diff --git a/.csslintrc b/.csslintrc index 1133ef2a..177e4fcc 100644 --- a/.csslintrc +++ b/.csslintrc @@ -1,37 +1,40 @@ -{ - "important": true, - "adjoining-classes": false, - "known-properties": true, - "box-sizing": false, - "box-model": true, - "overqualified-elements": true, - "display-property-grouping": true, - "bulletproof-font-face": false, - "compatible-vendor-prefixes": false, - "regex-selectors": false, - "errors": false, - "duplicate-background-images": true, - "duplicate-properties": true, - "empty-rules": true, - "selector-max-approaching": false, - "gradients": false, - "fallback-colors": false, - "font-sizes": false, - "font-faces": false, - "floats": false, - "star-property-hack": true, - "outline-none": true, - "import": true, - "ids": true, - "underscore-property-hack": true, - "rules-count": false, - "qualified-headings": true, - "selector-max": false, - "shorthand": true, - "text-indent": true, - "unique-headings": true, - "universal-selector": false, - "unqualified-attributes": true, - "vendor-prefix": true, - "zero-units": true -} +--errors=box-model, + display-property-grouping, + duplicate-background-images, + duplicate-properties, + empty-rules, + ids, + import, + important, + known-properties, + outline-none, + overqualified-elements, + qualified-headings, + shorthand, + star-property-hack, + text-indent, + underscore-property-hack, + unique-headings, + unqualified-attributes, + vendor-prefix, + zero-units +--ignore=adjoining-classes, + box-sizing, + bulletproof-font-face, + compatible-vendor-prefixes, + errors, + fallback-colors, + floats, + font-faces, + font-sizes, + gradients, + import-ie-limit, + order-alphabetical, + regex-selectors, + rules-count, + selector-max, + selector-max-approaching, + selector-newline, + universal-selector +--exclude-list=core/assets, + vendor diff --git a/.editorconfig b/.editorconfig index 242859d8..686c443c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,5 +13,5 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[composer.json] +[composer.{json,lock}] indent_size = 4 diff --git a/.eslintignore b/.eslintignore index 961edb75..9c134873 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,8 +1,8 @@ -core/assets/vendor/**/* -core/modules/locale/tests/locale_test.js +core/**/* vendor/**/* sites/**/files/**/* libraries/**/* sites/**/libraries/**/* profiles/**/libraries/**/* **/js_test_files/**/* +**/node_modules/**/* diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..d4bbc920 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "./core/.eslintrc.json" +} diff --git a/.gitattributes b/.gitattributes index fca87f35..a37894e8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -35,6 +35,7 @@ *.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 *.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php *.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 *.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php *.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 *.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 @@ -44,13 +45,17 @@ # Define binary file attributes. # - Do not treat them as text. # - Include binary diff in patches instead of "binary files differ." +*.eot -text diff +*.exe -text diff *.gif -text diff *.gz -text diff *.ico -text diff *.jpeg -text diff *.jpg -text diff -*.png -text diff +*.otf -text diff *.phar -text diff -*.exe -text diff +*.png -text diff *.svgz -text diff *.ttf -text diff +*.woff -text diff +*.woff2 -text diff diff --git a/.htaccess b/.htaccess index 4716fa12..83cb71a0 100644 --- a/.htaccess +++ b/.htaccess @@ -93,7 +93,7 @@ AddEncoding gzip svgz # If you do not have mod_rewrite installed, you should remove these # directories from your webroot or otherwise protect them from being # downloaded. - RewriteRule "(^|/)\.(?!well-known)" - [F] + RewriteRule "/\.|^\.(?!well-known/)" - [F] # If your site can be accessed both with and without the 'www.' prefix, you # can use one of the following settings to redirect users to your preferred diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 65a54d07..00000000 --- a/circle.yml +++ /dev/null @@ -1,18 +0,0 @@ -machine: - timezone: Asia/Tokyo - php: - version: 5.6.22 - -dependencies: - pre: - - echo 'date.timezone = "Asia/Tokyo"' > /opt/circleci/php/$(phpenv global)/etc/conf.d/date_timezone.ini - -deployment: - production: - branch: master - commands: - - | - curl -LO https://deployer.org/deployer.phar - mv deployer.phar /home/ubuntu/bin/dep - chmod +x /home/ubuntu/bin/dep - - dep -f=./config/deploy.php deploy production diff --git a/composer.json b/composer.json index 727e031d..b9536cfe 100644 --- a/composer.json +++ b/composer.json @@ -4,11 +4,11 @@ "type": "project", "license": "GPL-2.0+", "require": { - "composer/installers": "^1.0.21", - "wikimedia/composer-merge-plugin": "~1.3" + "composer/installers": "^1.0.24", + "wikimedia/composer-merge-plugin": "^1.4" }, "replace": { - "drupal/core": "~8.2" + "drupal/core": "^8.4" }, "minimum-stability": "dev", "prefer-stable": true, @@ -19,7 +19,10 @@ "extra": { "_readme": [ "By default Drupal loads the autoloader from ./vendor/autoload.php.", - "To change the autoloader you can edit ./autoload.php." + "To change the autoloader you can edit ./autoload.php.", + "This file specifies the packages.drupal.org repository.", + "You can read more about this composer repository at:", + "https://www.drupal.org/node/2718229" ], "merge-plugin": { "include": [ @@ -28,6 +31,15 @@ "recurse": false, "replace": false, "merge-extra": false + }, + "installer-paths": { + "core": ["type:drupal-core"], + "modules/contrib/{$name}": ["type:drupal-module"], + "profiles/contrib/{$name}": ["type:drupal-profile"], + "themes/contrib/{$name}": ["type:drupal-theme"], + "drush/contrib/{$name}": ["type:drupal-drush"], + "modules/custom/{$name}": ["type:drupal-custom-module"], + "themes/custom/{$name}": ["type:drupal-custom-theme"] } }, "autoload": { @@ -37,8 +49,16 @@ }, "scripts": { "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump", - "post-autoload-dump": "Drupal\\Core\\Composer\\Composer::ensureHtaccess", + "post-autoload-dump": [ + "Drupal\\Core\\Composer\\Composer::ensureHtaccess" + ], "post-package-install": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup", "post-package-update": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup" - } + }, + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + } + ] } diff --git a/composer.lock b/composer.lock index 3dfa8906..21fb0fdc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,32 +4,40 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7d101b08e5ae002d827cd42ae9a4e344", - "content-hash": "60f7057617c6d995bf9946d0b12f0b5d", + "content-hash": "bec46eaaa9fa07a4cbd8c84302f0d275", "packages": [ { "name": "asm89/stack-cors", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/asm89/stack-cors.git", - "reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc" + "reference": "65ccbd455370f043c2e3b93482a3813603d68731" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/asm89/stack-cors/zipball/3ae8ef219bb4c9a6caf857421719aa07fa7776cc", - "reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc", + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/65ccbd455370f043c2e3b93482a3813603d68731", + "reference": "65ccbd455370f043c2e3b93482a3813603d68731", "shasum": "" }, "require": { - "php": ">=5.3.2", - "symfony/http-foundation": "~2.1|~3.0", - "symfony/http-kernel": "~2.1|~3.0" + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0", + "symfony/http-kernel": "~2.7|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, "autoload": { - "psr-0": { - "Asm89\\Stack": "src/" + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" } }, "notification-url": "https://packagist.org/downloads/", @@ -48,22 +56,25 @@ "cors", "stack" ], - "time": "2016-08-01 12:05:04" + "time": "2017-04-11T20:03:41+00:00" }, { "name": "composer/installers", - "version": "v1.0.21", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45" + "reference": "9ce17fb70e9a38dd8acff0636a29f5cf4d575c1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45", - "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45", + "url": "https://api.github.com/repos/composer/installers/zipball/9ce17fb70e9a38dd8acff0636a29f5cf4d575c1b", + "reference": "9ce17fb70e9a38dd8acff0636a29f5cf4d575c1b", "shasum": "" }, + "require": { + "composer-plugin-api": "^1.0" + }, "replace": { "roundcube/plugin-installer": "*", "shama/baton": "*" @@ -72,16 +83,16 @@ "composer/composer": "1.0.*@dev", "phpunit/phpunit": "4.1.*" }, - "type": "composer-installer", + "type": "composer-plugin", "extra": { - "class": "Composer\\Installers\\Installer", + "class": "Composer\\Installers\\Plugin", "branch-alias": { "dev-master": "1.0-dev" } }, "autoload": { - "psr-0": { - "Composer\\Installers\\": "src/" + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" } }, "notification-url": "https://packagist.org/downloads/", @@ -96,80 +107,99 @@ } ], "description": "A multi-framework Composer library installer", - "homepage": "http://composer.github.com/installers/", + "homepage": "https://composer.github.io/installers/", "keywords": [ "Craft", "Dolibarr", + "Eliasis", "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", "MODX Evo", + "Mautic", + "Maya", "OXID", + "Plentymarkets", + "Porto", + "RadPHP", "SMF", "Thelia", "WolfCMS", "agl", "aimeos", "annotatecms", + "attogram", "bitrix", "cakephp", "chef", + "cockpit", "codeigniter", "concrete5", "croogo", "dokuwiki", "drupal", + "eZ Platform", "elgg", + "expressionengine", "fuelphp", "grav", "installer", + "itop", "joomla", "kohana", "laravel", + "lavalite", "lithium", "magento", "mako", "mediawiki", "modulework", "moodle", + "osclass", "phpbb", "piwik", "ppi", "puppet", + "reindex", "roundcube", "shopware", "silverstripe", + "sydes", "symfony", "typo3", "wordpress", + "yawik", "zend", "zikula" ], - "time": "2015-02-18 17:17:01" + "time": "2017-08-09T07:53:48+00:00" }, { "name": "composer/semver", - "version": "1.0.0", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", - "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "~2.3" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.1-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -182,10 +212,6 @@ "MIT" ], "authors": [ - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com" - }, { "name": "Nils Adermann", "email": "naderman@naderman.de", @@ -195,6 +221,11 @@ "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], "description": "Semver library that offers utilities, version constraint parsing and validation.", @@ -204,7 +235,7 @@ "validation", "versioning" ], - "time": "2015-09-21 09:42:36" + "time": "2016-08-30T16:08:34+00:00" }, { "name": "doctrine/annotations", @@ -272,42 +303,42 @@ "docblock", "parser" ], - "time": "2015-08-31 12:32:49" + "time": "2015-08-31T12:32:49+00:00" }, { "name": "doctrine/cache", - "version": "v1.4.2", + "version": "v1.6.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca" + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "conflict": { "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "phpunit/phpunit": ">=3.7", + "phpunit/phpunit": "~4.8|~5.0", "predis/predis": "~1.0", "satooshi/php-coveralls": "~0.6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.5.x-dev" + "dev-master": "1.6.x-dev" } }, "autoload": { - "psr-0": { - "Doctrine\\Common\\Cache\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } }, "notification-url": "https://packagist.org/downloads/", @@ -342,7 +373,7 @@ "cache", "caching" ], - "time": "2015-08-31 12:36:41" + "time": "2016-10-29T11:16:17+00:00" }, { "name": "doctrine/collections", @@ -408,20 +439,20 @@ "collections", "iterator" ], - "time": "2015-04-14 22:21:58" + "time": "2015-04-14T22:21:58+00:00" }, { "name": "doctrine/common", - "version": "v2.5.1", + "version": "v2.6.2", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9" + "reference": "7bce00698899aa2c06fe7365c76e4d78ddb15fa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9", + "url": "https://api.github.com/repos/doctrine/common/zipball/7bce00698899aa2c06fe7365c76e4d78ddb15fa3", + "reference": "7bce00698899aa2c06fe7365c76e4d78ddb15fa3", "shasum": "" }, "require": { @@ -430,20 +461,20 @@ "doctrine/collections": "1.*", "doctrine/inflector": "1.*", "doctrine/lexer": "1.*", - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "require-dev": { - "phpunit/phpunit": "~3.7" + "phpunit/phpunit": "~4.8|~5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } }, "autoload": { - "psr-0": { - "Doctrine\\Common\\": "lib/" + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", @@ -481,20 +512,20 @@ "persistence", "spl" ], - "time": "2015-08-31 13:00:22" + "time": "2016-11-30T16:50:46+00:00" }, { "name": "doctrine/inflector", - "version": "v1.0.1", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", "shasum": "" }, "require": { @@ -506,7 +537,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -548,7 +579,7 @@ "singularize", "string" ], - "time": "2014-12-20 21:24:13" + "time": "2015-11-06T14:35:42+00:00" }, { "name": "doctrine/lexer", @@ -602,7 +633,7 @@ "lexer", "parser" ], - "time": "2014-09-09 13:34:57" + "time": "2014-09-09T13:34:57+00:00" }, { "name": "easyrdf/easyrdf", @@ -664,29 +695,28 @@ "rdfa", "sparql" ], - "time": "2015-02-27 09:45:49" + "time": "2015-02-27T09:45:49+00:00" }, { "name": "egulias/email-validator", - "version": "1.2.9", + "version": "1.2.14", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "af864423f50ea59f96c87bb1eae147a70bcf67a1" + "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/af864423f50ea59f96c87bb1eae147a70bcf67a1", - "reference": "af864423f50ea59f96c87bb1eae147a70bcf67a1", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/5642614492f0ca2064c01d60cc33284cc2f731a9", + "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9", "shasum": "" }, "require": { - "doctrine/lexer": "~1.0,>=1.0.1", + "doctrine/lexer": "^1.0.1", "php": ">= 5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.4", - "satooshi/php-coveralls": "dev-master" + "phpunit/phpunit": "^4.8.24" }, "type": "library", "extra": { @@ -717,32 +747,35 @@ "validation", "validator" ], - "time": "2015-06-22 21:07:51" + "time": "2017-02-03T22:48:59+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.2.1", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "3f808fba627f2c5b69e2501217bf31af349c1427" + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427", - "reference": "3f808fba627f2c5b69e2501217bf31af349c1427", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", "shasum": "" }, "require": { "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.3.1", + "guzzlehttp/psr7": "^1.4", "php": ">=5.5" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.0", + "phpunit/phpunit": "^4.0 || ^5.0", "psr/log": "^1.0" }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, "type": "library", "extra": { "branch-alias": { @@ -779,32 +812,32 @@ "rest", "web service" ], - "time": "2016-07-15 17:22:37" + "time": "2017-06-22T18:50:49+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.2.0", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "shasum": "" }, "require": { "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -830,20 +863,20 @@ "keywords": [ "promise" ], - "time": "2016-05-18 16:56:05" + "time": "2016-12-20T10:07:11+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.3.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b" + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", - "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "shasum": "" }, "require": { @@ -879,71 +912,36 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } ], - "description": "PSR-7 message implementation", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ "http", "message", + "request", + "response", "stream", - "uri" - ], - "time": "2016-06-24 23:00:38" - }, - { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" + "uri", + "url" ], - "time": "2014-11-20 16:49:30" + "time": "2017-03-20T17:10:46+00:00" }, { "name": "masterminds/html5", - "version": "2.2.1", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "170aa5cb35b29fccafbf5ea63487c013f396fdc9" + "reference": "2c37c6c520b995b761674de3be8455a381679067" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/170aa5cb35b29fccafbf5ea63487c013f396fdc9", - "reference": "170aa5cb35b29fccafbf5ea63487c013f396fdc9", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/2c37c6c520b995b761674de3be8455a381679067", + "reference": "2c37c6c520b995b761674de3be8455a381679067", "shasum": "" }, "require": { @@ -958,7 +956,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, "autoload": { @@ -995,20 +993,20 @@ "serializer", "xml" ], - "time": "2016-05-10 14:11:45" + "time": "2017-09-04T12:26:28+00:00" }, { "name": "paragonie/random_compat", - "version": "1.1.1", + "version": "v2.0.10", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32" + "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a208865a5aeffc2dbbef2a5b3409887272d93f32", - "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", + "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", "shasum": "" }, "require": { @@ -1043,20 +1041,20 @@ "pseudorandom", "random" ], - "time": "2015-12-01 02:52:15" + "time": "2017-03-13T16:27:32+00:00" }, { "name": "psr/http-message", - "version": "1.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", "shasum": "" }, "require": { @@ -1084,6 +1082,7 @@ } ], "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", "keywords": [ "http", "http-message", @@ -1092,26 +1091,34 @@ "request", "response" ], - "time": "2015-05-04 20:22:00" + "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "1.0.0" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/1.0.0", - "reference": "1.0.0", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1125,12 +1132,13 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "stack/builder", @@ -1179,20 +1187,20 @@ "keywords": [ "stack" ], - "time": "2016-06-02 06:58:42" + "time": "2016-06-02T06:58:42+00:00" }, { "name": "symfony-cmf/routing", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", - "url": "https://github.com/symfony-cmf/Routing.git", - "reference": "b93704ca098334f56e9b317932f21a4362e620db" + "url": "https://github.com/symfony-cmf/routing.git", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/b93704ca098334f56e9b317932f21a4362e620db", - "reference": "b93704ca098334f56e9b317932f21a4362e620db", + "url": "https://api.github.com/repos/symfony-cmf/routing/zipball/fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", "shasum": "" }, "require": { @@ -1238,33 +1246,36 @@ "database", "routing" ], - "time": "2016-03-31 09:11:39" + "time": "2017-05-09T08:10:41+00:00" }, { "name": "symfony/class-loader", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68" + "reference": "fc4c04bfd17130a9dccfded9578353f311967da7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/7c46951128f7169cbece2c303fba4a9eb35cbe68", - "reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/fc4c04bfd17130a9dccfded9578353f311967da7", + "reference": "fc4c04bfd17130a9dccfded9578353f311967da7", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-apcu": "~1.1" + "php": ">=5.5.9" }, "require-dev": { - "symfony/finder": "~2.0,>=2.0.5|~3.0.0" + "symfony/finder": "~2.8|~3.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1291,41 +1302,43 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2017-01-10 14:03:07" + "time": "2017-04-12T14:13:17+00:00" }, { "name": "symfony/console", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912" + "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912", - "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912", + "url": "https://api.github.com/repos/symfony/console/zipball/a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38", + "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "~2.7,>=2.7.2|~3.0.0", + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/filesystem": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1352,37 +1365,37 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-01-08 20:43:03" + "time": "2017-04-26T01:39:17+00:00" }, { "name": "symfony/debug", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "567681e2c4e5431704e884e4be25a95fd900770f" + "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/567681e2c4e5431704e884e4be25a95fd900770f", - "reference": "567681e2c4e5431704e884e4be25a95fd900770f", + "url": "https://api.github.com/repos/symfony/debug/zipball/fd6eeee656a5a7b384d56f1072243fe1c0e81686", + "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "psr/log": "~1.0" }, "conflict": { "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0" + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1409,32 +1422,32 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-04-19T20:17:50+00:00" }, { "name": "symfony/dependency-injection", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "b75356611675364607d697f314850d9d870a84aa" + "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b75356611675364607d697f314850d9d870a84aa", - "reference": "b75356611675364607d697f314850d9d870a84aa", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59", + "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "conflict": { - "symfony/expression-language": "<2.6" + "symfony/yaml": "<3.2" }, "require-dev": { - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/yaml": "~3.2" }, "suggest": { "symfony/config": "", @@ -1445,7 +1458,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1472,31 +1485,31 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2017-01-10 14:27:01" + "time": "2017-04-26T01:39:17+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34" + "reference": "b8a401f733b43251e1d088c589368b2a94155e40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b8a401f733b43251e1d088c589368b2a94155e40", + "reference": "b8a401f733b43251e1d088c589368b2a94155e40", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" }, "suggest": { "symfony/dependency-injection": "", @@ -1505,7 +1518,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1532,35 +1545,33 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-05-01T14:58:48+00:00" }, { "name": "symfony/http-foundation", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f" + "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/464cdde6757a40701d758112cc7ff2c6adf6e82f", - "reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9de6add7f731e5af7f5b2e9c0da365e43383ebef", + "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/expression-language": "~2.8|~3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1587,48 +1598,48 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-01-08 20:43:03" + "time": "2017-05-01T14:55:58+00:00" }, { "name": "symfony/http-kernel", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c" + "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1097eb4ce0a7bdcd030f110c123682fed89a137c", - "reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/46e8b209abab55c072c47d72d5cd1d62c0585e05", + "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "psr/log": "~1.0", - "symfony/debug": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0", - "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6" + "symfony/debug": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { - "symfony/browser-kit": "~2.3|~3.0.0", - "symfony/class-loader": "~2.1|~3.0.0", - "symfony/config": "~2.8", - "symfony/console": "~2.3|~3.0.0", - "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.8|~3.0.0", - "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/finder": "~2.0,>=2.0.5|~3.0.0", - "symfony/process": "~2.0,>=2.0.5|~3.0.0", - "symfony/routing": "~2.8|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0", - "symfony/templating": "~2.2|~3.0.0", - "symfony/translation": "~2.0,>=2.0.5|~3.0.0", - "symfony/var-dumper": "~2.6|~3.0.0" + "symfony/browser-kit": "~2.8|~3.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/css-selector": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/dom-crawler": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0", + "symfony/routing": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", + "symfony/templating": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/var-dumper": "~3.2" }, "suggest": { "symfony/browser-kit": "", @@ -1642,7 +1653,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1669,60 +1680,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2017-01-12 20:27:24" - }, - { - "name": "symfony/polyfill-apcu", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-apcu.git", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "apcu", - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2016-11-14 01:06:16" + "time": "2017-05-01T17:46:48+00:00" }, { "name": "symfony/polyfill-iconv", @@ -1781,7 +1739,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1840,143 +1798,29 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" - }, - { - "name": "symfony/polyfill-php54", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2016-11-14 01:06:16" - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67", - "shasum": "" - }, - "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/process", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231" + "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ebb3c2abe0940a703f08e0cbe373f62d97d40231", - "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231", + "url": "https://api.github.com/repos/symfony/process/zipball/999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0", + "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2003,20 +1847,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-04-12T14:13:17+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v0.2", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "dc7e308e1dc2898a46776e2221a643cb08315453" + "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/dc7e308e1dc2898a46776e2221a643cb08315453", - "reference": "dc7e308e1dc2898a46776e2221a643cb08315453", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/66085f246d3893cbdbcec5f5ad15ac60546cf0de", + "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de", "shasum": "" }, "require": { @@ -2028,9 +1872,15 @@ "symfony/phpunit-bridge": "~2.7|~3.0" }, "suggest": { + "psr/http-message-implementation": "To use the HttpFoundation factory", "zendframework/zend-diactoros": "To use the Zend Diactoros factory" }, "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { "psr-4": { "Symfony\\Bridge\\PsrHttpMessage\\": "" @@ -2057,36 +1907,36 @@ "http-message", "psr-7" ], - "time": "2015-05-29 17:57:12" + "time": "2016-09-14T18:37:20+00:00" }, { "name": "symfony/routing", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f" + "reference": "5029745d6d463585e8b487dbc83d6333f408853a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f", - "reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f", + "url": "https://api.github.com/repos/symfony/routing/zipball/5029745d6d463585e8b487dbc83d6333f408853a", + "reference": "5029745d6d463585e8b487dbc83d6333f408853a", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/common": "~2.2", "psr/log": "~1.0", - "symfony/config": "~2.7|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", @@ -2099,7 +1949,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2132,44 +1982,55 @@ "uri", "url" ], - "time": "2017-01-02 20:30:24" + "time": "2017-04-12T14:13:17+00:00" }, { "name": "symfony/serializer", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a" + "reference": "6eeae1ba82005b761a53b7b8cf960bbf40c95986" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/3a5337e3daaabb9ada73d60f3271adb6bfa56a1a", - "reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a", + "url": "https://api.github.com/repos/symfony/serializer/zipball/6eeae1ba82005b761a53b7b8cf960bbf40c95986", + "reference": "6eeae1ba82005b761a53b7b8cf960bbf40c95986", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-php55": "~1.0" + "php": ">=5.5.9" + }, + "conflict": { + "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", + "symfony/property-info": "<3.1", + "symfony/yaml": "<3.1" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "symfony/config": "~2.2|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "phpdocumentor/reflection-docblock": "~3.0", + "symfony/cache": "~3.1", + "symfony/config": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/property-access": "~2.8|~3.0", + "symfony/property-info": "~3.1", + "symfony/yaml": "~3.1" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "To use the DataUriNormalizer.", "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", "symfony/yaml": "For using the default YAML mapping loader." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2196,34 +2057,34 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-05-01T14:55:58+00:00" }, { "name": "symfony/translation", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b4ac4a393f6970cc157fba17be537380de396a86" + "reference": "f4a04d2df710f81515df576b2de06bdeee518b83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b4ac4a393f6970cc157fba17be537380de396a86", - "reference": "b4ac4a393f6970cc157fba17be537380de396a86", + "url": "https://api.github.com/repos/symfony/translation/zipball/f4a04d2df710f81515df576b2de06bdeee518b83", + "reference": "f4a04d2df710f81515df576b2de06bdeee518b83", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.8", - "symfony/intl": "~2.4|~3.0.0", - "symfony/yaml": "~2.2|~3.0.0" + "symfony/config": "~2.8|~3.0", + "symfony/intl": "^2.8.18|^3.2.5", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "psr/log": "To use logging capability in translator", @@ -2233,7 +2094,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2260,53 +2121,57 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-04-12T14:13:17+00:00" }, { "name": "symfony/validator", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811" + "reference": "98bf011bf1f3b69bece3b79e19633e9c51545b2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/3b1a3188efea75ec7c0419a2568b6e5f82031811", - "reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811", + "url": "https://api.github.com/repos/symfony/validator/zipball/98bf011bf1f3b69bece3b79e19633e9c51545b2b", + "reference": "98bf011bf1f3b69bece3b79e19633e9c51545b2b", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation": "~2.4|~3.0.0" + "symfony/translation": "~2.8|~3.0" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "egulias/email-validator": "~1.2,>=1.2.1", - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/intl": "~2.7.4|~2.8|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "egulias/email-validator": "^1.2.8|~2.0", + "symfony/cache": "~3.1", + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/intl": "^2.8.18|^3.2.5", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", "doctrine/cache": "For using the default cached annotation reader and metadata cache.", "egulias/email-validator": "Strict (RFC compliant) email validation", + "psr/cache-implementation": "For using the metadata cache.", "symfony/config": "", - "symfony/expression-language": "For using the 2.4 Expression validator", + "symfony/expression-language": "For using the Expression validator", "symfony/http-foundation": "", "symfony/intl": "", - "symfony/property-access": "For using the 2.4 Validator API", + "symfony/property-access": "For using the Expression validator", "symfony/yaml": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2333,29 +2198,35 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2017-01-12 19:24:25" + "time": "2017-04-12T14:13:17+00:00" }, { "name": "symfony/yaml", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2" + "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", - "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", + "url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6", + "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2382,33 +2253,34 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-01-03 13:49:52" + "time": "2017-05-01T14:55:58+00:00" }, { "name": "twig/twig", - "version": "v1.24.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" + "reference": "9935b662e24d6e634da88901ab534cc12e8c728f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", - "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9935b662e24d6e634da88901ab534cc12e8c728f", + "reference": "9935b662e24d6e634da88901ab534cc12e8c728f", "shasum": "" }, "require": { "php": ">=5.2.7" }, "require-dev": { + "psr/container": "^1.0", "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" + "symfony/phpunit-bridge": "~3.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.24-dev" + "dev-master": "1.32-dev" } }, "autoload": { @@ -2443,20 +2315,20 @@ "keywords": [ "templating" ], - "time": "2016-01-25 21:22:18" + "time": "2017-02-27T00:07:03+00:00" }, { "name": "wikimedia/composer-merge-plugin", - "version": "v1.3.1", + "version": "v1.4.1", "source": { "type": "git", "url": "https://github.com/wikimedia/composer-merge-plugin.git", - "reference": "0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4" + "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4", - "reference": "0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/81c6ac72a24a67383419c7eb9aa2b3437f2ab100", + "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100", "shasum": "" }, "require": { @@ -2464,7 +2336,7 @@ "php": ">=5.3.2" }, "require-dev": { - "composer/composer": "1.0.*@dev", + "composer/composer": "~1.0.0", "jakub-onderka/php-parallel-lint": "~0.8", "phpunit/phpunit": "~4.8|~5.0", "squizlabs/php_codesniffer": "~2.1.0" @@ -2492,38 +2364,40 @@ } ], "description": "Composer plugin to merge multiple composer.json files", - "time": "2016-03-08 17:11:37" + "time": "2017-04-25T02:31:25+00:00" }, { "name": "zendframework/zend-diactoros", - "version": "1.1.3", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181" + "reference": "424a840dc3bedcdeea510b42e056c77c2d6c4bef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/e2f5c12916c74da384058d0dfbc7fbc0b03d1181", - "reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/424a840dc3bedcdeea510b42e056c77c2d6c4bef", + "reference": "424a840dc3bedcdeea510b42e056c77c2d6c4bef", "shasum": "" }, "require": { - "php": ">=5.4", + "php": "^5.4 || ^7.0", "psr/http-message": "~1.0" }, "provide": { - "psr/http-message-implementation": "~1.0.0" + "psr/http-message-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "~4.6", - "squizlabs/php_codesniffer": "^2.3.1" + "ext-dom": "*", + "ext-libxml": "*", + "phpunit/phpunit": "^4.6 || ^5.5", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" + "dev-master": "1.4-dev", + "dev-develop": "1.5-dev" } }, "autoload": { @@ -2542,24 +2416,24 @@ "psr", "psr-7" ], - "time": "2015-08-10 20:04:20" + "time": "2017-08-17T21:21:00+00:00" }, { "name": "zendframework/zend-escaper", - "version": "2.5.1", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73" + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73", - "reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": ">=5.5" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", @@ -2586,48 +2460,50 @@ "escaper", "zf2" ], - "time": "2015-06-03 14:05:37" + "time": "2016-06-30T19:48:38+00:00" }, { "name": "zendframework/zend-feed", - "version": "2.5.2", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-feed.git", - "reference": "0661345b82b51428619e05d3aadd3de65b57fa54" + "reference": "12b328d382aa5200f1de53d4147033b885776b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-feed/zipball/0661345b82b51428619e05d3aadd3de65b57fa54", - "reference": "0661345b82b51428619e05d3aadd3de65b57fa54", + "url": "https://api.github.com/repos/zendframework/zend-feed/zipball/12b328d382aa5200f1de53d4147033b885776b67", + "reference": "12b328d382aa5200f1de53d4147033b885776b67", "shasum": "" }, "require": { - "php": ">=5.5", - "zendframework/zend-escaper": "~2.5", - "zendframework/zend-stdlib": "~2.5" + "php": "^5.5 || ^7.0", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", "phpunit/phpunit": "~4.0", - "zendframework/zend-cache": "~2.5", - "zendframework/zend-db": "~2.5", - "zendframework/zend-http": "~2.5", - "zendframework/zend-servicemanager": "~2.5", - "zendframework/zend-validator": "~2.5" + "psr/http-message": "^1.0", + "zendframework/zend-cache": "^2.5", + "zendframework/zend-db": "^2.5", + "zendframework/zend-http": "^2.5", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-validator": "^2.5" }, "suggest": { - "zendframework/zend-cache": "Zend\\Cache component", - "zendframework/zend-db": "Zend\\Db component", + "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator", + "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests", + "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub", "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations", - "zendframework/zend-validator": "Zend\\Validator component" + "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations", + "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" } }, "autoload": { @@ -2645,104 +2521,35 @@ "feed", "zf2" ], - "time": "2015-08-04 21:39:18" - }, - { - "name": "zendframework/zend-hydrator", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-hydrator.git", - "reference": "f3ed8b833355140350bbed98d8a7b8b66875903f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/f3ed8b833355140350bbed98d8a7b8b66875903f", - "reference": "f3ed8b833355140350bbed98d8a7b8b66875903f", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "zendframework/zend-stdlib": "^2.5.1" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.0@dev", - "zendframework/zend-eventmanager": "^2.5.1", - "zendframework/zend-filter": "^2.5.1", - "zendframework/zend-inputfilter": "^2.5.1", - "zendframework/zend-serializer": "^2.5.1", - "zendframework/zend-servicemanager": "^2.5.1" - }, - "suggest": { - "zendframework/zend-eventmanager": "^2.5.1, to support aggregate hydrator usage", - "zendframework/zend-filter": "^2.5.1, to support naming strategy hydrator usage", - "zendframework/zend-serializer": "^2.5.1, to use the SerializableStrategy", - "zendframework/zend-servicemanager": "^2.5.1, to support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Hydrator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-hydrator", - "keywords": [ - "hydrator", - "zf2" - ], - "time": "2015-09-17 14:06:43" + "time": "2016-02-11T18:54:29+00:00" }, { "name": "zendframework/zend-stdlib", - "version": "2.7.3", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "8ac0c77ff567fcf49b58689ee3bfa7595be102bc" + "reference": "8bafa58574204bdff03c275d1d618aaa601588ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/8ac0c77ff567fcf49b58689ee3bfa7595be102bc", - "reference": "8ac0c77ff567fcf49b58689ee3bfa7595be102bc", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/8bafa58574204bdff03c275d1d618aaa601588ae", + "reference": "8bafa58574204bdff03c275d1d618aaa601588ae", "shasum": "" }, "require": { - "php": ">=5.5", - "zendframework/zend-hydrator": "~1.0" + "php": "^5.5 || ^7.0" }, "require-dev": { "athletic/athletic": "~0.1", "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-config": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-servicemanager": "~2.5" - }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-filter": "To support naming strategy hydrator usage", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" + "phpunit/phpunit": "~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "3.0-dev", + "dev-develop": "3.1-dev" } }, "autoload": { @@ -2759,22 +2566,22 @@ "stdlib", "zf2" ], - "time": "2015-09-25 04:06:33" + "time": "2016-04-12T21:19:36+00:00" } ], "packages-dev": [ { "name": "behat/mink", - "version": "v1.7.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/minkphp/Mink.git", - "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9" + "reference": "9ea1cebe3dc529ba3861d87c818f045362c40484" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9", - "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/9ea1cebe3dc529ba3861d87c818f045362c40484", + "reference": "9ea1cebe3dc529ba3861d87c818f045362c40484", "shasum": "" }, "require": { @@ -2819,7 +2626,7 @@ "testing", "web" ], - "time": "2016-03-05 08:26:18" + "time": "2017-02-06T09:59:54+00:00" }, { "name": "behat/mink-browserkit-driver", @@ -2875,7 +2682,7 @@ "browser", "testing" ], - "time": "2016-03-05 08:59:47" + "time": "2016-03-05T08:59:47+00:00" }, { "name": "behat/mink-goutte-driver", @@ -2930,7 +2737,7 @@ "headless", "testing" ], - "time": "2016-03-05 09:04:22" + "time": "2016-03-05T09:04:22+00:00" }, { "name": "doctrine/instantiator", @@ -2984,20 +2791,57 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "drupal/coder", + "version": "8.2.12", + "source": { + "type": "git", + "url": "https://github.com/klausi/coder.git", + "reference": "984c54a7b1e8f27ff1c32348df69712afd86b17f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/klausi/coder/zipball/984c54a7b1e8f27ff1c32348df69712afd86b17f", + "reference": "984c54a7b1e8f27ff1c32348df69712afd86b17f", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.4.0", + "squizlabs/php_codesniffer": ">=2.8.1 <3.0", + "symfony/yaml": ">=2.0.0" + }, + "require-dev": { + "phpunit/phpunit": ">=3.7 <6" + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "description": "Coder is a library to review Drupal code.", + "homepage": "https://www.drupal.org/project/coder", + "keywords": [ + "code review", + "phpcs", + "standards" + ], + "time": "2017-03-18T10:28:49+00:00" }, { "name": "fabpot/goutte", - "version": "v3.1.2", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/Goutte.git", - "reference": "3cbc6ed222422a28400e470050f14928a153207e" + "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/3cbc6ed222422a28400e470050f14928a153207e", - "reference": "3cbc6ed222422a28400e470050f14928a153207e", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638", + "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638", "shasum": "" }, "require": { @@ -3010,7 +2854,7 @@ "type": "application", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3033,7 +2877,49 @@ "keywords": [ "scraper" ], - "time": "2015-11-05 12:58:44" + "time": "2017-01-03T13:21:43+00:00" + }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ], + "time": "2014-11-20T16:49:30+00:00" }, { "name": "jcalderonzumba/gastonjs", @@ -3090,7 +2976,7 @@ "headless", "phantomjs" ], - "time": "2016-01-18 09:21:03" + "time": "2016-01-18T09:21:03+00:00" }, { "name": "jcalderonzumba/mink-phantomjs-driver", @@ -3151,20 +3037,20 @@ "phantomjs", "testing" ], - "time": "2015-12-04 13:55:02" + "time": "2015-12-04T13:55:02+00:00" }, { "name": "mikey179/vfsStream", - "version": "v1.6.0", + "version": "v1.6.5", "source": { "type": "git", "url": "https://github.com/mikey179/vfsStream.git", - "reference": "73bcb605b741a7d5044b47592338c633788b0eb7" + "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/73bcb605b741a7d5044b47592338c633788b0eb7", - "reference": "73bcb605b741a7d5044b47592338c633788b0eb7", + "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", "shasum": "" }, "require": { @@ -3197,7 +3083,7 @@ ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", - "time": "2015-10-06 16:59:57" + "time": "2017-08-01T08:02:14+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -3246,34 +3132,37 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2015-02-03 12:10:50" + "time": "2015-02-03T12:10:50+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.5.0", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { - "phpspec/phpspec": "~2.0" + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.6.x-dev" } }, "autoload": { @@ -3306,7 +3195,7 @@ "spy", "stub" ], - "time": "2015-08-13 10:07:40" + "time": "2017-03-02T20:05:34+00:00" }, { "name": "phpunit/php-code-coverage", @@ -3368,20 +3257,20 @@ "testing", "xunit" ], - "time": "2015-10-06 15:47:00" + "time": "2015-10-06T15:47:00+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { @@ -3415,7 +3304,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2016-10-03T07:40:28+00:00" }, { "name": "phpunit/php-text-template", @@ -3456,26 +3345,34 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "1.0.7", + "version": "1.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -3497,20 +3394,20 @@ "keywords": [ "timer" ], - "time": "2015-06-21 08:01:12" + "time": "2017-02-26T11:10:40+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "1.4.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", "shasum": "" }, "require": { @@ -3546,20 +3443,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2017-02-27T10:12:30+00:00" }, { "name": "phpunit/phpunit", - "version": "4.8.27", + "version": "4.8.36", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90" + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90", - "reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", "shasum": "" }, "require": { @@ -3575,7 +3472,7 @@ "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", + "sebastian/comparator": "~1.2.2", "sebastian/diff": "~1.2", "sebastian/environment": "~1.3", "sebastian/exporter": "~1.2", @@ -3618,7 +3515,7 @@ "testing", "xunit" ], - "time": "2016-07-21 06:48:14" + "time": "2017-06-21T08:07:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -3674,26 +3571,26 @@ "mock", "xunit" ], - "time": "2015-10-02 06:51:40" + "time": "2015-10-02T06:51:40+00:00" }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -3738,32 +3635,32 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", - "version": "1.3.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -3786,31 +3683,31 @@ } ], "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff" ], - "time": "2015-02-22 15:13:53" + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", - "version": "1.3.2", + "version": "1.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^4.8 || ^5.0" }, "type": "library", "extra": { @@ -3840,20 +3737,20 @@ "environment", "hhvm" ], - "time": "2015-08-03 06:14:51" + "time": "2016-08-18T05:49:44+00:00" }, { "name": "sebastian/exporter", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e" + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", "shasum": "" }, "require": { @@ -3861,12 +3758,13 @@ "sebastian/recursion-context": "~1.0" }, "require-dev": { + "ext-mbstring": "*", "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -3906,20 +3804,20 @@ "export", "exporter" ], - "time": "2015-06-21 07:55:53" + "time": "2016-06-17T09:04:28+00:00" }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -3957,20 +3855,20 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/recursion-context", - "version": "1.0.1", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba" + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba", - "reference": "994d4a811bafe801fb06dccbee797863ba2792ba", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", "shasum": "" }, "require": { @@ -4010,7 +3908,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-06-21 08:04:50" + "time": "2016-10-03T07:41:43+00:00" }, { "name": "sebastian/version", @@ -4045,29 +3943,107 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" + "time": "2015-06-21T13:59:46+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2017-03-01T22:17:45+00:00" }, { "name": "symfony/browser-kit", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "d2a5de15c8341a470a66becf4597bc675686a72b" + "reference": "9fab1ab6f77b77f3df5fc5250fc6956811699b57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/d2a5de15c8341a470a66becf4597bc675686a72b", - "reference": "d2a5de15c8341a470a66becf4597bc675686a72b", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9fab1ab6f77b77f3df5fc5250fc6956811699b57", + "reference": "9fab1ab6f77b77f3df5fc5250fc6956811699b57", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/dom-crawler": "~2.1|~3.0.0" + "php": ">=5.5.9", + "symfony/dom-crawler": "~2.8|~3.0" }, "require-dev": { - "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", - "symfony/process": "~2.3.34|~2.7,>=2.7.6|~3.0.0" + "symfony/css-selector": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" }, "suggest": { "symfony/process": "" @@ -4075,7 +4051,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -4102,29 +4078,29 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-04-12T14:13:17+00:00" }, { "name": "symfony/css-selector", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f" + "reference": "02983c144038e697c959e6b06ef6666de759ccbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/f45daea42232d9ca5cf561ec64f0d4aea820877f", - "reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/02983c144038e697c959e6b06ef6666de759ccbc", + "reference": "02983c144038e697c959e6b06ef6666de759ccbc", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -4155,28 +4131,28 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-05-01T14:55:58+00:00" }, { "name": "symfony/dom-crawler", - "version": "v2.8.16", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "52cc211afa9458c0a54c478010a55f44892c1c02" + "reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/52cc211afa9458c0a54c478010a55f44892c1c02", - "reference": "52cc211afa9458c0a54c478010a55f44892c1c02", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/f1ad34e8af09ed17570e027cf0c58a12eddec286", + "reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "~2.8|~3.0.0" + "symfony/css-selector": "~2.8|~3.0" }, "suggest": { "symfony/css-selector": "" @@ -4184,7 +4160,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -4211,12 +4187,76 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2017-01-02 20:30:24" + "time": "2017-04-12T14:13:17+00:00" + }, + { + "name": "symfony/phpunit-bridge", + "version": "v3.2.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "00916603c524b8048906de460b7ea0dfa1651281" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/00916603c524b8048906de460b7ea0dfa1651281", + "reference": "00916603c524b8048906de460b7ea0dfa1651281", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "conflict": { + "phpunit/phpunit": ">=6.0" + }, + "suggest": { + "ext-zip": "Zip support is required when using bin/simple-phpunit", + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "time": "2017-04-12T14:13:17+00:00" } ], "aliases": [], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": { + "behat/mink": 20 + }, "prefer-stable": true, "prefer-lowest": false, "platform": { diff --git a/core/.eslintignore b/core/.eslintignore new file mode 100644 index 00000000..fae39489 --- /dev/null +++ b/core/.eslintignore @@ -0,0 +1,6 @@ +assets/vendor/**/* +node_modules/**/* +**/js_test_files/**/* +*.js +!*.es6.js +modules/locale/tests/locale_test.es6.js diff --git a/core/.eslintrc b/core/.eslintrc deleted file mode 100644 index 9b34952f..00000000 --- a/core/.eslintrc +++ /dev/null @@ -1,95 +0,0 @@ -{ - "extends": "eslint:recommended", - "env": { - "browser": true - }, - "globals": { - "Drupal": true, - "drupalSettings": true, - "drupalTranslations": true, - "domready": true, - "jQuery": true, - "_": true, - "matchMedia": true, - "Backbone": true, - "Modernizr": true, - "CKEDITOR": true - }, - "rules": { - // Errors. - "array-bracket-spacing": [2, "never"], - "block-scoped-var": 2, - "brace-style": [2, "stroustrup", {"allowSingleLine": true}], - "comma-dangle": [2, "never"], - "comma-spacing": 2, - "comma-style": [2, "last"], - "computed-property-spacing": [2, "never"], - "curly": [2, "all"], - "eol-last": 2, - "eqeqeq": [2, "smart"], - "guard-for-in": 2, - "indent": [2, 2, {"SwitchCase": 1}], - "key-spacing": [2, {"beforeColon": false, "afterColon": true}], - "keyword-spacing": [2, {"before": true, "after": true}], - "linebreak-style": [2, "unix"], - "lines-around-comment": [2, {"beforeBlockComment": true, "afterBlockComment": false}], - "new-parens": 2, - "no-array-constructor": 2, - "no-caller": 2, - "no-catch-shadow": 2, - "no-eval": 2, - "no-extend-native": 2, - "no-extra-bind": 2, - "no-extra-parens": [2, "functions"], - "no-implied-eval": 2, - "no-iterator": 2, - "no-label-var": 2, - "no-labels": 2, - "no-lone-blocks": 2, - "no-loop-func": 2, - "no-multi-spaces": 2, - "no-multi-str": 2, - "no-native-reassign": 2, - "no-nested-ternary": 2, - "no-new-func": 2, - "no-new-object": 2, - "no-new-wrappers": 2, - "no-octal-escape": 2, - "no-process-exit": 2, - "no-proto": 2, - "no-return-assign": 2, - "no-script-url": 2, - "no-sequences": 2, - "no-shadow-restricted-names": 2, - "no-spaced-func": 2, - "no-trailing-spaces": 2, - "no-undef-init": 2, - "no-undefined": 2, - "no-unused-expressions": 2, - "no-unused-vars": [2, {"vars": "all", "args": "none"}], - "no-with": 2, - "object-curly-spacing": [2, "never"], - "one-var": [2, "never"], - "quote-props": [2, "consistent-as-needed"], - "quotes": [2, "single", "avoid-escape"], - "semi": [2, "always"], - "semi-spacing": [2, {"before": false, "after": true}], - "space-before-blocks": [2, "always"], - "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], - "space-in-parens": [2, "never"], - "space-infix-ops": 2, - "space-unary-ops": [2, { "words": true, "nonwords": false }], - "spaced-comment": [2, "always"], - "strict": [2, "function"], - "yoda": [2, "never"], - // Warnings. - "max-nested-callbacks": [1, 3], - "valid-jsdoc": [1, { - "prefer": { - "returns": "return", - "property": "prop" - }, - "requireReturn": false - }] - } -} diff --git a/core/.eslintrc.json b/core/.eslintrc.json new file mode 100644 index 00000000..369539d2 --- /dev/null +++ b/core/.eslintrc.json @@ -0,0 +1,41 @@ +{ + "extends": "eslint-config-airbnb", + "root": true, + "env": { + "browser": true, + "es6": true, + "node": true + }, + "globals": { + "Drupal": true, + "drupalSettings": true, + "drupalTranslations": true, + "domready": true, + "jQuery": true, + "_": true, + "matchMedia": true, + "Backbone": true, + "Modernizr": true, + "CKEDITOR": true + }, + "rules": { + "consistent-return": [0], + "no-underscore-dangle": [0], + "max-nested-callbacks": [1, 3], + "no-mutable-exports": [1], + "no-plusplus": [1, { + "allowForLoopAfterthoughts": true + }], + "no-param-reassign": [0], + "no-prototype-builtins": [0], + "valid-jsdoc": [1, { + "prefer": { + "returns": "return", + "property": "prop" + }, + "requireReturn": false + }], + "brace-style": ["error", "stroustrup"], + "no-unused-vars": [1] + } +} diff --git a/core/.eslintrc.legacy.json b/core/.eslintrc.legacy.json new file mode 100644 index 00000000..9051bbfa --- /dev/null +++ b/core/.eslintrc.legacy.json @@ -0,0 +1,94 @@ +{ + "extends": "eslint:recommended", + "root": true, + "env": { + "browser": true + }, + "globals": { + "Drupal": true, + "drupalSettings": true, + "drupalTranslations": true, + "domready": true, + "jQuery": true, + "_": true, + "matchMedia": true, + "Backbone": true, + "Modernizr": true, + "CKEDITOR": true + }, + "rules": { + "array-bracket-spacing": [2, "never"], + "block-scoped-var": 2, + "brace-style": [2, "stroustrup", {"allowSingleLine": true}], + "comma-dangle": [2, "never"], + "comma-spacing": 2, + "comma-style": [2, "last"], + "computed-property-spacing": [2, "never"], + "curly": [2, "all"], + "eol-last": 2, + "eqeqeq": [2, "smart"], + "guard-for-in": 2, + "indent": [2, 2, {"SwitchCase": 1}], + "key-spacing": [2, {"beforeColon": false, "afterColon": true}], + "keyword-spacing": [2, {"before": true, "after": true}], + "linebreak-style": [2, "unix"], + "lines-around-comment": [2, {"beforeBlockComment": true, "afterBlockComment": false}], + "new-parens": 2, + "no-array-constructor": 2, + "no-caller": 2, + "no-catch-shadow": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-extra-parens": [2, "functions"], + "no-implied-eval": 2, + "no-iterator": 2, + "no-label-var": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-spaces": 2, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-nested-ternary": 2, + "no-new-func": 2, + "no-new-object": 2, + "no-new-wrappers": 2, + "no-octal-escape": 2, + "no-process-exit": 2, + "no-proto": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-sequences": 2, + "no-shadow-restricted-names": 2, + "no-spaced-func": 2, + "no-trailing-spaces": 2, + "no-undef-init": 2, + "no-undefined": 2, + "no-unused-expressions": 2, + "no-unused-vars": [2, {"vars": "all", "args": "none"}], + "no-with": 2, + "object-curly-spacing": [2, "never"], + "one-var": [2, "never"], + "quote-props": [2, "consistent-as-needed"], + "quotes": [2, "single", "avoid-escape"], + "semi": [2, "always"], + "semi-spacing": [2, {"before": false, "after": true}], + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "spaced-comment": [2, "always"], + "strict": [2, "function"], + "yoda": [2, "never"], + "max-nested-callbacks": [1, 3], + "valid-jsdoc": [1, { + "prefer": { + "returns": "return", + "property": "prop" + }, + "requireReturn": false + }] + } +} diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 00000000..be42d488 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1,11 @@ +# Ignore node_modules folder created when installing core's JavaScript +# dependencies. +node_modules + +# Ignore overrides of core's phpcs.xml.dist and phpunit.xml.dist. +phpcs.xml +phpunit.xml + +# Ignore package-lock.json that is automatically created when adding +# dependencies by users of NPMv5. +package-lock.json diff --git a/core/.stylelintrc.json b/core/.stylelintrc.json new file mode 100644 index 00000000..832748d3 --- /dev/null +++ b/core/.stylelintrc.json @@ -0,0 +1,47 @@ +{ + "extends": "stylelint-config-standard", + "plugins": [ + "stylelint-no-browser-hacks/lib" + ], + "rules": { + "at-rule-empty-line-before": null, + "block-no-empty": null, + "color-hex-case": null, + "color-hex-length": null, + "comment-empty-line-before": null, + "declaration-block-no-duplicate-properties": null, + "declaration-block-no-redundant-longhand-properties": null, + "declaration-block-no-shorthand-property-overrides": null, + "declaration-block-trailing-semicolon": null, + "declaration-colon-space-after": null, + "function-comma-space-after": null, + "function-linear-gradient-no-nonstandard-direction": null, + "function-name-case": null, + "function-whitespace-after": null, + "length-zero-no-unit": null, + "no-empty-source": null, + "no-unknown-animations": true, + "number-leading-zero": null, + "number-no-trailing-zeros": null, + "plugin/no-browser-hacks": [true, { + "browsers": [ + "ie >= 9", + "edge >= 13", + "firefox >= 5", + "opera >= 12", + "safari >= 5", + "chrome >= 56" + ] + }], + "property-no-unknown": null, + "rule-empty-line-before": null, + "selector-pseudo-element-colon-notation": null, + "selector-type-no-unknown": null, + "shorthand-property-no-redundant-values": null, + "unit-whitelist": ["deg", "em", "ex", "ms", "rem", "%", "s", "px"] + }, + "ignoreFiles": [ + "assets/vendor/**/*.css", + "tests/Drupal/Tests/Core/Asset/css_test_files/**/*.css" + ] +} diff --git a/core/CHANGELOG.txt b/core/CHANGELOG.txt index 2b424d27..ac078d5c 100644 --- a/core/CHANGELOG.txt +++ b/core/CHANGELOG.txt @@ -1,6 +1,655 @@ -Drupal 8.2.3, 2016-11-16 +Drupal 8.4.0, 2017-10-04 ------------------------ -- Fixed security issues. See SA-CORE-2016-005. +### Drush users: Update to Drush 8.1.12+ or higher + +[Versions of Drush earlier than 8.1.12 will not work with Drupal +8.4.x](https://www.drupal.org/node/2874827). Update Drush to 8.1.12 or higher +**before using it to update to Drupal core 8.4.x** or you will encounter fatal +errors that prevent updates from running. + +* If Drush is installed globally (i.e., generally available on the web host), + Drush 8.1.12 and higher will successfully update Drupal 8.3.x to 8.4.0, but + users may still see [other error messages after updates have + run](https://github.com/drush-ops/drush/issues/2933).) +* If the site is built with Composer and includes Drush as a local dependency + (less common), you should update your `composer.json` file to require at + least [Drush 8.1.15](https://github.com/drush-ops/drush/releases/tag/8.1.15). + Drush 8.1.14 will not work in the same composer project as Drupal 8.4. + +### Updated browser requirements: Internet Explorer 9 and 10 no longer supported + +In April 2017, Microsoft discontinued all support for Internet Explorer 9 and +10. Therefore, [Drupal 8.4 has as well](https://www.drupal.org/node/2842298). +Drupal 8.4 still mostly works in these browser versions, but bugs that affect +them only will no longer be fixed, and existing workarounds for them will +be removed beginning in Drupal 8.5. + +Additionally, Drupal 8's [browser requirements documentation +page](https://www.drupal.org/docs/8/system-requirements/browser-requirements) +currently lists incorrect information regarding very outdated browser versions +such as Safari 5 and Firefox 5. [Clarifications to the browser policy and +documentation](https://www.drupal.org/node/2390621) are underway. + +### Known Issues + +Drupal 8.4.0 includes major version updates for two dependencies: +Symfony 3.2 and jQuery 3. Both updates may introduce backwards compatibility +issues for some sites or modules, so test carefully. For more information, see +the "Third-party library updates" section below. Known issues related to the +Symfony update include: + +* Drush issues: + * [Incompatibility with Drush 8.1.11 and earlier](https://www.drupal.org/node/2874827). + * [Other error messages with Drush 8.1.12 and higher](https://github.com/drush-ops/drush/issues/2933). + * [Incompatibility with Drush 8.1.14 and earlier for Composer-built sites](https://github.com/drupal-composer/drupal-project/issues/305). +* [Certain file uploads may fail + silently](https://www.drupal.org/node/2906030) due to a Symfony 3 backwards + compatibility break if they used the `$deep` parameter (which was already + deprecated in Symfony 2.8 and is removed in Symfony 3.0. *Check any custom + file upload code* that may have used the deprecated parameter and [update + it according to the API change record](https://www.drupal.org/node/2743809). + +See the ['8.4.0 update' tag for a list of known issues across +projects](https://www.drupal.org/project/issues/search?issue_tags=8.4.0%20update). + +[Search the issue queue for known +issues](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=Open&version%5B%5D=8.x&issue_tags_op=%3D). + +### Important fixes since 8.3.x + +Translators should take note of several [string additions and changes since the +last release](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&issue_tags_op=%3D&issue_tags=String+change+in+8.4.0). + +#### File usage tracking + +Drupal 8 has several longstanding [file usage tracking +bugs](https://www.drupal.org/node/2821423). To prevent further data loss, +Drupal 8.4 has [disabled the automatic deletion of files with no known +remaining usages](https://www.drupal.org/node/2801777). This will result of the +accumulation of unused files on sites, but ensures that files erroneously +reporting 0 usages are not deleted while in use. Additionally, an issue with +[validation errors when saving content referencing these +files](https://www.drupal.org/node/2896480) has also been resolved. + +[The change record explains how sites can opt back into marking files +temporary](https://www.drupal.org/node/2891902). If you choose to enable the +setting, you can also set "Delete orphaned files" to "Never" on +`/admin/config/media/file-system` to avoid permanent deletion of the affected +files. + +While the files will no longer be deleted by default, file usage is still not +tracked correctly in several scenarios, regardless of the setting. Discussion +on [how to evolve the file usage tracking +system](https://www.drupal.org/node/2821423) is underway. + +#### Configuration export sorting + +* [#2361539: Config export key order is not predictable for sequences, add + orderby property to config schema](https://www.drupal.org/node/2361539) + resolves an issue where sequences in configuration were not sorted unless + the code responsible for saving configuration explicitly performed a sort. + This resulted in unpredictable changes in configuration ordering and + confusing diffs even when nothing had changed. To resolve this issue, we've + [added an `orderby` key to the config schema](https://www.drupal.org/node/2852566) + that allows it to be sorted either by key or by value. Adding a preferred + sort is strongly recommended. +* Two related issues remain open: + * [#2860531: Add orderby key to third-party + settings](https://www.drupal.org/node/2860531) relates to unsorted + sequences which result in unexpected discrepancies in configuration + during a configuration import. + * [#2885368: Config export key order for sequences: "orderedby" does not + support cases where the order actually + matters](https://www.drupal.org/node/2885368) relates to various + sequences in core and contributed modules in which the source order is + important. + +#### Revision data integrity fixes + +* Previously, data from draft revisions for + [path aliases](https://www.drupal.org/node/2856363), + [menus](https://www.drupal.org/node/2858434), + and [books](https://www.drupal.org/node/2858431) could leak into the live + site. Drupal 8.4.0 hotfixes all three issues by preventing changes to + this data from being saved on any revision that is not the default revision. + These fixes improve revision support for both stable features and the + experimental Content Moderation module. +* Correspondingly, [Content Moderation now avoids such scenarios with + non-default revisions](https://www.drupal.org/node/2883868) by setting the + 'default revision' flag earlier. +* Previously, [saving a revision of an entity translation could cause draft + revisions to go "missing"](https://www.drupal.org/node/2766957). Drupal 8.4.0 + prevents this by preventing the moderation state from being set to anything + that would make the revision go "missing". Going forward, the entity system + will also [provide the 'revision_translation_affected' base field by default + for all revisionable and translatable entity + types](https://www.drupal.org/node/2896845) for tracking such revisions. +* [A similar but unrelated bug in + Content Moderation](https://www.drupal.org/node/2862988) has also been fixed + in this release. + +#### Other critical improvements + +* When nodes were deleted, Menu UI module deleted their menu items. However, + menu items may exist even whenm Menu UI module is not enabled and can also be + attached to entities other than nodes. Therefore, menu item cleanup on entity + deletetion [is now performed by the Custom Menu Links + module](https://www.drupal.org/node/2350797) instead, covering the previously + missing cases. A related issue that [broke module uninstallation for some + modules providing menu items for certain entity + forms](https://www.drupal.org/node/2907654) has also been resolved. +* A race condition occured in the Batch API when using fastcgi. The Batch API + now ensures that [the current batch state is written completely to the + database before starting the next + batch](https://www.drupal.org/node/2851111). +* When uninstalling modules, empty fields were left behind to be purged. + However, without the field definitions from the module, it was not possible + to purge them any more. [Empty field deletion is now performed + immediately](https://www.drupal.org/node/2884202) instead to avoid this + scenario. +* When clearing caches in a translated interface, the field labels would + [return to the default language](https://www.drupal.org/node/2650434). + +### New stable modules + +The following modules, previously considered experimental, are now stable and +safe for use on production sites, with full backwards compatibility and upgrade +paths from 8.4.0 to future releases: + +#### Datetime Range + +The [Datetime Range module](https://www.drupal.org/node/2893128) provides a +field type that allows end dates to support contributed modules like +[Calendar](https://www.drupal.org/project/calendar). This stable release is +backwards-compatible with the 8.3.x experimental version and shares a +consistent API with other Datetime fields. + +Future releases may improve Views support, usability, Datetime Range field +validation, and REST support. For bugs or feature requests for this module, +[see the core Datetime issue +queue](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=Open&version%5B%5D=8.x&component%5B%5D=datetime.module&issue_tags_op=%3D). + +#### Layout Discovery + +The [Layout Discovery module](https://www.drupal.org/node/2834025) provides +an API for modules or themes to register layouts as well as five common +layouts. Providing this API in core enables core and contributed layout +solutions to be compatible with each other. This stable release is +backwards-compatible with the 8.3.x experimental version and introduces +[support for per-region attributes](https://www.drupal.org/node/2885877). + +#### Media + +The new core [Media module](https://www.drupal.org/node/2831274) provides an +API for reusable media entities and references. It is based on the contributed +[Media Entity module](https://www.drupal.org/project/media_entity). + +Since there is a rich ecosystem of Drupal contributed modules built on Media +Entity, the top priority for this release is to [provide a stable core API and +data model](https://www.drupal.org/node/2895059) for a smoother transition for +these modules. Developers and expert site builders can now add Media as a +dependency. Work is underway to [provide an update path for existing sites' +Media Entity data](https://www.drupal.org/node/2880334) and to [port existing +contributed modules to the improved core +API](https://www.drupal.org/node/2860796). Both versions cannot be used at the +same time, so we also [prevent the 1.x version of the contributed Media Entity +module from being enabled at the same time as the core Media +module](https://www.drupal.org/node/2896427). + +Note that **the core Media module is currently marked hidden** and will not +appear on the 'Extend' (module administration) page. (Enabling a contributed +module that depends on the core Media module will also enable Media +automatically.) The module will be displayed to site builders normally once +user experience issues with it are resolved. Similarly, the REST API and +normalizations for Media is not final and support for decoupled applications +will also be improved in a future release. + +#### Inline Form Errors + +The [Inline Form Errors module](https://www.drupal.org/node/2897652) provides a +summary of any validation errors at the top of a form and places the individual +error messages next to the form elements themselves. This helps users +understand which entries need to be fixed, and how. Inline Form Errors was +provided as an experimental module from Drupal 8.0.0 on, but it is now stable +and polished enough for production use. See the core [Inline Form Errors module +issue queue](https://www.drupal.org/project/issues/drupal?text=&status=Open&priorities=All&categories=All&version=All&component=inline_form_errors.module) +for outstanding issues. + +#### Workflows + +The Workflows module provides an abstract system of states (like Draft, +Archived, and Published) and transitions between them. Workflows can be used by +modules that implement non-publishing workflows (such as for users or products) +as well as content publishing workflows. + +Drupal 8.4 introduces a final significant backwards compatibility and data +model break for this module, [moving responsibility for workflow states and +transitions from the Workflow entity to the Workflow type +plugin](https://www.drupal.org/node/2849827). Read [Workflow type plugins are +now responsible for state and transition +schema](https://www.drupal.org/node/2897706) for full details on the API and +data model changes related to this fix. Now that this change is complete, [the +Workflows module became stable](https://www.drupal.org/node/2897130)! + +While the module can be installed as-is, it is not useful in itself without +either Content Moderation and/or some other module that requires it. + +### Content authoring and site administration improvements + +* The "Save and keep (un)published" dropbutton has been replaced with [a + "Published" checkbox and single "Save" + button](https://www.drupal.org/node/2068063). The "Save and..." dropbutton + was a new design in Drupal 8, but users found it confusing, so we have + restored a design that is more similar to the user interface for Drupal 7 and + earlier. +* Previously, deleting a field on a content type would also delete any views + depending on the field. While the confirmation form did indicate that the + view would be deleted, users did not expect the behavior and often missed the + message, leading to data loss. [Now, the view is disabled + instead](https://www.drupal.org/node/2468045). In the future, we intend to + [notify users that configuration has been + disabled](https://www.drupal.org/node/2832558) (as in this fix) as well as + [give users clearer warnings for other highly destructive + operations](https://www.drupal.org/node/2773205). +* The [Drupal toolbar no longer flickers](https://www.drupal.org/node/2542050) + during page rendering, thus improving perceived front-end performance. +* Options in [timezones selector are now grouped by + regions](https://www.drupal.org/node/2847651) and labeled by cities instead + of timezone names, making it much easier for users to find and select the + specific timezone they need. +* Both the ["Comments" administration page at + `/admin/content/comment`](https://www.drupal.org/node/1986606) and the + ["Recent log messages" report provided by + dblog](https://www.drupal.org/node/2015149) are now configurable views. The + "Comments" administration page also [has some default filters + added](https://www.drupal.org/node/2898344). +* Useful meta information about a node's status is typically displayed at the + top of the node sidebar. Previously, this meta information was provided by + the Seven theme, so it was not available in other administrative themes. + [This meta information is now provided by node.module + itself](https://www.drupal.org/node/2803875) so other administration themes + can access it. +* [Views now supports rendering computed + fields](https://www.drupal.org/node/2852067). + +### REST and API-first improvements + +* Authenticated REST API performance increased by 15% by [utilizing the Dynamic + Page Cache](https://www.drupal.org/node/2827797). +* POSTing entities [can now happen at `/node`, `/taxonomy/term` and so + on](https://www.drupal.org/node/2293697), instead of `/entity/node`, + `/entity/taxonomy_term`. Instead of confusingly different URLs, they therefore + now use the URLs you'd expect. Backwards compatibility is maintained. +* There is now a dedicated resource for [resetting a user's + password](https://www.drupal.org/node/2847708). +* Time fields now are [normalized to RFC3339 timestamps by + default](https://www.drupal.org/node/2768651), fixing time ambiguity. + Existing sites continue to receive UNIX timestamps, but can opt in. [See the + change record for more information about backwards compatibility and on how + to opt in](https://www.drupal.org/node/2859657). +* [Path alias fields are now normalized as + well](https://www.drupal.org/node/2846554). [See the change record for + information about how this impacts API-first modules and other features + relying on serialized entities](https://www.drupal.org/node/2856220). +* When denormalization fails, a [422 response is now + returned](https://www.drupal.org/node/2827084) instead of a 400, per the HTTP + specification. +* With CORS enabled to allow origins besides the site's own host, [submitting + forms was broken](https://www.drupal.org/node/2853201) unless the site's own + host was also explicitly allowed. This is now resolved. +* Fatal errors and exceptions [now show a + backtrace](https://www.drupal.org/node/2853300) for all non-HTML requests as + well as HTML requests, which makes for easier debugging and better bug + reports. +* Massive expansion of test coverage. + +### Performance and scalability improvements + +* Drupal 8 caches at various different levels for more effective caching. + However, this resulted in exessively growing cache tables with tens or + hundreds of thousands of entries, and gigabytes in size. [A new limit of 5000 + rows per cache bin was introduced to limit this + growth](https://www.drupal.org/node/2526150). +* The internal page cache now [has a dedicated cache + bin](https://www.drupal.org/node/2889603) distinct from the rest of the + render cache for improved scalability. +* The service collector pattern instantiates all services it collects, which is + expensive, and unnecessary for some use cases. For those use cases, a [new + service ID collector](https://www.drupal.org/node/2472337) pattern has been + added and the theme negotiator updated to use it. [See the change record for + information about how to use the service ID + collector](https://www.drupal.org/node/2598944) for improved performance. +* The maximum time in-progress forms are cached [is now + customizable](https://www.drupal.org/node/1286154) rather than being limited + to a default cache lifetime of 6 hours. Sites can decrease the lifetime to + reduce cache footprint, or increase it if needed for a particular site's + usecase. [See the change record to learn how to access this new + setting](https://www.drupal.org/node/2886836). +* If there are no status messages, the corresponding rendering [is now + skipped](https://www.drupal.org/node/2853509). On simple sites that use the + Dynamic Page Cache (the default), this can result in a 10% improvement when + there are no messages! +* [Optimized the early Drupal installer](https://www.drupal.org/node/2872611) + to check whether any themes are installed first before invoking an + unnecessary function, which improves Drupal install time measurably for both + sites and automated tests. + +### Developer experience improvements + +* [Adopted Airbnb JavaScript style guide + 14.1](https://www.drupal.org/node/2815077) as the new baseline set of coding + standards for Drupal core and contributed modules. [See the change record for + information about how to configure your project for + eslint](https://www.drupal.org/node/2873849). +* Field type definitions can now [enforce the cardinality of the + field](https://www.drupal.org/node/2403703). [See the change record for + information about how to specify a cardinality via the + annotation](https://www.drupal.org/node/2869873). +* [Added new methods](https://www.drupal.org/node/2869809) to make getting + typed configuration entity representations easier. [See the change record for + more information about how to invoke these + methods](https://www.drupal.org/node/2877282). +* The `html_tag` render element now [supports nested render + arrays](https://www.drupal.org/node/2694535), enabling the creation of + dynamic SVGs. [See the change record for information about how you can use + this in your theme](https://www.drupal.org/node/2887146). +* [Added more helpful errors](https://www.drupal.org/node/2705037) when CSS + is not properly nested under an existing category in asset libraries. +* Also see the [change records for the 8.4.x + branch](https://www.drupal.org/list-changes/drupal/published?keywords_description=&to_branch=8.4.x&version=&created_op=%3E%3D&created%5Bvalue%5D=&created%5Bmin%5D=&created%5Bmax%5D=) + for other changes for developers. + +### Automated testing improvements + +* [PHPUnit has been updated from 4.8.28 to + 4.8.35](https://www.drupal.org/node/2850797) in order to incorporate a + forward-compatibility layer for PHPUnit 4.8, which will be useful during a + future migration to PHPUnit 5 or PHPUnit 6. +* Many former WebTestBase tests were converted to BrowserTestBase. [Track + current progress](http://simpletest-countdown.org/). +* The default approach for testing deprecated code has changed to [require use + of the Drupal core deprecation policy](https://www.drupal.org/node/2488860) + (`@trigger_error()`) to mark code deprecated; otherwise a test error will + be thrown. [See the change record for information about how to update + `phpunit.xml` and how to test deprecated + code](https://www.drupal.org/node/2811561). +* BrowserTestBase is [no longer dependent on traits from + Simpletest](https://www.drupal.org/node/2803621). Backwards + compatibility is preserved. +* [Resolved random test failures](https://www.drupal.org/node/2866056) due to + ResourceTestBase's HTTP client timeout of 30 seconds. + +### Third-party library updates + +* [Drupal's Symfony dependency has been updated from Symfony 2.8 to Symfony + 3.2](https://www.drupal.org/node/2712647). This major version update is + necessary because Symfony 2.8 support will end around the release of Drupal + 8.6.0 next year. See the change record for information about [Symfony 3 + backwards compatibility breaks that affected Drupal + core](https://www.drupal.org/node/2743809). [Drupal 8 also requires Symfony + 3.2.8](https://www.drupal.org/node/2871253) because of a bug in Symfony + 3.2.7. +* [#2533498: Update jQuery to version 3](https://www.drupal.org/node/2533498). + Now that jQuery 3.0 has been released, jQuery 2.x will only be receiving + security updates, so Drupal 8.4.0 ships with this library update. jQuery 3 + features numerous improvements, including better error reporting. See the + [jQuery Core 3.0 Upgrade Guide](https://jquery.com/upgrade-guide/3.0/) for + information on jQuery 3 backwards compatibility breaks that might affect the + JavaScript code in your modules, themes, and sites. +* The zurb/joyride library (used by the Tour module) has been [updated to a + development version higher than 2.1.0.1](https://www.drupal.org/node/2898808) + to resolve an upstream incompatibility with jQuery 3. We will update to + Joyride 2.1.1 once it is available with the needed fix. +* [zendframework/zend-diactoros has been updated from 1.3.10 to 1.4.1](https://www.drupal.org/node/2874817). +* [jQuery UI has been updated from 1.11.4 to 1.12.1](https://www.drupal.org/node/2809427). +* [jQuery Once has been updated from 2.1.1 to 2.2.0](https://www.drupal.org/node/2899156). +* [CKEditor has been updated from 4.6.2 to 4.7.2](https://www.drupal.org/node/2904142). +* [asm89/stack-cors has been updated from 1.0 to 1.1](https://www.drupal.org/node/2853201). +* [The minimum phpsec/prophecy requirement is now 1.4](https://www.drupal.org/node/2900800). +* [composer/installers has been updated from 1.2.0 to 1.4.0](https://www.drupal.org/node/2900112). +* [wikimedia/composer-merge-plugin has been updated from 1.4.0 to 1.4.1](https://www.drupal.org/node/2900112). +* [guzzlehttp/guzzle has been updated from 6.2.3 to 6.3.0](https://www.drupal.org/node/2900112). +* [mikey179/vfsstream has been updated from 1.6.4 to 1.6.5](https://www.drupal.org/node/2900112). +* [phpunit/phpunit has been updated from 4.8.35 to 4.8.36](https://www.drupal.org/node/2900112). +* [masterminds/html5 has been updated from 2.2.2 to 2.3.0](https://www.drupal.org/node/2909743). +* [symfony-cmf/routing has been udpated from 1.4.0 to 1.4.1](https://www.drupal.org/node/2909743). + +### Experimental modules + +#### Migrate ([beta stability](https://www.drupal.org/core/experimental#beta)) + +Migrate provides a general API for migrations. It will be considered completely +stable once all issues tagged [Migrate +critical](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=Open&version%5B%5D=8.x&issue_tags_op=%3D&issue_tags=Migrate+critical) +are resolved. + +* This release includes numerous developer experience improvements for Migrate + and Migrate Drupal, including [deprecating outdated references to + "CCK"](https://www.drupal.org/node/2751897), [simplifying field type + mapping](https://www.drupal.org/node/2896507), renaming several plugins to + better capture their and many other API and documentation improvements. + (Backwards compatibility is provided in each case Migrate is in beta.) +* Added the ability to [provide the source + module](https://www.drupal.org/node/2569805) to migrations to help site + owners review what data is being migrating, especially for cases where the + source and destination module are not the same (for example if a new Drupal 8 + module replaces old functionality. + + +#### Migrate Drupal and Migrate Drupal UI ([alpha stability](https://www.drupal.org/core/experimental#alpha)) + +Migrate Drupal module provides API support for Drupal-to-Drupal migrations, and +Migrate Drupal UI offers a simple user interface to run migrations from older +Drupal versions. + +* This release adds [date](https://www.drupal.org/node/2566779) and + [node reference](https://www.drupal.org/node/2814949) support for Drupal 6 to + 8 migrations. +* Core provides migrations for most Drupal 6 data and can be used for migrating + Drupal 6 sites to Drupal 8, and the Drupal 6 to 8 migration path is nearing + beta stability. Some gaps remain, such as for some internationalization data. + ([Outstanding issues for the Drupal 6 to Drupal 8 + migration](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=1&status%5B%5D=13&status%5B%5D=8&status%5B%5D=14&status%5B%5D=15&status%5B%5D=4&issue_tags_op=%3D&issue_tags=migrate-d6-d8).) +* The Drupal 7 to Drupal 8 migration is incomplete but is suitable for + developers who would like to help improve the migration and can be used to + test upgrades especially for simple Drupal 7 sites. Most high-priority + migrations are available. ([Outstanding issues for the Drupal 7 to Drupal 8 + migration](https://www.drupal.org/node/2456259).) +* Drush support for Migrate is currently only available in the + [Drupal Upgrade](https://www.drupal.org/project/migrate_upgrade) contributed + module. (See the [pull request to add support to + Drush](https://github.com/drush-ops/drush/issues/2140).) +* Conflicting text field processing settings [are now identified and + logged](https://www.drupal.org/node/2842222) to avoid security or data + integrity issues with the migration of plain and formatted text fields. +* Automatic redirects are now [added for translation node paths that are no + longer valid](https://www.drupal.org/node/2850085) after migration has merged + translations into a single node. +* A data integrity bug that resulted in [duplicate comment types and incorrect + comment_entity_statistics](https://www.drupal.org/node/2853872) for node and + forum comment migrations has been resolved. +* A bug that [stopped public files from being migrated from D6 to D8 if the + user first selected Drupal 7 in the UI](https://www.drupal.org/node/2907233) + has also been resolved. + +#### Content Moderation ([beta stability](https://www.drupal.org/core/experimental#beta)) + +Content Moderation allows workflows from the Workflows module to be applied to +content. Content Moderation has beta stability in 8.4.0-alpha1. Notable improvements in this release: + +* Workflow states are now [selected from a select list, rather than under a drop-button](https://www.drupal.org/node/2753717), which represents a significant + usability improvement. +* Now that workflows can be applied to any revisionable entity type, Content + Moderation [adds entity type checkboxes to the workflow form](https://www.drupal.org/node/2843083). + This allows site administrators to configure which entity types should have + the workflow at the same time as they configure the workflow itself, for a + more intuitive user experience. +* Content Moderation now [prevents the deletion of workflows that are currently in use](https://www.drupal.org/node/2830740) + to prevent fatal errors and data integrity problems. +* The confusing terminology of + ["forward revisions" has been replaced with that of "pending revisions"](https://www.drupal.org/node/2890364). + If your contributed module refers to revisions that are not yet published, it + should use this new term. +* [The 'Latest revision' views filter has been rewritten to avoid relying on a + custom {revision_tracker}](https://www.drupal.org/node/2865579), and that + table has been removed from the database schema. + +As per the experimental module process, there were some backwards-incompatible +changes since Drupal 8.3.x. Experimental modules do not offer a supported +upgrade path, but [an unofficial upgrade path is +available](https://www.drupal.org/node/2896630). + +#### Field Layout ([alpha stability](https://www.drupal.org/core/experimental#alpha)) + +This module provides the ability for site builders to rearrange fields on +content types, block types, etc. into new regions, for both the form and +display, on the same forms provided by the normal field user interface. Field +Layout has had several bugfixes since 8.3.0, but no significant changes. See +the [entity display layout roadmap](https://www.drupal.org/node/2795833) for +the next steps for this module, which needs to become stable by 8.5.0 to remain +in Drupal core. + +#### Settings Tray ([beta stability](https://www.drupal.org/core/experimental#beta)) + +The Settings Tray module allows configuring page elements such as blocks and +menus from the frontend of your site. Settings Tray has improved significantly +since Drupal 8.3.0, including numerous user interaction and accessibility +fixes, better compatibility with stable core modules like Quick Edit and +Contextual Links, added documentation, and [a CSS +reset](https://www.drupal.org/node/2826722) for better themer experience. + +The module reached beta stability following completion of [moving the +off-canvas dialog renderer into a core +component](https://www.drupal.org/node/2784443), and [renaming the machine name +of the module to settings_tray](https://www.drupal.org/node/2803375), to match +its user-facing name. We hope to make Settings Tray stable by 8.5.0. To track +progress, see the ["outside in" roadmap issue](https://www.drupal.org/node/2762505). + +#### Place Blocks ([alpha stability](https://www.drupal.org/core/experimental#alpha)) + +This feature allows the user to place a block on any page and see the region +where it will be displayed, without having to navigate to a backend +administration form. [8.4.0-alpha1 was the deadline for Place Blocks to +stabilize](https://www.drupal.org/core/experimental#versions), but the module's +roadmap was not completed. Furthermore, the module is not intended as a +standalone feature and should instead be a built-in part of the Block system. +For these reasons, [Place Blocks module has been marked hidden in this +release](https://www.drupal.org/node/2898267) (it can still be enabled with +Drush). The Place Blocks module itself will be turned into an empty module in +Drupal 8.5.x, since ideally the core Block system will offer the same +functionality in 8.5.0 (though this depends on completion of a [core patch for +the feature](https://www.drupal.org/node/2739075).) + +Drupal 8.3.0, 2017-04-05 +------------------------ +- Added modules: + * Added the Workflows module (experimental) which abstracts transitions and + states from Content Moderation into a separate component for reuse by + other modules implementing non-publishing workflows. + * Added the Layout Discovery module (experimental) which provides an API for + modules or themes to register layouts. + * Added the Field Layout module (experimental) which provides the ability + for site builders to rearrange fields on content types, block types, etc. + into new regions, for both the form and display, on the same forms + provided by the normal field user interface. +- Updated vendor libraries: + * Updated to Twig 1.25. + * Updated to jQuery 2.2.4. + * Updated to CKEditor 4.6.2 (with new Moono-Lisa skin). + * Updated Symfony components to 2.8.18. + * Updated PHPUnit to 4.8.35. + * Applied patch-level updates to the latest versions for all dependencies + wherever possible. Minor updates applied for Symfony PSR-7 Bridge and + Zend Stdlib, which Drupal does not depend on directly. +- Browser support: + * Advance notice: Internet Explore 9 and 10 will no longer supported from + 8.4.x, scheduled for October 2017. Microsoft has now ended support for + these browsers. Drupal will still support Internet Explorer 11 and its + replacement, Edge. +- Raised stability levels of experimental modules: + * Updated the BigPipe module from beta to stable. + * Updated the Migrate module from alpha to beta. + * See https://www.drupal.org/core/experimental#versions for more + information about the stability levels of experimental modules. +- Improved authoring features: + * Can now drag and drop images into image fields in Quick Edit mode. + * Image fields are now limited to only accepting images, so that users on + mobile clients are not offered a confusing and non-functional video + upload option. + * CKEditor now utilizes the AutoGrow plugin to better take advantage of + larger screen sizes. +- Improved site building and administration: + * Redesigned status report. + * Standardized display of Views overview page to more closely match that of + other administrative overview pages. + * Views filter order now matches the table column order below in Content + and People overview pages. + * The "Allowed HTML tags" input has been converted to a textarea, which + significantly improves the usability of HTML filter configuration. + * Removed the 'disabled' region from block administration. + * Incoming paths are again case-insensitive for routing, similar to earlier + major Drupal versions. +- Content Moderation improvements (experimental): + * Refactored to use new experimental Workflows module. + * Now supports moderation of non-translatable entity types. + * When reverting a moderated revision, the moderation state is now + reverted too. + * Added an API to create and enforce default workflow states and + transitions. + * Allow moderation of entity types without bundles, as long as they have + revisions. + * Publishes any entity type that implements EntityPublishedInterface, not + just Nodes. +- Migration improvements (experimental): + * Drupal 7 core node translations are now migrated to Drupal 8. + * Configuration translation support is added to migrations in general and + implemented for Drupal 6 user profile fields. +- Improved REST API and decoupled site features: + * REST API now supports the registering of users. + * Anonymous REST API performance increased by 60% by utilizing the internal + page cache. + * Improved the response bodies and status codes for requests with incorrect + request headers or request bodies, in dozens of situations. + * Massive overhaul of the test coverage. + * 403 responses now return reason why access was denied. + * Serialized values for Booleans and integers are now returned as the + correct data type, rather than incorrectly typed as strings. +- Improved performance/scalability: + * Optimized class loader detection made more generic to support class + loaders other than ApcClassLoader. + * ViewsData and Token info cache now use the default cache bin to prevent + APCu memory from being filled too quickly. + * Improve statistics performance by adding a swappable backend. +- Improved developer APIs: + * Deprecated several routing services in favor of two more unified services. + * Replaced the deprecated Symfony ExecutionContextInterface by subclassing + from ConstraintValidator to prepare for an update to Symfony 3. + * EntityPublishedInterface and EntityPublishedTrait have been added to give + a generic publishing API, and are being used by Node and Comment entity + types. + * Added a collection label to EntityType. This is a plural uppercase label + for a collection of entities - e.g. "Workflows". +- Changed coding standards: + * Officially adopted short array syntax and updated all of core accordingly. + * PHP CodeSniffer and Drupal Coder have been added as composer dev + requirements, so they can be installed automatically with + `composer install --dev` rather than requiring separate installation. (Do + not use `composer install --dev` for production sites.) + * Most global constants in Drupal 8 have been deprecated in favor of class + constants. As a best practice, use appropriate class constants rather than + global constants. +- Testing improvements: + * Integrated PHPUnit verbose output in SimpleTest UI. + * Improved backward compatibility with WebTestBase. + * Improved backward compatibility between BrowserTestBase and WebTestBase. + * Many old WebTestBase tests have been moved to BrowserTestBase. + * Expanded automated test coverage for JavaScript. +- Package management: + * composer.json now uses the new official endpoint for modules and themes, + packages.drupal.org. + * Custom modules and themes can now be installed to correct locations using + composer. + * Added Package.json enabling new JavaScript language features. Drupal 8.2.0, 2016-10-05 ------------------------ diff --git a/core/INSTALL.txt b/core/INSTALL.txt index c8397612..5d5525b1 100644 --- a/core/INSTALL.txt +++ b/core/INSTALL.txt @@ -88,7 +88,7 @@ INSTALLATION directory within your web server's document root or your public HTML directory, continue with this command: - mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc drupal-x.y.z/.gitattributes /path/to/your/installation + mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc.json drupal-x.y.z/.gitattributes /path/to/your/installation You can also download the latest version of Drupal using Git on the command line and set up a repository by following the instructions at @@ -353,7 +353,7 @@ Never edit Drupal's core modules and themes; instead, use the hooks available in the Drupal API. To modify the behavior of Drupal, develop a module as described at https://www.drupal.org/developing/modules. To modify the look of Drupal, create a subtheme as described at https://www.drupal.org/node/2165673, or a -completely new theme as described at https://www.drupal.org/documentation/theme +completely new theme as described at https://www.drupal.org/docs/8/theming MULTISITE CONFIGURATION ----------------------- diff --git a/core/MAINTAINERS.txt b/core/MAINTAINERS.txt index 0739fb09..884a046f 100644 --- a/core/MAINTAINERS.txt +++ b/core/MAINTAINERS.txt @@ -22,6 +22,8 @@ Drupal 8 (Product Manager) - Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch (Framework Manager, Release Manager) +- Chris McCafferty 'cilefen' https://www.drupal.org/u/cilefen + (Release Manager) - Jess Myrbo 'xjm' https://www.drupal.org/u/xjm (Release Manager) - Alex Pott 'alexpott' https://www.drupal.org/u/alexpott @@ -30,8 +32,14 @@ Drupal 8 (Framework Manager - Frontend) Provisional membership: -- Chris McCafferty 'cilefen' https://www.drupal.org/u/cilefen - (Release Manager) +- Lauri Eskola 'lauriii' https://www.drupal.org/u/lauriii + (Framework Manager - Frontend) +- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy + (Product Manager) +- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan + (Framework Manager) +- Roy Scholten 'yoroy' https://www.drupal.org/u/yoroy + (Product Manager) Drupal 7 - Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx @@ -81,7 +89,6 @@ Base system - ? Basic Auth -- Klaus Purer 'klausi' https://www.drupal.org/u/klausi - Juampy Novillo Requena 'juampy' https://www.drupal.org/u/juampy Batch API @@ -163,10 +170,9 @@ CSS - John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin Database API -- Larry Garfield 'Crell' https://www.drupal.org/u/crell +- ? MySQL DB driver - - Larry Garfield 'Crell' https://www.drupal.org/u/crell - David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss PostgreSQL DB driver @@ -176,7 +182,7 @@ Database API - ? Database Logging -- ? +- Mariano D'Agostino 'dagmar' https://www.drupal.org/u/dagmar Database Update API - ? @@ -237,6 +243,9 @@ Help Image - Claudiu Cristea 'claudiu.cristea' https://www.drupal.org/u/claudiu.cristea +Inline Form Errors +- Daniël Smidt 'dmsmidt' https://www.drupal.org/u/dmsmidt + Installer - ? @@ -246,6 +255,7 @@ Interface Translation (locale) JavaScript - Théodore Biadala 'nod_' https://www.drupal.org/u/nod_ - Kay Leung 'droplet' https://www.drupal.org/u/droplet +- Matthew Grill 'drpal' https://www.drupal.org/u/drpal Language - Francesco Placella 'plach' https://www.drupal.org/u/plach @@ -263,20 +273,9 @@ Mail Markup - ? -Migrate +Media +- Sean Blommaert 'seanB' https://www.drupal.org/u/seanb - Adam Globus-Hoenich 'phenaproxima' https://www.drupal.org/u/phenaproxima -- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy -- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn -- Michael Anello 'ultimike' https://www.drupal.org/u/ultimike -- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan -- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone - -Migrate (Drupal) -- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy -- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn -- Michael Anello 'ultimike' https://www.drupal.org/u/ultimike -- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan -- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone Menu - Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner @@ -289,8 +288,15 @@ Menu Link Content Menu UI - ? +Migrate +- Adam Globus-Hoenich 'phenaproxima' https://www.drupal.org/u/phenaproxima +- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn +- Markus Sipilä 'masipila' https://www.drupal.org/u/masipila +- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone +- Maxime Turcotte 'maxocub' https://www.drupal.org/u/maxocub + Node -- ? +- Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood Node Access - Ken Rickard 'agentrickard' https://www.drupal.org/u/agentrickard @@ -300,9 +306,6 @@ Node Access Options - ? -Outside In -- Ted Bowman 'tedbow' https://www.drupal.org/u/tedbow - Page Cache - Lorenz Schori 'znerol' https://www.drupal.org/u/znerol - Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx @@ -330,11 +333,9 @@ Render API - Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman Request Processing -- Larry Garfield 'Crell' https://www.drupal.org/u/crell +- ? REST -- Klaus Purer 'klausi' https://www.drupal.org/u/klausi -- Larry Garfield 'Crell' https://www.drupal.org/u/crell - Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers Responsive Image @@ -343,7 +344,6 @@ Responsive Image - Jelle Sebreghts 'Jelle_S' https://www.drupal.org/u/jelle_s Routing -- Larry Garfield 'Crell' https://www.drupal.org/u/crell - Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett Search @@ -352,6 +352,9 @@ Search Serialization - Damian Lee 'damiankloip' https://www.drupal.org/u/damiankloip +Settings Tray +- Ted Bowman 'tedbow' https://www.drupal.org/u/tedbow + Seven - ? @@ -369,7 +372,7 @@ Statistics - Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood Syslog -- Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey +- Mariano D'Agostino 'dagmar' https://www.drupal.org/u/dagmar System (module) - ? @@ -384,7 +387,6 @@ Telephone Testing framework - Alex Pott 'alexpott' https://www.drupal.org/u/alexpott - Sascha Grossenbacher 'Berdir' https://www.drupal.org/u/berdir -- Klaus Purer 'klausi' https://www.drupal.org/u/klausi - Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner Text Field @@ -427,6 +429,9 @@ Views - Jess Myrbo 'xjm' https://www.drupal.org/u/xjm - Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude +Workflows +- Sam Becker 'Sam152' https://www.drupal.org/u/sam152 + Topic maintainers ----------------- @@ -470,16 +475,28 @@ re-architect or otherwise improve large areas of Drupal core. See https://www.drupal.org/community-initiatives/drupal-core for more information on their responsibilities. The initiative coordinators for Drupal 8 are: -Multi-lingual -- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy +API-first Initiative +- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers +- Mateu Aguiló Bosch 'e0ipso' https://www.drupal.org/u/e0ipso -Workflow Initiative -- Dick Olsson 'dixon_' https://www.drupal.org/u/dixon_ +Layout Initiative +- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett +- Emilie Nouveau 'DyanneNova' https://www.drupal.org/u/dyannenova + +Media Initiative +- Janez Urevc 'slashrsm' https://www.drupal.org/u/slashrsm PHPUnit Initiative -- Klaus Purer 'klausi' https://www.drupal.org/u/klausi - Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner + Provisional membership: + - Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude + - Michiel Nugter 'michielnugter' https://www.drupal.org/u/michielnugter + +Workflow Initiative +- Dick Olsson 'dixon_' https://www.drupal.org/u/dixon_ + + Provisional membership: None at this time. @@ -494,11 +511,11 @@ tools, documentation, and processes to make it easier for new contributors to get involved. They organize communications and logistics, and actively participate in mentoring. +- Mauricio Dinarte 'dinarcon' https://www.drupal.org/u/dinarcon - Lucas Hedding 'heddn' https://www.drupal.org/u/heddn +- Rachel Lawson 'rachel_norfolk' https://www.drupal.org/u/rachel_norfolk - Valery Lourie 'valthebald' https://www.drupal.org/u/valthebald -- Alina Mackenzie 'alimac' https://www.drupal.org/u/alimac - Jess Myrbo 'xjm' https://www.drupal.org/u/xjm -- Andrea Soper 'ZenDoodles' https://www.drupal.org/u/zendoodles -- Cathy Theys 'YesCT' https://www.drupal.org/u/yesct +- Matthew Radcliffe 'mradcliffe' https://www.drupal.org/u/mradcliffe Provisional membership: None at this time. diff --git a/core/assets/vendor/ckeditor/CHANGES.md b/core/assets/vendor/ckeditor/CHANGES.md index d291c8d5..55ef74dc 100644 --- a/core/assets/vendor/ckeditor/CHANGES.md +++ b/core/assets/vendor/ckeditor/CHANGES.md @@ -1,11 +1,252 @@ CKEditor 4 Changelog ==================== +## CKEditor 4.7.3 + +New Features: + +* [#568](https://github.com/ckeditor/ckeditor-dev/issues/568): Added possibility to adjust nested editables' filters using the [`CKEDITOR.filter.disallowedContent`](https://docs.ckeditor.com/#!/api/CKEDITOR.filter-property-disallowedContent) property. + +Fixed Issues: + +* [#554](https://github.com/ckeditor/ckeditor-dev/issues/554): Fixed: [`change`](https://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event not fired when typing the first character after pasting into the editor. Thanks to [Daniel Miller](https://github.com/millerdev)! +* [#566](https://github.com/ckeditor/ckeditor-dev/issues/566): Fixed: The CSS `border` shorthand property with zero width (`border: 0px solid #000;`) causes the table to have the border attribute set to 1. +* [#779](https://github.com/ckeditor/ckeditor-dev/issues/779): Fixed: The [Remove Format](https://ckeditor.com/addon/removeformat) plugin removes elements with language definition inserted by the [Language](https://ckeditor.com/addon/language) plugin. +* [#423](https://github.com/ckeditor/ckeditor-dev/issues/423): Fixed: The [Paste from Word](https://ckeditor.com/addon/pastefromword) plugin pastes paragraphs into the editor even if [`CKEDITOR.config.enterMode`](https://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) is set to `CKEDITOR.ENTER_BR`. +* [#719](https://github.com/ckeditor/ckeditor-dev/issues/719): Fixed: Image inserted using the [Enhanced Image](https://ckeditor.com/addon/image2) plugin can be resized when the editor is in [read-only mode](https://docs.ckeditor.com/#!/guide/dev_readonly). +* [#577](https://github.com/ckeditor/ckeditor-dev/issues/577): Fixed: The "Delete Columns" command provided by the [Table Tools](https://ckeditor.com/addon/tabletools) plugin throws an error when trying to delete columns. +* [#867](https://github.com/ckeditor/ckeditor-dev/issues/867): Fixed: Typing into a selected table throws an error. +* [#817](https://github.com/ckeditor/ckeditor-dev/issues/817): Fixed: The [Save](https://ckeditor.com/addon/save) plugin does not work in [Source Mode](https://ckeditor.com/addon/sourcearea). + +Other Changes: + +* Updated the [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin: + * [#40](https://github.com/WebSpellChecker/ckeditor-plugin-wsc/issues/40): Fixed: IE10 throws an error when spell checking is started. +* [#800](https://github.com/ckeditor/ckeditor-dev/issues/800): Added the [`CKEDITOR.dom.selection.isCollapsed`](https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-isCollapsed) method which is a simpler way to check if the selection is collapsed. +* [#830](https://github.com/ckeditor/ckeditor-dev/issues/830): Added an option to define which dialog tab should be shown by default when creating [`CKEDITOR.dialogCommand`](https://docs.ckeditor.com/#!/api/CKEDITOR.dialogCommand). + +## CKEditor 4.7.2 + +New Features: + +* [#455](https://github.com/ckeditor/ckeditor-dev/issues/455): Added [Advanced Content Filter](https://docs.ckeditor.com/#!/guide/dev_acf) integration with the [Justify](http://ckeditor.com/addon/justify) plugin. + +Fixed Issues: + +* [#663](https://github.com/ckeditor/ckeditor-dev/issues/663): [Chrome] Fixed: Clicking the scrollbar throws an `Uncaught TypeError: element.is is not a function` error. +* [#694](https://github.com/ckeditor/ckeditor-dev/pull/694): Refactoring in the [Table Selection](http://ckeditor.com/addon/tableselection) plugin: + * [#520](https://github.com/ckeditor/ckeditor-dev/issues/520): Fixed: Widgets cannot be properly pasted into a table cell. + * [#460](https://github.com/ckeditor/ckeditor-dev/issues/460): Fixed: Editor gone after pasting into an editor within a table. +* [#579](https://github.com/ckeditor/ckeditor-dev/issues/579): Fixed: Internal `cke_table-faked-selection-table` class is visible in the Stylesheet Classes field of the [Table Properties](http://ckeditor.com/addon/table) dialog. +* [#545](https://github.com/ckeditor/ckeditor-dev/issues/545): [Edge] Fixed: Error thrown when pressing the [Select All](https://ckeditor.com/addon/selectall) button in [Source Mode](http://ckeditor.com/addon/sourcearea). +* [#582](https://github.com/ckeditor/ckeditor-dev/issues/582): Fixed: Double slash in the path to stylesheet needed by the [Table Selection](http://ckeditor.com/addon/tableselection) plugin. Thanks to [Marius Dumitru Florea](https://github.com/mflorea)! +* [#491](https://github.com/ckeditor/ckeditor-dev/issues/491): Fixed: Unnecessary dependency on the [Editor Toolbar](http://ckeditor.com/addon/toolbar) plugin inside the [Notification](http://ckeditor.com/addon/notification) plugin. +* [#646](https://github.com/ckeditor/ckeditor-dev/issues/646): Fixed: Error thrown into the browser console after opening the [Styles Combo](http://ckeditor.com/addon/stylescombo) plugin menu in the editor without any selection. +* [#501](https://github.com/ckeditor/ckeditor-dev/issues/501): Fixed: Double click does not open the dialog for modifying anchors inserted via the [Link](http://ckeditor.com/addon/link) plugin. +* [#9780](https://dev.ckeditor.com/ticket/9780): [IE8-9] Fixed: Clicking inside an empty [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) editor throws an error. +* [#16820](https://dev.ckeditor.com/ticket/16820): [IE10] Fixed: Clicking below a single horizontal rule throws an error. +* [#426](https://github.com/ckeditor/ckeditor-dev/issues/426): Fixed: The [`range.cloneContents`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) method selects the whole element when the selection starts at the beginning of that element. +* [#644](https://github.com/ckeditor/ckeditor-dev/issues/644): Fixed: The [`range.extractContents`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-extractContents) method returns an incorrect result when multiple nodes are selected. +* [#684](https://github.com/ckeditor/ckeditor-dev/issues/684): Fixed: The [`elementPath.contains`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.elementPath-method-contains) method incorrectly excludes the last element instead of root when the `fromTop` parameter is set to `true`. + +Other Changes: + +* Updated the [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type) plugin: + * [#148](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/148): Fixed: SCAYT leaves underlined word after the CKEditor Replace dialog corrects it. +* [#751](https://github.com/ckeditor/ckeditor-dev/issues/751): Added the [`CKEDITOR.dom.nodeList.toArray`](https://docs.ckeditor.com/#!/api/CKEDITOR.dom.nodeList-method-toArray) method which returns an array representation of a [node list](https://docs.ckeditor.com/#!/api/CKEDITOR.dom.nodeList). + +## CKEditor 4.7.1 + +New Features: + +* Added a new Mexican Spanish localization. Thanks to [David Alexandro Rodriguez](https://www.transifex.com/user/profile/darsco16/)! +* [#413](https://github.com/ckeditor/ckeditor-dev/issues/413): Added Paste as Plain Text keyboard shortcut to the [Accessibility Help](http://ckeditor.com/addon/a11yhelp) instructions. + +Fixed Issues: + +* [#515](https://github.com/ckeditor/ckeditor-dev/issues/515): [Chrome] Fixed: Mouse actions on CKEditor scrollbar throw an exception when the [Table Selection](http://ckeditor.com/addon/tableselection) plugin is loaded. +* [#493](https://github.com/ckeditor/ckeditor-dev/issues/493): Fixed: Selection started from a nested table causes an error in the browser while scrolling down. +* [#415](https://github.com/ckeditor/ckeditor-dev/issues/415): [Firefox] Fixed: Enter key breaks the table structure when pressed in a table selection. +* [#457](https://github.com/ckeditor/ckeditor-dev/issues/457): Fixed: Error thrown when deleting content from the editor with no selection. +* [#478](https://github.com/ckeditor/ckeditor-dev/issues/478): [Chrome] Fixed: Error thrown by the [Enter Key](http://ckeditor.com/addon/enterkey) plugin when pressing Enter with no selection. +* [#424](https://github.com/ckeditor/ckeditor-dev/issues/424): Fixed: Error thrown by [Tab Key Handling](http://ckeditor.com/addon/tab) and [Indent List](http://ckeditor.com/addon/indentlist) plugins when pressing Tab with no selection in inline editor. +* [#476](https://github.com/ckeditor/ckeditor-dev/issues/476): Fixed: Anchors inserted with the [Link](http://ckeditor.com/addon/link) plugin on collapsed selection cannot be edited. +* [#417](https://github.com/ckeditor/ckeditor-dev/issues/417): Fixed: The [Table Resize](http://ckeditor.com/addon/tableresize) plugin throws an error when used with a table with only header or footer rows. +* [#523](https://github.com/ckeditor/ckeditor-dev/issues/523): Fixed: The [`editor.getCommandKeystroke`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getCommandKeystroke) method does not obtain the correct keystroke. +* [#534](https://github.com/ckeditor/ckeditor-dev/issues/534): [IE] Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) does not work in Quirks Mode. +* [#450](https://github.com/ckeditor/ckeditor-dev/issues/450): Fixed: [`CKEDITOR.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter) incorrectly transforms the `margin` CSS property. + +## CKEditor 4.7 + +**Important Notes:** + +* [#13793](http://dev.ckeditor.com/ticket/13793): The [`embed_provider`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-embed_provider) configuration option for the [Media Embed](http://ckeditor.com/addon/embed) and [Semantic Media Embed](http://ckeditor.com/addon/embedsemantic) plugins is no longer preset by default. +* The [UI Color](http://ckeditor.com/addon/uicolor) plugin now uses a custom color picker instead of the `YUI 2.7.0` library which has some known vulnerabilities (it's a security precaution, there was no security issue in CKEditor due to the way it was used). + +New Features: + +* [#16755](http://dev.ckeditor.com/ticket/16755): Added the [Table Selection](http://ckeditor.com/addon/tableselection) plugin that lets you select and manipulate an arbitrary rectangular table fragment (a few cells, a row or a column). +* [#16961](http://dev.ckeditor.com/ticket/16961): Added support for pasting from Microsoft Excel. +* [#13381](http://dev.ckeditor.com/ticket/13381): Dynamic code evaluation call in [`CKEDITOR.template`](http://docs.ckeditor.com/#!/api/CKEDITOR.template) removed. CKEditor can now be used without the `unsafe-eval` Content Security Policy. Thanks to [Caridy Patiño](http://caridy.name)! +* [#16971](http://dev.ckeditor.com/ticket/16971): Added support for color in the `background` property containing also other styles for table cells in the [Table Tools](http://ckeditor.com/addon/tabletools) plugin. +* [#16847](http://dev.ckeditor.com/ticket/16847): Added support for parsing and inlining any formatting created using the Microsoft Word style system to the [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin. +* [#16818](http://dev.ckeditor.com/ticket/16818): Added table cell height parsing in the [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin. +* [#16850](http://dev.ckeditor.com/ticket/16850): Added a new [`config.enableContextMenu`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enableContextMenu) configuration option for enabling and disabling the [context menu](http://ckeditor.com/addon/contextmenu). +* [#16937](http://dev.ckeditor.com/ticket/16937): The `command` parameter in [CKEDITOR.editor.getCommandKeystroke](http://docs.ckeditor.dev/#!/api/CKEDITOR.editor-method-getCommandKeystroke) now also accepts a command name as an argument. +* [#17010](http://dev.ckeditor.com/ticket/17010): The [`CKEDITOR.dom.range.shrink`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-shrink) method now allows for skipping bogus `
` elements. + +Fixed Issues: + +* [#16935](http://dev.ckeditor.com/ticket/16935): [Chrome] Fixed: Blurring the editor in [Source Mode](http://ckeditor.com/addon/sourcearea) throws an error. +* [#16825](http://dev.ckeditor.com/ticket/16825): [Chrome] Fixed: Error thrown when destroying a focused inline editor. +* [#16857](http://dev.ckeditor.com/ticket/16857): Fixed: Ctrl+Shift+V blocked by [Copy Formatting](http://ckeditor.com/addon/copyformatting). +* [#16845](https://dev.ckeditor.com/ticket/16845): [IE] Fixed: Cursor jumps to the top of the scrolled editor after focusing it when the [Copy Formatting](http://ckeditor.com/addon/copyformatting) plugin is enabled. +* [#16786](http://dev.ckeditor.com/ticket/16786): Fixed: Added missing translations for the [Copy Formatting](http://ckeditor.com/addon/copyformatting) plugin. +* [#14714](http://dev.ckeditor.com/ticket/14714): [WebKit/Blink] Fixed: Exception thrown on refocusing a blurred inline editor. +* [#16913](http://dev.ckeditor.com/ticket/16913): [Firefox, IE] Fixed: [Paste as Plain Text](http://ckeditor.com/addon/pastetext) keystroke does not work. +* [#16968](http://dev.ckeditor.com/ticket/16968): Fixed: [Safari] [Paste as Plain Text](http://ckeditor.com/addon/pastetext) is not handled by the editor. +* [#16912](http://dev.ckeditor.com/ticket/16912): Fixed: Exception thrown when a single image is pasted using [Paste from Word](http://ckeditor.com/addon/pastefromword). +* [#16821](http://dev.ckeditor.com/ticket/16821): Fixed: Extraneous `` elements with `height` style stacked when [pasting from Word](http://ckeditor.com/addon/pastefromword). +* [#16866](http://dev.ckeditor.com/ticket/16866): [IE, Edge] Fixed: Whitespaces not preserved when [pasting from Word](http://ckeditor.com/addon/pastefromword). +* [#16860](http://dev.ckeditor.com/ticket/16860): Fixed: Paragraphs which only look like lists incorrectly transformed into them when [pasting from Word](http://ckeditor.com/addon/pastefromword). +* [#16817](http://dev.ckeditor.com/ticket/16817): Fixed: When [pasting from Word](http://ckeditor.com/addon/pastefromword), paragraphs are transformed into lists with some corrupted data. +* [#16833](http://dev.ckeditor.com/ticket/16833): [IE11] Fixed: Malformed list with headers [pasted from Word](http://ckeditor.com/addon/pastefromword). +* [#16826](http://dev.ckeditor.com/ticket/16826): [IE] Fixed: Superfluous paragraphs within lists [pasted from Word](http://ckeditor.com/addon/pastefromword). +* [#12465](http://dev.ckeditor.com/ticket/12465): Fixed: Cannot change the state of checkboxes or radio buttons if the properties dialog was invoked with a double-click. +* [#13062](http://dev.ckeditor.com/ticket/13062): Fixed: Impossible to unlink when the caret is at the edge of the link. +* [#13585](http://dev.ckeditor.com/ticket/13585): Fixed: Error when wrapping two adjacent `
` elements with a `
`. +* [#16811](http://dev.ckeditor.com/ticket/16811): Fixed: Table alignment is not preserved by the [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin. +* [#16810](http://dev.ckeditor.com/ticket/16810): Fixed: Vertical align in tables is not supported by the [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin. +* [#11956](http://dev.ckeditor.com/ticket/11956): [Blink, IE] Fixed: [Link](http://ckeditor.com/addon/link) dialog does not open on a double click on the second word of the link with a background color or other styles. +* [#10472](http://dev.ckeditor.com/ticket/10472): Fixed: Unable to use [Table Resize](http://ckeditor.com/addon/tableresize) on table header and footer. +* [#14762](http://dev.ckeditor.com/ticket/14762): Fixed: Hovering over an empty table (without rows or cells) throws an error when the [Table Resize](http://ckeditor.com/addon/tableresize) plugin is active. +* [#16777](https://dev.ckeditor.com/ticket/16777): [Edge] Fixed: The [Clipboard](http://ckeditor.com/addon/clipboard) plugin does not allow to drop widgets into the editor. +* [#14894](https://dev.ckeditor.com/ticket/14894): [Chrome] Fixed: The editor scrolls to the top after focusing or when a dialog is opened. +* [#14769](https://dev.ckeditor.com/ticket/14769): Fixed: URLs with '-' in host are not detected by the [Auto Link](http://ckeditor.com/addon/autolink) plugin. +* [#16804](https://dev.ckeditor.com/ticket/16804): Fixed: Focus is not on the first menu item when the user opens a context menu or a drop-down list from the editor toolbar. +* [#14407](https://dev.ckeditor.com/ticket/14407): [IE] Fixed: Non-editable widgets can be edited. +* [#16927](https://dev.ckeditor.com/ticket/16927): Fixed: An error thrown if a bundle containing the [Color Button](http://ckeditor.com/addon/colorbutton) plugin is run in ES5 strict mode. Thanks to [Igor Rubinovich](https://github.com/IgorRubinovich)! +* [#16920](http://dev.ckeditor.com/ticket/16920): Fixed: Several plugins not using the [Dialog](http://ckeditor.com/addon/dialog) plugin as a direct dependency. +* [PR#336](https://github.com/ckeditor/ckeditor-dev/pull/336): Fixed: Typo in [`CKEDITOR.getCss`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getCss) API documentation. Thanks to [knusperpixel](https://github.com/knusperpixel)! +* [#17027](http://dev.ckeditor.com/ticket/17027): Fixed: Command event data should be initialized as an empty object. +* Fixed the behavior of HTML parser when parsing `src`/`srcdoc` attributes of the `', ''); + $data[] = ['', '']; // IFRAME Event based. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#IFRAME_Event_based - $data[] = array('', ''); + $data[] = ['', '']; // FRAME. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#FRAME - $data[] = array('', ''); + $data[] = ['', '']; // TABLE. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#TABLE - $data[] = array('', '
'); + $data[] = ['
', '
']; // TD. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#TD - $data[] = array('
', '', 'Empty description found'); + + // Test that no error message is shown for other fields. + $this->drupalGet('admin/structure/views/nojs/add-handler/test_view_empty/default/field'); + $this->assertNoText('Error: missing help'); + } + + /** + * Asserts that fields only appear once. + * + * @param string $field_name + * The field name. + * @param string $entity_type + * The entity type to which the field belongs. + */ + public function assertNoDuplicateField($field_name, $entity_type) { + $elements = $this->xpath('//td[.=:entity_type]/preceding-sibling::td[@class="title" and .=:title]', [':title' => $field_name, ':entity_type' => $entity_type]); + $this->assertEqual(1, count($elements), $field_name . ' appears just once in ' . $entity_type . '.'); + } + +} diff --git a/core/modules/views_ui/tests/src/Functional/NewViewConfigSchemaTest.php b/core/modules/views_ui/tests/src/Functional/NewViewConfigSchemaTest.php new file mode 100644 index 00000000..ef493ff8 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/NewViewConfigSchemaTest.php @@ -0,0 +1,49 @@ +drupalLogin($this->drupalCreateUser(['administer views'])); + + // Create views with all core Views wizards. + $wizards = [ + // Wizard with their own classes. + 'node', + 'node_revision', + 'users', + 'comment', + 'file_managed', + 'taxonomy_term', + 'watchdog', + // Standard derivative classes. + 'standard:aggregator_feed', + 'standard:aggregator_item', + ]; + foreach ($wizards as $wizard_key) { + $edit = []; + $edit['label'] = $this->randomString(); + $edit['id'] = strtolower($this->randomMachineName()); + $edit['show[wizard_key]'] = $wizard_key; + $edit['description'] = $this->randomString(); + $this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit')); + } + } + +} diff --git a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php b/core/modules/views_ui/tests/src/Functional/OverrideDisplaysTest.php similarity index 90% rename from core/modules/views_ui/src/Tests/OverrideDisplaysTest.php rename to core/modules/views_ui/tests/src/Functional/OverrideDisplaysTest.php index 98576ad3..24116d97 100644 --- a/core/modules/views_ui/src/Tests/OverrideDisplaysTest.php +++ b/core/modules/views_ui/tests/src/Functional/OverrideDisplaysTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('page_title_block'); } @@ -18,7 +18,7 @@ protected function setUp() { /** * Tests that displays can be overridden via the UI. */ - function testOverrideDisplays() { + public function testOverrideDisplays() { // Create a basic view that shows all content, with a page and a block // display. $view['label'] = $this->randomMachineName(16); @@ -33,15 +33,15 @@ function testOverrideDisplays() { // same (empty) title in the views wizard, we expect the wizard to have set // things up so that they both inherit from the default display, and we // therefore only need to change that to have it take effect for both. - $edit = array(); + $edit = []; $edit['title'] = $original_title = $this->randomMachineName(16); $edit['override[dropdown]'] = 'default'; $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/title", $edit, t('Apply')); - $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/page_1", array(), t('Save')); + $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/page_1", [], t('Save')); // Add a node that will appear in the view, so that the block will actually // be displayed. - $this->drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); $this->drupalCreateNode(); // Make sure the title appears in the page. @@ -51,7 +51,7 @@ function testOverrideDisplays() { // Confirm that the view block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLinkPartialName('Place block'); + $this->clickLink('Place block'); $this->assertText($view['label']); // Place the block. @@ -63,11 +63,11 @@ function testOverrideDisplays() { // Change the title for the page display only, and make sure that the // original title still appears on the page. - $edit = array(); + $edit = []; $edit['title'] = $new_title = $this->randomMachineName(16); $edit['override[dropdown]'] = 'page_1'; $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/title", $edit, t('Apply')); - $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/page_1", array(), t('Save')); + $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/page_1", [], t('Save')); $this->drupalGet($view_path); $this->assertResponse(200); $this->assertText($new_title); @@ -77,7 +77,7 @@ function testOverrideDisplays() { /** * Tests that the wizard correctly sets up default and overridden displays. */ - function testWizardMixedDefaultOverriddenDisplays() { + public function testWizardMixedDefaultOverriddenDisplays() { // Create a basic view with a page, block, and feed. Give the page and feed // identical titles, but give the block a different one, so we expect the // page and feed to inherit their titles from the default display, but the @@ -95,7 +95,7 @@ function testWizardMixedDefaultOverriddenDisplays() { // Add a node that will appear in the view, so that the block will actually // be displayed. - $this->drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); $this->drupalCreateNode(); // Make sure that the feed, page and block all start off with the correct @@ -111,20 +111,20 @@ function testWizardMixedDefaultOverriddenDisplays() { // Confirm that the block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLinkPartialName('Place block'); + $this->clickLink('Place block'); $this->assertText($view['label']); // Put the block into the first sidebar region, and make sure it will not // display on the view's page display (since we will be searching for the // presence/absence of the view's title in both the page and the block). - $this->drupalPlaceBlock("views_block:{$view['id']}-block_1", array( - 'visibility' => array( - 'request_path' => array( + $this->drupalPlaceBlock("views_block:{$view['id']}-block_1", [ + 'visibility' => [ + 'request_path' => [ 'pages' => '/' . $view['page[path]'], 'negate' => TRUE, - ), - ), - )); + ], + ], + ]); $this->drupalGet(''); $this->assertText($view['block[title]']); @@ -132,10 +132,10 @@ function testWizardMixedDefaultOverriddenDisplays() { // Edit the page and change the title. This should automatically change // the feed's title also, but not the block. - $edit = array(); + $edit = []; $edit['title'] = $new_default_title = $this->randomMachineName(16); $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/title", $edit, t('Apply')); - $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/page_1", array(), t('Save')); + $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/page_1", [], t('Save')); $this->drupalGet($view['page[path]']); $this->assertResponse(200); $this->assertText($new_default_title); @@ -153,10 +153,10 @@ function testWizardMixedDefaultOverriddenDisplays() { // Edit the block and change the title. This should automatically change // the block title only, and leave the defaults alone. - $edit = array(); + $edit = []; $edit['title'] = $new_block_title = $this->randomMachineName(16); $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/block_1/title", $edit, t('Apply')); - $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/block_1", array(), t('Save')); + $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/block_1", [], t('Save')); $this->drupalGet($view['page[path]']); $this->assertResponse(200); $this->assertText($new_default_title); @@ -172,7 +172,7 @@ function testWizardMixedDefaultOverriddenDisplays() { /** * Tests that the revert to all displays select-option works as expected. */ - function testRevertAllDisplays() { + public function testRevertAllDisplays() { // Create a basic view with a page, block. // Because there is both a title on page and block we expect the title on // the block be overridden. @@ -187,12 +187,12 @@ function testRevertAllDisplays() { // Revert the title of the block to the default ones, but submit some new // values to be sure that the new value is not stored. - $edit = array(); + $edit = []; $edit['title'] = $new_block_title = $this->randomMachineName(); $edit['override[dropdown]'] = 'default_revert'; $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/block_1/title", $edit, t('Apply')); - $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/block_1", array(), t('Save')); + $this->drupalPostForm("admin/structure/views/view/{$view['id']}/edit/block_1", [], t('Save')); $this->assertText($view['page[title]']); } diff --git a/core/modules/views_ui/src/Tests/QueryTest.php b/core/modules/views_ui/tests/src/Functional/QueryTest.php similarity index 81% rename from core/modules/views_ui/src/Tests/QueryTest.php rename to core/modules/views_ui/tests/src/Functional/QueryTest.php index 351859bb..0eb58ce7 100644 --- a/core/modules/views_ui/src/Tests/QueryTest.php +++ b/core/modules/views_ui/tests/src/Functional/QueryTest.php @@ -1,6 +1,6 @@ randomMachineName(); - $this->drupalPostForm($query_settings_path, array('query[options][test_setting]' => $random_value), t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm($query_settings_path, ['query[options][test_setting]' => $random_value], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); // Check that the settings are saved into the view itself. $view = Views::getView('test_view'); diff --git a/core/modules/views_ui/src/Tests/RearrangeFieldsTest.php b/core/modules/views_ui/tests/src/Functional/RearrangeFieldsTest.php similarity index 93% rename from core/modules/views_ui/src/Tests/RearrangeFieldsTest.php rename to core/modules/views_ui/tests/src/Functional/RearrangeFieldsTest.php index 35c229bf..125a7e92 100644 --- a/core/modules/views_ui/src/Tests/RearrangeFieldsTest.php +++ b/core/modules/views_ui/tests/src/Functional/RearrangeFieldsTest.php @@ -1,6 +1,6 @@ setDisplay($display_id); - $fields = array(); + $fields = []; foreach ($view->displayHandlers->get('default')->getHandlers('field') as $field => $handler) { $fields[] = $field; } @@ -58,13 +58,13 @@ public function testRearrangeFields() { $this->assertFieldOrder($view_name, $this->getViewFields($view_name)); // Checks that a field is not deleted if a value is not passed back. - $fields = array(); + $fields = []; $this->drupalPostForm('admin/structure/views/nojs/rearrange/' . $view_name . '/default/field', $fields, t('Apply')); $this->assertFieldOrder($view_name, $this->getViewFields($view_name)); // Checks that revers the new field order is respected. $reversedFields = array_reverse($this->getViewFields($view_name)); - $fields = array(); + $fields = []; foreach ($reversedFields as $delta => $field) { $fields['fields[' . $field . '][weight]'] = $delta; } diff --git a/core/modules/views_ui/tests/src/Functional/RedirectTest.php b/core/modules/views_ui/tests/src/Functional/RedirectTest.php new file mode 100644 index 00000000..4df38cee --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/RedirectTest.php @@ -0,0 +1,45 @@ +randomMachineName(); + $edit_path = "admin/structure/views/view/$view_name/edit"; + + $this->drupalPostForm($edit_path, [], t('Save'), ['query' => ['destination' => $random_destination]]); + $this->assertUrl($random_destination, [], 'Make sure the user got redirected to the expected page defined in the destination.'); + + // Setup a view with a certain page display path. If you change the path + // but have the old url in the destination the user should be redirected to + // the new path. + $view_name = 'test_redirect_view'; + $new_path = $this->randomMachineName(); + + $edit_path = "admin/structure/views/view/$view_name/edit"; + $path_edit_path = "admin/structure/views/nojs/display/$view_name/page_1/path"; + + $this->drupalPostForm($path_edit_path, ['path' => $new_path], t('Apply')); + $this->drupalPostForm($edit_path, [], t('Save'), ['query' => ['destination' => 'test-redirect-view']]); + $this->assertUrl($new_path, [], 'Make sure the user got redirected to the expected page after changing the URL of a page display.'); + } + +} diff --git a/core/modules/views_ui/src/Tests/ReportFieldsTest.php b/core/modules/views_ui/tests/src/Functional/ReportFieldsTest.php similarity index 97% rename from core/modules/views_ui/src/Tests/ReportFieldsTest.php rename to core/modules/views_ui/tests/src/Functional/ReportFieldsTest.php index 9b2245e2..d2527d0b 100644 --- a/core/modules/views_ui/src/Tests/ReportFieldsTest.php +++ b/core/modules/views_ui/tests/src/Functional/ReportFieldsTest.php @@ -1,6 +1,6 @@ drupalLogin($this->adminUser); + + // Test the report page. + $this->drupalGet('admin/reports/views-plugins'); + $this->assertResponse(200, "Views report page exists"); + } + +} diff --git a/core/modules/views_ui/src/Tests/SettingsTest.php b/core/modules/views_ui/tests/src/Functional/SettingsTest.php similarity index 82% rename from core/modules/views_ui/src/Tests/SettingsTest.php rename to core/modules/views_ui/tests/src/Functional/SettingsTest.php index 30397f40..1ac98c6e 100644 --- a/core/modules/views_ui/src/Tests/SettingsTest.php +++ b/core/modules/views_ui/tests/src/Functional/SettingsTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('local_tasks_block'); } /** * Tests the settings for the edit ui. */ - function testEditUI() { + public function testEditUI() { $this->drupalLogin($this->adminUser); // Test the settings tab exists. @@ -35,16 +35,16 @@ function testEditUI() { $this->assertLinkByHref('admin/structure/views/settings'); // Test the confirmation message. - $this->drupalPostForm('admin/structure/views/settings', array(), t('Save configuration')); + $this->drupalPostForm('admin/structure/views/settings', [], t('Save configuration')); $this->assertText(t('The configuration options have been saved.')); // Configure to always show the master display. - $edit = array( + $edit = [ 'ui_show_master_display' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings', $edit, t('Save configuration')); - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['description'] = $this->randomMachineName(16); @@ -56,9 +56,9 @@ function testEditUI() { // Configure to not always show the master display. // If you have a view without a page or block the master display should be // still shown. - $edit = array( + $edit = [ 'ui_show_master_display' => FALSE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings', $edit, t('Save configuration')); $view['page[create]'] = FALSE; @@ -75,67 +75,67 @@ function testEditUI() { // @todo It doesn't seem to be a way to test this as this works just on js. // Configure to show the embeddable display. - $edit = array( + $edit = [ 'ui_show_display_embed' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings', $edit, t('Save configuration')); $view['id'] = strtolower($this->randomMachineName()); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - $this->assertFieldById('edit-displays-top-add-display-embed'); + $this->assertFieldById('edit-displays-top-add-display-embed', NULL); - $edit = array( + $edit = [ 'ui_show_display_embed' => FALSE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings', $edit, t('Save configuration')); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); $this->assertNoFieldById('edit-displays-top-add-display-embed'); // Configure to hide/show the sql at the preview. - $edit = array( + $edit = [ 'ui_show_sql_query_enabled' => FALSE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings', $edit, t('Save configuration')); $view['id'] = strtolower($this->randomMachineName()); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - $this->drupalPostForm(NULL, array(), t('Update preview')); + $this->drupalPostForm(NULL, [], t('Update preview')); $xpath = $this->xpath('//div[@class="views-query-info"]/pre'); $this->assertEqual(count($xpath), 0, 'The views sql is hidden.'); - $edit = array( + $edit = [ 'ui_show_sql_query_enabled' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings', $edit, t('Save configuration')); $view['id'] = strtolower($this->randomMachineName()); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - $this->drupalPostForm(NULL, array(), t('Update preview')); + $this->drupalPostForm(NULL, [], t('Update preview')); $xpath = $this->xpath('//div[@class="views-query-info"]//pre'); $this->assertEqual(count($xpath), 1, 'The views sql is shown.'); - $this->assertFalse(strpos($xpath[0], 'db_condition_placeholder') !== FALSE, 'No placeholders are shown in the views sql.'); - $this->assertTrue(strpos($xpath[0], "node_field_data.status = '1'") !== FALSE, 'The placeholders in the views sql is replace by the actual value.'); + $this->assertFalse(strpos($xpath[0]->getText(), 'db_condition_placeholder') !== FALSE, 'No placeholders are shown in the views sql.'); + $this->assertTrue(strpos($xpath[0]->getText(), "node_field_data.status = '1'") !== FALSE, 'The placeholders in the views sql is replace by the actual value.'); // Test the advanced settings form. // Test the confirmation message. - $this->drupalPostForm('admin/structure/views/settings/advanced', array(), t('Save configuration')); + $this->drupalPostForm('admin/structure/views/settings/advanced', [], t('Save configuration')); $this->assertText(t('The configuration options have been saved.')); - $edit = array( + $edit = [ 'skip_cache' => TRUE, 'sql_signature' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/views/settings/advanced', $edit, t('Save configuration')); $this->assertFieldChecked('edit-skip-cache', 'The skip_cache option is checked.'); $this->assertFieldChecked('edit-sql-signature', 'The sql_signature option is checked.'); // Test the "Clear Views' cache" button. - $this->drupalPostForm('admin/structure/views/settings/advanced', array(), t("Clear Views' cache")); + $this->drupalPostForm('admin/structure/views/settings/advanced', [], t("Clear Views' cache")); $this->assertText(t('The cache has been cleared.')); } diff --git a/core/modules/views_ui/tests/src/Functional/StorageTest.php b/core/modules/views_ui/tests/src/Functional/StorageTest.php new file mode 100644 index 00000000..df3d030e --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/StorageTest.php @@ -0,0 +1,56 @@ +save(); + + $edit = [ + 'label' => $this->randomMachineName(), + 'tag' => $this->randomMachineName(), + 'description' => $this->randomMachineName(30), + 'langcode' => 'fr', + ]; + + $this->drupalPostForm("admin/structure/views/nojs/edit-details/$view_name/default", $edit, t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); + + $view = Views::getView($view_name); + + foreach (['label', 'tag', 'description', 'langcode'] as $property) { + $this->assertEqual($view->storage->get($property), $edit[$property], format_string('Make sure the property @property got probably saved.', ['@property' => $property])); + } + } + +} diff --git a/core/modules/views_ui/tests/src/Functional/StyleTableTest.php b/core/modules/views_ui/tests/src/Functional/StyleTableTest.php new file mode 100644 index 00000000..d00df330 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/StyleTableTest.php @@ -0,0 +1,35 @@ +randomMachineName(16); + $view['id'] = strtolower($this->randomMachineName(16)); + $view['show[wizard_key]'] = 'node'; + $view['page[create]'] = TRUE; + $view['page[style][style_plugin]'] = 'table'; + $view['page[title]'] = $this->randomMachineName(16); + $view['page[path]'] = $view['id']; + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + + $view = Views::getView($view['id']); + $view->initHandlers(); + $this->assertEqual($view->field['title']->options['label'], 'Title', 'The field label for table styles is not empty.'); + } + +} diff --git a/core/modules/views_ui/src/Tests/StyleUITest.php b/core/modules/views_ui/tests/src/Functional/StyleUITest.php similarity index 88% rename from core/modules/views_ui/src/Tests/StyleUITest.php rename to core/modules/views_ui/tests/src/Functional/StyleUITest.php index f83cb039..1eb9c786 100644 --- a/core/modules/views_ui/src/Tests/StyleUITest.php +++ b/core/modules/views_ui/tests/src/Functional/StyleUITest.php @@ -1,6 +1,6 @@ drupalGet($style_plugin_url); $this->assertFieldByName('style[type]', 'default', 'The default style plugin selected in the UI should be unformatted list.'); - $edit = array( + $edit = [ 'style[type]' => 'test_style' - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply')); $this->assertFieldByName('style_options[test_option]', NULL, 'Make sure the custom settings form from the test plugin appears.'); $random_name = $this->randomMachineName(); - $edit = array( + $edit = [ 'style_options[test_option]' => $random_name - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply')); $this->drupalGet($style_options_url); $this->assertFieldByName('style_options[test_option]', $random_name, 'Make sure the custom settings form field has the expected value stored.'); - $this->drupalPostForm($view_edit_url, array(), t('Save')); + $this->drupalPostForm($view_edit_url, [], t('Save')); $this->assertLink(t('Test style plugin'), 0, 'Make sure the test style plugin is shown in the UI'); $view = Views::getView($view_name); @@ -56,8 +56,8 @@ public function testStyleUI() { // Test that fields are working correctly in the UI for style plugins when // a field row plugin is selected. - $this->drupalPostForm("admin/structure/views/view/$view_name/edit", array(), 'Add Page'); - $this->drupalPostForm("admin/structure/views/nojs/display/$view_name/page_1/row", array('row[type]' => 'fields'), t('Apply')); + $this->drupalPostForm("admin/structure/views/view/$view_name/edit", [], 'Add Page'); + $this->drupalPostForm("admin/structure/views/nojs/display/$view_name/page_1/row", ['row[type]' => 'fields'], t('Apply')); // If fields are being used this text will not be shown. $this->assertNoText(t('The selected style or row format does not use fields.')); } diff --git a/core/modules/views_ui/src/Tests/TokenizeAreaUITest.php b/core/modules/views_ui/tests/src/Functional/TokenizeAreaUITest.php similarity index 96% rename from core/modules/views_ui/src/Tests/TokenizeAreaUITest.php rename to core/modules/views_ui/tests/src/Functional/TokenizeAreaUITest.php index 38eb4756..df42d8e1 100644 --- a/core/modules/views_ui/src/Tests/TokenizeAreaUITest.php +++ b/core/modules/views_ui/tests/src/Functional/TokenizeAreaUITest.php @@ -1,6 +1,6 @@ enableViewsTestModule(); + + $this->adminUser = $this->drupalCreateUser(['administer views']); + + $this->fullAdminUser = $this->drupalCreateUser(['administer views', + 'administer blocks', + 'bypass node access', + 'access user profiles', + 'view all revisions', + 'administer permissions', + ]); + $this->drupalLogin($this->fullAdminUser); + } + + /** + * A helper method which creates a random view. + */ + public function randomView(array $view = []) { + // Create a new view in the UI. + $default = []; + $default['label'] = $this->randomMachineName(16); + $default['id'] = strtolower($this->randomMachineName(16)); + $default['description'] = $this->randomMachineName(16); + $default['page[create]'] = TRUE; + $default['page[path]'] = $default['id']; + + $view += $default; + + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + + return $default; + } + + /** + * {@inheritdoc} + */ + protected function drupalGet($path, array $options = [], array $headers = []) { + $url = $this->buildUrl($path, $options); + + // Ensure that each nojs page is accessible via ajax as well. + if (strpos($url, 'nojs') !== FALSE) { + $url = str_replace('nojs', 'ajax', $url); + $result = $this->drupalGet($url, $options); + $this->assertSession()->statusCodeEquals(200); + $this->assertEquals('application/json', $this->getSession()->getResponseHeader('Content-Type')); + $this->assertTrue(json_decode($result), 'Ensure that the AJAX request returned valid content.'); + } + + return parent::drupalGet($path, $options, $headers); + } + +} diff --git a/core/modules/views_ui/src/Tests/UnsavedPreviewTest.php b/core/modules/views_ui/tests/src/Functional/UnsavedPreviewTest.php similarity index 89% rename from core/modules/views_ui/src/Tests/UnsavedPreviewTest.php rename to core/modules/views_ui/tests/src/Functional/UnsavedPreviewTest.php index 4652daca..3265e1a2 100644 --- a/core/modules/views_ui/src/Tests/UnsavedPreviewTest.php +++ b/core/modules/views_ui/tests/src/Functional/UnsavedPreviewTest.php @@ -1,15 +1,13 @@ adminUser = $this->drupalCreateUser(['administer views']); diff --git a/core/modules/views_ui/src/Tests/ViewEditTest.php b/core/modules/views_ui/tests/src/Functional/ViewEditTest.php similarity index 79% rename from core/modules/views_ui/src/Tests/ViewEditTest.php rename to core/modules/views_ui/tests/src/Functional/ViewEditTest.php index afa21df6..94f9da81 100644 --- a/core/modules/views_ui/src/Tests/ViewEditTest.php +++ b/core/modules/views_ui/tests/src/Functional/ViewEditTest.php @@ -1,6 +1,6 @@ assertTrue($view instanceof View); $this->clickLink(t('Delete view')); $this->assertUrl('admin/structure/views/view/test_view/delete'); - $this->drupalPostForm(NULL, array(), t('Delete')); - $this->assertRaw(t('The view %name has been deleted.', array('%name' => $view->label()))); + $this->drupalPostForm(NULL, [], t('Delete')); + $this->assertRaw(t('The view %name has been deleted.', ['%name' => $view->label()])); $this->assertUrl('admin/structure/views'); $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view'); @@ -44,44 +44,55 @@ public function testDeleteLink() { public function testOtherOptions() { $this->drupalGet('admin/structure/views/view/test_view'); // Add a new attachment display. - $this->drupalPostForm(NULL, array(), 'Add Attachment'); + $this->drupalPostForm(NULL, [], 'Add Attachment'); // Test that a long administrative comment is truncated. - $edit = array('display_comment' => 'one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen'); + $edit = ['display_comment' => 'one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen']; $this->drupalPostForm('admin/structure/views/nojs/display/test_view/attachment_1/display_comment', $edit, 'Apply'); $this->assertText('one two three four five six seven eight nine ten eleven twelve thirteen fourteen...'); // Change the machine name for the display from page_1 to test_1. - $edit = array('display_id' => 'test_1'); + $edit = ['display_id' => 'test_1']; $this->drupalPostForm('admin/structure/views/nojs/display/test_view/attachment_1/display_id', $edit, 'Apply'); $this->assertLink(t('test_1')); // Save the view, and test the new ID has been saved. - $this->drupalPostForm(NULL, array(), 'Save'); + $this->drupalPostForm(NULL, [], 'Save'); $view = \Drupal::entityManager()->getStorage('view')->load('test_view'); $displays = $view->get('display'); $this->assertTrue(!empty($displays['test_1']), 'Display data found for new display ID key.'); $this->assertIdentical($displays['test_1']['id'], 'test_1', 'New display ID matches the display ID key.'); $this->assertFalse(array_key_exists('attachment_1', $displays), 'Old display ID not found.'); + // Set to the same machine name and save the View. + $edit = ['display_id' => 'test_1']; + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/test_1/display_id', $edit, 'Apply'); + $this->drupalPostForm(NULL, [], 'Save'); + $this->assertLink(t('test_1')); + // Test the form validation with invalid IDs. $machine_name_edit_url = 'admin/structure/views/nojs/display/test_view/test_1/display_id'; $error_text = t('Display name must be letters, numbers, or underscores only.'); // Test that potential invalid display ID requests are detected - $this->drupalGet('admin/structure/views/ajax/handler/test_view/fake_display_name/filter/title'); - $this->assertText('Invalid display id fake_display_name'); + try { + $this->drupalGet('admin/structure/views/ajax/handler/test_view/fake_display_name/filter/title'); + $this->fail('Expected error, when setDisplay() called with invalid display ID'); + } + catch (\Exception $e) { + $this->assertContains('setDisplay() called with invalid display ID "fake_display_name".', $e->getMessage()); + } - $edit = array('display_id' => 'test 1'); + $edit = ['display_id' => 'test 1']; $this->drupalPostForm($machine_name_edit_url, $edit, 'Apply'); $this->assertText($error_text); - $edit = array('display_id' => 'test_1#'); + $edit = ['display_id' => 'test_1#']; $this->drupalPostForm($machine_name_edit_url, $edit, 'Apply'); $this->assertText($error_text); // Test using an existing display ID. - $edit = array('display_id' => 'default'); + $edit = ['display_id' => 'default']; $this->drupalPostForm($machine_name_edit_url, $edit, 'Apply'); $this->assertText(t('Display id should be unique.')); @@ -97,32 +108,34 @@ public function testOtherOptions() { $fields['fields[id][removed]'] = 1; $fields['fields[name][removed]'] = 1; $this->drupalPostForm('admin/structure/views/nojs/rearrange/test_view/default/field', $fields, t('Apply')); - $this->drupalPostForm(NULL, array(), 'Save'); - $this->drupalPostForm(NULL, array(), t('Cancel')); + $this->drupalPostForm(NULL, [], 'Save'); + $this->drupalPostForm(NULL, [], t('Cancel')); $this->assertNoFieldByXpath('//div[contains(@class, "error")]', FALSE, 'No error message is displayed.'); - $this->assertUrl('admin/structure/views', array(), 'Redirected back to the view listing page..'); + $this->assertUrl('admin/structure/views', [], 'Redirected back to the view listing page..'); } /** * Tests the language options on the views edit form. */ public function testEditFormLanguageOptions() { + $assert_session = $this->assertSession(); + // Language options should not exist without language module. - $test_views = array( + $test_views = [ 'test_view' => 'default', 'test_display' => 'page_1', - ); + ]; foreach ($test_views as $view_name => $display) { $this->drupalGet('admin/structure/views/view/' . $view_name); $this->assertResponse(200); $langcode_url = 'admin/structure/views/nojs/display/' . $view_name . '/' . $display . '/rendering_language'; $this->assertNoLinkByHref($langcode_url); - $this->assertNoLink(t('@type language selected for page', array('@type' => t('Content')))); + $assert_session->linkNotExistsExact(t('@type language selected for page', ['@type' => t('Content')])); $this->assertNoLink(t('Content language of view row')); } // Make the site multilingual and test the options again. - $this->container->get('module_installer')->install(array('language', 'content_translation')); + $this->container->get('module_installer')->install(['language', 'content_translation']); ConfigurableLanguage::createFromLangcode('hu')->save(); $this->resetAll(); $this->rebuildContainer(); @@ -134,12 +147,12 @@ public function testEditFormLanguageOptions() { $langcode_url = 'admin/structure/views/nojs/display/' . $view_name . '/' . $display . '/rendering_language'; if ($view_name == 'test_view') { $this->assertNoLinkByHref($langcode_url); - $this->assertNoLink(t('@type language selected for page', array('@type' => t('Content')))); + $assert_session->linkNotExistsExact(t('@type language selected for page', ['@type' => t('Content')])); $this->assertNoLink(t('Content language of view row')); } else { $this->assertLinkByHref($langcode_url); - $this->assertNoLink(t('@type language selected for page', array('@type' => t('Content')))); + $assert_session->linkNotExistsExact(t('@type language selected for page', ['@type' => t('Content')])); $this->assertLink(t('Content language of view row')); } @@ -152,18 +165,18 @@ public function testEditFormLanguageOptions() { $this->assertFieldByName('rendering_language', '***LANGUAGE_entity_translation***'); // Test that the order of the language list is similar to other language // lists, such as in the content translation settings. - $expected_elements = array( + $expected_elements = [ '***LANGUAGE_entity_translation***', '***LANGUAGE_entity_default***', '***LANGUAGE_site_default***', '***LANGUAGE_language_interface***', 'en', 'hu', - ); + ]; $elements = $this->xpath('//select[@id="edit-rendering-language"]/option'); // Compare values inside the option elements with expected values. for ($i = 0; $i < count($elements); $i++) { - $this->assertEqual($elements[$i]->attributes()->{'value'}, $expected_elements[$i]); + $this->assertEqual($elements[$i]->getAttribute('value'), $expected_elements[$i]); } // Check that the selected values are respected even we they are not @@ -202,7 +215,7 @@ public function testEditFormLanguageOptions() { $this->drupalGet($langcode_url); $this->assertResponse(200); - $expected_elements = array( + $expected_elements = [ 'all', '***LANGUAGE_site_default***', '***LANGUAGE_language_interface***', @@ -211,11 +224,11 @@ public function testEditFormLanguageOptions() { 'hu', 'und', 'zxx', - ); + ]; $elements = $this->xpath('//div[@id="edit-options-value"]//input'); // Compare values inside the option elements with expected values. for ($i = 0; $i < count($elements); $i++) { - $this->assertEqual($elements[$i]->attributes()->{'value'}, $expected_elements[$i]); + $this->assertEqual($elements[$i]->getAttribute('value'), $expected_elements[$i]); } } } @@ -229,7 +242,7 @@ public function testRelationRepresentativeNode() { $edit["name[taxonomy_term_field_data.tid_representative]"] = TRUE; $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_groupwise_term_ui/default/relationship', $edit, 'Add and configure relationships'); // Apply changes. - $edit = array(); + $edit = []; $this->drupalPostForm('admin/structure/views/nojs/handler/test_groupwise_term_ui/default/relationship/tid_representative', $edit, 'Apply'); } diff --git a/core/modules/views_ui/src/Tests/ViewsListTest.php b/core/modules/views_ui/tests/src/Functional/ViewsListTest.php similarity index 86% rename from core/modules/views_ui/src/Tests/ViewsListTest.php rename to core/modules/views_ui/tests/src/Functional/ViewsListTest.php index 768e449d..956ab9bc 100644 --- a/core/modules/views_ui/src/Tests/ViewsListTest.php +++ b/core/modules/views_ui/tests/src/Functional/ViewsListTest.php @@ -1,8 +1,7 @@ drupalPlaceBlock('local_tasks_block'); $this->drupalPlaceBlock('local_actions_block'); diff --git a/core/modules/views_ui/src/Tests/ViewsUITourTest.php b/core/modules/views_ui/tests/src/Functional/ViewsUITourTest.php similarity index 85% rename from core/modules/views_ui/src/Tests/ViewsUITourTest.php rename to core/modules/views_ui/tests/src/Functional/ViewsUITourTest.php index ccc0f296..839fe3a4 100644 --- a/core/modules/views_ui/src/Tests/ViewsUITourTest.php +++ b/core/modules/views_ui/tests/src/Functional/ViewsUITourTest.php @@ -1,8 +1,8 @@ adminUser = $this->drupalCreateUser(array('administer views', 'access tour')); + $this->adminUser = $this->drupalCreateUser(['administer views', 'access tour']); $this->drupalLogin($this->adminUser); } @@ -66,18 +66,18 @@ public function testViewsUiTourTipsTranslated() { ConfigurableLanguage::createFromLangcode($langcode)->save(); // Handler titles that need translations. - $handler_titles = array( + $handler_titles = [ 'Format', 'Fields', 'Sort criteria', 'Filter criteria', - ); + ]; foreach ($handler_titles as $handler_title) { // Create source string. - $source = $this->localeStorage->createString(array( + $source = $this->localeStorage->createString([ 'source' => $handler_title - )); + ]); $source->save(); $this->createTranslation($source, $langcode); } @@ -101,11 +101,11 @@ public function testViewsUiTourTipsTranslated() { * Creates single translation for source string. */ public function createTranslation($source, $langcode) { - return $this->localeStorage->createTranslation(array( + return $this->localeStorage->createTranslation([ 'lid' => $source->lid, 'language' => $langcode, 'translation' => $this->randomMachineName(100), - ))->save(); + ])->save(); } } diff --git a/core/modules/views_ui/tests/src/Functional/WizardTest.php b/core/modules/views_ui/tests/src/Functional/WizardTest.php new file mode 100644 index 00000000..81154817 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/WizardTest.php @@ -0,0 +1,62 @@ +randomMachineName(256); + $view['id'] = strtolower($this->randomMachineName(129)); + $view['page[create]'] = TRUE; + $view['page[path]'] = $this->randomMachineName(255); + $view['page[title]'] = $this->randomMachineName(256); + $view['page[feed]'] = TRUE; + $view['page[feed_properties][path]'] = $this->randomMachineName(255); + $view['block[create]'] = TRUE; + $view['block[title]'] = $this->randomMachineName(256); + $view['rest_export[create]'] = TRUE; + $view['rest_export[path]'] = $this->randomMachineName(255); + + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + + $this->assertText('Machine-readable name cannot be longer than 128 characters but is currently 129 characters long.'); + $this->assertText('Path cannot be longer than 254 characters but is currently 255 characters long.'); + $this->assertText('Page title cannot be longer than 255 characters but is currently 256 characters long.'); + $this->assertText('View name cannot be longer than 255 characters but is currently 256 characters long.'); + $this->assertText('Feed path cannot be longer than 254 characters but is currently 255 characters long.'); + $this->assertText('Block title cannot be longer than 255 characters but is currently 256 characters long.'); + $this->assertText('REST export path cannot be longer than 254 characters but is currently 255 characters long.'); + + $view['label'] = $this->randomMachineName(255); + $view['id'] = strtolower($this->randomMachineName(128)); + $view['page[create]'] = TRUE; + $view['page[path]'] = $this->randomMachineName(254); + $view['page[title]'] = $this->randomMachineName(255); + $view['page[feed]'] = TRUE; + $view['page[feed_properties][path]'] = $this->randomMachineName(254); + $view['block[create]'] = TRUE; + $view['block[title]'] = $this->randomMachineName(255); + $view['rest_export[create]'] = TRUE; + $view['rest_export[path]'] = $this->randomMachineName(254); + + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + $this->assertUrl('admin/structure/views/view/' . $view['id'], [], 'Make sure the view saving was successful and the browser got redirected to the edit page.'); + // Assert that the page title is correctly truncated. + $this->assertText(views_ui_truncate($view['page[title]'], 32)); + } + +} diff --git a/core/modules/views_ui/src/Tests/XssTest.php b/core/modules/views_ui/tests/src/Functional/XssTest.php similarity index 79% rename from core/modules/views_ui/src/Tests/XssTest.php rename to core/modules/views_ui/tests/src/Functional/XssTest.php index 8eac3a68..cabb48eb 100644 --- a/core/modules/views_ui/src/Tests/XssTest.php +++ b/core/modules/views_ui/tests/src/Functional/XssTest.php @@ -1,6 +1,6 @@ drupalGet('admin/structure/views'); - $this->assertEscaped(', test', 'The view tag is properly escaped.'); - $this->drupalGet('admin/structure/views/view/sa_contrib_2013_035'); $this->assertEscaped('test', 'Field admin label is properly escaped.'); diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php new file mode 100644 index 00000000..c8d37f21 --- /dev/null +++ b/core/modules/views_ui/tests/src/FunctionalJavascript/DisplayTest.php @@ -0,0 +1,125 @@ +drupalCreateUser([ + 'administer site configuration', + 'administer views', + 'administer nodes', + 'access content overview', + 'access contextual links', + ]); + + // Disable automatic live preview to make the sequence of calls clearer. + \Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save(); + $this->drupalLogin($admin_user); + } + + /** + * Tests adding a display. + */ + public function testAddDisplay() { + $this->drupalGet('admin/structure/views/view/test_content_ajax'); + $page = $this->getSession()->getPage(); + + $page->find('css', '#views-display-menu-tabs .add')->click(); + + // Wait for the animation to complete. + $this->assertSession()->assertWaitOnAjaxRequest(); + + // Add the diplay. + $page->find('css', '#edit-displays-top-add-display-block')->click(); + + $element = $page->findById('views-display-menu-tabs')->findLink('Block'); + $this->assertNotEmpty($element); + } + + /** + * Tests contextual links on Views page displays. + */ + public function testPageContextualLinks() { + $view = View::load('test_display'); + $view->enable()->save(); + $this->container->get('router.builder')->rebuildIfNeeded(); + + // Create node so the view has content and the contextual area is higher + // than 0 pixels. + $this->drupalCreateContentType(['type' => 'page']); + $this->createNode(); + + // When no "main content" block is placed, we find a contextual link + // placeholder for editing just the view. + $this->drupalGet('test-display'); + $page = $this->getSession()->getPage(); + $this->assertSession()->assertWaitOnAjaxRequest(); + + $selector = '.view-test-display'; + $this->toggleContextualTriggerVisibility($selector); + + $element = $this->getSession()->getPage()->find('css', $selector); + $element->find('css', '.contextual button')->press(); + + $contextual_container_id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en'; + $contextual_container = $page->find('css', '[data-contextual-id="' . $contextual_container_id . '"]'); + $this->assertNotEmpty($contextual_container); + + $edit_link = $contextual_container->findLink('Edit view'); + $this->assertNotEmpty($edit_link); + + // When a "main content" is placed, we still find a contextual link + // placeholder for editing just the view (not the main content block). + // @see system_block_view_system_main_block_alter() + $this->drupalPlaceBlock('system_main_block', ['id' => 'main_content']); + $contextual_container = $page->find('css', '[data-contextual-id="' . $contextual_container_id . '"]'); + $this->assertNotEmpty($contextual_container); + } + + /** + * Toggles the visibility of a contextual trigger. + * + * @param string $selector + * The selector for the element that contains the contextual Rink. + */ + protected function toggleContextualTriggerVisibility($selector) { + // Hovering over the element itself with should be enough, but does not + // work. Manually remove the visually-hidden class. + $this->getSession()->executeScript("jQuery('{$selector} .contextual .trigger').toggleClass('visually-hidden');"); + } + +} diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/FilterOptionsTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/FilterOptionsTest.php new file mode 100644 index 00000000..32b1a400 --- /dev/null +++ b/core/modules/views_ui/tests/src/FunctionalJavascript/FilterOptionsTest.php @@ -0,0 +1,76 @@ +drupalCreateUser([ + 'administer views', + ]); + $this->drupalLogin($admin_user); + } + + /** + * Tests filtering options in the 'Add fields' dialog. + */ + public function testFilterOptionsAddFields() { + $this->drupalGet('admin/structure/views/view/content'); + + $session = $this->getSession(); + $web_assert = $this->assertSession(); + $page = $session->getPage(); + + // Open the dialog. + $page->clickLink('views-add-field'); + + // Wait for the popup to open and the search field to be available. + $options_search = $web_assert->waitForField('override[controls][options_search]'); + + // Test that the both special fields are visible. + $this->assertTrue($page->findField('name[views.views_test_field_1]')->isVisible()); + $this->assertTrue($page->findField('name[views.views_test_field_2]')->isVisible()); + + // Test the ".title" field in search. + $options_search->setValue('FIELD_1_TITLE'); + $page->waitFor(10, function () use ($page) { + return !$page->findField('name[views.views_test_field_2]')->isVisible(); + }); + $this->assertTrue($page->findField('name[views.views_test_field_1]')->isVisible()); + $this->assertFalse($page->findField('name[views.views_test_field_2]')->isVisible()); + + // Test the ".description" field in search. + $options_search->setValue('FIELD_2_DESCRIPTION'); + $page->waitFor(10, function () use ($page) { + return !$page->findField('name[views.views_test_field_1]')->isVisible(); + }); + $this->assertTrue($page->findField('name[views.views_test_field_2]')->isVisible()); + $this->assertFalse($page->findField('name[views.views_test_field_1]')->isVisible()); + + // Test the "label" field not in search. + $options_search->setValue('FIELD_1_LABEL'); + $page->waitFor(10, function () use ($page) { + return !$page->findField('name[views.views_test_field_2]')->isVisible(); + }); + $this->assertFalse($page->findField('name[views.views_test_field_2]')->isVisible()); + $this->assertFalse($page->findField('name[views.views_test_field_1]')->isVisible()); + } + +} diff --git a/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php b/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php index c39db77b..cab99bd7 100644 --- a/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php +++ b/core/modules/views_ui/tests/src/FunctionalJavascript/ViewsListingTest.php @@ -34,6 +34,10 @@ protected function setUp() { * Tests the filtering on the Views listing page. */ public function testFilterViewsListing() { + $enabled_views_count = 6; + $disabled_views_count = 2; + $content_views_count = 3; + $this->drupalGet('admin/structure/views'); $session = $this->assertSession(); @@ -47,8 +51,8 @@ public function testFilterViewsListing() { $disabled_rows = $this->filterVisibleElements($disabled_rows); // Test that we see some rows of views in both tables. - $this->assertCount(6, $enabled_rows); - $this->assertCount(2, $disabled_rows); + $this->assertCount($enabled_views_count, $enabled_rows); + $this->assertCount($disabled_views_count, $disabled_rows); // Filter on the string 'people'. This should only show the people view. $search_input = $page->find('css', '.views-filter-text.form-search'); @@ -70,8 +74,8 @@ public function testFilterViewsListing() { $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled'); $disabled_rows = $this->filterVisibleElements($disabled_rows); - $this->assertCount(3, $enabled_rows); - $this->assertCount(2, $disabled_rows); + $this->assertCount($content_views_count, $enabled_rows); + $this->assertCount($disabled_views_count, $disabled_rows); // Reset the search string and check that we are back to the initial stage. $search_input->setValue(''); @@ -83,8 +87,8 @@ public function testFilterViewsListing() { $disabled_rows = $page->findAll('css', 'tr.views-ui-list-disabled'); $disabled_rows = $this->filterVisibleElements($disabled_rows); - $this->assertCount(6, $enabled_rows); - $this->assertCount(2, $disabled_rows); + $this->assertCount($enabled_views_count, $enabled_rows); + $this->assertCount($disabled_views_count, $disabled_rows); // Disable a View and see if it moves to the disabled listing. $enabled_view = $page->find('css', 'tr.views-ui-list-enabled'); @@ -103,8 +107,8 @@ public function testFilterViewsListing() { $disabled_rows = $this->filterVisibleElements($disabled_rows); // Test that one enabled View has been moved to the disabled list. - $this->assertCount(5, $enabled_rows); - $this->assertCount(3, $disabled_rows); + $this->assertCount($enabled_views_count - 1, $enabled_rows); + $this->assertCount($disabled_views_count + 1, $disabled_rows); } /** @@ -114,7 +118,7 @@ public function testFilterViewsListing() { * @return array */ protected function filterVisibleElements($elements) { - $elements = array_filter($elements, function($element) { + $elements = array_filter($elements, function ($element) { return $element->isVisible(); }); return $elements; diff --git a/core/modules/views_ui/tests/src/Kernel/TagTest.php b/core/modules/views_ui/tests/src/Kernel/TagTest.php index fda2e285..e63bf228 100644 --- a/core/modules/views_ui/tests/src/Kernel/TagTest.php +++ b/core/modules/views_ui/tests/src/Kernel/TagTest.php @@ -19,7 +19,7 @@ class TagTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('views', 'views_ui', 'user'); + public static $modules = ['views', 'views_ui', 'user']; /** * Tests the views_ui_autocomplete_tag function. @@ -28,15 +28,15 @@ public function testViewsUiAutocompleteTag() { \Drupal::moduleHandler()->loadInclude('views_ui', 'inc', 'admin'); // Save 15 views with a tag. - $tags = array(); + $tags = []; for ($i = 0; $i < 16; $i++) { $suffix = $i % 2 ? 'odd' : 'even'; $tag = 'autocomplete_tag_test_' . $suffix . $this->randomMachineName(); $tags[] = $tag; - View::create(array('tag' => $tag, 'id' => $this->randomMachineName()))->save(); + View::create(['tag' => $tag, 'id' => $this->randomMachineName()])->save(); } - // Make sure just ten results are returns. + // Make sure just ten results are returned. $controller = ViewsUIController::create($this->container); $request = $this->container->get('request_stack')->getCurrentRequest(); $request->query->set('q', 'autocomplete_tag_test'); @@ -46,7 +46,7 @@ public function testViewsUiAutocompleteTag() { // Make sure the returned array has the proper format. $suggestions = array_map(function ($tag) { - return array('value' => $tag, 'label' => Html::escape($tag)); + return ['value' => $tag, 'label' => Html::escape($tag)]; }, $tags); foreach ($matches as $match) { $this->assertTrue(in_array($match, $suggestions), 'Make sure the returned array has the proper format.'); @@ -59,7 +59,7 @@ public function testViewsUiAutocompleteTag() { $matches = (array) json_decode($result->getContent(), TRUE); $this->assertEqual(count($matches), 8, 'Make sure that only a subset is returned.'); foreach ($matches as $tag) { - $this->assertTrue(array_search($tag['value'], $tags) !== FALSE, format_string('Make sure the returned tag @tag actually exists.', array('@tag' => $tag['value']))); + $this->assertTrue(array_search($tag['value'], $tags) !== FALSE, format_string('Make sure the returned tag @tag actually exists.', ['@tag' => $tag['value']])); } // Make sure an invalid result doesn't return anything. diff --git a/core/modules/views_ui/tests/src/Unit/Form/Ajax/RearrangeFilterTest.php b/core/modules/views_ui/tests/src/Unit/Form/Ajax/RearrangeFilterTest.php index bb8eb773..b2d3f96a 100644 --- a/core/modules/views_ui/tests/src/Unit/Form/Ajax/RearrangeFilterTest.php +++ b/core/modules/views_ui/tests/src/Unit/Form/Ajax/RearrangeFilterTest.php @@ -17,8 +17,8 @@ class RearrangeFilterTest extends UnitTestCase { */ public function testStaticMethods() { // Test the RearrangeFilter::arrayKeyPlus method. - $original = array(0 => 'one', 1 => 'two', 2 => 'three'); - $expected = array(1 => 'one', 2 => 'two', 3 => 'three'); + $original = [0 => 'one', 1 => 'two', 2 => 'three']; + $expected = [1 => 'one', 2 => 'two', 3 => 'three']; $this->assertSame(RearrangeFilter::arrayKeyPlus($original), $expected); } diff --git a/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php b/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php index 215728cd..23cc7a8e 100644 --- a/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php +++ b/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php @@ -38,54 +38,54 @@ public function testBuildRowEntityList() { $display_manager->expects($this->any()) ->method('getDefinition') - ->will($this->returnValueMap(array( - array( + ->will($this->returnValueMap([ + [ 'default', TRUE, - array( + [ 'id' => 'default', 'title' => 'Master', 'theme' => 'views_view', 'no_ui' => TRUE, 'admin' => '', - ) - ), - array( + ] + ], + [ 'page', TRUE, - array( + [ 'id' => 'page', 'title' => 'Page', 'uses_menu_links' => TRUE, 'uses_route' => TRUE, - 'contextual_links_locations' => array('page'), + 'contextual_links_locations' => ['page'], 'theme' => 'views_view', 'admin' => 'Page admin label', - ) - ), - array( + ] + ], + [ 'embed', TRUE, - array( + [ 'id' => 'embed', 'title' => 'embed', 'theme' => 'views_view', 'admin' => 'Embed admin label', - ) - ), - ))); + ] + ], + ])); $default_display = $this->getMock('Drupal\views\Plugin\views\display\DefaultDisplay', - array('initDisplay'), - array(array(), 'default', $display_manager->getDefinition('default')) + ['initDisplay'], + [[], 'default', $display_manager->getDefinition('default')] ); $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface'); $state = $this->getMock('\Drupal\Core\State\StateInterface'); $menu_storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface'); $page_display = $this->getMock('Drupal\views\Plugin\views\display\Page', - array('initDisplay', 'getPath'), - array(array(), 'default', $display_manager->getDefinition('page'), $route_provider, $state, $menu_storage) + ['initDisplay', 'getPath'], + [[], 'default', $display_manager->getDefinition('page'), $route_provider, $state, $menu_storage] ); $page_display->expects($this->any()) ->method('getPath') @@ -94,11 +94,11 @@ public function testBuildRowEntityList() { $this->returnValue('malformed_path'), $this->returnValue(''))); - $embed_display = $this->getMock('Drupal\views\Plugin\views\display\Embed', array('initDisplay'), - array(array(), 'default', $display_manager->getDefinition('embed')) + $embed_display = $this->getMock('Drupal\views\Plugin\views\display\Embed', ['initDisplay'], + [[], 'default', $display_manager->getDefinition('embed')] ); - $values = array(); + $values = []; $values['status'] = FALSE; $values['display']['default']['id'] = 'default'; $values['display']['default']['display_title'] = 'Display'; @@ -125,13 +125,13 @@ public function testBuildRowEntityList() { $display_manager->expects($this->any()) ->method('createInstance') - ->will($this->returnValueMap(array( - array('default', $values['display']['default'], $default_display), - array('page', $values['display']['page_1'], $page_display), - array('page', $values['display']['page_2'], $page_display), - array('page', $values['display']['page_3'], $page_display), - array('embed', $values['display']['embed'], $embed_display), - ))); + ->will($this->returnValueMap([ + ['default', $values['display']['default'], $default_display], + ['page', $values['display']['page_1'], $page_display], + ['page', $values['display']['page_2'], $page_display], + ['page', $values['display']['page_3'], $page_display], + ['embed', $values['display']['embed'], $embed_display], + ])); $container = new ContainerBuilder(); $user = $this->getMock('Drupal\Core\Session\AccountInterface'); @@ -152,21 +152,34 @@ public function testBuildRowEntityList() { $view_list_builder = new TestViewListBuilder($entity_type, $storage, $display_manager); $view_list_builder->setStringTranslation($this->getStringTranslationStub()); + // Create new view with test values. $view = new View($values, 'view'); + // Get the row object created by ViewListBuilder for this test view. $row = $view_list_builder->buildRow($view); - $expected_displays = array( - 'Embed admin label', - 'Page admin label', - 'Page admin label', - 'Page admin label', - ); - $this->assertEquals($expected_displays, $row['data']['view_name']['data']['#displays']); - - $display_paths = $row['data']['path']['data']['#items']; - // These values will be escaped by Twig when rendered. - $this->assertEquals('/test_page, /malformed_path, /', implode(', ', $display_paths)); + // Expected output array for view's displays. + $expected_displays = [ + '0' => [ + 'display' => 'Embed admin label', + 'path' => FALSE, + ], + '1' => [ + 'display' => 'Page admin label', + 'path' => '/malformed_path', + ], + '2' => [ + 'display' => 'Page admin label', + 'path' => '/', + ], + '3' => [ + 'display' => 'Page admin label', + 'path' => '/test_page', + ], + ]; + + // Compare the expected and generated output. + $this->assertEquals($expected_displays, $row['data']['displays']['data']['#displays']); } } @@ -174,7 +187,7 @@ public function testBuildRowEntityList() { class TestViewListBuilder extends ViewListBuilder { public function buildOperations(EntityInterface $entity) { - return array(); + return []; } } diff --git a/core/modules/views_ui/tests/src/Unit/ViewUIObjectTest.php b/core/modules/views_ui/tests/src/Unit/ViewUIObjectTest.php index 293bfebe..f49b25a9 100644 --- a/core/modules/views_ui/tests/src/Unit/ViewUIObjectTest.php +++ b/core/modules/views_ui/tests/src/Unit/ViewUIObjectTest.php @@ -18,14 +18,14 @@ class ViewUIObjectTest extends UnitTestCase { * Tests entity method decoration. */ public function testEntityDecoration() { - $method_args = array(); - $method_args['setOriginalId'] = array(12); - $method_args['setStatus'] = array(TRUE); - $method_args['enforceIsNew'] = array(FALSE); - $method_args['label'] = array(LanguageInterface::LANGCODE_NOT_SPECIFIED); + $method_args = []; + $method_args['setOriginalId'] = [12]; + $method_args['setStatus'] = [TRUE]; + $method_args['enforceIsNew'] = [FALSE]; + $method_args['label'] = [LanguageInterface::LANGCODE_NOT_SPECIFIED]; $reflection = new \ReflectionClass('Drupal\Core\Config\Entity\ConfigEntityInterface'); - $interface_methods = array(); + $interface_methods = []; foreach ($reflection->getMethods() as $reflection_method) { $interface_methods[] = $reflection_method->getName(); @@ -38,15 +38,15 @@ public function testEntityDecoration() { // dependency management. if (!in_array($reflection_method->getName(), ['isNew', 'isSyncing', 'isUninstalling', 'getConfigDependencyKey', 'getConfigDependencyName', 'calculateDependencies'])) { if (count($reflection_method->getParameters()) == 0) { - $method_args[$reflection_method->getName()] = array(); + $method_args[$reflection_method->getName()] = []; } } } - $storage = $this->getMock('Drupal\views\Entity\View', $interface_methods, array(array(), 'view')); + $storage = $this->getMock('Drupal\views\Entity\View', $interface_methods, [[], 'view']); $executable = $this->getMockBuilder('Drupal\views\ViewExecutable') ->disableOriginalConstructor() - ->setConstructorArgs(array($storage)) + ->setConstructorArgs([$storage]) ->getMock(); $storage->set('executable', $executable); @@ -58,7 +58,7 @@ public function testEntityDecoration() { foreach ($args as $arg) { $method_mock->with($this->equalTo($arg)); } - call_user_func_array(array($view_ui, $method), $args); + call_user_func_array([$view_ui, $method], $args); } $storage->expects($this->once()) @@ -70,10 +70,10 @@ public function testEntityDecoration() { * Tests the isLocked method. */ public function testIsLocked() { - $storage = $this->getMock('Drupal\views\Entity\View', array(), array(array(), 'view')); + $storage = $this->getMock('Drupal\views\Entity\View', [], [[], 'view']); $executable = $this->getMockBuilder('Drupal\views\ViewExecutable') ->disableOriginalConstructor() - ->setConstructorArgs(array($storage)) + ->setConstructorArgs([$storage]) ->getMock(); $storage->set('executable', $executable); $account = $this->getMock('Drupal\Core\Session\AccountInterface'); @@ -91,20 +91,20 @@ public function testIsLocked() { $this->assertFalse($view_ui->isLocked()); // Set the lock object with a different owner than the mocked account above. - $lock = (object) array( + $lock = (object) [ 'owner' => 2, - 'data' => array(), + 'data' => [], 'updated' => (int) $_SERVER['REQUEST_TIME'], - ); + ]; $view_ui->lock = $lock; $this->assertTrue($view_ui->isLocked()); // Set a different lock object with the same object as the mocked account. - $lock = (object) array( + $lock = (object) [ 'owner' => 1, - 'data' => array(), + 'data' => [], 'updated' => (int) $_SERVER['REQUEST_TIME'], - ); + ]; $view_ui->lock = $lock; $this->assertFalse($view_ui->isLocked()); } diff --git a/core/modules/views_ui/views_ui.info.yml b/core/modules/views_ui/views_ui.info.yml index 3bacf048..f911a5d3 100644 --- a/core/modules/views_ui/views_ui.info.yml +++ b/core/modules/views_ui/views_ui.info.yml @@ -8,8 +8,8 @@ configure: entity.view.collection dependencies: - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module index b51d2bbf..15f85e3a 100644 --- a/core/modules/views_ui/views_ui.module +++ b/core/modules/views_ui/views_ui.module @@ -19,15 +19,15 @@ function views_ui_help($route_name, RouteMatchInterface $route_match) { case 'help.page.views_ui': $output = ''; $output .= '

' . t('About') . '

'; - $output .= '

' . t('The Views UI module provides an interface for managing views for the Views module. For more information, see the online documentation for the Views UI module.', array(':views' => \Drupal::url('help.page', array('name' => 'views')), ':handbook' => 'https://www.drupal.org/documentation/modules/views_ui')) . '

'; + $output .= '

' . t('The Views UI module provides an interface for managing views for the Views module. For more information, see the online documentation for the Views UI module.', [':views' => \Drupal::url('help.page', ['name' => 'views']), ':handbook' => 'https://www.drupal.org/documentation/modules/views_ui']) . '

'; $output .= '

' . t('Uses') . '

'; $output .= '
'; $output .= '
' . t('Creating and managing views') . '
'; - $output .= '
' . t('Views can be created from the Views list page by using the "Add view" action. Existing views can be managed from the Views list page by locating the view in the "Enabled" or "Disabled" list and selecting the desired operation action, for example "Edit".', array(':list' => \Drupal::url('entity.view.collection', array('name' => 'views_ui')))) . '
'; + $output .= '
' . t('Views can be created from the Views list page by using the "Add view" action. Existing views can be managed from the Views list page by locating the view in the "Enabled" or "Disabled" list and selecting the desired operation action, for example "Edit".', [':list' => \Drupal::url('entity.view.collection', ['name' => 'views_ui'])]) . '
'; $output .= '
' . t('Enabling and disabling views') . '
'; - $output .= '
' . t('Views can be enabled or disabled from the Views list page. To enable a view, find the view within the "Disabled" list and select the "Enable" operation. To disable a view find the view within the "Enabled" list and select the "Disable" operation.', array(':list' => \Drupal::url('entity.view.collection', array('name' => 'views_ui')))) . '
'; + $output .= '
' . t('Views can be enabled or disabled from the Views list page. To enable a view, find the view within the "Disabled" list and select the "Enable" operation. To disable a view find the view within the "Enabled" list and select the "Disable" operation.', [':list' => \Drupal::url('entity.view.collection', ['name' => 'views_ui'])]) . '
'; $output .= '
' . t('Exporting and importing views') . '
'; - $output .= '
' . t('Views can be exported and imported as configuration files by using the Configuration Manager module.', array(':config' => (\Drupal::moduleHandler()->moduleExists('config')) ? \Drupal::url('help.page', array('name' => 'config')) : '#')) . '
'; + $output .= '
' . t('Views can be exported and imported as configuration files by using the Configuration Manager module.', [':config' => (\Drupal::moduleHandler()->moduleExists('config')) ? \Drupal::url('help.page', ['name' => 'config']) : '#']) . '
'; $output .= '
'; return $output; } @@ -61,56 +61,69 @@ function views_ui_entity_type_build(array &$entity_types) { * Implements hook_theme(). */ function views_ui_theme() { - return array( + return [ // edit a view - 'views_ui_display_tab_setting' => array( - 'variables' => array('description' => '', 'link' => '', 'settings_links' => array(), 'overridden' => FALSE, 'defaulted' => FALSE, 'description_separator' => TRUE, 'class' => array()), + 'views_ui_display_tab_setting' => [ + 'variables' => ['description' => '', 'link' => '', 'settings_links' => [], 'overridden' => FALSE, 'defaulted' => FALSE, 'description_separator' => TRUE, 'class' => []], 'file' => 'views_ui.theme.inc', - ), - 'views_ui_display_tab_bucket' => array( + ], + 'views_ui_display_tab_bucket' => [ 'render element' => 'element', 'file' => 'views_ui.theme.inc', - ), - 'views_ui_rearrange_filter_form' => array( + ], + 'views_ui_rearrange_filter_form' => [ 'render element' => 'form', 'file' => 'views_ui.theme.inc', - ), - 'views_ui_expose_filter_form' => array( + ], + 'views_ui_expose_filter_form' => [ 'render element' => 'form', 'file' => 'views_ui.theme.inc', - ), + ], - // list views - 'views_ui_view_info' => array( - 'variables' => array('view' => NULL, 'displays' => NULL), + // Legacy theme hook for displaying views info. + 'views_ui_view_info' => [ + 'variables' => ['view' => NULL, 'displays' => NULL], 'file' => 'views_ui.theme.inc', - ), + ], + + // List views. + 'views_ui_views_listing_table' => [ + 'variables' => [ + 'headers' => NULL, + 'rows' => NULL, + 'attributes' => [], + ], + 'file' => 'views_ui.theme.inc', + ], + 'views_ui_view_displays_list' => [ + 'variables' => ['displays' => []], + ], // Group of filters. - 'views_ui_build_group_filter_form' => array( + 'views_ui_build_group_filter_form' => [ 'render element' => 'form', 'file' => 'views_ui.theme.inc', - ), + ], // On behalf of a plugin - 'views_ui_style_plugin_table' => array( + 'views_ui_style_plugin_table' => [ 'render element' => 'form', 'file' => 'views_ui.theme.inc', - ), + ], // When previewing a view. - 'views_ui_view_preview_section' => array( - 'variables' => array('view' => NULL, 'section' => NULL, 'content' => NULL, 'links' => ''), + 'views_ui_view_preview_section' => [ + 'variables' => ['view' => NULL, 'section' => NULL, 'content' => NULL, 'links' => ''], 'file' => 'views_ui.theme.inc', - ), + ], // Generic container wrapper, to use instead of theme_container when an id // is not desired. - 'views_ui_container' => array( - 'variables' => array('children' => NULL, 'attributes' => array()), + 'views_ui_container' => [ + 'variables' => ['children' => NULL, 'attributes' => []], 'file' => 'views_ui.theme.inc', - ), - ); + ], + ]; } /** @@ -128,16 +141,16 @@ function views_ui_preprocess_views_view(&$variables) { if (!empty($view->live_preview) && \Drupal::moduleHandler()->moduleExists('contextual')) { $view->setShowAdminLinks(FALSE); - foreach (array('title', 'header', 'exposed', 'rows', 'pager', 'more', 'footer', 'empty', 'attachment_after', 'attachment_before') as $section) { + foreach (['title', 'header', 'exposed', 'rows', 'pager', 'more', 'footer', 'empty', 'attachment_after', 'attachment_before'] as $section) { if (!empty($variables[$section])) { - $variables[$section] = array( + $variables[$section] = [ '#theme' => 'views_ui_view_preview_section', '#view' => $view, '#section' => $section, '#content' => $variables[$section], - '#theme_wrappers' => array('views_ui_container'), - '#attributes' => array('class' => array('contextual-region')), - ); + '#theme_wrappers' => ['views_ui_container'], + '#attributes' => ['class' => ['contextual-region']], + ]; } } } @@ -156,28 +169,28 @@ function views_ui_preprocess_views_view(&$variables) { function views_ui_view_preview_section_handler_links(ViewExecutable $view, $type, $title = FALSE) { $display = $view->display_handler->display; $handlers = $view->display_handler->getHandlers($type); - $links = array(); + $links = []; $types = ViewExecutable::getHandlerTypes(); if ($title) { - $links[$type . '-title'] = array( + $links[$type . '-title'] = [ 'title' => $types[$type]['title'], - ); + ]; } foreach ($handlers as $id => $handler) { $field_name = $handler->adminLabel(TRUE); - $links[$type . '-edit-' . $id] = array( - 'title' => t('Edit @section', array('@section' => $field_name)), + $links[$type . '-edit-' . $id] = [ + 'title' => t('Edit @section', ['@section' => $field_name]), 'url' => Url::fromRoute('views_ui.form_handler', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id]), - 'attributes' => array('class' => array('views-ajax-link')), - ); + 'attributes' => ['class' => ['views-ajax-link']], + ]; } - $links[$type . '-add'] = array( + $links[$type . '-add'] = [ 'title' => t('Add new'), 'url' => Url::fromRoute('views_ui.form_add_handler', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type]), - 'attributes' => array('class' => array('views-ajax-link')), - ); + 'attributes' => ['class' => ['views-ajax-link']], + ]; return $links; } @@ -187,13 +200,13 @@ function views_ui_view_preview_section_handler_links(ViewExecutable $view, $type */ function views_ui_view_preview_section_display_category_links(ViewExecutable $view, $type, $title) { $display = $view->display_handler->display; - $links = array( - $type . '-edit' => array( - 'title' => t('Edit @section', array('@section' => $title)), + $links = [ + $type . '-edit' => [ + 'title' => t('Edit @section', ['@section' => $title]), 'url' => Url::fromRoute('views_ui.form_display', ['js' => 'nojs', 'view' => $view->storage->id(), 'display_id' => $display['id'], 'type' => $type]), - 'attributes' => array('class' => array('views-ajax-link')), - ), - ); + 'attributes' => ['class' => ['views-ajax-link']], + ], + ]; return $links; } @@ -202,7 +215,7 @@ function views_ui_view_preview_section_display_category_links(ViewExecutable $vi * Returns all contextual links for the main content part of the view. */ function views_ui_view_preview_section_rows_links(ViewExecutable $view) { - $links = array(); + $links = []; $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'filter', TRUE)); $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'field', TRUE)); $links = array_merge($links, views_ui_view_preview_section_handler_links($view, 'sort', TRUE)); @@ -220,10 +233,10 @@ function views_ui_views_plugins_display_alter(&$plugins) { // paths underneath "admin/structure/views/view/{$view->id()}" (i.e., paths // for editing and performing other contextual actions on the view). foreach ($plugins as &$display) { - $display['contextual links']['entity.view.edit_form'] = array( + $display['contextual links']['entity.view.edit_form'] = [ 'route_name' => 'entity.view.edit_form', - 'route_parameters_names' => array('view' => 'id'), - ); + 'route_parameters_names' => ['view' => 'id'], + ]; } } @@ -234,7 +247,7 @@ function views_ui_contextual_links_view_alter(&$element, $items) { // Remove contextual links from being rendered, when so desired, such as // within a View preview. if (views_ui_contextual_links_suppress()) { - $element['#links'] = array(); + $element['#links'] = []; } // Append the display ID to the Views UI edit links, so that clicking on the // contextual link takes you directly to the correct display tab on the edit @@ -292,7 +305,7 @@ function views_ui_contextual_links_suppress_pop() { * node.views.inc as well. */ function views_ui_views_analyze(ViewExecutable $view) { - $ret = array(); + $ret = []; // Check for something other than the default display: if (count($view->displayHandlers) < 2) { $ret[] = Analyzer::formatMessage(t('This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display.'), 'warning'); @@ -307,7 +320,7 @@ function views_ui_views_analyze(ViewExecutable $view) { if ($display->hasPath() && $path = $display->getOption('path')) { $normal_path = \Drupal::service('path.alias_manager')->getPathByAlias($path); if ($path != $normal_path) { - $ret[] = Analyzer::formatMessage(t('You have configured display %display with a path which is an path alias as well. This might lead to unwanted effects so better use an internal path.', array('%display' => $display->display['display_title'])), 'warning'); + $ret[] = Analyzer::formatMessage(t('You have configured display %display with a path which is an path alias as well. This might lead to unwanted effects so better use an internal path.', ['%display' => $display->display['display_title']]), 'warning'); } } } diff --git a/core/modules/views_ui/views_ui.theme.inc b/core/modules/views_ui/views_ui.theme.inc index 3b586789..e6ef8756 100644 --- a/core/modules/views_ui/views_ui.theme.inc +++ b/core/modules/views_ui/views_ui.theme.inc @@ -11,6 +11,7 @@ use Drupal\Core\Render\Element; use Drupal\Core\Render\Element\Checkboxes; use Drupal\Core\Render\Element\Radios; use Drupal\Core\Url; +use Drupal\Core\Template\Attribute; /** * Prepares variables for Views UI display tab setting templates. @@ -42,6 +43,31 @@ function template_preprocess_views_ui_display_tab_setting(&$variables) { } } +/** + * Prepares variables for Views UI view listing templates. + * + * Default template: views-ui-view-listing-table.html.twig. + * + * @param array $variables + * An associative array containing: + * - headers: An associative array containing the headers for the view + * listing table. + * - rows: An associative array containing the rows data for the view + * listing table. + */ +function template_preprocess_views_ui_views_listing_table(&$variables) { + // Convert the attributes to valid attribute objects. + foreach ($variables['headers'] as $key => $header) { + $variables['headers'][$key]['attributes'] = new Attribute($header['#attributes']); + } + + if (!empty($variables['rows'])) { + foreach ($variables['rows'] as $key => $row) { + $variables['rows'][$key]['attributes'] = new Attribute($row['#attributes']); + } + } +} + /** * Prepares variables for Views UI display tab bucket templates. * @@ -63,7 +89,7 @@ function template_preprocess_views_ui_display_tab_bucket(&$variables) { $variables['overridden'] = isset($element['#overridden']) ? $element['#overridden'] : NULL; $variables['content'] = $element['#children']; $variables['title'] = $element['#title']; - $variables['actions'] = !empty($element['#actions']) ? $element['#actions'] : array(); + $variables['actions'] = !empty($element['#actions']) ? $element['#actions'] : []; } /** @@ -79,14 +105,14 @@ function template_preprocess_views_ui_build_group_filter_form(&$variables) { $form = $variables['form']; // Prepare table of options. - $header = array( + $header = [ t('Default'), t('Weight'), t('Label'), t('Operator'), t('Value'), t('Operations'), - ); + ]; // Prepare default selectors. $form_state = new FormState(); @@ -94,15 +120,15 @@ function template_preprocess_views_ui_build_group_filter_form(&$variables) { $form['default_group_multiple'] = Checkboxes::processCheckboxes($form['default_group_multiple'], $form_state, $form); $form['default_group']['All']['#title'] = ''; - $rows[] = array( + $rows[] = [ ['data' => $form['default_group']['All']], '', - array( + [ 'data' => \Drupal::config('views.settings')->get('ui.exposed_filter_any_label') == 'old_any' ? t('<Any>') : t('- Any -'), 'colspan' => 4, - 'class' => array('class' => 'any-default-radios-row'), - ), - ); + 'class' => ['class' => 'any-default-radios-row'], + ], + ]; // Remove the 'All' default_group form element because it's added to the // table row. unset($variables['form']['default_group']['All']); @@ -135,32 +161,32 @@ function template_preprocess_views_ui_build_group_filter_form(&$variables) { '#title' => SafeMarkup::format('@text', ['@text' => t('Remove')]), ]; $remove = [$form['group_items'][$group_id]['remove'], $link]; - $data = array( + $data = [ 'default' => ['data' => $default], 'weight' => ['data' => $form['group_items'][$group_id]['weight']], 'title' => ['data' => $form['group_items'][$group_id]['title']], 'operator' => ['data' => $form['group_items'][$group_id]['operator']], 'value' => ['data' => $form['group_items'][$group_id]['value']], 'remove' => ['data' => $remove], - ); - $rows[] = array('data' => $data, 'id' => 'views-row-' . $group_id, 'class' => array('draggable')); + ]; + $rows[] = ['data' => $data, 'id' => 'views-row-' . $group_id, 'class' => ['draggable']]; } - $variables['table'] = array( + $variables['table'] = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, - '#attributes' => array( - 'class' => array('views-filter-groups'), + '#attributes' => [ + 'class' => ['views-filter-groups'], 'id' => 'views-filter-groups', - ), - '#tabledrag' => array( - array( + ], + '#tabledrag' => [ + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'weight', - ) - ), - ); + ] + ], + ]; // Hide fields used in table. unset($variables['form']['group_items']); @@ -177,7 +203,7 @@ function template_preprocess_views_ui_build_group_filter_form(&$variables) { */ function template_preprocess_views_ui_rearrange_filter_form(&$variables) { $form = &$variables['form']; - $rows = $ungroupable_rows = array(); + $rows = $ungroupable_rows = []; // Enable grouping only if > 1 group. $variables['grouping'] = count(array_keys($form['#group_options'])) > 1; @@ -186,41 +212,41 @@ function template_preprocess_views_ui_rearrange_filter_form(&$variables) { if ($group_id !== 'ungroupable') { // Set up tabledrag so that it changes the group dropdown when rows are // dragged between groups. - $options = array( + $options = [ 'table_id' => 'views-rearrange-filters', 'action' => 'match', 'relationship' => 'sibling', 'group' => 'views-group-select', 'subgroup' => 'views-group-select-' . $group_id, - ); + ]; drupal_attach_tabledrag($form['override'], $options); // Title row, spanning all columns. - $row = array(); + $row = []; // Add a cell to the first row, containing the group operator. - $row[] = array( - 'class' => array('group', 'group-operator', 'container-inline'), + $row[] = [ + 'class' => ['group', 'group-operator', 'container-inline'], 'data' => $form['filter_groups']['groups'][$group_id], - 'rowspan' => max(array(2, count($contents) + 1)), - ); + 'rowspan' => max([2, count($contents) + 1]), + ]; // Title. - $row[] = array( - 'class' => array('group', 'group-title'), - 'data' => array( + $row[] = [ + 'class' => ['group', 'group-title'], + 'data' => [ '#prefix' => '', '#markup' => $form['#group_options'][$group_id], '#suffix' => '', - ), + ], 'colspan' => 4, - ); - $rows[] = array( - 'class' => array('views-group-title'), + ]; + $rows[] = [ + 'class' => ['views-group-title'], 'data' => $row, 'id' => 'views-group-title-' . $group_id, - ); + ]; // Row which will only appear if the group has nothing in it. - $row = array(); + $row = []; $class = 'group-' . (count($contents) ? 'populated' : 'empty'); $instructions = '' . t('No filters have been added.') . '' . t('Drag to add filters.') . ''; // When JavaScript is enabled, the button for removing the group (if it's @@ -229,63 +255,63 @@ function template_preprocess_views_ui_rearrange_filter_form(&$variables) { if (!empty($form['remove_groups'][$group_id]['#type']) && $form['remove_groups'][$group_id]['#type'] == 'submit') { $form['remove_groups'][$group_id]['#attributes']['class'][] = 'js-hide'; } - $row[] = array( + $row[] = [ 'colspan' => 5, - 'data' => array( - array('#markup' => $instructions), + 'data' => [ + ['#markup' => $instructions], $form['remove_groups'][$group_id], - ), - ); - $rows[] = array( - 'class' => array( + ], + ]; + $rows[] = [ + 'class' => [ 'group-message', 'group-' . $group_id . '-message', $class, - ), + ], 'data' => $row, 'id' => 'views-group-' . $group_id, - ); + ]; } foreach ($contents as $id) { if (isset($form['filters'][$id]['name'])) { - $row = array(); + $row = []; $row[]['data'] = $form['filters'][$id]['name']; - $form['filters'][$id]['weight']['#attributes']['class'] = array('weight'); + $form['filters'][$id]['weight']['#attributes']['class'] = ['weight']; $row[]['data'] = $form['filters'][$id]['weight']; - $form['filters'][$id]['group']['#attributes']['class'] = array('views-group-select views-group-select-' . $group_id); + $form['filters'][$id]['group']['#attributes']['class'] = ['views-group-select views-group-select-' . $group_id]; $row[]['data'] = $form['filters'][$id]['group']; $form['filters'][$id]['removed']['#attributes']['class'][] = 'js-hide'; - $remove_link = array( + $remove_link = [ '#type' => 'link', '#url' => Url::fromRoute(''), - '#title' => SafeMarkup::format('@text', array('@text' => t('Remove'))), + '#title' => SafeMarkup::format('@text', ['@text' => t('Remove')]), '#weight' => '1', - '#options' => array( - 'attributes' => array( + '#options' => [ + 'attributes' => [ 'id' => 'views-remove-link-' . $id, - 'class' => array( + 'class' => [ 'views-hidden', 'views-button-remove', 'views-groups-remove-link', 'views-remove-link', - ), + ], 'alt' => t('Remove this item'), 'title' => t('Remove this item'), - ), - ), - ); - $row[]['data'] = array( + ], + ], + ]; + $row[]['data'] = [ $form['filters'][$id]['removed'], $remove_link, - ); + ]; - $row = array( + $row = [ 'data' => $row, - 'class' => array('draggable'), + 'class' => ['draggable'], 'id' => 'views-row-' . $id, - ); + ]; if ($group_id !== 'ungroupable') { $rows[] = $row; @@ -302,56 +328,56 @@ function template_preprocess_views_ui_rearrange_filter_form(&$variables) { } if (!empty($ungroupable_rows)) { - $header = array( + $header = [ t('Ungroupable filters'), t('Weight'), - array( + [ 'data' => t('Group'), - 'class' => array('views-hide-label'), - ), - array( + 'class' => ['views-hide-label'], + ], + [ 'data' => t('Remove'), - 'class' => array('views-hide-label'), - ), - ); - $variables['ungroupable_table'] = array( + 'class' => ['views-hide-label'], + ], + ]; + $variables['ungroupable_table'] = [ '#type' => 'table', '#header' => $header, '#rows' => $ungroupable_rows, - '#attributes' => array( + '#attributes' => [ 'id' => 'views-rearrange-filters-ungroupable', - 'class' => array('arrange'), - ), - '#tabledrag' => array( - array( + 'class' => ['arrange'], + ], + '#tabledrag' => [ + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'weight', - ) - ), - ); + ] + ], + ]; } if (empty($rows)) { - $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2')); + $rows[] = [['data' => t('No fields available.'), 'colspan' => '2']]; } // Set up tabledrag so that the weights are changed when rows are dragged. - $variables['table'] = array( + $variables['table'] = [ '#type' => 'table', '#rows' => $rows, - '#attributes' => array( + '#attributes' => [ 'id' => 'views-rearrange-filters', - 'class' => array('arrange'), - ), - '#tabledrag' => array( - array( + 'class' => ['arrange'], + ], + '#tabledrag' => [ + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'weight', - ), - ), - ); + ], + ], + ]; // When JavaScript is enabled, the button for adding a new group should be // hidden, since it will be replaced by a link on the client side. @@ -371,72 +397,72 @@ function template_preprocess_views_ui_rearrange_filter_form(&$variables) { function template_preprocess_views_ui_style_plugin_table(&$variables) { $form = $variables['form']; - $header = array( + $header = [ t('Field'), t('Column'), t('Align'), t('Separator'), - array( + [ 'data' => t('Sortable'), 'align' => 'center', - ), - array( + ], + [ 'data' => t('Default order'), 'align' => 'center', - ), - array( + ], + [ 'data' => t('Default sort'), 'align' => 'center', - ), - array( + ], + [ 'data' => t('Hide empty column'), 'align' => 'center', - ), - array( + ], + [ 'data' => t('Responsive'), 'align' => 'center', - ), - ); - $rows = array(); + ], + ]; + $rows = []; foreach (Element::children($form['columns']) as $id) { - $row = array(); + $row = []; $row[]['data'] = $form['info'][$id]['name']; $row[]['data'] = $form['columns'][$id]; $row[]['data'] = $form['info'][$id]['align']; $row[]['data'] = $form['info'][$id]['separator']; if (!empty($form['info'][$id]['sortable'])) { - $row[] = array( + $row[] = [ 'data' => $form['info'][$id]['sortable'], 'align' => 'center', - ); - $row[] = array( + ]; + $row[] = [ 'data' => $form['info'][$id]['default_sort_order'], 'align' => 'center', - ); - $row[] = array( + ]; + $row[] = [ 'data' => $form['default'][$id], 'align' => 'center', - ); + ]; } else { $row[] = ''; $row[] = ''; $row[] = ''; } - $row[] = array( + $row[] = [ 'data' => $form['info'][$id]['empty_column'], 'align' => 'center', - ); - $row[] = array( + ]; + $row[] = [ 'data' => $form['info'][$id]['responsive'], 'align' => 'center', - ); + ]; $rows[] = $row; } // Add the special 'None' row. - $rows[] = array(array('data' => t('None'), 'colspan' => 6), array('align' => 'center', 'data' => $form['default'][-1]), array('colspan' => 2)); + $rows[] = [['data' => t('None'), 'colspan' => 6], ['align' => 'center', 'data' => $form['default'][-1]], ['colspan' => 2]]; // Unset elements from the form array that are used to build the table so that // they are not rendered twice. @@ -444,12 +470,12 @@ function template_preprocess_views_ui_style_plugin_table(&$variables) { unset($form['info']); unset($form['columns']); - $variables['table'] = array( + $variables['table'] = [ '#type' => 'table', '#theme' => 'table__views_ui_style_plugin_table', '#header' => $header, '#rows' => $rows, - ); + ]; $variables['form'] = $form; } @@ -510,14 +536,14 @@ function template_preprocess_views_ui_view_preview_section(&$variables) { } if (isset($links)) { - $build = array( + $build = [ '#theme' => 'links__contextual', '#links' => $links, - '#attributes' => array('class' => array('contextual-links')), - '#attached' => array( - 'library' => array('contextual/drupal.contextual-links'), - ), - ); + '#attributes' => ['class' => ['contextual-links']], + '#attached' => [ + 'library' => ['contextual/drupal.contextual-links'], + ], + ]; $variables['links'] = $build; } } @@ -526,5 +552,5 @@ function template_preprocess_views_ui_view_preview_section(&$variables) { * Implements hook_theme_suggestions_HOOK(). */ function views_ui_theme_suggestions_views_ui_view_preview_section(array $variables) { - return array('views_ui_view_preview_section__' . $variables['section']); + return ['views_ui_view_preview_section__' . $variables['section']]; } diff --git a/core/modules/workflows/config/schema/workflows.schema.yml b/core/modules/workflows/config/schema/workflows.schema.yml new file mode 100644 index 00000000..42a5d972 --- /dev/null +++ b/core/modules/workflows/config/schema/workflows.schema.yml @@ -0,0 +1,44 @@ +workflows.workflow.*: + type: config_entity + label: 'Workflow' + mapping: + id: + type: string + label: 'ID' + label: + type: label + label: 'Label' + type: + type: string + label: 'Workflow type' + type_settings: + type: workflow.type_settings.[%parent.type] + +workflows.state: + type: mapping + mapping: + label: + type: label + label: 'Label' + weight: + type: integer + label: 'Weight' + +workflows.transition: + type: mapping + mapping: + label: + type: label + label: 'Transition label' + from: + type: sequence + label: 'From state IDs' + sequence: + type: string + label: 'From state ID' + to: + type: string + label: 'To state ID' + weight: + type: integer + label: 'Weight' diff --git a/core/modules/workflows/src/Annotation/WorkflowType.php b/core/modules/workflows/src/Annotation/WorkflowType.php new file mode 100644 index 00000000..496a9b82 --- /dev/null +++ b/core/modules/workflows/src/Annotation/WorkflowType.php @@ -0,0 +1,69 @@ +getTypePlugin(); + $missing_states = array_diff($workflow_type->getRequiredStates(), array_keys($this->getTypePlugin()->getStates())); + if (!empty($missing_states)) { + throw new RequiredStateMissingException(sprintf("Workflow type '{$workflow_type->label()}' requires states with the ID '%s' in workflow '{$this->id()}'", implode("', '", $missing_states))); + } + parent::preSave($storage); + } + + /** + * {@inheritdoc} + */ + public function getTypePlugin() { + return $this->getPluginCollection()->get($this->type); + } + + /** + * {@inheritdoc} + */ + public function getPluginCollections() { + return ['type_settings' => $this->getPluginCollection()]; + } + + /** + * Encapsulates the creation of the workflow's plugin collection. + * + * @return \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection + * The workflow's plugin collection. + */ + protected function getPluginCollection() { + if (!$this->pluginCollection && $this->type) { + $this->pluginCollection = new DefaultSingleLazyPluginCollection(\Drupal::service('plugin.manager.workflows.type'), $this->type, $this->type_settings); + } + return $this->pluginCollection; + } + + /** + * Loads all workflows of the provided type. + * + * @param string $type + * The workflow type to load all workflows for. + * + * @return static[] + * An array of workflow objects of the provided workflow type, indexed by + * their IDs. + * + * @see \Drupal\workflows\Annotation\WorkflowType + */ + public static function loadMultipleByType($type) { + return self::loadMultiple(\Drupal::entityQuery('workflow')->condition('type', $type)->execute()); + } + + /** + * {@inheritdoc} + */ + public function status() { + // In order for a workflow to be usable it must have at least one state. + return !empty($this->status) && !empty($this->getTypePlugin()->getStates()); + } + + /** + * {@inheritdoc} + */ + public function onDependencyRemoval(array $dependencies) { + // Give the parent method and the workflow type plugin a chance to react + // to removed dependencies and report if either of these two made a change. + $parent_changed_entity = parent::onDependencyRemoval($dependencies); + $plugin_changed_entity = $this->getTypePlugin()->onDependencyRemoval($dependencies); + return $plugin_changed_entity || $parent_changed_entity; + } + +} diff --git a/core/modules/workflows/src/Exception/RequiredStateMissingException.php b/core/modules/workflows/src/Exception/RequiredStateMissingException.php new file mode 100644 index 00000000..7e88bbfe --- /dev/null +++ b/core/modules/workflows/src/Exception/RequiredStateMissingException.php @@ -0,0 +1,11 @@ +workflowTypePluginManager = $workflow_type_plugin_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin.manager.workflows.type') + ); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#maxlength' => 255, + '#default_value' => $workflow->label(), + '#required' => TRUE, + ]; + + $form['id'] = [ + '#type' => 'machine_name', + '#default_value' => $workflow->id(), + '#machine_name' => [ + 'exists' => [Workflow::class, 'load'], + ], + ]; + + $workflow_types = array_column($this->workflowTypePluginManager->getDefinitions(), 'label', 'id'); + + $form['workflow_type'] = [ + '#type' => 'select', + '#title' => $this->t('Workflow type'), + '#required' => TRUE, + '#options' => $workflow_types, + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $return = $workflow->save(); + if (empty($workflow->getTypePlugin()->getStates())) { + drupal_set_message($this->t('Created the %label Workflow. In order for the workflow to be enabled there needs to be at least one state.', [ + '%label' => $workflow->label(), + ])); + $form_state->setRedirectUrl($workflow->toUrl('add-state-form')); + } + else { + drupal_set_message($this->t('Created the %label Workflow.', [ + '%label' => $workflow->label(), + ])); + $form_state->setRedirectUrl($workflow->toUrl('edit-form')); + } + return $return; + } + + /** + * {@inheritdoc} + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + // This form can only set the workflow's ID, label and the weights for each + // state. + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $values = $form_state->getValues(); + $entity->set('label', $values['label']); + $entity->set('id', $values['id']); + $entity->set('type', $values['workflow_type']); + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowDeleteForm.php b/core/modules/workflows/src/Form/WorkflowDeleteForm.php new file mode 100644 index 00000000..e122f405 --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowDeleteForm.php @@ -0,0 +1,62 @@ +entity->getTypePlugin()->workflowHasData($this->entity)) { + $form['#title'] = $this->getQuestion(); + $form['description'] = ['#markup' => $this->t('This workflow is in use. You cannot remove this workflow until you have removed all content using it.')]; + return $form; + } + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->t('Are you sure you want to delete %name?', ['%name' => $this->entity->label()]); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return new Url('entity.workflow.collection'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->entity->delete(); + + drupal_set_message($this->t( + 'Workflow %label deleted.', + ['%label' => $this->entity->label()] + )); + + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowEditForm.php b/core/modules/workflows/src/Form/WorkflowEditForm.php new file mode 100644 index 00000000..889b7bbf --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowEditForm.php @@ -0,0 +1,277 @@ +pluginFormFactory = $pluginFormFactory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin_form.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + $form['#title'] = $this->t('Edit %label workflow', ['%label' => $workflow->label()]); + + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#maxlength' => 255, + '#default_value' => $workflow->label(), + '#required' => TRUE, + ]; + + $form['id'] = [ + '#type' => 'machine_name', + '#default_value' => $workflow->id(), + '#machine_name' => [ + 'exists' => [Workflow::class, 'load'], + ], + '#disabled' => TRUE, + ]; + + $header = [ + 'state' => $this->t('State'), + 'weight' => $this->t('Weight'), + 'operations' => $this->t('Operations') + ]; + $form['states_container'] = [ + '#type' => 'details', + '#title' => $this->t('States'), + '#open' => TRUE, + '#collapsible' => 'FALSE', + ]; + $form['states_container']['states'] = [ + '#type' => 'table', + '#header' => $header, + '#title' => $this->t('States'), + '#empty' => $this->t('There are no states yet.'), + '#tabledrag' => [ + [ + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'state-weight', + ], + ], + ]; + + $states = $workflow->getTypePlugin()->getStates(); + + // Warn the user if there are no states. + if (empty($states)) { + drupal_set_message( + $this->t( + 'This workflow has no states and will be disabled until there is at least one, add a new state.', + [':add-state' => $workflow->toUrl('add-state-form')->toString()] + ), + 'warning' + ); + } + + foreach ($states as $state) { + $links = [ + 'edit' => [ + 'title' => $this->t('Edit'), + 'url' => Url::fromRoute('entity.workflow.edit_state_form', ['workflow' => $workflow->id(), 'workflow_state' => $state->id()]), + ] + ]; + if ($this->entity->access('delete-state:' . $state->id())) { + $links['delete'] = [ + 'title' => t('Delete'), + 'url' => Url::fromRoute('entity.workflow.delete_state_form', [ + 'workflow' => $workflow->id(), + 'workflow_state' => $state->id() + ]), + ]; + } + $form['states_container']['states'][$state->id()] = [ + '#attributes' => ['class' => ['draggable']], + 'state' => ['#markup' => $state->label()], + '#weight' => $state->weight(), + 'weight' => [ + '#type' => 'weight', + '#title' => t('Weight for @title', ['@title' => $state->label()]), + '#title_display' => 'invisible', + '#default_value' => $state->weight(), + '#attributes' => ['class' => ['state-weight']], + ], + 'operations' => [ + '#type' => 'operations', + '#links' => $links, + ], + ]; + } + $form['states_container']['state_add'] = [ + '#markup' => $workflow->toLink($this->t('Add a new state'), 'add-state-form')->toString(), + ]; + + $header = [ + 'label' => $this->t('Label'), + 'weight' => $this->t('Weight'), + 'from' => $this->t('From'), + 'to' => $this->t('To'), + 'operations' => $this->t('Operations') + ]; + $form['transitions_container'] = [ + '#type' => 'details', + '#title' => $this->t('Transitions'), + '#open' => TRUE, + ]; + $form['transitions_container']['transitions'] = [ + '#type' => 'table', + '#header' => $header, + '#title' => $this->t('Transitions'), + '#empty' => $this->t('There are no transitions yet.'), + '#tabledrag' => [ + [ + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'transition-weight', + ], + ], + ]; + foreach ($workflow->getTypePlugin()->getTransitions() as $transition) { + $links['edit'] = [ + 'title' => $this->t('Edit'), + 'url' => Url::fromRoute('entity.workflow.edit_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]), + ]; + $links['delete'] = [ + 'title' => t('Delete'), + 'url' => Url::fromRoute('entity.workflow.delete_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]), + ]; + $form['transitions_container']['transitions'][$transition->id()] = [ + '#attributes' => ['class' => ['draggable']], + 'label' => ['#markup' => $transition->label()], + '#weight' => $transition->weight(), + 'weight' => [ + '#type' => 'weight', + '#title' => t('Weight for @title', ['@title' => $transition->label()]), + '#title_display' => 'invisible', + '#default_value' => $transition->weight(), + '#attributes' => ['class' => ['transition-weight']], + ], + 'from' => [ + '#theme' => 'item_list', + '#items' => array_map([State::class, 'labelCallback'], $transition->from()), + '#context' => ['list_style' => 'comma-list'], + ], + 'to' => ['#markup' => $transition->to()->label()], + 'operations' => [ + '#type' => 'operations', + '#links' => $links, + ], + ]; + } + $form['transitions_container']['transition_add'] = [ + '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(), + ]; + + if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) { + $form['type_settings'] = [ + '#tree' => TRUE, + ]; + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $form['type_settings'] += $this->pluginFormFactory + ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY) + ->buildConfigurationForm($form['type_settings'], $subform_state); + } + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + + if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $this->pluginFormFactory + ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY) + ->validateConfigurationForm($form['type_settings'], $subform_state); + } + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + + if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $this->pluginFormFactory + ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY) + ->submitConfigurationForm($form['type_settings'], $subform_state); + } + + $workflow->save(); + drupal_set_message($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()])); + } + + /** + * {@inheritdoc} + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + // This form can only set the workflow's ID, label and the weights for each + // state. + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $values = $form_state->getValues(); + $entity->set('label', $values['label']); + $entity->set('id', $values['id']); + foreach ($values['states'] as $state_id => $state_values) { + $entity->getTypePlugin()->setStateWeight($state_id, $state_values['weight']); + } + foreach ($values['transitions'] as $transition_id => $transition_values) { + $entity->getTypePlugin()->setTransitionWeight($transition_id, $transition_values['weight']); + } + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowStateAddForm.php b/core/modules/workflows/src/Form/WorkflowStateAddForm.php new file mode 100644 index 00000000..ab4a4c1c --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowStateAddForm.php @@ -0,0 +1,182 @@ +pluginFormFactory = $pluginFormFactory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin_form.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'workflow_state_add_form'; + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->getEntity(); + $workflow_type = $workflow->getTypePlugin(); + + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#maxlength' => 255, + '#default_value' => '', + '#description' => $this->t('Label for the state.'), + '#required' => TRUE, + ]; + + $form['id'] = [ + '#type' => 'machine_name', + '#machine_name' => [ + 'exists' => [$this, 'exists'], + ], + ]; + + if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) { + $form['type_settings'] = [ + '#tree' => TRUE, + ]; + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $form['type_settings'] += $this->pluginFormFactory + ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY) + ->buildConfigurationForm($form['type_settings'], $subform_state); + } + + return $form; + } + + /** + * Determines if the workflow state already exists. + * + * @param string $state_id + * The workflow state ID. + * + * @return bool + * TRUE if the workflow state exists, FALSE otherwise. + */ + public function exists($state_id) { + /** @var \Drupal\workflows\WorkflowInterface $original_workflow */ + $original_workflow = \Drupal::entityTypeManager()->getStorage('workflow')->loadUnchanged($this->getEntity()->id()); + return $original_workflow->getTypePlugin()->hasState($state_id); + } + + /** + * Copies top-level form values to entity properties + * + * This form can only change values for a state, which is part of workflow. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity the current form should operate upon. + * @param array $form + * A nested array of form elements comprising the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $values = $form_state->getValues(); + $type_plugin = $entity->getTypePlugin(); + + // Replicate the validation that Workflow::addState() does internally as the + // form values have not been validated at this point. + if (!$type_plugin->hasState($values['id']) && !preg_match('/[^a-z0-9_]+/', $values['id'])) { + $type_plugin->addState($values['id'], $values['label']); + } + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + parent::validateForm($form, $form_state); + /** @var \Drupal\workflows\WorkflowTypeInterface $workflow_type */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + + if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $this->pluginFormFactory + ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY) + ->validateConfigurationForm($form['type_settings'], $subform_state); + } + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + $state = $workflow_type->getState($form_state->getValue('id')); + + if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('state', $state); + $this->pluginFormFactory + ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY) + ->submitConfigurationForm($form['type_settings'], $subform_state); + } + + $workflow->save(); + drupal_set_message($this->t('Created %label state.', [ + '%label' => $workflow->getTypePlugin()->getState($form_state->getValue('id'))->label(), + ])); + $form_state->setRedirectUrl($workflow->toUrl('edit-form')); + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, FormStateInterface $form_state) { + $actions['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Save'), + '#submit' => ['::submitForm', '::save'], + ]; + return $actions; + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowStateDeleteForm.php b/core/modules/workflows/src/Form/WorkflowStateDeleteForm.php new file mode 100644 index 00000000..bfca31e9 --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowStateDeleteForm.php @@ -0,0 +1,107 @@ +t('Are you sure you want to delete %state from %workflow?', ['%state' => $this->workflow->getTypePlugin()->getState($this->stateId)->label(), '%workflow' => $this->workflow->label()]); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return $this->workflow->toUrl(); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * Form constructor. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * @param \Drupal\workflows\WorkflowInterface $workflow + * The workflow entity being edited. + * @param string|null $workflow_state + * The workflow state being deleted. + * + * @return array + * The form structure. + */ + public function buildForm(array $form, FormStateInterface $form_state, WorkflowInterface $workflow = NULL, $workflow_state = NULL) { + if (!$workflow->getTypePlugin()->hasState($workflow_state)) { + throw new NotFoundHttpException(); + } + $this->workflow = $workflow; + $this->stateId = $workflow_state; + + if ($this->workflow->getTypePlugin()->workflowStateHasData($this->workflow, $this->workflow->getTypePlugin()->getState($this->stateId))) { + $form['#title'] = $this->getQuestion(); + $form['description'] = ['#markup' => $this->t('This workflow state is in use. You cannot remove this workflow state until you have removed all content using it.')]; + return $form; + } + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + + $workflow_label = $this->workflow->getTypePlugin()->getState($this->stateId)->label(); + $this->workflow + ->getTypePlugin() + ->deleteState($this->stateId); + $this->workflow->save(); + + drupal_set_message($this->t( + 'State %label deleted.', + ['%label' => $workflow_label] + )); + + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowStateEditForm.php b/core/modules/workflows/src/Form/WorkflowStateEditForm.php new file mode 100644 index 00000000..a04998d2 --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowStateEditForm.php @@ -0,0 +1,235 @@ +pluginFormFactory = $pluginFormFactory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin_form.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'workflow_state_edit_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, $workflow_state = NULL) { + $this->stateId = $workflow_state; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->getEntity(); + $workflow_type = $workflow->getTypePlugin(); + $state = $workflow->getTypePlugin()->getState($this->stateId); + + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#maxlength' => 255, + '#default_value' => $state->label(), + '#description' => $this->t('Label for the state.'), + '#required' => TRUE, + ]; + + $form['id'] = [ + '#type' => 'machine_name', + '#default_value' => $this->stateId, + '#machine_name' => [ + 'exists' => [$this, 'exists'], + ], + '#disabled' => TRUE, + ]; + + // Add additional form fields from the workflow type plugin. + if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) { + $form['type_settings'] = [ + '#tree' => TRUE, + ]; + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('state', $state); + $form['type_settings'] += $this->pluginFormFactory + ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY) + ->buildConfigurationForm($form['type_settings'], $subform_state); + } + + $header = [ + 'label' => $this->t('Transition'), + 'state' => $this->t('To'), + 'operations' => $this->t('Operations'), + ]; + $form['transitions'] = [ + '#type' => 'table', + '#header' => $header, + '#empty' => $this->t('There are no transitions to or from this state yet.'), + ]; + foreach ($state->getTransitions() as $transition) { + $links['edit'] = [ + 'title' => $this->t('Edit'), + 'url' => Url::fromRoute('entity.workflow.edit_transition_form', [ + 'workflow' => $workflow->id(), + 'workflow_transition' => $transition->id() + ]), + ]; + $links['delete'] = [ + 'title' => t('Delete'), + 'url' => Url::fromRoute('entity.workflow.delete_transition_form', [ + 'workflow' => $workflow->id(), + 'workflow_transition' => $transition->id() + ]), + ]; + $form['transitions'][$transition->id()] = [ + 'label' => [ + '#markup' => $transition->label(), + ], + 'state' => [ + '#markup' => $transition->to()->label(), + ], + 'operations' => [ + '#type' => 'operations', + '#links' => $links, + ], + ]; + } + + return $form; + } + + /** + * Copies top-level form values to entity properties + * + * This form can only change values for a state, which is part of workflow. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity the current form should operate upon. + * @param array $form + * A nested array of form elements comprising the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $values = $form_state->getValues(); + $entity->getTypePlugin()->setStateLabel($values['id'], $values['label']); + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + parent::validateForm($form, $form_state); + /** @var \Drupal\workflows\WorkflowTypeInterface $workflow_type */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + + if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('state', $workflow_type->getState($this->stateId)); + $this->pluginFormFactory + ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY) + ->validateConfigurationForm($form['type_settings'], $subform_state); + } + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + + if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('state', $workflow_type->getState($this->stateId)); + $this->pluginFormFactory + ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY) + ->submitConfigurationForm($form['type_settings'], $subform_state); + } + + $workflow->save(); + drupal_set_message($this->t('Saved %label state.', [ + '%label' => $workflow->getTypePlugin()->getState($this->stateId)->label(), + ])); + $form_state->setRedirectUrl($workflow->toUrl('edit-form')); + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, FormStateInterface $form_state) { + $actions['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Save'), + '#submit' => ['::submitForm', '::save'], + ]; + + $actions['delete'] = [ + '#type' => 'link', + '#title' => $this->t('Delete'), + '#access' => $this->entity->access('delete-state:' . $this->stateId), + '#attributes' => [ + 'class' => ['button', 'button--danger'], + ], + '#url' => Url::fromRoute('entity.workflow.delete_state_form', [ + 'workflow' => $this->entity->id(), + 'workflow_state' => $this->stateId + ]) + ]; + + return $actions; + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php b/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php new file mode 100644 index 00000000..84522929 --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowTransitionAddForm.php @@ -0,0 +1,208 @@ +pluginFormFactory = $pluginFormFactory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin_form.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'workflow_transition_add_form'; + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->getEntity(); + $workflow_type = $workflow->getTypePlugin(); + + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#maxlength' => 255, + '#default_value' => '', + '#description' => $this->t('Label for the transition.'), + '#required' => TRUE, + ]; + + $form['id'] = [ + '#type' => 'machine_name', + '#machine_name' => [ + 'exists' => [$this, 'exists'], + ], + ]; + + // @todo https://www.drupal.org/node/2830584 Add some ajax to ensure that + // only valid transitions are selectable. + $states = array_map([State::class, 'labelCallback'], $workflow->getTypePlugin()->getStates()); + $form['from'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('From'), + '#required' => TRUE, + '#default_value' => [], + '#options' => $states, + ]; + $form['to'] = [ + '#type' => 'radios', + '#title' => $this->t('To'), + '#required' => TRUE, + '#options' => $states, + ]; + + // Add additional form fields from the workflow type plugin. + if ($workflow_type->hasFormClass(TransitionInterface::PLUGIN_FORM_KEY)) { + $form['type_settings'] = [ + '#tree' => TRUE, + ]; + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $form['type_settings'] += $this->pluginFormFactory + ->createInstance($workflow_type, TransitionInterface::PLUGIN_FORM_KEY) + ->buildConfigurationForm($form['type_settings'], $subform_state); + } + + return $form; + } + + /** + * Determines if the workflow transition already exists. + * + * @param string $transition_id + * The workflow transition ID. + * + * @return bool + * TRUE if the workflow transition exists, FALSE otherwise. + */ + public function exists($transition_id) { + /** @var \Drupal\workflows\WorkflowInterface $original_workflow */ + $original_workflow = \Drupal::entityTypeManager()->getStorage('workflow')->loadUnchanged($this->getEntity()->id()); + return $original_workflow->getTypePlugin()->hasTransition($transition_id); + } + + /** + * Copies top-level form values to entity properties + * + * This form can only change values for a state, which is part of workflow. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity the current form should operate upon. + * @param array $form + * A nested array of form elements comprising the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + if (!$form_state->isValidationComplete()) { + // Only do something once form validation is complete. + return; + } + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $values = $form_state->getValues(); + $entity->getTypePlugin()->addTransition($values['id'], $values['label'], array_filter($values['from']), $values['to']); + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->getEntity(); + $workflow_type = $workflow->getTypePlugin(); + + $values = $form_state->getValues(); + foreach (array_filter($values['from']) as $from_state_id) { + if ($workflow->getTypePlugin()->hasTransitionFromStateToState($from_state_id, $values['to'])) { + $form_state->setErrorByName('from][' . $from_state_id, $this->t('The transition from %from to %to already exists.', [ + '%from' => $workflow->getTypePlugin()->getState($from_state_id)->label(), + '%to' => $workflow->getTypePlugin()->getState($values['to'])->label(), + ])); + } + } + + if ($workflow_type->hasFormClass(TransitionInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $this->pluginFormFactory + ->createInstance($workflow_type, TransitionInterface::PLUGIN_FORM_KEY) + ->validateConfigurationForm($form['type_settings'], $subform_state); + } + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + $transition = $workflow_type->getTransition($form_state->getValue('id')); + + if ($workflow_type->hasFormClass(TransitionInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('transition', $transition); + $this->pluginFormFactory + ->createInstance($workflow_type, TransitionInterface::PLUGIN_FORM_KEY) + ->submitConfigurationForm($form['type_settings'], $subform_state); + } + + $workflow->save(); + drupal_set_message($this->t('Created %label transition.', [ + '%label' => $form_state->getValue('label'), + ])); + $form_state->setRedirectUrl($workflow->toUrl('edit-form')); + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, FormStateInterface $form_state) { + $actions['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Save'), + '#submit' => ['::submitForm', '::save'], + ]; + return $actions; + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowTransitionDeleteForm.php b/core/modules/workflows/src/Form/WorkflowTransitionDeleteForm.php new file mode 100644 index 00000000..27add727 --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowTransitionDeleteForm.php @@ -0,0 +1,103 @@ +t('Are you sure you want to delete %transition from %workflow?', ['%transition' => $this->transition->label(), '%workflow' => $this->workflow->label()]); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return $this->workflow->toUrl(); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * Form constructor. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * @param \Drupal\workflows\WorkflowInterface $workflow + * The workflow entity being edited. + * @param string|null $workflow_transition + * The workflow transition being deleted. + * + * @return array + * The form structure. + */ + public function buildForm(array $form, FormStateInterface $form_state, WorkflowInterface $workflow = NULL, $workflow_transition = NULL) { + try { + $this->transition = $workflow->getTypePlugin()->getTransition($workflow_transition); + } + catch (\InvalidArgumentException $e) { + throw new NotFoundHttpException(); + } + $this->workflow = $workflow; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->workflow + ->getTypePlugin() + ->deleteTransition($this->transition->id()); + $this->workflow->save(); + + drupal_set_message($this->t('%transition transition deleted.', ['%transition' => $this->transition->label()])); + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} diff --git a/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php b/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php new file mode 100644 index 00000000..1406025a --- /dev/null +++ b/core/modules/workflows/src/Form/WorkflowTransitionEditForm.php @@ -0,0 +1,233 @@ +pluginFormFactory = $pluginFormFactory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin_form.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'workflow_transition_edit_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, $workflow_transition = NULL) { + $this->transitionId = $workflow_transition; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + /* @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->getEntity(); + $workflow_type = $workflow->getTypePlugin(); + $transition = $workflow->getTypePlugin()->getTransition($this->transitionId); + + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Label'), + '#maxlength' => 255, + '#default_value' => $transition->label(), + '#description' => $this->t('Label for the transition.'), + '#required' => TRUE, + ]; + + $form['id'] = [ + '#type' => 'value', + '#value' => $this->transitionId, + ]; + + // @todo https://www.drupal.org/node/2830584 Add some ajax to ensure that + // only valid transitions are selectable. + $states = array_map([State::class, 'labelCallback'], $workflow->getTypePlugin()->getStates()); + $form['from'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('From'), + '#required' => TRUE, + '#default_value' => array_keys($transition->from()), + '#options' => $states, + ]; + $form['to'] = [ + '#type' => 'radios', + '#title' => $this->t('To'), + '#required' => TRUE, + '#default_value' => $transition->to()->id(), + '#options' => $states, + '#disabled' => TRUE, + ]; + + // Add additional form fields from the workflow type plugin. + if ($workflow_type->hasFormClass(TransitionInterface::PLUGIN_FORM_KEY)) { + $form['type_settings'] = [ + '#tree' => TRUE, + ]; + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('transition', $transition); + $form['type_settings'] += $this->pluginFormFactory + ->createInstance($workflow_type, TransitionInterface::PLUGIN_FORM_KEY) + ->buildConfigurationForm($form['type_settings'], $subform_state); + } + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->getEntity(); + $workflow_type = $workflow->getTypePlugin(); + $transition = $workflow_type->getTransition($this->transitionId); + + $values = $form_state->getValues(); + foreach (array_filter($values['from']) as $from_state_id) { + if ($workflow_type->hasTransitionFromStateToState($from_state_id, $values['to'])) { + $existing_transition = $workflow_type->getTransitionFromStateToState($from_state_id, $values['to']); + if ($existing_transition->id() !== $values['id']) { + $form_state->setErrorByName('from][' . $from_state_id, $this->t('The transition from %from to %to already exists.', [ + '%from' => $workflow->getTypePlugin()->getState($from_state_id)->label(), + '%to' => $workflow->getTypePlugin()->getState($values['to'])->label(), + ])); + } + } + } + + if ($workflow_type->hasFormClass(TransitionInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('transition', $transition); + $this->pluginFormFactory + ->createInstance($workflow_type, TransitionInterface::PLUGIN_FORM_KEY) + ->validateConfigurationForm($form['type_settings'], $subform_state); + } + } + + /** + * Copies top-level form values to entity properties + * + * This form can only change values for a state, which is part of workflow. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity the current form should operate upon. + * @param array $form + * A nested array of form elements comprising the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + */ + protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { + if (!$form_state->isValidationComplete()) { + // Only do something once form validation is complete. + return; + } + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $values = $form_state->getValues(); + $form_state->set('created_transition', FALSE); + $entity->getTypePlugin()->setTransitionLabel($values['id'], $values['label']); + $entity->getTypePlugin()->setTransitionFromStates($values['id'], array_filter($values['from'])); + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = $this->entity; + $workflow_type = $workflow->getTypePlugin(); + $transition = $workflow_type->getTransition($this->transitionId); + + if ($workflow_type->hasFormClass(TransitionInterface::PLUGIN_FORM_KEY)) { + $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state); + $subform_state->set('transition', $transition); + $this->pluginFormFactory + ->createInstance($workflow_type, TransitionInterface::PLUGIN_FORM_KEY) + ->submitConfigurationForm($form['type_settings'], $subform_state); + } + + $workflow->save(); + drupal_set_message($this->t('Saved %label transition.', [ + '%label' => $workflow->getTypePlugin()->getTransition($this->transitionId)->label(), + ])); + $form_state->setRedirectUrl($workflow->toUrl('edit-form')); + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, FormStateInterface $form_state) { + $actions['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Save'), + '#submit' => ['::submitForm', '::save'], + ]; + + $actions['delete'] = [ + '#type' => 'link', + '#title' => $this->t('Delete'), + // Deleting a transition is editing a workflow. + '#access' => $this->entity->access('edit'), + '#attributes' => [ + 'class' => ['button', 'button--danger'], + ], + '#url' => Url::fromRoute('entity.workflow.delete_transition_form', [ + 'workflow' => $this->entity->id(), + 'workflow_transition' => $this->transitionId + ]) + ]; + + return $actions; + } + +} diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php new file mode 100644 index 00000000..a898253d --- /dev/null +++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php @@ -0,0 +1,455 @@ +setConfiguration($configuration); + } + + /** + * {@inheritdoc} + */ + public function label() { + $definition = $this->getPluginDefinition(); + // The label can be an object. + // @see \Drupal\Core\StringTranslation\TranslatableMarkup + return $definition['label']; + } + + /** + * {@inheritdoc} + */ + public function workflowHasData(WorkflowInterface $workflow) { + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function workflowStateHasData(WorkflowInterface $workflow, StateInterface $state) { + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * {@inheritdoc} + */ + public function setConfiguration(array $configuration) { + $this->configuration = $configuration + $this->defaultConfiguration(); + } + + /** + * {@inheritdoc} + */ + public function getRequiredStates() { + return $this->getPluginDefinition()['required_states']; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'states' => [], + 'transitions' => [], + ]; + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + return []; + } + + /** + * {@inheritdoc} + */ + public function onDependencyRemoval(array $dependencies) { + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function getInitialState() { + $ordered_states = $this->getStates(); + return reset($ordered_states); + } + + /** + * {@inheritdoc} + */ + public function addState($state_id, $label) { + if ($this->hasState($state_id)) { + throw new \InvalidArgumentException("The state '$state_id' already exists in workflow."); + } + if (preg_match(static::VALID_ID_REGEX, $state_id)) { + throw new \InvalidArgumentException("The state ID '$state_id' must contain only lowercase letters, numbers, and underscores"); + } + $this->configuration['states'][$state_id] = [ + 'label' => $label, + 'weight' => $this->getNextWeight($this->configuration['states']), + ]; + ksort($this->configuration['states']); + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasState($state_id) { + return isset($this->configuration['states'][$state_id]); + } + + /** + * {@inheritdoc} + */ + public function getStates($state_ids = NULL) { + if ($state_ids === NULL) { + $state_ids = array_keys($this->configuration['states']); + } + /** @var \Drupal\workflows\StateInterface[] $states */ + $states = array_combine($state_ids, array_map([$this, 'getState'], $state_ids)); + return static::labelWeightMultisort($states); + } + + /** + * {@inheritdoc} + */ + public function getState($state_id) { + if (!isset($this->configuration['states'][$state_id])) { + throw new \InvalidArgumentException("The state '$state_id' does not exist in workflow.'"); + } + return new State( + $this, + $state_id, + $this->configuration['states'][$state_id]['label'], + $this->configuration['states'][$state_id]['weight'] + ); + } + + /** + * {@inheritdoc} + */ + public function setStateLabel($state_id, $label) { + if (!$this->hasState($state_id)) { + throw new \InvalidArgumentException("The state '$state_id' does not exist in workflow.'"); + } + $this->configuration['states'][$state_id]['label'] = $label; + return $this; + } + + /** + * {@inheritdoc} + */ + public function setStateWeight($state_id, $weight) { + if (!$this->hasState($state_id)) { + throw new \InvalidArgumentException("The state '$state_id' does not exist in workflow.'"); + } + $this->configuration['states'][$state_id]['weight'] = $weight; + return $this; + } + + /** + * {@inheritdoc} + */ + public function deleteState($state_id) { + if (!$this->hasState($state_id)) { + throw new \InvalidArgumentException("The state '$state_id' does not exist in workflow.'"); + } + if (count($this->configuration['states']) === 1) { + throw new \InvalidArgumentException("The state '$state_id' can not be deleted from workflow as it is the only state."); + } + + foreach ($this->configuration['transitions'] as $transition_id => $transition) { + if ($transition['to'] === $state_id) { + $this->deleteTransition($transition_id); + continue; + } + $from_key = array_search($state_id, $transition['from'], TRUE); + if ($from_key !== FALSE) { + // Remove state from the from array. + unset($transition['from'][$from_key]); + if (empty($transition['from'])) { + // There are no more 'from' entries, remove the transition. + $this->deleteTransition($transition_id); + continue; + } + // We changed the from state, update the transition. + $this->setTransitionFromStates($transition_id, $transition['from']); + } + } + unset($this->configuration['states'][$state_id]); + return $this; + } + + /** + * {@inheritdoc} + */ + public function addTransition($transition_id, $label, array $from_state_ids, $to_state_id) { + if ($this->hasTransition($transition_id)) { + throw new \InvalidArgumentException("The transition '$transition_id' already exists in workflow.'"); + } + if (preg_match(static::VALID_ID_REGEX, $transition_id)) { + throw new \InvalidArgumentException("The transition ID '$transition_id' must contain only lowercase letters, numbers, and underscores."); + } + + if (!$this->hasState($to_state_id)) { + throw new \InvalidArgumentException("The state '$to_state_id' does not exist in workflow.'"); + } + $this->configuration['transitions'][$transition_id] = [ + 'label' => $label, + 'from' => [], + 'to' => $to_state_id, + // Always add to the end. + 'weight' => $this->getNextWeight($this->configuration['transitions']), + ]; + + try { + $this->setTransitionFromStates($transition_id, $from_state_ids); + } + catch (\InvalidArgumentException $e) { + unset($this->configuration['transitions'][$transition_id]); + throw $e; + } + + ksort($this->configuration['transitions']); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getTransitions(array $transition_ids = NULL) { + if ($transition_ids === NULL) { + $transition_ids = array_keys($this->configuration['transitions']); + } + /** @var \Drupal\workflows\TransitionInterface[] $transitions */ + $transitions = array_combine($transition_ids, array_map([$this, 'getTransition'], $transition_ids)); + return static::labelWeightMultisort($transitions); + } + + /** + * Sort states or transitions by weight, label, and key. + * + * @param \Drupal\workflows\StateInterface[]|\Drupal\workflows\TransitionInterface[] $objects + * An array of state or transition objects to multi-sort, keyed by the + * state or transition ID. + * + * @return \Drupal\workflows\StateInterface[]|\Drupal\workflows\TransitionInterface[] + * An array of sorted transitions or states, keyed by the state or + * transition ID. + */ + protected static function labelWeightMultisort($objects) { + if (count($objects) > 1) { + // Separate weights, labels, and keys into arrays. + $weights = $labels = []; + $keys = array_keys($objects); + foreach ($objects as $id => $object) { + $weights[$id] = $object->weight(); + $labels[$id] = $object->label(); + } + // Sort weights, labels, and keys in the same order as each other. + array_multisort( + // Use the numerical weight as the primary sort. + $weights, SORT_NUMERIC, SORT_ASC, + // When objects have the same weight, sort them alphabetically by label. + $labels, SORT_NATURAL, SORT_ASC, + // Ensure that the keys (the object IDs) are sorted in the same order as + // the weights. + $keys + ); + // Combine keys and weights to make sure the weights are keyed with the + // correct keys. + $weights = array_combine($keys, $weights); + // Return the objects sorted by weight. + return array_replace($weights, $objects); + } + return $objects; + } + + /** + * {@inheritdoc} + */ + public function getTransition($transition_id) { + if (!$this->hasTransition($transition_id)) { + throw new \InvalidArgumentException("The transition '$transition_id' does not exist in workflow.'"); + } + return new Transition( + $this, + $transition_id, + $this->configuration['transitions'][$transition_id]['label'], + $this->configuration['transitions'][$transition_id]['from'], + $this->configuration['transitions'][$transition_id]['to'], + $this->configuration['transitions'][$transition_id]['weight'] + ); + } + + /** + * {@inheritdoc} + */ + public function hasTransition($transition_id) { + return isset($this->configuration['transitions'][$transition_id]); + } + + /** + * {@inheritdoc} + */ + public function getTransitionsForState($state_id, $direction = 'from') { + $transition_ids = array_keys(array_filter($this->configuration['transitions'], function ($transition) use ($state_id, $direction) { + return in_array($state_id, (array) $transition[$direction], TRUE); + })); + return $this->getTransitions($transition_ids); + } + + /** + * {@inheritdoc} + */ + public function getTransitionFromStateToState($from_state_id, $to_state_id) { + $transition_id = $this->getTransitionIdFromStateToState($from_state_id, $to_state_id); + if (empty($transition_id)) { + throw new \InvalidArgumentException("The transition from '$from_state_id' to '$to_state_id' does not exist in workflow.'"); + } + return $this->getTransition($transition_id); + } + + /** + * {@inheritdoc} + */ + public function hasTransitionFromStateToState($from_state_id, $to_state_id) { + return $this->getTransitionIdFromStateToState($from_state_id, $to_state_id) !== NULL; + } + + /** + * Gets the transition ID from state to state. + * + * @param string $from_state_id + * The state ID to transition from. + * @param string $to_state_id + * The state ID to transition to. + * + * @return string|null + * The transition ID, or NULL if no transition exists. + */ + protected function getTransitionIdFromStateToState($from_state_id, $to_state_id) { + foreach ($this->configuration['transitions'] as $transition_id => $transition) { + if (in_array($from_state_id, $transition['from'], TRUE) && $transition['to'] === $to_state_id) { + return $transition_id; + } + } + return NULL; + } + + /** + * {@inheritdoc} + */ + public function setTransitionLabel($transition_id, $label) { + if (!$this->hasTransition($transition_id)) { + throw new \InvalidArgumentException("The transition '$transition_id' does not exist in workflow."); + } + $this->configuration['transitions'][$transition_id]['label'] = $label; + return $this; + } + + /** + * {@inheritdoc} + */ + public function setTransitionWeight($transition_id, $weight) { + if (!$this->hasTransition($transition_id)) { + throw new \InvalidArgumentException("The transition '$transition_id' does not exist in workflow.'"); + } + $this->configuration['transitions'][$transition_id]['weight'] = $weight; + return $this; + } + + /** + * {@inheritdoc} + */ + public function setTransitionFromStates($transition_id, array $from_state_ids) { + if (!$this->hasTransition($transition_id)) { + throw new \InvalidArgumentException("The transition '$transition_id' does not exist in workflow."); + } + + // Ensure that the states exist. + foreach ($from_state_ids as $from_state_id) { + if (!$this->hasState($from_state_id)) { + throw new \InvalidArgumentException("The state '$from_state_id' does not exist in workflow."); + } + if ($this->hasTransitionFromStateToState($from_state_id, $this->configuration['transitions'][$transition_id]['to'])) { + $existing_transition_id = $this->getTransitionIdFromStateToState($from_state_id, $this->configuration['transitions'][$transition_id]['to']); + if ($transition_id !== $existing_transition_id) { + throw new \InvalidArgumentException("The '$existing_transition_id' transition already allows '$from_state_id' to '{$this->configuration['transitions'][$transition_id]['to']}' transitions in workflow."); + } + } + } + + // Preserve the order of the state IDs in the from value and don't save any + // keys. + $from_state_ids = array_values($from_state_ids); + sort($from_state_ids); + $this->configuration['transitions'][$transition_id]['from'] = $from_state_ids; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function deleteTransition($transition_id) { + if (!$this->hasTransition($transition_id)) { + throw new \InvalidArgumentException("The transition '$transition_id' does not exist in workflow."); + } + unset($this->configuration['transitions'][$transition_id]); + return $this; + } + + /** + * Gets the weight for a new state or transition. + * + * @param array $items + * An array of states or transitions information where each item has a + * 'weight' key with a numeric value. + * + * @return int + * The weight for a new item in the array so that it has the highest weight. + */ + protected function getNextWeight(array $items) { + return array_reduce($items, function ($carry, $item) { + return max($carry, $item['weight'] + 1); + }, 0); + } + +} diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeConfigureFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeConfigureFormBase.php new file mode 100644 index 00000000..53533049 --- /dev/null +++ b/core/modules/workflows/src/Plugin/WorkflowTypeConfigureFormBase.php @@ -0,0 +1,38 @@ +workflowType = $plugin; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + } + +} diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeStateFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeStateFormBase.php new file mode 100644 index 00000000..274ddd63 --- /dev/null +++ b/core/modules/workflows/src/Plugin/WorkflowTypeStateFormBase.php @@ -0,0 +1,49 @@ +workflowType = $plugin; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $values = $form_state->getValues(); + $state = $form_state->get('state'); + $configuration = $this->workflowType->getConfiguration(); + $configuration['states'][$state->id()] = $values + $configuration['states'][$state->id()]; + $this->workflowType->setConfiguration($configuration); + } + +} diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeTransitionFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeTransitionFormBase.php new file mode 100644 index 00000000..e1d61964 --- /dev/null +++ b/core/modules/workflows/src/Plugin/WorkflowTypeTransitionFormBase.php @@ -0,0 +1,49 @@ +workflowType = $plugin; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $values = $form_state->getValues(); + $transition = $form_state->get('transition'); + $configuration = $this->workflowType->getConfiguration(); + $configuration['transitions'][$transition->id()] = $values + $configuration['transitions'][$transition->id()]; + $this->workflowType->setConfiguration($configuration); + } + +} diff --git a/core/modules/workflows/src/State.php b/core/modules/workflows/src/State.php new file mode 100644 index 00000000..5149e265 --- /dev/null +++ b/core/modules/workflows/src/State.php @@ -0,0 +1,114 @@ +workflow = $workflow; + $this->id = $id; + $this->label = $label; + $this->weight = $weight; + } + + /** + * {@inheritdoc} + */ + public function id() { + return $this->id; + } + + /** + * {@inheritdoc} + */ + public function label() { + return $this->label; + } + + /** + * {@inheritdoc} + */ + public function weight() { + return $this->weight; + } + + /** + * {@inheritdoc} + */ + public function canTransitionTo($to_state_id) { + return $this->workflow->hasTransitionFromStateToState($this->id, $to_state_id); + } + + /** + * {@inheritdoc} + */ + public function getTransitionTo($to_state_id) { + if (!$this->canTransitionTo($to_state_id)) { + throw new \InvalidArgumentException("Can not transition to '$to_state_id' state"); + } + return $this->workflow->getTransitionFromStateToState($this->id(), $to_state_id); + } + + /** + * {@inheritdoc} + */ + public function getTransitions() { + return $this->workflow->getTransitionsForState($this->id); + } + + /** + * Helper method to convert a State value object to a label. + * + * @param \Drupal\workflows\StateInterface $state + * + * @return string + * The label of the state. + */ + public static function labelCallback(StateInterface $state) { + return $state->label(); + } + +} diff --git a/core/modules/workflows/src/StateInterface.php b/core/modules/workflows/src/StateInterface.php new file mode 100644 index 00000000..3335ea74 --- /dev/null +++ b/core/modules/workflows/src/StateInterface.php @@ -0,0 +1,76 @@ +workflow = $workflow; + $this->id = $id; + $this->label = $label; + $this->fromStateIds = $from_state_ids; + $this->toStateId = $to_state_id; + $this->weight = $weight; + } + + /** + * {@inheritdoc} + */ + public function id() { + return $this->id; + } + + /** + * {@inheritdoc} + */ + public function label() { + return $this->label; + } + + /** + * {@inheritdoc} + */ + public function from() { + return $this->workflow->getStates($this->fromStateIds); + } + + /** + * {@inheritdoc} + */ + public function to() { + return $this->workflow->getState($this->toStateId); + } + + /** + * {@inheritdoc} + */ + public function weight() { + return $this->weight; + } + +} diff --git a/core/modules/workflows/src/TransitionInterface.php b/core/modules/workflows/src/TransitionInterface.php new file mode 100644 index 00000000..ae3f0231 --- /dev/null +++ b/core/modules/workflows/src/TransitionInterface.php @@ -0,0 +1,61 @@ +get('plugin.manager.workflows.type') + ); + } + + /** + * Constructs the workflow access control handler instance. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * The entity type definition. + * @param \Drupal\Component\Plugin\PluginManagerInterface $workflow_type_manager + * The workflow type plugin manager. + */ + public function __construct(EntityTypeInterface $entity_type, PluginManagerInterface $workflow_type_manager) { + parent::__construct($entity_type); + $this->workflowTypeManager = $workflow_type_manager; + } + + /** + * {@inheritdoc} + */ + protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { + /** @var \Drupal\workflows\Entity\Workflow $entity */ + $workflow_type = $entity->getTypePlugin(); + if (strpos($operation, 'delete-state') === 0) { + list(, $state_id) = explode(':', $operation, 2); + // Deleting a state is editing a workflow, but also we should forbid + // access if there is only one state. + return AccessResult::allowedIf(count($entity->getTypePlugin()->getStates()) > 1) + ->andIf(parent::checkAccess($entity, 'edit', $account)) + ->andIf(AccessResult::allowedIf(!in_array($state_id, $workflow_type->getRequiredStates(), TRUE))) + ->addCacheableDependency($entity); + } + + return parent::checkAccess($entity, $operation, $account); + } + + /** + * {@inheritdoc} + */ + protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { + $workflow_types_count = count($this->workflowTypeManager->getDefinitions()); + $admin_access = parent::checkCreateAccess($account, $context, $entity_bundle); + // Allow access if there is at least one workflow type. Since workflow types + // are provided by modules this is cacheable until extensions change. + return $admin_access + ->andIf(AccessResult::allowedIf($workflow_types_count > 0)) + ->addCacheTags(['workflow_type_plugins']); + } + +} diff --git a/core/modules/workflows/src/WorkflowDeleteAccessCheck.php b/core/modules/workflows/src/WorkflowDeleteAccessCheck.php new file mode 100644 index 00000000..adbcddd9 --- /dev/null +++ b/core/modules/workflows/src/WorkflowDeleteAccessCheck.php @@ -0,0 +1,57 @@ +getParameters(); + if ($parameters->has('workflow') && $parameters->has('workflow_state')) { + $entity = $parameters->get('workflow'); + if ($entity instanceof EntityInterface) { + return $entity->access('delete-state:' . $parameters->get('workflow_state'), $account, TRUE); + } + } + // No opinion, so other access checks should decide if access should be + // allowed or not. + return AccessResult::neutral(); + } + +} diff --git a/core/modules/workflows/src/WorkflowInterface.php b/core/modules/workflows/src/WorkflowInterface.php new file mode 100644 index 00000000..dc09956e --- /dev/null +++ b/core/modules/workflows/src/WorkflowInterface.php @@ -0,0 +1,20 @@ +get('entity_type.manager')->getStorage($entity_type->id()), + $container->get('plugin.manager.workflows.type') + ); + } + + /** + * Constructs a new WorkflowListBuilder object. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * The entity type definition. + * @param \Drupal\Core\Entity\EntityStorageInterface $storage + * The entity storage class. + * @param \Drupal\Component\Plugin\PluginManagerInterface $workflow_type_manager + * The workflow type plugin manager. + */ + public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, PluginManagerInterface $workflow_type_manager) { + parent::__construct($entity_type, $storage); + $this->workflowTypeManager = $workflow_type_manager; + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'workflow_admin_overview_form'; + } + + /** + * {@inheritdoc} + */ + public function buildHeader() { + $header['label'] = $this->t('Workflow'); + $header['type'] = $this->t('Type'); + $header['states'] = $this->t('States'); + + return $header + parent::buildHeader(); + } + + /** + * {@inheritdoc} + */ + public function buildRow(EntityInterface $entity) { + /** @var \Drupal\workflows\WorkflowInterface $entity */ + $row['label'] = $entity->label(); + + $row['type']['data'] = [ + '#markup' => $entity->getTypePlugin()->label() + ]; + + $items = array_map([State::class, 'labelCallback'], $entity->getTypePlugin()->getStates()); + $row['states']['data'] = [ + '#theme' => 'item_list', + '#context' => ['list_style' => 'comma-list'], + '#items' => $items, + ]; + + return $row + parent::buildRow($entity); + } + + /** + * {@inheritdoc} + */ + public function render() { + $build = parent::render(); + $workflow_types_count = count($this->workflowTypeManager->getDefinitions()); + if ($workflow_types_count === 0) { + $build['table']['#empty'] = $this->t('There are no workflow types available. In order to create workflows you need to install a module that provides a workflow type. For example, the Content Moderation module provides a workflow type that enables workflows for content entities.'); + } + return $build; + } + +} diff --git a/core/modules/workflows/src/WorkflowTypeInterface.php b/core/modules/workflows/src/WorkflowTypeInterface.php new file mode 100644 index 00000000..5ef843b4 --- /dev/null +++ b/core/modules/workflows/src/WorkflowTypeInterface.php @@ -0,0 +1,346 @@ +alterInfo('workflow_type_info'); + $this->setCacheBackend($cache_backend, 'workflow_type_info', ['workflow_type_plugins']); + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_third_party_settings_test/config/schema/workflow_third_party_settings_test.schema.yml b/core/modules/workflows/tests/modules/workflow_third_party_settings_test/config/schema/workflow_third_party_settings_test.schema.yml new file mode 100644 index 00000000..d1a2b4ee --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_third_party_settings_test/config/schema/workflow_third_party_settings_test.schema.yml @@ -0,0 +1,2 @@ +workflows.workflow.*.third_party.workflow_third_party_settings_test: + type: ignore diff --git a/core/modules/workflows/tests/modules/workflow_third_party_settings_test/workflow_third_party_settings_test.info.yml b/core/modules/workflows/tests/modules/workflow_third_party_settings_test/workflow_third_party_settings_test.info.yml new file mode 100644 index 00000000..a3637d37 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_third_party_settings_test/workflow_third_party_settings_test.info.yml @@ -0,0 +1,14 @@ +name: 'Workflow Third Party Settings Test' +type: module +description: 'Allows third party settings on workflows to be tested.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - workflows + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml b/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml new file mode 100644 index 00000000..1d9e7428 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml @@ -0,0 +1,72 @@ +workflow.type_settings.workflow_type_test: + type: mapping + label: 'Workflow test type settings' + mapping: + states: + type: sequence + sequence: + type: ignore + transitions: + type: sequence + sequence: + type: ignore + +workflow.type_settings.workflow_type_required_state_test: + type: mapping + label: 'Workflow test type settings' + mapping: + states: + type: sequence + sequence: + type: ignore + transitions: + type: sequence + sequence: + type: ignore + +# @todo, inline this straight into "workflow.type_settings.workflow_type_complex_test" +# after https://www.drupal.org/node/2871746 is resolved. +workflows.state.complex_test_state: + type: workflows.state + mapping: + extra: + type: string + label: 'Extra information' + +workflows.state.complex_test_transition: + type: workflows.transition + mapping: + extra: + type: string + label: 'Extra information' + +workflow.type_settings.workflow_type_complex_test: + type: mapping + label: 'Workflow complex test type settings' + mapping: + example_setting: + type: string + label: 'Example setting' + states: + type: sequence + label: 'States' + sequence: + type: workflows.state.complex_test_state + label: 'States' + transitions: + type: sequence + label: 'Transitions' + sequence: + label: 'Transitions' + type: workflows.state.complex_test_transition + +workflow.type_settings.predefined_states_workflow_test_type: + type: mapping + label: 'Predefined states workflow test type' + mapping: + transitions: + type: sequence + label: 'Transitions' + sequence: + label: 'Transitions' + type: workflows.transition diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeConfigureForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeConfigureForm.php new file mode 100644 index 00000000..ca915777 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeConfigureForm.php @@ -0,0 +1,38 @@ +workflowType->getConfiguration(); + $form['example_setting'] = [ + '#type' => 'textfield', + '#title' => $this->t('Example global workflow setting'), + '#description' => $this->t('Extra information added to the workflow'), + '#default_value' => $type_configuration['example_setting'], + ]; + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $type_configuration = $this->workflowType->getConfiguration(); + $type_configuration['example_setting'] = $form_state->getValue('example_setting'); + $this->workflowType->setConfiguration($type_configuration); + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php new file mode 100644 index 00000000..a466a7d5 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php @@ -0,0 +1,30 @@ +get('state'); + $configuration = $this->workflowType->getConfiguration(); + $form['extra'] = [ + '#type' => 'textfield', + '#title' => $this->t('Extra'), + '#description' => $this->t('Extra information added to state'), + '#default_value' => $state && isset($configuration['states'][$state->id()]['extra']) ? $configuration['states'][$state->id()]['extra'] : '', + ]; + return $form; + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php new file mode 100644 index 00000000..a88306c7 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php @@ -0,0 +1,30 @@ +get('transition'); + $configuration = $this->workflowType->getConfiguration(); + $form['extra'] = [ + '#type' => 'textfield', + '#title' => $this->t('Extra'), + '#description' => $this->t('Extra information added to transition'), + '#default_value' => $transition && isset($configuration['transitions'][$transition->id()]['extra']) ? $configuration['transitions'][$transition->id()]['extra'] : '', + ]; + return $form; + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php new file mode 100644 index 00000000..30b175c3 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php @@ -0,0 +1,43 @@ + '', + ]; + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/PredefinedStatesWorkflowTestType.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/PredefinedStatesWorkflowTestType.php new file mode 100644 index 00000000..aab488aa --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/PredefinedStatesWorkflowTestType.php @@ -0,0 +1,98 @@ + new State($this, 'pay_blinds', 'Pay Blinds'), + 'bet' => new State($this, 'bet', 'Bet'), + 'raise' => new State($this, 'raise', 'Raise'), + 'fold' => new State($this, 'fold', 'Fold'), + ], function ($state) use ($state_ids) { + return is_array($state_ids) ? in_array($state->id(), $state_ids) : TRUE; + }); + } + + /** + * {@inheritdoc} + */ + public function getState($state_id) { + $states = $this->getStates(); + if (!isset($states[$state_id])) { + throw new \InvalidArgumentException("The state '$state_id' does not exist in workflow.'"); + } + return $states[$state_id]; + } + + /** + * {@inheritdoc} + */ + public function hasState($state_id) { + $states = $this->getStates(); + return isset($states[$state_id]); + } + + /** + * {@inheritdoc} + */ + public function addState($state_id, $label) { + // States cannot be added on this workflow. + return $this; + } + + /** + * {@inheritdoc} + */ + public function setStateLabel($state_id, $label) { + // States cannot be altered on this workflow. + return $this; + } + + /** + * {@inheritdoc} + */ + public function setStateWeight($state_id, $weight) { + // States cannot be altered on this workflow. + return $this; + } + + /** + * {@inheritdoc} + */ + public function deleteState($state_id) { + // States cannot be deleted on this workflow. + return $this; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'transitions' => [], + ]; + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/RequiredStateTestType.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/RequiredStateTestType.php new file mode 100644 index 00000000..c2c88ddc --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/RequiredStateTestType.php @@ -0,0 +1,52 @@ + [ + 'fresh' => [ + 'label' => 'Fresh', + 'weight' => 0, + ], + 'rotten' => [ + 'label' => 'Rotten', + 'weight' => 1, + ], + ], + 'transitions' => [ + 'rot' => [ + 'label' => 'Rot', + 'to' => 'rotten', + 'weight' => 0, + 'from' => [ + 'fresh', + ], + ], + ], + ]; + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/TestType.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/TestType.php new file mode 100644 index 00000000..ddd074a0 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/TestType.php @@ -0,0 +1,26 @@ +get('workflow_type_test.required_states', []); + } + +} diff --git a/core/modules/workflows/tests/modules/workflow_type_test/workflow_type_test.info.yml b/core/modules/workflows/tests/modules/workflow_type_test/workflow_type_test.info.yml new file mode 100644 index 00000000..c6a44191 --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/workflow_type_test.info.yml @@ -0,0 +1,14 @@ +name: 'Workflow Type Test' +type: module +description: 'Provides a workflow type plugin for testing.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - workflows + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/workflows/tests/modules/workflow_type_test/workflow_type_test.module b/core/modules/workflows/tests/modules/workflow_type_test/workflow_type_test.module new file mode 100644 index 00000000..b97f2c5e --- /dev/null +++ b/core/modules/workflows/tests/modules/workflow_type_test/workflow_type_test.module @@ -0,0 +1,28 @@ +get('workflow_type_test.plugin_definitions') !== NULL) { + $definitions = $state->get('workflow_type_test.plugin_definitions'); + } +} + +/** + * Sets the type plugin definitions override and clear the cache. + * + * @param array $definitions + * Definitions to set. + */ +function workflow_type_test_set_definitions($definitions) { + \Drupal::state()->set('workflow_type_test.plugin_definitions', $definitions); + \Drupal::service('plugin.manager.workflows.type')->clearCachedDefinitions(); +} diff --git a/core/modules/workflows/tests/src/Functional/Hal/WorkflowHalJsonAnonTest.php b/core/modules/workflows/tests/src/Functional/Hal/WorkflowHalJsonAnonTest.php new file mode 100644 index 00000000..0c2fe004 --- /dev/null +++ b/core/modules/workflows/tests/src/Functional/Hal/WorkflowHalJsonAnonTest.php @@ -0,0 +1,30 @@ +grantPermissionsToTestedRole(['administer workflows']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $workflow = Workflow::create([ + 'id' => 'rest_workflow', + 'label' => 'REST Worklow', + 'type' => 'workflow_type_complex_test', + ]); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published'); + $configuration = $workflow->getTypePlugin()->getConfiguration(); + $configuration['example_setting'] = 'foo'; + $configuration['states']['draft']['extra'] = 'bar'; + $workflow->getTypePlugin()->setConfiguration($configuration); + $workflow->save(); + return $workflow; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [ + 'module' => [ + 'workflow_type_test', + ], + ], + 'id' => 'rest_workflow', + 'label' => 'REST Worklow', + 'langcode' => 'en', + 'status' => TRUE, + 'type' => 'workflow_type_complex_test', + 'type_settings' => [ + 'states' => [ + 'draft' => [ + 'extra' => 'bar', + 'label' => 'Draft', + 'weight' => 0, + ], + 'published' => [ + 'label' => 'Published', + 'weight' => 1, + ], + ], + 'transitions' => [], + 'example_setting' => 'foo', + ], + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/workflows/tests/src/Functional/WorkflowUiNoTypeTest.php b/core/modules/workflows/tests/src/Functional/WorkflowUiNoTypeTest.php new file mode 100644 index 00000000..c0c7de6f --- /dev/null +++ b/core/modules/workflows/tests/src/Functional/WorkflowUiNoTypeTest.php @@ -0,0 +1,54 @@ +drupalPlaceBlock('local_actions_block'); + } + + /** + * Tests the creation of a workflow through the UI. + */ + public function testWorkflowUiWithNoType() { + $this->drupalLogin($this->createUser(['access administration pages', 'administer workflows'])); + $this->drupalGet('admin/config/workflow/workflows/add'); + // There are no workflow types so this should be a 403. + $this->assertSession()->statusCodeEquals(403); + + $this->drupalGet('admin/config/workflow/workflows'); + $this->assertSession()->pageTextContains('There are no workflow types available. In order to create workflows you need to install a module that provides a workflow type. For example, the Content Moderation module provides a workflow type that enables workflows for content entities.'); + $this->assertSession()->pageTextNotContains('Add workflow'); + + $this->container->get('module_installer')->install(['workflow_type_test']); + // The render cache needs to be cleared because although the cache tags are + // correctly set the render cache does not pick it up. + \Drupal::cache('render')->deleteAll(); + + $this->drupalGet('admin/config/workflow/workflows'); + $this->assertSession()->pageTextNotContains('There are no workflow types available. In order to create workflows you need to install a module that provides a workflow type. For example, the Content Moderation module provides a workflow type that enables workflows for content entities.'); + $this->assertSession()->linkExists('Add workflow'); + $this->assertSession()->pageTextContains('There is no Workflow yet.'); + } + +} diff --git a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php new file mode 100644 index 00000000..b15b2409 --- /dev/null +++ b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php @@ -0,0 +1,394 @@ +drupalPlaceBlock('local_actions_block'); + } + + /** + * Tests route access/permissions. + */ + public function testAccess() { + // Create a minimal workflow for testing. + $workflow = Workflow::create(['id' => 'test', 'type' => 'workflow_type_test']); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['draft', 'published'], 'published'); + $workflow->save(); + + $paths = [ + 'admin/config/workflow/workflows', + 'admin/config/workflow/workflows/add', + 'admin/config/workflow/workflows/manage/test', + 'admin/config/workflow/workflows/manage/test/delete', + 'admin/config/workflow/workflows/manage/test/add_state', + 'admin/config/workflow/workflows/manage/test/state/published', + 'admin/config/workflow/workflows/manage/test/state/published/delete', + 'admin/config/workflow/workflows/manage/test/add_transition', + 'admin/config/workflow/workflows/manage/test/transition/publish', + 'admin/config/workflow/workflows/manage/test/transition/publish/delete', + ]; + + foreach ($paths as $path) { + $this->drupalGet($path); + // No access. + $this->assertSession()->statusCodeEquals(403); + } + $this->drupalLogin($this->createUser(['administer workflows'])); + foreach ($paths as $path) { + $this->drupalGet($path); + // User has access. + $this->assertSession()->statusCodeEquals(200); + } + + // Ensure that default states can not be deleted. + \Drupal::state()->set('workflow_type_test.required_states', ['published']); + $this->drupalGet('admin/config/workflow/workflows/manage/test/state/published/delete'); + $this->assertSession()->statusCodeEquals(403); + \Drupal::state()->set('workflow_type_test.required_states', []); + + // Delete one of the states and ensure the other test cannot be deleted. + $this->drupalGet('admin/config/workflow/workflows/manage/test/state/published/delete'); + $this->submitForm([], 'Delete'); + $this->drupalGet('admin/config/workflow/workflows/manage/test/state/draft/delete'); + $this->assertSession()->statusCodeEquals(403); + } + + /** + * Test the machine name validation of the state add form. + */ + public function testStateMachineNameValidation() { + Workflow::create([ + 'id' => 'test_workflow', + 'type' => 'workflow_type_test', + ])->save(); + + $this->drupalLogin($this->createUser(['administer workflows'])); + $this->drupalPostForm('admin/config/workflow/workflows/manage/test_workflow/add_state', [ + 'label' => 'Test State', + 'id' => 'Invalid ID', + ], 'Save'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextContains('The machine-readable name must contain only lowercase letters, numbers, and underscores.'); + } + + /** + * Tests the creation of a workflow through the UI. + */ + public function testWorkflowCreation() { + $workflow_storage = $this->container->get('entity_type.manager')->getStorage('workflow'); + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $this->drupalLogin($this->createUser(['access administration pages', 'administer workflows'])); + $this->drupalGet('admin/config/workflow'); + $this->assertSession()->linkByHrefExists('admin/config/workflow/workflows'); + $this->clickLink('Workflows'); + $this->assertSession()->pageTextContains('Workflows'); + $this->assertSession()->pageTextContains('There is no Workflow yet.'); + $this->clickLink('Add workflow'); + $this->submitForm(['label' => 'Test', 'id' => 'test', 'workflow_type' => 'workflow_type_test'], 'Save'); + $this->assertSession()->pageTextContains('Created the Test Workflow.'); + $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test/add_state'); + $this->drupalGet('/admin/config/workflow/workflows/manage/test'); + $this->assertSession()->pageTextContains('This workflow has no states and will be disabled until there is at least one, add a new state.'); + $this->assertSession()->pageTextContains('There are no states yet.'); + $this->clickLink('Add a new state'); + $this->submitForm(['label' => 'Published', 'id' => 'published'], 'Save'); + $this->assertSession()->pageTextContains('Created Published state.'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertFalse($workflow->getTypePlugin()->getState('published')->canTransitionTo('published'), 'No default transition from published to published exists.'); + + $this->clickLink('Add a new state'); + // Don't create a draft to draft transition by default. + $this->submitForm(['label' => 'Draft', 'id' => 'draft'], 'Save'); + $this->assertSession()->pageTextContains('Created Draft state.'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertFalse($workflow->getTypePlugin()->getState('draft')->canTransitionTo('draft'), 'Can not transition from draft to draft'); + + $this->clickLink('Add a new transition'); + $this->submitForm(['id' => 'publish', 'label' => 'Publish', 'from[draft]' => 'draft', 'to' => 'published'], 'Save'); + $this->assertSession()->pageTextContains('Created Publish transition.'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertTrue($workflow->getTypePlugin()->getState('draft')->canTransitionTo('published'), 'Can transition from draft to published'); + + $this->clickLink('Add a new transition'); + $this->assertCount(2, $this->cssSelect('input[name="to"][type="radio"]')); + $this->assertCount(0, $this->cssSelect('input[name="to"][checked="checked"][type="radio"]')); + $this->submitForm(['id' => 'create_new_draft', 'label' => 'Create new draft', 'from[draft]' => 'draft', 'to' => 'draft'], 'Save'); + $this->assertSession()->pageTextContains('Created Create new draft transition.'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertTrue($workflow->getTypePlugin()->getState('draft')->canTransitionTo('draft'), 'Can transition from draft to draft'); + + // The fist state to edit on the page should be published. + $this->clickLink('Edit'); + $this->assertSession()->fieldValueEquals('label', 'Published'); + // Change the label. + $this->submitForm(['label' => 'Live'], 'Save'); + $this->assertSession()->pageTextContains('Saved Live state.'); + + // Allow published to draft. + $this->clickLink('Edit', 3); + $this->submitForm(['from[published]' => 'published'], 'Save'); + $this->assertSession()->pageTextContains('Saved Create new draft transition.'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertTrue($workflow->getTypePlugin()->getState('published')->canTransitionTo('draft'), 'Can transition from published to draft'); + + // Try creating a duplicate transition. + $this->clickLink('Add a new transition'); + $this->submitForm(['id' => 'create_new_draft', 'label' => 'Create new draft', 'from[published]' => 'published', 'to' => 'draft'], 'Save'); + $this->assertSession()->pageTextContains('The machine-readable name is already in use. It must be unique.'); + // Try creating a transition which duplicates the states of another. + $this->submitForm(['id' => 'create_new_draft2', 'label' => 'Create new draft again', 'from[published]' => 'published', 'to' => 'draft'], 'Save'); + $this->assertSession()->pageTextContains('The transition from Live to Draft already exists.'); + + // Create a new transition. + $this->submitForm(['id' => 'save_and_publish', 'label' => 'Save and publish', 'from[published]' => 'published', 'to' => 'published'], 'Save'); + $this->assertSession()->pageTextContains('Created Save and publish transition.'); + // Edit the new transition and try to add an existing transition. + $this->clickLink('Edit', 4); + $this->submitForm(['from[draft]' => 'draft'], 'Save'); + $this->assertSession()->pageTextContains('The transition from Draft to Live already exists.'); + + // Delete the transition. + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('published', 'published'), 'Can transition from published to published'); + $this->clickLink('Delete'); + $this->assertSession()->pageTextContains('Are you sure you want to delete Save and publish from Test?'); + $this->submitForm([], 'Delete'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('published', 'published'), 'Cannot transition from published to published'); + + // Try creating a duplicate state. + $this->drupalGet('admin/config/workflow/workflows/manage/test'); + $this->clickLink('Add a new state'); + $this->submitForm(['label' => 'Draft', 'id' => 'draft'], 'Save'); + $this->assertSession()->pageTextContains('The machine-readable name is already in use. It must be unique.'); + + // Ensure that weight changes the state ordering. + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertEquals('published', $workflow->getTypePlugin()->getInitialState()->id()); + $this->drupalGet('admin/config/workflow/workflows/manage/test'); + $this->submitForm(['states[draft][weight]' => '-1'], 'Save'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertEquals('draft', $workflow->getTypePlugin()->getInitialState()->id()); + + // Verify that we are still on the workflow edit page. + $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test'); + + // Ensure that weight changes the transition ordering. + $this->assertEquals(['publish', 'create_new_draft'], array_keys($workflow->getTypePlugin()->getTransitions())); + $this->drupalGet('admin/config/workflow/workflows/manage/test'); + $this->submitForm(['transitions[create_new_draft][weight]' => '-1'], 'Save'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertEquals(['create_new_draft', 'publish'], array_keys($workflow->getTypePlugin()->getTransitions())); + + // Verify that we are still on the workflow edit page. + $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test'); + + // Ensure that a delete link for the published state exists before deleting + // the draft state. + $published_delete_link = Url::fromRoute('entity.workflow.delete_state_form', [ + 'workflow' => $workflow->id(), + 'workflow_state' => 'published', + ])->toString(); + $draft_delete_link = Url::fromRoute('entity.workflow.delete_state_form', [ + 'workflow' => $workflow->id(), + 'workflow_state' => 'draft', + ])->toString(); + $this->assertSession()->elementContains('css', 'tr[data-drupal-selector="edit-states-published"]', 'Delete'); + $this->assertSession()->linkByHrefExists($published_delete_link); + $this->assertSession()->linkByHrefExists($draft_delete_link); + + // Make the published state a default state and ensure it is no longer + // linked. + \Drupal::state()->set('workflow_type_test.required_states', ['published']); + $this->getSession()->reload(); + $this->assertSession()->linkByHrefNotExists($published_delete_link); + $this->assertSession()->linkByHrefExists($draft_delete_link); + $this->assertSession()->elementNotContains('css', 'tr[data-drupal-selector="edit-states-published"]', 'Delete'); + \Drupal::state()->set('workflow_type_test.required_states', []); + $this->getSession()->reload(); + $this->assertSession()->elementContains('css', 'tr[data-drupal-selector="edit-states-published"]', 'Delete'); + $this->assertSession()->linkByHrefExists($published_delete_link); + $this->assertSession()->linkByHrefExists($draft_delete_link); + + // Delete the Draft state. + $this->clickLink('Delete'); + $this->assertSession()->pageTextContains('Are you sure you want to delete Draft from Test?'); + $this->submitForm([], 'Delete'); + $this->assertSession()->pageTextContains('State Draft deleted.'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertFalse($workflow->getTypePlugin()->hasState('draft'), 'Draft state deleted'); + $this->assertTrue($workflow->getTypePlugin()->hasState('published'), 'Workflow still has published state'); + + // The last state cannot be deleted so the only delete link on the page will + // be for the workflow. + $this->assertSession()->linkByHrefNotExists($published_delete_link); + $this->clickLink('Delete'); + $this->assertSession()->pageTextContains('Are you sure you want to delete Test?'); + $this->submitForm([], 'Delete'); + $this->assertSession()->pageTextContains('Workflow Test deleted.'); + $this->assertSession()->pageTextContains('There is no Workflow yet.'); + $this->assertNull($workflow_storage->loadUnchanged('test'), 'The test workflow has been deleted'); + + // Ensure that workflow types with default configuration are initialized + // correctly. + $this->drupalGet('admin/config/workflow/workflows'); + $this->clickLink('Add workflow'); + $this->submitForm(['label' => 'Test 2', 'id' => 'test2', 'workflow_type' => 'workflow_type_required_state_test'], 'Save'); + $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test2'); + $workflow = $workflow_storage->loadUnchanged('test2'); + $this->assertTrue($workflow->getTypePlugin()->hasState('fresh'), 'The workflow has the "fresh" state'); + $this->assertTrue($workflow->getTypePlugin()->hasState('rotten'), 'The workflow has the "rotten" state'); + $this->assertTrue($workflow->getTypePlugin()->hasTransition('rot'), 'The workflow has the "rot" transition'); + $this->assertSession()->pageTextContains('Fresh'); + $this->assertSession()->pageTextContains('Rotten'); + } + + /** + * Test the workflow configuration form. + */ + public function testWorkflowConfigurationForm() { + $workflow = Workflow::create(['id' => 'test', 'type' => 'workflow_type_complex_test', 'label' => 'Test']); + $workflow + ->getTypePlugin() + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['published'], 'published'); + $workflow->save(); + + $this->drupalLogin($this->createUser(['administer workflows'])); + + // Add additional information to the workflow via the configuration form. + $this->drupalGet('admin/config/workflow/workflows/manage/test'); + $this->assertSession()->pageTextContains('Example global workflow setting'); + $this->submitForm(['type_settings[example_setting]' => 'Extra global settings'], 'Save'); + + $workflow_storage = $this->container->get('entity_type.manager')->getStorage('workflow'); + $workflow = $workflow_storage->loadUnchanged('test'); + $this->assertEquals('Extra global settings', $workflow->getTypePlugin()->getConfiguration()['example_setting']); + } + + /** + * Test a workflow, state, and transition can have a numeric ID and label. + */ + public function testNumericIds() { + $this->drupalLogin($this->createUser(['administer workflows'])); + $this->drupalGet('admin/config/workflow/workflows'); + $this->clickLink('Add workflow'); + $this->submitForm(['label' => 123, 'id' => 123, 'workflow_type' => 'workflow_type_complex_test'], 'Save'); + + $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/123/add_state'); + + $this->submitForm(['label' => 456, 'id' => 456], 'Save'); + $this->assertSession()->pageTextContains('Created 456 state.'); + + $this->clickLink('Add a new state'); + $this->submitForm(['label' => 789, 'id' => 789], 'Save'); + $this->assertSession()->pageTextContains('Created 789 state.'); + + $this->clickLink('Add a new transition'); + $this->submitForm(['id' => 101112, 'label' => 101112, 'from[456]' => 456, 'to' => 789], 'Save'); + $this->assertSession()->pageTextContains('Created 101112 transition.'); + + $workflow = $this->container->get('entity_type.manager')->getStorage('workflow')->loadUnchanged(123); + $this->assertEquals(123, $workflow->id()); + $this->assertEquals(456, $workflow->getTypePlugin()->getState(456)->id()); + $this->assertEquals(101112, $workflow->getTypePlugin()->getTransition(101112)->id()); + $this->assertEquals(789, $workflow->getTypePlugin()->getTransition(101112)->to()->id()); + } + + /** + * Test the sorting of states and transitions by weight and label. + */ + public function testSorting() { + $workflow = Workflow::create(['id' => 'test', 'type' => 'workflow_type_complex_test', 'label' => 'Test']); + $workflow + ->getTypePlugin() + ->setConfiguration([ + 'states' => [ + 'twoa' => [ + 'label' => 'twoa', + 'weight' => 2, + ], + 'three' => [ + 'label' => 'three', + 'weight' => 3, + ], + 'twob' => [ + 'label' => 'twob', + 'weight' => 2, + ], + 'one' => [ + 'label' => 'one', + 'weight' => 1, + ], + ], + 'transitions' => [ + 'three' => [ + 'label' => 'three', + 'from' => ['three'], + 'to' => 'three', + 'weight' => 3, + ], + 'twoa' => [ + 'label' => 'twoa', + 'from' => ['twoa'], + 'to' => 'twoa', + 'weight' => 2, + ], + 'one' => [ + 'label' => 'one', + 'from' => ['one'], + 'to' => 'one', + 'weight' => 1, + ], + 'twob' => [ + 'label' => 'twob', + 'from' => ['twob'], + 'to' => 'twob', + 'weight' => 2, + ], + ], + ]); + $workflow->save(); + + $this->drupalLogin($this->createUser(['administer workflows'])); + $this->drupalGet('admin/config/workflow/workflows/manage/test'); + $expected_states = ['one', 'twoa', 'twob', 'three']; + $elements = $this->xpath('//details[@id="edit-states-container"]//table/tbody/tr'); + foreach ($elements as $key => $element) { + $this->assertEquals($expected_states[$key], $element->find('xpath', 'td')->getText()); + } + $expected_transitions = ['one', 'twoa', 'twob', 'three']; + $elements = $this->xpath('//details[@id="edit-transitions-container"]//table/tbody/tr'); + foreach ($elements as $key => $element) { + $this->assertEquals($expected_transitions[$key], $element->find('xpath', 'td')->getText()); + } + } + +} diff --git a/core/modules/workflows/tests/src/Kernel/ComplexWorkflowTypeTest.php b/core/modules/workflows/tests/src/Kernel/ComplexWorkflowTypeTest.php new file mode 100644 index 00000000..15d27286 --- /dev/null +++ b/core/modules/workflows/tests/src/Kernel/ComplexWorkflowTypeTest.php @@ -0,0 +1,38 @@ + 'test1', 'type' => 'workflow_type_complex_test'], 'workflow'); + $workflow1->save(); + $workflow2 = new Workflow(['id' => 'test2', 'type' => 'workflow_type_complex_test'], 'workflow'); + $workflow2->save(); + $workflow3 = new Workflow(['id' => 'test3', 'type' => 'workflow_type_test'], 'workflow'); + $workflow3->save(); + + $this->assertEquals(['test1', 'test2'], array_keys(Workflow::loadMultipleByType('workflow_type_complex_test'))); + $this->assertEquals(['test3'], array_keys(Workflow::loadMultipleByType('workflow_type_test'))); + $this->assertEquals([], Workflow::loadMultipleByType('a_type_that_does_not_exist')); + } + +} diff --git a/core/modules/workflows/tests/src/Kernel/PredefinedWorkflowTypeTest.php b/core/modules/workflows/tests/src/Kernel/PredefinedWorkflowTypeTest.php new file mode 100644 index 00000000..f3f0b576 --- /dev/null +++ b/core/modules/workflows/tests/src/Kernel/PredefinedWorkflowTypeTest.php @@ -0,0 +1,52 @@ + 'aces', + 'label' => 'Aces Workflow', + 'type' => 'predefined_states_workflow_test_type', + 'transitions' => [ + 'bet' => [ + 'label' => 'Bet', + 'from' => [ + 'pay_blinds', + ], + 'to' => 'bet', + ], + 'raise' => [ + 'label' => 'Raise', + 'from' => [ + 'pay_blinds', + ], + 'to' => 'raise', + ], + ], + ]); + $workflow->save(); + + // No states configuration is stored for this workflow. + $configuration = $workflow->getTypePlugin()->getConfiguration(); + $this->assertFalse(isset($configuration['states'])); + } + +} diff --git a/core/modules/workflows/tests/src/Kernel/RequiredStatesTest.php b/core/modules/workflows/tests/src/Kernel/RequiredStatesTest.php new file mode 100644 index 00000000..8d4edc90 --- /dev/null +++ b/core/modules/workflows/tests/src/Kernel/RequiredStatesTest.php @@ -0,0 +1,125 @@ + 'test', + 'type' => 'workflow_type_required_state_test', + ], 'workflow'); + $workflow->save(); + $this->assertEquals(['fresh', 'rotten'], $workflow->getTypePlugin() + ->getRequiredStates()); + + // Ensure that the workflow has the default configuration. + $this->assertTrue($workflow->getTypePlugin()->hasState('rotten')); + $this->assertTrue($workflow->getTypePlugin()->hasState('fresh')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('fresh', 'rotten')); + } + + /** + * @covers \Drupal\workflows\Entity\Workflow::preSave + */ + public function testDeleteRequiredStateAPI() { + $workflow = new Workflow([ + 'id' => 'test', + 'type' => 'workflow_type_required_state_test', + ], 'workflow'); + $workflow->save(); + // Ensure that required states can't be deleted. + $this->setExpectedException(RequiredStateMissingException::class, "Required State Type Test' requires states with the ID 'fresh' in workflow 'test'"); + $workflow->getTypePlugin()->deleteState('fresh'); + $workflow->save(); + } + + /** + * @covers \Drupal\workflows\Entity\Workflow::preSave + */ + public function testNoStatesRequiredStateAPI() { + $workflow = new Workflow([ + 'id' => 'test', + 'type' => 'workflow_type_required_state_test', + 'type_settings' => [ + 'states' => [], + ], + ], 'workflow'); + $this->setExpectedException(RequiredStateMissingException::class, "Required State Type Test' requires states with the ID 'fresh', 'rotten' in workflow 'test'"); + $workflow->save(); + } + + /** + * Ensures that initialized configuration can be changed. + */ + public function testChangeRequiredStateAPI() { + $workflow = new Workflow([ + 'id' => 'test', + 'type' => 'workflow_type_required_state_test', + ], 'workflow'); + $workflow->save(); + + // Ensure states added by default configuration can be changed. + $this->assertEquals('Fresh', $workflow->getTypePlugin()->getState('fresh')->label()); + $workflow + ->getTypePlugin() + ->setStateLabel('fresh', 'Fresher'); + $workflow->save(); + $this->assertEquals('Fresher', $workflow->getTypePlugin()->getState('fresh')->label()); + + // Ensure transitions can be altered. + $workflow + ->getTypePlugin() + ->addState('cooked', 'Cooked') + ->setTransitionFromStates('rot', ['fresh', 'cooked']); + $workflow->save(); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('fresh', 'rotten')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('cooked', 'rotten')); + + $workflow + ->getTypePlugin() + ->setTransitionFromStates('rot', ['cooked']); + $workflow->save(); + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('fresh', 'rotten')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('cooked', 'rotten')); + + // Ensure the default configuration does not cause ordering issues. + $workflow->getTypePlugin()->addTransition('cook', 'Cook', ['fresh'], 'cooked'); + $workflow->save(); + $this->assertSame([ + 'cooked', + 'fresh', + 'rotten', + ], array_keys($workflow->getTypePlugin()->getConfiguration()['states'])); + $this->assertSame([ + 'cook', + 'rot', + ], array_keys($workflow->getTypePlugin()->getConfiguration()['transitions'])); + + // Ensure that transitions can be deleted. + $workflow->getTypePlugin()->deleteTransition('rot'); + $workflow->save(); + $this->assertFalse($workflow->getTypePlugin()->hasTransition('rot')); + } + +} diff --git a/core/modules/workflows/tests/src/Kernel/WorkflowAccessControlHandlerTest.php b/core/modules/workflows/tests/src/Kernel/WorkflowAccessControlHandlerTest.php new file mode 100644 index 00000000..cd4e7ceb --- /dev/null +++ b/core/modules/workflows/tests/src/Kernel/WorkflowAccessControlHandlerTest.php @@ -0,0 +1,218 @@ +installEntitySchema('workflow'); + $this->installEntitySchema('user'); + $this->installSchema('system', ['sequences']); + + $this->accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('workflow'); + + // Create and discard user 1, which is special and bypasses all access + // checking. + $this->createUser([]); + $this->user = $this->createUser([]); + $this->adminUser = $this->createUser(['administer workflows']); + } + + /** + * @covers ::checkCreateAccess + */ + public function testCheckCreateAccess() { + // A user must have the correct permission to create a workflow. + $this->assertEquals( + AccessResult::neutral() + ->addCacheContexts(['user.permissions']) + ->setReason("The 'administer workflows' permission is required.") + ->addCacheTags(['workflow_type_plugins']), + $this->accessControlHandler->createAccess(NULL, $this->user, [], TRUE) + ); + $this->assertEquals( + AccessResult::allowed() + ->addCacheContexts(['user.permissions']) + ->addCacheTags(['workflow_type_plugins']), + $this->accessControlHandler->createAccess(NULL, $this->adminUser, [], TRUE) + ); + + // Remove all plugin types and ensure not even the admin user is allowed to + // create a workflow. + workflow_type_test_set_definitions([]); + $this->accessControlHandler->resetCache(); + $this->assertEquals( + AccessResult::neutral() + ->addCacheContexts(['user.permissions']) + ->addCacheTags(['workflow_type_plugins']), + $this->accessControlHandler->createAccess(NULL, $this->adminUser, [], TRUE) + ); + } + + /** + * @covers ::checkAccess + * @dataProvider checkAccessProvider + */ + public function testCheckAccess($user, $operation, $result, $states_to_create = []) { + $workflow = Workflow::create([ + 'type' => 'workflow_type_test', + 'id' => 'test_workflow', + ]); + $workflow->save(); + $workflow_type = $workflow->getTypePlugin(); + foreach ($states_to_create as $state_id => $is_required) { + $workflow_type->addState($state_id, $this->randomString()); + } + \Drupal::state()->set('workflow_type_test.required_states', array_filter($states_to_create)); + $this->assertEquals($result, $this->accessControlHandler->access($workflow, $operation, $this->{$user}, TRUE)); + } + + /** + * Data provider for ::testCheckAccess. + * + * @return array + */ + public function checkAccessProvider() { + $container = new ContainerBuilder(); + $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); + $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); + $cache_contexts_manager->reveal(); + $container->set('cache_contexts_manager', $cache_contexts_manager); + \Drupal::setContainer($container); + + return [ + 'Admin view' => [ + 'adminUser', + 'view', + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'Admin update' => [ + 'adminUser', + 'update', + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'Admin delete' => [ + 'adminUser', + 'delete', + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'Admin delete only state' => [ + 'adminUser', + 'delete-state:foo', + AccessResult::neutral()->addCacheTags(['config:workflows.workflow.test_workflow']), + ['foo' => FALSE], + ], + 'Admin delete one of two states' => [ + 'adminUser', + 'delete-state:foo', + AccessResult::allowed() + ->addCacheTags(['config:workflows.workflow.test_workflow']) + ->addCacheContexts(['user.permissions']), + ['foo' => FALSE, 'bar' => FALSE], + ], + 'Admin delete required state when there are >1 states' => [ + 'adminUser', + 'delete-state:foo', + AccessResult::allowed() + ->addCacheTags(['config:workflows.workflow.test_workflow']) + ->addCacheContexts(['user.permissions']), + ['foo' => TRUE, 'bar' => FALSE], + ], + 'User view' => [ + 'user', + 'view', + AccessResult::neutral() + ->addCacheContexts(['user.permissions']) + ->setReason("The 'administer workflows' permission is required."), + ], + 'User update' => [ + 'user', + 'update', + AccessResult::neutral() + ->addCacheContexts(['user.permissions']) + ->setReason("The 'administer workflows' permission is required."), + ], + 'User delete' => [ + 'user', + 'delete', + AccessResult::neutral() + ->addCacheContexts(['user.permissions']) + ->setReason("The 'administer workflows' permission is required."), + ], + 'User delete only state' => [ + 'user', + 'delete-state:foo', + AccessResult::neutral()->addCacheTags(['config:workflows.workflow.test_workflow']), + ['foo' => FALSE], + ], + 'User delete one of two states' => [ + 'user', + 'delete-state:foo', + AccessResult::neutral() + ->addCacheTags(['config:workflows.workflow.test_workflow']) + ->addCacheContexts(['user.permissions']) + ->setReason("The 'administer workflows' permission is required."), + ['foo' => FALSE, 'bar' => FALSE], + ], + 'User delete required state when there are >1 states' => [ + 'user', + 'delete-state:foo', + AccessResult::neutral() + ->addCacheTags(['config:workflows.workflow.test_workflow']) + ->addCacheContexts(['user.permissions']) + ->setReason("The 'administer workflows' permission is required."), + ['foo' => TRUE, 'bar' => FALSE], + ], + ]; + } + +} diff --git a/core/modules/workflows/tests/src/Kernel/WorkflowDependenciesTest.php b/core/modules/workflows/tests/src/Kernel/WorkflowDependenciesTest.php new file mode 100644 index 00000000..c1070dc5 --- /dev/null +++ b/core/modules/workflows/tests/src/Kernel/WorkflowDependenciesTest.php @@ -0,0 +1,41 @@ + 'test3', 'type' => 'workflow_type_complex_test']); + $workflow->setThirdPartySetting('workflow_third_party_settings_test', 'key', 'value'); + $workflow->save(); + $this->assertSame(['workflow_third_party_settings_test', 'workflow_type_test'], $workflow->getDependencies()['module']); + + // Uninstall workflow_third_party_settings_test to ensure + // \Drupal\workflows\Entity\Workflow::onDependencyRemoval() works as + // expected. + \Drupal::service('module_installer')->uninstall(['node', 'workflow_third_party_settings_test']); + /** @var \Drupal\workflows\WorkflowInterface $workflow */ + $workflow = \Drupal::entityTypeManager()->getStorage('workflow')->loadUnchanged($workflow->id()); + $this->assertSame(['workflow_type_test'], $workflow->getDependencies()['module']); + } + +} diff --git a/core/modules/workflows/tests/src/Unit/StateTest.php b/core/modules/workflows/tests/src/Unit/StateTest.php new file mode 100644 index 00000000..92edbb9f --- /dev/null +++ b/core/modules/workflows/tests/src/Unit/StateTest.php @@ -0,0 +1,108 @@ +prophesize(WorkflowTypeInterface::class)->reveal(), + 'draft', + 'Draft', + 3 + ); + $this->assertEquals('draft', $state->id()); + $this->assertEquals('Draft', $state->label()); + $this->assertEquals(3, $state->weight()); + } + + /** + * @covers ::canTransitionTo + */ + public function testCanTransitionTo() { + $workflow_type = new TestType([], '', []); + $workflow_type + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + $state = $workflow_type->getState('draft'); + $this->assertTrue($state->canTransitionTo('published')); + $this->assertFalse($state->canTransitionTo('some_other_state')); + + $workflow_type->deleteTransition('publish'); + $this->assertFalse($state->canTransitionTo('published')); + } + + /** + * @covers ::getTransitionTo + */ + public function testGetTransitionTo() { + $workflow_type = new TestType([], '', []); + $workflow_type + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + $state = $workflow_type->getState('draft'); + $transition = $state->getTransitionTo('published'); + $this->assertEquals('Publish', $transition->label()); + } + + /** + * @covers ::getTransitionTo + */ + public function testGetTransitionToException() { + $this->setExpectedException(\InvalidArgumentException::class, "Can not transition to 'published' state"); + $workflow_type = new TestType([], '', []); + $workflow_type->addState('draft', 'Draft'); + $state = $workflow_type->getState('draft'); + $state->getTransitionTo('published'); + } + + /** + * @covers ::getTransitions + */ + public function testGetTransitions() { + $workflow_type = new TestType([], '', []); + $workflow_type + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft'], 'published') + ->addTransition('archive', 'Archive', ['published'], 'archived'); + $state = $workflow_type->getState('draft'); + $transitions = $state->getTransitions(); + $this->assertCount(2, $transitions); + $this->assertEquals('Create new draft', $transitions['create_new_draft']->label()); + $this->assertEquals('Publish', $transitions['publish']->label()); + } + + /** + * @covers ::labelCallback + */ + public function testLabelCallback() { + $workflow_type = $this->prophesize(WorkflowTypeInterface::class)->reveal(); + $states = [ + new State($workflow_type, 'draft', 'Draft'), + new State($workflow_type, 'published', 'Published'), + ]; + $this->assertEquals(['Draft', 'Published'], array_map([State::class, 'labelCallback'], $states)); + } + +} diff --git a/core/modules/workflows/tests/src/Unit/TransitionTest.php b/core/modules/workflows/tests/src/Unit/TransitionTest.php new file mode 100644 index 00000000..bbab5cf5 --- /dev/null +++ b/core/modules/workflows/tests/src/Unit/TransitionTest.php @@ -0,0 +1,50 @@ +prophesize(WorkflowTypeInterface::class)->reveal(), + 'draft_published', + 'Publish', + ['draft'], + 'published' + ); + $this->assertEquals('draft_published', $state->id()); + $this->assertEquals('Publish', $state->label()); + } + + /** + * @covers ::from + * @covers ::to + */ + public function testFromAndTo() { + $workflow = new TestType([], '', []); + $workflow + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + $state = $workflow->getState('draft'); + $transition = $state->getTransitionTo('published'); + $this->assertEquals($state, $transition->from()['draft']); + $this->assertEquals($workflow->getState('published'), $transition->to()); + } + +} diff --git a/core/modules/workflows/tests/src/Unit/WorkflowTest.php b/core/modules/workflows/tests/src/Unit/WorkflowTest.php new file mode 100644 index 00000000..8cf44936 --- /dev/null +++ b/core/modules/workflows/tests/src/Unit/WorkflowTest.php @@ -0,0 +1,668 @@ +prophesize(WorkflowTypeManager::class); + $workflow_manager->createInstance('test_type', Argument::any())->willReturn(new TestType([], '', [])); + $container->set('plugin.manager.workflows.type', $workflow_manager->reveal()); + \Drupal::setContainer($container); + } + + /** + * @covers ::addState + * @covers ::hasState + */ + public function testAddAndHasState() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $this->assertFalse($workflow->getTypePlugin()->hasState('draft')); + + // By default states are ordered in the order added. + $workflow->getTypePlugin()->addState('draft', 'Draft'); + $this->assertTrue($workflow->getTypePlugin()->hasState('draft')); + $this->assertFalse($workflow->getTypePlugin()->hasState('published')); + $this->assertEquals(0, $workflow->getTypePlugin()->getState('draft')->weight()); + // Adding a state does not set up a transition to itself. + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('draft', 'draft')); + + // New states are added with a new weight 1 more than the current highest + // weight. + $workflow->getTypePlugin()->addState('published', 'Published'); + $this->assertEquals(1, $workflow->getTypePlugin()->getState('published')->weight()); + } + + /** + * @covers ::addState + */ + public function testAddStateException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' already exists in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('draft', 'Draft'); + $workflow->getTypePlugin()->addState('draft', 'Draft'); + } + + /** + * @covers ::addState + */ + public function testAddStateInvalidIdException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state ID 'draft-draft' must contain only lowercase letters, numbers, and underscores"); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('draft-draft', 'Draft'); + } + + /** + * @covers ::getStates + */ + public function testGetStates() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + + // Getting states works when there are none. + $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getStates())); + $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getStates([]))); + + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived'); + + // States are stored in alphabetical key order. + $this->assertArrayEquals([ + 'archived', + 'draft', + 'published', + ], array_keys($workflow->getTypePlugin()->getConfiguration()['states'])); + + // Ensure we're returning state objects. + $this->assertInstanceOf(State::class, $workflow->getTypePlugin()->getStates()['draft']); + + // Passing in no IDs returns all states. + $this->assertArrayEquals(['draft', 'published', 'archived'], array_keys($workflow->getTypePlugin()->getStates())); + + // The order of states is by weight. + $workflow->getTypePlugin()->setStateWeight('published', -1); + $this->assertArrayEquals(['published', 'draft', 'archived'], array_keys($workflow->getTypePlugin()->getStates())); + + // The label is also used for sorting if weights are equal. + $workflow->getTypePlugin()->setStateWeight('archived', 0); + $this->assertArrayEquals(['published', 'archived', 'draft'], array_keys($workflow->getTypePlugin()->getStates())); + + // You can limit the states returned by passing in states IDs. + $this->assertArrayEquals(['archived', 'draft'], array_keys($workflow->getTypePlugin()->getStates(['draft', 'archived']))); + + // An empty array does not load all states. + $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getStates([]))); + } + + /** + * Test numeric IDs when added to a workflow. + */ + public function testNumericIdSorting() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow_type = $workflow->getTypePlugin(); + + $workflow_type->addState('1', 'One'); + $workflow_type->addState('2', 'Two'); + $workflow_type->addState('3', 'ZZZ'); + $workflow_type->addState('4', 'AAA'); + + $workflow_type->setStateWeight('1', 1); + $workflow_type->setStateWeight('2', 2); + $workflow_type->setStateWeight('3', 3); + $workflow_type->setStateWeight('4', 3); + + // Ensure numeric states are correctly sorted by weight first, label second. + $this->assertEquals([1, 2, 4, 3], array_keys($workflow_type->getStates())); + } + + /** + * @covers ::getStates + */ + public function testGetStatesException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'state_that_does_not_exist' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->getStates(['state_that_does_not_exist']); + } + + /** + * @covers ::getState + */ + public function testGetState() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + + // Ensure we're returning state objects and they are set up correctly + $this->assertInstanceOf(State::class, $workflow->getTypePlugin()->getState('draft')); + $this->assertEquals('archived', $workflow->getTypePlugin()->getState('archived')->id()); + $this->assertEquals('Archived', $workflow->getTypePlugin()->getState('archived')->label()); + + $draft = $workflow->getTypePlugin()->getState('draft'); + $this->assertTrue($draft->canTransitionTo('draft')); + $this->assertTrue($draft->canTransitionTo('published')); + $this->assertFalse($draft->canTransitionTo('archived')); + $this->assertEquals('Publish', $draft->getTransitionTo('published')->label()); + $this->assertEquals(0, $draft->weight()); + $this->assertEquals(1, $workflow->getTypePlugin()->getState('published')->weight()); + $this->assertEquals(2, $workflow->getTypePlugin()->getState('archived')->weight()); + } + + /** + * @covers ::getState + */ + public function testGetStateException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'state_that_does_not_exist' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->getState('state_that_does_not_exist'); + } + + /** + * @covers ::setStateLabel + */ + public function testSetStateLabel() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('draft', 'Draft'); + $this->assertEquals('Draft', $workflow->getTypePlugin()->getState('draft')->label()); + $workflow->getTypePlugin()->setStateLabel('draft', 'Unpublished'); + $this->assertEquals('Unpublished', $workflow->getTypePlugin()->getState('draft')->label()); + } + + /** + * @covers ::setStateLabel + */ + public function testSetStateLabelException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->setStateLabel('draft', 'Draft'); + } + + /** + * @covers ::setStateWeight + */ + public function testSetStateWeight() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('draft', 'Draft'); + $this->assertEquals(0, $workflow->getTypePlugin()->getState('draft')->weight()); + $workflow->getTypePlugin()->setStateWeight('draft', -10); + $this->assertEquals(-10, $workflow->getTypePlugin()->getState('draft')->weight()); + } + + /** + * @covers ::setStateWeight + */ + public function testSetStateWeightException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->setStateWeight('draft', 10); + } + + /** + * @covers ::deleteState + */ + public function testDeleteState() { + $workflow_type = new TestType([], '', []); + $workflow_type + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('publish', 'Publish', ['draft', 'published'], 'published') + ->addTransition('create_new_draft', 'Create new draft', ['draft', 'published'], 'draft') + ->addTransition('archive', 'Archive', ['draft', 'published'], 'archived'); + $this->assertCount(3, $workflow_type->getStates()); + $this->assertCount(3, $workflow_type->getState('published')->getTransitions()); + $workflow_type->deleteState('draft'); + $this->assertFalse($workflow_type->hasState('draft')); + $this->assertCount(2, $workflow_type->getStates()); + $this->assertCount(2, $workflow_type->getState('published')->getTransitions()); + $workflow_type->deleteState('published'); + $this->assertCount(0, $workflow_type->getTransitions()); + } + + /** + * @covers ::deleteState + */ + public function testDeleteStateException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->deleteState('draft'); + } + + /** + * @covers ::deleteState + */ + public function testDeleteOnlyStateException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' can not be deleted from workflow as it is the only state"); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('draft', 'Draft'); + $workflow->getTypePlugin()->deleteState('draft'); + } + + /** + * @covers ::addTransition + * @covers ::hasTransition + */ + public function testAddTransition() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published'); + + $this->assertFalse($workflow->getTypePlugin()->getState('draft')->canTransitionTo('published')); + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['draft'], 'published'); + $this->assertTrue($workflow->getTypePlugin()->getState('draft')->canTransitionTo('published')); + $this->assertEquals(0, $workflow->getTypePlugin()->getTransition('publish')->weight()); + $this->assertTrue($workflow->getTypePlugin()->hasTransition('publish')); + $this->assertFalse($workflow->getTypePlugin()->hasTransition('draft')); + + $workflow->getTypePlugin()->addTransition('save_publish', 'Save', ['published'], 'published'); + $this->assertEquals(1, $workflow->getTypePlugin()->getTransition('save_publish')->weight()); + } + + /** + * @covers ::addTransition + */ + public function testAddTransitionDuplicateException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition 'publish' already exists in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['published'], 'published'); + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['published'], 'published'); + } + + /** + * @covers ::addTransition + */ + public function testAddTransitionInvalidIdException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition ID 'publish-publish' must contain only lowercase letters, numbers, and underscores"); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + $workflow->getTypePlugin()->addTransition('publish-publish', 'Publish', ['published'], 'published'); + } + + /** + * @covers ::addTransition + */ + public function testAddTransitionMissingFromException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['draft'], 'published'); + } + + /** + * @covers ::addTransition + */ + public function testAddTransitionDuplicateTransitionStatesException() { + $this->setExpectedException(\InvalidArgumentException::class, "The 'publish' transition already allows 'draft' to 'published' transitions in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published'); + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['draft', 'published'], 'published'); + $workflow->getTypePlugin()->addTransition('draft_to_published', 'Publish a draft', ['draft'], 'published'); + } + + /** + * @covers ::addTransition + */ + public function testAddTransitionConsistentAfterFromCatch() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + try { + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['draft'], 'published'); + } + catch (\InvalidArgumentException $e) { + } + // Ensure that the workflow is not left in an inconsistent state after an + // exception is thrown from Workflow::setTransitionFromStates() whilst + // calling Workflow::addTransition(). + $this->assertFalse($workflow->getTypePlugin()->hasTransition('publish')); + } + + /** + * @covers ::addTransition + */ + public function testAddTransitionMissingToException() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'published' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('draft', 'Draft'); + $workflow->getTypePlugin()->addTransition('publish', 'Publish', ['draft'], 'published'); + } + + /** + * @covers ::getTransitions + * @covers ::setTransitionWeight + */ + public function testGetTransitions() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + + // Getting transitions works when there are none. + $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getTransitions())); + $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getTransitions([]))); + + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('a', 'A') + ->addState('b', 'B') + ->addTransition('a_b', 'A to B', ['a'], 'b') + ->addTransition('a_a', 'A to A', ['a'], 'a'); + + // Transitions are stored in alphabetical key order in configuration. + $this->assertArrayEquals(['a_a', 'a_b'], array_keys($workflow->getTypePlugin()->getConfiguration()['transitions'])); + + // Ensure we're returning transition objects. + $this->assertInstanceOf(Transition::class, $workflow->getTypePlugin()->getTransitions()['a_a']); + + // Passing in no IDs returns all transitions. + $this->assertArrayEquals(['a_b', 'a_a'], array_keys($workflow->getTypePlugin()->getTransitions())); + + // The order of states is by weight. + $workflow->getTypePlugin()->setTransitionWeight('a_a', -1); + $this->assertArrayEquals(['a_a', 'a_b'], array_keys($workflow->getTypePlugin()->getTransitions())); + + // If all weights are equal it will fallback to labels. + $workflow->getTypePlugin()->setTransitionWeight('a_a', 0); + $this->assertArrayEquals(['a_a', 'a_b'], array_keys($workflow->getTypePlugin()->getTransitions())); + $workflow->getTypePlugin()->setTransitionLabel('a_b', 'A B'); + $this->assertArrayEquals(['a_b', 'a_a'], array_keys($workflow->getTypePlugin()->getTransitions())); + + // You can limit the states returned by passing in states IDs. + $this->assertArrayEquals(['a_a'], array_keys($workflow->getTypePlugin()->getTransitions(['a_a']))); + + // An empty array does not load all states. + $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getTransitions([]))); + } + + + /** + * @covers ::getTransition + */ + public function testGetTransition() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + + // Ensure we're returning state objects and they are set up correctly + $this->assertInstanceOf(Transition::class, $workflow->getTypePlugin()->getTransition('create_new_draft')); + $this->assertEquals('publish', $workflow->getTypePlugin()->getTransition('publish')->id()); + $this->assertEquals('Publish', $workflow->getTypePlugin()->getTransition('publish')->label()); + + $transition = $workflow->getTypePlugin()->getTransition('publish'); + $this->assertEquals($workflow->getTypePlugin()->getState('draft'), $transition->from()['draft']); + $this->assertEquals($workflow->getTypePlugin()->getState('published'), $transition->to()); + } + + /** + * @covers ::getTransition + */ + public function testGetTransitionException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition 'transition_that_does_not_exist' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->getTransition('transition_that_does_not_exist'); + } + + /** + * @covers ::getTransitionsForState + */ + public function testGetTransitionsForState() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['archived', 'draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft', 'published'], 'published') + ->addTransition('archive', 'Archive', ['published'], 'archived'); + + $this->assertEquals(['create_new_draft', 'publish'], array_keys($workflow->getTypePlugin()->getTransitionsForState('draft'))); + $this->assertEquals(['create_new_draft'], array_keys($workflow->getTypePlugin()->getTransitionsForState('draft', 'to'))); + $this->assertEquals(['publish', 'archive'], array_keys($workflow->getTypePlugin()->getTransitionsForState('published'))); + $this->assertEquals(['publish'], array_keys($workflow->getTypePlugin()->getTransitionsForState('published', 'to'))); + $this->assertEquals(['create_new_draft'], array_keys($workflow->getTypePlugin()->getTransitionsForState('archived', 'from'))); + $this->assertEquals(['archive'], array_keys($workflow->getTypePlugin()->getTransitionsForState('archived', 'to'))); + } + + + /** + * @covers ::getTransitionFromStateToState + * @covers ::hasTransitionFromStateToState + */ + public function testGetTransitionFromStateToState() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['archived', 'draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft', 'published'], 'published') + ->addTransition('archive', 'Archive', ['published'], 'archived'); + + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('draft', 'published')); + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('archived', 'archived')); + $transition = $workflow->getTypePlugin()->getTransitionFromStateToState('published', 'archived'); + $this->assertEquals('Archive', $transition->label()); + } + + /** + * @covers ::getTransitionFromStateToState + */ + public function testGetTransitionFromStateToStateException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition from 'archived' to 'archived' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + // By default states are ordered in the order added. + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['archived', 'draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft', 'published'], 'published') + ->addTransition('archive', 'Archive', ['published'], 'archived'); + + $workflow->getTypePlugin()->getTransitionFromStateToState('archived', 'archived'); + } + + /** + * @covers ::setTransitionLabel + */ + public function testSetTransitionLabel() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + $this->assertEquals('Publish', $workflow->getTypePlugin()->getTransition('publish')->label()); + $workflow->getTypePlugin()->setTransitionLabel('publish', 'Publish!'); + $this->assertEquals('Publish!', $workflow->getTypePlugin()->getTransition('publish')->label()); + } + + /** + * @covers ::setTransitionLabel + */ + public function testSetTransitionLabelException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition 'draft-published' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + $workflow->getTypePlugin()->setTransitionLabel('draft-published', 'Publish'); + } + + /** + * @covers ::setTransitionWeight + */ + public function testSetTransitionWeight() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + $this->assertEquals(0, $workflow->getTypePlugin()->getTransition('publish')->weight()); + $workflow->getTypePlugin()->setTransitionWeight('publish', 10); + $this->assertEquals(10, $workflow->getTypePlugin()->getTransition('publish')->weight()); + } + + /** + * @covers ::setTransitionWeight + */ + public function testSetTransitionWeightException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition 'draft-published' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + $workflow->getTypePlugin()->setTransitionWeight('draft-published', 10); + } + + /** + * @covers ::setTransitionFromStates + */ + public function testSetTransitionFromStates() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('test', 'Test', ['draft'], 'draft'); + + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('draft', 'draft')); + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('published', 'draft')); + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('archived', 'draft')); + $workflow->getTypePlugin()->setTransitionFromStates('test', ['draft', 'published', 'archived']); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('draft', 'draft')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('published', 'draft')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('archived', 'draft')); + $workflow->getTypePlugin()->setTransitionFromStates('test', ['published', 'archived']); + $this->assertFalse($workflow->getTypePlugin()->hasTransitionFromStateToState('draft', 'draft')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('published', 'draft')); + $this->assertTrue($workflow->getTypePlugin()->hasTransitionFromStateToState('archived', 'draft')); + } + + /** + * @covers ::setTransitionFromStates + */ + public function testSetTransitionFromStatesMissingTransition() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition 'test' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft'); + + $workflow->getTypePlugin()->setTransitionFromStates('test', ['draft', 'published', 'archived']); + } + + /** + * @covers ::setTransitionFromStates + */ + public function testSetTransitionFromStatesMissingState() { + $this->setExpectedException(\InvalidArgumentException::class, "The state 'published' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('archived', 'Archived') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft'); + + $workflow->getTypePlugin()->setTransitionFromStates('create_new_draft', ['draft', 'published', 'archived']); + } + + /** + * @covers ::setTransitionFromStates + */ + public function testSetTransitionFromStatesAlreadyExists() { + $this->setExpectedException(\InvalidArgumentException::class, "The 'create_new_draft' transition already allows 'draft' to 'draft' transitions in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow + ->getTypePlugin() + ->addState('draft', 'Draft') + ->addState('archived', 'Archived') + ->addState('needs_review', 'Needs Review') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft') + ->addTransition('needs_review', 'Needs review', ['needs_review'], 'draft'); + + $workflow->getTypePlugin()->setTransitionFromStates('needs_review', ['draft']); + } + + /** + * @covers ::deleteTransition + */ + public function testDeleteTransition() { + $workflow_type = new TestType([], '', []); + $workflow_type + ->addState('draft', 'Draft') + ->addState('published', 'Published') + ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft') + ->addTransition('publish', 'Publish', ['draft'], 'published'); + $this->assertTrue($workflow_type->getState('draft')->canTransitionTo('published')); + $workflow_type->deleteTransition('publish'); + $this->assertFalse($workflow_type->getState('draft')->canTransitionTo('published')); + $this->assertTrue($workflow_type->getState('draft')->canTransitionTo('draft')); + } + + /** + * @covers ::deleteTransition + */ + public function testDeleteTransitionException() { + $this->setExpectedException(\InvalidArgumentException::class, "The transition 'draft-published' does not exist in workflow."); + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $workflow->getTypePlugin()->addState('published', 'Published'); + $workflow->getTypePlugin()->deleteTransition('draft-published'); + } + + /** + * @covers \Drupal\workflows\Entity\Workflow::status + */ + public function testStatus() { + $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); + $this->assertFalse($workflow->status()); + $workflow->getTypePlugin()->addState('published', 'Published'); + $this->assertTrue($workflow->status()); + } + +} diff --git a/core/modules/workflows/workflows.api.php b/core/modules/workflows/workflows.api.php new file mode 100644 index 00000000..ca55c877 --- /dev/null +++ b/core/modules/workflows/workflows.api.php @@ -0,0 +1,17 @@ +' . t('About') . ''; + $output .= '

' . t('The Workflows module provides a UI and an API for creating workflows content. This lets site admins define workflows and their states, and then define transitions between those states. For more information, see the online documentation for the Workflows module.', [':workflow' => 'https://www.drupal.org/documentation/modules/workflows']) . '

'; + $output .= '

' . t('Workflow') . '

'; + $output .= '

' . t('A collection of states and transitions between those states.') . '

'; + $output .= '

' . t('State') . '

'; + $output .= '

' . t('A particular condition that something is in at a specific time. The usage of the state is determined by a module that harnesses the Workflows module. For example, Content Moderation allows a state to be used for moderation of content by assigning a given state to a content item.') . '

'; + $output .= '

' . t('Transition') . '

'; + $output .= '

' . t('The process of changing from one state to another. A transition can occur from multiple states, but only to one state.') . '

'; + return $output; + } +} diff --git a/core/modules/workflows/workflows.permissions.yml b/core/modules/workflows/workflows.permissions.yml new file mode 100644 index 00000000..5889aaca --- /dev/null +++ b/core/modules/workflows/workflows.permissions.yml @@ -0,0 +1,4 @@ +administer workflows: + title: 'Administer workflows' + description: 'Create and edit workflows.' + restrict access: TRUE diff --git a/core/modules/workflows/workflows.routing.yml b/core/modules/workflows/workflows.routing.yml new file mode 100644 index 00000000..329ed10c --- /dev/null +++ b/core/modules/workflows/workflows.routing.yml @@ -0,0 +1,47 @@ +entity.workflow.add_state_form: + path: '/admin/config/workflow/workflows/manage/{workflow}/add_state' + defaults: + _entity_form: 'workflow.add-state' + _title: 'Add state' + requirements: + _entity_access: 'workflow.edit' + +entity.workflow.edit_state_form: + path: '/admin/config/workflow/workflows/manage/{workflow}/state/{workflow_state}' + defaults: + _entity_form: 'workflow.edit-state' + _title: 'Edit state' + requirements: + _entity_access: 'workflow.edit' + +entity.workflow.delete_state_form: + path: '/admin/config/workflow/workflows/manage/{workflow}/state/{workflow_state}/delete' + defaults: + _form: '\Drupal\workflows\Form\WorkflowStateDeleteForm' + _title: 'Delete state' + requirements: + _workflow_state_delete_access: 'true' + +entity.workflow.add_transition_form: + path: '/admin/config/workflow/workflows/manage/{workflow}/add_transition' + defaults: + _entity_form: 'workflow.add-transition' + _title: 'Add transition' + requirements: + _entity_access: 'workflow.edit' + +entity.workflow.edit_transition_form: + path: '/admin/config/workflow/workflows/manage/{workflow}/transition/{workflow_transition}' + defaults: + _entity_form: 'workflow.edit-transition' + _title: 'Edit transition' + requirements: + _entity_access: 'workflow.edit' + +entity.workflow.delete_transition_form: + path: '/admin/config/workflow/workflows/manage/{workflow}/transition/{workflow_transition}/delete' + defaults: + _form: '\Drupal\workflows\Form\WorkflowTransitionDeleteForm' + _title: 'Delete transition' + requirements: + _entity_access: 'workflow.edit' diff --git a/core/modules/workflows/workflows.services.yml b/core/modules/workflows/workflows.services.yml new file mode 100644 index 00000000..7d324202 --- /dev/null +++ b/core/modules/workflows/workflows.services.yml @@ -0,0 +1,10 @@ +services: + plugin.manager.workflows.type: + class: Drupal\workflows\WorkflowTypeManager + parent: default_plugin_manager + tags: + - { name: plugin_manager_cache_clear } + workflows.access_check.delete_state: + class: \Drupal\workflows\WorkflowDeleteAccessCheck + tags: + - { name: access_check, applies_to: _workflow_state_delete_access } diff --git a/core/package.json b/core/package.json new file mode 100644 index 00000000..6e9a49c1 --- /dev/null +++ b/core/package.json @@ -0,0 +1,54 @@ +{ + "name": "Drupal", + "description": "Drupal is an open source content management platform powering millions of websites and applications.", + "license": "GPL-2.0", + "private": true, + "scripts": { + "build:js": "node ./scripts/js/babel-es6-build.js", + "build:js-dev": "cross-env NODE_ENV=development node ./scripts/js/babel-es6-build.js", + "watch:js": "node ./scripts/js/babel-es6-watch.js", + "watch:js-dev": "cross-env NODE_ENV=development node ./scripts/js/babel-es6-watch.js", + "lint:core-js": "node ./node_modules/eslint/bin/eslint.js --ext=.es6.js . || exit 0", + "lint:css": "stylelint \"**/*.css\" || exit 0", + "lint:css-checkstyle": "stylelint \"**/*.css\" --custom-formatter ./node_modules/stylelint-checkstyle-formatter/index.js || exit 0" + }, + "devDependencies": { + "babel-core": "6.24.1", + "babel-plugin-add-header-comment": "1.0.3", + "babel-preset-env": "1.4.0", + "chalk": "^1.1.3", + "chokidar": "1.6.1", + "cross-env": "^4.0.0", + "eslint": "3.19.0", + "eslint-config-airbnb": "14.1.0", + "eslint-plugin-import": "2.2.0", + "eslint-plugin-jsx-a11y": "4.0.0", + "eslint-plugin-react": "6.10.3", + "glob": "7.1.1", + "minimist": "^1.2.0", + "stylelint": "^7.10.1", + "stylelint-checkstyle-formatter": "^0.1.0", + "stylelint-config-standard": "^16.0.0", + "stylelint-no-browser-hacks": "^1.0.2" + }, + "babel": { + "presets": [ + [ + "env", + { + "modules": false, + "targets": { + "browsers": [ + "ie >= 9", + "edge >= 13", + "firefox >= 5", + "opera >= 12", + "safari >= 5", + "chrome >= 56" + ] + } + } + ] + ] + } +} diff --git a/core/phpcs.xml.dist b/core/phpcs.xml.dist index e82c85a0..5b07e1e8 100644 --- a/core/phpcs.xml.dist +++ b/core/phpcs.xml.dist @@ -10,18 +10,25 @@ ./modules/system/tests/fixtures/HtaccessTest + + + ./core/lib/Drupal/Component/Diff/ + - - - - - - - + + + + + + + + + + - + @@ -41,76 +48,185 @@ - - - + + + - - - - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + - + + + + diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist index ef1ae3b6..e5bab48f 100644 --- a/core/phpunit.xml.dist +++ b/core/phpunit.xml.dist @@ -45,8 +45,12 @@ + + + + diff --git a/core/profiles/minimal/minimal.info.yml b/core/profiles/minimal/minimal.info.yml index a3c6a1d3..36cb6b5a 100644 --- a/core/profiles/minimal/minimal.info.yml +++ b/core/profiles/minimal/minimal.info.yml @@ -12,8 +12,8 @@ dependencies: themes: - stark -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/minimal/src/Tests/MinimalTest.php b/core/profiles/minimal/tests/src/Functional/MinimalTest.php similarity index 80% rename from core/profiles/minimal/src/Tests/MinimalTest.php rename to core/profiles/minimal/tests/src/Functional/MinimalTest.php index 056565e7..b5f170d4 100644 --- a/core/profiles/minimal/src/Tests/MinimalTest.php +++ b/core/profiles/minimal/tests/src/Functional/MinimalTest.php @@ -1,22 +1,22 @@ drupalGet(''); // Check the login block is present. $this->assertLink(t('Create new account')); @@ -24,7 +24,7 @@ function testMinimal() { // Create a user to test tools and navigation blocks for logged in users // with appropriate permissions. - $user = $this->drupalCreateUser(array('access administration pages', 'administer content types')); + $user = $this->drupalCreateUser(['access administration pages', 'administer content types']); $this->drupalLogin($user); $this->drupalGet(''); $this->assertText(t('Tools')); diff --git a/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml b/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml index ee0c1384..7ccb5b0a 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.block_content.basic.default.yml @@ -14,6 +14,7 @@ content: body: type: text_textarea_with_summary weight: -4 + region: content settings: rows: 9 summary_rows: 3 @@ -22,6 +23,7 @@ content: info: type: string_textfield weight: -5 + region: content settings: size: 60 placeholder: '' diff --git a/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml b/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml index fa5d834c..1010be29 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.comment.comment.default.yml @@ -13,9 +13,11 @@ mode: default content: author: weight: -2 + region: content comment_body: type: text_textarea weight: 11 + region: content settings: rows: 5 placeholder: '' @@ -23,6 +25,7 @@ content: subject: type: string_textfield weight: 10 + region: content settings: size: 60 placeholder: '' diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml index 79156b2e..9082f2d1 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml @@ -21,6 +21,7 @@ content: body: type: text_textarea_with_summary weight: 1 + region: content settings: rows: 9 summary_rows: 3 @@ -29,16 +30,19 @@ content: comment: type: comment_default weight: 20 + region: content settings: { } third_party_settings: { } created: type: datetime_timestamp weight: 10 + region: content settings: { } third_party_settings: { } field_image: type: image_image weight: 4 + region: content settings: progress_indicator: throbber preview_image_style: thumbnail @@ -46,11 +50,13 @@ content: field_tags: type: entity_reference_autocomplete_tags weight: 3 + region: content settings: { } third_party_settings: { } path: type: path weight: 30 + region: content settings: { } third_party_settings: { } promote: @@ -58,16 +64,26 @@ content: settings: display_label: true weight: 15 + region: content + third_party_settings: { } + status: + type: boolean_checkbox + settings: + display_label: true + weight: 120 + region: content third_party_settings: { } sticky: type: boolean_checkbox settings: display_label: true weight: 16 + region: content third_party_settings: { } title: type: string_textfield weight: 0 + region: content settings: size: 60 placeholder: '' @@ -75,6 +91,7 @@ content: uid: type: entity_reference_autocomplete weight: 5 + region: content settings: match_operator: CONTAINS size: 60 diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml index 1fef06d1..682f1a55 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml @@ -15,6 +15,7 @@ content: body: type: text_textarea_with_summary weight: 31 + region: content settings: rows: 9 summary_rows: 3 @@ -23,11 +24,13 @@ content: created: type: datetime_timestamp weight: 10 + region: content settings: { } third_party_settings: { } path: type: path weight: 30 + region: content settings: { } third_party_settings: { } promote: @@ -35,16 +38,26 @@ content: settings: display_label: true weight: 15 + region: content + third_party_settings: { } + status: + type: boolean_checkbox + settings: + display_label: true + weight: 120 + region: content third_party_settings: { } sticky: type: boolean_checkbox settings: display_label: true weight: 16 + region: content third_party_settings: { } title: type: string_textfield weight: -5 + region: content settings: size: 60 placeholder: '' @@ -52,6 +65,7 @@ content: uid: type: entity_reference_autocomplete weight: 5 + region: content settings: match_operator: CONTAINS size: 60 diff --git a/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml b/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml index 466b6e0b..68322292 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.user.user.default.yml @@ -14,12 +14,16 @@ mode: default content: account: weight: -10 + region: content contact: weight: 5 + region: content language: weight: 0 + region: content timezone: weight: 6 + region: content user_picture: type: image_image settings: @@ -27,4 +31,5 @@ content: preview_image_style: thumbnail third_party_settings: { } weight: -1 + region: content hidden: { } diff --git a/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml b/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml index bd52f775..e494882d 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.block_content.basic.default.yml @@ -15,6 +15,7 @@ content: label: hidden type: text_default weight: 0 + region: content settings: { } third_party_settings: { } hidden: { } diff --git a/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml b/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml index 1ed49ce2..6ae213d3 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.comment.comment.default.yml @@ -15,8 +15,10 @@ content: label: hidden type: text_default weight: 0 + region: content settings: { } third_party_settings: { } links: weight: 100 + region: content hidden: { } diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml index 98a2de8a..5c432527 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.default.yml @@ -22,12 +22,14 @@ content: body: type: text_default weight: 0 + region: content settings: { } third_party_settings: { } label: hidden comment: type: comment_default weight: 110 + region: content label: above settings: view_mode: default @@ -36,6 +38,7 @@ content: field_image: type: image weight: -1 + region: content settings: image_style: large image_link: '' @@ -44,12 +47,14 @@ content: field_tags: type: entity_reference_label weight: 10 + region: content label: above settings: link: true third_party_settings: { } links: weight: 100 + region: content hidden: field_image: true field_tags: true diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml index 75a14a3f..84660b6d 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.rss.yml @@ -17,6 +17,7 @@ mode: rss content: links: weight: 100 + region: content hidden: body: true comment: true diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml b/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml index 43ee079e..7b96908b 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.article.teaser.yml @@ -21,6 +21,7 @@ content: body: type: text_summary_or_trimmed weight: 0 + region: content settings: trim_length: 600 third_party_settings: { } @@ -28,6 +29,7 @@ content: field_image: type: image weight: -1 + region: content settings: image_style: medium image_link: content @@ -36,12 +38,14 @@ content: field_tags: type: entity_reference_label weight: 10 + region: content settings: link: true third_party_settings: { } label: above links: weight: 100 + region: content hidden: comment: true field_image: true diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml index dcb2d3ec..8afd9423 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.page.default.yml @@ -16,8 +16,10 @@ content: label: hidden type: text_default weight: 100 + region: content settings: { } third_party_settings: { } links: weight: 101 + region: content hidden: { } diff --git a/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml b/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml index f235a10e..bc7a68c5 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.node.page.teaser.yml @@ -17,9 +17,11 @@ content: label: hidden type: text_summary_or_trimmed weight: 100 + region: content settings: trim_length: 600 third_party_settings: { } links: weight: 101 + region: content hidden: { } diff --git a/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml b/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml index 4c137924..2ff13ad1 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.user.user.compact.yml @@ -16,6 +16,7 @@ content: user_picture: type: image weight: 0 + region: content settings: image_style: thumbnail image_link: content diff --git a/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml b/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml index 9e4621d5..ef1fdd79 100644 --- a/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml +++ b/core/profiles/standard/config/install/core.entity_view_display.user.user.default.yml @@ -14,9 +14,11 @@ mode: default content: member_for: weight: 5 + region: content user_picture: type: image weight: 0 + region: content settings: image_style: thumbnail image_link: content diff --git a/core/profiles/standard/config/install/field.field.user.user.user_picture.yml b/core/profiles/standard/config/install/field.field.user.user.user_picture.yml index b2e61f66..e06bd7d7 100644 --- a/core/profiles/standard/config/install/field.field.user.user.user_picture.yml +++ b/core/profiles/standard/config/install/field.field.user.user.user_picture.yml @@ -19,10 +19,10 @@ default_value_callback: '' settings: file_extensions: 'png gif jpg jpeg' file_directory: 'pictures/[date:custom:Y]-[date:custom:m]' - max_filesize: '30 KB' + max_filesize: '' alt_field: false title_field: false - max_resolution: 85x85 + max_resolution: '' min_resolution: '' default_image: uuid: null diff --git a/core/profiles/standard/config/install/system.cron.yml b/core/profiles/standard/config/install/system.cron.yml index e6f30d3d..c27b41db 100644 --- a/core/profiles/standard/config/install/system.cron.yml +++ b/core/profiles/standard/config/install/system.cron.yml @@ -1,3 +1,4 @@ threshold: requirements_warning: 172800 requirements_error: 1209600 +logging: 1 diff --git a/core/profiles/standard/standard.info.yml b/core/profiles/standard/standard.info.yml index bc2d2940..8115f57b 100644 --- a/core/profiles/standard/standard.info.yml +++ b/core/profiles/standard/standard.info.yml @@ -42,8 +42,8 @@ themes: - bartik - seven -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index 0a40ce6c..2f567abb 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -25,8 +25,8 @@ function standard_install() { $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(TRUE); // Enable default permissions for system roles. - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access comments')); - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access comments', 'post comments', 'skip comment approval')); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access comments']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access comments', 'post comments', 'skip comment approval']); // Assign user 1 the "administrator" role. $user = User::load(1); @@ -40,34 +40,34 @@ function standard_install() { // Enable the Contact link in the footer menu. /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - $menu_link_manager->updateDefinition('contact.site_page', array('enabled' => TRUE)); + $menu_link_manager->updateDefinition('contact.site_page', ['enabled' => TRUE]); - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access site-wide contact form')); - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access site-wide contact form')); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access site-wide contact form']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access site-wide contact form']); // Allow authenticated users to use shortcuts. - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access shortcuts')); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access shortcuts']); // Populate the default shortcut set. - $shortcut = Shortcut::create(array( + $shortcut = Shortcut::create([ 'shortcut_set' => 'default', 'title' => t('Add content'), 'weight' => -20, - 'link' => array('uri' => 'internal:/node/add'), - )); + 'link' => ['uri' => 'internal:/node/add'], + ]); $shortcut->save(); - $shortcut = Shortcut::create(array( + $shortcut = Shortcut::create([ 'shortcut_set' => 'default', 'title' => t('All content'), 'weight' => -19, - 'link' => array('uri' => 'internal:/admin/content'), - )); + 'link' => ['uri' => 'internal:/admin/content'], + ]); $shortcut->save(); // Allow all users to use search. - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('search content')); - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('search content')); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['search content']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['search content']); // Enable the admin theme. \Drupal::configFactory()->getEditable('node.settings')->set('use_admin_theme', TRUE)->save(TRUE); diff --git a/core/profiles/standard/tests/src/Functional/StandardTest.php b/core/profiles/standard/tests/src/Functional/StandardTest.php index 4f9e756f..f449c10a 100644 --- a/core/profiles/standard/tests/src/Functional/StandardTest.php +++ b/core/profiles/standard/tests/src/Functional/StandardTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\standard\Functional; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\contact\Entity\ContactForm; use Drupal\Core\Url; use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber; @@ -31,27 +31,27 @@ class StandardTest extends BrowserTestBase { /** * Tests Standard installation profile. */ - function testStandard() { + public function testStandard() { $this->drupalGet(''); $this->assertLink(t('Contact')); $this->clickLink(t('Contact')); $this->assertResponse(200); // Test anonymous user can access 'Main navigation' block. - $this->adminUser = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser([ 'administer blocks', 'post comments', 'skip comment approval', 'create article content', 'create page content', - )); + ]); $this->drupalLogin($this->adminUser); // Configure the block. $this->drupalGet('admin/structure/block/add/system_menu_block:main/bartik'); - $this->drupalPostForm(NULL, array( + $this->drupalPostForm(NULL, [ 'region' => 'sidebar_first', 'id' => 'main_navigation', - ), t('Save block')); + ], t('Save block')); // Verify admin user can see the block. $this->drupalGet(''); $this->assertText('Main navigation'); @@ -59,18 +59,18 @@ function testStandard() { // Verify we have role = aria on system_powered_by and help_block // blocks. $this->drupalGet('admin/structure/block'); - $elements = $this->xpath('//div[@role=:role and @id=:id]', array( + $elements = $this->xpath('//div[@role=:role and @id=:id]', [ ':role' => 'complementary', ':id' => 'block-bartik-help', - )); + ]); $this->assertEqual(count($elements), 1, 'Found complementary role on help block.'); $this->drupalGet(''); - $elements = $this->xpath('//div[@role=:role and @id=:id]', array( + $elements = $this->xpath('//div[@role=:role and @id=:id]', [ ':role' => 'complementary', ':id' => 'block-bartik-powered', - )); + ]); $this->assertEqual(count($elements), 1, 'Found complementary role on powered by block.'); // Verify anonymous user can see the block. @@ -79,22 +79,22 @@ function testStandard() { // Ensure comments don't show in the front page RSS feed. // Create an article. - $this->drupalCreateNode(array( + $this->drupalCreateNode([ 'type' => 'article', 'title' => 'Foobar', 'promote' => 1, 'status' => 1, - 'body' => array(array('value' => 'Then she picked out two somebodies,
Sally and me', 'format' => 'basic_html')), - )); + 'body' => [['value' => 'Then she picked out two somebodies,
Sally and me', 'format' => 'basic_html']], + ]); // Add a comment. $this->drupalLogin($this->adminUser); $this->drupalGet('node/1'); $this->assertRaw('Then she picked out two somebodies,
Sally and me', 'Found a line break.'); - $this->drupalPostForm(NULL, array( + $this->drupalPostForm(NULL, [ 'subject[0][value]' => 'Barfoo', 'comment_body[0][value]' => 'Then she picked out two somebodies, Sally and me', - ), t('Save')); + ], t('Save')); // Fetch the feed. $this->drupalGet('rss.xml'); $this->assertText('Foobar'); @@ -131,9 +131,9 @@ function testStandard() { $filter->removeFilter('editor_file_reference'); $filter->save(); } - \Drupal::service('module_installer')->uninstall(array('editor', 'ckeditor')); + \Drupal::service('module_installer')->uninstall(['editor', 'ckeditor']); $this->rebuildContainer(); - \Drupal::service('module_installer')->install(array('editor')); + \Drupal::service('module_installer')->install(['editor']); /** @var \Drupal\contact\ContactFormInterface $contact_form */ $contact_form = ContactForm::load('feedback'); $recipients = $contact_form->getRecipients(); @@ -167,7 +167,7 @@ function testStandard() { // Make sure the optional image styles are installed after enabling // the responsive_image module. - \Drupal::service('module_installer')->install(array('responsive_image')); + \Drupal::service('module_installer')->install(['responsive_image']); $this->rebuildContainer(); $this->drupalGet('admin/config/media/image-styles'); $this->assertText('Max 325x325'); diff --git a/core/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml b/core/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml index 658dbff4..92b70e67 100644 --- a/core/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml +++ b/core/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/testing/modules/drupal_system_listing_compatible_test/src/Tests/SystemListingCompatibleTest.php b/core/profiles/testing/modules/drupal_system_listing_compatible_test/src/Tests/SystemListingCompatibleTest.php index 332b0008..7df92f26 100644 --- a/core/profiles/testing/modules/drupal_system_listing_compatible_test/src/Tests/SystemListingCompatibleTest.php +++ b/core/profiles/testing/modules/drupal_system_listing_compatible_test/src/Tests/SystemListingCompatibleTest.php @@ -20,7 +20,7 @@ class SystemListingCompatibleTest extends WebTestBase { * * @var array */ - public static $modules = array('drupal_system_listing_compatible_test'); + public static $modules = ['drupal_system_listing_compatible_test']; /** * Use the Minimal profile. @@ -35,7 +35,7 @@ class SystemListingCompatibleTest extends WebTestBase { /** * Non-empty test* method required to executed the test case class. */ - function testSystemListing() { + public function testSystemListing() { $this->pass(__CLASS__ . ' test executed.'); } diff --git a/core/profiles/testing/testing.info.yml b/core/profiles/testing/testing.info.yml index d4ff46c0..e1eb8577 100644 --- a/core/profiles/testing/testing.info.yml +++ b/core/profiles/testing/testing.info.yml @@ -13,8 +13,8 @@ dependencies: themes: - classy -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/testing_config_import/testing_config_import.info.yml b/core/profiles/testing_config_import/testing_config_import.info.yml index 6dda1230..6f5b443d 100644 --- a/core/profiles/testing_config_import/testing_config_import.info.yml +++ b/core/profiles/testing_config_import/testing_config_import.info.yml @@ -9,8 +9,8 @@ dependencies: themes: - stark -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/testing_config_overrides/config/install/system.cron.yml b/core/profiles/testing_config_overrides/config/install/system.cron.yml index e9c97bc4..f3cdb47c 100644 --- a/core/profiles/testing_config_overrides/config/install/system.cron.yml +++ b/core/profiles/testing_config_overrides/config/install/system.cron.yml @@ -1,3 +1,4 @@ threshold: requirements_warning: 259200 requirements_error: 1209600 +logging: 1 diff --git a/core/profiles/testing_config_overrides/testing_config_overrides.info.yml b/core/profiles/testing_config_overrides/testing_config_overrides.info.yml index 75238da4..544d8d61 100644 --- a/core/profiles/testing_config_overrides/testing_config_overrides.info.yml +++ b/core/profiles/testing_config_overrides/testing_config_overrides.info.yml @@ -9,8 +9,8 @@ dependencies: - language - tour -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/testing_missing_dependencies/testing_missing_dependencies.info.yml b/core/profiles/testing_missing_dependencies/testing_missing_dependencies.info.yml index e7804bf6..30b52e40 100644 --- a/core/profiles/testing_missing_dependencies/testing_missing_dependencies.info.yml +++ b/core/profiles/testing_missing_dependencies/testing_missing_dependencies.info.yml @@ -9,8 +9,8 @@ dependencies: - missing_module2 keep_english: true -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/testing_multilingual/testing_multilingual.info.yml b/core/profiles/testing_multilingual/testing_multilingual.info.yml index 50451d30..dbe15a22 100644 --- a/core/profiles/testing_multilingual/testing_multilingual.info.yml +++ b/core/profiles/testing_multilingual/testing_multilingual.info.yml @@ -8,8 +8,8 @@ dependencies: - locale - tour -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/profiles/testing_multilingual_with_english/testing_multilingual_with_english.info.yml b/core/profiles/testing_multilingual_with_english/testing_multilingual_with_english.info.yml index 63950684..4b62c6b3 100644 --- a/core/profiles/testing_multilingual_with_english/testing_multilingual_with_english.info.yml +++ b/core/profiles/testing_multilingual_with_english/testing_multilingual_with_english.info.yml @@ -8,8 +8,8 @@ dependencies: - locale keep_english: true -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/rebuild.php b/core/rebuild.php index 4e69eabf..689540bc 100644 --- a/core/rebuild.php +++ b/core/rebuild.php @@ -42,10 +42,14 @@ ((REQUEST_TIME - $request->query->get('timestamp')) < 300) && Crypt::hashEquals(Crypt::hmacBase64($request->query->get('timestamp'), Settings::get('hash_salt')), $request->query->get('token')) )) { - // Clear the APCu cache to ensure APCu class loader is reset. - if (function_exists('apcu_clear_cache')) { - apcu_clear_cache(); - } + // Clear user cache for all major platforms. + $user_caches = [ + 'apcu_clear_cache', + 'wincache_ucache_clear', + 'xcache_clear_cache', + ]; + array_map('call_user_func', array_filter($user_caches, 'is_callable')); + drupal_rebuild($autoloader, $request); drupal_set_message('Cache rebuild complete.'); } diff --git a/core/scripts/js/.eslintrc.json b/core/scripts/js/.eslintrc.json new file mode 100644 index 00000000..4152517e --- /dev/null +++ b/core/scripts/js/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "strict": [2, "global"] + } +} diff --git a/core/scripts/js/babel-es6-build.js b/core/scripts/js/babel-es6-build.js new file mode 100644 index 00000000..0bbdfebd --- /dev/null +++ b/core/scripts/js/babel-es6-build.js @@ -0,0 +1,49 @@ +/** + * @file + * + * Provides the build:js command to compile *.es6.js files to ES5. + * + * Run build:js with --file to only parse a specific file. Using the --check + * flag build:js can be run to check if files are compiled correctly. + * @example
Check if all files have been compiled correctly { + if (error) { + process.exitCode = 1; + } + // Process all the found files. + let callback = changeOrAdded; + if (argv.check) { + callback = check; + } + filePaths.forEach(callback); +}; + +if (argv.file) { + processFiles(null, [].concat(argv.file)); +} +else { + glob(fileMatch, globOptions, processFiles); +} +process.exitCode = 0; diff --git a/core/scripts/js/babel-es6-watch.js b/core/scripts/js/babel-es6-watch.js new file mode 100644 index 00000000..9b494822 --- /dev/null +++ b/core/scripts/js/babel-es6-watch.js @@ -0,0 +1,46 @@ +/** + * @file + * + * Watch changes to *.es6.js files and compile them to ES5 during development. + * + * @internal This file is part of the core javascript build process and is only + * meant to be used in that context. + */ + +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const chokidar = require('chokidar'); + +const changeOrAdded = require('./changeOrAdded'); +const log = require('./log'); + +// Match only on .es6.js files. +const fileMatch = './**/*.es6.js'; +// Ignore everything in node_modules +const watcher = chokidar.watch(fileMatch, { + ignoreInitial: true, + ignored: './node_modules/**' +}); + +const unlinkHandler = (err) => { + if (err) { + log(err); + } +}; + +// Watch for filesystem changes. +watcher + .on('add', changeOrAdded) + .on('change', changeOrAdded) + .on('unlink', (filePath) => { + const fileName = filePath.slice(0, -7); + fs.stat(`${fileName}.js`, () => { + fs.unlink(`${fileName}.js`, unlinkHandler); + }); + fs.stat(`${fileName}.js.map`, () => { + fs.unlink(`${fileName}.js.map`, unlinkHandler); + }); + }) + .on('ready', () => log(`Watching '${fileMatch}' for changes.`)); diff --git a/core/scripts/js/changeOrAdded.js b/core/scripts/js/changeOrAdded.js new file mode 100644 index 00000000..18fd7106 --- /dev/null +++ b/core/scripts/js/changeOrAdded.js @@ -0,0 +1,15 @@ +const fs = require('fs'); +const log = require('./log'); +const compile = require('./compile'); + +module.exports = (filePath) => { + log(`'${filePath}' is being processed.`); + // Transform the file. + compile(filePath, function write(code) { + const fileName = filePath.slice(0, -7); + // Write the result to the filesystem. + fs.writeFile(`${fileName}.js`, code, () => { + log(`'${filePath}' is finished.`); + }); + }); +} diff --git a/core/scripts/js/check.js b/core/scripts/js/check.js new file mode 100644 index 00000000..8769d64e --- /dev/null +++ b/core/scripts/js/check.js @@ -0,0 +1,23 @@ +const chalk = require('chalk'); +const fs = require('fs'); +const log = require('./log'); +const compile = require('./compile'); + +module.exports = (filePath) => { + log(`'${filePath}' is being checked.`); + // Transform the file. + compile(filePath, function check(code) { + const fileName = filePath.slice(0, -7); + fs.readFile(`${fileName}.js`, function read(err, data) { + if (err) { + log(chalk.red(err)); + process.exitCode = 1; + return; + } + if (code !== data.toString()) { + log(chalk.red(`'${filePath}' is not updated.`)); + process.exitCode = 1; + } + }); + }); +} diff --git a/core/scripts/js/compile.js b/core/scripts/js/compile.js new file mode 100644 index 00000000..b1a34777 --- /dev/null +++ b/core/scripts/js/compile.js @@ -0,0 +1,31 @@ +const chalk = require('chalk'); +const log = require('./log'); +const babel = require('babel-core'); + +module.exports = (filePath, callback) => { + // Transform the file. + // Check process.env.NODE_ENV to see if we should create sourcemaps. + babel.transformFile( + filePath, + { + sourceMaps: process.env.NODE_ENV === 'development' ? 'inline' : false, + comments: false, + plugins: [ + ['add-header-comment', { + 'header': [ + `DO NOT EDIT THIS FILE.\nSee the following change record for more information,\nhttps://www.drupal.org/node/2815083\n@preserve` + ] + }] + ] + }, + (err, result) => { + if (err) { + log(chalk.red(err)); + process.exitCode = 1; + } + else { + callback(result.code); + } + } + ); +}; diff --git a/core/scripts/js/log.js b/core/scripts/js/log.js new file mode 100644 index 00000000..08349b3a --- /dev/null +++ b/core/scripts/js/log.js @@ -0,0 +1,4 @@ +module.exports = (message) => { + // Logging human-readable timestamp. + console.log(`[${new Date().toTimeString().slice(0, 8)}] ${message}`); +} diff --git a/core/scripts/rebuild_token_calculator.sh b/core/scripts/rebuild_token_calculator.sh index 38a64ab1..362be3d5 100755 --- a/core/scripts/rebuild_token_calculator.sh +++ b/core/scripts/rebuild_token_calculator.sh @@ -15,11 +15,11 @@ if (PHP_SAPI !== 'cli') { return; } -require __DIR__ . '/../../autoload.php'; +$autoloader = require __DIR__ . '/../../autoload.php'; require_once __DIR__ . '/../includes/bootstrap.inc'; $request = Request::createFromGlobals(); -Settings::initialize(DrupalKernel::findSitePath($request)); +Settings::initialize(DRUPAL_ROOT, DrupalKernel::findSitePath($request), $autoloader); $timestamp = time(); $token = Crypt::hmacBase64($timestamp, Settings::get('hash_salt')); diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index 9e832a5b..09a7aad5 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -17,6 +17,7 @@ use Drupal\Core\Test\TestRunnerKernel; use Drupal\simpletest\Form\SimpletestResultsForm; use Drupal\simpletest\TestBase; use Drupal\simpletest\TestDiscovery; +use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; $autoloader = require_once __DIR__ . '/../../autoload.php'; @@ -36,7 +37,7 @@ const SIMPLETEST_SCRIPT_EXIT_SUCCESS = 0; const SIMPLETEST_SCRIPT_EXIT_FAILURE = 1; const SIMPLETEST_SCRIPT_EXIT_EXCEPTION = 2; -if (!class_exists('\PHPUnit_Framework_TestCase')) { +if (!class_exists(TestCase::class)) { echo "\nrun-tests.sh requires the PHPUnit testing framework. Please use 'composer install --dev' to ensure that it is present.\n\n"; exit(SIMPLETEST_SCRIPT_EXIT_FAILURE); } @@ -783,7 +784,7 @@ function simpletest_script_run_one_test($test_id, $test_class) { $methods = array(); } $test = new $class_name($test_id); - if (is_subclass_of($test_class, '\PHPUnit_Framework_TestCase')) { + if (is_subclass_of($test_class, TestCase::class)) { $status = simpletest_script_run_phpunit($test_id, $test_class); } else { @@ -865,7 +866,7 @@ function simpletest_script_command($test_id, $test_class) { * @see simpletest_script_run_one_test() */ function simpletest_script_cleanup($test_id, $test_class, $exitcode) { - if (is_subclass_of($test_class, '\PHPUnit_Framework_TestCase')) { + if (is_subclass_of($test_class, TestCase::class)) { // PHPUnit test, move on. return; } @@ -1020,7 +1021,7 @@ function simpletest_script_get_test_list() { else { foreach ($matches[1] as $class_name) { $namespace_class = $namespace . '\\' . $class_name; - if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, '\PHPUnit_Framework_TestCase')) { + if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, TestCase::class)) { $test_list[] = $namespace_class; } } @@ -1062,19 +1063,19 @@ function simpletest_script_get_test_list() { $content = file_get_contents($file); // Extract a potential namespace. $namespace = FALSE; - if (preg_match('@^namespace ([^ ;]+)@m', $content, $matches)) { + if (preg_match('@^\s*namespace ([^ ;]+)@m', $content, $matches)) { $namespace = $matches[1]; } // Extract all class names. // Abstract classes are excluded on purpose. - preg_match_all('@^class ([^ ]+)@m', $content, $matches); + preg_match_all('@^\s*class ([^ ]+)@m', $content, $matches); if (!$namespace) { $test_list = array_merge($test_list, $matches[1]); } else { foreach ($matches[1] as $class_name) { $namespace_class = $namespace . '\\' . $class_name; - if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, '\PHPUnit_Framework_TestCase')) { + if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, TestCase::class)) { $test_list[] = $namespace_class; } } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php new file mode 100644 index 00000000..e13ecfd5 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxCallbacksTest.php @@ -0,0 +1,50 @@ +drupalGet('ajax_forms_test_ajax_element_form'); + $this->assertSession()->responseContains('No date yet selected'); + $this->getSession()->getPage()->fillField('edit-date', '2016-01-01'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->assertSession()->responseNotContains('No date yet selected'); + $this->assertSession()->responseContains('2016-01-01'); + } + + /** + * Tests if Ajax callback works on datetime element. + */ + public function testDateTimeAjaxCallback() { + + // Test Ajax callback when datetime changes. + $this->drupalGet('ajax_forms_test_ajax_element_form'); + $this->assertSession()->responseContains('No datetime selected.'); + $this->getSession()->getPage()->fillField('edit-datetime-date', '2016-01-01'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->assertSession()->responseNotContains('No datetime selected.'); + $this->assertSession()->responseContains('2016-01-01'); + $this->getSession()->getPage()->fillField('edit-datetime-time', '12:00:00'); + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->assertSession()->responseContains('2016-01-01 12:00:00'); + } + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxFormImageButtonTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxFormImageButtonTest.php new file mode 100644 index 00000000..4811a350 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxFormImageButtonTest.php @@ -0,0 +1,42 @@ +drupalGet('ajax_forms_image_button_form'); + $assertSession = $this->assertSession(); + $session = $this->getSession(); + + $enter_key_event = <<executeScript($enter_key_event); + + $this->assertNotEmpty($assertSession->waitForElementVisible('css', '#ajax-1-more-div'), 'Page updated after image button pressed'); + } + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxFormPageCacheTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxFormPageCacheTest.php new file mode 100644 index 00000000..3d174b04 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxFormPageCacheTest.php @@ -0,0 +1,127 @@ +config('system.performance'); + $config->set('cache.page.max_age', 300); + $config->save(); + } + + /** + * Return the build id of the current form. + */ + protected function getFormBuildId() { + $build_id_fields = $this->xpath('//input[@name="form_build_id"]'); + $this->assertEquals(count($build_id_fields), 1, 'One form build id field on the page'); + return $build_id_fields[0]->getValue(); + } + + /** + * Create a simple form, then submit the form via AJAX to change to it. + */ + public function testSimpleAJAXFormValue() { + $this->drupalGet('ajax_forms_test_get_form'); + $this->assertEquals($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); + $build_id_initial = $this->getFormBuildId(); + + // Changing the value of a select input element, triggers a AJAX + // request/response. The callback on the form responds with three AJAX + // commands: + // - UpdateBuildIdCommand + // - HtmlCommand + // - DataCommand + $session = $this->getSession(); + $session->getPage()->selectFieldOption('select', 'green'); + + // Wait for the DOM to update. The HtmlCommand will update + // #ajax_selected_color to reflect the color change. + $green_div = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('green')"); + $this->assertNotNull($green_div, 'DOM update: The selected color DIV is green.'); + + // Confirm the operation of the UpdateBuildIdCommand. + $build_id_first_ajax = $this->getFormBuildId(); + $this->assertNotEquals($build_id_initial, $build_id_first_ajax, 'Build id is changed in the form_build_id element on first AJAX submission'); + + // Changing the value of a select input element, triggers a AJAX + // request/response. + $session->getPage()->selectFieldOption('select', 'red'); + + // Wait for the DOM to update. + $red_div = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('red')"); + $this->assertNotNull($red_div, 'DOM update: The selected color DIV is red.'); + + // Confirm the operation of the UpdateBuildIdCommand. + $build_id_second_ajax = $this->getFormBuildId(); + $this->assertNotEquals($build_id_first_ajax, $build_id_second_ajax, 'Build id changes on subsequent AJAX submissions'); + + // Emulate a push of the reload button and then repeat the test sequence + // this time with a page loaded from the cache. + $session->reload(); + $this->assertEquals($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); + $build_id_from_cache_initial = $this->getFormBuildId(); + $this->assertEquals($build_id_initial, $build_id_from_cache_initial, 'Build id is the same as on the first request'); + + // Changing the value of a select input element, triggers a AJAX + // request/response. + $session->getPage()->selectFieldOption('select', 'green'); + + // Wait for the DOM to update. + $green_div2 = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('green')"); + $this->assertNotNull($green_div2, 'DOM update: After reload - the selected color DIV is green.'); + + $build_id_from_cache_first_ajax = $this->getFormBuildId(); + $this->assertNotEquals($build_id_from_cache_initial, $build_id_from_cache_first_ajax, 'Build id is changed in the simpletest-DOM on first AJAX submission'); + $this->assertNotEquals($build_id_first_ajax, $build_id_from_cache_first_ajax, 'Build id from first user is not reused'); + + // Changing the value of a select input element, triggers a AJAX + // request/response. + $session->getPage()->selectFieldOption('select', 'red'); + + // Wait for the DOM to update. + $red_div2 = $this->assertSession()->waitForElement('css', "#ajax_selected_color div:contains('red')"); + $this->assertNotNull($red_div2, 'DOM update: After reload - the selected color DIV is red.'); + + $build_id_from_cache_second_ajax = $this->getFormBuildId(); + $this->assertNotEquals($build_id_from_cache_first_ajax, $build_id_from_cache_second_ajax, 'Build id changes on subsequent AJAX submissions'); + + } + + /** + * Tests that updating the text field trigger an AJAX request/response. + * + * @see \Drupal\system\Tests\Ajax\ElementValidationTest::testAjaxElementValidation() + */ + public function testAjaxElementValidation() { + $this->drupalGet('ajax_validation_test'); + // Changing the value of the textfield will trigger an AJAX + // request/response. + $this->getSession()->getPage()->fillField('drivertext', 'some dumb text'); + + // When the AJAX command updates the DOM a
    unsorted list + // "message__list" structure will appear on the page echoing back the + // "some dumb text" message. + $placeholder = $this->assertSession()->waitForElement('css', "ul.messages__list li.messages__item em:contains('some dumb text')"); + $this->assertNotNull($placeholder, 'Message structure containing input data located.'); + } + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/FormGroupingElementsTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/FormGroupingElementsTest.php new file mode 100644 index 00000000..92b3a739 --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/FormGroupingElementsTest.php @@ -0,0 +1,133 @@ +drupalCreateUser(); + $this->drupalLogin($account); + } + + /** + * Tests that vertical tab children become visible. + * + * Makes sure that a child element of a vertical tab that is not visible, + * becomes visible when the tab is clicked, a fragment link to the child is + * clicked or when the URI fragment pointing to that child changes. + */ + public function testVerticalTabChildVisibility() { + $session = $this->getSession(); + $web_assert = $this->assertSession(); + + // Request the group vertical tabs testing page with a fragment identifier + // to the second element. + $this->drupalGet('form-test/group-vertical-tabs', ['fragment' => 'edit-element-2']); + + $page = $session->getPage(); + + $tab_link_1 = $page->find('css', '.vertical-tabs__menu-item > a'); + + $child_1_selector = '#edit-element'; + $child_1 = $page->find('css', $child_1_selector); + + $child_2_selector = '#edit-element-2'; + $child_2 = $page->find('css', $child_2_selector); + + // Assert that the child in the second vertical tab becomes visible. + // It should be visible after initial load due to the fragment in the URI. + $this->assertTrue($child_2->isVisible(), 'Child 2 is visible due to a URI fragment'); + + // Click on a fragment link pointing to an invisible child inside an + // inactive vertical tab. + $session->executeScript("jQuery('').insertAfter('h1')[0].click()"); + + // Assert that the child in the first vertical tab becomes visible. + $web_assert->waitForElementVisible('css', $child_1_selector, 50); + + // Trigger a URI fragment change (hashchange) to show the second vertical + // tab again. + $session->executeScript("location.replace('$child_2_selector')"); + + // Assert that the child in the second vertical tab becomes visible again. + $web_assert->waitForElementVisible('css', $child_2_selector, 50); + + $tab_link_1->click(); + + // Assert that the child in the first vertical tab is visible again after + // a click on the first tab. + $this->assertTrue($child_1->isVisible(), 'Child 1 is visible after clicking the parent tab'); + } + + /** + * Tests that details element children become visible. + * + * Makes sure that a child element of a details element that is not visible, + * becomes visible when a fragment link to the child is clicked or when the + * URI fragment pointing to that child changes. + */ + public function testDetailsChildVisibility() { + $session = $this->getSession(); + $web_assert = $this->assertSession(); + + // Store reusable JavaScript code to remove the current URI fragment and + // close all details. + $reset_js = "location.replace('#'); jQuery('details').removeAttr('open')"; + + // Request the group details testing page. + $this->drupalGet('form-test/group-details'); + + $page = $session->getPage(); + + $session->executeScript($reset_js); + + $child_selector = '#edit-element'; + $child = $page->find('css', $child_selector); + + // Assert that the child is not visible. + $this->assertFalse($child->isVisible(), 'Child is not visible'); + + // Trigger a URI fragment change (hashchange) to open all parent details + // elements of the child. + $session->executeScript("location.replace('$child_selector')"); + + // Assert that the child becomes visible again after a hash change. + $web_assert->waitForElementVisible('css', $child_selector, 50); + + $session->executeScript($reset_js); + + // Click on a fragment link pointing to an invisible child inside a closed + // details element. + $session->executeScript("jQuery('').insertAfter('h1')[0].click()"); + + // Assert that the child is visible again after a fragment link click. + $web_assert->waitForElementVisible('css', $child_selector, 50); + + // Find the summary belonging to the closest details element. + $summary = $page->find('css', '#edit-meta > summary'); + + // Assert that both aria-expanded and aria-pressed are true. + $this->assertTrue($summary->getAttribute('aria-expanded')); + $this->assertTrue($summary->getAttribute('aria-pressed')); + } + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php index 10aa88e9..bf2643da 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/MachineNameTest.php @@ -27,9 +27,9 @@ class MachineNameTest extends JavascriptTestBase { protected function setUp() { parent::setUp(); - $account = $this->drupalCreateUser(array( + $account = $this->drupalCreateUser([ 'access content', - )); + ]); $this->drupalLogin($account); } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php index e02e0dfb..fa2d541c 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Session/SessionTest.php @@ -48,13 +48,10 @@ public function testSessionExpiration() { // number of times. $this->drupalGet(''); - $session_assert = $this->assertSession(); - $page = $this->getSession()->getPage(); for ($i = 0; $i < 25; $i++) { $page->clickLink('Link to front page'); - $session_assert->statusCodeEquals(200); } } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php index a116c6fd..511dee6e 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php @@ -52,9 +52,9 @@ public function testEntityReferenceAutocompleteWidget() { entity_get_form_display('node', 'page', 'default') ->setComponent($field_name, [ 'type' => 'entity_reference_autocomplete', - 'settings' => array( + 'settings' => [ 'match_operator' => 'CONTAINS', - ), + ], ]) ->save(); @@ -78,9 +78,9 @@ public function testEntityReferenceAutocompleteWidget() { entity_get_form_display('node', 'page', 'default') ->setComponent($field_name, [ 'type' => 'entity_reference_autocomplete', - 'settings' => array( + 'settings' => [ 'match_operator' => 'STARTS_WITH', - ), + ], ]) ->save(); diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php index 815a26b5..10ae7015 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php @@ -64,7 +64,7 @@ function isAjaxing(instance) { public function waitForElement($selector, $locator, $timeout = 10000) { $page = $this->session->getPage(); - $result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) { + $result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) { return $page->find($selector, $locator); }); @@ -90,7 +90,7 @@ public function waitForElement($selector, $locator, $timeout = 10000) { public function waitForElementVisible($selector, $locator, $timeout = 10000) { $page = $this->session->getPage(); - $result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) { + $result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) { $element = $page->find($selector, $locator); if (!empty($element) && $element->isVisible()) { return $element; @@ -113,7 +113,7 @@ public function waitForElementVisible($selector, $locator, $timeout = 10000) { * The page element node if found, NULL if not. */ public function waitForButton($locator, $timeout = 10000) { - return $this->waitForElement('named', array('button', $locator), $timeout); + return $this->waitForElement('named', ['button', $locator], $timeout); } /** @@ -128,7 +128,7 @@ public function waitForButton($locator, $timeout = 10000) { * The page element node if found, NULL if not. */ public function waitForLink($locator, $timeout = 10000) { - return $this->waitForElement('named', array('link', $locator), $timeout); + return $this->waitForElement('named', ['link', $locator], $timeout); } /** @@ -143,7 +143,7 @@ public function waitForLink($locator, $timeout = 10000) { * The page element node if found, NULL if not. */ public function waitForField($locator, $timeout = 10000) { - return $this->waitForElement('named', array('field', $locator), $timeout); + return $this->waitForElement('named', ['field', $locator], $timeout); } /** @@ -158,7 +158,7 @@ public function waitForField($locator, $timeout = 10000) { * The page element node if found, NULL if not. */ public function waitForId($id, $timeout = 10000) { - return $this->waitForElement('named', array('id', $id), $timeout); + return $this->waitForElement('named', ['id', $id], $timeout); } /** diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php index d5156eeb..8aa46c7e 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/JavascriptTestBase.php @@ -7,7 +7,7 @@ use Zumba\Mink\Driver\PhantomJSDriver; /** - * Runs a browser test using PhantomJS. + * Runs a browser test using a driver that supports Javascript. * * Base class for testing browser interaction implemented in JavaScript. */ @@ -142,7 +142,7 @@ protected function createScreenshot($filename, $set_background_color = TRUE) { * {@inheritdoc} */ public function assertSession($name = NULL) { - return new JSWebAssert($this->getSession($name), $this->baseUrl); + return new WebDriverWebAssert($this->getSession($name), $this->baseUrl); } /** diff --git a/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php b/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php new file mode 100644 index 00000000..7cef5b8c --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/LegacyJavascriptTestBase.php @@ -0,0 +1,20 @@ +getSession($name), $this->baseUrl); + } + +} diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebAssertTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebAssertTest.php index 7930a909..36f6340f 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebAssertTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Tests/JSWebAssertTest.php @@ -80,7 +80,7 @@ public function testJsWebAssert() { $result = $page->findButton('Added WaitForElementVisible'); $this->assertEmpty($result); $test_wait_on_element_visible->click(); - $result = $assert_session->waitForElementVisible('named', array('button', 'Added WaitForElementVisible')); + $result = $assert_session->waitForElementVisible('named', ['button', 'Added WaitForElementVisible']); $this->assertNotEmpty($result); $this->assertTrue($result instanceof NodeElement); $this->assertEquals(TRUE, $result->isVisible()); diff --git a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverWebAssert.php new file mode 100644 index 00000000..16b1281d --- /dev/null +++ b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverWebAssert.php @@ -0,0 +1,58 @@ +assertSession()->fieldExists() or + * $this->assertSession()->buttonExists() or * $this->assertSession()->fieldValueEquals() instead. */ protected function assertFieldByName($name, $value = NULL) { - $this->assertSession()->fieldExists($name); - if ($value !== NULL) { - $this->assertSession()->fieldValueEquals($name, (string) $value); - } + $this->assertFieldByXPath($this->constructFieldXpath('name', $name), $value); } /** - * Asserts that a field exists with the given name and value. + * Asserts that a field does not exist with the given name and value. * * @param string $name * Name of field to assert. * @param string $value - * (optional) Value of the field to assert. You may pass in NULL (default) - * to skip checking the actual value, while still checking that the field - * exists. + * (optional) Value for the field, to assert that the field's value on the + * page does not match it. You may pass in NULL to skip checking the + * value, while still checking that the field does not exist. However, the + * default value ('') asserts that the field value is not an empty string. * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldNotExists() or + * $this->assertSession()->buttonNotExists() or * $this->assertSession()->fieldValueNotEquals() instead. */ - protected function assertNoFieldByName($name, $value = NULL) { - $this->assertSession()->fieldNotExists($name); - if ($value !== NULL) { - $this->assertSession()->fieldValueNotEquals($name, (string) $value); - } + protected function assertNoFieldByName($name, $value = '') { + $this->assertNoFieldByXPath($this->constructFieldXpath('name', $name), $value); } /** @@ -258,12 +258,15 @@ protected function assertNoFieldByName($name, $value = NULL) { * However, the default value ('') asserts that the field value is an empty * string. * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldExists() or + * $this->assertSession()->buttonExists() or * $this->assertSession()->fieldValueEquals() instead. */ - protected function assertFieldById($id, $value = NULL) { - $this->assertFieldByName($id, $value); + protected function assertFieldById($id, $value = '') { + $this->assertFieldByXPath($this->constructFieldXpath('id', $id), $value); } /** @@ -273,23 +276,25 @@ protected function assertFieldById($id, $value = NULL) { * Name or ID of field to assert. * * @deprecated Scheduled for removal in Drupal 9.0.0. - * Use $this->assertSession()->fieldExists() instead. + * Use $this->assertSession()->fieldExists() or + * $this->assertSession()->buttonExists() instead. */ protected function assertField($field) { - $this->assertSession()->fieldExists($field); + $this->assertFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field)); } /** - * Asserts that a field exists with the given name or ID does NOT exist. + * Asserts that a field does NOT exist with the given name or ID. * * @param string $field * Name or ID of field to assert. * * @deprecated Scheduled for removal in Drupal 9.0.0. - * Use $this->assertSession()->fieldNotExists() instead. + * Use $this->assertSession()->fieldNotExists() or + * $this->assertSession()->buttonNotExists() instead. */ protected function assertNoField($field) { - $this->assertSession()->fieldNotExists($field); + $this->assertNoFieldByXPath($this->constructFieldXpath('name', $field) . '|' . $this->constructFieldXpath('id', $field)); } /** @@ -376,7 +381,7 @@ protected function assertNoLink($label) { * Link position counting from zero. * * @deprecated Scheduled for removal in Drupal 9.0.0. - * Use $this->assertSession()->linkByHref() instead. + * Use $this->assertSession()->linkByHrefExists() instead. */ protected function assertLinkByHref($href, $index = 0) { $this->assertSession()->linkByHrefExists($href, $index); @@ -406,17 +411,15 @@ protected function assertNoLinkByHref($href) { * while still checking that the field doesn't exist. However, the default * value ('') asserts that the field value is not an empty string. * + * @throws \Behat\Mink\Exception\ExpectationException + * * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->fieldNotExists() or + * $this->assertSession()->buttonNotExists() or * $this->assertSession()->fieldValueNotEquals() instead. */ protected function assertNoFieldById($id, $value = '') { - if ($this->getSession()->getPage()->findField($id)) { - $this->assertSession()->fieldValueNotEquals($id, (string) $value); - } - else { - $this->assertSession()->fieldNotExists($id); - } + $this->assertNoFieldByXPath($this->constructFieldXpath('id', $id), $value); } /** @@ -447,6 +450,21 @@ protected function assertOption($id, $option) { return $this->assertSession()->optionExists($id, $option); } + /** + * Asserts that a select option with the visible text exists. + * + * @param string $id + * The ID of the select field to assert. + * @param string $text + * The text for the option tag to assert. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->assertSession()->optionExists() instead. + */ + protected function assertOptionByText($id, $text) { + return $this->assertSession()->optionExists($id, $text); + } + /** * Asserts that a select option does NOT exist in the current page. * @@ -509,6 +527,121 @@ protected function assertNoFieldChecked($id) { $this->assertSession()->checkboxNotChecked($id); } + /** + * Asserts that a field exists in the current page by the given XPath. + * + * @param string $xpath + * XPath used to find the field. + * @param string $value + * (optional) Value of the field to assert. You may pass in NULL (default) + * to skip checking the actual value, while still checking that the field + * exists. + * @param string $message + * (optional) A message to display with the assertion. Do not translate + * messages with t(). + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->xpath() instead and check the values directly in the test. + */ + protected function assertFieldByXPath($xpath, $value = NULL, $message = '') { + $fields = $this->xpath($xpath); + + $this->assertFieldsByValue($fields, $value, $message); + } + + /** + * Asserts that a field does not exist or its value does not match, by XPath. + * + * @param string $xpath + * XPath used to find the field. + * @param string $value + * (optional) Value of the field, to assert that the field's value on the + * page does not match it. + * @param string $message + * (optional) A message to display with the assertion. Do not translate + * messages with t(). + * + * @throws \Behat\Mink\Exception\ExpectationException + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->xpath() instead and assert that the result is empty. + */ + protected function assertNoFieldByXPath($xpath, $value = NULL, $message = '') { + $fields = $this->xpath($xpath); + + if (!empty($fields)) { + if (isset($value)) { + $found = FALSE; + try { + $this->assertFieldsByValue($fields, $value); + $found = TRUE; + } + catch (\Exception $e) { + } + + if ($found) { + throw new ExpectationException(sprintf('The field resulting from %s was found with the provided value %s.', $xpath, $value), $this->getSession()->getDriver()); + } + } + else { + throw new ExpectationException(sprintf('The field resulting from %s was found.', $xpath), $this->getSession()->getDriver()); + } + } + } + + /** + * Asserts that a field exists in the current page with a given Xpath result. + * + * @param \Behat\Mink\Element\NodeElement[] $fields + * Xml elements. + * @param string $value + * (optional) Value of the field to assert. You may pass in NULL (default) to skip + * checking the actual value, while still checking that the field exists. + * @param string $message + * (optional) A message to display with the assertion. Do not translate + * messages with t(). + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Iterate over the fields yourself instead and directly check the values in + * the test. + */ + protected function assertFieldsByValue($fields, $value = NULL, $message = '') { + // If value specified then check array for match. + $found = TRUE; + if (isset($value)) { + $found = FALSE; + if ($fields) { + foreach ($fields as $field) { + if ($field->getAttribute('type') == 'checkbox') { + if (is_bool($value)) { + $found = $field->isChecked() == $value; + } + else { + $found = TRUE; + } + } + elseif ($field->getAttribute('value') == $value) { + // Input element with correct value. + $found = TRUE; + } + elseif ($field->find('xpath', '//option[@value = ' . (new Escaper())->escapeLiteral($value) . ' and @selected = "selected"]')) { + // Select element with an option. + $found = TRUE; + } + elseif ($field->getTagName() === 'textarea' && $field->getValue() == $value) { + // Text area with correct text. Use getValue() here because + // getText() would remove any newlines in the value. + $found = TRUE; + } + elseif ($field->getTagName() !== 'input' && $field->getText() == $value) { + $found = TRUE; + } + } + } + } + $this->assertTrue($fields && $found, $message); + } + /** * Passes if the raw text IS found escaped on the loaded page, fail otherwise. * @@ -552,6 +685,22 @@ protected function assertPattern($pattern) { $this->assertSession()->responseMatches($pattern); } + /** + * Triggers a pass if the Perl regex pattern is not found in the raw content. + * + * @param string $pattern + * Perl regex to look for including the regex delimiters. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->assertSession()->responseNotMatches() instead. + * + * @see https://www.drupal.org/node/2864262 + */ + protected function assertNoPattern($pattern) { + @trigger_error('assertNoPattern() is deprecated and scheduled for removal in Drupal 9.0.0. Use $this->assertSession()->responseNotMatches($pattern) instead. See https://www.drupal.org/node/2864262.', E_USER_DEPRECATED); + $this->assertSession()->responseNotMatches($pattern); + } + /** * Asserts whether an expected cache tag was present in the last response. * @@ -565,6 +714,37 @@ protected function assertCacheTag($expected_cache_tag) { $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', $expected_cache_tag); } + /** + * Asserts whether an expected cache tag was absent in the last response. + * + * @param string $cache_tag + * The cache tag to check. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->assertSession()->responseHeaderNotContains() instead. + * + * @see https://www.drupal.org/node/2864029 + */ + protected function assertNoCacheTag($cache_tag) { + @trigger_error('assertNoCacheTag() is deprecated and scheduled for removal in Drupal 9.0.0. Use $this->assertSession()->responseHeaderNotContains() instead. See https://www.drupal.org/node/2864029.', E_USER_DEPRECATED); + $this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', $cache_tag); + } + + /** + * Checks that current response header equals value. + * + * @param string $name + * Name of header to assert. + * @param string $value + * Value of the header to assert + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->assertSession()->responseHeaderEquals() instead. + */ + protected function assertHeader($name, $value) { + $this->assertSession()->responseHeaderEquals($name, $value); + } + /** * Returns WebAssert object. * @@ -599,8 +779,55 @@ abstract public function assertSession($name = NULL); * @deprecated Scheduled for removal in Drupal 9.0.0. * Use $this->assertSession()->buildXPathQuery() instead. */ - protected function buildXPathQuery($xpath, array $args = array()) { + protected function buildXPathQuery($xpath, array $args = []) { return $this->assertSession()->buildXPathQuery($xpath, $args); } + /** + * Helper: Constructs an XPath for the given set of attributes and value. + * + * @param string $attribute + * Field attributes. + * @param string $value + * Value of field. + * + * @return string + * XPath for specified values. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->getSession()->getPage()->findField() instead. + */ + protected function constructFieldXpath($attribute, $value) { + $xpath = '//textarea[@' . $attribute . '=:value]|//input[@' . $attribute . '=:value]|//select[@' . $attribute . '=:value]'; + return $this->buildXPathQuery($xpath, [':value' => $value]); + } + + /** + * Gets the current raw content. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->getSession()->getPage()->getContent() instead. + */ + protected function getRawContent() { + @trigger_error('AssertLegacyTrait::getRawContent() is scheduled for removal in Drupal 9.0.0. Use $this->getSession()->getPage()->getContent() instead.', E_USER_DEPRECATED); + return $this->getSession()->getPage()->getContent(); + } + + /** + * Get all option elements, including nested options, in a select. + * + * @param \Behat\Mink\Element\NodeElement $element + * The element for which to get the options. + * + * @return \Behat\Mink\Element\NodeElement[] + * Option elements in select. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $element->findAll('xpath', 'option') instead. + */ + protected function getAllOptions(NodeElement $element) { + @trigger_error('AssertLegacyTrait::getAllOptions() is scheduled for removal in Drupal 9.0.0. Use $element->findAll(\'xpath\', \'option\') instead.', E_USER_DEPRECATED); + return $element->findAll('xpath', '//option'); + } + } diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php index d0a42493..882e6edc 100644 --- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php @@ -2,9 +2,12 @@ namespace Drupal\FunctionalTests; +use Behat\Mink\Exception\ExpectationException; +use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Html; use Drupal\Core\Url; use Drupal\Tests\BrowserTestBase; +use Drupal\Tests\Traits\Core\CronRunTrait; /** * Tests BrowserTestBase functionality. @@ -13,12 +16,14 @@ */ class BrowserTestBaseTest extends BrowserTestBase { + use CronRunTrait; + /** * Modules to enable. * * @var array */ - public static $modules = array('test_page_test', 'form_test', 'system_test'); + public static $modules = ['test_page_test', 'form_test', 'system_test']; /** * Tests basic page test. @@ -40,7 +45,7 @@ public function testGoTo() { $this->assertNotContains('', $text); // Response includes cache tags that we can assert. - $this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Tags', 'rendered'); + $this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Tags', 'http_response rendered'); // Test that we can read the JS settings. $js_settings = $this->getDrupalSettings(); @@ -55,9 +60,9 @@ public function testGoTo() { $this->assertSession()->pageTextContains('Hello Drupal'); // Test that setting headers with drupalGet() works. - $this->drupalGet('system-test/header', array(), array( + $this->drupalGet('system-test/header', [], [ 'Test-Header' => 'header value', - )); + ]); $returned_header = $this->getSession()->getResponseHeader('Test-Header'); $this->assertSame('header value', $returned_header); } @@ -74,12 +79,38 @@ public function testForm() { $this->assertSession()->elementExists('css', 'form#form-test-form-test-object'); $this->assertSession()->fieldExists('bananas'); + // Check that the hidden field exists and has a specific value. + $this->assertSession()->hiddenFieldExists('strawberry'); + $this->assertSession()->hiddenFieldExists('red'); + $this->assertSession()->hiddenFieldExists('redstrawberryhiddenfield'); + $this->assertSession()->hiddenFieldValueNotEquals('strawberry', 'brown'); + $this->assertSession()->hiddenFieldValueEquals('strawberry', 'red'); + + // Check that a hidden field does not exist. + $this->assertSession()->hiddenFieldNotExists('bananas'); + $this->assertSession()->hiddenFieldNotExists('pineapple'); + $edit = ['bananas' => 'green']; $this->submitForm($edit, 'Save', 'form-test-form-test-object'); $config_factory = $this->container->get('config.factory'); $value = $config_factory->get('form_test.object')->get('bananas'); $this->assertSame('green', $value); + + // Test drupalPostForm(). + $edit = ['bananas' => 'red']; + $result = $this->drupalPostForm('form-test/object-builder', $edit, 'Save'); + $this->assertSame($this->getSession()->getPage()->getContent(), $result); + $value = $config_factory->get('form_test.object')->get('bananas'); + $this->assertSame('red', $value); + + $this->drupalPostForm('form-test/object-builder', NULL, 'Save'); + $value = $config_factory->get('form_test.object')->get('bananas'); + $this->assertSame('', $value); + + // Test drupalPostForm() with no-html response. + $values = Json::decode($this->drupalPostForm('form_test/form-state-values-clean', [], t('Submit'))); + $this->assertTrue(1000, $values['beer']); } /** @@ -103,14 +134,463 @@ public function testError() { } /** - * Tests legacy asserts. + * Tests linkExists() with pipe character (|) in locator. + * + * @see \Drupal\Tests\WebAssert::linkExists() + */ + public function testPipeCharInLocator() { + $this->drupalGet('test-pipe-char'); + $this->assertSession()->linkExists('foo|bar|baz'); + } + + /** + * Tests linkExistsExact() functionality. + * + * @see \Drupal\Tests\WebAssert::linkExistsExact() + */ + public function testLinkExistsExact() { + $this->drupalGet('test-pipe-char'); + $this->assertSession()->linkExistsExact('foo|bar|baz'); + } + + /** + * Tests linkExistsExact() functionality fail. + * + * @see \Drupal\Tests\WebAssert::linkExistsExact() */ - public function testLegacyAsserts() { + public function testInvalidLinkExistsExact() { + $this->drupalGet('test-pipe-char'); + $this->setExpectedException(ExpectationException::class, 'Link with label foo|bar found'); + $this->assertSession()->linkExistsExact('foo|bar'); + } + + /** + * Tests linkNotExistsExact() functionality. + * + * @see \Drupal\Tests\WebAssert::linkNotExistsExact() + */ + public function testLinkNotExistsExact() { + $this->drupalGet('test-pipe-char'); + $this->assertSession()->linkNotExistsExact('foo|bar'); + } + + /** + * Tests linkNotExistsExact() functionality fail. + * + * @see \Drupal\Tests\WebAssert::linkNotExistsExact() + */ + public function testInvalidLinkNotExistsExact() { + $this->drupalGet('test-pipe-char'); + $this->setExpectedException(ExpectationException::class, 'Link with label foo|bar|baz not found'); + $this->assertSession()->linkNotExistsExact('foo|bar|baz'); + } + + /** + * Tests legacy text asserts. + */ + public function testLegacyTextAsserts() { $this->drupalGet('test-encoded'); $dangerous = 'Bad html '; $sanitized = Html::escape($dangerous); $this->assertNoText($dangerous); $this->assertText($sanitized); + + // Test getRawContent(). + $this->assertSame($this->getSession()->getPage()->getContent(), $this->getRawContent()); + } + + /** + * Tests legacy field asserts which use xpath directly. + */ + public function testLegacyXpathAsserts() { + $this->drupalGet('test-field-xpath'); + $this->assertFieldsByValue($this->xpath("//h1[@class = 'page-title']"), NULL); + $this->assertFieldsByValue($this->xpath('//table/tbody/tr[2]/td[1]'), 'one'); + $this->assertFieldByXPath('//table/tbody/tr[2]/td[1]', 'one'); + + $this->assertFieldsByValue($this->xpath("//input[@id = 'edit-name']"), 'Test name'); + $this->assertFieldByXPath("//input[@id = 'edit-name']", 'Test name'); + $this->assertFieldsByValue($this->xpath("//select[@id = 'edit-options']"), '2'); + $this->assertFieldByXPath("//select[@id = 'edit-options']", '2'); + + $this->assertNoFieldByXPath('//notexisting'); + $this->assertNoFieldByXPath("//input[@id = 'edit-name']", 'wrong value'); + + // Test that the assertion fails correctly. + try { + $this->assertFieldByXPath("//input[@id = 'notexisting']"); + $this->fail('The "notexisting" field was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('assertFieldByXPath correctly failed. The "notexisting" field was not found.'); + } + + try { + $this->assertNoFieldByXPath("//input[@id = 'edit-name']"); + $this->fail('The "edit-name" field was not found.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoFieldByXPath correctly failed. The "edit-name" field was found.'); + } + + try { + $this->assertFieldsByValue($this->xpath("//input[@id = 'edit-name']"), 'not the value'); + $this->fail('The "edit-name" field is found with the value "not the value".'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The "edit-name" field is not found with the value "not the value".'); + } + } + + /** + * Tests legacy field asserts using textfields. + */ + public function testLegacyFieldAssertsForTextfields() { + $this->drupalGet('test-field-xpath'); + + // *** 1. assertNoField(). + $this->assertNoField('invalid_name_and_id'); + + // Test that the assertion fails correctly when searching by name. + try { + $this->assertNoField('name'); + $this->fail('The "name" field was not found based on name.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoField correctly failed. The "name" field was found by name.'); + } + + // Test that the assertion fails correctly when searching by id. + try { + $this->assertNoField('edit-name'); + $this->fail('The "name" field was not found based on id.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoField correctly failed. The "name" field was found by id.'); + } + + // *** 2. assertField(). + $this->assertField('name'); + $this->assertField('edit-name'); + + // Test that the assertion fails correctly if the field does not exist. + try { + $this->assertField('invalid_name_and_id'); + $this->fail('The "invalid_name_and_id" field was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('assertField correctly failed. The "invalid_name_and_id" field was not found.'); + } + + // *** 3. assertNoFieldById(). + $this->assertNoFieldById('name'); + $this->assertNoFieldById('name', 'not the value'); + $this->assertNoFieldById('notexisting'); + $this->assertNoFieldById('notexisting', NULL); + + // Test that the assertion fails correctly if no value is passed in. + try { + $this->assertNoFieldById('edit-description'); + $this->fail('The "description" field, with no value was not found.'); + } + catch (ExpectationException $e) { + $this->pass('The "description" field, with no value was found.'); + } + + // Test that the assertion fails correctly if a NULL value is passed in. + try { + $this->assertNoFieldById('edit-name', NULL); + $this->fail('The "name" field was not found.'); + } + catch (ExpectationException $e) { + $this->pass('The "name" field was found.'); + } + + // *** 4. assertFieldById(). + $this->assertFieldById('edit-name', NULL); + $this->assertFieldById('edit-name', 'Test name'); + $this->assertFieldById('edit-description', NULL); + $this->assertFieldById('edit-description'); + + // Test that the assertion fails correctly if no value is passed in. + try { + $this->assertFieldById('edit-name'); + $this->fail('The "edit-name" field with no value was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The "edit-name" field with no value was not found.'); + } + + // Test that the assertion fails correctly if the wrong value is passed in. + try { + $this->assertFieldById('edit-name', 'not the value'); + $this->fail('The "name" field was found, using the wrong value.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The "name" field was not found, using the wrong value.'); + } + + // *** 5. assertNoFieldByName(). + $this->assertNoFieldByName('name'); + $this->assertNoFieldByName('name', 'not the value'); + $this->assertNoFieldByName('notexisting'); + $this->assertNoFieldByName('notexisting', NULL); + + // Test that the assertion fails correctly if no value is passed in. + try { + $this->assertNoFieldByName('description'); + $this->fail('The "description" field, with no value was not found.'); + } + catch (ExpectationException $e) { + $this->pass('The "description" field, with no value was found.'); + } + + // Test that the assertion fails correctly if a NULL value is passed in. + try { + $this->assertNoFieldByName('name', NULL); + $this->fail('The "name" field was not found.'); + } + catch (ExpectationException $e) { + $this->pass('The "name" field was found.'); + } + + // *** 6. assertFieldByName(). + $this->assertFieldByName('name'); + $this->assertFieldByName('name', NULL); + $this->assertFieldByName('name', 'Test name'); + $this->assertFieldByName('description'); + $this->assertFieldByName('description', ''); + $this->assertFieldByName('description', NULL); + + // Test that the assertion fails correctly if given the wrong name. + try { + $this->assertFieldByName('non-existing-name'); + $this->fail('The "non-existing-name" field was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('The "non-existing-name" field was not found'); + } + + // Test that the assertion fails correctly if given the wrong value. + try { + $this->assertFieldByName('name', 'not the value'); + $this->fail('The "name" field with incorrect value was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass('assertFieldByName correctly failed. The "name" field with incorrect value was not found.'); + } + + // Test that text areas can contain new lines. + $this->assertFieldsByValue($this->xpath("//textarea[@id = 'edit-test-textarea-with-newline']"), "Test text with\nnewline"); + } + + /** + * Tests legacy field asserts for options field type. + */ + public function testLegacyFieldAssertsForOptions() { + $this->drupalGet('test-field-xpath'); + + // Option field type. + $this->assertOptionByText('options', 'one'); + try { + $this->assertOptionByText('options', 'four'); + $this->fail('The select option "four" was found.'); + } + catch (ExpectationException $e) { + $this->pass($e->getMessage()); + } + + $this->assertOption('options', 1); + try { + $this->assertOption('options', 4); + $this->fail('The select option "4" was found.'); + } + catch (ExpectationException $e) { + $this->pass($e->getMessage()); + } + + $this->assertNoOption('options', 'non-existing'); + try { + $this->assertNoOption('options', 'one'); + $this->fail('The select option "one" was not found.'); + } + catch (ExpectationException $e) { + $this->pass($e->getMessage()); + } + + $this->assertOptionSelected('options', 2); + try { + $this->assertOptionSelected('options', 4); + $this->fail('The select option "4" was selected.'); + } + catch (ExpectationException $e) { + $this->pass($e->getMessage()); + } + + try { + $this->assertOptionSelected('options', 1); + $this->fail('The select option "1" was selected.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass($e->getMessage()); + } + + // Test \Drupal\FunctionalTests\AssertLegacyTrait::getAllOptions. + $this->drupalGet('/form-test/select'); + $this->assertCount(6, $this->getAllOptions($this->cssSelect('select[name="opt_groups"]')[0])); + } + + /** + * Tests legacy field asserts for button field type. + */ + public function testLegacyFieldAssertsForButton() { + $this->drupalGet('test-field-xpath'); + + $this->assertFieldById('edit-save', NULL); + // Test that the assertion fails correctly if the field value is passed in + // rather than the id. + try { + $this->assertFieldById('Save', NULL); + $this->fail('The field with id of "Save" was found.'); + } + catch (\PHPUnit_Framework_ExpectationFailedException $e) { + $this->pass($e->getMessage()); + } + + $this->assertNoFieldById('Save', NULL); + // Test that the assertion fails correctly if the id of an actual field is + // passed in. + try { + $this->assertNoFieldById('edit-save', NULL); + $this->fail('The field with id of "edit-save" was not found.'); + } + catch (ExpectationException $e) { + $this->pass($e->getMessage()); + } + + // Test that multiple fields with the same name are validated correctly. + $this->assertFieldByName('duplicate_button', 'Duplicate button 1'); + $this->assertFieldByName('duplicate_button', 'Duplicate button 2'); + $this->assertNoFieldByName('duplicate_button', 'Rabbit'); + + try { + $this->assertNoFieldByName('duplicate_button', 'Duplicate button 2'); + $this->fail('The "duplicate_button" field with the value Duplicate button 2 was not found.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoFieldByName correctly failed. The "duplicate_button" field with the value Duplicate button 2 was found.'); + } + } + + /** + * Tests legacy field asserts for checkbox field type. + */ + public function testLegacyFieldAssertsForCheckbox() { + $this->drupalGet('test-field-xpath'); + + // Part 1 - Test by name. + // Test that checkboxes are found/not found correctly by name, when using + // TRUE or FALSE to match their 'checked' state. + $this->assertFieldByName('checkbox_enabled', TRUE); + $this->assertFieldByName('checkbox_disabled', FALSE); + $this->assertNoFieldByName('checkbox_enabled', FALSE); + $this->assertNoFieldByName('checkbox_disabled', TRUE); + + // Test that checkboxes are found by name when using NULL to ignore the + // 'checked' state. + $this->assertFieldByName('checkbox_enabled', NULL); + $this->assertFieldByName('checkbox_disabled', NULL); + + // Test that checkboxes are found by name when passing no second parameter. + $this->assertFieldByName('checkbox_enabled'); + $this->assertFieldByName('checkbox_disabled'); + + // Test that we have legacy support. + $this->assertFieldByName('checkbox_enabled', '1'); + $this->assertFieldByName('checkbox_disabled', ''); + + // Test that the assertion fails correctly when using NULL to ignore state. + try { + $this->assertNoFieldByName('checkbox_enabled', NULL); + $this->fail('The "checkbox_enabled" field was not found by name, using NULL value.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoFieldByName failed correctly. The "checkbox_enabled" field was found using NULL value.'); + } + + // Part 2 - Test by ID. + // Test that checkboxes are found/not found correctly by ID, when using + // TRUE or FALSE to match their 'checked' state. + $this->assertFieldById('edit-checkbox-enabled', TRUE); + $this->assertFieldById('edit-checkbox-disabled', FALSE); + $this->assertNoFieldById('edit-checkbox-enabled', FALSE); + $this->assertNoFieldById('edit-checkbox-disabled', TRUE); + + // Test that checkboxes are found by ID, when using NULL to ignore the + // 'checked' state. + $this->assertFieldById('edit-checkbox-enabled', NULL); + $this->assertFieldById('edit-checkbox-disabled', NULL); + + // Test that checkboxes are found by ID when passing no second parameter. + $this->assertFieldById('edit-checkbox-enabled'); + $this->assertFieldById('edit-checkbox-disabled'); + + // Test that we have legacy support. + $this->assertFieldById('edit-checkbox-enabled', '1'); + $this->assertFieldById('edit-checkbox-disabled', ''); + + // Test that the assertion fails correctly when using NULL to ignore state. + try { + $this->assertNoFieldById('edit-checkbox-disabled', NULL); + $this->fail('The "edit-checkbox-disabled" field was not found by ID, using NULL value.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoFieldById failed correctly. The "edit-checkbox-disabled" field was found by ID using NULL value.'); + } + + // Part 3 - Test the specific 'checked' assertions. + $this->assertFieldChecked('edit-checkbox-enabled'); + $this->assertNoFieldChecked('edit-checkbox-disabled'); + + // Test that the assertion fails correctly with non-existant field id. + try { + $this->assertNoFieldChecked('incorrect_checkbox_id'); + $this->fail('The "incorrect_checkbox_id" field was found'); + } + catch (ExpectationException $e) { + $this->pass('assertNoFieldChecked correctly failed. The "incorrect_checkbox_id" field was not found.'); + } + + // Test that the assertion fails correctly for a checkbox that is checked. + try { + $this->assertNoFieldChecked('edit-checkbox-enabled'); + $this->fail('The "edit-checkbox-enabled" field was not found in a checked state.'); + } + catch (ExpectationException $e) { + $this->pass('assertNoFieldChecked correctly failed. The "edit-checkbox-enabled" field was found in a checked state.'); + } + + // Test that the assertion fails correctly for a checkbox that is not + // checked. + try { + $this->assertFieldChecked('edit-checkbox-disabled'); + $this->fail('The "edit-checkbox-disabled" field was found and checked.'); + } + catch (ExpectationException $e) { + $this->pass('assertFieldChecked correctly failed. The "edit-checkbox-disabled" field was not found in a checked state.'); + } + } + + /** + * Tests the ::cronRun() method. + */ + public function testCronRun() { + $last_cron_time = \Drupal::state()->get('system.cron_last'); + $this->cronRun(); + $this->assertSession()->statusCodeEquals(204); + $next_cron_time = \Drupal::state()->get('system.cron_last'); + + $this->assertGreaterThan($last_cron_time, $next_cron_time); } /** @@ -121,4 +601,36 @@ public function testInstall() { $this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists"); } + /** + * Tests the assumption that local time is in 'Australia/Sydney'. + */ + public function testLocalTimeZone() { + // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php + $this->assertEquals('Australia/Sydney', date_default_timezone_get()); + + // The 'Australia/Sydney' time zone is also set in + // FunctionalTestSetupTrait::initConfig(). + $config_factory = $this->container->get('config.factory'); + $value = $config_factory->get('system.date')->get('timezone.default'); + $this->assertEquals('Australia/Sydney', $value); + } + + /** + * Tests the ::checkForMetaRefresh() method. + */ + public function testCheckForMetaRefresh() { + // Disable following redirects in the client. + $this->getSession()->getDriver()->getClient()->followRedirects(FALSE); + // Set the maximumMetaRefreshCount to zero to make sure the redirect doesn't + // happen when doing a drupalGet. + $this->maximumMetaRefreshCount = 0; + $this->drupalGet('test-meta-refresh'); + $this->assertNotEmpty($this->cssSelect('meta[http-equiv="refresh"]')); + // Allow one redirect to happen. + $this->maximumMetaRefreshCount = 1; + $this->checkForMetaRefresh(); + // Check that we are now on the test page. + $this->assertSession()->pageTextContains('Test page text.'); + } + } diff --git a/core/tests/Drupal/FunctionalTests/Core/Config/SchemaConfigListenerTest.php b/core/tests/Drupal/FunctionalTests/Core/Config/SchemaConfigListenerTest.php index 7138c5e8..698a7d1a 100644 --- a/core/tests/Drupal/FunctionalTests/Core/Config/SchemaConfigListenerTest.php +++ b/core/tests/Drupal/FunctionalTests/Core/Config/SchemaConfigListenerTest.php @@ -17,6 +17,6 @@ class SchemaConfigListenerTest extends BrowserTestBase { /** * {@inheritdoc} */ - public static $modules = array('config_test'); + public static $modules = ['config_test']; } diff --git a/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php b/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php new file mode 100644 index 00000000..8faf8c6c --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Datetime/TimestampTest.php @@ -0,0 +1,149 @@ +drupalCreateUser([ + 'access content', + 'view test entity', + 'administer entity_test content', + 'administer entity_test form display', + 'administer content types', + 'administer node fields', + ]); + + $this->drupalLogin($web_user); + $field_name = 'field_timestamp'; + $type = 'timestamp'; + $widget_type = 'datetime_timestamp'; + $formatter_type = 'timestamp'; + + $this->fieldStorage = FieldStorageConfig::create([ + 'field_name' => $field_name, + 'entity_type' => 'entity_test', + 'type' => $type, + ]); + $this->fieldStorage->save(); + $this->field = FieldConfig::create([ + 'field_storage' => $this->fieldStorage, + 'bundle' => 'entity_test', + 'required' => TRUE, + ]); + $this->field->save(); + + EntityFormDisplay::load('entity_test.entity_test.default') + ->setComponent($field_name, ['type' => $widget_type]) + ->save(); + + $this->displayOptions = [ + 'type' => $formatter_type, + 'label' => 'hidden', + ]; + + EntityViewDisplay::create([ + 'targetEntityType' => $this->field->getTargetEntityTypeId(), + 'bundle' => $this->field->getTargetBundle(), + 'mode' => 'full', + 'status' => TRUE, + ])->setComponent($field_name, $this->displayOptions) + ->save(); + } + + /** + * Tests the "datetime_timestamp" widget. + */ + public function testWidget() { + // Build up a date in the UTC timezone. + $value = '2012-12-31 00:00:00'; + $date = new DrupalDateTime($value, 'UTC'); + + // Update the timezone to the system default. + $date->setTimezone(timezone_open(drupal_get_user_timezone())); + + // Display creation form. + $this->drupalGet('entity_test/add'); + + // Make sure the "datetime_timestamp" widget is on the page. + $fields = $this->xpath('//div[contains(@class, "field--widget-datetime-timestamp") and @id="edit-field-timestamp-wrapper"]'); + $this->assertEquals(1, count($fields)); + + // Look for the widget elements and make sure they are empty. + $this->assertSession()->fieldExists('field_timestamp[0][value][date]'); + $this->assertSession()->fieldValueEquals('field_timestamp[0][value][date]', ''); + $this->assertSession()->fieldExists('field_timestamp[0][value][time]'); + $this->assertSession()->fieldValueEquals('field_timestamp[0][value][time]', ''); + + // Submit the date. + $date_format = DateFormat::load('html_date')->getPattern(); + $time_format = DateFormat::load('html_time')->getPattern(); + + $edit = [ + 'field_timestamp[0][value][date]' => $date->format($date_format), + 'field_timestamp[0][value][time]' => $date->format($time_format), + ]; + $this->drupalPostForm(NULL, $edit, 'Save'); + + // Make sure the submitted date is set as the default in the widget. + $this->assertSession()->fieldExists('field_timestamp[0][value][date]'); + $this->assertSession()->fieldValueEquals('field_timestamp[0][value][date]', $date->format($date_format)); + $this->assertSession()->fieldExists('field_timestamp[0][value][time]'); + $this->assertSession()->fieldValueEquals('field_timestamp[0][value][time]', $date->format($time_format)); + + // Make sure the entity was saved. + preg_match('|entity_test/manage/(\d+)|', $this->getSession()->getCurrentUrl(), $match); + $id = $match[1]; + $this->assertSession()->pageTextContains(sprintf('entity_test %s has been created.', $id)); + + // Make sure the timestamp is output properly with the default formatter. + $medium = DateFormat::load('medium')->getPattern(); + $this->drupalGet('entity_test/' . $id); + $this->assertSession()->pageTextContains($date->format($medium)); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest.php b/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest.php index 9f1468ba..e8c8ae5e 100644 --- a/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest.php +++ b/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest.php @@ -2,8 +2,6 @@ namespace Drupal\FunctionalTests\Entity; -use Drupal\Core\Entity\ContentEntityInterface; -use Drupal\Core\Entity\ContentEntityStorageInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; @@ -14,7 +12,7 @@ * * @group Entity */ -class ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest extends BrowserTestBase { +class ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest extends BrowserTestBase { /** * The ID of the type of the entity under test. @@ -77,19 +75,21 @@ public function testCorrectUserInputMappingOnComplexFields() { $storage = $this->container->get('entity_type.manager')->getStorage($this->entityTypeId); /** @var ContentEntityInterface $entity */ - $entity = $storage->create([$this->fieldName => [ - ['shape' => 'rectangle', 'color' => 'green'], - ['shape' => 'circle', 'color' => 'blue'], - ]]); + $entity = $storage->create([ + $this->fieldName => [ + ['shape' => 'rectangle', 'color' => 'green'], + ['shape' => 'circle', 'color' => 'blue'], + ], + ]); $entity->save(); $this->drupalGet($this->entityTypeId . '/manage/' . $entity->id() . '/edit'); // Rearrange the field items. - $edit = array( + $edit = [ "$this->fieldName[0][_weight]" => 0, "$this->fieldName[1][_weight]" => -1, - ); + ]; // Executing an ajax call is important before saving as it will trigger // form state caching and so if for any reasons the form is rebuilt with // the entity built based on the user submitted values with already diff --git a/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormFieldValidationFilteringTest.php b/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormFieldValidationFilteringTest.php new file mode 100644 index 00000000..0f17e642 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormFieldValidationFilteringTest.php @@ -0,0 +1,164 @@ +drupalCreateUser(['administer entity_test content']); + $this->drupalLogin($web_user); + + // Create two fields of field type "test_field", one with single cardinality + // and one with unlimited cardinality on the entity type "entity_test". It + // is important to use this field type because its default widget has a + // custom \Drupal\Core\Field\WidgetInterface::errorElement() implementation. + $this->entityTypeId = 'entity_test'; + $this->fieldNameSingle = 'test_single'; + $this->fieldNameMultiple = 'test_multiple'; + $this->fieldNameFile = 'test_file'; + + FieldStorageConfig::create([ + 'field_name' => $this->fieldNameSingle, + 'entity_type' => $this->entityTypeId, + 'type' => 'test_field', + 'cardinality' => 1, + ])->save(); + FieldConfig::create([ + 'entity_type' => $this->entityTypeId, + 'field_name' => $this->fieldNameSingle, + 'bundle' => $this->entityTypeId, + 'label' => 'Test single', + 'required' => TRUE, + 'translatable' => FALSE, + ])->save(); + + FieldStorageConfig::create([ + 'field_name' => $this->fieldNameMultiple, + 'entity_type' => $this->entityTypeId, + 'type' => 'test_field', + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + ])->save(); + FieldConfig::create([ + 'entity_type' => $this->entityTypeId, + 'field_name' => $this->fieldNameMultiple, + 'bundle' => $this->entityTypeId, + 'label' => 'Test multiple', + 'translatable' => FALSE, + ])->save(); + + // Also create a file field to test its '#limit_validation_errors' + // implementation. + FieldStorageConfig::create([ + 'field_name' => $this->fieldNameFile, + 'entity_type' => $this->entityTypeId, + 'type' => 'file', + 'cardinality' => 1, + ])->save(); + FieldConfig::create([ + 'entity_type' => $this->entityTypeId, + 'field_name' => $this->fieldNameFile, + 'bundle' => $this->entityTypeId, + 'label' => 'Test file', + 'translatable' => FALSE, + ])->save(); + + + entity_get_form_display($this->entityTypeId, $this->entityTypeId, 'default') + ->setComponent($this->fieldNameSingle, ['type' => 'test_field_widget']) + ->setComponent($this->fieldNameMultiple, ['type' => 'test_field_widget']) + ->setComponent($this->fieldNameFile, ['type' => 'file_generic']) + ->save(); + } + + /** + * Tests field widgets with #limit_validation_errors. + */ + public function testFieldWidgetsWithLimitedValidationErrors() { + $assert_session = $this->assertSession(); + $this->drupalGet($this->entityTypeId . '/add'); + + // The 'Test multiple' field is the only multi-valued field in the form, so + // try to add a new item for it. This tests the '#limit_validation_errors' + // property set by \Drupal\Core\Field\WidgetBase::formMultipleElements(). + $assert_session->elementsCount('css', 'div#edit-test-multiple-wrapper div.form-type-textfield input', 1); + $this->drupalPostForm(NULL, [], 'Add another item'); + $assert_session->elementsCount('css', 'div#edit-test-multiple-wrapper div.form-type-textfield input', 2); + + // Now try to upload a file. This tests the '#limit_validation_errors' + // property set by + // \Drupal\file\Plugin\Field\FieldWidget\FileWidget::process(). + $text_file = current($this->getTestFiles('text')); + $edit = [ + 'files[test_file_0]' => drupal_realpath($text_file->uri) + ]; + $assert_session->elementNotExists('css', 'input#edit-test-file-0-remove-button'); + $this->drupalPostForm(NULL, $edit, 'Upload'); + $assert_session->elementExists('css', 'input#edit-test-file-0-remove-button'); + + // Make the 'Test multiple' field required and check that adding another + // item throws a validation error. + $field_config = FieldConfig::loadByName($this->entityTypeId, $this->entityTypeId, $this->fieldNameMultiple); + $field_config->setRequired(TRUE); + $field_config->save(); + + $this->drupalPostForm($this->entityTypeId . '/add', [], 'Add another item'); + $assert_session->pageTextContains('Test multiple (value 1) field is required.'); + + // Check that saving the form without entering any value for the required + // field still throws the proper validation errors. + $this->drupalPostForm(NULL, [], 'Save'); + $assert_session->pageTextContains('Test single field is required.'); + $assert_session->pageTextContains('Test multiple (value 1) field is required.'); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/GetTestMethodCallerExtendsTest.php b/core/tests/Drupal/FunctionalTests/GetTestMethodCallerExtendsTest.php new file mode 100644 index 00000000..81ebb813 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/GetTestMethodCallerExtendsTest.php @@ -0,0 +1,31 @@ +getTestMethodCaller(); + $expected = [ + 'file' => __FILE__, + 'line' => 18, + 'function' => __CLASS__ . '->' . __FUNCTION__ . '()', + 'class' => BrowserTestBase::class, + 'object' => $this, + 'type' => '->', + 'args' => [], + ]; + $this->assertEquals($expected, $method_caller); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/GetTestMethodCallerTest.php b/core/tests/Drupal/FunctionalTests/GetTestMethodCallerTest.php new file mode 100644 index 00000000..f40ff20e --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/GetTestMethodCallerTest.php @@ -0,0 +1,31 @@ +getTestMethodCaller(); + $expected = [ + 'file' => __FILE__, + 'line' => 18, + 'function' => __CLASS__ . '->' . __FUNCTION__ . '()', + 'class' => BrowserTestBase::class, + 'object' => $this, + 'type' => '->', + 'args' => [], + ]; + $this->assertEquals($expected, $method_caller); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php b/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php new file mode 100644 index 00000000..c8748342 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php @@ -0,0 +1,91 @@ +container->getParameter('cors.config'); + $this->assertSame(FALSE, $cors_config['enabled']); + $this->assertSame([], $cors_config['allowedHeaders']); + $this->assertSame([], $cors_config['allowedMethods']); + $this->assertSame(['*'], $cors_config['allowedOrigins']); + + $this->assertSame(FALSE, $cors_config['exposedHeaders']); + $this->assertSame(FALSE, $cors_config['maxAge']); + $this->assertSame(FALSE, $cors_config['supportsCredentials']); + + // Enable CORS with the default options. + $cors_config['enabled'] = TRUE; + + $this->setContainerParameter('cors.config', $cors_config); + $this->rebuildContainer(); + + // Fire off a request. + $this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'MISS'); + $this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com'); + + // Fire the same exact request. This time it should be cached. + $this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'HIT'); + $this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com'); + + // Fire a request for a different origin. Verify the CORS header. + $this->drupalGet('/test-page', [], ['Origin' => 'http://example.org']); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'HIT'); + $this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.org'); + + // Configure the CORS stack to allow a specific set of origins. + $cors_config['allowedOrigins'] = ['http://example.com']; + + $this->setContainerParameter('cors.config', $cors_config); + $this->rebuildContainer(); + + // Fire a request from an origin that isn't allowed. + /** @var \Symfony\Component\HttpFoundation\Response $response */ + $this->drupalGet('/test-page', [], ['Origin' => 'http://non-valid.com']); + $this->assertSession()->statusCodeEquals(403); + $this->assertSession()->pageTextContains('Not allowed.'); + + // Specify a valid origin. + $this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com'); + + // Verify POST still functions with 'Origin' header set to site's domain. + $origin = \Drupal::request()->getSchemeAndHttpHost(); + + /** @var \GuzzleHttp\ClientInterface $httpClient */ + $httpClient = $this->getSession()->getDriver()->getClient()->getClient(); + $url = Url::fromUri('base:/test-page'); + $response = $httpClient->request('POST', $url->setAbsolute()->toString(), [ + 'headers' => [ + 'Origin' => $origin, + ] + ]); + $this->assertEquals(200, $response->getStatusCode()); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Image/ToolkitSetupFormTest.php b/core/tests/Drupal/FunctionalTests/Image/ToolkitSetupFormTest.php new file mode 100644 index 00000000..d501f1d9 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Image/ToolkitSetupFormTest.php @@ -0,0 +1,74 @@ +adminUser = $this->drupalCreateUser([ + 'administer site configuration', + ]); + $this->drupalLogin($this->adminUser); + } + + /** + * Test Image toolkit setup form. + */ + public function testToolkitSetupForm() { + // Get form. + $this->drupalGet('admin/config/media/image-toolkit'); + + // Test that default toolkit is GD. + $this->assertFieldByName('image_toolkit', 'gd', 'The default image toolkit is GD.'); + + // Test changing the jpeg image quality. + $edit = ['gd[image_jpeg_quality]' => '70']; + $this->drupalPostForm(NULL, $edit, 'Save configuration'); + $this->assertEqual($this->config('system.image.gd')->get('jpeg_quality'), '70'); + + // Test changing the toolkit. + $edit = ['image_toolkit' => 'test']; + $this->drupalPostForm(NULL, $edit, 'Save configuration'); + $this->assertEqual($this->config('system.image')->get('toolkit'), 'test'); + $this->assertFieldByName('test[test_parameter]', '10'); + + // Test changing the test toolkit parameter. + $edit = ['test[test_parameter]' => '0']; + $this->drupalPostForm(NULL, $edit, 'Save configuration'); + $this->assertText(t('Test parameter should be different from 0.'), 'Validation error displayed.'); + $edit = ['test[test_parameter]' => '20']; + $this->drupalPostForm(NULL, $edit, 'Save configuration'); + $this->assertEqual($this->config('system.image.test_toolkit')->get('test_parameter'), '20'); + + // Test access without the permission 'administer site configuration'. + $this->drupalLogin($this->drupalCreateUser(['access administration pages'])); + $this->drupalGet('admin/config/media/image-toolkit'); + $this->assertResponse(403); + } + +} diff --git a/core/modules/system/src/Tests/Image/ToolkitTest.php b/core/tests/Drupal/FunctionalTests/Image/ToolkitTest.php similarity index 81% rename from core/modules/system/src/Tests/Image/ToolkitTest.php rename to core/tests/Drupal/FunctionalTests/Image/ToolkitTest.php index 88483238..789369ce 100644 --- a/core/modules/system/src/Tests/Image/ToolkitTest.php +++ b/core/tests/Drupal/FunctionalTests/Image/ToolkitTest.php @@ -1,6 +1,6 @@ container->get('image.toolkit.manager'); $toolkits = $manager->getAvailableToolkits(); $this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.'); $this->assertTrue(isset($toolkits['test:derived_toolkit']), 'The derived toolkit was returned.'); $this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned'); - $this->assertToolkitOperationsCalled(array()); + $this->assertToolkitOperationsCalled([]); } /** * Tests Image's methods. */ - function testLoad() { + public function testLoad() { $image = $this->getImage(); $this->assertTrue(is_object($image), 'Returned an object.'); $this->assertEqual($image->getToolkitId(), 'test', 'Image had toolkit set.'); - $this->assertToolkitOperationsCalled(array('parseFile')); + $this->assertToolkitOperationsCalled(['parseFile']); } /** * Test the image_save() function. */ - function testSave() { + public function testSave() { $this->assertFalse($this->image->save(), 'Function returned the expected value.'); - $this->assertToolkitOperationsCalled(array('save')); + $this->assertToolkitOperationsCalled(['save']); } /** * Test the image_apply() function. */ - function testApply() { - $data = array('p1' => 1, 'p2' => TRUE, 'p3' => 'text'); + public function testApply() { + $data = ['p1' => 1, 'p2' => TRUE, 'p3' => 'text']; $this->assertTrue($this->image->apply('my_operation', $data), 'Function returned the expected value.'); // Check that apply was called and with the correct parameters. - $this->assertToolkitOperationsCalled(array('apply')); + $this->assertToolkitOperationsCalled(['apply']); $calls = $this->imageTestGetAllCalls(); $this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation"); $this->assertEqual($calls['apply'][0][1]['p1'], 1, 'integer parameter p1 was passed correctly'); @@ -58,14 +58,14 @@ function testApply() { /** * Test the image_apply() function. */ - function testApplyNoParameters() { + public function testApplyNoParameters() { $this->assertTrue($this->image->apply('my_operation'), 'Function returned the expected value.'); // Check that apply was called and with the correct parameters. - $this->assertToolkitOperationsCalled(array('apply')); + $this->assertToolkitOperationsCalled(['apply']); $calls = $this->imageTestGetAllCalls(); $this->assertEqual($calls['apply'][0][0], 'my_operation', "'my_operation' was passed correctly as operation"); - $this->assertEqual($calls['apply'][0][1], array(), 'passing no parameters was handled correctly'); + $this->assertEqual($calls['apply'][0][1], [], 'passing no parameters was handled correctly'); } /** diff --git a/core/tests/Drupal/FunctionalTests/Image/ToolkitTestBase.php b/core/tests/Drupal/FunctionalTests/Image/ToolkitTestBase.php new file mode 100644 index 00000000..2f6b7ccd --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Image/ToolkitTestBase.php @@ -0,0 +1,158 @@ +imageFactory = $this->container->get('image.factory'); + + // Pick a file for testing. + $file = current($this->drupalGetTestFiles('image')); + $this->file = $file->uri; + + // Setup a dummy image to work with. + $this->image = $this->getImage(); + + // Clear out any hook calls. + $this->imageTestReset(); + } + + /** + * Sets up an image with the custom toolkit. + * + * @return \Drupal\Core\Image\ImageInterface + * The image object. + */ + protected function getImage() { + $image = $this->imageFactory->get($this->file, 'test'); + $this->assertTrue($image->isValid(), 'Image file was parsed.'); + return $image; + } + + /** + * Assert that all of the specified image toolkit operations were called + * exactly once once, other values result in failure. + * + * @param $expected + * Array with string containing with the operation name, e.g. 'load', + * 'save', 'crop', etc. + */ + public function assertToolkitOperationsCalled(array $expected) { + // If one of the image operations is expected, apply should be expected as + // well. + $operations = [ + 'resize', + 'rotate', + 'crop', + 'desaturate', + 'create_new', + 'scale', + 'scale_and_crop', + 'my_operation', + 'convert', + ]; + if (count(array_intersect($expected, $operations)) > 0 && !in_array('apply', $expected)) { + $expected[] = 'apply'; + } + + // Determine which operations were called. + $actual = array_keys(array_filter($this->imageTestGetAllCalls())); + + // Determine if there were any expected that were not called. + $uncalled = array_diff($expected, $actual); + if (count($uncalled)) { + $this->assertTrue(FALSE, SafeMarkup::format('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)])); + } + else { + $this->assertTrue(TRUE, SafeMarkup::format('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)])); + } + + // Determine if there were any unexpected calls. + // If all unexpected calls are operations and apply was expected, we do not + // count it as an error. + $unexpected = array_diff($actual, $expected); + if (count($unexpected) && (!in_array('apply', $expected) || count(array_intersect($unexpected, $operations)) !== count($unexpected))) { + $this->assertTrue(FALSE, SafeMarkup::format('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)])); + } + else { + $this->assertTrue(TRUE, 'No unexpected operations were called.'); + } + } + + /** + * Resets/initializes the history of calls to the test toolkit functions. + */ + protected function imageTestReset() { + // Keep track of calls to these operations + $results = [ + 'parseFile' => [], + 'save' => [], + 'settings' => [], + 'apply' => [], + 'resize' => [], + 'rotate' => [], + 'crop' => [], + 'desaturate' => [], + 'create_new' => [], + 'scale' => [], + 'scale_and_crop' => [], + 'convert' => [], + ]; + \Drupal::state()->set('image_test.results', $results); + } + + /** + * Gets an array of calls to the test toolkit. + * + * @return array + * An array keyed by operation name ('parseFile', 'save', 'settings', + * 'resize', 'rotate', 'crop', 'desaturate') with values being arrays of + * parameters passed to each call. + */ + protected function imageTestGetAllCalls() { + return \Drupal::state()->get('image_test.results') ?: []; + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Routing/CaseInsensitivePathTest.php b/core/tests/Drupal/FunctionalTests/Routing/CaseInsensitivePathTest.php new file mode 100644 index 00000000..3aaac143 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Routing/CaseInsensitivePathTest.php @@ -0,0 +1,113 @@ +set('system_test.module_hidden', FALSE); + $this->createContentType(['type' => 'page']); + } + + /** + * Tests mixed case paths. + */ + public function testMixedCasePaths() { + // Tests paths defined by routes from standard modules as anonymous. + $this->drupalGet('user/login'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/Log in/'); + $this->drupalGet('User/Login'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/Log in/'); + + // Tests paths defined by routes from the Views module. + $admin = $this->drupalCreateUser(['access administration pages', 'administer nodes', 'access content overview']); + $this->drupalLogin($admin); + + $this->drupalGet('admin/content'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/Content/'); + $this->drupalGet('Admin/Content'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/Content/'); + + // Tests paths with query arguments. + + // Make sure our node title doesn't exist. + $this->drupalGet('admin/content'); + $this->assertSession()->linkNotExists('FooBarBaz'); + $this->assertSession()->linkNotExists('foobarbaz'); + + // Create a node, and make sure it shows up on admin/content. + $node = $this->createNode([ + 'title' => 'FooBarBaz', + 'type' => 'page', + ]); + + $this->drupalGet('admin/content', [ + 'query' => [ + 'title' => 'FooBarBaz' + ] + ]); + + $this->assertSession()->linkExists('FooBarBaz'); + $this->assertSession()->linkByHrefExists($node->toUrl()->toString()); + + // Make sure the path is case-insensitive, and query case is preserved. + + $this->drupalGet('Admin/Content', [ + 'query' => [ + 'title' => 'FooBarBaz' + ] + ]); + + $this->assertSession()->linkExists('FooBarBaz'); + $this->assertSession()->linkByHrefExists($node->toUrl()->toString()); + $this->assertSession()->fieldValueEquals('edit-title', 'FooBarBaz'); + // Check that we can access the node with a mixed case path. + $this->drupalGet('NOdE/' . $node->id()); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/FooBarBaz/'); + } + + /** + * Tests paths with slugs. + */ + public function testPathsWithArguments() { + $this->drupalGet('system-test/echo/foobarbaz'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/foobarbaz/'); + $this->assertSession()->pageTextNotMatches('/FooBarBaz/'); + + $this->drupalGet('system-test/echo/FooBarBaz'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/FooBarBaz/'); + $this->assertSession()->pageTextNotMatches('/foobarbaz/'); + + // Test utf-8 characters in the route path. + $this->drupalGet('/system-test/È„chÈ/meΦω/ABc123'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/ABc123/'); + $this->drupalGet('/system-test/È…chÈŽ/MEΦΩ/ABc123'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextMatches('/ABc123/'); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Routing/PathEncodedTest.php b/core/tests/Drupal/FunctionalTests/Routing/PathEncodedTest.php new file mode 100644 index 00000000..a8aee897 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Routing/PathEncodedTest.php @@ -0,0 +1,54 @@ + '/hi/llamma:party', + 'path_encoded_test.atsign' => '/bloggy/@Dries', + 'path_encoded_test.parens' => '/cat(box)', + ]; + foreach ($route_paths as $route_name => $path) { + $this->drupalGet(Url::fromRoute($route_name)); + $this->assertSession()->pageTextContains('PathEncodedTestController works'); + } + } + + public function testAliasToEncoded() { + $route_paths = [ + 'path_encoded_test.colon' => '/hi/llamma:party', + 'path_encoded_test.atsign' => '/bloggy/@Dries', + 'path_encoded_test.parens' => '/cat(box)', + ]; + /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */ + $alias_storage = $this->container->get('path.alias_storage'); + $aliases = []; + foreach ($route_paths as $route_name => $path) { + $aliases[$route_name] = $this->randomMachineName(); + $alias_storage->save($path, '/' . $aliases[$route_name]); + } + foreach ($route_paths as $route_name => $path) { + // The alias may be only a suffix of the generated path when the test is + // run with Drupal installed in a subdirectory. + $this->assertRegExp('@/' . rawurlencode($aliases[$route_name]) . '$@', Url::fromRoute($route_name)->toString()); + $this->drupalGet(Url::fromRoute($route_name)); + $this->assertSession()->pageTextContains('PathEncodedTestController works'); + } + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Theme/BartikTest.php b/core/tests/Drupal/FunctionalTests/Theme/BartikTest.php new file mode 100644 index 00000000..8ef9db42 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Theme/BartikTest.php @@ -0,0 +1,40 @@ +assertTrue($this->container->get('theme_installer')->install(['bartik'])); + $this->container->get('config.factory') + ->getEditable('system.theme') + ->set('default', 'bartik') + ->save(); + } + + /** + * Tests that the Bartik theme always adds its message CSS and Classy's. + * + * @see bartik.libraries.yml + * @see classy.info.yml + */ + public function testRegressionMissingMessagesCss() { + $this->drupalGet(''); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseContains('bartik/css/components/messages.css'); + $this->assertSession()->responseContains('classy/css/components/messages.css'); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Theme/ClassyTest.php b/core/tests/Drupal/FunctionalTests/Theme/ClassyTest.php new file mode 100644 index 00000000..dca624e4 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Theme/ClassyTest.php @@ -0,0 +1,38 @@ +assertTrue($this->container->get('theme_installer')->install(['classy'])); + $this->container->get('config.factory') + ->getEditable('system.theme') + ->set('default', 'classy') + ->save(); + } + + /** + * Tests that the Classy theme always adds its message CSS. + * + * @see classy.info.yml + */ + public function testRegressionMissingMessagesCss() { + $this->drupalGet(''); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->responseContains('classy/css/components/messages.css'); + } + +} diff --git a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php new file mode 100644 index 00000000..4aca5003 --- /dev/null +++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php @@ -0,0 +1,436 @@ +databaseDumpFiles variable to the + * database dump files, and then call parent::setUp() to run the base setUp() + * method in this class. + * - In your test method, call $this->runUpdates() to run the necessary updates, + * and then use test assertions to verify that the result is what you expect. + * - In order to test both with a "bare" database dump as well as with a + * database dump filled with content, extend your update path test class with + * a new test class that overrides the bare database dump. Refer to + * UpdatePathTestBaseFilledTest for an example. + * + * @ingroup update_api + * + * @see hook_update_N() + */ +abstract class UpdatePathTestBase extends BrowserTestBase { + + use SchemaCheckTestTrait; + + /** + * Modules to enable after the database is loaded. + */ + protected static $modules = []; + + /** + * The file path(s) to the dumped database(s) to load into the child site. + * + * The file system/tests/fixtures/update/drupal-8.bare.standard.php.gz is + * normally included first -- this sets up the base database from a bare + * standard Drupal installation. + * + * The file system/tests/fixtures/update/drupal-8.filled.standard.php.gz + * can also be used in case we want to test with a database filled with + * content, and with all core modules enabled. + * + * @var array + */ + protected $databaseDumpFiles = []; + + /** + * The install profile used in the database dump file. + * + * @var string + */ + protected $installProfile = 'standard'; + + /** + * Flag that indicates whether the child site has been updated. + * + * @var bool + */ + protected $upgradedSite = FALSE; + + /** + * Array of errors triggered during the update process. + * + * @var array + */ + protected $upgradeErrors = []; + + /** + * Array of modules loaded when the test starts. + * + * @var array + */ + protected $loadedModules = []; + + /** + * Flag to indicate whether zlib is installed or not. + * + * @var bool + */ + protected $zlibInstalled = TRUE; + + /** + * Flag to indicate whether there are pending updates or not. + * + * @var bool + */ + protected $pendingUpdates = TRUE; + + /** + * The update URL. + * + * @var string + */ + protected $updateUrl; + + /** + * Disable strict config schema checking. + * + * The schema is verified at the end of running the update. + * + * @var bool + */ + protected $strictConfigSchema = FALSE; + + /** + * Fail the test if there are failed updates. + * + * @var bool + */ + protected $checkFailedUpdates = TRUE; + + /** + * Constructs an UpdatePathTestCase object. + * + * @param $test_id + * (optional) The ID of the test. Tests with the same id are reported + * together. + */ + public function __construct($test_id = NULL) { + parent::__construct($test_id); + $this->zlibInstalled = function_exists('gzopen'); + } + + /** + * Overrides WebTestBase::setUp() for update testing. + * + * The main difference in this method is that rather than performing the + * installation via the installer, a database is loaded. Additional work is + * then needed to set various things such as the config directories and the + * container that would normally be done via the installer. + */ + protected function setUp() { + $request = Request::createFromGlobals(); + + // Boot up Drupal into a state where calling the database API is possible. + // This is used to initialize the database system, so we can load the dump + // files. + $autoloader = require $this->root . '/autoload.php'; + $kernel = TestRunnerKernel::createFromRequest($request, $autoloader); + $kernel->loadLegacyIncludes(); + + $this->changeDatabasePrefix(); + $this->runDbTasks(); + // Allow classes to set database dump files. + $this->setDatabaseDumpFiles(); + + // We are going to set a missing zlib requirement property for usage + // during the performUpgrade() and tearDown() methods. Also set that the + // tests failed. + if (!$this->zlibInstalled) { + parent::setUp(); + return; + } + // Set the update url. This must be set here rather than in + // self::__construct() or the old URL generator will leak additional test + // sites. + $this->updateUrl = Url::fromRoute('system.db_update'); + + $this->setupBaseUrl(); + + // Install Drupal test site. + $this->prepareEnvironment(); + $this->installDrupal(); + + // Add the config directories to settings.php. + drupal_install_config_directories(); + + // Set the container. parent::rebuildAll() would normally do this, but this + // not safe to do here, because the database has not been updated yet. + $this->container = \Drupal::getContainer(); + + $this->replaceUser1(); + + require_once \Drupal::root() . '/core/includes/update.inc'; + + // Setup Mink. + $session = $this->initMink(); + + $cookies = $this->extractCookiesFromRequest(\Drupal::request()); + foreach ($cookies as $cookie_name => $values) { + foreach ($values as $value) { + $session->setCookie($cookie_name, $value); + } + } + + // Set up the browser test output file. + $this->initBrowserOutputFile(); + } + + /** + * {@inheritdoc} + */ + public function installDrupal() { + $this->initUserSession(); + $this->prepareSettings(); + $this->doInstall(); + $this->initSettings(); + + $request = Request::createFromGlobals(); + $container = $this->initKernel($request); + $this->initConfig($container); + } + + /** + * {@inheritdoc} + */ + protected function doInstall() { + $this->runDbTasks(); + // Allow classes to set database dump files. + $this->setDatabaseDumpFiles(); + + // Load the database(s). + foreach ($this->databaseDumpFiles as $file) { + if (substr($file, -3) == '.gz') { + $file = "compress.zlib://$file"; + } + require $file; + } + } + + /** + * {@inheritdoc} + */ + protected function initMink() { + $driver = $this->getDefaultDriverInstance(); + + if ($driver instanceof GoutteDriver) { + // Turn off curl timeout. Having a timeout is not a problem in a normal + // test running, but it is a problem when debugging. Also, disable SSL + // peer verification so that testing under HTTPS always works. + /** @var \GuzzleHttp\Client $client */ + $client = $this->container->get('http_client_factory')->fromOptions([ + 'timeout' => NULL, + 'verify' => FALSE, + ]); + + // Inject a Guzzle middleware to generate debug output for every request + // performed in the test. + $handler_stack = $client->getConfig('handler'); + $handler_stack->push($this->getResponseLogHandler()); + + $driver->getClient()->setClient($client); + } + + $selectors_handler = new SelectorsHandler([ + 'hidden_field_selector' => new HiddenFieldSelector() + ]); + $session = new Session($driver, $selectors_handler); + $this->mink = new Mink(); + $this->mink->registerSession('default', $session); + $this->mink->setDefaultSessionName('default'); + $this->registerSessions(); + + return $session; + } + + /** + * Set database dump files to be used. + */ + abstract protected function setDatabaseDumpFiles(); + + /** + * Add settings that are missed since the installer isn't run. + */ + protected function prepareSettings() { + parent::prepareSettings(); + + // Remember the profile which was used. + $settings['settings']['install_profile'] = (object) [ + 'value' => $this->installProfile, + 'required' => TRUE, + ]; + // Generate a hash salt. + $settings['settings']['hash_salt'] = (object) [ + 'value' => Crypt::randomBytesBase64(55), + 'required' => TRUE, + ]; + + // Since the installer isn't run, add the database settings here too. + $settings['databases']['default'] = (object) [ + 'value' => Database::getConnectionInfo(), + 'required' => TRUE, + ]; + + $this->writeSettings($settings); + } + + /** + * Helper function to run pending database updates. + */ + protected function runUpdates() { + if (!$this->zlibInstalled) { + $this->fail('Missing zlib requirement for update tests.'); + return FALSE; + } + // The site might be broken at the time so logging in using the UI might + // not work, so we use the API itself. + drupal_rewrite_settings([ + 'settings' => [ + 'update_free_access' => (object) [ + 'value' => TRUE, + 'required' => TRUE, + ], + ], + ]); + + $this->drupalGet($this->updateUrl); + $this->clickLink(t('Continue')); + + $this->doSelectionTest(); + // Run the update hooks. + $this->clickLink(t('Apply pending updates')); + $this->checkForMetaRefresh(); + + // Ensure there are no failed updates. + if ($this->checkFailedUpdates) { + $this->assertNoRaw('' . t('Failed:') . ''); + + // Ensure that there are no pending updates. + foreach (['update', 'post_update'] as $update_type) { + switch ($update_type) { + case 'update': + $all_updates = update_get_update_list(); + break; + case 'post_update': + $all_updates = \Drupal::service('update.post_update_registry')->getPendingUpdateInformation(); + break; + } + foreach ($all_updates as $module => $updates) { + if (!empty($updates['pending'])) { + foreach (array_keys($updates['pending']) as $update_name) { + $this->fail("The $update_name() update function from the $module module did not run."); + } + } + } + } + // Reset the static cache of drupal_get_installed_schema_version() so that + // more complex update path testing works. + drupal_static_reset('drupal_get_installed_schema_version'); + + // The config schema can be incorrect while the update functions are being + // executed. But once the update has been completed, it needs to be valid + // again. Assert the schema of all configuration objects now. + $names = $this->container->get('config.storage')->listAll(); + /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */ + $typed_config = $this->container->get('config.typed'); + $typed_config->clearCachedDefinitions(); + foreach ($names as $name) { + $config = $this->config($name); + $this->assertConfigSchema($typed_config, $name, $config->get()); + } + + // Ensure that the update hooks updated all entity schema. + $needs_updates = \Drupal::entityDefinitionUpdateManager()->needsUpdates(); + $this->assertFalse($needs_updates, 'After all updates ran, entity schema is up to date.'); + if ($needs_updates) { + foreach (\Drupal::entityDefinitionUpdateManager() + ->getChangeSummary() as $entity_type_id => $summary) { + foreach ($summary as $message) { + $this->fail($message); + } + } + } + } + } + + /** + * Runs the install database tasks for the driver used by the test runner. + */ + protected function runDbTasks() { + // Create a minimal container so that t() works. + // @see install_begin_request() + $container = new ContainerBuilder(); + $container->setParameter('language.default_values', Language::$defaultValues); + $container + ->register('language.default', 'Drupal\Core\Language\LanguageDefault') + ->addArgument('%language.default_values%'); + $container + ->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager') + ->addArgument(new Reference('language.default')); + \Drupal::setContainer($container); + + require_once __DIR__ . '/../../../../includes/install.inc'; + $connection = Database::getConnection(); + $errors = db_installer_object($connection->driver())->runTasks(); + if (!empty($errors)) { + $this->fail('Failed to run installer database tasks: ' . implode(', ', $errors)); + } + } + + /** + * Replace User 1 with the user created here. + */ + protected function replaceUser1() { + /** @var \Drupal\user\UserInterface $account */ + // @todo: Saving the account before the update is problematic. + // https://www.drupal.org/node/2560237 + $account = User::load(1); + $account->setPassword($this->rootUser->pass_raw); + $account->setEmail($this->rootUser->getEmail()); + $account->setUsername($this->rootUser->getUsername()); + $account->save(); + } + + /** + * Tests the selection page. + */ + protected function doSelectionTest() { + // No-op. Tests wishing to do test the selection page or the general + // update.php environment before running update.php can override this method + // and implement their required tests. + } + +} diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php similarity index 91% rename from core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php rename to core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php index efff9860..a375db7e 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php +++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php @@ -1,6 +1,6 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/drupal-8.update-test-schema-enabled.php', + __DIR__ . '/../../../../modules/system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php', ]; } @@ -83,7 +83,7 @@ public function testUpdateHookN() { $select->range(0, 5); $select->fields('watchdog', ['message']); - $container_cannot_be_saved_messages = array_filter(iterator_to_array($select->execute()), function($row) { + $container_cannot_be_saved_messages = array_filter(iterator_to_array($select->execute()), function ($row) { return strpos($row->message, 'Container cannot be saved to cache.') !== FALSE; }); $this->assertEqual([], $container_cannot_be_saved_messages); diff --git a/core/tests/Drupal/KernelTests/AssertLegacyTrait.php b/core/tests/Drupal/KernelTests/AssertLegacyTrait.php index 1d1816aa..f63c4bf0 100644 --- a/core/tests/Drupal/KernelTests/AssertLegacyTrait.php +++ b/core/tests/Drupal/KernelTests/AssertLegacyTrait.php @@ -6,7 +6,7 @@ * Translates Simpletest assertion methods to PHPUnit. * * Protected methods are custom. Public static methods override methods of - * \PHPUnit_Framework_Assert. + * \PHPUnit\Framework\Assert. * * @deprecated Scheduled for removal in Drupal 9.0.0. Use PHPUnit's native * assert methods instead. diff --git a/core/tests/Drupal/KernelTests/Component/Utility/SafeMarkupKernelTest.php b/core/tests/Drupal/KernelTests/Component/Utility/SafeMarkupKernelTest.php index cd42ad1b..8fab3072 100644 --- a/core/tests/Drupal/KernelTests/Component/Utility/SafeMarkupKernelTest.php +++ b/core/tests/Drupal/KernelTests/Component/Utility/SafeMarkupKernelTest.php @@ -107,10 +107,10 @@ public function providerTestSafeMarkupUri() { /** * @dataProvider providerTestSafeMarkupUriWithException - * @expectedException \InvalidArgumentException */ public function testSafeMarkupUriWithExceptionUri($string, $uri) { // Should throw an \InvalidArgumentException, due to Uri::toString(). + $this->setExpectedException(\InvalidArgumentException::class); $args = self::getSafeMarkupUriArgs($uri); SafeMarkup::format($string, $args); diff --git a/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php b/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php index 7b84b597..6abb5cce 100644 --- a/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php +++ b/core/tests/Drupal/KernelTests/Config/DefaultConfigTest.php @@ -6,6 +6,7 @@ use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\StorageInterface; use Drupal\KernelTests\AssertConfigTrait; +use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait; use Drupal\KernelTests\KernelTestBase; /** @@ -16,6 +17,7 @@ class DefaultConfigTest extends KernelTestBase { use AssertConfigTrait; + use FileSystemModuleDiscoveryDataProviderTrait; /** * {@inheritdoc} @@ -30,7 +32,7 @@ class DefaultConfigTest extends KernelTestBase { /** * The following config entries are changed on module install. * - * Compare them does not make sense. + * Comparing them does not make sense. * * @todo Figure out why simpletest.settings is not installed. * @@ -61,7 +63,7 @@ protected function setUp() { /** * Tests if installed config is equal to the exported config. * - * @dataProvider providerTestModuleConfig + * @dataProvider coreModuleListDataProvider */ public function testModuleConfig($module) { // System and user are required in order to be able to install some of the @@ -86,7 +88,7 @@ public function testModuleConfig($module) { } // Work out any additional modules and themes that need installing to create - // and optional config. + // an optional config. $optional_config_storage = new FileStorage($module_path . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION); $modules_to_install = [$module]; $themes_to_install = []; @@ -142,24 +144,4 @@ protected function doTestsOnConfigStorage(StorageInterface $default_config_stora } } - /** - * Test data provider for ::testModuleConfig(). - * - * @return array - * An array of module names to test. - */ - public function providerTestModuleConfig() { - $module_dirs = array_keys(iterator_to_array(new \FilesystemIterator(__DIR__ . '/../../../../modules/'))); - $module_names = array_map(function($path) { - return str_replace(__DIR__ . '/../../../../modules/', '', $path); - }, $module_dirs); - $modules_keyed = array_combine($module_names, $module_names); - - $data = array_map(function ($module) { - return [$module]; - }, $modules_keyed); - - return $data; - } - } diff --git a/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php b/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php new file mode 100644 index 00000000..06881f25 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php @@ -0,0 +1,165 @@ +installConfig('config_test'); + } + + /** + * Verifies that the Typed Data API is implemented correctly. + */ + public function testTypedDataAPI() { + /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */ + $typed_config_manager = \Drupal::service('config.typed'); + /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */ + $typed_config = $typed_config_manager->get('config_test.validation'); + + // Test a primitive. + $string_data = $typed_config->get('llama'); + $this->assertInstanceOf(StringInterface::class, $string_data); + $this->assertEquals('llama', $string_data->getValue()); + + // Test complex data. + $mapping = $typed_config->get('cat'); + /** @var \Drupal\Core\TypedData\ComplexDataInterface $mapping */ + $this->assertInstanceOf(ComplexDataInterface::class, $mapping); + $this->assertInstanceOf(StringInterface::class, $mapping->get('type')); + $this->assertEquals('kitten', $mapping->get('type')->getValue()); + $this->assertInstanceOf(IntegerInterface::class, $mapping->get('count')); + $this->assertEquals(2, $mapping->get('count')->getValue()); + // Verify the item metadata is available. + $this->assertInstanceOf(ComplexDataDefinitionInterface::class, $mapping->getDataDefinition()); + $this->assertArrayHasKey('type', $mapping->getProperties()); + $this->assertArrayHasKey('count', $mapping->getProperties()); + + // Test accessing sequences. + $sequence = $typed_config->get('giraffe'); + /** @var \Drupal\Core\TypedData\ListInterface $sequence */ + $this->assertInstanceOf(ComplexDataInterface::class, $sequence); + $this->assertInstanceOf(StringInterface::class, $sequence->get('hum1')); + $this->assertEquals('hum1', $sequence->get('hum1')->getValue()); + $this->assertEquals('hum2', $sequence->get('hum2')->getValue()); + $this->assertEquals(2, count($sequence->getIterator())); + // Verify the item metadata is available. + $this->assertInstanceOf(SequenceDataDefinition::class, $sequence->getDataDefinition()); + + // Test accessing typed config objects for simple config and config + // entities. + $typed_config_manager = \Drupal::service('config.typed'); + $typed_config = $typed_config_manager->createFromNameAndData('config_test.validation', \Drupal::configFactory()->get('config_test.validation')->get()); + $this->assertInstanceOf(TypedConfigInterface::class, $typed_config); + $this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', '_core'], array_keys($typed_config->getElements())); + + $config_test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([ + 'id' => 'asterix', + 'label' => 'Asterix', + 'weight' => 11, + 'style' => 'test_style', + ]); + + $typed_config = $typed_config_manager->createFromNameAndData($config_test_entity->getConfigDependencyName(), $config_test_entity->toArray()); + $this->assertInstanceOf(TypedConfigInterface::class, $typed_config); + $this->assertEquals(['uuid', 'langcode', 'status', 'dependencies', 'id', 'label', 'weight', 'style', 'size', 'size_value', 'protected_property'], array_keys($typed_config->getElements())); + } + + /** + * Tests config validation via the Typed Data API. + */ + public function testSimpleConfigValidation() { + $config = \Drupal::configFactory()->getEditable('config_test.validation'); + /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */ + $typed_config_manager = \Drupal::service('config.typed'); + /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */ + $typed_config = $typed_config_manager->get('config_test.validation'); + + $result = $typed_config->validate(); + $this->assertInstanceOf(ConstraintViolationListInterface::class, $result); + $this->assertEmpty($result); + + // Test constraints on primitive types. + $config->set('llama', 'elephant'); + $config->save(); + + $typed_config = $typed_config_manager->get('config_test.validation'); + $result = $typed_config->validate(); + // Its not a valid llama anymore. + $this->assertCount(1, $result); + $this->assertEquals('no valid llama', $result->get(0)->getMessage()); + + // Test constraints on mapping. + $config->set('llama', 'llama'); + $config->set('cat.type', 'nyans'); + $config->save(); + + $typed_config = $typed_config_manager->get('config_test.validation'); + $result = $typed_config->validate(); + $this->assertEmpty($result); + + // Test constrains on nested mapping. + $config->set('cat.type', 'miaus'); + $config->save(); + + $typed_config = $typed_config_manager->get('config_test.validation'); + $result = $typed_config->validate(); + $this->assertCount(1, $result); + $this->assertEquals('no valid cat', $result->get(0)->getMessage()); + + // Test constrains on sequences elements. + $config->set('cat.type', 'nyans'); + $config->set('giraffe', ['muh', 'hum2']); + $config->save(); + $typed_config = $typed_config_manager->get('config_test.validation'); + $result = $typed_config->validate(); + $this->assertCount(1, $result); + $this->assertEquals('Giraffes just hum', $result->get(0)->getMessage()); + + // Test constrains on the sequence itself. + $config->set('giraffe', ['hum', 'hum2', 'invalid-key' => 'hum']); + $config->save(); + + $typed_config = $typed_config_manager->get('config_test.validation'); + $result = $typed_config->validate(); + $this->assertCount(1, $result); + $this->assertEquals('giraffe', $result->get(0)->getPropertyPath()); + $this->assertEquals('Invalid giraffe key.', $result->get(0)->getMessage()); + + // Validates mapping. + $typed_config = $typed_config_manager->get('config_test.validation'); + $value = $typed_config->getValue(); + unset($value['giraffe']); + $value['elephant'] = 'foo'; + $typed_config->setValue($value); + $result = $typed_config->validate(); + $this->assertCount(1, $result); + $this->assertEquals('', $result->get(0)->getPropertyPath()); + $this->assertEquals('Missing giraffe.', $result->get(0)->getMessage()); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php b/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php index 72e7b6f8..1e1c6fd8 100644 --- a/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php +++ b/core/tests/Drupal/KernelTests/Core/Asset/AttachedAssetsTest.php @@ -39,7 +39,7 @@ class AttachedAssetsTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('language', 'simpletest', 'common_test', 'system'); + public static $modules = ['language', 'simpletest', 'common_test', 'system']; /** * {@inheritdoc} @@ -55,28 +55,28 @@ protected function setUp() { /** * Tests that default CSS and JavaScript is empty. */ - function testDefault() { + public function testDefault() { $assets = new AttachedAssets(); - $this->assertEqual(array(), $this->assetResolver->getCssAssets($assets, FALSE), 'Default CSS is empty.'); + $this->assertEqual([], $this->assetResolver->getCssAssets($assets, FALSE), 'Default CSS is empty.'); list($js_assets_header, $js_assets_footer) = $this->assetResolver->getJsAssets($assets, FALSE); - $this->assertEqual(array(), $js_assets_header, 'Default header JavaScript is empty.'); - $this->assertEqual(array(), $js_assets_footer, 'Default footer JavaScript is empty.'); + $this->assertEqual([], $js_assets_header, 'Default header JavaScript is empty.'); + $this->assertEqual([], $js_assets_footer, 'Default footer JavaScript is empty.'); } /** * Tests non-existing libraries. */ - function testLibraryUnknown() { + public function testLibraryUnknown() { $build['#attached']['library'][] = 'core/unknown'; $assets = AttachedAssets::createFromRenderArray($build); - $this->assertIdentical([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.'); + $this->assertSame([], $this->assetResolver->getJsAssets($assets, FALSE)[0], 'Unknown library was not added to the page.'); } /** * Tests adding a CSS and a JavaScript file. */ - function testAddFiles() { + public function testAddFiles() { $build['#attached']['library'][] = 'common_test/files'; $assets = AttachedAssets::createFromRenderArray($build); @@ -97,7 +97,7 @@ function testAddFiles() { /** * Tests adding JavaScript settings. */ - function testAddJsSettings() { + public function testAddJsSettings() { // Add a file in order to test default settings. $build['#attached']['library'][] = 'core/drupalSettings'; $assets = AttachedAssets::createFromRenderArray($build); @@ -116,7 +116,7 @@ function testAddJsSettings() { /** * Tests adding external CSS and JavaScript files. */ - function testAddExternalFiles() { + public function testAddExternalFiles() { $build['#attached']['library'][] = 'common_test/external'; $assets = AttachedAssets::createFromRenderArray($build); @@ -136,7 +136,7 @@ function testAddExternalFiles() { /** * Tests adding JavaScript files with additional attributes. */ - function testAttributes() { + public function testAttributes() { $build['#attached']['library'][] = 'common_test/js-attributes'; $assets = AttachedAssets::createFromRenderArray($build); @@ -152,7 +152,7 @@ function testAttributes() { /** * Tests that attributes are maintained when JS aggregation is enabled. */ - function testAggregatedAttributes() { + public function testAggregatedAttributes() { $build['#attached']['library'][] = 'common_test/js-attributes'; $assets = AttachedAssets::createFromRenderArray($build); @@ -168,7 +168,7 @@ function testAggregatedAttributes() { /** * Integration test for CSS/JS aggregation. */ - function testAggregation() { + public function testAggregation() { $build['#attached']['library'][] = 'core/drupal.timezone'; $build['#attached']['library'][] = 'core/drupal.vertical-tabs'; $assets = AttachedAssets::createFromRenderArray($build); @@ -186,8 +186,8 @@ function testAggregation() { /** * Tests JavaScript settings. */ - function testSettings() { - $build = array(); + public function testSettings() { + $build = []; $build['#attached']['library'][] = 'core/drupalSettings'; // Nonsensical value to verify if it's possible to override path settings. $build['#attached']['drupalSettings']['path']['pathPrefix'] = 'yarhar'; @@ -226,7 +226,7 @@ function testSettings() { /** * Tests JS assets depending on the 'core/' virtual library. */ - function testHeaderHTML() { + public function testHeaderHTML() { $build['#attached']['library'][] = 'common_test/js-header'; $assets = AttachedAssets::createFromRenderArray($build); @@ -242,7 +242,7 @@ function testHeaderHTML() { /** * Tests that for assets with cache = FALSE, Drupal sets preprocess = FALSE. */ - function testNoCache() { + public function testNoCache() { $build['#attached']['library'][] = 'common_test/no-cache'; $assets = AttachedAssets::createFromRenderArray($build); @@ -255,7 +255,7 @@ function testNoCache() { * * @see \Drupal\Core\Render\Element\HtmlTag::preRenderConditionalComments() */ - function testBrowserConditionalComments() { + public function testBrowserConditionalComments() { $default_query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; $build['#attached']['library'][] = 'common_test/browsers'; @@ -274,7 +274,7 @@ function testBrowserConditionalComments() { /** * Tests JavaScript versioning. */ - function testVersionQueryString() { + public function testVersionQueryString() { $build['#attached']['library'][] = 'core/backbone'; $build['#attached']['library'][] = 'core/domready'; $assets = AttachedAssets::createFromRenderArray($build); @@ -289,7 +289,7 @@ function testVersionQueryString() { /** * Tests JavaScript and CSS asset ordering. */ - function testRenderOrder() { + public function testRenderOrder() { $build['#attached']['library'][] = 'common_test/order'; $assets = AttachedAssets::createFromRenderArray($build); @@ -299,7 +299,8 @@ function testRenderOrder() { "-8_2", "-8_3", "-8_4", - "-5_1", // The external script. + // The external script. + "-5_1", "-3_1", "-3_2", "0_1", @@ -311,12 +312,12 @@ function testRenderOrder() { $js = $this->assetResolver->getJsAssets($assets, FALSE)[1]; $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); - $matches = array(); + $matches = []; if (preg_match_all('/weight_([-0-9]+_[0-9]+)/', $rendered_js, $matches)) { $result = $matches[1]; } else { - $result = array(); + $result = []; } $this->assertIdentical($result, $expected_order_js, 'JavaScript is added in the expected weight order.'); @@ -353,12 +354,12 @@ function testRenderOrder() { $css = $this->assetResolver->getCssAssets($assets, FALSE); $css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css); $rendered_css = $this->renderer->renderPlain($css_render_array); - $matches = array(); + $matches = []; if (preg_match_all('/([a-z]+)_weight_([-0-9]+_[0-9]+)/', $rendered_css, $matches)) { $result = $matches[0]; } else { - $result = array(); + $result = []; } $this->assertIdentical($result, $expected_order_css, 'CSS is added in the expected weight order.'); } @@ -366,7 +367,7 @@ function testRenderOrder() { /** * Tests rendering the JavaScript with a file's weight above jQuery's. */ - function testRenderDifferentWeight() { + public function testRenderDifferentWeight() { // If a library contains assets A and B, and A is listed first, then B can // still make itself appear first by defining a lower weight. $build['#attached']['library'][] = 'core/jquery'; @@ -386,7 +387,7 @@ function testRenderDifferentWeight() { * * @see simpletest_js_alter() */ - function testAlter() { + public function testAlter() { // Add both tableselect.js and simpletest.js. $build['#attached']['library'][] = 'core/drupal.tableselect'; $build['#attached']['library'][] = 'simpletest/drupal.simpletest'; @@ -406,7 +407,7 @@ function testAlter() { * * @see common_test_library_info_alter() */ - function testLibraryAlter() { + public function testLibraryAlter() { // Verify that common_test altered the title of Farbtastic. /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */ $library_discovery = \Drupal::service('library.discovery'); @@ -425,7 +426,7 @@ function testLibraryAlter() { /** * Dynamically defines an asset library and alters it. */ - function testDynamicLibrary() { + public function testDynamicLibrary() { /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */ $library_discovery = \Drupal::service('library.discovery'); // Retrieve a dynamic library definition. @@ -435,12 +436,12 @@ function testDynamicLibrary() { $dynamic_library = $library_discovery->getLibraryByName('common_test', 'dynamic_library'); $this->assertTrue(is_array($dynamic_library)); if ($this->assertTrue(isset($dynamic_library['version']))) { - $this->assertIdentical('1.0', $dynamic_library['version']); + $this->assertSame('1.0', $dynamic_library['version']); } // Make sure the dynamic library definition could be altered. // @see common_test_library_info_alter() if ($this->assertTrue(isset($dynamic_library['dependencies']))) { - $this->assertIdentical(['core/jquery'], $dynamic_library['dependencies']); + $this->assertSame(['core/jquery'], $dynamic_library['dependencies']); } } @@ -449,7 +450,7 @@ function testDynamicLibrary() { * * @see common_test.library.yml */ - function testLibraryNameConflicts() { + public function testLibraryNameConflicts() { /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */ $library_discovery = \Drupal::service('library.discovery'); $farbtastic = $library_discovery->getLibraryByName('common_test', 'jquery.farbtastic'); @@ -459,7 +460,7 @@ function testLibraryNameConflicts() { /** * Tests JavaScript files that have querystrings attached get added right. */ - function testAddJsFileWithQueryString() { + public function testAddJsFileWithQueryString() { $build['#attached']['library'][] = 'common_test/querystring'; $assets = AttachedAssets::createFromRenderArray($build); diff --git a/core/tests/Drupal/KernelTests/Core/Batch/BatchKernelTest.php b/core/tests/Drupal/KernelTests/Core/Batch/BatchKernelTest.php new file mode 100644 index 00000000..62403087 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Batch/BatchKernelTest.php @@ -0,0 +1,40 @@ +root . '/core/includes/batch.inc'; + } + + /** + * Tests _batch_needs_update(). + */ + public function testNeedsUpdate() { + // Before ever being called, the return value should be FALSE. + $this->assertEquals(FALSE, _batch_needs_update()); + + // Set the value to TRUE. + $this->assertEquals(TRUE, _batch_needs_update(TRUE)); + // Check that without a parameter TRUE is returned. + $this->assertEquals(TRUE, _batch_needs_update()); + + // Set the value to FALSE. + $this->assertEquals(FALSE, _batch_needs_update(FALSE)); + $this->assertEquals(FALSE, _batch_needs_update()); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php index 6cdc4b39..66005de4 100644 --- a/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php @@ -2,6 +2,7 @@ namespace Drupal\KernelTests\Core\Bootstrap; +use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\KernelTests\KernelTestBase; /** @@ -17,14 +18,18 @@ class GetFilenameTest extends KernelTestBase { public static $modules = ['system']; /** - * Tests that drupal_get_filename() works when the file is not in database. + * {@inheritdoc} */ - function testDrupalGetFilename() { - // drupal_get_profile() is using obtaining the profile from state if the - // install_state global is not set. - global $install_state; - $install_state['parameters']['profile'] = 'testing'; + public function register(ContainerBuilder $container) { + parent::register($container); + // Use the testing install profile. + $container->setParameter('install_profile', 'testing'); + } + /** + * Tests that drupal_get_filename() works when the file is not in database. + */ + public function testDrupalGetFilename() { // Rebuild system.module.files state data. // @todo Remove as part of https://www.drupal.org/node/2186491 drupal_static_reset('system_rebuild_module_data'); @@ -34,7 +39,7 @@ function testDrupalGetFilename() { $this->assertIdentical(drupal_get_filename('module', 'system'), 'core/modules/system/system.info.yml'); // Retrieving the location of a theme. - \Drupal::service('theme_handler')->install(array('stark')); + \Drupal::service('theme_handler')->install(['stark']); $this->assertIdentical(drupal_get_filename('theme', 'stark'), 'core/themes/stark/stark.info.yml'); // Retrieving the location of a theme engine. @@ -49,7 +54,7 @@ function testDrupalGetFilename() { $non_existing_module = uniqid("", TRUE); // Set a custom error handler so we can ignore the file not found error. - set_error_handler(function($severity, $message, $file, $line) { + set_error_handler(function ($severity, $message, $file, $line) { // Skip error handling if this is a "file not found" error. if (strstr($message, 'is missing from the file system:')) { \Drupal::state()->set('get_filename_test_triggered_error', TRUE); diff --git a/core/tests/Drupal/KernelTests/Core/Bootstrap/ResettableStaticTest.php b/core/tests/Drupal/KernelTests/Core/Bootstrap/ResettableStaticTest.php index 7b90ec11..a2a7a85b 100644 --- a/core/tests/Drupal/KernelTests/Core/Bootstrap/ResettableStaticTest.php +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/ResettableStaticTest.php @@ -17,7 +17,7 @@ class ResettableStaticTest extends KernelTestBase { * Tests that a variable reference returned by drupal_static() gets reset when * drupal_static_reset() is called. */ - function testDrupalStatic() { + public function testDrupalStatic() { $name = __CLASS__ . '_' . __METHOD__; $var = &drupal_static($name, 'foo'); $this->assertEqual($var, 'foo', 'Variable returned by drupal_static() was set to its default.'); diff --git a/core/tests/Drupal/KernelTests/Core/Cache/BackendChainTest.php b/core/tests/Drupal/KernelTests/Core/Cache/BackendChainTest.php index 02821803..72c0de99 100644 --- a/core/tests/Drupal/KernelTests/Core/Cache/BackendChainTest.php +++ b/core/tests/Drupal/KernelTests/Core/Cache/BackendChainTest.php @@ -17,9 +17,9 @@ protected function createCacheBackend($bin) { // We need to create some various backends in the chain. $chain - ->appendBackend(new MemoryBackend('foo')) - ->prependBackend(new MemoryBackend('bar')) - ->appendBackend(new MemoryBackend('baz')); + ->appendBackend(new MemoryBackend()) + ->prependBackend(new MemoryBackend()) + ->appendBackend(new MemoryBackend()); \Drupal::service('cache_tags.invalidator')->addInvalidator($chain); diff --git a/core/tests/Drupal/KernelTests/Core/Cache/ChainedFastBackendTest.php b/core/tests/Drupal/KernelTests/Core/Cache/ChainedFastBackendTest.php index 3021b041..a93b674d 100644 --- a/core/tests/Drupal/KernelTests/Core/Cache/ChainedFastBackendTest.php +++ b/core/tests/Drupal/KernelTests/Core/Cache/ChainedFastBackendTest.php @@ -20,7 +20,7 @@ class ChainedFastBackendTest extends GenericCacheBackendUnitTestBase { * A new ChainedFastBackend object. */ protected function createCacheBackend($bin) { - $consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin); + $consistent_backend = new DatabaseBackend(\Drupal::service('database'), \Drupal::service('cache_tags.invalidator.checksum'), $bin, 100); $fast_backend = new PhpBackend($bin, \Drupal::service('cache_tags.invalidator.checksum')); $backend = new ChainedFastBackend($consistent_backend, $fast_backend, $bin); // Explicitly register the cache bin as it can not work through the diff --git a/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTagTest.php b/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTagTest.php index 484ee9cc..0fefc390 100644 --- a/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTagTest.php +++ b/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTagTest.php @@ -19,7 +19,7 @@ class DatabaseBackendTagTest extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * {@inheritdoc} @@ -30,21 +30,21 @@ public function register(ContainerBuilder $container) { $container ->register('cache_factory', 'Drupal\Core\Cache\CacheFactory') ->addArgument(new Reference('settings')) - ->addMethodCall('setContainer', array(new Reference('service_container'))); + ->addMethodCall('setContainer', [new Reference('service_container')]); } public function testTagInvalidations() { // Create cache entry in multiple bins. - $tags = array('test_tag:1', 'test_tag:2', 'test_tag:3'); - $bins = array('data', 'bootstrap', 'render'); + $tags = ['test_tag:1', 'test_tag:2', 'test_tag:3']; + $bins = ['data', 'bootstrap', 'render']; foreach ($bins as $bin) { $bin = \Drupal::cache($bin); $bin->set('test', 'value', Cache::PERMANENT, $tags); $this->assertTrue($bin->get('test'), 'Cache item was set in bin.'); } - $invalidations_before = intval(db_select('cachetags')->fields('cachetags', array('invalidations'))->condition('tag', 'test_tag:2')->execute()->fetchField()); - Cache::invalidateTags(array('test_tag:2')); + $invalidations_before = intval(db_select('cachetags')->fields('cachetags', ['invalidations'])->condition('tag', 'test_tag:2')->execute()->fetchField()); + Cache::invalidateTags(['test_tag:2']); // Test that cache entry has been invalidated in multiple bins. foreach ($bins as $bin) { @@ -53,7 +53,7 @@ public function testTagInvalidations() { } // Test that only one tag invalidation has occurred. - $invalidations_after = intval(db_select('cachetags')->fields('cachetags', array('invalidations'))->condition('tag', 'test_tag:2')->execute()->fetchField()); + $invalidations_after = intval(db_select('cachetags')->fields('cachetags', ['invalidations'])->condition('tag', 'test_tag:2')->execute()->fetchField()); $this->assertEqual($invalidations_after, $invalidations_before + 1, 'Only one addition cache tag invalidation has occurred after invalidating a tag used in multiple bins.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTest.php b/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTest.php index fd1c9423..358b9253 100644 --- a/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTest.php +++ b/core/tests/Drupal/KernelTests/Core/Cache/DatabaseBackendTest.php @@ -11,12 +11,19 @@ */ class DatabaseBackendTest extends GenericCacheBackendUnitTestBase { + /** + * The max rows to use for test bins. + * + * @var int + */ + protected static $maxRows = 100; + /** * Modules to enable. * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * Creates a new instance of DatabaseBackend. @@ -25,7 +32,7 @@ class DatabaseBackendTest extends GenericCacheBackendUnitTestBase { * A new DatabaseBackend object. */ protected function createCacheBackend($bin) { - return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin); + return new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), $bin, static::$maxRows); } /** @@ -40,12 +47,60 @@ public function testSetGet() { $cid_long = str_repeat('愛€', 500); $cached_value_long = $this->randomMachineName(); $backend->set($cid_long, $cached_value_long); - $this->assertIdentical($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id."); + $this->assertSame($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id."); $cid_short = 'æ„›1€'; $cached_value_short = $this->randomMachineName(); $backend->set($cid_short, $cached_value_short); - $this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id."); + $this->assertSame($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id."); + } + + /** + * Tests the row count limiting of cache bin database tables. + */ + public function testGarbageCollection() { + $backend = $this->getCacheBackend(); + $max_rows = static::$maxRows; + + $this->assertSame(0, (int) $this->getNumRows()); + + // Fill to just the limit. + for ($i = 0; $i < $max_rows; $i++) { + // Ensure that each cache item created happens in a different millisecond, + // by waiting 1 ms (1000 microseconds). The garbage collection might + // otherwise keep less than exactly 100 records (which is acceptable for + // real-world cases, but not for this test). + usleep(1000); + $backend->set("test$i", $i); + } + $this->assertSame($max_rows, $this->getNumRows()); + + // Garbage collection has no effect. + $backend->garbageCollection(); + $this->assertSame($max_rows, $this->getNumRows()); + + // Go one row beyond the limit. + $backend->set('test' . ($max_rows + 1), $max_rows + 1); + $this->assertSame($max_rows + 1, $this->getNumRows()); + + // Garbage collection removes one row: the oldest. + $backend->garbageCollection(); + $this->assertSame($max_rows, $this->getNumRows()); + $this->assertFalse($backend->get('test0')); + } + + /** + * Gets the number of rows in the test cache bin database table. + * + * @return int + * The number of rows in the test cache bin database table. + */ + protected function getNumRows() { + $table = 'cache_' . $this->testBin; + $connection = $this->container->get('database'); + $query = $connection->select($table); + $query->addExpression('COUNT(cid)', 'cid'); + return (int) $query->execute()->fetchField(); } } diff --git a/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php b/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php index d5f3e957..ce5b28c9 100644 --- a/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php @@ -66,7 +66,7 @@ protected function getTestBin() { * @return \Drupal\Core\Cache\CacheBackendInterface * Cache backend to test. */ - protected abstract function createCacheBackend($bin); + abstract protected function createCacheBackend($bin); /** * Allows specific implementation to change the environment before a test run. @@ -102,7 +102,7 @@ protected function getCacheBackend($bin = NULL) { } protected function setUp() { - $this->cachebackends = array(); + $this->cachebackends = []; $this->defaultValue = $this->randomMachineName(10); parent::setUp(); @@ -130,22 +130,22 @@ protected function tearDown() { public function testSetGet() { $backend = $this->getCacheBackend(); - $this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1."); - $with_backslash = array('foo' => '\Drupal\foo\Bar'); + $this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1."); + $with_backslash = ['foo' => '\Drupal\foo\Bar']; $backend->set('test1', $with_backslash); $cached = $backend->get('test1'); $this->assert(is_object($cached), "Backend returned an object for cache id test1."); - $this->assertIdentical($with_backslash, $cached->data); + $this->assertSame($with_backslash, $cached->data); $this->assertTrue($cached->valid, 'Item is marked as valid.'); // We need to round because microtime may be rounded up in the backend. $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.'); - $this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2."); - $backend->set('test2', array('value' => 3), REQUEST_TIME + 3); + $this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2."); + $backend->set('test2', ['value' => 3], REQUEST_TIME + 3); $cached = $backend->get('test2'); $this->assert(is_object($cached), "Backend returned an object for cache id test2."); - $this->assertIdentical(array('value' => 3), $cached->data); + $this->assertSame(['value' => 3], $cached->data); $this->assertTrue($cached->valid, 'Item is marked as valid.'); $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, REQUEST_TIME + 3, 'Expire time is correct.'); @@ -158,31 +158,31 @@ public function testSetGet() { $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, REQUEST_TIME - 3, 'Expire time is correct.'); - $this->assertIdentical(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4."); - $with_eof = array('foo' => "\nEOF\ndata"); + $this->assertSame(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4."); + $with_eof = ['foo' => "\nEOF\ndata"]; $backend->set('test4', $with_eof); $cached = $backend->get('test4'); $this->assert(is_object($cached), "Backend returned an object for cache id test4."); - $this->assertIdentical($with_eof, $cached->data); + $this->assertSame($with_eof, $cached->data); $this->assertTrue($cached->valid, 'Item is marked as valid.'); $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.'); - $this->assertIdentical(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5."); - $with_eof_and_semicolon = array('foo' => "\nEOF;\ndata"); + $this->assertSame(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5."); + $with_eof_and_semicolon = ['foo' => "\nEOF;\ndata"]; $backend->set('test5', $with_eof_and_semicolon); $cached = $backend->get('test5'); $this->assert(is_object($cached), "Backend returned an object for cache id test5."); - $this->assertIdentical($with_eof_and_semicolon, $cached->data); + $this->assertSame($with_eof_and_semicolon, $cached->data); $this->assertTrue($cached->valid, 'Item is marked as valid.'); $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.'); - $with_variable = array('foo' => '$bar'); + $with_variable = ['foo' => '$bar']; $backend->set('test6', $with_variable); $cached = $backend->get('test6'); $this->assert(is_object($cached), "Backend returned an object for cache id test6."); - $this->assertIdentical($with_variable, $cached->data); + $this->assertSame($with_variable, $cached->data); // Make sure that a cached object is not affected by changing the original. $data = new \stdClass(); @@ -229,26 +229,26 @@ public function testSetGet() { public function testDelete() { $backend = $this->getCacheBackend(); - $this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1."); + $this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1."); $backend->set('test1', 7); $this->assert(is_object($backend->get('test1')), "Backend returned an object for cache id test1."); - $this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2."); + $this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2."); $backend->set('test2', 3); $this->assert(is_object($backend->get('test2')), "Backend returned an object for cache id %cid."); $backend->delete('test1'); - $this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1 after deletion."); + $this->assertSame(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1 after deletion."); $this->assert(is_object($backend->get('test2')), "Backend still has an object for cache id test2."); $backend->delete('test2'); - $this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion."); + $this->assertSame(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion."); $long_cid = str_repeat('a', 300); $backend->set($long_cid, 'test'); $backend->delete($long_cid); - $this->assertIdentical(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion."); + $this->assertSame(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion."); } /** @@ -257,14 +257,14 @@ public function testDelete() { public function testValueTypeIsKept() { $backend = $this->getCacheBackend(); - $variables = array( + $variables = [ 'test1' => 1, 'test2' => '0', 'test3' => '', 'test4' => 12.64, 'test5' => FALSE, - 'test6' => array(1, 2, 3), - ); + 'test6' => [1, 2, 3], + ]; // Create cache entries. foreach ($variables as $cid => $data) { @@ -275,7 +275,7 @@ public function testValueTypeIsKept() { foreach ($variables as $cid => $value) { $object = $backend->get($cid); $this->assert(is_object($object), sprintf("Backend returned an object for cache id %s.", $cid)); - $this->assertIdentical($value, $object->data, sprintf("Data of cached id %s kept is identical in type and value", $cid)); + $this->assertSame($value, $object->data, sprintf("Data of cached id %s kept is identical in type and value", $cid)); } } @@ -297,14 +297,16 @@ public function testGetMultiple() { $backend->set($long_cid, 300); // Mismatch order for harder testing. - $reference = array( + $reference = [ 'test3', 'test7', - 'test21', // Cid does not exist. + // Cid does not exist. + 'test21', 'test6', - 'test19', // Cid does not exist until added before second getMultiple(). + // Cid does not exist until added before second getMultiple(). + 'test19', 'test2', - ); + ]; $cids = $reference; $ret = $backend->getMultiple($cids); @@ -364,7 +366,7 @@ public function testGetMultiple() { $this->assertFalse(in_array('test19', $cids), "Added cache id test19 is not in cids array."); // Test with a long $cid and non-numeric array key. - $cids = array('key:key' => $long_cid); + $cids = ['key:key' => $long_cid]; $return = $backend->getMultiple($cids); $this->assertEqual(300, $return[$long_cid]->data); $this->assertTrue(empty($cids)); @@ -380,13 +382,13 @@ public function testSetMultiple() { // Set multiple testing keys. $backend->set('cid_1', 'Some other value'); - $items = array( - 'cid_1' => array('data' => 1), - 'cid_2' => array('data' => 2), - 'cid_3' => array('data' => array(1, 2)), - 'cid_4' => array('data' => 1, 'expire' => $future_expiration), - 'cid_5' => array('data' => 1, 'tags' => array('test:a', 'test:b')), - ); + $items = [ + 'cid_1' => ['data' => 1], + 'cid_2' => ['data' => 2], + 'cid_3' => ['data' => [1, 2]], + 'cid_4' => ['data' => 1, 'expire' => $future_expiration], + 'cid_5' => ['data' => 1, 'tags' => ['test:a', 'test:b']], + ]; $backend->setMultiple($items); $cids = array_keys($items); $cached = $backend->getMultiple($cids); @@ -411,9 +413,9 @@ public function testSetMultiple() { // assertion. try { $items = [ - 'exception_test_1' => array('data' => 1, 'tags' => []), - 'exception_test_2' => array('data' => 2, 'tags' => ['valid']), - 'exception_test_3' => array('data' => 3, 'tags' => ['node' => [3, 5, 7]]), + 'exception_test_1' => ['data' => 1, 'tags' => []], + 'exception_test_2' => ['data' => 2, 'tags' => ['valid']], + 'exception_test_3' => ['data' => 3, 'tags' => ['node' => [3, 5, 7]]], ]; $backend->setMultiple($items); $this->fail('::setMultiple() was called with invalid cache tags, runtime assertion did not fail.'); @@ -440,20 +442,23 @@ public function testDeleteMultiple() { $backend->set('test7', 17); $backend->delete('test1'); - $backend->delete('test23'); // Nonexistent key should not cause an error. - $backend->deleteMultiple(array( + // Nonexistent key should not cause an error. + $backend->delete('test23'); + $backend->deleteMultiple([ 'test3', 'test5', 'test7', - 'test19', // Nonexistent key should not cause an error. - 'test21', // Nonexistent key should not cause an error. - )); + // Nonexistent key should not cause an error. + 'test19', + // Nonexistent key should not cause an error. + 'test21', + ]); // Test if expected keys have been deleted. - $this->assertIdentical(FALSE, $backend->get('test1'), "Cache id test1 deleted."); - $this->assertIdentical(FALSE, $backend->get('test3'), "Cache id test3 deleted."); - $this->assertIdentical(FALSE, $backend->get('test5'), "Cache id test5 deleted."); - $this->assertIdentical(FALSE, $backend->get('test7'), "Cache id test7 deleted."); + $this->assertSame(FALSE, $backend->get('test1'), "Cache id test1 deleted."); + $this->assertSame(FALSE, $backend->get('test3'), "Cache id test3 deleted."); + $this->assertSame(FALSE, $backend->get('test5'), "Cache id test5 deleted."); + $this->assertSame(FALSE, $backend->get('test7'), "Cache id test7 deleted."); // Test if expected keys exist. $this->assertNotIdentical(FALSE, $backend->get('test2'), "Cache id test2 exists."); @@ -461,11 +466,11 @@ public function testDeleteMultiple() { $this->assertNotIdentical(FALSE, $backend->get('test6'), "Cache id test6 exists."); // Test if that expected keys do not exist. - $this->assertIdentical(FALSE, $backend->get('test19'), "Cache id test19 does not exist."); - $this->assertIdentical(FALSE, $backend->get('test21'), "Cache id test21 does not exist."); + $this->assertSame(FALSE, $backend->get('test19'), "Cache id test19 does not exist."); + $this->assertSame(FALSE, $backend->get('test21'), "Cache id test21 does not exist."); // Calling deleteMultiple() with an empty array should not cause an error. - $this->assertFalse($backend->deleteMultiple(array())); + $this->assertFalse($backend->deleteMultiple([])); } /** @@ -491,21 +496,21 @@ public function testDeleteAll() { * Test Drupal\Core\Cache\CacheBackendInterface::invalidate() and * Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple(). */ - function testInvalidate() { + public function testInvalidate() { $backend = $this->getCacheBackend(); $backend->set('test1', 1); $backend->set('test2', 2); $backend->set('test3', 2); $backend->set('test4', 2); - $reference = array('test1', 'test2', 'test3', 'test4'); + $reference = ['test1', 'test2', 'test3', 'test4']; $cids = $reference; $ret = $backend->getMultiple($cids); $this->assertEqual(count($ret), 4, 'Four items returned.'); $backend->invalidate('test1'); - $backend->invalidateMultiple(array('test2', 'test3')); + $backend->invalidateMultiple(['test2', 'test3']); $cids = $reference; $ret = $backend->getMultiple($cids); @@ -517,55 +522,55 @@ function testInvalidate() { // Calling invalidateMultiple() with an empty array should not cause an // error. - $this->assertFalse($backend->invalidateMultiple(array())); + $this->assertFalse($backend->invalidateMultiple([])); } /** * Tests Drupal\Core\Cache\CacheBackendInterface::invalidateTags(). */ - function testInvalidateTags() { + public function testInvalidateTags() { $backend = $this->getCacheBackend(); // Create two cache entries with the same tag and tag value. - $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, array('test_tag:2')); - $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, array('test_tag:2')); + $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']); + $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Two cache items were created.'); // Invalidate test_tag of value 1. This should invalidate both entries. - Cache::invalidateTags(array('test_tag:2')); + Cache::invalidateTags(['test_tag:2']); $this->assertFalse($backend->get('test_cid_invalidate1') || $backend->get('test_cid_invalidate2'), 'Two cache items invalidated after invalidating a cache tag.'); $this->assertTrue($backend->get('test_cid_invalidate1', TRUE) && $backend->get('test_cid_invalidate2', TRUE), 'Cache items not deleted after invalidating a cache tag.'); // Create two cache entries with the same tag and an array tag value. - $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, array('test_tag:1')); - $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, array('test_tag:1')); + $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']); + $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Two cache items were created.'); // Invalidate test_tag of value 1. This should invalidate both entries. - Cache::invalidateTags(array('test_tag:1')); + Cache::invalidateTags(['test_tag:1']); $this->assertFalse($backend->get('test_cid_invalidate1') || $backend->get('test_cid_invalidate2'), 'Two caches removed after invalidating a cache tag.'); $this->assertTrue($backend->get('test_cid_invalidate1', TRUE) && $backend->get('test_cid_invalidate2', TRUE), 'Cache items not deleted after invalidating a cache tag.'); // Create three cache entries with a mix of tags and tag values. - $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, array('test_tag:1')); - $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, array('test_tag:2')); - $backend->set('test_cid_invalidate3', $this->defaultValue, Cache::PERMANENT, array('test_tag_foo:3')); + $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']); + $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']); + $backend->set('test_cid_invalidate3', $this->defaultValue, Cache::PERMANENT, ['test_tag_foo:3']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2') && $backend->get('test_cid_invalidate3'), 'Three cached items were created.'); - Cache::invalidateTags(array('test_tag_foo:3')); + Cache::invalidateTags(['test_tag_foo:3']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Cache items not matching the tag were not invalidated.'); $this->assertFalse($backend->get('test_cid_invalidated3'), 'Cached item matching the tag was removed.'); // Create cache entry in multiple bins. Two cache entries // (test_cid_invalidate1 and test_cid_invalidate2) still exist from previous // tests. - $tags = array('test_tag:1', 'test_tag:2', 'test_tag:3'); - $bins = array('path', 'bootstrap', 'page'); + $tags = ['test_tag:1', 'test_tag:2', 'test_tag:3']; + $bins = ['path', 'bootstrap', 'page']; foreach ($bins as $bin) { $this->getCacheBackend($bin)->set('test', $this->defaultValue, Cache::PERMANENT, $tags); $this->assertTrue($this->getCacheBackend($bin)->get('test'), 'Cache item was set in bin.'); } - Cache::invalidateTags(array('test_tag:2')); + Cache::invalidateTags(['test_tag:2']); // Test that the cache entry has been invalidated in multiple bins. foreach ($bins as $bin) { diff --git a/core/tests/Drupal/KernelTests/Core/Cache/MemoryBackendTest.php b/core/tests/Drupal/KernelTests/Core/Cache/MemoryBackendTest.php index c1fb9f74..4518532c 100644 --- a/core/tests/Drupal/KernelTests/Core/Cache/MemoryBackendTest.php +++ b/core/tests/Drupal/KernelTests/Core/Cache/MemoryBackendTest.php @@ -18,7 +18,7 @@ class MemoryBackendTest extends GenericCacheBackendUnitTestBase { * A new MemoryBackend object. */ protected function createCacheBackend($bin) { - $backend = new MemoryBackend($bin); + $backend = new MemoryBackend(); \Drupal::service('cache_tags.invalidator')->addInvalidator($backend); return $backend; } diff --git a/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php b/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php index 8129410e..17b6ae41 100644 --- a/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php +++ b/core/tests/Drupal/KernelTests/Core/Command/DbDumpTest.php @@ -70,7 +70,8 @@ public function register(ContainerBuilder $container) { parent::register($container); $container->register('cache_factory', 'Drupal\Core\Cache\DatabaseBackendFactory') ->addArgument(new Reference('database')) - ->addArgument(new Reference('cache_tags.invalidator.checksum')); + ->addArgument(new Reference('cache_tags.invalidator.checksum')) + ->addArgument(new Reference('settings')); } /** @@ -205,8 +206,8 @@ public function testScriptLoad() { $this->assertTrue(Database::getConnection() ->schema() ->tableExists($table), SafeMarkup::format('Table @table created by the database script.', ['@table' => $table])); - $this->assertIdentical($this->originalTableSchemas[$table], $this->getTableSchema($table), SafeMarkup::format('The schema for @table was properly restored.', ['@table' => $table])); - $this->assertIdentical($this->originalTableIndexes[$table], $this->getTableIndexes($table), SafeMarkup::format('The indexes for @table were properly restored.', ['@table' => $table])); + $this->assertSame($this->originalTableSchemas[$table], $this->getTableSchema($table), SafeMarkup::format('The schema for @table was properly restored.', ['@table' => $table])); + $this->assertSame($this->originalTableIndexes[$table], $this->getTableIndexes($table), SafeMarkup::format('The indexes for @table were properly restored.', ['@table' => $table])); } // Ensure the test config has been replaced. diff --git a/core/tests/Drupal/KernelTests/Core/Common/SizeTest.php b/core/tests/Drupal/KernelTests/Core/Common/SizeTest.php index 2bcee753..1ff31b95 100644 --- a/core/tests/Drupal/KernelTests/Core/Common/SizeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Common/SizeTest.php @@ -18,7 +18,7 @@ class SizeTest extends KernelTestBase { protected function setUp() { parent::setUp(); $kb = Bytes::KILOBYTE; - $this->exactTestCases = array( + $this->exactTestCases = [ '1 byte' => 1, '1 KB' => $kb, '1 MB' => $kb * $kb, @@ -28,21 +28,25 @@ protected function setUp() { '1 EB' => $kb * $kb * $kb * $kb * $kb * $kb, '1 ZB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb, '1 YB' => $kb * $kb * $kb * $kb * $kb * $kb * $kb * $kb, - ); - $this->roundedTestCases = array( + ]; + $this->roundedTestCases = [ '2 bytes' => 2, - '1 MB' => ($kb * $kb) - 1, // rounded to 1 MB (not 1000 or 1024 kilobyte!) - round(3623651 / ($this->exactTestCases['1 MB']), 2) . ' MB' => 3623651, // megabytes - round(67234178751368124 / ($this->exactTestCases['1 PB']), 2) . ' PB' => 67234178751368124, // petabytes - round(235346823821125814962843827 / ($this->exactTestCases['1 YB']), 2) . ' YB' => 235346823821125814962843827, // yottabytes - ); + // Rounded to 1 MB (not 1000 or 1024 kilobyte!). + '1 MB' => ($kb * $kb) - 1, + // Megabytes. + round(3623651 / ($this->exactTestCases['1 MB']), 2) . ' MB' => 3623651, + // Petabytes. + round(67234178751368124 / ($this->exactTestCases['1 PB']), 2) . ' PB' => 67234178751368124, + // Yottabytes. + round(235346823821125814962843827 / ($this->exactTestCases['1 YB']), 2) . ' YB' => 235346823821125814962843827, + ]; } /** * Checks that format_size() returns the expected string. */ - function testCommonFormatSize() { - foreach (array($this->exactTestCases, $this->roundedTestCases) as $test_cases) { + public function testCommonFormatSize() { + foreach ([$this->exactTestCases, $this->roundedTestCases] as $test_cases) { foreach ($test_cases as $expected => $input) { $this->assertEqual( ($result = format_size($input, NULL)), @@ -56,7 +60,7 @@ function testCommonFormatSize() { /** * Cross-tests Bytes::toInt() and format_size(). */ - function testCommonParseSizeFormatSize() { + public function testCommonParseSizeFormatSize() { foreach ($this->exactTestCases as $size) { $this->assertEqual( $size, diff --git a/core/tests/Drupal/KernelTests/Core/Common/XssUnitTest.php b/core/tests/Drupal/KernelTests/Core/Common/XssUnitTest.php index 7c68ed45..23754879 100644 --- a/core/tests/Drupal/KernelTests/Core/Common/XssUnitTest.php +++ b/core/tests/Drupal/KernelTests/Core/Common/XssUnitTest.php @@ -18,29 +18,29 @@ class XssUnitTest extends KernelTestBase { * * @var array */ - public static $modules = array('filter', 'system'); + public static $modules = ['filter', 'system']; protected function setUp() { parent::setUp(); - $this->installConfig(array('system')); + $this->installConfig(['system']); } /** * Tests t() functionality. */ - function testT() { + public function testT() { $text = t('Simple text'); $this->assertEqual($text, 'Simple text', 't leaves simple text alone.'); - $text = t('Escaped text: @value', array('@value' => ' & < > " \' ', - ); + ]; // Encode and write, and reload and decode the configuration data. $filestorage = new FileStorage(config_get_config_directory(CONFIG_SYNC_DIRECTORY)); @@ -210,22 +210,22 @@ function testSerialization() { $config_parsed = $filestorage->read($name); $key = 'numeric keys'; - $this->assertIdentical($config_data[$key], $config_parsed[$key]); + $this->assertSame($config_data[$key], $config_parsed[$key]); $key = 'nested keys'; - $this->assertIdentical($config_data[$key], $config_parsed[$key]); + $this->assertSame($config_data[$key], $config_parsed[$key]); $key = 'HTML'; - $this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); + $this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); $key = 'UTF-8'; - $this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); + $this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); $key = 'ΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΣὨ'; - $this->assertIdentical($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); + $this->assertSame($config_data['nested keys'][$key], $config_parsed['nested keys'][$key]); $key = 'invalid xml'; - $this->assertIdentical($config_data[$key], $config_parsed[$key]); + $this->assertSame($config_data[$key], $config_parsed[$key]); } } diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php index 570ca4c1..c69f9feb 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php @@ -33,7 +33,7 @@ protected function setUp() { parent::setUp(); $this->installEntitySchema('node'); - $this->installConfig(array('field', 'node')); + $this->installConfig(['field', 'node']); $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync')); @@ -92,7 +92,7 @@ public function testRecreateEntity() { $this->assertEqual(5, count($creates), 'There are 5 configuration items to create.'); $this->assertEqual(5, count($deletes), 'There are 5 configuration items to delete.'); $this->assertEqual(0, count($this->configImporter->getUnprocessedConfiguration('update')), 'There are no configuration items to update.'); - $this->assertIdentical($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.'); + $this->assertSame($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.'); $this->configImporter->import(); diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php index 48b9c467..cbb2e958 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php @@ -40,7 +40,7 @@ protected function setUp() { $this->installEntitySchema('user'); $this->installEntitySchema('node'); - $this->installConfig(array('field')); + $this->installConfig(['field']); // Set up the ConfigImporter object for testing. $storage_comparer = new StorageComparer( @@ -67,10 +67,10 @@ protected function setUp() { public function testRenameValidation() { // Create a test entity. $test_entity_id = $this->randomMachineName(); - $test_entity = entity_create('config_test', array( + $test_entity = entity_create('config_test', [ 'id' => $test_entity_id, 'label' => $this->randomMachineName(), - )); + ]); $test_entity->save(); $uuid = $test_entity->uuid(); @@ -91,11 +91,11 @@ public function testRenameValidation() { // Confirm that the staged configuration is detected as a rename since the // UUIDs match. $this->configImporter->reset(); - $expected = array( + $expected = [ 'node.type.' . $content_type->id() . '::config_test.dynamic.' . $test_entity_id, - ); + ]; $renames = $this->configImporter->getUnprocessedConfiguration('rename'); - $this->assertIdentical($expected, $renames); + $this->assertSame($expected, $renames); // Try to import the configuration. We expect an exception to be thrown // because the staged entity is of a different type. @@ -105,9 +105,9 @@ public function testRenameValidation() { } catch (ConfigImporterException $e) { $this->pass('Expected ConfigImporterException thrown when a renamed configuration entity does not match the existing entity type.'); - $expected = array( - SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', array('@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id)) - ); + $expected = [ + SafeMarkup::format('Entity type mismatch on rename. @old_type not equal to @new_type for existing configuration @old_name and staged configuration @new_name.', ['@old_type' => 'node_type', '@new_type' => 'config_test', '@old_name' => 'node.type.' . $content_type->id(), '@new_name' => 'config_test.dynamic.' . $test_entity_id]) + ]; $this->assertEqual($expected, $this->configImporter->getErrors()); } } @@ -134,11 +134,11 @@ public function testRenameSimpleConfigValidation() { // Confirm that the staged configuration is detected as a rename since the // UUIDs match. $this->configImporter->reset(); - $expected = array( + $expected = [ 'config_test.old::config_test.new' - ); + ]; $renames = $this->configImporter->getUnprocessedConfiguration('rename'); - $this->assertIdentical($expected, $renames); + $this->assertSame($expected, $renames); // Try to import the configuration. We expect an exception to be thrown // because the rename is for simple configuration. @@ -148,9 +148,9 @@ public function testRenameSimpleConfigValidation() { } catch (ConfigImporterException $e) { $this->pass('Expected ConfigImporterException thrown when simple configuration is renamed.'); - $expected = array( - SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', array('@old_name' => 'config_test.old', '@new_name' => 'config_test.new')) - ); + $expected = [ + SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', ['@old_name' => 'config_test.old', '@new_name' => 'config_test.new']) + ]; $this->assertEqual($expected, $this->configImporter->getErrors()); } } diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php index 55f64814..59f9cb2e 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php @@ -26,14 +26,14 @@ class ConfigImporterMissingContentTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'entity_test', 'config_test', 'config_import_test'); + public static $modules = ['system', 'user', 'entity_test', 'config_test', 'config_import_test']; protected function setUp() { parent::setUp(); $this->installSchema('system', 'sequences'); $this->installEntitySchema('entity_test'); $this->installEntitySchema('user'); - $this->installConfig(array('config_test')); + $this->installConfig(['config_test']); // Installing config_test's default configuration pollutes the global // variable being used for recording hook invocations by this test already, // so it has to be cleared out manually. @@ -66,16 +66,16 @@ protected function setUp() { * @see \Drupal\Core\Config\ConfigImporter::processMissingContent() * @see \Drupal\config_import_test\EventSubscriber */ - function testMissingContent() { + public function testMissingContent() { \Drupal::state()->set('config_import_test.config_import_missing_content', TRUE); // Update a configuration entity in the sync directory to have a dependency // on two content entities that do not exist. $storage = $this->container->get('config.storage'); $sync = $this->container->get('config.storage.sync'); - $entity_one = EntityTest::create(array('name' => 'one')); - $entity_two = EntityTest::create(array('name' => 'two')); - $entity_three = EntityTest::create(array('name' => 'three')); + $entity_one = EntityTest::create(['name' => 'one']); + $entity_two = EntityTest::create(['name' => 'two']); + $entity_three = EntityTest::create(['name' => 'three']); $dynamic_name = 'config_test.dynamic.dotted.default'; $original_dynamic_data = $storage->read($dynamic_name); // Entity one will be resolved by diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php index 945e994e..9d3989cf 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php @@ -28,12 +28,12 @@ class ConfigImporterTest extends KernelTestBase { * * @var array */ - public static $modules = array('config_test', 'system', 'config_import_test'); + public static $modules = ['config_test', 'system', 'config_import_test']; protected function setUp() { parent::setUp(); - $this->installConfig(array('config_test')); + $this->installConfig(['config_test']); // Installing config_test's default configuration pollutes the global // variable being used for recording hook invocations by this test already, // so it has to be cleared out manually. @@ -63,7 +63,7 @@ protected function setUp() { /** * Tests omission of module APIs for bare configuration operations. */ - function testNoImport() { + public function testNoImport() { $dynamic_name = 'config_test.dynamic.dotted.default'; // Verify the default configuration values exist. @@ -78,7 +78,7 @@ function testNoImport() { * Tests that trying to import from an empty sync configuration directory * fails. */ - function testEmptyImportFails() { + public function testEmptyImportFails() { try { $this->container->get('config.storage.sync')->deleteAll(); $this->configImporter->reset()->import(); @@ -92,7 +92,7 @@ function testEmptyImportFails() { /** * Tests verification of site UUID before importing configuration. */ - function testSiteUuidValidate() { + public function testSiteUuidValidate() { $sync = \Drupal::service('config.storage.sync'); // Create updated configuration object. $config_data = $this->config('system.site')->get(); @@ -106,7 +106,7 @@ function testSiteUuidValidate() { catch (ConfigImporterException $e) { $this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.'); $error_log = $this->configImporter->getErrors(); - $expected = array('Site UUID in source storage does not match the target storage.'); + $expected = ['Site UUID in source storage does not match the target storage.']; $this->assertEqual($expected, $error_log); } } @@ -114,7 +114,7 @@ function testSiteUuidValidate() { /** * Tests deletion of configuration during import. */ - function testDeleted() { + public function testDeleted() { $dynamic_name = 'config_test.dynamic.dotted.default'; $storage = $this->container->get('config.storage'); $sync = $this->container->get('config.storage.sync'); @@ -151,7 +151,7 @@ function testDeleted() { /** * Tests creation of configuration during import. */ - function testNew() { + public function testNew() { $dynamic_name = 'config_test.dynamic.new'; $storage = $this->container->get('config.storage'); $sync = $this->container->get('config.storage.sync'); @@ -160,11 +160,11 @@ function testNew() { $this->assertIdentical($storage->exists($dynamic_name), FALSE, $dynamic_name . ' not found.'); // Create new config entity. - $original_dynamic_data = array( + $original_dynamic_data = [ 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(), 'status' => TRUE, - 'dependencies' => array(), + 'dependencies' => [], 'id' => 'new', 'label' => 'New', 'weight' => 0, @@ -172,7 +172,7 @@ function testNew() { 'size' => '', 'size_value' => '', 'protected_property' => '', - ); + ]; $sync->write($dynamic_name, $original_dynamic_data); $this->assertIdentical($sync->exists($dynamic_name), TRUE, $dynamic_name . ' found.'); @@ -205,29 +205,29 @@ function testNew() { /** * Tests that secondary writes are overwritten. */ - function testSecondaryWritePrimaryFirst() { + public function testSecondaryWritePrimaryFirst() { $name_primary = 'config_test.dynamic.primary'; $name_secondary = 'config_test.dynamic.secondary'; $sync = $this->container->get('config.storage.sync'); $uuid = $this->container->get('uuid'); - $values_primary = array( + $values_primary = [ 'id' => 'primary', 'label' => 'Primary', 'weight' => 0, 'uuid' => $uuid->generate(), - ); + ]; $sync->write($name_primary, $values_primary); - $values_secondary = array( + $values_secondary = [ 'id' => 'secondary', 'label' => 'Secondary Sync', 'weight' => 0, 'uuid' => $uuid->generate(), // Add a dependency on primary, to ensure that is synced first. - 'dependencies' => array( - 'config' => array($name_primary), - ) - ); + 'dependencies' => [ + 'config' => [$name_primary], + ] + ]; $sync->write($name_secondary, $values_secondary); // Import. @@ -245,35 +245,35 @@ function testSecondaryWritePrimaryFirst() { $logs = $this->configImporter->getErrors(); $this->assertEqual(count($logs), 1); - $this->assertEqual($logs[0], SafeMarkup::format('Deleted and replaced configuration entity "@name"', array('@name' => $name_secondary))); + $this->assertEqual($logs[0], SafeMarkup::format('Deleted and replaced configuration entity "@name"', ['@name' => $name_secondary])); } /** * Tests that secondary writes are overwritten. */ - function testSecondaryWriteSecondaryFirst() { + public function testSecondaryWriteSecondaryFirst() { $name_primary = 'config_test.dynamic.primary'; $name_secondary = 'config_test.dynamic.secondary'; $sync = $this->container->get('config.storage.sync'); $uuid = $this->container->get('uuid'); - $values_primary = array( + $values_primary = [ 'id' => 'primary', 'label' => 'Primary', 'weight' => 0, 'uuid' => $uuid->generate(), // Add a dependency on secondary, so that is synced first. - 'dependencies' => array( - 'config' => array($name_secondary), - ) - ); + 'dependencies' => [ + 'config' => [$name_secondary], + ] + ]; $sync->write($name_primary, $values_primary); - $values_secondary = array( + $values_secondary = [ 'id' => 'secondary', 'label' => 'Secondary Sync', 'weight' => 0, 'uuid' => $uuid->generate(), - ); + ]; $sync->write($name_secondary, $values_secondary); // Import. @@ -297,7 +297,7 @@ function testSecondaryWriteSecondaryFirst() { /** * Tests that secondary updates for deleted files work as expected. */ - function testSecondaryUpdateDeletedDeleterFirst() { + public function testSecondaryUpdateDeletedDeleterFirst() { $name_deleter = 'config_test.dynamic.deleter'; $name_deletee = 'config_test.dynamic.deletee'; $name_other = 'config_test.dynamic.other'; @@ -305,53 +305,53 @@ function testSecondaryUpdateDeletedDeleterFirst() { $sync = $this->container->get('config.storage.sync'); $uuid = $this->container->get('uuid'); - $values_deleter = array( + $values_deleter = [ 'id' => 'deleter', 'label' => 'Deleter', 'weight' => 0, 'uuid' => $uuid->generate(), - ); + ]; $storage->write($name_deleter, $values_deleter); $values_deleter['label'] = 'Updated Deleter'; $sync->write($name_deleter, $values_deleter); - $values_deletee = array( + $values_deletee = [ 'id' => 'deletee', 'label' => 'Deletee', 'weight' => 0, 'uuid' => $uuid->generate(), // Add a dependency on deleter, to make sure that is synced first. - 'dependencies' => array( - 'config' => array($name_deleter), - ) - ); + 'dependencies' => [ + 'config' => [$name_deleter], + ] + ]; $storage->write($name_deletee, $values_deletee); $values_deletee['label'] = 'Updated Deletee'; $sync->write($name_deletee, $values_deletee); // Ensure that import will continue after the error. - $values_other = array( + $values_other = [ 'id' => 'other', 'label' => 'Other', 'weight' => 0, 'uuid' => $uuid->generate(), // Add a dependency on deleter, to make sure that is synced first. This // will also be synced after the deletee due to alphabetical ordering. - 'dependencies' => array( - 'config' => array($name_deleter), - ) - ); + 'dependencies' => [ + 'config' => [$name_deleter], + ] + ]; $storage->write($name_other, $values_other); $values_other['label'] = 'Updated other'; $sync->write($name_other, $values_other); // Check update changelist order. $updates = $this->configImporter->reset()->getStorageComparer()->getChangelist('update'); - $expected = array( + $expected = [ $name_deleter, $name_deletee, $name_other, - ); - $this->assertIdentical($expected, $updates); + ]; + $this->assertSame($expected, $updates); // Import. $this->configImporter->import(); @@ -373,7 +373,7 @@ function testSecondaryUpdateDeletedDeleterFirst() { $logs = $this->configImporter->getErrors(); $this->assertEqual(count($logs), 1); - $this->assertEqual($logs[0], SafeMarkup::format('Update target "@name" is missing.', array('@name' => $name_deletee))); + $this->assertEqual($logs[0], SafeMarkup::format('Update target "@name" is missing.', ['@name' => $name_deletee])); } /** @@ -383,32 +383,32 @@ function testSecondaryUpdateDeletedDeleterFirst() { * configuration tree imports. Therefore, any configuration updates that cause * secondary deletes should be reflected already in the staged configuration. */ - function testSecondaryUpdateDeletedDeleteeFirst() { + public function testSecondaryUpdateDeletedDeleteeFirst() { $name_deleter = 'config_test.dynamic.deleter'; $name_deletee = 'config_test.dynamic.deletee'; $storage = $this->container->get('config.storage'); $sync = $this->container->get('config.storage.sync'); $uuid = $this->container->get('uuid'); - $values_deleter = array( + $values_deleter = [ 'id' => 'deleter', 'label' => 'Deleter', 'weight' => 0, 'uuid' => $uuid->generate(), // Add a dependency on deletee, to make sure that is synced first. - 'dependencies' => array( - 'config' => array($name_deletee), - ), - ); + 'dependencies' => [ + 'config' => [$name_deletee], + ], + ]; $storage->write($name_deleter, $values_deleter); $values_deleter['label'] = 'Updated Deleter'; $sync->write($name_deleter, $values_deleter); - $values_deletee = array( + $values_deletee = [ 'id' => 'deletee', 'label' => 'Deletee', 'weight' => 0, 'uuid' => $uuid->generate(), - ); + ]; $storage->write($name_deletee, $values_deletee); $values_deletee['label'] = 'Updated Deletee'; $sync->write($name_deletee, $values_deletee); @@ -429,30 +429,30 @@ function testSecondaryUpdateDeletedDeleteeFirst() { /** * Tests that secondary deletes for deleted files work as expected. */ - function testSecondaryDeletedDeleteeSecond() { + public function testSecondaryDeletedDeleteeSecond() { $name_deleter = 'config_test.dynamic.deleter'; $name_deletee = 'config_test.dynamic.deletee'; $storage = $this->container->get('config.storage'); $uuid = $this->container->get('uuid'); - $values_deleter = array( + $values_deleter = [ 'id' => 'deleter', 'label' => 'Deleter', 'weight' => 0, 'uuid' => $uuid->generate(), // Add a dependency on deletee, to make sure this delete is synced first. - 'dependencies' => array( - 'config' => array($name_deletee), - ), - ); + 'dependencies' => [ + 'config' => [$name_deletee], + ], + ]; $storage->write($name_deleter, $values_deleter); - $values_deletee = array( + $values_deletee = [ 'id' => 'deletee', 'label' => 'Deletee', 'weight' => 0, 'uuid' => $uuid->generate(), - ); + ]; $storage->write($name_deletee, $values_deletee); // Import. @@ -471,7 +471,7 @@ function testSecondaryDeletedDeleteeSecond() { /** * Tests updating of configuration during import. */ - function testUpdated() { + public function testUpdated() { $name = 'config_test.system'; $dynamic_name = 'config_test.dynamic.dotted.default'; $storage = $this->container->get('config.storage'); @@ -483,9 +483,9 @@ function testUpdated() { // Replace the file content of the existing configuration objects in the // sync directory. - $original_name_data = array( + $original_name_data = [ 'foo' => 'beer', - ); + ]; $sync->write($name, $original_name_data); $original_dynamic_data = $storage->read($dynamic_name); $original_dynamic_data['label'] = 'Updated'; @@ -528,11 +528,11 @@ function testUpdated() { /** * Tests the isInstallable method() */ - function testIsInstallable() { + public function testIsInstallable() { $config_name = 'config_test.dynamic.isinstallable'; $this->assertFalse($this->container->get('config.storage')->exists($config_name)); \Drupal::state()->set('config_test.isinstallable', TRUE); - $this->installConfig(array('config_test')); + $this->installConfig(['config_test']); $this->assertTrue($this->container->get('config.storage')->exists($config_name)); } @@ -668,6 +668,34 @@ public function testInstallProfile() { } } + /** + * Tests install profile validation during configuration import. + * + * @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber + */ + public function testInstallProfileMisMatch() { + $sync = $this->container->get('config.storage.sync'); + + $extensions = $sync->read('core.extension'); + // Change the install profile. + $extensions['profile'] = 'this_will_not_work'; + $sync->write('core.extension', $extensions); + + try { + $this->configImporter->reset()->import(); + $this->fail('ConfigImporterException not thrown; an invalid import was not stopped due to missing dependencies.'); + } + catch (ConfigImporterException $e) { + $this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.'); + $error_log = $this->configImporter->getErrors(); + // Install profiles can not be changed. Note that KernelTestBase currently + // does not use an install profile. This situation should be impossible + // to get in but site's can removed the install profile setting from + // settings.php so the test is valid. + $this->assertEqual(['Cannot change the install profile from this_will_not_work to once Drupal is installed.'], $error_log); + } + } + /** * Tests config_get_config_directory(). */ diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigInstallTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigInstallTest.php index f8d76c81..9e473c29 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigInstallTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigInstallTest.php @@ -34,7 +34,7 @@ protected function setUp() { /** * Tests module installation. */ - function testModuleInstallation() { + public function testModuleInstallation() { $default_config = 'config_test.system'; $default_configuration_entity = 'config_test.dynamic.dotted.default'; @@ -49,7 +49,7 @@ function testModuleInstallation() { $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.'); // Install the test module. - $this->installModules(array('config_test')); + $this->installModules(['config_test']); // Verify that default module config exists. \Drupal::configFactory()->reset($default_config); @@ -69,14 +69,14 @@ function testModuleInstallation() { $this->assertFalse(isset($GLOBALS['hook_config_test']['delete'])); // Install the schema test module. - $this->enableModules(array('config_schema_test')); - $this->installConfig(array('config_schema_test')); + $this->enableModules(['config_schema_test']); + $this->installConfig(['config_schema_test']); // After module installation the new schema should exist. $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.'); // Test that uninstalling configuration removes configuration schema. - $this->config('core.extension')->set('module', array())->save(); + $this->config('core.extension')->set('module', [])->save(); \Drupal::service('config.manager')->uninstall('module', 'config_test'); $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.'); } @@ -86,28 +86,28 @@ function testModuleInstallation() { */ public function testCollectionInstallationNoCollections() { // Install the test module. - $this->enableModules(array('config_collection_install_test')); - $this->installConfig(array('config_collection_install_test')); + $this->enableModules(['config_collection_install_test']); + $this->installConfig(['config_collection_install_test']); /** @var \Drupal\Core\Config\StorageInterface $active_storage */ $active_storage = \Drupal::service('config.storage'); - $this->assertEqual(array(), $active_storage->getAllCollectionNames()); + $this->assertEqual([], $active_storage->getAllCollectionNames()); } /** * Tests config objects in collections are installed as expected. */ public function testCollectionInstallationCollections() { - $collections = array( + $collections = [ 'another_collection', 'collection.test1', 'collection.test2', - ); + ]; // Set the event listener to return three possible collections. // @see \Drupal\config_collection_install_test\EventSubscriber \Drupal::state()->set('config_collection_install_test.collection_names', $collections); // Install the test module. - $this->enableModules(array('config_collection_install_test')); - $this->installConfig(array('config_collection_install_test')); + $this->enableModules(['config_collection_install_test']); + $this->installConfig(['config_collection_install_test']); /** @var \Drupal\Core\Config\StorageInterface $active_storage */ $active_storage = \Drupal::service('config.storage'); $this->assertEqual($collections, $active_storage->getAllCollectionNames()); @@ -140,20 +140,20 @@ public function testCollectionInstallationCollections() { // is not enabled. $this->assertEqual($collections, $active_storage->getAllCollectionNames()); // Enable the 'config_test' module and try again. - $this->enableModules(array('config_test')); + $this->enableModules(['config_test']); \Drupal::service('config.installer')->installCollectionDefaultConfig('entity'); $collections[] = 'entity'; $this->assertEqual($collections, $active_storage->getAllCollectionNames()); $collection_storage = $active_storage->createCollection('entity'); $data = $collection_storage->read('config_test.dynamic.dotted.default'); - $this->assertIdentical(array('label' => 'entity'), $data); + $this->assertSame(['label' => 'entity'], $data); // Test that the config manager uninstalls configuration from collections // as expected. \Drupal::service('config.manager')->uninstall('module', 'config_collection_install_test'); - $this->assertEqual(array('entity'), $active_storage->getAllCollectionNames()); + $this->assertEqual(['entity'], $active_storage->getAllCollectionNames()); \Drupal::service('config.manager')->uninstall('module', 'config_test'); - $this->assertEqual(array(), $active_storage->getAllCollectionNames()); + $this->assertEqual([], $active_storage->getAllCollectionNames()); } /** @@ -165,12 +165,12 @@ public function testCollectionInstallationCollections() { * using simple configuration. */ public function testCollectionInstallationCollectionConfigEntity() { - $collections = array( + $collections = [ 'entity', - ); + ]; \Drupal::state()->set('config_collection_install_test.collection_names', $collections); // Install the test module. - $this->installModules(array('config_test', 'config_collection_install_test')); + $this->installModules(['config_test', 'config_collection_install_test']); /** @var \Drupal\Core\Config\StorageInterface $active_storage */ $active_storage = \Drupal::service('config.storage'); $this->assertEqual($collections, $active_storage->getAllCollectionNames()); @@ -185,7 +185,7 @@ public function testCollectionInstallationCollectionConfigEntity() { $data = $active_storage->read($name); $this->assertTrue(isset($data['uuid'])); $data = $collection_storage->read($name); - $this->assertIdentical(array('label' => 'entity'), $data); + $this->assertSame(['label' => 'entity'], $data); } /** @@ -199,8 +199,27 @@ public function testDependencyChecking() { } catch (UnmetDependenciesException $e) { $this->assertEqual($e->getExtension(), 'config_install_dependency_test'); - $this->assertEqual($e->getConfigObjects(), ['config_other_module_config_test.weird_simple_config', 'config_test.dynamic.other_module_test_with_dependency']); - $this->assertEqual($e->getMessage(), 'Configuration objects (config_other_module_config_test.weird_simple_config, config_test.dynamic.other_module_test_with_dependency) provided by config_install_dependency_test have unmet dependencies'); + $this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test', 'config_test.dynamic.dotted.english']]); + $this->assertEqual($e->getMessage(), 'Configuration objects provided by config_install_dependency_test have unmet dependencies: config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test, config_test.dynamic.dotted.english)'); + } + try { + $this->installModules(['config_install_double_dependency_test']); + $this->fail('Expected UnmetDependenciesException not thrown.'); + } + catch (UnmetDependenciesException $e) { + $this->assertEquals('config_install_double_dependency_test', $e->getExtension()); + $this->assertEquals(['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test', 'config_test.dynamic.dotted.english']], $e->getConfigObjects()); + $this->assertEquals('Configuration objects provided by config_install_double_dependency_test have unmet dependencies: config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test, config_test.dynamic.dotted.english)', $e->getMessage()); + } + $this->installModules(['config_test_language']); + try { + $this->installModules(['config_install_dependency_test']); + $this->fail('Expected UnmetDependenciesException not thrown.'); + } + catch (UnmetDependenciesException $e) { + $this->assertEqual($e->getExtension(), 'config_install_dependency_test'); + $this->assertEqual($e->getConfigObjects(), ['config_test.dynamic.other_module_test_with_dependency' => ['config_other_module_config_test']]); + $this->assertEqual($e->getMessage(), 'Configuration objects provided by config_install_dependency_test have unmet dependencies: config_test.dynamic.other_module_test_with_dependency (config_other_module_config_test)'); } $this->installModules(['config_other_module_config_test']); $this->installModules(['config_install_dependency_test']); @@ -208,13 +227,13 @@ public function testDependencyChecking() { $this->assertTrue($entity, 'The config_test.dynamic.other_module_test_with_dependency configuration has been created during install.'); // Ensure that dependencies can be added during module installation by // hooks. - $this->assertIdentical('config_install_dependency_test', $entity->getDependencies()['module'][0]); + $this->assertSame('config_install_dependency_test', $entity->getDependencies()['module'][0]); } /** * Tests imported configuration entities with and without language information. */ - function testLanguage() { + public function testLanguage() { $this->installModules(['config_test_language']); // Test imported configuration with implicit language code. $storage = new InstallStorage(); diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigLanguageOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigLanguageOverrideTest.php index 994406c2..5bf6f0ec 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigLanguageOverrideTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigLanguageOverrideTest.php @@ -17,20 +17,20 @@ class ConfigLanguageOverrideTest extends KernelTestBase { * * @var array */ - public static $modules = array('user', 'language', 'config_test', 'system', 'field'); + public static $modules = ['user', 'language', 'config_test', 'system', 'field']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('config_test')); + $this->installConfig(['config_test']); } /** * Tests locale override based on language. */ - function testConfigLanguageOverride() { + public function testConfigLanguageOverride() { // The language module implements a config factory override object that // overrides configuration when the Language module is enabled. This test ensures that // English overrides work. @@ -68,40 +68,40 @@ function testConfigLanguageOverride() { // Test how overrides react to base configuration changes. Set up some base // values. \Drupal::configFactory()->getEditable('config_test.foo') - ->set('value', array('key' => 'original')) + ->set('value', ['key' => 'original']) ->set('label', 'Original') ->save(); \Drupal::languageManager() ->getLanguageConfigOverride('de', 'config_test.foo') - ->set('value', array('key' => 'override')) + ->set('value', ['key' => 'override']) ->set('label', 'Override') ->save(); \Drupal::languageManager() ->getLanguageConfigOverride('fr', 'config_test.foo') - ->set('value', array('key' => 'override')) + ->set('value', ['key' => 'override']) ->save(); \Drupal::configFactory()->clearStaticCache(); $config = \Drupal::config('config_test.foo'); - $this->assertIdentical($config->get('value'), array('key' => 'override')); + $this->assertIdentical($config->get('value'), ['key' => 'override']); // Ensure renaming the config will rename the override. \Drupal::languageManager()->setConfigOverrideLanguage(\Drupal::languageManager()->getLanguage('en')); \Drupal::configFactory()->rename('config_test.foo', 'config_test.bar'); $config = \Drupal::config('config_test.bar'); - $this->assertEqual($config->get('value'), array('key' => 'original')); + $this->assertEqual($config->get('value'), ['key' => 'original']); $override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.foo'); $this->assertTrue($override->isNew()); $this->assertEqual($override->get('value'), NULL); $override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar'); $this->assertFalse($override->isNew()); - $this->assertEqual($override->get('value'), array('key' => 'override')); + $this->assertEqual($override->get('value'), ['key' => 'override']); $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'config_test.bar'); $this->assertFalse($override->isNew()); - $this->assertEqual($override->get('value'), array('key' => 'override')); + $this->assertEqual($override->get('value'), ['key' => 'override']); // Ensure changing data in the config will update the overrides. $config = \Drupal::configFactory()->getEditable('config_test.bar')->clear('value.key')->save(); - $this->assertEqual($config->get('value'), array()); + $this->assertEqual($config->get('value'), []); $override = \Drupal::languageManager()->getLanguageConfigOverride('de', 'config_test.bar'); $this->assertFalse($override->isNew()); $this->assertEqual($override->get('value'), NULL); diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigModuleOverridesTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigModuleOverridesTest.php index 1310cb32..a94123d4 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigModuleOverridesTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigModuleOverridesTest.php @@ -16,7 +16,7 @@ class ConfigModuleOverridesTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'config', 'config_override_test'); + public static $modules = ['system', 'config', 'config_override_test']; public function testSimpleModuleOverrides() { $GLOBALS['config_test_run_module_overrides'] = TRUE; diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigOverrideTest.php index 914adcf1..b2ddaa39 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigOverrideTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigOverrideTest.php @@ -16,7 +16,7 @@ class ConfigOverrideTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'config_test'); + public static $modules = ['system', 'config_test']; protected function setUp() { parent::setUp(); @@ -26,12 +26,12 @@ protected function setUp() { /** * Tests configuration override. */ - function testConfOverride() { - $expected_original_data = array( + public function testConfOverride() { + $expected_original_data = [ 'foo' => 'bar', 'baz' => NULL, '404' => 'herp', - ); + ]; // Set globals before installing to prove that the installed file does not // contain these values. @@ -40,7 +40,7 @@ function testConfOverride() { $overrides['config_test.system']['404'] = 'derp'; $GLOBALS['config'] = $overrides; - $this->installConfig(array('config_test')); + $this->installConfig(['config_test']); // Verify that the original configuration data exists. Have to read storage // directly otherwise overrides will apply. @@ -90,10 +90,10 @@ function testConfOverride() { // Write file to sync. $sync = $this->container->get('config.storage.sync'); - $expected_new_data = array( + $expected_new_data = [ 'foo' => 'barbar', '404' => 'herpderp', - ); + ]; $sync->write('config_test.system', $expected_new_data); // Import changed data from sync to active. diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigOverridesPriorityTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigOverridesPriorityTest.php index f18bf3c8..6c568b84 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigOverridesPriorityTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigOverridesPriorityTest.php @@ -18,7 +18,7 @@ class ConfigOverridesPriorityTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'config', 'config_override_test', 'language'); + public static $modules = ['system', 'config', 'config_override_test', 'language']; public function testOverridePriorities() { $GLOBALS['config_test_run_module_overrides'] = FALSE; @@ -50,10 +50,10 @@ public function testOverridePriorities() { $this->assertEqual(50, $config_factory->get('system.site')->get('weight_select_max')); // Override using language. - $language = new Language(array( + $language = new Language([ 'name' => 'French', 'id' => 'fr', - )); + ]); \Drupal::languageManager()->setConfigOverrideLanguage($language); \Drupal::languageManager() ->getLanguageConfigOverride($language->getId(), 'system.site') diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php index ae3abdd8..6c0bc1a6 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php @@ -5,6 +5,10 @@ use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\Schema\ConfigSchemaAlterException; +use Drupal\Core\Config\Schema\Ignore; +use Drupal\Core\Config\Schema\Mapping; +use Drupal\Core\Config\Schema\Undefined; +use Drupal\Core\TypedData\Plugin\DataType\StringData; use Drupal\Core\TypedData\Type\IntegerInterface; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\KernelTests\KernelTestBase; @@ -21,130 +25,138 @@ class ConfigSchemaTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'language', 'field', 'image', 'config_test', 'config_schema_test'); + public static $modules = ['system', 'language', 'field', 'image', 'config_test', 'config_schema_test']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('system', 'image', 'config_schema_test')); + $this->installConfig(['system', 'image', 'config_schema_test']); } /** * Tests the basic metadata retrieval layer. */ - function testSchemaMapping() { + public function testSchemaMapping() { // Nonexistent configuration key will have Undefined as metadata. - $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key')); + $this->assertSame(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key')); $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key'); - $expected = array(); + $expected = []; $expected['label'] = 'Undefined'; - $expected['class'] = '\Drupal\Core\Config\Schema\Undefined'; + $expected['class'] = Undefined::class; $expected['type'] = 'undefined'; $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.'); // Configuration file without schema will return Undefined as well. - $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema')); + $this->assertSame(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema')); $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema'); $this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.'); // Configuration file with only some schema. - $this->assertIdentical(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema')); + $this->assertSame(TRUE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema')); $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema'); - $expected = array(); + $expected = []; $expected['label'] = 'Schema test data'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; $expected['mapping']['_core']['type'] = '_core_config_info'; - $expected['mapping']['testitem'] = array('label' => 'Test item'); - $expected['mapping']['testlist'] = array('label' => 'Test list'); + $expected['mapping']['testitem'] = ['label' => 'Test item']; + $expected['mapping']['testlist'] = ['label' => 'Test list']; $expected['type'] = 'config_schema_test.someschema'; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.'); // Check type detection on elements with undefined types. $config = \Drupal::service('config.typed')->get('config_schema_test.someschema'); $definition = $config->get('testitem')->getDataDefinition()->toArray(); - $expected = array(); + $expected = []; $expected['label'] = 'Test item'; - $expected['class'] = '\Drupal\Core\Config\Schema\Undefined'; + $expected['class'] = Undefined::class; $expected['type'] = 'undefined'; $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.'); $definition = $config->get('testlist')->getDataDefinition()->toArray(); - $expected = array(); + $expected = []; $expected['label'] = 'Test list'; - $expected['class'] = '\Drupal\Core\Config\Schema\Undefined'; + $expected['class'] = Undefined::class; $expected['type'] = 'undefined'; $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.'); $definition = $config->get('testnoschema')->getDataDefinition()->toArray(); - $expected = array(); + $expected = []; $expected['label'] = 'Undefined'; - $expected['class'] = '\Drupal\Core\Config\Schema\Undefined'; + $expected['class'] = Undefined::class; $expected['type'] = 'undefined'; $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Automatic type detected for an undefined integer is undefined.'); // Simple case, straight metadata. $definition = \Drupal::service('config.typed')->getDefinition('system.maintenance'); - $expected = array(); + $expected = []; $expected['label'] = 'Maintenance mode'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; - $expected['mapping']['message'] = array( + $expected['class'] = Mapping::class; + $expected['mapping']['message'] = [ 'label' => 'Message to display when in maintenance mode', 'type' => 'text', - ); - $expected['mapping']['langcode'] = array( + ]; + $expected['mapping']['langcode'] = [ 'label' => 'Language code', 'type' => 'string', - ); + ]; $expected['mapping']['_core']['type'] = '_core_config_info'; $expected['type'] = 'system.maintenance'; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance'); // Mixed schema with ignore elements. $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.ignore'); - $expected = array(); + $expected = []; $expected['label'] = 'Ignore test'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; - $expected['mapping']['langcode'] = array( + $expected['mapping']['langcode'] = [ 'type' => 'string', 'label' => 'Language code', - ); + ]; $expected['mapping']['_core']['type'] = '_core_config_info'; - $expected['mapping']['label'] = array( + $expected['mapping']['label'] = [ 'label' => 'Label', 'type' => 'label', - ); - $expected['mapping']['irrelevant'] = array( + ]; + $expected['mapping']['irrelevant'] = [ 'label' => 'Irrelevant', 'type' => 'ignore', - ); - $expected['mapping']['indescribable'] = array( + ]; + $expected['mapping']['indescribable'] = [ 'label' => 'Indescribable', 'type' => 'ignore', - ); - $expected['mapping']['weight'] = array( + ]; + $expected['mapping']['weight'] = [ 'label' => 'Weight', 'type' => 'integer', - ); + ]; $expected['type'] = 'config_schema_test.ignore'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected); // The ignore elements themselves. $definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('irrelevant')->getDataDefinition()->toArray(); - $expected = array(); + $expected = []; $expected['type'] = 'ignore'; $expected['label'] = 'Irrelevant'; - $expected['class'] = '\Drupal\Core\Config\Schema\Ignore'; + $expected['class'] = Ignore::class; $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected); $definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition()->toArray(); $expected['label'] = 'Indescribable'; @@ -152,12 +164,13 @@ function testSchemaMapping() { // More complex case, generic type. Metadata for image style. $definition = \Drupal::service('config.typed')->getDefinition('image.style.large'); - $expected = array(); + $expected = []; $expected['label'] = 'Image style'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $expected['mapping']['name']['type'] = 'string'; - $expected['mapping']['uuid']['type'] = 'string'; + $expected['mapping']['uuid']['type'] = 'uuid'; $expected['mapping']['uuid']['label'] = 'UUID'; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; @@ -173,7 +186,7 @@ function testSchemaMapping() { $expected['mapping']['effects']['sequence']['mapping']['id']['type'] = 'string'; $expected['mapping']['effects']['sequence']['mapping']['data']['type'] = 'image.effect.[%parent.id]'; $expected['mapping']['effects']['sequence']['mapping']['weight']['type'] = 'integer'; - $expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'string'; + $expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'uuid'; $expected['mapping']['third_party_settings']['type'] = 'sequence'; $expected['mapping']['third_party_settings']['label'] = 'Third party settings'; $expected['mapping']['third_party_settings']['sequence']['type'] = '[%parent.%parent.%type].third_party.[%key]'; @@ -185,10 +198,11 @@ function testSchemaMapping() { // More complex, type based on a complex one. $definition = \Drupal::service('config.typed')->getDefinition('image.effect.image_scale'); // This should be the schema for image.effect.image_scale. - $expected = array(); + $expected = []; $expected['label'] = 'Image scale'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $expected['mapping']['width']['type'] = 'integer'; $expected['mapping']['width']['label'] = 'Width'; $expected['mapping']['height']['type'] = 'integer'; @@ -211,11 +225,12 @@ function testSchemaMapping() { $a = \Drupal::config('config_test.dynamic.third_party'); $test = \Drupal::service('config.typed')->get('config_test.dynamic.third_party')->get('third_party_settings.config_schema_test'); $definition = $test->getDataDefinition()->toArray(); - $expected = array(); + $expected = []; $expected['type'] = 'config_test.dynamic.*.third_party.config_schema_test'; $expected['label'] = 'Mapping'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $expected['mapping'] = [ 'integer' => ['type' => 'integer'], 'string' => ['type' => 'string'], @@ -225,9 +240,9 @@ function testSchemaMapping() { // More complex, several level deep test. $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection'); // This should be the schema of config_schema_test.someschema.somemodule.*.*. - $expected = array(); + $expected = []; $expected['label'] = 'Schema multiple filesystem marker test'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; $expected['mapping']['_core']['type'] = '_core_config_info'; @@ -237,6 +252,7 @@ function testSchemaMapping() { $expected['mapping']['testdescription']['label'] = 'Description'; $expected['type'] = 'config_schema_test.someschema.somemodule.*.*'; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_one.subsection'); @@ -248,47 +264,50 @@ function testSchemaMapping() { /** * Tests metadata retrieval with several levels of %parent indirection. */ - function testSchemaMappingWithParents() { + public function testSchemaMappingWithParents() { $config_data = \Drupal::service('config.typed')->get('config_schema_test.someschema.with_parents'); // Test fetching parent one level up. $entry = $config_data->get('one_level'); $definition = $entry->get('testitem')->getDataDefinition()->toArray(); - $expected = array( + $expected = [ 'type' => 'config_schema_test.someschema.with_parents.key_1', 'label' => 'Test item nested one level', - 'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData', + 'class' => StringData::class, 'definition_class' => '\Drupal\Core\TypedData\DataDefinition', - ); + 'unwrap_for_canonical_representation' => TRUE, + ]; $this->assertEqual($definition, $expected); // Test fetching parent two levels up. $entry = $config_data->get('two_levels'); $definition = $entry->get('wrapper')->get('testitem')->getDataDefinition()->toArray(); - $expected = array( + $expected = [ 'type' => 'config_schema_test.someschema.with_parents.key_2', 'label' => 'Test item nested two levels', - 'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData', + 'class' => StringData::class, 'definition_class' => '\Drupal\Core\TypedData\DataDefinition', - ); + 'unwrap_for_canonical_representation' => TRUE, + ]; $this->assertEqual($definition, $expected); // Test fetching parent three levels up. $entry = $config_data->get('three_levels'); $definition = $entry->get('wrapper_1')->get('wrapper_2')->get('testitem')->getDataDefinition()->toArray(); - $expected = array( + $expected = [ 'type' => 'config_schema_test.someschema.with_parents.key_3', 'label' => 'Test item nested three levels', - 'class' => '\Drupal\Core\TypedData\Plugin\DataType\StringData', + 'class' => StringData::class, 'definition_class' => '\Drupal\Core\TypedData\DataDefinition', - ); + 'unwrap_for_canonical_representation' => TRUE, + ]; $this->assertEqual($definition, $expected); } /** * Tests metadata applied to configuration objects. */ - function testSchemaData() { + public function testSchemaData() { // Try a simple property. $meta = \Drupal::service('config.typed')->get('system.site'); $property = $meta->get('page')->get('front'); @@ -317,14 +336,14 @@ function testSchemaData() { $effect = $effects->get($uuid)->getElements(); $this->assertTrue(!$effect['data']->isEmpty() && $effect['id']->getValue() == 'image_scale', 'Got data for the image scale effect from metadata.'); $this->assertTrue($effect['data']->get('width') instanceof IntegerInterface, 'Got the right type for the scale effect width.'); - $this->assertEqual($effect['data']->get('width')->getValue(), 480, 'Got the right value for the scale effect width.' ); + $this->assertEqual($effect['data']->get('width')->getValue(), 480, 'Got the right value for the scale effect width.'); } /** * Test configuration value data type enforcement using schemas. */ public function testConfigSaveWithSchema() { - $untyped_values = array( + $untyped_values = [ 'string' => 1, 'empty_string' => '', 'null_string' => NULL, @@ -333,22 +352,22 @@ public function testConfigSaveWithSchema() { 'boolean' => 1, // If the config schema doesn't have a type it shouldn't be casted. 'no_type' => 1, - 'mapping' => array( + 'mapping' => [ 'string' => 1 - ), + ], 'float' => '3.14', 'null_float' => '', - 'sequence' => array (1, 0, 1), - 'sequence_bc' => array(1, 0, 1), + 'sequence' => [1, 0, 1], + 'sequence_bc' => [1, 0, 1], // Not in schema and therefore should be left untouched. 'not_present_in_schema' => TRUE, // Test a custom type. 'config_schema_test_integer' => '1', 'config_schema_test_integer_empty_string' => '', - ); + ]; $untyped_to_typed = $untyped_values; - $typed_values = array( + $typed_values = [ 'string' => '1', 'empty_string' => '', 'null_string' => NULL, @@ -356,17 +375,17 @@ public function testConfigSaveWithSchema() { 'null_integer' => NULL, 'boolean' => TRUE, 'no_type' => 1, - 'mapping' => array( + 'mapping' => [ 'string' => '1' - ), + ], 'float' => 3.14, 'null_float' => NULL, - 'sequence' => array (TRUE, FALSE, TRUE), - 'sequence_bc' => array(TRUE, FALSE, TRUE), + 'sequence' => [TRUE, FALSE, TRUE], + 'sequence_bc' => [TRUE, FALSE, TRUE], 'not_present_in_schema' => TRUE, 'config_schema_test_integer' => 1, 'config_schema_test_integer_empty_string' => NULL, - ); + ]; // Save config which has a schema that enforces types. $this->config('config_schema_test.schema_data_types') @@ -391,16 +410,87 @@ public function testConfigSaveWithSchema() { $this->assertIdentical($installed_data, $original_data); } + /** + * Tests configuration sequence sorting using schemas. + */ + public function testConfigSaveWithSequenceSorting() { + $data = [ + 'keyed_sort' => [ + 'b' => '1', + 'a' => '2', + ], + 'no_sort' => [ + 'b' => '2', + 'a' => '1', + ], + ]; + // Save config which has a schema that enforces sorting. + $this->config('config_schema_test.schema_sequence_sort') + ->setData($data) + ->save(); + $this->assertSame(['a' => '2', 'b' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('keyed_sort')); + $this->assertSame(['b' => '2', 'a' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort')); + + $data = [ + 'value_sort' => ['b', 'a'], + 'no_sort' => ['b', 'a'], + ]; + // Save config which has a schema that enforces sorting. + $this->config('config_schema_test.schema_sequence_sort') + ->setData($data) + ->save(); + + $this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort')); + $this->assertSame(['b', 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort')); + + // Value sort does not preserve keys - this is intentional. + $data = [ + 'value_sort' => [1 => 'b', 2 => 'a'], + 'no_sort' => [1 => 'b', 2 => 'a'], + ]; + // Save config which has a schema that enforces sorting. + $this->config('config_schema_test.schema_sequence_sort') + ->setData($data) + ->save(); + + $this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort')); + $this->assertSame([1 => 'b', 2 => 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort')); + + // Test sorts do not destroy complex values. + $data = [ + 'complex_sort_value' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']], + 'complex_sort_key' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']], + ]; + $this->config('config_schema_test.schema_sequence_sort') + ->setData($data) + ->save(); + $this->assertSame([['foo' => 'a', 'bar' => 'a'], ['foo' => 'b', 'bar' => 'b']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value')); + $this->assertSame(['a' => ['foo' => '2', 'bar' => '2'], 'b' => ['foo' => '1', 'bar' => '1']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key')); + + // Swap the previous test scenario around. + $data = [ + 'complex_sort_value' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']], + 'complex_sort_key' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']], + ]; + $this->config('config_schema_test.schema_sequence_sort') + ->setData($data) + ->save(); + $this->assertSame([['foo' => '1', 'bar' => '1'], ['foo' => '2', 'bar' => '2']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value')); + $this->assertSame([['foo' => 'b', 'bar' => 'b'], ['foo' => 'a', 'bar' => 'a']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key')); + + } + /** * Tests fallback to a greedy wildcard. */ - function testSchemaFallback() { + public function testSchemaFallback() { $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something'); // This should be the schema of config_schema_test.wildcard_fallback.*. - $expected = array(); + $expected = []; $expected['label'] = 'Schema wildcard fallback test'; - $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['class'] = Mapping::class; $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['unwrap_for_canonical_representation'] = TRUE; $expected['mapping']['langcode']['type'] = 'string'; $expected['mapping']['langcode']['label'] = 'Language code'; $expected['mapping']['_core']['type'] = '_core_config_info'; @@ -414,8 +504,8 @@ function testSchemaFallback() { $definition2 = \Drupal::service('config.typed')->getDefinition('config_schema_test.wildcard_fallback.something.something'); // This should be the schema of config_schema_test.wildcard_fallback.* as - //well. - $this->assertIdentical($definition, $definition2); + // well. + $this->assertSame($definition, $definition2); } /** @@ -423,7 +513,7 @@ function testSchemaFallback() { * * @see \Drupal\Core\Config\TypedConfigManager::getFallbackName() */ - function testColonsInSchemaTypeDetermination() { + public function testColonsInSchemaTypeDetermination() { $tests = \Drupal::service('config.typed')->get('config_schema_test.plugin_types')->get('tests')->getElements(); $definition = $tests[0]->getDataDefinition()->toArray(); $this->assertEqual($definition['type'], 'test.plugin_types.boolean'); @@ -631,6 +721,27 @@ public function testConfigSaveWithWrappingSchemaDoubleBrackets() { $this->assertEqual($definition['type'], 'wrapping.test.double_brackets.*||test.double_brackets.cat.dog'); $definition = $tests[1]->getDataDefinition()->toArray(); $this->assertEqual($definition['type'], 'wrapping.test.double_brackets.*||test.double_brackets.turtle.horse'); + + $typed_values = [ + 'tests' => [ + [ + 'id' => 'cat:persion.dog', + 'foo' => 'cat', + 'bar' => 'dog', + 'breed' => 'persion', + ], + ], + ]; + + \Drupal::configFactory()->getEditable('wrapping.config_schema_test.other_double_brackets') + ->setData($typed_values) + ->save(); + $tests = \Drupal::service('config.typed')->get('wrapping.config_schema_test.other_double_brackets')->get('tests')->getElements(); + $definition = $tests[0]->getDataDefinition()->toArray(); + // Check that definition type is a merge of the expected types. + $this->assertEqual($definition['type'], 'wrapping.test.other_double_brackets.*||test.double_brackets.cat:*.*'); + // Check that breed was inherited from parent definition. + $this->assertEqual($definition['mapping']['breed'], ['type' => 'string']); } } diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigSnapshotTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigSnapshotTest.php index efac2dd1..62eff04d 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/ConfigSnapshotTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigSnapshotTest.php @@ -17,7 +17,7 @@ class ConfigSnapshotTest extends KernelTestBase { * * @var array */ - public static $modules = array('config_test', 'system'); + public static $modules = ['config_test', 'system']; /** * {@inheritdoc} @@ -33,7 +33,7 @@ protected function setUp() { /** * Tests config snapshot creation and updating. */ - function testSnapshot() { + public function testSnapshot() { $active = $this->container->get('config.storage'); $sync = $this->container->get('config.storage.sync'); $snapshot = $this->container->get('config.storage.snapshot'); @@ -50,7 +50,7 @@ function testSnapshot() { $this->assertFalse($active_snapshot_comparer->createChangelist()->hasChanges()); // Install the default config. - $this->installConfig(array('config_test')); + $this->installConfig(['config_test']); // Although we have imported config this has not affected the snapshot. $this->assertTrue($active_snapshot_comparer->reset()->hasChanges()); diff --git a/core/tests/Drupal/KernelTests/Core/Config/DefaultConfigTest.php b/core/tests/Drupal/KernelTests/Core/Config/DefaultConfigTest.php index a8f9ef5d..f06806ca 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/DefaultConfigTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/DefaultConfigTest.php @@ -2,7 +2,7 @@ namespace Drupal\KernelTests\Core\Config; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\config_test\TestInstallStorage; use Drupal\Core\Config\InstallStorage; use Drupal\Core\DependencyInjection\ContainerBuilder; @@ -23,7 +23,7 @@ class DefaultConfigTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'config_test'); + public static $modules = ['system', 'config_test']; /** * Themes which provide default configuration and need enabling. diff --git a/core/tests/Drupal/KernelTests/Core/Config/SchemaCheckTraitTest.php b/core/tests/Drupal/KernelTests/Core/Config/SchemaCheckTraitTest.php index 15aecaaa..a11bcb65 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/SchemaCheckTraitTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/SchemaCheckTraitTest.php @@ -5,7 +5,6 @@ use Drupal\Core\Config\Schema\SchemaCheckTrait; use Drupal\KernelTests\KernelTestBase; - /** * Tests the functionality of SchemaCheckTrait. * @@ -27,14 +26,14 @@ class SchemaCheckTraitTest extends KernelTestBase { * * @var array */ - public static $modules = array('config_test', 'config_schema_test'); + public static $modules = ['config_test', 'config_schema_test']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('config_test', 'config_schema_test')); + $this->installConfig(['config_test', 'config_schema_test']); $this->typedConfig = \Drupal::service('config.typed'); } @@ -53,14 +52,14 @@ public function testTrait() { // Add a new key, a new array and overwrite boolean with array to test the // error messages. - $config_data = array('new_key' => 'new_value', 'new_array' => array()) + $config_data; - $config_data['boolean'] = array(); + $config_data = ['new_key' => 'new_value', 'new_array' => []] + $config_data; + $config_data['boolean'] = []; $ret = $this->checkConfigSchema($this->typedConfig, 'config_test.types', $config_data); - $expected = array( + $expected = [ 'config_test.types:new_key' => 'missing schema', 'config_test.types:new_array' => 'missing schema', 'config_test.types:boolean' => 'non-scalar value but not defined as an array (such as mapping or sequence)', - ); + ]; $this->assertEqual($ret, $expected); } diff --git a/core/tests/Drupal/KernelTests/Core/Config/SchemaConfigListenerTest.php b/core/tests/Drupal/KernelTests/Core/Config/SchemaConfigListenerTest.php index f0780212..2674a3c6 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/SchemaConfigListenerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/SchemaConfigListenerTest.php @@ -17,7 +17,7 @@ class SchemaConfigListenerTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('config_test'); + public static $modules = ['config_test']; /** * {@inheritdoc} diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/CachedStorageTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/CachedStorageTest.php index 163cca71..23664781 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/Storage/CachedStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/CachedStorageTest.php @@ -37,7 +37,7 @@ protected function setUp() { $this->storage = new CachedStorage($this->fileStorage, \Drupal::service('cache.config')); $this->cache = \Drupal::service('cache_factory')->get('config'); // ::listAll() verifications require other configuration data to exist. - $this->storage->write('system.performance', array()); + $this->storage->write('system.performance', []); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/ConfigStorageTestBase.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/ConfigStorageTestBase.php index 1863dab2..5bdbc74d 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/Storage/ConfigStorageTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/ConfigStorageTestBase.php @@ -33,7 +33,7 @@ abstract class ConfigStorageTestBase extends KernelTestBase { * * @todo Coverage: Trigger PDOExceptions / Database exceptions. */ - function testCRUD() { + public function testCRUD() { $name = 'config_test.storage'; // Checking whether a non-existing name exists returns FALSE. @@ -44,7 +44,7 @@ function testCRUD() { $this->assertIdentical($data, FALSE); // Writing data returns TRUE and the data has been written. - $data = array('foo' => 'bar'); + $data = ['foo' => 'bar']; $result = $this->storage->write($name, $data); $this->assertIdentical($result, TRUE); @@ -86,11 +86,11 @@ function testCRUD() { // Deleting all names with prefix deletes the appropriate data and returns // TRUE. - $files = array( + $files = [ 'config_test.test.biff', 'config_test.test.bang', 'config_test.test.pow', - ); + ]; foreach ($files as $name) { $this->storage->write($name, $data); } @@ -98,7 +98,7 @@ function testCRUD() { $result = $this->storage->deleteAll('config_test.'); $names = $this->storage->listAll('config_test.'); $this->assertIdentical($result, TRUE); - $this->assertIdentical($names, array()); + $this->assertIdentical($names, []); // Test renaming an object that does not exist throws an exception. try { @@ -127,7 +127,7 @@ public function testInvalidStorage() { // Write something to the valid storage to prove that the storages do not // pollute one another. - $data = array('foo' => 'bar'); + $data = ['foo' => 'bar']; $result = $this->storage->write($name, $data); $this->assertIdentical($result, TRUE); @@ -150,20 +150,20 @@ public function testInvalidStorage() { // Listing on a non-existing storage bin returns an empty array. $result = $this->invalidStorage->listAll(); - $this->assertIdentical($result, array()); + $this->assertIdentical($result, []); // Writing to a non-existing storage bin creates the bin. - $this->invalidStorage->write($name, array('foo' => 'bar')); + $this->invalidStorage->write($name, ['foo' => 'bar']); $result = $this->invalidStorage->read($name); - $this->assertIdentical($result, array('foo' => 'bar')); + $this->assertIdentical($result, ['foo' => 'bar']); } /** * Tests storage writing and reading data preserving data type. */ - function testDataTypes() { + public function testDataTypes() { $name = 'config_test.types'; - $data = array( - 'array' => array(), + $data = [ + 'array' => [], 'boolean' => TRUE, 'exp' => 1.2e+34, 'float' => 3.14159, @@ -172,7 +172,7 @@ function testDataTypes() { 'octal' => 0775, 'string' => 'string', 'string_int' => '1', - ); + ]; $result = $this->storage->write($name, $data); $this->assertIdentical($result, TRUE); @@ -186,73 +186,73 @@ function testDataTypes() { */ public function testCollection() { $name = 'config_test.storage'; - $data = array('foo' => 'bar'); + $data = ['foo' => 'bar']; $result = $this->storage->write($name, $data); $this->assertIdentical($result, TRUE); - $this->assertIdentical($data, $this->storage->read($name)); + $this->assertSame($data, $this->storage->read($name)); // Create configuration in a new collection. $new_storage = $this->storage->createCollection('collection.sub.new'); $this->assertFalse($new_storage->exists($name)); - $this->assertEqual(array(), $new_storage->listAll()); + $this->assertEqual([], $new_storage->listAll()); $new_storage->write($name, $data); $this->assertIdentical($result, TRUE); - $this->assertIdentical($data, $new_storage->read($name)); - $this->assertEqual(array($name), $new_storage->listAll()); + $this->assertSame($data, $new_storage->read($name)); + $this->assertEqual([$name], $new_storage->listAll()); $this->assertTrue($new_storage->exists($name)); - $new_data = array('foo' => 'baz'); + $new_data = ['foo' => 'baz']; $new_storage->write($name, $new_data); $this->assertIdentical($result, TRUE); - $this->assertIdentical($new_data, $new_storage->read($name)); + $this->assertSame($new_data, $new_storage->read($name)); // Create configuration in another collection. $another_storage = $this->storage->createCollection('collection.sub.another'); $this->assertFalse($another_storage->exists($name)); - $this->assertEqual(array(), $another_storage->listAll()); + $this->assertEqual([], $another_storage->listAll()); $another_storage->write($name, $new_data); $this->assertIdentical($result, TRUE); - $this->assertIdentical($new_data, $another_storage->read($name)); - $this->assertEqual(array($name), $another_storage->listAll()); + $this->assertSame($new_data, $another_storage->read($name)); + $this->assertEqual([$name], $another_storage->listAll()); $this->assertTrue($another_storage->exists($name)); // Create configuration in yet another collection. $alt_storage = $this->storage->createCollection('alternate'); $alt_storage->write($name, $new_data); $this->assertIdentical($result, TRUE); - $this->assertIdentical($new_data, $alt_storage->read($name)); + $this->assertSame($new_data, $alt_storage->read($name)); // Switch back to the collection-less mode and check the data still exists // add has not been touched. - $this->assertIdentical($data, $this->storage->read($name)); + $this->assertSame($data, $this->storage->read($name)); // Check that the getAllCollectionNames() method works. - $this->assertIdentical(array('alternate', 'collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames()); + $this->assertSame(['alternate', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames()); // Check that the collections are removed when they are empty. $alt_storage->delete($name); - $this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames()); + $this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames()); // Create configuration in collection called 'collection'. This ensures that // FileStorage's collection storage works regardless of its use of // subdirectories. $parent_storage = $this->storage->createCollection('collection'); $this->assertFalse($parent_storage->exists($name)); - $this->assertEqual(array(), $parent_storage->listAll()); + $this->assertEqual([], $parent_storage->listAll()); $parent_storage->write($name, $new_data); $this->assertIdentical($result, TRUE); - $this->assertIdentical($new_data, $parent_storage->read($name)); - $this->assertEqual(array($name), $parent_storage->listAll()); + $this->assertSame($new_data, $parent_storage->read($name)); + $this->assertEqual([$name], $parent_storage->listAll()); $this->assertTrue($parent_storage->exists($name)); - $this->assertIdentical(array('collection', 'collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames()); + $this->assertSame(['collection', 'collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames()); $parent_storage->deleteAll(); - $this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames()); + $this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames()); // Check that the having an empty collection-less storage does not break // anything. Before deleting check that the previous delete did not affect // data in another collection. - $this->assertIdentical($data, $this->storage->read($name)); + $this->assertSame($data, $this->storage->read($name)); $this->storage->delete($name); - $this->assertIdentical(array('collection.sub.another', 'collection.sub.new'), $this->storage->getAllCollectionNames()); + $this->assertSame(['collection.sub.another', 'collection.sub.new'], $this->storage->getAllCollectionNames()); } abstract protected function read($name); diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php index 6f09a829..0aecc72b 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/DatabaseStorageTest.php @@ -21,20 +21,20 @@ protected function setUp() { $this->invalidStorage = new DatabaseStorage($this->container->get('database'), 'invalid'); // ::listAll() verifications require other configuration data to exist. - $this->storage->write('system.performance', array()); + $this->storage->write('system.performance', []); } protected function read($name) { - $data = db_query('SELECT data FROM {config} WHERE name = :name', array(':name' => $name))->fetchField(); + $data = db_query('SELECT data FROM {config} WHERE name = :name', [':name' => $name])->fetchField(); return unserialize($data); } protected function insert($name, $data) { - db_insert('config')->fields(array('name' => $name, 'data' => $data))->execute(); + db_insert('config')->fields(['name' => $name, 'data' => $data])->execute(); } protected function update($name, $data) { - db_update('config')->fields(array('data' => $data))->condition('name', $name)->execute(); + db_update('config')->fields(['data' => $data])->condition('name', $name)->execute(); } protected function delete($name) { diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php index fa10a097..805af8ae 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/FileStorageTest.php @@ -33,7 +33,7 @@ protected function setUp() { // FileStorage::listAll() requires other configuration data to exist. $this->storage->write('system.performance', $this->config('system.performance')->get()); - $this->storage->write('core.extension', array('module' => array())); + $this->storage->write('core.extension', ['module' => []]); } protected function read($name) { @@ -57,10 +57,10 @@ protected function delete($name) { * Tests the FileStorage::listAll method with a relative and absolute path. */ public function testlistAll() { - $expected_files = array( + $expected_files = [ 'core.extension', 'system.performance', - ); + ]; $config_files = $this->storage->listAll(); $this->assertIdentical($config_files, $expected_files, 'Relative path, two config files found.'); @@ -68,8 +68,8 @@ public function testlistAll() { // @todo https://www.drupal.org/node/2666954 FileStorage::listAll() is // case-sensitive. However, \Drupal\Core\Config\DatabaseStorage::listAll() // is case-insensitive. - $this->assertIdentical(['system.performance'], $this->storage->listAll('system'), 'The FileStorage::listAll() with prefix works.'); - $this->assertIdentical([], $this->storage->listAll('System'), 'The FileStorage::listAll() is case sensitive.'); + $this->assertSame(['system.performance'], $this->storage->listAll('system'), 'The FileStorage::listAll() with prefix works.'); + $this->assertSame([], $this->storage->listAll('System'), 'The FileStorage::listAll() is case sensitive.'); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php index 84b4f564..44ce4958 100644 --- a/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php +++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php @@ -19,8 +19,8 @@ protected function setUp() { parent::setUp(); $this->storage = new StorageReplaceDataWrapper($this->container->get('config.storage')); // ::listAll() verifications require other configuration data to exist. - $this->storage->write('system.performance', array()); - $this->storage->replaceData('system.performance', array('foo' => 'bar')); + $this->storage->write('system.performance', []); + $this->storage->replaceData('system.performance', ['foo' => 'bar']); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Database/AlterTest.php b/core/tests/Drupal/KernelTests/Core/Database/AlterTest.php index c5f9e9f4..e2a6589d 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/AlterTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/AlterTest.php @@ -13,7 +13,7 @@ class AlterTest extends DatabaseTestBase { /** * Tests that we can do basic alters. */ - function testSimpleAlter() { + public function testSimpleAlter() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -27,7 +27,7 @@ function testSimpleAlter() { /** * Tests that we can alter the joins on a query. */ - function testAlterWithJoin() { + public function testAlterWithJoin() { $query = db_select('test_task'); $tid_field = $query->addField('test_task', 'tid'); $task_field = $query->addField('test_task', 'task'); @@ -51,7 +51,7 @@ function testAlterWithJoin() { /** * Tests that we can alter a query's conditionals. */ - function testAlterChangeConditional() { + public function testAlterChangeConditional() { $query = db_select('test_task'); $tid_field = $query->addField('test_task', 'tid'); $pid_field = $query->addField('test_task', 'pid'); @@ -76,7 +76,7 @@ function testAlterChangeConditional() { /** * Tests that we can alter the fields of a query. */ - function testAlterChangeFields() { + public function testAlterChangeFields() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); @@ -91,7 +91,7 @@ function testAlterChangeFields() { /** * Tests that we can alter expressions in the query. */ - function testAlterExpression() { + public function testAlterExpression() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_field = $query->addExpression("age*2", 'double_age'); @@ -111,7 +111,7 @@ function testAlterExpression() { * * This also tests hook_query_TAG_alter(). */ - function testAlterRemoveRange() { + public function testAlterRemoveRange() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -126,7 +126,7 @@ function testAlterRemoveRange() { /** * Tests that we can do basic alters on subqueries. */ - function testSimpleAlterSubquery() { + public function testSimpleAlterSubquery() { // Create a sub-query with an alter tag. $subquery = db_select('test', 'p'); $subquery->addField('p', 'name'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/BasicSyntaxTest.php b/core/tests/Drupal/KernelTests/Core/Database/BasicSyntaxTest.php index eaf50e50..53a87b7d 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/BasicSyntaxTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/BasicSyntaxTest.php @@ -15,63 +15,63 @@ class BasicSyntaxTest extends DatabaseTestBase { /** * Tests string concatenation. */ - function testConcatLiterals() { - $result = db_query('SELECT CONCAT(:a1, CONCAT(:a2, CONCAT(:a3, CONCAT(:a4, :a5))))', array( + public function testConcatLiterals() { + $result = db_query('SELECT CONCAT(:a1, CONCAT(:a2, CONCAT(:a3, CONCAT(:a4, :a5))))', [ ':a1' => 'This', ':a2' => ' ', ':a3' => 'is', ':a4' => ' a ', ':a5' => 'test.', - )); + ]); $this->assertIdentical($result->fetchField(), 'This is a test.', 'Basic CONCAT works.'); } /** * Tests string concatenation with field values. */ - function testConcatFields() { - $result = db_query('SELECT CONCAT(:a1, CONCAT(name, CONCAT(:a2, CONCAT(age, :a3)))) FROM {test} WHERE age = :age', array( + public function testConcatFields() { + $result = db_query('SELECT CONCAT(:a1, CONCAT(name, CONCAT(:a2, CONCAT(age, :a3)))) FROM {test} WHERE age = :age', [ ':a1' => 'The age of ', ':a2' => ' is ', ':a3' => '.', ':age' => 25, - )); + ]); $this->assertIdentical($result->fetchField(), 'The age of John is 25.', 'Field CONCAT works.'); } /** * Tests string concatenation with separator. */ - function testConcatWsLiterals() { - $result = db_query("SELECT CONCAT_WS(', ', :a1, NULL, :a2, :a3, :a4)", array( + public function testConcatWsLiterals() { + $result = db_query("SELECT CONCAT_WS(', ', :a1, NULL, :a2, :a3, :a4)", [ ':a1' => 'Hello', ':a2' => NULL, ':a3' => '', ':a4' => 'world.', - )); + ]); $this->assertIdentical($result->fetchField(), 'Hello, , world.'); } /** * Tests string concatenation with separator, with field values. */ - function testConcatWsFields() { - $result = db_query("SELECT CONCAT_WS('-', :a1, name, :a2, age) FROM {test} WHERE age = :age", array( + public function testConcatWsFields() { + $result = db_query("SELECT CONCAT_WS('-', :a1, name, :a2, age) FROM {test} WHERE age = :age", [ ':a1' => 'name', ':a2' => 'age', ':age' => 25, - )); + ]); $this->assertIdentical($result->fetchField(), 'name-John-age-25'); } /** * Tests escaping of LIKE wildcards. */ - function testLikeEscape() { + public function testLikeEscape() { db_insert('test') - ->fields(array( + ->fields([ 'name' => 'Ring_', - )) + ]) ->execute(); // Match both "Ringo" and "Ring_". @@ -93,15 +93,15 @@ function testLikeEscape() { /** * Tests a LIKE query containing a backslash. */ - function testLikeBackslash() { + public function testLikeBackslash() { db_insert('test') - ->fields(array('name')) - ->values(array( + ->fields(['name']) + ->values([ 'name' => 'abcde\f', - )) - ->values(array( + ]) + ->values([ 'name' => 'abc%\_', - )) + ]) ->execute(); // Match both rows using a LIKE expression with two wildcards and a verbatim diff --git a/core/tests/Drupal/KernelTests/Core/Database/CaseSensitivityTest.php b/core/tests/Drupal/KernelTests/Core/Database/CaseSensitivityTest.php index 35fdb4d9..cd241e51 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/CaseSensitivityTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/CaseSensitivityTest.php @@ -11,20 +11,21 @@ class CaseSensitivityTest extends DatabaseTestBase { /** * Tests BINARY collation in MySQL. */ - function testCaseSensitiveInsert() { + public function testCaseSensitiveInsert() { $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); db_insert('test') - ->fields(array( - 'name' => 'john', // <- A record already exists with name 'John'. + ->fields([ + // A record already exists with name 'John'. + 'name' => 'john', 'age' => 2, 'job' => 'Baby', - )) + ]) ->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); - $this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'john'))->fetchField(); + $this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.'); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'john'])->fetchField(); $this->assertIdentical($saved_age, '2', 'Can retrieve after inserting.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php b/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php index 0cc3627f..47e11dad 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php @@ -15,7 +15,7 @@ class ConnectionTest extends DatabaseTestBase { /** * Tests that connections return appropriate connection objects. */ - function testConnectionRouting() { + public function testConnectionRouting() { // Clone the primary credentials to a replica connection. // Note this will result in two independent connection objects that happen // to point to the same place. @@ -32,24 +32,24 @@ function testConnectionRouting() { // Try to open those targets another time, that should return the same objects. $db1b = Database::getConnection('default', 'default'); $db2b = Database::getConnection('replica', 'default'); - $this->assertIdentical($db1, $db1b, 'A second call to getConnection() returns the same object.'); - $this->assertIdentical($db2, $db2b, 'A second call to getConnection() returns the same object.'); + $this->assertSame($db1, $db1b, 'A second call to getConnection() returns the same object.'); + $this->assertSame($db2, $db2b, 'A second call to getConnection() returns the same object.'); // Try to open an unknown target. $unknown_target = $this->randomMachineName(); $db3 = Database::getConnection($unknown_target, 'default'); $this->assertNotNull($db3, 'Opening an unknown target returns a real connection object.'); - $this->assertIdentical($db1, $db3, 'An unknown target opens the default connection.'); + $this->assertSame($db1, $db3, 'An unknown target opens the default connection.'); // Try to open that unknown target another time, that should return the same object. $db3b = Database::getConnection($unknown_target, 'default'); - $this->assertIdentical($db3, $db3b, 'A second call to getConnection() returns the same object.'); + $this->assertSame($db3, $db3b, 'A second call to getConnection() returns the same object.'); } /** * Tests that connections return appropriate connection objects. */ - function testConnectionRoutingOverride() { + public function testConnectionRoutingOverride() { // Clone the primary credentials to a replica connection. // Note this will result in two independent connection objects that happen // to point to the same place. @@ -61,13 +61,13 @@ function testConnectionRoutingOverride() { $db1 = Database::getConnection('default', 'default'); $db2 = Database::getConnection('replica', 'default'); - $this->assertIdentical($db1, $db2, 'Both targets refer to the same connection.'); + $this->assertSame($db1, $db2, 'Both targets refer to the same connection.'); } /** * Tests the closing of a database connection. */ - function testConnectionClosing() { + public function testConnectionClosing() { // Open the default target so we have an object to compare. $db1 = Database::getConnection('default', 'default'); @@ -82,7 +82,7 @@ function testConnectionClosing() { /** * Tests the connection options of the active database. */ - function testConnectionOptions() { + public function testConnectionOptions() { $connection_info = Database::getConnectionInfo('default'); // Be sure we're connected to the default database. @@ -131,7 +131,7 @@ public function testMultipleStatementsForNewPhp() { try { $db->query('SELECT * FROM {test}; SELECT * FROM {test_people}', [], - [ 'allow_delimiter_in_query' => TRUE ] + ['allow_delimiter_in_query' => TRUE] ); $this->fail('No PDO exception thrown for multiple statements.'); } @@ -168,9 +168,9 @@ public function testPostgresqlReservedWords() { $stmt->execute(); foreach ($stmt->fetchAllAssoc('word') as $word => $row) { $expected = '"' . $word . '"'; - $this->assertIdentical($db->escapeTable($word), $expected, format_string('The reserved word %word was correctly escaped when used as a table name.', array('%word' => $word))); - $this->assertIdentical($db->escapeField($word), $expected, format_string('The reserved word %word was correctly escaped when used as a column name.', array('%word' => $word))); - $this->assertIdentical($db->escapeAlias($word), $expected, format_string('The reserved word %word was correctly escaped when used as an alias.', array('%word' => $word))); + $this->assertIdentical($db->escapeTable($word), $expected, format_string('The reserved word %word was correctly escaped when used as a table name.', ['%word' => $word])); + $this->assertIdentical($db->escapeField($word), $expected, format_string('The reserved word %word was correctly escaped when used as a column name.', ['%word' => $word])); + $this->assertIdentical($db->escapeAlias($word), $expected, format_string('The reserved word %word was correctly escaped when used as an alias.', ['%word' => $word])); } } diff --git a/core/tests/Drupal/KernelTests/Core/Database/ConnectionUnitTest.php b/core/tests/Drupal/KernelTests/Core/Database/ConnectionUnitTest.php index e315f965..f73f4155 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/ConnectionUnitTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/ConnectionUnitTest.php @@ -75,7 +75,7 @@ protected function getConnectionID() { */ protected function assertConnection($id) { $list = $this->monitor->query('SHOW PROCESSLIST')->fetchAllKeyed(0, 0); - return $this->assertTrue(isset($list[$id]), format_string('Connection ID @id found.', array('@id' => $id))); + return $this->assertTrue(isset($list[$id]), format_string('Connection ID @id found.', ['@id' => $id])); } /** @@ -86,7 +86,7 @@ protected function assertConnection($id) { */ protected function assertNoConnection($id) { $list = $this->monitor->query('SHOW PROCESSLIST')->fetchAllKeyed(0, 0); - return $this->assertFalse(isset($list[$id]), format_string('Connection ID @id not found.', array('@id' => $id))); + return $this->assertFalse(isset($list[$id]), format_string('Connection ID @id not found.', ['@id' => $id])); } /** @@ -94,7 +94,7 @@ protected function assertNoConnection($id) { * * @todo getConnectionID() executes a query. */ - function testOpenClose() { + public function testOpenClose() { if ($this->skipTest) { return; } @@ -118,7 +118,7 @@ function testOpenClose() { /** * Tests Database::closeConnection() with a query. */ - function testOpenQueryClose() { + public function testOpenQueryClose() { if ($this->skipTest) { return; } @@ -145,7 +145,7 @@ function testOpenQueryClose() { /** * Tests Database::closeConnection() with a query and custom prefetch method. */ - function testOpenQueryPrefetchClose() { + public function testOpenQueryPrefetchClose() { if ($this->skipTest) { return; } @@ -172,7 +172,7 @@ function testOpenQueryPrefetchClose() { /** * Tests Database::closeConnection() with a select query. */ - function testOpenSelectQueryClose() { + public function testOpenSelectQueryClose() { if ($this->skipTest) { return; } @@ -186,18 +186,18 @@ function testOpenSelectQueryClose() { // Create a table. $name = 'foo'; - Database::getConnection($this->target, $this->key)->schema()->createTable($name, array( - 'fields' => array( - 'name' => array( + Database::getConnection($this->target, $this->key)->schema()->createTable($name, [ + 'fields' => [ + 'name' => [ 'type' => 'varchar', 'length' => 255, - ), - ), - )); + ], + ], + ]); // Execute a query. Database::getConnection($this->target, $this->key)->select('foo', 'f') - ->fields('f', array('name')) + ->fields('f', ['name']) ->execute() ->fetchAll(); @@ -221,6 +221,12 @@ public function testConnectionOpen() { $reflection = new \ReflectionObject($connection); $connection_property = $reflection->getProperty('connection'); $connection_property->setAccessible(TRUE); + // Skip this test when a database driver does not implement PDO. + // An alternative database driver that does not implement PDO + // should implement its own connection test. + if (get_class($connection_property->getValue($connection)) !== 'PDO') { + $this->markTestSkipped('Ignored PDO connection unit test for this driver because it does not implement PDO.'); + } $error_mode = $connection_property->getValue($connection) ->getAttribute(\PDO::ATTR_ERRMODE); $this->assertEqual($error_mode, \PDO::ERRMODE_EXCEPTION, 'Ensure the default error mode is set to exception.'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/DatabaseTestBase.php b/core/tests/Drupal/KernelTests/Core/Database/DatabaseTestBase.php index f8c8c3dc..6fcfaa44 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/DatabaseTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Database/DatabaseTestBase.php @@ -12,11 +12,11 @@ */ abstract class DatabaseTestBase extends KernelTestBase { - public static $modules = array('database_test'); + public static $modules = ['database_test']; protected function setUp() { parent::setUp(); - $this->installSchema('database_test', array( + $this->installSchema('database_test', [ 'test', 'test_people', 'test_people_copy', @@ -27,120 +27,120 @@ protected function setUp() { 'test_serialized', 'test_special_columns', 'TEST_UPPERCASE', - )); + ]); self::addSampleData(); } /** * Sets up tables for NULL handling. */ - function ensureSampleDataNull() { + public function ensureSampleDataNull() { db_insert('test_null') - ->fields(array('name', 'age')) - ->values(array( + ->fields(['name', 'age']) + ->values([ 'name' => 'Kermit', 'age' => 25, - )) - ->values(array( + ]) + ->values([ 'name' => 'Fozzie', 'age' => NULL, - )) - ->values(array( + ]) + ->values([ 'name' => 'Gonzo', 'age' => 27, - )) + ]) ->execute(); } /** * Sets up our sample data. */ - static function addSampleData() { + public static function addSampleData() { // We need the IDs, so we can't use a multi-insert here. $john = db_insert('test') - ->fields(array( + ->fields([ 'name' => 'John', 'age' => 25, 'job' => 'Singer', - )) + ]) ->execute(); $george = db_insert('test') - ->fields(array( + ->fields([ 'name' => 'George', 'age' => 27, 'job' => 'Singer', - )) + ]) ->execute(); db_insert('test') - ->fields(array( + ->fields([ 'name' => 'Ringo', 'age' => 28, 'job' => 'Drummer', - )) + ]) ->execute(); $paul = db_insert('test') - ->fields(array( + ->fields([ 'name' => 'Paul', 'age' => 26, 'job' => 'Songwriter', - )) + ]) ->execute(); db_insert('test_people') - ->fields(array( + ->fields([ 'name' => 'Meredith', 'age' => 30, 'job' => 'Speaker', - )) + ]) ->execute(); db_insert('test_task') - ->fields(array('pid', 'task', 'priority')) - ->values(array( + ->fields(['pid', 'task', 'priority']) + ->values([ 'pid' => $john, 'task' => 'eat', 'priority' => 3, - )) - ->values(array( + ]) + ->values([ 'pid' => $john, 'task' => 'sleep', 'priority' => 4, - )) - ->values(array( + ]) + ->values([ 'pid' => $john, 'task' => 'code', 'priority' => 1, - )) - ->values(array( + ]) + ->values([ 'pid' => $george, 'task' => 'sing', 'priority' => 2, - )) - ->values(array( + ]) + ->values([ 'pid' => $george, 'task' => 'sleep', 'priority' => 2, - )) - ->values(array( + ]) + ->values([ 'pid' => $paul, 'task' => 'found new band', 'priority' => 1, - )) - ->values(array( + ]) + ->values([ 'pid' => $paul, 'task' => 'perform at superbowl', 'priority' => 3, - )) + ]) ->execute(); db_insert('test_special_columns') - ->fields(array( + ->fields([ 'id' => 1, 'offset' => 'Offset value 1', - )) + ]) ->execute(); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php b/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php index 1545dd9d..8d736613 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/DeleteTruncateTest.php @@ -20,13 +20,13 @@ class DeleteTruncateTest extends DatabaseTestBase { /** * Confirms that we can use a subselect in a delete successfully. */ - function testSubselectDelete() { + public function testSubselectDelete() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_task}')->fetchField(); $pid_to_delete = db_query("SELECT * FROM {test_task} WHERE task = 'sleep'")->fetchField(); $subquery = db_select('test', 't') - ->fields('t', array('id')) - ->condition('t.id', array($pid_to_delete), 'IN'); + ->fields('t', ['id']) + ->condition('t.id', [$pid_to_delete], 'IN'); $delete = db_delete('test_task') ->condition('task', 'sleep') ->condition('pid', $subquery, 'IN'); @@ -41,7 +41,7 @@ function testSubselectDelete() { /** * Confirms that we can delete a single record successfully. */ - function testSimpleDelete() { + public function testSimpleDelete() { $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); $num_deleted = db_delete('test') @@ -56,7 +56,7 @@ function testSimpleDelete() { /** * Confirms that we can truncate a whole table successfully. */ - function testTruncate() { + public function testTruncate() { $num_records_before = db_query("SELECT COUNT(*) FROM {test}")->fetchField(); $this->assertTrue($num_records_before > 0, 'The table is not empty.'); @@ -69,7 +69,7 @@ function testTruncate() { /** * Confirms that we can delete a single special column name record successfully. */ - function testSpecialColumnDelete() { + public function testSpecialColumnDelete() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_special_columns}')->fetchField(); $num_deleted = db_delete('test_special_columns') diff --git a/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php b/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php index e4f4d670..d0439c5f 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php @@ -4,7 +4,7 @@ use Drupal\Core\Database\RowCountException; use Drupal\Core\Database\StatementInterface; -use Drupal\system\Tests\Database\FakeRecord; +use Drupal\Tests\system\Functional\Database\FakeRecord; /** * Tests the Database system's various fetch capabilities. @@ -18,9 +18,9 @@ class FetchTest extends DatabaseTestBase { /** * Confirms that we can fetch a record properly in default object mode. */ - function testQueryFetchDefault() { - $records = array(); - $result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25)); + public function testQueryFetchDefault() { + $records = []; + $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25]); $this->assertTrue($result instanceof StatementInterface, 'Result set is a Drupal statement object.'); foreach ($result as $record) { $records[] = $record; @@ -34,9 +34,9 @@ function testQueryFetchDefault() { /** * Confirms that we can fetch a record to an object explicitly. */ - function testQueryFetchObject() { - $records = array(); - $result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_OBJ)); + public function testQueryFetchObject() { + $records = []; + $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_OBJ]); foreach ($result as $record) { $records[] = $record; $this->assertTrue(is_object($record), 'Record is an object.'); @@ -49,9 +49,9 @@ function testQueryFetchObject() { /** * Confirms that we can fetch a record to an associative array explicitly. */ - function testQueryFetchArray() { - $records = array(); - $result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_ASSOC)); + public function testQueryFetchArray() { + $records = []; + $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_ASSOC]); foreach ($result as $record) { $records[] = $record; if ($this->assertTrue(is_array($record), 'Record is an array.')) { @@ -67,9 +67,9 @@ function testQueryFetchArray() { * * @see \Drupal\system\Tests\Database\FakeRecord */ - function testQueryFetchClass() { - $records = array(); - $result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => 'Drupal\system\Tests\Database\FakeRecord')); + public function testQueryFetchClass() { + $records = []; + $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => FakeRecord::class]); foreach ($result as $record) { $records[] = $record; if ($this->assertTrue($record instanceof FakeRecord, 'Record is an object of class FakeRecord.')) { @@ -83,9 +83,9 @@ function testQueryFetchClass() { /** * Confirms that we can fetch a record into an indexed array explicitly. */ - function testQueryFetchNum() { - $records = array(); - $result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_NUM)); + public function testQueryFetchNum() { + $records = []; + $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_NUM]); foreach ($result as $record) { $records[] = $record; if ($this->assertTrue(is_array($record), 'Record is an array.')) { @@ -99,9 +99,9 @@ function testQueryFetchNum() { /** * Confirms that we can fetch a record into a doubly-keyed array explicitly. */ - function testQueryFetchBoth() { - $records = array(); - $result = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 25), array('fetch' => \PDO::FETCH_BOTH)); + public function testQueryFetchBoth() { + $records = []; + $result = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 25], ['fetch' => \PDO::FETCH_BOTH]); foreach ($result as $record) { $records[] = $record; if ($this->assertTrue(is_array($record), 'Record is an array.')) { @@ -129,12 +129,12 @@ public function testQueryFetchAllColumn() { /** * Confirms that we can fetch an entire column of a result set at once. */ - function testQueryFetchCol() { - $result = db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25)); + public function testQueryFetchCol() { + $result = db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25]); $column = $result->fetchCol(); $this->assertIdentical(count($column), 3, 'fetchCol() returns the right number of records.'); - $result = db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25)); + $result = db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25]); $i = 0; foreach ($result as $record) { $this->assertIdentical($record->name, $column[$i++], 'Column matches direct access.'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/InsertDefaultsTest.php b/core/tests/Drupal/KernelTests/Core/Database/InsertDefaultsTest.php index 6e0363ae..b5963cf4 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/InsertDefaultsTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/InsertDefaultsTest.php @@ -14,20 +14,20 @@ class InsertDefaultsTest extends DatabaseTestBase { /** * Tests that we can run a query that uses default values for everything. */ - function testDefaultInsert() { - $query = db_insert('test')->useDefaults(array('job')); + public function testDefaultInsert() { + $query = db_insert('test')->useDefaults(['job']); $id = $query->execute(); $schema = drupal_get_module_schema('database_test', 'test'); - $job = db_query('SELECT job FROM {test} WHERE id = :id', array(':id' => $id))->fetchField(); + $job = db_query('SELECT job FROM {test} WHERE id = :id', [':id' => $id])->fetchField(); $this->assertEqual($job, $schema['fields']['job']['default'], 'Default field value is set.'); } /** * Tests that no action will be preformed if no fields are specified. */ - function testDefaultEmptyInsert() { + public function testDefaultEmptyInsert() { $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField(); try { @@ -40,21 +40,21 @@ function testDefaultEmptyInsert() { } $num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField(); - $this->assertIdentical($num_records_before, $num_records_after, 'Do nothing as no fields are specified.'); + $this->assertSame($num_records_before, $num_records_after, 'Do nothing as no fields are specified.'); } /** * Tests that we can insert fields with values and defaults in the same query. */ - function testDefaultInsertWithFields() { + public function testDefaultInsertWithFields() { $query = db_insert('test') - ->fields(array('name' => 'Bob')) - ->useDefaults(array('job')); + ->fields(['name' => 'Bob']) + ->useDefaults(['job']); $id = $query->execute(); $schema = drupal_get_module_schema('database_test', 'test'); - $job = db_query('SELECT job FROM {test} WHERE id = :id', array(':id' => $id))->fetchField(); + $job = db_query('SELECT job FROM {test} WHERE id = :id', [':id' => $id])->fetchField(); $this->assertEqual($job, $schema['fields']['job']['default'], 'Default field value is set.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/InsertLobTest.php b/core/tests/Drupal/KernelTests/Core/Database/InsertLobTest.php index cb41dc03..e7a3107a 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/InsertLobTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/InsertLobTest.php @@ -12,27 +12,27 @@ class InsertLobTest extends DatabaseTestBase { /** * Tests that we can insert a single blob field successfully. */ - function testInsertOneBlob() { + public function testInsertOneBlob() { $data = "This is\000a test."; $this->assertTrue(strlen($data) === 15, 'Test data contains a NULL.'); $id = db_insert('test_one_blob') - ->fields(array('blob1' => $data)) + ->fields(['blob1' => $data]) ->execute(); - $r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', array(':id' => $id))->fetchAssoc(); - $this->assertTrue($r['blob1'] === $data, format_string('Can insert a blob: id @id, @data.', array('@id' => $id, '@data' => serialize($r)))); + $r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', [':id' => $id])->fetchAssoc(); + $this->assertTrue($r['blob1'] === $data, format_string('Can insert a blob: id @id, @data.', ['@id' => $id, '@data' => serialize($r)])); } /** * Tests that we can insert multiple blob fields in the same query. */ - function testInsertMultipleBlob() { + public function testInsertMultipleBlob() { $id = db_insert('test_two_blobs') - ->fields(array( + ->fields([ 'blob1' => 'This is', 'blob2' => 'a test', - )) + ]) ->execute(); - $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', array(':id' => $id))->fetchAssoc(); + $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', [':id' => $id])->fetchAssoc(); $this->assertTrue($r['blob1'] === 'This is' && $r['blob2'] === 'a test', 'Can insert multiple blobs per row.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/InsertTest.php b/core/tests/Drupal/KernelTests/Core/Database/InsertTest.php index d703f9d3..3812151b 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/InsertTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/InsertTest.php @@ -12,135 +12,136 @@ class InsertTest extends DatabaseTestBase { /** * Tests very basic insert functionality. */ - function testSimpleInsert() { + public function testSimpleInsert() { $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); $query = db_insert('test'); - $query->fields(array( + $query->fields([ 'name' => 'Yoko', 'age' => '29', - )); + ]); // Check how many records are queued for insertion. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.'); $query->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); - $this->assertIdentical($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Yoko'))->fetchField(); + $this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.'); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Yoko'])->fetchField(); $this->assertIdentical($saved_age, '29', 'Can retrieve after inserting.'); } /** * Tests that we can insert multiple records in one query object. */ - function testMultiInsert() { + public function testMultiInsert() { $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField(); $query = db_insert('test'); - $query->fields(array( + $query->fields([ 'name' => 'Larry', 'age' => '30', - )); + ]); // We should be able to specify values in any order if named. - $query->values(array( + $query->values([ 'age' => '31', 'name' => 'Curly', - )); + ]); // Check how many records are queued for insertion. $this->assertIdentical($query->count(), 2, 'Two records are queued for insertion.'); // We should be able to say "use the field order". // This is not the recommended mechanism for most cases, but it should work. - $query->values(array('Moe', '32')); + $query->values(['Moe', '32']); // Check how many records are queued for insertion. $this->assertIdentical($query->count(), 3, 'Three records are queued for insertion.'); $query->execute(); $num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField(); - $this->assertIdentical($num_records_before + 3, $num_records_after, 'Record inserts correctly.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Larry'))->fetchField(); + $this->assertSame($num_records_before + 3, $num_records_after, 'Record inserts correctly.'); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField(); $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Curly'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField(); $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Moe'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField(); $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.'); } /** * Tests that an insert object can be reused with new data after it executes. */ - function testRepeatedInsert() { + public function testRepeatedInsert() { $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); $query = db_insert('test'); - $query->fields(array( + $query->fields([ 'name' => 'Larry', 'age' => '30', - )); + ]); // Check how many records are queued for insertion. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.'); - $query->execute(); // This should run the insert, but leave the fields intact. + // This should run the insert, but leave the fields intact. + $query->execute(); // We should be able to specify values in any order if named. - $query->values(array( + $query->values([ 'age' => '31', 'name' => 'Curly', - )); + ]); // Check how many records are queued for insertion. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.'); $query->execute(); // We should be able to say "use the field order". - $query->values(array('Moe', '32')); + $query->values(['Moe', '32']); // Check how many records are queued for insertion. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.'); $query->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); - $this->assertIdentical((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Larry'))->fetchField(); + $this->assertSame((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.'); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField(); $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Curly'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField(); $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Moe'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField(); $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.'); } /** * Tests that we can specify fields without values and specify values later. */ - function testInsertFieldOnlyDefinition() { + public function testInsertFieldOnlyDefinition() { // This is useful for importers, when we want to create a query and define // its fields once, then loop over a multi-insert execution. db_insert('test') - ->fields(array('name', 'age')) - ->values(array('Larry', '30')) - ->values(array('Curly', '31')) - ->values(array('Moe', '32')) + ->fields(['name', 'age']) + ->values(['Larry', '30']) + ->values(['Curly', '31']) + ->values(['Moe', '32']) ->execute(); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Larry'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField(); $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Curly'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField(); $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Moe'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField(); $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.'); } /** * Tests that inserts return the proper auto-increment ID. */ - function testInsertLastInsertID() { + public function testInsertLastInsertID() { $id = db_insert('test') - ->fields(array( + ->fields([ 'name' => 'Larry', 'age' => '30', - )) + ]) ->execute(); $this->assertIdentical($id, '5', 'Auto-increment ID returned successfully.'); @@ -149,14 +150,14 @@ function testInsertLastInsertID() { /** * Tests that the INSERT INTO ... SELECT (fields) ... syntax works. */ - function testInsertSelectFields() { + public function testInsertSelectFields() { $query = db_select('test_people', 'tp'); // The query builder will always append expressions after fields. // Add the expression first to test that the insert fields are correctly // re-ordered. $query->addExpression('tp.age', 'age'); $query - ->fields('tp', array('name', 'job')) + ->fields('tp', ['name', 'job']) ->condition('tp.name', 'Meredith'); // The resulting query should be equivalent to: @@ -168,14 +169,14 @@ function testInsertSelectFields() { ->from($query) ->execute(); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Meredith'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Meredith'])->fetchField(); $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.'); } /** * Tests that the INSERT INTO ... SELECT * ... syntax works. */ - function testInsertSelectAll() { + public function testInsertSelectAll() { $query = db_select('test_people', 'tp') ->fields('tp') ->condition('tp.name', 'Meredith'); @@ -189,21 +190,21 @@ function testInsertSelectAll() { ->from($query) ->execute(); - $saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', array(':name' => 'Meredith'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', [':name' => 'Meredith'])->fetchField(); $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.'); } /** * Tests that we can INSERT INTO a special named column. */ - function testSpecialColumnInsert() { + public function testSpecialColumnInsert() { $id = db_insert('test_special_columns') - ->fields(array( + ->fields([ 'id' => 2, 'offset' => 'Offset value 2', - )) + ]) ->execute(); - $saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', array(':id' => 2))->fetchField(); + $saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', [':id' => 2])->fetchField(); $this->assertIdentical($saved_value, 'Offset value 2', 'Can retrieve special column name value after inserting.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php b/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php index 774a20b8..371800b7 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php @@ -14,31 +14,32 @@ class InvalidDataTest extends DatabaseTestBase { /** * Tests aborting of traditional SQL database systems with invalid data. */ - function testInsertDuplicateData() { + public function testInsertDuplicateData() { // Try to insert multiple records where at least one has bad data. try { db_insert('test') - ->fields(array('name', 'age', 'job')) - ->values(array( + ->fields(['name', 'age', 'job']) + ->values([ 'name' => 'Elvis', 'age' => 63, 'job' => 'Singer', - ))->values(array( - 'name' => 'John', // <-- Duplicate value on unique field. + ])->values([ + // Duplicate value on unique field. + 'name' => 'John', 'age' => 17, 'job' => 'Consultant', - )) - ->values(array( + ]) + ->values([ 'name' => 'Frank', 'age' => 75, 'job' => 'Singer', - )) + ]) ->execute(); $this->fail('Insert succeeded when it should not have.'); } catch (IntegrityConstraintViolationException $e) { // Check if the first record was inserted. - $name = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => 63))->fetchField(); + $name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 63])->fetchField(); if ($name == 'Elvis') { if (!Database::getConnection()->supportsTransactions()) { @@ -58,8 +59,85 @@ function testInsertDuplicateData() { // Ensure the other values were not inserted. $record = db_select('test') - ->fields('test', array('name', 'age')) - ->condition('age', array(17, 75), 'IN') + ->fields('test', ['name', 'age']) + ->condition('age', [17, 75], 'IN') + ->execute()->fetchObject(); + + $this->assertFalse($record, 'The rest of the insert aborted as expected.'); + } + } + + /** + * Tests inserting with invalid data from a select query. + */ + public function testInsertDuplicateDataFromSelect() { + // Insert multiple records in 'test_people' where one has bad data + // (duplicate key). A 'Meredith' record has already been inserted + // in ::setUp. + db_insert('test_people') + ->fields(['name', 'age', 'job']) + ->values([ + 'name' => 'Elvis', + 'age' => 63, + 'job' => 'Singer', + ])->values([ + // Duplicate value on unique field 'name' for later INSERT in 'test' + // table. + 'name' => 'John', + 'age' => 17, + 'job' => 'Consultant', + ]) + ->values([ + 'name' => 'Frank', + 'age' => 75, + 'job' => 'Bass', + ]) + ->execute(); + + try { + // Define the subselect query. Add ORDER BY to ensure we have consistent + // order in results. Will return: + // 0 => [name] => Elvis, [age] => 63, [job] => Singer + // 1 => [name] => Frank, [age] => 75, [job] => Bass + // 2 => [name] => John, [age] => 17, [job] => Consultant + // 3 => [name] => Meredith, [age] => 30, [job] => Speaker + // Records 0 and 1 should pass, record 2 should lead to integrity + // constraint violation. + $query = db_select('test_people', 'tp') + ->fields('tp', ['name', 'age', 'job']) + ->orderBy('name'); + + // Try inserting from the subselect. + db_insert('test') + ->from($query) + ->execute(); + + $this->fail('Insert succeeded when it should not have.'); + } + catch (IntegrityConstraintViolationException $e) { + // Check if the second record was inserted. + $name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 75])->fetchField(); + + if ($name == 'Frank') { + if (!Database::getConnection()->supportsTransactions()) { + // This is an expected fail. + // Database engines that don't support transactions can leave partial + // inserts in place when an error occurs. This is the case for MySQL + // when running on a MyISAM table. + $this->pass("The whole transaction has not been rolled-back when a duplicate key insert occurs, this is expected because the database doesn't support transactions"); + } + else { + $this->fail('The whole transaction is rolled back when a duplicate key insert occurs.'); + } + } + else { + $this->pass('The whole transaction is rolled back when a duplicate key insert occurs.'); + } + + // Ensure the values for records 2 and 3 were not inserted. + $record = db_select('test') + ->fields('test', ['name', 'age']) + ->condition('age', [17, 30], 'IN') ->execute()->fetchObject(); $this->assertFalse($record, 'The rest of the insert aborted as expected.'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/LargeQueryTest.php b/core/tests/Drupal/KernelTests/Core/Database/LargeQueryTest.php index 4b24ebef..a93d1fc8 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/LargeQueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/LargeQueryTest.php @@ -16,7 +16,7 @@ class LargeQueryTest extends DatabaseTestBase { /** * Tests truncation of messages when max_allowed_packet exception occurs. */ - function testMaxAllowedPacketQueryTruncating() { + public function testMaxAllowedPacketQueryTruncating() { // This test only makes sense if we are running on a MySQL database. // Test if we are. $database = Database::getConnectionInfo('default'); @@ -29,7 +29,7 @@ function testMaxAllowedPacketQueryTruncating() { if (Environment::checkMemoryLimit($max_allowed_packet + (16 * 1024 * 1024))) { $long_name = str_repeat('a', $max_allowed_packet + 1); try { - db_query('SELECT name FROM {test} WHERE name = :name', array(':name' => $long_name)); + db_query('SELECT name FROM {test} WHERE name = :name', [':name' => $long_name]); $this->fail("An exception should be thrown for queries larger than 'max_allowed_packet'"); } catch (DatabaseException $e) { diff --git a/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php b/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php index c354c829..28d9ff2b 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php @@ -14,14 +14,14 @@ class LoggingTest extends DatabaseTestBase { /** * Tests that we can log the existence of a query. */ - function testEnableLogging() { + public function testEnableLogging() { Database::startLog('testing'); - db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol(); - db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchCol(); + db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol(); + db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchCol(); // Trigger a call that does not have file in the backtrace. - call_user_func_array('db_query', array('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo')))->fetchCol(); + call_user_func_array('db_query', ['SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo']])->fetchCol(); $queries = Database::getLog('testing', 'default'); @@ -35,14 +35,14 @@ function testEnableLogging() { /** * Tests that we can run two logs in parallel. */ - function testEnableMultiLogging() { + public function testEnableMultiLogging() { Database::startLog('testing1'); - db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol(); + db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol(); Database::startLog('testing2'); - db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchCol(); + db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchCol(); $queries1 = Database::getLog('testing1'); $queries2 = Database::getLog('testing2'); @@ -54,7 +54,7 @@ function testEnableMultiLogging() { /** * Tests logging queries against multiple targets on the same connection. */ - function testEnableTargetLogging() { + public function testEnableTargetLogging() { // Clone the primary credentials to a replica connection and to another fake // connection. $connection_info = Database::getConnectionInfo('default'); @@ -62,9 +62,9 @@ function testEnableTargetLogging() { Database::startLog('testing1'); - db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol(); + db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol(); - db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'), array('target' => 'replica'));//->fetchCol(); + db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica'])->fetchCol(); $queries1 = Database::getLog('testing1'); @@ -80,17 +80,17 @@ function testEnableTargetLogging() { * a fake target so the query should fall back to running on the default * target. */ - function testEnableTargetLoggingNoTarget() { + public function testEnableTargetLoggingNoTarget() { Database::startLog('testing1'); - db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol(); + db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol(); // We use "fake" here as a target because any non-existent target will do. // However, because all of the tests in this class share a single page // request there is likely to be a target of "replica" from one of the other // unit tests, so we use a target here that we know with absolute certainty // does not exist. - db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'), array('target' => 'fake'))->fetchCol(); + db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'fake'])->fetchCol(); $queries1 = Database::getLog('testing1'); @@ -102,7 +102,7 @@ function testEnableTargetLoggingNoTarget() { /** * Tests that we can log queries separately on different connections. */ - function testEnableMultiConnectionLogging() { + public function testEnableMultiConnectionLogging() { // Clone the primary credentials to a fake connection. // That both connections point to the same physical database is irrelevant. $connection_info = Database::getConnectionInfo('default'); @@ -111,11 +111,11 @@ function testEnableMultiConnectionLogging() { Database::startLog('testing1'); Database::startLog('testing1', 'test2'); - db_query('SELECT name FROM {test} WHERE age > :age', array(':age' => 25))->fetchCol(); + db_query('SELECT name FROM {test} WHERE age > :age', [':age' => 25])->fetchCol(); $old_key = db_set_active('test2'); - db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'), array('target' => 'replica'))->fetchCol(); + db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'], ['target' => 'replica'])->fetchCol(); db_set_active($old_key); @@ -129,7 +129,7 @@ function testEnableMultiConnectionLogging() { /** * Tests that getLog with a wrong key return an empty array. */ - function testGetLoggingWrongKey() { + public function testGetLoggingWrongKey() { $result = Database::getLog('wrong'); $this->assertEqual($result, [], 'The function getLog with a wrong key returns an empty array.'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/MergeTest.php b/core/tests/Drupal/KernelTests/Core/Database/MergeTest.php index 34b81d0f..9a5688c5 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/MergeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/MergeTest.php @@ -15,15 +15,15 @@ class MergeTest extends DatabaseTestBase { /** * Confirms that we can merge-insert a record successfully. */ - function testMergeInsert() { + public function testMergeInsert() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $result = db_merge('test_people') ->key('job', 'Presenter') - ->fields(array( + ->fields([ 'age' => 31, 'name' => 'Tiffany', - )) + ]) ->execute(); $this->assertEqual($result, Merge::STATUS_INSERT, 'Insert status returned.'); @@ -31,7 +31,7 @@ function testMergeInsert() { $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before + 1, $num_records_after, 'Merge inserted properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Presenter'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Presenter'])->fetch(); $this->assertEqual($person->name, 'Tiffany', 'Name set correctly.'); $this->assertEqual($person->age, 31, 'Age set correctly.'); $this->assertEqual($person->job, 'Presenter', 'Job set correctly.'); @@ -40,15 +40,15 @@ function testMergeInsert() { /** * Confirms that we can merge-update a record successfully. */ - function testMergeUpdate() { + public function testMergeUpdate() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $result = db_merge('test_people') ->key('job', 'Speaker') - ->fields(array( + ->fields([ 'age' => 31, 'name' => 'Tiffany', - )) + ]) ->execute(); $this->assertEqual($result, Merge::STATUS_UPDATE, 'Update status returned.'); @@ -56,7 +56,7 @@ function testMergeUpdate() { $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->name, 'Tiffany', 'Name set correctly.'); $this->assertEqual($person->age, 31, 'Age set correctly.'); $this->assertEqual($person->job, 'Speaker', 'Job set correctly.'); @@ -68,19 +68,19 @@ function testMergeUpdate() { * This test varies from the previous test because it manually defines which * fields are inserted, and which fields are updated. */ - function testMergeUpdateExcept() { + public function testMergeUpdateExcept() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); db_merge('test_people') ->key('job', 'Speaker') - ->insertFields(array('age' => 31)) - ->updateFields(array('name' => 'Tiffany')) + ->insertFields(['age' => 31]) + ->updateFields(['name' => 'Tiffany']) ->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->name, 'Tiffany', 'Name set correctly.'); $this->assertEqual($person->age, 30, 'Age skipped correctly.'); $this->assertEqual($person->job, 'Speaker', 'Job set correctly.'); @@ -89,24 +89,24 @@ function testMergeUpdateExcept() { /** * Confirms that we can merge-update a record, with alternate replacement. */ - function testMergeUpdateExplicit() { + public function testMergeUpdateExplicit() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); db_merge('test_people') ->key('job', 'Speaker') - ->insertFields(array( + ->insertFields([ 'age' => 31, 'name' => 'Tiffany', - )) - ->updateFields(array( + ]) + ->updateFields([ 'name' => 'Joe', - )) + ]) ->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->name, 'Joe', 'Name set correctly.'); $this->assertEqual($person->age, 30, 'Age skipped correctly.'); $this->assertEqual($person->job, 'Speaker', 'Job set correctly.'); @@ -115,10 +115,10 @@ function testMergeUpdateExplicit() { /** * Confirms that we can merge-update a record successfully, with expressions. */ - function testMergeUpdateExpression() { + public function testMergeUpdateExpression() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); - $age_before = db_query('SELECT age FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetchField(); + $age_before = db_query('SELECT age FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetchField(); // This is a very contrived example, as I have no idea why you'd want to // change age this way, but that's beside the point. @@ -127,15 +127,15 @@ function testMergeUpdateExpression() { // which is what is supposed to happen. db_merge('test_people') ->key('job', 'Speaker') - ->fields(array('name' => 'Tiffany')) - ->insertFields(array('age' => 31)) - ->expression('age', 'age + :age', array(':age' => 4)) + ->fields(['name' => 'Tiffany']) + ->insertFields(['age' => 31]) + ->expression('age', 'age + :age', [':age' => 4]) ->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before, $num_records_after, 'Merge updated properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->name, 'Tiffany', 'Name set correctly.'); $this->assertEqual($person->age, $age_before + 4, 'Age updated correctly.'); $this->assertEqual($person->job, 'Speaker', 'Job set correctly.'); @@ -144,7 +144,7 @@ function testMergeUpdateExpression() { /** * Tests that we can merge-insert without any update fields. */ - function testMergeInsertWithoutUpdate() { + public function testMergeInsertWithoutUpdate() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); db_merge('test_people') @@ -154,7 +154,7 @@ function testMergeInsertWithoutUpdate() { $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before + 1, $num_records_after, 'Merge inserted properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Presenter'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Presenter'])->fetch(); $this->assertEqual($person->name, '', 'Name set correctly.'); $this->assertEqual($person->age, 0, 'Age set correctly.'); $this->assertEqual($person->job, 'Presenter', 'Job set correctly.'); @@ -163,7 +163,7 @@ function testMergeInsertWithoutUpdate() { /** * Confirms that we can merge-update without any update fields. */ - function testMergeUpdateWithoutUpdate() { + public function testMergeUpdateWithoutUpdate() { $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); db_merge('test_people') @@ -173,20 +173,20 @@ function testMergeUpdateWithoutUpdate() { $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before, $num_records_after, 'Merge skipped properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->name, 'Meredith', 'Name skipped correctly.'); $this->assertEqual($person->age, 30, 'Age skipped correctly.'); $this->assertEqual($person->job, 'Speaker', 'Job skipped correctly.'); db_merge('test_people') ->key('job', 'Speaker') - ->insertFields(array('age' => 31)) + ->insertFields(['age' => 31]) ->execute(); $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before, $num_records_after, 'Merge skipped properly.'); - $person = db_query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = db_query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->name, 'Meredith', 'Name skipped correctly.'); $this->assertEqual($person->age, 30, 'Age skipped correctly.'); $this->assertEqual($person->job, 'Speaker', 'Job skipped correctly.'); @@ -195,17 +195,17 @@ function testMergeUpdateWithoutUpdate() { /** * Tests that an invalid merge query throws an exception. */ - function testInvalidMerge() { + public function testInvalidMerge() { try { // This query will fail because there is no key field specified. // Normally it would throw an exception but we are suppressing it with // the throw_exception option. $options['throw_exception'] = FALSE; db_merge('test_people', $options) - ->fields(array( + ->fields([ 'age' => 31, 'name' => 'Tiffany', - )) + ]) ->execute(); $this->pass('$options[\'throw_exception\'] is FALSE, no InvalidMergeQueryException thrown.'); } @@ -217,10 +217,10 @@ function testInvalidMerge() { try { // This query will fail because there is no key field specified. db_merge('test_people') - ->fields(array( + ->fields([ 'age' => 31, 'name' => 'Tiffany', - )) + ]) ->execute(); } catch (InvalidMergeQueryException $e) { diff --git a/core/tests/Drupal/KernelTests/Core/Database/NextIdTest.php b/core/tests/Drupal/KernelTests/Core/Database/NextIdTest.php index b0cdc857..129d50ba 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/NextIdTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/NextIdTest.php @@ -15,7 +15,7 @@ class NextIdTest extends KernelTestBase { * The modules to enable. * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; protected function setUp() { parent::setUp(); @@ -25,7 +25,7 @@ protected function setUp() { /** * Tests that the sequences API works. */ - function testDbNextId() { + public function testDbNextId() { $first = db_next_id(); $second = db_next_id(); // We can test for exact increase in here because we know there is no diff --git a/core/tests/Drupal/KernelTests/Core/Database/PrefixInfoTest.php b/core/tests/Drupal/KernelTests/Core/Database/PrefixInfoTest.php index 131fb7ad..16fd0533 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/PrefixInfoTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/PrefixInfoTest.php @@ -20,7 +20,7 @@ class PrefixInfoTest extends DatabaseTestBase { * The other two by Drupal core supported databases do not have this variable * set in the return array. */ - function testGetPrefixInfo() { + public function testGetPrefixInfo() { $connection_info = Database::getConnectionInfo('default'); if ($connection_info['default']['driver'] == 'mysql') { // Copy the default connection info to the 'extra' key. diff --git a/core/tests/Drupal/KernelTests/Core/Database/QueryTest.php b/core/tests/Drupal/KernelTests/Core/Database/QueryTest.php index f84a9c86..04ba8ad1 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/QueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/QueryTest.php @@ -12,20 +12,20 @@ class QueryTest extends DatabaseTestBase { /** * Tests that we can pass an array of values directly in the query. */ - function testArraySubstitution() { - $names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', array(':ages[]' => array(25, 26, 27)))->fetchAll(); + public function testArraySubstitution() { + $names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', [':ages[]' => [25, 26, 27]])->fetchAll(); $this->assertEqual(count($names), 3, 'Correct number of names returned'); - $names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', array(':ages[]' => array(25)))->fetchAll(); + $names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', [':ages[]' => [25]])->fetchAll(); $this->assertEqual(count($names), 1, 'Correct number of names returned'); } /** * Tests that we can not pass a scalar value when an array is expected. */ - function testScalarSubstitution() { + public function testScalarSubstitution() { try { - $names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', array(':ages[]' => 25))->fetchAll(); + $names = db_query('SELECT name FROM {test} WHERE age IN ( :ages[] ) ORDER BY age', [':ages[]' => 25])->fetchAll(); $this->fail('Array placeholder with scalar argument should result in an exception.'); } catch (\InvalidArgumentException $e) { @@ -39,12 +39,12 @@ function testScalarSubstitution() { */ public function testArrayArgumentsSQLInjection() { // Attempt SQL injection and verify that it does not work. - $condition = array( + $condition = [ "1 ;INSERT INTO {test} (name) VALUES ('test12345678'); -- " => '', '1' => '', - ); + ]; try { - db_query("SELECT * FROM {test} WHERE name = :name", array(':name' => $condition))->fetchObject(); + db_query("SELECT * FROM {test} WHERE name = :name", [':name' => $condition])->fetchObject(); $this->fail('SQL injection attempt via array arguments should result in a database exception.'); } catch (\InvalidArgumentException $e) { @@ -101,7 +101,7 @@ public function testConditionOperatorArgumentsSQLInjection() { try { $result = db_select('test', 't') - ->fields('t', array('name', 'name')) + ->fields('t', ['name', 'name']) ->condition('name', 1, $injection) ->execute(); $this->fail('Should not be able to attempt SQL injection via operator.'); @@ -118,7 +118,7 @@ public function testConditionOperatorArgumentsSQLInjection() { try { $result = db_select('test', 't') - ->fields('t', array('name')) + ->fields('t', ['name']) ->condition('name', 1, $injection) ->execute(); $this->fail('Should not be able to attempt SQL injection via operator.'); @@ -139,9 +139,9 @@ public function testNumericExpressionSubstitution() { $count = db_query('SELECT COUNT(*) >= 3 FROM {test}')->fetchField(); $this->assertEqual((bool) $count, TRUE); - $count = db_query('SELECT COUNT(*) >= :count FROM {test}', array( + $count = db_query('SELECT COUNT(*) >= :count FROM {test}', [ ':count' => 3, - ))->fetchField(); + ])->fetchField(); $this->assertEqual((bool) $count, TRUE); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/RangeQueryTest.php b/core/tests/Drupal/KernelTests/Core/Database/RangeQueryTest.php index 33f315b7..b51316b6 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/RangeQueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/RangeQueryTest.php @@ -9,17 +9,10 @@ */ class RangeQueryTest extends DatabaseTestBase { - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('database_test'); - /** * Confirms that range queries work and return the correct result. */ - function testRangeQuery() { + public function testRangeQuery() { // Test if return correct number of rows. $range_rows = db_query_range("SELECT name FROM {test} ORDER BY name", 1, 3)->fetchAll(); $this->assertEqual(count($range_rows), 3, 'Range query work and return correct number of rows.'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/RegressionTest.php b/core/tests/Drupal/KernelTests/Core/Database/RegressionTest.php index e13bcfe5..66eed0ae 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/RegressionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/RegressionTest.php @@ -14,47 +14,47 @@ class RegressionTest extends DatabaseTestBase { * * @var array */ - public static $modules = array('node', 'user'); + public static $modules = ['node', 'user']; /** * Ensures that non-ASCII UTF-8 data is stored in the database properly. */ - function testRegression_310447() { + public function testRegression_310447() { // That's a 255 character UTF-8 string. $job = str_repeat("é", 255); db_insert('test') - ->fields(array( + ->fields([ 'name' => $this->randomMachineName(), 'age' => 20, 'job' => $job, - ))->execute(); + ])->execute(); - $from_database = db_query('SELECT job FROM {test} WHERE job = :job', array(':job' => $job))->fetchField(); - $this->assertIdentical($job, $from_database, 'The database handles UTF-8 characters cleanly.'); + $from_database = db_query('SELECT job FROM {test} WHERE job = :job', [':job' => $job])->fetchField(); + $this->assertSame($job, $from_database, 'The database handles UTF-8 characters cleanly.'); } /** * Tests the db_table_exists() function. */ - function testDBTableExists() { - $this->assertIdentical(TRUE, db_table_exists('test'), 'Returns true for existent table.'); - $this->assertIdentical(FALSE, db_table_exists('nosuchtable'), 'Returns false for nonexistent table.'); + public function testDBTableExists() { + $this->assertSame(TRUE, db_table_exists('test'), 'Returns true for existent table.'); + $this->assertSame(FALSE, db_table_exists('nosuchtable'), 'Returns false for nonexistent table.'); } /** * Tests the db_field_exists() function. */ - function testDBFieldExists() { - $this->assertIdentical(TRUE, db_field_exists('test', 'name'), 'Returns true for existent column.'); - $this->assertIdentical(FALSE, db_field_exists('test', 'nosuchcolumn'), 'Returns false for nonexistent column.'); + public function testDBFieldExists() { + $this->assertSame(TRUE, db_field_exists('test', 'name'), 'Returns true for existent column.'); + $this->assertSame(FALSE, db_field_exists('test', 'nosuchcolumn'), 'Returns false for nonexistent column.'); } /** * Tests the db_index_exists() function. */ - function testDBIndexExists() { - $this->assertIdentical(TRUE, db_index_exists('test', 'ages'), 'Returns true for existent index.'); - $this->assertIdentical(FALSE, db_index_exists('test', 'nosuchindex'), 'Returns false for nonexistent index.'); + public function testDBIndexExists() { + $this->assertSame(TRUE, db_index_exists('test', 'ages'), 'Returns true for existent index.'); + $this->assertSame(FALSE, db_index_exists('test', 'nosuchindex'), 'Returns false for nonexistent index.'); } } diff --git a/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php b/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php index 8641fd3c..e2390987 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php @@ -24,34 +24,34 @@ class SchemaTest extends KernelTestBase { /** * Tests database interactions. */ - function testSchema() { + public function testSchema() { // Try creating a table. - $table_specification = array( + $table_specification = [ 'description' => 'Schema table description may contain "quotes" and could be long—very long indeed.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'type' => 'int', 'default' => NULL, - ), - 'test_field' => array( + ], + 'test_field' => [ 'type' => 'int', 'not null' => TRUE, 'description' => 'Schema table description may contain "quotes" and could be long—very long indeed. There could be "multiple quoted regions".', - ), - 'test_field_string' => array( + ], + 'test_field_string' => [ 'type' => 'varchar', 'length' => 20, 'not null' => TRUE, 'default' => "'\"funky default'\"", 'description' => 'Schema column description for string.', - ), - 'test_field_string_ascii' => array( + ], + 'test_field_string_ascii' => [ 'type' => 'varchar_ascii', 'length' => 255, 'description' => 'Schema column description for ASCII string.', - ), - ), - ); + ], + ], + ]; db_create_table('test_table', $table_specification); // Assert that the table exists. @@ -95,7 +95,7 @@ function testSchema() { $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field'); $this->assertIdentical($index_exists, FALSE, 'Fake index does not exists'); // Add index. - db_add_index('test_table', 'test_field', array('test_field'), $table_specification); + db_add_index('test_table', 'test_field', ['test_field'], $table_specification); // Test for created index and test for the boolean result of indexExists(). $index_exists = Database::getConnection()->schema()->indexExists('test_table', 'test_field'); $this->assertIdentical($index_exists, TRUE, 'Index created.'); @@ -123,13 +123,13 @@ function testSchema() { // Recreate the table. db_create_table('test_table', $table_specification); db_field_set_default('test_table', 'test_field', 0); - db_add_field('test_table', 'test_serial', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Added column description.')); + db_add_field('test_table', 'test_serial', ['type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Added column description.']); // Assert that the column comment has been set. $this->checkSchemaComment('Added column description.', 'test_table', 'test_serial'); // Change the new field to a serial column. - db_change_field('test_table', 'test_serial', 'test_serial', array('type' => 'serial', 'not null' => TRUE, 'description' => 'Changed column description.'), array('primary key' => array('test_serial'))); + db_change_field('test_table', 'test_serial', 'test_serial', ['type' => 'serial', 'not null' => TRUE, 'description' => 'Changed column description.'], ['primary key' => ['test_serial']]); // Assert that the column comment has been set. $this->checkSchemaComment('Changed column description.', 'test_table', 'test_serial'); @@ -143,24 +143,46 @@ function testSchema() { $count = db_query('SELECT COUNT(*) FROM {test_table}')->fetchField(); $this->assertEqual($count, 2, 'There were two rows.'); + // Test adding a serial field to an existing table. + db_drop_table('test_table'); + db_create_table('test_table', $table_specification); + db_field_set_default('test_table', 'test_field', 0); + db_add_field('test_table', 'test_serial', ['type' => 'serial', 'not null' => TRUE], ['primary key' => ['test_serial']]); + + $this->assertPrimaryKeyColumns('test_table', ['test_serial']); + + $this->assertTrue($this->tryInsert(), 'Insert with a serial succeeded.'); + $max1 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField(); + $this->assertTrue($this->tryInsert(), 'Insert with a serial succeeded.'); + $max2 = db_query('SELECT MAX(test_serial) FROM {test_table}')->fetchField(); + $this->assertTrue($max2 > $max1, 'The serial is monotone.'); + + $count = db_query('SELECT COUNT(*) FROM {test_table}')->fetchField(); + $this->assertEqual($count, 2, 'There were two rows.'); + + // Test adding a new column and form a composite primary key with it. + db_add_field('test_table', 'test_composite_primary_key', ['type' => 'int', 'not null' => TRUE, 'default' => 0], ['primary key' => ['test_serial', 'test_composite_primary_key']]); + + $this->assertPrimaryKeyColumns('test_table', ['test_serial', 'test_composite_primary_key']); + // Test renaming of keys and constraints. db_drop_table('test_table'); - $table_specification = array( - 'fields' => array( - 'id' => array( + $table_specification = [ + 'fields' => [ + 'id' => [ 'type' => 'serial', 'not null' => TRUE, - ), - 'test_field' => array( + ], + 'test_field' => [ 'type' => 'int', 'default' => 0, - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'test_field' => array('test_field'), - ), - ); + ], + ], + 'primary key' => ['id'], + 'unique keys' => [ + 'test_field' => ['test_field'], + ], + ]; db_create_table('test_table', $table_specification); // Tests for indexes are Database specific. @@ -215,18 +237,18 @@ function testSchema() { } // Use database specific data type and ensure that table is created. - $table_specification = array( + $table_specification = [ 'description' => 'Schema table description.', - 'fields' => array( - 'timestamp' => array( + 'fields' => [ + 'timestamp' => [ 'mysql_type' => 'timestamp', 'pgsql_type' => 'timestamp', 'sqlite_type' => 'datetime', 'not null' => FALSE, 'default' => NULL, - ), - ), - ); + ], + ], + ]; try { db_create_table('test_timestamp', $table_specification); } @@ -240,56 +262,56 @@ function testSchema() { * * @see \Drupal\Core\Database\Driver\mysql\Schema::getNormalizedIndexes() */ - function testIndexLength() { + public function testIndexLength() { if (Database::getConnection()->databaseType() != 'mysql') { return; } - $table_specification = array( - 'fields' => array( - 'id' => array( + $table_specification = [ + 'fields' => [ + 'id' => [ 'type' => 'int', 'default' => NULL, - ), - 'test_field_text' => array( + ], + 'test_field_text' => [ 'type' => 'text', 'not null' => TRUE, - ), - 'test_field_string_long' => array( + ], + 'test_field_string_long' => [ 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, - ), - 'test_field_string_ascii_long' => array( + ], + 'test_field_string_ascii_long' => [ 'type' => 'varchar_ascii', 'length' => 255, - ), - 'test_field_string_short' => array( + ], + 'test_field_string_short' => [ 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, - ), - ), - 'indexes' => array( - 'test_regular' => array( + ], + ], + 'indexes' => [ + 'test_regular' => [ 'test_field_text', 'test_field_string_long', 'test_field_string_ascii_long', 'test_field_string_short', - ), - 'test_length' => array( - array('test_field_text', 128), - array('test_field_string_long', 128), - array('test_field_string_ascii_long', 128), - array('test_field_string_short', 128), - ), - 'test_mixed' => array( - array('test_field_text', 200), + ], + 'test_length' => [ + ['test_field_text', 128], + ['test_field_string_long', 128], + ['test_field_string_ascii_long', 128], + ['test_field_string_short', 128], + ], + 'test_mixed' => [ + ['test_field_text', 200], 'test_field_string_long', - array('test_field_string_ascii_long', 200), + ['test_field_string_ascii_long', 200], 'test_field_string_short', - ), - ), - ); + ], + ], + ]; db_create_table('test_table_index_length', $table_specification); $schema_object = Database::getConnection()->schema(); @@ -331,29 +353,29 @@ function testIndexLength() { // Get index information. $results = db_query('SHOW INDEX FROM {test_table_index_length}'); - $expected_lengths = array( - 'test_regular' => array( + $expected_lengths = [ + 'test_regular' => [ 'test_field_text' => 191, 'test_field_string_long' => 191, 'test_field_string_ascii_long' => NULL, 'test_field_string_short' => NULL, - ), - 'test_length' => array( + ], + 'test_length' => [ 'test_field_text' => 128, 'test_field_string_long' => 128, 'test_field_string_ascii_long' => 128, 'test_field_string_short' => NULL, - ), - 'test_mixed' => array( + ], + 'test_mixed' => [ 'test_field_text' => 191, 'test_field_string_long' => 191, 'test_field_string_ascii_long' => 200, 'test_field_string_short' => NULL, - ), - 'test_separate' => array( + ], + 'test_separate' => [ 'test_field_text' => 191, - ), - ); + ], + ]; // Count the number of columns defined in the indexes. $column_count = 0; @@ -379,10 +401,10 @@ function testIndexLength() { * @return * TRUE if the insert succeeded, FALSE otherwise. */ - function tryInsert($table = 'test_table') { + public function tryInsert($table = 'test_table') { try { db_insert($table) - ->fields(array('id' => mt_rand(10, 20))) + ->fields(['id' => mt_rand(10, 20)]) ->execute(); return TRUE; } @@ -401,7 +423,7 @@ function tryInsert($table = 'test_table') { * @param $column * Optional column to test. */ - function checkSchemaComment($description, $table, $column = NULL) { + public function checkSchemaComment($description, $table, $column = NULL) { if (method_exists(Database::getConnection()->schema(), 'getComment')) { $comment = Database::getConnection()->schema()->getComment($table, $column); // The schema comment truncation for mysql is different. @@ -416,21 +438,21 @@ function checkSchemaComment($description, $table, $column = NULL) { /** * Tests creating unsigned columns and data integrity thereof. */ - function testUnsignedColumns() { + public function testUnsignedColumns() { // First create the table with just a serial column. $table_name = 'unsigned_table'; - $table_spec = array( - 'fields' => array('serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE)), - 'primary key' => array('serial_column'), - ); + $table_spec = [ + 'fields' => ['serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE]], + 'primary key' => ['serial_column'], + ]; db_create_table($table_name, $table_spec); // Now set up columns for the other types. - $types = array('int', 'float', 'numeric'); + $types = ['int', 'float', 'numeric']; foreach ($types as $type) { - $column_spec = array('type' => $type, 'unsigned' => TRUE); + $column_spec = ['type' => $type, 'unsigned' => TRUE]; if ($type == 'numeric') { - $column_spec += array('precision' => 10, 'scale' => 0); + $column_spec += ['precision' => 10, 'scale' => 0]; } $column_name = $type . '_column'; $table_spec['fields'][$column_name] = $column_spec; @@ -439,8 +461,8 @@ function testUnsignedColumns() { // Finally, check each column and try to insert invalid values into them. foreach ($table_spec['fields'] as $column_name => $column_spec) { - $this->assertTrue(db_field_exists($table_name, $column_name), format_string('Unsigned @type column was created.', array('@type' => $column_spec['type']))); - $this->assertFalse($this->tryUnsignedInsert($table_name, $column_name), format_string('Unsigned @type column rejected a negative value.', array('@type' => $column_spec['type']))); + $this->assertTrue(db_field_exists($table_name, $column_name), format_string('Unsigned @type column was created.', ['@type' => $column_spec['type']])); + $this->assertFalse($this->tryUnsignedInsert($table_name, $column_name), format_string('Unsigned @type column rejected a negative value.', ['@type' => $column_spec['type']])); } } @@ -455,10 +477,10 @@ function testUnsignedColumns() { * @return * TRUE if the insert succeeded, FALSE otherwise. */ - function tryUnsignedInsert($table_name, $column_name) { + public function tryUnsignedInsert($table_name, $column_name) { try { db_insert($table_name) - ->fields(array($column_name => -1)) + ->fields([$column_name => -1]) ->execute(); return TRUE; } @@ -470,22 +492,22 @@ function tryUnsignedInsert($table_name, $column_name) { /** * Tests adding columns to an existing table. */ - function testSchemaAddField() { + public function testSchemaAddField() { // Test varchar types. - foreach (array(1, 32, 128, 256, 512) as $length) { - $base_field_spec = array( + foreach ([1, 32, 128, 256, 512] as $length) { + $base_field_spec = [ 'type' => 'varchar', 'length' => $length, - ); - $variations = array( - array('not null' => FALSE), - array('not null' => FALSE, 'default' => '7'), - array('not null' => FALSE, 'default' => substr('"thing"', 0, $length)), - array('not null' => FALSE, 'default' => substr("\"'hing", 0, $length)), - array('not null' => TRUE, 'initial' => 'd'), - array('not null' => FALSE, 'default' => NULL), - array('not null' => TRUE, 'initial' => 'd', 'default' => '7'), - ); + ]; + $variations = [ + ['not null' => FALSE], + ['not null' => FALSE, 'default' => '7'], + ['not null' => FALSE, 'default' => substr('"thing"', 0, $length)], + ['not null' => FALSE, 'default' => substr("\"'hing", 0, $length)], + ['not null' => TRUE, 'initial' => 'd'], + ['not null' => FALSE, 'default' => NULL], + ['not null' => TRUE, 'initial' => 'd', 'default' => '7'], + ]; foreach ($variations as $variation) { $field_spec = $variation + $base_field_spec; @@ -494,19 +516,19 @@ function testSchemaAddField() { } // Test int and float types. - foreach (array('int', 'float') as $type) { - foreach (array('tiny', 'small', 'medium', 'normal', 'big') as $size) { - $base_field_spec = array( + foreach (['int', 'float'] as $type) { + foreach (['tiny', 'small', 'medium', 'normal', 'big'] as $size) { + $base_field_spec = [ 'type' => $type, 'size' => $size, - ); - $variations = array( - array('not null' => FALSE), - array('not null' => FALSE, 'default' => 7), - array('not null' => TRUE, 'initial' => 1), - array('not null' => TRUE, 'initial' => 1, 'default' => 7), - array('not null' => TRUE, 'initial_from_field' => 'serial_column'), - ); + ]; + $variations = [ + ['not null' => FALSE], + ['not null' => FALSE, 'default' => 7], + ['not null' => TRUE, 'initial' => 1], + ['not null' => TRUE, 'initial' => 1, 'default' => 7], + ['not null' => TRUE, 'initial_from_field' => 'serial_column'], + ]; foreach ($variations as $variation) { $field_spec = $variation + $base_field_spec; @@ -516,25 +538,25 @@ function testSchemaAddField() { } // Test numeric types. - foreach (array(1, 5, 10, 40, 65) as $precision) { - foreach (array(0, 2, 10, 30) as $scale) { + foreach ([1, 5, 10, 40, 65] as $precision) { + foreach ([0, 2, 10, 30] as $scale) { // Skip combinations where precision is smaller than scale. if ($precision <= $scale) { continue; } - $base_field_spec = array( + $base_field_spec = [ 'type' => 'numeric', 'scale' => $scale, 'precision' => $precision, - ); - $variations = array( - array('not null' => FALSE), - array('not null' => FALSE, 'default' => 7), - array('not null' => TRUE, 'initial' => 1), - array('not null' => TRUE, 'initial' => 1, 'default' => 7), - array('not null' => TRUE, 'initial_from_field' => 'serial_column'), - ); + ]; + $variations = [ + ['not null' => FALSE], + ['not null' => FALSE, 'default' => 7], + ['not null' => TRUE, 'initial' => 1], + ['not null' => TRUE, 'initial' => 1, 'default' => 7], + ['not null' => TRUE, 'initial_from_field' => 'serial_column'], + ]; foreach ($variations as $variation) { $field_spec = $variation + $base_field_spec; @@ -556,15 +578,15 @@ function testSchemaAddField() { protected function assertFieldAdditionRemoval($field_spec) { // Try creating the field on a new table. $table_name = 'test_table_' . ($this->counter++); - $table_spec = array( - 'fields' => array( - 'serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), + $table_spec = [ + 'fields' => [ + 'serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE], 'test_field' => $field_spec, - ), - 'primary key' => array('serial_column'), - ); + ], + 'primary key' => ['serial_column'], + ]; db_create_table($table_name, $table_spec); - $this->pass(format_string('Table %table created.', array('%table' => $table_name))); + $this->pass(format_string('Table %table created.', ['%table' => $table_name])); // Check the characteristics of the field. $this->assertFieldCharacteristics($table_name, 'test_field', $field_spec); @@ -574,24 +596,24 @@ protected function assertFieldAdditionRemoval($field_spec) { // Try adding a field to an existing table. $table_name = 'test_table_' . ($this->counter++); - $table_spec = array( - 'fields' => array( - 'serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), - ), - 'primary key' => array('serial_column'), - ); + $table_spec = [ + 'fields' => [ + 'serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE], + ], + 'primary key' => ['serial_column'], + ]; db_create_table($table_name, $table_spec); - $this->pass(format_string('Table %table created.', array('%table' => $table_name))); + $this->pass(format_string('Table %table created.', ['%table' => $table_name])); // Insert some rows to the table to test the handling of initial values. for ($i = 0; $i < 3; $i++) { db_insert($table_name) - ->useDefaults(array('serial_column')) + ->useDefaults(['serial_column']) ->execute(); } db_add_field($table_name, 'test_field', $field_spec); - $this->pass(format_string('Column %column created.', array('%column' => 'test_field'))); + $this->pass(format_string('Column %column created.', ['%column' => 'test_field'])); // Check the characteristics of the field. $this->assertFieldCharacteristics($table_name, 'test_field', $field_spec); @@ -614,7 +636,7 @@ protected function assertFieldCharacteristics($table_name, $field_name, $field_s if (isset($field_spec['initial'])) { // There should be no row with a value different then $field_spec['initial']. $count = db_select($table_name) - ->fields($table_name, array('serial_column')) + ->fields($table_name, ['serial_column']) ->condition($field_name, $field_spec['initial'], '<>') ->countQuery() ->execute() @@ -627,7 +649,7 @@ protected function assertFieldCharacteristics($table_name, $field_name, $field_s // There should be no row with a value different than // $field_spec['initial_from_field']. $count = db_select($table_name) - ->fields($table_name, array('serial_column')) + ->fields($table_name, ['serial_column']) ->where($table_name . '.' . $field_spec['initial_from_field'] . ' <> ' . $table_name . '.' . $field_name) ->countQuery() ->execute() @@ -639,10 +661,10 @@ protected function assertFieldCharacteristics($table_name, $field_name, $field_s if (isset($field_spec['default'])) { // Try inserting a row, and check the resulting value of the new column. $id = db_insert($table_name) - ->useDefaults(array('serial_column')) + ->useDefaults(['serial_column']) ->execute(); $field_value = db_select($table_name) - ->fields($table_name, array($field_name)) + ->fields($table_name, [$field_name]) ->condition('serial_column', $id) ->execute() ->fetchField(); @@ -653,15 +675,15 @@ protected function assertFieldCharacteristics($table_name, $field_name, $field_s /** * Tests changing columns between types. */ - function testSchemaChangeField() { - $field_specs = array( - array('type' => 'int', 'size' => 'normal', 'not null' => FALSE), - array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 17), - array('type' => 'float', 'size' => 'normal', 'not null' => FALSE), - array('type' => 'float', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 7.3), - array('type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => FALSE), - array('type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => TRUE, 'initial' => 1, 'default' => 7), - ); + public function testSchemaChangeField() { + $field_specs = [ + ['type' => 'int', 'size' => 'normal', 'not null' => FALSE], + ['type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 17], + ['type' => 'float', 'size' => 'normal', 'not null' => FALSE], + ['type' => 'float', 'size' => 'normal', 'not null' => TRUE, 'initial' => 1, 'default' => 7.3], + ['type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => FALSE], + ['type' => 'numeric', 'scale' => 2, 'precision' => 10, 'not null' => TRUE, 'initial' => 1, 'default' => 7], + ]; foreach ($field_specs as $i => $old_spec) { foreach ($field_specs as $j => $new_spec) { @@ -673,12 +695,12 @@ function testSchemaChangeField() { } } - $field_specs = array( - array('type' => 'varchar_ascii', 'length' => '255'), - array('type' => 'varchar', 'length' => '255'), - array('type' => 'text'), - array('type' => 'blob', 'size' => 'big'), - ); + $field_specs = [ + ['type' => 'varchar_ascii', 'length' => '255'], + ['type' => 'varchar', 'length' => '255'], + ['type' => 'text'], + ['type' => 'blob', 'size' => 'big'], + ]; foreach ($field_specs as $i => $old_spec) { foreach ($field_specs as $j => $new_spec) { @@ -705,15 +727,15 @@ function testSchemaChangeField() { */ protected function assertFieldChange($old_spec, $new_spec, $test_data = NULL) { $table_name = 'test_table_' . ($this->counter++); - $table_spec = array( - 'fields' => array( - 'serial_column' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), + $table_spec = [ + 'fields' => [ + 'serial_column' => ['type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE], 'test_field' => $old_spec, - ), - 'primary key' => array('serial_column'), - ); + ], + 'primary key' => ['serial_column'], + ]; db_create_table($table_name, $table_spec); - $this->pass(format_string('Table %table created.', array('%table' => $table_name))); + $this->pass(format_string('Table %table created.', ['%table' => $table_name])); // Check the characteristics of the field. $this->assertFieldCharacteristics($table_name, 'test_field', $old_spec); @@ -804,4 +826,46 @@ public function testFindTables() { Database::setActiveConnection('default'); } + /** + * Tests the primary keys of a table. + * + * @param string $table_name + * The name of the table to check. + * @param array $primary_key + * The expected key column specifier for a table's primary key. + */ + protected function assertPrimaryKeyColumns($table_name, array $primary_key = []) { + $db_type = Database::getConnection()->databaseType(); + + switch ($db_type) { + case 'mysql': + $result = Database::getConnection()->query("SHOW KEYS FROM {" . $table_name . "} WHERE Key_name = 'PRIMARY'")->fetchAllAssoc('Column_name'); + $this->assertSame($primary_key, array_keys($result)); + + break; + case 'pgsql': + $result = Database::getConnection()->query("SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type + FROM pg_index i + JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = '{" . $table_name . "}'::regclass AND i.indisprimary") + ->fetchAllAssoc('attname'); + $this->assertSame($primary_key, array_keys($result)); + + break; + case 'sqlite': + // For SQLite we need access to the protected + // \Drupal\Core\Database\Driver\sqlite\Schema::introspectSchema() method + // because we have no other way of getting the table prefixes needed for + // running a straight PRAGMA query. + $schema_object = Database::getConnection()->schema(); + $reflection = new \ReflectionMethod($schema_object, 'introspectSchema'); + $reflection->setAccessible(TRUE); + + $table_info = $reflection->invoke($schema_object, $table_name); + $this->assertSame($primary_key, $table_info['primary key']); + + break; + } + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectCloneTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectCloneTest.php index 64e95d0b..30a4f1b9 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SelectCloneTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SelectCloneTest.php @@ -12,7 +12,7 @@ class SelectCloneTest extends DatabaseTestBase { /** * Test that subqueries as value within conditions are cloned properly. */ - function testSelectConditionSubQueryCloning() { + public function testSelectConditionSubQueryCloning() { $subquery = db_select('test', 't'); $subquery->addField('t', 'id', 'id'); $subquery->condition('age', 28, '<'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php index d6da2548..cd3ec4a1 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php @@ -3,6 +3,7 @@ namespace Drupal\KernelTests\Core\Database; use Drupal\Core\Database\Database; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Database\RowCountException; use Drupal\user\Entity\User; @@ -18,12 +19,12 @@ class SelectComplexTest extends DatabaseTestBase { * * @var array */ - public static $modules = array('system', 'user', 'node_access_test', 'field'); + public static $modules = ['system', 'user', 'node_access_test', 'field']; /** * Tests simple JOIN statements. */ - function testDefaultJoin() { + public function testDefaultJoin() { $query = db_select('test_task', 't'); $people_alias = $query->join('test', 'p', 't.pid = p.id'); $name_field = $query->addField($people_alias, 'name', 'name'); @@ -48,7 +49,7 @@ function testDefaultJoin() { /** * Tests LEFT OUTER joins. */ - function testLeftOuterJoin() { + public function testLeftOuterJoin() { $query = db_select('test', 'p'); $people_alias = $query->leftJoin('test_task', 't', 't.pid = p.id'); $name_field = $query->addField('p', 'name', 'name'); @@ -72,7 +73,7 @@ function testLeftOuterJoin() { /** * Tests GROUP BY clauses. */ - function testGroupBy() { + public function testGroupBy() { $query = db_select('test_task', 't'); $count_field = $query->addExpression('COUNT(task)', 'num'); $task_field = $query->addField('t', 'task'); @@ -82,7 +83,7 @@ function testGroupBy() { $num_records = 0; $last_count = 0; - $records = array(); + $records = []; foreach ($result as $record) { $num_records++; $this->assertTrue($record->$count_field >= $last_count, 'Results returned in correct order.'); @@ -90,16 +91,16 @@ function testGroupBy() { $records[$record->$task_field] = $record->$count_field; } - $correct_results = array( + $correct_results = [ 'eat' => 1, 'sleep' => 2, 'code' => 1, 'found new band' => 1, 'perform at superbowl' => 1, - ); + ]; foreach ($correct_results as $task => $count) { - $this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", array('@task' => $task))); + $this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", ['@task' => $task])); } $this->assertEqual($num_records, 6, 'Returned the correct number of total rows.'); @@ -108,7 +109,7 @@ function testGroupBy() { /** * Tests GROUP BY and HAVING clauses together. */ - function testGroupByAndHaving() { + public function testGroupByAndHaving() { $query = db_select('test_task', 't'); $count_field = $query->addExpression('COUNT(task)', 'num'); $task_field = $query->addField('t', 'task'); @@ -119,7 +120,7 @@ function testGroupByAndHaving() { $num_records = 0; $last_count = 0; - $records = array(); + $records = []; foreach ($result as $record) { $num_records++; $this->assertTrue($record->$count_field >= 2, 'Record has the minimum count.'); @@ -128,12 +129,12 @@ function testGroupByAndHaving() { $records[$record->$task_field] = $record->$count_field; } - $correct_results = array( + $correct_results = [ 'sleep' => 2, - ); + ]; foreach ($correct_results as $task => $count) { - $this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", array('@task' => $task))); + $this->assertEqual($records[$task], $count, format_string("Correct number of '@task' records found.", ['@task' => $task])); } $this->assertEqual($num_records, 1, 'Returned the correct number of total rows.'); @@ -144,7 +145,7 @@ function testGroupByAndHaving() { * * The SQL clause varies with the database. */ - function testRange() { + public function testRange() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -157,7 +158,7 @@ function testRange() { /** * Test whether the range property of a select clause can be undone. */ - function testRangeUndo() { + public function testRangeUndo() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); @@ -171,7 +172,7 @@ function testRangeUndo() { /** * Tests distinct queries. */ - function testDistinct() { + public function testDistinct() { $query = db_select('test_task'); $query->addField('test_task', 'task'); $query->distinct(); @@ -183,7 +184,7 @@ function testDistinct() { /** * Tests that we can generate a count query from a built query. */ - function testCountQuery() { + public function testCountQuery() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); @@ -203,7 +204,7 @@ function testCountQuery() { /** * Tests having queries. */ - function testHavingCountQuery() { + public function testHavingCountQuery() { $query = db_select('test') ->extend('Drupal\Core\Database\Query\PagerSelectExtender') ->groupBy('age') @@ -217,7 +218,7 @@ function testHavingCountQuery() { /** * Tests that countQuery removes 'all_fields' statements and ordering clauses. */ - function testCountQueryRemovals() { + public function testCountQueryRemovals() { $query = db_select('test'); $query->fields('test'); $query->orderBy('name'); @@ -248,14 +249,14 @@ function testCountQueryRemovals() { /** * Tests that countQuery properly removes fields and expressions. */ - function testCountQueryFieldRemovals() { + public function testCountQueryFieldRemovals() { // countQuery should remove all fields and expressions, so this can be // tested by adding a non-existent field and expression: if it ends // up in the query, an error will be thrown. If not, it will return the // number of records, which in this case happens to be 4 (there are four // records in the {test} table). $query = db_select('test'); - $query->fields('test', array('fail')); + $query->fields('test', ['fail']); $this->assertEqual(4, $query->countQuery()->execute()->fetchField(), 'Count Query removed fields'); $query = db_select('test'); @@ -266,7 +267,7 @@ function testCountQueryFieldRemovals() { /** * Tests that we can generate a count query from a query with distinct. */ - function testCountQueryDistinct() { + public function testCountQueryDistinct() { $query = db_select('test_task'); $query->addField('test_task', 'task'); $query->distinct(); @@ -279,7 +280,7 @@ function testCountQueryDistinct() { /** * Tests that we can generate a count query from a query with GROUP BY. */ - function testCountQueryGroupBy() { + public function testCountQueryGroupBy() { $query = db_select('test_task'); $query->addField('test_task', 'pid'); $query->groupBy('pid'); @@ -304,7 +305,7 @@ function testCountQueryGroupBy() { /** * Confirms that we can properly nest conditional clauses. */ - function testNestedConditions() { + public function testNestedConditions() { // This query should translate to: // "SELECT job FROM {test} WHERE name = 'Paul' AND (age = 26 OR age = 27)" // That should find only one record. Yes it's a non-optimal way of writing @@ -312,7 +313,7 @@ function testNestedConditions() { $query = db_select('test'); $query->addField('test', 'job'); $query->condition('name', 'Paul'); - $query->condition(db_or()->condition('age', 26)->condition('age', 27)); + $query->condition((new Condition('OR'))->condition('age', 26)->condition('age', 27)); $job = $query->execute()->fetchField(); $this->assertEqual($job, 'Songwriter', 'Correct data retrieved.'); @@ -321,7 +322,7 @@ function testNestedConditions() { /** * Confirms we can join on a single table twice with a dynamic alias. */ - function testJoinTwice() { + public function testJoinTwice() { $query = db_select('test')->fields('test'); $alias = $query->join('test', 'test', 'test.job = %alias.job'); $query->addField($alias, 'name', 'othername'); @@ -335,7 +336,7 @@ function testJoinTwice() { /** * Tests that we can join on a query. */ - function testJoinSubquery() { + public function testJoinSubquery() { $this->installSchema('system', 'sequences'); $account = User::create([ @@ -343,7 +344,7 @@ function testJoinSubquery() { 'mail' => $this->randomMachineName() . '@example.com', ]); - $query = db_select('test_task', 'tt', array('target' => 'replica')); + $query = db_select('test_task', 'tt', ['target' => 'replica']); $query->addExpression('tt.pid + 1', 'abc'); $query->condition('priority', 1, '>'); $query->condition('priority', 100, '<'); @@ -375,7 +376,7 @@ function testJoinSubquery() { /** * Tests that rowCount() throws exception on SELECT query. */ - function testSelectWithRowCount() { + public function testSelectWithRowCount() { $query = db_select('test'); $query->addField('test', 'name'); $result = $query->execute(); @@ -395,7 +396,7 @@ function testSelectWithRowCount() { public function testJoinConditionObject() { // Same test as testDefaultJoin, but with a Condition object. $query = db_select('test_task', 't'); - $join_cond = db_and()->where('t.pid = p.id'); + $join_cond = (new Condition('AND'))->where('t.pid = p.id'); $people_alias = $query->join('test', 'p', $join_cond); $name_field = $query->addField($people_alias, 'name', 'name'); $query->addField('t', 'task', 'task'); @@ -418,7 +419,7 @@ public function testJoinConditionObject() { // Test a condition object that creates placeholders. $t1_name = 'John'; $t2_name = 'George'; - $join_cond = db_and() + $join_cond = (new Condition('AND')) ->condition('t1.name', $t1_name) ->condition('t2.name', $t2_name); $query = db_select('test', 't1'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectOrderedTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectOrderedTest.php index c9e199be..5e81e089 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SelectOrderedTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SelectOrderedTest.php @@ -12,7 +12,7 @@ class SelectOrderedTest extends DatabaseTestBase { /** * Tests basic ORDER BY. */ - function testSimpleSelectOrdered() { + public function testSimpleSelectOrdered() { $query = db_select('test'); $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); @@ -33,7 +33,7 @@ function testSimpleSelectOrdered() { /** * Tests multiple ORDER BY. */ - function testSimpleSelectMultiOrdered() { + public function testSimpleSelectMultiOrdered() { $query = db_select('test'); $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); @@ -43,12 +43,12 @@ function testSimpleSelectMultiOrdered() { $result = $query->execute(); $num_records = 0; - $expected = array( - array('Ringo', 28, 'Drummer'), - array('John', 25, 'Singer'), - array('George', 27, 'Singer'), - array('Paul', 26, 'Songwriter'), - ); + $expected = [ + ['Ringo', 28, 'Drummer'], + ['John', 25, 'Singer'], + ['George', 27, 'Singer'], + ['Paul', 26, 'Songwriter'], + ]; $results = $result->fetchAll(\PDO::FETCH_NUM); foreach ($expected as $k => $record) { $num_records++; @@ -64,7 +64,7 @@ function testSimpleSelectMultiOrdered() { /** * Tests ORDER BY descending. */ - function testSimpleSelectOrderedDesc() { + public function testSimpleSelectOrderedDesc() { $query = db_select('test'); $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectSubqueryTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectSubqueryTest.php index 4877ca2f..58a66289 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SelectSubqueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SelectSubqueryTest.php @@ -12,7 +12,7 @@ class SelectSubqueryTest extends DatabaseTestBase { /** * Tests that we can use a subquery in a FROM clause. */ - function testFromSubquerySelect() { + public function testFromSubquerySelect() { // Create a subquery, which is just a normal query object. $subquery = db_select('test_task', 'tt'); $subquery->addField('tt', 'pid', 'pid'); @@ -39,14 +39,14 @@ function testFromSubquerySelect() { // WHERE tt.task = 'code' $people = $select->execute()->fetchCol(); - $this->assertEqual(count($people), 1, 'Returned the correct number of rows.'); + $this->assertCount(1, $people, 'Returned the correct number of rows.'); } } /** * Tests that we can use a subquery in a FROM clause with a LIMIT. */ - function testFromSubquerySelectWithLimit() { + public function testFromSubquerySelectWithLimit() { // Create a subquery, which is just a normal query object. $subquery = db_select('test_task', 'tt'); $subquery->addField('tt', 'pid', 'pid'); @@ -66,13 +66,13 @@ function testFromSubquerySelectWithLimit() { // INNER JOIN test t ON t.id=tt.pid $people = $select->execute()->fetchCol(); - $this->assertEqual(count($people), 1, 'Returned the correct number of rows.'); + $this->assertCount(1, $people, 'Returned the correct number of rows.'); } /** - * Tests that we can use a subquery in a WHERE clause. + * Tests that we can use a subquery with an IN operator in a WHERE clause. */ - function testConditionSubquerySelect() { + public function testConditionSubquerySelect() { // Create a subquery, which is just a normal query object. $subquery = db_select('test_task', 'tt'); $subquery->addField('tt', 'pid', 'pid'); @@ -89,13 +89,98 @@ function testConditionSubquerySelect() { // FROM test tt2 // WHERE tt2.pid IN (SELECT tt.pid AS pid FROM test_task tt WHERE tt.priority=1) $people = $select->execute()->fetchCol(); - $this->assertEqual(count($people), 5, 'Returned the correct number of rows.'); + $this->assertCount(5, $people, 'Returned the correct number of rows.'); + } + + /** + * Test that we can use a subquery with a relational operator in a WHERE clause. + */ + public function testConditionSubquerySelect2() { + // Create a subquery, which is just a normal query object. + $subquery = db_select('test', 't2'); + $subquery->addExpression('AVG(t2.age)'); + + // Create another query that adds a clause using the subquery. + $select = db_select('test', 't'); + $select->addField('t', 'name'); + $select->condition('t.age', $subquery, '<'); + + // The resulting query should be equivalent to: + // SELECT t.name + // FROM test t + // WHERE t.age < (SELECT AVG(t2.age) FROM test t2) + $people = $select->execute()->fetchCol(); + $this->assertEquals(['John', 'Paul'], $people, 'Returned Paul and John.', 0.0, 10, TRUE); + } + + /** + * Test that we can use 2 subqueries with a relational operator in a WHERE clause. + */ + public function testConditionSubquerySelect3() { + // Create subquery 1, which is just a normal query object. + $subquery1 = db_select('test_task', 'tt'); + $subquery1->addExpression('AVG(tt.priority)'); + $subquery1->where('tt.pid = t.id'); + + // Create subquery 2, which is just a normal query object. + $subquery2 = db_select('test_task', 'tt2'); + $subquery2->addExpression('AVG(tt2.priority)'); + + // Create another query that adds a clause using the subqueries. + $select = db_select('test', 't'); + $select->addField('t', 'name'); + $select->condition($subquery1, $subquery2, '>'); + + // The resulting query should be equivalent to: + // SELECT t.name + // FROM test t + // WHERE (SELECT AVG(tt.priority) FROM test_task tt WHERE tt.pid = t.id) > (SELECT AVG(tt2.priority) FROM test_task tt2) + $people = $select->execute()->fetchCol(); + $this->assertEquals(['John'], $people, 'Returned John.', 0.0, 10, TRUE); + } + + /** + * Test that we can use multiple subqueries. + * + * This test uses a subquery at the left hand side and multiple subqueries at + * the right hand side. The test query may not be that logical but that's due + * to the limited amount of data and tables. 'Valid' use cases do exist :) + */ + public function testConditionSubquerySelect4() { + // Create subquery 1, which is just a normal query object. + $subquery1 = db_select('test_task', 'tt'); + $subquery1->addExpression('AVG(tt.priority)'); + $subquery1->where('tt.pid = t.id'); + + // Create subquery 2, which is just a normal query object. + $subquery2 = db_select('test_task', 'tt2'); + $subquery2->addExpression('MIN(tt2.priority)'); + $subquery2->where('tt2.pid <> t.id'); + + // Create subquery 3, which is just a normal query object. + $subquery3 = db_select('test_task', 'tt3'); + $subquery3->addExpression('AVG(tt3.priority)'); + $subquery3->where('tt3.pid <> t.id'); + + // Create another query that adds a clause using the subqueries. + $select = db_select('test', 't'); + $select->addField('t', 'name'); + $select->condition($subquery1, [$subquery2, $subquery3], 'BETWEEN'); + + // The resulting query should be equivalent to: + // SELECT t.name AS name + // FROM {test} t + // WHERE (SELECT AVG(tt.priority) AS expression FROM {test_task} tt WHERE (tt.pid = t.id)) + // BETWEEN (SELECT MIN(tt2.priority) AS expression FROM {test_task} tt2 WHERE (tt2.pid <> t.id)) + // AND (SELECT AVG(tt3.priority) AS expression FROM {test_task} tt3 WHERE (tt3.pid <> t.id)); + $people = $select->execute()->fetchCol(); + $this->assertEquals(['George', 'Paul'], $people, 'Returned George and Paul.', 0.0, 10, TRUE); } /** * Tests that we can use a subquery in a JOIN clause. */ - function testJoinSubquerySelect() { + public function testJoinSubquerySelect() { // Create a subquery, which is just a normal query object. $subquery = db_select('test_task', 'tt'); $subquery->addField('tt', 'pid', 'pid'); @@ -113,7 +198,7 @@ function testJoinSubquerySelect() { // INNER JOIN (SELECT tt.pid AS pid FROM test_task tt WHERE priority=1) tt ON t.id=tt.pid $people = $select->execute()->fetchCol(); - $this->assertEqual(count($people), 2, 'Returned the correct number of rows.'); + $this->assertCount(2, $people, 'Returned the correct number of rows.'); } /** @@ -122,28 +207,28 @@ function testJoinSubquerySelect() { * We essentially select all rows from the {test} table that have matching * rows in the {test_people} table based on the shared name column. */ - function testExistsSubquerySelect() { + public function testExistsSubquerySelect() { // Put George into {test_people}. db_insert('test_people') - ->fields(array( + ->fields([ 'name' => 'George', 'age' => 27, 'job' => 'Singer', - )) + ]) ->execute(); // Base query to {test}. $query = db_select('test', 't') - ->fields('t', array('name')); + ->fields('t', ['name']); // Subquery to {test_people}. $subquery = db_select('test_people', 'tp') - ->fields('tp', array('name')) + ->fields('tp', ['name']) ->where('tp.name = t.name'); $query->exists($subquery); $result = $query->execute(); // Ensure that we got the right record. $record = $result->fetch(); - $this->assertEqual($record->name, 'George', 'Fetched name is correct using EXISTS query.'); + $this->assertEquals('George', $record->name, 'Fetched name is correct using EXISTS query.'); } /** @@ -152,28 +237,28 @@ function testExistsSubquerySelect() { * We essentially select all rows from the {test} table that don't have * matching rows in the {test_people} table based on the shared name column. */ - function testNotExistsSubquerySelect() { + public function testNotExistsSubquerySelect() { // Put George into {test_people}. db_insert('test_people') - ->fields(array( + ->fields([ 'name' => 'George', 'age' => 27, 'job' => 'Singer', - )) + ]) ->execute(); // Base query to {test}. $query = db_select('test', 't') - ->fields('t', array('name')); + ->fields('t', ['name']); // Subquery to {test_people}. $subquery = db_select('test_people', 'tp') - ->fields('tp', array('name')) + ->fields('tp', ['name']) ->where('tp.name = t.name'); $query->notExists($subquery); // Ensure that we got the right number of records. $people = $query->execute()->fetchCol(); - $this->assertEqual(count($people), 3, 'NOT EXISTS query returned the correct results.'); + $this->assertCount(3, $people, 'NOT EXISTS query returned the correct results.'); } } diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php index cc857a27..c28e1aa4 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php @@ -1,6 +1,7 @@ addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -26,7 +27,7 @@ function testSimpleSelect() { /** * Tests rudimentary SELECT statement with a COMMENT. */ - function testSimpleComment() { + public function testSimpleComment() { $query = db_select('test')->comment('Testing query comments'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -44,7 +45,7 @@ function testSimpleComment() { /** * Tests query COMMENT system against vulnerabilities. */ - function testVulnerableComment() { + public function testVulnerableComment() { $query = db_select('test')->comment('Testing query comments */ SELECT nid FROM {node}; --'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -68,7 +69,7 @@ function testVulnerableComment() { /** * Provides expected and input values for testVulnerableComment(). */ - function makeCommentsProvider() { + public function makeCommentsProvider() { return [ [ '/* */ ', @@ -99,7 +100,7 @@ function makeCommentsProvider() { /** * Tests basic conditionals on SELECT statements. */ - function testSimpleSelectConditional() { + public function testSimpleSelectConditional() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_field = $query->addField('test', 'age', 'age'); @@ -119,7 +120,7 @@ function testSimpleSelectConditional() { /** * Tests SELECT statements with expressions. */ - function testSimpleSelectExpression() { + public function testSimpleSelectExpression() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_field = $query->addExpression("age*2", 'double_age'); @@ -139,7 +140,7 @@ function testSimpleSelectExpression() { /** * Tests SELECT statements with multiple expressions. */ - function testSimpleSelectExpressionMultiple() { + public function testSimpleSelectExpressionMultiple() { $query = db_select('test'); $name_field = $query->addField('test', 'name'); $age_double_field = $query->addExpression("age*2"); @@ -161,9 +162,9 @@ function testSimpleSelectExpressionMultiple() { /** * Tests adding multiple fields to a SELECT statement at the same time. */ - function testSimpleSelectMultipleFields() { + public function testSimpleSelectMultipleFields() { $record = db_select('test') - ->fields('test', array('id', 'name', 'age', 'job')) + ->fields('test', ['id', 'name', 'age', 'job']) ->condition('age', 27) ->execute()->fetchObject(); @@ -184,7 +185,7 @@ function testSimpleSelectMultipleFields() { /** * Tests adding all fields from a given table to a SELECT statement. */ - function testSimpleSelectAllFields() { + public function testSimpleSelectAllFields() { $record = db_select('test') ->fields('test') ->condition('age', 27) @@ -207,11 +208,11 @@ function testSimpleSelectAllFields() { /** * Tests that a comparison with NULL is always FALSE. */ - function testNullCondition() { + public function testNullCondition() { $this->ensureSampleDataNull(); $names = db_select('test_null', 'tn') - ->fields('tn', array('name')) + ->fields('tn', ['name']) ->condition('age', NULL) ->execute()->fetchCol(); @@ -221,11 +222,11 @@ function testNullCondition() { /** * Tests that we can find a record with a NULL value. */ - function testIsNullCondition() { + public function testIsNullCondition() { $this->ensureSampleDataNull(); $names = db_select('test_null', 'tn') - ->fields('tn', array('name')) + ->fields('tn', ['name']) ->isNull('age') ->execute()->fetchCol(); @@ -236,11 +237,11 @@ function testIsNullCondition() { /** * Tests that we can find a record without a NULL value. */ - function testIsNotNullCondition() { + public function testIsNotNullCondition() { $this->ensureSampleDataNull(); $names = db_select('test_null', 'tn') - ->fields('tn', array('name')) + ->fields('tn', ['name']) ->isNotNull('tn.age') ->orderBy('name') ->execute()->fetchCol(); @@ -256,13 +257,13 @@ function testIsNotNullCondition() { * This is semantically equal to UNION DISTINCT, so we don't explicitly test * that. */ - function testUnion() { + public function testUnion() { $query_1 = db_select('test', 't') - ->fields('t', array('name')) - ->condition('age', array(27, 28), 'IN'); + ->fields('t', ['name']) + ->condition('age', [27, 28], 'IN'); $query_2 = db_select('test', 't') - ->fields('t', array('name')) + ->fields('t', ['name']) ->condition('age', 28); $query_1->union($query_2); @@ -279,13 +280,13 @@ function testUnion() { /** * Tests that we can UNION ALL multiple SELECT queries together. */ - function testUnionAll() { + public function testUnionAll() { $query_1 = db_select('test', 't') - ->fields('t', array('name')) - ->condition('age', array(27, 28), 'IN'); + ->fields('t', ['name']) + ->condition('age', [27, 28], 'IN'); $query_2 = db_select('test', 't') - ->fields('t', array('name')) + ->fields('t', ['name']) ->condition('age', 28); $query_1->union($query_2, 'ALL'); @@ -303,13 +304,13 @@ function testUnionAll() { /** * Tests that we can get a count query for a UNION Select query. */ - function testUnionCount() { + public function testUnionCount() { $query_1 = db_select('test', 't') - ->fields('t', array('name', 'age')) - ->condition('age', array(27, 28), 'IN'); + ->fields('t', ['name', 'age']) + ->condition('age', [27, 28], 'IN'); $query_2 = db_select('test', 't') - ->fields('t', array('name', 'age')) + ->fields('t', ['name', 'age']) ->condition('age', 28); $query_1->union($query_2, 'ALL'); @@ -325,15 +326,15 @@ function testUnionCount() { /** * Tests that we can UNION multiple Select queries together and set the ORDER. */ - function testUnionOrder() { + public function testUnionOrder() { // This gives George and Ringo. $query_1 = db_select('test', 't') - ->fields('t', array('name')) - ->condition('age', array(27, 28), 'IN'); + ->fields('t', ['name']) + ->condition('age', [27, 28], 'IN'); // This gives Paul. $query_2 = db_select('test', 't') - ->fields('t', array('name')) + ->fields('t', ['name']) ->condition('age', 26); $query_1->union($query_2); @@ -354,15 +355,15 @@ function testUnionOrder() { /** * Tests that we can UNION multiple Select queries together with and a LIMIT. */ - function testUnionOrderLimit() { + public function testUnionOrderLimit() { // This gives George and Ringo. $query_1 = db_select('test', 't') - ->fields('t', array('name')) - ->condition('age', array(27, 28), 'IN'); + ->fields('t', ['name']) + ->condition('age', [27, 28], 'IN'); // This gives Paul. $query_2 = db_select('test', 't') - ->fields('t', array('name')) + ->fields('t', ['name']) ->condition('age', 26); $query_1->union($query_2); @@ -395,19 +396,19 @@ function testUnionOrderLimit() { * order each time, the only way this could happen is if we have successfully * triggered the database's random ordering functionality. */ - function testRandomOrder() { + public function testRandomOrder() { // Use 52 items, so the chance that this test fails by accident will be the // same as the chance that a deck of cards will come out in the same order // after shuffling it (in other words, nearly impossible). $number_of_items = 52; while (db_query("SELECT MAX(id) FROM {test}")->fetchField() < $number_of_items) { - db_insert('test')->fields(array('name' => $this->randomMachineName()))->execute(); + db_insert('test')->fields(['name' => $this->randomMachineName()])->execute(); } // First select the items in order and make sure we get an ordered list. $expected_ids = range(1, $number_of_items); $ordered_ids = db_select('test', 't') - ->fields('t', array('id')) + ->fields('t', ['id']) ->range(0, $number_of_items) ->orderBy('id') ->execute() @@ -418,7 +419,7 @@ function testRandomOrder() { // expect this to contain a differently ordered version of the original // result. $randomized_ids = db_select('test', 't') - ->fields('t', array('id')) + ->fields('t', ['id']) ->range(0, $number_of_items) ->orderRandom() ->execute() @@ -431,7 +432,7 @@ function testRandomOrder() { // Now perform the exact same query again, and make sure the order is // different. $randomized_ids_second_set = db_select('test', 't') - ->fields('t', array('id')) + ->fields('t', ['id']) ->range(0, $number_of_items) ->orderRandom() ->execute() @@ -447,24 +448,24 @@ function testRandomOrder() { */ public function testRegexCondition() { - $test_groups[] = array( + $test_groups[] = [ 'regex' => 'hn$', - 'expected' => array( + 'expected' => [ 'John', - ), - ); - $test_groups[] = array( + ], + ]; + $test_groups[] = [ 'regex' => '^Pau', - 'expected' => array( + 'expected' => [ 'Paul', - ), - ); - $test_groups[] = array( + ], + ]; + $test_groups[] = [ 'regex' => 'Ringo|George', - 'expected' => array( + 'expected' => [ 'Ringo', 'George', - ), - ); + ], + ]; $database = $this->container->get('database'); @@ -480,25 +481,24 @@ public function testRegexCondition() { // Ensure that filter by "#" still works due to the quoting. $database->insert('test') - ->fields(array( + ->fields([ 'name' => 'Pete', 'age' => 26, 'job' => '#Drummer', - )) + ]) ->execute(); - $test_groups = array(); - $test_groups[] = array( + $test_groups = []; + $test_groups[] = [ 'regex' => '#Drummer', - 'expected' => array( + 'expected' => [ 'Pete', - ), - ); - $test_groups[] = array( + ], + ]; + $test_groups[] = [ 'regex' => '#Singer', - 'expected' => array( - ), - ); + 'expected' => [], + ]; foreach ($test_groups as $test_group) { $query = $database->select('test', 't'); @@ -509,12 +509,19 @@ public function testRegexCondition() { $this->assertEqual(count($result), count($test_group['expected']), 'Returns the expected number of rows.'); $this->assertEqual(sort($result), sort($test_group['expected']), 'Returns the expected rows.'); } + + // Ensure that REGEXP filter still works with no-string type field. + $query = $database->select('test', 't'); + $query->addField('t', 'age'); + $query->condition('t.age', '2[6]', 'REGEXP'); + $result = $query->execute()->fetchField(); + $this->assertEquals($result, '26', 'Regexp with number type.'); } /** * Tests that aliases are renamed when they are duplicates. */ - function testSelectDuplicateAlias() { + public function testSelectDuplicateAlias() { $query = db_select('test', 't'); $alias1 = $query->addField('t', 'name', 'the_alias'); $alias2 = $query->addField('t', 'age', 'the_alias'); @@ -524,7 +531,7 @@ function testSelectDuplicateAlias() { /** * Tests that an invalid merge query throws an exception. */ - function testInvalidSelectCount() { + public function testInvalidSelectCount() { try { // This query will fail because the table does not exist. // Normally it would throw an exception but we are suppressing @@ -559,11 +566,11 @@ function testInvalidSelectCount() { /** * Tests thrown exception for IN query conditions with an empty array. */ - function testEmptyInCondition() { + public function testEmptyInCondition() { try { db_select('test', 't') ->fields('t') - ->condition('age', array(), 'IN') + ->condition('age', [], 'IN') ->execute(); $this->fail('Expected exception not thrown'); @@ -575,7 +582,7 @@ function testEmptyInCondition() { try { db_select('test', 't') ->fields('t') - ->condition('age', array(), 'NOT IN') + ->condition('age', [], 'NOT IN') ->execute(); $this->fail('Expected exception not thrown'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/SerializeQueryTest.php b/core/tests/Drupal/KernelTests/Core/Database/SerializeQueryTest.php index 6505484f..357b39fe 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SerializeQueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SerializeQueryTest.php @@ -11,7 +11,7 @@ class SerializeQueryTest extends DatabaseTestBase { /** * Confirms that a query can be serialized and unserialized. */ - function testSerializeQuery() { + public function testSerializeQuery() { $query = db_select('test'); $query->addField('test', 'age'); $query->condition('name', 'Ringo'); diff --git a/core/tests/Drupal/KernelTests/Core/Database/TaggingTest.php b/core/tests/Drupal/KernelTests/Core/Database/TaggingTest.php index 611b2460..cab91381 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/TaggingTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/TaggingTest.php @@ -15,7 +15,7 @@ class TaggingTest extends DatabaseTestBase { /** * Confirms that a query has a tag added to it. */ - function testHasTag() { + public function testHasTag() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -29,7 +29,7 @@ function testHasTag() { /** * Tests query tagging "has all of these tags" functionality. */ - function testHasAllTags() { + public function testHasAllTags() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -44,7 +44,7 @@ function testHasAllTags() { /** * Tests query tagging "has at least one of these tags" functionality. */ - function testHasAnyTag() { + public function testHasAnyTag() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); @@ -58,7 +58,7 @@ function testHasAnyTag() { /** * Confirms that an extended query has a tag added to it. */ - function testExtenderHasTag() { + public function testExtenderHasTag() { $query = db_select('test') ->extend('Drupal\Core\Database\Query\SelectExtender'); $query->addField('test', 'name'); @@ -73,7 +73,7 @@ function testExtenderHasTag() { /** * Tests extended query tagging "has all of these tags" functionality. */ - function testExtenderHasAllTags() { + public function testExtenderHasAllTags() { $query = db_select('test') ->extend('Drupal\Core\Database\Query\SelectExtender'); $query->addField('test', 'name'); @@ -89,7 +89,7 @@ function testExtenderHasAllTags() { /** * Tests extended query tagging "has at least one of these tags" functionality. */ - function testExtenderHasAnyTag() { + public function testExtenderHasAnyTag() { $query = db_select('test') ->extend('Drupal\Core\Database\Query\SelectExtender'); $query->addField('test', 'name'); @@ -106,15 +106,15 @@ function testExtenderHasAnyTag() { * * This is how we pass additional context to alter hooks. */ - function testMetaData() { + public function testMetaData() { $query = db_select('test'); $query->addField('test', 'name'); $query->addField('test', 'age', 'age'); - $data = array( + $data = [ 'a' => 'A', 'b' => 'B', - ); + ]; $query->addMetaData('test', $data); diff --git a/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php b/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php index fe7de483..a07045dd 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/TransactionTest.php @@ -58,10 +58,10 @@ protected function transactionOuterLayer($suffix, $rollback = FALSE, $ddl_statem // Insert a single row into the testing table. db_insert('test') - ->fields(array( + ->fields([ 'name' => 'David' . $suffix, 'age' => '24', - )) + ]) ->execute(); $this->assertTrue($connection->inTransaction(), 'In transaction before calling nested transaction.'); @@ -75,8 +75,8 @@ protected function transactionOuterLayer($suffix, $rollback = FALSE, $ddl_statem if ($rollback) { // Roll back the transaction, if requested. // This rollback should propagate to the last savepoint. - $txn->rollback(); - $this->assertTrue(($connection->transactionDepth() == $depth), 'Transaction has rolled back to the last savepoint after calling rollback().'); + $txn->rollBack(); + $this->assertTrue(($connection->transactionDepth() == $depth), 'Transaction has rolled back to the last savepoint after calling rollBack().'); } } @@ -108,25 +108,25 @@ protected function transactionInnerLayer($suffix, $rollback = FALSE, $ddl_statem // Insert a single row into the testing table. db_insert('test') - ->fields(array( + ->fields([ 'name' => 'Daniel' . $suffix, 'age' => '19', - )) + ]) ->execute(); $this->assertTrue($connection->inTransaction(), 'In transaction inside nested transaction.'); if ($ddl_statement) { - $table = array( - 'fields' => array( - 'id' => array( + $table = [ + 'fields' => [ + 'id' => [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ), - ), - 'primary key' => array('id'), - ); + ], + ], + 'primary key' => ['id'], + ]; db_create_table('database_test_1', $table); $this->assertTrue($connection->inTransaction(), 'In transaction inside nested transaction.'); @@ -135,8 +135,8 @@ protected function transactionInnerLayer($suffix, $rollback = FALSE, $ddl_statem if ($rollback) { // Roll back the transaction, if requested. // This rollback should propagate to the last savepoint. - $txn->rollback(); - $this->assertTrue(($connection->transactionDepth() == $depth), 'Transaction has rolled back to the last savepoint after calling rollback().'); + $txn->rollBack(); + $this->assertTrue(($connection->transactionDepth() == $depth), 'Transaction has rolled back to the last savepoint after calling rollBack().'); } } @@ -146,7 +146,7 @@ protected function transactionInnerLayer($suffix, $rollback = FALSE, $ddl_statem * If the active connection does not support transactions, this test does * nothing. */ - function testTransactionRollBackSupported() { + public function testTransactionRollBackSupported() { // This test won't work right if transactions are not supported. if (!Database::getConnection()->supportsTransactions()) { return; @@ -157,9 +157,9 @@ function testTransactionRollBackSupported() { // Neither of the rows we inserted in the two transaction layers // should be present in the tables post-rollback. - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidB'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'DavidB'])->fetchField(); $this->assertNotIdentical($saved_age, '24', 'Cannot retrieve DavidB row after commit.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielB'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'DanielB'])->fetchField(); $this->assertNotIdentical($saved_age, '19', 'Cannot retrieve DanielB row after commit.'); } catch (\Exception $e) { @@ -172,7 +172,7 @@ function testTransactionRollBackSupported() { * * If the active driver supports transactions, this test does nothing. */ - function testTransactionRollBackNotSupported() { + public function testTransactionRollBackNotSupported() { // This test won't work right if transactions are supported. if (Database::getConnection()->supportsTransactions()) { return; @@ -183,9 +183,9 @@ function testTransactionRollBackNotSupported() { // Because our current database claims to not support transactions, // the inserted rows should be present despite the attempt to roll back. - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidB'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'DavidB'])->fetchField(); $this->assertIdentical($saved_age, '24', 'DavidB not rolled back, since transactions are not supported.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielB'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'DanielB'])->fetchField(); $this->assertIdentical($saved_age, '19', 'DanielB not rolled back, since transactions are not supported.'); } catch (\Exception $e) { @@ -199,15 +199,15 @@ function testTransactionRollBackNotSupported() { * The behavior of this test should be identical for connections that support * transactions and those that do not. */ - function testCommittedTransaction() { + public function testCommittedTransaction() { try { // Create two nested transactions. The changes should be committed. $this->transactionOuterLayer('A'); // Because we committed, both of the inserted rows should be present. - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DavidA'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'DavidA'])->fetchField(); $this->assertIdentical($saved_age, '24', 'Can retrieve DavidA row after commit.'); - $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'DanielA'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'DanielA'])->fetchField(); $this->assertIdentical($saved_age, '19', 'Can retrieve DanielA row after commit.'); } catch (\Exception $e) { @@ -218,7 +218,7 @@ function testCommittedTransaction() { /** * Tests the compatibility of transactions with DDL statements. */ - function testTransactionWithDdlStatement() { + public function testTransactionWithDdlStatement() { // First, test that a commit works normally, even with DDL statements. $transaction = db_transaction(); $this->insertRow('row'); @@ -254,7 +254,7 @@ function testTransactionWithDdlStatement() { unset($transaction2); $transaction3 = db_transaction(); $this->insertRow('row'); - $transaction3->rollback(); + $transaction3->rollBack(); unset($transaction3); unset($transaction); $this->assertRowAbsent('row'); @@ -267,7 +267,7 @@ function testTransactionWithDdlStatement() { $transaction = db_transaction(); $this->insertRow('row'); $this->executeDDLStatement(); - $transaction->rollback(); + $transaction->rollBack(); unset($transaction); $this->assertRowAbsent('row'); @@ -280,7 +280,7 @@ function testTransactionWithDdlStatement() { $transaction3 = db_transaction(); $this->insertRow('row'); unset($transaction3); - $transaction->rollback(); + $transaction->rollBack(); unset($transaction); $this->assertRowAbsent('row'); } @@ -293,7 +293,7 @@ function testTransactionWithDdlStatement() { $this->executeDDLStatement(); // Rollback the outer transaction. try { - $transaction->rollback(); + $transaction->rollBack(); unset($transaction); // @TODO: an exception should be triggered here, but is not, because // "ROLLBACK" fails silently in MySQL if there is no transaction active. @@ -311,9 +311,9 @@ function testTransactionWithDdlStatement() { */ protected function insertRow($name) { db_insert('test') - ->fields(array( + ->fields([ 'name' => $name, - )) + ]) ->execute(); } @@ -322,16 +322,16 @@ protected function insertRow($name) { */ protected function executeDDLStatement() { static $count = 0; - $table = array( - 'fields' => array( - 'id' => array( + $table = [ + 'fields' => [ + 'id' => [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ), - ), - 'primary key' => array('id'), - ); + ], + ], + 'primary key' => ['id'], + ]; db_create_table('database_test_' . ++$count, $table); } @@ -351,11 +351,11 @@ protected function cleanUp() { * @param $message * The message to log for the assertion. */ - function assertRowPresent($name, $message = NULL) { + public function assertRowPresent($name, $message = NULL) { if (!isset($message)) { - $message = format_string('Row %name is present.', array('%name' => $name)); + $message = format_string('Row %name is present.', ['%name' => $name]); } - $present = (boolean) db_query('SELECT 1 FROM {test} WHERE name = :name', array(':name' => $name))->fetchField(); + $present = (boolean) db_query('SELECT 1 FROM {test} WHERE name = :name', [':name' => $name])->fetchField(); return $this->assertTrue($present, $message); } @@ -367,18 +367,18 @@ function assertRowPresent($name, $message = NULL) { * @param $message * The message to log for the assertion. */ - function assertRowAbsent($name, $message = NULL) { + public function assertRowAbsent($name, $message = NULL) { if (!isset($message)) { - $message = format_string('Row %name is absent.', array('%name' => $name)); + $message = format_string('Row %name is absent.', ['%name' => $name]); } - $present = (boolean) db_query('SELECT 1 FROM {test} WHERE name = :name', array(':name' => $name))->fetchField(); + $present = (boolean) db_query('SELECT 1 FROM {test} WHERE name = :name', [':name' => $name])->fetchField(); return $this->assertFalse($present, $message); } /** * Tests transaction stacking, commit, and rollback. */ - function testTransactionStacking() { + public function testTransactionStacking() { // This test won't work right if transactions are not supported. if (!Database::getConnection()->supportsTransactions()) { return; @@ -424,7 +424,7 @@ function testTransactionStacking() { $transaction2 = db_transaction(); $this->insertRow('inner'); // Now rollback the inner transaction. - $transaction2->rollback(); + $transaction2->rollBack(); unset($transaction2); $this->assertTrue($database->inTransaction(), 'Still in a transaction after popping the outer transaction'); // Pop the outer transaction, it should commit. @@ -445,7 +445,7 @@ function testTransactionStacking() { unset($transaction); $this->assertTrue($database->inTransaction(), 'Still in a transaction after popping the outer transaction'); // Now rollback the inner transaction, it should rollback. - $transaction2->rollback(); + $transaction2->rollBack(); unset($transaction2); $this->assertFalse($database->inTransaction(), 'Transaction closed after popping the inner transaction'); $this->assertRowPresent('outer'); @@ -463,7 +463,7 @@ function testTransactionStacking() { $this->insertRow('inner2'); // Rollback the outer transaction. try { - $transaction->rollback(); + $transaction->rollBack(); unset($transaction); $this->fail('Rolling back the outer transaction while the inner transaction is active resulted in an exception.'); } @@ -476,7 +476,7 @@ function testTransactionStacking() { $this->pass('Trying to commit an inner transaction resulted in an exception.'); // Try to rollback one inner transaction. try { - $transaction->rollback(); + $transaction->rollBack(); unset($transaction2); $this->fail('Trying to commit an inner transaction resulted in an exception.'); } @@ -498,7 +498,7 @@ public function testQueryFailureInTransaction() { // Test a failed query using the query() method. try { - $connection->query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'David'))->fetchField(); + $connection->query('SELECT age FROM {test} WHERE name = :name', [':name' => 'David'])->fetchField(); $this->fail('Using the query method failed.'); } catch (\Exception $e) { @@ -594,16 +594,16 @@ public function testQueryFailureInTransaction() { // Create the missing schema and insert a row. $this->installSchema('database_test', ['test']); $connection->insert('test') - ->fields(array( + ->fields([ 'name' => 'David', 'age' => '24', - )) + ]) ->execute(); // Commit the transaction. unset($transaction); - $saved_age = $connection->query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'David'))->fetchField(); + $saved_age = $connection->query('SELECT age FROM {test} WHERE name = :name', [':name' => 'David'])->fetchField(); $this->assertEqual('24', $saved_age); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php b/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php index 74eb0f1f..69d5d5d3 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php @@ -2,6 +2,8 @@ namespace Drupal\KernelTests\Core\Database; +use Drupal\Core\Database\Query\Condition; + /** * Tests the Update query builder, complex queries. * @@ -12,122 +14,120 @@ class UpdateComplexTest extends DatabaseTestBase { /** * Tests updates with OR conditionals. */ - function testOrConditionUpdate() { + public function testOrConditionUpdate() { $update = db_update('test') - ->fields(array('job' => 'Musician')) - ->condition(db_or() + ->fields(['job' => 'Musician']) + ->condition((new Condition('OR')) ->condition('name', 'John') ->condition('name', 'Paul') ); $num_updated = $update->execute(); $this->assertIdentical($num_updated, 2, 'Updated 2 records.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '2', 'Updated fields successfully.'); } /** * Tests WHERE IN clauses. */ - function testInConditionUpdate() { + public function testInConditionUpdate() { $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) - ->condition('name', array('John', 'Paul'), 'IN') + ->fields(['job' => 'Musician']) + ->condition('name', ['John', 'Paul'], 'IN') ->execute(); $this->assertIdentical($num_updated, 2, 'Updated 2 records.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '2', 'Updated fields successfully.'); } /** * Tests WHERE NOT IN clauses. */ - function testNotInConditionUpdate() { + public function testNotInConditionUpdate() { // The o is lowercase in the 'NoT IN' operator, to make sure the operators // work in mixed case. $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) - ->condition('name', array('John', 'Paul', 'George'), 'NoT IN') + ->fields(['job' => 'Musician']) + ->condition('name', ['John', 'Paul', 'George'], 'NoT IN') ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '1', 'Updated fields successfully.'); } /** * Tests BETWEEN conditional clauses. */ - function testBetweenConditionUpdate() { + public function testBetweenConditionUpdate() { $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) - ->condition('age', array(25, 26), 'BETWEEN') + ->fields(['job' => 'Musician']) + ->condition('age', [25, 26], 'BETWEEN') ->execute(); $this->assertIdentical($num_updated, 2, 'Updated 2 records.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '2', 'Updated fields successfully.'); } /** * Tests LIKE conditionals. */ - function testLikeConditionUpdate() { + public function testLikeConditionUpdate() { $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) + ->fields(['job' => 'Musician']) ->condition('name', '%ge%', 'LIKE') ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '1', 'Updated fields successfully.'); } /** * Tests UPDATE with expression values. */ - function testUpdateExpression() { - $before_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchField(); - $GLOBALS['larry_test'] = 1; + public function testUpdateExpression() { + $before_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchField(); $num_updated = db_update('test') ->condition('name', 'Ringo') - ->fields(array('job' => 'Musician')) - ->expression('age', 'age + :age', array(':age' => 4)) + ->fields(['job' => 'Musician']) + ->expression('age', 'age + :age', [':age' => 4]) ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '1', 'Updated fields successfully.'); - $person = db_query('SELECT * FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetch(); + $person = db_query('SELECT * FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetch(); $this->assertEqual($person->name, 'Ringo', 'Name set correctly.'); $this->assertEqual($person->age, $before_age + 4, 'Age set correctly.'); $this->assertEqual($person->job, 'Musician', 'Job set correctly.'); - $GLOBALS['larry_test'] = 0; } /** * Tests UPDATE with only expression values. */ - function testUpdateOnlyExpression() { - $before_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchField(); + public function testUpdateOnlyExpression() { + $before_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchField(); $num_updated = db_update('test') ->condition('name', 'Ringo') - ->expression('age', 'age + :age', array(':age' => 4)) + ->expression('age', 'age + :age', [':age' => 4]) ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $after_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchField(); + $after_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchField(); $this->assertEqual($before_age + 4, $after_age, 'Age updated correctly'); } /** * Test UPDATE with a subselect value. */ - function testSubSelectUpdate() { + public function testSubSelectUpdate() { $subselect = db_select('test_task', 't'); - $subselect->addExpression('MAX(priority) + :increment', 'max_priority', array(':increment' => 30)); + $subselect->addExpression('MAX(priority) + :increment', 'max_priority', [':increment' => 30]); // Clone this to make sure we are running a different query when // asserting. $select = clone $subselect; @@ -136,7 +136,7 @@ function testSubSelectUpdate() { ->condition('name', 'Ringo'); // Save the number of rows that updated for assertion later. $num_updated = $query->execute(); - $after_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'Ringo'))->fetchField(); + $after_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Ringo'])->fetchField(); $expected_age = $select->execute()->fetchField(); $this->assertEqual($after_age, $expected_age); $this->assertEqual(1, $num_updated, t('Expected 1 row to be updated in subselect update query.')); diff --git a/core/tests/Drupal/KernelTests/Core/Database/UpdateLobTest.php b/core/tests/Drupal/KernelTests/Core/Database/UpdateLobTest.php index 57a14183..501f9183 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/UpdateLobTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/UpdateLobTest.php @@ -12,40 +12,40 @@ class UpdateLobTest extends DatabaseTestBase { /** * Confirms that we can update a blob column. */ - function testUpdateOneBlob() { + public function testUpdateOneBlob() { $data = "This is\000a test."; $this->assertTrue(strlen($data) === 15, 'Test data contains a NULL.'); $id = db_insert('test_one_blob') - ->fields(array('blob1' => $data)) + ->fields(['blob1' => $data]) ->execute(); $data .= $data; db_update('test_one_blob') ->condition('id', $id) - ->fields(array('blob1' => $data)) + ->fields(['blob1' => $data]) ->execute(); - $r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', array(':id' => $id))->fetchAssoc(); - $this->assertTrue($r['blob1'] === $data, format_string('Can update a blob: id @id, @data.', array('@id' => $id, '@data' => serialize($r)))); + $r = db_query('SELECT * FROM {test_one_blob} WHERE id = :id', [':id' => $id])->fetchAssoc(); + $this->assertTrue($r['blob1'] === $data, format_string('Can update a blob: id @id, @data.', ['@id' => $id, '@data' => serialize($r)])); } /** * Confirms that we can update two blob columns in the same table. */ - function testUpdateMultipleBlob() { + public function testUpdateMultipleBlob() { $id = db_insert('test_two_blobs') - ->fields(array( + ->fields([ 'blob1' => 'This is', 'blob2' => 'a test', - )) + ]) ->execute(); db_update('test_two_blobs') ->condition('id', $id) - ->fields(array('blob1' => 'and so', 'blob2' => 'is this')) + ->fields(['blob1' => 'and so', 'blob2' => 'is this']) ->execute(); - $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', array(':id' => $id))->fetchAssoc(); + $r = db_query('SELECT * FROM {test_two_blobs} WHERE id = :id', [':id' => $id])->fetchAssoc(); $this->assertTrue($r['blob1'] === 'and so' && $r['blob2'] === 'is this', 'Can update multiple blobs per row.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/UpdateTest.php b/core/tests/Drupal/KernelTests/Core/Database/UpdateTest.php index 25ad3cba..6bc91316 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/UpdateTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/UpdateTest.php @@ -12,93 +12,93 @@ class UpdateTest extends DatabaseTestBase { /** * Confirms that we can update a single record successfully. */ - function testSimpleUpdate() { + public function testSimpleUpdate() { $num_updated = db_update('test') - ->fields(array('name' => 'Tiffany')) + ->fields(['name' => 'Tiffany']) ->condition('id', 1) ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $saved_name = db_query('SELECT name FROM {test} WHERE id = :id', array(':id' => 1))->fetchField(); + $saved_name = db_query('SELECT name FROM {test} WHERE id = :id', [':id' => 1])->fetchField(); $this->assertIdentical($saved_name, 'Tiffany', 'Updated name successfully.'); } /** * Confirms updating to NULL. */ - function testSimpleNullUpdate() { + public function testSimpleNullUpdate() { $this->ensureSampleDataNull(); $num_updated = db_update('test_null') - ->fields(array('age' => NULL)) + ->fields(['age' => NULL]) ->condition('name', 'Kermit') ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $saved_age = db_query('SELECT age FROM {test_null} WHERE name = :name', array(':name' => 'Kermit'))->fetchField(); + $saved_age = db_query('SELECT age FROM {test_null} WHERE name = :name', [':name' => 'Kermit'])->fetchField(); $this->assertNull($saved_age, 'Updated name successfully.'); } /** * Confirms that we can update multiple records successfully. */ - function testMultiUpdate() { + public function testMultiUpdate() { $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) + ->fields(['job' => 'Musician']) ->condition('job', 'Singer') ->execute(); $this->assertIdentical($num_updated, 2, 'Updated 2 records.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '2', 'Updated fields successfully.'); } /** * Confirms that we can update multiple records with a non-equality condition. */ - function testMultiGTUpdate() { + public function testMultiGTUpdate() { $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) + ->fields(['job' => 'Musician']) ->condition('age', 26, '>') ->execute(); $this->assertIdentical($num_updated, 2, 'Updated 2 records.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '2', 'Updated fields successfully.'); } /** * Confirms that we can update multiple records with a where call. */ - function testWhereUpdate() { + public function testWhereUpdate() { $num_updated = db_update('test') - ->fields(array('job' => 'Musician')) - ->where('age > :age', array(':age' => 26)) + ->fields(['job' => 'Musician']) + ->where('age > :age', [':age' => 26]) ->execute(); $this->assertIdentical($num_updated, 2, 'Updated 2 records.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '2', 'Updated fields successfully.'); } /** * Confirms that we can stack condition and where calls. */ - function testWhereAndConditionUpdate() { + public function testWhereAndConditionUpdate() { $update = db_update('test') - ->fields(array('job' => 'Musician')) - ->where('age > :age', array(':age' => 26)) + ->fields(['job' => 'Musician']) + ->where('age > :age', [':age' => 26]) ->condition('name', 'Ringo'); $num_updated = $update->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', array(':job' => 'Musician'))->fetchField(); + $num_matches = db_query('SELECT COUNT(*) FROM {test} WHERE job = :job', [':job' => 'Musician'])->fetchField(); $this->assertIdentical($num_matches, '1', 'Updated fields successfully.'); } /** * Tests updating with expressions. */ - function testExpressionUpdate() { + public function testExpressionUpdate() { // Ensure that expressions are handled properly. This should set every // record's age to a square of itself. $num_rows = db_update('test') @@ -106,14 +106,14 @@ function testExpressionUpdate() { ->execute(); $this->assertIdentical($num_rows, 4, 'Updated 4 records.'); - $saved_name = db_query('SELECT name FROM {test} WHERE age = :age', array(':age' => pow(26, 2)))->fetchField(); + $saved_name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => pow(26, 2)])->fetchField(); $this->assertIdentical($saved_name, 'Paul', 'Successfully updated values using an algebraic expression.'); } /** * Tests return value on update. */ - function testUpdateAffectedRows() { + public function testUpdateAffectedRows() { // At 5am in the morning, all band members but those with a priority 1 task // are sleeping. So we set their tasks to 'sleep'. 5 records match the // condition and therefore are affected by the query, even though two of @@ -122,7 +122,7 @@ function testUpdateAffectedRows() { // because that's cross-db expected behavior. $num_rows = db_update('test_task') ->condition('priority', 1, '<>') - ->fields(array('task' => 'sleep')) + ->fields(['task' => 'sleep']) ->execute(); $this->assertIdentical($num_rows, 5, 'Correctly returned 5 affected rows.'); } @@ -130,28 +130,28 @@ function testUpdateAffectedRows() { /** * Confirm that we can update the primary key of a record successfully. */ - function testPrimaryKeyUpdate() { + public function testPrimaryKeyUpdate() { $num_updated = db_update('test') - ->fields(array('id' => 42, 'name' => 'John')) + ->fields(['id' => 42, 'name' => 'John']) ->condition('id', 1) ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - $saved_name = db_query('SELECT name FROM {test} WHERE id = :id', array(':id' => 42))->fetchField(); + $saved_name = db_query('SELECT name FROM {test} WHERE id = :id', [':id' => 42])->fetchField(); $this->assertIdentical($saved_name, 'John', 'Updated primary key successfully.'); } /** * Confirm that we can update values in a column with special name. */ - function testSpecialColumnUpdate() { + public function testSpecialColumnUpdate() { $num_updated = db_update('test_special_columns') - ->fields(array('offset' => 'New offset value')) + ->fields(['offset' => 'New offset value']) ->condition('id', 1) ->execute(); $this->assertIdentical($num_updated, 1, 'Updated 1 special column record.'); - $saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', array(':id' => 1))->fetchField(); + $saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', [':id' => 1])->fetchField(); $this->assertIdentical($saved_value, 'New offset value', 'Updated special column name value successfully.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Database/UpsertTest.php b/core/tests/Drupal/KernelTests/Core/Database/UpsertTest.php index 9b8e167e..5c62f87f 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/UpsertTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/UpsertTest.php @@ -42,12 +42,12 @@ public function testUpsert() { $num_records_after = $connection->query('SELECT COUNT(*) FROM {test_people}')->fetchField(); $this->assertEqual($num_records_before + 1, $num_records_after, 'Rows were inserted and updated properly.'); - $person = $connection->query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Presenter'))->fetch(); + $person = $connection->query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Presenter'])->fetch(); $this->assertEqual($person->job, 'Presenter', 'Job set correctly.'); $this->assertEqual($person->age, 31, 'Age set correctly.'); $this->assertEqual($person->name, 'Tiffany', 'Name set correctly.'); - $person = $connection->query('SELECT * FROM {test_people} WHERE job = :job', array(':job' => 'Speaker'))->fetch(); + $person = $connection->query('SELECT * FROM {test_people} WHERE job = :job', [':job' => 'Speaker'])->fetch(); $this->assertEqual($person->job, 'Speaker', 'Job was not changed.'); $this->assertEqual($person->age, 32, 'Age updated correctly.'); $this->assertEqual($person->name, 'Meredith', 'Name was not changed.'); diff --git a/core/tests/Drupal/KernelTests/Core/Datetime/FormatDateTest.php b/core/tests/Drupal/KernelTests/Core/Datetime/FormatDateTest.php index 5fbb4dff..036b385a 100644 --- a/core/tests/Drupal/KernelTests/Core/Datetime/FormatDateTest.php +++ b/core/tests/Drupal/KernelTests/Core/Datetime/FormatDateTest.php @@ -51,6 +51,8 @@ protected function setUp() { public function testFormatDate() { /** @var \Drupal\Core\Datetime\DateFormatterInterface $formatter */ $formatter = $this->container->get('date.formatter'); + /** @var \Drupal\Core\Language\LanguageManagerInterface $language_manager */ + $language_manager = $this->container->get('language_manager'); $timestamp = strtotime('2007-03-26T00:00:00+00:00'); $this->assertSame('Sunday, 25-Mar-07 17:00:00 PDT', $formatter->format($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Test all parameters.'); @@ -59,6 +61,14 @@ public function testFormatDate() { $this->assertSame('\\domingo, 25-Mar-07 17:00:00 PDT', $formatter->format($timestamp, 'custom', '\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'Test format containing backslash character.'); $this->assertSame('\\l, 25-Mar-07 17:00:00 PDT', $formatter->format($timestamp, 'custom', '\\\\\\l, d-M-y H:i:s T', 'America/Los_Angeles', self::LANGCODE), 'Test format containing backslash followed by escaped format string.'); $this->assertSame('Monday, 26-Mar-07 01:00:00 BST', $formatter->format($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London', 'en'), 'Test a different time zone.'); + $this->assertSame('Thu, 01/01/1970 - 00:00', $formatter->format(0, 'custom', '', 'UTC', 'en'), 'Test custom format with empty string.'); + + // Make sure we didn't change the configuration override language. + $this->assertSame('en', $language_manager->getConfigOverrideLanguage()->getId(), 'Configuration override language not disturbed,'); + + // Test bad format string will use the fallback format. + $this->assertSame($formatter->format($timestamp, 'fallback'), $formatter->format($timestamp, 'bad_format_string'), 'Test fallback format.'); + $this->assertSame('en', $language_manager->getConfigOverrideLanguage()->getId(), 'Configuration override language not disturbed,'); // Change the default language and timezone. $this->config('system.site')->set('default_langcode', static::LANGCODE)->save(); @@ -66,7 +76,8 @@ public function testFormatDate() { // Reset the language manager so new negotiations attempts will fall back on // on the new language. - $this->container->get('language_manager')->reset(); + $language_manager->reset(); + $this->assertSame('en', $language_manager->getConfigOverrideLanguage()->getId(), 'Configuration override language not disturbed,'); $this->assertSame('Sunday, 25-Mar-07 17:00:00 PDT', $formatter->format($timestamp, 'custom', 'l, d-M-y H:i:s T', 'America/Los_Angeles', 'en'), 'Test a different language.'); $this->assertSame('Monday, 26-Mar-07 01:00:00 BST', $formatter->format($timestamp, 'custom', 'l, d-M-y H:i:s T', 'Europe/London'), 'Test a different time zone.'); @@ -84,6 +95,13 @@ public function testFormatDate() { $this->assertSame('2007-03', $formatter->format($timestamp, 'html_month'), 'Test html_month date format.'); $this->assertSame('2007', $formatter->format($timestamp, 'html_year'), 'Test html_year date format.'); + // Make sure we didn't change the configuration override language. + $this->assertSame('en', $language_manager->getConfigOverrideLanguage()->getId(), 'Configuration override language not disturbed,'); + + // Test bad format string will use the fallback format. + $this->assertSame($formatter->format($timestamp, 'fallback'), $formatter->format($timestamp, 'bad_format_string'), 'Test fallback format.'); + $this->assertSame('en', $language_manager->getConfigOverrideLanguage()->getId(), 'Configuration override language not disturbed,'); + // HTML is not escaped by the date formatter, it must be escaped later. $this->assertSame("", $formatter->format($timestamp, 'custom', '\<\s\c\r\i\p\t\>\a\l\e\r\t\(\'Y\'\)\;\<\/\s\c\r\i\p\t\>'), 'Script tags not removed from dates.'); $this->assertSame('2007', $formatter->format($timestamp, 'custom', '\<\e\m\>Y\<\/\e\m\>'), 'Em tags are not removed from dates.'); diff --git a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php index 7778a5a4..b5cb96b8 100644 --- a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php +++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php @@ -60,10 +60,10 @@ protected function getTestKernel(Request $request, array $modules_enabled = NULL */ public function testCompileDIC() { // @todo: write a memory based storage backend for testing. - $modules_enabled = array( + $modules_enabled = [ 'system' => 'system', 'user' => 'user', - ); + ]; $request = Request::createFromGlobals(); $this->getTestKernel($request, $modules_enabled); @@ -128,16 +128,16 @@ public function testCompileDIC() { // Check that the location of the new module is registered. $modules = $container->getParameter('container.modules'); - $this->assertEqual($modules['service_provider_test'], array( + $this->assertEqual($modules['service_provider_test'], [ 'type' => 'module', 'pathname' => drupal_get_filename('module', 'service_provider_test'), 'filename' => NULL, - )); + ]); // Check that the container itself is not among the persist IDs because it // does not make sense to persist the container itself. $persist_ids = $container->getParameter('persist_ids'); - $this->assertIdentical(FALSE, array_search('service_container', $persist_ids)); + $this->assertSame(FALSE, array_search('service_container', $persist_ids)); } /** @@ -169,10 +169,10 @@ public function testRepeatedBootWithDifferentEnvironment() { */ public function testPreventChangeOfSitePath() { // @todo: write a memory based storage backend for testing. - $modules_enabled = array( + $modules_enabled = [ 'system' => 'system', 'user' => 'user', - ); + ]; $request = Request::createFromGlobals(); $kernel = $this->getTestKernel($request, $modules_enabled); @@ -184,6 +184,11 @@ public function testPreventChangeOfSitePath() { $pass = TRUE; } $this->assertTrue($pass, 'Throws LogicException if DrupalKernel::setSitePath() is called after boot'); + + // Ensure no LogicException if DrupalKernel::setSitePath() is called with + // identical path after boot. + $path = $kernel->getSitePath(); + $kernel->setSitePath($path); } } diff --git a/core/tests/Drupal/KernelTests/Core/DrupalKernel/ServiceDestructionTest.php b/core/tests/Drupal/KernelTests/Core/DrupalKernel/ServiceDestructionTest.php index f4fe0945..1716280d 100644 --- a/core/tests/Drupal/KernelTests/Core/DrupalKernel/ServiceDestructionTest.php +++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/ServiceDestructionTest.php @@ -17,7 +17,7 @@ class ServiceDestructionTest extends KernelTestBase { */ public function testDestructionUsed() { // Enable the test module to add it to the container. - $this->enableModules(array('service_provider_test')); + $this->enableModules(['service_provider_test']); $request = $this->container->get('request_stack')->getCurrentRequest(); $kernel = $this->container->get('kernel'); @@ -39,7 +39,7 @@ public function testDestructionUsed() { */ public function testDestructionUnused() { // Enable the test module to add it to the container. - $this->enableModules(array('service_provider_test')); + $this->enableModules(['service_provider_test']); $request = $this->container->get('request_stack')->getCurrentRequest(); $kernel = $this->container->get('kernel'); diff --git a/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php index ca4e5015..b5b9ffd5 100644 --- a/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php +++ b/core/tests/Drupal/KernelTests/Core/Element/PathElementFormTest.php @@ -30,7 +30,7 @@ class PathElementFormTest extends KernelTestBase implements FormInterface { * * @var array */ - public static $modules = array('system', 'user'); + public static $modules = ['system', 'user']; /** * Sets up the test. @@ -41,16 +41,16 @@ protected function setUp() { $this->installEntitySchema('user'); \Drupal::service('router.builder')->rebuild(); /** @var \Drupal\user\RoleInterface $role */ - $role = Role::create(array( + $role = Role::create([ 'id' => 'admin', 'label' => 'admin', - )); + ]); $role->grantPermission('link to any page'); $role->save(); - $this->testUser = User::create(array( + $this->testUser = User::create([ 'name' => 'foobar', 'mail' => 'foobar@example.com', - )); + ]); $this->testUser->addRole($role->id()); $this->testUser->save(); \Drupal::service('current_user')->setAccount($this->testUser); @@ -68,57 +68,57 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state) { // A required validated path. - $form['required_validate'] = array( + $form['required_validate'] = [ '#type' => 'path', '#required' => TRUE, '#title' => 'required_validate', '#convert_path' => PathElement::CONVERT_NONE, - ); + ]; // A non validated required path. - $form['required_non_validate'] = array( + $form['required_non_validate'] = [ '#type' => 'path', '#required' => TRUE, '#title' => 'required_non_validate', '#convert_path' => PathElement::CONVERT_NONE, '#validate_path' => FALSE, - ); + ]; // A non required validated path. - $form['optional_validate'] = array( + $form['optional_validate'] = [ '#type' => 'path', '#required' => FALSE, '#title' => 'optional_validate', '#convert_path' => PathElement::CONVERT_NONE, - ); + ]; // A non required converted path. - $form['optional_validate'] = array( + $form['optional_validate'] = [ '#type' => 'path', '#required' => FALSE, '#title' => 'optional_validate', '#convert_path' => PathElement::CONVERT_ROUTE, - ); + ]; // A converted required validated path. - $form['required_validate_route'] = array( + $form['required_validate_route'] = [ '#type' => 'path', '#required' => TRUE, '#title' => 'required_validate_route', - ); + ]; // A converted required validated path. - $form['required_validate_url'] = array( + $form['required_validate_url'] = [ '#type' => 'path', '#required' => TRUE, '#title' => 'required_validate_url', '#convert_path' => PathElement::CONVERT_URL, - ); + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } @@ -154,19 +154,19 @@ public function testPathElement() { // Valid form state. $this->assertEqual(count($form_state->getErrors()), 0); - $this->assertEqual($form_state->getValue('required_validate_route'), array( + $this->assertEqual($form_state->getValue('required_validate_route'), [ 'route_name' => 'entity.user.canonical', - 'route_parameters' => array( + 'route_parameters' => [ 'user' => $this->testUser->id(), - ), - )); + ], + ]); /** @var \Drupal\Core\Url $url */ $url = $form_state->getValue('required_validate_url'); $this->assertTrue($url instanceof Url); $this->assertEqual($url->getRouteName(), 'entity.user.canonical'); - $this->assertEqual($url->getRouteParameters(), array( + $this->assertEqual($url->getRouteParameters(), [ 'user' => $this->testUser->id(), - )); + ]); // Test #required. $form_state = (new FormState()) @@ -179,7 +179,7 @@ public function testPathElement() { $errors = $form_state->getErrors(); // Should be missing 'required_validate' field. $this->assertEqual(count($errors), 1); - $this->assertEqual($errors, array('required_validate' => t('@name field is required.', array('@name' => 'required_validate')))); + $this->assertEqual($errors, ['required_validate' => t('@name field is required.', ['@name' => 'required_validate'])]); // Test invalid parameters. $form_state = (new FormState()) @@ -195,11 +195,11 @@ public function testPathElement() { // Valid form state. $errors = $form_state->getErrors(); $this->assertEqual(count($errors), 3); - $this->assertEqual($errors, array( - 'required_validate' => t('This path does not exist or you do not have permission to link to %path.', array('%path' => 'user/74')), - 'required_validate_route' => t('This path does not exist or you do not have permission to link to %path.', array('%path' => 'user/74')), - 'required_validate_url' => t('This path does not exist or you do not have permission to link to %path.', array('%path' => 'user/74')), - )); + $this->assertEqual($errors, [ + 'required_validate' => t('This path does not exist or you do not have permission to link to %path.', ['%path' => 'user/74']), + 'required_validate_route' => t('This path does not exist or you do not have permission to link to %path.', ['%path' => 'user/74']), + 'required_validate_url' => t('This path does not exist or you do not have permission to link to %path.', ['%path' => 'user/74']), + ]); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/BundleConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/BundleConstraintValidatorTest.php index 2219487d..613ba4e1 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/BundleConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/BundleConstraintValidatorTest.php @@ -19,7 +19,7 @@ class BundleConstraintValidatorTest extends KernelTestBase { */ protected $typedData; - public static $modules = array('node', 'field', 'text', 'user'); + public static $modules = ['node', 'field', 'text', 'user']; protected function setUp() { parent::setUp(); @@ -32,7 +32,7 @@ protected function setUp() { */ public function testValidation() { // Test with multiple values. - $this->assertValidation(array('foo', 'bar')); + $this->assertValidation(['foo', 'bar']); // Test with a single string value as well. $this->assertValidation('foo'); } @@ -49,14 +49,14 @@ protected function assertValidation($bundle) { ->addConstraint('Bundle', $bundle); // Test the validation. - $node = $this->container->get('entity.manager')->getStorage('node')->create(array('type' => 'foo')); + $node = $this->container->get('entity.manager')->getStorage('node')->create(['type' => 'foo']); $typed_data = $this->typedData->create($definition, $node); $violations = $typed_data->validate(); $this->assertEqual($violations->count(), 0, 'Validation passed for correct value.'); // Test the validation when an invalid value is passed. - $page_node = $this->container->get('entity.manager')->getStorage('node')->create(array('type' => 'baz')); + $page_node = $this->container->get('entity.manager')->getStorage('node')->create(['type' => 'baz']); $typed_data = $this->typedData->create($definition, $page_node); $violations = $typed_data->validate(); @@ -64,7 +64,7 @@ protected function assertValidation($bundle) { // Make sure the information provided by a violation is correct. $violation = $violations[0]; - $this->assertEqual($violation->getMessage(), t('The entity must be of bundle %bundle.', array('%bundle' => implode(', ', (array) $bundle))), 'The message for invalid value is correct.'); + $this->assertEqual($violation->getMessage(), t('The entity must be of bundle %bundle.', ['%bundle' => implode(', ', (array) $bundle)]), 'The message for invalid value is correct.'); $this->assertEqual($violation->getRoot(), $typed_data, 'Violation root is correct.'); $this->assertEqual($violation->getInvalidValue(), $page_node, 'The invalid value is set correctly in the violation.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php index 22cae65f..56050a7d 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ConfigEntityQueryTest.php @@ -19,7 +19,7 @@ class ConfigEntityQueryTest extends KernelTestBase { * * @var array */ - public static $modules = array('config_test'); + public static $modules = ['config_test']; /** * Stores the search results for alter comparison. @@ -45,7 +45,7 @@ class ConfigEntityQueryTest extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->entities = array(); + $this->entities = []; $this->factory = $this->container->get('entity.query'); // These two are here to make sure that matchArray needs to go over several @@ -54,56 +54,56 @@ protected function setUp() { $array['level1a']['level2'] = 9; // The tests match array.level1.level2. $array['level1']['level2'] = 1; - $entity = ConfigQueryTest::create(array( + $entity = ConfigQueryTest::create([ 'label' => $this->randomMachineName(), 'id' => '1', 'number' => 31, 'array' => $array, - )); + ]); $this->entities[] = $entity; $entity->enforceIsNew(); $entity->save(); $array['level1']['level2'] = 2; - $entity = ConfigQueryTest::create(array( + $entity = ConfigQueryTest::create([ 'label' => $this->randomMachineName(), 'id' => '2', 'number' => 41, 'array' => $array, - )); + ]); $this->entities[] = $entity; $entity->enforceIsNew(); $entity->save(); $array['level1']['level2'] = 1; - $entity = ConfigQueryTest::create(array( + $entity = ConfigQueryTest::create([ 'label' => 'test_prefix_' . $this->randomMachineName(), 'id' => '3', 'number' => 59, 'array' => $array, - )); + ]); $this->entities[] = $entity; $entity->enforceIsNew(); $entity->save(); $array['level1']['level2'] = 2; - $entity = ConfigQueryTest::create(array( + $entity = ConfigQueryTest::create([ 'label' => $this->randomMachineName() . '_test_suffix', 'id' => '4', 'number' => 26, 'array' => $array, - )); + ]); $this->entities[] = $entity; $entity->enforceIsNew(); $entity->save(); $array['level1']['level2'] = 3; - $entity = ConfigQueryTest::create(array( + $entity = ConfigQueryTest::create([ 'label' => $this->randomMachineName() . '_TEST_contains_' . $this->randomMachineName(), 'id' => '5', 'number' => 53, 'array' => $array, - )); + ]); $this->entities[] = $entity; $entity->enforceIsNew(); $entity->save(); @@ -116,84 +116,84 @@ public function testConfigEntityQuery() { // Run a test without any condition. $this->queryResults = $this->factory->get('config_query_test') ->execute(); - $this->assertResults(array('1', '2', '3', '4', '5')); + $this->assertResults(['1', '2', '3', '4', '5']); // No conditions, OR. $this->queryResults = $this->factory->get('config_query_test', 'OR') ->execute(); - $this->assertResults(array('1', '2', '3', '4', '5')); + $this->assertResults(['1', '2', '3', '4', '5']); // Filter by ID with equality. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3') ->execute(); - $this->assertResults(array('3')); + $this->assertResults(['3']); // Filter by label with a known prefix. $this->queryResults = $this->factory->get('config_query_test') ->condition('label', 'test_prefix', 'STARTS_WITH') ->execute(); - $this->assertResults(array('3')); + $this->assertResults(['3']); // Filter by label with a known suffix. $this->queryResults = $this->factory->get('config_query_test') ->condition('label', 'test_suffix', 'ENDS_WITH') ->execute(); - $this->assertResults(array('4')); + $this->assertResults(['4']); // Filter by label with a known containing word. $this->queryResults = $this->factory->get('config_query_test') ->condition('label', 'test_contains', 'CONTAINS') ->execute(); - $this->assertResults(array('5')); + $this->assertResults(['5']); // Filter by ID with the IN operator. $this->queryResults = $this->factory->get('config_query_test') - ->condition('id', array('2', '3'), 'IN') + ->condition('id', ['2', '3'], 'IN') ->execute(); - $this->assertResults(array('2', '3')); + $this->assertResults(['2', '3']); // Filter by ID with the implicit IN operator. $this->queryResults = $this->factory->get('config_query_test') - ->condition('id', array('2', '3')) + ->condition('id', ['2', '3']) ->execute(); - $this->assertResults(array('2', '3')); + $this->assertResults(['2', '3']); // Filter by ID with the > operator. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '>') ->execute(); - $this->assertResults(array('4', '5')); + $this->assertResults(['4', '5']); // Filter by ID with the >= operator. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '>=') ->execute(); - $this->assertResults(array('3', '4', '5')); + $this->assertResults(['3', '4', '5']); // Filter by ID with the <> operator. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '<>') ->execute(); - $this->assertResults(array('1', '2', '4', '5')); + $this->assertResults(['1', '2', '4', '5']); // Filter by ID with the < operator. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '<') ->execute(); - $this->assertResults(array('1', '2')); + $this->assertResults(['1', '2']); // Filter by ID with the <= operator. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '<=') ->execute(); - $this->assertResults(array('1', '2', '3')); + $this->assertResults(['1', '2', '3']); // Filter by two conditions on the same field. $this->queryResults = $this->factory->get('config_query_test') ->condition('label', 'test_pref', 'STARTS_WITH') ->condition('label', 'test_prefix', 'STARTS_WITH') ->execute(); - $this->assertResults(array('3')); + $this->assertResults(['3']); // Filter by two conditions on different fields. The first query matches for // a different ID, so the result is empty. @@ -201,7 +201,7 @@ public function testConfigEntityQuery() { ->condition('label', 'test_prefix', 'STARTS_WITH') ->condition('id', '5') ->execute(); - $this->assertResults(array()); + $this->assertResults([]); // Filter by two different conditions on different fields. This time the // first condition matches on one item, but the second one does as well. @@ -209,7 +209,7 @@ public function testConfigEntityQuery() { ->condition('label', 'test_prefix', 'STARTS_WITH') ->condition('id', '3') ->execute(); - $this->assertResults(array('3')); + $this->assertResults(['3']); // Filter by two different conditions, of which the first one matches for // every entry, the second one as well, but just the third one filters so @@ -219,37 +219,37 @@ public function testConfigEntityQuery() { ->condition('number', 10, '>=') ->condition('number', 50, '>=') ->execute(); - $this->assertResults(array('3', '5')); + $this->assertResults(['3', '5']); // Filter with an OR condition group. $this->queryResults = $this->factory->get('config_query_test', 'OR') ->condition('id', 1) ->condition('id', '2') ->execute(); - $this->assertResults(array('1', '2')); + $this->assertResults(['1', '2']); // Simplify it with IN. $this->queryResults = $this->factory->get('config_query_test') - ->condition('id', array('1', '2')) + ->condition('id', ['1', '2']) ->execute(); - $this->assertResults(array('1', '2')); + $this->assertResults(['1', '2']); // Try explicit IN. $this->queryResults = $this->factory->get('config_query_test') - ->condition('id', array('1', '2'), 'IN') + ->condition('id', ['1', '2'], 'IN') ->execute(); - $this->assertResults(array('1', '2')); + $this->assertResults(['1', '2']); // Try not IN. $this->queryResults = $this->factory->get('config_query_test') - ->condition('id', array('1', '2'), 'NOT IN') + ->condition('id', ['1', '2'], 'NOT IN') ->execute(); - $this->assertResults(array('3', '4', '5')); + $this->assertResults(['3', '4', '5']); // Filter with an OR condition group on different fields. $this->queryResults = $this->factory->get('config_query_test', 'OR') ->condition('id', 1) ->condition('number', 41) ->execute(); - $this->assertResults(array('1', '2')); + $this->assertResults(['1', '2']); // Filter with an OR condition group on different fields but matching on the // same entity. @@ -257,7 +257,7 @@ public function testConfigEntityQuery() { ->condition('id', 1) ->condition('number', 31) ->execute(); - $this->assertResults(array('1')); + $this->assertResults(['1']); // NO simple conditions, YES complex conditions, 'AND'. $query = $this->factory->get('config_query_test', 'AND'); @@ -271,7 +271,7 @@ public function testConfigEntityQuery() { ->condition($and_condition_1) ->condition($and_condition_2) ->execute(); - $this->assertResults(array('1')); + $this->assertResults(['1']); // NO simple conditions, YES complex conditions, 'OR'. $query = $this->factory->get('config_query_test', 'OR'); @@ -285,7 +285,7 @@ public function testConfigEntityQuery() { ->condition($and_condition_1) ->condition($and_condition_2) ->execute(); - $this->assertResults(array('1', '2')); + $this->assertResults(['1', '2']); // YES simple conditions, YES complex conditions, 'AND'. $query = $this->factory->get('config_query_test', 'AND'); @@ -300,7 +300,7 @@ public function testConfigEntityQuery() { ->condition($and_condition_1) ->condition($and_condition_2) ->execute(); - $this->assertResults(array('1')); + $this->assertResults(['1']); // YES simple conditions, YES complex conditions, 'OR'. $query = $this->factory->get('config_query_test', 'OR'); @@ -315,28 +315,28 @@ public function testConfigEntityQuery() { ->condition($and_condition_1) ->condition($and_condition_2) ->execute(); - $this->assertResults(array('1', '2', '4', '5')); + $this->assertResults(['1', '2', '4', '5']); // Test the exists and notExists conditions. $this->queryResults = $this->factory->get('config_query_test') ->exists('id') ->execute(); - $this->assertResults(array('1', '2', '3', '4', '5')); + $this->assertResults(['1', '2', '3', '4', '5']); $this->queryResults = $this->factory->get('config_query_test') ->exists('non-existent') ->execute(); - $this->assertResults(array()); + $this->assertResults([]); $this->queryResults = $this->factory->get('config_query_test') ->notExists('id') ->execute(); - $this->assertResults(array()); + $this->assertResults([]); $this->queryResults = $this->factory->get('config_query_test') ->notExists('non-existent') ->execute(); - $this->assertResults(array('1', '2', '3', '4', '5')); + $this->assertResults(['1', '2', '3', '4', '5']); } /** @@ -344,10 +344,10 @@ public function testConfigEntityQuery() { */ public function testStringIdConditions() { // We need an entity with a non-numeric ID. - $entity = ConfigQueryTest::create(array( + $entity = ConfigQueryTest::create([ 'label' => $this->randomMachineName(), 'id' => 'foo.bar', - )); + ]); $this->entities[] = $entity; $entity->enforceIsNew(); $entity->save(); @@ -356,43 +356,43 @@ public function testStringIdConditions() { $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'foo.bar', 'STARTS_WITH') ->execute(); - $this->assertResults(array('foo.bar')); + $this->assertResults(['foo.bar']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'f', 'STARTS_WITH') ->execute(); - $this->assertResults(array('foo.bar')); + $this->assertResults(['foo.bar']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'miss', 'STARTS_WITH') ->execute(); - $this->assertResults(array()); + $this->assertResults([]); // Test 'CONTAINS' condition. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'foo.bar', 'CONTAINS') ->execute(); - $this->assertResults(array('foo.bar')); + $this->assertResults(['foo.bar']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'oo.ba', 'CONTAINS') ->execute(); - $this->assertResults(array('foo.bar')); + $this->assertResults(['foo.bar']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'miss', 'CONTAINS') ->execute(); - $this->assertResults(array()); + $this->assertResults([]); // Test 'ENDS_WITH' condition. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'foo.bar', 'ENDS_WITH') ->execute(); - $this->assertResults(array('foo.bar')); + $this->assertResults(['foo.bar']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'r', 'ENDS_WITH') ->execute(); - $this->assertResults(array('foo.bar')); + $this->assertResults(['foo.bar']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', 'miss', 'ENDS_WITH') ->execute(); - $this->assertResults(array()); + $this->assertResults([]); } /** @@ -429,62 +429,62 @@ public function testSortRange() { $this->queryResults = $this->factory->get('config_query_test') ->sort('number', 'DESC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('3', '5', '2', '1', '4')); + $this->assertIdentical(array_values($this->queryResults), ['3', '5', '2', '1', '4']); $this->queryResults = $this->factory->get('config_query_test') ->sort('number', 'ASC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('4', '1', '2', '5', '3')); + $this->assertIdentical(array_values($this->queryResults), ['4', '1', '2', '5', '3']); // Apply some filters and sort. $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '>') ->sort('number', 'DESC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('5', '4')); + $this->assertIdentical(array_values($this->queryResults), ['5', '4']); $this->queryResults = $this->factory->get('config_query_test') ->condition('id', '3', '>') ->sort('number', 'ASC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('4', '5')); + $this->assertIdentical(array_values($this->queryResults), ['4', '5']); // Apply a pager and sort. $this->queryResults = $this->factory->get('config_query_test') ->sort('number', 'DESC') ->range('2', '2') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('2', '1')); + $this->assertIdentical(array_values($this->queryResults), ['2', '1']); $this->queryResults = $this->factory->get('config_query_test') ->sort('number', 'ASC') ->range('2', '2') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('2', '5')); + $this->assertIdentical(array_values($this->queryResults), ['2', '5']); // Add a range to a query without a start parameter. $this->queryResults = $this->factory->get('config_query_test') ->range(0, '3') ->sort('id', 'ASC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('1', '2', '3')); + $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3']); // Apply a pager with limit 4. $this->queryResults = $this->factory->get('config_query_test') ->pager('4', 0) ->sort('id', 'ASC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('1', '2', '3', '4')); + $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3', '4']); } /** * Tests sorting with tableSort on config entity queries. */ public function testTableSort() { - $header = array( - array('data' => t('ID'), 'specifier' => 'id'), - array('data' => t('Number'), 'specifier' => 'number'), - ); + $header = [ + ['data' => t('ID'), 'specifier' => 'id'], + ['data' => t('Number'), 'specifier' => 'number'], + ]; // Sort key: id // Sorting with 'DESC' upper case @@ -492,28 +492,28 @@ public function testTableSort() { ->tableSort($header) ->sort('id', 'DESC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('5', '4', '3', '2', '1')); + $this->assertIdentical(array_values($this->queryResults), ['5', '4', '3', '2', '1']); // Sorting with 'ASC' upper case $this->queryResults = $this->factory->get('config_query_test') ->tableSort($header) ->sort('id', 'ASC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('1', '2', '3', '4', '5')); + $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3', '4', '5']); // Sorting with 'desc' lower case $this->queryResults = $this->factory->get('config_query_test') ->tableSort($header) ->sort('id', 'desc') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('5', '4', '3', '2', '1')); + $this->assertIdentical(array_values($this->queryResults), ['5', '4', '3', '2', '1']); // Sorting with 'asc' lower case $this->queryResults = $this->factory->get('config_query_test') ->tableSort($header) ->sort('id', 'asc') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('1', '2', '3', '4', '5')); + $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3', '4', '5']); // Sort key: number // Sorting with 'DeSc' mixed upper and lower case @@ -521,28 +521,28 @@ public function testTableSort() { ->tableSort($header) ->sort('number', 'DeSc') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('3', '5', '2', '1', '4')); + $this->assertIdentical(array_values($this->queryResults), ['3', '5', '2', '1', '4']); // Sorting with 'AsC' mixed upper and lower case $this->queryResults = $this->factory->get('config_query_test') ->tableSort($header) ->sort('number', 'AsC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('4', '1', '2', '5', '3')); + $this->assertIdentical(array_values($this->queryResults), ['4', '1', '2', '5', '3']); // Sorting with 'dEsC' mixed upper and lower case $this->queryResults = $this->factory->get('config_query_test') ->tableSort($header) ->sort('number', 'dEsC') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('3', '5', '2', '1', '4')); + $this->assertIdentical(array_values($this->queryResults), ['3', '5', '2', '1', '4']); // Sorting with 'aSc' mixed upper and lower case $this->queryResults = $this->factory->get('config_query_test') ->tableSort($header) ->sort('number', 'aSc') ->execute(); - $this->assertIdentical(array_values($this->queryResults), array('4', '1', '2', '5', '3')); + $this->assertIdentical(array_values($this->queryResults), ['4', '1', '2', '5', '3']); } /** @@ -552,26 +552,53 @@ public function testDotted() { $this->queryResults = $this->factory->get('config_query_test') ->condition('array.level1.*', 1) ->execute(); - $this->assertResults(array('1', '3')); + $this->assertResults(['1', '3']); $this->queryResults = $this->factory->get('config_query_test') ->condition('*.level1.level2', 2) ->execute(); - $this->assertResults(array('2', '4')); + $this->assertResults(['2', '4']); $this->queryResults = $this->factory->get('config_query_test') ->condition('array.level1.*', 3) ->execute(); - $this->assertResults(array('5')); + $this->assertResults(['5']); $this->queryResults = $this->factory->get('config_query_test') ->condition('array.level1.level2', 3) ->execute(); - $this->assertResults(array('5')); + $this->assertResults(['5']); // Make sure that values on the wildcard level do not match if there are // sub-keys defined. This must not find anything even if entity 2 has a // top-level key number with value 41. $this->queryResults = $this->factory->get('config_query_test') ->condition('*.level1.level2', 41) ->execute(); - $this->assertResults(array()); + $this->assertResults([]); + // Make sure that "IS NULL" and "IS NOT NULL" work correctly with + // array-valued fields/keys. + $all = ['1', '2', '3', '4', '5']; + $this->queryResults = $this->factory->get('config_query_test') + ->exists('array.level1.level2') + ->execute(); + $this->assertResults($all); + $this->queryResults = $this->factory->get('config_query_test') + ->exists('array.level1') + ->execute(); + $this->assertResults($all); + $this->queryResults = $this->factory->get('config_query_test') + ->exists('array') + ->execute(); + $this->assertResults($all); + $this->queryResults = $this->factory->get('config_query_test') + ->notExists('array.level1.level2') + ->execute(); + $this->assertResults([]); + $this->queryResults = $this->factory->get('config_query_test') + ->notExists('array.level1') + ->execute(); + $this->assertResults([]); + $this->queryResults = $this->factory->get('config_query_test') + ->notExists('array') + ->execute(); + $this->assertResults([]); } /** @@ -582,12 +609,12 @@ public function testCaseSensitivity() { $this->queryResults = $this->factory->get('config_query_test') ->condition('label', 'TEST', 'CONTAINS') ->execute(); - $this->assertResults(array('3', '4', '5')); + $this->assertResults(['3', '4', '5']); $this->queryResults = $this->factory->get('config_query_test') ->condition('label', 'test', 'CONTAINS') ->execute(); - $this->assertResults(array('3', '4', '5')); + $this->assertResults(['3', '4', '5']); } /** @@ -599,11 +626,11 @@ public function testLookupKeys() { $key_value = $this->container->get('keyvalue')->get(QueryFactory::CONFIG_LOOKUP_PREFIX . 'config_test'); $test_entities = []; - $entity = entity_create('config_test', array( + $entity = entity_create('config_test', [ 'label' => $this->randomMachineName(), 'id' => '1', 'style' => 'test', - )); + ]); $test_entities[$entity->getConfigDependencyName()] = $entity; $entity->enforceIsNew(); $entity->save(); @@ -612,22 +639,22 @@ public function testLookupKeys() { $expected[] = $entity->getConfigDependencyName(); $this->assertEqual($expected, $key_value->get('style:test')); - $entity = entity_create('config_test', array( + $entity = entity_create('config_test', [ 'label' => $this->randomMachineName(), 'id' => '2', 'style' => 'test', - )); + ]); $test_entities[$entity->getConfigDependencyName()] = $entity; $entity->enforceIsNew(); $entity->save(); $expected[] = $entity->getConfigDependencyName(); $this->assertEqual($expected, $key_value->get('style:test')); - $entity = entity_create('config_test', array( + $entity = entity_create('config_test', [ 'label' => $this->randomMachineName(), 'id' => '3', 'style' => 'blah', - )); + ]); $entity->enforceIsNew(); $entity->save(); // Do not add this entity to the list of expected result as it has a diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php index 51a204f9..aa0044bd 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php @@ -59,11 +59,12 @@ public function testChanged() { $user2 = $this->createUser(); // Create a test entity. - $entity = EntityTestMulChanged::create(array( + $entity = EntityTestMulChanged::create([ 'name' => $this->randomString(), + 'not_translatable' => $this->randomString(), 'user_id' => $user1->id(), 'language' => 'en', - )); + ]); $entity->save(); $this->assertTrue( @@ -73,7 +74,7 @@ public function testChanged() { // We can't assert equality here because the created time is set to the // request time, while instances of ChangedTestItem use the current - // timestamp every time. Therefor we check if the changed timestamp is + // timestamp every time. Therefore we check if the changed timestamp is // between the created time and now. $this->assertTrue( ($entity->getChangedTime() >= $entity->get('created')->value) && @@ -122,6 +123,25 @@ public function testChanged() { 'Changed time of the German translation did not change.' ); + // Update a non-translatable field to make sure that the changed timestamp + // is updated for all translations. + $entity->set('not_translatable', $this->randomString())->save(); + + $this->assertTrue( + $entity->getChangedTime() > $changed_en, + 'Changed time of original language did change.' + ); + + $this->assertTrue( + $german->getChangedTime() > $changed_de, + 'Changed time of the German translation did change.' + ); + + $this->assertEquals($entity->getChangedTime(), $german->getChangedTime(), 'When editing a non-translatable field the updated changed time is equal across all translations.'); + + $changed_en = $entity->getChangedTime(); + $changed_de = $german->getChangedTime(); + $entity->setOwner($user2); $entity->save(); @@ -269,11 +289,11 @@ public function testRevisionChanged() { $user2 = $this->createUser(); // Create a test entity. - $entity = EntityTestMulRevChanged::create(array( + $entity = EntityTestMulRevChanged::create([ 'name' => $this->randomString(), 'user_id' => $user1->id(), 'language' => 'en', - )); + ]); $entity->save(); $this->assertTrue( @@ -491,6 +511,10 @@ public function testRevisionChanged() { 'Changed flag of French translation is set when adding the translation and a new revision.' ); + // Since above a clone of the entity was saved and then this entity is saved + // again, we have to update the revision ID to the current one. + $german->set('revision_id', $form_entity_builder_clone->getRevisionId()); + $german->updateLoadedRevisionId(); $german->setOwner($user1); $german->setRevisionTranslationAffected(FALSE); $entity->save(); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php index cca7eb12..0f77535a 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php @@ -2,7 +2,9 @@ namespace Drupal\KernelTests\Core\Entity; +use Drupal\Component\Render\FormattableMarkup; use Drupal\entity_test\Entity\EntityTestMul; +use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\language\Entity\ConfigurableLanguage; /** @@ -27,6 +29,7 @@ protected function setUp() { ConfigurableLanguage::createFromLangcode('de')->save(); $this->installEntitySchema('entity_test_mul'); + $this->installEntitySchema('entity_test_mulrev'); } /** @@ -41,8 +44,15 @@ public function testFieldEntityReferenceAfterClone() { 'user_id' => $user->id(), 'language' => 'en', ]); + $translation = $entity->addTranslation('de'); - $clone = clone $entity->addTranslation('de'); + // Initialize the fields on the translation objects in order to check that + // they are properly cloned and have a reference to the cloned entity + // object and not to the original one. + $entity->getFields(); + $translation->getFields(); + + $clone = clone $translation; $this->assertEqual($entity->getTranslationLanguages(), $clone->getTranslationLanguages(), 'The entity and its clone have the same translation languages.'); @@ -53,10 +63,12 @@ public function testFieldEntityReferenceAfterClone() { if ($field->getFieldDefinition()->isTranslatable()) { $args = ['%field_name' => $field_name, '%langcode' => $langcode]; $this->assertEqual($langcode, $field->getEntity()->language()->getId(), format_string('Translatable field %field_name on translation %langcode has correct entity reference in translation %langcode after cloning.', $args)); + $this->assertSame($translation, $field->getEntity(), new FormattableMarkup('Translatable field %field_name on translation %langcode has correct reference to the cloned entity object.', $args)); } else { $args = ['%field_name' => $field_name, '%langcode' => $langcode, '%default_langcode' => $default_langcode]; $this->assertEqual($default_langcode, $field->getEntity()->language()->getId(), format_string('Non translatable field %field_name on translation %langcode has correct entity reference in the default translation %default_langcode after cloning.', $args)); + $this->assertSame($translation->getUntranslated(), $field->getEntity(), new FormattableMarkup('Non translatable field %field_name on translation %langcode has correct reference to the cloned entity object in the default translation %default_langcode.', $args)); } } } @@ -78,15 +90,248 @@ public function testEnforceIsNewOnClonedEntityTranslation() { // The entity is not new anymore. $this->assertFalse($entity_translation->isNew()); - // The clone should not be new as well. + // The clone should not be new either. $clone = clone $entity_translation; $this->assertFalse($clone->isNew()); - // After enforcing the clone to be new only it should be flagged as new, - // but the original entity should not be flagged as new. + // After forcing the clone to be new only it should be flagged as new, but + // the original entity should not. $clone->enforceIsNew(); $this->assertTrue($clone->isNew()); $this->assertFalse($entity_translation->isNew()); } + /** + * Tests if the entity fields are properly cloned. + */ + public function testClonedEntityFields() { + $user = $this->createUser(); + + // Create a test entity. + $entity = EntityTestMul::create([ + 'name' => $this->randomString(), + 'user_id' => $user->id(), + 'language' => 'en', + ]); + + $entity->addTranslation('de'); + $entity->save(); + $fields = array_keys($entity->getFieldDefinitions()); + + // Reload the entity, clone it and check that both entity objects reference + // different field instances. + $entity = $this->reloadEntity($entity); + $clone = clone $entity; + + $different_references = TRUE; + foreach ($fields as $field_name) { + if ($entity->get($field_name) === $clone->get($field_name)) { + $different_references = FALSE; + } + } + $this->assertTrue($different_references, 'The entity object and the cloned entity object reference different field item list objects.'); + + + // Reload the entity, initialize one translation, clone it and check that + // both entity objects reference different field instances. + $entity = $this->reloadEntity($entity); + $entity->getTranslation('de'); + $clone = clone $entity; + + $different_references = TRUE; + foreach ($fields as $field_name) { + if ($entity->get($field_name) === $clone->get($field_name)) { + $different_references = FALSE; + } + } + $this->assertTrue($different_references, 'The entity object and the cloned entity object reference different field item list objects if the entity is cloned after an entity translation has been initialized.'); + } + + /** + * Tests that the flag for enforcing a new revision is not shared. + */ + public function testNewRevisionOnCloneEntityTranslation() { + // Create a test entity. + $entity = EntityTestMulRev::create([ + 'name' => $this->randomString(), + 'language' => 'en', + ]); + $entity->save(); + $entity->addTranslation('de'); + $entity->save(); + + // Reload the entity as ContentEntityBase::postCreate() forces the entity to + // be a new revision. + $entity = EntityTestMulRev::load($entity->id()); + $entity_translation = $entity->getTranslation('de'); + + // The entity is not set to be a new revision. + $this->assertFalse($entity_translation->isNewRevision()); + + // The clone should not be set to be a new revision either. + $clone = clone $entity_translation; + $this->assertFalse($clone->isNewRevision()); + + // After forcing the clone to be a new revision only it should be flagged + // as a new revision, but the original entity should not. + $clone->setNewRevision(); + $this->assertTrue($clone->isNewRevision()); + $this->assertFalse($entity_translation->isNewRevision()); + } + + /** + * Tests modifications on entity keys of a cloned entity object. + */ + public function testEntityKeysModifications() { + // Create a test entity with a translation, which will internally trigger + // entity cloning for the new translation and create references for some of + // the entity properties. + $entity = EntityTestMulRev::create([ + 'name' => 'original-name', + 'uuid' => 'original-uuid', + 'language' => 'en', + ]); + $entity->addTranslation('de'); + $entity->save(); + + // Clone the entity. + $clone = clone $entity; + + // Alter a non-translatable and a translatable entity key fields of the + // cloned entity and assert that retrieving the value through the entity + // keys local cache will be different for the cloned and the original + // entity. + // We first have to call the ::uuid() and ::label() method on the original + // entity as it is going to cache the field values into the $entityKeys and + // $translatableEntityKeys properties of the entity object and we want to + // check that the cloned and the original entity aren't sharing the same + // reference to those local cache properties. + $uuid_field_name = $entity->getEntityType()->getKey('uuid'); + $this->assertFalse($entity->getFieldDefinition($uuid_field_name)->isTranslatable()); + $clone->$uuid_field_name->value = 'clone-uuid'; + $this->assertEquals('original-uuid', $entity->uuid()); + $this->assertEquals('clone-uuid', $clone->uuid()); + + $label_field_name = $entity->getEntityType()->getKey('label'); + $this->assertTrue($entity->getFieldDefinition($label_field_name)->isTranslatable()); + $clone->$label_field_name->value = 'clone-name'; + $this->assertEquals('original-name', $entity->label()); + $this->assertEquals('clone-name', $clone->label()); + } + + /** + * Tests the field values after serializing an entity and its clone. + */ + public function testFieldValuesAfterSerialize() { + // Create a test entity with a translation, which will internally trigger + // entity cloning for the new translation and create references for some of + // the entity properties. + $entity = EntityTestMulRev::create([ + 'name' => 'original', + 'language' => 'en', + ]); + $entity->addTranslation('de'); + $entity->save(); + + // Clone the entity. + $clone = clone $entity; + + // Alter the name field value of the cloned entity object. + $clone->setName('clone'); + + // Serialize the entity and the cloned object in order to destroy the field + // objects and put the field values into the entity property $values, so + // that on accessing a field again it will be newly created with the value + // from the $values property. + serialize($entity); + serialize($clone); + + // Assert that the original and the cloned entity both have different names. + $this->assertEquals('original', $entity->getName()); + $this->assertEquals('clone', $clone->getName()); + } + + /** + * Tests changing the default revision flag. + */ + public function testDefaultRevision() { + // Create a test entity with a translation, which will internally trigger + // entity cloning for the new translation and create references for some of + // the entity properties. + $entity = EntityTestMulRev::create([ + 'name' => 'original', + 'language' => 'en', + ]); + $entity->addTranslation('de'); + $entity->save(); + + // Assert that the entity is in the default revision. + $this->assertTrue($entity->isDefaultRevision()); + + // Clone the entity and modify its default revision flag. + $clone = clone $entity; + $clone->isDefaultRevision(FALSE); + + // Assert that the clone is not in default revision, but the original entity + // is still in the default revision. + $this->assertFalse($clone->isDefaultRevision()); + $this->assertTrue($entity->isDefaultRevision()); + } + + /** + * Tests references of entity properties after entity cloning. + */ + public function testEntityPropertiesModifications() { + // Create a test entity with a translation, which will internally trigger + // entity cloning for the new translation and create references for some of + // the entity properties. + $entity = EntityTestMulRev::create([ + 'name' => 'original', + 'language' => 'en', + ]); + $translation = $entity->addTranslation('de'); + $entity->save(); + + // Clone the entity. + $clone = clone $entity; + + // Retrieve the entity properties. + $reflection = new \ReflectionClass($entity); + $properties = $reflection->getProperties(~\ReflectionProperty::IS_STATIC); + $translation_unique_properties = ['activeLangcode', 'translationInitialize', 'fieldDefinitions', 'languages', 'langcodeKey', 'defaultLangcode', 'defaultLangcodeKey', 'validated', 'validationRequired', 'entityTypeId', 'typedData', 'cacheContexts', 'cacheTags', 'cacheMaxAge', '_serviceIds']; + + foreach ($properties as $property) { + // Modify each entity property on the clone and assert that the change is + // not propagated to the original entity. + $property->setAccessible(TRUE); + $property->setValue($entity, 'default-value'); + $property->setValue($translation, 'default-value'); + $property->setValue($clone, 'test-entity-cloning'); + $this->assertEquals('default-value', $property->getValue($entity), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + $this->assertEquals('default-value', $property->getValue($translation), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + $this->assertEquals('test-entity-cloning', $property->getValue($clone), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + + // Modify each entity property on the translation entity object and assert + // that the change is propagated to the default translation entity object + // except for the properties that are unique for each entity translation + // object. + $property->setValue($translation, 'test-translation-cloning'); + // Using assertEquals or assertNotEquals here is dangerous as if the + // assertion fails and the property for some reasons contains the entity + // object e.g. the "typedData" property then the property will be + // serialized, but this will cause exceptions because the entity is + // modified in a non-consistent way and ContentEntityBase::__sleep() will + // not be able to properly access all properties and this will cause + // exceptions without a proper backtrace. + if (in_array($property->getName(), $translation_unique_properties)) { + $this->assertEquals('default-value', $property->getValue($entity), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + $this->assertEquals('test-translation-cloning', $property->getValue($translation), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + } + else { + $this->assertEquals('test-translation-cloning', $property->getValue($entity), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + $this->assertEquals('test-translation-cloning', $property->getValue($translation), (string) new FormattableMarkup('Entity property %property_name is not cloned properly.', ['%property_name' => $property->getName()])); + } + } + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityHasChangesTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityHasChangesTest.php new file mode 100644 index 00000000..687ceb74 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityHasChangesTest.php @@ -0,0 +1,101 @@ +installEntitySchema('user'); + $this->installEntitySchema('entity_test_mulrev_chnged_revlog'); + $this->installSchema('system', 'sequences'); + } + + /** + * Tests the correct functionality of the hasTranslationChanges() function. + */ + public function testHasTranslationChanges() { + $user1 = User::create([ + 'name' => 'username1', + 'status' => 1, + ]); + $user1->save(); + + $user2 = User::create([ + 'name' => 'username2', + 'status' => 1, + ]); + $user2->save(); + + /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */ + $storage = $this->container->get('entity_type.manager') + ->getStorage('entity_test_mulrev_chnged_revlog'); + /** @var \Drupal\entity_test\Entity\EntityTestMulRevChangedWithRevisionLog $entity */ + $entity = $storage->create([ + 'name' => $this->randomString(), + ]); + $entity->setRevisionUserId($user1->id()); + $entity->save(); + + $this->assertFalse($entity->hasTranslationChanges(), 'ContentEntityBase::hasTranslationChanges() found no changes after the entity has been saved.'); + + // Update the revision metadata fields and the changed field, which should + // be skipped from checking for changes in + // ContentEntityBase::hasTranslationChanges(). + $entity_previous_rev_id = $entity->getRevisionId(); + // Revision metadata field revision_timestamp. + $entity->setRevisionCreationTime(time() + 1); + // Revision metadata field revision_uid. + $entity->setRevisionUserId($user2->id()); + // Revision metadata field revision_log. + $entity->setRevisionLogMessage('test'); + // Revision metadata field revision_translation_affected. + $entity->setRevisionTranslationAffected(TRUE); + // Changed field. + $entity->setChangedTime(time() + 1); + + // Check that the revision metadata fields and the changed field have been + // skipped when comparing same revisions. + $this->assertFalse($entity->hasTranslationChanges(), 'ContentEntityBase::hasTranslationChanges() found no changes when comparing different revisions.'); + + // Check that the revision metadata fields and the changed field have been + // skipped when comparing same revisions with enforced new revision to be + // created on save. + $entity->setNewRevision(TRUE); + $this->assertFalse($entity->hasTranslationChanges(), 'ContentEntityBase::hasTranslationChanges() found no changes when comparing different revisions.'); + + // Save the entity in new revision with changes on the revision metadata + // fields. + $entity->save(); + + // Check that the revision metadata fields and the changed field have been + // skipped when comparing different revisions. + $entity = $storage->loadRevision($entity_previous_rev_id); + $this->assertFalse($entity->hasTranslationChanges(), 'ContentEntityBase::hasTranslationChanges() found no changes when comparing different revisions.'); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php index 73684e9f..99c99b06 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNonRevisionableFieldTest.php @@ -57,21 +57,21 @@ public function testMulNonRevisionableField() { $user2 = $this->createUser(); // Create a test entity. - $entity = EntityTestMulRev::create(array( + $entity = EntityTestMulRev::create([ 'name' => $this->randomString(), 'user_id' => $user1->id(), 'language' => 'en', 'non_rev_field' => 'Huron', - )); + ]); $entity->save(); // Create a test entity. - $entity2 = EntityTestMulRev::create(array( + $entity2 = EntityTestMulRev::create([ 'name' => $this->randomString(), 'user_id' => $user1->id(), 'language' => 'en', 'non_rev_field' => 'Michigan', - )); + ]); $entity2->save(); $this->assertEquals('Huron', $entity->get('non_rev_field')->value, 'Huron found on entity 1'); @@ -123,19 +123,19 @@ public function testNonRevisionableField() { $user2 = $this->createUser(); // Create a test entity. - $entity = EntityTestRev::create(array( + $entity = EntityTestRev::create([ 'name' => $this->randomString(), 'user_id' => $user1->id(), 'non_rev_field' => 'Superior', - )); + ]); $entity->save(); // Create a test entity. - $entity2 = EntityTestRev::create(array( + $entity2 = EntityTestRev::create([ 'name' => $this->randomString(), 'user_id' => $user1->id(), 'non_rev_field' => 'Ontario', - )); + ]); $entity2->save(); $this->assertEquals('Superior', $entity->get('non_rev_field')->value, 'Superior found on entity 1'); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php index 51162fcd..6da9bb3b 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php @@ -22,7 +22,7 @@ class ContentEntityNullStorageTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'contact', 'user'); + public static $modules = ['system', 'contact', 'user']; /** * Tests using entity query with ContentEntityNullStorage. @@ -30,10 +30,10 @@ class ContentEntityNullStorageTest extends KernelTestBase { * @see \Drupal\Core\Entity\Query\Null\Query */ public function testEntityQuery() { - $this->assertIdentical(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.'); - $this->assertIdentical([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.'); - $this->assertIdentical([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.'); - $this->assertIdentical([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array'); + $this->assertSame(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.'); + $this->assertSame([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.'); + $this->assertSame([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.'); + $this->assertSame([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array'); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php index c2d737bf..c18910e2 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/Element/EntityAutocompleteElementFormTest.php @@ -50,23 +50,23 @@ protected function setUp() { $this->installEntitySchema('entity_test_string_id'); \Drupal::service('router.builder')->rebuild(); - $this->testUser = User::create(array( + $this->testUser = User::create([ 'name' => 'foobar1', 'mail' => 'foobar1@example.com', - )); + ]); $this->testUser->save(); \Drupal::service('current_user')->setAccount($this->testUser); - $this->testAutocreateUser = User::create(array( + $this->testAutocreateUser = User::create([ 'name' => 'foobar2', 'mail' => 'foobar2@example.com', - )); + ]); $this->testAutocreateUser->save(); for ($i = 1; $i < 3; $i++) { - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'name' => $this->randomMachineName() - )); + ]); $entity->save(); $this->referencedEntities[] = $entity; } @@ -94,84 +94,84 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['single'] = array( + $form['single'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', - ); - $form['single_autocreate'] = array( + ]; + $form['single_autocreate'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', - '#autocreate' => array( + '#autocreate' => [ 'bundle' => 'entity_test', - ), - ); - $form['single_autocreate_specific_uid'] = array( + ], + ]; + $form['single_autocreate_specific_uid'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', - '#autocreate' => array( + '#autocreate' => [ 'bundle' => 'entity_test', 'uid' => $this->testAutocreateUser->id(), - ), - ); + ], + ]; - $form['tags'] = array( + $form['tags'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#tags' => TRUE, - ); - $form['tags_autocreate'] = array( + ]; + $form['tags_autocreate'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#tags' => TRUE, - '#autocreate' => array( + '#autocreate' => [ 'bundle' => 'entity_test', - ), - ); - $form['tags_autocreate_specific_uid'] = array( + ], + ]; + $form['tags_autocreate_specific_uid'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#tags' => TRUE, - '#autocreate' => array( + '#autocreate' => [ 'bundle' => 'entity_test', 'uid' => $this->testAutocreateUser->id(), - ), - ); + ], + ]; - $form['single_no_validate'] = array( + $form['single_no_validate'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#validate_reference' => FALSE, - ); - $form['single_autocreate_no_validate'] = array( + ]; + $form['single_autocreate_no_validate'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#validate_reference' => FALSE, - '#autocreate' => array( + '#autocreate' => [ 'bundle' => 'entity_test', - ), - ); + ], + ]; - $form['single_access'] = array( + $form['single_access'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#default_value' => $this->referencedEntities[0], - ); - $form['tags_access'] = array( + ]; + $form['tags_access'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test', '#tags' => TRUE, - '#default_value' => array($this->referencedEntities[0], $this->referencedEntities[1]), - ); + '#default_value' => [$this->referencedEntities[0], $this->referencedEntities[1]], + ]; - $form['single_string_id'] = array( + $form['single_string_id'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test_string_id', - ); - $form['tags_string_id'] = array( + ]; + $form['tags_string_id'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'entity_test_string_id', '#tags' => TRUE, - ); + ]; return $form; } @@ -179,12 +179,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function submitForm(array &$form, FormStateInterface $form_state) { } + public function submitForm(array &$form, FormStateInterface $form_state) {} /** * {@inheritdoc} */ - public function validateForm(array &$form, FormStateInterface $form_state) { } + public function validateForm(array &$form, FormStateInterface $form_state) {} /** * Tests valid entries in the EntityAutocomplete Form API element. @@ -229,10 +229,10 @@ public function testValidEntityAutocompleteElement() { $this->assertEqual($value['entity']->getOwnerId(), $this->testAutocreateUser->id()); // Test the 'tags' element. - $expected = array( - array('target_id' => $this->referencedEntities[0]->id()), - array('target_id' => $this->referencedEntities[1]->id()), - ); + $expected = [ + ['target_id' => $this->referencedEntities[0]->id()], + ['target_id' => $this->referencedEntities[1]->id()], + ]; $this->assertEqual($form_state->getValue('tags'), $expected); // Test the 'single_autocreate' element. @@ -281,7 +281,7 @@ public function testInvalidEntityAutocompleteElement() { ]); $form_builder->submitForm($this, $form_state); $this->assertEqual(count($form_state->getErrors()), 1); - $this->assertEqual($form_state->getErrors()['single'], t('There are no entities matching "%value".', array('%value' => 'single - non-existent label'))); + $this->assertEqual($form_state->getErrors()['single'], t('There are no entities matching "%value".', ['%value' => 'single - non-existent label'])); // Test 'single' with a entity ID that doesn't exist. $form_state = (new FormState()) @@ -290,7 +290,7 @@ public function testInvalidEntityAutocompleteElement() { ]); $form_builder->submitForm($this, $form_state); $this->assertEqual(count($form_state->getErrors()), 1); - $this->assertEqual($form_state->getErrors()['single'], t('The referenced entity (%type: %id) does not exist.', array('%type' => 'entity_test', '%id' => 42))); + $this->assertEqual($form_state->getErrors()['single'], t('The referenced entity (%type: %id) does not exist.', ['%type' => 'entity_test', '%id' => 42])); // Do the same tests as above but on an element with '#validate_reference' // set to FALSE. @@ -304,7 +304,7 @@ public function testInvalidEntityAutocompleteElement() { // The element without 'autocreate' support still has to emit a warning when // the input doesn't end with an entity ID enclosed in parentheses. $this->assertEqual(count($form_state->getErrors()), 1); - $this->assertEqual($form_state->getErrors()['single_no_validate'], t('There are no entities matching "%value".', array('%value' => 'single - non-existent label'))); + $this->assertEqual($form_state->getErrors()['single_no_validate'], t('There are no entities matching "%value".', ['%value' => 'single - non-existent label'])); $form_state = (new FormState()) ->setValues([ @@ -333,7 +333,7 @@ public function testEntityAutocompleteAccess() { $this->assertEqual($form['tags_access']['#value'], $expected); // Set up a non-admin user that is *not* allowed to view test entities. - \Drupal::currentUser()->setAccount($this->createUser(array(), array())); + \Drupal::currentUser()->setAccount($this->createUser([], [])); // Rebuild the form. $form = $form_builder->getForm($this); @@ -353,7 +353,7 @@ public function testEntityAutocompleteAccess() { public function testEntityAutocompleteIdInput() { /** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */ $form_builder = $this->container->get('form_builder'); - //$form = $form_builder->getForm($this); + // $form = $form_builder->getForm($this); $form_state = (new FormState()) ->setMethod('GET') ->setValues([ @@ -381,7 +381,7 @@ public function testEntityAutocompleteIdInput() { * A string that can be used as a value for EntityAutocomplete elements. */ protected function getAutocompleteInput(EntityInterface $entity) { - return EntityAutocomplete::getEntityLabels(array($entity)); + return EntityAutocomplete::getEntityLabels([$entity]); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php index 77210d5c..b3af27fb 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityAccessControlHandlerTest.php @@ -9,7 +9,9 @@ use Drupal\Core\Session\AnonymousUserSession; use Drupal\entity_test\Entity\EntityTest; use Drupal\entity_test\Entity\EntityTestDefaultAccess; +use Drupal\entity_test\Entity\EntityTestNoUuid; use Drupal\entity_test\Entity\EntityTestLabel; +use Drupal\entity_test\Entity\EntityTestRev; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\user\Entity\User; @@ -20,15 +22,25 @@ */ class EntityAccessControlHandlerTest extends EntityLanguageTestBase { + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->installEntitySchema('entity_test_no_uuid'); + $this->installEntitySchema('entity_test_rev'); + } + /** * Asserts entity access correctly grants or denies access. */ - function assertEntityAccess($ops, AccessibleInterface $object, AccountInterface $account = NULL) { + public function assertEntityAccess($ops, AccessibleInterface $object, AccountInterface $account = NULL) { foreach ($ops as $op => $result) { - $message = format_string("Entity access returns @result with operation '@op'.", array( + $message = format_string("Entity access returns @result with operation '@op'.", [ '@result' => !isset($result) ? 'null' : ($result ? 'true' : 'false'), '@op' => $op, - )); + ]); $this->assertEqual($result, $object->access($op, $account), $message); } @@ -45,44 +57,44 @@ public function testUserLabelAccess() { $user = $this->createUser(); // The current user is allowed to view the anonymous user label. - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, 'view label' => TRUE, - ), $anonymous_user); + ], $anonymous_user); // The current user is allowed to view user labels. - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, 'view label' => TRUE, - ), $user); + ], $user); // Switch to a anonymous user account. $account_switcher = \Drupal::service('account_switcher'); $account_switcher->switchTo(new AnonymousUserSession()); // The anonymous user is allowed to view the anonymous user label. - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, 'view label' => TRUE, - ), $anonymous_user); + ], $anonymous_user); // The anonymous user is allowed to view user labels. - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, 'view label' => TRUE, - ), $user); + ], $user); // Restore user account. $account_switcher->switchBack(); @@ -91,35 +103,35 @@ public function testUserLabelAccess() { /** * Ensures entity access is properly working. */ - function testEntityAccess() { + public function testEntityAccess() { // Set up a non-admin user that is allowed to view test entities. - \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2), array('view test entity'))); + \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2], ['view test entity'])); // Use the 'entity_test_label' entity type in order to test the 'view label' // access operation. - $entity = EntityTestLabel::create(array( + $entity = EntityTestLabel::create([ 'name' => 'test', - )); + ]); // The current user is allowed to view entities. - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => TRUE, 'view label' => TRUE, - ), $entity); + ], $entity); // The custom user is not allowed to perform any operation on test entities, // except for viewing their label. $custom_user = $this->createUser(); - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, 'view label' => TRUE, - ), $entity, $custom_user); + ], $entity, $custom_user); } /** @@ -134,28 +146,28 @@ function testEntityAccess() { * @see \Drupal\entity_test\EntityTestAccessControlHandler::checkAccess() * @see entity_test_entity_access() */ - function testDefaultEntityAccess() { + public function testDefaultEntityAccess() { // Set up a non-admin user that is allowed to view test entities. - \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2), array('view test entity'))); - $entity = EntityTest::create(array( + \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2], ['view test entity'])); + $entity = EntityTest::create([ 'name' => 'forbid_access', - )); + ]); // The user is denied access to the entity. - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, - ), $entity); + ], $entity); } /** * Ensures that the default handler is used as a fallback. */ - function testEntityAccessDefaultController() { + public function testEntityAccessDefaultController() { // The implementation requires that the global user id can be loaded. - \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2))); + \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2])); // Check that the default access control handler is used for entities that don't // have a specific access control handler defined. @@ -163,40 +175,98 @@ function testEntityAccessDefaultController() { $this->assertTrue($handler instanceof EntityAccessControlHandler, 'The default entity handler is used for the entity_test_default_access entity type.'); $entity = EntityTestDefaultAccess::create(); - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'create' => FALSE, 'update' => FALSE, 'delete' => FALSE, 'view' => FALSE, - ), $entity); + ], $entity); } /** * Ensures entity access for entity translations is properly working. */ - function testEntityTranslationAccess() { + public function testEntityTranslationAccess() { // Set up a non-admin user that is allowed to view test entity translations. - \Drupal::currentUser()->setAccount($this->createUser(array('uid' => 2), array('view test entity translations'))); + \Drupal::currentUser()->setAccount($this->createUser(['uid' => 2], ['view test entity translations'])); // Create two test languages. - foreach (array('foo', 'bar') as $langcode) { - ConfigurableLanguage::create(array( + foreach (['foo', 'bar'] as $langcode) { + ConfigurableLanguage::create([ 'id' => $langcode, 'label' => $this->randomString(), - ))->save(); + ])->save(); } - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'name' => 'test', 'langcode' => 'foo', - )); + ]); $entity->save(); $translation = $entity->addTranslation('bar'); - $this->assertEntityAccess(array( + $this->assertEntityAccess([ 'view' => TRUE, - ), $translation); + ], $translation); + } + + /** + * Ensures the static access cache works correctly in the absence of an UUID. + * + * @see entity_test_entity_access() + */ + public function testEntityWithoutUuidAccessCache() { + $account = $this->createUser(); + + $entity1 = EntityTestNoUuid::create([ + 'name' => 'Accessible', + ]); + $entity1->save(); + + $entity2 = EntityTestNoUuid::create([ + 'name' => 'Inaccessible', + ]); + $entity2->save(); + + $this->assertTrue($entity1->access('delete', $account), 'Entity 1 can be deleted.'); + $this->assertFalse($entity2->access('delete', $account), 'Entity 2 CANNOT be deleted.'); + + $entity1 + ->setName('Inaccessible') + ->setNewRevision(); + $entity1->save(); + + $this->assertFalse($entity1->access('delete', $account), 'Entity 1 revision 2 CANNOT be deleted.'); + } + + /** + * Ensures the static access cache works correctly with a UUID and revisions. + * + * @see entity_test_entity_access() + */ + public function testEntityWithUuidAccessCache() { + $account = $this->createUser(); + + $entity1 = EntityTestRev::create([ + 'name' => 'Accessible', + ]); + $entity1->save(); + + $entity2 = EntityTestRev::create([ + 'name' => 'Inaccessible', + ]); + $entity2->save(); + + $this->assertTrue($entity1->access('delete', $account), 'Entity 1 can be deleted.'); + $this->assertFalse($entity2->access('delete', $account), 'Entity 2 CANNOT be deleted.'); + + $entity1 + ->setName('Inaccessible') + ->setNewRevision(); + $entity1->save(); + + $this->assertFalse($entity1->access('delete', $account), 'Entity 1 revision 2 CANNOT be deleted.'); } /** @@ -204,9 +274,9 @@ function testEntityTranslationAccess() { */ public function testHooks() { $state = $this->container->get('state'); - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'name' => 'test', - )); + ]); // Test hook_entity_create_access() and hook_ENTITY_TYPE_create_access(). $entity->access('create'); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityApiTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityApiTest.php index 31cdaec7..b32e78de 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityApiTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityApiTest.php @@ -49,15 +49,15 @@ protected function assertCRUD($entity_type, UserInterface $user1) { // Create some test entities. $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array('name' => 'test', 'user_id' => $user1->id())); + ->create(['name' => 'test', 'user_id' => $user1->id()]); $entity->save(); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array('name' => 'test2', 'user_id' => $user1->id())); + ->create(['name' => 'test2', 'user_id' => $user1->id()]); $entity->save(); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array('name' => 'test', 'user_id' => NULL)); + ->create(['name' => 'test', 'user_id' => NULL]); $entity->save(); /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */ @@ -65,32 +65,32 @@ protected function assertCRUD($entity_type, UserInterface $user1) { ->getStorage($entity_type); $entities = array_values($storage->loadByProperties(['name' => 'test'])); - $this->assertEqual($entities[0]->name->value, 'test', format_string('%entity_type: Created and loaded entity', array('%entity_type' => $entity_type))); - $this->assertEqual($entities[1]->name->value, 'test', format_string('%entity_type: Created and loaded entity', array('%entity_type' => $entity_type))); + $this->assertEqual($entities[0]->name->value, 'test', format_string('%entity_type: Created and loaded entity', ['%entity_type' => $entity_type])); + $this->assertEqual($entities[1]->name->value, 'test', format_string('%entity_type: Created and loaded entity', ['%entity_type' => $entity_type])); // Test loading a single entity. $loaded_entity = $storage->load($entity->id()); - $this->assertEqual($loaded_entity->id(), $entity->id(), format_string('%entity_type: Loaded a single entity by id.', array('%entity_type' => $entity_type))); + $this->assertEqual($loaded_entity->id(), $entity->id(), format_string('%entity_type: Loaded a single entity by id.', ['%entity_type' => $entity_type])); // Test deleting an entity. $entities = array_values($storage->loadByProperties(['name' => 'test2'])); $entities[0]->delete(); $entities = array_values($storage->loadByProperties(['name' => 'test2'])); - $this->assertEqual($entities, array(), format_string('%entity_type: Entity deleted.', array('%entity_type' => $entity_type))); + $this->assertEqual($entities, [], format_string('%entity_type: Entity deleted.', ['%entity_type' => $entity_type])); // Test updating an entity. $entities = array_values($storage->loadByProperties(['name' => 'test'])); $entities[0]->name->value = 'test3'; $entities[0]->save(); $entity = $storage->load($entities[0]->id()); - $this->assertEqual($entity->name->value, 'test3', format_string('%entity_type: Entity updated.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->name->value, 'test3', format_string('%entity_type: Entity updated.', ['%entity_type' => $entity_type])); // Try deleting multiple test entities by deleting all. $ids = array_keys($storage->loadMultiple()); entity_delete_multiple($entity_type, $ids); $all = $storage->loadMultiple(); - $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', array('%entity_type' => $entity_type))); + $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', ['%entity_type' => $entity_type])); // Verify that all data got deleted. $definition = \Drupal::entityManager()->getDefinition($entity_type); @@ -101,13 +101,16 @@ protected function assertCRUD($entity_type, UserInterface $user1) { if ($revision_table = $definition->getRevisionTable()) { $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_table . '}')->fetchField(), 'Data table was emptied'); } + if ($revision_data_table = $definition->getRevisionDataTable()) { + $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_data_table . '}')->fetchField(), 'Data table was emptied'); + } // Test deleting a list of entities not indexed by entity id. - $entities = array(); - $entity = entity_create($entity_type, array('name' => 'test', 'user_id' => $user1->id())); + $entities = []; + $entity = entity_create($entity_type, ['name' => 'test', 'user_id' => $user1->id()]); $entity->save(); $entities['test'] = $entity; - $entity = entity_create($entity_type, array('name' => 'test2', 'user_id' => $user1->id())); + $entity = entity_create($entity_type, ['name' => 'test2', 'user_id' => $user1->id()]); $entity->save(); $entities['test2'] = $entity; $controller = \Drupal::entityManager()->getStorage($entity_type); @@ -115,7 +118,7 @@ protected function assertCRUD($entity_type, UserInterface $user1) { // Verify that entities got deleted. $all = $storage->loadMultiple(); - $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', array('%entity_type' => $entity_type))); + $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', ['%entity_type' => $entity_type])); // Verify that all data got deleted from the tables. $definition = \Drupal::entityManager()->getDefinition($entity_type); @@ -126,13 +129,16 @@ protected function assertCRUD($entity_type, UserInterface $user1) { if ($revision_table = $definition->getRevisionTable()) { $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_table . '}')->fetchField(), 'Data table was emptied'); } + if ($revision_data_table = $definition->getRevisionDataTable()) { + $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {' . $revision_data_table . '}')->fetchField(), 'Data table was emptied'); + } } /** * Tests that exceptions are thrown when saving or deleting an entity. */ public function testEntityStorageExceptionHandling() { - $entity = EntityTest::create(array('name' => 'test')); + $entity = EntityTest::create(['name' => 'test']); try { $GLOBALS['entity_test_throw_exception'] = TRUE; $entity->save(); @@ -142,7 +148,7 @@ public function testEntityStorageExceptionHandling() { $this->assertEqual($e->getcode(), 1, 'Entity presave EntityStorageException caught.'); } - $entity = EntityTest::create(array('name' => 'test2')); + $entity = EntityTest::create(['name' => 'test2']); try { unset($GLOBALS['entity_test_throw_exception']); $entity->save(); @@ -152,7 +158,7 @@ public function testEntityStorageExceptionHandling() { $this->assertNotEqual($e->getCode(), 1, 'Entity presave EntityStorageException caught.'); } - $entity = EntityTest::create(array('name' => 'test3')); + $entity = EntityTest::create(['name' => 'test3']); $entity->save(); try { $GLOBALS['entity_test_throw_exception'] = TRUE; @@ -164,7 +170,7 @@ public function testEntityStorageExceptionHandling() { } unset($GLOBALS['entity_test_throw_exception']); - $entity = EntityTest::create(array('name' => 'test4')); + $entity = EntityTest::create(['name' => 'test4']); $entity->save(); try { $entity->delete(); @@ -175,4 +181,38 @@ public function testEntityStorageExceptionHandling() { } } + /** + * Tests that resaving a revision with a different revision ID throws an exception. + */ + public function testUpdateWithRevisionId() { + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev'); + + // Create a new entity. + /** @var \Drupal\entity_test\Entity\EntityTestMulRev $entity */ + $entity = $storage->create(['name' => 'revision_test']); + $entity->save(); + + $this->setExpectedException(EntityStorageException::class, "Update existing 'entity_test_mulrev' entity revision while changing the revision ID is not supported."); + + $entity->revision_id = 60; + $entity->save(); + } + + /** + * Tests that resaving an entity with a different entity ID throws an exception. + */ + public function testUpdateWithId() { + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev'); + + // Create a new entity. + /** @var \Drupal\entity_test\Entity\EntityTestMulRev $entity */ + $entity = $storage->create(['name' => 'revision_test']); + $entity->save(); + + $this->setExpectedException(EntityStorageException::class, "Update existing 'entity_test_mulrev' entity while changing the ID is not supported."); + + $entity->id = 60; + $entity->save(); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php index ae4925ce..ca65eb83 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php @@ -43,23 +43,23 @@ protected function setUp() { /** * Tests autocompletion edge cases with slashes in the names. */ - function testEntityReferenceAutocompletion() { + public function testEntityReferenceAutocompletion() { // Add an entity with a slash in its name. $entity_1 = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('name' => '10/16/2011')); + ->create(['name' => '10/16/2011']); $entity_1->save(); // Add another entity that differs after the slash character. $entity_2 = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('name' => '10/17/2011')); + ->create(['name' => '10/17/2011']); $entity_2->save(); // Add another entity that has both a comma, a slash and markup. $entity_3 = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('name' => 'label with, and / test')); + ->create(['name' => 'label with, and / test']); $entity_3->save(); // Try to autocomplete a entity label that matches both entities. @@ -73,10 +73,10 @@ function testEntityReferenceAutocompletion() { // We should only get the first entity in a JSON encoded string. $input = '10/16'; $data = $this->getAutocompleteResult($input); - $target = array( + $target = [ 'value' => $entity_1->name->value . ' (1)', 'label' => Html::escape($entity_1->name->value), - ); + ]; $this->assertIdentical(reset($data), $target, 'Autocomplete returns only the expected matching entity.'); // Try to autocomplete a entity label that matches the second entity, and @@ -91,10 +91,10 @@ function testEntityReferenceAutocompletion() { $n = $entity_3->name->value . ' (3)'; // Entity labels containing commas or quotes must be wrapped in quotes. $n = Tags::encode($n); - $target = array( + $target = [ 'value' => $n, 'label' => Html::escape($entity_3->name->value), - ); + ]; $this->assertIdentical(reset($data), $target, 'Autocomplete returns an entity label containing a comma and a slash.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php index ec8fd1cf..ed30d4b5 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityBundleFieldTest.php @@ -14,7 +14,7 @@ class EntityBundleFieldTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('entity_schema_test'); + public static $modules = ['entity_schema_test']; /** * The module handler. @@ -35,7 +35,7 @@ class EntityBundleFieldTest extends EntityKernelTestBase { */ protected function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); + $this->installSchema('user', ['users_data']); $this->moduleHandler = $this->container->get('module_handler'); $this->database = $this->container->get('database'); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityCrudHookTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityCrudHookTest.php index 935fd7a2..9b279a5e 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityCrudHookTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityCrudHookTest.php @@ -40,17 +40,17 @@ class EntityCrudHookTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('block', 'block_test', 'entity_crud_hook_test', 'file', 'taxonomy', 'node', 'comment'); + public static $modules = ['block', 'block_test', 'entity_crud_hook_test', 'file', 'taxonomy', 'node', 'comment']; - protected $ids = array(); + protected $ids = []; protected function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); - $this->installSchema('file', array('file_usage')); - $this->installSchema('node', array('node_access')); - $this->installSchema('comment', array('comment_entity_statistics')); + $this->installSchema('user', ['users_data']); + $this->installSchema('file', ['file_usage']); + $this->installSchema('node', ['node_access']); + $this->installSchema('comment', ['comment_entity_statistics']); $this->installConfig(['node', 'comment']); } @@ -64,7 +64,7 @@ protected function setUp() { * An array of plain-text messages in the order they should appear. */ protected function assertHookMessageOrder($messages) { - $positions = array(); + $positions = []; foreach ($messages as $message) { // Verify that each message is found and record its position. $position = array_search($message, $GLOBALS['entity_crud_hook_test']); @@ -83,55 +83,55 @@ protected function assertHookMessageOrder($messages) { * Tests hook invocations for CRUD operations on blocks. */ public function testBlockHooks() { - $entity = Block::create(array( + $entity = Block::create([ 'id' => 'stark_test_html', 'plugin' => 'test_html', 'theme' => 'stark', - )); + ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_block_create called', 'entity_crud_hook_test_entity_create called for type block', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $entity->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_block_presave called', 'entity_crud_hook_test_entity_presave called for type block', 'entity_crud_hook_test_block_insert called', 'entity_crud_hook_test_entity_insert called for type block', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $entity = Block::load($entity->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type block', 'entity_crud_hook_test_block_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $entity->label = 'New label'; $entity->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_block_presave called', 'entity_crud_hook_test_entity_presave called for type block', 'entity_crud_hook_test_block_update called', 'entity_crud_hook_test_entity_update called for type block', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $entity->delete(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_block_predelete called', 'entity_crud_hook_test_entity_predelete called for type block', 'entity_crud_hook_test_block_delete called', 'entity_crud_hook_test_entity_delete called for type block', - )); + ]); } /** @@ -158,9 +158,9 @@ public function testCommentHooks() { ]); $node->save(); $nid = $node->id(); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; - $comment = Comment::create(array( + $comment = Comment::create([ 'cid' => NULL, 'pid' => 0, 'entity_id' => $nid, @@ -172,51 +172,51 @@ public function testCommentHooks() { 'changed' => REQUEST_TIME, 'status' => 1, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_comment_create called', 'entity_crud_hook_test_entity_create called for type comment', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $comment->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_comment_presave called', 'entity_crud_hook_test_entity_presave called for type comment', 'entity_crud_hook_test_comment_insert called', 'entity_crud_hook_test_entity_insert called for type comment', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $comment = Comment::load($comment->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type comment', 'entity_crud_hook_test_comment_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $comment->setSubject('New subject'); $comment->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_comment_presave called', 'entity_crud_hook_test_entity_presave called for type comment', 'entity_crud_hook_test_comment_update called', 'entity_crud_hook_test_entity_update called for type comment', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $comment->delete(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_comment_predelete called', 'entity_crud_hook_test_entity_predelete called for type comment', 'entity_crud_hook_test_comment_delete called', 'entity_crud_hook_test_entity_delete called for type comment', - )); + ]); } /** @@ -239,49 +239,49 @@ public function testFileHooks() { 'changed' => REQUEST_TIME, ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_file_create called', 'entity_crud_hook_test_entity_create called for type file', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $file->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_file_presave called', 'entity_crud_hook_test_entity_presave called for type file', 'entity_crud_hook_test_file_insert called', 'entity_crud_hook_test_entity_insert called for type file', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $file = File::load($file->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type file', 'entity_crud_hook_test_file_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $file->setFilename('new.entity_crud_hook_test.file'); $file->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_file_presave called', 'entity_crud_hook_test_entity_presave called for type file', 'entity_crud_hook_test_file_update called', 'entity_crud_hook_test_entity_update called for type file', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $file->delete(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_file_predelete called', 'entity_crud_hook_test_entity_predelete called for type file', 'entity_crud_hook_test_file_delete called', 'entity_crud_hook_test_entity_delete called for type file', - )); + ]); } /** @@ -302,49 +302,49 @@ public function testNodeHooks() { 'changed' => REQUEST_TIME, ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_node_create called', 'entity_crud_hook_test_entity_create called for type node', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $node->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_node_presave called', 'entity_crud_hook_test_entity_presave called for type node', 'entity_crud_hook_test_node_insert called', 'entity_crud_hook_test_entity_insert called for type node', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $node = Node::load($node->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type node', 'entity_crud_hook_test_node_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $node->title = 'New title'; $node->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_node_presave called', 'entity_crud_hook_test_entity_presave called for type node', 'entity_crud_hook_test_node_update called', 'entity_crud_hook_test_entity_update called for type node', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $node->delete(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_node_predelete called', 'entity_crud_hook_test_entity_predelete called for type node', 'entity_crud_hook_test_node_delete called', 'entity_crud_hook_test_entity_delete called for type node', - )); + ]); } /** @@ -361,7 +361,7 @@ public function testTaxonomyTermHooks() { 'module' => 'entity_crud_hook_test', ]); $vocabulary->save(); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $term = Term::create([ 'vid' => $vocabulary->id(), @@ -371,49 +371,49 @@ public function testTaxonomyTermHooks() { 'format' => 1, ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_term_create called', 'entity_crud_hook_test_entity_create called for type taxonomy_term', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $term->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_term_presave called', 'entity_crud_hook_test_entity_presave called for type taxonomy_term', 'entity_crud_hook_test_taxonomy_term_insert called', 'entity_crud_hook_test_entity_insert called for type taxonomy_term', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $term = Term::load($term->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type taxonomy_term', 'entity_crud_hook_test_taxonomy_term_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $term->setName('New name'); $term->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_term_presave called', 'entity_crud_hook_test_entity_presave called for type taxonomy_term', 'entity_crud_hook_test_taxonomy_term_update called', 'entity_crud_hook_test_entity_update called for type taxonomy_term', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $term->delete(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_term_predelete called', 'entity_crud_hook_test_entity_predelete called for type taxonomy_term', 'entity_crud_hook_test_taxonomy_term_delete called', 'entity_crud_hook_test_entity_delete called for type taxonomy_term', - )); + ]); } /** @@ -430,49 +430,49 @@ public function testTaxonomyVocabularyHooks() { 'module' => 'entity_crud_hook_test', ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_vocabulary_create called', 'entity_crud_hook_test_entity_create called for type taxonomy_vocabulary', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $vocabulary->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_vocabulary_presave called', 'entity_crud_hook_test_entity_presave called for type taxonomy_vocabulary', 'entity_crud_hook_test_taxonomy_vocabulary_insert called', 'entity_crud_hook_test_entity_insert called for type taxonomy_vocabulary', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $vocabulary = Vocabulary::load($vocabulary->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type taxonomy_vocabulary', 'entity_crud_hook_test_taxonomy_vocabulary_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $vocabulary->set('name', 'New name'); $vocabulary->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_vocabulary_presave called', 'entity_crud_hook_test_entity_presave called for type taxonomy_vocabulary', 'entity_crud_hook_test_taxonomy_vocabulary_update called', 'entity_crud_hook_test_entity_update called for type taxonomy_vocabulary', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $vocabulary->delete(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_taxonomy_vocabulary_predelete called', 'entity_crud_hook_test_entity_predelete called for type taxonomy_vocabulary', 'entity_crud_hook_test_taxonomy_vocabulary_delete called', 'entity_crud_hook_test_entity_delete called for type taxonomy_vocabulary', - )); + ]); } /** @@ -487,58 +487,58 @@ public function testUserHooks() { 'language' => 'en', ]); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_user_create called', 'entity_crud_hook_test_entity_create called for type user', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $account->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_user_presave called', 'entity_crud_hook_test_entity_presave called for type user', 'entity_crud_hook_test_user_insert called', 'entity_crud_hook_test_entity_insert called for type user', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; User::load($account->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_entity_load called for type user', 'entity_crud_hook_test_user_load called', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; $account->name = 'New name'; $account->save(); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_user_presave called', 'entity_crud_hook_test_entity_presave called for type user', 'entity_crud_hook_test_user_update called', 'entity_crud_hook_test_entity_update called for type user', - )); + ]); - $GLOBALS['entity_crud_hook_test'] = array(); + $GLOBALS['entity_crud_hook_test'] = []; user_delete($account->id()); - $this->assertHookMessageOrder(array( + $this->assertHookMessageOrder([ 'entity_crud_hook_test_user_predelete called', 'entity_crud_hook_test_entity_predelete called for type user', 'entity_crud_hook_test_user_delete called', 'entity_crud_hook_test_entity_delete called for type user', - )); + ]); } /** * Tests rollback from failed entity save. */ - function testEntityRollback() { + public function testEntityRollback() { // Create a block. try { - EntityTest::create(array('name' => 'fail_insert'))->save(); + EntityTest::create(['name' => 'fail_insert'])->save(); $this->fail('Expected exception has not been thrown.'); } catch (\Exception $e) { diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php index 23cf0340..e2e4ae27 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php @@ -11,9 +11,10 @@ use Drupal\Core\Entity\EntityTypeEvents; use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Field\FieldException; use Drupal\Core\Field\FieldStorageDefinitionEvents; use Drupal\Core\Language\LanguageInterface; -use Drupal\entity_test\Entity\EntityTestUpdate; +use Drupal\entity_test_update\Entity\EntityTestUpdate; use Drupal\system\Tests\Entity\EntityDefinitionTestTrait; /** @@ -39,6 +40,13 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase { */ protected $database; + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['entity_test_update']; + /** * {@inheritdoc} */ @@ -49,7 +57,7 @@ protected function setUp() { // Install every entity type's schema that wasn't installed in the parent // method. - foreach (array_diff_key($this->entityManager->getDefinitions(), array_flip(array('user', 'entity_test'))) as $entity_type_id => $entity_type) { + foreach (array_diff_key($this->entityManager->getDefinitions(), array_flip(['user', 'entity_test'])) as $entity_type_id => $entity_type) { $this->installEntitySchema($entity_type_id); } } @@ -80,7 +88,7 @@ public function testNewEntityType() { public function testNoUpdates() { // Ensure that the definition update manager reports no updates. $this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that no updates are needed.'); - $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), array(), 'EntityDefinitionUpdateManager reports an empty change summary.'); + $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), [], 'EntityDefinitionUpdateManager reports an empty change summary.'); // Ensure that applyUpdates() runs without error (it's not expected to do // anything when there aren't updates). @@ -99,12 +107,15 @@ public function testEntityTypeUpdateWithoutData() { // reports that an update is needed. $this->updateEntityTypeToRevisionable(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %entity_type entity type needs to be updated.', ['%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel()]), - ), - ); - $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected); //, 'EntityDefinitionUpdateManager reports the expected change summary.'); + // The revision key is now defined, so the revision field needs to be + // created. + t('The %field_name field needs to be installed.', ['%field_name' => 'Revision ID']), + ], + ]; + $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the revision table is created. $this->entityDefinitionUpdateManager->applyUpdates(); @@ -138,11 +149,11 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() { // creates its schema. $this->addBaseField(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be installed.', ['%field_name' => t('A new base field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), 'Column created in shared table for new_base_field.'); @@ -151,11 +162,11 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() { // and the update creates it. $this->addBaseFieldIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be updated.', ['%field_name' => t('A new base field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update_field__new_base_field'), 'Index created.'); @@ -164,11 +175,11 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() { // update deletes it. $this->removeBaseFieldIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be updated.', ['%field_name' => t('A new base field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update_field__new_base_field'), 'Index deleted.'); @@ -178,11 +189,11 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() { // accordingly. $this->modifyBaseField(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be updated.', ['%field_name' => t('A new base field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->fieldExists('entity_test_update', 'new_base_field'), 'Original column deleted in shared table for new_base_field.'); @@ -193,11 +204,11 @@ public function testBaseFieldCreateUpdateDeleteWithoutData() { // update deletes the schema. $this->removeBaseField(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be uninstalled.', ['%field_name' => t('A new base field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->fieldExists('entity_test_update', 'new_base_field_value'), 'Value column deleted from shared table for new_base_field.'); @@ -212,11 +223,11 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() { // creates its schema. $this->addBundleField(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be installed.', ['%field_name' => t('A new bundle field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table created for new_bundle_field.'); @@ -226,11 +237,11 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() { // accordingly. $this->modifyBundleField(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( + $expected = [ 'entity_test_update' => [ t('The %field_name field needs to be updated.', ['%field_name' => t('A new bundle field')]), ], - ); + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->fieldExists('entity_test_update__new_bundle_field', 'new_bundle_field_format'), 'Format column created in dedicated table for new_base_field.'); @@ -239,11 +250,11 @@ public function testBundleFieldCreateUpdateDeleteWithoutData() { // update deletes the schema. $this->removeBundleField(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %field_name field needs to be uninstalled.', ['%field_name' => t('A new bundle field')]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->tableExists('entity_test_update__new_bundle_field'), 'Dedicated table deleted for new_bundle_field.'); @@ -261,7 +272,7 @@ public function testBaseFieldCreateDeleteWithExistingEntities() { // Save an entity. $name = $this->randomString(); $storage = $this->entityManager->getStorage('entity_test_update'); - $entity = $storage->create(array('name' => $name)); + $entity = $storage->create(['name' => $name]); $entity->save(); // Add a base field and run the update. Ensure the base field's column is @@ -301,7 +312,7 @@ public function testBaseFieldCreateDeleteWithExistingEntities() { $this->entityDefinitionUpdateManager->applyUpdates(); $assert = $schema_handler->fieldExists('entity_test_update', 'new_base_field__shape') && $schema_handler->fieldExists('entity_test_update', 'new_base_field__color'); $this->assertTrue($assert, 'Columns created again in shared table for new_base_field.'); - $entity = $storage->create(array('name' => $name)); + $entity = $storage->create(['name' => $name]); $entity->save(); $this->pass('The new_base_field columns are still nullable'); } @@ -318,7 +329,7 @@ public function testBundleFieldCreateDeleteWithExistingEntities() { // Save an entity. $name = $this->randomString(); $storage = $this->entityManager->getStorage('entity_test_update'); - $entity = $storage->create(array('name' => $name)); + $entity = $storage->create(['name' => $name]); $entity->save(); // Add a bundle field and run the update. Ensure the bundle field's table @@ -342,7 +353,7 @@ public function testBundleFieldCreateDeleteWithExistingEntities() { $this->addBundleField('shape_required'); $this->entityDefinitionUpdateManager->applyUpdates(); $message = 'The new_bundle_field_shape column is not nullable.'; - $values = array( + $values = [ 'bundle' => $entity->bundle(), 'deleted' => 0, 'entity_id' => $entity->id(), @@ -350,7 +361,7 @@ public function testBundleFieldCreateDeleteWithExistingEntities() { 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'delta' => 0, 'new_bundle_field_color' => $this->randomString(), - ); + ]; try { // Try to insert a record without providing a value for the 'not null' // column. This should fail. @@ -385,7 +396,7 @@ public function testBaseFieldDeleteWithExistingData() { $this->entityDefinitionUpdateManager->applyUpdates(); // Save an entity with the base field populated. - $this->entityManager->getStorage('entity_test_update')->create(array('new_base_field' => 'foo'))->save(); + $this->entityManager->getStorage('entity_test_update')->create(['new_base_field' => 'foo'])->save(); // Remove the base field and apply updates. It's expected to throw an // exception. @@ -411,7 +422,7 @@ public function testBundleFieldDeleteWithExistingData() { // Save an entity with the bundle field populated. entity_test_create_bundle('custom'); - $this->entityManager->getStorage('entity_test_update')->create(array('type' => 'test_bundle', 'new_bundle_field' => 'foo'))->save(); + $this->entityManager->getStorage('entity_test_update')->create(['type' => 'test_bundle', 'new_bundle_field' => 'foo'])->save(); // Remove the bundle field and apply updates. It's expected to throw an // exception. @@ -436,7 +447,7 @@ public function testBaseFieldUpdateWithExistingData() { $this->entityDefinitionUpdateManager->applyUpdates(); // Save an entity with the base field populated. - $this->entityManager->getStorage('entity_test_update')->create(array('new_base_field' => 'foo'))->save(); + $this->entityManager->getStorage('entity_test_update')->create(['new_base_field' => 'foo'])->save(); // Change the field's field type and apply updates. It's expected to // throw an exception. @@ -460,7 +471,7 @@ public function testBundleFieldUpdateWithExistingData() { // Save an entity with the bundle field populated. entity_test_create_bundle('custom'); - $this->entityManager->getStorage('entity_test_update')->create(array('type' => 'test_bundle', 'new_bundle_field' => 'foo'))->save(); + $this->entityManager->getStorage('entity_test_update')->create(['type' => 'test_bundle', 'new_bundle_field' => 'foo'])->save(); // Change the field's field type and apply updates. It's expected to // throw an exception. @@ -482,11 +493,11 @@ public function testEntityIndexCreateDeleteWithoutData() { // update to the entity type. $this->addEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %entity_type entity type needs to be updated.', ['%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel()]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the new index is created. @@ -497,11 +508,11 @@ public function testEntityIndexCreateDeleteWithoutData() { // update to the entity type. $this->removeEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); - $expected = array( - 'entity_test_update' => array( + $expected = [ + 'entity_test_update' => [ t('The %entity_type entity type needs to be updated.', ['%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel()]), - ), - ); + ], + ]; $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the index is deleted. @@ -527,7 +538,7 @@ public function testEntityIndexCreateDeleteWithoutData() { public function testEntityIndexCreateWithData() { // Save an entity. $name = $this->randomString(); - $entity = $this->entityManager->getStorage('entity_test_update')->create(array('name' => $name)); + $entity = $this->entityManager->getStorage('entity_test_update')->create(['name' => $name]); $entity->save(); // Add an entity index, run the update. Ensure that the index is created @@ -729,13 +740,13 @@ public function testCreateIndexUsingEntityStorageSchemaWithData() { // Save an entity. $name = $this->randomString(); $storage = $this->entityManager->getStorage('entity_test_update'); - $entity = $storage->create(array('name' => $name)); + $entity = $storage->create(['name' => $name]); $entity->save(); // Create an index. - $indexes = array( - 'entity_test_update__type_index' => array('type'), - ); + $indexes = [ + 'entity_test_update__type_index' => ['type'], + ]; $this->state->set('entity_test_update.additional_entity_indexes', $indexes); $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__type_index'), "New index 'entity_test_update__type_index' has been created on the 'entity_test_update' table."); @@ -766,6 +777,11 @@ public function testBaseFieldEntityKeyUpdateWithExistingData() { // of a NOT NULL constraint. $this->makeBaseFieldEntityKey(); + // Field storage CRUD operations use the last installed entity type + // definition so we need to update it before doing any other field storage + // updates. + $this->entityDefinitionUpdateManager->updateEntityType($this->state->get('entity_test_update.entity_type')); + // Try to apply the update and verify they fail since we have a NULL value. $message = 'An error occurs when trying to enabling NOT NULL constraints with NULL data.'; try { @@ -797,7 +813,7 @@ public function testBaseFieldEntityKeyUpdateWithExistingData() { /** * Check that field schema is correctly handled with long-named fields. */ - function testLongNameFieldIndexes() { + public function testLongNameFieldIndexes() { $this->addLongNameBaseField(); $entity_type_id = 'entity_test_update'; $entity_type = $this->entityManager->getDefinition($entity_type_id); @@ -807,4 +823,119 @@ function testLongNameFieldIndexes() { $this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'Entity and field schema data are correctly detected.'); } + /** + * Tests adding a base field with initial values. + */ + public function testInitialValue() { + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + $db_schema = $this->database->schema(); + + // Create two entities before adding the base field. + /** @var \Drupal\entity_test\Entity\EntityTestUpdate $entity */ + $storage->create()->save(); + $storage->create()->save(); + + // Add a base field with an initial value. + $this->addBaseField(); + $storage_definition = BaseFieldDefinition::create('string') + ->setLabel(t('A new base field')) + ->setInitialValue('test value'); + + $this->assertFalse($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' does not exist before applying the update."); + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition); + $this->assertTrue($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table."); + + // Check that the initial values have been applied. + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + $entities = $storage->loadMultiple(); + $this->assertEquals('test value', $entities[1]->get('new_base_field')->value); + $this->assertEquals('test value', $entities[2]->get('new_base_field')->value); + } + + /** + * Tests adding a base field with initial values inherited from another field. + */ + public function testInitialValueFromField() { + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + $db_schema = $this->database->schema(); + + // Create two entities before adding the base field. + /** @var \Drupal\entity_test\Entity\EntityTestUpdate $entity */ + $storage->create(['name' => 'First entity'])->save(); + $storage->create(['name' => 'Second entity'])->save(); + + // Add a base field with an initial value inherited from another field. + $this->addBaseField(); + $storage_definition = BaseFieldDefinition::create('string') + ->setLabel(t('A new base field')) + ->setInitialValueFromField('name'); + + $this->assertFalse($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' does not exist before applying the update."); + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition); + $this->assertTrue($db_schema->fieldExists('entity_test_update', 'new_base_field'), "New field 'new_base_field' has been created on the 'entity_test_update' table."); + + // Check that the initial values have been applied. + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + $entities = $storage->loadMultiple(); + $this->assertEquals('First entity', $entities[1]->get('new_base_field')->value); + $this->assertEquals('Second entity', $entities[2]->get('new_base_field')->value); + } + + /** + * Tests the error handling when using initial values from another field. + */ + public function testInitialValueFromFieldErrorHandling() { + // Check that setting invalid values for 'initial value from field' doesn't + // work. + try { + $this->addBaseField(); + $storage_definition = BaseFieldDefinition::create('string') + ->setLabel(t('A new base field')) + ->setInitialValueFromField('field_that_does_not_exist'); + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition); + $this->fail('Using a non-existent field as initial value does not work.'); + } + catch (FieldException $e) { + $this->assertEquals('Illegal initial value definition on new_base_field: The field field_that_does_not_exist does not exist.', $e->getMessage()); + $this->pass('Using a non-existent field as initial value does not work.'); + } + + try { + $this->addBaseField(); + $storage_definition = BaseFieldDefinition::create('integer') + ->setLabel(t('A new base field')) + ->setInitialValueFromField('name'); + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $storage_definition); + $this->fail('Using a field of a different type as initial value does not work.'); + } + catch (FieldException $e) { + $this->assertEquals('Illegal initial value definition on new_base_field: The field types do not match.', $e->getMessage()); + $this->pass('Using a field of a different type as initial value does not work.'); + } + + try { + // Add a base field that will not be stored in the shared tables. + $initial_field = BaseFieldDefinition::create('string') + ->setName('initial_field') + ->setLabel(t('An initial field')) + ->setCardinality(2); + $this->state->set('entity_test_update.additional_base_field_definitions', ['initial_field' => $initial_field]); + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('initial_field', 'entity_test_update', 'entity_test', $initial_field); + + // Now add the base field which will try to use the previously added field + // as the source of its initial values. + $new_base_field = BaseFieldDefinition::create('string') + ->setName('new_base_field') + ->setLabel(t('A new base field')) + ->setInitialValueFromField('initial_field'); + $this->state->set('entity_test_update.additional_base_field_definitions', ['initial_field' => $initial_field, 'new_base_field' => $new_base_field]); + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('new_base_field', 'entity_test_update', 'entity_test', $new_base_field); + $this->fail('Using a field that is not stored in the shared tables as initial value does not work.'); + } + catch (FieldException $e) { + $this->assertEquals('Illegal initial value definition on new_base_field: Both fields have to be stored in the shared entity tables.', $e->getMessage()); + $this->pass('Using a field that is not stored in the shared tables as initial value does not work.'); + } + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php index 2294a918..ec1a55cb 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayBaseTest.php @@ -20,6 +20,43 @@ class EntityDisplayBaseTest extends KernelTestBase { */ public static $modules = ['entity_test', 'entity_test_third_party', 'field', 'system', 'comment']; + /** + * @covers ::preSave + */ + public function testPreSave() { + $entity_display = EntityViewDisplay::create([ + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'status' => TRUE, + 'content' => [ + 'foo' => ['type' => 'visible'], + 'bar' => ['type' => 'hidden'], + 'name' => ['type' => 'hidden', 'region' => 'content'], + ], + ]); + + // Ensure that no region is set on the component. + $this->assertArrayNotHasKey('region', $entity_display->getComponent('foo')); + $this->assertArrayNotHasKey('region', $entity_display->getComponent('bar')); + + // Ensure that a region is set on the component after saving. + $entity_display->save(); + + // The component with a visible type has been assigned a region. + $component = $entity_display->getComponent('foo'); + $this->assertArrayHasKey('region', $component); + $this->assertSame('content', $component['region']); + + // The component with a hidden type has been removed. + $this->assertNull($entity_display->getComponent('bar')); + + // The component with a valid region and hidden type is unchanged. + $component = $entity_display->getComponent('name'); + $this->assertArrayHasKey('region', $component); + $this->assertSame('content', $component['region']); + } + /** * @covers ::onDependencyRemoval */ @@ -67,7 +104,7 @@ public function testOnDependencyRemoval() { 'mode' => 'default', 'status' => TRUE, 'content' => [ - 'test_field' => ['type' => 'comment_default', 'settings' => ['view_mode' => 'default'], 'label' => 'hidden', 'third_party_settings' => []], + 'test_field' => ['type' => 'comment_default', 'region' => 'content', 'settings' => ['view_mode' => 'default'], 'label' => 'hidden', 'third_party_settings' => []], ], 'third_party_settings' => [ 'entity_test_third_party' => [ @@ -79,6 +116,7 @@ public function testOnDependencyRemoval() { $expected_component = [ 'type' => 'comment_default', + 'region' => 'content', 'settings' => ['view_mode' => 'default'], 'label' => 'hidden', 'third_party_settings' => [], diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayFormBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayFormBaseTest.php new file mode 100644 index 00000000..11aeede8 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDisplayFormBaseTest.php @@ -0,0 +1,144 @@ +prophesize(EntityDisplayInterface::class); + $entity->getPluginCollections()->willReturn([]); + $entity->getTargetEntityTypeId()->willReturn('entity_test_with_bundle'); + $entity->getTargetBundle()->willReturn('target_bundle'); + + // An initially hidden field, with a submitted region change. + $entity->getComponent('new_field_mismatch_type_visible')->willReturn([]); + $field_values['new_field_mismatch_type_visible'] = [ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'hidden', + ]; + $entity->removeComponent('new_field_mismatch_type_visible') + ->will(function ($args) { + // On subsequent calls, getComponent() will return an empty array. + $this->getComponent($args[0])->willReturn([]); + }) + ->shouldBeCalled(); + + // An initially visible field, with identical submitted values. + $entity->getComponent('field_visible_no_changes') + ->willReturn([ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + ]); + $field_values['field_visible_no_changes'] = [ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + ]; + $entity + ->setComponent('field_visible_no_changes', [ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + ]) + ->shouldBeCalled(); + + + // An initially visible field, with a submitted region change. + $entity->getComponent('field_start_visible_change_region') + ->willReturn([ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + ]); + $field_values['field_start_visible_change_region'] = [ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'hidden', + ]; + $entity->removeComponent('field_start_visible_change_region') + ->will(function ($args) { + // On subsequent calls, getComponent() will return an empty array. + $this->getComponent($args[0])->willReturn([]); + }) + ->shouldBeCalled(); + + // A field that is flagged for plugin settings update on the second build. + $entity->getComponent('field_plugin_settings_update') + ->willReturn([ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + ]); + $field_values['field_plugin_settings_update'] = [ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + 'settings_edit_form' => [ + 'third_party_settings' => [ + 'foo' => 'bar', + ], + ], + ]; + $entity + ->setComponent('field_plugin_settings_update', [ + 'weight' => 0, + 'type' => 'textfield', + 'region' => 'content', + ]) + ->will(function ($args) { + // On subsequent calls, getComponent() will return the newly set values. + $this->getComponent($args[0])->willReturn($args[1]); + $args[1] += [ + 'settings' => [], + 'third_party_settings' => [ + 'foo' => 'bar', + ], + ]; + $this->setComponent($args[0], $args[1])->shouldBeCalled(); + }) + ->shouldBeCalled(); + + $form_object = new EntityViewDisplayEditForm($this->container->get('plugin.manager.field.field_type'), $this->container->get('plugin.manager.field.formatter')); + $form_object->setEntityManager($this->container->get('entity.manager')); + $form_object->setEntity($entity->reveal()); + + $form = [ + '#fields' => array_keys($field_values), + '#extra' => [], + ]; + $form_state = new FormState(); + $form_state->setValues(['fields' => $field_values]); + $form_state->setProcessInput(); + + $form_object->buildEntity($form, $form_state); + $form_state->setSubmitted(); + + // Flag one field for updating plugin settings. + $form_state->set('plugin_settings_update', 'field_plugin_settings_update'); + // During form submission, buildEntity() will be called twice. Simulate that + // here to prove copyFormValuesToEntity() is idempotent. + $form_object->buildEntity($form, $form_state); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDuplicateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDuplicateTest.php new file mode 100644 index 00000000..e2c1af47 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDuplicateTest.php @@ -0,0 +1,55 @@ +installEntitySchema('entity_test_rev'); + $this->entityTestRevStorage = $this->container->get('entity_type.manager')->getStorage('entity_test_rev'); + } + + /** + * Test duplicating a non-default revision. + */ + public function testDuplicateNonDefaultRevision() { + $entity = EntityTestRev::create([ + 'name' => 'First Revision', + ]); + $entity->save(); + $first_revision_id = $entity->getRevisionId(); + + $entity->setNewRevision(TRUE); + $entity->name = 'Second Revision'; + $entity->save(); + + $duplicate_first_revision = $this->entityTestRevStorage->loadRevision($first_revision_id)->createDuplicate(); + $this->assertTrue($duplicate_first_revision->isDefaultRevision(), 'Duplicating a non-default revision creates a default revision.'); + $this->assertEquals($duplicate_first_revision->label(), 'First Revision'); + $duplicate_first_revision->save(); + + $duplicate_first_revision->name = 'Updated name'; + $duplicate_first_revision->save(); + + $this->entityTestRevStorage->resetCache(); + $duplicate_first_revision = EntityTestRev::load($duplicate_first_revision->id()); + $this->assertEquals('Updated name', $duplicate_first_revision->label()); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldDefaultValueTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldDefaultValueTest.php index c806409f..c300b48e 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldDefaultValueTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldDefaultValueTest.php @@ -47,9 +47,9 @@ protected function assertDefaultValues($entity_type_id) { ->create(); $definition = $this->entityManager->getDefinition($entity_type_id); $langcode_key = $definition->getKey('langcode'); - $this->assertEqual($entity->{$langcode_key}->value, 'en', SafeMarkup::format('%entity_type: Default language', array('%entity_type' => $entity_type_id))); - $this->assertTrue(Uuid::isValid($entity->uuid->value), SafeMarkup::format('%entity_type: Default UUID', array('%entity_type' => $entity_type_id))); - $this->assertEqual($entity->name->getValue(), array(), 'Field has one empty value by default.'); + $this->assertEqual($entity->{$langcode_key}->value, 'en', SafeMarkup::format('%entity_type: Default language', ['%entity_type' => $entity_type_id])); + $this->assertTrue(Uuid::isValid($entity->uuid->value), SafeMarkup::format('%entity_type: Default UUID', ['%entity_type' => $entity_type_id])); + $this->assertEqual($entity->name->getValue(), [], 'Field has one empty value by default.'); } /** @@ -60,16 +60,16 @@ public function testDefaultValueCallback() { // The description field has a default value callback for testing, see // entity_test_field_default_value(). $string = 'description_' . $entity->language()->getId(); - $expected = array( - array( + $expected = [ + [ 'shape' => "shape:0:$string", 'color' => "color:0:$string", - ), - array( + ], + [ 'shape' => "shape:1:$string", 'color' => "color:1:$string", - ), - ); + ], + ]; $this->assertEqual($entity->description->getValue(), $expected); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php index 56af8881..31b1f9e9 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php @@ -3,6 +3,7 @@ namespace Drupal\KernelTests\Core\Entity; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\RevisionLogInterface; use Drupal\Core\Entity\TypedData\EntityDataDefinition; use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface; use Drupal\Core\Field\BaseFieldDefinition; @@ -15,6 +16,7 @@ use Drupal\Core\TypedData\ListInterface; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\entity_test\Entity\EntityTestComputedField; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; @@ -30,7 +32,7 @@ class EntityFieldTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('filter', 'text', 'node', 'user', 'field_test'); + public static $modules = ['filter', 'text', 'node', 'user', 'field_test']; /** * @var string @@ -62,7 +64,7 @@ protected function setUp() { entity_test_install(); // Install required default configuration for filter module. - $this->installConfig(array('system', 'filter')); + $this->installConfig(['system', 'filter']); } /** @@ -111,108 +113,108 @@ protected function doTestReadWrite($entity_type) { $langcode = 'en'; // Access the name field. - $this->assertTrue($entity->name instanceof FieldItemListInterface, format_string('%entity_type: Field implements interface', array('%entity_type' => $entity_type))); - $this->assertTrue($entity->name[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->name instanceof FieldItemListInterface, format_string('%entity_type: Field implements interface', ['%entity_type' => $entity_type])); + $this->assertTrue($entity->name[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', ['%entity_type' => $entity_type])); - $this->assertEqual($this->entityName, $entity->name->value, format_string('%entity_type: Name value can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityName, $entity->name[0]->value, format_string('%entity_type: Name value can be read through list access.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name->getValue(), array(0 => array('value' => $this->entityName)), format_string('%entity_type: Plain field value returned.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entityName, $entity->name->value, format_string('%entity_type: Name value can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityName, $entity->name[0]->value, format_string('%entity_type: Name value can be read through list access.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name->getValue(), [0 => ['value' => $this->entityName]], format_string('%entity_type: Plain field value returned.', ['%entity_type' => $entity_type])); // Change the name. $new_name = $this->randomMachineName(); $entity->name->value = $new_name; - $this->assertEqual($new_name, $entity->name->value, format_string('%entity_type: Name can be updated and read.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name->getValue(), array(0 => array('value' => $new_name)), format_string('%entity_type: Plain field value reflects the update.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_name, $entity->name->value, format_string('%entity_type: Name can be updated and read.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name->getValue(), [0 => ['value' => $new_name]], format_string('%entity_type: Plain field value reflects the update.', ['%entity_type' => $entity_type])); $new_name = $this->randomMachineName(); $entity->name[0]->value = $new_name; - $this->assertEqual($new_name, $entity->name->value, format_string('%entity_type: Name can be updated and read through list access.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_name, $entity->name->value, format_string('%entity_type: Name can be updated and read through list access.', ['%entity_type' => $entity_type])); // Access the user field. - $this->assertTrue($entity->user_id instanceof FieldItemListInterface, format_string('%entity_type: Field implements interface', array('%entity_type' => $entity_type))); - $this->assertTrue($entity->user_id[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->user_id instanceof FieldItemListInterface, format_string('%entity_type: Field implements interface', ['%entity_type' => $entity_type])); + $this->assertTrue($entity->user_id[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', ['%entity_type' => $entity_type])); - $this->assertEqual($this->entityUser->id(), $entity->user_id->target_id, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityUser->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entityUser->id(), $entity->user_id->target_id, format_string('%entity_type: User id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityUser->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', ['%entity_type' => $entity_type])); // Change the assigned user by entity. $new_user1 = $this->createUser(); $entity->user_id->entity = $new_user1; - $this->assertEqual($new_user1->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user1->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated username value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user1->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($new_user1->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated username value can be read.', ['%entity_type' => $entity_type])); // Change the assigned user by id. $new_user2 = $this->createUser(); $entity->user_id->target_id = $new_user2->id(); - $this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated username value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated username value can be read.', ['%entity_type' => $entity_type])); // Try unsetting a field property. $entity->name->value = NULL; $entity->user_id->target_id = NULL; - $this->assertNull($entity->name->value, format_string('%entity_type: Name field is not set.', array('%entity_type' => $entity_type))); - $this->assertNull($entity->user_id->target_id, format_string('%entity_type: User ID field is not set.', array('%entity_type' => $entity_type))); - $this->assertNull($entity->user_id->entity, format_string('%entity_type: User entity field is not set.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->name->value, format_string('%entity_type: Name field is not set.', ['%entity_type' => $entity_type])); + $this->assertNull($entity->user_id->target_id, format_string('%entity_type: User ID field is not set.', ['%entity_type' => $entity_type])); + $this->assertNull($entity->user_id->entity, format_string('%entity_type: User entity field is not set.', ['%entity_type' => $entity_type])); // Test setting the values via the typed data API works as well. // Change the assigned user by entity. $entity->user_id->first()->get('entity')->setValue($new_user2); - $this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', ['%entity_type' => $entity_type])); // Change the assigned user by id. $entity->user_id->first()->get('target_id')->setValue($new_user2->id()); - $this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user2->id(), $entity->user_id->target_id, format_string('%entity_type: Updated user id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($new_user2->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', ['%entity_type' => $entity_type])); // Try unsetting a field. $entity->name->first()->get('value')->setValue(NULL); $entity->user_id->first()->get('target_id')->setValue(NULL); - $this->assertNull($entity->name->value, format_string('%entity_type: Name field is not set.', array('%entity_type' => $entity_type))); - $this->assertNull($entity->user_id->target_id, format_string('%entity_type: User ID field is not set.', array('%entity_type' => $entity_type))); - $this->assertNull($entity->user_id->entity, format_string('%entity_type: User entity field is not set.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->name->value, format_string('%entity_type: Name field is not set.', ['%entity_type' => $entity_type])); + $this->assertNull($entity->user_id->target_id, format_string('%entity_type: User ID field is not set.', ['%entity_type' => $entity_type])); + $this->assertNull($entity->user_id->entity, format_string('%entity_type: User entity field is not set.', ['%entity_type' => $entity_type])); // Create a fresh entity so target_id does not get its property object // instantiated, then verify setting a new value via typed data API works. $entity2 = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( - 'user_id' => array('target_id' => $new_user1->id()), - )); + ->create([ + 'user_id' => ['target_id' => $new_user1->id()], + ]); // Access the property object, and set a value. $entity2->user_id->first()->get('target_id')->setValue($new_user2->id()); - $this->assertEqual($new_user2->id(), $entity2->user_id->target_id, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($new_user2->name->value, $entity2->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user2->id(), $entity2->user_id->target_id, format_string('%entity_type: Updated user id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($new_user2->name->value, $entity2->user_id->entity->name->value, format_string('%entity_type: Updated user name value can be read.', ['%entity_type' => $entity_type])); // Test using isset(), empty() and unset(). $entity->name->value = 'test unset'; unset($entity->name->value); - $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); - $this->assertTrue(empty($entity->name->value), format_string('%entity_type: Name is empty.', array('%entity_type' => $entity_type))); - $this->assertTrue(empty($entity->name[0]->value), format_string('%entity_type: Name is empty.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); + $this->assertTrue(empty($entity->name->value), format_string('%entity_type: Name is empty.', ['%entity_type' => $entity_type])); + $this->assertTrue(empty($entity->name[0]->value), format_string('%entity_type: Name is empty.', ['%entity_type' => $entity_type])); $entity->name->value = 'a value'; - $this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type))); - $this->assertTrue(isset($entity->name[0]->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type))); - $this->assertFalse(empty($entity->name->value), format_string('%entity_type: Name is not empty.', array('%entity_type' => $entity_type))); - $this->assertFalse(empty($entity->name[0]->value), format_string('%entity_type: Name is not empty.', array('%entity_type' => $entity_type))); - $this->assertTrue(isset($entity->name[0]), format_string('%entity_type: Name string item is set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name[1]), format_string('%entity_type: Second name string item is not set as it does not exist', array('%entity_type' => $entity_type))); - $this->assertTrue(isset($entity->name), format_string('%entity_type: Name field is set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->nameInvalid), format_string('%entity_type: Not existing field is not set.', array('%entity_type' => $entity_type))); + $this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', ['%entity_type' => $entity_type])); + $this->assertTrue(isset($entity->name[0]->value), format_string('%entity_type: Name is set.', ['%entity_type' => $entity_type])); + $this->assertFalse(empty($entity->name->value), format_string('%entity_type: Name is not empty.', ['%entity_type' => $entity_type])); + $this->assertFalse(empty($entity->name[0]->value), format_string('%entity_type: Name is not empty.', ['%entity_type' => $entity_type])); + $this->assertTrue(isset($entity->name[0]), format_string('%entity_type: Name string item is set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name[1]), format_string('%entity_type: Second name string item is not set as it does not exist', ['%entity_type' => $entity_type])); + $this->assertTrue(isset($entity->name), format_string('%entity_type: Name field is set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->nameInvalid), format_string('%entity_type: Not existing field is not set.', ['%entity_type' => $entity_type])); unset($entity->name[0]); - $this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', ['%entity_type' => $entity_type])); // Test emptying a field by assigning an empty value. NULL and array() // behave the same. - foreach ([NULL, array(), 'unset'] as $empty) { + foreach ([NULL, [], 'unset'] as $empty) { // Make sure a value is present $entity->name->value = 'a value'; - $this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type))); + $this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', ['%entity_type' => $entity_type])); // Now, empty the field. if ($empty === 'unset') { unset($entity->name); @@ -220,36 +222,36 @@ protected function doTestReadWrite($entity_type) { else { $entity->name = $empty; } - $this->assertTrue(isset($entity->name), format_string('%entity_type: Name field is set.', array('%entity_type' => $entity_type))); - $this->assertTrue($entity->name->isEmpty(), format_string('%entity_type: Name field is set.', array('%entity_type' => $entity_type))); - $this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', array('%entity_type' => $entity_type))); - $this->assertIdentical($entity->name->getValue(), array(), format_string('%entity_type: Name field value is an empty array.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: First name item value is not set.', array('%entity_type' => $entity_type))); - $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name value is not set.', array('%entity_type' => $entity_type))); + $this->assertTrue(isset($entity->name), format_string('%entity_type: Name field is set.', ['%entity_type' => $entity_type])); + $this->assertTrue($entity->name->isEmpty(), format_string('%entity_type: Name field is set.', ['%entity_type' => $entity_type])); + $this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', ['%entity_type' => $entity_type])); + $this->assertIdentical($entity->name->getValue(), [], format_string('%entity_type: Name field value is an empty array.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: First name item value is not set.', ['%entity_type' => $entity_type])); + $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name value is not set.', ['%entity_type' => $entity_type])); } // Access the language field. $langcode_key = $this->entityManager->getDefinition($entity_type)->getKey('langcode'); - $this->assertEqual($langcode, $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual(\Drupal::languageManager()->getLanguage($langcode), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($langcode, $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual(\Drupal::languageManager()->getLanguage($langcode), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', ['%entity_type' => $entity_type])); // Change the language by code. $entity->{$langcode_key}->value = \Drupal::languageManager()->getDefaultLanguage()->getId(); - $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage(), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage(), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', ['%entity_type' => $entity_type])); // Revert language by code then try setting it by language object. $entity->{$langcode_key}->value = $langcode; $entity->{$langcode_key}->language = \Drupal::languageManager()->getDefaultLanguage(); - $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage(), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage(), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', ['%entity_type' => $entity_type])); // Access the text field and test updating. - $this->assertEqual($entity->field_test_text->value, $this->entityFieldText, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->field_test_text->value, $this->entityFieldText, format_string('%entity_type: Text field can be read.', ['%entity_type' => $entity_type])); $new_text = $this->randomMachineName(); $entity->field_test_text->value = $new_text; - $this->assertEqual($entity->field_test_text->value, $new_text, format_string('%entity_type: Updated text field can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->field_test_text->value, $new_text, format_string('%entity_type: Updated text field can be read.', ['%entity_type' => $entity_type])); // Test creating the entity by passing in plain values. $this->entityName = $this->randomMachineName(); @@ -261,98 +263,98 @@ protected function doTestReadWrite($entity_type) { $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'name' => $name_item, 'user_id' => $user_item, 'field_test_text' => $text_item, - )); - $this->assertEqual($this->entityName, $entity->name->value, format_string('%entity_type: Name value can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityUser->id(), $entity->user_id->target_id, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityUser->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityFieldText, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); + ]); + $this->assertEqual($this->entityName, $entity->name->value, format_string('%entity_type: Name value can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityUser->id(), $entity->user_id->target_id, format_string('%entity_type: User id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityUser->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityFieldText, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', ['%entity_type' => $entity_type])); // Tests copying field values by assigning the TypedData objects. $entity2 = $this->createTestEntity($entity_type); $entity2->name = $entity->name; $entity2->user_id = $entity->user_id; $entity2->field_test_text = $entity->field_test_text; - $this->assertFalse($entity->name === $entity2->name, format_string('%entity_type: Copying properties results in a different field object.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name->value, $entity2->name->value, format_string('%entity_type: Name field copied.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->user_id->target_id, $entity2->user_id->target_id, format_string('%entity_type: User id field copied.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->field_test_text->value, $entity2->field_test_text->value, format_string('%entity_type: Text field copied.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity->name === $entity2->name, format_string('%entity_type: Copying properties results in a different field object.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name->value, $entity2->name->value, format_string('%entity_type: Name field copied.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->user_id->target_id, $entity2->user_id->target_id, format_string('%entity_type: User id field copied.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->field_test_text->value, $entity2->field_test_text->value, format_string('%entity_type: Text field copied.', ['%entity_type' => $entity_type])); // Tests that assigning TypedData objects to non-field properties keeps the // assigned value as is. $entity2 = $this->createTestEntity($entity_type); $entity2->_not_a_field = $entity->name; - $this->assertTrue($entity2->_not_a_field === $entity->name, format_string('%entity_type: Typed data objects can be copied to non-field properties as is.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity2->_not_a_field === $entity->name, format_string('%entity_type: Typed data objects can be copied to non-field properties as is.', ['%entity_type' => $entity_type])); // Tests adding a value to a field item list. $entity->name[] = 'Another name'; - $this->assertEqual($entity->name[1]->value, 'Another name', format_string('%entity_type: List item added via [] and the first property.', array('%entity_type' => $entity_type))); - $entity->name[] = array('value' => 'Third name'); - $this->assertEqual($entity->name[2]->value, 'Third name', format_string('%entity_type: List item added via [] and an array of properties.', array('%entity_type' => $entity_type))); - $entity->name[3] = array('value' => 'Fourth name'); - $this->assertEqual($entity->name[3]->value, 'Fourth name', format_string('%entity_type: List item added via offset and an array of properties.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->name[1]->value, 'Another name', format_string('%entity_type: List item added via [] and the first property.', ['%entity_type' => $entity_type])); + $entity->name[] = ['value' => 'Third name']; + $this->assertEqual($entity->name[2]->value, 'Third name', format_string('%entity_type: List item added via [] and an array of properties.', ['%entity_type' => $entity_type])); + $entity->name[3] = ['value' => 'Fourth name']; + $this->assertEqual($entity->name[3]->value, 'Fourth name', format_string('%entity_type: List item added via offset and an array of properties.', ['%entity_type' => $entity_type])); unset($entity->name[3]); // Test removing and empty-ing list items. - $this->assertEqual(count($entity->name), 3, format_string('%entity_type: List has 3 items.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entity->name), 3, format_string('%entity_type: List has 3 items.', ['%entity_type' => $entity_type])); unset($entity->name[1]); - $this->assertEqual(count($entity->name), 2, format_string('%entity_type: Second list item has been removed.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name[1]->value, 'Third name', format_string('%entity_type: The subsequent items have been shifted up.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name[1]->getName(), 1, format_string('%entity_type: The items names have been updated to their new delta.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entity->name), 2, format_string('%entity_type: Second list item has been removed.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name[1]->value, 'Third name', format_string('%entity_type: The subsequent items have been shifted up.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name[1]->getName(), 1, format_string('%entity_type: The items names have been updated to their new delta.', ['%entity_type' => $entity_type])); $entity->name[1] = NULL; - $this->assertEqual(count($entity->name), 2, format_string('%entity_type: Assigning NULL does not reduce array count.', array('%entity_type' => $entity_type))); - $this->assertTrue($entity->name[1]->isEmpty(), format_string('%entity_type: Assigning NULL empties the item.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entity->name), 2, format_string('%entity_type: Assigning NULL does not reduce array count.', ['%entity_type' => $entity_type])); + $this->assertTrue($entity->name[1]->isEmpty(), format_string('%entity_type: Assigning NULL empties the item.', ['%entity_type' => $entity_type])); // Test using isEmpty(). unset($entity->name[1]); - $this->assertFalse($entity->name[0]->isEmpty(), format_string('%entity_type: Name item is not empty.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity->name[0]->isEmpty(), format_string('%entity_type: Name item is not empty.', ['%entity_type' => $entity_type])); $entity->name->value = NULL; - $this->assertTrue($entity->name[0]->isEmpty(), format_string('%entity_type: Name item is empty.', array('%entity_type' => $entity_type))); - $this->assertTrue($entity->name->isEmpty(), format_string('%entity_type: Name field is empty.', array('%entity_type' => $entity_type))); - $this->assertEqual(count($entity->name), 1, format_string('%entity_type: Empty item is considered when counting.', array('%entity_type' => $entity_type))); - $this->assertEqual(count(iterator_to_array($entity->name->getIterator())), count($entity->name), format_string('%entity_type: Count matches iterator count.', array('%entity_type' => $entity_type))); - $this->assertTrue($entity->name->getValue() === array(0 => array('value' => NULL)), format_string('%entity_type: Name field value contains a NULL value.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->name[0]->isEmpty(), format_string('%entity_type: Name item is empty.', ['%entity_type' => $entity_type])); + $this->assertTrue($entity->name->isEmpty(), format_string('%entity_type: Name field is empty.', ['%entity_type' => $entity_type])); + $this->assertEqual(count($entity->name), 1, format_string('%entity_type: Empty item is considered when counting.', ['%entity_type' => $entity_type])); + $this->assertEqual(count(iterator_to_array($entity->name->getIterator())), count($entity->name), format_string('%entity_type: Count matches iterator count.', ['%entity_type' => $entity_type])); + $this->assertTrue($entity->name->getValue() === [0 => ['value' => NULL]], format_string('%entity_type: Name field value contains a NULL value.', ['%entity_type' => $entity_type])); // Test using filterEmptyItems(). - $entity->name = array(NULL, 'foo'); - $this->assertEqual(count($entity->name), 2, format_string('%entity_type: List has 2 items.', array('%entity_type' => $entity_type))); + $entity->name = [NULL, 'foo']; + $this->assertEqual(count($entity->name), 2, format_string('%entity_type: List has 2 items.', ['%entity_type' => $entity_type])); $entity->name->filterEmptyItems(); - $this->assertEqual(count($entity->name), 1, format_string('%entity_type: The empty item was removed.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name[0]->value, 'foo', format_string('%entity_type: The items were renumbered.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity->name[0]->getName(), 0, format_string('%entity_type: The deltas were updated in the items.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entity->name), 1, format_string('%entity_type: The empty item was removed.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name[0]->value, 'foo', format_string('%entity_type: The items were renumbered.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity->name[0]->getName(), 0, format_string('%entity_type: The deltas were updated in the items.', ['%entity_type' => $entity_type])); // Test get and set field values. $entity->name = 'foo'; - $this->assertEqual($entity->name[0]->toArray(), array('value' => 'foo'), format_string('%entity_type: Field value has been retrieved via toArray()', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->name[0]->toArray(), ['value' => 'foo'], format_string('%entity_type: Field value has been retrieved via toArray()', ['%entity_type' => $entity_type])); $values = $entity->toArray(); - $this->assertEqual($values['name'], array(0 => array('value' => 'foo')), format_string('%entity_type: Field value has been retrieved via toArray() from an entity.', array('%entity_type' => $entity_type))); + $this->assertEqual($values['name'], [0 => ['value' => 'foo']], format_string('%entity_type: Field value has been retrieved via toArray() from an entity.', ['%entity_type' => $entity_type])); // Make sure the user id can be set to zero. $user_item[0]['target_id'] = 0; $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'name' => $name_item, 'user_id' => $user_item, 'field_test_text' => $text_item, - )); - $this->assertNotNull($entity->user_id->target_id, format_string('%entity_type: User id is not NULL', array('%entity_type' => $entity_type))); - $this->assertIdentical($entity->user_id->target_id, 0, format_string('%entity_type: User id has been set to 0', array('%entity_type' => $entity_type))); + ]); + $this->assertNotNull($entity->user_id->target_id, format_string('%entity_type: User id is not NULL', ['%entity_type' => $entity_type])); + $this->assertIdentical($entity->user_id->target_id, 0, format_string('%entity_type: User id has been set to 0', ['%entity_type' => $entity_type])); // Test setting the ID with the value only. $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'name' => $name_item, 'user_id' => 0, 'field_test_text' => $text_item, - )); - $this->assertNotNull($entity->user_id->target_id, format_string('%entity_type: User id is not NULL', array('%entity_type' => $entity_type))); - $this->assertIdentical($entity->user_id->target_id, 0, format_string('%entity_type: User id has been set to 0', array('%entity_type' => $entity_type))); + ]); + $this->assertNotNull($entity->user_id->target_id, format_string('%entity_type: User id is not NULL', ['%entity_type' => $entity_type])); + $this->assertIdentical($entity->user_id->target_id, 0, format_string('%entity_type: User id has been set to 0', ['%entity_type' => $entity_type])); } /** @@ -375,21 +377,21 @@ protected function doTestSave($entity_type) { $langcode_key = $this->entityManager->getDefinition($entity_type)->getKey('langcode'); $entity = $this->createTestEntity($entity_type); $entity->save(); - $this->assertTrue((bool) $entity->id(), format_string('%entity_type: Entity has received an id.', array('%entity_type' => $entity_type))); + $this->assertTrue((bool) $entity->id(), format_string('%entity_type: Entity has received an id.', ['%entity_type' => $entity_type])); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) ->load($entity->id()); - $this->assertTrue((bool) $entity->id(), format_string('%entity_type: Entity loaded.', array('%entity_type' => $entity_type))); + $this->assertTrue((bool) $entity->id(), format_string('%entity_type: Entity loaded.', ['%entity_type' => $entity_type])); // Access the name field. - $this->assertEqual(1, $entity->id->value, format_string('%entity_type: ID value can be read.', array('%entity_type' => $entity_type))); - $this->assertTrue(is_string($entity->uuid->value), format_string('%entity_type: UUID value can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual('en', $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual(\Drupal::languageManager()->getLanguage('en'), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityUser->id(), $entity->user_id->target_id, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityUser->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entityFieldText, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(1, $entity->id->value, format_string('%entity_type: ID value can be read.', ['%entity_type' => $entity_type])); + $this->assertTrue(is_string($entity->uuid->value), format_string('%entity_type: UUID value can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual('en', $entity->{$langcode_key}->value, format_string('%entity_type: Language code can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual(\Drupal::languageManager()->getLanguage('en'), $entity->{$langcode_key}->language, format_string('%entity_type: Language object can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityUser->id(), $entity->user_id->target_id, format_string('%entity_type: User id can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityUser->getUsername(), $entity->user_id->entity->name->value, format_string('%entity_type: User name can be read.', ['%entity_type' => $entity_type])); + $this->assertEqual($this->entityFieldText, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', ['%entity_type' => $entity_type])); } /** @@ -470,30 +472,30 @@ protected function doTestIntrospection($entity_type) { // Make sure provided contextual information is right. $entity_adapter = $entity->getTypedData(); - $this->assertIdentical($entity_adapter->getRoot(), $entity_adapter, 'Entity is root object.'); + $this->assertSame($entity_adapter->getRoot(), $entity_adapter, 'Entity is root object.'); $this->assertEqual($entity_adapter->getPropertyPath(), ''); $this->assertEqual($entity_adapter->getName(), ''); $this->assertEqual($entity_adapter->getParent(), NULL); $field = $entity->user_id; - $this->assertIdentical($field->getRoot()->getValue(), $entity, 'Entity is root object.'); - $this->assertIdentical($field->getEntity(), $entity, 'getEntity() returns the entity.'); + $this->assertSame($field->getRoot()->getValue(), $entity, 'Entity is root object.'); + $this->assertSame($field->getEntity(), $entity, 'getEntity() returns the entity.'); $this->assertEqual($field->getPropertyPath(), 'user_id'); $this->assertEqual($field->getName(), 'user_id'); - $this->assertIdentical($field->getParent()->getValue(), $entity, 'Parent object matches.'); + $this->assertSame($field->getParent()->getValue(), $entity, 'Parent object matches.'); $field_item = $field[0]; - $this->assertIdentical($field_item->getRoot()->getValue(), $entity, 'Entity is root object.'); - $this->assertIdentical($field_item->getEntity(), $entity, 'getEntity() returns the entity.'); + $this->assertSame($field_item->getRoot()->getValue(), $entity, 'Entity is root object.'); + $this->assertSame($field_item->getEntity(), $entity, 'getEntity() returns the entity.'); $this->assertEqual($field_item->getPropertyPath(), 'user_id.0'); $this->assertEqual($field_item->getName(), '0'); - $this->assertIdentical($field_item->getParent(), $field, 'Parent object matches.'); + $this->assertSame($field_item->getParent(), $field, 'Parent object matches.'); $item_value = $field_item->get('entity'); - $this->assertIdentical($item_value->getRoot()->getValue(), $entity, 'Entity is root object.'); + $this->assertSame($item_value->getRoot()->getValue(), $entity, 'Entity is root object.'); $this->assertEqual($item_value->getPropertyPath(), 'user_id.0.entity'); $this->assertEqual($item_value->getName(), 'entity'); - $this->assertIdentical($item_value->getParent(), $field_item, 'Parent object matches.'); + $this->assertSame($item_value->getParent(), $field_item, 'Parent object matches.'); } /** @@ -531,8 +533,8 @@ protected function doTestIterator($entity_type) { } $fields = $entity->getFields(); - $this->assertEqual(array_keys($fields), array_keys($entity->getTypedData()->getDataDefinition()->getPropertyDefinitions()), format_string('%entity_type: All fields returned.', array('%entity_type' => $entity_type))); - $this->assertEqual($fields, iterator_to_array($entity->getIterator()), format_string('%entity_type: Entity iterator iterates over all fields.', array('%entity_type' => $entity_type))); + $this->assertEqual(array_keys($fields), array_keys($entity->getTypedData()->getDataDefinition()->getPropertyDefinitions()), format_string('%entity_type: All fields returned.', ['%entity_type' => $entity_type])); + $this->assertEqual($fields, iterator_to_array($entity->getIterator()), format_string('%entity_type: Entity iterator iterates over all fields.', ['%entity_type' => $entity_type])); } /** @@ -557,12 +559,12 @@ protected function doTestDataStructureInterfaces($entity_type) { // Test using the whole tree of typed data by navigating through the tree of // contained properties and getting all contained strings, limited by a // certain depth. - $strings = array(); + $strings = []; $this->getContainedStrings($entity->getTypedData(), 0, $strings); // @todo: Once the user entity has defined properties this should contain // the user name and other user entity strings as well. - $target_strings = array( + $target_strings = [ $entity->uuid->value, 'en', $this->entityName, @@ -571,10 +573,16 @@ protected function doTestDataStructureInterfaces($entity_type) { $this->entityFieldText, // Field format. NULL, - ); + ]; + + if ($entity instanceof RevisionLogInterface) { + // Adding empty string for revision message. + $target_strings[] = ''; + } + asort($strings); asort($target_strings); - $this->assertEqual(array_values($strings), array_values($target_strings), format_string('%entity_type: All contained strings found.', array('%entity_type' => $entity_type))); + $this->assertEqual(array_values($strings), array_values($target_strings), format_string('%entity_type: All contained strings found.', ['%entity_type' => $entity_type])); } /** @@ -622,10 +630,10 @@ public function testDataTypes() { * @see entity_test_entity_base_field_info_alter() */ public function testBaseFieldNonExistingBaseField() { - $this->entityManager->getStorage('node_type')->create(array( + $this->entityManager->getStorage('node_type')->create([ 'type' => 'page', 'name' => 'page', - ))->save(); + ])->save(); $this->entityManager->clearCachedFieldDefinitions(); $fields = $this->entityManager->getFieldDefinitions('node', 'page'); $override = $fields['status']->getConfig('page'); @@ -679,7 +687,7 @@ public function testEntityConstraintValidation() { ->setLabel('Test entity') ->setSetting('target_type', 'entity_test'); $reference_field = \Drupal::typedDataManager()->create($definition); - $reference = $reference_field->appendItem(array('entity' => $entity))->get('entity'); + $reference = $reference_field->appendItem(['entity' => $entity])->get('entity'); // Test validation the typed data object. $violations = $reference->validate(); @@ -698,14 +706,14 @@ public function testEntityConstraintValidation() { $this->assertEqual($violations->count(), 1); // Test bundle validation. - NodeType::create(array('type' => 'article')) + NodeType::create(['type' => 'article']) ->save(); $definition = BaseFieldDefinition::create('entity_reference') ->setLabel('Test entity') ->setSetting('target_type', 'node') ->setSetting('handler_settings', ['target_bundles' => ['article' => 'article']]); $reference_field = \Drupal::TypedDataManager()->create($definition); - $reference_field->appendItem(array('entity' => $node)); + $reference_field->appendItem(['entity' => $node]); $violations = $reference_field->validate(); $this->assertEqual($violations->count(), 1); @@ -730,6 +738,16 @@ public function testComputedProperties() { } } + /** + * Test computed fields. + */ + public function testComputedFields() { + \Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']); + + $entity = EntityTestComputedField::create([]); + $this->assertEquals($entity->computed_string_field->value, 'foo computed'); + } + /** * Executes the computed properties tests for the given entity type. * @@ -742,14 +760,14 @@ protected function doTestComputedProperties($entity_type) { $entity->field_test_text->format = filter_default_format(); $target = "

    The <strong>text</strong> text to filter.

    \n"; - $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', ['%entity_type' => $entity_type])); // Save and load entity and make sure it still works. $entity->save(); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) ->load($entity->id()); - $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', ['%entity_type' => $entity_type])); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php index 4b08a56f..f7108d53 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php @@ -31,7 +31,7 @@ abstract class EntityKernelTestBase extends KernelTestBase { * * @var array */ - protected $generatedIds = array(); + protected $generatedIds = []; /** * The state service. @@ -62,7 +62,7 @@ protected function setUp() { // Only check the modules, if the $modules property was not inherited. $rp = new \ReflectionProperty($class, 'modules'); if ($rp->class == $class) { - foreach (array_intersect(array('node', 'comment'), $class::$modules) as $module) { + foreach (array_intersect(['node', 'comment'], $class::$modules) as $module) { $this->installEntitySchema($module); } if (in_array('forum', $class::$modules, TRUE)) { @@ -79,7 +79,7 @@ protected function setUp() { $class = get_parent_class($class); } - $this->installConfig(array('field')); + $this->installConfig(['field']); } /** @@ -93,22 +93,22 @@ protected function setUp() { * @return \Drupal\user\Entity\User * The created user entity. */ - protected function createUser($values = array(), $permissions = array()) { + protected function createUser($values = [], $permissions = []) { if ($permissions) { // Create a new role and apply permissions to it. - $role = Role::create(array( + $role = Role::create([ 'id' => strtolower($this->randomMachineName(8)), 'label' => $this->randomMachineName(8), - )); + ]); $role->save(); user_role_grant_permissions($role->id(), $permissions); $values['roles'][] = $role->id(); } - $account = User::create($values + array( + $account = User::create($values + [ 'name' => $this->randomMachineName(), 'status' => 1, - )); + ]); $account->enforceIsNew(); $account->save(); return $account; @@ -125,7 +125,7 @@ protected function createUser($values = array(), $permissions = array()) { */ protected function reloadEntity(EntityInterface $entity) { $controller = $this->entityManager->getStorage($entity->getEntityTypeId()); - $controller->resetCache(array($entity->id())); + $controller->resetCache([$entity->id()]); return $controller->load($entity->id()); } @@ -138,7 +138,7 @@ protected function reloadEntity(EntityInterface $entity) { protected function getHooksInfo() { $key = 'entity_test.hooks'; $hooks = $this->state->get($key); - $this->state->set($key, array()); + $this->state->set($key, []); return $hooks; } @@ -149,7 +149,7 @@ protected function getHooksInfo() { * The module to install. */ protected function installModule($module) { - $this->enableModules(array($module)); + $this->enableModules([$module]); $this->refreshServices(); } @@ -160,7 +160,7 @@ protected function installModule($module) { * The module to uninstall. */ protected function uninstallModule($module) { - $this->disableModules(array($module)); + $this->disableModules([$module]); $this->refreshServices(); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php index 59510bac..570aa984 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityLanguageTestBase.php @@ -40,7 +40,7 @@ abstract class EntityLanguageTestBase extends EntityKernelTestBase { */ protected $untranslatableFieldName; - public static $modules = array('language', 'entity_test'); + public static $modules = ['language', 'entity_test']; protected function setUp() { parent::setUp(); @@ -54,7 +54,7 @@ protected function setUp() { } } - $this->installConfig(array('language')); + $this->installConfig(['language']); // Create the test field. module_load_install('entity_test'); @@ -71,12 +71,12 @@ protected function setUp() { // Create field fields in all entity variations. foreach (entity_test_entity_types() as $entity_type) { - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => $entity_type, 'type' => 'text', 'cardinality' => 4, - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => $entity_type, @@ -84,12 +84,12 @@ protected function setUp() { 'translatable' => TRUE, ])->save(); - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $this->untranslatableFieldName, 'entity_type' => $entity_type, 'type' => 'text', 'cardinality' => 4, - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $this->untranslatableFieldName, 'entity_type' => $entity_type, @@ -99,16 +99,16 @@ protected function setUp() { } // Create the default languages. - $this->installConfig(array('language')); + $this->installConfig(['language']); // Create test languages. - $this->langcodes = array(); + $this->langcodes = []; for ($i = 0; $i < 3; ++$i) { - $language = ConfigurableLanguage::create(array( + $language = ConfigurableLanguage::create([ 'id' => 'l' . $i, 'label' => $this->randomString(), 'weight' => $i, - )); + ]); $this->langcodes[$i] = $language->getId(); $language->save(); } @@ -121,7 +121,7 @@ protected function setUp() { * The type of the entity fields are attached to. */ protected function toggleFieldTranslatability($entity_type, $bundle) { - $fields = array($this->fieldName, $this->untranslatableFieldName); + $fields = [$this->fieldName, $this->untranslatableFieldName]; foreach ($fields as $field_name) { $field = FieldConfig::loadByName($entity_type, $bundle, $field_name); $translatable = !$field->isTranslatable(); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityLoadByUuidTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityLoadByUuidTest.php new file mode 100644 index 00000000..4974a74c --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityLoadByUuidTest.php @@ -0,0 +1,53 @@ +installEntitySchema('user'); + $this->installEntitySchema('entity_test'); + } + + /** + * Ensures that ::loadEntityByUuid() doesn't apply access checking. + */ + public function testLoadEntityByUuidAccessChecking() { + \Drupal::state()->set('entity_test_query_access', TRUE); + // Create two test entities. + $entity_0 = EntityTest::create([ + 'type' => 'entity_test', + 'name' => 'published entity' + ]); + $entity_0->save(); + $entity_1 = EntityTest::create([ + 'type' => 'entity_test', + 'name' => 'unpublished entity' + ]); + $entity_1->save(); + + /** @var \Drupal\Core\Entity\EntityRepositoryInterface $repository */ + $repository = \Drupal::service('entity.repository'); + $this->assertEquals($entity_0->id(), $repository->loadEntityByUuid('entity_test', $entity_0->uuid())->id()); + $this->assertEquals($entity_1->id(), $repository->loadEntityByUuid('entity_test', $entity_1->uuid())->id()); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityLoadedRevisionTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityLoadedRevisionTest.php new file mode 100644 index 00000000..a3b99fe0 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityLoadedRevisionTest.php @@ -0,0 +1,170 @@ +installEntitySchema('entity_test_mulrev'); + } + + /** + * Test getLoadedRevisionId() returns the correct ID throughout the process. + */ + public function testLoadedRevisionId() { + // Create a basic EntityTestMulRev entity and save it. + $entity = EntityTestMulRev::create(); + $entity->save(); + + // Load the created entity and create a new revision. + $loaded = EntityTestMulRev::load($entity->id()); + $loaded->setNewRevision(TRUE); + + // Before saving, the loaded Revision ID should be the same as the created + // entity, not the same as the loaded entity (which does not have a revision + // ID yet). + $this->assertEquals($entity->getRevisionId(), $loaded->getLoadedRevisionId()); + $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + $this->assertSame(NULL, $loaded->getRevisionId()); + + // After updating the loaded Revision ID the result should be the same. + $loaded->updateLoadedRevisionId(); + $this->assertEquals($entity->getRevisionId(), $loaded->getLoadedRevisionId()); + $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + $this->assertSame(NULL, $loaded->getRevisionId()); + + $loaded->save(); + + // In entity_test_entity_update() the loaded Revision ID was stored in + // state. This should be the same as we had before calling $loaded->save(). + /** @var \Drupal\Core\Entity\ContentEntityInterface $loaded_original */ + $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId'); + $this->assertEquals($entity->getRevisionId(), $loadedRevisionId); + $this->assertNotEquals($loaded->getRevisionId(), $loadedRevisionId); + + // The revision ID and loaded Revision ID should be different for the two + // versions of the entity, but the same for a saved entity. + $this->assertNotEquals($loaded->getRevisionId(), $entity->getRevisionId()); + $this->assertNotEquals($loaded->getLoadedRevisionId(), $entity->getLoadedRevisionId()); + $this->assertEquals($entity->getRevisionId(), $entity->getLoadedRevisionId()); + $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + } + + /** + * Tests the loaded revision ID after an entity re-save, clone and duplicate. + */ + public function testLoadedRevisionIdWithNoNewRevision() { + // Create a basic EntityTestMulRev entity and save it. + $entity = EntityTestMulRev::create(); + $entity->save(); + + // Load the created entity and create a new revision. + $loaded = EntityTestMulRev::load($entity->id()); + $loaded->setNewRevision(TRUE); + $loaded->save(); + + // Make a change to the loaded entity. + $loaded->set('name', 'dublin'); + + // The revision id and loaded Revision id should still be the same. + $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + + $loaded->save(); + + // After saving, the loaded Revision id set in entity_test_entity_update() + // and returned from the entity should be the same as the entity's revision + // id because a new revision wasn't created, the existing revision was + // updated. + $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId'); + $this->assertEquals($loaded->getRevisionId(), $loadedRevisionId); + $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + + // Creating a clone should keep the loaded Revision ID. + $clone = clone $loaded; + $this->assertSame($loaded->getLoadedRevisionId(), $clone->getLoadedRevisionId()); + + // Creating a duplicate should set a NULL loaded Revision ID. + $duplicate = $loaded->createDuplicate(); + $this->assertSame(NULL, $duplicate->getLoadedRevisionId()); + } + + /** + * Tests the loaded revision ID for translatable entities. + */ + public function testTranslatedLoadedRevisionId() { + ConfigurableLanguage::createFromLangcode('fr')->save(); + + // Create a basic EntityTestMulRev entity and save it. + $entity = EntityTestMulRev::create(); + $entity->save(); + + // Load the created entity and create a new revision. + $loaded = EntityTestMulRev::load($entity->id()); + $loaded->setNewRevision(TRUE); + $loaded->save(); + + // Check it all works with translations. + $french = $loaded->addTranslation('fr'); + // Adding a revision should return the same for each language. + $this->assertEquals($french->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertEquals($loaded->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertEquals($loaded->getLoadedRevisionId(), $french->getLoadedRevisionId()); + $french->save(); + // After saving nothing should change. + $this->assertEquals($french->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertEquals($loaded->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertEquals($loaded->getLoadedRevisionId(), $french->getLoadedRevisionId()); + $first_revision_id = $french->getRevisionId(); + $french->setNewRevision(); + // Setting a new revision will reset the loaded Revision ID. + $this->assertEquals($first_revision_id, $french->getLoadedRevisionId()); + $this->assertEquals($first_revision_id, $loaded->getLoadedRevisionId()); + $this->assertNotEquals($french->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertGreaterThan($french->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertNotEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + $this->assertGreaterThan($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + $french->save(); + // Saving the new revision will reset the origin revision ID again. + $this->assertEquals($french->getRevisionId(), $french->getLoadedRevisionId()); + $this->assertEquals($loaded->getRevisionId(), $loaded->getLoadedRevisionId()); + } + + /** + * Tests re-saving the entity in entity_test_entity_insert(). + */ + public function testSaveInHookEntityInsert() { + // Create an entity which will be saved again in entity_test_entity_insert(). + $entity = EntityTestMulRev::create(['name' => 'EntityLoadedRevisionTest']); + $entity->save(); + $loadedRevisionId = \Drupal::state()->get('entity_test.loadedRevisionId'); + $this->assertEquals($entity->getLoadedRevisionId(), $loadedRevisionId); + $this->assertEquals($entity->getRevisionId(), $entity->getLoadedRevisionId()); + + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityNonRevisionableTranslatableFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityNonRevisionableTranslatableFieldTest.php index da6ec664..2160da96 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityNonRevisionableTranslatableFieldTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityNonRevisionableTranslatableFieldTest.php @@ -1,6 +1,7 @@ set('non_rev_field', 'Hello'); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryAggregateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryAggregateTest.php index 819445d1..b6362fbc 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryAggregateTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryAggregateTest.php @@ -18,7 +18,7 @@ class EntityQueryAggregateTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array(); + public static $modules = []; /** * The entity_test storage to create the test entities. @@ -50,12 +50,12 @@ protected function setUp() { // Add some fieldapi fields to be used in the test. for ($i = 1; $i <= 2; $i++) { $field_name = 'field_test_' . $i; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'integer', 'cardinality' => 2, - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', @@ -63,53 +63,53 @@ protected function setUp() { ])->save(); } - $entity = $this->entityStorage->create(array( + $entity = $this->entityStorage->create([ 'id' => 1, 'user_id' => 1, 'field_test_1' => 1, 'field_test_2' => 2, - )); + ]); $entity->enforceIsNew(); $entity->save(); - $entity = $this->entityStorage->create(array( + $entity = $this->entityStorage->create([ 'id' => 2, 'user_id' => 2, 'field_test_1' => 1, 'field_test_2' => 7, - )); + ]); $entity->enforceIsNew(); $entity->save(); - $entity = $this->entityStorage->create(array( + $entity = $this->entityStorage->create([ 'id' => 3, 'user_id' => 2, 'field_test_1' => 2, 'field_test_2' => 1, - )); + ]); $entity->enforceIsNew(); $entity->save(); - $entity = $this->entityStorage->create(array( + $entity = $this->entityStorage->create([ 'id' => 4, 'user_id' => 2, 'field_test_1' => 2, 'field_test_2' => 8, - )); + ]); $entity->enforceIsNew(); $entity->save(); - $entity = $this->entityStorage->create(array( + $entity = $this->entityStorage->create([ 'id' => 5, 'user_id' => 3, 'field_test_1' => 2, 'field_test_2' => 2, - )); + ]); $entity->enforceIsNew(); $entity->save(); - $entity = $this->entityStorage->create(array( + $entity = $this->entityStorage->create([ 'id' => 6, 'user_id' => 3, 'field_test_1' => 3, 'field_test_2' => 8, - )); + ]); $entity->enforceIsNew(); $entity->save(); @@ -124,18 +124,18 @@ public function testAggregation() { ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 1), - array('user_id' => 2), - array('user_id' => 3), - )); + $this->assertResults([ + ['user_id' => 1], + ['user_id' => 2], + ['user_id' => 3], + ]); - $function_expected = array(); - $function_expected['count'] = array(array('id_count' => 6)); - $function_expected['min'] = array(array('id_min' => 1)); - $function_expected['max'] = array(array('id_max' => 6)); - $function_expected['sum'] = array(array('id_sum' => 21)); - $function_expected['avg'] = array(array('id_avg' => (21.0 / 6.0))); + $function_expected = []; + $function_expected['count'] = [['id_count' => 6]]; + $function_expected['min'] = [['id_min' => 1]]; + $function_expected['max'] = [['id_max' => 6]]; + $function_expected['sum'] = [['id_sum' => 21]]; + $function_expected['avg'] = [['id_avg' => (21.0 / 6.0)]]; // Apply a simple aggregation for different aggregation functions. foreach ($function_expected as $aggregation_function => $expected) { @@ -150,11 +150,11 @@ public function testAggregation() { ->aggregate('id', 'COUNT') ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 1, 'id_count' => 1), - array('user_id' => 2, 'id_count' => 3), - array('user_id' => 3, 'id_count' => 2), - )); + $this->assertResults([ + ['user_id' => 1, 'id_count' => 1], + ['user_id' => 2, 'id_count' => 3], + ['user_id' => 3, 'id_count' => 2], + ]); // Apply aggregation and a condition which matches. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -162,14 +162,14 @@ public function testAggregation() { ->groupBy('id') ->conditionAggregate('id', 'COUNT', 8) ->execute(); - $this->assertResults(array()); + $this->assertResults([]); // Don't call aggregate to test the implicit aggregate call. $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('id') ->conditionAggregate('id', 'COUNT', 8) ->execute(); - $this->assertResults(array()); + $this->assertResults([]); // Apply aggregation and a condition which matches. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -177,7 +177,7 @@ public function testAggregation() { ->groupBy('id') ->conditionAggregate('id', 'COUNT', 6) ->execute(); - $this->assertResults(array(array('id_count' => 6))); + $this->assertResults([['id_count' => 6]]); // Apply aggregation, a groupby and a condition which matches partially via // the operator '='. @@ -186,7 +186,7 @@ public function testAggregation() { ->conditionAggregate('id', 'count', 2) ->groupBy('user_id') ->execute(); - $this->assertResults(array(array('id_count' => 2, 'user_id' => 3))); + $this->assertResults([['id_count' => 2, 'user_id' => 3]]); // Apply aggregation, a groupby and a condition which matches partially via // the operator '>'. @@ -195,10 +195,10 @@ public function testAggregation() { ->conditionAggregate('id', 'COUNT', 1, '>') ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('id_count' => 2, 'user_id' => 3), - array('id_count' => 3, 'user_id' => 2), - )); + $this->assertResults([ + ['id_count' => 2, 'user_id' => 3], + ['id_count' => 3, 'user_id' => 2], + ]); // Apply aggregation and a sort. This might not be useful, but have a proper // test coverage. @@ -206,13 +206,13 @@ public function testAggregation() { ->aggregate('id', 'COUNT') ->sortAggregate('id', 'COUNT') ->execute(); - $this->assertSortedResults(array(array('id_count' => 6))); + $this->assertSortedResults([['id_count' => 6]]); // Don't call aggregate to test the implicit aggregate call. $this->queryResult = $this->factory->getAggregate('entity_test') ->sortAggregate('id', 'COUNT') ->execute(); - $this->assertSortedResults(array(array('id_count' => 6))); + $this->assertSortedResults([['id_count' => 6]]); // Apply aggregation, groupby and a sort descending. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -220,11 +220,11 @@ public function testAggregation() { ->groupBy('user_id') ->sortAggregate('id', 'COUNT', 'DESC') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 2, 'id_count' => 3), - array('user_id' => 3, 'id_count' => 2), - array('user_id' => 1, 'id_count' => 1), - )); + $this->assertSortedResults([ + ['user_id' => 2, 'id_count' => 3], + ['user_id' => 3, 'id_count' => 2], + ['user_id' => 1, 'id_count' => 1], + ]); // Apply aggregation, groupby and a sort ascending. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -232,11 +232,11 @@ public function testAggregation() { ->groupBy('user_id') ->sortAggregate('id', 'COUNT', 'ASC') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 1, 'id_count' => 1), - array('user_id' => 3, 'id_count' => 2), - array('user_id' => 2, 'id_count' => 3), - )); + $this->assertSortedResults([ + ['user_id' => 1, 'id_count' => 1], + ['user_id' => 3, 'id_count' => 2], + ['user_id' => 2, 'id_count' => 3], + ]); // Apply aggregation, groupby, an aggregation condition and a sort with the // operator '='. @@ -246,7 +246,7 @@ public function testAggregation() { ->sortAggregate('id', 'COUNT') ->conditionAggregate('id', 'COUNT', 2) ->execute(); - $this->assertSortedResults(array(array('id_count' => 2, 'user_id' => 3))); + $this->assertSortedResults([['id_count' => 2, 'user_id' => 3]]); // Apply aggregation, groupby, an aggregation condition and a sort with the // operator '<' and order ASC. @@ -256,10 +256,10 @@ public function testAggregation() { ->sortAggregate('id', 'COUNT', 'ASC') ->conditionAggregate('id', 'COUNT', 3, '<') ->execute(); - $this->assertSortedResults(array( - array('id_count' => 1, 'user_id' => 1), - array('id_count' => 2, 'user_id' => 3), - )); + $this->assertSortedResults([ + ['id_count' => 1, 'user_id' => 1], + ['id_count' => 2, 'user_id' => 3], + ]); // Apply aggregation, groupby, an aggregation condition and a sort with the // operator '<' and order DESC. @@ -269,10 +269,10 @@ public function testAggregation() { ->sortAggregate('id', 'COUNT', 'DESC') ->conditionAggregate('id', 'COUNT', 3, '<') ->execute(); - $this->assertSortedResults(array( - array('id_count' => 2, 'user_id' => 3), - array('id_count' => 1, 'user_id' => 1), - )); + $this->assertSortedResults([ + ['id_count' => 2, 'user_id' => 3], + ['id_count' => 1, 'user_id' => 1], + ]); // Test aggregation/groupby support for fieldapi fields. @@ -280,11 +280,11 @@ public function testAggregation() { $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('field_test_1') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1), - array('field_test_1' => 2), - array('field_test_1' => 3), - )); + $this->assertResults([ + ['field_test_1' => 1], + ['field_test_1' => 2], + ['field_test_1' => 3], + ]); // Group by a fieldapi field and aggregate a normal property. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -292,11 +292,11 @@ public function testAggregation() { ->groupBy('field_test_1') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'user_id_count' => 2), - array('field_test_1' => 2, 'user_id_count' => 3), - array('field_test_1' => 3, 'user_id_count' => 1), - )); + $this->assertResults([ + ['field_test_1' => 1, 'user_id_count' => 2], + ['field_test_1' => 2, 'user_id_count' => 3], + ['field_test_1' => 3, 'user_id_count' => 1], + ]); // Group by a normal property and aggregate a fieldapi field. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -304,21 +304,21 @@ public function testAggregation() { ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 1, 'field_test_1_count' => 1), - array('user_id' => 2, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_count' => 2), - )); + $this->assertResults([ + ['user_id' => 1, 'field_test_1_count' => 1], + ['user_id' => 2, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_count' => 2], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->aggregate('field_test_1', 'SUM') ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 1, 'field_test_1_sum' => 1), - array('user_id' => 2, 'field_test_1_sum' => 5), - array('user_id' => 3, 'field_test_1_sum' => 5), - )); + $this->assertResults([ + ['user_id' => 1, 'field_test_1_sum' => 1], + ['user_id' => 2, 'field_test_1_sum' => 5], + ['user_id' => 3, 'field_test_1_sum' => 5], + ]); // Aggregate by two different fieldapi fields. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -326,11 +326,11 @@ public function testAggregation() { ->aggregate('field_test_2', 'SUM') ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 1, 'field_test_1_sum' => 1, 'field_test_2_sum' => 2), - array('user_id' => 2, 'field_test_1_sum' => 5, 'field_test_2_sum' => 16), - array('user_id' => 3, 'field_test_1_sum' => 5, 'field_test_2_sum' => 10), - )); + $this->assertResults([ + ['user_id' => 1, 'field_test_1_sum' => 1, 'field_test_2_sum' => 2], + ['user_id' => 2, 'field_test_1_sum' => 5, 'field_test_2_sum' => 16], + ['user_id' => 3, 'field_test_1_sum' => 5, 'field_test_2_sum' => 10], + ]); // This time aggregate the same field twice. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -338,22 +338,22 @@ public function testAggregation() { ->aggregate('field_test_1', 'COUNT') ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 1, 'field_test_1_sum' => 1, 'field_test_1_count' => 1), - array('user_id' => 2, 'field_test_1_sum' => 5, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_sum' => 5, 'field_test_1_count' => 2), - )); + $this->assertResults([ + ['user_id' => 1, 'field_test_1_sum' => 1, 'field_test_1_count' => 1], + ['user_id' => 2, 'field_test_1_sum' => 5, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_sum' => 5, 'field_test_1_count' => 2], + ]); // Group by and aggregate by a fieldapi field. $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('field_test_1') ->aggregate('field_test_2', 'COUNT') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'field_test_2_count' => 2), - array('field_test_1' => 2, 'field_test_2_count' => 3), - array('field_test_1' => 3, 'field_test_2_count' => 1), - )); + $this->assertResults([ + ['field_test_1' => 1, 'field_test_2_count' => 2], + ['field_test_1' => 2, 'field_test_2_count' => 3], + ['field_test_1' => 3, 'field_test_2_count' => 1], + ]); // Group by and aggregate by a fieldapi field and use multiple aggregate // functions. @@ -362,11 +362,11 @@ public function testAggregation() { ->aggregate('field_test_2', 'COUNT') ->aggregate('field_test_2', 'SUM') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'field_test_2_count' => 2, 'field_test_2_sum' => 9), - array('field_test_1' => 2, 'field_test_2_count' => 3, 'field_test_2_sum' => 11), - array('field_test_1' => 3, 'field_test_2_count' => 1, 'field_test_2_sum' => 8), - )); + $this->assertResults([ + ['field_test_1' => 1, 'field_test_2_count' => 2, 'field_test_2_sum' => 9], + ['field_test_1' => 2, 'field_test_2_count' => 3, 'field_test_2_sum' => 11], + ['field_test_1' => 3, 'field_test_2_count' => 1, 'field_test_2_sum' => 8], + ]); // Apply an aggregate condition for a fieldapi field and group by a simple // property. @@ -374,20 +374,20 @@ public function testAggregation() { ->conditionAggregate('field_test_1', 'COUNT', 3) ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 2, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_count' => 2), - )); + $this->assertResults([ + ['user_id' => 2, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_count' => 2], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->aggregate('field_test_1', 'SUM') ->conditionAggregate('field_test_1', 'COUNT', 2, '>') ->groupBy('user_id') ->execute(); - $this->assertResults(array( - array('user_id' => 2, 'field_test_1_sum' => 5, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_sum' => 5, 'field_test_1_count' => 2), - )); + $this->assertResults([ + ['user_id' => 2, 'field_test_1_sum' => 5, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_sum' => 5, 'field_test_1_count' => 2], + ]); // Apply an aggregate condition for a simple property and a group by a // fieldapi field. @@ -395,35 +395,35 @@ public function testAggregation() { ->conditionAggregate('user_id', 'COUNT', 2) ->groupBy('field_test_1') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'user_id_count' => 2), - )); + $this->assertResults([ + ['field_test_1' => 1, 'user_id_count' => 2], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->conditionAggregate('user_id', 'COUNT', 2, '>') ->groupBy('field_test_1') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'user_id_count' => 2), - array('field_test_1' => 2, 'user_id_count' => 3), - )); + $this->assertResults([ + ['field_test_1' => 1, 'user_id_count' => 2], + ['field_test_1' => 2, 'user_id_count' => 3], + ]); // Apply an aggregate condition and a group by fieldapi fields. $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('field_test_1') ->conditionAggregate('field_test_2', 'COUNT', 2) ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'field_test_2_count' => 2), - )); + $this->assertResults([ + ['field_test_1' => 1, 'field_test_2_count' => 2], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('field_test_1') ->conditionAggregate('field_test_2', 'COUNT', 2, '>') ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'field_test_2_count' => 2), - array('field_test_1' => 2, 'field_test_2_count' => 3), - )); + $this->assertResults([ + ['field_test_1' => 1, 'field_test_2_count' => 2], + ['field_test_1' => 2, 'field_test_2_count' => 3], + ]); // Apply an aggregate condition and a group by fieldapi fields with multiple // conditions via AND. @@ -432,7 +432,7 @@ public function testAggregation() { ->conditionAggregate('field_test_2', 'COUNT', 2) ->conditionAggregate('field_test_2', 'SUM', 8) ->execute(); - $this->assertResults(array()); + $this->assertResults([]); // Apply an aggregate condition and a group by fieldapi fields with multiple // conditions via OR. @@ -441,10 +441,10 @@ public function testAggregation() { ->conditionAggregate('field_test_2', 'COUNT', 2) ->conditionAggregate('field_test_2', 'SUM', 8) ->execute(); - $this->assertResults(array( - array('field_test_1' => 1, 'field_test_2_count' => 2, 'field_test_2_sum' => 9), - array('field_test_1' => 3, 'field_test_2_count' => 1, 'field_test_2_sum' => 8), - )); + $this->assertResults([ + ['field_test_1' => 1, 'field_test_2_count' => 2, 'field_test_2_sum' => 9], + ['field_test_1' => 3, 'field_test_2_count' => 1, 'field_test_2_sum' => 8], + ]); // Group by a normal property and aggregate a fieldapi field and sort by the // groupby field. @@ -453,32 +453,32 @@ public function testAggregation() { ->groupBy('user_id') ->sort('user_id', 'DESC') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 3, 'field_test_1_count' => 2), - array('user_id' => 2, 'field_test_1_count' => 3), - array('user_id' => 1, 'field_test_1_count' => 1), - )); + $this->assertSortedResults([ + ['user_id' => 3, 'field_test_1_count' => 2], + ['user_id' => 2, 'field_test_1_count' => 3], + ['user_id' => 1, 'field_test_1_count' => 1], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->aggregate('field_test_1', 'COUNT') ->groupBy('user_id') ->sort('user_id', 'ASC') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 1, 'field_test_1_count' => 1), - array('user_id' => 2, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_count' => 2), - )); + $this->assertSortedResults([ + ['user_id' => 1, 'field_test_1_count' => 1], + ['user_id' => 2, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_count' => 2], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->conditionAggregate('field_test_1', 'COUNT', 2, '>') ->groupBy('user_id') ->sort('user_id', 'ASC') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 2, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_count' => 2), - )); + $this->assertSortedResults([ + ['user_id' => 2, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_count' => 2], + ]); // Group by a normal property, aggregate a fieldapi field, and sort by the // aggregated field. @@ -486,21 +486,21 @@ public function testAggregation() { ->sortAggregate('field_test_1', 'COUNT', 'DESC') ->groupBy('user_id') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 2, 'field_test_1_count' => 3), - array('user_id' => 3, 'field_test_1_count' => 2), - array('user_id' => 1, 'field_test_1_count' => 1), - )); + $this->assertSortedResults([ + ['user_id' => 2, 'field_test_1_count' => 3], + ['user_id' => 3, 'field_test_1_count' => 2], + ['user_id' => 1, 'field_test_1_count' => 1], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->sortAggregate('field_test_1', 'COUNT', 'ASC') ->groupBy('user_id') ->execute(); - $this->assertSortedResults(array( - array('user_id' => 1, 'field_test_1_count' => 1), - array('user_id' => 3, 'field_test_1_count' => 2), - array('user_id' => 2, 'field_test_1_count' => 3), - )); + $this->assertSortedResults([ + ['user_id' => 1, 'field_test_1_count' => 1], + ['user_id' => 3, 'field_test_1_count' => 2], + ['user_id' => 2, 'field_test_1_count' => 3], + ]); // Group by and aggregate by fieldapi field, and sort by the groupby field. $this->queryResult = $this->factory->getAggregate('entity_test') @@ -508,22 +508,22 @@ public function testAggregation() { ->aggregate('field_test_2', 'COUNT') ->sort('field_test_1', 'ASC') ->execute(); - $this->assertSortedResults(array( - array('field_test_1' => 1, 'field_test_2_count' => 2), - array('field_test_1' => 2, 'field_test_2_count' => 3), - array('field_test_1' => 3, 'field_test_2_count' => 1), - )); + $this->assertSortedResults([ + ['field_test_1' => 1, 'field_test_2_count' => 2], + ['field_test_1' => 2, 'field_test_2_count' => 3], + ['field_test_1' => 3, 'field_test_2_count' => 1], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('field_test_1') ->aggregate('field_test_2', 'COUNT') ->sort('field_test_1', 'DESC') ->execute(); - $this->assertSortedResults(array( - array('field_test_1' => 3, 'field_test_2_count' => 1), - array('field_test_1' => 2, 'field_test_2_count' => 3), - array('field_test_1' => 1, 'field_test_2_count' => 2), - )); + $this->assertSortedResults([ + ['field_test_1' => 3, 'field_test_2_count' => 1], + ['field_test_1' => 2, 'field_test_2_count' => 3], + ['field_test_1' => 1, 'field_test_2_count' => 2], + ]); // Groupby and aggregate by fieldapi field, and sort by the aggregated // field. @@ -531,21 +531,21 @@ public function testAggregation() { ->groupBy('field_test_1') ->sortAggregate('field_test_2', 'COUNT', 'DESC') ->execute(); - $this->assertSortedResults(array( - array('field_test_1' => 2, 'field_test_2_count' => 3), - array('field_test_1' => 1, 'field_test_2_count' => 2), - array('field_test_1' => 3, 'field_test_2_count' => 1), - )); + $this->assertSortedResults([ + ['field_test_1' => 2, 'field_test_2_count' => 3], + ['field_test_1' => 1, 'field_test_2_count' => 2], + ['field_test_1' => 3, 'field_test_2_count' => 1], + ]); $this->queryResult = $this->factory->getAggregate('entity_test') ->groupBy('field_test_1') ->sortAggregate('field_test_2', 'COUNT', 'ASC') ->execute(); - $this->assertSortedResults(array( - array('field_test_1' => 3, 'field_test_2_count' => 1), - array('field_test_1' => 1, 'field_test_2_count' => 2), - array('field_test_1' => 2, 'field_test_2_count' => 3), - )); + $this->assertSortedResults([ + ['field_test_1' => 3, 'field_test_2_count' => 1], + ['field_test_1' => 1, 'field_test_2_count' => 2], + ['field_test_1' => 2, 'field_test_2_count' => 3], + ]); } @@ -559,7 +559,7 @@ protected function assertResults($expected, $sorted = FALSE) { $found = TRUE; $expected_keys = array_keys($expected); foreach ($this->queryResult as $key => $row) { - $keys = $sorted ? array($key) : $expected_keys; + $keys = $sorted ? [$key] : $expected_keys; foreach ($keys as $key) { $expected_row = $expected[$key]; if (!array_diff_assoc($row, $expected_row) && !array_diff_assoc($expected_row, $row)) { @@ -569,7 +569,7 @@ protected function assertResults($expected, $sorted = FALSE) { $found = FALSE; break; } - return $this->assertTrue($found, strtr('!expected expected, !found found', array('!expected' => print_r($expected, TRUE), '!found' => print_r($this->queryResult, TRUE)))); + return $this->assertTrue($found, strtr('!expected expected, !found found', ['!expected' => print_r($expected, TRUE), '!found' => print_r($this->queryResult, TRUE)])); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php index 60dc13c6..0bb5b16c 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryRelationshipTest.php @@ -23,7 +23,7 @@ class EntityQueryRelationshipTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * @var \Drupal\Core\Entity\Query\QueryFactory @@ -80,12 +80,12 @@ protected function setUp() { // Second, create the field. entity_test_create_bundle('test_bundle'); $this->fieldName = strtolower($this->randomMachineName()); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $vocabulary->id() => $vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('entity_test', 'test_bundle', $this->fieldName, NULL, 'taxonomy_term', 'default', $handler_settings); // Create two terms and also two accounts. @@ -102,7 +102,7 @@ protected function setUp() { // 0th account and 0th term, the 1st and 2nd entity will point to the // 1st account and 1st term. for ($i = 0; $i <= 2; $i++) { - $entity = EntityTest::create(array('type' => 'test_bundle')); + $entity = EntityTest::create(['type' => 'test_bundle']); $entity->name->value = $this->randomMachineName(); $index = $i ? 1 : 0; $entity->user_id->target_id = $this->accounts[$index]->id(); @@ -122,18 +122,18 @@ public function testQuery() { $this->queryResults = $this->factory->get('entity_test') ->condition("user_id.entity.name", $this->accounts[0]->getUsername()) ->execute(); - $this->assertResults(array(0)); + $this->assertResults([0]); // This returns the 1st and 2nd entity as those point to the 1st account. $this->queryResults = $this->factory->get('entity_test') ->condition("user_id.entity.name", $this->accounts[0]->getUsername(), '<>') ->execute(); - $this->assertResults(array(1, 2)); + $this->assertResults([1, 2]); // This returns all three entities because all of them point to an // account. $this->queryResults = $this->factory->get('entity_test') ->exists("user_id.entity.name") ->execute(); - $this->assertResults(array(0, 1, 2)); + $this->assertResults([0, 1, 2]); // This returns no entities because all of them point to an account. $this->queryResults = $this->factory->get('entity_test') ->notExists("user_id.entity.name") @@ -144,35 +144,35 @@ public function testQuery() { $this->queryResults = $this->factory->get('entity_test') ->condition("$this->fieldName.entity.name", $this->terms[0]->name->value) ->execute(); - $this->assertResults(array(0)); + $this->assertResults([0]); // This returns the 0th entity as that's only one pointing to the 0th // term (test with specifying the column name). $this->queryResults = $this->factory->get('entity_test') ->condition("$this->fieldName.target_id.entity.name", $this->terms[0]->name->value) ->execute(); - $this->assertResults(array(0)); + $this->assertResults([0]); // This returns the 1st and 2nd entity as those point to the 1st term. $this->queryResults = $this->factory->get('entity_test') ->condition("$this->fieldName.entity.name", $this->terms[0]->name->value, '<>') ->execute(); - $this->assertResults(array(1, 2)); + $this->assertResults([1, 2]); // This returns the 0th entity as that's only one pointing to the 0th // account. $this->queryResults = $this->factory->get('entity_test') ->condition("user_id.entity:user.name", $this->accounts[0]->getUsername()) ->execute(); - $this->assertResults(array(0)); + $this->assertResults([0]); // This returns the 1st and 2nd entity as those point to the 1st account. $this->queryResults = $this->factory->get('entity_test') ->condition("user_id.entity:user.name", $this->accounts[0]->getUsername(), '<>') ->execute(); - $this->assertResults(array(1, 2)); + $this->assertResults([1, 2]); // This returns all three entities because all of them point to an // account. $this->queryResults = $this->factory->get('entity_test') ->exists("user_id.entity:user.name") ->execute(); - $this->assertResults(array(0, 1, 2)); + $this->assertResults([0, 1, 2]); // This returns no entities because all of them point to an account. $this->queryResults = $this->factory->get('entity_test') ->notExists("user_id.entity:user.name") @@ -183,18 +183,18 @@ public function testQuery() { $this->queryResults = $this->factory->get('entity_test') ->condition("$this->fieldName.entity:taxonomy_term.name", $this->terms[0]->name->value) ->execute(); - $this->assertResults(array(0)); + $this->assertResults([0]); // This returns the 0th entity as that's only one pointing to the 0th // term (test with specifying the column name). $this->queryResults = $this->factory->get('entity_test') ->condition("$this->fieldName.target_id.entity:taxonomy_term.name", $this->terms[0]->name->value) ->execute(); - $this->assertResults(array(0)); + $this->assertResults([0]); // This returns the 1st and 2nd entity as those point to the 1st term. $this->queryResults = $this->factory->get('entity_test') ->condition("$this->fieldName.entity:taxonomy_term.name", $this->terms[0]->name->value, '<>') ->execute(); - $this->assertResults(array(1, 2)); + $this->assertResults([1, 2]); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php index 8c79c5c6..ebb30728 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php @@ -7,6 +7,7 @@ use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; +use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; @@ -19,12 +20,14 @@ */ class EntityQueryTest extends EntityKernelTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * * @var array */ - public static $modules = array('field_test', 'language'); + public static $modules = ['field_test', 'language']; /** * @var array @@ -62,21 +65,21 @@ protected function setUp() { $this->installEntitySchema('entity_test_mulrev'); - $this->installConfig(array('language')); + $this->installConfig(['language']); $figures = Unicode::strtolower($this->randomMachineName()); $greetings = Unicode::strtolower($this->randomMachineName()); - foreach (array($figures => 'shape', $greetings => 'text') as $field_name => $field_type) { - $field_storage = FieldStorageConfig::create(array( + foreach ([$figures => 'shape', $greetings => 'text'] as $field_name => $field_type) { + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test_mulrev', 'type' => $field_type, 'cardinality' => 2, - )); + ]); $field_storage->save(); $field_storages[] = $field_storage; } - $bundles = array(); + $bundles = []; for ($i = 0; $i < 2; $i++) { // For the sake of tablesort, make sure the second bundle is higher than // the first one. Beware: MySQL is not case sensitive. @@ -93,24 +96,28 @@ protected function setUp() { $bundles[] = $bundle; } // Each unit is a list of field name, langcode and a column-value array. - $units[] = array($figures, 'en', array( - 'color' => 'red', - 'shape' => 'triangle', - )); - $units[] = array($figures, 'en', array( - 'color' => 'blue', - 'shape' => 'circle', - )); + $units[] = [$figures, 'en', [ + 'color' => 'red', + 'shape' => 'triangle', + ], + ]; + $units[] = [$figures, 'en', [ + 'color' => 'blue', + 'shape' => 'circle', + ], + ]; // To make it easier to test sorting, the greetings get formats according // to their langcode. - $units[] = array($greetings, 'tr', array( - 'value' => 'merhaba', - 'format' => 'format-tr' - )); - $units[] = array($greetings, 'pl', array( - 'value' => 'siema', - 'format' => 'format-pl' - )); + $units[] = [$greetings, 'tr', [ + 'value' => 'merhaba', + 'format' => 'format-tr', + ], + ]; + $units[] = [$greetings, 'pl', [ + 'value' => 'siema', + 'format' => 'format-pl', + ], + ]; // Make these languages available to the greetings field. ConfigurableLanguage::createFromLangcode('tr')->save(); ConfigurableLanguage::createFromLangcode('pl')->save(); @@ -119,13 +126,13 @@ protected function setUp() { // decimal 13 is binary 1101 so unit 3,2 and 0 will be added to the // entity. for ($i = 1; $i <= 15; $i++) { - $entity = EntityTestMulRev::create(array( + $entity = EntityTestMulRev::create([ 'type' => $bundles[$i & 1], 'name' => $this->randomMachineName(), 'langcode' => 'en', - )); + ]); // Make sure the name is set for every language that we might create. - foreach (array('tr', 'pl') as $langcode) { + foreach (['tr', 'pl'] as $langcode) { $entity->addTranslation($langcode)->name = $this->randomMachineName(); } foreach (array_reverse(str_split(decbin($i))) as $key => $bit) { @@ -145,7 +152,7 @@ protected function setUp() { /** * Test basic functionality. */ - function testEntityQuery() { + public function testEntityQuery() { $greetings = $this->greetings; $figures = $this->figures; $this->queryResults = $this->factory->get('entity_test_mulrev') @@ -216,8 +223,8 @@ function testEntityQuery() { // Do the same test but with IN operator. $query = $this->factory->get('entity_test_mulrev'); - $group_blue = $query->andConditionGroup()->condition("$figures.color", array('blue'), 'IN'); - $group_red = $query->andConditionGroup()->condition("$figures.color", array('red'), 'IN'); + $group_blue = $query->andConditionGroup()->condition("$figures.color", ['blue'], 'IN'); + $group_red = $query->andConditionGroup()->condition("$figures.color", ['red'], 'IN'); $this->queryResults = $query ->condition($group_blue) ->condition($group_red) @@ -228,7 +235,7 @@ function testEntityQuery() { // An entity might have either red or blue figure. $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("$figures.color", array('blue', 'red'), 'IN') + ->condition("$figures.color", ['blue', 'red'], 'IN') ->sort('id') ->execute(); // Bit 0 or 1 is on. @@ -267,7 +274,7 @@ function testEntityQuery() { ->allRevisions() ->sort('revision_id') ->execute(); - $this->assertRevisionResult(array($first_entity->id()), array($first_entity->id())); + $this->assertRevisionResult([$first_entity->id()], [$first_entity->id()]); // When querying current revisions, this string is no longer found. $this->queryResults = $this->factory->get('entity_test_mulrev') ->condition("$greetings.value", 'merhaba') @@ -279,14 +286,14 @@ function testEntityQuery() { ->sort('revision_id') ->execute(); // The query only matches the original revisions. - $this->assertRevisionResult(array(4, 5, 6, 7, 12, 13, 14, 15), array(4, 5, 6, 7, 12, 13, 14, 15)); + $this->assertRevisionResult([4, 5, 6, 7, 12, 13, 14, 15], [4, 5, 6, 7, 12, 13, 14, 15]); $results = $this->factory->get('entity_test_mulrev') ->condition("$greetings.value", 'siema', 'CONTAINS') ->sort('id') ->execute(); // This matches both the original and new current revisions, multiple // revisions are returned for some entities. - $assert = array(16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'); + $assert = [16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15']; $this->assertIdentical($results, $assert); $results = $this->factory->get('entity_test_mulrev') ->condition("$greetings.value", 'siema', 'STARTS_WITH') @@ -309,8 +316,18 @@ function testEntityQuery() { ->sort('revision_id') ->execute(); // Now we get everything. - $assert = array(4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15'); + $assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15']; $this->assertIdentical($results, $assert); + + // Check that a query on the latest revisions without any condition returns + // the correct results. + $results = $this->factory->get('entity_test_mulrev') + ->latestRevision() + ->sort('id') + ->sort('revision_id') + ->execute(); + $expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15']; + $this->assertSame($expected, $results); } /** @@ -318,7 +335,7 @@ function testEntityQuery() { * * Warning: this is complicated. */ - function testSort() { + public function testSort() { $greetings = $this->greetings; $figures = $this->figures; // Order up and down on a number. @@ -376,9 +393,9 @@ function testSort() { // Test the pager by setting element #1 to page 2 with a page size of 4. // Results will be #8-12 from above. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ 'page' => '0,2', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $this->queryResults = $this->factory->get('entity_test_mulrev') ->sort("$figures.color") @@ -407,40 +424,40 @@ public function testTableSort() { // assert that all entities from one bundle are after the other as the // order dictates. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ 'sort' => 'asc', 'order' => 'Type', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); - $header = array( - 'id' => array('data' => 'Id', 'specifier' => 'id'), - 'type' => array('data' => 'Type', 'specifier' => 'type'), - ); + $header = [ + 'id' => ['data' => 'Id', 'specifier' => 'id'], + 'type' => ['data' => 'Type', 'specifier' => 'type'], + ]; $this->queryResults = array_values($this->factory->get('entity_test_mulrev') ->tableSort($header) ->execute()); $this->assertBundleOrder('asc'); - $request->query->add(array( + $request->query->add([ 'sort' => 'desc', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); - $header = array( - 'id' => array('data' => 'Id', 'specifier' => 'id'), - 'type' => array('data' => 'Type', 'specifier' => 'type'), - ); + $header = [ + 'id' => ['data' => 'Id', 'specifier' => 'id'], + 'type' => ['data' => 'Type', 'specifier' => 'type'], + ]; $this->queryResults = array_values($this->factory->get('entity_test_mulrev') ->tableSort($header) ->execute()); $this->assertBundleOrder('desc'); // Ordering on ID is definite, however. - $request->query->add(array( + $request->query->add([ 'order' => 'Id', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $this->queryResults = $this->factory->get('entity_test_mulrev') ->tableSort($header) @@ -454,13 +471,13 @@ public function testTableSort() { public function testCount() { // Create a field with the same name in a different entity type. $field_name = $this->figures; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'shape', 'cardinality' => 2, 'translatable' => TRUE, - )); + ]); $field_storage->save(); $bundle = $this->randomMachineName(); FieldConfig::create([ @@ -468,10 +485,10 @@ public function testCount() { 'bundle' => $bundle, ])->save(); - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'id' => 1, 'type' => $bundle, - )); + ]); $entity->enforceIsNew(); $entity->save(); @@ -545,8 +562,8 @@ public function testDelta() { // Test the delta range condition. $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("$figures.%delta.color", array('blue', 'red'), 'IN') - ->condition("$figures.%delta", array(0, 1), 'IN') + ->condition("$figures.%delta.color", ['blue', 'red'], 'IN') + ->condition("$figures.%delta", [0, 1], 'IN') ->sort('id') ->execute(); // Figure delta 0 or 1 can be blue or red, this matches a lot of entities. @@ -563,12 +580,12 @@ public function testDelta() { // Numeric delta on single value base field should return results only if // the first item is being targeted. $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("id.0.value", array(1, 3, 5), 'IN') + ->condition("id.0.value", [1, 3, 5], 'IN') ->sort('id') ->execute(); $this->assertResult(1, 3, 5); $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("id.1.value", array(1, 3, 5), 'IN') + ->condition("id.1.value", [1, 3, 5], 'IN') ->sort('id') ->execute(); $this->assertResult(); @@ -576,18 +593,18 @@ public function testDelta() { // Delta range condition on single value base field should return results // only if just the field value is targeted. $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("id.%delta.value", array(1, 3, 5), 'IN') + ->condition("id.%delta.value", [1, 3, 5], 'IN') ->sort('id') ->execute(); $this->assertResult(1, 3, 5); $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("id.%delta.value", array(1, 3, 5), 'IN') + ->condition("id.%delta.value", [1, 3, 5], 'IN') ->condition("id.%delta", 0, '=') ->sort('id') ->execute(); $this->assertResult(1, 3, 5); $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition("id.%delta.value", array(1, 3, 5), 'IN') + ->condition("id.%delta.value", [1, 3, 5], 'IN') ->condition("id.%delta", 1, '=') ->sort('id') ->execute(); @@ -596,7 +613,7 @@ public function testDelta() { } protected function assertResult() { - $assert = array(); + $assert = []; $expected = func_get_args(); if ($expected && is_array($expected[0])) { $expected = $expected[0]; @@ -608,7 +625,7 @@ protected function assertResult() { } protected function assertRevisionResult($keys, $expected) { - $assert = array(); + $assert = []; foreach ($expected as $key => $binary) { $assert[$keys[$key]] = strval($binary); } @@ -659,41 +676,41 @@ public function testMetaData() { public function testCaseSensitivity() { $bundle = $this->randomMachineName(); - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'field_ci', 'entity_type' => 'entity_test_mulrev', 'type' => 'string', 'cardinality' => 1, 'translatable' => FALSE, - 'settings' => array( + 'settings' => [ 'case_sensitive' => FALSE, - ) - )); + ] + ]); $field_storage->save(); - FieldConfig::create(array( + FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => $bundle, - ))->save(); + ])->save(); - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'field_cs', 'entity_type' => 'entity_test_mulrev', 'type' => 'string', 'cardinality' => 1, 'translatable' => FALSE, - 'settings' => array( + 'settings' => [ 'case_sensitive' => TRUE, - ), - )); + ], + ]); $field_storage->save(); - FieldConfig::create(array( + FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => $bundle, - ))->save(); + ])->save(); - $fixtures = array(); + $fixtures = []; for ($i = 0; $i < 2; $i++) { // If the last 4 of the string are all numbers, then there is no @@ -701,20 +718,20 @@ public function testCaseSensitivity() { // test will fail. Ensure that can not happen by appending a non-numeric // character. See https://www.drupal.org/node/2397297. $string = $this->randomMachineName(7) . 'a'; - $fixtures[] = array( + $fixtures[] = [ 'original' => $string, 'uppercase' => Unicode::strtoupper($string), 'lowercase' => Unicode::strtolower($string), - ); + ]; } - EntityTestMulRev::create(array( + EntityTestMulRev::create([ 'type' => $bundle, 'name' => $this->randomMachineName(), 'langcode' => 'en', 'field_ci' => $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 'field_cs' => $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'] - ))->save(); + ])->save(); // Check the case insensitive field, = operator. $result = \Drupal::entityQuery('entity_test_mulrev')->condition( @@ -750,33 +767,33 @@ public function testCaseSensitivity() { // Check the case insensitive field, IN operator. $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', array($fixtures[0]['lowercase'] . $fixtures[1]['lowercase']), 'IN' + 'field_ci', [$fixtures[0]['lowercase'] . $fixtures[1]['lowercase']], 'IN' )->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, lowercase'); $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', array($fixtures[0]['uppercase'] . $fixtures[1]['uppercase']), 'IN' + 'field_ci', [$fixtures[0]['uppercase'] . $fixtures[1]['uppercase']], 'IN' )->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, uppercase'); $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', array($fixtures[0]['uppercase'] . $fixtures[1]['lowercase']), 'IN' + 'field_ci', [$fixtures[0]['uppercase'] . $fixtures[1]['lowercase']], 'IN' )->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, mixed'); // Check the case sensitive field, IN operator. $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', array($fixtures[0]['lowercase'] . $fixtures[1]['lowercase']), 'IN' + 'field_cs', [$fixtures[0]['lowercase'] . $fixtures[1]['lowercase']], 'IN' )->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, lowercase'); $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', array($fixtures[0]['uppercase'] . $fixtures[1]['uppercase']), 'IN' + 'field_cs', [$fixtures[0]['uppercase'] . $fixtures[1]['uppercase']], 'IN' )->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, uppercase'); $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', array($fixtures[0]['uppercase'] . $fixtures[1]['lowercase']), 'IN' + 'field_cs', [$fixtures[0]['uppercase'] . $fixtures[1]['lowercase']], 'IN' )->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, mixed'); @@ -863,19 +880,21 @@ public function testBaseFieldMultipleColumns() { $term1 = Term::create([ 'name' => $this->randomMachineName(), 'vid' => 'tags', - 'description' => array( + 'description' => [ 'value' => $this->randomString(), 'format' => 'format1', - )]); + ], + ]); $term1->save(); $term2 = Term::create([ 'name' => $this->randomMachineName(), 'vid' => 'tags', - 'description' => array( + 'description' => [ 'value' => $this->randomString(), 'format' => 'format2', - )]); + ], + ]); $term2->save(); $ids = \Drupal::entityQuery('taxonomy_term') @@ -887,9 +906,9 @@ public function testBaseFieldMultipleColumns() { } /** - * Test forward-revisions. + * Test pending revisions. */ - public function testForwardRevisions() { + public function testPendingRevisions() { // Ensure entity 14 is returned. $result = \Drupal::entityQuery('entity_test_mulrev') ->condition('id', [14], 'IN') @@ -914,7 +933,7 @@ public function testForwardRevisions() { ->execute(); $this->assertEqual(count($result), 1); - // Verify that field conditions on the default and forward revision are + // Verify that field conditions on the default and pending revision are // work as expected. $result = \Drupal::entityQuery('entity_test_mulrev') ->condition('id', [14], 'IN') @@ -927,6 +946,54 @@ public function testForwardRevisions() { ->allRevisions() ->execute(); $this->assertEqual($result, [16 => '14']); + + // Add another pending revision on the same entity and repeat the checks. + $entity->setNewRevision(TRUE); + $entity->isDefaultRevision(FALSE); + $entity->{$this->figures}->setValue([ + 'color' => 'red', + 'shape' => 'square' + ]); + $entity->save(); + + // A non-revisioned entity query should still return entity 14. + $result = $this->factory->get('entity_test_mulrev') + ->condition('id', [14], 'IN') + ->execute(); + $this->assertCount(1, $result); + $this->assertSame([14 => '14'], $result); + + // Now check an entity query on the latest revision. + $result = $this->factory->get('entity_test_mulrev') + ->condition('id', [14], 'IN') + ->latestRevision() + ->execute(); + $this->assertCount(1, $result); + $this->assertSame([17 => '14'], $result); + + // Verify that field conditions on the default and pending revision still + // work as expected. + $result = $this->factory->get('entity_test_mulrev') + ->condition('id', [14], 'IN') + ->condition("$this->figures.color", $current_values[0]['color']) + ->execute(); + $this->assertSame([14 => '14'], $result); + + // Now there are two revisions with same value for the figure color. + $result = $this->factory->get('entity_test_mulrev') + ->condition('id', [14], 'IN') + ->condition("$this->figures.color", 'red') + ->allRevisions() + ->execute(); + $this->assertSame([16 => '14', 17 => '14'], $result); + + // Check that querying for the latest revision returns the correct one. + $result = $this->factory->get('entity_test_mulrev') + ->condition('id', [14], 'IN') + ->condition("$this->figures.color", 'red') + ->latestRevision() + ->execute(); + $this->assertSame([17 => '14'], $result); } /** @@ -936,7 +1003,7 @@ public function testForwardRevisions() { public function testInjectionInCondition() { try { $this->queryResults = $this->factory->get('entity_test_mulrev') - ->condition('1 ; -- ', array(0, 1), 'IN') + ->condition('1 ; -- ', [0, 1], 'IN') ->sort('id') ->execute(); $this->fail('SQL Injection attempt in Entity Query condition in operator should result in an exception.'); @@ -946,4 +1013,54 @@ public function testInjectionInCondition() { } } + /** + * Tests that EntityQuery works when querying the same entity from two fields. + */ + public function testWithTwoEntityReferenceFieldsToSameEntityType() { + // Create two entity reference fields referring 'entity_test' entities. + $this->createEntityReferenceField('entity_test', 'entity_test', 'ref1', $this->randomMachineName(), 'entity_test'); + $this->createEntityReferenceField('entity_test', 'entity_test', 'ref2', $this->randomMachineName(), 'entity_test'); + + // Create two entities to be referred. + $ref1 = EntityTest::create(['type' => 'entity_test']); + $ref1->save(); + $ref2 = EntityTest::create(['type' => 'entity_test']); + $ref2->save(); + + // Create a main entity referring the previous created entities. + $entity = EntityTest::create([ + 'type' => 'entity_test', + 'ref1' => $ref1->id(), + 'ref2' => $ref2->id(), + ]); + $entity->save(); + + // Check that works when referring with "{$field_name}". + $result = $this->factory->get('entity_test') + ->condition('type', 'entity_test') + ->condition('ref1', $ref1->id()) + ->condition('ref2', $ref2->id()) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + + // Check that works when referring with "{$field_name}.target_id". + $result = $this->factory->get('entity_test') + ->condition('type', 'entity_test') + ->condition('ref1.target_id', $ref1->id()) + ->condition('ref2.target_id', $ref2->id()) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + + // Check that works when referring with "{$field_name}.entity.id". + $result = $this->factory->get('entity_test') + ->condition('type', 'entity_test') + ->condition('ref1.entity.id', $ref1->id()) + ->condition('ref2.entity.id', $ref2->id()) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php index 8f2239db..cedf6851 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceFieldTest.php @@ -2,7 +2,7 @@ namespace Drupal\KernelTests\Core\Entity; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Field\BaseFieldDefinition; @@ -59,7 +59,7 @@ class EntityReferenceFieldTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('entity_reference_test'); + public static $modules = ['entity_reference_test', 'entity_test_update']; /** * {@inheritdoc} @@ -77,7 +77,7 @@ protected function setUp() { 'Field test', $this->referencedEntityType, 'default', - array('target_bundles' => array($this->bundle)), + ['target_bundles' => [$this->bundle]], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ); @@ -90,12 +90,12 @@ public function testEntityReferenceFieldValidation() { // Test a valid reference. $referenced_entity = $this->container->get('entity_type.manager') ->getStorage($this->referencedEntityType) - ->create(array('type' => $this->bundle)); + ->create(['type' => $this->bundle]); $referenced_entity->save(); $entity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('type' => $this->bundle)); + ->create(['type' => $this->bundle]); $entity->{$this->fieldName}->target_id = $referenced_entity->id(); $violations = $entity->{$this->fieldName}->validate(); $this->assertEqual($violations->count(), 0, 'Validation passes.'); @@ -104,16 +104,16 @@ public function testEntityReferenceFieldValidation() { $entity->{$this->fieldName}->target_id = 9999; $violations = $entity->{$this->fieldName}->validate(); $this->assertEqual($violations->count(), 1, 'Validation throws a violation.'); - $this->assertEqual($violations[0]->getMessage(), t('The referenced entity (%type: %id) does not exist.', array('%type' => $this->referencedEntityType, '%id' => 9999))); + $this->assertEqual($violations[0]->getMessage(), t('The referenced entity (%type: %id) does not exist.', ['%type' => $this->referencedEntityType, '%id' => 9999])); // Test a non-referenceable bundle. entity_test_create_bundle('non_referenceable', NULL, $this->referencedEntityType); - $referenced_entity = entity_create($this->referencedEntityType, array('type' => 'non_referenceable')); + $referenced_entity = entity_create($this->referencedEntityType, ['type' => 'non_referenceable']); $referenced_entity->save(); $entity->{$this->fieldName}->target_id = $referenced_entity->id(); $violations = $entity->{$this->fieldName}->validate(); $this->assertEqual($violations->count(), 1, 'Validation throws a violation.'); - $this->assertEqual($violations[0]->getMessage(), t('This entity (%type: %id) cannot be referenced.', array('%type' => $this->referencedEntityType, '%id' => $referenced_entity->id()))); + $this->assertEqual($violations[0]->getMessage(), t('This entity (%type: %id) cannot be referenced.', ['%type' => $this->referencedEntityType, '%id' => $referenced_entity->id()])); } /** @@ -123,15 +123,15 @@ public function testReferencedEntitiesMultipleLoad() { // Create the parent entity. $entity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('type' => $this->bundle)); + ->create(['type' => $this->bundle]); // Create three target entities and attach them to parent field. - $target_entities = array(); - $reference_field = array(); + $target_entities = []; + $reference_field = []; for ($i = 0; $i < 3; $i++) { $target_entity = $this->container->get('entity_type.manager') ->getStorage($this->referencedEntityType) - ->create(array('type' => $this->bundle)); + ->create(['type' => $this->bundle]); $target_entity->save(); $target_entities[] = $target_entity; $reference_field[]['target_id'] = $target_entity->id(); @@ -154,7 +154,7 @@ public function testReferencedEntitiesMultipleLoad() { // "autocreate" feature. $target_entity_unsaved = $this->container->get('entity_type.manager') ->getStorage($this->referencedEntityType) - ->create(array('type' => $this->bundle, 'name' => $this->randomString())); + ->create(['type' => $this->bundle, 'name' => $this->randomString()]); $reference_field[6]['entity'] = $target_entity_unsaved; $target_entities[6] = $target_entity_unsaved; @@ -201,13 +201,13 @@ public function testReferencedEntitiesStringId() { 'Field test', 'entity_test_string_id', 'default', - array('target_bundles' => array($this->bundle)), + ['target_bundles' => [$this->bundle]], FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ); // Create the parent entity. $entity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('type' => $this->bundle)); + ->create(['type' => $this->bundle]); // Create the default target entity. $target_entity = EntityTestStringId::create([ @@ -217,7 +217,7 @@ public function testReferencedEntitiesStringId() { $target_entity->save(); // Set the field value. - $entity->{$field_name}->setValue(array(array('target_id' => $target_entity->id()))); + $entity->{$field_name}->setValue([['target_id' => $target_entity->id()]]); // Load the target entities using EntityReferenceField::referencedEntities(). $entities = $entity->{$field_name}->referencedEntities(); @@ -233,7 +233,7 @@ public function testReferencedEntitiesStringId() { // Test that the default value works. $entity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('type' => $this->bundle)); + ->create(['type' => $this->bundle]); $entities = $entity->{$field_name}->referencedEntities(); $this->assertEqual($entities[0]->id(), $target_entity->id()); } @@ -241,83 +241,83 @@ public function testReferencedEntitiesStringId() { /** * Tests all the possible ways to autocreate an entity via the API. */ - function testAutocreateApi() { + public function testAutocreateApi() { $entity = $this->entityManager ->getStorage($this->entityType) - ->create(array('name' => $this->randomString())); + ->create(['name' => $this->randomString()]); // Test content entity autocreation. - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $entity->set('user_id', $user); }); - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $entity->set('user_id', $user, FALSE); }); - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $entity->user_id->setValue($user); }); - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $entity->user_id[0]->get('entity')->setValue($user); }); - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { - $entity->user_id->setValue(array('entity' => $user, 'target_id' => NULL)); + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { + $entity->user_id->setValue(['entity' => $user, 'target_id' => NULL]); }); try { $message = 'Setting both the entity and an invalid target_id property fails.'; - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $user->save(); - $entity->user_id->setValue(array('entity' => $user, 'target_id' => $this->generateRandomEntityId())); + $entity->user_id->setValue(['entity' => $user, 'target_id' => $this->generateRandomEntityId()]); }); $this->fail($message); } catch (\InvalidArgumentException $e) { $this->pass($message); } - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $entity->user_id = $user; }); - $this->assertUserAutocreate($entity, function(EntityInterface $entity, UserInterface $user) { + $this->assertUserAutocreate($entity, function (EntityInterface $entity, UserInterface $user) { $entity->user_id->entity = $user; }); // Test config entity autocreation. - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $entity->set('user_role', $role); }); - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $entity->set('user_role', $role, FALSE); }); - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $entity->user_role->setValue($role); }); - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $entity->user_role[0]->get('entity')->setValue($role); }); - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { - $entity->user_role->setValue(array('entity' => $role, 'target_id' => NULL)); + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { + $entity->user_role->setValue(['entity' => $role, 'target_id' => NULL]); }); try { $message = 'Setting both the entity and an invalid target_id property fails.'; - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $role->save(); - $entity->user_role->setValue(array('entity' => $role, 'target_id' => $this->generateRandomEntityId(TRUE))); + $entity->user_role->setValue(['entity' => $role, 'target_id' => $this->generateRandomEntityId(TRUE)]); }); $this->fail($message); } catch (\InvalidArgumentException $e) { $this->pass($message); } - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $entity->user_role = $role; }); - $this->assertUserRoleAutocreate($entity, function(EntityInterface $entity, RoleInterface $role) { + $this->assertUserRoleAutocreate($entity, function (EntityInterface $entity, RoleInterface $role) { $entity->user_role->entity = $role; }); // Test target entity saving after setting it as new. $storage = $this->entityManager->getStorage('user'); $user_id = $this->generateRandomEntityId(); - $user = $storage->create(array('uid' => $user_id, 'name' => $this->randomString())); + $user = $storage->create(['uid' => $user_id, 'name' => $this->randomString()]); $entity->user_id = $user; $user->save(); $entity->save(); @@ -338,7 +338,7 @@ function testAutocreateApi() { protected function assertUserAutocreate(EntityInterface $entity, $setter_callback) { $storage = $this->entityManager->getStorage('user'); $user_id = $this->generateRandomEntityId(); - $user = $storage->create(array('uid' => $user_id, 'name' => $this->randomString())); + $user = $storage->create(['uid' => $user_id, 'name' => $this->randomString()]); $setter_callback($entity, $user); $entity->save(); $storage->resetCache(); @@ -360,7 +360,7 @@ protected function assertUserAutocreate(EntityInterface $entity, $setter_callbac protected function assertUserRoleAutocreate(EntityInterface $entity, $setter_callback) { $storage = $this->entityManager->getStorage('user_role'); $role_id = $this->generateRandomEntityId(TRUE); - $role = $storage->create(array('id' => $role_id, 'label' => $this->randomString())); + $role = $storage->create(['id' => $role_id, 'label' => $this->randomString()]); $setter_callback($entity, $role); $entity->save(); $storage->resetCache(); @@ -378,11 +378,11 @@ public function testTargetEntityNoLoad() { $entity_type = clone $this->entityManager->getDefinition('entity_test_update'); $entity_type->setHandlerClass('storage', '\Drupal\entity_test\EntityTestNoLoadStorage'); $this->state->set('entity_test_update.entity_type', $entity_type); - $definitions = array( + $definitions = [ 'target_reference' => BaseFieldDefinition::create('entity_reference') ->setSetting('target_type', $entity_type->id()) ->setSetting('handler', 'default') - ); + ]; $this->state->set('entity_test_update.additional_base_field_definitions', $definitions); $this->entityManager->clearCachedDefinitions(); $this->installEntitySchema($entity_type->id()); @@ -390,7 +390,7 @@ public function testTargetEntityNoLoad() { // Create the target entity. $storage = $this->entityManager->getStorage($entity_type->id()); $target_id = $this->generateRandomEntityId(); - $target = $storage->create(array('id' => $target_id, 'name' => $this->randomString())); + $target = $storage->create(['id' => $target_id, 'name' => $this->randomString()]); $target->save(); $this->assertEqual($target_id, $target->id(), 'The target entity has a random identifier.'); @@ -400,7 +400,7 @@ public function testTargetEntityNoLoad() { try { $entity = $this->entityManager ->getStorage($entity_type->id()) - ->create(array('name' => $this->randomString())); + ->create(['name' => $this->randomString()]); $entity->target_reference = $target_id; $this->pass($message); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php index f51c8ea3..b2c72b99 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityReferenceSelection/EntityReferenceSelectionSortTest.php @@ -21,19 +21,19 @@ class EntityReferenceSelectionSortTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('node'); + public static $modules = ['node']; protected function setUp() { parent::setUp(); // Create an Article node type. - $article = NodeType::create(array( + $article = NodeType::create([ 'type' => 'article', - )); + ]); $article->save(); // Test as a non-admin. - $normal_user = $this->createUser(array(), array('access content')); + $normal_user = $this->createUser([], ['access content']); \Drupal::currentUser()->setAccount($normal_user); } @@ -42,50 +42,50 @@ protected function setUp() { */ public function testSort() { // Add text field to entity, to sort by. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => 'field_text', 'entity_type' => 'node', 'type' => 'text', - 'entity_types' => array('node'), - ))->save(); + 'entity_types' => ['node'], + ])->save(); FieldConfig::create([ 'label' => 'Text Field', 'field_name' => 'field_text', 'entity_type' => 'node', 'bundle' => 'article', - 'settings' => array(), + 'settings' => [], 'required' => FALSE, ])->save(); // Build a set of test data. - $node_values = array( - 'published1' => array( + $node_values = [ + 'published1' => [ 'type' => 'article', 'status' => 1, 'title' => 'Node published1 (<&>)', 'uid' => 1, - 'field_text' => array( - array( + 'field_text' => [ + [ 'value' => 1, - ), - ), - ), - 'published2' => array( + ], + ], + ], + 'published2' => [ 'type' => 'article', 'status' => 1, 'title' => 'Node published2 (<&>)', 'uid' => 1, - 'field_text' => array( - array( + 'field_text' => [ + [ 'value' => 2, - ), - ), - ), - ); + ], + ], + ], + ]; - $nodes = array(); - $node_labels = array(); + $nodes = []; + $node_labels = []; foreach ($node_values as $key => $values) { $node = Node::create($values); $node->save(); @@ -93,40 +93,38 @@ public function testSort() { $node_labels[$key] = Html::escape($node->label()); } - $selection_options = array( + $selection_options = [ 'target_type' => 'node', 'handler' => 'default', - 'handler_settings' => array( - 'target_bundles' => NULL, - // Add sorting. - 'sort' => array( - 'field' => 'field_text.value', - 'direction' => 'DESC', - ), - ), - ); + 'target_bundles' => NULL, + // Add sorting. + 'sort' => [ + 'field' => 'field_text.value', + 'direction' => 'DESC', + ], + ]; $handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options); // Not only assert the result, but make sure the keys are sorted as // expected. $result = $handler->getReferenceableEntities(); - $expected_result = array( + $expected_result = [ $nodes['published2']->id() => $node_labels['published2'], $nodes['published1']->id() => $node_labels['published1'], - ); + ]; $this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values.'); // Assert sort by base field. - $selection_options['handler_settings']['sort'] = array( + $selection_options['sort'] = [ 'field' => 'nid', 'direction' => 'ASC', - ); + ]; $handler = $this->container->get('plugin.manager.entity_reference_selection')->getInstance($selection_options); $result = $handler->getReferenceableEntities(); - $expected_result = array( + $expected_result = [ $nodes['published1']->id() => $node_labels['published1'], $nodes['published2']->id() => $node_labels['published2'], - ); + ]; $this->assertIdentical($result['article'], $expected_result, 'Query sorted by property returned expected values.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityRevisionTranslationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityRevisionTranslationTest.php index 676a98ab..b43b376f 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityRevisionTranslationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityRevisionTranslationTest.php @@ -88,9 +88,9 @@ public function testRevertRevisionAfterTranslation() { } /** - * Tests the translation values when saving a forward revision. + * Tests the translation values when saving a pending revision. */ - public function testTranslationValuesWhenSavingForwardRevisions() { + public function testTranslationValuesWhenSavingPendingRevisions() { $user = $this->createUser(); $storage = $this->entityManager->getStorage('entity_test_mulrev'); @@ -103,33 +103,58 @@ public function testTranslationValuesWhenSavingForwardRevisions() { $entity->addTranslation('de', ['name' => 'default revision - de']); $entity->save(); - // Create a forward revision for the entity and change a field value for + // Create a pending revision for the entity and change a field value for // both languages. - $forward_revision = $this->reloadEntity($entity); + $pending_revision = $this->reloadEntity($entity); - $forward_revision->setNewRevision(); - $forward_revision->isDefaultRevision(FALSE); + $pending_revision->setNewRevision(); + $pending_revision->isDefaultRevision(FALSE); - $forward_revision->name = 'forward revision - en'; - $forward_revision->save(); + $pending_revision->name = 'pending revision - en'; + $pending_revision->save(); - $forward_revision_translation = $forward_revision->getTranslation('de'); - $forward_revision_translation->name = 'forward revision - de'; - $forward_revision_translation->save(); + $pending_revision_translation = $pending_revision->getTranslation('de'); + $pending_revision_translation->name = 'pending revision - de'; + $pending_revision_translation->save(); - $forward_revision_id = $forward_revision->getRevisionId(); - $forward_revision = $storage->loadRevision($forward_revision_id); + $pending_revision_id = $pending_revision->getRevisionId(); + $pending_revision = $storage->loadRevision($pending_revision_id); - // Change the value of the field in the default language, save the forward + // Change the value of the field in the default language, save the pending // revision and check that the value of the field in the second language is - // also taken from the forward revision, *not* from the default revision. - $forward_revision->name = 'updated forward revision - en'; - $forward_revision->save(); + // also taken from the pending revision, *not* from the default revision. + $pending_revision->name = 'updated pending revision - en'; + $pending_revision->save(); - $forward_revision = $storage->loadRevision($forward_revision_id); + $pending_revision = $storage->loadRevision($pending_revision_id); - $this->assertEquals($forward_revision->name->value, 'updated forward revision - en'); - $this->assertEquals($forward_revision->getTranslation('de')->name->value, 'forward revision - de'); + $this->assertEquals($pending_revision->name->value, 'updated pending revision - en'); + $this->assertEquals($pending_revision->getTranslation('de')->name->value, 'pending revision - de'); + } + + /** + * Tests changing the default revision flag is propagated to all translations. + */ + public function testDefaultRevision() { + // Create a test entity with a translation, which will internally trigger + // entity cloning for the new translation and create references for some of + // the entity properties. + $entity = EntityTestMulRev::create([ + 'name' => 'original', + 'language' => 'en', + ]); + $translation = $entity->addTranslation('de'); + $entity->save(); + + // Assert that the entity is in the default revision. + $this->assertTrue($entity->isDefaultRevision()); + $this->assertTrue($translation->isDefaultRevision()); + + // Change the default revision flag on one of the entity translations and + // assert that the change is propagated to all entity translation objects. + $translation->isDefaultRevision(FALSE); + $this->assertFalse($entity->isDefaultRevision()); + $this->assertFalse($translation->isDefaultRevision()); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php index fdf72df4..3e285ff6 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php @@ -23,7 +23,7 @@ class EntitySchemaTest extends EntityKernelTestBase { */ protected function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); + $this->installSchema('user', ['users_data']); $this->database = $this->container->get('database'); } @@ -80,33 +80,33 @@ public function testEntitySchemaUpdate() { $this->entityManager->onFieldStorageDefinitionCreate($storage_definitions['custom_base_field']); $this->entityManager->onFieldStorageDefinitionCreate($storage_definitions['custom_bundle_field']); $schema_handler = $this->database->schema(); - $tables = array('entity_test', 'entity_test_revision', 'entity_test_field_data', 'entity_test_field_revision'); - $dedicated_tables = array('entity_test__custom_bundle_field', 'entity_test_revision__custom_bundle_field'); + $tables = ['entity_test', 'entity_test_revision', 'entity_test_field_data', 'entity_test_field_revision']; + $dedicated_tables = ['entity_test__custom_bundle_field', 'entity_test_revision__custom_bundle_field']; // Initially only the base table and the dedicated field data table should // exist. foreach ($tables as $index => $table) { - $this->assertEqual($schema_handler->tableExists($table), !$index, SafeMarkup::format('Entity schema correct for the @table table.', array('@table' => $table))); + $this->assertEqual($schema_handler->tableExists($table), !$index, SafeMarkup::format('Entity schema correct for the @table table.', ['@table' => $table])); } - $this->assertTrue($schema_handler->tableExists($dedicated_tables[0]), SafeMarkup::format('Field schema correct for the @table table.', array('@table' => $table))); + $this->assertTrue($schema_handler->tableExists($dedicated_tables[0]), SafeMarkup::format('Field schema correct for the @table table.', ['@table' => $table])); // Update the entity type definition and check that the entity schema now // supports translations and revisions. $this->updateEntityType(TRUE); foreach ($tables as $table) { - $this->assertTrue($schema_handler->tableExists($table), SafeMarkup::format('Entity schema correct for the @table table.', array('@table' => $table))); + $this->assertTrue($schema_handler->tableExists($table), SafeMarkup::format('Entity schema correct for the @table table.', ['@table' => $table])); } foreach ($dedicated_tables as $table) { - $this->assertTrue($schema_handler->tableExists($table), SafeMarkup::format('Field schema correct for the @table table.', array('@table' => $table))); + $this->assertTrue($schema_handler->tableExists($table), SafeMarkup::format('Field schema correct for the @table table.', ['@table' => $table])); } // Revert changes and check that the entity schema now does not support // neither translations nor revisions. $this->updateEntityType(FALSE); foreach ($tables as $index => $table) { - $this->assertEqual($schema_handler->tableExists($table), !$index, SafeMarkup::format('Entity schema correct for the @table table.', array('@table' => $table))); + $this->assertEqual($schema_handler->tableExists($table), !$index, SafeMarkup::format('Entity schema correct for the @table table.', ['@table' => $table])); } - $this->assertTrue($schema_handler->tableExists($dedicated_tables[0]), SafeMarkup::format('Field schema correct for the @table table.', array('@table' => $table))); + $this->assertTrue($schema_handler->tableExists($dedicated_tables[0]), SafeMarkup::format('Field schema correct for the @table table.', ['@table' => $table])); } /** @@ -167,7 +167,7 @@ public function testCleanUpStorageDefinition() { $this->assertNotEqual($entity_type_id_count, 0, 'There are storage definitions provided by the entity_test module in the schema.'); // Uninstall the entity_test module. - $this->container->get('module_installer')->uninstall(array('entity_test')); + $this->container->get('module_installer')->uninstall(['entity_test']); // Get a list of all the entities in the schema. $key_value_store = \Drupal::keyValue('entity.storage_schema.sql'); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php index b247662a..bcd702ae 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTranslationTest.php @@ -4,6 +4,7 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Language\LanguageInterface; +use Drupal\Core\TypedData\TranslationStatusInterface; use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; @@ -36,28 +37,28 @@ protected function doTestEntityLanguageMethods($entity_type) { $langcode_key = $this->entityManager->getDefinition($entity_type)->getKey('langcode'); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'name' => 'test', 'user_id' => $this->container->get('current_user')->id(), - )); - $this->assertEqual($entity->language()->getId(), $this->languageManager->getDefaultLanguage()->getId(), format_string('%entity_type: Entity created with API has default language.', array('%entity_type' => $entity_type))); + ]); + $this->assertEqual($entity->language()->getId(), $this->languageManager->getDefaultLanguage()->getId(), format_string('%entity_type: Entity created with API has default language.', ['%entity_type' => $entity_type])); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'name' => 'test', 'user_id' => \Drupal::currentUser()->id(), $langcode_key => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); - $this->assertEqual($entity->language()->getId(), LanguageInterface::LANGCODE_NOT_SPECIFIED, format_string('%entity_type: Entity language not specified.', array('%entity_type' => $entity_type))); - $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->language()->getId(), LanguageInterface::LANGCODE_NOT_SPECIFIED, format_string('%entity_type: Entity language not specified.', ['%entity_type' => $entity_type])); + $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', ['%entity_type' => $entity_type])); // Set the value in default language. - $entity->set($this->fieldName, array(0 => array('value' => 'default value'))); + $entity->set($this->fieldName, [0 => ['value' => 'default value']]); // Get the value. $field = $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT)->get($this->fieldName); - $this->assertEqual($field->value, 'default value', format_string('%entity_type: Untranslated value retrieved.', array('%entity_type' => $entity_type))); - $this->assertEqual($field->getLangcode(), LanguageInterface::LANGCODE_NOT_SPECIFIED, format_string('%entity_type: Field object has the expected langcode.', array('%entity_type' => $entity_type))); + $this->assertEqual($field->value, 'default value', format_string('%entity_type: Untranslated value retrieved.', ['%entity_type' => $entity_type])); + $this->assertEqual($field->getLangcode(), LanguageInterface::LANGCODE_NOT_SPECIFIED, format_string('%entity_type: Field object has the expected langcode.', ['%entity_type' => $entity_type])); // Try to get add a translation to language neutral entity. $message = 'Adding a translation to a language-neutral entity results in an error.'; @@ -73,22 +74,22 @@ protected function doTestEntityLanguageMethods($entity_type) { // translating it. $default_langcode = $this->langcodes[0]; $entity->{$langcode_key}->value = $default_langcode; - $entity->{$this->fieldName} = array(); - $this->assertEqual($entity->language(), \Drupal::languageManager()->getLanguage($this->langcodes[0]), format_string('%entity_type: Entity language retrieved.', array('%entity_type' => $entity_type))); - $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', array('%entity_type' => $entity_type))); + $entity->{$this->fieldName} = []; + $this->assertEqual($entity->language(), \Drupal::languageManager()->getLanguage($this->langcodes[0]), format_string('%entity_type: Entity language retrieved.', ['%entity_type' => $entity_type])); + $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', ['%entity_type' => $entity_type])); // Set the value in default language. - $entity->set($this->fieldName, array(0 => array('value' => 'default value'))); + $entity->set($this->fieldName, [0 => ['value' => 'default value']]); // Get the value. $field = $entity->get($this->fieldName); - $this->assertEqual($field->value, 'default value', format_string('%entity_type: Untranslated value retrieved.', array('%entity_type' => $entity_type))); - $this->assertEqual($field->getLangcode(), $default_langcode, format_string('%entity_type: Field object has the expected langcode.', array('%entity_type' => $entity_type))); + $this->assertEqual($field->value, 'default value', format_string('%entity_type: Untranslated value retrieved.', ['%entity_type' => $entity_type])); + $this->assertEqual($field->getLangcode(), $default_langcode, format_string('%entity_type: Field object has the expected langcode.', ['%entity_type' => $entity_type])); // Set a translation. - $entity->addTranslation($this->langcodes[1])->set($this->fieldName, array(0 => array('value' => 'translation 1'))); + $entity->addTranslation($this->langcodes[1])->set($this->fieldName, [0 => ['value' => 'translation 1']]); $field = $entity->getTranslation($this->langcodes[1])->{$this->fieldName}; - $this->assertEqual($field->value, 'translation 1', format_string('%entity_type: Translated value set.', array('%entity_type' => $entity_type))); - $this->assertEqual($field->getLangcode(), $this->langcodes[1], format_string('%entity_type: Field object has the expected langcode.', array('%entity_type' => $entity_type))); + $this->assertEqual($field->value, 'translation 1', format_string('%entity_type: Translated value set.', ['%entity_type' => $entity_type])); + $this->assertEqual($field->getLangcode(), $this->langcodes[1], format_string('%entity_type: Field object has the expected langcode.', ['%entity_type' => $entity_type])); // Make sure the untranslated value stays. $field = $entity->get($this->fieldName); @@ -109,7 +110,7 @@ protected function doTestEntityLanguageMethods($entity_type) { } // Try to get a not available translation. - $this->assertNull($entity->addTranslation($this->langcodes[2])->get($this->fieldName)->value, format_string('%entity_type: A translation that is not available is NULL.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->addTranslation($this->langcodes[2])->get($this->fieldName)->value, format_string('%entity_type: A translation that is not available is NULL.', ['%entity_type' => $entity_type])); // Try to get a value using an invalid language code. $message = 'Getting an invalid translation results in an error.'; @@ -124,19 +125,19 @@ protected function doTestEntityLanguageMethods($entity_type) { // Try to set a value using an invalid language code. try { $entity->getTranslation('invalid')->set($this->fieldName, NULL); - $this->fail(format_string('%entity_type: Setting a translation for an invalid language throws an exception.', array('%entity_type' => $entity_type))); + $this->fail(format_string('%entity_type: Setting a translation for an invalid language throws an exception.', ['%entity_type' => $entity_type])); } catch (\InvalidArgumentException $e) { - $this->pass(format_string('%entity_type: Setting a translation for an invalid language throws an exception.', array('%entity_type' => $entity_type))); + $this->pass(format_string('%entity_type: Setting a translation for an invalid language throws an exception.', ['%entity_type' => $entity_type])); } // Set the value in default language. $field_name = 'field_test_text'; - $entity->getTranslation($this->langcodes[1])->set($field_name, array(0 => array('value' => 'default value2'))); + $entity->getTranslation($this->langcodes[1])->set($field_name, [0 => ['value' => 'default value2']]); // Get the value. $field = $entity->get($field_name); - $this->assertEqual($field->value, 'default value2', format_string('%entity_type: Untranslated value set into a translation in non-strict mode.', array('%entity_type' => $entity_type))); - $this->assertEqual($field->getLangcode(), $default_langcode, format_string('%entity_type: Field object has the expected langcode.', array('%entity_type' => $entity_type))); + $this->assertEqual($field->value, 'default value2', format_string('%entity_type: Untranslated value set into a translation in non-strict mode.', ['%entity_type' => $entity_type])); + $this->assertEqual($field->getLangcode(), $default_langcode, format_string('%entity_type: Field object has the expected langcode.', ['%entity_type' => $entity_type])); } /** @@ -170,51 +171,51 @@ protected function doTestMultilingualProperties($entity_type) { $entity->save(); $entity = $storage->load($entity->id()); $default_langcode = $entity->language()->getId(); - $this->assertEqual($default_langcode, LanguageInterface::LANGCODE_NOT_SPECIFIED, format_string('%entity_type: Entity created as language neutral.', array('%entity_type' => $entity_type))); + $this->assertEqual($default_langcode, LanguageInterface::LANGCODE_NOT_SPECIFIED, format_string('%entity_type: Entity created as language neutral.', ['%entity_type' => $entity_type])); $field = $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT)->get('name'); - $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name has been correctly stored as language neutral.', array('%entity_type' => $entity_type))); - $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); - $this->assertEqual($uid, $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT)->get('user_id')->target_id, format_string('%entity_type: The entity author has been correctly stored as language neutral.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name has been correctly stored as language neutral.', ['%entity_type' => $entity_type])); + $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', ['%entity_type' => $entity_type])); + $this->assertEqual($uid, $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT)->get('user_id')->target_id, format_string('%entity_type: The entity author has been correctly stored as language neutral.', ['%entity_type' => $entity_type])); $translation = $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT); $field = $translation->get('name'); - $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name defaults to neutral language.', array('%entity_type' => $entity_type))); - $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); - $this->assertEqual($uid, $translation->get('user_id')->target_id, format_string('%entity_type: The entity author defaults to neutral language.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name defaults to neutral language.', ['%entity_type' => $entity_type])); + $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', ['%entity_type' => $entity_type])); + $this->assertEqual($uid, $translation->get('user_id')->target_id, format_string('%entity_type: The entity author defaults to neutral language.', ['%entity_type' => $entity_type])); $field = $entity->get('name'); - $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); - $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); - $this->assertEqual($uid, $entity->get('user_id')->target_id, format_string('%entity_type: The entity author can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name can be retrieved without specifying a language.', ['%entity_type' => $entity_type])); + $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', ['%entity_type' => $entity_type])); + $this->assertEqual($uid, $entity->get('user_id')->target_id, format_string('%entity_type: The entity author can be retrieved without specifying a language.', ['%entity_type' => $entity_type])); // Create a language-aware entity and check that properties are stored // as language-aware. $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array('name' => $name, 'user_id' => $uid, $langcode_key => $langcode)); + ->create(['name' => $name, 'user_id' => $uid, $langcode_key => $langcode]); $entity->save(); $entity = $storage->load($entity->id()); $default_langcode = $entity->language()->getId(); - $this->assertEqual($default_langcode, $langcode, format_string('%entity_type: Entity created as language specific.', array('%entity_type' => $entity_type))); + $this->assertEqual($default_langcode, $langcode, format_string('%entity_type: Entity created as language specific.', ['%entity_type' => $entity_type])); $field = $entity->getTranslation($langcode)->get('name'); - $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name has been correctly stored as a language-aware property.', array('%entity_type' => $entity_type))); - $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); - $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->target_id, format_string('%entity_type: The entity author has been correctly stored as a language-aware property.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name has been correctly stored as a language-aware property.', ['%entity_type' => $entity_type])); + $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', ['%entity_type' => $entity_type])); + $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->target_id, format_string('%entity_type: The entity author has been correctly stored as a language-aware property.', ['%entity_type' => $entity_type])); // Create property translations. - $properties = array(); + $properties = []; $default_langcode = $langcode; foreach ($this->langcodes as $langcode) { if ($langcode != $default_langcode) { - $properties[$langcode] = array( - 'name' => array(0 => $this->randomMachineName()), - 'user_id' => array(0 => mt_rand(128, 256)), - ); + $properties[$langcode] = [ + 'name' => [0 => $this->randomMachineName()], + 'user_id' => [0 => mt_rand(128, 256)], + ]; } else { - $properties[$langcode] = array( - 'name' => array(0 => $name), - 'user_id' => array(0 => $uid), - ); + $properties[$langcode] = [ + 'name' => [0 => $name], + 'user_id' => [0 => $uid], + ]; } $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); foreach ($properties[$langcode] as $field_name => $values) { @@ -226,10 +227,10 @@ protected function doTestMultilingualProperties($entity_type) { // Check that property translation were correctly stored. $entity = $storage->load($entity->id()); foreach ($this->langcodes as $langcode) { - $args = array( + $args = [ '%entity_type' => $entity_type, '%langcode' => $langcode, - ); + ]; $field = $entity->getTranslation($langcode)->get('name'); $this->assertEqual($properties[$langcode]['name'][0], $field->value, format_string('%entity_type: The entity name has been correctly stored for language %langcode.', $args)); $field_langcode = ($langcode == $entity->language()->getId()) ? $default_langcode : $langcode; @@ -253,24 +254,24 @@ protected function doTestMultilingualProperties($entity_type) { ->save(); $entities = $storage->loadMultiple(); - $this->assertEqual(count($entities), 3, format_string('%entity_type: Three entities were created.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 3, format_string('%entity_type: Three entities were created.', ['%entity_type' => $entity_type])); $entities = $storage->loadMultiple([$translated_id]); - $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by id.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by id.', ['%entity_type' => $entity_type])); $entities = $storage->loadByProperties(['name' => $name]); - $this->assertEqual(count($entities), 2, format_string('%entity_type: Two entities correctly loaded by name.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 2, format_string('%entity_type: Two entities correctly loaded by name.', ['%entity_type' => $entity_type])); // @todo The default language condition should go away in favor of an // explicit parameter. $entities = $storage->loadByProperties(['name' => $properties[$langcode]['name'][0], $default_langcode_key => 0]); - $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by name translation.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by name translation.', ['%entity_type' => $entity_type])); $entities = $storage->loadByProperties([$langcode_key => $default_langcode, 'name' => $name]); - $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by name and language.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by name and language.', ['%entity_type' => $entity_type])); $entities = $storage->loadByProperties([$langcode_key => $langcode, 'name' => $properties[$langcode]['name'][0]]); - $this->assertEqual(count($entities), 0, format_string('%entity_type: No entity loaded by name translation specifying the translation language.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 0, format_string('%entity_type: No entity loaded by name translation specifying the translation language.', ['%entity_type' => $entity_type])); $entities = $storage->loadByProperties([$langcode_key => $langcode, 'name' => $properties[$langcode]['name'][0], $default_langcode_key => 0]); - $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity loaded by name translation and language specifying to look for translations.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity loaded by name translation and language specifying to look for translations.', ['%entity_type' => $entity_type])); $entities = $storage->loadByProperties(['user_id' => $properties[$langcode]['user_id'][0], $default_langcode_key => NULL]); - $this->assertEqual(count($entities), 2, format_string('%entity_type: Two entities loaded by uid without caring about property translatability.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entities), 2, format_string('%entity_type: Two entities loaded by uid without caring about property translatability.', ['%entity_type' => $entity_type])); // Test property conditions and orders with multiple languages in the same // query. @@ -282,13 +283,13 @@ protected function doTestMultilingualProperties($entity_type) { ->condition($group) ->condition('name', $properties[$langcode]['name'][0], '=', $langcode) ->execute(); - $this->assertEqual(count($result), 1, format_string('%entity_type: One entity loaded by name and uid using different language meta conditions.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($result), 1, format_string('%entity_type: One entity loaded by name and uid using different language meta conditions.', ['%entity_type' => $entity_type])); // Test mixed property and field conditions. $storage->resetCache($result); $entity = $storage->load(reset($result)); $field_value = $this->randomString(); - $entity->getTranslation($langcode)->set($this->fieldName, array(array('value' => $field_value))); + $entity->getTranslation($langcode)->set($this->fieldName, [['value' => $field_value]]); $entity->save(); $query = \Drupal::entityQuery($entity_type); $default_langcode_group = $query->andConditionGroup() @@ -302,13 +303,13 @@ protected function doTestMultilingualProperties($entity_type) { ->condition($default_langcode_group) ->condition($langcode_group) ->execute(); - $this->assertEqual(count($result), 1, format_string('%entity_type: One entity loaded by name, uid and field value using different language meta conditions.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($result), 1, format_string('%entity_type: One entity loaded by name, uid and field value using different language meta conditions.', ['%entity_type' => $entity_type])); } /** * Tests the Entity Translation API behavior. */ - function testEntityTranslationAPI() { + public function testEntityTranslationAPI() { // Test all entity variations with data table support. foreach (entity_test_entity_types(ENTITY_TEST_TYPES_MULTILINGUAL) as $entity_type) { $this->doTestEntityTranslationAPI($entity_type); @@ -330,7 +331,7 @@ protected function doTestEntityTranslationAPI($entity_type) { /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $this->entityManager ->getStorage($entity_type) - ->create(array('name' => $this->randomMachineName(), $langcode_key => LanguageInterface::LANGCODE_NOT_SPECIFIED)); + ->create(['name' => $this->randomMachineName(), $langcode_key => LanguageInterface::LANGCODE_NOT_SPECIFIED]); $entity->save(); $hooks = $this->getHooksInfo(); @@ -340,12 +341,12 @@ protected function doTestEntityTranslationAPI($entity_type) { // retrieve a translation referring to it. $translation = $entity->getTranslation(LanguageInterface::LANGCODE_NOT_SPECIFIED); $this->assertFalse($translation->isNewTranslation(), 'Existing translations are not marked as new.'); - $this->assertIdentical($entity, $translation, 'The translation object corresponding to a non-default language is the entity object itself when the entity is language-neutral.'); + $this->assertSame($entity, $translation, 'The translation object corresponding to a non-default language is the entity object itself when the entity is language-neutral.'); $entity->{$langcode_key}->value = $default_langcode; $translation = $entity->getTranslation($default_langcode); - $this->assertIdentical($entity, $translation, 'The translation object corresponding to the default language (explicit) is the entity object itself.'); + $this->assertSame($entity, $translation, 'The translation object corresponding to the default language (explicit) is the entity object itself.'); $translation = $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT); - $this->assertIdentical($entity, $translation, 'The translation object corresponding to the default language (implicit) is the entity object itself.'); + $this->assertSame($entity, $translation, 'The translation object corresponding to the default language (implicit) is the entity object itself.'); $this->assertTrue($entity->{$default_langcode_key}->value, 'The translation object is the default one.'); // Verify that trying to retrieve a translation for a locked language when @@ -461,8 +462,8 @@ protected function doTestEntityTranslationAPI($entity_type) { $entity = $this->reloadEntity($entity); $translation = $entity->getTranslation($langcode2); $entity->removeTranslation($langcode2); - foreach (array('get', 'set', '__get', '__set', 'createDuplicate') as $method) { - $message = format_string('The @method method raises an exception when trying to manipulate a removed translation.', array('@method' => $method)); + foreach (['get', 'set', '__get', '__set', 'createDuplicate'] as $method) { + $message = format_string('The @method method raises an exception when trying to manipulate a removed translation.', ['@method' => $method]); try { $translation->{$method}('name', $this->randomMachineName()); $this->fail($message); @@ -483,8 +484,8 @@ protected function doTestEntityTranslationAPI($entity_type) { // Check that removing an invalid translation causes an exception to be // thrown. - foreach (array($default_langcode, LanguageInterface::LANGCODE_DEFAULT, $this->randomMachineName()) as $invalid_langcode) { - $message = format_string('Removing an invalid translation (@langcode) causes an exception to be thrown.', array('@langcode' => $invalid_langcode)); + foreach ([$default_langcode, LanguageInterface::LANGCODE_DEFAULT, $this->randomMachineName()] as $invalid_langcode) { + $message = format_string('Removing an invalid translation (@langcode) causes an exception to be thrown.', ['@langcode' => $invalid_langcode]); try { $entity->removeTranslation($invalid_langcode); $this->fail($message); @@ -565,16 +566,16 @@ protected function doTestEntityTranslationAPI($entity_type) { ->getStorage('entity_test_mul_default_value') ->create(['name' => $this->randomMachineName(), 'langcode' => $langcode]); $translation = $entity->addTranslation($langcode2); - $expected = array( - array( + $expected = [ + [ 'shape' => "shape:0:description_$langcode2", 'color' => "color:0:description_$langcode2", - ), - array( + ], + [ 'shape' => "shape:1:description_$langcode2", 'color' => "color:1:description_$langcode2", - ), - ); + ], + ]; $this->assertEqual($translation->description->getValue(), $expected, 'Language-aware default values correctly populated.'); $this->assertEqual($translation->description->getLangcode(), $langcode2, 'Field object has the expected langcode.'); @@ -585,7 +586,7 @@ protected function doTestEntityTranslationAPI($entity_type) { /** * Tests language fallback applied to field and entity translations. */ - function testLanguageFallback() { + public function testLanguageFallback() { // Test all entity variations with data table support. foreach (entity_test_entity_types(ENTITY_TEST_TYPES_MULTILINGUAL) as $entity_type) { $this->doTestLanguageFallback($entity_type); @@ -605,7 +606,7 @@ protected function doTestLanguageFallback($entity_type) { $current_langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); $this->langcodes[] = $current_langcode; - $values = array(); + $values = []; foreach ($this->langcodes as $langcode) { $values[$langcode]['name'] = $this->randomMachineName(); $values[$langcode]['user_id'] = mt_rand(0, 127); @@ -622,7 +623,7 @@ protected function doTestLanguageFallback($entity_type) { $this->languageManager->reset(); $controller = $this->entityManager->getStorage($entity_type); - $entity = $controller->create(array($langcode_key => $default_langcode) + $values[$default_langcode]); + $entity = $controller->create([$langcode_key => $default_langcode] + $values[$default_langcode]); $entity->save(); $entity->addTranslation($langcode, $values[$langcode]); @@ -648,7 +649,7 @@ protected function doTestLanguageFallback($entity_type) { $this->assertEqual($current_langcode, $translation->language()->getId(), 'The current translation language matches the current language.'); // Check that if the entity has no translation no fallback is applied. - $entity2 = $controller->create(array($langcode_key => $default_langcode)); + $entity2 = $controller->create([$langcode_key => $default_langcode]); // Get an view builder. $controller = $this->entityManager->getViewBuilder($entity_type); $entity2_build = $controller->view($entity2); @@ -656,7 +657,7 @@ protected function doTestLanguageFallback($entity_type) { $translation = $this->entityManager->getTranslationFromContext($entity2, $default_langcode); $translation_build = $controller->view($translation); $translation_output = (string) $renderer->renderRoot($translation_build); - $this->assertIdentical($entity2_output, $translation_output, 'When the entity has no translation no fallback is applied.'); + $this->assertSame($entity2_output, $translation_output, 'When the entity has no translation no fallback is applied.'); // Checks that entity translations are rendered properly. $controller = $this->entityManager->getViewBuilder($entity_type); @@ -681,16 +682,16 @@ protected function doTestLanguageFallback($entity_type) { /** * Check that field translatability is handled properly. */ - function testFieldDefinitions() { + public function testFieldDefinitions() { // Check that field translatability can be altered to be enabled or disabled // in field definitions. $entity_type = 'entity_test_mulrev'; - $this->state->set('entity_test.field_definitions.translatable', array('name' => FALSE)); + $this->state->set('entity_test.field_definitions.translatable', ['name' => FALSE]); $this->entityManager->clearCachedFieldDefinitions(); $definitions = $this->entityManager->getBaseFieldDefinitions($entity_type); $this->assertFalse($definitions['name']->isTranslatable(), 'Field translatability can be disabled programmatically.'); - $this->state->set('entity_test.field_definitions.translatable', array('name' => TRUE)); + $this->state->set('entity_test.field_definitions.translatable', ['name' => TRUE]); $this->entityManager->clearCachedFieldDefinitions(); $definitions = $this->entityManager->getBaseFieldDefinitions($entity_type); $this->assertTrue($definitions['name']->isTranslatable(), 'Field translatability can be enabled programmatically.'); @@ -701,17 +702,17 @@ function testFieldDefinitions() { $this->assertFalse($definitions['id']->isTranslatable(), 'Field translatability is disabled by default.'); // Check that entity id keys have the expect translatability. - $translatable_fields = array( + $translatable_fields = [ 'id' => TRUE, 'uuid' => TRUE, 'revision_id' => TRUE, 'type' => TRUE, 'langcode' => FALSE, - ); + ]; foreach ($translatable_fields as $name => $translatable) { - $this->state->set('entity_test.field_definitions.translatable', array($name => $translatable)); + $this->state->set('entity_test.field_definitions.translatable', [$name => $translatable]); $this->entityManager->clearCachedFieldDefinitions(); - $message = format_string('Field %field cannot be translatable.', array('%field' => $name)); + $message = format_string('Field %field cannot be translatable.', ['%field' => $name]); try { $this->entityManager->getBaseFieldDefinitions($entity_type); @@ -746,13 +747,13 @@ protected function doTestLanguageChange($entity_type) { // check that field languages match entity language regardless of field // translatability. - $values = array( + $values = [ $langcode_key => $langcode, $this->fieldName => $this->randomMachineName(), $this->untranslatableFieldName => $this->randomMachineName(), - ); + ]; $entity = $controller->create($values); - foreach (array($this->fieldName, $this->untranslatableFieldName) as $field_name) { + foreach ([$this->fieldName, $this->untranslatableFieldName] as $field_name) { $this->assertEqual($entity->get($field_name)->getLangcode(), $langcode, 'Field language works as expected.'); } @@ -760,16 +761,16 @@ protected function doTestLanguageChange($entity_type) { // changing it. $langcode = $this->langcodes[1]; $entity->{$langcode_key}->value = $langcode; - foreach (array($this->fieldName, $this->untranslatableFieldName) as $field_name) { + foreach ([$this->fieldName, $this->untranslatableFieldName] as $field_name) { $this->assertEqual($entity->get($field_name)->getLangcode(), $langcode, 'Field language works as expected after changing entity language.'); } // Check that entity translation does not affect the language of original // field values and untranslatable ones. $langcode = $this->langcodes[0]; - $entity->addTranslation($this->langcodes[2], array($this->fieldName => $this->randomMachineName())); + $entity->addTranslation($this->langcodes[2], [$this->fieldName => $this->randomMachineName()]); $entity->{$langcode_key}->value = $langcode; - foreach (array($this->fieldName, $this->untranslatableFieldName) as $field_name) { + foreach ([$this->fieldName, $this->untranslatableFieldName] as $field_name) { $this->assertEqual($entity->get($field_name)->getLangcode(), $langcode, 'Field language works as expected after translating the entity and changing language.'); } @@ -788,24 +789,24 @@ protected function doTestLanguageChange($entity_type) { /** * Tests how entity adapters work with translations. */ - function testEntityAdapter() { + public function testEntityAdapter() { $entity_type = 'entity_test'; $default_langcode = 'en'; - $values[$default_langcode] = array('name' => $this->randomString()); + $values[$default_langcode] = ['name' => $this->randomString()]; $controller = $this->entityManager->getStorage($entity_type); /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $controller->create($values[$default_langcode]); foreach ($this->langcodes as $langcode) { - $values[$langcode] = array('name' => $this->randomString()); + $values[$langcode] = ['name' => $this->randomString()]; $entity->addTranslation($langcode, $values[$langcode]); } - $langcodes = array_merge(array($default_langcode), $this->langcodes); + $langcodes = array_merge([$default_langcode], $this->langcodes); foreach ($langcodes as $langcode) { $adapter = $entity->getTranslation($langcode)->getTypedData(); $name = $adapter->get('name')->value; - $this->assertEqual($name, $values[$langcode]['name'], SafeMarkup::format('Name correctly retrieved from "@langcode" adapter', array('@langcode' => $langcode))); + $this->assertEqual($name, $values[$langcode]['name'], SafeMarkup::format('Name correctly retrieved from "@langcode" adapter', ['@langcode' => $langcode])); } } @@ -878,11 +879,11 @@ public function testDeleteEntityTranslation() { $field->save(); // Create an entity with both translatable and untranslatable test fields. - $values = array( + $values = [ 'name' => $this->randomString(), 'translatable_test_field' => $this->randomString(), 'untranslatable_test_field' => $this->randomString(), - ); + ]; /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $controller->create($values); @@ -931,4 +932,85 @@ public function testDeleteEntityTranslation() { $this->assertEqual($actual, $expected_untranslatable); } + /** + * Tests the getTranslationStatus method. + */ + public function testTranslationStatus() { + $entity_type = 'entity_test_mul'; + $storage = $this->entityManager->getStorage($entity_type); + + // Create an entity with both translatable and untranslatable test fields. + $values = [ + 'name' => $this->randomString(), + 'translatable_test_field' => $this->randomString(), + 'untranslatable_test_field' => $this->randomString(), + ]; + + /** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\Core\TypedData\TranslationStatusInterface $entity */ + // Test that newly created entity has the translation status + // TRANSLATION_CREATED. + $entity = $storage->create($values); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_CREATED, $entity->getTranslationStatus($entity->language()->getId())); + + // Test that after saving a newly created entity it has the translation + // status TRANSLATION_EXISTING. + $entity->save(); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($entity->language()->getId())); + + // Test that after loading an existing entity it has the translation status + // TRANSLATION_EXISTING. + $storage->resetCache(); + $entity = $storage->load($entity->id()); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($entity->language()->getId())); + + foreach ($this->langcodes as $key => $langcode) { + // Test that after adding a new translation it has the translation status + // TRANSLATION_CREATED. + $entity->addTranslation($langcode, $values); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_CREATED, $entity->getTranslationStatus($langcode)); + + // Test that after removing a newly added and not yet saved translation + // it does not have any translation status for the removed translation. + $entity->removeTranslation($langcode); + $this->assertEquals(NULL, $entity->getTranslationStatus($langcode)); + + // Test that after adding a new translation and saving the entity it has + // the translation status TRANSLATION_EXISTING. + $entity->addTranslation($langcode, $values) + ->save(); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($langcode)); + + // Test that after removing an existing translation its translation + // status has changed to TRANSLATION_REMOVED. + $entity->removeTranslation($langcode); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_REMOVED, $entity->getTranslationStatus($langcode)); + + // Test that after removing an existing translation and adding it again + // its translation status has changed back to TRANSLATION_EXISTING. + $entity->addTranslation($langcode, $values); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($langcode)); + + // Test that after removing an existing translation and saving the entity + // it does not have any translation status for the removed translation. + $entity->removeTranslation($langcode); + $entity->save(); + $this->assertEquals(NULL, $entity->getTranslationStatus($langcode)); + + // Tests that after removing an existing translation, saving the entity, + // adding the translation again, the translation status of this + // translation is TRANSLATION_CREATED. + $entity->addTranslation($langcode, $values); + $this->assertEquals(TranslationStatusInterface::TRANSLATION_CREATED, $entity->getTranslationStatus($langcode)); + $entity->save(); + } + + // Test that after loading an existing entity it has the translation status + // TRANSLATION_EXISTING for all of its translations. + $storage->resetCache(); + $entity = $storage->load($entity->id()); + foreach (array_keys($entity->getTranslationLanguages()) as $langcode) { + $this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($langcode)); + } + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintValidatorTest.php index 87d76b48..3671d6d4 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintValidatorTest.php @@ -18,7 +18,7 @@ class EntityTypeConstraintValidatorTest extends EntityKernelTestBase { */ protected $typedData; - public static $modules = array('node', 'field', 'user'); + public static $modules = ['node', 'field', 'user']; protected function setUp() { parent::setUp(); @@ -32,13 +32,13 @@ public function testValidation() { // Create a typed data definition with an EntityType constraint. $entity_type = 'node'; $definition = DataDefinition::create('entity_reference') - ->setConstraints(array( + ->setConstraints([ 'EntityType' => $entity_type, - ) + ] ); // Test the validation. - $node = $this->container->get('entity.manager')->getStorage('node')->create(array('type' => 'page')); + $node = $this->container->get('entity.manager')->getStorage('node')->create(['type' => 'page']); $typed_data = $this->typedData->create($definition, $node); $violations = $typed_data->validate(); $this->assertEqual($violations->count(), 0, 'Validation passed for correct value.'); @@ -53,7 +53,7 @@ public function testValidation() { // Make sure the information provided by a violation is correct. $violation = $violations[0]; - $this->assertEqual($violation->getMessage(), t('The entity must be of type %type.', array('%type' => $entity_type)), 'The message for invalid value is correct.'); + $this->assertEqual($violation->getMessage(), t('The entity must be of type %type.', ['%type' => $entity_type]), 'The message for invalid value is correct.'); $this->assertEqual($violation->getRoot(), $typed_data, 'Violation root is correct.'); $this->assertEqual($violation->getInvalidValue(), $account, 'The invalid value is set correctly in the violation.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintsTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintsTest.php index 51286be3..a58b47c1 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintsTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeConstraintsTest.php @@ -41,7 +41,7 @@ public function testConstraintDefinition() { $this->assertEqual($default_constraints + $extra_constraints, $entity_type->getConstraints()); // Test altering constraints. - $altered_constraints = ['Test' => [ 'some_setting' => TRUE]]; + $altered_constraints = ['Test' => ['some_setting' => TRUE]]; $this->state->set('entity_test_constraints.alter', $altered_constraints); // Clear the cache in state instance in the Drupal container, so it can pick // up the modified value. diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php index b61a6dd4..5e755d95 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php @@ -31,7 +31,7 @@ class EntityTypedDataDefinitionTest extends KernelTestBase { * * @var array */ - public static $modules = array('filter', 'text', 'node', 'user'); + public static $modules = ['filter', 'text', 'node', 'user']; protected function setUp() { parent::setup(); @@ -51,14 +51,14 @@ public function testFields() { $this->assertTrue($field_item_definition instanceof ComplexDataDefinitionInterface); // Derive metadata about field item properties. - $this->assertEqual(array_keys($field_item_definition->getPropertyDefinitions()), array('value')); + $this->assertEqual(array_keys($field_item_definition->getPropertyDefinitions()), ['value']); $this->assertEqual($field_item_definition->getPropertyDefinition('value')->getDataType(), 'integer'); $this->assertEqual($field_item_definition->getMainPropertyName(), 'value'); $this->assertNull($field_item_definition->getPropertyDefinition('invalid')); // Test accessing field item property metadata via the field definition. $this->assertTrue($field_definition instanceof FieldDefinitionInterface); - $this->assertEqual(array_keys($field_definition->getPropertyDefinitions()), array('value')); + $this->assertEqual(array_keys($field_definition->getPropertyDefinitions()), ['value']); $this->assertEqual($field_definition->getPropertyDefinition('value')->getDataType(), 'integer'); $this->assertEqual($field_definition->getMainPropertyName(), 'value'); $this->assertNull($field_definition->getPropertyDefinition('invalid')); @@ -101,12 +101,12 @@ public function testEntities() { // Test that the definition factory creates the right definitions for all // entity data types variants. - $this->assertEqual($this->typedDataManager->createDataDefinition('entity'), EntityDataDefinition::create()); - $this->assertEqual($this->typedDataManager->createDataDefinition('entity:node'), EntityDataDefinition::create('node')); + $this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity')), serialize(EntityDataDefinition::create())); + $this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity:node')), serialize(EntityDataDefinition::create('node'))); // Config entities don't support typed data. $entity_definition = EntityDataDefinition::create('node_type'); - $this->assertEqual(array(), $entity_definition->getPropertyDefinitions()); + $this->assertEqual([], $entity_definition->getPropertyDefinitions()); } /** @@ -123,7 +123,7 @@ public function testEntityReferences() { // Test that the definition factory creates the right definition object. $reference_definition2 = $this->typedDataManager->createDataDefinition('entity_reference'); $this->assertTrue($reference_definition2 instanceof DataReferenceDefinitionInterface); - $this->assertEqual($reference_definition2, $reference_definition); + $this->assertEqual(serialize($reference_definition2), serialize($reference_definition)); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php index ae26ec59..a3466a49 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityUUIDTest.php @@ -23,7 +23,7 @@ protected function setUp() { /** * Tests UUID generation in entity CRUD operations. */ - function testCRUD() { + public function testCRUD() { // All entity variations have to have the same results. foreach (entity_test_entity_types() as $entity_type) { $this->assertCRUD($entity_type); @@ -42,10 +42,10 @@ protected function assertCRUD($entity_type) { $uuid = $uuid_service->generate(); $custom_entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'name' => $this->randomMachineName(), 'uuid' => $uuid, - )); + ]); $this->assertIdentical($custom_entity->uuid(), $uuid); // Save this entity, so we have more than one later. $custom_entity->save(); @@ -53,7 +53,7 @@ protected function assertCRUD($entity_type) { // Verify that a new UUID is generated upon creating an entity. $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array('name' => $this->randomMachineName())); + ->create(['name' => $this->randomMachineName()]); $uuid = $entity->uuid(); $this->assertTrue($uuid); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php index dc7d94f0..bf2a147e 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php @@ -16,7 +16,7 @@ class EntityValidationTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('filter', 'text'); + public static $modules = ['filter', 'text']; /** * @var string @@ -44,7 +44,7 @@ protected function setUp() { entity_test_install(); // Install required default configuration for filter module. - $this->installConfig(array('system', 'filter')); + $this->installConfig(['system', 'filter']); } /** @@ -123,13 +123,13 @@ protected function checkValidation($entity_type) { $test_entity->id->value = -1; $violations = $test_entity->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('%name: The integer must be larger or equal to %min.', array('%name' => 'ID', '%min' => 0))); + $this->assertEqual($violations[0]->getMessage(), t('%name: The integer must be larger or equal to %min.', ['%name' => 'ID', '%min' => 0])); $test_entity = clone $entity; $test_entity->uuid->value = $this->randomString(129); $violations = $test_entity->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => 'UUID', '@max' => 128))); + $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', ['%name' => 'UUID', '@max' => 128])); $test_entity = clone $entity; $langcode_key = $this->entityManager->getDefinition($entity_type)->getKey('langcode'); @@ -137,7 +137,7 @@ protected function checkValidation($entity_type) { $violations = $test_entity->validate(); // This should fail on AllowedValues and Length constraints. $this->assertEqual($violations->count(), 2, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => '12'))); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', ['%limit' => '12'])); $this->assertEqual($violations[1]->getMessage(), t('The value you selected is not a valid choice.')); $test_entity = clone $entity; @@ -150,7 +150,7 @@ protected function checkValidation($entity_type) { $test_entity->name->value = $this->randomString(33); $violations = $test_entity->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => 'Name', '@max' => 32))); + $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', ['%name' => 'Name', '@max' => 32])); // Make sure the information provided by a violation is correct. $violation = $violations[0]; @@ -162,7 +162,7 @@ protected function checkValidation($entity_type) { $test_entity->set('user_id', 9999); $violations = $test_entity->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('The referenced entity (%type: %id) does not exist.', array('%type' => 'user', '%id' => 9999))); + $this->assertEqual($violations[0]->getMessage(), t('The referenced entity (%type: %id) does not exist.', ['%type' => 'user', '%id' => 9999])); $test_entity = clone $entity; $test_entity->field_test_text->format = $this->randomString(33); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityViewBuilderTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityViewBuilderTest.php index 0143128f..e1537bc8 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityViewBuilderTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityViewBuilderTest.php @@ -23,7 +23,7 @@ class EntityViewBuilderTest extends EntityKernelTestBase { */ protected function setUp() { parent::setUp(); - $this->installConfig(array('user', 'entity_test')); + $this->installConfig(['user', 'entity_test']); // Give anonymous users permission to view test entities. Role::load(RoleInterface::ANONYMOUS_ID) @@ -182,7 +182,7 @@ public function testEntityViewBuilderWeight() { // Set a weight for the label component. entity_get_display('entity_test', 'entity_test', 'full') - ->setComponent('label', array('weight' => 20)) + ->setComponent('label', ['weight' => 20]) ->save(); // Create and build a test entity. @@ -204,10 +204,10 @@ public function testEntityViewBuilderWeight() { * The created entity. */ protected function createTestEntity($entity_type) { - $data = array( + $data = [ 'bundle' => $entity_type, 'name' => $this->randomMachineName(), - ); + ]; return $this->container->get('entity.manager')->getStorage($entity_type)->create($data); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php index 449f3f23..7ff6caf2 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php @@ -23,7 +23,7 @@ class FieldSqlStorageTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('field', 'field_test', 'text', 'entity_test'); + public static $modules = ['field', 'field_test', 'text', 'entity_test']; /** * The name of the created field. @@ -68,7 +68,7 @@ class FieldSqlStorageTest extends EntityKernelTestBase { /** * The table mapping for the tested entity type. * - * @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping + * @var \Drupal\Core\Entity\Sql\DefaultTableMapping */ protected $tableMapping; @@ -80,12 +80,12 @@ protected function setUp() { $this->fieldName = strtolower($this->randomMachineName()); $this->fieldCardinality = 4; - $this->fieldStorage = FieldStorageConfig::create(array( + $this->fieldStorage = FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => $entity_type, 'type' => 'test_field', 'cardinality' => $this->fieldCardinality, - )); + ]); $this->fieldStorage->save(); $this->field = FieldConfig::create([ 'field_storage' => $this->fieldStorage, @@ -103,14 +103,14 @@ protected function setUp() { /** * Tests field loading works correctly by inserting directly in the tables. */ - function testFieldLoad() { + public function testFieldLoad() { $entity_type = $bundle = 'entity_test_rev'; $storage = $this->container->get('entity.manager')->getStorage($entity_type); - $columns = array('bundle', 'deleted', 'entity_id', 'revision_id', 'delta', 'langcode', $this->tableMapping->getFieldColumnName($this->fieldStorage, 'value')); + $columns = ['bundle', 'deleted', 'entity_id', 'revision_id', 'delta', 'langcode', $this->tableMapping->getFieldColumnName($this->fieldStorage, 'value')]; // Create an entity with four revisions. - $revision_ids = array(); + $revision_ids = []; $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) ->create(); @@ -123,20 +123,20 @@ function testFieldLoad() { } // Generate values and insert them directly in the storage tables. - $values = array(); + $values = []; $query = db_insert($this->revisionTable)->fields($columns); foreach ($revision_ids as $revision_id) { // Put one value too many. for ($delta = 0; $delta <= $this->fieldCardinality; $delta++) { $value = mt_rand(1, 127); $values[$revision_id][] = $value; - $query->values(array($bundle, 0, $entity->id(), $revision_id, $delta, $entity->language()->getId(), $value)); + $query->values([$bundle, 0, $entity->id(), $revision_id, $delta, $entity->language()->getId(), $value]); } $query->execute(); } $query = db_insert($this->table)->fields($columns); foreach ($values[$revision_id] as $delta => $value) { - $query->values(array($bundle, 0, $entity->id(), $revision_id, $delta, $entity->language()->getId(), $value)); + $query->values([$bundle, 0, $entity->id(), $revision_id, $delta, $entity->language()->getId(), $value]); } $query->execute(); @@ -167,7 +167,7 @@ function testFieldLoad() { // Add a translation in an unavailable language code and verify it is not // loaded. $unavailable_langcode = 'xx'; - $values = array($bundle, 0, $entity->id(), $entity->getRevisionId(), 0, $unavailable_langcode, mt_rand(1, 127)); + $values = [$bundle, 0, $entity->id(), $entity->getRevisionId(), 0, $unavailable_langcode, mt_rand(1, 127)]; db_insert($this->table)->fields($columns)->values($values)->execute(); db_insert($this->revisionTable)->fields($columns)->values($values)->execute(); $entity = $storage->load($entity->id()); @@ -177,16 +177,16 @@ function testFieldLoad() { /** * Tests field saving works correctly by reading directly from the tables. */ - function testFieldWrite() { + public function testFieldWrite() { $entity_type = $bundle = 'entity_test_rev'; $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) ->create(); - $revision_values = array(); + $revision_values = []; // Check insert. Add one value too many. - $values = array(); + $values = []; for ($delta = 0; $delta <= $this->fieldCardinality; $delta++) { $values[$delta]['value'] = mt_rand(1, 127); } @@ -197,7 +197,7 @@ function testFieldWrite() { $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', \PDO::FETCH_ASSOC); $this->assertEqual(count($rows), $this->fieldCardinality); foreach ($rows as $delta => $row) { - $expected = array( + $expected = [ 'bundle' => $bundle, 'deleted' => 0, 'entity_id' => $entity->id(), @@ -205,13 +205,13 @@ function testFieldWrite() { 'langcode' => $entity->language()->getId(), 'delta' => $delta, $this->fieldName . '_value' => $values[$delta]['value'], - ); + ]; $this->assertEqual($row, $expected, "Row $delta was stored as expected."); } // Test update. Add less values and check that the previous values did not // persist. - $values = array(); + $values = []; for ($delta = 0; $delta <= $this->fieldCardinality - 2; $delta++) { $values[$delta]['value'] = mt_rand(1, 127); } @@ -220,7 +220,7 @@ function testFieldWrite() { $rows = db_select($this->table, 't')->fields('t')->execute()->fetchAllAssoc('delta', \PDO::FETCH_ASSOC); $this->assertEqual(count($rows), count($values)); foreach ($rows as $delta => $row) { - $expected = array( + $expected = [ 'bundle' => $bundle, 'deleted' => 0, 'entity_id' => $entity->id(), @@ -228,13 +228,13 @@ function testFieldWrite() { 'langcode' => $entity->language()->getId(), 'delta' => $delta, $this->fieldName . '_value' => $values[$delta]['value'], - ); + ]; $this->assertEqual($row, $expected, "Row $delta was stored as expected."); } // Create a new revision. $revision_values[$entity->getRevisionId()] = $values; - $values = array(); + $values = []; for ($delta = 0; $delta < $this->fieldCardinality; $delta++) { $values[$delta]['value'] = mt_rand(1, 127); } @@ -248,7 +248,7 @@ function testFieldWrite() { $rows = db_select($this->revisionTable, 't')->fields('t')->condition('revision_id', $revision_id)->execute()->fetchAllAssoc('delta', \PDO::FETCH_ASSOC); $this->assertEqual(count($rows), min(count($values), $this->fieldCardinality)); foreach ($rows as $delta => $row) { - $expected = array( + $expected = [ 'bundle' => $bundle, 'deleted' => 0, 'entity_id' => $entity->id(), @@ -256,7 +256,7 @@ function testFieldWrite() { 'langcode' => $entity->language()->getId(), 'delta' => $delta, $this->fieldName . '_value' => $values[$delta]['value'], - ); + ]; $this->assertEqual($row, $expected, "Row $delta was stored as expected."); } } @@ -271,7 +271,7 @@ function testFieldWrite() { /** * Tests that long entity type and field names do not break. */ - function testLongNames() { + public function testLongNames() { // Use one of the longest entity_type names in core. $entity_type = $bundle = 'entity_test_label_callback'; $this->installEntitySchema('entity_test_label_callback'); @@ -279,15 +279,15 @@ function testLongNames() { // Create two fields and generate random values. $name_base = Unicode::strtolower($this->randomMachineName(FieldStorageConfig::NAME_MAX_LENGTH - 1)); - $field_names = array(); - $values = array(); + $field_names = []; + $values = []; for ($i = 0; $i < 2; $i++) { $field_names[$i] = $name_base . $i; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $field_names[$i], 'entity_type' => $entity_type, 'type' => 'test_field', - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $field_names[$i], 'entity_type' => $entity_type, @@ -312,15 +312,15 @@ function testLongNames() { /** * Test trying to update a field with data. */ - function testUpdateFieldSchemaWithData() { + public function testUpdateFieldSchemaWithData() { $entity_type = 'entity_test_rev'; // Create a decimal 5.2 field and add some data. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'decimal52', 'entity_type' => $entity_type, 'type' => 'decimal', - 'settings' => array('precision' => 5, 'scale' => 2), - )); + 'settings' => ['precision' => 5, 'scale' => 2], + ]); $field_storage->save(); $field = FieldConfig::create([ 'field_storage' => $field_storage, @@ -329,10 +329,10 @@ function testUpdateFieldSchemaWithData() { $field->save(); $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'id' => 0, 'revision_id' => 0, - )); + ]); $entity->decimal52->value = '1.235'; $entity->save(); @@ -350,14 +350,14 @@ function testUpdateFieldSchemaWithData() { /** * Test that failure to create fields is handled gracefully. */ - function testFieldUpdateFailure() { + public function testFieldUpdateFailure() { // Create a text field. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'test_text', 'entity_type' => 'entity_test_rev', 'type' => 'text', - 'settings' => array('max_length' => 255), - )); + 'settings' => ['max_length' => 255], + ]); $field_storage->save(); // Attempt to update the field in a way that would break the storage. The @@ -376,48 +376,48 @@ function testFieldUpdateFailure() { } // Ensure that the field tables are still there. - $tables = array( + $tables = [ $this->tableMapping->getDedicatedDataTableName($prior_field_storage), $this->tableMapping->getDedicatedRevisionTableName($prior_field_storage), - ); + ]; foreach ($tables as $table_name) { - $this->assertTrue(db_table_exists($table_name), t('Table %table exists.', array('%table' => $table_name))); + $this->assertTrue(db_table_exists($table_name), t('Table %table exists.', ['%table' => $table_name])); } } /** * Test adding and removing indexes while data is present. */ - function testFieldUpdateIndexesWithData() { + public function testFieldUpdateIndexesWithData() { // Create a decimal field. $field_name = 'testfield'; $entity_type = 'entity_test_rev'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => $entity_type, 'type' => 'text', - )); + ]); $field_storage->save(); $field = FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => $entity_type, ]); $field->save(); - $tables = array($this->tableMapping->getDedicatedDataTableName($field_storage), $this->tableMapping->getDedicatedRevisionTableName($field_storage)); + $tables = [$this->tableMapping->getDedicatedDataTableName($field_storage), $this->tableMapping->getDedicatedRevisionTableName($field_storage)]; // Verify the indexes we will create do not exist yet. foreach ($tables as $table) { - $this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value'), t("No index named value exists in @table", array('@table' => $table))); - $this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value_format'), t("No index named value_format exists in @table", array('@table' => $table))); + $this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value'), t("No index named value exists in @table", ['@table' => $table])); + $this->assertFalse(Database::getConnection()->schema()->indexExists($table, 'value_format'), t("No index named value_format exists in @table", ['@table' => $table])); } // Add data so the table cannot be dropped. $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ 'id' => 1, 'revision_id' => 1, - )); + ]); $entity->$field_name->value = 'field data'; $entity->enforceIsNew(); $entity->save(); @@ -426,15 +426,15 @@ function testFieldUpdateIndexesWithData() { $field_storage->setIndexes(['value' => [['value', 255]]]); $field_storage->save(); foreach ($tables as $table) { - $this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value created in @table", array('@table' => $table))); + $this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value created in @table", ['@table' => $table])); } // Add a different index, removing the existing custom one. $field_storage->setIndexes(['value_format' => [['value', 127], ['format', 127]]]); $field_storage->save(); foreach ($tables as $table) { - $this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value_format"), t("Index on value_format created in @table", array('@table' => $table))); - $this->assertFalse(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value removed in @table", array('@table' => $table))); + $this->assertTrue(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value_format"), t("Index on value_format created in @table", ['@table' => $table])); + $this->assertFalse(Database::getConnection()->schema()->indexExists($table, "{$field_name}_value"), t("Index on value removed in @table", ['@table' => $table])); } // Verify that the tables were not dropped in the process. @@ -445,17 +445,17 @@ function testFieldUpdateIndexesWithData() { /** * Test foreign key support. */ - function testFieldSqlStorageForeignKeys() { + public function testFieldSqlStorageForeignKeys() { // Create a 'shape' field, with a configurable foreign key (see // field_test_field_schema()). $field_name = 'testfield'; $foreign_key_name = 'shape'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'shape', - 'settings' => array('foreign_key_name' => $foreign_key_name), - )); + 'settings' => ['foreign_key_name' => $foreign_key_name], + ]); $field_storage->save(); // Get the field schema. $schema = $field_storage->getSchema(); @@ -487,11 +487,11 @@ public function testTableNames() { // Short entity type and field name. $entity_type = 'short_entity_type'; $field_name = 'short_field_name'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'entity_type' => $entity_type, 'field_name' => $field_name, 'type' => 'test_field', - )); + ]); $expected = 'short_entity_type__short_field_name'; $this->assertEqual($this->tableMapping->getDedicatedDataTableName($field_storage), $expected); $expected = 'short_entity_type_revision__short_field_name'; @@ -500,11 +500,11 @@ public function testTableNames() { // Short entity type, long field name $entity_type = 'short_entity_type'; $field_name = 'long_field_name_abcdefghijklmnopqrstuvwxyz'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'entity_type' => $entity_type, 'field_name' => $field_name, 'type' => 'test_field', - )); + ]); $expected = 'short_entity_type__' . substr(hash('sha256', $field_storage->uuid()), 0, 10); $this->assertEqual($this->tableMapping->getDedicatedDataTableName($field_storage), $expected); $expected = 'short_entity_type_r__' . substr(hash('sha256', $field_storage->uuid()), 0, 10); @@ -513,11 +513,11 @@ public function testTableNames() { // Long entity type, short field name $entity_type = 'long_entity_type_abcdefghijklmnopqrstuvwxyz'; $field_name = 'short_field_name'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'entity_type' => $entity_type, 'field_name' => $field_name, 'type' => 'test_field', - )); + ]); $expected = 'long_entity_type_abcdefghijklmnopq__' . substr(hash('sha256', $field_storage->uuid()), 0, 10); $this->assertEqual($this->tableMapping->getDedicatedDataTableName($field_storage), $expected); $expected = 'long_entity_type_abcdefghijklmnopq_r__' . substr(hash('sha256', $field_storage->uuid()), 0, 10); @@ -526,31 +526,31 @@ public function testTableNames() { // Long entity type and field name. $entity_type = 'long_entity_type_abcdefghijklmnopqrstuvwxyz'; $field_name = 'long_field_name_abcdefghijklmnopqrstuvwxyz'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'entity_type' => $entity_type, 'field_name' => $field_name, 'type' => 'test_field', - )); + ]); $expected = 'long_entity_type_abcdefghijklmnopq__' . substr(hash('sha256', $field_storage->uuid()), 0, 10); $this->assertEqual($this->tableMapping->getDedicatedDataTableName($field_storage), $expected); $expected = 'long_entity_type_abcdefghijklmnopq_r__' . substr(hash('sha256', $field_storage->uuid()), 0, 10); $this->assertEqual($this->tableMapping->getDedicatedRevisionTableName($field_storage), $expected); // Try creating a second field and check there are no clashes. - $field_storage2 = FieldStorageConfig::create(array( + $field_storage2 = FieldStorageConfig::create([ 'entity_type' => $entity_type, 'field_name' => $field_name . '2', 'type' => 'test_field', - )); + ]); $this->assertNotEqual($this->tableMapping->getDedicatedDataTableName($field_storage), $this->tableMapping->getDedicatedDataTableName($field_storage2)); $this->assertNotEqual($this->tableMapping->getDedicatedRevisionTableName($field_storage), $this->tableMapping->getDedicatedRevisionTableName($field_storage2)); // Deleted field. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'entity_type' => 'some_entity_type', 'field_name' => 'some_field_name', 'type' => 'test_field', 'deleted' => TRUE, - )); + ]); $expected = 'field_deleted_data_' . substr(hash('sha256', $field_storage->uuid()), 0, 10); $this->assertEqual($this->tableMapping->getDedicatedDataTableName($field_storage, TRUE), $expected); $expected = 'field_deleted_revision_' . substr(hash('sha256', $field_storage->uuid()), 0, 10); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldTranslationSqlStorageTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldTranslationSqlStorageTest.php index b301c64f..c398732f 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/FieldTranslationSqlStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldTranslationSqlStorageTest.php @@ -20,10 +20,10 @@ public function testFieldSqlStorage() { $entity_type = 'entity_test_mul'; $controller = $this->entityManager->getStorage($entity_type); - $values = array( + $values = [ $this->fieldName => $this->randomMachineName(), $this->untranslatableFieldName => $this->randomMachineName(), - ); + ]; $entity = $controller->create($values); $entity->save(); @@ -45,7 +45,7 @@ public function testFieldSqlStorage() { // before. $this->toggleFieldTranslatability($entity_type, $entity_type); $entity = $this->reloadEntity($entity); - foreach (array($this->fieldName, $this->untranslatableFieldName) as $field_name) { + foreach ([$this->fieldName, $this->untranslatableFieldName] as $field_name) { $this->assertEqual($entity->get($field_name)->value, $values[$field_name], 'Field language works as expected after switching translatability.'); } @@ -76,7 +76,7 @@ protected function assertFieldStorageLangcode(FieldableEntityInterface $entity, $entity_type = $entity->getEntityTypeId(); $id = $entity->id(); $langcode = $entity->getUntranslated()->language()->getId(); - $fields = array($this->fieldName, $this->untranslatableFieldName); + $fields = [$this->fieldName, $this->untranslatableFieldName]; /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ $table_mapping = \Drupal::entityManager()->getStorage($entity_type)->getTableMapping(); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php index 50d173bc..041b062f 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php @@ -15,7 +15,7 @@ */ class FieldWidgetConstraintValidatorTest extends KernelTestBase { - public static $modules = array('entity_test', 'field', 'user', 'system'); + public static $modules = ['entity_test', 'field', 'user', 'system']; /** * {@inheritdoc} @@ -37,9 +37,9 @@ public function testValidation() { $entity_type = 'entity_test_constraint_violation'; $entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array('id' => 1, 'revision_id' => 1)); + ->create(['id' => 1, 'revision_id' => 1]); $display = entity_get_form_display($entity_type, $entity_type, 'default'); - $form = array(); + $form = []; $form_state = new FormState(); $display->buildForm($entity, $form, $form_state); @@ -149,6 +149,10 @@ public function testEntityLevelConstraintValidation() { $errors = $this->getErrorsForEntity($entity); $this->assertEqual($errors[''], 'Entity level validation'); + + $entity->name->value = 'entity-level-violation-with-path'; + $errors = $this->getErrorsForEntity($entity); + $this->assertEqual($errors['test][form][element'], 'Entity level validation'); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php index 1fd873cd..73b32546 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php @@ -2,9 +2,12 @@ namespace Drupal\KernelTests\Core\Entity; -use Drupal\entity_test\Entity\EntityTestWithRevisionLog; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\entity_test_revlog\Entity\EntityTestMulWithRevisionLog; use Drupal\KernelTests\KernelTestBase; use Drupal\user\Entity\User; +use Drupal\user\UserInterface; /** * @coversDefaultClass \Drupal\Core\Entity\RevisionableContentEntityBase @@ -15,7 +18,7 @@ class RevisionableContentEntityBaseTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = ['entity_test', 'system', 'user']; + public static $modules = ['entity_test_revlog', 'system', 'user']; /** * {@inheritdoc} @@ -23,34 +26,102 @@ class RevisionableContentEntityBaseTest extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->installEntitySchema('entity_test_revlog'); + $this->installEntitySchema('entity_test_mul_revlog'); $this->installEntitySchema('user'); $this->installSchema('system', 'sequences'); } + /** + * Tests the correct functionality CRUD operations of entity revisions. + */ public function testRevisionableContentEntity() { + $entity_type = 'entity_test_mul_revlog'; + $definition = \Drupal::entityManager()->getDefinition($entity_type); $user = User::create(['name' => 'test name']); $user->save(); - /** @var \Drupal\entity_test\Entity\EntityTestWithRevisionLog $entity */ - $entity = EntityTestWithRevisionLog::create([ - 'type' => 'entity_test_revlog', + /** @var \Drupal\entity_test_mul_revlog\Entity\EntityTestMulWithRevisionLog $entity */ + $entity = EntityTestMulWithRevisionLog::create([ + 'type' => $entity_type, ]); + + // Save the entity, this creates the first revision. $entity->save(); + $revision_ids[] = $entity->getRevisionId(); + $this->assertItemsTableCount(1, $definition); + // Create the second revision. $entity->setNewRevision(TRUE); $random_timestamp = rand(1e8, 2e8); - $entity->setRevisionCreationTime($random_timestamp); - $entity->setRevisionUserId($user->id()); - $entity->setRevisionLogMessage('This is my log message'); - $entity->save(); + $this->createRevision($entity, $user, $random_timestamp, 'This is my log message'); $revision_id = $entity->getRevisionId(); + $revision_ids[] = $revision_id; - $entity = \Drupal::entityTypeManager()->getStorage('entity_test_revlog')->loadRevision($revision_id); + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mul_revlog'); + $entity = $storage->loadRevision($revision_id); $this->assertEquals($random_timestamp, $entity->getRevisionCreationTime()); $this->assertEquals($user->id(), $entity->getRevisionUserId()); $this->assertEquals($user->id(), $entity->getRevisionUser()->id()); $this->assertEquals('This is my log message', $entity->getRevisionLogMessage()); + + // Create the third revision. + $random_timestamp = rand(1e8, 2e8); + $this->createRevision($entity, $user, $random_timestamp, 'This is my log message'); + $this->assertItemsTableCount(3, $definition); + $revision_ids[] = $entity->getRevisionId(); + + // Create another 3 revisions. + foreach (range(1, 3) as $count) { + $timestamp = rand(1e8, 2e8); + $this->createRevision($entity, $user, $timestamp, 'This is my log message number: ' . $count); + $revision_ids[] = $entity->getRevisionId(); + } + $this->assertItemsTableCount(6, $definition); + + $this->assertEqual(6, count($revision_ids)); + + // Delete the first 3 revisions. + foreach (range(0, 2) as $key) { + $storage->deleteRevision($revision_ids[$key]); + } + + // We should have only data for three revisions. + $this->assertItemsTableCount(3, $definition); + } + + /** + * Asserts the ammount of items on entity related tables. + * + * @param int $count + * The number of items expected to be in revisions related tables. + * @param \Drupal\Core\Entity\EntityTypeInterface $definition + * The definition and metada of the entity being tested. + */ + protected function assertItemsTableCount($count, EntityTypeInterface $definition) { + $this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getBaseTable() . '}')->fetchField()); + $this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getDataTable() . '}')->fetchField()); + $this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionTable() . '}')->fetchField()); + $this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionDataTable() . '}')->fetchField()); + } + + /** + * Creates a new revision in the entity of this test class. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity where revision will be created. + * @param \Drupal\user\UserInterface $user + * The author of the new revision. + * @param int $timestamp + * The timestamp of the new revision. + * @param string $log_message + * The log message of the new revision. + */ + protected function createRevision(EntityInterface $entity, UserInterface $user, $timestamp, $log_message) { + $entity->setNewRevision(TRUE); + $entity->setRevisionCreationTime($timestamp); + $entity->setRevisionUserId($user->id()); + $entity->setRevisionLogMessage($log_message); + $entity->save(); } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php index 64bb933d..3f182c91 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ValidReferenceConstraintValidatorTest.php @@ -3,6 +3,15 @@ namespace Drupal\KernelTests\Core\Entity; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\entity_test\Entity\EntityTest; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; +use Drupal\node\Entity\Node; +use Drupal\node\NodeInterface; +use Drupal\Tests\node\Traits\ContentTypeCreationTrait; +use Drupal\user\Entity\Role; +use Drupal\user\Entity\User; /** * Tests validation constraints for ValidReferenceConstraintValidator. @@ -11,6 +20,9 @@ */ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase { + use EntityReferenceTestTrait; + use ContentTypeCreationTrait; + /** * The typed data manager to use. * @@ -21,15 +33,20 @@ class ValidReferenceConstraintValidatorTest extends EntityKernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('field', 'user'); + public static $modules = ['field', 'node', 'user']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); + $this->installSchema('user', ['users_data']); + $this->installSchema('node', ['node_access']); + $this->installConfig('node'); $this->typedData = $this->container->get('typed_data_manager'); + + $this->createContentType(['type' => 'article', 'name' => 'Article']); + $this->createContentType(['type' => 'page', 'name' => 'Basic page']); } /** @@ -40,18 +57,18 @@ public function testValidation() { $entity = $this->createUser(); // By default entity references already have the ValidReference constraint. $definition = BaseFieldDefinition::create('entity_reference') - ->setSettings(array('target_type' => 'user')); + ->setSettings(['target_type' => 'user']); - $typed_data = $this->typedData->create($definition, array('target_id' => $entity->id())); + $typed_data = $this->typedData->create($definition, ['target_id' => $entity->id()]); $violations = $typed_data->validate(); $this->assertFalse($violations->count(), 'Validation passed for correct value.'); // NULL is also considered a valid reference. - $typed_data = $this->typedData->create($definition, array('target_id' => NULL)); + $typed_data = $this->typedData->create($definition, ['target_id' => NULL]); $violations = $typed_data->validate(); $this->assertFalse($violations->count(), 'Validation passed for correct value.'); - $typed_data = $this->typedData->create($definition, array('target_id' => $entity->id())); + $typed_data = $this->typedData->create($definition, ['target_id' => $entity->id()]); // Delete the referenced entity. $entity->delete(); $violations = $typed_data->validate(); @@ -59,11 +76,159 @@ public function testValidation() { // Make sure the information provided by a violation is correct. $violation = $violations[0]; - $this->assertEqual($violation->getMessage(), t('The referenced entity (%type: %id) does not exist.', array( + $this->assertEqual($violation->getMessage(), t('The referenced entity (%type: %id) does not exist.', [ '%type' => 'user', '%id' => $entity->id(), - )), 'The message for invalid value is correct.'); + ]), 'The message for invalid value is correct.'); $this->assertEqual($violation->getRoot(), $typed_data, 'Violation root is correct.'); } + /** + * Tests the validation of pre-existing items in an entity reference field. + */ + public function testPreExistingItemsValidation() { + // Create two types of users, with and without access to bypass content + // access. + /** @var \Drupal\user\RoleInterface $role_with_access */ + $role_with_access = Role::create(['id' => 'role_with_access']); + $role_with_access->grantPermission('access content'); + $role_with_access->grantPermission('bypass node access'); + $role_with_access->save(); + + /** @var \Drupal\user\RoleInterface $role_without_access */ + $role_without_access = Role::create(['id' => 'role_without_access']); + $role_without_access->grantPermission('access content'); + $role_without_access->save(); + + $user_with_access = User::create(['roles' => ['role_with_access']]); + $user_without_access = User::create(['roles' => ['role_without_access']]); + + // Add an entity reference field. + $this->createEntityReferenceField( + 'entity_test', + 'entity_test', + 'field_test', + 'Field test', + 'node', + 'default', + ['target_bundles' => ['article', 'page']], + FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED + ); + + // Create four test nodes. + $published_node = Node::create([ + 'title' => 'Test published node', + 'type' => 'article', + 'status' => NodeInterface::PUBLISHED, + ]); + $published_node->save(); + + $unpublished_node = Node::create([ + 'title' => 'Test unpublished node', + 'type' => 'article', + 'status' => NodeInterface::NOT_PUBLISHED, + ]); + $unpublished_node->save(); + + $different_bundle_node = Node::create([ + 'title' => 'Test page node', + 'type' => 'page', + 'status' => NodeInterface::PUBLISHED, + ]); + $different_bundle_node->save(); + + $deleted_node = Node::create([ + 'title' => 'Test deleted node', + 'type' => 'article', + 'status' => NodeInterface::PUBLISHED, + ]); + $deleted_node->save(); + + $referencing_entity = EntityTest::create([ + 'field_test' => [ + ['entity' => $published_node], + ['entity' => $unpublished_node], + ['entity' => $different_bundle_node], + ['entity' => $deleted_node], + ] + ]); + + // Check that users with access are able pass the validation for fields + // without pre-existing content. + $this->container->get('account_switcher')->switchTo($user_with_access); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(0, $violations); + + // Check that users without access are not able pass the validation for + // fields without pre-existing content. + $this->container->get('account_switcher')->switchTo($user_without_access); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(1, $violations); + $this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [ + '%type' => 'node', + '%id' => $unpublished_node->id(), + ]), $violations[0]->getMessage()); + + // Now save the referencing entity which will create a pre-existing state + // for it and repeat the checks. This time, the user without access should + // be able to pass the validation as well because it's not changing the + // pre-existing state. + $referencing_entity->save(); + + $this->container->get('account_switcher')->switchTo($user_with_access); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(0, $violations); + + // Check that users without access are able pass the validation for fields + // with pre-existing content. + $this->container->get('account_switcher')->switchTo($user_without_access); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(0, $violations); + + // Re-save the referencing entity and check that the referenced entity is + // not affected. + $referencing_entity->name->value = $this->randomString(); + $referencing_entity->save(); + $this->assertEquals($published_node->id(), $referencing_entity->field_test[0]->target_id); + $this->assertEquals($unpublished_node->id(), $referencing_entity->field_test[1]->target_id); + $this->assertEquals($different_bundle_node->id(), $referencing_entity->field_test[2]->target_id); + $this->assertEquals($deleted_node->id(), $referencing_entity->field_test[3]->target_id); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(0, $violations); + + // Remove one of the referencable bundles and check that a pre-existing node + // of that bundle can not be referenced anymore. + $field = FieldConfig::loadByName('entity_test', 'entity_test', 'field_test'); + $field->setSetting('handler_settings', ['target_bundles' => ['article']]); + $field->save(); + $referencing_entity = $this->reloadEntity($referencing_entity); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(1, $violations); + $this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [ + '%type' => 'node', + '%id' => $different_bundle_node->id(), + ]), $violations[0]->getMessage()); + + // Delete the last node and check that the pre-existing reference is not + // valid anymore. + $deleted_node->delete(); + + $violations = $referencing_entity->field_test->validate(); + $this->assertCount(2, $violations); + $this->assertEquals(t('This entity (%type: %id) cannot be referenced.', [ + '%type' => 'node', + '%id' => $different_bundle_node->id(), + ]), $violations[0]->getMessage()); + $this->assertEquals(t('The referenced entity (%type: %id) does not exist.', [ + '%type' => 'node', + '%id' => $deleted_node->id(), + ]), $violations[1]->getMessage()); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/EventSubscriber/IgnoreReplicaSubscriberTest.php b/core/tests/Drupal/KernelTests/Core/EventSubscriber/IgnoreReplicaSubscriberTest.php index 51315372..7ce994a9 100644 --- a/core/tests/Drupal/KernelTests/Core/EventSubscriber/IgnoreReplicaSubscriberTest.php +++ b/core/tests/Drupal/KernelTests/Core/EventSubscriber/IgnoreReplicaSubscriberTest.php @@ -20,7 +20,7 @@ class IgnoreReplicaSubscriberTest extends KernelTestBase { /** * Tests \Drupal\Core\EventSubscriber\ReplicaDatabaseIgnoreSubscriber::checkReplicaServer(). */ - function testSystemInitIgnoresSecondaries() { + public function testSystemInitIgnoresSecondaries() { // Clone the master credentials to a replica connection. // Note this will result in two independent connection objects that happen // to point to the same place. @@ -37,7 +37,7 @@ function testSystemInitIgnoresSecondaries() { $db1 = Database::getConnection('default', 'default'); $db2 = Database::getConnection('replica', 'default'); - $this->assertIdentical($db1, $db2, 'System Init ignores secondaries when requested.'); + $this->assertSame($db1, $db2, 'System Init ignores secondaries when requested.'); } } diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php new file mode 100644 index 00000000..96e469a8 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php @@ -0,0 +1,57 @@ +routeProvider = \Drupal::service('router.route_provider'); + $this->moduleInfo = system_rebuild_module_data(); + } + + /** + * Test the module configure routes exist. + * + * @dataProvider coreModuleListDataProvider + */ + public function testModuleConfigureRoutes($module) { + $module_info = $this->moduleInfo[$module]->info; + if (isset($module_info['configure'])) { + $this->container->get('module_installer')->install([$module]); + $route = $this->routeProvider->getRouteByName($module_info['configure']); + $this->assertNotEmpty($route, sprintf('The configure route for the "%s" module was found.', $module)); + } + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleImplementsAlterTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleImplementsAlterTest.php index f55d744f..7d29a261 100644 --- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleImplementsAlterTest.php +++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleImplementsAlterTest.php @@ -22,7 +22,7 @@ class ModuleImplementsAlterTest extends KernelTestBase { * @see \Drupal\Core\Extension\ModuleHandler::buildImplementationInfo() * @see module_test_module_implements_alter() */ - function testModuleImplementsAlter() { + public function testModuleImplementsAlter() { // Get an instance of the module handler, to observe how it is going to be // replaced. @@ -32,7 +32,7 @@ function testModuleImplementsAlter() { 'Module handler instance is still the same.'); // Install the module_test module. - \Drupal::service('module_installer')->install(array('module_test')); + \Drupal::service('module_installer')->install(['module_test']); // Assert that the \Drupal::moduleHandler() instance has been replaced. $this->assertFalse($module_handler === \Drupal::moduleHandler(), @@ -73,10 +73,10 @@ function testModuleImplementsAlter() { * @see \Drupal\Core\Extension\ModuleHandler::buildImplementationInfo() * @see module_test_module_implements_alter() */ - function testModuleImplementsAlterNonExistingImplementation() { + public function testModuleImplementsAlterNonExistingImplementation() { // Install the module_test module. - \Drupal::service('module_installer')->install(array('module_test')); + \Drupal::service('module_installer')->install(['module_test']); try { // Trigger hook discovery. diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php index c15e7fba..fa5a9a17 100644 --- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php @@ -44,4 +44,20 @@ public function testRouteRebuild() { $this->container->get('router.route_provider')->getRouteByName('router_test.1'); } + /** + * Tests config changes by hook_install() are saved for dependent modules. + * + * @covers ::install + */ + public function testConfigChangeOnInstall() { + // Install the child module so the parent is installed automatically. + $this->container->get('module_installer')->install(['module_handler_test_multiple_child']); + $modules = $this->config('core.extension')->get('module'); + + $this->assertArrayHasKey('module_handler_test_multiple', $modules, 'Module module_handler_test_multiple is installed'); + $this->assertArrayHasKey('module_handler_test_multiple_child', $modules, 'Module module_handler_test_multiple_child is installed'); + $this->assertEquals(1, $modules['module_handler_test_multiple'], 'Weight of module_handler_test_multiple is set.'); + $this->assertEquals(1, $modules['module_handler_test_multiple_child'], 'Weight of module_handler_test_multiple_child is set.'); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php new file mode 100644 index 00000000..404c2f0b --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php @@ -0,0 +1,65 @@ +installEntitySchema('base_field_override'); + } + + /** + * @covers ::getClass + * + * @dataProvider getClassTestCases + */ + public function testGetClass($field_type, $base_field_class, $expected_override_class) { + $base_field = BaseFieldDefinition::create($field_type) + ->setName('Test Field') + ->setTargetEntityTypeId('entity_test'); + if ($base_field_class) { + $base_field->setClass($base_field_class); + } + $override = BaseFieldOverride::createFromBaseFieldDefinition($base_field, 'test_bundle'); + $this->assertEquals($expected_override_class, ltrim($override->getClass(), '\\')); + } + + /** + * Test cases for ::testGetClass. + */ + public function getClassTestCases() { + return [ + 'String (default class)' => [ + 'string', + FALSE, + FieldItemList::class, + ], + 'String (overriden class)' => [ + 'string', + static::class, + static::class, + ], + ]; + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php index 5a59a235..f273029b 100644 --- a/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php +++ b/core/tests/Drupal/KernelTests/Core/Field/FieldAccessTest.php @@ -34,7 +34,7 @@ class FieldAccessTest extends KernelTestBase { protected function setUp() { parent::setUp(); // Install field configuration. - $this->installConfig(array('field')); + $this->installConfig(['field']); // The users table is needed for creating dummy user accounts. $this->installEntitySchema('user'); // Register entity_test text field. @@ -48,19 +48,19 @@ protected function setUp() { * @see entity_test_entity_field_access() * @see entity_test_entity_field_access_alter() */ - function testFieldAccess() { - $values = array( + public function testFieldAccess() { + $values = [ 'name' => $this->randomMachineName(), 'user_id' => 1, - 'field_test_text' => array( + 'field_test_text' => [ 'value' => 'no access value', 'format' => 'full_html', - ), - ); + ], + ]; $entity = EntityTest::create($values); // Create a dummy user account for testing access with. - $values = array('name' => 'test'); + $values = ['name' => 'test']; $account = User::create($values); $this->assertFalse($entity->field_test_text->access('view', $account), 'Access to the field was denied.'); diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldModuleUninstallValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldModuleUninstallValidatorTest.php index af2fb07e..b9d545e2 100644 --- a/core/tests/Drupal/KernelTests/Core/Field/FieldModuleUninstallValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Field/FieldModuleUninstallValidatorTest.php @@ -73,7 +73,7 @@ public function testUninstallingModule() { try { $message = 'Module uninstallation fails as the module provides a base field which has content.'; - $this->getModuleInstaller()->uninstall(array('entity_test_extra')); + $this->getModuleInstaller()->uninstall(['entity_test_extra']); $this->fail($message); } catch (ModuleUninstallValidatorException $e) { @@ -93,7 +93,7 @@ public function testUninstallingModule() { ]); $entity->save(); try { - $this->getModuleInstaller()->uninstall(array('entity_test_extra')); + $this->getModuleInstaller()->uninstall(['entity_test_extra']); $this->fail('Module uninstallation fails as the module provides a bundle field which has content.'); } catch (ModuleUninstallValidatorException $e) { diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php index a55888f6..583e55b7 100644 --- a/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php +++ b/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php @@ -19,7 +19,7 @@ class FieldSettingsTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('field', 'field_test'); + public static $modules = ['field', 'field_test']; /** * @covers \Drupal\Core\Field\BaseFieldDefinition::getSettings diff --git a/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php index d7e7c382..4e358216 100644 --- a/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php @@ -14,7 +14,7 @@ class DirectoryTest extends FileTestBase { /** * Test local directory handling functions. */ - function testFileCheckLocalDirectoryHandling() { + public function testFileCheckLocalDirectoryHandling() { $site_path = $this->container->get('site.path'); $directory = $site_path . '/files'; @@ -53,7 +53,7 @@ function testFileCheckLocalDirectoryHandling() { /** * Test directory handling functions. */ - function testFileCheckDirectoryHandling() { + public function testFileCheckDirectoryHandling() { // A directory to operate on. $directory = file_default_scheme() . '://' . $this->randomMachineName() . '/' . $this->randomMachineName(); $this->assertFalse(is_dir($directory), 'Directory does not exist prior to testing.'); @@ -99,21 +99,21 @@ function testFileCheckDirectoryHandling() { * This will take a directory and path, and find a valid filepath that is not * taken by another file. */ - function testFileCreateNewFilepath() { + public function testFileCreateNewFilepath() { // First we test against an imaginary file that does not exist in a // directory. $basename = 'xyz.txt'; $directory = 'core/misc'; $original = $directory . '/' . $basename; $path = file_create_filename($basename, $directory); - $this->assertEqual($path, $original, format_string('New filepath %new equals %original.', array('%new' => $path, '%original' => $original)), 'File'); + $this->assertEqual($path, $original, format_string('New filepath %new equals %original.', ['%new' => $path, '%original' => $original]), 'File'); // Then we test against a file that already exists within that directory. $basename = 'druplicon.png'; $original = $directory . '/' . $basename; $expected = $directory . '/druplicon_0.png'; $path = file_create_filename($basename, $directory); - $this->assertEqual($path, $expected, format_string('Creating a new filepath from %original equals %new (expected %expected).', array('%new' => $path, '%original' => $original, '%expected' => $expected)), 'File'); + $this->assertEqual($path, $expected, format_string('Creating a new filepath from %original equals %new (expected %expected).', ['%new' => $path, '%original' => $original, '%expected' => $expected]), 'File'); // @TODO: Finally we copy a file into a directory several times, to ensure a properly iterating filename suffix. } @@ -130,7 +130,7 @@ function testFileCreateNewFilepath() { * If the file doesn't currently exist, then it will simply return the * filepath. */ - function testFileDestination() { + public function testFileDestination() { // First test for non-existent file. $destination = 'core/misc/xyz.txt'; $path = file_destination($destination, FILE_EXISTS_REPLACE); @@ -152,7 +152,7 @@ function testFileDestination() { /** * Ensure that the file_directory_temp() function always returns a value. */ - function testFileDirectoryTemp() { + public function testFileDirectoryTemp() { // Start with an empty variable to ensure we have a clean slate. $config = $this->config('system.file'); $config->set('path.temporary', '')->save(); diff --git a/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php b/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php index 548d1bcf..92612ae7 100644 --- a/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php @@ -16,7 +16,7 @@ abstract class FileTestBase extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * A stream wrapper scheme to register for the test. @@ -37,7 +37,11 @@ abstract class FileTestBase extends KernelTestBase { */ protected function setUp() { parent::setUp(); - + // \Drupal\KernelTests\KernelTestBase::bootKernel() sets a global override + // for the default scheme because core relies on it in + // file_default_scheme(). As we are creating the configuration here remove + // the global override. + unset($GLOBALS['config']['system.file']); \Drupal::configFactory()->getEditable('system.file')->set('default_scheme', 'public')->save(); } @@ -70,9 +74,9 @@ protected function setUpFilesystem() { $this->setSetting('file_public_path', $public_file_directory); - $GLOBALS['config_directories'] = array( + $GLOBALS['config_directories'] = [ CONFIG_SYNC_DIRECTORY => $this->siteDirectory . '/files/config/sync', - ); + ]; } /** @@ -85,7 +89,7 @@ protected function setUpFilesystem() { * @param $message * Optional message. */ - function assertFilePermissions($filepath, $expected_mode, $message = NULL) { + public function assertFilePermissions($filepath, $expected_mode, $message = NULL) { // Clear out PHP's file stat cache to be sure we see the current value. clearstatcache(TRUE, $filepath); @@ -105,7 +109,7 @@ function assertFilePermissions($filepath, $expected_mode, $message = NULL) { } if (!isset($message)) { - $message = t('Expected file permission to be %expected, actually were %actual.', array('%actual' => decoct($actual_mode), '%expected' => decoct($expected_mode))); + $message = t('Expected file permission to be %expected, actually were %actual.', ['%actual' => decoct($actual_mode), '%expected' => decoct($expected_mode)]); } $this->assertEqual($actual_mode, $expected_mode, $message); } @@ -120,7 +124,7 @@ function assertFilePermissions($filepath, $expected_mode, $message = NULL) { * @param $message * Optional message. */ - function assertDirectoryPermissions($directory, $expected_mode, $message = NULL) { + public function assertDirectoryPermissions($directory, $expected_mode, $message = NULL) { // Clear out PHP's file stat cache to be sure we see the current value. clearstatcache(TRUE, $directory); @@ -141,7 +145,7 @@ function assertDirectoryPermissions($directory, $expected_mode, $message = NULL) } if (!isset($message)) { - $message = t('Expected directory permission to be %expected, actually were %actual.', array('%actual' => decoct($actual_mode), '%expected' => decoct($expected_mode))); + $message = t('Expected directory permission to be %expected, actually were %actual.', ['%actual' => decoct($actual_mode), '%expected' => decoct($expected_mode)]); } $this->assertEqual($actual_mode, $expected_mode, $message); } @@ -155,7 +159,7 @@ function assertDirectoryPermissions($directory, $expected_mode, $message = NULL) * @return * The path to the directory. */ - function createDirectory($path = NULL) { + public function createDirectory($path = NULL) { // A directory to operate on. if (!isset($path)) { $path = file_default_scheme() . '://' . $this->randomMachineName(); @@ -179,7 +183,7 @@ function createDirectory($path = NULL) { * @return * File URI. */ - function createUri($filepath = NULL, $contents = NULL, $scheme = NULL) { + public function createUri($filepath = NULL, $contents = NULL, $scheme = NULL) { if (!isset($filepath)) { // Prefix with non-latin characters to ensure that all file-related // tests work with international filenames. diff --git a/core/tests/Drupal/KernelTests/Core/File/HtaccessTest.php b/core/tests/Drupal/KernelTests/Core/File/HtaccessTest.php index 0ef50780..0c4c1eb7 100644 --- a/core/tests/Drupal/KernelTests/Core/File/HtaccessTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/HtaccessTest.php @@ -16,7 +16,7 @@ class HtaccessTest extends KernelTestBase { /** * Tests file_save_htaccess(). */ - function testHtaccessSave() { + public function testHtaccessSave() { // Prepare test directories. $public = Settings::get('file_public_path') . '/test/public'; $private = Settings::get('file_public_path') . '/test/private'; @@ -82,11 +82,11 @@ function testHtaccessSave() { */ protected function assertFilePermissions($uri, $expected) { $actual = fileperms($uri) & 0777; - return $this->assertIdentical($actual, $expected, SafeMarkup::format('@uri file permissions @actual are identical to @expected.', array( + return $this->assertIdentical($actual, $expected, SafeMarkup::format('@uri file permissions @actual are identical to @expected.', [ '@uri' => $uri, '@actual' => 0 . decoct($actual), '@expected' => 0 . decoct($expected), - ))); + ])); } } diff --git a/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php b/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php index 9bfe6815..05ac7c25 100644 --- a/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/MimeTypeTest.php @@ -14,7 +14,7 @@ class MimeTypeTest extends FileTestBase { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * Test mapping of mimetypes from filenames. @@ -22,7 +22,7 @@ class MimeTypeTest extends FileTestBase { public function testFileMimeTypeDetection() { $prefixes = ['public://', 'private://', 'temporary://', 'dummy-remote://']; - $test_case = array( + $test_case = [ 'test.jar' => 'application/java-archive', 'test.jpeg' => 'image/jpeg', 'test.JPEG' => 'image/jpeg', @@ -37,7 +37,7 @@ public function testFileMimeTypeDetection() { 'foo.file_test_2' => 'madeup/file_test_2', 'foo.doc' => 'madeup/doc', 'test.ogg' => 'audio/ogg', - ); + ]; $guesser = $this->container->get('file.mime_type.guesser'); // Test using default mappings. @@ -45,27 +45,27 @@ public function testFileMimeTypeDetection() { // Test stream [URI]. foreach ($prefixes as $prefix) { $output = $guesser->guess($prefix . $input); - $this->assertIdentical($output, $expected, format_string('Mimetype for %input is %output (expected: %expected).', array('%input' => $prefix . $input, '%output' => $output, '%expected' => $expected))); + $this->assertIdentical($output, $expected, format_string('Mimetype for %input is %output (expected: %expected).', ['%input' => $prefix . $input, '%output' => $output, '%expected' => $expected])); } // Test normal path equivalent $output = $guesser->guess($input); - $this->assertIdentical($output, $expected, format_string('Mimetype (using default mappings) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected))); + $this->assertIdentical($output, $expected, format_string('Mimetype (using default mappings) for %input is %output (expected: %expected).', ['%input' => $input, '%output' => $output, '%expected' => $expected])); } // Now test the extension gusser by passing in a custom mapping. - $mapping = array( - 'mimetypes' => array( + $mapping = [ + 'mimetypes' => [ 0 => 'application/java-archive', 1 => 'image/jpeg', - ), - 'extensions' => array( + ], + 'extensions' => [ 'jar' => 0, 'jpg' => 1, - ) - ); + ] + ]; - $test_case = array( + $test_case = [ 'test.jar' => 'application/java-archive', 'test.jpeg' => 'application/octet-stream', 'test.jpg' => 'image/jpeg', @@ -79,13 +79,13 @@ public function testFileMimeTypeDetection() { 'foo.file_test_2' => 'application/octet-stream', 'foo.doc' => 'application/octet-stream', 'test.ogg' => 'application/octet-stream', - ); + ]; $extension_guesser = $this->container->get('file.mime_type.guesser.extension'); $extension_guesser->setMapping($mapping); foreach ($test_case as $input => $expected) { $output = $extension_guesser->guess($input); - $this->assertIdentical($output, $expected, format_string('Mimetype (using passed-in mappings) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected))); + $this->assertIdentical($output, $expected, format_string('Mimetype (using passed-in mappings) for %input is %output (expected: %expected).', ['%input' => $input, '%output' => $output, '%expected' => $expected])); } } diff --git a/core/tests/Drupal/KernelTests/Core/File/NameMungingTest.php b/core/tests/Drupal/KernelTests/Core/File/NameMungingTest.php index 1fff41e2..2e5d0947 100644 --- a/core/tests/Drupal/KernelTests/Core/File/NameMungingTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/NameMungingTest.php @@ -34,19 +34,19 @@ protected function setUp() { /** * Create a file and munge/unmunge the name. */ - function testMunging() { + public function testMunging() { // Disable insecure uploads. $this->config('system.file')->set('allow_insecure_uploads', 0)->save(); $munged_name = file_munge_filename($this->name, '', TRUE); $messages = drupal_get_messages(); - $this->assertTrue(in_array(strtr('For security reasons, your upload has been renamed to %filename.', array('%filename' => $munged_name)), $messages['status']), 'Alert properly set when a file is renamed.'); - $this->assertNotEqual($munged_name, $this->name, format_string('The new filename (%munged) has been modified from the original (%original)', array('%munged' => $munged_name, '%original' => $this->name))); + $this->assertTrue(in_array(strtr('For security reasons, your upload has been renamed to %filename.', ['%filename' => $munged_name]), $messages['status']), 'Alert properly set when a file is renamed.'); + $this->assertNotEqual($munged_name, $this->name, format_string('The new filename (%munged) has been modified from the original (%original)', ['%munged' => $munged_name, '%original' => $this->name])); } /** * Tests munging with a null byte in the filename. */ - function testMungeNullByte() { + public function testMungeNullByte() { $prefix = $this->randomMachineName(); $filename = $prefix . '.' . $this->badExtension . "\0.txt"; $this->assertEqual(file_munge_filename($filename, ''), $prefix . '.' . $this->badExtension . '_.txt', 'A filename with a null byte is correctly munged to remove the null byte.'); @@ -56,32 +56,32 @@ function testMungeNullByte() { * If the system.file.allow_insecure_uploads setting evaluates to true, the file should * come out untouched, no matter how evil the filename. */ - function testMungeIgnoreInsecure() { + public function testMungeIgnoreInsecure() { $this->config('system.file')->set('allow_insecure_uploads', 1)->save(); $munged_name = file_munge_filename($this->name, ''); - $this->assertIdentical($munged_name, $this->name, format_string('The original filename (%original) matches the munged filename (%munged) when insecure uploads are enabled.', array('%munged' => $munged_name, '%original' => $this->name))); + $this->assertSame($munged_name, $this->name, format_string('The original filename (%original) matches the munged filename (%munged) when insecure uploads are enabled.', ['%munged' => $munged_name, '%original' => $this->name])); } /** * White listed extensions are ignored by file_munge_filename(). */ - function testMungeIgnoreWhitelisted() { + public function testMungeIgnoreWhitelisted() { // Declare our extension as whitelisted. The declared extensions should // be case insensitive so test using one with a different case. $munged_name = file_munge_filename($this->nameWithUcExt, $this->badExtension); - $this->assertIdentical($munged_name, $this->nameWithUcExt, format_string('The new filename (%munged) matches the original (%original) once the extension has been whitelisted.', array('%munged' => $munged_name, '%original' => $this->nameWithUcExt))); + $this->assertSame($munged_name, $this->nameWithUcExt, format_string('The new filename (%munged) matches the original (%original) once the extension has been whitelisted.', ['%munged' => $munged_name, '%original' => $this->nameWithUcExt])); // The allowed extensions should also be normalized. $munged_name = file_munge_filename($this->name, strtoupper($this->badExtension)); - $this->assertIdentical($munged_name, $this->name, format_string('The new filename (%munged) matches the original (%original) also when the whitelisted extension is in uppercase.', array('%munged' => $munged_name, '%original' => $this->name))); + $this->assertSame($munged_name, $this->name, format_string('The new filename (%munged) matches the original (%original) also when the whitelisted extension is in uppercase.', ['%munged' => $munged_name, '%original' => $this->name])); } /** * Ensure that unmunge gets your name back. */ - function testUnMunge() { + public function testUnMunge() { $munged_name = file_munge_filename($this->name, '', FALSE); $unmunged_name = file_unmunge_filename($munged_name); - $this->assertIdentical($unmunged_name, $this->name, format_string('The unmunged (%unmunged) filename matches the original (%original)', array('%unmunged' => $unmunged_name, '%original' => $this->name))); + $this->assertSame($unmunged_name, $this->name, format_string('The unmunged (%unmunged) filename matches the original (%original)', ['%unmunged' => $unmunged_name, '%original' => $this->name])); } } diff --git a/core/tests/Drupal/KernelTests/Core/File/ReadOnlyStreamWrapperTest.php b/core/tests/Drupal/KernelTests/Core/File/ReadOnlyStreamWrapperTest.php index ae19e021..00dfa0b8 100644 --- a/core/tests/Drupal/KernelTests/Core/File/ReadOnlyStreamWrapperTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/ReadOnlyStreamWrapperTest.php @@ -29,7 +29,7 @@ class ReadOnlyStreamWrapperTest extends FileTestBase { /** * Test read-only specific behavior. */ - function testReadOnlyBehavior() { + public function testReadOnlyBehavior() { $type = DummyReadOnlyStreamWrapper::getType(); // Checks that the stream wrapper type is not declared as writable. $this->assertSame(0, $type & StreamWrapperInterface::WRITE); diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileDirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileDirectoryTest.php index 3265562b..e41fb74e 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileDirectoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileDirectoryTest.php @@ -14,7 +14,7 @@ class RemoteFileDirectoryTest extends DirectoryTest { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileScanDirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileScanDirectoryTest.php index 3d872bce..e3c68a72 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileScanDirectoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileScanDirectoryTest.php @@ -14,7 +14,7 @@ class RemoteFileScanDirectoryTest extends ScanDirectoryTest { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedCopyTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedCopyTest.php index 8be67268..b13b92cb 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedCopyTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedCopyTest.php @@ -14,7 +14,7 @@ class RemoteFileUnmanagedCopyTest extends UnmanagedCopyTest { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteRecursiveTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteRecursiveTest.php index 06f0e1aa..6be98df4 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteRecursiveTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteRecursiveTest.php @@ -14,7 +14,7 @@ class RemoteFileUnmanagedDeleteRecursiveTest extends UnmanagedDeleteRecursiveTes * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteTest.php index fe0ad6ed..f826d4dd 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedDeleteTest.php @@ -14,7 +14,7 @@ class RemoteFileUnmanagedDeleteTest extends UnmanagedDeleteTest { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedMoveTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedMoveTest.php index 47b66f23..e41f87e6 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedMoveTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedMoveTest.php @@ -14,7 +14,7 @@ class RemoteFileUnmanagedMoveTest extends UnmanagedMoveTest { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedSaveDataTest.php b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedSaveDataTest.php index 15b59295..817da282 100644 --- a/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedSaveDataTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/RemoteFileUnmanagedSaveDataTest.php @@ -14,7 +14,7 @@ class RemoteFileUnmanagedSaveDataTest extends UnmanagedSaveDataTest { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. diff --git a/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php index 8362c041..0bd546bb 100644 --- a/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php @@ -14,7 +14,7 @@ class ScanDirectoryTest extends FileTestBase { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * @var string @@ -33,7 +33,7 @@ protected function setUp() { /** * Check the format of the returned values. */ - function testReturn() { + public function testReturn() { // Grab a listing of all the JavaScript files and check that they're // passed to the callback. $all_files = file_scan_directory($this->path, '/^javascript-/'); @@ -58,10 +58,10 @@ function testReturn() { /** * Check that the callback function is called correctly. */ - function testOptionCallback() { + public function testOptionCallback() { // When nothing is matched nothing should be passed to the callback. - $all_files = file_scan_directory($this->path, '/^NONEXISTINGFILENAME/', array('callback' => 'file_test_file_scan_callback')); + $all_files = file_scan_directory($this->path, '/^NONEXISTINGFILENAME/', ['callback' => 'file_test_file_scan_callback']); $this->assertEqual(0, count($all_files), 'No files were found.'); $results = file_test_file_scan_callback(); file_test_file_scan_callback_reset(); @@ -69,7 +69,7 @@ function testOptionCallback() { // Grab a listing of all the JavaScript files and check that they're // passed to the callback. - $all_files = file_scan_directory($this->path, '/^javascript-/', array('callback' => 'file_test_file_scan_callback')); + $all_files = file_scan_directory($this->path, '/^javascript-/', ['callback' => 'file_test_file_scan_callback']); $this->assertEqual(2, count($all_files), 'Found two, expected javascript files.'); $results = file_test_file_scan_callback(); file_test_file_scan_callback_reset(); @@ -79,41 +79,41 @@ function testOptionCallback() { /** * Check that the no-mask parameter is honored. */ - function testOptionNoMask() { + public function testOptionNoMask() { // Grab a listing of all the JavaScript files. $all_files = file_scan_directory($this->path, '/^javascript-/'); $this->assertEqual(2, count($all_files), 'Found two, expected javascript files.'); // Now use the nomask parameter to filter out the .script file. - $filtered_files = file_scan_directory($this->path, '/^javascript-/', array('nomask' => '/.script$/')); + $filtered_files = file_scan_directory($this->path, '/^javascript-/', ['nomask' => '/.script$/']); $this->assertEqual(1, count($filtered_files), 'Filtered correctly.'); } /** * Check that key parameter sets the return value's key. */ - function testOptionKey() { + public function testOptionKey() { // "filename", for the path starting with $dir. - $expected = array($this->path . '/javascript-1.txt', $this->path . '/javascript-2.script'); - $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', array('key' => 'filepath'))); + $expected = [$this->path . '/javascript-1.txt', $this->path . '/javascript-2.script']; + $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', ['key' => 'filepath'])); sort($actual); $this->assertEqual($expected, $actual, 'Returned the correct values for the filename key.'); // "basename", for the basename of the file. - $expected = array('javascript-1.txt', 'javascript-2.script'); - $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', array('key' => 'filename'))); + $expected = ['javascript-1.txt', 'javascript-2.script']; + $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', ['key' => 'filename'])); sort($actual); $this->assertEqual($expected, $actual, 'Returned the correct values for the basename key.'); // "name" for the name of the file without an extension. - $expected = array('javascript-1', 'javascript-2'); - $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', array('key' => 'name'))); + $expected = ['javascript-1', 'javascript-2']; + $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', ['key' => 'name'])); sort($actual); $this->assertEqual($expected, $actual, 'Returned the correct values for the name key.'); // Invalid option that should default back to "filename". - $expected = array($this->path . '/javascript-1.txt', $this->path . '/javascript-2.script'); - $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', array('key' => 'INVALID'))); + $expected = [$this->path . '/javascript-1.txt', $this->path . '/javascript-2.script']; + $actual = array_keys(file_scan_directory($this->path, '/^javascript-/', ['key' => 'INVALID'])); sort($actual); $this->assertEqual($expected, $actual, 'An invalid key defaulted back to the default.'); } @@ -121,11 +121,11 @@ function testOptionKey() { /** * Check that the recurse option descends into subdirectories. */ - function testOptionRecurse() { - $files = file_scan_directory($this->path . '/..', '/^javascript-/', array('recurse' => FALSE)); + public function testOptionRecurse() { + $files = file_scan_directory($this->path . '/..', '/^javascript-/', ['recurse' => FALSE]); $this->assertTrue(empty($files), "Without recursion couldn't find javascript files."); - $files = file_scan_directory($this->path . '/..', '/^javascript-/', array('recurse' => TRUE)); + $files = file_scan_directory($this->path . '/..', '/^javascript-/', ['recurse' => TRUE]); $this->assertEqual(2, count($files), 'With recursion we found the expected javascript files.'); } @@ -134,11 +134,11 @@ function testOptionRecurse() { * Check that the min_depth options lets us ignore files in the starting * directory. */ - function testOptionMinDepth() { - $files = file_scan_directory($this->path, '/^javascript-/', array('min_depth' => 0)); + public function testOptionMinDepth() { + $files = file_scan_directory($this->path, '/^javascript-/', ['min_depth' => 0]); $this->assertEqual(2, count($files), 'No minimum-depth gets files in current directory.'); - $files = file_scan_directory($this->path, '/^javascript-/', array('min_depth' => 1)); + $files = file_scan_directory($this->path, '/^javascript-/', ['min_depth' => 1]); $this->assertTrue(empty($files), 'Minimum-depth of 1 successfully excludes files from current directory.'); } diff --git a/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php b/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php index e9c86424..6c18b665 100644 --- a/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php @@ -19,7 +19,7 @@ class StreamWrapperTest extends FileTestBase { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * A stream wrapper scheme to register for the test. @@ -35,7 +35,7 @@ class StreamWrapperTest extends FileTestBase { */ protected $classname = 'Drupal\file_test\StreamWrapper\DummyStreamWrapper'; - function setUp() { + public function setUp() { parent::setUp(); // Add file_private_path setting. @@ -47,7 +47,7 @@ function setUp() { /** * Test the getClassName() function. */ - function testGetClassName() { + public function testGetClassName() { // Check the dummy scheme. $this->assertEqual($this->classname, \Drupal::service('stream_wrapper_manager')->getClass($this->scheme), 'Got correct class name for dummy scheme.'); // Check core's scheme. @@ -57,7 +57,7 @@ function testGetClassName() { /** * Test the getViaScheme() method. */ - function testGetInstanceByScheme() { + public function testGetInstanceByScheme() { $instance = \Drupal::service('stream_wrapper_manager')->getViaScheme($this->scheme); $this->assertEqual($this->classname, get_class($instance), 'Got correct class type for dummy scheme.'); @@ -68,7 +68,7 @@ function testGetInstanceByScheme() { /** * Test the getViaUri() and getViaScheme() methods and target functions. */ - function testUriFunctions() { + public function testUriFunctions() { $config = $this->config('system.file'); $instance = \Drupal::service('stream_wrapper_manager')->getViaUri($this->scheme . '://foo'); @@ -104,7 +104,7 @@ function testUriFunctions() { /** * Test some file handle functions. */ - function testFileFunctions() { + public function testFileFunctions() { $filename = 'public://' . $this->randomMachineName(); file_put_contents($filename, str_repeat('d', 1000)); @@ -119,7 +119,7 @@ function testFileFunctions() { $this->assertEqual(-1 /*EOF*/, @stream_set_write_buffer($handle, 512), 'Unable to set write buffer using a local stream wrapper.'); // This will test stream_cast(). - $read = array($handle); + $read = [$handle]; $write = NULL; $except = NULL; $this->assertEqual(1, stream_select($read, $write, $except, 0), 'Able to cast a stream via stream_select.'); @@ -136,7 +136,7 @@ function testFileFunctions() { /** * Test the scheme functions. */ - function testGetValidStreamScheme() { + public function testGetValidStreamScheme() { $this->assertEqual('foo', file_uri_scheme('foo://pork//chops'), 'Got the correct scheme from foo://asdf'); $this->assertEqual('data', file_uri_scheme('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='), 'Got the correct scheme from a data URI.'); $this->assertFalse(file_uri_scheme('foo/bar.txt'), 'foo/bar.txt is not a valid stream.'); diff --git a/core/tests/Drupal/KernelTests/Core/File/UnmanagedCopyTest.php b/core/tests/Drupal/KernelTests/Core/File/UnmanagedCopyTest.php index 6b2fbed2..d3c5cd4e 100644 --- a/core/tests/Drupal/KernelTests/Core/File/UnmanagedCopyTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/UnmanagedCopyTest.php @@ -14,7 +14,7 @@ class UnmanagedCopyTest extends FileTestBase { /** * Copy a normal file. */ - function testNormal() { + public function testNormal() { // Create a file for testing $uri = $this->createUri(); @@ -44,10 +44,10 @@ function testNormal() { /** * Copy a non-existent file. */ - function testNonExistent() { + public function testNonExistent() { // Copy non-existent file $desired_filepath = $this->randomMachineName(); - $this->assertFalse(file_exists($desired_filepath), "Randomly named file doesn't exists."); + $this->assertFalse(file_exists($desired_filepath), "Randomly named file doesn't exist."); $new_filepath = file_unmanaged_copy($desired_filepath, $this->randomMachineName()); $this->assertFalse($new_filepath, 'Copying a missing file fails.'); } @@ -55,7 +55,7 @@ function testNonExistent() { /** * Copy a file onto itself. */ - function testOverwriteSelf() { + public function testOverwriteSelf() { // Create a file for testing $uri = $this->createUri(); diff --git a/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteRecursiveTest.php b/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteRecursiveTest.php index feed31b5..64045fea 100644 --- a/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteRecursiveTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteRecursiveTest.php @@ -11,7 +11,7 @@ class UnmanagedDeleteRecursiveTest extends FileTestBase { /** * Delete a normal file. */ - function testSingleFile() { + public function testSingleFile() { // Create a file for testing $filepath = file_default_scheme() . '://' . $this->randomMachineName(); file_put_contents($filepath, ''); @@ -24,7 +24,7 @@ function testSingleFile() { /** * Try deleting an empty directory. */ - function testEmptyDirectory() { + public function testEmptyDirectory() { // A directory to operate on. $directory = $this->createDirectory(); @@ -36,7 +36,7 @@ function testEmptyDirectory() { /** * Try deleting a directory with some files. */ - function testDirectory() { + public function testDirectory() { // A directory to operate on. $directory = $this->createDirectory(); $filepathA = $directory . '/A'; @@ -54,7 +54,7 @@ function testDirectory() { /** * Try deleting subdirectories with some files. */ - function testSubDirectory() { + public function testSubDirectory() { // A directory to operate on. $directory = $this->createDirectory(); $subdirectory = $this->createDirectory($directory . '/sub'); diff --git a/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteTest.php b/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteTest.php index 55e45360..d1cfb2e7 100644 --- a/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/UnmanagedDeleteTest.php @@ -11,7 +11,7 @@ class UnmanagedDeleteTest extends FileTestBase { /** * Delete a normal file. */ - function testNormal() { + public function testNormal() { // Create a file for testing $uri = $this->createUri(); @@ -23,7 +23,7 @@ function testNormal() { /** * Try deleting a missing file. */ - function testMissing() { + public function testMissing() { // Try to delete a non-existing file $this->assertTrue(file_unmanaged_delete(file_default_scheme() . '/' . $this->randomMachineName()), 'Returns true when deleting a non-existent file.'); } @@ -31,7 +31,7 @@ function testMissing() { /** * Try deleting a directory. */ - function testDirectory() { + public function testDirectory() { // A directory to operate on. $directory = $this->createDirectory(); diff --git a/core/tests/Drupal/KernelTests/Core/File/UnmanagedMoveTest.php b/core/tests/Drupal/KernelTests/Core/File/UnmanagedMoveTest.php index 87a29f4a..8619a150 100644 --- a/core/tests/Drupal/KernelTests/Core/File/UnmanagedMoveTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/UnmanagedMoveTest.php @@ -14,7 +14,7 @@ class UnmanagedMoveTest extends FileTestBase { /** * Move a normal file. */ - function testNormal() { + public function testNormal() { // Create a file for testing $uri = $this->createUri(); @@ -45,7 +45,7 @@ function testNormal() { /** * Try to move a missing file. */ - function testMissing() { + public function testMissing() { // Move non-existent file. $new_filepath = file_unmanaged_move($this->randomMachineName(), $this->randomMachineName()); $this->assertFalse($new_filepath, 'Moving a missing file fails.'); @@ -54,7 +54,7 @@ function testMissing() { /** * Try to move a file onto itself. */ - function testOverwriteSelf() { + public function testOverwriteSelf() { // Create a file for testing. $uri = $this->createUri(); diff --git a/core/tests/Drupal/KernelTests/Core/File/UnmanagedSaveDataTest.php b/core/tests/Drupal/KernelTests/Core/File/UnmanagedSaveDataTest.php index dc06d2cb..54933233 100644 --- a/core/tests/Drupal/KernelTests/Core/File/UnmanagedSaveDataTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/UnmanagedSaveDataTest.php @@ -11,7 +11,7 @@ class UnmanagedSaveDataTest extends FileTestBase { /** * Test the file_unmanaged_save_data() function. */ - function testFileSaveData() { + public function testFileSaveData() { $contents = $this->randomMachineName(8); $this->setSetting('file_chmod_file', 0777); diff --git a/core/tests/Drupal/KernelTests/Core/File/UrlRewritingTest.php b/core/tests/Drupal/KernelTests/Core/File/UrlRewritingTest.php index 5494975a..bdf66bdd 100644 --- a/core/tests/Drupal/KernelTests/Core/File/UrlRewritingTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/UrlRewritingTest.php @@ -16,12 +16,12 @@ class UrlRewritingTest extends FileTestBase { * * @var array */ - public static $modules = array('file_test'); + public static $modules = ['file_test']; /** * Tests the rewriting of shipped file URLs by hook_file_url_alter(). */ - function testShippedFileURL() { + public function testShippedFileURL() { // Test generating a URL to a shipped file (i.e. a file that is part of // Drupal core, a module or a theme, for example a JavaScript file). @@ -68,7 +68,7 @@ function testShippedFileURL() { /** * Tests the rewriting of public managed file URLs by hook_file_url_alter(). */ - function testPublicManagedFileURL() { + public function testPublicManagedFileURL() { // Test generating a URL to a managed file. // Test alteration of file URLs to use a CDN. @@ -94,7 +94,7 @@ function testPublicManagedFileURL() { /** * Test file_url_transform_relative(). */ - function testRelativeFileURL() { + public function testRelativeFileURL() { // Disable file_test.module's hook_file_url_alter() implementation. \Drupal::state()->set('file_test.hook_file_url_alter', NULL); @@ -106,13 +106,13 @@ function testRelativeFileURL() { // Shipped file. $filepath = 'core/assets/vendor/jquery/jquery.min.js'; $url = file_create_url($filepath); - $this->assertIdentical(base_path() . $filepath, file_url_transform_relative($url)); + $this->assertSame(base_path() . $filepath, file_url_transform_relative($url)); // Managed file. $uri = $this->createUri(); $url = file_create_url($uri); $public_directory_path = \Drupal::service('stream_wrapper_manager')->getViaScheme('public')->getDirectoryPath(); - $this->assertIdentical(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url)); + $this->assertSame(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url)); } } diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php index fa86bee1..f6fb4f87 100644 --- a/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php +++ b/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php @@ -5,6 +5,7 @@ use Drupal\Core\Form\FormState; use Drupal\Core\Session\AnonymousUserSession; use Drupal\Core\Session\UserSession; +use Drupal\Core\Site\Settings; use Drupal\KernelTests\KernelTestBase; /** @@ -20,7 +21,7 @@ class FormCacheTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user'); + public static $modules = ['system', 'user']; /** * @var string @@ -39,12 +40,12 @@ class FormCacheTest extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('key_value_expire')); + $this->installSchema('system', ['key_value_expire']); $this->formBuildId = $this->randomMachineName(); - $this->form = array( + $this->form = [ '#property' => $this->randomMachineName(), - ); + ]; $this->formState = new FormState(); $this->formState->set('example', $this->randomMachineName()); } @@ -52,8 +53,8 @@ protected function setUp() { /** * Tests the form cache with a logged-in user. */ - function testCacheToken() { - \Drupal::currentUser()->setAccount(new UserSession(array('uid' => 1))); + public function testCacheToken() { + \Drupal::currentUser()->setAccount(new UserSession(['uid' => 1])); \Drupal::formBuilder()->setCache($this->formBuildId, $this->form, $this->formState); $cached_form_state = new FormState(); @@ -83,7 +84,7 @@ function testCacheToken() { /** * Tests the form cache without a logged-in user. */ - function testNoCacheToken() { + public function testNoCacheToken() { // Switch to a anonymous user account. $account_switcher = \Drupal::service('account_switcher'); $account_switcher->switchTo(new AnonymousUserSession()); @@ -101,4 +102,16 @@ function testNoCacheToken() { $account_switcher->switchBack(); } + /** + * Tests the form cache with an overridden cache expiration. + */ + public function testCacheCustomExpiration() { + // Override form cache expiration so that the cached form expired yesterday. + new Settings(['form_cache_expiration' => -1 * (24 * 60 * 60), 'hash_salt' => $this->randomMachineName()]); + \Drupal::formBuilder()->setCache($this->formBuildId, $this->form, $this->formState); + + $cached_form_state = new FormState(); + $this->assertFalse(\Drupal::formBuilder()->getCache($this->formBuildId, $cached_form_state), 'Expired form not returned from cache'); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php index 7f046e9d..6d79f17c 100644 --- a/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php +++ b/core/tests/Drupal/KernelTests/Core/Form/FormDefaultHandlersTest.php @@ -19,7 +19,7 @@ class FormDefaultHandlersTest extends KernelTestBase implements FormInterface { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * {@inheritdoc} @@ -42,7 +42,7 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { $form['#validate'][] = '::customValidateForm'; $form['#submit'][] = '::customSubmitForm'; - $form['submit'] = array('#type' => 'submit', '#value' => 'Save'); + $form['submit'] = ['#type' => 'submit', '#value' => 'Save']; return $form; } @@ -85,7 +85,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { /** * Tests that default handlers are added even if custom are specified. */ - function testDefaultAndCustomHandlers() { + public function testDefaultAndCustomHandlers() { $form_state = new FormState(); $form_builder = $this->container->get('form_builder'); $form_builder->submitForm($this, $form_state); diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormValidationMessageOrderTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormValidationMessageOrderTest.php new file mode 100644 index 00000000..1d203408 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Form/FormValidationMessageOrderTest.php @@ -0,0 +1,92 @@ + 'textfield', + '#title' => 'One', + '#required' => TRUE, + '#weight' => 40, + ]; + $form['two'] = [ + '#type' => 'textfield', + '#title' => 'Two', + '#required' => TRUE, + '#weight' => 30, + ]; + $form['three'] = [ + '#type' => 'textfield', + '#title' => 'Three', + '#required' => TRUE, + '#weight' => 10, + ]; + $form['four'] = [ + '#type' => 'textfield', + '#title' => 'Four', + '#required' => TRUE, + '#weight' => 20, + ]; + $form['actions'] = [ + '#type' => 'actions', + 'submit' => [ + '#type' => 'submit', + '#value' => 'Submit', + ], + ]; + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + } + + /** + * Tests that fields validation messages are sorted in the fields order. + */ + public function testLimitValidationErrors() { + $form_state = new FormState(); + $form_builder = $this->container->get('form_builder'); + $form_builder->submitForm($this, $form_state); + + $messages = drupal_get_messages(); + $this->assertTrue(isset($messages['error'])); + $error_messages = $messages['error']; + $this->assertEqual($error_messages[0], 'Three field is required.'); + $this->assertEqual($error_messages[1], 'Four field is required.'); + $this->assertEqual($error_messages[2], 'Two field is required.'); + $this->assertEqual($error_messages[3], 'One field is required.'); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Form/TriggeringElementProgrammedTest.php b/core/tests/Drupal/KernelTests/Core/Form/TriggeringElementProgrammedTest.php index c24d47e0..b2552c8c 100644 --- a/core/tests/Drupal/KernelTests/Core/Form/TriggeringElementProgrammedTest.php +++ b/core/tests/Drupal/KernelTests/Core/Form/TriggeringElementProgrammedTest.php @@ -25,27 +25,27 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['one'] = array( + $form['one'] = [ '#type' => 'textfield', '#title' => 'One', '#required' => TRUE, - ); - $form['two'] = array( + ]; + $form['two'] = [ '#type' => 'textfield', '#title' => 'Two', '#required' => TRUE, - ); - $form['actions'] = array('#type' => 'actions'); + ]; + $form['actions'] = ['#type' => 'actions']; $user_input = $form_state->getUserInput(); - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => 'Save', - '#limit_validation_errors' => array( - array($user_input['section']), - ), + '#limit_validation_errors' => [ + [$user_input['section']], + ], // Required for #limit_validation_errors. - '#submit' => array(array($this, 'submitForm')), - ); + '#submit' => [[$this, 'submitForm']], + ]; return $form; } @@ -66,7 +66,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { /** * Tests that #limit_validation_errors of the only submit button takes effect. */ - function testLimitValidationErrors() { + public function testLimitValidationErrors() { // Programmatically submit the form. $form_state = new FormState(); $form_state->setValue('section', 'one'); diff --git a/core/tests/Drupal/KernelTests/Core/Http/LinkRelationsTest.php b/core/tests/Drupal/KernelTests/Core/Http/LinkRelationsTest.php new file mode 100644 index 00000000..d01537b7 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Http/LinkRelationsTest.php @@ -0,0 +1,52 @@ +container->get('plugin.manager.link_relation_type'); + + // An link relation type of the "registered" kind. + /** @var \Drupal\Core\Http\LinkRelationTypeInterface $canonical */ + $canonical = $link_relation_type_manager->createInstance('canonical'); + $this->assertInstanceOf(LinkRelationType::class, $canonical); + $this->assertTrue($canonical->isRegistered()); + $this->assertFalse($canonical->isExtension()); + $this->assertSame('canonical', $canonical->getRegisteredName()); + $this->assertNull($canonical->getExtensionUri()); + $this->assertEquals('[RFC6596]', $canonical->getReference()); + $this->assertEquals('Designates the preferred version of a resource (the IRI and its contents).', $canonical->getDescription()); + $this->assertEquals('', $canonical->getNotes()); + + // An link relation type of the "extension" kind. + /** @var \Drupal\Core\Http\LinkRelationTypeInterface $canonical */ + $add_form = $link_relation_type_manager->createInstance('add-form'); + $this->assertInstanceOf(LinkRelationType::class, $add_form); + $this->assertFalse($add_form->isRegistered()); + $this->assertTrue($add_form->isExtension()); + $this->assertNull($add_form->getRegisteredName()); + $this->assertSame('https://drupal.org/link-relations/add-form', $add_form->getExtensionUri()); + $this->assertEquals('', $add_form->getReference()); + $this->assertEquals('A form where a resource of this type can be created.', $add_form->getDescription()); + $this->assertEquals('', $add_form->getNotes()); + + // Test a couple of examples. + $this->assertContains('about', array_keys($link_relation_type_manager->getDefinitions())); + $this->assertContains('original', array_keys($link_relation_type_manager->getDefinitions())); + $this->assertContains('type', array_keys($link_relation_type_manager->getDefinitions())); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/HttpKernel/CorsIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/HttpKernel/CorsIntegrationTest.php deleted file mode 100644 index e73efa3b..00000000 --- a/core/tests/Drupal/KernelTests/Core/HttpKernel/CorsIntegrationTest.php +++ /dev/null @@ -1,84 +0,0 @@ -installSchema('system', 'router'); - \Drupal::service('router.builder')->rebuild(); - } - - public function testCrossSiteRequest() { - - // Test default parameters. - $cors_config = $this->container->getParameter('cors.config'); - $this->assertSame(FALSE, $cors_config['enabled']); - $this->assertSame([], $cors_config['allowedHeaders']); - $this->assertSame([], $cors_config['allowedMethods']); - $this->assertSame(['*'], $cors_config['allowedOrigins']); - - $this->assertSame(FALSE, $cors_config['exposedHeaders']); - $this->assertSame(FALSE, $cors_config['maxAge']); - $this->assertSame(FALSE, $cors_config['supportsCredentials']); - - // Configure the CORS stack to allow a specific set of origins, but don't - // specify an origin header. - $request = Request::create('/test-page'); - $request->headers->set('Origin', ''); - $cors_config['enabled'] = TRUE; - $cors_config['allowedOrigins'] = ['http://example.com']; - - $this->corsConfig = $cors_config; - $this->container->get('kernel')->rebuildContainer(); - - /** @var \Symfony\Component\HttpFoundation\Response $response */ - $response = $this->container->get('http_kernel')->handle($request); - $this->assertEquals(Response::HTTP_FORBIDDEN, $response->getStatusCode()); - $this->assertEquals('Not allowed.', $response->getContent()); - - // Specify a valid origin. - $request->headers->set('Origin', 'http://example.com'); - $response = $this->container->get('http_kernel')->handle($request); - $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); - } - - /** - * {@inheritdoc} - */ - public function alter(ContainerBuilder $container) { - if (isset($this->corsConfig)) { - $container->setParameter('cors.config', $this->corsConfig); - } - } - -} diff --git a/core/tests/Drupal/KernelTests/Core/HttpKernel/StackKernelIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/HttpKernel/StackKernelIntegrationTest.php index 166ec244..29bbcff9 100644 --- a/core/tests/Drupal/KernelTests/Core/HttpKernel/StackKernelIntegrationTest.php +++ b/core/tests/Drupal/KernelTests/Core/HttpKernel/StackKernelIntegrationTest.php @@ -19,7 +19,7 @@ class StackKernelIntegrationTest extends KernelTestBase { * * @var array */ - public static $modules = array('httpkernel_test', 'system'); + public static $modules = ['httpkernel_test', 'system']; /** * {@inheritdoc} diff --git a/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php b/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php index fe36c3dc..d283d9b4 100644 --- a/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php +++ b/core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php @@ -23,16 +23,16 @@ class ToolkitGdTest extends KernelTestBase { protected $imageFactory; // Colors that are used in testing. - protected $black = array(0, 0, 0, 0); - protected $red = array(255, 0, 0, 0); - protected $green = array(0, 255, 0, 0); - protected $blue = array(0, 0, 255, 0); - protected $yellow = array(255, 255, 0, 0); - protected $white = array(255, 255, 255, 0); - protected $transparent = array(0, 0, 0, 127); + protected $black = [0, 0, 0, 0]; + protected $red = [255, 0, 0, 0]; + protected $green = [0, 255, 0, 0]; + protected $blue = [0, 0, 255, 0]; + protected $yellow = [255, 255, 0, 0]; + protected $white = [255, 255, 255, 0]; + protected $transparent = [0, 0, 0, 127]; // Used as rotate background colors. - protected $fuchsia = array(255, 0, 255, 0); - protected $rotateTransparent = array(255, 255, 255, 127); + protected $fuchsia = [255, 0, 255, 0]; + protected $rotateTransparent = [255, 255, 255, 127]; protected $width = 40; protected $height = 20; @@ -42,7 +42,7 @@ class ToolkitGdTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'simpletest'); + public static $modules = ['system', 'simpletest']; /** * {@inheritdoc} @@ -57,9 +57,9 @@ protected function setUp() { protected function checkRequirements() { // GD2 support is available. if (!function_exists('imagegd2')) { - return array( + return [ 'Image manipulations for the GD toolkit cannot run because the GD toolkit is not available.', - ); + ]; } return parent::checkRequirements(); } @@ -67,7 +67,7 @@ protected function checkRequirements() { /** * Function to compare two colors by RGBa. */ - function colorsAreEqual($color_a, $color_b) { + public function colorsAreEqual($color_a, $color_b) { // Fully transparent pixels are equal, regardless of RGB. if ($color_a[3] == 127 && $color_b[3] == 127) { return TRUE; @@ -85,13 +85,13 @@ function colorsAreEqual($color_a, $color_b) { /** * Function for finding a pixel's RGBa values. */ - function getPixelColor(ImageInterface $image, $x, $y) { + public function getPixelColor(ImageInterface $image, $x, $y) { $toolkit = $image->getToolkit(); $color_index = imagecolorat($toolkit->getResource(), $x, $y); $transparent_index = imagecolortransparent($toolkit->getResource()); if ($color_index == $transparent_index) { - return array(0, 0, 0, 127); + return [0, 0, 0, 127]; } return array_values(imagecolorsforindex($toolkit->getResource(), $color_index)); @@ -102,7 +102,7 @@ function getPixelColor(ImageInterface $image, $x, $y) { * properly, build a list of expected color values for each of the corners and * the expected height and widths for the final images. */ - function testManipulations() { + public function testManipulations() { // Test that the image factory is set to use the GD toolkit. $this->assertEqual($this->imageFactory->getToolkitId(), 'gd', 'The image factory is set to use the \'gd\' image toolkit.'); @@ -129,143 +129,145 @@ function testManipulations() { // Typically the corner colors will be unchanged. These colors are in the // order of top-left, top-right, bottom-right, bottom-left. - $default_corners = array($this->red, $this->green, $this->blue, $this->transparent); + $default_corners = [$this->red, $this->green, $this->blue, $this->transparent]; // A list of files that will be tested. - $files = array( + $files = [ 'image-test.png', 'image-test.gif', 'image-test-no-transparency.gif', 'image-test.jpg', - ); + ]; // Setup a list of tests to perform on each type. - $operations = array( - 'resize' => array( + $operations = [ + 'resize' => [ 'function' => 'resize', - 'arguments' => array('width' => 20, 'height' => 10), + 'arguments' => ['width' => 20, 'height' => 10], 'width' => 20, 'height' => 10, 'corners' => $default_corners, - ), - 'scale_x' => array( + ], + 'scale_x' => [ 'function' => 'scale', - 'arguments' => array('width' => 20), + 'arguments' => ['width' => 20], 'width' => 20, 'height' => 10, 'corners' => $default_corners, - ), - 'scale_y' => array( + ], + 'scale_y' => [ 'function' => 'scale', - 'arguments' => array('height' => 10), + 'arguments' => ['height' => 10], 'width' => 20, 'height' => 10, 'corners' => $default_corners, - ), - 'upscale_x' => array( + ], + 'upscale_x' => [ 'function' => 'scale', - 'arguments' => array('width' => 80, 'upscale' => TRUE), + 'arguments' => ['width' => 80, 'upscale' => TRUE], 'width' => 80, 'height' => 40, 'corners' => $default_corners, - ), - 'upscale_y' => array( + ], + 'upscale_y' => [ 'function' => 'scale', - 'arguments' => array('height' => 40, 'upscale' => TRUE), + 'arguments' => ['height' => 40, 'upscale' => TRUE], 'width' => 80, 'height' => 40, 'corners' => $default_corners, - ), - 'crop' => array( + ], + 'crop' => [ 'function' => 'crop', - 'arguments' => array('x' => 12, 'y' => 4, 'width' => 16, 'height' => 12), + 'arguments' => ['x' => 12, 'y' => 4, 'width' => 16, 'height' => 12], 'width' => 16, 'height' => 12, 'corners' => array_fill(0, 4, $this->white), - ), - 'scale_and_crop' => array( + ], + 'scale_and_crop' => [ 'function' => 'scale_and_crop', - 'arguments' => array('width' => 10, 'height' => 8), + 'arguments' => ['width' => 10, 'height' => 8], 'width' => 10, 'height' => 8, 'corners' => array_fill(0, 4, $this->black), - ), - 'convert_jpg' => array( + ], + 'convert_jpg' => [ 'function' => 'convert', 'width' => 40, 'height' => 20, - 'arguments' => array('extension' => 'jpeg'), + 'arguments' => ['extension' => 'jpeg'], 'corners' => $default_corners, - ), - 'convert_gif' => array( + ], + 'convert_gif' => [ 'function' => 'convert', 'width' => 40, 'height' => 20, - 'arguments' => array('extension' => 'gif'), + 'arguments' => ['extension' => 'gif'], 'corners' => $default_corners, - ), - 'convert_png' => array( + ], + 'convert_png' => [ 'function' => 'convert', 'width' => 40, 'height' => 20, - 'arguments' => array('extension' => 'png'), + 'arguments' => ['extension' => 'png'], 'corners' => $default_corners, - ), - ); + ], + ]; // Systems using non-bundled GD2 don't have imagerotate. Test if available. if (function_exists('imagerotate')) { - $operations += array( - 'rotate_5' => array( + $operations += [ + 'rotate_5' => [ 'function' => 'rotate', - 'arguments' => array('degrees' => 5, 'background' => '#FF00FF'), // Fuchsia background. + // Fuchsia background. + 'arguments' => ['degrees' => 5, 'background' => '#FF00FF'], 'width' => 41, 'height' => 23, 'corners' => array_fill(0, 4, $this->fuchsia), - ), - 'rotate_90' => array( + ], + 'rotate_90' => [ 'function' => 'rotate', - 'arguments' => array('degrees' => 90, 'background' => '#FF00FF'), // Fuchsia background. + // Fuchsia background. + 'arguments' => ['degrees' => 90, 'background' => '#FF00FF'], 'width' => 20, 'height' => 40, - 'corners' => array($this->transparent, $this->red, $this->green, $this->blue), - ), - 'rotate_transparent_5' => array( + 'corners' => [$this->transparent, $this->red, $this->green, $this->blue], + ], + 'rotate_transparent_5' => [ 'function' => 'rotate', - 'arguments' => array('degrees' => 5), + 'arguments' => ['degrees' => 5], 'width' => 41, 'height' => 23, 'corners' => array_fill(0, 4, $this->rotateTransparent), - ), - 'rotate_transparent_90' => array( + ], + 'rotate_transparent_90' => [ 'function' => 'rotate', - 'arguments' => array('degrees' => 90), + 'arguments' => ['degrees' => 90], 'width' => 20, 'height' => 40, - 'corners' => array($this->transparent, $this->red, $this->green, $this->blue), - ), - ); + 'corners' => [$this->transparent, $this->red, $this->green, $this->blue], + ], + ]; } // Systems using non-bundled GD2 don't have imagefilter. Test if available. if (function_exists('imagefilter')) { - $operations += array( - 'desaturate' => array( + $operations += [ + 'desaturate' => [ 'function' => 'desaturate', - 'arguments' => array(), + 'arguments' => [], 'height' => 20, 'width' => 40, // Grayscale corners are a bit funky. Each of the corners are a shade of // gray. The values of these were determined simply by looking at the // final image to see what desaturated colors end up being. - 'corners' => array( - array_fill(0, 3, 76) + array(3 => 0), - array_fill(0, 3, 149) + array(3 => 0), - array_fill(0, 3, 29) + array(3 => 0), - array_fill(0, 3, 225) + array(3 => 127) - ), - ), - ); + 'corners' => [ + array_fill(0, 3, 76) + [3 => 0], + array_fill(0, 3, 149) + [3 => 0], + array_fill(0, 3, 29) + [3 => 0], + array_fill(0, 3, 225) + [3 => 127] + ], + ], + ]; } // Prepare a directory for test file results. @@ -278,14 +280,14 @@ function testManipulations() { $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/' . $file); $toolkit = $image->getToolkit(); if (!$image->isValid()) { - $this->fail(SafeMarkup::format('Could not load image %file.', array('%file' => $file))); + $this->fail(SafeMarkup::format('Could not load image %file.', ['%file' => $file])); continue 2; } $image_original_type = $image->getToolkit()->getType(); // All images should be converted to truecolor when loaded. $image_truecolor = imageistruecolor($toolkit->getResource()); - $this->assertTrue($image_truecolor, SafeMarkup::format('Image %file after load is a truecolor image.', array('%file' => $file))); + $this->assertTrue($image_truecolor, SafeMarkup::format('Image %file after load is a truecolor image.', ['%file' => $file])); // Store the original GD resource. $old_res = $toolkit->getResource(); @@ -317,8 +319,8 @@ function testManipulations() { $file_path = $directory . '/' . $op . image_type_to_extension($image->getToolkit()->getType()); $image->save($file_path); - $this->assertTrue($correct_dimensions_real, SafeMarkup::format('Image %file after %action action has proper dimensions.', array('%file' => $file, '%action' => $op))); - $this->assertTrue($correct_dimensions_object, SafeMarkup::format('Image %file object after %action action is reporting the proper height and width values.', array('%file' => $file, '%action' => $op))); + $this->assertTrue($correct_dimensions_real, SafeMarkup::format('Image %file after %action action has proper dimensions.', ['%file' => $file, '%action' => $op])); + $this->assertTrue($correct_dimensions_object, SafeMarkup::format('Image %file object after %action action is reporting the proper height and width values.', ['%file' => $file, '%action' => $op])); // JPEG colors will always be messed up due to compression. So we skip // these tests if the original or the result is in jpeg format. @@ -365,7 +367,7 @@ function testManipulations() { if ($image->getToolkit()->getType() == $image_original_type || $corner != $this->transparent) { $correct_colors = $this->colorsAreEqual($color, $corner); $this->assertTrue($correct_colors, SafeMarkup::format('Image %file object after %action action has the correct color placement at corner %corner.', - array('%file' => $file, '%action' => $op, '%corner' => $key))); + ['%file' => $file, '%action' => $op, '%corner' => $key])); } } } @@ -377,30 +379,30 @@ function testManipulations() { } // Test creation of image from scratch, and saving to storage. - foreach (array(IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_JPEG) as $type) { + foreach ([IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_JPEG] as $type) { $image = $this->imageFactory->get(); $image->createNew(50, 20, image_type_to_extension($type, FALSE), '#ffff00'); $file = 'from_null' . image_type_to_extension($type); $file_path = $directory . '/' . $file ; - $this->assertEqual(50, $image->getWidth(), SafeMarkup::format('Image file %file has the correct width.', array('%file' => $file))); - $this->assertEqual(20, $image->getHeight(), SafeMarkup::format('Image file %file has the correct height.', array('%file' => $file))); - $this->assertEqual(image_type_to_mime_type($type), $image->getMimeType(), SafeMarkup::format('Image file %file has the correct MIME type.', array('%file' => $file))); - $this->assertTrue($image->save($file_path), SafeMarkup::format('Image %file created anew from a null image was saved.', array('%file' => $file))); + $this->assertEqual(50, $image->getWidth(), SafeMarkup::format('Image file %file has the correct width.', ['%file' => $file])); + $this->assertEqual(20, $image->getHeight(), SafeMarkup::format('Image file %file has the correct height.', ['%file' => $file])); + $this->assertEqual(image_type_to_mime_type($type), $image->getMimeType(), SafeMarkup::format('Image file %file has the correct MIME type.', ['%file' => $file])); + $this->assertTrue($image->save($file_path), SafeMarkup::format('Image %file created anew from a null image was saved.', ['%file' => $file])); // Reload saved image. $image_reloaded = $this->imageFactory->get($file_path); if (!$image_reloaded->isValid()) { - $this->fail(SafeMarkup::format('Could not load image %file.', array('%file' => $file))); + $this->fail(SafeMarkup::format('Could not load image %file.', ['%file' => $file])); continue; } - $this->assertEqual(50, $image_reloaded->getWidth(), SafeMarkup::format('Image file %file has the correct width.', array('%file' => $file))); - $this->assertEqual(20, $image_reloaded->getHeight(), SafeMarkup::format('Image file %file has the correct height.', array('%file' => $file))); - $this->assertEqual(image_type_to_mime_type($type), $image_reloaded->getMimeType(), SafeMarkup::format('Image file %file has the correct MIME type.', array('%file' => $file))); + $this->assertEqual(50, $image_reloaded->getWidth(), SafeMarkup::format('Image file %file has the correct width.', ['%file' => $file])); + $this->assertEqual(20, $image_reloaded->getHeight(), SafeMarkup::format('Image file %file has the correct height.', ['%file' => $file])); + $this->assertEqual(image_type_to_mime_type($type), $image_reloaded->getMimeType(), SafeMarkup::format('Image file %file has the correct MIME type.', ['%file' => $file])); if ($image_reloaded->getToolkit()->getType() == IMAGETYPE_GIF) { - $this->assertEqual('#ffff00', $image_reloaded->getToolkit()->getTransparentColor(), SafeMarkup::format('Image file %file has the correct transparent color channel set.', array('%file' => $file))); + $this->assertEqual('#ffff00', $image_reloaded->getToolkit()->getTransparentColor(), SafeMarkup::format('Image file %file has the correct transparent color channel set.', ['%file' => $file])); } else { - $this->assertEqual(NULL, $image_reloaded->getToolkit()->getTransparentColor(), SafeMarkup::format('Image file %file has no color channel set.', array('%file' => $file))); + $this->assertEqual(NULL, $image_reloaded->getToolkit()->getTransparentColor(), SafeMarkup::format('Image file %file has no color channel set.', ['%file' => $file])); } } @@ -443,7 +445,7 @@ public function testResourceDestruction() { /** * Tests for GIF images with transparency. */ - function testGifTransparentImages() { + public function testGifTransparentImages() { // Prepare a directory for test file results. $directory = Settings::get('file_public_path') . '/imagetest'; file_prepare_directory($directory, FILE_CREATE_DIRECTORY); @@ -496,19 +498,19 @@ function testGifTransparentImages() { $toolkit = $image->getToolkit(); if (!$image->isValid()) { - $this->fail(SafeMarkup::format('Could not load image %file.', array('%file' => $file))); + $this->fail(SafeMarkup::format('Could not load image %file.', ['%file' => $file])); } else { // All images should be converted to truecolor when loaded. $image_truecolor = imageistruecolor($toolkit->getResource()); - $this->assertTrue($image_truecolor, SafeMarkup::format('Image %file after load is a truecolor image.', array('%file' => $file))); + $this->assertTrue($image_truecolor, SafeMarkup::format('Image %file after load is a truecolor image.', ['%file' => $file])); } } /** * Tests calling a missing image operation plugin. */ - function testMissingOperation() { + public function testMissingOperation() { // Test that the image factory is set to use the GD toolkit. $this->assertEqual($this->imageFactory->getToolkitId(), 'gd', 'The image factory is set to use the \'gd\' image toolkit.'); @@ -519,11 +521,11 @@ function testMissingOperation() { // Load up a fresh image. $image = $this->imageFactory->get(drupal_get_path('module', 'simpletest') . '/files/' . $file); if (!$image->isValid()) { - $this->fail(SafeMarkup::format('Could not load image %file.', array('%file' => $file))); + $this->fail(SafeMarkup::format('Could not load image %file.', ['%file' => $file])); } // Try perform a missing toolkit operation. - $this->assertFalse($image->apply('missing_op', array()), 'Calling a missing image toolkit operation plugin fails.'); + $this->assertFalse($image->apply('missing_op', []), 'Calling a missing image toolkit operation plugin fails.'); } } diff --git a/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php index 060ee46f..3f911938 100644 --- a/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php @@ -15,24 +15,24 @@ class InstallerLanguageTest extends KernelTestBase { /** * Tests that the installer can find translation files. */ - function testInstallerTranslationFiles() { + public function testInstallerTranslationFiles() { // Different translation files would be found depending on which language // we are looking for. - $expected_translation_files = array( - NULL => array('drupal-8.0.0-beta2.hu.po', 'drupal-8.0.0.de.po'), - 'de' => array('drupal-8.0.0.de.po'), - 'hu' => array('drupal-8.0.0-beta2.hu.po'), - 'it' => array(), - ); + $expected_translation_files = [ + NULL => ['drupal-8.0.0-beta2.hu.po', 'drupal-8.0.0.de.po'], + 'de' => ['drupal-8.0.0.de.po'], + 'hu' => ['drupal-8.0.0-beta2.hu.po'], + 'it' => [], + ]; // Hardcode the simpletest module location as we don't yet know where it is. // @todo Remove as part of https://www.drupal.org/node/2186491 $file_translation = new FileTranslation('core/modules/simpletest/files/translations'); foreach ($expected_translation_files as $langcode => $files_expected) { $files_found = $file_translation->findTranslationFiles($langcode); - $this->assertTrue(count($files_found) == count($files_expected), format_string('@count installer languages found.', array('@count' => count($files_expected)))); + $this->assertTrue(count($files_found) == count($files_expected), format_string('@count installer languages found.', ['@count' => count($files_expected)])); foreach ($files_found as $file) { - $this->assertTrue(in_array($file->filename, $files_expected), format_string('@file found.', array('@file' => $file->filename))); + $this->assertTrue(in_array($file->filename, $files_expected), format_string('@file found.', ['@file' => $file->filename])); } } } @@ -40,7 +40,7 @@ function testInstallerTranslationFiles() { /** * Tests profile info caching in non-English languages. */ - function testInstallerTranslationCache() { + public function testInstallerTranslationCache() { require_once 'core/includes/install.inc'; // Prime the drupal_get_filename() static cache with the location of the diff --git a/core/tests/Drupal/KernelTests/Core/Installer/InstallerRedirectTraitTest.php b/core/tests/Drupal/KernelTests/Core/Installer/InstallerRedirectTraitTest.php new file mode 100644 index 00000000..1a24edaf --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerRedirectTraitTest.php @@ -0,0 +1,128 @@ +getMockBuilder(InstallerRedirectTrait::class) + ->setMethods(['isCli']) + ->getMockForTrait(); + + // Make sure that the method thinks we are not using the cli. + $trait->expects($this->any()) + ->method('isCli') + ->willReturn(FALSE); + + // Un-protect the method using reflection. + $method_ref = new \ReflectionMethod($trait, 'shouldRedirectToInstaller'); + $method_ref->setAccessible(TRUE); + + // Mock the database connection info. + $db = $this->getMockForAbstractClass(Database::class); + $property_ref = new \ReflectionProperty($db, 'databaseInfo'); + $property_ref->setAccessible(TRUE); + $property_ref->setValue($db, ['default' => $connection_info]); + + if ($connection) { + // Mock the database connection. + $connection = $this->getMockBuilder(Connection::class) + ->disableOriginalConstructor() + ->setMethods(['schema']) + ->getMockForAbstractClass(); + + if ($connection_info) { + // Mock the database schema class. + $schema = $this->getMockBuilder(Schema::class) + ->disableOriginalConstructor() + ->setMethods(['tableExists']) + ->getMockForAbstractClass(); + + $schema->expects($this->any()) + ->method('tableExists') + ->with('sessions') + ->willReturn($session_table_exists); + + $connection->expects($this->any()) + ->method('schema') + ->willReturn($schema); + } + } + else { + // Set the database connection if there is none. + $connection = NULL; + } + + // Call shouldRedirectToInstaller. + $this->assertSame($expected, $method_ref->invoke($trait, $e, $connection)); + } + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php index 16315010..26a1abef 100644 --- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php +++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageExpirableTest.php @@ -17,12 +17,12 @@ class DatabaseStorageExpirableTest extends StorageTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; protected function setUp() { parent::setUp(); $this->factory = 'keyvalue.expirable'; - $this->installSchema('system', array('key_value_expire')); + $this->installSchema('system', ['key_value_expire']); } /** @@ -60,12 +60,12 @@ public function testCRUDWithExpiration() { $this->assertIdenticalObject($this->objects[2], $stores[1]->get('foo')); // Verify that multiple items can be stored with setMultipleWithExpire(). - $values = array( + $values = [ 'foo' => $this->objects[3], 'bar' => $this->objects[4], - ); + ]; $stores[0]->setMultipleWithExpire($values, rand(500, 100000)); - $result = $stores[0]->getMultiple(array('foo', 'bar')); + $result = $stores[0]->getMultiple(['foo', 'bar']); foreach ($values as $j => $value) { $this->assertIdenticalObject($value, $result[$j]); } @@ -78,20 +78,20 @@ public function testCRUDWithExpiration() { // Ensure that an item with the same name exists in the other collection. $stores[1]->set('foo', $this->objects[5]); $result = $stores[0]->getAll(); - // Not using assertIdentical(), since the order is not defined for getAll(). + // Not using assertSame(), since the order is not defined for getAll(). $this->assertEqual(count($result), count($values)); foreach ($result as $key => $value) { $this->assertEqual($values[$key], $value); } // Verify that all items in the other collection are different. $result = $stores[1]->getAll(); - $this->assertEqual($result, array('foo' => $this->objects[5])); + $this->assertEqual($result, ['foo' => $this->objects[5]]); // Verify that multiple items can be deleted. $stores[0]->deleteMultiple(array_keys($values)); $this->assertFalse($stores[0]->get('foo')); $this->assertFalse($stores[0]->get('bar')); - $this->assertFalse($stores[0]->getMultiple(array('foo', 'bar'))); + $this->assertFalse($stores[0]->getMultiple(['foo', 'bar'])); // Verify that the item in the other collection still exists. $this->assertIdenticalObject($this->objects[5], $stores[1]->get('foo')); @@ -132,16 +132,16 @@ public function testExpiration() { $this->assertFalse($stores[0]->get('yesterday')); $this->assertTrue($stores[0]->has('troubles')); $this->assertIdentical($stores[0]->get('troubles'), 'here to stay'); - $this->assertIdentical(count($stores[0]->getMultiple(array('yesterday', 'troubles'))), 1); + $this->assertIdentical(count($stores[0]->getMultiple(['yesterday', 'troubles'])), 1); // Store items set to expire in the past in various ways. $stores[0]->setWithExpire($this->randomMachineName(), $this->objects[0], -7 * $day); $stores[0]->setWithExpireIfNotExists($this->randomMachineName(), $this->objects[1], -5 * $day); $stores[0]->setMultipleWithExpire( - array( + [ $this->randomMachineName() => $this->objects[2], $this->randomMachineName() => $this->objects[3], - ), + ], -3 * $day ); $stores[0]->setWithExpireIfNotExists('yesterday', "you'd forgiven me", -1 * $day); @@ -150,7 +150,7 @@ public function testExpiration() { // Ensure only non-expired items are retrieved. $all = $stores[0]->getAll(); $this->assertIdentical(count($all), 2); - foreach (array('troubles', 'still') as $key) { + foreach (['troubles', 'still'] as $key) { $this->assertTrue(!empty($all[$key])); } } diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php index 676ab108..5852da14 100644 --- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/DatabaseStorageTest.php @@ -17,11 +17,11 @@ class DatabaseStorageTest extends StorageTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; protected function setUp() { parent::setUp(); - $this->installSchema('system', array('key_value')); + $this->installSchema('system', ['key_value']); } /** diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php index 4dc9b47f..875ca7a4 100644 --- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php +++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/GarbageCollectionTest.php @@ -19,13 +19,13 @@ class GarbageCollectionTest extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; protected function setUp() { parent::setUp(); // These additional tables are necessary due to the call to system_cron(). - $this->installSchema('system', array('key_value_expire')); + $this->installSchema('system', ['key_value_expire']); } /** @@ -39,18 +39,18 @@ public function testGarbageCollection() { for ($i = 0; $i <= 3; $i++) { $store->setWithExpire('key_' . $i, $this->randomObject(), rand(500, 100000)); } - $this->assertIdentical(sizeof($store->getAll()), 4, 'Four items were written to the storage.'); + $this->assertIdentical(count($store->getAll()), 4, 'Four items were written to the storage.'); // Manually expire the data. for ($i = 0; $i <= 3; $i++) { db_merge('key_value_expire') - ->keys(array( + ->keys([ 'name' => 'key_' . $i, 'collection' => $collection, - )) - ->fields(array( + ]) + ->fields([ 'expire' => REQUEST_TIME - 1, - )) + ]) ->execute(); } @@ -62,9 +62,9 @@ public function testGarbageCollection() { // Query the database and confirm that the stale records were deleted. $result = db_query( 'SELECT name, value FROM {key_value_expire} WHERE collection = :collection', - array( + [ ':collection' => $collection, - ))->fetchAll(); + ])->fetchAll(); $this->assertIdentical(count($result), 1, 'Only one item remains after garbage collection'); } diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/KeyValueContentEntityStorageTest.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/KeyValueContentEntityStorageTest.php index 068216b3..98850055 100644 --- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/KeyValueContentEntityStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/KeyValueContentEntityStorageTest.php @@ -19,7 +19,7 @@ class KeyValueContentEntityStorageTest extends KernelTestBase { * * @var array */ - public static $modules = array('user', 'entity_test', 'keyvalue_test'); + public static $modules = ['user', 'entity_test', 'keyvalue_test']; /** * {@inheritdoc} @@ -31,9 +31,15 @@ protected function setUp() { /** * Tests CRUD operations. + * + * @covers \Drupal\Core\Entity\KeyValueStore\KeyValueEntityStorage::hasData */ - function testCRUD() { + public function testCRUD() { $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId(); + + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_label'); + $this->assertFalse($storage->hasData()); + // Verify default properties on a newly created empty entity. $empty = EntityTestLabel::create(); $this->assertIdentical($empty->id->value, NULL); @@ -69,9 +75,9 @@ function testCRUD() { } // Verify that an entity with an empty ID string is considered empty, too. - $empty_id = EntityTestLabel::create(array( + $empty_id = EntityTestLabel::create([ 'id' => '', - )); + ]); $this->assertIdentical($empty_id->isNew(), TRUE); try { $empty_id->save(); @@ -82,10 +88,10 @@ function testCRUD() { } // Verify properties on a newly created entity. - $entity_test = EntityTestLabel::create($expected = array( + $entity_test = EntityTestLabel::create($expected = [ 'id' => $this->randomMachineName(), 'name' => $this->randomString(), - )); + ]); $this->assertIdentical($entity_test->id->value, $expected['id']); $this->assertTrue($entity_test->uuid->value); $this->assertNotEqual($entity_test->uuid->value, $empty->uuid->value); @@ -108,6 +114,9 @@ function testCRUD() { $this->fail('EntityMalformedException was not thrown.'); } + // Verify that hasData() returns the expected result. + $this->assertTrue($storage->hasData()); + // Verify that the correct status is returned and properties did not change. $this->assertIdentical($status, SAVED_NEW); $this->assertIdentical($entity_test->id(), $expected['id']); @@ -125,9 +134,9 @@ function testCRUD() { // Ensure that creating an entity with the same id as an existing one is not // possible. - $same_id = EntityTestLabel::create(array( + $same_id = EntityTestLabel::create([ 'id' => $entity_test->id(), - )); + ]); $this->assertIdentical($same_id->isNew(), TRUE); try { $same_id->save(); @@ -138,7 +147,7 @@ function testCRUD() { } // Verify that renaming the ID returns correct status and properties. - $ids = array($expected['id'], 'second_' . $this->randomMachineName(4), 'third_' . $this->randomMachineName(4)); + $ids = [$expected['id'], 'second_' . $this->randomMachineName(4), 'third_' . $this->randomMachineName(4)]; for ($i = 1; $i < 3; $i++) { $old_id = $ids[$i - 1]; $new_id = $ids[$i]; @@ -157,4 +166,12 @@ function testCRUD() { } } + /** + * Tests uninstallation of a module that does not use the SQL entity storage. + */ + public function testUninstall() { + $uninstall_validator_reasons = \Drupal::service('content_uninstall_validator')->validate('keyvalue_test'); + $this->assertEmpty($uninstall_validator_reasons); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php b/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php index 48e047df..48af84d5 100644 --- a/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/KeyValueStore/StorageTestBase.php @@ -14,14 +14,14 @@ abstract class StorageTestBase extends KernelTestBase { * * @var array */ - protected $objects = array(); + protected $objects = []; /** * An array of data collection labels. * * @var array */ - protected $collections = array(); + protected $collections = []; /** * Whether we are using an expirable key/value store. @@ -34,7 +34,7 @@ protected function setUp() { parent::setUp(); // Define two data collections, - $this->collections = array(0 => 'zero', 1 => 'one'); + $this->collections = [0 => 'zero', 1 => 'one']; // Create several objects for testing. for ($i = 0; $i <= 5; $i++) { @@ -82,14 +82,14 @@ public function testCRUD() { $this->assertFalse($stores[1]->get('foo')); // Verify that multiple items can be stored. - $values = array( + $values = [ 'foo' => $this->objects[3], 'bar' => $this->objects[4], - ); + ]; $stores[0]->setMultiple($values); // Verify that multiple items can be retrieved. - $result = $stores[0]->getMultiple(array('foo', 'bar')); + $result = $stores[0]->getMultiple(['foo', 'bar']); foreach ($values as $j => $value) { $this->assertIdenticalObject($value, $result[$j]); } @@ -102,22 +102,22 @@ public function testCRUD() { // Ensure that an item with the same name exists in the other collection. $stores[1]->set('foo', $this->objects[5]); $result = $stores[0]->getAll(); - // Not using assertIdentical(), since the order is not defined for getAll(). + // Not using assertSame(), since the order is not defined for getAll(). $this->assertEqual(count($result), count($values)); foreach ($result as $key => $value) { $this->assertEqual($values[$key], $value); } // Verify that all items in the other collection are different. $result = $stores[1]->getAll(); - $this->assertEqual($result, array('foo' => $this->objects[5])); + $this->assertEqual($result, ['foo' => $this->objects[5]]); // Verify that multiple items can be deleted. $stores[0]->deleteMultiple(array_keys($values)); $this->assertFalse($stores[0]->get('foo')); $this->assertFalse($stores[0]->get('bar')); - $this->assertFalse($stores[0]->getMultiple(array('foo', 'bar'))); + $this->assertFalse($stores[0]->getMultiple(['foo', 'bar'])); // Verify that deleting no items does not cause an error. - $stores[0]->deleteMultiple(array()); + $stores[0]->deleteMultiple([]); // Verify that the item in the other collection still exists. $this->assertIdenticalObject($this->objects[5], $stores[1]->get('foo')); @@ -146,7 +146,7 @@ public function testNonExistingKeys() { // Verify that a non-existing key is not returned when getting multiple keys. $stores[0]->set('bar', 'baz'); - $values = $stores[0]->getMultiple(array('foo', 'bar')); + $values = $stores[0]->getMultiple(['foo', 'bar']); $this->assertFalse(isset($values['foo']), "Key 'foo' not found."); $this->assertIdentical($values['bar'], 'baz'); } @@ -204,7 +204,7 @@ public function testRename() { * @see \Drupal\Core\KeyValueStore\DatabaseStorageExpirable::garbageCollection() */ protected function createStorage() { - $stores = array(); + $stores = []; foreach ($this->collections as $i => $collection) { $stores[$i] = $this->container->get($this->factory)->get($collection); } diff --git a/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php b/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php index 0bd761fe..8e1a50d5 100644 --- a/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php +++ b/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php @@ -47,6 +47,21 @@ public function testBackendLockRelease() { $this->assertTrue($success, 'Could acquire second lock a second time within the same request.'); $this->lock->release('lock_b'); + + // Test acquiring an releasing a lock with a long key (over 255 chars). + $long_key = 'long_key:BZoMiSf9IIPULsJ98po18TxJ6T4usd3MZrLE0d3qMgG6iAgDlOi1G3oMap7zI5df84l7LtJBg4bOj6XvpO6vDRmP5h5QbA0Bj9rVFiPIPAIQZ9qFvJqTALiK1OR3GpOkWQ4vgEA4LkY0UfznrWBeuK7IWZfv1um6DLosnVXd1z1cJjvbEUqYGJj92rwHfhYihLm8IO9t3P2gAvEkH5Mhc8GBoiTsIDnP01Te1kxGFHO3RuvJIxPnHmZtSdBggmuVN7x9'; + + $success = $this->lock->acquire($long_key); + $this->assertTrue($success, 'Could acquire long key lock.'); + + // This function is not part of the backend, but the default database + // backend implement it, we can here use it safely. + $is_free = $this->lock->lockMayBeAvailable($long_key); + $this->assertFalse($is_free, 'Long key lock is unavailable.'); + + $this->lock->release($long_key); + $is_free = $this->lock->lockMayBeAvailable($long_key); + $this->assertTrue($is_free, 'Long key lock has been released.'); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkDefaultIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkDefaultIntegrationTest.php index b9998873..d0da9130 100644 --- a/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkDefaultIntegrationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkDefaultIntegrationTest.php @@ -17,9 +17,9 @@ class MenuLinkDefaultIntegrationTest extends KernelTestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'menu_test', - ); + ]; /** * Tests moving a static menu link without a specified menu to the root. @@ -39,7 +39,7 @@ public function testMoveToRoot() { $this->assertEqual($tree['menu_test.parent']->subtree['menu_test.child']->link->getPluginId(), 'menu_test.child'); // Ensure that the menu name is not forgotten. - $menu_link_manager->updateDefinition('menu_test.child', array('parent' => '')); + $menu_link_manager->updateDefinition('menu_test.child', ['parent' => '']); $menu_link = $menu_link_manager->getDefinition('menu_test.child'); $this->assertEqual($menu_link['parent'], ''); diff --git a/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkTreeTest.php b/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkTreeTest.php index 1efb14bc..9bb7f545 100644 --- a/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkTreeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Menu/MenuLinkTreeTest.php @@ -26,7 +26,7 @@ class MenuLinkTreeTest extends KernelTestBase { /** * The menu link plugin manager. * - * @var \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager + * @var \Drupal\Core\Menu\MenuLinkManagerInterface */ protected $menuLinkManager; @@ -35,13 +35,13 @@ class MenuLinkTreeTest extends KernelTestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'system', 'menu_test', 'menu_link_content', 'field', 'link', - ); + ]; /** * {@inheritdoc} @@ -59,12 +59,12 @@ protected function setUp() { * Tests deleting all the links in a menu. */ public function testDeleteLinksInMenu() { - \Drupal::entityManager()->getStorage('menu')->create(array('id' => 'menu1'))->save(); - \Drupal::entityManager()->getStorage('menu')->create(array('id' => 'menu2'))->save(); + \Drupal::entityManager()->getStorage('menu')->create(['id' => 'menu1'])->save(); + \Drupal::entityManager()->getStorage('menu')->create(['id' => 'menu2'])->save(); - \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save(); - \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save(); - \Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'))->save(); + \Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'])->save(); + \Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'])->save(); + \Drupal::entityManager()->getStorage('menu_link_content')->create(['link' => ['uri' => 'internal:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'])->save(); $output = $this->linkTree->load('menu1', new MenuTreeParameters()); $this->assertEqual(count($output), 2); @@ -95,23 +95,23 @@ public function testCreateLinksInMenu() { // - 8 // With link 6 being the only external link. - $links = array( - 1 => MenuLinkMock::create(array('id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '')), - 2 => MenuLinkMock::create(array('id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => 'test.example1', 'route_parameters' => array('foo' => 'bar'))), - 3 => MenuLinkMock::create(array('id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'route_parameters' => array('baz' => 'qux'))), - 4 => MenuLinkMock::create(array('id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3')), - 5 => MenuLinkMock::create(array('id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '')), - 6 => MenuLinkMock::create(array('id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '')), - 7 => MenuLinkMock::create(array('id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => '')), - 8 => MenuLinkMock::create(array('id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '')), - ); + $links = [ + 1 => MenuLinkMock::create(['id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '']), + 2 => MenuLinkMock::create(['id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => 'test.example1', 'route_parameters' => ['foo' => 'bar']]), + 3 => MenuLinkMock::create(['id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'route_parameters' => ['baz' => 'qux']]), + 4 => MenuLinkMock::create(['id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3']), + 5 => MenuLinkMock::create(['id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '']), + 6 => MenuLinkMock::create(['id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '']), + 7 => MenuLinkMock::create(['id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => '']), + 8 => MenuLinkMock::create(['id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '']), + ]; foreach ($links as $instance) { $this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition()); } $parameters = new MenuTreeParameters(); $tree = $this->linkTree->load('mock', $parameters); - $count = function(array $tree) { + $count = function (array $tree) { $sum = function ($carry, MenuLinkTreeElement $item) { return $carry + $item->count(); }; diff --git a/core/tests/Drupal/KernelTests/Core/Menu/MenuTreeStorageTest.php b/core/tests/Drupal/KernelTests/Core/Menu/MenuTreeStorageTest.php index cb1d74d9..ad3f04d0 100644 --- a/core/tests/Drupal/KernelTests/Core/Menu/MenuTreeStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Menu/MenuTreeStorageTest.php @@ -77,16 +77,16 @@ public function testSimpleHierarchy() { // -- test2 // --- test3 $this->addMenuLink('test1', ''); - $this->assertMenuLink('test1', array('has_children' => 0, 'depth' => 1)); + $this->assertMenuLink('test1', ['has_children' => 0, 'depth' => 1]); $this->addMenuLink('test2', 'test1'); - $this->assertMenuLink('test1', array('has_children' => 1, 'depth' => 1), array(), array('test2')); - $this->assertMenuLink('test2', array('has_children' => 0, 'depth' => 2), array('test1')); + $this->assertMenuLink('test1', ['has_children' => 1, 'depth' => 1], [], ['test2']); + $this->assertMenuLink('test2', ['has_children' => 0, 'depth' => 2], ['test1']); $this->addMenuLink('test3', 'test2'); - $this->assertMenuLink('test1', array('has_children' => 1, 'depth' => 1), array(), array('test2', 'test3')); - $this->assertMenuLink('test2', array('has_children' => 1, 'depth' => 2), array('test1'), array('test3')); - $this->assertMenuLink('test3', array('has_children' => 0, 'depth' => 3), array('test2', 'test1')); + $this->assertMenuLink('test1', ['has_children' => 1, 'depth' => 1], [], ['test2', 'test3']); + $this->assertMenuLink('test2', ['has_children' => 1, 'depth' => 2], ['test1'], ['test3']); + $this->assertMenuLink('test3', ['has_children' => 0, 'depth' => 3], ['test2', 'test1']); } /** @@ -109,11 +109,11 @@ public function testMenuLinkMoving() { $this->addMenuLink('test5', 'test4'); $this->addMenuLink('test6', 'test5'); - $this->assertMenuLink('test1', array('has_children' => 1, 'depth' => 1), array(), array('test2', 'test3')); - $this->assertMenuLink('test2', array('has_children' => 1, 'depth' => 2), array('test1'), array('test3')); - $this->assertMenuLink('test4', array('has_children' => 1, 'depth' => 1), array(), array('test5', 'test6')); - $this->assertMenuLink('test5', array('has_children' => 1, 'depth' => 2), array('test4'), array('test6')); - $this->assertMenuLink('test6', array('has_children' => 0, 'depth' => 3), array('test5', 'test4')); + $this->assertMenuLink('test1', ['has_children' => 1, 'depth' => 1], [], ['test2', 'test3']); + $this->assertMenuLink('test2', ['has_children' => 1, 'depth' => 2], ['test1'], ['test3']); + $this->assertMenuLink('test4', ['has_children' => 1, 'depth' => 1], [], ['test5', 'test6']); + $this->assertMenuLink('test5', ['has_children' => 1, 'depth' => 2], ['test4'], ['test6']); + $this->assertMenuLink('test6', ['has_children' => 0, 'depth' => 3], ['test5', 'test4']); $this->moveMenuLink('test2', 'test5'); // After the 1st move. @@ -125,12 +125,12 @@ public function testMenuLinkMoving() { // ---- test3 // --- test6 - $this->assertMenuLink('test1', array('has_children' => 0, 'depth' => 1)); - $this->assertMenuLink('test2', array('has_children' => 1, 'depth' => 3), array('test5', 'test4'), array('test3')); - $this->assertMenuLink('test3', array('has_children' => 0, 'depth' => 4), array('test2', 'test5', 'test4')); - $this->assertMenuLink('test4', array('has_children' => 1, 'depth' => 1), array(), array('test5', 'test2', 'test3', 'test6')); - $this->assertMenuLink('test5', array('has_children' => 1, 'depth' => 2), array('test4'), array('test2', 'test3', 'test6')); - $this->assertMenuLink('test6', array('has_children' => 0, 'depth' => 3), array('test5', 'test4')); + $this->assertMenuLink('test1', ['has_children' => 0, 'depth' => 1]); + $this->assertMenuLink('test2', ['has_children' => 1, 'depth' => 3], ['test5', 'test4'], ['test3']); + $this->assertMenuLink('test3', ['has_children' => 0, 'depth' => 4], ['test2', 'test5', 'test4']); + $this->assertMenuLink('test4', ['has_children' => 1, 'depth' => 1], [], ['test5', 'test2', 'test3', 'test6']); + $this->assertMenuLink('test5', ['has_children' => 1, 'depth' => 2], ['test4'], ['test2', 'test3', 'test6']); + $this->assertMenuLink('test6', ['has_children' => 0, 'depth' => 3], ['test5', 'test4']); $this->moveMenuLink('test4', 'test1'); $this->moveMenuLink('test3', 'test1'); @@ -143,12 +143,12 @@ public function testMenuLinkMoving() { // ---- test2 // ---- test6 - $this->assertMenuLink('test1', array('has_children' => 1, 'depth' => 1), array(), array('test4', 'test5', 'test2', 'test3', 'test6')); - $this->assertMenuLink('test2', array('has_children' => 0, 'depth' => 4), array('test5', 'test4', 'test1')); - $this->assertMenuLink('test3', array('has_children' => 0, 'depth' => 2), array('test1')); - $this->assertMenuLink('test4', array('has_children' => 1, 'depth' => 2), array('test1'), array('test2', 'test5', 'test6')); - $this->assertMenuLink('test5', array('has_children' => 1, 'depth' => 3), array('test4', 'test1'), array('test2', 'test6')); - $this->assertMenuLink('test6', array('has_children' => 0, 'depth' => 4), array('test5', 'test4', 'test1')); + $this->assertMenuLink('test1', ['has_children' => 1, 'depth' => 1], [], ['test4', 'test5', 'test2', 'test3', 'test6']); + $this->assertMenuLink('test2', ['has_children' => 0, 'depth' => 4], ['test5', 'test4', 'test1']); + $this->assertMenuLink('test3', ['has_children' => 0, 'depth' => 2], ['test1']); + $this->assertMenuLink('test4', ['has_children' => 1, 'depth' => 2], ['test1'], ['test2', 'test5', 'test6']); + $this->assertMenuLink('test5', ['has_children' => 1, 'depth' => 3], ['test4', 'test1'], ['test2', 'test6']); + $this->assertMenuLink('test6', ['has_children' => 0, 'depth' => 4], ['test5', 'test4', 'test1']); // Deleting a link in the middle should re-attach child links to the parent. $this->treeStorage->delete('test4'); @@ -159,12 +159,12 @@ public function testMenuLinkMoving() { // -- test5 // --- test2 // --- test6 - $this->assertMenuLink('test1', array('has_children' => 1, 'depth' => 1), array(), array('test5', 'test2', 'test3', 'test6')); - $this->assertMenuLink('test2', array('has_children' => 0, 'depth' => 3), array('test5', 'test1')); - $this->assertMenuLink('test3', array('has_children' => 0, 'depth' => 2), array('test1')); + $this->assertMenuLink('test1', ['has_children' => 1, 'depth' => 1], [], ['test5', 'test2', 'test3', 'test6']); + $this->assertMenuLink('test2', ['has_children' => 0, 'depth' => 3], ['test5', 'test1']); + $this->assertMenuLink('test3', ['has_children' => 0, 'depth' => 2], ['test1']); $this->assertFalse($this->treeStorage->load('test4')); - $this->assertMenuLink('test5', array('has_children' => 1, 'depth' => 2), array('test1'), array('test2', 'test6')); - $this->assertMenuLink('test6', array('has_children' => 0, 'depth' => 3), array('test5', 'test1')); + $this->assertMenuLink('test5', ['has_children' => 1, 'depth' => 2], ['test1'], ['test2', 'test6']); + $this->assertMenuLink('test6', ['has_children' => 0, 'depth' => 3], ['test5', 'test1']); } /** @@ -177,12 +177,12 @@ public function testMenuDisabledChildLinks() { // -- test2 (disabled) $this->addMenuLink('test1', ''); - $this->assertMenuLink('test1', array('has_children' => 0, 'depth' => 1)); + $this->assertMenuLink('test1', ['has_children' => 0, 'depth' => 1]); - $this->addMenuLink('test2', 'test1', '', array(), 'tools', array('enabled' => 0)); + $this->addMenuLink('test2', 'test1', '', [], 'tools', ['enabled' => 0]); // The 1st link does not have any visible children, so has_children is 0. - $this->assertMenuLink('test1', array('has_children' => 0, 'depth' => 1)); - $this->assertMenuLink('test2', array('has_children' => 0, 'depth' => 2, 'enabled' => 0), array('test1')); + $this->assertMenuLink('test1', ['has_children' => 0, 'depth' => 1]); + $this->assertMenuLink('test2', ['has_children' => 0, 'depth' => 2, 'enabled' => 0], ['test1']); // Add more links with parent on the previous one. //
    @@ -198,8 +198,8 @@ public function testMenuDisabledChildLinks() { // ------- test7 // -------- test8 // --------- test9 - $this->addMenuLink('footerA', '', '', array(), 'footer'); - $visible_children = array(); + $this->addMenuLink('footerA', '', '', [], 'footer'); + $visible_children = []; for ($i = 3; $i <= $this->treeStorage->maxDepth(); $i++) { $parent = $i - 1; $this->addMenuLink("test$i", "test$parent"); @@ -207,7 +207,7 @@ public function testMenuDisabledChildLinks() { } // The 1st link does not have any visible children, so has_children is still // 0. However, it has visible links below it that will be found. - $this->assertMenuLink('test1', array('has_children' => 0, 'depth' => 1), array(), $visible_children); + $this->assertMenuLink('test1', ['has_children' => 0, 'depth' => 1], [], $visible_children); // This should fail since test9 would end up at greater than max depth. try { $this->moveMenuLink('test1', 'footerA'); @@ -219,7 +219,7 @@ public function testMenuDisabledChildLinks() { // The opposite move should work, and change the has_children flag. $this->moveMenuLink('footerA', 'test1'); $visible_children[] = 'footerA'; - $this->assertMenuLink('test1', array('has_children' => 1, 'depth' => 1), array(), $visible_children); + $this->assertMenuLink('test1', ['has_children' => 1, 'depth' => 1], [], $visible_children); } /** @@ -241,7 +241,7 @@ public function testLoadTree() { $this->assertEqual(count($tree['test4']['subtree']['test5']['subtree']), 0); $parameters = new MenuTreeParameters(); - $parameters->setActiveTrail(array('test4', 'test5')); + $parameters->setActiveTrail(['test4', 'test5']); $data = $this->treeStorage->loadTreeData('tools', $parameters); $tree = $data['tree']; $this->assertEqual(count($tree['test1']['subtree']), 1); @@ -342,10 +342,10 @@ public function testMenuRebuild() { * Tests MenuTreeStorage::loadByProperties(). */ public function testLoadByProperties() { - $tests = array( - array('foo' => 'bar'), - array(0 => 'wrong'), - ); + $tests = [ + ['foo' => 'bar'], + [0 => 'wrong'], + ]; $message = 'An invalid property name throws an exception.'; foreach ($tests as $properties) { try { @@ -357,8 +357,8 @@ public function testLoadByProperties() { $this->pass($message); } } - $this->addMenuLink('test_link.1', '', 'test', array(), 'menu1'); - $properties = array('menu_name' => 'menu1'); + $this->addMenuLink('test_link.1', '', 'test', [], 'menu1'); + $properties = ['menu_name' => 'menu1']; $links = $this->treeStorage->loadByProperties($properties); $this->assertEqual('menu1', $links['test_link.1']['menu_name']); $this->assertEqual('test', $links['test_link.1']['route_name']); @@ -367,17 +367,17 @@ public function testLoadByProperties() { /** * Adds a link with the given ID and supply defaults. */ - protected function addMenuLink($id, $parent = '', $route_name = 'test', $route_parameters = array(), $menu_name = 'tools', $extra = array()) { - $link = array( + protected function addMenuLink($id, $parent = '', $route_name = 'test', $route_parameters = [], $menu_name = 'tools', $extra = []) { + $link = [ 'id' => $id, 'menu_name' => $menu_name, 'route_name' => $route_name, 'route_parameters' => $route_parameters, 'title' => 'test', 'parent' => $parent, - 'options' => array(), - 'metadata' => array(), - ) + $extra; + 'options' => [], + 'metadata' => [], + ] + $extra; $this->treeStorage->save($link); } @@ -407,7 +407,7 @@ protected function moveMenuLink($id, $new_parent) { * @param array $children * Array of child IDs that are visible (enabled == 1). */ - protected function assertMenuLink($id, array $expected_properties, array $parents = array(), array $children = array()) { + protected function assertMenuLink($id, array $expected_properties, array $parents = [], array $children = []) { $query = $this->connection->select('menu_tree'); $query->fields('menu_tree'); $query->condition('id', $id); @@ -422,7 +422,7 @@ protected function assertMenuLink($id, array $expected_properties, array $parent array_unshift($parents, $raw['id']); $query = $this->connection->select('menu_tree'); - $query->fields('menu_tree', array('id', 'mlid')); + $query->fields('menu_tree', ['id', 'mlid']); $query->condition('id', $parents, 'IN'); $found_parents = $query->execute()->fetchAllKeyed(0, 1); diff --git a/core/tests/Drupal/KernelTests/Core/Path/AliasTest.php b/core/tests/Drupal/KernelTests/Core/Path/AliasTest.php index 5eb2ace6..1f49b09f 100644 --- a/core/tests/Drupal/KernelTests/Core/Path/AliasTest.php +++ b/core/tests/Drupal/KernelTests/Core/Path/AliasTest.php @@ -15,90 +15,90 @@ */ class AliasTest extends PathUnitTestBase { - function testCRUD() { - //Prepare database table. + public function testCRUD() { + // Prepare database table. $connection = Database::getConnection(); $this->fixtures->createTables($connection); - //Create Path object. + // Create Path object. $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler')); $aliases = $this->fixtures->sampleUrlAliases(); - //Create a few aliases + // Create a few aliases foreach ($aliases as $idx => $alias) { $aliasStorage->save($alias['source'], $alias['alias'], $alias['langcode']); - $result = $connection->query('SELECT * FROM {url_alias} WHERE source = :source AND alias= :alias AND langcode = :langcode', array(':source' => $alias['source'], ':alias' => $alias['alias'], ':langcode' => $alias['langcode'])); + $result = $connection->query('SELECT * FROM {url_alias} WHERE source = :source AND alias= :alias AND langcode = :langcode', [':source' => $alias['source'], ':alias' => $alias['alias'], ':langcode' => $alias['langcode']]); $rows = $result->fetchAll(); - $this->assertEqual(count($rows), 1, format_string('Created an entry for %alias.', array('%alias' => $alias['alias']))); + $this->assertEqual(count($rows), 1, format_string('Created an entry for %alias.', ['%alias' => $alias['alias']])); - //Cache the pid for further tests. + // Cache the pid for further tests. $aliases[$idx]['pid'] = $rows[0]->pid; } - //Load a few aliases + // Load a few aliases foreach ($aliases as $alias) { $pid = $alias['pid']; - $loadedAlias = $aliasStorage->load(array('pid' => $pid)); - $this->assertEqual($loadedAlias, $alias, format_string('Loaded the expected path with pid %pid.', array('%pid' => $pid))); + $loadedAlias = $aliasStorage->load(['pid' => $pid]); + $this->assertEqual($loadedAlias, $alias, format_string('Loaded the expected path with pid %pid.', ['%pid' => $pid])); } // Load alias by source path. - $loadedAlias = $aliasStorage->load(array('source' => '/node/1')); + $loadedAlias = $aliasStorage->load(['source' => '/node/1']); $this->assertEqual($loadedAlias['alias'], '/alias_for_node_1_und', 'The last created alias loaded by default.'); - //Update a few aliases + // Update a few aliases foreach ($aliases as $alias) { $fields = $aliasStorage->save($alias['source'], $alias['alias'] . '_updated', $alias['langcode'], $alias['pid']); $this->assertEqual($alias['alias'], $fields['original']['alias']); - $result = $connection->query('SELECT pid FROM {url_alias} WHERE source = :source AND alias= :alias AND langcode = :langcode', array(':source' => $alias['source'], ':alias' => $alias['alias'] . '_updated', ':langcode' => $alias['langcode'])); + $result = $connection->query('SELECT pid FROM {url_alias} WHERE source = :source AND alias= :alias AND langcode = :langcode', [':source' => $alias['source'], ':alias' => $alias['alias'] . '_updated', ':langcode' => $alias['langcode']]); $pid = $result->fetchField(); - $this->assertEqual($pid, $alias['pid'], format_string('Updated entry for pid %pid.', array('%pid' => $pid))); + $this->assertEqual($pid, $alias['pid'], format_string('Updated entry for pid %pid.', ['%pid' => $pid])); } - //Delete a few aliases + // Delete a few aliases foreach ($aliases as $alias) { $pid = $alias['pid']; - $aliasStorage->delete(array('pid' => $pid)); + $aliasStorage->delete(['pid' => $pid]); - $result = $connection->query('SELECT * FROM {url_alias} WHERE pid = :pid', array(':pid' => $pid)); + $result = $connection->query('SELECT * FROM {url_alias} WHERE pid = :pid', [':pid' => $pid]); $rows = $result->fetchAll(); - $this->assertEqual(count($rows), 0, format_string('Deleted entry with pid %pid.', array('%pid' => $pid))); + $this->assertEqual(count($rows), 0, format_string('Deleted entry with pid %pid.', ['%pid' => $pid])); } } - function testLookupPath() { - //Prepare database table. + public function testLookupPath() { + // Prepare database table. $connection = Database::getConnection(); $this->fixtures->createTables($connection); - //Create AliasManager and Path object. + // Create AliasManager and Path object. $aliasManager = $this->container->get('path.alias_manager'); $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler')); // Test the situation where the source is the same for multiple aliases. // Start with a language-neutral alias, which we will override. - $path = array( + $path = [ 'source' => "/user/1", 'alias' => '/foo', - ); + ]; $aliasStorage->save($path['source'], $path['alias']); $this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'Basic alias lookup works.'); $this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'Basic source lookup works.'); // Create a language specific alias for the default language (English). - $path = array( + $path = [ 'source' => "/user/1", 'alias' => "/users/Dries", 'langcode' => 'en', - ); + ]; $aliasStorage->save($path['source'], $path['alias'], $path['langcode']); // Hook that clears cache is not executed with unit tests. \Drupal::service('path.alias_manager')->cacheClear(); @@ -106,19 +106,19 @@ function testLookupPath() { $this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'English source overrides language-neutral source.'); // Create a language-neutral alias for the same path, again. - $path = array( + $path = [ 'source' => "/user/1", 'alias' => '/bar', - ); + ]; $aliasStorage->save($path['source'], $path['alias']); $this->assertEqual($aliasManager->getAliasByPath($path['source']), "/users/Dries", 'English alias still returned after entering a language-neutral alias.'); // Create a language-specific (xx-lolspeak) alias for the same path. - $path = array( + $path = [ 'source' => "/user/1", 'alias' => '/LOL', 'langcode' => 'xx-lolspeak', - ); + ]; $aliasStorage->save($path['source'], $path['alias'], $path['langcode']); $this->assertEqual($aliasManager->getAliasByPath($path['source']), "/users/Dries", 'English alias still returned after entering a LOLspeak alias.'); // The LOLspeak alias should be returned if we really want LOLspeak. @@ -126,11 +126,11 @@ function testLookupPath() { // Create a new alias for this path in English, which should override the // previous alias for "user/1". - $path = array( + $path = [ 'source' => "/user/1", 'alias' => '/users/my-new-path', 'langcode' => 'en', - ); + ]; $aliasStorage->save($path['source'], $path['alias'], $path['langcode']); // Hook that clears cache is not executed with unit tests. $aliasManager->cacheClear(); @@ -139,7 +139,7 @@ function testLookupPath() { // Remove the English aliases, which should cause a fallback to the most // recently created language-neutral alias, 'bar'. - $aliasStorage->delete(array('langcode' => 'en')); + $aliasStorage->delete(['langcode' => 'en']); // Hook that clears cache is not executed with unit tests. $aliasManager->cacheClear(); $this->assertEqual($aliasManager->getAliasByPath($path['source']), '/bar', 'Path lookup falls back to recently created language-neutral alias.'); @@ -155,12 +155,12 @@ function testLookupPath() { /** * Tests the alias whitelist. */ - function testWhitelist() { + public function testWhitelist() { // Prepare database table. $connection = Database::getConnection(); $this->fixtures->createTables($connection); - $memoryCounterBackend = new MemoryCounterBackend('default'); + $memoryCounterBackend = new MemoryCounterBackend(); // Create AliasManager and Path object. $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler')); @@ -190,7 +190,7 @@ function testWhitelist() { $this->assertNull($whitelist->get($this->randomMachineName())); // Remove the user alias again, whitelist entry should be removed. - $aliasStorage->delete(array('source' => '/user/1')); + $aliasStorage->delete(['source' => '/user/1']); $aliasManager->cacheClear(); $this->assertNull($whitelist->get('user')); $this->assertTrue($whitelist->get('admin')); @@ -216,4 +216,62 @@ function testWhitelist() { $this->assertEqual($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 0); } + /** + * Tests situation where the whitelist cache is deleted mid-request. + */ + public function testWhitelistCacheDeletionMidRequest() { + // Prepare database table. + $connection = Database::getConnection(); + $this->fixtures->createTables($connection); + + $memoryCounterBackend = new MemoryCounterBackend(); + + // Create AliasManager and Path object. + $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler')); + $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage); + $aliasManager = new AliasManager($aliasStorage, $whitelist, $this->container->get('language_manager'), $memoryCounterBackend); + + // Whitelist cache should not exist at all yet. + $this->assertFalse($memoryCounterBackend->get('path_alias_whitelist')); + + // Add some aliases for both menu routes we have. + $aliasStorage->save('/admin/something', '/' . $this->randomMachineName()); + $aliasStorage->save('/user/something', '/' . $this->randomMachineName()); + $aliasManager->cacheClear(); + + // Lookup admin path in whitelist. It will query the DB and figure out + // that it indeed has an alias, and add it to the internal whitelist and + // flag it to be peristed to cache. + $this->assertTrue($whitelist->get('admin')); + + // Destruct the whitelist so it persists its cache. + $whitelist->destruct(); + $this->assertEquals($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 1); + // Cache data should have data for 'user' and 'admin', even though just + // 'admin' was looked up. This is because the cache is primed with all + // menu router base paths. + $this->assertEquals(['user' => FALSE, 'admin' => TRUE], $memoryCounterBackend->get('path_alias_whitelist')->data); + $memoryCounterBackend->resetCounter(); + + // Re-initialize the the whitelist and lookup an alias for the 'user' path. + // Whitelist should load data from its cache, see that it hasn't done a + // check for 'user' yet, perform the check, then mark the result to be + // persisted to cache. + $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage); + $this->assertTrue($whitelist->get('user')); + + // Delete the whitelist cache. This could happen from an outside process, + // like a code deployment that performs a cache rebuild. + $memoryCounterBackend->delete('path_alias_whitelist'); + + // Destruct whitelist so it attempts to save the whitelist data to cache. + // However it should recognize that the previous cache entry was deleted + // from underneath it and not save anything to cache, to protect from + // cache corruption. + $whitelist->destruct(); + $this->assertEquals($memoryCounterBackend->getCounter('set', 'path_alias_whitelist'), 0); + $this->assertFalse($memoryCounterBackend->get('path_alias_whitelist')); + $memoryCounterBackend->resetCounter(); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Path/PathUnitTestBase.php b/core/tests/Drupal/KernelTests/Core/Path/PathUnitTestBase.php index 9c50f9a4..671dbc47 100644 --- a/core/tests/Drupal/KernelTests/Core/Path/PathUnitTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Path/PathUnitTestBase.php @@ -21,7 +21,7 @@ protected function setUp() { $this->fixtures = new UrlAliasFixtures(); // The alias whitelist expects that the menu path roots are set by a // menu router rebuild. - \Drupal::state()->set('router.path_roots', array('user', 'admin')); + \Drupal::state()->set('router.path_roots', ['user', 'admin']); } protected function tearDown() { diff --git a/core/tests/Drupal/KernelTests/Core/Path/PathValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Path/PathValidatorTest.php new file mode 100644 index 00000000..1ecd5249 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Path/PathValidatorTest.php @@ -0,0 +1,70 @@ +installEntitySchema('entity_test'); + } + + public function testGetUrlIfValidWithoutAccessCheck() { + $requestContext = \Drupal::service('router.request_context'); + $pathValidator = \Drupal::service('path.validator'); + + $entity = EntityTest::create([ + 'name' => 'test', + ]); + $entity->save(); + + $methods = [ + 'POST', + 'GET', + 'PUT', + 'PATCH', + 'DELETE', + // Used in CLI context. + NULL, + // If no request was even pushed onto the request stack, and hence. + FALSE, + ]; + foreach ($methods as $method) { + if ($method === FALSE) { + $request_stack = $this->container->get('request_stack'); + while ($request_stack->getCurrentRequest()) { + $request_stack->pop(); + } + $this->container->set('router.request_context', new RequestContext()); + } + + $requestContext->setMethod($method); + /** @var \Drupal\Core\Url $url */ + $url = $pathValidator->getUrlIfValidWithoutAccessCheck($entity->toUrl()->toString(TRUE)->getGeneratedUrl()); + $this->assertEquals($method, $requestContext->getMethod()); + $this->assertInstanceOf(Url::class, $url); + $this->assertSame($url->getRouteParameters(), ['entity_test' => $entity->id()]); + } + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Path/UrlAlterTest.php b/core/tests/Drupal/KernelTests/Core/Path/UrlAlterTest.php new file mode 100644 index 00000000..37ac65ae --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Path/UrlAlterTest.php @@ -0,0 +1,28 @@ +assertEquals(\Drupal::request()->getBaseUrl() . '/user/login?foo=bar', $url->toString()); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Condition/CurrentThemeConditionTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Condition/CurrentThemeConditionTest.php index d9a7cb35..7a69d2eb 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Condition/CurrentThemeConditionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Condition/CurrentThemeConditionTest.php @@ -15,31 +15,31 @@ class CurrentThemeConditionTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('system', 'theme_test'); + public static $modules = ['system', 'theme_test']; /** * Tests the current theme condition. */ public function testCurrentTheme() { - \Drupal::service('theme_handler')->install(array('test_theme')); + \Drupal::service('theme_handler')->install(['test_theme']); $manager = \Drupal::service('plugin.manager.condition'); /** @var $condition \Drupal\Core\Condition\ConditionInterface */ $condition = $manager->createInstance('current_theme'); - $condition->setConfiguration(array('theme' => 'test_theme')); + $condition->setConfiguration(['theme' => 'test_theme']); /** @var $condition_negated \Drupal\Core\Condition\ConditionInterface */ $condition_negated = $manager->createInstance('current_theme'); - $condition_negated->setConfiguration(array('theme' => 'test_theme', 'negate' => TRUE)); + $condition_negated->setConfiguration(['theme' => 'test_theme', 'negate' => TRUE]); - $this->assertEqual($condition->summary(), SafeMarkup::format('The current theme is @theme', array('@theme' => 'test_theme'))); - $this->assertEqual($condition_negated->summary(), SafeMarkup::format('The current theme is not @theme', array('@theme' => 'test_theme'))); + $this->assertEqual($condition->summary(), SafeMarkup::format('The current theme is @theme', ['@theme' => 'test_theme'])); + $this->assertEqual($condition_negated->summary(), SafeMarkup::format('The current theme is not @theme', ['@theme' => 'test_theme'])); // The expected theme has not been set up yet. $this->assertFalse($condition->execute()); $this->assertTrue($condition_negated->execute()); // Set the expected theme to be used. - \Drupal::service('theme_handler')->setDefault('test_theme'); + $this->config('system.theme')->set('default', 'test_theme')->save(); \Drupal::theme()->resetActiveTheme(); $this->assertTrue($condition->execute()); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Condition/RequestPathTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Condition/RequestPathTest.php index 02f2a5de..68b6eb77 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Condition/RequestPathTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Condition/RequestPathTest.php @@ -42,7 +42,7 @@ class RequestPathTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field', 'path'); + public static $modules = ['system', 'user', 'field', 'path']; /** * The current path. @@ -57,7 +57,7 @@ class RequestPathTest extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('sequences')); + $this->installSchema('system', ['sequences']); $this->pluginManager = $this->container->get('plugin.manager.condition'); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/ContextPluginTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/ContextPluginTest.php index 3c25184a..a9ec4b8c 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/ContextPluginTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/ContextPluginTest.php @@ -17,12 +17,12 @@ */ class ContextPluginTest extends KernelTestBase { - public static $modules = array('system', 'user', 'node', 'field', 'filter', 'text'); + public static $modules = ['system', 'user', 'node', 'field', 'filter', 'text']; /** * Tests basic context definition and value getters and setters. */ - function testContext() { + public function testContext() { $this->installEntitySchema('user'); $this->installEntitySchema('node'); $this->installEntitySchema('node_type'); @@ -59,7 +59,7 @@ function testContext() { $plugin->getContextValue('user'); } catch (ContextException $e) { - $this->assertIdentical("The 'entity:user' context is required and not present.", $e->getMessage(), 'Requesting a non-set value of a required context should throw a context exception.'); + $this->assertSame("The 'entity:user' context is required and not present.", $e->getMessage(), 'Requesting a non-set value of a required context should throw a context exception.'); } // Try to pass the wrong class type as a context value. diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/DerivativeTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/DerivativeTest.php index 7a834afc..251abbf4 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/DerivativeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/DerivativeTest.php @@ -12,7 +12,7 @@ class DerivativeTest extends PluginTestBase { /** * Tests getDefinitions() and getDefinition() with a derivativeDecorator. */ - function testDerivativeDecorator() { + public function testDerivativeDecorator() { // Ensure that getDefinitions() returns the expected definitions. $this->assertEqual($this->mockBlockManager->getDefinitions(), $this->mockBlockExpectedDefinitions); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php index 9a714c43..9003713f 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/AnnotatedClassDiscoveryTest.php @@ -13,69 +13,69 @@ class AnnotatedClassDiscoveryTest extends DiscoveryTestBase { protected function setUp() { parent::setUp(); - $this->expectedDefinitions = array( - 'apple' => array( + $this->expectedDefinitions = [ + 'apple' => [ 'id' => 'apple', 'label' => 'Apple', 'color' => 'green', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple', 'provider' => 'plugin_test', - ), - 'banana' => array( + ], + 'banana' => [ 'id' => 'banana', 'label' => 'Banana', 'color' => 'yellow', - 'uses' => array( + 'uses' => [ 'bread' => t('Banana bread'), - 'loaf' => array( + 'loaf' => [ 'singular' => '@count loaf', 'plural' => '@count loaves', 'context' => NULL, - ), - ), + ], + ], 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Banana', 'provider' => 'plugin_test', - ), - 'cherry' => array( + ], + 'cherry' => [ 'id' => 'cherry', 'label' => 'Cherry', 'color' => 'red', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry', 'provider' => 'plugin_test', - ), - 'kale' => array( + ], + 'kale' => [ 'id' => 'kale', 'label' => 'Kale', 'color' => 'green', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Kale', 'provider' => 'plugin_test', - ), - 'orange' => array( + ], + 'orange' => [ 'id' => 'orange', 'label' => 'Orange', 'color' => 'orange', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange', 'provider' => 'plugin_test', - ), - 'big_apple' => array( + ], + 'big_apple' => [ 'id' => 'big_apple', 'label' => 'Big Apple', 'color' => 'green', 'class' => 'Drupal\plugin_test_extended\Plugin\plugin_test\fruit\BigApple', 'provider' => 'plugin_test_extended', - ), - 'extending_non_installed_class' => array( + ], + 'extending_non_installed_class' => [ 'id' => 'extending_non_installed_class', 'label' => 'A plugin whose class is extending from a non-installed module class', 'color' => 'pink', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\ExtendingNonInstalledClass', 'provider' => 'plugin_test', - ), - ); + ], + ]; $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src'; $base_directory2 = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test_extended/src'; - $namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory, 'Drupal\plugin_test_extended' => $base_directory2)); + $namespaces = new \ArrayObject(['Drupal\plugin_test' => $base_directory, 'Drupal\plugin_test_extended' => $base_directory2]); $annotation_namespaces = ['Drupal\plugin_test\Plugin\Annotation', 'Drupal\plugin_test_extended\Plugin\Annotation']; $this->discovery = new AnnotatedClassDiscovery('Plugin/plugin_test/fruit', $namespaces, 'Drupal\Component\Annotation\Plugin', $annotation_namespaces); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php index 5cd8f756..3ae576cf 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php @@ -15,23 +15,23 @@ class CustomAnnotationClassDiscoveryTest extends DiscoveryTestBase { protected function setUp() { parent::setUp(); - $this->expectedDefinitions = array( - 'example_1' => array( + $this->expectedDefinitions = [ + 'example_1' => [ 'id' => 'example_1', 'custom' => 'John', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\custom_annotation\Example1', 'provider' => 'plugin_test', - ), - 'example_2' => array( + ], + 'example_2' => [ 'id' => 'example_2', 'custom' => 'Paul', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\custom_annotation\Example2', 'provider' => 'plugin_test', - ), - ); + ], + ]; $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src'; - $root_namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory)); + $root_namespaces = new \ArrayObject(['Drupal\plugin_test' => $base_directory]); $this->discovery = new AnnotatedClassDiscovery('Plugin/plugin_test/custom_annotation', $root_namespaces, 'Drupal\plugin_test\Plugin\Annotation\PluginExample'); $this->emptyDiscovery = new AnnotatedClassDiscovery('Plugin/non_existing_module/non_existing_plugin_type', $root_namespaces, 'Drupal\plugin_test\Plugin\Annotation\PluginExample'); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php index a9fbf799..a6ae259b 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php @@ -15,73 +15,73 @@ class CustomDirectoryAnnotatedClassDiscoveryTest extends DiscoveryTestBase { protected function setUp() { parent::setUp(); - $this->expectedDefinitions = array( - 'custom_example_1' => array( + $this->expectedDefinitions = [ + 'custom_example_1' => [ 'id' => 'custom_example_1', 'custom' => 'Tim', 'class' => 'Drupal\plugin_test\CustomDirectoryExample1', 'provider' => 'plugin_test', - ), - 'custom_example_2' => array( + ], + 'custom_example_2' => [ 'id' => 'custom_example_2', 'custom' => 'Meghan', 'class' => 'Drupal\plugin_test\CustomDirectoryExample2', 'provider' => 'plugin_test', - ), - 'apple' => array( + ], + 'apple' => [ 'id' => 'apple', 'label' => 'Apple', 'color' => 'green', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Apple', 'provider' => 'plugin_test', - ), - 'banana' => array( + ], + 'banana' => [ 'id' => 'banana', 'label' => 'Banana', 'color' => 'yellow', - 'uses' => array( + 'uses' => [ 'bread' => t('Banana bread'), - 'loaf' => array( + 'loaf' => [ 'singular' => '@count loaf', 'plural' => '@count loaves', 'context' => NULL, - ), - ), + ], + ], 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Banana', 'provider' => 'plugin_test', - ), - 'cherry' => array( + ], + 'cherry' => [ 'id' => 'cherry', 'label' => 'Cherry', 'color' => 'red', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry', 'provider' => 'plugin_test', - ), - 'kale' => array( + ], + 'kale' => [ 'id' => 'kale', 'label' => 'Kale', 'color' => 'green', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Kale', 'provider' => 'plugin_test', - ), - 'orange' => array( + ], + 'orange' => [ 'id' => 'orange', 'label' => 'Orange', 'color' => 'orange', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\Orange', 'provider' => 'plugin_test', - ), - 'extending_non_installed_class' => array( + ], + 'extending_non_installed_class' => [ 'id' => 'extending_non_installed_class', 'label' => 'A plugin whose class is extending from a non-installed module class', 'color' => 'pink', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\fruit\ExtendingNonInstalledClass', 'provider' => 'plugin_test', - ), - ); + ], + ]; $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src'; - $namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory)); + $namespaces = new \ArrayObject(['Drupal\plugin_test' => $base_directory]); $this->discovery = new AnnotatedClassDiscovery('', $namespaces); $empty_namespaces = new \ArrayObject(); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/DiscoveryTestBase.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/DiscoveryTestBase.php index bbe20735..4c6e22a8 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/DiscoveryTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/DiscoveryTestBase.php @@ -37,7 +37,7 @@ abstract class DiscoveryTestBase extends KernelTestBase { /** * Tests getDefinitions() and getDefinition(). */ - function testDiscoveryInterface() { + public function testDiscoveryInterface() { // Ensure that getDefinitions() returns the expected definitions. // For the arrays to be identical (instead of only equal), they must be // sorted equally, which seems unnecessary here. @@ -51,7 +51,7 @@ function testDiscoveryInterface() { } // Ensure that an empty array is returned if no plugin definitions are found. - $this->assertIdentical($this->emptyDiscovery->getDefinitions(), array(), 'array() returned if no plugin definitions are found.'); + $this->assertIdentical($this->emptyDiscovery->getDefinitions(), [], 'array() returned if no plugin definitions are found.'); // Ensure that NULL is returned as the definition of a non-existing plugin. $this->assertIdentical($this->emptyDiscovery->getDefinition('non_existing', FALSE), NULL, 'NULL returned as the definition of a non-existing plugin.'); @@ -71,7 +71,7 @@ function testDiscoveryInterface() { * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertDefinitionIdentical(array $definition, array $expected_definition) { - $func = function (&$item){ + $func = function (&$item) { if ($item instanceof TranslatableMarkup) { $item = (string) $item; } diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/StaticDiscoveryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/StaticDiscoveryTest.php index bd0c3172..fb9eb3a9 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/StaticDiscoveryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/Discovery/StaticDiscoveryTest.php @@ -13,20 +13,20 @@ class StaticDiscoveryTest extends DiscoveryTestBase { protected function setUp() { parent::setUp(); - $this->expectedDefinitions = array( - 'apple' => array( + $this->expectedDefinitions = [ + 'apple' => [ 'label' => 'Apple', 'color' => 'green', - ), - 'cherry' => array( + ], + 'cherry' => [ 'label' => 'Cherry', 'color' => 'red', - ), - 'orange' => array( + ], + 'orange' => [ 'label' => 'Orange', 'color' => 'orange', - ), - ); + ], + ]; // Instead of registering the empty discovery component first and then // setting the plugin definitions, we set them first and then delete them // again. This implicitly tests StaticDiscovery::deleteDefinition() (in diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/FactoryTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/FactoryTest.php index 47609902..50da5cfa 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/FactoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/FactoryTest.php @@ -14,9 +14,9 @@ class FactoryTest extends PluginTestBase { /** * Test that DefaultFactory can create a plugin instance. */ - function testDefaultFactory() { + public function testDefaultFactory() { // Ensure a non-derivative plugin can be instantiated. - $plugin = $this->testPluginManager->createInstance('user_login', array('title' => 'Please enter your login name and password')); + $plugin = $this->testPluginManager->createInstance('user_login', ['title' => 'Please enter your login name and password']); $this->assertIdentical(get_class($plugin), 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', 'Correct plugin class instantiated with default factory.'); $this->assertIdentical($plugin->getTitle(), 'Please enter your login name and password', 'Plugin instance correctly configured.'); @@ -44,21 +44,21 @@ function testDefaultFactory() { * reflection factory and it provides some additional variety in plugin * object creation. */ - function testReflectionFactory() { + public function testReflectionFactory() { // Ensure a non-derivative plugin can be instantiated. - $plugin = $this->mockBlockManager->createInstance('user_login', array('title' => 'Please enter your login name and password')); + $plugin = $this->mockBlockManager->createInstance('user_login', ['title' => 'Please enter your login name and password']); $this->assertIdentical(get_class($plugin), 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', 'Correct plugin class instantiated.'); $this->assertIdentical($plugin->getTitle(), 'Please enter your login name and password', 'Plugin instance correctly configured.'); // Ensure a derivative plugin can be instantiated. - $plugin = $this->mockBlockManager->createInstance('menu:main_menu', array('depth' => 2)); + $plugin = $this->mockBlockManager->createInstance('menu:main_menu', ['depth' => 2]); $this->assertIdentical($plugin->getContent(), '
    • 1
      • 1.1
    ', 'Derived plugin instance correctly instantiated and configured.'); // Ensure that attempting to instantiate non-existing plugins throws a // PluginException. Test this for a non-existing base plugin, a non-existing // derivative plugin, and a base plugin that may not be used without // deriving. - foreach (array('non_existing', 'menu:non_existing', 'menu') as $invalid_id) { + foreach (['non_existing', 'menu:non_existing', 'menu'] as $invalid_id) { try { $this->mockBlockManager->createInstance($invalid_id); $this->fail('Drupal\Component\Plugin\Exception\ExceptionInterface expected'); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/InspectionTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/InspectionTest.php index 4ff9573c..454165d4 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/InspectionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/InspectionTest.php @@ -12,8 +12,8 @@ class InspectionTest extends PluginTestBase { /** * Ensure the test plugins correctly implement getPluginId() and getPluginDefinition(). */ - function testInspection() { - foreach (array('user_login') as $id) { + public function testInspection() { + foreach (['user_login'] as $id) { $plugin = $this->testPluginManager->createInstance($id); $expected_definition = $this->testPluginExpectedDefinitions[$id]; $this->assertIdentical($plugin->getPluginId(), $id); @@ -22,7 +22,7 @@ function testInspection() { } // Skip the 'menu' derived blocks, because MockMenuBlock does not implement // PluginInspectionInterface. The others do by extending PluginBase. - foreach (array('user_login', 'layout') as $id) { + foreach (['user_login', 'layout'] as $id) { $plugin = $this->mockBlockManager->createInstance($id); $expected_definition = $this->mockBlockExpectedDefinitions[$id]; $this->assertIdentical($plugin->getPluginId(), $id); @@ -30,7 +30,7 @@ function testInspection() { $this->assertIdentical($this->castSafeStrings($plugin->getPluginDefinition()), $expected_definition); } // Test a plugin manager that provides defaults. - foreach (array('test_block1', 'test_block2') as $id) { + foreach (['test_block1', 'test_block2'] as $id) { $plugin = $this->defaultsTestPluginManager->createInstance($id); $expected_definition = $this->defaultsTestPluginExpectedDefinitions[$id]; $this->assertIdentical($plugin->getPluginId(), $id); diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/PluginTestBase.php b/core/tests/Drupal/KernelTests/Core/Plugin/PluginTestBase.php index 2b70ed49..ccc82369 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/PluginTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/PluginTestBase.php @@ -20,7 +20,7 @@ abstract class PluginTestBase extends KernelTestBase { * * @var array */ - public static $modules = array('plugin_test'); + public static $modules = ['plugin_test']; protected $testPluginManager; protected $testPluginExpectedDefinitions; @@ -42,7 +42,7 @@ protected function setUp() { // as derivatives and ReflectionFactory. $this->testPluginManager = new TestPluginManager(); $this->mockBlockManager = new MockBlockManager(); - $module_handler = new ModuleHandler(\Drupal::root(), array(), new MemoryBackend('plugin'), $this->container->get('event_dispatcher')); + $module_handler = new ModuleHandler(\Drupal::root(), [], new MemoryBackend(), $this->container->get('event_dispatcher')); $this->defaultsTestPluginManager = new DefaultsTestPluginManager($module_handler); // The expected plugin definitions within each manager. Several tests assert @@ -50,81 +50,91 @@ protected function setUp() { // necessary API functions. // @see TestPluginManager::_construct(). // @see MockBlockManager::_construct(). - $this->testPluginExpectedDefinitions = array( - 'user_login' => array( + $this->testPluginExpectedDefinitions = [ + 'user_login' => [ 'label' => 'User login', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', - ), - ); - $this->mockBlockExpectedDefinitions = array( - 'user_login' => array( + ], + ]; + $this->mockBlockExpectedDefinitions = [ + 'user_login' => [ + 'id' => 'user_login', 'label' => 'User login', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', - ), - 'menu:main_menu' => array( + ], + 'menu:main_menu' => [ + 'id' => 'menu', 'label' => 'Main menu', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', - ), - 'menu:navigation' => array( + ], + 'menu:navigation' => [ + 'id' => 'menu', 'label' => 'Navigation', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', - ), - 'menu:foo' => array( + ], + 'menu:foo' => [ + 'id' => 'menu', 'label' => 'Base label', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', 'setting' => 'default', - ), - 'layout' => array( + ], + 'layout' => [ + 'id' => 'layout', 'label' => 'Layout', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlock', - ), - 'layout:foo' => array( + ], + 'layout:foo' => [ + 'id' => 'layout', 'label' => 'Layout Foo', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlock', - ), - 'user_name' => array( + ], + 'user_name' => [ + 'id' => 'user_name', 'label' => 'User name', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock', - 'context' => array( + 'context' => [ 'user' => new ContextDefinition('entity:user', 'User'), - ), - ), - 'user_name_optional' => array( + ], + ], + 'user_name_optional' => [ + 'id' => 'user_name_optional', 'label' => 'User name optional', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock', - 'context' => array( + 'context' => [ 'user' => new ContextDefinition('entity:user', 'User', FALSE), - ), - ), - 'string_context' => array( + ], + ], + 'string_context' => [ + 'id' => 'string_context', 'label' => 'String typed data', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\TypedDataStringBlock', - ), - 'complex_context' => array( + ], + 'complex_context' => [ + 'id' => 'complex_context', 'label' => 'Complex context', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock', - 'context' => array( + 'context' => [ 'user' => new ContextDefinition('entity:user', 'User'), 'node' => new ContextDefinition('entity:node', 'Node'), - ), - ), - ); - $this->defaultsTestPluginExpectedDefinitions = array( - 'test_block1' => array( - 'metadata' => array( + ], + ], + ]; + $this->defaultsTestPluginExpectedDefinitions = [ + 'test_block1' => [ + 'metadata' => [ 'default' => TRUE, 'custom' => TRUE, - ), + ], 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockTestBlock', - ), - 'test_block2' => array( - 'metadata' => array( + ], + 'test_block2' => [ + 'metadata' => [ 'default' => FALSE, 'custom' => TRUE, - ), + ], 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockTestBlock', - ), - ); + ], + ]; } } diff --git a/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php b/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php index 3ea4c66e..b4e122b4 100644 --- a/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Queue/QueueSerializationTest.php @@ -30,7 +30,7 @@ class QueueSerializationTest extends KernelTestBase implements FormInterface { * * @var array */ - public static $modules = array('system', 'user', 'aggregator'); + public static $modules = ['system', 'user', 'aggregator']; /** * {@inheritdoc} @@ -80,10 +80,10 @@ protected function setUp() { $this->installSchema('system', ['key_value_expire', 'sequences']); $this->installEntitySchema('user'); $this->queue = \Drupal::service('queue.database')->get('aggregator_refresh'); - $test_user = User::create(array( + $test_user = User::create([ 'name' => 'foobar', 'mail' => 'foobar@example.com', - )); + ]); $test_user->save(); \Drupal::service('current_user')->setAccount($test_user); } diff --git a/core/tests/Drupal/KernelTests/Core/Queue/QueueTest.php b/core/tests/Drupal/KernelTests/Core/Queue/QueueTest.php index 1a2af7d4..cd2ed517 100644 --- a/core/tests/Drupal/KernelTests/Core/Queue/QueueTest.php +++ b/core/tests/Drupal/KernelTests/Core/Queue/QueueTest.php @@ -24,7 +24,7 @@ public function testSystemQueue() { $queue2 = new DatabaseQueue($this->randomMachineName(), Database::getConnection()); $queue2->createQueue(); - $this->queueTest($queue1, $queue2); + $this->runQueueTest($queue1, $queue2); } /** @@ -37,7 +37,7 @@ public function testMemoryQueue() { $queue2 = new Memory($this->randomMachineName()); $queue2->createQueue(); - $this->queueTest($queue1, $queue2); + $this->runQueueTest($queue1, $queue2); } /** @@ -48,11 +48,11 @@ public function testMemoryQueue() { * @param \Drupal\Core\Queue\QueueInterface $queue2 * An instantiated queue object. */ - protected function queueTest($queue1, $queue2) { + protected function runQueueTest($queue1, $queue2) { // Create four items. - $data = array(); + $data = []; for ($i = 0; $i < 4; $i++) { - $data[] = array($this->randomMachineName() => $this->randomMachineName()); + $data[] = [$this->randomMachineName() => $this->randomMachineName()]; } // Queue items 1 and 2 in the queue1. @@ -60,8 +60,8 @@ protected function queueTest($queue1, $queue2) { $queue1->createItem($data[1]); // Retrieve two items from queue1. - $items = array(); - $new_items = array(); + $items = []; + $new_items = []; $items[] = $item = $queue1->claimItem(); $new_items[] = $item->data; diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/ActionsTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/ActionsTest.php new file mode 100644 index 00000000..135c7aab --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Render/Element/ActionsTest.php @@ -0,0 +1,70 @@ + 'actions']; + $form['actions']['key'] = [ + '#type' => 'submit', + '#value' => 'Key', + '#dropbutton' => 'submit', + '#cache' => [ + 'tags' => ['foo'], + ], + '#attached' => [ + 'library' => [ + 'system/base', + ], + ], + ]; + $form['actions']['submit'] = [ + '#type' => 'submit', + '#value' => 'Save', + ]; + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + } + + public function testDropbuttonWithBubbleableMetadata() { + $result = \Drupal::formBuilder()->getForm($this); + \Drupal::service('renderer')->renderRoot($result); + $this->assertEquals(['system/base', 'core/drupal.dropbutton'], $result['#attached']['library']); + $this->assertEquals(['foo'], $result['#cache']['tags']); + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php index 3e11695a..906e74bb 100644 --- a/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php +++ b/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php @@ -18,11 +18,11 @@ class RenderElementTypesTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'router_test'); + public static $modules = ['system', 'router_test']; protected function setUp() { parent::setUp(); - $this->installConfig(array('system')); + $this->installConfig(['system']); \Drupal::service('router.builder')->rebuild(); } @@ -51,141 +51,141 @@ protected function assertElements(array $elements, $expected_html, $message) { /** * Tests system #type 'container'. */ - function testContainer() { + public function testContainer() { // Basic container with no attributes. - $this->assertElements(array( + $this->assertElements([ '#type' => 'container', '#markup' => 'foo', - ), "
    foo
    \n", "#type 'container' with no HTML attributes"); + ], "
    foo
    \n", "#type 'container' with no HTML attributes"); // Container with a class. - $this->assertElements(array( + $this->assertElements([ '#type' => 'container', '#markup' => 'foo', - '#attributes' => array( - 'class' => array('bar'), - ), - ), '
    foo
    ' . "\n", "#type 'container' with a class HTML attribute"); + '#attributes' => [ + 'class' => ['bar'], + ], + ], '
    foo
    ' . "\n", "#type 'container' with a class HTML attribute"); // Container with children. - $this->assertElements(array( + $this->assertElements([ '#type' => 'container', - 'child' => array( + 'child' => [ '#markup' => 'foo', - ), - ), "
    foo
    \n", "#type 'container' with child elements"); + ], + ], "
    foo
    \n", "#type 'container' with child elements"); } /** * Tests system #type 'html_tag'. */ - function testHtmlTag() { + public function testHtmlTag() { // Test void element. - $this->assertElements(array( + $this->assertElements([ '#type' => 'html_tag', '#tag' => 'meta', '#value' => 'ignored', - '#attributes' => array( + '#attributes' => [ 'name' => 'description', 'content' => 'Drupal test', - ), - ), '' . "\n", "#type 'html_tag', void element renders properly"); + ], + ], '' . "\n", "#type 'html_tag', void element renders properly"); // Test non-void element. - $this->assertElements(array( + $this->assertElements([ '#type' => 'html_tag', '#tag' => 'section', '#value' => 'value', - '#attributes' => array( - 'class' => array('unicorns'), - ), - ), '
    value
    ' . "\n", "#type 'html_tag', non-void element renders properly"); + '#attributes' => [ + 'class' => ['unicorns'], + ], + ], '
    value
    ' . "\n", "#type 'html_tag', non-void element renders properly"); // Test empty void element tag. - $this->assertElements(array( + $this->assertElements([ '#type' => 'html_tag', '#tag' => 'link', - ), "\n", "#type 'html_tag' empty void element renders properly"); + ], "\n", "#type 'html_tag' empty void element renders properly"); // Test empty non-void element tag. - $this->assertElements(array( + $this->assertElements([ '#type' => 'html_tag', '#tag' => 'section', - ), "
    \n", "#type 'html_tag' empty non-void element renders properly"); + ], "
    \n", "#type 'html_tag' empty non-void element renders properly"); } /** * Tests system #type 'more_link'. */ - function testMoreLink() { - $elements = array( - array( + public function testMoreLink() { + $elements = [ + [ 'name' => "#type 'more_link' anchor tag generation without extra classes", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromUri('https://www.drupal.org'), - ), + ], 'expected' => '//div[@class="more-link"]/a[@href="https://www.drupal.org" and text()="More"]', - ), - array( + ], + [ 'name' => "#type 'more_link' anchor tag generation with different link text", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromUri('https://www.drupal.org'), '#title' => 'More Titles', - ), + ], 'expected' => '//div[@class="more-link"]/a[@href="https://www.drupal.org" and text()="More Titles"]', - ), - array( + ], + [ 'name' => "#type 'more_link' anchor tag generation with attributes on wrapper", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromUri('https://www.drupal.org'), - '#theme_wrappers' => array( - 'container' => array( - '#attributes' => array( + '#theme_wrappers' => [ + 'container' => [ + '#attributes' => [ 'title' => 'description', - 'class' => array('more-link', 'drupal', 'test'), - ), - ), - ), - ), + 'class' => ['more-link', 'drupal', 'test'], + ], + ], + ], + ], 'expected' => '//div[@title="description" and contains(@class, "more-link") and contains(@class, "drupal") and contains(@class, "test")]/a[@href="https://www.drupal.org" and text()="More"]', - ), - array( + ], + [ 'name' => "#type 'more_link' anchor tag with a relative path", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromRoute('router_test.1'), - ), + ], 'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('router_test.1')->toString() . '" and text()="More"]', - ), - array( + ], + [ 'name' => "#type 'more_link' anchor tag with a route", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromRoute('router_test.1'), - ), + ], 'expected' => '//div[@class="more-link"]/a[@href="' . \Drupal::urlGenerator()->generate('router_test.1') . '" and text()="More"]', - ), - array( + ], + [ 'name' => "#type 'more_link' anchor tag with an absolute path", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromRoute('system.admin_content'), - '#options' => array('absolute' => TRUE), - ), + '#options' => ['absolute' => TRUE], + ], 'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('system.admin_content')->setAbsolute()->toString() . '" and text()="More"]', - ), - array( + ], + [ 'name' => "#type 'more_link' anchor tag to the front page", - 'value' => array( + 'value' => [ '#type' => 'more_link', '#url' => Url::fromRoute(''), - ), + ], 'expected' => '//div[@class="more-link"]/a[@href="' . Url::fromRoute('')->toString() . '" and text()="More"]', - ), - ); + ], + ]; foreach ($elements as $element) { $xml = new \SimpleXMLElement(\Drupal::service('renderer')->renderRoot($element['value'])); @@ -197,26 +197,26 @@ function testMoreLink() { /** * Tests system #type 'system_compact_link'. */ - function testSystemCompactLink() { - $elements = array( - array( + public function testSystemCompactLink() { + $elements = [ + [ 'name' => "#type 'system_compact_link' when admin compact mode is off", - 'value' => array( + 'value' => [ '#type' => 'system_compact_link', - ), + ], 'expected' => '//div[@class="compact-link"]/a[contains(@href, "admin/compact/on?") and text()="Hide descriptions"]', - ), - array( + ], + [ 'name' => "#type 'system_compact_link' when adding extra attributes", - 'value' => array( + 'value' => [ '#type' => 'system_compact_link', - '#attributes' => array( - 'class' => array('kittens-rule'), - ), - ), + '#attributes' => [ + 'class' => ['kittens-rule'], + ], + ], 'expected' => '//div[@class="compact-link"]/a[contains(@href, "admin/compact/on?") and @class="kittens-rule" and text()="Hide descriptions"]', - ), - ); + ], + ]; foreach ($elements as $element) { $xml = new \SimpleXMLElement(\Drupal::service('renderer')->renderRoot($element['value'])); @@ -227,13 +227,13 @@ function testSystemCompactLink() { // Set admin compact mode on for additional tests. \Drupal::request()->cookies->set('Drupal_visitor_admin_compact_mode', TRUE); - $element = array( + $element = [ 'name' => "#type 'system_compact_link' when admin compact mode is on", - 'value' => array( + 'value' => [ '#type' => 'system_compact_link', - ), + ], 'expected' => '//div[@class="compact-link"]/a[contains(@href, "admin/compact?") and text()="Show descriptions"]', - ); + ]; $xml = new \SimpleXMLElement(\Drupal::service('renderer')->renderRoot($element['value'])); $result = $xml->xpath($element['expected']); diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/TableSortExtenderTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/TableSortExtenderTest.php index a77d52e5..4291179f 100644 --- a/core/tests/Drupal/KernelTests/Core/Render/Element/TableSortExtenderTest.php +++ b/core/tests/Drupal/KernelTests/Core/Render/Element/TableSortExtenderTest.php @@ -16,125 +16,125 @@ class TableSortExtenderTest extends KernelTestBase { /** * Tests tablesort_init(). */ - function testTableSortInit() { + public function testTableSortInit() { // Test simple table headers. - $headers = array('foo', 'bar', 'baz'); + $headers = ['foo', 'bar', 'baz']; // Reset $request->query to prevent parameters from Simpletest and Batch API // ending up in $ts['query']. - $expected_ts = array( + $expected_ts = [ 'name' => 'foo', 'sql' => '', 'sort' => 'asc', - 'query' => array(), - ); + 'query' => [], + ]; $request = Request::createFromGlobals(); - $request->query->replace(array()); + $request->query->replace([]); \Drupal::getContainer()->get('request_stack')->push($request); $ts = tablesort_init($headers); - $this->verbose(strtr('$ts:
    !ts
    ', array('!ts' => Html::escape(var_export($ts, TRUE))))); + $this->verbose(strtr('$ts:
    !ts
    ', ['!ts' => Html::escape(var_export($ts, TRUE))])); $this->assertEqual($ts, $expected_ts, 'Simple table headers sorted correctly.'); // Test with simple table headers plus $_GET parameters that should _not_ // override the default. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ // This should not override the table order because only complex // headers are overridable. 'order' => 'bar', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $ts = tablesort_init($headers); - $this->verbose(strtr('$ts:
    !ts
    ', array('!ts' => Html::escape(var_export($ts, TRUE))))); + $this->verbose(strtr('$ts:
    !ts
    ', ['!ts' => Html::escape(var_export($ts, TRUE))])); $this->assertEqual($ts, $expected_ts, 'Simple table headers plus non-overriding $_GET parameters sorted correctly.'); // Test with simple table headers plus $_GET parameters that _should_ // override the default. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ 'sort' => 'DESC', // Add an unrelated parameter to ensure that tablesort will include // it in the links that it creates. 'alpha' => 'beta', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $expected_ts['sort'] = 'desc'; - $expected_ts['query'] = array('alpha' => 'beta'); + $expected_ts['query'] = ['alpha' => 'beta']; $ts = tablesort_init($headers); - $this->verbose(strtr('$ts:
    !ts
    ', array('!ts' => Html::escape(var_export($ts, TRUE))))); + $this->verbose(strtr('$ts:
    !ts
    ', ['!ts' => Html::escape(var_export($ts, TRUE))])); $this->assertEqual($ts, $expected_ts, 'Simple table headers plus $_GET parameters sorted correctly.'); // Test complex table headers. - $headers = array( + $headers = [ 'foo', - array( + [ 'data' => '1', 'field' => 'one', 'sort' => 'asc', 'colspan' => 1, - ), - array( + ], + [ 'data' => '2', 'field' => 'two', 'sort' => 'desc', - ), - ); + ], + ]; // Reset $_GET from previous assertion. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ 'order' => '2', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $ts = tablesort_init($headers); - $expected_ts = array( + $expected_ts = [ 'name' => '2', 'sql' => 'two', 'sort' => 'desc', - 'query' => array(), - ); - $this->verbose(strtr('$ts:
    !ts
    ', array('!ts' => Html::escape(var_export($ts, TRUE))))); + 'query' => [], + ]; + $this->verbose(strtr('$ts:
    !ts
    ', ['!ts' => Html::escape(var_export($ts, TRUE))])); $this->assertEqual($ts, $expected_ts, 'Complex table headers sorted correctly.'); // Test complex table headers plus $_GET parameters that should _not_ // override the default. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ // This should not override the table order because this header does not // exist. 'order' => 'bar', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $ts = tablesort_init($headers); - $expected_ts = array( + $expected_ts = [ 'name' => '1', 'sql' => 'one', 'sort' => 'asc', - 'query' => array(), - ); - $this->verbose(strtr('$ts:
    !ts
    ', array('!ts' => Html::escape(var_export($ts, TRUE))))); + 'query' => [], + ]; + $this->verbose(strtr('$ts:
    !ts
    ', ['!ts' => Html::escape(var_export($ts, TRUE))])); $this->assertEqual($ts, $expected_ts, 'Complex table headers plus non-overriding $_GET parameters sorted correctly.'); // Test complex table headers plus $_GET parameters that _should_ // override the default. $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ 'order' => '1', 'sort' => 'ASC', // Add an unrelated parameter to ensure that tablesort will include // it in the links that it creates. 'alpha' => 'beta', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); - $expected_ts = array( + $expected_ts = [ 'name' => '1', 'sql' => 'one', 'sort' => 'asc', - 'query' => array('alpha' => 'beta'), - ); + 'query' => ['alpha' => 'beta'], + ]; $ts = tablesort_init($headers); - $this->verbose(strtr('$ts:
    !ts
    ', array('!ts' => Html::escape(var_export($ts, TRUE))))); + $this->verbose(strtr('$ts:
    !ts
    ', ['!ts' => Html::escape(var_export($ts, TRUE))])); $this->assertEqual($ts, $expected_ts, 'Complex table headers plus $_GET parameters sorted correctly.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/TableTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/TableTest.php index 34cbfc03..5966eaa7 100644 --- a/core/tests/Drupal/KernelTests/Core/Render/Element/TableTest.php +++ b/core/tests/Drupal/KernelTests/Core/Render/Element/TableTest.php @@ -21,15 +21,15 @@ class TableTest extends KernelTestBase { /** * Tableheader.js provides 'sticky' table headers, and is included by default. */ - function testThemeTableStickyHeaders() { - $header = array('one', 'two', 'three'); - $rows = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)); - $table = array( + public function testThemeTableStickyHeaders() { + $header = ['one', 'two', 'three']; + $rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#sticky' => TRUE, - ); + ]; $this->render($table); // Make sure tableheader.js was attached. $tableheader = $this->xpath("//script[contains(@src, 'tableheader.js')]"); @@ -40,13 +40,13 @@ function testThemeTableStickyHeaders() { /** * If $sticky is FALSE, no tableheader.js should be included. */ - function testThemeTableNoStickyHeaders() { - $header = array('one', 'two', 'three'); - $rows = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)); - $attributes = array(); + public function testThemeTableNoStickyHeaders() { + $header = ['one', 'two', 'three']; + $rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + $attributes = []; $caption = NULL; - $colgroups = array(); - $table = array( + $colgroups = []; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, @@ -54,7 +54,7 @@ function testThemeTableNoStickyHeaders() { '#caption' => $caption, '#colgroups' => $colgroups, '#sticky' => FALSE, - ); + ]; $this->render($table); // Make sure tableheader.js was not attached. $tableheader = $this->xpath("//script[contains(@src, 'tableheader.js')]"); @@ -66,24 +66,24 @@ function testThemeTableNoStickyHeaders() { * Tests that the table header is printed correctly even if there are no rows, * and that the empty text is displayed correctly. */ - function testThemeTableWithEmptyMessage() { - $header = array( + public function testThemeTableWithEmptyMessage() { + $header = [ 'Header 1', - array( + [ 'data' => 'Header 2', 'colspan' => 2, - ), - ); - $table = array( + ], + ]; + $table = [ '#type' => 'table', '#header' => $header, - '#rows' => array(), + '#rows' => [], '#empty' => 'Empty row.', - ); + ]; // Enable the Classy theme. \Drupal::service('theme_handler')->install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); $this->render($table); $this->removeWhiteSpace(); @@ -94,17 +94,17 @@ function testThemeTableWithEmptyMessage() { /** * Tests that the 'no_striping' option works correctly. */ - function testThemeTableWithNoStriping() { - $rows = array( - array( - 'data' => array(1), + public function testThemeTableWithNoStriping() { + $rows = [ + [ + 'data' => [1], 'no_striping' => TRUE, - ), - ); - $table = array( + ], + ]; + $table = [ '#type' => 'table', '#rows' => $rows, - ); + ]; $this->render($table); $this->assertNoRaw('class="odd"', 'Odd/even classes were not added because $no_striping = TRUE.'); $this->assertNoRaw('no_striping', 'No invalid no_striping HTML attribute was printed.'); @@ -113,19 +113,19 @@ function testThemeTableWithNoStriping() { /** * Test that the 'footer' option works correctly. */ - function testThemeTableFooter() { - $footer = array( - array( - 'data' => array(1), - ), - array('Foo'), - ); + public function testThemeTableFooter() { + $footer = [ + [ + 'data' => [1], + ], + ['Foo'], + ]; - $table = array( + $table = [ '#type' => 'table', - '#rows' => array(), + '#rows' => [], '#footer' => $footer, - ); + ]; $this->render($table); $this->removeWhiteSpace(); @@ -135,18 +135,18 @@ function testThemeTableFooter() { /** * Tests that the 'header' option in cells works correctly. */ - function testThemeTableHeaderCellOption() { - $rows = array( - array( - array('data' => 1, 'header' => TRUE), - array('data' => 1, 'header' => FALSE), - array('data' => 1), - ), - ); - $table = array( + public function testThemeTableHeaderCellOption() { + $rows = [ + [ + ['data' => 1, 'header' => TRUE], + ['data' => 1, 'header' => FALSE], + ['data' => 1], + ], + ]; + $table = [ '#type' => 'table', '#rows' => $rows, - ); + ]; $this->render($table); $this->removeWhiteSpace(); $this->assertRaw('
', 'The th and td tags was printed correctly.'); @@ -156,14 +156,14 @@ function testThemeTableHeaderCellOption() { * Tests that the 'responsive-table' class is applied correctly. */ public function testThemeTableResponsive() { - $header = array('one', 'two', 'three'); - $rows = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)); - $table = array( + $header = ['one', 'two', 'three']; + $rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#responsive' => TRUE, - ); + ]; $this->render($table); $this->assertRaw('responsive-enabled', 'The responsive-enabled class was printed correctly.'); } @@ -172,12 +172,12 @@ public function testThemeTableResponsive() { * Tests that the 'responsive-table' class is not applied without headers. */ public function testThemeTableNotResponsiveHeaders() { - $rows = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)); - $table = array( + $rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + $table = [ '#type' => 'table', '#rows' => $rows, '#responsive' => TRUE, - ); + ]; $this->render($table); $this->assertNoRaw('responsive-enabled', 'The responsive-enabled class is not applied without table headers.'); } @@ -186,14 +186,14 @@ public function testThemeTableNotResponsiveHeaders() { * Tests that 'responsive-table' class only applied when responsive is TRUE. */ public function testThemeTableNotResponsiveProperty() { - $header = array('one', 'two', 'three'); - $rows = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)); - $table = array( + $header = ['one', 'two', 'three']; + $rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#responsive' => FALSE, - ); + ]; $this->render($table); $this->assertNoRaw('responsive-enabled', 'The responsive-enabled class is not applied without the "responsive" property set to TRUE.'); } @@ -202,21 +202,21 @@ public function testThemeTableNotResponsiveProperty() { * Tests 'priority-medium' and 'priority-low' classes. */ public function testThemeTableResponsivePriority() { - $header = array( + $header = [ // Test associative header indices. - 'associative_key' => array('data' => 1, 'class' => array(RESPONSIVE_PRIORITY_MEDIUM)), + 'associative_key' => ['data' => 1, 'class' => [RESPONSIVE_PRIORITY_MEDIUM]], // Test non-associative header indices. - array('data' => 2, 'class' => array(RESPONSIVE_PRIORITY_LOW)), + ['data' => 2, 'class' => [RESPONSIVE_PRIORITY_LOW]], // Test no responsive priorities. - array('data' => 3), - ); - $rows = array(array(4, 5, 6)); - $table = array( + ['data' => 3], + ]; + $rows = [[4, 5, 6]]; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#responsive' => TRUE, - ); + ]; $this->render($table); $this->assertRaw('', 'Header 1: the priority-medium class was applied correctly.'); $this->assertRaw('', 'Header 2: the priority-low class was applied correctly.'); @@ -230,28 +230,28 @@ public function testThemeTableResponsivePriority() { * Tests header elements with a mix of string and render array values. */ public function testThemeTableHeaderRenderArray() { - $header = array( - array ( - 'data' => array( + $header = [ + [ + 'data' => [ '#markup' => 'one', - ), - ), + ], + ], 'two', - array ( - 'data' => array( + [ + 'data' => [ '#type' => 'html_tag', '#tag' => 'b', '#value' => 'three', - ), - ), - ); - $rows = array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)); - $table = array( + ], + ], + ]; + $rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#responsive' => FALSE, - ); + ]; $this->render($table); $this->removeWhiteSpace(); $this->assertRaw('', 'Table header found.'); @@ -261,37 +261,37 @@ public function testThemeTableHeaderRenderArray() { * Tests row elements with a mix of string and render array values. */ public function testThemeTableRowRenderArray() { - $header = array('one', 'two', 'three'); - $rows = array( - array( + $header = ['one', 'two', 'three']; + $rows = [ + [ '1-one', - array( + [ 'data' => '1-two' - ), + ], '1-three', - ), - array( - array ( - 'data' => array( + ], + [ + [ + 'data' => [ '#markup' => '2-one', - ), - ), + ], + ], '2-two', - array ( - 'data' => array( + [ + 'data' => [ '#type' => 'html_tag', '#tag' => 'b', '#value' => '2-three', - ), - ), - ), - ); - $table = array( + ], + ], + ], + ]; + $table = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#responsive' => FALSE, - ); + ]; $this->render($table); $this->removeWhiteSpace(); $this->assertRaw('', 'Table row 1 found.'); diff --git a/core/tests/Drupal/KernelTests/Core/Render/RenderTest.php b/core/tests/Drupal/KernelTests/Core/Render/RenderTest.php index 8860c19a..a64b553a 100644 --- a/core/tests/Drupal/KernelTests/Core/Render/RenderTest.php +++ b/core/tests/Drupal/KernelTests/Core/Render/RenderTest.php @@ -16,12 +16,12 @@ class RenderTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'common_test'); + public static $modules = ['system', 'common_test']; /** * Tests theme preprocess functions being able to attach assets. */ - function testDrupalRenderThemePreprocessAttached() { + public function testDrupalRenderThemePreprocessAttached() { \Drupal::state()->set('theme_preprocess_attached_test', TRUE); $test_element = [ diff --git a/core/tests/Drupal/KernelTests/Core/Routing/ContentNegotiationRoutingTest.php b/core/tests/Drupal/KernelTests/Core/Routing/ContentNegotiationRoutingTest.php index 812e4378..34c6d585 100644 --- a/core/tests/Drupal/KernelTests/Core/Routing/ContentNegotiationRoutingTest.php +++ b/core/tests/Drupal/KernelTests/Core/Routing/ContentNegotiationRoutingTest.php @@ -36,7 +36,7 @@ public function register(ContainerBuilder $container) { /** * Tests the content negotiation aspect of routing. */ - function testContentRouting() { + public function testContentRouting() { /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */ $path_alias_storage = $this->container->get('path.alias_storage'); // Alias with extension pointing to no extension/constant content-type. @@ -111,8 +111,10 @@ public function testFullNegotiation() { $tests = [ // ['path', 'accept', 'content-type'], - ['conneg/negotiate', '', 'text/html'], // 406? - ['conneg/negotiate', '', 'text/html'], // 406? + // 406? + ['conneg/negotiate', '', 'text/html'], + // 406? + ['conneg/negotiate', '', 'text/html'], // ['conneg/negotiate', '*/*', '??'], ['conneg/negotiate', 'application/json', 'application/json'], ['conneg/negotiate', 'application/xml', 'application/xml'], diff --git a/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php b/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php index 85649484..a791454f 100644 --- a/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php +++ b/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php @@ -155,7 +155,7 @@ public function testBacktraceEscaping() { $kernel = \Drupal::getContainer()->get('http_kernel'); $response = $kernel->handle($request)->prepare($request); $this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR); - $this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8'); + $this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8'); // Test both that the backtrace is properly escaped, and that the unescaped // string is not output at all. @@ -178,7 +178,7 @@ public function testExceptionEscaping() { $kernel = \Drupal::getContainer()->get('http_kernel'); $response = $kernel->handle($request)->prepare($request); $this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR); - $this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8'); + $this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8'); // Test message is properly escaped, and that the unescaped string is not // output at all. @@ -192,10 +192,11 @@ public function testExceptionEscaping() { $kernel = \Drupal::getContainer()->get('http_kernel'); $response = $kernel->handle($request)->prepare($request); // As the Content-type is text/plain the fact that the raw string is - // contained in the output does not matter. + // contained in the output would not matter, but because it is output by the + // final exception subscriber, it is printed as partial HTML, and hence + // escaped. $this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8'); - $this->setRawContent($response->getContent()); - $this->assertRaw($string); + $this->assertStringStartsWith('The website encountered an unexpected error. Please try again later.

Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException: Not acceptable format: json<script>alert(123);</script> in ', $response->getContent()); } } diff --git a/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php b/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php index 7c06df0b..1428fde9 100644 --- a/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php +++ b/core/tests/Drupal/KernelTests/Core/Routing/MatcherDumperTest.php @@ -2,7 +2,9 @@ namespace Drupal\KernelTests\Core\Routing; +use Drupal\Core\Cache\MemoryBackend; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; +use Drupal\Core\Lock\NullLockBackend; use Drupal\Core\State\State; use Drupal\KernelTests\KernelTestBase; use Symfony\Component\Routing\Route; @@ -36,13 +38,13 @@ protected function setUp() { parent::setUp(); $this->fixtures = new RoutingFixtures(); - $this->state = new State(new KeyValueMemoryFactory()); + $this->state = new State(new KeyValueMemoryFactory(), new MemoryBackend('test'), new NullLockBackend()); } /** * Confirms that the dumper can be instantiated successfully. */ - function testCreate() { + public function testCreate() { $connection = Database::getConnection(); $dumper = new MatcherDumper($connection, $this->state); @@ -53,7 +55,7 @@ function testCreate() { /** * Confirms that we can add routes to the dumper. */ - function testAddRoutes() { + public function testAddRoutes() { $connection = Database::getConnection(); $dumper = new MatcherDumper($connection, $this->state); @@ -74,7 +76,7 @@ function testAddRoutes() { /** * Confirms that we can add routes to the dumper when it already has some. */ - function testAddAdditionalRoutes() { + public function testAddAdditionalRoutes() { $connection = Database::getConnection(); $dumper = new MatcherDumper($connection, $this->state); @@ -123,9 +125,9 @@ public function testDump() { $this->fixtures->createTables($connection); - $dumper->dump(array('provider' => 'test')); + $dumper->dump(['provider' => 'test']); - $record = $connection->query("SELECT * FROM {test_routes} WHERE name= :name", array(':name' => 'test_route'))->fetchObject(); + $record = $connection->query("SELECT * FROM {test_routes} WHERE name= :name", [':name' => 'test_route'])->fetchObject(); $loaded_route = unserialize($record->route); @@ -153,15 +155,15 @@ public function testMenuMasksGeneration() { $this->fixtures->createTables($connection); - $dumper->dump(array('provider' => 'test')); + $dumper->dump(['provider' => 'test']); // Using binary for readability, we expect a 0 at any wildcard slug. They // should be ordered from longest to shortest. - $expected = array( + $expected = [ bindec('1011111'), bindec('10111'), bindec('111'), bindec('101'), - ); + ]; $this->assertEqual($this->state->get('routing.menu_masks.test_routes'), $expected); } diff --git a/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php b/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php index d28ca5e7..ed59f2f0 100644 --- a/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php +++ b/core/tests/Drupal/KernelTests/Core/Routing/RouteProviderTest.php @@ -7,10 +7,12 @@ namespace Drupal\KernelTests\Core\Routing; +use Drupal\Component\Utility\Unicode; use Drupal\Core\Cache\MemoryBackend; use Drupal\Core\Database\Database; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; +use Drupal\Core\Lock\NullLockBackend; use Drupal\Core\Path\CurrentPathStack; use Drupal\Core\Routing\MatcherDumper; use Drupal\Core\Routing\RouteProvider; @@ -81,9 +83,9 @@ class RouteProviderTest extends KernelTestBase { protected function setUp() { parent::setUp(); $this->fixtures = new RoutingFixtures(); - $this->state = new State(new KeyValueMemoryFactory()); + $this->state = new State(new KeyValueMemoryFactory(), new MemoryBackend('test'), new NullLockBackend()); $this->currentPath = new CurrentPathStack(new RequestStack()); - $this->cache = new MemoryBackend('data'); + $this->cache = new MemoryBackend(); $this->pathProcessor = \Drupal::service('path_processor_manager'); $this->cacheTagsInvalidator = \Drupal::service('cache_tags.invalidator'); } @@ -115,7 +117,7 @@ public function testCandidateOutlines() { $connection = Database::getConnection(); $provider = new TestRouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); - $parts = array('node', '5', 'edit'); + $parts = ['node', '5', 'edit']; $candidates = $provider->getCandidateOutlines($parts); @@ -143,7 +145,7 @@ public function testEmptyPathCandidatesOutlines() { /** * Confirms that we can find routes with the exact incoming path. */ - function testExactPathMatch() { + public function testExactPathMatch() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); @@ -167,7 +169,7 @@ function testExactPathMatch() { /** * Confirms that we can find routes whose pattern would match the request. */ - function testOutlinePathMatch() { + public function testOutlinePathMatch() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); @@ -194,9 +196,110 @@ function testOutlinePathMatch() { } /** - * Confirms that a trailing slash on the request doesn't result in a 404. + * Data provider for testMixedCasePaths() */ - function testOutlinePathMatchTrailingSlash() { + public function providerMixedCaseRoutePaths() { + return [ + ['/path/one', 'route_a'], + ['/path/two', NULL], + ['/PATH/one', 'route_a'], + ['/path/2/one', 'route_b', 'PUT'], + ['/paTH/3/one', 'route_b', 'PUT'], + // There should be no lower case of a Hebrew letter. + ['/somewhere/4/over/the/קainbow', 'route_c'], + ['/Somewhere/5/over/the/קainboW', 'route_c'], + ['/another/llama/aboUT/22', 'route_d'], + ['/another/llama/about/22', 'route_d'], + ['/place/meΦω', 'route_e', 'HEAD'], + ['/place/meφΩ', 'route_e', 'HEAD'], + ]; + } + + /** + * Confirms that we find routes using a case-insensitive path match. + * + * @dataProvider providerMixedCaseRoutePaths + */ + public function testMixedCasePaths($path, $expected_route_name, $method = 'GET') { + // The case-insensitive behavior for higher UTF-8 characters depends on + // \Drupal\Component\Utility\Unicode::strtolower() using mb_strtolower() + // but kernel tests do not currently run the check that enables it. + // @todo remove this when https://www.drupal.org/node/2849669 is fixed. + Unicode::check(); + + $connection = Database::getConnection(); + $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); + + $this->fixtures->createTables($connection); + + $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); + $dumper->addRoutes($this->fixtures->mixedCaseRouteCollection()); + $dumper->dump(); + + $request = Request::create($path, $method); + + $routes = $provider->getRouteCollectionForRequest($request); + + if ($expected_route_name) { + $this->assertEquals(1, count($routes), 'The correct number of routes was found.'); + $this->assertNotNull($routes->get($expected_route_name), 'The first matching route was found.'); + } + else { + $this->assertEquals(0, count($routes), 'No routes matched.'); + } + } + + /** + * Data provider for testMixedCasePaths() + */ + public function providerDuplicateRoutePaths() { + // When matching routes with the same fit the route with the lowest-sorting + // name should end up first in the resulting route collection. + return [ + ['/path/one', 3, 'route_a'], + ['/PATH/one', 3, 'route_a'], + ['/path/two', 1, 'route_d'], + ['/PATH/three', 0], + ['/place/meΦω', 2, 'route_e'], + ['/placE/meφΩ', 2, 'route_e'], + ]; + } + + /** + * Confirms that we find all routes with the same path. + * + * @dataProvider providerDuplicateRoutePaths + */ + public function testDuplicateRoutePaths($path, $number, $expected_route_name = NULL) { + + // The case-insensitive behavior for higher UTF-8 characters depends on + // \Drupal\Component\Utility\Unicode::strtolower() using mb_strtolower() + // but kernel tests do not currently run the check that enables it. + // @todo remove this when https://www.drupal.org/node/2849669 is fixed. + Unicode::check(); + + $connection = Database::getConnection(); + $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); + + $this->fixtures->createTables($connection); + + $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); + $dumper->addRoutes($this->fixtures->duplicatePathsRouteCollection()); + $dumper->dump(); + + $request = Request::create($path); + $routes = $provider->getRouteCollectionForRequest($request); + $this->assertEquals($number, count($routes), 'The correct number of routes was found.'); + if ($expected_route_name) { + $route_name = key(current($routes)); + $this->assertEquals($expected_route_name, $route_name, 'The expected route name was found.'); + } + } + + /** + * Confirms that a trailing slash on the request does not result in a 404. + */ + public function testOutlinePathMatchTrailingSlash() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); @@ -225,16 +328,16 @@ function testOutlinePathMatchTrailingSlash() { /** * Confirms that we can find routes whose pattern would match the request. */ - function testOutlinePathMatchDefaults() { + public function testOutlinePathMatchDefaults() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); $this->fixtures->createTables($connection); $collection = new RouteCollection(); - $collection->add('poink', new Route('/some/path/{value}', array( + $collection->add('poink', new Route('/some/path/{value}', [ 'value' => 'poink', - ))); + ])); $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); $dumper->addRoutes($collection); @@ -263,16 +366,16 @@ function testOutlinePathMatchDefaults() { /** * Confirms that we can find routes whose pattern would match the request. */ - function testOutlinePathMatchDefaultsCollision() { + public function testOutlinePathMatchDefaultsCollision() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); $this->fixtures->createTables($connection); $collection = new RouteCollection(); - $collection->add('poink', new Route('/some/path/{value}', array( + $collection->add('poink', new Route('/some/path/{value}', [ 'value' => 'poink', - ))); + ])); $collection->add('narf', new Route('/some/path/here')); $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); @@ -302,16 +405,16 @@ function testOutlinePathMatchDefaultsCollision() { /** * Confirms that we can find routes whose pattern would match the request. */ - function testOutlinePathMatchDefaultsCollision2() { + public function testOutlinePathMatchDefaultsCollision2() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); $this->fixtures->createTables($connection); $collection = new RouteCollection(); - $collection->add('poink', new Route('/some/path/{value}', array( + $collection->add('poink', new Route('/some/path/{value}', [ 'value' => 'poink', - ))); + ])); $collection->add('narf', new Route('/some/path/here')); $collection->add('eep', new Route('/something/completely/different')); @@ -328,7 +431,7 @@ function testOutlinePathMatchDefaultsCollision2() { $routes_array = $routes->all(); $this->assertEqual(count($routes), 2, 'The correct number of routes was found.'); - $this->assertEqual(array('narf', 'poink'), array_keys($routes_array), 'Ensure the fitness was taken into account.'); + $this->assertEqual(['narf', 'poink'], array_keys($routes_array), 'Ensure the fitness was taken into account.'); $this->assertNotNull($routes->get('narf'), 'The first matching route was found.'); $this->assertNotNull($routes->get('poink'), 'The second matching route was found.'); $this->assertNull($routes->get('eep'), 'Non-matching route was not found.'); @@ -341,7 +444,7 @@ function testOutlinePathMatchDefaultsCollision2() { /** * Confirms that we can find multiple routes that match the request equally. */ - function testOutlinePathMatchDefaultsCollision3() { + public function testOutlinePathMatchDefaultsCollision3() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); @@ -367,7 +470,7 @@ function testOutlinePathMatchDefaultsCollision3() { $routes_array = $routes->all(); $this->assertEqual(count($routes), 2, 'The correct number of routes was found.'); - $this->assertEqual(array('poink', 'poink2'), array_keys($routes_array), 'Ensure the fitness and name were taken into account in the sort.'); + $this->assertEqual(['poink', 'poink2'], array_keys($routes_array), 'Ensure the fitness and name were taken into account in the sort.'); $this->assertNotNull($routes->get('poink'), 'The first matching route was found.'); $this->assertNotNull($routes->get('poink2'), 'The second matching route was found.'); $this->assertNull($routes->get('eep'), 'Non-matching route was not found.'); @@ -415,7 +518,7 @@ public function testOutlinePathMatchZero() { /** * Confirms that an exception is thrown when no matching path is found. */ - function testOutlinePathNoMatch() { + public function testOutlinePathNoMatch() { $connection = Database::getConnection(); $provider = new RouteProvider($connection, $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes'); @@ -528,7 +631,7 @@ public function testRouteByName() { } $this->assertTrue($exception_thrown, 'Random route was not found.'); - $routes = $provider->getRoutesByNames(array('route_c', 'route_d', $this->randomMachineName())); + $routes = $provider->getRoutesByNames(['route_c', 'route_d', $this->randomMachineName()]); $this->assertEqual(count($routes), 2, 'Only two valid routes found.'); $this->assertEqual($routes['route_c']->getPath(), '/path/two'); $this->assertEqual($routes['route_d']->getPath(), '/path/three'); diff --git a/core/tests/Drupal/KernelTests/Core/Routing/UrlIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Routing/UrlIntegrationTest.php index a70cc1fa..053db792 100644 --- a/core/tests/Drupal/KernelTests/Core/Routing/UrlIntegrationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Routing/UrlIntegrationTest.php @@ -19,7 +19,7 @@ class UrlIntegrationTest extends KernelTestBase { * * @var array */ - public static $modules = array('user', 'router_test', 'system'); + public static $modules = ['user', 'router_test', 'system']; /** * Ensures that the access() method on \Drupal\Core\Url objects works. diff --git a/core/tests/Drupal/KernelTests/Core/ServiceProvider/ServiceProviderTest.php b/core/tests/Drupal/KernelTests/Core/ServiceProvider/ServiceProviderTest.php index 2995c973..970ea048 100644 --- a/core/tests/Drupal/KernelTests/Core/ServiceProvider/ServiceProviderTest.php +++ b/core/tests/Drupal/KernelTests/Core/ServiceProvider/ServiceProviderTest.php @@ -16,12 +16,12 @@ class ServiceProviderTest extends KernelTestBase { * * @var array */ - public static $modules = array('file', 'service_provider_test', 'system'); + public static $modules = ['file', 'service_provider_test', 'system']; /** * Tests that services provided by module service providers get registered to the DIC. */ - function testServiceProviderRegistration() { + public function testServiceProviderRegistration() { $definition = $this->container->getDefinition('file.usage'); $this->assertTrue($definition->getClass() == 'Drupal\\service_provider_test\\TestFileUsage', 'Class has been changed'); $this->assertTrue(\Drupal::hasService('service_provider_test_class'), 'The service_provider_test_class service has been registered to the DIC'); @@ -30,13 +30,13 @@ function testServiceProviderRegistration() { /** * Tests that the DIC keeps up with module enable/disable in the same request. */ - function testServiceProviderRegistrationDynamic() { + public function testServiceProviderRegistrationDynamic() { // Uninstall the module and ensure the service provider's service is not registered. - \Drupal::service('module_installer')->uninstall(array('service_provider_test')); + \Drupal::service('module_installer')->uninstall(['service_provider_test']); $this->assertFalse(\Drupal::hasService('service_provider_test_class'), 'The service_provider_test_class service does not exist in the DIC.'); // Install the module and ensure the service provider's service is registered. - \Drupal::service('module_installer')->install(array('service_provider_test')); + \Drupal::service('module_installer')->install(['service_provider_test']); $this->assertTrue(\Drupal::hasService('service_provider_test_class'), 'The service_provider_test_class service exists in the DIC.'); } diff --git a/core/tests/Drupal/KernelTests/Core/Session/AccountSwitcherTest.php b/core/tests/Drupal/KernelTests/Core/Session/AccountSwitcherTest.php index 0e6fa8a7..0492d773 100644 --- a/core/tests/Drupal/KernelTests/Core/Session/AccountSwitcherTest.php +++ b/core/tests/Drupal/KernelTests/Core/Session/AccountSwitcherTest.php @@ -20,7 +20,7 @@ public function testAccountSwitching() { $original_session_saving = $session_handler->isSessionWritable(); // Switch to user with uid 2. - $switcher->switchTo(new UserSession(array('uid' => 2))); + $switcher->switchTo(new UserSession(['uid' => 2])); // Verify that the active user has changed, and that session saving is // disabled. @@ -28,7 +28,7 @@ public function testAccountSwitching() { $this->assertFalse($session_handler->isSessionWritable(), 'Session saving is disabled.'); // Perform a second (nested) user account switch. - $switcher->switchTo(new UserSession(array('uid' => 3))); + $switcher->switchTo(new UserSession(['uid' => 3])); $this->assertEqual($user->id(), 3, 'Switched to user 3.'); // Revert to the user session that was active between the first and second diff --git a/core/tests/Drupal/KernelTests/Core/Site/SettingsRewriteTest.php b/core/tests/Drupal/KernelTests/Core/Site/SettingsRewriteTest.php index 948236bc..ef593751 100644 --- a/core/tests/Drupal/KernelTests/Core/Site/SettingsRewriteTest.php +++ b/core/tests/Drupal/KernelTests/Core/Site/SettingsRewriteTest.php @@ -15,86 +15,86 @@ class SettingsRewriteTest extends KernelTestBase { /** * Tests the drupal_rewrite_settings() function. */ - function testDrupalRewriteSettings() { + public function testDrupalRewriteSettings() { include_once \Drupal::root() . '/core/includes/install.inc'; $site_path = $this->container->get('site.path'); - $tests = array( - array( + $tests = [ + [ 'original' => '$no_index_value_scalar = TRUE;', - 'settings' => array( - 'no_index_value_scalar' => (object) array( + 'settings' => [ + 'no_index_value_scalar' => (object) [ 'value' => FALSE, 'comment' => 'comment', - ), - ), + ], + ], 'expected' => '$no_index_value_scalar = false; // comment', - ), - array( + ], + [ 'original' => '$no_index_value_scalar = TRUE;', - 'settings' => array( - 'no_index_value_foo' => array( - 'foo' => array( - 'value' => (object) array( + 'settings' => [ + 'no_index_value_foo' => [ + 'foo' => [ + 'value' => (object) [ 'value' => NULL, 'required' => TRUE, 'comment' => 'comment', - ), - ), - ), - ), + ], + ], + ], + ], 'expected' => <<<'EXPECTED' $no_index_value_scalar = TRUE; $no_index_value_foo['foo']['value'] = NULL; // comment EXPECTED - ), - array( + ], + [ 'original' => '$no_index_value_array = array("old" => "value");', - 'settings' => array( - 'no_index_value_array' => (object) array( + 'settings' => [ + 'no_index_value_array' => (object) [ 'value' => FALSE, 'required' => TRUE, 'comment' => 'comment', - ), - ), + ], + ], 'expected' => '$no_index_value_array = array("old" => "value"); $no_index_value_array = false; // comment', - ), - array( + ], + [ 'original' => '$has_index_value_scalar["foo"]["bar"] = NULL;', - 'settings' => array( - 'has_index_value_scalar' => array( - 'foo' => array( - 'bar' => (object) array( + 'settings' => [ + 'has_index_value_scalar' => [ + 'foo' => [ + 'bar' => (object) [ 'value' => FALSE, 'required' => TRUE, 'comment' => 'comment', - ), - ), - ), - ), + ], + ], + ], + ], 'expected' => '$has_index_value_scalar["foo"]["bar"] = false; // comment', - ), - array( + ], + [ 'original' => '$has_index_value_scalar["foo"]["bar"] = "foo";', - 'settings' => array( - 'has_index_value_scalar' => array( - 'foo' => array( - 'value' => (object) array( - 'value' => array('value' => 2), + 'settings' => [ + 'has_index_value_scalar' => [ + 'foo' => [ + 'value' => (object) [ + 'value' => ['value' => 2], 'required' => TRUE, 'comment' => 'comment', - ), - ), - ), - ), + ], + ], + ], + ], 'expected' => <<<'EXPECTED' $has_index_value_scalar["foo"]["bar"] = "foo"; $has_index_value_scalar['foo']['value'] = array ( 'value' => 2, ); // comment EXPECTED - ), - ); + ], + ]; foreach ($tests as $test) { $filename = Settings::get('file_public_path', $site_path . '/files') . '/mock_settings.php'; file_put_contents($filename, " array( - 'no_index' => (object) array( + $test = [ + 'settings' => [ + 'no_index' => (object) [ 'value' => TRUE, 'required' => TRUE, - ), - ), + ], + ], 'expected' => '$no_index = true;' - ); + ]; // Make an empty file. $filename = Settings::get('file_public_path', $site_path . '/files') . '/mock_settings.php'; file_put_contents($filename, ""); diff --git a/core/tests/Drupal/KernelTests/Core/Test/BrowserTestBaseTest.php b/core/tests/Drupal/KernelTests/Core/Test/BrowserTestBaseTest.php new file mode 100644 index 00000000..c93069c8 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Test/BrowserTestBaseTest.php @@ -0,0 +1,71 @@ +setName('testRequiresModule'); + + // We cannot use $this->setExpectedException() because PHPUnit would skip + // the test before comparing the exception type. + try { + $stub_test->publicCheckRequirements(); + $this->fail('Missing required module throws skipped test exception.'); + } + catch (\PHPUnit_Framework_SkippedTestError $e) { + $this->assertEqual('Required modules: module_does_not_exist', $e->getMessage()); + } + } + + /** + * Tests that a test case is skipped when it requires a module not present. + * + * In order to catch checkRequirements() regressions, we have to make a new + * test object and run checkRequirements() here. + * + * @covers ::checkRequirements + * @covers ::checkModuleRequirements + */ + public function testRequiresModule() { + require __DIR__ . '/../../../../fixtures/BrowserMissingDependentModuleTest.php'; + + $stub_test = new BrowserMissingDependentModuleTest(); + // We have to setName() to the method name we're concerned with. + $stub_test->setName('testRequiresModule'); + + // We cannot use $this->setExpectedException() because PHPUnit would skip + // the test before comparing the exception type. + try { + $stub_test->publicCheckRequirements(); + $this->fail('Missing required module throws skipped test exception.'); + } + catch (\PHPUnit_Framework_SkippedTestError $e) { + $this->assertEqual('Required modules: module_does_not_exist', $e->getMessage()); + } + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ImageTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ImageTest.php index 51608ebd..72cecce2 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ImageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ImageTest.php @@ -17,7 +17,7 @@ class ImageTest extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /* * The images to test with. @@ -36,19 +36,19 @@ protected function setUp() { $this->container = \Drupal::service('kernel')->getContainer(); $this->container->get('request_stack')->push($request); - $this->testImages = array( + $this->testImages = [ 'core/misc/druplicon.png', 'core/misc/loading.gif', - ); + ]; } /** * Tests that an image with the sizes attribute is output correctly. */ - function testThemeImageWithSizes() { + public function testThemeImageWithSizes() { // Test with multipliers. $sizes = '(max-width: ' . rand(10, 30) . 'em) 100vw, (max-width: ' . rand(30, 50) . 'em) 50vw, 30vw'; - $image = array( + $image = [ '#theme' => 'image', '#sizes' => $sizes, '#uri' => reset($this->testImages), @@ -56,7 +56,7 @@ function testThemeImageWithSizes() { '#height' => rand(0, 500) . 'px', '#alt' => $this->randomMachineName(), '#title' => $this->randomMachineName(), - ); + ]; $this->render($image); // Make sure sizes is set. @@ -66,16 +66,16 @@ function testThemeImageWithSizes() { /** * Tests that an image with the src attribute is output correctly. */ - function testThemeImageWithSrc() { + public function testThemeImageWithSrc() { - $image = array( + $image = [ '#theme' => 'image', '#uri' => reset($this->testImages), '#width' => rand(0, 1000) . 'px', '#height' => rand(0, 500) . 'px', '#alt' => $this->randomMachineName(), '#title' => $this->randomMachineName(), - ); + ]; $this->render($image); // Make sure the src attribute has the correct value. @@ -85,25 +85,25 @@ function testThemeImageWithSrc() { /** * Tests that an image with the srcset and multipliers is output correctly. */ - function testThemeImageWithSrcsetMultiplier() { + public function testThemeImageWithSrcsetMultiplier() { // Test with multipliers. - $image = array( + $image = [ '#theme' => 'image', - '#srcset' => array( - array( + '#srcset' => [ + [ 'uri' => $this->testImages[0], 'multiplier' => '1x', - ), - array( + ], + [ 'uri' => $this->testImages[1], 'multiplier' => '2x', - ), - ), + ], + ], '#width' => rand(0, 1000) . 'px', '#height' => rand(0, 500) . 'px', '#alt' => $this->randomMachineName(), '#title' => $this->randomMachineName(), - ); + ]; $this->render($image); // Make sure the srcset attribute has the correct value. @@ -113,29 +113,29 @@ function testThemeImageWithSrcsetMultiplier() { /** * Tests that an image with the srcset and widths is output correctly. */ - function testThemeImageWithSrcsetWidth() { + public function testThemeImageWithSrcsetWidth() { // Test with multipliers. - $widths = array( + $widths = [ rand(0, 500) . 'w', rand(500, 1000) . 'w', - ); - $image = array( + ]; + $image = [ '#theme' => 'image', - '#srcset' => array( - array( + '#srcset' => [ + [ 'uri' => $this->testImages[0], 'width' => $widths[0], - ), - array( + ], + [ 'uri' => $this->testImages[1], 'width' => $widths[1], - ), - ), + ], + ], '#width' => rand(0, 1000) . 'px', '#height' => rand(0, 500) . 'px', '#alt' => $this->randomMachineName(), '#title' => $this->randomMachineName(), - ); + ]; $this->render($image); // Make sure the srcset attribute has the correct value. diff --git a/core/tests/Drupal/KernelTests/Core/Theme/MessageTest.php b/core/tests/Drupal/KernelTests/Core/Theme/MessageTest.php index 76e14e9f..294c8dce 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/MessageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/MessageTest.php @@ -14,21 +14,21 @@ class MessageTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('system'); + public static $modules = ['system']; /** * Tests setting messages output. */ - function testMessages() { + public function testMessages() { // Enable the Classy theme. \Drupal::service('theme_handler')->install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); drupal_set_message('An error occurred', 'error'); drupal_set_message('But then something nice happened'); - $messages = array( + $messages = [ '#type' => 'status_messages', - ); + ]; $this->render($messages); $this->assertRaw('messages messages--error'); $this->assertRaw('messages messages--status'); diff --git a/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php index 93e931b8..a20798e1 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php @@ -2,6 +2,8 @@ namespace Drupal\KernelTests\Core\Theme; +use Drupal\Core\Path\CurrentPathStack; +use Drupal\Core\Path\PathMatcherInterface; use Drupal\Core\Theme\Registry; use Drupal\Core\Utility\ThemeRegistry; use Drupal\KernelTests\KernelTestBase; @@ -18,14 +20,14 @@ class RegistryTest extends KernelTestBase { * * @var array */ - public static $modules = array('theme_test', 'system'); + public static $modules = ['theme_test', 'system']; protected $profile = 'testing'; /** * Tests the behavior of the theme registry class. */ - function testRaceCondition() { + public function testRaceCondition() { // The theme registry is not marked as persistable in case we don't have a // proper request. \Drupal::request()->setMethod('GET'); @@ -35,7 +37,7 @@ function testRaceCondition() { // entry to be written in __construct(). $cache = \Drupal::cache(); $lock_backend = \Drupal::lock(); - $registry = new ThemeRegistry($cid, $cache, $lock_backend, array('theme_registry'), $this->container->get('module_handler')->isLoaded()); + $registry = new ThemeRegistry($cid, $cache, $lock_backend, ['theme_registry'], $this->container->get('module_handler')->isLoaded()); $this->assertTrue(\Drupal::cache()->get($cid), 'Cache entry was created.'); @@ -55,7 +57,7 @@ function testRaceCondition() { // Create a new instance of the class. Confirm that both the offset // requested previously, and one that has not yet been requested are both // available. - $registry = new ThemeRegistry($cid, $cache, $lock_backend, array('theme_registry'), $this->container->get('module_handler')->isLoaded()); + $registry = new ThemeRegistry($cid, $cache, $lock_backend, ['theme_registry'], $this->container->get('module_handler')->isLoaded()); $this->assertTrue($registry->get('theme_test_template_test'), 'Offset was returned correctly from the theme registry'); $this->assertTrue($registry->get('theme_test_template_test_2'), 'Offset was returned correctly from the theme registry'); } @@ -75,7 +77,7 @@ public function testMultipleSubThemes() { $registry_base_theme->setThemeManager(\Drupal::theme()); $preprocess_functions = $registry_subsub_theme->get()['theme_test_template_test']['preprocess functions']; - $this->assertIdentical([ + $this->assertSame([ 'template_preprocess', 'test_basetheme_preprocess_theme_test_template_test', 'test_subtheme_preprocess_theme_test_template_test', @@ -83,20 +85,20 @@ public function testMultipleSubThemes() { ], $preprocess_functions); $preprocess_functions = $registry_sub_theme->get()['theme_test_template_test']['preprocess functions']; - $this->assertIdentical([ + $this->assertSame([ 'template_preprocess', 'test_basetheme_preprocess_theme_test_template_test', 'test_subtheme_preprocess_theme_test_template_test', ], $preprocess_functions); $preprocess_functions = $registry_base_theme->get()['theme_test_template_test']['preprocess functions']; - $this->assertIdentical([ + $this->assertSame([ 'template_preprocess', 'test_basetheme_preprocess_theme_test_template_test', ], $preprocess_functions); $preprocess_functions = $registry_base_theme->get()['theme_test_function_suggestions']['preprocess functions']; - $this->assertIdentical([ + $this->assertSame([ 'template_preprocess_theme_test_function_suggestions', 'test_basetheme_preprocess_theme_test_function_suggestions', ], $preprocess_functions, "Theme functions don't have template_preprocess but do have template_preprocess_HOOK"); @@ -123,7 +125,7 @@ public function testSuggestionPreprocessFunctions() { $hook .= "$suggestion"; $expected_preprocess_functions[] = "test_theme_preprocess_$hook"; $preprocess_functions = $registry_theme->get()[$hook]['preprocess functions']; - $this->assertIdentical($expected_preprocess_functions, $preprocess_functions, "$hook has correct preprocess functions."); + $this->assertSame($expected_preprocess_functions, $preprocess_functions, "$hook has correct preprocess functions."); } while ($suggestion = array_shift($suggestions)); $expected_preprocess_functions = [ @@ -134,10 +136,10 @@ public function testSuggestionPreprocessFunctions() { ]; $preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat']['preprocess functions']; - $this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a function correctly inherits preprocess functions.'); + $this->assertSame($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a function correctly inherits preprocess functions.'); $preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__bearcat']['preprocess functions']; - $this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.'); + $this->assertSame($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.'); $this->assertTrue(isset($registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat__tarsier__moose']), 'Preprocess function with an unimplemented lower-level suggestion is added to the registry.'); } @@ -150,11 +152,44 @@ public function testThemeRegistryAlterByTheme() { /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */ $theme_handler = \Drupal::service('theme_handler'); $theme_handler->install(['test_theme']); - $theme_handler->setDefault('test_theme'); + $this->config('system.theme')->set('default', 'test_theme')->save(); $registry = new Registry(\Drupal::root(), \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme'); $registry->setThemeManager(\Drupal::theme()); $this->assertEqual('value', $registry->get()['theme_test_template_test']['variables']['additional']); } + /** + * Tests front node theme suggestion generation. + */ + public function testThemeSuggestions() { + // Mock the current page as the front page. + /** @var PathMatcherInterface $path_matcher */ + $path_matcher = $this->prophesize(PathMatcherInterface::class); + $path_matcher->isFrontPage()->willReturn(TRUE); + $this->container->set('path.matcher', $path_matcher->reveal()); + /** @var CurrentPathStack $path_matcher */ + $path_current = $this->prophesize(CurrentPathStack::class); + $path_current->getPath()->willReturn('/node/1'); + $this->container->set('path.current', $path_current->reveal()); + + // Check suggestions provided through hook_theme_suggestions_html(). + $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_html', [[]]); + $this->assertSame([ + 'html__node', + 'html__node__%', + 'html__node__1', + 'html__front', + ], $suggestions, 'Found expected html node suggestions.'); + + // Check suggestions provided through hook_theme_suggestions_page(). + $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_page', [[]]); + $this->assertSame([ + 'page__node', + 'page__node__%', + 'page__node__1', + 'page__front', + ], $suggestions, 'Found expected page node suggestions.'); + } + } diff --git a/core/tests/Drupal/KernelTests/Core/Theme/StableThemeTest.php b/core/tests/Drupal/KernelTests/Core/Theme/StableThemeTest.php index da585d08..8a79a9ef 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/StableThemeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/StableThemeTest.php @@ -47,7 +47,7 @@ protected function setUp() { */ public function testStableIsDefault() { $this->themeHandler->install(['test_stable']); - $this->themeHandler->setDefault('test_stable'); + $this->config('system.theme')->set('default', 'test_stable')->save(); $theme = $this->themeManager->getActiveTheme(); /** @var \Drupal\Core\Theme\ActiveTheme $base_theme */ $base_themes = $theme->getBaseThemes(); @@ -60,7 +60,7 @@ public function testStableIsDefault() { */ public function testWildWest() { $this->themeHandler->install(['test_wild_west']); - $this->themeHandler->setDefault('test_wild_west'); + $this->config('system.theme')->set('default', 'test_wild_west')->save(); $theme = $this->themeManager->getActiveTheme(); /** @var \Drupal\Core\Theme\ActiveTheme $base_theme */ $base_themes = $theme->getBaseThemes(); diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php index b82978cd..61f64752 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php @@ -18,7 +18,7 @@ class ThemeInstallerTest extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * {@inheritdoc} @@ -33,13 +33,13 @@ public function register(ContainerBuilder $container) { protected function setUp() { parent::setUp(); - $this->installConfig(array('system')); + $this->installConfig(['system']); } /** * Verifies that no themes are installed by default. */ - function testEmpty() { + public function testEmpty() { $this->assertFalse($this->extensionConfig()->get('theme')); $this->assertFalse(array_keys($this->themeHandler()->listInfo())); @@ -55,13 +55,13 @@ function testEmpty() { /** * Tests installing a theme. */ - function testInstall() { + public function testInstall() { $name = 'test_basetheme'; $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name])); - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $this->assertIdentical($this->extensionConfig()->get("theme.$name"), 0); @@ -80,20 +80,20 @@ function testInstall() { /** * Tests installing a sub-theme. */ - function testInstallSubTheme() { + public function testInstallSubTheme() { $name = 'test_subtheme'; $base_name = 'test_basetheme'; $themes = $this->themeHandler()->listInfo(); $this->assertFalse(array_keys($themes)); - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $themes = $this->themeHandler()->listInfo(); $this->assertTrue(isset($themes[$name])); $this->assertTrue(isset($themes[$base_name])); - $this->themeInstaller()->uninstall(array($name)); + $this->themeInstaller()->uninstall([$name]); $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name])); @@ -103,7 +103,7 @@ function testInstallSubTheme() { /** * Tests installing a non-existing theme. */ - function testInstallNonExisting() { + public function testInstallNonExisting() { $name = 'non_existing_theme'; $themes = $this->themeHandler()->listInfo(); @@ -111,7 +111,7 @@ function testInstallNonExisting() { try { $message = 'ThemeHandler::install() throws InvalidArgumentException upon installing a non-existing theme.'; - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $this->fail($message); } catch (\InvalidArgumentException $e) { @@ -125,12 +125,12 @@ function testInstallNonExisting() { /** * Tests installing a theme with a too long name. */ - function testInstallNameTooLong() { + public function testInstallNameTooLong() { $name = 'test_theme_having_veery_long_name_which_is_too_long'; try { $message = 'ThemeHandler::install() throws ExtensionNameLengthException upon installing a theme with a too long name.'; - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $this->fail($message); } catch (ExtensionNameLengthException $e) { @@ -141,11 +141,11 @@ function testInstallNameTooLong() { /** * Tests uninstalling the default theme. */ - function testUninstallDefault() { + public function testUninstallDefault() { $name = 'stark'; $other_name = 'bartik'; - $this->themeInstaller()->install(array($name, $other_name)); - $this->themeHandler()->setDefault($name); + $this->themeInstaller()->install([$name, $other_name]); + $this->config('system.theme')->set('default', $name)->save(); $themes = $this->themeHandler()->listInfo(); $this->assertTrue(isset($themes[$name])); @@ -153,7 +153,7 @@ function testUninstallDefault() { try { $message = 'ThemeHandler::uninstall() throws InvalidArgumentException upon disabling default theme.'; - $this->themeHandler()->uninstall(array($name)); + $this->themeHandler()->uninstall([$name]); $this->fail($message); } catch (\InvalidArgumentException $e) { @@ -168,10 +168,10 @@ function testUninstallDefault() { /** * Tests uninstalling the admin theme. */ - function testUninstallAdmin() { + public function testUninstallAdmin() { $name = 'stark'; $other_name = 'bartik'; - $this->themeInstaller()->install(array($name, $other_name)); + $this->themeInstaller()->install([$name, $other_name]); $this->config('system.theme')->set('admin', $name)->save(); $themes = $this->themeHandler()->listInfo(); @@ -180,7 +180,7 @@ function testUninstallAdmin() { try { $message = 'ThemeHandler::uninstall() throws InvalidArgumentException upon disabling admin theme.'; - $this->themeHandler()->uninstall(array($name)); + $this->themeHandler()->uninstall([$name]); $this->fail($message); } catch (\InvalidArgumentException $e) { @@ -195,12 +195,12 @@ function testUninstallAdmin() { /** * Tests uninstalling a sub-theme. */ - function testUninstallSubTheme() { + public function testUninstallSubTheme() { $name = 'test_subtheme'; $base_name = 'test_basetheme'; - $this->themeInstaller()->install(array($name)); - $this->themeInstaller()->uninstall(array($name)); + $this->themeInstaller()->install([$name]); + $this->themeInstaller()->uninstall([$name]); $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name])); @@ -210,15 +210,15 @@ function testUninstallSubTheme() { /** * Tests uninstalling a base theme before its sub-theme. */ - function testUninstallBaseBeforeSubTheme() { + public function testUninstallBaseBeforeSubTheme() { $name = 'test_basetheme'; $sub_name = 'test_subtheme'; - $this->themeInstaller()->install(array($sub_name)); + $this->themeInstaller()->install([$sub_name]); try { $message = 'ThemeHandler::install() throws InvalidArgumentException upon uninstalling base theme before sub theme.'; - $this->themeInstaller()->uninstall(array($name)); + $this->themeInstaller()->uninstall([$name]); $this->fail($message); } catch (\InvalidArgumentException $e) { @@ -230,7 +230,7 @@ function testUninstallBaseBeforeSubTheme() { $this->assertTrue(isset($themes[$sub_name])); // Verify that uninstalling both at the same time works. - $this->themeInstaller()->uninstall(array($name, $sub_name)); + $this->themeInstaller()->uninstall([$name, $sub_name]); $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name])); @@ -240,7 +240,7 @@ function testUninstallBaseBeforeSubTheme() { /** * Tests uninstalling a non-existing theme. */ - function testUninstallNonExisting() { + public function testUninstallNonExisting() { $name = 'non_existing_theme'; $themes = $this->themeHandler()->listInfo(); @@ -248,7 +248,7 @@ function testUninstallNonExisting() { try { $message = 'ThemeHandler::uninstall() throws InvalidArgumentException upon uninstalling a non-existing theme.'; - $this->themeInstaller()->uninstall(array($name)); + $this->themeInstaller()->uninstall([$name]); $this->fail($message); } catch (\InvalidArgumentException $e) { @@ -262,13 +262,13 @@ function testUninstallNonExisting() { /** * Tests uninstalling a theme. */ - function testUninstall() { + public function testUninstall() { $name = 'test_basetheme'; - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $this->assertTrue($this->config("$name.settings")->get()); - $this->themeInstaller()->uninstall(array($name)); + $this->themeInstaller()->uninstall([$name]); $this->assertFalse(array_keys($this->themeHandler()->listInfo())); $this->assertFalse(array_keys(system_list('theme'))); @@ -276,7 +276,7 @@ function testUninstall() { $this->assertFalse($this->config("$name.settings")->get()); // Ensure that the uninstalled theme can be installed again. - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $themes = $this->themeHandler()->listInfo(); $this->assertTrue(isset($themes[$name])); $this->assertEqual($themes[$name]->getName(), $name); @@ -287,12 +287,12 @@ function testUninstall() { /** * Tests uninstalling a theme that is not installed. */ - function testUninstallNotInstalled() { + public function testUninstallNotInstalled() { $name = 'test_basetheme'; try { $message = 'ThemeHandler::uninstall() throws InvalidArgumentException upon uninstalling a theme that is not installed.'; - $this->themeInstaller()->uninstall(array($name)); + $this->themeInstaller()->uninstall([$name]); $this->fail($message); } catch (\InvalidArgumentException $e) { @@ -305,11 +305,11 @@ function testUninstallNotInstalled() { * * @see module_test_system_info_alter() */ - function testThemeInfoAlter() { + public function testThemeInfoAlter() { $name = 'seven'; $this->container->get('state')->set('module_test.hook_system_info_alter', TRUE); - $this->themeInstaller()->install(array($name)); + $this->themeInstaller()->install([$name]); $themes = $this->themeHandler()->listInfo(); $this->assertFalse(isset($themes[$name]->info['regions']['test_region'])); @@ -317,7 +317,7 @@ function testThemeInfoAlter() { // Rebuild module data so we know where module_test is located. // @todo Remove as part of https://www.drupal.org/node/2186491 system_rebuild_module_data(); - $this->moduleInstaller()->install(array('module_test'), FALSE); + $this->moduleInstaller()->install(['module_test'], FALSE); $this->assertTrue($this->moduleHandler()->moduleExists('module_test')); $themes = $this->themeHandler()->listInfo(); @@ -333,7 +333,7 @@ function testThemeInfoAlter() { $system_list = system_list('theme'); $this->assertTrue(isset($system_list[$name]->info['regions']['test_region'])); - $this->moduleInstaller()->uninstall(array('module_test')); + $this->moduleInstaller()->uninstall(['module_test']); $this->assertFalse($this->moduleHandler()->moduleExists('module_test')); $themes = $this->themeHandler()->listInfo(); diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php index 98423ca0..c44cc1c8 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php @@ -82,10 +82,9 @@ public function providerTestThemeRenderAndAutoescape() { /** * Ensures invalid content is handled correctly. - * - * @expectedException \Exception */ public function testThemeEscapeAndRenderNotPrintable() { + $this->setExpectedException(\Exception::class); theme_render_and_autoescape(new NonPrintable()); } @@ -135,4 +134,4 @@ public function testBubblingMetadataWithRenderable() { } -class NonPrintable { } +class NonPrintable {} diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeSettingsTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeSettingsTest.php index 6c2dfb39..a077c25a 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeSettingsTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeSettingsTest.php @@ -18,7 +18,7 @@ class ThemeSettingsTest extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * List of discovered themes. @@ -30,7 +30,7 @@ class ThemeSettingsTest extends KernelTestBase { protected function setUp() { parent::setUp(); // Theme settings rely on System module's system.theme.global configuration. - $this->installConfig(array('system')); + $this->installConfig(['system']); if (!isset($this->availableThemes)) { $discovery = new ExtensionDiscovery(\Drupal::root()); @@ -41,22 +41,22 @@ protected function setUp() { /** * Tests that $theme.settings are imported and used as default theme settings. */ - function testDefaultConfig() { + public function testDefaultConfig() { $name = 'test_basetheme'; $path = $this->availableThemes[$name]->getPath(); $this->assertTrue(file_exists("$path/" . InstallStorage::CONFIG_INSTALL_DIRECTORY . "/$name.settings.yml")); - $this->container->get('theme_handler')->install(array($name)); + $this->container->get('theme_handler')->install([$name]); $this->assertIdentical(theme_get_setting('base', $name), 'only'); } /** * Tests that the $theme.settings default config file is optional. */ - function testNoDefaultConfig() { + public function testNoDefaultConfig() { $name = 'stark'; $path = $this->availableThemes[$name]->getPath(); $this->assertFalse(file_exists("$path/" . InstallStorage::CONFIG_INSTALL_DIRECTORY . "/$name.settings.yml")); - $this->container->get('theme_handler')->install(array($name)); + $this->container->get('theme_handler')->install([$name]); $this->assertNotNull(theme_get_setting('features.favicon', $name)); } diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php index deaf0334..5d6f61f2 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigEnvironmentTest.php @@ -2,8 +2,10 @@ namespace Drupal\KernelTests\Core\Theme; +use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\Html; use Drupal\Core\Site\Settings; +use Drupal\Core\Template\TwigPhpStorageCache; use Drupal\KernelTests\KernelTestBase; /** @@ -19,7 +21,7 @@ class TwigEnvironmentTest extends KernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * Tests inline templates. @@ -30,15 +32,15 @@ public function testInlineTemplate() { /** @var \Drupal\Core\Template\TwigEnvironment $environment */ $environment = \Drupal::service('twig'); $this->assertEqual($environment->renderInline('test-no-context'), 'test-no-context'); - $this->assertEqual($environment->renderInline('test-with-context {{ llama }}', array('llama' => 'muuh')), 'test-with-context muuh'); + $this->assertEqual($environment->renderInline('test-with-context {{ llama }}', ['llama' => 'muuh']), 'test-with-context muuh'); - $element = array(); + $element = []; $unsafe_string = ''; - $element['test'] = array( + $element['test'] = [ '#type' => 'inline_template', '#template' => 'test-with-context ', - '#context' => array('unsafe_content' => $unsafe_string), - ); + '#context' => ['unsafe_content' => $unsafe_string], + ]; $this->assertEqual($renderer->renderRoot($element), 'test-with-context '); // Enable twig_auto_reload and twig_debug. @@ -50,12 +52,12 @@ public function testInlineTemplate() { $this->container = \Drupal::service('kernel')->rebuildContainer(); \Drupal::setContainer($this->container); - $element = array(); - $element['test'] = array( + $element = []; + $element['test'] = [ '#type' => 'inline_template', '#template' => 'test-with-context {{ llama }}', - '#context' => array('llama' => 'muuh'), - ); + '#context' => ['llama' => 'muuh'], + ]; $element_copy = $element; // Render it twice so that twig caching is triggered. $this->assertEqual($renderer->renderRoot($element), 'test-with-context muuh'); @@ -83,11 +85,11 @@ public function testInlineTemplate() { $this->assertEqual($renderer->renderRoot($element_copy), $expected); $name = '{# inline_template_start #}' . $element['test']['#template']; - $hash = $this->container->getParameter('twig_extension_hash'); + $prefix = $environment->getTwigCachePrefix(); $cache = $environment->getCache(); $class = $environment->getTemplateClass($name); - $expected = $hash . '_inline-template' . '_' . hash('sha256', $class); + $expected = $prefix . '_inline-template_' . substr(Crypt::hashBase64($class), 0, TwigPhpStorageCache::SUFFIX_SUBSTRING_LENGTH); $this->assertEqual($expected, $cache->generateKey($name, $class)); } @@ -99,7 +101,7 @@ public function testTemplateNotFoundException() { $environment = \Drupal::service('twig'); try { - $environment->loadTemplate('this-template-does-not-exist.html.twig')->render(array()); + $environment->loadTemplate('this-template-does-not-exist.html.twig')->render([]); $this->fail('Did not throw an exception as expected.'); } catch (\Twig_Error_Loader $e) { @@ -116,6 +118,20 @@ public function testCacheFilename() { // static cache. $environment = \Drupal::service('twig'); + // A template basename greater than the constant + // TwigPhpStorageCache::SUFFIX_SUBSTRING_LENGTH should get truncated. + $cache = $environment->getCache(); + $long_name = 'core/modules/system/templates/block--system-messages-block.html.twig'; + $this->assertGreaterThan(TwigPhpStorageCache::SUFFIX_SUBSTRING_LENGTH, strlen(basename($long_name))); + $class = $environment->getTemplateClass($long_name); + $key = $cache->generateKey($long_name, $class); + $prefix = $environment->getTwigCachePrefix(); + // The key should consist of the prefix, an underscore, and two strings + // each truncated to length TwigPhpStorageCache::SUFFIX_SUBSTRING_LENGTH + // separated by an underscore. + $expected = strlen($prefix) + 2 + 2 * TwigPhpStorageCache::SUFFIX_SUBSTRING_LENGTH; + $this->assertEquals($expected, strlen($key)); + $original_filename = $environment->getCacheFilename('core/modules/system/templates/container.html.twig'); \Drupal::getContainer()->set('twig', NULL); diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigMarkupInterfaceTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigMarkupInterfaceTest.php index 2e6e5a40..d30d2de1 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/TwigMarkupInterfaceTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigMarkupInterfaceTest.php @@ -90,7 +90,7 @@ protected function renderObjectWithTwig($variable) { $elements = [ '#type' => 'inline_template', '#template' => '{%- if variable is not empty -%}{{ variable }}{%- endif -%}', - '#context' => array('variable' => $variable), + '#context' => ['variable' => $variable], ]; return $renderer->render($elements); }); diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php index 41984d66..7af10f59 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php @@ -42,7 +42,8 @@ class TwigWhiteListTest extends KernelTestBase { */ protected function setUp() { parent::setUp(); - $this->installSchema('system', array('sequences')); + \Drupal::service('theme_handler')->install(['test_theme']); + $this->installSchema('system', ['sequences']); $this->installEntitySchema('node'); $this->installEntitySchema('user'); $this->installEntitySchema('taxonomy_term'); @@ -71,38 +72,38 @@ protected function setUp() { $this->term->save(); // Create a field. - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $vocabulary->id() => $vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; // Add the term field. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => 'field_term', 'type' => 'entity_reference', 'entity_type' => 'node', 'cardinality' => 1, - 'settings' => array( + 'settings' => [ 'target_type' => 'taxonomy_term', - ), - ))->save(); - FieldConfig::create(array( + ], + ])->save(); + FieldConfig::create([ 'field_name' => 'field_term', 'entity_type' => 'node', 'bundle' => 'page', 'label' => 'Terms', - 'settings' => array( + 'settings' => [ 'handler' => 'default', 'handler_settings' => $handler_settings, - ), - ))->save(); + ], + ])->save(); // Show on default display and teaser. entity_get_display('node', 'page', 'default') - ->setComponent('field_term', array( + ->setComponent('field_term', [ 'type' => 'entity_reference_label', - )) + ]) ->save(); // Boot twig environment. $this->twig = \Drupal::service('twig'); diff --git a/core/tests/Drupal/KernelTests/Core/TypedData/AllowedValuesConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/TypedData/AllowedValuesConstraintValidatorTest.php index 4a23fbbc..05a36ba2 100644 --- a/core/tests/Drupal/KernelTests/Core/TypedData/AllowedValuesConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/TypedData/AllowedValuesConstraintValidatorTest.php @@ -32,7 +32,7 @@ protected function setUp() { public function testValidation() { // Create a definition that specifies some AllowedValues. $definition = DataDefinition::create('integer') - ->addConstraint('AllowedValues', array(1, 2, 3)); + ->addConstraint('AllowedValues', [1, 2, 3]); // Test the validation. $typed_data = $this->typedData->create($definition, 1); diff --git a/core/tests/Drupal/KernelTests/Core/TypedData/ComplexDataConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/TypedData/ComplexDataConstraintValidatorTest.php index 078cb7a7..bbdf1099 100644 --- a/core/tests/Drupal/KernelTests/Core/TypedData/ComplexDataConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/TypedData/ComplexDataConstraintValidatorTest.php @@ -35,19 +35,19 @@ public function testValidation() { // Create a definition that specifies some ComplexData constraint. $definition = MapDataDefinition::create() ->setPropertyDefinition('key', DataDefinition::create('integer')) - ->addConstraint('ComplexData', array( - 'key' => array( - 'AllowedValues' => array(1, 2, 3) - ), - )); + ->addConstraint('ComplexData', [ + 'key' => [ + 'AllowedValues' => [1, 2, 3] + ], + ]); // Test the validation. - $typed_data = $this->typedData->create($definition, array('key' => 1)); + $typed_data = $this->typedData->create($definition, ['key' => 1]); $violations = $typed_data->validate(); $this->assertEqual($violations->count(), 0, 'Validation passed for correct value.'); // Test the validation when an invalid value is passed. - $typed_data = $this->typedData->create($definition, array('key' => 4)); + $typed_data = $this->typedData->create($definition, ['key' => 4]); $violations = $typed_data->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed for incorrect value.'); @@ -59,19 +59,19 @@ public function testValidation() { // Test using the constraint with a map without the specified key. This // should be ignored as long as there is no NotNull or NotBlank constraint. - $typed_data = $this->typedData->create($definition, array('foo' => 'bar')); + $typed_data = $this->typedData->create($definition, ['foo' => 'bar']); $violations = $typed_data->validate(); $this->assertEqual($violations->count(), 0, 'Constraint on non-existing key is ignored.'); $definition = MapDataDefinition::create() ->setPropertyDefinition('key', DataDefinition::create('integer')) - ->addConstraint('ComplexData', array( - 'key' => array( - 'NotNull' => array() - ), - )); + ->addConstraint('ComplexData', [ + 'key' => [ + 'NotNull' => [] + ], + ]); - $typed_data = $this->typedData->create($definition, array('foo' => 'bar')); + $typed_data = $this->typedData->create($definition, ['foo' => 'bar']); $violations = $typed_data->validate(); $this->assertEqual($violations->count(), 1, 'Key is required.'); } diff --git a/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php index 4ff9ff6d..ad266c28 100644 --- a/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php +++ b/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php @@ -66,7 +66,7 @@ public function testMaps() { $this->assertTrue($map_definition instanceof ComplexDataDefinitionInterface); // Test retrieving metadata about contained properties. - $this->assertEqual(array_keys($map_definition->getPropertyDefinitions()), array('one', 'two', 'three')); + $this->assertEqual(array_keys($map_definition->getPropertyDefinitions()), ['one', 'two', 'three']); $this->assertEqual($map_definition->getPropertyDefinition('one')->getDataType(), 'string'); $this->assertNull($map_definition->getMainPropertyName()); $this->assertNull($map_definition->getPropertyDefinition('invalid')); @@ -77,7 +77,7 @@ public function testMaps() { $map_definition2->setPropertyDefinition('one', DataDefinition::create('string')) ->setPropertyDefinition('two', DataDefinition::create('string')) ->setPropertyDefinition('three', DataDefinition::create('string')); - $this->assertEqual($map_definition, $map_definition2); + $this->assertEqual(serialize($map_definition), serialize($map_definition2)); } /** @@ -93,7 +93,7 @@ public function testDataReferences() { // Test using the definition factory. $language_reference_definition2 = $this->typedDataManager->createDataDefinition('language_reference'); $this->assertTrue($language_reference_definition2 instanceof DataReferenceDefinitionInterface); - $this->assertEqual($language_reference_definition, $language_reference_definition2); + $this->assertEqual(serialize($language_reference_definition), serialize($language_reference_definition2)); } } diff --git a/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataTest.php b/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataTest.php index 08f27b36..e3e3fae2 100644 --- a/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataTest.php +++ b/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataTest.php @@ -38,7 +38,7 @@ class TypedDataTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'field', 'file', 'user'); + public static $modules = ['system', 'field', 'file', 'user']; protected function setUp() { parent::setup(); @@ -66,7 +66,7 @@ protected function createTypedData($definition, $value = NULL, $name = NULL) { */ public function testGetAndSet() { // Boolean type. - $typed_data = $this->createTypedData(array('type' => 'boolean'), TRUE); + $typed_data = $this->createTypedData(['type' => 'boolean'], TRUE); $this->assertTrue($typed_data instanceof BooleanInterface, 'Typed data object is an instance of BooleanInterface.'); $this->assertTrue($typed_data->getValue() === TRUE, 'Boolean value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -82,7 +82,7 @@ public function testGetAndSet() { // String type. $value = $this->randomString(); - $typed_data = $this->createTypedData(array('type' => 'string'), $value); + $typed_data = $this->createTypedData(['type' => 'string'], $value); $this->assertTrue($typed_data instanceof StringInterface, 'Typed data object is an instance of StringInterface.'); $this->assertTrue($typed_data->getValue() === $value, 'String value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -95,12 +95,12 @@ public function testGetAndSet() { $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue(), 'String wrapper is null-able.'); $this->assertEqual($typed_data->validate()->count(), 0); - $typed_data->setValue(array('no string')); + $typed_data->setValue(['no string']); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Integer type. $value = rand(); - $typed_data = $this->createTypedData(array('type' => 'integer'), $value); + $typed_data = $this->createTypedData(['type' => 'integer'], $value); $this->assertTrue($typed_data instanceof IntegerInterface, 'Typed data object is an instance of IntegerInterface.'); $this->assertTrue($typed_data->getValue() === $value, 'Integer value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -117,7 +117,7 @@ public function testGetAndSet() { // Float type. $value = 123.45; - $typed_data = $this->createTypedData(array('type' => 'float'), $value); + $typed_data = $this->createTypedData(['type' => 'float'], $value); $this->assertTrue($typed_data instanceof FloatInterface, 'Typed data object is an instance of FloatInterface.'); $this->assertTrue($typed_data->getValue() === $value, 'Float value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -134,7 +134,7 @@ public function testGetAndSet() { // Date Time type. $value = '2014-01-01T20:00:00+00:00'; - $typed_data = $this->createTypedData(array('type' => 'datetime_iso8601'), $value); + $typed_data = $this->createTypedData(['type' => 'datetime_iso8601'], $value); $this->assertTrue($typed_data instanceof DateTimeInterface, 'Typed data object is an instance of DateTimeInterface.'); $this->assertTrue($typed_data->getValue() == $value, 'Date value was fetched.'); $this->assertEqual($typed_data->getValue(), $typed_data->getDateTime()->format('c'), 'Value representation of a date is ISO 8601'); @@ -151,7 +151,7 @@ public function testGetAndSet() { $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DateTimeInterface. - $typed_data = $this->createTypedData(array('type' => 'datetime_iso8601'), '2014-01-01T20:00:00+00:00'); + $typed_data = $this->createTypedData(['type' => 'datetime_iso8601'], '2014-01-01T20:00:00+00:00'); $this->assertTrue($typed_data->getDateTime() instanceof DrupalDateTime); $typed_data->setDateTime(new DrupalDateTime('2014-01-02T20:00:00+00:00')); $this->assertEqual($typed_data->getValue(), '2014-01-02T20:00:00+00:00'); @@ -160,7 +160,7 @@ public function testGetAndSet() { // Timestamp type. $value = REQUEST_TIME; - $typed_data = $this->createTypedData(array('type' => 'timestamp'), $value); + $typed_data = $this->createTypedData(['type' => 'timestamp'], $value); $this->assertTrue($typed_data instanceof DateTimeInterface, 'Typed data object is an instance of DateTimeInterface.'); $this->assertTrue($typed_data->getValue() == $value, 'Timestamp value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -174,7 +174,7 @@ public function testGetAndSet() { $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DateTimeInterface. - $typed_data = $this->createTypedData(array('type' => 'timestamp'), REQUEST_TIME); + $typed_data = $this->createTypedData(['type' => 'timestamp'], REQUEST_TIME); $this->assertTrue($typed_data->getDateTime() instanceof DrupalDateTime); $typed_data->setDateTime(DrupalDateTime::createFromTimestamp(REQUEST_TIME + 1)); $this->assertEqual($typed_data->getValue(), REQUEST_TIME + 1); @@ -183,7 +183,7 @@ public function testGetAndSet() { // DurationIso8601 type. $value = 'PT20S'; - $typed_data = $this->createTypedData(array('type' => 'duration_iso8601'), $value); + $typed_data = $this->createTypedData(['type' => 'duration_iso8601'], $value); $this->assertTrue($typed_data instanceof DurationInterface, 'Typed data object is an instance of DurationInterface.'); $this->assertIdentical($typed_data->getValue(), $value, 'DurationIso8601 value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -197,7 +197,7 @@ public function testGetAndSet() { $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DurationInterface. - $typed_data = $this->createTypedData(array('type' => 'duration_iso8601'), 'PT20S'); + $typed_data = $this->createTypedData(['type' => 'duration_iso8601'], 'PT20S'); $this->assertTrue($typed_data->getDuration() instanceof \DateInterval); $typed_data->setDuration(new \DateInterval('P40D')); // @todo: Should we make this "nicer"? @@ -207,7 +207,7 @@ public function testGetAndSet() { // Time span type. $value = 20; - $typed_data = $this->createTypedData(array('type' => 'timespan'), $value); + $typed_data = $this->createTypedData(['type' => 'timespan'], $value); $this->assertTrue($typed_data instanceof DurationInterface, 'Typed data object is an instance of DurationInterface.'); $this->assertIdentical($typed_data->getValue(), $value, 'Time span value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -221,7 +221,7 @@ public function testGetAndSet() { $typed_data->setValue('invalid'); $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Check implementation of DurationInterface. - $typed_data = $this->createTypedData(array('type' => 'timespan'), 20); + $typed_data = $this->createTypedData(['type' => 'timespan'], 20); $this->assertTrue($typed_data->getDuration() instanceof \DateInterval); $typed_data->setDuration(new \DateInterval('PT4H')); $this->assertEqual($typed_data->getValue(), 60 * 60 * 4); @@ -230,7 +230,7 @@ public function testGetAndSet() { // URI type. $uri = 'http://example.com/foo/'; - $typed_data = $this->createTypedData(array('type' => 'uri'), $uri); + $typed_data = $this->createTypedData(['type' => 'uri'], $uri); $this->assertTrue($typed_data instanceof UriInterface, 'Typed data object is an instance of UriInterface.'); $this->assertTrue($typed_data->getValue() === $uri, 'URI value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -247,7 +247,7 @@ public function testGetAndSet() { $this->assertEqual($typed_data->validate()->count(), 0, 'Filename with spaces is valid.'); // Generate some files that will be used to test the binary data type. - $files = array(); + $files = []; for ($i = 0; $i < 3; $i++) { $path = "public://example_$i.png"; file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', $path); @@ -258,7 +258,7 @@ public function testGetAndSet() { // Email type. $value = $this->randomString(); - $typed_data = $this->createTypedData(array('type' => 'email'), $value); + $typed_data = $this->createTypedData(['type' => 'email'], $value); $this->assertTrue($typed_data instanceof StringInterface, 'Typed data object is an instance of StringInterface.'); $this->assertIdentical($typed_data->getValue(), $value, 'Email value was fetched.'); $new_value = 'test@example.com'; @@ -273,7 +273,7 @@ public function testGetAndSet() { $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Binary type. - $typed_data = $this->createTypedData(array('type' => 'binary'), $files[0]->getFileUri()); + $typed_data = $this->createTypedData(['type' => 'binary'], $files[0]->getFileUri()); $this->assertTrue($typed_data instanceof BinaryInterface, 'Typed data object is an instance of BinaryInterface.'); $this->assertTrue(is_resource($typed_data->getValue()), 'Binary value was fetched.'); $this->assertEqual($typed_data->validate()->count(), 0); @@ -294,8 +294,8 @@ public function testGetAndSet() { $this->assertEqual($typed_data->validate()->count(), 1, 'Validation detected invalid value.'); // Any type. - $value = array('foo'); - $typed_data = $this->createTypedData(array('type' => 'any'), $value); + $value = ['foo']; + $typed_data = $this->createTypedData(['type' => 'any'], $value); $this->assertIdentical($typed_data->getValue(), $value, 'Any value was fetched.'); $new_value = 'test@example.com'; $typed_data->setValue($new_value); @@ -307,9 +307,9 @@ public function testGetAndSet() { $this->assertEqual($typed_data->validate()->count(), 0); // We cannot test invalid values as everything is valid for the any type, // but make sure an array or object value passes validation also. - $typed_data->setValue(array('entry')); + $typed_data->setValue(['entry']); $this->assertEqual($typed_data->validate()->count(), 0); - $typed_data->setValue((object) array('entry')); + $typed_data->setValue((object) ['entry']); $this->assertEqual($typed_data->validate()->count(), 0); } @@ -318,7 +318,7 @@ public function testGetAndSet() { */ public function testTypedDataLists() { // Test working with an existing list of strings. - $value = array('one', 'two', 'three'); + $value = ['one', 'two', 'three']; $typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value); $this->assertEqual($typed_data->getValue(), $value, 'List value has been set.'); // Test iterating. @@ -347,14 +347,14 @@ public function testTypedDataLists() { $clone = clone $typed_data; $this->assertTrue($typed_data->getValue() === $clone->getValue()); $this->assertTrue($typed_data[0] !== $clone[0]); - $clone->setValue(array()); + $clone->setValue([]); $this->assertTrue($clone->isEmpty()); // Make sure that resetting the value using NULL results in an empty array. - $clone->setValue(array()); + $clone->setValue([]); $typed_data->setValue(NULL); - $this->assertIdentical($typed_data->getValue(), array()); - $this->assertIdentical($clone->getValue(), array()); + $this->assertIdentical($typed_data->getValue(), []); + $this->assertIdentical($clone->getValue(), []); // Test dealing with NULL items. $typed_data[] = NULL; @@ -367,7 +367,7 @@ public function testTypedDataLists() { $this->assertFalse($typed_data->isEmpty()); $this->assertEqual(count($typed_data), 3); - $this->assertEqual($typed_data->getValue(), array(NULL, '', 'three')); + $this->assertEqual($typed_data->getValue(), [NULL, '', 'three']); // Test unsetting. unset($typed_data[1]); $this->assertEqual(count($typed_data), 2); @@ -379,7 +379,7 @@ public function testTypedDataLists() { $this->assertEqual(count($typed_data), 2); // Test setting the list with less values. - $typed_data->setValue(array('one')); + $typed_data->setValue(['one']); $this->assertEqual($typed_data->count(), 1); // Test setting invalid values. @@ -397,9 +397,9 @@ public function testTypedDataLists() { */ public function testTypedDataListsFilter() { // Check that an all-pass filter leaves the list untouched. - $value = array('zero', 'one'); + $value = ['zero', 'one']; $typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value); - $typed_data->filter(function(TypedDataInterface $item) { + $typed_data->filter(function (TypedDataInterface $item) { return TRUE; }); $this->assertEqual($typed_data->count(), 2); @@ -409,17 +409,17 @@ public function testTypedDataListsFilter() { $this->assertEqual($typed_data[1]->getName(), 1); // Check that a none-pass filter empties the list. - $value = array('zero', 'one'); + $value = ['zero', 'one']; $typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value); - $typed_data->filter(function(TypedDataInterface $item) { + $typed_data->filter(function (TypedDataInterface $item) { return FALSE; }); $this->assertEqual($typed_data->count(), 0); // Check that filtering correctly renumbers elements. - $value = array('zero', 'one', 'two'); + $value = ['zero', 'one', 'two']; $typed_data = $this->createTypedData(ListDataDefinition::create('string'), $value); - $typed_data->filter(function(TypedDataInterface $item) { + $typed_data->filter(function (TypedDataInterface $item) { return $item->getValue() !== 'one'; }); $this->assertEqual($typed_data->count(), 2); @@ -434,11 +434,11 @@ public function testTypedDataListsFilter() { */ public function testTypedDataMaps() { // Test working with a simple map. - $value = array( + $value = [ 'one' => 'eins', 'two' => 'zwei', 'three' => 'drei', - ); + ]; $definition = MapDataDefinition::create() ->setPropertyDefinition('one', DataDefinition::create('string')) ->setPropertyDefinition('two', DataDefinition::create('string')) @@ -467,11 +467,11 @@ public function testTypedDataMaps() { $this->assertEqual($typed_data->get('one')->getValue(), 'uno'); // Make sure the update is reflected in the value of the map also. $value = $typed_data->getValue(); - $this->assertEqual($value, array( + $this->assertEqual($value, [ 'one' => 'uno', 'two' => 'zwei', 'three' => 'drei' - )); + ]); $properties = $typed_data->getProperties(); $this->assertEqual(array_keys($properties), array_keys($value)); @@ -479,12 +479,12 @@ public function testTypedDataMaps() { // Test setting a not defined property. It shouldn't show up in the // properties, but be kept in the values. - $typed_data->setValue(array('foo' => 'bar')); - $this->assertEqual(array_keys($typed_data->getProperties()), array('one', 'two', 'three')); - $this->assertEqual(array_keys($typed_data->getValue()), array('foo', 'one', 'two', 'three')); + $typed_data->setValue(['foo' => 'bar']); + $this->assertEqual(array_keys($typed_data->getProperties()), ['one', 'two', 'three']); + $this->assertEqual(array_keys($typed_data->getValue()), ['foo', 'one', 'two', 'three']); // Test getting the string representation. - $typed_data->setValue(array('one' => 'eins', 'two' => '', 'three' => 'drei')); + $typed_data->setValue(['one' => 'eins', 'two' => '', 'three' => 'drei']); $this->assertEqual($typed_data->getString(), 'eins, drei'); // Test isEmpty and cloning. @@ -492,14 +492,14 @@ public function testTypedDataMaps() { $clone = clone $typed_data; $this->assertTrue($typed_data->getValue() === $clone->getValue()); $this->assertTrue($typed_data->get('one') !== $clone->get('one')); - $clone->setValue(array()); + $clone->setValue([]); $this->assertTrue($clone->isEmpty()); // Make sure the difference between NULL (not set) and an empty array is // kept. $typed_data->setValue(NULL); $this->assertNull($typed_data->getValue()); - $typed_data->setValue(array()); + $typed_data->setValue([]); $value = $typed_data->getValue(); $this->assertTrue(isset($value) && is_array($value)); @@ -535,9 +535,9 @@ public function testTypedDataMaps() { */ public function testTypedDataValidation() { $definition = DataDefinition::create('integer') - ->setConstraints(array( - 'Range' => array('min' => 5), - )); + ->setConstraints([ + 'Range' => ['min' => 5], + ]); $violations = $this->typedDataManager->create($definition, 10)->validate(); $this->assertEqual($violations->count(), 0); @@ -546,27 +546,27 @@ public function testTypedDataValidation() { $this->assertEqual($violations->count(), 1); // Test translating violation messages. - $message = t('This value should be %limit or more.', array('%limit' => 5)); + $message = t('This value should be %limit or more.', ['%limit' => 5]); $this->assertEqual($violations[0]->getMessage(), $message, 'Translated violation message retrieved.'); $this->assertEqual($violations[0]->getPropertyPath(), ''); $this->assertIdentical($violations[0]->getRoot(), $integer, 'Root object returned.'); // Test translating violation messages when pluralization is used. $definition = DataDefinition::create('string') - ->setConstraints(array( - 'Length' => array('min' => 10), - )); + ->setConstraints([ + 'Length' => ['min' => 10], + ]); $violations = $this->typedDataManager->create($definition, "short")->validate(); $this->assertEqual($violations->count(), 1); - $message = t('This value is too short. It should have %limit characters or more.', array('%limit' => 10)); + $message = t('This value is too short. It should have %limit characters or more.', ['%limit' => 10]); $this->assertEqual($violations[0]->getMessage(), $message, 'Translated violation message retrieved.'); // Test having multiple violations. $definition = DataDefinition::create('integer') - ->setConstraints(array( - 'Range' => array('min' => 5), - 'Null' => array(), - )); + ->setConstraints([ + 'Range' => ['min' => 5], + 'Null' => [], + ]); $violations = $this->typedDataManager->create($definition, 10)->validate(); $this->assertEqual($violations->count(), 1); $violations = $this->typedDataManager->create($definition, 1)->validate(); @@ -575,12 +575,12 @@ public function testTypedDataValidation() { // Test validating property containers and make sure the NotNull and Null // constraints work with typed data containers. $definition = BaseFieldDefinition::create('integer') - ->setConstraints(array('NotNull' => array())); - $field_item = $this->typedDataManager->create($definition, array('value' => 10)); + ->setConstraints(['NotNull' => []]); + $field_item = $this->typedDataManager->create($definition, ['value' => 10]); $violations = $field_item->validate(); $this->assertEqual($violations->count(), 0); - $field_item = $this->typedDataManager->create($definition, array('value' => 'no integer')); + $field_item = $this->typedDataManager->create($definition, ['value' => 'no integer']); $violations = $field_item->validate(); $this->assertEqual($violations->count(), 1); $this->assertEqual($violations[0]->getPropertyPath(), '0.value'); @@ -592,8 +592,8 @@ public function testTypedDataValidation() { // Test the Null constraint with typed data containers. $definition = BaseFieldDefinition::create('float') - ->setConstraints(array('Null' => array())); - $field_item = $this->typedDataManager->create($definition, array('value' => 11.5)); + ->setConstraints(['Null' => []]); + $field_item = $this->typedDataManager->create($definition, ['value' => 11.5]); $violations = $field_item->validate(); $this->assertEqual($violations->count(), 1); $field_item = $this->typedDataManager->create($definition); @@ -622,9 +622,9 @@ public function testTypedDataValidation() { // Test validating a list of a values and make sure property paths starting // with "0" are created. $definition = BaseFieldDefinition::create('integer'); - $violations = $this->typedDataManager->create($definition, array(array('value' => 10)))->validate(); + $violations = $this->typedDataManager->create($definition, [['value' => 10]])->validate(); $this->assertEqual($violations->count(), 0); - $violations = $this->typedDataManager->create($definition, array(array('value' => 'string')))->validate(); + $violations = $this->typedDataManager->create($definition, [['value' => 'string']])->validate(); $this->assertEqual($violations->count(), 1); $this->assertEqual($violations[0]->getInvalidValue(), 'string'); diff --git a/core/tests/Drupal/KernelTests/Core/Update/CompatibilityFixTest.php b/core/tests/Drupal/KernelTests/Core/Update/CompatibilityFixTest.php index ee1b6e17..a724623e 100644 --- a/core/tests/Drupal/KernelTests/Core/Update/CompatibilityFixTest.php +++ b/core/tests/Drupal/KernelTests/Core/Update/CompatibilityFixTest.php @@ -21,7 +21,7 @@ protected function setUp() { require_once \Drupal::root() . '/core/includes/update.inc'; } - function testFixCompatibility() { + public function testFixCompatibility() { $extension_config = \Drupal::configFactory()->getEditable('core.extension'); // Add an incompatible/non-existent module to the config. diff --git a/core/tests/Drupal/KernelTests/Core/Url/LinkGenerationTest.php b/core/tests/Drupal/KernelTests/Core/Url/LinkGenerationTest.php index 3d7ce5ec..16452d01 100644 --- a/core/tests/Drupal/KernelTests/Core/Url/LinkGenerationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Url/LinkGenerationTest.php @@ -19,7 +19,7 @@ class LinkGenerationTest extends KernelTestBase { /** * Tests how hook_link_alter() can affect escaping of the link text. */ - function testHookLinkAlter() { + public function testHookLinkAlter() { $url = Url::fromUri('http://example.com'); $renderer = \Drupal::service('renderer'); diff --git a/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php b/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php new file mode 100644 index 00000000..8e17422f --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php @@ -0,0 +1,45 @@ +installConfig('config_test'); + } + + /** + * @see \Drupal\Core\Validation\Plugin\Validation\Constraint\UuidConstraint + */ + public function testUuid() { + $typed_config_manager = \Drupal::service('config.typed'); + /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */ + $typed_config = $typed_config_manager->get('config_test.validation'); + $typed_config->get('uuid') + ->setValue(\Drupal::service('uuid')->generate()); + + $this->assertCount(0, $typed_config->validate()); + + $typed_config->get('uuid') + ->setValue(\Drupal::service('uuid')->generate() . '-invalid'); + $this->assertCount(1, $typed_config->validate()); + } + +} diff --git a/core/tests/Drupal/KernelTests/FileSystemModuleDiscoveryDataProviderTrait.php b/core/tests/Drupal/KernelTests/FileSystemModuleDiscoveryDataProviderTrait.php new file mode 100644 index 00000000..02d63841 --- /dev/null +++ b/core/tests/Drupal/KernelTests/FileSystemModuleDiscoveryDataProviderTrait.php @@ -0,0 +1,30 @@ +streamWrappers = array(); + $this->streamWrappers = []; \Drupal::unsetContainer(); $this->classLoader = require $this->root . '/autoload.php'; @@ -262,13 +271,13 @@ protected function bootEnvironment() { $this->databasePrefix = $test_db->getDatabasePrefix(); drupal_valid_test_ua($this->databasePrefix); - $settings = array( + $settings = [ 'hash_salt' => get_class($this), 'file_public_path' => $this->siteDirectory . '/files', // Disable Twig template caching/dumping. 'twig_cache' => FALSE, // @see \Drupal\KernelTests\KernelTestBase::register() - ); + ]; new Settings($settings); $this->setUpFilesystem(); @@ -297,9 +306,9 @@ protected function setUpFilesystem() { $settings['file_public_path'] = $this->siteDirectory . '/files'; new Settings($settings); - $GLOBALS['config_directories'] = array( + $GLOBALS['config_directories'] = [ CONFIG_SYNC_DIRECTORY => $this->siteDirectory . '/files/config/sync', - ); + ]; } /** @@ -342,23 +351,13 @@ private function bootKernel() { // PHPUnit's @test annotations are intentionally ignored/not supported. return strpos($method->getName(), 'test') === 0; })); - if ($test_method_count > 1 && !$this->isTestInIsolation()) { - // Clone a precompiled, empty ContainerBuilder instance for each test. - $container = $this->getCompiledContainerBuilder($modules); - } // Bootstrap the kernel. Do not use createFromRequest() to retain Settings. $kernel = new DrupalKernel('testing', $this->classLoader, FALSE); $kernel->setSitePath($this->siteDirectory); - // Boot the precompiled container. The kernel will enhance it with synthetic - // services. - if (isset($container)) { - $kernel->setContainer($container); - unset($container); - } // Boot a new one-time container from scratch. Ensure to set the module list // upfront to avoid a subsequent rebuild. - elseif ($modules && $extensions = $this->getExtensionsForModules($modules)) { + if ($modules && $extensions = $this->getExtensionsForModules($modules)) { $kernel->updateModules($extensions, $extensions); } // DrupalKernel::boot() is not sufficient as it does not invoke preHandle(), @@ -388,10 +387,11 @@ private function bootKernel() { // Write the core.extension configuration. // Required for ConfigInstaller::installDefaultConfig() to work. - $this->container->get('config.storage')->write('core.extension', array( + $this->container->get('config.storage')->write('core.extension', [ 'module' => array_fill_keys($modules, 0), - 'theme' => array(), - )); + 'theme' => [], + 'profile' => '', + ]); $settings = Settings::getAll(); $settings['php_storage']['default'] = [ @@ -404,6 +404,11 @@ private function bootKernel() { // While this should be enforced via settings.php prior to installation, // some tests expect to be able to test mail system implementations. $GLOBALS['config']['system.mail']['interface']['default'] = 'test_mail_collector'; + + // Manually configure the default file scheme so that modules that use file + // functions don't have to install system and its configuration. + // @see file_default_scheme() + $GLOBALS['config']['system.file']['default_scheme'] = 'public'; } /** @@ -454,76 +459,14 @@ protected function getDatabaseConnectionInfo() { foreach ($connection_info as $target => $value) { // Replace the full table prefix definition to ensure that no table // prefixes of the test runner leak into the test. - $connection_info[$target]['prefix'] = array( + $connection_info[$target]['prefix'] = [ 'default' => $value['prefix']['default'] . $this->databasePrefix, - ); + ]; } } return $connection_info; } - /** - * Prepares a precompiled ContainerBuilder for all tests of this class. - * - * Avoids repetitive calls to ContainerBuilder::compile(), which is very slow. - * - * Based on the (always identical) list of $modules to enable, an initial - * container is compiled, all instantiated services are reset/removed, and - * this precompiled container is stored in a static class property. (Static, - * because PHPUnit instantiates a new class instance for each test *method*.) - * - * This method is not invoked if there is only a single test method. It is - * also not invoked for tests running in process isolation (since each test - * method runs in a separate process). - * - * The ContainerBuilder is not dumped into the filesystem (which would yield - * an actually compiled Container class), because - * - * 1. PHP code cannot be unloaded, so e.g. 900 tests would load 900 different, - * full Container classes into memory, quickly exceeding any sensible - * memory consumption (GigaBytes). - * 2. Dumping a Container class requires to actually write to the system's - * temporary directory. This is not really easy with vfs, because vfs - * doesn't support yet "include 'vfs://container.php'.". Maybe we could fix - * that upstream. - * 3. PhpDumper is very slow on its own. - * - * @param string[] $modules - * The list of modules to enable. - * - * @return \Drupal\Core\DependencyInjection\ContainerBuilder - * A clone of the precompiled, empty service container. - */ - private function getCompiledContainerBuilder(array $modules) { - if (!isset(self::$initialContainerBuilder)) { - $kernel = new DrupalKernel('testing', $this->classLoader, FALSE); - $kernel->setSitePath($this->siteDirectory); - if ($modules && $extensions = $this->getExtensionsForModules($modules)) { - $kernel->updateModules($extensions, $extensions); - } - $kernel->boot(); - self::$initialContainerBuilder = $kernel->getContainer(); - - // Remove all instantiated services, so the container is safe for cloning. - // Technically, ContainerBuilder::set($id, NULL) removes each definition, - // but the container is compiled/frozen already. - foreach (self::$initialContainerBuilder->getServiceIds() as $id) { - self::$initialContainerBuilder->set($id, NULL); - } - - // Destruct and trigger garbage collection. - \Drupal::unsetContainer(); - $kernel->shutdown(); - $kernel = NULL; - // @see register() - $this->container = NULL; - } - - $container = clone self::$initialContainerBuilder; - - return $container; - } - /** * Initializes the FileCache component. * @@ -561,9 +504,9 @@ protected function initFileCache() { * @see \Drupal\Core\Extension\ModuleHandler::add() */ private function getExtensionsForModules(array $modules) { - $extensions = array(); + $extensions = []; $discovery = new ExtensionDiscovery($this->root); - $discovery->setProfileDirectories(array()); + $discovery->setProfileDirectories([]); $list = $discovery->scan('module'); foreach ($modules as $name) { if (!isset($list[$name])) { @@ -608,7 +551,7 @@ public function register(ContainerBuilder $container) { if ($this->strictConfigSchema) { $container - ->register('simpletest.config_schema_checker', 'Drupal\Core\Config\Testing\ConfigSchemaChecker') + ->register('simpletest.config_schema_checker', ConfigSchemaChecker::class) ->addArgument(new Reference('config.typed')) ->addArgument($this->getConfigSchemaExclusions()) ->addTag('event_subscriber'); @@ -626,7 +569,7 @@ public function register(ContainerBuilder $container) { if ($container->hasDefinition('password')) { $container->getDefinition('password') - ->setArguments(array(1)); + ->setArguments([1]); } TestServiceProvider::addRouteProvider($container); } @@ -704,7 +647,7 @@ protected function tearDown() { // Free up memory: Custom test class properties. // Note: Private properties cannot be cleaned up. $rc = new \ReflectionClass(__CLASS__); - $blacklist = array(); + $blacklist = []; foreach ($rc->getProperties() as $property) { $blacklist[$property->name] = $property->getDeclaringClass()->name; } @@ -724,7 +667,7 @@ protected function tearDown() { } \Drupal::unsetContainer(); $this->container = NULL; - new Settings(array()); + new Settings([]); parent::tearDown(); } @@ -742,20 +685,11 @@ public function tearDownCloseDatabaseConnection() { } } - /** - * {@inheritdoc} - */ - public static function tearDownAfterClass() { - // Free up memory: Precompiled container. - self::$initialContainerBuilder = NULL; - parent::tearDownAfterClass(); - } - /** * Installs default configuration for a given list of modules. * * @param string|string[] $modules - * A list of modules for which to install default configuration. + * A module or list of modules for which to install default configuration. * * @throws \LogicException * If any module in $modules is not enabled. @@ -827,18 +761,18 @@ protected function installEntitySchema($entity_type_id) { $all_tables_exist = TRUE; foreach ($tables as $table) { if (!$db_schema->tableExists($table)) { - $this->fail(SafeMarkup::format('Installed entity type table for the %entity_type entity type: %table', array( + $this->fail(SafeMarkup::format('Installed entity type table for the %entity_type entity type: %table', [ '%entity_type' => $entity_type_id, '%table' => $table, - ))); + ])); $all_tables_exist = FALSE; } } if ($all_tables_exist) { - $this->pass(SafeMarkup::format('Installed entity type tables for the %entity_type entity type: %tables', array( + $this->pass(SafeMarkup::format('Installed entity type tables for the %entity_type entity type: %tables', [ '%entity_type' => $entity_type_id, '%tables' => '{' . implode('}, {', $tables) . '}', - ))); + ])); } } } @@ -846,6 +780,9 @@ protected function installEntitySchema($entity_type_id) { /** * Enables modules for this test. * + * This method does not install modules fully. Services and hooks for the + * module are available, but the install process is not performed. + * * To install test modules outside of the testing environment, add * @code * $settings['extension_discovery_scan_tests'] = TRUE; @@ -1025,7 +962,7 @@ protected function vfsDump() { * @return array */ private static function getModulesToEnable($class) { - $modules = array(); + $modules = []; while ($class) { if (property_exists($class, 'modules')) { // Only add the modules, if the $modules property was not inherited. @@ -1057,21 +994,28 @@ protected function prepareTemplate(\Text_Template $template) { // @see /core/tests/bootstrap.php $bootstrap_globals .= '$namespaces = ' . var_export($GLOBALS['namespaces'], TRUE) . ";\n"; - $template->setVar(array( + $template->setVar([ 'constants' => '', 'included_files' => '', 'globals' => $bootstrap_globals, - )); + ]); } /** - * Returns whether the current test runs in isolation. + * Returns whether the current test method is running in a separate process. + * + * Note that KernelTestBase will run in a separate process by default. * * @return bool * + * @see \Drupal\KernelTests\KernelTestBase::$runTestInSeparateProcess * @see https://github.com/sebastianbergmann/phpunit/pull/1350 + * + * @deprecated in Drupal 8.4.x, for removal before the Drupal 9.0.0 release. + * KernelTestBase tests are always run in isolated processes. */ protected function isTestInIsolation() { + @trigger_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated in Drupal 8.4.x, for removal before the Drupal 9.0.0 release. KernelTestBase tests are always run in isolated processes.', E_USER_DEPRECATED); return function_exists('__phpunit_run_isolated_test'); } @@ -1084,12 +1028,12 @@ protected function isTestInIsolation() { * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.2.0. */ public function __get($name) { - if (in_array($name, array( + if (in_array($name, [ 'public_files_directory', 'private_files_directory', 'temp_files_directory', 'translation_files_directory', - ))) { + ])) { // @comment it in again. trigger_error(sprintf("KernelTestBase::\$%s no longer exists. Use the regular API method to retrieve it instead (e.g., Settings).", $name), E_USER_DEPRECATED); switch ($name) { @@ -1109,12 +1053,12 @@ public function __get($name) { if ($name === 'configDirectories') { trigger_error(sprintf("KernelTestBase::\$%s no longer exists. Use config_get_config_directory() directly instead.", $name), E_USER_DEPRECATED); - return array( + return [ CONFIG_SYNC_DIRECTORY => config_get_config_directory(CONFIG_SYNC_DIRECTORY), - ); + ]; } - $denied = array( + $denied = [ // @see \Drupal\simpletest\TestBase 'testId', 'timeLimit', @@ -1132,7 +1076,7 @@ public function __get($name) { 'generatedTestFiles', // Properties from the old KernelTestBase class that has been removed. 'keyValueFactory', - ); + ]; if (in_array($name, $denied) || strpos($name, 'original') === 0) { throw new \RuntimeException(sprintf('TestBase::$%s property no longer exists', $name)); } diff --git a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php index 469debed..f44c9650 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php +++ b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php @@ -9,7 +9,10 @@ /** * @coversDefaultClass \Drupal\KernelTests\KernelTestBase + * * @group PHPUnit + * @group Test + * @group KernelTests */ class KernelTestBaseTest extends KernelTestBase { @@ -27,21 +30,21 @@ public function testSetUpBeforeClass() { public function testBootEnvironment() { $this->assertRegExp('/^test\d{8}$/', $this->databasePrefix); $this->assertStringStartsWith('vfs://root/sites/simpletest/', $this->siteDirectory); - $this->assertEquals(array( - 'root' => array( - 'sites' => array( - 'simpletest' => array( - substr($this->databasePrefix, 4) => array( - 'files' => array( - 'config' => array( - 'sync' => array(), - ), - ), - ), - ), - ), - ), - ), vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure()); + $this->assertEquals([ + 'root' => [ + 'sites' => [ + 'simpletest' => [ + substr($this->databasePrefix, 4) => [ + 'files' => [ + 'config' => [ + 'sync' => [], + ], + ], + ], + ], + ], + ], + ], vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure()); } /** @@ -70,15 +73,15 @@ public function testSetUp() { $this->assertArrayHasKey('destroy-me', $GLOBALS); $database = $this->container->get('database'); - $database->schema()->createTable('foo', array( - 'fields' => array( - 'number' => array( + $database->schema()->createTable('foo', [ + 'fields' => [ + 'number' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, - ), - ), - )); + ], + ], + ]); $this->assertTrue($database->schema()->tableExists('foo')); // Ensure that the database tasks have been run during set up. Neither MySQL @@ -120,7 +123,7 @@ public function testRegister() { $this->assertSame($request, \Drupal::request()); // Trigger a container rebuild. - $this->enableModules(array('system')); + $this->enableModules(['system']); // Verify that this container is identical to the actual container. $this->assertInstanceOf('Symfony\Component\DependencyInjection\ContainerInterface', $this->container); @@ -137,22 +140,21 @@ public function testRegister() { } /** - * @covers ::getCompiledContainerBuilder + * Tests whether the fixture allows us to install modules and configuration. * - * The point of this test is to have integration level testing. + * @see ::testSubsequentContainerIsolation() */ - public function testCompiledContainer() { + public function testContainerIsolation() { $this->enableModules(['system', 'user']); $this->assertNull($this->installConfig('user')); } /** - * @covers ::getCompiledContainerBuilder - * @depends testCompiledContainer + * Tests whether the fixture can re-install modules and configuration. * - * The point of this test is to have integration level testing. + * @depends testContainerIsolation */ - public function testCompiledContainerIsDestructed() { + public function testSubsequentContainerIsolation() { $this->enableModules(['system', 'user']); $this->assertNull($this->installConfig('user')); } @@ -165,23 +167,23 @@ public function testRender() { $element_info = $this->container->get('element_info'); $this->assertSame(['#defaults_loaded' => TRUE], $element_info->getInfo($type)); - $this->enableModules(array('filter')); + $this->enableModules(['filter']); $this->assertNotSame($element_info, $this->container->get('element_info')); $this->assertNotEmpty($this->container->get('element_info')->getInfo($type)); - $build = array( + $build = [ '#type' => 'html_tag', '#tag' => 'h3', '#value' => 'Inner', - ); + ]; $expected = "

Inner

\n"; $this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName()); $output = \Drupal::service('renderer')->renderRoot($build); $this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName()); - $this->assertEquals($expected, $build['#children']); + $this->assertEquals($expected, $build['#markup']); $this->assertEquals($expected, $output); } @@ -189,12 +191,12 @@ public function testRender() { * @covers ::render */ public function testRenderWithTheme() { - $this->enableModules(array('system')); + $this->enableModules(['system']); - $build = array( + $build = [ '#type' => 'textfield', '#name' => 'test', - ); + ]; $expected = '/' . preg_quote('assertArrayNotHasKey('theme', $GLOBALS); @@ -205,6 +207,76 @@ public function testRenderWithTheme() { $this->assertRegExp($expected, (string) $output); } + /** + * @covers ::bootKernel + */ + public function testFileDefaultScheme() { + $this->assertEquals('public', file_default_scheme()); + $this->assertEquals('public', \Drupal::config('system.file')->get('default_scheme')); + } + + /** + * Tests the assumption that local time is in 'Australia/Sydney'. + */ + public function testLocalTimeZone() { + // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php + $this->assertEquals('Australia/Sydney', date_default_timezone_get()); + } + + /** + * Tests that a test method is skipped when it requires a module not present. + * + * In order to catch checkRequirements() regressions, we have to make a new + * test object and run checkRequirements() here. + * + * @covers ::checkRequirements + * @covers ::checkModuleRequirements + */ + public function testMethodRequiresModule() { + require __DIR__ . '/../../fixtures/KernelMissingDependentModuleMethodTest.php'; + + $stub_test = new KernelMissingDependentModuleMethodTest(); + // We have to setName() to the method name we're concerned with. + $stub_test->setName('testRequiresModule'); + + // We cannot use $this->setExpectedException() because PHPUnit would skip + // the test before comparing the exception type. + try { + $stub_test->publicCheckRequirements(); + $this->fail('Missing required module throws skipped test exception.'); + } + catch (\PHPUnit_Framework_SkippedTestError $e) { + $this->assertEqual('Required modules: module_does_not_exist', $e->getMessage()); + } + } + + /** + * Tests that a test case is skipped when it requires a module not present. + * + * In order to catch checkRequirements() regressions, we have to make a new + * test object and run checkRequirements() here. + * + * @covers ::checkRequirements + * @covers ::checkModuleRequirements + */ + public function testRequiresModule() { + require __DIR__ . '/../../fixtures/KernelMissingDependentModuleTest.php'; + + $stub_test = new KernelMissingDependentModuleTest(); + // We have to setName() to the method name we're concerned with. + $stub_test->setName('testRequiresModule'); + + // We cannot use $this->setExpectedException() because PHPUnit would skip + // the test before comparing the exception type. + try { + $stub_test->publicCheckRequirements(); + $this->fail('Missing required module throws skipped test exception.'); + } + catch (\PHPUnit_Framework_SkippedTestError $e) { + $this->assertEqual('Required modules: module_does_not_exist', $e->getMessage()); + } + } + /** * {@inheritdoc} */ @@ -220,11 +292,11 @@ protected function tearDown() { $this->assertTrue(empty($tables), 'All test tables have been removed.'); } else { - $result = $connection->query("SELECT name FROM " . $this->databasePrefix . ".sqlite_master WHERE type = :type AND name LIKE :table_name AND name NOT LIKE :pattern", array( + $result = $connection->query("SELECT name FROM " . $this->databasePrefix . ".sqlite_master WHERE type = :type AND name LIKE :table_name AND name NOT LIKE :pattern", [ ':type' => 'table', ':table_name' => '%', ':pattern' => 'sqlite_%', - ))->fetchAllKeyed(0, 0); + ])->fetchAllKeyed(0, 0); $this->assertTrue(empty($result), 'All test tables have been removed.'); } diff --git a/core/tests/Drupal/Tests/AssertHelperTrait.php b/core/tests/Drupal/Tests/AssertHelperTrait.php new file mode 100644 index 00000000..ba814d96 --- /dev/null +++ b/core/tests/Drupal/Tests/AssertHelperTrait.php @@ -0,0 +1,35 @@ +assertSame($expected, $class->testMethod($value)); + } + + public function providerCastSafeStrings() { + $safe_string = Markup::create('test safe string'); + return [ + ['test simple string', 'test simple string'], + [['test simple array', 'test simple array'], ['test simple array', 'test simple array']], + ['test safe string', $safe_string], + [['test safe string', 'test safe string'], [$safe_string, $safe_string]], + [['test safe string', 'mixed array', 'test safe string'], [$safe_string, 'mixed array', $safe_string]], + ]; + } + +} + +class AssertHelperTestClass { + use AssertHelperTrait; + + public function testMethod($value) { + return $this->castSafeStrings($value); + } + +} diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php index d38db65b..e7c79f38 100644 --- a/core/tests/Drupal/Tests/BrowserTestBase.php +++ b/core/tests/Drupal/Tests/BrowserTestBase.php @@ -5,33 +5,28 @@ use Behat\Mink\Driver\GoutteDriver; use Behat\Mink\Element\Element; use Behat\Mink\Mink; +use Behat\Mink\Selector\SelectorsHandler; use Behat\Mink\Session; -use Drupal\Component\FileCache\FileCacheFactory; +use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Html; -use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\UrlHelper; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Config\Testing\ConfigSchemaChecker; use Drupal\Core\Database\Database; -use Drupal\Core\DrupalKernel; -use Drupal\Core\Serialization\Yaml; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AnonymousUserSession; -use Drupal\Core\Session\UserSession; -use Drupal\Core\Site\Settings; -use Drupal\Core\StreamWrapper\StreamWrapperInterface; -use Drupal\Core\Test\TestRunnerKernel; +use Drupal\Core\Test\FunctionalTestSetupTrait; +use Drupal\Core\Test\TestSetupTrait; use Drupal\Core\Url; -use Drupal\Core\Test\TestDatabase; +use Drupal\Core\Utility\Error; use Drupal\FunctionalTests\AssertLegacyTrait; -use Drupal\simpletest\AssertHelperTrait; -use Drupal\simpletest\ContentTypeCreationTrait; -use Drupal\simpletest\BlockCreationTrait; -use Drupal\simpletest\NodeCreationTrait; -use Drupal\simpletest\UserCreationTrait; +use Drupal\Tests\block\Traits\BlockCreationTrait; +use Drupal\Tests\node\Traits\ContentTypeCreationTrait; +use Drupal\Tests\node\Traits\NodeCreationTrait; +use Drupal\Tests\user\Traits\UserCreationTrait; +use PHPUnit\Framework\TestCase; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; use Symfony\Component\CssSelector\CssSelectorConverter; -use Symfony\Component\HttpFoundation\Request; /** * Provides a test case for functional Drupal tests. @@ -42,7 +37,10 @@ * * @ingroup testing */ -abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { +abstract class BrowserTestBase extends TestCase { + + use FunctionalTestSetupTrait; + use TestSetupTrait; use AssertHelperTrait; use BlockCreationTrait { placeBlock as drupalPlaceBlock; @@ -58,24 +56,12 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { createContentType as drupalCreateContentType; } use ConfigTestTrait; + use TestRequirementsTrait; use UserCreationTrait { createRole as drupalCreateRole; createUser as drupalCreateUser; } - - /** - * Class loader. - * - * @var object - */ - protected $classLoader; - - /** - * The site directory of this test run. - * - * @var string - */ - protected $siteDirectory; + use XdebugRequestTrait; /** * The database prefix of this test run. @@ -84,13 +70,6 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected $databasePrefix; - /** - * The site directory of the original parent site. - * - * @var string - */ - protected $originalSiteDirectory; - /** * Time limit in seconds for the test. * @@ -98,37 +77,6 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected $timeLimit = 500; - /** - * The public file directory for the test environment. - * - * This is set in BrowserTestBase::prepareEnvironment(). - * - * @var string - */ - protected $publicFilesDirectory; - - /** - * The private file directory for the test environment. - * - * This is set in BrowserTestBase::prepareEnvironment(). - * - * @var string - */ - protected $privateFilesDirectory; - - /** - * The temp file directory for the test environment. - * - * This is set in BrowserTestBase::prepareEnvironment(). This value has to - * match the temporary directory created in install_base_system() for test - * installs. - * - * @see install_base_system() - * - * @var string - */ - protected $tempFilesDirectory; - /** * The translation file directory for the test environment. * @@ -138,20 +86,6 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected $translationFilesDirectory; - /** - * The DrupalKernel instance used in the test. - * - * @var \Drupal\Core\DrupalKernel - */ - protected $kernel; - - /** - * The dependency injection container used in the test. - * - * @var \Symfony\Component\DependencyInjection\ContainerInterface - */ - protected $container; - /** * The config importer that can be used in a test. * @@ -159,15 +93,6 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected $configImporter; - /** - * Set to TRUE to strict check all configuration saved. - * - * @see \Drupal\Core\Config\Testing\ConfigSchemaChecker - * - * @var bool - */ - protected $strictConfigSchema = TRUE; - /** * Modules to enable. * @@ -181,22 +106,6 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected static $modules = []; - /** - * An array of config object names that are excluded from schema checking. - * - * @var string[] - */ - protected static $configSchemaCheckerExclusions = array( - // Following are used to test lack of or partial schema. Where partial - // schema is provided, that is explicitly tested in specific tests. - 'config_schema_test.noschema', - 'config_schema_test.someschema', - 'config_schema_test.schema_data_types', - 'config_schema_test.no_schema_data_types', - // Used to test application of schema to filtering of configuration. - 'config_test.dynamic.system', - ); - /** * The profile to install as a basis for testing. * @@ -211,20 +120,6 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected $loggedInUser = FALSE; - /** - * The root user. - * - * @var \Drupal\Core\Session\UserSession - */ - protected $rootUser; - - /** - * The config directories used in this test. - * - * @var array - */ - protected $configDirectories = array(); - /** * An array of custom translations suitable for drupal_rewrite_settings(). * @@ -348,6 +243,46 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase { */ protected $originalShutdownCallbacks = []; + /** + * The number of meta refresh redirects to follow, or NULL if unlimited. + * + * @var null|int + */ + protected $maximumMetaRefreshCount = NULL; + + /** + * The number of meta refresh redirects followed during ::drupalGet(). + * + * @var int + */ + protected $metaRefreshCount = 0; + + /** + * The app root. + * + * @var string + */ + protected $root; + + /** + * The original container. + * + * Move this to \Drupal\Core\Test\FunctionalTestSetupTrait once TestBase no + * longer provides the same value. + * + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + protected $originalContainer; + + /** + * {@inheritdoc} + */ + public function __construct($name = NULL, array $data = [], $dataName = '') { + parent::__construct($name, $data, $dataName); + + $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))); + } + /** * Initializes Mink sessions. */ @@ -356,13 +291,26 @@ protected function initMink() { if ($driver instanceof GoutteDriver) { // Turn off curl timeout. Having a timeout is not a problem in a normal - // test running, but it is a problem when debugging. + // test running, but it is a problem when debugging. Also, disable SSL + // peer verification so that testing under HTTPS always works. /** @var \GuzzleHttp\Client $client */ - $client = $this->container->get('http_client_factory')->fromOptions(['timeout' => NULL]); + $client = $this->container->get('http_client_factory')->fromOptions([ + 'timeout' => NULL, + 'verify' => FALSE, + ]); + + // Inject a Guzzle middleware to generate debug output for every request + // performed in the test. + $handler_stack = $client->getConfig('handler'); + $handler_stack->push($this->getResponseLogHandler()); + $driver->getClient()->setClient($client); } - $session = new Session($driver); + $selectors_handler = new SelectorsHandler([ + 'hidden_field_selector' => new HiddenFieldSelector() + ]); + $session = new Session($driver, $selectors_handler); $this->mink = new Mink(); $this->mink->registerSession('default', $session); $this->mink->setDefaultSessionName('default'); @@ -418,6 +366,67 @@ protected function getDefaultDriverInstance() { return $driver; } + /** + * Creates the directory to store browser output. + * + * Creates the directory to store browser output in if a file to write + * URLs to has been created by \Drupal\Tests\Listeners\HtmlOutputPrinter. + */ + protected function initBrowserOutputFile() { + $browser_output_file = getenv('BROWSERTEST_OUTPUT_FILE'); + $this->htmlOutputEnabled = is_file($browser_output_file); + if ($this->htmlOutputEnabled) { + $this->htmlOutputFile = $browser_output_file; + $this->htmlOutputClassName = str_replace("\\", "_", get_called_class()); + $this->htmlOutputDirectory = DRUPAL_ROOT . '/sites/simpletest/browser_output'; + if (file_prepare_directory($this->htmlOutputDirectory, FILE_CREATE_DIRECTORY) && !file_exists($this->htmlOutputDirectory . '/.htaccess')) { + file_put_contents($this->htmlOutputDirectory . '/.htaccess', "\nExpiresActive Off\n\n"); + } + $this->htmlOutputCounterStorage = $this->htmlOutputDirectory . '/' . $this->htmlOutputClassName . '.counter'; + $this->htmlOutputTestId = str_replace('sites/simpletest/', '', $this->siteDirectory); + if (is_file($this->htmlOutputCounterStorage)) { + $this->htmlOutputCounter = max(1, (int) file_get_contents($this->htmlOutputCounterStorage)) + 1; + } + } + } + + /** + * Provides a Guzzle middleware handler to log every response received. + * + * @return callable + * The callable handler that will do the logging. + */ + protected function getResponseLogHandler() { + return function (callable $handler) { + return function (RequestInterface $request, array $options) use ($handler) { + return $handler($request, $options) + ->then(function (ResponseInterface $response) use ($request) { + if ($this->htmlOutputEnabled) { + + $caller = $this->getTestMethodCaller(); + $html_output = 'Called from ' . $caller['function'] . ' line ' . $caller['line']; + $html_output .= '
' . $request->getMethod() . ' request to: ' . $request->getUri(); + + // On redirect responses (status code starting with '3') we need + // to remove the meta tag that would do a browser refresh. We + // don't want to redirect developers away when they look at the + // debug output file in their browser. + $body = $response->getBody(); + $status_code = (string) $response->getStatusCode(); + if ($status_code[0] === '3') { + $body = preg_replace('##', '', $body, 1); + } + $html_output .= '
' . $body; + $html_output .= $this->formatHtmlOutputHeaders($response->getHeaders()); + + $this->htmlOutput($html_output); + } + return $response; + }); + }; + }; + } + /** * Registers additional Mink sessions. * @@ -437,43 +446,9 @@ protected function registerSessions() {} * {@inheritdoc} */ protected function setUp() { - global $base_url; parent::setUp(); - // Get and set the domain of the environment we are running our test - // coverage against. - $base_url = getenv('SIMPLETEST_BASE_URL'); - if (!$base_url) { - throw new \Exception( - 'You must provide a SIMPLETEST_BASE_URL environment variable to run some PHPUnit based functional tests.' - ); - } - - // Setup $_SERVER variable. - $parsed_url = parse_url($base_url); - $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''); - $path = isset($parsed_url['path']) ? rtrim(rtrim($parsed_url['path']), '/') : ''; - $port = isset($parsed_url['port']) ? $parsed_url['port'] : 80; - - $this->baseUrl = $base_url; - - // If the passed URL schema is 'https' then setup the $_SERVER variables - // properly so that testing will run under HTTPS. - if ($parsed_url['scheme'] === 'https') { - $_SERVER['HTTPS'] = 'on'; - } - $_SERVER['HTTP_HOST'] = $host; - $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; - $_SERVER['SERVER_ADDR'] = '127.0.0.1'; - $_SERVER['SERVER_PORT'] = $port; - $_SERVER['SERVER_SOFTWARE'] = NULL; - $_SERVER['SERVER_NAME'] = 'localhost'; - $_SERVER['REQUEST_URI'] = $path . '/'; - $_SERVER['REQUEST_METHOD'] = 'GET'; - $_SERVER['SCRIPT_NAME'] = $path . '/index.php'; - $_SERVER['SCRIPT_FILENAME'] = $path . '/index.php'; - $_SERVER['PHP_SELF'] = $path . '/index.php'; - $_SERVER['HTTP_USER_AGENT'] = 'Drupal command line'; + $this->setupBaseUrl(); // Install Drupal test site. $this->prepareEnvironment(); @@ -482,49 +457,15 @@ protected function setUp() { // Setup Mink. $session = $this->initMink(); - // In order to debug web tests you need to either set a cookie, have the - // Xdebug session in the URL or set an environment variable in case of CLI - // requests. If the developer listens to connection when running tests, by - // default the cookie is not forwarded to the client side, so you cannot - // debug the code running on the test site. In order to make debuggers work - // this bit of information is forwarded. Make sure that the debugger listens - // to at least three external connections. - $request = \Drupal::request(); - $cookie_params = $request->cookies; - if ($cookie_params->has('XDEBUG_SESSION')) { - $session->setCookie('XDEBUG_SESSION', $cookie_params->get('XDEBUG_SESSION')); - } - // For CLI requests, the information is stored in $_SERVER. - $server = $request->server; - if ($server->has('XDEBUG_CONFIG')) { - // $_SERVER['XDEBUG_CONFIG'] has the form "key1=value1 key2=value2 ...". - $pairs = explode(' ', $server->get('XDEBUG_CONFIG')); - foreach ($pairs as $pair) { - list($key, $value) = explode('=', $pair); - // Account for key-value pairs being separated by multiple spaces. - if (trim($key) == 'idekey') { - $session->setCookie('XDEBUG_SESSION', trim($value)); - } + $cookies = $this->extractCookiesFromRequest(\Drupal::request()); + foreach ($cookies as $cookie_name => $values) { + foreach ($values as $value) { + $session->setCookie($cookie_name, $value); } } - // Creates the directory to store browser output in if a file to write - // URLs to has been created by \Drupal\Tests\Listeners\HtmlOutputPrinter. - $browser_output_file = getenv('BROWSERTEST_OUTPUT_FILE'); - $this->htmlOutputEnabled = is_file($browser_output_file); - if ($this->htmlOutputEnabled) { - $this->htmlOutputFile = $browser_output_file; - $this->htmlOutputClassName = str_replace("\\", "_", get_called_class()); - $this->htmlOutputDirectory = DRUPAL_ROOT . '/sites/simpletest/browser_output'; - if (file_prepare_directory($this->htmlOutputDirectory, FILE_CREATE_DIRECTORY) && !file_exists($this->htmlOutputDirectory . '/.htaccess')) { - file_put_contents($this->htmlOutputDirectory . '/.htaccess', "\nExpiresActive Off\n\n"); - } - $this->htmlOutputCounterStorage = $this->htmlOutputDirectory . '/' . $this->htmlOutputClassName . '.counter'; - $this->htmlOutputTestId = str_replace('sites/simpletest/', '', $this->siteDirectory); - if (is_file($this->htmlOutputCounterStorage)) { - $this->htmlOutputCounter = max(1, (int) file_get_contents($this->htmlOutputCounterStorage)) + 1; - } - } + // Set up the browser test output file. + $this->initBrowserOutputFile(); } /** @@ -564,7 +505,7 @@ protected function cleanupEnvironment() { } // Delete test site directory. - file_unmanaged_delete_recursive($this->siteDirectory, array($this, 'filePreDeleteCallback')); + file_unmanaged_delete_recursive($this->siteDirectory, [$this, 'filePreDeleteCallback']); } /** @@ -643,7 +584,7 @@ protected function prepareRequest() { * @return string * An absolute URL stsring. */ - protected function buildUrl($path, array $options = array()) { + protected function buildUrl($path, array $options = []) { if ($path instanceof Url) { $url_options = $path->getOptions(); $options = $url_options + $options; @@ -691,7 +632,7 @@ protected function buildUrl($path, array $options = array()) { * @return string * The retrieved HTML string, also available as $this->getRawContent() */ - protected function drupalGet($path, array $options = array(), array $headers = array()) { + protected function drupalGet($path, array $options = [], array $headers = []) { $options['absolute'] = TRUE; $url = $this->buildUrl($path, $options); @@ -708,7 +649,16 @@ protected function drupalGet($path, array $options = array(), array $headers = a // Ensure that any changes to variables in the other thread are picked up. $this->refreshVariables(); - if ($this->htmlOutputEnabled) { + // Replace original page output with new output from redirected page(s). + if ($new = $this->checkForMetaRefresh()) { + $out = $new; + // We are finished with all meta refresh redirects, so reset the counter. + $this->metaRefreshCount = 0; + } + + // Log only for JavascriptTestBase tests because for Goutte we log with + // ::getResponseLogHandler. + if ($this->htmlOutputEnabled && !($this->getSession()->getDriver() instanceof GoutteDriver)) { $html_output = 'GET request to: ' . $url . '
Ending URL: ' . $this->getSession()->getCurrentUrl(); $html_output .= '
' . $out; @@ -782,16 +732,15 @@ protected function drupalLogin(AccountInterface $account) { $this->drupalLogout(); } - $this->drupalGet('user'); - $this->assertSession()->statusCodeEquals(200); - $this->submitForm(array( + $this->drupalGet('user/login'); + $this->submitForm([ 'name' => $account->getUsername(), 'pass' => $account->passRaw, - ), t('Log in')); + ], t('Log in')); // @see BrowserTestBase::drupalUserIsLoggedIn() $account->sessionId = $this->getSession()->getCookie($this->getSessionName()); - $this->assertTrue($this->drupalUserIsLoggedIn($account), SafeMarkup::format('User %name successfully logged in.', array('name' => $account->getUsername()))); + $this->assertTrue($this->drupalUserIsLoggedIn($account), new FormattableMarkup('User %name successfully logged in.', ['%name' => $account->getAccountName()])); $this->loggedInUser = $account; $this->container->get('current_user')->setAccount($account); @@ -807,8 +756,7 @@ protected function drupalLogout() { // idea being if you were properly logged out you should be seeing a login // screen. $assert_session = $this->assertSession(); - $this->drupalGet('user/logout', array('query' => array('destination' => 'user'))); - $assert_session->statusCodeEquals(200); + $this->drupalGet('user/logout', ['query' => ['destination' => 'user']]); $assert_session->fieldExists('name'); $assert_session->fieldExists('pass'); @@ -878,7 +826,16 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) { // Ensure that any changes to variables in the other thread are picked up. $this->refreshVariables(); - if ($this->htmlOutputEnabled) { + + // Check if there are any meta refresh redirects (like Batch API pages). + if ($this->checkForMetaRefresh()) { + // We are finished with all meta refresh redirects, so reset the counter. + $this->metaRefreshCount = 0; + } + + // Log only for JavascriptTestBase tests because for Goutte we log with + // ::getResponseLogHandler. + if ($this->htmlOutputEnabled && !($this->getSession()->getDriver() instanceof GoutteDriver)) { $out = $this->getSession()->getPage()->getContent(); $html_output = 'POST request to: ' . $action . '
Ending URL: ' . $this->getSession()->getCurrentUrl(); @@ -886,6 +843,7 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) { $html_output .= $this->getHtmlOutputHeaders(); $this->htmlOutput($html_output); } + } /** @@ -931,6 +889,8 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) { * $edit = array(); * $edit['name[]'] = array('value1', 'value2'); * @endcode + * @todo change $edit to disallow NULL as a value for Drupal 9. + * https://www.drupal.org/node/2802401 * @param string $submit * Value of the submit button whose click is to be emulated. For example, * t('Save'). The processing of the request depends on this value. For @@ -955,12 +915,20 @@ protected function submitForm(array $edit, $submit, $form_html_id = NULL) { * POST data. * @param array $options * Options to be forwarded to the url generator. + * + * @return string + * (deprecated) The response content after submit form. It is necessary for + * backwards compatibility and will be removed before Drupal 9.0. You should + * just use the webAssert object for your assertions. */ - protected function drupalPostForm($path, array $edit, $submit, array $options = array()) { + protected function drupalPostForm($path, $edit, $submit, array $options = []) { if (is_object($submit)) { // Cast MarkupInterface objects to string. $submit = (string) $submit; } + if ($edit === NULL) { + $edit = []; + } if (is_array($edit)) { $edit = $this->castSafeStrings($edit); } @@ -970,6 +938,8 @@ protected function drupalPostForm($path, array $edit, $submit, array $options = } $this->submitForm($edit, $submit); + + return $this->getSession()->getPage()->getContent(); } /** @@ -1001,503 +971,14 @@ protected function getOptions($select, Element $container = NULL) { * Installs Drupal into the Simpletest site. */ public function installDrupal() { - // Define information about the user 1 account. - $this->rootUser = new UserSession(array( - 'uid' => 1, - 'name' => 'admin', - 'mail' => 'admin@example.com', - 'passRaw' => $this->randomMachineName(), - )); - - // The child site derives its session name from the database prefix when - // running web tests. - $this->generateSessionName($this->databasePrefix); - - // Get parameters for install_drupal() before removing global variables. - $parameters = $this->installParameters(); - - // Prepare installer settings that are not install_drupal() parameters. - // Copy and prepare an actual settings.php, so as to resemble a regular - // installation. - // Not using File API; a potential error must trigger a PHP warning. - $directory = DRUPAL_ROOT . '/' . $this->siteDirectory; - copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php'); - - // The public file system path is created during installation. Additionally, - // during tests: - // - The temporary directory is set and created by install_base_system(). - // - The private file directory is created post install by this method. - // @see system_requirements() - // @see TestBase::prepareEnvironment() - // @see install_base_system() - $settings['settings']['file_public_path'] = (object) array( - 'value' => $this->publicFilesDirectory, - 'required' => TRUE, - ); - $settings['settings']['file_private_path'] = (object) [ - 'value' => $this->privateFilesDirectory, - 'required' => TRUE, - ]; - $this->writeSettings($settings); - // Allow for test-specific overrides. - $settings_testing_file = DRUPAL_ROOT . '/' . $this->originalSiteDirectory . '/settings.testing.php'; - if (file_exists($settings_testing_file)) { - // Copy the testing-specific settings.php overrides in place. - copy($settings_testing_file, $directory . '/settings.testing.php'); - // Add the name of the testing class to settings.php and include the - // testing specific overrides. - file_put_contents($directory . '/settings.php', "\n\$test_class = '" . get_class($this) . "';\n" . 'include DRUPAL_ROOT . \'/\' . $site_path . \'/settings.testing.php\';' . "\n", FILE_APPEND); - } - - $settings_services_file = DRUPAL_ROOT . '/' . $this->originalSiteDirectory . '/testing.services.yml'; - if (!file_exists($settings_services_file)) { - // Otherwise, use the default services as a starting point for overrides. - $settings_services_file = DRUPAL_ROOT . '/sites/default/default.services.yml'; - } - // Copy the testing-specific service overrides in place. - copy($settings_services_file, $directory . '/services.yml'); - if ($this->strictConfigSchema) { - // Add a listener to validate configuration schema on save. - $content = file_get_contents($directory . '/services.yml'); - $services = Yaml::decode($content); - $services['services']['simpletest.config_schema_checker'] = [ - 'class' => ConfigSchemaChecker::class, - 'arguments' => ['@config.typed', $this->getConfigSchemaExclusions()], - 'tags' => [['name' => 'event_subscriber']] - ]; - file_put_contents($directory . '/services.yml', Yaml::encode($services)); - } - - // Since Drupal is bootstrapped already, install_begin_request() will not - // bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to - // reload the newly written custom settings.php manually. - Settings::initialize(DRUPAL_ROOT, $directory, $this->classLoader); - - // Execute the non-interactive installer. - require_once DRUPAL_ROOT . '/core/includes/install.core.inc'; - install_drupal($parameters); - - // Import new settings.php written by the installer. - Settings::initialize(DRUPAL_ROOT, $directory, $this->classLoader); - foreach ($GLOBALS['config_directories'] as $type => $path) { - $this->configDirectories[$type] = $path; - } - - // After writing settings.php, the installer removes write permissions from - // the site directory. To allow drupal_generate_test_ua() to write a file - // containing the private key for drupal_valid_test_ua(), the site directory - // has to be writable. - // TestBase::restoreEnvironment() will delete the entire site directory. Not - // using File API; a potential error must trigger a PHP warning. - chmod($directory, 0777); - - // During tests, cacheable responses should get the debugging cacheability - // headers by default. - $this->setContainerParameter('http.response.debug_cacheability_headers', TRUE); - - $request = \Drupal::request(); - $this->kernel = DrupalKernel::createFromRequest($request, $this->classLoader, 'prod', TRUE); - $this->kernel->prepareLegacyRequest($request); - // Force the container to be built from scratch instead of loaded from the - // disk. This forces us to not accidentally load the parent site. - $container = $this->kernel->rebuildContainer(); - - $config = $container->get('config.factory'); - - // Manually create the private directory. - file_prepare_directory($this->privateFilesDirectory, FILE_CREATE_DIRECTORY); - - // Manually configure the test mail collector implementation to prevent - // tests from sending out emails and collect them in state instead. - // While this should be enforced via settings.php prior to installation, - // some tests expect to be able to test mail system implementations. - $config->getEditable('system.mail') - ->set('interface.default', 'test_mail_collector') - ->save(); - - // By default, verbosely display all errors and disable all production - // environment optimizations for all tests to avoid needless overhead and - // ensure a sane default experience for test authors. - // @see https://www.drupal.org/node/2259167 - $config->getEditable('system.logging') - ->set('error_level', 'verbose') - ->save(); - $config->getEditable('system.performance') - ->set('css.preprocess', FALSE) - ->set('js.preprocess', FALSE) - ->save(); - - // Collect modules to install. - $class = get_class($this); - $modules = array(); - while ($class) { - if (property_exists($class, 'modules')) { - $modules = array_merge($modules, $class::$modules); - } - $class = get_parent_class($class); - } - if ($modules) { - $modules = array_unique($modules); - $success = $container->get('module_installer')->install($modules, TRUE); - $this->assertTrue($success, SafeMarkup::format('Enabled modules: %modules', array('%modules' => implode(', ', $modules)))); - $this->rebuildContainer(); - } - - // Reset/rebuild all data structures after enabling the modules, primarily - // to synchronize all data structures and caches between the test runner and - // the child site. - // Affects e.g. StreamWrapperManagerInterface::getWrappers(). - // @see \Drupal\Core\DrupalKernel::bootCode() - // @todo Test-specific setUp() methods may set up further fixtures; find a - // way to execute this after setUp() is done, or to eliminate it entirely. - $this->resetAll(); - $this->kernel->prepareLegacyRequest($request); - } - - /** - * Returns the parameters that will be used when Simpletest installs Drupal. - * - * @see install_drupal() - * @see install_state_defaults() - */ - protected function installParameters() { - $connection_info = Database::getConnectionInfo(); - $driver = $connection_info['default']['driver']; - $connection_info['default']['prefix'] = $connection_info['default']['prefix']['default']; - unset($connection_info['default']['driver']); - unset($connection_info['default']['namespace']); - unset($connection_info['default']['pdo']); - unset($connection_info['default']['init_commands']); - $parameters = array( - 'interactive' => FALSE, - 'parameters' => array( - 'profile' => $this->profile, - 'langcode' => 'en', - ), - 'forms' => array( - 'install_settings_form' => array( - 'driver' => $driver, - $driver => $connection_info['default'], - ), - 'install_configure_form' => array( - 'site_name' => 'Drupal', - 'site_mail' => 'simpletest@example.com', - 'account' => array( - 'name' => $this->rootUser->name, - 'mail' => $this->rootUser->getEmail(), - 'pass' => array( - 'pass1' => $this->rootUser->passRaw, - 'pass2' => $this->rootUser->passRaw, - ), - ), - // form_type_checkboxes_value() requires NULL instead of FALSE values - // for programmatic form submissions to disable a checkbox. - 'update_status_module' => array( - 1 => NULL, - 2 => NULL, - ), - ), - ), - ); - return $parameters; - } - - /** - * Generates a database prefix for running tests. - * - * The database prefix is used by prepareEnvironment() to setup a public files - * directory for the test to be run, which also contains the PHP error log, - * which is written to in case of a fatal error. Since that directory is based - * on the database prefix, all tests (even unit tests) need to have one, in - * order to access and read the error log. - * - * The generated database table prefix is used for the Drupal installation - * being performed for the test. It is also used by the cookie value of - * SIMPLETEST_USER_AGENT by the Mink controlled browser. During early Drupal - * bootstrap, the cookie is parsed, and if it matches, all database queries - * use the database table prefix that has been generated here. - * - * @see drupal_valid_test_ua() - * @see BrowserTestBase::prepareEnvironment() - */ - private function prepareDatabasePrefix() { - $test_db = new TestDatabase(); - $this->siteDirectory = $test_db->getTestSitePath(); - $this->databasePrefix = $test_db->getDatabasePrefix(); - } - - /** - * Changes the database connection to the prefixed one. - * - * @see BrowserTestBase::prepareEnvironment() - */ - private function changeDatabasePrefix() { - if (empty($this->databasePrefix)) { - $this->prepareDatabasePrefix(); - } - - // If the test is run with argument dburl then use it. - $db_url = getenv('SIMPLETEST_DB'); - if (!empty($db_url)) { - $database = Database::convertDbUrlToConnectionInfo($db_url, DRUPAL_ROOT); - Database::addConnectionInfo('default', 'default', $database); - } - - // Clone the current connection and replace the current prefix. - $connection_info = Database::getConnectionInfo('default'); - if (is_null($connection_info)) { - throw new \InvalidArgumentException('There is no database connection so no tests can be run. You must provide a SIMPLETEST_DB environment variable to run PHPUnit based functional tests outside of run-tests.sh.'); - } - else { - Database::renameConnection('default', 'simpletest_original_default'); - foreach ($connection_info as $target => $value) { - // Replace the full table prefix definition to ensure that no table - // prefixes of the test runner leak into the test. - $connection_info[$target]['prefix'] = array( - 'default' => $value['prefix']['default'] . $this->databasePrefix, - ); - } - Database::addConnectionInfo('default', 'default', $connection_info['default']); - } - } - - /** - * Prepares the current environment for running the test. - * - * Also sets up new resources for the testing environment, such as the public - * filesystem and configuration directories. - * - * This method is private as it must only be called once by - * BrowserTestBase::setUp() (multiple invocations for the same test would have - * unpredictable consequences) and it must not be callable or overridable by - * test classes. - */ - protected function prepareEnvironment() { - // Bootstrap Drupal so we can use Drupal's built in functions. - $this->classLoader = require __DIR__ . '/../../../../autoload.php'; - $request = Request::createFromGlobals(); - $kernel = TestRunnerKernel::createFromRequest($request, $this->classLoader); - // TestRunnerKernel expects the working directory to be DRUPAL_ROOT. - chdir(DRUPAL_ROOT); - $kernel->prepareLegacyRequest($request); - $this->prepareDatabasePrefix(); - - $this->originalSiteDirectory = $kernel->findSitePath($request); - - // Create test directory ahead of installation so fatal errors and debug - // information can be logged during installation process. - file_prepare_directory($this->siteDirectory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); - - // Prepare filesystem directory paths. - $this->publicFilesDirectory = $this->siteDirectory . '/files'; - $this->privateFilesDirectory = $this->siteDirectory . '/private'; - $this->tempFilesDirectory = $this->siteDirectory . '/temp'; - $this->translationFilesDirectory = $this->siteDirectory . '/translations'; - - // Ensure the configImporter is refreshed for each test. - $this->configImporter = NULL; - - // Unregister all custom stream wrappers of the parent site. - $wrappers = \Drupal::service('stream_wrapper_manager')->getWrappers(StreamWrapperInterface::ALL); - foreach ($wrappers as $scheme => $info) { - stream_wrapper_unregister($scheme); - } - - // Reset statics. - drupal_static_reset(); - - // Ensure there is no service container. - $this->container = NULL; - \Drupal::unsetContainer(); - - // Unset globals. - unset($GLOBALS['config_directories']); - unset($GLOBALS['config']); - unset($GLOBALS['conf']); - - // Log fatal errors. - ini_set('log_errors', 1); - ini_set('error_log', DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log'); - - // Change the database prefix. - $this->changeDatabasePrefix(); - - // After preparing the environment and changing the database prefix, we are - // in a valid test environment. - drupal_valid_test_ua($this->databasePrefix); - - // Reset settings. - new Settings(array( - // For performance, simply use the database prefix as hash salt. - 'hash_salt' => $this->databasePrefix, - )); - - drupal_set_time_limit($this->timeLimit); - - // Save and clean the shutdown callbacks array because it is static cached - // and will be changed by the test run. Otherwise it will contain callbacks - // from both environments and the testing environment will try to call the - // handlers defined by the original one. - $callbacks = &drupal_register_shutdown_function(); - $this->originalShutdownCallbacks = $callbacks; - $callbacks = []; - } - - /** - * Returns the database connection to the site running Simpletest. - * - * @return \Drupal\Core\Database\Connection - * The database connection to use for inserting assertions. - */ - public static function getDatabaseConnection() { - return TestDatabase::getConnection(); - } - - /** - * Rewrites the settings.php file of the test site. - * - * @param array $settings - * An array of settings to write out, in the format expected by - * drupal_rewrite_settings(). - * - * @see drupal_rewrite_settings() - */ - protected function writeSettings(array $settings) { - include_once DRUPAL_ROOT . '/core/includes/install.inc'; - $filename = $this->siteDirectory . '/settings.php'; - - // system_requirements() removes write permissions from settings.php - // whenever it is invoked. - // Not using File API; a potential error must trigger a PHP warning. - chmod($filename, 0666); - drupal_rewrite_settings($settings, $filename); - } - - /** - * Rebuilds \Drupal::getContainer(). - * - * Use this to build a new kernel and service container. For example, when the - * list of enabled modules is changed via the Mink controlled browser, in - * which case the test process still contains an old kernel and service - * container with an old module list. - * - * @see BrowserTestBase::prepareEnvironment() - * @see BrowserTestBase::restoreEnvironment() - * - * @todo Fix https://www.drupal.org/node/2021959 so that module enable/disable - * changes are immediately reflected in \Drupal::getContainer(). Until then, - * tests can invoke this workaround when requiring services from newly - * enabled modules to be immediately available in the same request. - */ - protected function rebuildContainer() { - // Rebuild the kernel and bring it back to a fully bootstrapped state. - $this->container = $this->kernel->rebuildContainer(); - - // Make sure the url generator has a request object, otherwise calls to - // $this->drupalGet() will fail. - $this->prepareRequestForGenerator(); - } - - /** - * Creates a mock request and sets it on the generator. - * - * This is used to manipulate how the generator generates paths during tests. - * It also ensures that calls to $this->drupalGet() will work when running - * from run-tests.sh because the url generator no longer looks at the global - * variables that are set there but relies on getting this information from a - * request object. - * - * @param bool $clean_urls - * Whether to mock the request using clean urls. - * @param array $override_server_vars - * An array of server variables to override. - * - * @return Request - * The mocked request object. - */ - protected function prepareRequestForGenerator($clean_urls = TRUE, $override_server_vars = array()) { - $request = Request::createFromGlobals(); - $server = $request->server->all(); - if (basename($server['SCRIPT_FILENAME']) != basename($server['SCRIPT_NAME'])) { - // We need this for when the test is executed by run-tests.sh. - // @todo Remove this once run-tests.sh has been converted to use a Request - // object. - $cwd = getcwd(); - $server['SCRIPT_FILENAME'] = $cwd . '/' . basename($server['SCRIPT_NAME']); - $base_path = rtrim($server['REQUEST_URI'], '/'); - } - else { - $base_path = $request->getBasePath(); - } - if ($clean_urls) { - $request_path = $base_path ? $base_path . '/user' : 'user'; - } - else { - $request_path = $base_path ? $base_path . '/index.php/user' : '/index.php/user'; - } - $server = array_merge($server, $override_server_vars); - - $request = Request::create($request_path, 'GET', array(), array(), array(), $server); - // Ensure the request time is REQUEST_TIME to ensure that API calls - // in the test use the right timestamp. - $request->server->set('REQUEST_TIME', REQUEST_TIME); - $this->container->get('request_stack')->push($request); - - // The request context is normally set by the router_listener from within - // its KernelEvents::REQUEST listener. In the Simpletest parent site this - // event is not fired, therefore it is necessary to updated the request - // context manually here. - $this->container->get('router.request_context')->fromRequest($request); - - return $request; - } - - /** - * Resets all data structures after having enabled new modules. - * - * This method is called by \Drupal\simpletest\BrowserTestBase::setUp() after - * enabling the requested modules. It must be called again when additional - * modules are enabled later. - */ - protected function resetAll() { - // Clear all database and static caches and rebuild data structures. - drupal_flush_all_caches(); - $this->container = \Drupal::getContainer(); - - // Reset static variables and reload permissions. - $this->refreshVariables(); - } - - /** - * Refreshes in-memory configuration and state information. - * - * Useful after a page request is made that changes configuration or state in - * a different thread. - * - * In other words calling a settings page with $this->submitForm() with a - * changed value would update configuration to reflect that change, but in the - * thread that made the call (thread running the test) the changed values - * would not be picked up. - * - * This method clears the cache and loads a fresh copy. - */ - protected function refreshVariables() { - // Clear the tag cache. - $this->container->get('cache_tags.invalidator')->resetChecksums(); - // @todo Replace drupal_static() usage within classes and provide a - // proper interface for invoking reset() on a cache backend: - // https://www.drupal.org/node/2311945. - drupal_static_reset('Drupal\Core\Cache\CacheBackendInterface::tagCache'); - drupal_static_reset('Drupal\Core\Cache\DatabaseBackend::deletedTags'); - drupal_static_reset('Drupal\Core\Cache\DatabaseBackend::invalidatedTags'); - foreach (Cache::getBins() as $backend) { - if (is_callable(array($backend, 'reset'))) { - $backend->reset(); - } - } - - $this->container->get('config.factory')->reset(); - $this->container->get('state')->resetCache(); + $this->initUserSession(); + $this->prepareSettings(); + $this->doInstall(); + $this->initSettings(); + $container = $this->initKernel(\Drupal::request()); + $this->initConfig($container); + $this->installModulesFromClassProperty($container); + $this->rebuildAll(); } /** @@ -1576,15 +1057,28 @@ protected function htmlOutput($message) { * HTML output headers. */ protected function getHtmlOutputHeaders() { - $headers = array_map(function($headers) { - if (is_array($headers)) { - return implode(';', array_map('trim', $headers)); + return $this->formatHtmlOutputHeaders($this->getSession()->getResponseHeaders()); + } + + /** + * Formats HTTP headers as string for HTML output logging. + * + * @param array[] $headers + * Headers that should be formatted. + * + * @return string + * The formatted HTML string. + */ + protected function formatHtmlOutputHeaders(array $headers) { + $flattened_headers = array_map(function ($header) { + if (is_array($header)) { + return implode(';', array_map('trim', $header)); } else { - return $headers; + return $header; } - }, $this->getSession()->getResponseHeaders()); - return '
Headers:
' . Html::escape(var_export($headers, TRUE)) . '
'; + }, $headers); + return '
Headers:
' . Html::escape(var_export($flattened_headers, TRUE)) . '
'; } /** @@ -1680,6 +1174,19 @@ protected function config($name) { return $this->container->get('config.factory')->getEditable($name); } + /** + * Returns all response headers. + * + * @return array + * The HTTP headers values. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use $this->getSession()->getResponseHeaders() instead. + */ + protected function drupalGetHeaders() { + return $this->getSession()->getResponseHeaders(); + } + /** * Gets the value of an HTTP response header. * @@ -1734,43 +1241,56 @@ public static function assertEquals($expected, $actual, $message = '', $delta = } /** - * Changes parameters in the services.yml file. + * Retrieves the current calling line in the class under test. * - * @param string $name - * The name of the parameter. - * @param mixed $value - * The value of the parameter. - */ - protected function setContainerParameter($name, $value) { - $filename = $this->siteDirectory . '/services.yml'; - chmod($filename, 0666); - - $services = Yaml::decode(file_get_contents($filename)); - $services['parameters'][$name] = $value; - file_put_contents($filename, Yaml::encode($services)); + * @return array + * An associative array with keys 'file', 'line' and 'function'. + */ + protected function getTestMethodCaller() { + $backtrace = debug_backtrace(); + // Find the test class that has the test method. + while ($caller = Error::getLastCaller($backtrace)) { + if (isset($caller['class']) && $caller['class'] === get_class($this)) { + break; + } + // If the test method is implemented by a test class's parent then the + // class name of $this will not be part of the backtrace. + // In that case we process the backtrace until the caller is not a + // subclass of $this and return the previous caller. + if (isset($last_caller) && (!isset($caller['class']) || !is_subclass_of($this, $caller['class']))) { + // Return the last caller since that has to be the test class. + $caller = $last_caller; + break; + } + // Otherwise we have not reached our test class yet: save the last caller + // and remove an element from to backtrace to process the next call. + $last_caller = $caller; + array_shift($backtrace); + } - // Ensure that the cache is deleted for the yaml file loader. - $file_cache = FileCacheFactory::get('container_yaml_loader'); - $file_cache->delete($filename); + return $caller; } /** - * Gets the config schema exclusions for this test. + * Checks for meta refresh tag and if found call drupalGet() recursively. + * + * This function looks for the http-equiv attribute to be set to "Refresh" and + * is case-insensitive. * - * @return string[] - * An array of config object names that are excluded from schema checking. + * @return string|false + * Either the new page content or FALSE. */ - protected function getConfigSchemaExclusions() { - $class = get_class($this); - $exceptions = []; - while ($class) { - if (property_exists($class, 'configSchemaCheckerExclusions')) { - $exceptions = array_merge($exceptions, $class::$configSchemaCheckerExclusions); + protected function checkForMetaRefresh() { + $refresh = $this->cssSelect('meta[http-equiv="Refresh"], meta[http-equiv="refresh"]'); + if (!empty($refresh) && (!isset($this->maximumMetaRefreshCount) || $this->metaRefreshCount < $this->maximumMetaRefreshCount)) { + // Parse the content attribute of the meta tag for the format: + // "[delay]: URL=[page_to_redirect_to]". + if (preg_match('/\d+;\s*URL=(?.*)/i', $refresh[0]->getAttribute('content'), $match)) { + $this->metaRefreshCount++; + return $this->drupalGet($this->getAbsoluteUrl(Html::decodeEntities($match['url']))); } - $class = get_parent_class($class); } - // Filter out any duplicates. - return array_unique($exceptions); + return FALSE; } } diff --git a/core/tests/Drupal/Tests/Component/Annotation/Plugin/Discovery/AnnotationBridgeDecoratorTest.php b/core/tests/Drupal/Tests/Component/Annotation/Plugin/Discovery/AnnotationBridgeDecoratorTest.php new file mode 100644 index 00000000..62d3c840 --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Annotation/Plugin/Discovery/AnnotationBridgeDecoratorTest.php @@ -0,0 +1,61 @@ + 'foo']); + $definitions['array'] = ['id' => 'bar']; + $discovery = $this->prophesize(DiscoveryInterface::class); + $discovery->getDefinitions()->willReturn($definitions); + + $decorator = new AnnotationBridgeDecorator($discovery->reveal(), TestAnnotation::class); + + $expected = [ + 'object' => new ObjectDefinition(['id' => 'foo']), + 'array' => new ObjectDefinition(['id' => 'bar']), + ]; + $this->assertEquals($expected, $decorator->getDefinitions()); + } + +} + +class TestAnnotation extends Plugin { + + /** + * {@inheritdoc} + */ + public function get() { + return new ObjectDefinition($this->definition); + } + +} +class ObjectDefinition extends PluginDefinition { + + /** + * ObjectDefinition constructor. + * + * @param array $definition + */ + public function __construct(array $definition) { + foreach ($definition as $property => $value) { + $this->{$property} = $value; + } + } + +} diff --git a/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php b/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php index 1299cd64..f4182441 100644 --- a/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php +++ b/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php @@ -7,14 +7,14 @@ namespace Drupal\Tests\Component\Assertion; -use PHPUnit_Framework_TestCase; +use PHPUnit\Framework\TestCase; use Drupal\Component\Assertion\Inspector; /** * @coversDefaultClass \Drupal\Component\Assertion\Inspector * @group Assertion */ -class InspectorTest extends PHPUnit_Framework_TestCase { +class InspectorTest extends TestCase { /** * Tests asserting argument is an array or traversable object. @@ -157,7 +157,7 @@ public function testAllCallable() { 'strchr', [$this, 'callMe'], [__CLASS__, 'callMeStatic'], - function() { + function () { return TRUE; } ])); @@ -166,7 +166,7 @@ function() { 'strchr', [$this, 'callMe'], [__CLASS__, 'callMeStatic'], - function() { + function () { return TRUE; }, "I'm not callable" diff --git a/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php b/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php index 9efbf4ec..3aaf9d11 100644 --- a/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php +++ b/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php @@ -3,14 +3,14 @@ namespace Drupal\Tests\Component\Bridge; use Drupal\Component\Bridge\ZfExtensionManagerSfContainer; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; /** * @coversDefaultClass \Drupal\Component\Bridge\ZfExtensionManagerSfContainer * @group Bridge */ -class ZfExtensionManagerSfContainerTest extends UnitTestCase { +class ZfExtensionManagerSfContainerTest extends TestCase { /** * @covers ::setContainer @@ -80,41 +80,41 @@ public function testCanonicalizeName($name, $canonical_name) { * array('-' => '', '_' => '', ' ' => '', '\\' => '', '/' => '') */ public function canonicalizeNameProvider() { - return array( - array( + return [ + [ 'foobar', 'foobar', - ), - array( + ], + [ 'foo-bar', 'foobar', - ), - array( + ], + [ 'foo_bar', 'foobar', - ), - array( + ], + [ 'foo bar', 'foobar', - ), - array( + ], + [ 'foo\\bar', 'foobar', - ), - array( + ], + [ 'foo/bar', 'foobar', - ), + ], // There is also a strtolower in canonicalizeName. - array( + [ 'Foo/bAr', 'foobar', - ), - array( + ], + [ 'foo/-_\\ bar', 'foobar', - ), - ); + ], + ]; } } diff --git a/core/tests/Drupal/Tests/Component/ClassFinder/ClassFinderTest.php b/core/tests/Drupal/Tests/Component/ClassFinder/ClassFinderTest.php index cf1a84b1..9e66b6b7 100644 --- a/core/tests/Drupal/Tests/Component/ClassFinder/ClassFinderTest.php +++ b/core/tests/Drupal/Tests/Component/ClassFinder/ClassFinderTest.php @@ -4,13 +4,13 @@ use Composer\Autoload\ClassLoader; use Drupal\Component\ClassFinder\ClassFinder; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\ClassFinder\ClassFinder * @group ClassFinder */ -class ClassFinderTest extends UnitTestCase { +class ClassFinderTest extends TestCase { /** * @covers ::findFile @@ -20,7 +20,7 @@ public function testFindFile() { // The full path is returned therefore only tests with // assertStringEndsWith() so the test is portable. - $this->assertStringEndsWith('core/tests/Drupal/Tests/UnitTestCase.php', $finder->findFile(UnitTestCase::class)); + $this->assertStringEndsWith('core/tests/Drupal/Tests/Component/ClassFinder/ClassFinderTest.php', $finder->findFile(ClassFinderTest::class)); $class = 'Not\\A\\Class'; $this->assertNull($finder->findFile($class)); @@ -30,7 +30,7 @@ public function testFindFile() { $loader->register(); $this->assertEquals(__FILE__, $finder->findFile($class)); // This shouldn't prevent us from finding the original file. - $this->assertStringEndsWith('core/tests/Drupal/Tests/UnitTestCase.php', $finder->findFile(UnitTestCase::class)); + $this->assertStringEndsWith('core/tests/Drupal/Tests/Component/ClassFinder/ClassFinderTest.php', $finder->findFile(ClassFinderTest::class)); // Clean up the additional autoloader after the test. $loader->unregister(); diff --git a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php index b8be130c..21228d6b 100644 --- a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php +++ b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php @@ -2,14 +2,14 @@ namespace Drupal\Tests\Component\Datetime; -use Drupal\Tests\UnitTestCase; use Drupal\Component\Datetime\DateTimePlus; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Datetime\DateTimePlus * @group Datetime */ -class DateTimePlusTest extends UnitTestCase { +class DateTimePlusTest extends TestCase { /** * Test creating dates from string and array input. @@ -98,11 +98,13 @@ public function testInvalidDateDiff($input1, $input2, $absolute) { * Input argument for DateTimePlus. * @param string $timezone * Timezone argument for DateTimePlus. + * @param string $class + * The Exception subclass to expect to be thrown. * * @dataProvider providerTestInvalidDateArrays - * @expectedException \Exception */ - public function testInvalidDateArrays($input, $timezone) { + public function testInvalidDateArrays($input, $timezone, $class) { + $this->setExpectedException($class); $this->assertInstanceOf( '\Drupal\Component\DateTimePlus', DateTimePlus::createFromArray($input, $timezone) @@ -234,11 +236,13 @@ public function testDateFormat($input, $timezone, $format, $format_date, $expect * Format argument for DateTimePlus. * @param string $message * Message to print if no errors are thrown by the invalid dates. + * @param string $class + * The Exception subclass to expect to be thrown. * * @dataProvider providerTestInvalidDates - * @expectedException \Exception */ - public function testInvalidDates($input, $timezone, $format, $message) { + public function testInvalidDates($input, $timezone, $format, $message, $class) { + $this->setExpectedException($class); DateTimePlus::createFromFormat($format, $input, $timezone); } @@ -289,21 +293,34 @@ public function testDateTimezoneWithDateTimeObject() { * @see DateTimePlusTest::testDates() */ public function providerTestDates() { - return array( + $dates = [ // String input. // Create date object from datetime string. - array('2009-03-07 10:30', 'America/Chicago', '2009-03-07T10:30:00-06:00'), + ['2009-03-07 10:30', 'America/Chicago', '2009-03-07T10:30:00-06:00'], // Same during daylight savings time. - array('2009-06-07 10:30', 'America/Chicago', '2009-06-07T10:30:00-05:00'), + ['2009-06-07 10:30', 'America/Chicago', '2009-06-07T10:30:00-05:00'], // Create date object from date string. - array('2009-03-07', 'America/Chicago', '2009-03-07T00:00:00-06:00'), + ['2009-03-07', 'America/Chicago', '2009-03-07T00:00:00-06:00'], // Same during daylight savings time. - array('2009-06-07', 'America/Chicago', '2009-06-07T00:00:00-05:00'), + ['2009-06-07', 'America/Chicago', '2009-06-07T00:00:00-05:00'], // Create date object from date string. - array('2009-03-07 10:30', 'Australia/Canberra', '2009-03-07T10:30:00+11:00'), + ['2009-03-07 10:30', 'Australia/Canberra', '2009-03-07T10:30:00+11:00'], // Same during daylight savings time. - array('2009-06-07 10:30', 'Australia/Canberra', '2009-06-07T10:30:00+10:00'), - ); + ['2009-06-07 10:30', 'Australia/Canberra', '2009-06-07T10:30:00+10:00'], + ]; + + // On 32-bit systems, timestamps are limited to 1901-2038. + if (PHP_INT_SIZE > 4) { + // Create a date object in the distant past. + // @see https://www.drupal.org/node/2795489#comment-12127088 + if (version_compare(PHP_VERSION, '5.6.15', '>=')) { + $dates[] = ['1809-02-12 10:30', 'America/Chicago', '1809-02-12T10:30:00-06:00']; + } + // Create a date object in the far future. + $dates[] = ['2345-01-02 02:04', 'UTC', '2345-01-02T02:04:00+00:00']; + } + + return $dates; } /** @@ -316,17 +333,30 @@ public function providerTestDates() { * @see DateTimePlusTest::testDates() */ public function providerTestDateArrays() { - return array( + $dates = [ // Array input. // Create date object from date array, date only. - array(array('year' => 2010, 'month' => 2, 'day' => 28), 'America/Chicago', '2010-02-28T00:00:00-06:00'), + [['year' => 2010, 'month' => 2, 'day' => 28], 'America/Chicago', '2010-02-28T00:00:00-06:00'], // Create date object from date array with hour. - array(array('year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10), 'America/Chicago', '2010-02-28T10:00:00-06:00'), + [['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10], 'America/Chicago', '2010-02-28T10:00:00-06:00'], // Create date object from date array, date only. - array(array('year' => 2010, 'month' => 2, 'day' => 28), 'Europe/Berlin', '2010-02-28T00:00:00+01:00'), + [['year' => 2010, 'month' => 2, 'day' => 28], 'Europe/Berlin', '2010-02-28T00:00:00+01:00'], // Create date object from date array with hour. - array(array('year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10), 'Europe/Berlin', '2010-02-28T10:00:00+01:00'), - ); + [['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10], 'Europe/Berlin', '2010-02-28T10:00:00+01:00'], + ]; + + // On 32-bit systems, timestamps are limited to 1901-2038. + if (PHP_INT_SIZE > 4) { + // Create a date object in the distant past. + // @see https://www.drupal.org/node/2795489#comment-12127088 + if (version_compare(PHP_VERSION, '5.6.15', '>=')) { + $dates[] = [['year' => 1809, 'month' => 2, 'day' => 12], 'America/Chicago', '1809-02-12T00:00:00-06:00']; + } + // Create a date object in the far future. + $dates[] = [['year' => 2345, 'month' => 1, 'day' => 2], 'UTC', '2345-01-02T00:00:00+00:00']; + } + + return $dates; } /** @@ -343,16 +373,16 @@ public function providerTestDateArrays() { * @see testDateFormats() */ public function providerTestDateFormat() { - return array( + return [ // Create a year-only date. - array('2009', NULL, 'Y', 'Y', '2009'), + ['2009', NULL, 'Y', 'Y', '2009'], // Create a month and year-only date. - array('2009-10', NULL, 'Y-m', 'Y-m', '2009-10'), + ['2009-10', NULL, 'Y-m', 'Y-m', '2009-10'], // Create a time-only date. - array('T10:30:00', NULL, '\TH:i:s', 'H:i:s', '10:30:00'), + ['T10:30:00', NULL, '\TH:i:s', 'H:i:s', '10:30:00'], // Create a time-only date. - array('10:30:00', NULL, 'H:i:s', 'H:i:s', '10:30:00'), - ); + ['10:30:00', NULL, 'H:i:s', 'H:i:s', '10:30:00'], + ]; } /** @@ -368,20 +398,20 @@ public function providerTestDateFormat() { * @see testInvalidDates */ public function providerTestInvalidDates() { - return array( + return [ // Test for invalid month names when we are using a short version // of the month. - array('23 abc 2012', NULL, 'd M Y', "23 abc 2012 contains an invalid month name and did not produce errors."), + ['23 abc 2012', NULL, 'd M Y', "23 abc 2012 contains an invalid month name and did not produce errors.", \InvalidArgumentException::class], // Test for invalid hour. - array('0000-00-00T45:30:00', NULL, 'Y-m-d\TH:i:s', "0000-00-00T45:30:00 contains an invalid hour and did not produce errors."), + ['0000-00-00T45:30:00', NULL, 'Y-m-d\TH:i:s', "0000-00-00T45:30:00 contains an invalid hour and did not produce errors.", \UnexpectedValueException::class], // Test for invalid day. - array('0000-00-99T05:30:00', NULL, 'Y-m-d\TH:i:s', "0000-00-99T05:30:00 contains an invalid day and did not produce errors."), + ['0000-00-99T05:30:00', NULL, 'Y-m-d\TH:i:s', "0000-00-99T05:30:00 contains an invalid day and did not produce errors.", \UnexpectedValueException::class], // Test for invalid month. - array('0000-75-00T15:30:00', NULL, 'Y-m-d\TH:i:s', "0000-75-00T15:30:00 contains an invalid month and did not produce errors."), + ['0000-75-00T15:30:00', NULL, 'Y-m-d\TH:i:s', "0000-75-00T15:30:00 contains an invalid month and did not produce errors.", \UnexpectedValueException::class], // Test for invalid year. - array('11-08-01T15:30:00', NULL, 'Y-m-d\TH:i:s', "11-08-01T15:30:00 contains an invalid year and did not produce errors."), + ['11-08-01T15:30:00', NULL, 'Y-m-d\TH:i:s', "11-08-01T15:30:00 contains an invalid year and did not produce errors.", \UnexpectedValueException::class], - ); + ]; } /** @@ -395,20 +425,20 @@ public function providerTestInvalidDates() { * @see testInvalidDateArrays */ public function providerTestInvalidDateArrays() { - return array( + return [ // One year larger than the documented upper limit of checkdate(). - array(array('year' => 32768, 'month' => 1, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0), 'America/Chicago'), + [['year' => 32768, 'month' => 1, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], // One year smaller than the documented lower limit of checkdate(). - array(array('year' => 0, 'month' => 1, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0), 'America/Chicago'), + [['year' => 0, 'month' => 1, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], // Test for invalid month from date array. - array(array('year' => 2010, 'month' => 27, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0), 'America/Chicago'), + [['year' => 2010, 'month' => 27, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], // Test for invalid hour from date array. - array(array('year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 80, 'minute' => 0, 'second' => 0), 'America/Chicago'), + [['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 80, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], // Test for invalid minute from date array. - array(array('year' => 2010, 'month' => 7, 'day' => 8, 'hour' => 8, 'minute' => 88, 'second' => 0), 'America/Chicago'), + [['year' => 2010, 'month' => 7, 'day' => 8, 'hour' => 8, 'minute' => 88, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], // Regression test for https://www.drupal.org/node/2084455. - array(array('hour' => 59, 'minute' => 1, 'second' => 1), 'America/Chicago'), - ); + [['hour' => 59, 'minute' => 1, 'second' => 1], 'America/Chicago', \InvalidArgumentException::class], + ]; } /** @@ -430,17 +460,17 @@ public function providerTestDateTimezone() { // Detect the system timezone. $system_timezone = date_default_timezone_get(); - return array( + return [ // Create a date object with an unspecified timezone, which should // end up using the system timezone. - array($date_string, NULL, $system_timezone, 'DateTimePlus uses the system timezone when there is no site timezone.'), + [$date_string, NULL, $system_timezone, 'DateTimePlus uses the system timezone when there is no site timezone.'], // Create a date object with a specified timezone name. - array($date_string, 'America/Yellowknife', 'America/Yellowknife', 'DateTimePlus uses the specified timezone if provided.'), + [$date_string, 'America/Yellowknife', 'America/Yellowknife', 'DateTimePlus uses the specified timezone if provided.'], // Create a date object with a timezone object. - array($date_string, new \DateTimeZone('Australia/Canberra'), 'Australia/Canberra', 'DateTimePlus uses the specified timezone if provided.'), + [$date_string, new \DateTimeZone('Australia/Canberra'), 'Australia/Canberra', 'DateTimePlus uses the specified timezone if provided.'], // Create a date object with another date object. - array(new DateTimePlus('now', 'Pacific/Midway'), NULL, 'Pacific/Midway', 'DateTimePlus uses the specified timezone if provided.'), - ); + [new DateTimePlus('now', 'Pacific/Midway'), NULL, 'Pacific/Midway', 'DateTimePlus uses the specified timezone if provided.'], + ]; } /** @@ -453,46 +483,46 @@ public function providerTestDateTimezone() { * @see testTimestamp() */ public function providerTestTimestamp() { - return array( + return [ // Create date object from a unix timestamp and display it in // local time. - array( + [ 'input' => 0, - 'initial' => array( + 'initial' => [ 'timezone' => 'UTC', 'format' => 'c', 'expected_date' => '1970-01-01T00:00:00+00:00', 'expected_timezone' => 'UTC', 'expected_offset' => 0, - ), - 'transform' => array( + ], + 'transform' => [ 'timezone' => 'America/Los_Angeles', 'format' => 'c', 'expected_date' => '1969-12-31T16:00:00-08:00', 'expected_timezone' => 'America/Los_Angeles', 'expected_offset' => '-28800', - ), - ), + ], + ], // Create a date using the timestamp of zero, then display its // value both in UTC and the local timezone. - array( + [ 'input' => 0, - 'initial' => array( + 'initial' => [ 'timezone' => 'America/Los_Angeles', 'format' => 'c', 'expected_date' => '1969-12-31T16:00:00-08:00', 'expected_timezone' => 'America/Los_Angeles', 'expected_offset' => '-28800', - ), - 'transform' => array( + ], + 'transform' => [ 'timezone' => 'UTC', 'format' => 'c', 'expected_date' => '1970-01-01T00:00:00+00:00', 'expected_timezone' => 'UTC', 'expected_offset' => 0, - ), - ), - ); + ], + ], + ]; } /** @@ -505,63 +535,63 @@ public function providerTestTimestamp() { * @see testDateTimestamp() */ public function providerTestDateTimestamp() { - return array( + return [ // Create date object from datetime string in UTC, and convert // it to a local date. - array( + [ 'input' => '1970-01-01 00:00:00', - 'initial' => array( + 'initial' => [ 'timezone' => 'UTC', 'format' => 'c', 'expected_date' => '1970-01-01T00:00:00+00:00', 'expected_timezone' => 'UTC', 'expected_offset' => 0, - ), - 'transform' => array( + ], + 'transform' => [ 'timezone' => 'America/Los_Angeles', 'format' => 'c', 'expected_date' => '1969-12-31T16:00:00-08:00', 'expected_timezone' => 'America/Los_Angeles', 'expected_offset' => '-28800', - ), - ), + ], + ], // Convert the local time to UTC using string input. - array( + [ 'input' => '1969-12-31 16:00:00', - 'initial' => array( + 'initial' => [ 'timezone' => 'America/Los_Angeles', 'format' => 'c', 'expected_date' => '1969-12-31T16:00:00-08:00', 'expected_timezone' => 'America/Los_Angeles', 'expected_offset' => '-28800', - ), - 'transform' => array( + ], + 'transform' => [ 'timezone' => 'UTC', 'format' => 'c', 'expected_date' => '1970-01-01T00:00:00+00:00', 'expected_timezone' => 'UTC', 'expected_offset' => 0, - ), - ), + ], + ], // Convert the local time to UTC using string input. - array( + [ 'input' => '1969-12-31 16:00:00', - 'initial' => array( + 'initial' => [ 'timezone' => 'Europe/Warsaw', 'format' => 'c', 'expected_date' => '1969-12-31T16:00:00+01:00', 'expected_timezone' => 'Europe/Warsaw', 'expected_offset' => '+3600', - ), - 'transform' => array( + ], + 'transform' => [ 'timezone' => 'UTC', 'format' => 'c', 'expected_date' => '1969-12-31T15:00:00+00:00', 'expected_timezone' => 'UTC', 'expected_offset' => 0, - ), - ), - ); + ], + ], + ]; } /** @@ -586,60 +616,60 @@ public function providerTestDateDiff() { $negative_1_hour = new \DateInterval('PT1H'); $negative_1_hour->invert = 1; - return array( + return [ // There should be a 19 hour time interval between // new years in Sydney and new years in LA in year 2000. - array( + [ 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')), 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')), 'absolute' => FALSE, 'expected' => $positive_19_hours, - ), + ], // In 1970 Sydney did not observe daylight savings time // So there is only a 18 hour time interval. - array( + [ 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')), 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')), 'absolute' => FALSE, 'expected' => $positive_18_hours, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 3600, new \DateTimeZone('America/Los_Angeles')), 'input2' => DateTimePlus::createFromFormat('U', 0, new \DateTimeZone('UTC')), 'absolute' => FALSE, 'expected' => $negative_1_hour, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 3600), 'input2' => DateTimePlus::createFromFormat('U', 0), 'absolute' => FALSE, 'expected' => $negative_1_hour, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 3600), 'input2' => \DateTime::createFromFormat('U', 0), 'absolute' => FALSE, 'expected' => $negative_1_hour, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 3600), 'input2' => DateTimePlus::createFromFormat('U', 0), 'absolute' => TRUE, 'expected' => $positive_1_hour, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 3600), 'input2' => \DateTime::createFromFormat('U', 0), 'absolute' => TRUE, 'expected' => $positive_1_hour, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 0), 'input2' => DateTimePlus::createFromFormat('U', 0), 'absolute' => FALSE, 'expected' => $empty_interval, - ), - ); + ], + ]; } /** @@ -652,18 +682,174 @@ public function providerTestDateDiff() { * @see DateTimePlusTest::testInvalidDateDiff() */ public function providerTestInvalidDateDiff() { - return array( - array( + return [ + [ 'input1' => DateTimePlus::createFromFormat('U', 3600), 'input2' => '1970-01-01 00:00:00', 'absolute' => FALSE, - ), - array( + ], + [ 'input1' => DateTimePlus::createFromFormat('U', 3600), 'input2' => NULL, 'absolute' => FALSE, - ), - ); + ], + ]; + } + + /** + * Tests invalid values passed to constructor. + * + * @param string $time + * A date/time string. + * @param string[] $errors + * An array of error messages. + * + * @covers ::__construct + * + * @dataProvider providerTestInvalidConstructor + */ + public function testInvalidConstructor($time, array $errors) { + $date = new DateTimePlus($time); + + $this->assertEquals(TRUE, $date->hasErrors()); + $this->assertEquals($errors, $date->getErrors()); + } + + /** + * Provider for testInvalidConstructor(). + * + * @return array + * An array of invalid date/time strings, and corresponding error messages. + */ + public function providerTestInvalidConstructor() { + return [ + [ + 'YYYY-MM-DD', + [ + 'The timezone could not be found in the database', + 'Unexpected character', + 'Double timezone specification', + ], + ], + [ + '2017-MM-DD', + [ + 'Unexpected character', + 'The timezone could not be found in the database', + ], + ], + [ + 'YYYY-03-DD', + [ + 'The timezone could not be found in the database', + 'Unexpected character', + 'Double timezone specification', + ], + ], + [ + 'YYYY-MM-07', + [ + 'The timezone could not be found in the database', + 'Unexpected character', + 'Double timezone specification', + ], + ], + [ + '2017-13-55', + [ + 'Unexpected character', + ], + ], + [ + 'YYYY-MM-DD hh:mm:ss', + [ + 'The timezone could not be found in the database', + 'Unexpected character', + 'Double timezone specification', + ], + ], + [ + '2017-03-07 25:70:80', + [ + 'Unexpected character', + 'Double time specification', + ], + ], + [ + 'lorem ipsum dolor sit amet', + [ + 'The timezone could not be found in the database', + 'Double timezone specification', + ], + ], + ]; + } + + /** + * Tests the $settings['validate_format'] parameter in ::createFromFormat(). + */ + public function testValidateFormat() { + // Check that an input that does not strictly follow the input format will + // produce the desired date. In this case the year string '11' doesn't + // precisely match the 'Y' formater parameter, but PHP will parse it + // regardless. However, when formatted with the same string, the year will + // be output with four digits. With the ['validate_format' => FALSE] + // $settings, this will not thrown an exception. + $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '11-03-31 17:44:00', 'UTC', ['validate_format' => FALSE]); + $this->assertEquals('0011-03-31 17:44:00', $date->format('Y-m-d H:i:s')); + + // Parse the same date with ['validate_format' => TRUE] and make sure we + // get the expected exception. + $this->setExpectedException(\UnexpectedValueException::class); + $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '11-03-31 17:44:00', 'UTC', ['validate_format' => TRUE]); + } + + /** + * Tests that object methods are chainable. + * + * @covers ::__call + */ + public function testChainable() { + $date = new DateTimePlus('now', 'Australia/Sydney'); + + $date->setTimestamp(12345678); + $rendered = $date->render(); + $this->assertEquals('1970-05-24 07:21:18 Australia/Sydney', $rendered); + + $date->setTimestamp(23456789); + $rendered = $date->setTimezone(new \DateTimeZone('America/New_York'))->render(); + $this->assertEquals('1970-09-29 07:46:29 America/New_York', $rendered); + + $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-05-24 07:21:18', new \DateTimeZone('Australia/Sydney')) + ->setTimezone(new \DateTimeZone('America/New_York')); + $rendered = $date->render(); + $this->assertInstanceOf(DateTimePlus::class, $date); + $this->assertEquals(12345678, $date->getTimestamp()); + $this->assertEquals('1970-05-23 17:21:18 America/New_York', $rendered); + } + + /** + * Tests that non-chainable methods work. + * + * @covers ::__call + */ + public function testChainableNonChainable() { + $datetime1 = new DateTimePlus('2009-10-11 12:00:00'); + $datetime2 = new DateTimePlus('2009-10-13 12:00:00'); + $interval = $datetime1->diff($datetime2); + $this->assertInstanceOf(\DateInterval::class, $interval); + $this->assertEquals('+2 days', $interval->format('%R%a days')); + } + + /** + * Tests that chained calls to non-existent functions throw an exception. + * + * @covers ::__call + */ + public function testChainableNonCallable() { + $this->setExpectedException(\BadMethodCallException::class, 'Call to undefined method Drupal\Component\Datetime\DateTimePlus::nonexistent()'); + $date = new DateTimePlus('now', 'Australia/Sydney'); + $date->setTimezone(new \DateTimeZone('America/New_York'))->nonexistent(); } } diff --git a/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php b/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php new file mode 100644 index 00000000..4a5fa802 --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php @@ -0,0 +1,123 @@ +requestStack = $this->getMock('Symfony\Component\HttpFoundation\RequestStack'); + + $this->time = new Time($this->requestStack); + } + + /** + * Tests the getRequestTime method. + * + * @covers ::getRequestTime + */ + public function testGetRequestTime() { + $expected = 12345678; + + $request = Request::createFromGlobals(); + $request->server->set('REQUEST_TIME', $expected); + + // Mocks a the request stack getting the current request. + $this->requestStack->expects($this->any()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->assertEquals($expected, $this->time->getRequestTime()); + } + + /** + * Tests the getRequestMicroTime method. + * + * @covers ::getRequestMicroTime + */ + public function testGetRequestMicroTime() { + $expected = 1234567.89; + + $request = Request::createFromGlobals(); + $request->server->set('REQUEST_TIME_FLOAT', $expected); + + // Mocks a the request stack getting the current request. + $this->requestStack->expects($this->any()) + ->method('getCurrentRequest') + ->willReturn($request); + + $this->assertEquals($expected, $this->time->getRequestMicroTime()); + } + + /** + * Tests the getCurrentTime method. + * + * @covers ::getCurrentTime + */ + public function testGetCurrentTime() { + $expected = 12345678; + $this->assertEquals($expected, $this->time->getCurrentTime()); + } + + /** + * Tests the getCurrentMicroTime method. + * + * @covers ::getCurrentMicroTime + */ + public function testGetCurrentMicroTime() { + $expected = 1234567.89; + $this->assertEquals($expected, $this->time->getCurrentMicroTime()); + } + +} + +namespace Drupal\Component\Datetime; + +/** + * Shadow time() system call. + * + * @returns int + */ +function time() { + return 12345678; +} + +/** + * Shadow microtime system call. + * + * @returns float + */ +function microtime() { + return 1234567.89; +} diff --git a/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php b/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php index 3c89804d..963496db 100644 --- a/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php +++ b/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php @@ -7,15 +7,22 @@ namespace Drupal\Tests\Component\DependencyInjection; +use Drupal\Component\Utility\Crypt; +use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Prophecy\Argument; /** * @coversDefaultClass \Drupal\Component\DependencyInjection\Container * @group DependencyInjection */ -class ContainerTest extends \PHPUnit_Framework_TestCase { +class ContainerTest extends TestCase { /** * The tested container. @@ -59,12 +66,11 @@ protected function setUp() { * Tests that passing a non-supported format throws an InvalidArgumentException. * * @covers ::__construct - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException */ public function testConstruct() { $container_definition = $this->getMockContainerDefinition(); $container_definition['machine_format'] = !$this->machineFormat; + $this->setExpectedException(InvalidArgumentException::class); $container = new $this->containerClass($container_definition); } @@ -85,10 +91,9 @@ public function testGetParameter() { * @covers ::getParameter * @covers ::getParameterAlternatives * @covers ::getAlternatives - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException */ public function testGetParameterIfNotFound() { + $this->setExpectedException(ParameterNotFoundException::class); $this->container->getParameter('parameter_that_does_not_exist'); } @@ -96,10 +101,9 @@ public function testGetParameterIfNotFound() { * Tests that Container::getParameter() works properly for NULL parameters. * * @covers ::getParameter - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException */ public function testGetParameterIfNotFoundBecauseNull() { + $this->setExpectedException(ParameterNotFoundException::class); $this->container->getParameter(NULL); } @@ -130,11 +134,10 @@ public function testSetParameterWithUnfrozenContainer() { * Tests that Container::setParameter() in a frozen case works properly. * * @covers ::setParameter - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException */ public function testSetParameterWithFrozenContainer() { $this->container = new $this->containerClass($this->containerDefinition); + $this->setExpectedException(LogicException::class); $this->container->setParameter('some_config', 'new_value'); } @@ -235,11 +238,11 @@ public function testHasForAliasedService() { /** * Tests that Container::get() for circular dependencies works properly. - * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException * @covers ::get * @covers ::createService */ public function testGetForCircularServices() { + $this->setExpectedException(ServiceCircularReferenceException::class); $this->container->get('circular_dependency'); } @@ -250,10 +253,9 @@ public function testGetForCircularServices() { * @covers ::createService * @covers ::getAlternatives * @covers ::getServiceAlternatives - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException */ public function testGetForNonExistantService() { + $this->setExpectedException(ServiceNotFoundException::class); $this->container->get('service_not_exists'); } @@ -295,8 +297,6 @@ public function testGetForNonExistantParameterDependency() { * @covers ::get * @covers ::createService * @covers ::resolveServicesAndParameters - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException */ public function testGetForParameterDependencyWithExceptionOnSecondCall() { $service = $this->container->get('service_parameter_not_exists', ContainerInterface::NULL_ON_INVALID_REFERENCE); @@ -304,6 +304,7 @@ public function testGetForParameterDependencyWithExceptionOnSecondCall() { // Reset the service. $this->container->set('service_parameter_not_exists', NULL); + $this->setExpectedException(InvalidArgumentException::class); $this->container->get('service_parameter_not_exists'); } @@ -313,10 +314,9 @@ public function testGetForParameterDependencyWithExceptionOnSecondCall() { * @covers ::get * @covers ::createService * @covers ::resolveServicesAndParameters - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException */ public function testGetForNonExistantParameterDependencyWithException() { + $this->setExpectedException(InvalidArgumentException::class); $this->container->get('service_parameter_not_exists'); } @@ -339,10 +339,9 @@ public function testGetForNonExistantServiceDependency() { * @covers ::createService * @covers ::resolveServicesAndParameters * @covers ::getAlternatives - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException */ public function testGetForNonExistantServiceDependencyWithException() { + $this->setExpectedException(ServiceNotFoundException::class); $this->container->get('service_dependency_not_exists'); } @@ -360,10 +359,9 @@ public function testGetForNonExistantServiceWhenUsingNull() { * Tests that Container::get() for NULL service works properly. * @covers ::get * @covers ::createService - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException */ public function testGetForNonExistantNULLService() { + $this->setExpectedException(ServiceNotFoundException::class); $this->container->get(NULL); } @@ -386,11 +384,10 @@ public function testGetForNonExistantServiceMultipleTimes() { * @covers ::get * @covers ::createService * @covers ::getAlternatives - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException */ public function testGetForNonExistantServiceWithExceptionOnSecondCall() { $this->assertNull($this->container->get('service_not_exists', ContainerInterface::NULL_ON_INVALID_REFERENCE), 'Not found service does nto throw exception.'); + $this->setExpectedException(ServiceNotFoundException::class); $this->container->get('service_not_exists'); } @@ -424,10 +421,9 @@ public function testGetForSyntheticService() { * * @covers ::get * @covers ::createService - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException */ public function testGetForSyntheticServiceWithException() { + $this->setExpectedException(RuntimeException::class); $this->container->get('synthetic'); } @@ -451,7 +447,7 @@ public function testGetWithFileInclude() { * @covers ::resolveServicesAndParameters */ public function testGetForInstantiationWithVariousArgumentLengths() { - $args = array(); + $args = []; for ($i = 0; $i < 12; $i++) { $instantiation_service = $this->container->get('service_test_instantiation_' . $i); $this->assertEquals($args, $instantiation_service->getArguments()); @@ -464,10 +460,9 @@ public function testGetForInstantiationWithVariousArgumentLengths() { * * @covers ::get * @covers ::createService - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException */ public function testGetForWrongFactory() { + $this->setExpectedException(RuntimeException::class); $this->container->get('wrong_factory'); } @@ -503,10 +498,9 @@ public function testGetForFactoryClass() { * * @covers ::get * @covers ::createService - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException */ public function testGetForConfiguratorWithException() { + $this->setExpectedException(InvalidArgumentException::class); $this->container->get('configurable_service_exception'); } @@ -523,7 +517,7 @@ public function testGetForConfigurator() { $configurator = $this->prophesize('\Drupal\Tests\Component\DependencyInjection\MockConfiguratorInterface'); $configurator->configureService(Argument::type('object')) ->shouldBeCalled(1) - ->will(function($args) use ($container) { + ->will(function ($args) use ($container) { $args[0]->setContainer($container); }); $container->set('configurator', $configurator->reveal()); @@ -602,10 +596,9 @@ public function testResolveServicesAndParametersForOptionalServiceDependencies() * @covers ::get * @covers ::createService * @covers ::resolveServicesAndParameters - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException */ public function testResolveServicesAndParametersForInvalidArgument() { + $this->setExpectedException(InvalidArgumentException::class); $this->container->get('invalid_argument_service'); } @@ -615,12 +608,11 @@ public function testResolveServicesAndParametersForInvalidArgument() { * @covers ::get * @covers ::createService * @covers ::resolveServicesAndParameters - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException */ public function testResolveServicesAndParametersForInvalidArguments() { // In case the machine-optimized format is not used, we need to simulate the // test failure. + $this->setExpectedException(InvalidArgumentException::class); if (!$this->machineFormat) { throw new InvalidArgumentException('Simulating the test failure.'); } @@ -662,47 +654,6 @@ public function testInitializedForAliases() { $this->assertTrue($this->container->initialized('late.service_alias'), 'Late service is initialized after it was retrieved once.'); } - /** - * Tests that unsupported methods throw an Exception. - * - * @covers ::enterScope - * @covers ::leaveScope - * @covers ::addScope - * @covers ::hasScope - * @covers ::isScopeActive - * - * @expectedException \BadMethodCallException - * - * @dataProvider scopeExceptionTestProvider - */ - public function testScopeFunctionsWithException($method, $argument) { - $callable = array( - $this->container, - $method, - ); - - $callable($argument); - } - - /** - * Data provider for scopeExceptionTestProvider(). - * - * @return array[] - * Returns per data set an array with: - * - method name to call - * - argument to pass - */ - public function scopeExceptionTestProvider() { - $scope = $this->prophesize('\Symfony\Component\DependencyInjection\ScopeInterface')->reveal(); - return array( - array('enterScope', 'test_scope'), - array('leaveScope', 'test_scope'), - array('hasScope', 'test_scope'), - array('isScopeActive', 'test_scope'), - array('addScope', $scope), - ); - } - /** * Tests that Container::getServiceIds() works properly. * @@ -728,7 +679,7 @@ public function testGetServiceIds() { */ protected function getMockContainerDefinition() { $fake_service = new \stdClass(); - $parameters = array(); + $parameters = []; $parameters['some_parameter_class'] = get_class($fake_service); $parameters['some_private_config'] = 'really_private_lama'; $parameters['some_config'] = 'foo'; @@ -737,262 +688,272 @@ protected function getMockContainerDefinition() { // Also test alias resolving. $parameters['service_from_parameter'] = $this->getServiceCall('service.provider_alias'); - $services = array(); - $services['service_container'] = array( + $services = []; + $services['service_container'] = [ 'class' => '\Drupal\service_container\DependencyInjection\Container', - ); - $services['other.service'] = array( + ]; + $services['other.service'] = [ 'class' => get_class($fake_service), - ); + ]; - $services['non_shared_service'] = array( + $services['non_shared_service'] = [ 'class' => get_class($fake_service), 'shared' => FALSE, - ); + ]; - $services['other.service_class_from_parameter'] = array( + $services['other.service_class_from_parameter'] = [ 'class' => $this->getParameterCall('some_parameter_class'), - ); - $services['late.service'] = array( + ]; + $services['late.service'] = [ 'class' => get_class($fake_service), - ); - $services['service.provider'] = array( + ]; + $services['service.provider'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getServiceCall('other.service'), $this->getParameterCall('some_config'), - )), - 'properties' => $this->getCollection(array('_someProperty' => 'foo')), - 'calls' => array( - array('setContainer', $this->getCollection(array( - $this->getServiceCall('service_container'), - ))), - array('setOtherConfigParameter', $this->getCollection(array( - $this->getParameterCall('some_other_config'), - ))), - ), + ]), + 'properties' => $this->getCollection(['_someProperty' => 'foo']), + 'calls' => [ + [ + 'setContainer', + $this->getCollection([ + $this->getServiceCall('service_container'), + ]), + ], + [ + 'setOtherConfigParameter', + $this->getCollection([ + $this->getParameterCall('some_other_config'), + ]), + ], + ], 'priority' => 0, - ); + ]; // Test private services. - $private_service = array( + $private_service = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getServiceCall('other.service'), $this->getParameterCall('some_private_config'), - )), + ]), 'public' => FALSE, - ); + ]; - $services['service_using_private'] = array( + $services['service_using_private'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getPrivateServiceCall(NULL, $private_service), $this->getParameterCall('some_config'), - )), - ); - $services['another_service_using_private'] = array( + ]), + ]; + $services['another_service_using_private'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getPrivateServiceCall(NULL, $private_service), $this->getParameterCall('some_config'), - )), - ); + ]), + ]; // Test shared private services. $id = 'private_service_shared_1'; - $services['service_using_shared_private'] = array( + $services['service_using_shared_private'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getPrivateServiceCall($id, $private_service, TRUE), $this->getParameterCall('some_config'), - )), - ); - $services['another_service_using_shared_private'] = array( + ]), + ]; + $services['another_service_using_shared_private'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getPrivateServiceCall($id, $private_service, TRUE), $this->getParameterCall('some_config'), - )), - ); + ]), + ]; // Tests service with invalid argument. - $services['invalid_argument_service'] = array( + $services['invalid_argument_service'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( - 1, // Test passing non-strings, too. - (object) array( + 'arguments' => $this->getCollection([ + // Test passing non-strings, too. + 1, + (object) [ 'type' => 'invalid', - ), - )), - ); + ], + ]), + ]; - $services['invalid_arguments_service'] = array( + $services['invalid_arguments_service'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => (object) array( + 'arguments' => (object) [ 'type' => 'invalid', - ), - ); + ], + ]; // Test service that needs deep-traversal. - $services['service_using_array'] = array( + $services['service_using_array'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( - $this->getCollection(array( + 'arguments' => $this->getCollection([ + $this->getCollection([ $this->getServiceCall('other.service'), - )), + ]), $this->getParameterCall('some_private_config'), - )), - ); + ]), + ]; - $services['service_with_optional_dependency'] = array( + $services['service_with_optional_dependency'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getServiceCall('service.does_not_exist', ContainerInterface::NULL_ON_INVALID_REFERENCE), $this->getParameterCall('some_private_config'), - )), + ]), - ); + ]; - $services['factory_service'] = array( + $services['factory_service'] = [ 'class' => '\Drupal\service_container\ServiceContainer\ControllerInterface', - 'factory' => array( + 'factory' => [ $this->getServiceCall('service.provider'), 'getFactoryMethod', - ), - 'arguments' => $this->getCollection(array( + ], + 'arguments' => $this->getCollection([ $this->getParameterCall('factory_service_class'), - )), - ); - $services['factory_class'] = array( + ]), + ]; + $services['factory_class'] = [ 'class' => '\Drupal\service_container\ServiceContainer\ControllerInterface', 'factory' => '\Drupal\Tests\Component\DependencyInjection\MockService::getFactoryMethod', - 'arguments' => array( + 'arguments' => [ '\Drupal\Tests\Component\DependencyInjection\MockService', - array(NULL, 'bar'), - ), - 'calls' => array( - array('setContainer', $this->getCollection(array( - $this->getServiceCall('service_container'), - ))), - ), - ); - - $services['wrong_factory'] = array( + [NULL, 'bar'], + ], + 'calls' => [ + [ + 'setContainer', + $this->getCollection([ + $this->getServiceCall('service_container'), + ]), + ], + ], + ]; + + $services['wrong_factory'] = [ 'class' => '\Drupal\service_container\ServiceContainer\ControllerInterface', - 'factory' => (object) array('I am not a factory, but I pretend to be.'), - ); + 'factory' => (object) ['I am not a factory, but I pretend to be.'], + ]; - $services['circular_dependency'] = array( + $services['circular_dependency'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getServiceCall('circular_dependency'), - )), - ); - $services['synthetic'] = array( + ]), + ]; + $services['synthetic'] = [ 'synthetic' => TRUE, - ); + ]; // The file could have been named as a .php file. The reason it is a .data // file is that SimpleTest tries to load it. SimpleTest does not like such // fixtures and hence we use a neutral name like .data. - $services['container_test_file_service_test'] = array( + $services['container_test_file_service_test'] = [ 'class' => '\stdClass', 'file' => __DIR__ . '/Fixture/container_test_file_service_test_service_function.data', - ); + ]; // Test multiple arguments. - $args = array(); + $args = []; for ($i = 0; $i < 12; $i++) { - $services['service_test_instantiation_' . $i] = array( + $services['service_test_instantiation_' . $i] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockInstantiationService', // Also test a collection that does not need resolving. 'arguments' => $this->getCollection($args, FALSE), - ); + ]; $args[] = 'arg_' . $i; } - $services['service_parameter_not_exists'] = array( + $services['service_parameter_not_exists'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getServiceCall('service.provider'), $this->getParameterCall('not_exists'), - )), - ); - $services['service_dependency_not_exists'] = array( + ]), + ]; + $services['service_dependency_not_exists'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getServiceCall('service_not_exists'), $this->getParameterCall('some_config'), - )), - ); + ]), + ]; - $services['service_with_parameter_service'] = array( + $services['service_with_parameter_service'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $this->getParameterCall('service_from_parameter'), // Also test deep collections that don't need resolving. - $this->getCollection(array( + $this->getCollection([ 1, - ), FALSE), - )), - ); + ], FALSE), + ]), + ]; // To ensure getAlternatives() finds something. - $services['service_not_exists_similar'] = array( + $services['service_not_exists_similar'] = [ 'synthetic' => TRUE, - ); + ]; // Test configurator. - $services['configurator'] = array( + $services['configurator'] = [ 'synthetic' => TRUE, - ); - $services['configurable_service'] = array( + ]; + $services['configurable_service'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => array(), - 'configurator' => array( + 'arguments' => [], + 'configurator' => [ $this->getServiceCall('configurator'), 'configureService' - ), - ); - $services['configurable_service_exception'] = array( + ], + ]; + $services['configurable_service_exception'] = [ 'class' => '\Drupal\Tests\Component\DependencyInjection\MockService', - 'arguments' => array(), + 'arguments' => [], 'configurator' => 'configurator_service_test_does_not_exist', - ); + ]; - $aliases = array(); + $aliases = []; $aliases['service.provider_alias'] = 'service.provider'; $aliases['late.service_alias'] = 'late.service'; - return array( + return [ 'aliases' => $aliases, 'parameters' => $parameters, 'services' => $services, 'frozen' => TRUE, 'machine_format' => $this->machineFormat, - ); + ]; } /** * Helper function to return a service definition. */ protected function getServiceCall($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { - return (object) array( + return (object) [ 'type' => 'service', 'id' => $id, 'invalidBehavior' => $invalid_behavior, - ); + ]; } /** * Helper function to return a service definition. */ protected function getParameterCall($name) { - return (object) array( + return (object) [ 'type' => 'parameter', 'name' => $name, - ); + ]; } /** @@ -1000,26 +961,26 @@ protected function getParameterCall($name) { */ protected function getPrivateServiceCall($id, $service_definition, $shared = FALSE) { if (!$id) { - $hash = sha1(serialize($service_definition)); + $hash = Crypt::hashBase64(serialize($service_definition)); $id = 'private__' . $hash; } - return (object) array( + return (object) [ 'type' => 'private_service', 'id' => $id, 'value' => $service_definition, 'shared' => $shared, - ); + ]; } /** * Helper function to return a machine-optimized collection. */ protected function getCollection($collection, $resolve = TRUE) { - return (object) array( + return (object) [ 'type' => 'collection', 'value' => $collection, 'resolve' => $resolve, - ); + ]; } } @@ -1188,7 +1149,7 @@ public function getSomeOtherParameter() { * @return object * The instantiated service object. */ - public static function getFactoryMethod($class, $arguments = array()) { + public static function getFactoryMethod($class, $arguments = []) { $r = new \ReflectionClass($class); $service = ($r->getConstructor() === NULL) ? $r->newInstance() : $r->newInstanceArgs($arguments); diff --git a/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php b/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php index 49b65565..3c447527 100644 --- a/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php +++ b/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php @@ -7,18 +7,22 @@ namespace Drupal\Tests\Component\DependencyInjection\Dumper { + use Drupal\Component\Utility\Crypt; + use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\ContainerInterface; + use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + use Symfony\Component\DependencyInjection\Exception\RuntimeException; /** * @coversDefaultClass \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper * @group DependencyInjection */ - class OptimizedPhpArrayDumperTest extends \PHPUnit_Framework_TestCase { + class OptimizedPhpArrayDumperTest extends TestCase { /** * The container builder instance. @@ -61,15 +65,15 @@ class OptimizedPhpArrayDumperTest extends \PHPUnit_Framework_TestCase { protected function setUp() { // Setup a mock container builder. $this->containerBuilder = $this->prophesize('\Symfony\Component\DependencyInjection\ContainerBuilder'); - $this->containerBuilder->getAliases()->willReturn(array()); + $this->containerBuilder->getAliases()->willReturn([]); $this->containerBuilder->getParameterBag()->willReturn(new ParameterBag()); $this->containerBuilder->getDefinitions()->willReturn(NULL); $this->containerBuilder->isFrozen()->willReturn(TRUE); - $definition = array(); - $definition['aliases'] = array(); - $definition['parameters'] = array(); - $definition['services'] = array(); + $definition = []; + $definition['aliases'] = []; + $definition['parameters'] = []; + $definition['services'] = []; $definition['frozen'] = TRUE; $definition['machine_format'] = $this->machineFormat; @@ -113,17 +117,17 @@ public function testGetAliases($aliases, $definition_aliases) { * - aliases as expected in the container definition. */ public function getAliasesDataProvider() { - return array( - array(array(), array()), - array( - array('foo' => 'foo.alias'), - array('foo' => 'foo.alias'), - ), - array( - array('foo' => 'foo.alias', 'foo.alias' => 'foo.alias.alias'), - array('foo' => 'foo.alias.alias', 'foo.alias' => 'foo.alias.alias'), - ), - ); + return [ + [[], []], + [ + ['foo' => 'foo.alias'], + ['foo' => 'foo.alias'], + ], + [ + ['foo' => 'foo.alias', 'foo.alias' => 'foo.alias.alias'], + ['foo' => 'foo.alias.alias', 'foo.alias' => 'foo.alias.alias'], + ], + ]; } /** @@ -163,34 +167,34 @@ public function testGetParameters($parameters, $definition_parameters, $is_froze * - frozen value */ public function getParametersDataProvider() { - return array( - array(array(), array(), TRUE), - array( - array('foo' => 'value_foo'), - array('foo' => 'value_foo'), + return [ + [[], [], TRUE], + [ + ['foo' => 'value_foo'], + ['foo' => 'value_foo'], TRUE, - ), - array( - array('foo' => array('llama' => 'yes')), - array('foo' => array('llama' => 'yes')), + ], + [ + ['foo' => ['llama' => 'yes']], + ['foo' => ['llama' => 'yes']], TRUE, - ), - array( - array('foo' => '%llama%', 'llama' => 'yes'), - array('foo' => '%%llama%%', 'llama' => 'yes'), + ], + [ + ['foo' => '%llama%', 'llama' => 'yes'], + ['foo' => '%%llama%%', 'llama' => 'yes'], TRUE, - ), - array( - array('foo' => '%llama%', 'llama' => 'yes'), - array('foo' => '%llama%', 'llama' => 'yes'), + ], + [ + ['foo' => '%llama%', 'llama' => 'yes'], + ['foo' => '%llama%', 'llama' => 'yes'], FALSE, - ), - array( - array('reference' => new Reference('referenced_service')), - array('reference' => $this->getServiceCall('referenced_service')), + ], + [ + ['reference' => new Reference('referenced_service')], + ['reference' => $this->getServiceCall('referenced_service')], TRUE, - ), - ); + ], + ]; } /** @@ -208,6 +212,8 @@ public function getParametersDataProvider() { * @covers ::getParameterCall * * @dataProvider getDefinitionsDataProvider + * + * @group legacy */ public function testGetServiceDefinitions($services, $definition_services) { $this->containerDefinition['services'] = $definition_services; @@ -235,164 +241,158 @@ public function testGetServiceDefinitions($services, $definition_services) { * - frozen value */ public function getDefinitionsDataProvider() { - $base_service_definition = array( + $base_service_definition = [ 'class' => '\stdClass', 'public' => TRUE, 'file' => FALSE, 'synthetic' => FALSE, 'lazy' => FALSE, - 'arguments' => array(), + 'arguments' => [], 'arguments_count' => 0, - 'properties' => array(), - 'calls' => array(), - 'scope' => ContainerInterface::SCOPE_CONTAINER, + 'properties' => [], + 'calls' => [], 'shared' => TRUE, 'factory' => FALSE, 'configurator' => FALSE, - ); + ]; // Test basic flags. - $service_definitions[] = array() + $base_service_definition; + $service_definitions[] = [] + $base_service_definition; - $service_definitions[] = array( + $service_definitions[] = [ 'public' => FALSE, - ) + $base_service_definition; + ] + $base_service_definition; - $service_definitions[] = array( + $service_definitions[] = [ 'file' => 'test_include.php', - ) + $base_service_definition; + ] + $base_service_definition; - $service_definitions[] = array( + $service_definitions[] = [ 'synthetic' => TRUE, - ) + $base_service_definition; + ] + $base_service_definition; - $service_definitions[] = array( + $service_definitions[] = [ 'shared' => FALSE, - ) + $base_service_definition; + ] + $base_service_definition; - $service_definitions[] = array( + $service_definitions[] = [ 'lazy' => TRUE, - ) + $base_service_definition; + ] + $base_service_definition; // Test a basic public Reference. - $service_definitions[] = array( - 'arguments' => array('foo', new Reference('bar')), + $service_definitions[] = [ + 'arguments' => ['foo', new Reference('bar')], 'arguments_count' => 2, - 'arguments_expected' => $this->getCollection(array('foo', $this->getServiceCall('bar'))), - ) + $base_service_definition; + 'arguments_expected' => $this->getCollection(['foo', $this->getServiceCall('bar')]), + ] + $base_service_definition; // Test a public reference that should not throw an Exception. $reference = new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE); - $service_definitions[] = array( - 'arguments' => array($reference), + $service_definitions[] = [ + 'arguments' => [$reference], 'arguments_count' => 1, - 'arguments_expected' => $this->getCollection(array($this->getServiceCall('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE))), - ) + $base_service_definition; + 'arguments_expected' => $this->getCollection([$this->getServiceCall('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE)]), + ] + $base_service_definition; // Test a private shared service, denoted by having a Reference. - $private_definition = array( + $private_definition = [ 'class' => '\stdClass', 'public' => FALSE, 'arguments_count' => 0, - ); + ]; - $service_definitions[] = array( - 'arguments' => array('foo', new Reference('private_definition')), + $service_definitions[] = [ + 'arguments' => ['foo', new Reference('private_definition')], 'arguments_count' => 2, - 'arguments_expected' => $this->getCollection(array( + 'arguments_expected' => $this->getCollection([ 'foo', $this->getPrivateServiceCall('private_definition', $private_definition, TRUE), - )), - ) + $base_service_definition; + ]), + ] + $base_service_definition; // Test a private non-shared service, denoted by having a Definition. $private_definition_object = new Definition('\stdClass'); $private_definition_object->setPublic(FALSE); - $service_definitions[] = array( - 'arguments' => array('foo', $private_definition_object), + $service_definitions[] = [ + 'arguments' => ['foo', $private_definition_object], 'arguments_count' => 2, - 'arguments_expected' => $this->getCollection(array( + 'arguments_expected' => $this->getCollection([ 'foo', $this->getPrivateServiceCall(NULL, $private_definition), - )), - ) + $base_service_definition; + ]), + ] + $base_service_definition; // Test a deep collection without a reference. - $service_definitions[] = array( - 'arguments' => array(array(array('foo'))), + $service_definitions[] = [ + 'arguments' => [[['foo']]], 'arguments_count' => 1, - ) + $base_service_definition; + ] + $base_service_definition; // Test a deep collection with a reference to resolve. - $service_definitions[] = array( - 'arguments' => array(array(new Reference('bar'))), + $service_definitions[] = [ + 'arguments' => [[new Reference('bar')]], 'arguments_count' => 1, - 'arguments_expected' => $this->getCollection(array($this->getCollection(array($this->getServiceCall('bar'))))), - ) + $base_service_definition; + 'arguments_expected' => $this->getCollection([$this->getCollection([$this->getServiceCall('bar')])]), + ] + $base_service_definition; // Test a collection with a variable to resolve. - $service_definitions[] = array( - 'arguments' => array(new Parameter('llama_parameter')), + $service_definitions[] = [ + 'arguments' => [new Parameter('llama_parameter')], 'arguments_count' => 1, - 'arguments_expected' => $this->getCollection(array($this->getParameterCall('llama_parameter'))), - ) + $base_service_definition; + 'arguments_expected' => $this->getCollection([$this->getParameterCall('llama_parameter')]), + ] + $base_service_definition; // Test objects that have _serviceId property. $drupal_service = new \stdClass(); $drupal_service->_serviceId = 'bar'; - $service_definitions[] = array( - 'arguments' => array($drupal_service), + $service_definitions[] = [ + 'arguments' => [$drupal_service], 'arguments_count' => 1, - 'arguments_expected' => $this->getCollection(array($this->getServiceCall('bar'))), - ) + $base_service_definition; + 'arguments_expected' => $this->getCollection([$this->getServiceCall('bar')]), + ] + $base_service_definition; // Test getMethodCalls. - $calls = array( - array('method', $this->getCollection(array())), - array('method2', $this->getCollection(array())), - ); - $service_definitions[] = array( + $calls = [ + ['method', $this->getCollection([])], + ['method2', $this->getCollection([])], + ]; + $service_definitions[] = [ 'calls' => $calls, - ) + $base_service_definition; - - $service_definitions[] = array( - 'scope' => ContainerInterface::SCOPE_PROTOTYPE, - 'shared' => FALSE, - ) + $base_service_definition; + ] + $base_service_definition; - $service_definitions[] = array( + $service_definitions[] = [ 'shared' => FALSE, - ) + $base_service_definition; + ] + $base_service_definition; // Test factory. - $service_definitions[] = array( - 'factory' => array(new Reference('bar'), 'factoryMethod'), - 'factory_expected' => array($this->getServiceCall('bar'), 'factoryMethod'), - ) + $base_service_definition; + $service_definitions[] = [ + 'factory' => [new Reference('bar'), 'factoryMethod'], + 'factory_expected' => [$this->getServiceCall('bar'), 'factoryMethod'], + ] + $base_service_definition; // Test invalid factory - needed to test deep dumpValue(). - $service_definitions[] = array( - 'factory' => array(array('foo', 'llama'), 'factoryMethod'), - ) + $base_service_definition; + $service_definitions[] = [ + 'factory' => [['foo', 'llama'], 'factoryMethod'], + ] + $base_service_definition; // Test properties. - $service_definitions[] = array( - 'properties' => array('_value' => 'llama'), - ) + $base_service_definition; + $service_definitions[] = [ + 'properties' => ['_value' => 'llama'], + ] + $base_service_definition; // Test configurator. - $service_definitions[] = array( - 'configurator' => array(new Reference('bar'), 'configureService'), - 'configurator_expected' => array($this->getServiceCall('bar'), 'configureService'), - ) + $base_service_definition; + $service_definitions[] = [ + 'configurator' => [new Reference('bar'), 'configureService'], + 'configurator_expected' => [$this->getServiceCall('bar'), 'configureService'], + ] + $base_service_definition; - $services_provided = array(); - $services_provided[] = array( - array(), - array(), - ); + $services_provided = []; + $services_provided[] = [ + [], + [], + ]; foreach ($service_definitions as $service_definition) { $definition = $this->prophesize('\Symfony\Component\DependencyInjection\Definition'); @@ -404,14 +404,13 @@ public function getDefinitionsDataProvider() { $definition->getArguments()->willReturn($service_definition['arguments']); $definition->getProperties()->willReturn($service_definition['properties']); $definition->getMethodCalls()->willReturn($service_definition['calls']); - $definition->getScope()->willReturn($service_definition['scope']); $definition->isShared()->willReturn($service_definition['shared']); $definition->getDecoratedService()->willReturn(NULL); $definition->getFactory()->willReturn($service_definition['factory']); $definition->getConfigurator()->willReturn($service_definition['configurator']); // Preserve order. - $filtered_service_definition = array(); + $filtered_service_definition = []; foreach ($base_service_definition as $key => $value) { $filtered_service_definition[$key] = $service_definition[$key]; unset($service_definition[$key]); @@ -429,7 +428,7 @@ public function getDefinitionsDataProvider() { $filtered_service_definition += $service_definition; // Allow to set _expected values. - foreach (array('arguments', 'factory', 'configurator') as $key) { + foreach (['arguments', 'factory', 'configurator'] as $key) { $expected = $key . '_expected'; if (isset($filtered_service_definition[$expected])) { $filtered_service_definition[$key] = $filtered_service_definition[$expected]; @@ -437,21 +436,18 @@ public function getDefinitionsDataProvider() { } } - // Remove any remaining scope. - unset($filtered_service_definition['scope']); - if (isset($filtered_service_definition['public']) && $filtered_service_definition['public'] === FALSE) { - $services_provided[] = array( - array('foo_service' => $definition->reveal()), - array(), - ); + $services_provided[] = [ + ['foo_service' => $definition->reveal()], + [], + ]; continue; } - $services_provided[] = array( - array('foo_service' => $definition->reveal()), - array('foo_service' => $this->serializeDefinition($filtered_service_definition)), - ); + $services_provided[] = [ + ['foo_service' => $definition->reveal()], + ['foo_service' => $this->serializeDefinition($filtered_service_definition)], + ]; } return $services_provided; @@ -470,27 +466,11 @@ protected function serializeDefinition(array $service_definition) { * Helper function to return a service definition. */ protected function getServiceCall($id, $invalid_behavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { - return (object) array( + return (object) [ 'type' => 'service', 'id' => $id, 'invalidBehavior' => $invalid_behavior, - ); - } - - /** - * Tests that the correct InvalidArgumentException is thrown for getScope(). - * - * @covers ::getServiceDefinition - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException - */ - public function testGetServiceDefinitionWithInvalidScope() { - $bar_definition = new Definition('\stdClass'); - $bar_definition->setScope('foo_scope'); - $services['bar'] = $bar_definition; - - $this->containerBuilder->getDefinitions()->willReturn($services); - $this->dumper->getArray(); + ]; } /** @@ -499,12 +479,14 @@ public function testGetServiceDefinitionWithInvalidScope() { * @covers ::getReferenceCall * * @dataProvider publicPrivateDataProvider + * + * @group legacy */ public function testGetServiceDefinitionWithReferenceToAlias($public) { $bar_definition = new Definition('\stdClass'); - $bar_definition_php_array = array( + $bar_definition_php_array = [ 'class' => '\stdClass', - ); + ]; if (!$public) { $bar_definition->setPublic(FALSE); $bar_definition_php_array['public'] = FALSE; @@ -530,21 +512,21 @@ public function testGetServiceDefinitionWithReferenceToAlias($public) { else { $service_definition = $this->getPrivateServiceCall('bar', $bar_definition_php_array, TRUE); } - $data = array( + $data = [ 'class' => '\stdClass', - 'arguments' => $this->getCollection(array( + 'arguments' => $this->getCollection([ $service_definition, - )), + ]), 'arguments_count' => 1, - ); + ]; $this->assertEquals($this->serializeDefinition($data), $dump['services']['foo'], 'Expected definition matches dump.'); } public function publicPrivateDataProvider() { - return array( - array(TRUE), - array(FALSE), - ); + return [ + [TRUE], + [FALSE], + ]; } /** @@ -555,7 +537,7 @@ public function publicPrivateDataProvider() { * * @covers ::getServiceDefinition * - * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @group legacy */ public function testGetServiceDefinitionForDecoratedService() { $bar_definition = new Definition('\stdClass'); @@ -563,6 +545,7 @@ public function testGetServiceDefinitionForDecoratedService() { $services['bar'] = $bar_definition; $this->containerBuilder->getDefinitions()->willReturn($services); + $this->setExpectedException(InvalidArgumentException::class); $this->dumper->getArray(); } @@ -570,8 +553,6 @@ public function testGetServiceDefinitionForDecoratedService() { * Tests that the correct RuntimeException is thrown for expressions. * * @covers ::dumpValue - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException */ public function testGetServiceDefinitionForExpression() { $expression = new Expression(); @@ -581,6 +562,7 @@ public function testGetServiceDefinitionForExpression() { $services['bar'] = $bar_definition; $this->containerBuilder->getDefinitions()->willReturn($services); + $this->setExpectedException(RuntimeException::class); $this->dumper->getArray(); } @@ -588,8 +570,6 @@ public function testGetServiceDefinitionForExpression() { * Tests that the correct RuntimeException is thrown for dumping an object. * * @covers ::dumpValue - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException */ public function testGetServiceDefinitionForObject() { $service = new \stdClass(); @@ -599,6 +579,7 @@ public function testGetServiceDefinitionForObject() { $services['bar'] = $bar_definition; $this->containerBuilder->getDefinitions()->willReturn($services); + $this->setExpectedException(RuntimeException::class); $this->dumper->getArray(); } @@ -606,8 +587,6 @@ public function testGetServiceDefinitionForObject() { * Tests that the correct RuntimeException is thrown for dumping a resource. * * @covers ::dumpValue - * - * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException */ public function testGetServiceDefinitionForResource() { $resource = fopen('php://memory', 'r'); @@ -617,6 +596,7 @@ public function testGetServiceDefinitionForResource() { $services['bar'] = $bar_definition; $this->containerBuilder->getDefinitions()->willReturn($services); + $this->setExpectedException(RuntimeException::class); $this->dumper->getArray(); } @@ -625,36 +605,36 @@ public function testGetServiceDefinitionForResource() { */ protected function getPrivateServiceCall($id, $service_definition, $shared = FALSE) { if (!$id) { - $hash = sha1(serialize($service_definition)); + $hash = Crypt::hashBase64(serialize($service_definition)); $id = 'private__' . $hash; } - return (object) array( + return (object) [ 'type' => 'private_service', 'id' => $id, 'value' => $service_definition, 'shared' => $shared, - ); + ]; } /** * Helper function to return a machine-optimized collection. */ protected function getCollection($collection, $resolve = TRUE) { - return (object) array( + return (object) [ 'type' => 'collection', 'value' => $collection, 'resolve' => $resolve, - ); + ]; } /** * Helper function to return a parameter definition. */ protected function getParameterCall($name) { - return (object) array( + return (object) [ 'type' => 'parameter', 'name' => $name, - ); + ]; } } @@ -666,6 +646,7 @@ protected function getParameterCall($name) { * define a dummy, else it cannot be tested. */ namespace Symfony\Component\ExpressionLanguage { + if (!class_exists('\Symfony\Component\ExpressionLanguage\Expression')) { /** * Dummy class to ensure non-existent Symfony component can be tested. diff --git a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php index 70fb0dcf..c5fab909 100644 --- a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php +++ b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php @@ -4,6 +4,7 @@ use Drupal\Component\Diff\Diff; use Drupal\Component\Diff\DiffFormatter; +use PHPUnit\Framework\TestCase; /** * Test DiffFormatter classes. @@ -12,7 +13,7 @@ * * @group Diff */ -class DiffFormatterTest extends \PHPUnit_Framework_TestCase { +class DiffFormatterTest extends TestCase { /** * @return array diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php index ade15275..69f92dae 100644 --- a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php +++ b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php @@ -7,6 +7,7 @@ use Drupal\Component\Diff\Engine\DiffOpCopy; use Drupal\Component\Diff\Engine\DiffOpChange; use Drupal\Component\Diff\Engine\DiffOpDelete; +use PHPUnit\Framework\TestCase; /** * Test DiffEngine class. @@ -15,7 +16,7 @@ * * @group Diff */ -class DiffEngineTest extends \PHPUnit_Framework_TestCase { +class DiffEngineTest extends TestCase { /** * @return array diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php index 4275bb7a..1a649ae5 100644 --- a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php +++ b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\Component\Diff\Engine; use Drupal\Component\Diff\Engine\DiffOp; +use PHPUnit\Framework\TestCase; /** * Test DiffOp base class. @@ -15,7 +16,7 @@ * * @group Diff */ -class DiffOpTest extends \PHPUnit_Framework_TestCase { +class DiffOpTest extends TestCase { /** * DiffOp::reverse() always throws an error. diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php index ccf468d3..194f37f5 100644 --- a/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php +++ b/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\Component\Diff\Engine; use Drupal\Component\Diff\Engine\HWLDFWordAccumulator; +use PHPUnit\Framework\TestCase; /** * Test HWLDFWordAccumulator. @@ -11,7 +12,7 @@ * * @group Diff */ -class HWLDFWordAccumulatorTest extends \PHPUnit_Framework_TestCase { +class HWLDFWordAccumulatorTest extends TestCase { /** * Verify that we only get back a NBSP from an empty accumulator. diff --git a/core/tests/Drupal/Tests/Component/Discovery/YamlDirectoryDiscoveryTest.php b/core/tests/Drupal/Tests/Component/Discovery/YamlDirectoryDiscoveryTest.php index c9862b64..86134a7b 100644 --- a/core/tests/Drupal/Tests/Component/Discovery/YamlDirectoryDiscoveryTest.php +++ b/core/tests/Drupal/Tests/Component/Discovery/YamlDirectoryDiscoveryTest.php @@ -4,8 +4,9 @@ use Drupal\Component\Discovery\DiscoveryException; use Drupal\Component\Discovery\YamlDirectoryDiscovery; -use Drupal\Tests\UnitTestCase; +use Drupal\Component\FileCache\FileCacheFactory; use org\bovigo\vfs\vfsStream; +use PHPUnit\Framework\TestCase; /** * YamlDirectoryDiscoveryTest component unit tests. @@ -14,7 +15,15 @@ * * @group Discovery */ -class YamlDirectoryDiscoveryTest extends UnitTestCase { +class YamlDirectoryDiscoveryTest extends TestCase { + + /** + * {@inheritdoc} + */ + protected function setUp() { + // Ensure that FileCacheFactory has a prefix. + FileCacheFactory::setPrefix('prefix'); + } /** * Tests YAML directory discovery. diff --git a/core/tests/Drupal/Tests/Component/Discovery/YamlDiscoveryTest.php b/core/tests/Drupal/Tests/Component/Discovery/YamlDiscoveryTest.php index 68b16eeb..2922586f 100644 --- a/core/tests/Drupal/Tests/Component/Discovery/YamlDiscoveryTest.php +++ b/core/tests/Drupal/Tests/Component/Discovery/YamlDiscoveryTest.php @@ -2,18 +2,27 @@ namespace Drupal\Tests\Component\Discovery; -use Drupal\Tests\UnitTestCase; use Drupal\Component\Discovery\YamlDiscovery; +use Drupal\Component\FileCache\FileCacheFactory; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamWrapper; use org\bovigo\vfs\vfsStreamDirectory; +use PHPUnit\Framework\TestCase; /** * YamlDiscovery component unit tests. * * @group Discovery */ -class YamlDiscoveryTest extends UnitTestCase { +class YamlDiscoveryTest extends TestCase { + + /** + * {@inheritdoc} + */ + protected function setUp() { + // Ensure that FileCacheFactory has a prefix. + FileCacheFactory::setPrefix('prefix'); + } /** * Tests the YAML file discovery. @@ -34,12 +43,12 @@ public function testDiscovery() { file_put_contents($url . '/test_2/test_4.test.yml', ''); // Set up the directories to search. - $directories = array( + $directories = [ 'test_1' => $url . '/test_1', 'test_2' => $url . '/test_1', 'test_3' => $url . '/test_2', 'test_4' => $url . '/test_2', - ); + ]; $discovery = new YamlDiscovery('test', $directories); $data = $discovery->findAll(); @@ -50,12 +59,12 @@ public function testDiscovery() { $this->assertArrayHasKey('test_3', $data); $this->assertArrayHasKey('test_4', $data); - foreach (array('test_1', 'test_2', 'test_3') as $key) { + foreach (['test_1', 'test_2', 'test_3'] as $key) { $this->assertArrayHasKey('name', $data[$key]); $this->assertEquals($data[$key]['name'], 'test'); } - $this->assertSame(array(), $data['test_4']); + $this->assertSame([], $data['test_4']); } } diff --git a/core/tests/Drupal/Tests/Component/DrupalComponentTest.php b/core/tests/Drupal/Tests/Component/DrupalComponentTest.php index 11ce86f0..03d39d3f 100644 --- a/core/tests/Drupal/Tests/Component/DrupalComponentTest.php +++ b/core/tests/Drupal/Tests/Component/DrupalComponentTest.php @@ -2,15 +2,15 @@ namespace Drupal\Tests\Component; -use Drupal\Tests\UnitTestCase; use org\bovigo\vfs\vfsStream; +use PHPUnit\Framework\TestCase; /** * General tests for \Drupal\Component that can't go anywhere else. * * @group Component */ -class DrupalComponentTest extends UnitTestCase { +class DrupalComponentTest extends TestCase { /** * Tests that classes in Component do not use any Core class. @@ -42,7 +42,7 @@ public function testNoCoreInComponentTests() { * An array of class paths. */ protected function findPhpClasses($dir) { - $classes = array(); + $classes = []; foreach (new \DirectoryIterator($dir) as $file) { if ($file->isDir() && !$file->isDot()) { $classes = array_merge($classes, $this->findPhpClasses($file->getPathname())); @@ -64,7 +64,7 @@ protected function findPhpClasses($dir) { protected function assertNoCoreUsage($class_path) { $contents = file_get_contents($class_path); preg_match_all('/^.*Drupal\\\Core.*$/m', $contents, $matches); - $matches = array_filter($matches[0], function($line) { + $matches = array_filter($matches[0], function ($line) { // Filter references to @see as they don't really matter. return strpos($line, '@see') === FALSE; }); @@ -80,26 +80,26 @@ protected function assertNoCoreUsage($class_path) { * - File data as a string. This will be used as a virtual file. */ public function providerAssertNoCoreUseage() { - return array( - array( + return [ + [ TRUE, '@see \\Drupal\\Core\\Something', - ), - array( + ], + [ FALSE, '\\Drupal\\Core\\Something', - ), - array( + ], + [ FALSE, "@see \\Drupal\\Core\\Something\n" . '\\Drupal\\Core\\Something', - ), - array( + ], + [ FALSE, "\\Drupal\\Core\\Something\n" . '@see \\Drupal\\Core\\Something', - ), - ); + ], + ]; } /** diff --git a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php index 7bc2382b..ea0685a7 100644 --- a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php +++ b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php @@ -6,9 +6,10 @@ use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\EventDispatcher\Tests\CallableClass; -use Symfony\Component\EventDispatcher\Tests\TestEventListener; use Symfony\Component\EventDispatcher\Tests\ContainerAwareEventDispatcherTest as SymfonyContainerAwareEventDispatcherTest; +use Symfony\Component\EventDispatcher\Tests\TestEventListener; /** * Unit tests for the ContainerAwareEventDispatcher. @@ -37,7 +38,7 @@ public function testGetListenersWithCallables() // When passing in callables exclusively as listeners into the event // dispatcher constructor, the event dispatcher must not attempt to // resolve any services. - $container = $this->getMock('Symfony\Component\DependencyInjection\IntrospectableContainerInterface'); + $container = $this->getMock(ContainerInterface::class); $container->expects($this->never())->method($this->anything()); $firstListener = new CallableClass(); @@ -72,7 +73,7 @@ public function testDispatchWithCallables() // When passing in callables exclusively as listeners into the event // dispatcher constructor, the event dispatcher must not attempt to // resolve any services. - $container = $this->getMock('Symfony\Component\DependencyInjection\IntrospectableContainerInterface'); + $container = $this->getMock(ContainerInterface::class); $container->expects($this->never())->method($this->anything()); $firstListener = new CallableClass(); diff --git a/core/tests/Drupal/Tests/Component/FileCache/FileCacheFactoryTest.php b/core/tests/Drupal/Tests/Component/FileCache/FileCacheFactoryTest.php index b4d8de9c..c317bd84 100644 --- a/core/tests/Drupal/Tests/Component/FileCache/FileCacheFactoryTest.php +++ b/core/tests/Drupal/Tests/Component/FileCache/FileCacheFactoryTest.php @@ -5,13 +5,14 @@ use Drupal\Component\FileCache\FileCache; use Drupal\Component\FileCache\NullFileCache; use Drupal\Component\FileCache\FileCacheFactory; -use Drupal\Tests\UnitTestCase; +use Drupal\Component\Utility\Random; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\FileCache\FileCacheFactory * @group FileCache */ -class FileCacheFactoryTest extends UnitTestCase { +class FileCacheFactoryTest extends TestCase { /** * {@inheritdoc} @@ -55,12 +56,10 @@ public function testGet() { /** * @covers ::get - * - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Required prefix configuration is missing */ public function testGetNoPrefix() { FileCacheFactory::setPrefix(NULL); + $this->setExpectedException(\InvalidArgumentException::class, 'Required prefix configuration is missing'); FileCacheFactory::get('test_foo_settings', []); } @@ -101,56 +100,59 @@ public function configurationDataProvider() { // Get a unique FileCache class. $file_cache = $this->getMockBuilder(FileCache::class) - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $class = get_class($file_cache); // Test fallback configuration. - $data['fallback-configuration'] = [[ - ], [], FileCache::class]; + $data['fallback-configuration'] = [ + [], + [], + FileCache::class, + ]; // Test default configuration. - $data['default-configuration'] = [[ - 'default' => [ - 'class' => $class, - ], - ], [], $class]; + $data['default-configuration'] = [ + ['default' => ['class' => $class]], + [], + $class, + ]; // Test specific per collection setting. - $data['collection-setting'] = [[ - 'test_foo_settings' => [ - 'class' => $class, - ], - ], [], $class]; + $data['collection-setting'] = [ + ['test_foo_settings' => ['class' => $class]], + [], + $class, + ]; // Test default configuration plus specific per collection setting. - $data['default-plus-collection-setting'] = [[ - 'default' => [ - 'class' => '\stdClass', + $data['default-plus-collection-setting'] = [ + [ + 'default' => ['class' => '\stdClass'], + 'test_foo_settings' => ['class' => $class], ], - 'test_foo_settings' => [ - 'class' => $class, - ], - ], [], $class]; + [], + $class, + ]; // Test default configuration plus class specific override. - $data['default-plus-class-override'] = [[ - 'default' => [ - 'class' => '\stdClass', - ], - ], [ 'class' => $class ], $class]; + $data['default-plus-class-override'] = [ + ['default' => ['class' => '\stdClass']], + ['class' => $class], + $class, + ]; // Test default configuration plus class specific override plus specific // per collection setting. - $data['default-plus-class-plus-collection-setting'] = [[ - 'default' => [ - 'class' => '\stdClass', + $data['default-plus-class-plus-collection-setting'] = [ + [ + 'default' => ['class' => '\stdClass'], + 'test_foo_settings' => ['class' => $class], ], - 'test_foo_settings' => [ - 'class' => $class, - ], - ], [ 'class' => '\stdClass'], $class]; + ['class' => '\stdClass'], + $class, + ]; return $data; } @@ -172,7 +174,10 @@ public function testGetSetConfiguration() { * @covers ::setPrefix */ public function testGetSetPrefix() { - $prefix = $this->randomMachineName(); + // Random generator. + $random = new Random(); + + $prefix = $random->name(8, TRUE); FileCacheFactory::setPrefix($prefix); $this->assertEquals($prefix, FileCacheFactory::getPrefix()); } diff --git a/core/tests/Drupal/Tests/Component/FileCache/FileCacheTest.php b/core/tests/Drupal/Tests/Component/FileCache/FileCacheTest.php index 9ad30b76..15ef1ac9 100644 --- a/core/tests/Drupal/Tests/Component/FileCache/FileCacheTest.php +++ b/core/tests/Drupal/Tests/Component/FileCache/FileCacheTest.php @@ -3,13 +3,13 @@ namespace Drupal\Tests\Component\FileCache; use Drupal\Component\FileCache\FileCache; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\FileCache\FileCache * @group FileCache */ -class FileCacheTest extends UnitTestCase { +class FileCacheTest extends TestCase { /** * FileCache object used for the tests. diff --git a/core/tests/Drupal/Tests/Component/FileSystem/RegexDirectoryIteratorTest.php b/core/tests/Drupal/Tests/Component/FileSystem/RegexDirectoryIteratorTest.php index 6a9cd0ca..4760c195 100644 --- a/core/tests/Drupal/Tests/Component/FileSystem/RegexDirectoryIteratorTest.php +++ b/core/tests/Drupal/Tests/Component/FileSystem/RegexDirectoryIteratorTest.php @@ -3,14 +3,14 @@ namespace Drupal\Tests\Component\FileSystem; use Drupal\Component\FileSystem\RegexDirectoryIterator; -use Drupal\Tests\UnitTestCase; use org\bovigo\vfs\vfsStream; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\FileSystem\RegexDirectoryIterator * @group FileSystem */ -class RegexDirectoryIteratorTest extends UnitTestCase { +class RegexDirectoryIteratorTest extends TestCase { /** * @covers ::accept @@ -21,7 +21,7 @@ public function testRegexDirectoryIterator(array $directory, $regex, array $expe $iterator = new RegexDirectoryIterator(vfsStream::url('root'), $regex); // Create an array of filenames to assert against. - $file_list = array_map(function(\SplFileInfo $file) { + $file_list = array_map(function (\SplFileInfo $file) { return $file->getFilename(); }, array_values(iterator_to_array($iterator))); diff --git a/core/tests/Drupal/Tests/Component/Gettext/PoHeaderTest.php b/core/tests/Drupal/Tests/Component/Gettext/PoHeaderTest.php index eab85b38..caae2d82 100644 --- a/core/tests/Drupal/Tests/Component/Gettext/PoHeaderTest.php +++ b/core/tests/Drupal/Tests/Component/Gettext/PoHeaderTest.php @@ -3,7 +3,7 @@ namespace Drupal\Tests\Component\Gettext; use Drupal\Component\Gettext\PoHeader; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * Unit tests for the Gettext PO file header handling features. @@ -12,7 +12,7 @@ * * @group Gettext */ -class PoHeaderTest extends UnitTestCase { +class PoHeaderTest extends TestCase { /** * Tests that plural expressions are evaluated correctly. @@ -48,22 +48,22 @@ public function testPluralsFormula($plural, $expected) { * value. */ public function providerTestPluralsFormula() { - return array( - array( + return [ + [ 'nplurals=1; plural=0;', - array('default' => 0), - ), - array( + ['default' => 0], + ], + [ 'nplurals=2; plural=(n > 1);', - array(0 => 0, 1 => 0, 'default' => 1), - ), - array( + [0 => 0, 1 => 0, 'default' => 1], + ], + [ 'nplurals=2; plural=(n!=1);', - array(1 => 0, 'default' => 1), - ), - array( + [1 => 0, 'default' => 1], + ], + [ 'nplurals=2; plural=(((n==1)||((n%10)==1))?(0):1);', - array( + [ 1 => 0, 11 => 0, 21 => 0, @@ -85,11 +85,11 @@ public function providerTestPluralsFormula() { 181 => 0, 191 => 0, 'default' => 1, - ), - ), - array( + ], + ], + [ 'nplurals=3; plural=((((n%10)==1)&&((n%100)!=11))?(0):(((((n%10)>=2)&&((n%10)<=4))&&(((n%100)<10)||((n%100)>=20)))?(1):2));', - array( + [ 1 => 0, 2 => 1, 3 => 1, @@ -163,21 +163,21 @@ public function providerTestPluralsFormula() { 193 => 1, 194 => 1, 'default' => 2, - ), - ), - array( + ], + ], + [ 'nplurals=3; plural=((n==1)?(0):(((n>=2)&&(n<=4))?(1):2));', - array( + [ 1 => 0, 2 => 1, 3 => 1, 4 => 1, 'default' => 2, - ), - ), - array( + ], + ], + [ 'nplurals=3; plural=((n==1)?(0):(((n==0)||(((n%100)>0)&&((n%100)<20)))?(1):2));', - array( + [ 0 => 1, 1 => 0, 2 => 1, @@ -218,11 +218,11 @@ public function providerTestPluralsFormula() { 118 => 1, 119 => 1, 'default' => 2, - ), - ), - array( + ], + ], + [ 'nplurals=3; plural=((n==1)?(0):(((((n%10)>=2)&&((n%10)<=4))&&(((n%100)<10)||((n%100)>=20)))?(1):2));', - array( + [ 1 => 0, 2 => 1, 3 => 1, @@ -279,10 +279,11 @@ public function providerTestPluralsFormula() { 193 => 1, 194 => 1, 'default' => 2, - ),), - array( + ], + ], + [ 'nplurals=4; plural=(((n==1)||(n==11))?(0):(((n==2)||(n==12))?(1):(((n>2)&&(n<20))?(2):3)));', - array( + [ 1 => 0, 2 => 1, 3 => 2, @@ -303,11 +304,11 @@ public function providerTestPluralsFormula() { 18 => 2, 19 => 2, 'default' => 3, - ), - ), - array( + ], + ], + [ 'nplurals=4; plural=(((n%100)==1)?(0):(((n%100)==2)?(1):((((n%100)==3)||((n%100)==4))?(2):3)));', - array( + [ 1 => 0, 2 => 1, 3 => 2, @@ -317,11 +318,11 @@ public function providerTestPluralsFormula() { 103 => 2, 104 => 2, 'default' => 3, - ), - ), - array( + ], + ], + [ 'nplurals=5; plural=((n==1)?(0):((n==2)?(1):((n<7)?(2):((n<11)?(3):4))));', - array( + [ 0 => 2, 1 => 0, 2 => 1, @@ -334,11 +335,11 @@ public function providerTestPluralsFormula() { 9 => 3, 10 => 3, 'default' => 4, - ), - ), - array( + ], + ], + [ 'nplurals=6; plural=((n==1)?(0):((n==0)?(1):((n==2)?(2):((((n%100)>=3)&&((n%100)<=10))?(3):((((n%100)>=11)&&((n%100)<=99))?(4):5)))));', - array( + [ 0 => 1, 1 => 0, 2 => 2, @@ -362,9 +363,9 @@ public function providerTestPluralsFormula() { 109 => 3, 110 => 3, 'default' => 4, - ), - ), - ); + ], + ], + ]; } } diff --git a/core/tests/Drupal/Tests/Component/Graph/GraphTest.php b/core/tests/Drupal/Tests/Component/Graph/GraphTest.php index e17c7ff0..940217c6 100644 --- a/core/tests/Drupal/Tests/Component/Graph/GraphTest.php +++ b/core/tests/Drupal/Tests/Component/Graph/GraphTest.php @@ -3,13 +3,13 @@ namespace Drupal\Tests\Component\Graph; use Drupal\Component\Graph\Graph; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Graph\Graph * @group Graph */ -class GraphTest extends UnitTestCase { +class GraphTest extends TestCase { /** * Test depth-first-search features. @@ -21,59 +21,59 @@ public function testDepthFirstSearch() { // | | | // | | | // +---> 4 <-- 7 8 ---> 9 - $graph = $this->normalizeGraph(array( - 1 => array(2), - 2 => array(3, 4), - 3 => array(), - 4 => array(3), - 5 => array(6), - 7 => array(4, 5), - 8 => array(9), - 9 => array(), - )); + $graph = $this->normalizeGraph([ + 1 => [2], + 2 => [3, 4], + 3 => [], + 4 => [3], + 5 => [6], + 7 => [4, 5], + 8 => [9], + 9 => [], + ]); $graph_object = new Graph($graph); $graph = $graph_object->searchAndSort(); - $expected_paths = array( - 1 => array(2, 3, 4), - 2 => array(3, 4), - 3 => array(), - 4 => array(3), - 5 => array(6), - 7 => array(4, 3, 5, 6), - 8 => array(9), - 9 => array(), - ); + $expected_paths = [ + 1 => [2, 3, 4], + 2 => [3, 4], + 3 => [], + 4 => [3], + 5 => [6], + 7 => [4, 3, 5, 6], + 8 => [9], + 9 => [], + ]; $this->assertPaths($graph, $expected_paths); - $expected_reverse_paths = array( - 1 => array(), - 2 => array(1), - 3 => array(2, 1, 4, 7), - 4 => array(2, 1, 7), - 5 => array(7), - 7 => array(), - 8 => array(), - 9 => array(8), - ); + $expected_reverse_paths = [ + 1 => [], + 2 => [1], + 3 => [2, 1, 4, 7], + 4 => [2, 1, 7], + 5 => [7], + 7 => [], + 8 => [], + 9 => [8], + ]; $this->assertReversePaths($graph, $expected_reverse_paths); // Assert that DFS didn't created "missing" vertexes automatically. $this->assertFalse(isset($graph[6]), 'Vertex 6 has not been created'); - $expected_components = array( - array(1, 2, 3, 4, 5, 7), - array(8, 9), - ); + $expected_components = [ + [1, 2, 3, 4, 5, 7], + [8, 9], + ]; $this->assertComponents($graph, $expected_components); - $expected_weights = array( - array(1, 2, 3), - array(2, 4, 3), - array(7, 4, 3), - array(7, 5), - array(8, 9), - ); + $expected_weights = [ + [1, 2, 3], + [2, 4, 3], + [7, 4, 3], + [7, 5], + [8, 9], + ]; $this->assertWeights($graph, $expected_weights); } @@ -87,10 +87,10 @@ public function testDepthFirstSearch() { * The normalized version of a graph. */ protected function normalizeGraph($graph) { - $normalized_graph = array(); + $normalized_graph = []; foreach ($graph as $vertex => $edges) { // Create vertex even if it hasn't any edges. - $normalized_graph[$vertex] = array(); + $normalized_graph[$vertex] = []; foreach ($edges as $edge) { $normalized_graph[$vertex]['edges'][$edge] = TRUE; } @@ -110,7 +110,7 @@ protected function assertPaths($graph, $expected_paths) { foreach ($expected_paths as $vertex => $paths) { // Build an array with keys = $paths and values = TRUE. $expected = array_fill_keys($paths, TRUE); - $result = isset($graph[$vertex]['paths']) ? $graph[$vertex]['paths'] : array(); + $result = isset($graph[$vertex]['paths']) ? $graph[$vertex]['paths'] : []; $this->assertEquals($expected, $result, sprintf('Expected paths for vertex %s: %s, got %s', $vertex, $this->displayArray($expected, TRUE), $this->displayArray($result, TRUE))); } } @@ -128,7 +128,7 @@ protected function assertReversePaths($graph, $expected_reverse_paths) { foreach ($expected_reverse_paths as $vertex => $paths) { // Build an array with keys = $paths and values = TRUE. $expected = array_fill_keys($paths, TRUE); - $result = isset($graph[$vertex]['reverse_paths']) ? $graph[$vertex]['reverse_paths'] : array(); + $result = isset($graph[$vertex]['reverse_paths']) ? $graph[$vertex]['reverse_paths'] : []; $this->assertEquals($expected, $result, sprintf('Expected reverse paths for vertex %s: %s, got %s', $vertex, $this->displayArray($expected, TRUE), $this->displayArray($result, TRUE))); } } @@ -144,14 +144,14 @@ protected function assertReversePaths($graph, $expected_reverse_paths) { protected function assertComponents($graph, $expected_components) { $unassigned_vertices = array_fill_keys(array_keys($graph), TRUE); foreach ($expected_components as $component) { - $result_components = array(); + $result_components = []; foreach ($component as $vertex) { $result_components[] = $graph[$vertex]['component']; unset($unassigned_vertices[$vertex]); } $this->assertEquals(1, count(array_unique($result_components)), sprintf('Expected one unique component for vertices %s, got %s', $this->displayArray($component), $this->displayArray($result_components))); } - $this->assertEquals(array(), $unassigned_vertices, sprintf('Vertices not assigned to a component: %s', $this->displayArray($unassigned_vertices, TRUE))); + $this->assertEquals([], $unassigned_vertices, sprintf('Vertices not assigned to a component: %s', $this->displayArray($unassigned_vertices, TRUE))); } /** diff --git a/core/tests/Drupal/Tests/Component/HttpFoundation/SecuredRedirectResponseTest.php b/core/tests/Drupal/Tests/Component/HttpFoundation/SecuredRedirectResponseTest.php index f569c0ac..17149723 100644 --- a/core/tests/Drupal/Tests/Component/HttpFoundation/SecuredRedirectResponseTest.php +++ b/core/tests/Drupal/Tests/Component/HttpFoundation/SecuredRedirectResponseTest.php @@ -8,7 +8,7 @@ namespace Drupal\Tests\Component\HttpFoundation; use Drupal\Component\HttpFoundation\SecuredRedirectResponse; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -18,7 +18,7 @@ * @group Routing * @coversDefaultClass \Drupal\Component\HttpFoundation\SecuredRedirectResponse */ -class SecuredRedirectResponseTest extends UnitTestCase { +class SecuredRedirectResponseTest extends TestCase { /** * Test copying of redirect response. diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php index eca12416..46ef5900 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageReadOnlyTest.php @@ -4,6 +4,7 @@ use Drupal\Component\PhpStorage\FileStorage; use Drupal\Component\PhpStorage\FileReadOnlyStorage; +use Drupal\Component\Utility\Random; /** * @coversDefaultClass \Drupal\Component\PhpStorage\FileReadOnlyStorage @@ -33,23 +34,26 @@ class FileStorageReadOnlyTest extends PhpStorageTestBase { protected function setUp() { parent::setUp(); - $this->standardSettings = array( + $this->standardSettings = [ 'directory' => $this->directory, 'bin' => 'test', - ); - $this->readonlyStorage = array( + ]; + $this->readonlyStorage = [ 'directory' => $this->directory, // Let this read from the bin where the other instance is writing. 'bin' => 'test', - ); + ]; } /** * Tests writing with one class and reading with another. */ public function testReadOnly() { + // Random generator. + $random = new Random(); + $php = new FileStorage($this->standardSettings); - $name = $this->randomMachineName() . '/' . $this->randomMachineName() . '.php'; + $name = $random->name(8, TRUE) . '/' . $random->name(8, TRUE) . '.php'; // Find a global that doesn't exist. do { @@ -85,8 +89,11 @@ public function testWriteable() { * @covers ::deleteAll */ public function testDeleteAll() { + // Random generator. + $random = new Random(); + $php = new FileStorage($this->standardSettings); - $name = $this->randomMachineName() . '/' . $this->randomMachineName() . '.php'; + $name = $random->name(8, TRUE) . '/' . $random->name(8, TRUE) . '.php'; // Find a global that doesn't exist. do { diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php index 25a0ed00..14260630 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\Component\PhpStorage; use Drupal\Component\PhpStorage\FileStorage; +use Drupal\Component\Utility\Random; /** * @coversDefaultClass \Drupal\Component\PhpStorage\FileStorage @@ -24,10 +25,10 @@ class FileStorageTest extends PhpStorageTestBase { protected function setUp() { parent::setUp(); - $this->standardSettings = array( + $this->standardSettings = [ 'directory' => $this->directory, 'bin' => 'test', - ); + ]; } /** @@ -55,11 +56,13 @@ public function testWriteable() { * @covers ::deleteAll */ public function testDeleteAll() { + // Random generator. + $random_generator = new Random(); // Write out some files. $php = new FileStorage($this->standardSettings); - $name = $this->randomMachineName() . '/' . $this->randomMachineName() . '.php'; + $name = $random_generator->name(8, TRUE) . '/' . $random_generator->name(8, TRUE) . '.php'; // Find a global that doesn't exist. do { diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFastFileStorageTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFastFileStorageTest.php index 726cd1c7..577241d4 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFastFileStorageTest.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFastFileStorageTest.php @@ -19,7 +19,7 @@ class MTimeProtectedFastFileStorageTest extends MTimeProtectedFileStorageBase { * include the hacked file on the first try but the second test will change * the directory mtime and so on the second try the file will not be included. */ - protected $expected = array(TRUE, FALSE); + protected $expected = [TRUE, FALSE]; /** * The PHP storage class to test. diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php index 64d17eb2..e7875100 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php @@ -2,6 +2,9 @@ namespace Drupal\Tests\Component\PhpStorage; +use Drupal\Component\Utility\Crypt; +use Drupal\Component\Utility\Random; + /** * Base test class for MTime protected storage. */ @@ -34,13 +37,16 @@ abstract class MTimeProtectedFileStorageBase extends PhpStorageTestBase { protected function setUp() { parent::setUp(); - $this->secret = $this->randomMachineName(); + // Random generator. + $random = new Random(); + + $this->secret = $random->name(8, TRUE); - $this->settings = array( + $this->settings = [ 'directory' => $this->directory, 'bin' => 'test', 'secret' => $this->secret, - ); + ]; } /** @@ -77,7 +83,7 @@ public function testSecurity() { $expected_directory = $expected_root_directory . '/' . $name; } $directory_mtime = filemtime($expected_directory); - $expected_filename = $expected_directory . '/' . hash_hmac('sha256', $name, $this->secret . $directory_mtime) . '.php'; + $expected_filename = $expected_directory . '/' . Crypt::hmacBase64($name, $this->secret . $directory_mtime) . '.php'; // Ensure the file exists and that it and the containing directory have // minimal permissions. fileperms() can return high bits unrelated to @@ -88,7 +94,7 @@ public function testSecurity() { // Ensure the root directory for the bin has a .htaccess file denying web // access. - $this->assertSame(file_get_contents($expected_root_directory . '/.htaccess'), call_user_func(array($this->storageClass, 'htaccessLines'))); + $this->assertSame(file_get_contents($expected_root_directory . '/.htaccess'), call_user_func([$this->storageClass, 'htaccessLines'])); // Ensure that if the file is replaced with an untrusted one (due to another // script's file upload vulnerability), it does not get loaded. Since mtime diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php index 15b75e72..bc88c334 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageTest.php @@ -18,7 +18,7 @@ class MTimeProtectedFileStorageTest extends MTimeProtectedFileStorageBase { * The default implementation protects against even the filemtime change so * both iterations will return FALSE. */ - protected $expected = array(FALSE, FALSE); + protected $expected = [FALSE, FALSE]; /** * The PHP storage class to test. diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/PhpStorageTestBase.php b/core/tests/Drupal/Tests/Component/PhpStorage/PhpStorageTestBase.php index f32155e3..cc0e79d0 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/PhpStorageTestBase.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/PhpStorageTestBase.php @@ -3,13 +3,14 @@ namespace Drupal\Tests\Component\PhpStorage; use Drupal\Component\PhpStorage\PhpStorageInterface; -use Drupal\Tests\UnitTestCase; +use Drupal\Component\Utility\Random; use org\bovigo\vfs\vfsStream; +use PHPUnit\Framework\TestCase; /** * Base test for PHP storages. */ -abstract class PhpStorageTestBase extends UnitTestCase { +abstract class PhpStorageTestBase extends TestCase { /** * A unique per test class directory path to test php storage. @@ -31,7 +32,10 @@ protected function setUp() { * Assert that a PHP storage's load/save/delete operations work. */ public function assertCRUD($php) { - $name = $this->randomMachineName() . '/' . $this->randomMachineName() . '.php'; + // Random generator. + $random_generator = new Random(); + + $name = $random_generator->name(8, TRUE) . '/' . $random_generator->name(8, TRUE) . '.php'; // Find a global that doesn't exist. do { diff --git a/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php b/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php index 917379e4..6a2cf466 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Context/ContextTest.php @@ -3,13 +3,13 @@ namespace Drupal\Tests\Component\Plugin\Context; use Drupal\Component\Plugin\Context\Context; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Plugin\Context\Context * @group Plugin */ -class ContextTest extends UnitTestCase { +class ContextTest extends TestCase { /** * Data provider for testGetContextValue. @@ -30,7 +30,7 @@ public function testGetContextValue($expected, $context_value, $is_required, $da // Mock a Context object. $mock_context = $this->getMockBuilder('Drupal\Component\Plugin\Context\Context') ->disableOriginalConstructor() - ->setMethods(array('getContextDefinition')) + ->setMethods(['getContextDefinition']) ->getMock(); // If the context value exists, getContextValue() behaves like a normal @@ -49,7 +49,7 @@ public function testGetContextValue($expected, $context_value, $is_required, $da else { // Create a mock definition. $mock_definition = $this->getMockBuilder('Drupal\Component\Plugin\Context\ContextDefinitionInterface') - ->setMethods(array('isRequired', 'getDataType')) + ->setMethods(['isRequired', 'getDataType']) ->getMockForAbstractClass(); // Set expectation for isRequired(). @@ -87,7 +87,7 @@ public function testGetContextValue($expected, $context_value, $is_required, $da */ public function testDefaultValue() { $mock_definition = $this->getMockBuilder('Drupal\Component\Plugin\Context\ContextDefinitionInterface') - ->setMethods(array('getDefaultValue')) + ->setMethods(['getDefaultValue']) ->getMockForAbstractClass(); $mock_definition->expects($this->once()) diff --git a/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php b/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php index 1fc805bf..b6bb32c8 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php @@ -3,17 +3,18 @@ namespace Drupal\Tests\Component\Plugin; use Drupal\Component\Plugin\Definition\PluginDefinitionInterface; +use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Component\Plugin\Factory\DefaultFactory; use Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry; use Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface; use Drupal\plugin_test\Plugin\plugin_test\fruit\Kale; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Plugin\Factory\DefaultFactory * @group Plugin */ -class DefaultFactoryTest extends UnitTestCase { +class DefaultFactoryTest extends TestCase { /** * Tests getPluginClass() with a valid array plugin definition. @@ -47,11 +48,9 @@ public function testGetPluginClassWithValidObjectPluginDefinition() { * Tests getPluginClass() with a missing class definition. * * @covers ::getPluginClass - * - * @expectedException \Drupal\Component\Plugin\Exception\PluginException - * @expectedExceptionMessage The plugin (cherry) did not specify an instance class. */ public function testGetPluginClassWithMissingClassWithArrayPluginDefinition() { + $this->setExpectedException(PluginException::class, 'The plugin (cherry) did not specify an instance class.'); DefaultFactory::getPluginClass('cherry', []); } @@ -59,12 +58,10 @@ public function testGetPluginClassWithMissingClassWithArrayPluginDefinition() { * Tests getPluginClass() with a missing class definition. * * @covers ::getPluginClass - * - * @expectedException \Drupal\Component\Plugin\Exception\PluginException - * @expectedExceptionMessage The plugin (cherry) did not specify an instance class. */ public function testGetPluginClassWithMissingClassWithObjectPluginDefinition() { $plugin_definition = $this->getMock(PluginDefinitionInterface::class); + $this->setExpectedException(PluginException::class, 'The plugin (cherry) did not specify an instance class.'); DefaultFactory::getPluginClass('cherry', $plugin_definition); } @@ -72,11 +69,9 @@ public function testGetPluginClassWithMissingClassWithObjectPluginDefinition() { * Tests getPluginClass() with a not existing class definition. * * @covers ::getPluginClass - * - * @expectedException \Drupal\Component\Plugin\Exception\PluginException - * @expectedExceptionMessage Plugin (kiwifruit) instance class "\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit" does not exist. */ public function testGetPluginClassWithNotExistingClassWithArrayPluginDefinition() { + $this->setExpectedException(PluginException::class, 'Plugin (kiwifruit) instance class "\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit" does not exist.'); DefaultFactory::getPluginClass('kiwifruit', ['class' => '\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit']); } @@ -84,8 +79,6 @@ public function testGetPluginClassWithNotExistingClassWithArrayPluginDefinition( * Tests getPluginClass() with a not existing class definition. * * @covers ::getPluginClass - * - * @expectedException \Drupal\Component\Plugin\Exception\PluginException */ public function testGetPluginClassWithNotExistingClassWithObjectPluginDefinition() { $plugin_class = '\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit'; @@ -93,6 +86,7 @@ public function testGetPluginClassWithNotExistingClassWithObjectPluginDefinition $plugin_definition->expects($this->atLeastOnce()) ->method('getClass') ->willReturn($plugin_class); + $this->setExpectedException(PluginException::class); DefaultFactory::getPluginClass('kiwifruit', $plugin_definition); } @@ -128,12 +122,10 @@ public function testGetPluginClassWithInterfaceWithObjectPluginDefinition() { * Tests getPluginClass() with a required interface but no implementation. * * @covers ::getPluginClass - * - * @expectedException \Drupal\Component\Plugin\Exception\PluginException - * @expectedExceptionMessage Plugin "cherry" (Drupal\plugin_test\Plugin\plugin_test\fruit\Kale) must implement interface Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface. */ public function testGetPluginClassWithInterfaceAndInvalidClassWithArrayPluginDefinition() { $plugin_class = Kale::class; + $this->setExpectedException(PluginException::class, 'Plugin "cherry" (Drupal\plugin_test\Plugin\plugin_test\fruit\Kale) must implement interface Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface.'); DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class, 'provider' => 'core'], FruitInterface::class); } @@ -141,8 +133,6 @@ public function testGetPluginClassWithInterfaceAndInvalidClassWithArrayPluginDef * Tests getPluginClass() with a required interface but no implementation. * * @covers ::getPluginClass - * - * @expectedException \Drupal\Component\Plugin\Exception\PluginException */ public function testGetPluginClassWithInterfaceAndInvalidClassWithObjectPluginDefinition() { $plugin_class = Kale::class; @@ -150,6 +140,7 @@ public function testGetPluginClassWithInterfaceAndInvalidClassWithObjectPluginDe $plugin_definition->expects($this->atLeastOnce()) ->method('getClass') ->willReturn($plugin_class); + $this->setExpectedException(PluginException::class); DefaultFactory::getPluginClass('cherry', $plugin_definition, FruitInterface::class); } diff --git a/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryCachedTraitTest.php b/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryCachedTraitTest.php index 5218ec2a..2ed15bbf 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryCachedTraitTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryCachedTraitTest.php @@ -2,14 +2,14 @@ namespace Drupal\Tests\Component\Plugin\Discovery; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait * @uses \Drupal\Component\Plugin\Discovery\DiscoveryTrait * @group Plugin */ -class DiscoveryCachedTraitTest extends UnitTestCase { +class DiscoveryCachedTraitTest extends TestCase { /** * Data provider for testGetDefinition(). @@ -21,11 +21,11 @@ class DiscoveryCachedTraitTest extends UnitTestCase { * - Plugin name to query for. */ public function providerGetDefinition() { - return array( + return [ ['definition', [], ['plugin_name' => 'definition'], 'plugin_name'], ['definition', ['plugin_name' => 'definition'], [], 'plugin_name'], [NULL, ['plugin_name' => 'definition'], [], 'bad_plugin_name'], - ); + ]; } /** @@ -46,7 +46,7 @@ public function testGetDefinition($expected, $cached_definitions, $get_definitio $trait->expects($this->once()) ->method('getDefinitions') // Use a callback method, so we can perform the side-effects. - ->willReturnCallback(function() use ($reflection_definitions, $trait, $get_definitions) { + ->willReturnCallback(function () use ($reflection_definitions, $trait, $get_definitions) { $reflection_definitions->setValue($trait, $get_definitions); return $get_definitions; }); diff --git a/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryTraitTest.php b/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryTraitTest.php index 9f747f91..c37a4b5a 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryTraitTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Discovery/DiscoveryTraitTest.php @@ -2,13 +2,14 @@ namespace Drupal\Tests\Component\Plugin\Discovery; -use Drupal\Tests\UnitTestCase; +use Drupal\Component\Plugin\Exception\PluginNotFoundException; +use PHPUnit\Framework\TestCase; /** * @group Plugin * @coversDefaultClass \Drupal\Component\Plugin\Discovery\DiscoveryTrait */ -class DiscoveryTraitTest extends UnitTestCase { +class DiscoveryTraitTest extends TestCase { /** * Data provider for testDoGetDefinition(). @@ -19,10 +20,10 @@ class DiscoveryTraitTest extends UnitTestCase { * - Plugin ID to get, passed to doGetDefinition(). */ public function providerDoGetDefinition() { - return array( + return [ ['definition', ['plugin_name' => 'definition'], 'plugin_name'], [NULL, ['plugin_name' => 'definition'], 'bad_plugin_name'], - ); + ]; } /** @@ -51,14 +52,13 @@ public function testDoGetDefinition($expected, $definitions, $plugin_id) { * - Plugin ID to get, passed to doGetDefinition(). */ public function providerDoGetDefinitionException() { - return array( + return [ [FALSE, ['plugin_name' => 'definition'], 'bad_plugin_name'], - ); + ]; } /** * @covers ::doGetDefinition - * @expectedException \Drupal\Component\Plugin\Exception\PluginNotFoundException * @dataProvider providerDoGetDefinitionException * @uses \Drupal\Component\Plugin\Exception\PluginNotFoundException */ @@ -69,10 +69,8 @@ public function testDoGetDefinitionException($expected, $definitions, $plugin_id $method_ref = new \ReflectionMethod($trait, 'doGetDefinition'); $method_ref->setAccessible(TRUE); // Call doGetDefinition, with $exception_on_invalid always TRUE. - $this->assertSame( - $expected, - $method_ref->invoke($trait, $definitions, $plugin_id, TRUE) - ); + $this->setExpectedException(PluginNotFoundException::class); + $method_ref->invoke($trait, $definitions, $plugin_id, TRUE); } /** @@ -96,7 +94,6 @@ public function testGetDefinition($expected, $definitions, $plugin_id) { /** * @covers ::getDefinition - * @expectedException \Drupal\Component\Plugin\Exception\PluginNotFoundException * @dataProvider providerDoGetDefinitionException * @uses \Drupal\Component\Plugin\Exception\PluginNotFoundException */ @@ -109,10 +106,8 @@ public function testGetDefinitionException($expected, $definitions, $plugin_id) ->method('getDefinitions') ->willReturn($definitions); // Call getDefinition(), with $exception_on_invalid always TRUE. - $this->assertSame( - $expected, - $trait->getDefinition($plugin_id, TRUE) - ); + $this->setExpectedException(PluginNotFoundException::class); + $trait->getDefinition($plugin_id, TRUE); } /** @@ -123,10 +118,10 @@ public function testGetDefinitionException($expected, $definitions, $plugin_id) * - Plugin ID to look for. */ public function providerHasDefinition() { - return array( + return [ [TRUE, 'valid'], [FALSE, 'not_valid'], - ); + ]; } /** @@ -135,16 +130,16 @@ public function providerHasDefinition() { */ public function testHasDefinition($expected, $plugin_id) { $trait = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryTrait') - ->setMethods(array('getDefinition')) + ->setMethods(['getDefinition']) ->getMockForTrait(); // Set up our mocked getDefinition() to return TRUE for 'valid' and FALSE // for 'not_valid'. $trait->expects($this->once()) ->method('getDefinition') - ->will($this->returnValueMap(array( + ->will($this->returnValueMap([ ['valid', FALSE, TRUE], ['not_valid', FALSE, FALSE], - ))); + ])); // Call hasDefinition(). $this->assertSame( $expected, diff --git a/core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php b/core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php index bdab19c7..a44721bd 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php @@ -2,13 +2,13 @@ namespace Drupal\Tests\Component\Plugin\Discovery; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @group Plugin * @coversDefaultClass \Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator */ -class StaticDiscoveryDecoratorTest extends UnitTestCase { +class StaticDiscoveryDecoratorTest extends TestCase { /** * Helper method to provide a mocked callback object with expectations. @@ -23,7 +23,7 @@ class StaticDiscoveryDecoratorTest extends UnitTestCase { */ public function getRegisterDefinitionsCallback() { $mock_callable = $this->getMockBuilder('\stdClass') - ->setMethods(array('registerDefinitionsCallback')) + ->setMethods(['registerDefinitionsCallback']) ->getMock(); // Set expectations for the callback method. $mock_callable->expects($this->once()) @@ -62,7 +62,7 @@ public function testGetDefinition($expected, $has_register_definitions, $excepti // Mock our StaticDiscoveryDecorator. $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator') ->disableOriginalConstructor() - ->setMethods(array('registeredDefintionCallback')) + ->setMethods(['registeredDefintionCallback']) ->getMock(); // Set up the ::$registerDefinitions property. @@ -72,7 +72,7 @@ public function testGetDefinition($expected, $has_register_definitions, $excepti // Set the callback object on the mocked decorator. $ref_register_definitions->setValue( $mock_decorator, - array($this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback') + [$this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback'] ); } else { @@ -83,11 +83,11 @@ public function testGetDefinition($expected, $has_register_definitions, $excepti // Set up ::$definitions to an empty array. $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions'); $ref_definitions->setAccessible(TRUE); - $ref_definitions->setValue($mock_decorator, array()); + $ref_definitions->setValue($mock_decorator, []); // Mock a decorated object. $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface') - ->setMethods(array('getDefinitions')) + ->setMethods(['getDefinitions']) ->getMockForAbstractClass(); // Return our definitions from getDefinitions(). $mock_decorated->expects($this->once()) @@ -132,7 +132,7 @@ public function testGetDefinitions($has_register_definitions, $definitions) { // Mock our StaticDiscoveryDecorator. $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator') ->disableOriginalConstructor() - ->setMethods(array('registeredDefintionCallback')) + ->setMethods(['registeredDefintionCallback']) ->getMock(); // Set up the ::$registerDefinitions property. @@ -142,7 +142,7 @@ public function testGetDefinitions($has_register_definitions, $definitions) { // Set the callback object on the mocked decorator. $ref_register_definitions->setValue( $mock_decorator, - array($this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback') + [$this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback'] ); } else { @@ -153,11 +153,11 @@ public function testGetDefinitions($has_register_definitions, $definitions) { // Set up ::$definitions to an empty array. $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions'); $ref_definitions->setAccessible(TRUE); - $ref_definitions->setValue($mock_decorator, array()); + $ref_definitions->setValue($mock_decorator, []); // Mock a decorated object. $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface') - ->setMethods(array('getDefinitions')) + ->setMethods(['getDefinitions']) ->getMockForAbstractClass(); // Our mocked method will return any arguments sent to it. $mock_decorated->expects($this->once()) @@ -171,7 +171,7 @@ public function testGetDefinitions($has_register_definitions, $definitions) { // Exercise getDefinitions(). It calls parent::getDefinitions() but in this // case there will be no side-effects. - $this->assertArrayEquals( + $this->assertEquals( $definitions, $mock_decorator->getDefinitions() ); @@ -199,7 +199,7 @@ public function providerCall() { public function testCall($method, $args) { // Mock a decorated object. $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface') - ->setMethods(array($method)) + ->setMethods([$method]) ->getMockForAbstractClass(); // Our mocked method will return any arguments sent to it. $mock_decorated->expects($this->once()) @@ -220,9 +220,9 @@ function () { $ref_decorated->setValue($mock_decorator, $mock_decorated); // Exercise __call. - $this->assertArrayEquals( + $this->assertEquals( $args, - \call_user_func_array(array($mock_decorated, $method), $args) + \call_user_func_array([$mock_decorated, $method], $args) ); } diff --git a/core/tests/Drupal/Tests/Component/Plugin/Factory/ReflectionFactoryTest.php b/core/tests/Drupal/Tests/Component/Plugin/Factory/ReflectionFactoryTest.php index 8130b2df..7e8fbefd 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/Factory/ReflectionFactoryTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Factory/ReflectionFactoryTest.php @@ -10,13 +10,13 @@ namespace Drupal\Tests\Component\Plugin\Factory; use Drupal\Component\Plugin\Factory\ReflectionFactory; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @group Plugin * @coversDefaultClass \Drupal\Component\Plugin\Factory\ReflectionFactory */ -class ReflectionFactoryTest extends UnitTestCase { +class ReflectionFactoryTest extends TestCase { /** * Data provider for testGetInstanceArguments. @@ -88,7 +88,7 @@ public function providerGetInstanceArguments() { public function testCreateInstance($expected, $reflector_name, $plugin_id, $plugin_definition, $configuration) { // Create a mock DiscoveryInterface which can return our plugin definition. $mock_discovery = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface') - ->setMethods(array('getDefinition', 'getDefinitions', 'hasDefinition')) + ->setMethods(['getDefinition', 'getDefinitions', 'hasDefinition']) ->getMock(); $mock_discovery->expects($this->never())->method('getDefinitions'); $mock_discovery->expects($this->never())->method('hasDefinition'); @@ -172,9 +172,7 @@ public function __construct($plugin_id) { */ class ArgumentsMany { - public function __construct( - $configuration, $plugin_definition, $plugin_id, $foo = 'default_value', $what_am_i_doing_here = 'what_default' - ) { + public function __construct($configuration, $plugin_definition, $plugin_id, $foo = 'default_value', $what_am_i_doing_here = 'what_default') { // No-op. } diff --git a/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php index 60099320..de684885 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/PluginBaseTest.php @@ -2,24 +2,24 @@ namespace Drupal\Tests\Component\Plugin; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Plugin\PluginBase * @group Plugin */ -class PluginBaseTest extends UnitTestCase { +class PluginBaseTest extends TestCase { /** * @dataProvider providerTestGetPluginId * @covers ::getPluginId */ public function testGetPluginId($plugin_id, $expected) { - $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', array( - array(), + $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', [ + [], $plugin_id, - array(), - )); + [], + ]); $this->assertEquals($expected, $plugin_base->getPluginId()); } @@ -30,10 +30,10 @@ public function testGetPluginId($plugin_id, $expected) { * @return array */ public function providerTestGetPluginId() { - return array( - array('base_id', 'base_id'), - array('base_id:derivative', 'base_id:derivative'), - ); + return [ + ['base_id', 'base_id'], + ['base_id:derivative', 'base_id:derivative'], + ]; } /** @@ -42,11 +42,11 @@ public function providerTestGetPluginId() { */ public function testGetBaseId($plugin_id, $expected) { /** @var \Drupal\Component\Plugin\PluginBase|\PHPUnit_Framework_MockObject_MockObject $plugin_base */ - $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', array( - array(), + $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', [ + [], $plugin_id, - array(), - )); + [], + ]); $this->assertEquals($expected, $plugin_base->getBaseId()); } @@ -57,10 +57,10 @@ public function testGetBaseId($plugin_id, $expected) { * @return array */ public function providerTestGetBaseId() { - return array( - array('base_id', 'base_id'), - array('base_id:derivative', 'base_id'), - ); + return [ + ['base_id', 'base_id'], + ['base_id:derivative', 'base_id'], + ]; } @@ -70,11 +70,11 @@ public function providerTestGetBaseId() { */ public function testGetDerivativeId($plugin_id = NULL, $expected = NULL) { /** @var \Drupal\Component\Plugin\PluginBase|\PHPUnit_Framework_MockObject_MockObject $plugin_base */ - $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', array( - array(), + $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', [ + [], $plugin_id, - array(), - )); + [], + ]); $this->assertEquals($expected, $plugin_base->getDerivativeId()); } @@ -85,23 +85,23 @@ public function testGetDerivativeId($plugin_id = NULL, $expected = NULL) { * @return array */ public function providerTestGetDerivativeId() { - return array( - array('base_id', NULL), - array('base_id:derivative', 'derivative'), - ); + return [ + ['base_id', NULL], + ['base_id:derivative', 'derivative'], + ]; } /** * @covers ::getPluginDefinition */ public function testGetPluginDefinition() { - $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', array( - array(), + $plugin_base = $this->getMockForAbstractClass('Drupal\Component\Plugin\PluginBase', [ + [], 'plugin_id', - array('value', array('key' => 'value')), - )); + ['value', ['key' => 'value']], + ]); - $this->assertEquals(array('value', array('key' => 'value')), $plugin_base->getPluginDefinition()); + $this->assertEquals(['value', ['key' => 'value']], $plugin_base->getPluginDefinition()); } } diff --git a/core/tests/Drupal/Tests/Component/Plugin/PluginManagerBaseTest.php b/core/tests/Drupal/Tests/Component/Plugin/PluginManagerBaseTest.php index 608479a9..a4dd6a76 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/PluginManagerBaseTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/PluginManagerBaseTest.php @@ -3,13 +3,13 @@ namespace Drupal\Tests\Component\Plugin; use Drupal\Component\Plugin\Exception\PluginNotFoundException; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\Plugin\PluginManagerBase * @group Plugin */ -class PluginManagerBaseTest extends UnitTestCase { +class PluginManagerBaseTest extends TestCase { /** * A callback method for mocking FactoryInterface objects. @@ -21,10 +21,10 @@ public function createInstanceCallback() { if ('invalid' == $plugin_id) { throw new PluginNotFoundException($plugin_id); } - return array( + return [ 'plugin_id' => $plugin_id, 'configuration' => $configuration, - ); + ]; } /** @@ -32,11 +32,11 @@ public function createInstanceCallback() { */ public function getMockFactoryInterface($expects_count) { $mock_factory = $this->getMockBuilder('Drupal\Component\Plugin\Factory\FactoryInterface') - ->setMethods(array('createInstance')) + ->setMethods(['createInstance']) ->getMockForAbstractClass(); $mock_factory->expects($this->exactly($expects_count)) ->method('createInstance') - ->willReturnCallback(array($this, 'createInstanceCallback')); + ->willReturnCallback([$this, 'createInstanceCallback']); return $mock_factory; } @@ -55,10 +55,10 @@ public function testCreateInstance() { $factory_ref->setValue($manager, $this->getMockFactoryInterface(1)); // Finally the test. - $configuration_array = array('config' => 'something'); + $configuration_array = ['config' => 'something']; $result = $manager->createInstance('valid', $configuration_array); $this->assertEquals('valid', $result['plugin_id']); - $this->assertArrayEquals($configuration_array, $result['configuration']); + $this->assertEquals($configuration_array, $result['configuration']); } /** @@ -75,19 +75,19 @@ public function testCreateInstanceFallback() { $factory_ref->setAccessible(TRUE); // Set up the configuration array. - $configuration_array = array('config' => 'something'); + $configuration_array = ['config' => 'something']; // Test with fallback interface and valid plugin_id. $factory_ref->setValue($manager, $this->getMockFactoryInterface(1)); $no_fallback_result = $manager->createInstance('valid', $configuration_array); $this->assertEquals('valid', $no_fallback_result['plugin_id']); - $this->assertArrayEquals($configuration_array, $no_fallback_result['configuration']); + $this->assertEquals($configuration_array, $no_fallback_result['configuration']); // Test with fallback interface and invalid plugin_id. $factory_ref->setValue($manager, $this->getMockFactoryInterface(2)); $fallback_result = $manager->createInstance('invalid', $configuration_array); $this->assertEquals('invalid_fallback', $fallback_result['plugin_id']); - $this->assertArrayEquals($configuration_array, $fallback_result['configuration']); + $this->assertEquals($configuration_array, $fallback_result['configuration']); } } diff --git a/core/tests/Drupal/Tests/Component/Plugin/StubFallbackPluginManager.php b/core/tests/Drupal/Tests/Component/Plugin/StubFallbackPluginManager.php index 8dc4f087..50283c66 100644 --- a/core/tests/Drupal/Tests/Component/Plugin/StubFallbackPluginManager.php +++ b/core/tests/Drupal/Tests/Component/Plugin/StubFallbackPluginManager.php @@ -20,7 +20,7 @@ class StubFallbackPluginManager extends PluginManagerBase implements FallbackPlu /** * {@inheritdoc} */ - public function getFallbackPluginId($plugin_id, array $configuration = array()) { + public function getFallbackPluginId($plugin_id, array $configuration = []) { // Minimally implement getFallbackPluginId so that we can test it. return $plugin_id . '_fallback'; } diff --git a/core/tests/Drupal/Tests/Component/ProxyBuilder/ProxyBuilderTest.php b/core/tests/Drupal/Tests/Component/ProxyBuilder/ProxyBuilderTest.php index f81ca0da..1b06ddef 100644 --- a/core/tests/Drupal/Tests/Component/ProxyBuilder/ProxyBuilderTest.php +++ b/core/tests/Drupal/Tests/Component/ProxyBuilder/ProxyBuilderTest.php @@ -8,13 +8,13 @@ namespace Drupal\Tests\Component\ProxyBuilder; use Drupal\Component\ProxyBuilder\ProxyBuilder; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Drupal\Component\ProxyBuilder\ProxyBuilder * @group proxy_builder */ -class ProxyBuilderTest extends UnitTestCase { +class ProxyBuilderTest extends TestCase { /** * The tested proxy builder. @@ -381,7 +381,7 @@ public function methodWithParameter($parameter) { class TestServiceComplexMethod { - public function complexMethod($parameter, callable $function, TestServiceNoMethod $test_service = NULL, array &$elements = array()) { + public function complexMethod($parameter, callable $function, TestServiceNoMethod $test_service = NULL, array &$elements = []) { } diff --git a/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php b/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php index 5d4cad94..27445b15 100644 --- a/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php +++ b/core/tests/Drupal/Tests/Component/Render/FormattableMarkupTest.php @@ -3,7 +3,7 @@ namespace Drupal\Tests\Component\Render; use Drupal\Component\Render\FormattableMarkup; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * Tests the TranslatableMarkup class. @@ -11,7 +11,7 @@ * @coversDefaultClass \Drupal\Component\Render\FormattableMarkup * @group utility */ -class FormattableMarkupTest extends UnitTestCase { +class FormattableMarkupTest extends TestCase { /** * The error message of the last error in the error handler. diff --git a/core/tests/Drupal/Tests/Component/Render/HtmlEscapedTextTest.php b/core/tests/Drupal/Tests/Component/Render/HtmlEscapedTextTest.php index fa6c325d..5fc3902f 100644 --- a/core/tests/Drupal/Tests/Component/Render/HtmlEscapedTextTest.php +++ b/core/tests/Drupal/Tests/Component/Render/HtmlEscapedTextTest.php @@ -4,7 +4,7 @@ use Drupal\Component\Render\HtmlEscapedText; use Drupal\Component\Render\MarkupInterface; -use Drupal\Tests\UnitTestCase; +use PHPUnit\Framework\TestCase; /** * Tests the HtmlEscapedText class. @@ -12,7 +12,7 @@ * @coversDefaultClass \Drupal\Component\Render\HtmlEscapedText * @group utility */ -class HtmlEscapedTextTest extends UnitTestCase { +class HtmlEscapedTextTest extends TestCase { /** * @covers ::__toString @@ -31,23 +31,23 @@ public function testToString($text, $expected, $message) { * * @see testToString() */ - function providerToString() { + public function providerToString() { // Checks that invalid multi-byte sequences are escaped. - $tests[] = array("Foo\xC0barbaz", 'Foo�barbaz', 'Escapes invalid sequence "Foo\xC0barbaz"'); - $tests[] = array("\xc2\"", '�"', 'Escapes invalid sequence "\xc2\""'); - $tests[] = array("Fooÿñ", "Fooÿñ", 'Does not escape valid sequence "Fooÿñ"'); + $tests[] = ["Foo\xC0barbaz", 'Foo�barbaz', 'Escapes invalid sequence "Foo\xC0barbaz"']; + $tests[] = ["\xc2\"", '�"', 'Escapes invalid sequence "\xc2\""']; + $tests[] = ["Fooÿñ", "Fooÿñ", 'Does not escape valid sequence "Fooÿñ"']; // Checks that special characters are escaped. $script_tag = $this->prophesize(MarkupInterface::class); $script_tag->__toString()->willReturn('', 'script', 'HTML tag stripping -- simple script without special characters.', - ), - array( + ], + [ '', 'script', 'HTML tag stripping evasion -- non whitespace character after tag name.', - ), - array( + ], + [ '', 'script', 'HTML tag stripping evasion -- no space between tag and attribute.', - ), + ], // Null between < and tag name works at least with IE6. - array( + [ "<\0scr\0ipt>alert(0)", 'ipt', 'HTML tag stripping evasion -- breaking HTML with nulls.', - ), - array( + ], + [ "", 'script', 'HTML tag stripping evasion -- filter just removing "script".', - ), - array( + ], + [ '<', 'script', 'HTML tag stripping evasion -- double opening brackets.', - ), - array( + ], + [ '', 'script', 'HTML tag stripping evasion -- a malformed image tag.', - array('img'), - ), - array( + ['img'], + ], + [ '
', 'script', 'HTML tag stripping evasion -- script in a blockqoute.', - array('blockquote'), - ), - array( + ['blockquote'], + ], + [ "", 'script', 'HTML tag stripping evasion -- script within a comment.', - ), + ], // Dangerous attributes removal. - array( + [ '

', 'onmouseover', 'HTML filter attributes removal -- events, no evasion.', - array('p'), - ), - array( + ['p'], + ], + [ '

  • ', 'style', 'HTML filter attributes removal -- style, no evasion.', - array('li'), - ), - array( + ['li'], + ], + [ '', 'onerror', 'HTML filter attributes removal evasion -- spaces before equals sign.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'onabort', 'HTML filter attributes removal evasion -- non alphanumeric characters before equals sign.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'onmediaerror', 'HTML filter attributes removal evasion -- varying case.', - array('img'), - ), + ['img'], + ], // Works at least with IE6. - array( + [ "", 'focus', 'HTML filter attributes removal evasion -- breaking with nulls.', - array('img'), - ), + ['img'], + ], // Only whitelisted scheme names allowed in attributes. - array( + [ '', 'javascript', 'HTML scheme clearing -- no evasion.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'javascript', 'HTML scheme clearing evasion -- no quotes.', - array('img'), - ), + ['img'], + ], // A bit like CVE-2006-0070. - array( + [ '', 'javascript', 'HTML scheme clearing evasion -- no alert ;)', - array('img'), - ), - array( + ['img'], + ], + [ '', 'javascript', 'HTML scheme clearing evasion -- grave accents.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'javascript', 'HTML scheme clearing -- rare attribute.', - array('img'), - ), - array( + ['img'], + ], + [ '
  • '); + $data[] = [' + * http://example.com/foo?tips=bar + * + * @param {jQuery} $tour + * A jQuery element pointing to a `
      ` containing tour items. + * @param {jQuery} $document + * A jQuery element pointing to the document within which the elements + * should be sought. + * + * @see Drupal.tour.views.ToggleTourView#_getDocument + */ + _removeIrrelevantTourItems($tour, $document) { + let removals = false; + const tips = /tips=([^&]+)/.exec(queryString); + $tour + .find('li') + .each(function () { + const $this = $(this); + const itemId = $this.attr('data-id'); + const itemClass = $this.attr('data-class'); + // If the query parameter 'tips' is set, remove all tips that don't + // have the matching class. + if (tips && !$(this).hasClass(tips[1])) { + removals = true; + $this.remove(); + return; + } + // Remove tip from the DOM if there is no corresponding page element. + if ((!itemId && !itemClass) || + (itemId && $document.find(`#${itemId}`).length) || + (itemClass && $document.find(`.${itemClass}`).length)) { + return; + } + removals = true; + $this.remove(); + }); + + // If there were removals, we'll have to do some clean-up. + if (removals) { + const total = $tour.find('li').length; + if (!total) { + this.model.set({ tour: [] }); + } + + $tour + .find('li') + // Rebuild the progress data. + .each(function (index) { + const progress = Drupal.t('!tour_item of !total', { '!tour_item': index + 1, '!total': total }); + $(this).find('.tour-progress').text(progress); + }) + // Update the last item to have "End tour" as the button. + .eq(-1) + .attr('data-text', Drupal.t('End tour')); + } + }, + + }); +}(jQuery, Backbone, Drupal, document)); diff --git a/core/modules/tour/js/tour.js b/core/modules/tour/js/tour.js index 2c7050f7..f20796a4 100644 --- a/core/modules/tour/js/tour.js +++ b/core/modules/tour/js/tour.js @@ -1,33 +1,15 @@ /** - * @file - * Attaches behaviors for the Tour module's toolbar tab. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Backbone, Drupal, document) { - - 'use strict'; - var queryString = decodeURI(window.location.search); - /** - * Attaches the tour's toolbar tab behavior. - * - * It uses the query string for: - * - tour: When ?tour=1 is present, the tour will start automatically after - * the page has loaded. - * - tips: Pass ?tips=class in the url to filter the available tips to the - * subset which match the given class. - * - * @example - * http://example.com/foo?tour=1&tips=bar - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attach tour functionality on `tour` events. - */ Drupal.behaviors.tour = { - attach: function (context) { + attach: function attach(context) { $('body').once('tour').each(function () { var model = new Drupal.tour.models.StateModel(); new Drupal.tour.views.ToggleTourView({ @@ -35,16 +17,10 @@ model: model }); - model - // Allow other scripts to respond to tour events. - .on('change:isActive', function (model, isActive) { - $(document).trigger((isActive) ? 'drupalTourStarted' : 'drupalTourStopped'); - }) - // Initialization: check whether a tour is available on the current - // page. - .set('tour', $(context).find('ol#tour')); + model.on('change:isActive', function (model, isActive) { + $(document).trigger(isActive ? 'drupalTourStarted' : 'drupalTourStopped'); + }).set('tour', $(context).find('ol#tour')); - // Start the tour immediately if toggled via query string. if (/tour=?/i.test(queryString)) { model.set('isActive', true); } @@ -52,99 +28,37 @@ } }; - /** - * @namespace - */ Drupal.tour = Drupal.tour || { - - /** - * @namespace Drupal.tour.models - */ models: {}, - /** - * @namespace Drupal.tour.views - */ views: {} }; - /** - * Backbone Model for tours. - * - * @constructor - * - * @augments Backbone.Model - */ - Drupal.tour.models.StateModel = Backbone.Model.extend(/** @lends Drupal.tour.models.StateModel# */{ - - /** - * @type {object} - */ - defaults: /** @lends Drupal.tour.models.StateModel# */{ - - /** - * Indicates whether the Drupal root window has a tour. - * - * @type {Array} - */ + Drupal.tour.models.StateModel = Backbone.Model.extend({ + defaults: { tour: [], - /** - * Indicates whether the tour is currently running. - * - * @type {bool} - */ isActive: false, - /** - * Indicates which tour is the active one (necessary to cleanly stop). - * - * @type {Array} - */ activeTour: [] } }); - Drupal.tour.views.ToggleTourView = Backbone.View.extend(/** @lends Drupal.tour.views.ToggleTourView# */{ - - /** - * @type {object} - */ - events: {click: 'onClick'}, + Drupal.tour.views.ToggleTourView = Backbone.View.extend({ + events: { click: 'onClick' }, - /** - * Handles edit mode toggle interactions. - * - * @constructs - * - * @augments Backbone.View - */ - initialize: function () { + initialize: function initialize() { this.listenTo(this.model, 'change:tour change:isActive', this.render); this.listenTo(this.model, 'change:isActive', this.toggleTour); }, - - /** - * @inheritdoc - * - * @return {Drupal.tour.views.ToggleTourView} - * The `ToggleTourView` view. - */ - render: function () { - // Render the visibility. + render: function render() { this.$el.toggleClass('hidden', this._getTour().length === 0); - // Render the state. + var isActive = this.model.get('isActive'); - this.$el.find('button') - .toggleClass('is-active', isActive) - .prop('aria-pressed', isActive); + this.$el.find('button').toggleClass('is-active', isActive).prop('aria-pressed', isActive); return this; }, - - /** - * Model change handler; starts or stops the tour. - */ - toggleTour: function () { + toggleTour: function toggleTour() { if (this.model.get('isActive')) { var $tour = this._getTour(); this._removeIrrelevantTourItems($tour, this._getDocument()); @@ -152,119 +66,65 @@ if ($tour.find('li').length) { $tour.joyride({ autoStart: true, - postRideCallback: function () { that.model.set('isActive', false); }, - // HTML segments for tip layout. + postRideCallback: function postRideCallback() { + that.model.set('isActive', false); + }, + template: { link: '×', button: '' } }); - this.model.set({isActive: true, activeTour: $tour}); + this.model.set({ isActive: true, activeTour: $tour }); } - } - else { + } else { this.model.get('activeTour').joyride('destroy'); - this.model.set({isActive: false, activeTour: []}); + this.model.set({ isActive: false, activeTour: [] }); } }, - - /** - * Toolbar tab click event handler; toggles isActive. - * - * @param {jQuery.Event} event - * The click event. - */ - onClick: function (event) { + onClick: function onClick(event) { this.model.set('isActive', !this.model.get('isActive')); event.preventDefault(); event.stopPropagation(); }, - - /** - * Gets the tour. - * - * @return {jQuery} - * A jQuery element pointing to a `
        ` containing tour items. - */ - _getTour: function () { + _getTour: function _getTour() { return this.model.get('tour'); }, - - /** - * Gets the relevant document as a jQuery element. - * - * @return {jQuery} - * A jQuery element pointing to the document within which a tour would be - * started given the current state. - */ - _getDocument: function () { + _getDocument: function _getDocument() { return $(document); }, - - /** - * Removes tour items for elements that don't have matching page elements. - * - * Or that are explicitly filtered out via the 'tips' query string. - * - * @example - *
    - * http://example.com/foo?tips=bar - * - * @param {jQuery} $tour - * A jQuery element pointing to a `
      ` containing tour items. - * @param {jQuery} $document - * A jQuery element pointing to the document within which the elements - * should be sought. - * - * @see Drupal.tour.views.ToggleTourView#_getDocument - */ - _removeIrrelevantTourItems: function ($tour, $document) { + _removeIrrelevantTourItems: function _removeIrrelevantTourItems($tour, $document) { var removals = false; var tips = /tips=([^&]+)/.exec(queryString); - $tour - .find('li') - .each(function () { - var $this = $(this); - var itemId = $this.attr('data-id'); - var itemClass = $this.attr('data-class'); - // If the query parameter 'tips' is set, remove all tips that don't - // have the matching class. - if (tips && !$(this).hasClass(tips[1])) { - removals = true; - $this.remove(); - return; - } - // Remove tip from the DOM if there is no corresponding page element. - if ((!itemId && !itemClass) || - (itemId && $document.find('#' + itemId).length) || - (itemClass && $document.find('.' + itemClass).length)) { - return; - } + $tour.find('li').each(function () { + var $this = $(this); + var itemId = $this.attr('data-id'); + var itemClass = $this.attr('data-class'); + + if (tips && !$(this).hasClass(tips[1])) { removals = true; $this.remove(); - }); + return; + } + + if (!itemId && !itemClass || itemId && $document.find('#' + itemId).length || itemClass && $document.find('.' + itemClass).length) { + return; + } + removals = true; + $this.remove(); + }); - // If there were removals, we'll have to do some clean-up. if (removals) { var total = $tour.find('li').length; if (!total) { - this.model.set({tour: []}); + this.model.set({ tour: [] }); } - $tour - .find('li') - // Rebuild the progress data. - .each(function (index) { - var progress = Drupal.t('!tour_item of !total', {'!tour_item': index + 1, '!total': total}); - $(this).find('.tour-progress').text(progress); - }) - // Update the last item to have "End tour" as the button. - .eq(-1) - .attr('data-text', Drupal.t('End tour')); + $tour.find('li').each(function (index) { + var progress = Drupal.t('!tour_item of !total', { '!tour_item': index + 1, '!total': total }); + $(this).find('.tour-progress').text(progress); + }).eq(-1).attr('data-text', Drupal.t('End tour')); } } - }); - -})(jQuery, Backbone, Drupal, document); +})(jQuery, Backbone, Drupal, document); \ No newline at end of file diff --git a/core/modules/tour/src/Entity/Tour.php b/core/modules/tour/src/Entity/Tour.php index 290d3f8f..9a8e1666 100644 --- a/core/modules/tour/src/Entity/Tour.php +++ b/core/modules/tour/src/Entity/Tour.php @@ -13,8 +13,10 @@ * id = "tour", * label = @Translation("Tour"), * handlers = { - * "view_builder" = "Drupal\tour\TourViewBuilder" + * "view_builder" = "Drupal\tour\TourViewBuilder", + * "access" = "Drupal\tour\TourAccessControlHandler", * }, + * admin_permission = "administer site configuration", * entity_keys = { * "id" = "id", * "label" = "label" @@ -59,7 +61,7 @@ class Tour extends ConfigEntityBase implements TourInterface { * * @var array */ - protected $routes = array(); + protected $routes = []; /** * The routes on which this tour should be displayed, keyed by route id. @@ -80,7 +82,7 @@ class Tour extends ConfigEntityBase implements TourInterface { * * @var array */ - protected $tips = array(); + protected $tips = []; /** * {@inheritdoc} @@ -109,7 +111,7 @@ public function getTip($id) { * {@inheritdoc} */ public function getTips() { - $tips = array(); + $tips = []; foreach ($this->tips as $id => $tip) { $tips[] = $this->getTip($id); } @@ -136,9 +138,9 @@ public function getModule() { */ public function hasMatchingRoute($route_name, $route_params) { if (!isset($this->keyedRoutes)) { - $this->keyedRoutes = array(); + $this->keyedRoutes = []; foreach ($this->getRoutes() as $route) { - $this->keyedRoutes[$route['route_name']] = isset($route['route_params']) ? $route['route_params'] : array(); + $this->keyedRoutes[$route['route_name']] = isset($route['route_params']) ? $route['route_params'] : []; } } if (!isset($this->keyedRoutes[$route_name])) { diff --git a/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php b/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php index f7d27938..268741a8 100644 --- a/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php +++ b/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php @@ -116,7 +116,7 @@ public function getAttributes() { public function getOutput() { $output = '

      ' . Html::escape($this->getLabel()) . '

      '; $output .= '

      ' . $this->token->replace($this->getBody()) . '

      '; - return array('#markup' => $output); + return ['#markup' => $output]; } } diff --git a/core/modules/tour/src/Tests/TourTestBase.php b/core/modules/tour/src/Tests/TourTestBase.php index 8383c99d..e1396507 100644 --- a/core/modules/tour/src/Tests/TourTestBase.php +++ b/core/modules/tour/src/Tests/TourTestBase.php @@ -4,8 +4,13 @@ use Drupal\simpletest\WebTestBase; +@trigger_error('\Drupal\tour\Tests\TourTestBase is deprecated in 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\tour\Functional\TourTestBase.', E_USER_DEPRECATED); + /** * Base class for testing Tour functionality. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\tour\Functional\TourTestBase instead. */ abstract class TourTestBase extends WebTestBase { @@ -29,7 +34,7 @@ abstract class TourTestBase extends WebTestBase { * $this->assertTourTips($tips); * @endcode */ - public function assertTourTips($tips = array()) { + public function assertTourTips($tips = []) { // Get the rendered tips and their data-id and data-class attributes. if (empty($tips)) { // Tips are rendered as
    1. elements inside
        . @@ -51,11 +56,11 @@ public function assertTourTips($tips = array()) { foreach ($tips as $tip) { if (!empty($tip['data-id'])) { $elements = \PHPUnit_Util_XML::cssSelect('#' . $tip['data-id'], TRUE, $this->content, TRUE); - $this->assertTrue(!empty($elements) && count($elements) === 1, format_string('Found corresponding page element for tour tip with id #%data-id', array('%data-id' => $tip['data-id']))); + $this->assertTrue(!empty($elements) && count($elements) === 1, format_string('Found corresponding page element for tour tip with id #%data-id', ['%data-id' => $tip['data-id']])); } elseif (!empty($tip['data-class'])) { $elements = \PHPUnit_Util_XML::cssSelect('.' . $tip['data-class'], TRUE, $this->content, TRUE); - $this->assertFalse(empty($elements), format_string('Found corresponding page element for tour tip with class .%data-class', array('%data-class' => $tip['data-class']))); + $this->assertFalse(empty($elements), format_string('Found corresponding page element for tour tip with class .%data-class', ['%data-class' => $tip['data-class']])); } else { // It's a modal. @@ -63,7 +68,7 @@ public function assertTourTips($tips = array()) { } $total++; } - $this->pass(format_string('Total %total Tips tested of which %modals modal(s).', array('%total' => $total, '%modals' => $modals))); + $this->pass(format_string('Total %total Tips tested of which %modals modal(s).', ['%total' => $total, '%modals' => $modals])); } } diff --git a/core/modules/tour/src/TourAccessControlHandler.php b/core/modules/tour/src/TourAccessControlHandler.php new file mode 100644 index 00000000..a0d427a0 --- /dev/null +++ b/core/modules/tour/src/TourAccessControlHandler.php @@ -0,0 +1,28 @@ + $entity) { $tips = $entity->getTips(); $count = count($tips); - $list_items = array(); + $list_items = []; foreach ($tips as $index => $tip) { if ($output = $tip->getOutput()) { - $attributes = array( - 'class' => array( + $attributes = [ + 'class' => [ 'tip-module-' . Html::cleanCssIdentifier($entity->getModule()), 'tip-type-' . Html::cleanCssIdentifier($tip->getPluginId()), 'tip-' . Html::cleanCssIdentifier($tip->id()), - ), - ); - $list_items[] = array( + ], + ]; + $list_items[] = [ 'output' => $output, - 'counter' => array( + 'counter' => [ '#type' => 'container', - '#attributes' => array( - 'class' => array( + '#attributes' => [ + 'class' => [ 'tour-progress', - ), - ), - '#children' => t('@tour_item of @total', array('@tour_item' => $index + 1, '@total' => $count)), - ), + ], + ], + '#children' => t('@tour_item of @total', ['@tour_item' => $index + 1, '@total' => $count]), + ], '#wrapper_attributes' => $tip->getAttributes() + $attributes, - ); + ]; } } // If there is at least one tour item, build the tour. @@ -49,20 +49,20 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la end($list_items); $key = key($list_items); $list_items[$key]['#wrapper_attributes']['data-text'] = t('End tour'); - $build[$entity_id] = array( + $build[$entity_id] = [ '#theme' => 'item_list', '#items' => $list_items, '#list_type' => 'ol', - '#attributes' => array( + '#attributes' => [ 'id' => 'tour', - 'class' => array( + 'class' => [ 'hidden', - ), - ), + ], + ], '#cache' => [ 'tags' => $entity->getCacheTags(), ], - ); + ]; } } // If at least one tour was built, attach the tour library. diff --git a/core/modules/tour/src/Tests/TourCacheTagsTest.php b/core/modules/tour/tests/src/Functional/TourCacheTagsTest.php similarity index 90% rename from core/modules/tour/src/Tests/TourCacheTagsTest.php rename to core/modules/tour/tests/src/Functional/TourCacheTagsTest.php index 4f2164e1..daed6fa2 100644 --- a/core/modules/tour/src/Tests/TourCacheTagsTest.php +++ b/core/modules/tour/tests/src/Functional/TourCacheTagsTest.php @@ -1,9 +1,9 @@ verifyPageCache($url, 'HIT', $expected_tags); @@ -68,6 +69,7 @@ public function testRenderedTour() { // Verify a cache hit. $expected_tags = [ 'config:user.role.anonymous', + 'http_response', 'rendered', ]; $this->verifyPageCache($url, 'HIT', $expected_tags); diff --git a/core/modules/tour/src/Tests/TourHelpPageTest.php b/core/modules/tour/tests/src/Functional/TourHelpPageTest.php similarity index 95% rename from core/modules/tour/src/Tests/TourHelpPageTest.php rename to core/modules/tour/tests/src/Functional/TourHelpPageTest.php index 8a41eb9f..ad60df10 100644 --- a/core/modules/tour/src/Tests/TourHelpPageTest.php +++ b/core/modules/tour/tests/src/Functional/TourHelpPageTest.php @@ -1,15 +1,15 @@ assertText($title); - $this->assertNoLink($title); + $this->assertSession()->linkNotExistsExact($title); } else { $this->assertNoText($title); diff --git a/core/modules/tour/src/Tests/TourTest.php b/core/modules/tour/tests/src/Functional/TourTest.php similarity index 87% rename from core/modules/tour/src/Tests/TourTest.php rename to core/modules/tour/tests/src/Functional/TourTest.php index 78304c6e..55f3743f 100644 --- a/core/modules/tour/src/Tests/TourTest.php +++ b/core/modules/tour/tests/src/Functional/TourTest.php @@ -1,6 +1,6 @@ array(), - ); + protected $tips = [ + 'tour-test-1' => [], + ]; /** * {@inheritdoc} @@ -57,18 +57,18 @@ public function testTourFunctionality() { $this->drupalGet('tour-test-1'); // Test the TourTestBase class assertTourTips() method. - $tips = array(); - $tips[] = array('data-id' => 'tour-test-1'); - $tips[] = array('data-class' => 'tour-test-5'); + $tips = []; + $tips[] = ['data-id' => 'tour-test-1']; + $tips[] = ['data-class' => 'tour-test-5']; $this->assertTourTips($tips); $this->assertTourTips(); - $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./p//a[@href=:href and contains(., :text)]]', array( + $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./p//a[@href=:href and contains(., :text)]]', [ ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1', ':data_id' => 'tour-test-1', ':href' => \Drupal::url('', [], ['absolute' => TRUE]), ':text' => 'Drupal', - )); + ]); $this->assertEqual(count($elements), 1, 'Found Token replacement.'); $elements = $this->cssSelect("li[data-id=tour-test-1] h2:contains('The first tip')"); @@ -104,43 +104,43 @@ public function testTourFunctionality() { $this->assertNotEqual(count($elements), 1, 'Did not find English variant of tip 1.'); // Programmatically create a tour for use through the remainder of the test. - $tour = Tour::create(array( + $tour = Tour::create([ 'id' => 'tour-entity-create-test-en', 'label' => 'Tour test english', 'langcode' => 'en', 'module' => 'system', - 'routes' => array( - array('route_name' => 'tour_test.1'), - ), - 'tips' => array( - 'tour-test-1' => array( + 'routes' => [ + ['route_name' => 'tour_test.1'], + ], + 'tips' => [ + 'tour-test-1' => [ 'id' => 'tour-code-test-1', 'plugin' => 'text', 'label' => 'The rain in spain', 'body' => 'Falls mostly on the plain.', 'weight' => '100', - 'attributes' => array( + 'attributes' => [ 'data-id' => 'tour-code-test-1', - ), - ), - 'tour-code-test-2' => array( + ], + ], + 'tour-code-test-2' => [ 'id' => 'tour-code-test-2', 'plugin' => 'image', 'label' => 'The awesome image', 'url' => 'http://local/image.png', 'weight' => 1, - 'attributes' => array( + 'attributes' => [ 'data-id' => 'tour-code-test-2' - ), - ), - ), - )); + ], + ], + ], + ]); $tour->save(); // Ensure that a tour entity has the expected dependencies based on plugin // providers and the module named in the configuration entity. $dependencies = $tour->calculateDependencies()->getDependencies(); - $this->assertEqual($dependencies['module'], array('system', 'tour_test')); + $this->assertEqual($dependencies['module'], ['system', 'tour_test']); $this->drupalGet('tour-test-1'); @@ -167,21 +167,21 @@ public function testTourFunctionality() { // Navigate to tour-test-3 and verify the tour_test_1 tip is found with // appropriate classes. $this->drupalGet('tour-test-3/foo'); - $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', array( + $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', [ ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1', ':data_id' => 'tour-test-1', ':text' => 'The first tip', - )); + ]); $this->assertEqual(count($elements), 1, 'Found English variant of tip 1.'); // Navigate to tour-test-3 and verify the tour_test_1 tip is not found with // appropriate classes. $this->drupalGet('tour-test-3/bar'); - $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', array( + $elements = $this->xpath('//li[@data-id=:data_id and @class=:classes and ./h2[contains(., :text)]]', [ ':classes' => 'tip-module-tour-test tip-type-text tip-tour-test-1', ':data_id' => 'tour-test-1', ':text' => 'The first tip', - )); + ]); $this->assertEqual(count($elements), 0, 'Did not find English variant of tip 1.'); } diff --git a/core/modules/tour/tests/src/Functional/TourTestBase.php b/core/modules/tour/tests/src/Functional/TourTestBase.php new file mode 100644 index 00000000..522e8e6f --- /dev/null +++ b/core/modules/tour/tests/src/Functional/TourTestBase.php @@ -0,0 +1,73 @@ +assertTourTips(); + * + * // Advanced example. The following would be used for multipage or + * // targeting a specific subset of tips. + * $tips = array(); + * $tips[] = array('data-id' => 'foo'); + * $tips[] = array('data-id' => 'bar'); + * $tips[] = array('data-class' => 'baz'); + * $this->assertTourTips($tips); + * @endcode + */ + public function assertTourTips($tips = []) { + // Get the rendered tips and their data-id and data-class attributes. + if (empty($tips)) { + // Tips are rendered as
      1. elements inside
          . + $rendered_tips = $this->xpath('//ol[@id = "tour"]//li[starts-with(@class, "tip")]'); + foreach ($rendered_tips as $rendered_tip) { + $tips[] = [ + 'data-id' => $rendered_tip->getAttribute('data-id'), + 'data-class' => $rendered_tip->getAttribute('data-class'), + ]; + } + } + + // If the tips are still empty we need to fail. + if (empty($tips)) { + $this->fail('Could not find tour tips on the current page.'); + } + else { + // Check for corresponding page elements. + $total = 0; + $modals = 0; + $raw_content = $this->getSession()->getPage()->getContent(); + foreach ($tips as $tip) { + if (!empty($tip['data-id'])) { + $elements = \PHPUnit_Util_XML::cssSelect('#' . $tip['data-id'], TRUE, $raw_content, TRUE); + $this->assertTrue(!empty($elements) && count($elements) === 1, format_string('Found corresponding page element for tour tip with id #%data-id', ['%data-id' => $tip['data-id']])); + } + elseif (!empty($tip['data-class'])) { + $elements = \PHPUnit_Util_XML::cssSelect('.' . $tip['data-class'], TRUE, $raw_content, TRUE); + $this->assertFalse(empty($elements), format_string('Found corresponding page element for tour tip with class .%data-class', ['%data-class' => $tip['data-class']])); + } + else { + // It's a modal. + $modals++; + } + $total++; + } + $this->pass(format_string('Total %total Tips tested of which %modals modal(s).', ['%total' => $total, '%modals' => $modals])); + } + } + +} diff --git a/core/modules/tour/src/Tests/TourTestBasic.php b/core/modules/tour/tests/src/Functional/TourTestBasic.php similarity index 88% rename from core/modules/tour/src/Tests/TourTestBasic.php rename to core/modules/tour/tests/src/Functional/TourTestBasic.php index e79eb2b4..ca188d70 100644 --- a/core/modules/tour/src/Tests/TourTestBasic.php +++ b/core/modules/tour/tests/src/Functional/TourTestBasic.php @@ -1,6 +1,6 @@ container->get('theme_handler')->install(array('bartik', 'seven')); + $this->container->get('theme_handler')->install(['bartik', 'seven']); $this->config('system.theme') ->set('default', 'bartik') ->set('admin', 'seven') diff --git a/core/modules/tour/tests/src/Kernel/TourPluginTest.php b/core/modules/tour/tests/src/Kernel/TourPluginTest.php index 9278e2e5..ce47467d 100644 --- a/core/modules/tour/tests/src/Kernel/TourPluginTest.php +++ b/core/modules/tour/tests/src/Kernel/TourPluginTest.php @@ -16,7 +16,7 @@ class TourPluginTest extends KernelTestBase { * * @var array */ - public static $modules = array('tour'); + public static $modules = ['tour']; /** * Stores the tour plugin manager. @@ -28,7 +28,7 @@ class TourPluginTest extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->installConfig(array('tour')); + $this->installConfig(['tour']); $this->pluginManager = $this->container->get('plugin.manager.tour.tip'); } diff --git a/core/modules/tour/tests/src/Unit/Entity/TourTest.php b/core/modules/tour/tests/src/Unit/Entity/TourTest.php index 2c71aa96..08944eef 100644 --- a/core/modules/tour/tests/src/Unit/Entity/TourTest.php +++ b/core/modules/tour/tests/src/Unit/Entity/TourTest.php @@ -29,7 +29,7 @@ class TourTest extends UnitTestCase { public function testHasMatchingRoute($routes, $route_name, $route_params, $result) { $tour = $this->getMockBuilder('\Drupal\tour\Entity\Tour') ->disableOriginalConstructor() - ->setMethods(array('getRoutes')) + ->setMethods(['getRoutes']) ->getMock(); $tour->expects($this->any()) @@ -45,94 +45,94 @@ public function testHasMatchingRoute($routes, $route_name, $route_params, $resul * Provides sample routes for testing. */ public function routeProvider() { - return array( + return [ // Simple match. - array( - array( - array('route_name' => 'some.route'), - ), + [ + [ + ['route_name' => 'some.route'], + ], 'some.route', - array(), + [], TRUE, - ), + ], // Simple non-match. - array( - array( - array('route_name' => 'another.route'), - ), + [ + [ + ['route_name' => 'another.route'], + ], 'some.route', - array(), + [], FALSE, - ), + ], // Empty params. - array( - array( - array( + [ + [ + [ 'route_name' => 'some.route', - 'route_params' => array('foo' => 'bar'), - ), - ), + 'route_params' => ['foo' => 'bar'], + ], + ], 'some.route', - array(), + [], FALSE, - ), + ], // Match on params. - array( - array( - array( + [ + [ + [ 'route_name' => 'some.route', - 'route_params' => array('foo' => 'bar'), - ), - ), + 'route_params' => ['foo' => 'bar'], + ], + ], 'some.route', - array('foo' => 'bar'), + ['foo' => 'bar'], TRUE, - ), + ], // Non-matching params. - array( - array( - array( + [ + [ + [ 'route_name' => 'some.route', - 'route_params' => array('foo' => 'bar'), - ), - ), + 'route_params' => ['foo' => 'bar'], + ], + ], 'some.route', - array('bar' => 'foo'), + ['bar' => 'foo'], FALSE, - ), + ], // One matching, one not. - array( - array( - array( + [ + [ + [ 'route_name' => 'some.route', - 'route_params' => array('foo' => 'bar'), - ), - array( + 'route_params' => ['foo' => 'bar'], + ], + [ 'route_name' => 'some.route', - 'route_params' => array('bar' => 'foo'), - ), - ), + 'route_params' => ['bar' => 'foo'], + ], + ], 'some.route', - array('bar' => 'foo'), + ['bar' => 'foo'], TRUE, - ), + ], // One matching, one not. - array( - array( - array( + [ + [ + [ 'route_name' => 'some.route', - 'route_params' => array('foo' => 'bar'), - ), - array( + 'route_params' => ['foo' => 'bar'], + ], + [ 'route_name' => 'some.route', - 'route_params' => array('foo' => 'baz'), - ), - ), + 'route_params' => ['foo' => 'baz'], + ], + ], 'some.route', - array('foo' => 'baz'), + ['foo' => 'baz'], TRUE, - ), - ); + ], + ]; } } diff --git a/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php b/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php index 87b817df..56505aa0 100644 --- a/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php +++ b/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php @@ -18,56 +18,56 @@ class TourTestController { * Array of markup. */ public function tourTest1($locale = 'foo') { - return array( - 'tip-1' => array( + return [ + 'tip-1' => [ '#type' => 'container', - '#attributes' => array( + '#attributes' => [ 'id' => 'tour-test-1', - ), + ], '#children' => t('Where does the rain in Spain fail?'), - ), - 'tip-3' => array( + ], + 'tip-3' => [ '#type' => 'container', - '#attributes' => array( + '#attributes' => [ 'id' => 'tour-test-3', - ), + ], '#children' => t('Tip created now?'), - ), - 'tip-4' => array( + ], + 'tip-4' => [ '#type' => 'container', - '#attributes' => array( + '#attributes' => [ 'id' => 'tour-test-4', - ), + ], '#children' => t('Tip created later?'), - ), - 'tip-5' => array( + ], + 'tip-5' => [ '#type' => 'container', - '#attributes' => array( - 'class' => array('tour-test-5'), - ), + '#attributes' => [ + 'class' => ['tour-test-5'], + ], '#children' => t('Tip created later?'), - ), - 'code-tip-1' => array( + ], + 'code-tip-1' => [ '#type' => 'container', - '#attributes' => array( + '#attributes' => [ 'id' => 'tour-code-test-1', - ), + ], '#children' => t('Tip created now?'), - ), - ); + ], + ]; } /** * Outputs some content for testing tours. */ public function tourTest2() { - return array( + return [ '#type' => 'container', - '#attributes' => array( + '#attributes' => [ 'id' => 'tour-test-2', - ), + ], '#children' => t('Pangram example'), - ); + ]; } diff --git a/core/modules/tour/tests/tour_test/tour_test.info.yml b/core/modules/tour/tests/tour_test/tour_test.info.yml index 0cf8aafa..4926724f 100644 --- a/core/modules/tour/tests/tour_test/tour_test.info.yml +++ b/core/modules/tour/tests/tour_test/tour_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - tour -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/tour/tour.info.yml b/core/modules/tour/tour.info.yml index 3056f5c3..e671c57c 100644 --- a/core/modules/tour/tour.info.yml +++ b/core/modules/tour/tour.info.yml @@ -5,8 +5,8 @@ package: Core # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/tour/tour.module b/core/modules/tour/tour.module index e456361f..ce9f3092 100644 --- a/core/modules/tour/tour.module +++ b/core/modules/tour/tour.module @@ -16,13 +16,13 @@ function tour_help($route_name, RouteMatchInterface $route_match) { case 'help.page.tour': $output = ''; $output .= '

          ' . t('About') . '

          '; - $output .= '

          ' . t("The Tour module provides users with guided tours of the site interface. Each tour consists of several tips that highlight elements of the user interface, guide the user through a workflow, or explain key concepts of the website. For more information, see the online documentation for the Tour module.", array(':tour' => 'https://www.drupal.org/documentation/modules/tour')) . '

          '; + $output .= '

          ' . t("The Tour module provides users with guided tours of the site interface. Each tour consists of several tips that highlight elements of the user interface, guide the user through a workflow, or explain key concepts of the website. For more information, see the online documentation for the Tour module.", [':tour' => 'https://www.drupal.org/documentation/modules/tour']) . '

          '; $output .= '

          ' . t('Uses') . '

          '; $output .= '
          '; $output .= '
          ' . t('Viewing tours') . '
          '; $output .= '
          ' . t("If a tour is available on a page, a Tour button will be visible in the toolbar. If you click this button the first tip of the tour will appear. The tour continues after clicking the Next button in the tip. To see a tour users must have the permission Access tour and JavaScript must be enabled in the browser") . '
          '; $output .= '
          ' . t('Creating tours') . '
          '; - $output .= '
          ' . t("Tours can be written as YAML-documents with a text editor, or using the contributed Tour UI module. For more information, see the online documentation for writing tours.", array(':doc_url' => 'https://www.drupal.org/developing/api/tour', ':tour_ui' => 'https://www.drupal.org/project/tour_ui')) . '
          '; + $output .= '
          ' . t("Tours can be written as YAML-documents with a text editor, or using the contributed Tour UI module. For more information, see the online documentation for writing tours.", [':doc_url' => 'https://www.drupal.org/developing/api/tour', ':tour_ui' => 'https://www.drupal.org/project/tour_ui']) . '
          '; $output .= '
          '; return $output; } @@ -45,27 +45,28 @@ function tour_toolbar() { return $items; } - $items['tour'] += array( + $items['tour'] += [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'html_tag', '#tag' => 'button', '#value' => t('Tour'), - '#attributes' => array( - 'class' => array('toolbar-icon', 'toolbar-icon-help'), + '#attributes' => [ + 'class' => ['toolbar-icon', 'toolbar-icon-help'], 'aria-pressed' => 'false', - ), - ), - '#wrapper_attributes' => array( - 'class' => array('tour-toolbar-tab', 'hidden'), + 'type' => 'button', + ], + ], + '#wrapper_attributes' => [ + 'class' => ['tour-toolbar-tab', 'hidden'], 'id' => 'toolbar-tab-tour', - ), - '#attached' => array( - 'library' => array( + ], + '#attached' => [ + 'library' => [ 'tour/tour', - ), - ), - ); + ], + ], + ]; return $items; } diff --git a/core/modules/tracker/js/tracker-history.es6.js b/core/modules/tracker/js/tracker-history.es6.js new file mode 100644 index 00000000..5df3494a --- /dev/null +++ b/core/modules/tracker/js/tracker-history.es6.js @@ -0,0 +1,116 @@ +/** + * Attaches behaviors for the Tracker module's History module integration. + * + * May only be loaded for authenticated users, with the History module enabled. + */ +(function ($, Drupal, window) { + /** + * Render "new" and "updated" node indicators, as well as "X new" replies links. + */ + Drupal.behaviors.trackerHistory = { + attach(context) { + // Find all "new" comment indicator placeholders newer than 30 days ago that + // have not already been read after their last comment timestamp. + const nodeIDs = []; + const $nodeNewPlaceholders = $(context) + .find('[data-history-node-timestamp]') + .once('history') + .filter(function () { + const nodeTimestamp = parseInt(this.getAttribute('data-history-node-timestamp'), 10); + const nodeID = this.getAttribute('data-history-node-id'); + if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) { + nodeIDs.push(nodeID); + return true; + } + + return false; + }); + + // Find all "new" comment indicator placeholders newer than 30 days ago that + // have not already been read after their last comment timestamp. + const $newRepliesPlaceholders = $(context) + .find('[data-history-node-last-comment-timestamp]') + .once('history') + .filter(function () { + const lastCommentTimestamp = parseInt(this.getAttribute('data-history-node-last-comment-timestamp'), 10); + const nodeTimestamp = parseInt(this.previousSibling.previousSibling.getAttribute('data-history-node-timestamp'), 10); + // Discard placeholders that have zero comments. + if (lastCommentTimestamp === nodeTimestamp) { + return false; + } + const nodeID = this.previousSibling.previousSibling.getAttribute('data-history-node-id'); + if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) { + if (nodeIDs.indexOf(nodeID) === -1) { + nodeIDs.push(nodeID); + } + return true; + } + + return false; + }); + + if ($nodeNewPlaceholders.length === 0 && $newRepliesPlaceholders.length === 0) { + return; + } + + // Fetch the node read timestamps from the server. + Drupal.history.fetchTimestamps(nodeIDs, () => { + processNodeNewIndicators($nodeNewPlaceholders); + processNewRepliesIndicators($newRepliesPlaceholders); + }); + }, + }; + + function processNodeNewIndicators($placeholders) { + const newNodeString = Drupal.t('new'); + const updatedNodeString = Drupal.t('updated'); + + $placeholders.each((index, placeholder) => { + const timestamp = parseInt(placeholder.getAttribute('data-history-node-timestamp'), 10); + const nodeID = placeholder.getAttribute('data-history-node-id'); + const lastViewTimestamp = Drupal.history.getLastRead(nodeID); + + if (timestamp > lastViewTimestamp) { + const message = (lastViewTimestamp === 0) ? newNodeString : updatedNodeString; + $(placeholder).append(`${message}`); + } + }); + } + + function processNewRepliesIndicators($placeholders) { + // Figure out which placeholders need the "x new" replies links. + const placeholdersToUpdate = {}; + $placeholders.each((index, placeholder) => { + const timestamp = parseInt(placeholder.getAttribute('data-history-node-last-comment-timestamp'), 10); + const nodeID = placeholder.previousSibling.previousSibling.getAttribute('data-history-node-id'); + const lastViewTimestamp = Drupal.history.getLastRead(nodeID); + + // Queue this placeholder's "X new" replies link to be downloaded from the + // server. + if (timestamp > lastViewTimestamp) { + placeholdersToUpdate[nodeID] = placeholder; + } + }); + + // Perform an AJAX request to retrieve node view timestamps. + const nodeIDs = Object.keys(placeholdersToUpdate); + if (nodeIDs.length === 0) { + return; + } + $.ajax({ + url: Drupal.url('comments/render_new_comments_node_links'), + type: 'POST', + data: { 'node_ids[]': nodeIDs }, + dataType: 'json', + success(results) { + for (const nodeID in results) { + if (results.hasOwnProperty(nodeID) && placeholdersToUpdate.hasOwnProperty(nodeID)) { + const url = results[nodeID].first_new_comment_link; + const text = Drupal.formatPlural(results[nodeID].new_comment_count, '1 new', '@count new'); + $(placeholdersToUpdate[nodeID]).append(`
          ${text}`); + } + } + }, + }); + } +}(jQuery, Drupal, window)); diff --git a/core/modules/tracker/js/tracker-history.js b/core/modules/tracker/js/tracker-history.js index 877a9cae..c60f50d9 100644 --- a/core/modules/tracker/js/tracker-history.js +++ b/core/modules/tracker/js/tracker-history.js @@ -1,64 +1,47 @@ /** - * Attaches behaviors for the Tracker module's History module integration. - * - * May only be loaded for authenticated users, with the History module enabled. - */ -(function ($, Drupal, window) { - - 'use strict'; +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ - /** - * Render "new" and "updated" node indicators, as well as "X new" replies links. - */ +(function ($, Drupal, window) { Drupal.behaviors.trackerHistory = { - attach: function (context) { - // Find all "new" comment indicator placeholders newer than 30 days ago that - // have not already been read after their last comment timestamp. + attach: function attach(context) { var nodeIDs = []; - var $nodeNewPlaceholders = $(context) - .find('[data-history-node-timestamp]') - .once('history') - .filter(function () { - var nodeTimestamp = parseInt(this.getAttribute('data-history-node-timestamp'), 10); - var nodeID = this.getAttribute('data-history-node-id'); - if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) { + var $nodeNewPlaceholders = $(context).find('[data-history-node-timestamp]').once('history').filter(function () { + var nodeTimestamp = parseInt(this.getAttribute('data-history-node-timestamp'), 10); + var nodeID = this.getAttribute('data-history-node-id'); + if (Drupal.history.needsServerCheck(nodeID, nodeTimestamp)) { + nodeIDs.push(nodeID); + return true; + } + + return false; + }); + + var $newRepliesPlaceholders = $(context).find('[data-history-node-last-comment-timestamp]').once('history').filter(function () { + var lastCommentTimestamp = parseInt(this.getAttribute('data-history-node-last-comment-timestamp'), 10); + var nodeTimestamp = parseInt(this.previousSibling.previousSibling.getAttribute('data-history-node-timestamp'), 10); + + if (lastCommentTimestamp === nodeTimestamp) { + return false; + } + var nodeID = this.previousSibling.previousSibling.getAttribute('data-history-node-id'); + if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) { + if (nodeIDs.indexOf(nodeID) === -1) { nodeIDs.push(nodeID); - return true; - } - else { - return false; } - }); + return true; + } - // Find all "new" comment indicator placeholders newer than 30 days ago that - // have not already been read after their last comment timestamp. - var $newRepliesPlaceholders = $(context) - .find('[data-history-node-last-comment-timestamp]') - .once('history') - .filter(function () { - var lastCommentTimestamp = parseInt(this.getAttribute('data-history-node-last-comment-timestamp'), 10); - var nodeTimestamp = parseInt(this.previousSibling.previousSibling.getAttribute('data-history-node-timestamp'), 10); - // Discard placeholders that have zero comments. - if (lastCommentTimestamp === nodeTimestamp) { - return false; - } - var nodeID = this.previousSibling.previousSibling.getAttribute('data-history-node-id'); - if (Drupal.history.needsServerCheck(nodeID, lastCommentTimestamp)) { - if (nodeIDs.indexOf(nodeID) === -1) { - nodeIDs.push(nodeID); - } - return true; - } - else { - return false; - } - }); + return false; + }); if ($nodeNewPlaceholders.length === 0 && $newRepliesPlaceholders.length === 0) { return; } - // Fetch the node read timestamps from the server. Drupal.history.fetchTimestamps(nodeIDs, function () { processNodeNewIndicators($nodeNewPlaceholders); processNewRepliesIndicators($newRepliesPlaceholders); @@ -76,28 +59,24 @@ var lastViewTimestamp = Drupal.history.getLastRead(nodeID); if (timestamp > lastViewTimestamp) { - var message = (lastViewTimestamp === 0) ? newNodeString : updatedNodeString; + var message = lastViewTimestamp === 0 ? newNodeString : updatedNodeString; $(placeholder).append('' + message + ''); } }); } function processNewRepliesIndicators($placeholders) { - // Figure out which placeholders need the "x new" replies links. var placeholdersToUpdate = {}; $placeholders.each(function (index, placeholder) { var timestamp = parseInt(placeholder.getAttribute('data-history-node-last-comment-timestamp'), 10); var nodeID = placeholder.previousSibling.previousSibling.getAttribute('data-history-node-id'); var lastViewTimestamp = Drupal.history.getLastRead(nodeID); - // Queue this placeholder's "X new" replies link to be downloaded from the - // server. if (timestamp > lastViewTimestamp) { placeholdersToUpdate[nodeID] = placeholder; } }); - // Perform an AJAX request to retrieve node view timestamps. var nodeIDs = Object.keys(placeholdersToUpdate); if (nodeIDs.length === 0) { return; @@ -105,9 +84,9 @@ $.ajax({ url: Drupal.url('comments/render_new_comments_node_links'), type: 'POST', - data: {'node_ids[]': nodeIDs}, + data: { 'node_ids[]': nodeIDs }, dataType: 'json', - success: function (results) { + success: function success(results) { for (var nodeID in results) { if (results.hasOwnProperty(nodeID) && placeholdersToUpdate.hasOwnProperty(nodeID)) { var url = results[nodeID].first_new_comment_link; @@ -118,5 +97,4 @@ } }); } - -})(jQuery, Drupal, window); +})(jQuery, Drupal, window); \ No newline at end of file diff --git a/core/modules/tracker/migration_templates/d7_tracker_settings.yml b/core/modules/tracker/migration_templates/d7_tracker_settings.yml index ce06cbd8..ac61d7db 100644 --- a/core/modules/tracker/migration_templates/d7_tracker_settings.yml +++ b/core/modules/tracker/migration_templates/d7_tracker_settings.yml @@ -6,6 +6,7 @@ source: plugin: variable variables: - tracker_batch_size + source_module: tracker process: cron_index_limit: tracker_batch_size destination: diff --git a/core/modules/tracker/src/Access/ViewOwnTrackerAccessCheck.php b/core/modules/tracker/src/Access/ViewOwnTrackerAccessCheck.php deleted file mode 100644 index 471eacfe..00000000 --- a/core/modules/tracker/src/Access/ViewOwnTrackerAccessCheck.php +++ /dev/null @@ -1,30 +0,0 @@ -isAuthenticated() && ($user->id() == $account->id()))->cachePerUser(); - } - -} diff --git a/core/modules/tracker/src/Controller/TrackerUserRecent.php b/core/modules/tracker/src/Controller/TrackerUserRecent.php index 4ca428e5..ff3d4b02 100644 --- a/core/modules/tracker/src/Controller/TrackerUserRecent.php +++ b/core/modules/tracker/src/Controller/TrackerUserRecent.php @@ -2,7 +2,9 @@ namespace Drupal\tracker\Controller; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Session\AccountInterface; use Drupal\user\UserInterface; /** @@ -18,4 +20,20 @@ public function getContent(UserInterface $user) { return tracker_page($user); } + /** + * Checks access for the users recent content tracker page. + * + * @param \Drupal\user\UserInterface $user + * The user being viewed. + * @param \Drupal\Core\Session\AccountInterface $account + * The account viewing the page. + * + * @return \Drupal\Core\Access\AccessResult + * The access result. + */ + public function checkAccess(UserInterface $user, AccountInterface $account) { + return AccessResult::allowedIf($account->isAuthenticated() && $user->id() == $account->id()) + ->cachePerUser(); + } + } diff --git a/core/modules/tracker/src/Plugin/Menu/UserTrackerTab.php b/core/modules/tracker/src/Plugin/Menu/UserTrackerTab.php index 1cd42177..95264803 100644 --- a/core/modules/tracker/src/Plugin/Menu/UserTrackerTab.php +++ b/core/modules/tracker/src/Plugin/Menu/UserTrackerTab.php @@ -37,7 +37,7 @@ protected function currentUser() { * {@inheritdoc} */ public function getRouteParameters(RouteMatchInterface $route_match) { - return array('user' => $this->currentUser()->Id()); + return ['user' => $this->currentUser()->Id()]; } } diff --git a/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerNode.php b/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerNode.php index ffdc5cd3..2805b7d7 100644 --- a/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerNode.php +++ b/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerNode.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d7_tracker_node", - * source_provider = "tracker" + * source_module = "tracker" * ) */ class TrackerNode extends DrupalSqlBase { diff --git a/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerUser.php b/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerUser.php index 9ce3ff31..4991dbe2 100644 --- a/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerUser.php +++ b/core/modules/tracker/src/Plugin/migrate/source/d7/TrackerUser.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d7_tracker_user", - * source_provider = "tracker" + * source_module = "tracker" * ) */ class TrackerUser extends DrupalSqlBase { diff --git a/core/modules/tracker/src/Tests/Views/TrackerTestBase.php b/core/modules/tracker/src/Tests/Views/TrackerTestBase.php index 7b2f9462..9746a22a 100644 --- a/core/modules/tracker/src/Tests/Views/TrackerTestBase.php +++ b/core/modules/tracker/src/Tests/Views/TrackerTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\tracker\Tests\Views; +@trigger_error(__NAMESPACE__ . '\TrackerTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\tracker\Functional\Views\TrackerTestBase', E_USER_DEPRECATED); + use Drupal\comment\Tests\CommentTestTrait; use Drupal\Core\Language\LanguageInterface; use Drupal\views\Tests\ViewTestBase; @@ -10,6 +12,9 @@ /** * Base class for all tracker tests. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\tracker\Functional\Views\TrackerTestBase instead. */ abstract class TrackerTestBase extends ViewTestBase { @@ -20,7 +25,7 @@ abstract class TrackerTestBase extends ViewTestBase { * * @var array */ - public static $modules = array('comment', 'tracker', 'tracker_test_views'); + public static $modules = ['comment', 'tracker', 'tracker_test_views']; /** * The node used for testing. @@ -39,30 +44,30 @@ abstract class TrackerTestBase extends ViewTestBase { protected function setUp() { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('tracker_test_views')); + ViewTestData::createTestViews(get_class($this), ['tracker_test_views']); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); // Add a comment field. $this->addDefaultCommentField('node', 'page'); - $permissions = array('access comments', 'create page content', 'post comments', 'skip comment approval'); + $permissions = ['access comments', 'create page content', 'post comments', 'skip comment approval']; $account = $this->drupalCreateUser($permissions); $this->drupalLogin($account); - $this->node = $this->drupalCreateNode(array( + $this->node = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'uid' => $account->id(), 'status' => 1, - )); + ]); - $this->comment = Comment::create(array( + $this->comment = Comment::create([ 'entity_id' => $this->node->id(), 'entity_type' => 'node', 'field_name' => 'comment', 'subject' => $this->randomMachineName(), 'comment_body[' . LanguageInterface::LANGCODE_NOT_SPECIFIED . '][0][value]' => $this->randomMachineName(20), - )); + ]); } diff --git a/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.info.yml b/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.info.yml index 555ebf0d..20b7594a 100644 --- a/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.info.yml +++ b/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.info.yml @@ -8,8 +8,8 @@ dependencies: - tracker - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/tracker/src/Tests/TrackerNodeAccessTest.php b/core/modules/tracker/tests/src/Functional/TrackerNodeAccessTest.php similarity index 79% rename from core/modules/tracker/src/Tests/TrackerNodeAccessTest.php rename to core/modules/tracker/tests/src/Functional/TrackerNodeAccessTest.php index 29492bc6..2b320ae4 100644 --- a/core/modules/tracker/src/Tests/TrackerNodeAccessTest.php +++ b/core/modules/tracker/tests/src/Functional/TrackerNodeAccessTest.php @@ -1,18 +1,18 @@ drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); node_access_test_add_field(NodeType::load('page')); $this->addDefaultCommentField('node', 'page', 'comment', CommentItemInterface::OPEN); \Drupal::state()->set('node_access_test.private', TRUE); @@ -35,24 +35,24 @@ protected function setUp() { /** * Ensure private node on /tracker is only visible to users with permission. */ - function testTrackerNodeAccess() { + public function testTrackerNodeAccess() { // Create user with node test view permission. - $access_user = $this->drupalCreateUser(array('node test view', 'access user profiles')); + $access_user = $this->drupalCreateUser(['node test view', 'access user profiles']); // Create user without node test view permission. - $no_access_user = $this->drupalCreateUser(array('access user profiles')); + $no_access_user = $this->drupalCreateUser(['access user profiles']); $this->drupalLogin($access_user); // Create some nodes. - $private_node = $this->drupalCreateNode(array( + $private_node = $this->drupalCreateNode([ 'title' => t('Private node test'), 'private' => TRUE, - )); - $public_node = $this->drupalCreateNode(array( + ]); + $public_node = $this->drupalCreateNode([ 'title' => t('Public node test'), 'private' => FALSE, - )); + ]); // User with access should see both nodes created. $this->drupalGet('activity'); diff --git a/core/modules/tracker/src/Tests/TrackerTest.php b/core/modules/tracker/tests/src/Functional/TrackerTest.php similarity index 87% rename from core/modules/tracker/src/Tests/TrackerTest.php rename to core/modules/tracker/tests/src/Functional/TrackerTest.php index a927e891..1a77d95a 100644 --- a/core/modules/tracker/src/Tests/TrackerTest.php +++ b/core/modules/tracker/tests/src/Functional/TrackerTest.php @@ -1,6 +1,6 @@ drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); - $permissions = array('access comments', 'create page content', 'post comments', 'skip comment approval'); + $permissions = ['access comments', 'create page content', 'post comments', 'skip comment approval']; $this->user = $this->drupalCreateUser($permissions); $this->otherUser = $this->drupalCreateUser($permissions); $this->addDefaultCommentField('node', 'page'); - user_role_grant_permissions(AccountInterface::ANONYMOUS_ROLE, array( + user_role_grant_permissions(AccountInterface::ANONYMOUS_ROLE, [ 'access content', 'access user profiles', - )); + ]); $this->drupalPlaceBlock('local_tasks_block', ['id' => 'page_tabs_block']); $this->drupalPlaceBlock('local_actions_block', ['id' => 'page_actions_block']); } @@ -63,17 +63,17 @@ protected function setUp() { /** * Tests for the presence of nodes on the global tracker listing. */ - function testTrackerAll() { + public function testTrackerAll() { $this->drupalLogin($this->user); - $unpublished = $this->drupalCreateNode(array( + $unpublished = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'status' => 0, - )); - $published = $this->drupalCreateNode(array( + ]); + $published = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'status' => 1, - )); + ]); $this->drupalGet('activity'); $this->assertNoText($unpublished->label(), 'Unpublished node does not show up in the tracker listing.'); @@ -129,33 +129,33 @@ function testTrackerAll() { /** * Tests for the presence of nodes on a user's tracker listing. */ - function testTrackerUser() { + public function testTrackerUser() { $this->drupalLogin($this->user); - $unpublished = $this->drupalCreateNode(array( + $unpublished = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'uid' => $this->user->id(), 'status' => 0, - )); - $my_published = $this->drupalCreateNode(array( + ]); + $my_published = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'uid' => $this->user->id(), 'status' => 1, - )); - $other_published_no_comment = $this->drupalCreateNode(array( + ]); + $other_published_no_comment = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'uid' => $this->otherUser->id(), 'status' => 1, - )); - $other_published_my_comment = $this->drupalCreateNode(array( + ]); + $other_published_my_comment = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), 'uid' => $this->otherUser->id(), 'status' => 1, - )); - $comment = array( + ]); + $comment = [ 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20), - ); + ]; $this->drupalPostForm('comment/reply/node/' . $other_published_my_comment->id() . '/comment', $comment, t('Save')); $this->drupalGet('user/' . $this->user->id() . '/activity'); @@ -197,12 +197,12 @@ function testTrackerUser() { $this->assertNoLink($unpublished->label()); // Verify that title and tab title have been set correctly. $this->assertText('Activity', 'The user activity tab has the name "Activity".'); - $this->assertTitle(t('@name | @site', array('@name' => $this->user->getUsername(), '@site' => $this->config('system.site')->get('name'))), 'The user tracker page has the correct page title.'); + $this->assertTitle(t('@name | @site', ['@name' => $this->user->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'The user tracker page has the correct page title.'); // Verify that unpublished comments are removed from the tracker. - $admin_user = $this->drupalCreateUser(array('post comments', 'administer comments', 'access user profiles')); + $admin_user = $this->drupalCreateUser(['post comments', 'administer comments', 'access user profiles']); $this->drupalLogin($admin_user); - $this->drupalPostForm('comment/1/edit', array('status' => CommentInterface::NOT_PUBLISHED), t('Save')); + $this->drupalPostForm('comment/1/edit', ['status' => CommentInterface::NOT_PUBLISHED], t('Save')); $this->drupalGet('user/' . $this->user->id() . '/activity'); $this->assertNoText($other_published_my_comment->label(), 'Unpublished comments are not counted on the tracker listing.'); @@ -223,13 +223,13 @@ function testTrackerUser() { /** * Tests the metadata for the "new"/"updated" indicators. */ - function testTrackerHistoryMetadata() { + public function testTrackerHistoryMetadata() { $this->drupalLogin($this->user); // Create a page node. - $edit = array( + $edit = [ 'title' => $this->randomMachineName(8), - ); + ]; $node = $this->drupalCreateNode($edit); // Verify that the history metadata is present. @@ -243,10 +243,10 @@ function testTrackerHistoryMetadata() { // Add a comment to the page, make sure it is created after the node by // sleeping for one second, to ensure the last comment timestamp is // different from before. - $comment = array( + $comment = [ 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20), - ); + ]; sleep(1); $this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $comment, t('Save')); // Reload the node so that comment.module's hook_node_load() @@ -274,25 +274,25 @@ function testTrackerHistoryMetadata() { /** * Tests for ordering on a users tracker listing when comments are posted. */ - function testTrackerOrderingNewComments() { + public function testTrackerOrderingNewComments() { $this->drupalLogin($this->user); - $node_one = $this->drupalCreateNode(array( + $node_one = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), - )); + ]); - $node_two = $this->drupalCreateNode(array( + $node_two = $this->drupalCreateNode([ 'title' => $this->randomMachineName(8), - )); + ]); // Now get otherUser to track these pieces of content. $this->drupalLogin($this->otherUser); // Add a comment to the first page. - $comment = array( + $comment = [ 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20), - ); + ]; $this->drupalPostForm('comment/reply/node/' . $node_one->id() . '/comment', $comment, t('Save')); // If the comment is posted in the same second as the last one then Drupal @@ -300,10 +300,10 @@ function testTrackerOrderingNewComments() { sleep(1); // Add a comment to the second page. - $comment = array( + $comment = [ 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20), - ); + ]; $this->drupalPostForm('comment/reply/node/' . $node_two->id() . '/comment', $comment, t('Save')); // We should at this point have in our tracker for otherUser: @@ -320,10 +320,10 @@ function testTrackerOrderingNewComments() { sleep(1); // Add a comment to the second page. - $comment = array( + $comment = [ 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20), - ); + ]; $this->drupalPostForm('comment/reply/node/' . $node_one->id() . '/comment', $comment, t('Save')); // Switch back to the otherUser and assert that the order has swapped. @@ -340,25 +340,25 @@ function testTrackerOrderingNewComments() { /** * Tests that existing nodes are indexed by cron. */ - function testTrackerCronIndexing() { + public function testTrackerCronIndexing() { $this->drupalLogin($this->user); // Create 3 nodes. - $edits = array(); - $nodes = array(); + $edits = []; + $nodes = []; for ($i = 1; $i <= 3; $i++) { - $edits[$i] = array( + $edits[$i] = [ 'title' => $this->randomMachineName(), - ); + ]; $nodes[$i] = $this->drupalCreateNode($edits[$i]); } // Add a comment to the last node as other user. $this->drupalLogin($this->otherUser); - $comment = array( + $comment = [ 'subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20), - ); + ]; $this->drupalPostForm('comment/reply/node/' . $nodes[3]->id() . '/comment', $comment, t('Save')); // Start indexing backwards from node 3. @@ -378,7 +378,7 @@ function testTrackerCronIndexing() { // Assert that all node titles are displayed. foreach ($nodes as $i => $node) { - $this->assertText($node->label(), format_string('Node @i is displayed on the tracker listing pages.', array('@i' => $i))); + $this->assertText($node->label(), format_string('Node @i is displayed on the tracker listing pages.', ['@i' => $i])); } // Fetch the site-wide tracker. @@ -386,32 +386,32 @@ function testTrackerCronIndexing() { // Assert that all node titles are displayed. foreach ($nodes as $i => $node) { - $this->assertText($node->label(), format_string('Node @i is displayed on the tracker listing pages.', array('@i' => $i))); + $this->assertText($node->label(), format_string('Node @i is displayed on the tracker listing pages.', ['@i' => $i])); } } /** * Tests that publish/unpublish works at admin/content/node. */ - function testTrackerAdminUnpublish() { - \Drupal::service('module_installer')->install(array('views')); + public function testTrackerAdminUnpublish() { + \Drupal::service('module_installer')->install(['views']); \Drupal::service('router.builder')->rebuild(); - $admin_user = $this->drupalCreateUser(array('access content overview', 'administer nodes', 'bypass node access')); + $admin_user = $this->drupalCreateUser(['access content overview', 'administer nodes', 'bypass node access']); $this->drupalLogin($admin_user); - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'title' => $this->randomMachineName(), - )); + ]); // Assert that the node is displayed. $this->drupalGet('activity'); $this->assertText($node->label(), 'A node is displayed on the tracker listing pages.'); // Unpublish the node and ensure that it's no longer displayed. - $edit = array( + $edit = [ 'action' => 'node_unpublish_action', 'node_bulk_form[0]' => $node->id(), - ); + ]; $this->drupalPostForm('admin/content', $edit, t('Apply to selected items')); $this->drupalGet('activity'); @@ -438,7 +438,7 @@ function testTrackerAdminUnpublish() { * @param bool $library_is_present * Whether the drupal.tracker-history library should be present or not. */ - function assertHistoryMetadata($node_id, $node_timestamp, $node_last_comment_timestamp, $library_is_present = TRUE) { + public function assertHistoryMetadata($node_id, $node_timestamp, $node_last_comment_timestamp, $library_is_present = TRUE) { $settings = $this->getDrupalSettings(); $this->assertIdentical($library_is_present, isset($settings['ajaxPageState']) && in_array('tracker/history', explode(',', $settings['ajaxPageState']['libraries'])), 'drupal.tracker-history library is present.'); $this->assertIdentical(1, count($this->xpath('//table/tbody/tr/td[@data-history-node-id="' . $node_id . '" and @data-history-node-timestamp="' . $node_timestamp . '"]')), 'Tracker table cell contains the data-history-node-id and data-history-node-timestamp attributes for the node.'); diff --git a/core/modules/tracker/tests/src/Functional/Views/TrackerTestBase.php b/core/modules/tracker/tests/src/Functional/Views/TrackerTestBase.php new file mode 100644 index 00000000..d7068437 --- /dev/null +++ b/core/modules/tracker/tests/src/Functional/Views/TrackerTestBase.php @@ -0,0 +1,69 @@ +drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + // Add a comment field. + $this->addDefaultCommentField('node', 'page'); + + $permissions = ['access comments', 'create page content', 'post comments', 'skip comment approval']; + $account = $this->drupalCreateUser($permissions); + + $this->drupalLogin($account); + + $this->node = $this->drupalCreateNode([ + 'title' => $this->randomMachineName(8), + 'uid' => $account->id(), + 'status' => 1, + ]); + + $this->comment = Comment::create([ + 'entity_id' => $this->node->id(), + 'entity_type' => 'node', + 'field_name' => 'comment', + 'subject' => $this->randomMachineName(), + 'comment_body[' . LanguageInterface::LANGCODE_NOT_SPECIFIED . '][0][value]' => $this->randomMachineName(20), + ]); + + } + +} diff --git a/core/modules/tracker/src/Tests/Views/TrackerUserUidTest.php b/core/modules/tracker/tests/src/Functional/Views/TrackerUserUidTest.php similarity index 76% rename from core/modules/tracker/src/Tests/Views/TrackerUserUidTest.php rename to core/modules/tracker/tests/src/Functional/Views/TrackerUserUidTest.php index 68b77777..7bd675b2 100644 --- a/core/modules/tracker/src/Tests/Views/TrackerUserUidTest.php +++ b/core/modules/tracker/tests/src/Functional/Views/TrackerUserUidTest.php @@ -1,6 +1,6 @@ 'nid', 'title' => 'title', - ); + ]; - $expected = array( - array( + $expected = [ + [ 'nid' => $this->node->id(), 'title' => $this->node->label(), - ) - ); + ] + ]; $view = Views::getView('test_tracker_user_uid'); $this->executeView($view); // We should have no results as the filter is set for uid 0. - $this->assertIdenticalResultSet($view, array(), $map); + $this->assertIdenticalResultSet($view, [], $map); $view->destroy(); // Change the filter value to our user. @@ -55,13 +55,13 @@ public function testUserUid() { // Test the incorrect argument UID. $view->initHandlers(); - $this->executeView($view, array(rand())); - $this->assertIdenticalResultSet($view, array(), $map); + $this->executeView($view, [rand()]); + $this->assertIdenticalResultSet($view, [], $map); $view->destroy(); // Test the correct argument UID. $view->initHandlers(); - $this->executeView($view, array($this->node->getOwnerId())); + $this->executeView($view, [$this->node->getOwnerId()]); $this->assertIdenticalResultSet($view, $expected, $map); } diff --git a/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerNodeTest.php b/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerNodeTest.php index d72f13dc..d3705026 100644 --- a/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerNodeTest.php +++ b/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerNodeTest.php @@ -16,6 +16,7 @@ class MigrateTrackerNodeTest extends MigrateDrupal7TestBase { * {@inheritdoc} */ public static $modules = [ + 'menu_ui', 'node', 'text', 'tracker', @@ -47,17 +48,17 @@ protected function setUp() { public function testMigrateTrackerNode() { $connection = Database::getConnection('default', 'migrate'); $num_rows = $connection - ->select('tracker_node', 'tn') - ->fields('tn', ['nid', 'published', 'changed']) - ->countQuery() - ->execute() - ->fetchField(); + ->select('tracker_node', 'tn') + ->fields('tn', ['nid', 'published', 'changed']) + ->countQuery() + ->execute() + ->fetchField(); $this->assertIdentical('1', $num_rows); $tracker_nodes = $connection - ->select('tracker_node', 'tn') - ->fields('tn', ['nid', 'published', 'changed']) - ->execute(); + ->select('tracker_node', 'tn') + ->fields('tn', ['nid', 'published', 'changed']) + ->execute(); $row = $tracker_nodes->fetchAssoc(); $this->assertIdentical('1', $row['nid']); $this->assertIdentical('1', $row['published']); diff --git a/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerUserTest.php b/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerUserTest.php index e3ed88e9..3b0c11bb 100644 --- a/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerUserTest.php +++ b/core/modules/tracker/tests/src/Kernel/Migrate/d7/MigrateTrackerUserTest.php @@ -16,6 +16,7 @@ class MigrateTrackerUserTest extends MigrateDrupal7TestBase { * {@inheritdoc} */ public static $modules = [ + 'menu_ui', 'node', 'text', 'tracker', @@ -47,17 +48,17 @@ protected function setUp() { public function testMigrateTrackerUser() { $connection = Database::getConnection('default', 'migrate'); $num_rows = $connection - ->select('tracker_user', 'tn') - ->fields('tu', ['nid', 'uid', 'published', 'changed']) - ->countQuery() - ->execute() - ->fetchField(); + ->select('tracker_user', 'tn') + ->fields('tu', ['nid', 'uid', 'published', 'changed']) + ->countQuery() + ->execute() + ->fetchField(); $this->assertIdentical('1', $num_rows); $tracker_nodes = $connection - ->select('tracker_user', 'tu') - ->fields('tu', ['nid', 'uid', 'published', 'changed']) - ->execute(); + ->select('tracker_user', 'tu') + ->fields('tu', ['nid', 'uid', 'published', 'changed']) + ->execute(); $row = $tracker_nodes->fetchAssoc(); $this->assertIdentical('1', $row['nid']); $this->assertIdentical('2', $row['uid']); diff --git a/core/modules/tracker/tracker.info.yml b/core/modules/tracker/tracker.info.yml index 99fcf0ec..ca40a9c8 100644 --- a/core/modules/tracker/tracker.info.yml +++ b/core/modules/tracker/tracker.info.yml @@ -8,8 +8,8 @@ package: Core # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/tracker/tracker.install b/core/modules/tracker/tracker.install index 5f3e5a0f..bc9ebc57 100644 --- a/core/modules/tracker/tracker.install +++ b/core/modules/tracker/tracker.install @@ -29,90 +29,90 @@ function tracker_install() { * Implements hook_schema(). */ function tracker_schema() { - $schema['tracker_node'] = array( + $schema['tracker_node'] = [ 'description' => 'Tracks when nodes were last changed or commented on.', - 'fields' => array( - 'nid' => array( + 'fields' => [ + 'nid' => [ 'description' => 'The {node}.nid this record tracks.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'published' => array( + ], + 'published' => [ 'description' => 'Boolean indicating whether the node is published.', 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'size' => 'tiny', - ), - 'changed' => array( + ], + 'changed' => [ 'description' => 'The Unix timestamp when the node was most recently saved or commented on.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - ), - 'indexes' => array( - 'tracker' => array('published', 'changed'), - ), - 'primary key' => array('nid'), - 'foreign keys' => array( - 'tracked_node' => array( + ], + ], + 'indexes' => [ + 'tracker' => ['published', 'changed'], + ], + 'primary key' => ['nid'], + 'foreign keys' => [ + 'tracked_node' => [ 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - ), - ); + 'columns' => ['nid' => 'nid'], + ], + ], + ]; - $schema['tracker_user'] = array( + $schema['tracker_user'] = [ 'description' => 'Tracks when nodes were last changed or commented on, for each user that authored the node or one of its comments.', - 'fields' => array( - 'nid' => array( + 'fields' => [ + 'nid' => [ 'description' => 'The {node}.nid this record tracks.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'uid' => array( + ], + 'uid' => [ 'description' => 'The {users}.uid of the node author or commenter.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'published' => array( + ], + 'published' => [ 'description' => 'Boolean indicating whether the node is published.', 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'size' => 'tiny', - ), - 'changed' => array( + ], + 'changed' => [ 'description' => 'The Unix timestamp when the node was most recently saved or commented on.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - ), - 'indexes' => array( - 'tracker' => array('uid', 'published', 'changed'), - ), - 'primary key' => array('nid', 'uid'), - 'foreign keys' => array( - 'tracked_node' => array( + ], + ], + 'indexes' => [ + 'tracker' => ['uid', 'published', 'changed'], + ], + 'primary key' => ['nid', 'uid'], + 'foreign keys' => [ + 'tracked_node' => [ 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - 'tracked_user' => array( + 'columns' => ['nid' => 'nid'], + ], + 'tracked_user' => [ 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - ); + 'columns' => ['uid' => 'uid'], + ], + ], + ]; return $schema; } diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module index 1b2f648d..bf40dc1e 100644 --- a/core/modules/tracker/tracker.module +++ b/core/modules/tracker/tracker.module @@ -19,11 +19,11 @@ function tracker_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.tracker': $output = '

          ' . t('About') . '

          '; - $output .= '

          ' . t('The Activity Tracker module displays the most recently added and updated content on your site, and allows you to follow new content created by each user. This module has no configuration options. For more information, see the online documentation for the Activity Tracker module.', array(':tracker' => 'https://www.drupal.org/documentation/modules/tracker')) . '

          '; + $output .= '

          ' . t('The Activity Tracker module displays the most recently added and updated content on your site, and allows you to follow new content created by each user. This module has no configuration options. For more information, see the online documentation for the Activity Tracker module.', [':tracker' => 'https://www.drupal.org/documentation/modules/tracker']) . '

          '; $output .= '

          ' . t('Uses') . '

          '; $output .= '
          '; $output .= '
          ' . t('Tracking new and updated site content') . '
          '; - $output .= '
          ' . t('The Recent content page shows new and updated content in reverse chronological order, listing the content type, title, author\'s name, number of comments, and time of last update. Content is considered updated when changes occur in the text, or when new comments are added. The My recent content tab limits the list to the currently logged-in user.', array(':recent' => \Drupal::url('tracker.page'))) . '
          '; + $output .= '
          ' . t('The Recent content page shows new and updated content in reverse chronological order, listing the content type, title, author\'s name, number of comments, and time of last update. Content is considered updated when changes occur in the text, or when new comments are added. The My recent content tab limits the list to the currently logged-in user.', [':recent' => \Drupal::url('tracker.page')]) . '
          '; $output .= '
          ' . t('Tracking user-specific content') . '
          '; $output .= '
          ' . t("To follow a specific user's new and updated content, select the Activity tab from the user's profile page.") . '
          '; $output .= '
          '; @@ -70,21 +70,21 @@ function tracker_cron() { // Insert the node-level data. db_insert('tracker_node') - ->fields(array( + ->fields([ 'nid' => $nid, 'published' => $node->isPublished(), 'changed' => $changed, - )) + ]) ->execute(); // Insert the user-level data for the node's author. db_insert('tracker_user') - ->fields(array( + ->fields([ 'nid' => $nid, 'published' => $node->isPublished(), 'changed' => $changed, 'uid' => $node->getOwnerId(), - )) + ]) ->execute(); // Insert the user-level data for the commenters (except if a commenter @@ -103,12 +103,12 @@ function tracker_cron() { if ($result) { $query = db_insert('tracker_user'); foreach ($result as $row) { - $query->fields(array( + $query->fields([ 'uid' => $row['uid'], 'nid' => $nid, 'published' => CommentInterface::PUBLISHED, 'changed' => $changed, - )); + ]); } $query->execute(); } @@ -123,7 +123,7 @@ function tracker_cron() { // Prepare a starting point for the next run. $state->set('tracker.index_nid', $last_nid - 1); - \Drupal::logger('tracker')->notice('Indexed %count content items for tracking.', array('%count' => $count)); + \Drupal::logger('tracker')->notice('Indexed %count content items for tracking.', ['%count' => $count]); } else { // If all nodes have been indexed, set to zero to skip future cron runs. @@ -135,16 +135,21 @@ function tracker_cron() { /** * Access callback: Determines access permission for a user's own account. * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. As + * internal API, _tracker_user_access() may also be removed in a minor + * release. + * + * @internal + * * @param \Drupal\Core\Session\AccountInterface $account * The user account to track. * * @return bool * TRUE if a user is accessing tracking info for their own account and * has permission to access the content. - * - * @see tracker_menu() */ function _tracker_myrecent_access(AccountInterface $account) { + @trigger_error('_tracker_myrecent_access() is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.', E_USER_DEPRECATED); // This path is only allowed for authenticated users looking at their own content. return $account->id() && (\Drupal::currentUser()->id() == $account->id()) && $account->hasPermission('access content'); } @@ -152,16 +157,21 @@ function _tracker_myrecent_access(AccountInterface $account) { /** * Access callback: Determines access permission for an account. * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. As + * internal API, _tracker_user_access() may also be removed in a minor + * release. + * + * @internal + * * @param int $account * The user account ID to track. * * @return bool * TRUE if a user has permission to access the account for $account and * has permission to access the content. - * - * @see tracker_menu() */ function _tracker_user_access($account) { + @trigger_error('_tracker_user_access() is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.', E_USER_DEPRECATED); return $account->access('view') && $account->hasPermission('access content'); } @@ -242,7 +252,7 @@ function tracker_comment_delete(CommentInterface $comment) { function _tracker_add($nid, $uid, $changed) { // @todo This should be actually filtering on the desired language and just // fall back to the default language. - $node = db_query('SELECT nid, status, uid, changed FROM {node_field_data} WHERE nid = :nid AND default_langcode = 1 ORDER BY changed DESC, status DESC', array(':nid' => $nid))->fetchObject(); + $node = db_query('SELECT nid, status, uid, changed FROM {node_field_data} WHERE nid = :nid AND default_langcode = 1 ORDER BY changed DESC, status DESC', [':nid' => $nid])->fetchObject(); // Adding a comment can only increase the changed timestamp, so our // calculation here is simple. @@ -251,30 +261,30 @@ function _tracker_add($nid, $uid, $changed) { // Update the node-level data. db_merge('tracker_node') ->key('nid', $nid) - ->fields(array( + ->fields([ 'changed' => $changed, 'published' => $node->status, - )) + ]) ->execute(); // Create or update the user-level data, first for the user posting. db_merge('tracker_user') - ->keys(array( + ->keys([ 'nid' => $nid, 'uid' => $uid, - )) - ->fields(array( + ]) + ->fields([ 'changed' => $changed, 'published' => $node->status, - )) + ]) ->execute(); // Update the times for all the other users tracking the post. db_update('tracker_user') ->condition('nid', $nid) - ->fields(array( + ->fields([ 'changed' => $changed, 'published' => $node->status, - )) + ]) ->execute(); } @@ -293,7 +303,7 @@ function _tracker_add($nid, $uid, $changed) { */ function _tracker_calculate_changed($node) { $changed = $node->getChangedTime(); - $latest_comment = \Drupal::service('comment.statistics')->read(array($node), 'node', FALSE); + $latest_comment = \Drupal::service('comment.statistics')->read([$node], 'node', FALSE); if ($latest_comment && $latest_comment->last_comment_timestamp > $changed) { $changed = $latest_comment->last_comment_timestamp; } @@ -343,7 +353,7 @@ function _tracker_remove($nid, $uid = NULL, $changed = NULL) { // and the node itself. // We only need to do this if the removed item has a timestamp that equals // or exceeds the listed changed timestamp for the node. - $tracker_node = db_query('SELECT nid, changed FROM {tracker_node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject(); + $tracker_node = db_query('SELECT nid, changed FROM {tracker_node} WHERE nid = :nid', [':nid' => $nid])->fetchObject(); if ($tracker_node && $changed >= $tracker_node->changed) { // If we're here, the item being removed is *possibly* the item that // established the node's changed timestamp. @@ -354,17 +364,17 @@ function _tracker_remove($nid, $uid = NULL, $changed = NULL) { // And then we push the out the new changed timestamp to our denormalized // tables. db_update('tracker_node') - ->fields(array( + ->fields([ 'changed' => $changed, 'published' => $node->isPublished(), - )) + ]) ->condition('nid', $nid) ->execute(); db_update('tracker_node') - ->fields(array( + ->fields([ 'changed' => $changed, 'published' => $node->isPublished(), - )) + ]) ->condition('nid', $nid) ->execute(); } diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc index e3082acf..de08c63c 100644 --- a/core/modules/tracker/tracker.pages.inc +++ b/core/modules/tracker/tracker.pages.inc @@ -19,8 +19,6 @@ use Drupal\node\Entity\Node; * * @return array * A renderable array. - * - * @see tracker_menu() */ function tracker_page($account = NULL) { if ($account) { @@ -30,7 +28,7 @@ function tracker_page($account = NULL) { ->condition('t.uid', $account->id()); } else { - $query = db_select('tracker_node', 't', array('target' => 'replica')) + $query = db_select('tracker_node', 't', ['target' => 'replica']) ->extend('Drupal\Core\Database\Query\PagerSelectExtender') ->addMetaData('base_table', 'tracker_node'); } @@ -39,7 +37,7 @@ function tracker_page($account = NULL) { // while keeping the correct order. $tracker_data = $query ->addTag('node_access') - ->fields('t', array('nid', 'changed')) + ->fields('t', ['nid', 'changed']) ->condition('t.published', 1) ->orderBy('t.changed', 'DESC') ->limit(25) @@ -86,34 +84,34 @@ function tracker_page($account = NULL) { $comments = $node->comment_count; } - $row = array( + $row = [ 'type' => node_get_type_label($node), - 'title' => array( - 'data' => array( + 'title' => [ + 'data' => [ '#type' => 'link', '#url' => $node->urlInfo(), '#title' => $node->getTitle(), - ), + ], 'data-history-node-id' => $node->id(), 'data-history-node-timestamp' => $node->getChangedTime(), - ), - 'author' => array( - 'data' => array( + ], + 'author' => [ + 'data' => [ '#theme' => 'username', '#account' => $node->getOwner(), - ), - ), - 'comments' => array( - 'class' => array('comments'), + ], + ], + 'comments' => [ + 'class' => ['comments'], 'data' => $comments, 'data-history-node-last-comment-timestamp' => $node->last_comment_timestamp, - ), - 'last updated' => array( - 'data' => t('@time ago', array( + ], + 'last updated' => [ + 'data' => t('@time ago', [ '@time' => \Drupal::service('date.formatter')->formatTimeDiffSince($node->last_activity), - )), - ), - ); + ]), + ], + ]; $rows[] = $row; @@ -128,16 +126,16 @@ function tracker_page($account = NULL) { // Add the list cache tag for nodes. $cache_tags = Cache::mergeTags($cache_tags, \Drupal::entityManager()->getDefinition('node')->getListCacheTags()); - $page['tracker'] = array( + $page['tracker'] = [ '#rows' => $rows, - '#header' => array(t('Type'), t('Title'), t('Author'), t('Comments'), t('Last updated')), + '#header' => [t('Type'), t('Title'), t('Author'), t('Comments'), t('Last updated')], '#type' => 'table', '#empty' => t('No content available.'), - ); - $page['pager'] = array( + ]; + $page['pager'] = [ '#type' => 'pager', '#weight' => 10, - ); + ]; $page['#sorted'] = TRUE; $page['#cache']['tags'] = $cache_tags; $page['#cache']['contexts'][] = 'user.node_grants:view'; diff --git a/core/modules/tracker/tracker.routing.yml b/core/modules/tracker/tracker.routing.yml index ed2f8681..ea9855f3 100644 --- a/core/modules/tracker/tracker.routing.yml +++ b/core/modules/tracker/tracker.routing.yml @@ -13,7 +13,7 @@ tracker.users_recent_content: _title: 'My recent content' requirements: _permission: 'access content' - _access_tracker_own_information: 'TRUE' + _custom_access: '\Drupal\tracker\Controller\TrackerUserRecent::checkAccess' user: \d+ tracker.user_tab: diff --git a/core/modules/tracker/tracker.services.yml b/core/modules/tracker/tracker.services.yml deleted file mode 100644 index 11e29e7e..00000000 --- a/core/modules/tracker/tracker.services.yml +++ /dev/null @@ -1,5 +0,0 @@ -services: - access_check.tracker.view_own: - class: Drupal\tracker\Access\ViewOwnTrackerAccessCheck - tags: - - { name: access_check, applies_to: _access_tracker_own_information } diff --git a/core/modules/tracker/tracker.views.inc b/core/modules/tracker/tracker.views.inc index b7e4b954..54402879 100644 --- a/core/modules/tracker/tracker.views.inc +++ b/core/modules/tracker/tracker.views.inc @@ -9,146 +9,146 @@ * Implements hook_views_data(). */ function tracker_views_data() { - $data = array(); + $data = []; $data['tracker_node']['table']['group'] = t('Tracker'); - $data['tracker_node']['table']['join'] = array( - 'node_field_data' => array( + $data['tracker_node']['table']['join'] = [ + 'node_field_data' => [ 'type' => 'INNER', 'left_field' => 'nid', 'field' => 'nid', - ), - ); - $data['tracker_node']['nid'] = array( + ], + ]; + $data['tracker_node']['nid'] = [ 'title' => t('Nid'), 'help' => t('The node ID of the node.'), - 'field' => array( + 'field' => [ 'id' => 'node', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'node_nid', 'name field' => 'title', 'numeric' => TRUE, 'validate type' => 'nid', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['tracker_node']['published'] = array( + ], + ]; + $data['tracker_node']['published'] = [ 'title' => t('Published'), 'help' => t('Whether or not the node is published.'), - 'field' => array( + 'field' => [ 'id' => 'boolean', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'boolean', 'label' => t('Published'), 'type' => 'yes-no', 'accept null' => TRUE, 'use_equal' => TRUE, - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['tracker_node']['changed'] = array( + ], + ]; + $data['tracker_node']['changed'] = [ 'title' => t('Updated date'), 'help' => t('The date the node was last updated.'), - 'field' => array( + 'field' => [ 'id' => 'date', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'date', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'date', - ), - ); + ], + ]; $data['tracker_user']['table']['group'] = t('Tracker - User'); - $data['tracker_user']['table']['join'] = array( - 'node_field_data' => array( + $data['tracker_user']['table']['join'] = [ + 'node_field_data' => [ 'type' => 'INNER', 'left_field' => 'nid', 'field' => 'nid', - ), - 'user_field_data' => array( + ], + 'user_field_data' => [ 'type' => 'INNER', 'left_field' => 'uid', 'field' => 'uid', - ), - ); - $data['tracker_user']['nid'] = array( + ], + ]; + $data['tracker_user']['nid'] = [ 'title' => t('Nid'), 'help' => t('The node ID of the node a user created or commented on. You must use an argument or filter on UID or you will get misleading results using this field.'), - 'field' => array( + 'field' => [ 'id' => 'node', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'node_nid', 'name field' => 'title', 'numeric' => TRUE, 'validate type' => 'nid', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['tracker_user']['uid'] = array( + ], + ]; + $data['tracker_user']['uid'] = [ 'title' => t('Uid'), 'help' => t('The user ID of a user who touched the node (either created or commented on it).'), - 'field' => array( + 'field' => [ 'id' => 'user_name', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'user_uid', 'name field' => 'name', - ), - 'filter' => array( + ], + 'filter' => [ 'title' => t('Name'), 'id' => 'user_name', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['tracker_user']['published'] = array( + ], + ]; + $data['tracker_user']['published'] = [ 'title' => t('Published'), 'help' => t('Whether or not the node is published. You must use an argument or filter on UID or you will get misleading results using this field.'), - 'field' => array( + 'field' => [ 'id' => 'boolean', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'boolean', 'label' => t('Published'), 'type' => 'yes-no', 'accept null' => TRUE, 'use_equal' => TRUE, - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['tracker_user']['changed'] = array( + ], + ]; + $data['tracker_user']['changed'] = [ 'title' => t('Updated date'), 'help' => t('The date the node was last updated or commented on. You must use an argument or filter on UID or you will get misleading results using this field.'), - 'field' => array( + 'field' => [ 'id' => 'date', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'date', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'date', - ), - ); + ], + ]; return $data; } @@ -158,22 +158,22 @@ function tracker_views_data() { */ function tracker_views_data_alter(&$data) { // Provide additional uid_touch handlers which are handled by tracker - $data['node_field_data']['uid_touch_tracker'] = array( + $data['node_field_data']['uid_touch_tracker'] = [ 'group' => t('Tracker - User'), 'title' => t('User posted or commented'), 'help' => t('Display nodes only if a user posted the node or commented on the node.'), - 'argument' => array( + 'argument' => [ 'field' => 'uid', 'name table' => 'users_field_data', 'name field' => 'name', 'id' => 'tracker_user_uid', 'no group by' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'field' => 'uid', 'name table' => 'users_field_data', 'name field' => 'name', 'id' => 'tracker_user_uid' - ), - ); + ], + ]; } diff --git a/core/modules/update/migration_templates/update_settings.yml b/core/modules/update/migration_templates/update_settings.yml index ad224723..a7adfd7d 100644 --- a/core/modules/update/migration_templates/update_settings.yml +++ b/core/modules/update/migration_templates/update_settings.yml @@ -11,6 +11,7 @@ source: - update_notification_threshold - update_notify_emails - update_check_frequency + source_module: update process: 'fetch/max_attempts': update_max_fetch_attempts 'fetch/url': update_fetch_url diff --git a/core/modules/update/src/Controller/UpdateController.php b/core/modules/update/src/Controller/UpdateController.php index cdd63b83..30b25c20 100644 --- a/core/modules/update/src/Controller/UpdateController.php +++ b/core/modules/update/src/Controller/UpdateController.php @@ -44,9 +44,9 @@ public static function create(ContainerInterface $container) { * A build array with the update status of projects. */ public function updateStatus() { - $build = array( + $build = [ '#theme' => 'update_report' - ); + ]; if ($available = update_get_available(TRUE)) { $this->moduleHandler()->loadInclude('update', 'compare.inc'); $build['#data'] = update_calculate_project_data($available); @@ -59,15 +59,15 @@ public function updateStatus() { */ public function updateStatusManually() { $this->updateManager->refreshUpdateData(); - $batch = array( - 'operations' => array( - array(array($this->updateManager, 'fetchDataBatch'), array()), - ), + $batch = [ + 'operations' => [ + [[$this->updateManager, 'fetchDataBatch'], []], + ], 'finished' => 'update_fetch_data_finished', 'title' => t('Checking available update data'), 'progress_message' => t('Trying to check available update data ...'), 'error_message' => t('Error checking available update data.'), - ); + ]; batch_set($batch); return batch_process('admin/reports/updates'); } diff --git a/core/modules/update/src/Form/UpdateManagerInstall.php b/core/modules/update/src/Form/UpdateManagerInstall.php index 3bc2c78a..a99383ab 100644 --- a/core/modules/update/src/Form/UpdateManagerInstall.php +++ b/core/modules/update/src/Form/UpdateManagerInstall.php @@ -79,41 +79,41 @@ public function buildForm(array $form, FormStateInterface $form_state) { return $form; } - $form['help_text'] = array( + $form['help_text'] = [ '#prefix' => '

          ', - '#markup' => $this->t('You can find modules and themes on drupal.org. The following file extensions are supported: %extensions.', array( + '#markup' => $this->t('You can find modules and themes on drupal.org. The following file extensions are supported: %extensions.', [ ':module_url' => 'https://www.drupal.org/project/modules', ':theme_url' => 'https://www.drupal.org/project/themes', ':drupal_org_url' => 'https://www.drupal.org', '%extensions' => archiver_get_extensions(), - )), + ]), '#suffix' => '

          ', - ); + ]; - $form['project_url'] = array( + $form['project_url'] = [ '#type' => 'url', '#title' => $this->t('Install from a URL'), - '#description' => $this->t('For example: %url', array('%url' => 'http://ftp.drupal.org/files/projects/name.tar.gz')), - ); + '#description' => $this->t('For example: %url', ['%url' => 'https://ftp.drupal.org/files/projects/name.tar.gz']), + ]; - $form['information'] = array( + $form['information'] = [ '#prefix' => '', '#markup' => $this->t('Or'), '#suffix' => '', - ); + ]; - $form['project_upload'] = array( + $form['project_upload'] = [ '#type' => 'file', '#title' => $this->t('Upload a module or theme archive to install'), - '#description' => $this->t('For example: %filename from your local computer', array('%filename' => 'name.tar.gz')), - ); + '#description' => $this->t('For example: %filename from your local computer', ['%filename' => 'name.tar.gz']), + ]; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#button_type' => 'primary', '#value' => $this->t('Install'), - ); + ]; return $form; } @@ -136,12 +136,12 @@ public function submitForm(array &$form, FormStateInterface $form_state) { if ($form_state->getValue('project_url')) { $local_cache = update_manager_file_get($form_state->getValue('project_url')); if (!$local_cache) { - drupal_set_message($this->t('Unable to retrieve Drupal project from %url.', array('%url' => $form_state->getValue('project_url'))), 'error'); + drupal_set_message($this->t('Unable to retrieve Drupal project from %url.', ['%url' => $form_state->getValue('project_url')]), 'error'); return; } } elseif ($_FILES['files']['name']['project_upload']) { - $validators = array('file_validate_extensions' => array(archiver_get_extensions())); + $validators = ['file_validate_extensions' => [archiver_get_extensions()]]; if (!($finfo = file_save_upload('project_upload', $validators, NULL, 0, FILE_EXISTS_REPLACE))) { // Failed to upload the file. file_save_upload() calls // drupal_set_message() on failure. @@ -170,7 +170,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // MODULE/) and others list an actual file (i.e., MODULE/README.TXT). $project = strtok($files[0], '/\\'); - $archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', array($project, $local_cache, $directory)); + $archive_errors = $this->moduleHandler->invokeAll('verify_update_archive', [$project, $local_cache, $directory]); if (!empty($archive_errors)) { drupal_set_message(array_shift($archive_errors), 'error'); // @todo: Fix me in D8: We need a way to set multiple errors on the same @@ -204,20 +204,20 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } if (!$project_title) { - drupal_set_message($this->t('Unable to determine %project name.', array('%project' => $project)), 'error'); + drupal_set_message($this->t('Unable to determine %project name.', ['%project' => $project]), 'error'); } if ($updater->isInstalled()) { - drupal_set_message($this->t('%project is already installed.', array('%project' => $project_title)), 'error'); + drupal_set_message($this->t('%project is already installed.', ['%project' => $project_title]), 'error'); return; } $project_real_location = drupal_realpath($project_location); - $arguments = array( + $arguments = [ 'project' => $project, 'updater_name' => get_class($updater), 'local_url' => $project_real_location, - ); + ]; // This process is inherently difficult to test therefore use a state flag. $test_authorize = FALSE; @@ -232,7 +232,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { if (fileowner($project_real_location) == fileowner($this->sitePath) && !$test_authorize) { $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize'); $filetransfer = new Local($this->root); - $response = call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments)); + $response = call_user_func_array('update_authorize_run_install', array_merge([$filetransfer], $arguments)); if ($response instanceof Response) { $form_state->setResponse($response); } diff --git a/core/modules/update/src/Form/UpdateManagerUpdate.php b/core/modules/update/src/Form/UpdateManagerUpdate.php index 44b7f626..0b319686 100644 --- a/core/modules/update/src/Form/UpdateManagerUpdate.php +++ b/core/modules/update/src/Form/UpdateManagerUpdate.php @@ -64,13 +64,13 @@ public static function create(ContainerInterface $container) { public function buildForm(array $form, FormStateInterface $form_state) { $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); - $last_markup = array( + $last_markup = [ '#theme' => 'update_last_check', '#last' => $this->state->get('update.last_check') ?: 0, - ); - $form['last_check'] = array( - '#markup' => drupal_render($last_markup), - ); + ]; + $form['last_check'] = [ + '#markup' => \Drupal::service('renderer')->render($last_markup), + ]; if (!_update_manager_check_backends($form, 'update')) { return $form; @@ -78,9 +78,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { $available = update_get_available(TRUE); if (empty($available)) { - $form['message'] = array( + $form['message'] = [ '#markup' => $this->t('There was a problem getting update information. Try again later.'), - ); + ]; return $form; } @@ -91,11 +91,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { // manual updates, such as core). Then, each subarray is an array of // projects of that type, indexed by project short name, and containing an // array of data for cells in that project's row in the appropriate table. - $projects = array(); + $projects = []; // This stores the actual download link we're going to update from for each // project in the form, regardless of if it's enabled or disabled. - $form['project_downloads'] = array('#tree' => TRUE); + $form['project_downloads'] = ['#tree' => TRUE]; $this->moduleHandler->loadInclude('update', 'inc', 'update.compare'); $project_data = update_calculate_project_data($available); foreach ($project_data as $name => $project) { @@ -134,25 +134,25 @@ public function buildForm(array $form, FormStateInterface $form_state) { $recommended_version .= '
          {{ major_update_warning_text }}
          '; } - $recommended_version = array( + $recommended_version = [ '#type' => 'inline_template', '#template' => $recommended_version, - '#context' => array( + '#context' => [ 'release_version' => $recommended_release['version'], 'release_link' => $recommended_release['release_link'], - 'project_title' => $this->t('Release notes for @project_title', array('@project_title' => $project['title'])), + 'project_title' => $this->t('Release notes for @project_title', ['@project_title' => $project['title']]), 'major_update_warning_title' => $this->t('Major upgrade warning'), 'major_update_warning_text' => $this->t('This update is a major version update which means that it may not be backwards compatible with your currently running version. It is recommended that you read the release notes and proceed at your own risk.'), 'release_notes' => $this->t('Release notes'), - ), - ); + ], + ]; // Create an entry for this project. - $entry = array( + $entry = [ 'title' => $project_name, 'installed_version' => $project['existing_version'], - 'recommended_version' => array('data' => $recommended_version), - ); + 'recommended_version' => ['data' => $recommended_version], + ]; switch ($project['status']) { case UPDATE_NOT_SECURE: @@ -181,11 +181,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { } // Use the project title for the tableselect checkboxes. - $entry['title'] = array('data' => array( - '#title' => $entry['title'], - '#markup' => $entry['title'], - )); - $entry['#attributes'] = array('class' => array('update-' . $type)); + $entry['title'] = [ + 'data' => [ + '#title' => $entry['title'], + '#markup' => $entry['title'], + ], + ]; + $entry['#attributes'] = ['class' => ['update-' . $type]]; // Drupal core needs to be upgraded manually. $needs_manual = $project['project_type'] == 'core'; @@ -198,15 +200,15 @@ public function buildForm(array $form, FormStateInterface $form_state) { unset($entry['#weight']); $attributes = $entry['#attributes']; unset($entry['#attributes']); - $entry = array( + $entry = [ 'data' => $entry, - ) + $attributes; + ] + $attributes; } else { - $form['project_downloads'][$name] = array( + $form['project_downloads'][$name] = [ '#type' => 'value', '#value' => $recommended_release['download_link'], - ); + ]; } // Based on what kind of project this is, save the entry into the @@ -230,62 +232,62 @@ public function buildForm(array $form, FormStateInterface $form_state) { } if (empty($projects)) { - $form['message'] = array( + $form['message'] = [ '#markup' => $this->t('All of your projects are up to date.'), - ); + ]; return $form; } - $headers = array( - 'title' => array( + $headers = [ + 'title' => [ 'data' => $this->t('Name'), - 'class' => array('update-project-name'), - ), + 'class' => ['update-project-name'], + ], 'installed_version' => $this->t('Installed version'), 'recommended_version' => $this->t('Recommended version'), - ); + ]; if (!empty($projects['enabled'])) { - $form['projects'] = array( + $form['projects'] = [ '#type' => 'tableselect', '#header' => $headers, '#options' => $projects['enabled'], - ); + ]; if (!empty($projects['disabled'])) { $form['projects']['#prefix'] = '

          ' . $this->t('Enabled') . '

          '; } } if (!empty($projects['disabled'])) { - $form['disabled_projects'] = array( + $form['disabled_projects'] = [ '#type' => 'tableselect', '#header' => $headers, '#options' => $projects['disabled'], '#weight' => 1, '#prefix' => '

          ' . $this->t('Disabled') . '

          ', - ); + ]; } // If either table has been printed yet, we need a submit button and to // validate the checkboxes. if (!empty($projects['enabled']) || !empty($projects['disabled'])) { - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Download these updates'), - ); + ]; } if (!empty($projects['manual'])) { $prefix = '

          ' . $this->t('Manual updates required') . '

          '; - $prefix .= '

          ' . $this->t('Updates of Drupal core are not supported at this time.') . '

          '; - $form['manual_updates'] = array( + $prefix .= '

          ' . $this->t('Automatic updates of Drupal core are not supported at this time.') . '

          '; + $form['manual_updates'] = [ '#type' => 'table', '#header' => $headers, '#rows' => $projects['manual'], '#prefix' => $prefix, '#weight' => 120, - ); + ]; } return $form; @@ -311,29 +313,29 @@ public function validateForm(array &$form, FormStateInterface $form_state) { */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->moduleHandler->loadInclude('update', 'inc', 'update.manager'); - $projects = array(); - foreach (array('projects', 'disabled_projects') as $type) { + $projects = []; + foreach (['projects', 'disabled_projects'] as $type) { if (!$form_state->isValueEmpty($type)) { $projects = array_merge($projects, array_keys(array_filter($form_state->getValue($type)))); } } - $operations = array(); + $operations = []; foreach ($projects as $project) { - $operations[] = array( + $operations[] = [ 'update_manager_batch_project_get', - array( + [ $project, - $form_state->getValue(array('project_downloads', $project)), - ), - ); + $form_state->getValue(['project_downloads', $project]), + ], + ]; } - $batch = array( + $batch = [ 'title' => $this->t('Downloading updates'), 'init_message' => $this->t('Preparing to download selected updates'), 'operations' => $operations, 'finished' => 'update_manager_download_batch_finished', 'file' => drupal_get_path('module', 'update') . '/update.manager.inc', - ); + ]; batch_set($batch); } diff --git a/core/modules/update/src/Form/UpdateReady.php b/core/modules/update/src/Form/UpdateReady.php index c8f64a3e..ef9a2f17 100644 --- a/core/modules/update/src/Form/UpdateReady.php +++ b/core/modules/update/src/Form/UpdateReady.php @@ -91,23 +91,23 @@ public function buildForm(array $form, FormStateInterface $form_state) { return $form; } - $form['backup'] = array( + $form['backup'] = [ '#prefix' => '', - '#markup' => $this->t('Back up your database and site before you continue. Learn how.', array(':backup_url' => 'https://www.drupal.org/node/22281')), + '#markup' => $this->t('Back up your database and site before you continue. Learn how.', [':backup_url' => 'https://www.drupal.org/node/22281']), '#suffix' => '', - ); + ]; - $form['maintenance_mode'] = array( + $form['maintenance_mode'] = [ '#title' => $this->t('Perform updates with site in maintenance mode (strongly recommended)'), '#type' => 'checkbox', '#default_value' => TRUE, - ); + ]; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Continue'), - ); + ]; return $form; } @@ -126,7 +126,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Make sure the Updater registry is loaded. drupal_get_updaters(); - $updates = array(); + $updates = []; $directory = _update_manager_extract_directory(); $projects = $_SESSION['update_manager_update_projects']; @@ -137,11 +137,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $project_location = $directory . '/' . $project; $updater = Updater::factory($project_location, $this->root); $project_real_location = drupal_realpath($project_location); - $updates[] = array( + $updates[] = [ 'project' => $project, 'updater_name' => get_class($updater), 'local_url' => $project_real_location, - ); + ]; } // If the owner of the last directory we extracted is the same as the @@ -164,7 +164,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // The page title must be passed here to ensure it is initially used // when authorize.php loads for the first time with the FTP/SSH // credentials form. - system_authorized_init('update_authorize_run_update', __DIR__ . '/../../update.authorize.inc', array($updates), $this->t('Update manager')); + system_authorized_init('update_authorize_run_update', __DIR__ . '/../../update.authorize.inc', [$updates], $this->t('Update manager')); $form_state->setRedirectUrl(system_authorized_get_url()); } } diff --git a/core/modules/update/src/Tests/UpdateTestBase.php b/core/modules/update/src/Tests/UpdateTestBase.php index 9cb3c20f..e243d0b8 100644 --- a/core/modules/update/src/Tests/UpdateTestBase.php +++ b/core/modules/update/src/Tests/UpdateTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\update\Tests; +@trigger_error(__NAMESPACE__ . '\UpdateTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\update\Functional\UpdateTestBase', E_USER_DEPRECATED); + use Drupal\Core\DrupalKernel; use Drupal\Core\Url; use Drupal\simpletest\WebTestBase; @@ -22,6 +24,9 @@ * (via the 'update_test_xml_map' variable), and then performs a series of * assertions that the report matches our expectations given the specific * initial state and availability scenario. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\update\Functional\UpdateTestBase instead. */ abstract class UpdateTestBase extends WebTestBase { @@ -58,12 +63,12 @@ protected function setUp() { * (optional) A string containing the URL to fetch update data from. * Defaults to 'update-test'. * - * @see Drupal\update_test\Controller\UpdateTestController::updateTest() + * @see \Drupal\update_test\Controller\UpdateTestController::updateTest() */ protected function refreshUpdateStatus($xml_map, $url = 'update-test') { // Tell the Update Manager module to fetch from the URL provided by // update_test module. - $this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, array('absolute' => TRUE))->toString())->save(); + $this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, ['absolute' => TRUE])->toString())->save(); // Save the map for UpdateTestController::updateTest() to use. $this->config('update_test.settings')->set('xml_map', $xml_map)->save(); // Manually check the update status. diff --git a/core/modules/update/src/UpdateFetcher.php b/core/modules/update/src/UpdateFetcher.php index 29d5582e..2b03c9c1 100644 --- a/core/modules/update/src/UpdateFetcher.php +++ b/core/modules/update/src/UpdateFetcher.php @@ -62,7 +62,7 @@ public function fetchProjectData(array $project, $site_key = '') { $data = ''; try { $data = (string) $this->httpClient - ->get($url, array('headers' => array('Accept' => 'text/xml'))) + ->get($url, ['headers' => ['Accept' => 'text/xml']]) ->getBody(); } catch (RequestException $exception) { diff --git a/core/modules/update/src/UpdateFetcherInterface.php b/core/modules/update/src/UpdateFetcherInterface.php index 8d8f2a9f..e9f44103 100644 --- a/core/modules/update/src/UpdateFetcherInterface.php +++ b/core/modules/update/src/UpdateFetcherInterface.php @@ -7,6 +7,26 @@ */ interface UpdateFetcherInterface { + /** + * Project's status cannot be checked. + */ + const NOT_CHECKED = -1; + + /** + * No available update data was found for project. + */ + const UNKNOWN = -2; + + /** + * There was a failure fetching available update data for this project. + */ + const NOT_FETCHED = -3; + + /** + * We need to (re)fetch available update data for this project. + */ + const FETCH_PENDING = -4; + /** * Returns the base of the URL to fetch available update data for a project. * diff --git a/core/modules/update/src/UpdateManager.php b/core/modules/update/src/UpdateManager.php index 52a7eb28..07416915 100644 --- a/core/modules/update/src/UpdateManager.php +++ b/core/modules/update/src/UpdateManager.php @@ -91,7 +91,7 @@ public function __construct(ConfigFactoryInterface $config_factory, ModuleHandle $this->keyValueStore = $key_value_expirable_factory->get('update'); $this->themeHandler = $theme_handler; $this->availableReleasesTempStore = $key_value_expirable_factory->get('update_available_releases'); - $this->projects = array(); + $this->projects = []; } /** @@ -151,11 +151,11 @@ public function getProjects() { * {@inheritdoc} */ public function projectStorage($key) { - $projects = array(); + $projects = []; // On certain paths, we should clear the data and recompute the projects for // update status of the site to avoid presenting stale information. - $route_names = array( + $route_names = [ 'update.theme_update', 'system.modules_list', 'system.theme_install', @@ -169,12 +169,12 @@ public function projectStorage($key) { 'update.manual_status', 'update.confirmation_page', 'system.themes_page', - ); + ]; if (in_array(\Drupal::routeMatch()->getRouteName(), $route_names)) { $this->keyValueStore->delete($key); } else { - $projects = $this->keyValueStore->get($key, array()); + $projects = $this->keyValueStore->get($key, []); } return $projects; } @@ -198,10 +198,10 @@ public function fetchDataBatch(&$context) { if ($item = $this->updateProcessor->claimQueueItem()) { if ($this->updateProcessor->processFetchTask($item->data)) { $context['results']['updated']++; - $context['message'] = $this->t('Checked available update data for %title.', array('%title' => $item->data['info']['name'])); + $context['message'] = $this->t('Checked available update data for %title.', ['%title' => $item->data['info']['name']]); } else { - $context['message'] = $this->t('Failed to check available update data for %title.', array('%title' => $item->data['info']['name'])); + $context['message'] = $this->t('Failed to check available update data for %title.', ['%title' => $item->data['info']['name']]); $context['results']['failures']++; } $context['sandbox']['progress']++; diff --git a/core/modules/update/src/UpdateManagerInterface.php b/core/modules/update/src/UpdateManagerInterface.php index d3ea88f4..036138d4 100644 --- a/core/modules/update/src/UpdateManagerInterface.php +++ b/core/modules/update/src/UpdateManagerInterface.php @@ -7,6 +7,31 @@ */ interface UpdateManagerInterface { + /** + * Project is missing security update(s). + */ + const NOT_SECURE = 1; + + /** + * Current release has been unpublished and is no longer available. + */ + const REVOKED = 2; + + /** + * Current release is no longer supported by the project maintainer. + */ + const NOT_SUPPORTED = 3; + + /** + * Project has a new release available, but it is not a security release. + */ + const NOT_CURRENT = 4; + + /** + * Project is up to date. + */ + const CURRENT = 5; + /** * Fetches an array of installed and enabled projects. * diff --git a/core/modules/update/src/UpdateProcessor.php b/core/modules/update/src/UpdateProcessor.php index 75e3241c..25dfc7a0 100644 --- a/core/modules/update/src/UpdateProcessor.php +++ b/core/modules/update/src/UpdateProcessor.php @@ -104,8 +104,8 @@ public function __construct(ConfigFactoryInterface $config_factory, QueueFactory $this->availableReleasesTempStore = $key_value_expirable_factory->get('update_available_releases'); $this->stateStore = $state_store; $this->privateKey = $private_key; - $this->fetchTasks = array(); - $this->failed = array(); + $this->fetchTasks = []; + $this->failed = []; } /** @@ -151,7 +151,7 @@ public function processFetchTask($project) { $max_fetch_attempts = $this->updateSettings->get('fetch.max_attempts'); $success = FALSE; - $available = array(); + $available = []; $site_key = Crypt::hmacBase64($base_url, $this->privateKey->get()); $fetch_url_base = $this->updateFetcher->getFetchBaseUrl($project); $project_name = $project['name']; @@ -219,23 +219,23 @@ protected function parseXml($raw_xml) { if (!isset($xml->short_name)) { return NULL; } - $data = array(); + $data = []; foreach ($xml as $k => $v) { $data[$k] = (string) $v; } - $data['releases'] = array(); + $data['releases'] = []; if (isset($xml->releases)) { foreach ($xml->releases->children() as $release) { $version = (string) $release->version; - $data['releases'][$version] = array(); + $data['releases'][$version] = []; foreach ($release->children() as $k => $v) { $data['releases'][$version][$k] = (string) $v; } - $data['releases'][$version]['terms'] = array(); + $data['releases'][$version]['terms'] = []; if ($release->terms) { foreach ($release->terms->children() as $term) { if (!isset($data['releases'][$version]['terms'][(string) $term->name])) { - $data['releases'][$version]['terms'][(string) $term->name] = array(); + $data['releases'][$version]['terms'][(string) $term->name] = []; } $data['releases'][$version]['terms'][(string) $term->name][] = (string) $term->value; } diff --git a/core/modules/update/src/UpdateProcessorInterface.php b/core/modules/update/src/UpdateProcessorInterface.php index f744bfb2..22ae904f 100644 --- a/core/modules/update/src/UpdateProcessorInterface.php +++ b/core/modules/update/src/UpdateProcessorInterface.php @@ -2,7 +2,6 @@ namespace Drupal\update; - /** * Processor of project update information. */ diff --git a/core/modules/update/src/UpdateSettingsForm.php b/core/modules/update/src/UpdateSettingsForm.php index d830de57..1860269d 100644 --- a/core/modules/update/src/UpdateSettingsForm.php +++ b/core/modules/update/src/UpdateSettingsForm.php @@ -59,42 +59,42 @@ protected function getEditableConfigNames() { public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('update.settings'); - $form['update_check_frequency'] = array( + $form['update_check_frequency'] = [ '#type' => 'radios', '#title' => t('Check for updates'), '#default_value' => $config->get('check.interval_days'), - '#options' => array( + '#options' => [ '1' => t('Daily'), '7' => t('Weekly'), - ), + ], '#description' => t('Select how frequently you want to automatically check for new releases of your currently installed modules and themes.'), - ); + ]; - $form['update_check_disabled'] = array( + $form['update_check_disabled'] = [ '#type' => 'checkbox', '#title' => t('Check for updates of uninstalled modules and themes'), '#default_value' => $config->get('check.disabled_extensions'), - ); + ]; $notification_emails = $config->get('notification.emails'); - $form['update_notify_emails'] = array( + $form['update_notify_emails'] = [ '#type' => 'textarea', '#title' => t('Email addresses to notify when updates are available'), '#rows' => 4, '#default_value' => implode("\n", $notification_emails), '#description' => t('Whenever your site checks for available updates and finds new releases, it can notify a list of users via email. Put each address on a separate line. If blank, no emails will be sent.'), - ); + ]; - $form['update_notification_threshold'] = array( + $form['update_notification_threshold'] = [ '#type' => 'radios', '#title' => t('Email notification threshold'), '#default_value' => $config->get('notification.threshold'), - '#options' => array( + '#options' => [ 'all' => t('All newer versions'), 'security' => t('Only security updates'), - ), - '#description' => t('You can choose to send email only if a security update is available, or to be notified about all newer versions. If there are updates available of Drupal core or any of your installed modules and themes, your site will always print a message on the status report page, and will also display an error message on administration pages if there is a security update.', array(':status_report' => $this->url('system.status'))) - ); + ], + '#description' => t('You can choose to send email only if a security update is available, or to be notified about all newer versions. If there are updates available of Drupal core or any of your installed modules and themes, your site will always print a message on the status report page, and will also display an error message on administration pages if there is a security update.', [':status_report' => $this->url('system.status')]) + ]; return parent::buildForm($form, $form_state); } @@ -105,8 +105,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function validateForm(array &$form, FormStateInterface $form_state) { $form_state->set('notify_emails', []); if (!$form_state->isValueEmpty('update_notify_emails')) { - $valid = array(); - $invalid = array(); + $valid = []; + $invalid = []; foreach (explode("\n", trim($form_state->getValue('update_notify_emails'))) as $email) { $email = trim($email); if (!empty($email)) { @@ -122,10 +122,10 @@ public function validateForm(array &$form, FormStateInterface $form_state) { $form_state->set('notify_emails', $valid); } elseif (count($invalid) == 1) { - $form_state->setErrorByName('update_notify_emails', $this->t('%email is not a valid email address.', array('%email' => reset($invalid)))); + $form_state->setErrorByName('update_notify_emails', $this->t('%email is not a valid email address.', ['%email' => reset($invalid)])); } else { - $form_state->setErrorByName('update_notify_emails', $this->t('%emails are not valid email addresses.', array('%emails' => implode(', ', $invalid)))); + $form_state->setErrorByName('update_notify_emails', $this->t('%emails are not valid email addresses.', ['%emails' => implode(', ', $invalid)])); } } diff --git a/core/modules/update/tests/aaa_update_test/aaa_update_test.info.yml b/core/modules/update/tests/aaa_update_test/aaa_update_test.info.yml index 4dec9ec5..56a77e79 100644 --- a/core/modules/update/tests/aaa_update_test/aaa_update_test.info.yml +++ b/core/modules/update/tests/aaa_update_test/aaa_update_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml b/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml index 4dec9ec5..56a77e79 100644 --- a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml +++ b/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.info.yml b/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.info.yml index e117311b..a0a656dc 100644 --- a/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.info.yml +++ b/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.info.yml b/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.info.yml index 1f1a78b7..3e27ba8c 100644 --- a/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.info.yml +++ b/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/tests/modules/update_test/src/Controller/UpdateTestController.php b/core/modules/update/tests/modules/update_test/src/Controller/UpdateTestController.php index bdf6d343..3ca46baa 100644 --- a/core/modules/update/tests/modules/update_test/src/Controller/UpdateTestController.php +++ b/core/modules/update/tests/modules/update_test/src/Controller/UpdateTestController.php @@ -64,7 +64,7 @@ public function updateTest($project_name, $version) { } $file = __DIR__ . "/../../$project_name.$availability_scenario.xml"; - $headers = array('Content-Type' => 'text/xml; charset=utf-8'); + $headers = ['Content-Type' => 'text/xml; charset=utf-8']; if (!is_file($file)) { // Return an empty response. return new Response('', 200, $headers); diff --git a/core/modules/update/tests/modules/update_test/src/Plugin/Archiver/UpdateTestArchiver.php b/core/modules/update/tests/modules/update_test/src/Plugin/Archiver/UpdateTestArchiver.php index a9e499a7..ffa4e46d 100644 --- a/core/modules/update/tests/modules/update_test/src/Plugin/Archiver/UpdateTestArchiver.php +++ b/core/modules/update/tests/modules/update_test/src/Plugin/Archiver/UpdateTestArchiver.php @@ -32,7 +32,7 @@ public function remove($path) { /** * {@inheritdoc} */ - public function extract($path, array $files = array()) { + public function extract($path, array $files = []) { return $this; } @@ -40,7 +40,7 @@ public function extract($path, array $files = array()) { * {@inheritdoc} */ public function listContents() { - return array(); + return []; } } diff --git a/core/modules/update/tests/modules/update_test/src/TestFileTransferWithSettingsForm.php b/core/modules/update/tests/modules/update_test/src/TestFileTransferWithSettingsForm.php index 5737c09c..4afcade7 100644 --- a/core/modules/update/tests/modules/update_test/src/TestFileTransferWithSettingsForm.php +++ b/core/modules/update/tests/modules/update_test/src/TestFileTransferWithSettingsForm.php @@ -29,11 +29,11 @@ public static function factory($jail, $settings) { * Returns a settings form with a text field to input a username. */ public function getSettingsForm() { - $form = array(); - $form['update_test_username'] = array( + $form = []; + $form['update_test_username'] = [ '#type' => 'textfield', '#title' => t('Update Test Username'), - ); + ]; return $form; } diff --git a/core/modules/update/tests/modules/update_test/update_test.info.yml b/core/modules/update/tests/modules/update_test/update_test.info.yml index e886a54a..8903eee9 100644 --- a/core/modules/update/tests/modules/update_test/update_test.info.yml +++ b/core/modules/update/tests/modules/update_test/update_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/tests/modules/update_test/update_test.module b/core/modules/update/tests/modules/update_test/update_test.module index 90b6cdc0..5dd20706 100644 --- a/core/modules/update/tests/modules/update_test/update_test.module +++ b/core/modules/update/tests/modules/update_test/update_test.module @@ -20,7 +20,7 @@ use Drupal\Core\Extension\Extension; */ function update_test_system_info_alter(&$info, Extension $file) { $setting = \Drupal::config('update_test.settings')->get('system_info'); - foreach (array('#all', $file->getName()) as $id) { + foreach (['#all', $file->getName()] as $id) { if (!empty($setting[$id])) { foreach ($setting[$id] as $key => $value) { $info[$key] = $value; @@ -44,7 +44,7 @@ function update_test_update_status_alter(&$projects) { $setting = \Drupal::config('update_test.settings')->get('update_status'); if (!empty($setting)) { foreach ($projects as $project_name => &$project) { - foreach (array('#all', $project_name) as $id) { + foreach (['#all', $project_name] as $id) { if (!empty($setting[$id])) { foreach ($setting[$id] as $key => $value) { $project[$key] = $value; @@ -62,11 +62,11 @@ function update_test_filetransfer_info() { // Define a test file transfer method, to ensure that there will always be at // least one method available in the user interface (regardless of the // environment in which the update manager tests are run). - return array( - 'system_test' => array( + return [ + 'system_test' => [ 'title' => t('Update Test FileTransfer'), 'class' => 'Drupal\update_test\TestFileTransferWithSettingsForm', 'weight' => -20, - ), - ); + ], + ]; } diff --git a/core/modules/update/src/Tests/FileTransferAuthorizeFormTest.php b/core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php similarity index 83% rename from core/modules/update/src/Tests/FileTransferAuthorizeFormTest.php rename to core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php index 0d0989ba..d768b06d 100644 --- a/core/modules/update/src/Tests/FileTransferAuthorizeFormTest.php +++ b/core/modules/update/tests/src/Functional/FileTransferAuthorizeFormTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('administer modules', 'administer software updates', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer modules', 'administer software updates', 'administer site configuration']); $this->drupalLogin($admin_user); // Create a local cache so the module is not downloaded from drupal.org. $cache_directory = _update_manager_cache_directory(TRUE); - $validArchiveFile = __DIR__ . '/../../tests/update_test_new_module/8.x-1.0/update_test_new_module.tar.gz'; + $validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz'; copy($validArchiveFile, $cache_directory . '/update_test_new_module.tar.gz'); } diff --git a/core/modules/update/src/Tests/UpdateContribTest.php b/core/modules/update/tests/src/Functional/UpdateContribTest.php similarity index 85% rename from core/modules/update/src/Tests/UpdateContribTest.php rename to core/modules/update/tests/src/Functional/UpdateContribTest.php index 88cf3784..20d397cd 100644 --- a/core/modules/update/src/Tests/UpdateContribTest.php +++ b/core/modules/update/tests/src/Functional/UpdateContribTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); } /** * Tests when there is no available release data for a contrib module. */ - function testNoReleasesAvailable() { - $system_info = array( - '#all' => array( + public function testNoReleasesAvailable() { + $system_info = [ + '#all' => [ 'version' => '8.0.0', - ), - 'aaa_update_test' => array( + ], + 'aaa_update_test' => [ 'project' => 'aaa_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); - $this->refreshUpdateStatus(array('drupal' => '0.0', 'aaa_update_test' => 'no-releases')); + $this->refreshUpdateStatus(['drupal' => '0.0', 'aaa_update_test' => 'no-releases']); $this->drupalGet('admin/reports/updates'); // Cannot use $this->standardTests() because we need to check for the // 'No available releases found' string. @@ -60,24 +60,24 @@ function testNoReleasesAvailable() { /** * Tests the basic functionality of a contrib module on the status report. */ - function testUpdateContribBasic() { + public function testUpdateContribBasic() { $project_link = \Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')); - $system_info = array( - '#all' => array( + $system_info = [ + '#all' => [ 'version' => '8.0.0', - ), - 'aaa_update_test' => array( + ], + 'aaa_update_test' => [ 'project' => 'aaa_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); $this->refreshUpdateStatus( - array( + [ 'drupal' => '0.0', 'aaa_update_test' => '1_0', - ) + ] ); $this->standardTests(); $this->assertText(t('Up to date')); @@ -90,10 +90,10 @@ function testUpdateContribBasic() { $system_info['aaa_update_test']['hidden'] = TRUE; $this->config('update_test.settings')->set('system_info', $system_info)->save(); $this->refreshUpdateStatus( - array( + [ 'drupal' => '0.0', 'aaa_update_test' => '1_0', - ) + ] ); $this->assertNoRaw($project_link, 'Link to aaa_update_test project does not appear.'); @@ -101,10 +101,10 @@ function testUpdateContribBasic() { $system_info['aaa_update_test']['package'] = 'aaa_update_test'; $this->config('update_test.settings')->set('system_info', $system_info)->save(); $this->refreshUpdateStatus( - array( + [ 'drupal' => '0.0', 'aaa_update_test' => '1_0', - ) + ] ); $this->assertRaw($project_link, 'Link to aaa_update_test project appears.'); } @@ -122,40 +122,40 @@ function testUpdateContribBasic() { * if you sort alphabetically by module name (which is the order we see things * inside system_rebuild_module_data() for example). */ - function testUpdateContribOrder() { + public function testUpdateContribOrder() { // We want core to be version 8.0.0. - $system_info = array( - '#all' => array( + $system_info = [ + '#all' => [ 'version' => '8.0.0', - ), + ], // All the rest should be visible as contrib modules at version 8.x-1.0. // aaa_update_test needs to be part of the "CCC Update test" project, // which would throw off the report if we weren't properly sorting by // the project names. - 'aaa_update_test' => array( + 'aaa_update_test' => [ 'project' => 'ccc_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), + ], // This should be its own project, and listed first on the report. - 'bbb_update_test' => array( + 'bbb_update_test' => [ 'project' => 'bbb_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), + ], // This will contain both aaa_update_test and ccc_update_test, and // should come after the bbb_update_test project. - 'ccc_update_test' => array( + 'ccc_update_test' => [ 'project' => 'ccc_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); - $this->refreshUpdateStatus(array('drupal' => '0.0', '#all' => '1_0')); + $this->refreshUpdateStatus(['drupal' => '0.0', '#all' => '1_0']); $this->standardTests(); // We're expecting the report to say all projects are up to date. $this->assertText(t('Up to date')); @@ -184,37 +184,37 @@ function testUpdateContribOrder() { /** * Tests that subthemes are notified about security updates for base themes. */ - function testUpdateBaseThemeSecurityUpdate() { + public function testUpdateBaseThemeSecurityUpdate() { // @todo https://www.drupal.org/node/2338175 base themes have to be // installed. // Only install the subtheme, not the base theme. - \Drupal::service('theme_handler')->install(array('update_test_subtheme')); + \Drupal::service('theme_handler')->install(['update_test_subtheme']); // Define the initial state for core and the subtheme. - $system_info = array( + $system_info = [ // We want core to be version 8.0.0. - '#all' => array( + '#all' => [ 'version' => '8.0.0', - ), + ], // Show the update_test_basetheme - 'update_test_basetheme' => array( + 'update_test_basetheme' => [ 'project' => 'update_test_basetheme', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), + ], // Show the update_test_subtheme - 'update_test_subtheme' => array( + 'update_test_subtheme' => [ 'project' => 'update_test_subtheme', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); - $xml_mapping = array( + $xml_mapping = [ 'drupal' => '0.0', 'update_test_subtheme' => '1_0', 'update_test_basetheme' => '1_1-sec', - ); + ]; $this->refreshUpdateStatus($xml_mapping); $this->assertText(t('Security update required!')); $this->assertRaw(\Drupal::l(t('Update test base theme'), Url::fromUri('http://example.com/project/update_test_basetheme')), 'Link to the Update test base theme project appears.'); @@ -226,7 +226,7 @@ function testUpdateBaseThemeSecurityUpdate() { * @todo https://www.drupal.org/node/2338175 extensions can not be hidden and * base themes have to be installed. */ - function testUpdateShowDisabledThemes() { + public function testUpdateShowDisabledThemes() { $update_settings = $this->config('update.settings'); // Make sure all the update_test_* themes are disabled. $extension_config = $this->config('core.extension'); @@ -238,38 +238,38 @@ function testUpdateShowDisabledThemes() { $extension_config->save(); // Define the initial state for core and the test contrib themes. - $system_info = array( + $system_info = [ // We want core to be version 8.0.0. - '#all' => array( + '#all' => [ 'version' => '8.0.0', - ), + ], // The update_test_basetheme should be visible and up to date. - 'update_test_basetheme' => array( + 'update_test_basetheme' => [ 'project' => 'update_test_basetheme', 'version' => '8.x-1.1', 'hidden' => FALSE, - ), + ], // The update_test_subtheme should be visible and up to date. - 'update_test_subtheme' => array( + 'update_test_subtheme' => [ 'project' => 'update_test_subtheme', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; // When there are contributed modules in the site's file system, the // total number of attempts made in the test may exceed the default value // of update_max_fetch_attempts. Therefore this variable is set very high // to avoid test failures in those cases. $update_settings->set('fetch.max_attempts', 99999)->save(); $this->config('update_test.settings')->set('system_info', $system_info)->save(); - $xml_mapping = array( + $xml_mapping = [ 'drupal' => '0.0', 'update_test_subtheme' => '1_0', 'update_test_basetheme' => '1_1-sec', - ); + ]; $base_theme_project_link = \Drupal::l(t('Update test base theme'), Url::fromUri('http://example.com/project/update_test_basetheme')); $sub_theme_project_link = \Drupal::l(t('Update test subtheme'), Url::fromUri('http://example.com/project/update_test_subtheme')); - foreach (array(TRUE, FALSE) as $check_disabled) { + foreach ([TRUE, FALSE] as $check_disabled) { $update_settings->set('check.disabled_extensions', $check_disabled)->save(); $this->refreshUpdateStatus($xml_mapping); // In neither case should we see the "Themes" heading for installed @@ -291,25 +291,25 @@ function testUpdateShowDisabledThemes() { /** * Tests updates with a hidden base theme. */ - function testUpdateHiddenBaseTheme() { + public function testUpdateHiddenBaseTheme() { module_load_include('compare.inc', 'update'); // Install the subtheme. - \Drupal::service('theme_handler')->install(array('update_test_subtheme')); + \Drupal::service('theme_handler')->install(['update_test_subtheme']); // Add a project and initial state for base theme and subtheme. - $system_info = array( + $system_info = [ // Hide the update_test_basetheme. - 'update_test_basetheme' => array( + 'update_test_basetheme' => [ 'project' => 'update_test_basetheme', 'hidden' => TRUE, - ), + ], // Show the update_test_subtheme. - 'update_test_subtheme' => array( + 'update_test_subtheme' => [ 'project' => 'update_test_subtheme', 'hidden' => FALSE, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); $projects = \Drupal::service('update.manager')->getProjects(); $theme_data = \Drupal::service('theme_handler')->rebuildThemeData(); @@ -322,38 +322,38 @@ function testUpdateHiddenBaseTheme() { /** * Makes sure that if we fetch from a broken URL, sane things happen. */ - function testUpdateBrokenFetchURL() { - $system_info = array( - '#all' => array( + public function testUpdateBrokenFetchURL() { + $system_info = [ + '#all' => [ 'version' => '8.0.0', - ), - 'aaa_update_test' => array( + ], + 'aaa_update_test' => [ 'project' => 'aaa_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - 'bbb_update_test' => array( + ], + 'bbb_update_test' => [ 'project' => 'bbb_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - 'ccc_update_test' => array( + ], + 'ccc_update_test' => [ 'project' => 'ccc_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); // Ensure that the update information is correct before testing. $this->drupalGet('admin/reports/updates'); - $xml_mapping = array( + $xml_mapping = [ 'drupal' => '0.0', 'aaa_update_test' => '1_0', 'bbb_update_test' => 'does-not-exist', 'ccc_update_test' => '1_0', - ); + ]; $this->refreshUpdateStatus($xml_mapping); $this->assertText(t('Up to date')); @@ -386,33 +386,33 @@ function testUpdateBrokenFetchURL() { * hook_update_status_alter() to try to mark this as missing a security * update, then assert if we see the appropriate warnings on the right pages. */ - function testHookUpdateStatusAlter() { + public function testHookUpdateStatusAlter() { $update_test_config = $this->config('update_test.settings'); - $update_admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer software updates')); + $update_admin_user = $this->drupalCreateUser(['administer site configuration', 'administer software updates']); $this->drupalLogin($update_admin_user); - $system_info = array( - '#all' => array( + $system_info = [ + '#all' => [ 'version' => '8.0.0', - ), - 'aaa_update_test' => array( + ], + 'aaa_update_test' => [ 'project' => 'aaa_update_test', 'version' => '8.x-1.0', 'hidden' => FALSE, - ), - ); + ], + ]; $update_test_config->set('system_info', $system_info)->save(); - $update_status = array( - 'aaa_update_test' => array( + $update_status = [ + 'aaa_update_test' => [ 'status' => UPDATE_NOT_SECURE, - ), - ); + ], + ]; $update_test_config->set('update_status', $update_status)->save(); $this->refreshUpdateStatus( - array( + [ 'drupal' => '0.0', 'aaa_update_test' => '1_0', - ) + ] ); $this->drupalGet('admin/reports/updates'); $this->assertRaw('

          ' . t('Modules') . '

          '); @@ -421,7 +421,7 @@ function testHookUpdateStatusAlter() { // Visit the reports page again without the altering and make sure the // status is back to normal. - $update_test_config->set('update_status', array())->save(); + $update_test_config->set('update_status', [])->save(); $this->drupalGet('admin/reports/updates'); $this->assertRaw('

          ' . t('Modules') . '

          '); $this->assertNoText(t('Security update required!')); @@ -433,7 +433,7 @@ function testHookUpdateStatusAlter() { $this->assertText(t('Security update')); // Turn the altering back off and visit the Update manager UI. - $update_test_config->set('update_status', array())->save(); + $update_test_config->set('update_status', [])->save(); $this->drupalGet('admin/modules/update'); $this->assertNoText(t('Security update')); } diff --git a/core/modules/update/src/Tests/UpdateCoreTest.php b/core/modules/update/tests/src/Functional/UpdateCoreTest.php similarity index 84% rename from core/modules/update/src/Tests/UpdateCoreTest.php rename to core/modules/update/tests/src/Functional/UpdateCoreTest.php index baecde88..5cd4b102 100644 --- a/core/modules/update/src/Tests/UpdateCoreTest.php +++ b/core/modules/update/tests/src/Functional/UpdateCoreTest.php @@ -1,8 +1,9 @@ drupalCreateUser(array('administer site configuration', 'administer modules', 'administer themes')); + $admin_user = $this->drupalCreateUser(['administer site configuration', 'administer modules', 'administer themes']); $this->drupalLogin($admin_user); $this->drupalPlaceBlock('local_actions_block'); } @@ -33,23 +36,23 @@ protected function setUp() { * The version. */ protected function setSystemInfo($version) { - $setting = array( - '#all' => array( + $setting = [ + '#all' => [ 'version' => $version, - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $setting)->save(); } /** * Tests the Update Manager module when no updates are available. */ - function testNoUpdatesAvailable() { - foreach (array(0, 1) as $minor_version) { - foreach (array(0, 1) as $patch_version) { - foreach (array('-alpha1', '-beta1', '') as $extra_version) { + public function testNoUpdatesAvailable() { + foreach ([0, 1] as $minor_version) { + foreach ([0, 1] as $patch_version) { + foreach (['-alpha1', '-beta1', ''] as $extra_version) { $this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version); - $this->refreshUpdateStatus(array('drupal' => "$minor_version.$patch_version" . $extra_version)); + $this->refreshUpdateStatus(['drupal' => "$minor_version.$patch_version" . $extra_version]); $this->standardTests(); $this->assertText(t('Up to date')); $this->assertNoText(t('Update available')); @@ -63,19 +66,20 @@ function testNoUpdatesAvailable() { /** * Tests the Update Manager module when one normal update is available. */ - function testNormalUpdateAvailable() { + public function testNormalUpdateAvailable() { $this->setSystemInfo('8.0.0'); // Ensure that the update check requires a token. $this->drupalGet('admin/reports/updates/check'); $this->assertResponse(403, 'Accessing admin/reports/updates/check without a CSRF token results in access denied.'); - foreach (array(0, 1) as $minor_version) { - foreach (array('-alpha1', '-beta1', '') as $extra_version) { - $this->refreshUpdateStatus(array('drupal' => "$minor_version.1" . $extra_version)); + foreach ([0, 1] as $minor_version) { + foreach (['-alpha1', '-beta1', ''] as $extra_version) { + $this->refreshUpdateStatus(['drupal' => "$minor_version.1" . $extra_version]); $this->standardTests(); $this->drupalGet('admin/reports/updates'); $this->clickLink(t('Check manually')); + $this->checkForMetaRefresh(); $this->assertNoText(t('Security update required!')); $this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.'); $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.'); @@ -130,15 +134,16 @@ function testNormalUpdateAvailable() { /** * Tests the Update Manager module when a major update is available. */ - function testMajorUpdateAvailable() { - foreach (array(0, 1) as $minor_version) { - foreach (array(0, 1) as $patch_version) { - foreach (array('-alpha1', '-beta1', '') as $extra_version) { + public function testMajorUpdateAvailable() { + foreach ([0, 1] as $minor_version) { + foreach ([0, 1] as $patch_version) { + foreach (['-alpha1', '-beta1', ''] as $extra_version) { $this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version); - $this->refreshUpdateStatus(array('drupal' => '9')); + $this->refreshUpdateStatus(['drupal' => '9']); $this->standardTests(); $this->drupalGet('admin/reports/updates'); $this->clickLink(t('Check manually')); + $this->checkForMetaRefresh(); $this->assertNoText(t('Security update required!')); $this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.'); $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.'); @@ -156,10 +161,10 @@ function testMajorUpdateAvailable() { /** * Tests the Update Manager module when a security update is available. */ - function testSecurityUpdateAvailable() { - foreach (array(0, 1) as $minor_version) { + public function testSecurityUpdateAvailable() { + foreach ([0, 1] as $minor_version) { $this->setSystemInfo("8.$minor_version.0"); - $this->refreshUpdateStatus(array('drupal' => "$minor_version.2-sec")); + $this->refreshUpdateStatus(['drupal' => "$minor_version.2-sec"]); $this->standardTests(); $this->assertNoText(t('Up to date')); $this->assertNoText(t('Update available')); @@ -174,20 +179,20 @@ function testSecurityUpdateAvailable() { /** * Ensures proper results where there are date mismatches among modules. */ - function testDatestampMismatch() { - $system_info = array( - '#all' => array( + public function testDatestampMismatch() { + $system_info = [ + '#all' => [ // We need to think we're running a -dev snapshot to see dates. 'version' => '8.1.0-dev', 'datestamp' => time(), - ), - 'block' => array( + ], + 'block' => [ // This is 2001-09-09 01:46:40 GMT, so test for "2001-Sep-". 'datestamp' => '1000000000', - ), - ); + ], + ]; $this->config('update_test.settings')->set('system_info', $system_info)->save(); - $this->refreshUpdateStatus(array('drupal' => 'dev')); + $this->refreshUpdateStatus(['drupal' => 'dev']); $this->assertNoText(t('2001-Sep-')); $this->assertText(t('Up to date')); $this->assertNoText(t('Update available')); @@ -197,13 +202,13 @@ function testDatestampMismatch() { /** * Checks that running cron updates the list of available updates. */ - function testModulePageRunCron() { + public function testModulePageRunCron() { $this->setSystemInfo('8.0.0'); $this->config('update.settings') ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString()) ->save(); $this->config('update_test.settings') - ->set('xml_map', array('drupal' => '0.0')) + ->set('xml_map', ['drupal' => '0.0']) ->save(); $this->cronRun(); @@ -214,18 +219,19 @@ function testModulePageRunCron() { /** * Checks the messages at admin/modules when the site is up to date. */ - function testModulePageUpToDate() { + public function testModulePageUpToDate() { $this->setSystemInfo('8.0.0'); // Instead of using refreshUpdateStatus(), set these manually. $this->config('update.settings') ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString()) ->save(); $this->config('update_test.settings') - ->set('xml_map', array('drupal' => '0.0')) + ->set('xml_map', ['drupal' => '0.0']) ->save(); $this->drupalGet('admin/reports/updates'); $this->clickLink(t('Check manually')); + $this->checkForMetaRefresh(); $this->assertText(t('Checked available update data for one project.')); $this->drupalGet('admin/modules'); $this->assertNoText(t('There are updates available for your version of Drupal.')); @@ -235,18 +241,19 @@ function testModulePageUpToDate() { /** * Checks the messages at admin/modules when an update is missing. */ - function testModulePageRegularUpdate() { + public function testModulePageRegularUpdate() { $this->setSystemInfo('8.0.0'); // Instead of using refreshUpdateStatus(), set these manually. $this->config('update.settings') ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString()) ->save(); $this->config('update_test.settings') - ->set('xml_map', array('drupal' => '0.1')) + ->set('xml_map', ['drupal' => '0.1']) ->save(); $this->drupalGet('admin/reports/updates'); $this->clickLink(t('Check manually')); + $this->checkForMetaRefresh(); $this->assertText(t('Checked available update data for one project.')); $this->drupalGet('admin/modules'); $this->assertText(t('There are updates available for your version of Drupal.')); @@ -256,18 +263,19 @@ function testModulePageRegularUpdate() { /** * Checks the messages at admin/modules when a security update is missing. */ - function testModulePageSecurityUpdate() { + public function testModulePageSecurityUpdate() { $this->setSystemInfo('8.0.0'); // Instead of using refreshUpdateStatus(), set these manually. $this->config('update.settings') ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString()) ->save(); $this->config('update_test.settings') - ->set('xml_map', array('drupal' => '0.2-sec')) + ->set('xml_map', ['drupal' => '0.2-sec']) ->save(); $this->drupalGet('admin/reports/updates'); $this->clickLink(t('Check manually')); + $this->checkForMetaRefresh(); $this->assertText(t('Checked available update data for one project.')); $this->drupalGet('admin/modules'); $this->assertNoText(t('There are updates available for your version of Drupal.')); @@ -295,8 +303,8 @@ function testModulePageSecurityUpdate() { /** * Tests the Update Manager module when the update server returns 503 errors. */ - function testServiceUnavailable() { - $this->refreshUpdateStatus(array(), '503-error'); + public function testServiceUnavailable() { + $this->refreshUpdateStatus([], '503-error'); // Ensure that no "Warning: SimpleXMLElement..." parse errors are found. $this->assertNoText('SimpleXMLElement'); $this->assertUniqueText(t('Failed to get available update data for one project.')); @@ -305,13 +313,13 @@ function testServiceUnavailable() { /** * Tests that exactly one fetch task per project is created and not more. */ - function testFetchTasks() { - $projecta = array( + public function testFetchTasks() { + $projecta = [ 'name' => 'aaa_update_test', - ); - $projectb = array( + ]; + $projectb = [ 'name' => 'bbb_update_test', - ); + ]; $queue = \Drupal::queue('update_fetch_tasks'); $this->assertEqual($queue->numberOfItems(), 0, 'Queue is empty'); update_create_fetch_task($projecta); @@ -331,14 +339,14 @@ function testFetchTasks() { /** * Checks language module in core package at admin/reports/updates. */ - function testLanguageModuleUpdate() { + public function testLanguageModuleUpdate() { $this->setSystemInfo('8.0.0'); // Instead of using refreshUpdateStatus(), set these manually. $this->config('update.settings') ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString()) ->save(); $this->config('update_test.settings') - ->set('xml_map', array('drupal' => '0.1')) + ->set('xml_map', ['drupal' => '0.1']) ->save(); $this->drupalGet('admin/reports/updates'); @@ -349,7 +357,7 @@ function testLanguageModuleUpdate() { * Ensures that the local actions appear. */ public function testLocalActions() { - $admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer modules', 'administer software updates', 'administer themes')); + $admin_user = $this->drupalCreateUser(['administer site configuration', 'administer modules', 'administer software updates', 'administer themes']); $this->drupalLogin($admin_user); $this->drupalGet('admin/modules'); diff --git a/core/modules/update/src/Tests/UpdateDeleteFileIfStaleTest.php b/core/modules/update/tests/src/Functional/UpdateDeleteFileIfStaleTest.php similarity index 88% rename from core/modules/update/src/Tests/UpdateDeleteFileIfStaleTest.php rename to core/modules/update/tests/src/Functional/UpdateDeleteFileIfStaleTest.php index 63c2889a..601a6cc2 100644 --- a/core/modules/update/src/Tests/UpdateDeleteFileIfStaleTest.php +++ b/core/modules/update/tests/src/Functional/UpdateDeleteFileIfStaleTest.php @@ -1,6 +1,6 @@ randomMachineName()); $this->assertNotNull($file_name); diff --git a/core/modules/update/tests/src/Functional/UpdateTestBase.php b/core/modules/update/tests/src/Functional/UpdateTestBase.php new file mode 100644 index 00000000..a4d07d0b --- /dev/null +++ b/core/modules/update/tests/src/Functional/UpdateTestBase.php @@ -0,0 +1,84 @@ +container->get('update.root') . '/' . DrupalKernel::findSitePath($request); + $this->container->set('update.root', $update_root); + \Drupal::setContainer($this->container); + + // Create the directories within the root path within which the Update + // Manager will install projects. + foreach (drupal_get_updaters() as $updater_info) { + $updater = $updater_info['class']; + $install_directory = $update_root . '/' . $updater::getRootDirectoryRelativePath(); + if (!is_dir($install_directory)) { + mkdir($install_directory); + } + } + } + + /** + * Refreshes the update status based on the desired available update scenario. + * + * @param $xml_map + * Array that maps project names to availability scenarios to fetch. The key + * '#all' is used if a project-specific mapping is not defined. + * @param $url + * (optional) A string containing the URL to fetch update data from. + * Defaults to 'update-test'. + * + * @see \Drupal\update_test\Controller\UpdateTestController::updateTest() + */ + protected function refreshUpdateStatus($xml_map, $url = 'update-test') { + // Tell the Update Manager module to fetch from the URL provided by + // update_test module. + $this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, ['absolute' => TRUE])->toString())->save(); + // Save the map for UpdateTestController::updateTest() to use. + $this->config('update_test.settings')->set('xml_map', $xml_map)->save(); + // Manually check the update status. + $this->drupalGet('admin/reports/updates'); + $this->clickLink(t('Check manually')); + $this->checkForMetaRefresh(); + } + + /** + * Runs a series of assertions that are applicable to all update statuses. + */ + protected function standardTests() { + $this->assertRaw('

          ' . t('Drupal core') . '

          '); + $this->assertRaw(\Drupal::l(t('Drupal'), Url::fromUri('http://example.com/project/drupal')), 'Link to the Drupal project appears.'); + $this->assertNoText(t('No available releases found')); + } + +} diff --git a/core/modules/update/src/Tests/UpdateUploadTest.php b/core/modules/update/tests/src/Functional/UpdateUploadTest.php similarity index 80% rename from core/modules/update/src/Tests/UpdateUploadTest.php rename to core/modules/update/tests/src/Functional/UpdateUploadTest.php index 39b6944b..60966200 100644 --- a/core/modules/update/src/Tests/UpdateUploadTest.php +++ b/core/modules/update/tests/src/Functional/UpdateUploadTest.php @@ -1,10 +1,11 @@ drupalCreateUser(array('administer modules', 'administer software updates', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer modules', 'administer software updates', 'administer site configuration']); $this->drupalLogin($admin_user); } @@ -39,23 +44,23 @@ public function testUploadModule() { // emits a notice in strict mode. $imageTestFiles = $this->drupalGetTestFiles('image'); $invalidArchiveFile = reset($imageTestFiles); - $edit = array( + $edit = [ 'files[project_upload]' => $invalidArchiveFile->uri, - ); + ]; // This also checks that the correct archive extensions are allowed. $this->drupalPostForm('admin/modules/install', $edit, t('Install')); - $this->assertText(t('Only files with the following extensions are allowed: @archive_extensions.', array('@archive_extensions' => archiver_get_extensions())), 'Only valid archives can be uploaded.'); + $this->assertText(t('Only files with the following extensions are allowed: @archive_extensions.', ['@archive_extensions' => archiver_get_extensions()]), 'Only valid archives can be uploaded.'); $this->assertUrl('admin/modules/install'); // Check to ensure an existing module can't be reinstalled. Also checks that // the archive was extracted since we can't know if the module is already // installed until after extraction. - $validArchiveFile = __DIR__ . '/../../tests/aaa_update_test.tar.gz'; - $edit = array( + $validArchiveFile = __DIR__ . '/../../aaa_update_test.tar.gz'; + $edit = [ 'files[project_upload]' => $validArchiveFile, - ); + ]; $this->drupalPostForm('admin/modules/install', $edit, t('Install')); - $this->assertText(t('@module_name is already installed.', array('@module_name' => 'AAA Update test')), 'Existing module was extracted and not reinstalled.'); + $this->assertText(t('@module_name is already installed.', ['@module_name' => 'AAA Update test']), 'Existing module was extracted and not reinstalled.'); $this->assertUrl('admin/modules/install'); // Ensure that a new module can be extracted and installed. @@ -63,17 +68,17 @@ public function testUploadModule() { $moduleUpdater = $updaters['module']['class']; $installedInfoFilePath = $this->container->get('update.root') . '/' . $moduleUpdater::getRootDirectoryRelativePath() . '/update_test_new_module/update_test_new_module.info.yml'; $this->assertFalse(file_exists($installedInfoFilePath), 'The new module does not exist in the filesystem before it is installed with the Update Manager.'); - $validArchiveFile = __DIR__ . '/../../tests/update_test_new_module/8.x-1.0/update_test_new_module.tar.gz'; - $edit = array( + $validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz'; + $edit = [ 'files[project_upload]' => $validArchiveFile, - ); + ]; $this->drupalPostForm('admin/modules/install', $edit, t('Install')); // Check that submitting the form takes the user to authorize.php. $this->assertUrl('core/authorize.php'); $this->assertTitle('Update manager | Drupal'); // Check for a success message on the page, and check that the installed // module now exists in the expected place in the filesystem. - $this->assertRaw(t('Installed %project_name successfully', array('%project_name' => 'update_test_new_module'))); + $this->assertRaw(t('Installed %project_name successfully', ['%project_name' => 'update_test_new_module'])); $this->assertTrue(file_exists($installedInfoFilePath), 'The new module exists in the filesystem after it is installed with the Update Manager.'); // Ensure the links are relative to the site root and not // core/authorize.php. @@ -98,27 +103,27 @@ public function testUploadModule() { $this->assertEqual($info['version'], '8.x-1.0'); // Enable the module. - $this->drupalPostForm('admin/modules', array('modules[Testing][update_test_new_module][enable]' => TRUE), t('Install')); + $this->drupalPostForm('admin/modules', ['modules[update_test_new_module][enable]' => TRUE], t('Install')); // Define the update XML such that the new module downloaded above needs an // update from 8.x-1.0 to 8.x-1.1. $update_test_config = $this->config('update_test.settings'); - $system_info = array( - 'update_test_new_module' => array( + $system_info = [ + 'update_test_new_module' => [ 'project' => 'update_test_new_module', - ), - ); + ], + ]; $update_test_config->set('system_info', $system_info)->save(); - $xml_mapping = array( + $xml_mapping = [ 'update_test_new_module' => '1_1', - ); + ]; $this->refreshUpdateStatus($xml_mapping); // Run the updates for the new module. - $this->drupalPostForm('admin/reports/updates/update', array('projects[update_test_new_module]' => TRUE), t('Download these updates')); - $this->drupalPostForm(NULL, array('maintenance_mode' => FALSE), t('Continue')); + $this->drupalPostForm('admin/reports/updates/update', ['projects[update_test_new_module]' => TRUE], t('Download these updates')); + $this->drupalPostForm(NULL, ['maintenance_mode' => FALSE], t('Continue')); $this->assertText(t('Update was completed successfully.')); - $this->assertRaw(t('Installed %project_name successfully', array('%project_name' => 'update_test_new_module'))); + $this->assertRaw(t('Installed %project_name successfully', ['%project_name' => 'update_test_new_module'])); // Parse the info file again to check that the module has been updated to // 8.x-1.1. @@ -129,7 +134,7 @@ public function testUploadModule() { /** * Ensures that archiver extensions are properly merged in the UI. */ - function testFileNameExtensionMerging() { + public function testFileNameExtensionMerging() { $this->drupalGet('admin/modules/install'); // Make sure the bogus extension supported by update_test.module is there. $this->assertPattern('/file extensions are supported:.*update-test-extension/', "Found 'update-test-extension' extension."); @@ -140,15 +145,15 @@ function testFileNameExtensionMerging() { /** * Checks the messages on update manager pages when missing a security update. */ - function testUpdateManagerCoreSecurityUpdateMessages() { - $setting = array( - '#all' => array( + public function testUpdateManagerCoreSecurityUpdateMessages() { + $setting = [ + '#all' => [ 'version' => '8.0.0', - ), - ); + ], + ]; $this->config('update_test.settings') ->set('system_info', $setting) - ->set('xml_map', array('drupal' => '0.2-sec')) + ->set('xml_map', ['drupal' => '0.2-sec']) ->save(); $this->config('update.settings') ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString()) diff --git a/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php b/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php index a0222066..aa3563c6 100644 --- a/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php +++ b/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\update\Kernel\Migrate\d6; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** @@ -17,7 +17,7 @@ class MigrateUpdateConfigsTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('update'); + public static $modules = ['update']; /** * {@inheritdoc} @@ -35,7 +35,7 @@ public function testUpdateSettings() { $this->assertIdentical(2, $config->get('fetch.max_attempts')); $this->assertIdentical('http://updates.drupal.org/release-history', $config->get('fetch.url')); $this->assertIdentical('all', $config->get('notification.threshold')); - $this->assertIdentical(array(), $config->get('notification.emails')); + $this->assertIdentical([], $config->get('notification.emails')); $this->assertIdentical(7, $config->get('check.interval_days')); $this->assertConfigSchema(\Drupal::service('config.typed'), 'update.settings', $config->get()); } diff --git a/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php b/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php index f57997fd..113f006a 100644 --- a/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php +++ b/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php @@ -12,7 +12,7 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase { protected function setUp() { - $this->directoryList = array('update' => 'core/modules/update'); + $this->directoryList = ['update' => 'core/modules/update']; parent::setUp(); } @@ -22,20 +22,20 @@ protected function setUp() { * @dataProvider getUpdateReportRoutes */ public function testUpdateReportLocalTasks($route) { - $this->assertLocalTasks($route, array( - 0 => array('update.status', 'update.settings', 'update.report_update'), - )); + $this->assertLocalTasks($route, [ + 0 => ['update.status', 'update.settings', 'update.report_update'], + ]); } /** * Provides a list of report routes to test. */ public function getUpdateReportRoutes() { - return array( - array('update.status'), - array('update.settings'), - array('update.report_update'), - ); + return [ + ['update.status'], + ['update.settings'], + ['update.report_update'], + ]; } /** @@ -44,9 +44,9 @@ public function getUpdateReportRoutes() { * @dataProvider getUpdateModuleRoutes */ public function testUpdateModuleLocalTasks($route) { - $this->assertLocalTasks($route, array( - 0 => array('update.module_update'), - )); + $this->assertLocalTasks($route, [ + 0 => ['update.module_update'], + ]); ; } @@ -54,9 +54,9 @@ public function testUpdateModuleLocalTasks($route) { * Provides a list of module routes to test. */ public function getUpdateModuleRoutes() { - return array( - array('update.module_update'), - ); + return [ + ['update.module_update'], + ]; } /** @@ -65,9 +65,9 @@ public function getUpdateModuleRoutes() { * @dataProvider getUpdateThemeRoutes */ public function testUpdateThemeLocalTasks($route) { - $this->assertLocalTasks($route, array( - 0 => array('update.theme_update'), - )); + $this->assertLocalTasks($route, [ + 0 => ['update.theme_update'], + ]); ; } @@ -75,9 +75,9 @@ public function testUpdateThemeLocalTasks($route) { * Provides a list of theme routes to test. */ public function getUpdateThemeRoutes() { - return array( - array('update.theme_update'), - ); + return [ + ['update.theme_update'], + ]; } } diff --git a/core/modules/update/tests/src/Unit/UpdateFetcherTest.php b/core/modules/update/tests/src/Unit/UpdateFetcherTest.php index c203f3b5..c3e447d1 100644 --- a/core/modules/update/tests/src/Unit/UpdateFetcherTest.php +++ b/core/modules/update/tests/src/Unit/UpdateFetcherTest.php @@ -27,7 +27,7 @@ class UpdateFetcherTest extends UnitTestCase { * {@inheritdoc} */ protected function setUp() { - $config_factory = $this->getConfigFactoryStub(array('update.settings' => array('fetch_url' => 'http://www.example.com'))); + $config_factory = $this->getConfigFactoryStub(['update.settings' => ['fetch_url' => 'http://www.example.com']]); $http_client_mock = $this->getMock('\GuzzleHttp\ClientInterface'); $this->updateFetcher = new UpdateFetcher($config_factory, $http_client_mock); } @@ -62,25 +62,25 @@ public function testUpdateBuildFetchUrl(array $project, $site_key, $expected) { * - 'expected' - The expected url from UpdateFetcher::buildFetchUrl(). */ public function providerTestUpdateBuildFetchUrl() { - $data = array(); + $data = []; // First test that we didn't break the trivial case. $project['name'] = 'update_test'; $project['project_type'] = ''; $project['info']['version'] = ''; $project['info']['project status url'] = 'http://www.example.com'; - $project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2'); + $project['includes'] = ['module1' => 'Module 1', 'module2' => 'Module 2']; $site_key = ''; $expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY; - $data[] = array($project, $site_key, $expected); + $data[] = [$project, $site_key, $expected]; // For disabled projects it shouldn't add the site key either. $site_key = 'site_key'; $project['project_type'] = 'disabled'; $expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY; - $data[] = array($project, $site_key, $expected); + $data[] = [$project, $site_key, $expected]; // For enabled projects, test adding the site key. $project['project_type'] = ''; @@ -88,7 +88,7 @@ public function providerTestUpdateBuildFetchUrl() { $expected .= '?site_key=site_key'; $expected .= '&list=' . rawurlencode('module1,module2'); - $data[] = array($project, $site_key, $expected); + $data[] = [$project, $site_key, $expected]; // Test when the URL contains a question mark. $project['info']['project status url'] = 'http://www.example.com/?project='; @@ -96,7 +96,7 @@ public function providerTestUpdateBuildFetchUrl() { $expected .= '&site_key=site_key'; $expected .= '&list=' . rawurlencode('module1,module2'); - $data[] = array($project, $site_key, $expected); + $data[] = [$project, $site_key, $expected]; return $data; } diff --git a/core/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info.yml b/core/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info.yml index 536a4df4..ec5a048d 100644 --- a/core/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info.yml +++ b/core/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info.yml @@ -4,8 +4,8 @@ description: 'Test theme which acts as a base theme for other test subthemes.' # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info.yml b/core/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info.yml index 4c0dca68..a1a32c69 100644 --- a/core/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info.yml +++ b/core/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info.yml @@ -5,8 +5,8 @@ description: 'Test theme which uses update_test_basetheme as the base theme.' # core: 8.x base theme: update_test_basetheme -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/update.api.php b/core/modules/update/update.api.php index 37ef66a4..48216eb0 100644 --- a/core/modules/update/update.api.php +++ b/core/modules/update/update.api.php @@ -40,11 +40,11 @@ function hook_update_projects_alter(&$projects) { // Add a disabled module to the list. // The key for the array should be the machine-readable project "short name". - $projects['disabled_project_name'] = array( + $projects['disabled_project_name'] = [ // Machine-readable project short name (same as the array key above). 'name' => 'disabled_project_name', // Array of values from the main .info.yml file for this project. - 'info' => array( + 'info' => [ 'name' => 'Some disabled module', 'description' => 'A module not enabled on the site that you want to see in the available updates report.', 'version' => '8.x-1.0', @@ -52,7 +52,7 @@ function hook_update_projects_alter(&$projects) { // The maximum file change time (the "ctime" returned by the filectime() // PHP method) for all of the .info.yml files included in this project. '_info_file_ctime' => 1243888165, - ), + ], // The date stamp when the project was released, if known. If the disabled // project was an officially packaged release from drupal.org, this will // be included in the .info.yml file as the 'datestamp' field. This only @@ -62,15 +62,15 @@ function hook_update_projects_alter(&$projects) { // Any modules (or themes) included in this project. Keyed by machine- // readable "short name", value is the human-readable project name printed // in the UI. - 'includes' => array( + 'includes' => [ 'disabled_project' => 'Disabled module', 'disabled_project_helper' => 'Disabled module helper module', 'disabled_project_foo' => 'Disabled module foo add-on module', - ), + ], // Does this project contain a 'module', 'theme', 'disabled-module', or // 'disabled-theme'? 'project_type' => 'disabled-module', - ); + ]; } /** @@ -92,11 +92,11 @@ function hook_update_status_alter(&$projects) { $projects[$project]['status'] = UPDATE_NOT_CHECKED; $projects[$project]['reason'] = t('Ignored from settings'); if (!empty($settings[$project]['notes'])) { - $projects[$project]['extra'][] = array( - 'class' => array('admin-note'), + $projects[$project]['extra'][] = [ + 'class' => ['admin-note'], 'label' => t('Administrator note'), 'data' => $settings[$project]['notes'], - ); + ]; } } } @@ -120,9 +120,9 @@ function hook_update_status_alter(&$projects) { * @ingroup update_manager_file */ function hook_verify_update_archive($project, $archive_file, $directory) { - $errors = array(); + $errors = []; if (!file_exists($directory)) { - $errors[] = t('The %directory does not exist.', array('%directory' => $directory)); + $errors[] = t('The %directory does not exist.', ['%directory' => $directory]); } // Add other checks on the archive integrity here. return $errors; diff --git a/core/modules/update/update.authorize.inc b/core/modules/update/update.authorize.inc index 58f14647..1c2cc60f 100644 --- a/core/modules/update/update.authorize.inc +++ b/core/modules/update/update.authorize.inc @@ -36,25 +36,25 @@ use Drupal\Core\Url; * should use that response for the current page request. */ function update_authorize_run_update($filetransfer, $projects) { - $operations = array(); + $operations = []; foreach ($projects as $project_info) { - $operations[] = array( + $operations[] = [ 'update_authorize_batch_copy_project', - array( + [ $project_info['project'], $project_info['updater_name'], $project_info['local_url'], $filetransfer, - ), - ); + ], + ]; } - $batch = array( + $batch = [ 'init_message' => t('Preparing to update your site'), 'operations' => $operations, 'finished' => 'update_authorize_update_batch_finished', 'file' => drupal_get_path('module', 'update') . '/update.authorize.inc', - ); + ]; batch_set($batch); // Since authorize.php has its own method for setting the page title, set it @@ -91,30 +91,30 @@ function update_authorize_run_update($filetransfer, $projects) { * should use that response for the current page request. */ function update_authorize_run_install($filetransfer, $project, $updater_name, $local_url) { - $operations[] = array( + $operations[] = [ 'update_authorize_batch_copy_project', - array( + [ $project, $updater_name, $local_url, $filetransfer, - ), - ); + ], + ]; // @todo Instantiate our Updater to set the human-readable title? - $batch = array( + $batch = [ 'init_message' => t('Preparing to install'), 'operations' => $operations, // @todo Use a different finished callback for different messages? 'finished' => 'update_authorize_install_batch_finished', 'file' => drupal_get_path('module', 'update') . '/update.authorize.inc', - ); + ]; batch_set($batch); // Since authorize.php has its own method for setting the page title, set it // manually here rather than passing it in to batch_set() as would normally // be done. - $_SESSION['authorize_page_title'] = t('Installing %project', array('%project' => $project)); + $_SESSION['authorize_page_title'] = t('Installing %project', ['%project' => $project]); // Invoke the batch via authorize.php. return system_authorized_batch_process(); @@ -142,14 +142,14 @@ function update_authorize_batch_copy_project($project, $updater_name, $local_url // Initialize some variables in the Batch API $context array. if (!isset($context['results']['log'])) { - $context['results']['log'] = array(); + $context['results']['log'] = []; } if (!isset($context['results']['log'][$project])) { - $context['results']['log'][$project] = array(); + $context['results']['log'][$project] = []; } if (!isset($context['results']['tasks'])) { - $context['results']['tasks'] = array(); + $context['results']['tasks'] = []; } // The batch API uses a session, and since all the arguments are serialized @@ -184,7 +184,7 @@ function update_authorize_batch_copy_project($project, $updater_name, $local_url return; } - _update_batch_create_message($context['results']['log'][$project], t('Installed %project_name successfully', array('%project_name' => $project))); + _update_batch_create_message($context['results']['log'][$project], t('Installed %project_name successfully', ['%project_name' => $project])); if (!empty($tasks)) { $context['results']['tasks'] += $tasks; } @@ -221,29 +221,29 @@ function update_authorize_update_batch_finished($success, $results) { // Take the site out of maintenance mode if it was previously that way. if ($offline && isset($_SESSION['maintenance_mode']) && $_SESSION['maintenance_mode'] == FALSE) { \Drupal::state()->set('system.maintenance_mode', FALSE); - $page_message = array( + $page_message = [ 'message' => t('Update was completed successfully. Your site has been taken out of maintenance mode.'), 'type' => 'status', - ); + ]; } else { - $page_message = array( + $page_message = [ 'message' => t('Update was completed successfully.'), 'type' => 'status', - ); + ]; } } elseif (!$offline) { - $page_message = array( + $page_message = [ 'message' => t('Update failed! See the log below for more information.'), 'type' => 'error', - ); + ]; } else { - $page_message = array( + $page_message = [ 'message' => t('Update failed! See the log below for more information. Your site is still in maintenance mode.'), 'type' => 'error', - ); + ]; } // Since we're doing an update of existing code, always add a task for // running update.php. @@ -300,29 +300,29 @@ function update_authorize_install_batch_finished($success, $results) { // Take the site out of maintenance mode if it was previously that way. if ($offline && isset($_SESSION['maintenance_mode']) && $_SESSION['maintenance_mode'] == FALSE) { \Drupal::state()->set('system.maintenance_mode', FALSE); - $page_message = array( + $page_message = [ 'message' => t('Installation was completed successfully. Your site has been taken out of maintenance mode.'), 'type' => 'status', - ); + ]; } else { - $page_message = array( + $page_message = [ 'message' => t('Installation was completed successfully.'), 'type' => 'status', - ); + ]; } } elseif (!$success && !$offline) { - $page_message = array( + $page_message = [ 'message' => t('Installation failed! See the log below for more information.'), 'type' => 'error', - ); + ]; } else { - $page_message = array( + $page_message = [ 'message' => t('Installation failed! See the log below for more information. Your site is still in maintenance mode.'), 'type' => 'error', - ); + ]; } // Unset the variable since it is no longer needed. @@ -348,7 +348,7 @@ function update_authorize_install_batch_finished($success, $results) { * if there were errors. Defaults to TRUE. */ function _update_batch_create_message(&$project_results, $message, $success = TRUE) { - $project_results[] = array('message' => $message, 'success' => $success); + $project_results[] = ['message' => $message, 'success' => $success]; } /** diff --git a/core/modules/update/update.compare.inc b/core/modules/update/update.compare.inc index a077c38d..2ba5fdce 100644 --- a/core/modules/update/update.compare.inc +++ b/core/modules/update/update.compare.inc @@ -32,7 +32,7 @@ function update_process_project_info(&$projects) { // Figure out what the currently installed major version is. We need // to handle both contribution (e.g. "5.x-1.3", major = 1) and core // (e.g. "5.1", major = 5) version strings. - $matches = array(); + $matches = []; if (preg_match('/^(\d+\.x-)?(\d+)\..*$/', $info['version'], $matches)) { $info['major'] = $matches[2]; } @@ -171,7 +171,7 @@ function update_calculate_project_data($available) { * Data about available project releases of a specific project. */ function update_calculate_project_update_status(&$project_data, $available) { - foreach (array('title', 'link') as $attribute) { + foreach (['title', 'link'] as $attribute) { if (!isset($project_data[$attribute]) && isset($available[$attribute])) { $project_data[$attribute] = $available[$attribute]; } @@ -184,33 +184,33 @@ function update_calculate_project_update_status(&$project_data, $available) { case 'insecure': $project_data['status'] = UPDATE_NOT_SECURE; if (empty($project_data['extra'])) { - $project_data['extra'] = array(); + $project_data['extra'] = []; } - $project_data['extra'][] = array( + $project_data['extra'][] = [ 'label' => t('Project not secure'), 'data' => t('This project has been labeled insecure by the Drupal security team, and is no longer available for download. Immediately disabling everything included by this project is strongly recommended!'), - ); + ]; break; case 'unpublished': case 'revoked': $project_data['status'] = UPDATE_REVOKED; if (empty($project_data['extra'])) { - $project_data['extra'] = array(); + $project_data['extra'] = []; } - $project_data['extra'][] = array( + $project_data['extra'][] = [ 'label' => t('Project revoked'), 'data' => t('This project has been revoked, and is no longer available for download. Disabling everything included by this project is strongly recommended!'), - ); + ]; break; case 'unsupported': $project_data['status'] = UPDATE_NOT_SUPPORTED; if (empty($project_data['extra'])) { - $project_data['extra'] = array(); + $project_data['extra'] = []; } - $project_data['extra'][] = array( + $project_data['extra'][] = [ 'label' => t('Project not supported'), 'data' => t('This project is no longer supported, and is no longer available for download. Disabling everything included by this project is strongly recommended!'), - ); + ]; break; case 'not-fetched': $project_data['status'] = UPDATE_NOT_FETCHED; @@ -233,7 +233,7 @@ function update_calculate_project_update_status(&$project_data, $available) { // Figure out the target major version. $existing_major = $project_data['existing_major']; - $supported_majors = array(); + $supported_majors = []; if (isset($available['supported_majors'])) { $supported_majors = explode(',', $available['supported_majors']); } @@ -303,25 +303,25 @@ function update_calculate_project_update_status(&$project_data, $available) { elseif ($release['status'] == 'unpublished') { $project_data['status'] = UPDATE_REVOKED; if (empty($project_data['extra'])) { - $project_data['extra'] = array(); + $project_data['extra'] = []; } - $project_data['extra'][] = array( - 'class' => array('release-revoked'), + $project_data['extra'][] = [ + 'class' => ['release-revoked'], 'label' => t('Release revoked'), 'data' => t('Your currently installed release has been revoked, and is no longer available for download. Disabling everything included in this release or upgrading is strongly recommended!'), - ); + ]; } elseif (isset($release['terms']['Release type']) && in_array('Unsupported', $release['terms']['Release type'])) { $project_data['status'] = UPDATE_NOT_SUPPORTED; if (empty($project_data['extra'])) { - $project_data['extra'] = array(); + $project_data['extra'] = []; } - $project_data['extra'][] = array( - 'class' => array('release-not-supported'), + $project_data['extra'][] = [ + 'class' => ['release-not-supported'], 'label' => t('Release not supported'), 'data' => t('Your currently installed release is now unsupported, and is no longer available for download. Disabling everything included in this release or upgrading is strongly recommended!'), - ); + ]; } } @@ -341,7 +341,7 @@ function update_calculate_project_update_status(&$project_data, $available) { if (isset($release['version_major']) && $release['version_major'] > $target_major) { if (in_array($release['version_major'], $supported_majors)) { if (!isset($project_data['also'])) { - $project_data['also'] = array(); + $project_data['also'] = []; } if (!isset($project_data['also'][$release['version_major']])) { $project_data['also'][$release['version_major']] = $version; diff --git a/core/modules/update/update.fetch.inc b/core/modules/update/update.fetch.inc index a710dd9f..9964910b 100644 --- a/core/modules/update/update.fetch.inc +++ b/core/modules/update/update.fetch.inc @@ -18,9 +18,9 @@ function _update_cron_notify() { $update_config = \Drupal::config('update.settings'); module_load_install('update'); $status = update_requirements('runtime'); - $params = array(); + $params = []; $notify_all = ($update_config->get('notification.threshold') == 'all'); - foreach (array('core', 'contrib') as $report_type) { + foreach (['core', 'contrib'] as $report_type) { $type = 'update_' . $report_type; if (isset($status[$type]['severity']) && ($status[$type]['severity'] == REQUIREMENT_ERROR || ($notify_all && $status[$type]['reason'] == UPDATE_NOT_CURRENT))) { diff --git a/core/modules/update/update.info.yml b/core/modules/update/update.info.yml index 464f1164..b705253d 100644 --- a/core/modules/update/update.info.yml +++ b/core/modules/update/update.info.yml @@ -8,8 +8,8 @@ configure: update.settings dependencies: - file -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/update/update.install b/core/modules/update/update.install index e8101295..c616412a 100644 --- a/core/modules/update/update.install +++ b/core/modules/update/update.install @@ -28,7 +28,7 @@ use Drupal\Core\Url; * @see _update_cron_notify() */ function update_requirements($phase) { - $requirements = array(); + $requirements = []; if ($phase == 'runtime') { if ($available = update_get_available(FALSE)) { module_load_include('inc', 'update', 'update.compare'); @@ -97,7 +97,7 @@ function update_uninstall() { * @see update_calculate_project_data() */ function _update_requirement_check($project, $type) { - $requirement = array(); + $requirement = []; if ($type == 'core') { $requirement['title'] = t('Drupal core update status'); } @@ -143,17 +143,12 @@ function _update_requirement_check($project, $type) { $requirement_label = t('Up to date'); } if ($status != UPDATE_CURRENT && $type == 'core' && isset($project['recommended'])) { - $requirement_label .= ' ' . t('(version @version available)', array('@version' => $project['recommended'])); + $requirement_label .= ' ' . t('(version @version available)', ['@version' => $project['recommended']]); } $requirement['value'] = \Drupal::l($requirement_label, new Url(_update_manager_access() ? 'update.report_update' : 'update.status')); return $requirement; } -/** - * @addtogroup updates-8.1.x - * @{ - */ - /** * Rebuild the router to ensure admin/reports/updates/check has CSRF protection. */ @@ -161,7 +156,3 @@ function update_update_8001() { // Empty update forces a call to drupal_flush_all_caches() which rebuilds the // router. } - -/** - * @} End of "addtogroup updates-8.1.x". - */ diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc index f9c7c5f3..399694f2 100644 --- a/core/modules/update/update.manager.inc +++ b/core/modules/update/update.manager.inc @@ -48,12 +48,12 @@ use Symfony\Component\HttpFoundation\RedirectResponse; */ function update_manager_download_batch_finished($success, $results) { if (!empty($results['errors'])) { - $item_list = array( + $item_list = [ '#theme' => 'item_list', '#title' => t('Downloading updates failed:'), '#items' => $results['errors'], - ); - drupal_set_message(drupal_render($item_list), 'error'); + ]; + drupal_set_message(\Drupal::service('renderer')->render($item_list), 'error'); } elseif ($success) { drupal_set_message(t('Updates downloaded successfully.')); @@ -91,45 +91,45 @@ function _update_manager_check_backends(&$form, $operation) { } // Otherwise, show the available backends. - $form['available_backends'] = array( + $form['available_backends'] = [ '#prefix' => '

          ', '#suffix' => '

          ', - ); + ]; $available_backends = drupal_get_filetransfer_info(); if (empty($available_backends)) { if ($operation == 'update') { - $form['available_backends']['#markup'] = t('Your server does not support updating modules and themes from this interface. Instead, update modules and themes by uploading the new versions directly to the server, as described in the handbook.', array(':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib')); + $form['available_backends']['#markup'] = t('Your server does not support updating modules and themes from this interface. Instead, update modules and themes by uploading the new versions directly to the server, as documented in Extending Drupal 8.', [':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview']); } else { - $form['available_backends']['#markup'] = t('Your server does not support installing modules and themes from this interface. Instead, install modules and themes by uploading them directly to the server, as described in the handbook.', array(':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib')); + $form['available_backends']['#markup'] = t('Your server does not support installing modules and themes from this interface. Instead, install modules and themes by uploading them directly to the server, as documented in Extending Drupal 8.', [':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview']); } return FALSE; } - $backend_names = array(); + $backend_names = []; foreach ($available_backends as $backend) { $backend_names[] = $backend['title']; } if ($operation == 'update') { $form['available_backends']['#markup'] = \Drupal::translation()->formatPlural( count($available_backends), - 'Updating modules and themes requires @backends access to your server. See the handbook for other update methods.', - 'Updating modules and themes requires access to your server via one of the following methods: @backends. See the handbook for other update methods.', - array( + 'Updating modules and themes requires @backends access to your server. See Extending Drupal 8 for other update methods.', + 'Updating modules and themes requires access to your server via one of the following methods: @backends. See Extending Drupal 8 for other update methods.', + [ '@backends' => implode(', ', $backend_names), - ':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib', - )); + ':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview', + ]); } else { $form['available_backends']['#markup'] = \Drupal::translation()->formatPlural( count($available_backends), - 'Installing modules and themes requires @backends access to your server. See the handbook for other installation methods.', - 'Installing modules and themes requires access to your server via one of the following methods: @backends. See the handbook for other installation methods.', - array( + 'Installing modules and themes requires @backends access to your server. See Extending Drupal 8 for other installation methods.', + 'Installing modules and themes requires access to your server via one of the following methods: @backends. See Extending Drupal 8 for other installation methods.', + [ '@backends' => implode(', ', $backend_names), - ':handbook_url' => 'https://www.drupal.org/getting-started/install-contrib', - )); + ':doc_url' => 'https://www.drupal.org/docs/8/extending-drupal-8/overview', + ]); } return TRUE; } @@ -150,7 +150,7 @@ function _update_manager_check_backends(&$form, $operation) { function update_manager_archive_extract($file, $directory) { $archiver = archiver_get_archiver($file); if (!$archiver) { - throw new Exception(t('Cannot extract %file, not a valid archive.', array ('%file' => $file))); + throw new Exception(t('Cannot extract %file, not a valid archive.', ['%file' => $file])); } // Remove the directory if it exists, otherwise it might contain a mixture of @@ -189,7 +189,7 @@ function update_manager_archive_extract($file, $directory) { * are no errors, it will be an empty array. */ function update_manager_archive_verify($project, $archive_file, $directory) { - return \Drupal::moduleHandler()->invokeAll('verify_update_archive', array($project, $archive_file, $directory)); + return \Drupal::moduleHandler()->invokeAll('verify_update_archive', [$project, $archive_file, $directory]); } /** @@ -205,7 +205,7 @@ function update_manager_archive_verify($project, $archive_file, $directory) { */ function update_manager_file_get($url) { $parsed_url = parse_url($url); - $remote_schemes = array('http', 'https', 'ftp', 'ftps', 'smb', 'nfs'); + $remote_schemes = ['http', 'https', 'ftp', 'ftps', 'smb', 'nfs']; if (!isset($parsed_url['scheme']) || !in_array($parsed_url['scheme'], $remote_schemes)) { // This is a local file, just return the path. return drupal_realpath($url); @@ -245,14 +245,14 @@ function update_manager_batch_project_get($project, $url, &$context) { // This is here to show the user that we are in the process of downloading. if (!isset($context['sandbox']['started'])) { $context['sandbox']['started'] = TRUE; - $context['message'] = t('Downloading %project', array('%project' => $project)); + $context['message'] = t('Downloading %project', ['%project' => $project]); $context['finished'] = 0; return; } // Actually try to download the file. if (!($local_cache = update_manager_file_get($url))) { - $context['results']['errors'][$project] = t('Failed to download %project from %url', array('%project' => $project, '%url' => $url)); + $context['results']['errors'][$project] = t('Failed to download %project from %url', ['%project' => $project, '%url' => $url]); return; } diff --git a/core/modules/update/update.module b/core/modules/update/update.module index f45b5893..0545aef8 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -20,46 +20,91 @@ use Drupal\Core\Site\Settings; /** * Project is missing security update(s). + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateManagerInterface::NOT_SECURE instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_NOT_SECURE = 1; /** * Current release has been unpublished and is no longer available. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateManagerInterface::REVOKED instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_REVOKED = 2; /** * Current release is no longer supported by the project maintainer. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateManagerInterface::NOT_SUPPORTED instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_NOT_SUPPORTED = 3; /** * Project has a new release available, but it is not a security release. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateManagerInterface::NOT_CURRENT instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_NOT_CURRENT = 4; /** * Project is up to date. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateManagerInterface::CURRENT instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_CURRENT = 5; /** * Project's status cannot be checked. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateFetcherInterface::NOT_CHECKED instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_NOT_CHECKED = -1; /** * No available update data was found for project. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateFetcherInterface::UNKNOWN instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_UNKNOWN = -2; /** * There was a failure fetching available update data for this project. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateFetcherInterface::NOT_FETCHED instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_NOT_FETCHED = -3; /** * We need to (re)fetch available update data for this project. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\update\UpdateFetcherInterface::FETCH_PENDING instead. + * + * @see https://www.drupal.org/node/2831620 */ const UPDATE_FETCH_PENDING = -4; @@ -71,7 +116,7 @@ function update_help($route_name, RouteMatchInterface $route_match) { case 'help.page.update': $output = ''; $output .= '

          ' . t('About') . '

          '; - $output .= '

          ' . t('The Update Manager module periodically checks for new versions of your site\'s software (including contributed modules and themes), and alerts administrators to available updates. The Update Manager system is also used by some other modules to manage updates and downloads; for example, the Interface Translation module uses the Update Manager to download translations from the localization server. Note that whenever the Update Manager system is used, anonymous usage statistics are sent to Drupal.org. If desired, you may disable the Update Manager module from the Extend page; if you do so, functionality that depends on the Update Manager system will not work. For more information, see the online documentation for the Update Manager module.', array(':update' => 'https://www.drupal.org/documentation/modules/update', ':modules' => \Drupal::url('system.modules_list'))) . '

          '; + $output .= '

          ' . t('The Update Manager module periodically checks for new versions of your site\'s software (including contributed modules and themes), and alerts administrators to available updates. The Update Manager system is also used by some other modules to manage updates and downloads; for example, the Interface Translation module uses the Update Manager to download translations from the localization server. Note that whenever the Update Manager system is used, anonymous usage statistics are sent to Drupal.org. If desired, you may disable the Update Manager module from the Extend page; if you do so, functionality that depends on the Update Manager system will not work. For more information, see the online documentation for the Update Manager module.', [':update' => 'https://www.drupal.org/documentation/modules/update', ':modules' => \Drupal::url('system.modules_list')]) . '

          '; // Only explain the Update manager if it has not been disabled. if (_update_manager_access()) { $output .= '

          ' . t('The Update Manager also allows administrators to update and install modules and themes through the administration interface.') . '

          '; @@ -79,13 +124,13 @@ function update_help($route_name, RouteMatchInterface $route_match) { $output .= '

          ' . t('Uses') . '

          '; $output .= '
          '; $output .= '
          ' . t('Checking for available updates') . '
          '; - $output .= '
          ' . t('The Available updates report displays core, contributed modules, and themes for which there are new releases available for download. On the report page, you can also check manually for updates. You can configure the frequency of update checks, which are performed during cron runs, and whether notifications are sent on the Update Manager settings page.', array(':update-report' => \Drupal::url('update.status'), ':update-settings' => \Drupal::url('update.settings'))) . '
          '; + $output .= '
          ' . t('The Available updates report displays core, contributed modules, and themes for which there are new releases available for download. On the report page, you can also check manually for updates. You can configure the frequency of update checks, which are performed during cron runs, and whether notifications are sent on the Update Manager settings page.', [':update-report' => \Drupal::url('update.status'), ':update-settings' => \Drupal::url('update.settings')]) . '
          '; // Only explain the Update manager if it has not been disabled. if (_update_manager_access()) { $output .= '
          ' . t('Performing updates through the Update page') . '
          '; - $output .= '
          ' . t('The Update Manager module allows administrators to perform updates directly from the Update page. It lists all available updates, and you can confirm whether you want to download them. If you don\'t have sufficient access rights to your web server, you could be prompted for your FTP/SSH password. Afterwards the files are transferred into your site installation, overwriting your old files. Direct links to the Update page are also displayed on the Extend page and the Appearance page.', array(':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':update-page' => \Drupal::url('update.report_update'))) . '
          '; + $output .= '
          ' . t('The Update Manager module allows administrators to perform updates directly from the Update page. It lists all available updates, and you can confirm whether you want to download them. If you don\'t have sufficient access rights to your web server, you could be prompted for your FTP/SSH password. Afterwards the files are transferred into your site installation, overwriting your old files. Direct links to the Update page are also displayed on the Extend page and the Appearance page.', [':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':update-page' => \Drupal::url('update.report_update')]) . '
          '; $output .= '
          ' . t('Installing new modules and themes through the Install page') . '
          '; - $output .= '
          ' . t('You can also install new modules and themes in the same fashion, through the Install page, or by clicking the Install new module/theme links at the top of the Extend page and the Appearance page. In this case, you are prompted to provide either the URL to the download, or to upload a packaged release file from your local computer.', array(':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':install' => \Drupal::url('update.report_install'))) . '
          '; + $output .= '
          ' . t('You can also install new modules and themes in the same fashion, through the Install page, or by clicking the Install new module/theme links at the top of the Extend page and the Appearance page. In this case, you are prompted to provide either the URL to the download, or to upload a packaged release file from your local computer.', [':modules_page' => \Drupal::url('system.modules_list'), ':themes_page' => \Drupal::url('system.themes_page'), ':install' => \Drupal::url('update.report_install')]) . '
          '; } $output .= '
          '; return $output; @@ -95,10 +140,10 @@ function update_help($route_name, RouteMatchInterface $route_match) { case 'system.modules_list': if (_update_manager_access()) { - $output = '

          ' . t('Regularly review and install available updates to maintain a secure and current site. Always run the update script each time a module is updated.', array(':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status'))) . '

          '; + $output = '

          ' . t('Regularly review and install available updates to maintain a secure and current site. Always run the update script each time a module is updated.', [':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status')]) . '

          '; } else { - $output = '

          ' . t('Regularly review available updates to maintain a secure and current site. Always run the update script each time a module is updated.', array(':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status'))) . '

          '; + $output = '

          ' . t('Regularly review available updates to maintain a secure and current site. Always run the update script each time a module is updated.', [':update-php' => \Drupal::url('system.db_update'), ':updates' => \Drupal::url('update.status')]) . '

          '; } return $output; } @@ -137,7 +182,7 @@ function update_page_top() { } module_load_install('update'); $status = update_requirements('runtime'); - foreach (array('core', 'contrib') as $report_type) { + foreach (['core', 'contrib'] as $report_type) { $type = 'update_' . $report_type; // hook_requirements() supports render arrays therefore we need to render // them before using drupal_set_message(). @@ -185,25 +230,25 @@ function _update_manager_access() { * Implements hook_theme(). */ function update_theme() { - return array( - 'update_last_check' => array( - 'variables' => array('last' => 0), - ), - 'update_report' => array( - 'variables' => array('data' => NULL), + return [ + 'update_last_check' => [ + 'variables' => ['last' => 0], + ], + 'update_report' => [ + 'variables' => ['data' => NULL], 'file' => 'update.report.inc', - ), - 'update_project_status' => array( - 'variables' => array('project' => array()), + ], + 'update_project_status' => [ + 'variables' => ['project' => []], 'file' => 'update.report.inc', - ), + ], // We are using template instead of '#type' => 'table' here to keep markup // out of preprocess and allow for easier changes to markup. - 'update_version' => array( - 'variables' => array('version' => NULL, 'title' => NULL, 'attributes' => array()), + 'update_version' => [ + 'variables' => ['version' => NULL, 'title' => NULL, 'attributes' => []], 'file' => 'update.report.inc', - ), - ); + ], + ]; } /** @@ -285,10 +330,10 @@ function update_storage_clear_submit($form, FormStateInterface $form_state) { */ function _update_no_data() { $destination = \Drupal::destination()->getAsArray(); - return t('No update information available. Run cron or check manually.', array( + return t('No update information available. Run cron or check manually.', [ ':run_cron' => \Drupal::url('system.run_cron', [], ['query' => $destination]), ':check_manually' => \Drupal::url('update.manual_status', [], ['query' => $destination]), - )); + ]); } /** @@ -322,7 +367,7 @@ function update_get_available($refresh = FALSE) { foreach ($projects as $key => $project) { // If there's no data at all, we clearly need to fetch some. if (empty($available[$key])) { - //update_create_fetch_task($project); + // update_create_fetch_task($project); \Drupal::service('update.processor')->createFetchTask($project); $needs_refresh = TRUE; continue; @@ -444,20 +489,20 @@ function update_fetch_data_finished($success, $results) { function update_mail($key, &$message, $params) { $langcode = $message['langcode']; $language = \Drupal::languageManager()->getLanguage($langcode); - $message['subject'] .= t('New release(s) available for @site_name', array('@site_name' => \Drupal::config('system.site')->get('name')), array('langcode' => $langcode)); + $message['subject'] .= t('New release(s) available for @site_name', ['@site_name' => \Drupal::config('system.site')->get('name')], ['langcode' => $langcode]); foreach ($params as $msg_type => $msg_reason) { $message['body'][] = _update_message_text($msg_type, $msg_reason, $langcode); } - $message['body'][] = t('See the available updates page for more information:', array(), array('langcode' => $langcode)) . "\n" . \Drupal::url('update.status', [], ['absolute' => TRUE, 'language' => $language]); + $message['body'][] = t('See the available updates page for more information:', [], ['langcode' => $langcode]) . "\n" . \Drupal::url('update.status', [], ['absolute' => TRUE, 'language' => $language]); if (_update_manager_access()) { - $message['body'][] = t('You can automatically install your missing updates using the Update manager:', array(), array('langcode' => $langcode)) . "\n" . \Drupal::url('update.report_update', [], ['absolute' => TRUE, 'language' => $language]); + $message['body'][] = t('You can automatically install your missing updates using the Update manager:', [], ['langcode' => $langcode]) . "\n" . \Drupal::url('update.report_update', [], ['absolute' => TRUE, 'language' => $language]); } $settings_url = \Drupal::url('update.settings', [], ['absolute' => TRUE]); if (\Drupal::config('update.settings')->get('notification.threshold') == 'all') { - $message['body'][] = t('Your site is currently configured to send these emails when any updates are available. To get notified only for security updates, @url.', array('@url' => $settings_url)); + $message['body'][] = t('Your site is currently configured to send these emails when any updates are available. To get notified only for security updates, @url.', ['@url' => $settings_url]); } else { - $message['body'][] = t('Your site is currently configured to send these emails only when security updates are available. To get notified for any available updates, @url.', array('@url' => $settings_url)); + $message['body'][] = t('Your site is currently configured to send these emails only when security updates are available. To get notified for any available updates, @url.', ['@url' => $settings_url]); } } @@ -484,37 +529,37 @@ function _update_message_text($msg_type, $msg_reason, $langcode = NULL) { switch ($msg_reason) { case UPDATE_NOT_SECURE: if ($msg_type == 'core') { - $text = t('There is a security update available for your version of Drupal. To ensure the security of your server, you should update immediately!', array(), array('langcode' => $langcode)); + $text = t('There is a security update available for your version of Drupal. To ensure the security of your server, you should update immediately!', [], ['langcode' => $langcode]); } else { - $text = t('There are security updates available for one or more of your modules or themes. To ensure the security of your server, you should update immediately!', array(), array('langcode' => $langcode)); + $text = t('There are security updates available for one or more of your modules or themes. To ensure the security of your server, you should update immediately!', [], ['langcode' => $langcode]); } break; case UPDATE_REVOKED: if ($msg_type == 'core') { - $text = t('Your version of Drupal has been revoked and is no longer available for download. Upgrading is strongly recommended!', array(), array('langcode' => $langcode)); + $text = t('Your version of Drupal has been revoked and is no longer available for download. Upgrading is strongly recommended!', [], ['langcode' => $langcode]); } else { - $text = t('The installed version of at least one of your modules or themes has been revoked and is no longer available for download. Upgrading or disabling is strongly recommended!', array(), array('langcode' => $langcode)); + $text = t('The installed version of at least one of your modules or themes has been revoked and is no longer available for download. Upgrading or disabling is strongly recommended!', [], ['langcode' => $langcode]); } break; case UPDATE_NOT_SUPPORTED: if ($msg_type == 'core') { - $text = t('Your version of Drupal is no longer supported. Upgrading is strongly recommended!', array(), array('langcode' => $langcode)); + $text = t('Your version of Drupal is no longer supported. Upgrading is strongly recommended!', [], ['langcode' => $langcode]); } else { - $text = t('The installed version of at least one of your modules or themes is no longer supported. Upgrading or disabling is strongly recommended. See the project homepage for more details.', array(), array('langcode' => $langcode)); + $text = t('The installed version of at least one of your modules or themes is no longer supported. Upgrading or disabling is strongly recommended. See the project homepage for more details.', [], ['langcode' => $langcode]); } break; case UPDATE_NOT_CURRENT: if ($msg_type == 'core') { - $text = t('There are updates available for your version of Drupal. To ensure the proper functioning of your site, you should update as soon as possible.', array(), array('langcode' => $langcode)); + $text = t('There are updates available for your version of Drupal. To ensure the proper functioning of your site, you should update as soon as possible.', [], ['langcode' => $langcode]); } else { - $text = t('There are updates available for one or more of your modules or themes. To ensure the proper functioning of your site, you should update as soon as possible.', array(), array('langcode' => $langcode)); + $text = t('There are updates available for one or more of your modules or themes. To ensure the proper functioning of your site, you should update as soon as possible.', [], ['langcode' => $langcode]); } break; @@ -523,10 +568,10 @@ function _update_message_text($msg_type, $msg_reason, $langcode = NULL) { case UPDATE_NOT_FETCHED: case UPDATE_FETCH_PENDING: if ($msg_type == 'core') { - $text = t('There was a problem checking available updates for Drupal.', array(':update-report' => \Drupal::url('update.status')), array('langcode' => $langcode)); + $text = t('There was a problem checking available updates for Drupal.', [':update-report' => \Drupal::url('update.status')], ['langcode' => $langcode]); } else { - $text = t('There was a problem checking available updates for your modules or themes.', array(':update-report' => \Drupal::url('update.status')), array('langcode' => $langcode)); + $text = t('There was a problem checking available updates for your modules or themes.', [':update-report' => \Drupal::url('update.status')], ['langcode' => $langcode]); } break; } @@ -566,7 +611,7 @@ function _update_project_status_sort($a, $b) { */ function template_preprocess_update_last_check(&$variables) { $variables['time'] = \Drupal::service('date.formatter')->formatTimeDiffSince($variables['last']); - $variables['link'] = \Drupal::l(t('Check manually'), new Url('update.manual_status', array(), array('query' => \Drupal::destination()->getAsArray()))); + $variables['link'] = \Drupal::l(t('Check manually'), new Url('update.manual_status', [], ['query' => \Drupal::destination()->getAsArray()])); } /** @@ -583,7 +628,7 @@ function template_preprocess_update_last_check(&$variables) { * @see _system_rebuild_module_data() */ function update_verify_update_archive($project, $archive_file, $directory) { - $errors = array(); + $errors = []; // Make sure this isn't a tarball of Drupal core. if ( @@ -593,9 +638,9 @@ function update_verify_update_archive($project, $archive_file, $directory) { && file_exists("$directory/$project/core/modules/node/node.module") && file_exists("$directory/$project/core/modules/system/system.module") ) { - return array( - 'no-core' => t('Automatic updating of Drupal core is not supported. See the upgrade guide for information on how to update Drupal core manually.', array(':upgrade-guide' => 'https://www.drupal.org/upgrade')), - ); + return [ + 'no-core' => t('Automatic updating of Drupal core is not supported. See the upgrade guide for information on how to update Drupal core manually.', [':upgrade-guide' => 'https://www.drupal.org/upgrade']), + ]; } // Parse all the .info.yml files and make sure at least one is compatible with @@ -604,8 +649,8 @@ function update_verify_update_archive($project, $archive_file, $directory) { // with some out-of-date modules that are not necessary for its overall // functionality). $compatible_project = FALSE; - $incompatible = array(); - $files = file_scan_directory("$directory/$project", '/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', array('key' => 'name', 'min_depth' => 0)); + $incompatible = []; + $files = file_scan_directory("$directory/$project", '/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', ['key' => 'name', 'min_depth' => 0]); foreach ($files as $file) { // Get the .info.yml file for the module or theme this file belongs to. $info = \Drupal::service('info_parser')->parse($file->uri); @@ -621,14 +666,14 @@ function update_verify_update_archive($project, $archive_file, $directory) { } if (empty($files)) { - $errors[] = t('%archive_file does not contain any .info.yml files.', array('%archive_file' => drupal_basename($archive_file))); + $errors[] = t('%archive_file does not contain any .info.yml files.', ['%archive_file' => drupal_basename($archive_file)]); } elseif (!$compatible_project) { $errors[] = \Drupal::translation()->formatPlural( count($incompatible), '%archive_file contains a version of %names that is not compatible with Drupal @version.', '%archive_file contains versions of modules or themes that are not compatible with Drupal @version: %names', - array('@version' => \Drupal::CORE_COMPATIBILITY, '%archive_file' => drupal_basename($archive_file), '%names' => implode(', ', $incompatible)) + ['@version' => \Drupal::CORE_COMPATIBILITY, '%archive_file' => drupal_basename($archive_file), '%names' => implode(', ', $incompatible)] ); } @@ -707,14 +752,14 @@ function _update_manager_cache_directory($create = TRUE) { function update_clear_update_disk_cache() { // List of update module cache directories. Do not create the directories if // they do not exist. - $directories = array( + $directories = [ _update_manager_cache_directory(FALSE), _update_manager_extract_directory(FALSE), - ); + ]; // Search for files and directories in base folder only without recursion. foreach ($directories as $directory) { - file_scan_directory($directory, '/.*/', array('callback' => 'update_delete_file_if_stale', 'recurse' => FALSE)); + file_scan_directory($directory, '/.*/', ['callback' => 'update_delete_file_if_stale', 'recurse' => FALSE]); } } diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc index 5f198d9b..7b14a058 100644 --- a/core/modules/update/update.report.inc +++ b/core/modules/update/update.report.inc @@ -23,36 +23,36 @@ function template_preprocess_update_report(&$variables) { $last = \Drupal::state()->get('update.last_check') ?: 0; - $variables['last_checked'] = array( + $variables['last_checked'] = [ '#theme' => 'update_last_check', '#last' => $last, // Attach the library to a variable that gets printed always. - '#attached' => array( - 'library' => array( + '#attached' => [ + 'library' => [ 'update/drupal.update.admin', - ), - ) - ); + ], + ] + ]; // For no project update data, populate no data message. if (empty($data)) { $variables['no_updates_message'] = _update_no_data(); } - $rows = array(); + $rows = []; foreach ($data as $project) { - $project_status = array( + $project_status = [ '#theme' => 'update_project_status', '#project' => $project, - ); + ]; // Build project rows. if (!isset($rows[$project['project_type']])) { - $rows[$project['project_type']] = array( + $rows[$project['project_type']] = [ '#type' => 'table', - '#attributes' => array('class' => array('update')), - ); + '#attributes' => ['class' => ['update']], + ]; } $row_key = !empty($project['title']) ? Unicode::strtolower($project['title']) : Unicode::strtolower($project['name']); @@ -62,7 +62,7 @@ function template_preprocess_update_report(&$variables) { // Add project status class attribute to the table row. switch ($project['status']) { case UPDATE_CURRENT: - $rows[$project['project_type']][$row_key]['#attributes'] = array('class' => array('color-success')); + $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-success']]; break; case UPDATE_UNKNOWN: case UPDATE_FETCH_PENDING: @@ -70,32 +70,32 @@ function template_preprocess_update_report(&$variables) { case UPDATE_NOT_SECURE: case UPDATE_REVOKED: case UPDATE_NOT_SUPPORTED: - $rows[$project['project_type']][$row_key]['#attributes'] = array('class' => array('color-error')); + $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-error']]; break; case UPDATE_NOT_CHECKED: case UPDATE_NOT_CURRENT: default: - $rows[$project['project_type']][$row_key]['#attributes'] = array('class' => array('color-warning')); + $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-warning']]; break; } } - $project_types = array( + $project_types = [ 'core' => t('Drupal core'), 'module' => t('Modules'), 'theme' => t('Themes'), 'module-disabled' => t('Uninstalled modules'), 'theme-disabled' => t('Uninstalled themes'), - ); + ]; - $variables['project_types'] = array(); + $variables['project_types'] = []; foreach ($project_types as $type_name => $type_label) { if (!empty($rows[$type_name])) { ksort($rows[$type_name]); - $variables['project_types'][] = array( + $variables['project_types'][] = [ 'label' => $type_label, 'table' => $rows[$type_name], - ); + ]; } } } @@ -124,9 +124,9 @@ function template_preprocess_update_project_status(&$variables) { $variables['existing_version'] = $project['existing_version']; - $versions_inner = array(); - $security_class = array(); - $version_class = array(); + $versions_inner = []; + $security_class = []; + $version_class = []; if (isset($project['recommended'])) { if ($project['status'] != UPDATE_CURRENT || $project['existing_version'] !== $project['recommended']) { @@ -156,57 +156,57 @@ function template_preprocess_update_project_status(&$variables) { ) { $version_class[] = 'project-update__version--recommended-strong'; } - $versions_inner[] = array( + $versions_inner[] = [ '#theme' => 'update_version', '#version' => $project['releases'][$project['recommended']], '#title' => t('Recommended version:'), - '#attributes' => array('class' => $version_class), - ); + '#attributes' => ['class' => $version_class], + ]; } // Now, print any security updates. if (!empty($project['security updates'])) { $security_class[] = 'version-security'; foreach ($project['security updates'] as $security_update) { - $versions_inner[] = array( + $versions_inner[] = [ '#theme' => 'update_version', '#version' => $security_update, '#title' => t('Security update:'), - '#attributes' => array('class' => $security_class), - ); + '#attributes' => ['class' => $security_class], + ]; } } } if ($project['recommended'] !== $project['latest_version']) { - $versions_inner[] = array( + $versions_inner[] = [ '#theme' => 'update_version', '#version' => $project['releases'][$project['latest_version']], '#title' => t('Latest version:'), - '#attributes' => array('class' => array('version-latest')), - ); + '#attributes' => ['class' => ['version-latest']], + ]; } if ($project['install_type'] == 'dev' && $project['status'] != UPDATE_CURRENT && isset($project['dev_version']) && $project['recommended'] !== $project['dev_version']) { - $versions_inner[] = array( + $versions_inner[] = [ '#theme' => 'update_version', '#version' => $project['releases'][$project['dev_version']], '#title' => t('Development version:'), - '#attributes' => array('class' => array('version-latest')), - ); + '#attributes' => ['class' => ['version-latest']], + ]; } } if (isset($project['also'])) { foreach ($project['also'] as $also) { - $versions_inner[] = array( + $versions_inner[] = [ '#theme' => 'update_version', '#version' => $project['releases'][$also], '#title' => t('Also available:'), - '#attributes' => array('class' => array('version-also-available')), - ); + '#attributes' => ['class' => ['version-also-available']], + ]; } } @@ -222,10 +222,10 @@ function template_preprocess_update_project_status(&$variables) { sort($project['includes']); $variables['includes'] = $project['includes']; - $variables['extras'] = array(); + $variables['extras'] = []; if (!empty($project['extra'])) { foreach ($project['extra'] as $value) { - $extra_item = array(); + $extra_item = []; $extra_item['attributes'] = new Attribute(); $extra_item['label'] = $value['label']; $extra_item['data'] = [ @@ -285,12 +285,12 @@ function template_preprocess_update_project_status(&$variables) { break; } - $variables['status']['icon'] = array( + $variables['status']['icon'] = [ '#theme' => 'image', '#width' => 18, '#height' => 18, '#uri' => $uri, '#alt' => $text, '#title' => $text, - ); + ]; } diff --git a/core/modules/user/config/optional/views.view.user_admin_people.yml b/core/modules/user/config/optional/views.view.user_admin_people.yml index 386b10ea..e829a209 100644 --- a/core/modules/user/config/optional/views.view.user_admin_people.yml +++ b/core/modules/user/config/optional/views.view.user_admin_people.yml @@ -617,6 +617,54 @@ display: name: name mail: mail plugin_id: combine + status: + id: status + table: users_field_data + field: status + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: '1' + group: 1 + exposed: true + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: status_op + identifier: status + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: true + group_info: + label: Status + description: '' + identifier: status + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: + 1: + title: Active + operator: '=' + value: '1' + 2: + title: Blocked + operator: '=' + value: '0' + plugin_id: boolean + entity_type: user + entity_field: status roles_target_id: id: roles_target_id table: user__roles @@ -697,54 +745,6 @@ display: group_items: { } reduce_duplicates: false plugin_id: user_permissions - status: - id: status - table: users_field_data - field: status - relationship: none - group_type: group - admin_label: '' - operator: '=' - value: '1' - group: 1 - exposed: true - expose: - operator_id: '' - label: '' - description: '' - use_operator: false - operator: status_op - identifier: status - required: false - remember: false - multiple: false - remember_roles: - authenticated: authenticated - anonymous: '0' - administrator: '0' - is_grouped: true - group_info: - label: Status - description: '' - identifier: status - optional: true - widget: select - multiple: false - remember: false - default_group: All - default_group_multiple: { } - group_items: - 1: - title: Active - operator: '=' - value: '1' - 2: - title: Blocked - operator: '=' - value: '0' - plugin_id: boolean - entity_type: user - entity_field: status default_langcode: id: default_langcode table: users_field_data diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml index 627d8a69..2f9bda44 100644 --- a/core/modules/user/config/schema/user.schema.yml +++ b/core/modules/user/config/schema/user.schema.yml @@ -166,8 +166,10 @@ condition.plugin.user_role: sequence: type: string +# Schema for the entity reference 'default:user' selection handler settings. entity_reference_selection.default:user: - type: entity_reference_selection + type: entity_reference_selection.default + label: 'User selection handler settings' mapping: filter: type: mapping diff --git a/core/modules/user/migration_templates/d6_user.yml b/core/modules/user/migration_templates/d6_user.yml index c82c6575..d58607b1 100644 --- a/core/modules/user/migration_templates/d6_user.yml +++ b/core/modules/user/migration_templates/d6_user.yml @@ -32,11 +32,11 @@ process: fallback_to_site_default: true init: init roles: - plugin: migration + plugin: migration_lookup migration: d6_user_role source: roles user_picture: - plugin: migration + plugin: migration_lookup migration: d6_user_picture_file source: uid no_stub: true diff --git a/core/modules/user/migration_templates/d6_user_mail.yml b/core/modules/user/migration_templates/d6_user_mail.yml index b06b6ea2..9b25b943 100644 --- a/core/modules/user/migration_templates/d6_user_mail.yml +++ b/core/modules/user/migration_templates/d6_user_mail.yml @@ -19,6 +19,7 @@ source: - user_mail_register_pending_approval_body - user_mail_status_blocked_subject - user_mail_status_blocked_body + source_module: user process: 'status_activated/subject': plugin: convert_tokens diff --git a/core/modules/user/migration_templates/d6_user_picture_file.yml b/core/modules/user/migration_templates/d6_user_picture_file.yml index d367f33b..3518d7a6 100644 --- a/core/modules/user/migration_templates/d6_user_picture_file.yml +++ b/core/modules/user/migration_templates/d6_user_picture_file.yml @@ -11,9 +11,6 @@ source: # table are specified, and must end with a /. source_base_path: '' process: - # If you are using both this migration and d6_file in a custom migration - # and executing migrations incrementally, it is recommended that you - # remove the fid mapping from d6_file to avoid potential ID conflicts. filename: filename uid: uid source_full_path: diff --git a/core/modules/user/migration_templates/d6_user_settings.yml b/core/modules/user/migration_templates/d6_user_settings.yml index 6e25ece3..2dfa946f 100644 --- a/core/modules/user/migration_templates/d6_user_settings.yml +++ b/core/modules/user/migration_templates/d6_user_settings.yml @@ -10,6 +10,7 @@ source: - user_email_verification - user_register - anonymous + source_module: user process: 'notify/status_blocked': user_mail_status_blocked_notify 'notify/status_activated': user_mail_status_activated_notify diff --git a/core/modules/user/migration_templates/d7_user.yml b/core/modules/user/migration_templates/d7_user.yml index d68e2971..54c88058 100644 --- a/core/modules/user/migration_templates/d7_user.yml +++ b/core/modules/user/migration_templates/d7_user.yml @@ -31,7 +31,7 @@ process: fallback_to_site_default: true init: init roles: - plugin: migration + plugin: migration_lookup migration: d7_user_role source: roles user_picture: @@ -40,7 +40,7 @@ process: source: picture default_value: null - - plugin: migration + plugin: migration_lookup migration: d7_file destination: plugin: entity:user @@ -55,4 +55,3 @@ migration_dependencies: - user_picture_field_instance - user_picture_entity_display - user_picture_entity_form_display - - d7_field_instance diff --git a/core/modules/user/migration_templates/d7_user_flood.yml b/core/modules/user/migration_templates/d7_user_flood.yml index ae00ce08..db087534 100644 --- a/core/modules/user/migration_templates/d7_user_flood.yml +++ b/core/modules/user/migration_templates/d7_user_flood.yml @@ -10,6 +10,7 @@ source: - user_failed_login_ip_window - user_failed_login_user_window - user_failed_login_user_limit + source_module: user process: uid_only: user_failed_login_identifier_uid_only ip_limit: user_failed_login_ip_limit diff --git a/core/modules/user/migration_templates/d7_user_mail.yml b/core/modules/user/migration_templates/d7_user_mail.yml index 0c5e74c3..81051ef4 100644 --- a/core/modules/user/migration_templates/d7_user_mail.yml +++ b/core/modules/user/migration_templates/d7_user_mail.yml @@ -19,6 +19,7 @@ source: - user_mail_register_pending_approval_body - user_mail_status_blocked_subject - user_mail_status_blocked_body + source_module: user process: 'status_activated/subject': user_mail_status_activated_subject 'status_activated/body': user_mail_status_activated_body diff --git a/core/modules/user/migration_templates/user_picture_field.yml b/core/modules/user/migration_templates/user_picture_field.yml index ff8bd827..7f7134de 100644 --- a/core/modules/user/migration_templates/user_picture_field.yml +++ b/core/modules/user/migration_templates/user_picture_field.yml @@ -12,6 +12,7 @@ source: type: image name: user_picture cardinality: 1 + source_module: user process: entity_type: 'constants/entity_type' field_name: 'constants/name' diff --git a/core/modules/user/src/Access/LoginStatusCheck.php b/core/modules/user/src/Access/LoginStatusCheck.php index 3212c0a7..c3784206 100644 --- a/core/modules/user/src/Access/LoginStatusCheck.php +++ b/core/modules/user/src/Access/LoginStatusCheck.php @@ -26,7 +26,11 @@ class LoginStatusCheck implements AccessInterface { public function access(AccountInterface $account, Route $route) { $required_status = filter_var($route->getRequirement('_user_is_logged_in'), FILTER_VALIDATE_BOOLEAN); $actual_status = $account->isAuthenticated(); - return AccessResult::allowedIf($required_status === $actual_status)->addCacheContexts(['user.roles:authenticated']); + $access_result = AccessResult::allowedIf($required_status === $actual_status)->addCacheContexts(['user.roles:authenticated']); + if (!$access_result->isAllowed()) { + $access_result->setReason($required_status === TRUE ? 'This route can only be accessed by authenticated users.' : 'This route can only be accessed by anonymous users.'); + } + return $access_result; } } diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php index dbdb08b8..d6959681 100644 --- a/core/modules/user/src/AccountForm.php +++ b/core/modules/user/src/AccountForm.php @@ -2,11 +2,12 @@ namespace Drupal\user; +use Drupal\Component\Datetime\TimeInterface; use Drupal\Component\Utility\Crypt; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\EntityConstraintViolationListInterface; use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageManagerInterface; @@ -27,13 +28,6 @@ abstract class AccountForm extends ContentEntityForm { */ protected $languageManager; - /** - * The entity query factory service. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $entityQuery; - /** * Constructs a new EntityForm object. * @@ -41,13 +35,14 @@ abstract class AccountForm extends ContentEntityForm { * The entity manager. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * The language manager. - * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query - * The entity query factory. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info + * The entity type bundle service. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. */ - public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, QueryFactory $entity_query) { - parent::__construct($entity_manager); + public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) { + parent::__construct($entity_manager, $entity_type_bundle_info, $time); $this->languageManager = $language_manager; - $this->entityQuery = $entity_query; } /** @@ -57,7 +52,8 @@ public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager'), $container->get('language_manager'), - $container->get('entity.query') + $container->get('entity_type.bundle.info'), + $container->get('datetime.time') ); } @@ -76,48 +72,48 @@ public function form(array $form, FormStateInterface $form_state) { $admin = $user->hasPermission('administer users'); // Account information. - $form['account'] = array( + $form['account'] = [ '#type' => 'container', '#weight' => -10, - ); + ]; // The mail field is NOT required if account originally had no mail set // and the user performing the edit has 'administer users' permission. // This allows users without email address to be edited and deleted. // Also see \Drupal\user\Plugin\Validation\Constraint\UserMailRequired. - $form['account']['mail'] = array( + $form['account']['mail'] = [ '#type' => 'email', '#title' => $this->t('Email address'), '#description' => $this->t('A valid email address. All emails from the system will be sent to this address. The email address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by email.'), - '#required' => !(!$account->getEmail() && $user->hasPermission('administer users')), + '#required' => !(!$account->getEmail() && $admin), '#default_value' => (!$register ? $account->getEmail() : ''), - ); + ]; // Only show name field on registration form or user can change own username. - $form['account']['name'] = array( + $form['account']['name'] = [ '#type' => 'textfield', '#title' => $this->t('Username'), '#maxlength' => USERNAME_MAX_LENGTH, '#description' => $this->t("Several special characters are allowed, including space, period (.), hyphen (-), apostrophe ('), underscore (_), and the @ sign."), '#required' => TRUE, - '#attributes' => array( - 'class' => array('username'), + '#attributes' => [ + 'class' => ['username'], 'autocorrect' => 'off', 'autocapitalize' => 'off', 'spellcheck' => 'false', - ), - '#default_value' => (!$register ? $account->getUsername() : ''), + ], + '#default_value' => (!$register ? $account->getAccountName() : ''), '#access' => ($register || ($user->id() == $account->id() && $user->hasPermission('change own username')) || $admin), - ); + ]; // Display password field only for existing users or when user is allowed to // assign a password during registration. if (!$register) { - $form['account']['pass'] = array( + $form['account']['pass'] = [ '#type' => 'password_confirm', '#size' => 25, '#description' => $this->t('To change the current user password, enter the new password in both fields.'), - ); + ]; // To skip the current password field, the user must have logged in via a // one-time link and have the token in the URL. Store this in $form_state @@ -130,7 +126,7 @@ public function form(array $form, FormStateInterface $form_state) { // The user must enter their current password to change to a new one. if ($user->id() == $account->id()) { - $form['account']['current_pass'] = array( + $form['account']['current_pass'] = [ '#type' => 'password', '#title' => $this->t('Current password'), '#size' => 25, @@ -139,34 +135,34 @@ public function form(array $form, FormStateInterface $form_state) { // Do not let web browsers remember this password, since we are // trying to confirm that the person submitting the form actually // knows the current one. - '#attributes' => array('autocomplete' => 'off'), - ); + '#attributes' => ['autocomplete' => 'off'], + ]; $form_state->set('user', $account); // The user may only change their own password without their current // password if they logged in via a one-time login link. if (!$form_state->get('user_pass_reset')) { - $form['account']['current_pass']['#description'] = $this->t('Required if you want to change the %mail or %pass below. Reset your password.', array( + $form['account']['current_pass']['#description'] = $this->t('Required if you want to change the %mail or %pass below. Reset your password.', [ '%mail' => $form['account']['mail']['#title'], '%pass' => $this->t('Password'), ':request_new_url' => $this->url('user.pass'), - )); + ]); } } } elseif (!$config->get('verify_mail') || $admin) { - $form['account']['pass'] = array( + $form['account']['pass'] = [ '#type' => 'password_confirm', '#size' => 25, '#description' => $this->t('Provide a password for the new account in both fields.'), '#required' => TRUE, - ); + ]; } // When not building the user registration form, prevent web browsers from // autofilling/prefilling the email, username, and password fields. if ($this->getOperation() != 'register') { - foreach (array('mail', 'name', 'pass') as $key) { + foreach (['mail', 'name', 'pass'] as $key) { if (isset($form['account'][$key])) { $form['account'][$key]['#attributes']['autocomplete'] = 'off'; } @@ -180,35 +176,35 @@ public function form(array $form, FormStateInterface $form_state) { $status = $config->get('register') == USER_REGISTER_VISITORS ? 1 : 0; } - $form['account']['status'] = array( + $form['account']['status'] = [ '#type' => 'radios', '#title' => $this->t('Status'), '#default_value' => $status, - '#options' => array($this->t('Blocked'), $this->t('Active')), + '#options' => [$this->t('Blocked'), $this->t('Active')], '#access' => $admin, - ); + ]; - $roles = array_map(array('\Drupal\Component\Utility\Html', 'escape'), user_role_names(TRUE)); + $roles = array_map(['\Drupal\Component\Utility\Html', 'escape'], user_role_names(TRUE)); - $form['account']['roles'] = array( + $form['account']['roles'] = [ '#type' => 'checkboxes', '#title' => $this->t('Roles'), - '#default_value' => (!$register ? $account->getRoles() : array()), + '#default_value' => (!$register ? $account->getRoles() : []), '#options' => $roles, '#access' => $roles && $user->hasPermission('administer permissions'), - ); + ]; // Special handling for the inevitable "Authenticated user" role. - $form['account']['roles'][RoleInterface::AUTHENTICATED_ID] = array( + $form['account']['roles'][RoleInterface::AUTHENTICATED_ID] = [ '#default_value' => TRUE, '#disabled' => TRUE, - ); + ]; - $form['account']['notify'] = array( + $form['account']['notify'] = [ '#type' => 'checkbox', '#title' => $this->t('Notify user of new account'), '#access' => $register && $admin, - ); + ]; $user_preferred_langcode = $register ? $language_interface->getId() : $account->getPreferredLangcode(); @@ -220,16 +216,16 @@ public function form(array $form, FormStateInterface $form_state) { $negotiator = $this->languageManager->getNegotiator(); $user_language_added = $negotiator && $negotiator->isNegotiationMethodEnabled(LanguageNegotiationUser::METHOD_ID, LanguageInterface::TYPE_INTERFACE); } - $form['language'] = array( + $form['language'] = [ '#type' => $this->languageManager->isMultilingual() ? 'details' : 'container', '#title' => $this->t('Language settings'), '#open' => TRUE, // Display language selector when either creating a user on the admin // interface or editing a user account. - '#access' => !$register || $user->hasPermission('administer users'), - ); + '#access' => !$register || $admin, + ]; - $form['language']['preferred_langcode'] = array( + $form['language']['preferred_langcode'] = [ '#type' => 'language_select', '#title' => $this->t('Site language'), '#languages' => LanguageInterface::STATE_CONFIGURABLE, @@ -239,7 +235,7 @@ public function form(array $form, FormStateInterface $form_state) { // language are synchronized. It can be removed if a different behavior is // desired. '#pre_render' => ['user_langcode' => [$this, 'alterPreferredLangcodeDescription']], - ); + ]; // Only show the account setting for Administration pages language to users // if one of the detection and selection methods uses it. @@ -248,7 +244,7 @@ public function form(array $form, FormStateInterface $form_state) { $negotiator = $this->languageManager->getNegotiator(); $show_admin_language = $negotiator && $negotiator->isNegotiationMethodEnabled(LanguageNegotiationUserAdmin::METHOD_ID); } - $form['language']['preferred_admin_langcode'] = array( + $form['language']['preferred_admin_langcode'] = [ '#type' => 'language_select', '#title' => $this->t('Administration pages language'), '#languages' => LanguageInterface::STATE_CONFIGURABLE, @@ -256,7 +252,7 @@ public function form(array $form, FormStateInterface $form_state) { '#access' => $show_admin_language, '#empty_option' => $this->t('- No preference -'), '#empty_value' => '', - ); + ]; // User entities contain both a langcode property (for identifying the // language of the entity data) and a preferred_langcode property (see @@ -265,7 +261,7 @@ public function form(array $form, FormStateInterface $form_state) { // language. This entity builder provides that synchronization. For // use-cases where this synchronization is not desired, a module can alter // or remove this item. - $form['#entity_builders']['sync_user_langcode'] = [$this, 'syncUserLangcode']; + $form['#entity_builders']['sync_user_langcode'] = '::syncUserLangcode'; return parent::form($form, $form_state, $account); } @@ -321,7 +317,7 @@ public function buildEntity(array $form, FormStateInterface $form_state) { $account = parent::buildEntity($form, $form_state); // Translate the empty value '' of language selects to an unset field. - foreach (array('preferred_langcode', 'preferred_admin_langcode') as $field_name) { + foreach (['preferred_langcode', 'preferred_admin_langcode'] as $field_name) { if ($form_state->getValue($field_name) === '') { $account->$field_name = NULL; } @@ -344,7 +340,7 @@ public function buildEntity(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ protected function getEditedFieldNames(FormStateInterface $form_state) { - return array_merge(array( + return array_merge([ 'name', 'pass', 'mail', @@ -352,7 +348,7 @@ protected function getEditedFieldNames(FormStateInterface $form_state) { 'langcode', 'preferred_langcode', 'preferred_admin_langcode' - ), parent::getEditedFieldNames($form_state)); + ], parent::getEditedFieldNames($form_state)); } /** @@ -362,7 +358,7 @@ protected function flagViolations(EntityConstraintViolationListInterface $violat // Manually flag violations of fields not handled by the form display. This // is necessary as entity form displays only flag violations for fields // contained in the display. - $field_names = array( + $field_names = [ 'name', 'pass', 'mail', @@ -370,7 +366,7 @@ protected function flagViolations(EntityConstraintViolationListInterface $violat 'langcode', 'preferred_langcode', 'preferred_admin_langcode' - ); + ]; foreach ($violations->getByFields($field_names) as $violation) { list($field_name) = explode('.', $violation->getPropertyPath(), 2); $form_state->setErrorByName($field_name, $violation->getMessage()); diff --git a/core/modules/user/src/AccountSettingsForm.php b/core/modules/user/src/AccountSettingsForm.php index 1e5cd498..eacc3785 100644 --- a/core/modules/user/src/AccountSettingsForm.php +++ b/core/modules/user/src/AccountSettingsForm.php @@ -85,25 +85,25 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['#attached']['library'][] = 'user/drupal.user.admin'; // Settings for anonymous users. - $form['anonymous_settings'] = array( + $form['anonymous_settings'] = [ '#type' => 'details', '#title' => $this->t('Anonymous users'), '#open' => TRUE, - ); - $form['anonymous_settings']['anonymous'] = array( + ]; + $form['anonymous_settings']['anonymous'] = [ '#type' => 'textfield', '#title' => $this->t('Name'), '#default_value' => $config->get('anonymous'), '#description' => $this->t('The name used to indicate anonymous users.'), '#required' => TRUE, - ); + ]; // Administrative role option. - $form['admin_role'] = array( + $form['admin_role'] = [ '#type' => 'details', '#title' => $this->t('Administrator role'), '#open' => TRUE, - ); + ]; // Do not allow users to set the anonymous or authenticated user roles as the // administrator role. $roles = user_role_names(TRUE); @@ -114,7 +114,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { ->execute(); $default_value = reset($admin_roles); - $form['admin_role']['user_admin_role'] = array( + $form['admin_role']['user_admin_role'] = [ '#type' => 'select', '#title' => $this->t('Administrator role'), '#empty_value' => '', @@ -124,53 +124,53 @@ public function buildForm(array $form, FormStateInterface $form_state) { // Don't allow to select a single admin role in case multiple roles got // marked as admin role already. '#access' => count($admin_roles) <= 1, - ); + ]; // @todo Remove this check once language settings are generalized. if ($this->moduleHandler->moduleExists('content_translation')) { - $form['language'] = array( + $form['language'] = [ '#type' => 'details', '#title' => $this->t('Language settings'), '#open' => TRUE, '#tree' => TRUE, - ); + ]; $form_state->set(['content_translation', 'key'], 'language'); $form['language'] += content_translation_enable_widget('user', 'user', $form, $form_state); } // User registration settings. - $form['registration_cancellation'] = array( + $form['registration_cancellation'] = [ '#type' => 'details', '#title' => $this->t('Registration and cancellation'), '#open' => TRUE, - ); - $form['registration_cancellation']['user_register'] = array( + ]; + $form['registration_cancellation']['user_register'] = [ '#type' => 'radios', '#title' => $this->t('Who can register accounts?'), '#default_value' => $config->get('register'), - '#options' => array( + '#options' => [ USER_REGISTER_ADMINISTRATORS_ONLY => $this->t('Administrators only'), USER_REGISTER_VISITORS => $this->t('Visitors'), USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL => $this->t('Visitors, but administrator approval is required'), - ) - ); - $form['registration_cancellation']['user_email_verification'] = array( + ] + ]; + $form['registration_cancellation']['user_email_verification'] = [ '#type' => 'checkbox', '#title' => $this->t('Require email verification when a visitor creates an account'), '#default_value' => $config->get('verify_mail'), '#description' => $this->t('New users will be required to validate their email address prior to logging into the site, and will be assigned a system-generated password. With this setting disabled, users will be logged in immediately upon registering, and may select their own passwords during registration.') - ); - $form['registration_cancellation']['user_password_strength'] = array( + ]; + $form['registration_cancellation']['user_password_strength'] = [ '#type' => 'checkbox', '#title' => $this->t('Enable password strength indicator'), '#default_value' => $config->get('password_strength'), - ); - $form['registration_cancellation']['user_cancel_method'] = array( + ]; + $form['registration_cancellation']['user_cancel_method'] = [ '#type' => 'radios', '#title' => $this->t('When cancelling a user account'), '#default_value' => $config->get('cancel_method'), - '#description' => $this->t('Users with the %select-cancel-method or %administer-users permissions can override this default method.', array('%select-cancel-method' => $this->t('Select method for cancelling account'), '%administer-users' => $this->t('Administer users'), ':permissions-url' => $this->url('user.admin_permissions'))), - ); + '#description' => $this->t('Users with the %select-cancel-method or %administer-users permissions can override this default method.', ['%select-cancel-method' => $this->t('Select method for cancelling account'), '%administer-users' => $this->t('Administer users'), ':permissions-url' => $this->url('user.admin_permissions')]), + ]; $form['registration_cancellation']['user_cancel_method'] += user_cancel_methods(); foreach (Element::children($form['registration_cancellation']['user_cancel_method']) as $key) { // All account cancellation methods that specify #access cannot be @@ -182,239 +182,239 @@ public function buildForm(array $form, FormStateInterface $form_state) { } // Default notifications address. - $form['mail_notification_address'] = array( + $form['mail_notification_address'] = [ '#type' => 'email', '#title' => $this->t('Notification email address'), '#default_value' => $site_config->get('mail_notification'), - '#description' => $this->t("The email address to be used as the 'from' address for all account notifications listed below. If 'Visitors, but administrator approval is required' is selected above, a notification email will also be sent to this address for any new registrations. Leave empty to use the default system email address (%site-email).", array('%site-email' => $site_config->get('mail'))), + '#description' => $this->t("The email address to be used as the 'from' address for all account notifications listed below. If 'Visitors, but administrator approval is required' is selected above, a notification email will also be sent to this address for any new registrations. Leave empty to use the default system email address (%site-email).", ['%site-email' => $site_config->get('mail')]), '#maxlength' => 180, - ); + ]; - $form['email'] = array( + $form['email'] = [ '#type' => 'vertical_tabs', '#title' => $this->t('Emails'), - ); + ]; // These email tokens are shared for all settings, so just define // the list once to help ensure they stay in sync. $email_token_help = $this->t('Available variables are: [site:name], [site:url], [user:display-name], [user:account-name], [user:mail], [site:login-url], [site:url-brief], [user:edit-url], [user:one-time-login-url], [user:cancel-url].'); - $form['email_admin_created'] = array( + $form['email_admin_created'] = [ '#type' => 'details', '#title' => $this->t('Welcome (new user created by administrator)'), '#open' => $config->get('register') == USER_REGISTER_ADMINISTRATORS_ONLY, '#description' => $this->t('Edit the welcome email messages sent to new member accounts created by an administrator.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_admin_created']['user_mail_register_admin_created_subject'] = array( + ]; + $form['email_admin_created']['user_mail_register_admin_created_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('register_admin_created.subject'), '#maxlength' => 180, - ); - $form['email_admin_created']['user_mail_register_admin_created_body'] = array( + ]; + $form['email_admin_created']['user_mail_register_admin_created_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('register_admin_created.body'), '#rows' => 15, - ); + ]; - $form['email_pending_approval'] = array( + $form['email_pending_approval'] = [ '#type' => 'details', '#title' => $this->t('Welcome (awaiting approval)'), '#open' => $config->get('register') == USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL, '#description' => $this->t('Edit the welcome email messages sent to new members upon registering, when administrative approval is required.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_pending_approval']['user_mail_register_pending_approval_subject'] = array( + ]; + $form['email_pending_approval']['user_mail_register_pending_approval_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('register_pending_approval.subject'), '#maxlength' => 180, - ); - $form['email_pending_approval']['user_mail_register_pending_approval_body'] = array( + ]; + $form['email_pending_approval']['user_mail_register_pending_approval_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('register_pending_approval.body'), '#rows' => 8, - ); + ]; - $form['email_pending_approval_admin'] = array( + $form['email_pending_approval_admin'] = [ '#type' => 'details', '#title' => $this->t('Admin (user awaiting approval)'), '#open' => $config->get('register') == USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL, '#description' => $this->t('Edit the email notifying the site administrator that there are new members awaiting administrative approval.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_pending_approval_admin']['register_pending_approval_admin_subject'] = array( + ]; + $form['email_pending_approval_admin']['register_pending_approval_admin_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('register_pending_approval_admin.subject'), '#maxlength' => 180, - ); - $form['email_pending_approval_admin']['register_pending_approval_admin_body'] = array( + ]; + $form['email_pending_approval_admin']['register_pending_approval_admin_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('register_pending_approval_admin.body'), '#rows' => 8, - ); + ]; - $form['email_no_approval_required'] = array( + $form['email_no_approval_required'] = [ '#type' => 'details', '#title' => $this->t('Welcome (no approval required)'), '#open' => $config->get('register') == USER_REGISTER_VISITORS, '#description' => $this->t('Edit the welcome email messages sent to new members upon registering, when no administrator approval is required.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_no_approval_required']['user_mail_register_no_approval_required_subject'] = array( + ]; + $form['email_no_approval_required']['user_mail_register_no_approval_required_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('register_no_approval_required.subject'), '#maxlength' => 180, - ); - $form['email_no_approval_required']['user_mail_register_no_approval_required_body'] = array( + ]; + $form['email_no_approval_required']['user_mail_register_no_approval_required_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('register_no_approval_required.body'), '#rows' => 15, - ); + ]; - $form['email_password_reset'] = array( + $form['email_password_reset'] = [ '#type' => 'details', '#title' => $this->t('Password recovery'), '#description' => $this->t('Edit the email messages sent to users who request a new password.') . ' ' . $email_token_help, '#group' => 'email', '#weight' => 10, - ); - $form['email_password_reset']['user_mail_password_reset_subject'] = array( + ]; + $form['email_password_reset']['user_mail_password_reset_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('password_reset.subject'), '#maxlength' => 180, - ); - $form['email_password_reset']['user_mail_password_reset_body'] = array( + ]; + $form['email_password_reset']['user_mail_password_reset_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('password_reset.body'), '#rows' => 12, - ); + ]; - $form['email_activated'] = array( + $form['email_activated'] = [ '#type' => 'details', '#title' => $this->t('Account activation'), '#description' => $this->t('Enable and edit email messages sent to users upon account activation (when an administrator activates an account of a user who has already registered, on a site where administrative approval is required).') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_activated']['user_mail_status_activated_notify'] = array( + ]; + $form['email_activated']['user_mail_status_activated_notify'] = [ '#type' => 'checkbox', '#title' => $this->t('Notify user when account is activated'), '#default_value' => $config->get('notify.status_activated'), - ); - $form['email_activated']['settings'] = array( + ]; + $form['email_activated']['settings'] = [ '#type' => 'container', - '#states' => array( + '#states' => [ // Hide the additional settings when this email is disabled. - 'invisible' => array( - 'input[name="user_mail_status_activated_notify"]' => array('checked' => FALSE), - ), - ), - ); - $form['email_activated']['settings']['user_mail_status_activated_subject'] = array( + 'invisible' => [ + 'input[name="user_mail_status_activated_notify"]' => ['checked' => FALSE], + ], + ], + ]; + $form['email_activated']['settings']['user_mail_status_activated_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('status_activated.subject'), '#maxlength' => 180, - ); - $form['email_activated']['settings']['user_mail_status_activated_body'] = array( + ]; + $form['email_activated']['settings']['user_mail_status_activated_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('status_activated.body'), '#rows' => 15, - ); + ]; - $form['email_blocked'] = array( + $form['email_blocked'] = [ '#type' => 'details', '#title' => $this->t('Account blocked'), '#description' => $this->t('Enable and edit email messages sent to users when their accounts are blocked.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_blocked']['user_mail_status_blocked_notify'] = array( + ]; + $form['email_blocked']['user_mail_status_blocked_notify'] = [ '#type' => 'checkbox', '#title' => $this->t('Notify user when account is blocked'), '#default_value' => $config->get('notify.status_blocked'), - ); - $form['email_blocked']['settings'] = array( + ]; + $form['email_blocked']['settings'] = [ '#type' => 'container', - '#states' => array( + '#states' => [ // Hide the additional settings when the blocked email is disabled. - 'invisible' => array( - 'input[name="user_mail_status_blocked_notify"]' => array('checked' => FALSE), - ), - ), - ); - $form['email_blocked']['settings']['user_mail_status_blocked_subject'] = array( + 'invisible' => [ + 'input[name="user_mail_status_blocked_notify"]' => ['checked' => FALSE], + ], + ], + ]; + $form['email_blocked']['settings']['user_mail_status_blocked_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('status_blocked.subject'), '#maxlength' => 180, - ); - $form['email_blocked']['settings']['user_mail_status_blocked_body'] = array( + ]; + $form['email_blocked']['settings']['user_mail_status_blocked_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('status_blocked.body'), '#rows' => 3, - ); + ]; - $form['email_cancel_confirm'] = array( + $form['email_cancel_confirm'] = [ '#type' => 'details', '#title' => $this->t('Account cancellation confirmation'), '#description' => $this->t('Edit the email messages sent to users when they attempt to cancel their accounts.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_cancel_confirm']['user_mail_cancel_confirm_subject'] = array( + ]; + $form['email_cancel_confirm']['user_mail_cancel_confirm_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('cancel_confirm.subject'), '#maxlength' => 180, - ); - $form['email_cancel_confirm']['user_mail_cancel_confirm_body'] = array( + ]; + $form['email_cancel_confirm']['user_mail_cancel_confirm_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('cancel_confirm.body'), '#rows' => 3, - ); + ]; - $form['email_canceled'] = array( + $form['email_canceled'] = [ '#type' => 'details', '#title' => $this->t('Account canceled'), '#description' => $this->t('Enable and edit email messages sent to users when their accounts are canceled.') . ' ' . $email_token_help, '#group' => 'email', - ); - $form['email_canceled']['user_mail_status_canceled_notify'] = array( + ]; + $form['email_canceled']['user_mail_status_canceled_notify'] = [ '#type' => 'checkbox', '#title' => $this->t('Notify user when account is canceled'), '#default_value' => $config->get('notify.status_canceled'), - ); - $form['email_canceled']['settings'] = array( + ]; + $form['email_canceled']['settings'] = [ '#type' => 'container', - '#states' => array( + '#states' => [ // Hide the settings when the cancel notify checkbox is disabled. - 'invisible' => array( - 'input[name="user_mail_status_canceled_notify"]' => array('checked' => FALSE), - ), - ), - ); - $form['email_canceled']['settings']['user_mail_status_canceled_subject'] = array( + 'invisible' => [ + 'input[name="user_mail_status_canceled_notify"]' => ['checked' => FALSE], + ], + ], + ]; + $form['email_canceled']['settings']['user_mail_status_canceled_subject'] = [ '#type' => 'textfield', '#title' => $this->t('Subject'), '#default_value' => $mail_config->get('status_canceled.subject'), '#maxlength' => 180, - ); - $form['email_canceled']['settings']['user_mail_status_canceled_body'] = array( + ]; + $form['email_canceled']['settings']['user_mail_status_canceled_body'] = [ '#type' => 'textarea', '#title' => $this->t('Body'), '#default_value' => $mail_config->get('status_canceled.body'), '#rows' => 3, - ); + ]; return $form; } diff --git a/core/modules/user/src/Controller/UserAuthenticationController.php b/core/modules/user/src/Controller/UserAuthenticationController.php index 3aff75ff..f45ec3a7 100644 --- a/core/modules/user/src/Controller/UserAuthenticationController.php +++ b/core/modules/user/src/Controller/UserAuthenticationController.php @@ -10,6 +10,7 @@ use Drupal\user\UserAuthInterface; use Drupal\user\UserInterface; use Drupal\user\UserStorageInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -86,6 +87,13 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn */ protected $serializerFormats = []; + /** + * A logger instance. + * + * @var \Psr\Log\LoggerInterface + */ + protected $logger; + /** * Constructs a new UserAuthenticationController object. * @@ -103,8 +111,10 @@ class UserAuthenticationController extends ControllerBase implements ContainerIn * The serializer. * @param array $serializer_formats * The available serialization formats. + * @param \Psr\Log\LoggerInterface $logger + * A logger instance. */ - public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, CsrfTokenGenerator $csrf_token, UserAuthInterface $user_auth, RouteProviderInterface $route_provider, Serializer $serializer, array $serializer_formats) { + public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, CsrfTokenGenerator $csrf_token, UserAuthInterface $user_auth, RouteProviderInterface $route_provider, Serializer $serializer, array $serializer_formats, LoggerInterface $logger) { $this->flood = $flood; $this->userStorage = $user_storage; $this->csrfToken = $csrf_token; @@ -112,6 +122,7 @@ public function __construct(FloodInterface $flood, UserStorageInterface $user_st $this->serializer = $serializer; $this->serializerFormats = $serializer_formats; $this->routeProvider = $route_provider; + $this->logger = $logger; } /** @@ -135,7 +146,8 @@ public static function create(ContainerInterface $container) { $container->get('user.auth'), $container->get('router.route_provider'), $serializer, - $formats + $formats, + $container->get('logger.factory')->get('user') ); } @@ -207,6 +219,56 @@ public function login(Request $request) { throw new BadRequestHttpException('Sorry, unrecognized username or password.'); } + /** + * Resets a user password. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request. + * + * @return \Symfony\Component\HttpFoundation\Response + * The response object. + */ + public function resetPassword(Request $request) { + $format = $this->getRequestFormat($request); + + $content = $request->getContent(); + $credentials = $this->serializer->decode($content, $format); + + // Check if a name or mail is provided. + if (!isset($credentials['name']) && !isset($credentials['mail'])) { + throw new BadRequestHttpException('Missing credentials.name or credentials.mail'); + } + + // Load by name if provided. + if (isset($credentials['name'])) { + $users = $this->userStorage->loadByProperties(['name' => trim($credentials['name'])]); + } + elseif (isset($credentials['mail'])) { + $users = $this->userStorage->loadByProperties(['mail' => trim($credentials['mail'])]); + } + + /** @var \Drupal\Core\Session\AccountInterface $account */ + $account = reset($users); + if ($account && $account->id()) { + if ($this->userIsBlocked($account->getAccountName())) { + throw new BadRequestHttpException('The user has not been activated or is blocked.'); + } + + // Send the password reset email. + $mail = _user_mail_notify('password_reset', $account, $account->getPreferredLangcode()); + if (empty($mail)) { + throw new BadRequestHttpException('Unable to send email. Contact the site administrator if the problem persists.'); + } + else { + $this->logger->notice('Password reset instructions mailed to %name at %email.', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]); + return new Response(); + } + } + + // Error if no users found with provided name or mail. + throw new BadRequestHttpException('Unrecognized username or email address.'); + } + /** * Verifies if the user is blocked. * diff --git a/core/modules/user/src/Controller/UserController.php b/core/modules/user/src/Controller/UserController.php index 779cf90f..be15fac4 100644 --- a/core/modules/user/src/Controller/UserController.php +++ b/core/modules/user/src/Controller/UserController.php @@ -121,7 +121,7 @@ public function resetPass(Request $request, $uid, $timestamp, $hash) { /** @var \Drupal\user\UserInterface $reset_link_user */ if ($reset_link_user = $this->userStorage->load($uid)) { drupal_set_message($this->t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please log out and try using the link again.', - array('%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout'))), 'warning'); + ['%other_user' => $account->getUsername(), '%resetting_user' => $reset_link_user->getUsername(), ':logout' => $this->url('user.logout')]), 'warning'); } else { // Invalid one-time link specifies an unknown user. @@ -254,7 +254,7 @@ public function resetPassLogin($uid, $timestamp, $hash) { * Returns a redirect to the profile of the currently logged in user. */ public function userPage() { - return $this->redirect('entity.user.canonical', array('user' => $this->currentUser()->id())); + return $this->redirect('entity.user.canonical', ['user' => $this->currentUser()->id()]); } /** @@ -305,9 +305,9 @@ public function confirmCancel(UserInterface $user, $timestamp = 0, $hashed_pass if (isset($account_data['cancel_method']) && !empty($timestamp) && !empty($hashed_pass)) { // Validate expiration and hashed password/login. if ($timestamp <= $current && $current - $timestamp < $timeout && $user->id() && $timestamp >= $user->getLastLoginTime() && Crypt::hashEquals($hashed_pass, user_pass_rehash($user, $timestamp))) { - $edit = array( + $edit = [ 'user_cancel_notify' => isset($account_data['cancel_notify']) ? $account_data['cancel_notify'] : $this->config('user.settings')->get('notify.status_canceled'), - ); + ]; user_cancel($edit, $user->id(), $account_data['cancel_method']); // Since user_cancel() is not invoked via Form API, batch processing // needs to be invoked manually and should redirect to the front page diff --git a/core/modules/user/src/Entity/Role.php b/core/modules/user/src/Entity/Role.php index 5ecbc028..0226f94b 100644 --- a/core/modules/user/src/Entity/Role.php +++ b/core/modules/user/src/Entity/Role.php @@ -72,7 +72,7 @@ class Role extends ConfigEntityBase implements RoleInterface { * * @var array */ - protected $permissions = array(); + protected $permissions = []; /** * An indicator whether the role has all permissions. @@ -136,7 +136,7 @@ public function revokePermission($permission) { if ($this->isAdmin()) { return $this; } - $this->permissions = array_diff($this->permissions, array($permission)); + $this->permissions = array_diff($this->permissions, [$permission]); return $this; } @@ -173,11 +173,17 @@ public function preSave(EntityStorageInterface $storage) { if (!isset($this->weight) && ($roles = $storage->loadMultiple())) { // Set a role weight to make this new role last. - $max = array_reduce($roles, function($max, $role) { + $max = array_reduce($roles, function ($max, $role) { return $max > $role->weight ? $max : $role->weight; }); $this->weight = $max + 1; } + + if (!$this->isSyncing()) { + // Permissions are always ordered alphabetically to avoid conflicts in the + // exported configuration. + sort($this->permissions); + } } } diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 6a3d6b16..75295325 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -82,13 +82,13 @@ public function preSave(EntityStorageInterface $storage) { // Make sure that the authenticated/anonymous roles are not persisted. foreach ($this->get('roles') as $index => $item) { - if (in_array($item->target_id, array(RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID))) { + if (in_array($item->target_id, [RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID])) { $this->get('roles')->offsetUnset($index); } } // Store account cancellation information. - foreach (array('user_cancel_method', 'user_cancel_notify') as $key) { + foreach (['user_cancel_method', 'user_cancel_notify'] as $key) { if (isset($this->{$key})) { \Drupal::service('user.data')->set('user', $this->id(), substr($key, 5), $this->{$key}); } @@ -140,7 +140,7 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti * {@inheritdoc} */ public function getRoles($exclude_locked_roles = FALSE) { - $roles = array(); + $roles = []; // Users with an ID always have the authenticated user role. if (!$exclude_locked_roles) { @@ -186,7 +186,7 @@ public function addRole($rid) { * {@inheritdoc} */ public function removeRole($rid) { - $this->set('roles', array_diff($this->getRoles(TRUE), array($rid))); + $this->set('roles', array_diff($this->getRoles(TRUE), [$rid])); } /** @@ -308,7 +308,7 @@ public function getTimeZone() { /** * {@inheritdoc} */ - function getPreferredLangcode($fallback_to_default = TRUE) { + public function getPreferredLangcode($fallback_to_default = TRUE) { $language_list = $this->languageManager()->getLanguages(); $preferred_langcode = $this->get('preferred_langcode')->value; if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) { @@ -322,7 +322,7 @@ function getPreferredLangcode($fallback_to_default = TRUE) { /** * {@inheritdoc} */ - function getPreferredAdminLangcode($fallback_to_default = TRUE) { + public function getPreferredAdminLangcode($fallback_to_default = TRUE) { $language_list = $this->languageManager()->getLanguages(); $preferred_langcode = $this->get('preferred_admin_langcode')->value; if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) { @@ -438,16 +438,16 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['langcode']->setLabel(t('Language code')) ->setDescription(t('The user language code.')) - ->setDisplayOptions('form', ['type' => 'hidden']); + ->setDisplayOptions('form', ['region' => 'hidden']); $fields['preferred_langcode'] = BaseFieldDefinition::create('language') ->setLabel(t('Preferred language code')) ->setDescription(t("The user's preferred language code for receiving emails and viewing the site.")) // @todo: Define this via an options provider once // https://www.drupal.org/node/2329937 is completed. - ->addPropertyConstraints('value', array( - 'AllowedValues' => array('callback' => __CLASS__ . '::getAllowedConfigurableLanguageCodes'), - )); + ->addPropertyConstraints('value', [ + 'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedConfigurableLanguageCodes'], + ]); $fields['preferred_admin_langcode'] = BaseFieldDefinition::create('language') ->setLabel(t('Preferred admin language code')) @@ -455,12 +455,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { // @todo: A default value of NULL is ignored, so we have to specify // an empty field item structure instead. Fix this in // https://www.drupal.org/node/2318605. - ->setDefaultValue(array(0 => array ('value' => NULL))) + ->setDefaultValue([0 => ['value' => NULL]]) // @todo: Define this via an options provider once // https://www.drupal.org/node/2329937 is completed. - ->addPropertyConstraints('value', array( - 'AllowedValues' => array('callback' => __CLASS__ . '::getAllowedConfigurableLanguageCodes'), - )); + ->addPropertyConstraints('value', [ + 'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedConfigurableLanguageCodes'], + ]); // The name should not vary per language. The username is the visual // identifier for a user and needs to be consistent in all languages. @@ -468,12 +468,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Name')) ->setDescription(t('The name of this user.')) ->setRequired(TRUE) - ->setConstraints(array( + ->setConstraints([ // No Length constraint here because the UserName constraint also covers // that. - 'UserName' => array(), - 'UserNameUnique' => array(), - )); + 'UserName' => [], + 'UserNameUnique' => [], + ]); $fields['name']->getItemDefinition()->setClass('\Drupal\user\UserNameItem'); $fields['pass'] = BaseFieldDefinition::create('password') @@ -495,9 +495,9 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setSetting('max_length', 32) // @todo: Define this via an options provider once // https://www.drupal.org/node/2329937 is completed. - ->addPropertyConstraints('value', array( - 'AllowedValues' => array('callback' => __CLASS__ . '::getAllowedTimezones'), - )); + ->addPropertyConstraints('value', [ + 'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedTimezones'], + ]); $fields['status'] = BaseFieldDefinition::create('boolean') ->setLabel(t('User status')) diff --git a/core/modules/user/src/Form/UserCancelForm.php b/core/modules/user/src/Form/UserCancelForm.php index 0ab89335..14c553c3 100644 --- a/core/modules/user/src/Form/UserCancelForm.php +++ b/core/modules/user/src/Form/UserCancelForm.php @@ -31,7 +31,7 @@ public function getQuestion() { if ($this->entity->id() == $this->currentUser()->id()) { return $this->t('Are you sure you want to cancel your account?'); } - return $this->t('Are you sure you want to cancel the account %name?', array('%name' => $this->entity->label())); + return $this->t('Are you sure you want to cancel the account %name?', ['%name' => $this->entity->label()]); } /** @@ -74,43 +74,43 @@ public function buildForm(array $form, FormStateInterface $form_state) { // Display account cancellation method selection, if allowed. $admin_access = $user->hasPermission('administer users'); - $form['user_cancel_method'] = array( + $form['user_cancel_method'] = [ '#type' => 'radios', '#title' => ($this->entity->id() == $user->id() ? $this->t('When cancelling your account') : $this->t('When cancelling the account')), '#access' => $admin_access || $user->hasPermission('select account cancellation method'), - ); + ]; $form['user_cancel_method'] += $this->cancelMethods; // Allow user administrators to skip the account cancellation confirmation // mail (by default), as long as they do not attempt to cancel their own // account. $override_access = $admin_access && ($this->entity->id() != $user->id()); - $form['user_cancel_confirm'] = array( + $form['user_cancel_confirm'] = [ '#type' => 'checkbox', '#title' => $this->t('Require email confirmation to cancel account'), '#default_value' => !$override_access, '#access' => $override_access, '#description' => $this->t('When enabled, the user must confirm the account cancellation via email.'), - ); + ]; // Also allow to send account canceled notification mail, if enabled. $default_notify = $this->config('user.settings')->get('notify.status_canceled'); - $form['user_cancel_notify'] = array( + $form['user_cancel_notify'] = [ '#type' => 'checkbox', '#title' => $this->t('Notify user when account is canceled'), '#default_value' => ($override_access ? FALSE : $default_notify), '#access' => $override_access && $default_notify, '#description' => $this->t('When enabled, the user will receive an email notification after the account has been canceled.'), - ); + ]; // Always provide entity id in the same form key as in the entity edit form. - $form['uid'] = array('#type' => 'value', '#value' => $this->entity->id()); + $form['uid'] = ['#type' => 'value', '#value' => $this->entity->id()]; // Store the user permissions so that it can be altered in hook_form_alter() // if desired. - $form['access'] = array( + $form['access'] = [ '#type' => 'value', '#value' => $user->hasPermission('administer users'), - ); + ]; $form = parent::buildForm($form, $form_state); @@ -138,11 +138,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->entity->save(); _user_mail_notify('cancel_confirm', $this->entity); drupal_set_message($this->t('A confirmation request to cancel your account has been sent to your email address.')); - $this->logger('user')->notice('Sent account cancellation request to %name %email.', array('%name' => $this->entity->label(), '%email' => '<' . $this->entity->getEmail() . '>')); + $this->logger('user')->notice('Sent account cancellation request to %name %email.', ['%name' => $this->entity->label(), '%email' => '<' . $this->entity->getEmail() . '>']); $form_state->setRedirect( 'entity.user.canonical', - array('user' => $this->entity->id()) + ['user' => $this->entity->id()] ); } } diff --git a/core/modules/user/src/Form/UserLoginForm.php b/core/modules/user/src/Form/UserLoginForm.php index 43b29e54..25a54ec4 100644 --- a/core/modules/user/src/Form/UserLoginForm.php +++ b/core/modules/user/src/Form/UserLoginForm.php @@ -88,31 +88,31 @@ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('system.site'); // Display login form: - $form['name'] = array( + $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Username'), '#size' => 60, '#maxlength' => USERNAME_MAX_LENGTH, - '#description' => $this->t('Enter your @s username.', array('@s' => $config->get('name'))), + '#description' => $this->t('Enter your @s username.', ['@s' => $config->get('name')]), '#required' => TRUE, - '#attributes' => array( + '#attributes' => [ 'autocorrect' => 'none', 'autocapitalize' => 'none', 'spellcheck' => 'false', 'autofocus' => 'autofocus', - ), - ); + ], + ]; - $form['pass'] = array( + $form['pass'] = [ '#type' => 'password', '#title' => $this->t('Password'), '#size' => 60, '#description' => $this->t('Enter the password that accompanies your username.'), '#required' => TRUE, - ); + ]; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Log in')); + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = ['#type' => 'submit', '#value' => $this->t('Log in')]; $form['#validate'][] = '::validateName'; $form['#validate'][] = '::validateAuthentication'; @@ -133,7 +133,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { if (!$this->getRequest()->request->has('destination')) { $form_state->setRedirect( 'entity.user.canonical', - array('user' => $account->id()) + ['user' => $account->id()] ); } else { @@ -149,7 +149,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { public function validateName(array &$form, FormStateInterface $form_state) { if (!$form_state->isValueEmpty('name') && user_is_blocked($form_state->getValue('name'))) { // Blocked in user administration. - $form_state->setErrorByName('name', $this->t('The username %name has not been activated or is blocked.', array('%name' => $form_state->getValue('name')))); + $form_state->setErrorByName('name', $this->t('The username %name has not been activated or is blocked.', ['%name' => $form_state->getValue('name')])); } } @@ -171,7 +171,7 @@ public function validateAuthentication(array &$form, FormStateInterface $form_st $form_state->set('flood_control_triggered', 'ip'); return; } - $accounts = $this->userStorage->loadByProperties(array('name' => $form_state->getValue('name'), 'status' => 1)); + $accounts = $this->userStorage->loadByProperties(['name' => $form_state->getValue('name'), 'status' => 1]); $account = reset($accounts); if ($account) { if ($flood_config->get('uid_only')) { @@ -218,11 +218,11 @@ public function validateFinal(array &$form, FormStateInterface $form_state) { if ($flood_control_triggered = $form_state->get('flood_control_triggered')) { if ($flood_control_triggered == 'user') { - $form_state->setErrorByName('name', $this->formatPlural($flood_config->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array(':url' => $this->url('user.pass')))); + $form_state->setErrorByName('name', $this->formatPlural($flood_config->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', [':url' => $this->url('user.pass')])); } else { // We did not find a uid, so the limit is IP-based. - $form_state->setErrorByName('name', $this->t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', array(':url' => $this->url('user.pass')))); + $form_state->setErrorByName('name', $this->t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', [':url' => $this->url('user.pass')])); } } else { @@ -231,16 +231,16 @@ public function validateFinal(array &$form, FormStateInterface $form_state) { // $form_state->getValue() may have been modified by validation // handlers that ran earlier than this one. $user_input = $form_state->getUserInput(); - $query = isset($user_input['name']) ? array('name' => $user_input['name']) : array(); - $form_state->setErrorByName('name', $this->t('Unrecognized username or password. Forgot your password?', array(':password' => $this->url('user.pass', [], array('query' => $query))))); - $accounts = $this->userStorage->loadByProperties(array('name' => $form_state->getValue('name'))); + $query = isset($user_input['name']) ? ['name' => $user_input['name']] : []; + $form_state->setErrorByName('name', $this->t('Unrecognized username or password. Forgot your password?', [':password' => $this->url('user.pass', [], ['query' => $query])])); + $accounts = $this->userStorage->loadByProperties(['name' => $form_state->getValue('name')]); if (!empty($accounts)) { - $this->logger('user')->notice('Login attempt failed for %user.', array('%user' => $form_state->getValue('name'))); + $this->logger('user')->notice('Login attempt failed for %user.', ['%user' => $form_state->getValue('name')]); } else { // If the username entered is not a valid user, // only store the IP address. - $this->logger('user')->notice('Login attempt failed from %ip.', array('%ip' => $this->getRequest()->getClientIp())); + $this->logger('user')->notice('Login attempt failed from %ip.', ['%ip' => $this->getRequest()->getClientIp()]); } } } diff --git a/core/modules/user/src/Form/UserMultipleCancelConfirm.php b/core/modules/user/src/Form/UserMultipleCancelConfirm.php index 1fb6ab15..62a64e5d 100644 --- a/core/modules/user/src/Form/UserMultipleCancelConfirm.php +++ b/core/modules/user/src/Form/UserMultipleCancelConfirm.php @@ -96,6 +96,7 @@ public function getConfirmText() { */ public function buildForm(array $form, FormStateInterface $form_state) { // Retrieve the accounts to be canceled from the temp store. + /* @var \Drupal\user\Entity\User[] $accounts */ $accounts = $this->tempStoreFactory ->get('user_user_operations_cancel') ->get($this->currentUser()->id()); @@ -104,26 +105,31 @@ public function buildForm(array $form, FormStateInterface $form_state) { } $root = NULL; - $form['accounts'] = array('#prefix' => '
            ', '#suffix' => '
          ', '#tree' => TRUE); + $names = []; + $form['accounts'] = ['#tree' => TRUE]; foreach ($accounts as $account) { $uid = $account->id(); + $names[$uid] = $account->label(); // Prevent user 1 from being canceled. if ($uid <= 1) { $root = intval($uid) === 1 ? $account : $root; continue; } - $form['accounts'][$uid] = array( + $form['accounts'][$uid] = [ '#type' => 'hidden', '#value' => $uid, - '#prefix' => '
        1. ', - '#suffix' => $account->label() . "
        2. \n", - ); + ]; } + $form['account']['names'] = [ + '#theme' => 'item_list', + '#items' => $names, + ]; + // Output a notice that user 1 cannot be canceled. if (isset($root)) { $redirect = (count($accounts) == 1); - $message = $this->t('The user account %name cannot be canceled.', array('%name' => $root->label())); + $message = $this->t('The user account %name cannot be canceled.', ['%name' => $root->label()]); drupal_set_message($message, $redirect ? 'error' : 'warning'); // If only user 1 was selected, redirect to the overview. if ($redirect) { @@ -131,30 +137,30 @@ public function buildForm(array $form, FormStateInterface $form_state) { } } - $form['operation'] = array('#type' => 'hidden', '#value' => 'cancel'); + $form['operation'] = ['#type' => 'hidden', '#value' => 'cancel']; - $form['user_cancel_method'] = array( + $form['user_cancel_method'] = [ '#type' => 'radios', '#title' => $this->t('When cancelling these accounts'), - ); + ]; $form['user_cancel_method'] += user_cancel_methods(); // Allow to send the account cancellation confirmation mail. - $form['user_cancel_confirm'] = array( + $form['user_cancel_confirm'] = [ '#type' => 'checkbox', '#title' => $this->t('Require email confirmation to cancel account'), '#default_value' => FALSE, '#description' => $this->t('When enabled, the user must confirm the account cancellation via email.'), - ); + ]; // Also allow to send account canceled notification mail, if enabled. - $form['user_cancel_notify'] = array( + $form['user_cancel_notify'] = [ '#type' => 'checkbox', '#title' => $this->t('Notify user when account is canceled'), '#default_value' => FALSE, '#access' => $this->config('user.settings')->get('notify.status_canceled'), '#description' => $this->t('When enabled, the user will receive an email notification after the account has been canceled.'), - ); + ]; $form = parent::buildForm($form, $form_state); @@ -177,7 +183,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } // Prevent user administrators from deleting themselves without confirmation. if ($uid == $current_user_id) { - $admin_form_mock = array(); + $admin_form_mock = []; $admin_form_state = $form_state; $admin_form_state->unsetValue('user_cancel_confirm'); // The $user global is not a complete user entity, so load the full diff --git a/core/modules/user/src/Form/UserPasswordForm.php b/core/modules/user/src/Form/UserPasswordForm.php index a89549a0..972f8250 100644 --- a/core/modules/user/src/Form/UserPasswordForm.php +++ b/core/modules/user/src/Form/UserPasswordForm.php @@ -60,45 +60,42 @@ public function getFormId() { /** * {@inheritdoc} - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['name'] = array( + $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Username or email address'), '#size' => 60, '#maxlength' => max(USERNAME_MAX_LENGTH, Email::EMAIL_MAX_LENGTH), '#required' => TRUE, - '#attributes' => array( + '#attributes' => [ 'autocorrect' => 'off', 'autocapitalize' => 'off', 'spellcheck' => 'false', 'autofocus' => 'autofocus', - ), - ); + ], + ]; // Allow logged in users to request this also. $user = $this->currentUser(); if ($user->isAuthenticated()) { $form['name']['#type'] = 'value'; $form['name']['#value'] = $user->getEmail(); - $form['mail'] = array( + $form['mail'] = [ '#prefix' => '

          ', - '#markup' => $this->t('Password reset instructions will be mailed to %email. You must log out to use the password reset link in the email.', array('%email' => $user->getEmail())), + '#markup' => $this->t('Password reset instructions will be mailed to %email. You must log out to use the password reset link in the email.', ['%email' => $user->getEmail()]), '#suffix' => '

          ', - ); + ]; } else { - $form['mail'] = array( + $form['mail'] = [ '#prefix' => '

          ', '#markup' => $this->t('Password reset instructions will be sent to your registered email address.'), '#suffix' => '

          ', - ); + ]; $form['name']['#default_value'] = $this->getRequest()->query->get('name'); } - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Submit')); + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = ['#type' => 'submit', '#value' => $this->t('Submit')]; $form['#cache']['contexts'][] = 'url.query_args'; return $form; @@ -110,23 +107,23 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function validateForm(array &$form, FormStateInterface $form_state) { $name = trim($form_state->getValue('name')); // Try to load by email. - $users = $this->userStorage->loadByProperties(array('mail' => $name)); + $users = $this->userStorage->loadByProperties(['mail' => $name]); if (empty($users)) { // No success, try to load by name. - $users = $this->userStorage->loadByProperties(array('name' => $name)); + $users = $this->userStorage->loadByProperties(['name' => $name]); } $account = reset($users); if ($account && $account->id()) { // Blocked accounts cannot request a new password. if (!$account->isActive()) { - $form_state->setErrorByName('name', $this->t('%name is blocked or has not been activated yet.', array('%name' => $name))); + $form_state->setErrorByName('name', $this->t('%name is blocked or has not been activated yet.', ['%name' => $name])); } else { - $form_state->setValueForElement(array('#parents' => array('account')), $account); + $form_state->setValueForElement(['#parents' => ['account']], $account); } } else { - $form_state->setErrorByName('name', $this->t('%name is not recognized as a username or an email address.', array('%name' => $name))); + $form_state->setErrorByName('name', $this->t('%name is not recognized as a username or an email address.', ['%name' => $name])); } } @@ -140,7 +137,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Mail one time login URL and instructions using current language. $mail = _user_mail_notify('password_reset', $account, $langcode); if (!empty($mail)) { - $this->logger('user')->notice('Password reset instructions mailed to %name at %email.', array('%name' => $account->getUsername(), '%email' => $account->getEmail())); + $this->logger('user')->notice('Password reset instructions mailed to %name at %email.', ['%name' => $account->getUsername(), '%email' => $account->getEmail()]); drupal_set_message($this->t('Further instructions have been sent to your email address.')); } diff --git a/core/modules/user/src/Form/UserPasswordResetForm.php b/core/modules/user/src/Form/UserPasswordResetForm.php index 1372415c..ce8c7cca 100644 --- a/core/modules/user/src/Form/UserPasswordResetForm.php +++ b/core/modules/user/src/Form/UserPasswordResetForm.php @@ -38,21 +38,21 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state, AccountInterface $user = NULL, $expiration_date = NULL, $timestamp = NULL, $hash = NULL) { if ($expiration_date) { - $form['message'] = array('#markup' => $this->t('

          This is a one-time login for %user_name and will expire on %expiration_date.

          Click on this button to log in to the site and change your password.

          ', array('%user_name' => $user->getUsername(), '%expiration_date' => $expiration_date))); + $form['message'] = ['#markup' => $this->t('

          This is a one-time login for %user_name and will expire on %expiration_date.

          Click on this button to log in to the site and change your password.

          ', ['%user_name' => $user->getUsername(), '%expiration_date' => $expiration_date])]; $form['#title'] = $this->t('Reset password'); } else { // No expiration for first time login. - $form['message'] = array('#markup' => $this->t('

          This is a one-time login for %user_name.

          Click on this button to log in to the site and change your password.

          ', array('%user_name' => $user->getUsername()))); + $form['message'] = ['#markup' => $this->t('

          This is a one-time login for %user_name.

          Click on this button to log in to the site and change your password.

          ', ['%user_name' => $user->getUsername()])]; $form['#title'] = $this->t('Set password'); } - $form['help'] = array('#markup' => '

          ' . $this->t('This login can be used only once.') . '

          '); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['help'] = ['#markup' => '

          ' . $this->t('This login can be used only once.') . '

          ']; + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Log in'), - ); + ]; $form['#action'] = Url::fromRoute('user.reset.login', [ 'uid' => $user->id(), 'timestamp' => $timestamp, diff --git a/core/modules/user/src/Form/UserPermissionsForm.php b/core/modules/user/src/Form/UserPermissionsForm.php index 75bbaf23..26f26c92 100644 --- a/core/modules/user/src/Form/UserPermissionsForm.php +++ b/core/modules/user/src/Form/UserPermissionsForm.php @@ -83,9 +83,9 @@ protected function getRoles() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $role_names = array(); - $role_permissions = array(); - $admin_roles = array(); + $role_names = []; + $role_permissions = []; + $admin_roles = []; foreach ($this->getRoles() as $role_name => $role) { // Retrieve role names for columns. $role_names[$role_name] = $role->label(); @@ -95,79 +95,81 @@ public function buildForm(array $form, FormStateInterface $form_state) { } // Store $role_names for use when saving the data. - $form['role_names'] = array( + $form['role_names'] = [ '#type' => 'value', '#value' => $role_names, - ); + ]; // Render role/permission overview: $hide_descriptions = system_admin_compact_mode(); - $form['system_compact_link'] = array( + $form['system_compact_link'] = [ '#id' => FALSE, '#type' => 'system_compact_link', - ); + ]; - $form['permissions'] = array( + $form['permissions'] = [ '#type' => 'table', - '#header' => array($this->t('Permission')), + '#header' => [$this->t('Permission')], '#id' => 'permissions', '#attributes' => ['class' => ['permissions', 'js-permissions']], '#sticky' => TRUE, - ); + ]; foreach ($role_names as $name) { - $form['permissions']['#header'][] = array( + $form['permissions']['#header'][] = [ 'data' => $name, - 'class' => array('checkbox'), - ); + 'class' => ['checkbox'], + ]; } $permissions = $this->permissionHandler->getPermissions(); - $permissions_by_provider = array(); + $permissions_by_provider = []; foreach ($permissions as $permission_name => $permission) { $permissions_by_provider[$permission['provider']][$permission_name] = $permission; } foreach ($permissions_by_provider as $provider => $permissions) { // Module name. - $form['permissions'][$provider] = array(array( - '#wrapper_attributes' => array( - 'colspan' => count($role_names) + 1, - 'class' => array('module'), - 'id' => 'module-' . $provider, - ), - '#markup' => $this->moduleHandler->getName($provider), - )); + $form['permissions'][$provider] = [ + [ + '#wrapper_attributes' => [ + 'colspan' => count($role_names) + 1, + 'class' => ['module'], + 'id' => 'module-' . $provider, + ], + '#markup' => $this->moduleHandler->getName($provider), + ], + ]; foreach ($permissions as $perm => $perm_item) { // Fill in default values for the permission. - $perm_item += array( + $perm_item += [ 'description' => '', 'restrict access' => FALSE, 'warning' => !empty($perm_item['restrict access']) ? $this->t('Warning: Give to trusted roles only; this permission has security implications.') : '', - ); - $form['permissions'][$perm]['description'] = array( + ]; + $form['permissions'][$perm]['description'] = [ '#type' => 'inline_template', '#template' => '
          {{ title }}{% if description or warning %}
          {% if warning %}{{ warning }} {% endif %}{{ description }}
          {% endif %}
          ', - '#context' => array( + '#context' => [ 'title' => $perm_item['title'], - ), - ); + ], + ]; // Show the permission description. if (!$hide_descriptions) { $form['permissions'][$perm]['description']['#context']['description'] = $perm_item['description']; $form['permissions'][$perm]['description']['#context']['warning'] = $perm_item['warning']; } foreach ($role_names as $rid => $name) { - $form['permissions'][$perm][$rid] = array( + $form['permissions'][$perm][$rid] = [ '#title' => $name . ': ' . $perm_item['title'], '#title_display' => 'invisible', - '#wrapper_attributes' => array( - 'class' => array('checkbox'), - ), + '#wrapper_attributes' => [ + 'class' => ['checkbox'], + ], '#type' => 'checkbox', '#default_value' => in_array($perm, $role_permissions[$rid]) ? 1 : 0, - '#attributes' => array('class' => array('rid-' . $rid, 'js-rid-' . $rid)), - '#parents' => array($rid, $perm), - ); + '#attributes' => ['class' => ['rid-' . $rid, 'js-rid-' . $rid]], + '#parents' => [$rid, $perm], + ]; // Show a column of disabled but checked checkboxes. if ($admin_roles[$rid]) { $form['permissions'][$perm][$rid]['#disabled'] = TRUE; @@ -177,12 +179,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { } } - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save permissions'), '#button_type' => 'primary', - ); + ]; $form['#attached']['library'][] = 'user/drupal.user.permissions'; @@ -192,7 +194,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - function submitForm(array &$form, FormStateInterface $form_state) { + public function submitForm(array &$form, FormStateInterface $form_state) { foreach ($form_state->getValue('role_names') as $role_name => $name) { user_role_change_permissions($role_name, (array) $form_state->getValue($role_name)); } diff --git a/core/modules/user/src/Form/UserPermissionsRoleSpecificForm.php b/core/modules/user/src/Form/UserPermissionsRoleSpecificForm.php index 41ae8b87..b8caf7bb 100644 --- a/core/modules/user/src/Form/UserPermissionsRoleSpecificForm.php +++ b/core/modules/user/src/Form/UserPermissionsRoleSpecificForm.php @@ -21,14 +21,18 @@ class UserPermissionsRoleSpecificForm extends UserPermissionsForm { * {@inheritdoc} */ protected function getRoles() { - return array($this->userRole->id() => $this->userRole); + return [$this->userRole->id() => $this->userRole]; } /** - * {@inheritdoc} + * Builds the user permissions administration form for a specific role. * - * @param string $role_id - * The user role ID used for this form. + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * @param \Drupal\user\RoleInterface|null $user_role + * (optional) The user role used for this form. Defaults to NULL. */ public function buildForm(array $form, FormStateInterface $form_state, RoleInterface $user_role = NULL) { $this->userRole = $user_role; diff --git a/core/modules/user/src/PermissionHandler.php b/core/modules/user/src/PermissionHandler.php index d7179b65..1f07b25d 100644 --- a/core/modules/user/src/PermissionHandler.php +++ b/core/modules/user/src/PermissionHandler.php @@ -136,8 +136,8 @@ public function moduleProvidesPermissions($module_name) { * - provider: The provider of the permission. */ protected function buildPermissionsYaml() { - $all_permissions = array(); - $all_callback_permissions = array(); + $all_permissions = []; + $all_callback_permissions = []; foreach ($this->getYamlDiscovery()->findAll() as $provider => $permissions) { // The top-level 'permissions_callback' is a list of methods in controller @@ -151,15 +151,15 @@ protected function buildPermissionsYaml() { // defaults can then get processed below. foreach ($callback_permissions as $name => $callback_permission) { if (!is_array($callback_permission)) { - $callback_permission = array( + $callback_permission = [ 'title' => $callback_permission, - ); + ]; } - $callback_permission += array( + $callback_permission += [ 'description' => NULL, 'provider' => $provider, - ); + ]; $all_callback_permissions[$name] = $callback_permission; } @@ -171,9 +171,9 @@ protected function buildPermissionsYaml() { foreach ($permissions as &$permission) { if (!is_array($permission)) { - $permission = array( + $permission = [ 'title' => $permission, - ); + ]; } $permission['title'] = $this->t($permission['title']); $permission['description'] = isset($permission['description']) ? $this->t($permission['description']) : NULL; @@ -198,7 +198,7 @@ protected function buildPermissionsYaml() { * - description: The description of the permission, defaults to NULL. * - provider: The provider of the permission. */ - protected function sortPermissions(array $all_permissions = array()) { + protected function sortPermissions(array $all_permissions = []) { // Get a list of all the modules providing permissions and sort by // display name. $modules = $this->getModuleNames(); @@ -221,7 +221,7 @@ protected function sortPermissions(array $all_permissions = array()) { * Returns the human readable names of all modules keyed by machine name. */ protected function getModuleNames() { - $modules = array(); + $modules = []; foreach (array_keys($this->moduleHandler->getModuleList()) as $module) { $modules[$module] = $this->moduleHandler->getName($module); } diff --git a/core/modules/user/src/Plugin/Action/CancelUser.php b/core/modules/user/src/Plugin/Action/CancelUser.php index 7c51f5fe..140ef42e 100644 --- a/core/modules/user/src/Plugin/Action/CancelUser.php +++ b/core/modules/user/src/Plugin/Action/CancelUser.php @@ -79,7 +79,7 @@ public function executeMultiple(array $entities) { * {@inheritdoc} */ public function execute($object = NULL) { - $this->executeMultiple(array($object)); + $this->executeMultiple([$object]); } /** diff --git a/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php b/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php index 02424bc3..de4c4040 100644 --- a/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php +++ b/core/modules/user/src/Plugin/Action/ChangeUserRoleBase.php @@ -49,9 +49,9 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'rid' => '', - ); + ]; } /** @@ -60,13 +60,13 @@ public function defaultConfiguration() { public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $roles = user_role_names(TRUE); unset($roles[RoleInterface::AUTHENTICATED_ID]); - $form['rid'] = array( + $form['rid'] = [ '#type' => 'radios', '#title' => t('Role'), '#options' => $roles, '#default_value' => $this->configuration['rid'], '#required' => TRUE, - ); + ]; return $form; } diff --git a/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/core/modules/user/src/Plugin/Block/UserLoginBlock.php index 34957c90..a9341f9b 100644 --- a/core/modules/user/src/Plugin/Block/UserLoginBlock.php +++ b/core/modules/user/src/Plugin/Block/UserLoginBlock.php @@ -6,7 +6,6 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Routing\RedirectDestinationTrait; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Routing\UrlGeneratorTrait; use Drupal\Core\Url; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Block\BlockBase; @@ -23,7 +22,6 @@ */ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface { - use UrlGeneratorTrait; use RedirectDestinationTrait; /** @@ -72,7 +70,7 @@ public static function create(ContainerInterface $container, array $configuratio */ protected function blockAccess(AccountInterface $account) { $route_name = $this->routeMatch->getRouteName(); - if ($account->isAnonymous() && !in_array($route_name, array('user.login', 'user.logout'))) { + if ($account->isAnonymous() && !in_array($route_name, ['user.login', 'user.logout'])) { return AccessResult::allowed() ->addCacheContexts(['route.name', 'user.roles:anonymous']); } @@ -94,30 +92,71 @@ public function build() { unset($form['pass']['#attributes']['aria-describedby']); $form['name']['#size'] = 15; $form['pass']['#size'] = 15; - $form['#action'] = $this->url('', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]); + + // Instead of setting an actual action URL, we set the placeholder, which + // will be replaced at the very last moment. This ensures forms with + // dynamically generated action URLs don't have poor cacheability. + // Use the proper API to generate the placeholder, when we have one. See + // https://www.drupal.org/node/2562341. The placholder uses a fixed string + // that is + // Crypt::hashBase64('\Drupal\user\Plugin\Block\UserLoginBlock::build'); + // This is based on the implementation in + // \Drupal\Core\Form\FormBuilder::prepareForm(), but the user login block + // requires different behavior for the destination query argument. + $placeholder = 'form_action_p_4r8ITd22yaUvXM6SzwrSe9rnQWe48hz9k1Sxto3pBvE'; + + $form['#attached']['placeholders'][$placeholder] = [ + '#lazy_builder' => ['\Drupal\user\Plugin\Block\UserLoginBlock::renderPlaceholderFormAction', []], + ]; + $form['#action'] = $placeholder; + // Build action links. - $items = array(); + $items = []; if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) { - $items['create_account'] = \Drupal::l($this->t('Create new account'), new Url('user.register', array(), array( - 'attributes' => array( - 'title' => $this->t('Create a new user account.'), - 'class' => array('create-account-link'), - ), - ))); + $items['create_account'] = [ + '#type' => 'link', + '#title' => $this->t('Create new account'), + '#url' => Url::fromRoute('user.register', [], [ + 'attributes' => [ + 'title' => $this->t('Create a new user account.'), + 'class' => ['create-account-link'], + ], + ]), + ]; } - $items['request_password'] = \Drupal::l($this->t('Reset your password'), new Url('user.pass', array(), array( - 'attributes' => array( - 'title' => $this->t('Send password reset instructions via email.'), - 'class' => array('request-password-link'), - ), - ))); - return array( + $items['request_password'] = [ + '#type' => 'link', + '#title' => $this->t('Reset your password'), + '#url' => Url::fromRoute('user.pass', [], [ + 'attributes' => [ + 'title' => $this->t('Send password reset instructions via email.'), + 'class' => ['request-password-link'], + ], + ]), + ]; + return [ 'user_login_form' => $form, - 'user_links' => array( + 'user_links' => [ '#theme' => 'item_list', '#items' => $items, - ), - ); + ], + ]; + } + + /** + * #lazy_builder callback; renders a form action URL including destination. + * + * @return array + * A renderable array representing the form action. + * + * @see \Drupal\Core\Form\FormBuilder::renderPlaceholderFormAction() + */ + public static function renderPlaceholderFormAction() { + return [ + '#type' => 'markup', + '#markup' => Url::fromRoute('', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(), + '#cache' => ['contexts' => ['url.path', 'url.query_args']], + ]; } } diff --git a/core/modules/user/src/Plugin/Condition/UserRole.php b/core/modules/user/src/Plugin/Condition/UserRole.php index ea69e143..60b8b0e2 100644 --- a/core/modules/user/src/Plugin/Condition/UserRole.php +++ b/core/modules/user/src/Plugin/Condition/UserRole.php @@ -22,13 +22,13 @@ class UserRole extends ConditionPluginBase { * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $form['roles'] = array( + $form['roles'] = [ '#type' => 'checkboxes', '#title' => $this->t('When the user has the following roles'), '#default_value' => $this->configuration['roles'], '#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()), '#description' => $this->t('If you select no roles, the condition will evaluate to TRUE for all users.'), - ); + ]; return parent::buildConfigurationForm($form, $form_state); } @@ -36,9 +36,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function defaultConfiguration() { - return array( - 'roles' => array(), - ) + parent::defaultConfiguration(); + return [ + 'roles' => [], + ] + parent::defaultConfiguration(); } /** @@ -62,10 +62,10 @@ public function summary() { $roles = reset($roles); } if (!empty($this->configuration['negate'])) { - return $this->t('The user is not a member of @roles', array('@roles' => $roles)); + return $this->t('The user is not a member of @roles', ['@roles' => $roles]); } else { - return $this->t('The user is a member of @roles', array('@roles' => $roles)); + return $this->t('The user is a member of @roles', ['@roles' => $roles]); } } diff --git a/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php index 8dfba396..d06a81c4 100644 --- a/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php +++ b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php @@ -3,6 +3,7 @@ namespace Drupal\user\Plugin\EntityReferenceSelection; use Drupal\Core\Database\Connection; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection; @@ -82,55 +83,55 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $selection_handler_settings = $this->configuration['handler_settings']; - - // Merge in default values. - $selection_handler_settings += array( - 'filter' => array( + public function defaultConfiguration() { + return [ + 'filter' => [ 'type' => '_none', - ), + 'role' => NULL, + ], 'include_anonymous' => TRUE, - ); + ] + parent::defaultConfiguration(); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $configuration = $this->getConfiguration(); - $form['include_anonymous'] = array( + $form['include_anonymous'] = [ '#type' => 'checkbox', '#title' => $this->t('Include the anonymous user.'), - '#default_value' => $selection_handler_settings['include_anonymous'], - ); + '#default_value' => $configuration['include_anonymous'], + ]; // Add user specific filter options. - $form['filter']['type'] = array( + $form['filter']['type'] = [ '#type' => 'select', '#title' => $this->t('Filter by'), - '#options' => array( + '#options' => [ '_none' => $this->t('- None -'), 'role' => $this->t('User role'), - ), + ], '#ajax' => TRUE, - '#limit_validation_errors' => array(), - '#default_value' => $selection_handler_settings['filter']['type'], - ); + '#limit_validation_errors' => [], + '#default_value' => $configuration['filter']['type'], + ]; - $form['filter']['settings'] = array( + $form['filter']['settings'] = [ '#type' => 'container', - '#attributes' => array('class' => array('entity_reference-settings')), - '#process' => array(array('\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent')), - ); + '#attributes' => ['class' => ['entity_reference-settings']], + '#process' => [['\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem', 'formProcessMergeParent']], + ]; - if ($selection_handler_settings['filter']['type'] == 'role') { - // Merge in default values. - $selection_handler_settings['filter'] += array( - 'role' => NULL, - ); - - $form['filter']['settings']['role'] = array( + if ($configuration['filter']['type'] == 'role') { + $form['filter']['settings']['role'] = [ '#type' => 'checkboxes', '#title' => $this->t('Restrict to the selected roles'), '#required' => TRUE, - '#options' => array_diff_key(user_role_names(TRUE), array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)), - '#default_value' => $selection_handler_settings['filter']['role'], - ); + '#options' => array_diff_key(user_role_names(TRUE), [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]), + '#default_value' => $configuration['filter']['role'], + ]; } $form += parent::buildConfigurationForm($form, $form_state); @@ -143,11 +144,12 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') { $query = parent::buildEntityQuery($match, $match_operator); - $handler_settings = $this->configuration['handler_settings']; + + $configuration = $this->getConfiguration(); // Filter out the Anonymous user if the selection handler is configured to // exclude it. - if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) { + if (!$configuration['include_anonymous']) { $query->condition('uid', 0, '<>'); } @@ -157,8 +159,8 @@ protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') } // Filter by role. - if (!empty($handler_settings['filter']['role'])) { - $query->condition('roles', $handler_settings['filter']['role'], 'IN'); + if (!empty($configuration['filter']['role'])) { + $query->condition('roles', $configuration['filter']['role'], 'IN'); } // Adding the permission check is sadly insufficient for users: core @@ -190,10 +192,10 @@ public function createNewEntity($entity_type_id, $bundle, $label, $uid) { public function validateReferenceableNewEntities(array $entities) { $entities = parent::validateReferenceableNewEntities($entities); // Mirror the conditions checked in buildEntityQuery(). - if (!empty($this->configuration['handler_settings']['filter']['role'])) { - $entities = array_filter($entities, function ($user) { + if ($role = $this->getConfiguration()['filter']['role']) { + $entities = array_filter($entities, function ($user) use ($role) { /** @var \Drupal\user\UserInterface $user */ - return !empty(array_intersect($user->getRoles(), $this->configuration['handler_settings']['filter']['role'])); + return !empty(array_intersect($user->getRoles(), $role)); }); } if (!$this->currentUser->hasPermission('administer users')) { @@ -209,9 +211,10 @@ public function validateReferenceableNewEntities(array $entities) { * {@inheritdoc} */ public function entityQueryAlter(SelectInterface $query) { + parent::entityQueryAlter($query); + // Bail out early if we do not need to match the Anonymous user. - $handler_settings = $this->configuration['handler_settings']; - if (isset($handler_settings['include_anonymous']) && !$handler_settings['include_anonymous']) { + if (!$this->getConfiguration()['include_anonymous']) { return; } @@ -228,18 +231,18 @@ public function entityQueryAlter(SelectInterface $query) { // Re-add the condition and a condition on uid = 0 so that we end up // with a query in the form: // WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0) - $or = db_or(); + $or = new Condition('OR'); $or->condition($condition['field'], $condition['value'], $condition['operator']); // Sadly, the Database layer doesn't allow us to build a condition // in the form ':placeholder = :placeholder2', because the 'field' // part of a condition is always escaped. // As a (cheap) workaround, we separately build a condition with no // field, and concatenate the field and the condition separately. - $value_part = db_and(); + $value_part = new Condition('AND'); $value_part->condition('anonymous_name', $condition['value'], $condition['operator']); $value_part->compile($this->connection, $query); - $or->condition(db_and() - ->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => \Drupal::config('user.settings')->get('anonymous'))) + $or->condition((new Condition('AND')) + ->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + [':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')]) ->condition('base_table.uid', 0) ); $query->condition($or); diff --git a/core/modules/user/src/Plugin/Field/FieldFormatter/AuthorFormatter.php b/core/modules/user/src/Plugin/Field/FieldFormatter/AuthorFormatter.php index df97a798..9f74d67d 100644 --- a/core/modules/user/src/Plugin/Field/FieldFormatter/AuthorFormatter.php +++ b/core/modules/user/src/Plugin/Field/FieldFormatter/AuthorFormatter.php @@ -2,7 +2,6 @@ namespace Drupal\user\Plugin\Field\FieldFormatter; -use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; @@ -26,18 +25,18 @@ class AuthorFormatter extends EntityReferenceFormatterBase { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $elements = array(); + $elements = []; foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) { /** @var $referenced_user \Drupal\user\UserInterface */ - $elements[$delta] = array( + $elements[$delta] = [ '#theme' => 'username', '#account' => $entity, - '#link_options' => array('attributes' => array('rel' => 'author')), - '#cache' => array( + '#link_options' => ['attributes' => ['rel' => 'author']], + '#cache' => [ 'tags' => $entity->getCacheTags(), - ), - ); + ], + ]; } return $elements; @@ -54,9 +53,7 @@ public static function isApplicable(FieldDefinitionInterface $field_definition) * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity) { - // Always allow an entity author's username to be read, even if the current - // user does not have permission to view the entity author's profile. - return AccessResult::allowed(); + return $entity->access('view label', NULL, TRUE); } } diff --git a/core/modules/user/src/Plugin/Search/UserSearch.php b/core/modules/user/src/Plugin/Search/UserSearch.php index f8471211..ca4820ca 100644 --- a/core/modules/user/src/Plugin/Search/UserSearch.php +++ b/core/modules/user/src/Plugin/Search/UserSearch.php @@ -52,7 +52,7 @@ class UserSearch extends SearchPluginBase implements AccessibleInterface { /** * {@inheritdoc} */ - static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $container->get('database'), $container->get('entity.manager'), @@ -104,7 +104,7 @@ public function access($operation = 'view', AccountInterface $account = NULL, $r * {@inheritdoc} */ public function execute() { - $results = array(); + $results = []; if (!$this->isSearchExecutable()) { return $results; } @@ -120,12 +120,12 @@ public function execute() { $query = $this->database ->select('users_field_data', 'users') ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); - $query->fields('users', array('uid')); + $query->fields('users', ['uid']); $query->condition('default_langcode', 1); if ($this->currentUser->hasPermission('administer users')) { // Administrators can also search in the otherwise private email field, // and they don't need to be restricted to only active users. - $query->fields('users', array('mail')); + $query->fields('users', ['mail']); $query->condition($query->orConditionGroup() ->condition('name', '%' . $keys . '%', 'LIKE') ->condition('mail', '%' . $keys . '%', 'LIKE') @@ -144,10 +144,10 @@ public function execute() { $accounts = $this->entityManager->getStorage('user')->loadMultiple($uids); foreach ($accounts as $account) { - $result = array( + $result = [ 'title' => $account->getDisplayName(), - 'link' => $account->url('canonical', array('absolute' => TRUE)), - ); + 'link' => $account->url('canonical', ['absolute' => TRUE]), + ]; if ($this->currentUser->hasPermission('administer users')) { $result['title'] .= ' (' . $account->getEmail() . ')'; } @@ -162,13 +162,15 @@ public function execute() { * {@inheritdoc} */ public function getHelp() { - $help = array('list' => array( - '#theme' => 'item_list', - '#items' => array( - $this->t('User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.'), - $this->t('You can use * as a wildcard within your keyword. Example: m*r would match user names mar, delmar, and elementary.'), - ), - )); + $help = [ + 'list' => [ + '#theme' => 'item_list', + '#items' => [ + $this->t('User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.'), + $this->t('You can use * as a wildcard within your keyword. Example: m*r would match user names mar, delmar, and elementary.'), + ], + ], + ]; return $help; } diff --git a/core/modules/user/src/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidator.php b/core/modules/user/src/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidator.php index 2bfdca4c..a8b12af8 100644 --- a/core/modules/user/src/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidator.php +++ b/core/modules/user/src/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidator.php @@ -86,7 +86,7 @@ public function validate($items, Constraint $constraint) { $changed = $items->getValue() != $account_unchanged->get($field->getName())->getValue(); } if ($changed && (!$account->checkExistingPassword($account_unchanged))) { - $this->context->addViolation($constraint->message, array('%name' => $field->getLabel())); + $this->context->addViolation($constraint->message, ['%name' => $field->getLabel()]); } } } diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequired.php b/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequired.php index 5905e121..b500a8d9 100644 --- a/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequired.php +++ b/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequired.php @@ -3,8 +3,6 @@ namespace Drupal\user\Plugin\Validation\Constraint; use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidatorInterface; -use Symfony\Component\Validator\ExecutionContextInterface; /** * Checks if the user's email address is provided if required. @@ -18,7 +16,7 @@ * label = @Translation("User email required", context = "Validation") * ) */ -class UserMailRequired extends Constraint implements ConstraintValidatorInterface { +class UserMailRequired extends Constraint { /** * Violation message. Use the same message as FormValidator. @@ -30,45 +28,4 @@ class UserMailRequired extends Constraint implements ConstraintValidatorInterfac */ public $message = '@name field is required.'; - /** - * @var \Symfony\Component\Validator\ExecutionContextInterface - */ - protected $context; - - /** - * {@inheritdoc} - */ - public function initialize(ExecutionContextInterface $context) { - $this->context = $context; - } - - /** - * {@inheritdoc} - */ - public function validatedBy() { - return get_class($this); - } - - /** - * {@inheritdoc} - */ - public function validate($items, Constraint $constraint) { - /** @var \Drupal\Core\Field\FieldItemListInterface $items */ - /** @var \Drupal\user\UserInterface $account */ - $account = $items->getEntity(); - $existing_value = NULL; - if ($account->id()) { - $account_unchanged = \Drupal::entityManager() - ->getStorage('user') - ->loadUnchanged($account->id()); - $existing_value = $account_unchanged->getEmail(); - } - - $required = !(!$existing_value && \Drupal::currentUser()->hasPermission('administer users')); - - if ($required && (!isset($items) || $items->isEmpty())) { - $this->context->addViolation($this->message, ['@name' => $account->getFieldDefinition('mail')->getLabel()]); - } - } - } diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequiredValidator.php b/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequiredValidator.php new file mode 100644 index 00000000..7e20b7a8 --- /dev/null +++ b/core/modules/user/src/Plugin/Validation/Constraint/UserMailRequiredValidator.php @@ -0,0 +1,39 @@ +getEntity(); + $existing_value = NULL; + if ($account->id()) { + $account_unchanged = \Drupal::entityManager() + ->getStorage('user') + ->loadUnchanged($account->id()); + $existing_value = $account_unchanged->getEmail(); + } + + $required = !(!$existing_value && \Drupal::currentUser()->hasPermission('administer users')); + + if ($required && (!isset($items) || $items->isEmpty())) { + $this->context->addViolation($constraint->message, ['@name' => $account->getFieldDefinition('mail')->getLabel()]); + } + } + +} diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php b/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php index fa714646..9e4776bd 100644 --- a/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php +++ b/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php @@ -54,7 +54,7 @@ public function validate($items, Constraint $constraint) { $this->context->addViolation($constraint->illegalMessage); } if (Unicode::strlen($name) > USERNAME_MAX_LENGTH) { - $this->context->addViolation($constraint->tooLongMessage, array('%name' => $name, '%max' => USERNAME_MAX_LENGTH)); + $this->context->addViolation($constraint->tooLongMessage, ['%name' => $name, '%max' => USERNAME_MAX_LENGTH]); } } diff --git a/core/modules/user/src/Plugin/migrate/User.php b/core/modules/user/src/Plugin/migrate/User.php index d89787c5..0605443f 100644 --- a/core/modules/user/src/Plugin/migrate/User.php +++ b/core/modules/user/src/Plugin/migrate/User.php @@ -3,12 +3,12 @@ namespace Drupal\user\Plugin\migrate; use Drupal\migrate\Exception\RequirementsException; -use Drupal\migrate_drupal\Plugin\migrate\CckMigration; +use Drupal\migrate_drupal\Plugin\migrate\FieldMigration; /** * Plugin class for Drupal 7 user migrations dealing with fields and profiles. */ -class User extends CckMigration { +class User extends FieldMigration { /** * {@inheritdoc} @@ -30,16 +30,26 @@ public function getProcess() { if (empty($field_type)) { continue; } - if ($this->cckPluginManager->hasDefinition($field_type)) { - if (!isset($this->cckPluginCache[$field_type])) { - $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $this); + if ($this->fieldPluginManager->hasDefinition($field_type)) { + if (!isset($this->fieldPluginCache[$field_type])) { + $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($field_type, [], $this); } $info = $row->getSource(); - $this->cckPluginCache[$field_type] - ->processCckFieldValues($this, $field_name, $info); + $this->fieldPluginCache[$field_type] + ->processFieldValues($this, $field_name, $info); } else { - $this->process[$field_name] = $field_name; + if ($this->cckPluginManager->hasDefinition($field_type)) { + if (!isset($this->cckPluginCache[$field_type])) { + $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $this); + } + $info = $row->getSource(); + $this->cckPluginCache[$field_type] + ->processCckFieldValues($this, $field_name, $info); + } + else { + $this->process[$field_name] = $field_name; + } } } } diff --git a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php index b11d8670..7c2c81af 100644 --- a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php +++ b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php @@ -77,7 +77,7 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} * @throws \Drupal\migrate\MigrateException */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { // Do not overwrite the root account password. if ($row->getDestinationProperty('uid') == 1) { $row->removeDestinationProperty('pass'); @@ -88,7 +88,7 @@ public function import(Row $row, array $old_destination_id_values = array()) { /** * {@inheritdoc} */ - protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) { + protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) { // Do not overwrite the root account password. if ($entity->id() != 1) { // Set the pre_hashed password so that the PasswordItem field does not hash diff --git a/core/modules/user/src/Plugin/migrate/destination/UserData.php b/core/modules/user/src/Plugin/migrate/destination/UserData.php index 6ca60179..7c48f93e 100644 --- a/core/modules/user/src/Plugin/migrate/destination/UserData.php +++ b/core/modules/user/src/Plugin/migrate/destination/UserData.php @@ -56,7 +56,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { $uid = $row->getDestinationProperty('uid'); $module = $row->getDestinationProperty('module'); $key = $row->getDestinationProperty('key'); diff --git a/core/modules/user/src/Plugin/migrate/process/ConvertTokens.php b/core/modules/user/src/Plugin/migrate/process/ConvertTokens.php index ce93c0e7..ed95db27 100644 --- a/core/modules/user/src/Plugin/migrate/process/ConvertTokens.php +++ b/core/modules/user/src/Plugin/migrate/process/ConvertTokens.php @@ -21,7 +21,7 @@ class ConvertTokens extends ProcessPluginBase { * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $tokens = array( + $tokens = [ '!site' => '[site:name]', '!username' => '[user:name]', '!mailto' => '[user:mail]', @@ -32,7 +32,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable '!uri' => '[site:url]', '!date' => '[date:medium]', '!password' => '', - ); + ]; // Given that our source is a database column that could hold a NULL // value, sometimes that filters down to here. str_replace() cannot diff --git a/core/modules/user/src/Plugin/migrate/process/ProfileFieldSettings.php b/core/modules/user/src/Plugin/migrate/process/ProfileFieldSettings.php index 6230f7b7..6e16c59d 100644 --- a/core/modules/user/src/Plugin/migrate/process/ProfileFieldSettings.php +++ b/core/modules/user/src/Plugin/migrate/process/ProfileFieldSettings.php @@ -17,7 +17,7 @@ class ProfileFieldSettings extends ProcessPluginBase { * {@inheritdoc} */ public function transform($type, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $settings = array(); + $settings = []; switch ($type) { case 'date': $settings['datetime_type'] = 'date'; diff --git a/core/modules/user/src/Plugin/migrate/process/UserUpdate8002.php b/core/modules/user/src/Plugin/migrate/process/UserUpdate8002.php index 36f65741..7a67c466 100644 --- a/core/modules/user/src/Plugin/migrate/process/UserUpdate8002.php +++ b/core/modules/user/src/Plugin/migrate/process/UserUpdate8002.php @@ -22,10 +22,10 @@ class UserUpdate8002 extends ProcessPluginBase { */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { $rid = $row->getSourceProperty('rid'); - $map = array( + $map = [ 1 => 'anonymous', 2 => 'authenticated', - ); + ]; return isset($map[$rid]) ? $map[$rid] : $value; } diff --git a/core/modules/user/src/Plugin/migrate/source/ProfileField.php b/core/modules/user/src/Plugin/migrate/source/ProfileField.php index c2a6fe44..93a0430d 100644 --- a/core/modules/user/src/Plugin/migrate/source/ProfileField.php +++ b/core/modules/user/src/Plugin/migrate/source/ProfileField.php @@ -10,7 +10,7 @@ * * @MigrateSource( * id = "profile_field", - * source_provider = "profile" + * source_module = "profile" * ) */ class ProfileField extends DrupalSqlBase { @@ -70,7 +70,7 @@ public function prepareRow(Row $row) { // D6 profile checkboxes values are always 0 or 1 (with no labels), so we // need to create two label-less options that will get 0 and 1 for their // keys. - $row->setSourceProperty('options', array(NULL, NULL)); + $row->setSourceProperty('options', [NULL, NULL]); } return parent::prepareRow($row); @@ -80,7 +80,7 @@ public function prepareRow(Row $row) { * {@inheritdoc} */ public function fields() { - return array( + return [ 'fid' => $this->t('Primary Key: Unique profile field ID.'), 'title' => $this->t('Title of the field shown to the end user.'), 'name' => $this->t('Internal name of the field used in the form HTML and URLs.'), @@ -94,7 +94,7 @@ public function fields() { 'visibility' => $this->t('The level of visibility for the field. (0 = hidden, 1 = private, 2 = public on profile but not member list pages, 3 = public on profile and list pages)'), 'autocomplete' => $this->t('Whether form auto-completion is enabled. (0 = disabled, 1 = enabled)'), 'options' => $this->t('List of options to be used in a list selection field.'), - ); + ]; } /** diff --git a/core/modules/user/src/Plugin/migrate/source/UserPictureInstance.php b/core/modules/user/src/Plugin/migrate/source/UserPictureInstance.php index 746a76fd..b7013bae 100644 --- a/core/modules/user/src/Plugin/migrate/source/UserPictureInstance.php +++ b/core/modules/user/src/Plugin/migrate/source/UserPictureInstance.php @@ -11,7 +11,8 @@ * @todo Support default picture? * * @MigrateSource( - * id = "user_picture_instance" + * id = "user_picture_instance", + * source_module = "user" * ) */ class UserPictureInstance extends DrupalSqlBase { @@ -22,24 +23,25 @@ class UserPictureInstance extends DrupalSqlBase { * {@inheritdoc} */ public function initializeIterator() { - return new \ArrayIterator(array( - array( + return new \ArrayIterator([ + [ 'id' => '', 'file_directory' => $this->variableGet('user_picture_path', 'pictures'), 'max_filesize' => $this->variableGet('user_picture_file_size', '30') . 'KB', 'max_resolution' => $this->variableGet('user_picture_dimensions', '85x85'), - ))); + ], + ]); } /** * {@inheritdoc} */ public function fields() { - return array( + return [ 'file_directory' => 'The directory to store images..', 'max_filesize' => 'The maximum allowed file size in KBs.', 'max_resolution' => "The maximum resolution.", - ); + ]; } /** diff --git a/core/modules/user/src/Plugin/migrate/source/d6/ProfileFieldValues.php b/core/modules/user/src/Plugin/migrate/source/d6/ProfileFieldValues.php index 0ccbbeb5..ac492909 100644 --- a/core/modules/user/src/Plugin/migrate/source/d6/ProfileFieldValues.php +++ b/core/modules/user/src/Plugin/migrate/source/d6/ProfileFieldValues.php @@ -10,7 +10,7 @@ * * @MigrateSource( * id = "d6_profile_field_values", - * source_provider = "profile" + * source_module = "profile" * ) */ class ProfileFieldValues extends DrupalSqlBase { @@ -21,7 +21,7 @@ class ProfileFieldValues extends DrupalSqlBase { public function query() { $query = $this->select('profile_values', 'pv') ->distinct() - ->fields('pv', array('uid')); + ->fields('pv', ['uid']); return $query; } @@ -32,9 +32,9 @@ public function query() { public function prepareRow(Row $row) { // Find profile values for this row. $query = $this->select('profile_values', 'pv') - ->fields('pv', array('fid', 'value')); + ->fields('pv', ['fid', 'value']); $query->leftJoin('profile_fields', 'pf', 'pf.fid=pv.fid'); - $query->fields('pf', array('name', 'type')); + $query->fields('pf', ['name', 'type']); $query->condition('uid', $row->getSourceProperty('uid')); $results = $query->execute(); @@ -43,14 +43,14 @@ public function prepareRow(Row $row) { if ($profile_value['type'] == 'date') { $date = unserialize($profile_value['value']); $date = date('Y-m-d', mktime(0, 0, 0, $date['month'], $date['day'], $date['year'])); - $row->setSourceProperty($profile_value['name'], array('value' => $date)); + $row->setSourceProperty($profile_value['name'], ['value' => $date]); } elseif ($profile_value['type'] == 'list') { // Explode by newline and comma. $row->setSourceProperty($profile_value['name'], preg_split("/[\r\n,]+/", $profile_value['value'])); } else { - $row->setSourceProperty($profile_value['name'], array($profile_value['value'])); + $row->setSourceProperty($profile_value['name'], [$profile_value['value']]); } } @@ -61,16 +61,16 @@ public function prepareRow(Row $row) { * {@inheritdoc} */ public function fields() { - $fields = array( + $fields = [ 'fid' => $this->t('Unique profile field ID.'), 'uid' => $this->t('The user Id.'), 'value' => $this->t('The value for this field.'), - ); + ]; $query = $this->select('profile_values', 'pv') - ->fields('pv', array('fid', 'value')); + ->fields('pv', ['fid', 'value']); $query->leftJoin('profile_fields', 'pf', 'pf.fid=pv.fid'); - $query->fields('pf', array('name', 'title')); + $query->fields('pf', ['name', 'title']); $results = $query->execute(); foreach ($results as $profile) { $fields[$profile['name']] = $this->t($profile['title']); @@ -83,12 +83,12 @@ public function fields() { * {@inheritdoc} */ public function getIds() { - return array( - 'uid' => array( + return [ + 'uid' => [ 'type' => 'integer', 'alias' => 'pv', - ), - ); + ], + ]; } } diff --git a/core/modules/user/src/Plugin/migrate/source/d6/Role.php b/core/modules/user/src/Plugin/migrate/source/d6/Role.php index 2357c5c8..a809b07d 100644 --- a/core/modules/user/src/Plugin/migrate/source/d6/Role.php +++ b/core/modules/user/src/Plugin/migrate/source/d6/Role.php @@ -9,7 +9,8 @@ * Drupal 6 role source from database. * * @MigrateSource( - * id = "d6_user_role" + * id = "d6_user_role", + * source_module = "user" * ) */ class Role extends DrupalSqlBase { @@ -19,14 +20,14 @@ class Role extends DrupalSqlBase { * * @var array */ - protected $filterPermissions = array(); + protected $filterPermissions = []; /** * {@inheritdoc} */ public function query() { $query = $this->select('role', 'r') - ->fields('r', array('rid', 'name')) + ->fields('r', ['rid', 'name']) ->orderBy('r.rid'); return $query; } @@ -35,10 +36,10 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'rid' => $this->t('Role ID.'), 'name' => $this->t('The name of the user role.'), - ); + ]; } /** @@ -46,7 +47,7 @@ public function fields() { */ protected function initializeIterator() { $filter_roles = $this->select('filter_formats', 'f') - ->fields('f', array('format', 'roles')) + ->fields('f', ['format', 'roles']) ->execute() ->fetchAllKeyed(); foreach ($filter_roles as $format => $roles) { @@ -65,7 +66,7 @@ protected function initializeIterator() { public function prepareRow(Row $row) { $rid = $row->getSourceProperty('rid'); $permissions = $this->select('permission', 'p') - ->fields('p', array('perm')) + ->fields('p', ['perm']) ->condition('rid', $rid) ->execute() ->fetchField(); diff --git a/core/modules/user/src/Plugin/migrate/source/d6/User.php b/core/modules/user/src/Plugin/migrate/source/d6/User.php index 56f68bf8..5213534b 100644 --- a/core/modules/user/src/Plugin/migrate/source/d6/User.php +++ b/core/modules/user/src/Plugin/migrate/source/d6/User.php @@ -9,7 +9,8 @@ * Drupal 6 user source from database. * * @MigrateSource( - * id = "d6_user" + * id = "d6_user", + * source_module = "user" * ) */ class User extends DrupalSqlBase { @@ -35,7 +36,7 @@ public function fields() { // Profile fields. if ($this->moduleExists('profile')) { $fields += $this->select('profile_fields', 'pf') - ->fields('pf', array('name', 'title')) + ->fields('pf', ['name', 'title']) ->execute() ->fetchAllKeyed(); } @@ -49,7 +50,7 @@ public function fields() { public function prepareRow(Row $row) { // User roles. $roles = $this->select('users_roles', 'ur') - ->fields('ur', array('rid')) + ->fields('ur', ['rid']) ->condition('ur.uid', $row->getSourceProperty('uid')) ->execute() ->fetchCol(); @@ -60,7 +61,7 @@ public function prepareRow(Row $row) { if ($row->hasSourceProperty('timezone_id') && $row->getSourceProperty('timezone_id')) { if ($this->getDatabase()->schema()->tableExists('event_timezones')) { $event_timezone = $this->select('event_timezones', 'e') - ->fields('e', array('name')) + ->fields('e', ['name']) ->condition('e.timezone', $row->getSourceProperty('timezone_id')) ->execute() ->fetchField(); @@ -80,12 +81,12 @@ public function prepareRow(Row $row) { * {@inheritdoc} */ public function getIds() { - return array( - 'uid' => array( + return [ + 'uid' => [ 'type' => 'integer', 'alias' => 'u', - ), - ); + ], + ]; } /** @@ -95,7 +96,7 @@ public function getIds() { * Associative array having field name as key and description as value. */ protected function baseFields() { - $fields = array( + $fields = [ 'uid' => $this->t('User ID'), 'name' => $this->t('Username'), 'pass' => $this->t('Password'), @@ -112,7 +113,7 @@ protected function baseFields() { 'picture' => $this->t('Picture'), 'init' => $this->t('Init'), 'data' => $this->t('User data'), - ); + ]; // Possible field added by Date contributed module. // @see https://api.drupal.org/api/drupal/modules%21user%21user.install/function/user_update_7002/7 diff --git a/core/modules/user/src/Plugin/migrate/source/d6/UserPicture.php b/core/modules/user/src/Plugin/migrate/source/d6/UserPicture.php index 13ae4f31..0d5bd6bc 100644 --- a/core/modules/user/src/Plugin/migrate/source/d6/UserPicture.php +++ b/core/modules/user/src/Plugin/migrate/source/d6/UserPicture.php @@ -10,7 +10,8 @@ * @todo Support default picture? * * @MigrateSource( - * id = "d6_user_picture" + * id = "d6_user_picture", + * source_module = "user" * ) */ class UserPicture extends DrupalSqlBase { @@ -21,7 +22,7 @@ class UserPicture extends DrupalSqlBase { public function query() { $query = $this->select('users', 'u') ->condition('picture', '', '<>') - ->fields('u', array('uid', 'access', 'picture')) + ->fields('u', ['uid', 'access', 'picture']) ->orderBy('u.access'); return $query; } @@ -30,11 +31,11 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'uid' => 'Primary Key: Unique user ID.', 'access' => 'Timestamp for previous time user accessed the site.', 'picture' => "Path to the user's uploaded picture.", - ); + ]; } /** * {@inheritdoc} diff --git a/core/modules/user/src/Plugin/migrate/source/d6/UserPictureFile.php b/core/modules/user/src/Plugin/migrate/source/d6/UserPictureFile.php index d394e9c0..72d18fd0 100644 --- a/core/modules/user/src/Plugin/migrate/source/d6/UserPictureFile.php +++ b/core/modules/user/src/Plugin/migrate/source/d6/UserPictureFile.php @@ -9,7 +9,8 @@ * Drupal 6 user picture source from database. * * @MigrateSource( - * id = "d6_user_picture_file" + * id = "d6_user_picture_file", + * source_module = "user" * ) */ class UserPictureFile extends DrupalSqlBase { @@ -34,7 +35,7 @@ class UserPictureFile extends DrupalSqlBase { public function query() { $query = $this->select('users', 'u') ->condition('u.picture', '', '<>') - ->fields('u', array('uid', 'picture')); + ->fields('u', ['uid', 'picture']); return $query; } @@ -62,10 +63,10 @@ public function prepareRow(Row $row) { * {@inheritdoc} */ public function fields() { - return array( + return [ 'picture' => "Path to the user's uploaded picture.", 'filename' => 'The picture filename.', - ); + ]; } /** * {@inheritdoc} diff --git a/core/modules/user/src/Plugin/migrate/source/d7/Role.php b/core/modules/user/src/Plugin/migrate/source/d7/Role.php index 1067610e..7950991a 100644 --- a/core/modules/user/src/Plugin/migrate/source/d7/Role.php +++ b/core/modules/user/src/Plugin/migrate/source/d7/Role.php @@ -9,7 +9,8 @@ * Drupal 7 role source from database. * * @MigrateSource( - * id = "d7_user_role" + * id = "d7_user_role", + * source_module = "user" * ) */ class Role extends DrupalSqlBase { @@ -25,11 +26,11 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'rid' => $this->t('Role ID.'), 'name' => $this->t('The name of the user role.'), 'weight' => $this->t('The weight of the role.'), - ); + ]; } /** diff --git a/core/modules/user/src/Plugin/migrate/source/d7/User.php b/core/modules/user/src/Plugin/migrate/source/d7/User.php index 717e1202..41f9ab4d 100644 --- a/core/modules/user/src/Plugin/migrate/source/d7/User.php +++ b/core/modules/user/src/Plugin/migrate/source/d7/User.php @@ -9,7 +9,8 @@ * Drupal 7 user source from database. * * @MigrateSource( - * id = "d7_user" + * id = "d7_user", + * source_module = "user" * ) */ class User extends FieldableEntity { @@ -27,7 +28,7 @@ public function query() { * {@inheritdoc} */ public function fields() { - $fields = array( + $fields = [ 'uid' => $this->t('User ID'), 'name' => $this->t('Username'), 'pass' => $this->t('Password'), @@ -44,12 +45,12 @@ public function fields() { 'init' => $this->t('Init'), 'data' => $this->t('User data'), 'roles' => $this->t('Roles'), - ); + ]; // Profile fields. if ($this->moduleExists('profile')) { $fields += $this->select('profile_fields', 'pf') - ->fields('pf', array('name', 'title')) + ->fields('pf', ['name', 'title']) ->execute() ->fetchAllKeyed(); } @@ -79,9 +80,9 @@ public function prepareRow(Row $row) { // ProfileFieldValues plugin. if ($this->getDatabase()->schema()->tableExists('profile_value')) { $query = $this->select('profile_value', 'pv') - ->fields('pv', array('fid', 'value')); + ->fields('pv', ['fid', 'value']); $query->leftJoin('profile_field', 'pf', 'pf.fid=pv.fid'); - $query->fields('pf', array('name', 'type')); + $query->fields('pf', ['name', 'type']); $query->condition('uid', $row->getSourceProperty('uid')); $results = $query->execute(); @@ -89,14 +90,14 @@ public function prepareRow(Row $row) { if ($profile_value['type'] == 'date') { $date = unserialize($profile_value['value']); $date = date('Y-m-d', mktime(0, 0, 0, $date['month'], $date['day'], $date['year'])); - $row->setSourceProperty($profile_value['name'], array('value' => $date)); + $row->setSourceProperty($profile_value['name'], ['value' => $date]); } elseif ($profile_value['type'] == 'list') { // Explode by newline and comma. $row->setSourceProperty($profile_value['name'], preg_split("/[\r\n,]+/", $profile_value['value'])); } else { - $row->setSourceProperty($profile_value['name'], array($profile_value['value'])); + $row->setSourceProperty($profile_value['name'], [$profile_value['value']]); } } } @@ -108,12 +109,12 @@ public function prepareRow(Row $row) { * {@inheritdoc} */ public function getIds() { - return array( - 'uid' => array( + return [ + 'uid' => [ 'type' => 'integer', 'alias' => 'u', - ), - ); + ], + ]; } } diff --git a/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php b/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php new file mode 100644 index 00000000..6a243c3a --- /dev/null +++ b/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php @@ -0,0 +1,190 @@ +userSettings = $user_settings; + $this->currentUser = $current_user; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->getParameter('serializer.formats'), + $container->get('logger.factory')->get('rest'), + $container->get('config.factory')->get('user.settings'), + $container->get('current_user') + ); + } + + /** + * Responds to user registration POST request. + * + * @param \Drupal\user\UserInterface $account + * The user account entity. + * + * @return \Drupal\rest\ModifiedResourceResponse + * The HTTP response object. + * + * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + */ + public function post(UserInterface $account = NULL) { + $this->ensureAccountCanRegister($account); + + // Only activate new users if visitors are allowed to register and no email + // verification required. + if ($this->userSettings->get('register') == USER_REGISTER_VISITORS && !$this->userSettings->get('verify_mail')) { + $account->activate(); + } + else { + $account->block(); + } + + $this->checkEditFieldAccess($account); + + // Make sure that the user entity is valid (email and name are valid). + $this->validate($account); + + // Create the account. + $account->save(); + + $this->sendEmailNotifications($account); + + return new ModifiedResourceResponse($account, 200); + } + + /** + * Ensure the account can be registered in this request. + * + * @param \Drupal\user\UserInterface $account + * The user account to register. + */ + protected function ensureAccountCanRegister(UserInterface $account = NULL) { + if ($account === NULL) { + throw new BadRequestHttpException('No user account data for registration received.'); + } + + // POSTed user accounts must not have an ID set, because we always want to + // create new entities here. + if (!$account->isNew()) { + throw new BadRequestHttpException('An ID has been set and only new user accounts can be registered.'); + } + + // Only allow anonymous users to register, authenticated users with the + // necessary permissions can POST a new user to the "user" REST resource. + // @see \Drupal\rest\Plugin\rest\resource\EntityResource + if (!$this->currentUser->isAnonymous()) { + throw new AccessDeniedHttpException('Only anonymous users can register a user.'); + } + + // Verify that the current user can register a user account. + if ($this->userSettings->get('register') == USER_REGISTER_ADMINISTRATORS_ONLY) { + throw new AccessDeniedHttpException('You cannot register a new user account.'); + } + + if (!$this->userSettings->get('verify_mail')) { + if (empty($account->getPassword())) { + // If no e-mail verification then the user must provide a password. + throw new UnprocessableEntityHttpException('No password provided.'); + } + } + else { + if (!empty($account->getPassword())) { + // If e-mail verification required then a password cannot provided. + // The password will be set when the user logs in. + throw new UnprocessableEntityHttpException('A Password cannot be specified. It will be generated on login.'); + } + } + } + + /** + * Sends email notifications if necessary for user that was registered. + * + * @param \Drupal\user\UserInterface $account + * The user account. + */ + protected function sendEmailNotifications(UserInterface $account) { + $approval_settings = $this->userSettings->get('register'); + // No e-mail verification is required. Activating the user. + if ($approval_settings == USER_REGISTER_VISITORS) { + if ($this->userSettings->get('verify_mail')) { + // No administrator approval required. + _user_mail_notify('register_no_approval_required', $account); + } + } + // Administrator approval required. + elseif ($approval_settings == USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL) { + _user_mail_notify('register_pending_approval', $account); + } + } + +} diff --git a/core/modules/user/src/Plugin/views/access/Permission.php b/core/modules/user/src/Plugin/views/access/Permission.php index d2d757bd..8d0c43df 100644 --- a/core/modules/user/src/Plugin/views/access/Permission.php +++ b/core/modules/user/src/Plugin/views/access/Permission.php @@ -103,7 +103,7 @@ public function summaryTitle() { protected function defineOptions() { $options = parent::defineOptions(); - $options['perm'] = array('default' => 'access content'); + $options['perm'] = ['default' => 'access content']; return $options; } @@ -119,13 +119,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $perms[$display_name][$perm] = strip_tags($perm_item['title']); } - $form['perm'] = array( + $form['perm'] = [ '#type' => 'select', '#options' => $perms, '#title' => $this->t('Permission'), '#default_value' => $this->options['perm'], '#description' => $this->t('Only users with the selected permission flag will be able to access this display.'), - ); + ]; } /** diff --git a/core/modules/user/src/Plugin/views/access/Role.php b/core/modules/user/src/Plugin/views/access/Role.php index 2e5b6b4b..e35daa1e 100644 --- a/core/modules/user/src/Plugin/views/access/Role.php +++ b/core/modules/user/src/Plugin/views/access/Role.php @@ -99,31 +99,31 @@ public function summaryTitle() { protected function defineOptions() { $options = parent::defineOptions(); - $options['role'] = array('default' => array()); + $options['role'] = ['default' => []]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['role'] = array( + $form['role'] = [ '#type' => 'checkboxes', '#title' => $this->t('Role'), '#default_value' => $this->options['role'], '#options' => array_map('\Drupal\Component\Utility\Html::escape', user_role_names()), '#description' => $this->t('Only the checked roles will be able to access this display.'), - ); + ]; } public function validateOptionsForm(&$form, FormStateInterface $form_state) { - $role = $form_state->getValue(array('access_options', 'role')); + $role = $form_state->getValue(['access_options', 'role']); $role = array_filter($role); if (!$role) { $form_state->setError($form['role'], $this->t('You must select at least one role if type is "by role"')); } - $form_state->setValue(array('access_options', 'role'), $role); + $form_state->setValue(['access_options', 'role'], $role); } /** diff --git a/core/modules/user/src/Plugin/views/argument/RolesRid.php b/core/modules/user/src/Plugin/views/argument/RolesRid.php index a1bba793..ff9bf5ec 100644 --- a/core/modules/user/src/Plugin/views/argument/RolesRid.php +++ b/core/modules/user/src/Plugin/views/argument/RolesRid.php @@ -52,7 +52,7 @@ public static function create(ContainerInterface $container, array $configuratio */ public function titleQuery() { $entities = $this->roleStorage->loadMultiple($this->value); - $titles = array(); + $titles = []; foreach ($entities as $entity) { $titles[] = $entity->label(); } diff --git a/core/modules/user/src/Plugin/views/argument/Uid.php b/core/modules/user/src/Plugin/views/argument/Uid.php index 77fac073..5efbecd5 100644 --- a/core/modules/user/src/Plugin/views/argument/Uid.php +++ b/core/modules/user/src/Plugin/views/argument/Uid.php @@ -51,10 +51,10 @@ public static function create(ContainerInterface $container, array $configuratio * Override the behavior of title(). Get the name of the user. * * @return array - * A list of usernames. + * A list of usernames. */ public function titleQuery() { - return array_map(function($account) { + return array_map(function ($account) { return $account->label(); }, $this->storage->loadMultiple($this->value)); } diff --git a/core/modules/user/src/Plugin/views/argument_default/User.php b/core/modules/user/src/Plugin/views/argument_default/User.php index 0d1d4458..448f79c5 100644 --- a/core/modules/user/src/Plugin/views/argument_default/User.php +++ b/core/modules/user/src/Plugin/views/argument_default/User.php @@ -64,7 +64,7 @@ public static function create(ContainerInterface $container, array $configuratio */ protected function defineOptions() { $options = parent::defineOptions(); - $options['user'] = array('default' => ''); + $options['user'] = ['default' => '']; return $options; } @@ -73,11 +73,11 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['user'] = array( + $form['user'] = [ '#type' => 'checkbox', '#title' => $this->t('Also look for a node and use the node author'), '#default_value' => $this->options['user'], - ); + ]; } /** diff --git a/core/modules/user/src/Plugin/views/argument_validator/User.php b/core/modules/user/src/Plugin/views/argument_validator/User.php index fa61dbf6..e7d21391 100644 --- a/core/modules/user/src/Plugin/views/argument_validator/User.php +++ b/core/modules/user/src/Plugin/views/argument_validator/User.php @@ -38,8 +38,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition */ protected function defineOptions() { $options = parent::defineOptions(); - $options['restrict_roles'] = array('default' => FALSE); - $options['roles'] = array('default' => array()); + $options['restrict_roles'] = ['default' => FALSE]; + $options['roles'] = ['default' => []]; return $options; } @@ -51,30 +51,30 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $sanitized_id = ArgumentPluginBase::encodeValidatorId($this->definition['id']); - $form['restrict_roles'] = array( + $form['restrict_roles'] = [ '#type' => 'checkbox', '#title' => $this->t('Restrict user based on role'), '#default_value' => $this->options['restrict_roles'], - ); + ]; - $form['roles'] = array( + $form['roles'] = [ '#type' => 'checkboxes', '#title' => $this->t('Restrict to the selected roles'), - '#options' => array_map(array('\Drupal\Component\Utility\Html', 'escape'), user_role_names(TRUE)), + '#options' => array_map(['\Drupal\Component\Utility\Html', 'escape'], user_role_names(TRUE)), '#default_value' => $this->options['roles'], '#description' => $this->t('If no roles are selected, users from any role will be allowed.'), - '#states' => array( - 'visible' => array( - ':input[name="options[validate][options][' . $sanitized_id . '][restrict_roles]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[validate][options][' . $sanitized_id . '][restrict_roles]"]' => ['checked' => TRUE], + ], + ], + ]; } /** * {@inheritdoc} */ - public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = array()) { + public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) { // filter trash out of the options so we don't store giant unnecessary arrays $options['roles'] = array_filter($options['roles']); } diff --git a/core/modules/user/src/Plugin/views/argument_validator/UserName.php b/core/modules/user/src/Plugin/views/argument_validator/UserName.php index 88ffd646..8ef4999b 100644 --- a/core/modules/user/src/Plugin/views/argument_validator/UserName.php +++ b/core/modules/user/src/Plugin/views/argument_validator/UserName.php @@ -23,10 +23,10 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $entity_type = $this->entityManager->getDefinition('user'); - $form['multiple']['#options'] = array( - 0 => $this->t('Single name', array('%type' => $entity_type->getLabel())), - 1 => $this->t('One or more names separated by , or +', array('%type' => $entity_type->getLabel())), - ); + $form['multiple']['#options'] = [ + 0 => $this->t('Single name', ['%type' => $entity_type->getLabel()]), + 1 => $this->t('One or more names separated by , or +', ['%type' => $entity_type->getLabel()]), + ]; } /** @@ -39,14 +39,14 @@ public function validateArgument($argument) { $names = array_filter(preg_split('/[,+ ]/', $argument)); } elseif ($argument) { - $names = array($argument); + $names = [$argument]; } // No specified argument should be invalid. else { return FALSE; } - $accounts = $this->userStorage->loadByProperties(array('name' => $names)); + $accounts = $this->userStorage->loadByProperties(['name' => $names]); // If there are no accounts, return FALSE now. As we will not enter the // loop below otherwise. diff --git a/core/modules/user/src/Plugin/views/field/Permissions.php b/core/modules/user/src/Plugin/views/field/Permissions.php index bd5c11d5..71aef597 100644 --- a/core/modules/user/src/Plugin/views/field/Permissions.php +++ b/core/modules/user/src/Plugin/views/field/Permissions.php @@ -66,7 +66,7 @@ public static function create(ContainerInterface $container, array $configuratio public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $this->additional_fields['uid'] = array('table' => 'users_field_data', 'field' => 'uid'); + $this->additional_fields['uid'] = ['table' => 'users_field_data', 'field' => 'uid']; } public function query() { @@ -75,12 +75,11 @@ public function query() { } public function preRender(&$values) { - $uids = array(); - $this->items = array(); + $this->items = []; $permission_names = \Drupal::service('user.permissions')->getPermissions(); - $rids = array(); + $rids = []; foreach ($values as $result) { $user_rids = $this->getEntity($result)->getRoles(); $uid = $this->getValue($result); @@ -100,15 +99,13 @@ public function preRender(&$values) { } } - foreach ($uids as $uid) { - if (isset($this->items[$uid])) { - ksort($this->items[$uid]); - } + foreach ($this->items as &$permission) { + ksort($permission); } } } - function render_item($count, $item) { + public function render_item($count, $item) { return $item['permission']; } diff --git a/core/modules/user/src/Plugin/views/field/Roles.php b/core/modules/user/src/Plugin/views/field/Roles.php index 9d8edc04..e7d9495b 100644 --- a/core/modules/user/src/Plugin/views/field/Roles.php +++ b/core/modules/user/src/Plugin/views/field/Roles.php @@ -55,7 +55,7 @@ public static function create(ContainerInterface $container, array $configuratio public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $this->additional_fields['uid'] = array('table' => 'users_field_data', 'field' => 'uid'); + $this->additional_fields['uid'] = ['table' => 'users_field_data', 'field' => 'uid']; } public function query() { @@ -64,8 +64,8 @@ public function query() { } public function preRender(&$values) { - $uids = array(); - $this->items = array(); + $uids = []; + $this->items = []; foreach ($values as $result) { $uids[] = $this->getValue($result); @@ -73,7 +73,7 @@ public function preRender(&$values) { if ($uids) { $roles = user_roles(); - $result = $this->database->query('SELECT u.entity_id as uid, u.roles_target_id as rid FROM {user__roles} u WHERE u.entity_id IN ( :uids[] ) AND u.roles_target_id IN ( :rids[] )', array(':uids[]' => $uids, ':rids[]' => array_keys($roles))); + $result = $this->database->query('SELECT u.entity_id as uid, u.roles_target_id as rid FROM {user__roles} u WHERE u.entity_id IN ( :uids[] ) AND u.roles_target_id IN ( :rids[] )', [':uids[]' => $uids, ':rids[]' => array_keys($roles)]); foreach ($result as $role) { $this->items[$role->uid][$role->rid]['role'] = $roles[$role->rid]->label(); $this->items[$role->uid][$role->rid]['rid'] = $role->rid; @@ -90,7 +90,7 @@ public function preRender(&$values) { } } - function render_item($count, $item) { + public function render_item($count, $item) { return $item['role']; } diff --git a/core/modules/user/src/Plugin/views/field/UserBulkForm.php b/core/modules/user/src/Plugin/views/field/UserBulkForm.php index 57ae4370..3d0196a9 100644 --- a/core/modules/user/src/Plugin/views/field/UserBulkForm.php +++ b/core/modules/user/src/Plugin/views/field/UserBulkForm.php @@ -25,7 +25,7 @@ public function viewsForm(&$form, FormStateInterface $form_state) { foreach ($this->view->result as $row_index => $result) { $account = $result->_entity; if ($account instanceof UserInterface) { - $form[$this->options['id']][$row_index]['#title'] = $this->t('Update the user %name', array('%name' => $account->label())); + $form[$this->options['id']][$row_index]['#title'] = $this->t('Update the user %name', ['%name' => $account->label()]); } } } diff --git a/core/modules/user/src/Plugin/views/field/UserData.php b/core/modules/user/src/Plugin/views/field/UserData.php index b87346fc..365ab3b7 100644 --- a/core/modules/user/src/Plugin/views/field/UserData.php +++ b/core/modules/user/src/Plugin/views/field/UserData.php @@ -58,8 +58,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition protected function defineOptions() { $options = parent::defineOptions(); - $options['data_module'] = array('default' => ''); - $options['data_name'] = array('default' => ''); + $options['data_module'] = ['default' => '']; + $options['data_name'] = ['default' => '']; return $options; } @@ -71,25 +71,25 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $modules = $this->moduleHandler->getModuleList(); - $names = array(); + $names = []; foreach (array_keys($modules) as $name) { $names[$name] = $this->moduleHandler->getName($name); } - $form['data_module'] = array( + $form['data_module'] = [ '#title' => $this->t('Module name'), '#type' => 'select', '#description' => $this->t('The module which sets this user data.'), '#default_value' => $this->options['data_module'], '#options' => $names, - ); + ]; - $form['data_name'] = array( + $form['data_name'] = [ '#title' => $this->t('Name'), '#type' => 'textfield', '#description' => $this->t('The name of the data key.'), '#default_value' => $this->options['data_name'], - ); + ]; } /** diff --git a/core/modules/user/src/Plugin/views/filter/Current.php b/core/modules/user/src/Plugin/views/filter/Current.php index e7126736..aa42529f 100644 --- a/core/modules/user/src/Plugin/views/filter/Current.php +++ b/core/modules/user/src/Plugin/views/filter/Current.php @@ -2,6 +2,7 @@ namespace Drupal\user\Plugin\views\filter; +use Drupal\Core\Database\Query\Condition; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\filter\BooleanOperator; @@ -28,7 +29,7 @@ public function query() { $this->ensureMyTable(); $field = $this->tableAlias . '.' . $this->realField . ' '; - $or = db_or(); + $or = new Condition('OR'); if (empty($this->value)) { $or->condition($field, '***CURRENT_USER***', '<>'); diff --git a/core/modules/user/src/Plugin/views/filter/Name.php b/core/modules/user/src/Plugin/views/filter/Name.php index e241e876..3ad018fa 100644 --- a/core/modules/user/src/Plugin/views/filter/Name.php +++ b/core/modules/user/src/Plugin/views/filter/Name.php @@ -19,9 +19,9 @@ class Name extends InOperator { protected $alwaysMultiple = TRUE; protected function valueForm(&$form, FormStateInterface $form_state) { - $users = $this->value ? User::loadMultiple($this->value) : array(); + $users = $this->value ? User::loadMultiple($this->value) : []; $default_value = EntityAutocomplete::getEntityLabels($users); - $form['value'] = array( + $form['value'] = [ '#type' => 'entity_autocomplete', '#title' => $this->t('Usernames'), '#description' => $this->t('Enter a comma separated list of user names.'), @@ -29,7 +29,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) { '#tags' => TRUE, '#default_value' => $default_value, '#process_default_value' => $this->isExposed(), - ); + ]; $user_input = $form_state->getUserInput(); if ($form_state->get('exposed') && !isset($user_input[$this->options['expose']['identifier']])) { @@ -40,13 +40,13 @@ protected function valueForm(&$form, FormStateInterface $form_state) { protected function valueValidate($form, FormStateInterface $form_state) { $uids = []; - if ($values = $form_state->getValue(array('options', 'value'))) { + if ($values = $form_state->getValue(['options', 'value'])) { foreach ($values as $value) { $uids[] = $value['target_id']; } sort($uids); } - $form_state->setValue(array('options', 'value'), $uids); + $form_state->setValue(['options', 'value'], $uids); } public function acceptExposedInput($input) { @@ -105,7 +105,7 @@ public function getValueOptions() { public function adminSummary() { // set up $this->valueOptions for the parent summary - $this->valueOptions = array(); + $this->valueOptions = []; if ($this->value) { $result = \Drupal::entityTypeManager()->getStorage('user') @@ -115,7 +115,8 @@ public function adminSummary() { $this->valueOptions[$account->id()] = $account->label(); } else { - $this->valueOptions[$account->id()] = 'Anonymous'; // Intentionally NOT translated. + // Intentionally NOT translated. + $this->valueOptions[$account->id()] = 'Anonymous'; } } } diff --git a/core/modules/user/src/Plugin/views/filter/Permissions.php b/core/modules/user/src/Plugin/views/filter/Permissions.php index 7d444c68..7dd9171a 100644 --- a/core/modules/user/src/Plugin/views/filter/Permissions.php +++ b/core/modules/user/src/Plugin/views/filter/Permissions.php @@ -88,7 +88,7 @@ public function getValueOptions() { */ public function query() { // @todo user_role_names() should maybe support multiple permissions. - $rids = array(); + $rids = []; // Get all role IDs that have the configured permissions. foreach ($this->value as $permission) { $roles = user_role_names(FALSE, $permission); diff --git a/core/modules/user/src/Plugin/views/filter/Roles.php b/core/modules/user/src/Plugin/views/filter/Roles.php index 64074c39..47adafb8 100644 --- a/core/modules/user/src/Plugin/views/filter/Roles.php +++ b/core/modules/user/src/Plugin/views/filter/Roles.php @@ -62,7 +62,7 @@ public function getValueOptions() { /** * Override empty and not empty operator labels to be clearer for user roles. */ - function operators() { + public function operators() { $operators = parent::operators(); $operators['empty']['title'] = $this->t("Only has the 'authenticated user' role"); $operators['not empty']['title'] = $this->t("Has roles in addition to 'authenticated user'"); @@ -73,7 +73,10 @@ function operators() { * {@inheritdoc} */ public function calculateDependencies() { - $dependencies = array(); + $dependencies = []; + if (in_array($this->operator, ['empty', 'not empty'])) { + return $dependencies; + } foreach ($this->value as $role_id) { $role = $this->roleStorage->load($role_id); $dependencies[$role->getConfigDependencyKey()][] = $role->getConfigDependencyName(); diff --git a/core/modules/user/src/Plugin/views/wizard/Users.php b/core/modules/user/src/Plugin/views/wizard/Users.php index efd42723..081a509a 100644 --- a/core/modules/user/src/Plugin/views/wizard/Users.php +++ b/core/modules/user/src/Plugin/views/wizard/Users.php @@ -27,16 +27,16 @@ class Users extends WizardPluginBase { /** * Set default values for the filters. */ - protected $filters = array( - 'status' => array( + protected $filters = [ + 'status' => [ 'value' => TRUE, 'table' => 'users_field_data', 'field' => 'status', 'plugin_id' => 'boolean', 'entity_type' => 'user', 'entity_field' => 'status', - ) - ); + ] + ]; /** * {@inheritdoc} diff --git a/core/modules/user/src/PrivateTempStore.php b/core/modules/user/src/PrivateTempStore.php index bb022460..651227c3 100644 --- a/core/modules/user/src/PrivateTempStore.php +++ b/core/modules/user/src/PrivateTempStore.php @@ -112,6 +112,9 @@ public function get($key) { * The key of the data to store. * @param mixed $value * The data to store. + * + * @throws \Drupal\user\TempStoreException + * Thrown when a lock for the backend storage could not be acquired. */ public function set($key, $value) { $key = $this->createkey($key); @@ -122,11 +125,11 @@ public function set($key, $value) { } } - $value = (object) array( + $value = (object) [ 'owner' => $this->getOwner(), 'data' => $value, 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'), - ); + ]; $this->storage->setWithExpire($key, $value, $this->expire); $this->lockBackend->release($key); } @@ -161,6 +164,9 @@ public function getMetadata($key) { * @return bool * TRUE if the object was deleted or does not exist, FALSE if it exists but * is not owned by $this->owner. + * + * @throws \Drupal\user\TempStoreException + * Thrown when a lock for the backend storage could not be acquired. */ public function delete($key) { $key = $this->createkey($key); diff --git a/core/modules/user/src/PrivateTempStoreFactory.php b/core/modules/user/src/PrivateTempStoreFactory.php index acbf41bc..e51faf34 100644 --- a/core/modules/user/src/PrivateTempStoreFactory.php +++ b/core/modules/user/src/PrivateTempStoreFactory.php @@ -22,7 +22,7 @@ class PrivateTempStoreFactory { /** * The lock object used for this data. * - * @var \Drupal\Core\Lock\LockBackendInterface $lockBackend + * @var \Drupal\Core\Lock\LockBackendInterface */ protected $lockBackend; @@ -61,7 +61,7 @@ class PrivateTempStoreFactory { * @param int $expire * The time to live for items, in seconds. */ - function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) { + public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) { $this->storageFactory = $storage_factory; $this->lockBackend = $lock_backend; $this->currentUser = $current_user; @@ -79,7 +79,7 @@ function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBac * @return \Drupal\user\PrivateTempStore * An instance of the key/value store. */ - function get($collection) { + public function get($collection) { // Store the data for this collection in the database. $storage = $this->storageFactory->get("user.private_tempstore.$collection"); return new PrivateTempStore($storage, $this->lockBackend, $this->currentUser, $this->requestStack, $this->expire); diff --git a/core/modules/user/src/ProfileForm.php b/core/modules/user/src/ProfileForm.php index aee2e3aa..343d4d0e 100644 --- a/core/modules/user/src/ProfileForm.php +++ b/core/modules/user/src/ProfileForm.php @@ -2,23 +2,13 @@ namespace Drupal\user; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Language\LanguageManagerInterface; /** * Form handler for the profile forms. */ class ProfileForm extends AccountForm { - /** - * {@inheritdoc} - */ - public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, QueryFactory $entity_query) { - parent::__construct($entity_manager, $language_manager, $entity_query); - } - /** * {@inheritdoc} */ @@ -32,7 +22,7 @@ protected function actions(array $form, FormStateInterface $form_state) { $user = $this->currentUser(); $element['delete']['#type'] = 'submit'; $element['delete']['#value'] = $this->t('Cancel account'); - $element['delete']['#submit'] = array('::editCancelSubmit'); + $element['delete']['#submit'] = ['::editCancelSubmit']; $element['delete']['#access'] = $account->id() > 1 && (($account->id() == $user->id() && $user->hasPermission('cancel account')) || $user->hasPermission('administer users')); return $element; @@ -53,17 +43,17 @@ public function save(array $form, FormStateInterface $form_state) { * Provides a submit handler for the 'Cancel account' button. */ public function editCancelSubmit($form, FormStateInterface $form_state) { - $destination = array(); + $destination = []; $query = $this->getRequest()->query; if ($query->has('destination')) { - $destination = array('destination' => $query->get('destination')); + $destination = ['destination' => $query->get('destination')]; $query->remove('destination'); } // We redirect from user/%/edit to user/%/cancel to make the tabs disappear. $form_state->setRedirect( 'entity.user.cancel_form', - array('user' => $this->entity->id()), - array('query' => $destination) + ['user' => $this->entity->id()], + ['query' => $destination] ); } diff --git a/core/modules/user/src/ProfileTranslationHandler.php b/core/modules/user/src/ProfileTranslationHandler.php index d981f99f..5b469525 100644 --- a/core/modules/user/src/ProfileTranslationHandler.php +++ b/core/modules/user/src/ProfileTranslationHandler.php @@ -32,7 +32,7 @@ protected function hasCreatedTime() { */ public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { parent::entityFormAlter($form, $form_state, $entity); - $form['actions']['submit']['#submit'][] = array($this, 'entityFormSave'); + $form['actions']['submit']['#submit'][] = [$this, 'entityFormSave']; } /** diff --git a/core/modules/user/src/RegisterForm.php b/core/modules/user/src/RegisterForm.php index 9bc047b5..7a97974f 100644 --- a/core/modules/user/src/RegisterForm.php +++ b/core/modules/user/src/RegisterForm.php @@ -20,10 +20,10 @@ public function form(array $form, FormStateInterface $form_state) { // Pass access information to the submit handler. Running an access check // inside the submit function interferes with form processing and breaks // hook_form_alter(). - $form['administer_users'] = array( + $form['administer_users'] = [ '#type' => 'value', '#value' => $admin, - ); + ]; $form['#attached']['library'][] = 'core/drupal.form'; @@ -94,14 +94,14 @@ public function save(array $form, FormStateInterface $form_state) { $form_state->set('user', $account); $form_state->setValue('uid', $account->id()); - $this->logger('user')->notice('New user: %name %email.', array('%name' => $form_state->getValue('name'), '%email' => '<' . $form_state->getValue('mail') . '>', 'type' => $account->link($this->t('Edit'), 'edit-form'))); + $this->logger('user')->notice('New user: %name %email.', ['%name' => $form_state->getValue('name'), '%email' => '<' . $form_state->getValue('mail') . '>', 'type' => $account->link($this->t('Edit'), 'edit-form')]); // Add plain text password into user account to generate mail tokens. $account->password = $pass; // New administrative account without notification. if ($admin && !$notify) { - drupal_set_message($this->t('Created a new user account for %name. No email has been sent.', array(':url' => $account->url(), '%name' => $account->getUsername()))); + drupal_set_message($this->t('Created a new user account for %name. No email has been sent.', [':url' => $account->url(), '%name' => $account->getUsername()])); } // No email verification required; log in user immediately. elseif (!$admin && !\Drupal::config('user.settings')->get('verify_mail') && $account->isActive()) { @@ -113,13 +113,13 @@ public function save(array $form, FormStateInterface $form_state) { // No administrator approval required. elseif ($account->isActive() || $notify) { if (!$account->getEmail() && $notify) { - drupal_set_message($this->t('The new user %name was created without an email address, so no welcome message was sent.', array(':url' => $account->url(), '%name' => $account->getUsername()))); + drupal_set_message($this->t('The new user %name was created without an email address, so no welcome message was sent.', [':url' => $account->url(), '%name' => $account->getUsername()])); } else { $op = $notify ? 'register_admin_created' : 'register_no_approval_required'; if (_user_mail_notify($op, $account)) { if ($notify) { - drupal_set_message($this->t('A welcome message with further instructions has been emailed to the new user %name.', array(':url' => $account->url(), '%name' => $account->getUsername()))); + drupal_set_message($this->t('A welcome message with further instructions has been emailed to the new user %name.', [':url' => $account->url(), '%name' => $account->getUsername()])); } else { drupal_set_message($this->t('A welcome message with further instructions has been sent to your email address.')); diff --git a/core/modules/user/src/RoleForm.php b/core/modules/user/src/RoleForm.php index 3199c45a..7e788535 100644 --- a/core/modules/user/src/RoleForm.php +++ b/core/modules/user/src/RoleForm.php @@ -15,7 +15,7 @@ class RoleForm extends EntityForm { */ public function form(array $form, FormStateInterface $form_state) { $entity = $this->entity; - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Role name'), '#default_value' => $entity->label(), @@ -23,22 +23,22 @@ public function form(array $form, FormStateInterface $form_state) { '#required' => TRUE, '#maxlength' => 64, '#description' => $this->t('The name for this role. Example: "Moderator", "Editorial board", "Site architect".'), - ); - $form['id'] = array( + ]; + $form['id'] = [ '#type' => 'machine_name', '#default_value' => $entity->id(), '#required' => TRUE, '#disabled' => !$entity->isNew(), '#size' => 30, '#maxlength' => 64, - '#machine_name' => array( + '#machine_name' => [ 'exists' => ['\Drupal\user\Entity\Role', 'load'], - ), - ); - $form['weight'] = array( + ], + ]; + $form['weight'] = [ '#type' => 'value', '#value' => $entity->getWeight(), - ); + ]; return parent::form($form, $form_state, $entity); } @@ -55,12 +55,12 @@ public function save(array $form, FormStateInterface $form_state) { $edit_link = $this->entity->link($this->t('Edit')); if ($status == SAVED_UPDATED) { - drupal_set_message($this->t('Role %label has been updated.', array('%label' => $entity->label()))); - $this->logger('user')->notice('Role %label has been updated.', array('%label' => $entity->label(), 'link' => $edit_link)); + drupal_set_message($this->t('Role %label has been updated.', ['%label' => $entity->label()])); + $this->logger('user')->notice('Role %label has been updated.', ['%label' => $entity->label(), 'link' => $edit_link]); } else { - drupal_set_message($this->t('Role %label has been added.', array('%label' => $entity->label()))); - $this->logger('user')->notice('Role %label has been added.', array('%label' => $entity->label(), 'link' => $edit_link)); + drupal_set_message($this->t('Role %label has been added.', ['%label' => $entity->label()])); + $this->logger('user')->notice('Role %label has been added.', ['%label' => $entity->label(), 'link' => $edit_link]); } $form_state->setRedirect('entity.user_role.collection'); } diff --git a/core/modules/user/src/RoleListBuilder.php b/core/modules/user/src/RoleListBuilder.php index 16bd92cd..aa3b844f 100644 --- a/core/modules/user/src/RoleListBuilder.php +++ b/core/modules/user/src/RoleListBuilder.php @@ -43,11 +43,11 @@ public function getDefaultOperations(EntityInterface $entity) { $operations = parent::getDefaultOperations($entity); if ($entity->hasLinkTemplate('edit-permissions-form')) { - $operations['permissions'] = array( + $operations['permissions'] = [ 'title' => t('Edit permissions'), 'weight' => 20, 'url' => $entity->urlInfo('edit-permissions-form'), - ); + ]; } return $operations; } diff --git a/core/modules/user/src/SharedTempStore.php b/core/modules/user/src/SharedTempStore.php index d6295266..2c6113ff 100644 --- a/core/modules/user/src/SharedTempStore.php +++ b/core/modules/user/src/SharedTempStore.php @@ -142,11 +142,11 @@ public function getIfOwner($key) { * TRUE if the data was set, or FALSE if it already existed. */ public function setIfNotExists($key, $value) { - $value = (object) array( + $value = (object) [ 'owner' => $this->owner, 'data' => $value, 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'), - ); + ]; return $this->storage->setWithExpireIfNotExists($key, $value, $this->expire); } @@ -164,6 +164,9 @@ public function setIfNotExists($key, $value) { * @return bool * TRUE if the data was set, or FALSE if it already exists and is not owned * by $this->user. + * + * @throws \Drupal\user\TempStoreException + * Thrown when a lock for the backend storage could not be acquired. */ public function setIfOwner($key, $value) { if ($this->setIfNotExists($key, $value)) { @@ -185,6 +188,9 @@ public function setIfOwner($key, $value) { * The key of the data to store. * @param mixed $value * The data to store. + * + * @throws \Drupal\user\TempStoreException + * Thrown when a lock for the backend storage could not be acquired. */ public function set($key, $value) { if (!$this->lockBackend->acquire($key)) { @@ -194,11 +200,11 @@ public function set($key, $value) { } } - $value = (object) array( + $value = (object) [ 'owner' => $this->owner, 'data' => $value, 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'), - ); + ]; $this->storage->setWithExpire($key, $value, $this->expire); $this->lockBackend->release($key); } @@ -228,6 +234,9 @@ public function getMetadata($key) { * * @param string $key * The key of the data to delete. + * + * @throws \Drupal\user\TempStoreException + * Thrown when a lock for the backend storage could not be acquired. */ public function delete($key) { if (!$this->lockBackend->acquire($key)) { @@ -251,6 +260,9 @@ public function delete($key) { * @return bool * TRUE if the object was deleted or does not exist, FALSE if it exists but * is not owned by $this->owner. + * + * @throws \Drupal\user\TempStoreException + * Thrown when a lock for the backend storage could not be acquired. */ public function deleteIfOwner($key) { if (!$object = $this->storage->get($key)) { diff --git a/core/modules/user/src/SharedTempStoreFactory.php b/core/modules/user/src/SharedTempStoreFactory.php index 662ef47a..29f86832 100644 --- a/core/modules/user/src/SharedTempStoreFactory.php +++ b/core/modules/user/src/SharedTempStoreFactory.php @@ -21,7 +21,7 @@ class SharedTempStoreFactory { /** * The lock object used for this data. * - * @var \Drupal\Core\Lock\LockBackendInterface $lockBackend + * @var \Drupal\Core\Lock\LockBackendInterface */ protected $lockBackend; @@ -51,7 +51,7 @@ class SharedTempStoreFactory { * @param int $expire * The time to live for items, in seconds. */ - function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, RequestStack $request_stack, $expire = 604800) { + public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, RequestStack $request_stack, $expire = 604800) { $this->storageFactory = $storage_factory; $this->lockBackend = $lock_backend; $this->requestStack = $request_stack; @@ -72,7 +72,7 @@ function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBac * @return \Drupal\user\SharedTempStore * An instance of the key/value store. */ - function get($collection, $owner = NULL) { + public function get($collection, $owner = NULL) { // Use the currently authenticated user ID or the active user ID unless // the owner is overridden. if (!isset($owner)) { diff --git a/core/modules/user/src/Tests/RestRegisterUserTest.php b/core/modules/user/src/Tests/RestRegisterUserTest.php new file mode 100644 index 00000000..450c5529 --- /dev/null +++ b/core/modules/user/src/Tests/RestRegisterUserTest.php @@ -0,0 +1,172 @@ +enableService('user_registration', 'POST', 'hal_json'); + + Role::load(RoleInterface::ANONYMOUS_ID) + ->grantPermission('restful post user_registration') + ->save(); + + Role::load(RoleInterface::AUTHENTICATED_ID) + ->grantPermission('restful post user_registration') + ->save(); + } + + /** + * Tests that only anonymous users can register users. + */ + public function testRegisterUser() { + // Verify that an authenticated user cannot register a new user, despite + // being granted permission to do so because only anonymous users can + // register themselves, authenticated users with the necessary permissions + // can POST a new user to the "user" REST resource. + $user = $this->createUser(); + $this->drupalLogin($user); + $this->registerRequest('palmer.eldritch'); + $this->assertResponse('403', 'Only anonymous users can register users.'); + $this->drupalLogout(); + + $user_settings = $this->config('user.settings'); + + // Test out different setting User Registration and Email Verification. + // Allow visitors to register with no email verification. + $user_settings->set('register', USER_REGISTER_VISITORS); + $user_settings->set('verify_mail', 0); + $user_settings->save(); + $user = $this->registerUser('Palmer.Eldritch'); + $this->assertFalse($user->isBlocked()); + $this->assertFalse(empty($user->getPassword())); + $email_count = count($this->drupalGetMails()); + $this->assertEqual(0, $email_count); + + // Attempt to register without sending a password. + $this->registerRequest('Rick.Deckard', FALSE); + $this->assertResponse('422', 'No password provided'); + + // Allow visitors to register with email verification. + $user_settings->set('register', USER_REGISTER_VISITORS); + $user_settings->set('verify_mail', 1); + $user_settings->save(); + $user = $this->registerUser('Jason.Taverner', FALSE); + $this->assertTrue(empty($user->getPassword())); + $this->assertTrue($user->isBlocked()); + $this->assertMailString('body', 'You may now log in by clicking this link', 1); + + // Attempt to register with a password when e-mail verification is on. + $this->registerRequest('Estraven', TRUE); + $this->assertResponse('422', 'A Password cannot be specified. It will be generated on login.'); + + // Allow visitors to register with Admin approval and e-mail verification. + $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL); + $user_settings->set('verify_mail', 1); + $user_settings->save(); + $user = $this->registerUser('Bob.Arctor', FALSE); + $this->assertTrue(empty($user->getPassword())); + $this->assertTrue($user->isBlocked()); + $this->assertMailString('body', 'Your application for an account is', 2); + $this->assertMailString('body', 'Bob.Arctor has applied for an account', 2); + + // Attempt to register with a password when e-mail verification is on. + $this->registerRequest('Ursula', TRUE); + $this->assertResponse('422', 'A Password cannot be specified. It will be generated on login.'); + + // Allow visitors to register with Admin approval and no email verification. + $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL); + $user_settings->set('verify_mail', 0); + $user_settings->save(); + $user = $this->registerUser('Argaven'); + $this->assertFalse(empty($user->getPassword())); + $this->assertTrue($user->isBlocked()); + $this->assertMailString('body', 'Your application for an account is', 2); + $this->assertMailString('body', 'Argaven has applied for an account', 2); + + // Attempt to register without sending a password. + $this->registerRequest('Tibe', FALSE); + $this->assertResponse('422', 'No password provided'); + } + + /** + * Creates serialize user values. + * + * @param string $name + * The name of the user. Use only valid values for emails. + * + * @param bool $include_password + * Whether to include a password in the user values. + * + * @return string + * Serialized user values. + */ + protected function createSerializedUser($name, $include_password = TRUE) { + global $base_url; + // New user info to be serialized. + $data = [ + "_links" => ["type" => ["href" => $base_url . "/rest/type/user/user"]], + "langcode" => [["value" => "en"]], + "name" => [["value" => $name]], + "mail" => [["value" => "$name@example.com"]], + ]; + if ($include_password) { + $data['pass']['value'] = 'SuperSecretPassword'; + } + + // Create a HAL+JSON version for the user entity we want to create. + $serialized = $this->container->get('serializer') + ->serialize($data, 'hal_json'); + return $serialized; + } + + /** + * Registers a user via REST resource. + * + * @param $name + * User name. + * + * @param bool $include_password + * + * @return bool|\Drupal\user\Entity\User + */ + protected function registerUser($name, $include_password = TRUE) { + // Verify that an anonymous user can register. + $this->registerRequest($name, $include_password); + $this->assertResponse('200', 'HTTP response code is correct.'); + $user = user_load_by_name($name); + $this->assertFalse(empty($user), 'User was create as expected'); + return $user; + } + + /** + * Make a REST user registration request. + * + * @param $name + * @param $include_password + */ + protected function registerRequest($name, $include_password = TRUE) { + $serialized = $this->createSerializedUser($name, $include_password); + $this->httpRequest('/user/register', 'POST', $serialized, 'application/hal+json'); + } + +} diff --git a/core/modules/user/src/Tests/Update/UserUpdateEmailToken.php b/core/modules/user/src/Tests/Update/UserUpdateEmailToken.php deleted file mode 100644 index d321ee04..00000000 --- a/core/modules/user/src/Tests/Update/UserUpdateEmailToken.php +++ /dev/null @@ -1,35 +0,0 @@ -databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/drupal-8.user-email-token-2587275.php', - ]; - } - - /** - * Tests that email token in status_blocked of user.mail is updated. - */ - public function testEmailToken() { - $mail = \Drupal::config('user.mail')->get('status_blocked'); - $this->assertTrue(strpos($mail['body'], '[site:account-name]')); - $this->runUpdates(); - $mail = \Drupal::config('user.mail')->get('status_blocked'); - $this->assertFalse(strpos($mail['body'], '[site:account-name]')); - } - -} diff --git a/core/modules/user/src/Tests/UserAccountLinksTest.php b/core/modules/user/src/Tests/UserAccountLinksTest.php index 6d7d723f..15a4b205 100644 --- a/core/modules/user/src/Tests/UserAccountLinksTest.php +++ b/core/modules/user/src/Tests/UserAccountLinksTest.php @@ -16,7 +16,7 @@ class UserAccountLinksTest extends WebTestBase { * * @var array */ - public static $modules = array('menu_ui', 'block', 'test_page_test'); + public static $modules = ['menu_ui', 'block', 'test_page_test']; /** * {@inheritdoc} @@ -31,9 +31,9 @@ protected function setUp() { /** * Tests the secondary menu. */ - function testSecondaryMenu() { + public function testSecondaryMenu() { // Create a regular user. - $user = $this->drupalCreateUser(array()); + $user = $this->drupalCreateUser([]); // Log in and get the homepage. $this->drupalLogin($user); @@ -41,18 +41,18 @@ function testSecondaryMenu() { // For a logged-in user, expect the secondary menu to have links for "My // account" and "Log out". - $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array( + $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [ ':menu_class' => 'menu', ':href' => 'user', ':text' => 'My account', - )); + ]); $this->assertEqual(count($link), 1, 'My account link is in secondary menu.'); - $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array( + $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [ ':menu_class' => 'menu', ':href' => 'user/logout', ':text' => 'Log out', - )); + ]); $this->assertEqual(count($link), 1, 'Log out link is in secondary menu.'); // Log out and get the homepage. @@ -60,35 +60,35 @@ function testSecondaryMenu() { $this->drupalGet(''); // For a logged-out user, expect the secondary menu to have a "Log in" link. - $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array( + $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [ ':menu_class' => 'menu', ':href' => 'user/login', ':text' => 'Log in', - )); + ]); $this->assertEqual(count($link), 1, 'Log in link is in secondary menu.'); } /** * Tests disabling the 'My account' link. */ - function testDisabledAccountLink() { + public function testDisabledAccountLink() { // Create an admin user and log in. - $this->drupalLogin($this->drupalCreateUser(array('access administration pages', 'administer menu'))); + $this->drupalLogin($this->drupalCreateUser(['access administration pages', 'administer menu'])); // Verify that the 'My account' link exists before we check for its // disappearance. - $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array( + $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [ ':menu_class' => 'menu', ':href' => 'user', ':text' => 'My account', - )); + ]); $this->assertEqual(count($link), 1, 'My account link is in the secondary menu.'); // Verify that the 'My account' link is enabled. Do not assume the value of // auto-increment is 1. Use XPath to obtain input element id and name using // the consistent label text. $this->drupalGet('admin/structure/menu/manage/account'); - $label = $this->xpath('//label[contains(.,:text)]/@for', array(':text' => 'Enable My account menu link')); + $label = $this->xpath('//label[contains(.,:text)]/@for', [':text' => 'Enable My account menu link']); $this->assertFieldChecked((string) $label[0], "The 'My account' link is enabled by default."); // Disable the 'My account' link. @@ -99,18 +99,18 @@ function testDisabledAccountLink() { $this->drupalGet(''); // Verify that the 'My account' link does not appear when disabled. - $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', array( + $link = $this->xpath('//ul[@class=:menu_class]/li/a[contains(@href, :href) and text()=:text]', [ ':menu_class' => 'menu', ':href' => 'user', ':text' => 'My account', - )); + ]); $this->assertEqual(count($link), 0, 'My account link is not in the secondary menu.'); } /** * Tests page title is set correctly on user account tabs. */ - function testAccountPageTitles() { + public function testAccountPageTitles() { // Default page titles are suffixed with the site name - Drupal. $title_suffix = ' | Drupal'; diff --git a/core/modules/user/src/Tests/UserAdminLanguageTest.php b/core/modules/user/src/Tests/UserAdminLanguageTest.php index 03baa044..cd6cc657 100644 --- a/core/modules/user/src/Tests/UserAdminLanguageTest.php +++ b/core/modules/user/src/Tests/UserAdminLanguageTest.php @@ -31,12 +31,12 @@ class UserAdminLanguageTest extends WebTestBase { * * @var array */ - public static $modules = array('user', 'language', 'language_test'); + public static $modules = ['user', 'language', 'language_test']; protected function setUp() { parent::setUp(); // User to add and remove language. - $this->adminUser = $this->drupalCreateUser(array('administer languages', 'access administration pages')); + $this->adminUser = $this->drupalCreateUser(['administer languages', 'access administration pages']); // User to check non-admin access. $this->regularUser = $this->drupalCreateUser(); } @@ -44,7 +44,7 @@ protected function setUp() { /** * Tests that admin language is not configurable in single language sites. */ - function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() { + public function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() { $this->drupalLogin($this->adminUser); $this->setLanguageNegotiation(); $path = 'user/' . $this->adminUser->id() . '/edit'; @@ -56,7 +56,7 @@ function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() { /** * Tests that admin language negotiation is configurable only if enabled. */ - function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation() { + public function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation() { $this->drupalLogin($this->adminUser); $this->addCustomLanguage(); $path = 'user/' . $this->adminUser->id() . '/edit'; @@ -83,7 +83,7 @@ function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation * have a setting for pages they cannot access, so they should not be able to * set a language for those pages. */ - function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIsEnabled() { + public function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIsEnabled() { $this->drupalLogin($this->adminUser); // Adds a new language, because with only one language, setting won't show. $this->addCustomLanguage(); @@ -103,7 +103,7 @@ function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIs /** * Tests the actual language negotiation. */ - function testActualNegotiation() { + public function testActualNegotiation() { $this->drupalLogin($this->adminUser); $this->addCustomLanguage(); $this->setLanguageNegotiation(); @@ -117,7 +117,7 @@ function testActualNegotiation() { $this->assertText('Language negotiation method: language-url'); // Set a preferred language code for the user. - $edit = array(); + $edit = []; $edit['preferred_admin_langcode'] = 'xx'; $this->drupalPostForm($path, $edit, t('Save')); @@ -137,7 +137,7 @@ function testActualNegotiation() { $this->assertText('Language negotiation method: language-user-admin'); // Unset the preferred language code for the user. - $edit = array(); + $edit = []; $edit['preferred_admin_langcode'] = ''; $this->drupalPostForm($path, $edit, t('Save')); $this->drupalGet($path); @@ -155,29 +155,29 @@ function testActualNegotiation() { * @param bool $admin_first * Whether the admin negotiation should be first. */ - function setLanguageNegotiation($admin_first = FALSE) { - $edit = array( + public function setLanguageNegotiation($admin_first = FALSE) { + $edit = [ 'language_interface[enabled][language-user-admin]' => TRUE, 'language_interface[enabled][language-url]' => TRUE, 'language_interface[weight][language-user-admin]' => ($admin_first ? -12 : -8), 'language_interface[weight][language-url]' => -10, - ); + ]; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); } /** * Helper method for adding a custom language. */ - function addCustomLanguage() { + public function addCustomLanguage() { $langcode = 'xx'; // The English name for the language. $name = $this->randomMachineName(16); - $edit = array( + $edit = [ 'predefined_langcode' => 'custom', 'langcode' => $langcode, 'label' => $name, 'direction' => LanguageInterface::DIRECTION_LTR, - ); + ]; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); } diff --git a/core/modules/user/src/Tests/UserAdminListingTest.php b/core/modules/user/src/Tests/UserAdminListingTest.php index 2ca50c8f..9ec95060 100644 --- a/core/modules/user/src/Tests/UserAdminListingTest.php +++ b/core/modules/user/src/Tests/UserAdminListingTest.php @@ -21,7 +21,7 @@ public function testUserListing() { $this->assertResponse(403, 'Anonymous user does not have access to the user admin listing.'); // Create a bunch of users. - $accounts = array(); + $accounts = []; for ($i = 0; $i < 3; $i++) { $account = $this->drupalCreateUser(); $accounts[$account->label()] = $account; @@ -39,8 +39,8 @@ public function testUserListing() { $accounts[$account->label()] = $account; $timestamp_user = $account->label(); - $rid_1 = $this->drupalCreateRole(array(), 'custom_role_1', 'custom_role_1'); - $rid_2 = $this->drupalCreateRole(array(), 'custom_role_2', 'custom_role_2'); + $rid_1 = $this->drupalCreateRole([], 'custom_role_1', 'custom_role_1'); + $rid_2 = $this->drupalCreateRole([], 'custom_role_2', 'custom_role_2'); $account = $this->drupalCreateUser(); $account->addRole($rid_1); @@ -50,7 +50,7 @@ public function testUserListing() { $role_account_name = $account->label(); // Create an admin user and look at the listing. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $accounts[$admin_user->label()] = $admin_user; $accounts['admin'] = User::load(1); @@ -61,22 +61,22 @@ public function testUserListing() { $this->assertResponse(200, 'The admin user has access to the user admin listing.'); $result = $this->xpath('//table[contains(@class, "responsive-enabled")]/tbody/tr'); - $result_accounts = array(); + $result_accounts = []; foreach ($result as $account) { $name = (string) $account->td[0]->span; - $roles = array(); + $roles = []; if (isset($account->td[2]->div->ul)) { foreach ($account->td[2]->div->ul->li as $element) { $roles[] = (string) $element; } } - $result_accounts[$name] = array( + $result_accounts[$name] = [ 'name' => $name, 'status' => (string) $account->td[1], 'roles' => $roles, 'member_for' => (string) $account->td[3], 'last_access' => (string) $account->td[4], - ); + ]; } $this->assertFalse(array_keys(array_diff_key($result_accounts, $accounts)), 'Ensure all accounts are listed.'); @@ -84,7 +84,7 @@ public function testUserListing() { $this->assertEqual($values['status'] == t('active'), $accounts[$name]->status->value, 'Ensure the status is displayed properly.'); } - $expected_roles = array('custom_role_1', 'custom_role_2'); + $expected_roles = ['custom_role_1', 'custom_role_2']; $this->assertEqual($result_accounts[$role_account_name]['roles'], $expected_roles, 'Ensure roles are listed properly.'); $this->assertEqual($result_accounts[$timestamp_user]['member_for'], \Drupal::service('date.formatter')->formatTimeDiffSince($accounts[$timestamp_user]->created->value), 'Ensure the right member time is displayed.'); diff --git a/core/modules/user/src/Tests/UserAdminSettingsFormTest.php b/core/modules/user/src/Tests/UserAdminSettingsFormTest.php index 2fba848b..b7741115 100644 --- a/core/modules/user/src/Tests/UserAdminSettingsFormTest.php +++ b/core/modules/user/src/Tests/UserAdminSettingsFormTest.php @@ -16,33 +16,33 @@ protected function setUp() { parent::setUp(); $this->form = AccountSettingsForm::create($this->container); - $this->values = array( - 'anonymous' => array( + $this->values = [ + 'anonymous' => [ '#value' => $this->randomString(10), '#config_name' => 'user.settings', '#config_key' => 'anonymous', - ), - 'user_mail_cancel_confirm_body' => array( + ], + 'user_mail_cancel_confirm_body' => [ '#value' => $this->randomString(), '#config_name' => 'user.mail', '#config_key' => 'cancel_confirm.body', - ), - 'user_mail_cancel_confirm_subject' => array( + ], + 'user_mail_cancel_confirm_subject' => [ '#value' => $this->randomString(20), '#config_name' => 'user.mail', '#config_key' => 'cancel_confirm.subject', - ), - 'register_pending_approval_admin_body' => array( + ], + 'register_pending_approval_admin_body' => [ '#value' => $this->randomString(), '#config_name' => 'user.mail', '#config_key' => 'register_pending_approval_admin.body', - ), - 'register_pending_approval_admin_subject' => array( + ], + 'register_pending_approval_admin_subject' => [ '#value' => $this->randomString(20), '#config_name' => 'user.mail', '#config_key' => 'register_pending_approval_admin.subject', - ), - ); + ], + ]; } } diff --git a/core/modules/user/src/Tests/UserAdminTest.php b/core/modules/user/src/Tests/UserAdminTest.php index 8d4a22be..f3ee85a9 100644 --- a/core/modules/user/src/Tests/UserAdminTest.php +++ b/core/modules/user/src/Tests/UserAdminTest.php @@ -17,28 +17,28 @@ class UserAdminTest extends WebTestBase { * * @var array */ - public static $modules = array('taxonomy', 'views'); + public static $modules = ['taxonomy', 'views']; /** * Registers a user and deletes it. */ - function testUserAdmin() { + public function testUserAdmin() { $config = $this->config('user.settings'); $user_a = $this->drupalCreateUser(); $user_a->name = 'User A'; $user_a->mail = $this->randomMachineName() . '@example.com'; $user_a->save(); - $user_b = $this->drupalCreateUser(array('administer taxonomy')); + $user_b = $this->drupalCreateUser(['administer taxonomy']); $user_b->name = 'User B'; $user_b->save(); - $user_c = $this->drupalCreateUser(array('administer taxonomy')); + $user_c = $this->drupalCreateUser(['administer taxonomy']); $user_c->name = 'User C'; $user_c->save(); $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create admin user to delete registered user. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); // Use a predictable name so that we can reliably order the user admin page // by name. $admin_user->name = 'Admin user'; @@ -51,11 +51,11 @@ function testUserAdmin() { $this->assertText($admin_user->getUsername(), 'Found Admin user on admin users page'); // Test for existence of edit link in table. - $link = $user_a->link(t('Edit'), 'edit-form', array('query' => array('destination' => $user_a->url('collection')))); + $link = $user_a->link(t('Edit'), 'edit-form', ['query' => ['destination' => $user_a->url('collection')]]); $this->assertRaw($link, 'Found user A edit link on admin users page'); // Test exposed filter elements. - foreach (array('user', 'role', 'permission', 'status') as $field) { + foreach (['user', 'role', 'permission', 'status'] as $field) { $this->assertField("edit-$field", "$field exposed filter found."); } // Make sure the reduce duplicates element from the ManyToOneHelper is not @@ -63,18 +63,18 @@ function testUserAdmin() { $this->assertNoField('edit-reduce-duplicates', 'Reduce duplicates form element not found in exposed filters.'); // Filter the users by name/email. - $this->drupalGet('admin/people', array('query' => array('user' => $user_a->getUsername()))); + $this->drupalGet('admin/people', ['query' => ['user' => $user_a->getUsername()]]); $result = $this->xpath('//table/tbody/tr'); $this->assertEqual(1, count($result), 'Filter by username returned the right amount.'); $this->assertEqual($user_a->getUsername(), (string) $result[0]->td[1]->span, 'Filter by username returned the right user.'); - $this->drupalGet('admin/people', array('query' => array('user' => $user_a->getEmail()))); + $this->drupalGet('admin/people', ['query' => ['user' => $user_a->getEmail()]]); $result = $this->xpath('//table/tbody/tr'); $this->assertEqual(1, count($result), 'Filter by username returned the right amount.'); $this->assertEqual($user_a->getUsername(), (string) $result[0]->td[1]->span, 'Filter by username returned the right user.'); // Filter the users by permission 'administer taxonomy'. - $this->drupalGet('admin/people', array('query' => array('permission' => 'administer taxonomy'))); + $this->drupalGet('admin/people', ['query' => ['permission' => 'administer taxonomy']]); // Check if the correct users show up. $this->assertNoText($user_a->getUsername(), 'User A not on filtered by perm admin users page'); @@ -84,7 +84,7 @@ function testUserAdmin() { // Filter the users by role. Grab the system-generated role name for User C. $roles = $user_c->getRoles(); unset($roles[array_search(RoleInterface::AUTHENTICATED_ID, $roles)]); - $this->drupalGet('admin/people', array('query' => array('role' => reset($roles)))); + $this->drupalGet('admin/people', ['query' => ['role' => reset($roles)]]); // Check if the correct users show up when filtered by role. $this->assertNoText($user_a->getUsername(), 'User A not on filtered by role on admin users page'); @@ -94,53 +94,53 @@ function testUserAdmin() { // Test blocking of a user. $account = $user_storage->load($user_c->id()); $this->assertTrue($account->isActive(), 'User C not blocked'); - $edit = array(); + $edit = []; $edit['action'] = 'user_block_user_action'; $edit['user_bulk_form[4]'] = TRUE; $config ->set('notify.status_blocked', TRUE) ->save(); - $this->drupalPostForm('admin/people', $edit, t('Apply to selected items'), array( + $this->drupalPostForm('admin/people', $edit, t('Apply to selected items'), [ // Sort the table by username so that we know reliably which user will be // targeted with the blocking action. - 'query' => array('order' => 'name', 'sort' => 'asc') - )); + 'query' => ['order' => 'name', 'sort' => 'asc'] + ]); $site_name = $this->config('system.site')->get('name'); $this->assertMailString('body', 'Your account on ' . $site_name . ' has been blocked.', 1, 'Blocked message found in the mail sent to user C.'); - $user_storage->resetCache(array($user_c->id())); + $user_storage->resetCache([$user_c->id()]); $account = $user_storage->load($user_c->id()); $this->assertTrue($account->isBlocked(), 'User C blocked'); // Test filtering on admin page for blocked users - $this->drupalGet('admin/people', array('query' => array('status' => 2))); + $this->drupalGet('admin/people', ['query' => ['status' => 2]]); $this->assertNoText($user_a->getUsername(), 'User A not on filtered by status on admin users page'); $this->assertNoText($user_b->getUsername(), 'User B not on filtered by status on admin users page'); $this->assertText($user_c->getUsername(), 'User C on filtered by status on admin users page'); // Test unblocking of a user from /admin/people page and sending of activation mail - $editunblock = array(); + $editunblock = []; $editunblock['action'] = 'user_unblock_user_action'; $editunblock['user_bulk_form[4]'] = TRUE; - $this->drupalPostForm('admin/people', $editunblock, t('Apply to selected items'), array( + $this->drupalPostForm('admin/people', $editunblock, t('Apply to selected items'), [ // Sort the table by username so that we know reliably which user will be // targeted with the blocking action. - 'query' => array('order' => 'name', 'sort' => 'asc') - )); - $user_storage->resetCache(array($user_c->id())); + 'query' => ['order' => 'name', 'sort' => 'asc'] + ]); + $user_storage->resetCache([$user_c->id()]); $account = $user_storage->load($user_c->id()); $this->assertTrue($account->isActive(), 'User C unblocked'); $this->assertMail("to", $account->getEmail(), "Activation mail sent to user C"); // Test blocking and unblocking another user from /user/[uid]/edit form and sending of activation mail - $user_d = $this->drupalCreateUser(array()); - $user_storage->resetCache(array($user_d->id())); + $user_d = $this->drupalCreateUser([]); + $user_storage->resetCache([$user_d->id()]); $account1 = $user_storage->load($user_d->id()); - $this->drupalPostForm('user/' . $account1->id() . '/edit', array('status' => 0), t('Save')); - $user_storage->resetCache(array($user_d->id())); + $this->drupalPostForm('user/' . $account1->id() . '/edit', ['status' => 0], t('Save')); + $user_storage->resetCache([$user_d->id()]); $account1 = $user_storage->load($user_d->id()); $this->assertTrue($account1->isBlocked(), 'User D blocked'); - $this->drupalPostForm('user/' . $account1->id() . '/edit', array('status' => TRUE), t('Save')); - $user_storage->resetCache(array($user_d->id())); + $this->drupalPostForm('user/' . $account1->id() . '/edit', ['status' => TRUE], t('Save')); + $user_storage->resetCache([$user_d->id()]); $account1 = $user_storage->load($user_d->id()); $this->assertTrue($account1->isActive(), 'User D unblocked'); $this->assertMail("to", $account1->getEmail(), "Activation mail sent to user D"); @@ -149,9 +149,9 @@ function testUserAdmin() { /** * Tests the alternate notification email address for user mails. */ - function testNotificationEmailAddress() { + public function testNotificationEmailAddress() { // Test that the Notification Email address field is on the config page. - $admin_user = $this->drupalCreateUser(array('administer users', 'administer account settings')); + $admin_user = $this->drupalCreateUser(['administer users', 'administer account settings']); $this->drupalLogin($admin_user); $this->drupalGet('admin/config/people/accounts'); $this->assertRaw('id="edit-mail-notification-address"', 'Notification Email address field exists'); @@ -173,27 +173,27 @@ function testNotificationEmailAddress() { ->set('mail_notification', $notify_address) ->save(); // Register a new user account. - $edit = array(); + $edit = []; $edit['name'] = $this->randomMachineName(); $edit['mail'] = $edit['name'] . '@example.com'; $this->drupalPostForm('user/register', $edit, t('Create new account')); $subject = 'Account details for ' . $edit['name'] . ' at ' . $system->get('name') . ' (pending admin approval)'; // Ensure that admin notification mail is sent to the configured // Notification Email address. - $admin_mail = $this->drupalGetMails(array( + $admin_mail = $this->drupalGetMails([ 'to' => $notify_address, 'from' => $server_address, 'subject' => $subject, - )); + ]); $this->assertTrue(count($admin_mail), 'New user mail to admin is sent to configured Notification Email address'); // Ensure that user notification mail is sent from the configured // Notification Email address. - $user_mail = $this->drupalGetMails(array( + $user_mail = $this->drupalGetMails([ 'to' => $edit['mail'], 'from' => $server_address, 'reply-to' => $notify_address, 'subject' => $subject, - )); + ]); $this->assertTrue(count($user_mail), 'New user mail to user is sent from configured Notification Email address'); } diff --git a/core/modules/user/src/Tests/UserBlocksTest.php b/core/modules/user/src/Tests/UserBlocksTest.php index 9216a276..0a4c619d 100644 --- a/core/modules/user/src/Tests/UserBlocksTest.php +++ b/core/modules/user/src/Tests/UserBlocksTest.php @@ -2,6 +2,7 @@ namespace Drupal\user\Tests; +use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber; use Drupal\simpletest\WebTestBase; /** @@ -16,7 +17,7 @@ class UserBlocksTest extends WebTestBase { * * @var array */ - public static $modules = array('block', 'views'); + public static $modules = ['block', 'views']; /** * A user with the 'administer blocks' permission. @@ -28,7 +29,7 @@ class UserBlocksTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->adminUser = $this->drupalCreateUser(array('administer blocks')); + $this->adminUser = $this->drupalCreateUser(['administer blocks']); $this->drupalLogin($this->adminUser); $this->drupalPlaceBlock('user_login_block'); $this->drupalLogout($this->adminUser); @@ -37,7 +38,7 @@ protected function setUp() { /** * Tests that user login block is hidden from user/login. */ - function testUserLoginBlockVisibility() { + public function testUserLoginBlockVisibility() { // Array keyed list where key being the URL address and value being expected // visibility as boolean type. $paths = [ @@ -61,12 +62,12 @@ function testUserLoginBlockVisibility() { /** * Test the user login block. */ - function testUserLoginBlock() { + public function testUserLoginBlock() { // Create a user with some permission that anonymous users lack. - $user = $this->drupalCreateUser(array('administer permissions')); + $user = $this->drupalCreateUser(['administer permissions']); // Log in using the block. - $edit = array(); + $edit = []; $edit['name'] = $user->getUsername(); $edit['pass'] = $user->pass_raw; $this->drupalPostForm('admin/people/permissions', $edit, t('Log in')); @@ -77,21 +78,41 @@ function testUserLoginBlock() { // Now, log out and repeat with a non-403 page. $this->drupalLogout(); - $this->drupalPostForm('filter/tips', $edit, t('Log in')); + $this->drupalGet('filter/tips'); + $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + $this->drupalPostForm(NULL, $edit, t('Log in')); + $this->assertNoText(t('User login'), 'Logged in.'); + $this->assertPattern('!!', 'Still on the same page after login for allowed page'); + + // Log out again and repeat with a non-403 page including query arguments. + $this->drupalLogout(); + $this->drupalGet('filter/tips', ['query' => ['foo' => 'bar']]); + $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + $this->drupalPostForm(NULL, $edit, t('Log in')); + $this->assertNoText(t('User login'), 'Logged in.'); + $this->assertPattern('!!', 'Still on the same page after login for allowed page'); + $this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=bar') !== FALSE, 'Correct query arguments are displayed after login'); + + // Repeat with different query arguments. + $this->drupalLogout(); + $this->drupalGet('filter/tips', ['query' => ['foo' => 'baz']]); + $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + $this->drupalPostForm(NULL, $edit, t('Log in')); $this->assertNoText(t('User login'), 'Logged in.'); $this->assertPattern('!!', 'Still on the same page after login for allowed page'); + $this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=baz') !== FALSE, 'Correct query arguments are displayed after login'); // Check that the user login block is not vulnerable to information // disclosure to third party sites. $this->drupalLogout(); - $this->drupalPostForm('http://example.com/', $edit, t('Log in'), array('external' => FALSE)); + $this->drupalPostForm('http://example.com/', $edit, t('Log in'), ['external' => FALSE]); // Check that we remain on the site after login. $this->assertUrl($user->url('canonical', ['absolute' => TRUE]), [], 'Redirected to user profile page after login from the frontpage'); // Verify that form validation errors are displayed immediately for forms // in blocks and not on subsequent page requests. $this->drupalLogout(); - $edit = array(); + $edit = []; $edit['name'] = 'foo'; $edit['pass'] = 'invalid password'; $this->drupalPostForm('filter/tips', $edit, t('Log in')); @@ -103,13 +124,13 @@ function testUserLoginBlock() { /** * Test the Who's Online block. */ - function testWhosOnlineBlock() { + public function testWhosOnlineBlock() { $block = $this->drupalPlaceBlock('views_block:who_s_online-who_s_online_block'); // Generate users. - $user1 = $this->drupalCreateUser(array('access user profiles')); - $user2 = $this->drupalCreateUser(array()); - $user3 = $this->drupalCreateUser(array()); + $user1 = $this->drupalCreateUser(['access user profiles']); + $user2 = $this->drupalCreateUser([]); + $user3 = $this->drupalCreateUser([]); // Update access of two users to be within the active timespan. $this->updateAccess($user1->id()); @@ -138,7 +159,7 @@ function testWhosOnlineBlock() { private function updateAccess($uid, $access = REQUEST_TIME) { db_update('users_field_data') ->condition('uid', $uid) - ->fields(array('access' => $access)) + ->fields(['access' => $access]) ->execute(); } diff --git a/core/modules/user/src/Tests/UserCreateFailMailTest.php b/core/modules/user/src/Tests/UserCreateFailMailTest.php deleted file mode 100644 index a51229a3..00000000 --- a/core/modules/user/src/Tests/UserCreateFailMailTest.php +++ /dev/null @@ -1,45 +0,0 @@ -drupalCreateUser(array('administer users')); - $this->drupalLogin($user); - - // Replace the mail functionality with a fake, malfunctioning service. - $this->config('system.mail')->set('interface.default', 'test_php_mail_failure')->save(); - // Create a user, but fail to send an email. - $name = $this->randomMachineName(); - $edit = array( - 'name' => $name, - 'mail' => $this->randomMachineName() . '@example.com', - 'pass[pass1]' => $pass = $this->randomString(), - 'pass[pass2]' => $pass, - 'notify' => TRUE, - ); - $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); - - $this->assertText(t('Unable to send email. Contact the site administrator if the problem persists.')); - $this->assertNoText(t('A welcome message with further instructions has been emailed to the new user @name.', array('@name' => $edit['name']))); - } - -} diff --git a/core/modules/user/src/Tests/UserCreateTest.php b/core/modules/user/src/Tests/UserCreateTest.php index efc7ddf7..7b534435 100644 --- a/core/modules/user/src/Tests/UserCreateTest.php +++ b/core/modules/user/src/Tests/UserCreateTest.php @@ -18,14 +18,14 @@ class UserCreateTest extends WebTestBase { * * @var array */ - public static $modules = array('image'); + public static $modules = ['image']; /** * Create a user through the administration interface and ensure that it * displays in the user list. */ public function testUserAdd() { - $user = $this->drupalCreateUser(array('administer users')); + $user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($user); $this->assertEqual($user->getCreatedTime(), REQUEST_TIME, 'Creating a user sets default "created" timestamp.'); @@ -33,18 +33,18 @@ public function testUserAdd() { // Create a field. $field_name = 'test_field'; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'user', 'module' => 'image', 'type' => 'image', 'cardinality' => 1, 'locked' => FALSE, - 'indexes' => array('target_id' => array('target_id')), - 'settings' => array( + 'indexes' => ['target_id' => ['target_id']], + 'settings' => [ 'uri_scheme' => 'public', - ), - ))->save(); + ], + ])->save(); FieldConfig::create([ 'field_name' => $field_name, @@ -53,7 +53,7 @@ public function testUserAdd() { 'bundle' => 'user', 'description' => t('Your virtual face or picture.'), 'required' => FALSE, - 'settings' => array( + 'settings' => [ 'file_extensions' => 'png gif jpg jpeg', 'file_directory' => 'pictures', 'max_filesize' => '30 KB', @@ -61,7 +61,7 @@ public function testUserAdd() { 'title_field' => 0, 'max_resolution' => '85x85', 'min_resolution' => '', - ), + ], ])->save(); // Test user creation page for valid fields. @@ -86,23 +86,23 @@ public function testUserAdd() { // We create two users, notifying one and not notifying the other, to // ensure that the tests work in both cases. - foreach (array(FALSE, TRUE) as $notify) { + foreach ([FALSE, TRUE] as $notify) { $name = $this->randomMachineName(); - $edit = array( + $edit = [ 'name' => $name, 'mail' => $this->randomMachineName() . '@example.com', 'pass[pass1]' => $pass = $this->randomString(), 'pass[pass2]' => $pass, 'notify' => $notify, - ); + ]; $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); if ($notify) { - $this->assertText(t('A welcome message with further instructions has been emailed to the new user @name.', array('@name' => $edit['name'])), 'User created'); + $this->assertText(t('A welcome message with further instructions has been emailed to the new user @name.', ['@name' => $edit['name']]), 'User created'); $this->assertEqual(count($this->drupalGetMails()), 1, 'Notification email sent'); } else { - $this->assertText(t('Created a new user account for @name. No email has been sent.', array('@name' => $edit['name'])), 'User created'); + $this->assertText(t('Created a new user account for @name. No email has been sent.', ['@name' => $edit['name']]), 'User created'); $this->assertEqual(count($this->drupalGetMails()), 0, 'Notification email not sent'); } @@ -115,13 +115,13 @@ public function testUserAdd() { // Test that the password '0' is considered a password. // @see https://www.drupal.org/node/2563751. $name = $this->randomMachineName(); - $edit = array( + $edit = [ 'name' => $name, 'mail' => $this->randomMachineName() . '@example.com', 'pass[pass1]' => 0, 'pass[pass2]' => 0, 'notify' => FALSE, - ); + ]; $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); $this->assertText("Created a new user account for $name. No email has been sent"); $this->assertNoText('Password field is required'); diff --git a/core/modules/user/src/Tests/UserDeleteTest.php b/core/modules/user/src/Tests/UserDeleteTest.php deleted file mode 100644 index dbb3002a..00000000 --- a/core/modules/user/src/Tests/UserDeleteTest.php +++ /dev/null @@ -1,55 +0,0 @@ -drupalCreateUser(array('access user profiles')); - $user_b = $this->drupalCreateUser(array('access user profiles')); - $user_c = $this->drupalCreateUser(array('access user profiles')); - - $uids = array($user_a->id(), $user_b->id(), $user_c->id()); - - // These users should have a role - $query = db_select('user__roles', 'r'); - $roles_created = $query - ->fields('r', array('entity_id')) - ->condition('entity_id', $uids, 'IN') - ->countQuery() - ->execute() - ->fetchField(); - - $this->assertTrue($roles_created > 0, 'Role assignments created for new users and deletion of role assignments can be tested'); - // We should be able to load one of the users. - $this->assertTrue(User::load($user_a->id()), 'User is created and deletion of user can be tested'); - // Delete the users. - user_delete_multiple($uids); - // Test if the roles assignments are deleted. - $query = db_select('user__roles', 'r'); - $roles_after_deletion = $query - ->fields('r', array('entity_id')) - ->condition('entity_id', $uids, 'IN') - ->countQuery() - ->execute() - ->fetchField(); - $this->assertTrue($roles_after_deletion == 0, 'Role assignments deleted along with users'); - // Test if the users are deleted, User::load() will return NULL. - $this->assertNull(User::load($user_a->id()), format_string('User with id @uid deleted.', array('@uid' => $user_a->id()))); - $this->assertNull(User::load($user_b->id()), format_string('User with id @uid deleted.', array('@uid' => $user_b->id()))); - $this->assertNull(User::load($user_c->id()), format_string('User with id @uid deleted.', array('@uid' => $user_c->id()))); - } - -} diff --git a/core/modules/user/src/Tests/UserEditTest.php b/core/modules/user/src/Tests/UserEditTest.php index 225b1944..6f1e3699 100644 --- a/core/modules/user/src/Tests/UserEditTest.php +++ b/core/modules/user/src/Tests/UserEditTest.php @@ -14,19 +14,26 @@ class UserEditTest extends WebTestBase { /** * Test user edit page. */ - function testUserEdit() { + public function testUserEdit() { // Test user edit functionality. - $user1 = $this->drupalCreateUser(array('change own username')); - $user2 = $this->drupalCreateUser(array()); + $user1 = $this->drupalCreateUser(['change own username']); + $user2 = $this->drupalCreateUser([]); $this->drupalLogin($user1); // Test that error message appears when attempting to use a non-unique user name. $edit['name'] = $user2->getUsername(); $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); - $this->assertRaw(t('The username %name is already taken.', array('%name' => $edit['name']))); + $this->assertRaw(t('The username %name is already taken.', ['%name' => $edit['name']])); + + // Check that the default value in user name field + // is the raw value and not a formatted one. + \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE); + \Drupal::service('module_installer')->install(['user_hooks_test']); + $this->drupalGet('user/' . $user1->id() . '/edit'); + $this->assertFieldByName('name', $user1->getAccountName()); // Check that filling out a single password field does not validate. - $edit = array(); + $edit = []; $edit['pass[pass1]'] = ''; $edit['pass[pass2]'] = $this->randomMachineName(); $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); @@ -39,21 +46,21 @@ function testUserEdit() { // Test that the error message appears when attempting to change the mail or // pass without the current password. - $edit = array(); + $edit = []; $edit['mail'] = $this->randomMachineName() . '@new.example.com'; $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); - $this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", array('%name' => t('Email')))); + $this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", ['%name' => t('Email')])); $edit['current_pass'] = $user1->pass_raw; $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); $this->assertRaw(t("The changes have been saved.")); // Test that the user must enter current password before changing passwords. - $edit = array(); + $edit = []; $edit['pass[pass1]'] = $new_pass = $this->randomMachineName(); $edit['pass[pass2]'] = $new_pass; $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); - $this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", array('%name' => t('Password')))); + $this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", ['%name' => t('Password')])); // Try again with the current password. $edit['current_pass'] = $user1->pass_raw; @@ -83,20 +90,20 @@ function testUserEdit() { // Check that the user status field has the correct value and that it is // properly displayed. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); $this->drupalGet('user/' . $user1->id() . '/edit'); $this->assertNoFieldChecked('edit-status-0'); $this->assertFieldChecked('edit-status-1'); - $edit = array('status' => 0); + $edit = ['status' => 0]; $this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save')); $this->assertText(t('The changes have been saved.')); $this->assertFieldChecked('edit-status-0'); $this->assertNoFieldChecked('edit-status-1'); - $edit = array('status' => 1); + $edit = ['status' => 1]; $this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save')); $this->assertText(t('The changes have been saved.')); $this->assertNoFieldChecked('edit-status-0'); @@ -124,16 +131,16 @@ public function testUserWith0Password() { /** * Tests editing of a user account without an email address. */ - function testUserWithoutEmailEdit() { + public function testUserWithoutEmailEdit() { // Test that an admin can edit users without an email address. - $admin = $this->drupalCreateUser(array('administer users')); + $admin = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin); // Create a regular user. - $user1 = $this->drupalCreateUser(array()); + $user1 = $this->drupalCreateUser([]); // This user has no email address. $user1->mail = ''; $user1->save(); - $this->drupalPostForm("user/" . $user1->id() . "/edit", array('mail' => ''), t('Save')); + $this->drupalPostForm("user/" . $user1->id() . "/edit", ['mail' => ''], t('Save')); $this->assertRaw(t("The changes have been saved.")); } diff --git a/core/modules/user/src/Tests/UserEditedOwnAccountTest.php b/core/modules/user/src/Tests/UserEditedOwnAccountTest.php deleted file mode 100644 index 6c058bfa..00000000 --- a/core/modules/user/src/Tests/UserEditedOwnAccountTest.php +++ /dev/null @@ -1,43 +0,0 @@ -config('user.settings')->set('register', USER_REGISTER_ADMINISTRATORS_ONLY)->save(); - - // Create a new user account and log in. - $account = $this->drupalCreateUser(array('change own username')); - $this->drupalLogin($account); - - // Change own username. - $edit = array(); - $edit['name'] = $this->randomMachineName(); - $this->drupalPostForm('user/' . $account->id() . '/edit', $edit, t('Save')); - - // Log out. - $this->drupalLogout(); - - // Set the new name on the user account and attempt to log back in. - $account->name = $edit['name']; - $this->drupalLogin($account); - } - -} diff --git a/core/modules/user/src/Tests/UserLanguageCreationTest.php b/core/modules/user/src/Tests/UserLanguageCreationTest.php index 08ca7077..0dd29079 100644 --- a/core/modules/user/src/Tests/UserLanguageCreationTest.php +++ b/core/modules/user/src/Tests/UserLanguageCreationTest.php @@ -18,14 +18,14 @@ class UserLanguageCreationTest extends WebTestBase { * * @var array */ - public static $modules = array('user', 'language'); + public static $modules = ['user', 'language']; /** * Functional test for language handling during user creation. */ - function testLocalUserCreation() { + public function testLocalUserCreation() { // User to add and remove language and create new users. - $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'administer users')); + $admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages', 'administer users']); $this->drupalLogin($admin_user); // Add predefined language. @@ -33,9 +33,9 @@ function testLocalUserCreation() { ConfigurableLanguage::createFromLangcode($langcode)->save(); // Set language negotiation. - $edit = array( + $edit = [ 'language_interface[enabled][language-url]' => TRUE, - ); + ]; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); $this->assertText(t('Language detection configuration saved.'), 'Set language negotiation.'); @@ -47,12 +47,12 @@ function testLocalUserCreation() { // Create a user with the admin/people/create form and check if the correct // language is set. $username = $this->randomMachineName(10); - $edit = array( + $edit = [ 'name' => $username, 'mail' => $this->randomMachineName(4) . '@example.com', 'pass[pass1]' => $username, 'pass[pass2]' => $username, - ); + ]; $this->drupalPostForm($langcode . '/admin/people/create', $edit, t('Create new account')); @@ -67,10 +67,10 @@ function testLocalUserCreation() { $this->assertNoFieldByName('language[fr]', 'Language selector is not accessible.'); $username = $this->randomMachineName(10); - $edit = array( + $edit = [ 'name' => $username, 'mail' => $this->randomMachineName(4) . '@example.com', - ); + ]; $this->drupalPostForm($langcode . '/user/register', $edit, t('Create new account')); @@ -88,10 +88,10 @@ function testLocalUserCreation() { // Set pass_raw so we can log in the new user. $user->pass_raw = $this->randomMachineName(10); - $edit = array( + $edit = [ 'pass[pass1]' => $user->pass_raw, 'pass[pass2]' => $user->pass_raw, - ); + ]; $this->drupalPostForm($user_edit, $edit, t('Save')); diff --git a/core/modules/user/src/Tests/UserLoginTest.php b/core/modules/user/src/Tests/UserLoginTest.php index af00c747..d92c1c7a 100644 --- a/core/modules/user/src/Tests/UserLoginTest.php +++ b/core/modules/user/src/Tests/UserLoginTest.php @@ -15,15 +15,15 @@ class UserLoginTest extends WebTestBase { /** * Tests login with destination. */ - function testLoginCacheTagsAndDestination() { + public function testLoginCacheTagsAndDestination() { $this->drupalGet('user/login'); // The user login form says "Enter your username.", hence it // depends on config:system.site, and its cache tags should be present. $this->assertCacheTag('config:system.site'); - $user = $this->drupalCreateUser(array()); - $this->drupalGet('user/login', array('query' => array('destination' => 'foo'))); - $edit = array('name' => $user->getUserName(), 'pass' => $user->pass_raw); + $user = $this->drupalCreateUser([]); + $this->drupalGet('user/login', ['query' => ['destination' => 'foo']]); + $edit = ['name' => $user->getUserName(), 'pass' => $user->pass_raw]; $this->drupalPostForm(NULL, $edit, t('Log in')); $this->assertUrl('foo', [], 'Redirected to the correct URL'); } @@ -31,14 +31,14 @@ function testLoginCacheTagsAndDestination() { /** * Test the global login flood control. */ - function testGlobalLoginFloodControl() { + public function testGlobalLoginFloodControl() { $this->config('user.flood') ->set('ip_limit', 10) // Set a high per-user limit out so that it is not relevant in the test. ->set('user_limit', 4000) ->save(); - $user1 = $this->drupalCreateUser(array()); + $user1 = $this->drupalCreateUser([]); $incorrect_user1 = clone $user1; $incorrect_user1->pass_raw .= 'incorrect'; @@ -68,18 +68,18 @@ function testGlobalLoginFloodControl() { /** * Test the per-user login flood control. */ - function testPerUserLoginFloodControl() { + public function testPerUserLoginFloodControl() { $this->config('user.flood') // Set a high global limit out so that it is not relevant in the test. ->set('ip_limit', 4000) ->set('user_limit', 3) ->save(); - $user1 = $this->drupalCreateUser(array()); + $user1 = $this->drupalCreateUser([]); $incorrect_user1 = clone $user1; $incorrect_user1->pass_raw .= 'incorrect'; - $user2 = $this->drupalCreateUser(array()); + $user2 = $this->drupalCreateUser([]); // Try 2 failed logins. for ($i = 0; $i < 2; $i++) { @@ -108,7 +108,7 @@ function testPerUserLoginFloodControl() { /** * Test that user password is re-hashed upon login after changing $count_log2. */ - function testPasswordRehashOnLogin() { + public function testPasswordRehashOnLogin() { // Determine default log2 for phpass hashing algorithm $default_count_log2 = 16; @@ -116,7 +116,7 @@ function testPasswordRehashOnLogin() { $password_hasher = $this->container->get('password'); // Create a new user and authenticate. - $account = $this->drupalCreateUser(array()); + $account = $this->drupalCreateUser([]); $password = $account->pass_raw; $this->drupalLogin($account); $this->drupalLogout(); @@ -129,13 +129,13 @@ function testPasswordRehashOnLogin() { // containing the necessary container builder code and then verify that the // users password gets rehashed during the login. $overridden_count_log2 = 19; - \Drupal::service('module_installer')->install(array('user_custom_phpass_params_test')); + \Drupal::service('module_installer')->install(['user_custom_phpass_params_test']); $this->resetAll(); $account->pass_raw = $password; $this->drupalLogin($account); // Load the stored user, which should have a different password hash now. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertIdentical($password_hasher->getCountLog2($account->getPassword()), $overridden_count_log2); $this->assertTrue($password_hasher->check($password, $account->getPassword())); @@ -154,20 +154,20 @@ function testPasswordRehashOnLogin() { * . * - Set to NULL to expect a failed login. */ - function assertFailedLogin($account, $flood_trigger = NULL) { - $edit = array( + public function assertFailedLogin($account, $flood_trigger = NULL) { + $edit = [ 'name' => $account->getUsername(), 'pass' => $account->pass_raw, - ); + ]; $this->drupalPostForm('user/login', $edit, t('Log in')); $this->assertNoFieldByXPath("//input[@name='pass' and @value!='']", NULL, 'Password value attribute is blank.'); if (isset($flood_trigger)) { if ($flood_trigger == 'user') { - $this->assertRaw(\Drupal::translation()->formatPlural($this->config('user.flood')->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array(':url' => \Drupal::url('user.pass')))); + $this->assertRaw(\Drupal::translation()->formatPlural($this->config('user.flood')->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', [':url' => \Drupal::url('user.pass')])); } else { // No uid, so the limit is IP-based. - $this->assertRaw(t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', array(':url' => \Drupal::url('user.pass')))); + $this->assertRaw(t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', [':url' => \Drupal::url('user.pass')])); } } else { diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/src/Tests/UserPasswordResetTest.php index f3463bf1..88fe72c6 100644 --- a/core/modules/user/src/Tests/UserPasswordResetTest.php +++ b/core/modules/user/src/Tests/UserPasswordResetTest.php @@ -61,7 +61,7 @@ protected function setUp() { // that it is definitely over a second ago. $account->login = REQUEST_TIME - mt_rand(10, 100000); db_update('users_field_data') - ->fields(array('login' => $account->getLastLoginTime())) + ->fields(['login' => $account->getLastLoginTime()]) ->condition('uid', $account->id()) ->execute(); } @@ -69,7 +69,7 @@ protected function setUp() { /** * Tests password reset functionality. */ - function testUserPasswordReset() { + public function testUserPasswordReset() { // Verify that accessing the password reset form without having the session // variables set results in an access denied message. $this->drupalGet(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()])); @@ -78,11 +78,11 @@ function testUserPasswordReset() { // Try to reset the password for an invalid account. $this->drupalGet('user/password'); - $edit = array('name' => $this->randomMachineName(32)); + $edit = ['name' => $this->randomMachineName(32)]; $this->drupalPostForm(NULL, $edit, t('Submit')); - $this->assertText(t('@name is not recognized as a username or an email address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.'); - $this->assertEqual(count($this->drupalGetMails(array('id' => 'user_password_reset'))), 0, 'No email was sent when requesting a password for an invalid account.'); + $this->assertText(t('@name is not recognized as a username or an email address.', ['@name' => $edit['name']]), 'Validation error message shown when trying to request password for invalid account.'); + $this->assertEqual(count($this->drupalGetMails(['id' => 'user_password_reset'])), 0, 'No email was sent when requesting a password for an invalid account.'); // Reset the password by username via the password reset page. $edit['name'] = $this->account->getUsername(); @@ -90,7 +90,7 @@ function testUserPasswordReset() { // Verify that the user was sent an email. $this->assertMail('to', $this->account->getEmail(), 'Password email sent to user.'); - $subject = t('Replacement login information for @username at @site', array('@username' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name'))); + $subject = t('Replacement login information for @username at @site', ['@username' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]); $this->assertMail('subject', $subject, 'Password reset email subject is correct.'); $resetURL = $this->getResetURL(); @@ -112,25 +112,25 @@ function testUserPasswordReset() { // Check successful login. $this->drupalPostForm(NULL, NULL, t('Log in')); $this->assertLink(t('Log out')); - $this->assertTitle(t('@name | @site', array('@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name'))), 'Logged in using password reset link.'); + $this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.'); // Make sure the ajax request from uploading a user picture does not // invalidate the reset token. $image = current($this->drupalGetTestFiles('image')); - $edit = array( + $edit = [ 'files[user_picture_0]' => drupal_realpath($image->uri), - ); + ]; $this->drupalPostAjaxForm(NULL, $edit, 'user_picture_0_upload_button'); // Change the forgotten password. $password = user_password(); - $edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password); + $edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password]; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('The changes have been saved.'), 'Forgotten password changed.'); // Verify that the password reset session has been destroyed. $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('Your current password is missing or incorrect; it\'s required to change the Password.'), 'Password needed to make profile changes.'); + $this->assertText(t("Your current password is missing or incorrect; it's required to change the Password."), 'Password needed to make profile changes.'); // Log out, and try to log in again using the same one-time link. $this->drupalLogout(); @@ -141,10 +141,10 @@ function testUserPasswordReset() { // Request a new password again, this time using the email address. $this->drupalGet('user/password'); // Count email messages before to compare with after. - $before = count($this->drupalGetMails(array('id' => 'user_password_reset'))); - $edit = array('name' => $this->account->getEmail()); + $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); + $edit = ['name' => $this->account->getEmail()]; $this->drupalPostForm(NULL, $edit, t('Submit')); - $this->assertTrue( count($this->drupalGetMails(array('id' => 'user_password_reset'))) === $before + 1, 'Email sent when requesting password reset using email address.'); + $this->assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before + 1, 'Email sent when requesting password reset using email address.'); // Visit the user edit page without pass-reset-token and make sure it does // not cause an error. @@ -173,15 +173,15 @@ function testUserPasswordReset() { // Verify a blocked user can not request a new password. $this->drupalGet('user/password'); // Count email messages before to compare with after. - $before = count($this->drupalGetMails(array('id' => 'user_password_reset'))); - $edit = array('name' => $blocked_account->getUsername()); + $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); + $edit = ['name' => $blocked_account->getUsername()]; $this->drupalPostForm(NULL, $edit, t('Submit')); - $this->assertRaw(t('%name is blocked or has not been activated yet.', array('%name' => $blocked_account->getUsername())), 'Notified user blocked accounts can not request a new password'); - $this->assertTrue(count($this->drupalGetMails(array('id' => 'user_password_reset'))) === $before, 'No email was sent when requesting password reset for a blocked account'); + $this->assertRaw(t('%name is blocked or has not been activated yet.', ['%name' => $blocked_account->getUsername()]), 'Notified user blocked accounts can not request a new password'); + $this->assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before, 'No email was sent when requesting password reset for a blocked account'); // Verify a password reset link is invalidated when the user's email address changes. $this->drupalGet('user/password'); - $edit = array('name' => $this->account->getUsername()); + $edit = ['name' => $this->account->getUsername()]; $this->drupalPostForm(NULL, $edit, t('Submit')); $old_email_reset_link = $this->getResetURL(); $this->account->setEmail("1" . $this->account->getEmail()); @@ -193,12 +193,12 @@ function testUserPasswordReset() { // Verify a password reset link will automatically log a user when /login is // appended. $this->drupalGet('user/password'); - $edit = array('name' => $this->account->getUsername()); + $edit = ['name' => $this->account->getUsername()]; $this->drupalPostForm(NULL, $edit, t('Submit')); $reset_url = $this->getResetURL(); $this->drupalGet($reset_url . '/login'); $this->assertLink(t('Log out')); - $this->assertTitle(t('@name | @site', array('@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name'))), 'Logged in using password reset link.'); + $this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.'); // Ensure blocked and deleted accounts can't access the user.reset.login // route. @@ -221,7 +221,7 @@ public function getResetURL() { // Assume the most recent email. $_emails = $this->drupalGetMails(); $email = end($_emails); - $urls = array(); + $urls = []; preg_match('#.+user/reset/.+#', $email['body'], $urls); return $urls[0]; @@ -264,7 +264,7 @@ public function testUserPasswordResetLoggedIn() { // Change the password. $password = user_password(); - $edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password); + $edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password]; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('The changes have been saved.'), 'Password changed.'); @@ -282,15 +282,15 @@ public function testUserPasswordResetLoggedIn() { */ public function testUserResetPasswordTextboxFilled() { $this->drupalGet('user/login'); - $edit = array( + $edit = [ 'name' => $this->randomMachineName(), 'pass' => $this->randomMachineName(), - ); + ]; $this->drupalPostForm('user/login', $edit, t('Log in')); $this->assertRaw(t('Unrecognized username or password. Forgot your password?', - array(':password' => \Drupal::url('user.pass', [], array('query' => array('name' => $edit['name'])))))); + [':password' => \Drupal::url('user.pass', [], ['query' => ['name' => $edit['name']]])])); unset($edit['pass']); - $this->drupalGet('user/password', array('query' => array('name' => $edit['name']))); + $this->drupalGet('user/password', ['query' => ['name' => $edit['name']]]); $this->assertFieldByName('name', $edit['name'], 'User name found.'); // Ensure the name field value is not cached. $this->drupalGet('user/password'); @@ -300,10 +300,10 @@ public function testUserResetPasswordTextboxFilled() { /** * Make sure that users cannot forge password reset URLs of other users. */ - function testResetImpersonation() { + public function testResetImpersonation() { // Create two identical user accounts except for the user name. They must // have the same empty password, so we can't use $this->drupalCreateUser(). - $edit = array(); + $edit = []; $edit['name'] = $this->randomMachineName(); $edit['mail'] = $edit['name'] . '@example.com'; $edit['status'] = 1; @@ -333,7 +333,7 @@ function testResetImpersonation() { $this->drupalGet($attack_reset_url); $this->drupalPostForm(NULL, NULL, t('Log in')); $this->assertNoText($user2->getUsername(), 'The invalid password reset page does not show the user name.'); - $this->assertUrl('user/password', array(), 'The user is redirected to the password reset request page.'); + $this->assertUrl('user/password', [], 'The user is redirected to the password reset request page.'); $this->assertText('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'); } diff --git a/core/modules/user/src/Tests/UserPermissionsTest.php b/core/modules/user/src/Tests/UserPermissionsTest.php index 5e3ecd54..4f9e260a 100644 --- a/core/modules/user/src/Tests/UserPermissionsTest.php +++ b/core/modules/user/src/Tests/UserPermissionsTest.php @@ -31,7 +31,7 @@ class UserPermissionsTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->adminUser = $this->drupalCreateUser(array('administer permissions', 'access user profiles', 'administer site configuration', 'administer modules', 'administer account settings')); + $this->adminUser = $this->drupalCreateUser(['administer permissions', 'access user profiles', 'administer site configuration', 'administer modules', 'administer account settings']); // Find the new role ID. $all_rids = $this->adminUser->getRoles(); @@ -42,7 +42,7 @@ protected function setUp() { /** * Test changing user permissions through the permissions page. */ - function testUserPermissionChanges() { + public function testUserPermissionChanges() { $permissions_hash_generator = $this->container->get('user_permissions_hash_generator'); $storage = $this->container->get('entity.manager')->getStorage('user_role'); @@ -59,7 +59,7 @@ function testUserPermissionChanges() { // Add a permission. $this->assertFalse($account->hasPermission('administer users'), 'User does not have "administer users" permission.'); - $edit = array(); + $edit = []; $edit[$rid . '[administer users]'] = TRUE; $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), 'Successful save message displayed.'); @@ -72,7 +72,7 @@ function testUserPermissionChanges() { // Remove a permission. $this->assertTrue($account->hasPermission('access user profiles'), 'User has "access user profiles" permission.'); - $edit = array(); + $edit = []; $edit[$rid . '[access user profiles]'] = FALSE; $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), 'Successful save message displayed.'); @@ -92,7 +92,7 @@ function testUserPermissionChanges() { /** * Test assigning of permissions for the administrator role. */ - function testAdministratorRole() { + public function testAdministratorRole() { $this->drupalLogin($this->adminUser); $this->drupalGet('admin/config/people/accounts'); @@ -102,7 +102,7 @@ function testAdministratorRole() { $this->assertFalse(Role::load($this->rid)->isAdmin()); // Set the user's role to be the administrator role. - $edit = array(); + $edit = []; $edit['user_admin_role'] = $this->rid; $this->drupalPostForm('admin/config/people/accounts', $edit, t('Save configuration')); @@ -111,12 +111,12 @@ function testAdministratorRole() { // Enable aggregator module and ensure the 'administer news feeds' // permission is assigned by default. - \Drupal::service('module_installer')->install(array('aggregator')); + \Drupal::service('module_installer')->install(['aggregator']); $this->assertTrue($this->adminUser->hasPermission('administer news feeds'), 'The permission was automatically assigned to the administrator role'); // Ensure that selecting '- None -' removes the admin role. - $edit = array(); + $edit = []; $edit['user_admin_role'] = ''; $this->drupalPostForm('admin/config/people/accounts', $edit, t('Save configuration')); @@ -135,7 +135,7 @@ function testAdministratorRole() { /** * Verify proper permission changes by user_role_change_permissions(). */ - function testUserRoleChangePermissions() { + public function testUserRoleChangePermissions() { $permissions_hash_generator = $this->container->get('user_permissions_hash_generator'); $rid = $this->rid; @@ -148,10 +148,10 @@ function testUserRoleChangePermissions() { $this->assertTrue($account->hasPermission('administer site configuration'), 'User has "administer site configuration" permission.'); // Change permissions. - $permissions = array( + $permissions = [ 'administer users' => 1, 'access user profiles' => 0, - ); + ]; user_role_change_permissions($rid, $permissions); // Verify proper permission changes. diff --git a/core/modules/user/src/Tests/UserPictureTest.php b/core/modules/user/src/Tests/UserPictureTest.php index 3f8db427..d8504133 100644 --- a/core/modules/user/src/Tests/UserPictureTest.php +++ b/core/modules/user/src/Tests/UserPictureTest.php @@ -33,18 +33,24 @@ class UserPictureTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->webUser = $this->drupalCreateUser(array( + // This test expects unused managed files to be marked temporary and then + // cleaned up by file_cron(). + $this->config('file.settings') + ->set('make_unused_managed_files_temporary', TRUE) + ->save(); + + $this->webUser = $this->drupalCreateUser([ 'access content', 'access comments', 'post comments', 'skip comment approval', - )); + ]); } /** * Tests creation, display, and deletion of user pictures. */ - function testCreateDeletePicture() { + public function testCreateDeletePicture() { $this->drupalLogin($this->webUser); // Save a new picture. @@ -56,17 +62,17 @@ function testCreateDeletePicture() { $this->assertRaw(file_uri_target($file->getFileUri()), 'User picture found on user account page.'); // Delete the picture. - $edit = array(); + $edit = []; $this->drupalPostForm('user/' . $this->webUser->id() . '/edit', $edit, t('Remove')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); // Call file_cron() to clean up the file. Make sure the timestamp // of the file is older than the system.file.temporary_maximum_age // configuration value. db_update('file_managed') - ->fields(array( + ->fields([ 'changed' => REQUEST_TIME - ($this->config('system.file')->get('temporary_maximum_age') + 1), - )) + ]) ->condition('fid', $file->id()) ->execute(); \Drupal::service('cron')->run(); @@ -81,14 +87,14 @@ function testCreateDeletePicture() { /** * Tests embedded users on node pages. */ - function testPictureOnNodeComment() { + public function testPictureOnNodeComment() { $this->drupalLogin($this->webUser); // Save a new picture. $image = current($this->drupalGetTestFiles('image')); $file = $this->saveUserPicture($image); - $node = $this->drupalCreateNode(array('type' => 'article')); + $node = $this->drupalCreateNode(['type' => 'article']); // Enable user pictures on nodes. $this->config('system.theme.global')->set('features.node_user_picture', TRUE)->save(); @@ -109,9 +115,9 @@ function testPictureOnNodeComment() { ->set('features.comment_user_picture', TRUE) ->save(); - $edit = array( + $edit = [ 'comment_body[0][value]' => $this->randomString(), - ); + ]; $this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit, t('Save')); $elements = $this->cssSelect('.comment__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]'); $this->assertEqual(count($elements), 1, 'User picture with alt text found on the comment.'); @@ -129,13 +135,13 @@ function testPictureOnNodeComment() { /** * Edits the user picture for the test user. */ - function saveUserPicture($image) { - $edit = array('files[user_picture_0]' => drupal_realpath($image->uri)); + public function saveUserPicture($image) { + $edit = ['files[user_picture_0]' => drupal_realpath($image->uri)]; $this->drupalPostForm('user/' . $this->webUser->id() . '/edit', $edit, t('Save')); // Load actual user data from database. $user_storage = $this->container->get('entity.manager')->getStorage('user'); - $user_storage->resetCache(array($this->webUser->id())); + $user_storage->resetCache([$this->webUser->id()]); $account = $user_storage->load($this->webUser->id()); return File::load($account->user_picture->target_id); } diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php index 08313626..128b71b7 100644 --- a/core/modules/user/src/Tests/UserRegistrationTest.php +++ b/core/modules/user/src/Tests/UserRegistrationTest.php @@ -21,9 +21,9 @@ class UserRegistrationTest extends WebTestBase { * * @var array */ - public static $modules = array('field_test'); + public static $modules = ['field_test']; - function testRegistrationWithEmailVerification() { + public function testRegistrationWithEmailVerification() { $config = $this->config('user.settings'); // Require email verification. $config->set('verify_mail', TRUE)->save(); @@ -35,7 +35,7 @@ function testRegistrationWithEmailVerification() { // Allow registration by site visitors without administrator approval. $config->set('register', USER_REGISTER_VISITORS)->save(); - $edit = array(); + $edit = []; $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; $this->drupalPostForm('user/register', $edit, t('Create new account')); @@ -52,7 +52,7 @@ function testRegistrationWithEmailVerification() { // Allow registration by site visitors, but require administrator approval. $config->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); - $edit = array(); + $edit = []; $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; $this->drupalPostForm('user/register', $edit, t('Create new account')); @@ -62,7 +62,7 @@ function testRegistrationWithEmailVerification() { $this->assertFalse($new_user->isActive(), 'New account is blocked until approved by an administrator.'); } - function testRegistrationWithoutEmailVerification() { + public function testRegistrationWithoutEmailVerification() { $config = $this->config('user.settings'); // Don't require email verification and allow registration by site visitors // without administrator approval. @@ -71,7 +71,7 @@ function testRegistrationWithoutEmailVerification() { ->set('register', USER_REGISTER_VISITORS) ->save(); - $edit = array(); + $edit = []; $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; @@ -95,7 +95,7 @@ function testRegistrationWithoutEmailVerification() { // Allow registration by site visitors, but require administrator approval. $config->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); - $edit = array(); + $edit = []; $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; $edit['pass[pass1]'] = $pass = $this->randomMachineName(); @@ -104,22 +104,22 @@ function testRegistrationWithoutEmailVerification() { $this->assertText(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.'), 'Users are notified of pending approval'); // Try to log in before administrator approval. - $auth = array( + $auth = [ 'name' => $name, 'pass' => $pass, - ); + ]; $this->drupalPostForm('user/login', $auth, t('Log in')); - $this->assertText(t('The username @name has not been activated or is blocked.', array('@name' => $name)), 'User cannot log in yet.'); + $this->assertText(t('The username @name has not been activated or is blocked.', ['@name' => $name]), 'User cannot log in yet.'); // Activate the new account. $accounts = $this->container->get('entity_type.manager')->getStorage('user') ->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); - $edit = array( + $edit = [ 'status' => 1, - ); + ]; $this->drupalPostForm('user/' . $new_user->id() . '/edit', $edit, t('Save')); $this->drupalLogout(); @@ -128,7 +128,7 @@ function testRegistrationWithoutEmailVerification() { $this->assertText(t('Member for'), 'User can log in after administrator approval.'); } - function testRegistrationEmailDuplicates() { + public function testRegistrationEmailDuplicates() { // Don't require email verification and allow registration by site visitors // without administrator approval. $this->config('user.settings') @@ -139,19 +139,19 @@ function testRegistrationEmailDuplicates() { // Set up a user to check for duplicates. $duplicate_user = $this->drupalCreateUser(); - $edit = array(); + $edit = []; $edit['name'] = $this->randomMachineName(); $edit['mail'] = $duplicate_user->getEmail(); // Attempt to create a new account using an existing email address. $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The email address @email is already taken.', array('@email' => $duplicate_user->getEmail())), 'Supplying an exact duplicate email address displays an error message'); + $this->assertText(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()]), 'Supplying an exact duplicate email address displays an error message'); // Attempt to bypass duplicate email registration validation by adding spaces. $edit['mail'] = ' ' . $duplicate_user->getEmail() . ' '; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The email address @email is already taken.', array('@email' => $duplicate_user->getEmail())), 'Supplying a duplicate email address with added whitespace displays an error message'); + $this->assertText(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()]), 'Supplying a duplicate email address with added whitespace displays an error message'); } /** @@ -223,7 +223,7 @@ public function testUuidFormState() { $this->assertTrue($user_storage->loadByProperties(['name' => $edit['name']])); } - function testRegistrationDefaultValues() { + public function testRegistrationDefaultValues() { // Don't require email verification and allow registration by site visitors // without administrator approval. $config_user_settings = $this->config('user.settings') @@ -237,15 +237,11 @@ function testRegistrationDefaultValues() { ->set('timezone.default', 'Europe/Brussels') ->save(); - // Check that the account information options are not displayed - // as a details element if there is not more than one details in the form. - $this->drupalGet('user/register'); - $this->assertNoRaw('
          Account information'); - // Check the presence of expected cache tags. + $this->drupalGet('user/register'); $this->assertCacheTag('config:user.settings'); - $edit = array(); + $edit = []; $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; $edit['pass[pass1]'] = $new_pass = $this->randomMachineName(); @@ -258,7 +254,7 @@ function testRegistrationDefaultValues() { $new_user = reset($accounts); $this->assertEqual($new_user->getUsername(), $name, 'Username matches.'); $this->assertEqual($new_user->getEmail(), $mail, 'Email address matches.'); - $this->assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20 ), 'Correct creation time.'); + $this->assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20), 'Correct creation time.'); $this->assertEqual($new_user->isActive(), $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.'); $this->assertEqual($new_user->getTimezone(), $config_system_date->get('timezone.default'), 'Correct time zone field.'); $this->assertEqual($new_user->langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct language field.'); @@ -287,14 +283,14 @@ public function testUniqueFields() { /** * Tests Field API fields on user registration forms. */ - function testRegistrationWithUserFields() { + public function testRegistrationWithUserFields() { // Create a field on 'user' entity type. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'test_user_field', 'entity_type' => 'user', 'type' => 'test_field', 'cardinality' => 1, - )); + ]); $field_storage->save(); $field = FieldConfig::create([ 'field_storage' => $field_storage, @@ -304,7 +300,7 @@ function testRegistrationWithUserFields() { ]); $field->save(); entity_get_form_display('user', 'user', 'default') - ->setComponent('test_user_field', array('type' => 'test_field_widget')) + ->setComponent('test_user_field', ['type' => 'test_field_widget']) ->save(); entity_get_form_display('user', 'user', 'register') ->save(); @@ -317,7 +313,7 @@ function testRegistrationWithUserFields() { // Have the field appear on the registration form. entity_get_form_display('user', 'user', 'register') - ->setComponent('test_user_field', array('type' => 'test_field_widget')) + ->setComponent('test_user_field', ['type' => 'test_field_widget']) ->save(); $this->drupalGet('user/register'); @@ -325,19 +321,19 @@ function testRegistrationWithUserFields() { $this->assertRegistrationFormCacheTagsWithUserFields(); // Check that validation errors are correctly reported. - $edit = array(); + $edit = []; $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; // Missing input in required field. $edit['test_user_field[0][value]'] = ''; $this->drupalPostForm(NULL, $edit, t('Create new account')); $this->assertRegistrationFormCacheTagsWithUserFields(); - $this->assertRaw(t('@name field is required.', array('@name' => $field->label())), 'Field validation error was correctly reported.'); + $this->assertRaw(t('@name field is required.', ['@name' => $field->label()]), 'Field validation error was correctly reported.'); // Invalid input. $edit['test_user_field[0][value]'] = '-1'; $this->drupalPostForm(NULL, $edit, t('Create new account')); $this->assertRegistrationFormCacheTagsWithUserFields(); - $this->assertRaw(t('%name does not accept the value -1.', array('%name' => $field->label())), 'Field validation error was correctly reported.'); + $this->assertRaw(t('%name does not accept the value -1.', ['%name' => $field->label()]), 'Field validation error was correctly reported.'); // Submit with valid data. $value = rand(1, 255); @@ -352,12 +348,12 @@ function testRegistrationWithUserFields() { // Check that the 'add more' button works. $field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); $field_storage->save(); - foreach (array('js', 'nojs') as $js) { + foreach (['js', 'nojs'] as $js) { $this->drupalGet('user/register'); $this->assertRegistrationFormCacheTagsWithUserFields(); // Add two inputs. $value = rand(1, 255); - $edit = array(); + $edit = []; $edit['test_user_field[0][value]'] = $value; if ($js == 'js') { $this->drupalPostAjaxForm(NULL, $edit, 'test_user_field_add_more'); @@ -375,11 +371,11 @@ function testRegistrationWithUserFields() { $this->drupalPostForm(NULL, $edit, t('Create new account')); // Check user fields. $accounts = $this->container->get('entity_type.manager')->getStorage('user') - ->loadByProperties(array('name' => $name, 'mail' => $mail)); + ->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); - $this->assertEqual($new_user->test_user_field[0]->value, $value, format_string('@js : The field value was correctly saved.', array('@js' => $js))); - $this->assertEqual($new_user->test_user_field[1]->value, $value + 1, format_string('@js : The field value was correctly saved.', array('@js' => $js))); - $this->assertEqual($new_user->test_user_field[2]->value, $value + 2, format_string('@js : The field value was correctly saved.', array('@js' => $js))); + $this->assertEqual($new_user->test_user_field[0]->value, $value, format_string('@js : The field value was correctly saved.', ['@js' => $js])); + $this->assertEqual($new_user->test_user_field[1]->value, $value + 1, format_string('@js : The field value was correctly saved.', ['@js' => $js])); + $this->assertEqual($new_user->test_user_field[2]->value, $value + 2, format_string('@js : The field value was correctly saved.', ['@js' => $js])); } } diff --git a/core/modules/user/src/Tests/UserResetEmailTestTrait.php b/core/modules/user/src/Tests/UserResetEmailTestTrait.php new file mode 100644 index 00000000..2fbbbbf7 --- /dev/null +++ b/core/modules/user/src/Tests/UserResetEmailTestTrait.php @@ -0,0 +1,29 @@ +drupalGetMails(); + $email = end($_emails); + $urls = []; + preg_match('#.+user/reset/.+#', $email['body'], $urls); + $resetURL = $urls[0]; + $this->drupalGet($resetURL); + $this->drupalPostForm(NULL, NULL, 'Log in'); + } + +} diff --git a/core/modules/user/src/Tests/UserRoleAdminTest.php b/core/modules/user/src/Tests/UserRoleAdminTest.php index 182da93c..eca9915d 100644 --- a/core/modules/user/src/Tests/UserRoleAdminTest.php +++ b/core/modules/user/src/Tests/UserRoleAdminTest.php @@ -32,31 +32,31 @@ class UserRoleAdminTest extends WebTestBase { */ protected function setUp() { parent::setUp(); - $this->adminUser = $this->drupalCreateUser(array('administer permissions', 'administer users')); + $this->adminUser = $this->drupalCreateUser(['administer permissions', 'administer users']); $this->drupalPlaceBlock('local_tasks_block'); } /** * Test adding, renaming and deleting roles. */ - function testRoleAdministration() { + public function testRoleAdministration() { $this->drupalLogin($this->adminUser); $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId(); // Test presence of tab. $this->drupalGet('admin/people/permissions'); - $tabs = $this->xpath('//ul[@class=:classes and //a[contains(., :text)]]', array( + $tabs = $this->xpath('//ul[@class=:classes and //a[contains(., :text)]]', [ ':classes' => 'tabs primary', ':text' => t('Roles'), - )); + ]); $this->assertEqual(count($tabs), 1, 'Found roles tab'); // Test adding a role. (In doing so, we use a role name that happens to // correspond to an integer, to test that the role administration pages // correctly distinguish between role names and IDs.) $role_name = '123'; - $edit = array('label' => $role_name, 'id' => $role_name); + $edit = ['label' => $role_name, 'id' => $role_name]; $this->drupalPostForm('admin/people/roles/add', $edit, t('Save')); - $this->assertRaw(t('Role %label has been added.', array('%label' => 123))); + $this->assertRaw(t('Role %label has been added.', ['%label' => 123])); $role = Role::load($role_name); $this->assertTrue(is_object($role), 'The role was successfully retrieved from the database.'); @@ -69,20 +69,20 @@ function testRoleAdministration() { // Test renaming a role. $role_name = '456'; - $edit = array('label' => $role_name); + $edit = ['label' => $role_name]; $this->drupalPostForm("admin/people/roles/manage/{$role->id()}", $edit, t('Save')); - $this->assertRaw(t('Role %label has been updated.', array('%label' => $role_name))); - \Drupal::entityManager()->getStorage('user_role')->resetCache(array($role->id())); + $this->assertRaw(t('Role %label has been updated.', ['%label' => $role_name])); + \Drupal::entityManager()->getStorage('user_role')->resetCache([$role->id()]); $new_role = Role::load($role->id()); $this->assertEqual($new_role->label(), $role_name, 'The role name has been successfully changed.'); // Test deleting a role. $this->drupalGet("admin/people/roles/manage/{$role->id()}"); $this->clickLink(t('Delete')); - $this->drupalPostForm(NULL, array(), t('Delete')); - $this->assertRaw(t('The role %label has been deleted.', array('%label' => $role_name))); + $this->drupalPostForm(NULL, [], t('Delete')); + $this->assertRaw(t('The role %label has been deleted.', ['%label' => $role_name])); $this->assertNoLinkByHref("admin/people/roles/manage/{$role->id()}", 'Role edit link removed.'); - \Drupal::entityManager()->getStorage('user_role')->resetCache(array($role->id())); + \Drupal::entityManager()->getStorage('user_role')->resetCache([$role->id()]); $this->assertFalse(Role::load($role->id()), 'A deleted role can no longer be loaded.'); // Make sure that the system-defined roles can be edited via the user @@ -98,15 +98,15 @@ function testRoleAdministration() { /** * Test user role weight change operation and ordering. */ - function testRoleWeightOrdering() { + public function testRoleWeightOrdering() { $this->drupalLogin($this->adminUser); $roles = user_roles(); $weight = count($roles); - $new_role_weights = array(); - $saved_rids = array(); + $new_role_weights = []; + $saved_rids = []; // Change the role weights to make the roles in reverse order. - $edit = array(); + $edit = []; foreach ($roles as $role) { $edit['entities[' . $role->id() . '][weight]'] = $weight; $new_role_weights[$role->id()] = $weight; @@ -119,7 +119,7 @@ function testRoleWeightOrdering() { // Load up the user roles with the new weights. drupal_static_reset('user_roles'); $roles = user_roles(); - $rids = array(); + $rids = []; // Test that the role weights have been correctly saved. foreach ($roles as $role) { $this->assertEqual($role->getWeight(), $new_role_weights[$role->id()]); diff --git a/core/modules/user/src/Tests/UserTimeZoneTest.php b/core/modules/user/src/Tests/UserTimeZoneTest.php index 3229d319..396add4c 100644 --- a/core/modules/user/src/Tests/UserTimeZoneTest.php +++ b/core/modules/user/src/Tests/UserTimeZoneTest.php @@ -17,19 +17,26 @@ class UserTimeZoneTest extends WebTestBase { * * @var array */ - public static $modules = array('node', 'system_test'); + public static $modules = ['node', 'system_test']; /** * Tests the display of dates and time when user-configurable time zones are set. */ - function testUserTimeZone() { + public function testUserTimeZone() { // Setup date/time settings for Los Angeles time. $this->config('system.date') ->set('timezone.user.configurable', 1) ->set('timezone.default', 'America/Los_Angeles') ->save(); + + // Load the 'medium' date format, which is the default for node creation + // time, and override it. Since we are testing time zones with Daylight + // Saving Time, and need to future proof against changes to the zoneinfo + // database, we choose the 'I' format placeholder instead of a + // human-readable zone name. With 'I', a 1 means the date is in DST, and 0 + // if not. DateFormat::load('medium') - ->setPattern('Y-m-d H:i T') + ->setPattern('Y-m-d H:i I') ->save(); // Create a user account and login. @@ -42,21 +49,21 @@ function testUserTimeZone() { $date2 = '2007-03-11 01:00:00 -0800'; // One date in PDT (summer time): $date3 = '2007-03-20 21:00:00 -0700'; - $this->drupalCreateContentType(array('type' => 'article')); - $node1 = $this->drupalCreateNode(array('created' => strtotime($date1), 'type' => 'article')); - $node2 = $this->drupalCreateNode(array('created' => strtotime($date2), 'type' => 'article')); - $node3 = $this->drupalCreateNode(array('created' => strtotime($date3), 'type' => 'article')); + $this->drupalCreateContentType(['type' => 'article']); + $node1 = $this->drupalCreateNode(['created' => strtotime($date1), 'type' => 'article']); + $node2 = $this->drupalCreateNode(['created' => strtotime($date2), 'type' => 'article']); + $node3 = $this->drupalCreateNode(['created' => strtotime($date3), 'type' => 'article']); // Confirm date format and time zone. $this->drupalGet('node/' . $node1->id()); - $this->assertText('2007-03-09 21:00 PST', 'Date should be PST.'); + $this->assertText('2007-03-09 21:00 0', 'Date should be PST.'); $this->drupalGet('node/' . $node2->id()); - $this->assertText('2007-03-11 01:00 PST', 'Date should be PST.'); + $this->assertText('2007-03-11 01:00 0', 'Date should be PST.'); $this->drupalGet('node/' . $node3->id()); - $this->assertText('2007-03-20 21:00 PDT', 'Date should be PDT.'); + $this->assertText('2007-03-20 21:00 1', 'Date should be PDT.'); // Change user time zone to Santiago time. - $edit = array(); + $edit = []; $edit['mail'] = $web_user->getEmail(); $edit['timezone'] = 'America/Santiago'; $this->drupalPostForm("user/" . $web_user->id() . "/edit", $edit, t('Save')); @@ -64,25 +71,25 @@ function testUserTimeZone() { // Confirm date format and time zone. $this->drupalGet('node/' . $node1->id()); - $this->assertText('2007-03-10 02:00 CLST', 'Date should be Chile summer time; five hours ahead of PST.'); + $this->assertText('2007-03-10 02:00 1', 'Date should be Chile summer time; five hours ahead of PST.'); $this->drupalGet('node/' . $node2->id()); - $this->assertText('2007-03-11 05:00 CLT', 'Date should be Chile time; four hours ahead of PST'); + $this->assertText('2007-03-11 05:00 0', 'Date should be Chile time; four hours ahead of PST'); $this->drupalGet('node/' . $node3->id()); - $this->assertText('2007-03-21 00:00 CLT', 'Date should be Chile time; three hours ahead of PDT.'); + $this->assertText('2007-03-21 00:00 0', 'Date should be Chile time; three hours ahead of PDT.'); // Ensure that anonymous users also use the default timezone. $this->drupalLogout(); $this->drupalGet('node/' . $node1->id()); - $this->assertText('2007-03-09 21:00 PST', 'Date should be PST.'); + $this->assertText('2007-03-09 21:00 0', 'Date should be PST.'); $this->drupalGet('node/' . $node2->id()); - $this->assertText('2007-03-11 01:00 PST', 'Date should be PST.'); + $this->assertText('2007-03-11 01:00 0', 'Date should be PST.'); $this->drupalGet('node/' . $node3->id()); - $this->assertText('2007-03-20 21:00 PDT', 'Date should be PDT.'); + $this->assertText('2007-03-20 21:00 1', 'Date should be PDT.'); // Format a date without accessing the current user at all and // ensure that it uses the default timezone. $this->drupalGet('/system-test/date'); - $this->assertText('2016-01-13 08:29 PST', 'Date should be PST.'); + $this->assertText('2016-01-13 08:29 0', 'Date should be PST.'); } } diff --git a/core/modules/user/src/Tests/UserTranslationUITest.php b/core/modules/user/src/Tests/UserTranslationUITest.php index 82a34451..32a9b8fe 100644 --- a/core/modules/user/src/Tests/UserTranslationUITest.php +++ b/core/modules/user/src/Tests/UserTranslationUITest.php @@ -23,7 +23,7 @@ class UserTranslationUITest extends ContentTranslationUITestBase { * * @var array */ - public static $modules = array('language', 'content_translation', 'user', 'views'); + public static $modules = ['language', 'content_translation', 'user', 'views']; protected function setUp() { $this->entityTypeId = 'user'; @@ -38,7 +38,7 @@ protected function setUp() { * {@inheritdoc} */ protected function getTranslatorPermissions() { - return array_merge(parent::getTranslatorPermissions(), array('administer users')); + return array_merge(parent::getTranslatorPermissions(), ['administer users']); } /** @@ -46,7 +46,7 @@ protected function getTranslatorPermissions() { */ protected function getNewEntityValues($langcode) { // User name is not translatable hence we use a fixed value. - return array('name' => $this->name) + parent::getNewEntityValues($langcode); + return ['name' => $this->name] + parent::getNewEntityValues($langcode); } /** @@ -62,14 +62,14 @@ protected function doTestTranslationEdit() { foreach ($this->langcodes as $langcode) { // We only want to test the title for non-english translations. if ($langcode != 'en') { - $options = array('language' => $languages[$langcode]); + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); $this->drupalGet($url); - $title = t('@title [%language translation]', array( + $title = t('@title [%language translation]', [ '@title' => $entity->getTranslation($langcode)->label(), '%language' => $languages[$langcode]->getName(), - )); + ]); $this->assertRaw($title); } } diff --git a/core/modules/user/src/Tests/Views/AccessPermissionTest.php b/core/modules/user/src/Tests/Views/AccessPermissionTest.php index b8ef5a9f..477abd94 100644 --- a/core/modules/user/src/Tests/Views/AccessPermissionTest.php +++ b/core/modules/user/src/Tests/Views/AccessPermissionTest.php @@ -19,12 +19,12 @@ class AccessPermissionTest extends AccessTestBase { * * @var array */ - public static $testViews = array('test_access_perm'); + public static $testViews = ['test_access_perm']; /** * Tests perm access plugin. */ - function testAccessPerm() { + public function testAccessPerm() { $view = Views::getView('test_access_perm'); $view->setDisplay(); diff --git a/core/modules/user/src/Tests/Views/AccessRoleTest.php b/core/modules/user/src/Tests/Views/AccessRoleTest.php index 02a83a71..addda24f 100644 --- a/core/modules/user/src/Tests/Views/AccessRoleTest.php +++ b/core/modules/user/src/Tests/Views/AccessRoleTest.php @@ -20,18 +20,18 @@ class AccessRoleTest extends AccessTestBase { * * @var array */ - public static $testViews = array('test_access_role'); + public static $testViews = ['test_access_role']; /** * Tests role access plugin. */ - function testAccessRole() { + public function testAccessRole() { /** @var \Drupal\views\ViewEntityInterface $view */ $view = \Drupal::entityManager()->getStorage('view')->load('test_access_role'); $display = &$view->getDisplay('default'); - $display['display_options']['access']['options']['role'] = array( + $display['display_options']['access']['options']['role'] = [ $this->normalRole => $this->normalRole, - ); + ]; $view->save(); $this->container->get('router.builder')->rebuildIfNeeded(); $expected = [ @@ -63,10 +63,10 @@ function testAccessRole() { // Test allowing multiple roles. $view = Views::getView('test_access_role')->storage; $display = &$view->getDisplay('default'); - $display['display_options']['access']['options']['role'] = array( + $display['display_options']['access']['options']['role'] = [ $this->normalRole => $this->normalRole, 'anonymous' => 'anonymous', - ); + ]; $view->save(); $this->container->get('router.builder')->rebuildIfNeeded(); @@ -102,9 +102,9 @@ public function testRenderCaching() { $display['display_options']['cache'] = [ 'type' => 'tag', ]; - $display['display_options']['access']['options']['role'] = array( + $display['display_options']['access']['options']['role'] = [ $this->normalRole => $this->normalRole, - ); + ]; $view->save(); /** @var \Drupal\Core\Render\RendererInterface $renderer */ @@ -126,10 +126,10 @@ public function testRenderCaching() { $account_switcher->switchTo($this->webUser); $result = $renderer->renderPlain($build); // @todo Fix this in https://www.drupal.org/node/2551037, - // DisplayPluginBase::applyDisplayCachablityMetadata() is not invoked when + // DisplayPluginBase::applyDisplayCacheabilityMetadata() is not invoked when // using buildBasicRenderable() and a Views access plugin returns FALSE. - //$this->assertTrue(in_array('user.roles', $build['#cache']['contexts'])); - //$this->assertEqual([], $build['#cache']['tags']); + // $this->assertTrue(in_array('user.roles', $build['#cache']['contexts'])); + // $this->assertEqual([], $build['#cache']['tags']); $this->assertEqual(Cache::PERMANENT, $build['#cache']['max-age']); $this->assertEqual($result, ''); } diff --git a/core/modules/user/src/Tests/Views/AccessRoleUITest.php b/core/modules/user/src/Tests/Views/AccessRoleUITest.php deleted file mode 100644 index 7fb94960..00000000 --- a/core/modules/user/src/Tests/Views/AccessRoleUITest.php +++ /dev/null @@ -1,64 +0,0 @@ -container->get('entity.manager'); - $entity_manager->getStorage('user_role')->create(array('id' => 'custom_role', 'label' => 'Custom role'))->save(); - $access_url = "admin/structure/views/nojs/display/test_access_role/default/access_options"; - $this->drupalPostForm($access_url, array('access_options[role][custom_role]' => 1), t('Apply')); - $this->assertResponse(200); - - $this->drupalPostForm(NULL, array(), t('Save')); - $view = $entity_manager->getStorage('view')->load('test_access_role'); - - $display = $view->getDisplay('default'); - $this->assertEqual($display['display_options']['access']['options']['role'], array('custom_role' => 'custom_role')); - - // Test changing access plugin from role to none. - $this->drupalPostForm('admin/structure/views/nojs/display/test_access_role/default/access', ['access[type]' => 'none'], t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); - // Verify that role option is not set. - $view = $entity_manager->getStorage('view')->load('test_access_role'); - $display = $view->getDisplay('default'); - $this->assertFalse(isset($display['display_options']['access']['options']['role'])); - } - -} diff --git a/core/modules/user/src/Tests/Views/AccessTestBase.php b/core/modules/user/src/Tests/Views/AccessTestBase.php index 90a3d2f5..b0395b0f 100644 --- a/core/modules/user/src/Tests/Views/AccessTestBase.php +++ b/core/modules/user/src/Tests/Views/AccessTestBase.php @@ -12,7 +12,7 @@ abstract class AccessTestBase extends UserTestBase { * * @var array */ - public static $modules = array('block'); + public static $modules = ['block']; /** * Contains a user object that has no special permissions. @@ -55,8 +55,8 @@ protected function setUp() { $roles = $this->webUser->getRoles(); $this->webRole = $roles[0]; - $this->normalRole = $this->drupalCreateRole(array()); - $this->normalUser = $this->drupalCreateUser(array('views_test_data test permission')); + $this->normalRole = $this->drupalCreateRole([]); + $this->normalUser = $this->drupalCreateUser(['views_test_data test permission']); $this->normalUser->addRole($this->normalRole); $this->normalUser->save(); // @todo when all the plugin information is cached make a reset function and diff --git a/core/modules/user/src/Tests/Views/ArgumentDefaultTest.php b/core/modules/user/src/Tests/Views/ArgumentDefaultTest.php index 4e21d79c..7db32373 100644 --- a/core/modules/user/src/Tests/Views/ArgumentDefaultTest.php +++ b/core/modules/user/src/Tests/Views/ArgumentDefaultTest.php @@ -16,7 +16,7 @@ class ArgumentDefaultTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_plugin_argument_default_current_user'); + public static $testViews = ['test_plugin_argument_default_current_user']; public function test_plugin_argument_default_current_user() { // Create a user to test. diff --git a/core/modules/user/src/Tests/Views/ArgumentValidateTest.php b/core/modules/user/src/Tests/Views/ArgumentValidateTest.php index 0a491425..3365bd89 100644 --- a/core/modules/user/src/Tests/Views/ArgumentValidateTest.php +++ b/core/modules/user/src/Tests/Views/ArgumentValidateTest.php @@ -18,7 +18,7 @@ class ArgumentValidateTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_view_argument_validate_user', 'test_view_argument_validate_username'); + public static $testViews = ['test_view_argument_validate_user', 'test_view_argument_validate_username']; /** * A user for this test. @@ -36,7 +36,7 @@ protected function setUp() { /** * Tests the User (ID) argument validator. */ - function testArgumentValidateUserUid() { + public function testArgumentValidateUserUid() { $account = $this->account; $view = Views::getView('test_view_argument_validate_user'); @@ -48,7 +48,7 @@ function testArgumentValidateUserUid() { // Fail for a valid numeric, but for a user that doesn't exist $this->assertFalse($view->argument['null']->validateArgument(32)); - $form = array(); + $form = []; $form_state = new FormState(); $view->argument['null']->buildOptionsForm($form, $form_state); $sanitized_id = ArgumentPluginBase::encodeValidatorId('entity:user'); diff --git a/core/modules/user/src/Tests/Views/BulkFormAccessTest.php b/core/modules/user/src/Tests/Views/BulkFormAccessTest.php index 3aa5f93f..a6ab3c86 100644 --- a/core/modules/user/src/Tests/Views/BulkFormAccessTest.php +++ b/core/modules/user/src/Tests/Views/BulkFormAccessTest.php @@ -1,6 +1,7 @@ drupalCreateUser(array(), 'no_edit'); + $no_edit_user = $this->drupalCreateUser([], 'no_edit'); // Ensure this account is not blocked. $this->assertFalse($no_edit_user->isBlocked(), 'The user is not blocked.'); // Log in as user admin. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); // Ensure that the account "no_edit" can not be edited. @@ -46,10 +47,10 @@ public function testUserEditAccess() { $this->assertResponse(403, 'The user may not be edited.'); // Test blocking the account "no_edit". - $edit = array( + $edit = [ 'user_bulk_form[' . ($no_edit_user->id() - 1) . ']' => TRUE, 'action' => 'user_block_user_action', - ); + ]; $this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items')); $this->assertResponse(200); @@ -67,10 +68,10 @@ public function testUserEditAccess() { $normal_user = $this->drupalCreateUser(); $this->assertTrue($normal_user->access('update', $admin_user)); - $edit = array( + $edit = [ 'user_bulk_form[' . ($normal_user->id() - 1) . ']' => TRUE, 'action' => 'user_block_user_action', - ); + ]; $this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items')); $normal_user = User::load($normal_user->id()); @@ -79,10 +80,10 @@ public function testUserEditAccess() { // Log in as user without the 'administer users' permission. $this->drupalLogin($this->drupalCreateUser()); - $edit = array( + $edit = [ 'user_bulk_form[' . ($normal_user->id() - 1) . ']' => TRUE, 'action' => 'user_unblock_user_action', - ); + ]; $this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items')); // Re-load the normal user and ensure it is still blocked. @@ -95,11 +96,11 @@ public function testUserEditAccess() { */ public function testUserDeleteAccess() { // Create two authenticated users. - $account = $this->drupalCreateUser(array(), 'no_delete'); - $account2 = $this->drupalCreateUser(array(), 'may_delete'); + $account = $this->drupalCreateUser([], 'no_delete'); + $account2 = $this->drupalCreateUser([], 'may_delete'); // Log in as user admin. - $this->drupalLogin($this->drupalCreateUser(array('administer users'))); + $this->drupalLogin($this->drupalCreateUser(['administer users'])); // Ensure that the account "no_delete" can not be deleted. $this->drupalGet('user/' . $account->id() . '/cancel'); @@ -109,15 +110,15 @@ public function testUserDeleteAccess() { $this->assertResponse(200, 'The user "may_delete" may be deleted.'); // Test deleting the accounts "no_delete" and "may_delete". - $edit = array( + $edit = [ 'user_bulk_form[' . ($account->id() - 1) . ']' => TRUE, 'user_bulk_form[' . ($account2->id() - 1) . ']' => TRUE, 'action' => 'user_cancel_user_action', - ); + ]; $this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items')); - $edit = array( + $edit = [ 'user_cancel_method' => 'user_cancel_delete', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Cancel accounts')); // Ensure the account "no_delete" still exists. diff --git a/core/modules/user/src/Tests/Views/BulkFormTest.php b/core/modules/user/src/Tests/Views/BulkFormTest.php index 00bdc821..665af74a 100644 --- a/core/modules/user/src/Tests/Views/BulkFormTest.php +++ b/core/modules/user/src/Tests/Views/BulkFormTest.php @@ -19,33 +19,33 @@ class BulkFormTest extends UserTestBase { * * @var array */ - public static $modules = array('views_ui'); + public static $modules = ['views_ui']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_user_bulk_form', 'test_user_bulk_form_combine_filter'); + public static $testViews = ['test_user_bulk_form', 'test_user_bulk_form_combine_filter']; /** * Tests the user bulk form. */ public function testBulkForm() { // Log in as a user without 'administer users'. - $this->drupalLogin($this->drupalCreateUser(array('administer permissions'))); + $this->drupalLogin($this->drupalCreateUser(['administer permissions'])); $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create an user which actually can change users. - $this->drupalLogin($this->drupalCreateUser(array('administer users'))); + $this->drupalLogin($this->drupalCreateUser(['administer users'])); $this->drupalGet('test-user-bulk-form'); $result = $this->cssSelect('#edit-action option'); $this->assertTrue(count($result) > 0); // Test submitting the page with no selection. - $edit = array( + $edit = [ 'action' => 'user_block_user_action', - ); + ]; $this->drupalPostForm('test-user-bulk-form', $edit, t('Apply to selected items')); $this->assertText(t('No users selected.')); @@ -56,36 +56,36 @@ public function testBulkForm() { $role = key($roles); $this->assertFalse($account->hasRole($role), 'The user currently does not have a custom role.'); - $edit = array( + $edit = [ 'user_bulk_form[1]' => TRUE, 'action' => 'user_add_role_action.' . $role, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); // Re-load the user and check their roles. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->hasRole($role), 'The user now has the custom role.'); - $edit = array( + $edit = [ 'user_bulk_form[1]' => TRUE, 'action' => 'user_remove_role_action.' . $role, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); // Re-load the user and check their roles. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertFalse($account->hasRole($role), 'The user no longer has the custom role.'); // Block a user using the bulk form. $this->assertTrue($account->isActive(), 'The user is not blocked.'); $this->assertRaw($account->label(), 'The user is found in the table.'); - $edit = array( + $edit = [ 'user_bulk_form[1]' => TRUE, 'action' => 'user_block_user_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); // Re-load the user and check their status. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->isBlocked(), 'The user is blocked.'); $this->assertNoRaw($account->label(), 'The user is not found in the table.'); @@ -100,16 +100,16 @@ public function testBulkForm() { $this->assertText($this->config('user.settings')->get('anonymous')); // Attempt to block the anonymous user. - $edit = array( + $edit = [ 'user_bulk_form[0]' => TRUE, 'action' => 'user_block_user_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $anonymous_account = $user_storage->load(0); $this->assertTrue($anonymous_account->isBlocked(), 'Ensure the anonymous user got blocked.'); // Test the list of available actions with a value that contains a dot. - $this->drupalLogin($this->drupalCreateUser(array('administer permissions', 'administer views', 'administer users'))); + $this->drupalLogin($this->drupalCreateUser(['administer permissions', 'administer views', 'administer users'])); $action_id = 'user_add_role_action.' . $role; $edit = [ 'options[include_exclude]' => 'exclude', @@ -134,7 +134,7 @@ public function testBulkFormCombineFilter() { User::load($this->users[0]->id()); $view = Views::getView('test_user_bulk_form_combine_filter'); $errors = $view->validate(); - $this->assertEqual(reset($errors['default']), t('Field %field set in %filter is not usable for this filter type. Combined field filter only works for simple fields.', array('%field' => 'User: Bulk update', '%filter' => 'Global: Combine fields filter'))); + $this->assertEqual(reset($errors['default']), t('Field %field set in %filter is not usable for this filter type. Combined field filter only works for simple fields.', ['%field' => 'User: Bulk update', '%filter' => 'Global: Combine fields filter'])); } } diff --git a/core/modules/user/src/Tests/Views/FilterPermissionUiTest.php b/core/modules/user/src/Tests/Views/FilterPermissionUiTest.php index e55c6c38..f9444bc7 100644 --- a/core/modules/user/src/Tests/Views/FilterPermissionUiTest.php +++ b/core/modules/user/src/Tests/Views/FilterPermissionUiTest.php @@ -30,7 +30,7 @@ class FilterPermissionUiTest extends ViewTestBase { protected function setUp() { parent::setUp(TRUE); - ViewTestData::createTestViews(get_class($this), array('user_test_views')); + ViewTestData::createTestViews(get_class($this), ['user_test_views']); $this->enableViewsTestModule(); } diff --git a/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php b/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php index d84a5425..73ee53fa 100644 --- a/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php +++ b/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php @@ -16,7 +16,7 @@ class HandlerArgumentUserUidTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_user_uid_argument'); + public static $testViews = ['test_user_uid_argument']; /** * Tests the generated title of an user: uid argument. @@ -25,29 +25,29 @@ public function testArgumentTitle() { $view = Views::getView('test_user_uid_argument'); // Tests an invalid user uid. - $this->executeView($view, array(rand(1000, 10000))); + $this->executeView($view, [rand(1000, 10000)]); $this->assertFalse($view->getTitle()); $view->destroy(); // Tests a valid user. $account = $this->drupalCreateUser(); - $this->executeView($view, array($account->id())); + $this->executeView($view, [$account->id()]); $this->assertEqual($view->getTitle(), $account->label()); $view->destroy(); // Tests the anonymous user. $anonymous = $this->config('user.settings')->get('anonymous'); - $this->executeView($view, array(0)); + $this->executeView($view, [0]); $this->assertEqual($view->getTitle(), $anonymous); $view->destroy(); $view->getDisplay()->getHandler('argument', 'uid')->options['break_phrase'] = TRUE; - $this->executeView($view, array($account->id() . ',0')); + $this->executeView($view, [$account->id() . ',0']); $this->assertEqual($view->getTitle(), $account->label() . ', ' . $anonymous); $view->destroy(); $view->getDisplay()->getHandler('argument', 'uid')->options['break_phrase'] = TRUE; - $this->executeView($view, array('0,' . $account->id())); + $this->executeView($view, ['0,' . $account->id()]); $this->assertEqual($view->getTitle(), $anonymous . ', ' . $account->label()); $view->destroy(); } diff --git a/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php b/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php index de7c65c9..6a5ebfc6 100644 --- a/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php +++ b/core/modules/user/src/Tests/Views/HandlerFieldRoleTest.php @@ -18,18 +18,18 @@ class HandlerFieldRoleTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_views_handler_field_role'); + public static $testViews = ['test_views_handler_field_role']; public function testRole() { // Create a couple of roles for the view. $rolename_a = 'a' . $this->randomMachineName(8); - $this->drupalCreateRole(array('access content'), $rolename_a, '' . $rolename_a . '', 9); + $this->drupalCreateRole(['access content'], $rolename_a, '' . $rolename_a . '', 9); $rolename_b = 'b' . $this->randomMachineName(8); - $this->drupalCreateRole(array('access content'), $rolename_b, $rolename_b, 8); + $this->drupalCreateRole(['access content'], $rolename_b, $rolename_b, 8); $rolename_not_assigned = $this->randomMachineName(8); - $this->drupalCreateRole(array('access content'), $rolename_not_assigned, $rolename_not_assigned); + $this->drupalCreateRole(['access content'], $rolename_not_assigned, $rolename_not_assigned); // Add roles to user 1. $user = User::load(1); diff --git a/core/modules/user/src/Tests/Views/HandlerFieldUserNameTest.php b/core/modules/user/src/Tests/Views/HandlerFieldUserNameTest.php index 6af16447..39a3ec87 100644 --- a/core/modules/user/src/Tests/Views/HandlerFieldUserNameTest.php +++ b/core/modules/user/src/Tests/Views/HandlerFieldUserNameTest.php @@ -18,13 +18,13 @@ class HandlerFieldUserNameTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_views_handler_field_user_name'); + public static $testViews = ['test_views_handler_field_user_name']; public function testUserName() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); - $new_user = $this->drupalCreateUser(array('access user profiles')); + $new_user = $this->drupalCreateUser(['access user profiles']); $this->drupalLogin($new_user); // Set defaults. diff --git a/core/modules/user/src/Tests/Views/HandlerFilterUserNameTest.php b/core/modules/user/src/Tests/Views/HandlerFilterUserNameTest.php index eaf24aa0..4f7d4cdb 100644 --- a/core/modules/user/src/Tests/Views/HandlerFilterUserNameTest.php +++ b/core/modules/user/src/Tests/Views/HandlerFilterUserNameTest.php @@ -19,47 +19,47 @@ class HandlerFilterUserNameTest extends ViewTestBase { * * @var array */ - public static $modules = array('views_ui', 'user_test_views'); + public static $modules = ['views_ui', 'user_test_views']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_user_name'); + public static $testViews = ['test_user_name']; /** * Accounts used by this test. * * @var array */ - protected $accounts = array(); + protected $accounts = []; /** * Usernames of $accounts. * * @var array */ - protected $names = array(); + protected $names = []; /** * Stores the column map for this testCase. * * @var array */ - public $columnMap = array( + public $columnMap = [ 'uid' => 'uid', - ); + ]; protected function setUp() { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('user_test_views')); + ViewTestData::createTestViews(get_class($this), ['user_test_views']); $this->enableViewsTestModule(); - $this->accounts = array(); - $this->names = array(); + $this->accounts = []; + $this->names = []; for ($i = 0; $i < 3; $i++) { $this->accounts[] = $account = $this->drupalCreateUser(); $this->names[] = $account->label(); @@ -74,10 +74,10 @@ public function testUserNameApi() { $view = Views::getView('test_user_name'); $view->initHandlers(); - $view->filter['uid']->value = array($this->accounts[0]->id()); + $view->filter['uid']->value = [$this->accounts[0]->id()]; $this->executeView($view); - $this->assertIdenticalResultset($view, array(array('uid' => $this->accounts[0]->id())), $this->columnMap); + $this->assertIdenticalResultset($view, [['uid' => $this->accounts[0]->id()]], $this->columnMap); $this->assertEqual($view->filter['uid']->getValueOptions(), NULL); } @@ -86,40 +86,40 @@ public function testUserNameApi() { * Tests using the user interface. */ public function testAdminUserInterface() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); $this->drupalLogin($admin_user); $path = 'admin/structure/views/nojs/handler/test_user_name/default/filter/uid'; $this->drupalGet($path); // Pass in an invalid username, the validation should catch it. - $users = array($this->randomMachineName()); + $users = [$this->randomMachineName()]; $users = array_map('strtolower', $users); - $edit = array( + $edit = [ 'options[value]' => implode(', ', $users) - ); + ]; $this->drupalPostForm($path, $edit, t('Apply')); - $this->assertRaw(t('There are no entities matching "%value".', array('%value' => implode(', ', $users)))); + $this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)])); // Pass in an invalid username and a valid username. $random_name = $this->randomMachineName(); - $users = array($random_name, $this->names[0]); + $users = [$random_name, $this->names[0]]; $users = array_map('strtolower', $users); - $edit = array( + $edit = [ 'options[value]' => implode(', ', $users) - ); - $users = array($users[0]); + ]; + $users = [$users[0]]; $this->drupalPostForm($path, $edit, t('Apply')); - $this->assertRaw(t('There are no entities matching "%value".', array('%value' => implode(', ', $users)))); + $this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)])); // Pass in just valid usernames. $users = $this->names; $users = array_map('strtolower', $users); - $edit = array( + $edit = [ 'options[value]' => implode(', ', $users) - ); + ]; $this->drupalPostForm($path, $edit, t('Apply')); - $this->assertNoRaw(t('There are no entities matching "%value".', array('%value' => implode(', ', $users)))); + $this->assertNoRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)])); } /** @@ -128,14 +128,14 @@ public function testAdminUserInterface() { public function testExposedFilter() { $path = 'test_user_name'; - $options = array(); + $options = []; // Pass in an invalid username, the validation should catch it. - $users = array($this->randomMachineName()); + $users = [$this->randomMachineName()]; $users = array_map('strtolower', $users); $options['query']['uid'] = implode(', ', $users); $this->drupalGet($path, $options); - $this->assertRaw(t('There are no entities matching "%value".', array('%value' => implode(', ', $users)))); + $this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)])); // Pass in an invalid target_id in for the entity_autocomplete value format. // There should be no errors, but all results should be returned as the @@ -149,13 +149,13 @@ public function testExposedFilter() { } // Pass in an invalid username and a valid username. - $users = array($this->randomMachineName(), $this->names[0]); + $users = [$this->randomMachineName(), $this->names[0]]; $users = array_map('strtolower', $users); $options['query']['uid'] = implode(', ', $users); - $users = array($users[0]); + $users = [$users[0]]; $this->drupalGet($path, $options); - $this->assertRaw(t('There are no entities matching "%value".', array('%value' => implode(', ', $users)))); + $this->assertRaw(t('There are no entities matching "%value".', ['%value' => implode(', ', $users)])); // Pass in just valid usernames. $users = $this->names; @@ -169,7 +169,7 @@ public function testExposedFilter() { } // Pass in just valid user IDs in the entity_autocomplete target_id format. - $options['query']['uid'] = array_map(function($account) { + $options['query']['uid'] = array_map(function ($account) { return ['target_id' => $account->id()]; }, $this->accounts); diff --git a/core/modules/user/src/Tests/Views/RelationshipRepresentativeNodeTest.php b/core/modules/user/src/Tests/Views/RelationshipRepresentativeNodeTest.php index 3ad6346a..14f44123 100644 --- a/core/modules/user/src/Tests/Views/RelationshipRepresentativeNodeTest.php +++ b/core/modules/user/src/Tests/Views/RelationshipRepresentativeNodeTest.php @@ -16,7 +16,7 @@ class RelationshipRepresentativeNodeTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_groupwise_user'); + public static $testViews = ['test_groupwise_user']; /** * Tests the relationship. @@ -24,17 +24,17 @@ class RelationshipRepresentativeNodeTest extends UserTestBase { public function testRelationship() { $view = Views::getView('test_groupwise_user'); $this->executeView($view); - $map = array('node_field_data_users_field_data_nid' => 'nid', 'uid' => 'uid'); - $expected_result = array( - array( + $map = ['node_field_data_users_field_data_nid' => 'nid', 'uid' => 'uid']; + $expected_result = [ + [ 'uid' => $this->users[1]->id(), 'nid' => $this->nodes[1]->id(), - ), - array( + ], + [ 'uid' => $this->users[0]->id(), 'nid' => $this->nodes[0]->id(), - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $expected_result, $map); } diff --git a/core/modules/user/src/Tests/Views/RolesRidArgumentTest.php b/core/modules/user/src/Tests/Views/RolesRidArgumentTest.php index a658b220..58782e94 100644 --- a/core/modules/user/src/Tests/Views/RolesRidArgumentTest.php +++ b/core/modules/user/src/Tests/Views/RolesRidArgumentTest.php @@ -15,7 +15,7 @@ class RolesRidArgumentTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_user_roles_rid'); + public static $testViews = ['test_user_roles_rid']; /** * Tests the generated title of a user: roles argument. diff --git a/core/modules/user/src/Tests/Views/UserChangedTest.php b/core/modules/user/src/Tests/Views/UserChangedTest.php index 50e21e58..ddd7903e 100644 --- a/core/modules/user/src/Tests/Views/UserChangedTest.php +++ b/core/modules/user/src/Tests/Views/UserChangedTest.php @@ -17,19 +17,19 @@ class UserChangedTest extends ViewTestBase { * * @var array */ - public static $modules = array('views_ui', 'user_test_views'); + public static $modules = ['views_ui', 'user_test_views']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_user_changed'); + public static $testViews = ['test_user_changed']; protected function setUp() { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('user_test_views')); + ViewTestData::createTestViews(get_class($this), ['user_test_views']); $this->enableViewsTestModule(); } @@ -40,7 +40,7 @@ protected function setUp() { public function testChangedField() { $path = 'test_user_changed'; - $options = array(); + $options = []; $this->drupalGet($path, $options); diff --git a/core/modules/user/src/Tests/Views/UserDataTest.php b/core/modules/user/src/Tests/Views/UserDataTest.php index a55eac5e..4628ae2b 100644 --- a/core/modules/user/src/Tests/Views/UserDataTest.php +++ b/core/modules/user/src/Tests/Views/UserDataTest.php @@ -24,7 +24,7 @@ class UserDataTest extends UserTestBase { * * @var array */ - public static $testViews = array('test_user_data'); + public static $testViews = ['test_user_data']; /** * Tests field handler. diff --git a/core/modules/user/src/Tests/Views/UserTestBase.php b/core/modules/user/src/Tests/Views/UserTestBase.php index 4c8007ae..c49dcb23 100644 --- a/core/modules/user/src/Tests/Views/UserTestBase.php +++ b/core/modules/user/src/Tests/Views/UserTestBase.php @@ -16,31 +16,31 @@ abstract class UserTestBase extends ViewTestBase { * * @var array */ - public static $modules = array('user_test_views', 'node'); + public static $modules = ['user_test_views', 'node']; /** * Users to use during this test. * * @var array */ - protected $users = array(); + protected $users = []; /** * Nodes to use during this test. * * @var array */ - protected $nodes = array(); + protected $nodes = []; protected function setUp() { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('user_test_views')); + ViewTestData::createTestViews(get_class($this), ['user_test_views']); $this->users[] = $this->drupalCreateUser(); $this->users[] = User::load(1); - $this->nodes[] = $this->drupalCreateNode(array('uid' => $this->users[0]->id())); - $this->nodes[] = $this->drupalCreateNode(array('uid' => 1)); + $this->nodes[] = $this->drupalCreateNode(['uid' => $this->users[0]->id()]); + $this->nodes[] = $this->drupalCreateNode(['uid' => 1]); } } diff --git a/core/modules/user/src/UserAccessControlHandler.php b/core/modules/user/src/UserAccessControlHandler.php index 9c86758f..712b32ab 100644 --- a/core/modules/user/src/UserAccessControlHandler.php +++ b/core/modules/user/src/UserAccessControlHandler.php @@ -3,6 +3,7 @@ namespace Drupal\user; use Drupal\Core\Access\AccessResult; +use Drupal\Core\Access\AccessResultNeutral; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityAccessControlHandler; use Drupal\Core\Field\FieldDefinitionInterface; @@ -56,6 +57,9 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter elseif ($account->id() == $entity->id()) { return AccessResult::allowed()->cachePerUser(); } + else { + return AccessResultNeutral::neutral("The 'access user profiles' permission is required and the user must be active."); + } break; case 'update': @@ -76,9 +80,9 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter */ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) { // Fields that are not implicitly allowed to administrative users. - $explicit_check_fields = array( + $explicit_check_fields = [ 'pass', - ); + ]; // Administrative users are allowed to edit and view all fields. if (!in_array($field_definition->getName(), $explicit_check_fields) && $account->hasPermission('administer users')) { diff --git a/core/modules/user/src/UserAuth.php b/core/modules/user/src/UserAuth.php index 9fbcf094..43ce31b8 100644 --- a/core/modules/user/src/UserAuth.php +++ b/core/modules/user/src/UserAuth.php @@ -44,7 +44,7 @@ public function authenticate($username, $password) { $uid = FALSE; if (!empty($username) && strlen($password) > 0) { - $account_search = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $username)); + $account_search = $this->entityManager->getStorage('user')->loadByProperties(['name' => $username]); if ($account = reset($account_search)) { if ($this->passwordChecker->check($password, $account->getPassword())) { diff --git a/core/modules/user/src/UserData.php b/core/modules/user/src/UserData.php index 3418c838..fe7fc222 100644 --- a/core/modules/user/src/UserData.php +++ b/core/modules/user/src/UserData.php @@ -40,7 +40,7 @@ public function get($module, $uid = NULL, $name = NULL) { $query->condition('name', $name); } $result = $query->execute(); - // If $module, $uid, and $name was passed, return the value. + // If $module, $uid, and $name were passed, return the value. if (isset($name) && isset($uid)) { $result = $result->fetchAllAssoc('uid'); if (isset($result[$uid])) { @@ -48,17 +48,17 @@ public function get($module, $uid = NULL, $name = NULL) { } return NULL; } - // If $module and $uid was passed, return the name/value pairs. + // If $module and $uid were passed, return data keyed by name. elseif (isset($uid)) { - $return = array(); + $return = []; foreach ($result as $record) { $return[$record->name] = ($record->serialized ? unserialize($record->value) : $record->value); } return $return; } - // If $module and $name was passed, return the uid/value pairs. + // If $module and $name were passed, return data keyed by uid. elseif (isset($name)) { - $return = array(); + $return = []; foreach ($result as $record) { $return[$record->uid] = ($record->serialized ? unserialize($record->value) : $record->value); } @@ -66,7 +66,7 @@ public function get($module, $uid = NULL, $name = NULL) { } // If only $module was passed, return data keyed by uid and name. else { - $return = array(); + $return = []; foreach ($result as $record) { $return[$record->uid][$record->name] = ($record->serialized ? unserialize($record->value) : $record->value); } @@ -78,21 +78,20 @@ public function get($module, $uid = NULL, $name = NULL) { * {@inheritdoc} */ public function set($module, $uid, $name, $value) { - $serialized = 0; - if (!is_scalar($value)) { + $serialized = (int) !is_scalar($value); + if ($serialized) { $value = serialize($value); - $serialized = 1; } $this->connection->merge('users_data') - ->keys(array( + ->keys([ 'uid' => $uid, 'module' => $module, 'name' => $name, - )) - ->fields(array( + ]) + ->fields([ 'value' => $value, 'serialized' => $serialized, - )) + ]) ->execute(); } diff --git a/core/modules/user/src/UserInterface.php b/core/modules/user/src/UserInterface.php index 1aea7576..6919e0d7 100644 --- a/core/modules/user/src/UserInterface.php +++ b/core/modules/user/src/UserInterface.php @@ -13,6 +13,43 @@ */ interface UserInterface extends ContentEntityInterface, EntityChangedInterface, AccountInterface { + /** + * Maximum length of username text field. + * + * Keep this under 191 characters so we can use a unique constraint in MySQL. + */ + const USERNAME_MAX_LENGTH = 60; + + /** + * Only administrators can create user accounts. + */ + const REGISTER_ADMINISTRATORS_ONLY = 'admin_only'; + + /** + * Visitors can create their own accounts. + */ + const REGISTER_VISITORS = 'visitors'; + + /** + * Visitors can create accounts that only become active with admin approval. + */ + const REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL = 'visitors_admin_approval'; + + /** + * New users will be set to the default time zone at registration. + */ + const TIMEZONE_DEFAULT = 0; + + /** + * New users will get an empty time zone at registration. + */ + const TIMEZONE_EMPTY = 1; + + /** + * New users will select their own timezone at registration. + */ + const TIMEZONE_SELECT = 2; + /** * Whether a user has a certain role. * diff --git a/core/modules/user/src/UserListBuilder.php b/core/modules/user/src/UserListBuilder.php index 1692f5a5..306d0460 100644 --- a/core/modules/user/src/UserListBuilder.php +++ b/core/modules/user/src/UserListBuilder.php @@ -8,7 +8,6 @@ use Drupal\Core\Entity\EntityListBuilder; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Routing\RedirectDestinationInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -19,13 +18,6 @@ */ class UserListBuilder extends EntityListBuilder { - /** - * The entity query factory. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $queryFactory; - /** * The date formatter service. * @@ -47,16 +39,13 @@ class UserListBuilder extends EntityListBuilder { * The entity type definition. * @param \Drupal\Core\Entity\EntityStorageInterface $storage * The entity storage class. - * @param \Drupal\Core\Entity\Query\QueryFactory $query_factory - * The entity query factory. * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter * The date formatter service. * @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination * The redirect destination service. */ - public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, QueryFactory $query_factory, DateFormatterInterface $date_formatter, RedirectDestinationInterface $redirect_destination) { + public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, DateFormatterInterface $date_formatter, RedirectDestinationInterface $redirect_destination) { parent::__construct($entity_type, $storage); - $this->queryFactory = $query_factory; $this->dateFormatter = $date_formatter; $this->redirectDestination = $redirect_destination; } @@ -68,7 +57,6 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_type, $container->get('entity.manager')->getStorage($entity_type->id()), - $container->get('entity.query'), $container->get('date.formatter'), $container->get('redirect.destination') ); @@ -78,7 +66,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * {@inheritdoc} */ public function load() { - $entity_query = $this->queryFactory->get('user'); + $entity_query = $this->storage->getQuery(); $entity_query->condition('uid', 0, '<>'); $entity_query->pager(50); $header = $this->buildHeader(); @@ -91,36 +79,36 @@ public function load() { * {@inheritdoc} */ public function buildHeader() { - $header = array( - 'username' => array( + $header = [ + 'username' => [ 'data' => $this->t('Username'), 'field' => 'name', 'specifier' => 'name', - ), - 'status' => array( + ], + 'status' => [ 'data' => $this->t('Status'), 'field' => 'status', 'specifier' => 'status', - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ), - 'roles' => array( + 'class' => [RESPONSIVE_PRIORITY_LOW], + ], + 'roles' => [ 'data' => $this->t('Roles'), - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ), - 'member_for' => array( + 'class' => [RESPONSIVE_PRIORITY_LOW], + ], + 'member_for' => [ 'data' => $this->t('Member for'), 'field' => 'created', 'specifier' => 'created', 'sort' => 'desc', - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ), - 'access' => array( + 'class' => [RESPONSIVE_PRIORITY_LOW], + ], + 'access' => [ 'data' => $this->t('Last access'), 'field' => 'access', 'specifier' => 'access', - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ), - ); + 'class' => [RESPONSIVE_PRIORITY_LOW], + ], + ]; return $header + parent::buildHeader(); } @@ -128,25 +116,25 @@ public function buildHeader() { * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { - $row['username']['data'] = array( + $row['username']['data'] = [ '#theme' => 'username', '#account' => $entity, - ); + ]; $row['status'] = $entity->isActive() ? $this->t('active') : $this->t('blocked'); $roles = user_role_names(TRUE); unset($roles[RoleInterface::AUTHENTICATED_ID]); - $users_roles = array(); + $users_roles = []; foreach ($entity->getRoles() as $role) { if (isset($roles[$role])) { $users_roles[] = $roles[$role]; } } asort($users_roles); - $row['roles']['data'] = array( + $row['roles']['data'] = [ '#theme' => 'item_list', '#items' => $users_roles, - ); + ]; $options = [ 'return_as_object' => TRUE, ]; diff --git a/core/modules/user/src/UserStorage.php b/core/modules/user/src/UserStorage.php index 9759d270..809f3e38 100644 --- a/core/modules/user/src/UserStorage.php +++ b/core/modules/user/src/UserStorage.php @@ -40,11 +40,11 @@ protected function isColumnSerial($table_name, $schema_name) { */ public function updateLastLoginTimestamp(UserInterface $account) { $this->database->update('users_field_data') - ->fields(array('login' => $account->getLastLoginTime())) + ->fields(['login' => $account->getLastLoginTime()]) ->condition('uid', $account->id()) ->execute(); // Ensure that the entity cache is cleared. - $this->resetCache(array($account->id())); + $this->resetCache([$account->id()]); } /** @@ -52,13 +52,13 @@ public function updateLastLoginTimestamp(UserInterface $account) { */ public function updateLastAccessTimestamp(AccountInterface $account, $timestamp) { $this->database->update('users_field_data') - ->fields(array( + ->fields([ 'access' => $timestamp, - )) + ]) ->condition('uid', $account->id()) ->execute(); // Ensure that the entity cache is cleared. - $this->resetCache(array($account->id())); + $this->resetCache([$account->id()]); } /** @@ -67,8 +67,8 @@ public function updateLastAccessTimestamp(AccountInterface $account, $timestamp) public function deleteRoleReferences(array $rids) { // Remove the role from all users. $this->database->delete('user__roles') - ->condition('roles_target_id', $rids) - ->execute(); + ->condition('roles_target_id', $rids) + ->execute(); $this->resetCache(); } diff --git a/core/modules/user/src/UserStorageSchema.php b/core/modules/user/src/UserStorageSchema.php index c8c3e46e..5e590b89 100644 --- a/core/modules/user/src/UserStorageSchema.php +++ b/core/modules/user/src/UserStorageSchema.php @@ -17,9 +17,9 @@ class UserStorageSchema extends SqlContentEntityStorageSchema { protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { $schema = parent::getEntitySchema($entity_type, $reset); - $schema['users_field_data']['unique keys'] += array( - 'user__name' => array('name', 'langcode'), - ); + $schema['users_field_data']['unique keys'] += [ + 'user__name' => ['name', 'langcode'], + ]; return $schema; } diff --git a/core/modules/user/src/UserViewsData.php b/core/modules/user/src/UserViewsData.php index e2229112..2c791147 100644 --- a/core/modules/user/src/UserViewsData.php +++ b/core/modules/user/src/UserViewsData.php @@ -21,15 +21,15 @@ public function getViewsData() { $data['users_field_data']['table']['wizard_id'] = 'user'; $data['users_field_data']['uid']['argument']['id'] = 'user_uid'; - $data['users_field_data']['uid']['argument'] += array( + $data['users_field_data']['uid']['argument'] += [ 'name table' => 'users_field_data', 'name field' => 'name', 'empty field name' => \Drupal::config('user.settings')->get('anonymous'), - ); + ]; $data['users_field_data']['uid']['filter']['id'] = 'user_name'; $data['users_field_data']['uid']['filter']['title'] = $this->t('Name (autocomplete)'); $data['users_field_data']['uid']['filter']['help'] = $this->t('The user or author name. Uses an autocomplete widget to find a user name, the actual filter uses the resulting user ID.'); - $data['users_field_data']['uid']['relationship'] = array( + $data['users_field_data']['uid']['relationship'] = [ 'title' => $this->t('Content authored'), 'help' => $this->t('Relate content to the user who created it. This relationship will create one record for each content item created by the user.'), 'id' => 'standard', @@ -37,19 +37,19 @@ public function getViewsData() { 'base field' => 'uid', 'field' => 'uid', 'label' => $this->t('nodes'), - ); + ]; - $data['users_field_data']['uid_raw'] = array( + $data['users_field_data']['uid_raw'] = [ 'help' => $this->t('The raw numeric user ID.'), 'real field' => 'uid', - 'filter' => array( + 'filter' => [ 'title' => $this->t('The user ID'), 'id' => 'numeric', - ), - ); + ], + ]; - $data['users_field_data']['uid_representative'] = array( - 'relationship' => array( + $data['users_field_data']['uid_representative'] = [ + 'relationship' => [ 'title' => $this->t('Representative node'), 'label' => $this->t('Representative node'), 'help' => $this->t('Obtains a single representative node for each user, according to a chosen sort criterion.'), @@ -61,18 +61,18 @@ public function getViewsData() { 'base' => 'node_field_data', 'field' => 'nid', 'relationship' => 'node_field_data:uid' - ), - ); + ], + ]; - $data['users']['uid_current'] = array( + $data['users']['uid_current'] = [ 'real field' => 'uid', 'title' => $this->t('Current'), 'help' => $this->t('Filter the view to the currently logged in user.'), - 'filter' => array( + 'filter' => [ 'id' => 'user_current', 'type' => 'yes-no', - ), - ); + ], + ]; $data['users_field_data']['name']['help'] = $this->t('The user or author name.'); $data['users_field_data']['name']['field']['default_formatter'] = 'user_name'; @@ -90,178 +90,178 @@ public function getViewsData() { $data['users_field_data']['preferred_admin_langcode']['title'] = $this->t('Preferred admin language'); $data['users_field_data']['preferred_admin_langcode']['help'] = $this->t('Preferred administrative language of the user'); - $data['users_field_data']['created_fulldate'] = array( + $data['users_field_data']['created_fulldate'] = [ 'title' => $this->t('Created date'), 'help' => $this->t('Date in the form of CCYYMMDD.'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_fulldate', - ), - ); + ], + ]; - $data['users_field_data']['created_year_month'] = array( + $data['users_field_data']['created_year_month'] = [ 'title' => $this->t('Created year + month'), 'help' => $this->t('Date in the form of YYYYMM.'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_year_month', - ), - ); + ], + ]; - $data['users_field_data']['created_year'] = array( + $data['users_field_data']['created_year'] = [ 'title' => $this->t('Created year'), 'help' => $this->t('Date in the form of YYYY.'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_year', - ), - ); + ], + ]; - $data['users_field_data']['created_month'] = array( + $data['users_field_data']['created_month'] = [ 'title' => $this->t('Created month'), 'help' => $this->t('Date in the form of MM (01 - 12).'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_month', - ), - ); + ], + ]; - $data['users_field_data']['created_day'] = array( + $data['users_field_data']['created_day'] = [ 'title' => $this->t('Created day'), 'help' => $this->t('Date in the form of DD (01 - 31).'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_day', - ), - ); + ], + ]; - $data['users_field_data']['created_week'] = array( + $data['users_field_data']['created_week'] = [ 'title' => $this->t('Created week'), 'help' => $this->t('Date in the form of WW (01 - 53).'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_week', - ), - ); + ], + ]; $data['users_field_data']['status']['filter']['label'] = $this->t('Active'); $data['users_field_data']['status']['filter']['type'] = 'yes-no'; $data['users_field_data']['changed']['title'] = $this->t('Updated date'); - $data['users_field_data']['changed_fulldate'] = array( + $data['users_field_data']['changed_fulldate'] = [ 'title' => $this->t('Updated date'), 'help' => $this->t('Date in the form of CCYYMMDD.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_fulldate', - ), - ); + ], + ]; - $data['users_field_data']['changed_year_month'] = array( + $data['users_field_data']['changed_year_month'] = [ 'title' => $this->t('Updated year + month'), 'help' => $this->t('Date in the form of YYYYMM.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_year_month', - ), - ); + ], + ]; - $data['users_field_data']['changed_year'] = array( + $data['users_field_data']['changed_year'] = [ 'title' => $this->t('Updated year'), 'help' => $this->t('Date in the form of YYYY.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_year', - ), - ); + ], + ]; - $data['users_field_data']['changed_month'] = array( + $data['users_field_data']['changed_month'] = [ 'title' => $this->t('Updated month'), 'help' => $this->t('Date in the form of MM (01 - 12).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_month', - ), - ); + ], + ]; - $data['users_field_data']['changed_day'] = array( + $data['users_field_data']['changed_day'] = [ 'title' => $this->t('Updated day'), 'help' => $this->t('Date in the form of DD (01 - 31).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_day', - ), - ); + ], + ]; - $data['users_field_data']['changed_week'] = array( + $data['users_field_data']['changed_week'] = [ 'title' => $this->t('Updated week'), 'help' => $this->t('Date in the form of WW (01 - 53).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_week', - ), - ); + ], + ]; - $data['users']['data'] = array( + $data['users']['data'] = [ 'title' => $this->t('Data'), 'help' => $this->t('Provides access to the user data service.'), 'real field' => 'uid', - 'field' => array( + 'field' => [ 'id' => 'user_data', - ), - ); + ], + ]; - $data['users']['user_bulk_form'] = array( + $data['users']['user_bulk_form'] = [ 'title' => $this->t('Bulk update'), 'help' => $this->t('Add a form element that lets you run operations on multiple users.'), - 'field' => array( + 'field' => [ 'id' => 'user_bulk_form', - ), - ); + ], + ]; $data['user__roles']['table']['group'] = $this->t('User'); - $data['user__roles']['table']['join'] = array( - 'users_field_data' => array( + $data['user__roles']['table']['join'] = [ + 'users_field_data' => [ 'left_field' => 'uid', 'field' => 'entity_id', - ), - ); + ], + ]; - $data['user__roles']['roles_target_id'] = array( + $data['user__roles']['roles_target_id'] = [ 'title' => $this->t('Roles'), 'help' => $this->t('Roles that a user belongs to.'), - 'field' => array( + 'field' => [ 'id' => 'user_roles', 'no group by' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'user_roles', 'allow empty' => TRUE, - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'user__roles_rid', 'name table' => 'role', 'name field' => 'name', 'empty field name' => $this->t('No role'), 'zero is null' => TRUE, 'numeric' => TRUE, - ), - ); + ], + ]; - $data['user__roles']['permission'] = array( + $data['user__roles']['permission'] = [ 'title' => $this->t('Permission'), 'help' => $this->t('The user permissions.'), - 'field' => array( + 'field' => [ 'id' => 'user_permissions', 'no group by' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'user_permissions', 'real field' => 'roles_target_id', - ), - ); + ], + ]; return $data; } diff --git a/core/modules/user/templates/username.html.twig b/core/modules/user/templates/username.html.twig index 6c1fccbf..10c7a6b0 100644 --- a/core/modules/user/templates/username.html.twig +++ b/core/modules/user/templates/username.html.twig @@ -5,10 +5,16 @@ * * Available variables: * - account: The full account information for the user. - * - name: The user's name, sanitized. + * - uid: The user ID, or zero if not a user. As used in anonymous comments. + * - name: The user's name, sanitized, and optionally truncated. + * - name_raw: The user's name, un-truncated. + * - truncated: Whether the user's name was truncated. * - extra: Additional text to append to the user's name, sanitized. + * - profile_access: Whether the current user has permission to access this + users profile page. * - link_path: The path or URL of the user's profile page, home page, * or other desired page to link to for more information about the user. + * - homepage: (optional) The home page of the account, only set for non users. * - link_options: Options to set on the \Drupal\Core\Url object if linking the * user's name to the user's page. * - attributes: HTML attributes for the containing element. diff --git a/core/modules/user/tests/fixtures/update/drupal-8.user-email-token-2587275.php b/core/modules/user/tests/fixtures/update/drupal-8.user-email-token-2587275.php index 75ec703f..eaa2a9a6 100644 --- a/core/modules/user/tests/fixtures/update/drupal-8.user-email-token-2587275.php +++ b/core/modules/user/tests/fixtures/update/drupal-8.user-email-token-2587275.php @@ -14,9 +14,9 @@ // already. $connection->delete('config')->condition('name', 'user.mail')->execute(); $connection->insert('config') - ->fields(array('collection', 'name', 'data')) - ->values(array( + ->fields(['collection', 'name', 'data']) + ->values([ 'collection' => '', 'name' => 'user.mail', 'data' => "a:10:{s:14:\"cancel_confirm\";a:2:{s:4:\"body\";s:369:\"[user:name],\n\nA request to cancel your account has been made at [site:name].\n\nYou may now cancel your account on [site:url-brief] by clicking this link or copying and pasting it into your browser:\n\n[user:cancel-url]\n\nNOTE: The cancellation of your account is not reversible.\n\nThis link expires in one day and nothing will happen if it is not used.\n\n-- [site:name] team\";s:7:\"subject\";s:59:\"Account cancellation request for [user:name] at [site:name]\";}s:14:\"password_reset\";a:2:{s:4:\"body\";s:397:\"[user:name],\n\nA request to reset the password for your account has been made at [site:name].\n\nYou may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password. It expires after one day and nothing will happen if it's not used.\n\n-- [site:name] team\";s:7:\"subject\";s:60:\"Replacement login information for [user:name] at [site:name]\";}s:22:\"register_admin_created\";a:2:{s:4:\"body\";s:463:\"[user:name],\n\nA site administrator at [site:name] has created an account for you. You may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:58:\"An administrator created an account for you at [site:name]\";}s:29:\"register_no_approval_required\";a:2:{s:4:\"body\";s:437:\"[user:name],\n\nThank you for registering at [site:name]. You may now log in by clicking this link or copying and pasting it to your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:46:\"Account details for [user:name] at [site:name]\";}s:25:\"register_pending_approval\";a:2:{s:4:\"body\";s:281:\"[user:name],\n\nThank you for registering at [site:name]. Your application for an account is currently pending approval. Once it has been approved, you will receive another email containing information about how to log in, set your password, and other details.\n\n\n-- [site:name] team\";s:7:\"subject\";s:71:\"Account details for [user:name] at [site:name] (pending admin approval)\";}s:31:\"register_pending_approval_admin\";a:2:{s:4:\"body\";s:56:\"[user:name] has applied for an account.\n\n[user:edit-url]\";s:7:\"subject\";s:71:\"Account details for [user:name] at [site:name] (pending admin approval)\";}s:16:\"status_activated\";a:2:{s:4:\"body\";s:446:\"[user:name],\n\nYour account at [site:name] has been activated.\n\nYou may now log in by clicking this link or copying and pasting it into your browser:\n\n[user:one-time-login-url]\n\nThis link can only be used once to log in and will lead you to a page where you can set your password.\n\nAfter setting your password, you will be able to log in at [site:login-url] in the future using:\n\nusername: [user:name]\npassword: Your password\n\n-- [site:name] team\";s:7:\"subject\";s:57:\"Account details for [user:name] at [site:name] (approved)\";}s:14:\"status_blocked\";a:2:{s:4:\"body\";s:89:\"[user:name],\n\nYour account on [site:account-name] has been blocked.\n\n-- [site:name] team\";s:7:\"subject\";s:56:\"Account details for [user:name] at [site:name] (blocked)\";}s:15:\"status_canceled\";a:2:{s:4:\"body\";s:82:\"[user:name],\n\nYour account on [site:name] has been canceled.\n\n-- [site:name] team\";s:7:\"subject\";s:57:\"Account details for [user:name] at [site:name] (canceled)\";}s:8:\"langcode\";s:2:\"en\";}" -))->execute(); +])->execute(); diff --git a/core/modules/user/tests/modules/user_access_test/user_access_test.info.yml b/core/modules/user/tests/modules/user_access_test/user_access_test.info.yml index 17507991..44ca640b 100644 --- a/core/modules/user/tests/modules/user_access_test/user_access_test.info.yml +++ b/core/modules/user/tests/modules/user_access_test/user_access_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/tests/modules/user_custom_phpass_params_test/user_custom_phpass_params_test.info.yml b/core/modules/user/tests/modules/user_custom_phpass_params_test/user_custom_phpass_params_test.info.yml index 2639a7ac..99269b3f 100644 --- a/core/modules/user/tests/modules/user_custom_phpass_params_test/user_custom_phpass_params_test.info.yml +++ b/core/modules/user/tests/modules/user_custom_phpass_params_test/user_custom_phpass_params_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/tests/modules/user_form_test/user_form_test.info.yml b/core/modules/user/tests/modules/user_form_test/user_form_test.info.yml index 0ae9857d..104c903d 100644 --- a/core/modules/user/tests/modules/user_form_test/user_form_test.info.yml +++ b/core/modules/user/tests/modules/user_form_test/user_form_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml index 8388c154..face52e4 100644 --- a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml +++ b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module index a036c65c..9baf8ab4 100644 --- a/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module +++ b/core/modules/user/tests/modules/user_hooks_test/user_hooks_test.module @@ -13,7 +13,7 @@ use Drupal\Component\Utility\SafeMarkup; function user_hooks_test_user_format_name_alter(&$name, $account) { if (\Drupal::state()->get('user_hooks_test_user_format_name_alter', FALSE)) { if (\Drupal::state()->get('user_hooks_test_user_format_name_alter_safe', FALSE)) { - $name = SafeMarkup::format('@uid', array('@uid' => $account->id())); + $name = SafeMarkup::format('@uid', ['@uid' => $account->id()]); } else { $name = '' . $account->id() . ''; diff --git a/core/modules/user/tests/modules/user_test_views/user_test_views.info.yml b/core/modules/user/tests/modules/user_test_views/user_test_views.info.yml index 60aeec20..e2aa3f68 100644 --- a/core/modules/user/tests/modules/user_test_views/user_test_views.info.yml +++ b/core/modules/user/tests/modules/user_test_views/user_test_views.info.yml @@ -8,8 +8,8 @@ dependencies: - user - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/tests/src/Functional/AccessRoleUITest.php b/core/modules/user/tests/src/Functional/AccessRoleUITest.php new file mode 100644 index 00000000..6c1004c9 --- /dev/null +++ b/core/modules/user/tests/src/Functional/AccessRoleUITest.php @@ -0,0 +1,64 @@ +container->get('entity.manager'); + $entity_manager->getStorage('user_role')->create(['id' => 'custom_role', 'label' => 'Custom role'])->save(); + $access_url = "admin/structure/views/nojs/display/test_access_role/default/access_options"; + $this->drupalPostForm($access_url, ['access_options[role][custom_role]' => 1], t('Apply')); + $this->assertResponse(200); + + $this->drupalPostForm(NULL, [], t('Save')); + $view = $entity_manager->getStorage('view')->load('test_access_role'); + + $display = $view->getDisplay('default'); + $this->assertEqual($display['display_options']['access']['options']['role'], ['custom_role' => 'custom_role']); + + // Test changing access plugin from role to none. + $this->drupalPostForm('admin/structure/views/nojs/display/test_access_role/default/access', ['access[type]' => 'none'], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); + // Verify that role option is not set. + $view = $entity_manager->getStorage('view')->load('test_access_role'); + $display = $view->getDisplay('default'); + $this->assertFalse(isset($display['display_options']['access']['options']['role'])); + } + +} diff --git a/core/modules/user/tests/src/Functional/Update/UserUpdateEmailToken.php b/core/modules/user/tests/src/Functional/Update/UserUpdateEmailToken.php new file mode 100644 index 00000000..a01c8a57 --- /dev/null +++ b/core/modules/user/tests/src/Functional/Update/UserUpdateEmailToken.php @@ -0,0 +1,35 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/drupal-8.user-email-token-2587275.php', + ]; + } + + /** + * Tests that email token in status_blocked of user.mail is updated. + */ + public function testEmailToken() { + $mail = \Drupal::config('user.mail')->get('status_blocked'); + $this->assertTrue(strpos($mail['body'], '[site:account-name]')); + $this->runUpdates(); + $mail = \Drupal::config('user.mail')->get('status_blocked'); + $this->assertFalse(strpos($mail['body'], '[site:account-name]')); + } + +} diff --git a/core/modules/user/tests/src/Functional/Update/UserUpdateOrderPermissionsTest.php b/core/modules/user/tests/src/Functional/Update/UserUpdateOrderPermissionsTest.php new file mode 100644 index 00000000..4d6e7f96 --- /dev/null +++ b/core/modules/user/tests/src/Functional/Update/UserUpdateOrderPermissionsTest.php @@ -0,0 +1,38 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + ]; + } + + /** + * Tests that permissions are ordered by machine name. + */ + public function testPermissionsOrder() { + $authenticated = Role::load('authenticated'); + $permissions = $authenticated->getPermissions(); + sort($permissions); + $this->assertNotIdentical($permissions, $authenticated->getPermissions()); + + $this->runUpdates(); + $authenticated = Role::load('authenticated'); + $this->assertIdentical($permissions, $authenticated->getPermissions()); + } + +} diff --git a/core/modules/user/src/Tests/UserCacheTagsTest.php b/core/modules/user/tests/src/Functional/UserCacheTagsTest.php similarity index 93% rename from core/modules/user/src/Tests/UserCacheTagsTest.php rename to core/modules/user/tests/src/Functional/UserCacheTagsTest.php index 8dc7437f..a9e98575 100644 --- a/core/modules/user/src/Tests/UserCacheTagsTest.php +++ b/core/modules/user/tests/src/Functional/UserCacheTagsTest.php @@ -1,6 +1,6 @@ drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); } /** * Attempt to cancel account without permission. */ - function testUserCancelWithoutPermission() { + public function testUserCancelWithoutPermission() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $account = $this->drupalCreateUser(array()); + $account = $this->drupalCreateUser([]); $this->drupalLogin($account); // Load a real user object. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); // Create a node. - $node = $this->drupalCreateNode(array('uid' => $account->id())); + $node = $this->drupalCreateNode(['uid' => $account->id()]); // Attempt to cancel account. $this->drupalGet('user/' . $account->id() . '/edit'); @@ -56,12 +56,12 @@ function testUserCancelWithoutPermission() { $timestamp = $account->getLastLoginTime(); $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp)); $this->assertResponse(403, 'Bogus cancelling request rejected.'); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->isActive(), 'User account was not canceled.'); // Confirm user's content has not been altered. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $test_node = $node_storage->load($node->id()); $this->assertTrue(($test_node->getOwnerId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.'); } @@ -70,21 +70,21 @@ function testUserCancelWithoutPermission() { * Test ability to change the permission for canceling users. */ public function testUserCancelChangePermission() { - \Drupal::service('module_installer')->install(array('user_form_test')); + \Drupal::service('module_installer')->install(['user_form_test']); \Drupal::service('router.builder')->rebuild(); $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); // Create a regular user. - $account = $this->drupalCreateUser(array()); + $account = $this->drupalCreateUser([]); - $admin_user = $this->drupalCreateUser(array('cancel other accounts')); + $admin_user = $this->drupalCreateUser(['cancel other accounts']); $this->drupalLogin($admin_user); // Delete regular user. - $this->drupalPostForm('user_form_test_cancel/' . $account->id(), array(), t('Cancel account')); + $this->drupalPostForm('user_form_test_cancel/' . $account->id(), [], t('Cancel account')); // Confirm deletion. - $this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), 'User deleted.'); + $this->assertRaw(t('%name has been deleted.', ['%name' => $account->getUsername()]), 'User deleted.'); $this->assertFalse(User::load($account->id()), 'User is not found in the database.'); } @@ -94,17 +94,17 @@ public function testUserCancelChangePermission() { * This should never be possible, or the site owner would become unable to * administer the site. */ - function testUserCancelUid1() { + public function testUserCancelUid1() { $user_storage = $this->container->get('entity.manager')->getStorage('user'); - \Drupal::service('module_installer')->install(array('views')); + \Drupal::service('module_installer')->install(['views']); \Drupal::service('router.builder')->rebuild(); // Update uid 1's name and password to we know it. $password = user_password(); - $account = array( + $account = [ 'name' => 'user1', 'pass' => $this->container->get('password')->hash(trim($password)), - ); + ]; // We cannot use $account->save() here, because this would result in the // password being hashed again. db_update('users_field_data') @@ -113,21 +113,21 @@ function testUserCancelUid1() { ->execute(); // Reload and log in uid 1. - $user_storage->resetCache(array(1)); + $user_storage->resetCache([1]); $user1 = $user_storage->load(1); $user1->pass_raw = $password; // Try to cancel uid 1's account with a different user. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); - $edit = array( + $edit = [ 'action' => 'user_cancel_user_action', 'user_bulk_form[0]' => TRUE, - ); + ]; $this->drupalPostForm('admin/people', $edit, t('Apply to selected items')); // Verify that uid 1's account was not cancelled. - $user_storage->resetCache(array(1)); + $user_storage->resetCache([1]); $user1 = $user_storage->load(1); $this->assertTrue($user1->isActive(), 'User #1 still exists and is not blocked.'); } @@ -135,20 +135,20 @@ function testUserCancelUid1() { /** * Attempt invalid account cancellations. */ - function testUserCancelInvalid() { + public function testUserCancelInvalid() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $account = $this->drupalCreateUser(array('cancel account')); + $account = $this->drupalCreateUser(['cancel account']); $this->drupalLogin($account); // Load a real user object. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); // Create a node. - $node = $this->drupalCreateNode(array('uid' => $account->id())); + $node = $this->drupalCreateNode(['uid' => $account->id()]); // Attempt to cancel account. $this->drupalPostForm('user/' . $account->id() . '/edit', NULL, t('Cancel account')); @@ -162,7 +162,7 @@ function testUserCancelInvalid() { $bogus_timestamp = $timestamp + 60; $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$bogus_timestamp/" . user_pass_rehash($account, $bogus_timestamp)); $this->assertText(t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'), 'Bogus cancelling request rejected.'); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->isActive(), 'User account was not canceled.'); @@ -170,12 +170,12 @@ function testUserCancelInvalid() { $bogus_timestamp = $timestamp - 86400 - 60; $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$bogus_timestamp/" . user_pass_rehash($account, $bogus_timestamp)); $this->assertText(t('You have tried to use an account cancellation link that has expired. Please request a new one using the form below.'), 'Expired cancel account request rejected.'); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->isActive(), 'User account was not canceled.'); // Confirm user's content has not been altered. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $test_node = $node_storage->load($node->id()); $this->assertTrue(($test_node->getOwnerId() == $account->id() && $test_node->isPublished()), 'Node of the user has not been altered.'); } @@ -183,16 +183,16 @@ function testUserCancelInvalid() { /** * Disable account and keep all content. */ - function testUserBlock() { + public function testUserBlock() { $this->config('user.settings')->set('cancel_method', 'user_cancel_block')->save(); $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $web_user = $this->drupalCreateUser(array('cancel account')); + $web_user = $this->drupalCreateUser(['cancel account']); $this->drupalLogin($web_user); // Load a real user object. - $user_storage->resetCache(array($web_user->id())); + $user_storage->resetCache([$web_user->id()]); $account = $user_storage->load($web_user->id()); // Attempt to cancel account. @@ -210,18 +210,18 @@ function testUserBlock() { // Confirm account cancellation request. $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp)); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->isBlocked(), 'User has been blocked.'); // Confirm that the confirmation message made it through to the end user. - $this->assertRaw(t('%name has been disabled.', array('%name' => $account->getUsername())), "Confirmation message displayed to user."); + $this->assertRaw(t('%name has been disabled.', ['%name' => $account->getUsername()]), "Confirmation message displayed to user."); } /** * Disable account and unpublish all content. */ - function testUserBlockUnpublish() { + public function testUserBlockUnpublish() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $this->config('user.settings')->set('cancel_method', 'user_cancel_block_unpublish')->save(); // Create comment field on page. @@ -229,14 +229,14 @@ function testUserBlockUnpublish() { $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $account = $this->drupalCreateUser(array('cancel account')); + $account = $this->drupalCreateUser(['cancel account']); $this->drupalLogin($account); // Load a real user object. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); // Create a node with two revisions. - $node = $this->drupalCreateNode(array('uid' => $account->id())); + $node = $this->drupalCreateNode(['uid' => $account->id()]); $settings = get_object_vars($node); $settings['revision'] = 1; $node = $this->drupalCreateNode($settings); @@ -244,7 +244,7 @@ function testUserBlockUnpublish() { // Add a comment to the page. $comment_subject = $this->randomMachineName(8); $comment_body = $this->randomMachineName(8); - $comment = Comment::create(array( + $comment = Comment::create([ 'subject' => $comment_subject, 'comment_body' => $comment_body, 'entity_id' => $node->id(), @@ -252,7 +252,7 @@ function testUserBlockUnpublish() { 'field_name' => 'comment', 'status' => CommentInterface::PUBLISHED, 'uid' => $account->id(), - )); + ]); $comment->save(); // Attempt to cancel account. @@ -268,30 +268,30 @@ function testUserBlockUnpublish() { // Confirm account cancellation request. $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp)); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); $this->assertTrue($account->isBlocked(), 'User has been blocked.'); // Confirm user's content has been unpublished. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $test_node = $node_storage->load($node->id()); $this->assertFalse($test_node->isPublished(), 'Node of the user has been unpublished.'); $test_node = node_revision_load($node->getRevisionId()); $this->assertFalse($test_node->isPublished(), 'Node revision of the user has been unpublished.'); $storage = \Drupal::entityManager()->getStorage('comment'); - $storage->resetCache(array($comment->id())); + $storage->resetCache([$comment->id()]); $comment = $storage->load($comment->id()); $this->assertFalse($comment->isPublished(), 'Comment of the user has been unpublished.'); // Confirm that the confirmation message made it through to the end user. - $this->assertRaw(t('%name has been disabled.', array('%name' => $account->getUsername())), "Confirmation message displayed to user."); + $this->assertRaw(t('%name has been disabled.', ['%name' => $account->getUsername()]), "Confirmation message displayed to user."); } /** * Delete account and anonymize all content. */ - function testUserAnonymize() { + public function testUserAnonymize() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); // Create comment field on page. @@ -299,19 +299,19 @@ function testUserAnonymize() { $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $account = $this->drupalCreateUser(array('cancel account')); + $account = $this->drupalCreateUser(['cancel account']); $this->drupalLogin($account); // Load a real user object. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); // Create a simple node. - $node = $this->drupalCreateNode(array('uid' => $account->id())); + $node = $this->drupalCreateNode(['uid' => $account->id()]); // Add a comment to the page. $comment_subject = $this->randomMachineName(8); $comment_body = $this->randomMachineName(8); - $comment = Comment::create(array( + $comment = Comment::create([ 'subject' => $comment_subject, 'comment_body' => $comment_body, 'entity_id' => $node->id(), @@ -319,23 +319,24 @@ function testUserAnonymize() { 'field_name' => 'comment', 'status' => CommentInterface::PUBLISHED, 'uid' => $account->id(), - )); + ]); $comment->save(); // Create a node with two revisions, the initial one belonging to the // cancelling user. - $revision_node = $this->drupalCreateNode(array('uid' => $account->id())); + $revision_node = $this->drupalCreateNode(['uid' => $account->id()]); $revision = $revision_node->getRevisionId(); $settings = get_object_vars($revision_node); $settings['revision'] = 1; - $settings['uid'] = 1; // Set new/current revision to someone else. + // Set new/current revision to someone else. + $settings['uid'] = 1; $revision_node = $this->drupalCreateNode($settings); // Attempt to cancel account. $this->drupalGet('user/' . $account->id() . '/edit'); $this->drupalPostForm(NULL, NULL, t('Cancel account')); $this->assertText(t('Are you sure you want to cancel your account?'), 'Confirmation form to cancel account displayed.'); - $this->assertRaw(t('Your account will be removed and all account information deleted. All of your content will be assigned to the %anonymous-name user.', array('%anonymous-name' => $this->config('user.settings')->get('anonymous'))), 'Informs that all content will be attributed to anonymous account.'); + $this->assertRaw(t('Your account will be removed and all account information deleted. All of your content will be assigned to the %anonymous-name user.', ['%anonymous-name' => $this->config('user.settings')->get('anonymous')]), 'Informs that all content will be attributed to anonymous account.'); // Confirm account cancellation. $timestamp = time(); @@ -344,28 +345,28 @@ function testUserAnonymize() { // Confirm account cancellation request. $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp)); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $this->assertFalse($user_storage->load($account->id()), 'User is not found in the database.'); // Confirm that user's content has been attributed to anonymous user. $anonymous_user = User::getAnonymousUser(); - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $test_node = $node_storage->load($node->id()); $this->assertTrue(($test_node->getOwnerId() == 0 && $test_node->isPublished()), 'Node of the user has been attributed to anonymous user.'); $test_node = node_revision_load($revision, TRUE); $this->assertTrue(($test_node->getRevisionUser()->id() == 0 && $test_node->isPublished()), 'Node revision of the user has been attributed to anonymous user.'); - $node_storage->resetCache(array($revision_node->id())); + $node_storage->resetCache([$revision_node->id()]); $test_node = $node_storage->load($revision_node->id()); $this->assertTrue(($test_node->getOwnerId() != 0 && $test_node->isPublished()), "Current revision of the user's node was not attributed to anonymous user."); $storage = \Drupal::entityManager()->getStorage('comment'); - $storage->resetCache(array($comment->id())); + $storage->resetCache([$comment->id()]); $test_comment = $storage->load($comment->id()); $this->assertTrue(($test_comment->getOwnerId() == 0 && $test_comment->isPublished()), 'Comment of the user has been attributed to anonymous user.'); $this->assertEqual($test_comment->getAuthorName(), $anonymous_user->getDisplayName(), 'Comment of the user has been attributed to anonymous user name.'); // Confirm that the confirmation message made it through to the end user. - $this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), "Confirmation message displayed to user."); + $this->assertRaw(t('%name has been deleted.', ['%name' => $account->getUsername()]), "Confirmation message displayed to user."); } /** @@ -377,7 +378,7 @@ public function testUserAnonymizeBatch() { $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $account = $this->drupalCreateUser(array('cancel account')); + $account = $this->drupalCreateUser(['cancel account']); $this->drupalLogin($account); // Load a real user object. $user_storage->resetCache([$account->id()]); @@ -395,7 +396,7 @@ public function testUserAnonymizeBatch() { $this->drupalGet('user/' . $account->id() . '/edit'); $this->drupalPostForm(NULL, NULL, t('Cancel account')); $this->assertText(t('Are you sure you want to cancel your account?'), 'Confirmation form to cancel account displayed.'); - $this->assertRaw(t('Your account will be removed and all account information deleted. All of your content will be assigned to the %anonymous-name user.', array('%anonymous-name' => $this->config('user.settings')->get('anonymous'))), 'Informs that all content will be attributed to anonymous account.'); + $this->assertRaw(t('Your account will be removed and all account information deleted. All of your content will be assigned to the %anonymous-name user.', ['%anonymous-name' => $this->config('user.settings')->get('anonymous')]), 'Informs that all content will be attributed to anonymous account.'); // Confirm account cancellation. $timestamp = time(); @@ -418,43 +419,44 @@ public function testUserAnonymizeBatch() { /** * Delete account and remove all content. */ - function testUserDelete() { + public function testUserDelete() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $this->config('user.settings')->set('cancel_method', 'user_cancel_delete')->save(); - \Drupal::service('module_installer')->install(array('comment')); + \Drupal::service('module_installer')->install(['comment']); $this->resetAll(); $this->addDefaultCommentField('node', 'page'); $user_storage = $this->container->get('entity.manager')->getStorage('user'); // Create a user. - $account = $this->drupalCreateUser(array('cancel account', 'post comments', 'skip comment approval')); + $account = $this->drupalCreateUser(['cancel account', 'post comments', 'skip comment approval']); $this->drupalLogin($account); // Load a real user object. - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); // Create a simple node. - $node = $this->drupalCreateNode(array('uid' => $account->id())); + $node = $this->drupalCreateNode(['uid' => $account->id()]); // Create comment. - $edit = array(); + $edit = []; $edit['subject[0][value]'] = $this->randomMachineName(8); $edit['comment_body[0][value]'] = $this->randomMachineName(16); $this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit, t('Preview')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertText(t('Your comment has been posted.')); - $comments = entity_load_multiple_by_properties('comment', array('subject' => $edit['subject[0][value]'])); + $comments = entity_load_multiple_by_properties('comment', ['subject' => $edit['subject[0][value]']]); $comment = reset($comments); $this->assertTrue($comment->id(), 'Comment found.'); // Create a node with two revisions, the initial one belonging to the // cancelling user. - $revision_node = $this->drupalCreateNode(array('uid' => $account->id())); + $revision_node = $this->drupalCreateNode(['uid' => $account->id()]); $revision = $revision_node->getRevisionId(); $settings = get_object_vars($revision_node); $settings['revision'] = 1; - $settings['uid'] = 1; // Set new/current revision to someone else. + // Set new/current revision to someone else. + $settings['uid'] = 1; $revision_node = $this->drupalCreateNode($settings); // Attempt to cancel account. @@ -470,80 +472,80 @@ function testUserDelete() { // Confirm account cancellation request. $this->drupalGet("user/" . $account->id() . "/cancel/confirm/$timestamp/" . user_pass_rehash($account, $timestamp)); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $this->assertFalse($user_storage->load($account->id()), 'User is not found in the database.'); // Confirm that user's content has been deleted. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $this->assertFalse($node_storage->load($node->id()), 'Node of the user has been deleted.'); $this->assertFalse(node_revision_load($revision), 'Node revision of the user has been deleted.'); - $node_storage->resetCache(array($revision_node->id())); + $node_storage->resetCache([$revision_node->id()]); $this->assertTrue($node_storage->load($revision_node->id()), "Current revision of the user's node was not deleted."); - \Drupal::entityManager()->getStorage('comment')->resetCache(array($comment->id())); + \Drupal::entityManager()->getStorage('comment')->resetCache([$comment->id()]); $this->assertFalse(Comment::load($comment->id()), 'Comment of the user has been deleted.'); // Confirm that the confirmation message made it through to the end user. - $this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), "Confirmation message displayed to user."); + $this->assertRaw(t('%name has been deleted.', ['%name' => $account->getUsername()]), "Confirmation message displayed to user."); } /** * Create an administrative user and delete another user. */ - function testUserCancelByAdmin() { + public function testUserCancelByAdmin() { $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); // Create a regular user. - $account = $this->drupalCreateUser(array()); + $account = $this->drupalCreateUser([]); // Create administrative user. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); // Delete regular user. $this->drupalGet('user/' . $account->id() . '/edit'); $this->drupalPostForm(NULL, NULL, t('Cancel account')); - $this->assertRaw(t('Are you sure you want to cancel the account %name?', array('%name' => $account->getUsername())), 'Confirmation form to cancel account displayed.'); + $this->assertRaw(t('Are you sure you want to cancel the account %name?', ['%name' => $account->getUsername()]), 'Confirmation form to cancel account displayed.'); $this->assertText(t('Select the method to cancel the account above.'), 'Allows to select account cancellation method.'); // Confirm deletion. $this->drupalPostForm(NULL, NULL, t('Cancel account')); - $this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), 'User deleted.'); + $this->assertRaw(t('%name has been deleted.', ['%name' => $account->getUsername()]), 'User deleted.'); $this->assertFalse(User::load($account->id()), 'User is not found in the database.'); } /** * Tests deletion of a user account without an email address. */ - function testUserWithoutEmailCancelByAdmin() { + public function testUserWithoutEmailCancelByAdmin() { $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); // Create a regular user. - $account = $this->drupalCreateUser(array()); + $account = $this->drupalCreateUser([]); // This user has no email address. $account->mail = ''; $account->save(); // Create administrative user. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); // Delete regular user without email address. $this->drupalGet('user/' . $account->id() . '/edit'); $this->drupalPostForm(NULL, NULL, t('Cancel account')); - $this->assertRaw(t('Are you sure you want to cancel the account %name?', array('%name' => $account->getUsername())), 'Confirmation form to cancel account displayed.'); + $this->assertRaw(t('Are you sure you want to cancel the account %name?', ['%name' => $account->getUsername()]), 'Confirmation form to cancel account displayed.'); $this->assertText(t('Select the method to cancel the account above.'), 'Allows to select account cancellation method.'); // Confirm deletion. $this->drupalPostForm(NULL, NULL, t('Cancel account')); - $this->assertRaw(t('%name has been deleted.', array('%name' => $account->getUsername())), 'User deleted.'); + $this->assertRaw(t('%name has been deleted.', ['%name' => $account->getUsername()]), 'User deleted.'); $this->assertFalse(User::load($account->id()), 'User is not found in the database.'); } /** * Create an administrative user and mass-delete other users. */ - function testMassUserCancelByAdmin() { - \Drupal::service('module_installer')->install(array('views')); + public function testMassUserCancelByAdmin() { + \Drupal::service('module_installer')->install(['views']); \Drupal::service('router.builder')->rebuild(); $this->config('user.settings')->set('cancel_method', 'user_cancel_reassign')->save(); $user_storage = $this->container->get('entity.manager')->getStorage('user'); @@ -551,18 +553,18 @@ function testMassUserCancelByAdmin() { $this->config('user.settings')->set('notify.status_canceled', TRUE)->save(); // Create administrative user. - $admin_user = $this->drupalCreateUser(array('administer users')); + $admin_user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($admin_user); // Create some users. - $users = array(); + $users = []; for ($i = 0; $i < 3; $i++) { - $account = $this->drupalCreateUser(array()); + $account = $this->drupalCreateUser([]); $users[$account->id()] = $account; } // Cancel user accounts, including own one. - $edit = array(); + $edit = []; $edit['action'] = 'user_cancel_user_action'; for ($i = 0; $i <= 4; $i++) { $edit['user_bulk_form[' . $i . ']'] = TRUE; @@ -577,8 +579,8 @@ function testMassUserCancelByAdmin() { $this->drupalPostForm(NULL, NULL, t('Cancel accounts')); $status = TRUE; foreach ($users as $account) { - $status = $status && (strpos($this->content, $account->getUsername() . ' has been deleted.') !== FALSE); - $user_storage->resetCache(array($account->id())); + $status = $status && (strpos($this->getTextContent(), $account->getUsername() . ' has been deleted.') !== FALSE); + $user_storage->resetCache([$account->id()]); $status = $status && !$user_storage->load($account->id()); } $this->assertTrue($status, 'Users deleted and not found in the database.'); @@ -589,9 +591,25 @@ function testMassUserCancelByAdmin() { $this->assertTrue($admin_user->isActive(), 'Administrative user is found in the database and enabled.'); // Verify that uid 1's account was not cancelled. - $user_storage->resetCache(array(1)); + $user_storage->resetCache([1]); $user1 = $user_storage->load(1); $this->assertTrue($user1->isActive(), 'User #1 still exists and is not blocked.'); } + /** + * Tests user cancel with node access. + */ + public function testUserDeleteWithContentAndNodeAccess() { + + \Drupal::service('module_installer')->install(['node_access_test']); + // Rebuild node access. + node_access_rebuild(); + + $account = $this->drupalCreateUser(['access content']); + $node = $this->drupalCreateNode(['type' => 'page', 'uid' => $account->id()]); + $account->delete(); + $load2 = \Drupal::entityTypeManager()->getStorage('node')->load($node->id()); + $this->assertTrue(empty($load2)); + } + } diff --git a/core/modules/user/tests/src/Functional/UserCreateFailMailTest.php b/core/modules/user/tests/src/Functional/UserCreateFailMailTest.php new file mode 100644 index 00000000..38f2514a --- /dev/null +++ b/core/modules/user/tests/src/Functional/UserCreateFailMailTest.php @@ -0,0 +1,45 @@ +drupalCreateUser(['administer users']); + $this->drupalLogin($user); + + // Replace the mail functionality with a fake, malfunctioning service. + $this->config('system.mail')->set('interface.default', 'test_php_mail_failure')->save(); + // Create a user, but fail to send an email. + $name = $this->randomMachineName(); + $edit = [ + 'name' => $name, + 'mail' => $this->randomMachineName() . '@example.com', + 'pass[pass1]' => $pass = $this->randomString(), + 'pass[pass2]' => $pass, + 'notify' => TRUE, + ]; + $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); + + $this->assertText(t('Unable to send email. Contact the site administrator if the problem persists.')); + $this->assertNoText(t('A welcome message with further instructions has been emailed to the new user @name.', ['@name' => $edit['name']])); + } + +} diff --git a/core/modules/user/tests/src/Functional/UserDeleteTest.php b/core/modules/user/tests/src/Functional/UserDeleteTest.php new file mode 100644 index 00000000..5803a049 --- /dev/null +++ b/core/modules/user/tests/src/Functional/UserDeleteTest.php @@ -0,0 +1,55 @@ +drupalCreateUser(['access user profiles']); + $user_b = $this->drupalCreateUser(['access user profiles']); + $user_c = $this->drupalCreateUser(['access user profiles']); + + $uids = [$user_a->id(), $user_b->id(), $user_c->id()]; + + // These users should have a role + $query = db_select('user__roles', 'r'); + $roles_created = $query + ->fields('r', ['entity_id']) + ->condition('entity_id', $uids, 'IN') + ->countQuery() + ->execute() + ->fetchField(); + + $this->assertTrue($roles_created > 0, 'Role assignments created for new users and deletion of role assignments can be tested'); + // We should be able to load one of the users. + $this->assertTrue(User::load($user_a->id()), 'User is created and deletion of user can be tested'); + // Delete the users. + user_delete_multiple($uids); + // Test if the roles assignments are deleted. + $query = db_select('user__roles', 'r'); + $roles_after_deletion = $query + ->fields('r', ['entity_id']) + ->condition('entity_id', $uids, 'IN') + ->countQuery() + ->execute() + ->fetchField(); + $this->assertTrue($roles_after_deletion == 0, 'Role assignments deleted along with users'); + // Test if the users are deleted, User::load() will return NULL. + $this->assertNull(User::load($user_a->id()), format_string('User with id @uid deleted.', ['@uid' => $user_a->id()])); + $this->assertNull(User::load($user_b->id()), format_string('User with id @uid deleted.', ['@uid' => $user_b->id()])); + $this->assertNull(User::load($user_c->id()), format_string('User with id @uid deleted.', ['@uid' => $user_c->id()])); + } + +} diff --git a/core/modules/user/tests/src/Functional/UserEditedOwnAccountTest.php b/core/modules/user/tests/src/Functional/UserEditedOwnAccountTest.php new file mode 100644 index 00000000..a6f4bede --- /dev/null +++ b/core/modules/user/tests/src/Functional/UserEditedOwnAccountTest.php @@ -0,0 +1,43 @@ +config('user.settings')->set('register', USER_REGISTER_ADMINISTRATORS_ONLY)->save(); + + // Create a new user account and log in. + $account = $this->drupalCreateUser(['change own username']); + $this->drupalLogin($account); + + // Change own username. + $edit = []; + $edit['name'] = $this->randomMachineName(); + $this->drupalPostForm('user/' . $account->id() . '/edit', $edit, t('Save')); + + // Log out. + $this->drupalLogout(); + + // Set the new name on the user account and attempt to log back in. + $account->name = $edit['name']; + $this->drupalLogin($account); + } + +} diff --git a/core/modules/user/src/Tests/UserEntityCallbacksTest.php b/core/modules/user/tests/src/Functional/UserEntityCallbacksTest.php similarity index 88% rename from core/modules/user/src/Tests/UserEntityCallbacksTest.php rename to core/modules/user/tests/src/Functional/UserEntityCallbacksTest.php index 944b352c..feea805a 100644 --- a/core/modules/user/src/Tests/UserEntityCallbacksTest.php +++ b/core/modules/user/tests/src/Functional/UserEntityCallbacksTest.php @@ -1,8 +1,8 @@ assertEqual($this->account->label(), $this->account->getUsername(), 'The username should be used as label'); // Setup a random anonymous name to be sure the name is used. diff --git a/core/modules/user/src/Tests/UserLanguageTest.php b/core/modules/user/tests/src/Functional/UserLanguageTest.php similarity index 82% rename from core/modules/user/src/Tests/UserLanguageTest.php rename to core/modules/user/tests/src/Functional/UserLanguageTest.php index 5c5f73f0..0e6c0f1a 100644 --- a/core/modules/user/src/Tests/UserLanguageTest.php +++ b/core/modules/user/tests/src/Functional/UserLanguageTest.php @@ -1,30 +1,30 @@ drupalCreateUser(array('administer languages', 'access administration pages')); + $admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages']); // User to change their default language. $web_user = $this->drupalCreateUser(); @@ -34,12 +34,12 @@ function testUserLanguageConfiguration() { $langcode = 'xx'; // The English name for the language. $name = $this->randomMachineName(16); - $edit = array( + $edit = [ 'predefined_langcode' => 'custom', 'langcode' => $langcode, 'label' => $name, 'direction' => LanguageInterface::DIRECTION_LTR, - ); + ]; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->drupalLogout(); @@ -52,9 +52,9 @@ function testUserLanguageConfiguration() { // Ensure custom language is present. $this->assertText($name, 'Language present on form.'); // Switch to our custom language. - $edit = array( + $edit = [ 'preferred_langcode' => $langcode, - ); + ]; $this->drupalPostForm($path, $edit, t('Save')); // Ensure form was submitted successfully. $this->assertText(t('The changes have been saved.'), 'Changes were saved.'); diff --git a/core/modules/user/tests/src/Functional/UserLoginHttpTest.php b/core/modules/user/tests/src/Functional/UserLoginHttpTest.php index 29b97277..b12a72b5 100644 --- a/core/modules/user/tests/src/Functional/UserLoginHttpTest.php +++ b/core/modules/user/tests/src/Functional/UserLoginHttpTest.php @@ -6,6 +6,7 @@ use Drupal\Core\Url; use Drupal\Tests\BrowserTestBase; use Drupal\user\Controller\UserAuthenticationController; +use Drupal\user\Tests\UserResetEmailTestTrait; use GuzzleHttp\Cookie\CookieJar; use Psr\Http\Message\ResponseInterface; use Symfony\Component\Serializer\Encoder\JsonEncoder; @@ -14,12 +15,14 @@ use Symfony\Component\Serializer\Serializer; /** - * Tests login via direct HTTP. + * Tests login and password reset via direct HTTP. * * @group user */ class UserLoginHttpTest extends BrowserTestBase { + use UserResetEmailTestTrait; + /** * Modules to install. * @@ -61,7 +64,7 @@ protected function setUp() { * @param string $format * The format to use to make the request. * - * @return \Psr\Http\Message\ResponseInterface The HTTP response. + * @return \Psr\Http\Message\ResponseInterface * The HTTP response. */ protected function loginRequest($name, $pass, $format = 'json') { @@ -92,99 +95,153 @@ protected function loginRequest($name, $pass, $format = 'json') { * Tests user session life cycle. */ public function testLogin() { + // Without the serialization module only JSON is supported. + $this->doTestLogin('json'); + + // Enable serialization so we have access to additional formats. + $this->container->get('module_installer')->install(['serialization']); + $this->doTestLogin('json'); + $this->doTestLogin('xml'); + $this->doTestLogin('hal_json'); + } + + /** + * Do login testing for a given serialization format. + * + * @param string $format + * Serialization format. + */ + protected function doTestLogin($format) { $client = \Drupal::httpClient(); - foreach ([FALSE, TRUE] as $serialization_enabled_option) { - if ($serialization_enabled_option) { - /** @var \Drupal\Core\Extension\ModuleInstaller $module_installer */ - $module_installer = $this->container->get('module_installer'); - $module_installer->install(['serialization']); - $formats = ['json', 'xml', 'hal_json']; - } - else { - // Without the serialization module only JSON is supported. - $formats = ['json']; - } - foreach ($formats as $format) { - // Create new user for each iteration to reset flood. - // Grant the user administer users permissions to they can see the - // 'roles' field. - $account = $this->drupalCreateUser(['administer users']); - $name = $account->getUsername(); - $pass = $account->passRaw; + // Create new user for each iteration to reset flood. + // Grant the user administer users permissions to they can see the + // 'roles' field. + $account = $this->drupalCreateUser(['administer users']); + $name = $account->getUsername(); + $pass = $account->passRaw; - $login_status_url = $this->getLoginStatusUrlString($format); - $response = $client->get($login_status_url); - $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT); + $login_status_url = $this->getLoginStatusUrlString($format); + $response = $client->get($login_status_url); + $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT); - // Flooded. - $this->config('user.flood') - ->set('user_limit', 3) - ->save(); + // Flooded. + $this->config('user.flood') + ->set('user_limit', 3) + ->save(); - $response = $this->loginRequest($name, 'wrong-pass', $format); - $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); + $response = $this->loginRequest($name, 'wrong-pass', $format); + $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); - $response = $this->loginRequest($name, 'wrong-pass', $format); - $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); + $response = $this->loginRequest($name, 'wrong-pass', $format); + $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); - $response = $this->loginRequest($name, 'wrong-pass', $format); - $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); + $response = $this->loginRequest($name, 'wrong-pass', $format); + $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); + + $response = $this->loginRequest($name, 'wrong-pass', $format); + $this->assertHttpResponseWithMessage($response, 403, 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.', $format); + + // After testing the flood control we can increase the limit. + $this->config('user.flood') + ->set('user_limit', 100) + ->save(); - $response = $this->loginRequest($name, 'wrong-pass', $format); - $this->assertHttpResponseWithMessage($response, 403, 'Too many failed login attempts from your IP address. This IP address is temporarily blocked.', $format); + $response = $this->loginRequest(NULL, NULL, $format); + $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.', $format); - // After testing the flood control we can increase the limit. - $this->config('user.flood') - ->set('user_limit', 100) - ->save(); + $response = $this->loginRequest(NULL, $pass, $format); + $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format); - $response = $this->loginRequest(NULL, NULL, $format); - $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.', $format); + $response = $this->loginRequest($name, NULL, $format); + $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format); - $response = $this->loginRequest(NULL, $pass, $format); - $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name.', $format); + // Blocked. + $account + ->block() + ->save(); - $response = $this->loginRequest($name, NULL, $format); - $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.pass.', $format); + $response = $this->loginRequest($name, $pass, $format); + $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format); - // Blocked. - $account - ->block() - ->save(); + $account + ->activate() + ->save(); - $response = $this->loginRequest($name, $pass, $format); - $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format); + $response = $this->loginRequest($name, 'garbage', $format); + $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); - $account - ->activate() - ->save(); + $response = $this->loginRequest('garbage', $pass, $format); + $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); - $response = $this->loginRequest($name, 'garbage', $format); - $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); + $response = $this->loginRequest($name, $pass, $format); + $this->assertEquals(200, $response->getStatusCode()); + $result_data = $this->serializer->decode($response->getBody(), $format); + $this->assertEquals($name, $result_data['current_user']['name']); + $this->assertEquals($account->id(), $result_data['current_user']['uid']); + $this->assertEquals($account->getRoles(), $result_data['current_user']['roles']); + $logout_token = $result_data['logout_token']; - $response = $this->loginRequest('garbage', $pass, $format); - $this->assertHttpResponseWithMessage($response, 400, 'Sorry, unrecognized username or password.', $format); + // Logging in while already logged in results in a 403 with helpful message. + $response = $this->loginRequest($name, $pass, $format); + $this->assertSame(403, $response->getStatusCode()); + $this->assertSame(['message' => 'This route can only be accessed by anonymous users.'], $this->serializer->decode($response->getBody(), $format)); - $response = $this->loginRequest($name, $pass, $format); - $this->assertEquals(200, $response->getStatusCode()); - $result_data = $this->serializer->decode($response->getBody(), $format); - $this->assertEquals($name, $result_data['current_user']['name']); - $this->assertEquals($account->id(), $result_data['current_user']['uid']); - $this->assertEquals($account->getRoles(), $result_data['current_user']['roles']); - $logout_token = $result_data['logout_token']; + $response = $client->get($login_status_url, ['cookies' => $this->cookies]); + $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN); - $response = $client->get($login_status_url, ['cookies' => $this->cookies]); - $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_IN); + $response = $this->logoutRequest($format, $logout_token); + $this->assertEquals(204, $response->getStatusCode()); - $response = $this->logoutRequest($format, $logout_token); - $this->assertEquals(204, $response->getStatusCode()); + $response = $client->get($login_status_url, ['cookies' => $this->cookies]); + $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT); - $response = $client->get($login_status_url, ['cookies' => $this->cookies]); - $this->assertHttpResponse($response, 200, UserAuthenticationController::LOGGED_OUT); + $this->resetFlood(); + } - $this->resetFlood(); - } - } + /** + * Executes a password HTTP request. + * + * @param array $request_body + * The request body. + * @param string $format + * The format to use to make the request. + * + * @return \Psr\Http\Message\ResponseInterface + * The HTTP response. + */ + protected function passwordRequest(array $request_body, $format = 'json') { + $password_reset_url = Url::fromRoute('user.pass.http') + ->setRouteParameter('_format', $format) + ->setAbsolute(); + + $result = \Drupal::httpClient()->post($password_reset_url->toString(), [ + 'body' => $this->serializer->encode($request_body, $format), + 'headers' => [ + 'Accept' => "application/$format", + ], + 'http_errors' => FALSE, + 'cookies' => $this->cookies, + ]); + + return $result; + } + + /** + * Tests user password reset. + */ + public function testPasswordReset() { + // Create a user account. + $account = $this->drupalCreateUser(); + + // Without the serialization module only JSON is supported. + $this->doTestPasswordReset('json', $account); + + // Enable serialization so we have access to additional formats. + $this->container->get('module_installer')->install(['serialization']); + + $this->doTestPasswordReset('json', $account); + $this->doTestPasswordReset('xml', $account); + $this->doTestPasswordReset('hal_json', $account); } /** @@ -343,7 +400,7 @@ public function testPerUserLoginFloodControl() { * @param string $logout_token * The csrf token for user logout. * - * @return \Psr\Http\Message\ResponseInterface The HTTP response. + * @return \Psr\Http\Message\ResponseInterface * The HTTP response. */ protected function logoutRequest($format = 'json', $logout_token = '') { @@ -426,4 +483,47 @@ protected function getLoginStatusUrlString($format = 'json') { return $user_login_status_url->toString(); } + /** + * Do password reset testing for given format and account. + * + * @param string $format + * Serialization format. + * @param \Drupal\user\UserInterface $account + * Test account. + */ + protected function doTestPasswordReset($format, $account) { + $response = $this->passwordRequest([], $format); + $this->assertHttpResponseWithMessage($response, 400, 'Missing credentials.name or credentials.mail', $format); + + $response = $this->passwordRequest(['name' => 'dramallama'], $format); + $this->assertHttpResponseWithMessage($response, 400, 'Unrecognized username or email address.', $format); + + $response = $this->passwordRequest(['mail' => 'llama@drupal.org'], $format); + $this->assertHttpResponseWithMessage($response, 400, 'Unrecognized username or email address.', $format); + + $account + ->block() + ->save(); + + $response = $this->passwordRequest(['name' => $account->getAccountName()], $format); + $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format); + + $response = $this->passwordRequest(['mail' => $account->getEmail()], $format); + $this->assertHttpResponseWithMessage($response, 400, 'The user has not been activated or is blocked.', $format); + + $account + ->activate() + ->save(); + + $response = $this->passwordRequest(['name' => $account->getAccountName()], $format); + $this->assertEquals(200, $response->getStatusCode()); + $this->loginFromResetEmail(); + $this->drupalLogout(); + + $response = $this->passwordRequest(['mail' => $account->getEmail()], $format); + $this->assertEquals(200, $response->getStatusCode()); + $this->loginFromResetEmail(); + $this->drupalLogout(); + } + } diff --git a/core/modules/user/src/Tests/UserMailNotifyTest.php b/core/modules/user/tests/src/Functional/UserMailNotifyTest.php similarity index 96% rename from core/modules/user/src/Tests/UserMailNotifyTest.php rename to core/modules/user/tests/src/Functional/UserMailNotifyTest.php index 9943c5b7..57bebc04 100644 --- a/core/modules/user/src/Tests/UserMailNotifyTest.php +++ b/core/modules/user/tests/src/Functional/UserMailNotifyTest.php @@ -1,6 +1,6 @@ createUser()); $this->assertTrue($return, '_user_mail_notify() returns TRUE.'); foreach ($mail_keys as $key) { - $filter = array('key' => $key); + $filter = ['key' => $key]; $this->assertNotEmpty($this->getMails($filter), "Mails with $key exists."); } $this->assertCount(count($mail_keys), $this->getMails(), 'The expected number of emails sent.'); diff --git a/core/modules/user/src/Tests/UserRolesAssignmentTest.php b/core/modules/user/tests/src/Functional/UserRolesAssignmentTest.php similarity index 76% rename from core/modules/user/src/Tests/UserRolesAssignmentTest.php rename to core/modules/user/tests/src/Functional/UserRolesAssignmentTest.php index 485bd2f3..fc8958c0 100644 --- a/core/modules/user/src/Tests/UserRolesAssignmentTest.php +++ b/core/modules/user/tests/src/Functional/UserRolesAssignmentTest.php @@ -1,19 +1,19 @@ drupalCreateUser(array('administer permissions', 'administer users')); + $admin_user = $this->drupalCreateUser(['administer permissions', 'administer users']); $this->drupalLogin($admin_user); } @@ -21,18 +21,18 @@ protected function setUp() { * Tests that a user can be assigned a role and that the role can be removed * again. */ - function testAssignAndRemoveRole() { - $rid = $this->drupalCreateRole(array('administer users')); + public function testAssignAndRemoveRole() { + $rid = $this->drupalCreateRole(['administer users']); $account = $this->drupalCreateUser(); // Assign the role to the user. - $this->drupalPostForm('user/' . $account->id() . '/edit', array("roles[$rid]" => $rid), t('Save')); + $this->drupalPostForm('user/' . $account->id() . '/edit', ["roles[$rid]" => $rid], t('Save')); $this->assertText(t('The changes have been saved.')); $this->assertFieldChecked('edit-roles-' . $rid, 'Role is assigned.'); $this->userLoadAndCheckRoleAssigned($account, $rid); // Remove the role from the user. - $this->drupalPostForm('user/' . $account->id() . '/edit', array("roles[$rid]" => FALSE), t('Save')); + $this->drupalPostForm('user/' . $account->id() . '/edit', ["roles[$rid]" => FALSE], t('Save')); $this->assertText(t('The changes have been saved.')); $this->assertNoFieldChecked('edit-roles-' . $rid, 'Role is removed from user.'); $this->userLoadAndCheckRoleAssigned($account, $rid, FALSE); @@ -42,18 +42,18 @@ function testAssignAndRemoveRole() { * Tests that when creating a user the role can be assigned. And that it can * be removed again. */ - function testCreateUserWithRole() { - $rid = $this->drupalCreateRole(array('administer users')); + public function testCreateUserWithRole() { + $rid = $this->drupalCreateRole(['administer users']); // Create a new user and add the role at the same time. - $edit = array( + $edit = [ 'name' => $this->randomMachineName(), 'mail' => $this->randomMachineName() . '@example.com', 'pass[pass1]' => $pass = $this->randomString(), 'pass[pass2]' => $pass, "roles[$rid]" => $rid, - ); + ]; $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); - $this->assertText(t('Created a new user account for @name.', array('@name' => $edit['name']))); + $this->assertText(t('Created a new user account for @name.', ['@name' => $edit['name']])); // Get the newly added user. $account = user_load_by_name($edit['name']); @@ -62,7 +62,7 @@ function testCreateUserWithRole() { $this->userLoadAndCheckRoleAssigned($account, $rid); // Remove the role again. - $this->drupalPostForm('user/' . $account->id() . '/edit', array("roles[$rid]" => FALSE), t('Save')); + $this->drupalPostForm('user/' . $account->id() . '/edit', ["roles[$rid]" => FALSE], t('Save')); $this->assertText(t('The changes have been saved.')); $this->assertNoFieldChecked('edit-roles-' . $rid, 'Role is removed from user.'); $this->userLoadAndCheckRoleAssigned($account, $rid, FALSE); @@ -81,7 +81,7 @@ function testCreateUserWithRole() { */ private function userLoadAndCheckRoleAssigned($account, $rid, $is_assigned = TRUE) { $user_storage = $this->container->get('entity.manager')->getStorage('user'); - $user_storage->resetCache(array($account->id())); + $user_storage->resetCache([$account->id()]); $account = $user_storage->load($account->id()); if ($is_assigned) { $this->assertFalse(array_search($rid, $account->getRoles()) === FALSE, 'The role is present in the user object.'); diff --git a/core/modules/user/src/Tests/UserSaveTest.php b/core/modules/user/tests/src/Functional/UserSaveTest.php similarity index 87% rename from core/modules/user/src/Tests/UserSaveTest.php rename to core/modules/user/tests/src/Functional/UserSaveTest.php index 6a454eee..c693b39c 100644 --- a/core/modules/user/src/Tests/UserSaveTest.php +++ b/core/modules/user/tests/src/Functional/UserSaveTest.php @@ -1,8 +1,8 @@ getStorage('user')->getQuery() @@ -48,7 +48,7 @@ function testUserImport() { /** * Ensures that an existing password is unset after the user was saved. */ - function testExistingPasswordRemoval() { + public function testExistingPasswordRemoval() { /** @var \Drupal\user\Entity\User $user */ $user = User::create(['name' => $this->randomMachineName()]); $user->save(); diff --git a/core/modules/user/src/Tests/UserSearchTest.php b/core/modules/user/tests/src/Functional/UserSearchTest.php similarity index 82% rename from core/modules/user/src/Tests/UserSearchTest.php rename to core/modules/user/tests/src/Functional/UserSearchTest.php index d154030e..8ce0319b 100644 --- a/core/modules/user/src/Tests/UserSearchTest.php +++ b/core/modules/user/tests/src/Functional/UserSearchTest.php @@ -1,8 +1,8 @@ drupalCreateUser(array('access user profiles', 'search content'), "foo+bar"); + $user1 = $this->drupalCreateUser(['access user profiles', 'search content'], "foo+bar"); $this->drupalLogin($user1); $keys = $user1->getEmail(); - $edit = array('keys' => $keys); + $edit = ['keys' => $keys]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText(t('Your search yielded no results.'), 'Search by email did not work for non-admin user'); $this->assertText('no results', 'Search by email gave no-match message'); // Verify that a non-matching query gives an appropriate message. $keys = 'nomatch'; - $edit = array('keys' => $keys); + $edit = ['keys' => $keys]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText('no results', 'Non-matching search gave appropriate message'); // Verify that a user with search permission can search for users by name. $keys = $user1->getUsername(); - $edit = array('keys' => $keys); + $edit = ['keys' => $keys]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertLink($keys, 0, 'Search by username worked for non-admin user'); // Verify that searching by sub-string works too. $subkey = substr($keys, 1, 5); - $edit = array('keys' => $subkey); + $edit = ['keys' => $subkey]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertLink($keys, 0, 'Search by username substring worked for non-admin user'); // Verify that wildcard search works. $subkey = substr($keys, 0, 2) . '*' . substr($keys, 4, 2); - $edit = array('keys' => $subkey); + $edit = ['keys' => $subkey]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertLink($keys, 0, 'Search with wildcard worked for non-admin user'); // Verify that a user with 'administer users' permission can search by // email. - $user2 = $this->drupalCreateUser(array('administer users', 'access user profiles', 'search content')); + $user2 = $this->drupalCreateUser(['administer users', 'access user profiles', 'search content']); $this->drupalLogin($user2); $keys = $user2->getEmail(); - $edit = array('keys' => $keys); + $edit = ['keys' => $keys]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText($keys, 'Search by email works for administrative user'); $this->assertText($user2->getUsername(), 'Search by email resulted in username on page for administrative user'); // Verify that a substring works too for email. $subkey = substr($keys, 1, 5); - $edit = array('keys' => $subkey); + $edit = ['keys' => $subkey]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText($keys, 'Search by email substring works for administrative user'); $this->assertText($user2->getUsername(), 'Search by email substring resulted in username on page for administrative user'); // Verify that wildcard search works for email $subkey = substr($keys, 0, 2) . '*' . substr($keys, 4, 2); - $edit = array('keys' => $subkey); + $edit = ['keys' => $subkey]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText($user2->getUsername(), 'Search for email wildcard resulted in username on page for administrative user'); // Verify that if they search by user name, they see email address too. $keys = $user1->getUsername(); - $edit = array('keys' => $keys); + $edit = ['keys' => $keys]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText($keys, 'Search by username works for admin user'); $this->assertText($user1->getEmail(), 'Search by username for admin shows email address too'); @@ -92,25 +92,25 @@ function testUserSearch() { // Verify that users with "administer users" permissions can see blocked // accounts in search results. - $edit = array('keys' => $blocked_user->getUsername()); + $edit = ['keys' => $blocked_user->getUsername()]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText($blocked_user->getUsername(), 'Blocked users are listed on the user search results for users with the "administer users" permission.'); // Verify that users without "administer users" permissions do not see // blocked accounts in search results. $this->drupalLogin($user1); - $edit = array('keys' => $blocked_user->getUsername()); + $edit = ['keys' => $blocked_user->getUsername()]; $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText(t('Your search yielded no results.'), 'Blocked users are hidden from the user search results.'); // Create a user without search permission, and one without user page view // permission. Verify that neither one can access the user search page. - $user3 = $this->drupalCreateUser(array('search content')); + $user3 = $this->drupalCreateUser(['search content']); $this->drupalLogin($user3); $this->drupalGet('search/user'); $this->assertResponse('403', 'User without user profile access cannot search'); - $user4 = $this->drupalCreateUser(array('access user profiles')); + $user4 = $this->drupalCreateUser(['access user profiles']); $this->drupalLogin($user4); $this->drupalGet('search/user'); $this->assertResponse('403', 'User without search permission cannot search'); diff --git a/core/modules/user/src/Tests/UserTokenReplaceTest.php b/core/modules/user/tests/src/Functional/UserTokenReplaceTest.php similarity index 88% rename from core/modules/user/src/Tests/UserTokenReplaceTest.php rename to core/modules/user/tests/src/Functional/UserTokenReplaceTest.php index b8cfde0e..e272b607 100644 --- a/core/modules/user/src/Tests/UserTokenReplaceTest.php +++ b/core/modules/user/tests/src/Functional/UserTokenReplaceTest.php @@ -1,11 +1,11 @@ getCurrentLanguage(); - $url_options = array( + $url_options = [ 'absolute' => TRUE, 'language' => $language_interface, - ); + ]; \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE); \Drupal::state()->set('user_hooks_test_user_format_name_alter_safe', TRUE); // Create two users and log them in one after another. - $user1 = $this->drupalCreateUser(array()); - $user2 = $this->drupalCreateUser(array()); + $user1 = $this->drupalCreateUser([]); + $user2 = $this->drupalCreateUser([]); $this->drupalLogin($user1); $this->drupalLogout(); $this->drupalLogin($user2); @@ -56,7 +56,7 @@ function testUserTokenReplacement() { $global_account = User::load(\Drupal::currentUser()->id()); // Generate and test tokens. - $tests = array(); + $tests = []; $tests['[user:uid]'] = $account->id(); $tests['[user:name]'] = $account->getAccountName(); $tests['[user:account-name]'] = $account->getAccountName(); @@ -121,18 +121,18 @@ function testUserTokenReplacement() { foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); - $output = $token_service->replace($input, array('user' => $anonymous_user), array('langcode' => $language_interface->getId()), $bubbleable_metadata); - $this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input))); + $output = $token_service->replace($input, ['user' => $anonymous_user], ['langcode' => $language_interface->getId()], $bubbleable_metadata); + $this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate login and cancel link. - $tests = array(); + $tests = []; $tests['[user:one-time-login-url]'] = user_pass_reset_url($account); $tests['[user:cancel-url]'] = user_cancel_url($account); // Generate tokens with interface language. - $link = \Drupal::url('user.page', [], array('absolute' => TRUE)); + $link = \Drupal::url('user.page', [], ['absolute' => TRUE]); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, ['user' => $account], ['langcode' => $language_interface->getId(), 'callback' => 'user_mail_tokens', 'clear' => TRUE]); $this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.'); @@ -141,16 +141,16 @@ function testUserTokenReplacement() { // Generate tokens with the user's preferred language. $account->preferred_langcode = 'de'; $account->save(); - $link = \Drupal::url('user.page', [], array('language' => \Drupal::languageManager()->getLanguage($account->getPreferredLangcode()), 'absolute' => TRUE)); + $link = \Drupal::url('user.page', [], ['language' => \Drupal::languageManager()->getLanguage($account->getPreferredLangcode()), 'absolute' => TRUE]); foreach ($tests as $input => $expected) { $output = $token_service->replace($input, ['user' => $account], ['callback' => 'user_mail_tokens', 'clear' => TRUE]); $this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language."); } // Generate tokens with one specific language. - $link = \Drupal::url('user.page', [], array('language' => \Drupal::languageManager()->getLanguage('de'), 'absolute' => TRUE)); + $link = \Drupal::url('user.page', [], ['language' => \Drupal::languageManager()->getLanguage('de'), 'absolute' => TRUE]); foreach ($tests as $input => $expected) { - foreach (array($user1, $user2) as $account) { + foreach ([$user1, $user2] as $account) { $output = $token_service->replace($input, ['user' => $account], ['langcode' => 'de', 'callback' => 'user_mail_tokens', 'clear' => TRUE]); $this->assertTrue(strpos($output, $link) === 0, "Generated URL in the requested language."); } diff --git a/core/modules/user/tests/src/Kernel/Condition/UserRoleConditionTest.php b/core/modules/user/tests/src/Kernel/Condition/UserRoleConditionTest.php index 6e553646..075b04c5 100644 --- a/core/modules/user/tests/src/Kernel/Condition/UserRoleConditionTest.php +++ b/core/modules/user/tests/src/Kernel/Condition/UserRoleConditionTest.php @@ -48,7 +48,7 @@ class UserRoleConditionTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; /** * {@inheritdoc} @@ -62,38 +62,38 @@ protected function setUp() { $this->manager = $this->container->get('plugin.manager.condition'); // Set up the authenticated and anonymous roles. - Role::create(array( + Role::create([ 'id' => RoleInterface::ANONYMOUS_ID, 'label' => 'Anonymous user', - ))->save(); - Role::create(array( + ])->save(); + Role::create([ 'id' => RoleInterface::AUTHENTICATED_ID, 'label' => 'Authenticated user', - ))->save(); + ])->save(); // Create new role. $rid = strtolower($this->randomMachineName(8)); $label = $this->randomString(8); - $role = Role::create(array( + $role = Role::create([ 'id' => $rid, 'label' => $label, - )); + ]); $role->save(); $this->role = $role; // Setup an anonymous user for our tests. - $this->anonymous = User::create(array( + $this->anonymous = User::create([ 'name' => '', 'uid' => 0, - )); + ]); $this->anonymous->save(); // Loading the anonymous user adds the correct role. $this->anonymous = User::load($this->anonymous->id()); // Setup an authenticated user for our tests. - $this->authenticated = User::create(array( + $this->authenticated = User::create([ 'name' => $this->randomMachineName(), - )); + ]); $this->authenticated->save(); // Add the custom role. $this->authenticated->addRole($this->role->id()); @@ -107,7 +107,7 @@ public function testConditions() { // authenticated user roles. /** @var $condition \Drupal\Core\Condition\ConditionInterface */ $condition = $this->manager->createInstance('user_role') - ->setConfig('roles', array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)) + ->setConfig('roles', [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]) ->setContextValue('user', $this->anonymous); $this->assertFalse($condition->execute(), 'Anonymous users fail role checks for authenticated.'); // Check for the proper summary. @@ -115,13 +115,13 @@ public function testConditions() { $this->assertEqual($condition->summary(), 'The user is a member of Authenticated user'); // Set the user role to anonymous. - $condition->setConfig('roles', array(RoleInterface::ANONYMOUS_ID => RoleInterface::ANONYMOUS_ID)); + $condition->setConfig('roles', [RoleInterface::ANONYMOUS_ID => RoleInterface::ANONYMOUS_ID]); $this->assertTrue($condition->execute(), 'Anonymous users pass role checks for anonymous.'); // Check for the proper summary. $this->assertEqual($condition->summary(), 'The user is a member of Anonymous user'); // Set the user role to check anonymous or authenticated. - $condition->setConfig('roles', array(RoleInterface::ANONYMOUS_ID => RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)); + $condition->setConfig('roles', [RoleInterface::ANONYMOUS_ID => RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]); $this->assertTrue($condition->execute(), 'Anonymous users pass role checks for anonymous or authenticated.'); // Check for the proper summary. $this->assertEqual($condition->summary(), 'The user is a member of Anonymous user, Authenticated user'); @@ -132,11 +132,11 @@ public function testConditions() { $this->assertTrue($condition->execute(), 'Authenticated users pass role checks for anonymous or authenticated.'); // Set the role to just authenticated and recheck. - $condition->setConfig('roles', array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)); + $condition->setConfig('roles', [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]); $this->assertTrue($condition->execute(), 'Authenticated users pass role checks for authenticated.'); // Test Constructor injection. - $condition = $this->manager->createInstance('user_role', array('roles' => array(RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID), 'context' => array('user' => $this->authenticated))); + $condition = $this->manager->createInstance('user_role', ['roles' => [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID], 'context' => ['user' => $this->authenticated]]); $this->assertTrue($condition->execute(), 'Constructor injection of context and configuration working as anticipated.'); // Check the negated summary. @@ -144,14 +144,14 @@ public function testConditions() { $this->assertEqual($condition->summary(), 'The user is not a member of Authenticated user'); // Check the complex negated summary. - $condition->setConfig('roles', array(RoleInterface::ANONYMOUS_ID => RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID)); + $condition->setConfig('roles', [RoleInterface::ANONYMOUS_ID => RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID]); $this->assertEqual($condition->summary(), 'The user is not a member of Anonymous user, Authenticated user'); // Check a custom role. - $condition->setConfig('roles', array($this->role->id() => $this->role->id())); + $condition->setConfig('roles', [$this->role->id() => $this->role->id()]); $condition->setConfig('negate', FALSE); $this->assertTrue($condition->execute(), 'Authenticated user is a member of the custom role.'); - $this->assertEqual($condition->summary(), SafeMarkup::format('The user is a member of @roles', array('@roles' => $this->role->label()))); + $this->assertEqual($condition->summary(), SafeMarkup::format('The user is a member of @roles', ['@roles' => $this->role->label()])); } } diff --git a/core/modules/user/tests/src/Kernel/Migrate/MigrateUserProfileFieldTest.php b/core/modules/user/tests/src/Kernel/Migrate/MigrateUserProfileFieldTest.php index 0f64c79a..75bccf14 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/MigrateUserProfileFieldTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/MigrateUserProfileFieldTest.php @@ -41,7 +41,7 @@ public function testUserProfileFields() { $field_storage = FieldStorageConfig::load('user.profile_sold_to'); $this->assertIdentical('list_string', $field_storage->getType(), 'Field type is list_string.'); $settings = $field_storage->getSettings(); - $this->assertEqual($settings['allowed_values'], array( + $this->assertEqual($settings['allowed_values'], [ 'Pill spammers' => 'Pill spammers', 'Fitness spammers' => 'Fitness spammers', 'Back\slash' => 'Back\slash', @@ -49,7 +49,7 @@ public function testUserProfileFields() { 'Dot.in.the.middle' => 'Dot.in.the.middle', 'Faithful servant' => 'Faithful servant', 'Anonymous donor' => 'Anonymous donor', - )); + ]); $this->assertIdentical('list_string', $field_storage->getType(), 'Field type is list_string.'); // Migrated list field. diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserConfigsTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserConfigsTest.php index 5b6e95d5..eed2be8e 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserConfigsTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\user\Kernel\Migrate\d6; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; use Drupal\user\AccountSettingsForm; use Drupal\Core\Database\Database; @@ -71,10 +71,10 @@ public function testUserSettings() { foreach ($user_register_map as $map) { // Tests migration of user_register = 1 Database::getConnection('default', 'migrate') - ->update('variable') - ->fields(['value' => serialize($map[0])]) - ->condition('name', 'user_register') - ->execute(); + ->update('variable') + ->fields(['value' => serialize($map[0])]) + ->condition('name', 'user_register') + ->execute(); /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ $migration = $this->getMigration('d6_user_settings'); diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureD6FileTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureD6FileTest.php new file mode 100644 index 00000000..1bef3702 --- /dev/null +++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureD6FileTest.php @@ -0,0 +1,69 @@ +installEntitySchema('file'); + $this->executeMigration('d6_user_picture_file'); + $this->setUpMigratedFiles(); + } + + /** + * Asserts a file entity. + * + * @param int $fid + * The file ID. + * @param string $name + * The expected file name. + * @param int $size + * The expected file size. + * @param string $uri + * The expected file URI. + * @param string $type + * The expected MIME type. + * @param int $uid + * The expected file owner ID. + */ + protected function assertEntity($fid, $name, $size, $uri, $type, $uid) { + /** @var \Drupal\file\FileInterface $file */ + $file = File::load($fid); + $this->assertInstanceOf(FileInterface::class, $file); + $this->assertSame($name, $file->getFilename()); + $this->assertSame($size, $file->getSize()); + $this->assertSame($uri, $file->getFileUri()); + $this->assertSame($type, $file->getMimeType()); + $this->assertSame($uid, $file->getOwnerId()); + } + + /** + * Tests the D6 user pictures migration in combination with D6 file. + */ + public function testUserPicturesWithD6File() { + $this->assertEntity(1, 'image-test.jpg', '1901', 'public://image-test.jpg', 'image/jpeg', '2'); + $this->assertEntity(2, 'image-test.png', '125', 'public://image-test.png', 'image/png', '8'); + $this->assertEntity(3, 'Image1.png', '39325', 'public://image-1.png', 'image/png', '1'); + $this->assertEntity(4, 'Image2.jpg', '1831', 'public://image-2.jpg', 'image/jpeg', '1'); + $this->assertEntity(5, 'Image-test.gif', '183', 'public://image-test.gif', 'image/jpeg', '1'); + $this->assertEntity(6, 'html-1.txt', '24', 'public://html-1.txt', 'text/plain', '1'); + } + +} diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureFileTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureFileTest.php index b3b6a642..1d28e2a7 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureFileTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserPictureFileTest.php @@ -29,7 +29,7 @@ protected function setUp() { * Tests the Drupal 6 user pictures to Drupal 8 migration. */ public function testUserPictures() { - $file_ids = array(); + $file_ids = []; foreach ($this->migration->getIdMap() as $destination_ids) { $file_ids[] = reset($destination_ids); } diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php index a52b6a77..5393805c 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php @@ -38,6 +38,7 @@ protected function assertRole($id, array $permissions, $lookupId, MigrateIdMapIn /** @var \Drupal\user\RoleInterface $role */ $role = Role::load($id); $this->assertInstanceOf(RoleInterface::class, $role); + sort($permissions); $this->assertSame($permissions, $role->getPermissions()); $this->assertSame([[$id]], $id_map->lookupDestinationIds(['rid' => $lookupId])); } @@ -67,9 +68,9 @@ protected function assertRoles(MigrateIdMapInterface $id_map) { // From permission table. 'access comments', 'access content', + 'migrate test authenticated permission', 'post comments', 'skip comment approval', - 'migrate test authenticated permission', // From filter_format. 'use text format filtered_html', ]; diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php index 33952d17..ed287770 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserTest.php @@ -37,7 +37,7 @@ protected function setUp() { // Make sure uid 1 is created. user_install(); - $file = File::create(array( + $file = File::create([ 'fid' => 2, 'uid' => 2, 'filename' => 'image-test.jpg', @@ -46,12 +46,12 @@ protected function setUp() { 'created' => 1, 'changed' => 1, 'status' => FILE_STATUS_PERMANENT, - )); + ]); $file->enforceIsNew(); file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-1.png')); $file->save(); - $file = File::create(array( + $file = File::create([ 'fid' => 8, 'uid' => 8, 'filename' => 'image-test.png', @@ -60,7 +60,7 @@ protected function setUp() { 'created' => 1, 'changed' => 1, 'status' => FILE_STATUS_PERMANENT, - )); + ]); $file->enforceIsNew(); file_put_contents($file->getFileUri(), file_get_contents('core/modules/simpletest/files/image-2.jpg')); $file->save(); @@ -84,14 +84,14 @@ public function testUser() { // Get roles directly from the source. $rids = Database::getConnection('default', 'migrate') ->select('users_roles', 'ur') - ->fields('ur', array('rid')) + ->fields('ur', ['rid']) ->condition('ur.uid', $source->uid) ->execute() ->fetchCol(); - $roles = array(RoleInterface::AUTHENTICATED_ID); + $roles = [RoleInterface::AUTHENTICATED_ID]; $id_map = $this->getMigration('d6_user_role')->getIdMap(); foreach ($rids as $rid) { - $role = $id_map->lookupDestinationId(array($rid)); + $role = $id_map->lookupDestinationId([$rid]); $roles[] = reset($role); } diff --git a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php index edd5e3c0..9b5a7725 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php @@ -45,6 +45,7 @@ protected function assertEntity($id, $label, $original_rid) { ->condition('rid', $original_rid) ->execute() ->fetchCol(); + sort($permissions); $this->assertIdentical($permissions, $entity->getPermissions()); } } diff --git a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php index d18d0711..bbfc41d7 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php @@ -2,10 +2,9 @@ namespace Drupal\Tests\user\Kernel\Migrate\d7; -use Drupal\comment\Entity\CommentType; use Drupal\Core\Database\Database; -use Drupal\node\Entity\NodeType; use Drupal\taxonomy\Entity\Vocabulary; +use Drupal\Tests\migrate\Kernel\NodeCommentCombinationTrait; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; use Drupal\user\Entity\User; use Drupal\user\RoleInterface; @@ -18,6 +17,8 @@ */ class MigrateUserTest extends MigrateDrupal7TestBase { + use NodeCommentCombinationTrait; + /** * {@inheritdoc} */ @@ -43,12 +44,12 @@ protected function setUp() { // Prepare to migrate user pictures as well. $this->installEntitySchema('file'); - $this->createType('page'); - $this->createType('article'); - $this->createType('blog'); - $this->createType('book'); - $this->createType('forum'); - $this->createType('test_content_type'); + $this->createNodeCommentCombination('page'); + $this->createNodeCommentCombination('article'); + $this->createNodeCommentCombination('blog'); + $this->createNodeCommentCombination('book'); + $this->createNodeCommentCombination('forum', 'comment_forum'); + $this->createNodeCommentCombination('test_content_type'); Vocabulary::create(['vid' => 'test_vocabulary'])->save(); $this->executeMigrations([ 'language', @@ -61,25 +62,6 @@ protected function setUp() { ]); } - /** - * Creates a node type with a corresponding comment type. - * - * @param string $id - * The node type ID. - */ - protected function createType($id) { - NodeType::create([ - 'type' => $id, - 'label' => $this->randomString(), - ])->save(); - - CommentType::create([ - 'id' => 'comment_node_' . $id, - 'label' => $this->randomString(), - 'target_entity_type_id' => 'node', - ])->save(); - } - /** * Asserts various aspects of a user account. * @@ -177,20 +159,20 @@ public function testUser() { foreach ($users as $source) { $rids = Database::getConnection('default', 'migrate') ->select('users_roles', 'ur') - ->fields('ur', array('rid')) + ->fields('ur', ['rid']) ->condition('ur.uid', $source->uid) ->execute() ->fetchCol(); - $roles = array(RoleInterface::AUTHENTICATED_ID); + $roles = [RoleInterface::AUTHENTICATED_ID]; $id_map = $this->getMigration('d7_user_role')->getIdMap(); foreach ($rids as $rid) { - $role = $id_map->lookupDestinationId(array($rid)); + $role = $id_map->lookupDestinationId([$rid]); $roles[] = reset($role); } $field_integer = Database::getConnection('default', 'migrate') ->select('field_data_field_integer', 'fi') - ->fields('fi', array('field_integer_value')) + ->fields('fi', ['field_integer_value']) ->condition('fi.entity_id', $source->uid) ->execute() ->fetchCol(); diff --git a/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php b/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php index 254524a9..b3d7ff1e 100644 --- a/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php +++ b/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php @@ -21,7 +21,7 @@ class TempStoreDatabaseTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user'); + public static $modules = ['system', 'user']; /** * A key/value store factory. @@ -42,21 +42,21 @@ class TempStoreDatabaseTest extends KernelTestBase { * * @var array */ - protected $users = array(); + protected $users = []; /** * An array of random stdClass objects. * * @var array */ - protected $objects = array(); + protected $objects = []; protected function setUp() { parent::setUp(); // Install system tables to test the key/value storage without installing a // full Drupal environment. - $this->installSchema('system', array('key_value_expire')); + $this->installSchema('system', ['key_value_expire']); // Create several objects for testing. for ($i = 0; $i <= 3; $i++) { @@ -135,7 +135,7 @@ public function testUserTempStore() { // Now manually expire the item (this is not exposed by the API) and then // assert it is no longer accessible. db_update('key_value_expire') - ->fields(array('expire' => REQUEST_TIME - 1)) + ->fields(['expire' => REQUEST_TIME - 1]) ->condition('collection', "user.shared_tempstore.$collection") ->condition('name', $key) ->execute(); diff --git a/core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php b/core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php index 40229725..64330219 100644 --- a/core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php +++ b/core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php @@ -18,12 +18,12 @@ class UserAccountFormFieldsTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; /** * Tests the root user account form section in the "Configure site" form. */ - function testInstallConfigureForm() { + public function testInstallConfigureForm() { require_once \Drupal::root() . '/core/includes/install.core.inc'; require_once \Drupal::root() . '/core/includes/install.inc'; $install_state = install_state_defaults(); @@ -37,7 +37,7 @@ function testInstallConfigureForm() { // Verify that web browsers may autocomplete the email value and // autofill/prefill the name and pass values. - foreach (array('mail', 'name', 'pass') as $key) { + foreach (['mail', 'name', 'pass'] as $key) { $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found."); } } @@ -45,9 +45,9 @@ function testInstallConfigureForm() { /** * Tests the user registration form. */ - function testUserRegistrationForm() { + public function testUserRegistrationForm() { // Install default configuration; required for AccountFormController. - $this->installConfig(array('user')); + $this->installConfig(['user']); // Disable email confirmation to unlock the password field. $this->config('user.settings') @@ -61,7 +61,7 @@ function testUserRegistrationForm() { // Verify that web browsers may autocomplete the email value and // autofill/prefill the name and pass values. - foreach (array('mail', 'name', 'pass') as $key) { + foreach (['mail', 'name', 'pass'] as $key) { $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found."); } } @@ -69,9 +69,9 @@ function testUserRegistrationForm() { /** * Tests the user edit form. */ - function testUserEditForm() { + public function testUserEditForm() { // Install default configuration; required for AccountFormController. - $this->installConfig(array('user')); + $this->installConfig(['user']); // Install the router table and then rebuild. \Drupal::service('router.builder')->rebuild(); @@ -82,7 +82,7 @@ function testUserEditForm() { $this->assertFieldOrder($form['account']); // Verify that autocomplete is off on all account fields. - foreach (array('mail', 'name', 'pass') as $key) { + foreach (['mail', 'name', 'pass'] as $key) { $this->assertIdentical($form['account'][$key]['#attributes']['autocomplete'], 'off', "'$key' field: 'autocomplete' attribute is 'off'."); } } @@ -128,7 +128,7 @@ protected function assertFieldOrder(array $elements) { protected function buildAccountForm($operation) { // @see HtmlEntityFormController::getFormObject() $entity_type = 'user'; - $fields = array(); + $fields = []; if ($operation != 'register') { $fields['uid'] = 2; } diff --git a/core/modules/user/tests/src/Kernel/UserActionConfigSchemaTest.php b/core/modules/user/tests/src/Kernel/UserActionConfigSchemaTest.php index 3426349c..dfafb1d5 100644 --- a/core/modules/user/tests/src/Kernel/UserActionConfigSchemaTest.php +++ b/core/modules/user/tests/src/Kernel/UserActionConfigSchemaTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\user\Kernel; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\KernelTests\KernelTestBase; use Drupal\user\Entity\Role; @@ -21,14 +21,14 @@ class UserActionConfigSchemaTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user'); + public static $modules = ['system', 'user']; /** * Tests whether the user action config schema are valid. */ - function testValidUserActionConfigSchema() { + public function testValidUserActionConfigSchema() { $rid = strtolower($this->randomMachineName(8)); - Role::create(array('id' => $rid))->save(); + Role::create(['id' => $rid])->save(); // Test user_add_role_action configuration. $config = $this->config('system.action.user_add_role_action.' . $rid); diff --git a/core/modules/user/tests/src/Kernel/UserEntityReferenceTest.php b/core/modules/user/tests/src/Kernel/UserEntityReferenceTest.php index 8958c542..159a699c 100644 --- a/core/modules/user/tests/src/Kernel/UserEntityReferenceTest.php +++ b/core/modules/user/tests/src/Kernel/UserEntityReferenceTest.php @@ -36,16 +36,16 @@ class UserEntityReferenceTest extends EntityKernelTestBase { protected function setUp() { parent::setUp(); - $this->role1 = Role::create(array( + $this->role1 = Role::create([ 'id' => strtolower($this->randomMachineName(8)), 'label' => $this->randomMachineName(8), - )); + ]); $this->role1->save(); - $this->role2 = Role::create(array( + $this->role2 = Role::create([ 'id' => strtolower($this->randomMachineName(8)), 'label' => $this->randomMachineName(8), - )); + ]); $this->role2->save(); $this->createEntityReferenceField('user', 'user', 'user_reference', 'User reference', 'user'); @@ -54,26 +54,26 @@ protected function setUp() { /** * Tests user selection by roles. */ - function testUserSelectionByRole() { + public function testUserSelectionByRole() { $field_definition = FieldConfig::loadByName('user', 'user', 'user_reference'); $handler_settings = $field_definition->getSetting('handler_settings'); - $handler_settings['filter']['role'] = array( + $handler_settings['filter']['role'] = [ $this->role1->id() => $this->role1->id(), $this->role2->id() => 0, - ); + ]; $handler_settings['filter']['type'] = 'role'; $field_definition->setSetting('handler_settings', $handler_settings); $field_definition->save(); - $user1 = $this->createUser(array('name' => 'aabb')); + $user1 = $this->createUser(['name' => 'aabb']); $user1->addRole($this->role1->id()); $user1->save(); - $user2 = $this->createUser(array('name' => 'aabbb')); + $user2 = $this->createUser(['name' => 'aabbb']); $user2->addRole($this->role1->id()); $user2->save(); - $user3 = $this->createUser(array('name' => 'aabbbb')); + $user3 = $this->createUser(['name' => 'aabbbb']); $user3->addRole($this->role2->id()); $user3->save(); @@ -83,7 +83,7 @@ function testUserSelectionByRole() { $matches = $autocomplete->getMatches('user', 'default', $field_definition->getSetting('handler_settings'), 'aabb'); $this->assertEqual(count($matches), 2); - $users = array(); + $users = []; foreach ($matches as $match) { $users[] = $match['label']; } diff --git a/core/modules/user/tests/src/Kernel/UserEntityTest.php b/core/modules/user/tests/src/Kernel/UserEntityTest.php index 9002e5ca..1c501f04 100644 --- a/core/modules/user/tests/src/Kernel/UserEntityTest.php +++ b/core/modules/user/tests/src/Kernel/UserEntityTest.php @@ -19,7 +19,7 @@ class UserEntityTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; /** * Tests some of the methods. @@ -30,39 +30,39 @@ class UserEntityTest extends KernelTestBase { */ public function testUserMethods() { $role_storage = $this->container->get('entity.manager')->getStorage('user_role'); - $role_storage->create(array('id' => 'test_role_one'))->save(); - $role_storage->create(array('id' => 'test_role_two'))->save(); - $role_storage->create(array('id' => 'test_role_three'))->save(); + $role_storage->create(['id' => 'test_role_one'])->save(); + $role_storage->create(['id' => 'test_role_two'])->save(); + $role_storage->create(['id' => 'test_role_three'])->save(); - $values = array( + $values = [ 'uid' => 1, - 'roles' => array('test_role_one'), - ); + 'roles' => ['test_role_one'], + ]; $user = User::create($values); $this->assertTrue($user->hasRole('test_role_one')); $this->assertFalse($user->hasRole('test_role_two')); - $this->assertEqual(array(RoleInterface::AUTHENTICATED_ID, 'test_role_one'), $user->getRoles()); + $this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_one'], $user->getRoles()); $user->addRole('test_role_one'); $this->assertTrue($user->hasRole('test_role_one')); $this->assertFalse($user->hasRole('test_role_two')); - $this->assertEqual(array(RoleInterface::AUTHENTICATED_ID, 'test_role_one'), $user->getRoles()); + $this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_one'], $user->getRoles()); $user->addRole('test_role_two'); $this->assertTrue($user->hasRole('test_role_one')); $this->assertTrue($user->hasRole('test_role_two')); - $this->assertEqual(array(RoleInterface::AUTHENTICATED_ID, 'test_role_one', 'test_role_two'), $user->getRoles()); + $this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_one', 'test_role_two'], $user->getRoles()); $user->removeRole('test_role_three'); $this->assertTrue($user->hasRole('test_role_one')); $this->assertTrue($user->hasRole('test_role_two')); - $this->assertEqual(array(RoleInterface::AUTHENTICATED_ID, 'test_role_one', 'test_role_two'), $user->getRoles()); + $this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_one', 'test_role_two'], $user->getRoles()); $user->removeRole('test_role_one'); $this->assertFalse($user->hasRole('test_role_one')); $this->assertTrue($user->hasRole('test_role_two')); - $this->assertEqual(array(RoleInterface::AUTHENTICATED_ID, 'test_role_two'), $user->getRoles()); + $this->assertEqual([RoleInterface::AUTHENTICATED_ID, 'test_role_two'], $user->getRoles()); } } diff --git a/core/modules/user/tests/src/Kernel/UserFieldsTest.php b/core/modules/user/tests/src/Kernel/UserFieldsTest.php index f0fb5322..672ddb06 100644 --- a/core/modules/user/tests/src/Kernel/UserFieldsTest.php +++ b/core/modules/user/tests/src/Kernel/UserFieldsTest.php @@ -27,7 +27,7 @@ protected function setUp() { $this->installEntitySchema('user'); // Set up a test theme that prints the user's mail field. - \Drupal::service('theme_handler')->install(array('user_test_theme')); + \Drupal::service('theme_handler')->install(['user_test_theme']); \Drupal::theme()->setActiveTheme(\Drupal::service('theme.initialization')->initTheme('user_test_theme')); // Clear the theme registry. $this->container->set('theme.registry', NULL); @@ -36,7 +36,7 @@ protected function setUp() { /** * Tests account's available fields. */ - function testUserFields() { + public function testUserFields() { // Create the user to test the user fields. $user = User::create([ 'name' => 'foobar', diff --git a/core/modules/user/tests/src/Kernel/UserInstallTest.php b/core/modules/user/tests/src/Kernel/UserInstallTest.php index 2bbcd5fc..f61811be 100644 --- a/core/modules/user/tests/src/Kernel/UserInstallTest.php +++ b/core/modules/user/tests/src/Kernel/UserInstallTest.php @@ -16,7 +16,7 @@ class UserInstallTest extends KernelTestBase { * * @var array */ - public static $modules = array('user'); + public static $modules = ['user']; /** * {@inheritdoc} diff --git a/core/modules/user/tests/src/Kernel/UserRoleDeleteTest.php b/core/modules/user/tests/src/Kernel/UserRoleDeleteTest.php index 1aefbcfc..cac470aa 100644 --- a/core/modules/user/tests/src/Kernel/UserRoleDeleteTest.php +++ b/core/modules/user/tests/src/Kernel/UserRoleDeleteTest.php @@ -17,7 +17,7 @@ class UserRoleDeleteTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; protected function setUp() { parent::setUp(); @@ -32,15 +32,15 @@ protected function setUp() { public function testRoleDeleteUserRoleReferenceDelete() { // Create two test roles. $role_storage = $this->container->get('entity.manager')->getStorage('user_role'); - $role_storage->create(array('id' => 'test_role_one'))->save(); - $role_storage->create(array('id' => 'test_role_two'))->save(); + $role_storage->create(['id' => 'test_role_one'])->save(); + $role_storage->create(['id' => 'test_role_two'])->save(); // Create user and assign both test roles. - $values = array( + $values = [ 'uid' => 1, 'name' => $this->randomString(), - 'roles' => array('test_role_one', 'test_role_two'), - ); + 'roles' => ['test_role_one', 'test_role_two'], + ]; $user = User::create($values); $user->save(); @@ -60,7 +60,7 @@ public function testRoleDeleteUserRoleReferenceDelete() { $this->assertTrue($user->hasRole('test_role_two')); // Create new role with same name. - $role_storage->create(array('id' => 'test_role_one'))->save(); + $role_storage->create(['id' => 'test_role_one'])->save(); // Load user again from the database. $user = User::load($user->id()); diff --git a/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php new file mode 100644 index 00000000..562ada11 --- /dev/null +++ b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php @@ -0,0 +1,30 @@ + 'test_role']); + $role->grantPermission('b') + ->grantPermission('a') + ->grantPermission('c') + ->save(); + $this->assertEquals($role->getPermissions(), ['a', 'b', 'c']); + + $role->revokePermission('b')->save(); + $this->assertEquals($role->getPermissions(), ['a', 'c']); + + $role->grantPermission('b')->save(); + $this->assertEquals($role->getPermissions(), ['a', 'b', 'c']); + } + +} diff --git a/core/modules/user/tests/src/Kernel/UserSaveStatusTest.php b/core/modules/user/tests/src/Kernel/UserSaveStatusTest.php index 00a29fcd..17364c05 100644 --- a/core/modules/user/tests/src/Kernel/UserSaveStatusTest.php +++ b/core/modules/user/tests/src/Kernel/UserSaveStatusTest.php @@ -17,7 +17,7 @@ class UserSaveStatusTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; protected function setUp() { parent::setUp(); @@ -27,12 +27,12 @@ protected function setUp() { /** * Test SAVED_NEW and SAVED_UPDATED statuses for user entity type. */ - function testUserSaveStatus() { + public function testUserSaveStatus() { // Create a new user. - $values = array( + $values = [ 'uid' => 1, 'name' => $this->randomMachineName(), - ); + ]; $user = User::create($values); // Test SAVED_NEW. diff --git a/core/modules/user/tests/src/Kernel/UserValidationTest.php b/core/modules/user/tests/src/Kernel/UserValidationTest.php index b27b00f7..4aa5850d 100644 --- a/core/modules/user/tests/src/Kernel/UserValidationTest.php +++ b/core/modules/user/tests/src/Kernel/UserValidationTest.php @@ -21,7 +21,7 @@ class UserValidationTest extends KernelTestBase { * * @var array */ - public static $modules = array('field', 'user', 'system'); + public static $modules = ['field', 'user', 'system']; /** * {@inheritdoc} @@ -29,36 +29,42 @@ class UserValidationTest extends KernelTestBase { protected function setUp() { parent::setUp(); $this->installEntitySchema('user'); - $this->installSchema('system', array('sequences')); + $this->installSchema('system', ['sequences']); // Make sure that the default roles exist. - $this->installConfig(array('user')); + $this->installConfig(['user']); } /** * Tests user name validation. */ - function testUsernames() { - $test_cases = array( // '' => array('', 'assert'), - 'foo' => array('Valid username', 'assertNull'), - 'FOO' => array('Valid username', 'assertNull'), - 'Foo O\'Bar' => array('Valid username', 'assertNull'), - 'foo@bar' => array('Valid username', 'assertNull'), - 'foo@example.com' => array('Valid username', 'assertNull'), - 'foo@-example.com' => array('Valid username', 'assertNull'), // invalid domains are allowed in usernames - 'þòøÇߪř€' => array('Valid username', 'assertNull'), - 'foo+bar' => array('Valid username', 'assertNull'), // '+' symbol is allowed - 'ᚠᛇᚻ᛫ᛒᛦᚦ' => array('Valid UTF8 username', 'assertNull'), // runes - ' foo' => array('Invalid username that starts with a space', 'assertNotNull'), - 'foo ' => array('Invalid username that ends with a space', 'assertNotNull'), - 'foo bar' => array('Invalid username that contains 2 spaces \'  \'', 'assertNotNull'), - '' => array('Invalid empty username', 'assertNotNull'), - 'foo/' => array('Invalid username containing invalid chars', 'assertNotNull'), - 'foo' . chr(0) . 'bar' => array('Invalid username containing chr(0)', 'assertNotNull'), // NULL - 'foo' . chr(13) . 'bar' => array('Invalid username containing chr(13)', 'assertNotNull'), // CR - str_repeat('x', USERNAME_MAX_LENGTH + 1) => array('Invalid excessively long username', 'assertNotNull'), - ); + public function testUsernames() { + $test_cases = [ + // '' => ['', 'assert']. + 'foo' => ['Valid username', 'assertNull'], + 'FOO' => ['Valid username', 'assertNull'], + 'Foo O\'Bar' => ['Valid username', 'assertNull'], + 'foo@bar' => ['Valid username', 'assertNull'], + 'foo@example.com' => ['Valid username', 'assertNull'], + // invalid domains are allowed in usernames. + 'foo@-example.com' => ['Valid username', 'assertNull'], + 'þòøÇߪř€' => ['Valid username', 'assertNull'], + // '+' symbol is allowed. + 'foo+bar' => ['Valid username', 'assertNull'], + // runes. + 'ᚠᛇᚻ᛫ᛒᛦᚦ' => ['Valid UTF8 username', 'assertNull'], + ' foo' => ['Invalid username that starts with a space', 'assertNotNull'], + 'foo ' => ['Invalid username that ends with a space', 'assertNotNull'], + 'foo bar' => ['Invalid username that contains 2 spaces \'  \'', 'assertNotNull'], + '' => ['Invalid empty username', 'assertNotNull'], + 'foo/' => ['Invalid username containing invalid chars', 'assertNotNull'], + // NULL. + 'foo' . chr(0) . 'bar' => ['Invalid username containing chr(0)', 'assertNotNull'], + // CR. + 'foo' . chr(13) . 'bar' => ['Invalid username containing chr(13)', 'assertNotNull'], + str_repeat('x', USERNAME_MAX_LENGTH + 1) => ['Invalid excessively long username', 'assertNotNull'], + ]; foreach ($test_cases as $name => $test_case) { list($description, $test) = $test_case; $result = user_validate_name($name); @@ -69,11 +75,11 @@ function testUsernames() { /** * Runs entity validation checks. */ - function testValidation() { - $user = User::create(array( + public function testValidation() { + $user = User::create([ 'name' => 'test', 'mail' => 'test@example.com', - )); + ]); $violations = $user->validate(); $this->assertEqual(count($violations), 0, 'No violations when validating a default user.'); @@ -84,7 +90,7 @@ function testValidation() { $violations = $user->validate(); $this->assertEqual(count($violations), 1, 'Violation found when name is too long.'); $this->assertEqual($violations[0]->getPropertyPath(), 'name'); - $this->assertEqual($violations[0]->getMessage(), t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => 60))); + $this->assertEqual($violations[0]->getMessage(), t('The username %name is too long: it must be %max characters or less.', ['%name' => $name, '%max' => 60])); // Create a second test user to provoke a name collision. $user2 = User::create([ @@ -96,7 +102,7 @@ function testValidation() { $violations = $user->validate(); $this->assertEqual(count($violations), 1, 'Violation found on name collision.'); $this->assertEqual($violations[0]->getPropertyPath(), 'name'); - $this->assertEqual($violations[0]->getMessage(), t('The username %name is already taken.', array('%name' => 'existing'))); + $this->assertEqual($violations[0]->getMessage(), t('The username %name is already taken.', ['%name' => 'existing'])); // Make the name valid. $user->set('name', $this->randomMachineName()); @@ -116,7 +122,7 @@ function testValidation() { // https://www.drupal.org/node/2023465. $this->assertEqual(count($violations), 2, 'Violations found when email is too long'); $this->assertEqual($violations[0]->getPropertyPath(), 'mail.0.value'); - $this->assertEqual($violations[0]->getMessage(), t('%name: the email address can not be longer than @max characters.', array('%name' => $user->get('mail')->getFieldDefinition()->getLabel(), '@max' => Email::EMAIL_MAX_LENGTH))); + $this->assertEqual($violations[0]->getMessage(), t('%name: the email address can not be longer than @max characters.', ['%name' => $user->get('mail')->getFieldDefinition()->getLabel(), '@max' => Email::EMAIL_MAX_LENGTH])); $this->assertEqual($violations[1]->getPropertyPath(), 'mail.0.value'); $this->assertEqual($violations[1]->getMessage(), t('This value is not a valid email address.')); @@ -125,12 +131,12 @@ function testValidation() { $violations = $user->validate(); $this->assertEqual(count($violations), 1, 'Violation found when email already exists.'); $this->assertEqual($violations[0]->getPropertyPath(), 'mail'); - $this->assertEqual($violations[0]->getMessage(), t('The email address %mail is already taken.', array('%mail' => 'existing@example.com'))); + $this->assertEqual($violations[0]->getMessage(), t('The email address %mail is already taken.', ['%mail' => 'existing@example.com'])); $user->set('mail', NULL); $violations = $user->validate(); $this->assertEqual(count($violations), 1, 'Email addresses may not be removed'); $this->assertEqual($violations[0]->getPropertyPath(), 'mail'); - $this->assertEqual($violations[0]->getMessage(), t('@name field is required.', array('@name' => $user->getFieldDefinition('mail')->getLabel()))); + $this->assertEqual($violations[0]->getMessage(), t('@name field is required.', ['@name' => $user->getFieldDefinition('mail')->getLabel()])); $user->set('mail', 'someone@example.com'); $user->set('timezone', $this->randomString(33)); @@ -157,14 +163,14 @@ function testValidation() { $this->assertAllowedValuesViolation($user, 'preferred_admin_langcode'); $user->set('preferred_admin_langcode', NULL); - Role::create(array('id' => 'role1'))->save(); - Role::create(array('id' => 'role2'))->save(); + Role::create(['id' => 'role1'])->save(); + Role::create(['id' => 'role2'])->save(); // Test cardinality of user roles. $user = User::create([ 'name' => 'role_test', 'mail' => 'test@example.com', - 'roles' => array('role1', 'role2'), + 'roles' => ['role1', 'role2'], ]); $violations = $user->validate(); $this->assertEqual(count($violations), 0); @@ -173,7 +179,7 @@ function testValidation() { $violations = $user->validate(); $this->assertEqual(count($violations), 1); $this->assertEqual($violations[0]->getPropertyPath(), 'roles.1.target_id'); - $this->assertEqual($violations[0]->getMessage(), t('The referenced entity (%entity_type: %name) does not exist.', array('%entity_type' => 'user_role', '%name' => 'unknown_role'))); + $this->assertEqual($violations[0]->getMessage(), t('The referenced entity (%entity_type: %name) does not exist.', ['%entity_type' => 'user_role', '%name' => 'unknown_role'])); } /** @@ -195,7 +201,7 @@ protected function assertLengthViolation(EntityInterface $entity, $field_name, $ $this->assertEqual(count($violations), $count, "Violation found when $field_name is too long."); $this->assertEqual($violations[$expected_index]->getPropertyPath(), "$field_name.0.value"); $field_label = $entity->get($field_name)->getFieldDefinition()->getLabel(); - $this->assertEqual($violations[$expected_index]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => $field_label, '@max' => $length))); + $this->assertEqual($violations[$expected_index]->getMessage(), t('%name: may not be longer than @max characters.', ['%name' => $field_label, '@max' => $length])); } /** diff --git a/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php b/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php index 9def2b81..0d212218 100644 --- a/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php +++ b/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php @@ -17,7 +17,7 @@ class HandlerFieldPermissionTest extends UserKernelTestBase { * * @var array */ - public static $testViews = array('test_field_permission'); + public static $testViews = ['test_field_permission']; /** * Tests the permission field handler output. @@ -31,15 +31,15 @@ public function testFieldPermission() { $view->render(); $style_plugin = $view->style_plugin; - $expected_permissions = array(); - $expected_permissions[$this->users[0]->id()] = array(); - $expected_permissions[$this->users[1]->id()] = array(); + $expected_permissions = []; + $expected_permissions[$this->users[0]->id()] = []; + $expected_permissions[$this->users[1]->id()] = []; $expected_permissions[$this->users[2]->id()][] = t('Administer permissions'); // View user profiles comes first, because we sort by the permission // machine name. + $expected_permissions[$this->users[3]->id()][] = t('View user information'); $expected_permissions[$this->users[3]->id()][] = t('Administer permissions'); $expected_permissions[$this->users[3]->id()][] = t('Administer users'); - $expected_permissions[$this->users[3]->id()][] = t('View user information'); foreach ($view->result as $index => $row) { $uid = $view->field['uid']->getValue($row); diff --git a/core/modules/user/tests/src/Kernel/Views/HandlerFilterPermissionTest.php b/core/modules/user/tests/src/Kernel/Views/HandlerFilterPermissionTest.php index 069a9239..b005f62a 100644 --- a/core/modules/user/tests/src/Kernel/Views/HandlerFilterPermissionTest.php +++ b/core/modules/user/tests/src/Kernel/Views/HandlerFilterPermissionTest.php @@ -18,7 +18,7 @@ class HandlerFilterPermissionTest extends UserKernelTestBase { * * @var array */ - public static $testViews = array('test_filter_permission'); + public static $testViews = ['test_filter_permission']; protected $columnMap; @@ -31,64 +31,64 @@ class HandlerFilterPermissionTest extends UserKernelTestBase { public function testFilterPermission() { $this->setupPermissionTestData(); - $column_map = array('uid' => 'uid'); + $column_map = ['uid' => 'uid']; $view = Views::getView('test_filter_permission'); // Filter by a non existing permission. $view->initHandlers(); - $view->filter['permission']->value = array('non_existent_permission'); + $view->filter['permission']->value = ['non_existent_permission']; $this->executeView($view); $this->assertEqual(count($view->result), 4, 'A non existent permission is not filtered so everything is the result.'); - $expected[] = array('uid' => 1); - $expected[] = array('uid' => 2); - $expected[] = array('uid' => 3); - $expected[] = array('uid' => 4); + $expected[] = ['uid' => 1]; + $expected[] = ['uid' => 2]; + $expected[] = ['uid' => 3]; + $expected[] = ['uid' => 4]; $this->assertIdenticalResultset($view, $expected, $column_map); $view->destroy(); // Filter by a permission. $view->initHandlers(); - $view->filter['permission']->value = array('administer permissions'); + $view->filter['permission']->value = ['administer permissions']; $this->executeView($view); $this->assertEqual(count($view->result), 2); - $expected = array(); - $expected[] = array('uid' => 3); - $expected[] = array('uid' => 4); + $expected = []; + $expected[] = ['uid' => 3]; + $expected[] = ['uid' => 4]; $this->assertIdenticalResultset($view, $expected, $column_map); $view->destroy(); // Filter by not a permission. $view->initHandlers(); $view->filter['permission']->operator = 'not'; - $view->filter['permission']->value = array('administer users'); + $view->filter['permission']->value = ['administer users']; $this->executeView($view); $this->assertEqual(count($view->result), 3); - $expected = array(); - $expected[] = array('uid' => 1); - $expected[] = array('uid' => 2); - $expected[] = array('uid' => 3); + $expected = []; + $expected[] = ['uid' => 1]; + $expected[] = ['uid' => 2]; + $expected[] = ['uid' => 3]; $this->assertIdenticalResultset($view, $expected, $column_map); $view->destroy(); // Filter by not multiple permissions, that are present in multiple roles. $view->initHandlers(); $view->filter['permission']->operator = 'not'; - $view->filter['permission']->value = array('administer users', 'administer permissions'); + $view->filter['permission']->value = ['administer users', 'administer permissions']; $this->executeView($view); $this->assertEqual(count($view->result), 2); - $expected = array(); - $expected[] = array('uid' => 1); - $expected[] = array('uid' => 2); + $expected = []; + $expected[] = ['uid' => 1]; + $expected[] = ['uid' => 2]; $this->assertIdenticalResultset($view, $expected, $column_map); $view->destroy(); // Filter by another permission of a role with multiple permissions. $view->initHandlers(); - $view->filter['permission']->value = array('administer users'); + $view->filter['permission']->value = ['administer users']; $this->executeView($view); $this->assertEqual(count($view->result), 1); - $expected = array(); - $expected[] = array('uid' => 4); + $expected = []; + $expected[] = ['uid' => 4]; $this->assertIdenticalResultset($view, $expected, $column_map); $view->destroy(); @@ -103,7 +103,7 @@ public function testFilterPermission() { foreach ($permissions as $name => $permission) { $permission_by_module[$permission['provider']][$name] = $permission; } - foreach (array('system' => 'System', 'user' => 'User') as $module => $title) { + foreach (['system' => 'System', 'user' => 'User'] as $module => $title) { $expected = array_map(function ($permission) { return Html::escape(strip_tags($permission['title'])); }, $permission_by_module[$module]); diff --git a/core/modules/user/tests/src/Kernel/Views/HandlerFilterRolesTest.php b/core/modules/user/tests/src/Kernel/Views/HandlerFilterRolesTest.php index 37d0f2cd..ec5a06bf 100644 --- a/core/modules/user/tests/src/Kernel/Views/HandlerFilterRolesTest.php +++ b/core/modules/user/tests/src/Kernel/Views/HandlerFilterRolesTest.php @@ -20,7 +20,7 @@ class HandlerFilterRolesTest extends UserKernelTestBase { * * @var array */ - public static $testViews = array('test_user_name'); + public static $testViews = ['test_user_name']; /** * Tests that role filter dependencies are calculated correctly. @@ -34,6 +34,19 @@ public function testDependencies() { ]; $this->assertEqual($expected, $view->getDependencies()); + $display = &$view->getDisplay('default'); + $display['display_options']['filters']['roles_target_id'] = [ + 'id' => 'roles_target_id', + 'table' => 'user__roles', + 'field' => 'roles_target_id', + 'value' => ['test_user_role' => 'test_user_role'], + 'plugin_id' => 'user_roles', + ]; + $view->save(); + $expected['config'][] = 'user.role.test_user_role'; + $this->assertEqual($expected, $view->getDependencies()); + + $view = View::load('test_user_name'); $display = &$view->getDisplay('default'); $display['display_options']['filters']['roles_target_id'] = [ 'id' => 'roles_target_id', @@ -42,10 +55,26 @@ public function testDependencies() { 'value' => [ 'test_user_role' => 'test_user_role', ], + 'operator' => 'empty', + 'plugin_id' => 'user_roles', + ]; + $view->save(); + unset($expected['config']); + $this->assertEqual($expected, $view->getDependencies()); + + $view = View::load('test_user_name'); + $display = &$view->getDisplay('default'); + $display['display_options']['filters']['roles_target_id'] = [ + 'id' => 'roles_target_id', + 'table' => 'user__roles', + 'field' => 'roles_target_id', + 'value' => [ + 'test_user_role' => 'test_user_role', + ], + 'operator' => 'not empty', 'plugin_id' => 'user_roles', ]; $view->save(); - $expected['config'][] = 'user.role.test_user_role'; $this->assertEqual($expected, $view->getDependencies()); $view = Views::getView('test_user_name'); @@ -63,7 +92,6 @@ public function testDependencies() { 'plugin_id' => 'user_roles', ]; $view->save(); - unset($expected['config']); $this->assertEqual($expected, $view->getDependencies()); } diff --git a/core/modules/user/tests/src/Kernel/Views/UserKernelTestBase.php b/core/modules/user/tests/src/Kernel/Views/UserKernelTestBase.php index 075315c5..0e862c86 100644 --- a/core/modules/user/tests/src/Kernel/Views/UserKernelTestBase.php +++ b/core/modules/user/tests/src/Kernel/Views/UserKernelTestBase.php @@ -15,14 +15,14 @@ abstract class UserKernelTestBase extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('user_test_views', 'user', 'system', 'field'); + public static $modules = ['user_test_views', 'user', 'system', 'field']; /** * Users to use during this test. * * @var array */ - protected $users = array(); + protected $users = []; /** * The entity storage for roles. @@ -41,7 +41,7 @@ abstract class UserKernelTestBase extends ViewsKernelTestBase { protected function setUp($import_test_views = TRUE) { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('user_test_views')); + ViewTestData::createTestViews(get_class($this), ['user_test_views']); $this->installEntitySchema('user'); @@ -55,33 +55,33 @@ protected function setUp($import_test_views = TRUE) { */ protected function setupPermissionTestData() { // Setup a role without any permission. - $this->roleStorage->create(array('id' => 'authenticated')) + $this->roleStorage->create(['id' => 'authenticated']) ->save(); - $this->roleStorage->create(array('id' => 'no_permission')) + $this->roleStorage->create(['id' => 'no_permission']) ->save(); // Setup a role with just one permission. - $this->roleStorage->create(array('id' => 'one_permission')) + $this->roleStorage->create(['id' => 'one_permission']) ->save(); - user_role_grant_permissions('one_permission', array('administer permissions')); + user_role_grant_permissions('one_permission', ['administer permissions']); // Setup a role with multiple permissions. - $this->roleStorage->create(array('id' => 'multiple_permissions')) + $this->roleStorage->create(['id' => 'multiple_permissions']) ->save(); - user_role_grant_permissions('multiple_permissions', array('administer permissions', 'administer users', 'access user profiles')); + user_role_grant_permissions('multiple_permissions', ['administer permissions', 'administer users', 'access user profiles']); // Setup a user without an extra role. $this->users[] = $account = $this->userStorage->create(['name' => $this->randomString()]); $account->save(); // Setup a user with just the first role (so no permission beside the // ones from the authenticated role). - $this->users[] = $account = $this->userStorage->create(array('name' => 'first_role')); + $this->users[] = $account = $this->userStorage->create(['name' => 'first_role']); $account->addRole('no_permission'); $account->save(); // Setup a user with just the second role (so one additional permission). - $this->users[] = $account = $this->userStorage->create(array('name' => 'second_role')); + $this->users[] = $account = $this->userStorage->create(['name' => 'second_role']); $account->addRole('one_permission'); $account->save(); // Setup a user with both the second and the third role. - $this->users[] = $account = $this->userStorage->create(array('name' => 'second_third_role')); + $this->users[] = $account = $this->userStorage->create(['name' => 'second_third_role']); $account->addRole('one_permission'); $account->addRole('multiple_permissions'); $account->save(); diff --git a/core/modules/user/tests/src/Traits/UserCreationTrait.php b/core/modules/user/tests/src/Traits/UserCreationTrait.php new file mode 100644 index 00000000..ccccfa77 --- /dev/null +++ b/core/modules/user/tests/src/Traits/UserCreationTrait.php @@ -0,0 +1,213 @@ +setAccount($account); + } + + /** + * Create a user with a given set of permissions. + * + * @param array $permissions + * Array of permission names to assign to user. Note that the user always + * has the default permissions derived from the "authenticated users" role. + * @param string $name + * The user name. + * @param bool $admin + * (optional) Whether the user should be an administrator + * with all the available permissions. + * + * @return \Drupal\user\Entity\User|false + * A fully loaded user object with pass_raw property, or FALSE if account + * creation fails. + */ + protected function createUser(array $permissions = [], $name = NULL, $admin = FALSE) { + // Create a role with the given permission set, if any. + $rid = FALSE; + if ($permissions) { + $rid = $this->createRole($permissions); + if (!$rid) { + return FALSE; + } + } + + // Create a user assigned to that role. + $edit = []; + $edit['name'] = !empty($name) ? $name : $this->randomMachineName(); + $edit['mail'] = $edit['name'] . '@example.com'; + $edit['pass'] = user_password(); + $edit['status'] = 1; + if ($rid) { + $edit['roles'] = [$rid]; + } + + if ($admin) { + $edit['roles'][] = $this->createAdminRole(); + } + + $account = User::create($edit); + $account->save(); + + $this->assertTrue($account->id(), SafeMarkup::format('User created with name %name and pass %pass', ['%name' => $edit['name'], '%pass' => $edit['pass']]), 'User login'); + if (!$account->id()) { + return FALSE; + } + + // Add the raw password so that we can log in as this user. + $account->pass_raw = $edit['pass']; + // Support BrowserTestBase as well. + $account->passRaw = $account->pass_raw; + return $account; + } + + /** + * Creates an administrative role. + * + * @param string $rid + * (optional) The role ID (machine name). Defaults to a random name. + * @param string $name + * (optional) The label for the role. Defaults to a random string. + * @param int $weight + * (optional) The weight for the role. Defaults NULL so that entity_create() + * sets the weight to maximum + 1. + * + * @return string + * Role ID of newly created role, or FALSE if role creation failed. + */ + protected function createAdminRole($rid = NULL, $name = NULL, $weight = NULL) { + $rid = $this->createRole([], $rid, $name, $weight); + if ($rid) { + /** @var \Drupal\user\RoleInterface $role */ + $role = Role::load($rid); + $role->setIsAdmin(TRUE); + $role->save(); + } + return $rid; + } + + /** + * Creates a role with specified permissions. + * + * @param array $permissions + * Array of permission names to assign to role. + * @param string $rid + * (optional) The role ID (machine name). Defaults to a random name. + * @param string $name + * (optional) The label for the role. Defaults to a random string. + * @param int $weight + * (optional) The weight for the role. Defaults NULL so that entity_create() + * sets the weight to maximum + 1. + * + * @return string + * Role ID of newly created role, or FALSE if role creation failed. + */ + protected function createRole(array $permissions, $rid = NULL, $name = NULL, $weight = NULL) { + // Generate a random, lowercase machine name if none was passed. + if (!isset($rid)) { + $rid = strtolower($this->randomMachineName(8)); + } + // Generate a random label. + if (!isset($name)) { + // In the role UI role names are trimmed and random string can start or + // end with a space. + $name = trim($this->randomString(8)); + } + + // Check the all the permissions strings are valid. + if (!$this->checkPermissions($permissions)) { + return FALSE; + } + + // Create new role. + $role = Role::create([ + 'id' => $rid, + 'label' => $name, + ]); + if (isset($weight)) { + $role->set('weight', $weight); + } + $result = $role->save(); + + $this->assertIdentical($result, SAVED_NEW, SafeMarkup::format('Created role ID @rid with name @name.', [ + '@name' => var_export($role->label(), TRUE), + '@rid' => var_export($role->id(), TRUE), + ]), 'Role'); + + if ($result === SAVED_NEW) { + // Grant the specified permissions to the role, if any. + if (!empty($permissions)) { + $this->grantPermissions($role, $permissions); + $assigned_permissions = Role::load($role->id())->getPermissions(); + $missing_permissions = array_diff($permissions, $assigned_permissions); + if (!$missing_permissions) { + $this->pass(SafeMarkup::format('Created permissions: @perms', ['@perms' => implode(', ', $permissions)]), 'Role'); + } + else { + $this->fail(SafeMarkup::format('Failed to create permissions: @perms', ['@perms' => implode(', ', $missing_permissions)]), 'Role'); + } + } + return $role->id(); + } + else { + return FALSE; + } + } + + /** + * Checks whether a given list of permission names is valid. + * + * @param array $permissions + * The permission names to check. + * + * @return bool + * TRUE if the permissions are valid, FALSE otherwise. + */ + protected function checkPermissions(array $permissions) { + $available = array_keys(\Drupal::service('user.permissions')->getPermissions()); + $valid = TRUE; + foreach ($permissions as $permission) { + if (!in_array($permission, $available)) { + $this->fail(SafeMarkup::format('Invalid permission %permission.', ['%permission' => $permission]), 'Role'); + $valid = FALSE; + } + } + return $valid; + } + + /** + * Grant permissions to a user role. + * + * @param \Drupal\user\RoleInterface $role + * The ID of a user role to alter. + * @param array $permissions + * (optional) A list of permission names to grant. + */ + protected function grantPermissions(RoleInterface $role, array $permissions) { + foreach ($permissions as $permission) { + $role->grantPermission($permission); + } + $role->trustData()->save(); + } + +} diff --git a/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php b/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php index 97e9f33f..97cf5931 100644 --- a/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php +++ b/core/modules/user/tests/src/Unit/Menu/UserLocalTasksTest.php @@ -12,7 +12,7 @@ class UserLocalTasksTest extends LocalTaskIntegrationTestBase { protected function setUp() { - $this->directoryList = array('user' => 'core/modules/user'); + $this->directoryList = ['user' => 'core/modules/user']; parent::setUp(); } @@ -29,12 +29,12 @@ public function testUserAdminLocalTasks($route, $expected) { * Provides a list of routes to test. */ public function getUserAdminRoutes() { - return array( - array('entity.user.collection', array(array('entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection'))), - array('user.admin_permissions', array(array('entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection'))), - array('entity.user_role.collection', array(array('entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection'))), - array('entity.user.admin_form', array(array('user.account_settings_tab'))), - ); + return [ + ['entity.user.collection', [['entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection']]], + ['user.admin_permissions', [['entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection']]], + ['entity.user_role.collection', [['entity.user.collection', 'user.admin_permissions', 'entity.user_role.collection']]], + ['entity.user.admin_form', [['user.account_settings_tab']]], + ]; } /** @@ -43,9 +43,9 @@ public function getUserAdminRoutes() { * @dataProvider getUserLoginRoutes */ public function testUserLoginLocalTasks($route) { - $tasks = array( - 0 => array('user.register', 'user.pass', 'user.login',), - ); + $tasks = [ + 0 => ['user.register', 'user.pass', 'user.login'], + ]; $this->assertLocalTasks($route, $tasks); } @@ -53,11 +53,11 @@ public function testUserLoginLocalTasks($route) { * Provides a list of routes to test. */ public function getUserLoginRoutes() { - return array( - array('user.login'), - array('user.register'), - array('user.pass'), - ); + return [ + ['user.login'], + ['user.register'], + ['user.pass'], + ]; } /** @@ -65,11 +65,13 @@ public function getUserLoginRoutes() { * * @dataProvider getUserPageRoutes */ - public function testUserPageLocalTasks($route, $subtask = array()) { - $tasks = array( - 0 => array('entity.user.canonical', 'entity.user.edit_form',), - ); - if ($subtask) $tasks[] = $subtask; + public function testUserPageLocalTasks($route, $subtask = []) { + $tasks = [ + 0 => ['entity.user.canonical', 'entity.user.edit_form'], + ]; + if ($subtask) { + $tasks[] = $subtask; + } $this->assertLocalTasks($route, $tasks); } @@ -77,10 +79,10 @@ public function testUserPageLocalTasks($route, $subtask = array()) { * Provides a list of routes to test. */ public function getUserPageRoutes() { - return array( - array('entity.user.canonical'), - array('entity.user.edit_form'), - ); + return [ + ['entity.user.canonical'], + ['entity.user.edit_form'], + ]; } } diff --git a/core/modules/user/tests/src/Unit/PermissionAccessCheckTest.php b/core/modules/user/tests/src/Unit/PermissionAccessCheckTest.php index bcfd7505..84290cc9 100644 --- a/core/modules/user/tests/src/Unit/PermissionAccessCheckTest.php +++ b/core/modules/user/tests/src/Unit/PermissionAccessCheckTest.php @@ -55,10 +55,10 @@ public function providerTestAccess() { return [ [[], FALSE], [['_permission' => 'allowed'], TRUE, ['user.permissions']], - [['_permission' => 'denied'], FALSE, ['user.permissions']], + [['_permission' => 'denied'], FALSE, ['user.permissions'], "The 'denied' permission is required."], [['_permission' => 'allowed+denied'], TRUE, ['user.permissions']], [['_permission' => 'allowed+denied+other'], TRUE, ['user.permissions']], - [['_permission' => 'allowed,denied'], FALSE, ['user.permissions']], + [['_permission' => 'allowed,denied'], FALSE, ['user.permissions'], "The following permissions are required: 'allowed' AND 'denied'."], ]; } @@ -68,8 +68,11 @@ public function providerTestAccess() { * @dataProvider providerTestAccess * @covers ::access */ - public function testAccess($requirements, $access, array $contexts = []) { + public function testAccess($requirements, $access, array $contexts = [], $message = '') { $access_result = AccessResult::allowedIf($access)->addCacheContexts($contexts); + if (!empty($message)) { + $access_result->setReason($message); + } $user = $this->getMock('Drupal\Core\Session\AccountInterface'); $user->expects($this->any()) ->method('hasPermission') diff --git a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php index b0b91da8..2918d2f6 100644 --- a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php +++ b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php @@ -97,11 +97,11 @@ public function testBuildPermissionsYaml() { $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->moduleHandler->expects($this->once()) ->method('getModuleDirectories') - ->willReturn(array( + ->willReturn([ 'module_a' => vfsStream::url('modules/module_a'), 'module_b' => vfsStream::url('modules/module_b'), 'module_c' => vfsStream::url('modules/module_c'), - )); + ]); $url = vfsStream::url('modules'); mkdir($url . '/module_a'); @@ -124,16 +124,16 @@ public function testBuildPermissionsYaml() { 'restrict access': TRUE EOF ); - $modules = array('module_a', 'module_b', 'module_c'); - $extensions = array( + $modules = ['module_a', 'module_b', 'module_c']; + $extensions = [ 'module_a' => $this->mockModuleExtension('module_a', 'Module a'), 'module_b' => $this->mockModuleExtension('module_b', 'Module b'), 'module_c' => $this->mockModuleExtension('module_c', 'Module c'), - ); + ]; $this->moduleHandler->expects($this->any()) ->method('getImplementations') ->with('permission') - ->willReturn(array()); + ->willReturn([]); $this->moduleHandler->expects($this->any()) ->method('getModuleList') @@ -227,11 +227,11 @@ public function testBuildPermissionsYamlCallback() { $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->moduleHandler->expects($this->once()) ->method('getModuleDirectories') - ->willReturn(array( + ->willReturn([ 'module_a' => vfsStream::url('modules/module_a'), 'module_b' => vfsStream::url('modules/module_b'), 'module_c' => vfsStream::url('modules/module_c'), - )); + ]); $url = vfsStream::url('modules'); mkdir($url . '/module_a'); @@ -254,17 +254,17 @@ public function testBuildPermissionsYamlCallback() { EOF ); - $modules = array('module_a', 'module_b', 'module_c'); - $extensions = array( + $modules = ['module_a', 'module_b', 'module_c']; + $extensions = [ 'module_a' => $this->mockModuleExtension('module_a', 'Module a'), 'module_b' => $this->mockModuleExtension('module_b', 'Module b'), 'module_c' => $this->mockModuleExtension('module_c', 'Module c'), - ); + ]; $this->moduleHandler->expects($this->any()) ->method('getImplementations') ->with('permission') - ->willReturn(array()); + ->willReturn([]); $this->moduleHandler->expects($this->any()) ->method('getModuleList') @@ -273,19 +273,19 @@ public function testBuildPermissionsYamlCallback() { $this->controllerResolver->expects($this->at(0)) ->method('getControllerFromDefinition') ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::singleDescription') - ->willReturn(array(new TestPermissionCallbacks(), 'singleDescription')); + ->willReturn([new TestPermissionCallbacks(), 'singleDescription']); $this->controllerResolver->expects($this->at(1)) ->method('getControllerFromDefinition') ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription') - ->willReturn(array(new TestPermissionCallbacks(), 'titleDescription')); + ->willReturn([new TestPermissionCallbacks(), 'titleDescription']); $this->controllerResolver->expects($this->at(2)) ->method('getControllerFromDefinition') ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleProvider') - ->willReturn(array(new TestPermissionCallbacks(), 'titleProvider')); + ->willReturn([new TestPermissionCallbacks(), 'titleProvider']); $this->controllerResolver->expects($this->at(3)) ->method('getControllerFromDefinition') ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescriptionRestrictAccess') - ->willReturn(array(new TestPermissionCallbacks(), 'titleDescriptionRestrictAccess')); + ->willReturn([new TestPermissionCallbacks(), 'titleDescriptionRestrictAccess']); $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver); @@ -307,9 +307,9 @@ public function testPermissionsYamlStaticAndCallback() { $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->moduleHandler->expects($this->once()) ->method('getModuleDirectories') - ->willReturn(array( + ->willReturn([ 'module_a' => vfsStream::url('modules/module_a'), - )); + ]); $url = vfsStream::url('modules'); mkdir($url . '/module_a'); @@ -322,15 +322,15 @@ public function testPermissionsYamlStaticAndCallback() { EOF ); - $modules = array('module_a'); - $extensions = array( + $modules = ['module_a']; + $extensions = [ 'module_a' => $this->mockModuleExtension('module_a', 'Module a'), - ); + ]; $this->moduleHandler->expects($this->any()) ->method('getImplementations') ->with('permission') - ->willReturn(array()); + ->willReturn([]); $this->moduleHandler->expects($this->any()) ->method('getModuleList') @@ -339,7 +339,7 @@ public function testPermissionsYamlStaticAndCallback() { $this->controllerResolver->expects($this->once()) ->method('getControllerFromDefinition') ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription') - ->willReturn(array(new TestPermissionCallbacks(), 'titleDescription')); + ->willReturn([new TestPermissionCallbacks(), 'titleDescription']); $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver); @@ -399,37 +399,37 @@ public function setSystemRebuildModuleData(array $extensions) { class TestPermissionCallbacks { public function singleDescription() { - return array( + return [ 'access_module_a' => 'single_description' - ); + ]; } public function titleDescription() { - return array( - 'access module b' => array( + return [ + 'access module b' => [ 'title' => 'Access B', 'description' => 'bla bla', - ), - ); + ], + ]; } public function titleDescriptionRestrictAccess() { - return array( - 'access_module_c' => array( + return [ + 'access_module_c' => [ 'title' => 'Access C', 'description' => 'bla bla', 'restrict access' => TRUE, - ), - ); + ], + ]; } public function titleProvider() { - return array( - 'access module a via module b' => array( + return [ + 'access module a via module b' => [ 'title' => 'Access A via B', 'provider' => 'module_a', - ), - ); + ], + ]; } } @@ -442,7 +442,7 @@ class TestTranslationManager implements TranslationInterface { /** * {@inheritdoc} */ - public function translate($string, array $args = array(), array $options = array()) { + public function translate($string, array $args = [], array $options = []) { return new TranslatableMarkup($string, $args, $options, $this); } @@ -456,7 +456,7 @@ public function translateString(TranslatableMarkup $translated_string) { /** * {@inheritdoc} */ - public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array()) { + public function formatPlural($count, $singular, $plural, array $args = [], array $options = []) { return new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $this); } diff --git a/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php b/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php index 0763b256..1f460517 100644 --- a/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php +++ b/core/modules/user/tests/src/Unit/Plugin/Action/AddRoleUserTest.php @@ -22,10 +22,10 @@ public function testExecuteAddExistingRole() { ->with($this->equalTo('test_role_1')) ->will($this->returnValue(TRUE)); - $config = array('rid' => 'test_role_1'); - $remove_role_plugin = new AddRoleUser($config, 'user_add_role_action', array('type' => 'user'), $this->userRoleEntityType); + $config = ['rid' => 'test_role_1']; + $add_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType); - $remove_role_plugin->execute($this->account); + $add_role_plugin->execute($this->account); } /** @@ -40,10 +40,10 @@ public function testExecuteAddNonExistingRole() { ->with($this->equalTo('test_role_1')) ->will($this->returnValue(FALSE)); - $config = array('rid' => 'test_role_1'); - $remove_role_plugin = new AddRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType); + $config = ['rid' => 'test_role_1']; + $add_role_plugin = new AddRoleUser($config, 'user_add_role_action', ['type' => 'user'], $this->userRoleEntityType); - $remove_role_plugin->execute($this->account); + $add_role_plugin->execute($this->account); } } diff --git a/core/modules/user/tests/src/Unit/Plugin/Action/RemoveRoleUserTest.php b/core/modules/user/tests/src/Unit/Plugin/Action/RemoveRoleUserTest.php index 1c6fa25b..878b4baa 100644 --- a/core/modules/user/tests/src/Unit/Plugin/Action/RemoveRoleUserTest.php +++ b/core/modules/user/tests/src/Unit/Plugin/Action/RemoveRoleUserTest.php @@ -22,8 +22,8 @@ public function testExecuteRemoveExistingRole() { ->with($this->equalTo('test_role_1')) ->will($this->returnValue(TRUE)); - $config = array('rid' => 'test_role_1'); - $remove_role_plugin = new RemoveRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType); + $config = ['rid' => 'test_role_1']; + $remove_role_plugin = new RemoveRoleUser($config, 'user_remove_role_action', ['type' => 'user'], $this->userRoleEntityType); $remove_role_plugin->execute($this->account); } @@ -40,8 +40,8 @@ public function testExecuteRemoveNonExistingRole() { ->with($this->equalTo('test_role_1')) ->will($this->returnValue(FALSE)); - $config = array('rid' => 'test_role_1'); - $remove_role_plugin = new RemoveRoleUser($config, 'user_remove_role_action', array('type' => 'user'), $this->userRoleEntityType); + $config = ['rid' => 'test_role_1']; + $remove_role_plugin = new RemoveRoleUser($config, 'user_remove_role_action', ['type' => 'user'], $this->userRoleEntityType); $remove_role_plugin->execute($this->account); } diff --git a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php index 86ce8e9a..623203ee 100644 --- a/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php +++ b/core/modules/user/tests/src/Unit/Plugin/Core/Entity/UserTest.php @@ -14,20 +14,20 @@ class UserTest extends UserSessionTest { /** * {@inheritdoc} */ - protected function createUserSession(array $rids = array(), $authenticated = FALSE) { + protected function createUserSession(array $rids = [], $authenticated = FALSE) { $user = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('get', 'id')) + ->setMethods(['get', 'id']) ->getMock(); $user->expects($this->any()) ->method('id') // @todo Also test the uid = 1 handling. ->will($this->returnValue($authenticated ? 2 : 0)); - $roles = array(); + $roles = []; foreach ($rids as $rid) { - $roles[] = (object) array( + $roles[] = (object) [ 'target_id' => $rid, - ); + ]; } $user->expects($this->any()) ->method('get') @@ -44,14 +44,14 @@ protected function createUserSession(array $rids = array(), $authenticated = FAL */ public function testUserGetRoles() { // Anonymous user. - $user = $this->createUserSession(array()); - $this->assertEquals(array(RoleInterface::ANONYMOUS_ID), $user->getRoles()); - $this->assertEquals(array(), $user->getRoles(TRUE)); + $user = $this->createUserSession([]); + $this->assertEquals([RoleInterface::ANONYMOUS_ID], $user->getRoles()); + $this->assertEquals([], $user->getRoles(TRUE)); // Authenticated user. - $user = $this->createUserSession(array(), TRUE); - $this->assertEquals(array(RoleInterface::AUTHENTICATED_ID), $user->getRoles()); - $this->assertEquals(array(), $user->getRoles(TRUE)); + $user = $this->createUserSession([], TRUE); + $this->assertEquals([RoleInterface::AUTHENTICATED_ID], $user->getRoles()); + $this->assertEquals([], $user->getRoles(TRUE)); } } diff --git a/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidatorTest.php b/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidatorTest.php index d29c8c53..805c96ec 100644 --- a/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidatorTest.php +++ b/core/modules/user/tests/src/Unit/Plugin/Validation/Constraint/ProtectedUserFieldConstraintValidatorTest.php @@ -5,6 +5,7 @@ use Drupal\Tests\UnitTestCase; use Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraint; use Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraintValidator; +use Symfony\Component\Validator\Context\ExecutionContextInterface; /** * @coversDefaultClass \Drupal\user\Plugin\Validation\Constraint\ProtectedUserFieldConstraintValidator @@ -47,12 +48,12 @@ public function testValidate($items, $expected_violation, $name = FALSE) { // If a violation is expected, then the context's addViolation method will // be called, otherwise it should not be called. - $context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface'); + $context = $this->getMock(ExecutionContextInterface::class); if ($expected_violation) { $context->expects($this->once()) ->method('addViolation') - ->with($constraint->message, array('%name' => $name)); + ->with($constraint->message, ['%name' => $name]); } else { $context->expects($this->never()) diff --git a/core/modules/user/tests/src/Unit/Plugin/views/field/UserBulkFormTest.php b/core/modules/user/tests/src/Unit/Plugin/views/field/UserBulkFormTest.php index cdbd30a5..11a970a0 100644 --- a/core/modules/user/tests/src/Unit/Plugin/views/field/UserBulkFormTest.php +++ b/core/modules/user/tests/src/Unit/Plugin/views/field/UserBulkFormTest.php @@ -25,7 +25,7 @@ protected function tearDown() { * Tests the constructor assignment of actions. */ public function testConstructor() { - $actions = array(); + $actions = []; for ($i = 1; $i <= 2; $i++) { $action = $this->getMock('\Drupal\system\ActionConfigEntityInterface'); @@ -60,7 +60,7 @@ public function testConstructor() { $views_data->expects($this->any()) ->method('get') ->with('users') - ->will($this->returnValue(array('table' => array('entity type' => 'user')))); + ->will($this->returnValue(['table' => ['entity type' => 'user']])); $container = new ContainerBuilder(); $container->set('views.views_data', $views_data); $container->set('string_translation', $this->getStringTranslationStub()); @@ -82,9 +82,9 @@ public function testConstructor() { ->getMock(); $definition['title'] = ''; - $options = array(); + $options = []; - $user_bulk_form = new UserBulkForm(array(), 'user_bulk_form', $definition, $entity_manager, $language_manager); + $user_bulk_form = new UserBulkForm([], 'user_bulk_form', $definition, $entity_manager, $language_manager); $user_bulk_form->init($executable, $display, $options); $this->assertAttributeEquals(array_slice($actions, 0, -1, TRUE), 'actions', $user_bulk_form); diff --git a/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php b/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php index 515c862a..8d188114 100644 --- a/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php +++ b/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php @@ -4,6 +4,7 @@ use Drupal\Tests\UnitTestCase; use Drupal\user\PrivateTempStore; +use Drupal\user\TempStoreException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -81,11 +82,11 @@ protected function setUp() { $this->tempStore = new PrivateTempStore($this->keyValue, $this->lock, $this->currentUser, $this->requestStack, 604800); - $this->ownObject = (object) array( + $this->ownObject = (object) [ 'data' => 'test_data', 'owner' => $this->currentUser->id(), 'updated' => (int) $request->server->get('REQUEST_TIME'), - ); + ]; // Clone the object but change the owner. $this->otherObject = clone $this->ownObject; @@ -121,7 +122,6 @@ public function testGet() { * Tests the set() method with no lock available. * * @covers ::set - * @expectedException \Drupal\user\TempStoreException */ public function testSetWithNoLockAvailable() { $this->lock->expects($this->at(0)) @@ -139,6 +139,7 @@ public function testSetWithNoLockAvailable() { $this->keyValue->expects($this->once()) ->method('getCollectionName'); + $this->setExpectedException(TempStoreException::class); $this->tempStore->set('test', 'value'); } @@ -220,7 +221,6 @@ public function testDeleteLocking() { * Tests the delete() method with no lock available. * * @covers ::delete - * @expectedException \Drupal\user\TempStoreException */ public function testDeleteWithNoLockAvailable() { $this->keyValue->expects($this->once()) @@ -242,6 +242,7 @@ public function testDeleteWithNoLockAvailable() { $this->keyValue->expects($this->once()) ->method('getCollectionName'); + $this->setExpectedException(TempStoreException::class); $this->tempStore->delete('test'); } diff --git a/core/modules/user/tests/src/Unit/SharedTempStoreTest.php b/core/modules/user/tests/src/Unit/SharedTempStoreTest.php index 15a4ec6c..33bde413 100644 --- a/core/modules/user/tests/src/Unit/SharedTempStoreTest.php +++ b/core/modules/user/tests/src/Unit/SharedTempStoreTest.php @@ -4,6 +4,7 @@ use Drupal\Tests\UnitTestCase; use Drupal\user\SharedTempStore; +use Drupal\user\TempStoreException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -76,11 +77,11 @@ protected function setUp() { $this->tempStore = new SharedTempStore($this->keyValue, $this->lock, $this->owner, $this->requestStack, 604800); - $this->ownObject = (object) array( + $this->ownObject = (object) [ 'data' => 'test_data', 'owner' => $this->owner, 'updated' => (int) $request->server->get('REQUEST_TIME'), - ); + ]; // Clone the object but change the owner. $this->otherObject = clone $this->ownObject; @@ -132,7 +133,6 @@ public function testGetIfOwner() { * Tests the set() method with no lock available. * * @covers ::set - * @expectedException \Drupal\user\TempStoreException */ public function testSetWithNoLockAvailable() { $this->lock->expects($this->at(0)) @@ -150,6 +150,7 @@ public function testSetWithNoLockAvailable() { $this->keyValue->expects($this->once()) ->method('getCollectionName'); + $this->setExpectedException(TempStoreException::class); $this->tempStore->set('test', 'value'); } @@ -296,7 +297,6 @@ public function testDelete() { * Tests the delete() method with no lock available. * * @covers ::delete - * @expectedException \Drupal\user\TempStoreException */ public function testDeleteWithNoLockAvailable() { $this->lock->expects($this->at(0)) @@ -314,6 +314,7 @@ public function testDeleteWithNoLockAvailable() { $this->keyValue->expects($this->once()) ->method('getCollectionName'); + $this->setExpectedException(TempStoreException::class); $this->tempStore->delete('test'); } diff --git a/core/modules/user/tests/src/Unit/UserAccessControlHandlerTest.php b/core/modules/user/tests/src/Unit/UserAccessControlHandlerTest.php index 75e6ccb1..216e8d65 100644 --- a/core/modules/user/tests/src/Unit/UserAccessControlHandlerTest.php +++ b/core/modules/user/tests/src/Unit/UserAccessControlHandlerTest.php @@ -80,10 +80,10 @@ protected function setUp() { $this->owner ->expects($this->any()) ->method('hasPermission') - ->will($this->returnValueMap(array( - array('administer users', FALSE), - array('change own username', TRUE), - ))); + ->will($this->returnValueMap([ + ['administer users', FALSE], + ['change own username', TRUE], + ])); $this->owner ->expects($this->any()) @@ -102,7 +102,7 @@ protected function setUp() { $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $module_handler->expects($this->any()) ->method('getImplementations') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $this->accessControlHandler->setModuleHandler($module_handler); $this->items = $this->getMockBuilder('Drupal\Core\Field\FieldItemList') @@ -128,7 +128,7 @@ public function assertFieldAccess($field, $viewer, $target, $view, $edit) { ->method('getEntity') ->will($this->returnValue($this->{$target})); - foreach (array('view' => $view, 'edit' => $edit) as $operation => $result) { + foreach (['view' => $view, 'edit' => $edit] as $operation => $result) { $result_text = !isset($result) ? 'null' : ($result ? 'true' : 'false'); $message = "User '$field' field access returns '$result_text' with operation '$operation' for '$viewer' accessing '$target'"; $this->assertSame($result, $this->accessControlHandler->fieldAccess($operation, $field_definition, $this->{$viewer}, $this->items), $message); @@ -145,44 +145,44 @@ public function testUserNameAccess($viewer, $target, $view, $edit) { } /** - * Provides test data for estUserNameAccess(). + * Provides test data for testUserNameAccess(). */ public function userNameProvider() { - $name_access = array( + $name_access = [ // The viewer user is allowed to see user names on all accounts. - array( + [ 'viewer' => 'viewer', 'target' => 'viewer', 'view' => TRUE, 'edit' => FALSE, - ), - array( + ], + [ 'viewer' => 'owner', 'target' => 'viewer', 'view' => TRUE, 'edit' => FALSE, - ), - array( + ], + [ 'viewer' => 'viewer', 'target' => 'owner', 'view' => TRUE, 'edit' => FALSE, - ), + ], // The owner user is allowed to change its own user name. - array( + [ 'viewer' => 'owner', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ), + ], // The users-administrator user has full access. - array( + [ 'viewer' => 'admin', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ), - ); + ], + ]; return $name_access; } @@ -199,24 +199,24 @@ public function testHiddenUserSettings($field, $viewer, $target, $view, $edit) { * Provides test data for testHiddenUserSettings(). */ public function hiddenUserSettingsProvider() { - $access_info = array(); + $access_info = []; - $fields = array( + $fields = [ 'preferred_langcode', 'preferred_admin_langcode', 'timezone', 'mail', - ); + ]; foreach ($fields as $field) { - $access_info[] = array( + $access_info[] = [ 'field' => $field, 'viewer' => 'viewer', 'target' => 'viewer', 'view' => TRUE, 'edit' => TRUE, - ); - $access_info[] = array( + ]; + $access_info[] = [ 'field' => $field, 'viewer' => 'viewer', 'target' => 'owner', @@ -225,21 +225,21 @@ public function hiddenUserSettingsProvider() { // reality edit access will already be checked on entity level and the // user without view access will typically not be able to edit. 'edit' => TRUE, - ); - $access_info[] = array( + ]; + $access_info[] = [ 'field' => $field, 'viewer' => 'owner', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ); - $access_info[] = array( + ]; + $access_info[] = [ 'field' => $field, 'viewer' => 'admin', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ); + ]; } return $access_info; @@ -258,38 +258,38 @@ public function testAdminFieldAccess($field, $viewer, $target, $view, $edit) { * Provides test data for testAdminFieldAccess(). */ public function adminFieldAccessProvider() { - $access_info = array(); + $access_info = []; - $fields = array( + $fields = [ 'roles', 'status', 'access', 'login', 'init', - ); + ]; foreach ($fields as $field) { - $access_info[] = array( + $access_info[] = [ 'field' => $field, 'viewer' => 'viewer', 'target' => 'viewer', 'view' => FALSE, 'edit' => FALSE, - ); - $access_info[] = array( + ]; + $access_info[] = [ 'field' => $field, 'viewer' => 'viewer', 'target' => 'owner', 'view' => FALSE, 'edit' => FALSE, - ); - $access_info[] = array( + ]; + $access_info[] = [ 'field' => $field, 'viewer' => 'admin', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ); + ]; } return $access_info; @@ -308,14 +308,14 @@ public function testPasswordAccess($viewer, $target, $view, $edit) { * Provides test data for passwordAccessProvider(). */ public function passwordAccessProvider() { - $pass_access = array( - array( + $pass_access = [ + [ 'viewer' => 'viewer', 'target' => 'viewer', 'view' => FALSE, 'edit' => TRUE, - ), - array( + ], + [ 'viewer' => 'viewer', 'target' => 'owner', 'view' => FALSE, @@ -323,20 +323,20 @@ public function passwordAccessProvider() { // reality edit access will already be checked on entity level and the // user without view access will typically not be able to edit. 'edit' => TRUE, - ), - array( + ], + [ 'viewer' => 'owner', 'target' => 'viewer', 'view' => FALSE, 'edit' => TRUE, - ), - array( + ], + [ 'viewer' => 'admin', 'target' => 'owner', 'view' => FALSE, 'edit' => TRUE, - ), - ); + ], + ]; return $pass_access; } @@ -353,26 +353,26 @@ public function testCreatedAccess($viewer, $target, $view, $edit) { * Provides test data for testCreatedAccess(). */ public function createdAccessProvider() { - $created_access = array( - array( + $created_access = [ + [ 'viewer' => 'viewer', 'target' => 'viewer', 'view' => TRUE, 'edit' => FALSE, - ), - array( + ], + [ 'viewer' => 'owner', 'target' => 'viewer', 'view' => TRUE, 'edit' => FALSE, - ), - array( + ], + [ 'viewer' => 'admin', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ), - ); + ], + ]; return $created_access; } @@ -392,26 +392,26 @@ public function testNonExistingFieldAccess($viewer, $target, $view, $edit) { * Provides test data for testNonExistingFieldAccess(). */ public function NonExistingFieldAccessProvider() { - $created_access = array( - array( + $created_access = [ + [ 'viewer' => 'viewer', 'target' => 'viewer', 'view' => TRUE, 'edit' => TRUE, - ), - array( + ], + [ 'viewer' => 'owner', 'target' => 'viewer', 'view' => TRUE, 'edit' => TRUE, - ), - array( + ], + [ 'viewer' => 'admin', 'target' => 'owner', 'view' => TRUE, 'edit' => TRUE, - ), - ); + ], + ]; return $created_access; } diff --git a/core/modules/user/tests/src/Unit/UserAuthTest.php b/core/modules/user/tests/src/Unit/UserAuthTest.php index 1b96d8f8..698c8b5f 100644 --- a/core/modules/user/tests/src/Unit/UserAuthTest.php +++ b/core/modules/user/tests/src/Unit/UserAuthTest.php @@ -69,7 +69,7 @@ protected function setUp() { $this->testUser = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('id', 'setPassword', 'save', 'getPassword')) + ->setMethods(['id', 'setPassword', 'save', 'getPassword']) ->getMock(); $this->userAuth = new UserAuth($entity_manager, $this->passwordService); @@ -95,12 +95,12 @@ public function testAuthenticateWithMissingCredentials($username, $password) { * @return array */ public function providerTestAuthenticateWithMissingCredentials() { - return array( - array(NULL, NULL), - array(NULL, ''), - array('', NULL), - array('', ''), - ); + return [ + [NULL, NULL], + [NULL, ''], + ['', NULL], + ['', ''], + ]; } /** @@ -111,8 +111,8 @@ public function providerTestAuthenticateWithMissingCredentials() { public function testAuthenticateWithNoAccountReturned() { $this->userStorage->expects($this->once()) ->method('loadByProperties') - ->with(array('name' => $this->username)) - ->will($this->returnValue(array())); + ->with(['name' => $this->username]) + ->will($this->returnValue([])); $this->assertFalse($this->userAuth->authenticate($this->username, $this->password)); } @@ -125,8 +125,8 @@ public function testAuthenticateWithNoAccountReturned() { public function testAuthenticateWithIncorrectPassword() { $this->userStorage->expects($this->once()) ->method('loadByProperties') - ->with(array('name' => $this->username)) - ->will($this->returnValue(array($this->testUser))); + ->with(['name' => $this->username]) + ->will($this->returnValue([$this->testUser])); $this->passwordService->expects($this->once()) ->method('check') @@ -148,8 +148,8 @@ public function testAuthenticateWithCorrectPassword() { $this->userStorage->expects($this->once()) ->method('loadByProperties') - ->with(array('name' => $this->username)) - ->will($this->returnValue(array($this->testUser))); + ->with(['name' => $this->username]) + ->will($this->returnValue([$this->testUser])); $this->passwordService->expects($this->once()) ->method('check') @@ -175,8 +175,8 @@ public function testAuthenticateWithZeroPassword() { $this->userStorage->expects($this->once()) ->method('loadByProperties') - ->with(array('name' => $this->username)) - ->will($this->returnValue(array($this->testUser))); + ->with(['name' => $this->username]) + ->will($this->returnValue([$this->testUser])); $this->passwordService->expects($this->once()) ->method('check') @@ -203,8 +203,8 @@ public function testAuthenticateWithCorrectPasswordAndNewPasswordHash() { $this->userStorage->expects($this->once()) ->method('loadByProperties') - ->with(array('name' => $this->username)) - ->will($this->returnValue(array($this->testUser))); + ->with(['name' => $this->username]) + ->will($this->returnValue([$this->testUser])); $this->passwordService->expects($this->once()) ->method('check') diff --git a/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php b/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php new file mode 100644 index 00000000..142685c2 --- /dev/null +++ b/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php @@ -0,0 +1,151 @@ +logger = $this->prophesize(LoggerInterface::class)->reveal(); + + $this->userSettings = $this->prophesize(ImmutableConfig::class); + + $this->currentUser = $this->prophesize(AccountInterface::class); + + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + $this->reflection = new \ReflectionClass($this->testClass); + } + + /** + * Tests that an exception is thrown when no data provided for the account. + */ + public function testEmptyPost() { + $this->setExpectedException(BadRequestHttpException::class); + $this->testClass->post(NULL); + } + + /** + * Tests that only new user accounts can be registered. + */ + public function testExistedEntityPost() { + $entity = $this->prophesize(User::class); + $entity->isNew()->willReturn(FALSE); + $this->setExpectedException(BadRequestHttpException::class); + + $this->testClass->post($entity->reveal()); + } + + /** + * Tests that admin permissions are required to register a user account. + */ + public function testRegistrationAdminOnlyPost() { + + $this->userSettings->get('register')->willReturn(USER_REGISTER_ADMINISTRATORS_ONLY); + + $this->currentUser->isAnonymous()->willReturn(TRUE); + + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + + $entity = $this->prophesize(User::class); + $entity->isNew()->willReturn(TRUE); + + $this->setExpectedException(AccessDeniedHttpException::class); + + $this->testClass->post($entity->reveal()); + } + + /** + * Tests that only anonymous users can register users. + */ + public function testRegistrationAnonymousOnlyPost() { + $this->currentUser->isAnonymous()->willReturn(FALSE); + + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + + $entity = $this->prophesize(User::class); + $entity->isNew()->willReturn(TRUE); + + $this->setExpectedException(AccessDeniedHttpException::class); + + $this->testClass->post($entity->reveal()); + } + +} diff --git a/core/modules/user/tests/src/Unit/Views/Argument/RolesRidTest.php b/core/modules/user/tests/src/Unit/Views/Argument/RolesRidTest.php index 8693fc4b..b8f28884 100644 --- a/core/modules/user/tests/src/Unit/Views/Argument/RolesRidTest.php +++ b/core/modules/user/tests/src/Unit/Views/Argument/RolesRidTest.php @@ -19,24 +19,24 @@ class RolesRidTest extends UnitTestCase { * @covers ::titleQuery */ public function testTitleQuery() { - $role1 = new Role(array( + $role1 = new Role([ 'id' => 'test_rid_1', 'label' => 'test rid 1' - ), 'user_role'); - $role2 = new Role(array( + ], 'user_role'); + $role2 = new Role([ 'id' => 'test_rid_2', 'label' => 'test rid 2', - ), 'user_role'); + ], 'user_role'); // Creates a stub entity storage; $role_storage = $this->getMockForAbstractClass('Drupal\Core\Entity\EntityStorageInterface'); $role_storage->expects($this->any()) ->method('loadMultiple') - ->will($this->returnValueMap(array( - array(array(), array()), - array(array('test_rid_1'), array('test_rid_1' => $role1)), - array(array('test_rid_1', 'test_rid_2'), array('test_rid_1' => $role1, 'test_rid_2' => $role2)), - ))); + ->will($this->returnValueMap([ + [[], []], + [['test_rid_1'], ['test_rid_1' => $role1]], + [['test_rid_1', 'test_rid_2'], ['test_rid_1' => $role1, 'test_rid_2' => $role2]], + ])); $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); $entity_type->expects($this->any()) @@ -63,19 +63,19 @@ public function testTitleQuery() { $container->set('entity.manager', $entity_manager); \Drupal::setContainer($container); - $roles_rid_argument = new RolesRid(array(), 'user__roles_rid', array(), $entity_manager); + $roles_rid_argument = new RolesRid([], 'user__roles_rid', [], $entity_manager); - $roles_rid_argument->value = array(); + $roles_rid_argument->value = []; $titles = $roles_rid_argument->titleQuery(); - $this->assertEquals(array(), $titles); + $this->assertEquals([], $titles); - $roles_rid_argument->value = array('test_rid_1'); + $roles_rid_argument->value = ['test_rid_1']; $titles = $roles_rid_argument->titleQuery(); - $this->assertEquals(array('test rid 1'), $titles); + $this->assertEquals(['test rid 1'], $titles); - $roles_rid_argument->value = array('test_rid_1', 'test_rid_2'); + $roles_rid_argument->value = ['test_rid_1', 'test_rid_2']; $titles = $roles_rid_argument->titleQuery(); - $this->assertEquals(array('test rid 1', 'test rid 2'), $titles); + $this->assertEquals(['test rid 1', 'test rid 2'], $titles); } } diff --git a/core/modules/user/tests/themes/user_test_theme/user_test_theme.info.yml b/core/modules/user/tests/themes/user_test_theme/user_test_theme.info.yml index e4397b91..54ba2d98 100644 --- a/core/modules/user/tests/themes/user_test_theme/user_test_theme.info.yml +++ b/core/modules/user/tests/themes/user_test_theme/user_test_theme.info.yml @@ -4,8 +4,8 @@ description: 'Theme for testing the available fields in user twig template' # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php index 2f40eb90..364dd1ac 100644 --- a/core/modules/user/user.api.php +++ b/core/modules/user/user.api.php @@ -44,7 +44,7 @@ function hook_user_cancel($edit, $account, $method) { $nodes = \Drupal::entityQuery('node') ->condition('uid', $account->id()) ->execute(); - node_mass_update($nodes, array('status' => 0), NULL, TRUE); + node_mass_update($nodes, ['status' => 0], NULL, TRUE); break; case 'user_cancel_reassign': @@ -53,10 +53,10 @@ function hook_user_cancel($edit, $account, $method) { $nodes = \Drupal::entityQuery('node') ->condition('uid', $account->id()) ->execute(); - node_mass_update($nodes, array('uid' => 0), NULL, TRUE); + node_mass_update($nodes, ['uid' => 0], NULL, TRUE); // Anonymize old revisions. db_update('node_field_revision') - ->fields(array('uid' => 0)) + ->fields(['uid' => 0]) ->condition('uid', $account->id()) ->execute(); break; @@ -94,12 +94,12 @@ function hook_user_cancel_methods_alter(&$methods) { unset($methods['user_cancel_reassign']); // Add a custom zero-out method. - $methods['mymodule_zero_out'] = array( + $methods['mymodule_zero_out'] = [ 'title' => t('Delete the account and remove all content.'), 'description' => t('All your content will be replaced by empty strings.'), // access should be used for administrative methods only. 'access' => $account->hasPermission('access zero-out account cancellation method'), - ); + ]; } /** @@ -123,7 +123,7 @@ function hook_user_cancel_methods_alter(&$methods) { function hook_user_format_name_alter(&$name, $account) { // Display the user's uid instead of name. if ($account->id()) { - $name = t('User @uid', array('@uid' => $account->id())); + $name = t('User @uid', ['@uid' => $account->id()]); } } @@ -137,7 +137,7 @@ function hook_user_login($account) { $config = \Drupal::config('system.date'); // If the user has a NULL time zone, notify them to set a time zone. if (!$account->getTimezone() && $config->get('timezone.user.configurable') && $config->get('timezone.user.warn')) { - drupal_set_message(t('Configure your account time zone setting.', array(':user-edit' => $account->url('edit-form', array('query' => \Drupal::destination()->getAsArray(), 'fragment' => 'edit-timezone'))))); + drupal_set_message(t('Configure your account time zone setting.', [':user-edit' => $account->url('edit-form', ['query' => \Drupal::destination()->getAsArray(), 'fragment' => 'edit-timezone'])])); } } @@ -149,10 +149,10 @@ function hook_user_login($account) { */ function hook_user_logout($account) { db_insert('logouts') - ->fields(array( + ->fields([ 'uid' => $account->id(), 'time' => time(), - )) + ]) ->execute(); } diff --git a/core/modules/user/user.es6.js b/core/modules/user/user.es6.js new file mode 100644 index 00000000..74cab06f --- /dev/null +++ b/core/modules/user/user.es6.js @@ -0,0 +1,212 @@ +/** + * @file + * User behaviors. + */ + +(function ($, Drupal, drupalSettings) { + /** + * Attach handlers to evaluate the strength of any password fields and to + * check that its confirmation is correct. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches password strength indicator and other relevant validation to + * password fields. + */ + Drupal.behaviors.password = { + attach(context, settings) { + const $passwordInput = $(context).find('input.js-password-field').once('password'); + + if ($passwordInput.length) { + const translate = settings.password; + + const $passwordInputParent = $passwordInput.parent(); + const $passwordInputParentWrapper = $passwordInputParent.parent(); + let $passwordSuggestions; + + // Add identifying class to password element parent. + $passwordInputParent.addClass('password-parent'); + + // Add the password confirmation layer. + $passwordInputParentWrapper + .find('input.js-password-confirm') + .parent() + .append(`
          ${translate.confirmTitle}
          `) + .addClass('confirm-parent'); + + const $confirmInput = $passwordInputParentWrapper.find('input.js-password-confirm'); + const $confirmResult = $passwordInputParentWrapper.find('div.js-password-confirm'); + const $confirmChild = $confirmResult.find('span'); + + // If the password strength indicator is enabled, add its markup. + if (settings.password.showStrengthIndicator) { + const passwordMeter = `
          ${translate.strengthTitle}
          `; + $confirmInput.parent().after('
          '); + $passwordInputParent.append(passwordMeter); + $passwordSuggestions = $passwordInputParentWrapper.find('div.password-suggestions').hide(); + } + + // Check that password and confirmation inputs match. + const passwordCheckMatch = function (confirmInputVal) { + const success = $passwordInput.val() === confirmInputVal; + const confirmClass = success ? 'ok' : 'error'; + + // Fill in the success message and set the class accordingly. + $confirmChild.html(translate[`confirm${success ? 'Success' : 'Failure'}`]) + .removeClass('ok error').addClass(confirmClass); + }; + + // Check the password strength. + const passwordCheck = function () { + if (settings.password.showStrengthIndicator) { + // Evaluate the password strength. + const result = Drupal.evaluatePasswordStrength($passwordInput.val(), settings.password); + + // Update the suggestions for how to improve the password. + if ($passwordSuggestions.html() !== result.message) { + $passwordSuggestions.html(result.message); + } + + // Only show the description box if a weakness exists in the + // password. + $passwordSuggestions.toggle(result.strength !== 100); + + // Adjust the length of the strength indicator. + $passwordInputParent.find('.js-password-strength__indicator') + .css('width', `${result.strength}%`) + .removeClass('is-weak is-fair is-good is-strong') + .addClass(result.indicatorClass); + + // Update the strength indication text. + $passwordInputParent.find('.js-password-strength__text').html(result.indicatorText); + } + + // Check the value in the confirm input and show results. + if ($confirmInput.val()) { + passwordCheckMatch($confirmInput.val()); + $confirmResult.css({ visibility: 'visible' }); + } + else { + $confirmResult.css({ visibility: 'hidden' }); + } + }; + + // Monitor input events. + $passwordInput.on('input', passwordCheck); + $confirmInput.on('input', passwordCheck); + } + }, + }; + + /** + * Evaluate the strength of a user's password. + * + * Returns the estimated strength and the relevant output message. + * + * @param {string} password + * The password to evaluate. + * @param {object} translate + * An object containing the text to display for each strength level. + * + * @return {object} + * An object containing strength, message, indicatorText and indicatorClass. + */ + Drupal.evaluatePasswordStrength = function (password, translate) { + password = password.trim(); + let indicatorText; + let indicatorClass; + let weaknesses = 0; + let strength = 100; + let msg = []; + + const hasLowercase = /[a-z]/.test(password); + const hasUppercase = /[A-Z]/.test(password); + const hasNumbers = /[0-9]/.test(password); + const hasPunctuation = /[^a-zA-Z0-9]/.test(password); + + // If there is a username edit box on the page, compare password to that, + // otherwise use value from the database. + const $usernameBox = $('input.username'); + const username = ($usernameBox.length > 0) ? $usernameBox.val() : translate.username; + + // Lose 5 points for every character less than 12, plus a 30 point penalty. + if (password.length < 12) { + msg.push(translate.tooShort); + strength -= ((12 - password.length) * 5) + 30; + } + + // Count weaknesses. + if (!hasLowercase) { + msg.push(translate.addLowerCase); + weaknesses++; + } + if (!hasUppercase) { + msg.push(translate.addUpperCase); + weaknesses++; + } + if (!hasNumbers) { + msg.push(translate.addNumbers); + weaknesses++; + } + if (!hasPunctuation) { + msg.push(translate.addPunctuation); + weaknesses++; + } + + // Apply penalty for each weakness (balanced against length penalty). + switch (weaknesses) { + case 1: + strength -= 12.5; + break; + + case 2: + strength -= 25; + break; + + case 3: + strength -= 40; + break; + + case 4: + strength -= 40; + break; + } + + // Check if password is the same as the username. + if (password !== '' && password.toLowerCase() === username.toLowerCase()) { + msg.push(translate.sameAsUsername); + // Passwords the same as username are always very weak. + strength = 5; + } + + // Based on the strength, work out what text should be shown by the + // password strength meter. + if (strength < 60) { + indicatorText = translate.weak; + indicatorClass = 'is-weak'; + } + else if (strength < 70) { + indicatorText = translate.fair; + indicatorClass = 'is-fair'; + } + else if (strength < 80) { + indicatorText = translate.good; + indicatorClass = 'is-good'; + } + else if (strength <= 100) { + indicatorText = translate.strong; + indicatorClass = 'is-strong'; + } + + // Assemble the final message. + msg = `${translate.hasWeaknesses}
          • ${msg.join('
          • ')}
          `; + + return { + strength, + message: msg, + indicatorText, + indicatorClass, + }; + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/user/user.info.yml b/core/modules/user/user.info.yml index 95519a28..a7edd41b 100644 --- a/core/modules/user/user.info.yml +++ b/core/modules/user/user.info.yml @@ -9,8 +9,8 @@ configure: user.admin_index dependencies: - system -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/user/user.install b/core/modules/user/user.install index 7cc46ef6..0af797a4 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -9,53 +9,53 @@ * Implements hook_schema(). */ function user_schema() { - $schema['users_data'] = array( + $schema['users_data'] = [ 'description' => 'Stores module data as key/value pairs per user.', - 'fields' => array( - 'uid' => array( + 'fields' => [ + 'uid' => [ 'description' => 'Primary key: {users}.uid for user.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'module' => array( + ], + 'module' => [ 'description' => 'The name of the module declaring the variable.', 'type' => 'varchar_ascii', 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, 'not null' => TRUE, 'default' => '', - ), - 'name' => array( + ], + 'name' => [ 'description' => 'The identifier of the data.', 'type' => 'varchar_ascii', 'length' => 128, 'not null' => TRUE, 'default' => '', - ), - 'value' => array( + ], + 'value' => [ 'description' => 'The value.', 'type' => 'blob', 'not null' => FALSE, 'size' => 'big', - ), - 'serialized' => array( + ], + 'serialized' => [ 'description' => 'Whether value is serialized.', 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, - ), - ), - 'primary key' => array('uid', 'module', 'name'), - 'indexes' => array( - 'module' => array('module'), - 'name' => array('name'), - ), - 'foreign keys' => array( - 'uid' => array('users' => 'uid'), - ), - ); + ], + ], + 'primary key' => ['uid', 'module', 'name'], + 'indexes' => [ + 'module' => ['module'], + 'name' => ['name'], + ], + 'foreign keys' => [ + 'uid' => ['users' => 'uid'], + ], + ]; return $schema; } @@ -67,30 +67,25 @@ function user_install() { $storage = \Drupal::entityManager()->getStorage('user'); // Insert a row for the anonymous user. $storage - ->create(array( + ->create([ 'uid' => 0, 'status' => 0, 'name' => '', - )) + ]) ->save(); // We need some placeholders here as name and mail are unique. // This will be changed by the settings form in the installer. $storage - ->create(array( + ->create([ 'uid' => 1, 'name' => 'placeholder-for-uid-1', 'mail' => 'placeholder-for-uid-1', 'status' => TRUE, - )) + ]) ->save(); } -/** - * @addtogroup updates-8.1.0-beta - * @{ - */ - /** * Fix invalid token in the status_blocked email body. */ @@ -103,7 +98,3 @@ function user_update_8100() { $config->set('status_blocked', $mail)->save(TRUE); } } - -/** - * @} End of "addtogroup updates-8.1.0-beta". - */ diff --git a/core/modules/user/user.js b/core/modules/user/user.js index f4602c67..ec9735cf 100644 --- a/core/modules/user/user.js +++ b/core/modules/user/user.js @@ -1,24 +1,13 @@ /** - * @file - * User behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * Attach handlers to evaluate the strength of any password fields and to - * check that its confirmation is correct. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches password strength indicator and other relevant validation to - * password fields. - */ Drupal.behaviors.password = { - attach: function (context, settings) { + attach: function attach(context, settings) { var $passwordInput = $(context).find('input.js-password-field').once('password'); if ($passwordInput.length) { @@ -26,23 +15,16 @@ var $passwordInputParent = $passwordInput.parent(); var $passwordInputParentWrapper = $passwordInputParent.parent(); - var $passwordSuggestions; + var $passwordSuggestions = void 0; - // Add identifying class to password element parent. $passwordInputParent.addClass('password-parent'); - // Add the password confirmation layer. - $passwordInputParentWrapper - .find('input.js-password-confirm') - .parent() - .append('
          ' + translate.confirmTitle + '
          ') - .addClass('confirm-parent'); + $passwordInputParentWrapper.find('input.js-password-confirm').parent().append('
          ' + translate.confirmTitle + '
          ').addClass('confirm-parent'); var $confirmInput = $passwordInputParentWrapper.find('input.js-password-confirm'); var $confirmResult = $passwordInputParentWrapper.find('div.js-password-confirm'); var $confirmChild = $confirmResult.find('span'); - // If the password strength indicator is enabled, add its markup. if (settings.password.showStrengthIndicator) { var passwordMeter = '
          ' + translate.strengthTitle + '
          '; $confirmInput.parent().after('
          '); @@ -50,75 +32,46 @@ $passwordSuggestions = $passwordInputParentWrapper.find('div.password-suggestions').hide(); } - // Check that password and confirmation inputs match. - var passwordCheckMatch = function (confirmInputVal) { + var passwordCheckMatch = function passwordCheckMatch(confirmInputVal) { var success = $passwordInput.val() === confirmInputVal; var confirmClass = success ? 'ok' : 'error'; - // Fill in the success message and set the class accordingly. - $confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]) - .removeClass('ok error').addClass(confirmClass); + $confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]).removeClass('ok error').addClass(confirmClass); }; - // Check the password strength. - var passwordCheck = function () { + var passwordCheck = function passwordCheck() { if (settings.password.showStrengthIndicator) { - // Evaluate the password strength. var result = Drupal.evaluatePasswordStrength($passwordInput.val(), settings.password); - // Update the suggestions for how to improve the password. if ($passwordSuggestions.html() !== result.message) { $passwordSuggestions.html(result.message); } - // Only show the description box if a weakness exists in the - // password. $passwordSuggestions.toggle(result.strength !== 100); - // Adjust the length of the strength indicator. - $passwordInputParent.find('.js-password-strength__indicator') - .css('width', result.strength + '%') - .removeClass('is-weak is-fair is-good is-strong') - .addClass(result.indicatorClass); + $passwordInputParent.find('.js-password-strength__indicator').css('width', result.strength + '%').removeClass('is-weak is-fair is-good is-strong').addClass(result.indicatorClass); - // Update the strength indication text. $passwordInputParent.find('.js-password-strength__text').html(result.indicatorText); } - // Check the value in the confirm input and show results. if ($confirmInput.val()) { passwordCheckMatch($confirmInput.val()); - $confirmResult.css({visibility: 'visible'}); - } - else { - $confirmResult.css({visibility: 'hidden'}); + $confirmResult.css({ visibility: 'visible' }); + } else { + $confirmResult.css({ visibility: 'hidden' }); } }; - // Monitor input events. $passwordInput.on('input', passwordCheck); $confirmInput.on('input', passwordCheck); } } }; - /** - * Evaluate the strength of a user's password. - * - * Returns the estimated strength and the relevant output message. - * - * @param {string} password - * The password to evaluate. - * @param {object} translate - * An object containing the text to display for each strength level. - * - * @return {object} - * An object containing strength, message, indicatorText and indicatorClass. - */ Drupal.evaluatePasswordStrength = function (password, translate) { password = password.trim(); - var indicatorText; - var indicatorClass; + var indicatorText = void 0; + var indicatorClass = void 0; var weaknesses = 0; var strength = 100; var msg = []; @@ -128,18 +81,14 @@ var hasNumbers = /[0-9]/.test(password); var hasPunctuation = /[^a-zA-Z0-9]/.test(password); - // If there is a username edit box on the page, compare password to that, - // otherwise use value from the database. var $usernameBox = $('input.username'); - var username = ($usernameBox.length > 0) ? $usernameBox.val() : translate.username; + var username = $usernameBox.length > 0 ? $usernameBox.val() : translate.username; - // Lose 5 points for every character less than 12, plus a 30 point penalty. if (password.length < 12) { msg.push(translate.tooShort); - strength -= ((12 - password.length) * 5) + 30; + strength -= (12 - password.length) * 5 + 30; } - // Count weaknesses. if (!hasLowercase) { msg.push(translate.addLowerCase); weaknesses++; @@ -157,7 +106,6 @@ weaknesses++; } - // Apply penalty for each weakness (balanced against length penalty). switch (weaknesses) { case 1: strength -= 12.5; @@ -176,33 +124,26 @@ break; } - // Check if password is the same as the username. if (password !== '' && password.toLowerCase() === username.toLowerCase()) { msg.push(translate.sameAsUsername); - // Passwords the same as username are always very weak. + strength = 5; } - // Based on the strength, work out what text should be shown by the - // password strength meter. if (strength < 60) { indicatorText = translate.weak; indicatorClass = 'is-weak'; - } - else if (strength < 70) { + } else if (strength < 70) { indicatorText = translate.fair; indicatorClass = 'is-fair'; - } - else if (strength < 80) { + } else if (strength < 80) { indicatorText = translate.good; indicatorClass = 'is-good'; - } - else if (strength <= 100) { + } else if (strength <= 100) { indicatorText = translate.strong; indicatorClass = 'is-strong'; } - // Assemble the final message. msg = translate.hasWeaknesses + '
          • ' + msg.join('
          • ') + '
          '; return { @@ -211,7 +152,5 @@ indicatorText: indicatorText, indicatorClass: indicatorClass }; - }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 1e9f539e..2d7d24a0 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -28,22 +28,43 @@ use Drupal\user\UserInterface; * Maximum length of username text field. * * Keep this under 191 characters so we can use a unique constraint in MySQL. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\user\UserInterface::USERNAME_MAX_LENGTH instead. + * + * @see https://www.drupal.org/node/2831620 */ const USERNAME_MAX_LENGTH = 60; /** * Only administrators can create user accounts. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\user\UserInterface::REGISTER_ADMINISTRATORS_ONLY instead. + * + * @see https://www.drupal.org/node/2831620 */ const USER_REGISTER_ADMINISTRATORS_ONLY = 'admin_only'; /** * Visitors can create their own accounts. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\user\UserInterface::REGISTER_VISITORS instead. + * + * @see https://www.drupal.org/node/2831620 */ const USER_REGISTER_VISITORS = 'visitors'; /** * Visitors can create accounts, but they don't become active without * administrative approval. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + * Use \Drupal\user\UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL + * instead. + * + * @see https://www.drupal.org/node/2831620 */ const USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL = 'visitors_admin_approval'; @@ -55,19 +76,19 @@ function user_help($route_name, RouteMatchInterface $route_match) { case 'help.page.user': $output = ''; $output .= '

          ' . t('About') . '

          '; - $output .= '

          ' . t('The User module allows users to register, log in, and log out. It also allows users with proper permissions to manage user roles and permissions. For more information, see the online documentation for the User module.', array(':user_docs' => 'https://www.drupal.org/documentation/modules/user')) . '

          '; + $output .= '

          ' . t('The User module allows users to register, log in, and log out. It also allows users with proper permissions to manage user roles and permissions. For more information, see the online documentation for the User module.', [':user_docs' => 'https://www.drupal.org/documentation/modules/user']) . '

          '; $output .= '

          ' . t('Uses') . '

          '; $output .= '
          '; $output .= '
          ' . t('Creating and managing users') . '
          '; - $output .= '
          ' . t('Through the People administration page you can add and cancel user accounts and assign users to roles. By editing one particular user you can change their username, email address, password, and information in other fields.', array(':people' => \Drupal::url('entity.user.collection'))) . '
          '; + $output .= '
          ' . t('Through the People administration page you can add and cancel user accounts and assign users to roles. By editing one particular user you can change their username, email address, password, and information in other fields.', [':people' => \Drupal::url('entity.user.collection')]) . '
          '; $output .= '
          ' . t('Configuring user roles') . '
          '; - $output .= '
          ' . t('Roles are used to group and classify users; each user can be assigned one or more roles. Typically there are two pre-defined roles: Anonymous user (users that are not logged in), and Authenticated user (users that are registered and logged in). Depending on how your site was set up, an Administrator role may also be available: users with this role will automatically be assigned any new permissions whenever a module is enabled. You can create additional roles on the Roles administration page.', array(':roles' => \Drupal::url('entity.user_role.collection'))) . '
          '; + $output .= '
          ' . t('Roles are used to group and classify users; each user can be assigned one or more roles. Typically there are two pre-defined roles: Anonymous user (users that are not logged in), and Authenticated user (users that are registered and logged in). Depending on how your site was set up, an Administrator role may also be available: users with this role will automatically be assigned any new permissions whenever a module is enabled. You can create additional roles on the Roles administration page.', [':roles' => \Drupal::url('entity.user_role.collection')]) . '
          '; $output .= '
          ' . t('Setting permissions') . '
          '; - $output .= '
          ' . t('After creating roles, you can set permissions for each role on the Permissions page. Granting a permission allows users who have been assigned a particular role to perform an action on the site, such as viewing content, editing or creating a particular type of content, administering settings for a particular module, or using a particular function of the site (such as search).', array(':permissions_user' => \Drupal::url('user.admin_permissions'))) . '
          '; + $output .= '
          ' . t('After creating roles, you can set permissions for each role on the Permissions page. Granting a permission allows users who have been assigned a particular role to perform an action on the site, such as viewing content, editing or creating a particular type of content, administering settings for a particular module, or using a particular function of the site (such as search).', [':permissions_user' => \Drupal::url('user.admin_permissions')]) . '
          '; $output .= '
          ' . t('Managing account settings') . '
          '; - $output .= '
          ' . t('The Account settings page allows you to manage settings for the displayed name of the Anonymous user role, personal contact forms, user registration settings, and account cancellation settings. On this page you can also manage settings for account personalization, and adapt the text for the email messages that users receive when they register or request a password recovery. You may also set which role is automatically assigned new permissions whenever a module is enabled (the Administrator role).', array(':accounts' => \Drupal::url('entity.user.admin_form'))) . '
          '; + $output .= '
          ' . t('The Account settings page allows you to manage settings for the displayed name of the Anonymous user role, personal contact forms, user registration settings, and account cancellation settings. On this page you can also manage settings for account personalization, and adapt the text for the email messages that users receive when they register or request a password recovery. You may also set which role is automatically assigned new permissions whenever a module is enabled (the Administrator role).', [':accounts' => \Drupal::url('entity.user.admin_form')]) . '
          '; $output .= '
          ' . t('Managing user account fields') . '
          '; - $output .= '
          ' . t('Because User accounts are an entity type, you can extend them by adding fields through the Manage fields tab on the Account settings page. By adding fields for e.g., a picture, a biography, or address, you can a create a custom profile for the users of the website. For background information on entities and fields, see the Field module help page.', array(':field_help' => (\Drupal::moduleHandler()->moduleExists('field')) ? \Drupal::url('help.page', array('name' => 'field')) : '#', ':accounts' => \Drupal::url('entity.user.admin_form'))) . '
          '; + $output .= '
          ' . t('Because User accounts are an entity type, you can extend them by adding fields through the Manage fields tab on the Account settings page. By adding fields for e.g., a picture, a biography, or address, you can a create a custom profile for the users of the website. For background information on entities and fields, see the Field module help page.', [':field_help' => (\Drupal::moduleHandler()->moduleExists('field')) ? \Drupal::url('help.page', ['name' => 'field']) : '#', ':accounts' => \Drupal::url('entity.user.admin_form')]) . '
          '; $output .= '
          '; return $output; @@ -75,10 +96,10 @@ function user_help($route_name, RouteMatchInterface $route_match) { return '

          ' . t("This web page allows administrators to register new users. Users' email addresses and usernames must be unique.") . '

          '; case 'user.admin_permissions': - return '

          ' . t('Permissions let you control what users can do and see on your site. You can define a specific set of permissions for each role. (See the Roles page to create a role.) Any permissions granted to the Authenticated user role will be given to any user who is logged in to your site. From the Account settings page, you can make any role into an Administrator role for the site, meaning that role will be granted all new permissions automatically. You should be careful to ensure that only trusted users are given this access and level of control of your site.', array(':role' => \Drupal::url('entity.user_role.collection'), ':settings' => \Drupal::url('entity.user.admin_form'))) . '

          '; + return '

          ' . t('Permissions let you control what users can do and see on your site. You can define a specific set of permissions for each role. (See the Roles page to create a role.) Any permissions granted to the Authenticated user role will be given to any user who is logged in to your site. From the Account settings page, you can make any role into an Administrator role for the site, meaning that role will be granted all new permissions automatically. You should be careful to ensure that only trusted users are given this access and level of control of your site.', [':role' => \Drupal::url('entity.user_role.collection'), ':settings' => \Drupal::url('entity.user.admin_form')]) . '

          '; case 'entity.user_role.collection': - return '

          ' . t('A role defines a group of users that have certain privileges. These privileges are defined on the Permissions page. Here, you can define the names and the display sort order of the roles on your site. It is recommended to order roles from least permissive (for example, Anonymous user) to most permissive (for example, Administrator user). Users who are not logged in have the Anonymous user role. Users who are logged in have the Authenticated user role, plus any other roles granted to their user account.', array(':permissions' => \Drupal::url('user.admin_permissions'))) . '

          '; + return '

          ' . t('A role defines a group of users that have certain privileges. These privileges are defined on the Permissions page. Here, you can define the names and the display sort order of the roles on your site. It is recommended to order roles from least permissive (for example, Anonymous user) to most permissive (for example, Administrator user). Users who are not logged in have the Anonymous user role. Users who are logged in have the Authenticated user role, plus any other roles granted to their user account.', [':permissions' => \Drupal::url('user.admin_permissions')]) . '

          '; case 'entity.user.field_ui_fields': return '

          ' . t('This form lets administrators add and edit fields for storing user data.') . '

          '; @@ -95,14 +116,14 @@ function user_help($route_name, RouteMatchInterface $route_match) { * Implements hook_theme(). */ function user_theme() { - return array( - 'user' => array( + return [ + 'user' => [ 'render element' => 'elements', - ), - 'username' => array( - 'variables' => array('account' => NULL, 'attributes' => array(), 'link_options' => array()), - ), - ); + ], + 'username' => [ + 'variables' => ['account' => NULL, 'attributes' => [], 'link_options' => []], + ], + ]; } /** @@ -136,29 +157,29 @@ function user_picture_enabled() { * Implements hook_entity_extra_field_info(). */ function user_entity_extra_field_info() { - $fields['user']['user']['form']['account'] = array( + $fields['user']['user']['form']['account'] = [ 'label' => t('User name and password'), 'description' => t('User module account form elements.'), 'weight' => -10, - ); - $fields['user']['user']['form']['language'] = array( + ]; + $fields['user']['user']['form']['language'] = [ 'label' => t('Language settings'), 'description' => t('User module form element.'), 'weight' => 0, - ); + ]; if (\Drupal::config('system.date')->get('timezone.user.configurable')) { - $fields['user']['user']['form']['timezone'] = array( + $fields['user']['user']['form']['timezone'] = [ 'label' => t('Timezone'), 'description' => t('System module form element.'), 'weight' => 6, - ); + ]; } - $fields['user']['user']['display']['member_for'] = array( + $fields['user']['user']['display']['member_for'] = [ 'label' => t('Member for'), - 'description' => t('User module \'member for\' view element.'), + 'description' => t("User module 'member for' view element."), 'weight' => 5, - ); + ]; return $fields; } @@ -215,7 +236,7 @@ function user_load_multiple(array $uids = NULL, $reset = FALSE) { */ function user_load($uid, $reset = FALSE) { if ($reset) { - \Drupal::entityManager()->getStorage('user')->resetCache(array($uid)); + \Drupal::entityManager()->getStorage('user')->resetCache([$uid]); } return User::load($uid); } @@ -266,7 +287,7 @@ function user_load_by_name($name) { */ function user_validate_name($name) { $definition = BaseFieldDefinition::create('string') - ->addConstraint('UserName', array()); + ->addConstraint('UserName', []); $data = \Drupal::typedDataManager()->create($definition); $data->setValue($name); $violations = $data->validate(); @@ -321,9 +342,9 @@ function user_role_permissions(array $roles) { return _user_role_permissions_update($roles); } $entities = Role::loadMultiple($roles); - $role_permissions = array(); + $role_permissions = []; foreach ($roles as $rid) { - $role_permissions[$rid] = isset($entities[$rid]) ? $entities[$rid]->getPermissions() : array(); + $role_permissions[$rid] = isset($entities[$rid]) ? $entities[$rid]->getPermissions() : []; } return $role_permissions; } @@ -343,9 +364,9 @@ function user_role_permissions(array $roles) { * for the given role. */ function _user_role_permissions_update($roles) { - $role_permissions = array(); + $role_permissions = []; foreach ($roles as $rid) { - $role_permissions[$rid] = \Drupal::config("user.role.$rid")->get('permissions') ?: array(); + $role_permissions[$rid] = \Drupal::config("user.role.$rid")->get('permissions') ?: []; } return $role_permissions; } @@ -371,10 +392,10 @@ function user_is_blocked($name) { */ function user_user_view(array &$build, UserInterface $account, EntityViewDisplayInterface $display) { if ($display->getComponent('member_for')) { - $build['member_for'] = array( + $build['member_for'] = [ '#type' => 'item', '#markup' => '

          ' . t('Member for') . '

          ' . \Drupal::service('date.formatter')->formatTimeDiffSince($account->getCreatedTime()), - ); + ]; } } @@ -506,9 +527,9 @@ function template_preprocess_username(&$variables) { ->toString(); } else { - $variables['attributes']['href'] = Url::fromRoute('entity.user.canonical', array( + $variables['attributes']['href'] = Url::fromRoute('entity.user.canonical', [ 'user' => $variables['uid'], - ))->toString(); + ])->toString(); } } } @@ -529,7 +550,7 @@ function template_preprocess_username(&$variables) { */ function user_login_finalize(UserInterface $account) { \Drupal::currentUser()->setAccount($account); - \Drupal::logger('user')->notice('Session opened for %name.', array('%name' => $account->getUsername())); + \Drupal::logger('user')->notice('Session opened for %name.', ['%name' => $account->getUsername()]); // Update the user table timestamp noting user has logged in. // This is also used to invalidate one-time login links. $account->setLastLoginTime(REQUEST_TIME); @@ -543,7 +564,7 @@ function user_login_finalize(UserInterface $account) { // in place. \Drupal::service('session')->migrate(); \Drupal::service('session')->set('uid', $account->id()); - \Drupal::moduleHandler()->invokeAll('user_login', array($account)); + \Drupal::moduleHandler()->invokeAll('user_login', [$account]); } /** @@ -578,19 +599,19 @@ function user_user_logout($account) { * A unique URL that provides a one-time log in for the user, from which * they can change their password. */ -function user_pass_reset_url($account, $options = array()) { +function user_pass_reset_url($account, $options = []) { $timestamp = REQUEST_TIME; $langcode = isset($options['langcode']) ? $options['langcode'] : $account->getPreferredLangcode(); return \Drupal::url('user.reset', - array( + [ 'uid' => $account->id(), 'timestamp' => $timestamp, 'hash' => user_pass_rehash($account, $timestamp), - ), - array( + ], + [ 'absolute' => TRUE, 'language' => \Drupal::languageManager()->getLanguage($langcode) - ) + ] ); } @@ -611,10 +632,10 @@ function user_pass_reset_url($account, $options = array()) { * @see user_mail_tokens() * @see \Drupal\user\Controller\UserController::confirmCancel() */ -function user_cancel_url(UserInterface $account, $options = array()) { +function user_cancel_url(UserInterface $account, $options = []) { $timestamp = REQUEST_TIME; $langcode = isset($options['langcode']) ? $options['langcode'] : $account->getPreferredLangcode(); - $url_options = array('absolute' => TRUE, 'language' => \Drupal::languageManager()->getLanguage($langcode)); + $url_options = ['absolute' => TRUE, 'language' => \Drupal::languageManager()->getLanguage($langcode)]; return \Drupal::url('user.cancel_confirm', [ 'user' => $account->id(), 'timestamp' => $timestamp, @@ -670,16 +691,16 @@ function user_cancel($edit, $uid, $method) { $account = User::load($uid); if (!$account) { - drupal_set_message(t('The user account %id does not exist.', array('%id' => $uid)), 'error'); - \Drupal::logger('user')->error('Attempted to cancel non-existing user account: %id.', array('%id' => $uid)); + drupal_set_message(t('The user account %id does not exist.', ['%id' => $uid]), 'error'); + \Drupal::logger('user')->error('Attempted to cancel non-existing user account: %id.', ['%id' => $uid]); return; } // Initialize batch (to set title). - $batch = array( + $batch = [ 'title' => t('Cancelling account'), - 'operations' => array(), - ); + 'operations' => [], + ]; batch_set($batch); // When the 'user_cancel_delete' method is used, user_delete() is called, @@ -688,16 +709,16 @@ function user_cancel($edit, $uid, $method) { // account deletion. if ($method != 'user_cancel_delete') { // Allow modules to add further sets to this batch. - \Drupal::moduleHandler()->invokeAll('user_cancel', array($edit, $account, $method)); + \Drupal::moduleHandler()->invokeAll('user_cancel', [$edit, $account, $method]); } // Finish the batch and actually cancel the account. - $batch = array( + $batch = [ 'title' => t('Cancelling user account'), - 'operations' => array( - array('_user_cancel', array($edit, $account, $method)), - ), - ); + 'operations' => [ + ['_user_cancel', [$edit, $account, $method]], + ], + ]; // After cancelling account, ensure that user is logged out. if ($account->id() == \Drupal::currentUser()->id()) { @@ -741,8 +762,8 @@ function _user_cancel($edit, $account, $method) { } $account->block(); $account->save(); - drupal_set_message(t('%name has been disabled.', array('%name' => $account->getDisplayName()))); - $logger->notice('Blocked user: %name %email.', array('%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>')); + drupal_set_message(t('%name has been disabled.', ['%name' => $account->getDisplayName()])); + $logger->notice('Blocked user: %name %email.', ['%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>']); break; case 'user_cancel_reassign': @@ -752,8 +773,8 @@ function _user_cancel($edit, $account, $method) { _user_mail_notify('status_canceled', $account); } $account->delete(); - drupal_set_message(t('%name has been deleted.', array('%name' => $account->getDisplayName()))); - $logger->notice('Deleted user: %name %email.', array('%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>')); + drupal_set_message(t('%name has been deleted.', ['%name' => $account->getDisplayName()])); + $logger->notice('Deleted user: %name %email.', ['%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>']); break; } @@ -793,33 +814,33 @@ function _user_cancel_session_regenerate() { function user_cancel_methods() { $user_settings = \Drupal::config('user.settings'); $anonymous_name = $user_settings->get('anonymous'); - $methods = array( - 'user_cancel_block' => array( + $methods = [ + 'user_cancel_block' => [ 'title' => t('Disable the account and keep its content.'), 'description' => t('Your account will be blocked and you will no longer be able to log in. All of your content will remain attributed to your username.'), - ), - 'user_cancel_block_unpublish' => array( + ], + 'user_cancel_block_unpublish' => [ 'title' => t('Disable the account and unpublish its content.'), 'description' => t('Your account will be blocked and you will no longer be able to log in. All of your content will be hidden from everyone but administrators.'), - ), - 'user_cancel_reassign' => array( - 'title' => t('Delete the account and make its content belong to the %anonymous-name user.', array('%anonymous-name' => $anonymous_name)), - 'description' => t('Your account will be removed and all account information deleted. All of your content will be assigned to the %anonymous-name user.', array('%anonymous-name' => $anonymous_name)), - ), - 'user_cancel_delete' => array( + ], + 'user_cancel_reassign' => [ + 'title' => t('Delete the account and make its content belong to the %anonymous-name user.', ['%anonymous-name' => $anonymous_name]), + 'description' => t('Your account will be removed and all account information deleted. All of your content will be assigned to the %anonymous-name user.', ['%anonymous-name' => $anonymous_name]), + ], + 'user_cancel_delete' => [ 'title' => t('Delete the account and its content.'), 'description' => t('Your account will be removed and all account information deleted. All of your content will also be deleted.'), 'access' => \Drupal::currentUser()->hasPermission('administer users'), - ), - ); + ], + ]; // Allow modules to customize account cancellation methods. \Drupal::moduleHandler()->alter('user_cancel_methods', $methods); // Turn all methods into real form elements. - $form = array( - '#options' => array(), + $form = [ + '#options' => [], '#default_value' => $user_settings->get('cancel_method'), - ); + ]; foreach ($methods as $name => $method) { $form['#options'][$name] = $method['title']; // Add the description for the confirmation form. This description is never @@ -842,7 +863,7 @@ function user_cancel_methods() { * A user ID. */ function user_delete($uid) { - user_delete_multiple(array($uid)); + user_delete_multiple([$uid]); } /** @@ -911,9 +932,9 @@ function user_mail($key, &$message, $params) { $token_service = \Drupal::token(); $language_manager = \Drupal::languageManager(); $langcode = $message['langcode']; - $variables = array('user' => $params['account']); + $variables = ['user' => $params['account']]; - $language = \Drupal::languageManager()->getLanguage($params['account']->getPreferredLangcode()); + $language = $language_manager->getLanguage($params['account']->getPreferredLangcode()); $original_language = $language_manager->getConfigOverrideLanguage(); $language_manager->setConfigOverrideLanguage($language); $mail_config = \Drupal::config('user.mail'); @@ -981,34 +1002,34 @@ function user_role_names($membersonly = FALSE, $permission = NULL) { */ function user_user_role_insert(RoleInterface $role) { // Ignore the authenticated and anonymous roles or the role is being synced. - if (in_array($role->id(), array(RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID)) || $role->isSyncing()) { + if (in_array($role->id(), [RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID]) || $role->isSyncing()) { return; } $add_id = 'user_add_role_action.' . $role->id(); if (!Action::load($add_id)) { - $action = Action::create(array( + $action = Action::create([ 'id' => $add_id, 'type' => 'user', - 'label' => t('Add the @label role to the selected users', array('@label' => $role->label())), - 'configuration' => array( + 'label' => t('Add the @label role to the selected user(s)', ['@label' => $role->label()]), + 'configuration' => [ 'rid' => $role->id(), - ), + ], 'plugin' => 'user_add_role_action', - )); + ]); $action->trustData()->save(); } $remove_id = 'user_remove_role_action.' . $role->id(); if (!Action::load($remove_id)) { - $action = Action::create(array( + $action = Action::create([ 'id' => $remove_id, 'type' => 'user', - 'label' => t('Remove the @label role from the selected users', array('@label' => $role->label())), - 'configuration' => array( + 'label' => t('Remove the @label role from the selected user(s)', ['@label' => $role->label()]), + 'configuration' => [ 'rid' => $role->id(), - ), + ], 'plugin' => 'user_remove_role_action', - )); + ]); $action->trustData()->save(); } } @@ -1019,10 +1040,10 @@ function user_user_role_insert(RoleInterface $role) { function user_user_role_delete(RoleInterface $role) { // Delete role references for all users. $user_storage = \Drupal::entityManager()->getStorage('user'); - $user_storage->deleteRoleReferences(array($role->id())); + $user_storage->deleteRoleReferences([$role->id()]); // Ignore the authenticated and anonymous roles or the role is being synced. - if (in_array($role->id(), array(RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID)) || $role->isSyncing()) { + if (in_array($role->id(), [RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID]) || $role->isSyncing()) { return; } @@ -1112,7 +1133,7 @@ function user_role_load($rid) { * @see user_role_grant_permissions() * @see user_role_revoke_permissions() */ -function user_role_change_permissions($rid, array $permissions = array()) { +function user_role_change_permissions($rid, array $permissions = []) { // Grant new permissions for the role. $grant = array_filter($permissions); if (!empty($grant)) { @@ -1136,7 +1157,7 @@ function user_role_change_permissions($rid, array $permissions = array()) { * @see user_role_change_permissions() * @see user_role_revoke_permissions() */ -function user_role_grant_permissions($rid, array $permissions = array()) { +function user_role_grant_permissions($rid, array $permissions = []) { // Grant new permissions for the role. if ($role = Role::load($rid)) { foreach ($permissions as $permission) { @@ -1157,7 +1178,7 @@ function user_role_grant_permissions($rid, array $permissions = array()) { * @see user_role_change_permissions() * @see user_role_grant_permissions() */ -function user_role_revoke_permissions($rid, array $permissions = array()) { +function user_role_revoke_permissions($rid, array $permissions = []) { // Revoke permissions for the role. $role = Role::load($rid); foreach ($permissions as $permission) { @@ -1238,16 +1259,16 @@ function user_element_info_alter(array &$types) { * validation. */ function user_form_process_password_confirm($element) { - $password_settings = array( + $password_settings = [ 'confirmTitle' => t('Passwords match:'), 'confirmSuccess' => t('yes'), 'confirmFailure' => t('no'), 'showStrengthIndicator' => FALSE, - ); + ]; if (\Drupal::config('user.settings')->get('password_strength')) { $password_settings['showStrengthIndicator'] = TRUE; - $password_settings += array( + $password_settings += [ 'strengthTitle' => t('Password strength:'), 'hasWeaknesses' => t('Recommendations to make your password stronger:'), 'tooShort' => t('Make it at least 12 characters'), @@ -1261,7 +1282,7 @@ function user_form_process_password_confirm($element) { 'good' => t('Good'), 'strong' => t('Strong'), 'username' => \Drupal::currentUser()->getUsername(), - ); + ]; } $element['#attached']['library'][] = 'user/drupal.user'; @@ -1310,77 +1331,77 @@ function user_toolbar() { // Add logout & user account links or login link. $links_cache_contexts = []; if ($user->isAuthenticated()) { - $links = array( - 'account' => array( + $links = [ + 'account' => [ 'title' => t('View profile'), 'url' => Url::fromRoute('user.page'), - 'attributes' => array( + 'attributes' => [ 'title' => t('User account'), - ), - ), - 'account_edit' => array( + ], + ], + 'account_edit' => [ 'title' => t('Edit profile'), 'url' => Url::fromRoute('entity.user.edit_form', ['user' => $user->id()]), - 'attributes' => array( + 'attributes' => [ 'title' => t('Edit user account'), - ), - ), - 'logout' => array( + ], + ], + 'logout' => [ 'title' => t('Log out'), 'url' => Url::fromRoute('user.logout'), - ), - ); + ], + ]; // The "Edit user account" link is per-user. $links_cache_contexts[] = 'user'; } else { - $links = array( - 'login' => array( + $links = [ + 'login' => [ 'title' => t('Log in'), 'url' => Url::fromRoute('user.page'), - ), - ); + ], + ]; } - $items['user'] = array( + $items['user'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => $user->getDisplayName(), '#url' => Url::fromRoute('user.page'), - '#attributes' => array( + '#attributes' => [ 'title' => t('My account'), - 'class' => array('toolbar-icon', 'toolbar-icon-user'), - ), + 'class' => ['toolbar-icon', 'toolbar-icon-user'], + ], '#cache' => [ 'contexts' => [ // Cacheable per user, because the current user's name is shown. 'user', ], ], - ), - 'tray' => array( + ], + 'tray' => [ '#heading' => t('User account actions'), - 'user_links' => array( + 'user_links' => [ '#cache' => [ // Cacheable per "authenticated or not", because the links to // display depend on that. - 'contexts' => Cache::mergeContexts(array('user.roles:authenticated'), $links_cache_contexts), + 'contexts' => Cache::mergeContexts(['user.roles:authenticated'], $links_cache_contexts), ], '#theme' => 'links__toolbar_user', '#links' => $links, - '#attributes' => array( - 'class' => array('toolbar-menu'), - ), - ), - ), + '#attributes' => [ + 'class' => ['toolbar-menu'], + ], + ], + ], '#weight' => 100, - '#attached' => array( - 'library' => array( + '#attached' => [ + 'library' => [ 'user/drupal.user.icons', - ), - ), - ); + ], + ], + ]; return $items; } @@ -1391,9 +1412,9 @@ function user_toolbar() { function user_logout() { $user = \Drupal::currentUser(); - \Drupal::logger('user')->notice('Session closed for %name.', array('%name' => $user->getAccountName())); + \Drupal::logger('user')->notice('Session closed for %name.', ['%name' => $user->getAccountName()]); - \Drupal::moduleHandler()->invokeAll('user_logout', array($user)); + \Drupal::moduleHandler()->invokeAll('user_logout', [$user]); // Destroy the current session, and reset $user to the anonymous user. // Note: In Symfony the session is intended to be destroyed with diff --git a/core/modules/user/user.permissions.es6.js b/core/modules/user/user.permissions.es6.js new file mode 100644 index 00000000..7aa79bbf --- /dev/null +++ b/core/modules/user/user.permissions.es6.js @@ -0,0 +1,84 @@ +/** + * @file + * User permission page behaviors. + */ + +(function ($, Drupal) { + /** + * Shows checked and disabled checkboxes for inherited permissions. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches functionality to the permissions table. + */ + Drupal.behaviors.permissions = { + attach(context) { + const self = this; + $('table#permissions').once('permissions').each(function () { + // On a site with many roles and permissions, this behavior initially + // has to perform thousands of DOM manipulations to inject checkboxes + // and hide them. By detaching the table from the DOM, all operations + // can be performed without triggering internal layout and re-rendering + // processes in the browser. + const $table = $(this); + let $ancestor; + let method; + if ($table.prev().length) { + $ancestor = $table.prev(); + method = 'after'; + } + else { + $ancestor = $table.parent(); + method = 'append'; + } + $table.detach(); + + // Create dummy checkboxes. We use dummy checkboxes instead of reusing + // the existing checkboxes here because new checkboxes don't alter the + // submitted form. If we'd automatically check existing checkboxes, the + // permission table would be polluted with redundant entries. This + // is deliberate, but desirable when we automatically check them. + const $dummy = $('') + .attr('title', Drupal.t('This permission is inherited from the authenticated user role.')) + .hide(); + + $table + .find('input[type="checkbox"]') + .not('.js-rid-anonymous, .js-rid-authenticated') + .addClass('real-checkbox js-real-checkbox') + .after($dummy); + + // Initialize the authenticated user checkbox. + $table.find('input[type=checkbox].js-rid-authenticated') + .on('click.permissions', self.toggle) + // .triggerHandler() cannot be used here, as it only affects the first + // element. + .each(self.toggle); + + // Re-insert the table into the DOM. + $ancestor[method]($table); + }); + }, + + /** + * Toggles all dummy checkboxes based on the checkboxes' state. + * + * If the "authenticated user" checkbox is checked, the checked and disabled + * checkboxes are shown, the real checkboxes otherwise. + */ + toggle() { + const authCheckbox = this; + const $row = $(this).closest('tr'); + // jQuery performs too many layout calculations for .hide() and .show(), + // leading to a major page rendering lag on sites with many roles and + // permissions. Therefore, we toggle visibility directly. + $row.find('.js-real-checkbox').each(function () { + this.style.display = (authCheckbox.checked ? 'none' : ''); + }); + $row.find('.js-dummy-checkbox').each(function () { + this.style.display = (authCheckbox.checked ? '' : 'none'); + }); + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/user/user.permissions.js b/core/modules/user/user.permissions.js index c3dc24f1..f0e6a2ac 100644 --- a/core/modules/user/user.permissions.js +++ b/core/modules/user/user.permissions.js @@ -1,88 +1,46 @@ /** - * @file - * User permission page behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Shows checked and disabled checkboxes for inherited permissions. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches functionality to the permissions table. - */ Drupal.behaviors.permissions = { - attach: function (context) { + attach: function attach(context) { var self = this; $('table#permissions').once('permissions').each(function () { - // On a site with many roles and permissions, this behavior initially - // has to perform thousands of DOM manipulations to inject checkboxes - // and hide them. By detaching the table from the DOM, all operations - // can be performed without triggering internal layout and re-rendering - // processes in the browser. var $table = $(this); - var $ancestor; - var method; + var $ancestor = void 0; + var method = void 0; if ($table.prev().length) { $ancestor = $table.prev(); method = 'after'; - } - else { + } else { $ancestor = $table.parent(); method = 'append'; } $table.detach(); - // Create dummy checkboxes. We use dummy checkboxes instead of reusing - // the existing checkboxes here because new checkboxes don't alter the - // submitted form. If we'd automatically check existing checkboxes, the - // permission table would be polluted with redundant entries. This - // is deliberate, but desirable when we automatically check them. - var $dummy = $('') - .attr('title', Drupal.t('This permission is inherited from the authenticated user role.')) - .hide(); + var $dummy = $('').attr('title', Drupal.t('This permission is inherited from the authenticated user role.')).hide(); - $table - .find('input[type="checkbox"]') - .not('.js-rid-anonymous, .js-rid-authenticated') - .addClass('real-checkbox js-real-checkbox') - .after($dummy); + $table.find('input[type="checkbox"]').not('.js-rid-anonymous, .js-rid-authenticated').addClass('real-checkbox js-real-checkbox').after($dummy); - // Initialize the authenticated user checkbox. - $table.find('input[type=checkbox].js-rid-authenticated') - .on('click.permissions', self.toggle) - // .triggerHandler() cannot be used here, as it only affects the first - // element. - .each(self.toggle); + $table.find('input[type=checkbox].js-rid-authenticated').on('click.permissions', self.toggle).each(self.toggle); - // Re-insert the table into the DOM. $ancestor[method]($table); }); }, - - /** - * Toggles all dummy checkboxes based on the checkboxes' state. - * - * If the "authenticated user" checkbox is checked, the checked and disabled - * checkboxes are shown, the real checkboxes otherwise. - */ - toggle: function () { + toggle: function toggle() { var authCheckbox = this; var $row = $(this).closest('tr'); - // jQuery performs too many layout calculations for .hide() and .show(), - // leading to a major page rendering lag on sites with many roles and - // permissions. Therefore, we toggle visibility directly. + $row.find('.js-real-checkbox').each(function () { - this.style.display = (authCheckbox.checked ? 'none' : ''); + this.style.display = authCheckbox.checked ? 'none' : ''; }); $row.find('.js-dummy-checkbox').each(function () { - this.style.display = (authCheckbox.checked ? '' : 'none'); + this.style.display = authCheckbox.checked ? '' : 'none'; }); } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/user/user.post_update.php b/core/modules/user/user.post_update.php new file mode 100644 index 00000000..3f19b0c1 --- /dev/null +++ b/core/modules/user/user.post_update.php @@ -0,0 +1,22 @@ +getPermissions(); + sort($permissions); + if ($permissions !== $role->getPermissions()) { + $role->save(); + } + }; + array_map($entity_save, Role::loadMultiple()); +} diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index 319f219e..e38bb7ac 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -111,6 +111,15 @@ user.pass: options: _maintenance_access: TRUE +user.pass.http: + path: '/user/password' + defaults: + _controller: \Drupal\user\Controller\UserAuthenticationController::resetPassword + methods: [POST] + requirements: + _access: 'TRUE' + _format: 'json' + user.page: path: '/user' defaults: diff --git a/core/modules/user/user.tokens.inc b/core/modules/user/user.tokens.inc index 7f456f66..8c02f6e6 100644 --- a/core/modules/user/user.tokens.inc +++ b/core/modules/user/user.tokens.inc @@ -13,61 +13,61 @@ use Drupal\user\Entity\User; * Implements hook_token_info(). */ function user_token_info() { - $types['user'] = array( + $types['user'] = [ 'name' => t('Users'), 'description' => t('Tokens related to individual user accounts.'), 'needs-data' => 'user', - ); - $types['current-user'] = array( + ]; + $types['current-user'] = [ 'name' => t('Current user'), 'description' => t('Tokens related to the currently logged in user.'), 'type' => 'user', - ); + ]; - $user['uid'] = array( + $user['uid'] = [ 'name' => t('User ID'), 'description' => t("The unique ID of the user account."), - ); - $user['name'] = array( + ]; + $user['name'] = [ 'name' => t("Deprecated: User Name"), 'description' => t("Deprecated: Use account-name or display-name instead."), - ); - $user['account-name'] = array( + ]; + $user['account-name'] = [ 'name' => t("Account Name"), 'description' => t("The login name of the user account."), - ); - $user['display-name'] = array( + ]; + $user['display-name'] = [ 'name' => t("Display Name"), 'description' => t("The display name of the user account."), - ); - $user['mail'] = array( + ]; + $user['mail'] = [ 'name' => t("Email"), 'description' => t("The email address of the user account."), - ); - $user['url'] = array( + ]; + $user['url'] = [ 'name' => t("URL"), 'description' => t("The URL of the account profile page."), - ); - $user['edit-url'] = array( + ]; + $user['edit-url'] = [ 'name' => t("Edit URL"), 'description' => t("The URL of the account edit page."), - ); + ]; - $user['last-login'] = array( + $user['last-login'] = [ 'name' => t("Last login"), 'description' => t("The date the user last logged in to the site."), 'type' => 'date', - ); - $user['created'] = array( + ]; + $user['created'] = [ 'name' => t("Created"), 'description' => t("The date the user account was created."), 'type' => 'date', - ); + ]; - return array( + return [ 'types' => $types, - 'tokens' => array('user' => $user), - ); + 'tokens' => ['user' => $user], + ]; } /** @@ -76,7 +76,7 @@ function user_token_info() { function user_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { $token_service = \Drupal::token(); - $url_options = array('absolute' => TRUE); + $url_options = ['absolute' => TRUE]; if (isset($options['langcode'])) { $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']); $langcode = $options['langcode']; @@ -84,7 +84,7 @@ function user_tokens($type, $tokens, array $data, array $options, BubbleableMeta else { $langcode = NULL; } - $replacements = array(); + $replacements = []; if ($type == 'user' && !empty($data['user'])) { /** @var \Drupal\user\UserInterface $account */ @@ -142,18 +142,18 @@ function user_tokens($type, $tokens, array $data, array $options, BubbleableMeta } if ($login_tokens = $token_service->findWithPrefix($tokens, 'last-login')) { - $replacements += $token_service->generate('date', $login_tokens, array('date' => $account->getLastLoginTime()), $options, $bubbleable_metadata); + $replacements += $token_service->generate('date', $login_tokens, ['date' => $account->getLastLoginTime()], $options, $bubbleable_metadata); } if ($registered_tokens = $token_service->findWithPrefix($tokens, 'created')) { - $replacements += $token_service->generate('date', $registered_tokens, array('date' => $account->getCreatedTime()), $options, $bubbleable_metadata); + $replacements += $token_service->generate('date', $registered_tokens, ['date' => $account->getCreatedTime()], $options, $bubbleable_metadata); } } if ($type == 'current-user') { $account = User::load(\Drupal::currentUser()->id()); $bubbleable_metadata->addCacheContexts(['user']); - $replacements += $token_service->generate('user', $tokens, array('user' => $account), $options, $bubbleable_metadata); + $replacements += $token_service->generate('user', $tokens, ['user' => $account], $options, $bubbleable_metadata); } return $replacements; diff --git a/core/modules/user/user.views_execution.inc b/core/modules/user/user.views_execution.inc index c9a3f1db..255fbf26 100644 --- a/core/modules/user/user.views_execution.inc +++ b/core/modules/user/user.views_execution.inc @@ -13,5 +13,5 @@ use Drupal\views\ViewExecutable; * Allow replacement of current userid so we can cache these queries. */ function user_views_query_substitutions(ViewExecutable $view) { - return array('***CURRENT_USER***' => \Drupal::currentUser()->id()); + return ['***CURRENT_USER***' => \Drupal::currentUser()->id()]; } diff --git a/core/modules/views/config/schema/views.data_types.schema.yml b/core/modules/views/config/schema/views.data_types.schema.yml index 0683380c..a3d1b343 100644 --- a/core/modules/views/config/schema/views.data_types.schema.yml +++ b/core/modules/views/config/schema/views.data_types.schema.yml @@ -777,7 +777,7 @@ views_filter_group_item: type: string label: 'Operator' value: - type: label + type: views.filter_value.[%parent.%parent.%parent.%parent.plugin_id] label: 'Value' views_relationship: diff --git a/core/modules/views/config/schema/views.display.schema.yml b/core/modules/views/config/schema/views.display.schema.yml index d17c48cf..3e696143 100644 --- a/core/modules/views/config/schema/views.display.schema.yml +++ b/core/modules/views/config/schema/views.display.schema.yml @@ -49,9 +49,6 @@ views.display.page: context: type: string label: 'Context' - expanded: - type: boolean - label: 'Expanded' tab_options: type: mapping label: 'Tab options' diff --git a/core/modules/views/config/schema/views.entity_reference.schema.yml b/core/modules/views/config/schema/views.entity_reference.schema.yml index 027c62fa..f13645ab 100644 --- a/core/modules/views/config/schema/views.entity_reference.schema.yml +++ b/core/modules/views/config/schema/views.entity_reference.schema.yml @@ -1,8 +1,8 @@ -# Schema for the views entity reference selection plugins. +# Schema for the entity reference 'views' selection handler settings. entity_reference_selection.views: - type: mapping - label: 'View handler settings' + type: entity_reference_selection + label: 'Views selection handler settings' mapping: view: type: mapping diff --git a/core/modules/views/config/schema/views.filter.schema.yml b/core/modules/views/config/schema/views.filter.schema.yml index e411489b..18c13b68 100644 --- a/core/modules/views/config/schema/views.filter.schema.yml +++ b/core/modules/views/config/schema/views.filter.schema.yml @@ -31,14 +31,6 @@ views.filter.combine: type: string label: 'Field' -views.filter_value.date: - type: views.filter_value.numeric - label: 'Date' - mapping: - type: - type: string - label: 'Type' - views.filter_value.groupby_numeric: type: views.filter_value.numeric label: 'Group by numeric' @@ -63,6 +55,12 @@ views.filter.in_operator: reduce: type: boolean label: 'Reduce' + group_info: + mapping: + group_items: + sequence: + type: views.filter.group_item.in_operator + label: 'Group item' views.filter.string: type: views_filter @@ -93,8 +91,12 @@ views.filter_value.numeric: type: string label: 'Value' +views.filter_value.*: + type: string + label: 'Filter value' + views.filter_value.equality: - type: views.filter_value.numeric + type: string label: 'Equality' views.filter.many_to_one: @@ -109,18 +111,26 @@ views.filter.standard: type: views_filter label: 'Standard' +# Schema for the views group items. views.filter.group_item.*: type: views_filter_group_item - label: 'Default' + label: 'Group item' -views.filter.group_item.numeric: +views.filter.group_item.boolean: type: views_filter_group_item - label: 'Group items' mapping: value: - type: views.filter_value.numeric + type: views.filter_value.string + +views.filter.group_item.in_operator: + type: views_filter_group_item + mapping: + value: + type: views.filter_value.in_operator # Schema for the views filter value. +views.filter_value.string: + type: string views.filter_value.boolean: type: string @@ -131,3 +141,30 @@ views.filter_value.combine: views.filter.language: type: views.filter.in_operator label: 'Language' + +views.filter.latest_revision: + type: views_filter + label: 'Latest revision' + +views.filter_value.date: + type: views.filter_value.numeric + label: 'Date' + mapping: + type: + type: string + label: 'Type' + +views.filter_value.datetime: + type: views.filter_value.numeric + label: 'Date' + mapping: + type: + type: string + label: 'Type' + +views.filter_value.in_operator: + type: sequence + label: 'Values' + sequence: + type: string + label: 'Value' diff --git a/core/modules/views/js/ajax_view.es6.js b/core/modules/views/js/ajax_view.es6.js new file mode 100644 index 00000000..df2c4da6 --- /dev/null +++ b/core/modules/views/js/ajax_view.es6.js @@ -0,0 +1,201 @@ +/** + * @file + * Handles AJAX fetching of views, including filter submission and response. + */ + +(function ($, Drupal, drupalSettings) { + /** + * Attaches the AJAX behavior to exposed filters forms and key View links. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches ajaxView functionality to relevant elements. + */ + Drupal.behaviors.ViewsAjaxView = {}; + Drupal.behaviors.ViewsAjaxView.attach = function () { + if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) { + const ajaxViews = drupalSettings.views.ajaxViews; + for (const i in ajaxViews) { + if (ajaxViews.hasOwnProperty(i)) { + Drupal.views.instances[i] = new Drupal.views.ajaxView(ajaxViews[i]); + } + } + } + }; + + /** + * @namespace + */ + Drupal.views = {}; + + /** + * @type {object.} + */ + Drupal.views.instances = {}; + + /** + * Javascript object for a certain view. + * + * @constructor + * + * @param {object} settings + * Settings object for the ajax view. + * @param {string} settings.view_dom_id + * The DOM id of the view. + */ + Drupal.views.ajaxView = function (settings) { + const selector = `.js-view-dom-id-${settings.view_dom_id}`; + this.$view = $(selector); + + // Retrieve the path to use for views' ajax. + let ajax_path = drupalSettings.views.ajax_path; + + // If there are multiple views this might've ended up showing up multiple + // times. + if (ajax_path.constructor.toString().indexOf('Array') !== -1) { + ajax_path = ajax_path[0]; + } + + // Check if there are any GET parameters to send to views. + let queryString = window.location.search || ''; + if (queryString !== '') { + // Remove the question mark and Drupal path component if any. + queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, ''); + if (queryString !== '') { + // If there is a '?' in ajax_path, clean url are on and & should be + // used to add parameters. + queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString; + } + } + + this.element_settings = { + url: ajax_path + queryString, + submit: settings, + setClick: true, + event: 'click', + selector, + progress: { type: 'fullscreen' }, + }; + + this.settings = settings; + + // Add the ajax to exposed forms. + this.$exposed_form = $(`form#views-exposed-form-${settings.view_name.replace(/_/g, '-')}-${settings.view_display_id.replace(/_/g, '-')}`); + this.$exposed_form.once('exposed-form').each($.proxy(this.attachExposedFormAjax, this)); + + // Add the ajax to pagers. + this.$view + // Don't attach to nested views. Doing so would attach multiple behaviors + // to a given element. + .filter($.proxy(this.filterNestedViews, this)) + .once('ajax-pager').each($.proxy(this.attachPagerAjax, this)); + + // Add a trigger to update this view specifically. In order to trigger a + // refresh use the following code. + // + // @code + // $('.view-name').trigger('RefreshView'); + // @endcode + const self_settings = $.extend({}, this.element_settings, { + event: 'RefreshView', + base: this.selector, + element: this.$view.get(0), + }); + this.refreshViewAjax = Drupal.ajax(self_settings); + }; + + /** + * @method + */ + Drupal.views.ajaxView.prototype.attachExposedFormAjax = function () { + const that = this; + this.exposedFormAjax = []; + // Exclude the reset buttons so no AJAX behaviours are bound. Many things + // break during the form reset phase if using AJAX. + $('input[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) { + const self_settings = $.extend({}, that.element_settings, { + base: $(this).attr('id'), + element: this, + }); + that.exposedFormAjax[index] = Drupal.ajax(self_settings); + }); + }; + + /** + * @return {bool} + * If there is at least one parent with a view class return false. + */ + Drupal.views.ajaxView.prototype.filterNestedViews = function () { + // If there is at least one parent with a view class, this view + // is nested (e.g., an attachment). Bail. + return !this.$view.parents('.view').length; + }; + + /** + * Attach the ajax behavior to each link. + */ + Drupal.views.ajaxView.prototype.attachPagerAjax = function () { + this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a') + .each($.proxy(this.attachPagerLinkAjax, this)); + }; + + /** + * Attach the ajax behavior to a singe link. + * + * @param {string} [id] + * The ID of the link. + * @param {HTMLElement} link + * The link element. + */ + Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) { + const $link = $(link); + const viewData = {}; + const href = $link.attr('href'); + // Construct an object using the settings defaults and then overriding + // with data specific to the link. + $.extend( + viewData, + this.settings, + Drupal.Views.parseQueryString(href), + // Extract argument data from the URL. + Drupal.Views.parseViewArgs(href, this.settings.view_base_path), + ); + + const self_settings = $.extend({}, this.element_settings, { + submit: viewData, + base: false, + element: link, + }); + this.pagerAjax = Drupal.ajax(self_settings); + }; + + /** + * Views scroll to top ajax command. + * + * @param {Drupal.Ajax} [ajax] + * A {@link Drupal.ajax} object. + * @param {object} response + * Ajax response. + * @param {string} response.selector + * Selector to use. + */ + Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) { + // Scroll to the top of the view. This will allow users + // to browse newly loaded content after e.g. clicking a pager + // link. + const offset = $(response.selector).offset(); + // We can't guarantee that the scrollable object should be + // the body, as the view could be embedded in something + // more complex such as a modal popup. Recurse up the DOM + // and scroll the first element that has a non-zero top. + let scrollTarget = response.selector; + while ($(scrollTarget).scrollTop() === 0 && $(scrollTarget).parent()) { + scrollTarget = $(scrollTarget).parent(); + } + // Only scroll upward. + if (offset.top - 10 < $(scrollTarget).scrollTop()) { + $(scrollTarget).animate({ scrollTop: (offset.top - 10) }, 500); + } + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js index 6422dd0a..67601a12 100644 --- a/core/modules/views/js/ajax_view.js +++ b/core/modules/views/js/ajax_view.js @@ -1,20 +1,11 @@ /** - * @file - * Handles AJAX fetching of views, including filter submission and response. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * Attaches the AJAX behavior to exposed filters forms and key View links. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches ajaxView functionality to relevant elements. - */ Drupal.behaviors.ViewsAjaxView = {}; Drupal.behaviors.ViewsAjaxView.attach = function () { if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) { @@ -27,48 +18,25 @@ } }; - /** - * @namespace - */ Drupal.views = {}; - /** - * @type {object.} - */ Drupal.views.instances = {}; - /** - * Javascript object for a certain view. - * - * @constructor - * - * @param {object} settings - * Settings object for the ajax view. - * @param {string} settings.view_dom_id - * The DOM id of the view. - */ Drupal.views.ajaxView = function (settings) { var selector = '.js-view-dom-id-' + settings.view_dom_id; this.$view = $(selector); - // Retrieve the path to use for views' ajax. var ajax_path = drupalSettings.views.ajax_path; - // If there are multiple views this might've ended up showing up multiple - // times. if (ajax_path.constructor.toString().indexOf('Array') !== -1) { ajax_path = ajax_path[0]; } - // Check if there are any GET parameters to send to views. var queryString = window.location.search || ''; if (queryString !== '') { - // Remove the question mark and Drupal path component if any. queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, ''); if (queryString !== '') { - // If there is a '?' in ajax_path, clean url are on and & should be - // used to add parameters. - queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString; + queryString = (/\?/.test(ajax_path) ? '&' : '?') + queryString; } } @@ -78,28 +46,16 @@ setClick: true, event: 'click', selector: selector, - progress: {type: 'fullscreen'} + progress: { type: 'fullscreen' } }; this.settings = settings; - // Add the ajax to exposed forms. this.$exposed_form = $('form#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')); this.$exposed_form.once('exposed-form').each($.proxy(this.attachExposedFormAjax, this)); - // Add the ajax to pagers. - this.$view - // Don't attach to nested views. Doing so would attach multiple behaviors - // to a given element. - .filter($.proxy(this.filterNestedViews, this)) - .once('ajax-pager').each($.proxy(this.attachPagerAjax, this)); - - // Add a trigger to update this view specifically. In order to trigger a - // refresh use the following code. - // - // @code - // $('.view-name').trigger('RefreshView'); - // @endcode + this.$view.filter($.proxy(this.filterNestedViews, this)).once('ajax-pager').each($.proxy(this.attachPagerAjax, this)); + var self_settings = $.extend({}, this.element_settings, { event: 'RefreshView', base: this.selector, @@ -108,14 +64,10 @@ this.refreshViewAjax = Drupal.ajax(self_settings); }; - /** - * @method - */ Drupal.views.ajaxView.prototype.attachExposedFormAjax = function () { var that = this; this.exposedFormAjax = []; - // Exclude the reset buttons so no AJAX behaviours are bound. Many things - // break during the form reset phase if using AJAX. + $('input[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) { var self_settings = $.extend({}, that.element_settings, { base: $(this).attr('id'), @@ -125,47 +77,20 @@ }); }; - /** - * @return {bool} - * If there is at least one parent with a view class return false. - * - * @todo remove .size() replace with .length. - */ Drupal.views.ajaxView.prototype.filterNestedViews = function () { - // If there is at least one parent with a view class, this view - // is nested (e.g., an attachment). Bail. - return !this.$view.parents('.view').size(); + return !this.$view.parents('.view').length; }; - /** - * Attach the ajax behavior to each link. - */ Drupal.views.ajaxView.prototype.attachPagerAjax = function () { - this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a') - .each($.proxy(this.attachPagerLinkAjax, this)); + this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a').each($.proxy(this.attachPagerLinkAjax, this)); }; - /** - * Attach the ajax behavior to a singe link. - * - * @param {string} [id] - * The ID of the link. - * @param {HTMLElement} link - * The link element. - */ Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) { var $link = $(link); var viewData = {}; var href = $link.attr('href'); - // Construct an object using the settings defaults and then overriding - // with data specific to the link. - $.extend( - viewData, - this.settings, - Drupal.Views.parseQueryString(href), - // Extract argument data from the URL. - Drupal.Views.parseViewArgs(href, this.settings.view_base_path) - ); + + $.extend(viewData, this.settings, Drupal.Views.parseQueryString(href), Drupal.Views.parseViewArgs(href, this.settings.view_base_path)); var self_settings = $.extend({}, this.element_settings, { submit: viewData, @@ -175,33 +100,16 @@ this.pagerAjax = Drupal.ajax(self_settings); }; - /** - * Views scroll to top ajax command. - * - * @param {Drupal.Ajax} [ajax] - * A {@link Drupal.ajax} object. - * @param {object} response - * Ajax response. - * @param {string} response.selector - * Selector to use. - */ Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) { - // Scroll to the top of the view. This will allow users - // to browse newly loaded content after e.g. clicking a pager - // link. var offset = $(response.selector).offset(); - // We can't guarantee that the scrollable object should be - // the body, as the view could be embedded in something - // more complex such as a modal popup. Recurse up the DOM - // and scroll the first element that has a non-zero top. + var scrollTarget = response.selector; while ($(scrollTarget).scrollTop() === 0 && $(scrollTarget).parent()) { scrollTarget = $(scrollTarget).parent(); } - // Only scroll upward. + if (offset.top - 10 < $(scrollTarget).scrollTop()) { - $(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500); + $(scrollTarget).animate({ scrollTop: offset.top - 10 }, 500); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/views/js/base.es6.js b/core/modules/views/js/base.es6.js new file mode 100644 index 00000000..88c5db33 --- /dev/null +++ b/core/modules/views/js/base.es6.js @@ -0,0 +1,106 @@ +/** + * @file + * Some basic behaviors and utility functions for Views. + */ + +(function ($, Drupal, drupalSettings) { + /** + * @namespace + */ + Drupal.Views = {}; + + /** + * Helper function to parse a querystring. + * + * @param {string} query + * The querystring to parse. + * + * @return {object} + * A map of query parameters. + */ + Drupal.Views.parseQueryString = function (query) { + const args = {}; + const pos = query.indexOf('?'); + if (pos !== -1) { + query = query.substring(pos + 1); + } + let pair; + const pairs = query.split('&'); + for (let i = 0; i < pairs.length; i++) { + pair = pairs[i].split('='); + // Ignore the 'q' path argument, if present. + if (pair[0] !== 'q' && pair[1]) { + args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); + } + } + return args; + }; + + /** + * Helper function to return a view's arguments based on a path. + * + * @param {string} href + * The href to check. + * @param {string} viewPath + * The views path to check. + * + * @return {object} + * An object containing `view_args` and `view_path`. + */ + Drupal.Views.parseViewArgs = function (href, viewPath) { + const returnObj = {}; + const path = Drupal.Views.getPath(href); + // Get viewPath url without baseUrl portion. + const viewHref = Drupal.url(viewPath).substring(drupalSettings.path.baseUrl.length); + // Ensure we have a correct path. + if (viewHref && path.substring(0, viewHref.length + 1) === `${viewHref}/`) { + returnObj.view_args = decodeURIComponent(path.substring(viewHref.length + 1, path.length)); + returnObj.view_path = path; + } + return returnObj; + }; + + /** + * Strip off the protocol plus domain from an href. + * + * @param {string} href + * The href to strip. + * + * @return {string} + * The href without the protocol and domain. + */ + Drupal.Views.pathPortion = function (href) { + // Remove e.g. http://example.com if present. + const protocol = window.location.protocol; + if (href.substring(0, protocol.length) === protocol) { + // 2 is the length of the '//' that normally follows the protocol. + href = href.substring(href.indexOf('/', protocol.length + 2)); + } + return href; + }; + + /** + * Return the Drupal path portion of an href. + * + * @param {string} href + * The href to check. + * + * @return {string} + * An internal path. + */ + Drupal.Views.getPath = function (href) { + href = Drupal.Views.pathPortion(href); + href = href.substring(drupalSettings.path.baseUrl.length, href.length); + // 3 is the length of the '?q=' added to the url without clean urls. + if (href.substring(0, 3) === '?q=') { + href = href.substring(3, href.length); + } + const chars = ['#', '?', '&']; + for (let i = 0; i < chars.length; i++) { + if (href.indexOf(chars[i]) > -1) { + href = href.substr(0, href.indexOf(chars[i])); + } + } + return href; + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/views/js/base.js b/core/modules/views/js/base.js index cca3be4d..be522cf5 100644 --- a/core/modules/views/js/base.js +++ b/core/modules/views/js/base.js @@ -1,37 +1,24 @@ /** - * @file - * Some basic behaviors and utility functions for Views. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * @namespace - */ Drupal.Views = {}; - /** - * Helper function to parse a querystring. - * - * @param {string} query - * The querystring to parse. - * - * @return {object} - * A map of query parameters. - */ Drupal.Views.parseQueryString = function (query) { var args = {}; var pos = query.indexOf('?'); if (pos !== -1) { query = query.substring(pos + 1); } - var pair; + var pair = void 0; var pairs = query.split('&'); for (var i = 0; i < pairs.length; i++) { pair = pairs[i].split('='); - // Ignore the 'q' path argument, if present. + if (pair[0] !== 'q' && pair[1]) { args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); } @@ -39,23 +26,12 @@ return args; }; - /** - * Helper function to return a view's arguments based on a path. - * - * @param {string} href - * The href to check. - * @param {string} viewPath - * The views path to check. - * - * @return {object} - * An object containing `view_args` and `view_path`. - */ Drupal.Views.parseViewArgs = function (href, viewPath) { var returnObj = {}; var path = Drupal.Views.getPath(href); - // Get viewPath url without baseUrl portion. + var viewHref = Drupal.url(viewPath).substring(drupalSettings.path.baseUrl.length); - // Ensure we have a correct path. + if (viewHref && path.substring(0, viewHref.length + 1) === viewHref + '/') { returnObj.view_args = decodeURIComponent(path.substring(viewHref.length + 1, path.length)); returnObj.view_path = path; @@ -63,38 +39,18 @@ return returnObj; }; - /** - * Strip off the protocol plus domain from an href. - * - * @param {string} href - * The href to strip. - * - * @return {string} - * The href without the protocol and domain. - */ Drupal.Views.pathPortion = function (href) { - // Remove e.g. http://example.com if present. var protocol = window.location.protocol; if (href.substring(0, protocol.length) === protocol) { - // 2 is the length of the '//' that normally follows the protocol. href = href.substring(href.indexOf('/', protocol.length + 2)); } return href; }; - /** - * Return the Drupal path portion of an href. - * - * @param {string} href - * The href to check. - * - * @return {string} - * An internal path. - */ Drupal.Views.getPath = function (href) { href = Drupal.Views.pathPortion(href); href = href.substring(drupalSettings.path.baseUrl.length, href.length); - // 3 is the length of the '?q=' added to the url without clean urls. + if (href.substring(0, 3) === '?q=') { href = href.substring(3, href.length); } @@ -106,5 +62,4 @@ } return href; }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/views/src/Ajax/HighlightCommand.php b/core/modules/views/src/Ajax/HighlightCommand.php index c19ff1b6..b04c0bef 100644 --- a/core/modules/views/src/Ajax/HighlightCommand.php +++ b/core/modules/views/src/Ajax/HighlightCommand.php @@ -32,10 +32,10 @@ public function __construct($selector) { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => 'viewsHighlight', 'selector' => $this->selector, - ); + ]; } } diff --git a/core/modules/views/src/Ajax/ReplaceTitleCommand.php b/core/modules/views/src/Ajax/ReplaceTitleCommand.php index 45972c3c..90e462ab 100644 --- a/core/modules/views/src/Ajax/ReplaceTitleCommand.php +++ b/core/modules/views/src/Ajax/ReplaceTitleCommand.php @@ -32,10 +32,10 @@ public function __construct($title) { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => 'viewsReplaceTitle', 'selector' => $this->title, - ); + ]; } } diff --git a/core/modules/views/src/Ajax/ScrollTopCommand.php b/core/modules/views/src/Ajax/ScrollTopCommand.php index a303ffbb..bf2db4e7 100644 --- a/core/modules/views/src/Ajax/ScrollTopCommand.php +++ b/core/modules/views/src/Ajax/ScrollTopCommand.php @@ -32,10 +32,10 @@ public function __construct($selector) { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => 'viewsScrollTop', 'selector' => $this->selector, - ); + ]; } } diff --git a/core/modules/views/src/Ajax/ShowButtonsCommand.php b/core/modules/views/src/Ajax/ShowButtonsCommand.php index f5d7dceb..aecd6bd6 100644 --- a/core/modules/views/src/Ajax/ShowButtonsCommand.php +++ b/core/modules/views/src/Ajax/ShowButtonsCommand.php @@ -33,10 +33,10 @@ public function __construct($changed) { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => 'viewsShowButtons', 'changed' => $this->changed, - ); + ]; } } diff --git a/core/modules/views/src/Ajax/TriggerPreviewCommand.php b/core/modules/views/src/Ajax/TriggerPreviewCommand.php index 080bc024..64e76cb8 100644 --- a/core/modules/views/src/Ajax/TriggerPreviewCommand.php +++ b/core/modules/views/src/Ajax/TriggerPreviewCommand.php @@ -15,9 +15,9 @@ class TriggerPreviewCommand implements CommandInterface { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => 'viewsTriggerPreview', - ); + ]; } } diff --git a/core/modules/views/src/Ajax/ViewAjaxResponse.php b/core/modules/views/src/Ajax/ViewAjaxResponse.php index 9af9a67d..d1918004 100644 --- a/core/modules/views/src/Ajax/ViewAjaxResponse.php +++ b/core/modules/views/src/Ajax/ViewAjaxResponse.php @@ -32,7 +32,7 @@ public function setView(ViewExecutable $view) { /** * Gets the executed view of this response. * - * @return \Drupal\views\ViewExecutable $view + * @return \Drupal\views\ViewExecutable * The View executed on this ajax request. */ public function getView() { diff --git a/core/modules/views/src/Analyzer.php b/core/modules/views/src/Analyzer.php index 2a333429..a6a8d56b 100644 --- a/core/modules/views/src/Analyzer.php +++ b/core/modules/views/src/Analyzer.php @@ -44,7 +44,7 @@ public function __construct(ModuleHandlerInterface $module_handler) { */ public function getMessages(ViewExecutable $view) { $view->initDisplay(); - $messages = $this->moduleHandler->invokeAll('views_analyze', array($view)); + $messages = $this->moduleHandler->invokeAll('views_analyze', [$view]); return $messages; } @@ -57,13 +57,13 @@ public function getMessages(ViewExecutable $view) { */ public function formatMessages(array $messages) { if (empty($messages)) { - $messages = array(static::formatMessage(t('View analysis can find nothing to report.'), 'ok')); + $messages = [static::formatMessage(t('View analysis can find nothing to report.'), 'ok')]; } - $types = array('ok' => array(), 'warning' => array(), 'error' => array()); + $types = ['ok' => [], 'warning' => [], 'error' => []]; foreach ($messages as $message) { if (empty($types[$message['type']])) { - $types[$message['type']] = array(); + $types[$message['type']] = []; } $types[$message['type']][] = $message['message']; } @@ -73,11 +73,11 @@ public function formatMessages(array $messages) { $type .= ' messages'; $message = ''; if (count($messages) > 1) { - $item_list = array( + $item_list = [ '#theme' => 'item_list', '#items' => $messages, - ); - $message = drupal_render($item_list); + ]; + $message = \Drupal::service('renderer')->render($item_list); } elseif ($messages) { $message = array_shift($messages); @@ -115,8 +115,8 @@ public function formatMessages(array $messages) { * @return array * A single formatted message, consisting of a key message and a key type. */ - static function formatMessage($message, $type = 'error') { - return array('message' => $message, 'type' => $type); + public static function formatMessage($message, $type = 'error') { + return ['message' => $message, 'type' => $type]; } } diff --git a/core/modules/views/src/Annotation/ViewsAccess.php b/core/modules/views/src/Annotation/ViewsAccess.php index fde990d8..9cfcb24c 100644 --- a/core/modules/views/src/Annotation/ViewsAccess.php +++ b/core/modules/views/src/Annotation/ViewsAccess.php @@ -2,7 +2,6 @@ namespace Drupal\views\Annotation; - /** * Defines a Plugin annotation object for views access plugins. * diff --git a/core/modules/views/src/Controller/ViewAjaxController.php b/core/modules/views/src/Controller/ViewAjaxController.php index 7993d2a5..4aefdabd 100644 --- a/core/modules/views/src/Controller/ViewAjaxController.php +++ b/core/modules/views/src/Controller/ViewAjaxController.php @@ -114,7 +114,7 @@ public function ajaxView(Request $request) { $display_id = $request->request->get('view_display_id'); if (isset($name) && isset($display_id)) { $args = $request->request->get('view_args'); - $args = isset($args) && $args !== '' ? explode('/', $args) : array(); + $args = isset($args) && $args !== '' ? explode('/', $args) : []; // Arguments can be empty, make sure they are passed on as NULL so that // argument validation is not triggered. @@ -132,7 +132,7 @@ public function ajaxView(Request $request) { // Remove all of this stuff from the query of the request so it doesn't // end up in pagers and tablesort URLs. - foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER) as $key) { + foreach (['view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER] as $key) { $request->query->remove($key); $request->request->remove($key); } @@ -142,7 +142,7 @@ public function ajaxView(Request $request) { throw new NotFoundHttpException(); } $view = $this->executableFactory->get($entity); - if ($view && $view->access($display_id)) { + if ($view && $view->access($display_id) && $view->setDisplay($display_id) && $view->display_handler->ajaxEnabled()) { $response->setView($view); // Fix the current path for paging. if (!empty($path)) { @@ -181,7 +181,7 @@ public function ajaxView(Request $request) { $view->dom_id = $dom_id; $context = new RenderContext(); - $preview = $this->renderer->executeInRenderContext($context, function() use ($view, $display_id, $args) { + $preview = $this->renderer->executeInRenderContext($context, function () use ($view, $display_id, $args) { return $view->preview($display_id, $args); }); if (!$context->isEmpty()) { diff --git a/core/modules/views/src/DisplayPluginCollection.php b/core/modules/views/src/DisplayPluginCollection.php index 0b692b11..7c3c736f 100644 --- a/core/modules/views/src/DisplayPluginCollection.php +++ b/core/modules/views/src/DisplayPluginCollection.php @@ -80,7 +80,7 @@ protected function initializePlugin($display_id) { // display plugin isn't found. catch (PluginException $e) { $message = $e->getMessage(); - drupal_set_message(t('@message', array('@message' => $message)), 'warning'); + drupal_set_message(t('@message', ['@message' => $message]), 'warning'); } // If no plugin instance has been created, return NULL. diff --git a/core/modules/views/src/Element/View.php b/core/modules/views/src/Element/View.php index b02e260f..43d1058c 100644 --- a/core/modules/views/src/Element/View.php +++ b/core/modules/views/src/Element/View.php @@ -17,16 +17,16 @@ class View extends RenderElement { */ public function getInfo() { $class = get_class($this); - return array( - '#pre_render' => array( - array($class, 'preRenderViewElement'), - ), + return [ + '#pre_render' => [ + [$class, 'preRenderViewElement'], + ], '#name' => NULL, '#display_id' => 'default', - '#arguments' => array(), + '#arguments' => [], '#embed' => TRUE, '#cache' => [], - ); + ]; } /** @@ -92,7 +92,7 @@ public static function preRenderViewElement($element) { } if (empty($view->display_handler->getPluginDefinition()['returns_response'])) { $element['#attributes']['class'][] = 'views-element-container'; - $element['#theme_wrappers'] = array('container'); + $element['#theme_wrappers'] = ['container']; } } diff --git a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php index 1b05c1b2..3c38da17 100644 --- a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php +++ b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php @@ -7,7 +7,7 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Language\LanguageManagerInterface; -use Drupal\views\Plugin\views\field\Field; +use Drupal\views\Plugin\views\field\EntityField; use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\views\ResultRow; use Drupal\views\ViewExecutable; @@ -111,13 +111,13 @@ public function query(QueryPluginBase $query, $relationship = NULL) { * * @param \Drupal\views\ResultRow $row * A single row of the query result. - * @param \Drupal\views\Plugin\views\field\Field $field + * @param \Drupal\views\Plugin\views\field\EntityField $field * (optional) A field to be rendered. * * @return array * A renderable array for the entity data contained in the result row. */ - public function render(ResultRow $row, Field $field = NULL) { + public function render(ResultRow $row, EntityField $field = NULL) { // The method is called for each field in each result row. In order to // leverage multiple-entity building of formatter output, we build the // render arrays for all fields in all rows on the first call. @@ -259,7 +259,7 @@ protected function buildFields(array $values) { protected function getRenderableFieldIds() { $field_ids = []; foreach ($this->view->field as $field_id => $field) { - if ($field instanceof Field && $field->relationship == $this->relationship) { + if ($field instanceof EntityField && $field->relationship == $this->relationship) { $field_ids[] = $field_id; } } diff --git a/core/modules/views/src/Entity/Render/EntityTranslationRenderTrait.php b/core/modules/views/src/Entity/Render/EntityTranslationRenderTrait.php index e08ef04d..8fbc191d 100644 --- a/core/modules/views/src/Entity/Render/EntityTranslationRenderTrait.php +++ b/core/modules/views/src/Entity/Render/EntityTranslationRenderTrait.php @@ -30,10 +30,10 @@ protected function getEntityTranslationRenderer() { $view = $this->getView(); $rendering_language = $view->display_handler->getOption('rendering_language'); $langcode = NULL; - $dynamic_renderers = array( + $dynamic_renderers = [ '***LANGUAGE_entity_translation***' => 'TranslationLanguageRenderer', '***LANGUAGE_entity_default***' => 'DefaultLanguageRenderer', - ); + ]; if (isset($dynamic_renderers[$rendering_language])) { // Dynamic language set based on result rows or instance defaults. $renderer = $dynamic_renderers[$rendering_language]; diff --git a/core/modules/views/src/Entity/Render/TranslationLanguageRenderer.php b/core/modules/views/src/Entity/Render/TranslationLanguageRenderer.php index 00ae5248..5b4b3561 100644 --- a/core/modules/views/src/Entity/Render/TranslationLanguageRenderer.php +++ b/core/modules/views/src/Entity/Render/TranslationLanguageRenderer.php @@ -28,13 +28,52 @@ public function query(QueryPluginBase $query, $relationship = NULL) { if (!$this->languageManager->isMultilingual() || !$this->entityType->hasKey('langcode')) { return; } + $langcode_table = $this->getLangcodeTable($query, $relationship); + if ($langcode_table) { + /** @var \Drupal\views\Plugin\views\query\Sql $query */ + $table_alias = $query->ensureTable($langcode_table, $relationship); + $langcode_key = $this->entityType->getKey('langcode'); + $this->langcodeAlias = $query->addField($table_alias, $langcode_key); + } + } + + /** + * Returns the name of the table holding the "langcode" field. + * + * @param \Drupal\views\Plugin\views\query\QueryPluginBase $query + * The query being executed. + * @param string $relationship + * The relationship used by the entity type. + * + * @return string + * A table name. + */ + protected function getLangcodeTable(QueryPluginBase $query, $relationship) { + /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */ + $storage = \Drupal::entityTypeManager()->getStorage($this->entityType->id()); $langcode_key = $this->entityType->getKey('langcode'); - $storage = \Drupal::entityManager()->getStorage($this->entityType->id()); + $langcode_table = $storage->getTableMapping()->getFieldTableName($langcode_key); - if ($table = $storage->getTableMapping()->getFieldTableName($langcode_key)) { - $table_alias = $query->ensureTable($table, $relationship); - $this->langcodeAlias = $query->addField($table_alias, $langcode_key); + // If the entity type is revisionable, we need to take into account views of + // entity revisions. Usually the view will use the entity data table as the + // query base table, however, in case of an entity revision view, we need to + // use the revision table or the revision data table, depending on which one + // is being used as query base table. + if ($this->entityType->isRevisionable()) { + $query_base_table = isset($query->relationships[$relationship]['base']) ? + $query->relationships[$relationship]['base'] : + $this->view->storage->get('base_table'); + $revision_table = $storage->getRevisionTable(); + $revision_data_table = $storage->getRevisionDataTable(); + if ($query_base_table === $revision_table) { + $langcode_table = $revision_table; + } + elseif ($query_base_table === $revision_data_table) { + $langcode_table = $revision_data_table; + } } + + return $langcode_table; } /** diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 1e9fac10..b69234c3 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -5,8 +5,11 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\Cache; use Drupal\Core\Config\Entity\ConfigEntityBase; +use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Language\LanguageInterface; +use Drupal\views\Plugin\DependentWithRemovalPluginInterface; use Drupal\views\Views; use Drupal\views\ViewEntityInterface; @@ -16,9 +19,6 @@ * @ConfigEntityType( * id = "view", * label = @Translation("View", context = "View entity type"), - * handlers = { - * "access" = "Drupal\views\ViewAccessControlHandler" - * }, * admin_permission = "administer views", * entity_keys = { * "id" = "id", @@ -91,7 +91,7 @@ class View extends ConfigEntityBase implements ViewEntityInterface { * * @var array */ - protected $display = array(); + protected $display = []; /** * The name of the base field to use. @@ -182,15 +182,15 @@ public function addDisplay($plugin_id = 'page', $title = NULL, $id = NULL) { } } - $display_options = array( + $display_options = [ 'display_plugin' => $plugin_id, 'id' => $id, // Cast the display title to a string since it is an object. // @see \Drupal\Core\StringTranslation\TranslatableMarkup 'display_title' => (string) $title, 'position' => $id === 'default' ? 0 : count($this->display), - 'display_options' => array(), - ); + 'display_options' => [], + ]; // Add the display options to the view. $this->display[$id] = $display_options; @@ -290,10 +290,13 @@ public function calculateDependencies() { public function preSave(EntityStorageInterface $storage) { parent::preSave($storage); + $displays = $this->get('display'); + + $this->fixTableNames($displays); + // Sort the displays. - $display = $this->get('display'); - ksort($display); - $this->set('display', array('default' => $display['default']) + $display); + ksort($displays); + $this->set('display', ['default' => $displays['default']] + $displays); // @todo Check whether isSyncing is needed. if (!$this->isSyncing()) { @@ -301,6 +304,45 @@ public function preSave(EntityStorageInterface $storage) { } } + /** + * Fixes table names for revision metadata fields of revisionable entities. + * + * Views for revisionable entity types using revision metadata fields might + * be using the wrong table to retrieve the fields after system_update_8300 + * has moved them correctly to the revision table. This method updates the + * views to use the correct tables. + * + * @param array &$displays + * An array containing display handlers of a view. + * + * @deprecated in Drupal 8.3.0, will be removed in Drupal 9.0.0. + */ + private function fixTableNames(array &$displays) { + // Fix wrong table names for entity revision metadata fields. + foreach ($displays as $display => $display_data) { + if (isset($display_data['display_options']['fields'])) { + foreach ($display_data['display_options']['fields'] as $property_name => $property_data) { + if (isset($property_data['entity_type']) && isset($property_data['field']) && isset($property_data['table'])) { + $entity_type = $this->entityTypeManager()->getDefinition($property_data['entity_type']); + // We need to update the table name only for revisionable entity + // types, otherwise the view is already using the correct table. + if (($entity_type instanceof ContentEntityTypeInterface) && is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable()) { + $revision_metadata_fields = $entity_type->getRevisionMetadataKeys(); + // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() + $revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision'; + + // Check if this is a revision metadata field and if it uses the + // wrong table. + if (in_array($property_data['field'], $revision_metadata_fields) && $property_data['table'] != $revision_table) { + $displays[$display]['display_options']['fields'][$property_name]['table'] = $revision_table; + } + } + } + } + } + } + } + /** * Fills in the cache metadata of this view. * @@ -369,17 +411,17 @@ public static function preCreate(EntityStorageInterface $storage, array &$values // If there is no information about displays available add at least the // default display. - $values += array( - 'display' => array( - 'default' => array( + $values += [ + 'display' => [ + 'default' => [ 'display_plugin' => 'default', 'id' => 'default', 'display_title' => 'Master', 'position' => 0, - 'display_options' => array(), - ), - ) - ); + 'display_options' => [], + ], + ] + ]; } /** @@ -424,15 +466,15 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti * {@inheritdoc} */ public function mergeDefaultDisplaysOptions() { - $displays = array(); + $displays = []; foreach ($this->get('display') as $key => $options) { - $options += array( - 'display_options' => array(), + $options += [ + 'display_options' => [], 'display_plugin' => NULL, 'id' => NULL, 'display_title' => '', 'position' => NULL, - ); + ]; // Add the defaults for the display. $displays[$key] = $options; } @@ -468,4 +510,61 @@ public function invalidateCaches() { \Drupal::service('cache_tags.invalidator')->invalidateTags($tags); } + /** + * {@inheritdoc} + */ + public function onDependencyRemoval(array $dependencies) { + $changed = FALSE; + + // Don't intervene if the views module is removed. + if (isset($dependencies['module']) && in_array('views', $dependencies['module'])) { + return FALSE; + } + + // If the base table for the View is provided by a module being removed, we + // delete the View because this is not something that can be fixed manually. + $views_data = Views::viewsData(); + $base_table = $this->get('base_table'); + $base_table_data = $views_data->get($base_table); + if (!empty($base_table_data['table']['provider']) && in_array($base_table_data['table']['provider'], $dependencies['module'])) { + return FALSE; + } + + $current_display = $this->getExecutable()->current_display; + $handler_types = Views::getHandlerTypes(); + + // Find all the handlers and check whether they want to do something on + // dependency removal. + foreach ($this->display as $display_id => $display_plugin_base) { + $this->getExecutable()->setDisplay($display_id); + $display = $this->getExecutable()->getDisplay(); + + foreach (array_keys($handler_types) as $handler_type) { + $handlers = $display->getHandlers($handler_type); + foreach ($handlers as $handler_id => $handler) { + if ($handler instanceof DependentWithRemovalPluginInterface) { + if ($handler->onDependencyRemoval($dependencies)) { + // Remove the handler and indicate we made changes. + unset($this->display[$display_id]['display_options'][$handler_types[$handler_type]['plural']][$handler_id]); + $changed = TRUE; + } + } + } + } + } + + // Disable the View if we made changes. + // @todo https://www.drupal.org/node/2832558 Give better feedback for + // disabled config. + if ($changed) { + // Force a recalculation of the dependencies if we made changes. + $this->getExecutable()->current_display = NULL; + $this->calculateDependencies(); + $this->disable(); + } + + $this->getExecutable()->setDisplay($current_display); + return $changed; + } + } diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php index 61def5ac..59e9196f 100644 --- a/core/modules/views/src/EntityViewsData.php +++ b/core/modules/views/src/EntityViewsData.php @@ -78,7 +78,7 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac * @param \Drupal\Core\StringTranslation\TranslationInterface $translation_manager * The translation manager. */ - function __construct(EntityTypeInterface $entity_type, SqlEntityStorageInterface $storage_controller, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, TranslationInterface $translation_manager) { + public function __construct(EntityTypeInterface $entity_type, SqlEntityStorageInterface $storage_controller, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, TranslationInterface $translation_manager) { $this->entityType = $entity_type; $this->entityManager = $entity_manager; $this->storage = $storage_controller; @@ -161,28 +161,28 @@ public function getViewsData() { if ($label_key = $this->entityType->getKey('label')) { if ($data_table) { - $data[$views_base_table]['table']['base']['defaults'] = array( + $data[$views_base_table]['table']['base']['defaults'] = [ 'field' => $label_key, 'table' => $data_table, - ); + ]; } else { - $data[$views_base_table]['table']['base']['defaults'] = array( + $data[$views_base_table]['table']['base']['defaults'] = [ 'field' => $label_key, - ); + ]; } } // Entity types must implement a list_builder in order to use Views' // entity operations field. if ($this->entityType->hasListBuilderClass()) { - $data[$base_table]['operations'] = array( - 'field' => array( + $data[$base_table]['operations'] = [ + 'field' => [ 'title' => $this->t('Operations links'), 'help' => $this->t('Provides links to perform entity operations.'), 'id' => 'entity_operations', - ), - ); + ], + ]; } if ($this->entityType->hasViewBuilderClass()) { @@ -215,27 +215,34 @@ public function getViewsData() { $views_revision_base_table = $revision_data_table; } $data[$views_revision_base_table]['table']['entity revision'] = TRUE; - $data[$views_revision_base_table]['table']['base'] = array( + $data[$views_revision_base_table]['table']['base'] = [ 'field' => $revision_field, - 'title' => $this->t('@entity_type revisions', array('@entity_type' => $this->entityType->getLabel())), - ); + 'title' => $this->t('@entity_type revisions', ['@entity_type' => $this->entityType->getLabel()]), + ]; // Join the revision table to the base table. - $data[$views_revision_base_table]['table']['join'][$views_base_table] = array( + $data[$views_revision_base_table]['table']['join'][$views_base_table] = [ 'left_field' => $revision_field, 'field' => $revision_field, 'type' => 'INNER', - ); + ]; if ($revision_data_table) { $data[$revision_data_table]['table']['group'] = $this->t('@entity_type revision', ['@entity_type' => $this->entityType->getLabel()]); $data[$revision_data_table]['table']['entity revision'] = TRUE; - $data[$revision_table]['table']['join'][$revision_data_table] = array( + $data[$revision_table]['table']['join'][$revision_data_table] = [ 'left_field' => $revision_field, 'field' => $revision_field, 'type' => 'INNER', - ); + ]; } + + // Add a filter for showing only the latest revisions of an entity. + $data[$revision_table]['latest_revision'] = [ + 'title' => $this->t('Is Latest Revision'), + 'help' => $this->t('Restrict the view to only revisions that are the latest revision of their entity.'), + 'filter' => ['id' => 'latest_revision'], + ]; } $this->addEntityLinks($data[$base_table]); @@ -300,7 +307,7 @@ public function getViewsData() { // Add the entity type key to each table generated. $entity_type_id = $this->entityType->id(); - array_walk($data, function(&$table_data) use ($entity_type_id){ + array_walk($data, function (&$table_data) use ($entity_type_id) { $table_data['table']['entity type'] = $entity_type_id; }); @@ -404,7 +411,7 @@ protected function mapFieldDefinition($table, $field_name, FieldDefinitionInterf * The modified views data field definition. */ protected function mapSingleFieldViewsData($table, $field_name, $field_type, $column_name, $column_type, $first, FieldDefinitionInterface $field_definition) { - $views_field = array(); + $views_field = []; // Provide a nicer, less verbose label for the first column within a field. // @todo Introduce concept of the "main" column for a field, rather than diff --git a/core/modules/views/src/EventSubscriber/RouteSubscriber.php b/core/modules/views/src/EventSubscriber/RouteSubscriber.php index e8b09927..c2b9ea89 100644 --- a/core/modules/views/src/EventSubscriber/RouteSubscriber.php +++ b/core/modules/views/src/EventSubscriber/RouteSubscriber.php @@ -49,7 +49,7 @@ class RouteSubscriber extends RouteSubscriberBase { * * @var array */ - protected $viewRouteNames = array(); + protected $viewRouteNames = []; /** * Constructs a \Drupal\views\EventSubscriber\RouteSubscriber instance. @@ -76,7 +76,7 @@ public function reset() { */ public static function getSubscribedEvents() { $events = parent::getSubscribedEvents(); - $events[RoutingEvents::FINISHED] = array('routeRebuildFinished'); + $events[RoutingEvents::FINISHED] = ['routeRebuildFinished']; // Ensure to run after the entity resolver subscriber // @see \Drupal\Core\EventSubscriber\EntityRouteAlterSubscriber $events[RoutingEvents::ALTER] = ['onAlterRoutes', -175]; @@ -89,7 +89,7 @@ public static function getSubscribedEvents() { */ protected function getViewsDisplayIDsWithRoute() { if (!isset($this->viewsDisplayPairs)) { - $this->viewsDisplayPairs = array(); + $this->viewsDisplayPairs = []; // @todo Convert this method to some service. $views = $this->getApplicableViews(); @@ -156,7 +156,11 @@ protected function alterRoutes(RouteCollection $collection) { } /** - * {@inheritdoc} + * Stores the new route names after they have been rebuilt. + * + * Callback for the RoutingEvents::FINISHED event. + * + * @see \Drupal\views\EventSubscriber::getSubscribedEvents() */ public function routeRebuildFinished() { $this->reset(); diff --git a/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php b/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php index 59ecde69..6060ae40 100644 --- a/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php +++ b/core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php @@ -144,6 +144,11 @@ public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeI $changes[] = static::REVISION_DATA_TABLE_REMOVAL; } + // Stop here if no changes are needed. + if (empty($changes)) { + return; + } + /** @var \Drupal\views\Entity\View[] $all_views */ $all_views = $this->entityManager->getStorage('view')->loadMultiple(NULL); diff --git a/core/modules/views/src/ExposedFormCache.php b/core/modules/views/src/ExposedFormCache.php index cb67a9ba..f60cc71c 100644 --- a/core/modules/views/src/ExposedFormCache.php +++ b/core/modules/views/src/ExposedFormCache.php @@ -14,7 +14,7 @@ class ExposedFormCache { * * @var array */ - protected $cache = array(); + protected $cache = []; /** * Save the Views exposed form for later use. @@ -56,7 +56,7 @@ public function getForm($view_id, $display_id) { * Rests the form cache. */ public function reset() { - $this->cache = array(); + $this->cache = []; } } diff --git a/core/modules/views/src/Form/ViewsExposedForm.php b/core/modules/views/src/Form/ViewsExposedForm.php index bacd5549..44e7ec4b 100644 --- a/core/modules/views/src/Form/ViewsExposedForm.php +++ b/core/modules/views/src/Form/ViewsExposedForm.php @@ -52,10 +52,10 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { // Don't show the form when batch operations are in progress. if ($batch = batch_get() && isset($batch['current_set'])) { - return array( + return [ // Set the theme callback to be nothing to avoid errors in template_preprocess_views_exposed_form(). '#theme' => '', - ); + ]; } // Make sure that we validate because this form might be submitted @@ -74,7 +74,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { return $cache; } - $form['#info'] = array(); + $form['#info'] = []; // Go through each handler and let it generate its exposed widget. foreach ($view->display_handler->handlers as $type => $value) { @@ -100,16 +100,16 @@ public function buildForm(array $form, FormStateInterface $form_state) { } } - $form['actions'] = array( + $form['actions'] = [ '#type' => 'actions' - ); - $form['actions']['submit'] = array( + ]; + $form['actions']['submit'] = [ // Prevent from showing up in \Drupal::request()->query. '#name' => '', '#type' => 'submit', '#value' => $this->t('Apply'), '#id' => Html::getUniqueId('edit-submit-' . $view->storage->id()), - ); + ]; $form['#action'] = $view->hasUrl() ? $view->getUrl()->toString() : Url::fromRoute('')->toString(); $form['#theme'] = $view->buildThemeFunctions('views_exposed_form'); @@ -131,7 +131,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function validateForm(array &$form, FormStateInterface $form_state) { $view = $form_state->get('view'); - foreach (array('field', 'filter') as $type) { + foreach (['field', 'filter'] as $type) { /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface[] $handlers */ $handlers = &$view->$type; foreach ($handlers as $key => $handler) { @@ -148,9 +148,9 @@ public function validateForm(array &$form, FormStateInterface $form_state) { */ public function submitForm(array &$form, FormStateInterface $form_state) { // Form input keys that will not be included in $view->exposed_raw_data. - $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset'); + $exclude = ['submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset']; $values = $form_state->getValues(); - foreach (array('field', 'filter') as $type) { + foreach (['field', 'filter'] as $type) { /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface[] $handlers */ $handlers = &$form_state->get('view')->$type; foreach ($handlers as $key => $info) { @@ -169,7 +169,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $view->exposed_data = $values; $view->exposed_raw_input = []; - $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset'); + $exclude = ['submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset']; /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */ $exposed_form_plugin = $view->display_handler->getPlugin('exposed_form'); $exposed_form_plugin->exposedFormSubmit($form, $form_state, $exclude); diff --git a/core/modules/views/src/Form/ViewsForm.php b/core/modules/views/src/Form/ViewsForm.php index b124d653..575b9231 100644 --- a/core/modules/views/src/Form/ViewsForm.php +++ b/core/modules/views/src/Form/ViewsForm.php @@ -151,19 +151,19 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu // Add the base form ID. $form_state->addBuildInfo('base_form_id', $this->getBaseFormId()); - $form = array(); + $form = []; $query = $this->requestStack->getCurrentRequest()->query->all(); - $query = UrlHelper::filterQueryParameters($query, array(), ''); + $query = UrlHelper::filterQueryParameters($query, [], ''); - $options = array('query' => $query); + $options = ['query' => $query]; $form['#action'] = $view->hasUrl() ? $view->getUrl()->setOptions($options)->toString() : Url::fromRoute('')->setOptions($options)->toString(); // Tell the preprocessor whether it should hide the header, footer, pager, // etc. - $form['show_view_elements'] = array( + $form['show_view_elements'] = [ '#type' => 'value', '#value' => ($step == 'views_form_views_form') ? TRUE : FALSE, - ); + ]; $form_object = $this->getFormObject($form_state); $form += $form_object->buildForm($form, $form_state, $view, $output); diff --git a/core/modules/views/src/Form/ViewsFormMainForm.php b/core/modules/views/src/Form/ViewsFormMainForm.php index fb8818ae..da56f491 100644 --- a/core/modules/views/src/Form/ViewsFormMainForm.php +++ b/core/modules/views/src/Form/ViewsFormMainForm.php @@ -30,15 +30,15 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu // (below the exposed widgets). $form['output']['#weight'] = 50; - $form['actions'] = array( + $form['actions'] = [ '#type' => 'actions', - ); - $form['actions']['submit'] = array( + ]; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => t('Save'), - ); + ]; - $substitutions = array(); + $substitutions = []; foreach ($view->field as $field_name => $field) { $form_element_name = $field_name; if (method_exists($field, 'form_element_name')) { @@ -71,11 +71,11 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu $form_element_row_id = $row_id; } - $substitutions[] = array( + $substitutions[] = [ 'placeholder' => '', 'field_name' => $form_element_name, 'row_id' => $form_element_row_id, - ); + ]; } } } @@ -89,10 +89,10 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu } } - $form['#substitutions'] = array( + $form['#substitutions'] = [ '#type' => 'value', '#value' => $substitutions, - ); + ]; return $form; } @@ -111,7 +111,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { } // Call the validate method on every area handler that has it. - foreach (array('header', 'footer') as $area) { + foreach (['header', 'footer'] as $area) { foreach ($view->{$area} as $area_handler) { if (method_exists($area_handler, 'viewsFormValidate')) { $area_handler->viewsFormValidate($form, $form_state); @@ -134,7 +134,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } // Call the submit method on every area handler that has it. - foreach (array('header', 'footer') as $area) { + foreach (['header', 'footer'] as $area) { foreach ($view->{$area} as $area_handler) { if (method_exists($area_handler, 'viewsFormSubmit')) { $area_handler->viewsFormSubmit($form, $form_state); diff --git a/core/modules/views/src/ManyToOneHelper.php b/core/modules/views/src/ManyToOneHelper.php index a3c4834a..cb2e5754 100644 --- a/core/modules/views/src/ManyToOneHelper.php +++ b/core/modules/views/src/ManyToOneHelper.php @@ -2,6 +2,7 @@ namespace Drupal\views; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\HandlerBase; @@ -20,22 +21,22 @@ */ class ManyToOneHelper { - function __construct($handler) { + public function __construct($handler) { $this->handler = $handler; } public static function defineOptions(&$options) { - $options['reduce_duplicates'] = array('default' => FALSE); + $options['reduce_duplicates'] = ['default' => FALSE]; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['reduce_duplicates'] = array( + $form['reduce_duplicates'] = [ '#type' => 'checkbox', '#title' => t('Reduce duplicates'), '#description' => t("This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution. Shouldn't be set on single-value fields, as it may cause values to disappear from display, if used on an incompatible field."), '#default_value' => !empty($this->handler->options['reduce_duplicates']), '#weight' => 4, - ); + ]; } /** @@ -133,14 +134,14 @@ public function summaryJoin() { else { if (!empty($view->many_to_one_tables[$field])) { foreach ($view->many_to_one_tables[$field] as $value) { - $join->extra = array( - array( + $join->extra = [ + [ 'field' => $this->handler->realField, 'operator' => '!=', 'value' => $value, 'numeric' => !empty($this->definition['numeric']), - ), - ); + ], + ]; } } return $this->addTable($join); @@ -172,14 +173,14 @@ public function ensureMyTable() { $join->type = 'LEFT'; if (!empty($this->handler->view->many_to_one_tables[$field])) { foreach ($this->handler->view->many_to_one_tables[$field] as $value) { - $join->extra = array( - array( + $join->extra = [ + [ 'field' => $this->handler->realField, 'operator' => '!=', 'value' => $value, 'numeric' => !empty($this->handler->definition['numeric']), - ), - ); + ], + ]; } } @@ -193,19 +194,19 @@ public function ensureMyTable() { // We do one join per selected value. if ($this->handler->operator != 'not') { // Clone the join for each table: - $this->handler->tableAliases = array(); + $this->handler->tableAliases = []; foreach ($this->handler->value as $value) { $join = $this->getJoin(); if ($this->handler->operator == 'and') { $join->type = 'INNER'; } - $join->extra = array( - array( + $join->extra = [ + [ 'field' => $this->handler->realField, 'value' => $value, 'numeric' => !empty($this->handler->definition['numeric']), - ), - ); + ], + ]; // The table alias needs to be unique to this value across the // multiple times the filter or argument is called by the view. @@ -229,14 +230,14 @@ public function ensureMyTable() { else { $join = $this->getJoin(); $join->type = 'LEFT'; - $join->extra = array(); + $join->extra = []; $join->extraOperator = 'OR'; foreach ($this->handler->value as $value) { - $join->extra[] = array( + $join->extra[] = [ 'field' => $this->handler->realField, 'value' => $value, 'numeric' => !empty($this->handler->definition['numeric']), - ); + ]; } $this->handler->tableAlias = $this->addTable($join); @@ -268,8 +269,8 @@ public function addFilter() { $options['group'] = 0; } - // add_condition determines whether a single expression is enough(FALSE) or the - // conditions should be added via an db_or()/db_and() (TRUE). + // If $add_condition is set to FALSE, a single expression is enough. If it + // is set to TRUE, conditions will be added. $add_condition = TRUE; if ($operator == 'not') { $value = NULL; @@ -296,9 +297,9 @@ public function addFilter() { else { $operator = "$operator $placeholder"; } - $placeholders = array( + $placeholders = [ $placeholder => $value, - ); + ]; $this->handler->query->addWhereExpression($options['group'], "$field $operator", $placeholders); } else { @@ -310,7 +311,7 @@ public function addFilter() { $this->handler->query->addWhereExpression(0, "$field $operator"); } else { - $this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value)); + $this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", [$placeholder => $value]); } } else { @@ -318,7 +319,7 @@ public function addFilter() { $this->handler->query->addWhereExpression(0, "$field $operator"); } else { - $this->handler->query->addWhereExpression(0, "$field $operator $placeholder", array($placeholder => $value)); + $this->handler->query->addWhereExpression(0, "$field $operator $placeholder", [$placeholder => $value]); } } } @@ -326,7 +327,7 @@ public function addFilter() { if ($add_condition) { $field = $this->handler->realField; - $clause = $operator == 'or' ? db_or() : db_and(); + $clause = $operator == 'or' ? new Condition('OR') : new Condition('AND'); foreach ($this->handler->tableAliases as $value => $alias) { $clause->condition("$alias.$field", $value); } diff --git a/core/modules/views/src/Plugin/Block/ViewsBlock.php b/core/modules/views/src/Plugin/Block/ViewsBlock.php index ad8d7c91..34738cdd 100644 --- a/core/modules/views/src/Plugin/Block/ViewsBlock.php +++ b/core/modules/views/src/Plugin/Block/ViewsBlock.php @@ -5,6 +5,7 @@ use Drupal\Component\Utility\Xss; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Element\View; +use Drupal\Core\Entity\EntityInterface; /** * Provides a generic Views block. @@ -23,10 +24,31 @@ class ViewsBlock extends ViewsBlockBase { public function build() { $this->view->display_handler->preBlockBuild($this); + $args = []; + foreach ($this->view->display_handler->getHandlers('argument') as $argument_name => $argument) { + // Initialize the argument value. Work around a limitation in + // \Drupal\views\ViewExecutable::_buildArguments() that skips processing + // later arguments if an argument with default action "ignore" and no + // argument is provided. + $args[$argument_name] = $argument->options['default_action'] == 'ignore' ? 'all' : NULL; + + if (!empty($this->context[$argument_name])) { + if ($value = $this->context[$argument_name]->getContextValue()) { + + // Context values are often entities, but views arguments expect to + // receive just the entity ID, convert it. + if ($value instanceof EntityInterface) { + $value = $value->id(); + } + $args[$argument_name] = $value; + } + } + } + // We ask ViewExecutable::buildRenderable() to avoid creating a render cache // entry for the view output by passing FALSE, because we're going to cache // the whole block instead. - if ($output = $this->view->buildRenderable($this->displayID, [], FALSE)) { + if ($output = $this->view->buildRenderable($this->displayID, array_values($args), FALSE)) { // Before returning the block output, convert it to a renderable array // with contextual links. $this->addContextualLinks($output); @@ -52,7 +74,7 @@ public function build() { return $output; } - return array(); + return []; } /** @@ -95,7 +117,7 @@ public function blockForm($form, FormStateInterface $form_state) { return $this->view->display_handler->blockForm($this, $form, $form_state); } - return array(); + return []; } /** diff --git a/core/modules/views/src/Plugin/Block/ViewsBlockBase.php b/core/modules/views/src/Plugin/Block/ViewsBlockBase.php index 4a814d75..4e3020ca 100644 --- a/core/modules/views/src/Plugin/Block/ViewsBlockBase.php +++ b/core/modules/views/src/Plugin/Block/ViewsBlockBase.php @@ -102,7 +102,7 @@ protected function blockAccess(AccountInterface $account) { * {@inheritdoc} */ public function defaultConfiguration() { - return array('views_label' => ''); + return ['views_label' => '']; } /** @@ -122,39 +122,39 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['#pre_render'][] = '\Drupal\views\Plugin\views\PluginBase::preRenderAddFieldsetMarkup'; // Allow to override the label on the actual page. - $form['views_label_checkbox'] = array( + $form['views_label_checkbox'] = [ '#type' => 'checkbox', '#title' => $this->t('Override title'), '#default_value' => !empty($this->configuration['views_label']), - ); + ]; - $form['views_label_fieldset'] = array( + $form['views_label_fieldset'] = [ '#type' => 'fieldset', - '#states' => array( - 'visible' => array( - array( - ':input[name="settings[views_label_checkbox]"]' => array('checked' => TRUE), - ), - ), - ), - ); - - $form['views_label'] = array( + '#states' => [ + 'visible' => [ + [ + ':input[name="settings[views_label_checkbox]"]' => ['checked' => TRUE], + ], + ], + ], + ]; + + $form['views_label'] = [ '#title' => $this->t('Title'), '#type' => 'textfield', '#default_value' => $this->configuration['views_label'] ?: $this->view->getTitle(), - '#states' => array( - 'visible' => array( - array( - ':input[name="settings[views_label_checkbox]"]' => array('checked' => TRUE), - ), - ), - ), + '#states' => [ + 'visible' => [ + [ + ':input[name="settings[views_label_checkbox]"]' => ['checked' => TRUE], + ], + ], + ], '#fieldset' => 'views_label_fieldset', - ); + ]; if ($this->view->storage->access('edit') && \Drupal::moduleHandler()->moduleExists('views_ui')) { - $form['views_label']['#description'] = $this->t('Changing the title here means it cannot be dynamically altered anymore. (Try changing it directly in @name.)', array(':url' => \Drupal::url('entity.view.edit_display_form', array('view' => $this->view->storage->id(), 'display_id' => $this->displayID)), '@name' => $this->view->storage->label())); + $form['views_label']['#description'] = $this->t('Changing the title here means it cannot be dynamically altered anymore. (Try changing it directly in @name.)', [':url' => \Drupal::url('entity.view.edit_display_form', ['view' => $this->view->storage->id(), 'display_id' => $this->displayID]), '@name' => $this->view->storage->label()]); } else { $form['views_label']['#description'] = $this->t('Changing the title here means it cannot be dynamically altered anymore.'); @@ -194,7 +194,7 @@ protected function addContextualLinks(&$output, $block_type = 'block') { // array, so if the block contains a string of already-rendered markup, // convert it to an array. if (is_string($output)) { - $output = array('#markup' => $output); + $output = ['#markup' => $output]; } // views_add_contextual_links() needs the following information in diff --git a/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php b/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php index 2dd4652a..4b40a0d3 100644 --- a/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php +++ b/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php @@ -1,6 +1,7 @@ view->display_handler->viewExposedFormBlocks(); + // Provide the context for block build and block view alter hooks. + // \Drupal\views\Plugin\Block\ViewsBlock::build() adds the same context in + // \Drupal\views\ViewExecutable::buildRenderable() using + // \Drupal\views\Plugin\views\display\DisplayPluginBase::buildRenderable(). + if (is_array($output) && !empty($output)) { + $output += [ + '#view' => $this->view, + '#display_id' => $this->displayID, + ]; + } // Before returning the block output, convert it to a renderable array with // contextual links. diff --git a/core/modules/views/src/Plugin/DependentWithRemovalPluginInterface.php b/core/modules/views/src/Plugin/DependentWithRemovalPluginInterface.php new file mode 100644 index 00000000..59cb42d4 --- /dev/null +++ b/core/modules/views/src/Plugin/DependentWithRemovalPluginInterface.php @@ -0,0 +1,31 @@ +fetchBaseTables()); - $this->derivatives = array(); + $this->derivatives = []; foreach ($base_tables as $table) { $views_info = $views_data->get($table); if (empty($views_info['table']['wizard_id'])) { - $this->derivatives[$table] = array( + $this->derivatives[$table] = [ 'id' => 'standard', 'base_table' => $table, 'title' => $views_info['table']['base']['title'], 'class' => 'Drupal\views\Plugin\views\wizard\Standard' - ); + ]; } } return parent::getDerivativeDefinitions($base_plugin_definition); diff --git a/core/modules/views/src/Plugin/Derivative/ViewsBlock.php b/core/modules/views/src/Plugin/Derivative/ViewsBlock.php index 2e0c1647..f4da73d4b 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsBlock.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsBlock.php @@ -19,7 +19,7 @@ class ViewsBlock implements ContainerDeriverInterface { * * @var array */ - protected $derivatives = array(); + protected $derivatives = []; /** * The base plugin ID. @@ -82,6 +82,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { $executable = $view->getExecutable(); $executable->initDisplay(); foreach ($executable->displayHandlers as $display) { + /** @var \Drupal\views\Plugin\views\display\DisplayPluginInterface $display */ // Add a block plugin definition for each block display. if (isset($display) && !empty($display->definition['uses_hook_block'])) { $delta = $view->id() . '-' . $display->display['id']; @@ -100,15 +101,24 @@ public function getDerivativeDefinitions($base_plugin_definition) { } } - $this->derivatives[$delta] = array( + $this->derivatives[$delta] = [ 'category' => $display->getOption('block_category'), 'admin_label' => $admin_label, - 'config_dependencies' => array( - 'config' => array( + 'config_dependencies' => [ + 'config' => [ $view->getConfigDependencyName(), - ) - ) - ); + ], + ], + ]; + + // Look for arguments and expose them as context. + foreach ($display->getHandlers('argument') as $argument_name => $argument) { + /** @var \Drupal\views\Plugin\views\argument\ArgumentPluginBase $argument */ + if ($context_definition = $argument->getContextDefinition()) { + $this->derivatives[$delta]['context'][$argument_name] = $context_definition; + } + } + $this->derivatives[$delta] += $base_plugin_definition; } } diff --git a/core/modules/views/src/Plugin/Derivative/ViewsEntityArgumentValidator.php b/core/modules/views/src/Plugin/Derivative/ViewsEntityArgumentValidator.php index 2343c9d5..539eb479 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsEntityArgumentValidator.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsEntityArgumentValidator.php @@ -38,7 +38,7 @@ class ViewsEntityArgumentValidator extends DeriverBase implements ContainerDeriv * * @var array */ - protected $derivatives = array(); + protected $derivatives = []; /** * Constructs an ViewsEntityArgumentValidator object. @@ -72,16 +72,16 @@ public static function create(ContainerInterface $container, $base_plugin_id) { */ public function getDerivativeDefinitions($base_plugin_definition) { $entity_types = $this->entityManager->getDefinitions(); - $this->derivatives = array(); + $this->derivatives = []; foreach ($entity_types as $entity_type_id => $entity_type) { - $this->derivatives[$entity_type_id] = array( + $this->derivatives[$entity_type_id] = [ 'id' => 'entity:' . $entity_type_id, 'provider' => 'views', 'title' => $entity_type->getLabel(), - 'help' => $this->t('Validate @label', array('@label' => $entity_type->getLabel())), + 'help' => $this->t('Validate @label', ['@label' => $entity_type->getLabel()]), 'entity_type' => $entity_type_id, 'class' => $base_plugin_definition['class'], - ); + ]; } return $this->derivatives; diff --git a/core/modules/views/src/Plugin/Derivative/ViewsEntityRow.php b/core/modules/views/src/Plugin/Derivative/ViewsEntityRow.php index 6b36c083..67e7c33f 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsEntityRow.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsEntityRow.php @@ -21,7 +21,7 @@ class ViewsEntityRow implements ContainerDeriverInterface { * * @var array */ - protected $derivatives = array(); + protected $derivatives = []; /** * The base plugin ID that the derivative is for. @@ -89,16 +89,16 @@ public function getDerivativeDefinitions($base_plugin_definition) { foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { // Just add support for entity types which have a views integration. if (($base_table = $entity_type->getBaseTable()) && $this->viewsData->get($base_table) && $this->entityManager->hasHandler($entity_type_id, 'view_builder')) { - $this->derivatives[$entity_type_id] = array( + $this->derivatives[$entity_type_id] = [ 'id' => 'entity:' . $entity_type_id, 'provider' => 'views', 'title' => $entity_type->getLabel(), - 'help' => t('Display the @label', array('@label' => $entity_type->getLabel())), - 'base' => array($entity_type->getDataTable() ?: $entity_type->getBaseTable()), + 'help' => t('Display the @label', ['@label' => $entity_type->getLabel()]), + 'base' => [$entity_type->getDataTable() ?: $entity_type->getBaseTable()], 'entity_type' => $entity_type_id, - 'display_types' => array('normal'), + 'display_types' => ['normal'], 'class' => $base_plugin_definition['class'], - ); + ]; } } diff --git a/core/modules/views/src/Plugin/Derivative/ViewsExposedFilterBlock.php b/core/modules/views/src/Plugin/Derivative/ViewsExposedFilterBlock.php index 50edadcb..fc2e9b89 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsExposedFilterBlock.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsExposedFilterBlock.php @@ -18,7 +18,7 @@ class ViewsExposedFilterBlock implements ContainerDeriverInterface { * * @var array */ - protected $derivatives = array(); + protected $derivatives = []; /** * The view storage. @@ -85,15 +85,15 @@ public function getDerivativeDefinitions($base_plugin_definition) { // Add a block definition for the block. if ($display->usesExposedFormInBlock()) { $delta = $view->id() . '-' . $display->display['id']; - $desc = t('Exposed form: @view-@display_id', array('@view' => $view->id(), '@display_id' => $display->display['id'])); - $this->derivatives[$delta] = array( + $desc = t('Exposed form: @view-@display_id', ['@view' => $view->id(), '@display_id' => $display->display['id']]); + $this->derivatives[$delta] = [ 'admin_label' => $desc, - 'config_dependencies' => array( - 'config' => array( + 'config_dependencies' => [ + 'config' => [ $view->getConfigDependencyName(), - ) - ) - ); + ] + ] + ]; $this->derivatives[$delta] += $base_plugin_definition; } } diff --git a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php index a8149848..bc6400c0 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsLocalTask.php @@ -67,7 +67,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $this->derivatives = array(); + $this->derivatives = []; $view_route_names = $this->state->get('views.view_route_names'); foreach ($this->getApplicableMenuViews() as $pair) { @@ -77,7 +77,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { $executable->setDisplay($display_id); $menu = $executable->display_handler->getOption('menu'); - if (in_array($menu['type'], array('tab', 'default tab'))) { + if (in_array($menu['type'], ['tab', 'default tab'])) { $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; $route_name = $view_route_names[$executable->storage->id() . '.' . $display_id]; @@ -87,11 +87,11 @@ public function getDerivativeDefinitions($base_plugin_definition) { continue; } - $this->derivatives[$plugin_id] = array( + $this->derivatives[$plugin_id] = [ 'route_name' => $route_name, 'weight' => $menu['weight'], 'title' => $menu['title'], - ) + $base_plugin_definition; + ] + $base_plugin_definition; // Default local tasks have themselves as root tab. if ($menu['type'] == 'default tab') { @@ -117,7 +117,7 @@ public function alterLocalTasks(&$local_tasks) { $menu = $executable->display_handler->getOption('menu'); // We already have set the base_route for default tabs. - if (in_array($menu['type'], array('tab'))) { + if (in_array($menu['type'], ['tab'])) { $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id]; diff --git a/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php b/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php index 1095d01f..40dfe44a 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsMenuLink.php @@ -46,7 +46,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $links = array(); + $links = []; $views = Views::getApplicableViews('uses_menu_links'); foreach ($views as $data) { diff --git a/core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php b/core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php index db190529..9911f61a 100644 --- a/core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php +++ b/core/modules/views/src/Plugin/EntityReferenceSelection/ViewsSelection.php @@ -2,17 +2,12 @@ namespace Drupal\views\Plugin\EntityReferenceSelection; -use Drupal\Core\Database\Query\SelectInterface; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase; +use Drupal\Core\Entity\EntityReferenceSelection\SelectionTrait; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\Core\Plugin\PluginBase; -use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; use Drupal\views\Views; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Plugin implementation of the 'selection' entity_reference. @@ -24,87 +19,44 @@ * weight = 0 * ) */ -class ViewsSelection extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface { +class ViewsSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface { - /** - * The entity manager. - * - * @var \Drupal\Core\Entity\EntityManagerInterface - */ - protected $entityManager; - - /** - * The module handler service. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ - protected $moduleHandler; - - /** - * The current user. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $currentUser; + use SelectionTrait; /** - * Constructs a new SelectionBase object. + * The loaded View object. * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin_id for the plugin instance. - * @param mixed $plugin_definition - * The plugin implementation definition. - * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager service. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler service. - * @param \Drupal\Core\Session\AccountInterface $current_user - * The current user. + * @var \Drupal\views\ViewExecutable; */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->entityManager = $entity_manager; - $this->moduleHandler = $module_handler; - $this->currentUser = $current_user; - } + protected $view; /** * {@inheritdoc} */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('entity.manager'), - $container->get('module_handler'), - $container->get('current_user') - ); + public function defaultConfiguration() { + return [ + 'view' => [ + 'view_name' => NULL, + 'display_name' => NULL, + 'arguments' => [], + ], + ] + parent::defaultConfiguration(); } - /** - * The loaded View object. - * - * @var \Drupal\views\ViewExecutable; - */ - protected $view; - /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $selection_handler_settings = $this->configuration['handler_settings']; - $view_settings = !empty($selection_handler_settings['view']) ? $selection_handler_settings['view'] : array(); + $form = parent::buildConfigurationForm($form, $form_state); + + $view_settings = $this->getConfiguration()['view']; $displays = Views::getApplicableViews('entity_reference_display'); // Filter views that list the entity type we want, and group the separate // displays by view. $entity_type = $this->entityManager->getDefinition($this->configuration['target_type']); $view_storage = $this->entityManager->getStorage('view'); - $options = array(); + $options = []; foreach ($displays as $data) { list($view_id, $display_id) = $data; $view = $view_storage->load($view_id); @@ -118,36 +70,36 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta // into 'view_name' and 'view_display' in the final submitted values, so // we massage the data at validate time on the wrapping element (not // ideal). - $form['view']['#element_validate'] = array(array(get_called_class(), 'settingsFormValidate')); + $form['view']['#element_validate'] = [[get_called_class(), 'settingsFormValidate']]; if ($options) { $default = !empty($view_settings['view_name']) ? $view_settings['view_name'] . ':' . $view_settings['display_name'] : NULL; - $form['view']['view_and_display'] = array( + $form['view']['view_and_display'] = [ '#type' => 'select', '#title' => $this->t('View used to select the entities'), '#required' => TRUE, '#options' => $options, '#default_value' => $default, '#description' => '

          ' . $this->t('Choose the view and display that select the entities that can be referenced.
          Only views with a display of type "Entity Reference" are eligible.') . '

          ', - ); + ]; $default = !empty($view_settings['arguments']) ? implode(', ', $view_settings['arguments']) : ''; - $form['view']['arguments'] = array( + $form['view']['arguments'] = [ '#type' => 'textfield', '#title' => $this->t('View arguments'), '#default_value' => $default, '#required' => FALSE, '#description' => $this->t('Provide a comma separated list of arguments to pass to the view.'), - ); + ]; } else { if ($this->currentUser->hasPermission('administer views') && $this->moduleHandler->moduleExists('views_ui')) { - $form['view']['no_view_help'] = array( - '#markup' => '

          ' . $this->t('No eligible views were found. Create a view with an Entity Reference display, or add such a display to an existing view.', array( + $form['view']['no_view_help'] = [ + '#markup' => '

          ' . $this->t('No eligible views were found. Create a view with an Entity Reference display, or add such a display to an existing view.', [ ':create' => Url::fromRoute('views_ui.add')->toString(), ':existing' => Url::fromRoute('entity.view.collection')->toString(), - )) . '

          ', - ); + ]) . '

          ', + ]; } else { $form['view']['no_view_help']['#markup'] = '

          ' . $this->t('No eligible views were found.') . '

          '; @@ -156,16 +108,6 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta return $form; } - /** - * {@inheritdoc} - */ - public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { } - - /** - * {@inheritdoc} - */ - public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { } - /** * Initializes a view. * @@ -184,25 +126,24 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s * Return TRUE if the view was initialized, FALSE otherwise. */ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) { - $handler_settings = $this->configuration['handler_settings']; - $view_name = $handler_settings['view']['view_name']; - $display_name = $handler_settings['view']['display_name']; + $view_name = $this->getConfiguration()['view']['view_name']; + $display_name = $this->getConfiguration()['view']['display_name']; // Check that the view is valid and the display still exists. $this->view = Views::getView($view_name); if (!$this->view || !$this->view->access($display_name)) { - drupal_set_message(t('The reference view %view_name cannot be found.', array('%view_name' => $view_name)), 'warning'); + drupal_set_message(t('The reference view %view_name cannot be found.', ['%view_name' => $view_name]), 'warning'); return FALSE; } $this->view->setDisplay($display_name); // Pass options to the display handler to make them available later. - $entity_reference_options = array( + $entity_reference_options = [ 'match' => $match, 'match_operator' => $match_operator, 'limit' => $limit, 'ids' => $ids, - ); + ]; $this->view->displayHandlers->get($display_name)->setOption('entity_reference_options', $entity_reference_options); return TRUE; } @@ -211,16 +152,15 @@ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $ * {@inheritdoc} */ public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { - $handler_settings = $this->configuration['handler_settings']; - $display_name = $handler_settings['view']['display_name']; - $arguments = $handler_settings['view']['arguments']; - $result = array(); + $display_name = $this->getConfiguration()['view']['display_name']; + $arguments = $this->getConfiguration()['view']['arguments']; + $result = []; if ($this->initializeView($match, $match_operator, $limit)) { // Get the results. $result = $this->view->executeDisplay($display_name, $arguments); } - $return = array(); + $return = []; if ($result) { foreach ($this->view->result as $row) { $entity = $row->_entity; @@ -242,10 +182,9 @@ public function countReferenceableEntities($match = NULL, $match_operator = 'CON * {@inheritdoc} */ public function validateReferenceableEntities(array $ids) { - $handler_settings = $this->configuration['handler_settings']; - $display_name = $handler_settings['view']['display_name']; - $arguments = $handler_settings['view']['arguments']; - $result = array(); + $display_name = $this->getConfiguration()['view']['display_name']; + $arguments = $this->getConfiguration()['view']['arguments']; + $result = []; if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) { // Get the results. $entities = $this->view->executeDisplay($display_name, $arguments); @@ -272,20 +211,15 @@ public static function settingsFormValidate($element, FormStateInterface $form_s // empty array instead. $arguments_string = trim($element['arguments']['#value']); if ($arguments_string === '') { - $arguments = array(); + $arguments = []; } else { // array_map() is called to trim whitespaces from the arguments. $arguments = array_map('trim', explode(',', $arguments_string)); } - $value = array('view_name' => $view, 'display_name' => $display, 'arguments' => $arguments); + $value = ['view_name' => $view, 'display_name' => $display, 'arguments' => $arguments]; $form_state->setValueForElement($element, $value); } - /** - * {@inheritdoc} - */ - public function entityQueryAlter(SelectInterface $query) { } - } diff --git a/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php b/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php index d330cdf3..1699f3e9 100644 --- a/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php +++ b/core/modules/views/src/Plugin/Menu/Form/ViewsMenuLinkForm.php @@ -28,16 +28,16 @@ class ViewsMenuLinkForm extends MenuLinkDefaultForm { public function buildConfigurationForm(array $form, FormStateInterface $form_state) { // Put the title field first. - $form['title'] = array( + $form['title'] = [ '#type' => 'textfield', '#title' => $this->t('Title'), // @todo Ensure that the view is not loaded with a localized title. // https://www.drupal.org/node/2309507 '#default_value' => $this->menuLink->getTitle(), '#weight' => -10, - ); + ]; - $form['description'] = array( + $form['description'] = [ '#type' => 'textfield', '#title' => $this->t('Description'), '#description' => $this->t('Shown when hovering over the menu link.'), @@ -45,7 +45,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta // https://www.drupal.org/node/2309507 '#default_value' => $this->menuLink->getDescription(), '#weight' => -5, - ); + ]; $form += parent::buildConfigurationForm($form, $form_state); @@ -56,10 +56,10 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $id = $view->storage->id(); $label = $view->storage->label(); if ($this->moduleHandler->moduleExists('views_ui')) { - $message = $this->t('This link is provided by the Views module. The path can be changed by editing the view @label', array(':url' => \Drupal::url('entity.view.edit_form', array('view' => $id)), '@label' => $label)); + $message = $this->t('This link is provided by the Views module. The path can be changed by editing the view @label', [':url' => \Drupal::url('entity.view.edit_form', ['view' => $id]), '@label' => $label]); } else { - $message = $this->t('This link is provided by the Views module from view %label.', array('%label' => $label)); + $message = $this->t('This link is provided by the Views module from view %label.', ['%label' => $label]); } $form['info']['#title'] = $message; return $form; diff --git a/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php b/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php index b484c24b..b4f078fc 100644 --- a/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php +++ b/core/modules/views/src/Plugin/Menu/ViewsMenuLink.php @@ -18,7 +18,7 @@ class ViewsMenuLink extends MenuLinkBase implements ContainerFactoryPluginInterf /** * {@inheritdoc} */ - protected $overrideAllowed = array( + protected $overrideAllowed = [ 'menu_name' => 1, 'parent' => 1, 'weight' => 1, @@ -26,7 +26,7 @@ class ViewsMenuLink extends MenuLinkBase implements ContainerFactoryPluginInterf 'enabled' => 1, 'title' => 1, 'description' => 1, - ); + ]; /** * The entity manager. diff --git a/core/modules/views/src/Plugin/ViewsHandlerManager.php b/core/modules/views/src/Plugin/ViewsHandlerManager.php index d918696d..bfc85922 100644 --- a/core/modules/views/src/Plugin/ViewsHandlerManager.php +++ b/core/modules/views/src/Plugin/ViewsHandlerManager.php @@ -59,9 +59,9 @@ public function __construct($handler_type, \Traversable $namespaces, ViewsData $ $this->viewsData = $views_data; $this->handlerType = $handler_type; - $this->defaults = array( + $this->defaults = [ 'plugin_type' => $handler_type, - ); + ]; } /** @@ -86,7 +86,7 @@ public function getHandler($item, $override = NULL) { if (isset($data[$field][$this->handlerType])) { $definition = $data[$field][$this->handlerType]; - foreach (array('group', 'title', 'title short', 'label', 'help', 'real field', 'real table', 'entity type', 'entity field') as $key) { + foreach (['group', 'title', 'title short', 'label', 'help', 'real field', 'real table', 'entity type', 'entity field'] as $key) { if (!isset($definition[$key])) { // First check the field level. if (!empty($data[$field][$key])) { @@ -111,13 +111,13 @@ public function getHandler($item, $override = NULL) { } // Finally, use the 'broken' handler. - return $this->createInstance('broken', array('original_configuration' => $item)); + return $this->createInstance('broken', ['original_configuration' => $item]); } /** * {@inheritdoc} */ - public function createInstance($plugin_id, array $configuration = array()) { + public function createInstance($plugin_id, array $configuration = []) { $instance = parent::createInstance($plugin_id, $configuration); if ($instance instanceof HandlerBase) { $instance->setModuleHandler($this->moduleHandler); @@ -129,7 +129,7 @@ public function createInstance($plugin_id, array $configuration = array()) { /** * {@inheritdoc} */ - public function getFallbackPluginId($plugin_id, array $configuration = array()) { + public function getFallbackPluginId($plugin_id, array $configuration = []) { return 'broken'; } diff --git a/core/modules/views/src/Plugin/ViewsPluginManager.php b/core/modules/views/src/Plugin/ViewsPluginManager.php index a8dadb04..8124d316 100644 --- a/core/modules/views/src/Plugin/ViewsPluginManager.php +++ b/core/modules/views/src/Plugin/ViewsPluginManager.php @@ -31,11 +31,11 @@ public function __construct($type, \Traversable $namespaces, CacheBackendInterfa $plugin_definition_annotation_name = 'Drupal\views\Annotation\Views' . Container::camelize($type); parent::__construct("Plugin/views/$type", $namespaces, $module_handler, 'Drupal\views\Plugin\views\ViewsPluginInterface', $plugin_definition_annotation_name); - $this->defaults += array( + $this->defaults += [ 'parent' => 'parent', 'plugin_type' => $type, 'register_theme' => TRUE, - ); + ]; $this->alterInfo('views_plugins_' . $type); $this->setCacheBackend($cache_backend, "views:$type"); diff --git a/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php b/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php index df129da4..bd7d59ce 100644 --- a/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php +++ b/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php @@ -25,7 +25,7 @@ public function adminLabel($short = FALSE) { * @see \Drupal\views\Plugin\views\PluginBase::defineOptions() */ public function defineOptions() { - return array(); + return []; } /** @@ -55,28 +55,28 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { foreach ($this->definition['original_configuration'] as $key => $value) { if (is_scalar($value)) { - $items[] = SafeMarkup::format('@key: @value', array('@key' => $key, '@value' => $value)); + $items[] = SafeMarkup::format('@key: @value', ['@key' => $key, '@value' => $value]); } } - $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + $description_bottom = t('Enabling the appropriate module may solve this issue. Otherwise, check to see if there is a module update available.'); - $form['description'] = array( + $form['description'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('js-form-item', 'form-item', 'description'), - ), - 'description_top' => array( + '#attributes' => [ + 'class' => ['js-form-item', 'form-item', 'description'], + ], + 'description_top' => [ '#markup' => '

          ' . $description_top . '

          ', - ), - 'detail_list' => array( + ], + 'detail_list' => [ '#theme' => 'item_list', '#items' => $items, - ), - 'description_bottom' => array( + ], + 'description_bottom' => [ '#markup' => '

          ' . $description_bottom . '

          ', - ), - ); + ], + ]; } /** diff --git a/core/modules/views/src/Plugin/views/HandlerBase.php b/core/modules/views/src/Plugin/views/HandlerBase.php index b6b5a5be..4cc4e4bb 100644 --- a/core/modules/views/src/Plugin/views/HandlerBase.php +++ b/core/modules/views/src/Plugin/views/HandlerBase.php @@ -138,12 +138,12 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o protected function defineOptions() { $options = parent::defineOptions(); - $options['id'] = array('default' => ''); - $options['table'] = array('default' => ''); - $options['field'] = array('default' => ''); - $options['relationship'] = array('default' => 'none'); - $options['group_type'] = array('default' => 'group'); - $options['admin_label'] = array('default' => ''); + $options['id'] = ['default' => '']; + $options['table'] = ['default' => '']; + $options['field'] = ['default' => '']; + $options['relationship'] = ['default' => 'none']; + $options['group_type'] = ['default' => 'group']; + $options['admin_label'] = ['default' => '']; return $options; } @@ -156,7 +156,7 @@ public function adminLabel($short = FALSE) { return $this->options['admin_label']; } $title = ($short && isset($this->definition['title short'])) ? $this->definition['title short'] : $this->definition['title']; - return $this->t('@group: @title', array('@group' => $this->definition['group'], '@title' => $title)); + return $this->t('@group: @title', ['@group' => $this->definition['group'], '@title' => $title]); } /** @@ -214,16 +214,16 @@ public function sanitizeValue($value, $type = NULL) { * Transform a string by a certain method. * * @param $string - * The input you want to transform. + * The input you want to transform. * @param $option - * How do you want to transform it, possible values: - * - upper: Uppercase the string. - * - lower: lowercase the string. - * - ucfirst: Make the first char uppercase. - * - ucwords: Make each word in the string uppercase. + * How do you want to transform it, possible values: + * - upper: Uppercase the string. + * - lower: lowercase the string. + * - ucfirst: Make the first char uppercase. + * - ucwords: Make each word in the string uppercase. * * @return string - * The transformed string. + * The transformed string. */ protected function caseTransform($string, $option) { switch ($option) { @@ -248,36 +248,36 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // be moved into one because of the $form_state->getValues() hierarchy. Those // elements can add a #fieldset => 'fieldset_name' property, and they'll // be moved to their fieldset during pre_render. - $form['#pre_render'][] = array(get_class($this), 'preRenderAddFieldsetMarkup'); + $form['#pre_render'][] = [get_class($this), 'preRenderAddFieldsetMarkup']; parent::buildOptionsForm($form, $form_state); - $form['fieldsets'] = array( + $form['fieldsets'] = [ '#type' => 'value', - '#value' => array('more', 'admin_label'), - ); + '#value' => ['more', 'admin_label'], + ]; - $form['admin_label'] = array( + $form['admin_label'] = [ '#type' => 'details', '#title' => $this->t('Administrative title'), '#weight' => 150, - ); - $form['admin_label']['admin_label'] = array( + ]; + $form['admin_label']['admin_label'] = [ '#type' => 'textfield', '#title' => $this->t('Administrative title'), '#description' => $this->t('This title will be displayed on the views edit page instead of the default one. This might be useful if you have the same item twice.'), '#default_value' => $this->options['admin_label'], - '#parents' => array('options', 'admin_label'), - ); + '#parents' => ['options', 'admin_label'], + ]; // This form is long and messy enough that the "Administrative title" option // belongs in "Administrative title" fieldset at the bottom of the form. - $form['more'] = array( + $form['more'] = [ '#type' => 'details', '#title' => $this->t('More'), '#weight' => 200, '#optional' => TRUE, - ); + ]; // Allow to alter the default values brought into the form. // @todo Do we really want to keep this hook. @@ -329,13 +329,13 @@ public function buildGroupByForm(&$form, FormStateInterface $form_state) { $group_types[$id] = $aggregate['title']; } - $form['group_type'] = array( + $form['group_type'] = [ '#type' => 'select', '#title' => $this->t('Aggregation type'), '#default_value' => $this->options['group_type'], '#description' => $this->t('Select the aggregation function to use on this field.'), '#options' => $group_types, - ); + ]; } /** @@ -350,80 +350,84 @@ public function submitGroupByForm(&$form, FormStateInterface $form_state) { * If a handler has 'extra options' it will get a little settings widget and * another form called extra_options. */ - public function hasExtraOptions() { return FALSE; } + public function hasExtraOptions() { + return FALSE; + } /** * Provide defaults for the handler. */ - public function defineExtraOptions(&$option) { } + public function defineExtraOptions(&$option) {} /** * Provide a form for setting options. */ - public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) { } + public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {} /** * Validate the options form. */ - public function validateExtraOptionsForm($form, FormStateInterface $form_state) { } + public function validateExtraOptionsForm($form, FormStateInterface $form_state) {} /** * Perform any necessary changes to the form values prior to storage. * There is no need for this function to actually store the data. */ - public function submitExtraOptionsForm($form, FormStateInterface $form_state) { } + public function submitExtraOptionsForm($form, FormStateInterface $form_state) {} /** * Determine if a handler can be exposed. */ - public function canExpose() { return FALSE; } + public function canExpose() { + return FALSE; + } /** * Set new exposed option defaults when exposed setting is flipped * on. */ - public function defaultExposeOptions() { } + public function defaultExposeOptions() {} /** * Get information about the exposed form for the form renderer. */ - public function exposedInfo() { } + public function exposedInfo() {} /** * Render our chunk of the exposed handler form when selecting */ - public function buildExposedForm(&$form, FormStateInterface $form_state) { } + public function buildExposedForm(&$form, FormStateInterface $form_state) {} /** * Validate the exposed handler form */ - public function validateExposed(&$form, FormStateInterface $form_state) { } + public function validateExposed(&$form, FormStateInterface $form_state) {} /** * Submit the exposed handler form */ - public function submitExposed(&$form, FormStateInterface $form_state) { } + public function submitExposed(&$form, FormStateInterface $form_state) {} /** * Form for exposed handler options. */ - public function buildExposeForm(&$form, FormStateInterface $form_state) { } + public function buildExposeForm(&$form, FormStateInterface $form_state) {} /** * Validate the options form. */ - public function validateExposeForm($form, FormStateInterface $form_state) { } + public function validateExposeForm($form, FormStateInterface $form_state) {} /** * Perform any necessary changes to the form exposes prior to storage. * There is no need for this function to actually store the data. */ - public function submitExposeForm($form, FormStateInterface $form_state) { } + public function submitExposeForm($form, FormStateInterface $form_state) {} /** * Shortcut to display the expose/hide button. */ - public function showExposeButton(&$form, FormStateInterface $form_state) { } + public function showExposeButton(&$form, FormStateInterface $form_state) {} /** * Shortcut to display the exposed options form. @@ -454,7 +458,7 @@ public function showExposeForm(&$form, FormStateInterface $form_state) { public function access(AccountInterface $account) { if (isset($this->definition['access callback']) && function_exists($this->definition['access callback'])) { if (isset($this->definition['access arguments']) && is_array($this->definition['access arguments'])) { - return call_user_func_array($this->definition['access callback'], array($account) + $this->definition['access arguments']); + return call_user_func_array($this->definition['access callback'], [$account] + $this->definition['access arguments']); } return $this->definition['access callback']($account); } @@ -477,7 +481,7 @@ public function query() { /** * {@inheritdoc} */ - public function postExecute(&$values) { } + public function postExecute(&$values) {} /** * Provides a unique placeholders for handlers. @@ -531,13 +535,13 @@ public function ensureMyTable() { /** * {@inheritdoc} */ - public function adminSummary() { } + public function adminSummary() {} /** * Determine if this item is 'exposed', meaning it provides form elements * to let users modify the view. * - * @return TRUE/FALSE + * @return bool */ public function isExposed() { return !empty($this->options['exposed']); @@ -546,24 +550,32 @@ public function isExposed() { /** * Returns TRUE if the exposed filter works like a grouped filter. */ - public function isAGroup() { return FALSE; } + public function isAGroup() { + return FALSE; + } /** * Define if the exposed input has to be submitted multiple times. * This is TRUE when exposed filters grouped are using checkboxes as * widgets. */ - public function multipleExposedInput() { return FALSE; } + public function multipleExposedInput() { + return FALSE; + } /** * Take input from exposed handlers and assign to this handler, if necessary. */ - public function acceptExposedInput($input) { return TRUE; } + public function acceptExposedInput($input) { + return TRUE; + } /** * If set to remember exposed input in the session, store it there. */ - public function storeExposedInput($input, $status) { return TRUE; } + public function storeExposedInput($input, $status) { + return TRUE; + } /** * {@inheritdoc} @@ -587,7 +599,9 @@ public function getJoin() { /** * {@inheritdoc} */ - public function validate() { return array(); } + public function validate() { + return []; + } /** * {@inheritdoc} @@ -703,7 +717,7 @@ public function getEntityType() { */ public static function breakString($str, $force_int = FALSE) { $operator = NULL; - $value = array(); + $value = []; // Determine if the string has 'or' operators (plus signs) or 'and' // operators (commas) and split the string accordingly. @@ -726,7 +740,7 @@ public static function breakString($str, $force_int = FALSE) { $value = array_map('intval', $value); } - return (object) array('value' => $value, 'operator' => $operator); + return (object) ['value' => $value, 'operator' => $operator]; } /** diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php index 6d5aec18..5f9c9788 100644 --- a/core/modules/views/src/Plugin/views/PluginBase.php +++ b/core/modules/views/src/Plugin/views/PluginBase.php @@ -66,7 +66,7 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor * * @var array */ - public $options = array(); + public $options = []; /** * The top object of a view. @@ -155,7 +155,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o * @return array * Returns the options of this handler/plugin. */ - protected function defineOptions() { return array(); } + protected function defineOptions() { + return []; + } /** * Fills up the options of the plugin with defaults. @@ -175,7 +177,7 @@ protected function defineOptions() { return array(); } protected function setOptionDefaults(array &$storage, array $options) { foreach ($options as $option => $definition) { if (isset($definition['contains'])) { - $storage[$option] = array(); + $storage[$option] = []; $this->setOptionDefaults($storage[$option], $definition['contains']); } else { @@ -231,7 +233,7 @@ public function unpackOptions(&$storage, $options, $definition = NULL, $all = TR } if (!isset($storage[$key]) || !is_array($storage[$key])) { - $storage[$key] = array(); + $storage[$key] = []; } // If we're just unpacking our known options, and we're dropping an @@ -242,7 +244,7 @@ public function unpackOptions(&$storage, $options, $definition = NULL, $all = TR continue; } - $this->unpackOptions($storage[$key], $value, isset($definition[$key]['contains']) ? $definition[$key]['contains'] : array(), $all, FALSE); + $this->unpackOptions($storage[$key], $value, isset($definition[$key]['contains']) ? $definition[$key]['contains'] : [], $all, FALSE); } elseif ($all || !empty($definition[$key])) { $storage[$key] = $value; @@ -265,23 +267,23 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // be moved into one because of the $form_state->getValues() hierarchy. Those // elements can add a #fieldset => 'fieldset_name' property, and they'll // be moved to their fieldset during pre_render. - $form['#pre_render'][] = array(get_class($this), 'preRenderAddFieldsetMarkup'); + $form['#pre_render'][] = [get_class($this), 'preRenderAddFieldsetMarkup']; } /** * {@inheritdoc} */ - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} /** * {@inheritdoc} */ - public function submitOptionsForm(&$form, FormStateInterface $form_state) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state) {} /** * {@inheritdoc} */ - public function query() { } + public function query() {} /** * {@inheritdoc} @@ -293,7 +295,9 @@ public function themeFunctions() { /** * {@inheritdoc} */ - public function validate() { return array(); } + public function validate() { + return []; + } /** * {@inheritdoc} @@ -323,8 +327,8 @@ public function usesOptions() { /** * {@inheritdoc} */ - public function globalTokenReplace($string = '', array $options = array()) { - return \Drupal::token()->replace($string, array('view' => $this->view), $options); + public function globalTokenReplace($string = '', array $options = []) { + return \Drupal::token()->replace($string, ['view' => $this->view], $options); } /** @@ -347,11 +351,11 @@ protected function viewsTokenReplace($text, $tokens) { return Xss::filterAdmin($text); } - $twig_tokens = array(); + $twig_tokens = []; foreach ($tokens as $token => $replacement) { // Twig wants a token replacement array stripped of curly-brackets. // Some Views tokens come with curly-braces, others do not. - //@todo: https://www.drupal.org/node/2544392 + // @todo: https://www.drupal.org/node/2544392 if (strpos($token, '{{') !== FALSE) { // Twig wants a token replacement array stripped of curly-brackets. $token = trim(str_replace(['{{', '}}'], '', $token)); @@ -371,11 +375,11 @@ protected function viewsTokenReplace($text, $tokens) { $parts = explode('.', $token); $top = array_shift($parts); assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $top) === 1', 'Tokens need to be valid Twig variables.'); - $token_array = array(array_pop($parts) => $replacement); + $token_array = [array_pop($parts) => $replacement]; foreach (array_reverse($parts) as $key) { // The key could also be numeric (array index) so allow that. assert('is_numeric($key) || (preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $key) === 1)', 'Tokens need to be valid Twig variables.'); - $token_array = array($key => $token_array); + $token_array = [$key => $token_array]; } if (!isset($twig_tokens[$top])) { $twig_tokens[$top] = []; @@ -389,7 +393,7 @@ protected function viewsTokenReplace($text, $tokens) { // Otherwise, Xss::filterAdmin could remove valid Twig syntax before the // template is parsed. - $build = array( + $build = [ '#type' => 'inline_template', '#template' => $text, '#context' => $twig_tokens, @@ -398,7 +402,7 @@ function ($children, $elements) { return Xss::filterAdmin($children); } ], - ); + ]; // Currently you cannot attach assets to tokens with // Renderer::renderPlain(). This may be unnecessarily limiting. Consider @@ -414,15 +418,15 @@ function ($children, $elements) { /** * {@inheritdoc} */ - public function getAvailableGlobalTokens($prepared = FALSE, array $types = array()) { + public function getAvailableGlobalTokens($prepared = FALSE, array $types = []) { $info = \Drupal::token()->getInfo(); // Site and view tokens should always be available. - $types += array('site', 'view'); + $types += ['site', 'view']; $available = array_intersect_key($info['tokens'], array_flip($types)); // Construct the token string for each token. if ($prepared) { - $prepared = array(); + $prepared = []; foreach ($available as $type => $tokens) { foreach (array_keys($tokens) as $token) { $prepared[$type][] = "[$type:$token]"; @@ -439,13 +443,13 @@ public function getAvailableGlobalTokens($prepared = FALSE, array $types = array * {@inheritdoc} */ public function globalTokenForm(&$form, FormStateInterface $form_state) { - $token_items = array(); + $token_items = []; foreach ($this->getAvailableGlobalTokens() as $type => $tokens) { - $item = array( + $item = [ '#markup' => $type, - 'children' => array(), - ); + 'children' => [], + ]; foreach ($tokens as $name => $info) { $item['children'][$name] = "[$type:$name]" . ' - ' . $info['name'] . ': ' . $info['description']; } @@ -453,17 +457,17 @@ public function globalTokenForm(&$form, FormStateInterface $form_state) { $token_items[$type] = $item; } - $form['global_tokens'] = array( + $form['global_tokens'] = [ '#type' => 'details', '#title' => $this->t('Available global token replacements'), - ); - $form['global_tokens']['list'] = array( + ]; + $form['global_tokens']['list'] = [ '#theme' => 'item_list', '#items' => $token_items, - '#attributes' => array( - 'class' => array('global-tokens'), - ), - ); + '#attributes' => [ + 'class' => ['global-tokens'], + ], + ]; } /** @@ -546,7 +550,7 @@ public function getProvider() { protected function listLanguages($flags = LanguageInterface::STATE_ALL, array $current_values = NULL) { $manager = \Drupal::languageManager(); $languages = $manager->getLanguages($flags); - $list = array(); + $list = []; // The entity languages should come first, if requested. if ($flags & PluginBase::INCLUDE_ENTITY) { @@ -582,7 +586,7 @@ protected function listLanguages($flags = LanguageInterface::STATE_ALL, array $c $name = $types_info[$id]['name']; // Surround IDs by '***LANGUAGE_...***', to avoid query collisions. $id = '***LANGUAGE_' . $id . '***'; - $list[$id] = $this->t('@type language selected for page', array('@type' => $name)); + $list[$id] = $this->t('@type language selected for page', ['@type' => $name]); } } if (!empty($current_values)) { @@ -592,7 +596,7 @@ protected function listLanguages($flags = LanguageInterface::STATE_ALL, array $c // add that option too, so it is not lost. If not among the current // values, skip displaying it to avoid user confusion. if (isset($type['name']) && !isset($list[$id]) && in_array($id, $current_values)) { - $list[$id] = $this->t('@type language selected for page', array('@type' => $type['name'])); + $list[$id] = $this->t('@type language selected for page', ['@type' => $type['name']]); } } } @@ -619,7 +623,7 @@ protected function listLanguages($flags = LanguageInterface::STATE_ALL, array $c * the query substitutions needed for the special language types. */ public static function queryLanguageSubstitutions() { - $changes = array(); + $changes = []; $manager = \Drupal::languageManager(); // Handle default language. diff --git a/core/modules/views/src/Plugin/views/PluginInterface.php b/core/modules/views/src/Plugin/views/PluginInterface.php index daa07245..fabbe066 100644 --- a/core/modules/views/src/Plugin/views/PluginInterface.php +++ b/core/modules/views/src/Plugin/views/PluginInterface.php @@ -4,6 +4,9 @@ use Drupal\Component\Plugin\PluginInspectionInterface; +/** + * @deprecated as of Drupal 8.3.x, will be removed in Drupal 9.0.0 + */ interface PluginInterface extends PluginInspectionInterface { } diff --git a/core/modules/views/src/Plugin/views/ViewsPluginInterface.php b/core/modules/views/src/Plugin/views/ViewsPluginInterface.php index e685c4d8..83d9c89b 100644 --- a/core/modules/views/src/Plugin/views/ViewsPluginInterface.php +++ b/core/modules/views/src/Plugin/views/ViewsPluginInterface.php @@ -113,7 +113,7 @@ public function globalTokenForm(&$form, FormStateInterface $form_state); * @return array * An array of available token replacement info or tokens, grouped by type. */ - public function getAvailableGlobalTokens($prepared = FALSE, array $types = array()); + public function getAvailableGlobalTokens($prepared = FALSE, array $types = []); /** * Flattens the structure of form elements. @@ -141,7 +141,7 @@ public static function preRenderFlattenData($form); * @return string * The tokenized string. */ - public function globalTokenReplace($string = '', array $options = array()); + public function globalTokenReplace($string = '', array $options = []); /** * Clears a plugin. diff --git a/core/modules/views/src/Plugin/views/area/AreaPluginBase.php b/core/modules/views/src/Plugin/views/area/AreaPluginBase.php index 2ad7f46b..476a808c 100644 --- a/core/modules/views/src/Plugin/views/area/AreaPluginBase.php +++ b/core/modules/views/src/Plugin/views/area/AreaPluginBase.php @@ -62,7 +62,7 @@ protected function defineOptions() { $this->definition['field'] = !empty($this->definition['field']) ? $this->definition['field'] : ''; $label = !empty($this->definition['label']) ? $this->definition['label'] : $this->definition['field']; $options['admin_label']['default'] = $label; - $options['empty'] = array('default' => FALSE); + $options['empty'] = ['default' => FALSE]; return $options; } @@ -81,11 +81,11 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); if ($form_state->get('type') != 'empty') { - $form['empty'] = array( + $form['empty'] = [ '#type' => 'checkbox', '#title' => $this->t('Display even if view has no result'), '#default_value' => isset($this->options['empty']) ? $this->options['empty'] : 0, - ); + ]; } } @@ -107,7 +107,7 @@ public function preRender(array $results) { * @return array * In any case we need a valid Drupal render array to return. */ - public abstract function render($empty = FALSE); + abstract public function render($empty = FALSE); /** * Does that area have nothing to show. diff --git a/core/modules/views/src/Plugin/views/area/Broken.php b/core/modules/views/src/Plugin/views/area/Broken.php index 549c3062..7bd6cdbd 100644 --- a/core/modules/views/src/Plugin/views/area/Broken.php +++ b/core/modules/views/src/Plugin/views/area/Broken.php @@ -19,7 +19,7 @@ class Broken extends AreaPluginBase { */ public function render($empty = FALSE) { // Simply render nothing by returning an empty render array. - return array(); + return []; } } diff --git a/core/modules/views/src/Plugin/views/area/Entity.php b/core/modules/views/src/Plugin/views/area/Entity.php index 30c24ecb..d073d53f 100644 --- a/core/modules/views/src/Plugin/views/area/Entity.php +++ b/core/modules/views/src/Plugin/views/area/Entity.php @@ -93,12 +93,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['view_mode'] = array( + $form['view_mode'] = [ '#type' => 'select', '#options' => $this->entityManager->getViewModeOptions($this->entityType), '#title' => $this->t('View mode'), '#default_value' => $this->options['view_mode'], - ); + ]; $label = $this->entityManager->getDefinition($this->entityType)->getLabel(); $target = $this->options['target']; @@ -121,12 +121,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#default_value' => $target, ]; - $form['bypass_access'] = array( + $form['bypass_access'] = [ '#type' => 'checkbox', '#title' => $this->t('Bypass access checks'), '#description' => $this->t('If enabled, access permissions for rendering the entity are not checked.'), '#default_value' => !empty($this->options['bypass_access']), - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/area/HTTPStatusCode.php b/core/modules/views/src/Plugin/views/area/HTTPStatusCode.php index 4f6667a5..5d3f42ad 100644 --- a/core/modules/views/src/Plugin/views/area/HTTPStatusCode.php +++ b/core/modules/views/src/Plugin/views/area/HTTPStatusCode.php @@ -20,7 +20,7 @@ class HTTPStatusCode extends AreaPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['status_code'] = array('default' => 200); + $options['status_code'] = ['default' => 200]; return $options; } @@ -35,29 +35,29 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $options = Response::$statusTexts; // Move 403/404/500 to the top. - $options = array( + $options = [ '404' => $options['404'], '403' => $options['403'], '500' => $options['500'], - ) + $options; + ] + $options; // Add the HTTP status code, so it's easier for people to find it. - array_walk($options, function($title, $code) use(&$options) { - $options[$code] = $this->t('@code (@title)', array('@code' => $code, '@title' => $title)); + array_walk($options, function ($title, $code) use (&$options) { + $options[$code] = $this->t('@code (@title)', ['@code' => $code, '@title' => $title]); }); - $form['status_code'] = array( + $form['status_code'] = [ '#title' => $this->t('HTTP status code'), '#type' => 'select', '#default_value' => $this->options['status_code'], '#options' => $options, - ); + ]; } /** * {@inheritdoc} */ - function render($empty = FALSE) { + public function render($empty = FALSE) { if (!$empty || !empty($this->options['empty'])) { $build['#attached']['http_header'][] = ['Status', $this->options['status_code']]; return $build; diff --git a/core/modules/views/src/Plugin/views/area/Messages.php b/core/modules/views/src/Plugin/views/area/Messages.php index 37df125a..c26b995e 100644 --- a/core/modules/views/src/Plugin/views/area/Messages.php +++ b/core/modules/views/src/Plugin/views/area/Messages.php @@ -26,11 +26,11 @@ protected function defineOptions() { */ public function render($empty = FALSE) { if (!$empty || !empty($this->options['empty'])) { - return array( + return [ '#type' => 'status_messages', - ); + ]; } - return array(); + return []; } } diff --git a/core/modules/views/src/Plugin/views/area/Result.php b/core/modules/views/src/Plugin/views/area/Result.php index d8139cbe..2bbd23bb 100644 --- a/core/modules/views/src/Plugin/views/area/Result.php +++ b/core/modules/views/src/Plugin/views/area/Result.php @@ -22,9 +22,9 @@ class Result extends AreaPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['content'] = array( + $options['content'] = [ 'default' => $this->t('Displaying @start - @end of @total'), - ); + ]; return $options; } @@ -34,9 +34,9 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $item_list = array( + $item_list = [ '#theme' => 'item_list', - '#items' => array( + '#items' => [ '@start -- the initial record number in the set', '@end -- the last record number in the set', '@total -- the total records in the set', @@ -45,16 +45,16 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '@current_page -- the current page number', '@current_record_count -- the current page record count', '@page_count -- the total page count', - ), - ); - $list = drupal_render($item_list); - $form['content'] = array( + ], + ]; + $list = \Drupal::service('renderer')->render($item_list); + $form['content'] = [ '#title' => $this->t('Display'), '#type' => 'textarea', '#rows' => 3, '#default_value' => $this->options['content'], '#description' => $this->t('You may use HTML code in this field. The following tokens are supported:') . $list, - ); + ]; } /** @@ -72,7 +72,7 @@ public function query() { public function render($empty = FALSE) { // Must have options and does not work on summaries. if (!isset($this->options['content']) || $this->view->style_plugin instanceof DefaultSummary) { - return array(); + return []; } $output = ''; $format = $this->options['content']; @@ -83,9 +83,13 @@ public function render($empty = FALSE) { // Not every view has total_rows set, use view->result instead. $total = isset($this->view->total_rows) ? $this->view->total_rows : count($this->view->result); $label = Html::escape($this->view->storage->label()); + // If there is no result the "start" and "current_record_count" should be + // equal to 0. To have the same calculation logic, we use a "start offset" + // to handle all the cases. + $start_offset = empty($total) ? 0 : 1; if ($per_page === 0) { $page_count = 1; - $start = 1; + $start = $start_offset; $end = $total; } else { @@ -94,10 +98,10 @@ public function render($empty = FALSE) { if ($total_count > $total) { $total_count = $total; } - $start = ($current_page - 1) * $per_page + 1; + $start = ($current_page - 1) * $per_page + $start_offset; $end = $total_count; } - $current_record_count = ($end - $start) + 1; + $current_record_count = ($end - $start) + $start_offset; // Get the search information. $replacements = []; $replacements['@start'] = $start; @@ -109,13 +113,13 @@ public function render($empty = FALSE) { $replacements['@current_record_count'] = $current_record_count; $replacements['@page_count'] = $page_count; // Send the output. - if (!empty($total)) { + if (!empty($total) || !empty($this->options['empty'])) { $output .= Xss::filterAdmin(str_replace(array_keys($replacements), array_values($replacements), $format)); } // Return as render array. - return array( + return [ '#markup' => $output, - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/area/Text.php b/core/modules/views/src/Plugin/views/area/Text.php index cee182fa..aafcbf20 100644 --- a/core/modules/views/src/Plugin/views/area/Text.php +++ b/core/modules/views/src/Plugin/views/area/Text.php @@ -18,12 +18,12 @@ class Text extends TokenizeAreaPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['content'] = array( - 'contains' => array( - 'value' => array('default' => ''), - 'format' => array('default' => NULL), - ), - ); + $options['content'] = [ + 'contains' => [ + 'value' => ['default' => ''], + 'format' => ['default' => NULL], + ], + ]; return $options; } @@ -33,14 +33,25 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['content'] = array( + $form['content'] = [ '#title' => $this->t('Content'), '#type' => 'text_format', '#default_value' => $this->options['content']['value'], '#rows' => 6, '#format' => isset($this->options['content']['format']) ? $this->options['content']['format'] : filter_default_format(), '#editor' => FALSE, - ); + ]; + } + + /** + * {@inheritdoc} + */ + public function preQuery() { + $content = $this->options['content']['value']; + // Check for tokens that require a total row count. + if (strpos($content, '[view:page-count]') !== FALSE || strpos($content, '[view:total-rows]') !== FALSE) { + $this->view->get_total_rows = TRUE; + } } /** @@ -49,14 +60,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function render($empty = FALSE) { $format = isset($this->options['content']['format']) ? $this->options['content']['format'] : filter_default_format(); if (!$empty || !empty($this->options['empty'])) { - return array( + return [ '#type' => 'processed_text', '#text' => $this->tokenizeValue($this->options['content']['value']), '#format' => $format, - ); + ]; } - return array(); + return []; } } diff --git a/core/modules/views/src/Plugin/views/area/TextCustom.php b/core/modules/views/src/Plugin/views/area/TextCustom.php index 0eeabaa9..56e963dd 100644 --- a/core/modules/views/src/Plugin/views/area/TextCustom.php +++ b/core/modules/views/src/Plugin/views/area/TextCustom.php @@ -18,7 +18,7 @@ class TextCustom extends TokenizeAreaPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['content'] = array('default' => ''); + $options['content'] = ['default' => '']; return $options; } @@ -28,12 +28,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['content'] = array( + $form['content'] = [ '#title' => $this->t('Content'), '#type' => 'textarea', '#default_value' => $this->options['content'], '#rows' => 6, - ); + ]; } /** @@ -41,12 +41,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function render($empty = FALSE) { if (!$empty || !empty($this->options['empty'])) { - return array( + return [ '#markup' => $this->renderTextarea($this->options['content']), - ); + ]; } - return array(); + return []; } /** diff --git a/core/modules/views/src/Plugin/views/area/Title.php b/core/modules/views/src/Plugin/views/area/Title.php index 85e47881..d6139e0a 100644 --- a/core/modules/views/src/Plugin/views/area/Title.php +++ b/core/modules/views/src/Plugin/views/area/Title.php @@ -18,7 +18,7 @@ class Title extends AreaPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['title'] = array('default' => ''); + $options['title'] = ['default' => '']; return $options; } @@ -28,12 +28,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['title'] = array( + $form['title'] = [ '#type' => 'textfield', '#title' => $this->t('Overridden title'), '#default_value' => $this->options['title'], '#description' => $this->t('Override the title of this view when it is empty. The available global tokens below can be used here.'), - ); + ]; // Don't use the AreaPluginBase tokenForm method, we don't want row tokens. $this->globalTokenForm($form, $form_state); @@ -57,7 +57,7 @@ public function preRender(array $results) { */ public function render($empty = FALSE) { // Do nothing for this handler by returning an empty render array. - return array(); + return []; } } diff --git a/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php b/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php index e8833787..1e004797 100644 --- a/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php +++ b/core/modules/views/src/Plugin/views/area/TokenizeAreaPluginBase.php @@ -21,7 +21,7 @@ abstract class TokenizeAreaPluginBase extends AreaPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['tokenize'] = array('default' => FALSE); + $options['tokenize'] = ['default' => FALSE]; return $options; } @@ -39,14 +39,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * Adds tokenization form elements. */ public function tokenForm(&$form, FormStateInterface $form_state) { - $form['tokenize'] = array( + $form['tokenize'] = [ '#type' => 'checkbox', '#title' => $this->t('Use replacement tokens from the first row'), '#default_value' => $this->options['tokenize'], - ); + ]; // Get a list of the available fields and arguments for token replacement. - $options = array(); + $options = []; $optgroup_arguments = (string) t('Arguments'); $optgroup_fields = (string) t('Fields'); foreach ($this->view->display_handler->getHandlers('field') as $field => $handler) { @@ -54,35 +54,35 @@ public function tokenForm(&$form, FormStateInterface $form_state) { } foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) { - $options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', array('@argument' => $handler->adminLabel())); - $options[$optgroup_arguments]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', array('@argument' => $handler->adminLabel())); + $options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', ['@argument' => $handler->adminLabel()]); + $options[$optgroup_arguments]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', ['@argument' => $handler->adminLabel()]); } if (!empty($options)) { - $form['tokens'] = array( + $form['tokens'] = [ '#type' => 'details', '#title' => $this->t('Replacement patterns'), '#open' => TRUE, '#id' => 'edit-options-token-help', - '#states' => array( - 'visible' => array( - ':input[name="options[tokenize]"]' => array('checked' => TRUE), - ), - ), - ); - $form['tokens']['help'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[tokenize]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['tokens']['help'] = [ '#markup' => '

          ' . $this->t('The following tokens are available. You may use Twig syntax in this field.') . '

          ', - ); + ]; foreach (array_keys($options) as $type) { if (!empty($options[$type])) { - $items = array(); + $items = []; foreach ($options[$type] as $key => $value) { $items[] = $key . ' == ' . $value; } - $form['tokens'][$type]['tokens'] = array( + $form['tokens'][$type]['tokens'] = [ '#theme' => 'item_list', '#items' => $items, - ); + ]; } } } diff --git a/core/modules/views/src/Plugin/views/area/View.php b/core/modules/views/src/Plugin/views/area/View.php index 12f417cf..832e2318 100644 --- a/core/modules/views/src/Plugin/views/area/View.php +++ b/core/modules/views/src/Plugin/views/area/View.php @@ -66,8 +66,8 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['view_to_insert'] = array('default' => ''); - $options['inherit_arguments'] = array('default' => FALSE); + $options['view_to_insert'] = ['default' => '']; + $options['inherit_arguments'] = ['default' => FALSE]; return $options; } @@ -79,22 +79,22 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $view_display = $this->view->storage->id() . ':' . $this->view->current_display; - $options = array('' => $this->t('-Select-')); + $options = ['' => $this->t('-Select-')]; $options += Views::getViewsAsOptions(FALSE, 'all', $view_display, FALSE, TRUE); - $form['view_to_insert'] = array( + $form['view_to_insert'] = [ '#type' => 'select', '#title' => $this->t('View to insert'), '#default_value' => $this->options['view_to_insert'], '#description' => $this->t('The view to insert into this area.'), '#options' => $options, - ); + ]; - $form['inherit_arguments'] = array( + $form['inherit_arguments'] = [ '#type' => 'checkbox', '#title' => $this->t('Inherit contextual filters'), '#default_value' => $this->options['inherit_arguments'], '#description' => $this->t('If checked, this view will receive the same contextual filters as its parent.'), - ); + ]; } /** @@ -107,7 +107,7 @@ public function render($empty = FALSE) { $view = $this->viewStorage->load($view_name)->getExecutable(); if (empty($view) || !$view->access($display_id)) { - return array(); + return []; } $view->setDisplay($display_id); @@ -118,7 +118,7 @@ public function render($empty = FALSE) { // Check if the view is part of the parent views of this view $search = "$view_name:$display_id"; if (in_array($search, $this->view->parent_views)) { - drupal_set_message(t("Recursion detected in view @view display @display.", array('@view' => $view_name, '@display' => $display_id)), 'error'); + drupal_set_message(t("Recursion detected in view @view display @display.", ['@view' => $view_name, '@display' => $display_id]), 'error'); } else { if (!empty($this->options['inherit_arguments']) && !empty($this->view->args)) { @@ -131,7 +131,7 @@ public function render($empty = FALSE) { return $output; } } - return array(); + return []; } /** diff --git a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php index db75a675..9bcd5ba6 100644 --- a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php +++ b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php @@ -105,7 +105,7 @@ public function exceptionTitle() { /** * Determine if the argument needs a style plugin. * - * @return TRUE/FALSE + * @return bool */ public function needsStylePlugin() { $info = $this->defaultActions($this->options['default_action']); @@ -116,35 +116,35 @@ public function needsStylePlugin() { protected function defineOptions() { $options = parent::defineOptions(); - $options['default_action'] = array('default' => 'ignore'); - $options['exception'] = array( - 'contains' => array( - 'value' => array('default' => 'all'), - 'title_enable' => array('default' => FALSE), - 'title' => array('default' => 'All'), - ), - ); - $options['title_enable'] = array('default' => FALSE); - $options['title'] = array('default' => ''); - $options['default_argument_type'] = array('default' => 'fixed'); - $options['default_argument_options'] = array('default' => array()); - $options['default_argument_skip_url'] = array('default' => FALSE); - $options['summary_options'] = array('default' => array()); - $options['summary'] = array( - 'contains' => array( - 'sort_order' => array('default' => 'asc'), - 'number_of_records' => array('default' => 0), - 'format' => array('default' => 'default_summary'), - ), - ); - $options['specify_validation'] = array('default' => FALSE); - $options['validate'] = array( - 'contains' => array( - 'type' => array('default' => 'none'), - 'fail' => array('default' => 'not found'), - ), - ); - $options['validate_options'] = array('default' => array()); + $options['default_action'] = ['default' => 'ignore']; + $options['exception'] = [ + 'contains' => [ + 'value' => ['default' => 'all'], + 'title_enable' => ['default' => FALSE], + 'title' => ['default' => 'All'], + ], + ]; + $options['title_enable'] = ['default' => FALSE]; + $options['title'] = ['default' => '']; + $options['default_argument_type'] = ['default' => 'fixed']; + $options['default_argument_options'] = ['default' => []]; + $options['default_argument_skip_url'] = ['default' => FALSE]; + $options['summary_options'] = ['default' => []]; + $options['summary'] = [ + 'contains' => [ + 'sort_order' => ['default' => 'asc'], + 'number_of_records' => ['default' => 0], + 'format' => ['default' => 'default_summary'], + ], + ]; + $options['specify_validation'] = ['default' => FALSE]; + $options['validate'] = [ + 'contains' => [ + 'type' => ['default' => 'none'], + 'fail' => ['default' => 'not found'], + ], + ]; + $options['validate_options'] = ['default' => []]; return $options; } @@ -154,68 +154,68 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $argument_text = $this->view->display_handler->getArgumentText(); - $form['#pre_render'][] = array(get_class($this), 'preRenderMoveArgumentOptions'); + $form['#pre_render'][] = [get_class($this), 'preRenderMoveArgumentOptions']; - $form['description'] = array( + $form['description'] = [ '#markup' => $argument_text['description'], - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('description')), - ); + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['description']], + ]; - $form['no_argument'] = array( + $form['no_argument'] = [ '#type' => 'details', '#title' => $argument_text['filter value not present'], '#open' => TRUE, - ); + ]; // Everything in the details is floated, so the last element needs to // clear those floats. - $form['no_argument']['clearfix'] = array( + $form['no_argument']['clearfix'] = [ '#weight' => 1000, '#markup' => '
          ', - ); - $form['default_action'] = array( + ]; + $form['default_action'] = [ '#title' => $this->t('Default actions'), '#title_display' => 'invisible', '#type' => 'radios', - '#process' => array(array($this, 'processContainerRadios')), + '#process' => [[$this, 'processContainerRadios']], '#default_value' => $this->options['default_action'], '#fieldset' => 'no_argument', - ); + ]; - $form['exception'] = array( + $form['exception'] = [ '#type' => 'details', '#title' => $this->t('Exceptions'), '#fieldset' => 'no_argument', - ); - $form['exception']['value'] = array( + ]; + $form['exception']['value'] = [ '#type' => 'textfield', '#title' => $this->t('Exception value'), '#size' => 20, '#default_value' => $this->options['exception']['value'], '#description' => $this->t('If this value is received, the filter will be ignored; i.e, "all values"'), - ); - $form['exception']['title_enable'] = array( + ]; + $form['exception']['title_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Override title'), '#default_value' => $this->options['exception']['title_enable'], - ); - $form['exception']['title'] = array( + ]; + $form['exception']['title'] = [ '#type' => 'textfield', '#title' => $this->t('Override title'), '#title_display' => 'invisible', '#size' => 20, '#default_value' => $this->options['exception']['title'], '#description' => $this->t('Override the view and other argument titles. You may use Twig syntax in this field as well as the "arguments" and "raw_arguments" arrays.'), - '#states' => array( - 'visible' => array( - ':input[name="options[exception][title_enable]"]' => array('checked' => TRUE), - ), - ), - ); - - $options = array(); + '#states' => [ + 'visible' => [ + ':input[name="options[exception][title_enable]"]' => ['checked' => TRUE], + ], + ], + ]; + + $options = []; $defaults = $this->defaultActions(); - $validate_options = array(); + $validate_options = []; foreach ($defaults as $id => $info) { $options[$id] = $info['title']; if (empty($info['default only'])) { @@ -227,30 +227,30 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } $form['default_action']['#options'] = $options; - $form['argument_present'] = array( + $form['argument_present'] = [ '#type' => 'details', '#title' => $argument_text['filter value present'], '#open' => TRUE, - ); - $form['title_enable'] = array( + ]; + $form['title_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Override title'), '#default_value' => $this->options['title_enable'], '#fieldset' => 'argument_present', - ); - $form['title'] = array( + ]; + $form['title'] = [ '#type' => 'textfield', '#title' => $this->t('Provide title'), '#title_display' => 'invisible', '#default_value' => $this->options['title'], '#description' => $this->t('Override the view and other argument titles. You may use Twig syntax in this field.'), - '#states' => array( - 'visible' => array( - ':input[name="options[title_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[title_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'argument_present', - ); + ]; $output = $this->getTokenHelp(); $form['token_help'] = [ @@ -269,29 +269,29 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { ], ]; - $form['specify_validation'] = array( + $form['specify_validation'] = [ '#type' => 'checkbox', '#title' => $this->t('Specify validation criteria'), '#default_value' => $this->options['specify_validation'], '#fieldset' => 'argument_present', - ); + ]; - $form['validate'] = array( + $form['validate'] = [ '#type' => 'container', '#fieldset' => 'argument_present', - ); + ]; // Validator options include derivatives with :. These are sanitized for js // and reverted on submission. - $form['validate']['type'] = array( + $form['validate']['type'] = [ '#type' => 'select', '#title' => $this->t('Validator'), '#default_value' => static::encodeValidatorId($this->options['validate']['type']), - '#states' => array( - 'visible' => array( - ':input[name="options[specify_validation]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[specify_validation]"]' => ['checked' => TRUE], + ], + ], + ]; $plugins = Views::pluginManager('argument_validator')->getDefinitions(); foreach ($plugins as $id => $info) { @@ -320,21 +320,22 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if ($plugin->access() || $this->options['validate']['type'] == $id) { // Sanitize ID for js. $sanitized_id = static::encodeValidatorId($id); - $form['validate']['options'][$sanitized_id] = array( + $form['validate']['options'][$sanitized_id] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#type' => 'item', // Even if the plugin has no options add the key to the form_state. - '#input' => TRUE, // trick it into checking input to make #process run - '#states' => array( - 'visible' => array( - ':input[name="options[specify_validation]"]' => array('checked' => TRUE), - ':input[name="options[validate][type]"]' => array('value' => $sanitized_id), - ), - ), + // trick it into checking input to make #process run. + '#input' => TRUE, + '#states' => [ + 'visible' => [ + ':input[name="options[specify_validation]"]' => ['checked' => TRUE], + ':input[name="options[validate][type]"]' => ['value' => $sanitized_id], + ], + ], '#id' => 'edit-options-validate-options-' . $sanitized_id, - '#default_value' => array(), - ); + '#default_value' => [], + ]; $plugin->buildOptionsForm($form['validate']['options'][$sanitized_id], $form_state); $validate_types[$sanitized_id] = $info['title']; } @@ -345,18 +346,18 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { asort($validate_types); $form['validate']['type']['#options'] = $validate_types; - $form['validate']['fail'] = array( + $form['validate']['fail'] = [ '#type' => 'select', '#title' => $this->t('Action to take if filter value does not validate'), '#default_value' => $this->options['validate']['fail'], '#options' => $validate_options, - '#states' => array( - 'visible' => array( - ':input[name="options[specify_validation]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[specify_validation]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'argument_present', - ); + ]; } /** @@ -370,8 +371,8 @@ protected function getTokenHelp() { foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) { /** @var \Drupal\views\Plugin\views\argument\ArgumentPluginBase $handler */ - $options[(string) t('Arguments')]["{{ arguments.$arg }}"] = $this->t('@argument title', array('@argument' => $handler->adminLabel())); - $options[(string) t('Arguments')]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', array('@argument' => $handler->adminLabel())); + $options[(string) t('Arguments')]["{{ arguments.$arg }}"] = $this->t('@argument title', ['@argument' => $handler->adminLabel()]); + $options[(string) t('Arguments')]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', ['@argument' => $handler->adminLabel()]); } // We have some options, so make a list. @@ -381,14 +382,14 @@ protected function getTokenHelp() { ]; foreach (array_keys($options) as $type) { if (!empty($options[$type])) { - $items = array(); + $items = []; foreach ($options[$type] as $key => $value) { $items[] = $key . ' == ' . $value; } - $item_list = array( + $item_list = [ '#theme' => 'item_list', '#items' => $items, - ); + ]; $output[] = $item_list; } } @@ -488,38 +489,40 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { * Override this method to provide additional (or fewer) default behaviors. */ protected function defaultActions($which = NULL) { - $defaults = array( - 'ignore' => array( + $defaults = [ + 'ignore' => [ 'title' => $this->t('Display all results for the specified field'), 'method' => 'defaultIgnore', - ), - 'default' => array( + ], + 'default' => [ 'title' => $this->t('Provide default value'), 'method' => 'defaultDefault', 'form method' => 'defaultArgumentForm', 'has default argument' => TRUE, - 'default only' => TRUE, // this can only be used for missing argument, not validation failure - ), - 'not found' => array( + // This can only be used for missing argument, not validation failure. + 'default only' => TRUE, + ], + 'not found' => [ 'title' => $this->t('Hide view'), 'method' => 'defaultNotFound', - 'hard fail' => TRUE, // This is a hard fail condition - ), - 'summary' => array( + // This is a hard fail condition. + 'hard fail' => TRUE, + ], + 'summary' => [ 'title' => $this->t('Display a summary'), 'method' => 'defaultSummary', 'form method' => 'defaultSummaryForm', 'style plugin' => TRUE, - ), - 'empty' => array( + ], + 'empty' => [ 'title' => $this->t('Display contents of "No results found"'), 'method' => 'defaultEmpty', - ), - 'access denied' => array( + ], + 'access denied' => [ 'title' => $this->t('Display "Access Denied"'), 'method' => 'defaultAccessDenied', - ), - ); + ], + ]; if ($this->view->display_handler->hasPath()) { $defaults['not found']['title'] = $this->t('Show "Page not found"'); @@ -541,31 +544,31 @@ protected function defaultActions($which = NULL) { */ public function defaultArgumentForm(&$form, FormStateInterface $form_state) { $plugins = Views::pluginManager('argument_default')->getDefinitions(); - $options = array(); + $options = []; - $form['default_argument_skip_url'] = array( + $form['default_argument_skip_url'] = [ '#type' => 'checkbox', '#title' => $this->t('Skip default argument for view URL'), '#default_value' => $this->options['default_argument_skip_url'], '#description' => $this->t('Select whether to include this default argument when constructing the URL for this view. Skipping default arguments is useful e.g. in the case of feeds.') - ); + ]; - $form['default_argument_type'] = array( + $form['default_argument_type'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#type' => 'select', '#id' => 'edit-options-default-argument-type', '#title' => $this->t('Type'), '#default_value' => $this->options['default_argument_type'], - '#states' => array( - 'visible' => array( - ':input[name="options[default_action]"]' => array('value' => 'default'), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[default_action]"]' => ['value' => 'default'], + ], + ], // Views custom key, moves this element to the appropriate container // under the radio button. '#argument_option' => 'default', - ); + ]; foreach ($plugins as $id => $info) { if (!empty($info['no_ui'])) { @@ -575,21 +578,21 @@ public function defaultArgumentForm(&$form, FormStateInterface $form_state) { if ($plugin) { if ($plugin->access() || $this->options['default_argument_type'] == $id) { $form['argument_default']['#argument_option'] = 'default'; - $form['argument_default'][$id] = array( + $form['argument_default'][$id] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#id' => 'edit-options-argument-default-options-' . $id, '#type' => 'item', // Even if the plugin has no options add the key to the form_state. '#input' => TRUE, - '#states' => array( - 'visible' => array( - ':input[name="options[default_action]"]' => array('value' => 'default'), - ':input[name="options[default_argument_type]"]' => array('value' => $id), - ), - ), - '#default_value' => array(), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[default_action]"]' => ['value' => 'default'], + ':input[name="options[default_argument_type]"]' => ['value' => $id], + ], + ], + '#default_value' => [], + ]; $options[$id] = $info['title']; $plugin->buildOptionsForm($form['argument_default'][$id], $form_state); } @@ -606,8 +609,8 @@ public function defaultArgumentForm(&$form, FormStateInterface $form_state) { */ public function defaultSummaryForm(&$form, FormStateInterface $form_state) { $style_plugins = Views::pluginManager('style')->getDefinitions(); - $summary_plugins = array(); - $format_options = array(); + $summary_plugins = []; + $format_options = []; foreach ($style_plugins as $key => $plugin) { if (isset($plugin['display_types']) && in_array('summary', $plugin['display_types'])) { $summary_plugins[$key] = $plugin; @@ -615,48 +618,48 @@ public function defaultSummaryForm(&$form, FormStateInterface $form_state) { } } - $form['summary'] = array( + $form['summary'] = [ // Views custom key, moves this element to the appropriate container // under the radio button. '#argument_option' => 'summary', - ); - $form['summary']['sort_order'] = array( + ]; + $form['summary']['sort_order'] = [ '#type' => 'radios', '#title' => $this->t('Sort order'), - '#options' => array('asc' => $this->t('Ascending'), 'desc' => $this->t('Descending')), + '#options' => ['asc' => $this->t('Ascending'), 'desc' => $this->t('Descending')], '#default_value' => $this->options['summary']['sort_order'], - '#states' => array( - 'visible' => array( - ':input[name="options[default_action]"]' => array('value' => 'summary'), - ), - ), - ); - $form['summary']['number_of_records'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[default_action]"]' => ['value' => 'summary'], + ], + ], + ]; + $form['summary']['number_of_records'] = [ '#type' => 'radios', '#title' => $this->t('Sort by'), '#default_value' => $this->options['summary']['number_of_records'], - '#options' => array( + '#options' => [ 0 => $this->getSortName(), 1 => $this->t('Number of records') - ), - '#states' => array( - 'visible' => array( - ':input[name="options[default_action]"]' => array('value' => 'summary'), - ), - ), - ); - - $form['summary']['format'] = array( + ], + '#states' => [ + 'visible' => [ + ':input[name="options[default_action]"]' => ['value' => 'summary'], + ], + ], + ]; + + $form['summary']['format'] = [ '#type' => 'radios', '#title' => $this->t('Format'), '#options' => $format_options, '#default_value' => $this->options['summary']['format'], - '#states' => array( - 'visible' => array( - ':input[name="options[default_action]"]' => array('value' => 'summary'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[default_action]"]' => ['value' => 'summary'], + ], + ], + ]; foreach ($summary_plugins as $id => $info) { $plugin = $this->getPlugin('style', $id); @@ -664,20 +667,21 @@ public function defaultSummaryForm(&$form, FormStateInterface $form_state) { continue; } if ($plugin) { - $form['summary']['options'][$id] = array( + $form['summary']['options'][$id] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#id' => 'edit-options-summary-options-' . $id, '#type' => 'item', - '#input' => TRUE, // trick it into checking input to make #process run - '#states' => array( - 'visible' => array( - ':input[name="options[default_action]"]' => array('value' => 'summary'), - ':input[name="options[summary][format]"]' => array('value' => $id), - ), - ), - '#default_value' => array(), - ); + // Trick it into checking input to make #process run. + '#input' => TRUE, + '#states' => [ + 'visible' => [ + ':input[name="options[default_action]"]' => ['value' => 'summary'], + ':input[name="options[summary][format]"]' => ['value' => $id], + ], + ], + '#default_value' => [], + ]; $options[$id] = $info['title']; $plugin->buildOptionsForm($form['summary']['options'][$id], $form_state); } @@ -703,7 +707,7 @@ public function defaultAction($info = NULL) { } if (!empty($info['method args'])) { - return call_user_func_array(array(&$this, $info['method']), $info['method args']); + return call_user_func_array([&$this, $info['method']], $info['method args']); } else { return $this->{$info['method']}(); @@ -760,7 +764,7 @@ public function defaultEmpty() { // We return with no query; this will force the empty text. $this->view->built = TRUE; $this->view->executed = TRUE; - $this->view->result = array(); + $this->view->result = []; return FALSE; } @@ -775,7 +779,7 @@ protected function defaultDefault() { /** * Determine if the argument is set to provide a default argument. */ - function hasDefaultArgument() { + public function hasDefaultArgument() { $info = $this->defaultActions($this->options['default_action']); return !empty($info['has default argument']); } @@ -897,7 +901,7 @@ public function summaryBasics($count_field = TRUE) { // Add the number of nodes counter $distinct = ($this->view->display_handler->getOption('distinct') && empty($this->query->no_distinct)); - $count_alias = $this->query->addField($this->view->storage->get('base_table'), $this->view->storage->get('base_field'), 'num_records', array('count' => TRUE, 'distinct' => $distinct)); + $count_alias = $this->query->addField($this->view->storage->get('base_table'), $this->view->storage->get('base_field'), 'num_records', ['count' => TRUE, 'distinct' => $distinct]); $this->query->addGroupBy($this->name_alias); if ($count_field) { @@ -960,7 +964,7 @@ public function query($group_by = FALSE) { * * This usually needs to be overridden to provide a proper title. */ - function title() { + public function title() { return $this->argument; } @@ -1074,7 +1078,7 @@ public function getValue() { * Get the display or row plugin, if it exists. */ public function getPlugin($type = 'argument_default', $name = NULL) { - $options = array(); + $options = []; switch ($type) { case 'argument_default': if (!isset($this->options['default_argument_type'])) { @@ -1127,7 +1131,7 @@ public function getPlugin($type = 'argument_default', $name = NULL) { * their argument is (e.g. alphabetical, numeric, date). */ public function getSortName() { - return $this->t('Default sort', array(), array('context' => 'Sort order')); + return $this->t('Default sort', [], ['context' => 'Sort order']); } /** @@ -1142,12 +1146,12 @@ public function getSortName() { public static function processContainerRadios($element) { if (count($element['#options']) > 0) { foreach ($element['#options'] as $key => $choice) { - $element += array($key => array()); + $element += [$key => []]; // Generate the parents as the autogenerator does, so we will have a // unique id for each radio button. - $parents_for_id = array_merge($element['#parents'], array($key)); + $parents_for_id = array_merge($element['#parents'], [$key]); - $element[$key] += array( + $element[$key] += [ '#type' => 'radio', '#title' => $choice, // The key is sanitized in drupal_attributes() during output from the @@ -1158,11 +1162,11 @@ public static function processContainerRadios($element) { '#parents' => $element['#parents'], '#id' => Html::getUniqueId('edit-' . implode('-', $parents_for_id)), '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL, - ); - $element[$key . '_options'] = array( + ]; + $element[$key . '_options'] = [ '#type' => 'container', - '#attributes' => array('class' => array('views-admin-dependent')), - ); + '#attributes' => ['class' => ['views-admin-dependent']], + ]; } } return $element; @@ -1326,6 +1330,17 @@ public function calculateDependencies() { return $dependencies; } + /** + * Returns a context definition for this argument. + * + * @return \Drupal\Core\Plugin\Context\ContextDefinitionInterface|null + * A context definition that represents the argument or NULL if that is + * not possible. + */ + public function getContextDefinition() { + return $this->getPlugin('argument_validator')->getContextDefinition(); + } + } /** diff --git a/core/modules/views/src/Plugin/views/argument/Date.php b/core/modules/views/src/Plugin/views/argument/Date.php index 8d1dd401..a751d561 100644 --- a/core/modules/views/src/Plugin/views/argument/Date.php +++ b/core/modules/views/src/Plugin/views/argument/Date.php @@ -85,9 +85,9 @@ public static function create(ContainerInterface $container, array $configuratio */ public function defaultArgumentForm(&$form, FormStateInterface $form_state) { parent::defaultArgumentForm($form, $form_state); - $form['default_argument_type']['#options'] += array('date' => $this->t('Current date')); - $form['default_argument_type']['#options'] += array('node_created' => $this->t("Current node's creation time")); - $form['default_argument_type']['#options'] += array('node_changed' => $this->t("Current node's update time")); + $form['default_argument_type']['#options'] += ['date' => $this->t('Current date')]; + $form['default_argument_type']['#options'] += ['node_created' => $this->t("Current node's creation time")]; + $form['default_argument_type']['#options'] += ['node_changed' => $this->t("Current node's update time")]; } /** @@ -98,7 +98,7 @@ public function getDefaultArgument($raw = FALSE) { if (!$raw && $this->options['default_argument_type'] == 'date') { return date($this->argFormat, REQUEST_TIME); } - elseif (!$raw && in_array($this->options['default_argument_type'], array('node_created', 'node_changed'))) { + elseif (!$raw && in_array($this->options['default_argument_type'], ['node_created', 'node_changed'])) { $node = $this->routeMatch->getParameter('node'); if (!($node instanceof NodeInterface)) { @@ -119,7 +119,7 @@ public function getDefaultArgument($raw = FALSE) { * {@inheritdoc} */ public function getSortName() { - return $this->t('Date', array(), array('context' => 'Sort order')); + return $this->t('Date', [], ['context' => 'Sort order']); } /** diff --git a/core/modules/views/src/Plugin/views/argument/DayDate.php b/core/modules/views/src/Plugin/views/argument/DayDate.php index 187be041..42bd8174 100644 --- a/core/modules/views/src/Plugin/views/argument/DayDate.php +++ b/core/modules/views/src/Plugin/views/argument/DayDate.php @@ -31,7 +31,7 @@ public function summaryName($data) { /** * Provide a link to the next level of the view */ - function title() { + public function title() { $day = str_pad($this->argument, 2, '0', STR_PAD_LEFT); return format_date(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); } diff --git a/core/modules/views/src/Plugin/views/argument/Formula.php b/core/modules/views/src/Plugin/views/argument/Formula.php index a80074c6..83b33782 100644 --- a/core/modules/views/src/Plugin/views/argument/Formula.php +++ b/core/modules/views/src/Plugin/views/argument/Formula.php @@ -59,9 +59,9 @@ public function query($group_by = FALSE) { // Now that our table is secure, get our formula. $placeholder = $this->placeholder(); $formula = $this->getFormula() . ' = ' . $placeholder; - $placeholders = array( + $placeholders = [ $placeholder => $this->argument, - ); + ]; $this->query->addWhere(0, $formula, $placeholders, 'formula'); } diff --git a/core/modules/views/src/Plugin/views/argument/FullDate.php b/core/modules/views/src/Plugin/views/argument/FullDate.php index 84bcd8cf..ca4ca9f6 100644 --- a/core/modules/views/src/Plugin/views/argument/FullDate.php +++ b/core/modules/views/src/Plugin/views/argument/FullDate.php @@ -30,7 +30,7 @@ public function summaryName($data) { /** * Provide a link to the next level of the view */ - function title() { + public function title() { return format_date(strtotime($this->argument . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); } diff --git a/core/modules/views/src/Plugin/views/argument/GroupByNumeric.php b/core/modules/views/src/Plugin/views/argument/GroupByNumeric.php index 1e7ba388..64be23ef 100644 --- a/core/modules/views/src/Plugin/views/argument/GroupByNumeric.php +++ b/core/modules/views/src/Plugin/views/argument/GroupByNumeric.php @@ -16,7 +16,7 @@ public function query($group_by = FALSE) { $field = $this->getField(); $placeholder = $this->placeholder(); - $this->query->addHavingExpression(0, "$field = $placeholder", array($placeholder => $this->argument)); + $this->query->addHavingExpression(0, "$field = $placeholder", [$placeholder => $this->argument]); } public function adminLabel($short = FALSE) { @@ -27,7 +27,7 @@ public function adminLabel($short = FALSE) { * {@inheritdoc} */ public function getSortName() { - return $this->t('Numerical', array(), array('context' => 'Sort order')); + return $this->t('Numerical', [], ['context' => 'Sort order']); } } diff --git a/core/modules/views/src/Plugin/views/argument/LanguageArgument.php b/core/modules/views/src/Plugin/views/argument/LanguageArgument.php index ef9e1520..2eb1870e 100644 --- a/core/modules/views/src/Plugin/views/argument/LanguageArgument.php +++ b/core/modules/views/src/Plugin/views/argument/LanguageArgument.php @@ -26,7 +26,7 @@ public function summaryName($data) { * Gets the user friendly version of the language name for display as a * title placeholder. */ - function title() { + public function title() { return $this->language($this->argument); } @@ -40,7 +40,7 @@ function title() { * The translated name for the language, or "Unknown language" if the * language was not found. */ - function language($langcode) { + public function language($langcode) { $languages = $this->listLanguages(); return isset($languages[$langcode]) ? $languages[$langcode] : $this->t('Unknown language'); } diff --git a/core/modules/views/src/Plugin/views/argument/ManyToOne.php b/core/modules/views/src/Plugin/views/argument/ManyToOne.php index 48385d53..680c19f2 100644 --- a/core/modules/views/src/Plugin/views/argument/ManyToOne.php +++ b/core/modules/views/src/Plugin/views/argument/ManyToOne.php @@ -34,18 +34,18 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o // Ensure defaults for these, during summaries and stuff: $this->operator = 'or'; - $this->value = array(); + $this->value = []; } protected function defineOptions() { $options = parent::defineOptions(); if (!empty($this->definition['numeric'])) { - $options['break_phrase'] = array('default' => FALSE); + $options['break_phrase'] = ['default' => FALSE]; } - $options['add_table'] = array('default' => FALSE); - $options['require_value'] = array('default' => FALSE); + $options['add_table'] = ['default' => FALSE]; + $options['require_value'] = ['default' => FALSE]; if (isset($this->helper)) { $this->helper->defineOptions($options); @@ -62,28 +62,28 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); // allow + for or, , for and - $form['break_phrase'] = array( + $form['break_phrase'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple values'), '#description' => $this->t('If selected, users can enter multiple values in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'), '#default_value' => !empty($this->options['break_phrase']), '#group' => 'options][more', - ); + ]; - $form['add_table'] = array( + $form['add_table'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple filter values to work together'), '#description' => $this->t('If selected, multiple instances of this filter can work together, as though multiple values were supplied to the same filter. This setting is not compatible with the "Reduce duplicates" setting.'), '#default_value' => !empty($this->options['add_table']), '#group' => 'options][more', - ); + ]; - $form['require_value'] = array( + $form['require_value'] = [ '#type' => 'checkbox', '#title' => $this->t('Do not display items with no value in summary'), '#default_value' => !empty($this->options['require_value']), '#group' => 'options][more', - ); + ]; $this->helper->buildOptionsForm($form, $form_state); } @@ -119,14 +119,14 @@ public function query($group_by = FALSE) { $this->unpackArgumentValue($force_int); } else { - $this->value = array($this->argument); + $this->value = [$this->argument]; $this->operator = 'or'; } $this->helper->addFilter(); } - function title() { + public function title() { if (!$this->argument) { return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : $this->t('Uncategorized'); } @@ -136,7 +136,7 @@ function title() { $this->unpackArgumentValue($force_int); } else { - $this->value = array($this->argument); + $this->value = [$this->argument]; $this->operator = 'or'; } @@ -146,7 +146,7 @@ function title() { return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : $this->t('Uncategorized'); } - if ($this->value === array(-1)) { + if ($this->value === [-1]) { return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : $this->t('Invalid input'); } diff --git a/core/modules/views/src/Plugin/views/argument/MonthDate.php b/core/modules/views/src/Plugin/views/argument/MonthDate.php index c1b493bd..a22824df 100644 --- a/core/modules/views/src/Plugin/views/argument/MonthDate.php +++ b/core/modules/views/src/Plugin/views/argument/MonthDate.php @@ -24,13 +24,13 @@ class MonthDate extends Date { */ public function summaryName($data) { $month = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT); - return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC" ), 'custom', $this->format, 'UTC'); + return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); } /** * Provide a link to the next level of the view */ - function title() { + public function title() { $month = str_pad($this->argument, 2, '0', STR_PAD_LEFT); return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); } diff --git a/core/modules/views/src/Plugin/views/argument/NullArgument.php b/core/modules/views/src/Plugin/views/argument/NullArgument.php index 181fb33c..7fadf168 100644 --- a/core/modules/views/src/Plugin/views/argument/NullArgument.php +++ b/core/modules/views/src/Plugin/views/argument/NullArgument.php @@ -15,7 +15,7 @@ class NullArgument extends ArgumentPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['must_not_be'] = array('default' => FALSE); + $options['must_not_be'] = ['default' => FALSE]; return $options; } @@ -25,13 +25,13 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['must_not_be'] = array( + $form['must_not_be'] = [ '#type' => 'checkbox', '#title' => $this->t('Fail basic validation if any argument is given'), '#default_value' => !empty($this->options['must_not_be']), '#description' => $this->t('By checking this field, you can use this to make sure views with more arguments than necessary fail validation.'), '#group' => 'options][more', - ); + ]; unset($form['exception']); } @@ -42,7 +42,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ protected function defaultActions($which = NULL) { if ($which) { - if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) { + if (in_array($which, ['ignore', 'not found', 'empty', 'default'])) { return parent::defaultActions($which); } return; diff --git a/core/modules/views/src/Plugin/views/argument/NumericArgument.php b/core/modules/views/src/Plugin/views/argument/NumericArgument.php index b3148369..954171a6 100644 --- a/core/modules/views/src/Plugin/views/argument/NumericArgument.php +++ b/core/modules/views/src/Plugin/views/argument/NumericArgument.php @@ -3,6 +3,7 @@ namespace Drupal\views\Plugin\views\argument; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\Context\ContextDefinition; /** * Basic argument handler for arguments that are numeric. Incorporates @@ -29,8 +30,8 @@ class NumericArgument extends ArgumentPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['break_phrase'] = array('default' => FALSE); - $options['not'] = array('default' => FALSE); + $options['break_phrase'] = ['default' => FALSE]; + $options['not'] = ['default' => FALSE]; return $options; } @@ -39,24 +40,24 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); // allow + for or, , for and - $form['break_phrase'] = array( + $form['break_phrase'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple values'), '#description' => $this->t('If selected, users can enter multiple values in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'), '#default_value' => !empty($this->options['break_phrase']), '#group' => 'options][more', - ); + ]; - $form['not'] = array( + $form['not'] = [ '#type' => 'checkbox', '#title' => $this->t('Exclude'), '#description' => $this->t('If selected, the numbers entered for the filter will be excluded rather than limiting the view.'), '#default_value' => !empty($this->options['not']), '#group' => 'options][more', - ); + ]; } - function title() { + public function title() { if (!$this->argument) { return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : $this->t('Uncategorized'); } @@ -67,7 +68,7 @@ function title() { $this->operator = $break->operator; } else { - $this->value = array($this->argument); + $this->value = [$this->argument]; $this->operator = 'or'; } @@ -75,7 +76,7 @@ function title() { return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : $this->t('Uncategorized'); } - if ($this->value === array(-1)) { + if ($this->value === [-1]) { return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : $this->t('Invalid input'); } @@ -85,7 +86,7 @@ function title() { /** * Override for specific title lookups. * @return array - * Returns all titles, if it's just one title it's an array with one entry. + * Returns all titles, if it's just one title it's an array with one entry. */ public function titleQuery() { return $this->value; @@ -100,7 +101,7 @@ public function query($group_by = FALSE) { $this->operator = $break->operator; } else { - $this->value = array($this->argument); + $this->value = [$this->argument]; } $placeholder = $this->placeholder(); @@ -109,11 +110,11 @@ public function query($group_by = FALSE) { if (count($this->value) > 1) { $operator = empty($this->options['not']) ? 'IN' : 'NOT IN'; $placeholder .= '[]'; - $this->query->addWhereExpression(0, "$this->tableAlias.$this->realField $operator($placeholder) $null_check", array($placeholder => $this->value)); + $this->query->addWhereExpression(0, "$this->tableAlias.$this->realField $operator($placeholder) $null_check", [$placeholder => $this->value]); } else { $operator = empty($this->options['not']) ? '=' : '!='; - $this->query->addWhereExpression(0, "$this->tableAlias.$this->realField $operator $placeholder $null_check", array($placeholder => $this->argument)); + $this->query->addWhereExpression(0, "$this->tableAlias.$this->realField $operator $placeholder $null_check", [$placeholder => $this->argument]); } } @@ -121,7 +122,20 @@ public function query($group_by = FALSE) { * {@inheritdoc} */ public function getSortName() { - return $this->t('Numerical', array(), array('context' => 'Sort order')); + return $this->t('Numerical', [], ['context' => 'Sort order']); + } + + /** + * {@inheritdoc} + */ + public function getContextDefinition() { + if ($context_definition = parent::getContextDefinition()) { + return $context_definition; + } + + // If the parent does not provide a context definition through the + // validation plugin, fall back to the integer type. + return new ContextDefinition('integer', $this->adminLabel(), FALSE); } } diff --git a/core/modules/views/src/Plugin/views/argument/StringArgument.php b/core/modules/views/src/Plugin/views/argument/StringArgument.php index 085589ab..6058d661 100644 --- a/core/modules/views/src/Plugin/views/argument/StringArgument.php +++ b/core/modules/views/src/Plugin/views/argument/StringArgument.php @@ -5,6 +5,7 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Database\Database; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\Context\ContextDefinition; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ManyToOneHelper; @@ -30,23 +31,23 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o // Ensure defaults for these, during summaries and stuff: $this->operator = 'or'; - $this->value = array(); + $this->value = []; } } protected function defineOptions() { $options = parent::defineOptions(); - $options['glossary'] = array('default' => FALSE); - $options['limit'] = array('default' => 0); - $options['case'] = array('default' => 'none'); - $options['path_case'] = array('default' => 'none'); - $options['transform_dash'] = array('default' => FALSE); - $options['break_phrase'] = array('default' => FALSE); + $options['glossary'] = ['default' => FALSE]; + $options['limit'] = ['default' => 0]; + $options['case'] = ['default' => 'none']; + $options['path_case'] = ['default' => 'none']; + $options['transform_dash'] = ['default' => FALSE]; + $options['break_phrase'] = ['default' => FALSE]; if (!empty($this->definition['many to one'])) { - $options['add_table'] = array('default' => FALSE); - $options['require_value'] = array('default' => FALSE); + $options['add_table'] = ['default' => FALSE]; + $options['require_value'] = ['default' => FALSE]; } return $options; @@ -55,89 +56,89 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['glossary'] = array( + $form['glossary'] = [ '#type' => 'checkbox', '#title' => $this->t('Glossary mode'), '#description' => $this->t('Glossary mode applies a limit to the number of characters used in the filter value, which allows the summary view to act as a glossary.'), '#default_value' => $this->options['glossary'], '#group' => 'options][more', - ); + ]; - $form['limit'] = array( + $form['limit'] = [ '#type' => 'textfield', '#title' => $this->t('Character limit'), '#description' => $this->t('How many characters of the filter value to filter against. If set to 1, all fields starting with the first letter in the filter value would be matched.'), '#default_value' => $this->options['limit'], - '#states' => array( - 'visible' => array( - ':input[name="options[glossary]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[glossary]"]' => ['checked' => TRUE], + ], + ], '#group' => 'options][more', - ); + ]; - $form['case'] = array( + $form['case'] = [ '#type' => 'select', '#title' => $this->t('Case'), '#description' => $this->t('When printing the title and summary, how to transform the case of the filter value.'), - '#options' => array( + '#options' => [ 'none' => $this->t('No transform'), 'upper' => $this->t('Upper case'), 'lower' => $this->t('Lower case'), 'ucfirst' => $this->t('Capitalize first letter'), 'ucwords' => $this->t('Capitalize each word'), - ), + ], '#default_value' => $this->options['case'], '#group' => 'options][more', - ); + ]; - $form['path_case'] = array( + $form['path_case'] = [ '#type' => 'select', '#title' => $this->t('Case in path'), '#description' => $this->t('When printing URL paths, how to transform the case of the filter value. Do not use this unless with Postgres as it uses case sensitive comparisons.'), - '#options' => array( + '#options' => [ 'none' => $this->t('No transform'), 'upper' => $this->t('Upper case'), 'lower' => $this->t('Lower case'), 'ucfirst' => $this->t('Capitalize first letter'), 'ucwords' => $this->t('Capitalize each word'), - ), + ], '#default_value' => $this->options['path_case'], '#group' => 'options][more', - ); + ]; - $form['transform_dash'] = array( + $form['transform_dash'] = [ '#type' => 'checkbox', '#title' => $this->t('Transform spaces to dashes in URL'), '#default_value' => $this->options['transform_dash'], '#group' => 'options][more', - ); + ]; if (!empty($this->definition['many to one'])) { - $form['add_table'] = array( + $form['add_table'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple filter values to work together'), '#description' => $this->t('If selected, multiple instances of this filter can work together, as though multiple values were supplied to the same filter. This setting is not compatible with the "Reduce duplicates" setting.'), '#default_value' => !empty($this->options['add_table']), '#group' => 'options][more', - ); + ]; - $form['require_value'] = array( + $form['require_value'] = [ '#type' => 'checkbox', '#title' => $this->t('Do not display items with no value in summary'), '#default_value' => !empty($this->options['require_value']), '#group' => 'options][more', - ); + ]; } // allow + for or, , for and - $form['break_phrase'] = array( + $form['break_phrase'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple values'), '#description' => $this->t('If selected, users can enter multiple values in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'), '#default_value' => !empty($this->options['break_phrase']), '#group' => 'options][more', - ); + ]; } /** @@ -205,7 +206,7 @@ public function query($group_by = FALSE) { $this->unpackArgumentValue(); } else { - $this->value = array($argument); + $this->value = [$argument]; $this->operator = 'or'; } @@ -252,9 +253,9 @@ public function query($group_by = FALSE) { else { $field .= ' = ' . $placeholder; } - $placeholders = array( + $placeholders = [ $placeholder => $argument, - ); + ]; $this->query->addWhereExpression(0, $field, $placeholders); } else { @@ -274,10 +275,10 @@ public function summaryArgument($data) { * {@inheritdoc} */ public function getSortName() { - return $this->t('Alphabetical', array(), array('context' => 'Sort order')); + return $this->t('Alphabetical', [], ['context' => 'Sort order']); } - function title() { + public function title() { // Support case-insensitive title comparisons for PostgreSQL by converting // the title to lowercase. if ($this->options['case'] != 'none' && Database::getConnection()->databaseType() == 'pgsql') { @@ -293,7 +294,7 @@ function title() { $this->unpackArgumentValue(); } else { - $this->value = array($this->argument); + $this->value = [$this->argument]; $this->operator = 'or'; } @@ -301,7 +302,7 @@ function title() { return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : $this->t('Uncategorized'); } - if ($this->value === array(-1)) { + if ($this->value === [-1]) { return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : $this->t('Invalid input'); } @@ -319,4 +320,17 @@ public function summaryName($data) { return $this->caseTransform(parent::summaryName($data), $this->options['case']); } + /** + * {@inheritdoc} + */ + public function getContextDefinition() { + if ($context_definition = parent::getContextDefinition()) { + return $context_definition; + } + + // If the parent does not provide a context definition through the + // validation plugin, fall back to the string type. + return new ContextDefinition('string', $this->adminLabel(), FALSE); + } + } diff --git a/core/modules/views/src/Plugin/views/argument/WeekDate.php b/core/modules/views/src/Plugin/views/argument/WeekDate.php index 73cc2055..918cfec5 100644 --- a/core/modules/views/src/Plugin/views/argument/WeekDate.php +++ b/core/modules/views/src/Plugin/views/argument/WeekDate.php @@ -19,7 +19,7 @@ class WeekDate extends Date { */ public function summaryName($data) { $created = $data->{$this->name_alias}; - return $this->t('Week @week', array('@week' => $created)); + return $this->t('Week @week', ['@week' => $created]); } } diff --git a/core/modules/views/src/Plugin/views/argument/YearMonthDate.php b/core/modules/views/src/Plugin/views/argument/YearMonthDate.php index 8185513e..1e1effe1 100644 --- a/core/modules/views/src/Plugin/views/argument/YearMonthDate.php +++ b/core/modules/views/src/Plugin/views/argument/YearMonthDate.php @@ -30,7 +30,7 @@ public function summaryName($data) { /** * Provide a link to the next level of the view */ - function title() { + public function title() { return format_date(strtotime($this->argument . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); } diff --git a/core/modules/views/src/Plugin/views/argument_default/ArgumentDefaultPluginBase.php b/core/modules/views/src/Plugin/views/argument_default/ArgumentDefaultPluginBase.php index c3b1c86c..74a8ab20 100644 --- a/core/modules/views/src/Plugin/views/argument_default/ArgumentDefaultPluginBase.php +++ b/core/modules/views/src/Plugin/views/argument_default/ArgumentDefaultPluginBase.php @@ -42,7 +42,7 @@ abstract class ArgumentDefaultPluginBase extends PluginBase { * * This needs to be overridden by every default argument handler to properly do what is needed. */ - public function getArgument() { } + public function getArgument() {} /** * Sets the parent argument this plugin is associated with. @@ -58,28 +58,32 @@ public function setArgument(ArgumentPluginBase $argument) { * Retrieve the options when this is a new access * control plugin */ - protected function defineOptions() { return array(); } + protected function defineOptions() { + return []; + } /** * Provide the default form for setting options. */ - public function buildOptionsForm(&$form, FormStateInterface $form_state) { } + public function buildOptionsForm(&$form, FormStateInterface $form_state) {} /** * Provide the default form form for validating options */ - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} /** * Provide the default form form for submitting options */ - public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = array()) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) {} /** * Determine if the administrator has the privileges to use this * plugin */ - public function access() { return TRUE; } + public function access() { + return TRUE; + } /** * If we don't have access to the form but are showing it anyway, ensure that diff --git a/core/modules/views/src/Plugin/views/argument_default/Fixed.php b/core/modules/views/src/Plugin/views/argument_default/Fixed.php index 317708aa..da08e561 100644 --- a/core/modules/views/src/Plugin/views/argument_default/Fixed.php +++ b/core/modules/views/src/Plugin/views/argument_default/Fixed.php @@ -23,7 +23,7 @@ class Fixed extends ArgumentDefaultPluginBase implements CacheableDependencyInte */ protected function defineOptions() { $options = parent::defineOptions(); - $options['argument'] = array('default' => ''); + $options['argument'] = ['default' => '']; return $options; } @@ -33,11 +33,11 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['argument'] = array( + $form['argument'] = [ '#type' => 'textfield', '#title' => $this->t('Fixed value'), '#default_value' => $this->options['argument'], - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php b/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php index e5b5e201..1b45615f 100644 --- a/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php +++ b/core/modules/views/src/Plugin/views/argument_default/QueryParameter.php @@ -23,9 +23,9 @@ class QueryParameter extends ArgumentDefaultPluginBase implements CacheableDepen */ protected function defineOptions() { $options = parent::defineOptions(); - $options['query_param'] = array('default' => ''); - $options['fallback'] = array('default' => ''); - $options['multiple'] = array('default' => 'and'); + $options['query_param'] = ['default' => '']; + $options['fallback'] = ['default' => '']; + $options['multiple'] = ['default' => 'and']; return $options; } @@ -35,28 +35,28 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['query_param'] = array( + $form['query_param'] = [ '#type' => 'textfield', '#title' => $this->t('Query parameter'), '#description' => $this->t('The query parameter to use.'), '#default_value' => $this->options['query_param'], - ); - $form['fallback'] = array( + ]; + $form['fallback'] = [ '#type' => 'textfield', '#title' => $this->t('Fallback value'), '#description' => $this->t('The fallback value to use when the above query parameter is not present.'), '#default_value' => $this->options['fallback'], - ); - $form['multiple'] = array( + ]; + $form['multiple'] = [ '#type' => 'radios', '#title' => $this->t('Multiple values'), '#description' => $this->t('Conjunction to use when handling multiple values. E.g. "?value[0]=a&value[1]=b".'), '#default_value' => $this->options['multiple'], - '#options' => array( + '#options' => [ 'and' => $this->t('AND'), 'or' => $this->t('OR'), - ), - ); + ], + ]; } /** diff --git a/core/modules/views/src/Plugin/views/argument_default/Raw.php b/core/modules/views/src/Plugin/views/argument_default/Raw.php index 8dd32733..2491bd83 100644 --- a/core/modules/views/src/Plugin/views/argument_default/Raw.php +++ b/core/modules/views/src/Plugin/views/argument_default/Raw.php @@ -74,8 +74,8 @@ public static function create(ContainerInterface $container, array $configuratio */ protected function defineOptions() { $options = parent::defineOptions(); - $options['index'] = array('default' => ''); - $options['use_alias'] = array('default' => FALSE); + $options['index'] = ['default' => '']; + $options['use_alias'] = ['default' => FALSE]; return $options; } @@ -85,7 +85,7 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['index'] = array( + $form['index'] = [ '#type' => 'select', '#title' => $this->t('Path component'), '#default_value' => $this->options['index'], @@ -94,13 +94,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // - values that count from 1 for display to humans. '#options' => range(1, 10), '#description' => $this->t('The numbering starts from 1, e.g. on the page admin/structure/types, the 3rd path component is "types".'), - ); - $form['use_alias'] = array( + ]; + $form['use_alias'] = [ '#type' => 'checkbox', '#title' => $this->t('Use path alias'), '#default_value' => $this->options['use_alias'], '#description' => $this->t('Use path alias instead of internal path.'), - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/argument_validator/ArgumentValidatorPluginBase.php b/core/modules/views/src/Plugin/views/argument_validator/ArgumentValidatorPluginBase.php index 109af509..6e797b49 100644 --- a/core/modules/views/src/Plugin/views/argument_validator/ArgumentValidatorPluginBase.php +++ b/core/modules/views/src/Plugin/views/argument_validator/ArgumentValidatorPluginBase.php @@ -53,27 +53,31 @@ public function setArgument(ArgumentPluginBase $argument) { /** * Retrieves the options when this is a new access control plugin. */ - protected function defineOptions() { return array(); } + protected function defineOptions() { + return []; + } /** * Provides the default form for setting options. */ - public function buildOptionsForm(&$form, FormStateInterface $form_state) { } + public function buildOptionsForm(&$form, FormStateInterface $form_state) {} /** * Provides the default form for validating options. */ - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} /** * Provides the default form for submitting options. */ - public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = array()) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) {} /** * Determines if the administrator has the privileges to use this plugin. */ - public function access() { return TRUE; } + public function access() { + return TRUE; + } /** * Blocks user input when the form is shown but we don´t have access. @@ -92,7 +96,9 @@ protected function checkAccess(&$form, $option_name) { /** * Performs validation for a given argument. */ - public function validateArgument($arg) { return TRUE; } + public function validateArgument($arg) { + return TRUE; + } /** * Processes the summary arguments for displaying. @@ -102,7 +108,16 @@ public function validateArgument($arg) { return TRUE; } * for a faster query. But there are use cases where you want to use * the old value again, for example the summary. */ - public function processSummaryArguments(&$args) { } + public function processSummaryArguments(&$args) {} + + /** + * Returns a context definition for this argument. + * + * @return \Drupal\Core\Plugin\Context\ContextDefinitionInterface|null + * A context definition that represents the argument or NULL if that is + * not possible. + */ + public function getContextDefinition() {} } diff --git a/core/modules/views/src/Plugin/views/argument_validator/Entity.php b/core/modules/views/src/Plugin/views/argument_validator/Entity.php index 53e29d7b..896d24bf 100644 --- a/core/modules/views/src/Plugin/views/argument_validator/Entity.php +++ b/core/modules/views/src/Plugin/views/argument_validator/Entity.php @@ -5,6 +5,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\Context\ContextDefinition; use Drupal\views\Plugin\views\argument\ArgumentPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -70,10 +71,10 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['bundles'] = array('default' => array()); - $options['access'] = array('default' => FALSE); - $options['operation'] = array('default' => 'view'); - $options['multiple'] = array('default' => FALSE); + $options['bundles'] = ['default' => []]; + $options['access'] = ['default' => FALSE]; + $options['operation'] = ['default' => 'view']; + $options['multiple'] = ['default' => FALSE]; return $options; } @@ -92,60 +93,60 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // If the entity has bundles, allow option to restrict to bundle(s). if ($entity_type->hasKey('bundle')) { - $bundle_options = array(); + $bundle_options = []; foreach ($this->entityManager->getBundleInfo($entity_type_id) as $bundle_id => $bundle_info) { $bundle_options[$bundle_id] = $bundle_info['label']; } - $form['bundles'] = array( + $form['bundles'] = [ '#title' => $entity_type->getBundleLabel() ?: $this->t('Bundles'), '#default_value' => $this->options['bundles'], '#type' => 'checkboxes', '#options' => $bundle_options, '#description' => $this->t('If none are selected, all are allowed.'), - ); + ]; } // Offer the option to filter by access to the entity in the argument. - $form['access'] = array( + $form['access'] = [ '#type' => 'checkbox', - '#title' => $this->t('Validate user has access to the %name', array('%name' => $entity_type->getLabel())), + '#title' => $this->t('Validate user has access to the %name', ['%name' => $entity_type->getLabel()]), '#default_value' => $this->options['access'], - ); - $form['operation'] = array( + ]; + $form['operation'] = [ '#type' => 'radios', '#title' => $this->t('Access operation to check'), - '#options' => array( + '#options' => [ 'view' => $this->t('View'), 'update' => $this->t('Edit'), 'delete' => $this->t('Delete'), - ), + ], '#default_value' => $this->options['operation'], - '#states' => array( - 'visible' => array( - ':input[name="options[validate][options][' . $sanitized_id . '][access]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[validate][options][' . $sanitized_id . '][access]"]' => ['checked' => TRUE], + ], + ], + ]; // If class is multiple capable give the option to validate single/multiple. if ($this->multipleCapable) { - $form['multiple'] = array( + $form['multiple'] = [ '#type' => 'radios', '#title' => $this->t('Multiple arguments'), - '#options' => array( - 0 => $this->t('Single ID', array('%type' => $entity_type->getLabel())), - 1 => $this->t('One or more IDs separated by , or +', array('%type' => $entity_type->getLabel())), - ), + '#options' => [ + 0 => $this->t('Single ID', ['%type' => $entity_type->getLabel()]), + 1 => $this->t('One or more IDs separated by , or +', ['%type' => $entity_type->getLabel()]), + ], '#default_value' => (string) $this->options['multiple'], - ); + ]; } } /** * {@inheritdoc} */ - public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = array()) { + public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) { // Filter out unused options so we don't store giant unnecessary arrays. $options['bundles'] = array_filter($options['bundles']); } @@ -162,7 +163,7 @@ public function validateArgument($argument) { $ids = array_filter(preg_split('/[,+ ]/', $argument)); } elseif ($argument) { - $ids = array($argument); + $ids = [$argument]; } // No specified argument should be invalid. else { @@ -228,4 +229,11 @@ public function calculateDependencies() { return $dependencies; } + /** + * {@inheritdoc} + */ + public function getContextDefinition() { + return new ContextDefinition('entity:' . $this->definition['entity_type'], $this->argument->adminLabel(), FALSE); + } + } diff --git a/core/modules/views/src/Plugin/views/argument_validator/NumericArgumentValidator.php b/core/modules/views/src/Plugin/views/argument_validator/NumericArgumentValidator.php index a3184f4f..7368e062 100644 --- a/core/modules/views/src/Plugin/views/argument_validator/NumericArgumentValidator.php +++ b/core/modules/views/src/Plugin/views/argument_validator/NumericArgumentValidator.php @@ -2,6 +2,8 @@ namespace Drupal\views\Plugin\views\argument_validator; +use Drupal\Core\Plugin\Context\ContextDefinition; + /** * Validate whether an argument is numeric or not. * @@ -18,4 +20,11 @@ public function validateArgument($argument) { return is_numeric($argument); } + /** + * {@inheritdoc} + */ + public function getContextDefinition() { + return new ContextDefinition('integer', $this->argument->adminLabel(), FALSE); + } + } diff --git a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php index 87465ca0..dff5eed9 100644 --- a/core/modules/views/src/Plugin/views/cache/CachePluginBase.php +++ b/core/modules/views/src/Plugin/views/cache/CachePluginBase.php @@ -31,7 +31,7 @@ abstract class CachePluginBase extends PluginBase { /** * Contains all data that should be written/read from cache. */ - public $storage = array(); + public $storage = []; /** * Which cache bin to store query results in. @@ -104,11 +104,11 @@ public function cacheSet($type) { // Not supported currently, but this is certainly where we'd put it. break; case 'results': - $data = array( + $data = [ 'result' => $this->prepareViewResult($this->view->result), 'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0, 'current_page' => $this->view->getCurrentPage(), - ); + ]; $expire = ($this->cacheSetMaxAge($type) === Cache::PERMANENT) ? Cache::PERMANENT : (int) $this->view->getRequest()->server->get('REQUEST_TIME') + $this->cacheSetMaxAge($type); \Drupal::cache($this->resultsBin)->set($this->generateResultsKey(), $data, $expire, $this->getCacheTags()); break; @@ -171,7 +171,7 @@ public function cacheFlush() { * All of the cached result data will be available in $view->result, as well, * so all ids used in the query should be discoverable. */ - public function postRender(&$output) { } + public function postRender(&$output) {} /** * Calculates and sets a cache ID used for the result cache. @@ -183,16 +183,16 @@ public function generateResultsKey() { if (!isset($this->resultsKey)) { $build_info = $this->view->build_info; - foreach (array('query', 'count_query') as $index) { + foreach (['query', 'count_query'] as $index) { // If the default query back-end is used generate SQL query strings from // the query objects. if ($build_info[$index] instanceof Select) { $query = clone $build_info[$index]; $query->preExecute(); - $build_info[$index] = array( - 'query' => (string)$query, + $build_info[$index] = [ + 'query' => (string) $query, 'arguments' => $query->getArguments(), - ); + ]; } } @@ -263,7 +263,7 @@ protected function getDefaultCacheMaxAge() { * @param \Drupal\views\ResultRow[] $result * The result containing loaded entities. * - * @return \Drupal\views\ResultRow[] $result + * @return \Drupal\views\ResultRow[] * The result without loaded entities. */ protected function prepareViewResult(array $result) { diff --git a/core/modules/views/src/Plugin/views/cache/Time.php b/core/modules/views/src/Plugin/views/cache/Time.php index 601fbac9..962693d9 100644 --- a/core/modules/views/src/Plugin/views/cache/Time.php +++ b/core/modules/views/src/Plugin/views/cache/Time.php @@ -76,64 +76,64 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['results_lifespan'] = array('default' => 3600); - $options['results_lifespan_custom'] = array('default' => 0); - $options['output_lifespan'] = array('default' => 3600); - $options['output_lifespan_custom'] = array('default' => 0); + $options['results_lifespan'] = ['default' => 3600]; + $options['results_lifespan_custom'] = ['default' => 0]; + $options['output_lifespan'] = ['default' => 3600]; + $options['output_lifespan_custom'] = ['default' => 0]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $options = array(60, 300, 1800, 3600, 21600, 518400); - $options = array_map(array($this->dateFormatter, 'formatInterval'), array_combine($options, $options)); - $options = array(0 => $this->t('Never cache')) + $options + array('custom' => $this->t('Custom')); + $options = [60, 300, 1800, 3600, 21600, 518400]; + $options = array_map([$this->dateFormatter, 'formatInterval'], array_combine($options, $options)); + $options = [0 => $this->t('Never cache')] + $options + ['custom' => $this->t('Custom')]; - $form['results_lifespan'] = array( + $form['results_lifespan'] = [ '#type' => 'select', '#title' => $this->t('Query results'), '#description' => $this->t('The length of time raw query results should be cached.'), '#options' => $options, '#default_value' => $this->options['results_lifespan'], - ); - $form['results_lifespan_custom'] = array( + ]; + $form['results_lifespan_custom'] = [ '#type' => 'textfield', '#title' => $this->t('Seconds'), '#size' => '25', '#maxlength' => '30', '#description' => $this->t('Length of time in seconds raw query results should be cached.'), '#default_value' => $this->options['results_lifespan_custom'], - '#states' => array( - 'visible' => array( - ':input[name="cache_options[results_lifespan]"]' => array('value' => 'custom'), - ), - ), - ); - $form['output_lifespan'] = array( + '#states' => [ + 'visible' => [ + ':input[name="cache_options[results_lifespan]"]' => ['value' => 'custom'], + ], + ], + ]; + $form['output_lifespan'] = [ '#type' => 'select', '#title' => $this->t('Rendered output'), '#description' => $this->t('The length of time rendered HTML output should be cached.'), '#options' => $options, '#default_value' => $this->options['output_lifespan'], - ); - $form['output_lifespan_custom'] = array( + ]; + $form['output_lifespan_custom'] = [ '#type' => 'textfield', '#title' => $this->t('Seconds'), '#size' => '25', '#maxlength' => '30', '#description' => $this->t('Length of time in seconds rendered HTML output should be cached.'), '#default_value' => $this->options['output_lifespan_custom'], - '#states' => array( - 'visible' => array( - ':input[name="cache_options[output_lifespan]"]' => array('value' => 'custom'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="cache_options[output_lifespan]"]' => ['value' => 'custom'], + ], + ], + ]; } public function validateOptionsForm(&$form, FormStateInterface $form_state) { - $custom_fields = array('output_lifespan', 'results_lifespan'); + $custom_fields = ['output_lifespan', 'results_lifespan']; foreach ($custom_fields as $field) { $cache_options = $form_state->getValue('cache_options'); if ($cache_options[$field] == 'custom' && !is_numeric($cache_options[$field . '_custom'])) { diff --git a/core/modules/views/src/Plugin/views/display/Attachment.php b/core/modules/views/src/Plugin/views/display/Attachment.php index 6171525a..315ab595 100644 --- a/core/modules/views/src/Plugin/views/display/Attachment.php +++ b/core/modules/views/src/Plugin/views/display/Attachment.php @@ -34,12 +34,12 @@ class Attachment extends DisplayPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['displays'] = array('default' => array()); - $options['attachment_position'] = array('default' => 'before'); - $options['inherit_arguments'] = array('default' => TRUE); - $options['inherit_exposed_filters'] = array('default' => FALSE); - $options['inherit_pager'] = array('default' => FALSE); - $options['render_pager'] = array('default' => FALSE); + $options['displays'] = ['default' => []]; + $options['attachment_position'] = ['default' => 'before']; + $options['inherit_arguments'] = ['default' => TRUE]; + $options['inherit_exposed_filters'] = ['default' => FALSE]; + $options['inherit_pager'] = ['default' => FALSE]; + $options['render_pager'] = ['default' => FALSE]; return $options; } @@ -49,11 +49,11 @@ public function execute() { } public function attachmentPositions($position = NULL) { - $positions = array( + $positions = [ 'before' => $this->t('Before'), 'after' => $this->t('After'), 'both' => $this->t('Both'), - ); + ]; if ($position) { return $positions[$position]; @@ -71,13 +71,13 @@ public function optionsSummary(&$categories, &$options) { // It is very important to call the parent function here: parent::optionsSummary($categories, $options); - $categories['attachment'] = array( + $categories['attachment'] = [ 'title' => $this->t('Attachment settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -10, - ), - ); + ], + ]; $displays = array_filter($this->getOption('displays')); if (count($displays) > 1) { @@ -94,41 +94,41 @@ public function optionsSummary(&$categories, &$options) { $attach_to = $this->t('Not defined'); } - $options['displays'] = array( + $options['displays'] = [ 'category' => 'attachment', 'title' => $this->t('Attach to'), 'value' => $attach_to, - ); + ]; - $options['attachment_position'] = array( + $options['attachment_position'] = [ 'category' => 'attachment', 'title' => $this->t('Attachment position'), 'value' => $this->attachmentPositions($this->getOption('attachment_position')), - ); + ]; - $options['inherit_arguments'] = array( + $options['inherit_arguments'] = [ 'category' => 'attachment', 'title' => $this->t('Inherit contextual filters'), 'value' => $this->getOption('inherit_arguments') ? $this->t('Yes') : $this->t('No'), - ); + ]; - $options['inherit_exposed_filters'] = array( + $options['inherit_exposed_filters'] = [ 'category' => 'attachment', 'title' => $this->t('Inherit exposed filters'), 'value' => $this->getOption('inherit_exposed_filters') ? $this->t('Yes') : $this->t('No'), - ); + ]; - $options['inherit_pager'] = array( + $options['inherit_pager'] = [ 'category' => 'pager', 'title' => $this->t('Inherit pager'), 'value' => $this->getOption('inherit_pager') ? $this->t('Yes') : $this->t('No'), - ); + ]; - $options['render_pager'] = array( + $options['render_pager'] = [ 'category' => 'pager', 'title' => $this->t('Render pager'), 'value' => $this->getOption('render_pager') ? $this->t('Yes') : $this->t('No'), - ); + ]; } @@ -142,65 +142,65 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($form_state->get('section')) { case 'inherit_arguments': $form['#title'] .= $this->t('Inherit contextual filters'); - $form['inherit_arguments'] = array( + $form['inherit_arguments'] = [ '#type' => 'checkbox', '#title' => $this->t('Inherit'), '#description' => $this->t('Should this display inherit its contextual filter values from the parent display to which it is attached?'), '#default_value' => $this->getOption('inherit_arguments'), - ); + ]; break; case 'inherit_exposed_filters': $form['#title'] .= $this->t('Inherit exposed filters'); - $form['inherit_exposed_filters'] = array( + $form['inherit_exposed_filters'] = [ '#type' => 'checkbox', '#title' => $this->t('Inherit'), '#description' => $this->t('Should this display inherit its exposed filter values from the parent display to which it is attached?'), '#default_value' => $this->getOption('inherit_exposed_filters'), - ); + ]; break; case 'inherit_pager': $form['#title'] .= $this->t('Inherit pager'); - $form['inherit_pager'] = array( + $form['inherit_pager'] = [ '#type' => 'checkbox', '#title' => $this->t('Inherit'), '#description' => $this->t('Should this display inherit its paging values from the parent display to which it is attached?'), '#default_value' => $this->getOption('inherit_pager'), - ); + ]; break; case 'render_pager': $form['#title'] .= $this->t('Render pager'); - $form['render_pager'] = array( + $form['render_pager'] = [ '#type' => 'checkbox', '#title' => $this->t('Render'), '#description' => $this->t('Should this display render the pager values? This is only meaningful if inheriting a pager.'), '#default_value' => $this->getOption('render_pager'), - ); + ]; break; case 'attachment_position': $form['#title'] .= $this->t('Position'); - $form['attachment_position'] = array( + $form['attachment_position'] = [ '#title' => $this->t('Position'), '#type' => 'radios', '#description' => $this->t('Attach before or after the parent display?'), '#options' => $this->attachmentPositions(), '#default_value' => $this->getOption('attachment_position'), - ); + ]; break; case 'displays': $form['#title'] .= $this->t('Attach to'); - $displays = array(); + $displays = []; foreach ($this->view->storage->get('display') as $display_id => $display) { if ($this->view->displayHandlers->has($display_id) && $this->view->displayHandlers->get($display_id)->acceptAttachments()) { $displays[$display_id] = $display['display_title']; } } - $form['displays'] = array( + $form['displays'] = [ '#title' => $this->t('Displays'), '#type' => 'checkboxes', '#description' => $this->t('Select which display or displays this should attach to.'), '#options' => array_map('\Drupal\Component\Utility\Html::escape', $displays), '#default_value' => $this->getOption('displays'), - ); + ]; break; } } @@ -240,7 +240,7 @@ public function attachTo(ViewExecutable $view, $display_id, array &$build) { return; } - $args = $this->getOption('inherit_arguments') ? $this->view->args : array(); + $args = $this->getOption('inherit_arguments') ? $this->view->args : []; $view->setArguments($args); $view->setDisplay($this->display['id']); if ($this->getOption('inherit_pager')) { diff --git a/core/modules/views/src/Plugin/views/display/Block.php b/core/modules/views/src/Plugin/views/display/Block.php index e3208b46..5e833d75 100644 --- a/core/modules/views/src/Plugin/views/display/Block.php +++ b/core/modules/views/src/Plugin/views/display/Block.php @@ -78,15 +78,15 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['block_description'] = array('default' => ''); - $options['block_category'] = array('default' => $this->t('Lists (Views)')); - $options['block_hide_empty'] = array('default' => FALSE); - - $options['allow'] = array( - 'contains' => array( - 'items_per_page' => array('default' => 'items_per_page'), - ), - ); + $options['block_description'] = ['default' => '']; + $options['block_category'] = ['default' => $this->t('Lists (Views)')]; + $options['block_hide_empty'] = ['default' => FALSE]; + + $options['allow'] = [ + 'contains' => [ + 'items_per_page' => ['default' => 'items_per_page'], + ], + ]; return $options; } @@ -116,7 +116,7 @@ public function execute() { // display, and arguments should be set on the view. $element = $this->view->render(); if ($this->outputIsEmpty() && $this->getOption('block_hide_empty') && empty($this->view->style_plugin->definition['even empty'])) { - return array(); + return []; } else { return $element; @@ -131,13 +131,13 @@ public function execute() { public function optionsSummary(&$categories, &$options) { parent::optionsSummary($categories, $options); - $categories['block'] = array( + $categories['block'] = [ 'title' => $this->t('Block settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -10, - ), - ); + ], + ]; $block_description = strip_tags($this->getOption('block_description')); if (empty($block_description)) { @@ -145,30 +145,30 @@ public function optionsSummary(&$categories, &$options) { } $block_category = $this->getOption('block_category'); - $options['block_description'] = array( + $options['block_description'] = [ 'category' => 'block', 'title' => $this->t('Block name'), 'value' => views_ui_truncate($block_description, 24), - ); - $options['block_category'] = array( + ]; + $options['block_category'] = [ 'category' => 'block', 'title' => $this->t('Block category'), 'value' => views_ui_truncate($block_category, 24), - ); + ]; $filtered_allow = array_filter($this->getOption('allow')); - $options['allow'] = array( + $options['allow'] = [ 'category' => 'block', 'title' => $this->t('Allow settings'), 'value' => empty($filtered_allow) ? $this->t('None') : $this->t('Items per page'), - ); + ]; - $options['block_hide_empty'] = array( + $options['block_hide_empty'] = [ 'category' => 'other', 'title' => $this->t('Hide block if the view output is empty'), 'value' => $this->getOption('block_hide_empty') ? $this->t('Yes') : $this->t('No'), - ); + ]; } /** @@ -180,53 +180,53 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($form_state->get('section')) { case 'block_description': $form['#title'] .= $this->t('Block admin description'); - $form['block_description'] = array( + $form['block_description'] = [ '#type' => 'textfield', '#description' => $this->t('This will appear as the name of this block in administer >> structure >> blocks.'), '#default_value' => $this->getOption('block_description'), - ); + ]; break; case 'block_category': $form['#title'] .= $this->t('Block category'); - $form['block_category'] = array( + $form['block_category'] = [ '#type' => 'textfield', '#autocomplete_route_name' => 'block.category_autocomplete', - '#description' => $this->t('The category this block will appear under on the blocks placement page.', array(':href' => \Drupal::url('block.admin_display'))), + '#description' => $this->t('The category this block will appear under on the blocks placement page.', [':href' => \Drupal::url('block.admin_display')]), '#default_value' => $this->getOption('block_category'), - ); + ]; break; case 'block_hide_empty': $form['#title'] .= $this->t('Block empty settings'); - $form['block_hide_empty'] = array( + $form['block_hide_empty'] = [ '#title' => $this->t('Hide block if no result/empty text'), '#type' => 'checkbox', '#description' => $this->t('Hide the block if there is no result and no empty text and no header/footer which is shown on empty result'), '#default_value' => $this->getOption('block_hide_empty'), - ); + ]; break; case 'exposed_form_options': $this->view->initHandlers(); if (!$this->usesExposed() && parent::usesExposed()) { - $form['exposed_form_options']['warning'] = array( + $form['exposed_form_options']['warning'] = [ '#weight' => -10, '#markup' => '
          ' . $this->t('Exposed filters in block displays require "Use AJAX" to be set to work correctly.') . '
          ', - ); + ]; } break; case 'allow': $form['#title'] .= $this->t('Allow settings in the block configuration'); - $options = array( + $options = [ 'items_per_page' => $this->t('Items per page'), - ); + ]; $allow = array_filter($this->getOption('allow')); - $form['allow'] = array( + $form['allow'] = [ '#type' => 'checkboxes', '#default_value' => $allow, '#options' => $options, - ); + ]; break; } } @@ -260,7 +260,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * - * @return array $form + * @return array * The renderable form array representing the entire configuration form. * * @see \Drupal\views\Plugin\Block\ViewsBlock::blockForm() @@ -276,18 +276,18 @@ public function blockForm(ViewsBlock $block, array &$form, FormStateInterface $f } switch ($type) { case 'items_per_page': - $form['override']['items_per_page'] = array( + $form['override']['items_per_page'] = [ '#type' => 'select', '#title' => $this->t('Items per block'), - '#options' => array( - 'none' => $this->t('@count (default setting)', array('@count' => $this->getPlugin('pager')->getItemsPerPage())), + '#options' => [ + 'none' => $this->t('@count (default setting)', ['@count' => $this->getPlugin('pager')->getItemsPerPage()]), 5 => 5, 10 => 10, 20 => 20, 40 => 40, - ), + ], '#default_value' => $block_configuration['items_per_page'], - ); + ]; break; } } @@ -323,10 +323,10 @@ public function blockValidate(ViewsBlock $block, array $form, FormStateInterface * @see \Drupal\views\Plugin\Block\ViewsBlock::blockSubmit() */ public function blockSubmit(ViewsBlock $block, $form, FormStateInterface $form_state) { - if ($items_per_page = $form_state->getValue(array('override', 'items_per_page'))) { + if ($items_per_page = $form_state->getValue(['override', 'items_per_page'])) { $block->setConfigurationValue('items_per_page', $items_per_page); } - $form_state->unsetValue(array('override', 'items_per_page')); + $form_state->unsetValue(['override', 'items_per_page']); } /** diff --git a/core/modules/views/src/Plugin/views/display/DefaultDisplay.php b/core/modules/views/src/Plugin/views/display/DefaultDisplay.php index ec01d6a3..2d14cfb1 100644 --- a/core/modules/views/src/Plugin/views/display/DefaultDisplay.php +++ b/core/modules/views/src/Plugin/views/display/DefaultDisplay.php @@ -28,7 +28,9 @@ class DefaultDisplay extends DisplayPluginBase { * Determine if this display is the 'default' display which contains * fallback settings */ - public function isDefaultDisplay() { return TRUE; } + public function isDefaultDisplay() { + return TRUE; + } /** * The default execute handler fully renders the view. diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index 37b6a4cc..a2e19a29 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -44,7 +44,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte * * @var \Drupal\views\Plugin\views\ViewsPluginInterface[] */ - protected $plugins = array(); + protected $plugins = []; /** * Stores all available display extenders. @@ -107,7 +107,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte * * @var array */ - protected static $unpackOptions = array(); + protected static $unpackOptions = []; /** * The display information coming directly from the view entity. @@ -139,7 +139,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte * The plugin implementation definition. */ public function __construct(array $configuration, $plugin_id, $plugin_definition) { - parent::__construct(array(), $plugin_id, $plugin_definition); + parent::__construct([], $plugin_id, $plugin_definition); } /** @@ -150,7 +150,7 @@ public function initDisplay(ViewExecutable $view, array &$display, array &$optio // Load extenders as soon as possible. $display['display_options'] += ['display_extenders' => []]; - $this->extenders = array(); + $this->extenders = []; if ($extenders = Views::getEnabledDisplayExtenders()) { $manager = Views::pluginManager('display_extender'); $display_extender_options = $display['display_options']['display_extenders']; @@ -182,7 +182,7 @@ public function initDisplay(ViewExecutable $view, array &$display, array &$optio $skip_cache = \Drupal::config('views.settings')->get('skip_cache'); if (empty($view->editing) || !$skip_cache) { - $cid = 'views:unpack_options:' . hash('sha256', serialize(array($this->options, $options))) . ':' . \Drupal::languageManager()->getCurrentLanguage()->getId(); + $cid = 'views:unpack_options:' . hash('sha256', serialize([$this->options, $options])) . ':' . \Drupal::languageManager()->getCurrentLanguage()->getId(); if (empty(static::$unpackOptions[$cid])) { $cache = \Drupal::cache('data')->get($cid); if (!empty($cache->data)) { @@ -234,7 +234,9 @@ public function destroy() { /** * {@inheritdoc} */ - public function isDefaultDisplay() { return FALSE; } + public function isDefaultDisplay() { + return FALSE; + } /** * {@inheritdoc} @@ -394,46 +396,46 @@ public function usesAreas() { /** * {@inheritdoc} */ - public function attachTo(ViewExecutable $view, $display_id, array &$build) { } + public function attachTo(ViewExecutable $view, $display_id, array &$build) {} /** * {@inheritdoc} */ public function defaultableSections($section = NULL) { - $sections = array( - 'access' => array('access'), - 'cache' => array('cache'), - 'title' => array('title'), - 'css_class' => array('css_class'), - 'use_ajax' => array('use_ajax'), - 'hide_attachment_summary' => array('hide_attachment_summary'), - 'show_admin_links' => array('show_admin_links'), - 'group_by' => array('group_by'), - 'query' => array('query'), - 'use_more' => array('use_more', 'use_more_always', 'use_more_text'), - 'use_more_always' => array('use_more', 'use_more_always', 'use_more_text'), - 'use_more_text' => array('use_more', 'use_more_always', 'use_more_text'), - 'link_display' => array('link_display', 'link_url'), + $sections = [ + 'access' => ['access'], + 'cache' => ['cache'], + 'title' => ['title'], + 'css_class' => ['css_class'], + 'use_ajax' => ['use_ajax'], + 'hide_attachment_summary' => ['hide_attachment_summary'], + 'show_admin_links' => ['show_admin_links'], + 'group_by' => ['group_by'], + 'query' => ['query'], + 'use_more' => ['use_more', 'use_more_always', 'use_more_text'], + 'use_more_always' => ['use_more', 'use_more_always', 'use_more_text'], + 'use_more_text' => ['use_more', 'use_more_always', 'use_more_text'], + 'link_display' => ['link_display', 'link_url'], // Force these to cascade properly. - 'style' => array('style', 'row'), - 'row' => array('style', 'row'), + 'style' => ['style', 'row'], + 'row' => ['style', 'row'], - 'pager' => array('pager'), + 'pager' => ['pager'], - 'exposed_form' => array('exposed_form'), + 'exposed_form' => ['exposed_form'], // These sections are special. - 'header' => array('header'), - 'footer' => array('footer'), - 'empty' => array('empty'), - 'relationships' => array('relationships'), - 'fields' => array('fields'), - 'sorts' => array('sorts'), - 'arguments' => array('arguments'), - 'filters' => array('filters', 'filter_groups'), - 'filter_groups' => array('filters', 'filter_groups'), - ); + 'header' => ['header'], + 'footer' => ['footer'], + 'empty' => ['empty'], + 'relationships' => ['relationships'], + 'fields' => ['fields'], + 'sorts' => ['sorts'], + 'arguments' => ['arguments'], + 'filters' => ['filters', 'filter_groups'], + 'filter_groups' => ['filters', 'filter_groups'], + ]; // If the display cannot use a pager, then we cannot default it. if (!$this->usesPager()) { @@ -456,9 +458,9 @@ public function defaultableSections($section = NULL) { } protected function defineOptions() { - $options = array( - 'defaults' => array( - 'default' => array( + $options = [ + 'defaults' => [ + 'default' => [ 'access' => TRUE, 'cache' => TRUE, 'query' => TRUE, @@ -492,152 +494,152 @@ protected function defineOptions() { 'arguments' => TRUE, 'filters' => TRUE, 'filter_groups' => TRUE, - ), - ), + ], + ], - 'title' => array( + 'title' => [ 'default' => '', - ), - 'enabled' => array( + ], + 'enabled' => [ 'default' => TRUE, - ), - 'display_comment' => array( + ], + 'display_comment' => [ 'default' => '', - ), - 'css_class' => array( + ], + 'css_class' => [ 'default' => '', - ), - 'display_description' => array( + ], + 'display_description' => [ 'default' => '', - ), - 'use_ajax' => array( + ], + 'use_ajax' => [ 'default' => FALSE, - ), - 'hide_attachment_summary' => array( + ], + 'hide_attachment_summary' => [ 'default' => FALSE, - ), - 'show_admin_links' => array( + ], + 'show_admin_links' => [ 'default' => TRUE, - ), - 'use_more' => array( + ], + 'use_more' => [ 'default' => FALSE, - ), - 'use_more_always' => array( + ], + 'use_more_always' => [ 'default' => TRUE, - ), - 'use_more_text' => array( + ], + 'use_more_text' => [ 'default' => 'more', - ), - 'link_display' => array( + ], + 'link_display' => [ 'default' => '', - ), - 'link_url' => array( + ], + 'link_url' => [ 'default' => '', - ), - 'group_by' => array( + ], + 'group_by' => [ 'default' => FALSE, - ), - 'rendering_language' => array( + ], + 'rendering_language' => [ 'default' => '***LANGUAGE_entity_translation***', - ), + ], // These types are all plugins that can have individual settings // and therefore need special handling. - 'access' => array( - 'contains' => array( - 'type' => array('default' => 'none'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - 'cache' => array( - 'contains' => array( - 'type' => array('default' => 'tag'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - 'query' => array( - 'contains' => array( - 'type' => array('default' => 'views_query'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - 'exposed_form' => array( - 'contains' => array( - 'type' => array('default' => 'basic'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - 'pager' => array( - 'contains' => array( - 'type' => array('default' => 'mini'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - 'style' => array( - 'contains' => array( - 'type' => array('default' => 'default'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - 'row' => array( - 'contains' => array( - 'type' => array('default' => 'fields'), - 'options' => array('default' => array()), - ), - 'merge_defaults' => array($this, 'mergePlugin'), - ), - - 'exposed_block' => array( + 'access' => [ + 'contains' => [ + 'type' => ['default' => 'none'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + 'cache' => [ + 'contains' => [ + 'type' => ['default' => 'tag'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + 'query' => [ + 'contains' => [ + 'type' => ['default' => 'views_query'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + 'exposed_form' => [ + 'contains' => [ + 'type' => ['default' => 'basic'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + 'pager' => [ + 'contains' => [ + 'type' => ['default' => 'mini'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + 'style' => [ + 'contains' => [ + 'type' => ['default' => 'default'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + 'row' => [ + 'contains' => [ + 'type' => ['default' => 'fields'], + 'options' => ['default' => []], + ], + 'merge_defaults' => [$this, 'mergePlugin'], + ], + + 'exposed_block' => [ 'default' => FALSE, - ), - - 'header' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), - 'footer' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), - 'empty' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), + ], + + 'header' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], + 'footer' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], + 'empty' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], // We want these to export last. // These are the 5 handler types. - 'relationships' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), - 'fields' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), - 'sorts' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), - 'arguments' => array( - 'default' => array(), - 'merge_defaults' => array($this, 'mergeHandler'), - ), - 'filter_groups' => array( - 'contains' => array( - 'operator' => array('default' => 'AND'), - 'groups' => array('default' => array(1 => 'AND')), - ), - ), - 'filters' => array( - 'default' => array(), - ), - ); + 'relationships' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], + 'fields' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], + 'sorts' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], + 'arguments' => [ + 'default' => [], + 'merge_defaults' => [$this, 'mergeHandler'], + ], + 'filter_groups' => [ + 'contains' => [ + 'operator' => ['default' => 'AND'], + 'groups' => ['default' => [1 => 'AND']], + ], + ], + 'filters' => [ + 'default' => [], + ], + ]; if (!$this->usesPager()) { $options['defaults']['default']['pager'] = FALSE; @@ -665,24 +667,30 @@ protected function defineOptions() { /** * {@inheritdoc} */ - public function hasPath() { return FALSE; } + public function hasPath() { + return FALSE; + } /** * {@inheritdoc} */ - public function usesLinkDisplay() { return !$this->hasPath(); } + public function usesLinkDisplay() { + return !$this->hasPath(); + } /** * {@inheritdoc} */ - public function usesExposedFormInBlock() { return $this->hasPath(); } + public function usesExposedFormInBlock() { + return $this->hasPath(); + } /** * {@inheritdoc} */ public function getAttachedDisplays() { $current_display_id = $this->display['id']; - $attached_displays = array(); + $attached_displays = []; // Go through all displays and search displays which link to this one. foreach ($this->view->storage->get('display') as $display_id => $display) { @@ -772,7 +780,7 @@ public function getOption($option) { return $this->default_display->getOption($option); } - if (array_key_exists($option, $this->options)) { + if (isset($this->options[$option]) || array_key_exists($option, $this->options)) { return $this->options[$option]; } } @@ -840,7 +848,7 @@ public function &getHandler($type, $id) { */ public function &getHandlers($type) { if (!isset($this->handlers[$type])) { - $this->handlers[$type] = array(); + $this->handlers[$type] = []; $types = ViewExecutable::getHandlerTypes(); $plural = $types[$type]['plural']; @@ -950,7 +958,7 @@ public function calculateDependencies() { // Collect all the dependencies of handlers and plugins. Only calculate // their dependencies if they are configured by this display. $plugins = array_merge($this->getAllHandlers(TRUE), $this->getAllPlugins(TRUE)); - array_walk($plugins, array($this, 'calculatePluginDependencies')); + array_walk($plugins, [$this, 'calculatePluginDependencies']); return $this->dependencies; } @@ -960,7 +968,7 @@ public function calculateDependencies() { * {@inheritdoc} */ public function getFieldLabels($groupable_only = FALSE) { - $options = array(); + $options = []; foreach ($this->getHandlers('relationship') as $relationship => $handler) { $relationships[$relationship] = $handler->adminLabel(); } @@ -1015,48 +1023,36 @@ public function optionLink($text, $section, $class = '', $title = '') { } if (!empty($class)) { - $text = SafeMarkup::format('@text', array('@text' => $text)); + $text = SafeMarkup::format('@text', ['@text' => $text]); } if (empty($title)) { $title = $text; } - return \Drupal::l($text, new Url('views_ui.form_display', array( + return \Drupal::l($text, new Url('views_ui.form_display', [ 'js' => 'nojs', 'view' => $this->view->storage->id(), 'display_id' => $this->display['id'], 'type' => $section - ), array( - 'attributes' => array( - 'class' => array('views-ajax-link', $class), + ], [ + 'attributes' => [ + 'class' => ['views-ajax-link', $class], 'title' => $title, 'id' => Html::getUniqueId('views-' . $this->display['id'] . '-' . $section) - ) - ))); + ] + ])); } /** * {@inheritdoc} */ public function getArgumentsTokens() { - $tokens = array(); + $tokens = []; if (!empty($this->view->build_info['substitutions'])) { $tokens = $this->view->build_info['substitutions']; } - // Add tokens for every argument (contextual filter) and path arg. - $handlers = count($this->view->display_handler->getHandlers('argument')); - for ($count = 1; $count <= $handlers; $count++) { - if (!isset($tokens["%$count"])) { - $tokens["%$count"] = ''; - } - // Use strip tags as there should never be HTML in the path. - // However, we need to preserve special characters like " that - // were encoded by \Drupal\Component\Utility\Html::escape(). - $tokens["!$count"] = isset($this->view->args[$count - 1]) ? strip_tags(Html::decodeEntities($this->view->args[$count - 1])) : ''; - } - return $tokens; } @@ -1064,94 +1060,94 @@ public function getArgumentsTokens() { * {@inheritdoc} */ public function optionsSummary(&$categories, &$options) { - $categories = array( - 'title' => array( + $categories = [ + 'title' => [ 'title' => $this->t('Title'), 'column' => 'first', - ), - 'format' => array( + ], + 'format' => [ 'title' => $this->t('Format'), 'column' => 'first', - ), - 'filters' => array( + ], + 'filters' => [ 'title' => $this->t('Filters'), 'column' => 'first', - ), - 'fields' => array( + ], + 'fields' => [ 'title' => $this->t('Fields'), 'column' => 'first', - ), - 'pager' => array( + ], + 'pager' => [ 'title' => $this->t('Pager'), 'column' => 'second', - ), - 'language' => array( + ], + 'language' => [ 'title' => $this->t('Language'), 'column' => 'second', - ), - 'exposed' => array( + ], + 'exposed' => [ 'title' => $this->t('Exposed form'), 'column' => 'third', - 'build' => array( + 'build' => [ '#weight' => 1, - ), - ), - 'access' => array( + ], + ], + 'access' => [ 'title' => '', 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -5, - ), - ), - 'other' => array( + ], + ], + 'other' => [ 'title' => $this->t('Other'), 'column' => 'third', - 'build' => array( + 'build' => [ '#weight' => 2, - ), - ), - ); + ], + ], + ]; if ($this->display['id'] != 'default') { - $options['display_id'] = array( + $options['display_id'] = [ 'category' => 'other', 'title' => $this->t('Machine Name'), 'value' => !empty($this->display['new_id']) ? $this->display['new_id'] : $this->display['id'], 'desc' => $this->t('Change the machine name of this display.'), - ); + ]; } $display_comment = views_ui_truncate($this->getOption('display_comment'), 80); - $options['display_comment'] = array( + $options['display_comment'] = [ 'category' => 'other', 'title' => $this->t('Administrative comment'), 'value' => !empty($display_comment) ? $display_comment : $this->t('None'), 'desc' => $this->t('Comment or document this display.'), - ); + ]; $title = strip_tags($this->getOption('title')); if (!$title) { $title = $this->t('None'); } - $options['title'] = array( + $options['title'] = [ 'category' => 'title', 'title' => $this->t('Title'), 'value' => views_ui_truncate($title, 32), 'desc' => $this->t('Change the title that this display will use.'), - ); + ]; $style_plugin_instance = $this->getPlugin('style'); $style_summary = empty($style_plugin_instance->definition['title']) ? $this->t('Missing style plugin') : $style_plugin_instance->summaryTitle(); $style_title = empty($style_plugin_instance->definition['title']) ? $this->t('Missing style plugin') : $style_plugin_instance->pluginTitle(); - $options['style'] = array( + $options['style'] = [ 'category' => 'format', 'title' => $this->t('Format'), 'value' => $style_title, 'setting' => $style_summary, 'desc' => $this->t('Change the way content is formatted.'), - ); + ]; // This adds a 'Settings' link to the style_options setting if the style has // options. @@ -1164,13 +1160,13 @@ public function optionsSummary(&$categories, &$options) { $row_summary = empty($row_plugin_instance->definition['title']) ? $this->t('Missing row plugin') : $row_plugin_instance->summaryTitle(); $row_title = empty($row_plugin_instance->definition['title']) ? $this->t('Missing row plugin') : $row_plugin_instance->pluginTitle(); - $options['row'] = array( + $options['row'] = [ 'category' => 'format', 'title' => $this->t('Show'), 'value' => $row_title, 'setting' => $row_summary, 'desc' => $this->t('Change the way each row in the view is styled.'), - ); + ]; // This adds a 'Settings' link to the row_options setting if the row style // has options. if ($row_plugin_instance->usesOptions()) { @@ -1178,28 +1174,28 @@ public function optionsSummary(&$categories, &$options) { } } if ($this->usesAJAX()) { - $options['use_ajax'] = array( + $options['use_ajax'] = [ 'category' => 'other', 'title' => $this->t('Use AJAX'), 'value' => $this->getOption('use_ajax') ? $this->t('Yes') : $this->t('No'), 'desc' => $this->t('Change whether or not this display will use AJAX.'), - ); + ]; } if ($this->usesAttachments()) { - $options['hide_attachment_summary'] = array( + $options['hide_attachment_summary'] = [ 'category' => 'other', 'title' => $this->t('Hide attachments in summary'), 'value' => $this->getOption('hide_attachment_summary') ? $this->t('Yes') : $this->t('No'), 'desc' => $this->t('Change whether or not to display attachments when displaying a contextual filter summary.'), - ); + ]; } if (!isset($this->definition['contextual links locations']) || !empty($this->definition['contextual links locations'])) { - $options['show_admin_links'] = array( + $options['show_admin_links'] = [ 'category' => 'other', 'title' => $this->t('Contextual links'), 'value' => $this->getOption('show_admin_links') ? $this->t('Shown') : $this->t('Hidden'), 'desc' => $this->t('Change whether or not to display contextual links for this view.'), - ); + ]; } $pager_plugin = $this->getPlugin('pager'); @@ -1210,13 +1206,13 @@ public function optionsSummary(&$categories, &$options) { $pager_str = $pager_plugin->summaryTitle(); - $options['pager'] = array( + $options['pager'] = [ 'category' => 'pager', 'title' => $this->t('Use pager'), 'value' => $pager_plugin->pluginTitle(), 'setting' => $pager_str, 'desc' => $this->t("Change this display's pager setting."), - ); + ]; // If pagers aren't allowed, change the text of the item. if (!$this->usesPager()) { @@ -1228,39 +1224,39 @@ public function optionsSummary(&$categories, &$options) { } if ($this->usesMore()) { - $options['use_more'] = array( + $options['use_more'] = [ 'category' => 'pager', 'title' => $this->t('More link'), 'value' => $this->getOption('use_more') ? $this->t('Yes') : $this->t('No'), 'desc' => $this->t('Specify whether this display will provide a "more" link.'), - ); + ]; } $this->view->initQuery(); if ($this->view->query->getAggregationInfo()) { - $options['group_by'] = array( + $options['group_by'] = [ 'category' => 'other', 'title' => $this->t('Use aggregation'), 'value' => $this->getOption('group_by') ? $this->t('Yes') : $this->t('No'), 'desc' => $this->t('Allow grouping and aggregation (calculation) of fields.'), - ); + ]; } - $options['query'] = array( + $options['query'] = [ 'category' => 'other', 'title' => $this->t('Query settings'), 'value' => $this->t('Settings'), 'desc' => $this->t('Allow to set some advanced settings for the query plugin'), - ); + ]; if (\Drupal::languageManager()->isMultilingual() && $this->isBaseTableTranslatable()) { $rendering_language_options = $this->buildRenderingLanguageOptions(); - $options['rendering_language'] = array( + $options['rendering_language'] = [ 'category' => 'language', 'title' => $this->t('Rendering Language'), 'value' => $rendering_language_options[$this->getOption('rendering_language')], 'desc' => $this->t('All content that supports translations will be displayed in the selected language.'), - ); + ]; } $access_plugin = $this->getPlugin('access'); @@ -1271,13 +1267,13 @@ public function optionsSummary(&$categories, &$options) { $access_str = $access_plugin->summaryTitle(); - $options['access'] = array( + $options['access'] = [ 'category' => 'access', 'title' => $this->t('Access'), 'value' => $access_plugin->pluginTitle(), 'setting' => $access_str, 'desc' => $this->t('Specify access control type for this display.'), - ); + ]; if ($access_plugin->usesOptions()) { $options['access']['links']['access_options'] = $this->t('Change settings for this access type.'); @@ -1291,13 +1287,13 @@ public function optionsSummary(&$categories, &$options) { $cache_str = $cache_plugin->summaryTitle(); - $options['cache'] = array( + $options['cache'] = [ 'category' => 'other', 'title' => $this->t('Caching'), 'value' => $cache_plugin->pluginTitle(), 'setting' => $cache_str, 'desc' => $this->t('Specify caching type for this display.'), - ); + ]; if ($cache_plugin->usesOptions()) { $options['cache']['links']['cache_options'] = $this->t('Change settings for this caching type.'); @@ -1322,21 +1318,21 @@ public function optionsSummary(&$categories, &$options) { } } - $options['link_display'] = array( + $options['link_display'] = [ 'category' => 'pager', 'title' => $this->t('Link display'), 'value' => $link_display, 'desc' => $this->t('Specify which display or custom URL this display will link to.'), - ); + ]; } if ($this->usesExposedFormInBlock()) { - $options['exposed_block'] = array( + $options['exposed_block'] = [ 'category' => 'exposed', 'title' => $this->t('Exposed form in block'), 'value' => $this->getOption('exposed_block') ? $this->t('Yes') : $this->t('No'), 'desc' => $this->t('Allow the exposed form to appear in a block instead of the view.'), - ); + ]; } /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginInterface $exposed_form_plugin */ @@ -1348,13 +1344,13 @@ public function optionsSummary(&$categories, &$options) { $exposed_form_str = $exposed_form_plugin->summaryTitle(); - $options['exposed_form'] = array( + $options['exposed_form'] = [ 'category' => 'exposed', 'title' => $this->t('Exposed form style'), 'value' => $exposed_form_plugin->pluginTitle(), 'setting' => $exposed_form_str, 'desc' => $this->t('Select the kind of exposed filter to use.'), - ); + ]; if ($exposed_form_plugin->usesOptions()) { $options['exposed_form']['links']['exposed_form_options'] = $this->t('Exposed form settings for this exposed form style.'); @@ -1365,12 +1361,12 @@ public function optionsSummary(&$categories, &$options) { $css_class = $this->t('None'); } - $options['css_class'] = array( + $options['css_class'] = [ 'category' => 'other', 'title' => $this->t('CSS class'), 'value' => $css_class, 'desc' => $this->t('Change the CSS class name(s) that will be added to this display.'), - ); + ]; foreach ($this->extenders as $extender) { $extender->optionsSummary($categories, $options); @@ -1402,144 +1398,144 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($section) { case 'display_id': $form['#title'] .= $this->t('The machine name of this display'); - $form['display_id'] = array( + $form['display_id'] = [ '#type' => 'textfield', '#title' => $this->t('Machine name of the display'), '#default_value' => !empty($this->display['new_id']) ? $this->display['new_id'] : $this->display['id'], '#required' => TRUE, '#size' => 64, - ); + ]; break; case 'display_title': $form['#title'] .= $this->t('The name and the description of this display'); - $form['display_title'] = array( + $form['display_title'] = [ '#title' => $this->t('Administrative name'), '#type' => 'textfield', '#default_value' => $this->display['display_title'], - ); - $form['display_description'] = array( + ]; + $form['display_description'] = [ '#title' => $this->t('Administrative description'), '#type' => 'textfield', '#default_value' => $this->getOption('display_description'), - ); + ]; break; case 'display_comment': $form['#title'] .= $this->t('Administrative comment'); - $form['display_comment'] = array( + $form['display_comment'] = [ '#type' => 'textarea', '#title' => $this->t('Administrative comment'), '#description' => $this->t('This description will only be seen within the administrative interface and can be used to document this display.'), '#default_value' => $this->getOption('display_comment'), - ); + ]; break; case 'title': $form['#title'] .= $this->t('The title of this view'); - $form['title'] = array( + $form['title'] = [ '#title' => $this->t('Title'), '#type' => 'textfield', '#description' => $this->t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'), '#default_value' => $this->getOption('title'), '#maxlength' => 255, - ); + ]; break; case 'css_class': $form['#title'] .= $this->t('CSS class'); - $form['css_class'] = array( + $form['css_class'] = [ '#type' => 'textfield', '#title' => $this->t('CSS class name(s)'), '#description' => $this->t('Separate multiple classes by spaces.'), '#default_value' => $this->getOption('css_class'), - ); + ]; break; case 'use_ajax': $form['#title'] .= $this->t('AJAX'); - $form['use_ajax'] = array( + $form['use_ajax'] = [ '#description' => $this->t('Options such as paging, table sorting, and exposed filters will not initiate a page refresh.'), '#type' => 'checkbox', '#title' => $this->t('Use AJAX'), '#default_value' => $this->getOption('use_ajax') ? 1 : 0, - ); + ]; break; case 'hide_attachment_summary': $form['#title'] .= $this->t('Hide attachments when displaying a contextual filter summary'); - $form['hide_attachment_summary'] = array( + $form['hide_attachment_summary'] = [ '#type' => 'checkbox', '#title' => $this->t('Hide attachments in summary'), '#default_value' => $this->getOption('hide_attachment_summary') ? 1 : 0, - ); + ]; break; case 'show_admin_links': $form['#title'] .= $this->t('Show contextual links on this view.'); - $form['show_admin_links'] = array( + $form['show_admin_links'] = [ '#type' => 'checkbox', '#title' => $this->t('Show contextual links'), '#default_value' => $this->getOption('show_admin_links'), - ); + ]; break; case 'use_more': $form['#title'] .= $this->t('Add a more link to the bottom of the display.'); - $form['use_more'] = array( + $form['use_more'] = [ '#type' => 'checkbox', '#title' => $this->t('Create more link'), '#description' => $this->t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' section under pager. You can override the URL at the link display setting."), '#default_value' => $this->getOption('use_more'), - ); - $form['use_more_always'] = array( + ]; + $form['use_more_always'] = [ '#type' => 'checkbox', '#title' => $this->t('Always display the more link'), '#description' => $this->t('Check this to display the more link even if there are no more items to display.'), '#default_value' => $this->getOption('use_more_always'), - '#states' => array( - 'visible' => array( - ':input[name="use_more"]' => array('checked' => TRUE), - ), - ), - ); - $form['use_more_text'] = array( + '#states' => [ + 'visible' => [ + ':input[name="use_more"]' => ['checked' => TRUE], + ], + ], + ]; + $form['use_more_text'] = [ '#type' => 'textfield', '#title' => $this->t('More link text'), '#description' => $this->t('The text to display for the more link.'), '#default_value' => $this->getOption('use_more_text'), - '#states' => array( - 'visible' => array( - ':input[name="use_more"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="use_more"]' => ['checked' => TRUE], + ], + ], + ]; break; case 'group_by': $form['#title'] .= $this->t('Allow grouping and aggregation (calculation) of fields.'); - $form['group_by'] = array( + $form['group_by'] = [ '#type' => 'checkbox', '#title' => $this->t('Aggregate'), '#description' => $this->t('If enabled, some fields may become unavailable. All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.'), '#default_value' => $this->getOption('group_by'), - ); + ]; break; case 'access': $form['#title'] .= $this->t('Access restrictions'); - $form['access'] = array( + $form['access'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); + ]; $access = $this->getOption('access'); - $form['access']['type'] = array( + $form['access']['type'] = [ '#title' => $this->t('Access'), '#title_display' => 'invisible', '#type' => 'radios', - '#options' => Views::fetchPluginNames('access', $this->getType(), array($this->view->storage->get('base_table'))), + '#options' => Views::fetchPluginNames('access', $this->getType(), [$this->view->storage->get('base_table')]), '#default_value' => $access['type'], - ); + ]; $access_plugin = $this->getPlugin('access'); if ($access_plugin->usesOptions()) { - $form['markup'] = array( + $form['markup'] = [ '#prefix' => '
          ', - '#markup' => $this->t('You may also adjust the @settings for the currently selected access restriction.', array('@settings' => $this->optionLink($this->t('settings'), 'access_options'))), + '#markup' => $this->t('You may also adjust the @settings for the currently selected access restriction.', ['@settings' => $this->optionLink($this->t('settings'), 'access_options')]), '#suffix' => '
          ', - ); + ]; } break; @@ -1547,45 +1543,45 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $plugin = $this->getPlugin('access'); $form['#title'] .= $this->t('Access options'); if ($plugin) { - $form['access_options'] = array( + $form['access_options'] = [ '#tree' => TRUE, - ); + ]; $plugin->buildOptionsForm($form['access_options'], $form_state); } break; case 'cache': $form['#title'] .= $this->t('Caching'); - $form['cache'] = array( + $form['cache'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); + ]; $cache = $this->getOption('cache'); - $form['cache']['type'] = array( + $form['cache']['type'] = [ '#title' => $this->t('Caching'), '#title_display' => 'invisible', '#type' => 'radios', - '#options' => Views::fetchPluginNames('cache', $this->getType(), array($this->view->storage->get('base_table'))), + '#options' => Views::fetchPluginNames('cache', $this->getType(), [$this->view->storage->get('base_table')]), '#default_value' => $cache['type'], - ); + ]; $cache_plugin = $this->getPlugin('cache'); if ($cache_plugin->usesOptions()) { - $form['markup'] = array( + $form['markup'] = [ '#prefix' => '
          ', '#suffix' => '
          ', - '#markup' => $this->t('You may also adjust the @settings for the currently selected cache mechanism.', array('@settings' => $this->optionLink($this->t('settings'), 'cache_options'))), - ); + '#markup' => $this->t('You may also adjust the @settings for the currently selected cache mechanism.', ['@settings' => $this->optionLink($this->t('settings'), 'cache_options')]), + ]; } break; case 'cache_options': $plugin = $this->getPlugin('cache'); $form['#title'] .= $this->t('Caching options'); if ($plugin) { - $form['cache_options'] = array( + $form['cache_options'] = [ '#tree' => TRUE, - ); + ]; $plugin->buildOptionsForm($form['cache_options'], $form_state); } break; @@ -1596,16 +1592,16 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['#title'] .= $this->t('Query options'); $this->view->initQuery(); if ($this->view->query) { - $form['query'] = array( + $form['query'] = [ '#tree' => TRUE, - 'type' => array( + 'type' => [ '#type' => 'value', '#value' => $plugin_name, - ), - 'options' => array( + ], + 'options' => [ '#tree' => TRUE, - ), - ); + ], + ]; $this->view->query->buildOptionsForm($form['query']['options'], $form_state); } @@ -1614,13 +1610,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['#title'] .= $this->t('Rendering language'); if (\Drupal::languageManager()->isMultilingual() && $this->isBaseTableTranslatable()) { $options = $this->buildRenderingLanguageOptions(); - $form['rendering_language'] = array( + $form['rendering_language'] = [ '#type' => 'select', '#options' => $options, '#title' => $this->t('Rendering language'), '#description' => $this->t('All content that supports translations will be displayed in the selected language.'), '#default_value' => $this->getOption('rendering_language'), - ); + ]; } else { $form['rendering_language']['#markup'] = $this->t('The view is not based on a translatable entity type or the site is not multilingual.'); @@ -1629,26 +1625,26 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { case 'style': $form['#title'] .= $this->t('How should this view be styled'); $style_plugin = $this->getPlugin('style'); - $form['style'] = array( + $form['style'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); - $form['style']['type'] = array( + ]; + $form['style']['type'] = [ '#title' => $this->t('Style'), '#title_display' => 'invisible', '#type' => 'radios', - '#options' => Views::fetchPluginNames('style', $this->getType(), array($this->view->storage->get('base_table'))), + '#options' => Views::fetchPluginNames('style', $this->getType(), [$this->view->storage->get('base_table')]), '#default_value' => $style_plugin->definition['id'], '#description' => $this->t('If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary.'), - ); + ]; if ($style_plugin->usesOptions()) { - $form['markup'] = array( + $form['markup'] = [ '#prefix' => '
          ', '#suffix' => '
          ', - '#markup' => $this->t('You may also adjust the @settings for the currently selected style.', array('@settings' => $this->optionLink($this->t('settings'), 'style_options'))), - ); + '#markup' => $this->t('You may also adjust the @settings for the currently selected style.', ['@settings' => $this->optionLink($this->t('settings'), 'style_options')]), + ]; } break; @@ -1678,31 +1674,31 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { case 'row': $form['#title'] .= $this->t('How should each row in this view be styled'); $row_plugin_instance = $this->getPlugin('row'); - $form['row'] = array( + $form['row'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); - $form['row']['type'] = array( + ]; + $form['row']['type'] = [ '#title' => $this->t('Row'), '#title_display' => 'invisible', '#type' => 'radios', - '#options' => Views::fetchPluginNames('row', $this->getType(), array($this->view->storage->get('base_table'))), + '#options' => Views::fetchPluginNames('row', $this->getType(), [$this->view->storage->get('base_table')]), '#default_value' => $row_plugin_instance->definition['id'], - ); + ]; if ($row_plugin_instance->usesOptions()) { - $form['markup'] = array( + $form['markup'] = [ '#prefix' => '
          ', '#suffix' => '
          ', - '#markup' => $this->t('You may also adjust the @settings for the currently selected row style.', array('@settings' => $this->optionLink($this->t('settings'), 'row_options'))), - ); + '#markup' => $this->t('You may also adjust the @settings for the currently selected row style.', ['@settings' => $this->optionLink($this->t('settings'), 'row_options')]), + ]; } break; case 'link_display': $form['#title'] .= $this->t('Which display to use for path'); - $options = array(FALSE => $this->t('None'), 'custom_url' => $this->t('Custom URL')); + $options = [FALSE => $this->t('None'), 'custom_url' => $this->t('Custom URL')]; foreach ($this->view->storage->get('display') as $display_id => $display) { if ($this->view->displayHandlers->get($display_id)->hasPath()) { @@ -1710,18 +1706,18 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } } - $form['link_display'] = array( + $form['link_display'] = [ '#type' => 'radios', '#options' => $options, '#description' => $this->t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."), '#default_value' => $this->getOption('link_display'), - ); + ]; - $options = array(); + $options = []; $optgroup_arguments = (string) t('Arguments'); foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) { - $options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', array('@argument' => $handler->adminLabel())); - $options[$optgroup_arguments]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', array('@argument' => $handler->adminLabel())); + $options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', ['@argument' => $handler->adminLabel()]); + $options[$optgroup_arguments]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', ['@argument' => $handler->adminLabel()]); } // Default text. @@ -1738,102 +1734,102 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { ]; foreach (array_keys($options) as $type) { if (!empty($options[$type])) { - $items = array(); + $items = []; foreach ($options[$type] as $key => $value) { $items[] = $key . ' == ' . $value; } - $item_list = array( + $item_list = [ '#theme' => 'item_list', '#items' => $items, - ); + ]; $description[] = $item_list; } } } - $form['link_url'] = array( + $form['link_url'] = [ '#type' => 'textfield', '#title' => $this->t('Custom URL'), '#default_value' => $this->getOption('link_url'), '#description' => $description, - '#states' => array( - 'visible' => array( - ':input[name="link_display"]' => array('value' => 'custom_url'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="link_display"]' => ['value' => 'custom_url'], + ], + ], + ]; break; case 'exposed_block': $form['#title'] .= $this->t('Put the exposed form in a block'); - $form['description'] = array( + $form['description'] = [ '#markup' => '
          ' . $this->t('If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you.') . '
          ', - ); - $form['exposed_block'] = array( + ]; + $form['exposed_block'] = [ '#type' => 'radios', - '#options' => array(1 => $this->t('Yes'), 0 => $this->t('No')), + '#options' => [1 => $this->t('Yes'), 0 => $this->t('No')], '#default_value' => $this->getOption('exposed_block') ? 1 : 0, - ); + ]; break; case 'exposed_form': $form['#title'] .= $this->t('Exposed Form'); - $form['exposed_form'] = array( + $form['exposed_form'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); + ]; $exposed_form = $this->getOption('exposed_form'); - $form['exposed_form']['type'] = array( + $form['exposed_form']['type'] = [ '#title' => $this->t('Exposed form'), '#title_display' => 'invisible', '#type' => 'radios', - '#options' => Views::fetchPluginNames('exposed_form', $this->getType(), array($this->view->storage->get('base_table'))), + '#options' => Views::fetchPluginNames('exposed_form', $this->getType(), [$this->view->storage->get('base_table')]), '#default_value' => $exposed_form['type'], - ); + ]; $exposed_form_plugin = $this->getPlugin('exposed_form'); if ($exposed_form_plugin->usesOptions()) { - $form['markup'] = array( + $form['markup'] = [ '#prefix' => '
          ', '#suffix' => '
          ', - '#markup' => $this->t('You may also adjust the @settings for the currently selected style.', array('@settings' => $this->optionLink($this->t('settings'), 'exposed_form_options'))), - ); + '#markup' => $this->t('You may also adjust the @settings for the currently selected style.', ['@settings' => $this->optionLink($this->t('settings'), 'exposed_form_options')]), + ]; } break; case 'exposed_form_options': $plugin = $this->getPlugin('exposed_form'); $form['#title'] .= $this->t('Exposed form options'); if ($plugin) { - $form['exposed_form_options'] = array( + $form['exposed_form_options'] = [ '#tree' => TRUE, - ); + ]; $plugin->buildOptionsForm($form['exposed_form_options'], $form_state); } break; case 'pager': $form['#title'] .= $this->t('Select pager'); - $form['pager'] = array( + $form['pager'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); + ]; $pager = $this->getOption('pager'); - $form['pager']['type'] = array( + $form['pager']['type'] = [ '#title' => $this->t('Pager'), '#title_display' => 'invisible', '#type' => 'radios', - '#options' => Views::fetchPluginNames('pager', !$this->usesPager() ? 'basic' : NULL, array($this->view->storage->get('base_table'))), + '#options' => Views::fetchPluginNames('pager', !$this->usesPager() ? 'basic' : NULL, [$this->view->storage->get('base_table')]), '#default_value' => $pager['type'], - ); + ]; $pager_plugin = $this->getPlugin('pager'); if ($pager_plugin->usesOptions()) { - $form['markup'] = array( + $form['markup'] = [ '#prefix' => '
          ', '#suffix' => '
          ', - '#markup' => $this->t('You may also adjust the @settings for the currently selected pager.', array('@settings' => $this->optionLink($this->t('settings'), 'pager_options'))), - ); + '#markup' => $this->t('You may also adjust the @settings for the currently selected pager.', ['@settings' => $this->optionLink($this->t('settings'), 'pager_options')]), + ]; } break; @@ -1841,9 +1837,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $plugin = $this->getPlugin('pager'); $form['#title'] .= $this->t('Pager options'); if ($plugin) { - $form['pager_options'] = array( + $form['pager_options'] = [ '#tree' => TRUE, - ); + ]; $plugin->buildOptionsForm($form['pager_options'], $form_state); } break; @@ -1967,16 +1963,16 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { case 'style': $plugin_type = $section; $plugin_options = $this->getOption($plugin_type); - $type = $form_state->getValue(array($plugin_type, 'type')); + $type = $form_state->getValue([$plugin_type, 'type']); if ($plugin_options['type'] != $type) { /** @var \Drupal\views\Plugin\views\ViewsPluginInterface $plugin */ $plugin = Views::pluginManager($plugin_type)->createInstance($type); if ($plugin) { $plugin->init($this->view, $this, $plugin_options['options']); - $plugin_options = array( + $plugin_options = [ 'type' => $type, 'options' => $plugin->options, - ); + ]; $plugin->filterByDefinedOptions($plugin_options['options']); $this->setOption($plugin_type, $plugin_options); if ($plugin->usesOptions()) { @@ -2063,7 +2059,7 @@ public function query() { /** * {@inheritdoc} */ - public function renderFilters() { } + public function renderFilters() {} /** * {@inheritdoc} @@ -2094,18 +2090,18 @@ public function renderMoreLink() { // If a URL is available (either from the display or a custom path), // render the "More" link. if ($url) { - $url_options = array(); + $url_options = []; if (!empty($this->view->exposed_raw_input)) { $url_options['query'] = $this->view->exposed_raw_input; } $url->setOptions($url_options); - return array( + return [ '#type' => 'more_link', '#url' => $url, '#title' => $this->useMoreText(), '#view' => $this->view, - ); + ]; } } } @@ -2114,9 +2110,9 @@ public function renderMoreLink() { * {@inheritdoc} */ public function render() { - $rows = (!empty($this->view->result) || $this->view->style_plugin->evenEmpty()) ? $this->view->style_plugin->render($this->view->result) : array(); + $rows = (!empty($this->view->result) || $this->view->style_plugin->evenEmpty()) ? $this->view->style_plugin->render($this->view->result) : []; - $element = array( + $element = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#pre_render' => [[$this, 'elementPreRender']], @@ -2124,9 +2120,10 @@ public function render() { // Assigned by reference so anything added in $element['#attached'] will // be available on the view. '#attached' => &$this->view->element['#attached'], - ); + '#cache' => &$this->view->element['#cache'], + ]; - $this->applyDisplayCachablityMetadata($this->view->element); + $this->applyDisplayCacheabilityMetadata($this->view->element); return $element; } @@ -2137,7 +2134,7 @@ public function render() { * @param array $element * The render array with updated cacheability metadata. */ - protected function applyDisplayCachablityMetadata(array &$element) { + protected function applyDisplayCacheabilityMetadata(array &$element) { /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache */ $cache = $this->getPlugin('cache'); @@ -2149,6 +2146,22 @@ protected function applyDisplayCachablityMetadata(array &$element) { ->applyTo($element); } + /** + * Applies the cacheability of the current display to the given render array. + * + * @param array $element + * The render array with updated cacheability metadata. + * + * @deprecated in Drupal 8.4.0, will be removed before Drupal 9.0. Use + * DisplayPluginBase::applyDisplayCacheabilityMetadata instead. + * + * @see \Drupal\views\Plugin\views\display\DisplayPluginBase::applyDisplayCacheabilityMetadata() + */ + protected function applyDisplayCachablityMetadata(array &$element) { + @trigger_error('The DisplayPluginBase::applyDisplayCachablityMetadata method is deprecated since version 8.4 and will be removed in 9.0. Use DisplayPluginBase::applyDisplayCacheabilityMetadata instead.', E_USER_DEPRECATED); + $this->applyDisplayCacheabilityMetadata($element); + } + /** * {@inheritdoc} */ @@ -2158,15 +2171,15 @@ public function elementPreRender(array $element) { // Force a render array so CSS/JS can be attached. if (!is_array($element['#rows'])) { - $element['#rows'] = array('#markup' => $element['#rows']); + $element['#rows'] = ['#markup' => $element['#rows']]; } $element['#header'] = $view->display_handler->renderArea('header', $empty); $element['#footer'] = $view->display_handler->renderArea('footer', $empty); - $element['#empty'] = $empty ? $view->display_handler->renderArea('empty', $empty) : array(); - $element['#exposed'] = !empty($view->exposed_widgets) ? $view->exposed_widgets : array(); + $element['#empty'] = $empty ? $view->display_handler->renderArea('empty', $empty) : []; + $element['#exposed'] = !empty($view->exposed_widgets) ? $view->exposed_widgets : []; $element['#more'] = $view->display_handler->renderMoreLink(); - $element['#feed_icons'] = !empty($view->feedIcons) ? $view->feedIcons : array(); + $element['#feed_icons'] = !empty($view->feedIcons) ? $view->feedIcons : []; if ($view->display_handler->renderPager()) { $exposed_input = isset($view->exposed_raw_input) ? $view->exposed_raw_input : NULL; @@ -2196,12 +2209,12 @@ public function elementPreRender(array $element) { // The form is requesting that all non-essential views elements be hidden, // usually because the rendered step is not a view result. if ($form['show_view_elements']['#value'] == FALSE) { - $element['#header'] = array(); - $element['#exposed'] = array(); - $element['#pager'] = array(); - $element['#footer'] = array(); - $element['#more'] = array(); - $element['#feed_icons'] = array(); + $element['#header'] = []; + $element['#exposed'] = []; + $element['#pager'] = []; + $element['#footer'] = []; + $element['#more'] = []; + $element['#feed_icons'] = []; } $element['#rows'] = $form; @@ -2214,7 +2227,7 @@ public function elementPreRender(array $element) { * {@inheritdoc} */ public function renderArea($area, $empty = FALSE) { - $return = array(); + $return = []; foreach ($this->getHandlers($area) as $key => $area_handler) { if ($area_render = $area_handler->render($empty)) { if (isset($area_handler->position)) { @@ -2320,7 +2333,7 @@ public function getCacheMetadata() { /** * {@inheritdoc} */ - public function execute() { } + public function execute() {} /** * {@inheritdoc} @@ -2341,7 +2354,7 @@ public function buildRenderable(array $args = [], $cache = TRUE) { // of cacheability metadata (e.g.: cache contexts), so they can bubble up. // Thus, we add the cacheability metadata first, then modify / remove the // cache keys depending on the $cache argument. - $this->applyDisplayCachablityMetadata($this->view->element); + $this->applyDisplayCacheabilityMetadata($this->view->element); if ($cache) { $this->view->element['#cache'] += ['keys' => []]; // Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an @@ -2387,7 +2400,7 @@ public static function buildBasicRenderable($view_id, $display_id, array $args = /** * {@inheritdoc} */ - function preview() { + public function preview() { return $this->view->render(); } @@ -2402,7 +2415,7 @@ public function getType() { * {@inheritdoc} */ public function validate() { - $errors = array(); + $errors = []; // Make sure displays that use fields HAVE fields. if ($this->usesFields()) { $fields = FALSE; @@ -2413,7 +2426,7 @@ public function validate() { } if (!$fields) { - $errors[] = $this->t('Display "@display" uses fields but there are none defined for it or all are excluded.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display "@display" uses fields but there are none defined for it or all are excluded.', ['@display' => $this->display['display_title']]); } } @@ -2421,18 +2434,18 @@ public function validate() { if ($this->isMoreEnabled() && $this->getOption('link_display') !== 'custom_url') { $routed_display = $this->getRoutedDisplay(); if (!$routed_display || !$routed_display->isEnabled()) { - $errors[] = $this->t('Display "@display" uses a "more" link but there are no displays it can link to. You need to specify a custom URL.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display "@display" uses a "more" link but there are no displays it can link to. You need to specify a custom URL.', ['@display' => $this->display['display_title']]); } } if ($this->hasPath() && !$this->getOption('path')) { - $errors[] = $this->t('Display "@display" uses a path but the path is undefined.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display "@display" uses a path but the path is undefined.', ['@display' => $this->display['display_title']]); } // Validate style plugin. $style = $this->getPlugin('style'); if (empty($style)) { - $errors[] = $this->t('Display "@display" has an invalid style plugin.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display "@display" has an invalid style plugin.', ['@display' => $this->display['display_title']]); } else { $result = $style->validate(); @@ -2453,7 +2466,7 @@ public function validate() { foreach (ViewExecutable::getHandlerTypes() as $type => $handler_type_info) { foreach ($this->getHandlers($type) as $handler_id => $handler) { if (!empty($handler->options['relationship']) && $handler->options['relationship'] != 'none' && !in_array($handler->options['relationship'], $relationships)) { - $errors[] = $this->t('The %handler_type %handler uses a relationship that has been removed.', array('%handler_type' => $handler_type_info['lstitle'], '%handler' => $handler->adminLabel())); + $errors[] = $this->t('The %handler_type %handler uses a relationship that has been removed.', ['%handler_type' => $handler_type_info['lstitle'], '%handler' => $handler->adminLabel()]); } } } @@ -2509,7 +2522,7 @@ public function outputIsEmpty() { } // Check whether all of the area handlers are empty. - foreach (array('empty', 'footer', 'header') as $type) { + foreach (['empty', 'footer', 'header'] as $type) { $handlers = $this->getHandlers($type); foreach ($handlers as $handler) { // If one is not empty, return FALSE now. @@ -2526,15 +2539,15 @@ public function outputIsEmpty() { * {@inheritdoc} */ public function getSpecialBlocks() { - $blocks = array(); + $blocks = []; if ($this->usesExposedFormInBlock()) { $delta = '-exp-' . $this->view->storage->id() . '-' . $this->display['id']; - $desc = $this->t('Exposed form: @view-@display_id', array('@view' => $this->view->storage->id(), '@display_id' => $this->display['id'])); + $desc = $this->t('Exposed form: @view-@display_id', ['@view' => $this->view->storage->id(), '@display_id' => $this->display['id']]); - $blocks[$delta] = array( + $blocks[$delta] = [ 'info' => $desc, - ); + ]; } return $blocks; @@ -2562,21 +2575,21 @@ public function viewExposedFormBlocks() { * {@inheritdoc} */ public function getArgumentText() { - return array( + return [ 'filter value not present' => $this->t('When the filter value is NOT available'), 'filter value present' => $this->t('When the filter value IS available or a default is provided'), 'description' => $this->t("This display does not have a source for contextual filters, so no contextual filter value will be available unless you select 'Provide default'."), - ); + ]; } /** * {@inheritdoc} */ public function getPagerText() { - return array( + return [ 'items per page title' => $this->t('Items to display'), 'items per page description' => $this->t('Enter 0 for no limit.') - ); + ]; } /** @@ -2586,7 +2599,7 @@ public function mergeDefaults() { $defined_options = $this->defineOptions(); // Build a map of plural => singular for handler types. - $type_map = array(); + $type_map = []; foreach (ViewExecutable::getHandlerTypes() as $type => $info) { $type_map[$info['plural']] = $type; } @@ -2663,7 +2676,7 @@ protected function buildRenderingLanguageOptions() { // https://www.drupal.org/node/2173811. // Pass the current rendering language (in this case a one element array) so // is not lost when there are language configuration changes. - return $this->listLanguages(LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_SITE_DEFAULT | PluginBase::INCLUDE_NEGOTIATED | PluginBase::INCLUDE_ENTITY, array($this->getOption('rendering_language'))); + return $this->listLanguages(LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_SITE_DEFAULT | PluginBase::INCLUDE_NEGOTIATED | PluginBase::INCLUDE_ENTITY, [$this->getOption('rendering_language')]); } /** diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php index d3b4c79b..f8630af0 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php @@ -497,7 +497,7 @@ public function buildRenderable(array $args = [], $cache = TRUE); * * Also might be used for some other AJAXy reason. */ - function preview(); + public function preview(); /** * Returns the display type that this display requires. diff --git a/core/modules/views/src/Plugin/views/display/EntityReference.php b/core/modules/views/src/Plugin/views/display/EntityReference.php index bf2d4603..eb5f04cf 100644 --- a/core/modules/views/src/Plugin/views/display/EntityReference.php +++ b/core/modules/views/src/Plugin/views/display/EntityReference.php @@ -2,6 +2,8 @@ namespace Drupal\views\Plugin\views\display; +use Drupal\Core\Database\Query\Condition; + /** * The plugin that handles an EntityReference display. * @@ -47,9 +49,9 @@ protected function defineOptions() { // Force the style plugin to 'entity_reference_style' and the row plugin to // 'fields'. - $options['style']['contains']['type'] = array('default' => 'entity_reference'); + $options['style']['contains']['type'] = ['default' => 'entity_reference']; $options['defaults']['default']['style'] = FALSE; - $options['row']['contains']['type'] = array('default' => 'entity_reference'); + $options['row']['contains']['type'] = ['default' => 'entity_reference']; $options['defaults']['default']['row'] = FALSE; // Make sure the query is not cached. @@ -88,13 +90,16 @@ public function execute() { } /** - * {@inheritdoc} + * Builds the view result as a renderable array. + * + * @return array + * Renderable array or empty array. */ public function render() { if (!empty($this->view->result) && $this->view->style_plugin->evenEmpty()) { return $this->view->style_plugin->render($this->view->result); } - return ''; + return []; } /** @@ -131,7 +136,7 @@ public function query() { } // Multiple search fields are OR'd together. - $conditions = db_or(); + $conditions = new Condition('OR'); // Build the condition using the selected search fields. foreach ($style_options['options']['search_fields'] as $field_id) { @@ -165,14 +170,14 @@ public function validate() { // Verify that search fields are set up. $style = $this->getOption('style'); if (!isset($style['options']['search_fields'])) { - $errors[] = $this->t('Display "@display" needs a selected search fields to work properly. See the settings for the Entity Reference list format.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display "@display" needs a selected search fields to work properly. See the settings for the Entity Reference list format.', ['@display' => $this->display['display_title']]); } else { // Verify that the search fields used actually exist. $fields = array_keys($this->handlers['field']); foreach ($style['options']['search_fields'] as $field_alias => $enabled) { if ($enabled && !in_array($field_alias, $fields)) { - $errors[] = $this->t('Display "@display" uses field %field as search field, but the field is no longer present. See the settings for the Entity Reference list format.', array('@display' => $this->display['display_title'], '%field' => $field_alias)); + $errors[] = $this->t('Display "@display" uses field %field as search field, but the field is no longer present. See the settings for the Entity Reference list format.', ['@display' => $this->display['display_title'], '%field' => $field_alias]); } } } diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php index bd590910..c664c053 100644 --- a/core/modules/views/src/Plugin/views/display/Feed.php +++ b/core/modules/views/src/Plugin/views/display/Feed.php @@ -90,11 +90,11 @@ public function preview() { $output = $this->view->render(); if (!empty($this->view->live_preview)) { - $output = array( + $output = [ '#prefix' => '
          ',
                   '#plain_text' => drupal_render_root($output),
                   '#suffix' => '
          ', - ); + ]; } return $output; @@ -106,7 +106,7 @@ public function preview() { public function render() { $build = $this->view->style_plugin->render($this->view->result); - $this->applyDisplayCachablityMetadata($build); + $this->applyDisplayCacheabilityMetadata($build); return $build; } @@ -117,7 +117,7 @@ public function render() { public function defaultableSections($section = NULL) { $sections = parent::defaultableSections($section); - if (in_array($section, array('style', 'row'))) { + if (in_array($section, ['style', 'row'])) { return FALSE; } @@ -137,11 +137,11 @@ public function defaultableSections($section = NULL) { protected function defineOptions() { $options = parent::defineOptions(); - $options['displays'] = array('default' => array()); + $options['displays'] = ['default' => []]; // Overrides for standard stuff. $options['style']['contains']['type']['default'] = 'rss'; - $options['style']['contains']['options']['default'] = array('description' => ''); + $options['style']['contains']['options']['default'] = ['description' => '']; $options['sitename_title']['default'] = FALSE; $options['row']['contains']['type']['default'] = 'rss_fields'; $options['defaults']['default']['style'] = FALSE; @@ -160,7 +160,7 @@ public function newDisplay() { // definition, but in this case it's dependent on the view's base table, // which we don't know until init(). if (empty($this->options['row']['type']) || $this->options['row']['type'] === 'rss_fields') { - $row_plugins = Views::fetchPluginNames('row', $this->getType(), array($this->view->storage->get('base_table'))); + $row_plugins = Views::fetchPluginNames('row', $this->getType(), [$this->view->storage->get('base_table')]); $default_row_plugin = key($row_plugins); $options = $this->getOption('row'); @@ -177,13 +177,13 @@ public function optionsSummary(&$categories, &$options) { // Since we're childing off the 'path' type, we'll still *call* our // category 'page' but let's override it so it says feed settings. - $categories['page'] = array( + $categories['page'] = [ 'title' => $this->t('Feed settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -10, - ), - ); + ], + ]; if ($this->getOption('sitename_title')) { $options['title']['value'] = $this->t('Using the site name'); @@ -205,11 +205,11 @@ public function optionsSummary(&$categories, &$options) { $attach_to = $this->t('None'); } - $options['displays'] = array( + $options['displays'] = [ 'category' => 'page', 'title' => $this->t('Attach to'), 'value' => $attach_to, - ); + ]; } /** @@ -224,34 +224,34 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $title = $form['title']; // A little juggling to move the 'title' field beyond our checkbox. unset($form['title']); - $form['sitename_title'] = array( + $form['sitename_title'] = [ '#type' => 'checkbox', '#title' => $this->t('Use the site name for the title'), '#default_value' => $this->getOption('sitename_title'), - ); + ]; $form['title'] = $title; - $form['title']['#states'] = array( - 'visible' => array( - ':input[name="sitename_title"]' => array('checked' => FALSE), - ), - ); + $form['title']['#states'] = [ + 'visible' => [ + ':input[name="sitename_title"]' => ['checked' => FALSE], + ], + ]; break; case 'displays': $form['#title'] .= $this->t('Attach to'); - $displays = array(); + $displays = []; foreach ($this->view->storage->get('display') as $display_id => $display) { // @todo The display plugin should have display_title and id as well. if ($this->view->displayHandlers->has($display_id) && $this->view->displayHandlers->get($display_id)->acceptAttachments()) { $displays[$display_id] = $display['display_title']; } } - $form['displays'] = array( + $form['displays'] = [ '#title' => $this->t('Displays'), '#type' => 'checkboxes', '#description' => $this->t('The feed icon will be available only to the selected displays.'), '#options' => array_map('\Drupal\Component\Utility\Html::escape', $displays), '#default_value' => $this->getOption('displays'), - ); + ]; break; case 'path': $form['path']['#description'] = $this->t('This view will be displayed by visiting this path on your site. It is recommended that the path be something like "path/%/%/feed" or "path/%/%/rss.xml", putting one % in the path for each contextual filter you have defined in the view.'); diff --git a/core/modules/views/src/Plugin/views/display/Page.php b/core/modules/views/src/Plugin/views/display/Page.php index d79b75b8..aca0683f 100644 --- a/core/modules/views/src/Plugin/views/display/Page.php +++ b/core/modules/views/src/Plugin/views/display/Page.php @@ -118,27 +118,27 @@ public static function &getPageRenderArray() { protected function defineOptions() { $options = parent::defineOptions(); - $options['menu'] = array( - 'contains' => array( - 'type' => array('default' => 'none'), - 'title' => array('default' => ''), - 'description' => array('default' => ''), - 'weight' => array('default' => 0), - 'enabled' => array('default' => TRUE), - 'menu_name' => array('default' => 'main'), - 'parent' => array('default' => ''), - 'context' => array('default' => ''), - 'expanded' => array('default' => FALSE), - ), - ); - $options['tab_options'] = array( - 'contains' => array( - 'type' => array('default' => 'none'), - 'title' => array('default' => ''), - 'description' => array('default' => ''), - 'weight' => array('default' => 0), - ), - ); + $options['menu'] = [ + 'contains' => [ + 'type' => ['default' => 'none'], + 'title' => ['default' => ''], + 'description' => ['default' => ''], + 'weight' => ['default' => 0], + 'enabled' => ['default' => TRUE], + 'menu_name' => ['default' => 'main'], + 'parent' => ['default' => ''], + 'context' => ['default' => ''], + 'expanded' => ['default' => FALSE], + ], + ]; + $options['tab_options'] = [ + 'contains' => [ + 'type' => ['default' => 'none'], + 'title' => ['default' => ''], + 'description' => ['default' => ''], + 'weight' => ['default' => 0], + ], + ]; return $options; } @@ -175,9 +175,9 @@ public function execute() { // @todo Figure out how to support custom response objects. Maybe for pages // it should be dropped. if (is_array($render)) { - $render += array( + $render += [ '#title' => ['#markup' => $this->view->getTitle(), '#allowed_tags' => Xss::getHtmlTagList()], - ); + ]; } return $render; } @@ -190,7 +190,7 @@ public function optionsSummary(&$categories, &$options) { $menu = $this->getOption('menu'); if (!is_array($menu)) { - $menu = array('type' => 'none'); + $menu = ['type' => 'none']; } switch ($menu['type']) { case 'none': @@ -198,19 +198,19 @@ public function optionsSummary(&$categories, &$options) { $menu_str = $this->t('No menu'); break; case 'normal': - $menu_str = $this->t('Normal: @title', array('@title' => $menu['title'])); + $menu_str = $this->t('Normal: @title', ['@title' => $menu['title']]); break; case 'tab': case 'default tab': - $menu_str = $this->t('Tab: @title', array('@title' => $menu['title'])); + $menu_str = $this->t('Tab: @title', ['@title' => $menu['title']]); break; } - $options['menu'] = array( + $options['menu'] = [ 'category' => 'page', 'title' => $this->t('Menu'), 'value' => views_ui_truncate($menu_str, 24), - ); + ]; // This adds a 'Settings' link to the style_options setting if the style // has options. @@ -229,67 +229,67 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($form_state->get('section')) { case 'menu': $form['#title'] .= $this->t('Menu item entry'); - $form['menu'] = array( + $form['menu'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); + ]; $menu = $this->getOption('menu'); if (empty($menu)) { - $menu = array('type' => 'none', 'title' => '', 'weight' => 0, 'expanded' => FALSE); + $menu = ['type' => 'none', 'title' => '', 'weight' => 0, 'expanded' => FALSE]; } - $form['menu']['type'] = array( + $form['menu']['type'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#title' => $this->t('Type'), '#type' => 'radios', - '#options' => array( + '#options' => [ 'none' => $this->t('No menu entry'), 'normal' => $this->t('Normal menu entry'), 'tab' => $this->t('Menu tab'), 'default tab' => $this->t('Default menu tab') - ), + ], '#default_value' => $menu['type'], - ); + ]; - $form['menu']['title'] = array( + $form['menu']['title'] = [ '#prefix' => '
          ', '#title' => $this->t('Menu link title'), '#type' => 'textfield', '#default_value' => $menu['title'], - '#states' => array( - 'visible' => array( - array( - ':input[name="menu[type]"]' => array('value' => 'normal'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'tab'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'default tab'), - ), - ), - ), - ); - $form['menu']['description'] = array( + '#states' => [ + 'visible' => [ + [ + ':input[name="menu[type]"]' => ['value' => 'normal'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'tab'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'default tab'], + ], + ], + ], + ]; + $form['menu']['description'] = [ '#title' => $this->t('Description'), '#type' => 'textfield', '#default_value' => $menu['description'], '#description' => $this->t("Shown when hovering over the menu link."), - '#states' => array( - 'visible' => array( - array( - ':input[name="menu[type]"]' => array('value' => 'normal'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'tab'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'default tab'), - ), - ), - ), - ); + '#states' => [ + 'visible' => [ + [ + ':input[name="menu[type]"]' => ['value' => 'normal'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'tab'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'default tab'], + ], + ], + ], + ]; $form['menu']['expanded'] = [ '#title' => $this->t('Show as expanded'), '#type' => 'checkbox', @@ -302,133 +302,133 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if (\Drupal::moduleHandler()->moduleExists('menu_ui')) { $menu_link = 'views_view:views.' . $form_state->get('view')->id() . '.' . $form_state->get('display_id'); $form['menu']['parent'] = \Drupal::service('menu.parent_form_selector')->parentSelectElement($menu_parent, $menu_link); - $form['menu']['parent'] += array( + $form['menu']['parent'] += [ '#title' => $this->t('Parent'), '#description' => $this->t('The maximum depth for a link and all its children is fixed. Some menu links may not be available as parents if selecting them would exceed this limit.'), - '#attributes' => array('class' => array('menu-title-select')), - '#states' => array( - 'visible' => array( - array( - ':input[name="menu[type]"]' => array('value' => 'normal'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'tab'), - ), - ), - ), - ); + '#attributes' => ['class' => ['menu-title-select']], + '#states' => [ + 'visible' => [ + [ + ':input[name="menu[type]"]' => ['value' => 'normal'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'tab'], + ], + ], + ], + ]; } else { - $form['menu']['parent'] = array( + $form['menu']['parent'] = [ '#type' => 'value', '#value' => $menu_parent, - ); - $form['menu']['markup'] = array( + ]; + $form['menu']['markup'] = [ '#markup' => $this->t('Menu selection requires the activation of Menu UI module.'), - ); + ]; } - $form['menu']['weight'] = array( + $form['menu']['weight'] = [ '#title' => $this->t('Weight'), '#type' => 'textfield', '#default_value' => isset($menu['weight']) ? $menu['weight'] : 0, '#description' => $this->t('In the menu, the heavier links will sink and the lighter links will be positioned nearer the top.'), - '#states' => array( - 'visible' => array( - array( - ':input[name="menu[type]"]' => array('value' => 'normal'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'tab'), - ), - array( - ':input[name="menu[type]"]' => array('value' => 'default tab'), - ), - ), - ), - ); - $form['menu']['context'] = array( + '#states' => [ + 'visible' => [ + [ + ':input[name="menu[type]"]' => ['value' => 'normal'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'tab'], + ], + [ + ':input[name="menu[type]"]' => ['value' => 'default tab'], + ], + ], + ], + ]; + $form['menu']['context'] = [ '#title' => $this->t('Context'), '#suffix' => '
          ', '#type' => 'checkbox', '#default_value' => !empty($menu['context']), '#description' => $this->t('Displays the link in contextual links'), - '#states' => array( - 'visible' => array( - ':input[name="menu[type]"]' => array('value' => 'tab'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="menu[type]"]' => ['value' => 'tab'], + ], + ], + ]; break; case 'tab_options': $form['#title'] .= $this->t('Default tab options'); $tab_options = $this->getOption('tab_options'); if (empty($tab_options)) { - $tab_options = array('type' => 'none', 'title' => '', 'weight' => 0); + $tab_options = ['type' => 'none', 'title' => '', 'weight' => 0]; } - $form['tab_markup'] = array( + $form['tab_markup'] = [ '#markup' => '
          ' . $this->t('When providing a menu item as a tab, Drupal needs to know what the parent menu item of that tab will be. Sometimes the parent will already exist, but other times you will need to have one created. The path of a parent item will always be the same path with the last part left off. i.e, if the path to this view is foo/bar/baz, the parent path would be foo/bar.') . '
          ', - ); + ]; - $form['tab_options'] = array( + $form['tab_options'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#tree' => TRUE, - ); - $form['tab_options']['type'] = array( + ]; + $form['tab_options']['type'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#title' => $this->t('Parent menu item'), '#type' => 'radios', - '#options' => array('none' => $this->t('Already exists'), 'normal' => $this->t('Normal menu item'), 'tab' => $this->t('Menu tab')), + '#options' => ['none' => $this->t('Already exists'), 'normal' => $this->t('Normal menu item'), 'tab' => $this->t('Menu tab')], '#default_value' => $tab_options['type'], - ); - $form['tab_options']['title'] = array( + ]; + $form['tab_options']['title'] = [ '#prefix' => '
          ', '#title' => $this->t('Title'), '#type' => 'textfield', '#default_value' => $tab_options['title'], '#description' => $this->t('If creating a parent menu item, enter the title of the item.'), - '#states' => array( - 'visible' => array( - array( - ':input[name="tab_options[type]"]' => array('value' => 'normal'), - ), - array( - ':input[name="tab_options[type]"]' => array('value' => 'tab'), - ), - ), - ), - ); - $form['tab_options']['description'] = array( + '#states' => [ + 'visible' => [ + [ + ':input[name="tab_options[type]"]' => ['value' => 'normal'], + ], + [ + ':input[name="tab_options[type]"]' => ['value' => 'tab'], + ], + ], + ], + ]; + $form['tab_options']['description'] = [ '#title' => $this->t('Description'), '#type' => 'textfield', '#default_value' => $tab_options['description'], '#description' => $this->t('If creating a parent menu item, enter the description of the item.'), - '#states' => array( - 'visible' => array( - array( - ':input[name="tab_options[type]"]' => array('value' => 'normal'), - ), - array( - ':input[name="tab_options[type]"]' => array('value' => 'tab'), - ), - ), - ), - ); - $form['tab_options']['weight'] = array( + '#states' => [ + 'visible' => [ + [ + ':input[name="tab_options[type]"]' => ['value' => 'normal'], + ], + [ + ':input[name="tab_options[type]"]' => ['value' => 'tab'], + ], + ], + ], + ]; + $form['tab_options']['weight'] = [ '#suffix' => '
          ', '#title' => $this->t('Tab weight'), '#type' => 'textfield', '#default_value' => $tab_options['weight'], '#size' => 5, '#description' => $this->t('If the parent menu item is a tab, enter the weight of the tab. Heavier tabs will sink and the lighter tabs will be positioned nearer to the first menu item.'), - '#states' => array( - 'visible' => array( - ':input[name="tab_options[type]"]' => array('value' => 'tab'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="tab_options[type]"]' => ['value' => 'tab'], + ], + ], + ]; break; } } @@ -441,7 +441,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { if ($form_state->get('section') == 'menu') { $path = $this->getOption('path'); - $menu_type = $form_state->getValue(array('menu', 'type')); + $menu_type = $form_state->getValue(['menu', 'type']); if ($menu_type == 'normal' && strpos($path, '%') !== FALSE) { $form_state->setError($form['menu']['type'], $this->t('Views cannot create normal menu items for paths with a % in them.')); } @@ -454,7 +454,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { } } - if ($menu_type != 'none' && $form_state->isValueEmpty(array('menu', 'title'))) { + if ($menu_type != 'none' && $form_state->isValueEmpty(['menu', 'title'])) { $form_state->setError($form['menu']['title'], $this->t('Title is required for this menu type.')); } } @@ -472,7 +472,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { list($menu['menu_name'], $menu['parent']) = explode(':', $menu['parent'], 2); $this->setOption('menu', $menu); // send ajax form to options page if we use it. - if ($form_state->getValue(array('menu', 'type')) == 'default tab') { + if ($form_state->getValue(['menu', 'type']) == 'default tab') { $form_state->get('view')->addFormToStack('display', $this->display['id'], 'tab_options'); } break; @@ -490,13 +490,13 @@ public function validate() { $menu = $this->getOption('menu'); if (!empty($menu['type']) && $menu['type'] != 'none' && empty($menu['title'])) { - $errors[] = $this->t('Display @display is set to use a menu but the menu link text is not set.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display @display is set to use a menu but the menu link text is not set.', ['@display' => $this->display['display_title']]); } if ($menu['type'] == 'default tab') { $tab_options = $this->getOption('tab_options'); if (!empty($tab_options['type']) && $tab_options['type'] != 'none' && empty($tab_options['title'])) { - $errors[] = $this->t('Display @display is set to use a parent menu but the parent menu link text is not set.', array('@display' => $this->display['display_title'])); + $errors[] = $this->t('Display @display is set to use a parent menu but the parent menu link text is not set.', ['@display' => $this->display['display_title']]); } } @@ -507,21 +507,21 @@ public function validate() { * {@inheritdoc} */ public function getArgumentText() { - return array( + return [ 'filter value not present' => $this->t('When the filter value is NOT in the URL'), 'filter value present' => $this->t('When the filter value IS in the URL or a default is provided'), 'description' => $this->t('The contextual filter values are provided by the URL.'), - ); + ]; } /** * {@inheritdoc} */ public function getPagerText() { - return array( + return [ 'items per page title' => $this->t('Items per page'), 'items per page description' => $this->t('Enter 0 for no limit.') - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php index 966cc1ad..17d8663e 100644 --- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php @@ -109,8 +109,8 @@ protected function isDefaultTabPath() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['path'] = array('default' => ''); - $options['route_name'] = array('default' => ''); + $options['path'] = ['default' => '']; + $options['route_name'] = ['default' => '']; return $options; } @@ -127,13 +127,13 @@ protected function defineOptions() { * The route for the view. */ protected function getRoute($view_id, $display_id) { - $defaults = array( + $defaults = [ '_controller' => 'Drupal\views\Routing\ViewPageController::handle', '_title' => $this->view->getTitle(), 'view_id' => $view_id, 'display_id' => $display_id, '_view_display_show_admin_links' => $this->getOption('show_admin_links'), - ); + ]; // @todo How do we apply argument validation? $bits = explode('/', $this->getOption('path')); @@ -145,7 +145,7 @@ protected function getRoute($view_id, $display_id) { $argument_ids = array_keys((array) $this->getOption('arguments')); $total_arguments = count($argument_ids); - $argument_map = array(); + $argument_map = []; // Replace arguments in the views UI (defined via %) with parameters in // routes (defined via {}). As a name for the parameter use arg_$key, so @@ -223,22 +223,65 @@ public function collectRoutes(RouteCollection $collection) { $route_name = "view.$view_id.$display_id"; } $collection->add($route_name, $route); - return array("$view_id.$display_id" => $route_name); + return ["$view_id.$display_id" => $route_name]; + } + + /** + * Determines whether the view overrides the given route. + * + * @param string $view_path + * The path of the view. + * @param \Symfony\Component\Routing\Route $view_route + * The route of the view. + * @param \Symfony\Component\Routing\Route $route + * The route itself. + * + * @return bool + * TRUE, when the view should override the given route. + */ + protected function overrideApplies($view_path, Route $view_route, Route $route) { + return $this->overrideAppliesPathAndMethod($view_path, $view_route, $route) + && (!$route->hasRequirement('_format') || $route->getRequirement('_format') === 'html'); + } + + /** + * Determines whether a override for the path and method should happen. + * + * @param string $view_path + * The path of the view. + * @param \Symfony\Component\Routing\Route $view_route + * The route of the view. + * @param \Symfony\Component\Routing\Route $route + * The route itself. + * + * @return bool + * TRUE, when the view should override the given route. + */ + protected function overrideAppliesPathAndMethod($view_path, Route $view_route, Route $route) { + // Find all paths which match the path of the current display.. + $route_path = RouteCompiler::getPathWithoutDefaults($route); + $route_path = RouteCompiler::getPatternOutline($route_path); + + // Ensure that we don't override a route which is already controlled by + // views. + return !$route->hasDefault('view_id') + && ('/' . $view_path == $route_path) + // Also ensure that we don't override for example REST routes. + && (!$route->getMethods() || in_array('GET', $route->getMethods())); } /** * {@inheritdoc} */ public function alterRoutes(RouteCollection $collection) { - $view_route_names = array(); + $view_route_names = []; $view_path = $this->getPath(); + $view_id = $this->view->storage->id(); + $display_id = $this->display['id']; + $view_route = $this->getRoute($view_id, $display_id); + foreach ($collection->all() as $name => $route) { - // Find all paths which match the path of the current display.. - $route_path = RouteCompiler::getPathWithoutDefaults($route); - $route_path = RouteCompiler::getPatternOutline($route_path); - // Ensure that we don't override a route which is already controlled by - // views. Also ensure that we don't override for example REST routes. - if (!$route->hasDefault('view_id') && ('/' . $view_path == $route_path) && (!$route->getMethods() || in_array('GET', $route->getMethods()))) { + if ($this->overrideApplies($view_path, $view_route, $route)) { $parameters = $route->compile()->getPathVariables(); // @todo Figure out whether we need to merge some settings (like @@ -248,13 +291,9 @@ public function alterRoutes(RouteCollection $collection) { $original_route = $collection->get($name); $collection->remove($name); - $view_id = $this->view->storage->id(); - $display_id = $this->display['id']; - $route = $this->getRoute($view_id, $display_id); - - $path = $route->getPath(); + $path = $view_route->getPath(); // Replace the path with the original parameter names and add a mapping. - $argument_map = array(); + $argument_map = []; // We assume that the numeric ids of the parameters match the one from // the view argument handlers. foreach ($parameters as $position => $parameter_name) { @@ -263,17 +302,17 @@ public function alterRoutes(RouteCollection $collection) { } // Copy the original options from the route, so for example we ensure // that parameter conversion options is carried over. - $route->setOptions($route->getOptions() + $original_route->getOptions()); + $view_route->setOptions($view_route->getOptions() + $original_route->getOptions()); if ($original_route->hasDefault('_title_callback')) { - $route->setDefault('_title_callback', $original_route->getDefault('_title_callback')); + $view_route->setDefault('_title_callback', $original_route->getDefault('_title_callback')); } // Set the corrected path and the mapping to the route object. - $route->setOption('_view_argument_map', $argument_map); - $route->setPath($path); + $view_route->setOption('_view_argument_map', $argument_map); + $view_route->setPath($path); - $collection->add($name, $route); + $collection->add($name, $view_route); $view_route_names[$view_id . '.' . $display_id] = $name; } } @@ -285,7 +324,7 @@ public function alterRoutes(RouteCollection $collection) { * {@inheritdoc} */ public function getMenuLinks() { - $links = array(); + $links = []; // Replace % with the link to our standard views argument loader // views_arg_load -- which lives in views.module. @@ -297,7 +336,7 @@ public function getMenuLinks() { foreach ($bits as $pos => $bit) { if ($bit == '%') { // If a view requires any arguments we cannot create a static menu link. - return array(); + return []; } } @@ -310,15 +349,15 @@ public function getMenuLinks() { if ($path) { $menu = $this->getOption('menu'); if (!empty($menu['type']) && $menu['type'] == 'normal') { - $links[$menu_link_id] = array(); + $links[$menu_link_id] = []; // Some views might override existing paths, so we have to set the route // name based upon the altering. - $links[$menu_link_id] = array( + $links[$menu_link_id] = [ 'route_name' => $this->getRouteName(), // Identify URL embedded arguments and correlate them to a handler. - 'load arguments' => array($this->view->storage->id(), $this->display['id'], '%index'), + 'load arguments' => [$this->view->storage->id(), $this->display['id'], '%index'], 'id' => $menu_link_id, - ); + ]; $links[$menu_link_id]['title'] = $menu['title']; $links[$menu_link_id]['description'] = $menu['description']; $links[$menu_link_id]['parent'] = $menu['parent']; @@ -332,10 +371,10 @@ public function getMenuLinks() { // Insert item into the proper menu. $links[$menu_link_id]['menu_name'] = $menu['menu_name']; // Keep track of where we came from. - $links[$menu_link_id]['metadata'] = array( + $links[$menu_link_id]['metadata'] = [ 'view_id' => $view_id, 'display_id' => $display_id, - ); + ]; } } @@ -365,13 +404,13 @@ public function execute() { public function optionsSummary(&$categories, &$options) { parent::optionsSummary($categories, $options); - $categories['page'] = array( + $categories['page'] = [ 'title' => $this->t('Page settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -10, - ), - ); + ], + ]; $path = strip_tags($this->getOption('path')); @@ -382,11 +421,11 @@ public function optionsSummary(&$categories, &$options) { $path = '/' . $path; } - $options['path'] = array( + $options['path'] = [ 'category' => 'page', 'title' => $this->t('Path'), 'value' => views_ui_truncate($path, 24), - ); + ]; } /** @@ -398,17 +437,17 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($form_state->get('section')) { case 'path': $form['#title'] .= $this->t('The menu path or URL of this view'); - $form['path'] = array( + $form['path'] = [ '#type' => 'textfield', '#title' => $this->t('Path'), '#description' => $this->t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed". If needed you can even specify named route parameters like taxonomy/term/%taxonomy_term'), '#default_value' => $this->getOption('path'), '#field_prefix' => '' . $this->url('', [], ['absolute' => TRUE]), '#field_suffix' => '‎', - '#attributes' => array('dir' => LanguageInterface::DIRECTION_LTR), + '#attributes' => ['dir' => LanguageInterface::DIRECTION_LTR], // Account for the leading backslash. '#maxlength' => 254, - ); + ]; break; } } @@ -451,7 +490,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { * A list of error strings. */ protected function validatePath($path) { - $errors = array(); + $errors = []; if (strpos($path, '%') === 0) { $errors[] = $this->t('"%" may not be used for the first segment of a path.'); } @@ -518,7 +557,7 @@ public function getRouteName() { * {@inheritdoc} */ public function getAlteredRouteNames() { - return $this->state->get('views.view_route_names') ?: array(); + return $this->state->get('views.view_route_names') ?: []; } /** diff --git a/core/modules/views/src/Plugin/views/display_extender/DisplayExtenderPluginBase.php b/core/modules/views/src/Plugin/views/display_extender/DisplayExtenderPluginBase.php index d54fc1cd..630c0f0a 100644 --- a/core/modules/views/src/Plugin/views/display_extender/DisplayExtenderPluginBase.php +++ b/core/modules/views/src/Plugin/views/display_extender/DisplayExtenderPluginBase.php @@ -36,45 +36,45 @@ abstract class DisplayExtenderPluginBase extends PluginBase { /** * Provide a form to edit options for this plugin. */ - public function defineOptionsAlter(&$options) { } + public function defineOptionsAlter(&$options) {} /** * Provide a form to edit options for this plugin. */ - public function buildOptionsForm(&$form, FormStateInterface $form_state) { } + public function buildOptionsForm(&$form, FormStateInterface $form_state) {} /** * Validate the options form. */ - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} /** * Handle any special handling on the validate form. */ - public function submitOptionsForm(&$form, FormStateInterface $form_state) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state) {} /** * Set up any variables on the view prior to execution. */ - public function preExecute() { } + public function preExecute() {} /** * Inject anything into the query that the display_extender handler needs. */ - public function query() { } + public function query() {} /** * Provide the default summary for options in the views UI. * * This output is returned as an array. */ - public function optionsSummary(&$categories, &$options) { } + public function optionsSummary(&$categories, &$options) {} /** * Static member function to list which sections are defaultable * and what items each section contains. */ - public function defaultableSections(&$sections, $section = NULL) { } + public function defaultableSections(&$sections, $section = NULL) {} } diff --git a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php index 62cb79c1..13d6b112 100644 --- a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php +++ b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php @@ -26,13 +26,13 @@ abstract class ExposedFormPluginBase extends PluginBase implements CacheableDepe */ protected function defineOptions() { $options = parent::defineOptions(); - $options['submit_button'] = array('default' => $this->t('Apply')); - $options['reset_button'] = array('default' => FALSE); - $options['reset_button_label'] = array('default' => $this->t('Reset')); - $options['exposed_sorts_label'] = array('default' => $this->t('Sort by')); - $options['expose_sort_order'] = array('default' => TRUE); - $options['sort_asc_label'] = array('default' => $this->t('Asc')); - $options['sort_desc_label'] = array('default' => $this->t('Desc')); + $options['submit_button'] = ['default' => $this->t('Apply')]; + $options['reset_button'] = ['default' => FALSE]; + $options['reset_button_label'] = ['default' => $this->t('Reset')]; + $options['exposed_sorts_label'] = ['default' => $this->t('Sort by')]; + $options['expose_sort_order'] = ['default' => TRUE]; + $options['sort_asc_label'] = ['default' => $this->t('Asc')]; + $options['sort_desc_label'] = ['default' => $this->t('Desc')]; return $options; } @@ -41,69 +41,69 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['submit_button'] = array( + $form['submit_button'] = [ '#type' => 'textfield', '#title' => $this->t('Submit button text'), '#default_value' => $this->options['submit_button'], '#required' => TRUE, - ); + ]; - $form['reset_button'] = array( + $form['reset_button'] = [ '#type' => 'checkbox', '#title' => $this->t('Include reset button (resets all applied exposed filters)'), '#default_value' => $this->options['reset_button'], - ); + ]; - $form['reset_button_label'] = array( + $form['reset_button_label'] = [ '#type' => 'textfield', '#title' => $this->t('Reset button label'), '#description' => $this->t('Text to display in the reset button of the exposed form.'), '#default_value' => $this->options['reset_button_label'], '#required' => TRUE, - '#states' => array( - 'invisible' => array( - 'input[name="exposed_form_options[reset_button]"]' => array('checked' => FALSE), - ), - ), - ); - - $form['exposed_sorts_label'] = array( + '#states' => [ + 'invisible' => [ + 'input[name="exposed_form_options[reset_button]"]' => ['checked' => FALSE], + ], + ], + ]; + + $form['exposed_sorts_label'] = [ '#type' => 'textfield', '#title' => $this->t('Exposed sorts label'), '#default_value' => $this->options['exposed_sorts_label'], '#required' => TRUE, - ); + ]; - $form['expose_sort_order'] = array( + $form['expose_sort_order'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow people to choose the sort order'), '#description' => $this->t('If sort order is not exposed, the sort criteria settings for each sort will determine its order.'), '#default_value' => $this->options['expose_sort_order'], - ); + ]; - $form['sort_asc_label'] = array( + $form['sort_asc_label'] = [ '#type' => 'textfield', '#title' => $this->t('Label for ascending sort'), '#default_value' => $this->options['sort_asc_label'], '#required' => TRUE, - '#states' => array( - 'visible' => array( - 'input[name="exposed_form_options[expose_sort_order]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['sort_desc_label'] = array( + '#states' => [ + 'visible' => [ + 'input[name="exposed_form_options[expose_sort_order]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['sort_desc_label'] = [ '#type' => 'textfield', '#title' => $this->t('Label for descending sort'), '#default_value' => $this->options['sort_desc_label'], '#required' => TRUE, - '#states' => array( - 'visible' => array( - 'input[name="exposed_form_options[expose_sort_order]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + 'input[name="exposed_form_options[expose_sort_order]"]' => ['checked' => TRUE], + ], + ], + ]; } /** @@ -133,9 +133,15 @@ public function renderExposedForm($block = FALSE) { } $form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state); + $errors = $form_state->getErrors(); + + // If the exposed form had errors, do not build the view. + if (!empty($errors)) { + $this->view->build_info['abort'] = TRUE; + } if (!$this->view->display_handler->displaysExposed() || (!$block && $this->view->display_handler->getOption('exposed_block'))) { - return array(); + return []; } else { return $form; @@ -147,19 +153,19 @@ public function renderExposedForm($block = FALSE) { */ public function query() { $view = $this->view; - $exposed_data = isset($view->exposed_data) ? $view->exposed_data : array(); + $exposed_data = isset($view->exposed_data) ? $view->exposed_data : []; $sort_by = isset($exposed_data['sort_by']) ? $exposed_data['sort_by'] : NULL; if (!empty($sort_by)) { // Make sure the original order of sorts is preserved // (e.g. a sticky sort is often first) if (isset($view->sort[$sort_by])) { - $view->query->orderby = array(); + $view->query->orderby = []; foreach ($view->sort as $key => $sort) { if (!$sort->isExposed()) { $sort->query(); } elseif ($key == $sort_by) { - if (isset($exposed_data['sort_order']) && in_array($exposed_data['sort_order'], array('ASC', 'DESC'))) { + if (isset($exposed_data['sort_order']) && in_array($exposed_data['sort_order'], ['ASC', 'DESC'])) { $sort->options['order'] = $exposed_data['sort_order']; } $sort->setRelationship(); @@ -173,22 +179,22 @@ public function query() { /** * {@inheritdoc} */ - public function preRender($values) { } + public function preRender($values) {} /** * {@inheritdoc} */ - public function postRender(&$output) { } + public function postRender(&$output) {} /** * {@inheritdoc} */ - public function preExecute() { } + public function preExecute() {} /** * {@inheritdoc} */ - public function postExecute() { } + public function postExecute() {} /** * {@inheritdoc} @@ -199,7 +205,7 @@ public function exposedFormAlter(&$form, FormStateInterface $form_state) { } // Check if there is exposed sorts for this view - $exposed_sorts = array(); + $exposed_sorts = []; foreach ($this->view->sort as $id => $handler) { if ($handler->canExpose() && $handler->isExposed()) { $exposed_sorts[$id] = Html::escape($handler->options['expose']['label']); @@ -207,15 +213,15 @@ public function exposedFormAlter(&$form, FormStateInterface $form_state) { } if (count($exposed_sorts)) { - $form['sort_by'] = array( + $form['sort_by'] = [ '#type' => 'select', '#options' => $exposed_sorts, '#title' => $this->options['exposed_sorts_label'], - ); - $sort_order = array( + ]; + $sort_order = [ 'ASC' => $this->options['sort_asc_label'], 'DESC' => $this->options['sort_desc_label'], - ); + ]; $user_input = $form_state->getUserInput(); if (isset($user_input['sort_by']) && isset($this->view->sort[$user_input['sort_by']])) { $default_sort_order = $this->view->sort[$user_input['sort_by']]->options['order']; @@ -232,22 +238,22 @@ public function exposedFormAlter(&$form, FormStateInterface $form_state) { } if ($this->options['expose_sort_order']) { - $form['sort_order'] = array( + $form['sort_order'] = [ '#type' => 'select', '#options' => $sort_order, - '#title' => $this->t('Order', array(), array('context' => 'Sort order')), + '#title' => $this->t('Order', [], ['context' => 'Sort order']), '#default_value' => $default_sort_order, - ); + ]; } $form['submit']['#weight'] = 10; } if (!empty($this->options['reset_button'])) { - $form['actions']['reset'] = array( + $form['actions']['reset'] = [ '#value' => $this->options['reset_button_label'], '#type' => 'submit', '#weight' => 10, - ); + ]; // Get an array of exposed filters, keyed by identifier option. $exposed_filters = []; @@ -323,7 +329,7 @@ public function resetForm(&$form, FormStateInterface $form_state) { } else { $form_state->setRebuild(); - $this->view->exposed_data = array(); + $this->view->exposed_data = []; } $form_state->setRedirect(''); diff --git a/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php b/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php index 8b885978..38a52836 100644 --- a/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php +++ b/core/modules/views/src/Plugin/views/exposed_form/InputRequired.php @@ -21,28 +21,28 @@ class InputRequired extends ExposedFormPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['text_input_required'] = array('default' => $this->t('Select any filter and click on Apply to see results')); - $options['text_input_required_format'] = array('default' => NULL); + $options['text_input_required'] = ['default' => $this->t('Select any filter and click on Apply to see results')]; + $options['text_input_required_format'] = ['default' => NULL]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['text_input_required'] = array( + $form['text_input_required'] = [ '#type' => 'text_format', '#title' => $this->t('Text on demand'), '#description' => $this->t('Text to display instead of results until the user selects and applies an exposed filter.'), '#default_value' => $this->options['text_input_required'], '#format' => isset($this->options['text_input_required_format']) ? $this->options['text_input_required_format'] : filter_default_format(), '#editor' => FALSE, - ); + ]; } public function submitOptionsForm(&$form, FormStateInterface $form_state) { $exposed_form_options = $form_state->getValue('exposed_form_options'); - $form_state->setValue(array('exposed_form_options', 'text_input_required_format'), $exposed_form_options['text_input_required']['format']); - $form_state->setValue(array('exposed_form_options', 'text_input_required'), $exposed_form_options['text_input_required']['value']); + $form_state->setValue(['exposed_form_options', 'text_input_required_format'], $exposed_form_options['text_input_required']['format']); + $form_state->setValue(['exposed_form_options', 'text_input_required'], $exposed_form_options['text_input_required']['value']); parent::submitOptionsForm($form, $form_state); } @@ -72,7 +72,7 @@ public function preRender($values) { // text to display instead of results until the user selects and applies // an exposed filter. if (!$this->exposedFilterApplied()) { - $options = array( + $options = [ 'id' => 'area', 'table' => 'views', 'field' => 'area', @@ -88,14 +88,14 @@ public function preRender($values) { 'value' => $this->options['text_input_required'], 'format' => $this->options['text_input_required_format'], ], - ); + ]; $handler = Views::handlerManager('area')->getHandler($options); $handler->init($this->view, $this->displayHandler, $options); - $this->displayHandler->handlers['empty'] = array( + $this->displayHandler->handlers['empty'] = [ 'area' => $handler, - ); + ]; // Override the existing empty result message (if applicable). - $this->displayHandler->setOption('empty', array('text' => $options)); + $this->displayHandler->setOption('empty', ['text' => $options]); } } @@ -104,7 +104,7 @@ public function query() { // We return with no query; this will force the empty text. $this->view->built = TRUE; $this->view->executed = TRUE; - $this->view->result = array(); + $this->view->result = []; } else { parent::query(); diff --git a/core/modules/views/src/Plugin/views/field/Boolean.php b/core/modules/views/src/Plugin/views/field/Boolean.php index 59d3b292..75f097e1 100644 --- a/core/modules/views/src/Plugin/views/field/Boolean.php +++ b/core/modules/views/src/Plugin/views/field/Boolean.php @@ -34,10 +34,10 @@ class Boolean extends FieldPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['type'] = array('default' => 'yes-no'); - $options['type_custom_true'] = array('default' => ''); - $options['type_custom_false'] = array('default' => ''); - $options['not'] = array('default' => FALSE); + $options['type'] = ['default' => 'yes-no']; + $options['type_custom_true'] = ['default' => '']; + $options['type_custom_false'] = ['default' => '']; + $options['not'] = ['default' => FALSE]; return $options; } @@ -48,16 +48,16 @@ protected function defineOptions() { public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $default_formats = array( - 'yes-no' => array(t('Yes'), $this->t('No')), - 'true-false' => array(t('True'), $this->t('False')), - 'on-off' => array(t('On'), $this->t('Off')), - 'enabled-disabled' => array(t('Enabled'), $this->t('Disabled')), - 'boolean' => array(1, 0), - 'unicode-yes-no' => array('✔', '✖'), - ); - $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : array(); - $custom_format = array('custom' => array(t('Custom'))); + $default_formats = [ + 'yes-no' => [t('Yes'), $this->t('No')], + 'true-false' => [t('True'), $this->t('False')], + 'on-off' => [t('On'), $this->t('Off')], + 'enabled-disabled' => [t('Enabled'), $this->t('Disabled')], + 'boolean' => [1, 0], + 'unicode-yes-no' => ['✔', '✖'], + ]; + $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : []; + $custom_format = ['custom' => [t('Custom')]]; $this->formats = array_merge($default_formats, $output_formats, $custom_format); } @@ -69,38 +69,38 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $options[$key] = implode('/', $item); } - $form['type'] = array( + $form['type'] = [ '#type' => 'select', '#title' => $this->t('Output format'), '#options' => $options, '#default_value' => $this->options['type'], - ); - $form['type_custom_true'] = array( + ]; + $form['type_custom_true'] = [ '#type' => 'textfield', '#title' => $this->t('Custom output for TRUE'), '#default_value' => $this->options['type_custom_true'], - '#states' => array( - 'visible' => array( - 'select[name="options[type]"]' => array('value' => 'custom'), - ), - ), - ); - $form['type_custom_false'] = array( + '#states' => [ + 'visible' => [ + 'select[name="options[type]"]' => ['value' => 'custom'], + ], + ], + ]; + $form['type_custom_false'] = [ '#type' => 'textfield', '#title' => $this->t('Custom output for FALSE'), '#default_value' => $this->options['type_custom_false'], - '#states' => array( - 'visible' => array( - 'select[name="options[type]"]' => array('value' => 'custom'), - ), - ), - ); - $form['not'] = array( + '#states' => [ + 'visible' => [ + 'select[name="options[type]"]' => ['value' => 'custom'], + ], + ], + ]; + $form['not'] = [ '#type' => 'checkbox', '#title' => $this->t('Reverse'), '#description' => $this->t('If checked, true will be displayed as false.'), '#default_value' => $this->options['not'], - ); + ]; parent::buildOptionsForm($form, $form_state); } diff --git a/core/modules/views/src/Plugin/views/field/Counter.php b/core/modules/views/src/Plugin/views/field/Counter.php index 06d9b561..d32e5e75 100644 --- a/core/modules/views/src/Plugin/views/field/Counter.php +++ b/core/modules/views/src/Plugin/views/field/Counter.php @@ -28,7 +28,7 @@ public function usesGroupBy() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['counter_start'] = array('default' => 1); + $options['counter_start'] = ['default' => 1]; return $options; } @@ -36,13 +36,13 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['counter_start'] = array( + $form['counter_start'] = [ '#type' => 'textfield', '#title' => $this->t('Starting value'), '#default_value' => $this->options['counter_start'], '#description' => $this->t('Specify the number the counter should start at.'), '#size' => 2, - ); + ]; parent::buildOptionsForm($form, $form_state); } diff --git a/core/modules/views/src/Plugin/views/field/Custom.php b/core/modules/views/src/Plugin/views/field/Custom.php index 19552b22..6dfa8ac1 100644 --- a/core/modules/views/src/Plugin/views/field/Custom.php +++ b/core/modules/views/src/Plugin/views/field/Custom.php @@ -37,8 +37,8 @@ protected function defineOptions() { $options = parent::defineOptions(); // Override the alter text option to always alter the text. - $options['alter']['contains']['alter_text'] = array('default' => TRUE); - $options['hide_alter_empty'] = array('default' => FALSE); + $options['alter']['contains']['alter_text'] = ['default' => TRUE]; + $options['hide_alter_empty'] = ['default' => FALSE]; return $options; } @@ -52,7 +52,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { unset($form['alter']['alter_text']); unset($form['alter']['text']['#states']); unset($form['alter']['help']['#states']); - $form['#pre_render'][] = array($this, 'preRenderCustomForm'); + $form['#pre_render'][] = [$this, 'preRenderCustomForm']; } /** diff --git a/core/modules/views/src/Plugin/views/field/Date.php b/core/modules/views/src/Plugin/views/field/Date.php index f5a5204b..ee38a4a6 100644 --- a/core/modules/views/src/Plugin/views/field/Date.php +++ b/core/modules/views/src/Plugin/views/field/Date.php @@ -71,9 +71,9 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['date_format'] = array('default' => 'small'); - $options['custom_date_format'] = array('default' => ''); - $options['timezone'] = array('default' => ''); + $options['date_format'] = ['default' => 'small']; + $options['custom_date_format'] = ['default' => '']; + $options['timezone'] = ['default' => '']; return $options; } @@ -83,15 +83,15 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $date_formats = array(); + $date_formats = []; foreach ($this->dateFormatStorage->loadMultiple() as $machine_name => $value) { - $date_formats[$machine_name] = $this->t('@name format: @date', array('@name' => $value->label(), '@date' => $this->dateFormatter->format(REQUEST_TIME, $machine_name))); + $date_formats[$machine_name] = $this->t('@name format: @date', ['@name' => $value->label(), '@date' => $this->dateFormatter->format(REQUEST_TIME, $machine_name)]); } - $form['date_format'] = array( + $form['date_format'] = [ '#type' => 'select', '#title' => $this->t('Date format'), - '#options' => $date_formats + array( + '#options' => $date_formats + [ 'custom' => $this->t('Custom'), 'raw time ago' => $this->t('Time ago'), 'time ago' => $this->t('Time ago (with "ago" appended)'), @@ -100,32 +100,32 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { 'raw time span' => $this->t('Time span (future dates have "-" prepended)'), 'inverse time span' => $this->t('Time span (past dates have "-" prepended)'), 'time span' => $this->t('Time span (with "ago/hence" appended)'), - ), + ], '#default_value' => isset($this->options['date_format']) ? $this->options['date_format'] : 'small', - ); - $form['custom_date_format'] = array( + ]; + $form['custom_date_format'] = [ '#type' => 'textfield', '#title' => $this->t('Custom date format'), '#description' => $this->t('If "Custom", see the PHP docs for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.'), '#default_value' => isset($this->options['custom_date_format']) ? $this->options['custom_date_format'] : '', - ); + ]; // Setup #states for all possible date_formats on the custom_date_format form element. - foreach (array('custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span') as $custom_date_possible) { - $form['custom_date_format']['#states']['visible'][] = array( - ':input[name="options[date_format]"]' => array('value' => $custom_date_possible), - ); + foreach (['custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span'] as $custom_date_possible) { + $form['custom_date_format']['#states']['visible'][] = [ + ':input[name="options[date_format]"]' => ['value' => $custom_date_possible], + ]; } - $form['timezone'] = array( + $form['timezone'] = [ '#type' => 'select', '#title' => $this->t('Timezone'), '#description' => $this->t('Timezone to be used for date output.'), - '#options' => array('' => $this->t('- Default site/user timezone -')) + system_time_zones(FALSE), + '#options' => ['' => $this->t('- Default site/user timezone -')] + system_time_zones(FALSE, TRUE), '#default_value' => $this->options['timezone'], - ); - foreach (array_merge(array('custom'), array_keys($date_formats)) as $timezone_date_formats) { - $form['timezone']['#states']['visible'][] = array( - ':input[name="options[date_format]"]' => array('value' => $timezone_date_formats), - ); + ]; + foreach (array_merge(['custom'], array_keys($date_formats)) as $timezone_date_formats) { + $form['timezone']['#states']['visible'][] = [ + ':input[name="options[date_format]"]' => ['value' => $timezone_date_formats], + ]; } parent::buildOptionsForm($form, $form_state); @@ -137,35 +137,37 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function render(ResultRow $values) { $value = $this->getValue($values); $format = $this->options['date_format']; - if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span'))) { + if (in_array($format, ['custom', 'raw time ago', 'time ago', 'raw time hence', 'time hence', 'raw time span', 'time span', 'raw time span', 'inverse time span', 'time span'])) { $custom_format = $this->options['custom_date_format']; } if ($value) { $timezone = !empty($this->options['timezone']) ? $this->options['timezone'] : NULL; - $time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence) + // Will be positive for a datetime in the past (ago), and negative for a + // datetime in the future (hence). + $time_diff = REQUEST_TIME - $value; switch ($format) { case 'raw time ago': - return $this->dateFormatter->formatTimeDiffSince($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2)); + return $this->dateFormatter->formatTimeDiffSince($value, ['granularity' => is_numeric($custom_format) ? $custom_format : 2]); case 'time ago': - return $this->t('%time ago', array('%time' => $this->dateFormatter->formatTimeDiffSince($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2)))); + return $this->t('%time ago', ['%time' => $this->dateFormatter->formatTimeDiffSince($value, ['granularity' => is_numeric($custom_format) ? $custom_format : 2])]); case 'raw time hence': - return $this->dateFormatter->formatTimeDiffUntil($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2)); + return $this->dateFormatter->formatTimeDiffUntil($value, ['granularity' => is_numeric($custom_format) ? $custom_format : 2]); case 'time hence': - return $this->t('%time hence', array('%time' => $this->dateFormatter->formatTimeDiffUntil($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2)))); + return $this->t('%time hence', ['%time' => $this->dateFormatter->formatTimeDiffUntil($value, ['granularity' => is_numeric($custom_format) ? $custom_format : 2])]); case 'raw time span': - return ($time_diff < 0 ? '-' : '') . $this->dateFormatter->formatTimeDiffSince($value, array('strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2)); + return ($time_diff < 0 ? '-' : '') . $this->dateFormatter->formatTimeDiffSince($value, ['strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2]); case 'inverse time span': - return ($time_diff > 0 ? '-' : '') . $this->dateFormatter->formatTimeDiffSince($value, array('strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2)); + return ($time_diff > 0 ? '-' : '') . $this->dateFormatter->formatTimeDiffSince($value, ['strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2]); case 'time span': - $time = $this->dateFormatter->formatTimeDiffSince($value, array('strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2)); - return ($time_diff < 0) ? $this->t('%time hence', array('%time' => $time)) : $this->t('%time ago', array('%time' => $time)); + $time = $this->dateFormatter->formatTimeDiffSince($value, ['strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2]); + return ($time_diff < 0) ? $this->t('%time hence', ['%time' => $time]) : $this->t('%time ago', ['%time' => $time]); case 'custom': if ($custom_format == 'r') { diff --git a/core/modules/views/src/Plugin/views/field/Dropbutton.php b/core/modules/views/src/Plugin/views/field/Dropbutton.php index f5cf4d34..b5a9b60d 100644 --- a/core/modules/views/src/Plugin/views/field/Dropbutton.php +++ b/core/modules/views/src/Plugin/views/field/Dropbutton.php @@ -20,10 +20,10 @@ public function render(ResultRow $values) { $links = $this->getLinks(); if (!empty($links)) { - return array( + return [ '#type' => 'dropbutton', '#links' => $links, - ); + ]; } else { return ''; diff --git a/core/modules/views/src/Plugin/views/field/EntityField.php b/core/modules/views/src/Plugin/views/field/EntityField.php new file mode 100644 index 00000000..ee2882c3 --- /dev/null +++ b/core/modules/views/src/Plugin/views/field/EntityField.php @@ -0,0 +1,1118 @@ +base_table. + * + * @var string + */ + public $base_table; + + /** + * An array of formatter options. + * + * @var array + */ + protected $formatterOptions; + + /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** + * The field formatter plugin manager. + * + * @var \Drupal\Core\Field\FormatterPluginManager + */ + protected $formatterPluginManager; + + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * The renderer. + * + * @var \Drupal\Core\Render\RendererInterface + */ + protected $renderer; + + /** + * The field type plugin manager. + * + * @var \Drupal\Core\Field\FieldTypePluginManagerInterface + */ + protected $fieldTypePluginManager; + + /** + * Static cache for ::getEntityFieldRenderer(). + * + * @var \Drupal\views\Entity\Render\EntityFieldRenderer + */ + protected $entityFieldRenderer; + + /** + * Constructs a \Drupal\field\Plugin\views\field\Field object. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The field formatter plugin manager. + * @param \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager + * The field formatter plugin manager. + * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager + * The field plugin type manager. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + * @param \Drupal\Core\Render\RendererInterface $renderer + * The renderer. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, FormatterPluginManager $formatter_plugin_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, LanguageManagerInterface $language_manager, RendererInterface $renderer) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + + $this->entityManager = $entity_manager; + $this->formatterPluginManager = $formatter_plugin_manager; + $this->fieldTypePluginManager = $field_type_plugin_manager; + $this->languageManager = $language_manager; + $this->renderer = $renderer; + + // @todo Unify 'entity field'/'field_name' instead of converting back and + // forth. https://www.drupal.org/node/2410779 + if (isset($this->definition['entity field'])) { + $this->definition['field_name'] = $this->definition['entity field']; + } + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.manager'), + $container->get('plugin.manager.field.formatter'), + $container->get('plugin.manager.field.field_type'), + $container->get('language_manager'), + $container->get('renderer') + ); + } + + /** + * {@inheritdoc} + */ + public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + parent::init($view, $display, $options); + + $this->multiple = FALSE; + $this->limit_values = FALSE; + + $field_definition = $this->getFieldDefinition(); + $cardinality = $field_definition->getFieldStorageDefinition()->getCardinality(); + if ($field_definition->getFieldStorageDefinition()->isMultiple()) { + $this->multiple = TRUE; + + // If "Display all values in the same row" is FALSE, then we always limit + // in order to show a single unique value per row. + if (!$this->options['group_rows']) { + $this->limit_values = TRUE; + } + + // If "First and last only" is chosen, limit the values + if (!empty($this->options['delta_first_last'])) { + $this->limit_values = TRUE; + } + + // Otherwise, we only limit values if the user hasn't selected "all", 0, or + // the value matching field cardinality. + if ((($this->options['delta_limit'] > 0) && ($this->options['delta_limit'] != $cardinality)) || intval($this->options['delta_offset'])) { + $this->limit_values = TRUE; + } + } + } + + /** + * {@inheritdoc} + */ + protected function getEntityManager() { + return $this->entityManager; + } + + /** + * {@inheritdoc} + */ + public function access(AccountInterface $account) { + $access_control_handler = $this->entityManager->getAccessControlHandler($this->getEntityType()); + return $access_control_handler->fieldAccess('view', $this->getFieldDefinition(), $account); + } + + /** + * Called to add the field to a query. + * + * By default, all needed data is taken from entities loaded by the query + * plugin. Columns are added only if they are used in groupings. + */ + public function query($use_groupby = FALSE) { + $fields = $this->additional_fields; + // No need to add the entity type. + $entity_type_key = array_search('entity_type', $fields); + if ($entity_type_key !== FALSE) { + unset($fields[$entity_type_key]); + } + + if ($use_groupby) { + // Add the fields that we're actually grouping on. + $options = []; + if ($this->options['group_column'] != 'entity_id') { + $options = [$this->options['group_column'] => $this->options['group_column']]; + } + $options += is_array($this->options['group_columns']) ? $this->options['group_columns'] : []; + + // Go through the list and determine the actual column name from field api. + $fields = []; + $table_mapping = $this->getTableMapping(); + $field_definition = $this->getFieldStorageDefinition(); + + foreach ($options as $column) { + $fields[$column] = $table_mapping->getFieldColumnName($field_definition, $column); + } + + $this->group_fields = $fields; + } + + // Add additional fields (and the table join itself) if needed. + if ($this->add_field_table($use_groupby)) { + $this->ensureMyTable(); + $this->addAdditionalFields($fields); + } + + // Let the entity field renderer alter the query if needed. + $this->getEntityFieldRenderer()->query($this->query, $this->relationship); + } + + /** + * Determine if the field table should be added to the query. + */ + public function add_field_table($use_groupby) { + // Grouping is enabled. + if ($use_groupby) { + return TRUE; + } + // This a multiple value field, but "group multiple values" is not checked. + if ($this->multiple && !$this->options['group_rows']) { + return TRUE; + } + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function clickSortable() { + // A field is not click sortable if it's a multiple field with + // "group multiple values" checked, since a click sort in that case would + // add a join to the field table, which would produce unwanted duplicates. + if ($this->multiple && $this->options['group_rows']) { + return FALSE; + } + + // If field definition is set, use that. + if (isset($this->definition['click sortable'])) { + return (bool) $this->definition['click sortable']; + } + + // Default to true. + return TRUE; + } + + /** + * Called to determine what to tell the clicksorter. + */ + public function clickSort($order) { + // No column selected, can't continue. + if (empty($this->options['click_sort_column'])) { + return; + } + + $this->ensureMyTable(); + $field_storage_definition = $this->getFieldStorageDefinition(); + $column = $this->getTableMapping()->getFieldColumnName($field_storage_definition, $this->options['click_sort_column']); + if (!isset($this->aliases[$column])) { + // Column is not in query; add a sort on it (without adding the column). + $this->aliases[$column] = $this->tableAlias . '.' . $column; + } + $this->query->addOrderBy(NULL, NULL, $order, $this->aliases[$column]); + } + + /** + * Gets the field storage definition. + * + * @return \Drupal\Core\Field\FieldStorageDefinitionInterface + * The field storage definition used by this handler. + */ + protected function getFieldStorageDefinition() { + $entity_type_id = $this->definition['entity_type']; + $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); + + // @todo Unify 'entity field'/'field_name' instead of converting back and + // forth. https://www.drupal.org/node/2410779 + if (isset($this->definition['field_name']) && isset($field_storage_definitions[$this->definition['field_name']])) { + return $field_storage_definitions[$this->definition['field_name']]; + } + + if (isset($this->definition['entity field']) && isset($field_storage_definitions[$this->definition['entity field']])) { + return $field_storage_definitions[$this->definition['entity field']]; + } + + // The list of field storage definitions above does not include computed + // base fields, so we need to explicitly fetch a list of all base fields in + // order to support them. + // @see \Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions() + $base_fields = $this->entityManager->getBaseFieldDefinitions($entity_type_id); + if (isset($this->definition['field_name']) && isset($base_fields[$this->definition['field_name']])) { + return $base_fields[$this->definition['field_name']]->getFieldStorageDefinition(); + } + } + + /** + * {@inheritdoc} + */ + protected function defineOptions() { + $options = parent::defineOptions(); + + $field_storage_definition = $this->getFieldStorageDefinition(); + $field_type = $this->fieldTypePluginManager->getDefinition($field_storage_definition->getType()); + $column_names = array_keys($field_storage_definition->getColumns()); + $default_column = ''; + // Try to determine a sensible default. + if (count($column_names) == 1) { + $default_column = $column_names[0]; + } + elseif (in_array('value', $column_names)) { + $default_column = 'value'; + } + + // If the field has a "value" column, we probably need that one. + $options['click_sort_column'] = [ + 'default' => $default_column, + ]; + + if (isset($this->definition['default_formatter'])) { + $options['type'] = ['default' => $this->definition['default_formatter']]; + } + elseif (isset($field_type['default_formatter'])) { + $options['type'] = ['default' => $field_type['default_formatter']]; + } + else { + $options['type'] = ['default' => '']; + } + + $options['settings'] = [ + 'default' => isset($this->definition['default_formatter_settings']) ? $this->definition['default_formatter_settings'] : [], + ]; + $options['group_column'] = [ + 'default' => $default_column, + ]; + $options['group_columns'] = [ + 'default' => [], + ]; + + // Options used for multiple value fields. + $options['group_rows'] = [ + 'default' => TRUE, + ]; + // If we know the exact number of allowed values, then that can be + // the default. Otherwise, default to 'all'. + $options['delta_limit'] = [ + 'default' => ($field_storage_definition->getCardinality() > 1) ? $field_storage_definition->getCardinality() : 0, + ]; + $options['delta_offset'] = [ + 'default' => 0, + ]; + $options['delta_reversed'] = [ + 'default' => FALSE, + ]; + $options['delta_first_last'] = [ + 'default' => FALSE, + ]; + + $options['multi_type'] = [ + 'default' => 'separator' + ]; + $options['separator'] = [ + 'default' => ', ' + ]; + + $options['field_api_classes'] = [ + 'default' => FALSE, + ]; + + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + parent::buildOptionsForm($form, $form_state); + + $field = $this->getFieldDefinition(); + $formatters = $this->formatterPluginManager->getOptions($field->getType()); + $column_names = array_keys($field->getColumns()); + + // If this is a multiple value field, add its options. + if ($this->multiple) { + $this->multiple_options_form($form, $form_state); + } + + // No need to ask the user anything if the field has only one column. + if (count($field->getColumns()) == 1) { + $form['click_sort_column'] = [ + '#type' => 'value', + '#value' => isset($column_names[0]) ? $column_names[0] : '', + ]; + } + else { + $form['click_sort_column'] = [ + '#type' => 'select', + '#title' => $this->t('Column used for click sorting'), + '#options' => array_combine($column_names, $column_names), + '#default_value' => $this->options['click_sort_column'], + '#description' => $this->t('Used by Style: Table to determine the actual column to click sort the field on. The default is usually fine.'), + ]; + } + + $form['type'] = [ + '#type' => 'select', + '#title' => $this->t('Formatter'), + '#options' => $formatters, + '#default_value' => $this->options['type'], + '#ajax' => [ + 'url' => views_ui_build_form_url($form_state), + ], + '#submit' => [[$this, 'submitTemporaryForm']], + '#executes_submit_callback' => TRUE, + ]; + + $form['field_api_classes'] = [ + '#title' => $this->t('Use field template'), + '#type' => 'checkbox', + '#default_value' => $this->options['field_api_classes'], + '#description' => $this->t('If checked, field api classes will be added by field templates. This is not recommended unless your CSS depends upon these classes. If not checked, template will not be used.'), + '#fieldset' => 'style_settings', + '#weight' => 20, + ]; + + if ($this->multiple) { + $form['field_api_classes']['#description'] .= ' ' . $this->t('Checking this option will cause the group Display Type and Separator values to be ignored.'); + } + + // Get the settings form. + $settings_form = ['#value' => []]; + $format = isset($form_state->getUserInput()['options']['type']) ? $form_state->getUserInput()['options']['type'] : $this->options['type']; + if ($formatter = $this->getFormatterInstance($format)) { + $settings_form = $formatter->settingsForm($form, $form_state); + // Convert field UI selector states to work in the Views field form. + FormHelper::rewriteStatesSelector($settings_form, "fields[{$field->getName()}][settings_edit_form]", 'options'); + } + $form['settings'] = $settings_form; + } + + /** + * {@inheritdoc} + */ + public function submitFormCalculateOptions(array $options, array $form_state_options) { + // When we change the formatter type we don't want to keep any of the + // previous configured formatter settings, as there might be schema + // conflict. + unset($options['settings']); + $options = $form_state_options + $options; + if (!isset($options['settings'])) { + $options['settings'] = []; + } + return $options; + } + + /** + * Provide options for multiple value fields. + */ + public function multiple_options_form(&$form, FormStateInterface $form_state) { + $field = $this->getFieldDefinition(); + + $form['multiple_field_settings'] = [ + '#type' => 'details', + '#title' => $this->t('Multiple field settings'), + '#weight' => 5, + ]; + + $form['group_rows'] = [ + '#title' => $this->t('Display all values in the same row'), + '#type' => 'checkbox', + '#default_value' => $this->options['group_rows'], + '#description' => $this->t('If checked, multiple values for this field will be shown in the same row. If not checked, each value in this field will create a new row. If using group by, please make sure to group by "Entity ID" for this setting to have any effect.'), + '#fieldset' => 'multiple_field_settings', + ]; + + // Make the string translatable by keeping it as a whole rather than + // translating prefix and suffix separately. + list($prefix, $suffix) = explode('@count', $this->t('Display @count value(s)')); + + if ($field->getCardinality() == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) { + $type = 'textfield'; + $options = NULL; + $size = 5; + } + else { + $type = 'select'; + $range = range(1, $field->getCardinality()); + $options = array_combine($range, $range); + $size = 1; + } + $form['multi_type'] = [ + '#type' => 'radios', + '#title' => $this->t('Display type'), + '#options' => [ + 'ul' => $this->t('Unordered list'), + 'ol' => $this->t('Ordered list'), + 'separator' => $this->t('Simple separator'), + ], + '#states' => [ + 'visible' => [ + ':input[name="options[group_rows]"]' => ['checked' => TRUE], + ], + ], + '#default_value' => $this->options['multi_type'], + '#fieldset' => 'multiple_field_settings', + ]; + + $form['separator'] = [ + '#type' => 'textfield', + '#title' => $this->t('Separator'), + '#default_value' => $this->options['separator'], + '#states' => [ + 'visible' => [ + ':input[name="options[group_rows]"]' => ['checked' => TRUE], + ':input[name="options[multi_type]"]' => ['value' => 'separator'], + ], + ], + '#fieldset' => 'multiple_field_settings', + ]; + + $form['delta_limit'] = [ + '#type' => $type, + '#size' => $size, + '#field_prefix' => $prefix, + '#field_suffix' => $suffix, + '#options' => $options, + '#default_value' => $this->options['delta_limit'], + '#prefix' => '
          ', + '#states' => [ + 'visible' => [ + ':input[name="options[group_rows]"]' => ['checked' => TRUE], + ], + ], + '#fieldset' => 'multiple_field_settings', + ]; + + list($prefix, $suffix) = explode('@count', $this->t('starting from @count')); + $form['delta_offset'] = [ + '#type' => 'textfield', + '#size' => 5, + '#field_prefix' => $prefix, + '#field_suffix' => $suffix, + '#default_value' => $this->options['delta_offset'], + '#states' => [ + 'visible' => [ + ':input[name="options[group_rows]"]' => ['checked' => TRUE], + ], + ], + '#description' => $this->t('(first item is 0)'), + '#fieldset' => 'multiple_field_settings', + ]; + $form['delta_reversed'] = [ + '#title' => $this->t('Reversed'), + '#type' => 'checkbox', + '#default_value' => $this->options['delta_reversed'], + '#suffix' => $suffix, + '#states' => [ + 'visible' => [ + ':input[name="options[group_rows]"]' => ['checked' => TRUE], + ], + ], + '#description' => $this->t('(start from last values)'), + '#fieldset' => 'multiple_field_settings', + ]; + $form['delta_first_last'] = [ + '#title' => $this->t('First and last only'), + '#type' => 'checkbox', + '#default_value' => $this->options['delta_first_last'], + '#suffix' => '
          ', + '#states' => [ + 'visible' => [ + ':input[name="options[group_rows]"]' => ['checked' => TRUE], + ], + ], + '#fieldset' => 'multiple_field_settings', + ]; + } + + /** + * Extend the groupby form with group columns. + */ + public function buildGroupByForm(&$form, FormStateInterface $form_state) { + parent::buildGroupByForm($form, $form_state); + // With "field API" fields, the column target of the grouping function + // and any additional grouping columns must be specified. + + $field_columns = array_keys($this->getFieldDefinition()->getColumns()); + $group_columns = [ + 'entity_id' => $this->t('Entity ID'), + ] + array_map('ucfirst', array_combine($field_columns, $field_columns)); + + $form['group_column'] = [ + '#type' => 'select', + '#title' => $this->t('Group column'), + '#default_value' => $this->options['group_column'], + '#description' => $this->t('Select the column of this field to apply the grouping function selected above.'), + '#options' => $group_columns, + ]; + + $options = [ + 'bundle' => 'Bundle', + 'language' => 'Language', + 'entity_type' => 'Entity_type', + ]; + // Add on defined fields, noting that they're prefixed with the field name. + $form['group_columns'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('Group columns (additional)'), + '#default_value' => $this->options['group_columns'], + '#description' => $this->t('Select any additional columns of this field to include in the query and to group on.'), + '#options' => $options + $group_columns, + ]; + } + + public function submitGroupByForm(&$form, FormStateInterface $form_state) { + parent::submitGroupByForm($form, $form_state); + $item = &$form_state->get('handler')->options; + + // Add settings for "field API" fields. + $item['group_column'] = $form_state->getValue(['options', 'group_column']); + $item['group_columns'] = array_filter($form_state->getValue(['options', 'group_columns'])); + } + + /** + * Render all items in this field together. + * + * When using advanced render, each possible item in the list is rendered + * individually. Then the items are all pasted together. + */ + public function renderItems($items) { + if (!empty($items)) { + $items = $this->prepareItemsByDelta($items); + if ($this->options['multi_type'] == 'separator' || !$this->options['group_rows']) { + $separator = $this->options['multi_type'] == 'separator' ? Xss::filterAdmin($this->options['separator']) : ''; + $build = [ + '#type' => 'inline_template', + '#template' => '{{ items | safe_join(separator) }}', + '#context' => ['separator' => $separator, 'items' => $items], + ]; + } + else { + $build = [ + '#theme' => 'item_list', + '#items' => $items, + '#title' => NULL, + '#list_type' => $this->options['multi_type'], + ]; + } + return $this->renderer->render($build); + } + } + + /** + * Adapts the $items according to the delta configuration. + * + * This selects displayed deltas, reorders items, and takes offsets into + * account. + * + * @param array $all_values + * The items for individual rendering. + * + * @return array + * The manipulated items. + */ + protected function prepareItemsByDelta(array $all_values) { + if ($this->options['delta_reversed']) { + $all_values = array_reverse($all_values); + } + + // We are supposed to show only certain deltas. + if ($this->limit_values) { + $row = $this->view->result[$this->view->row_index]; + + // Offset is calculated differently when row grouping for a field is not + // enabled. Since there are multiple rows, delta needs to be taken into + // account, so that different values are shown per row. + if (!$this->options['group_rows'] && isset($this->aliases['delta']) && isset($row->{$this->aliases['delta']})) { + $delta_limit = 1; + $offset = $row->{$this->aliases['delta']}; + } + // Single fields don't have a delta available so choose 0. + elseif (!$this->options['group_rows'] && !$this->multiple) { + $delta_limit = 1; + $offset = 0; + } + else { + $delta_limit = $this->options['delta_limit']; + $offset = intval($this->options['delta_offset']); + + // We should only get here in this case if there is an offset, and in + // that case we are limiting to all values after the offset. + if ($delta_limit === 0) { + $delta_limit = count($all_values) - $offset; + } + } + + // Determine if only the first and last values should be shown. + $delta_first_last = $this->options['delta_first_last']; + + $new_values = []; + for ($i = 0; $i < $delta_limit; $i++) { + $new_delta = $offset + $i; + + if (isset($all_values[$new_delta])) { + // If first-last option was selected, only use the first and last + // values. + if (!$delta_first_last + // Use the first value. + || $new_delta == $offset + // Use the last value. + || $new_delta == ($delta_limit + $offset - 1)) { + $new_values[] = $all_values[$new_delta]; + } + } + } + $all_values = $new_values; + } + + return $all_values; + } + + /** + * {@inheritdoc} + */ + public function preRender(&$values) { + parent::preRender($values); + $this->getEntityFieldRenderer()->preRender($values); + } + + /** + * Returns the entity field renderer. + * + * @return \Drupal\views\Entity\Render\EntityFieldRenderer + * The entity field renderer. + */ + protected function getEntityFieldRenderer() { + if (!isset($this->entityFieldRenderer)) { + // This can be invoked during field handler initialization in which case + // view fields are not set yet. + if (!empty($this->view->field)) { + foreach ($this->view->field as $field) { + // An entity field renderer can handle only a single relationship. + if ($field->relationship == $this->relationship && isset($field->entityFieldRenderer)) { + $this->entityFieldRenderer = $field->entityFieldRenderer; + break; + } + } + } + if (!isset($this->entityFieldRenderer)) { + $entity_type = $this->entityManager->getDefinition($this->getEntityType()); + $this->entityFieldRenderer = new EntityFieldRenderer($this->view, $this->relationship, $this->languageManager, $entity_type, $this->entityManager); + } + } + return $this->entityFieldRenderer; + } + + /** + * Gets an array of items for the field. + * + * @param \Drupal\views\ResultRow $values + * The result row object containing the values. + * + * @return array + * An array of items for the field. + */ + public function getItems(ResultRow $values) { + if (!$this->displayHandler->useGroupBy()) { + $build_list = $this->getEntityFieldRenderer()->render($values, $this); + } + else { + // For grouped results we need to retrieve a massaged entity having + // grouped field values to ensure that "grouped by" values, especially + // those with multiple cardinality work properly. See + // \Drupal\Tests\views\Kernel\QueryGroupByTest::testGroupByFieldWithCardinality. + $display = [ + 'type' => $this->options['type'], + 'settings' => $this->options['settings'], + 'label' => 'hidden', + ]; + // Optional relationships may not provide an entity at all. So we can't + // use createEntityForGroupBy() for those rows. + if ($entity = $this->getEntity($values)) { + $entity = $this->createEntityForGroupBy($entity, $values); + // Some bundles might not have a specific field, in which case the faked + // entity doesn't have it either. + $build_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']}->view($display) : NULL; + } + else { + $build_list = NULL; + } + } + + if (!$build_list) { + return []; + } + + if ($this->options['field_api_classes']) { + return [['rendered' => $this->renderer->render($build_list)]]; + } + + // Render using the formatted data itself. + $items = []; + // Each item is extracted and rendered separately, the top-level formatter + // render array itself is never rendered, so we extract its bubbleable + // metadata and add it to each child individually. + $bubbleable = BubbleableMetadata::createFromRenderArray($build_list); + foreach (Element::children($build_list) as $delta) { + BubbleableMetadata::createFromRenderArray($build_list[$delta]) + ->merge($bubbleable) + ->applyTo($build_list[$delta]); + $items[$delta] = [ + 'rendered' => $build_list[$delta], + // Add the raw field items (for use in tokens). + 'raw' => $build_list['#items'][$delta], + ]; + } + return $items; + } + + /** + * Creates a fake entity with grouped field values. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to be processed. + * @param \Drupal\views\ResultRow $row + * The result row object containing the values. + * + * @return bool|\Drupal\Core\Entity\FieldableEntityInterface + * Returns a new entity object containing the grouped field values. + */ + protected function createEntityForGroupBy(EntityInterface $entity, ResultRow $row) { + // Retrieve the correct translation object. + $processed_entity = clone $this->getEntityFieldRenderer()->getEntityTranslation($entity, $row); + + // Copy our group fields into the cloned entity. It is possible this will + // cause some weirdness, but there is only so much we can hope to do. + if (!empty($this->group_fields) && isset($entity->{$this->definition['field_name']})) { + // first, test to see if we have a base value. + $base_value = []; + // Note: We would copy original values here, but it can cause problems. + // For example, text fields store cached filtered values as 'safe_value' + // which does not appear anywhere in the field definition so we cannot + // affect it. Other side effects could happen similarly. + $data = FALSE; + foreach ($this->group_fields as $field_name => $column) { + if (property_exists($row, $this->aliases[$column])) { + $base_value[$field_name] = $row->{$this->aliases[$column]}; + if (isset($base_value[$field_name])) { + $data = TRUE; + } + } + } + + // If any of our aggregated fields have data, fake it: + if ($data) { + // Now, overwrite the original value with our aggregated value. + // This overwrites it so there is always just one entry. + $processed_entity->{$this->definition['field_name']} = [$base_value]; + } + else { + $processed_entity->{$this->definition['field_name']} = []; + } + } + + return $processed_entity; + } + + public function render_item($count, $item) { + return render($item['rendered']); + } + + protected function documentSelfTokens(&$tokens) { + $field = $this->getFieldDefinition(); + foreach ($field->getColumns() as $id => $column) { + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = $this->t('Raw @column', ['@column' => $id]); + } + } + + protected function addSelfTokens(&$tokens, $item) { + $field = $this->getFieldDefinition(); + foreach ($field->getColumns() as $id => $column) { + // Use \Drupal\Component\Utility\Xss::filterAdmin() because it's user data + // and we can't be sure it is safe. We know nothing about the data, + // though, so we can't really do much else. + if (isset($item['raw'])) { + $raw = $item['raw']; + + if (is_array($raw)) { + if (isset($raw[$id]) && is_scalar($raw[$id])) { + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($raw[$id]); + } + else { + // Make sure that empty values are replaced as well. + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = ''; + } + } + + if (is_object($raw)) { + $property = $raw->get($id); + // Check if TypedDataInterface is implemented so we know how to render + // the item as a string. + if (!empty($property) && $property instanceof TypedDataInterface) { + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getString()); + } + else { + // Make sure that empty values are replaced as well. + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = ''; + } + } + } + } + } + + /** + * Returns the field formatter instance. + * + * @return \Drupal\Core\Field\FormatterInterface|null + * The field formatter instance. + */ + protected function getFormatterInstance($format = NULL) { + if (!isset($format)) { + $format = $this->options['type']; + } + $settings = $this->options['settings'] + $this->formatterPluginManager->getDefaultSettings($format); + + $options = [ + 'field_definition' => $this->getFieldDefinition(), + 'configuration' => [ + 'type' => $format, + 'settings' => $settings, + 'label' => '', + 'weight' => 0, + ], + 'view_mode' => '_custom', + ]; + + return $this->formatterPluginManager->getInstance($options); + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $this->dependencies = parent::calculateDependencies(); + + // Add the module providing the configured field storage as a dependency. + if (($field_storage_definition = $this->getFieldStorageDefinition()) && $field_storage_definition instanceof EntityInterface) { + $this->dependencies['config'][] = $field_storage_definition->getConfigDependencyName(); + } + if (!empty($this->options['type'])) { + // Add the module providing the formatter. + $this->dependencies['module'][] = $this->formatterPluginManager->getDefinition($this->options['type'])['provider']; + + // Add the formatter's dependencies. + if (($formatter = $this->getFormatterInstance()) && $formatter instanceof DependentPluginInterface) { + $this->calculatePluginDependencies($formatter); + } + } + + return $this->dependencies; + } + + /** + * {@inheritdoc} + */ + public function getCacheMaxAge() { + return Cache::PERMANENT; + } + + /** + * {@inheritdoc} + */ + public function getCacheContexts() { + return $this->getEntityFieldRenderer()->getCacheContexts(); + } + + /** + * {@inheritdoc} + */ + public function getCacheTags() { + $field_definition = $this->getFieldDefinition(); + $field_storage_definition = $this->getFieldStorageDefinition(); + return Cache::mergeTags( + $field_definition instanceof CacheableDependencyInterface ? $field_definition->getCacheTags() : [], + $field_storage_definition instanceof CacheableDependencyInterface ? $field_storage_definition->getCacheTags() : [] + ); + } + + /** + * Gets the table mapping for the entity type of the field. + * + * @return \Drupal\Core\Entity\Sql\DefaultTableMapping + * The table mapping. + */ + protected function getTableMapping() { + return $this->entityManager->getStorage($this->definition['entity_type'])->getTableMapping(); + } + + /** + * {@inheritdoc} + */ + public function getValue(ResultRow $values, $field = NULL) { + $entity = $this->getEntity($values); + // Retrieve the translated object. + $translated_entity = $this->getEntityFieldRenderer()->getEntityTranslation($entity, $values); + + // Some bundles might not have a specific field, in which case the entity + // (potentially a fake one) doesn't have it either. + /** @var \Drupal\Core\Field\FieldItemListInterface $field_item_list */ + $field_item_list = isset($translated_entity->{$this->definition['field_name']}) ? $translated_entity->{$this->definition['field_name']} : NULL; + + if (!isset($field_item_list)) { + // There isn't anything we can do without a valid field. + return NULL; + } + + $field_item_definition = $field_item_list->getFieldDefinition(); + + $values = []; + foreach ($field_item_list as $field_item) { + /** @var \Drupal\Core\Field\FieldItemInterface $field_item */ + if ($field) { + $values[] = $field_item->$field; + } + // Find the value using the main property of the field. If no main + // property is provided fall back to 'value'. + elseif ($main_property_name = $field_item->mainPropertyName()) { + $values[] = $field_item->{$main_property_name}; + } + else { + $values[] = $field_item->value; + } + } + if ($field_item_definition->getFieldStorageDefinition()->getCardinality() == 1) { + return reset($values); + } + else { + return $values; + } + } + + /** + * {@inheritdoc} + */ + public function onDependencyRemoval(array $dependencies) { + // See if this handler is responsible for any of the dependencies being + // removed. If this is the case, indicate that this handler needs to be + // removed from the View. + $remove = FALSE; + // Get all the current dependencies for this handler. + $current_dependencies = $this->calculateDependencies(); + foreach ($current_dependencies as $group => $dependency_list) { + // Check if any of the handler dependencies match the dependencies being + // removed. + foreach ($dependency_list as $config_key) { + if (isset($dependencies[$group]) && array_key_exists($config_key, $dependencies[$group])) { + // This handlers dependency matches a dependency being removed, + // indicate that this handler needs to be removed. + $remove = TRUE; + break 2; + } + } + } + return $remove; + } + +} diff --git a/core/modules/views/src/Plugin/views/field/EntityLabel.php b/core/modules/views/src/Plugin/views/field/EntityLabel.php index 967fd526..86ccd054 100644 --- a/core/modules/views/src/Plugin/views/field/EntityLabel.php +++ b/core/modules/views/src/Plugin/views/field/EntityLabel.php @@ -23,7 +23,7 @@ class EntityLabel extends FieldPluginBase { * * @var array */ - protected $loadedReferencers = array(); + protected $loadedReferencers = []; /** * EntityManager class. @@ -75,7 +75,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o */ protected function defineOptions() { $options = parent::defineOptions(); - $options['link_to_entity'] = array('default' => FALSE); + $options['link_to_entity'] = ['default' => FALSE]; return $options; } @@ -83,12 +83,12 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['link_to_entity'] = array( + $form['link_to_entity'] = [ '#title' => $this->t('Link to entity'), '#description' => $this->t('Make entity label a link to entity page.'), '#type' => 'checkbox', '#default_value' => !empty($this->options['link_to_entity']), - ); + ]; parent::buildOptionsForm($form, $form_state); } @@ -128,7 +128,7 @@ public function render(ResultRow $values) { public function preRender(&$values) { parent::preRender($values); - $entity_ids_per_type = array(); + $entity_ids_per_type = []; foreach ($values as $value) { if ($type = $this->getValue($value, 'type')) { $entity_ids_per_type[$type][] = $this->getValue($value); diff --git a/core/modules/views/src/Plugin/views/field/EntityOperations.php b/core/modules/views/src/Plugin/views/field/EntityOperations.php index f2a3ba99..33f37fe7 100644 --- a/core/modules/views/src/Plugin/views/field/EntityOperations.php +++ b/core/modules/views/src/Plugin/views/field/EntityOperations.php @@ -46,7 +46,7 @@ class EntityOperations extends FieldPluginBase { * @param array $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager. + * The entity manager. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * The language manager. */ @@ -83,9 +83,9 @@ public function usesGroupBy() { public function defineOptions() { $options = parent::defineOptions(); - $options['destination'] = array( + $options['destination'] = [ 'default' => TRUE, - ); + ]; return $options; } @@ -96,12 +96,12 @@ public function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['destination'] = array( + $form['destination'] = [ '#type' => 'checkbox', '#title' => $this->t('Include destination'), '#description' => $this->t('Include a destination parameter in the link to return the user to the original view upon completing the link action.'), '#default_value' => $this->options['destination'], - ); + ]; } /** @@ -113,15 +113,15 @@ public function render(ResultRow $values) { if ($this->options['destination']) { foreach ($operations as &$operation) { if (!isset($operation['query'])) { - $operation['query'] = array(); + $operation['query'] = []; } $operation['query'] += $this->getDestinationArray(); } } - $build = array( + $build = [ '#type' => 'operations', '#links' => $operations, - ); + ]; return $build; } diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php index c4003b4e..625d3c8a 100644 --- a/core/modules/views/src/Plugin/views/field/Field.php +++ b/core/modules/views/src/Plugin/views/field/Field.php @@ -2,1074 +2,12 @@ namespace Drupal\views\Plugin\views\field; -use Drupal\Component\Plugin\DependentPluginInterface; -use Drupal\Component\Utility\Xss; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Cache\CacheableDependencyInterface; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Field\FieldStorageDefinitionInterface; -use Drupal\Core\Field\FieldTypePluginManagerInterface; -use Drupal\Core\Field\FormatterPluginManager; -use Drupal\Core\Form\FormHelper; -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Language\LanguageManagerInterface; -use Drupal\Core\Plugin\PluginDependencyTrait; -use Drupal\Core\Render\BubbleableMetadata; -use Drupal\Core\Render\Element; -use Drupal\Core\Render\RendererInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\Core\TypedData\TypedDataInterface; -use Drupal\views\FieldAPIHandlerTrait; -use Drupal\views\Entity\Render\EntityFieldRenderer; -use Drupal\views\Plugin\views\display\DisplayPluginBase; -use Drupal\views\ResultRow; -use Drupal\views\ViewExecutable; -use Symfony\Component\DependencyInjection\ContainerInterface; - /** - * A field that displays entity field data. - * - * @ingroup views_field_handlers + * A stub class to provide backward compatibility for EntityField. * - * @todo Rename the class https://www.drupal.org/node/2408667 - * - * @ViewsField("field") + * @deprecated in Drupal 8.3.x and will be removed before 9.0.0 + * Use \Drupal\views\Plugin\views\field\EntityField instead. */ -class Field extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface { - - use FieldAPIHandlerTrait; - use PluginDependencyTrait; - - /** - * An array to store field renderable arrays for use by renderItems(). - * - * @var array - */ - public $items = array(); - - /** - * Does the field supports multiple field values. - * - * @var bool - */ - public $multiple; - - /** - * Does the rendered fields get limited. - * - * @var bool - */ - public $limit_values; - - /** - * A shortcut for $view->base_table. - * - * @var string - */ - public $base_table; - - /** - * An array of formatter options. - * - * @var array - */ - protected $formatterOptions; - - /** - * The entity manager. - * - * @var \Drupal\Core\Entity\EntityManagerInterface - */ - protected $entityManager; - - /** - * The field formatter plugin manager. - * - * @var \Drupal\Core\Field\FormatterPluginManager - */ - protected $formatterPluginManager; - - /** - * The language manager. - * - * @var \Drupal\Core\Language\LanguageManagerInterface - */ - protected $languageManager; - - /** - * The renderer. - * - * @var \Drupal\Core\Render\RendererInterface - */ - protected $renderer; - - /** - * The field type plugin manager. - * - * @var \Drupal\Core\Field\FieldTypePluginManagerInterface - */ - protected $fieldTypePluginManager; - - /** - * Static cache for ::getEntityFieldRenderer(). - * - * @var \Drupal\views\Entity\Render\EntityFieldRenderer - */ - protected $entityFieldRenderer; - - /** - * Constructs a \Drupal\field\Plugin\views\field\Field object. - * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin_id for the plugin instance. - * @param mixed $plugin_definition - * The plugin implementation definition. - * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The field formatter plugin manager. - * @param \Drupal\Core\Field\FormatterPluginManager $formatter_plugin_manager - * The field formatter plugin manager. - * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager - * The field plugin type manager. - * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager - * The language manager. - * @param \Drupal\Core\Render\RendererInterface $renderer - * The renderer. - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, FormatterPluginManager $formatter_plugin_manager, FieldTypePluginManagerInterface $field_type_plugin_manager, LanguageManagerInterface $language_manager, RendererInterface $renderer) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->entityManager = $entity_manager; - $this->formatterPluginManager = $formatter_plugin_manager; - $this->fieldTypePluginManager = $field_type_plugin_manager; - $this->languageManager = $language_manager; - $this->renderer = $renderer; - - // @todo Unify 'entity field'/'field_name' instead of converting back and - // forth. https://www.drupal.org/node/2410779 - if (isset($this->definition['entity field'])) { - $this->definition['field_name'] = $this->definition['entity field']; - } - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('entity.manager'), - $container->get('plugin.manager.field.formatter'), - $container->get('plugin.manager.field.field_type'), - $container->get('language_manager'), - $container->get('renderer') - ); - } - - /** - * {@inheritdoc} - */ - public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { - parent::init($view, $display, $options); - - $this->multiple = FALSE; - $this->limit_values = FALSE; - - $field_definition = $this->getFieldDefinition(); - $cardinality = $field_definition->getFieldStorageDefinition()->getCardinality(); - if ($field_definition->getFieldStorageDefinition()->isMultiple()) { - $this->multiple = TRUE; - - // If "Display all values in the same row" is FALSE, then we always limit - // in order to show a single unique value per row. - if (!$this->options['group_rows']) { - $this->limit_values = TRUE; - } - - // If "First and last only" is chosen, limit the values - if (!empty($this->options['delta_first_last'])) { - $this->limit_values = TRUE; - } - - // Otherwise, we only limit values if the user hasn't selected "all", 0, or - // the value matching field cardinality. - if ((($this->options['delta_limit'] > 0) && ($this->options['delta_limit'] != $cardinality)) || intval($this->options['delta_offset'])) { - $this->limit_values = TRUE; - } - } - } - - /** - * {@inheritdoc} - */ - protected function getEntityManager() { - return $this->entityManager; - } - - /** - * {@inheritdoc} - */ - public function access(AccountInterface $account) { - $access_control_handler = $this->entityManager->getAccessControlHandler($this->getEntityType()); - return $access_control_handler->fieldAccess('view', $this->getFieldDefinition(), $account); - } - - /** - * Called to add the field to a query. - * - * By default, all needed data is taken from entities loaded by the query - * plugin. Columns are added only if they are used in groupings. - */ - public function query($use_groupby = FALSE) { - $fields = $this->additional_fields; - // No need to add the entity type. - $entity_type_key = array_search('entity_type', $fields); - if ($entity_type_key !== FALSE) { - unset($fields[$entity_type_key]); - } - - if ($use_groupby) { - // Add the fields that we're actually grouping on. - $options = array(); - if ($this->options['group_column'] != 'entity_id') { - $options = array($this->options['group_column'] => $this->options['group_column']); - } - $options += is_array($this->options['group_columns']) ? $this->options['group_columns'] : array(); - - // Go through the list and determine the actual column name from field api. - $fields = array(); - $table_mapping = $this->getTableMapping(); - $field_definition = $this->getFieldStorageDefinition(); - - foreach ($options as $column) { - $fields[$column] = $table_mapping->getFieldColumnName($field_definition, $column); - } - - $this->group_fields = $fields; - } - - // Add additional fields (and the table join itself) if needed. - if ($this->add_field_table($use_groupby)) { - $this->ensureMyTable(); - $this->addAdditionalFields($fields); - } - - // Let the entity field renderer alter the query if needed. - $this->getEntityFieldRenderer()->query($this->query, $this->relationship); - } - - /** - * Determine if the field table should be added to the query. - */ - function add_field_table($use_groupby) { - // Grouping is enabled. - if ($use_groupby) { - return TRUE; - } - // This a multiple value field, but "group multiple values" is not checked. - if ($this->multiple && !$this->options['group_rows']) { - return TRUE; - } - return FALSE; - } - - /** - * {@inheritdoc} - */ - public function clickSortable() { - // A field is not click sortable if it's a multiple field with - // "group multiple values" checked, since a click sort in that case would - // add a join to the field table, which would produce unwanted duplicates. - if ($this->multiple && $this->options['group_rows']) { - return FALSE; - } - - // If field definition is set, use that. - if (isset($this->definition['click sortable'])) { - return (bool) $this->definition['click sortable']; - } - - // Default to true. - return TRUE; - } - - /** - * Called to determine what to tell the clicksorter. - */ - public function clickSort($order) { - // No column selected, can't continue. - if (empty($this->options['click_sort_column'])) { - return; - } - - $this->ensureMyTable(); - $field_storage_definition = $this->getFieldStorageDefinition(); - $column = $this->getTableMapping()->getFieldColumnName($field_storage_definition, $this->options['click_sort_column']); - if (!isset($this->aliases[$column])) { - // Column is not in query; add a sort on it (without adding the column). - $this->aliases[$column] = $this->tableAlias . '.' . $column; - } - $this->query->addOrderBy(NULL, NULL, $order, $this->aliases[$column]); - } - - /** - * Gets the field storage of the used field. - * - * @return \Drupal\Core\Field\FieldStorageDefinitionInterface - */ - protected function getFieldStorageDefinition() { - $entity_type_id = $this->definition['entity_type']; - $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); - - $field_storage = NULL; - // @todo Unify 'entity field'/'field_name' instead of converting back and - // forth. https://www.drupal.org/node/2410779 - if (isset($this->definition['field_name'])) { - $field_storage = $field_storage_definitions[$this->definition['field_name']]; - } - elseif (isset($this->definition['entity field'])) { - $field_storage = $field_storage_definitions[$this->definition['entity field']]; - } - return $field_storage; - } - - /** - * {@inheritdoc} - */ - protected function defineOptions() { - $options = parent::defineOptions(); - - $field_storage_definition = $this->getFieldStorageDefinition(); - $field_type = $this->fieldTypePluginManager->getDefinition($field_storage_definition->getType()); - $column_names = array_keys($field_storage_definition->getColumns()); - $default_column = ''; - // Try to determine a sensible default. - if (count($column_names) == 1) { - $default_column = $column_names[0]; - } - elseif (in_array('value', $column_names)) { - $default_column = 'value'; - } - - // If the field has a "value" column, we probably need that one. - $options['click_sort_column'] = array( - 'default' => $default_column, - ); - - if (isset($this->definition['default_formatter'])) { - $options['type'] = ['default' => $this->definition['default_formatter']]; - } - elseif (isset($field_type['default_formatter'])) { - $options['type'] = ['default' => $field_type['default_formatter']]; - } - else { - $options['type'] = ['default' => '']; - } - - $options['settings'] = array( - 'default' => isset($this->definition['default_formatter_settings']) ? $this->definition['default_formatter_settings'] : [], - ); - $options['group_column'] = array( - 'default' => $default_column, - ); - $options['group_columns'] = array( - 'default' => array(), - ); - - // Options used for multiple value fields. - $options['group_rows'] = array( - 'default' => TRUE, - ); - // If we know the exact number of allowed values, then that can be - // the default. Otherwise, default to 'all'. - $options['delta_limit'] = array( - 'default' => ($field_storage_definition->getCardinality() > 1) ? $field_storage_definition->getCardinality() : 0, - ); - $options['delta_offset'] = array( - 'default' => 0, - ); - $options['delta_reversed'] = array( - 'default' => FALSE, - ); - $options['delta_first_last'] = array( - 'default' => FALSE, - ); - - $options['multi_type'] = array( - 'default' => 'separator' - ); - $options['separator'] = array( - 'default' => ', ' - ); - - $options['field_api_classes'] = array( - 'default' => FALSE, - ); - - return $options; - } - - /** - * {@inheritdoc} - */ - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - parent::buildOptionsForm($form, $form_state); - - $field = $this->getFieldDefinition(); - $formatters = $this->formatterPluginManager->getOptions($field->getType()); - $column_names = array_keys($field->getColumns()); - - // If this is a multiple value field, add its options. - if ($this->multiple) { - $this->multiple_options_form($form, $form_state); - } - - // No need to ask the user anything if the field has only one column. - if (count($field->getColumns()) == 1) { - $form['click_sort_column'] = array( - '#type' => 'value', - '#value' => isset($column_names[0]) ? $column_names[0] : '', - ); - } - else { - $form['click_sort_column'] = array( - '#type' => 'select', - '#title' => $this->t('Column used for click sorting'), - '#options' => array_combine($column_names, $column_names), - '#default_value' => $this->options['click_sort_column'], - '#description' => $this->t('Used by Style: Table to determine the actual column to click sort the field on. The default is usually fine.'), - ); - } - - $form['type'] = array( - '#type' => 'select', - '#title' => $this->t('Formatter'), - '#options' => $formatters, - '#default_value' => $this->options['type'], - '#ajax' => array( - 'url' => views_ui_build_form_url($form_state), - ), - '#submit' => array(array($this, 'submitTemporaryForm')), - '#executes_submit_callback' => TRUE, - ); - - $form['field_api_classes'] = array( - '#title' => $this->t('Use field template'), - '#type' => 'checkbox', - '#default_value' => $this->options['field_api_classes'], - '#description' => $this->t('If checked, field api classes will be added by field templates. This is not recommended unless your CSS depends upon these classes. If not checked, template will not be used.'), - '#fieldset' => 'style_settings', - '#weight' => 20, - ); - - if ($this->multiple) { - $form['field_api_classes']['#description'] .= ' ' . $this->t('Checking this option will cause the group Display Type and Separator values to be ignored.'); - } - - // Get the settings form. - $settings_form = array('#value' => array()); - $format = isset($form_state->getUserInput()['options']['type']) ? $form_state->getUserInput()['options']['type'] : $this->options['type']; - if ($formatter = $this->getFormatterInstance($format)) { - $settings_form = $formatter->settingsForm($form, $form_state); - // Convert field UI selector states to work in the Views field form. - FormHelper::rewriteStatesSelector($settings_form, "fields[{$field->getName()}][settings_edit_form]", 'options'); - } - $form['settings'] = $settings_form; - } - - /** - * {@inheritdoc} - */ - public function submitFormCalculateOptions(array $options, array $form_state_options) { - // When we change the formatter type we don't want to keep any of the - // previous configured formatter settings, as there might be schema - // conflict. - unset($options['settings']); - $options = $form_state_options + $options; - if (!isset($options['settings'])) { - $options['settings'] = []; - } - return $options; - } - - /** - * Provide options for multiple value fields. - */ - function multiple_options_form(&$form, FormStateInterface $form_state) { - $field = $this->getFieldDefinition(); - - $form['multiple_field_settings'] = array( - '#type' => 'details', - '#title' => $this->t('Multiple field settings'), - '#weight' => 5, - ); - - $form['group_rows'] = array( - '#title' => $this->t('Display all values in the same row'), - '#type' => 'checkbox', - '#default_value' => $this->options['group_rows'], - '#description' => $this->t('If checked, multiple values for this field will be shown in the same row. If not checked, each value in this field will create a new row. If using group by, please make sure to group by "Entity ID" for this setting to have any effect.'), - '#fieldset' => 'multiple_field_settings', - ); - - // Make the string translatable by keeping it as a whole rather than - // translating prefix and suffix separately. - list($prefix, $suffix) = explode('@count', $this->t('Display @count value(s)')); - - if ($field->getCardinality() == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) { - $type = 'textfield'; - $options = NULL; - $size = 5; - } - else { - $type = 'select'; - $range = range(1, $field->getCardinality()); - $options = array_combine($range, $range); - $size = 1; - } - $form['multi_type'] = array( - '#type' => 'radios', - '#title' => $this->t('Display type'), - '#options' => array( - 'ul' => $this->t('Unordered list'), - 'ol' => $this->t('Ordered list'), - 'separator' => $this->t('Simple separator'), - ), - '#states' => array( - 'visible' => array( - ':input[name="options[group_rows]"]' => array('checked' => TRUE), - ), - ), - '#default_value' => $this->options['multi_type'], - '#fieldset' => 'multiple_field_settings', - ); - - $form['separator'] = array( - '#type' => 'textfield', - '#title' => $this->t('Separator'), - '#default_value' => $this->options['separator'], - '#states' => array( - 'visible' => array( - ':input[name="options[group_rows]"]' => array('checked' => TRUE), - ':input[name="options[multi_type]"]' => array('value' => 'separator'), - ), - ), - '#fieldset' => 'multiple_field_settings', - ); - - $form['delta_limit'] = array( - '#type' => $type, - '#size' => $size, - '#field_prefix' => $prefix, - '#field_suffix' => $suffix, - '#options' => $options, - '#default_value' => $this->options['delta_limit'], - '#prefix' => '
          ', - '#states' => array( - 'visible' => array( - ':input[name="options[group_rows]"]' => array('checked' => TRUE), - ), - ), - '#fieldset' => 'multiple_field_settings', - ); - - list($prefix, $suffix) = explode('@count', $this->t('starting from @count')); - $form['delta_offset'] = array( - '#type' => 'textfield', - '#size' => 5, - '#field_prefix' => $prefix, - '#field_suffix' => $suffix, - '#default_value' => $this->options['delta_offset'], - '#states' => array( - 'visible' => array( - ':input[name="options[group_rows]"]' => array('checked' => TRUE), - ), - ), - '#description' => $this->t('(first item is 0)'), - '#fieldset' => 'multiple_field_settings', - ); - $form['delta_reversed'] = array( - '#title' => $this->t('Reversed'), - '#type' => 'checkbox', - '#default_value' => $this->options['delta_reversed'], - '#suffix' => $suffix, - '#states' => array( - 'visible' => array( - ':input[name="options[group_rows]"]' => array('checked' => TRUE), - ), - ), - '#description' => $this->t('(start from last values)'), - '#fieldset' => 'multiple_field_settings', - ); - $form['delta_first_last'] = array( - '#title' => $this->t('First and last only'), - '#type' => 'checkbox', - '#default_value' => $this->options['delta_first_last'], - '#suffix' => '
          ', - '#states' => array( - 'visible' => array( - ':input[name="options[group_rows]"]' => array('checked' => TRUE), - ), - ), - '#fieldset' => 'multiple_field_settings', - ); - } - - /** - * Extend the groupby form with group columns. - */ - public function buildGroupByForm(&$form, FormStateInterface $form_state) { - parent::buildGroupByForm($form, $form_state); - // With "field API" fields, the column target of the grouping function - // and any additional grouping columns must be specified. - - $field_columns = array_keys($this->getFieldDefinition()->getColumns()); - $group_columns = array( - 'entity_id' => $this->t('Entity ID'), - ) + array_map('ucfirst', array_combine($field_columns, $field_columns)); - - $form['group_column'] = array( - '#type' => 'select', - '#title' => $this->t('Group column'), - '#default_value' => $this->options['group_column'], - '#description' => $this->t('Select the column of this field to apply the grouping function selected above.'), - '#options' => $group_columns, - ); - - $options = array( - 'bundle' => 'Bundle', - 'language' => 'Language', - 'entity_type' => 'Entity_type', - ); - // Add on defined fields, noting that they're prefixed with the field name. - $form['group_columns'] = array( - '#type' => 'checkboxes', - '#title' => $this->t('Group columns (additional)'), - '#default_value' => $this->options['group_columns'], - '#description' => $this->t('Select any additional columns of this field to include in the query and to group on.'), - '#options' => $options + $group_columns, - ); - } - - public function submitGroupByForm(&$form, FormStateInterface $form_state) { - parent::submitGroupByForm($form, $form_state); - $item = &$form_state->get('handler')->options; - - // Add settings for "field API" fields. - $item['group_column'] = $form_state->getValue(array('options', 'group_column')); - $item['group_columns'] = array_filter($form_state->getValue(array('options', 'group_columns'))); - } - - /** - * Render all items in this field together. - * - * When using advanced render, each possible item in the list is rendered - * individually. Then the items are all pasted together. - */ - public function renderItems($items) { - if (!empty($items)) { - $items = $this->prepareItemsByDelta($items); - if ($this->options['multi_type'] == 'separator' || !$this->options['group_rows']) { - $separator = $this->options['multi_type'] == 'separator' ? Xss::filterAdmin($this->options['separator']) : ''; - $build = [ - '#type' => 'inline_template', - '#template' => '{{ items | safe_join(separator) }}', - '#context' => ['separator' => $separator, 'items' => $items], - ]; - } - else { - $build = array( - '#theme' => 'item_list', - '#items' => $items, - '#title' => NULL, - '#list_type' => $this->options['multi_type'], - ); - } - return $this->renderer->render($build); - } - } - - /** - * Adapts the $items according to the delta configuration. - * - * This selects displayed deltas, reorders items, and takes offsets into - * account. - * - * @param array $all_values - * The items for individual rendering. - * - * @return array - * The manipulated items. - */ - protected function prepareItemsByDelta(array $all_values) { - if ($this->options['delta_reversed']) { - $all_values = array_reverse($all_values); - } - - // We are supposed to show only certain deltas. - if ($this->limit_values) { - $row = $this->view->result[$this->view->row_index]; - - // Offset is calculated differently when row grouping for a field is not - // enabled. Since there are multiple rows, delta needs to be taken into - // account, so that different values are shown per row. - if (!$this->options['group_rows'] && isset($this->aliases['delta']) && isset($row->{$this->aliases['delta']})) { - $delta_limit = 1; - $offset = $row->{$this->aliases['delta']}; - } - // Single fields don't have a delta available so choose 0. - elseif (!$this->options['group_rows'] && !$this->multiple) { - $delta_limit = 1; - $offset = 0; - } - else { - $delta_limit = $this->options['delta_limit']; - $offset = intval($this->options['delta_offset']); - - // We should only get here in this case if there is an offset, and in - // that case we are limiting to all values after the offset. - if ($delta_limit === 0) { - $delta_limit = count($all_values) - $offset; - } - } - - // Determine if only the first and last values should be shown. - $delta_first_last = $this->options['delta_first_last']; - - $new_values = array(); - for ($i = 0; $i < $delta_limit; $i++) { - $new_delta = $offset + $i; - - if (isset($all_values[$new_delta])) { - // If first-last option was selected, only use the first and last - // values. - if (!$delta_first_last - // Use the first value. - || $new_delta == $offset - // Use the last value. - || $new_delta == ($delta_limit + $offset - 1)) { - $new_values[] = $all_values[$new_delta]; - } - } - } - $all_values = $new_values; - } - - return $all_values; - } - - /** - * {@inheritdoc} - */ - public function preRender(&$values) { - parent::preRender($values); - $this->getEntityFieldRenderer()->preRender($values); - } - - /** - * Returns the entity field renderer. - * - * @return \Drupal\views\Entity\Render\EntityFieldRenderer - * The entity field renderer. - */ - protected function getEntityFieldRenderer() { - if (!isset($this->entityFieldRenderer)) { - // This can be invoked during field handler initialization in which case - // view fields are not set yet. - if (!empty($this->view->field)) { - foreach ($this->view->field as $field) { - // An entity field renderer can handle only a single relationship. - if ($field->relationship == $this->relationship && isset($field->entityFieldRenderer)) { - $this->entityFieldRenderer = $field->entityFieldRenderer; - break; - } - } - } - if (!isset($this->entityFieldRenderer)) { - $entity_type = $this->entityManager->getDefinition($this->getEntityType()); - $this->entityFieldRenderer = new EntityFieldRenderer($this->view, $this->relationship, $this->languageManager, $entity_type, $this->entityManager); - } - } - return $this->entityFieldRenderer; - } - - /** - * Gets an array of items for the field. - * - * @param \Drupal\views\ResultRow $values - * The result row object containing the values. - * - * @return array - * An array of items for the field. - */ - public function getItems(ResultRow $values) { - if (!$this->displayHandler->useGroupBy()) { - $build_list = $this->getEntityFieldRenderer()->render($values, $this); - } - else { - // For grouped results we need to retrieve a massaged entity having - // grouped field values to ensure that "grouped by" values, especially - // those with multiple cardinality work properly. See - // \Drupal\Tests\views\Kernel\QueryGroupByTest::testGroupByFieldWithCardinality. - $display = [ - 'type' => $this->options['type'], - 'settings' => $this->options['settings'], - 'label' => 'hidden', - ]; - // Some bundles might not have a specific field, in which case the faked - // entity doesn't have it either. - $entity = $this->createEntityForGroupBy($this->getEntity($values), $values); - $build_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']}->view($display) : NULL; - } - - if (!$build_list) { - return []; - } - - if ($this->options['field_api_classes']) { - return [['rendered' => $this->renderer->render($build_list)]]; - } - - // Render using the formatted data itself. - $items = []; - // Each item is extracted and rendered separately, the top-level formatter - // render array itself is never rendered, so we extract its bubbleable - // metadata and add it to each child individually. - $bubbleable = BubbleableMetadata::createFromRenderArray($build_list); - foreach (Element::children($build_list) as $delta) { - BubbleableMetadata::createFromRenderArray($build_list[$delta]) - ->merge($bubbleable) - ->applyTo($build_list[$delta]); - $items[$delta] = [ - 'rendered' => $build_list[$delta], - // Add the raw field items (for use in tokens). - 'raw' => $build_list['#items'][$delta], - ]; - } - return $items; - } - - /** - * Creates a fake entity with grouped field values. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity to be processed. - * @param \Drupal\views\ResultRow $row - * The result row object containing the values. - * - * @return bool|\Drupal\Core\Entity\FieldableEntityInterface - * Returns a new entity object containing the grouped field values. - */ - protected function createEntityForGroupBy(EntityInterface $entity, ResultRow $row) { - // Retrieve the correct translation object. - $processed_entity = clone $this->getEntityFieldRenderer()->getEntityTranslation($entity, $row); - - // Copy our group fields into the cloned entity. It is possible this will - // cause some weirdness, but there is only so much we can hope to do. - if (!empty($this->group_fields) && isset($entity->{$this->definition['field_name']})) { - // first, test to see if we have a base value. - $base_value = array(); - // Note: We would copy original values here, but it can cause problems. - // For example, text fields store cached filtered values as 'safe_value' - // which does not appear anywhere in the field definition so we cannot - // affect it. Other side effects could happen similarly. - $data = FALSE; - foreach ($this->group_fields as $field_name => $column) { - if (property_exists($row, $this->aliases[$column])) { - $base_value[$field_name] = $row->{$this->aliases[$column]}; - if (isset($base_value[$field_name])) { - $data = TRUE; - } - } - } - - // If any of our aggregated fields have data, fake it: - if ($data) { - // Now, overwrite the original value with our aggregated value. - // This overwrites it so there is always just one entry. - $processed_entity->{$this->definition['field_name']} = array($base_value); - } - else { - $processed_entity->{$this->definition['field_name']} = array(); - } - } - - return $processed_entity; - } - - function render_item($count, $item) { - return render($item['rendered']); - } - - protected function documentSelfTokens(&$tokens) { - $field = $this->getFieldDefinition(); - foreach ($field->getColumns() as $id => $column) { - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = $this->t('Raw @column', array('@column' => $id)); - } - } - - protected function addSelfTokens(&$tokens, $item) { - $field = $this->getFieldDefinition(); - foreach ($field->getColumns() as $id => $column) { - // Use \Drupal\Component\Utility\Xss::filterAdmin() because it's user data - // and we can't be sure it is safe. We know nothing about the data, - // though, so we can't really do much else. - if (isset($item['raw'])) { - $raw = $item['raw']; - - if (is_array($raw)) { - if (isset($raw[$id]) && is_scalar($raw[$id])) { - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($raw[$id]); - } - else { - // Make sure that empty values are replaced as well. - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = ''; - } - } - - if (is_object($raw)) { - $property = $raw->get($id); - // Check if TypedDataInterface is implemented so we know how to render - // the item as a string. - if (!empty($property) && $property instanceof TypedDataInterface) { - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getString()); - } - else { - // Make sure that empty values are replaced as well. - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = ''; - } - } - } - } - } - - /** - * Returns the field formatter instance. - * - * @return \Drupal\Core\Field\FormatterInterface|null - * The field formatter instance. - */ - protected function getFormatterInstance($format = NULL) { - if (!isset($format)) { - $format = $this->options['type']; - } - $settings = $this->options['settings'] + $this->formatterPluginManager->getDefaultSettings($format); - - $options = [ - 'field_definition' => $this->getFieldDefinition(), - 'configuration' => [ - 'type' => $format, - 'settings' => $settings, - 'label' => '', - 'weight' => 0, - ], - 'view_mode' => '_custom', - ]; - - return $this->formatterPluginManager->getInstance($options); - } - - /** - * {@inheritdoc} - */ - public function calculateDependencies() { - $this->dependencies = parent::calculateDependencies(); - - // Add the module providing the configured field storage as a dependency. - if (($field_storage_definition = $this->getFieldStorageDefinition()) && $field_storage_definition instanceof EntityInterface) { - $this->dependencies['config'][] = $field_storage_definition->getConfigDependencyName(); - } - if (!empty($this->options['type'])) { - // Add the module providing the formatter. - $this->dependencies['module'][] = $this->formatterPluginManager->getDefinition($this->options['type'])['provider']; - - // Add the formatter's dependencies. - if (($formatter = $this->getFormatterInstance()) && $formatter instanceof DependentPluginInterface) { - $this->calculatePluginDependencies($formatter); - } - } - - return $this->dependencies; - } - - /** - * {@inheritdoc} - */ - public function getCacheMaxAge() { - return Cache::PERMANENT; - } - - /** - * {@inheritdoc} - */ - public function getCacheContexts() { - return $this->getEntityFieldRenderer()->getCacheContexts(); - } - - /** - * {@inheritdoc} - */ - public function getCacheTags() { - $field_definition = $this->getFieldDefinition(); - $field_storage_definition = $this->getFieldStorageDefinition(); - return Cache::mergeTags( - $field_definition instanceof CacheableDependencyInterface ? $field_definition->getCacheTags() : [], - $field_storage_definition instanceof CacheableDependencyInterface ? $field_storage_definition->getCacheTags() : [] - ); - } - - /** - * Gets the table mapping for the entity type of the field. - * - * @return \Drupal\Core\Entity\Sql\DefaultTableMapping - * The table mapping. - */ - protected function getTableMapping() { - return $this->entityManager->getStorage($this->definition['entity_type'])->getTableMapping(); - } - - /** - * {@inheritdoc} - */ - public function getValue(ResultRow $values, $field = NULL) { - $entity = $this->getEntity($values); - // Some bundles might not have a specific field, in which case the entity - // (potentially a fake one) doesn't have it either. - /** @var \Drupal\Core\Field\FieldItemListInterface $field_item_list */ - $field_item_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']} : NULL; - - if (!isset($field_item_list)) { - // There isn't anything we can do without a valid field. - return NULL; - } - - $field_item_definition = $field_item_list->getFieldDefinition(); - - $values = []; - foreach ($field_item_list as $field_item) { - /** @var \Drupal\Core\Field\FieldItemInterface $field_item */ - if ($field) { - $values[] = $field_item->$field; - } - // Find the value using the main property of the field. If no main - // property is provided fall back to 'value'. - elseif ($main_property_name = $field_item->mainPropertyName()) { - $values[] = $field_item->{$main_property_name}; - } - else { - $values[] = $field_item->value; - } - } - if ($field_item_definition->getFieldStorageDefinition()->getCardinality() == 1) { - return reset($values); - } - else { - return $values; - } - } +class Field extends EntityField { } diff --git a/core/modules/views/src/Plugin/views/field/FieldHandlerInterface.php b/core/modules/views/src/Plugin/views/field/FieldHandlerInterface.php index d7389c93..2562b954 100644 --- a/core/modules/views/src/Plugin/views/field/FieldHandlerInterface.php +++ b/core/modules/views/src/Plugin/views/field/FieldHandlerInterface.php @@ -265,6 +265,6 @@ public function getRenderTokens($item); * is safe it will be wrapped in an object that implements * MarkupInterface. If it is empty or unsafe it will be a string. */ - function theme(ResultRow $values); + public function theme(ResultRow $values); } diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php index bdb44faf..c5ce66bd 100644 --- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php +++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php @@ -69,7 +69,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf const RENDER_TEXT_PHASE_EMPTY = 2; public $field_alias = 'unknown'; - public $aliases = array(); + public $aliases = []; /** * The field value prior to any rewriting. @@ -85,7 +85,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf * * @var array */ - public $additional_fields = array(); + public $additional_fields = []; /** * The link generator. @@ -114,7 +114,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); - $this->additional_fields = array(); + $this->additional_fields = []; if (!empty($this->definition['additional fields'])) { $this->additional_fields = $this->definition['additional fields']; } @@ -140,7 +140,7 @@ protected function allowAdvancedRender() { public function query() { $this->ensureMyTable(); // Add the field. - $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array(); + $params = $this->options['group_type'] != 'group' ? ['function' => $this->options['group_type']] : []; $this->field_alias = $this->query->addField($this->tableAlias, $this->realField, NULL, $params); $this->addAdditionalFields(); @@ -165,11 +165,11 @@ protected function addAdditionalFields($fields = NULL) { $fields = $this->additional_fields; } - $group_params = array(); + $group_params = []; if ($this->options['group_type'] != 'group') { - $group_params = array( + $group_params = [ 'function' => $this->options['group_type'], - ); + ]; } if (!empty($fields) && is_array($fields)) { @@ -183,12 +183,12 @@ protected function addAdditionalFields($fields = NULL) { } if (empty($table_alias)) { - debug(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array('@handler' => $this->definition['id'], '@identifier' => $identifier, '@table' => $info['table']))); + debug(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', ['@handler' => $this->definition['id'], '@identifier' => $identifier, '@table' => $info['table']])); $this->aliases[$identifier] = 'broken'; continue; } - $params = array(); + $params = []; if (!empty($info['params'])) { $params = $info['params']; } @@ -210,7 +210,7 @@ public function clickSort($order) { if (isset($this->field_alias)) { // Since fields should always have themselves already added, just // add a sort on the field. - $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array(); + $params = $this->options['group_type'] != 'group' ? ['function' => $this->options['group_type']] : []; $this->query->addOrderBy(NULL, NULL, $order, $this->field_alias, $params); } } @@ -307,10 +307,10 @@ public function getElements() { static $elements = NULL; if (!isset($elements)) { // @todo Add possible html5 elements. - $elements = array( + $elements = [ '' => $this->t('- Use default -'), '0' => $this->t('- None -') - ); + ]; $elements += \Drupal::config('views.settings')->get('field_rewrite_elements'); } @@ -321,9 +321,9 @@ public function getElements() { * {@inheritdoc} */ public function elementClasses($row_index = NULL) { - $classes = explode(' ', $this->options['element_class']); + $classes = $this->tokenizeValue($this->options['element_class'], $row_index); + $classes = explode(' ', $classes); foreach ($classes as &$class) { - $class = $this->tokenizeValue($class, $row_index); $class = Html::cleanCssIdentifier($class); } return implode(' ', $classes); @@ -334,10 +334,10 @@ public function elementClasses($row_index = NULL) { */ public function tokenizeValue($value, $row_index = NULL) { if (strpos($value, '{{') !== FALSE) { - $fake_item = array( + $fake_item = [ 'alter_text' => TRUE, 'text' => $value, - ); + ]; // Use isset() because empty() will trigger on 0 and 0 is // the first row. @@ -368,9 +368,9 @@ public function tokenizeValue($value, $row_index = NULL) { * {@inheritdoc} */ public function elementLabelClasses($row_index = NULL) { - $classes = explode(' ', $this->options['element_label_class']); + $classes = $this->tokenizeValue($this->options['element_label_class'], $row_index); + $classes = explode(' ', $classes); foreach ($classes as &$class) { - $class = $this->tokenizeValue($class, $row_index); $class = Html::cleanCssIdentifier($class); } return implode(' ', $classes); @@ -380,9 +380,9 @@ public function elementLabelClasses($row_index = NULL) { * {@inheritdoc} */ public function elementWrapperClasses($row_index = NULL) { - $classes = explode(' ', $this->options['element_wrapper_class']); + $classes = $this->tokenizeValue($this->options['element_wrapper_class'], $row_index); + $classes = explode(' ', $classes); foreach ($classes as &$class) { - $class = $this->tokenizeValue($class, $row_index); $class = Html::cleanCssIdentifier($class); } return implode(' ', $classes); @@ -421,60 +421,60 @@ public function useStringGroupBy() { protected function defineOptions() { $options = parent::defineOptions(); - $options['label'] = array('default' => ''); + $options['label'] = ['default' => '']; // Some styles (for example table) should have labels enabled by default. $style = $this->view->getStyle(); if (isset($style) && $style->defaultFieldLabels()) { $options['label']['default'] = $this->definition['title']; } - $options['exclude'] = array('default' => FALSE); - $options['alter'] = array( - 'contains' => array( - 'alter_text' => array('default' => FALSE), - 'text' => array('default' => ''), - 'make_link' => array('default' => FALSE), - 'path' => array('default' => ''), - 'absolute' => array('default' => FALSE), - 'external' => array('default' => FALSE), - 'replace_spaces' => array('default' => FALSE), - 'path_case' => array('default' => 'none'), - 'trim_whitespace' => array('default' => FALSE), - 'alt' => array('default' => ''), - 'rel' => array('default' => ''), - 'link_class' => array('default' => ''), - 'prefix' => array('default' => ''), - 'suffix' => array('default' => ''), - 'target' => array('default' => ''), - 'nl2br' => array('default' => FALSE), - 'max_length' => array('default' => 0), - 'word_boundary' => array('default' => TRUE), - 'ellipsis' => array('default' => TRUE), - 'more_link' => array('default' => FALSE), - 'more_link_text' => array('default' => ''), - 'more_link_path' => array('default' => ''), - 'strip_tags' => array('default' => FALSE), - 'trim' => array('default' => FALSE), - 'preserve_tags' => array('default' => ''), - 'html' => array('default' => FALSE), - ), - ); - $options['element_type'] = array('default' => ''); - $options['element_class'] = array('default' => ''); - - $options['element_label_type'] = array('default' => ''); - $options['element_label_class'] = array('default' => ''); - $options['element_label_colon'] = array('default' => TRUE); - - $options['element_wrapper_type'] = array('default' => ''); - $options['element_wrapper_class'] = array('default' => ''); - - $options['element_default_classes'] = array('default' => TRUE); - - $options['empty'] = array('default' => ''); - $options['hide_empty'] = array('default' => FALSE); - $options['empty_zero'] = array('default' => FALSE); - $options['hide_alter_empty'] = array('default' => TRUE); + $options['exclude'] = ['default' => FALSE]; + $options['alter'] = [ + 'contains' => [ + 'alter_text' => ['default' => FALSE], + 'text' => ['default' => ''], + 'make_link' => ['default' => FALSE], + 'path' => ['default' => ''], + 'absolute' => ['default' => FALSE], + 'external' => ['default' => FALSE], + 'replace_spaces' => ['default' => FALSE], + 'path_case' => ['default' => 'none'], + 'trim_whitespace' => ['default' => FALSE], + 'alt' => ['default' => ''], + 'rel' => ['default' => ''], + 'link_class' => ['default' => ''], + 'prefix' => ['default' => ''], + 'suffix' => ['default' => ''], + 'target' => ['default' => ''], + 'nl2br' => ['default' => FALSE], + 'max_length' => ['default' => 0], + 'word_boundary' => ['default' => TRUE], + 'ellipsis' => ['default' => TRUE], + 'more_link' => ['default' => FALSE], + 'more_link_text' => ['default' => ''], + 'more_link_path' => ['default' => ''], + 'strip_tags' => ['default' => FALSE], + 'trim' => ['default' => FALSE], + 'preserve_tags' => ['default' => ''], + 'html' => ['default' => FALSE], + ], + ]; + $options['element_type'] = ['default' => '']; + $options['element_class'] = ['default' => '']; + + $options['element_label_type'] = ['default' => '']; + $options['element_label_class'] = ['default' => '']; + $options['element_label_colon'] = ['default' => TRUE]; + + $options['element_wrapper_type'] = ['default' => '']; + $options['element_wrapper_class'] = ['default' => '']; + + $options['element_default_classes'] = ['default' => TRUE]; + + $options['empty'] = ['default' => '']; + $options['hide_empty'] = ['default' => FALSE]; + $options['empty_zero'] = ['default' => FALSE]; + $options['hide_alter_empty'] = ['default' => TRUE]; return $options; } @@ -484,8 +484,8 @@ protected function defineOptions() { */ public function submitOptionsForm(&$form, FormStateInterface $form_state) { $options = &$form_state->getValue('options'); - $types = array('element_type', 'element_label_type', 'element_wrapper_type'); - $classes = array_combine(array('element_class', 'element_label_class', 'element_wrapper_class'), $types); + $types = ['element_type', 'element_label_type', 'element_wrapper_type']; + $classes = array_combine(['element_class', 'element_label_class', 'element_wrapper_class'], $types); foreach ($types as $type) { if (!$options[$type . '_enable']) { @@ -513,349 +513,349 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $label = $this->label(); - $form['custom_label'] = array( + $form['custom_label'] = [ '#type' => 'checkbox', '#title' => $this->t('Create a label'), '#default_value' => $label !== '', '#weight' => -103, - ); - $form['label'] = array( + ]; + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Label'), '#default_value' => $label, - '#states' => array( - 'visible' => array( - ':input[name="options[custom_label]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[custom_label]"]' => ['checked' => TRUE], + ], + ], '#weight' => -102, - ); - $form['element_label_colon'] = array( + ]; + $form['element_label_colon'] = [ '#type' => 'checkbox', '#title' => $this->t('Place a colon after the label'), '#default_value' => $this->options['element_label_colon'], - '#states' => array( - 'visible' => array( - ':input[name="options[custom_label]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[custom_label]"]' => ['checked' => TRUE], + ], + ], '#weight' => -101, - ); + ]; - $form['exclude'] = array( + $form['exclude'] = [ '#type' => 'checkbox', '#title' => $this->t('Exclude from display'), '#default_value' => $this->options['exclude'], '#description' => $this->t('Enable to load this field as hidden. Often used to group fields, or to use as token in another field.'), '#weight' => -100, - ); + ]; - $form['style_settings'] = array( + $form['style_settings'] = [ '#type' => 'details', '#title' => $this->t('Style settings'), '#weight' => 99, - ); + ]; - $form['element_type_enable'] = array( + $form['element_type_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Customize field HTML'), '#default_value' => !empty($this->options['element_type']) || (string) $this->options['element_type'] == '0' || !empty($this->options['element_class']) || (string) $this->options['element_class'] == '0', '#fieldset' => 'style_settings', - ); - $form['element_type'] = array( + ]; + $form['element_type'] = [ '#title' => $this->t('HTML element'), '#options' => $this->getElements(), '#type' => 'select', '#default_value' => $this->options['element_type'], '#description' => $this->t('Choose the HTML element to wrap around this field, e.g. H1, H2, etc.'), - '#states' => array( - 'visible' => array( - ':input[name="options[element_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_type_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'style_settings', - ); + ]; - $form['element_class_enable'] = array( + $form['element_class_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Create a CSS class'), - '#states' => array( - 'visible' => array( - ':input[name="options[element_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_type_enable]"]' => ['checked' => TRUE], + ], + ], '#default_value' => !empty($this->options['element_class']) || (string) $this->options['element_class'] == '0', '#fieldset' => 'style_settings', - ); - $form['element_class'] = array( + ]; + $form['element_class'] = [ '#title' => $this->t('CSS class'), '#description' => $this->t('You may use token substitutions from the rewriting section in this class.'), '#type' => 'textfield', '#default_value' => $this->options['element_class'], - '#states' => array( - 'visible' => array( - ':input[name="options[element_type_enable]"]' => array('checked' => TRUE), - ':input[name="options[element_class_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_type_enable]"]' => ['checked' => TRUE], + ':input[name="options[element_class_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'style_settings', - ); + ]; - $form['element_label_type_enable'] = array( + $form['element_label_type_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Customize label HTML'), '#default_value' => !empty($this->options['element_label_type']) || (string) $this->options['element_label_type'] == '0' || !empty($this->options['element_label_class']) || (string) $this->options['element_label_class'] == '0', '#fieldset' => 'style_settings', - ); - $form['element_label_type'] = array( + ]; + $form['element_label_type'] = [ '#title' => $this->t('Label HTML element'), '#options' => $this->getElements(FALSE), '#type' => 'select', '#default_value' => $this->options['element_label_type'], '#description' => $this->t('Choose the HTML element to wrap around this label, e.g. H1, H2, etc.'), - '#states' => array( - 'visible' => array( - ':input[name="options[element_label_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_label_type_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'style_settings', - ); - $form['element_label_class_enable'] = array( + ]; + $form['element_label_class_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Create a CSS class'), - '#states' => array( - 'visible' => array( - ':input[name="options[element_label_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_label_type_enable]"]' => ['checked' => TRUE], + ], + ], '#default_value' => !empty($this->options['element_label_class']) || (string) $this->options['element_label_class'] == '0', '#fieldset' => 'style_settings', - ); - $form['element_label_class'] = array( + ]; + $form['element_label_class'] = [ '#title' => $this->t('CSS class'), '#description' => $this->t('You may use token substitutions from the rewriting section in this class.'), '#type' => 'textfield', '#default_value' => $this->options['element_label_class'], - '#states' => array( - 'visible' => array( - ':input[name="options[element_label_type_enable]"]' => array('checked' => TRUE), - ':input[name="options[element_label_class_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_label_type_enable]"]' => ['checked' => TRUE], + ':input[name="options[element_label_class_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'style_settings', - ); + ]; - $form['element_wrapper_type_enable'] = array( + $form['element_wrapper_type_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Customize field and label wrapper HTML'), '#default_value' => !empty($this->options['element_wrapper_type']) || (string) $this->options['element_wrapper_type'] == '0' || !empty($this->options['element_wrapper_class']) || (string) $this->options['element_wrapper_class'] == '0', '#fieldset' => 'style_settings', - ); - $form['element_wrapper_type'] = array( + ]; + $form['element_wrapper_type'] = [ '#title' => $this->t('Wrapper HTML element'), '#options' => $this->getElements(FALSE), '#type' => 'select', '#default_value' => $this->options['element_wrapper_type'], '#description' => $this->t('Choose the HTML element to wrap around this field and label, e.g. H1, H2, etc. This may not be used if the field and label are not rendered together, such as with a table.'), - '#states' => array( - 'visible' => array( - ':input[name="options[element_wrapper_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_wrapper_type_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'style_settings', - ); + ]; - $form['element_wrapper_class_enable'] = array( + $form['element_wrapper_class_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Create a CSS class'), - '#states' => array( - 'visible' => array( - ':input[name="options[element_wrapper_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_wrapper_type_enable]"]' => ['checked' => TRUE], + ], + ], '#default_value' => !empty($this->options['element_wrapper_class']) || (string) $this->options['element_wrapper_class'] == '0', '#fieldset' => 'style_settings', - ); - $form['element_wrapper_class'] = array( + ]; + $form['element_wrapper_class'] = [ '#title' => $this->t('CSS class'), '#description' => $this->t('You may use token substitutions from the rewriting section in this class.'), '#type' => 'textfield', '#default_value' => $this->options['element_wrapper_class'], - '#states' => array( - 'visible' => array( - ':input[name="options[element_wrapper_class_enable]"]' => array('checked' => TRUE), - ':input[name="options[element_wrapper_type_enable]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[element_wrapper_class_enable]"]' => ['checked' => TRUE], + ':input[name="options[element_wrapper_type_enable]"]' => ['checked' => TRUE], + ], + ], '#fieldset' => 'style_settings', - ); + ]; - $form['element_default_classes'] = array( + $form['element_default_classes'] = [ '#type' => 'checkbox', '#title' => $this->t('Add default classes'), '#default_value' => $this->options['element_default_classes'], '#description' => $this->t('Use default Views classes to identify the field, field label and field content.'), '#fieldset' => 'style_settings', - ); + ]; - $form['alter'] = array( + $form['alter'] = [ '#title' => $this->t('Rewrite results'), '#type' => 'details', '#weight' => 100, - ); + ]; if ($this->allowAdvancedRender()) { $form['alter']['#tree'] = TRUE; - $form['alter']['alter_text'] = array( + $form['alter']['alter_text'] = [ '#type' => 'checkbox', '#title' => $this->t('Override the output of this field with custom text'), '#default_value' => $this->options['alter']['alter_text'], - ); + ]; - $form['alter']['text'] = array( + $form['alter']['text'] = [ '#title' => $this->t('Text'), '#type' => 'textarea', '#default_value' => $this->options['alter']['text'], - '#description' => $this->t('The text to display for this field. You may include HTML or Twig. You may enter data from this view as per the "Replacement patterns" below.', array(':url' => CoreUrl::fromUri('http://twig.sensiolabs.org/documentation')->toString())), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][alter_text]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['make_link'] = array( + '#description' => $this->t('The text to display for this field. You may include HTML or Twig. You may enter data from this view as per the "Replacement patterns" below.', [':url' => CoreUrl::fromUri('http://twig.sensiolabs.org/documentation')->toString()]), + '#states' => [ + 'visible' => [ + ':input[name="options[alter][alter_text]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['make_link'] = [ '#type' => 'checkbox', '#title' => $this->t('Output this field as a custom link'), '#default_value' => $this->options['alter']['make_link'], - ); - $form['alter']['path'] = array( + ]; + $form['alter']['path'] = [ '#title' => $this->t('Link path'), '#type' => 'textfield', '#default_value' => $this->options['alter']['path'], '#description' => $this->t('The Drupal path or absolute URL for this link. You may enter data from this view as per the "Replacement patterns" below.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], '#maxlength' => 255, - ); - $form['alter']['absolute'] = array( + ]; + $form['alter']['absolute'] = [ '#type' => 'checkbox', '#title' => $this->t('Use absolute path'), '#default_value' => $this->options['alter']['absolute'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['replace_spaces'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['replace_spaces'] = [ '#type' => 'checkbox', '#title' => $this->t('Replace spaces with dashes'), '#default_value' => $this->options['alter']['replace_spaces'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['external'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['external'] = [ '#type' => 'checkbox', '#title' => $this->t('External server URL'), '#default_value' => $this->options['alter']['external'], '#description' => $this->t("Links to an external server using a full URL: e.g. 'http://www.example.com' or 'www.example.com'."), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['path_case'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['path_case'] = [ '#type' => 'select', '#title' => $this->t('Transform the case'), '#description' => $this->t('When printing URL paths, how to transform the case of the filter value.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - '#options' => array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + '#options' => [ 'none' => $this->t('No transform'), 'upper' => $this->t('Upper case'), 'lower' => $this->t('Lower case'), 'ucfirst' => $this->t('Capitalize first letter'), 'ucwords' => $this->t('Capitalize each word'), - ), + ], '#default_value' => $this->options['alter']['path_case'], - ); - $form['alter']['link_class'] = array( + ]; + $form['alter']['link_class'] = [ '#title' => $this->t('Link class'), '#type' => 'textfield', '#default_value' => $this->options['alter']['link_class'], '#description' => $this->t('The CSS class to apply to the link.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['alt'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['alt'] = [ '#title' => $this->t('Title text'), '#type' => 'textfield', '#default_value' => $this->options['alter']['alt'], '#description' => $this->t('Text to place as "title" text which most browsers display as a tooltip when hovering over the link.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['rel'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['rel'] = [ '#title' => $this->t('Rel Text'), '#type' => 'textfield', '#default_value' => $this->options['alter']['rel'], '#description' => $this->t('Include Rel attribute for use in lightbox2 or other javascript utility.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['prefix'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['prefix'] = [ '#title' => $this->t('Prefix text'), '#type' => 'textfield', '#default_value' => $this->options['alter']['prefix'], '#description' => $this->t('Any text to display before this link. You may include HTML.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['suffix'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['suffix'] = [ '#title' => $this->t('Suffix text'), '#type' => 'textfield', '#default_value' => $this->options['alter']['suffix'], '#description' => $this->t('Any text to display after this link. You may include HTML.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['target'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['target'] = [ '#title' => $this->t('Target'), '#type' => 'textfield', '#default_value' => $this->options['alter']['target'], '#description' => $this->t("Target of the link, such as _blank, _parent or an iframe's name. This field is rarely used."), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + ], + ]; // Get a list of the available fields and arguments for token replacement. @@ -865,14 +865,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $optgroup_arguments = (string) t('Arguments'); $optgroup_fields = (string) t('Fields'); foreach ($previous as $id => $label) { - $options[$optgroup_fields]["{{ $id }}"] = substr(strrchr($label, ":"), 2 ); + $options[$optgroup_fields]["{{ $id }}"] = substr(strrchr($label, ":"), 2); } // Add the field to the list of options. - $options[$optgroup_fields]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2 ); + $options[$optgroup_fields]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2); foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) { - $options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', array('@argument' => $handler->adminLabel())); - $options[$optgroup_arguments]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', array('@argument' => $handler->adminLabel())); + $options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', ['@argument' => $handler->adminLabel()]); + $options[$optgroup_arguments]["{{ raw_arguments.$arg }}"] = $this->t('@argument input', ['@argument' => $handler->adminLabel()]); } $this->documentSelfTokens($options[$optgroup_fields]); @@ -890,14 +890,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { ]; foreach (array_keys($options) as $type) { if (!empty($options[$type])) { - $items = array(); + $items = []; foreach ($options[$type] as $key => $value) { $items[] = $key . ' == ' . $value; } - $item_list = array( + $item_list = [ '#theme' => 'item_list', '#items' => $items, - ); + ]; $output[] = $item_list; } } @@ -906,181 +906,181 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // run. It also has an extra div because the dependency wants to hide // the parent in situations like this, so we need a second div to // make this work. - $form['alter']['help'] = array( + $form['alter']['help'] = [ '#type' => 'details', '#title' => $this->t('Replacement patterns'), '#value' => $output, - '#states' => array( - 'visible' => array( - array( - ':input[name="options[alter][make_link]"]' => array('checked' => TRUE), - ), - array( - ':input[name="options[alter][alter_text]"]' => array('checked' => TRUE), - ), - array( - ':input[name="options[alter][more_link]"]' => array('checked' => TRUE), - ), - ), - ), - ); - - $form['alter']['trim'] = array( + '#states' => [ + 'visible' => [ + [ + ':input[name="options[alter][make_link]"]' => ['checked' => TRUE], + ], + [ + ':input[name="options[alter][alter_text]"]' => ['checked' => TRUE], + ], + [ + ':input[name="options[alter][more_link]"]' => ['checked' => TRUE], + ], + ], + ], + ]; + + $form['alter']['trim'] = [ '#type' => 'checkbox', '#title' => $this->t('Trim this field to a maximum number of characters'), '#default_value' => $this->options['alter']['trim'], - ); + ]; - $form['alter']['max_length'] = array( + $form['alter']['max_length'] = [ '#title' => $this->t('Maximum number of characters'), '#type' => 'textfield', '#default_value' => $this->options['alter']['max_length'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['word_boundary'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['word_boundary'] = [ '#type' => 'checkbox', '#title' => $this->t('Trim only on a word boundary'), '#description' => $this->t('If checked, this field be trimmed only on a word boundary. This is guaranteed to be the maximum characters stated or less. If there are no word boundaries this could trim a field to nothing.'), '#default_value' => $this->options['alter']['word_boundary'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['ellipsis'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['ellipsis'] = [ '#type' => 'checkbox', '#title' => $this->t('Add "…" at the end of trimmed text'), '#default_value' => $this->options['alter']['ellipsis'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['more_link'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['more_link'] = [ '#type' => 'checkbox', '#title' => $this->t('Add a read-more link if output is trimmed'), '#default_value' => $this->options['alter']['more_link'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['more_link_text'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['more_link_text'] = [ '#type' => 'textfield', '#title' => $this->t('More link label'), '#default_value' => $this->options['alter']['more_link_text'], '#description' => $this->t('You may use the "Replacement patterns" above.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ':input[name="options[alter][more_link]"]' => array('checked' => TRUE), - ), - ), - ); - $form['alter']['more_link_path'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ':input[name="options[alter][more_link]"]' => ['checked' => TRUE], + ], + ], + ]; + $form['alter']['more_link_path'] = [ '#type' => 'textfield', '#title' => $this->t('More link path'), '#default_value' => $this->options['alter']['more_link_path'], '#description' => $this->t('This can be an internal Drupal path such as node/add or an external URL such as "https://www.drupal.org". You may use the "Replacement patterns" above.'), - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ':input[name="options[alter][more_link]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['html'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ':input[name="options[alter][more_link]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['html'] = [ '#type' => 'checkbox', '#title' => $this->t('Field can contain HTML'), '#description' => $this->t('An HTML corrector will be run to ensure HTML tags are properly closed after trimming.'), '#default_value' => $this->options['alter']['html'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][trim]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['strip_tags'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][trim]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['strip_tags'] = [ '#type' => 'checkbox', '#title' => $this->t('Strip HTML tags'), '#default_value' => $this->options['alter']['strip_tags'], - ); + ]; - $form['alter']['preserve_tags'] = array( + $form['alter']['preserve_tags'] = [ '#type' => 'textfield', '#title' => $this->t('Preserve certain tags'), '#description' => $this->t('List the tags that need to be preserved during the stripping process. example "<p> <br>" which will preserve all p and br elements'), '#default_value' => $this->options['alter']['preserve_tags'], - '#states' => array( - 'visible' => array( - ':input[name="options[alter][strip_tags]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['alter']['trim_whitespace'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[alter][strip_tags]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['alter']['trim_whitespace'] = [ '#type' => 'checkbox', '#title' => $this->t('Remove whitespace'), '#default_value' => $this->options['alter']['trim_whitespace'], - ); + ]; - $form['alter']['nl2br'] = array( + $form['alter']['nl2br'] = [ '#type' => 'checkbox', '#title' => $this->t('Convert newlines to HTML <br> tags'), '#default_value' => $this->options['alter']['nl2br'], - ); + ]; } - $form['empty_field_behavior'] = array( + $form['empty_field_behavior'] = [ '#type' => 'details', '#title' => $this->t('No results behavior'), '#weight' => 100, - ); + ]; - $form['empty'] = array( + $form['empty'] = [ '#type' => 'textarea', '#title' => $this->t('No results text'), '#default_value' => $this->options['empty'], '#description' => $this->t('Provide text to display if this field contains an empty result. You may include HTML. You may enter data from this view as per the "Replacement patterns" in the "Rewrite Results" section below.'), '#fieldset' => 'empty_field_behavior', - ); + ]; - $form['empty_zero'] = array( + $form['empty_zero'] = [ '#type' => 'checkbox', '#title' => $this->t('Count the number 0 as empty'), '#default_value' => $this->options['empty_zero'], '#description' => $this->t('Enable to display the "no results text" if the field contains the number 0.'), '#fieldset' => 'empty_field_behavior', - ); + ]; - $form['hide_empty'] = array( + $form['hide_empty'] = [ '#type' => 'checkbox', '#title' => $this->t('Hide if empty'), '#default_value' => $this->options['hide_empty'], '#description' => $this->t('Enable to hide this field if it is empty. Note that the field label or rewritten output may still be displayed. To hide labels, check the style or row style settings for empty fields. To hide rewritten content, check the "Hide rewriting if empty" checkbox.'), '#fieldset' => 'empty_field_behavior', - ); + ]; - $form['hide_alter_empty'] = array( + $form['hide_alter_empty'] = [ '#type' => 'checkbox', '#title' => $this->t('Hide rewriting if empty'), '#default_value' => $this->options['hide_alter_empty'], '#description' => $this->t('Do not display rewritten content if this field is empty.'), '#fieldset' => 'empty_field_behavior', - ); + ]; } /** @@ -1105,7 +1105,7 @@ public function adminSummary() { /** * {@inheritdoc} */ - public function preRender(&$values) { } + public function preRender(&$values) {} /** * {@inheritdoc} @@ -1152,7 +1152,7 @@ public function advancedRender(ResultRow $values) { if ($this->allowAdvancedRender()) { $tokens = NULL; if ($this instanceof MultiItemsFieldHandlerInterface) { - $items = array(); + $items = []; foreach ($raw_items as $count => $item) { $value = $this->render_item($count, $item); if (is_array($value)) { @@ -1169,7 +1169,7 @@ public function advancedRender(ResultRow $values) { $value = $this->renderItems($items); } else { - $alter = array('phase' => static::RENDER_TEXT_PHASE_COMPLETELY) + $this->options['alter']; + $alter = ['phase' => static::RENDER_TEXT_PHASE_COMPLETELY] + $this->options['alter']; $value = $this->renderText($alter); } @@ -1291,13 +1291,13 @@ public function renderText($alter) { // @todo Views should expect and store a leading /. See // https://www.drupal.org/node/2423913. - $options = array( - 'attributes' => array( - 'class' => array( + $options = [ + 'attributes' => [ + 'class' => [ 'views-more-link', - ), - ), - ); + ], + ], + ]; if (UrlHelper::isExternal($more_link_path)) { $more_link_url = CoreUrl::fromUri($more_link_path, $options); } @@ -1375,7 +1375,7 @@ protected function renderTrimText($alter, $value) { * the user. */ protected function renderAsLink($alter, $text, $tokens) { - $options = array( + $options = [ 'absolute' => !empty($alter['absolute']) ? TRUE : FALSE, 'alias' => FALSE, 'entity' => NULL, @@ -1383,7 +1383,7 @@ protected function renderAsLink($alter, $text, $tokens) { 'fragment' => NULL, 'language' => NULL, 'query' => [], - ); + ]; $alter += [ 'path' => NULL @@ -1395,7 +1395,7 @@ protected function renderAsLink($alter, $text, $tokens) { if ($path != '') { // Use strip_tags as there should never be HTML in the path. // However, we need to preserve special characters like " that were - // removed by SafeMarkup::checkPlain(). + // removed by Html::escape(). $path = Html::decodeEntities($this->viewsTokenReplace($alter['path'], $tokens)); // Tokens might contain , so check for again. @@ -1488,7 +1488,7 @@ protected function renderAsLink($alter, $text, $tokens) { } if (isset($url['fragment'])) { - $path = strtr($path, array('#' . $url['fragment'] => '')); + $path = strtr($path, ['#' . $url['fragment'] => '']); // If the path is empty we want to have a fragment for the current site. if ($path == '') { $options['external'] = TRUE; @@ -1504,7 +1504,7 @@ protected function renderAsLink($alter, $text, $tokens) { $class = $this->viewsTokenReplace($alter['link_class'], $tokens); if ($class) { - $options['attributes']['class'] = array($class); + $options['attributes']['class'] = [$class]; } if (!empty($alter['rel']) && $rel = $this->viewsTokenReplace($alter['rel'], $tokens)) { @@ -1534,7 +1534,7 @@ protected function renderAsLink($alter, $text, $tokens) { // \Drupal\Core\Utility\LinkGeneratorInterface::generate(). $options['query'] = UrlHelper::buildQuery($alter['query']); $options['query'] = $this->viewsTokenReplace($options['query'], $tokens); - $query = array(); + $query = []; parse_str($options['query'], $query); $options['query'] = $query; } @@ -1582,7 +1582,7 @@ protected function renderAsLink($alter, $text, $tokens) { * {@inheritdoc} */ public function getRenderTokens($item) { - $tokens = array(); + $tokens = []; if (!empty($this->view->build_info['substitutions'])) { $tokens = $this->view->build_info['substitutions']; } @@ -1595,7 +1595,7 @@ public function getRenderTokens($item) { // Use strip tags as there should never be HTML in the path. // However, we need to preserve special characters like " that - // were removed by SafeMarkup::checkPlain(). + // were removed by Html::escape(). $tokens["{{ raw_arguments.$arg }}"] = isset($this->view->args[$count]) ? strip_tags(Html::decodeEntities($this->view->args[$count])) : ''; $count++; } @@ -1677,8 +1677,8 @@ protected function getFieldTokenPlaceholder() { * @return * An array of available tokens, with nested keys representative of the array structure. */ - protected function getTokenValuesRecursive(array $array, array $parent_keys = array()) { - $tokens = array(); + protected function getTokenValuesRecursive(array $array, array $parent_keys = []) { + $tokens = []; foreach ($array as $param => $val) { if (is_array($val)) { @@ -1713,26 +1713,26 @@ protected function getTokenValuesRecursive(array $array, array $parent_keys = ar * field ID is terms, then the tokens might be {{ terms__tid }} and * {{ terms__name }}. */ - protected function addSelfTokens(&$tokens, $item) { } + protected function addSelfTokens(&$tokens, $item) {} /** * Document any special tokens this field might use for itself. * * @see addSelfTokens() */ - protected function documentSelfTokens(&$tokens) { } + protected function documentSelfTokens(&$tokens) {} /** * {@inheritdoc} */ - function theme(ResultRow $values) { + public function theme(ResultRow $values) { $renderer = $this->getRenderer(); - $build = array( + $build = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#field' => $this, '#row' => $values, - ); + ]; $output = $renderer->render($build); // Set the bubbleable rendering metadata on $view->element. This ensures the @@ -1744,7 +1744,7 @@ function theme(ResultRow $values) { } public function themeFunctions() { - $themes = array(); + $themes = []; $hook = 'views_view_field'; $display = $this->view->display_handler->display; diff --git a/core/modules/views/src/Plugin/views/field/FileSize.php b/core/modules/views/src/Plugin/views/field/FileSize.php index af184d3e..c8a0b956 100644 --- a/core/modules/views/src/Plugin/views/field/FileSize.php +++ b/core/modules/views/src/Plugin/views/field/FileSize.php @@ -20,7 +20,7 @@ class FileSize extends FieldPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['file_size_display'] = array('default' => 'formatted'); + $options['file_size_display'] = ['default' => 'formatted']; return $options; } @@ -30,14 +30,14 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['file_size_display'] = array( + $form['file_size_display'] = [ '#title' => $this->t('File size display'), '#type' => 'select', - '#options' => array( + '#options' => [ 'formatted' => $this->t('Formatted (in KB or MB)'), 'bytes' => $this->t('Raw bytes'), - ), - ); + ], + ]; } /** diff --git a/core/modules/views/src/Plugin/views/field/LanguageField.php b/core/modules/views/src/Plugin/views/field/LanguageField.php index f51f2fbb..53e2c84e 100644 --- a/core/modules/views/src/Plugin/views/field/LanguageField.php +++ b/core/modules/views/src/Plugin/views/field/LanguageField.php @@ -19,7 +19,7 @@ class LanguageField extends FieldPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['native_language'] = array('default' => FALSE); + $options['native_language'] = ['default' => FALSE]; return $options; } @@ -29,11 +29,11 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['native_language'] = array( + $form['native_language'] = [ '#title' => $this->t('Display in native language'), '#type' => 'checkbox', '#default_value' => $this->options['native_language'], - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/field/LinkBase.php b/core/modules/views/src/Plugin/views/field/LinkBase.php index ebe1e9d0..31dca4c7 100644 --- a/core/modules/views/src/Plugin/views/field/LinkBase.php +++ b/core/modules/views/src/Plugin/views/field/LinkBase.php @@ -82,7 +82,7 @@ protected function currentUser() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['text'] = array('default' => $this->getDefaultLabel()); + $options['text'] = ['default' => $this->getDefaultLabel()]; return $options; } diff --git a/core/modules/views/src/Plugin/views/field/Links.php b/core/modules/views/src/Plugin/views/field/Links.php index 6f169572..4e731a9a 100644 --- a/core/modules/views/src/Plugin/views/field/Links.php +++ b/core/modules/views/src/Plugin/views/field/Links.php @@ -26,8 +26,8 @@ public function usesGroupBy() { public function defineOptions() { $options = parent::defineOptions(); - $options['fields'] = array('default' => array()); - $options['destination'] = array('default' => TRUE); + $options['fields'] = ['default' => []]; + $options['destination'] = ['default' => TRUE]; return $options; } @@ -39,19 +39,19 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); // Only show fields that precede this one. $field_options = $this->getPreviousFieldLabels(); - $form['fields'] = array( + $form['fields'] = [ '#type' => 'checkboxes', '#title' => $this->t('Fields'), '#description' => $this->t('Fields to be included as links.'), '#options' => $field_options, '#default_value' => $this->options['fields'], - ); - $form['destination'] = array( + ]; + $form['destination'] = [ '#type' => 'checkbox', '#title' => $this->t('Include destination'), '#description' => $this->t('Include a "destination" parameter in the link to return the user to the original view upon completing the link action.'), '#default_value' => $this->options['destination'], - ); + ]; } /** @@ -61,7 +61,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * The links which are used by the render function. */ protected function getLinks() { - $links = array(); + $links = []; foreach ($this->options['fields'] as $field) { if (empty($this->view->field[$field]->last_render_text)) { continue; @@ -76,13 +76,13 @@ protected function getLinks() { $url = $this->view->field[$field]->options['alter']['url']; } // Make sure that tokens are replaced for this paths as well. - $tokens = $this->getRenderTokens(array()); + $tokens = $this->getRenderTokens([]); $path = strip_tags(Html::decodeEntities($this->viewsTokenReplace($path, $tokens))); - $links[$field] = array( + $links[$field] = [ 'url' => $path ? UrlObject::fromUri('internal:/' . $path) : $url, 'title' => $title, - ); + ]; if (!empty($this->options['destination'])) { $links[$field]['query'] = \Drupal::destination()->getAsArray(); } diff --git a/core/modules/views/src/Plugin/views/field/MachineName.php b/core/modules/views/src/Plugin/views/field/MachineName.php index feba80e6..ea6a0c4b 100644 --- a/core/modules/views/src/Plugin/views/field/MachineName.php +++ b/core/modules/views/src/Plugin/views/field/MachineName.php @@ -36,7 +36,7 @@ public function getValueOptions() { } } else { - $this->valueOptions = array(); + $this->valueOptions = []; } } @@ -45,7 +45,7 @@ public function getValueOptions() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['machine_name'] = array('default' => FALSE); + $options['machine_name'] = ['default' => FALSE]; return $options; } @@ -56,12 +56,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['machine_name'] = array( + $form['machine_name'] = [ '#title' => $this->t('Output machine name'), '#description' => $this->t('Display field as machine name.'), '#type' => 'checkbox', '#default_value' => !empty($this->options['machine_name']), - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/field/Markup.php b/core/modules/views/src/Plugin/views/field/Markup.php index 7ca789f6..883bd56f 100644 --- a/core/modules/views/src/Plugin/views/field/Markup.php +++ b/core/modules/views/src/Plugin/views/field/Markup.php @@ -29,7 +29,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o $this->format = $this->definition['format']; - $this->additional_fields = array(); + $this->additional_fields = []; if (is_array($this->format)) { $this->additional_fields['format'] = $this->format; } diff --git a/core/modules/views/src/Plugin/views/field/NumericField.php b/core/modules/views/src/Plugin/views/field/NumericField.php index 0cf4c889..75113348 100644 --- a/core/modules/views/src/Plugin/views/field/NumericField.php +++ b/core/modules/views/src/Plugin/views/field/NumericField.php @@ -25,14 +25,14 @@ class NumericField extends FieldPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['set_precision'] = array('default' => FALSE); - $options['precision'] = array('default' => 0); - $options['decimal'] = array('default' => '.'); - $options['separator'] = array('default' => ','); - $options['format_plural'] = array('default' => FALSE); - $options['format_plural_string'] = array('default' => '1' . LOCALE_PLURAL_DELIMITER . '@count'); - $options['prefix'] = array('default' => ''); - $options['suffix'] = array('default' => ''); + $options['set_precision'] = ['default' => FALSE]; + $options['precision'] = ['default' => 0]; + $options['decimal'] = ['default' => '.']; + $options['separator'] = ['default' => ',']; + $options['format_plural'] = ['default' => FALSE]; + $options['format_plural_string'] = ['default' => '1' . LOCALE_PLURAL_DELIMITER . '@count']; + $options['prefix'] = ['default' => '']; + $options['suffix'] = ['default' => '']; return $options; } @@ -42,72 +42,72 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if (!empty($this->definition['float'])) { - $form['set_precision'] = array( + $form['set_precision'] = [ '#type' => 'checkbox', '#title' => $this->t('Round'), '#description' => $this->t('If checked, the number will be rounded.'), '#default_value' => $this->options['set_precision'], - ); - $form['precision'] = array( + ]; + $form['precision'] = [ '#type' => 'textfield', '#title' => $this->t('Precision'), '#default_value' => $this->options['precision'], '#description' => $this->t('Specify how many digits to print after the decimal point.'), - '#states' => array( - 'visible' => array( - ':input[name="options[set_precision]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[set_precision]"]' => ['checked' => TRUE], + ], + ], '#size' => 2, - ); - $form['decimal'] = array( + ]; + $form['decimal'] = [ '#type' => 'textfield', '#title' => $this->t('Decimal point'), '#default_value' => $this->options['decimal'], '#description' => $this->t('What single character to use as a decimal point.'), '#size' => 2, - ); + ]; } - $form['separator'] = array( + $form['separator'] = [ '#type' => 'select', '#title' => $this->t('Thousands marker'), - '#options' => array( + '#options' => [ '' => $this->t('- None -'), ',' => $this->t('Comma'), ' ' => $this->t('Space'), '.' => $this->t('Decimal'), '\'' => $this->t('Apostrophe'), - ), + ], '#default_value' => $this->options['separator'], '#description' => $this->t('What single character to use as the thousands separator.'), '#size' => 2, - ); - $form['format_plural'] = array( + ]; + $form['format_plural'] = [ '#type' => 'checkbox', '#title' => $this->t('Format plural'), '#description' => $this->t('If checked, special handling will be used for plurality.'), '#default_value' => $this->options['format_plural'], - ); - $form['format_plural_string'] = array( + ]; + $form['format_plural_string'] = [ '#type' => 'value', '#default_value' => $this->options['format_plural_string'], - ); + ]; $plural_array = explode(LOCALE_PLURAL_DELIMITER, $this->options['format_plural_string']); $plurals = $this->getNumberOfPlurals($this->view->storage->get('langcode')); for ($i = 0; $i < $plurals; $i++) { - $form['format_plural_values'][$i] = array( + $form['format_plural_values'][$i] = [ '#type' => 'textfield', // @todo Should use better labels https://www.drupal.org/node/2499639 '#title' => ($i == 0 ? $this->t('Singular form') : $this->formatPlural($i, 'First plural form', '@count. plural form')), '#default_value' => isset($plural_array[$i]) ? $plural_array[$i] : '', '#description' => $this->t('Text to use for this variant, @count will be replaced with the value.'), - '#states' => array( - 'visible' => array( - ':input[name="options[format_plural]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[format_plural]"]' => ['checked' => TRUE], + ], + ], + ]; } if ($plurals == 2) { // Simplify interface text for the most common case. @@ -116,18 +116,18 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['format_plural_values'][1]['#description'] = $this->t('Text to use for the plural form, @count will be replaced with the value.'); } - $form['prefix'] = array( + $form['prefix'] = [ '#type' => 'textfield', '#title' => $this->t('Prefix'), '#default_value' => $this->options['prefix'], '#description' => $this->t('Text to put before the number, such as currency symbol.'), - ); - $form['suffix'] = array( + ]; + $form['suffix'] = [ '#type' => 'textfield', '#title' => $this->t('Suffix'), '#default_value' => $this->options['suffix'], '#description' => $this->t('Text to put after the number, such as currency symbol.'), - ); + ]; parent::buildOptionsForm($form, $form_state); } @@ -149,24 +149,32 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { */ public function render(ResultRow $values) { $value = $this->getValue($values); + + // Check to see if hiding should happen before adding prefix and suffix + // and before rewriting. + if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) { + return ''; + } + if (!empty($this->options['set_precision'])) { - $value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']); + $precision = $this->options['precision']; + } + elseif ($decimal_position = strpos($value, '.')) { + $precision = strlen($value) - $decimal_position - 1; } else { - $remainder = abs($value) - intval(abs($value)); - $value = $value > 0 ? floor($value) : ceil($value); - $value = number_format($value, 0, '', $this->options['separator']); - if ($remainder) { - // The substr may not be locale safe. - $value .= $this->options['decimal'] . substr($remainder, 2); - } + $precision = 0; } - // Check to see if hiding should happen before adding prefix and suffix. - if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) { + // Use round first to avoid negative zeros. + $value = round($value, $precision); + // Test against both integer zero and float zero. + if ($this->options['empty_zero'] && ($value === 0 || $value === 0.0)) { return ''; } + $value = number_format($value, $precision, $this->options['decimal'], $this->options['separator']); + // If we should format as plural, take the (possibly) translated plural // setting and format with the current language. if (!empty($this->options['format_plural'])) { diff --git a/core/modules/views/src/Plugin/views/field/PrerenderList.php b/core/modules/views/src/Plugin/views/field/PrerenderList.php index aa8f7520..f27973eb 100644 --- a/core/modules/views/src/Plugin/views/field/PrerenderList.php +++ b/core/modules/views/src/Plugin/views/field/PrerenderList.php @@ -25,7 +25,7 @@ abstract class PrerenderList extends FieldPluginBase implements MultiItemsFieldH * * @var array */ - public $items = array(); + public $items = []; /** * {@inheritdoc} @@ -33,8 +33,8 @@ abstract class PrerenderList extends FieldPluginBase implements MultiItemsFieldH protected function defineOptions() { $options = parent::defineOptions(); - $options['type'] = array('default' => 'separator'); - $options['separator'] = array('default' => ', '); + $options['type'] = ['default' => 'separator']; + $options['separator'] = ['default' => ', ']; return $options; } @@ -43,27 +43,27 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['type'] = array( + $form['type'] = [ '#type' => 'radios', '#title' => $this->t('Display type'), - '#options' => array( + '#options' => [ 'ul' => $this->t('Unordered list'), 'ol' => $this->t('Ordered list'), 'separator' => $this->t('Simple separator'), - ), + ], '#default_value' => $this->options['type'], - ); + ]; - $form['separator'] = array( + $form['separator'] = [ '#type' => 'textfield', '#title' => $this->t('Separator'), '#default_value' => $this->options['separator'], - '#states' => array( - 'visible' => array( - ':input[name="options[type]"]' => array('value' => 'separator'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[type]"]' => ['value' => 'separator'], + ], + ], + ]; parent::buildOptionsForm($form, $form_state); } @@ -83,14 +83,14 @@ public function renderItems($items) { ]; } else { - $render = array( + $render = [ '#theme' => 'item_list', '#items' => $items, '#title' => NULL, '#list_type' => $this->options['type'], - ); + ]; } - return drupal_render($render); + return \Drupal::service('renderer')->render($render); } } @@ -110,7 +110,7 @@ public function getItems(ResultRow $values) { return $this->items[$field]; } - return array(); + return []; } } diff --git a/core/modules/views/src/Plugin/views/field/RenderedEntity.php b/core/modules/views/src/Plugin/views/field/RenderedEntity.php index 3d0f8c72..86763865 100644 --- a/core/modules/views/src/Plugin/views/field/RenderedEntity.php +++ b/core/modules/views/src/Plugin/views/field/RenderedEntity.php @@ -46,7 +46,7 @@ class RenderedEntity extends FieldPluginBase implements CacheableDependencyInter * @param array $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager. + * The entity manager. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * The language manager. */ diff --git a/core/modules/views/src/Plugin/views/field/Serialized.php b/core/modules/views/src/Plugin/views/field/Serialized.php index 3df1cca7..4d74a4f1 100644 --- a/core/modules/views/src/Plugin/views/field/Serialized.php +++ b/core/modules/views/src/Plugin/views/field/Serialized.php @@ -19,8 +19,8 @@ class Serialized extends FieldPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['format'] = array('default' => 'unserialized'); - $options['key'] = array('default' => ''); + $options['format'] = ['default' => 'unserialized']; + $options['key'] = ['default' => '']; return $options; } @@ -30,27 +30,27 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['format'] = array( + $form['format'] = [ '#type' => 'select', '#title' => $this->t('Display format'), '#description' => $this->t('How should the serialized data be displayed. You can choose a custom array/object key or a print_r on the full output.'), - '#options' => array( + '#options' => [ 'unserialized' => $this->t('Full data (unserialized)'), 'serialized' => $this->t('Full data (serialized)'), 'key' => $this->t('A certain key'), - ), + ], '#default_value' => $this->options['format'], - ); - $form['key'] = array( + ]; + $form['key'] = [ '#type' => 'textfield', '#title' => $this->t('Which key should be displayed'), '#default_value' => $this->options['key'], - '#states' => array( - 'visible' => array( - ':input[name="options[format]"]' => array('value' => 'key'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[format]"]' => ['value' => 'key'], + ], + ], + ]; } /** @@ -58,7 +58,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { // Require a key if the format is key. - if ($form_state->getValue(array('options', 'format')) == 'key' && $form_state->getValue(array('options', 'key')) == '') { + if ($form_state->getValue(['options', 'format']) == 'key' && $form_state->getValue(['options', 'key']) == '') { $form_state->setError($form['key'], $this->t('You have to enter a key if you want to display a key of the data.')); } } diff --git a/core/modules/views/src/Plugin/views/field/TimeInterval.php b/core/modules/views/src/Plugin/views/field/TimeInterval.php index d7ec0d31..79cd1906 100644 --- a/core/modules/views/src/Plugin/views/field/TimeInterval.php +++ b/core/modules/views/src/Plugin/views/field/TimeInterval.php @@ -58,7 +58,7 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['granularity'] = array('default' => 2); + $options['granularity'] = ['default' => 2]; return $options; } @@ -69,12 +69,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['granularity'] = array( + $form['granularity'] = [ '#type' => 'textfield', '#title' => $this->t('Granularity'), '#description' => $this->t('How many different units to display in the string.'), '#default_value' => $this->options['granularity'], - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/field/Url.php b/core/modules/views/src/Plugin/views/field/Url.php index e847e447..08e1fbad 100644 --- a/core/modules/views/src/Plugin/views/field/Url.php +++ b/core/modules/views/src/Plugin/views/field/Url.php @@ -21,7 +21,7 @@ class Url extends FieldPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['display_as_link'] = array('default' => TRUE); + $options['display_as_link'] = ['default' => TRUE]; return $options; } @@ -30,11 +30,11 @@ protected function defineOptions() { * Provide link to the page being visited. */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['display_as_link'] = array( + $form['display_as_link'] = [ '#title' => $this->t('Display as link'), '#type' => 'checkbox', '#default_value' => !empty($this->options['display_as_link']), - ); + ]; parent::buildOptionsForm($form, $form_state); } diff --git a/core/modules/views/src/Plugin/views/filter/BooleanOperator.php b/core/modules/views/src/Plugin/views/filter/BooleanOperator.php index 7078032e..fa0d730f 100644 --- a/core/modules/views/src/Plugin/views/filter/BooleanOperator.php +++ b/core/modules/views/src/Plugin/views/filter/BooleanOperator.php @@ -49,12 +49,11 @@ class BooleanOperator extends FilterPluginBase { public $accept_null = FALSE; - /** * {@inheritdoc} */ public function operatorOptions($which = 'title') { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { $options[$id] = $info[$which]; } @@ -68,22 +67,22 @@ public function operatorOptions($which = 'title') { * @return array */ protected function operators() { - return array( - '=' => array( + return [ + '=' => [ 'title' => $this->t('Is equal to'), 'method' => 'queryOpBoolean', 'short' => $this->t('='), 'values' => 1, - 'query_operator' => static::EQUAL, - ), - '!=' => array( + 'query_operator' => self::EQUAL, + ], + '!=' => [ 'title' => $this->t('Is not equal to'), 'method' => 'queryOpBoolean', 'short' => $this->t('!='), 'values' => 1, - 'query_operator' => static::NOT_EQUAL, - ), - ); + 'query_operator' => self::NOT_EQUAL, + ], + ]; } /** @@ -125,19 +124,19 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o public function getValueOptions() { if (isset($this->definition['type'])) { if ($this->definition['type'] == 'yes-no') { - $this->valueOptions = array(1 => $this->t('Yes'), 0 => $this->t('No')); + $this->valueOptions = [1 => $this->t('Yes'), 0 => $this->t('No')]; } if ($this->definition['type'] == 'on-off') { - $this->valueOptions = array(1 => $this->t('On'), 0 => $this->t('Off')); + $this->valueOptions = [1 => $this->t('On'), 0 => $this->t('Off')]; } if ($this->definition['type'] == 'enabled-disabled') { - $this->valueOptions = array(1 => $this->t('Enabled'), 0 => $this->t('Disabled')); + $this->valueOptions = [1 => $this->t('Enabled'), 0 => $this->t('Disabled')]; } } // Provide a fallback if the above didn't set anything. if (!isset($this->valueOptions)) { - $this->valueOptions = array(1 => $this->t('True'), 0 => $this->t('False')); + $this->valueOptions = [1 => $this->t('True'), 0 => $this->t('False')]; } } @@ -162,12 +161,12 @@ protected function valueForm(&$form, FormStateInterface $form_state) { // Configuring a filter: use radios for clarity. $filter_form_type = 'radios'; } - $form['value'] = array( + $form['value'] = [ '#type' => $filter_form_type, '#title' => $this->value_value, '#options' => $this->valueOptions, '#default_value' => $this->value, - ); + ]; if (!empty($this->options['exposed'])) { $identifier = $this->options['expose']['identifier']; $user_input = $form_state->getUserInput(); @@ -177,13 +176,13 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } // If we're configuring an exposed filter, add an - Any - option. if (!$exposed || empty($this->options['expose']['required'])) { - $form['value']['#options'] = array('All' => $this->t('- Any -')) + $form['value']['#options']; + $form['value']['#options'] = ['All' => $this->t('- Any -')] + $form['value']['#options']; } } } protected function valueValidate($form, FormStateInterface $form_state) { - if ($form_state->getValue(array('options', 'value')) == 'All' && !$form_state->isValueEmpty(array('options', 'expose', 'required'))) { + if ($form_state->getValue(['options', 'value']) == 'All' && !$form_state->isValueEmpty(['options', 'expose', 'required'])) { $form_state->setErrorByName('value', $this->t('You must select a value unless this is an non-required exposed filter.')); } } @@ -221,7 +220,7 @@ public function query() { $info = $this->operators(); if (!empty($info[$this->operator]['method'])) { - call_user_func(array($this, $info[$this->operator]['method']), $field, $info[$this->operator]['query_operator']); + call_user_func([$this, $info[$this->operator]['method']], $field, $info[$this->operator]['query_operator']); } } @@ -231,13 +230,13 @@ public function query() { * @param string $field * The field name to add the where condition for. * @param string $query_operator - * (optional) Either static::EQUAL or static::NOT_EQUAL. Defaults to - * static::EQUAL. + * (optional) Either self::EQUAL or self::NOT_EQUAL. Defaults to + * self::EQUAL. */ - protected function queryOpBoolean($field, $query_operator = EQUAL) { + protected function queryOpBoolean($field, $query_operator = self::EQUAL) { if (empty($this->value)) { if ($this->accept_null) { - if ($query_operator == static::EQUAL) { + if ($query_operator === self::EQUAL) { $condition = (new Condition('OR')) ->condition($field, 0, $query_operator) ->isNull($field); @@ -255,12 +254,13 @@ protected function queryOpBoolean($field, $query_operator = EQUAL) { } else { if (!empty($this->definition['use_equal'])) { - // Forces an '=' operator instead of a '<>' for performance reasons. - if ($query_operator == static::EQUAL) { - $this->query->addWhere($this->options['group'], $field, 1, static::EQUAL); + // Forces a self::EQUAL operator instead of a self::NOT_EQUAL for + // performance reasons. + if ($query_operator === self::EQUAL) { + $this->query->addWhere($this->options['group'], $field, 1, self::EQUAL); } else { - $this->query->addWhere($this->options['group'], $field, 0, static::EQUAL); + $this->query->addWhere($this->options['group'], $field, 0, self::EQUAL); } } else { diff --git a/core/modules/views/src/Plugin/views/filter/Bundle.php b/core/modules/views/src/Plugin/views/filter/Bundle.php index 1ae5eb38..e14c35aa 100644 --- a/core/modules/views/src/Plugin/views/filter/Bundle.php +++ b/core/modules/views/src/Plugin/views/filter/Bundle.php @@ -56,6 +56,8 @@ class Bundle extends InOperator { * The plugin implementation definition. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info_service + * The bundle info service. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $bundle_info_service) { parent::__construct($configuration, $plugin_id, $plugin_definition); @@ -94,9 +96,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o public function getValueOptions() { if (!isset($this->valueOptions)) { $types = $this->bundleInfoService->getBundleInfo($this->entityTypeId); - $this->valueTitle = $this->t('@entity types', array('@entity' => $this->entityType->getLabel())); + $this->valueTitle = $this->t('@entity types', ['@entity' => $this->entityType->getLabel()]); - $options = array(); + $options = []; foreach ($types as $type => $info) { $options[$type] = $info['label']; } diff --git a/core/modules/views/src/Plugin/views/filter/Combine.php b/core/modules/views/src/Plugin/views/filter/Combine.php index 1b4ab9c1..f8ea624e 100644 --- a/core/modules/views/src/Plugin/views/filter/Combine.php +++ b/core/modules/views/src/Plugin/views/filter/Combine.php @@ -21,7 +21,7 @@ class Combine extends StringFilter { protected function defineOptions() { $options = parent::defineOptions(); - $options['fields'] = array('default' => array()); + $options['fields'] = ['default' => []]; return $options; } @@ -32,7 +32,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // Allow to choose all fields as possible if ($this->view->style_plugin->usesFields()) { - $options = array(); + $options = []; foreach ($this->view->display_handler->getHandlers('field') as $name => $field) { // Only allow clickSortable fields. Fields without clickSorting will // probably break in the Combine filter. @@ -41,14 +41,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } } if ($options) { - $form['fields'] = array( + $form['fields'] = [ '#type' => 'select', '#title' => $this->t('Choose fields to combine for filtering'), '#description' => $this->t("This filter doesn't work for very special field handlers."), '#multiple' => TRUE, '#options' => $options, '#default_value' => $this->options['fields'], - ); + ]; } else { $form_state->setErrorByName('', $this->t('You have to add some fields to be able to use this filter.')); @@ -58,7 +58,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function query() { $this->view->_build('field'); - $fields = array(); + $fields = []; // Only add the fields if they have a proper field and table alias. foreach ($this->options['fields'] as $id) { // Overridden fields can lead to fields missing from a display that are @@ -78,7 +78,7 @@ public function query() { } if ($fields) { $count = count($fields); - $separated_fields = array(); + $separated_fields = []; foreach ($fields as $key => $field) { $separated_fields[] = $field; if ($key < $count - 1) { @@ -106,7 +106,7 @@ public function validate() { if (!isset($fields[$id])) { // Combined field filter only works with fields that are in the field // settings. - $errors[] = $this->t('Field %field set in %filter is not set in display %display.', array('%field' => $id, '%filter' => $this->adminLabel(), '%display' => $this->displayHandler->display['display_title'])); + $errors[] = $this->t('Field %field set in %filter is not set in display %display.', ['%field' => $id, '%filter' => $this->adminLabel(), '%display' => $this->displayHandler->display['display_title']]); break; } elseif (!$fields[$id]->clickSortable()) { @@ -114,12 +114,12 @@ public function validate() { // is not click sortable we can assume it is not a simple field. // @todo change this check to isComputed. See // https://www.drupal.org/node/2349465 - $errors[] = $this->t('Field %field set in %filter is not usable for this filter type. Combined field filter only works for simple fields.', array('%field' => $fields[$id]->adminLabel(), '%filter' => $this->adminLabel())); + $errors[] = $this->t('Field %field set in %filter is not usable for this filter type. Combined field filter only works for simple fields.', ['%field' => $fields[$id]->adminLabel(), '%filter' => $this->adminLabel()]); } } } else { - $errors[] = $this->t('%display: %filter can only be used on displays that use fields. Set the style or row format for that display to one using fields to use the combine field filter.', array('%display' => $this->displayHandler->display['display_title'], '%filter' => $this->adminLabel())); + $errors[] = $this->t('%display: %filter can only be used on displays that use fields. Set the style or row format for that display to one using fields to use the combine field filter.', ['%display' => $this->displayHandler->display['display_title'], '%filter' => $this->adminLabel()]); } return $errors; } @@ -128,15 +128,15 @@ public function validate() { * By default things like opEqual uses add_where, that doesn't support * complex expressions, so override opEqual (and all operators below). */ - function opEqual($expression) { + public function opEqual($expression) { $placeholder = $this->placeholder(); $operator = $this->operator(); - $this->query->addWhereExpression($this->options['group'], "$expression $operator $placeholder", array($placeholder => $this->value)); + $this->query->addWhereExpression($this->options['group'], "$expression $operator $placeholder", [$placeholder => $this->value]); } protected function opContains($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%')); + $this->query->addWhereExpression($this->options['group'], "$expression LIKE $placeholder", [$placeholder => '%' . db_like($this->value) . '%']); } /** @@ -169,38 +169,38 @@ protected function opContainsWord($expression) { $temp_placeholder = $placeholder . '_' . $match_key; // Clean up the user input and remove the sentence delimiters. $word = trim($match[2], ',?!();:-"'); - $this->query->addWhereExpression($group, "$expression $operator $temp_placeholder", array($temp_placeholder => '%' . Database::getConnection()->escapeLike($word) . '%')); + $this->query->addWhereExpression($group, "$expression $operator $temp_placeholder", [$temp_placeholder => '%' . Database::getConnection()->escapeLike($word) . '%']); } } protected function opStartsWith($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression LIKE $placeholder", array($placeholder => db_like($this->value) . '%')); + $this->query->addWhereExpression($this->options['group'], "$expression LIKE $placeholder", [$placeholder => db_like($this->value) . '%']); } protected function opNotStartsWith($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression NOT LIKE $placeholder", array($placeholder => db_like($this->value) . '%')); + $this->query->addWhereExpression($this->options['group'], "$expression NOT LIKE $placeholder", [$placeholder => db_like($this->value) . '%']); } protected function opEndsWith($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression LIKE $placeholder", array($placeholder => '%' . db_like($this->value))); + $this->query->addWhereExpression($this->options['group'], "$expression LIKE $placeholder", [$placeholder => '%' . db_like($this->value)]); } protected function opNotEndsWith($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value))); + $this->query->addWhereExpression($this->options['group'], "$expression NOT LIKE $placeholder", [$placeholder => '%' . db_like($this->value)]); } protected function opNotLike($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%')); + $this->query->addWhereExpression($this->options['group'], "$expression NOT LIKE $placeholder", [$placeholder => '%' . db_like($this->value) . '%']); } protected function opRegex($expression) { $placeholder = $this->placeholder(); - $this->query->addWhereExpression($this->options['group'], "$expression REGEXP $placeholder", array($placeholder => $this->value)); + $this->query->addWhereExpression($this->options['group'], "$expression REGEXP $placeholder", [$placeholder => $this->value]); } protected function opEmpty($expression) { diff --git a/core/modules/views/src/Plugin/views/filter/Date.php b/core/modules/views/src/Plugin/views/filter/Date.php index 84a1c421..92e77dff 100644 --- a/core/modules/views/src/Plugin/views/filter/Date.php +++ b/core/modules/views/src/Plugin/views/filter/Date.php @@ -27,15 +27,15 @@ protected function defineOptions() { */ protected function valueForm(&$form, FormStateInterface $form_state) { if (!$form_state->get('exposed')) { - $form['value']['type'] = array( + $form['value']['type'] = [ '#type' => 'radios', '#title' => $this->t('Value type'), - '#options' => array( + '#options' => [ 'date' => $this->t('A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred.'), - 'offset' => $this->t('An offset from the current time such as "@example1" or "@example2"', array('@example1' => '+1 day', '@example2' => '-2 hours -30 minutes')), - ), + 'offset' => $this->t('An offset from the current time such as "@example1" or "@example2"', ['@example1' => '+1 day', '@example2' => '-2 hours -30 minutes']), + ], '#default_value' => !empty($this->value['type']) ? $this->value['type'] : 'date', - ); + ]; } parent::valueForm($form, $form_state); } @@ -43,12 +43,12 @@ protected function valueForm(&$form, FormStateInterface $form_state) { public function validateOptionsForm(&$form, FormStateInterface $form_state) { parent::validateOptionsForm($form, $form_state); - if (!empty($this->options['exposed']) && $form_state->isValueEmpty(array('options', 'expose', 'required'))) { + if (!empty($this->options['exposed']) && $form_state->isValueEmpty(['options', 'expose', 'required'])) { // Who cares what the value is if it's exposed and non-required. return; } - $this->validateValidTime($form['value'], $form_state, $form_state->getValue(array('options', 'operator')), $form_state->getValue(array('options', 'value'))); + $this->validateValidTime($form['value'], $form_state, $form_state->getValue(['options', 'operator']), $form_state->getValue(['options', 'value'])); } public function validateExposed(&$form, FormStateInterface $form_state) { @@ -122,9 +122,22 @@ public function acceptExposedInput($input) { } // Store this because it will get overwritten. - $type = $this->value['type']; + $type = NULL; + if ($this->isAGroup()) { + if (is_array($this->group_info)) { + $type = $this->group_info['type']; + } + } + else { + $type = $this->value['type']; + } $rc = parent::acceptExposedInput($input); + // Restore what got overwritten by the parent. + if (!is_null($type)) { + $this->value['type'] = $type; + } + // Don't filter if value(s) are empty. $operators = $this->operators(); if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) { @@ -145,8 +158,6 @@ public function acceptExposedInput($input) { } } - // restore what got overwritten by the parent. - $this->value['type'] = $type; return $rc; } @@ -155,8 +166,10 @@ protected function opBetween($field) { $b = intval(strtotime($this->value['max'], 0)); if ($this->value['type'] == 'offset') { - $a = '***CURRENT_TIME***' . sprintf('%+d', $a); // keep sign - $b = '***CURRENT_TIME***' . sprintf('%+d', $b); // keep sign + // Keep sign. + $a = '***CURRENT_TIME***' . sprintf('%+d', $a); + // Keep sign. + $b = '***CURRENT_TIME***' . sprintf('%+d', $b); } // This is safe because we are manually scrubbing the values. // It is necessary to do it this way because $a and $b are formulas when using an offset. @@ -167,7 +180,8 @@ protected function opBetween($field) { protected function opSimple($field) { $value = intval(strtotime($this->value['value'], 0)); if (!empty($this->value['type']) && $this->value['type'] == 'offset') { - $value = '***CURRENT_TIME***' . sprintf('%+d', $value); // keep sign + // Keep sign. + $value = '***CURRENT_TIME***' . sprintf('%+d', $value); } // This is safe because we are manually scrubbing the value. // It is necessary to do it this way because $value is a formula when using an offset. diff --git a/core/modules/views/src/Plugin/views/filter/Equality.php b/core/modules/views/src/Plugin/views/filter/Equality.php index 748c60d6..e1d2aeb1 100644 --- a/core/modules/views/src/Plugin/views/filter/Equality.php +++ b/core/modules/views/src/Plugin/views/filter/Equality.php @@ -20,22 +20,22 @@ class Equality extends FilterPluginBase { * Provide simple equality operator */ public function operatorOptions() { - return array( + return [ '=' => $this->t('Is equal to'), '!=' => $this->t('Is not equal to'), - ); + ]; } /** * Provide a simple textfield for equality */ protected function valueForm(&$form, FormStateInterface $form_state) { - $form['value'] = array( + $form['value'] = [ '#type' => 'textfield', '#title' => $this->t('Value'), '#size' => 30, '#default_value' => $this->value, - ); + ]; if ($exposed = $form_state->get('exposed')) { $identifier = $this->options['expose']['identifier']; diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php index 5c2a8d8c..fc1d7e17 100644 --- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php @@ -116,26 +116,28 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o protected function defineOptions() { $options = parent::defineOptions(); - $options['operator'] = array('default' => '='); - $options['value'] = array('default' => ''); - $options['group'] = array('default' => '1'); - $options['exposed'] = array('default' => FALSE); - $options['expose'] = array( - 'contains' => array( - 'operator_id' => array('default' => FALSE), - 'label' => array('default' => ''), - 'description' => array('default' => ''), - 'use_operator' => array('default' => FALSE), - 'operator' => array('default' => ''), - 'identifier' => array('default' => ''), - 'required' => array('default' => FALSE), - 'remember' => array('default' => FALSE), - 'multiple' => array('default' => FALSE), - 'remember_roles' => array('default' => array( - RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID, - )), - ), - ); + $options['operator'] = ['default' => '=']; + $options['value'] = ['default' => '']; + $options['group'] = ['default' => '1']; + $options['exposed'] = ['default' => FALSE]; + $options['expose'] = [ + 'contains' => [ + 'operator_id' => ['default' => FALSE], + 'label' => ['default' => ''], + 'description' => ['default' => ''], + 'use_operator' => ['default' => FALSE], + 'operator' => ['default' => ''], + 'identifier' => ['default' => ''], + 'required' => ['default' => FALSE], + 'remember' => ['default' => FALSE], + 'multiple' => ['default' => FALSE], + 'remember_roles' => [ + 'default' => [ + RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID, + ], + ], + ], + ]; // A group is a combination of a filter, an operator and a value // operating like a single filter. @@ -145,21 +147,21 @@ protected function defineOptions() { // an identifier and other settings like the widget and the label. // This settings are saved in another array to allow users to switch // between a normal filter and a group of filters with a single click. - $options['is_grouped'] = array('default' => FALSE); - $options['group_info'] = array( - 'contains' => array( - 'label' => array('default' => ''), - 'description' => array('default' => ''), - 'identifier' => array('default' => ''), - 'optional' => array('default' => TRUE), - 'widget' => array('default' => 'select'), - 'multiple' => array('default' => FALSE), - 'remember' => array('default' => 0), - 'default_group' => array('default' => 'All'), - 'default_group_multiple' => array('default' => array()), - 'group_items' => array('default' => array()), - ), - ); + $options['is_grouped'] = ['default' => FALSE]; + $options['group_info'] = [ + 'contains' => [ + 'label' => ['default' => ''], + 'description' => ['default' => ''], + 'identifier' => ['default' => ''], + 'optional' => ['default' => TRUE], + 'widget' => ['default' => 'select'], + 'multiple' => ['default' => FALSE], + 'remember' => ['default' => 0], + 'default_group' => ['default' => 'All'], + 'default_group_multiple' => ['default' => []], + 'group_items' => ['default' => []], + ], + ]; return $options; } @@ -174,7 +176,9 @@ public function adminSummary() { /** * Determine if a filter can be exposed. */ - public function canExpose() { return TRUE; } + public function canExpose() { + return TRUE; + } /** * Determine if a filter can be converted into a group. @@ -205,19 +209,19 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if ($this->canBuildGroup()) { $this->showBuildGroupButton($form, $form_state); } - $form['clear_markup_start'] = array( + $form['clear_markup_start'] = [ '#markup' => '
          ', - ); + ]; if ($this->isAGroup()) { if ($this->canBuildGroup()) { - $form['clear_markup_start'] = array( + $form['clear_markup_start'] = [ '#markup' => '
          ', - ); + ]; // Render the build group form. $this->showBuildGroupForm($form, $form_state); - $form['clear_markup_end'] = array( + $form['clear_markup_end'] = [ '#markup' => '
          ', - ); + ]; } } else { @@ -225,9 +229,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $this->showOperatorForm($form, $form_state); // Add the subform from valueForm(). $this->showValueForm($form, $form_state); - $form['clear_markup_end'] = array( + $form['clear_markup_end'] = [ '#markup' => '
          ', - ); + ]; if ($this->canExpose()) { // Add the subform from buildExposeForm(). $this->showExposeForm($form, $form_state); @@ -289,12 +293,12 @@ public function showOperatorForm(&$form, FormStateInterface $form_state) { protected function operatorForm(&$form, FormStateInterface $form_state) { $options = $this->operatorOptions(); if (!empty($options)) { - $form['operator'] = array( + $form['operator'] = [ '#type' => count($options) < 10 ? 'radios' : 'select', '#title' => $this->t('Operator'), '#default_value' => $this->operator, '#options' => $options, - ); + ]; } } @@ -302,18 +306,20 @@ protected function operatorForm(&$form, FormStateInterface $form_state) { * Provide a list of options for the default operator form. * Should be overridden by classes that don't override operatorForm */ - public function operatorOptions() { return array(); } + public function operatorOptions() { + return []; + } /** * Validate the operator form. */ - protected function operatorValidate($form, FormStateInterface $form_state) { } + protected function operatorValidate($form, FormStateInterface $form_state) {} /** * Perform any necessary changes to the form values prior to storage. * There is no need for this function to actually store the data. */ - public function operatorSubmit($form, FormStateInterface $form_state) { } + public function operatorSubmit($form, FormStateInterface $form_state) {} /** * Shortcut to display the value form. @@ -335,19 +341,19 @@ protected function showValueForm(&$form, FormStateInterface $form_state) { * @see buildOptionsForm() */ protected function valueForm(&$form, FormStateInterface $form_state) { - $form['value'] = array(); + $form['value'] = []; } /** * Validate the options form. */ - protected function valueValidate($form, FormStateInterface $form_state) { } + protected function valueValidate($form, FormStateInterface $form_state) {} /** * Perform any necessary changes to the form values prior to storage. * There is no need for this function to actually store the data. */ - protected function valueSubmit($form, FormStateInterface $form_state) { } + protected function valueSubmit($form, FormStateInterface $form_state) {} /** * Shortcut to display the exposed options form. @@ -377,47 +383,47 @@ public function showBuildGroupForm(&$form, FormStateInterface $form_state) { */ protected function showBuildGroupButton(&$form, FormStateInterface $form_state) { - $form['group_button'] = array( + $form['group_button'] = [ '#prefix' => '
          ', '#suffix' => '
          ', // Should always come after the description and the relationship. '#weight' => -190, - ); + ]; $grouped_description = $this->t('Grouped filters allow a choice between predefined operator|value pairs.'); - $form['group_button']['radios'] = array( - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('js-only')), - ); - $form['group_button']['radios']['radios'] = array( + $form['group_button']['radios'] = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['js-only']], + ]; + $form['group_button']['radios']['radios'] = [ '#title' => $this->t('Filter type to expose'), '#description' => $grouped_description, '#type' => 'radios', - '#options' => array( + '#options' => [ $this->t('Single filter'), $this->t('Grouped filters'), - ), - ); + ], + ]; if (empty($this->options['is_grouped'])) { - $form['group_button']['markup'] = array( + $form['group_button']['markup'] = [ '#markup' => '
          ' . $grouped_description . '
          ', - ); - $form['group_button']['button'] = array( - '#limit_validation_errors' => array(), + ]; + $form['group_button']['button'] = [ + '#limit_validation_errors' => [], '#type' => 'submit', '#value' => $this->t('Grouped filters'), - '#submit' => array(array($this, 'buildGroupForm')), - ); + '#submit' => [[$this, 'buildGroupForm']], + ]; $form['group_button']['radios']['radios']['#default_value'] = 0; } else { - $form['group_button']['button'] = array( - '#limit_validation_errors' => array(), + $form['group_button']['button'] = [ + '#limit_validation_errors' => [], '#type' => 'submit', '#value' => $this->t('Single filter'), - '#submit' => array(array($this, 'buildGroupForm')), - ); + '#submit' => [[$this, 'buildGroupForm']], + ]; $form['group_button']['radios']['radios']['#default_value'] = 1; } } @@ -453,47 +459,47 @@ public function buildGroupForm($form, FormStateInterface $form_state) { * Shortcut to display the expose/hide button. */ public function showExposeButton(&$form, FormStateInterface $form_state) { - $form['expose_button'] = array( + $form['expose_button'] = [ '#prefix' => '
          ', '#suffix' => '
          ', // Should always come after the description and the relationship. '#weight' => -200, - ); + ]; // Add a checkbox for JS users, which will have behavior attached to it // so it can replace the button. - $form['expose_button']['checkbox'] = array( - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('js-only')), - ); - $form['expose_button']['checkbox']['checkbox'] = array( + $form['expose_button']['checkbox'] = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['js-only']], + ]; + $form['expose_button']['checkbox']['checkbox'] = [ '#title' => $this->t('Expose this filter to visitors, to allow them to change it'), '#type' => 'checkbox', - ); + ]; // Then add the button itself. if (empty($this->options['exposed'])) { - $form['expose_button']['markup'] = array( + $form['expose_button']['markup'] = [ '#markup' => '
          ' . $this->t('This filter is not exposed. Expose it to allow the users to change it.') . '
          ', - ); - $form['expose_button']['button'] = array( - '#limit_validation_errors' => array(), + ]; + $form['expose_button']['button'] = [ + '#limit_validation_errors' => [], '#type' => 'submit', '#value' => $this->t('Expose filter'), - '#submit' => array(array($this, 'displayExposedForm')), - ); + '#submit' => [[$this, 'displayExposedForm']], + ]; $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0; } else { - $form['expose_button']['markup'] = array( + $form['expose_button']['markup'] = [ '#markup' => '
          ' . $this->t('This filter is exposed. If you hide it, users will not be able to change it.') . '
          ', - ); - $form['expose_button']['button'] = array( - '#limit_validation_errors' => array(), + ]; + $form['expose_button']['button'] = [ + '#limit_validation_errors' => [], '#type' => 'submit', '#value' => $this->t('Hide filter'), - '#submit' => array(array($this, 'displayExposedForm')), - ); + '#submit' => [[$this, 'displayExposedForm']], + ]; $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1; } } @@ -509,35 +515,35 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { // prior to rendering. That's why the preRender for it needs to run first, // so that when the next preRender (the one for fieldsets) runs, it gets // the flattened data. - array_unshift($form['#pre_render'], array(get_class($this), 'preRenderFlattenData')); + array_unshift($form['#pre_render'], [get_class($this), 'preRenderFlattenData']); $form['expose']['#flatten'] = TRUE; if (empty($this->always_required)) { - $form['expose']['required'] = array( + $form['expose']['required'] = [ '#type' => 'checkbox', '#title' => $this->t('Required'), '#default_value' => $this->options['expose']['required'], - ); + ]; } else { - $form['expose']['required'] = array( + $form['expose']['required'] = [ '#type' => 'value', '#value' => TRUE, - ); + ]; } - $form['expose']['label'] = array( + $form['expose']['label'] = [ '#type' => 'textfield', '#default_value' => $this->options['expose']['label'], '#title' => $this->t('Label'), '#size' => 40, - ); + ]; - $form['expose']['description'] = array( + $form['expose']['description'] = [ '#type' => 'textfield', '#default_value' => $this->options['expose']['description'], '#title' => $this->t('Description'), '#size' => 60, - ); + ]; if (!empty($form['operator']['#type'])) { // Increase the width of the left (operator) column. @@ -546,75 +552,75 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { $form['value']['#prefix'] = '
          '; $form['value']['#suffix'] = '
          '; - $form['expose']['use_operator'] = array( + $form['expose']['use_operator'] = [ '#type' => 'checkbox', '#title' => $this->t('Expose operator'), '#description' => $this->t('Allow the user to choose the operator.'), '#default_value' => !empty($this->options['expose']['use_operator']), - ); - $form['expose']['operator_id'] = array( + ]; + $form['expose']['operator_id'] = [ '#type' => 'textfield', '#default_value' => $this->options['expose']['operator_id'], '#title' => $this->t('Operator identifier'), '#size' => 40, '#description' => $this->t('This will appear in the URL after the ? to identify this operator.'), - '#states' => array( - 'visible' => array( - ':input[name="options[expose][use_operator]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[expose][use_operator]"]' => ['checked' => TRUE], + ], + ], + ]; } else { - $form['expose']['operator_id'] = array( + $form['expose']['operator_id'] = [ '#type' => 'value', '#value' => '', - ); + ]; } if (empty($this->alwaysMultiple)) { - $form['expose']['multiple'] = array( + $form['expose']['multiple'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple selections'), '#description' => $this->t('Enable to allow users to select multiple items.'), '#default_value' => $this->options['expose']['multiple'], - ); + ]; } - $form['expose']['remember'] = array( + $form['expose']['remember'] = [ '#type' => 'checkbox', '#title' => $this->t('Remember the last selection'), '#description' => $this->t('Enable to remember the last selection made by the user.'), '#default_value' => $this->options['expose']['remember'], - ); + ]; $role_options = array_map('\Drupal\Component\Utility\Html::escape', user_role_names()); - $form['expose']['remember_roles'] = array( + $form['expose']['remember_roles'] = [ '#type' => 'checkboxes', '#title' => $this->t('User roles'), '#description' => $this->t('Remember exposed selection only for the selected user role(s). If you select no roles, the exposed data will never be stored.'), '#default_value' => $this->options['expose']['remember_roles'], '#options' => $role_options, - '#states' => array( - 'invisible' => array( - ':input[name="options[expose][remember]"]' => array('checked' => FALSE), - ), - ), - ); - - $form['expose']['identifier'] = array( + '#states' => [ + 'invisible' => [ + ':input[name="options[expose][remember]"]' => ['checked' => FALSE], + ], + ], + ]; + + $form['expose']['identifier'] = [ '#type' => 'textfield', '#default_value' => $this->options['expose']['identifier'], '#title' => $this->t('Filter identifier'), '#size' => 40, '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), - ); + ]; } /** * Validate the options form. */ public function validateExposeForm($form, FormStateInterface $form_state) { - $identifier = $form_state->getValue(array('options', 'expose', 'identifier')); + $identifier = $form_state->getValue(['options', 'expose', 'identifier']); $this->validateIdentifier($identifier, $form_state, $form['expose']['identifier']); } @@ -654,12 +660,12 @@ protected function hasValidGroupedValue(array $group) { * Validate the build group options form. */ protected function buildGroupValidate($form, FormStateInterface $form_state) { - if (!$form_state->isValueEmpty(array('options', 'group_info'))) { - $identifier = $form_state->getValue(array('options', 'group_info', 'identifier')); + if (!$form_state->isValueEmpty(['options', 'group_info'])) { + $identifier = $form_state->getValue(['options', 'group_info', 'identifier']); $this->validateIdentifier($identifier, $form_state, $form['group_info']['identifier']); } - if ($group_items = $form_state->getValue(array('options', 'group_info', 'group_items'))) { + if ($group_items = $form_state->getValue(['options', 'group_info', 'group_items'])) { foreach ($group_items as $id => $group) { if (empty($group['remove'])) { $has_valid_value = $this->hasValidGroupedValue($group); @@ -694,7 +700,7 @@ protected function buildGroupValidate($form, FormStateInterface $form_state) { * * @return string */ - protected function validateIdentifier($identifier, FormStateInterface $form_state = NULL, &$form_group = array()) { + protected function validateIdentifier($identifier, FormStateInterface $form_state = NULL, &$form_group = []) { $error = ''; if (empty($identifier)) { $error = $this->t('The identifier is required if the filter is exposed.'); @@ -720,9 +726,9 @@ protected function validateIdentifier($identifier, FormStateInterface $form_stat * Save new group items, re-enumerates and remove groups marked to delete. */ protected function buildGroupSubmit($form, FormStateInterface $form_state) { - $groups = array(); - $group_items = $form_state->getValue(array('options', 'group_info', 'group_items')); - uasort($group_items, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); + $groups = []; + $group_items = $form_state->getValue(['options', 'group_info', 'group_items']); + uasort($group_items, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']); // Filter out removed items. // Start from 1 to avoid problems with #default_value in the widget. @@ -735,26 +741,26 @@ protected function buildGroupSubmit($form, FormStateInterface $form_state) { unset($group['weight']); $groups[$new_id] = $group; - if ($form_state->getValue(array('options', 'group_info', 'default_group')) == $id) { + if ($form_state->getValue(['options', 'group_info', 'default_group']) == $id) { $new_default = $new_id; } } $new_id++; } if ($new_default != 'All') { - $form_state->setValue(array('options', 'group_info', 'default_group'), $new_default); + $form_state->setValue(['options', 'group_info', 'default_group'], $new_default); } - $filter_default_multiple = $form_state->getValue(array('options', 'group_info', 'default_group_multiple')); - $form_state->setValue(array('options', 'group_info', 'default_group_multiple'), array_filter($filter_default_multiple)); + $filter_default_multiple = $form_state->getValue(['options', 'group_info', 'default_group_multiple']); + $form_state->setValue(['options', 'group_info', 'default_group_multiple'], array_filter($filter_default_multiple)); - $form_state->setValue(array('options', 'group_info', 'group_items'), $groups); + $form_state->setValue(['options', 'group_info', 'group_items'], $groups); } /** * Provide default options for exposed filters. */ public function defaultExposeOptions() { - $this->options['expose'] = array( + $this->options['expose'] = [ 'use_operator' => FALSE, 'operator' => $this->options['id'] . '_op', 'identifier' => $this->options['id'], @@ -763,14 +769,14 @@ public function defaultExposeOptions() { 'remember' => FALSE, 'multiple' => FALSE, 'required' => FALSE, - ); + ]; } /** * Provide default options for exposed filters. */ protected function buildGroupOptions() { - $this->options['group_info'] = array( + $this->options['group_info'] = [ 'label' => $this->definition['title'], 'description' => NULL, 'identifier' => $this->options['id'], @@ -779,9 +785,9 @@ protected function buildGroupOptions() { 'multiple' => FALSE, 'remember' => FALSE, 'default_group' => 'All', - 'default_group_multiple' => array(), - 'group_items' => array(), - ); + 'default_group_multiple' => [], + 'group_items' => [], + ]; } /** @@ -790,7 +796,7 @@ protected function buildGroupOptions() { */ public function groupForm(&$form, FormStateInterface $form_state) { if (!empty($this->options['group_info']['optional']) && !$this->multipleExposedInput()) { - $groups = array('All' => $this->t('- Any -')); + $groups = ['All' => $this->t('- Any -')]; } foreach ($this->options['group_info']['group_items'] as $id => $group) { if (!empty($group['title'])) { @@ -801,12 +807,12 @@ public function groupForm(&$form, FormStateInterface $form_state) { if (count($groups)) { $value = $this->options['group_info']['identifier']; - $form[$value] = array( + $form[$value] = [ '#title' => $this->options['group_info']['label'], '#type' => $this->options['group_info']['widget'], '#default_value' => $this->group_info, '#options' => $groups, - ); + ]; if (!empty($this->options['group_info']['multiple'])) { if (count($groups) < 5) { $form[$value]['#type'] = 'checkboxes'; @@ -890,7 +896,7 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form // prior to rendering. That's why the preRender for it needs to run first, // so that when the next preRender (the one for fieldsets) runs, it gets // the flattened data. - array_unshift($form['#pre_render'], array(get_class($this), 'preRenderFlattenData')); + array_unshift($form['#pre_render'], [get_class($this), 'preRenderFlattenData']); $form['group_info']['#flatten'] = TRUE; if (!empty($this->options['group_info']['identifier'])) { @@ -899,53 +905,53 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form else { $identifier = 'group_' . $this->options['expose']['identifier']; } - $form['group_info']['identifier'] = array( + $form['group_info']['identifier'] = [ '#type' => 'textfield', '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), - ); - $form['group_info']['label'] = array( + ]; + $form['group_info']['label'] = [ '#type' => 'textfield', '#default_value' => $this->options['group_info']['label'], '#title' => $this->t('Label'), '#size' => 40, - ); - $form['group_info']['description'] = array( + ]; + $form['group_info']['description'] = [ '#type' => 'textfield', '#default_value' => $this->options['group_info']['description'], '#title' => $this->t('Description'), '#size' => 60, - ); - $form['group_info']['optional'] = array( + ]; + $form['group_info']['optional'] = [ '#type' => 'checkbox', '#title' => $this->t('Optional'), '#description' => $this->t('This exposed filter is optional and will have added options to allow it not to be set.'), '#default_value' => $this->options['group_info']['optional'], - ); - $form['group_info']['multiple'] = array( + ]; + $form['group_info']['multiple'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple selections'), '#description' => $this->t('Enable to allow users to select multiple items.'), '#default_value' => $this->options['group_info']['multiple'], - ); - $form['group_info']['widget'] = array( + ]; + $form['group_info']['widget'] = [ '#type' => 'radios', '#default_value' => $this->options['group_info']['widget'], '#title' => $this->t('Widget type'), - '#options' => array( + '#options' => [ 'radios' => $this->t('Radios'), 'select' => $this->t('Select'), - ), + ], '#description' => $this->t('Select which kind of widget will be used to render the group of filters'), - ); - $form['group_info']['remember'] = array( + ]; + $form['group_info']['remember'] = [ '#type' => 'checkbox', '#title' => $this->t('Remember'), '#description' => $this->t('Remember the last setting the user gave this filter.'), '#default_value' => $this->options['group_info']['remember'], - ); + ]; if (!empty($this->options['group_info']['identifier'])) { $identifier = $this->options['group_info']['identifier']; @@ -953,53 +959,55 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form else { $identifier = 'group_' . $this->options['expose']['identifier']; } - $form['group_info']['identifier'] = array( + $form['group_info']['identifier'] = [ '#type' => 'textfield', '#default_value' => $identifier, '#title' => $this->t('Filter identifier'), '#size' => 40, '#description' => $this->t('This will appear in the URL after the ? to identify this filter. Cannot be blank. Only letters, digits and the dot ("."), hyphen ("-"), underscore ("_"), and tilde ("~") characters are allowed.'), - ); - $form['group_info']['label'] = array( + ]; + $form['group_info']['label'] = [ '#type' => 'textfield', '#default_value' => $this->options['group_info']['label'], '#title' => $this->t('Label'), '#size' => 40, - ); - $form['group_info']['optional'] = array( + ]; + $form['group_info']['optional'] = [ '#type' => 'checkbox', '#title' => $this->t('Optional'), '#description' => $this->t('This exposed filter is optional and will have added options to allow it not to be set.'), '#default_value' => $this->options['group_info']['optional'], - ); - $form['group_info']['widget'] = array( + ]; + $form['group_info']['widget'] = [ '#type' => 'radios', '#default_value' => $this->options['group_info']['widget'], '#title' => $this->t('Widget type'), - '#options' => array( + '#options' => [ 'radios' => $this->t('Radios'), 'select' => $this->t('Select'), - ), + ], '#description' => $this->t('Select which kind of widget will be used to render the group of filters'), - ); - $form['group_info']['remember'] = array( + ]; + $form['group_info']['remember'] = [ '#type' => 'checkbox', '#title' => $this->t('Remember'), '#description' => $this->t('Remember the last setting the user gave this filter.'), '#default_value' => $this->options['group_info']['remember'], - ); + ]; - $groups = array('All' => $this->t('- Any -')); // The string '- Any -' will not be rendered see @theme_views_ui_build_group_filter_form + // The string '- Any -' will not be rendered. + // @see theme_views_ui_build_group_filter_form() + $groups = ['All' => $this->t('- Any -')]; // Provide 3 options to start when we are in a new group. if (count($this->options['group_info']['group_items']) == 0) { - $this->options['group_info']['group_items'] = array_fill(1, 3, array()); + $this->options['group_info']['group_items'] = array_fill(1, 3, []); } // After the general settings, comes a table with all the existent groups. $default_weight = 0; foreach ($this->options['group_info']['group_items'] as $item_id => $item) { - if (!$form_state->isValueEmpty(array('options', 'group_info', 'group_items', $item_id, 'remove'))) { + if (!$form_state->isValueEmpty(['options', 'group_info', 'group_items', $item_id, 'remove'])) { continue; } // Each rows contains three widgets: @@ -1009,8 +1017,8 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form // In each row, we have to display the operator form and the value from // $row acts as a fake form to render each widget in a row. - $row = array(); - $groups[$item_id] = $this->t('Grouping @id', array('@id' => $item_id)); + $row = []; + $groups[$item_id] = $this->t('Grouping @id', ['@id' => $item_id]); $this->operatorForm($row, $form_state); // Force the operator form to be a select box. Some handlers uses // radios and they occupy a lot of space in a table row. @@ -1028,17 +1036,20 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form $children = Element::children($row['value']); if (!empty($children)) { foreach ($children as $child) { - foreach ($row['value'][$child]['#states']['visible'] as $state) { - if (isset($state[':input[name="options[group_info][group_items][' . $item_id . '][operator]"]'])) { - $row['value'][$child]['#title'] = ''; + if (!empty($row['value'][$child]['#states']['visible'])) { + foreach ($row['value'][$child]['#states']['visible'] as $state) { + if (isset($state[':input[name="options[group_info][group_items][' . $item_id . '][operator]"]'])) { + $row['value'][$child]['#title'] = ''; - if (!empty($this->options['group_info']['group_items'][$item_id]['value'][$child])) { - $row['value'][$child]['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'][$child]; + // Exit this loop and process the next child element. + break; } - // Exit this loop and process the next child element. - break; } } + + if (!empty($this->options['group_info']['group_items'][$item_id]['value'][$child])) { + $row['value'][$child]['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'][$child]; + } } } else { @@ -1057,71 +1068,71 @@ protected function buildExposedFiltersGroupForm(&$form, FormStateInterface $form } // Per item group, we have a title that identifies it. - $form['group_info']['group_items'][$item_id] = array( - 'title' => array( + $form['group_info']['group_items'][$item_id] = [ + 'title' => [ '#title' => $this->t('Label'), '#title_display' => 'invisible', '#type' => 'textfield', '#size' => 20, '#default_value' => $default_title, - ), + ], 'operator' => $row['operator'], 'value' => $row['value'], // No title is given here, since this input is never displayed. It is // only triggered by JavaScript. - 'remove' => array( + 'remove' => [ '#type' => 'checkbox', '#id' => 'views-removed-' . $item_id, - '#attributes' => array('class' => array('views-remove-checkbox')), + '#attributes' => ['class' => ['views-remove-checkbox']], '#default_value' => 0, - ), - 'weight' => array( + ], + 'weight' => [ '#title' => $this->t('Weight'), '#title_display' => 'invisible', '#type' => 'weight', - '#delta' => 10, + '#delta' => count($this->options['group_info']['group_items']), '#default_value' => $default_weight++, - '#attributes' => array('class' => array('weight')), - ), - ); + '#attributes' => ['class' => ['weight']], + ], + ]; } // From all groups, let chose which is the default. - $form['group_info']['default_group'] = array( + $form['group_info']['default_group'] = [ '#type' => 'radios', '#options' => $groups, '#default_value' => $this->options['group_info']['default_group'], '#required' => TRUE, - '#attributes' => array( - 'class' => array('default-radios'), - ) - ); + '#attributes' => [ + 'class' => ['default-radios'], + ] + ]; // From all groups, let chose which is the default. - $form['group_info']['default_group_multiple'] = array( + $form['group_info']['default_group_multiple'] = [ '#type' => 'checkboxes', '#options' => $groups, '#default_value' => $this->options['group_info']['default_group_multiple'], - '#attributes' => array( - 'class' => array('default-checkboxes'), - ) - ); + '#attributes' => [ + 'class' => ['default-checkboxes'], + ] + ]; - $form['group_info']['add_group'] = array( + $form['group_info']['add_group'] = [ '#prefix' => '
          ', '#suffix' => '
          ', '#type' => 'submit', '#value' => $this->t('Add another item'), - '#submit' => array(array($this, 'addGroupForm')), - ); + '#submit' => [[$this, 'addGroupForm']], + ]; - $js = array(); - $js['tableDrag']['views-filter-groups']['weight'][0] = array( + $js = []; + $js['tableDrag']['views-filter-groups']['weight'][0] = [ 'target' => 'weight', 'source' => NULL, 'relationship' => 'sibling', 'action' => 'order', 'hidden' => TRUE, 'limit' => 0, - ); + ]; $js_settings = $form_state->get('js_settings'); if ($js_settings && is_array($js)) { $js_settings = array_merge($js_settings, $js); @@ -1139,7 +1150,7 @@ public function addGroupForm($form, FormStateInterface $form_state) { $item = &$this->options; // Add a new row. - $item['group_info']['group_items'][] = array(); + $item['group_info']['group_items'][] = []; $view = $form_state->get('view'); $display_id = $form_state->get('display_id'); @@ -1186,7 +1197,7 @@ protected function exposedTranslate(&$form, $type) { } if ($type == 'value' && empty($this->always_required) && empty($this->options['expose']['required']) && $form['#type'] == 'select' && empty($form['#multiple'])) { - $form['#options'] = array('All' => $this->t('- Any -')) + $form['#options']; + $form['#options'] = ['All' => $this->t('- Any -')] + $form['#options']; $form['#default_value'] = 'All'; } @@ -1196,7 +1207,6 @@ protected function exposedTranslate(&$form, $type) { } - /** * Sanitizes the HTML select element's options. * @@ -1240,19 +1250,19 @@ public function exposedInfo() { } if ($this->isAGroup()) { - return array( + return [ 'value' => $this->options['group_info']['identifier'], 'label' => $this->options['group_info']['label'], 'description' => $this->options['group_info']['description'], - ); + ]; } - return array( + return [ 'operator' => $this->options['expose']['operator_id'], 'value' => $this->options['expose']['identifier'], 'label' => $this->options['expose']['label'], 'description' => $this->options['expose']['description'], - ); + ]; } /** @@ -1286,7 +1296,7 @@ public function convertExposedInput(&$input, $selected_group_id = NULL) { $input[$this->options['expose']['operator']] = $this->options['group_info']['group_items'][$selected_group]['operator']; // Value can be optional, For example for 'empty' and 'not empty' filters. - if (isset($this->options['group_info']['group_items'][$selected_group]['value']) && $this->options['group_info']['group_items'][$selected_group]['value'] != '') { + if (isset($this->options['group_info']['group_items'][$selected_group]['value']) && $this->options['group_info']['group_items'][$selected_group]['value'] !== '') { $input[$this->options['expose']['identifier']] = $this->options['group_info']['group_items'][$selected_group]['value']; } $this->options['expose']['use_operator'] = TRUE; @@ -1309,7 +1319,7 @@ public function groupMultipleExposedInput(&$input) { if (!empty($input[$this->options['group_info']['identifier']])) { return array_filter($input[$this->options['group_info']['identifier']]); } - return array(); + return []; } /** @@ -1350,7 +1360,7 @@ public function storeGroupInput($input, $status) { if ($status !== FALSE) { if (!isset($_SESSION['views'][$this->view->storage->id()][$display_id])) { - $_SESSION['views'][$this->view->storage->id()][$display_id] = array(); + $_SESSION['views'][$this->view->storage->id()][$display_id] = []; } $session = &$_SESSION['views'][$this->view->storage->id()][$display_id]; @@ -1388,7 +1398,7 @@ public function acceptExposedInput($input) { } if ($this->operator != 'empty' && $this->operator != 'not empty') { - if ($value == 'All' || $value === array()) { + if ($value == 'All' || $value === []) { return FALSE; } @@ -1406,7 +1416,7 @@ public function acceptExposedInput($input) { if (isset($value)) { $this->value = $value; if (empty($this->alwaysMultiple) && empty($this->options['expose']['multiple']) && !is_array($value)) { - $this->value = array($value); + $this->value = [$value]; } } else { @@ -1428,7 +1438,7 @@ public function storeExposedInput($input, $status) { // Check if we store exposed value for current user. $user = \Drupal::currentUser(); - $allowed_rids = empty($this->options['expose']['remember_roles']) ? array() : array_filter($this->options['expose']['remember_roles']); + $allowed_rids = empty($this->options['expose']['remember_roles']) ? [] : array_filter($this->options['expose']['remember_roles']); $intersect_rids = array_intersect(array_keys($allowed_rids), $user->getRoles()); if (empty($intersect_rids)) { return; @@ -1456,7 +1466,7 @@ public function storeExposedInput($input, $status) { if ($status) { if (!isset($_SESSION['views'][$this->view->storage->id()][$display_id])) { - $_SESSION['views'][$this->view->storage->id()][$display_id] = array(); + $_SESSION['views'][$this->view->storage->id()][$display_id] = []; } $session = &$_SESSION['views'][$this->view->storage->id()][$display_id]; diff --git a/core/modules/views/src/Plugin/views/filter/GroupByNumeric.php b/core/modules/views/src/Plugin/views/filter/GroupByNumeric.php index 4f1baa18..577b2dfd 100644 --- a/core/modules/views/src/Plugin/views/filter/GroupByNumeric.php +++ b/core/modules/views/src/Plugin/views/filter/GroupByNumeric.php @@ -24,17 +24,17 @@ protected function opBetween($field) { $placeholder_min = $this->placeholder(); $placeholder_max = $this->placeholder(); if ($this->operator == 'between') { - $this->query->addHavingExpression($this->options['group'], "$field >= $placeholder_min", array($placeholder_min => $this->value['min'])); - $this->query->addHavingExpression($this->options['group'], "$field <= $placeholder_max", array($placeholder_max => $this->value['max'])); + $this->query->addHavingExpression($this->options['group'], "$field >= $placeholder_min", [$placeholder_min => $this->value['min']]); + $this->query->addHavingExpression($this->options['group'], "$field <= $placeholder_max", [$placeholder_max => $this->value['max']]); } else { - $this->query->addHavingExpression($this->options['group'], "$field < $placeholder_min OR $field > $placeholder_max", array($placeholder_min => $this->value['min'], $placeholder_max => $this->value['max'])); + $this->query->addHavingExpression($this->options['group'], "$field < $placeholder_min OR $field > $placeholder_max", [$placeholder_min => $this->value['min'], $placeholder_max => $this->value['max']]); } } protected function opSimple($field) { $placeholder = $this->placeholder(); - $this->query->addHavingExpression($this->options['group'], "$field $this->operator $placeholder", array($placeholder => $this->value['value'])); + $this->query->addHavingExpression($this->options['group'], "$field $this->operator $placeholder", [$placeholder => $this->value['value']]); } protected function opEmpty($field) { @@ -52,6 +52,8 @@ public function adminLabel($short = FALSE) { return $this->getField(parent::adminLabel($short)); } - public function canGroup() { return FALSE; } + public function canGroup() { + return FALSE; + } } diff --git a/core/modules/views/src/Plugin/views/filter/InOperator.php b/core/modules/views/src/Plugin/views/filter/InOperator.php index ff4186f4..cff42b96 100644 --- a/core/modules/views/src/Plugin/views/filter/InOperator.php +++ b/core/modules/views/src/Plugin/views/filter/InOperator.php @@ -71,7 +71,7 @@ public function getValueOptions() { } } else { - $this->valueOptions = array(t('Yes'), $this->t('No')); + $this->valueOptions = [t('Yes'), $this->t('No')]; } return $this->valueOptions; @@ -84,20 +84,21 @@ public function defaultExposeOptions() { public function buildExposeForm(&$form, FormStateInterface $form_state) { parent::buildExposeForm($form, $form_state); - $form['expose']['reduce'] = array( + $form['expose']['reduce'] = [ '#type' => 'checkbox', '#title' => $this->t('Limit list to selected items'), '#description' => $this->t('If checked, the only items presented to the user will be the ones selected here.'), - '#default_value' => !empty($this->options['expose']['reduce']), // safety - ); + // Safety. + '#default_value' => !empty($this->options['expose']['reduce']), + ]; } protected function defineOptions() { $options = parent::defineOptions(); $options['operator']['default'] = 'in'; - $options['value']['default'] = array(); - $options['expose']['contains']['reduce'] = array('default' => FALSE); + $options['value']['default'] = []; + $options['expose']['contains']['reduce'] = ['default' => FALSE]; return $options; } @@ -107,39 +108,39 @@ protected function defineOptions() { * to add or remove functionality by overriding this function and * adding/removing items from this array. */ - function operators() { - $operators = array( - 'in' => array( + public function operators() { + $operators = [ + 'in' => [ 'title' => $this->t('Is one of'), 'short' => $this->t('in'), 'short_single' => $this->t('='), 'method' => 'opSimple', 'values' => 1, - ), - 'not in' => array( + ], + 'not in' => [ 'title' => $this->t('Is not one of'), 'short' => $this->t('not in'), 'short_single' => $this->t('<>'), 'method' => 'opSimple', 'values' => 1, - ), - ); + ], + ]; // if the definition allows for the empty operator, add it. if (!empty($this->definition['allow empty'])) { - $operators += array( - 'empty' => array( + $operators += [ + 'empty' => [ 'title' => $this->t('Is empty (NULL)'), 'method' => 'opEmpty', 'short' => $this->t('empty'), 'values' => 0, - ), - 'not empty' => array( + ], + 'not empty' => [ 'title' => $this->t('Is not empty (NOT NULL)'), 'method' => 'opEmpty', 'short' => $this->t('not empty'), 'values' => 0, - ), - ); + ], + ]; } return $operators; @@ -149,7 +150,7 @@ function operators() { * Build strings from the operators() for 'select' options */ public function operatorOptions($which = 'title') { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { $options[$id] = $info[$which]; } @@ -158,7 +159,7 @@ public function operatorOptions($which = 'title') { } protected function operatorValues($values = 1) { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { if (isset($info['values']) && $info['values'] == $values) { $options[] = $id; @@ -169,13 +170,13 @@ protected function operatorValues($values = 1) { } protected function valueForm(&$form, FormStateInterface $form_state) { - $form['value'] = array(); - $options = array(); + $form['value'] = []; + $options = []; $exposed = $form_state->get('exposed'); if (!$exposed) { // Add a select all option to the value form. - $options = array('all' => $this->t('Select all')); + $options = ['all' => $this->t('Select all')]; } $this->getValueOptions(); @@ -201,7 +202,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) { $options = $this->reduceValueOptions(); if (!empty($this->options['expose']['multiple']) && empty($this->options['expose']['required'])) { - $default_value = array(); + $default_value = []; } } @@ -221,7 +222,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } if ($which == 'all' || $which == 'value') { - $form['value'] = array( + $form['value'] = [ '#type' => $this->valueFormType, '#title' => $this->valueTitle, '#options' => $options, @@ -229,7 +230,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) { // These are only valid for 'select' type, but do no harm to checkboxes. '#multiple' => TRUE, '#size' => count($options) > 8 ? 8 : count($options), - ); + ]; $user_input = $form_state->getUserInput(); if ($exposed && !isset($user_input[$identifier])) { $user_input[$identifier] = $default_value; @@ -243,9 +244,9 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } // Setup #states for all operators with one value. foreach ($this->operatorValues(1) as $operator) { - $form['value']['#states']['visible'][] = array( - $source => array('value' => $operator), - ); + $form['value']['#states']['visible'][] = [ + $source => ['value' => $operator], + ]; } } } @@ -262,7 +263,7 @@ public function reduceValueOptions($input = NULL) { // Because options may be an array of strings, or an array of mixed arrays // and strings (optgroups) or an array of objects, we have to // step through and handle each one individually. - $options = array(); + $options = []; foreach ($input as $id => $option) { if (is_array($option)) { $options[$id] = $this->reduceValueOptions($option); @@ -313,7 +314,7 @@ protected function valueSubmit($form, FormStateInterface $form_state) { // *only* a list of checkboxes that were set, and we can use that // instead. - $form_state->setValue(array('options', 'value'), $form['value']['#value']); + $form_state->setValue(['options', 'value'], $form['value']['#value']); } public function adminSummary() { @@ -417,11 +418,11 @@ public function validate() { // If the operator is an operator which doesn't require a value, there is // no need for additional validation. if (in_array($this->operator, $this->operatorValues(0))) { - return array(); + return []; } if (!in_array($this->operator, $this->operatorValues(1))) { - $errors[] = $this->t('The operator is invalid on filter: @filter.', array('@filter' => $this->adminLabel(TRUE))); + $errors[] = $this->t('The operator is invalid on filter: @filter.', ['@filter' => $this->adminLabel(TRUE)]); } if (is_array($this->value)) { if (!isset($this->valueOptions)) { @@ -444,11 +445,11 @@ public function validate() { } // Choose different kind of output for 0, a single and multiple values. if (count($this->value) == 0) { - $errors[] = $this->t('No valid values found on filter: @filter.', array('@filter' => $this->adminLabel(TRUE))); + $errors[] = $this->t('No valid values found on filter: @filter.', ['@filter' => $this->adminLabel(TRUE)]); } } elseif (!empty($this->value) && ($this->operator == 'in' || $this->operator == 'not in')) { - $errors[] = $this->t('The value @value is not an array for @operator on filter: @filter', array('@value' => var_export($this->value), '@operator' => $this->operator, '@filter' => $this->adminLabel(TRUE))); + $errors[] = $this->t('The value @value is not an array for @operator on filter: @filter', ['@value' => var_export($this->value), '@operator' => $this->operator, '@filter' => $this->adminLabel(TRUE)]); } return $errors; } diff --git a/core/modules/views/src/Plugin/views/filter/LatestRevision.php b/core/modules/views/src/Plugin/views/filter/LatestRevision.php new file mode 100644 index 00000000..7930a7fb --- /dev/null +++ b/core/modules/views/src/Plugin/views/filter/LatestRevision.php @@ -0,0 +1,113 @@ +entityTypeManager = $entity_type_manager; + $this->joinHandler = $join_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, $plugin_id, $plugin_definition, + $container->get('entity_type.manager'), + $container->get('plugin.manager.views.join') + ); + } + + /** + * {@inheritdoc} + */ + public function adminSummary() { + } + + /** + * {@inheritdoc} + */ + protected function operatorForm(&$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function canExpose() { + return FALSE; + } + + /** + * {@inheritdoc} + */ + public function query() { + /** @var \Drupal\views\Plugin\views\query\Sql $query */ + $query = $this->query; + $query_base_table = $this->relationship ?: $this->view->storage->get('base_table'); + + $entity_type = $this->entityTypeManager->getDefinition($this->getEntityType()); + $keys = $entity_type->getKeys(); + + $definition = [ + 'table' => $query_base_table, + 'type' => 'LEFT', + 'field' => $keys['id'], + 'left_table' => $query_base_table, + 'left_field' => $keys['id'], + 'extra' => [ + ['left_field' => $keys['revision'], 'field' => $keys['revision'], 'operator' => '>'], + ], + ]; + + $join = $this->joinHandler->createInstance('standard', $definition); + + $join_table_alias = $query->addTable($query_base_table, $this->relationship, $join); + $query->addWhere($this->options['group'], "$join_table_alias.{$keys['id']}", NULL, 'IS NULL'); + } + +} diff --git a/core/modules/views/src/Plugin/views/filter/ManyToOne.php b/core/modules/views/src/Plugin/views/filter/ManyToOne.php index 7fa1fbc4..86eb1f33 100644 --- a/core/modules/views/src/Plugin/views/filter/ManyToOne.php +++ b/core/modules/views/src/Plugin/views/filter/ManyToOne.php @@ -41,7 +41,7 @@ protected function defineOptions() { $options = parent::defineOptions(); $options['operator']['default'] = 'or'; - $options['value']['default'] = array(); + $options['value']['default'] = []; if (isset($this->helper)) { $this->helper->defineOptions($options); @@ -54,49 +54,49 @@ protected function defineOptions() { return $options; } - function operators() { - $operators = array( - 'or' => array( + public function operators() { + $operators = [ + 'or' => [ 'title' => $this->t('Is one of'), 'short' => $this->t('or'), 'short_single' => $this->t('='), 'method' => 'opHelper', 'values' => 1, 'ensure_my_table' => 'helper', - ), - 'and' => array( + ], + 'and' => [ 'title' => $this->t('Is all of'), 'short' => $this->t('and'), 'short_single' => $this->t('='), 'method' => 'opHelper', 'values' => 1, 'ensure_my_table' => 'helper', - ), - 'not' => array( + ], + 'not' => [ 'title' => $this->t('Is none of'), 'short' => $this->t('not'), 'short_single' => $this->t('<>'), 'method' => 'opHelper', 'values' => 1, 'ensure_my_table' => 'helper', - ), - ); + ], + ]; // if the definition allows for the empty operator, add it. if (!empty($this->definition['allow empty'])) { - $operators += array( - 'empty' => array( + $operators += [ + 'empty' => [ 'title' => $this->t('Is empty (NULL)'), 'method' => 'opEmpty', 'short' => $this->t('empty'), 'values' => 0, - ), - 'not empty' => array( + ], + 'not empty' => [ 'title' => $this->t('Is not empty (NOT NULL)'), 'method' => 'opEmpty', 'short' => $this->t('not empty'), 'values' => 0, - ), - ); + ], + ]; } return $operators; @@ -129,6 +129,9 @@ protected function opHelper() { if (empty($this->value)) { return; } + // Form API returns unchecked options in the form of option_id => 0. This + // breaks the generated query for "is all of" filters so we remove them. + $this->value = array_filter($this->value, 'static::arrayFilterZero'); $this->helper->addFilter(); } diff --git a/core/modules/views/src/Plugin/views/filter/NumericFilter.php b/core/modules/views/src/Plugin/views/filter/NumericFilter.php index e7720dfa..7f687a14 100644 --- a/core/modules/views/src/Plugin/views/filter/NumericFilter.php +++ b/core/modules/views/src/Plugin/views/filter/NumericFilter.php @@ -18,91 +18,91 @@ class NumericFilter extends FilterPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['value'] = array( - 'contains' => array( - 'min' => array('default' => ''), - 'max' => array('default' => ''), - 'value' => array('default' => ''), - ), - ); + $options['value'] = [ + 'contains' => [ + 'min' => ['default' => ''], + 'max' => ['default' => ''], + 'value' => ['default' => ''], + ], + ]; return $options; } - function operators() { - $operators = array( - '<' => array( + public function operators() { + $operators = [ + '<' => [ 'title' => $this->t('Is less than'), 'method' => 'opSimple', 'short' => $this->t('<'), 'values' => 1, - ), - '<=' => array( + ], + '<=' => [ 'title' => $this->t('Is less than or equal to'), 'method' => 'opSimple', 'short' => $this->t('<='), 'values' => 1, - ), - '=' => array( + ], + '=' => [ 'title' => $this->t('Is equal to'), 'method' => 'opSimple', 'short' => $this->t('='), 'values' => 1, - ), - '!=' => array( + ], + '!=' => [ 'title' => $this->t('Is not equal to'), 'method' => 'opSimple', 'short' => $this->t('!='), 'values' => 1, - ), - '>=' => array( + ], + '>=' => [ 'title' => $this->t('Is greater than or equal to'), 'method' => 'opSimple', 'short' => $this->t('>='), 'values' => 1, - ), - '>' => array( + ], + '>' => [ 'title' => $this->t('Is greater than'), 'method' => 'opSimple', 'short' => $this->t('>'), 'values' => 1, - ), - 'between' => array( + ], + 'between' => [ 'title' => $this->t('Is between'), 'method' => 'opBetween', 'short' => $this->t('between'), 'values' => 2, - ), - 'not between' => array( + ], + 'not between' => [ 'title' => $this->t('Is not between'), 'method' => 'opBetween', 'short' => $this->t('not between'), 'values' => 2, - ), - 'regular_expression' => array( + ], + 'regular_expression' => [ 'title' => $this->t('Regular expression'), 'short' => $this->t('regex'), - 'method' => 'op_regex', + 'method' => 'opRegex', 'values' => 1, - ), - ); + ], + ]; // if the definition allows for the empty operator, add it. if (!empty($this->definition['allow empty'])) { - $operators += array( - 'empty' => array( + $operators += [ + 'empty' => [ 'title' => $this->t('Is empty (NULL)'), 'method' => 'opEmpty', 'short' => $this->t('empty'), 'values' => 0, - ), - 'not empty' => array( + ], + 'not empty' => [ 'title' => $this->t('Is not empty (NOT NULL)'), 'method' => 'opEmpty', 'short' => $this->t('not empty'), 'values' => 0, - ), - ); + ], + ]; } return $operators; @@ -112,7 +112,7 @@ function operators() { * Provide a list of all the numeric operators */ public function operatorOptions($which = 'title') { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { $options[$id] = $info[$which]; } @@ -121,7 +121,7 @@ public function operatorOptions($which = 'title') { } protected function operatorValues($values = 1) { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { if ($info['values'] == $values) { $options[] = $id; @@ -159,17 +159,17 @@ protected function valueForm(&$form, FormStateInterface $form_state) { $user_input = $form_state->getUserInput(); if ($which == 'all') { - $form['value']['value'] = array( + $form['value']['value'] = [ '#type' => 'textfield', '#title' => !$exposed ? $this->t('Value') : '', '#size' => 30, '#default_value' => $this->value['value'], - ); + ]; // Setup #states for all operators with one value. foreach ($this->operatorValues(1) as $operator) { - $form['value']['value']['#states']['visible'][] = array( - $source => array('value' => $operator), - ); + $form['value']['value']['#states']['visible'][] = [ + $source => ['value' => $operator], + ]; } if ($exposed && !isset($user_input[$identifier]['value'])) { $user_input[$identifier]['value'] = $this->value['value']; @@ -179,12 +179,12 @@ protected function valueForm(&$form, FormStateInterface $form_state) { elseif ($which == 'value') { // When exposed we drop the value-value and just do value if // the operator is locked. - $form['value'] = array( + $form['value'] = [ '#type' => 'textfield', '#title' => !$exposed ? $this->t('Value') : '', '#size' => 30, '#default_value' => $this->value['value'], - ); + ]; if ($exposed && !isset($user_input[$identifier])) { $user_input[$identifier] = $this->value['value']; $form_state->setUserInput($user_input); @@ -192,26 +192,26 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } if ($which == 'all' || $which == 'minmax') { - $form['value']['min'] = array( + $form['value']['min'] = [ '#type' => 'textfield', '#title' => !$exposed ? $this->t('Min') : $this->exposedInfo()['label'], '#size' => 30, '#default_value' => $this->value['min'], '#description' => !$exposed ? '' : $this->exposedInfo()['description'] - ); - $form['value']['max'] = array( + ]; + $form['value']['max'] = [ '#type' => 'textfield', '#title' => !$exposed ? $this->t('And max') : $this->t('And'), '#size' => 30, '#default_value' => $this->value['max'], - ); + ]; if ($which == 'all') { - $states = array(); + $states = []; // Setup #states for all operators with two values. foreach ($this->operatorValues(2) as $operator) { - $states['#states']['visible'][] = array( - $source => array('value' => $operator), - ); + $states['#states']['visible'][] = [ + $source => ['value' => $operator], + ]; } $form['value']['min'] += $states; $form['value']['max'] += $states; @@ -225,10 +225,10 @@ protected function valueForm(&$form, FormStateInterface $form_state) { if (!isset($form['value'])) { // Ensure there is something in the 'value'. - $form['value'] = array( + $form['value'] = [ '#type' => 'value', '#value' => NULL - ); + ]; } } } @@ -245,10 +245,10 @@ public function query() { protected function opBetween($field) { if ($this->operator == 'between') { - $this->query->addWhere($this->options['group'], $field, array($this->value['min'], $this->value['max']), 'BETWEEN'); + $this->query->addWhere($this->options['group'], $field, [$this->value['min'], $this->value['max']], 'BETWEEN'); } else { - $this->query->addWhere($this->options['group'], $field, array($this->value['min'], $this->value['max']), 'NOT BETWEEN'); + $this->query->addWhere($this->options['group'], $field, [$this->value['min'], $this->value['max']], 'NOT BETWEEN'); } } @@ -274,7 +274,7 @@ protected function opEmpty($field) { * The expression pointing to the queries field, for example "foo.bar". */ protected function opRegex($field) { - $this->query->addWhere($this->options['group'], $field, $this->value, 'REGEXP'); + $this->query->addWhere($this->options['group'], $field, $this->value['value'], 'REGEXP'); } public function adminSummary() { @@ -288,7 +288,7 @@ public function adminSummary() { $options = $this->operatorOptions('short'); $output = $options[$this->operator]; if (in_array($this->operator, $this->operatorValues(2))) { - $output .= ' ' . $this->t('@min and @max', array('@min' => $this->value['min'], '@max' => $this->value['max'])); + $output .= ' ' . $this->t('@min and @max', ['@min' => $this->value['min'], '@max' => $this->value['max']]); } elseif (in_array($this->operator, $this->operatorValues(1))) { $output .= ' ' . $this->value['value']; @@ -309,9 +309,9 @@ public function acceptExposedInput($input) { if (!empty($this->options['expose']['identifier'])) { $value = &$input[$this->options['expose']['identifier']]; if (!is_array($value)) { - $value = array( + $value = [ 'value' => $value, - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/filter/StringFilter.php b/core/modules/views/src/Plugin/views/filter/StringFilter.php index 618b5845..a9ab5a18 100644 --- a/core/modules/views/src/Plugin/views/filter/StringFilter.php +++ b/core/modules/views/src/Plugin/views/filter/StringFilter.php @@ -2,6 +2,7 @@ namespace Drupal\views\Plugin\views\filter; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Form\FormStateInterface; /** @@ -25,7 +26,7 @@ class StringFilter extends FilterPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['expose']['contains']['required'] = array('default' => FALSE); + $options['expose']['contains']['required'] = ['default' => FALSE]; return $options; } @@ -35,103 +36,103 @@ protected function defineOptions() { * to add or remove functionality by overriding this function and * adding/removing items from this array. */ - function operators() { - $operators = array( - '=' => array( + public function operators() { + $operators = [ + '=' => [ 'title' => $this->t('Is equal to'), 'short' => $this->t('='), 'method' => 'opEqual', 'values' => 1, - ), - '!=' => array( + ], + '!=' => [ 'title' => $this->t('Is not equal to'), 'short' => $this->t('!='), 'method' => 'opEqual', 'values' => 1, - ), - 'contains' => array( + ], + 'contains' => [ 'title' => $this->t('Contains'), 'short' => $this->t('contains'), 'method' => 'opContains', 'values' => 1, - ), - 'word' => array( + ], + 'word' => [ 'title' => $this->t('Contains any word'), 'short' => $this->t('has word'), 'method' => 'opContainsWord', 'values' => 1, - ), - 'allwords' => array( + ], + 'allwords' => [ 'title' => $this->t('Contains all words'), 'short' => $this->t('has all'), 'method' => 'opContainsWord', 'values' => 1, - ), - 'starts' => array( + ], + 'starts' => [ 'title' => $this->t('Starts with'), 'short' => $this->t('begins'), 'method' => 'opStartsWith', 'values' => 1, - ), - 'not_starts' => array( + ], + 'not_starts' => [ 'title' => $this->t('Does not start with'), 'short' => $this->t('not_begins'), 'method' => 'opNotStartsWith', 'values' => 1, - ), - 'ends' => array( + ], + 'ends' => [ 'title' => $this->t('Ends with'), 'short' => $this->t('ends'), 'method' => 'opEndsWith', 'values' => 1, - ), - 'not_ends' => array( + ], + 'not_ends' => [ 'title' => $this->t('Does not end with'), 'short' => $this->t('not_ends'), 'method' => 'opNotEndsWith', 'values' => 1, - ), - 'not' => array( + ], + 'not' => [ 'title' => $this->t('Does not contain'), 'short' => $this->t('!has'), 'method' => 'opNotLike', 'values' => 1, - ), - 'shorterthan' => array( + ], + 'shorterthan' => [ 'title' => $this->t('Length is shorter than'), 'short' => $this->t('shorter than'), 'method' => 'opShorterThan', 'values' => 1, - ), - 'longerthan' => array( + ], + 'longerthan' => [ 'title' => $this->t('Length is longer than'), 'short' => $this->t('longer than'), 'method' => 'opLongerThan', 'values' => 1, - ), - 'regular_expression' => array( + ], + 'regular_expression' => [ 'title' => $this->t('Regular expression'), 'short' => $this->t('regex'), 'method' => 'opRegex', 'values' => 1, - ), - ); + ], + ]; // if the definition allows for the empty operator, add it. if (!empty($this->definition['allow empty'])) { - $operators += array( - 'empty' => array( + $operators += [ + 'empty' => [ 'title' => $this->t('Is empty (NULL)'), 'method' => 'opEmpty', 'short' => $this->t('empty'), 'values' => 0, - ), - 'not empty' => array( + ], + 'not empty' => [ 'title' => $this->t('Is not empty (NOT NULL)'), 'method' => 'opEmpty', 'short' => $this->t('not empty'), 'values' => 0, - ), - ); + ], + ]; } return $operators; @@ -141,7 +142,7 @@ function operators() { * Build strings from the operators() for 'select' options */ public function operatorOptions($which = 'title') { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { $options[$id] = $info[$which]; } @@ -169,7 +170,7 @@ public function adminSummary() { } protected function operatorValues($values = 1) { - $options = array(); + $options = []; foreach ($this->operators() as $id => $info) { if (isset($info['values']) && $info['values'] == $values) { $options[] = $id; @@ -204,12 +205,12 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } if ($which == 'all' || $which == 'value') { - $form['value'] = array( + $form['value'] = [ '#type' => 'textfield', '#title' => $this->t('Value'), '#size' => 30, '#default_value' => $this->value, - ); + ]; $user_input = $form_state->getUserInput(); if ($exposed && !isset($user_input[$identifier])) { $user_input[$identifier] = $this->value; @@ -219,23 +220,23 @@ protected function valueForm(&$form, FormStateInterface $form_state) { if ($which == 'all') { // Setup #states for all operators with one value. foreach ($this->operatorValues(1) as $operator) { - $form['value']['#states']['visible'][] = array( - $source => array('value' => $operator), - ); + $form['value']['#states']['visible'][] = [ + $source => ['value' => $operator], + ]; } } } if (!isset($form['value'])) { // Ensure there is something in the 'value'. - $form['value'] = array( + $form['value'] = [ '#type' => 'value', '#value' => NULL - ); + ]; } } - function operator() { + public function operator() { return $this->operator == '=' ? 'LIKE' : 'NOT LIKE'; } @@ -265,7 +266,7 @@ protected function opContains($field) { } protected function opContainsWord($field) { - $where = $this->operator == 'word' ? db_or() : db_and(); + $where = $this->operator == 'word' ? new Condition('OR') : new Condition('AND'); // Don't filter on empty strings. if (empty($this->value)) { @@ -281,13 +282,13 @@ protected function opContainsWord($field) { $phrase = TRUE; } $words = trim($match[2], ',?!();:-'); - $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY); + $words = $phrase ? [$words] : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY); foreach ($words as $word) { $where->condition($field, '%' . db_like(trim($word, " ,!?")) . '%', 'LIKE'); } } - if (!$where) { + if ($where->count() === 0) { return; } @@ -320,14 +321,14 @@ protected function opShorterThan($field) { $placeholder = $this->placeholder(); // Type cast the argument to an integer because the SQLite database driver // has to do some specific alterations to the query base on that data type. - $this->query->addWhereExpression($this->options['group'], "LENGTH($field) < $placeholder", array($placeholder => (int) $this->value)); + $this->query->addWhereExpression($this->options['group'], "LENGTH($field) < $placeholder", [$placeholder => (int) $this->value]); } protected function opLongerThan($field) { $placeholder = $this->placeholder(); // Type cast the argument to an integer because the SQLite database driver // has to do some specific alterations to the query base on that data type. - $this->query->addWhereExpression($this->options['group'], "LENGTH($field) > $placeholder", array($placeholder => (int) $this->value)); + $this->query->addWhereExpression($this->options['group'], "LENGTH($field) > $placeholder", [$placeholder => (int) $this->value]); } /** diff --git a/core/modules/views/src/Plugin/views/join/FieldOrLanguageJoin.php b/core/modules/views/src/Plugin/views/join/FieldOrLanguageJoin.php new file mode 100644 index 00000000..44734d45 --- /dev/null +++ b/core/modules/views/src/Plugin/views/join/FieldOrLanguageJoin.php @@ -0,0 +1,106 @@ + 'field_or_language_join', + * 'table' => 'node__field_tags', + * 'left_field' => 'nid', + * 'field' => 'entity_id', + * 'extra' => [ + * [ + * 'field' => 'deleted', + * 'value' => 0, + * 'numeric' => TRUE, + * ], + * [ + * 'left_field' => 'langcode', + * 'field' => 'langcode', + * ], + * [ + * 'field' => 'bundle', + * 'value' => ['news', 'page'], + * ], + * ], + * ]; + * @endcode + * + * The resulting join condition for this example would be the following: + * + * @code + * ON node__field_tags.deleted = 0 + * AND ( + * node_field_data.langcode = node__field_tags.langcode + * OR node__field.tags.bundle IN ['news', 'page'] + * ) + * @endcode + * + * @see views_field_default_views_data() + * + * @ingroup views_join_handlers + * + * @ViewsJoin("field_or_language_join") + */ +class FieldOrLanguageJoin extends JoinPluginBase { + + /** + * {@inheritdoc} + */ + protected function joinAddExtra(&$arguments, &$condition, $table, SelectInterface $select_query, $left_table = NULL) { + if (empty($this->extra)) { + return; + } + + if (is_array($this->extra)) { + $extras = []; + foreach ($this->extra as $extra) { + $extras[] = $this->buildExtra($extra, $arguments, $table, $select_query, $left_table); + } + + // Remove and store the langcode OR bundle join condition extra. + $language_bundle_conditions = []; + foreach ($extras as $key => $extra) { + if (strpos($extra, '.langcode') !== FALSE || strpos($extra, '.bundle') !== FALSE) { + $language_bundle_conditions[] = $extra; + unset($extras[$key]); + } + } + + if (count($extras) > 1) { + $condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')'; + } + elseif ($extras) { + $condition .= ' AND ' . array_shift($extras); + } + + // Tack on the langcode OR bundle join condition extra. + if (!empty($language_bundle_conditions)) { + $condition .= ' AND (' . implode(' OR ', $language_bundle_conditions) . ')'; + } + } + elseif (is_string($this->extra)) { + $condition .= " AND ($this->extra)"; + } + } + +} diff --git a/core/modules/views/src/Plugin/views/join/JoinPluginBase.php b/core/modules/views/src/Plugin/views/join/JoinPluginBase.php index 37c1e064..ccf40f64 100644 --- a/core/modules/views/src/Plugin/views/join/JoinPluginBase.php +++ b/core/modules/views/src/Plugin/views/join/JoinPluginBase.php @@ -2,6 +2,7 @@ namespace Drupal\views\Plugin\views\join; +use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Plugin\PluginBase; /** @@ -191,7 +192,7 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface { * * @see \Drupal\views\Plugin\views\join\JoinPluginBase::initJoin() */ - public $configuration = array(); + public $configuration = []; /** * How all the extras will be combined. Either AND or OR. @@ -223,10 +224,10 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface { public function __construct(array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); // Merge in some default values. - $configuration += array( + $configuration += [ 'type' => 'LEFT', 'extra_operator' => 'AND' - ); + ]; $this->configuration = $configuration; if (!empty($configuration['table'])) { @@ -261,102 +262,137 @@ public function buildJoin($select_query, $table, $view_query) { } if ($this->leftTable) { - $left = $view_query->getTableInfo($this->leftTable); - $left_field = "$left[alias].$this->leftField"; + $left_table = $view_query->getTableInfo($this->leftTable); + $left_field = "$left_table[alias].$this->leftField"; } else { // This can be used if left_field is a formula or something. It should be used only *very* rarely. $left_field = $this->leftField; + $left_table = NULL; } $condition = "$left_field = $table[alias].$this->field"; - $arguments = array(); + $arguments = []; // Tack on the extra. if (isset($this->extra)) { - if (is_array($this->extra)) { - $extras = array(); - foreach ($this->extra as $info) { - // Do not require 'value' to be set; allow for field syntax instead. - $info += array( - 'value' => NULL, - ); - // Figure out the table name. Remember, only use aliases provided - // if at all possible. - $join_table = ''; - if (!array_key_exists('table', $info)) { - $join_table = $table['alias'] . '.'; - } - elseif (isset($info['table'])) { - // If we're aware of a table alias for this table, use the table - // alias instead of the table name. - if (isset($left) && $left['table'] == $info['table']) { - $join_table = $left['alias'] . '.'; - } - else { - $join_table = $info['table'] . '.'; - } - } + $this->joinAddExtra($arguments, $condition, $table, $select_query, $left_table); + } - // Convert a single-valued array of values to the single-value case, - // and transform from IN() notation to = notation - if (is_array($info['value']) && count($info['value']) == 1) { - $info['value'] = array_shift($info['value']); - } - if (is_array($info['value'])) { - // We use an SA-CORE-2014-005 conformant placeholder for our array - // of values. Also, note that the 'IN' operator is implicit. - // @see https://www.drupal.org/node/2401615. - $operator = !empty($info['operator']) ? $info['operator'] : 'IN'; - $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder() . '[]'; - $placeholder_sql = "( $placeholder )"; - } - else { - // With a single value, the '=' operator is implicit. - $operator = !empty($info['operator']) ? $info['operator'] : '='; - $placeholder = $placeholder_sql = ':views_join_condition_' . $select_query->nextPlaceholder(); - } - // Set 'field' as join table field if available or set 'left field' as - // join table field is not set. - if (isset($info['field'])) { - $join_table_field = "$join_table$info[field]"; - // Allow the value to be set either with the 'value' element or - // with 'left_field'. - if (isset($info['left_field'])) { - $placeholder_sql = "$left[alias].$info[left_field]"; - } - else { - $arguments[$placeholder] = $info['value']; - } - } - // Set 'left field' as join table field is not set. - else { - $join_table_field = "$left[alias].$info[left_field]"; - $arguments[$placeholder] = $info['value']; - } - // Render out the SQL fragment with parameters. - $extras[] = "$join_table_field $operator $placeholder_sql"; - } + $select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments); + } + /** + * Adds the extras to the join condition. + * + * @param array $arguments + * Array of query arguments. + * @param string $condition + * The condition to be built. + * @param array $table + * The right table. + * @param \Drupal\Core\Database\Query\SelectInterface $select_query + * The current select query being built. + * @param array $left_table + * The left table. + */ + protected function joinAddExtra(&$arguments, &$condition, $table, SelectInterface $select_query, $left_table = NULL) { + if (is_array($this->extra)) { + $extras = []; + foreach ($this->extra as $info) { + $extras[] = $this->buildExtra($info, $arguments, $table, $select_query, $left_table); + } - if ($extras) { - if (count($extras) == 1) { - $condition .= ' AND ' . array_shift($extras); - } - else { - $condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')'; - } + if ($extras) { + if (count($extras) == 1) { + $condition .= ' AND ' . array_shift($extras); } + else { + $condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')'; + } + } + } + elseif ($this->extra && is_string($this->extra)) { + $condition .= " AND ($this->extra)"; + } + } + + /** + * Builds a single extra condition. + * + * @param array $info + * The extra information. See JoinPluginBase::$extra for details. + * @param array $arguments + * Array of query arguments. + * @param array $table + * The right table. + * @param \Drupal\Core\Database\Query\SelectInterface $select_query + * The current select query being built. + * @param array $left + * The left table. + * + * @return string + * The extra condition + */ + protected function buildExtra($info, &$arguments, $table, SelectInterface $select_query, $left) { + // Do not require 'value' to be set; allow for field syntax instead. + $info += [ + 'value' => NULL, + ]; + // Figure out the table name. Remember, only use aliases provided + // if at all possible. + $join_table = ''; + if (!array_key_exists('table', $info)) { + $join_table = $table['alias'] . '.'; + } + elseif (isset($info['table'])) { + // If we're aware of a table alias for this table, use the table + // alias instead of the table name. + if (isset($left) && $left['table'] == $info['table']) { + $join_table = $left['alias'] . '.'; } - elseif ($this->extra && is_string($this->extra)) { - $condition .= " AND ($this->extra)"; + else { + $join_table = $info['table'] . '.'; } } - $select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments); + // Convert a single-valued array of values to the single-value case, + // and transform from IN() notation to = notation + if (is_array($info['value']) && count($info['value']) == 1) { + $info['value'] = array_shift($info['value']); + } + if (is_array($info['value'])) { + // We use an SA-CORE-2014-005 conformant placeholder for our array + // of values. Also, note that the 'IN' operator is implicit. + // @see https://www.drupal.org/node/2401615. + $operator = !empty($info['operator']) ? $info['operator'] : 'IN'; + $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder() . '[]'; + $placeholder_sql = "( $placeholder )"; + } + else { + // With a single value, the '=' operator is implicit. + $operator = !empty($info['operator']) ? $info['operator'] : '='; + $placeholder = $placeholder_sql = ':views_join_condition_' . $select_query->nextPlaceholder(); + } + // Set 'field' as join table field if available or set 'left field' as + // join table field is not set. + if (isset($info['field'])) { + $join_table_field = "$join_table$info[field]"; + // Allow the value to be set either with the 'value' element or + // with 'left_field'. + if (isset($info['left_field'])) { + $placeholder_sql = "$left[alias].$info[left_field]"; + } + else { + $arguments[$placeholder] = $info['value']; + } + } + // Set 'left field' as join table field is not set. + else { + $join_table_field = "$left[alias].$info[left_field]"; + $arguments[$placeholder] = $info['value']; + } + // Render out the SQL fragment with parameters. + return "$join_table_field $operator $placeholder_sql"; } } - -/** - * @} - */ diff --git a/core/modules/views/src/Plugin/views/join/Subquery.php b/core/modules/views/src/Plugin/views/join/Subquery.php index fa2e421b..f407ffce 100644 --- a/core/modules/views/src/Plugin/views/join/Subquery.php +++ b/core/modules/views/src/Plugin/views/join/Subquery.php @@ -48,14 +48,14 @@ public function buildJoin($select_query, $table, $view_query) { // Add our join condition, using a subquery on the left instead of a field. $condition = "($this->left_query) = $table[alias].$this->field"; - $arguments = array(); + $arguments = []; // Tack on the extra. // This is just copied verbatim from the parent class, which itself has a // bug: https://www.drupal.org/node/1118100. if (isset($this->extra)) { if (is_array($this->extra)) { - $extras = array(); + $extras = []; foreach ($this->extra as $info) { // Figure out the table name. Remember, only use aliases provided // if at all possible. diff --git a/core/modules/views/src/Plugin/views/pager/Full.php b/core/modules/views/src/Plugin/views/pager/Full.php index 76e64697..7d3adae6 100644 --- a/core/modules/views/src/Plugin/views/pager/Full.php +++ b/core/modules/views/src/Plugin/views/pager/Full.php @@ -27,10 +27,10 @@ protected function defineOptions() { $options = parent::defineOptions(); // Use the same default quantity that core uses by default. - $options['quantity'] = array('default' => 9); + $options['quantity'] = ['default' => 9]; - $options['tags']['contains']['first'] = array('default' => $this->t('« First')); - $options['tags']['contains']['last'] = array('default' => $this->t('Last »')); + $options['tags']['contains']['first'] = ['default' => $this->t('« First')]; + $options['tags']['contains']['last'] = ['default' => $this->t('Last »')]; return $options; } @@ -41,26 +41,26 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['quantity'] = array( + $form['quantity'] = [ '#type' => 'number', '#title' => $this->t('Number of pager links visible'), '#description' => $this->t('Specify the number of links to pages to display in the pager.'), '#default_value' => $this->options['quantity'], - ); + ]; - $form['tags']['first'] = array( + $form['tags']['first'] = [ '#type' => 'textfield', '#title' => $this->t('First page link text'), '#default_value' => $this->options['tags']['first'], '#weight' => -10, - ); + ]; - $form['tags']['last'] = array( + $form['tags']['last'] = [ '#type' => 'textfield', '#title' => $this->t('Last page link text'), '#default_value' => $this->options['tags']['last'], '#weight' => 10, - ); + ]; } /** @@ -68,9 +68,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function summaryTitle() { if (!empty($this->options['offset'])) { - return $this->formatPlural($this->options['items_per_page'], '@count item, skip @skip', 'Paged, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset'])); + return $this->formatPlural($this->options['items_per_page'], '@count item, skip @skip', 'Paged, @count items, skip @skip', ['@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']]); } - return $this->formatPlural($this->options['items_per_page'], '@count item', 'Paged, @count items', array('@count' => $this->options['items_per_page'])); + return $this->formatPlural($this->options['items_per_page'], '@count item', 'Paged, @count items', ['@count' => $this->options['items_per_page']]); } /** @@ -79,20 +79,20 @@ public function summaryTitle() { public function render($input) { // The 0, 1, 3, 4 indexes are correct. See the template_preprocess_pager() // documentation. - $tags = array( + $tags = [ 0 => $this->options['tags']['first'], 1 => $this->options['tags']['previous'], 3 => $this->options['tags']['next'], 4 => $this->options['tags']['last'], - ); - return array( + ]; + return [ '#theme' => $this->themeFunctions(), '#tags' => $tags, '#element' => $this->options['id'], '#parameters' => $input, '#quantity' => $this->options['quantity'], '#route_name' => !empty($this->view->live_preview) ? '' : '', - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/pager/Mini.php b/core/modules/views/src/Plugin/views/pager/Mini.php index c6520f4f..f92f193b 100644 --- a/core/modules/views/src/Plugin/views/pager/Mini.php +++ b/core/modules/views/src/Plugin/views/pager/Mini.php @@ -36,9 +36,9 @@ public function defineOptions() { */ public function summaryTitle() { if (!empty($this->options['offset'])) { - return $this->formatPlural($this->options['items_per_page'], 'Mini pager, @count item, skip @skip', 'Mini pager, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset'])); + return $this->formatPlural($this->options['items_per_page'], 'Mini pager, @count item, skip @skip', 'Mini pager, @count items, skip @skip', ['@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']]); } - return $this->formatPlural($this->options['items_per_page'], 'Mini pager, @count item', 'Mini pager, @count items', array('@count' => $this->options['items_per_page'])); + return $this->formatPlural($this->options['items_per_page'], 'Mini pager, @count item', 'Mini pager, @count items', ['@count' => $this->options['items_per_page']]); } /** @@ -89,17 +89,17 @@ public function postExecute(&$result) { */ public function render($input) { // The 1, 3 indexes are correct, see template_preprocess_pager(). - $tags = array( + $tags = [ 1 => $this->options['tags']['previous'], 3 => $this->options['tags']['next'], - ); - return array( + ]; + return [ '#theme' => $this->themeFunctions(), '#tags' => $tags, '#element' => $this->options['id'], '#parameters' => $input, '#route_name' => !empty($this->view->live_preview) ? '' : '', - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/pager/None.php b/core/modules/views/src/Plugin/views/pager/None.php index e5dcecde..ae2891a2 100644 --- a/core/modules/views/src/Plugin/views/pager/None.php +++ b/core/modules/views/src/Plugin/views/pager/None.php @@ -32,14 +32,14 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o public function summaryTitle() { if (!empty($this->options['offset'])) { - return $this->t('All items, skip @skip', array('@skip' => $this->options['offset'])); + return $this->t('All items, skip @skip', ['@skip' => $this->options['offset']]); } return $this->t('All items'); } protected function defineOptions() { $options = parent::defineOptions(); - $options['offset'] = array('default' => 0); + $options['offset'] = ['default' => 0]; return $options; } @@ -49,12 +49,12 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['offset'] = array( + $form['offset'] = [ '#type' => 'textfield', '#title' => $this->t('Offset (number of items to skip)'), '#description' => $this->t('For example, set this to 3 and the first 3 items will not be displayed.'), '#default_value' => $this->options['offset'], - ); + ]; } public function usePager() { diff --git a/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php b/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php index ec231a0b..52f4393d 100644 --- a/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php +++ b/core/modules/views/src/Plugin/views/pager/PagerPluginBase.php @@ -114,12 +114,12 @@ public function getPagerId() { /** * Provide the default form form for validating options */ - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} /** * Provide the default form form for submitting options */ - public function submitOptionsForm(&$form, FormStateInterface $form_state) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state) {} /** * Return a string to display as the clickable title for the @@ -156,6 +156,8 @@ public function executeCountQuery(&$count_query) { if (!empty($this->options['offset'])) { $this->total_items -= $this->options['offset']; } + // Prevent from being negative. + $this->total_items = max(0, $this->total_items); return $this->total_items; } @@ -173,22 +175,22 @@ public function updatePageInfo() { * * This is called during the build phase and can directly modify the query. */ - public function query() { } + public function query() {} /** * Perform any needed actions just prior to the query executing. */ - public function preExecute(&$query) { } + public function preExecute(&$query) {} /** * Perform any needed actions just after the query executing. */ - public function postExecute(&$result) { } + public function postExecute(&$result) {} /** * Perform any needed actions just before rendering. */ - public function preRender(&$result) { } + public function preRender(&$result) {} /** * Return the renderable array of the pager. @@ -199,7 +201,7 @@ public function preRender(&$result) { } * Any extra GET parameters that should be retained, such as exposed * input. */ - public function render($input) { } + public function render($input) {} /** * Determine if there are more records available. @@ -211,11 +213,11 @@ public function hasMoreRecords() { && $this->total_items > (intval($this->current_page) + 1) * $this->getItemsPerPage(); } - public function exposedFormAlter(&$form, FormStateInterface $form_state) { } + public function exposedFormAlter(&$form, FormStateInterface $form_state) {} - public function exposedFormValidate(&$form, FormStateInterface $form_state) { } + public function exposedFormValidate(&$form, FormStateInterface $form_state) {} - public function exposedFormSubmit(&$form, FormStateInterface $form_state, &$exclude) { } + public function exposedFormSubmit(&$form, FormStateInterface $form_state, &$exclude) {} public function usesExposed() { return FALSE; diff --git a/core/modules/views/src/Plugin/views/pager/Some.php b/core/modules/views/src/Plugin/views/pager/Some.php index ef7f65d8..59edaea0 100644 --- a/core/modules/views/src/Plugin/views/pager/Some.php +++ b/core/modules/views/src/Plugin/views/pager/Some.php @@ -20,15 +20,15 @@ class Some extends PagerPluginBase { public function summaryTitle() { if (!empty($this->options['offset'])) { - return $this->formatPlural($this->options['items_per_page'], '@count item, skip @skip', '@count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset'])); + return $this->formatPlural($this->options['items_per_page'], '@count item, skip @skip', '@count items, skip @skip', ['@count' => $this->options['items_per_page'], '@skip' => $this->options['offset']]); } - return $this->formatPlural($this->options['items_per_page'], '@count item', '@count items', array('@count' => $this->options['items_per_page'])); + return $this->formatPlural($this->options['items_per_page'], '@count item', '@count items', ['@count' => $this->options['items_per_page']]); } protected function defineOptions() { $options = parent::defineOptions(); - $options['items_per_page'] = array('default' => 10); - $options['offset'] = array('default' => 0); + $options['items_per_page'] = ['default' => 10]; + $options['offset'] = ['default' => 0]; return $options; } @@ -39,19 +39,19 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $pager_text = $this->displayHandler->getPagerText(); - $form['items_per_page'] = array( + $form['items_per_page'] = [ '#title' => $pager_text['items per page title'], '#type' => 'textfield', '#description' => $pager_text['items per page description'], '#default_value' => $this->options['items_per_page'], - ); + ]; - $form['offset'] = array( + $form['offset'] = [ '#type' => 'textfield', '#title' => $this->t('Offset (number of items to skip)'), '#description' => $this->t('For example, set this to 3 and the first 3 items will not be displayed.'), '#default_value' => $this->options['offset'], - ); + ]; } public function usePager() { diff --git a/core/modules/views/src/Plugin/views/pager/SqlBase.php b/core/modules/views/src/Plugin/views/pager/SqlBase.php index 0154762c..55e07dfa 100644 --- a/core/modules/views/src/Plugin/views/pager/SqlBase.php +++ b/core/modules/views/src/Plugin/views/pager/SqlBase.php @@ -13,28 +13,28 @@ abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInt protected function defineOptions() { $options = parent::defineOptions(); - $options['items_per_page'] = array('default' => 10); - $options['offset'] = array('default' => 0); - $options['id'] = array('default' => 0); - $options['total_pages'] = array('default' => ''); - $options['expose'] = array( - 'contains' => array( - 'items_per_page' => array('default' => FALSE), - 'items_per_page_label' => array('default' => $this->t('Items per page')), - 'items_per_page_options' => array('default' => '5, 10, 25, 50'), - 'items_per_page_options_all' => array('default' => FALSE), - 'items_per_page_options_all_label' => array('default' => $this->t('- All -')), - - 'offset' => array('default' => FALSE), - 'offset_label' => array('default' => $this->t('Offset')), - ), - ); - $options['tags'] = array( - 'contains' => array( - 'previous' => array('default' => $this->t('‹ Previous')), - 'next' => array('default' => $this->t('Next ›')), - ), - ); + $options['items_per_page'] = ['default' => 10]; + $options['offset'] = ['default' => 0]; + $options['id'] = ['default' => 0]; + $options['total_pages'] = ['default' => '']; + $options['expose'] = [ + 'contains' => [ + 'items_per_page' => ['default' => FALSE], + 'items_per_page_label' => ['default' => $this->t('Items per page')], + 'items_per_page_options' => ['default' => '5, 10, 25, 50'], + 'items_per_page_options_all' => ['default' => FALSE], + 'items_per_page_options_all_label' => ['default' => $this->t('- All -')], + + 'offset' => ['default' => FALSE], + 'offset_label' => ['default' => $this->t('Offset')], + ], + ]; + $options['tags'] = [ + 'contains' => [ + 'previous' => ['default' => $this->t('‹ Previous')], + 'next' => ['default' => $this->t('Next ›')], + ], + ]; return $options; } @@ -44,135 +44,135 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $pager_text = $this->displayHandler->getPagerText(); - $form['items_per_page'] = array( + $form['items_per_page'] = [ '#title' => $pager_text['items per page title'], '#type' => 'number', '#description' => $pager_text['items per page description'], '#default_value' => $this->options['items_per_page'], - ); + ]; - $form['offset'] = array( + $form['offset'] = [ '#type' => 'number', '#title' => $this->t('Offset (number of items to skip)'), '#description' => $this->t('For example, set this to 3 and the first 3 items will not be displayed.'), '#default_value' => $this->options['offset'], - ); + ]; - $form['id'] = array( + $form['id'] = [ '#type' => 'number', '#title' => $this->t('Pager ID'), '#description' => $this->t("Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."), '#default_value' => $this->options['id'], - ); + ]; - $form['total_pages'] = array( + $form['total_pages'] = [ '#type' => 'number', '#title' => $this->t('Number of pages'), '#description' => $this->t('Leave empty to show all pages.'), '#default_value' => $this->options['total_pages'], - ); + ]; - $form['tags'] = array( + $form['tags'] = [ '#type' => 'details', '#open' => TRUE, '#tree' => TRUE, '#title' => $this->t('Pager link labels'), '#input' => TRUE, - ); + ]; - $form['tags']['previous'] = array( + $form['tags']['previous'] = [ '#type' => 'textfield', '#title' => $this->t('Previous page link text'), '#default_value' => $this->options['tags']['previous'], - ); + ]; - $form['tags']['next'] = array( + $form['tags']['next'] = [ '#type' => 'textfield', '#title' => $this->t('Next page link text'), '#default_value' => $this->options['tags']['next'], - ); + ]; - $form['expose'] = array( + $form['expose'] = [ '#type' => 'details', '#open' => TRUE, '#tree' => TRUE, '#title' => $this->t('Exposed options'), '#input' => TRUE, '#description' => $this->t('Allow user to control selected display options for this view.'), - ); + ]; - $form['expose']['items_per_page'] = array( + $form['expose']['items_per_page'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow user to control the number of items displayed in this view'), '#default_value' => $this->options['expose']['items_per_page'], - ); + ]; - $form['expose']['items_per_page_label'] = array( + $form['expose']['items_per_page_label'] = [ '#type' => 'textfield', '#title' => $this->t('Items per page label'), '#required' => TRUE, '#default_value' => $this->options['expose']['items_per_page_label'], - '#states' => array( - 'invisible' => array( - 'input[name="pager_options[expose][items_per_page]"]' => array('checked' => FALSE), - ), - ), - ); - - $form['expose']['items_per_page_options'] = array( + '#states' => [ + 'invisible' => [ + 'input[name="pager_options[expose][items_per_page]"]' => ['checked' => FALSE], + ], + ], + ]; + + $form['expose']['items_per_page_options'] = [ '#type' => 'textfield', '#title' => $this->t('Exposed items per page options'), '#required' => TRUE, '#description' => $this->t('Set between which values the user can choose when determining the items per page. Separated by comma.'), '#default_value' => $this->options['expose']['items_per_page_options'], - '#states' => array( - 'invisible' => array( - 'input[name="pager_options[expose][items_per_page]"]' => array('checked' => FALSE), - ), - ), - ); + '#states' => [ + 'invisible' => [ + 'input[name="pager_options[expose][items_per_page]"]' => ['checked' => FALSE], + ], + ], + ]; - $form['expose']['items_per_page_options_all'] = array( + $form['expose']['items_per_page_options_all'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow user to display all items'), '#default_value' => $this->options['expose']['items_per_page_options_all'], - ); + ]; - $form['expose']['items_per_page_options_all_label'] = array( + $form['expose']['items_per_page_options_all_label'] = [ '#type' => 'textfield', '#title' => $this->t('All items label'), '#default_value' => $this->options['expose']['items_per_page_options_all_label'], - '#states' => array( - 'invisible' => array( - 'input[name="pager_options[expose][items_per_page_options_all]"]' => array('checked' => FALSE), - ), - ), - ); - - $form['expose']['offset'] = array( + '#states' => [ + 'invisible' => [ + 'input[name="pager_options[expose][items_per_page_options_all]"]' => ['checked' => FALSE], + ], + ], + ]; + + $form['expose']['offset'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow user to specify number of items skipped from beginning of this view.'), '#default_value' => $this->options['expose']['offset'], - ); + ]; - $form['expose']['offset_label'] = array( + $form['expose']['offset_label'] = [ '#type' => 'textfield', '#title' => $this->t('Offset label'), '#required' => TRUE, '#default_value' => $this->options['expose']['offset_label'], - '#states' => array( - 'invisible' => array( - 'input[name="pager_options[expose][offset]"]' => array('checked' => FALSE), - ), - ), - ); + '#states' => [ + 'invisible' => [ + 'input[name="pager_options[expose][offset]"]' => ['checked' => FALSE], + ], + ], + ]; } public function validateOptionsForm(&$form, FormStateInterface $form_state) { // Only accept integer values. $error = FALSE; - $exposed_options = $form_state->getValue(array('pager_options', 'expose', 'items_per_page_options')); + $exposed_options = $form_state->getValue(['pager_options', 'expose', 'items_per_page_options']); if (strpos($exposed_options, '.') !== FALSE) { $error = TRUE; } @@ -192,11 +192,11 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { } // Make sure that the items_per_page is part of the expose settings. - if (!$form_state->isValueEmpty(array('pager_options', 'expose', 'items_per_page')) && !$form_state->isValueEmpty(array('pager_options', 'items_per_page'))) { - $items_per_page = $form_state->getValue(array('pager_options', 'items_per_page')); + if (!$form_state->isValueEmpty(['pager_options', 'expose', 'items_per_page']) && !$form_state->isValueEmpty(['pager_options', 'items_per_page'])) { + $items_per_page = $form_state->getValue(['pager_options', 'items_per_page']); if (array_search($items_per_page, $options) === FALSE) { $form_state->setErrorByName('pager_options][expose][items_per_page_options', $this->t("The Exposed items per page field's options must include the value from the Items per page field (@items_per_page).", - array('@items_per_page' => $items_per_page)) + ['@items_per_page' => $items_per_page]) ); } } @@ -253,13 +253,13 @@ public function setCurrentPage($number = NULL) { global $pager_page_array; if (empty($pager_page_array)) { - $pager_page_array = array(); + $pager_page_array = []; } // Fill in missing values in the global page array, in case the global page // array hasn't been initialized before. $page = $this->view->getRequest()->query->get('page'); - $page = isset($page) ? explode(',', $page) : array(); + $page = isset($page) ? explode(',', $page) : []; for ($i = 0; $i <= $this->options['id'] || $i < count($pager_page_array); $i++) { $pager_page_array[$i] = empty($page[$i]) ? 0 : $page[$i]; @@ -331,7 +331,7 @@ protected function isOffsetExposed() { public function exposedFormAlter(&$form, FormStateInterface $form_state) { if ($this->itemsPerPageExposed()) { $options = explode(',', $this->options['expose']['items_per_page_options']); - $sanitized_options = array(); + $sanitized_options = []; if (is_array($options)) { foreach ($options as $option) { $sanitized_options[intval($option)] = intval($option); @@ -339,30 +339,30 @@ public function exposedFormAlter(&$form, FormStateInterface $form_state) { if (!empty($this->options['expose']['items_per_page_options_all']) && !empty($this->options['expose']['items_per_page_options_all_label'])) { $sanitized_options['All'] = $this->options['expose']['items_per_page_options_all_label']; } - $form['items_per_page'] = array( + $form['items_per_page'] = [ '#type' => 'select', '#title' => $this->options['expose']['items_per_page_label'], '#options' => $sanitized_options, '#default_value' => $this->getItemsPerPage(), - ); + ]; } } if ($this->isOffsetExposed()) { - $form['offset'] = array( + $form['offset'] = [ '#type' => 'textfield', '#size' => 10, '#maxlength' => 10, '#title' => $this->options['expose']['offset_label'], '#default_value' => $this->getOffset(), - ); + ]; } } public function exposedFormValidate(&$form, FormStateInterface $form_state) { if (!$form_state->isValueEmpty('offset') && trim($form_state->getValue('offset'))) { if (!is_numeric($form_state->getValue('offset')) || $form_state->getValue('offset') < 0) { - $form_state->setErrorByName('offset', $this->t('Offset must be an number greater or equal than 0.')); + $form_state->setErrorByName('offset', $this->t('Offset must be a number greater than or equal to 0.')); } } } diff --git a/core/modules/views/src/Plugin/views/query/QueryPluginBase.php b/core/modules/views/src/Plugin/views/query/QueryPluginBase.php index d4e1b23c..35453c11 100644 --- a/core/modules/views/src/Plugin/views/query/QueryPluginBase.php +++ b/core/modules/views/src/Plugin/views/query/QueryPluginBase.php @@ -54,7 +54,7 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency * @param $get_count * Provide a countquery if this is true, otherwise provide a normal query. */ - public function query($get_count = FALSE) { } + public function query($get_count = FALSE) {} /** * Let modules modify the query just prior to finalizing it. @@ -62,7 +62,7 @@ public function query($get_count = FALSE) { } * @param view $view * The view which is executed. */ - public function alter(ViewExecutable $view) { } + public function alter(ViewExecutable $view) {} /** * Builds the necessary info to execute the query. @@ -70,7 +70,7 @@ public function alter(ViewExecutable $view) { } * @param view $view * The view which is executed. */ - public function build(ViewExecutable $view) { } + public function build(ViewExecutable $view) {} /** * Executes the query and fills the associated view object with according @@ -85,7 +85,7 @@ public function build(ViewExecutable $view) { } * @param view $view * The view which is executed. */ - public function execute(ViewExecutable $view) { } + public function execute(ViewExecutable $view) {} /** * Add a signature to the query, if such a thing is feasible. @@ -96,18 +96,18 @@ public function execute(ViewExecutable $view) { } * @param view $view * The view which is executed. */ - public function addSignature(ViewExecutable $view) { } + public function addSignature(ViewExecutable $view) {} /** * Get aggregation info for group by queries. * * If NULL, aggregation is not allowed. */ - public function getAggregationInfo() { } + public function getAggregationInfo() {} - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} - public function submitOptionsForm(&$form, FormStateInterface $form_state) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state) {} public function summaryTitle() { return $this->t('Settings'); @@ -173,7 +173,7 @@ public function setWhereGroup($type = 'AND', $group = NULL, $where = 'where') { // Create an empty group if (empty($groups[$group])) { - $groups[$group] = array('conditions' => array(), 'args' => array()); + $groups[$group] = ['conditions' => [], 'args' => []]; } $groups[$group]['type'] = strtoupper($type); @@ -199,7 +199,7 @@ public function setGroupOperator($type = 'AND') { * * Query plugins that don't support entities can leave the method empty. */ - function loadEntities(&$results) {} + public function loadEntities(&$results) {} /** * Returns a Unix timestamp to database native timestamp expression. @@ -261,19 +261,19 @@ public function getDateFormat($field, $format, $string_date = FALSE) { */ public function getEntityTableInfo() { // Start with the base table. - $entity_tables = array(); + $entity_tables = []; $views_data = Views::viewsData(); $base_table = $this->view->storage->get('base_table'); $base_table_data = $views_data->get($base_table); if (isset($base_table_data['table']['entity type'])) { - $entity_tables[$base_table_data['table']['entity type']] = array( + $entity_tables[$base_table_data['table']['entity type']] = [ 'base' => $base_table, 'alias' => $base_table, 'relationship_id' => 'none', 'entity_type' => $base_table_data['table']['entity type'], 'revision' => $base_table_data['table']['entity revision'], - ); + ]; // Include the entity provider. if (!empty($base_table_data['table']['provider'])) { @@ -293,13 +293,13 @@ public function getEntityTableInfo() { continue; } - $entity_tables[$relationship_id . '__' . $relationship->tableAlias] = array( + $entity_tables[$relationship_id . '__' . $relationship->tableAlias] = [ 'base' => $relationship->definition['base'], 'relationship_id' => $relationship_id, 'alias' => $relationship->alias, 'entity_type' => $table_data['table']['entity type'], 'revision' => $table_data['table']['entity revision'], - ); + ]; // Include the entity provider. if (!empty($table_data['table']['provider'])) { diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php index cfe593cc..612b0fc6 100644 --- a/core/modules/views/src/Plugin/views/query/Sql.php +++ b/core/modules/views/src/Plugin/views/query/Sql.php @@ -5,6 +5,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\Cache; use Drupal\Core\Database\Database; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\display\DisplayPluginBase; @@ -32,31 +33,31 @@ class Sql extends QueryPluginBase { /** * A list of tables in the order they should be added, keyed by alias. */ - protected $tableQueue = array(); + protected $tableQueue = []; /** * Holds an array of tables and counts added so that we can create aliases */ - public $tables = array(); + public $tables = []; /** * Holds an array of relationships, which are aliases of the primary * table that represent different ways to join the same table in. */ - public $relationships = array(); + public $relationships = []; /** * An array of sections of the WHERE query. Each section is in itself * an array of pieces and a flag as to whether or not it should be AND * or OR. */ - public $where = array(); + public $where = []; /** * An array of sections of the HAVING query. Each section is in itself * an array of pieces and a flag as to whether or not it should be AND * or OR. */ - public $having = array(); + public $having = []; /** * The default operator to use when connecting the WHERE groups. May be * AND or OR. @@ -66,18 +67,18 @@ class Sql extends QueryPluginBase { /** * A simple array of order by clauses. */ - public $orderby = array(); + public $orderby = []; /** * A simple array of group by clauses. */ - public $groupby = array(); + public $groupby = []; /** * An array of fields. */ - public $fields = array(); + public $fields = []; /** * A flag as to whether or not to make the primary field distinct. @@ -94,12 +95,12 @@ class Sql extends QueryPluginBase { /** * An array mapping table aliases and field names to field aliases. */ - protected $fieldAliases = array(); + protected $fieldAliases = []; /** * Query tags which will be passed over to the dbtng query object. */ - public $tags = array(); + public $tags = []; /** * Is the view marked as not distinct. @@ -150,33 +151,33 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o $base_table = $this->view->storage->get('base_table'); $base_field = $this->view->storage->get('base_field'); - $this->relationships[$base_table] = array( + $this->relationships[$base_table] = [ 'link' => NULL, 'table' => $base_table, 'alias' => $base_table, 'base' => $base_table - ); + ]; // init the table queue with our primary table. - $this->tableQueue[$base_table] = array( + $this->tableQueue[$base_table] = [ 'alias' => $base_table, 'table' => $base_table, 'relationship' => $base_table, 'join' => NULL, - ); + ]; // init the tables with our primary table - $this->tables[$base_table][$base_table] = array( + $this->tables[$base_table][$base_table] = [ 'count' => 1, 'alias' => $base_table, - ); + ]; - $this->count_field = array( + $this->count_field = [ 'table' => $base_table, 'field' => $base_field, 'alias' => $base_field, 'count' => TRUE, - ); + ]; } /** @@ -198,31 +199,31 @@ public function setCountField($table, $field, $alias = NULL) { if (empty($alias)) { $alias = $table . '_' . $field; } - $this->count_field = array( + $this->count_field = [ 'table' => $table, 'field' => $field, 'alias' => $alias, 'count' => TRUE, - ); + ]; } protected function defineOptions() { $options = parent::defineOptions(); - $options['disable_sql_rewrite'] = array( + $options['disable_sql_rewrite'] = [ 'default' => FALSE, - ); - $options['distinct'] = array( + ]; + $options['distinct'] = [ 'default' => FALSE, - ); - $options['replica'] = array( + ]; + $options['replica'] = [ 'default' => FALSE, - ); - $options['query_comment'] = array( + ]; + $options['query_comment'] = [ 'default' => '', - ); - $options['query_tags'] = array( - 'default' => array(), - ); + ]; + $options['query_tags'] = [ + 'default' => [], + ]; return $options; } @@ -233,45 +234,45 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['disable_sql_rewrite'] = array( + $form['disable_sql_rewrite'] = [ '#title' => $this->t('Disable SQL rewriting'), '#description' => $this->t('Disabling SQL rewriting will omit all query tags, i. e. disable node access checks as well as override hook_query_alter() implementations in other modules.'), '#type' => 'checkbox', '#default_value' => !empty($this->options['disable_sql_rewrite']), '#suffix' => '
          ' . $this->t('WARNING: Disabling SQL rewriting means that node access security is disabled. This may allow users to see data they should not be able to see if your view is misconfigured. Use this option only if you understand and accept this security risk.') . '
          ', - ); - $form['distinct'] = array( + ]; + $form['distinct'] = [ '#type' => 'checkbox', '#title' => $this->t('Distinct'), '#description' => $this->t('This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution.'), '#default_value' => !empty($this->options['distinct']), - ); - $form['replica'] = array( + ]; + $form['replica'] = [ '#type' => 'checkbox', '#title' => $this->t('Use Secondary Server'), '#description' => $this->t('This will make the query attempt to connect to a replica server if available. If no replica server is defined or available, it will fall back to the default server.'), '#default_value' => !empty($this->options['replica']), - ); - $form['query_comment'] = array( + ]; + $form['query_comment'] = [ '#type' => 'textfield', '#title' => $this->t('Query Comment'), '#description' => $this->t('If set, this comment will be embedded in the query and passed to the SQL server. This can be helpful for logging or debugging.'), '#default_value' => $this->options['query_comment'], - ); - $form['query_tags'] = array( + ]; + $form['query_tags'] = [ '#type' => 'textfield', '#title' => $this->t('Query Tags'), '#description' => $this->t('If set, these tags will be appended to the query and can be used to identify the query in a module. This can be helpful for altering queries.'), '#default_value' => implode(', ', $this->options['query_tags']), - '#element_validate' => array('views_element_validate_tags'), - ); + '#element_validate' => ['views_element_validate_tags'], + ]; } /** * Special submit handling. */ public function submitOptionsForm(&$form, FormStateInterface $form_state) { - $element = array('#parents' => array('query', 'options', 'query_tags')); + $element = ['#parents' => ['query', 'options', 'query_tags']]; $value = explode(',', NestedArray::getValue($form_state->getValues(), $element['#parents'])); $value = array_filter(array_map('trim', $value)); $form_state->setValueForElement($element, $value); @@ -327,24 +328,24 @@ public function addRelationship($alias, JoinPluginBase $join, $base, $link_point // Add the table directly to the queue to avoid accidentally marking // it. - $this->tableQueue[$alias] = array( + $this->tableQueue[$alias] = [ 'table' => $join->table, 'num' => 1, 'alias' => $alias, 'join' => $join, 'relationship' => $link_point, - ); + ]; - $this->relationships[$alias] = array( + $this->relationships[$alias] = [ 'link' => $link_point, 'table' => $join->table, 'base' => $base, - ); + ]; - $this->tables[$this->view->storage->get('base_table')][$alias] = array( + $this->tables[$this->view->storage->get('base_table')][$alias] = [ 'count' => 1, 'alias' => $alias, - ); + ]; return $alias; } @@ -470,13 +471,13 @@ public function queueTable($table, $relationship = NULL, JoinPluginBase $join = $join = $this->adjustJoin($join, $relationship); } - $this->tableQueue[$alias] = array( + $this->tableQueue[$alias] = [ 'table' => $table, 'num' => $this->tables[$relationship][$table]['count'], 'alias' => $alias, 'join' => $join, 'relationship' => $relationship, - ); + ]; return $alias; } @@ -493,10 +494,10 @@ protected function markTable($table, $relationship, $alias) { } $alias .= $table; } - $this->tables[$relationship][$table] = array( + $this->tables[$relationship][$table] = [ 'count' => 1, 'alias' => $alias, - ); + ]; } else { $this->tables[$relationship][$table]['count']++; @@ -602,7 +603,7 @@ public function ensureTable($table, $relationship = NULL, JoinPluginBase $join = * query they will be added, but additional copies will NOT be added * if the table is already there. */ - protected function ensurePath($table, $relationship = NULL, $join = NULL, $traced = array(), $add = array()) { + protected function ensurePath($table, $relationship = NULL, $join = NULL, $traced = [], $add = []) { if (!isset($relationship)) { $relationship = $this->view->storage->get('base_table'); } @@ -762,7 +763,7 @@ public function getTableInfo($table) { * @return string * The name that this field can be referred to as. Usually this is the alias. */ - public function addField($table, $field, $alias = '', $params = array()) { + public function addField($table, $field, $alias = '', $params = []) { // We check for this specifically because it gets a special alias. if ($table == $this->view->storage->get('base_table') && $field == $this->view->storage->get('base_field') && empty($alias)) { $alias = $this->view->storage->get('base_field'); @@ -787,11 +788,11 @@ public function addField($table, $field, $alias = '', $params = array()) { $alias = strtolower(substr($alias, 0, 60)); // Create a field info array. - $field_info = array( + $field_info = [ 'field' => $field, 'table' => $table, 'alias' => $alias, - ) + $params; + ] + $params; // Test to see if the field is actually the same or not. Due to // differing parameters changing the aggregation function, we need @@ -817,7 +818,7 @@ public function addField($table, $field, $alias = '', $params = array()) { * mode where we're changing the query because we didn't get data we needed. */ public function clearFields() { - $this->fields = array(); + $this->fields = []; } /** @@ -830,7 +831,7 @@ public function clearFields() { * @code * $this->query->addWhere( * $this->options['group'], - * db_or() + * (new Condition('OR')) * ->condition($field, $value, 'NOT IN') * ->condition($field, $value, 'IS NULL') * ); @@ -866,11 +867,11 @@ public function addWhere($group, $field, $value = NULL, $operator = NULL) { $this->setWhereGroup('AND', $group); } - $this->where[$group]['conditions'][] = array( + $this->where[$group]['conditions'][] = [ 'field' => $field, 'value' => $value, 'operator' => $operator, - ); + ]; } /** @@ -892,7 +893,7 @@ public function addWhere($group, $field, $value = NULL, $operator = NULL) { * * @see QueryConditionInterface::where() */ - public function addWhereExpression($group, $snippet, $args = array()) { + public function addWhereExpression($group, $snippet, $args = []) { // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all // the default group. if (empty($group)) { @@ -904,11 +905,11 @@ public function addWhereExpression($group, $snippet, $args = array()) { $this->setWhereGroup('AND', $group); } - $this->where[$group]['conditions'][] = array( + $this->where[$group]['conditions'][] = [ 'field' => $snippet, 'value' => $args, 'operator' => 'formula', - ); + ]; } /** @@ -929,7 +930,7 @@ public function addWhereExpression($group, $snippet, $args = array()) { * * @see QueryConditionInterface::having() */ - public function addHavingExpression($group, $snippet, $args = array()) { + public function addHavingExpression($group, $snippet, $args = []) { // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all // the default group. if (empty($group)) { @@ -942,11 +943,11 @@ public function addHavingExpression($group, $snippet, $args = array()) { } // Add the clause and the args. - $this->having[$group]['conditions'][] = array( + $this->having[$group]['conditions'][] = [ 'field' => $snippet, 'value' => $args, 'operator' => 'formula', - ); + ]; } /** @@ -968,7 +969,7 @@ public function addHavingExpression($group, $snippet, $args = array()) { * @param $params * Any params that should be passed through to the addField. */ - public function addOrderBy($table, $field = NULL, $order = 'ASC', $alias = '', $params = array()) { + public function addOrderBy($table, $field = NULL, $order = 'ASC', $alias = '', $params = []) { // Only ensure the table if it's not the special random key. // @todo: Maybe it would make sense to just add an addOrderByRand or something similar. if ($table && $table != 'rand') { @@ -988,10 +989,10 @@ public function addOrderBy($table, $field = NULL, $order = 'ASC', $alias = '', $ $as = $this->addField($table, $field, $as, $params); } - $this->orderby[] = array( + $this->orderby[] = [ 'field' => $as, 'direction' => strtoupper($order) - ); + ]; } /** @@ -1030,7 +1031,7 @@ public function addTag($tag) { * Generates a unique placeholder used in the db query. */ public function placeholder($base = 'views') { - static $placeholders = array(); + static $placeholders = []; if (!isset($placeholders[$base])) { $placeholders[$base] = 0; return ':' . $base; @@ -1056,13 +1057,13 @@ protected function buildCondition($where = 'where') { $has_arguments = FALSE; $has_filter = FALSE; - $main_group = db_and(); - $filter_group = $this->groupOperator == 'OR' ? db_or() : db_and(); + $main_group = new Condition('AND'); + $filter_group = $this->groupOperator == 'OR' ? new Condition('OR') : new Condition('AND'); foreach ($this->$where as $group => $info) { if (!empty($info['conditions'])) { - $sub_group = $info['type'] == 'OR' ? db_or() : db_and(); + $sub_group = $info['type'] == 'OR' ? new Condition('OR') : new Condition('AND'); foreach ($info['conditions'] as $clause) { if ($clause['operator'] == 'formula') { $has_condition = TRUE; @@ -1110,7 +1111,7 @@ protected function buildCondition($where = 'where') { * An array of the fieldnames which are non-aggregates. */ protected function getNonAggregates() { - $non_aggregates = array(); + $non_aggregates = []; foreach ($this->fields as $field) { $string = ''; if (!empty($field['table'])) { @@ -1166,9 +1167,9 @@ protected function compileFields($query) { if (!empty($field['function'])) { $info = $this->getAggregationInfo(); - if (!empty($info[$field['function']]['method']) && is_callable(array($this, $info[$field['function']]['method']))) { + if (!empty($info[$field['function']]['method']) && is_callable([$this, $info[$field['function']]['method']])) { $string = $this::{$info[$field['function']]['method']}($field['function'], $string); - $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array(); + $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : []; $query->addExpression($string, $fieldname, $placeholders); } @@ -1176,7 +1177,7 @@ protected function compileFields($query) { } // This is a formula, using no tables. elseif (empty($field['table'])) { - $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array(); + $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : []; $query->addExpression($string, $fieldname, $placeholders); } elseif ($this->distinct && !in_array($fieldname, $this->groupby)) { @@ -1227,7 +1228,7 @@ public function query($get_count = FALSE) { $this->getCountOptimized = TRUE; } - $options = array(); + $options = []; $target = 'default'; $key = 'default'; // Detect an external database and set the @@ -1273,7 +1274,7 @@ public function query($get_count = FALSE) { // Allow 'GROUP BY' even no aggregation function has been set. $this->hasAggregate = $this->view->display_handler->getOption('group_by'); } - $groupby = array(); + $groupby = []; if ($this->hasAggregate && (!empty($this->groupby) || !empty($non_aggregates))) { $groupby = array_unique(array_merge($this->groupby, $non_aggregates)); } @@ -1282,12 +1283,12 @@ public function query($get_count = FALSE) { // entities can be loaded. $entity_information = $this->getEntityTableInfo(); if ($entity_information) { - $params = array(); + $params = []; if ($groupby) { // Handle grouping, by retrieving the minimum entity_id. - $params = array( + $params = [ 'function' => 'min', - ); + ]; } foreach ($entity_information as $entity_type_id => $info) { @@ -1346,7 +1347,7 @@ public function query($get_count = FALSE) { } // Add all query substitutions as metadata. - $query->addMetaData('views_substitutions', \Drupal::moduleHandler()->invokeAll('views_query_substitutions', array($this->view))); + $query->addMetaData('views_substitutions', \Drupal::moduleHandler()->invokeAll('views_query_substitutions', [$this->view])); return $query; } @@ -1355,7 +1356,7 @@ public function query($get_count = FALSE) { * Get the arguments attached to the WHERE and HAVING clauses of this query. */ public function getWhereArgs() { - $args = array(); + $args = []; foreach ($this->where as $where) { $args = array_merge($args, $where['args']); } @@ -1369,7 +1370,7 @@ public function getWhereArgs() { * Let modules modify the query just prior to finalizing it. */ public function alter(ViewExecutable $view) { - \Drupal::moduleHandler()->invokeAll('views_query_alter', array($view, $this)); + \Drupal::moduleHandler()->invokeAll('views_query_alter', [$view, $this]); } /** @@ -1424,7 +1425,7 @@ public function execute(ViewExecutable $view) { } if ($query) { - $additional_arguments = \Drupal::moduleHandler()->invokeAll('views_query_substitutions', array($view)); + $additional_arguments = \Drupal::moduleHandler()->invokeAll('views_query_substitutions', [$view]); // Count queries must be run through the preExecute() method. // If not, then hook_query_node_access_alter() may munge the count by @@ -1468,7 +1469,7 @@ public function execute(ViewExecutable $view) { // Setup the result row objects. $view->result = iterator_to_array($result); - array_walk($view->result, function(ResultRow $row, $index) { + array_walk($view->result, function (ResultRow $row, $index) { $row->index = $index; }); @@ -1480,7 +1481,7 @@ public function execute(ViewExecutable $view) { $this->loadEntities($view->result); } catch (DatabaseExceptionWrapper $e) { - $view->result = array(); + $view->result = []; if (!empty($view->live_preview)) { drupal_set_message($e->getMessage(), 'error'); } @@ -1514,7 +1515,7 @@ public function loadEntities(&$results) { } // Extract all entity types from entity_information. - $entity_types = array(); + $entity_types = []; foreach ($entity_information as $info) { $entity_type = $info['entity_type']; if (!isset($entity_types[$entity_type])) { @@ -1664,82 +1665,82 @@ public function addSignature(ViewExecutable $view) { public function getAggregationInfo() { // @todo -- need a way to get database specific and customized aggregation // functions into here. - return array( - 'group' => array( + return [ + 'group' => [ 'title' => $this->t('Group results together'), 'is aggregate' => FALSE, - ), - 'count' => array( + ], + 'count' => [ 'title' => $this->t('Count'), 'method' => 'aggregationMethodSimple', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ), - 'count_distinct' => array( + ], + ], + 'count_distinct' => [ 'title' => $this->t('Count DISTINCT'), 'method' => 'aggregationMethodDistinct', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ), - 'sum' => array( + ], + ], + 'sum' => [ 'title' => $this->t('Sum'), 'method' => 'aggregationMethodSimple', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ), - 'avg' => array( + ], + ], + 'avg' => [ 'title' => $this->t('Average'), 'method' => 'aggregationMethodSimple', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ), - 'min' => array( + ], + ], + 'min' => [ 'title' => $this->t('Minimum'), 'method' => 'aggregationMethodSimple', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ), - 'max' => array( + ], + ], + 'max' => [ 'title' => $this->t('Maximum'), 'method' => 'aggregationMethodSimple', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ), - 'stddev_pop' => array( + ], + ], + 'stddev_pop' => [ 'title' => $this->t('Standard deviation'), 'method' => 'aggregationMethodSimple', - 'handler' => array( + 'handler' => [ 'argument' => 'groupby_numeric', 'field' => 'numeric', 'filter' => 'groupby_numeric', 'sort' => 'groupby_numeric', - ), - ) - ); + ], + ] + ]; } public function aggregationMethodSimple($group_type, $field) { @@ -1794,7 +1795,7 @@ public function setupTimezone() { // set up the database timezone $db_type = Database::getConnection()->databaseType(); - if (in_array($db_type, array('mysql', 'pgsql'))) { + if (in_array($db_type, ['mysql', 'pgsql'])) { $offset = '+00:00'; static $already_set = FALSE; if (!$already_set) { @@ -1819,7 +1820,7 @@ public function getDateFormat($field, $format, $string_date = FALSE) { $db_type = Database::getConnection()->databaseType(); switch ($db_type) { case 'mysql': - $replace = array( + $replace = [ 'Y' => '%Y', 'y' => '%y', 'M' => '%b', @@ -1836,11 +1837,11 @@ public function getDateFormat($field, $format, $string_date = FALSE) { 'i' => '%i', 's' => '%s', 'A' => '%p', - ); + ]; $format = strtr($format, $replace); return "DATE_FORMAT($field, '$format')"; case 'pgsql': - $replace = array( + $replace = [ 'Y' => 'YYYY', 'y' => 'YY', 'M' => 'Mon', @@ -1860,7 +1861,7 @@ public function getDateFormat($field, $format, $string_date = FALSE) { 'i' => 'MI', 's' => 'SS', 'A' => 'AM', - ); + ]; $format = strtr($format, $replace); if (!$string_date) { return "TO_CHAR($field, '$format')"; @@ -1869,7 +1870,7 @@ public function getDateFormat($field, $format, $string_date = FALSE) { // date, back to a string again. return "TO_CHAR(TO_TIMESTAMP($field, 'YYYY-MM-DD HH24:MI:SS'), '$format')"; case 'sqlite': - $replace = array( + $replace = [ 'Y' => '%Y', // No format for 2 digit year number. 'y' => '%Y', @@ -1895,7 +1896,7 @@ public function getDateFormat($field, $format, $string_date = FALSE) { 's' => '%S', // No format for AM/PM. 'A' => '', - ); + ]; $format = strtr($format, $replace); // Don't use the 'unixepoch' flag for string date comparisons. diff --git a/core/modules/views/src/Plugin/views/relationship/EntityReverse.php b/core/modules/views/src/Plugin/views/relationship/EntityReverse.php index 42d6fa1e..7c016046 100644 --- a/core/modules/views/src/Plugin/views/relationship/EntityReverse.php +++ b/core/modules/views/src/Plugin/views/relationship/EntityReverse.php @@ -48,13 +48,13 @@ public function query() { $views_data = Views::viewsData()->get($this->table); $left_field = $views_data['table']['base']['field']; - $first = array( + $first = [ 'left_table' => $this->tableAlias, 'left_field' => $left_field, 'table' => $this->definition['field table'], 'field' => $this->definition['field field'], 'adjusted' => TRUE - ); + ]; if (!empty($this->options['required'])) { $first['type'] = 'INNER'; } @@ -76,13 +76,13 @@ public function query() { // Second, relate the field table to the entity specified using // the entity id on the field table and the entity's id field. - $second = array( + $second = [ 'left_table' => $this->first_alias, 'left_field' => 'entity_id', 'table' => $this->definition['base'], 'field' => $this->definition['base field'], 'adjusted' => TRUE - ); + ]; if (!empty($this->options['required'])) { $second['type'] = 'INNER'; diff --git a/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php b/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php index dc23a687..62389140 100644 --- a/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php +++ b/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php @@ -65,12 +65,12 @@ class GroupwiseMax extends RelationshipPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['subquery_sort'] = array('default' => NULL); + $options['subquery_sort'] = ['default' => NULL]; // Descending more useful. - $options['subquery_order'] = array('default' => 'DESC'); - $options['subquery_regenerate'] = array('default' => FALSE); - $options['subquery_view'] = array('default' => FALSE); - $options['subquery_namespace'] = array('default' => FALSE); + $options['subquery_order'] = ['default' => 'DESC']; + $options['subquery_regenerate'] = ['default' => FALSE]; + $options['subquery_view'] = ['default' => FALSE]; + $options['subquery_namespace'] = ['default' => FALSE]; return $options; } @@ -83,7 +83,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // Get the sorts that apply to our base. $sorts = Views::viewsDataHelper()->fetchFields($this->definition['base'], 'sort'); - $sort_options = array(); + $sort_options = []; foreach ($sorts as $sort_id => $sort) { $sort_options[$sort_id] = "$sort[group]: $sort[title]"; } @@ -91,34 +91,34 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // Extends the relationship's basic options, allowing the user to pick a // sort and an order for it. - $form['subquery_sort'] = array( + $form['subquery_sort'] = [ '#type' => 'select', '#title' => $this->t('Representative sort criteria'), // Provide the base field as sane default sort option. '#default_value' => !empty($this->options['subquery_sort']) ? $this->options['subquery_sort'] : $this->definition['base'] . '.' . $base_table_data['table']['base']['field'], '#options' => $sort_options, '#description' => $this->t("The sort criteria is applied to the data brought in by the relationship to determine how a representative item is obtained for each row. For example, to show the most recent node for each user, pick 'Content: Updated date'."), - ); + ]; - $form['subquery_order'] = array( + $form['subquery_order'] = [ '#type' => 'radios', '#title' => $this->t('Representative sort order'), '#description' => $this->t("The ordering to use for the sort criteria selected above."), - '#options' => array('ASC' => $this->t('Ascending'), 'DESC' => $this->t('Descending')), + '#options' => ['ASC' => $this->t('Ascending'), 'DESC' => $this->t('Descending')], '#default_value' => $this->options['subquery_order'], - ); + ]; - $form['subquery_namespace'] = array( + $form['subquery_namespace'] = [ '#type' => 'textfield', '#title' => $this->t('Subquery namespace'), '#description' => $this->t('Advanced. Enter a namespace for the subquery used by this relationship.'), '#default_value' => $this->options['subquery_namespace'], - ); + ]; // WIP: This stuff doesn't work yet: namespacing issues. // A list of suitable views to pick one as the subview. - $views = array('' => '- None -'); + $views = ['' => '- None -']; foreach (Views::getAllViews() as $view) { // Only get views that are suitable: // - base must the base that our relationship joins towards @@ -130,20 +130,20 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } } - $form['subquery_view'] = array( + $form['subquery_view'] = [ '#type' => 'select', '#title' => $this->t('Representative view'), '#default_value' => $this->options['subquery_view'], '#options' => $views, '#description' => $this->t('Advanced. Use another view to generate the relationship subquery. This allows you to use filtering and more than one sort. If you pick a view here, the sort options above are ignored. Your view must have the ID of its base as its only field, and should have some kind of sorting.'), - ); + ]; - $form['subquery_regenerate'] = array( + $form['subquery_regenerate'] = [ '#type' => 'checkbox', '#title' => $this->t('Generate subquery each time view is run'), '#default_value' => $this->options['subquery_regenerate'], '#description' => $this->t('Will re-generate the subquery for this relationship every time the view is run, instead of only when these options are saved. Use for testing if you are making changes elsewhere. WARNING: seriously impairs performance.'), - ); + ]; } /** @@ -152,7 +152,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * We use this to obtain our subquery SQL. */ protected function getTemporaryView() { - $view = View::create(array('base_table' => $this->definition['base'])); + $view = View::create(['base_table' => $this->definition['base']]); $view->addDisplay('default'); return $view->getExecutable(); } @@ -178,7 +178,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { * - subquery_order: either ASC or DESC. * * @return string - * The subquery SQL string, ready for use in the main query. + * The subquery SQL string, ready for use in the main query. */ protected function leftQuery($options) { // Either load another view, or create one on the fly. @@ -198,7 +198,7 @@ protected function leftQuery($options) { // We work around this further down. $sort = $options['subquery_sort']; list($sort_table, $sort_field) = explode('.', $sort); - $sort_options = array('order' => $options['subquery_order']); + $sort_options = ['order' => $options['subquery_order']]; $temp_view->addHandler('default', 'sort', $sort_table, $sort_field, $sort_options); } @@ -219,7 +219,7 @@ protected function leftQuery($options) { list($relationship_table, $relationship_field) = explode(':', $this->definition['relationship']); $relationship_id = $temp_view->addHandler('default', 'relationship', $relationship_table, $relationship_field); } - $temp_item_options = array('relationship' => $relationship_id); + $temp_item_options = ['relationship' => $relationship_id]; // Add the correct argument for our relationship's base // ie the 'how to get back to base' argument. diff --git a/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php b/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php index 25a0001e..86018917 100644 --- a/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php +++ b/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php @@ -99,7 +99,7 @@ protected function defineOptions() { } $options['admin_label']['default'] = $label; - $options['required'] = array('default' => FALSE); + $options['required'] = ['default' => FALSE]; return $options; } @@ -113,12 +113,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { unset($form['admin_label']['#fieldset']); $form['admin_label']['#weight'] = -1; - $form['required'] = array( + $form['required'] = [ '#type' => 'checkbox', '#title' => $this->t('Require this relationship'), '#description' => $this->t('Enable to hide items that do not contain this relationship'), '#default_value' => !empty($this->options['required']), - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/row/EntityReference.php b/core/modules/views/src/Plugin/views/row/EntityReference.php index 4ca79ba4..29661e3e 100644 --- a/core/modules/views/src/Plugin/views/row/EntityReference.php +++ b/core/modules/views/src/Plugin/views/row/EntityReference.php @@ -25,7 +25,7 @@ class EntityReference extends Fields { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['separator'] = array('default' => '-'); + $options['separator'] = ['default' => '-']; return $options; } @@ -37,7 +37,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); // Expand the description of the 'Inline field' checkboxes. - $form['inline']['#description'] .= '
          ' . $this->t("Note: In 'Entity Reference' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here." ); + $form['inline']['#description'] .= '
          ' . $this->t("Note: In 'Entity Reference' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here."); } /** diff --git a/core/modules/views/src/Plugin/views/row/EntityRow.php b/core/modules/views/src/Plugin/views/row/EntityRow.php index f5365296..e98133af 100644 --- a/core/modules/views/src/Plugin/views/row/EntityRow.php +++ b/core/modules/views/src/Plugin/views/row/EntityRow.php @@ -130,7 +130,7 @@ protected function getView() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['view_mode'] = array('default' => 'default'); + $options['view_mode'] = ['default' => 'default']; return $options; } @@ -140,12 +140,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['view_mode'] = array( + $form['view_mode'] = [ '#type' => 'select', '#options' => \Drupal::entityManager()->getViewModeOptions($this->entityTypeId), '#title' => $this->t('View mode'), '#default_value' => $this->options['view_mode'], - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/row/Fields.php b/core/modules/views/src/Plugin/views/row/Fields.php index 3904b0c0..711704ea 100644 --- a/core/modules/views/src/Plugin/views/row/Fields.php +++ b/core/modules/views/src/Plugin/views/row/Fields.php @@ -32,10 +32,10 @@ class Fields extends RowPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['inline'] = array('default' => array()); - $options['separator'] = array('default' => ''); - $options['hide_empty'] = array('default' => FALSE); - $options['default_field_elements'] = array('default' => TRUE); + $options['inline'] = ['default' => []]; + $options['separator'] = ['default' => '']; + $options['hide_empty'] = ['default' => FALSE]; + $options['default_field_elements'] = ['default' => TRUE]; return $options; } @@ -47,48 +47,48 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $options = $this->displayHandler->getFieldLabels(); if (empty($this->options['inline'])) { - $this->options['inline'] = array(); + $this->options['inline'] = []; } - $form['default_field_elements'] = array( + $form['default_field_elements'] = [ '#type' => 'checkbox', '#title' => $this->t('Provide default field wrapper elements'), '#default_value' => $this->options['default_field_elements'], '#description' => $this->t('If not checked, fields that are not configured to customize their HTML elements will get no wrappers at all for their field, label and field + label wrappers. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'), - ); + ]; - $form['inline'] = array( + $form['inline'] = [ '#type' => 'checkboxes', '#title' => $this->t('Inline fields'), '#options' => $options, '#default_value' => $this->options['inline'], '#description' => $this->t('Inline fields will be displayed next to each other rather than one after another. Note that some fields will ignore this if they are block elements, particularly body fields and other formatted HTML.'), - '#states' => array( - 'visible' => array( - ':input[name="row_options[default_field_elements]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="row_options[default_field_elements]"]' => ['checked' => TRUE], + ], + ], + ]; - $form['separator'] = array( + $form['separator'] = [ '#title' => $this->t('Separator'), '#type' => 'textfield', '#size' => 10, '#default_value' => isset($this->options['separator']) ? $this->options['separator'] : '', '#description' => $this->t('The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field.'), - '#states' => array( - 'visible' => array( - ':input[name="row_options[default_field_elements]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="row_options[default_field_elements]"]' => ['checked' => TRUE], + ], + ], + ]; - $form['hide_empty'] = array( + $form['hide_empty'] = [ '#type' => 'checkbox', '#title' => $this->t('Hide empty fields'), '#default_value' => $this->options['hide_empty'], '#description' => $this->t('Do not display fields, labels or markup for fields that are empty.'), - ); + ]; } @@ -97,8 +97,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * There is no need for this function to actually store the data. */ public function submitOptionsForm(&$form, FormStateInterface $form_state) { - $inline = $form_state->getValue(array('row_options', 'inline')); - $form_state->setValue(array('row_options', 'inline'), array_filter($inline)); + $inline = $form_state->getValue(['row_options', 'inline']); + $form_state->setValue(['row_options', 'inline'], array_filter($inline)); } } diff --git a/core/modules/views/src/Plugin/views/row/OpmlFields.php b/core/modules/views/src/Plugin/views/row/OpmlFields.php index 0c8f684b..aaeecbf6 100644 --- a/core/modules/views/src/Plugin/views/row/OpmlFields.php +++ b/core/modules/views/src/Plugin/views/row/OpmlFields.php @@ -29,14 +29,14 @@ class OpmlFields extends RowPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['text_field'] = array('default' => ''); - $options['created_field'] = array('default' => ''); - $options['type_field'] = array('default' => ''); - $options['description_field'] = array('default' => ''); - $options['html_url_field'] = array('default' => ''); - $options['language_field'] = array('default' => ''); - $options['xml_url_field'] = array('default' => ''); - $options['url_field'] = array('default' => ''); + $options['text_field'] = ['default' => '']; + $options['created_field'] = ['default' => '']; + $options['type_field'] = ['default' => '']; + $options['description_field'] = ['default' => '']; + $options['html_url_field'] = ['default' => '']; + $options['language_field'] = ['default' => '']; + $options['xml_url_field'] = ['default' => '']; + $options['url_field'] = ['default' => '']; return $options; } @@ -46,101 +46,101 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $initial_labels = array('' => $this->t('- None -')); + $initial_labels = ['' => $this->t('- None -')]; $view_fields_labels = $this->displayHandler->getFieldLabels(); $view_fields_labels = array_merge($initial_labels, $view_fields_labels); - $types = array( + $types = [ 'rss' => $this->t('RSS'), 'link' => $this->t('Link'), 'include' => $this->t('Include'), - ); + ]; $types = array_merge($initial_labels, $types); - $form['type_field'] = array( + $form['type_field'] = [ '#type' => 'select', '#title' => $this->t('Type attribute'), '#description' => $this->t('The type of this row.'), '#options' => $types, '#default_value' => $this->options['type_field'], - ); - $form['text_field'] = array( + ]; + $form['text_field'] = [ '#type' => 'select', '#title' => $this->t('Text attribute'), '#description' => $this->t('The field that is going to be used as the OPML text attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['text_field'], '#required' => TRUE, - ); - $form['created_field'] = array( + ]; + $form['created_field'] = [ '#type' => 'select', '#title' => $this->t('Created attribute'), '#description' => $this->t('The field that is going to be used as the OPML created attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['created_field'], - ); - $form['description_field'] = array( + ]; + $form['description_field'] = [ '#type' => 'select', '#title' => $this->t('Description attribute'), '#description' => $this->t('The field that is going to be used as the OPML description attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['description_field'], - '#states' => array( - 'visible' => array( - ':input[name="row_options[type_field]"]' => array('value' => 'rss'), - ), - ), - ); - $form['html_url_field'] = array( + '#states' => [ + 'visible' => [ + ':input[name="row_options[type_field]"]' => ['value' => 'rss'], + ], + ], + ]; + $form['html_url_field'] = [ '#type' => 'select', '#title' => $this->t('HTML URL attribute'), '#description' => $this->t('The field that is going to be used as the OPML htmlUrl attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['html_url_field'], - '#states' => array( - 'visible' => array( - ':input[name="row_options[type_field]"]' => array('value' => 'rss'), - ), - ), - ); - $form['language_field'] = array( + '#states' => [ + 'visible' => [ + ':input[name="row_options[type_field]"]' => ['value' => 'rss'], + ], + ], + ]; + $form['language_field'] = [ '#type' => 'select', '#title' => $this->t('Language attribute'), '#description' => $this->t('The field that is going to be used as the OPML language attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['language_field'], - '#states' => array( - 'visible' => array( - ':input[name="row_options[type_field]"]' => array('value' => 'rss'), - ), - ), - ); - $form['xml_url_field'] = array( + '#states' => [ + 'visible' => [ + ':input[name="row_options[type_field]"]' => ['value' => 'rss'], + ], + ], + ]; + $form['xml_url_field'] = [ '#type' => 'select', '#title' => $this->t('XML URL attribute'), '#description' => $this->t('The field that is going to be used as the OPML text attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['xml_url_field'], - '#states' => array( - 'visible' => array( - ':input[name="row_options[type_field]"]' => array('value' => 'rss'), - ), - ), - ); - $form['url_field'] = array( + '#states' => [ + 'visible' => [ + ':input[name="row_options[type_field]"]' => ['value' => 'rss'], + ], + ], + ]; + $form['url_field'] = [ '#type' => 'select', '#title' => $this->t('URL attribute'), '#description' => $this->t('The field that is going to be used as the OPML URL attribute for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['url_field'], - '#states' => array( - 'visible' => array( - ':input[name="row_options[type_field]"]' => array( - array('value' => 'link'), - array('value' => 'include'), - ), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="row_options[type_field]"]' => [ + ['value' => 'link'], + ['value' => 'include'], + ], + ], + ], + ]; } /** @@ -157,7 +157,7 @@ public function validate() { $errors[] = $this->t('Row style plugin requires specifying which views field to use for XML URL attribute.'); } } - elseif (in_array($this->options['type_field'], array('link', 'include'))) { + elseif (in_array($this->options['type_field'], ['link', 'include'])) { if (empty($this->options['url_field'])) { $errors[] = $this->t('Row style plugin requires specifying which views field to use for URL attribute.'); } @@ -171,7 +171,7 @@ public function validate() { */ public function render($row) { // Create the OPML item array. - $item = array(); + $item = []; $row_index = $this->view->row_index; $item['text'] = $this->getField($row_index, $this->options['text_field']); $item['created'] = $this->getField($row_index, $this->options['created_field']); @@ -190,13 +190,13 @@ public function render($row) { // Remove empty attributes. $item = array_filter($item); - $build = array( + $build = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#row' => $item, '#field_alias' => isset($this->field_alias) ? $this->field_alias : '', - ); + ]; return $build; } diff --git a/core/modules/views/src/Plugin/views/row/RowPluginBase.php b/core/modules/views/src/Plugin/views/row/RowPluginBase.php index d1e090e0..3c09eaf0 100644 --- a/core/modules/views/src/Plugin/views/row/RowPluginBase.php +++ b/core/modules/views/src/Plugin/views/row/RowPluginBase.php @@ -54,7 +54,7 @@ abstract class RowPluginBase extends PluginBase { * * @return bool */ - function usesFields() { + public function usesFields() { return $this->usesFields; } @@ -64,7 +64,7 @@ function usesFields() { protected function defineOptions() { $options = parent::defineOptions(); if (isset($this->base_table)) { - $options['relationship'] = array('default' => 'none'); + $options['relationship'] = ['default' => 'none']; } return $options; @@ -81,7 +81,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // A whole bunch of code to figure out what relationships are valid for // this item. $relationships = $executable->display_handler->getOption('relationships'); - $relationship_options = array(); + $relationship_options = []; foreach ($relationships as $relationship) { $relationship_handler = Views::handlerManager('relationship')->getHandler($relationship); @@ -96,25 +96,25 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } if (!empty($relationship_options)) { - $relationship_options = array_merge(array('none' => $this->t('Do not use a relationship')), $relationship_options); + $relationship_options = array_merge(['none' => $this->t('Do not use a relationship')], $relationship_options); $rel = empty($this->options['relationship']) ? 'none' : $this->options['relationship']; if (empty($relationship_options[$rel])) { // Pick the first relationship. $rel = key($relationship_options); } - $form['relationship'] = array( + $form['relationship'] = [ '#type' => 'select', '#title' => $this->t('Relationship'), '#options' => $relationship_options, '#default_value' => $rel, - ); + ]; } else { - $form['relationship'] = array( + $form['relationship'] = [ '#type' => 'value', '#value' => 'none', - ); + ]; } } } @@ -122,13 +122,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { /** * Validate the options form. */ - public function validateOptionsForm(&$form, FormStateInterface $form_state) { } + public function validateOptionsForm(&$form, FormStateInterface $form_state) {} /** * Perform any necessary changes to the form values prior to storage. * There is no need for this function to actually store the data. */ - public function submitOptionsForm(&$form, FormStateInterface $form_state) { } + public function submitOptionsForm(&$form, FormStateInterface $form_state) {} /** * {@inheritdoc} @@ -151,7 +151,7 @@ public function query() { * @param $result * The full array of results from the query. */ - public function preRender($result) { } + public function preRender($result) {} /** * Render a row object. This usually passes through to a theme template @@ -164,13 +164,13 @@ public function preRender($result) { } * The rendered output of a single row, used by the style plugin. */ public function render($row) { - return array( + return [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#row' => $row, '#field_alias' => isset($this->field_alias) ? $this->field_alias : '', - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/row/RssFields.php b/core/modules/views/src/Plugin/views/row/RssFields.php index a420bb7f..1b56aae5 100644 --- a/core/modules/views/src/Plugin/views/row/RssFields.php +++ b/core/modules/views/src/Plugin/views/row/RssFields.php @@ -27,87 +27,87 @@ class RssFields extends RowPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['title_field'] = array('default' => ''); - $options['link_field'] = array('default' => ''); - $options['description_field'] = array('default' => ''); - $options['creator_field'] = array('default' => ''); - $options['date_field'] = array('default' => ''); - $options['guid_field_options']['contains']['guid_field'] = array('default' => ''); - $options['guid_field_options']['contains']['guid_field_is_permalink'] = array('default' => TRUE); + $options['title_field'] = ['default' => '']; + $options['link_field'] = ['default' => '']; + $options['description_field'] = ['default' => '']; + $options['creator_field'] = ['default' => '']; + $options['date_field'] = ['default' => '']; + $options['guid_field_options']['contains']['guid_field'] = ['default' => '']; + $options['guid_field_options']['contains']['guid_field_is_permalink'] = ['default' => TRUE]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $initial_labels = array('' => $this->t('- None -')); + $initial_labels = ['' => $this->t('- None -')]; $view_fields_labels = $this->displayHandler->getFieldLabels(); $view_fields_labels = array_merge($initial_labels, $view_fields_labels); - $form['title_field'] = array( + $form['title_field'] = [ '#type' => 'select', '#title' => $this->t('Title field'), '#description' => $this->t('The field that is going to be used as the RSS item title for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['title_field'], '#required' => TRUE, - ); - $form['link_field'] = array( + ]; + $form['link_field'] = [ '#type' => 'select', '#title' => $this->t('Link field'), '#description' => $this->t('The field that is going to be used as the RSS item link for each row. This must be a drupal relative path.'), '#options' => $view_fields_labels, '#default_value' => $this->options['link_field'], '#required' => TRUE, - ); - $form['description_field'] = array( + ]; + $form['description_field'] = [ '#type' => 'select', '#title' => $this->t('Description field'), '#description' => $this->t('The field that is going to be used as the RSS item description for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['description_field'], '#required' => TRUE, - ); - $form['creator_field'] = array( + ]; + $form['creator_field'] = [ '#type' => 'select', '#title' => $this->t('Creator field'), '#description' => $this->t('The field that is going to be used as the RSS item creator for each row.'), '#options' => $view_fields_labels, '#default_value' => $this->options['creator_field'], '#required' => TRUE, - ); - $form['date_field'] = array( + ]; + $form['date_field'] = [ '#type' => 'select', '#title' => $this->t('Publication date field'), '#description' => $this->t('The field that is going to be used as the RSS item pubDate for each row. It needs to be in RFC 2822 format.'), '#options' => $view_fields_labels, '#default_value' => $this->options['date_field'], '#required' => TRUE, - ); - $form['guid_field_options'] = array( + ]; + $form['guid_field_options'] = [ '#type' => 'details', '#title' => $this->t('GUID settings'), '#open' => TRUE, - ); - $form['guid_field_options']['guid_field'] = array( + ]; + $form['guid_field_options']['guid_field'] = [ '#type' => 'select', '#title' => $this->t('GUID field'), '#description' => $this->t('The globally unique identifier of the RSS item.'), '#options' => $view_fields_labels, '#default_value' => $this->options['guid_field_options']['guid_field'], '#required' => TRUE, - ); - $form['guid_field_options']['guid_field_is_permalink'] = array( + ]; + $form['guid_field_options']['guid_field_is_permalink'] = [ '#type' => 'checkbox', '#title' => $this->t('GUID is permalink'), '#description' => $this->t('The RSS item GUID is a permalink.'), '#default_value' => $this->options['guid_field_options']['guid_field_is_permalink'], - ); + ]; } public function validate() { $errors = parent::validate(); - $required_options = array('title_field', 'link_field', 'description_field', 'creator_field', 'date_field'); + $required_options = ['title_field', 'link_field', 'description_field', 'creator_field', 'date_field']; foreach ($required_options as $required_option) { if (empty($this->options[$required_option])) { $errors[] = $this->t('Row style plugin requires specifying which views fields to use for RSS item.'); @@ -129,7 +129,7 @@ public function render($row) { if (function_exists('rdf_get_namespaces')) { // Merge RDF namespaces in the XML namespaces in case they are used // further in the RSS content. - $xml_rdf_namespaces = array(); + $xml_rdf_namespaces = []; foreach (rdf_get_namespaces() as $prefix => $uri) { $xml_rdf_namespaces['xmlns:' . $prefix] = $uri; } @@ -146,14 +146,14 @@ public function render($row) { $field = $this->getField($row_index, $this->options['description_field']); $item->description = is_array($field) ? $field : ['#markup' => $field]; - $item->elements = array( - array('key' => 'pubDate', 'value' => $this->getField($row_index, $this->options['date_field'])), - array( + $item->elements = [ + ['key' => 'pubDate', 'value' => $this->getField($row_index, $this->options['date_field'])], + [ 'key' => 'dc:creator', 'value' => $this->getField($row_index, $this->options['creator_field']), - 'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'), - ), - ); + 'namespace' => ['xmlns:dc' => 'http://purl.org/dc/elements/1.1/'], + ], + ]; $guid_is_permalink_string = 'false'; $item_guid = $this->getField($row_index, $this->options['guid_field_options']['guid_field']); if ($this->options['guid_field_options']['guid_field_is_permalink']) { @@ -162,11 +162,11 @@ public function render($row) { // https://www.drupal.org/node/2430589. $item_guid = Url::fromUserInput('/' . $item_guid)->setAbsolute()->toString(); } - $item->elements[] = array( + $item->elements[] = [ 'key' => 'guid', 'value' => $item_guid, - 'attributes' => array('isPermaLink' => $guid_is_permalink_string), - ); + 'attributes' => ['isPermaLink' => $guid_is_permalink_string], + ]; $row_index++; @@ -176,13 +176,13 @@ public function render($row) { } } - $build = array( + $build = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#row' => $item, '#field_alias' => isset($this->field_alias) ? $this->field_alias : '', - ); + ]; return $build; } diff --git a/core/modules/views/src/Plugin/views/row/RssPluginBase.php b/core/modules/views/src/Plugin/views/row/RssPluginBase.php index b5fd385b..b8c518bc 100644 --- a/core/modules/views/src/Plugin/views/row/RssPluginBase.php +++ b/core/modules/views/src/Plugin/views/row/RssPluginBase.php @@ -61,7 +61,7 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['view_mode'] = array('default' => 'default'); + $options['view_mode'] = ['default' => 'default']; return $options; } @@ -72,12 +72,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['view_mode'] = array( + $form['view_mode'] = [ '#type' => 'select', '#title' => $this->t('Display type'), '#options' => $this->buildOptionsForm_summary_options(), '#default_value' => $this->options['view_mode'], - ); + ]; } /** @@ -85,7 +85,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function buildOptionsForm_summary_options() { $view_modes = $this->entityManager->getViewModes($this->entityTypeId); - $options = array(); + $options = []; foreach ($view_modes as $mode => $settings) { $options[$mode] = $settings['label']; } diff --git a/core/modules/views/src/Plugin/views/sort/Date.php b/core/modules/views/src/Plugin/views/sort/Date.php index 4017e2b4..0c7d9e14 100644 --- a/core/modules/views/src/Plugin/views/sort/Date.php +++ b/core/modules/views/src/Plugin/views/sort/Date.php @@ -17,7 +17,7 @@ class Date extends SortPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['granularity'] = array('default' => 'second'); + $options['granularity'] = ['default' => 'second']; return $options; } @@ -25,20 +25,20 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['granularity'] = array( + $form['granularity'] = [ '#type' => 'radios', '#title' => $this->t('Granularity'), - '#options' => array( + '#options' => [ 'second' => $this->t('Second'), 'minute' => $this->t('Minute'), 'hour' => $this->t('Hour'), 'day' => $this->t('Day'), 'month' => $this->t('Month'), 'year' => $this->t('Year'), - ), + ], '#description' => $this->t('The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is "Year" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date.'), '#default_value' => $this->options['granularity'], - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/sort/GroupByNumeric.php b/core/modules/views/src/Plugin/views/sort/GroupByNumeric.php index b7245ddc..5308439e 100644 --- a/core/modules/views/src/Plugin/views/sort/GroupByNumeric.php +++ b/core/modules/views/src/Plugin/views/sort/GroupByNumeric.php @@ -30,9 +30,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o public function query() { $this->ensureMyTable(); - $params = array( + $params = [ 'function' => $this->options['group_type'], - ); + ]; $this->query->addOrderBy($this->tableAlias, $this->realField, $this->options['order'], NULL, $params); } diff --git a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php index 97122b15..3cc82bf8 100644 --- a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php +++ b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php @@ -28,7 +28,9 @@ abstract class SortPluginBase extends HandlerBase implements CacheableDependency /** * Determine if a sort can be exposed. */ - public function canExpose() { return TRUE; } + public function canExpose() { + return TRUE; + } /** * Called to add the sort to a query. @@ -42,13 +44,13 @@ public function query() { protected function defineOptions() { $options = parent::defineOptions(); - $options['order'] = array('default' => 'ASC'); - $options['exposed'] = array('default' => FALSE); - $options['expose'] = array( - 'contains' => array( - 'label' => array('default' => ''), - ), - ); + $options['order'] = ['default' => 'ASC']; + $options['exposed'] = ['default' => FALSE]; + $options['expose'] = [ + 'contains' => [ + 'label' => ['default' => ''], + ], + ]; return $options; } @@ -79,9 +81,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if ($this->canExpose()) { $this->showExposeButton($form, $form_state); } - $form['op_val_start'] = array('#value' => '
          '); + $form['op_val_start'] = ['#value' => '
          ']; $this->showSortForm($form, $form_state); - $form['op_val_end'] = array('#value' => '
          '); + $form['op_val_end'] = ['#value' => '
          ']; if ($this->canExpose()) { $this->showExposeForm($form, $form_state); } @@ -91,47 +93,47 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * Shortcut to display the expose/hide button. */ public function showExposeButton(&$form, FormStateInterface $form_state) { - $form['expose_button'] = array( + $form['expose_button'] = [ '#prefix' => '
          ', '#suffix' => '
          ', // Should always come first '#weight' => -1000, - ); + ]; // Add a checkbox for JS users, which will have behavior attached to it // so it can replace the button. - $form['expose_button']['checkbox'] = array( - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('js-only')), - ); - $form['expose_button']['checkbox']['checkbox'] = array( + $form['expose_button']['checkbox'] = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['js-only']], + ]; + $form['expose_button']['checkbox']['checkbox'] = [ '#title' => $this->t('Expose this sort to visitors, to allow them to change it'), '#type' => 'checkbox', - ); + ]; // Then add the button itself. if (empty($this->options['exposed'])) { - $form['expose_button']['markup'] = array( + $form['expose_button']['markup'] = [ '#markup' => '
          ' . $this->t('This sort is not exposed. Expose it to allow the users to change it.') . '
          ', - ); - $form['expose_button']['button'] = array( - '#limit_validation_errors' => array(), + ]; + $form['expose_button']['button'] = [ + '#limit_validation_errors' => [], '#type' => 'submit', '#value' => $this->t('Expose sort'), - '#submit' => array(array($this, 'displayExposedForm')), - ); + '#submit' => [[$this, 'displayExposedForm']], + ]; $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0; } else { - $form['expose_button']['markup'] = array( + $form['expose_button']['markup'] = [ '#markup' => '
          ' . $this->t('This sort is exposed. If you hide it, users will not be able to change it.') . '
          ', - ); - $form['expose_button']['button'] = array( - '#limit_validation_errors' => array(), + ]; + $form['expose_button']['button'] = [ + '#limit_validation_errors' => [], '#type' => 'submit', '#value' => $this->t('Hide sort'), - '#submit' => array(array($this, 'displayExposedForm')), - ); + '#submit' => [[$this, 'displayExposedForm']], + ]; $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1; } } @@ -166,28 +168,28 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { protected function showSortForm(&$form, FormStateInterface $form_state) { $options = $this->sortOptions(); if (!empty($options)) { - $form['order'] = array( + $form['order'] = [ '#title' => $this->t('Order'), '#type' => 'radios', '#options' => $options, '#default_value' => $this->options['order'], - ); + ]; } } - protected function sortValidate(&$form, FormStateInterface $form_state) { } + protected function sortValidate(&$form, FormStateInterface $form_state) {} - public function sortSubmit(&$form, FormStateInterface $form_state) { } + public function sortSubmit(&$form, FormStateInterface $form_state) {} /** * Provide a list of options for the default sort form. * Should be overridden by classes that don't override sort_form */ protected function sortOptions() { - return array( + return [ 'ASC' => $this->t('Sort ascending'), 'DESC' => $this->t('Sort descending'), - ); + ]; } public function buildExposeForm(&$form, FormStateInterface $form_state) { @@ -195,26 +197,26 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { // prior to rendering. That's why the preRender for it needs to run first, // so that when the next preRender (the one for fieldsets) runs, it gets // the flattened data. - array_unshift($form['#pre_render'], array(get_class($this), 'preRenderFlattenData')); + array_unshift($form['#pre_render'], [get_class($this), 'preRenderFlattenData']); $form['expose']['#flatten'] = TRUE; - $form['expose']['label'] = array( + $form['expose']['label'] = [ '#type' => 'textfield', '#default_value' => $this->options['expose']['label'], '#title' => $this->t('Label'), '#required' => TRUE, '#size' => 40, '#weight' => -1, - ); + ]; } /** * Provide default options for exposed sorts. */ public function defaultExposeOptions() { - $this->options['expose'] = array( + $this->options['expose'] = [ 'label' => $this->definition['title'], - ); + ]; } /** diff --git a/core/modules/views/src/Plugin/views/style/DefaultStyle.php b/core/modules/views/src/Plugin/views/style/DefaultStyle.php index 60aa9bd3..fe67d9be 100644 --- a/core/modules/views/src/Plugin/views/style/DefaultStyle.php +++ b/core/modules/views/src/Plugin/views/style/DefaultStyle.php @@ -19,9 +19,7 @@ class DefaultStyle extends StylePluginBase { /** - * Does the style plugin allows to use style plugins. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; diff --git a/core/modules/views/src/Plugin/views/style/DefaultSummary.php b/core/modules/views/src/Plugin/views/style/DefaultSummary.php index abd149dc..0b4325bc 100644 --- a/core/modules/views/src/Plugin/views/style/DefaultSummary.php +++ b/core/modules/views/src/Plugin/views/style/DefaultSummary.php @@ -22,10 +22,10 @@ class DefaultSummary extends StylePluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['base_path'] = array('default' => ''); - $options['count'] = array('default' => TRUE); - $options['override'] = array('default' => FALSE); - $options['items_per_page'] = array('default' => 25); + $options['base_path'] = ['default' => '']; + $options['count'] = ['default' => TRUE]; + $options['override'] = ['default' => FALSE]; + $options['items_per_page'] = ['default' => 25]; return $options; } @@ -37,7 +37,7 @@ public function query() { } public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['base_path'] = array( + $form['base_path'] = [ '#type' => 'textfield', '#title' => $this->t('Base path'), '#default_value' => $this->options['base_path'], @@ -46,43 +46,43 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { Do not include beginning and ending forward slash. If this value is empty, views will use the first path found as the base path, in page displays, or / if no path could be found.'), - ); - $form['count'] = array( + ]; + $form['count'] = [ '#type' => 'checkbox', '#default_value' => !empty($this->options['count']), '#title' => $this->t('Display record count with link'), - ); - $form['override'] = array( + ]; + $form['override'] = [ '#type' => 'checkbox', '#default_value' => !empty($this->options['override']), '#title' => $this->t('Override number of items to display'), - ); + ]; - $form['items_per_page'] = array( + $form['items_per_page'] = [ '#type' => 'textfield', '#title' => $this->t('Items to display'), '#default_value' => $this->options['items_per_page'], - '#states' => array( - 'visible' => array( - ':input[name="options[summary][options][' . $this->definition['id'] . '][override]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[summary][options][' . $this->definition['id'] . '][override]"]' => ['checked' => TRUE], + ], + ], + ]; } public function render() { - $rows = array(); + $rows = []; foreach ($this->view->result as $row) { // @todo: Include separator as an option. $rows[] = $row; } - return array( + return [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/style/EntityReference.php b/core/modules/views/src/Plugin/views/style/EntityReference.php index f694b00e..e07a0f18 100644 --- a/core/modules/views/src/Plugin/views/style/EntityReference.php +++ b/core/modules/views/src/Plugin/views/style/EntityReference.php @@ -41,7 +41,7 @@ class EntityReference extends StylePluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['search_fields'] = array('default' => array()); + $options['search_fields'] = ['default' => []]; return $options; } @@ -53,7 +53,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $options = $this->displayHandler->getFieldLabels(TRUE); - $form['search_fields'] = array( + $form['search_fields'] = [ '#type' => 'checkboxes', '#title' => $this->t('Search fields'), '#options' => $options, @@ -61,7 +61,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#default_value' => $this->options['search_fields'], '#description' => $this->t('Select the field(s) that will be searched when using the autocomplete widget.'), '#weight' => -3, - ); + ]; } /** @@ -81,7 +81,7 @@ public function render() { // @todo We don't display grouping info for now. Could be useful for select // widget, though. - $results = array(); + $results = []; foreach ($sets as $records) { foreach ($records as $values) { $results[$values->{$id_field_alias}] = $this->view->rowPlugin->render($values); diff --git a/core/modules/views/src/Plugin/views/style/Grid.php b/core/modules/views/src/Plugin/views/style/Grid.php index 34ab8ed2..f33f7f9c 100644 --- a/core/modules/views/src/Plugin/views/style/Grid.php +++ b/core/modules/views/src/Plugin/views/style/Grid.php @@ -21,9 +21,7 @@ class Grid extends StylePluginBase { /** - * Does the style plugin allows to use style plugins. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; @@ -32,13 +30,13 @@ class Grid extends StylePluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['columns'] = array('default' => '4'); - $options['automatic_width'] = array('default' => TRUE); - $options['alignment'] = array('default' => 'horizontal'); - $options['col_class_custom'] = array('default' => ''); - $options['col_class_default'] = array('default' => TRUE); - $options['row_class_custom'] = array('default' => ''); - $options['row_class_default'] = array('default' => TRUE); + $options['columns'] = ['default' => '4']; + $options['automatic_width'] = ['default' => TRUE]; + $options['alignment'] = ['default' => 'horizontal']; + $options['col_class_custom'] = ['default' => '']; + $options['col_class_default'] = ['default' => TRUE]; + $options['row_class_custom'] = ['default' => '']; + $options['row_class_default'] = ['default' => TRUE]; return $options; } @@ -47,53 +45,53 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['columns'] = array( + $form['columns'] = [ '#type' => 'number', '#title' => $this->t('Number of columns'), '#default_value' => $this->options['columns'], '#required' => TRUE, '#min' => 1, - ); - $form['automatic_width'] = array( + ]; + $form['automatic_width'] = [ '#type' => 'checkbox', '#title' => $this->t('Automatic width'), '#description' => $this->t('The width of each column will be calculated automatically based on the number of columns provided. If additional classes are entered or a theme injects classes based on a grid system, disabling this option may prove beneficial.'), '#default_value' => $this->options['automatic_width'], - ); - $form['alignment'] = array( + ]; + $form['alignment'] = [ '#type' => 'radios', '#title' => $this->t('Alignment'), - '#options' => array('horizontal' => $this->t('Horizontal'), 'vertical' => $this->t('Vertical')), + '#options' => ['horizontal' => $this->t('Horizontal'), 'vertical' => $this->t('Vertical')], '#default_value' => $this->options['alignment'], '#description' => $this->t('Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down.'), - ); - $form['col_class_default'] = array( + ]; + $form['col_class_default'] = [ '#title' => $this->t('Default column classes'), '#description' => $this->t('Add the default views column classes like views-col, col-1 and clearfix to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'), '#type' => 'checkbox', '#default_value' => $this->options['col_class_default'], - ); - $form['col_class_custom'] = array( + ]; + $form['col_class_custom'] = [ '#title' => $this->t('Custom column class'), '#description' => $this->t('Additional classes to provide on each column. Separated by a space.'), '#type' => 'textfield', '#default_value' => $this->options['col_class_custom'], - ); + ]; if ($this->usesFields()) { $form['col_class_custom']['#description'] .= ' ' . $this->t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); } - $form['row_class_default'] = array( + $form['row_class_default'] = [ '#title' => $this->t('Default row classes'), '#description' => $this->t('Adds the default views row classes like views-row, row-1 and clearfix to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'), '#type' => 'checkbox', '#default_value' => $this->options['row_class_default'], - ); - $form['row_class_custom'] = array( + ]; + $form['row_class_custom'] = [ '#title' => $this->t('Custom row class'), '#description' => $this->t('Additional classes to provide on each row. Separated by a space.'), '#type' => 'textfield', '#default_value' => $this->options['row_class_custom'], - ); + ]; if ($this->usesFields()) { $form['row_class_custom']['#description'] .= ' ' . $this->t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); } diff --git a/core/modules/views/src/Plugin/views/style/HtmlList.php b/core/modules/views/src/Plugin/views/style/HtmlList.php index a89b0f12..519dff64 100644 --- a/core/modules/views/src/Plugin/views/style/HtmlList.php +++ b/core/modules/views/src/Plugin/views/style/HtmlList.php @@ -20,9 +20,7 @@ class HtmlList extends StylePluginBase { /** - * Does the style plugin allows to use style plugins. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; @@ -39,9 +37,9 @@ class HtmlList extends StylePluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['type'] = array('default' => 'ul'); - $options['class'] = array('default' => ''); - $options['wrapper_class'] = array('default' => 'item-list'); + $options['type'] = ['default' => 'ul']; + $options['class'] = ['default' => '']; + $options['wrapper_class'] = ['default' => 'item-list']; return $options; } @@ -51,26 +49,26 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['type'] = array( + $form['type'] = [ '#type' => 'radios', '#title' => $this->t('List type'), - '#options' => array('ul' => $this->t('Unordered list'), 'ol' => $this->t('Ordered list')), + '#options' => ['ul' => $this->t('Unordered list'), 'ol' => $this->t('Ordered list')], '#default_value' => $this->options['type'], - ); - $form['wrapper_class'] = array( + ]; + $form['wrapper_class'] = [ '#title' => $this->t('Wrapper class'), '#description' => $this->t('The class to provide on the wrapper, outside the list.'), '#type' => 'textfield', '#size' => '30', '#default_value' => $this->options['wrapper_class'], - ); - $form['class'] = array( + ]; + $form['class'] = [ '#title' => $this->t('List class'), '#description' => $this->t('The class to provide on the list element itself.'), '#type' => 'textfield', '#size' => '30', '#default_value' => $this->options['class'], - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/style/Mapping.php b/core/modules/views/src/Plugin/views/style/Mapping.php index e7c72422..7db52478 100644 --- a/core/modules/views/src/Plugin/views/style/Mapping.php +++ b/core/modules/views/src/Plugin/views/style/Mapping.php @@ -49,14 +49,14 @@ protected function defineOptions() { // Parse the mapping and add a default for each. foreach ($this->defineMapping() as $key => $value) { - $default = !empty($value['#multiple']) ? array() : ''; - $options['mapping']['contains'][$key] = array( + $default = !empty($value['#multiple']) ? [] : ''; + $options['mapping']['contains'][$key] = [ 'default' => isset($value['#default_value']) ? $value['#default_value'] : $default, - ); + ]; if (!empty($value['#toggle'])) { - $options['mapping']['contains']["toggle_$key"] = array( + $options['mapping']['contains']["toggle_$key"] = [ 'default' => FALSE, - ); + ]; } } @@ -79,19 +79,19 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $field_labels = $this->displayHandler->getFieldLabels(); // Provide some default values. - $defaults = array( + $defaults = [ '#type' => 'select', '#required' => FALSE, '#multiple' => FALSE, - ); + ]; // For each mapping, add a select element to the form. foreach ($options as $key => $value) { // If the field is optional, add a 'None' value to the top of the options. - $field_options = array(); + $field_options = []; $required = !empty($mapping[$key]['#required']); if (!$required && empty($mapping[$key]['#multiple'])) { - $field_options = array('' => $this->t('- None -')); + $field_options = ['' => $this->t('- None -')]; } $field_options += $field_labels; @@ -104,19 +104,19 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } // These values must always be set. - $overrides = array( + $overrides = [ '#options' => $field_options, '#default_value' => $options[$key], - ); + ]; // Optionally allow the select to be toggleable. if (!empty($mapping[$key]['#toggle'])) { - $form['mapping']["toggle_$key"] = array( + $form['mapping']["toggle_$key"] = [ '#type' => 'checkbox', - '#title' => $this->t('Use a custom %field_name', array('%field_name' => strtolower($mapping[$key]['#title']))), + '#title' => $this->t('Use a custom %field_name', ['%field_name' => strtolower($mapping[$key]['#title'])]), '#default_value' => $this->options['mapping']["toggle_$key"], - ); - $overrides['#states']['visible'][':input[name="style_options[mapping][' . "toggle_$key" . ']"]'] = array('checked' => TRUE); + ]; + $overrides['#states']['visible'][':input[name="style_options[mapping][' . "toggle_$key" . ']"]'] = ['checked' => TRUE]; } $form['mapping'][$key] = $overrides + $mapping[$key] + $defaults; @@ -129,13 +129,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * Provides the mapping definition as an available variable. */ public function render() { - return array( + return [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#rows' => $this->view->result, '#mapping' => $this->defineMapping(), - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/style/Opml.php b/core/modules/views/src/Plugin/views/style/Opml.php index ed02511a..016405e4 100644 --- a/core/modules/views/src/Plugin/views/style/Opml.php +++ b/core/modules/views/src/Plugin/views/style/Opml.php @@ -20,9 +20,7 @@ class Opml extends StylePluginBase { /** - * Does the style plugin for itself support to add fields to its output. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; @@ -31,7 +29,7 @@ class Opml extends StylePluginBase { */ public function attachTo(array &$build, $display_id, Url $feed_url, $title) { $display = $this->view->displayHandlers->get($display_id); - $url_options = array(); + $url_options = []; $input = $this->view->getExposedInput(); if ($input) { $url_options['query'] = $input; @@ -41,15 +39,15 @@ public function attachTo(array &$build, $display_id, Url $feed_url, $title) { $url = $feed_url->setOptions($url_options)->toString(); if ($display->hasPath()) { if (empty($this->preview)) { - $build['#attached']['feed'][] = array($url, $title); + $build['#attached']['feed'][] = [$url, $title]; } } else { - $this->view->feedIcons[] = array( + $this->view->feedIcons[] = [ '#theme' => 'feed_icon', '#url' => $url, '#title' => $title, - ); + ]; } } @@ -61,19 +59,19 @@ public function render() { debug('Drupal\views\Plugin\views\style\Opml: Missing row plugin'); return; } - $rows = array(); + $rows = []; foreach ($this->view->result as $row_index => $row) { $this->view->row_index = $row_index; $rows[] = $this->view->rowPlugin->render($row); } - $build = array( + $build = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, - ); + ]; unset($this->view->row_index); return $build; } diff --git a/core/modules/views/src/Plugin/views/style/Rss.php b/core/modules/views/src/Plugin/views/style/Rss.php index e612453e..96d1deae 100644 --- a/core/modules/views/src/Plugin/views/style/Rss.php +++ b/core/modules/views/src/Plugin/views/style/Rss.php @@ -21,14 +21,12 @@ class Rss extends StylePluginBase { /** - * Does the style plugin for itself support to add fields to it's output. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; public function attachTo(array &$build, $display_id, Url $feed_url, $title) { - $url_options = array(); + $url_options = []; $input = $this->view->getExposedInput(); if ($input) { $url_options['query'] = $input; @@ -45,18 +43,18 @@ public function attachTo(array &$build, $display_id, Url $feed_url, $title) { ]; // Attach a link to the RSS feed, which is an alternate representation. - $build['#attached']['html_head_link'][][] = array( + $build['#attached']['html_head_link'][][] = [ 'rel' => 'alternate', 'type' => 'application/rss+xml', 'title' => $title, 'href' => $url, - ); + ]; } protected function defineOptions() { $options = parent::defineOptions(); - $options['description'] = array('default' => ''); + $options['description'] = ['default' => '']; return $options; } @@ -64,13 +62,13 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['description'] = array( + $form['description'] = [ '#type' => 'textfield', '#title' => $this->t('RSS description'), '#default_value' => $this->options['description'], '#description' => $this->t('This will appear in the RSS feed itself.'), '#maxlength' => 1024, - ); + ]; } /** @@ -80,7 +78,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * A render array. */ protected function getChannelElements() { - return array(); + return []; } /** @@ -101,13 +99,13 @@ public function getDescription() { public function render() { if (empty($this->view->rowPlugin)) { debug('Drupal\views\Plugin\views\style\Rss: Missing row plugin'); - return array(); + return []; } $rows = []; // This will be filled in by the row plugin and is used later on in the // theming output. - $this->namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'); + $this->namespaces = ['xmlns:dc' => 'http://purl.org/dc/elements/1.1/']; // Fetch any additional elements for the channel and merge in their // namespaces. @@ -123,12 +121,12 @@ public function render() { $rows[] = $this->view->rowPlugin->render($row); } - $build = array( + $build = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#rows' => $rows, - ); + ]; unset($this->view->row_index); return $build; } diff --git a/core/modules/views/src/Plugin/views/style/StylePluginBase.php b/core/modules/views/src/Plugin/views/style/StylePluginBase.php index 3bee96a5..1d6b4917 100644 --- a/core/modules/views/src/Plugin/views/style/StylePluginBase.php +++ b/core/modules/views/src/Plugin/views/style/StylePluginBase.php @@ -47,10 +47,10 @@ abstract class StylePluginBase extends PluginBase { /** * Store all available tokens row rows. */ - protected $rowTokens = array(); + protected $rowTokens = []; /** - * Does the style plugin allows to use style plugins. + * Whether or not this style uses a row plugin. * * @var bool */ @@ -122,9 +122,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o $this->view->rowPlugin = $display->getPlugin('row'); } - $this->options += array( - 'grouping' => array(), - ); + $this->options += [ + 'grouping' => [], + ]; } @@ -144,7 +144,7 @@ public function destroy() { * * @return bool */ - function usesRowPlugin() { + public function usesRowPlugin() { return $this->usesRowPlugin; } @@ -154,7 +154,7 @@ function usesRowPlugin() { * * @return bool */ - function usesRowClass() { + public function usesRowClass() { return $this->usesRowClass; } @@ -163,7 +163,7 @@ function usesRowClass() { * * @return bool */ - function usesGrouping() { + public function usesGrouping() { return $this->usesGrouping; } @@ -172,7 +172,7 @@ function usesGrouping() { * * @return bool */ - function usesFields() { + public function usesFields() { // If we use a row plugin, ask the row plugin. Chances are, we don't // care, it does. $row_uses_fields = FALSE; @@ -230,7 +230,7 @@ public function getRowClass($row_index) { public function tokenizeValue($value, $row_index) { if (strpos($value, '{{') !== FALSE) { // Row tokens might be empty, for example for node row style. - $tokens = isset($this->rowTokens[$row_index]) ? $this->rowTokens[$row_index] : array(); + $tokens = isset($this->rowTokens[$row_index]) ? $this->rowTokens[$row_index] : []; if (!empty($this->view->build_info['substitutions'])) { $tokens += $this->view->build_info['substitutions']; } @@ -257,12 +257,12 @@ public function evenEmpty() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['grouping'] = array('default' => array()); + $options['grouping'] = ['default' => []]; if ($this->usesRowClass()) { - $options['row_class'] = array('default' => ''); - $options['default_row_class'] = array('default' => TRUE); + $options['row_class'] = ['default' => '']; + $options['default_row_class'] = ['default' => TRUE]; } - $options['uses_fields'] = array('default' => FALSE); + $options['uses_fields'] = ['default' => FALSE]; return $options; } @@ -277,7 +277,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // to FALSE. // @TODO: Document "usesGrouping" in docs.php when docs.php is written. if ($this->usesFields() && $this->usesGrouping()) { - $options = array('' => $this->t('- None -')); + $options = ['' => $this->t('- None -')]; $field_labels = $this->displayHandler->getFieldLabels(TRUE); $options += $field_labels; // If there are no fields, we can't group on them. @@ -286,7 +286,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // select form. if (is_string($this->options['grouping'])) { $grouping = $this->options['grouping']; - $this->options['grouping'] = array(); + $this->options['grouping'] = []; $this->options['grouping'][0]['field'] = $grouping; } if (isset($this->options['group_rendered']) && is_string($this->options['group_rendered'])) { @@ -297,67 +297,67 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $c = count($this->options['grouping']); // Add a form for every grouping, plus one. for ($i = 0; $i <= $c; $i++) { - $grouping = !empty($this->options['grouping'][$i]) ? $this->options['grouping'][$i] : array(); - $grouping += array('field' => '', 'rendered' => TRUE, 'rendered_strip' => FALSE); - $form['grouping'][$i]['field'] = array( + $grouping = !empty($this->options['grouping'][$i]) ? $this->options['grouping'][$i] : []; + $grouping += ['field' => '', 'rendered' => TRUE, 'rendered_strip' => FALSE]; + $form['grouping'][$i]['field'] = [ '#type' => 'select', - '#title' => $this->t('Grouping field Nr.@number', array('@number' => $i + 1)), + '#title' => $this->t('Grouping field Nr.@number', ['@number' => $i + 1]), '#options' => $options, '#default_value' => $grouping['field'], '#description' => $this->t('You may optionally specify a field by which to group the records. Leave blank to not group.'), - ); - $form['grouping'][$i]['rendered'] = array( + ]; + $form['grouping'][$i]['rendered'] = [ '#type' => 'checkbox', '#title' => $this->t('Use rendered output to group rows'), '#default_value' => $grouping['rendered'], '#description' => $this->t('If enabled the rendered output of the grouping field is used to group the rows.'), - '#states' => array( - 'invisible' => array( - ':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''), - ), - ), - ); - $form['grouping'][$i]['rendered_strip'] = array( + '#states' => [ + 'invisible' => [ + ':input[name="style_options[grouping][' . $i . '][field]"]' => ['value' => ''], + ], + ], + ]; + $form['grouping'][$i]['rendered_strip'] = [ '#type' => 'checkbox', '#title' => $this->t('Remove tags from rendered output'), '#default_value' => $grouping['rendered_strip'], - '#states' => array( - 'invisible' => array( - ':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''), - ), - ), - ); + '#states' => [ + 'invisible' => [ + ':input[name="style_options[grouping][' . $i . '][field]"]' => ['value' => ''], + ], + ], + ]; } } } if ($this->usesRowClass()) { - $form['row_class'] = array( + $form['row_class'] = [ '#title' => $this->t('Row class'), '#description' => $this->t('The class to provide on each row.'), '#type' => 'textfield', '#default_value' => $this->options['row_class'], - ); + ]; if ($this->usesFields()) { $form['row_class']['#description'] .= ' ' . $this->t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); } - $form['default_row_class'] = array( + $form['default_row_class'] = [ '#title' => $this->t('Add views row classes'), - '#description' => $this->t('Add the default row classes like @classes to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.', array('@classes' => 'views-row')), + '#description' => $this->t('Add the default row classes like @classes to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.', ['@classes' => 'views-row']), '#type' => 'checkbox', '#default_value' => $this->options['default_row_class'], - ); + ]; } if (!$this->usesFields() || !empty($this->options['uses_fields'])) { - $form['uses_fields'] = array( + $form['uses_fields'] = [ '#type' => 'checkbox', '#title' => $this->t('Force using fields'), '#description' => $this->t('If neither the row nor the style plugin supports fields, this field allows to enable them, so you can for example use groupby.'), '#default_value' => $this->options['uses_fields'], - ); + ]; } } @@ -366,12 +366,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { // Don't run validation on style plugins without the grouping setting. - if ($form_state->hasValue(array('style_options', 'grouping'))) { + if ($form_state->hasValue(['style_options', 'grouping'])) { // Don't save grouping if no field is specified. - $groupings = $form_state->getValue(array('style_options', 'grouping')); + $groupings = $form_state->getValue(['style_options', 'grouping']); foreach ($groupings as $index => $grouping) { if (empty($grouping['field'])) { - $form_state->unsetValue(array('style_options', 'grouping', $index)); + $form_state->unsetValue(['style_options', 'grouping', $index]); } } } @@ -385,7 +385,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * @param string $type - * The display type, either block or page. + * The display type, either block or page. */ public function wizardForm(&$form, FormStateInterface $form_state, $type) { } @@ -413,13 +413,15 @@ public function wizardSubmit(&$form, FormStateInterface $form_state, WizardInter * interfere with the sorts. If so it should build; if it returns * any non-TRUE value, normal sorting will NOT be added to the query. */ - public function buildSort() { return TRUE; } + public function buildSort() { + return TRUE; + } /** * Called by the view builder to let the style build a second set of * sorts that will come after any other sorts in the view. */ - public function buildSortPost() { } + public function buildSortPost() {} /** * Allow the style to do stuff before each row is rendered. @@ -442,12 +444,12 @@ public function preRender($result) { * @return array * The render array containing the single group theme output. */ - protected function renderRowGroup(array $rows = array()) { - return array( + protected function renderRowGroup(array $rows = []) { + return [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#rows' => $rows, - ); + ]; } /** @@ -481,18 +483,12 @@ public function render() { * - group: The group content. * - level: The hierarchical level of the grouping. * - rows: The result rows to be rendered in this group.. - * @param $level - * (deprecated) This is no longer used and will be removed in Drupal 9. The - * 'level' key in $sets is used to indicate the hierarchical level of the - * grouping. * - * @todo Remove the $level parameter in https://www.drupal.org/node/2633890. - * - * @return string - * Rendered output of given grouping sets. + * @return array + * Render array of grouping sets. */ - public function renderGroupingSets($sets, $level = 0) { - $output = array(); + public function renderGroupingSets($sets) { + $output = []; $theme_functions = $this->view->buildThemeFunctions($this->groupingTheme); foreach ($sets as $set) { $level = isset($set['level']) ? $set['level'] : 0; @@ -500,12 +496,12 @@ public function renderGroupingSets($sets, $level = 0) { $row = reset($set['rows']); // Render as a grouping set. if (is_array($row) && isset($row['group'])) { - $single_output = array( + $single_output = [ '#theme' => $theme_functions, '#view' => $this->view, '#grouping' => $this->options['grouping'][$level], '#rows' => $set['rows'], - ); + ]; } // Render as a record set. else { @@ -568,17 +564,17 @@ public function renderGroupingSets($sets, $level = 0) { * ) * @endcode */ - public function renderGrouping($records, $groupings = array(), $group_rendered = NULL) { + public function renderGrouping($records, $groupings = [], $group_rendered = NULL) { // This is for backward compatibility, when $groupings was a string // containing the ID of a single field. if (is_string($groupings)) { $rendered = $group_rendered === NULL ? TRUE : $group_rendered; - $groupings = array(array('field' => $groupings, 'rendered' => $rendered)); + $groupings = [['field' => $groupings, 'rendered' => $rendered]]; } // Make sure fields are rendered $this->renderFields($this->view->result); - $sets = array(); + $sets = []; if ($groupings) { foreach ($records as $index => $row) { // Iterate through configured grouping fields to determine the @@ -619,7 +615,7 @@ public function renderGrouping($records, $groupings = array(), $group_rendered = if (empty($set[$grouping])) { $set[$grouping]['group'] = $group_content; $set[$grouping]['level'] = $level; - $set[$grouping]['rows'] = array(); + $set[$grouping]['rows'] = []; } // Move the set reference into the row set of the group we just determined. @@ -631,17 +627,17 @@ public function renderGrouping($records, $groupings = array(), $group_rendered = } else { // Create a single group with an empty grouping field. - $sets[''] = array( + $sets[''] = [ 'group' => '', 'rows' => $records, - ); + ]; } // If this parameter isn't explicitly set, modify the output to be fully // backward compatible to code before Views 7.x-3.0-rc2. // @TODO Remove this as soon as possible e.g. October 2020 if ($group_rendered === NULL) { - $old_style_sets = array(); + $old_style_sets = []; foreach ($sets as $group) { $old_style_sets[$group['group']] = $group['rows']; } @@ -794,7 +790,7 @@ public function getField($index, $field) { * @param $index * The index count of the row. * @param $field - * The id of the field. + * The id of the field. */ public function getFieldValue($index, $field) { $this->view->row_index = $index; @@ -812,7 +808,7 @@ public function validate() { if ($this->usesRowPlugin()) { $plugin = $this->displayHandler->getPlugin('row'); if (empty($plugin)) { - $errors[] = $this->t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title'])); + $errors[] = $this->t('Style @style requires a row style but the row plugin is invalid.', ['@style' => $this->definition['title']]); } else { $result = $plugin->validate(); diff --git a/core/modules/views/src/Plugin/views/style/Table.php b/core/modules/views/src/Plugin/views/style/Table.php index c49f6e98..bbc9a1ea 100644 --- a/core/modules/views/src/Plugin/views/style/Table.php +++ b/core/modules/views/src/Plugin/views/style/Table.php @@ -30,9 +30,7 @@ class Table extends StylePluginBase implements CacheableDependencyInterface { protected $usesFields = TRUE; /** - * Does the style plugin allows to use style plugins. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = FALSE; @@ -65,16 +63,16 @@ class Table extends StylePluginBase implements CacheableDependencyInterface { protected function defineOptions() { $options = parent::defineOptions(); - $options['columns'] = array('default' => array()); - $options['default'] = array('default' => ''); - $options['info'] = array('default' => array()); - $options['override'] = array('default' => TRUE); - $options['sticky'] = array('default' => FALSE); - $options['order'] = array('default' => 'asc'); - $options['caption'] = array('default' => ''); - $options['summary'] = array('default' => ''); - $options['description'] = array('default' => ''); - $options['empty_table'] = array('default' => FALSE); + $options['columns'] = ['default' => []]; + $options['default'] = ['default' => '']; + $options['info'] = ['default' => []]; + $options['override'] = ['default' => TRUE]; + $options['sticky'] = ['default' => FALSE]; + $options['order'] = ['default' => 'asc']; + $options['caption'] = ['default' => '']; + $options['summary'] = ['default' => '']; + $options['description'] = ['default' => '']; + $options['empty_table'] = ['default' => FALSE]; return $options; } @@ -162,10 +160,10 @@ public function buildSortPost() { * display has listed due to access control or other changes. * * @return array - * An array of all the sanitized columns. + * An array of all the sanitized columns. */ public function sanitizeColumns($columns, $fields = NULL) { - $sanitized = array(); + $sanitized = []; if ($fields === NULL) { $fields = $this->displayHandler->getOption('fields'); } @@ -202,57 +200,57 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $handlers = $this->displayHandler->getHandlers('field'); if (empty($handlers)) { - $form['error_markup'] = array( + $form['error_markup'] = [ '#markup' => '
          ' . $this->t('You need at least one field before you can configure your table settings') . '
          ', - ); + ]; return; } - $form['override'] = array( + $form['override'] = [ '#type' => 'checkbox', '#title' => $this->t('Override normal sorting if click sorting is used'), '#default_value' => !empty($this->options['override']), - ); + ]; - $form['sticky'] = array( + $form['sticky'] = [ '#type' => 'checkbox', '#title' => $this->t('Enable Drupal style "sticky" table headers (Javascript)'), '#default_value' => !empty($this->options['sticky']), '#description' => $this->t('(Sticky header effects will not be active for preview below, only on live output.)'), - ); + ]; - $form['caption'] = array( + $form['caption'] = [ '#type' => 'textfield', '#title' => $this->t('Caption for the table'), '#description' => $this->t('A title semantically associated with your table for increased accessibility.'), '#default_value' => $this->options['caption'], '#maxlength' => 255, - ); + ]; - $form['accessibility_details'] = array( + $form['accessibility_details'] = [ '#type' => 'details', '#title' => $this->t('Table details'), - ); + ]; - $form['summary'] = array( + $form['summary'] = [ '#title' => $this->t('Summary title'), '#type' => 'textfield', '#default_value' => $this->options['summary'], '#fieldset' => 'accessibility_details', - ); + ]; - $form['description'] = array( + $form['description'] = [ '#title' => $this->t('Table description'), '#type' => 'textarea', '#description' => $this->t('Provide additional details about the table to increase accessibility.'), '#default_value' => $this->options['description'], - '#states' => array( - 'visible' => array( - 'input[name="style_options[summary]"]' => array('filled' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + 'input[name="style_options[summary]"]' => ['filled' => TRUE], + ], + ], '#fieldset' => 'accessibility_details', - ); + ]; // Note: views UI registers this theme handler on our behalf. Your module // will have to register your theme handlers if you do stuff like this. @@ -276,137 +274,137 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { foreach ($columns as $field => $column) { $column_selector = ':input[name="style_options[columns][' . $field . ']"]'; - $form['columns'][$field] = array( - '#title' => $this->t('Columns for @field', array('@field' => $field)), + $form['columns'][$field] = [ + '#title' => $this->t('Columns for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'select', '#options' => $field_names, '#default_value' => $column, - ); + ]; if ($handlers[$field]->clickSortable()) { - $form['info'][$field]['sortable'] = array( - '#title' => $this->t('Sortable for @field', array('@field' => $field)), + $form['info'][$field]['sortable'] = [ + '#title' => $this->t('Sortable for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'checkbox', '#default_value' => !empty($this->options['info'][$field]['sortable']), - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ), - ), - ); - $form['info'][$field]['default_sort_order'] = array( - '#title' => $this->t('Default sort order for @field', array('@field' => $field)), + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['default_sort_order'] = [ + '#title' => $this->t('Default sort order for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'select', - '#options' => array('asc' => $this->t('Ascending'), 'desc' => $this->t('Descending')), + '#options' => ['asc' => $this->t('Ascending'), 'desc' => $this->t('Descending')], '#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc', - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ':input[name="style_options[info][' . $field . '][sortable]"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ':input[name="style_options[info][' . $field . '][sortable]"]' => ['checked' => TRUE], + ], + ], + ]; // Provide an ID so we can have such things. $radio_id = Html::getUniqueId('edit-default-' . $field); - $form['default'][$field] = array( - '#title' => $this->t('Default sort for @field', array('@field' => $field)), + $form['default'][$field] = [ + '#title' => $this->t('Default sort for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'radio', '#return_value' => $field, - '#parents' => array('style_options', 'default'), + '#parents' => ['style_options', 'default'], '#id' => $radio_id, // because 'radio' doesn't fully support '#id' =( - '#attributes' => array('id' => $radio_id), + '#attributes' => ['id' => $radio_id], '#default_value' => $default, - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ), - ), - ); + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; } - $form['info'][$field]['align'] = array( - '#title' => $this->t('Alignment for @field', array('@field' => $field)), + $form['info'][$field]['align'] = [ + '#title' => $this->t('Alignment for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'select', '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '', - '#options' => array( + '#options' => [ '' => $this->t('None'), - 'views-align-left' => $this->t('Left', array(), array('context' => 'Text alignment')), - 'views-align-center' => $this->t('Center', array(), array('context' => 'Text alignment')), - 'views-align-right' => $this->t('Right', array(), array('context' => 'Text alignment')), - ), - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ), - ), - ); - $form['info'][$field]['separator'] = array( - '#title' => $this->t('Separator for @field', array('@field' => $field)), + 'views-align-left' => $this->t('Left', [], ['context' => 'Text alignment']), + 'views-align-center' => $this->t('Center', [], ['context' => 'Text alignment']), + 'views-align-right' => $this->t('Right', [], ['context' => 'Text alignment']), + ], + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['separator'] = [ + '#title' => $this->t('Separator for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'textfield', '#size' => 10, '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '', - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ), - ), - ); - $form['info'][$field]['empty_column'] = array( - '#title' => $this->t('Hide empty column for @field', array('@field' => $field)), + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['empty_column'] = [ + '#title' => $this->t('Hide empty column for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'checkbox', '#default_value' => isset($this->options['info'][$field]['empty_column']) ? $this->options['info'][$field]['empty_column'] : FALSE, - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ), - ), - ); - $form['info'][$field]['responsive'] = array( - '#title' => $this->t('Responsive setting for @field', array('@field' => $field)), + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; + $form['info'][$field]['responsive'] = [ + '#title' => $this->t('Responsive setting for @field', ['@field' => $field]), '#title_display' => 'invisible', '#type' => 'select', '#default_value' => isset($this->options['info'][$field]['responsive']) ? $this->options['info'][$field]['responsive'] : '', - '#options' => array('' => $this->t('High'), RESPONSIVE_PRIORITY_MEDIUM => $this->t('Medium'), RESPONSIVE_PRIORITY_LOW => $this->t('Low')), - '#states' => array( - 'visible' => array( - $column_selector => array('value' => $field), - ), - ), - ); + '#options' => ['' => $this->t('High'), RESPONSIVE_PRIORITY_MEDIUM => $this->t('Medium'), RESPONSIVE_PRIORITY_LOW => $this->t('Low')], + '#states' => [ + 'visible' => [ + $column_selector => ['value' => $field], + ], + ], + ]; // markup for the field name - $form['info'][$field]['name'] = array( + $form['info'][$field]['name'] = [ '#markup' => $field_names[$field], - ); + ]; } // Provide a radio for no default sort - $form['default'][-1] = array( + $form['default'][-1] = [ '#title' => $this->t('No default sort'), '#title_display' => 'invisible', '#type' => 'radio', '#return_value' => -1, - '#parents' => array('style_options', 'default'), + '#parents' => ['style_options', 'default'], '#id' => 'edit-default-0', '#default_value' => $default, - ); + ]; - $form['empty_table'] = array( + $form['empty_table'] = [ '#type' => 'checkbox', '#title' => $this->t('Show the empty text in the table'), '#default_value' => $this->options['empty_table'], '#description' => $this->t('Per default the table is hidden for an empty view. With this option it is possible to show an empty table with the text in it.'), - ); + ]; - $form['description_markup'] = array( + $form['description_markup'] = [ '#markup' => '
          ' . $this->t('Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section.') . '
          ', - ); + ]; } public function evenEmpty() { diff --git a/core/modules/views/src/Plugin/views/style/UnformattedSummary.php b/core/modules/views/src/Plugin/views/style/UnformattedSummary.php index b6b6d6e4..6460841a 100644 --- a/core/modules/views/src/Plugin/views/style/UnformattedSummary.php +++ b/core/modules/views/src/Plugin/views/style/UnformattedSummary.php @@ -21,23 +21,23 @@ class UnformattedSummary extends DefaultSummary { protected function defineOptions() { $options = parent::defineOptions(); - $options['inline'] = array('default' => FALSE); - $options['separator'] = array('default' => ''); + $options['inline'] = ['default' => FALSE]; + $options['separator'] = ['default' => '']; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['inline'] = array( + $form['inline'] = [ '#type' => 'checkbox', '#default_value' => !empty($this->options['inline']), '#title' => $this->t('Display items inline'), - ); - $form['separator'] = array( + ]; + $form['separator'] = [ '#type' => 'textfield', '#title' => $this->t('Separator'), '#default_value' => $this->options['separator'], - ); + ]; } } diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php index 3f64626f..1771c710 100644 --- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php @@ -66,7 +66,7 @@ abstract class WizardPluginBase extends PluginBase implements WizardInterface { * * @var array */ - protected $validated_views = array(); + protected $validated_views = []; /** * The table column used for sorting by create date of this wizard. @@ -80,21 +80,21 @@ abstract class WizardPluginBase extends PluginBase implements WizardInterface { * * @var array */ - protected $filters = array(); + protected $filters = []; /** * Views items configuration arrays for sorts added by the wizard. * * @var array */ - protected $sorts = array(); + protected $sorts = []; /** * The available store criteria. * * @var array */ - protected $availableSorts = array(); + protected $availableSorts = []; /** * Default values for filters. @@ -104,11 +104,11 @@ abstract class WizardPluginBase extends PluginBase implements WizardInterface { * * @var array() */ - protected $filter_defaults = array( + protected $filter_defaults = [ 'id' => NULL, - 'expose' => array('operator' => FALSE), + 'expose' => ['operator' => FALSE], 'group' => 1, - ); + ]; /** * The bundle info service. @@ -163,7 +163,7 @@ public function getCreatedColumn() { * @return array */ public function getFilters() { - $filters = array(); + $filters = []; $default = $this->filter_defaults; @@ -197,100 +197,100 @@ public function getSorts() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $style_options = Views::fetchPluginNames('style', 'normal', array($this->base_table)); - $feed_row_options = Views::fetchPluginNames('row', 'feed', array($this->base_table)); + $style_options = Views::fetchPluginNames('style', 'normal', [$this->base_table]); + $feed_row_options = Views::fetchPluginNames('row', 'feed', [$this->base_table]); $path_prefix = $this->url('', [], ['absolute' => TRUE]); // Add filters and sorts which apply to the view as a whole. $this->buildFilters($form, $form_state); $this->buildSorts($form, $form_state); - $form['displays']['page'] = array( + $form['displays']['page'] = [ '#type' => 'fieldset', '#title' => $this->t('Page settings'), - '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend')), + '#attributes' => ['class' => ['views-attachment', 'fieldset-no-legend']], '#tree' => TRUE, - ); - $form['displays']['page']['create'] = array( + ]; + $form['displays']['page']['create'] = [ '#title' => $this->t('Create a page'), '#type' => 'checkbox', - '#attributes' => array('class' => array('strong')), + '#attributes' => ['class' => ['strong']], '#default_value' => FALSE, '#id' => 'edit-page-create', - ); + ]; // All options for the page display are included in this container so they // can be hidden as a group when the "Create a page" checkbox is unchecked. - $form['displays']['page']['options'] = array( + $form['displays']['page']['options'] = [ '#type' => 'container', - '#attributes' => array('class' => array('options-set')), - '#states' => array( - 'visible' => array( - ':input[name="page[create]"]' => array('checked' => TRUE), - ), - ), + '#attributes' => ['class' => ['options-set']], + '#states' => [ + 'visible' => [ + ':input[name="page[create]"]' => ['checked' => TRUE], + ], + ], '#prefix' => '
          ', '#suffix' => '
          ', - '#parents' => array('page'), - ); + '#parents' => ['page'], + ]; - $form['displays']['page']['options']['title'] = array( + $form['displays']['page']['options']['title'] = [ '#title' => $this->t('Page title'), '#type' => 'textfield', '#maxlength' => 255, - ); - $form['displays']['page']['options']['path'] = array( + ]; + $form['displays']['page']['options']['path'] = [ '#title' => $this->t('Path'), '#type' => 'textfield', '#field_prefix' => $path_prefix, // Account for the leading backslash. '#maxlength' => 254, - ); - $form['displays']['page']['options']['style'] = array( + ]; + $form['displays']['page']['options']['style'] = [ '#type' => 'fieldset', '#title' => $this->t('Page display settings'), - '#attributes' => array('class' => array('container-inline', 'fieldset-no-legend')), - ); + '#attributes' => ['class' => ['container-inline', 'fieldset-no-legend']], + ]; // Create the dropdown for choosing the display format. - $form['displays']['page']['options']['style']['style_plugin'] = array( + $form['displays']['page']['options']['style']['style_plugin'] = [ '#title' => $this->t('Display format'), '#type' => 'select', '#options' => $style_options, - ); + ]; $style_form = &$form['displays']['page']['options']['style']; - $style_form['style_plugin']['#default_value'] = static::getSelected($form_state, array('page', 'style', 'style_plugin'), 'default', $style_form['style_plugin']); + $style_form['style_plugin']['#default_value'] = static::getSelected($form_state, ['page', 'style', 'style_plugin'], 'default', $style_form['style_plugin']); // Changing this dropdown updates $form['displays']['page']['options'] via // AJAX. - views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'page', 'options')); + views_ui_add_ajax_trigger($style_form, 'style_plugin', ['displays', 'page', 'options']); $this->buildFormStyle($form, $form_state, 'page'); - $form['displays']['page']['options']['items_per_page'] = array( + $form['displays']['page']['options']['items_per_page'] = [ '#title' => $this->t('Items to display'), '#type' => 'number', '#default_value' => 10, '#min' => 0, - ); - $form['displays']['page']['options']['pager'] = array( + ]; + $form['displays']['page']['options']['pager'] = [ '#title' => $this->t('Use a pager'), '#type' => 'checkbox', '#default_value' => TRUE, - ); - $form['displays']['page']['options']['link'] = array( + ]; + $form['displays']['page']['options']['link'] = [ '#title' => $this->t('Create a menu link'), '#type' => 'checkbox', '#id' => 'edit-page-link', - ); - $form['displays']['page']['options']['link_properties'] = array( + ]; + $form['displays']['page']['options']['link_properties'] = [ '#type' => 'container', - '#states' => array( - 'visible' => array( - ':input[name="page[link]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="page[link]"]' => ['checked' => TRUE], + ], + ], '#prefix' => '', - ); + ]; if (\Drupal::moduleHandler()->moduleExists('menu_ui')) { $menu_options = menu_ui_get_menus(); } @@ -301,162 +301,162 @@ public function buildForm(array $form, FormStateInterface $form_state) { $menu_options[$name] = $this->t($title); } } - $form['displays']['page']['options']['link_properties']['menu_name'] = array( + $form['displays']['page']['options']['link_properties']['menu_name'] = [ '#title' => $this->t('Menu'), '#type' => 'select', '#options' => $menu_options, - ); - $form['displays']['page']['options']['link_properties']['title'] = array( + ]; + $form['displays']['page']['options']['link_properties']['title'] = [ '#title' => $this->t('Link text'), '#type' => 'textfield', - ); + ]; // Only offer a feed if we have at least one available feed row style. if ($feed_row_options) { - $form['displays']['page']['options']['feed'] = array( + $form['displays']['page']['options']['feed'] = [ '#title' => $this->t('Include an RSS feed'), '#type' => 'checkbox', '#id' => 'edit-page-feed', - ); - $form['displays']['page']['options']['feed_properties'] = array( + ]; + $form['displays']['page']['options']['feed_properties'] = [ '#type' => 'container', - '#states' => array( - 'visible' => array( - ':input[name="page[feed]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="page[feed]"]' => ['checked' => TRUE], + ], + ], '#prefix' => '
          ', '#suffix' => '
          ', - ); - $form['displays']['page']['options']['feed_properties']['path'] = array( + ]; + $form['displays']['page']['options']['feed_properties']['path'] = [ '#title' => $this->t('Feed path'), '#type' => 'textfield', '#field_prefix' => $path_prefix, // Account for the leading backslash. '#maxlength' => 254, - ); + ]; // This will almost never be visible. - $form['displays']['page']['options']['feed_properties']['row_plugin'] = array( + $form['displays']['page']['options']['feed_properties']['row_plugin'] = [ '#title' => $this->t('Feed row style'), '#type' => 'select', '#options' => $feed_row_options, '#default_value' => key($feed_row_options), '#access' => (count($feed_row_options) > 1), - '#states' => array( - 'visible' => array( - ':input[name="page[feed]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="page[feed]"]' => ['checked' => TRUE], + ], + ], '#prefix' => '
          ', '#suffix' => '
          ', - ); + ]; } // Only offer the block settings if the module is enabled. if (\Drupal::moduleHandler()->moduleExists('block')) { - $form['displays']['block'] = array( + $form['displays']['block'] = [ '#type' => 'fieldset', '#title' => $this->t('Block settings'), - '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend')), + '#attributes' => ['class' => ['views-attachment', 'fieldset-no-legend']], '#tree' => TRUE, - ); - $form['displays']['block']['create'] = array( + ]; + $form['displays']['block']['create'] = [ '#title' => $this->t('Create a block'), '#type' => 'checkbox', - '#attributes' => array('class' => array('strong')), + '#attributes' => ['class' => ['strong']], '#id' => 'edit-block-create', - ); + ]; // All options for the block display are included in this container so // they can be hidden as a group when the "Create a block" checkbox is // unchecked. - $form['displays']['block']['options'] = array( + $form['displays']['block']['options'] = [ '#type' => 'container', - '#attributes' => array('class' => array('options-set')), - '#states' => array( - 'visible' => array( - ':input[name="block[create]"]' => array('checked' => TRUE), - ), - ), + '#attributes' => ['class' => ['options-set']], + '#states' => [ + 'visible' => [ + ':input[name="block[create]"]' => ['checked' => TRUE], + ], + ], '#prefix' => '
          ', '#suffix' => '
          ', - '#parents' => array('block'), - ); + '#parents' => ['block'], + ]; - $form['displays']['block']['options']['title'] = array( + $form['displays']['block']['options']['title'] = [ '#title' => $this->t('Block title'), '#type' => 'textfield', '#maxlength' => 255, - ); - $form['displays']['block']['options']['style'] = array( + ]; + $form['displays']['block']['options']['style'] = [ '#type' => 'fieldset', '#title' => $this->t('Block display settings'), - '#attributes' => array('class' => array('container-inline', 'fieldset-no-legend')), - ); + '#attributes' => ['class' => ['container-inline', 'fieldset-no-legend']], + ]; // Create the dropdown for choosing the display format. - $form['displays']['block']['options']['style']['style_plugin'] = array( + $form['displays']['block']['options']['style']['style_plugin'] = [ '#title' => $this->t('Display format'), '#type' => 'select', '#options' => $style_options, - ); + ]; $style_form = &$form['displays']['block']['options']['style']; - $style_form['style_plugin']['#default_value'] = static::getSelected($form_state, array('block', 'style', 'style_plugin'), 'default', $style_form['style_plugin']); + $style_form['style_plugin']['#default_value'] = static::getSelected($form_state, ['block', 'style', 'style_plugin'], 'default', $style_form['style_plugin']); // Changing this dropdown updates $form['displays']['block']['options'] // via AJAX. - views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'block', 'options')); + views_ui_add_ajax_trigger($style_form, 'style_plugin', ['displays', 'block', 'options']); $this->buildFormStyle($form, $form_state, 'block'); - $form['displays']['block']['options']['items_per_page'] = array( + $form['displays']['block']['options']['items_per_page'] = [ '#title' => $this->t('Items per block'), '#type' => 'number', '#default_value' => 5, '#min' => 0, - ); - $form['displays']['block']['options']['pager'] = array( + ]; + $form['displays']['block']['options']['pager'] = [ '#title' => $this->t('Use a pager'), '#type' => 'checkbox', '#default_value' => FALSE, - ); + ]; } // Only offer the REST export settings if the module is enabled. if (\Drupal::moduleHandler()->moduleExists('rest')) { - $form['displays']['rest_export'] = array( + $form['displays']['rest_export'] = [ '#type' => 'fieldset', '#title' => $this->t('REST export settings'), - '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend')), + '#attributes' => ['class' => ['views-attachment', 'fieldset-no-legend']], '#tree' => TRUE, - ); - $form['displays']['rest_export']['create'] = array( + ]; + $form['displays']['rest_export']['create'] = [ '#title' => $this->t('Provide a REST export'), '#type' => 'checkbox', - '#attributes' => array('class' => array('strong')), + '#attributes' => ['class' => ['strong']], '#id' => 'edit-rest-export-create', - ); + ]; // All options for the REST export display are included in this container // so they can be hidden as a group when the "Provide a REST export" // checkbox is unchecked. - $form['displays']['rest_export']['options'] = array( + $form['displays']['rest_export']['options'] = [ '#type' => 'container', - '#attributes' => array('class' => array('options-set')), - '#states' => array( - 'visible' => array( - ':input[name="rest_export[create]"]' => array('checked' => TRUE), - ), - ), + '#attributes' => ['class' => ['options-set']], + '#states' => [ + 'visible' => [ + ':input[name="rest_export[create]"]' => ['checked' => TRUE], + ], + ], '#prefix' => '
          ', '#suffix' => '
          ', - '#parents' => array('rest_export'), - ); + '#parents' => ['rest_export'], + ]; - $form['displays']['rest_export']['options']['path'] = array( + $form['displays']['rest_export']['options']['path'] = [ '#title' => $this->t('REST export path'), '#type' => 'textfield', '#field_prefix' => $path_prefix, // Account for the leading backslash. '#maxlength' => 254, - ); + ]; } return $form; @@ -561,28 +561,28 @@ protected function buildFormStyle(array &$form, FormStateInterface $form_state, $style_plugin = Views::pluginManager('style')->createInstance($style); if (isset($style_plugin) && $style_plugin->usesRowPlugin()) { $options = $this->rowStyleOptions(); - $style_form['row_plugin'] = array( + $style_form['row_plugin'] = [ '#type' => 'select', '#title' => $this->t('of'), '#options' => $options, '#access' => count($options) > 1, - ); + ]; // For the block display, the default value should be "titles (linked)", // if it's available (since that's the most common use case). $block_with_linked_titles_available = ($type == 'block' && isset($options['titles_linked'])); $default_value = $block_with_linked_titles_available ? 'titles_linked' : key($options); - $style_form['row_plugin']['#default_value'] = static::getSelected($form_state, array($type, 'style', 'row_plugin'), $default_value, $style_form['row_plugin']); + $style_form['row_plugin']['#default_value'] = static::getSelected($form_state, [$type, 'style', 'row_plugin'], $default_value, $style_form['row_plugin']); // Changing this dropdown updates the individual row options via AJAX. - views_ui_add_ajax_trigger($style_form, 'row_plugin', array('displays', $type, 'options', 'style', 'row_options')); + views_ui_add_ajax_trigger($style_form, 'row_plugin', ['displays', $type, 'options', 'style', 'row_options']); // This is the region that can be updated by AJAX. The base class doesn't // add anything here, but child classes can. - $style_form['row_options'] = array( - '#theme_wrappers' => array('container'), - ); + $style_form['row_options'] = [ + '#theme_wrappers' => ['container'], + ]; } elseif ($style_plugin->usesFields()) { - $style_form['row_plugin'] = array('#markup' => '' . $this->t('of fields') . ''); + $style_form['row_plugin'] = ['#markup' => '' . $this->t('of fields') . '']; } } @@ -594,7 +594,7 @@ protected function buildFormStyle(array &$form, FormStateInterface $form_state, */ protected function rowStyleOptions() { // Get all available row plugins by default. - $options = Views::fetchPluginNames('row', 'normal', array($this->base_table)); + $options = Views::fetchPluginNames('row', 'normal', [$this->base_table]); return $options; } @@ -611,21 +611,21 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { // If the current base table support bundles and has more than one (like user). if (!empty($bundles) && $this->entityType && $this->entityType->hasKey('bundle')) { // Get all bundles and their human readable names. - $options = array('all' => $this->t('All')); + $options = ['all' => $this->t('All')]; foreach ($bundles as $type => $bundle) { $options[$type] = $bundle['label']; } - $form['displays']['show']['type'] = array( + $form['displays']['show']['type'] = [ '#type' => 'select', '#title' => $this->t('of type'), '#options' => $options, - ); - $selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']); + ]; + $selected_bundle = static::getSelected($form_state, ['show', 'type'], 'all', $form['displays']['show']['type']); $form['displays']['show']['type']['#default_value'] = $selected_bundle; // Changing this dropdown updates the entire content of $form['displays'] // via AJAX, since each bundle might have entirely different fields // attached to it, etc. - views_ui_add_ajax_trigger($form['displays']['show'], 'type', array('displays')); + views_ui_add_ajax_trigger($form['displays']['show'], 'type', ['displays']); } } @@ -635,16 +635,16 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { * By default, this adds a "sorted by [date]" filter (when it is available). */ protected function buildSorts(&$form, FormStateInterface $form_state) { - $sorts = array( + $sorts = [ 'none' => $this->t('Unsorted'), - ); + ]; // Check if we are allowed to sort by creation date. $created_column = $this->getCreatedColumn(); if ($created_column) { - $sorts += array( + $sorts += [ $created_column . ':DESC' => $this->t('Newest first'), $created_column . ':ASC' => $this->t('Oldest first'), - ); + ]; } if ($available_sorts = $this->getAvailableSorts()) { $sorts += $available_sorts; @@ -652,12 +652,12 @@ protected function buildSorts(&$form, FormStateInterface $form_state) { // If there is no sorts option available continue. if (!empty($sorts)) { - $form['displays']['show']['sort'] = array( + $form['displays']['show']['sort'] = [ '#type' => 'select', '#title' => $this->t('sorted by'), '#options' => $sorts, '#default_value' => isset($created_column) ? $created_column . ':DESC' : 'none', - ); + ]; } } @@ -669,13 +669,13 @@ protected function buildSorts(&$form, FormStateInterface $form_state) { */ protected function instantiateView($form, FormStateInterface $form_state) { // Build the basic view properties and create the view. - $values = array( + $values = [ 'id' => $form_state->getValue('id'), 'label' => $form_state->getValue('label'), 'description' => $form_state->getValue('description'), 'base_table' => $this->base_table, 'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(), - ); + ]; $view = View::create($values); @@ -702,25 +702,25 @@ protected function instantiateView($form, FormStateInterface $form_state) { protected function buildDisplayOptions($form, FormStateInterface $form_state) { // Display: Master $display_options['default'] = $this->defaultDisplayOptions(); - $display_options['default'] += array( - 'filters' => array(), - 'sorts' => array(), - ); + $display_options['default'] += [ + 'filters' => [], + 'sorts' => [], + ]; $display_options['default']['filters'] += $this->defaultDisplayFilters($form, $form_state); $display_options['default']['sorts'] += $this->defaultDisplaySorts($form, $form_state); // Display: Page - if (!$form_state->isValueEmpty(array('page', 'create'))) { + if (!$form_state->isValueEmpty(['page', 'create'])) { $display_options['page'] = $this->pageDisplayOptions($form, $form_state); // Display: Feed (attached to the page) - if (!$form_state->isValueEmpty(array('page', 'feed'))) { + if (!$form_state->isValueEmpty(['page', 'feed'])) { $display_options['feed'] = $this->pageFeedDisplayOptions($form, $form_state); } } // Display: Block - if (!$form_state->isValueEmpty(array('block', 'create'))) { + if (!$form_state->isValueEmpty(['block', 'create'])) { $display_options['block'] = $this->blockDisplayOptions($form, $form_state); } @@ -812,7 +812,7 @@ protected function addDisplays(View $view, $display_options, $form, FormStateInt * Returns an array of display options. */ protected function defaultDisplayOptions() { - $display_options = array(); + $display_options = []; $display_options['access']['type'] = 'none'; $display_options['cache']['type'] = 'tag'; $display_options['query']['type'] = 'views_query'; @@ -823,7 +823,7 @@ protected function defaultDisplayOptions() { // Add default options array to each plugin type. foreach ($display_options as &$options) { - $options['options'] = array(); + $options['options'] = []; } // Add a least one field so the view validates and the user has a preview. @@ -849,14 +849,14 @@ protected function defaultDisplayOptions() { } // @todo Refactor the code to use ViewExecutable::addHandler. See // https://www.drupal.org/node/2383157. - $display_options['fields'][$default_field] = array( + $display_options['fields'][$default_field] = [ 'table' => $default_table, 'field' => $default_field, 'id' => $default_field, 'entity_type' => isset($data[$default_field]['entity type']) ? $data[$default_field]['entity type'] : NULL, 'entity_field' => isset($data[$default_field]['entity field']) ? $data[$default_field]['entity field'] : NULL, 'plugin_id' => $data[$default_field]['field']['id'], - ); + ]; return $display_options; } @@ -877,7 +877,7 @@ protected function defaultDisplayOptions() { * accepted by a filter handler. */ protected function defaultDisplayFilters($form, FormStateInterface $form_state) { - $filters = array(); + $filters = []; // Add any filters provided by the plugin. foreach ($this->getFilters() as $name => $info) { @@ -903,9 +903,9 @@ protected function defaultDisplayFilters($form, FormStateInterface $form_state) * accepted by a filter handler. */ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $form_state) { - $filters = array(); + $filters = []; - if (($type = $form_state->getValue(array('show', 'type'))) && $type != 'all') { + if (($type = $form_state->getValue(['show', 'type'])) && $type != 'all') { $bundle_key = $this->entityType->getKey('bundle'); // Figure out the table where $bundle_key lives. It may not be the same as // the base table for the view; the taxonomy vocabulary machine_name, for @@ -928,14 +928,14 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo $handler = $table_data[$bundle_key]['filter']['id']; $handler_definition = Views::pluginManager('filter')->getDefinition($handler); if ($handler == 'in_operator' || is_subclass_of($handler_definition['class'], 'Drupal\\views\\Plugin\\views\\filter\\InOperator')) { - $value = array($type => $type); + $value = [$type => $type]; } // Otherwise, use just a single value. else { $value = $type; } - $filters[$bundle_key] = array( + $filters[$bundle_key] = [ 'id' => $bundle_key, 'table' => $table, 'field' => $bundle_key, @@ -943,7 +943,7 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo 'entity_type' => isset($table_data['table']['entity type']) ? $table_data['table']['entity type'] : NULL, 'entity_field' => isset($table_data[$bundle_key]['entity field']) ? $table_data[$bundle_key]['entity field'] : NULL, 'plugin_id' => $handler, - ); + ]; } return $filters; @@ -965,7 +965,7 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo * accepted by a sort handler. */ protected function defaultDisplaySorts($form, FormStateInterface $form_state) { - $sorts = array(); + $sorts = []; // Add any sorts provided by the plugin. foreach ($this->getSorts() as $name => $info) { @@ -991,11 +991,11 @@ protected function defaultDisplaySorts($form, FormStateInterface $form_state) { * accepted by a sort handler. */ protected function defaultDisplaySortsUser($form, FormStateInterface $form_state) { - $sorts = array(); + $sorts = []; // Don't add a sort if there is no form value or the user set the sort to // 'none'. - if (($sort_type = $form_state->getValue(array('show', 'sort'))) && $sort_type != 'none') { + if (($sort_type = $form_state->getValue(['show', 'sort'])) && $sort_type != 'none') { list($column, $sort) = explode(':', $sort_type); // Column either be a column-name or the table-column-name. $column = explode('-', $column); @@ -1014,7 +1014,7 @@ protected function defaultDisplaySortsUser($form, FormStateInterface $form_state // enabled. $data = Views::viewsData()->get($table); if (isset($data[$column]['sort'])) { - $sorts[$column] = array( + $sorts[$column] = [ 'id' => $column, 'table' => $table, 'field' => $column, @@ -1022,7 +1022,7 @@ protected function defaultDisplaySortsUser($form, FormStateInterface $form_state 'entity_type' => isset($data['table']['entity type']) ? $data['table']['entity type'] : NULL, 'entity_field' => isset($data[$column]['entity field']) ? $data[$column]['entity field'] : NULL, 'plugin_id' => $data[$column]['sort']['id'], - ); + ]; } } @@ -1041,15 +1041,15 @@ protected function defaultDisplaySortsUser($form, FormStateInterface $form_state * Returns an array of display options. */ protected function pageDisplayOptions(array $form, FormStateInterface $form_state) { - $display_options = array(); + $display_options = []; $page = $form_state->getValue('page'); $display_options['title'] = $page['title']; $display_options['path'] = $page['path']; - $display_options['style'] = array('type' => $page['style']['style_plugin']); + $display_options['style'] = ['type' => $page['style']['style_plugin']]; // Not every style plugin supports row style plugins. // Make sure that the selected row plugin is a valid one. $options = $this->rowStyleOptions(); - $display_options['row'] = array('type' => (isset($page['style']['row_plugin']) && isset($options[$page['style']['row_plugin']])) ? $page['style']['row_plugin'] : 'fields'); + $display_options['row'] = ['type' => (isset($page['style']['row_plugin']) && isset($options[$page['style']['row_plugin']])) ? $page['style']['row_plugin'] : 'fields']; // If the specific 0 items per page, use no pager. if (empty($page['items_per_page'])) { @@ -1087,12 +1087,12 @@ protected function pageDisplayOptions(array $form, FormStateInterface $form_stat * Returns an array of display options. */ protected function blockDisplayOptions(array $form, FormStateInterface $form_state) { - $display_options = array(); + $display_options = []; $block = $form_state->getValue('block'); $display_options['title'] = $block['title']; - $display_options['style'] = array('type' => $block['style']['style_plugin']); + $display_options['style'] = ['type' => $block['style']['style_plugin']]; $options = $this->rowStyleOptions(); - $display_options['row'] = array('type' => (isset($block['style']['row_plugin']) && isset($options[$block['style']['row_plugin']])) ? $block['style']['row_plugin'] : 'fields'); + $display_options['row'] = ['type' => (isset($block['style']['row_plugin']) && isset($options[$block['style']['row_plugin']])) ? $block['style']['row_plugin'] : 'fields']; $display_options['pager']['type'] = $block['pager'] ? 'full' : (empty($block['items_per_page']) ? 'none' : 'some'); $display_options['pager']['options']['items_per_page'] = $block['items_per_page']; return $display_options; @@ -1110,9 +1110,9 @@ protected function blockDisplayOptions(array $form, FormStateInterface $form_sta * Returns an array of display options. */ protected function restExportDisplayOptions(array $form, FormStateInterface $form_state) { - $display_options = array(); + $display_options = []; $display_options['path'] = $form_state->getValue(['rest_export', 'path']); - $display_options['style'] = array('type' => 'serializer'); + $display_options['style'] = ['type' => 'serializer']; return $display_options; } @@ -1129,16 +1129,16 @@ protected function restExportDisplayOptions(array $form, FormStateInterface $for * Returns an array of display options. */ protected function pageFeedDisplayOptions($form, FormStateInterface $form_state) { - $display_options = array(); + $display_options = []; $display_options['pager']['type'] = 'some'; - $display_options['style'] = array('type' => 'rss'); - $display_options['row'] = array('type' => $form_state->getValue(array('page', 'feed_properties', 'row_plugin'))); - $display_options['path'] = $form_state->getValue(array('page', 'feed_properties', 'path')); - $display_options['title'] = $form_state->getValue(array('page', 'title')); - $display_options['displays'] = array( + $display_options['style'] = ['type' => 'rss']; + $display_options['row'] = ['type' => $form_state->getValue(['page', 'feed_properties', 'row_plugin'])]; + $display_options['path'] = $form_state->getValue(['page', 'feed_properties', 'path']); + $display_options['title'] = $form_state->getValue(['page', 'title']); + $display_options['displays'] = [ 'default' => 'default', 'page_1' => 'page_1', - ); + ]; return $display_options; } @@ -1221,7 +1221,7 @@ protected function setOverrideOptions(array $options, DisplayPluginBase $display * @param bool $unset * Should the view be removed from the list of validated views. * - * @return \Drupal\views_ui\ViewUI $view + * @return \Drupal\views_ui\ViewUI * The validated view object. */ protected function retrieveValidatedView(array $form, FormStateInterface $form_state, $unset = TRUE) { diff --git a/core/modules/views/src/ResultRow.php b/core/modules/views/src/ResultRow.php index 39febcf6..da55038f 100644 --- a/core/modules/views/src/ResultRow.php +++ b/core/modules/views/src/ResultRow.php @@ -34,7 +34,7 @@ class ResultRow { * @param array $values * (optional) An array of values to add as properties on the object. */ - public function __construct(array $values = array()) { + public function __construct(array $values = []) { foreach ($values as $key => $value) { $this->{$key} = $value; } diff --git a/core/modules/views/src/Routing/ViewPageController.php b/core/modules/views/src/Routing/ViewPageController.php index dc9153c4..772103d3 100644 --- a/core/modules/views/src/Routing/ViewPageController.php +++ b/core/modules/views/src/Routing/ViewPageController.php @@ -22,9 +22,9 @@ class ViewPageController { * @return null|void */ public function handle($view_id, $display_id, RouteMatchInterface $route_match) { - $args = array(); + $args = []; $route = $route_match->getRouteObject(); - $map = $route->hasOption('_view_argument_map') ? $route->getOption('_view_argument_map') : array(); + $map = $route->hasOption('_view_argument_map') ? $route->getOption('_view_argument_map') : []; foreach ($map as $attribute => $parameter_name) { // Allow parameters be pulled from the request. diff --git a/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php b/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php index 123a9cb5..b01e9854 100644 --- a/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php +++ b/core/modules/views/src/Tests/AssertViewsCacheTagsTrait.php @@ -3,7 +3,7 @@ namespace Drupal\views\Tests; use Drupal\Core\Cache\Cache; -use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; +use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ViewExecutable; use Symfony\Component\HttpFoundation\Request; diff --git a/core/modules/views/src/Tests/DefaultViewsTest.php b/core/modules/views/src/Tests/DefaultViewsTest.php deleted file mode 100644 index 5c1f601b..00000000 --- a/core/modules/views/src/Tests/DefaultViewsTest.php +++ /dev/null @@ -1,220 +0,0 @@ - array(1), - 'taxonomy_term' => array(1), - 'glossary' => array('all'), - ); - - protected function setUp() { - parent::setUp(); - - $this->drupalPlaceBlock('page_title_block'); - - // Create Basic page node type. - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - - $vocabulary = Vocabulary::create([ - 'name' => $this->randomMachineName(), - 'description' => $this->randomMachineName(), - 'vid' => Unicode::strtolower($this->randomMachineName()), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - 'help' => '', - 'nodes' => array('page' => 'page'), - 'weight' => mt_rand(0, 10), - ]); - $vocabulary->save(); - - // Create a field. - $field_name = Unicode::strtolower($this->randomMachineName()); - - $handler_settings = array( - 'target_bundles' => array( - $vocabulary->id() => $vocabulary->id(), - ), - 'auto_create' => TRUE, - ); - $this->createEntityReferenceField('node', 'page', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - - // Create a time in the past for the archive. - $time = REQUEST_TIME - 3600; - - $this->addDefaultCommentField('node', 'page'); - - for ($i = 0; $i <= 10; $i++) { - $user = $this->drupalCreateUser(); - $term = $this->createTerm($vocabulary); - - $values = array('created' => $time, 'type' => 'page'); - $values[$field_name][]['target_id'] = $term->id(); - - // Make every other node promoted. - if ($i % 2) { - $values['promote'] = TRUE; - } - $values['body'][]['value'] = \Drupal::l('Node ' . 1, new Url('entity.node.canonical', ['node' => 1])); - - $node = $this->drupalCreateNode($values); - - $comment = array( - 'uid' => $user->id(), - 'status' => CommentInterface::PUBLISHED, - 'entity_id' => $node->id(), - 'entity_type' => 'node', - 'field_name' => 'comment' - ); - Comment::create($comment)->save(); - } - - // Some views, such as the "Who's Online" view, only return results if at - // least one user is logged in. - $account = $this->drupalCreateUser(array()); - $this->drupalLogin($account); - } - - /** - * Test that all Default views work as expected. - */ - public function testDefaultViews() { - // Get all default views. - $controller = $this->container->get('entity.manager')->getStorage('view'); - $views = $controller->loadMultiple(); - - foreach ($views as $name => $view_storage) { - $view = $view_storage->getExecutable(); - $view->initDisplay(); - foreach ($view->storage->get('display') as $display_id => $display) { - $view->setDisplay($display_id); - - // Add any args if needed. - if (array_key_exists($name, $this->viewArgMap)) { - $view->preExecute($this->viewArgMap[$name]); - } - - $this->assert(TRUE, format_string('View @view will be executed.', array('@view' => $view->storage->id()))); - $view->execute(); - - $tokens = array('@name' => $name, '@display_id' => $display_id); - $this->assertTrue($view->executed, format_string('@name:@display_id has been executed.', $tokens)); - - $count = count($view->result); - $this->assertTrue($count > 0, format_string('@count results returned', array('@count' => $count))); - $view->destroy(); - } - } - } - - /** - * Returns a new term with random properties in vocabulary $vid. - */ - function createTerm($vocabulary) { - $filter_formats = filter_formats(); - $format = array_pop($filter_formats); - $term = Term::create([ - 'name' => $this->randomMachineName(), - 'description' => $this->randomMachineName(), - // Use the first available text format. - 'format' => $format->id(), - 'vid' => $vocabulary->id(), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ]); - $term->save(); - return $term; - } - - /** - * Tests the archive view. - */ - public function testArchiveView() { - // Create additional nodes compared to the one in the setup method. - // Create two nodes in the same month, and one in each following month. - $node = array( - 'created' => 280299600, // Sun, 19 Nov 1978 05:00:00 GMT - ); - $this->drupalCreateNode($node); - $this->drupalCreateNode($node); - $node = array( - 'created' => 282891600, // Tue, 19 Dec 1978 05:00:00 GMT - ); - $this->drupalCreateNode($node); - $node = array( - 'created' => 285570000, // Fri, 19 Jan 1979 05:00:00 GMT - ); - $this->drupalCreateNode($node); - - $view = Views::getView('archive'); - $view->setDisplay('page_1'); - $this->executeView($view); - $columns = array('nid', 'created_year_month', 'num_records'); - $column_map = array_combine($columns, $columns); - // Create time of additional nodes created in the setup method. - $created_year_month = date('Ym', REQUEST_TIME - 3600); - $expected_result = array( - array( - 'nid' => 1, - 'created_year_month' => $created_year_month, - 'num_records' => 11, - ), - array( - 'nid' => 15, - 'created_year_month' => 197901, - 'num_records' => 1, - ), - array( - 'nid' => 14, - 'created_year_month' => 197812, - 'num_records' => 1, - ), - array( - 'nid' => 12, - 'created_year_month' => 197811, - 'num_records' => 2, - ), - ); - $this->assertIdenticalResultset($view, $expected_result, $column_map); - - $view->storage->setStatus(TRUE); - $view->save(); - \Drupal::service('router.builder')->rebuild(); - - $this->drupalGet('archive'); - $this->assertResponse(200); - } - -} diff --git a/core/modules/views/src/Tests/FieldApiDataTest.php b/core/modules/views/src/Tests/FieldApiDataTest.php index 3fd8a03f..f6d5159d 100644 --- a/core/modules/views/src/Tests/FieldApiDataTest.php +++ b/core/modules/views/src/Tests/FieldApiDataTest.php @@ -5,6 +5,11 @@ use Drupal\Component\Render\MarkupInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Tests\Views\FieldTestBase; +use Drupal\language\Entity\ConfigurableLanguage; +use Drupal\language\Entity\ContentLanguageSettings; +use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; +use Drupal\views\Views; /** * Tests the Field Views data. @@ -13,18 +18,35 @@ */ class FieldApiDataTest extends FieldTestBase { + /** + * {@inheritdoc} + */ + public static $modules = ['language']; + + /** + * {@inheritdoc} + */ + public static $testViews = ['test_field_config_translation_filter']; + + /** + * The nodes used by the translation filter tests. + * + * @var \Drupal\node\NodeInterface[] + */ + protected $translationNodes; + protected function setUp() { - parent::setUp(); + parent::setUp(FALSE); - $field_names = $this->setUpFieldStorages(1); + $field_names = $this->setUpFieldStorages(4); // Attach the field to nodes only. - $field = array( + $field = [ 'field_name' => $field_names[0], 'entity_type' => 'node', 'bundle' => 'page', 'label' => 'GiraffeA" label' - ); + ]; FieldConfig::create($field)->save(); // Attach the same field to a different bundle with a different label. @@ -38,11 +60,114 @@ protected function setUp() { // Now create some example nodes/users for the view result. for ($i = 0; $i < 5; $i++) { - $edit = array( - $field_names[0] => array((array('value' => $this->randomMachineName()))), - ); + $edit = [ + $field_names[0] => [(['value' => $this->randomMachineName()])], + ]; $nodes[] = $this->drupalCreateNode($edit); } + + $bundles = []; + $bundles[] = $bundle = NodeType::create(['type' => 'bundle1']); + $bundle->save(); + $bundles[] = $bundle = NodeType::create(['type' => 'bundle2']); + $bundle->save(); + + // Make the first field translatable on all bundles. + $field = FieldConfig::create([ + 'field_name' => $field_names[1], + 'entity_type' => 'node', + 'bundle' => $bundles[0]->id(), + 'translatable' => TRUE, + ]); + $field->save(); + $field = FieldConfig::create([ + 'field_name' => $field_names[1], + 'entity_type' => 'node', + 'bundle' => $bundles[1]->id(), + 'translatable' => TRUE, + ]); + $field->save(); + + // Make the second field not translatable on any bundle. + $field = FieldConfig::create([ + 'field_name' => $field_names[2], + 'entity_type' => 'node', + 'bundle' => $bundles[0]->id(), + 'translatable' => FALSE, + ]); + $field->save(); + $field = FieldConfig::create([ + 'field_name' => $field_names[2], + 'entity_type' => 'node', + 'bundle' => $bundles[1]->id(), + 'translatable' => FALSE, + ]); + $field->save(); + + // Make the last field translatable on some bundles. + $field = FieldConfig::create([ + 'field_name' => $field_names[3], + 'entity_type' => 'node', + 'bundle' => $bundles[0]->id(), + 'translatable' => TRUE, + ]); + $field->save(); + $field = FieldConfig::create([ + 'field_name' => $field_names[3], + 'entity_type' => 'node', + 'bundle' => $bundles[1]->id(), + 'translatable' => FALSE, + ]); + $field->save(); + + // Create some example content. + ConfigurableLanguage::create([ + 'id' => 'es', + ])->save(); + ConfigurableLanguage::create([ + 'id' => 'fr', + ])->save(); + + $config = ContentLanguageSettings::loadByEntityTypeBundle('node', $bundles[0]->id()); + $config->setDefaultLangcode('es') + ->setLanguageAlterable(TRUE) + ->save(); + $config = ContentLanguageSettings::loadByEntityTypeBundle('node', $bundles[1]->id()); + $config->setDefaultLangcode('es') + ->setLanguageAlterable(TRUE) + ->save(); + + $node = Node::create([ + 'title' => 'Test title ' . $bundles[0]->id(), + 'type' => $bundles[0]->id(), + 'langcode' => 'es', + $field_names[1] => 'field name 1: es', + $field_names[2] => 'field name 2: es', + $field_names[3] => 'field name 3: es', + ]); + $node->save(); + $this->translationNodes[] = $node; + $translation = $node->addTranslation('fr'); + $translation->{$field_names[1]}->value = 'field name 1: fr'; + $translation->{$field_names[3]}->value = 'field name 3: fr'; + $translation->title->value = $node->title->value; + $translation->save(); + + $node = Node::create([ + 'title' => 'Test title ' . $bundles[1]->id(), + 'type' => $bundles[1]->id(), + 'langcode' => 'es', + $field_names[1] => 'field name 1: es', + $field_names[2] => 'field name 2: es', + $field_names[3] => 'field name 3: es', + ]); + $node->save(); + $this->translationNodes[] = $node; + $translation = $node->addTranslation('fr'); + $translation->{$field_names[1]}->value = 'field name 1: fr'; + $translation->title->value = $node->title->value; + $translation->save(); + } /** @@ -50,7 +175,7 @@ protected function setUp() { * * We check data structure for both node and node revision tables. */ - function testViewsData() { + public function testViewsData() { $table_mapping = \Drupal::entityManager()->getStorage('node')->getTableMapping(); $field_storage = $this->fieldStorages[0]; $current_table = $table_mapping->getDedicatedDataTableName($field_storage); @@ -63,25 +188,25 @@ function testViewsData() { $this->assertTrue(isset($data[$current_table]['table']['join']['node_field_data'])); $this->assertTrue(isset($data[$revision_table]['table']['join']['node_field_revision'])); - $expected_join = array( + $expected_join = [ 'table' => $current_table, 'left_field' => 'nid', 'field' => 'entity_id', - 'extra' => array( - array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), - array('left_field' => 'langcode', 'field' => 'langcode'), - ), - ); + 'extra' => [ + ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], + ['left_field' => 'langcode', 'field' => 'langcode'], + ], + ]; $this->assertEqual($expected_join, $data[$current_table]['table']['join']['node_field_data']); - $expected_join = array( + $expected_join = [ 'table' => $revision_table, 'left_field' => 'vid', 'field' => 'revision_id', - 'extra' => array( - array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), - array('left_field' => 'langcode', 'field' => 'langcode'), - ), - ); + 'extra' => [ + ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], + ['left_field' => 'langcode', 'field' => 'langcode'], + ], + ]; $this->assertEqual($expected_join, $data[$revision_table]['table']['join']['node_field_revision']); // Test click sortable. @@ -124,7 +249,7 @@ function testViewsData() { */ protected function getViewsData() { $views_data = $this->container->get('views.views_data'); - $data = array(); + $data = []; // Check the table and the joins of the first field. // Attached to node only. @@ -137,4 +262,118 @@ protected function getViewsData() { return $data; } + /** + * Tests filtering entries with different translatabilty. + */ + public function testEntityFieldFilter() { + $map = [ + 'nid' => 'nid', + 'langcode' => 'langcode', + ]; + + $view = Views::getView('test_field_config_translation_filter'); + + // Filter by 'field name 1: es'. + $view->setDisplay('embed_1'); + $this->executeView($view); + $expected = [ + [ + 'nid' => $this->translationNodes[0]->id(), + 'langcode' => 'es', + ], + [ + 'nid' => $this->translationNodes[1]->id(), + 'langcode' => 'es', + ], + ]; + + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + + // Filter by 'field name 1: fr'. + $view->setDisplay('embed_2'); + $this->executeView($view); + $expected = [ + [ + 'nid' => $this->translationNodes[0]->id(), + 'langcode' => 'fr', + ], + [ + 'nid' => $this->translationNodes[1]->id(), + 'langcode' => 'fr', + ], + ]; + + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + + // Filter by 'field name 2: es'. + $view->setDisplay('embed_3'); + $this->executeView($view); + $expected = [ + [ + 'nid' => $this->translationNodes[0]->id(), + 'langcode' => 'es', + ], + [ + 'nid' => $this->translationNodes[0]->id(), + 'langcode' => 'fr', + ], + [ + 'nid' => $this->translationNodes[1]->id(), + 'langcode' => 'es', + ], + [ + 'nid' => $this->translationNodes[1]->id(), + 'langcode' => 'fr', + ], + ]; + + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + + // Filter by 'field name 2: fr', which doesn't exist. + $view->setDisplay('embed_4'); + $this->executeView($view); + $expected = []; + + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + + // Filter by 'field name 3: es'. + $view->setDisplay('embed_5'); + $this->executeView($view); + $expected = [ + [ + 'nid' => $this->translationNodes[0]->id(), + 'langcode' => 'es', + ], + [ + 'nid' => $this->translationNodes[1]->id(), + 'langcode' => 'es', + ], + // Why is this one returned? + [ + 'nid' => $this->translationNodes[1]->id(), + 'langcode' => 'fr', + ], + ]; + + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + + // Filter by 'field name 3: fr'. + $view->setDisplay('embed_6'); + $this->executeView($view); + $expected = [ + [ + 'nid' => $this->translationNodes[0]->id(), + 'langcode' => 'fr', + ], + ]; + + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + } + } diff --git a/core/modules/views/src/Tests/Handler/AreaTest.php b/core/modules/views/src/Tests/Handler/AreaTest.php deleted file mode 100644 index 454ab58d..00000000 --- a/core/modules/views/src/Tests/Handler/AreaTest.php +++ /dev/null @@ -1,251 +0,0 @@ -enableViewsTestModule(); - } - - protected function viewsData() { - $data = parent::viewsData(); - $data['views']['test_example'] = array( - 'title' => 'Test Example area', - 'help' => 'A area handler which just exists for tests.', - 'area' => array( - 'id' => 'test_example' - ) - ); - - return $data; - } - - - /** - * Tests the generic UI of a area handler. - */ - public function testUI() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); - $this->drupalLogin($admin_user); - - $types = array('header', 'footer', 'empty'); - $labels = array(); - foreach ($types as $type) { - $edit_path = 'admin/structure/views/nojs/handler/test_example_area/default/' . $type . '/test_example'; - - // First setup an empty label. - $this->drupalPostForm($edit_path, array(), t('Apply')); - $this->assertText('Test Example area'); - - // Then setup a no empty label. - $labels[$type] = $this->randomMachineName(); - $this->drupalPostForm($edit_path, array('options[admin_label]' => $labels[$type]), t('Apply')); - // Make sure that the new label appears on the site. - $this->assertText($labels[$type]); - - // Test that the settings (empty/admin_label) are accessible. - $this->drupalGet($edit_path); - $this->assertField('options[admin_label]'); - if ($type !== 'empty') { - $this->assertField('options[empty]'); - } - } - } - - /** - * Tests the rendering of an area. - */ - public function testRenderArea() { - $view = Views::getView('test_example_area'); - $view->initHandlers(); - - // Insert a random string with XSS injection in the test area plugin. - // Ensure that the string is rendered for the header, footer, and empty - // text with the markup properly escaped. - $header_string = '

          ' . $this->randomMachineName() . '

          '; - $footer_string = '

          ' . $this->randomMachineName() . '

          '; - $empty_string = '

          ' . $this->randomMachineName() . '

          '; - - $view->header['test_example']->options['string'] = $header_string; - $view->header['test_example']->options['empty'] = TRUE; - - $view->footer['test_example']->options['string'] = $footer_string; - $view->footer['test_example']->options['empty'] = TRUE; - - $view->empty['test_example']->options['string'] = $empty_string; - - // Check whether the strings exist in the output and are sanitized. - $output = $view->preview(); - $output = $this->container->get('renderer')->renderRoot($output); - $this->assertTrue(strpos($output, Xss::filterAdmin($header_string)) !== FALSE, 'Views header exists in the output and is sanitized'); - $this->assertTrue(strpos($output, Xss::filterAdmin($footer_string)) !== FALSE, 'Views footer exists in the output and is sanitized'); - $this->assertTrue(strpos($output, Xss::filterAdmin($empty_string)) !== FALSE, 'Views empty exists in the output and is sanitized'); - $this->assertTrue(strpos($output, 'initHandlers(); - - // Set example empty text. - $view->empty['test_example']->options['string'] = '

          ' . $this->randomMachineName() . '

          '; - - $xpath = '//div[contains(@class, :class)]'; - - // Verify that the empty header and footer sections have not been rendered. - $output = $view->preview(); - $html = $this->container->get('renderer')->renderRoot($output); - $this->setRawContent($html); - $this->assertEqual(0, count($this->xpath($xpath, [':class' => 'view-header']))); - $this->assertEqual(0, count($this->xpath($xpath, [':class' => 'view-footer']))); - - // Set example header text. - $view->header['test_example']->options['string'] = '

          ' . $this->randomMachineName() . '

          '; - $view->header['test_example']->options['empty'] = TRUE; - - // Set example footer text. - $view->footer['test_example']->options['string'] = '

          ' . $this->randomMachineName() . '

          '; - $view->footer['test_example']->options['empty'] = TRUE; - - // Verify that the header and footer sections have been rendered. - $output = $view->preview(); - $html = $this->container->get('renderer')->renderRoot($output); - $this->setRawContent($html); - $this->assertEqual(1, count($this->xpath($xpath, [':class' => 'view-header']))); - $this->assertEqual(1, count($this->xpath($xpath, [':class' => 'view-footer']))); - } - - /** - * Tests the access for an area. - */ - public function testAreaAccess() { - // Test with access denied for the area handler. - $view = Views::getView('test_example_area_access'); - $view->initDisplay(); - $view->initHandlers(); - $handlers = $view->display_handler->getHandlers('empty'); - $this->assertEqual(0, count($handlers)); - - $output = $view->preview(); - $output = \Drupal::service('renderer')->renderRoot($output); - // The area output should not be present since access was denied. - $this->assertFalse(strpos($output, 'a custom string') !== FALSE); - $view->destroy(); - - // Test with access granted for the area handler. - $view = Views::getView('test_example_area_access'); - $view->initDisplay(); - $view->display_handler->overrideOption('empty', [ - 'test_example' => [ - 'field' => 'test_example', - 'id' => 'test_example', - 'table' => 'views', - 'plugin_id' => 'test_example', - 'string' => 'a custom string', - 'custom_access' => TRUE, - ], - ]); - $view->initHandlers(); - $handlers = $view->display_handler->getHandlers('empty'); - - $output = $view->preview(); - $output = \Drupal::service('renderer')->renderRoot($output); - $this->assertTrue(strpos($output, 'a custom string') !== FALSE); - $this->assertEqual(1, count($handlers)); - } - - /** - * Tests global tokens. - */ - public function testRenderAreaToken() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); - $this->drupalLogin($admin_user); - - $view = Views::getView('test_example_area'); - $view->initHandlers(); - - $this->drupalGet('admin/structure/views/nojs/handler/test_example_area/default/empty/test_example'); - - // Test that the list is token present. - $element = $this->xpath('//ul[@class="global-tokens"]'); - $this->assertTrue($element, 'Token list found on the options form.'); - - $empty_handler = &$view->empty['test_example']; - - // Test the list of available tokens. - $available = $empty_handler->getAvailableGlobalTokens(); - foreach (array('site', 'view') as $type) { - $this->assertTrue(!empty($available[$type]) && is_array($available[$type])); - // Test that each item exists in the list. - foreach ($available[$type] as $token => $info) { - $this->assertText("[$type:$token]"); - } - } - - // Test the rendered output of a token. - $empty_handler->options['string'] = '[site:name]'; - - // Test we have the site:name token in the output. - $output = $view->preview(); - $output = $this->container->get('renderer')->renderRoot($output); - $expected = \Drupal::token()->replace('[site:name]'); - $this->assertTrue(strpos($output, $expected) !== FALSE); - } - - /** - * Tests overriding the view title using the area title handler. - */ - public function testTitleArea() { - $view = Views::getView('frontpage'); - $view->initDisplay('page_1'); - - // Add the title area handler to the empty area. - $view->displayHandlers->get('page_1')->overrideOption('empty', array( - 'title' => array( - 'id' => 'title', - 'table' => 'views', - 'field' => 'title', - 'admin_label' => '', - 'empty' => '0', - 'title' => 'Overridden title', - 'plugin_id' => 'title', - ), - )); - - $view->storage->enable()->save(); - - $this->drupalGet('node'); - $this->assertText('Overridden title', 'Overridden title found.'); - } - -} diff --git a/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php b/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php deleted file mode 100644 index f2082f0a..00000000 --- a/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php +++ /dev/null @@ -1,64 +0,0 @@ -drupalCreateUser(['access content overview', 'administer nodes', 'bypass node access']); - $this->drupalLogin($admin_user); - } - - /** - * Tests dropbutton field. - */ - public function testDropbutton() { - // Create some test nodes. - $nodes = array(); - for ($i = 0; $i < 5; $i++) { - $nodes[] = $this->drupalCreateNode(); - } - - $this->drupalGet('test-dropbutton'); - foreach ($nodes as $node) { - $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', array(':path' => '/node/' . $node->id(), ':title' => $node->label())); - $this->assertEqual(count($result), 1, 'Just one node title link was found.'); - $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', array(':path' => '/node/' . $node->id(), ':title' => t('Custom Text'))); - $this->assertEqual(count($result), 1, 'Just one custom link was found.'); - } - - // Check if the dropbutton.js library is available. - $this->drupalGet('admin/content'); - $this->assertRaw('dropbutton.js'); - // Check if the dropbutton.js library is available on a cached page to - // ensure that bubbleable metadata is not lost in the views render workflow. - $this->drupalGet('admin/content'); - $this->assertRaw('dropbutton.js'); - } - -} diff --git a/core/modules/views/src/Tests/Handler/FilterDateTest.php b/core/modules/views/src/Tests/Handler/FilterDateTest.php deleted file mode 100644 index 2045b8af..00000000 --- a/core/modules/views/src/Tests/Handler/FilterDateTest.php +++ /dev/null @@ -1,155 +0,0 @@ -nodes = array(); - $this->nodes[] = $this->drupalCreateNode(array('created' => 100000)); - $this->nodes[] = $this->drupalCreateNode(array('created' => 200000)); - $this->nodes[] = $this->drupalCreateNode(array('created' => 300000)); - $this->nodes[] = $this->drupalCreateNode(array('created' => time() + 86400)); - - $this->map = array( - 'nid' => 'nid', - ); - } - - /** - * Runs other test methods. - */ - public function testDateFilter() { - $this->_testOffset(); - $this->_testBetween(); - $this->_testUiValidation(); - } - - /** - * Test the general offset functionality. - */ - protected function _testOffset() { - $view = Views::getView('test_filter_date_between'); - - // Test offset for simple operator. - $view->initHandlers(); - $view->filter['created']->operator = '>'; - $view->filter['created']->value['type'] = 'offset'; - $view->filter['created']->value['value'] = '+1 hour'; - $view->executeDisplay('default'); - $expected_result = array( - array('nid' => $this->nodes[3]->id()), - ); - $this->assertIdenticalResultset($view, $expected_result, $this->map); - $view->destroy(); - - // Test offset for between operator. - $view->initHandlers(); - $view->filter['created']->operator = 'between'; - $view->filter['created']->value['type'] = 'offset'; - $view->filter['created']->value['max'] = '+2 days'; - $view->filter['created']->value['min'] = '+1 hour'; - $view->executeDisplay('default'); - $expected_result = array( - array('nid' => $this->nodes[3]->id()), - ); - $this->assertIdenticalResultset($view, $expected_result, $this->map); - } - - /** - * Tests the filter operator between/not between. - */ - protected function _testBetween() { - $view = Views::getView('test_filter_date_between'); - - // Test between with min and max. - $view->initHandlers(); - $view->filter['created']->operator = 'between'; - $view->filter['created']->value['min'] = format_date(150000, 'custom', 'Y-m-d H:i:s'); - $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); - $view->executeDisplay('default'); - $expected_result = array( - array('nid' => $this->nodes[1]->id()), - ); - $this->assertIdenticalResultset($view, $expected_result, $this->map); - $view->destroy(); - - // Test between with just max. - $view->initHandlers(); - $view->filter['created']->operator = 'between'; - $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); - $view->executeDisplay('default'); - $expected_result = array( - array('nid' => $this->nodes[0]->id()), - array('nid' => $this->nodes[1]->id()), - ); - $this->assertIdenticalResultset($view, $expected_result, $this->map); - $view->destroy(); - - // Test not between with min and max. - $view->initHandlers(); - $view->filter['created']->operator = 'not between'; - $view->filter['created']->value['min'] = format_date(100000, 'custom', 'Y-m-d H:i:s'); - $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); - - $view->executeDisplay('default'); - $expected_result = array( - array('nid' => $this->nodes[2]->id()), - array('nid' => $this->nodes[3]->id()), - ); - $this->assertIdenticalResultset($view, $expected_result, $this->map); - $view->destroy(); - - // Test not between with just max. - $view->initHandlers(); - $view->filter['created']->operator = 'not between'; - $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); - $view->executeDisplay('default'); - $expected_result = array( - array('nid' => $this->nodes[2]->id()), - array('nid' => $this->nodes[3]->id()), - ); - $this->assertIdenticalResultset($view, $expected_result, $this->map); - } - - /** - * Make sure the validation callbacks works. - */ - protected function _testUiValidation() { - - $this->drupalLogin($this->drupalCreateUser(array('administer views', 'administer site configuration'))); - - $this->drupalGet('admin/structure/views/view/test_filter_date_between/edit'); - $this->drupalGet('admin/structure/views/nojs/handler/test_filter_date_between/default/filter/created'); - - $edit = array(); - // Generate a definitive wrong value, which should be checked by validation. - $edit['options[value][value]'] = $this->randomString() . '-------'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertText(t('Invalid date format.'), 'Make sure that validation is run and the invalidate date format is identified.'); - } - -} diff --git a/core/modules/views/src/Tests/Handler/HandlerTest.php b/core/modules/views/src/Tests/Handler/HandlerTest.php deleted file mode 100644 index 8ff4033b..00000000 --- a/core/modules/views/src/Tests/Handler/HandlerTest.php +++ /dev/null @@ -1,401 +0,0 @@ -drupalCreateContentType(array('type' => 'page')); - $this->addDefaultCommentField('node', 'page'); - $this->enableViewsTestModule(); - } - - /** - * {@inheritdoc} - */ - protected function viewsData() { - $data = parent::viewsData(); - // Override the name handler to be able to call placeholder() from outside. - $data['views_test_data']['name']['field']['id'] = 'test_field'; - - // Setup one field with an access callback and one with an access callback - // and arguments. - $data['views_test_data']['access_callback'] = $data['views_test_data']['id']; - $data['views_test_data']['access_callback_arguments'] = $data['views_test_data']['id']; - foreach (ViewExecutable::getHandlerTypes() as $type => $info) { - if (isset($data['views_test_data']['access_callback'][$type]['id'])) { - $data['views_test_data']['access_callback'][$type]['access callback'] = 'views_test_data_handler_test_access_callback'; - - $data['views_test_data']['access_callback_arguments'][$type]['access callback'] = 'views_test_data_handler_test_access_callback_argument'; - $data['views_test_data']['access_callback_arguments'][$type]['access arguments'] = array(TRUE); - } - } - - return $data; - } - - /** - * Tests the breakString method. - */ - public function testBreakString() { - // Check defaults. - $this->assertEqual((object) array('value' => array(), 'operator' => NULL), HandlerBase::breakString('')); - - // Test ors - $handler = HandlerBase::breakString('word1 word2+word'); - $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); - $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakString('word1+word2+word'); - $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); - $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakString('word1 word2 word'); - $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); - $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakString('word-1+word-2+word'); - $this->assertEqualValue(array('word-1', 'word-2', 'word'), $handler); - $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakString('wõrd1+wõrd2+wõrd'); - $this->assertEqualValue(array('wõrd1', 'wõrd2', 'wõrd'), $handler); - $this->assertEqual('or', $handler->operator); - - // Test ands. - $handler = HandlerBase::breakString('word1,word2,word'); - $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); - $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakString('word1 word2,word'); - $this->assertEqualValue(array('word1 word2', 'word'), $handler); - $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakString('word1,word2 word'); - $this->assertEqualValue(array('word1', 'word2 word'), $handler); - $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakString('word-1,word-2,word'); - $this->assertEqualValue(array('word-1', 'word-2', 'word'), $handler); - $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakString('wõrd1,wõrd2,wõrd'); - $this->assertEqualValue(array('wõrd1', 'wõrd2', 'wõrd'), $handler); - $this->assertEqual('and', $handler->operator); - - // Test a single word - $handler = HandlerBase::breakString('word'); - $this->assertEqualValue(array('word'), $handler); - $this->assertEqual('and', $handler->operator); - - $s1 = $this->randomMachineName(); - // Generate three random numbers which can be used below; - $n1 = rand(0, 100); - $n2 = rand(0, 100); - $n3 = rand(0, 100); - - // Test "or"s. - $handlerBase = HandlerBase::breakString("$s1 $n2+$n3"); - $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1+$n2+$n3"); - $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1 $n2 $n3"); - $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1 $n2++$n3"); - $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - // Test "and"s. - $handlerBase = HandlerBase::breakString("$s1,$n2,$n3"); - $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); - $this->assertEqual('and', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1,,$n2,$n3"); - $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); - $this->assertEqual('and', $handlerBase->operator); - - // Enforce int values. - $handlerBase = HandlerBase::breakString("$n1,$n2,$n3", TRUE); - $this->assertEqualValue(array($n1, $n2, $n3), $handlerBase); - $this->assertEqual('and', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$n1+$n2+$n3", TRUE); - $this->assertEqualValue(array($n1, $n2, $n3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1,$n2,$n3", TRUE); - $this->assertEqualValue(array((int) $s1, $n2, $n3), $handlerBase); - $this->assertEqual('and', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1+$n2+$n3", TRUE); - $this->assertEqualValue(array((int) $s1, $n2, $n3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - // Generate three random decimals which can be used below; - $d1 = rand(0, 10) / 10; - $d2 = rand(0, 10) / 10; - $d3 = rand(0, 10) / 10; - - // Test "or"s. - $handlerBase = HandlerBase::breakString("$s1 $d1+$d2"); - $this->assertEqualValue(array($s1, $d1, $d2), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1+$d1+$d3"); - $this->assertEqualValue(array($s1, $d1, $d3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1 $d2 $d3"); - $this->assertEqualValue(array($s1, $d2, $d3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1 $d2++$d3"); - $this->assertEqualValue(array($s1, $d2, $d3), $handlerBase); - $this->assertEqual('or', $handlerBase->operator); - - // Test "and"s. - $handlerBase = HandlerBase::breakString("$s1,$d2,$d3"); - $this->assertEqualValue(array($s1, $d2, $d3), $handlerBase); - $this->assertEqual('and', $handlerBase->operator); - - $handlerBase = HandlerBase::breakString("$s1,,$d2,$d3"); - $this->assertEqualValue(array($s1, $d2, $d3), $handlerBase); - $this->assertEqual('and', $handlerBase->operator); - } - - /** - * Tests the order of handlers is the same before and after saving. - */ - public function testHandlerWeights() { - $handler_types = array('fields', 'filters', 'sorts'); - - $view = Views::getView('test_view_handler_weight'); - $view->initDisplay(); - - // Store the order of handlers before saving the view. - $original_order = array(); - foreach ($handler_types as $type) { - $original_order[$type] = array_keys($view->display_handler->getOption($type)); - } - - // Save the view and see if our filters are in the same order. - $view->save(); - $view = views::getView('test_view_handler_weight'); - $view->initDisplay(); - - foreach ($handler_types as $type) { - $loaded_order = array_keys($view->display_handler->getOption($type)); - $this->assertIdentical($original_order[$type], $loaded_order); - } - } - - /** - * Check to see if a value is the same as the value on a certain handler. - * - * @param $expected - * The expected value to check. - * @param \Drupal\views\Plugin\views\ViewsHandlerInterface $handler - * The handler that has the $handler->value property to compare with first. - * @param string $message - * The message to display along with the assertion. - * @param string $group - * The type of assertion - examples are "Browser", "PHP". - * - * @return bool - * TRUE if the assertion succeeded, FALSE otherwise. - */ - protected function assertEqualValue($expected, $handler, $message = '', $group = 'Other') { - if (empty($message)) { - $message = t('Comparing @first and @second', array('@first' => implode(',', $expected), '@second' => implode(',', $handler->value))); - } - - return $this->assert($expected == $handler->value, $message, $group); - } - - /** - * Tests the relationship ui for field/filter/argument/relationship. - */ - public function testRelationshipUI() { - $views_admin = $this->drupalCreateUser(array('administer views')); - $this->drupalLogin($views_admin); - - // Make sure the link to the field options exists. - $handler_options_path = 'admin/structure/views/nojs/handler/test_handler_relationships/default/field/title'; - $view_edit_path = 'admin/structure/views/view/test_handler_relationships/edit'; - $this->drupalGet($view_edit_path); - $this->assertLinkByHref($handler_options_path); - - // The test view has a relationship to node_revision so the field should - // show a relationship selection. - - $this->drupalGet($handler_options_path); - $relationship_name = 'options[relationship]'; - $this->assertFieldByName($relationship_name); - - // Check for available options. - $xpath = $this->constructFieldXpath('name', $relationship_name); - $fields = $this->xpath($xpath); - $options = array(); - foreach ($fields as $field) { - $items = $this->getAllOptions($field); - foreach ($items as $item) { - $options[] = $item->attributes()->value; - } - } - $expected_options = array('none', 'nid'); - $this->assertEqual($options, $expected_options); - - // Remove the relationship and make sure no relationship option appears. - $this->drupalPostForm('admin/structure/views/nojs/handler/test_handler_relationships/default/relationship/nid', array(), t('Remove')); - $this->drupalGet($handler_options_path); - $this->assertNoFieldByName($relationship_name, NULL, 'Make sure that no relationship option is available'); - - // Create a view of comments with node relationship. - View::create(['base_table' => 'comment_field_data', 'id' => 'test_get_entity_type'])->save(); - $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_get_entity_type/default/relationship', ['name[comment_field_data.node]' => 'comment_field_data.node'], t('Add and configure relationships')); - $this->drupalPostForm(NULL, [], t('Apply')); - // Add a content type filter. - $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_get_entity_type/default/filter', ['name[node_field_data.type]' => 'node_field_data.type'], t('Add and configure filter criteria')); - $this->assertOptionSelected('edit-options-relationship', 'node'); - $this->drupalPostForm(NULL, ['options[value][page]' => 'page'], t('Apply')); - // Check content type filter options. - $this->drupalGet('admin/structure/views/nojs/handler/test_get_entity_type/default/filter/type'); - $this->assertOptionSelected('edit-options-relationship', 'node'); - $this->assertFieldChecked('edit-options-value-page'); - } - - /** - * Tests the relationship method on the base class. - */ - public function testSetRelationship() { - $view = Views::getView('test_handler_relationships'); - $view->setDisplay(); - // Setup a broken relationship. - $view->addHandler('default', 'relationship', $this->randomMachineName(), $this->randomMachineName(), array(), 'broken_relationship'); - // Setup a valid relationship. - $view->addHandler('default', 'relationship', 'comment_field_data', 'node', array('relationship' => 'cid'), 'valid_relationship'); - $view->initHandlers(); - $field = $view->field['title']; - - $field->options['relationship'] = NULL; - $field->setRelationship(); - $this->assertFalse($field->relationship, 'Make sure that an empty relationship does not create a relationship on the field.'); - - $field->options['relationship'] = $this->randomMachineName(); - $field->setRelationship(); - $this->assertFalse($field->relationship, 'Make sure that a random relationship does not create a relationship on the field.'); - - $field->options['relationship'] = 'broken_relationship'; - $field->setRelationship(); - $this->assertFalse($field->relationship, 'Make sure that a broken relationship does not create a relationship on the field.'); - - $field->options['relationship'] = 'valid_relationship'; - $field->setRelationship(); - $this->assertFalse(!empty($field->relationship), 'Make sure that the relationship alias was not set without building a views query before.'); - - // Remove the invalid relationship. - unset($view->relationship['broken_relationship']); - - $view->build(); - $field->setRelationship(); - $this->assertEqual($field->relationship, $view->relationship['valid_relationship']->alias, 'Make sure that a valid relationship does create the right relationship query alias.'); - } - - /** - * Tests the placeholder function. - * - * @see \Drupal\views\Plugin\views\HandlerBase::placeholder() - */ - public function testPlaceholder() { - $view = Views::getView('test_view'); - $view->initHandlers(); - $view->initQuery(); - - $handler = $view->field['name']; - $table = $handler->table; - $field = $handler->field; - $string = ':' . $table . '_' . $field; - - // Make sure the placeholder variables are like expected. - $this->assertEqual($handler->getPlaceholder(), $string); - $this->assertEqual($handler->getPlaceholder(), $string . 1); - $this->assertEqual($handler->getPlaceholder(), $string . 2); - - // Set another table/field combination and make sure there are new - // placeholders. - $table = $handler->table = $this->randomMachineName(); - $field = $handler->field = $this->randomMachineName(); - $string = ':' . $table . '_' . $field; - - // Make sure the placeholder variables are like expected. - $this->assertEqual($handler->getPlaceholder(), $string); - $this->assertEqual($handler->getPlaceholder(), $string . 1); - $this->assertEqual($handler->getPlaceholder(), $string . 2); - } - - /** - * Tests access to a handler. - * - * @see views_test_data_handler_test_access_callback - */ - public function testAccess() { - $view = Views::getView('test_handler_test_access'); - $views_data = $this->viewsData(); - $views_data = $views_data['views_test_data']; - - // Enable access to callback only field and deny for callback + arguments. - $this->config('views_test_data.tests')->set('handler_access_callback', TRUE)->save(); - $this->config('views_test_data.tests')->set('handler_access_callback_argument', FALSE)->save(); - $view->initDisplay(); - $view->initHandlers(); - - foreach ($views_data['access_callback'] as $type => $info) { - if (!in_array($type, array('title', 'help'))) { - $this->assertTrue($view->field['access_callback'] instanceof HandlerBase, 'Make sure the user got access to the access_callback field '); - $this->assertFalse(isset($view->field['access_callback_arguments']), 'Make sure the user got no access to the access_callback_arguments field '); - } - } - - // Enable access to the callback + argument handlers and deny for callback. - $this->config('views_test_data.tests')->set('handler_access_callback', FALSE)->save(); - $this->config('views_test_data.tests')->set('handler_access_callback_argument', TRUE)->save(); - $view->destroy(); - $view->initDisplay(); - $view->initHandlers(); - - foreach ($views_data['access_callback'] as $type => $info) { - if (!in_array($type, array('title', 'help'))) { - $this->assertFalse(isset($view->field['access_callback']), 'Make sure the user got no access to the access_callback field '); - $this->assertTrue($view->field['access_callback_arguments'] instanceof HandlerBase, 'Make sure the user got access to the access_callback_arguments field '); - } - } - } - -} diff --git a/core/modules/views/src/Tests/Handler/HandlerTestBase.php b/core/modules/views/src/Tests/Handler/HandlerTestBase.php index 5345f47b..da4ecece 100644 --- a/core/modules/views/src/Tests/Handler/HandlerTestBase.php +++ b/core/modules/views/src/Tests/Handler/HandlerTestBase.php @@ -2,10 +2,13 @@ namespace Drupal\views\Tests\Handler; +@trigger_error('\Drupal\views\Tests\Handler\HandlerTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED); + use Drupal\views\Tests\ViewTestBase; /** - * @todo. + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\views\Functional\ViewTestBase. */ abstract class HandlerTestBase extends ViewTestBase { diff --git a/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php b/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php deleted file mode 100644 index 88db8b1b..00000000 --- a/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php +++ /dev/null @@ -1,106 +0,0 @@ -enableViewsTestModule(); - - $admin_user = $this->drupalCreateUser(array('administer site configuration')); - $this->drupalLogin($admin_user); - } - - - /** - * Tests the attachment plugin. - */ - public function testAttachment() { - $this->drupalGet('test-display-attachment'); - - $result = $this->xpath('//div[contains(@class, "view-content")]'); - $this->assertEqual(count($result), 2, 'Both actual view and the attachment is rendered.'); - - $result = $this->xpath('//div[contains(@class, "attachment-after")]'); - $this->assertEqual(count($result), 0, 'The attachment is not rendered after the actual view.'); - - $result = $this->xpath('//div[contains(@class, "attachment-before")]'); - $this->assertEqual(count($result), 1, 'The attachment is rendered before the actual view.'); - } - - /** - * Tests that nothing is output when the attachment displays are disabled. - */ - public function testDisabledAttachments() { - $this->drupalCreateContentType(['type' => 'page']); - $this->drupalCreateNode(); - - // Ensure that the feed_1 display is attached to the page_1 display. - $view = Views::getView('test_attached_disabled'); - $view->setDisplay('page_1'); - $attached_displays = $view->display_handler->getAttachedDisplays(); - $this->assertTrue(in_array('attachment_1', $attached_displays), 'The attachment_1 display is attached to the page display.'); - $this->assertTrue(in_array('attachment_2', $attached_displays), 'The attachment_2 display is attached to the page display.'); - - // Check that the attachments are output on the page display. - $this->drupalGet('test-attached-disabled'); - - $result = $this->xpath('//div[contains(@class, "view-content")]'); - $this->assertEqual(count($result), 3, 'The page view and the attachments are rendered.'); - - $result = $this->xpath('//div[contains(@class, "attachment-before")]'); - $this->assertEqual(count($result), 1, 'The attachment is rendered before the page view.'); - - $result = $this->xpath('//div[contains(@class, "attachment-after")]'); - $this->assertEqual(count($result), 1, 'The attachment is rendered after the page view.'); - - // Disable the attachment_1 display. - $view->displayHandlers->get('attachment_1')->setOption('enabled', FALSE); - $view->save(); - - // Test that the before attachment is not displayed. - $this->drupalGet('/test-attached-disabled'); - $result = $this->xpath('//div[contains(@class, "view-content")]'); - $this->assertEqual(count($result), 2, 'The page view and only one attachment are rendered.'); - - $result = $this->xpath('//div[contains(@class, "attachment-before")]'); - $this->assertEqual(count($result), 0, 'The attachment_1 is not rendered.'); - - // Disable the attachment_2 display. - $view->displayHandlers->get('attachment_2')->setOption('enabled', FALSE); - $view->save(); - - // Test that the after attachment is not displayed. - $this->drupalGet('/test-attached-disabled'); - $result = $this->xpath('//div[contains(@class, "view-content")]'); - $this->assertEqual(count($result), 1, 'The page view is rendered without attachments.'); - - $result = $this->xpath('//div[contains(@class, "attachment-after")]'); - $this->assertEqual(count($result), 0, 'The attachment_2 is not rendered.'); - } - -} diff --git a/core/modules/views/src/Tests/Plugin/DisplayFeedTest.php b/core/modules/views/src/Tests/Plugin/DisplayFeedTest.php index d31f457b..e8d25491 100644 --- a/core/modules/views/src/Tests/Plugin/DisplayFeedTest.php +++ b/core/modules/views/src/Tests/Plugin/DisplayFeedTest.php @@ -17,21 +17,21 @@ class DisplayFeedTest extends PluginTestBase { * * @var array */ - public static $testViews = array('test_display_feed', 'test_attached_disabled', 'test_feed_icon'); + public static $testViews = ['test_display_feed', 'test_attached_disabled', 'test_feed_icon']; /** * Modules to enable. * * @var array */ - public static $modules = array('block', 'node', 'views'); + public static $modules = ['block', 'node', 'views']; protected function setUp() { parent::setUp(); $this->enableViewsTestModule(); - $admin_user = $this->drupalCreateUser(array('administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); } @@ -45,10 +45,12 @@ public function testFeedOutput() { $node_title = 'This "cool" & "neat" article\'s title'; $node = $this->drupalCreateNode([ 'title' => $node_title, - 'body' => [0 => [ - 'value' => 'A paragraph', - 'format' => filter_default_format(), - ]], + 'body' => [ + 0 => [ + 'value' => 'A paragraph', + 'format' => filter_default_format(), + ], + ], ]); // Test the site name setting. @@ -101,13 +103,15 @@ public function testFeedFieldOutput() { // Verify a title with HTML entities is properly escaped. $node_title = 'This "cool" & "neat" article\'s title'; - $this->drupalCreateNode(array( + $this->drupalCreateNode([ 'title' => $node_title, - 'body' => [0 => [ - 'value' => 'A paragraph', - 'format' => filter_default_format(), - ]], - )); + 'body' => [ + 0 => [ + 'value' => 'A paragraph', + 'format' => filter_default_format(), + ], + ], + ]); $this->drupalGet('test-feed-display-fields.xml'); $result = $this->xpath('//title/a'); @@ -149,4 +153,24 @@ public function testDisabledFeed() { $this->assertResponse(404); } + /** + * Tests that the feed display works when the linked display is disabled. + */ + public function testDisabledLinkedDisplay() { + $view = Views::getView('test_attached_disabled'); + $view->setDisplay(); + // Disable the page and link the feed to the page. + $view->displayHandlers->get('feed_1')->setOption('link_display', 'page_1'); + $view->displayHandlers->get('page_1')->setOption('enabled', FALSE); + $view->save(); + + \Drupal::service('router.builder')->rebuild(); + + $this->drupalGet('test-attached-disabled'); + $this->assertResponse(404); + // Ensure the feed can still be reached. + $this->drupalGet('test-attached-disabled.xml'); + $this->assertResponse(200); + } + } diff --git a/core/modules/views/src/Tests/Plugin/DisplayTest.php b/core/modules/views/src/Tests/Plugin/DisplayTest.php deleted file mode 100644 index 3bbfd66b..00000000 --- a/core/modules/views/src/Tests/Plugin/DisplayTest.php +++ /dev/null @@ -1,425 +0,0 @@ -enableViewsTestModule(); - - $this->adminUser = $this->drupalCreateUser(array('administer views')); - $this->drupalLogin($this->adminUser); - - // Create 10 nodes. - for ($i = 0; $i <= 10; $i++) { - $this->drupalCreateNode(array('promote' => TRUE)); - } - } - - /** - * Tests the display test plugin. - * - * @see \Drupal\views_test_data\Plugin\views\display\DisplayTest - */ - public function testDisplayPlugin() { - /** @var \Drupal\Core\Render\RendererInterface $renderer */ - $renderer = $this->container->get('renderer'); - $view = Views::getView('test_view'); - - // Add a new 'display_test' display and test it's there. - $view->storage->addDisplay('display_test'); - $displays = $view->storage->get('display'); - - $this->assertTrue(isset($displays['display_test_1']), 'Added display has been assigned to "display_test_1"'); - - // Check the display options are like expected. - $options = array( - 'display_options' => array(), - 'display_plugin' => 'display_test', - 'id' => 'display_test_1', - 'display_title' => 'Display test', - 'position' => 1, - ); - $this->assertEqual($displays['display_test_1'], $options); - - // Add another one to ensure that position is counted up. - $view->storage->addDisplay('display_test'); - $displays = $view->storage->get('display'); - $options = array( - 'display_options' => array(), - 'display_plugin' => 'display_test', - 'id' => 'display_test_2', - 'display_title' => 'Display test 2', - 'position' => 2, - ); - $this->assertEqual($displays['display_test_2'], $options); - - // Move the second display before the first one in order to test custom - // sorting. - $displays['display_test_1']['position'] = 2; - $displays['display_test_2']['position'] = 1; - $view->storage->set('display', $displays); - $view->save(); - - $view->setDisplay('display_test_1'); - - $this->assertTrue($view->display_handler instanceof DisplayTestPlugin, 'The correct display handler instance is on the view object.'); - - // Check the test option. - $this->assertIdentical($view->display_handler->getOption('test_option'), ''); - - $output = $view->preview(); - $output = $renderer->renderRoot($output); - - $this->assertTrue(strpos($output, '

          ') !== FALSE, 'An empty value for test_option found in output.'); - - // Change this option and check the title of out output. - $view->display_handler->overrideOption('test_option', 'Test option title'); - $view->save(); - - $output = $view->preview(); - $output = $renderer->renderRoot($output); - - // Test we have our custom

          tag in the output of the view. - $this->assertTrue(strpos($output, '

          Test option title

          ') !== FALSE, 'The test_option value found in display output title.'); - - // Test that the display category/summary is in the UI. - $this->drupalGet('admin/structure/views/view/test_view/edit/display_test_1'); - $this->assertText('Display test settings'); - // Ensure that the order is as expected. - $result = $this->xpath('//ul[@id="views-display-menu-tabs"]/li'); - $this->assertEqual((string) $result[0]->a, 'Display test 2'); - $this->assertEqual((string) $result[1]->a, 'Display test'); - - $this->clickLink('Test option title'); - - $test_option = $this->randomString(); - $this->drupalPostForm(NULL, array('test_option' => $test_option), t('Apply')); - - // Check the new value has been saved by checking the UI summary text. - $this->drupalGet('admin/structure/views/view/test_view/edit/display_test_1'); - $this->assertLink($test_option); - - // Test the enable/disable status of a display. - $view->display_handler->setOption('enabled', FALSE); - $this->assertFalse($view->display_handler->isEnabled(), 'Make sure that isEnabled returns FALSE on a disabled display.'); - $view->display_handler->setOption('enabled', TRUE); - $this->assertTrue($view->display_handler->isEnabled(), 'Make sure that isEnabled returns TRUE on a disabled display.'); - } - - /** - * Tests the overriding of filter_groups. - */ - public function testFilterGroupsOverriding() { - $view = Views::getView('test_filter_groups'); - $view->initDisplay(); - - // mark is as overridden, yes FALSE, means overridden. - $view->displayHandlers->get('page')->setOverride('filter_groups', FALSE); - $this->assertFalse($view->displayHandlers->get('page')->isDefaulted('filter_groups'), "Make sure that 'filter_groups' is marked as overridden."); - $this->assertFalse($view->displayHandlers->get('page')->isDefaulted('filters'), "Make sure that 'filters'' is marked as overridden."); - } - - /** - * Tests the getAttachedDisplays method. - */ - public function testGetAttachedDisplays() { - $view = Views::getView('test_get_attach_displays'); - - // Both the feed_1 and the feed_2 display are attached to the page display. - $view->setDisplay('page_1'); - $this->assertEqual($view->display_handler->getAttachedDisplays(), array('feed_1', 'feed_2')); - - $view->setDisplay('feed_1'); - $this->assertEqual($view->display_handler->getAttachedDisplays(), array()); - } - - /** - * Tests the readmore functionality. - */ - public function testReadMore() { - /** @var \Drupal\Core\Render\RendererInterface $renderer */ - $renderer = $this->container->get('renderer'); - - if (!isset($this->options['validate']['type'])) { - return; - } - $expected_more_text = 'custom more text'; - - $view = Views::getView('test_display_more'); - $this->executeView($view); - - $output = $view->preview(); - $output = $renderer->renderRoot($output); - - $this->setRawContent($output); - $result = $this->xpath('//a[@class=:class]', array(':class' => 'more-link')); - $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.'); - $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.'); - - // Test the renderMoreLink method directly. This could be directly unit - // tested. - $more_link = $view->display_handler->renderMoreLink(); - $more_link = $renderer->renderRoot($more_link); - $this->setRawContent($more_link); - $result = $this->xpath('//a[@class=:class]', array(':class' => 'more-link')); - $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.'); - $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.'); - - // Test the useMoreText method directly. This could be directly unit - // tested. - $more_text = $view->display_handler->useMoreText(); - $this->assertEqual($more_text, $expected_more_text, 'The right more text is chosen.'); - - $view = Views::getView('test_display_more'); - $view->setDisplay(); - $view->display_handler->setOption('use_more', 0); - $this->executeView($view); - $output = $view->preview(); - $output = $renderer->renderRoot($output); - $this->setRawContent($output); - $result = $this->xpath('//a[@class=:class]', array(':class' => 'more-link')); - $this->assertTrue(empty($result), 'The more link is not shown.'); - - $view = Views::getView('test_display_more'); - $view->setDisplay(); - $view->display_handler->setOption('use_more', 0); - $view->display_handler->setOption('use_more_always', 0); - $view->display_handler->setOption('pager', array( - 'type' => 'some', - 'options' => array( - 'items_per_page' => 1, - 'offset' => 0, - ), - )); - $this->executeView($view); - $output = $view->preview(); - $output = $renderer->renderRoot($output); - $this->setRawContent($output); - $result = $this->xpath('//a[@class=:class]', array(':class' => 'more-link')); - $this->assertTrue(empty($result), 'The more link is not shown when view has more records.'); - - // Test the default value of use_more_always. - $view = View::create()->getExecutable(); - $this->assertTrue($view->getDisplay()->getOption('use_more_always'), 'Always display the more link by default.'); - } - - /** - * Tests the readmore validation. - */ - public function testReadMoreNoDisplay() { - $view = Views::getView('test_display_more'); - // Confirm that the view validates when there is a page display. - $errors = $view->validate(); - $this->assertTrue(empty($errors), 'More link validation has no errors.'); - - // Confirm that the view does not validate when the page display is disabled. - $view->setDisplay('page_1'); - $view->display_handler->setOption('enabled', FALSE); - $view->setDisplay('default'); - $errors = $view->validate(); - $this->assertTrue(!empty($errors), 'More link validation has some errors.'); - $this->assertEqual($errors['default'][0], 'Display "Master" uses a "more" link but there are no displays it can link to. You need to specify a custom URL.', 'More link validation has the right error.'); - - // Confirm that the view does not validate when the page display does not exist. - $view = Views::getView('test_view'); - $view->setDisplay('default'); - $view->display_handler->setOption('use_more', 1); - $errors = $view->validate(); - $this->assertTrue(!empty($errors), 'More link validation has some errors.'); - $this->assertEqual($errors['default'][0], 'Display "Master" uses a "more" link but there are no displays it can link to. You need to specify a custom URL.', 'More link validation has the right error.'); - } - - /** - * Tests invalid display plugins. - */ - public function testInvalidDisplayPlugins() { - $this->drupalGet('test_display_invalid'); - $this->assertResponse(200); - - // Change the page plugin id to an invalid one. Bypass the entity system - // so no menu rebuild was executed (so the path is still available). - $config = $this->config('views.view.test_display_invalid'); - $config->set('display.page_1.display_plugin', 'invalid'); - $config->save(); - - $this->drupalGet('test_display_invalid'); - $this->assertResponse(200); - $this->assertText('The "invalid" plugin does not exist.'); - - // Rebuild the router, and ensure that the path is not accessible anymore. - views_invalidate_cache(); - \Drupal::service('router.builder')->rebuildIfNeeded(); - - $this->drupalGet('test_display_invalid'); - $this->assertResponse(404); - - // Change the display plugin ID back to the correct ID. - $config = $this->config('views.view.test_display_invalid'); - $config->set('display.page_1.display_plugin', 'page'); - $config->save(); - - // Place the block display. - $block = $this->drupalPlaceBlock('views_block:test_display_invalid-block_1', array('label' => 'Invalid display')); - - $this->drupalGet(''); - $this->assertResponse(200); - $this->assertBlockAppears($block); - - // Change the block plugin ID to an invalid one. - $config = $this->config('views.view.test_display_invalid'); - $config->set('display.block_1.display_plugin', 'invalid'); - $config->save(); - - // Test the page is still displayed, the block not present, and has the - // plugin warning message. - $this->drupalGet(''); - $this->assertResponse(200); - $this->assertText('The "invalid" plugin does not exist.'); - $this->assertNoBlockAppears($block); - } - - /** - * Tests display validation when a required relationship is missing. - */ - public function testMissingRelationship() { - $view = Views::getView('test_exposed_relationship_admin_ui'); - - // Remove the relationship that is not used by other handlers. - $view->removeHandler('default', 'relationship', 'uid_1'); - $errors = $view->validate(); - // Check that no error message is shown. - $this->assertTrue(empty($errors['default']), 'No errors found when removing unused relationship.'); - - // Unset cached relationships (see DisplayPluginBase::getHandlers()) - unset($view->display_handler->handlers['relationship']); - - // Remove the relationship used by other handlers. - $view->removeHandler('default', 'relationship', 'uid'); - // Validate display - $errors = $view->validate(); - // Check that the error messages are shown. - $this->assertTrue(count($errors['default']) == 2, 'Error messages found for required relationship'); - $this->assertEqual($errors['default'][0], t('The %handler_type %handler uses a relationship that has been removed.', array('%handler_type' => 'field', '%handler' => 'User: Last login'))); - $this->assertEqual($errors['default'][1], t('The %handler_type %handler uses a relationship that has been removed.', array('%handler_type' => 'field', '%handler' => 'User: Created'))); - } - - /** - * Tests the outputIsEmpty method on the display. - */ - public function testOutputIsEmpty() { - $view = Views::getView('test_display_empty'); - $this->executeView($view); - $this->assertTrue(count($view->result) > 0, 'Ensure the result of the view is not empty.'); - $this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty.'); - $view->destroy(); - - // Add a filter, so the view result is empty. - $view->setDisplay('default'); - $item = array( - 'table' => 'views_test_data', - 'field' => 'id', - 'id' => 'id', - 'value' => array('value' => 7297) - ); - $view->setHandler('default', 'filter', 'id', $item); - $this->executeView($view); - $this->assertFalse(count($view->result), 'Ensure the result of the view is empty.'); - $this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty, because the empty text still appears.'); - $view->destroy(); - - // Remove the empty area, but mark the header area to still appear. - $view->removeHandler('default', 'empty', 'area'); - $item = $view->getHandler('default', 'header', 'area'); - $item['empty'] = TRUE; - $view->setHandler('default', 'header', 'area', $item); - $this->executeView($view); - $this->assertFalse(count($view->result), 'Ensure the result of the view is empty.'); - $this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty, because the header text still appears.'); - $view->destroy(); - - // Hide the header on empty results. - $item = $view->getHandler('default', 'header', 'area'); - $item['empty'] = FALSE; - $view->setHandler('default', 'header', 'area', $item); - $this->executeView($view); - $this->assertFalse(count($view->result), 'Ensure the result of the view is empty.'); - $this->assertTrue($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as empty.'); - } - - /** - * Test translation rendering settings based on entity translatability. - */ - public function testTranslationSetting() { - \Drupal::service('module_installer')->install(['file']); - \Drupal::service('router.builder')->rebuild(); - - // By default there should be no language settings. - $this->checkTranslationSetting(); - \Drupal::service('module_installer')->install(['language']); - - // Enabling the language module should not make a difference. - $this->checkTranslationSetting(); - - // Making the site multilingual should let translatable entity types support - // translation rendering. - ConfigurableLanguage::createFromLangcode('it')->save(); - $this->checkTranslationSetting(TRUE); - } - - /** - * Asserts a node and a file based view for the translation setting. - * - * The file based view should never expose that setting. The node based view - * should if the site is multilingual. - * - * @param bool $expected_node_translatability - * Whether the node based view should be expected to support translation - * settings. - */ - protected function checkTranslationSetting($expected_node_translatability = FALSE) { - $not_supported_text = 'The view is not based on a translatable entity type or the site is not multilingual.'; - $supported_text = 'All content that supports translations will be displayed in the selected language.'; - - $this->drupalGet('admin/structure/views/nojs/display/content/page_1/rendering_language'); - if ($expected_node_translatability) { - $this->assertNoText($not_supported_text); - $this->assertText($supported_text); - } - else { - $this->assertText($not_supported_text); - $this->assertNoText($supported_text); - } - - $this->drupalGet('admin/structure/views/nojs/display/files/page_1/rendering_language'); - $this->assertText($not_supported_text); - $this->assertNoText($supported_text); - } - -} diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php deleted file mode 100644 index 55957e59..00000000 --- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php +++ /dev/null @@ -1,401 +0,0 @@ -drupalCreateContentType(array('type' => 'article')); - - // Create some random nodes. - for ($i = 0; $i < 5; $i++) { - $this->drupalCreateNode(array('type' => 'article')); - } - } - - /** - * Tests the submit button. - */ - public function testSubmitButton() { - // Test the submit button value defaults to 'Apply'. - $this->drupalGet('test_exposed_form_buttons'); - $this->assertResponse(200); - $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', t('Apply')); - - // Rename the label of the submit button. - $view = Views::getView('test_exposed_form_buttons'); - $view->setDisplay(); - - $exposed_form = $view->display_handler->getOption('exposed_form'); - $exposed_form['options']['submit_button'] = $expected_label = $this->randomMachineName(); - $view->display_handler->setOption('exposed_form', $exposed_form); - $view->save(); - - // Make sure the submit button label changed. - $this->drupalGet('test_exposed_form_buttons'); - $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', $expected_label); - - // Make sure an empty label uses the default 'Apply' button value too. - $view = Views::getView('test_exposed_form_buttons'); - $view->setDisplay(); - - $exposed_form = $view->display_handler->getOption('exposed_form'); - $exposed_form['options']['submit_button'] = ''; - $view->display_handler->setOption('exposed_form', $exposed_form); - $view->save(); - - // Make sure the submit button label shows 'Apply'. - $this->drupalGet('test_exposed_form_buttons'); - $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', t('Apply')); - } - - /** - * Tests the exposed form with a non-standard identifier. - */ - public function testExposedIdentifier() { - // Alter the identifier of the filter to a random string. - $view = Views::getView('test_exposed_form_buttons'); - $view->setDisplay(); - $identifier = 'new_identifier'; - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'type' => [ - 'exposed' => TRUE, - 'field' => 'type', - 'id' => 'type', - 'table' => 'node_field_data', - 'plugin_id' => 'in_operator', - 'entity_type' => 'node', - 'entity_field' => 'type', - 'expose' => [ - 'identifier' => $identifier, - 'label' => 'Content: Type', - 'operator_id' => 'type_op', - 'reduce' => FALSE, - 'description' => 'Exposed overridden description' - ], - ] - )); - $view->save(); - $this->drupalGet('test_exposed_form_buttons', array('query' => array($identifier => 'article'))); - $this->assertFieldById(Html::getId('edit-' . $identifier), 'article', "Article type filter set with new identifier."); - - // Alter the identifier of the filter to a random string containing - // restricted characters. - $view = Views::getView('test_exposed_form_buttons'); - $view->setDisplay(); - $identifier = 'bad identifier'; - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'type' => [ - 'exposed' => TRUE, - 'field' => 'type', - 'id' => 'type', - 'table' => 'node_field_data', - 'plugin_id' => 'in_operator', - 'entity_type' => 'node', - 'entity_field' => 'type', - 'expose' => [ - 'identifier' => $identifier, - 'label' => 'Content: Type', - 'operator_id' => 'type_op', - 'reduce' => FALSE, - 'description' => 'Exposed overridden description' - ], - ] - )); - $this->executeView($view); - - $errors = $view->validate(); - $expected = [ - 'default' => ['This identifier has illegal characters.'], - 'page_1' => ['This identifier has illegal characters.'], - ]; - $this->assertEqual($errors, $expected); - } - - /** - * Tests whether the reset button works on an exposed form. - */ - public function testResetButton() { - // Test the button is hidden when there is no exposed input. - $this->drupalGet('test_exposed_form_buttons'); - $this->assertNoField('edit-reset'); - - $this->drupalGet('test_exposed_form_buttons', array('query' => array('type' => 'article'))); - // Test that the type has been set. - $this->assertFieldById('edit-type', 'article', 'Article type filter set.'); - - // Test the reset works. - $this->drupalGet('test_exposed_form_buttons', array('query' => array('op' => 'Reset'))); - $this->assertResponse(200); - // Test the type has been reset. - $this->assertFieldById('edit-type', 'All', 'Article type filter has been reset.'); - - // Test the button is hidden after reset. - $this->assertNoField('edit-reset'); - - // Test the reset works with type set. - $this->drupalGet('test_exposed_form_buttons', array('query' => array('type' => 'article', 'op' => 'Reset'))); - $this->assertResponse(200); - $this->assertFieldById('edit-type', 'All', 'Article type filter has been reset.'); - - // Test the button is hidden after reset. - $this->assertNoField('edit-reset'); - - // Rename the label of the reset button. - $view = Views::getView('test_exposed_form_buttons'); - $view->setDisplay(); - - $exposed_form = $view->display_handler->getOption('exposed_form'); - $exposed_form['options']['reset_button_label'] = $expected_label = $this->randomMachineName(); - $exposed_form['options']['reset_button'] = TRUE; - $view->display_handler->setOption('exposed_form', $exposed_form); - $view->save(); - - // Look whether the reset button label changed. - $this->drupalGet('test_exposed_form_buttons', array('query' => array('type' => 'article'))); - $this->assertResponse(200); - - $this->helperButtonHasLabel('edit-reset', $expected_label); - } - - /** - * Tests the exposed form markup. - */ - public function testExposedFormRender() { - $view = Views::getView('test_exposed_form_buttons'); - $this->executeView($view); - $exposed_form = $view->display_handler->getPlugin('exposed_form'); - $output = $exposed_form->renderExposedForm(); - $this->setRawContent(\Drupal::service('renderer')->renderRoot($output)); - - $this->assertFieldByXpath('//form/@id', $this->getExpectedExposedFormId($view), 'Expected form ID found.'); - - $view->setDisplay('page_1'); - $expected_action = $view->display_handler->getUrlInfo()->toString(); - $this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.'); - // Make sure the description is shown. - $result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', array(':id' => 'edit-type--description', ':description' => t('Exposed description'))); - $this->assertEqual(count($result), 1, 'Filter description was found.'); - } - - /** - * Tests overriding the default render option with checkboxes. - */ - public function testExposedFormRenderCheckboxes() { - // Make sure we have at least two options for node type. - $this->drupalCreateContentType(['type' => 'page']); - $this->drupalCreateNode(['type' => 'page']); - - // Use a test theme to convert multi-select elements into checkboxes. - \Drupal::service('theme_handler')->install(array('views_test_checkboxes_theme')); - $this->config('system.theme') - ->set('default', 'views_test_checkboxes_theme') - ->save(); - - // Set the "type" filter to multi-select. - $view = Views::getView('test_exposed_form_buttons'); - $filter = $view->getHandler('page_1', 'filter', 'type'); - $filter['expose']['multiple'] = TRUE; - $view->setHandler('page_1', 'filter', 'type', $filter); - - // Only display 5 items per page so we can test that paging works. - $display = &$view->storage->getDisplay('default'); - $display['display_options']['pager']['options']['items_per_page'] = 5; - - $view->save(); - $this->drupalGet('test_exposed_form_buttons'); - - $actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]'); - $this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.'); - $actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]'); - $this->assertEqual(count($actual), 1, 'Page option renders as a checkbox'); - - // Ensure that all results are displayed. - $rows = $this->xpath("//div[contains(@class, 'views-row')]"); - $this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.'); - - $this->clickLink('Page 2'); - $rows = $this->xpath("//div[contains(@class, 'views-row')]"); - $this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.'); - $this->assertNoText('An illegal choice has been detected. Please contact the site administrator.'); - } - - /** - * Tests the exposed block functionality. - */ - public function testExposedBlock() { - $this->drupalCreateContentType(['type' => 'page']); - $view = Views::getView('test_exposed_block'); - $view->setDisplay('page_1'); - $block = $this->drupalPlaceBlock('views_exposed_filter_block:test_exposed_block-page_1'); - $this->drupalGet('test_exposed_block'); - - // Test there is an exposed form in a block. - $xpath = $this->buildXPathQuery('//div[@id=:id]/form/@id', array(':id' => Html::getUniqueId('block-' . $block->id()))); - $this->assertFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'Expected form found in views block.'); - - // Test there is not an exposed form in the view page content area. - $xpath = $this->buildXPathQuery('//div[@class="view-content"]/form/@id', array(':id' => Html::getUniqueId('block-' . $block->id()))); - $this->assertNoFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'No exposed form found in views content region.'); - - // Test there is only one views exposed form on the page. - $elements = $this->xpath('//form[@id=:id]', array(':id' => $this->getExpectedExposedFormId($view))); - $this->assertEqual(count($elements), 1, 'One exposed form block found.'); - - // Test that the correct option is selected after form submission. - $this->assertCacheContext('url'); - $this->assertOptionSelected('edit-type', 'All'); - foreach (['All', 'article', 'page'] as $argument) { - $this->drupalGet('test_exposed_block', ['query' => ['type' => $argument]]); - $this->assertCacheContext('url'); - $this->assertOptionSelected('edit-type', $argument); - } - } - - /** - * Test the input required exposed form type. - */ - public function testInputRequired() { - $view = View::load('test_exposed_form_buttons'); - $display = &$view->getDisplay('default'); - $display['display_options']['exposed_form']['type'] = 'input_required'; - $view->save(); - - $this->drupalGet('test_exposed_form_buttons'); - $this->assertResponse(200); - $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', t('Apply')); - - // Ensure that no results are displayed. - $rows = $this->xpath("//div[contains(@class, 'views-row')]"); - $this->assertEqual(count($rows), 0, 'No rows are displayed by default when no input is provided.'); - - $this->drupalGet('test_exposed_form_buttons', array('query' => array('type' => 'article'))); - - // Ensure that results are displayed. - $rows = $this->xpath("//div[contains(@class, 'views-row')]"); - $this->assertEqual(count($rows), 5, 'All rows are displayed by default when input is provided.'); - } - - /** - * Test the "on demand text" for the input required exposed form type. - */ - public function testTextInputRequired() { - $view = Views::getView('test_exposed_form_buttons'); - $display = &$view->storage->getDisplay('default'); - $display['display_options']['exposed_form']['type'] = 'input_required'; - // Set up the "on demand text". - // @see https://www.drupal.org/node/535868 - $on_demand_text = 'Select any filter and click Apply to see results.'; - $display['display_options']['exposed_form']['options']['text_input_required'] = $on_demand_text; - $display['display_options']['exposed_form']['options']['text_input_required_format'] = filter_default_format(); - $view->save(); - - // Ensure that the "on demand text" is displayed when no exposed filters are - // applied. - $this->drupalGet('test_exposed_form_buttons'); - $this->assertText('Select any filter and click Apply to see results.'); - - // Ensure that the "on demand text" is not displayed when an exposed filter - // is applied. - $this->drupalGet('test_exposed_form_buttons', array('query' => array('type' => 'article'))); - $this->assertNoText($on_demand_text); - } - - /** - * Tests exposed forms with exposed sort and items per page. - */ - public function testExposedSortAndItemsPerPage() { - for ($i = 0; $i < 50; $i++) { - $entity = EntityTest::create([ - ]); - $entity->save(); - } - $contexts = [ - 'languages:language_interface', - 'entity_test_view_grants', - 'theme', - 'url.query_args', - 'languages:language_content' - ]; - - $this->drupalGet('test_exposed_form_sort_items_per_page'); - $this->assertCacheContexts($contexts); - $this->assertIds(range(1, 10, 1)); - - $this->drupalGet('test_exposed_form_sort_items_per_page', ['query' => ['sort_order' => 'DESC']]); - $this->assertCacheContexts($contexts); - $this->assertIds(range(50, 41, 1)); - - $this->drupalGet('test_exposed_form_sort_items_per_page', ['query' => ['sort_order' => 'DESC', 'items_per_page' => 25]]); - $this->assertCacheContexts($contexts); - $this->assertIds(range(50, 26, 1)); - - $this->drupalGet('test_exposed_form_sort_items_per_page', ['query' => ['sort_order' => 'DESC', 'items_per_page' => 25, 'offset' => 10]]); - $this->assertCacheContexts($contexts); - $this->assertIds(range(40, 16, 1)); - } - - /** - * Checks whether the specified ids are the ones displayed in the view output. - * - * @param int[] $ids - * The ids to check. - * - * @return bool - * TRUE if ids match, FALSE otherwise. - */ - protected function assertIds(array $ids) { - $elements = $this->cssSelect('div.view-test-exposed-form-sort-items-per-page div.views-row span.field-content'); - $actual_ids = []; - foreach ($elements as $element) { - $actual_ids[] = (int) $element; - } - - return $this->assertIdentical($ids, $actual_ids); - } - - /** - * Returns a views exposed form ID. - * - * @param \Drupal\views\ViewExecutable $view - * The view to create an ID for. - * - * @return string - * The form ID. - */ - protected function getExpectedExposedFormId(ViewExecutable $view) { - return Html::cleanCssIdentifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display); - } - -} diff --git a/core/modules/views/src/Tests/Plugin/PagerTest.php b/core/modules/views/src/Tests/Plugin/PagerTest.php deleted file mode 100644 index f922748e..00000000 --- a/core/modules/views/src/Tests/Plugin/PagerTest.php +++ /dev/null @@ -1,453 +0,0 @@ -getEditable('views.settings')->set('ui.show.master_display', TRUE)->save(); - - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); - $this->drupalLogin($admin_user); - // Test behavior described in - // https://www.drupal.org/node/652712#comment-2354918. - - $this->drupalGet('admin/structure/views/view/test_view/edit'); - - $edit = array( - 'pager[type]' => 'full', - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/pager', $edit, t('Apply')); - $edit = array( - 'pager_options[items_per_page]' => 20, - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/pager_options', $edit, t('Apply')); - $this->assertText('20 items'); - - // Change type and check whether the type is new type is stored. - $edit = array( - 'pager[type]' => 'mini', - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/pager', $edit, t('Apply')); - $this->drupalGet('admin/structure/views/view/test_view/edit'); - $this->assertText('Mini', 'Changed pager plugin, should change some text'); - - // Test behavior described in - // https://www.drupal.org/node/652712#comment-2354400. - $view = Views::getView('test_store_pager_settings'); - // Make it editable in the admin interface. - $view->save(); - - $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit'); - - $edit = array( - 'pager[type]' => 'full', - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/default/pager', $edit, t('Apply')); - $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit'); - $this->assertText('Full'); - - $edit = array( - 'pager_options[items_per_page]' => 20, - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/default/pager_options', $edit, t('Apply')); - $this->assertText('20 items'); - - // add new display and test the settings again, by override it. - $edit = array( ); - // Add a display and override the pager settings. - $this->drupalPostForm('admin/structure/views/view/test_store_pager_settings/edit', $edit, t('Add Page')); - $edit = array( - 'override[dropdown]' => 'page_1', - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager', $edit, t('Apply')); - - $edit = array( - 'pager[type]' => 'mini', - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager', $edit, t('Apply')); - $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit/page_1'); - $this->assertText('Mini', 'Changed pager plugin, should change some text'); - - $edit = array( - 'pager_options[items_per_page]' => 10, - ); - $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/default/pager_options', $edit, t('Apply')); - $this->assertText('10 items', 'The default value has been changed.'); - $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit/page_1'); - $this->assertText('20 items', 'The original value remains unchanged.'); - - // Test that the override element is only displayed on pager plugin selection form. - $this->drupalGet('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager'); - $this->assertFieldByName('override[dropdown]', 'page_1', 'The override element is displayed on plugin selection form.'); - $this->drupalGet('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager_options'); - $this->assertNoFieldByName('override[dropdown]', NULL, 'The override element is not displayed on plugin settings form.'); - } - - /** - * Tests the none-pager-query. - */ - public function testNoLimit() { - // Create 11 nodes and make sure that everyone is returned. - // We create 11 nodes, because the default pager plugin had 10 items per page. - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 11; $i++) { - $this->drupalCreateNode(); - } - $view = Views::getView('test_pager_none'); - $this->executeView($view); - $this->assertEqual(count($view->result), 11, 'Make sure that every item is returned in the result'); - - // Setup and test a offset. - $view = Views::getView('test_pager_none'); - $view->setDisplay(); - $pager = array( - 'type' => 'none', - 'options' => array( - 'offset' => 3, - ), - ); - $view->display_handler->setOption('pager', $pager); - $this->executeView($view); - - $this->assertEqual(count($view->result), 8, 'Make sure that every item beside the first three is returned in the result'); - - // Check some public functions. - $this->assertFalse($view->pager->usePager()); - $this->assertFalse($view->pager->useCountQuery()); - $this->assertEqual($view->pager->getItemsPerPage(), 0); - } - - public function testViewTotalRowsWithoutPager() { - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 23; $i++) { - $this->drupalCreateNode(); - } - - $view = Views::getView('test_pager_none'); - $view->get_total_rows = TRUE; - $this->executeView($view); - - $this->assertEqual($view->total_rows, 23, "'total_rows' is calculated when pager type is 'none' and 'get_total_rows' is TRUE."); - } - - /** - * Tests the some pager plugin. - */ - public function testLimit() { - // Create 11 nodes and make sure that everyone is returned. - // We create 11 nodes, because the default pager plugin had 10 items per page. - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 11; $i++) { - $this->drupalCreateNode(); - } - - $view = Views::getView('test_pager_some'); - $this->executeView($view); - $this->assertEqual(count($view->result), 5, 'Make sure that only a certain count of items is returned'); - - // Setup and test a offset. - $view = Views::getView('test_pager_some'); - $view->setDisplay(); - $pager = array( - 'type' => 'none', - 'options' => array( - 'offset' => 8, - 'items_per_page' => 5, - ), - ); - $view->display_handler->setOption('pager', $pager); - $this->executeView($view); - $this->assertEqual(count($view->result), 3, 'Make sure that only a certain count of items is returned'); - - // Check some public functions. - $this->assertFalse($view->pager->usePager()); - $this->assertFalse($view->pager->useCountQuery()); - } - - /** - * Tests the normal pager. - */ - public function testNormalPager() { - // Create 11 nodes and make sure that everyone is returned. - // We create 11 nodes, because the default pager plugin had 10 items per page. - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 11; $i++) { - $this->drupalCreateNode(); - } - - $view = Views::getView('test_pager_full'); - $this->executeView($view); - $this->assertEqual(count($view->result), 5, 'Make sure that only a certain count of items is returned'); - - // Setup and test a offset. - $view = Views::getView('test_pager_full'); - $view->setDisplay(); - $pager = array( - 'type' => 'full', - 'options' => array( - 'offset' => 8, - 'items_per_page' => 5, - ), - ); - $view->display_handler->setOption('pager', $pager); - $this->executeView($view); - $this->assertEqual(count($view->result), 3, 'Make sure that only a certain count of items is returned'); - - // Test items per page = 0 - $view = Views::getView('test_view_pager_full_zero_items_per_page'); - $this->executeView($view); - - $this->assertEqual(count($view->result), 11, 'All items are return'); - - // TODO test number of pages. - - // Test items per page = 0. - // Setup and test a offset. - $view = Views::getView('test_pager_full'); - $view->setDisplay(); - $pager = array( - 'type' => 'full', - 'options' => array( - 'offset' => 0, - 'items_per_page' => 0, - ), - ); - - $view->display_handler->setOption('pager', $pager); - $this->executeView($view); - $this->assertEqual($view->pager->getItemsPerPage(), 0); - $this->assertEqual(count($view->result), 11); - - // Test pager cache contexts. - $this->drupalGet('test_pager_full'); - $this->assertCacheContexts(['languages:language_interface', 'theme', 'timezone', 'url.query_args', 'user.node_grants:view']); - } - - /** - * Tests rendering with NULL pager. - */ - public function testRenderNullPager() { - // Create 11 nodes and make sure that everyone is returned. - // We create 11 nodes, because the default pager plugin had 10 items per page. - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 11; $i++) { - $this->drupalCreateNode(); - } - $view = Views::getView('test_pager_full'); - $this->executeView($view); - // Force the value again here. - $view->setAjaxEnabled(TRUE); - $view->pager = NULL; - $output = $view->render(); - $output = \Drupal::service('renderer')->renderRoot($output); - $this->assertEqual(preg_match('/
            /', $output), 0, 'The pager is not rendered.'); - } - - /** - * Test the api functions on the view object. - */ - function testPagerApi() { - $view = Views::getView('test_pager_full'); - $view->setDisplay(); - // On the first round don't initialize the pager. - - $this->assertEqual($view->getItemsPerPage(), NULL, 'If the pager is not initialized and no manual override there is no items per page.'); - $rand_number = rand(1, 5); - $view->setItemsPerPage($rand_number); - $this->assertEqual($view->getItemsPerPage(), $rand_number, 'Make sure getItemsPerPage uses the settings of setItemsPerPage.'); - - $this->assertEqual($view->getOffset(), NULL, 'If the pager is not initialized and no manual override there is no offset.'); - $rand_number = rand(1, 5); - $view->setOffset($rand_number); - $this->assertEqual($view->getOffset(), $rand_number, 'Make sure getOffset uses the settings of setOffset.'); - - $this->assertEqual($view->getCurrentPage(), NULL, 'If the pager is not initialized and no manual override there is no current page.'); - $rand_number = rand(1, 5); - $view->setCurrentPage($rand_number); - $this->assertEqual($view->getCurrentPage(), $rand_number, 'Make sure getCurrentPage uses the settings of set_current_page.'); - - $view->destroy(); - - // On this round enable the pager. - $view->initDisplay(); - $view->initQuery(); - $view->initPager(); - - $this->assertEqual($view->getItemsPerPage(), 5, 'Per default the view has 5 items per page.'); - $rand_number = rand(1, 5); - $view->setItemsPerPage($rand_number); - $rand_number = rand(6, 11); - $view->pager->setItemsPerPage($rand_number); - $this->assertEqual($view->getItemsPerPage(), $rand_number, 'Make sure getItemsPerPage uses the settings of setItemsPerPage.'); - - $this->assertEqual($view->getOffset(), 0, 'Per default a view has a 0 offset.'); - $rand_number = rand(1, 5); - $view->setOffset($rand_number); - $rand_number = rand(6, 11); - $view->pager->setOffset($rand_number); - $this->assertEqual($view->getOffset(), $rand_number, 'Make sure getOffset uses the settings of setOffset.'); - - $this->assertEqual($view->getCurrentPage(), 0, 'Per default the current page is 0.'); - $rand_number = rand(1, 5); - $view->setCurrentPage($rand_number); - $rand_number = rand(6, 11); - $view->pager->setCurrentPage($rand_number); - $this->assertEqual($view->getCurrentPage(), $rand_number, 'Make sure getCurrentPage uses the settings of set_current_page.'); - - // Set an invalid page and make sure the method takes care about it. - $view->setCurrentPage(-1); - $this->assertEqual($view->getCurrentPage(), 0, 'Make sure setCurrentPage always sets a valid page number.'); - } - - /** - * Tests translating the pager using config_translation. - */ - public function testPagerConfigTranslation() { - $view = Views::getView('content'); - $display = &$view->storage->getDisplay('default'); - $display['display_options']['pager']['options']['items_per_page'] = 5; - $view->save(); - - // Enable locale, config_translation and language module. - $this->container->get('module_installer')->install(array('locale', 'language', 'config_translation')); - $this->resetAll(); - - $admin_user = $this->drupalCreateUser(array('access content overview', 'administer nodes', 'bypass node access', 'translate configuration')); - $this->drupalLogin($admin_user); - - $langcode = 'nl'; - - // Add a default locale storage for this test. - $this->localeStorage = $this->container->get('locale.storage'); - - // Add Dutch language programmatically. - ConfigurableLanguage::createFromLangcode($langcode)->save(); - - $edit = array( - 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][first]' => '« Eerste', - 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][previous]' => '‹ Vorige', - 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][next]' => 'Volgende ›', - 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][last]' => 'Laatste »', - ); - $this->drupalPostForm('admin/structure/views/view/content/translate/nl/edit', $edit, t('Save translation')); - - // We create 11 nodes, this will give us 3 pages. - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 11; $i++) { - $this->drupalCreateNode(); - } - - // Go to the second page so we see both previous and next buttons. - $this->drupalGet('nl/admin/content', array('query' => array('page' => 1))); - // Translation mapping.. - $labels = array( - '« First' => '« Eerste', - '‹ Previous' => '‹ Vorige', - 'Next ›' => 'Volgende ›', - 'Last »' => 'Laatste »', - ); - foreach ($labels as $label => $translation) { - // Check if we can find the translation. - $this->assertRaw($translation); - } - } - - /** - * Tests translating the pager using locale. - */ - public function testPagerLocale() { - // Enable locale and language module. - $this->container->get('module_installer')->install(array('locale', 'language')); - $this->resetAll(); - $langcode = 'nl'; - - // Add a default locale storage for this test. - $this->localeStorage = $this->container->get('locale.storage'); - - // Add Dutch language programmatically. - ConfigurableLanguage::createFromLangcode($langcode)->save(); - - // Labels that need translations. - $labels = array( - '« First' => '« Eerste', - '‹ Previous' => '‹ Vorige', - 'Next ›' => 'Volgende ›', - 'Last »' => 'Laatste »', - ); - foreach ($labels as $label => $translation) { - // Create source string. - $source = $this->localeStorage->createString( - array( - 'source' => $label - ) - ); - $source->save(); - $this->createTranslation($source, $translation, $langcode); - } - - // We create 11 nodes, this will give us 3 pages. - $this->drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 11; $i++) { - $this->drupalCreateNode(); - } - - // Go to the second page so we see both previous and next buttons. - $this->drupalGet('nl/test_pager_full', array('query' => array('page' => 1))); - foreach ($labels as $label => $translation) { - // Check if we can find the translation. - $this->assertRaw($translation); - } - } - - /** - * Creates single translation for source string. - */ - protected function createTranslation($source, $translation, $langcode) { - $values = array( - 'lid' => $source->lid, - 'language' => $langcode, - 'translation' => $translation, - ); - return $this->localeStorage->createTranslation($values)->save(); - } - -} diff --git a/core/modules/views/src/Tests/Plugin/PluginTestBase.php b/core/modules/views/src/Tests/Plugin/PluginTestBase.php index 3b03dcd8..d8e22923 100644 --- a/core/modules/views/src/Tests/Plugin/PluginTestBase.php +++ b/core/modules/views/src/Tests/Plugin/PluginTestBase.php @@ -2,10 +2,13 @@ namespace Drupal\views\Tests\Plugin; +@trigger_error('\Drupal\views\Tests\Plugin\PluginTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED); + use Drupal\views\Tests\ViewTestBase; /** - * @todo. + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\views\Functional\ViewTestBase. */ abstract class PluginTestBase extends ViewTestBase { diff --git a/core/modules/views/src/Tests/Plugin/StyleOpmlTest.php b/core/modules/views/src/Tests/Plugin/StyleOpmlTest.php index 1b4a53de..4e84433d 100644 --- a/core/modules/views/src/Tests/Plugin/StyleOpmlTest.php +++ b/core/modules/views/src/Tests/Plugin/StyleOpmlTest.php @@ -15,14 +15,14 @@ class StyleOpmlTest extends PluginTestBase { * * @var array */ - public static $testViews = array('test_style_opml'); + public static $testViews = ['test_style_opml']; /** * Modules to enable. * * @var array */ - public static $modules = array('aggregator'); + public static $modules = ['aggregator']; /** * {@inheritdoc} @@ -32,7 +32,7 @@ protected function setUp() { $this->enableViewsTestModule(); - $admin_user = $this->drupalCreateUser(array('administer news feeds')); + $admin_user = $this->drupalCreateUser(['administer news feeds']); $this->drupalLogin($admin_user); } @@ -41,11 +41,11 @@ protected function setUp() { */ public function testOpmlOutput() { // Create a test feed. - $values = array( + $values = [ 'title' => $this->randomMachineName(10), 'url' => 'http://example.com/rss.xml', 'refresh' => '900', - ); + ]; $feed = $this->container->get('entity.manager') ->getStorage('aggregator_feed') ->create($values); diff --git a/core/modules/views/src/Tests/Plugin/StyleTableTest.php b/core/modules/views/src/Tests/Plugin/StyleTableTest.php deleted file mode 100644 index 9a3f25ef..00000000 --- a/core/modules/views/src/Tests/Plugin/StyleTableTest.php +++ /dev/null @@ -1,231 +0,0 @@ -enableViewsTestModule(); - } - - /** - * Test table caption/summary/description. - */ - public function testAccessibilitySettings() { - $this->drupalGet('test-table'); - - $result = $this->xpath('//caption'); - $this->assertTrue(count($result), 'The caption appears on the table.'); - $this->assertEqual(trim((string) $result[0]), 'caption-text'); - - $result = $this->xpath('//summary'); - $this->assertTrue(count($result), 'The summary appears on the table.'); - $this->assertEqual(trim((string) $result[0]), 'summary-text'); - - $result = $this->xpath('//caption/details'); - $this->assertTrue(count($result), 'The table description appears on the table.'); - $this->assertEqual(trim((string) $result[0]), 'description-text'); - - // Remove the caption and ensure the caption is not displayed anymore. - $view = View::load('test_table'); - $display = &$view->getDisplay('default'); - $display['display_options']['style']['options']['caption'] = ''; - $view->save(); - - $this->drupalGet('test-table'); - $result = $this->xpath('//caption'); - $this->assertFalse(trim((string) $result[0]), 'Ensure that the caption disappears.'); - - // Remove the table summary. - $display = &$view->getDisplay('default'); - $display['display_options']['style']['options']['summary'] = ''; - $view->save(); - - $this->drupalGet('test-table'); - $result = $this->xpath('//summary'); - $this->assertFalse(count($result), 'Ensure that the summary disappears.'); - - // Remove the table description. - $display = &$view->getDisplay('default'); - $display['display_options']['style']['options']['description'] = ''; - $view->save(); - - $this->drupalGet('test-table'); - $result = $this->xpath('//caption/details'); - $this->assertFalse(count($result), 'Ensure that the description disappears.'); - } - - /** - * Test table fields in columns. - */ - public function testFieldInColumns() { - $this->drupalGet('test-table'); - - // Ensure that both columns are in separate tds. - // Check for class " views-field-job ", because just "views-field-job" won't - // do: "views-field-job-1" would also contain "views-field-job". - // @see Drupal\system\Tests\Form\ElementTest::testButtonClasses(). - $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job ")]'); - $this->assertTrue(count($result), 'Ensure there is a td with the class views-field-job'); - $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job-1 ")]'); - $this->assertTrue(count($result), 'Ensure there is a td with the class views-field-job-1'); - - // Combine the second job-column with the first one, with ', ' as separator. - $view = View::load('test_table'); - $display = &$view->getDisplay('default'); - $display['display_options']['style']['options']['columns']['job_1'] = 'job'; - $display['display_options']['style']['options']['info']['job']['separator'] = ', '; - $view->save(); - - // Ensure that both columns are properly combined. - $this->drupalGet('test-table'); - - $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job views-field-job-1 ")]'); - $this->assertTrue(count($result), 'Ensure that the job column class names are joined into a single column'); - - $result = $this->xpath('//tbody/tr/td[contains(., "Drummer, Drummer")]'); - $this->assertTrue(count($result), 'Ensure the job column values are joined into a single column'); - } - - /** - * Test that a number with the value of "0" is displayed in the table. - */ - public function testNumericFieldVisible() { - // Adds a new datapoint in the views_test_data table to have a person with - // an age of zero. - $data_set = $this->dataSet(); - $query = db_insert('views_test_data') - ->fields(array_keys($data_set[0])); - $query->values(array( - 'name' => 'James McCartney', - 'age' => 0, - 'job' => 'Baby', - 'created' => gmmktime(6, 30, 10, 1, 1, 2000), - 'status' => 1, - )); - $query->execute(); - - $this->drupalGet('test-table'); - - $result = $this->xpath('//tbody/tr/td[contains(., "Baby")]'); - $this->assertTrue(count($result), 'Ensure that the baby is found.'); - - $result = $this->xpath('//tbody/tr/td[text()=0]'); - $this->assertTrue(count($result), 'Ensure that the baby\'s age is shown'); - } - - /** - * Test that empty columns are hidden when empty_column is set. - */ - public function testEmptyColumn() { - // Empty the 'job' data. - \Drupal::database()->update('views_test_data') - ->fields(['job' => '']) - ->execute(); - - $this->drupalGet('test-table'); - - // Test that only one of the job columns still shows. - $result = $this->xpath('//thead/tr/th/a[text()="Job"]'); - $this->assertEqual(count($result), 1, 'Ensure that empty column header is hidden.'); - - $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job-1 ")]'); - $this->assertEqual(count($result), 0, 'Ensure the empty table cells are hidden.'); - } - - /** - * Tests grouping by a field. - */ - public function testGrouping() { - /** @var \Drupal\views\ViewEntityInterface $view */ - $view = \Drupal::entityTypeManager()->getStorage('view')->load('test_table'); - // Get a reference to the display configuration so we can alter some - // specific style options. - $display = &$view->getDisplay('default'); - // Set job as the grouping field. - $display['display_options']['style']['options']['grouping'][0] = array( - 'field' => 'job', - 'rendered' => TRUE, - 'rendered_strip' => FALSE, - ); - // Clear the caption text, the rendered job field will be used as a caption. - $display['display_options']['style']['options']['caption'] = ''; - $display['display_options']['style']['options']['summary'] = ''; - $display['display_options']['style']['options']['description'] = ''; - $view->save(); - - // Add a record containing unsafe markup to be sure it's filtered out. - $unsafe_markup = ''; - $unsafe_markup_data = array( - 'name' => 'Marshall', - 'age' => 42, - 'job' => $unsafe_markup, - 'created' => gmmktime(0, 0, 0, 2, 15, 2001), - 'status' => 1, - ); - $database = $this->container->get('database'); - $database->insert('views_test_data') - ->fields(array_keys($unsafe_markup_data)) - ->values($unsafe_markup_data) - ->execute(); - - $this->drupalGet('test-table'); - $expected_captions = array( - 'Job: Speaker', - 'Job: Songwriter', - 'Job: Drummer', - 'Job: Singer', - 'Job: ' . $unsafe_markup, - ); - - // Ensure that we don't find the caption containing unsafe markup. - $this->assertNoRaw($unsafe_markup, "Didn't find caption containing unsafe markup."); - - // Ensure that all expected captions are found. - foreach ($expected_captions as $raw_caption) { - $this->assertEscaped($raw_caption); - } - - $display = &$view->getDisplay('default'); - // Remove the label from the grouping field. - $display['display_options']['fields']['job']['label'] = ''; - $view->save(); - - $this->drupalGet('test-table'); - $expected_captions = array( - 'Speaker', - 'Songwriter', - 'Drummer', - 'Singer', - $unsafe_markup, - ); - - // Ensure that we don't find the caption containing unsafe markup. - $this->assertNoRaw($unsafe_markup, "Didn't find caption containing unsafe markup."); - - // Ensure that all expected captions are found. - foreach ($expected_captions as $raw_caption) { - $this->assertEscaped($raw_caption); - } - } - -} diff --git a/core/modules/views/src/Tests/Update/EntityViewsDataUpdateFilledTest.php b/core/modules/views/src/Tests/Update/EntityViewsDataUpdateFilledTest.php deleted file mode 100644 index 57f219d9..00000000 --- a/core/modules/views/src/Tests/Update/EntityViewsDataUpdateFilledTest.php +++ /dev/null @@ -1,20 +0,0 @@ -databaseDumpFiles[0] = __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz'; - } - -} diff --git a/core/modules/views/src/Tests/ViewAjaxTest.php b/core/modules/views/src/Tests/ViewAjaxTest.php index c1705a5b..5a966a8f 100644 --- a/core/modules/views/src/Tests/ViewAjaxTest.php +++ b/core/modules/views/src/Tests/ViewAjaxTest.php @@ -17,7 +17,7 @@ class ViewAjaxTest extends ViewTestBase { * * @var array */ - public static $testViews = array('test_ajax_view'); + public static $testViews = ['test_ajax_view', 'test_view']; protected function setUp() { parent::setUp(); @@ -38,14 +38,14 @@ public function testAjaxView() { $this->assertEqual($drupal_settings['views']['ajaxViews'][$view_entry]['view_name'], 'test_ajax_view', 'The view\'s ajaxViews array entry has the correct \'view_name\' key.'); $this->assertEqual($drupal_settings['views']['ajaxViews'][$view_entry]['view_display_id'], 'page_1', 'The view\'s ajaxViews array entry has the correct \'view_display_id\' key.'); - $data = array(); + $data = []; $data['view_name'] = 'test_ajax_view'; $data['view_display_id'] = 'test_ajax_view'; - $post = array( + $post = [ 'view_name' => 'test_ajax_view', 'view_display_id' => 'page_1', - ); + ]; $post += $this->getAjaxPageStatePostData(); $response = $this->drupalPost('views/ajax', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $data = Json::decode($response); @@ -61,4 +61,14 @@ public function testAjaxView() { $this->assertEqual(count($result), 2, 'Ensure that two items are rendered in the HTML.'); } + /** + * Ensures that non-ajax view cannot be accessed via an ajax HTTP request. + */ + public function testNonAjaxViewViaAjax() { + $this->drupalPost('views/ajax', '', ['view_name' => 'test_ajax_view', 'view_display_id' => 'default'], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); + $this->assertResponse(200); + $this->drupalPost('views/ajax', '', ['view_name' => 'test_view', 'view_display_id' => 'default'], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); + $this->assertResponse(403); + } + } diff --git a/core/modules/views/src/Tests/ViewElementTest.php b/core/modules/views/src/Tests/ViewElementTest.php deleted file mode 100644 index 2ec2e679..00000000 --- a/core/modules/views/src/Tests/ViewElementTest.php +++ /dev/null @@ -1,173 +0,0 @@ -enableViewsTestModule(); - } - - /** - * Tests the rendered output and form output of a view element. - */ - public function testViewElement() { - /** @var \Drupal\Core\Render\RendererInterface $renderer */ - $renderer = $this->container->get('renderer'); - $view = Views::getView('test_view_embed'); - - // Get the render array, #embed must be FALSE since this is the default - // display. - $render = $view->buildRenderable(); - $this->assertEqual($render['#embed'], FALSE); - $this->setRawContent($renderer->renderRoot($render)); - - $xpath = $this->xpath('//div[@class="views-element-container"]'); - $this->assertTrue($xpath, 'The view container has been found in the rendered output.'); - - $xpath = $this->xpath('//div[@class="view-content"]'); - $this->assertTrue($xpath, 'The view content has been found in the rendered output.'); - // There should be 5 rows in the results. - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 5); - - // Test a form. - $this->drupalGet('views_test_data_element_form'); - - $xpath = $this->xpath('//div[@class="views-element-container js-form-wrapper form-wrapper"]'); - $this->assertTrue($xpath, 'The view container has been found on the form.'); - - $xpath = $this->xpath('//div[@class="view-content"]'); - $this->assertTrue($xpath, 'The view content has been found on the form.'); - // There should be 5 rows in the results. - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 5); - - // Add an argument and save the view. - $view->displayHandlers->get('default')->overrideOption('arguments', array( - 'age' => array( - 'default_action' => 'ignore', - 'title' => '', - 'default_argument_type' => 'fixed', - 'validate' => array( - 'type' => 'none', - 'fail' => 'not found', - ), - 'break_phrase' => FALSE, - 'not' => FALSE, - 'id' => 'age', - 'table' => 'views_test_data', - 'field' => 'age', - 'plugin_id' => 'numeric', - ) - )); - $view->save(); - - // Test the render array again. - $view = Views::getView('test_view_embed'); - $render = $view->buildRenderable(NULL, [25]); - $this->setRawContent($renderer->renderRoot($render)); - // There should be 1 row in the results, 'John' arg 25. - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 1); - - // Test that the form has the same expected result. - $this->drupalGet('views_test_data_element_form'); - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 1); - } - - /** - * Tests the rendered output and form output of a view element, using the - * embed display plugin. - */ - public function testViewElementEmbed() { - /** @var \Drupal\Core\Render\RendererInterface $renderer */ - $renderer = $this->container->get('renderer'); - $view = Views::getView('test_view_embed'); - - // Get the render array, #embed must be TRUE since this is an embed display. - $render = $view->buildRenderable('embed_1'); - $this->assertEqual($render['#embed'], TRUE); - $this->setRawContent($renderer->renderRoot($render)); - - $xpath = $this->xpath('//div[@class="views-element-container"]'); - $this->assertTrue($xpath, 'The view container has been found in the rendered output.'); - - $xpath = $this->xpath('//div[@class="view-content"]'); - $this->assertTrue($xpath, 'The view content has been found in the rendered output.'); - // There should be 5 rows in the results. - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 5); - - // Test a form. - $this->drupalGet('views_test_data_element_embed_form'); - - $xpath = $this->xpath('//div[@class="views-element-container js-form-wrapper form-wrapper"]'); - $this->assertTrue($xpath, 'The view container has been found on the form.'); - - $xpath = $this->xpath('//div[@class="view-content"]'); - $this->assertTrue($xpath, 'The view content has been found on the form.'); - // There should be 5 rows in the results. - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 5); - - // Add an argument and save the view. - $view->displayHandlers->get('default')->overrideOption('arguments', array( - 'age' => array( - 'default_action' => 'ignore', - 'title' => '', - 'default_argument_type' => 'fixed', - 'validate' => array( - 'type' => 'none', - 'fail' => 'not found', - ), - 'break_phrase' => FALSE, - 'not' => FALSE, - 'id' => 'age', - 'table' => 'views_test_data', - 'field' => 'age', - 'plugin_id' => 'numeric', - ) - )); - $view->save(); - - // Test the render array again. - $view = Views::getView('test_view_embed'); - $render = $view->buildRenderable('embed_1', [25]); - $this->setRawContent($renderer->renderRoot($render)); - // There should be 1 row in the results, 'John' arg 25. - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 1); - - // Test that the form has the same expected result. - $this->drupalGet('views_test_data_element_embed_form'); - $xpath = $this->xpath('//div[@class="view-content"]/div'); - $this->assertEqual(count($xpath), 1); - - // Tests the render array with an exposed filter. - $view = Views::getView('test_view_embed'); - $render = $view->buildRenderable('embed_2'); - $this->setRawContent($renderer->renderRoot($render)); - - // Ensure that the exposed form is rendered. - $this->assertEqual(1, count($this->xpath('//form[@class="views-exposed-form"]'))); - } - -} diff --git a/core/modules/views/src/Tests/ViewKernelTestBase.php b/core/modules/views/src/Tests/ViewKernelTestBase.php index 3a5df345..5a232859 100644 --- a/core/modules/views/src/Tests/ViewKernelTestBase.php +++ b/core/modules/views/src/Tests/ViewKernelTestBase.php @@ -26,7 +26,7 @@ abstract class ViewKernelTestBase extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'views', 'views_test_config', 'views_test_data', 'user'); + public static $modules = ['system', 'views', 'views_test_config', 'views_test_data', 'user']; /** * {@inheritdoc} @@ -39,11 +39,11 @@ abstract class ViewKernelTestBase extends KernelTestBase { protected function setUp($import_test_views = TRUE) { parent::setUp(); - $this->installSchema('system', array('sequences')); + $this->installSchema('system', ['sequences']); $this->setUpFixtures(); if ($import_test_views) { - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); } } @@ -56,13 +56,13 @@ protected function setUp($import_test_views = TRUE) { protected function setUpFixtures() { // First install the system module. Many Views have Page displays have menu // links, and for those to work, the system menus must already be present. - $this->installConfig(array('system')); + $this->installConfig(['system']); // Define the schema and views data variable before enabling the test module. \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition()); \Drupal::state()->set('views_test_data_views_data', $this->viewsData()); - $this->installConfig(array('views', 'views_test_config', 'views_test_data')); + $this->installConfig(['views', 'views_test_config', 'views_test_data']); foreach ($this->schemaDefinition() as $table => $schema) { $this->installSchema('views_test_data', $table); } @@ -113,7 +113,7 @@ protected function orderResultSet($result_set, $column, $reverse = FALSE) { * @param array $args * (optional) An array of the view arguments to use for the view. */ - protected function executeView($view, array $args = array()) { + protected function executeView($view, array $args = []) { $view->setDisplay(); $view->preExecute($args); $view->execute(); @@ -126,6 +126,8 @@ protected function executeView($view, array $args = array()) { /** * Returns the schema definition. + * + * @internal */ protected function schemaDefinition() { return ViewTestData::schemaDefinition(); diff --git a/core/modules/views/src/Tests/ViewResultAssertionTrait.php b/core/modules/views/src/Tests/ViewResultAssertionTrait.php index 62ae67ce..00501f5f 100644 --- a/core/modules/views/src/Tests/ViewResultAssertionTrait.php +++ b/core/modules/views/src/Tests/ViewResultAssertionTrait.php @@ -2,7 +2,7 @@ namespace Drupal\views\Tests; -use Drupal\views\Plugin\views\field\Field; +use Drupal\views\Plugin\views\field\EntityField; /** * Provides a class for assertions to check for the expected result of a View. @@ -30,7 +30,7 @@ trait ViewResultAssertionTrait { * @return bool * TRUE if the assertion succeeded, or FALSE otherwise. */ - protected function assertIdenticalResultset($view, $expected_result, $column_map = array(), $message = NULL) { + protected function assertIdenticalResultset($view, $expected_result, $column_map = [], $message = NULL) { return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, 'assertIdentical', $message); } @@ -53,7 +53,7 @@ protected function assertIdenticalResultset($view, $expected_result, $column_map * @return bool * TRUE if the assertion succeeded, or FALSE otherwise. */ - protected function assertNotIdenticalResultset($view, $expected_result, $column_map = array(), $message = NULL) { + protected function assertNotIdenticalResultset($view, $expected_result, $column_map = [], $message = NULL) { return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, 'assertNotIdentical', $message); } @@ -81,9 +81,9 @@ protected function assertNotIdenticalResultset($view, $expected_result, $column_ */ protected function assertIdenticalResultsetHelper($view, $expected_result, $column_map, $assert_method, $message = NULL) { // Convert $view->result to an array of arrays. - $result = array(); + $result = []; foreach ($view->result as $key => $value) { - $row = array(); + $row = []; foreach ($column_map as $view_column => $expected_column) { if (property_exists($value, $view_column)) { $row[$expected_column] = (string) $value->$view_column; @@ -91,7 +91,7 @@ protected function assertIdenticalResultsetHelper($view, $expected_result, $colu // The comparison will be done on the string representation of the value. // For entity fields we don't have the raw value. Let's try to fetch it // using the entity itself. - elseif (empty($value->$view_column) && isset($view->field[$expected_column]) && ($field = $view->field[$expected_column]) && $field instanceof Field) { + elseif (empty($value->$view_column) && isset($view->field[$expected_column]) && ($field = $view->field[$expected_column]) && $field instanceof EntityField) { $column = NULL; if (count(explode(':', $view_column)) == 2) { $column = explode(':', $view_column)[1]; @@ -104,7 +104,7 @@ protected function assertIdenticalResultsetHelper($view, $expected_result, $colu // Remove the columns we don't need from the expected result. foreach ($expected_result as $key => $value) { - $row = array(); + $row = []; foreach ($column_map as $expected_column) { // The comparison will be done on the string representation of the value. if (is_object($value)) { @@ -136,10 +136,10 @@ protected function assertIdenticalResultsetHelper($view, $expected_result, $colu // Do the actual comparison. if (!isset($message)) { $not = (strpos($assert_method, 'Not') ? 'not' : ''); - $message = format_string("Actual result
            \n@actual\n
            is $not identical to expected
            \n@expected\n
            ", array( + $message = format_string("Actual result
            \n@actual\n
            is $not identical to expected
            \n@expected\n
            ", [ '@actual' => var_export($result, TRUE), '@expected' => var_export($expected_result, TRUE), - )); + ]); } return $this->$assert_method($result, $expected_result, $message); } diff --git a/core/modules/views/src/Tests/ViewTestBase.php b/core/modules/views/src/Tests/ViewTestBase.php index 6ce34946..e1e5190f 100644 --- a/core/modules/views/src/Tests/ViewTestBase.php +++ b/core/modules/views/src/Tests/ViewTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\views\Tests; +@trigger_error('\Drupal\views\Tests\ViewTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED); + use Drupal\Core\Database\Query\SelectInterface; use Drupal\simpletest\WebTestBase; use Drupal\views\ViewExecutable; @@ -13,6 +15,9 @@ * When possible, ViewsKernelTestBase should be used instead. Both base classes * include the same methods. * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\views\Functional\ViewTestBase. + * * @see \Drupal\Tests\views\Kernel\ViewsKernelTestBase * @see \Drupal\simpletest\WebTestBase */ @@ -25,12 +30,12 @@ abstract class ViewTestBase extends WebTestBase { * * @var array */ - public static $modules = array('views', 'views_test_config'); + public static $modules = ['views', 'views_test_config']; protected function setUp($import_test_views = TRUE) { parent::setUp(); if ($import_test_views) { - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); } } @@ -45,7 +50,7 @@ protected function enableViewsTestModule() { \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition()); \Drupal::state()->set('views_test_data_views_data', $this->viewsData()); - \Drupal::service('module_installer')->install(array('views_test_data')); + \Drupal::service('module_installer')->install(['views_test_data']); $this->resetAll(); $this->rebuildContainer(); $this->container->get('module_handler')->reload(); @@ -91,7 +96,7 @@ protected function orderResultSet($result_set, $column, $reverse = FALSE) { * * @param string $id * The HTML ID of the button - * @param string $label. + * @param string $expected_label * The expected label for the button. * @param string $message * (optional) A custom message to display with the assertion. If no custom @@ -101,7 +106,7 @@ protected function orderResultSet($result_set, $column, $reverse = FALSE) { * TRUE if the assertion was successful, or FALSE on failure. */ protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') { - return $this->assertFieldById($id, $expected_label, t($message, array('%label' => $expected_label))); + return $this->assertFieldById($id, $expected_label, t($message, ['%label' => $expected_label])); } /** @@ -112,7 +117,7 @@ protected function helperButtonHasLabel($id, $expected_label, $message = 'Label * @param array $args * (optional) An array of the view arguments to use for the view. */ - protected function executeView(ViewExecutable $view, $args = array()) { + protected function executeView(ViewExecutable $view, $args = []) { // A view does not really work outside of a request scope, due to many // dependencies like the current user. $view->setDisplay(); @@ -127,6 +132,8 @@ protected function executeView(ViewExecutable $view, $args = array()) { /** * Returns the schema definition. + * + * @internal */ protected function schemaDefinition() { return ViewTestData::schemaDefinition(); diff --git a/core/modules/views/src/Tests/ViewTestData.php b/core/modules/views/src/Tests/ViewTestData.php index d54902d6..27ddf7c4 100644 --- a/core/modules/views/src/Tests/ViewTestData.php +++ b/core/modules/views/src/Tests/ViewTestData.php @@ -23,7 +23,7 @@ class ViewTestData { * The module directories to look in for test views. */ public static function createTestViews($class, array $modules) { - $views = array(); + $views = []; while ($class) { if (property_exists($class, 'testViews')) { $views = array_merge($views, $class::$testViews); @@ -58,59 +58,62 @@ public static function createTestViews($class, array $modules) { /** * Returns the schema definition. + * + * @internal */ public static function schemaDefinition() { - $schema['views_test_data'] = array( + $schema['views_test_data'] = [ 'description' => 'Basic test table for Views tests.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ), - 'name' => array( + ], + 'name' => [ 'description' => "A person's name", 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'age' => array( + ], + 'age' => [ 'description' => "The person's age", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => 0), - 'job' => array( + 'default' => 0, + ], + 'job' => [ 'description' => "The person's job", 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'Undefined', - ), - 'created' => array( + ], + 'created' => [ 'description' => "The creation date of this record", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'status' => array( + ], + 'status' => [ 'description' => "The status of this record", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'name' => array('name') - ), - 'indexes' => array( - 'ages' => array('age'), - ), - ); + ], + ], + 'primary key' => ['id'], + 'unique keys' => [ + 'name' => ['name'] + ], + 'indexes' => [ + 'ages' => ['age'], + ], + ]; return $schema; } @@ -119,109 +122,109 @@ public static function schemaDefinition() { */ public static function viewsData() { // Declaration of the base table. - $data['views_test_data']['table'] = array( + $data['views_test_data']['table'] = [ 'group' => 'Views test', - 'base' => array( + 'base' => [ 'field' => 'id', 'title' => 'Views test data', 'help' => 'Users who have created accounts on your site.', - ), - ); + ], + ]; // Declaration of fields. - $data['views_test_data']['id'] = array( + $data['views_test_data']['id'] = [ 'title' => 'ID', 'help' => 'The test data ID', - 'field' => array( + 'field' => [ 'id' => 'numeric', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'numeric', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['views_test_data']['name'] = array( + ], + ]; + $data['views_test_data']['name'] = [ 'title' => 'Name', 'help' => 'The name of the person', - 'field' => array( + 'field' => [ 'id' => 'standard', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'string', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'string', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['views_test_data']['age'] = array( + ], + ]; + $data['views_test_data']['age'] = [ 'title' => 'Age', 'help' => 'The age of the person', - 'field' => array( + 'field' => [ 'id' => 'numeric', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'numeric', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['views_test_data']['job'] = array( + ], + ]; + $data['views_test_data']['job'] = [ 'title' => 'Job', 'help' => 'The job of the person', - 'field' => array( + 'field' => [ 'id' => 'standard', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'string', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'string', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); - $data['views_test_data']['created'] = array( + ], + ]; + $data['views_test_data']['created'] = [ 'title' => 'Created', 'help' => 'The creation date of this record', - 'field' => array( + 'field' => [ 'id' => 'date', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'date', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'date', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'date', - ), - ); - $data['views_test_data']['status'] = array( + ], + ]; + $data['views_test_data']['status'] = [ 'title' => 'Status', 'help' => 'The status of this record', - 'field' => array( + 'field' => [ 'id' => 'boolean', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'boolean', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); + ], + ]; return $data; } @@ -229,43 +232,43 @@ public static function viewsData() { * Returns a very simple test dataset. */ public static function dataSet() { - return array( - array( + return [ + [ 'name' => 'John', 'age' => 25, 'job' => 'Singer', 'created' => gmmktime(0, 0, 0, 1, 1, 2000), 'status' => 1, - ), - array( + ], + [ 'name' => 'George', 'age' => 27, 'job' => 'Singer', 'created' => gmmktime(0, 0, 0, 1, 2, 2000), 'status' => 0, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, 'job' => 'Drummer', 'created' => gmmktime(6, 30, 30, 1, 1, 2000), 'status' => 1, - ), - array( + ], + [ 'name' => 'Paul', 'age' => 26, 'job' => 'Songwriter', 'created' => gmmktime(6, 0, 0, 1, 1, 2000), 'status' => 0, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, 'job' => 'Speaker', 'created' => gmmktime(6, 30, 10, 1, 1, 2000), 'status' => 1, - ), - ); + ], + ]; } } diff --git a/core/modules/views/src/Tests/Wizard/PagerTest.php b/core/modules/views/src/Tests/Wizard/PagerTest.php deleted file mode 100644 index 1dfc21e5..00000000 --- a/core/modules/views/src/Tests/Wizard/PagerTest.php +++ /dev/null @@ -1,61 +0,0 @@ -drupalCreateContentType(array('type' => 'page')); - for ($i = 0; $i < 12; $i++) { - $this->drupalCreateNode(array('created' => REQUEST_TIME - $i)); - } - - // Make a View that uses a pager. - $path_with_pager = 'test-view-with-pager'; - $this->createViewAtPath($path_with_pager, TRUE); - $this->drupalGet($path_with_pager); - - // This technique for finding the existence of a pager - // matches that used in Drupal\views_ui\Tests\PreviewTest.php. - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); - $this->assertTrue(!empty($elements), 'Full pager found.'); - - // Make a View that does not have a pager. - $path_with_no_pager = 'test-view-without-pager'; - $this->createViewAtPath($path_with_no_pager, FALSE); - $this->drupalGet($path_with_no_pager); - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); - $this->assertTrue(empty($elements), 'Full pager not found.'); - } - - /** - * Create a simple View of nodes at a given path. - * - * @param string $path - * The path at which the View should be created. - * @param bool $pager - * A boolean for whether the View created should use a pager. - */ - protected function createViewAtPath($path, $pager = TRUE) { - $view = array(); - $view['label'] = $this->randomMachineName(16); - $view['id'] = strtolower($this->randomMachineName(16)); - $view['show[sort]'] = 'node_field_data-created:ASC'; - $view['page[create]'] = 1; - $view['page[title]'] = $this->randomMachineName(16); - $view['page[path]'] = $path; - $view['page[pager]'] = $pager; - $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - } - -} diff --git a/core/modules/views/src/Tests/Wizard/WizardTestBase.php b/core/modules/views/src/Tests/Wizard/WizardTestBase.php index e00b0182..ba7509c8 100644 --- a/core/modules/views/src/Tests/Wizard/WizardTestBase.php +++ b/core/modules/views/src/Tests/Wizard/WizardTestBase.php @@ -2,10 +2,15 @@ namespace Drupal\views\Tests\Wizard; +@trigger_error('\Drupal\views\Tests\Wizard\WizardTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\Wizard\WizardTestBase', E_USER_DEPRECATED); + use Drupal\views\Tests\ViewTestBase; /** * Views UI wizard tests. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\views\Functional\Wizard\WizardTestBase. */ abstract class WizardTestBase extends ViewTestBase { @@ -14,13 +19,13 @@ abstract class WizardTestBase extends ViewTestBase { * * @var array */ - public static $modules = array('node', 'views_ui', 'block', 'rest'); + public static $modules = ['node', 'views_ui', 'block', 'rest']; protected function setUp() { parent::setUp(); // Create and log in a user with administer views permission. - $views_admin = $this->drupalCreateUser(array('administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions')); + $views_admin = $this->drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions']); $this->drupalLogin($views_admin); $this->drupalPlaceBlock('local_actions_block'); } diff --git a/core/modules/views/src/ViewAccessControlHandler.php b/core/modules/views/src/ViewAccessControlHandler.php deleted file mode 100644 index f28148b8..00000000 --- a/core/modules/views/src/ViewAccessControlHandler.php +++ /dev/null @@ -1,29 +0,0 @@ -getValues(). * * @var array */ - public $exposed_raw_input = array(); + public $exposed_raw_input = []; /** * Used to store views that were previously running if we recurse. * * @var \Drupal\views\ViewExecutable[] */ - public $old_view = array(); + public $old_view = []; /** * To avoid recursion in views embedded into areas. * * @var \Drupal\views\ViewExecutable[] */ - public $parent_views = array(); + public $parent_views = []; /** * Whether this view is an attachment to another view. @@ -435,6 +439,13 @@ class ViewExecutable implements \Serializable { */ protected $baseEntityType; + /** + * Holds all necessary data for proper unserialization. + * + * @var array + */ + protected $serializationData; + /** * Constructs a new ViewExecutable object. * @@ -681,7 +692,7 @@ public function getExposedInput() { $this->exposed_input = \Drupal::request()->query->all(); // unset items that are definitely not our input: - foreach (array('page', 'q') as $key) { + foreach (['page', 'q'] as $key) { if (isset($this->exposed_input[$key])) { unset($this->exposed_input[$key]); } @@ -789,7 +800,7 @@ public function setDisplay($display_id = NULL) { // Ensure the requested display exists. if (!$this->displayHandlers->has($display_id)) { - debug(format_string('setDisplay() called with invalid display ID "@display".', array('@display' => $display_id))); + trigger_error(new FormattableMarkup('setDisplay() called with invalid display ID "@display".', ['@display' => $display_id]), E_USER_WARNING); return FALSE; } @@ -957,10 +968,10 @@ public function renderPager($exposed_input) { * An array of base tables to be used by the view. */ public function getBaseTables() { - $base_tables = array( + $base_tables = [ $this->storage->get('base_table') => TRUE, '#global' => TRUE, - ); + ]; foreach ($this->display_handler->getHandlers('relationship') as $handler) { $base_tables[$handler->definition['base']] = TRUE; @@ -1055,7 +1066,7 @@ protected function _buildArguments() { // build arguments. $position = -1; - $substitutions = array(); + $substitutions = []; $status = TRUE; // Get the title. @@ -1193,18 +1204,18 @@ public function build($display_id = NULL) { // Let modules modify the view just prior to building it. $module_handler = \Drupal::moduleHandler(); - $module_handler->invokeAll('views_pre_build', array($this)); + $module_handler->invokeAll('views_pre_build', [$this]); // Attempt to load from cache. // @todo Load a build_info from cache. $start = microtime(TRUE); // If that fails, let's build! - $this->build_info = array( + $this->build_info = [ 'query' => '', 'count_query' => '', - 'query_args' => array(), - ); + 'query_args' => [], + ]; $this->initQuery(); @@ -1223,7 +1234,7 @@ public function build($display_id = NULL) { /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginInterface $exposed_form */ $exposed_form = $this->display_handler->getPlugin('exposed_form'); $this->exposed_widgets = $exposed_form->renderExposedForm(); - if (FormState::hasAnyErrors() || !empty($this->build_info['abort'])) { + if (!empty($this->build_info['abort'])) { $this->built = TRUE; // Don't execute the query, $form_state, but rendering will still be executed to display the empty text. $this->executed = TRUE; @@ -1315,7 +1326,7 @@ public function build($display_id = NULL) { $this->attachDisplays(); // Let modules modify the view just after building it. - $module_handler->invokeAll('views_post_build', array($this)); + $module_handler->invokeAll('views_post_build', [$this]); return TRUE; } @@ -1328,15 +1339,15 @@ public function build($display_id = NULL) { * @todo Some filter needs this function, even it is internal. * * @param string $key - * The type of handlers (filter etc.) which should be iterated over to - * build the relationship and query information. + * The type of handlers (filter etc.) which should be iterated over to build + * the relationship and query information. */ public function _build($key) { $handlers = &$this->$key; foreach ($handlers as $id => $data) { if (!empty($handlers[$id]) && is_object($handlers[$id])) { - $multiple_exposed_input = array(0 => NULL); + $multiple_exposed_input = [0 => NULL]; if ($handlers[$id]->multipleExposedInput()) { $multiple_exposed_input = $handlers[$id]->groupMultipleExposedInput($this->exposed_data); } @@ -1392,7 +1403,7 @@ public function execute($display_id = NULL) { // Let modules modify the view just prior to executing it. $module_handler = \Drupal::moduleHandler(); - $module_handler->invokeAll('views_pre_execute', array($this)); + $module_handler->invokeAll('views_pre_execute', [$this]); // Check for already-cached results. /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache */ @@ -1419,7 +1430,7 @@ public function execute($display_id = NULL) { } // Let modules modify the view just after executing it. - $module_handler->invokeAll('views_post_execute', array($this)); + $module_handler->invokeAll('views_post_execute', [$this]); return $this->executed = TRUE; } @@ -1495,7 +1506,7 @@ public function render($display_id = NULL) { $this->style_plugin->preRender($this->result); // Let each area handler have access to the result set. - $areas = array('header', 'footer'); + $areas = ['header', 'footer']; // Only call preRender() on the empty handlers if the result is empty. if (empty($this->result)) { $areas[] = 'empty'; @@ -1507,7 +1518,7 @@ public function render($display_id = NULL) { } // Let modules modify the view just prior to rendering it. - $module_handler->invokeAll('views_pre_render', array($this)); + $module_handler->invokeAll('views_pre_render', [$this]); // Let the themes play too, because pre render is a very themey thing. foreach ($themes as $theme_name) { @@ -1524,7 +1535,7 @@ public function render($display_id = NULL) { $cache->postRender($this->display_handler->output); // Let modules modify the view output after it is rendered. - $module_handler->invokeAll('views_post_render', array($this, &$this->display_handler->output, $cache)); + $module_handler->invokeAll('views_post_render', [$this, &$this->display_handler->output, $cache]); // Let the themes play too, because post render is a very themey thing. foreach ($themes as $theme_name) { @@ -1571,7 +1582,7 @@ public function getCacheTags() { * A renderable array with #type 'view' or NULL if the display ID was * invalid. */ - public function buildRenderable($display_id = NULL, $args = array(), $cache = TRUE) { + public function buildRenderable($display_id = NULL, $args = [], $cache = TRUE) { // @todo Extract that into a generic method. if (empty($this->current_display) || $this->current_display != $this->chooseDisplay($display_id)) { if (!$this->setDisplay($display_id)) { @@ -1604,7 +1615,7 @@ public function buildRenderable($display_id = NULL, $args = array(), $cache = TR * A renderable array containing the view output or NULL if the display ID * of the view to be executed doesn't exist. */ - public function executeDisplay($display_id = NULL, $args = array()) { + public function executeDisplay($display_id = NULL, $args = []) { if (empty($this->current_display) || $this->current_display != $this->chooseDisplay($display_id)) { if (!$this->setDisplay($display_id)) { return NULL; @@ -1636,7 +1647,7 @@ public function executeDisplay($display_id = NULL, $args = array()) { * A renderable array containing the view output or NULL if the display ID * of the view to be executed doesn't exist. */ - public function preview($display_id = NULL, $args = array()) { + public function preview($display_id = NULL, $args = []) { if (empty($this->current_display) || ((!empty($display_id)) && $this->current_display != $display_id)) { if (!$this->setDisplay($display_id)) { return FALSE; @@ -1658,7 +1669,7 @@ public function preview($display_id = NULL, $args = array()) { * @param array $args * An array of arguments from the URL that can be used by the view. */ - public function preExecute($args = array()) { + public function preExecute($args = []) { $this->old_view[] = views_get_current_view(); views_set_current_view($this); $display_id = $this->current_display; @@ -1670,7 +1681,7 @@ public function preExecute($args = array()) { } // Let modules modify the view just prior to executing it. - \Drupal::moduleHandler()->invokeAll('views_pre_view', array($this, $display_id, &$this->args)); + \Drupal::moduleHandler()->invokeAll('views_pre_view', [$this, $display_id, &$this->args]); // Allow hook_views_pre_view() to set the dom_id, then ensure it is set. $this->dom_id = !empty($this->dom_id) ? $this->dom_id : hash('sha256', $this->storage->id() . REQUEST_TIME . mt_rand()); @@ -1747,7 +1758,7 @@ public function access($displays = NULL, $account = NULL) { // We can't use choose_display() here because that function // calls this one. - $displays = (array)$displays; + $displays = (array) $displays; foreach ($displays as $display_id) { if ($this->displayHandlers->has($display_id)) { if (($display = $this->displayHandlers->get($display_id)) && $display->access($account)) { @@ -1948,7 +1959,7 @@ public function getUrl($args = NULL, $display_id = NULL) { return $display_handler->getUrlInfo(); } - $argument_keys = isset($this->argument) ? array_keys($this->argument) : array(); + $argument_keys = isset($this->argument) ? array_keys($this->argument) : []; $id = current($argument_keys); /** @var \Drupal\Core\Url $url */ @@ -2085,7 +2096,7 @@ public function destroy() { * errors. */ public function validate() { - $errors = array(); + $errors = []; $this->initDisplay(); $current_display = $this->current_display; @@ -2159,7 +2170,7 @@ public static function getPluginTypes($type = NULL) { * @return string * The unique ID for this handler instance. */ - public function addHandler($display_id, $type, $table, $field, $options = array(), $id = NULL) { + public function addHandler($display_id, $type, $table, $field, $options = [], $id = NULL) { $types = $this::getHandlerTypes(); $this->setDisplay($display_id); @@ -2173,11 +2184,11 @@ public function addHandler($display_id, $type, $table, $field, $options = array( // If the desired type is not found, use the original value directly. $handler_type = !empty($types[$type]['type']) ? $types[$type]['type'] : $type; - $fields[$id] = array( + $fields[$id] = [ 'id' => $id, 'table' => $table, 'field' => $field, - ) + $options; + ] + $options; if (isset($data['table']['entity type'])) { $fields[$id]['entity_type'] = $data['table']['entity type']; @@ -2406,7 +2417,7 @@ public function mergeDefaults() { * An array of theme hook suggestions. */ public function buildThemeFunctions($hook) { - $themes = array(); + $themes = []; $display = isset($this->display_handler) ? $this->display_handler->display : NULL; $id = $this->storage->id(); @@ -2467,52 +2478,68 @@ public function getDependencies() { } /** - * {@inheritdoc} - */ - public function serialize() { - return serialize([ - // Only serialize the storage entity ID. - $this->storage->id(), - $this->current_display, - $this->args, - $this->current_page, - $this->exposed_input, - $this->exposed_raw_input, - $this->exposed_data, - $this->dom_id, - $this->executed, - ]); - } - - /** - * {@inheritdoc} - */ - public function unserialize($serialized) { - list($storage, $current_display, $args, $current_page, $exposed_input, $exposed_raw_input, $exposed_data, $dom_id, $executed) = unserialize($serialized); - - // There are cases, like in testing, where we don't have a container + * Magic method implementation to serialize the view executable. + * + * @return array + * The names of all variables that should be serialized. + */ + public function __sleep() { + // Limit to only the required data which is needed to properly restore the + // state during unserialization. + $this->serializationData = [ + 'storage' => $this->storage->id(), + 'views_data' => $this->viewsData->_serviceId, + 'route_provider' => $this->routeProvider->_serviceId, + 'current_display' => $this->current_display, + 'args' => $this->args, + 'current_page' => $this->current_page, + 'exposed_input' => $this->exposed_input, + 'exposed_raw_input' => $this->exposed_raw_input, + 'exposed_data' => $this->exposed_data, + 'dom_id' => $this->dom_id, + 'executed' => $this->executed, + ]; + return ['serializationData']; + } + + /** + * Magic method implementation to unserialize the view executable. + */ + public function __wakeup() { + // There are cases, like in testing where we don't have a container // available. - if (\Drupal::hasContainer()) { - $this->setRequest(\Drupal::request()); - $this->user = \Drupal::currentUser(); + if (\Drupal::hasContainer() && !empty($this->serializationData)) { + // Load and reference the storage. + $this->storage = \Drupal::entityTypeManager()->getStorage('view') + ->load($this->serializationData['storage']); + $this->storage->set('executable', $this); - $this->storage = \Drupal::entityManager()->getStorage('view')->load($storage); + // Attach all necessary services. + $this->user = \Drupal::currentUser(); + $this->viewsData = \Drupal::service($this->serializationData['views_data']); + $this->routeProvider = \Drupal::service($this->serializationData['route_provider']); - $this->setDisplay($current_display); - $this->setArguments($args); - $this->setCurrentPage($current_page); - $this->setExposedInput($exposed_input); - $this->exposed_data = $exposed_data; - $this->exposed_raw_input = $exposed_raw_input; - $this->dom_id = $dom_id; + // Restore the state of this executable. + if ($request = \Drupal::request()) { + $this->setRequest($request); + } + $this->setDisplay($this->serializationData['current_display']); + $this->setArguments($this->serializationData['args']); + $this->setCurrentPage($this->serializationData['current_page']); + $this->setExposedInput($this->serializationData['exposed_input']); + $this->exposed_data = $this->serializationData['exposed_data']; + $this->exposed_raw_input = $this->serializationData['exposed_raw_input']; + $this->dom_id = $this->serializationData['dom_id']; $this->initHandlers(); // If the display was previously executed, execute it now. - if ($executed) { + if ($this->serializationData['executed']) { $this->execute($this->current_display); } } + // Unset serializationData since it serves no further purpose. + unset($this->serializationData); } } diff --git a/core/modules/views/src/Views.php b/core/modules/views/src/Views.php index a82a670a..dd241f71 100644 --- a/core/modules/views/src/Views.php +++ b/core/modules/views/src/Views.php @@ -26,7 +26,7 @@ class Views { * * @var array */ - protected static $plugins = array( + protected static $plugins = [ 'access' => 'plugin', 'area' => 'handler', 'argument' => 'handler', @@ -46,7 +46,7 @@ class Views { 'sort' => 'handler', 'style' => 'plugin', 'wizard' => 'plugin', - ); + ]; /** * Returns the views data service. @@ -139,9 +139,9 @@ public static function getView($id) { * @return * A keyed array of in the form of 'base_table' => 'Description'. */ - public static function fetchPluginNames($type, $key = NULL, array $base = array()) { + public static function fetchPluginNames($type, $key = NULL, array $base = []) { $definitions = static::pluginManager($type)->getDefinitions(); - $plugins = array(); + $plugins = []; foreach ($definitions as $id => $plugin) { // Skip plugins that don't conform to our key, if they have one. @@ -169,7 +169,7 @@ public static function fetchPluginNames($type, $key = NULL, array $base = array( * An array of plugin definitions for all types. */ public static function getPluginDefinitions() { - $plugins = array(); + $plugins = []; foreach (ViewExecutable::getPluginTypes() as $plugin_type) { $plugins[$plugin_type] = static::pluginManager($plugin_type)->getDefinitions(); } @@ -213,13 +213,13 @@ public static function getApplicableViews($type) { } } - $entity_ids = \Drupal::service('entity.query')->get('view') + $entity_ids = \Drupal::entityQuery('view') ->condition('status', TRUE) ->condition("display.*.display_plugin", $plugin_ids, 'IN') ->execute(); - $result = array(); - foreach (\Drupal::entityManager()->getStorage('view')->loadMultiple($entity_ids) as $view) { + $result = []; + foreach (\Drupal::entityTypeManager()->getStorage('view')->loadMultiple($entity_ids) as $view) { // Check each display to see if it meets the criteria and is enabled. foreach ($view->get('display') as $id => $display) { @@ -283,8 +283,8 @@ public static function getDisabledViews() { * Filters the views on status. Can either be 'all' (default), 'enabled' or * 'disabled' * @param mixed $exclude_view - * view or current display to exclude - * either a + * View or current display to exclude. + * Either a: * - views object (containing $exclude_view->storage->name and $exclude_view->current_display) * - views name as string: e.g. my_view * - views name and display id (separated by ':'): e.g. my_view:default @@ -309,7 +309,7 @@ public static function getViewsAsOptions($views_only = FALSE, $filter = 'all', $ $views = call_user_func("static::get{$filter}Views"); break; default: - return array(); + return []; } // Prepare exclude view strings for comparison. @@ -327,7 +327,7 @@ public static function getViewsAsOptions($views_only = FALSE, $filter = 'all', $ list($exclude_view_name, $exclude_view_display) = explode(':', "$exclude_view:"); } - $options = array(); + $options = []; foreach ($views as $view) { $id = $view->id(); // Return only views. @@ -339,10 +339,10 @@ public static function getViewsAsOptions($views_only = FALSE, $filter = 'all', $ foreach ($view->get('display') as $display_id => $display) { if (!($id == $exclude_view_name && $display_id == $exclude_view_display)) { if ($optgroup) { - $options[$id][$id . ':' . $display['id']] = t('@view : @display', array('@view' => $id, '@display' => $display['id'])); + $options[$id][$id . ':' . $display['id']] = t('@view : @display', ['@view' => $id, '@display' => $display['id']]); } else { - $options[$id . ':' . $display['id']] = t('View: @view - Display: @display', array('@view' => $id, '@display' => $display['id'])); + $options[$id . ':' . $display['id']] = t('View: @view - Display: @display', ['@view' => $id, '@display' => $display['id']]); } } } @@ -368,7 +368,7 @@ public static function getViewsAsOptions($views_only = FALSE, $filter = 'all', $ */ public static function pluginList() { $plugin_data = static::getPluginDefinitions(); - $plugins = array(); + $plugins = []; foreach (static::getEnabledViews() as $view) { foreach ($view->get('display') as $display) { foreach ($plugin_data as $type => $info) { @@ -389,12 +389,12 @@ public static function pluginList() { $key = $type . ':' . $name; // Add info for this plugin. if (!isset($plugins[$key])) { - $plugins[$key] = array( + $plugins[$key] = [ 'type' => $type, 'title' => $info[$name]['title'], 'provider' => $info[$name]['provider'], - 'views' => array(), - ); + 'views' => [], + ]; } // Add this view to the list for this plugin. @@ -423,8 +423,8 @@ public static function getHandlerTypes() { // Statically cache this so translation only occurs once per request for all // of these values. if (!isset(static::$handlerTypes)) { - static::$handlerTypes = array( - 'field' => array( + static::$handlerTypes = [ + 'field' => [ // title 'title' => static::t('Fields'), // Lowercase title for mid-sentence. @@ -434,60 +434,60 @@ public static function getHandlerTypes() { // Singular lowercase title for mid sentence 'lstitle' => static::t('field'), 'plural' => 'fields', - ), - 'argument' => array( + ], + 'argument' => [ 'title' => static::t('Contextual filters'), 'ltitle' => static::t('contextual filters'), 'stitle' => static::t('Contextual filter'), 'lstitle' => static::t('contextual filter'), 'plural' => 'arguments', - ), - 'sort' => array( + ], + 'sort' => [ 'title' => static::t('Sort criteria'), 'ltitle' => static::t('sort criteria'), 'stitle' => static::t('Sort criterion'), 'lstitle' => static::t('sort criterion'), 'plural' => 'sorts', - ), - 'filter' => array( + ], + 'filter' => [ 'title' => static::t('Filter criteria'), 'ltitle' => static::t('filter criteria'), 'stitle' => static::t('Filter criterion'), 'lstitle' => static::t('filter criterion'), 'plural' => 'filters', - ), - 'relationship' => array( + ], + 'relationship' => [ 'title' => static::t('Relationships'), 'ltitle' => static::t('relationships'), 'stitle' => static::t('Relationship'), 'lstitle' => static::t('Relationship'), 'plural' => 'relationships', - ), - 'header' => array( + ], + 'header' => [ 'title' => static::t('Header'), 'ltitle' => static::t('header'), 'stitle' => static::t('Header'), 'lstitle' => static::t('Header'), 'plural' => 'header', 'type' => 'area', - ), - 'footer' => array( + ], + 'footer' => [ 'title' => static::t('Footer'), 'ltitle' => static::t('footer'), 'stitle' => static::t('Footer'), 'lstitle' => static::t('Footer'), 'plural' => 'footer', 'type' => 'area', - ), - 'empty' => array( + ], + 'empty' => [ 'title' => static::t('No results behavior'), 'ltitle' => static::t('no results behavior'), 'stitle' => static::t('No results behavior'), 'lstitle' => static::t('No results behavior'), 'plural' => 'empty', 'type' => 'area', - ), - ); + ], + ]; } return static::$handlerTypes; @@ -508,11 +508,11 @@ public static function getPluginTypes($type = NULL) { return array_keys(static::$plugins); } - if (!in_array($type, array('plugin', 'handler'))) { + if (!in_array($type, ['plugin', 'handler'])) { throw new \Exception('Invalid plugin type used. Valid types are "plugin" or "handler".'); } - return array_keys(array_filter(static::$plugins, function($plugin_type) use ($type) { + return array_keys(array_filter(static::$plugins, function ($plugin_type) use ($type) { return $plugin_type == $type; })); } @@ -522,7 +522,7 @@ public static function getPluginTypes($type = NULL) { * * See the t() documentation for details. */ - protected static function t($string, array $args = array(), array $options = array()) { + protected static function t($string, array $args = [], array $options = []) { if (empty(static::$translationManager)) { static::$translationManager = \Drupal::service('string_translation'); } diff --git a/core/modules/views/src/ViewsData.php b/core/modules/views/src/ViewsData.php index 8bb6b53c..e5281abf 100644 --- a/core/modules/views/src/ViewsData.php +++ b/core/modules/views/src/ViewsData.php @@ -40,7 +40,7 @@ class ViewsData { * * @var array */ - protected $storage = array(); + protected $storage = []; /** * All table storage data loaded from cache. @@ -50,7 +50,7 @@ class ViewsData { * * @var array */ - protected $allStorage = array(); + protected $allStorage = []; /** * Whether the data has been fully loaded in this request. @@ -113,7 +113,7 @@ public function __construct(CacheBackendInterface $cache_backend, ConfigFactoryI * * @see https://www.drupal.org/node/2723553 * - * @return array $data + * @return array * An array of table data. */ public function getAll() { @@ -140,7 +140,7 @@ public function getAll() { * * @see https://www.drupal.org/node/2723553 * - * @return array $data + * @return array * An array of table data. */ public function get($key = NULL) { @@ -167,8 +167,8 @@ public function get($key = NULL) { // Write an empty cache entry if no information for that table // exists to avoid repeated cache get calls for this table and // prevent loading all tables unnecessarily. - $this->storage[$key] = array(); - $this->allStorage[$key] = array(); + $this->storage[$key] = []; + $this->allStorage[$key] = []; } else { $this->storage[$key] = $this->allStorage[$key]; @@ -208,7 +208,7 @@ protected function cacheGet($cid) { * The data that will be cached. */ protected function cacheSet($cid, $data) { - return $this->cacheBackend->set($this->prepareCid($cid), $data, Cache::PERMANENT, array('views_data', 'config:core.extension')); + return $this->cacheBackend->set($this->prepareCid($cid), $data, Cache::PERMANENT, ['views_data', 'config:core.extension']); } /** @@ -274,9 +274,9 @@ protected function processEntityTypes(array &$data) { if (!empty($table_info['table']['entity type'])) { $entity_table = 'views_entity_' . $table_info['table']['entity type']; - $data[$entity_table]['table']['join'][$table_name] = array( + $data[$entity_table]['table']['join'][$table_name] = [ 'left_table' => $table_name, - ); + ]; $data[$entity_table]['table']['entity type'] = $table_info['table']['entity type']; // Copy over the default table group if we have none yet. if (!empty($table_info['table']['group']) && empty($data[$entity_table]['table']['group'])) { @@ -297,15 +297,15 @@ protected function processEntityTypes(array &$data) { * - weight: The weight of the base table. */ public function fetchBaseTables() { - $tables = array(); + $tables = []; foreach ($this->get() as $table => $info) { if (!empty($info['table']['base'])) { - $tables[$table] = array( + $tables[$table] = [ 'title' => $info['table']['base']['title'], 'help' => !empty($info['table']['base']['help']) ? $info['table']['base']['help'] : '', 'weight' => !empty($info['table']['base']['weight']) ? $info['table']['base']['weight'] : 0, - ); + ]; } } @@ -327,10 +327,10 @@ public function fetchBaseTables() { * Clears the class storage and cache. */ public function clear() { - $this->storage = array(); - $this->allStorage = array(); + $this->storage = []; + $this->allStorage = []; $this->fullyLoaded = FALSE; - Cache::invalidateTags(array('views_data')); + Cache::invalidateTags(['views_data']); } } diff --git a/core/modules/views/src/ViewsDataHelper.php b/core/modules/views/src/ViewsDataHelper.php index 791cd37f..32e6adae 100644 --- a/core/modules/views/src/ViewsDataHelper.php +++ b/core/modules/views/src/ViewsDataHelper.php @@ -37,7 +37,7 @@ public function __construct(ViewsData $views_data) { /** * Fetches a list of all fields available for a given base type. * - * @param (array|string) $base + * @param array|string $base * A list or a single base_table, for example node. * @param string $type * The handler type, for example field or filter. @@ -64,9 +64,9 @@ public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) { // each field have a cheap kind of inheritance. foreach ($data as $table => $table_data) { - $bases = array(); - $strings = array(); - $skip_bases = array(); + $bases = []; + $strings = []; + $skip_bases = []; foreach ($table_data as $field => $info) { // Collect table data from this table if ($field == 'table') { @@ -78,7 +78,7 @@ public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) { $bases[] = $table; continue; } - foreach (array('field', 'sort', 'filter', 'argument', 'relationship', 'area') as $key) { + foreach (['field', 'sort', 'filter', 'argument', 'relationship', 'area'] as $key) { if (!empty($info[$key])) { if ($grouping && !empty($info[$key]['no group by'])) { continue; @@ -96,7 +96,7 @@ public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) { $skip_bases[$field][$key][$base_name] = TRUE; } } - foreach (array('title', 'group', 'help', 'base', 'aliases') as $string) { + foreach (['title', 'group', 'help', 'base', 'aliases'] as $string) { // First, try the lowest possible level if (!empty($info[$key][$string])) { $strings[$field][$key][$string] = $info[$key][$string]; @@ -120,7 +120,7 @@ public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) { } else { if ($string != 'base') { - $strings[$field][$key][$string] = SafeMarkup::format("Error: missing @component", array('@component' => $string)); + $strings[$field][$key][$string] = SafeMarkup::format("Error: missing @component", ['@component' => $string]); } } } @@ -143,21 +143,21 @@ public function fetchFields($base, $type, $grouping = FALSE, $sub_type = NULL) { // all and add them together. Duplicate keys will be lost and that's // Just Fine. if (is_array($base)) { - $strings = array(); + $strings = []; foreach ($base as $base_table) { if (isset($this->fields[$base_table][$type])) { $strings += $this->fields[$base_table][$type]; } } - uasort($strings, array('self', 'fetchedFieldSort')); + uasort($strings, ['self', 'fetchedFieldSort']); return $strings; } if (isset($this->fields[$base][$type])) { - uasort($this->fields[$base][$type], array($this, 'fetchedFieldSort')); + uasort($this->fields[$base][$type], [$this, 'fetchedFieldSort']); return $this->fields[$base][$type]; } - return array(); + return []; } /** diff --git a/core/modules/views/tests/fixtures/update/argument-placeholder.php b/core/modules/views/tests/fixtures/update/argument-placeholder.php index 2a7cf4bb..2158eb27 100644 --- a/core/modules/views/tests/fixtures/update/argument-placeholder.php +++ b/core/modules/views/tests/fixtures/update/argument-placeholder.php @@ -11,9 +11,9 @@ $connection = Database::getConnection(); $connection->insert('config') - ->fields(array( + ->fields([ 'collection' => '', 'name' => 'views.view.test_token_view', 'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_token_view.yml'))), - )) + ]) ->execute(); diff --git a/core/modules/views/tests/fixtures/update/boolean-filter-values.php b/core/modules/views/tests/fixtures/update/boolean-filter-values.php index d78a3edd..2b8e78fb 100644 --- a/core/modules/views/tests/fixtures/update/boolean-filter-values.php +++ b/core/modules/views/tests/fixtures/update/boolean-filter-values.php @@ -11,9 +11,9 @@ $connection = Database::getConnection(); $connection->insert('config') - ->fields(array( + ->fields([ 'collection' => '', 'name' => 'views.view.test_boolean_filter_values', 'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/fixtures/update/views.view.test_boolean_filter_values.yml'))), - )) + ]) ->execute(); diff --git a/core/modules/views/tests/fixtures/update/duplicate-field-handler.php b/core/modules/views/tests/fixtures/update/duplicate-field-handler.php index 775f75a4..21cf164f 100644 --- a/core/modules/views/tests/fixtures/update/duplicate-field-handler.php +++ b/core/modules/views/tests/fixtures/update/duplicate-field-handler.php @@ -11,9 +11,9 @@ $connection = Database::getConnection(); $connection->insert('config') - ->fields(array( + ->fields([ 'collection' => '', 'name' => 'views.view.test_duplicate_field_handlers', 'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.test_duplicate_field_handlers.yml'))), - )) + ]) ->execute(); diff --git a/core/modules/views/tests/modules/views_entity_test/views_entity_test.info.yml b/core/modules/views/tests/modules/views_entity_test/views_entity_test.info.yml index efc647e9..0212758f 100644 --- a/core/modules/views/tests/modules/views_entity_test/views_entity_test.info.yml +++ b/core/modules/views/tests/modules/views_entity_test/views_entity_test.info.yml @@ -8,8 +8,8 @@ dependencies: - views - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/tests/modules/views_entity_test/views_entity_test.module b/core/modules/views/tests/modules/views_entity_test/views_entity_test.module index 0506710f..6ed0772e 100644 --- a/core/modules/views/tests/modules/views_entity_test/views_entity_test.module +++ b/core/modules/views/tests/modules/views_entity_test/views_entity_test.module @@ -12,7 +12,6 @@ use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Session\AccountInterface; - /** * Implements hook_entity_bundle_field_info(). */ @@ -22,10 +21,10 @@ function views_entity_test_entity_base_field_info(EntityTypeInterface $entity_ty ->setLabel(t('Test access')) ->setTranslatable(FALSE) ->setSetting('max_length', 64) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => 10, - )); + ]); return $definitions; } } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml new file mode 100644 index 00000000..d8de3f18 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml @@ -0,0 +1,171 @@ +langcode: en +status: true +dependencies: + module: + - entity_test +id: computed_field_view +label: 'Computed Field View' +module: views +description: '' +tag: '' +base_table: entity_test_computed_field +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + computed_string_field: + id: computed_string_field + table: entity_test_computed_field + field: computed_string_field + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_computed_field + plugin_id: field + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: foo + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + tags: { } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.rest_export_with_authorization_correction.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.rest_export_with_authorization_correction.yml new file mode 100644 index 00000000..27130f2f --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.rest_export_with_authorization_correction.yml @@ -0,0 +1,213 @@ +langcode: en +status: true +dependencies: + config: + - user.role.authenticated + module: + - node + - rest + - user +id: rest_export_with_authorization_correction +label: 'Rest Export' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: role + options: + role: + authenticated: authenticated + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Filter + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: '‹ Previous' + next: 'Next ›' + first: '« First' + last: 'Last »' + quantity: 9 + style: + type: default + row: + type: 'fields' + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: true + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: string + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + filters: + status: + id: status + table: node_field_data + field: status + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: '0' + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: boolean + entity_type: node + entity_field: status + sorts: + created: + id: created + table: node_field_data + field: created + order: DESC + entity_type: node + entity_field: created + plugin_id: date + relationship: none + group_type: group + admin_label: '' + exposed: false + expose: + label: '' + granularity: second + title: 'Rest Export' + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - 'user.node_grants:view' + - user.roles + tags: { } + rest_export_1: + display_plugin: rest_export + id: rest_export_1 + display_title: 'REST export' + position: 2 + display_options: + display_extenders: { } + path: unpublished-content + auth: + - user + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - request_format + - 'user.node_grants:view' + - user.roles + tags: { } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_area_result.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_area_result.yml new file mode 100644 index 00000000..8ca56285 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_area_result.yml @@ -0,0 +1,79 @@ +langcode: en +status: true +dependencies: { } +id: test_area_result +label: '' +module: views +description: '' +tag: '' +base_table: views_test_data +base_field: nid +core: '8' +display: + default: + display_options: + defaults: + fields: false + pager: false + sorts: false + fields: + id: + field: id + id: id + relationship: none + table: views_test_data + plugin_id: numeric + pager: + options: + offset: 0 + type: none + sorts: + id: + field: id + id: id + order: ASC + relationship: none + table: views_test_data + plugin_id: numeric + empty: + title: + field: title + id: title + table: views + plugin_id: title + title: test_title_empty + header: + result: + id: result + table: views + field: result + relationship: none + group_type: group + admin_label: '' + empty: true + content: "start: @start | end: @end | total: @total | label: @label | per page: @per_page | current page: @current_page | current record count: @current_record_count | page count: @page_count" + plugin_id: result + display_plugin: default + display_title: Master + id: default + position: 0 + page_1: + display_options: + path: test-area-result + defaults: + header: false + header: + result: + id: result + table: views + field: result + relationship: none + group_type: group + admin_label: '' + empty: false + content: "start: @start | end: @end | total: @total | label: @label | per page: @per_page | current page: @current_page | current record count: @current_record_count | page count: @page_count" + plugin_id: result + display_plugin: page + display_title: 'Page 1' + id: page_1 + position: 1 diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_row_renderers_revisions_base.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_row_renderers_revisions_base.yml new file mode 100644 index 00000000..a4ebba1c --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_row_renderers_revisions_base.yml @@ -0,0 +1,225 @@ +uuid: b133bd43-c494-4db6-83f0-24380fe3964b +langcode: en +status: true +dependencies: + module: + - user +id: test_entity_row_renderers_revisions_base +label: test_entity_row_renderers_revisions_base +module: views +description: '' +tag: '' +base_table: node_field_revision +base_field: vid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'view all revisions' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: none + options: + offset: 0 + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + nid: + id: nid + table: node_field_revision + field: nid + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: node + entity_field: nid + plugin_id: field + uid: + id: uid + table: users_field_data + field: uid + relationship: revision_uid + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: user + entity_field: uid + plugin_id: field + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: + revision_uid: + id: revision_uid + table: node_revision + field: revision_uid + relationship: none + group_type: group + admin_label: 'revision user' + required: false + entity_type: node + entity_field: revision_uid + plugin_id: standard + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } + diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml index db16bcb7..d8830676 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml @@ -31,7 +31,7 @@ display: field: type id: type table: node_field_data - plugin_id: node_type + plugin_id: bundle entity_type: node entity_field: type body_value: @@ -76,6 +76,72 @@ display: plugin_id: string entity_type: node entity_field: body + created: + id: created + table: node_field_data + field: created + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: + min: '' + max: '' + value: '' + type: date + group: 1 + exposed: true + expose: + operator_id: created_op + label: 'Authored on' + description: null + use_operator: false + operator: created_op + identifier: created + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: true + group_info: + label: 'Authored on' + description: '' + identifier: created + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: + 1: + title: Between + operator: between + value: + type: date + value: '' + min: '2015-01-01' + max: '2016-01-01' + 2: + title: 'Not Between' + operator: 'not between' + value: + type: date + value: '' + min: '2015-01-01' + max: '2016-01-01' + 3: + title: Equal + operator: '=' + value: + type: date + value: '2016-01-01' + min: '' + max: '' + entity_type: node + entity_field: created + plugin_id: date pager: type: full sorts: diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml new file mode 100644 index 00000000..26b1d325 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml @@ -0,0 +1,155 @@ +langcode: en +status: true +dependencies: + config: + - taxonomy.vocabulary.test_exposed_checkboxes + module: + - node + - taxonomy +id: test_exposed_form_checkboxes +label: '' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +core: '8' +display: + default: + display_options: + access: + type: none + cache: + type: tag + exposed_form: + options: + reset_button: true + type: basic + filters: + type: + id: type + table: node_field_data + field: type + relationship: none + group_type: group + admin_label: '' + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: type_op + label: 'Content: Type' + description: 'Exposed description' + use_operator: false + operator: '' + identifier: type + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: in_operator + entity_type: node + entity_field: type + tid: + id: tid + table: taxonomy_index + field: tid + relationship: none + group_type: group + admin_label: '' + operator: and + value: { } + group: 1 + exposed: true + expose: + operator_id: tid_op + label: 'Has taxonomy term' + description: '' + use_operator: false + operator: tid_op + identifier: tid + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + reduce_duplicates: false + type: select + limit: true + vid: test_exposed_checkboxes + hierarchy: false + error_message: true + plugin_id: taxonomy_index_tid + pager: + type: full + query: + options: + query_comment: '' + type: views_query + style: + type: default + row: + type: 'entity:node' + display_extenders: { } + display_plugin: default + display_title: Master + id: default + position: 0 + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - url + - url.query_args + - user + - 'user.node_grants:view' + tags: { } + page_1: + display_options: + path: test_exposed_form_checkboxes + display_extenders: { } + display_plugin: page + display_title: Page + id: page_1 + position: 0 + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - url + - url.query_args + - user + - 'user.node_grants:view' + tags: { } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_config_translation_filter.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_config_translation_filter.yml new file mode 100644 index 00000000..2202d9cf --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_config_translation_filter.yml @@ -0,0 +1,187 @@ +langcode: en +status: true +dependencies: { } +id: test_field_config_translation_filter +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: id +core: '8' +display: + default: + display_options: + access: + type: none + cache: + type: none + fields: + nid: + id: nid + field: nid + table: node_field_data + plugin_id: field + entity_type: node + entity_field: nid + langcode: + id: langcode + field: langcode + table: node_field_data + plugin_id: field + entity_type: node + entity_field: langcode + field_name_1: + id: field_name_1 + table: node__field_name_1 + field: field_name_1 + plugin_id: field + entity_type: node + entity_field: field_name_1 + field_name_2: + id: field_name_2 + table: node__field_name_2 + field: field_name_2 + plugin_id: field + entity_type: node + entity_field: field_name_2 + field_name_3: + id: field_name_3 + table: node__field_name_3 + field: field_name_3 + plugin_id: field + entity_type: node + entity_field: field_name_3 + sorts: + nid: + id: nid + table: node_field_data + field: nid + order: ASC + plugin_id: standard + entity_type: node + entity_field: nid + langcode: + id: langcode + table: node_field_data + field: langcode + relationship: none + group_type: group + admin_label: '' + order: ASC + exposed: false + expose: + label: '' + entity_type: node + entity_field: langcode + plugin_id: standard + style: + type: html_list + row: + type: fields + display_plugin: default + display_title: Master + id: default + position: 0 + embed_1: + display_options: + defaults: + fields: true + filters: false + filters: + field_name_1_value: + id: field_name_1_value + table: node__field_name_1 + field: field_name_1_value + value: 'field name 1: es' + plugin_id: string + entity_type: node + entity_field: field_name_1 + display_plugin: embed + display_title: Embed 1 + id: embed_1 + position: 1 + embed_2: + display_options: + defaults: + filters: false + filters: + field_name_1_value: + id: field_name_1_value + table: node__field_name_1 + field: field_name_1_value + value: 'field name 1: fr' + plugin_id: string + entity_type: node + entity_field: field_name_1 + display_plugin: embed + display_title: Embed 2 + id: embed_2 + position: 2 + embed_3: + display_options: + defaults: + filters: false + filters: + field_name_2_value: + id: field_name_2_value + table: node__field_name_2 + field: field_name_2_value + value: 'field name 2: es' + plugin_id: string + entity_type: node + entity_field: field_name_2 + display_plugin: embed + display_title: Embed 3 + id: embed_3 + position: 3 + embed_4: + display_options: + defaults: + filters: false + filters: + field_name_2_value: + id: field_name_2_value + table: node__field_name_2 + field: field_name_2_value + value: 'field name 2: fr' + plugin_id: string + entity_type: node + entity_field: field_name_2 + display_plugin: embed + display_title: Embed 4 + id: embed_4 + position: 4 + embed_5: + display_options: + defaults: + filters: false + filters: + field_name_3_value: + id: field_name_3_value + table: node__field_name_3 + field: field_name_3_value + value: 'field name 3: es' + plugin_id: string + entity_type: node + entity_field: field_name_3 + display_plugin: embed + display_title: Embed 5 + id: embed_5 + position: 5 + embed_6: + display_options: + defaults: + filters: false + filters: + field_name_3_value: + id: field_name_3_value + table: node__field_name_3 + field: field_name_3_value + value: 'field name 3: fr' + plugin_id: string + entity_type: node + entity_field: field_name_3 + display_plugin: embed + display_title: Embed 6 + id: embed_6 + position: 6 diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_latest_revision_filter.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_latest_revision_filter.yml new file mode 100644 index 00000000..53f0f72a --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_latest_revision_filter.yml @@ -0,0 +1,163 @@ +langcode: en +status: true +dependencies: + module: + - node +id: test_latest_revision_filter +label: '' +module: views +description: '' +tag: '' +base_table: node_field_revision +base_field: vid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: none + options: + offset: 0 + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + title: + id: title + table: node_field_revision + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: false + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: string + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + filters: + latest_revision: + id: latest_revision + table: node_revision + field: latest_revision + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: '' + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: node + plugin_id: latest_revision + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + show_admin_links: false + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + tags: { } diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml index dc893efd..08e2d3a0 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml @@ -59,7 +59,6 @@ display: type: string settings: link_to_entity: true - plugin_id: field filters: type: id: type diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tokens.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tokens.yml index 2bb82167..6032b48f 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tokens.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tokens.yml @@ -77,3 +77,34 @@ display: operator: '=' value: 'not an existing name' path: test_tokens_empty + page_3: + display_plugin: page + id: page_3 + display_title: Page + position: 1 + display_options: + defaults: + title: false + pager: false + header: false + pager: + type: mini + options: + items_per_page: 2 + title: 'Test token page with minipager' + path: test_tokens_minipager + display_extenders: { } + header: + area: + id: area + table: views + field: area + relationship: none + group_type: group + admin_label: '' + empty: false + tokenize: false + content: + value: "Total rows: [view:total-rows] - Page count: [view:page-count]" + format: basic_html + plugin_id: text diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_sort_translation.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_sort_translation.yml new file mode 100644 index 00000000..09b9e41a --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_sort_translation.yml @@ -0,0 +1,86 @@ +langcode: en +status: true +dependencies: { } +id: test_view_sort_translation +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: id +core: '8' +display: + default: + display_options: + fields: + nid: + id: nid + field: nid + table: node_field_data + plugin_id: field + entity_type: node + entity_field: nid + langcode: + id: langcode + field: langcode + table: node_field_data + plugin_id: field + entity_type: node + entity_field: langcode + weight: + id: weight + table: node__weight + field: weight + plugin_id: numeric + entity_type: node + entity_field: weight + filters: + langcode: + id: langcode + table: node_field_data + field: langcode + relationship: none + group_type: group + admin_label: '' + operator: in + value: + 'en': 'en' + group: 1 + exposed: false + entity_type: node + entity_field: langcode + plugin_id: language + sorts: + weight: + id: weight + table: node__weight + field: weight_value + order: ASC + plugin_id: standard + entity_type: node + entity_field: weight + display_plugin: default + display_title: Master + id: default + position: 0 + display_de: + display_plugin: embed + id: display_de + display_options: + defaults: + filters: false + filters: + langcode: + id: langcode + table: node_field_data + field: langcode + relationship: none + group_type: group + admin_label: '' + operator: in + value: + 'de': 'de' + group: 1 + exposed: false + entity_type: node + entity_field: langcode + plugin_id: language diff --git a/core/modules/views/tests/modules/views_test_config/views_test_config.info.yml b/core/modules/views/tests/modules/views_test_config/views_test_config.info.yml index dd35948e..4a23badf 100644 --- a/core/modules/views/tests/modules/views_test_config/views_test_config.info.yml +++ b/core/modules/views/tests/modules/views_test_config/views_test_config.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php b/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php new file mode 100644 index 00000000..987be303 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php @@ -0,0 +1,27 @@ + 'view', + '#name' => 'test_exposed_form_buttons', + ]; + $build['error_form'] = \Drupal::formBuilder()->getForm('Drupal\views_test_data\Form\ViewsTestDataErrorForm'); + + return $build; + } + +} diff --git a/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementEmbedForm.php b/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementEmbedForm.php index f80092b3..80d19d1f 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementEmbedForm.php +++ b/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementEmbedForm.php @@ -21,13 +21,13 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['view'] = array( + $form['view'] = [ '#type' => 'view', '#name' => 'test_view_embed', '#display_id' => 'embed_1', - '#arguments' => array(25), + '#arguments' => [25], '#embed' => TRUE, - ); + ]; return $form; } diff --git a/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementForm.php b/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementForm.php index ba00cacb..78aa9980 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementForm.php +++ b/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataElementForm.php @@ -21,13 +21,13 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['view'] = array( + $form['view'] = [ '#type' => 'view', '#name' => 'test_view_embed', '#display_id' => 'default', - '#arguments' => array(25), + '#arguments' => [25], '#embed' => FALSE, - ); + ]; return $form; } diff --git a/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataErrorForm.php b/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataErrorForm.php new file mode 100644 index 00000000..6ad0361c --- /dev/null +++ b/core/modules/views/tests/modules/views_test_data/src/Form/ViewsTestDataErrorForm.php @@ -0,0 +1,48 @@ + 'textfield', + ]; + $form['submit'] = [ + '#type' => 'submit', + '#value' => t('Submit'), + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + $form_state->setErrorByName('text', t('Form validation error')); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + } + +} diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/access/StaticTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/access/StaticTest.php index b2026f7c..55159863 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/access/StaticTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/access/StaticTest.php @@ -19,7 +19,7 @@ class StaticTest extends AccessPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['access'] = array('default' => FALSE); + $options['access'] = ['default' => FALSE]; return $options; } diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/area/TestExample.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/area/TestExample.php index 5cd26239..74818e8b 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/area/TestExample.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/area/TestExample.php @@ -27,8 +27,8 @@ public function access(AccountInterface $account) { */ public function defineOptions() { $options = parent::defineOptions(); - $options['string'] = array('default' => ''); - $options['custom_access'] = array('default' => TRUE); + $options['string'] = ['default' => '']; + $options['custom_access'] = ['default' => TRUE]; return $options; } @@ -46,11 +46,11 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function render($empty = FALSE) { if (!$empty || !empty($this->options['empty'])) { - return array( + return [ '#markup' => $this->globalTokenReplace($this->options['string']), - ); + ]; } - return array(); + return []; } } diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_default/ArgumentDefaultTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_default/ArgumentDefaultTest.php index 6f35ba48..ac068e17 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_default/ArgumentDefaultTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_default/ArgumentDefaultTest.php @@ -19,7 +19,7 @@ class ArgumentDefaultTest extends ArgumentDefaultPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['value'] = array('default' => ''); + $options['value'] = ['default' => '']; return $options; } @@ -28,6 +28,7 @@ protected function defineOptions() { * {@inheritdoc} */ public function getArgument() { + $this->view->element['#cache']['tags'][] = 'example_tag'; return $this->options['value']; } diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php index 61ef3279..ff251b29 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/argument_validator/ArgumentValidatorTest.php @@ -1,6 +1,7 @@ ''); + $options['test_option'] = ['default' => '']; return $options; } @@ -50,21 +50,21 @@ protected function defineOptions() { public function optionsSummary(&$categories, &$options) { parent::optionsSummary($categories, $options); - $categories['display_test'] = array( + $categories['display_test'] = [ 'title' => $this->t('Display test settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -100, - ), - ); + ], + ]; $test_option = $this->getOption('test_option') ?: $this->t('Empty'); - $options['test_option'] = array( + $options['test_option'] = [ 'category' => 'display_test', 'title' => $this->t('Test option'), 'value' => views_ui_truncate($test_option, 24), - ); + ]; } /** @@ -76,12 +76,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($form_state->get('section')) { case 'test_option': $form['#title'] .= $this->t('Test option'); - $form['test_option'] = array( + $form['test_option'] = [ '#title' => $this->t('Test option'), '#type' => 'textfield', '#description' => $this->t('This is a textfield for test_option.'), '#default_value' => $this->getOption('test_option'), - ); + ]; break; } } diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php index 8e3dbd82..25594c35 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php @@ -39,19 +39,19 @@ protected function defineOptions() { public function optionsSummary(&$categories, &$options) { parent::optionsSummary($categories, $options); - $categories['display_extender_test'] = array( + $categories['display_extender_test'] = [ 'title' => $this->t('Display extender test settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -100, - ), - ); + ], + ]; - $options['test_extender_test_option'] = array( + $options['test_extender_test_option'] = [ 'category' => 'display_extender_test', 'title' => $this->t('Test option'), 'value' => views_ui_truncate($this->options['test_extender_test_option'], 24), - ); + ]; } /** @@ -61,12 +61,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { switch ($form_state->get('section')) { case 'test_extender_test_option': $form['#title'] .= $this->t('Test option'); - $form['test_extender_test_option'] = array( + $form['test_extender_test_option'] = [ '#title' => $this->t('Test option'), '#type' => 'textfield', '#description' => $this->t('This is a textfield for test_option.'), '#default_value' => $this->options['test_extender_test_option'], - ); + ]; } } @@ -86,7 +86,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function defaultableSections(&$sections, $section = NULL) { - $sections['test_extender_test_option'] = array('test_extender_test_option'); + $sections['test_extender_test_option'] = ['test_extender_test_option']; } /** diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterBooleanOperatorDefaultTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterBooleanOperatorDefaultTest.php new file mode 100644 index 00000000..33cb5f97 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterBooleanOperatorDefaultTest.php @@ -0,0 +1,25 @@ +ensureMyTable(); + $field = "$this->tableAlias.$this->realField"; + $this->queryOpBoolean($field); + } + +} diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterTest.php index 4d6cd298..5bc7a190 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterTest.php @@ -18,7 +18,7 @@ class FilterTest extends FilterPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['test_enable'] = array('default' => TRUE); + $options['test_enable'] = ['default' => TRUE]; return $options; } @@ -30,11 +30,11 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['test_enable'] = array( + $form['test_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Controls whether the filter plugin should be active'), '#default_value' => $this->options['test_enable'], - ); + ]; } /** diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php index c1d04cf0..cf430af2 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php @@ -18,17 +18,17 @@ * ) */ class QueryTest extends QueryPluginBase { - protected $conditions = array(); - protected $fields = array(); - protected $allItems = array(); - protected $orderBy = array(); + protected $conditions = []; + protected $fields = []; + protected $allItems = []; + protected $orderBy = []; /** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); - $options['test_setting'] = array('default' => ''); + $options['test_setting'] = ['default' => '']; return $options; } @@ -39,11 +39,11 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['test_setting'] = array( + $form['test_setting'] = [ '#title' => $this->t('Test setting'), '#type' => 'textfield', '#default_value' => $this->options['test_setting'], - ); + ]; } /** @@ -57,21 +57,21 @@ public function setAllItems($allItems) { } public function addWhere($group, $field, $value = NULL, $operator = NULL) { - $this->conditions[] = array( + $this->conditions[] = [ 'field' => $field, 'value' => $value, 'operator' => $operator - ); + ]; } - public function addField($table, $field, $alias = '', $params = array()) { + public function addField($table, $field, $alias = '', $params = []) { $this->fields[$field] = $field; return $field; } - public function addOrderBy($table, $field = NULL, $order = 'ASC', $alias = '', $params = array()) { - $this->orderBy = array('field' => $field, 'order' => $order); + public function addOrderBy($table, $field = NULL, $order = 'ASC', $alias = '', $params = []) { + $this->orderBy = ['field' => $field, 'order' => $order]; } @@ -96,7 +96,7 @@ public function build(ViewExecutable $view) { * {@inheritdoc} */ public function execute(ViewExecutable $view) { - $result = array(); + $result = []; foreach ($this->allItems as $element) { // Run all conditions on the element, and add it to the result if they // match. diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/row/RowTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/row/RowTest.php index 8ca36c6f..6af493b1 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/row/RowTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/row/RowTest.php @@ -32,7 +32,7 @@ class RowTest extends RowPluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['test_option'] = array('default' => ''); + $options['test_option'] = ['default' => '']; return $options; } @@ -43,12 +43,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['test_option'] = array( + $form['test_option'] = [ '#title' => $this->t('Test option'), '#type' => 'textfield', '#description' => $this->t('This is a textfield for test_option.'), '#default_value' => $this->options['test_option'], - ); + ]; } /** diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/MappingTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/MappingTest.php index 2c655e74..3ae816a8 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/MappingTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/MappingTest.php @@ -24,26 +24,26 @@ class MappingTest extends Mapping { * {@inheritdoc} */ protected function defineMapping() { - return array( - 'title_field' => array( + return [ + 'title_field' => [ '#title' => $this->t('Title field'), '#description' => $this->t('Choose the field with the custom title.'), '#toggle' => TRUE, '#required' => TRUE, - ), - 'name_field' => array( + ], + 'name_field' => [ '#title' => $this->t('Name field'), '#description' => $this->t('Choose the field with the custom name.'), - ), - 'numeric_field' => array( + ], + 'numeric_field' => [ '#title' => $this->t('Numeric field'), '#description' => $this->t('Select one or more numeric fields.'), '#multiple' => TRUE, '#toggle' => TRUE, '#filter' => 'filterNumericFields', '#required' => TRUE, - ), - ); + ], + ]; } /** diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTemplateTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTemplateTest.php index d64883c7..b924d90e 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTemplateTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTemplateTest.php @@ -20,9 +20,7 @@ class StyleTemplateTest extends StylePluginBase { /** - * Can the style plugin use row plugins. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTest.php index cb66d43f..fa6f57f6 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/style/StyleTest.php @@ -29,9 +29,7 @@ class StyleTest extends StylePluginBase { public $output; /** - * Can the style plugin use row plugins. - * - * @var bool + * {@inheritdoc} */ protected $usesRowPlugin = TRUE; @@ -40,7 +38,7 @@ class StyleTest extends StylePluginBase { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['test_option'] = array('default' => ''); + $options['test_option'] = ['default' => '']; return $options; } @@ -51,12 +49,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['test_option'] = array( + $form['test_option'] = [ '#title' => $this->t('Test option'), '#type' => 'textfield', '#description' => $this->t('This is a textfield for test_option.'), '#default_value' => $this->options['test_option'], - ); + ]; } /** diff --git a/core/modules/views/tests/modules/views_test_data/views_cache.test.es6.js b/core/modules/views/tests/modules/views_test_data/views_cache.test.es6.js new file mode 100644 index 00000000..4089267f --- /dev/null +++ b/core/modules/views/tests/modules/views_test_data/views_cache.test.es6.js @@ -0,0 +1,8 @@ +/** + * @file + * Just a placeholder file for the test. + * + * @see ViewsCacheTest::testHeaderStorage + * + * @ignore + */ diff --git a/core/modules/views/tests/modules/views_test_data/views_cache.test.js b/core/modules/views/tests/modules/views_test_data/views_cache.test.js index 4089267f..9d11a7c1 100644 --- a/core/modules/views/tests/modules/views_test_data/views_cache.test.js +++ b/core/modules/views/tests/modules/views_test_data/views_cache.test.js @@ -1,8 +1,6 @@ /** - * @file - * Just a placeholder file for the test. - * - * @see ViewsCacheTest::testHeaderStorage - * - * @ignore - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ \ No newline at end of file diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.info.yml b/core/modules/views/tests/modules/views_test_data/views_test_data.info.yml index b3d99d16..441eeb4f 100644 --- a/core/modules/views/tests/modules/views_test_data/views_test_data.info.yml +++ b/core/modules/views/tests/modules/views_test_data/views_test_data.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.install b/core/modules/views/tests/modules/views_test_data/views_test_data.install index eeb5faa8..3590440b 100644 --- a/core/modules/views/tests/modules/views_test_data/views_test_data.install +++ b/core/modules/views/tests/modules/views_test_data/views_test_data.install @@ -17,7 +17,7 @@ function views_test_data_schema() { */ function views_test_data_install() { // Add the marquee tag to possible html elements to test the field handler. - $values = array( + $values = [ 'div' => 'DIV', 'span' => 'SPAN', 'h1' => 'H1', @@ -30,6 +30,6 @@ function views_test_data_install() { 'strong' => 'STRONG', 'em' => 'EM', 'marquee' => 'MARQUEE' - ); + ]; \Drupal::configFactory()->getEditable('views.settings')->set('field_rewrite_elements', $values)->save(); } diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.module b/core/modules/views/tests/modules/views_test_data/views_test_data.module index bd917c7e..cdb99cc1 100644 --- a/core/modules/views/tests/modules/views_test_data/views_test_data.module +++ b/core/modules/views/tests/modules/views_test_data/views_test_data.module @@ -66,13 +66,13 @@ function views_test_data_preprocess_views_view_table(&$variables) { * - view: The view object. */ function template_preprocess_views_view_mapping_test(&$variables) { - $variables['element'] = array(); + $variables['element'] = []; foreach ($variables['rows'] as $delta => $row) { - $fields = array(); + $fields = []; foreach ($variables['options']['mapping'] as $type => $field_names) { if (!is_array($field_names)) { - $field_names = array($field_names); + $field_names = [$field_names]; } foreach ($field_names as $field_name) { if ($value = $variables['view']->style_plugin->getField($delta, $field_name)) { @@ -87,26 +87,26 @@ function template_preprocess_views_view_mapping_test(&$variables) { } // Build a container for the row. - $variables['element'][$delta] = array( + $variables['element'][$delta] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array( + '#attributes' => [ + 'class' => [ 'views-row-mapping-test', - ), - ), - ); + ], + ], + ]; // Add each field to the row. foreach ($fields as $key => $render) { - $variables['element'][$delta][$key] = array( + $variables['element'][$delta][$key] = [ '#children' => $render, '#type' => 'container', - '#attributes' => array( - 'class' => array( + '#attributes' => [ + 'class' => [ $key, - ), - ), - ); + ], + ], + ]; } } } diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.routing.yml b/core/modules/views/tests/modules/views_test_data/views_test_data.routing.yml index cb0ad637..1bf63f40 100644 --- a/core/modules/views/tests/modules/views_test_data/views_test_data.routing.yml +++ b/core/modules/views/tests/modules/views_test_data/views_test_data.routing.yml @@ -19,3 +19,11 @@ views_test_data.form_multiple: _controller: '\Drupal\views_test_data\Controller\ViewsTestFormMultipleController::testPage' requirements: _access: 'TRUE' + +views_test_data.error_form_page: + path: '/views_test_data_error_form_page' + defaults: + _title: 'Test Views Form Exposed Errors' + _controller: '\Drupal\views_test_data\Controller\ViewsTestDataController::errorFormPage' + requirements: + _access: 'TRUE' diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.views.inc b/core/modules/views/tests/modules/views_test_data/views_test_data.views.inc index ceaa8e9f..11159412 100644 --- a/core/modules/views/tests/modules/views_test_data/views_test_data.views.inc +++ b/core/modules/views/tests/modules/views_test_data/views_test_data.views.inc @@ -39,7 +39,7 @@ function views_test_data_views_data_alter() { function views_test_data_views_analyze(ViewExecutable $view) { \Drupal::state()->set('views_hook_test_views_analyze', TRUE); - $ret = array(); + $ret = []; $ret[] = Analyzer::formatMessage(t('Test ok message'), 'ok'); $ret[] = Analyzer::formatMessage(t('Test warning message'), 'warning'); diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc b/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc index d9d2a668..dd69f4c9 100644 --- a/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc +++ b/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc @@ -22,10 +22,10 @@ function views_test_data_views_query_substitutions(ViewExecutable $view) { function views_test_data_views_form_substitutions() { \Drupal::state()->set('views_hook_test_views_form_substitutions', TRUE); $render = ['#markup' => 'unescaped']; - return array( + return [ '' => 'escaped', '' => \Drupal::service('renderer')->renderPlain($render), - ); + ]; } /** diff --git a/core/modules/views/tests/modules/views_test_formatter/views_test_formatter.info.yml b/core/modules/views/tests/modules/views_test_formatter/views_test_formatter.info.yml index e6fa7c55..319edb8f 100644 --- a/core/modules/views/tests/modules/views_test_formatter/views_test_formatter.info.yml +++ b/core/modules/views/tests/modules/views_test_formatter/views_test_formatter.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/tests/modules/views_test_language/views_test_language.info.yml b/core/modules/views/tests/modules/views_test_language/views_test_language.info.yml index 691104f2..8b833856 100644 --- a/core/modules/views/tests/modules/views_test_language/views_test_language.info.yml +++ b/core/modules/views/tests/modules/views_test_language/views_test_language.info.yml @@ -8,8 +8,8 @@ dependencies: - views - language -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/tests/src/Functional/DefaultViewsTest.php b/core/modules/views/tests/src/Functional/DefaultViewsTest.php new file mode 100644 index 00000000..9e4c338d --- /dev/null +++ b/core/modules/views/tests/src/Functional/DefaultViewsTest.php @@ -0,0 +1,232 @@ + [1], + 'taxonomy_term' => [1], + 'glossary' => ['all'], + ]; + + protected function setUp($import_test_views = TRUE) { + parent::setUp($import_test_views); + + $this->drupalPlaceBlock('page_title_block'); + + // Create Basic page node type. + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + + $vocabulary = Vocabulary::create([ + 'name' => $this->randomMachineName(), + 'description' => $this->randomMachineName(), + 'vid' => Unicode::strtolower($this->randomMachineName()), + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + 'help' => '', + 'nodes' => ['page' => 'page'], + 'weight' => mt_rand(0, 10), + ]); + $vocabulary->save(); + + // Create a field. + $field_name = Unicode::strtolower($this->randomMachineName()); + + $handler_settings = [ + 'target_bundles' => [ + $vocabulary->id() => $vocabulary->id(), + ], + 'auto_create' => TRUE, + ]; + $this->createEntityReferenceField('node', 'page', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + + // Create a time in the past for the archive. + $time = REQUEST_TIME - 3600; + + $this->addDefaultCommentField('node', 'page'); + + for ($i = 0; $i <= 10; $i++) { + $user = $this->drupalCreateUser(); + $term = $this->createTerm($vocabulary); + + $values = ['created' => $time, 'type' => 'page']; + $values[$field_name][]['target_id'] = $term->id(); + + // Make every other node promoted. + if ($i % 2) { + $values['promote'] = TRUE; + } + $values['body'][]['value'] = \Drupal::l('Node ' . 1, new Url('entity.node.canonical', ['node' => 1])); + + $node = $this->drupalCreateNode($values); + + $comment = [ + 'uid' => $user->id(), + 'status' => CommentInterface::PUBLISHED, + 'entity_id' => $node->id(), + 'entity_type' => 'node', + 'field_name' => 'comment' + ]; + Comment::create($comment)->save(); + + $unpublished_comment = [ + 'uid' => $user->id(), + 'status' => CommentInterface::NOT_PUBLISHED, + 'entity_id' => $node->id(), + 'entity_type' => 'node', + 'field_name' => 'comment', + ]; + Comment::create($unpublished_comment)->save(); + } + + // Some views, such as the "Who's Online" view, only return results if at + // least one user is logged in. + $account = $this->drupalCreateUser([]); + $this->drupalLogin($account); + } + + /** + * Test that all Default views work as expected. + */ + public function testDefaultViews() { + // Get all default views. + $controller = $this->container->get('entity.manager')->getStorage('view'); + $views = $controller->loadMultiple(); + + foreach ($views as $name => $view_storage) { + $view = $view_storage->getExecutable(); + $view->initDisplay(); + foreach ($view->storage->get('display') as $display_id => $display) { + $view->setDisplay($display_id); + + // Add any args if needed. + if (array_key_exists($name, $this->viewArgMap)) { + $view->preExecute($this->viewArgMap[$name]); + } + + $this->assert(TRUE, format_string('View @view will be executed.', ['@view' => $view->storage->id()])); + $view->execute(); + + $tokens = ['@name' => $name, '@display_id' => $display_id]; + $this->assertTrue($view->executed, format_string('@name:@display_id has been executed.', $tokens)); + + $count = count($view->result); + $this->assertTrue($count > 0, format_string('@count results returned', ['@count' => $count])); + $view->destroy(); + } + } + } + + /** + * Returns a new term with random properties in vocabulary $vid. + */ + public function createTerm($vocabulary) { + $filter_formats = filter_formats(); + $format = array_pop($filter_formats); + $term = Term::create([ + 'name' => $this->randomMachineName(), + 'description' => $this->randomMachineName(), + // Use the first available text format. + 'format' => $format->id(), + 'vid' => $vocabulary->id(), + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ]); + $term->save(); + return $term; + } + + /** + * Tests the archive view. + */ + public function testArchiveView() { + // Create additional nodes compared to the one in the setup method. + // Create two nodes in the same month, and one in each following month. + $node = [ + // Sun, 19 Nov 1978 05:00:00 GMT. + 'created' => 280299600, + ]; + $this->drupalCreateNode($node); + $this->drupalCreateNode($node); + $node = [ + // Tue, 19 Dec 1978 05:00:00 GMT. + 'created' => 282891600, + ]; + $this->drupalCreateNode($node); + $node = [ + // Fri, 19 Jan 1979 05:00:00 GMT. + 'created' => 285570000, + ]; + $this->drupalCreateNode($node); + + $view = Views::getView('archive'); + $view->setDisplay('page_1'); + $this->executeView($view); + $columns = ['nid', 'created_year_month', 'num_records']; + $column_map = array_combine($columns, $columns); + // Create time of additional nodes created in the setup method. + $created_year_month = date('Ym', REQUEST_TIME - 3600); + $expected_result = [ + [ + 'nid' => 1, + 'created_year_month' => $created_year_month, + 'num_records' => 11, + ], + [ + 'nid' => 15, + 'created_year_month' => 197901, + 'num_records' => 1, + ], + [ + 'nid' => 14, + 'created_year_month' => 197812, + 'num_records' => 1, + ], + [ + 'nid' => 12, + 'created_year_month' => 197811, + 'num_records' => 2, + ], + ]; + $this->assertIdenticalResultset($view, $expected_result, $column_map); + + $view->storage->setStatus(TRUE); + $view->save(); + \Drupal::service('router.builder')->rebuild(); + + $this->drupalGet('archive'); + $this->assertResponse(200); + } + +} diff --git a/core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php similarity index 81% rename from core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php rename to core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php index db1110d4..19aa191e 100644 --- a/core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php +++ b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php @@ -1,9 +1,9 @@ container->get('entity.definition_update_manager'); \Drupal::entityManager()->clearCachedDefinitions(); $update_manager->applyUpdates(); - ViewTestData::createTestViews(get_class($this), array('comment_test_views')); + ViewTestData::createTestViews(get_class($this), ['comment_test_views']); \Drupal::state()->set('entity_test.views_data', [ 'entity_test' => [ 'test_text_access' => [ diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTest.php b/core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php similarity index 84% rename from core/modules/views/src/Tests/Entity/FieldEntityTest.php rename to core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php index 215b631b..a46e54c9 100644 --- a/core/modules/views/src/Tests/Entity/FieldEntityTest.php +++ b/core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php @@ -1,11 +1,11 @@ drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); $this->addDefaultCommentField('node', 'page'); - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); } /** @@ -61,12 +61,12 @@ public function testGetEntity() { 'title' => $this->randomString(), ]); $node->save(); - $comment = Comment::create(array( + $comment = Comment::create([ 'uid' => $account->id(), 'entity_id' => $node->id(), 'entity_type' => 'node', 'field_name' => 'comment' - )); + ]); $comment->save(); $user = $this->drupalCreateUser(['access comments']); diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php b/core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php similarity index 91% rename from core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php rename to core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php index bd4e2ed1..2a227c54 100644 --- a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php +++ b/core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php @@ -1,12 +1,12 @@ cssSelect('div.views-row'); foreach ($rows as $row) { $actual[] = [ - 'title' => (string) $row->xpath((new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))[0], - 'sticky' => (string) $row->xpath((new CssSelectorConverter())->toXPath('.views-field-sticky span.field-content'))[0], + 'title' => $row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))->getText(), + 'sticky' => $row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-sticky span.field-content'))->getText(), ]; } $this->assertEqual($actual, $expected); diff --git a/core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php b/core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php similarity index 81% rename from core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php rename to core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php index 589c4dc0..993293ce 100644 --- a/core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php +++ b/core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php @@ -1,9 +1,9 @@ drupalCreateContentType(array('type' => 'test_bundle')); - $this->drupalCreateContentType(array('type' => 'test_bundle_2')); + $this->drupalCreateContentType(['type' => 'test_bundle']); + $this->drupalCreateContentType(['type' => 'test_bundle_2']); - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); $this->entityBundles = $this->container->get('entity_type.bundle.info')->getBundleInfo('node'); @@ -92,7 +92,7 @@ public function testFilterEntity() { $this->assertEqual(count($view->result), $this->entities['count']); // Test the valueOptions of the filter handler. - $expected = array(); + $expected = []; foreach ($this->entityBundles as $key => $info) { $expected[$key] = $info['label']; @@ -106,7 +106,7 @@ public function testFilterEntity() { // Test each bundle type. $view->initDisplay(); $filters = $view->display_handler->getOption('filters'); - $filters['type']['value'] = array($key => $key); + $filters['type']['value'] = [$key => $key]; $view->display_handler->setOption('filters', $filters); $this->executeView($view); @@ -118,7 +118,7 @@ public function testFilterEntity() { // Test an invalid bundle type to make sure we have no results. $view->initDisplay(); $filters = $view->display_handler->getOption('filters'); - $filters['type']['value'] = array('type_3' => 'type_3'); + $filters['type']['value'] = ['type_3' => 'type_3']; $view->display_handler->setOption('filters', $filters); $this->executeView($view); diff --git a/core/modules/views/tests/src/Functional/Entity/LatestRevisionFilterTest.php b/core/modules/views/tests/src/Functional/Entity/LatestRevisionFilterTest.php new file mode 100644 index 00000000..d73a1179 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Entity/LatestRevisionFilterTest.php @@ -0,0 +1,160 @@ +drupalCreateContentType(['type' => 'article']); + + // Create a node that goes through various default/pending revision stages. + $node = Node::create([ + 'title' => 'First node - v1 - default', + 'type' => 'article', + ]); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + + $node->setTitle('First node - v2 - pending'); + $node->setNewRevision(TRUE); + $node->isDefaultRevision(FALSE); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + + $node->setTitle('First node - v3 - default'); + $node->setNewRevision(TRUE); + $node->isDefaultRevision(TRUE); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + + $node->setTitle('First node - v4 - pending'); + $node->setNewRevision(TRUE); + $node->isDefaultRevision(TRUE); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + $this->latestRevisions[$node->getRevisionId()] = $node; + + // Create a node that has a default and a pending revision. + $node = Node::create([ + 'title' => 'Second node - v1 - default', + 'type' => 'article', + ]); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + + $node->setTitle('Second node - v2 - pending'); + $node->setNewRevision(TRUE); + $node->isDefaultRevision(FALSE); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + $this->latestRevisions[$node->getRevisionId()] = $node; + + // Create a node that only has a default revision. + $node = Node::create([ + 'title' => 'Third node - v1 - default', + 'type' => 'article', + ]); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + $this->latestRevisions[$node->getRevisionId()] = $node; + + // Create a node that only has a pending revision. + $node = Node::create([ + 'title' => 'Fourth node - v1 - pending', + 'type' => 'article', + ]); + $node->isDefaultRevision(FALSE); + $node->save(); + $this->allRevisions[$node->getRevisionId()] = $node; + $this->latestRevisions[$node->getRevisionId()] = $node; + } + + /** + * Tests the 'Latest revision' filter. + */ + public function testLatestRevisionFilter() { + $view = Views::getView('test_latest_revision_filter'); + + $this->executeView($view); + + // Check that we have all the results. + $this->assertCount(count($this->latestRevisions), $view->result); + + $expected = $not_expected = []; + foreach ($this->allRevisions as $revision_id => $revision) { + if (isset($this->latestRevisions[$revision_id])) { + $expected[] = [ + 'vid' => $revision_id, + 'title' => $revision->label(), + ]; + } + else { + $not_expected[] = $revision_id; + } + } + $this->assertIdenticalResultset($view, $expected, ['vid' => 'vid', 'title' => 'title'], 'The test view only shows the latest revisions.'); + $this->assertNotInResultSet($view, $not_expected, 'Non-latest revisions are not shown by the view.'); + $view->destroy(); + } + + /** + * Verifies that a list of revision IDs are not in the result. + * + * @param \Drupal\views\ViewExecutable $view + * An executed View. + * @param array $not_expected_revision_ids + * An array of revision IDs which should not be part of the result set. + * @param string $message + * (optional) A custom message to display with the assertion. + */ + protected function assertNotInResultSet(ViewExecutable $view, array $not_expected_revision_ids, $message = '') { + $found_revision_ids = array_filter($view->result, function ($row) use ($not_expected_revision_ids) { + return in_array($row->vid, $not_expected_revision_ids); + }); + $this->assertFalse($found_revision_ids, $message); + } + +} diff --git a/core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php b/core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php similarity index 84% rename from core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php rename to core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php index df6f7d4d..911cd61e 100644 --- a/core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php +++ b/core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php @@ -1,29 +1,29 @@ drupalCreateContentType(); - $nodes_per_char = array( + $nodes_per_char = [ 'd' => 1, 'r' => 4, 'u' => 10, 'p' => 2, 'a' => 3, 'l' => 6, - ); + ]; $nodes_by_char = []; foreach ($nodes_per_char as $char => $count) { - $setting = array( + $setting = [ 'type' => $type->id() - ); + ]; for ($i = 0; $i < $count; $i++) { $node = $setting; $node['title'] = $char . $this->randomString(3); @@ -95,9 +96,10 @@ public function testGlossaryView() { 'node_list', 'user:0', 'user_list', + 'http_response', 'rendered', - // FinishResponseSubscriber adds this cache tag to responses that have the - // 'user.permissions' cache context for anonymous users. + // FinishResponseSubscriber adds this cache tag to responses that have + // the 'user.permissions' cache context for anonymous users. 'config:user.role.anonymous', ] ); @@ -110,10 +112,11 @@ public function testGlossaryView() { $label = Unicode::strtoupper($char); // Get the summary link for a certain character. Filter by label and href // to ensure that both of them are correct. - $result = $this->xpath('//a[contains(@href, :href) and normalize-space(text())=:label]/..', array(':href' => $href, ':label' => $label)); + $result = $this->xpath('//a[contains(@href, :href) and normalize-space(text())=:label]/..', [':href' => $href, ':label' => $label]); $this->assertTrue(count($result)); - // The rendered output looks like "| (count)" so let's figure out the int. - $result_count = trim(str_replace(array('|', '(', ')'), '', (string) $result[0])); + // The rendered output looks like "X | (count)" so let's + // figure out the int. + $result_count = explode(' ', trim(str_replace(['|', '(', ')'], '', $result[0]->getText())))[1]; $this->assertEqual($result_count, $count, 'The expected number got rendered.'); } } diff --git a/core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php b/core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php similarity index 77% rename from core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php rename to core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php index 86d1f992..dc914ce2 100644 --- a/core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php +++ b/core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php @@ -1,7 +1,8 @@ enableViewsTestModule(); + } + + protected function viewsData() { + $data = parent::viewsData(); + $data['views']['test_example'] = [ + 'title' => 'Test Example area', + 'help' => 'A area handler which just exists for tests.', + 'area' => [ + 'id' => 'test_example' + ] + ]; + + return $data; + } + + + /** + * Tests the generic UI of a area handler. + */ + public function testUI() { + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); + $this->drupalLogin($admin_user); + + $types = ['header', 'footer', 'empty']; + $labels = []; + foreach ($types as $type) { + $edit_path = 'admin/structure/views/nojs/handler/test_example_area/default/' . $type . '/test_example'; + + // First setup an empty label. + $this->drupalPostForm($edit_path, [], t('Apply')); + $this->assertText('Test Example area'); + + // Then setup a no empty label. + $labels[$type] = $this->randomMachineName(); + $this->drupalPostForm($edit_path, ['options[admin_label]' => $labels[$type]], t('Apply')); + // Make sure that the new label appears on the site. + $this->assertText($labels[$type]); + + // Test that the settings (empty/admin_label) are accessible. + $this->drupalGet($edit_path); + $this->assertField('options[admin_label]'); + if ($type !== 'empty') { + $this->assertField('options[empty]'); + } + } + } + + /** + * Tests the rendering of an area. + */ + public function testRenderArea() { + $view = Views::getView('test_example_area'); + $view->initHandlers(); + + // Insert a random string with XSS injection in the test area plugin. + // Ensure that the string is rendered for the header, footer, and empty + // text with the markup properly escaped. + $header_string = '

            ' . $this->randomMachineName() . '

            '; + $footer_string = '

            ' . $this->randomMachineName() . '

            '; + $empty_string = '

            ' . $this->randomMachineName() . '

            '; + + $view->header['test_example']->options['string'] = $header_string; + $view->header['test_example']->options['empty'] = TRUE; + + $view->footer['test_example']->options['string'] = $footer_string; + $view->footer['test_example']->options['empty'] = TRUE; + + $view->empty['test_example']->options['string'] = $empty_string; + + // Check whether the strings exist in the output and are sanitized. + $output = $view->preview(); + $output = $this->container->get('renderer')->renderRoot($output); + $this->assertTrue(strpos($output, Xss::filterAdmin($header_string)) !== FALSE, 'Views header exists in the output and is sanitized'); + $this->assertTrue(strpos($output, Xss::filterAdmin($footer_string)) !== FALSE, 'Views footer exists in the output and is sanitized'); + $this->assertTrue(strpos($output, Xss::filterAdmin($empty_string)) !== FALSE, 'Views empty exists in the output and is sanitized'); + $this->assertTrue(strpos($output, 'initDisplay(); + $view->initHandlers(); + $handlers = $view->display_handler->getHandlers('empty'); + $this->assertEqual(0, count($handlers)); + + $output = $view->preview(); + $output = \Drupal::service('renderer')->renderRoot($output); + // The area output should not be present since access was denied. + $this->assertFalse(strpos($output, 'a custom string') !== FALSE); + $view->destroy(); + + // Test with access granted for the area handler. + $view = Views::getView('test_example_area_access'); + $view->initDisplay(); + $view->display_handler->overrideOption('empty', [ + 'test_example' => [ + 'field' => 'test_example', + 'id' => 'test_example', + 'table' => 'views', + 'plugin_id' => 'test_example', + 'string' => 'a custom string', + 'custom_access' => TRUE, + ], + ]); + $view->initHandlers(); + $handlers = $view->display_handler->getHandlers('empty'); + + $output = $view->preview(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->assertTrue(strpos($output, 'a custom string') !== FALSE); + $this->assertEqual(1, count($handlers)); + } + + /** + * Tests global tokens. + */ + public function testRenderAreaToken() { + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); + $this->drupalLogin($admin_user); + + $view = Views::getView('test_example_area'); + $view->initHandlers(); + + $this->drupalGet('admin/structure/views/nojs/handler/test_example_area/default/empty/test_example'); + + // Test that the list is token present. + $element = $this->xpath('//ul[@class="global-tokens"]'); + $this->assertTrue($element, 'Token list found on the options form.'); + + $empty_handler = &$view->empty['test_example']; + + // Test the list of available tokens. + $available = $empty_handler->getAvailableGlobalTokens(); + foreach (['site', 'view'] as $type) { + $this->assertTrue(!empty($available[$type]) && is_array($available[$type])); + // Test that each item exists in the list. + foreach ($available[$type] as $token => $info) { + $this->assertText("[$type:$token]"); + } + } + + // Test the rendered output of a token. + $empty_handler->options['string'] = '[site:name]'; + + // Test we have the site:name token in the output. + $output = $view->preview(); + $output = $this->container->get('renderer')->renderRoot($output); + $expected = \Drupal::token()->replace('[site:name]'); + $this->assertTrue(strpos($output, $expected) !== FALSE); + } + + /** + * Tests overriding the view title using the area title handler. + */ + public function testTitleArea() { + $view = Views::getView('frontpage'); + $view->initDisplay('page_1'); + + // Add the title area handler to the empty area. + $view->displayHandlers->get('page_1')->overrideOption('empty', [ + 'title' => [ + 'id' => 'title', + 'table' => 'views', + 'field' => 'title', + 'admin_label' => '', + 'empty' => '0', + 'title' => 'Overridden title', + 'plugin_id' => 'title', + ], + ]); + + $view->storage->enable()->save(); + + $this->drupalGet('node'); + $this->assertText('Overridden title', 'Overridden title found.'); + } + +} diff --git a/core/modules/views/src/Tests/Handler/AreaTitleWebTest.php b/core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php similarity index 91% rename from core/modules/views/src/Tests/Handler/AreaTitleWebTest.php rename to core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php index afae1eb8..9e1fcfad 100644 --- a/core/modules/views/src/Tests/Handler/AreaTitleWebTest.php +++ b/core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php @@ -1,9 +1,9 @@ enableViewsTestModule(); } diff --git a/core/modules/views/src/Tests/Handler/ArgumentStringTest.php b/core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php similarity index 76% rename from core/modules/views/src/Tests/Handler/ArgumentStringTest.php rename to core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php index e47b1a36..17ece944 100644 --- a/core/modules/views/src/Tests/Handler/ArgumentStringTest.php +++ b/core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php @@ -1,7 +1,8 @@ $char . $this->randomMachineName(), - ); + ]; $this->drupalCreateNode($edit); } } diff --git a/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php b/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php new file mode 100644 index 00000000..e0e380b0 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php @@ -0,0 +1,66 @@ +drupalCreateUser(['access content overview', 'administer nodes', 'bypass node access']); + $this->drupalLogin($admin_user); + } + + /** + * Tests dropbutton field. + */ + public function testDropbutton() { + // Create some test nodes. + $nodes = []; + for ($i = 0; $i < 5; $i++) { + $nodes[] = $this->drupalCreateNode(); + } + + $this->drupalGet('test-dropbutton'); + foreach ($nodes as $node) { + $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => $node->label()]); + $this->assertEqual(count($result), 1, 'Just one node title link was found.'); + $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => 'Custom Text']); + $this->assertEqual(count($result), 1, 'Just one custom link was found.'); + } + + // Check if the dropbutton.js library is available. + $this->drupalGet('admin/content'); + $this->assertRaw('dropbutton.js'); + // Check if the dropbutton.js library is available on a cached page to + // ensure that bubbleable metadata is not lost in the views render workflow. + $this->drupalGet('admin/content'); + $this->assertRaw('dropbutton.js'); + } + +} diff --git a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php similarity index 79% rename from core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php rename to core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php index e76d54e3..653ce115 100644 --- a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php +++ b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php @@ -1,34 +1,35 @@ drupalCreateContentType(['type' => 'article', 'name' => 'Article']); @@ -46,7 +47,7 @@ public function testEntityOperations() { // Create some test entities. Every other entity is Hungarian while all // have a Spanish translation. - $entities = array(); + $entities = []; for ($i = 0; $i < 5; $i++) { $entity = Node::create([ 'title' => $this->randomString(), @@ -60,7 +61,7 @@ public function testEntityOperations() { $entities[$i] = $entity; } - $admin_user = $this->drupalCreateUser(array('access administration pages', 'administer nodes', 'bypass node access')); + $admin_user = $this->drupalCreateUser(['access administration pages', 'administer nodes', 'bypass node access']); $this->drupalLogin($this->rootUser); $this->drupalGet('test-entity-operations'); /** @var $entity \Drupal\entity_test\Entity\EntityTest */ @@ -72,8 +73,8 @@ public function testEntityOperations() { $this->assertTrue(count($operations) > 0, 'There are operations.'); foreach ($operations as $operation) { $expected_destination = Url::fromUri('internal:/test-entity-operations')->toString(); - $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[@href=:path and text()=:title]', array(':path' => $operation['url']->toString() . '?destination=' . $expected_destination, ':title' => $operation['title'])); - $this->assertEqual(count($result), 1, t('Found entity @operation link with destination parameter.', array('@operation' => $operation['title']))); + $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[@href=:path and text()=:title]', [':path' => $operation['url']->toString() . '?destination=' . $expected_destination, ':title' => (string) $operation['title']]); + $this->assertEqual(count($result), 1, t('Found entity @operation link with destination parameter.', ['@operation' => $operation['title']])); // Entities which were created in Hungarian should link to the Hungarian // edit form, others to the English one (which has no path prefix here). $base_path = \Drupal::request()->getBasePath(); diff --git a/core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php similarity index 80% rename from core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php rename to core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php index 4a37b58e..d38ba417 100644 --- a/core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php +++ b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php @@ -1,35 +1,36 @@ drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $node_type = $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); // Create the unlimited text field. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'node', 'type' => 'text', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - )); + ]); $field_storage->save(); // Create an instance of the text field on the content type. - $field = array( + $field = [ 'field_storage' => $field_storage, 'bundle' => $node_type->id(), - ); + ]; FieldConfig::create($field)->save(); } @@ -68,10 +69,10 @@ public function testGroupRows() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); - $edit = array( + $edit = [ 'title' => $this->randomMachineName(), - $this->fieldName => array('a', 'b', 'c'), - ); + $this->fieldName => ['a', 'b', 'c'], + ]; $this->drupalCreateNode($edit); $view = Views::getView('test_group_rows'); diff --git a/core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php similarity index 90% rename from core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php rename to core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php index 646cb122..275960cb 100644 --- a/core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php +++ b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php @@ -1,11 +1,11 @@ nodeType = $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); @@ -98,7 +98,7 @@ public function testGroupRows() { $rendered_value = []; foreach ($result as $row) { - $rendered_value[] = (string) $row[0]; + $rendered_value[] = $row->getText(); } $this->assertEqual(['a, b, c'], $rendered_value); } @@ -111,7 +111,7 @@ public function testUngroupedRows() { $result = $this->cssSelect('div.views-field-field-views-testing-group- div'); $rendered_value = []; foreach ($result as $row) { - $rendered_value[] = (string) $row[0]; + $rendered_value[] = $row->getText(); } $this->assertEqual(['a', 'b', 'c'], $rendered_value); } diff --git a/core/modules/views/src/Tests/Handler/FieldWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php similarity index 91% rename from core/modules/views/src/Tests/Handler/FieldWebTest.php rename to core/modules/views/tests/src/Functional/Handler/FieldWebTest.php index e8520698..a3646f0c 100644 --- a/core/modules/views/src/Tests/Handler/FieldWebTest.php +++ b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php @@ -1,13 +1,14 @@ 'name', - ); + ]; - protected function setUp() { - parent::setUp(); + protected function setUp($import_test_views = TRUE) { + parent::setUp($import_test_views); $this->enableViewsTestModule(); } @@ -97,9 +98,9 @@ public function testClickSorting() { */ protected function clickSortLoadIdsFromOutput() { $fields = $this->xpath("//td[contains(@class, 'views-field-id')]"); - $ids = array(); + $ids = []; foreach ($fields as $field) { - $ids[] = (int) $field[0]; + $ids[] = (int) $field->getText(); } return $ids; } @@ -174,14 +175,14 @@ protected function parseContent($content) { * format and return values see the SimpleXML documentation, * http://php.net/manual/function.simplexml-element-xpath.php. */ - protected function xpathContent($content, $xpath, array $arguments = array()) { + protected function xpathContent($content, $xpath, array $arguments = []) { if ($elements = $this->parseContent($content)) { $xpath = $this->buildXPathQuery($xpath, $arguments); $result = $elements->xpath($xpath); // Some combinations of PHP / libxml versions return an empty array // instead of the documented FALSE. Forcefully convert any falsish values // to an empty array to allow foreach(...) constructions. - return $result ? $result : array(); + return $result ? $result : []; } else { return FALSE; @@ -224,7 +225,7 @@ public function testAlterUrl() { // Some generic test code adapted from the UrlTest class, which tests // mostly the different options for the path. - foreach (array(FALSE, TRUE) as $absolute) { + foreach ([FALSE, TRUE] as $absolute) { $alter = &$id_field->options['alter']; $alter['path'] = 'node/123'; @@ -258,7 +259,7 @@ public function testAlterUrl() { // @todo The route-based URL generator strips out NULL attributes. // $expected_result = \Drupal::url('entity.node.canonical', ['node' => '123'], ['query' => ['foo' => NULL], 'fragment' => 'bar', 'absolute' => $absolute]); - $expected_result = Url::fromUserInput('/node/123', array('query' => array('foo' => NULL), 'fragment' => 'bar', 'absolute' => $absolute))->toString(); + $expected_result = Url::fromUserInput('/node/123', ['query' => ['foo' => NULL], 'fragment' => 'bar', 'absolute' => $absolute])->toString(); $alter['path'] = 'node/123?foo#bar'; $result = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) { return $id_field->theme($row); @@ -345,7 +346,7 @@ public function testAlterUrl() { $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) { return $id_field->theme($row); }); - $elements = $this->xpathContent($output, '//a[contains(@class, :class)]', array(':class' => $class)); + $elements = $this->xpathContent($output, '//a[contains(@class, :class)]', [':class' => $class]); $this->assertTrue($elements); // @fixme link_class, alt, rel cannot be unset, which should be fixed. $id_field->options['alter']['link_class'] = ''; @@ -355,7 +356,7 @@ public function testAlterUrl() { $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) { return $id_field->theme($row); }); - $elements = $this->xpathContent($output, '//a[contains(@title, :alt)]', array(':alt' => $rel)); + $elements = $this->xpathContent($output, '//a[contains(@title, :alt)]', [':alt' => $rel]); $this->assertTrue($elements); $id_field->options['alter']['alt'] = ''; @@ -364,7 +365,7 @@ public function testAlterUrl() { $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) { return $id_field->theme($row); }); - $elements = $this->xpathContent($output, '//a[contains(@rel, :rel)]', array(':rel' => $rel)); + $elements = $this->xpathContent($output, '//a[contains(@rel, :rel)]', [':rel' => $rel]); $this->assertTrue($elements); $id_field->options['alter']['rel'] = ''; @@ -373,7 +374,7 @@ public function testAlterUrl() { $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($id_field, $row) { return $id_field->theme($row); }); - $elements = $this->xpathContent($output, '//a[contains(@target, :target)]', array(':target' => $target)); + $elements = $this->xpathContent($output, '//a[contains(@target, :target)]', [':target' => $target]); $this->assertTrue($elements); unset($id_field->options['alter']['target']); } @@ -395,81 +396,81 @@ public function testFieldClasses() { $id_field->options['label'] = $this->randomMachineName(); $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', array(':class' => 'field-content'))); - $this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', array(':class' => 'field__label'))); + $this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', [':class' => 'field-content'])); + $this->assertFalse($this->xpathContent($output, '//div[contains(@class, :class)]', [':class' => 'field__label'])); $id_field->options['element_default_classes'] = TRUE; $output = $view->preview(); $output = $renderer->renderRoot($output); // Per default the label and the element of the field are spans. - $this->assertTrue($this->xpathContent($output, '//span[contains(@class, :class)]', array(':class' => 'field-content'))); - $this->assertTrue($this->xpathContent($output, '//span[contains(@class, :class)]', array(':class' => 'views-label'))); - $this->assertTrue($this->xpathContent($output, '//div[contains(@class, :class)]', array(':class' => 'views-field'))); + $this->assertTrue($this->xpathContent($output, '//span[contains(@class, :class)]', [':class' => 'field-content'])); + $this->assertTrue($this->xpathContent($output, '//span[contains(@class, :class)]', [':class' => 'views-label'])); + $this->assertTrue($this->xpathContent($output, '//div[contains(@class, :class)]', [':class' => 'views-field'])); // Tests the element wrapper classes/element. $random_class = $this->randomMachineName(); // Set some common wrapper element types and see whether they appear with and without a custom class set. - foreach (array('h1', 'span', 'p', 'div') as $element_type) { + foreach (['h1', 'span', 'p', 'div'] as $element_type) { $id_field->options['element_wrapper_type'] = $element_type; // Set a custom wrapper element css class. $id_field->options['element_wrapper_class'] = $random_class; $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertTrue($this->xpathContent($output, "//{$element_type}[contains(@class, :class)]", array(':class' => $random_class))); + $this->assertTrue($this->xpathContent($output, "//{$element_type}[contains(@class, :class)]", [':class' => $random_class])); // Set no custom css class. $id_field->options['element_wrapper_class'] = ''; $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertFalse($this->xpathContent($output, "//{$element_type}[contains(@class, :class)]", array(':class' => $random_class))); + $this->assertFalse($this->xpathContent($output, "//{$element_type}[contains(@class, :class)]", [':class' => $random_class])); $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]/{$element_type}")); } // Tests the label class/element. // Set some common label element types and see whether they appear with and without a custom class set. - foreach (array('h1', 'span', 'p', 'div') as $element_type) { + foreach (['h1', 'span', 'p', 'div'] as $element_type) { $id_field->options['element_label_type'] = $element_type; // Set a custom label element css class. $id_field->options['element_label_class'] = $random_class; $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]//{$element_type}[contains(@class, :class)]", array(':class' => $random_class))); + $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]//{$element_type}[contains(@class, :class)]", [':class' => $random_class])); // Set no custom css class. $id_field->options['element_label_class'] = ''; $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertFalse($this->xpathContent($output, "//li[contains(@class, views-row)]//{$element_type}[contains(@class, :class)]", array(':class' => $random_class))); + $this->assertFalse($this->xpathContent($output, "//li[contains(@class, views-row)]//{$element_type}[contains(@class, :class)]", [':class' => $random_class])); $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]//{$element_type}")); } // Tests the element classes/element. // Set some common element element types and see whether they appear with and without a custom class set. - foreach (array('h1', 'span', 'p', 'div') as $element_type) { + foreach (['h1', 'span', 'p', 'div'] as $element_type) { $id_field->options['element_type'] = $element_type; // Set a custom label element css class. $id_field->options['element_class'] = $random_class; $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]//div[contains(@class, views-field)]//{$element_type}[contains(@class, :class)]", array(':class' => $random_class))); + $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]//div[contains(@class, views-field)]//{$element_type}[contains(@class, :class)]", [':class' => $random_class])); // Set no custom css class. $id_field->options['element_class'] = ''; $output = $view->preview(); $output = $renderer->renderRoot($output); - $this->assertFalse($this->xpathContent($output, "//li[contains(@class, views-row)]//div[contains(@class, views-field)]//{$element_type}[contains(@class, :class)]", array(':class' => $random_class))); + $this->assertFalse($this->xpathContent($output, "//li[contains(@class, views-row)]//div[contains(@class, views-field)]//{$element_type}[contains(@class, :class)]", [':class' => $random_class])); $this->assertTrue($this->xpathContent($output, "//li[contains(@class, views-row)]//div[contains(@class, views-field)]//{$element_type}")); } // Tests the available html elements. $element_types = $id_field->getElements(); - $expected_elements = array( + $expected_elements = [ '', 0, 'div', @@ -484,7 +485,7 @@ public function testFieldClasses() { 'strong', 'em', 'marquee' - ); + ]; $this->assertEqual(array_keys($element_types), $expected_elements); } @@ -560,14 +561,14 @@ public function testTextRendering() { $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field, $row) { return $name_field->advancedRender($row); }); - $this->assertSubString($output, $trimmed_name, format_string('Make sure the trimmed output (@trimmed) appears in the rendered output (@output).', array('@trimmed' => $trimmed_name, '@output' => $output))); - $this->assertNotSubString($output, $row->views_test_data_name, format_string("Make sure the untrimmed value (@untrimmed) shouldn't appear in the rendered output (@output).", array('@untrimmed' => $row->views_test_data_name, '@output' => $output))); + $this->assertSubString($output, $trimmed_name, format_string('Make sure the trimmed output (@trimmed) appears in the rendered output (@output).', ['@trimmed' => $trimmed_name, '@output' => $output])); + $this->assertNotSubString($output, $row->views_test_data_name, format_string("Make sure the untrimmed value (@untrimmed) shouldn't appear in the rendered output (@output).", ['@untrimmed' => $row->views_test_data_name, '@output' => $output])); $name_field->options['alter']['max_length'] = 9; $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field, $row) { return $name_field->advancedRender($row); }); - $this->assertSubString($output, $trimmed_name, format_string('Make sure the untrimmed (@untrimmed) output appears in the rendered output (@output).', array('@trimmed' => $trimmed_name, '@output' => $output))); + $this->assertSubString($output, $trimmed_name, format_string('Make sure the untrimmed (@untrimmed) output appears in the rendered output (@output).', ['@trimmed' => $trimmed_name, '@output' => $output])); // Take word_boundary into account for the tests. $name_field->options['alter']['max_length'] = 5; @@ -575,34 +576,34 @@ public function testTextRendering() { $random_text_2 = $this->randomMachineName(2); $random_text_4 = $this->randomMachineName(4); $random_text_8 = $this->randomMachineName(8); - $tuples = array( + $tuples = [ // Create one string which doesn't fit at all into the limit. - array( + [ 'value' => $random_text_8, 'trimmed_value' => '', 'trimmed' => TRUE - ), + ], // Create one string with two words which doesn't fit both into the limit. - array( + [ 'value' => $random_text_8 . ' ' . $random_text_8, 'trimmed_value' => '', 'trimmed' => TRUE - ), + ], // Create one string which contains of two words, of which only the first // fits into the limit. - array( + [ 'value' => $random_text_4 . ' ' . $random_text_8, 'trimmed_value' => $random_text_4, 'trimmed' => TRUE - ), + ], // Create one string which contains of two words, of which both fits into // the limit. - array( + [ 'value' => $random_text_2 . ' ' . $random_text_2, 'trimmed_value' => $random_text_2 . ' ' . $random_text_2, 'trimmed' => FALSE - ) - ); + ] + ]; foreach ($tuples as $tuple) { $row->views_test_data_name = $tuple['value']; @@ -611,10 +612,10 @@ public function testTextRendering() { }); if ($tuple['trimmed']) { - $this->assertNotSubString($output, $tuple['value'], format_string('The untrimmed value (@untrimmed) should not appear in the trimmed output (@output).', array('@untrimmed' => $tuple['value'], '@output' => $output))); + $this->assertNotSubString($output, $tuple['value'], format_string('The untrimmed value (@untrimmed) should not appear in the trimmed output (@output).', ['@untrimmed' => $tuple['value'], '@output' => $output])); } if (!empty($tuple['trimmed_value'])) { - $this->assertSubString($output, $tuple['trimmed_value'], format_string('The trimmed value (@trimmed) should appear in the trimmed output (@output).', array('@trimmed' => $tuple['trimmed_value'], '@output' => $output))); + $this->assertSubString($output, $tuple['trimmed_value'], format_string('The trimmed value (@trimmed) should appear in the trimmed output (@output).', ['@trimmed' => $tuple['trimmed_value'], '@output' => $output])); } } @@ -629,14 +630,14 @@ public function testTextRendering() { return $name_field->advancedRender($row); }); $this->assertSubString($output, $more_text, 'Make sure a read more text is displayed if the output got trimmed'); - $this->assertTrue($this->xpathContent($output, '//a[contains(@href, :path)]', array(':path' => $more_path)), 'Make sure the read more link points to the right destination.'); + $this->assertTrue($this->xpathContent($output, '//a[contains(@href, :path)]', [':path' => $more_path]), 'Make sure the read more link points to the right destination.'); $name_field->options['alter']['more_link'] = FALSE; $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($name_field, $row) { return $name_field->advancedRender($row); }); $this->assertNotSubString($output, $more_text, 'Make sure no read more text appears.'); - $this->assertFalse($this->xpathContent($output, '//a[contains(@href, :path)]', array(':path' => $more_path)), 'Make sure no read more link appears.'); + $this->assertFalse($this->xpathContent($output, '//a[contains(@href, :path)]', [':path' => $more_path]), 'Make sure no read more link appears.'); // Check for the ellipses. $row->views_test_data_name = $this->randomMachineName(8); diff --git a/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php new file mode 100644 index 00000000..ec3b5238 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php @@ -0,0 +1,319 @@ + 'page', + 'name' => 'Page', + ])->save(); + + // Setup a field storage and field, but also change the views data for the + // entity_test entity type. + $field_storage = FieldStorageConfig::create([ + 'field_name' => 'field_date', + 'type' => 'datetime', + 'entity_type' => 'node', + ]); + $field_storage->save(); + + $field = FieldConfig::create([ + 'field_name' => 'field_date', + 'entity_type' => 'node', + 'bundle' => 'page', + ]); + $field->save(); + + // Add some basic test nodes. + $this->nodes = []; + $this->nodes[] = $this->drupalCreateNode(['created' => 100000, 'field_date' => 10000]); + $this->nodes[] = $this->drupalCreateNode(['created' => 200000, 'field_date' => 20000]); + $this->nodes[] = $this->drupalCreateNode(['created' => 300000, 'field_date' => 30000]); + $this->nodes[] = $this->drupalCreateNode(['created' => time() + 86400, 'field_date' => time() + 86400]); + + $this->map = [ + 'nid' => 'nid', + ]; + } + + /** + * Runs other test methods. + */ + public function testDateFilter() { + $this->_testOffset(); + $this->_testBetween(); + $this->_testUiValidation(); + $this->_testFilterDateUI(); + $this->_testFilterDatetimeUI(); + } + + /** + * Test the general offset functionality. + */ + protected function _testOffset() { + $view = Views::getView('test_filter_date_between'); + + // Test offset for simple operator. + $view->initHandlers(); + $view->filter['created']->operator = '>'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['value'] = '+1 hour'; + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[3]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test offset for between operator. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['max'] = '+2 days'; + $view->filter['created']->value['min'] = '+1 hour'; + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[3]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + } + + /** + * Tests the filter operator between/not between. + */ + protected function _testBetween() { + $view = Views::getView('test_filter_date_between'); + + // Test between with min and max. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['min'] = format_date(150000, 'custom', 'Y-m-d H:i:s'); + $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[1]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test between with just max. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[0]->id()], + ['nid' => $this->nodes[1]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test not between with min and max. + $view->initHandlers(); + $view->filter['created']->operator = 'not between'; + $view->filter['created']->value['min'] = format_date(100000, 'custom', 'Y-m-d H:i:s'); + $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); + + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[2]->id()], + ['nid' => $this->nodes[3]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test not between with just max. + $view->initHandlers(); + $view->filter['created']->operator = 'not between'; + $view->filter['created']->value['max'] = format_date(200000, 'custom', 'Y-m-d H:i:s'); + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[2]->id()], + ['nid' => $this->nodes[3]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + } + + /** + * Make sure the validation callbacks works. + */ + protected function _testUiValidation() { + + $this->drupalLogin($this->drupalCreateUser(['administer views', 'administer site configuration'])); + + $this->drupalGet('admin/structure/views/view/test_filter_date_between/edit'); + $this->drupalGet('admin/structure/views/nojs/handler/test_filter_date_between/default/filter/created'); + + $edit = []; + // Generate a definitive wrong value, which should be checked by validation. + $edit['options[value][value]'] = $this->randomString() . '-------'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertText(t('Invalid date format.'), 'Make sure that validation is run and the invalidate date format is identified.'); + } + + /** + * Test date filter UI. + */ + protected function _testFilterDateUI() { + $this->drupalLogin($this->drupalCreateUser(['administer views'])); + $this->drupalGet('admin/structure/views/nojs/handler/test_filter_date_between/default/filter/created'); + $this->drupalPostForm(NULL, [], t('Expose filter')); + $this->drupalPostForm(NULL, [], t('Grouped filters')); + + $edit = []; + $edit['options[group_info][group_items][1][title]'] = 'simple-offset'; + $edit['options[group_info][group_items][1][operator]'] = '>'; + $edit['options[group_info][group_items][1][value][type]'] = 'offset'; + $edit['options[group_info][group_items][1][value][value]'] = '+1 hour'; + $edit['options[group_info][group_items][2][title]'] = 'between-offset'; + $edit['options[group_info][group_items][2][operator]'] = 'between'; + $edit['options[group_info][group_items][2][value][type]'] = 'offset'; + $edit['options[group_info][group_items][2][value][min]'] = '+1 hour'; + $edit['options[group_info][group_items][2][value][max]'] = '+2 days'; + $edit['options[group_info][group_items][3][title]'] = 'between-date'; + $edit['options[group_info][group_items][3][operator]'] = 'between'; + $edit['options[group_info][group_items][3][value][min]'] = format_date(150000, 'custom', 'Y-m-d H:i:s'); + $edit['options[group_info][group_items][3][value][max]'] = format_date(250000, 'custom', 'Y-m-d H:i:s'); + + $this->drupalPostForm(NULL, $edit, t('Apply')); + + $this->drupalGet('admin/structure/views/nojs/handler/test_filter_date_between/default/filter/created'); + foreach ($edit as $name => $value) { + $this->assertFieldByName($name, $value); + if (strpos($name, '[value][type]')) { + $radio = $this->cssSelect('input[name="' . $name . '"][checked="checked"][type="radio"]'); + $this->assertEqual($radio[0]->getAttribute('value'), $value); + } + } + + $this->drupalPostForm('admin/structure/views/view/test_filter_date_between', [], t('Save')); + $this->assertConfigSchemaByName('views.view.test_filter_date_between'); + + // Test that the exposed filter works as expected. + $path = 'test_filter_date_between-path'; + $this->drupalPostForm('admin/structure/views/view/test_filter_date_between/edit', [], 'Add Page'); + $this->drupalPostForm('admin/structure/views/nojs/display/test_filter_date_between/page_1/path', ['path' => $path], 'Apply'); + $this->drupalPostForm(NULL, [], t('Save')); + + $this->drupalGet($path); + $this->drupalPostForm(NULL, [], 'Apply'); + $results = $this->cssSelect('.view-content .field-content'); + $this->assertEqual(count($results), 4); + $this->drupalPostForm(NULL, ['created' => '1'], 'Apply'); + $results = $this->cssSelect('.view-content .field-content'); + $this->assertEqual(count($results), 1); + $this->assertEqual($results[0]->getText(), $this->nodes[3]->id()); + $this->drupalPostForm(NULL, ['created' => '2'], 'Apply'); + $results = $this->cssSelect('.view-content .field-content'); + $this->assertEqual(count($results), 1); + $this->assertEqual($results[0]->getText(), $this->nodes[3]->id()); + $this->drupalPostForm(NULL, ['created' => '3'], 'Apply'); + $results = $this->cssSelect('.view-content .field-content'); + $this->assertEqual(count($results), 1); + $this->assertEqual($results[0]->getText(), $this->nodes[1]->id()); + + // Change the filter to a single filter to test the schema when the operator + // is not exposed. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_date_between/default/filter/created', [], t('Single filter')); + $edit = []; + $edit['options[operator]'] = '>'; + $edit['options[value][type]'] = 'date'; + $edit['options[value][value]'] = format_date(350000, 'custom', 'Y-m-d H:i:s'); + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->drupalPostForm('admin/structure/views/view/test_filter_date_between', [], t('Save')); + $this->assertConfigSchemaByName('views.view.test_filter_date_between'); + + // Test that the filter works as expected. + $this->drupalGet($path); + $results = $this->cssSelect('.view-content .field-content'); + $this->assertEqual(count($results), 1); + $this->assertEqual($results[0]->getText(), $this->nodes[3]->id()); + $this->drupalPostForm(NULL, ['created' => format_date(250000, 'custom', 'Y-m-d H:i:s')], 'Apply'); + $results = $this->cssSelect('.view-content .field-content'); + $this->assertEqual(count($results), 2); + $this->assertEqual($results[0]->getText(), $this->nodes[2]->id()); + $this->assertEqual($results[1]->getText(), $this->nodes[3]->id()); + } + + /** + * Test datetime grouped filter UI. + */ + protected function _testFilterDatetimeUI() { + $this->drupalLogin($this->drupalCreateUser(['administer views'])); + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_filter_date_between/default/filter', ['name[node__field_date.field_date_value]' => 'node__field_date.field_date_value'], t('Add and configure filter criteria')); + + $this->drupalPostForm(NULL, [], t('Expose filter')); + $this->drupalPostForm(NULL, [], t('Grouped filters')); + + $edit = []; + $edit['options[group_info][group_items][1][title]'] = 'simple-offset'; + $edit['options[group_info][group_items][1][operator]'] = '>'; + $edit['options[group_info][group_items][1][value][type]'] = 'offset'; + $edit['options[group_info][group_items][1][value][value]'] = '+1 hour'; + $edit['options[group_info][group_items][2][title]'] = 'between-offset'; + $edit['options[group_info][group_items][2][operator]'] = 'between'; + $edit['options[group_info][group_items][2][value][type]'] = 'offset'; + $edit['options[group_info][group_items][2][value][min]'] = '+1 hour'; + $edit['options[group_info][group_items][2][value][max]'] = '+2 days'; + $edit['options[group_info][group_items][3][title]'] = 'between-date'; + $edit['options[group_info][group_items][3][operator]'] = 'between'; + $edit['options[group_info][group_items][3][value][min]'] = format_date(150000, 'custom', 'Y-m-d H:i:s'); + $edit['options[group_info][group_items][3][value][max]'] = format_date(250000, 'custom', 'Y-m-d H:i:s'); + + $this->drupalPostForm(NULL, $edit, t('Apply')); + + $this->drupalPostForm('admin/structure/views/view/test_filter_date_between', [], t('Save')); + $this->assertConfigSchemaByName('views.view.test_filter_date_between'); + } + + /** + * Tests that the exposed date filter is displayed without errors. + */ + public function testExposedFilter() { + $this->drupalLogin($this->drupalCreateUser(['administer views'])); + $this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_date_between/default/filter/created', [], t('Expose filter')); + $this->drupalPostForm('admin/structure/views/view/test_filter_date_between/edit', [], t('Add Page')); + $edit = [ + 'path' => 'exposed-date-filter', + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_filter_date_between/page_1/path', $edit, t('Apply')); + + $this->drupalPostForm(NULL, [], t('Save')); + + $this->drupalGet('exposed-date-filter'); + $this->assertField('created'); + } + +} diff --git a/core/modules/views/src/Tests/Handler/HandlerAllTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php similarity index 86% rename from core/modules/views/src/Tests/Handler/HandlerAllTest.php rename to core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php index c15ce57e..1a37ce83 100644 --- a/core/modules/views/src/Tests/Handler/HandlerAllTest.php +++ b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php @@ -1,8 +1,9 @@ drupalCreateContentType(array('type' => 'article')); + $this->drupalCreateContentType(['type' => 'article']); $this->addDefaultCommentField('node', 'article'); $object_types = array_keys(ViewExecutable::getHandlerTypes()); @@ -55,7 +56,7 @@ public function testHandlers() { continue; } - $view = View::create(array('base_table' => $base_table)); + $view = View::create(['base_table' => $base_table]); $view = $view->getExecutable(); // @todo The groupwise relationship is currently broken. @@ -66,18 +67,18 @@ public function testHandlers() { foreach ($info as $field => $field_info) { // Table is a reserved key for the metainformation. if ($field != 'table' && !in_array("$base_table:$field", $exclude)) { - $item = array( + $item = [ 'table' => $base_table, 'field' => $field, - ); + ]; foreach ($object_types as $type) { if (isset($field_info[$type]['id'])) { - $options = array(); + $options = []; if ($type == 'filter') { $handler = $this->container->get("plugin.manager.views.$type")->getHandler($item); // Set the value to use for the filter based on the filter type. if ($handler instanceof InOperator) { - $options['value'] = array(1); + $options['value'] = [1]; } else { $options['value'] = 1; @@ -102,10 +103,10 @@ public function testHandlers() { foreach ($view->{$type} as $handler) { $this->assertTrue($handler instanceof HandlerBase, format_string( '@type handler of class %class is an instance of HandlerBase', - array( + [ '@type' => $type, '%class' => get_class($handler), - ))); + ])); } } } diff --git a/core/modules/views/tests/src/Functional/Handler/HandlerTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php new file mode 100644 index 00000000..cffe6d14 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php @@ -0,0 +1,400 @@ +drupalCreateContentType(['type' => 'page']); + $this->addDefaultCommentField('node', 'page'); + $this->enableViewsTestModule(); + } + + /** + * {@inheritdoc} + */ + protected function viewsData() { + $data = parent::viewsData(); + // Override the name handler to be able to call placeholder() from outside. + $data['views_test_data']['name']['field']['id'] = 'test_field'; + + // Setup one field with an access callback and one with an access callback + // and arguments. + $data['views_test_data']['access_callback'] = $data['views_test_data']['id']; + $data['views_test_data']['access_callback_arguments'] = $data['views_test_data']['id']; + foreach (ViewExecutable::getHandlerTypes() as $type => $info) { + if (isset($data['views_test_data']['access_callback'][$type]['id'])) { + $data['views_test_data']['access_callback'][$type]['access callback'] = 'views_test_data_handler_test_access_callback'; + + $data['views_test_data']['access_callback_arguments'][$type]['access callback'] = 'views_test_data_handler_test_access_callback_argument'; + $data['views_test_data']['access_callback_arguments'][$type]['access arguments'] = [TRUE]; + } + } + + return $data; + } + + /** + * Tests the breakString method. + */ + public function testBreakString() { + // Check defaults. + $this->assertEqual((object) ['value' => [], 'operator' => NULL], HandlerBase::breakString('')); + + // Test ors + $handler = HandlerBase::breakString('word1 word2+word'); + $this->assertEqualValue(['word1', 'word2', 'word'], $handler); + $this->assertEqual('or', $handler->operator); + $handler = HandlerBase::breakString('word1+word2+word'); + $this->assertEqualValue(['word1', 'word2', 'word'], $handler); + $this->assertEqual('or', $handler->operator); + $handler = HandlerBase::breakString('word1 word2 word'); + $this->assertEqualValue(['word1', 'word2', 'word'], $handler); + $this->assertEqual('or', $handler->operator); + $handler = HandlerBase::breakString('word-1+word-2+word'); + $this->assertEqualValue(['word-1', 'word-2', 'word'], $handler); + $this->assertEqual('or', $handler->operator); + $handler = HandlerBase::breakString('wõrd1+wõrd2+wõrd'); + $this->assertEqualValue(['wõrd1', 'wõrd2', 'wõrd'], $handler); + $this->assertEqual('or', $handler->operator); + + // Test ands. + $handler = HandlerBase::breakString('word1,word2,word'); + $this->assertEqualValue(['word1', 'word2', 'word'], $handler); + $this->assertEqual('and', $handler->operator); + $handler = HandlerBase::breakString('word1 word2,word'); + $this->assertEqualValue(['word1 word2', 'word'], $handler); + $this->assertEqual('and', $handler->operator); + $handler = HandlerBase::breakString('word1,word2 word'); + $this->assertEqualValue(['word1', 'word2 word'], $handler); + $this->assertEqual('and', $handler->operator); + $handler = HandlerBase::breakString('word-1,word-2,word'); + $this->assertEqualValue(['word-1', 'word-2', 'word'], $handler); + $this->assertEqual('and', $handler->operator); + $handler = HandlerBase::breakString('wõrd1,wõrd2,wõrd'); + $this->assertEqualValue(['wõrd1', 'wõrd2', 'wõrd'], $handler); + $this->assertEqual('and', $handler->operator); + + // Test a single word + $handler = HandlerBase::breakString('word'); + $this->assertEqualValue(['word'], $handler); + $this->assertEqual('and', $handler->operator); + + $s1 = $this->randomMachineName(); + // Generate three random numbers which can be used below; + $n1 = rand(0, 100); + $n2 = rand(0, 100); + $n3 = rand(0, 100); + + // Test "or"s. + $handlerBase = HandlerBase::breakString("$s1 $n2+$n3"); + $this->assertEqualValue([$s1, $n2, $n3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1+$n2+$n3"); + $this->assertEqualValue([$s1, $n2, $n3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1 $n2 $n3"); + $this->assertEqualValue([$s1, $n2, $n3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1 $n2++$n3"); + $this->assertEqualValue([$s1, $n2, $n3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + // Test "and"s. + $handlerBase = HandlerBase::breakString("$s1,$n2,$n3"); + $this->assertEqualValue([$s1, $n2, $n3], $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1,,$n2,$n3"); + $this->assertEqualValue([$s1, $n2, $n3], $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + // Enforce int values. + $handlerBase = HandlerBase::breakString("$n1,$n2,$n3", TRUE); + $this->assertEqualValue([$n1, $n2, $n3], $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$n1+$n2+$n3", TRUE); + $this->assertEqualValue([$n1, $n2, $n3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1,$n2,$n3", TRUE); + $this->assertEqualValue([(int) $s1, $n2, $n3], $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1+$n2+$n3", TRUE); + $this->assertEqualValue([(int) $s1, $n2, $n3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + // Generate three random decimals which can be used below; + $d1 = rand(0, 10) / 10; + $d2 = rand(0, 10) / 10; + $d3 = rand(0, 10) / 10; + + // Test "or"s. + $handlerBase = HandlerBase::breakString("$s1 $d1+$d2"); + $this->assertEqualValue([$s1, $d1, $d2], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1+$d1+$d3"); + $this->assertEqualValue([$s1, $d1, $d3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1 $d2 $d3"); + $this->assertEqualValue([$s1, $d2, $d3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1 $d2++$d3"); + $this->assertEqualValue([$s1, $d2, $d3], $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + // Test "and"s. + $handlerBase = HandlerBase::breakString("$s1,$d2,$d3"); + $this->assertEqualValue([$s1, $d2, $d3], $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1,,$d2,$d3"); + $this->assertEqualValue([$s1, $d2, $d3], $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + } + + /** + * Tests the order of handlers is the same before and after saving. + */ + public function testHandlerWeights() { + $handler_types = ['fields', 'filters', 'sorts']; + + $view = Views::getView('test_view_handler_weight'); + $view->initDisplay(); + + // Store the order of handlers before saving the view. + $original_order = []; + foreach ($handler_types as $type) { + $original_order[$type] = array_keys($view->display_handler->getOption($type)); + } + + // Save the view and see if our filters are in the same order. + $view->save(); + $view = views::getView('test_view_handler_weight'); + $view->initDisplay(); + + foreach ($handler_types as $type) { + $loaded_order = array_keys($view->display_handler->getOption($type)); + $this->assertIdentical($original_order[$type], $loaded_order); + } + } + + /** + * Check to see if a value is the same as the value on a certain handler. + * + * @param $expected + * The expected value to check. + * @param \Drupal\views\Plugin\views\ViewsHandlerInterface $handler + * The handler that has the $handler->value property to compare with first. + * @param string $message + * The message to display along with the assertion. + * @param string $group + * The type of assertion - examples are "Browser", "PHP". + * + * @return bool + * TRUE if the assertion succeeded, FALSE otherwise. + */ + protected function assertEqualValue($expected, $handler, $message = '', $group = 'Other') { + if (empty($message)) { + $message = t('Comparing @first and @second', ['@first' => implode(',', $expected), '@second' => implode(',', $handler->value)]); + } + + return $this->assert($expected == $handler->value, $message, $group); + } + + /** + * Tests the relationship ui for field/filter/argument/relationship. + */ + public function testRelationshipUI() { + $views_admin = $this->drupalCreateUser(['administer views']); + $this->drupalLogin($views_admin); + + // Make sure the link to the field options exists. + $handler_options_path = 'admin/structure/views/nojs/handler/test_handler_relationships/default/field/title'; + $view_edit_path = 'admin/structure/views/view/test_handler_relationships/edit'; + $this->drupalGet($view_edit_path); + $this->assertLinkByHref($handler_options_path); + + // The test view has a relationship to node_revision so the field should + // show a relationship selection. + + $this->drupalGet($handler_options_path); + $relationship_name = 'options[relationship]'; + $this->assertFieldByName($relationship_name); + + // Check for available options. + $fields = $this->getSession()->getPage()->findAll('named_exact', ['field', $relationship_name]); + $options = []; + foreach ($fields as $field) { + $items = $field->findAll('css', 'option'); + foreach ($items as $item) { + $options[] = $item->getAttribute('value'); + } + } + $expected_options = ['none', 'nid']; + $this->assertEqual($options, $expected_options); + + // Remove the relationship and make sure no relationship option appears. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_handler_relationships/default/relationship/nid', [], t('Remove')); + $this->drupalGet($handler_options_path); + $this->assertNoFieldByName($relationship_name, NULL, 'Make sure that no relationship option is available'); + + // Create a view of comments with node relationship. + View::create(['base_table' => 'comment_field_data', 'id' => 'test_get_entity_type'])->save(); + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_get_entity_type/default/relationship', ['name[comment_field_data.node]' => 'comment_field_data.node'], t('Add and configure relationships')); + $this->drupalPostForm(NULL, [], t('Apply')); + // Add a content type filter. + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_get_entity_type/default/filter', ['name[node_field_data.type]' => 'node_field_data.type'], t('Add and configure filter criteria')); + $this->assertOptionSelected('edit-options-relationship', 'node'); + $this->drupalPostForm(NULL, ['options[value][page]' => 'page'], t('Apply')); + // Check content type filter options. + $this->drupalGet('admin/structure/views/nojs/handler/test_get_entity_type/default/filter/type'); + $this->assertOptionSelected('edit-options-relationship', 'node'); + $this->assertFieldChecked('edit-options-value-page'); + } + + /** + * Tests the relationship method on the base class. + */ + public function testSetRelationship() { + $view = Views::getView('test_handler_relationships'); + $view->setDisplay(); + // Setup a broken relationship. + $view->addHandler('default', 'relationship', $this->randomMachineName(), $this->randomMachineName(), [], 'broken_relationship'); + // Setup a valid relationship. + $view->addHandler('default', 'relationship', 'comment_field_data', 'node', ['relationship' => 'cid'], 'valid_relationship'); + $view->initHandlers(); + $field = $view->field['title']; + + $field->options['relationship'] = NULL; + $field->setRelationship(); + $this->assertFalse($field->relationship, 'Make sure that an empty relationship does not create a relationship on the field.'); + + $field->options['relationship'] = $this->randomMachineName(); + $field->setRelationship(); + $this->assertFalse($field->relationship, 'Make sure that a random relationship does not create a relationship on the field.'); + + $field->options['relationship'] = 'broken_relationship'; + $field->setRelationship(); + $this->assertFalse($field->relationship, 'Make sure that a broken relationship does not create a relationship on the field.'); + + $field->options['relationship'] = 'valid_relationship'; + $field->setRelationship(); + $this->assertFalse(!empty($field->relationship), 'Make sure that the relationship alias was not set without building a views query before.'); + + // Remove the invalid relationship. + unset($view->relationship['broken_relationship']); + + $view->build(); + $field->setRelationship(); + $this->assertEqual($field->relationship, $view->relationship['valid_relationship']->alias, 'Make sure that a valid relationship does create the right relationship query alias.'); + } + + /** + * Tests the placeholder function. + * + * @see \Drupal\views\Plugin\views\HandlerBase::placeholder() + */ + public function testPlaceholder() { + $view = Views::getView('test_view'); + $view->initHandlers(); + $view->initQuery(); + + $handler = $view->field['name']; + $table = $handler->table; + $field = $handler->field; + $string = ':' . $table . '_' . $field; + + // Make sure the placeholder variables are like expected. + $this->assertEqual($handler->getPlaceholder(), $string); + $this->assertEqual($handler->getPlaceholder(), $string . 1); + $this->assertEqual($handler->getPlaceholder(), $string . 2); + + // Set another table/field combination and make sure there are new + // placeholders. + $table = $handler->table = $this->randomMachineName(); + $field = $handler->field = $this->randomMachineName(); + $string = ':' . $table . '_' . $field; + + // Make sure the placeholder variables are like expected. + $this->assertEqual($handler->getPlaceholder(), $string); + $this->assertEqual($handler->getPlaceholder(), $string . 1); + $this->assertEqual($handler->getPlaceholder(), $string . 2); + } + + /** + * Tests access to a handler. + * + * @see views_test_data_handler_test_access_callback + */ + public function testAccess() { + $view = Views::getView('test_handler_test_access'); + $views_data = $this->viewsData(); + $views_data = $views_data['views_test_data']; + + // Enable access to callback only field and deny for callback + arguments. + $this->config('views_test_data.tests')->set('handler_access_callback', TRUE)->save(); + $this->config('views_test_data.tests')->set('handler_access_callback_argument', FALSE)->save(); + $view->initDisplay(); + $view->initHandlers(); + + foreach ($views_data['access_callback'] as $type => $info) { + if (!in_array($type, ['title', 'help'])) { + $this->assertTrue($view->field['access_callback'] instanceof HandlerBase, 'Make sure the user got access to the access_callback field '); + $this->assertFalse(isset($view->field['access_callback_arguments']), 'Make sure the user got no access to the access_callback_arguments field '); + } + } + + // Enable access to the callback + argument handlers and deny for callback. + $this->config('views_test_data.tests')->set('handler_access_callback', FALSE)->save(); + $this->config('views_test_data.tests')->set('handler_access_callback_argument', TRUE)->save(); + $view->destroy(); + $view->initDisplay(); + $view->initHandlers(); + + foreach ($views_data['access_callback'] as $type => $info) { + if (!in_array($type, ['title', 'help'])) { + $this->assertFalse(isset($view->field['access_callback']), 'Make sure the user got no access to the access_callback field '); + $this->assertTrue($view->field['access_callback_arguments'] instanceof HandlerBase, 'Make sure the user got access to the access_callback_arguments field '); + } + } + } + +} diff --git a/core/modules/views/src/Tests/Plugin/AccessTest.php b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php similarity index 76% rename from core/modules/views/src/Tests/Plugin/AccessTest.php rename to core/modules/views/tests/src/Functional/Plugin/AccessTest.php index 1bcf3001..41aa6ec5 100644 --- a/core/modules/views/src/Tests/Plugin/AccessTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php @@ -1,7 +1,8 @@ enableViewsTestModule(); - ViewTestData::createTestViews(get_class($this), array('views_test_data')); + ViewTestData::createTestViews(get_class($this), ['views_test_data']); $this->webUser = $this->drupalCreateUser(); - $normal_role = $this->drupalCreateRole(array()); - $this->normalUser = $this->drupalCreateUser(array('views_test_data test permission')); + $normal_role = $this->drupalCreateRole([]); + $this->normalUser = $this->drupalCreateUser(['views_test_data test permission']); $this->normalUser->addRole($normal_role); // @todo when all the plugin information is cached make a reset function and // call it here. @@ -61,7 +62,7 @@ protected function setUp() { /** * Tests none access plugin. */ - function testAccessNone() { + public function testAccessNone() { $view = Views::getView('test_access_none'); $view->setDisplay(); @@ -78,7 +79,7 @@ function testAccessNone() { * * @see \Drupal\views_test\Plugin\views\access\StaticTest */ - function testStaticAccessPlugin() { + public function testStaticAccessPlugin() { $view = Views::getView('test_access_static'); $view->setDisplay(); diff --git a/core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php b/core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php similarity index 82% rename from core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php rename to core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php index 5abc27c8..57eb2320 100644 --- a/core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php @@ -1,44 +1,44 @@ enableViewsTestModule(); } @@ -52,13 +52,13 @@ public function testArgumentDefaultPlugin() { $view = Views::getView('test_view'); // Add a new argument and set the test plugin for the argument_default. - $options = array( + $options = [ 'default_argument_type' => 'argument_default_test', - 'default_argument_options' => array( + 'default_argument_options' => [ 'value' => 'John' - ), + ], 'default_action' => 'default' - ); + ]; $id = $view->addHandler('default', 'argument', 'views_test_data', 'name', $options); $view->initHandlers(); $plugin = $view->argument[$id]->getPlugin('argument_default'); @@ -70,15 +70,15 @@ public function testArgumentDefaultPlugin() { // just returns John. $this->executeView($view); $this->assertEqual($view->argument[$id]->getValue(), 'John', 'The correct argument value is used.'); - $expected_result = array(array('name' => 'John')); - $this->assertIdenticalResultset($view, $expected_result, array('views_test_data_name' => 'name')); + $expected_result = [['name' => 'John']]; + $this->assertIdenticalResultset($view, $expected_result, ['views_test_data_name' => 'name']); // Pass in value as argument to be sure that not the default value is used. $view->destroy(); - $this->executeView($view, array('George')); + $this->executeView($view, ['George']); $this->assertEqual($view->argument[$id]->getValue(), 'George', 'The correct argument value is used.'); - $expected_result = array(array('name' => 'George')); - $this->assertIdenticalResultset($view, $expected_result, array('views_test_data_name' => 'name')); + $expected_result = [['name' => 'George']]; + $this->assertIdenticalResultset($view, $expected_result, ['views_test_data_name' => 'name']); } @@ -86,24 +86,24 @@ public function testArgumentDefaultPlugin() { * Tests the use of a default argument plugin that provides no options. */ public function testArgumentDefaultNoOptions() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); $this->drupalLogin($admin_user); // The current_user plugin has no options form, and should pass validation. $argument_type = 'current_user'; - $edit = array( + $edit = [ 'options[default_argument_type]' => $argument_type, - ); + ]; $this->drupalPostForm('admin/structure/views/nojs/handler/test_argument_default_current_user/default/argument/uid', $edit, t('Apply')); // Note, the undefined index error has two spaces after it. - $error = array( + $error = [ '%type' => 'Notice', '@message' => 'Undefined index: ' . $argument_type, '%function' => 'views_handler_argument->validateOptionsForm()', - ); + ]; $message = t('%type: @message in %function', $error); - $this->assertNoRaw($message, format_string('Did not find error message: @message.', array('@message' => $message))); + $this->assertNoRaw($message, format_string('Did not find error message: @message.', ['@message' => $message])); } /** @@ -122,7 +122,7 @@ public function testArgumentDefaultFixed() { // Make sure that a normal argument provided is used $random_string = $this->randomMachineName(); - $view->executeDisplay('default', array($random_string)); + $view->executeDisplay('default', [$random_string]); $this->assertEqual($view->args[0], $random_string, 'Provided argument should be used.'); } @@ -130,20 +130,20 @@ public function testArgumentDefaultFixed() { /** * @todo Test php default argument. */ - //function testArgumentDefaultPhp() {} + // function testArgumentDefaultPhp() {} /** * Test node default argument. */ public function testArgumentDefaultNode() { // Create a user that has permission to place a view block. - $permissions = array( + $permissions = [ 'administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions', - ); + ]; $views_admin = $this->drupalCreateUser($permissions); $this->drupalLogin($views_admin); @@ -161,9 +161,9 @@ public function testArgumentDefaultNode() { $this->drupalPlaceBlock("views_block:test_argument_default_node-block_1", ['id' => $id]); $xpath = '//*[@id="block-' . $id . '"]'; $this->drupalGet('node/' . $node1->id()); - $this->assertTrue(strpos($this->xpath($xpath)[0]->asXml(), $node1->getTitle())); + $this->assertTrue(strpos($this->xpath($xpath)[0]->getText(), $node1->getTitle())); $this->drupalGet('node/' . $node2->id()); - $this->assertTrue(strpos($this->xpath($xpath)[0]->asXml(), $node2->getTitle())); + $this->assertTrue(strpos($this->xpath($xpath)[0]->getText(), $node2->getTitle())); } /** diff --git a/core/modules/views/src/Tests/Plugin/CacheTagTest.php b/core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php similarity index 90% rename from core/modules/views/src/Tests/Plugin/CacheTagTest.php rename to core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php index eaee6569..1d78204d 100644 --- a/core/modules/views/src/Tests/Plugin/CacheTagTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php @@ -1,8 +1,9 @@ drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); $this->nodeStorage = $this->container->get('entity.manager')->getStorage('node'); $this->nodeViewBuilder = $this->container->get('entity.manager')->getViewBuilder('node'); $this->userViewBuilder = $this->container->get('entity.manager')->getViewBuilder('user'); for ($i = 1; $i <= 5; $i++) { - $this->pages[] = $this->drupalCreateNode(array('title' => "Test $i", 'type' => 'page')); + $this->pages[] = $this->drupalCreateNode(['title' => "Test $i", 'type' => 'page']); } - $this->article = $this->drupalCreateNode(array('title' => "Test article", 'type' => 'article')); + $this->article = $this->drupalCreateNode(['title' => "Test article", 'type' => 'article']); $this->user = $this->drupalCreateUser(); // Mark the current request safe, in order to make render cache working, see @@ -183,7 +184,7 @@ public function testTagCaching() { $this->assertTrue($cache_plugin->cacheGet('results'), 'Results cache found.'); $this->assertTrue($this->getRenderCache($view), 'Output cache found.'); - $this->userViewBuilder->resetCache(array($this->user)); + $this->userViewBuilder->resetCache([$this->user]); $cache_plugin = $view->display_handler->getPlugin('cache'); $this->assertTrue($cache_plugin->cacheGet('results'), 'Results cache found after a user is invalidated.'); diff --git a/core/modules/views/src/Tests/Plugin/CacheWebTest.php b/core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php similarity index 82% rename from core/modules/views/src/Tests/Plugin/CacheWebTest.php rename to core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php index f41e786e..f8ce5a92 100644 --- a/core/modules/views/src/Tests/Plugin/CacheWebTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php @@ -1,8 +1,9 @@ enableViewsTestModule(); } @@ -46,13 +47,13 @@ public function testCacheOutputOnPage() { $view = Views::getView('test_display'); $view->storage->setStatus(TRUE); $view->setDisplay('page_1'); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'time', - 'options' => array( + 'options' => [ 'results_lifespan' => '3600', 'output_lifespan' => '3600' - ) - )); + ] + ]); $view->save(); $this->container->get('router.builder')->rebuildIfNeeded(); diff --git a/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php b/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php new file mode 100644 index 00000000..215ee289 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php @@ -0,0 +1,153 @@ +enableViewsTestModule(); + + $this->nodeType = $this->container->get('entity_type.manager') + ->getStorage('node_type') + ->create([ + 'name' => 'Test node type', + 'type' => 'test', + ]); + $this->nodeType->save(); + + $this->nodes[0] = $this->container->get('entity_type.manager') + ->getStorage('node') + ->create(['type' => $this->nodeType->id(), 'title' => 'First test node']); + $this->nodes[0]->save(); + + $this->nodes[1] = $this->container->get('entity_type.manager') + ->getStorage('node') + ->create(['type' => $this->nodeType->id(), 'title' => 'Second test node']); + $this->nodes[1]->save(); + } + + /** + * Tests exposed context. + */ + public function testBlockContext() { + $this->drupalLogin($this->drupalCreateUser(['administer views', 'administer blocks'])); + + // Check if context was correctly propagated to the block. + $definition = $this->container->get('plugin.manager.block') + ->getDefinition('views_block:test_view_block_with_context-block_1'); + $this->assertTrue($definition['context']['nid'] instanceof ContextDefinitionInterface); + /** @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context */ + $context = $definition['context']['nid']; + $this->assertEqual($context->getDataType(), 'entity:node', 'Context definition data type is correct.'); + $this->assertEqual($context->getLabel(), 'Content: ID', 'Context definition label is correct.'); + $this->assertFalse($context->isRequired(), 'Context is not required.'); + + // Place test block via block UI to check if contexts are correctly exposed. + $this->drupalGet( + 'admin/structure/block/add/views_block:test_view_block_with_context-block_1/classy', + ['query' => ['region' => 'content']] + ); + $edit = [ + 'settings[context_mapping][nid]' => '@node.node_route_context:node', + ]; + $this->drupalPostForm(NULL, $edit, 'Save block'); + + // Check if mapping saved correctly. + /** @var \Drupal\block\BlockInterface $block */ + $block = $this->container->get('entity_type.manager') + ->getStorage('block') + ->load('views_block__test_view_block_with_context_block_1'); + $expected_settings = [ + 'id' => 'views_block:test_view_block_with_context-block_1', + 'label' => '', + 'provider' => 'views', + 'label_display' => 'visible', + 'views_label' => '', + 'items_per_page' => 'none', + 'context_mapping' => ['nid' => '@node.node_route_context:node'] + ]; + $this->assertEqual($block->getPlugin()->getConfiguration(), $expected_settings, 'Block settings are correct.'); + + // Make sure view behaves as expected. + $this->drupalGet(''); + $this->assertText('Test view: No results found.'); + + $this->drupalGet($this->nodes[0]->toUrl()); + $this->assertText('Test view row: First test node'); + + $this->drupalGet($this->nodes[1]->toUrl()); + $this->assertText('Test view row: Second test node'); + + // Check the second block which should expose two integer contexts, one + // based on the numeric plugin and the other based on numeric validation. + $definition = $this->container->get('plugin.manager.block') + ->getDefinition('views_block:test_view_block_with_context-block_2'); + $this->assertTrue($definition['context']['created'] instanceof ContextDefinitionInterface); + /** @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context */ + $context = $definition['context']['created']; + $this->assertEqual($context->getDataType(), 'integer', 'Context definition data type is correct.'); + $this->assertEqual($context->getLabel(), 'Content: Authored on', 'Context definition label is correct.'); + $this->assertFalse($context->isRequired(), 'Context is not required.'); + + $this->assertTrue($definition['context']['vid'] instanceof ContextDefinitionInterface); + /** @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context */ + $context = $definition['context']['vid']; + $this->assertEqual($context->getDataType(), 'integer', 'Context definition data type is correct.'); + $this->assertEqual($context->getLabel(), 'Content: Revision ID', 'Context definition label is correct.'); + $this->assertFalse($context->isRequired(), 'Context is not required.'); + + $this->assertTrue($definition['context']['title'] instanceof ContextDefinitionInterface); + /** @var \Drupal\Core\Plugin\Context\ContextDefinitionInterface $context */ + $context = $definition['context']['title']; + $this->assertEqual($context->getDataType(), 'string', 'Context definition data type is correct.'); + $this->assertEqual($context->getLabel(), 'Content: Title', 'Context definition label is correct.'); + $this->assertFalse($context->isRequired(), 'Context is not required.'); + } + +} diff --git a/core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php similarity index 78% rename from core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php rename to core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php index 9238dda3..708ac550 100644 --- a/core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php @@ -1,6 +1,8 @@ enableViewsTestModule(); $this->drupalPlaceBlock('page_title_block'); - $admin_user = $this->drupalCreateUser(array('administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); } @@ -44,7 +46,7 @@ protected function setUp() { */ public function testDisabledDisplays() { // The displays defined in this view. - $display_ids = array('attachment_1', 'block_1', 'embed_1', 'feed_1', 'page_2'); + $display_ids = ['attachment_1', 'block_1', 'embed_1', 'feed_1', 'page_2']; $this->drupalCreateContentType(['type' => 'page']); $this->drupalCreateNode(); @@ -56,7 +58,7 @@ public function testDisabledDisplays() { // Enabled page display should return content. $this->drupalGet('test-disabled-display'); $result = $this->xpath('//h1[@class="page-title"]'); - $this->assertEqual($result[0], 'test_disabled_display', 'The enabled page_1 display is accessible.'); + $this->assertEqual($result[0]->getText(), 'test_disabled_display', 'The enabled page_1 display is accessible.'); // Disabled page view should 404. $this->drupalGet('test-disabled-display-2'); @@ -75,7 +77,7 @@ public function testDisabledDisplays() { // Check that the originally disabled page_2 display is now enabled. $this->drupalGet('test-disabled-display-2'); $result = $this->xpath('//h1[@class="page-title"]'); - $this->assertEqual($result[0], 'test_disabled_display', 'The enabled page_2 display is accessible.'); + $this->assertEqual($result[0]->getText(), 'test_disabled_display', 'The enabled page_2 display is accessible.'); // Disable each disabled display and save the view. foreach ($display_ids as $display_id) { diff --git a/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php new file mode 100644 index 00000000..8c326baa --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php @@ -0,0 +1,107 @@ +enableViewsTestModule(); + + $admin_user = $this->drupalCreateUser(['administer site configuration']); + $this->drupalLogin($admin_user); + } + + + /** + * Tests the attachment plugin. + */ + public function testAttachment() { + $this->drupalGet('test-display-attachment'); + + $result = $this->xpath('//div[contains(@class, "view-content")]'); + $this->assertEqual(count($result), 2, 'Both actual view and the attachment is rendered.'); + + $result = $this->xpath('//div[contains(@class, "attachment-after")]'); + $this->assertEqual(count($result), 0, 'The attachment is not rendered after the actual view.'); + + $result = $this->xpath('//div[contains(@class, "attachment-before")]'); + $this->assertEqual(count($result), 1, 'The attachment is rendered before the actual view.'); + } + + /** + * Tests that nothing is output when the attachment displays are disabled. + */ + public function testDisabledAttachments() { + $this->drupalCreateContentType(['type' => 'page']); + $this->drupalCreateNode(); + + // Ensure that the feed_1 display is attached to the page_1 display. + $view = Views::getView('test_attached_disabled'); + $view->setDisplay('page_1'); + $attached_displays = $view->display_handler->getAttachedDisplays(); + $this->assertTrue(in_array('attachment_1', $attached_displays), 'The attachment_1 display is attached to the page display.'); + $this->assertTrue(in_array('attachment_2', $attached_displays), 'The attachment_2 display is attached to the page display.'); + + // Check that the attachments are output on the page display. + $this->drupalGet('test-attached-disabled'); + + $result = $this->xpath('//div[contains(@class, "view-content")]'); + $this->assertEqual(count($result), 3, 'The page view and the attachments are rendered.'); + + $result = $this->xpath('//div[contains(@class, "attachment-before")]'); + $this->assertEqual(count($result), 1, 'The attachment is rendered before the page view.'); + + $result = $this->xpath('//div[contains(@class, "attachment-after")]'); + $this->assertEqual(count($result), 1, 'The attachment is rendered after the page view.'); + + // Disable the attachment_1 display. + $view->displayHandlers->get('attachment_1')->setOption('enabled', FALSE); + $view->save(); + + // Test that the before attachment is not displayed. + $this->drupalGet('/test-attached-disabled'); + $result = $this->xpath('//div[contains(@class, "view-content")]'); + $this->assertEqual(count($result), 2, 'The page view and only one attachment are rendered.'); + + $result = $this->xpath('//div[contains(@class, "attachment-before")]'); + $this->assertEqual(count($result), 0, 'The attachment_1 is not rendered.'); + + // Disable the attachment_2 display. + $view->displayHandlers->get('attachment_2')->setOption('enabled', FALSE); + $view->save(); + + // Test that the after attachment is not displayed. + $this->drupalGet('/test-attached-disabled'); + $result = $this->xpath('//div[contains(@class, "view-content")]'); + $this->assertEqual(count($result), 1, 'The page view is rendered without attachments.'); + + $result = $this->xpath('//div[contains(@class, "attachment-after")]'); + $this->assertEqual(count($result), 0, 'The attachment_2 is not rendered.'); + } + +} diff --git a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php similarity index 91% rename from core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php rename to core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php index 96d03692..daad1489 100644 --- a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php @@ -1,11 +1,12 @@ drupalLogin($this->drupalCreateUser(array('administer views'))); + $this->drupalLogin($this->drupalCreateUser(['administer views'])); // Create the text field. $this->fieldName = 'field_test_entity_ref_display'; @@ -248,6 +249,12 @@ public function testEntityReferenceDisplay() { $this->executeView($view); $this->assertEqual(count($view->result), 2, 'Search returned two rows'); + + // Test that the render() return empty array for empty result. + $view = Views::getView('test_display_entity_reference'); + $view->setDisplay('entity_reference_1'); + $render = $view->display_handler->render(); + $this->assertSame([], $render, 'Render returned empty array'); } } diff --git a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php similarity index 80% rename from core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php rename to core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php index acb3af86..501d9226 100644 --- a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php @@ -1,8 +1,9 @@ enableViewsTestModule(); $this->drupalPlaceBlock('local_tasks_block'); @@ -55,13 +56,13 @@ public function testArguments() { $this->assertCacheContexts(['languages:language_interface', 'route', 'theme', 'url']); $result = $this->xpath('//span[@class="field-content"]'); $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.'); - $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.'); + $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.'); $this->drupalGet('test_route_with_suffix/1/suffix'); $this->assertResponse(200); $result = $this->xpath('//span[@class="field-content"]'); $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.'); - $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.'); + $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.'); $this->drupalGet('test_route_with_suffix_and_argument/1/suffix/2'); $this->assertResponse(200); @@ -72,13 +73,13 @@ public function testArguments() { $this->assertResponse(200); $result = $this->xpath('//span[@class="field-content"]'); $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.'); - $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.'); + $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.'); $this->drupalGet('test_route_with_long_argument/1'); $this->assertResponse(200); $result = $this->xpath('//span[@class="field-content"]'); $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.'); - $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.'); + $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.'); } /** @@ -88,11 +89,11 @@ public function testPageDisplayMenu() { // Check local tasks. $this->drupalGet('test_page_display_menu'); $this->assertResponse(200); - $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', array( + $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]/child::text()', [ ':ul_class' => 'tabs primary', ':a_class' => 'is-active', - )); - $this->assertEqual((string) $element[0], t('Test default tab')); + ]); + $this->assertEqual($element[0]->getText(), t('Test default tab')); $this->assertTitle(t('Test default page | Drupal')); $this->drupalGet('test_page_display_menu/default'); @@ -100,11 +101,11 @@ public function testPageDisplayMenu() { $this->drupalGet('test_page_display_menu/local'); $this->assertResponse(200); - $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', array( + $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]/child::text()', [ ':ul_class' => 'tabs primary', ':a_class' => 'is-active', - )); - $this->assertEqual((string) $element[0], t('Test local tab')); + ]); + $this->assertEqual($element[0]->getText(), t('Test local tab')); $this->assertTitle(t('Test local page | Drupal')); // Check an ordinary menu link. @@ -114,7 +115,7 @@ public function testPageDisplayMenu() { $this->drupalGet(''); $menu_link = $this->cssSelect('nav.block-menu ul.menu a'); - $this->assertEqual((string) $menu_link[0], 'Test menu link'); + $this->assertEqual($menu_link[0]->getText(), 'Test menu link'); // Update the menu link. $this->drupalPostForm("admin/structure/menu/link/views_view:views.test_page_display_menu.page_3/edit", [ @@ -123,7 +124,7 @@ public function testPageDisplayMenu() { $this->drupalGet(''); $menu_link = $this->cssSelect('nav.block-menu ul.menu a'); - $this->assertEqual((string) $menu_link[0], 'New title'); + $this->assertEqual($menu_link[0]->getText(), 'New title'); } /** diff --git a/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php new file mode 100644 index 00000000..67481529 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php @@ -0,0 +1,364 @@ +enableViewsTestModule(); + + $this->adminUser = $this->drupalCreateUser(['administer views']); + $this->drupalLogin($this->adminUser); + + // Create 10 nodes. + for ($i = 0; $i <= 10; $i++) { + $this->drupalCreateNode(['promote' => TRUE]); + } + } + + /** + * Tests the display test plugin. + * + * @see \Drupal\views_test_data\Plugin\views\display\DisplayTest + */ + public function testDisplayPlugin() { + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = $this->container->get('renderer'); + $view = Views::getView('test_view'); + + // Add a new 'display_test' display and test it's there. + $view->storage->addDisplay('display_test'); + $displays = $view->storage->get('display'); + + $this->assertTrue(isset($displays['display_test_1']), 'Added display has been assigned to "display_test_1"'); + + // Check the display options are like expected. + $options = [ + 'display_options' => [], + 'display_plugin' => 'display_test', + 'id' => 'display_test_1', + 'display_title' => 'Display test', + 'position' => 1, + ]; + $this->assertEqual($displays['display_test_1'], $options); + + // Add another one to ensure that position is counted up. + $view->storage->addDisplay('display_test'); + $displays = $view->storage->get('display'); + $options = [ + 'display_options' => [], + 'display_plugin' => 'display_test', + 'id' => 'display_test_2', + 'display_title' => 'Display test 2', + 'position' => 2, + ]; + $this->assertEqual($displays['display_test_2'], $options); + + // Move the second display before the first one in order to test custom + // sorting. + $displays['display_test_1']['position'] = 2; + $displays['display_test_2']['position'] = 1; + $view->storage->set('display', $displays); + $view->save(); + + $view->setDisplay('display_test_1'); + + $this->assertTrue($view->display_handler instanceof DisplayTestPlugin, 'The correct display handler instance is on the view object.'); + + // Check the test option. + $this->assertIdentical($view->display_handler->getOption('test_option'), ''); + + $style = $view->display_handler->getOption('style'); + $style['type'] = 'test_style'; + $view->display_handler->setOption('style', $style); + $view->initDisplay(); + $view->initStyle(); + $view->style_plugin->setUsesRowPlugin(FALSE); + + $output = $view->preview(); + $output = $renderer->renderRoot($output); + + $this->assertTrue(strpos($output, '

            ') !== FALSE, 'An empty value for test_option found in output.'); + + // Change this option and check the title of out output. + $view->display_handler->overrideOption('test_option', 'Test option title'); + $view->save(); + + $output = $view->preview(); + $output = $renderer->renderRoot($output); + + // Test we have our custom

            tag in the output of the view. + $this->assertTrue(strpos($output, '

            Test option title

            ') !== FALSE, 'The test_option value found in display output title.'); + + // Test that the display category/summary is in the UI. + $this->drupalGet('admin/structure/views/view/test_view/edit/display_test_1'); + $this->assertText('Display test settings'); + // Ensure that the order is as expected. + $result = $this->xpath('//ul[@id="views-display-menu-tabs"]/li/a/child::text()'); + $this->assertEqual($result[0]->getText(), 'Display test 2'); + $this->assertEqual($result[1]->getText(), 'Display test'); + + $this->clickLink('Test option title'); + + $test_option = $this->randomString(); + $this->drupalPostForm(NULL, ['test_option' => $test_option], t('Apply')); + + // Check the new value has been saved by checking the UI summary text. + $this->drupalGet('admin/structure/views/view/test_view/edit/display_test_1'); + $this->assertLink($test_option); + + // Test the enable/disable status of a display. + $view->display_handler->setOption('enabled', FALSE); + $this->assertFalse($view->display_handler->isEnabled(), 'Make sure that isEnabled returns FALSE on a disabled display.'); + $view->display_handler->setOption('enabled', TRUE); + $this->assertTrue($view->display_handler->isEnabled(), 'Make sure that isEnabled returns TRUE on a disabled display.'); + } + + /** + * Tests the overriding of filter_groups. + */ + public function testFilterGroupsOverriding() { + $view = Views::getView('test_filter_groups'); + $view->initDisplay(); + + // mark is as overridden, yes FALSE, means overridden. + $view->displayHandlers->get('page')->setOverride('filter_groups', FALSE); + $this->assertFalse($view->displayHandlers->get('page')->isDefaulted('filter_groups'), "Make sure that 'filter_groups' is marked as overridden."); + $this->assertFalse($view->displayHandlers->get('page')->isDefaulted('filters'), "Make sure that 'filters'' is marked as overridden."); + } + + /** + * Tests the getAttachedDisplays method. + */ + public function testGetAttachedDisplays() { + $view = Views::getView('test_get_attach_displays'); + + // Both the feed_1 and the feed_2 display are attached to the page display. + $view->setDisplay('page_1'); + $this->assertEqual($view->display_handler->getAttachedDisplays(), ['feed_1', 'feed_2']); + + $view->setDisplay('feed_1'); + $this->assertEqual($view->display_handler->getAttachedDisplays(), []); + } + + /** + * Tests the readmore validation. + */ + public function testReadMoreNoDisplay() { + $view = Views::getView('test_display_more'); + // Confirm that the view validates when there is a page display. + $errors = $view->validate(); + $this->assertTrue(empty($errors), 'More link validation has no errors.'); + + // Confirm that the view does not validate when the page display is disabled. + $view->setDisplay('page_1'); + $view->display_handler->setOption('enabled', FALSE); + $view->setDisplay('default'); + $errors = $view->validate(); + $this->assertTrue(!empty($errors), 'More link validation has some errors.'); + $this->assertEqual($errors['default'][0], 'Display "Master" uses a "more" link but there are no displays it can link to. You need to specify a custom URL.', 'More link validation has the right error.'); + + // Confirm that the view does not validate when the page display does not exist. + $view = Views::getView('test_view'); + $view->setDisplay('default'); + $view->display_handler->setOption('use_more', 1); + $errors = $view->validate(); + $this->assertTrue(!empty($errors), 'More link validation has some errors.'); + $this->assertEqual($errors['default'][0], 'Display "Master" uses a "more" link but there are no displays it can link to. You need to specify a custom URL.', 'More link validation has the right error.'); + } + + /** + * Tests invalid display plugins. + */ + public function testInvalidDisplayPlugins() { + $this->drupalGet('test_display_invalid'); + $this->assertResponse(200); + + // Change the page plugin id to an invalid one. Bypass the entity system + // so no menu rebuild was executed (so the path is still available). + $config = $this->config('views.view.test_display_invalid'); + $config->set('display.page_1.display_plugin', 'invalid'); + $config->save(); + + $this->drupalGet('test_display_invalid'); + $this->assertResponse(200); + $this->assertText('The "invalid" plugin does not exist.'); + + // Rebuild the router, and ensure that the path is not accessible anymore. + views_invalidate_cache(); + \Drupal::service('router.builder')->rebuildIfNeeded(); + + $this->drupalGet('test_display_invalid'); + $this->assertResponse(404); + + // Change the display plugin ID back to the correct ID. + $config = $this->config('views.view.test_display_invalid'); + $config->set('display.page_1.display_plugin', 'page'); + $config->save(); + + // Place the block display. + $block = $this->drupalPlaceBlock('views_block:test_display_invalid-block_1', ['label' => 'Invalid display']); + + $this->drupalGet(''); + $this->assertResponse(200); + $result = $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]); + $this->assertEquals(1, count($result)); + + // Change the block plugin ID to an invalid one. + $config = $this->config('views.view.test_display_invalid'); + $config->set('display.block_1.display_plugin', 'invalid'); + $config->save(); + + // Test the page is still displayed, the block not present, and has the + // plugin warning message. + $this->drupalGet(''); + $this->assertResponse(200); + $this->assertText('The "invalid" plugin does not exist.'); + $result = $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]); + $this->assertEquals(0, count($result)); + } + + /** + * Tests display validation when a required relationship is missing. + */ + public function testMissingRelationship() { + $view = Views::getView('test_exposed_relationship_admin_ui'); + + // Remove the relationship that is not used by other handlers. + $view->removeHandler('default', 'relationship', 'uid_1'); + $errors = $view->validate(); + // Check that no error message is shown. + $this->assertTrue(empty($errors['default']), 'No errors found when removing unused relationship.'); + + // Unset cached relationships (see DisplayPluginBase::getHandlers()) + unset($view->display_handler->handlers['relationship']); + + // Remove the relationship used by other handlers. + $view->removeHandler('default', 'relationship', 'uid'); + // Validate display + $errors = $view->validate(); + // Check that the error messages are shown. + $this->assertTrue(count($errors['default']) == 2, 'Error messages found for required relationship'); + $this->assertEqual($errors['default'][0], t('The %handler_type %handler uses a relationship that has been removed.', ['%handler_type' => 'field', '%handler' => 'User: Last login'])); + $this->assertEqual($errors['default'][1], t('The %handler_type %handler uses a relationship that has been removed.', ['%handler_type' => 'field', '%handler' => 'User: Created'])); + } + + /** + * Tests the outputIsEmpty method on the display. + */ + public function testOutputIsEmpty() { + $view = Views::getView('test_display_empty'); + $this->executeView($view); + $this->assertTrue(count($view->result) > 0, 'Ensure the result of the view is not empty.'); + $this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty.'); + $view->destroy(); + + // Add a filter, so the view result is empty. + $view->setDisplay('default'); + $item = [ + 'table' => 'views_test_data', + 'field' => 'id', + 'id' => 'id', + 'value' => ['value' => 7297] + ]; + $view->setHandler('default', 'filter', 'id', $item); + $this->executeView($view); + $this->assertFalse(count($view->result), 'Ensure the result of the view is empty.'); + $this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty, because the empty text still appears.'); + $view->destroy(); + + // Remove the empty area, but mark the header area to still appear. + $view->removeHandler('default', 'empty', 'area'); + $item = $view->getHandler('default', 'header', 'area'); + $item['empty'] = TRUE; + $view->setHandler('default', 'header', 'area', $item); + $this->executeView($view); + $this->assertFalse(count($view->result), 'Ensure the result of the view is empty.'); + $this->assertFalse($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as not empty, because the header text still appears.'); + $view->destroy(); + + // Hide the header on empty results. + $item = $view->getHandler('default', 'header', 'area'); + $item['empty'] = FALSE; + $view->setHandler('default', 'header', 'area', $item); + $this->executeView($view); + $this->assertFalse(count($view->result), 'Ensure the result of the view is empty.'); + $this->assertTrue($view->display_handler->outputIsEmpty(), 'Ensure the view output is marked as empty.'); + } + + /** + * Test translation rendering settings based on entity translatability. + */ + public function testTranslationSetting() { + \Drupal::service('module_installer')->install(['file']); + \Drupal::service('router.builder')->rebuild(); + + // By default there should be no language settings. + $this->checkTranslationSetting(); + \Drupal::service('module_installer')->install(['language']); + + // Enabling the language module should not make a difference. + $this->checkTranslationSetting(); + + // Making the site multilingual should let translatable entity types support + // translation rendering. + ConfigurableLanguage::createFromLangcode('it')->save(); + $this->checkTranslationSetting(TRUE); + } + + /** + * Asserts a node and a file based view for the translation setting. + * + * The file based view should never expose that setting. The node based view + * should if the site is multilingual. + * + * @param bool $expected_node_translatability + * Whether the node based view should be expected to support translation + * settings. + */ + protected function checkTranslationSetting($expected_node_translatability = FALSE) { + $not_supported_text = 'The view is not based on a translatable entity type or the site is not multilingual.'; + $supported_text = 'All content that supports translations will be displayed in the selected language.'; + + $this->drupalGet('admin/structure/views/nojs/display/content/page_1/rendering_language'); + if ($expected_node_translatability) { + $this->assertNoText($not_supported_text); + $this->assertText($supported_text); + } + else { + $this->assertText($not_supported_text); + $this->assertNoText($supported_text); + } + + $this->drupalGet('admin/structure/views/nojs/display/files/page_1/rendering_language'); + $this->assertText($not_supported_text); + $this->assertNoText($supported_text); + } + +} diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php new file mode 100644 index 00000000..80584d79 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php @@ -0,0 +1,168 @@ + 'test_exposed_checkboxes', + 'vid' => 'test_exposed_checkboxes', + 'nodes' => ['article' => 'article'], + ]); + $vocabulary->save(); + $this->vocabulary = $vocabulary; + + ViewTestData::createTestViews(self::class, ['views_test_config']); + $this->enableViewsTestModule(); + + // Create two content types. + $this->drupalCreateContentType(['type' => 'article']); + $this->drupalCreateContentType(['type' => 'page']); + + // Create some random nodes: 5 articles, one page. + for ($i = 0; $i < 5; $i++) { + $this->drupalCreateNode(['type' => 'article']); + } + $this->drupalCreateNode(['type' => 'page']); + } + + /** + * Tests overriding the default render option with checkboxes. + */ + public function testExposedFormRenderCheckboxes() { + // Use a test theme to convert multi-select elements into checkboxes. + \Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']); + $this->config('system.theme') + ->set('default', 'views_test_checkboxes_theme') + ->save(); + + // Only display 5 items per page so we can test that paging works. + $view = Views::getView('test_exposed_form_checkboxes'); + $display = &$view->storage->getDisplay('default'); + $display['display_options']['pager']['options']['items_per_page'] = 5; + + $view->save(); + $this->drupalGet('test_exposed_form_checkboxes'); + + $actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]'); + $this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.'); + $actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]'); + $this->assertEqual(count($actual), 1, 'Page option renders as a checkbox'); + + // Ensure that all results are displayed. + $rows = $this->xpath("//div[contains(@class, 'views-row')]"); + $this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.'); + + $this->clickLink('Page 2'); + $rows = $this->xpath("//div[contains(@class, 'views-row')]"); + $this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.'); + $this->assertNoText('An illegal choice has been detected. Please contact the site administrator.'); + } + + /** + * Tests that "is all of" filters work with checkboxes. + */ + public function testExposedIsAllOfFilter() { + foreach (['Term 1', 'Term 2', 'Term 3'] as $term_name) { + // Add a few terms to the new vocabulary. + $term = Term::create([ + 'name' => $term_name, + 'vid' => $this->vocabulary->id(), + ]); + $term->save(); + $this->terms[] = $term; + } + + // Create a field. + $field_name = Unicode::strtolower($this->randomMachineName()); + $handler_settings = [ + 'target_bundles' => [ + $this->vocabulary->id() => $this->vocabulary->id(), + ], + 'auto_create' => FALSE, + ]; + $this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + + // Add some test nodes. + $this->createNode([ + 'type' => 'article', + $field_name => [$this->terms[0]->id(), $this->terms[1]->id()], + ]); + $this->createNode([ + 'type' => 'article', + $field_name => [$this->terms[0]->id(), $this->terms[2]->id()], + ]); + + // Use a test theme to convert multi-select elements into checkboxes. + \Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']); + $this->config('system.theme') + ->set('default', 'views_test_checkboxes_theme') + ->save(); + + $this->drupalGet('test_exposed_form_checkboxes'); + + // Ensure that all results are displayed. + $rows = $this->xpath("//div[contains(@class, 'views-row')]"); + $this->assertEqual(count($rows), 8, 'All rows are displayed by default on the first page when no options are checked.'); + $this->assertNoText('An illegal choice has been detected. Please contact the site administrator.'); + + // Select one option and ensure we still have results. + $tid = $this->terms[0]->id(); + $this->drupalPostForm(NULL, ["tid[$tid]" => $tid], t('Apply')); + + // Ensure only nodes tagged with $tid are displayed. + $rows = $this->xpath("//div[contains(@class, 'views-row')]"); + $this->assertEqual(count($rows), 2, 'Correct rows are displayed when a tid is selected.'); + $this->assertNoText('An illegal choice has been detected. Please contact the site administrator.'); + } + +} diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php new file mode 100644 index 00000000..eaa5aaa3 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php @@ -0,0 +1,360 @@ +enableViewsTestModule(); + + $this->drupalCreateContentType(['type' => 'article']); + + // Create some random nodes. + for ($i = 0; $i < 5; $i++) { + $this->drupalCreateNode(['type' => 'article']); + } + } + + /** + * Tests the submit button. + */ + public function testSubmitButton() { + // Test the submit button value defaults to 'Apply'. + $this->drupalGet('test_exposed_form_buttons'); + $this->assertResponse(200); + $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', t('Apply')); + + // Rename the label of the submit button. + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + + $exposed_form = $view->display_handler->getOption('exposed_form'); + $exposed_form['options']['submit_button'] = $expected_label = $this->randomMachineName(); + $view->display_handler->setOption('exposed_form', $exposed_form); + $view->save(); + + // Make sure the submit button label changed. + $this->drupalGet('test_exposed_form_buttons'); + $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', $expected_label); + + // Make sure an empty label uses the default 'Apply' button value too. + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + + $exposed_form = $view->display_handler->getOption('exposed_form'); + $exposed_form['options']['submit_button'] = ''; + $view->display_handler->setOption('exposed_form', $exposed_form); + $view->save(); + + // Make sure the submit button label shows 'Apply'. + $this->drupalGet('test_exposed_form_buttons'); + $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', t('Apply')); + } + + /** + * Tests the exposed form with a non-standard identifier. + */ + public function testExposedIdentifier() { + // Alter the identifier of the filter to a random string. + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + $identifier = 'new_identifier'; + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'type' => [ + 'exposed' => TRUE, + 'field' => 'type', + 'id' => 'type', + 'table' => 'node_field_data', + 'plugin_id' => 'in_operator', + 'entity_type' => 'node', + 'entity_field' => 'type', + 'expose' => [ + 'identifier' => $identifier, + 'label' => 'Content: Type', + 'operator_id' => 'type_op', + 'reduce' => FALSE, + 'description' => 'Exposed overridden description' + ], + ] + ]); + $view->save(); + $this->drupalGet('test_exposed_form_buttons', ['query' => [$identifier => 'article']]); + $this->assertFieldById(Html::getId('edit-' . $identifier), 'article', "Article type filter set with new identifier."); + + // Alter the identifier of the filter to a random string containing + // restricted characters. + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + $identifier = 'bad identifier'; + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'type' => [ + 'exposed' => TRUE, + 'field' => 'type', + 'id' => 'type', + 'table' => 'node_field_data', + 'plugin_id' => 'in_operator', + 'entity_type' => 'node', + 'entity_field' => 'type', + 'expose' => [ + 'identifier' => $identifier, + 'label' => 'Content: Type', + 'operator_id' => 'type_op', + 'reduce' => FALSE, + 'description' => 'Exposed overridden description' + ], + ] + ]); + $this->executeView($view); + + $errors = $view->validate(); + $expected = [ + 'default' => ['This identifier has illegal characters.'], + 'page_1' => ['This identifier has illegal characters.'], + ]; + $this->assertEqual($errors, $expected); + } + + /** + * Tests whether the reset button works on an exposed form. + */ + public function testResetButton() { + // Test the button is hidden when there is no exposed input. + $this->drupalGet('test_exposed_form_buttons'); + $this->assertNoField('edit-reset'); + + $this->drupalGet('test_exposed_form_buttons', ['query' => ['type' => 'article']]); + // Test that the type has been set. + $this->assertFieldById('edit-type', 'article', 'Article type filter set.'); + + // Test the reset works. + $this->drupalGet('test_exposed_form_buttons', ['query' => ['op' => 'Reset']]); + $this->assertResponse(200); + // Test the type has been reset. + $this->assertFieldById('edit-type', 'All', 'Article type filter has been reset.'); + + // Test the button is hidden after reset. + $this->assertNoField('edit-reset'); + + // Test the reset works with type set. + $this->drupalGet('test_exposed_form_buttons', ['query' => ['type' => 'article', 'op' => 'Reset']]); + $this->assertResponse(200); + $this->assertFieldById('edit-type', 'All', 'Article type filter has been reset.'); + + // Test the button is hidden after reset. + $this->assertNoField('edit-reset'); + + // Rename the label of the reset button. + $view = Views::getView('test_exposed_form_buttons'); + $view->setDisplay(); + + $exposed_form = $view->display_handler->getOption('exposed_form'); + $exposed_form['options']['reset_button_label'] = $expected_label = $this->randomMachineName(); + $exposed_form['options']['reset_button'] = TRUE; + $view->display_handler->setOption('exposed_form', $exposed_form); + $view->save(); + + // Look whether the reset button label changed. + $this->drupalGet('test_exposed_form_buttons', ['query' => ['type' => 'article']]); + $this->assertResponse(200); + + $this->helperButtonHasLabel('edit-reset', $expected_label); + } + + /** + * Tests the exposed block functionality. + */ + public function testExposedBlock() { + $this->drupalCreateContentType(['type' => 'page']); + $view = Views::getView('test_exposed_block'); + $view->setDisplay('page_1'); + $block = $this->drupalPlaceBlock('views_exposed_filter_block:test_exposed_block-page_1'); + $this->drupalGet('test_exposed_block'); + + // Test there is an exposed form in a block. + $xpath = $this->buildXPathQuery('//div[@id=:id]/form/@id', [':id' => Html::getUniqueId('block-' . $block->id())]); + $result = $this->xpath($xpath); + $this->assertEquals(1, count($result)); + + // Test there is not an exposed form in the view page content area. + $xpath = $this->buildXPathQuery('//div[@class="view-content"]/form/@id', [':id' => Html::getUniqueId('block-' . $block->id())]); + $this->assertNoFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'No exposed form found in views content region.'); + + // Test there is only one views exposed form on the page. + $elements = $this->xpath('//form[@id=:id]', [':id' => $this->getExpectedExposedFormId($view)]); + $this->assertEqual(count($elements), 1, 'One exposed form block found.'); + + // Test that the correct option is selected after form submission. + $this->assertCacheContext('url'); + $this->assertOptionSelected('edit-type', 'All'); + foreach (['All', 'article', 'page'] as $argument) { + $this->drupalGet('test_exposed_block', ['query' => ['type' => $argument]]); + $this->assertCacheContext('url'); + $this->assertOptionSelected('edit-type', $argument); + } + } + + /** + * Test the input required exposed form type. + */ + public function testInputRequired() { + $view = View::load('test_exposed_form_buttons'); + $display = &$view->getDisplay('default'); + $display['display_options']['exposed_form']['type'] = 'input_required'; + $view->save(); + + $this->drupalGet('test_exposed_form_buttons'); + $this->assertResponse(200); + $this->helperButtonHasLabel('edit-submit-test-exposed-form-buttons', t('Apply')); + + // Ensure that no results are displayed. + $rows = $this->xpath("//div[contains(@class, 'views-row')]"); + $this->assertEqual(count($rows), 0, 'No rows are displayed by default when no input is provided.'); + + $this->drupalGet('test_exposed_form_buttons', ['query' => ['type' => 'article']]); + + // Ensure that results are displayed. + $rows = $this->xpath("//div[contains(@class, 'views-row')]"); + $this->assertEqual(count($rows), 5, 'All rows are displayed by default when input is provided.'); + } + + /** + * Test the "on demand text" for the input required exposed form type. + */ + public function testTextInputRequired() { + $view = Views::getView('test_exposed_form_buttons'); + $display = &$view->storage->getDisplay('default'); + $display['display_options']['exposed_form']['type'] = 'input_required'; + // Set up the "on demand text". + // @see https://www.drupal.org/node/535868 + $on_demand_text = 'Select any filter and click Apply to see results.'; + $display['display_options']['exposed_form']['options']['text_input_required'] = $on_demand_text; + $display['display_options']['exposed_form']['options']['text_input_required_format'] = filter_default_format(); + $view->save(); + + // Ensure that the "on demand text" is displayed when no exposed filters are + // applied. + $this->drupalGet('test_exposed_form_buttons'); + $this->assertText('Select any filter and click Apply to see results.'); + + // Ensure that the "on demand text" is not displayed when an exposed filter + // is applied. + $this->drupalGet('test_exposed_form_buttons', ['query' => ['type' => 'article']]); + $this->assertNoText($on_demand_text); + } + + /** + * Tests exposed forms with exposed sort and items per page. + */ + public function testExposedSortAndItemsPerPage() { + for ($i = 0; $i < 50; $i++) { + $entity = EntityTest::create([]); + $entity->save(); + } + $contexts = [ + 'languages:language_interface', + 'entity_test_view_grants', + 'theme', + 'url.query_args', + 'languages:language_content' + ]; + + $this->drupalGet('test_exposed_form_sort_items_per_page'); + $this->assertCacheContexts($contexts); + $this->assertIds(range(1, 10, 1)); + + $this->drupalGet('test_exposed_form_sort_items_per_page', ['query' => ['sort_order' => 'DESC']]); + $this->assertCacheContexts($contexts); + $this->assertIds(range(50, 41, 1)); + + $this->drupalGet('test_exposed_form_sort_items_per_page', ['query' => ['sort_order' => 'DESC', 'items_per_page' => 25]]); + $this->assertCacheContexts($contexts); + $this->assertIds(range(50, 26, 1)); + + $this->drupalGet('test_exposed_form_sort_items_per_page', ['query' => ['sort_order' => 'DESC', 'items_per_page' => 25, 'offset' => 10]]); + $this->assertCacheContexts($contexts); + $this->assertIds(range(40, 16, 1)); + } + + /** + * Checks whether the specified ids are the ones displayed in the view output. + * + * @param int[] $ids + * The ids to check. + * + * @return bool + * TRUE if ids match, FALSE otherwise. + */ + protected function assertIds(array $ids) { + $elements = $this->cssSelect('div.view-test-exposed-form-sort-items-per-page div.views-row span.field-content'); + $actual_ids = []; + foreach ($elements as $element) { + $actual_ids[] = (int) $element->getText(); + } + + return $this->assertIdentical($ids, $actual_ids); + } + + /** + * Returns a views exposed form ID. + * + * @param \Drupal\views\ViewExecutable $view + * The view to create an ID for. + * + * @return string + * The form ID. + */ + protected function getExpectedExposedFormId(ViewExecutable $view) { + return Html::cleanCssIdentifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display); + } + + /** + * Tests a view which is rendered after a form with a validation error. + */ + public function testFormErrorWithExposedForm() { + $this->drupalGet('views_test_data_error_form_page'); + $this->assertResponse(200); + $form = $this->cssSelect('form.views-exposed-form'); + $this->assertTrue($form, 'The exposed form element was found.'); + $this->assertRaw(t('Apply'), 'Ensure the exposed form is rendered before submitting the normal form.'); + $this->assertRaw('
            ', 'Views result shown.'); + + $this->drupalPostForm(NULL, [], t('Submit')); + $this->assertResponse(200); + $form = $this->cssSelect('form.views-exposed-form'); + $this->assertTrue($form, 'The exposed form element was found.'); + $this->assertRaw(t('Apply'), 'Ensure the exposed form is rendered after submitting the normal form.'); + $this->assertRaw('
            ', 'Views result shown.'); + } + +} diff --git a/core/modules/views/src/Tests/Plugin/FilterTest.php b/core/modules/views/tests/src/Functional/Plugin/FilterTest.php similarity index 86% rename from core/modules/views/src/Tests/Plugin/FilterTest.php rename to core/modules/views/tests/src/Functional/Plugin/FilterTest.php index 5e26356b..60424108 100644 --- a/core/modules/views/src/Tests/Plugin/FilterTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/FilterTest.php @@ -1,7 +1,8 @@ enableViewsTestModule(); - $this->adminUser = $this->drupalCreateUser(array('administer views')); + $this->adminUser = $this->drupalCreateUser(['administer views']); $this->drupalLogin($this->adminUser); $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); $this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']); @@ -60,16 +61,16 @@ public function testFilterQuery() { $view->initDisplay(); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_filter', 'table' => 'views_test_data', 'field' => 'name', 'operator' => '=', 'value' => 'John', 'group' => 0, - ), - )); + ], + ]); $this->executeView($view); @@ -90,23 +91,23 @@ public function testFilterQuery() { // Check that we have a single element, as a result of applying the '= John' // filter. - $this->assertEqual(count($view->result), 1, format_string('Results were returned. @count results.', array('@count' => count($view->result)))); + $this->assertEqual(count($view->result), 1, format_string('Results were returned. @count results.', ['@count' => count($view->result)])); $view->destroy(); $view->initDisplay(); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_filter', 'table' => 'views_test_data', 'field' => 'name', 'operator' => '<>', 'value' => 'John', 'group' => 0, - ), - )); + ], + ]); $this->executeView($view); @@ -116,15 +117,15 @@ public function testFilterQuery() { // Check if we have the other elements in the dataset, as a result of // applying the '<> John' filter. - $this->assertEqual(count($view->result), 4, format_string('Results were returned. @count results.', array('@count' => count($view->result)))); + $this->assertEqual(count($view->result), 4, format_string('Results were returned. @count results.', ['@count' => count($view->result)])); $view->destroy(); $view->initDisplay(); // Set the test_enable option to FALSE. The 'where' clause should not be // added to the query. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_filter', 'table' => 'views_test_data', 'field' => 'name', @@ -133,14 +134,14 @@ public function testFilterQuery() { 'group' => 0, // Disable this option, so nothing should be added to the query. 'test_enable' => FALSE, - ), - )); + ], + ]); // Execute the view again. $this->executeView($view); // Check if we have all 5 results. - $this->assertEqual(count($view->result), 5, format_string('All @count results returned', array('@count' => count($view->displayHandlers)))); + $this->assertEqual(count($view->result), 5, format_string('All @count results returned', ['@count' => count($view->displayHandlers)])); } /** @@ -162,4 +163,5 @@ public function testInOperatorSelectAllOptions() { $this->drupalPostForm(NULL, [], t('Update preview')); $this->assertNoText('An illegal choice has been detected.'); } + } diff --git a/core/modules/views/src/Tests/Plugin/MenuLinkTest.php b/core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php similarity index 93% rename from core/modules/views/src/Tests/Plugin/MenuLinkTest.php rename to core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php index 06e661f2..8afbb57b 100644 --- a/core/modules/views/src/Tests/Plugin/MenuLinkTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php @@ -1,9 +1,9 @@ enableViewsTestModule(); diff --git a/core/modules/views/src/Tests/Plugin/MiniPagerTest.php b/core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php similarity index 84% rename from core/modules/views/src/Tests/Plugin/MiniPagerTest.php rename to core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php index 1a73b698..492d22f9 100644 --- a/core/modules/views/src/Tests/Plugin/MiniPagerTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php @@ -1,7 +1,8 @@ drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); // Create a bunch of test nodes. for ($i = 0; $i < 20; $i++) { $this->nodes[] = $this->drupalCreateNode(); @@ -55,7 +56,7 @@ public function testMiniPagerRender() { $this->assertText($this->nodes[1]->label()); $this->assertText($this->nodes[2]->label()); - $this->drupalGet('test_mini_pager', array('query' => array('page' => 1))); + $this->drupalGet('test_mini_pager', ['query' => ['page' => 1]]); $this->assertText('‹‹ test', 'The previous link appears.'); $this->assertText('Page 2', 'The current page info shows the second page.'); $this->assertText('›› test', 'The next link appears.'); @@ -63,7 +64,7 @@ public function testMiniPagerRender() { $this->assertText($this->nodes[4]->label()); $this->assertText($this->nodes[5]->label()); - $this->drupalGet('test_mini_pager', array('query' => array('page' => 6))); + $this->drupalGet('test_mini_pager', ['query' => ['page' => 6]]); $this->assertNoText('›› test', 'The next link appears on the last page.'); $this->assertText('Page 7', 'The current page info shows the last page.'); $this->assertText('‹‹ test', 'The previous link does not appear on the last page.'); @@ -77,9 +78,9 @@ public function testMiniPagerRender() { $this->assertIdentical($view->get_total_rows, TRUE, 'The query was set to calculate the total number of rows.'); $this->assertEqual(count($this->nodes), $view->total_rows, 'The total row count is equal to the number of nodes.'); - $this->drupalGet('test_mini_pager_total', array('query' => array('page' => 1))); + $this->drupalGet('test_mini_pager_total', ['query' => ['page' => 1]]); $this->assertText('of ' . count($this->nodes), 'The first page shows the total row count.'); - $this->drupalGet('test_mini_pager_total', array('query' => array('page' => 6))); + $this->drupalGet('test_mini_pager_total', ['query' => ['page' => 6]]); $this->assertText('of ' . count($this->nodes), 'The last page shows the total row count.'); // Test a mini pager with just one item per page. @@ -88,13 +89,13 @@ public function testMiniPagerRender() { $this->assertText('Page 1'); $this->assertText($this->nodes[0]->label()); - $this->drupalGet('test_mini_pager_one', array('query' => array('page' => 1))); + $this->drupalGet('test_mini_pager_one', ['query' => ['page' => 1]]); $this->assertText('‹‹'); $this->assertText('Page 2'); $this->assertText('››'); $this->assertText($this->nodes[1]->label()); - $this->drupalGet('test_mini_pager_one', array('query' => array('page' => 19))); + $this->drupalGet('test_mini_pager_one', ['query' => ['page' => 19]]); $this->assertNoText('››'); $this->assertText('Page 20'); $this->assertText('‹‹'); diff --git a/core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php b/core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php similarity index 93% rename from core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php rename to core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php index bb063287..08f2504c 100644 --- a/core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php @@ -1,10 +1,10 @@ drupalCreateUser(['administer views', 'administer languages']); $this->drupalLogin($web_user); @@ -37,7 +37,7 @@ protected function setUp() { /** * Test plural formatting setting on a numeric views handler. */ - function testNumericFormatPlural() { + public function testNumericFormatPlural() { // Create a file. $file = $this->createFile(); @@ -59,7 +59,7 @@ function testNumericFormatPlural() { // Assert that changing the settings will change configuration properly. $edit = ['options[format_plural_values][0]' => '1 time', 'options[format_plural_values][1]' => '@count times']; $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $config = $this->config('views.view.numeric_test'); $field_config_prefix = 'display.default.display_options.fields.count.'; @@ -103,7 +103,7 @@ function testNumericFormatPlural() { 'options[format_plural_values][3]' => '@count time3', ]; $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $config = $this->config('views.view.numeric_test'); $field_config_prefix = 'display.default.display_options.fields.count.'; $this->assertEqual($config->get($field_config_prefix . 'format_plural'), TRUE); diff --git a/core/modules/views/tests/src/Functional/Plugin/PagerTest.php b/core/modules/views/tests/src/Functional/Plugin/PagerTest.php new file mode 100644 index 00000000..c80fa09b --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/PagerTest.php @@ -0,0 +1,454 @@ +getEditable('views.settings')->set('ui.show.master_display', TRUE)->save(); + + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); + $this->drupalLogin($admin_user); + // Test behavior described in + // https://www.drupal.org/node/652712#comment-2354918. + + $this->drupalGet('admin/structure/views/view/test_view/edit'); + + $edit = [ + 'pager[type]' => 'full', + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/pager', $edit, t('Apply')); + $edit = [ + 'pager_options[items_per_page]' => 20, + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/pager_options', $edit, t('Apply')); + $this->assertText('20 items'); + + // Change type and check whether the type is new type is stored. + $edit = [ + 'pager[type]' => 'mini', + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/pager', $edit, t('Apply')); + $this->drupalGet('admin/structure/views/view/test_view/edit'); + $this->assertText('Mini', 'Changed pager plugin, should change some text'); + + // Test behavior described in + // https://www.drupal.org/node/652712#comment-2354400. + $view = Views::getView('test_store_pager_settings'); + // Make it editable in the admin interface. + $view->save(); + + $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit'); + + $edit = [ + 'pager[type]' => 'full', + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/default/pager', $edit, t('Apply')); + $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit'); + $this->assertText('Full'); + + $edit = [ + 'pager_options[items_per_page]' => 20, + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/default/pager_options', $edit, t('Apply')); + $this->assertText('20 items'); + + // add new display and test the settings again, by override it. + $edit = []; + // Add a display and override the pager settings. + $this->drupalPostForm('admin/structure/views/view/test_store_pager_settings/edit', $edit, t('Add Page')); + $edit = [ + 'override[dropdown]' => 'page_1', + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager', $edit, t('Apply')); + + $edit = [ + 'pager[type]' => 'mini', + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager', $edit, t('Apply')); + $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit/page_1'); + $this->assertText('Mini', 'Changed pager plugin, should change some text'); + + $edit = [ + 'pager_options[items_per_page]' => 10, + ]; + $this->drupalPostForm('admin/structure/views/nojs/display/test_store_pager_settings/default/pager_options', $edit, t('Apply')); + $this->assertText('10 items', 'The default value has been changed.'); + $this->drupalGet('admin/structure/views/view/test_store_pager_settings/edit/page_1'); + $this->assertText('20 items', 'The original value remains unchanged.'); + + // Test that the override element is only displayed on pager plugin selection form. + $this->drupalGet('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager'); + $this->assertFieldByName('override[dropdown]', 'page_1', 'The override element is displayed on plugin selection form.'); + $this->drupalGet('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager_options'); + $this->assertNoFieldByName('override[dropdown]', NULL, 'The override element is not displayed on plugin settings form.'); + } + + /** + * Tests the none-pager-query. + */ + public function testNoLimit() { + // Create 11 nodes and make sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + $view = Views::getView('test_pager_none'); + $this->executeView($view); + $this->assertEqual(count($view->result), 11, 'Make sure that every item is returned in the result'); + + // Setup and test a offset. + $view = Views::getView('test_pager_none'); + $view->setDisplay(); + $pager = [ + 'type' => 'none', + 'options' => [ + 'offset' => 3, + ], + ]; + $view->display_handler->setOption('pager', $pager); + $this->executeView($view); + + $this->assertEqual(count($view->result), 8, 'Make sure that every item beside the first three is returned in the result'); + + // Check some public functions. + $this->assertFalse($view->pager->usePager()); + $this->assertFalse($view->pager->useCountQuery()); + $this->assertEqual($view->pager->getItemsPerPage(), 0); + } + + public function testViewTotalRowsWithoutPager() { + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 23; $i++) { + $this->drupalCreateNode(); + } + + $view = Views::getView('test_pager_none'); + $view->get_total_rows = TRUE; + $this->executeView($view); + + $this->assertEqual($view->total_rows, 23, "'total_rows' is calculated when pager type is 'none' and 'get_total_rows' is TRUE."); + } + + /** + * Tests the some pager plugin. + */ + public function testLimit() { + // Create 11 nodes and make sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + + $view = Views::getView('test_pager_some'); + $this->executeView($view); + $this->assertEqual(count($view->result), 5, 'Make sure that only a certain count of items is returned'); + + // Setup and test a offset. + $view = Views::getView('test_pager_some'); + $view->setDisplay(); + $pager = [ + 'type' => 'none', + 'options' => [ + 'offset' => 8, + 'items_per_page' => 5, + ], + ]; + $view->display_handler->setOption('pager', $pager); + $this->executeView($view); + $this->assertEqual(count($view->result), 3, 'Make sure that only a certain count of items is returned'); + + // Check some public functions. + $this->assertFalse($view->pager->usePager()); + $this->assertFalse($view->pager->useCountQuery()); + } + + /** + * Tests the normal pager. + */ + public function testNormalPager() { + // Create 11 nodes and make sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + + $view = Views::getView('test_pager_full'); + $this->executeView($view); + $this->assertEqual(count($view->result), 5, 'Make sure that only a certain count of items is returned'); + + // Setup and test a offset. + $view = Views::getView('test_pager_full'); + $view->setDisplay(); + $pager = [ + 'type' => 'full', + 'options' => [ + 'offset' => 8, + 'items_per_page' => 5, + ], + ]; + $view->display_handler->setOption('pager', $pager); + $this->executeView($view); + $this->assertEqual(count($view->result), 3, 'Make sure that only a certain count of items is returned'); + + // Test items per page = 0 + $view = Views::getView('test_view_pager_full_zero_items_per_page'); + $this->executeView($view); + + $this->assertEqual(count($view->result), 11, 'All items are return'); + + // TODO test number of pages. + + // Test items per page = 0. + // Setup and test a offset. + $view = Views::getView('test_pager_full'); + $view->setDisplay(); + $pager = [ + 'type' => 'full', + 'options' => [ + 'offset' => 0, + 'items_per_page' => 0, + ], + ]; + + $view->display_handler->setOption('pager', $pager); + $this->executeView($view); + $this->assertEqual($view->pager->getItemsPerPage(), 0); + $this->assertEqual(count($view->result), 11); + + // Test pager cache contexts. + $this->drupalGet('test_pager_full'); + $this->assertCacheContexts(['languages:language_interface', 'theme', 'timezone', 'url.query_args', 'user.node_grants:view']); + } + + /** + * Tests rendering with NULL pager. + */ + public function testRenderNullPager() { + // Create 11 nodes and make sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + $view = Views::getView('test_pager_full'); + $this->executeView($view); + // Force the value again here. + $view->setAjaxEnabled(TRUE); + $view->pager = NULL; + $output = $view->render(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->assertEqual(preg_match('/
              /', $output), 0, 'The pager is not rendered.'); + } + + /** + * Test the api functions on the view object. + */ + public function testPagerApi() { + $view = Views::getView('test_pager_full'); + $view->setDisplay(); + // On the first round don't initialize the pager. + + $this->assertEqual($view->getItemsPerPage(), NULL, 'If the pager is not initialized and no manual override there is no items per page.'); + $rand_number = rand(1, 5); + $view->setItemsPerPage($rand_number); + $this->assertEqual($view->getItemsPerPage(), $rand_number, 'Make sure getItemsPerPage uses the settings of setItemsPerPage.'); + + $this->assertEqual($view->getOffset(), NULL, 'If the pager is not initialized and no manual override there is no offset.'); + $rand_number = rand(1, 5); + $view->setOffset($rand_number); + $this->assertEqual($view->getOffset(), $rand_number, 'Make sure getOffset uses the settings of setOffset.'); + + $this->assertEqual($view->getCurrentPage(), NULL, 'If the pager is not initialized and no manual override there is no current page.'); + $rand_number = rand(1, 5); + $view->setCurrentPage($rand_number); + $this->assertEqual($view->getCurrentPage(), $rand_number, 'Make sure getCurrentPage uses the settings of set_current_page.'); + + $view->destroy(); + + // On this round enable the pager. + $view->initDisplay(); + $view->initQuery(); + $view->initPager(); + + $this->assertEqual($view->getItemsPerPage(), 5, 'Per default the view has 5 items per page.'); + $rand_number = rand(1, 5); + $view->setItemsPerPage($rand_number); + $rand_number = rand(6, 11); + $view->pager->setItemsPerPage($rand_number); + $this->assertEqual($view->getItemsPerPage(), $rand_number, 'Make sure getItemsPerPage uses the settings of setItemsPerPage.'); + + $this->assertEqual($view->getOffset(), 0, 'Per default a view has a 0 offset.'); + $rand_number = rand(1, 5); + $view->setOffset($rand_number); + $rand_number = rand(6, 11); + $view->pager->setOffset($rand_number); + $this->assertEqual($view->getOffset(), $rand_number, 'Make sure getOffset uses the settings of setOffset.'); + + $this->assertEqual($view->getCurrentPage(), 0, 'Per default the current page is 0.'); + $rand_number = rand(1, 5); + $view->setCurrentPage($rand_number); + $rand_number = rand(6, 11); + $view->pager->setCurrentPage($rand_number); + $this->assertEqual($view->getCurrentPage(), $rand_number, 'Make sure getCurrentPage uses the settings of set_current_page.'); + + // Set an invalid page and make sure the method takes care about it. + $view->setCurrentPage(-1); + $this->assertEqual($view->getCurrentPage(), 0, 'Make sure setCurrentPage always sets a valid page number.'); + } + + /** + * Tests translating the pager using config_translation. + */ + public function testPagerConfigTranslation() { + $view = Views::getView('content'); + $display = &$view->storage->getDisplay('default'); + $display['display_options']['pager']['options']['items_per_page'] = 5; + $view->save(); + + // Enable locale, config_translation and language module. + $this->container->get('module_installer')->install(['locale', 'language', 'config_translation']); + $this->resetAll(); + + $admin_user = $this->drupalCreateUser(['access content overview', 'administer nodes', 'bypass node access', 'translate configuration']); + $this->drupalLogin($admin_user); + + $langcode = 'nl'; + + // Add a default locale storage for this test. + $this->localeStorage = $this->container->get('locale.storage'); + + // Add Dutch language programmatically. + ConfigurableLanguage::createFromLangcode($langcode)->save(); + + $edit = [ + 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][first]' => '« Eerste', + 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][previous]' => '‹ Vorige', + 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][next]' => 'Volgende ›', + 'translation[config_names][views.view.content][display][default][display_options][pager][options][tags][last]' => 'Laatste »', + ]; + $this->drupalPostForm('admin/structure/views/view/content/translate/nl/edit', $edit, t('Save translation')); + + // We create 11 nodes, this will give us 3 pages. + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + + // Go to the second page so we see both previous and next buttons. + $this->drupalGet('nl/admin/content', ['query' => ['page' => 1]]); + // Translation mapping.. + $labels = [ + '« First' => '« Eerste', + '‹ Previous' => '‹ Vorige', + 'Next ›' => 'Volgende ›', + 'Last »' => 'Laatste »', + ]; + foreach ($labels as $label => $translation) { + // Check if we can find the translation. + $this->assertRaw($translation); + } + } + + /** + * Tests translating the pager using locale. + */ + public function testPagerLocale() { + // Enable locale and language module. + $this->container->get('module_installer')->install(['locale', 'language']); + $this->resetAll(); + $langcode = 'nl'; + + // Add a default locale storage for this test. + $this->localeStorage = $this->container->get('locale.storage'); + + // Add Dutch language programmatically. + ConfigurableLanguage::createFromLangcode($langcode)->save(); + + // Labels that need translations. + $labels = [ + '« First' => '« Eerste', + '‹ Previous' => '‹ Vorige', + 'Next ›' => 'Volgende ›', + 'Last »' => 'Laatste »', + ]; + foreach ($labels as $label => $translation) { + // Create source string. + $source = $this->localeStorage->createString( + [ + 'source' => $label + ] + ); + $source->save(); + $this->createTranslation($source, $translation, $langcode); + } + + // We create 11 nodes, this will give us 3 pages. + $this->drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + + // Go to the second page so we see both previous and next buttons. + $this->drupalGet('nl/test_pager_full', ['query' => ['page' => 1]]); + foreach ($labels as $label => $translation) { + // Check if we can find the translation. + $this->assertRaw($translation); + } + } + + /** + * Creates single translation for source string. + */ + protected function createTranslation($source, $translation, $langcode) { + $values = [ + 'lid' => $source->lid, + 'language' => $langcode, + 'translation' => $translation, + ]; + return $this->localeStorage->createTranslation($values)->save(); + } + +} diff --git a/core/modules/views/src/Tests/Plugin/StyleSummaryTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php similarity index 88% rename from core/modules/views/src/Tests/Plugin/StyleSummaryTest.php rename to core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php index cbd569ca..a2359b97 100644 --- a/core/modules/views/src/Tests/Plugin/StyleSummaryTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php @@ -1,9 +1,9 @@ drupalGet('test-summary'); + // Ensure styles are properly added for summary views. + $this->assertRaw('stable/css/views/views.module.css'); + $summary_list = $this->cssSelect('ul.views-summary li'); $this->assertEqual(4, count($summary_list)); foreach ($summary_list as $summary_list_item) { - $this->assertEqual('(5)', trim((string) $summary_list_item)); + $this->assertEqual('(5)', trim(explode(' ', $summary_list_item->getText())[1])); } $summary_links = $this->cssSelect('ul.views-summary a'); $this->assertEqual(4, count($summary_links)); foreach ($summary_links as $index => $summary_link) { - $this->assertEqual('type' . $index, trim((string) $summary_link)); + $this->assertEqual('type' . $index, trim($summary_link->getText())); } $this->clickLink('type1'); @@ -100,13 +103,13 @@ public function testSummaryView() { $this->assertEqual(3, count($summary_list)); foreach ($summary_list as $summary_list_item) { - $this->assertEqual('(5)', trim((string) $summary_list_item)); + $this->assertEqual('(5)', trim(explode(' ', $summary_list_item->getText())[1])); } $summary_links = $this->cssSelect('.views-summary-unformatted a'); $this->assertEqual(3, count($summary_links)); foreach ($summary_links as $index => $summary_link) { - $this->assertEqual('type' . $index, trim((string) $summary_link)); + $this->assertEqual('type' . $index, trim($summary_link->getText())); } $this->clickLink('type1'); diff --git a/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php new file mode 100644 index 00000000..3bbe6bf9 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php @@ -0,0 +1,232 @@ +enableViewsTestModule(); + } + + /** + * Test table caption/summary/description. + */ + public function testAccessibilitySettings() { + $this->drupalGet('test-table'); + + $result = $this->xpath('//caption/child::text()'); + $this->assertTrue(count($result), 'The caption appears on the table.'); + $this->assertEqual(trim($result[0]->getText()), 'caption-text'); + + $result = $this->xpath('//summary/child::text()'); + $this->assertTrue(count($result), 'The summary appears on the table.'); + $this->assertEqual(trim($result[0]->getText()), 'summary-text'); + + $result = $this->xpath('//caption/details/child::text()'); + $this->assertTrue(count($result), 'The table description appears on the table.'); + $this->assertEqual(trim($result[0]->getText()), 'description-text'); + + // Remove the caption and ensure the caption is not displayed anymore. + $view = View::load('test_table'); + $display = &$view->getDisplay('default'); + $display['display_options']['style']['options']['caption'] = ''; + $view->save(); + + $this->drupalGet('test-table'); + $result = $this->xpath('//caption/child::text()'); + $this->assertFalse(trim($result[0]->getText()), 'Ensure that the caption disappears.'); + + // Remove the table summary. + $display = &$view->getDisplay('default'); + $display['display_options']['style']['options']['summary'] = ''; + $view->save(); + + $this->drupalGet('test-table'); + $result = $this->xpath('//summary/child::text()'); + $this->assertFalse(count($result), 'Ensure that the summary disappears.'); + + // Remove the table description. + $display = &$view->getDisplay('default'); + $display['display_options']['style']['options']['description'] = ''; + $view->save(); + + $this->drupalGet('test-table'); + $result = $this->xpath('//caption/details/child::text()'); + $this->assertFalse(count($result), 'Ensure that the description disappears.'); + } + + /** + * Test table fields in columns. + */ + public function testFieldInColumns() { + $this->drupalGet('test-table'); + + // Ensure that both columns are in separate tds. + // Check for class " views-field-job ", because just "views-field-job" won't + // do: "views-field-job-1" would also contain "views-field-job". + // @see Drupal\system\Tests\Form\ElementTest::testButtonClasses(). + $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job ")]'); + $this->assertTrue(count($result), 'Ensure there is a td with the class views-field-job'); + $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job-1 ")]'); + $this->assertTrue(count($result), 'Ensure there is a td with the class views-field-job-1'); + + // Combine the second job-column with the first one, with ', ' as separator. + $view = View::load('test_table'); + $display = &$view->getDisplay('default'); + $display['display_options']['style']['options']['columns']['job_1'] = 'job'; + $display['display_options']['style']['options']['info']['job']['separator'] = ', '; + $view->save(); + + // Ensure that both columns are properly combined. + $this->drupalGet('test-table'); + + $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job views-field-job-1 ")]'); + $this->assertTrue(count($result), 'Ensure that the job column class names are joined into a single column'); + + $result = $this->xpath('//tbody/tr/td[contains(., "Drummer, Drummer")]'); + $this->assertTrue(count($result), 'Ensure the job column values are joined into a single column'); + } + + /** + * Test that a number with the value of "0" is displayed in the table. + */ + public function testNumericFieldVisible() { + // Adds a new datapoint in the views_test_data table to have a person with + // an age of zero. + $data_set = $this->dataSet(); + $query = db_insert('views_test_data') + ->fields(array_keys($data_set[0])); + $query->values([ + 'name' => 'James McCartney', + 'age' => 0, + 'job' => 'Baby', + 'created' => gmmktime(6, 30, 10, 1, 1, 2000), + 'status' => 1, + ]); + $query->execute(); + + $this->drupalGet('test-table'); + + $result = $this->xpath('//tbody/tr/td[contains(., "Baby")]'); + $this->assertTrue(count($result), 'Ensure that the baby is found.'); + + $result = $this->xpath('//tbody/tr/td[text()=0]'); + $this->assertTrue(count($result), 'Ensure that the baby\'s age is shown'); + } + + /** + * Test that empty columns are hidden when empty_column is set. + */ + public function testEmptyColumn() { + // Empty the 'job' data. + \Drupal::database()->update('views_test_data') + ->fields(['job' => '']) + ->execute(); + + $this->drupalGet('test-table'); + + // Test that only one of the job columns still shows. + $result = $this->xpath('//thead/tr/th/a[text()="Job"]'); + $this->assertEqual(count($result), 1, 'Ensure that empty column header is hidden.'); + + $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job-1 ")]'); + $this->assertEqual(count($result), 0, 'Ensure the empty table cells are hidden.'); + } + + /** + * Tests grouping by a field. + */ + public function testGrouping() { + /** @var \Drupal\views\ViewEntityInterface $view */ + $view = \Drupal::entityTypeManager()->getStorage('view')->load('test_table'); + // Get a reference to the display configuration so we can alter some + // specific style options. + $display = &$view->getDisplay('default'); + // Set job as the grouping field. + $display['display_options']['style']['options']['grouping'][0] = [ + 'field' => 'job', + 'rendered' => TRUE, + 'rendered_strip' => FALSE, + ]; + // Clear the caption text, the rendered job field will be used as a caption. + $display['display_options']['style']['options']['caption'] = ''; + $display['display_options']['style']['options']['summary'] = ''; + $display['display_options']['style']['options']['description'] = ''; + $view->save(); + + // Add a record containing unsafe markup to be sure it's filtered out. + $unsafe_markup = ''; + $unsafe_markup_data = [ + 'name' => 'Marshall', + 'age' => 42, + 'job' => $unsafe_markup, + 'created' => gmmktime(0, 0, 0, 2, 15, 2001), + 'status' => 1, + ]; + $database = $this->container->get('database'); + $database->insert('views_test_data') + ->fields(array_keys($unsafe_markup_data)) + ->values($unsafe_markup_data) + ->execute(); + + $this->drupalGet('test-table'); + $expected_captions = [ + 'Job: Speaker', + 'Job: Songwriter', + 'Job: Drummer', + 'Job: Singer', + 'Job: ' . $unsafe_markup, + ]; + + // Ensure that we don't find the caption containing unsafe markup. + $this->assertNoRaw($unsafe_markup, "Didn't find caption containing unsafe markup."); + + // Ensure that all expected captions are found. + foreach ($expected_captions as $raw_caption) { + $this->assertEscaped($raw_caption); + } + + $display = &$view->getDisplay('default'); + // Remove the label from the grouping field. + $display['display_options']['fields']['job']['label'] = ''; + $view->save(); + + $this->drupalGet('test-table'); + $expected_captions = [ + 'Speaker', + 'Songwriter', + 'Drummer', + 'Singer', + $unsafe_markup, + ]; + + // Ensure that we don't find the caption containing unsafe markup. + $this->assertNoRaw($unsafe_markup, "Didn't find caption containing unsafe markup."); + + // Ensure that all expected captions are found. + foreach ($expected_captions as $raw_caption) { + $this->assertEscaped($raw_caption); + } + } + +} diff --git a/core/modules/views/src/Tests/Plugin/StyleTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTest.php similarity index 87% rename from core/modules/views/src/Tests/Plugin/StyleTest.php rename to core/modules/views/tests/src/Functional/Plugin/StyleTest.php index 6773c83c..fbb5bcff 100644 --- a/core/modules/views/src/Tests/Plugin/StyleTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/StyleTest.php @@ -1,9 +1,9 @@ enableViewsTestModule(); } @@ -87,7 +87,7 @@ public function testStyle() { $this->assertTrue(strpos($output, $random_text) !== FALSE, 'Make sure that the rendering of the style plugin appears in the output of the view.'); } - function testGrouping() { + public function testGrouping() { $this->_testGrouping(FALSE); $this->_testGrouping(TRUE); } @@ -95,57 +95,57 @@ function testGrouping() { /** * Tests the grouping features of styles. */ - function _testGrouping($stripped = FALSE) { + public function _testGrouping($stripped = FALSE) { $view = Views::getView('test_view'); $view->setDisplay(); // Setup grouping by the job and the age field. $view->initStyle(); - $view->style_plugin->options['grouping'] = array( - array('field' => 'job'), - array('field' => 'age'), - ); + $view->style_plugin->options['grouping'] = [ + ['field' => 'job'], + ['field' => 'age'], + ]; // Reduce the amount of items to make the test a bit easier. // Set up the pager. - $view->displayHandlers->get('default')->overrideOption('pager', array( + $view->displayHandlers->get('default')->overrideOption('pager', [ 'type' => 'some', - 'options' => array('items_per_page' => 3), - )); + 'options' => ['items_per_page' => 3], + ]); // Add the job and age field. - $fields = array( - 'name' => array( + $fields = [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'label' => 'Name', - ), - 'job' => array( + ], + 'job' => [ 'id' => 'job', 'table' => 'views_test_data', 'field' => 'job', 'relationship' => 'none', 'label' => 'Job', - ), - 'age' => array( + ], + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'label' => 'Age', - ), - ); + ], + ]; $view->displayHandlers->get('default')->overrideOption('fields', $fields); // Now run the query and groupby the result. $this->executeView($view); - $expected = array(); - $expected['Job: Singer'] = array(); + $expected = []; + $expected['Job: Singer'] = []; $expected['Job: Singer']['group'] = 'Job: Singer'; $expected['Job: Singer']['level'] = 0; - $expected['Job: Singer']['rows']['Age: 25'] = array(); + $expected['Job: Singer']['rows']['Age: 25'] = []; $expected['Job: Singer']['rows']['Age: 25']['group'] = 'Age: 25'; $expected['Job: Singer']['rows']['Age: 25']['level'] = 1; $expected['Job: Singer']['rows']['Age: 25']['rows'][0] = new ResultRow(['index' => 0]); @@ -153,7 +153,7 @@ function _testGrouping($stripped = FALSE) { $expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_data_job = 'Singer'; $expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_data_age = '25'; $expected['Job: Singer']['rows']['Age: 25']['rows'][0]->views_test_data_id = '1'; - $expected['Job: Singer']['rows']['Age: 27'] = array(); + $expected['Job: Singer']['rows']['Age: 27'] = []; $expected['Job: Singer']['rows']['Age: 27']['group'] = 'Age: 27'; $expected['Job: Singer']['rows']['Age: 27']['level'] = 1; $expected['Job: Singer']['rows']['Age: 27']['rows'][1] = new ResultRow(['index' => 1]); @@ -161,10 +161,10 @@ function _testGrouping($stripped = FALSE) { $expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_data_job = 'Singer'; $expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_data_age = '27'; $expected['Job: Singer']['rows']['Age: 27']['rows'][1]->views_test_data_id = '2'; - $expected['Job: Drummer'] = array(); + $expected['Job: Drummer'] = []; $expected['Job: Drummer']['group'] = 'Job: Drummer'; $expected['Job: Drummer']['level'] = 0; - $expected['Job: Drummer']['rows']['Age: 28'] = array(); + $expected['Job: Drummer']['rows']['Age: 28'] = []; $expected['Job: Drummer']['rows']['Age: 28']['group'] = 'Age: 28'; $expected['Job: Drummer']['rows']['Age: 28']['level'] = 1; $expected['Job: Drummer']['rows']['Age: 28']['rows'][2] = new ResultRow(['index' => 2]); @@ -190,8 +190,8 @@ function _testGrouping($stripped = FALSE) { $expected['Job: Drummer']['rows']['Age: 28']['rows'][2]->views_test_data_job = 'Drummer' . $rand3; $expected['Job: Drummer']['group'] = 'Job: Drummer'; - $view->style_plugin->options['grouping'][0] = array('field' => 'job', 'rendered' => TRUE, 'rendered_strip' => TRUE); - $view->style_plugin->options['grouping'][1] = array('field' => 'age', 'rendered' => TRUE, 'rendered_strip' => TRUE); + $view->style_plugin->options['grouping'][0] = ['field' => 'job', 'rendered' => TRUE, 'rendered_strip' => TRUE]; + $view->style_plugin->options['grouping'][1] = ['field' => 'age', 'rendered' => TRUE, 'rendered_strip' => TRUE]; } @@ -226,10 +226,10 @@ function _testGrouping($stripped = FALSE) { $view->setDisplay(); $view->initStyle(); $view->displayHandlers->get('default')->overrideOption('fields', $fields); - $view->style_plugin->options['grouping'] = array( - array('field' => 'job'), - array('field' => 'age'), - ); + $view->style_plugin->options['grouping'] = [ + ['field' => 'job'], + ['field' => 'age'], + ]; $this->executeView($view); @@ -237,8 +237,8 @@ function _testGrouping($stripped = FALSE) { $view->result[0]->views_test_data_job .= $rand1; $view->result[1]->views_test_data_job .= $rand2; $view->result[2]->views_test_data_job .= $rand3; - $view->style_plugin->options['grouping'][0] = array('field' => 'job', 'rendered' => TRUE, 'rendered_strip' => TRUE); - $view->style_plugin->options['grouping'][1] = array('field' => 'age', 'rendered' => TRUE, 'rendered_strip' => TRUE); + $view->style_plugin->options['grouping'][0] = ['field' => 'job', 'rendered' => TRUE, 'rendered_strip' => TRUE]; + $view->style_plugin->options['grouping'][1] = ['field' => 'age', 'rendered' => TRUE, 'rendered_strip' => TRUE]; } $sets_new_rendered = $view->style_plugin->renderGrouping($view->result, $view->style_plugin->options['grouping'], TRUE); @@ -256,7 +256,7 @@ function _testGrouping($stripped = FALSE) { /** * Tests custom css classes. */ - function testCustomRowClasses() { + public function testCustomRowClasses() { $view = Views::getView('test_view'); $view->setDisplay(); diff --git a/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php new file mode 100644 index 00000000..1b3078b5 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php @@ -0,0 +1,84 @@ +drupalCreateContentType(['type' => 'page']); + $this->admin_user = $this->createUser(['bypass node access', 'administer nodes', 'access content overview']); + } + + /** + * Tests bulk selection. + */ + public function testBulkSelection() { + + // Create first node, set updated time to the past. + $node_1 = $this->drupalCreateNode([ + 'type' => 'page', + 'title' => 'The first node', + 'changed' => \Drupal::time()->getRequestTime() - 180 + ]); + + // Login as administrator and go to admin/content. + $this->drupalLogin($this->admin_user); + $this->drupalGet('admin/content'); + $this->assertText($node_1->getTitle()); + + // Create second node now that the admin overview has been rendered. + $node_2 = $this->drupalCreateNode([ + 'type' => 'page', + 'title' => 'The second node', + 'changed' => \Drupal::time()->getRequestTime() - 120 + ]); + + // Now click 'Apply to selected items' and assert the first node is selected + // on the confirm form. + $this->drupalPostForm(NULL, ['node_bulk_form[0]' => TRUE], 'Apply to selected items'); + $this->assertText($node_1->getTitle()); + $this->assertNoText($node_2->getTitle()); + + // Change the pager limit to 2. + $this->config('views.view.content')->set('display.default.display_options.pager.options.items_per_page', 2)->save(); + + // Render the overview page again. + $this->drupalGet('admin/content'); + + // Create third node now that the admin overview has been rendered. + $node_3 = $this->drupalCreateNode([ + 'type' => 'page', + 'title' => 'The third node', + ]); + + // Now click 'Apply to selected items' and assert the second node is + // selected on the confirm form. + $this->drupalPostForm(NULL, ['node_bulk_form[1]' => TRUE], 'Apply to selected items'); + $this->assertText($node_1->getTitle()); + $this->assertNoText($node_3->getTitle()); + } + +} diff --git a/core/modules/views/src/Tests/Plugin/ViewsFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php similarity index 77% rename from core/modules/views/src/Tests/Plugin/ViewsFormTest.php rename to core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php index 01f7a8cf..3f6e1eca 100644 --- a/core/modules/views/src/Tests/Plugin/ViewsFormTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php @@ -1,22 +1,22 @@ enableViewsTestModule(); } @@ -46,16 +47,16 @@ public function testSqlException() { $view->initDisplay(); // Adding a filter that will result in an invalid query. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_exception_filter', 'table' => 'views_test_data', 'field' => 'name', 'operator' => '=', 'value' => 'John', 'group' => 0, - ), - )); + ], + ]); try { $this->executeView($view); diff --git a/core/modules/views/src/Tests/RenderCacheWebTest.php b/core/modules/views/tests/src/Functional/RenderCacheWebTest.php similarity index 83% rename from core/modules/views/src/Tests/RenderCacheWebTest.php rename to core/modules/views/tests/src/Functional/RenderCacheWebTest.php index fcd38b73..f8dfdd81 100644 --- a/core/modules/views/src/Tests/RenderCacheWebTest.php +++ b/core/modules/views/tests/src/Functional/RenderCacheWebTest.php @@ -1,6 +1,6 @@ assertEqual([], $this->cssSelect('div.region-header div.views-field-title')); $this->drupalGet($this->nodes[0]->toUrl()); - $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span; + $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText(); $this->assertEqual('test title 1', $result); $this->drupalGet($this->nodes[1]->toUrl()); - $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span; + $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText(); $this->assertEqual('test title 2', $result); $this->drupalGet($this->nodes[0]->toUrl()); - $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span; + $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText(); $this->assertEqual('test title 1', $result); } diff --git a/core/modules/views/src/Tests/SearchIntegrationTest.php b/core/modules/views/tests/src/Functional/SearchIntegrationTest.php similarity index 82% rename from core/modules/views/src/Tests/SearchIntegrationTest.php rename to core/modules/views/tests/src/Functional/SearchIntegrationTest.php index e71e1594..f4daac77 100644 --- a/core/modules/views/src/Tests/SearchIntegrationTest.php +++ b/core/modules/views/tests/src/Functional/SearchIntegrationTest.php @@ -1,8 +1,9 @@ 'pizza')); + $node['body'] = [['value' => 'pizza']]; $node['type'] = $type->id(); $this->drupalCreateNode($node); @@ -44,11 +47,11 @@ public function testSearchIntegration() { $node_url = $this->getUrl(); $node['title'] = 'sandwich'; - $node['body'] = array(array('value' => 'sandwich with a link to first node')); + $node['body'] = [['value' => 'sandwich with a link to first node']]; $this->drupalCreateNode($node); $node['title'] = 'cola'; - $node['body'] = array(array('value' => 'cola is good with pizza')); + $node['body'] = [['value' => 'cola is good with pizza']]; $node['type'] = $type->id(); $this->drupalCreateNode($node); @@ -108,10 +111,10 @@ public function testSearchIntegration() { $this->cronRun(); $this->drupalGet('test-arg/rocks'); $xpath = '//div[@class="views-row"]//a'; - /** @var \SimpleXMLElement[] $results */ + /** @var \Behat\Mink\Element\NodeElement[] $results */ $results = $this->xpath($xpath); - $this->assertEqual((string) $results[0], "Drupal's search rocks really rocks!"); - $this->assertEqual((string) $results[1], "Drupal's search rocks."); + $this->assertEqual($results[0]->getText(), "Drupal's search rocks really rocks!"); + $this->assertEqual($results[1]->getText(), "Drupal's search rocks."); $this->assertEscaped("Drupal's search rocks really rocks!"); // Test sorting with another set of titles. @@ -127,8 +130,8 @@ public function testSearchIntegration() { $xpath = '//div[@class="views-row"]//a'; /** @var \SimpleXMLElement[] $results */ $results = $this->xpath($xpath); - $this->assertEqual((string) $results[0], "Testing one one one"); - $this->assertEqual((string) $results[1], "Testing one two two two"); + $this->assertEqual($results[0]->getText(), "Testing one one one"); + $this->assertEqual($results[1]->getText(), "Testing one two two two"); } /** @@ -141,8 +144,8 @@ public function testSearchIntegration() { * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertOneLink($label) { - $links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label)); - $message = SafeMarkup::format('Link with label %label found once.', array('%label' => $label)); + $links = $this->xpath('//a[normalize-space(text())=:label]', [':label' => $label]); + $message = SafeMarkup::format('Link with label %label found once.', ['%label' => $label]); return $this->assert(isset($links[0]) && !isset($links[1]), $message); } diff --git a/core/modules/views/src/Tests/SearchMultilingualTest.php b/core/modules/views/tests/src/Functional/SearchMultilingualTest.php similarity index 79% rename from core/modules/views/src/Tests/SearchMultilingualTest.php rename to core/modules/views/tests/src/Functional/SearchMultilingualTest.php index 5f583f09..d6a72bf8 100644 --- a/core/modules/views/src/Tests/SearchMultilingualTest.php +++ b/core/modules/views/tests/src/Functional/SearchMultilingualTest.php @@ -1,8 +1,10 @@ drupalCreateUser(array('administer nodes', 'administer content types', 'administer languages', 'administer content translation', 'access content', 'search content')); + $user = $this->drupalCreateUser(['administer nodes', 'administer content types', 'administer languages', 'administer content translation', 'access content', 'search content']); $this->drupalLogin($user); // Add Spanish language programmatically. @@ -39,28 +43,28 @@ public function testMultilingualSearchFilter() { // Create a content type and make it translatable. $type = $this->drupalCreateContentType(); - $edit = array( + $edit = [ 'language_configuration[language_alterable]' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/types/manage/' . $type->id(), $edit, t('Save content type')); - $edit = array( + $edit = [ 'entity_types[node]' => TRUE, 'settings[node][' . $type->id() . '][translatable]' => TRUE, 'settings[node][' . $type->id() . '][fields][title]' => TRUE, 'settings[node][' . $type->id() . '][fields][body]' => TRUE, - ); + ]; $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); \Drupal::entityManager()->clearCachedDefinitions(); // Add a node in English, with title "sandwich". - $values = array( + $values = [ 'title' => 'sandwich', 'type' => $type->id(), - ); + ]; $node = $this->drupalCreateNode($values); // "Translate" this node into Spanish, with title "pizza". - $node->addTranslation('es', array('title' => 'pizza', 'status' => NODE_PUBLISHED)); + $node->addTranslation('es', ['title' => 'pizza', 'status' => NodeInterface::PUBLISHED]); $node->save(); // Run cron so that the search index tables are updated. diff --git a/core/modules/views/src/Tests/TaxonomyGlossaryTest.php b/core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php similarity index 84% rename from core/modules/views/src/Tests/TaxonomyGlossaryTest.php rename to core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php index ccda8877..fbf5f414 100644 --- a/core/modules/views/src/Tests/TaxonomyGlossaryTest.php +++ b/core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php @@ -1,8 +1,8 @@ enableViewsTestModule(); diff --git a/core/modules/views/src/Tests/Update/ArgumentPlaceholderUpdatePathTest.php b/core/modules/views/tests/src/Functional/Update/ArgumentPlaceholderUpdatePathTest.php similarity index 91% rename from core/modules/views/src/Tests/Update/ArgumentPlaceholderUpdatePathTest.php rename to core/modules/views/tests/src/Functional/Update/ArgumentPlaceholderUpdatePathTest.php index c42cf190..8d60f358 100644 --- a/core/modules/views/src/Tests/Update/ArgumentPlaceholderUpdatePathTest.php +++ b/core/modules/views/tests/src/Functional/Update/ArgumentPlaceholderUpdatePathTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/argument-placeholder.php' + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/argument-placeholder.php' ]; } diff --git a/core/modules/views/src/Tests/Update/BooleanFilterValuesUpdateTest.php b/core/modules/views/tests/src/Functional/Update/BooleanFilterValuesUpdateTest.php similarity index 75% rename from core/modules/views/src/Tests/Update/BooleanFilterValuesUpdateTest.php rename to core/modules/views/tests/src/Functional/Update/BooleanFilterValuesUpdateTest.php index c06539ff..a4787c44 100644 --- a/core/modules/views/src/Tests/Update/BooleanFilterValuesUpdateTest.php +++ b/core/modules/views/tests/src/Functional/Update/BooleanFilterValuesUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/boolean-filter-values.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/boolean-filter-values.php', ]; } diff --git a/core/modules/views/src/Tests/Update/CacheabilityMetadataUpdateTest.php b/core/modules/views/tests/src/Functional/Update/CacheabilityMetadataUpdateTest.php similarity index 81% rename from core/modules/views/src/Tests/Update/CacheabilityMetadataUpdateTest.php rename to core/modules/views/tests/src/Functional/Update/CacheabilityMetadataUpdateTest.php index ef203b2a..6410a608 100644 --- a/core/modules/views/src/Tests/Update/CacheabilityMetadataUpdateTest.php +++ b/core/modules/views/tests/src/Functional/Update/CacheabilityMetadataUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz']; + $this->databaseDumpFiles = [__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz']; } /** diff --git a/core/modules/views/tests/src/Functional/Update/EntityViewsDataUpdateFilledTest.php b/core/modules/views/tests/src/Functional/Update/EntityViewsDataUpdateFilledTest.php new file mode 100644 index 00000000..a1ef463b --- /dev/null +++ b/core/modules/views/tests/src/Functional/Update/EntityViewsDataUpdateFilledTest.php @@ -0,0 +1,20 @@ +databaseDumpFiles[0] = __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz'; + } + +} diff --git a/core/modules/views/src/Tests/Update/EntityViewsDataUpdateTest.php b/core/modules/views/tests/src/Functional/Update/EntityViewsDataUpdateTest.php similarity index 84% rename from core/modules/views/src/Tests/Update/EntityViewsDataUpdateTest.php rename to core/modules/views/tests/src/Functional/Update/EntityViewsDataUpdateTest.php index 1778043a..2de6568e 100644 --- a/core/modules/views/src/Tests/Update/EntityViewsDataUpdateTest.php +++ b/core/modules/views/tests/src/Functional/Update/EntityViewsDataUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php', ]; } @@ -35,11 +35,11 @@ public function testUpdateHookN() { $view->initHandlers(); // Extract the fields from the test view that were updated. - /** @var \Drupal\views\Plugin\views\field\Field $field */ + /** @var \Drupal\views\Plugin\views\field\EntityField $field */ $created = $view->field['created']; - /** @var \Drupal\views\Plugin\views\field\Field $field */ + /** @var \Drupal\views\Plugin\views\field\EntityField $field */ $created_1 = $view->field['created_1']; - /** @var \Drupal\views\Plugin\views\field\Field $field */ + /** @var \Drupal\views\Plugin\views\field\EntityField $field */ $created_2 = $view->field['created_2']; // Make sure the plugins were converted from date to field. diff --git a/core/modules/views/src/Tests/Update/FieldHandlersUpdateTest.php b/core/modules/views/tests/src/Functional/Update/FieldHandlersUpdateTest.php similarity index 81% rename from core/modules/views/src/Tests/Update/FieldHandlersUpdateTest.php rename to core/modules/views/tests/src/Functional/Update/FieldHandlersUpdateTest.php index 99900945..1af16196 100644 --- a/core/modules/views/src/Tests/Update/FieldHandlersUpdateTest.php +++ b/core/modules/views/tests/src/Functional/Update/FieldHandlersUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/duplicate-field-handler.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/duplicate-field-handler.php', ]; } diff --git a/core/modules/views/src/Tests/Update/ImageStyleDependencyUpdateTest.php b/core/modules/views/tests/src/Functional/Update/ImageStyleDependencyUpdateTest.php similarity index 82% rename from core/modules/views/src/Tests/Update/ImageStyleDependencyUpdateTest.php rename to core/modules/views/tests/src/Functional/Update/ImageStyleDependencyUpdateTest.php index 0afae2d6..e183aded 100644 --- a/core/modules/views/src/Tests/Update/ImageStyleDependencyUpdateTest.php +++ b/core/modules/views/tests/src/Functional/Update/ImageStyleDependencyUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal8.views-image-style-dependency-2649914.php', ]; } diff --git a/core/modules/views/tests/src/Functional/ViewElementTest.php b/core/modules/views/tests/src/Functional/ViewElementTest.php new file mode 100644 index 00000000..2dbc54f6 --- /dev/null +++ b/core/modules/views/tests/src/Functional/ViewElementTest.php @@ -0,0 +1,119 @@ +enableViewsTestModule(); + } + + /** + * Tests the rendered output and form output of a view element. + */ + public function testViewElement() { + $view = Views::getView('test_view_embed'); + $view->setDisplay(); + // Test a form. + $this->drupalGet('views_test_data_element_form'); + + $xpath = $this->xpath('//div[@class="views-element-container js-form-wrapper form-wrapper"]'); + $this->assertTrue($xpath, 'The view container has been found on the form.'); + + $xpath = $this->xpath('//div[@class="view-content"]'); + $this->assertTrue($xpath, 'The view content has been found on the form.'); + // There should be 5 rows in the results. + $xpath = $this->xpath('//div[@class="view-content"]/div'); + $this->assertEqual(count($xpath), 5); + + // Add an argument and save the view. + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'age' => [ + 'default_action' => 'ignore', + 'title' => '', + 'default_argument_type' => 'fixed', + 'validate' => [ + 'type' => 'none', + 'fail' => 'not found', + ], + 'break_phrase' => FALSE, + 'not' => FALSE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'plugin_id' => 'numeric', + ], + ]); + $view->save(); + + // Test that the form has the expected result. + $this->drupalGet('views_test_data_element_form'); + $xpath = $this->xpath('//div[@class="view-content"]/div'); + $this->assertEqual(count($xpath), 1); + } + + /** + * Tests the rendered output and form output of a view element, using the + * embed display plugin. + */ + public function testViewElementEmbed() { + $view = Views::getView('test_view_embed'); + $view->setDisplay(); + // Test a form. + $this->drupalGet('views_test_data_element_embed_form'); + + $xpath = $this->xpath('//div[@class="views-element-container js-form-wrapper form-wrapper"]'); + $this->assertTrue($xpath, 'The view container has been found on the form.'); + + $xpath = $this->xpath('//div[@class="view-content"]'); + $this->assertTrue($xpath, 'The view content has been found on the form.'); + // There should be 5 rows in the results. + $xpath = $this->xpath('//div[@class="view-content"]/div'); + $this->assertEqual(count($xpath), 5); + + // Add an argument and save the view. + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'age' => [ + 'default_action' => 'ignore', + 'title' => '', + 'default_argument_type' => 'fixed', + 'validate' => [ + 'type' => 'none', + 'fail' => 'not found', + ], + 'break_phrase' => FALSE, + 'not' => FALSE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'plugin_id' => 'numeric', + ], + ]); + $view->save(); + + // Test that the form has the same expected result. + $this->drupalGet('views_test_data_element_embed_form'); + $xpath = $this->xpath('//div[@class="view-content"]/div'); + $this->assertEqual(count($xpath), 1); + } + +} diff --git a/core/modules/views/src/Tests/ViewRenderTest.php b/core/modules/views/tests/src/Functional/ViewRenderTest.php similarity index 78% rename from core/modules/views/src/Tests/ViewRenderTest.php rename to core/modules/views/tests/src/Functional/ViewRenderTest.php index 4bde8b27..aaf894cd 100644 --- a/core/modules/views/src/Tests/ViewRenderTest.php +++ b/core/modules/views/tests/src/Functional/ViewRenderTest.php @@ -1,6 +1,6 @@ enableViewsTestModule(); } diff --git a/core/modules/views/tests/src/Functional/ViewTestBase.php b/core/modules/views/tests/src/Functional/ViewTestBase.php new file mode 100644 index 00000000..10bc5d48 --- /dev/null +++ b/core/modules/views/tests/src/Functional/ViewTestBase.php @@ -0,0 +1,160 @@ +set('views_test_data_schema', $this->schemaDefinition()); + \Drupal::state()->set('views_test_data_views_data', $this->viewsData()); + + \Drupal::service('module_installer')->install(['views_test_data']); + $this->resetAll(); + $this->rebuildContainer(); + $this->container->get('module_handler')->reload(); + + // Load the test dataset. + $data_set = $this->dataSet(); + $query = db_insert('views_test_data') + ->fields(array_keys($data_set[0])); + foreach ($data_set as $record) { + $query->values($record); + } + $query->execute(); + } + + /** + * Orders a nested array containing a result set based on a given column. + * + * @param array $result_set + * An array of rows from a result set, with each row as an associative + * array keyed by column name. + * @param string $column + * The column name by which to sort the result set. + * @param bool $reverse + * (optional) Boolean indicating whether to sort the result set in reverse + * order. Defaults to FALSE. + * + * @return array + * The sorted result set. + */ + protected function orderResultSet($result_set, $column, $reverse = FALSE) { + $order = $reverse ? -1 : 1; + usort($result_set, function ($a, $b) use ($column, $order) { + if ($a[$column] == $b[$column]) { + return 0; + } + return $order * (($a[$column] < $b[$column]) ? -1 : 1); + }); + return $result_set; + } + + /** + * Asserts the existence of a button with a certain ID and label. + * + * @param string $id + * The HTML ID of the button + * @param string $expected_label + * The expected label for the button. + * @param string $message + * (optional) A custom message to display with the assertion. If no custom + * message is provided, the message will indicate the button label. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + */ + protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') { + $xpath = $this->assertSession()->buildXPathQuery('//button[@id=:value]|//input[@id=:value]', [':value' => $id]); + $field = $this->getSession()->getPage()->find('xpath', $xpath); + + if (empty($field)) { + throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id', $field); + } + + $this->assertEquals($expected_label, $field->getValue()); + } + + /** + * Executes a view with debugging. + * + * @param \Drupal\views\ViewExecutable $view + * The view object. + * @param array $args + * (optional) An array of the view arguments to use for the view. + */ + protected function executeView(ViewExecutable $view, $args = []) { + // A view does not really work outside of a request scope, due to many + // dependencies like the current user. + $view->setDisplay(); + $view->preExecute($args); + $view->execute(); + $verbose_message = '
              Executed view: ' . ((string) $view->build_info['query']) . '
              '; + if ($view->build_info['query'] instanceof SelectInterface) { + $verbose_message .= '
              Arguments: ' . print_r($view->build_info['query']->getArguments(), TRUE) . '
              '; + } + $this->verbose($verbose_message); + } + + /** + * Returns the schema definition. + * + * @internal + */ + protected function schemaDefinition() { + return ViewTestData::schemaDefinition(); + } + + /** + * Returns the views data definition. + */ + protected function viewsData() { + return ViewTestData::viewsData(); + } + + /** + * Returns a very simple test dataset. + */ + protected function dataSet() { + return ViewTestData::dataSet(); + } + +} diff --git a/core/modules/views/src/Tests/ViewsEscapingTest.php b/core/modules/views/tests/src/Functional/ViewsEscapingTest.php similarity index 83% rename from core/modules/views/src/Tests/ViewsEscapingTest.php rename to core/modules/views/tests/src/Functional/ViewsEscapingTest.php index 34f51480..80a83987 100644 --- a/core/modules/views/src/Tests/ViewsEscapingTest.php +++ b/core/modules/views/tests/src/Functional/ViewsEscapingTest.php @@ -1,6 +1,6 @@ enableViewsTestModule(); } @@ -47,12 +47,12 @@ public function testViewsViewFieldsEscaping() { $this->assertNoEscaped('<'); // Install theme to test with template system. - \Drupal::service('theme_handler')->install(array('views_test_theme')); + \Drupal::service('theme_handler')->install(['views_test_theme']); // Make base theme default then test for hook invocations. $this->config('system.theme') - ->set('default', 'views_test_theme') - ->save(); + ->set('default', 'views_test_theme') + ->save(); $this->assertEqual($this->config('system.theme')->get('default'), 'views_test_theme'); $this->drupalGet('test_page_display_200'); diff --git a/core/modules/views/src/Tests/ViewsFormMultipleTest.php b/core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php similarity index 81% rename from core/modules/views/src/Tests/ViewsFormMultipleTest.php rename to core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php index 844a1b10..03d5bcee 100644 --- a/core/modules/views/src/Tests/ViewsFormMultipleTest.php +++ b/core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php @@ -1,6 +1,6 @@ enableViewsTestModule(); } @@ -51,9 +51,9 @@ public function testViewsFormMultiple() { // Submit the forms, validate argument returned in message set by handler. // @note There is not a way to specify a specific index for a submit button. So // the row index returned is always the last occurrence. - $this->drupalPostForm(NULL, [], t('Test Button'), [], [], 'views-form-test-form-multiple-default-arg2'); + $this->getSession()->getPage()->pressButton('edit-field-form-button-test-4--2'); $this->assertText('The test button at row 4 for test_form_multiple (default) View with args: arg2 was submitted.'); - $this->drupalPostForm(NULL, [], t('Test Button'), [], [], 'views-form-test-form-multiple-default-arg1'); + $this->getSession()->getPage()->pressButton('edit-field-form-button-test-4'); $this->assertText('The test button at row 4 for test_form_multiple (default) View with args: arg1 was submitted.'); } diff --git a/core/modules/views/src/Tests/ViewsTemplateTest.php b/core/modules/views/tests/src/Functional/ViewsTemplateTest.php similarity index 77% rename from core/modules/views/src/Tests/ViewsTemplateTest.php rename to core/modules/views/tests/src/Functional/ViewsTemplateTest.php index 2d7b206d..8f7de401 100644 --- a/core/modules/views/src/Tests/ViewsTemplateTest.php +++ b/core/modules/views/tests/src/Functional/ViewsTemplateTest.php @@ -1,7 +1,8 @@ enableViewsTestModule(); - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); } /** diff --git a/core/modules/views/src/Tests/ViewsThemeIntegrationTest.php b/core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php similarity index 84% rename from core/modules/views/src/Tests/ViewsThemeIntegrationTest.php rename to core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php index e9beb38d..9bdb405b 100644 --- a/core/modules/views/src/Tests/ViewsThemeIntegrationTest.php +++ b/core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php @@ -1,6 +1,6 @@ enableViewsTestModule(); } @@ -45,12 +45,12 @@ protected function setUp() { */ public function testThemedViewPage() { - \Drupal::service('theme_handler')->install(array('test_basetheme', 'test_subtheme')); + \Drupal::service('theme_handler')->install(['test_basetheme', 'test_subtheme']); // Make base theme default then test for hook invocations. $this->config('system.theme') - ->set('default', 'test_basetheme') - ->save(); + ->set('default', 'test_basetheme') + ->save(); $this->assertEqual($this->config('system.theme')->get('default'), 'test_basetheme'); // Make sure a views rendered page is touched. @@ -62,8 +62,8 @@ public function testThemedViewPage() { // Make sub theme default to test for hook invocation // from both sub and base theme. $this->config('system.theme') - ->set('default', 'test_subtheme') - ->save(); + ->set('default', 'test_subtheme') + ->save(); $this->assertEqual($this->config('system.theme')->get('default'), 'test_subtheme'); // Make sure a views rendered page is touched. diff --git a/core/modules/views/src/Tests/Wizard/BasicTest.php b/core/modules/views/tests/src/Functional/Wizard/BasicTest.php similarity index 88% rename from core/modules/views/src/Tests/Wizard/BasicTest.php rename to core/modules/views/tests/src/Functional/Wizard/BasicTest.php index 00237d79..eb2ddbbb 100644 --- a/core/modules/views/src/Tests/Wizard/BasicTest.php +++ b/core/modules/views/tests/src/Functional/Wizard/BasicTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('page_title_block'); } - function testViewsWizardAndListing() { - $this->drupalCreateContentType(array('type' => 'article')); - $this->drupalCreateContentType(array('type' => 'page')); + public function testViewsWizardAndListing() { + $this->drupalCreateContentType(['type' => 'article']); + $this->drupalCreateContentType(['type' => 'page']); // Check if we can access the main views admin page. $this->drupalGet('admin/structure/views'); $this->assertText(t('Add view')); // Create a simple and not at all useful view. - $view1 = array(); + $view1 = []; $view1['label'] = $this->randomMachineName(16); $view1['id'] = strtolower($this->randomMachineName(16)); $view1['description'] = $this->randomMachineName(16); @@ -51,11 +51,11 @@ function testViewsWizardAndListing() { $this->assertNoText($view1['label']); // Create two nodes. - $node1 = $this->drupalCreateNode(array('type' => 'page')); - $node2 = $this->drupalCreateNode(array('type' => 'article')); + $node1 = $this->drupalCreateNode(['type' => 'page']); + $node2 = $this->drupalCreateNode(['type' => 'article']); // Now create a page with simple node listing and an attached feed. - $view2 = array(); + $view2 = []; $view2['label'] = $this->randomMachineName(16); $view2['id'] = strtolower($this->randomMachineName(16)); $view2['description'] = $this->randomMachineName(16); @@ -80,7 +80,9 @@ function testViewsWizardAndListing() { $elements = $this->cssSelect('link[href="' . Url::fromRoute('view.' . $view2['id'] . '.feed_1', [], ['absolute' => TRUE])->toString() . '"]'); $this->assertEqual(count($elements), 1, 'Feed found.'); $this->drupalGet($view2['page[feed_properties][path]']); - $this->assertTrue(!empty($this->cssSelect('rss[version="2.0"]'))); + // Because the response is XML we can't use the page which depends on an + // HTML tag being present. + $this->assertEquals('2.0', $this->getSession()->getDriver()->getAttribute('//rss', 'version')); // The feed should have the same title and nodes as the page. $this->assertText($view2['page[title]']); $this->assertRaw($node1->url('canonical', ['absolute' => TRUE])); @@ -102,7 +104,7 @@ function testViewsWizardAndListing() { $this->assertNoText('View: ' . $view2['label']); // Create a view with a page and a block, and filter the listing. - $view3 = array(); + $view3 = []; $view3['label'] = $this->randomMachineName(16); $view3['id'] = strtolower($this->randomMachineName(16)); $view3['description'] = $this->randomMachineName(16); @@ -134,7 +136,7 @@ function testViewsWizardAndListing() { // Confirm that the block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLinkPartialName('Place block'); + $this->clickLink('Place block'); $this->assertText($view3['label']); // Place the block. @@ -150,7 +152,7 @@ function testViewsWizardAndListing() { $this->assertNoText('tracker', 'Default tracker view does not show on the listing page.'); // Create a view with only a REST export. - $view4 = array(); + $view4 = []; $view4['label'] = $this->randomMachineName(16); $view4['id'] = strtolower($this->randomMachineName(16)); $view4['description'] = $this->randomMachineName(16); @@ -159,12 +161,12 @@ function testViewsWizardAndListing() { $view4['rest_export[create]'] = 1; $view4['rest_export[path]'] = $this->randomMachineName(16); $this->drupalPostForm('admin/structure/views/add', $view4, t('Save and edit')); - $this->assertRaw(t('The view %view has been saved.', array('%view' => $view4['label']))); + $this->assertRaw(t('The view %view has been saved.', ['%view' => $view4['label']])); // Check that the REST export path works. $this->drupalGet($view4['rest_export[path]']); $this->assertResponse(200); - $data = Json::decode($this->content); + $data = Json::decode($this->getSession()->getPage()->getContent()); $this->assertEqual(count($data), 1, 'Only the node of type page is exported.'); $node = reset($data); $this->assertEqual($node['nid'][0]['value'], $node1->id(), 'The node of type page is exported.'); @@ -178,7 +180,7 @@ function testViewsWizardAndListing() { public function testWizardDefaultValues() { $random_id = strtolower($this->randomMachineName(16)); // Create a basic view. - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = $random_id; $view['description'] = $this->randomMachineName(16); @@ -192,8 +194,8 @@ public function testWizardDefaultValues() { $displays = $view->storage->get('display'); foreach ($displays as $display) { - foreach (array('query', 'exposed_form', 'pager', 'style', 'row') as $type) { - $this->assertFalse(empty($display['display_options'][$type]['options']), SafeMarkup::format('Default options found for @plugin.', array('@plugin' => $type))); + foreach (['query', 'exposed_form', 'pager', 'style', 'row'] as $type) { + $this->assertFalse(empty($display['display_options'][$type]['options']), SafeMarkup::format('Default options found for @plugin.', ['@plugin' => $type])); } } } diff --git a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php b/core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php similarity index 78% rename from core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php rename to core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php index 7a2f4302..c480ba94 100644 --- a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php +++ b/core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('page_title_block'); } @@ -19,23 +19,23 @@ protected function setUp() { /** * Tests the number of items per page. */ - function testItemsPerPage() { - $this->drupalCreateContentType(array('type' => 'article')); + public function testItemsPerPage() { + $this->drupalCreateContentType(['type' => 'article']); // Create articles, each with a different creation time so that we can do a // meaningful sort. - $node1 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME)); - $node2 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 1)); - $node3 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 2)); - $node4 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 3)); - $node5 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 4)); + $node1 = $this->drupalCreateNode(['type' => 'article', 'created' => REQUEST_TIME]); + $node2 = $this->drupalCreateNode(['type' => 'article', 'created' => REQUEST_TIME + 1]); + $node3 = $this->drupalCreateNode(['type' => 'article', 'created' => REQUEST_TIME + 2]); + $node4 = $this->drupalCreateNode(['type' => 'article', 'created' => REQUEST_TIME + 3]); + $node5 = $this->drupalCreateNode(['type' => 'article', 'created' => REQUEST_TIME + 4]); // Create a page. This should never appear in the view created below. - $page_node = $this->drupalCreateNode(array('type' => 'page', 'created' => REQUEST_TIME + 2)); + $page_node = $this->drupalCreateNode(['type' => 'page', 'created' => REQUEST_TIME + 2]); // Create a view that sorts newest first, and shows 4 items in the page and // 3 in the block. - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['description'] = $this->randomMachineName(16); @@ -72,7 +72,7 @@ function testItemsPerPage() { // Confirm that the block is listed in the block administration UI. $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLinkPartialName('Place block'); + $this->clickLink('Place block'); $this->assertText($view['label']); // Place the block, visit a page that displays the block, and check that the diff --git a/core/modules/views/src/Tests/Wizard/MenuTest.php b/core/modules/views/tests/src/Functional/Wizard/MenuTest.php similarity index 88% rename from core/modules/views/src/Tests/Wizard/MenuTest.php rename to core/modules/views/tests/src/Functional/Wizard/MenuTest.php index 552ff507..853c0692 100644 --- a/core/modules/views/src/Tests/Wizard/MenuTest.php +++ b/core/modules/views/tests/src/Functional/Wizard/MenuTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('system_menu_block:main'); // Create a view with a page display and a menu link in the Main Menu. - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['description'] = $this->randomMachineName(16); @@ -44,9 +44,9 @@ function testMenus() { /** @var \Drupal\Core\Menu\MenuLinkInterface $link */ $link = $menu_link_manager->createInstance('views_view:views.' . $view['id'] . '.page_1'); $url = $link->getUrlObject(); - $this->assertEqual($url->getRouteName(), 'view.' . $view['id'] . '.page_1', SafeMarkup::format('Found a link to %path in the main menu', array('%path' => $view['page[path]']))); + $this->assertEqual($url->getRouteName(), 'view.' . $view['id'] . '.page_1', SafeMarkup::format('Found a link to %path in the main menu', ['%path' => $view['page[path]']])); $metadata = $link->getMetaData(); - $this->assertEqual(array('view_id' => $view['id'], 'display_id' => 'page_1'), $metadata); + $this->assertEqual(['view_id' => $view['id'], 'display_id' => 'page_1'], $metadata); } } diff --git a/core/modules/views/src/Tests/Wizard/NodeWizardTest.php b/core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php similarity index 92% rename from core/modules/views/src/Tests/Wizard/NodeWizardTest.php rename to core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php index 14a1766e..41870b6d 100644 --- a/core/modules/views/src/Tests/Wizard/NodeWizardTest.php +++ b/core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php @@ -1,7 +1,6 @@ drupalCreateContentType(array('type' => 'article')); + $this->drupalCreateContentType(['type' => 'article']); - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['description'] = $this->randomMachineName(16); diff --git a/core/modules/views/tests/src/Functional/Wizard/PagerTest.php b/core/modules/views/tests/src/Functional/Wizard/PagerTest.php new file mode 100644 index 00000000..c8c697c0 --- /dev/null +++ b/core/modules/views/tests/src/Functional/Wizard/PagerTest.php @@ -0,0 +1,61 @@ +drupalCreateContentType(['type' => 'page']); + for ($i = 0; $i < 12; $i++) { + $this->drupalCreateNode(['created' => REQUEST_TIME - $i]); + } + + // Make a View that uses a pager. + $path_with_pager = 'test-view-with-pager'; + $this->createViewAtPath($path_with_pager, TRUE); + $this->drupalGet($path_with_pager); + + // This technique for finding the existence of a pager + // matches that used in Drupal\views_ui\Tests\PreviewTest.php. + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); + $this->assertTrue(!empty($elements), 'Full pager found.'); + + // Make a View that does not have a pager. + $path_with_no_pager = 'test-view-without-pager'; + $this->createViewAtPath($path_with_no_pager, FALSE); + $this->drupalGet($path_with_no_pager); + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); + $this->assertTrue(empty($elements), 'Full pager not found.'); + } + + /** + * Create a simple View of nodes at a given path. + * + * @param string $path + * The path at which the View should be created. + * @param bool $pager + * A boolean for whether the View created should use a pager. + */ + protected function createViewAtPath($path, $pager = TRUE) { + $view = []; + $view['label'] = $this->randomMachineName(16); + $view['id'] = strtolower($this->randomMachineName(16)); + $view['show[sort]'] = 'node_field_data-created:ASC'; + $view['page[create]'] = 1; + $view['page[title]'] = $this->randomMachineName(16); + $view['page[path]'] = $path; + $view['page[pager]'] = $pager; + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + } + +} diff --git a/core/modules/views/src/Tests/Wizard/SortingTest.php b/core/modules/views/tests/src/Functional/Wizard/SortingTest.php similarity index 85% rename from core/modules/views/src/Tests/Wizard/SortingTest.php rename to core/modules/views/tests/src/Functional/Wizard/SortingTest.php index 61729306..07268e3f 100644 --- a/core/modules/views/src/Tests/Wizard/SortingTest.php +++ b/core/modules/views/tests/src/Functional/Wizard/SortingTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('page_title_block'); } @@ -18,16 +18,16 @@ protected function setUp() { /** * Tests the sorting functionality. */ - function testSorting() { + public function testSorting() { // Create nodes, each with a different creation time so that we can do a // meaningful sort. - $this->drupalCreateContentType(array('type' => 'page')); - $node1 = $this->drupalCreateNode(array('created' => REQUEST_TIME)); - $node2 = $this->drupalCreateNode(array('created' => REQUEST_TIME + 1)); - $node3 = $this->drupalCreateNode(array('created' => REQUEST_TIME + 2)); + $this->drupalCreateContentType(['type' => 'page']); + $node1 = $this->drupalCreateNode(['created' => REQUEST_TIME]); + $node2 = $this->drupalCreateNode(['created' => REQUEST_TIME + 1]); + $node3 = $this->drupalCreateNode(['created' => REQUEST_TIME + 2]); // Create a view that sorts oldest first. - $view1 = array(); + $view1 = []; $view1['label'] = $this->randomMachineName(16); $view1['id'] = strtolower($this->randomMachineName(16)); $view1['description'] = $this->randomMachineName(16); @@ -52,7 +52,7 @@ function testSorting() { $this->assertTrue($pos1 < $pos2 && $pos2 < $pos3, 'The nodes appear in the expected order in a view that sorts by oldest first.'); // Create a view that sorts newest first. - $view2 = array(); + $view2 = []; $view2['label'] = $this->randomMachineName(16); $view2['id'] = strtolower($this->randomMachineName(16)); $view2['description'] = $this->randomMachineName(16); diff --git a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php b/core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php similarity index 90% rename from core/modules/views/src/Tests/Wizard/TaggedWithTest.php rename to core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php index 939473f5..680d6449 100644 --- a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php +++ b/core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php @@ -1,6 +1,6 @@ tagFieldName = 'field_views_testing_tags'; - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->tagVocabulary->id() => $this->tagVocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', $this->nodeTypeWithTags->id(), $this->tagFieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', $this->nodeTypeWithTags->id(), 'default') - ->setComponent($this->tagFieldName, array( + ->setComponent($this->tagFieldName, [ 'type' => 'entity_reference_autocomplete_tags', - )) + ]) ->save(); entity_get_display('node', $this->nodeTypeWithTags->id(), 'default') - ->setComponent($this->tagFieldName, array( + ->setComponent($this->tagFieldName, [ 'type' => 'entity_reference_label', 'weight' => 10, - )) + ]) ->save(); entity_get_display('node', $this->nodeTypeWithTags->id(), 'teaser') - ->setComponent('field_views_testing_tags', array( + ->setComponent('field_views_testing_tags', [ 'type' => 'entity_reference_label', 'weight' => 10, - )) + ]) ->save(); } /** * Tests the "tagged with" functionality. */ - function testTaggedWith() { + public function testTaggedWith() { // In this test we will only create nodes that have an instance of the tag // field. $node_add_path = 'node/add/' . $this->nodeTypeWithTags->id(); // Create three nodes, with different tags. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $node_tag1_title = $this->randomMachineName(); $edit[$this->tagFieldName . '[target_id]'] = 'tag1'; $this->drupalPostForm($node_add_path, $edit, t('Save')); - $edit = array(); + $edit = []; $edit['title[0][value]'] = $node_tag1_tag2_title = $this->randomMachineName(); $edit[$this->tagFieldName . '[target_id]'] = 'tag1, tag2'; $this->drupalPostForm($node_add_path, $edit, t('Save')); - $edit = array(); + $edit = []; $edit['title[0][value]'] = $node_no_tags_title = $this->randomMachineName(); $this->drupalPostForm($node_add_path, $edit, t('Save')); // Create a view that filters by taxonomy term "tag1". It should show only // the two nodes from above that are tagged with "tag1". - $view1 = array(); + $view1 = []; // First select the node type and update the form so the correct tag field // is used. $view1['show[type]'] = $this->nodeTypeWithTags->id(); @@ -158,7 +158,7 @@ function testTaggedWith() { // Create a view that filters by taxonomy term "tag2". It should show only // the one node from above that is tagged with "tag2". - $view2 = array(); + $view2 = []; $view2['show[type]'] = $this->nodeTypeWithTags->id(); $this->drupalPostForm('admin/structure/views/add', $view2, t('Update "of type" choice')); $this->assertResponse(200); @@ -180,7 +180,7 @@ function testTaggedWith() { /** * Tests that the "tagged with" form element only shows for node types that support it. */ - function testTaggedWithByNodeType() { + public function testTaggedWithByNodeType() { // The tagging field is associated with one of our node types only. So the // "tagged with" form element on the view wizard should appear on the form // by default (when the wizard is configured to display all content) and @@ -202,20 +202,20 @@ function testTaggedWithByNodeType() { 'field_name' => $this->tagFieldName, 'entity_type' => 'node', 'bundle' => $this->nodeTypeWithoutTags->id(), - 'settings' => array( + 'settings' => [ 'handler' => 'default', - 'handler_settings' => array( - 'target_bundles' => array( + 'handler_settings' => [ + 'target_bundles' => [ $this->tagVocabulary->id() => $this->tagVocabulary->id(), - ), + ], 'auto_create' => TRUE, - ), - ), + ], + ], ])->save(); entity_get_form_display('node', $this->nodeTypeWithoutTags->id(), 'default') - ->setComponent($this->tagFieldName, array( + ->setComponent($this->tagFieldName, [ 'type' => 'entity_reference_autocomplete_tags', - )) + ]) ->save(); $view['show[type]'] = $this->nodeTypeWithTags->id(); diff --git a/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php b/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php new file mode 100644 index 00000000..0178c08c --- /dev/null +++ b/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php @@ -0,0 +1,28 @@ +drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions']); + $this->drupalLogin($views_admin); + $this->drupalPlaceBlock('local_actions_block'); + } + +} diff --git a/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php b/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php index 42da7b65..3611829e 100644 --- a/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php +++ b/core/modules/views/tests/src/FunctionalJavascript/GlossaryViewTest.php @@ -42,7 +42,7 @@ class GlossaryViewTest extends JavascriptTestBase { protected function setUp() { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); // Create a Content type and some test nodes with titles that start with // different letters. diff --git a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php index 8cca9c36..dd1d1ae2 100644 --- a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/ContextualFilterTest.php @@ -24,7 +24,6 @@ class ContextualFilterTest extends JavascriptTestBase { */ public static $testViews = ['test_field_body']; - /** * {@inheritdoc} */ @@ -33,9 +32,14 @@ protected function setUp() { ViewTestData::createTestViews(get_class($this), ['views_test_config']); - // Disable automatic live preview to make the sequence of calls clearer. + // Always show advanced column. \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.advanced_column', TRUE)->save(); + // Disable automatic live preview to make the sequence of calls clearer. And + // prevent errors on saving the view with the preview ajax load that are + // cancelled. + \Drupal::configFactory()->getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save(); + $account = $this->drupalCreateUser(['administer views']); $this->drupalLogin($account); } @@ -44,32 +48,40 @@ protected function setUp() { * Test adding a contextual filter handler through the UI. */ public function testAddContextualFilterUI() { - $web_assert = $this->assertSession(); - $this->drupalGet('/admin/structure/views/view/test_field_body'); - $web_assert->assertWaitOnAjaxRequest(); + $web_assert = $this->assertSession(); $page = $this->getSession()->getPage(); $page->clickLink('views-add-argument'); - $web_assert->assertWaitOnAjaxRequest(); - $page->checkField('name[node_field_data.nid]'); + $field = $web_assert->waitForField('name[node_field_data.nid]'); + $this->assertNotEmpty($field); + $field->check(); + $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary'); $add_button->click(); - $web_assert->assertWaitOnAjaxRequest(); - $page->fillField('options[default_action]', 'default'); + $field_action = $web_assert->waitForField('options[default_action]'); + $this->assertNotEmpty($field_action); + $field_action->setValue('default'); + $page->selectFieldOption('options[default_argument_type]', 'node'); $add_button = $page->find('css', '.ui-dialog-buttonset .button--primary'); $add_button->click(); - $web_assert->assertWaitOnAjaxRequest(); + + // Wait for the dialog to close. + $page->waitFor(10, function () use ($page) { + $field = $page->find('css', '.ui-dialog-buttonset .button--primary'); + return empty($field); + }); + $page->pressButton('edit-actions-submit'); - $web_assert->assertWaitOnAjaxRequest(); + $page->clickLink('Content: ID'); // Check that the dialog opens. - $web_assert->assertWaitOnAjaxRequest(); - $page->pressButton('Close'); + $field_action = $web_assert->waitForField('options[default_action]'); + $this->assertNotEmpty($field_action); } } diff --git a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php index 6676daf1..76f0ff1e 100644 --- a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/FieldTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\field\Entity\FieldConfig; use Drupal\FunctionalJavascriptTests\JavascriptTestBase; use Drupal\node\Entity\NodeType; diff --git a/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/GroupedExposedFilterTest.php b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/GroupedExposedFilterTest.php new file mode 100644 index 00000000..9a9b2da4 --- /dev/null +++ b/core/modules/views/tests/src/FunctionalJavascript/Plugin/views/Handler/GroupedExposedFilterTest.php @@ -0,0 +1,105 @@ +getEditable('views.settings')->set('ui.always_live_preview', FALSE)->save(); + + $this->account = $this->drupalCreateUser(['administer views']); + $this->drupalLogin($this->account); + + // Setup a node type that has the right fields for the test view. + NodeType::create([ + 'type' => 'page', + ])->save(); + + FieldConfig::create([ + 'entity_type' => 'node', + 'field_name' => 'body', + 'bundle' => 'page', + ])->save(); + } + + /** + * Test if the right fields are shown and the right values set. + */ + public function testGroupedFilterValuesUI() { + $web_assert = $this->assertSession(); + + $this->drupalGet('/admin/structure/views/view/test_exposed_admin_ui'); + $page = $this->getSession()->getPage(); + + // Open the dialog for the grouped filter. + $page->clickLink('Content: Authored on (grouped)'); + $web_assert->assertWaitOnAjaxRequest(); + + // Test that the 'min' field is shown and that it contains the right value. + $between_from = $page->findField('options[group_info][group_items][1][value][min]'); + $this->assertNotEmpty($between_from->isVisible()); + $this->assertEquals('2015-01-01', $between_from->getValue()); + + // Test that the 'max' field is shown and that it contains the right value. + $between_to = $page->findField('options[group_info][group_items][1][value][max]'); + $this->assertNotEmpty($between_to->isVisible()); + $this->assertEquals('2016-01-01', $between_to->getValue()); + + $weight = $page->findField('options[group_info][group_items][1][weight]'); + + // If there are 3 items, values from -3 to 3 should be available. + $this->assertFalse($weight->find('named', ['option', -4])); + foreach (range(-3, 3) as $value) { + $this->assertTrue($weight->find('named', ['option', $value])); + } + $this->assertFalse($weight->find('named', ['option', 4])); + + $page->pressButton("Add another item"); + $web_assert->waitForField('options[group_info][group_items][4][title]'); + + // A new items was added, weight options should now be -4 to 4. + $this->assertFalse($weight->find('named', ['option', -5])); + foreach (range(-4, 4) as $value) { + $this->assertTrue($weight->find('named', ['option', $value])); + } + $this->assertFalse($weight->find('named', ['option', 5])); + } + +} diff --git a/core/modules/views/tests/src/Kernel/BasicTest.php b/core/modules/views/tests/src/Kernel/BasicTest.php index 49f4398b..4ef22b14 100644 --- a/core/modules/views/tests/src/Kernel/BasicTest.php +++ b/core/modules/views/tests/src/Kernel/BasicTest.php @@ -16,7 +16,7 @@ class BasicTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view', 'test_simple_argument'); + public static $testViews = ['test_view', 'test_simple_argument']; /** * Tests a trivial result set. @@ -30,10 +30,10 @@ public function testSimpleResultSet() { // Verify the result. $this->assertEqual(5, count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->dataSet(), array( + $this->assertIdenticalResultset($view, $this->dataSet(), [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); } /** @@ -44,55 +44,55 @@ public function testSimpleFiltering() { $view->setDisplay(); // Add a filter. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'operator' => '<', - 'value' => array( + 'value' => [ 'value' => '28', 'min' => '', 'max' => '', - ), + ], 'group' => '0', 'exposed' => FALSE, - 'expose' => array( + 'expose' => [ 'operator' => FALSE, 'label' => '', - ), + ], 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', - ), - )); + ], + ]); // Execute the view. $this->executeView($view); // Build the expected result. - $dataset = array( - array( + $dataset = [ + [ 'id' => 1, 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'id' => 2, 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'id' => 4, 'name' => 'Paul', 'age' => 26, - ), - ); + ], + ]; // Verify the result. $this->assertEqual(3, count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultSet($view, $dataset, array( + $this->assertIdenticalResultSet($view, $dataset, [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); } /** @@ -101,24 +101,24 @@ public function testSimpleFiltering() { public function testSimpleArgument() { // Execute with a view $view = Views::getView('test_simple_argument'); - $view->setArguments(array(27)); + $view->setArguments([27]); $this->executeView($view); // Build the expected result. - $dataset = array( - array( + $dataset = [ + [ 'id' => 2, 'name' => 'George', 'age' => 27, - ), - ); + ], + ]; // Verify the result. $this->assertEqual(1, count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultSet($view, $dataset, array( + $this->assertIdenticalResultSet($view, $dataset, [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); // Test "show all" if no argument is present. $view = Views::getView('test_simple_argument'); @@ -128,10 +128,10 @@ public function testSimpleArgument() { $dataset = $this->dataSet(); $this->assertEqual(5, count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultSet($view, $dataset, array( + $this->assertIdenticalResultSet($view, $dataset, [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); } } diff --git a/core/modules/views/tests/src/Kernel/Entity/RowEntityRenderersTest.php b/core/modules/views/tests/src/Kernel/Entity/RowEntityRenderersTest.php index dfcb30e2..a110f002 100644 --- a/core/modules/views/tests/src/Kernel/Entity/RowEntityRenderersTest.php +++ b/core/modules/views/tests/src/Kernel/Entity/RowEntityRenderersTest.php @@ -5,6 +5,7 @@ use Drupal\language\Entity\ConfigurableLanguage; use Drupal\node\Entity\NodeType; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; +use Drupal\user\Entity\User; use Drupal\views\Views; /** @@ -27,7 +28,10 @@ class RowEntityRenderersTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_entity_row_renderers'); + public static $testViews = [ + 'test_entity_row_renderers', + 'test_entity_row_renderers_revisions_base', + ]; /** * An array of added languages. @@ -43,6 +47,20 @@ class RowEntityRenderersTest extends ViewsKernelTestBase { */ protected $expected; + /** + * The author of the test content. + * + * @var \Drupal\user\UserInterface + */ + protected $testAuthor; + + /** + * An array of IDs of the test content. + * + * @var array[] + */ + protected $testIds; + /** * {@inheritdoc} */ @@ -51,47 +69,58 @@ protected function setUp($import_test_views = TRUE) { $this->installEntitySchema('node'); $this->installEntitySchema('user'); - $this->installSchema('node', array('node_access')); - $this->installConfig(array('node', 'language')); + $this->installSchema('node', ['node_access']); + $this->installConfig(['node', 'language']); // The entity.node.canonical route must exist when nodes are rendered. $this->container->get('router.builder')->rebuild(); - $this->langcodes = array(\Drupal::languageManager()->getDefaultLanguage()->getId()); + $this->langcodes = [\Drupal::languageManager()->getDefaultLanguage()->getId()]; for ($i = 0; $i < 2; $i++) { $langcode = 'l' . $i; $this->langcodes[] = $langcode; ConfigurableLanguage::createFromLangcode($langcode)->save(); } + $this->testAuthor = User::create([ + 'name' => 'foo', + ]); + $this->testAuthor->save(); + // Make sure we do not try to render non-existing user data. - $node_type = NodeType::create(array('type' => 'test')); + $node_type = NodeType::create(['type' => 'test']); $node_type->setDisplaySubmitted(FALSE); $node_type->save(); - $this->values = array(); + $this->values = []; + $this->ids = []; $controller = \Drupal::entityManager()->getStorage('node'); $langcode_index = 0; for ($i = 0; $i < count($this->langcodes); $i++) { // Create a node with a different default language each time. $default_langcode = $this->langcodes[$langcode_index++]; - $node = $controller->create(array('type' => 'test', 'uid' => 0, 'langcode' => $default_langcode)); + $node = $controller->create(['type' => 'test', 'uid' => $this->testAuthor->id(), 'langcode' => $default_langcode]); // Ensure the default language is processed first. - $langcodes = array_merge(array($default_langcode), array_diff($this->langcodes, array($default_langcode))); + $langcodes = array_merge([$default_langcode], array_diff($this->langcodes, [$default_langcode])); foreach ($langcodes as $langcode) { // Ensure we have a predictable result order. $this->values[$i][$langcode] = $i . '-' . $langcode . '-' . $this->randomMachineName(); if ($langcode != $default_langcode) { - $node->addTranslation($langcode, array('title' => $this->values[$i][$langcode])); + $node->addTranslation($langcode, ['title' => $this->values[$i][$langcode]]); } else { $node->setTitle($this->values[$i][$langcode]); } $node->save(); + + $this->ids[] = [ + 'nid' => $node->id(), + 'uid' => $this->testAuthor->id(), + ]; } } } @@ -110,6 +139,15 @@ public function testFieldRenderers() { $this->checkLanguageRenderers('page_2', $this->values); } + /** + * Tests the row renderer with a revision base table. + */ + public function testRevisionBaseTable() { + $view = Views::getView('test_entity_row_renderers_revisions_base'); + $view->execute(); + $this->assertIdenticalResultset($view, $this->ids, ['nid' => 'nid', 'uid' => 'uid']); + } + /** * Checks that the language renderer configurations work as expected. * @@ -121,7 +159,7 @@ public function testFieldRenderers() { * node. */ protected function checkLanguageRenderers($display, $values) { - $expected = array( + $expected = [ $values[0]['en'], $values[0]['en'], $values[0]['en'], @@ -131,10 +169,10 @@ protected function checkLanguageRenderers($display, $values) { $values[2]['en'], $values[2]['en'], $values[2]['en'], - ); + ]; $this->assertTranslations($display, '***LANGUAGE_language_content***', $expected, 'The current language renderer behaves as expected.'); - $expected = array( + $expected = [ $values[0]['en'], $values[0]['en'], $values[0]['en'], @@ -144,10 +182,10 @@ protected function checkLanguageRenderers($display, $values) { $values[2]['l1'], $values[2]['l1'], $values[2]['l1'], - ); + ]; $this->assertTranslations($display, '***LANGUAGE_entity_default***', $expected, 'The default language renderer behaves as expected.'); - $expected = array( + $expected = [ $values[0]['en'], $values[0]['l0'], $values[0]['l1'], @@ -157,10 +195,10 @@ protected function checkLanguageRenderers($display, $values) { $values[2]['en'], $values[2]['l0'], $values[2]['l1'], - ); + ]; $this->assertTranslations($display, '***LANGUAGE_entity_translation***', $expected, 'The translation language renderer behaves as expected.'); - $expected = array( + $expected = [ $values[0][$this->langcodes[0]], $values[0][$this->langcodes[0]], $values[0][$this->langcodes[0]], @@ -170,10 +208,10 @@ protected function checkLanguageRenderers($display, $values) { $values[2][$this->langcodes[0]], $values[2][$this->langcodes[0]], $values[2][$this->langcodes[0]], - ); + ]; $this->assertTranslations($display, '***LANGUAGE_site_default***', $expected, 'The site default language renderer behaves as expected.'); - $expected = array( + $expected = [ $values[0]['l0'], $values[0]['l0'], $values[0]['l0'], @@ -183,7 +221,7 @@ protected function checkLanguageRenderers($display, $values) { $values[2]['l0'], $values[2]['l0'], $values[2]['l0'], - ); + ]; $this->assertTranslations($display, 'l0', $expected, 'The language specific renderer behaves as expected.'); } diff --git a/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php b/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php index f97659a7..4929c7ec 100644 --- a/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php +++ b/core/modules/views/tests/src/Kernel/Entity/ViewEntityDependenciesTest.php @@ -40,14 +40,14 @@ protected function setUp($import_test_views = TRUE) { // Install the necessary dependencies for node type creation to work. $this->installEntitySchema('node'); - $this->installConfig(array('field', 'node')); + $this->installConfig(['field', 'node']); - $comment_type = CommentType::create(array( + $comment_type = CommentType::create([ 'id' => 'comment', 'label' => 'Comment settings', 'description' => 'Comment settings', 'target_entity_type_id' => 'node', - )); + ]); $comment_type->save(); $content_type = NodeType::create([ @@ -55,29 +55,29 @@ protected function setUp($import_test_views = TRUE) { 'name' => $this->randomString(), ]); $content_type->save(); - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => Unicode::strtolower($this->randomMachineName()), 'entity_type' => 'node', 'type' => 'comment', - )); + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => $content_type->id(), 'label' => $this->randomMachineName() . '_label', 'description' => $this->randomMachineName() . '_description', - 'settings' => array( + 'settings' => [ 'comment_type' => $comment_type->id(), - ), + ], ])->save(); FieldConfig::create([ 'field_storage' => FieldStorageConfig::loadByName('node', 'body'), 'bundle' => $content_type->id(), 'label' => $this->randomMachineName() . '_body', - 'settings' => array('display_summary' => TRUE), + 'settings' => ['display_summary' => TRUE], ])->save(); - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); } /** diff --git a/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php b/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php index 3c46c9ed..2319a706 100644 --- a/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php +++ b/core/modules/views/tests/src/Kernel/EventSubscriber/ViewsEntitySchemaSubscriberIntegrationTest.php @@ -26,7 +26,7 @@ class ViewsEntitySchemaSubscriberIntegrationTest extends ViewsKernelTestBase { /** * {@inheritdoc} */ - public static $modules = ['entity_test', 'user', 'text']; + public static $modules = ['entity_test', 'entity_test_update', 'user', 'text']; /** * Views used by this test. @@ -79,7 +79,7 @@ protected function setUp($import_test_views = TRUE) { // Install every entity type's schema that wasn't installed in the parent // method. - foreach (array_diff_key($this->entityManager->getDefinitions(), array_flip(array('user', 'entity_test'))) as $entity_type_id => $entity_type) { + foreach (array_diff_key($this->entityManager->getDefinitions(), array_flip(['user', 'entity_test'])) as $entity_type_id => $entity_type) { $this->installEntitySchema($entity_type_id); } } @@ -90,6 +90,10 @@ protected function setUp($import_test_views = TRUE) { public function testDeleteEntityType() { $entity_storage = $this->entityManager->getStorage('view'); + // Make the test entity type revisionable. + $this->updateEntityTypeToRevisionable(); + $this->entityDefinitionUpdateManager->applyUpdates(); + $views = $entity_storage->loadMultiple(); // Ensure that all test views exists. diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php new file mode 100644 index 00000000..0f209cac --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php @@ -0,0 +1,94 @@ +installEntitySchema('node'); + } + + /** + * {@inheritdoc} + */ + protected function viewsData() { + $data = parent::viewsData(); + $data['views']['test_example'] = [ + 'title' => 'Test Example area', + 'help' => 'A area handler which just exists for tests.', + 'area' => [ + 'id' => 'test_example' + ] + ]; + + return $data; + } + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = ['test_example_area']; + + /** + * Tests that the header and footer areas are not rendered if empty. + */ + public function testRenderEmptyHeaderFooter() { + $view = Views::getView('test_example_area'); + $view->initHandlers(); + + // Set example empty text. + $empty_text = $this->randomMachineName(); + $empty_header = $this->randomMachineName(); + $empty_footer = $this->randomMachineName(); + + // Set empty text. + $view->empty['test_example']->options['string'] = '

              ' . $empty_text . '

              '; + // Set example header text. + $view->header['test_example']->options['string'] = '

              ' . $empty_header . '

              '; + // Set example footer text. + $view->footer['test_example']->options['string'] = '

              ' . $empty_footer . '

              '; + + // Verify that the empty header and footer sections have not been rendered. + $view->setDisplay('default'); + $this->executeView($view); + $output = $view->render(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->setRawContent($output); + $this->assertText($empty_text); + $this->assertNoText($empty_header); + $this->assertNoText($empty_footer); + + // Enable displaying the header and footer when the View is empty. + $view->header['test_example']->options['empty'] = TRUE; + $view->footer['test_example']->options['empty'] = TRUE; + + // Verify that the header and footer sections have been rendered. + $this->executeView($view); + $output = $view->render(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->setRawContent($output); + $this->assertText($empty_header); + $this->assertText($empty_footer); + } + +} diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php index af3d6583..a95214a7 100644 --- a/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/AreaEntityTest.php @@ -2,9 +2,9 @@ namespace Drupal\Tests\views\Kernel\Handler; -use Drupal\block\Entity\Block; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormState; +use Drupal\simpletest\BlockCreationTrait; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; use Drupal\views\Entity\View; use Drupal\views\Views; @@ -17,6 +17,8 @@ */ class AreaEntityTest extends ViewsKernelTestBase { + use BlockCreationTrait; + /** * Modules to enable. * @@ -29,7 +31,7 @@ class AreaEntityTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_entity_area'); + public static $testViews = ['test_entity_area']; /** * {@inheritdoc} @@ -42,14 +44,15 @@ protected function setUp($import_test_views = TRUE) { * {@inheritdoc} */ protected function setUpFixtures() { + // Install the themes used for this test. + $this->container->get('theme_installer')->install(['bartik']); + $this->container->get('config.factory')->getEditable('system.theme')->set('default', 'bartik')->save(); + $this->installEntitySchema('user'); $this->installEntitySchema('entity_test'); $this->installConfig(['entity_test']); - Block::create([ - 'id' => 'test_block', - 'plugin' => 'system_main_block', - ])->save(); + $this->placeBlock('system_main_block', ['id' => 'test_block']); parent::setUpFixtures(); } @@ -67,9 +70,9 @@ public function testEntityAreaData() { // Test that all expected entity types have data. foreach (array_keys($expected_entities) as $entity) { - $this->assertTrue(!empty($data['entity_' . $entity]), format_string('Views entity area data found for @entity', array('@entity' => $entity))); + $this->assertTrue(!empty($data['entity_' . $entity]), format_string('Views entity area data found for @entity', ['@entity' => $entity])); // Test that entity_type is set correctly in the area data. - $this->assertEqual($entity, $data['entity_' . $entity]['area']['entity_type'], format_string('Correct entity_type set for @entity', array('@entity' => $entity))); + $this->assertEqual($entity, $data['entity_' . $entity]['area']['entity_type'], format_string('Correct entity_type set for @entity', ['@entity' => $entity])); } $expected_entities = array_filter($entity_types, function (EntityTypeInterface $type) { @@ -78,7 +81,7 @@ public function testEntityAreaData() { // Test that no configuration entity types have data. foreach (array_keys($expected_entities) as $entity) { - $this->assertTrue(empty($data['entity_' . $entity]), format_string('Views config entity area data not found for @entity', array('@entity' => $entity))); + $this->assertTrue(empty($data['entity_' . $entity]), format_string('Views config entity area data not found for @entity', ['@entity' => $entity])); } } @@ -87,10 +90,10 @@ public function testEntityAreaData() { */ public function testEntityArea() { /** @var \Drupal\Core\Entity\EntityInterface[] $entities */ - $entities = array(); + $entities = []; for ($i = 0; $i < 3; $i++) { $random_label = $this->randomMachineName(); - $data = array('bundle' => 'entity_test', 'name' => $random_label); + $data = ['bundle' => 'entity_test', 'name' => $random_label]; $entity_test = $this->container->get('entity.manager') ->getStorage('entity_test') ->create($data); @@ -134,7 +137,7 @@ public function doTestRender($entities) { $this->assertTrue(strpos(trim((string) $result[0]), $entities[1]->label()) !== FALSE, 'The rendered entity appears in the footer of the view.'); $this->assertTrue(strpos(trim((string) $result[0]), 'full') !== FALSE, 'The rendered entity appeared in the right view mode.'); - $preview = $view->preview('default', array($entities[1]->id())); + $preview = $view->preview('default', [$entities[1]->id()]); $this->setRawContent($renderer->renderRoot($preview)); $result = $this->xpath($header_xpath); @@ -156,7 +159,7 @@ public function doTestRender($entities) { $item['view_mode'] = 'test'; $view->setHandler('default', 'header', 'entity_entity_test', $item); - $preview = $view->preview('default', array($entities[1]->id())); + $preview = $view->preview('default', [$entities[1]->id()]); $this->setRawContent($renderer->renderRoot($preview)); $view_class = 'js-view-dom-id-' . $view->dom_id; $result = $this->xpath('//div[@class = "' . $view_class . '"]/header[1]'); @@ -165,14 +168,14 @@ public function doTestRender($entities) { // Test entity access. $view = Views::getView('test_entity_area'); - $preview = $view->preview('default', array($entities[2]->id())); + $preview = $view->preview('default', [$entities[2]->id()]); $this->setRawContent($renderer->renderRoot($preview)); $view_class = 'js-view-dom-id-' . $view->dom_id; $result = $this->xpath('//div[@class = "' . $view_class . '"]/footer[1]'); $this->assertTrue(strpos($result[0], $entities[2]->label()) === FALSE, 'The rendered entity does not appear in the footer of the view.'); // Test the available view mode options. - $form = array(); + $form = []; $form_state = (new FormState()) ->set('type', 'header'); $view->display_handler->getHandler('header', 'entity_entity_test')->buildOptionsForm($form, $form_state); diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaMessagesTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaMessagesTest.php index 7e1fbb91..476551c9 100644 --- a/core/modules/views/tests/src/Kernel/Handler/AreaMessagesTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/AreaMessagesTest.php @@ -18,7 +18,7 @@ class AreaMessagesTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_area_messages'); + public static $testViews = ['test_area_messages']; /** * Tests the messages area handler. diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaOrderTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaOrderTest.php index 457c6357..84a66ab5 100644 --- a/core/modules/views/tests/src/Kernel/Handler/AreaOrderTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/AreaOrderTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\views\Kernel\Handler; -use Drupal\block\Entity\Block; +use Drupal\simpletest\BlockCreationTrait; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; use Drupal\views\Views; @@ -14,41 +14,41 @@ */ class AreaOrderTest extends ViewsKernelTestBase { + use BlockCreationTrait; + /** * Modules to enable. * * @var array */ - public static $modules = array('user', 'block'); + public static $modules = ['user', 'block']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_area_order'); + public static $testViews = ['test_area_order']; /** * {@inheritdoc} */ protected function setUpFixtures() { - Block::create( - [ - 'id' => 'bartik_branding', - 'theme' => 'bartik', - 'plugin' => 'system_branding_block', - 'weight' => 1, - ] - )->save(); + // Install the themes used for this test. + $this->container->get('theme_installer')->install(['bartik']); + + $this->placeBlock('system_branding_block', [ + 'id' => 'bartik_branding', + 'theme' => 'bartik', + 'plugin' => 'system_branding_block', + 'weight' => 1, + ]); - Block::create( - [ - 'id' => 'bartik_powered', - 'theme' => 'bartik', - 'plugin' => 'system_powered_by_block', - 'weight' => 2, - ] - )->save(); + $this->placeBlock('system_powered_by_block', [ + 'id' => 'bartik_powered', + 'theme' => 'bartik', + 'weight' => 2, + ]); parent::setUpFixtures(); } diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaResultTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaResultTest.php new file mode 100644 index 00000000..8b67fec6 --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/AreaResultTest.php @@ -0,0 +1,72 @@ +setDisplay('default'); + $this->executeView($view); + $output = $view->render(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->setRawContent($output); + $this->assertText('start: 1 | end: 5 | total: 5 | label: test_area_result | per page: 0 | current page: 1 | current record count: 5 | page count: 1'); + } + + /** + * Tests the results area handler. + */ + public function testResultEmpty() { + $view = Views::getView('test_area_result'); + + // Test that the area is displayed if we have checked the empty checkbox. + $view->setDisplay('default'); + + // Add a filter that will make the result set empty. + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ + 'id' => 'name', + 'table' => 'views_test_data', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => '=', + 'value' => 'non-existing-name', + ], + ]); + + $this->executeView($view); + $output = $view->render(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->setRawContent($output); + $this->assertText('start: 0 | end: 0 | total: 0 | label: test_area_result | per page: 0 | current page: 1 | current record count: 0 | page count: 1'); + + // Test that the area is not displayed if we have not checked the empty + // checkbox. + $view->setDisplay('page_1'); + + $this->executeView($view); + $output = $view->render(); + $output = \Drupal::service('renderer')->renderRoot($output); + $this->setRawContent($output); + $this->assertNoText('start: 0 | end: 0 | total: 0 | label: test_area_result | per page: 0 | current page: 1 | current record count: 0 | page count: 1'); + } + +} diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php index 5ccacd87..2feaaf14 100644 --- a/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php @@ -13,19 +13,19 @@ */ class AreaTextTest extends ViewsKernelTestBase { - public static $modules = array('system', 'user', 'filter'); + public static $modules = ['system', 'user', 'filter']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; protected function setUp($import_test_views = TRUE) { parent::setUp(); - $this->installConfig(array('system', 'filter')); + $this->installConfig(['system', 'filter']); $this->installEntitySchema('user'); } @@ -37,16 +37,16 @@ public function testAreaText() { // add a text header $string = $this->randomMachineName(); - $view->displayHandlers->get('default')->overrideOption('header', array( - 'area' => array( + $view->displayHandlers->get('default')->overrideOption('header', [ + 'area' => [ 'id' => 'area', 'table' => 'views', 'field' => 'area', - 'content' => array( + 'content' => [ 'value' => $string, - ), - ), - )); + ], + ], + ]); // Execute the view. $this->executeView($view); @@ -60,7 +60,7 @@ public function testAreaText() { $this->assertEqual(check_markup($string), $renderer->renderRoot($build), 'Existent format should return something'); // Empty results, and it shouldn't be displayed . - $this->assertEqual(array(), $view->display_handler->handlers['header']['area']->render(TRUE), 'No result should lead to no header'); + $this->assertEqual([], $view->display_handler->handlers['header']['area']->render(TRUE), 'No result should lead to no header'); // Empty results, and it should be displayed. $view->display_handler->handlers['header']['area']->options['empty'] = TRUE; $build = $view->display_handler->handlers['header']['area']->render(TRUE); diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaTitleTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaTitleTest.php index f2a4151e..8c16b630 100644 --- a/core/modules/views/tests/src/Kernel/Handler/AreaTitleTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/AreaTitleTest.php @@ -18,7 +18,7 @@ class AreaTitleTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_area_title'); + public static $testViews = ['test_area_title']; /** * Tests the title area handler. @@ -34,7 +34,7 @@ public function testTitleText() { $view->setDisplay('default'); $this->executeView($view); - $view->result = array(); + $view->result = []; $view->render(); $this->assertEqual($view->getTitle(), 'test_title_empty', 'The title area should override the title if the result is empty.'); $view->destroy(); @@ -47,7 +47,7 @@ public function testTitleText() { $view->setDisplay('page_1'); $this->executeView($view); - $view->result = array(); + $view->result = []; $view->render(); $this->assertEqual($view->getTitle(), 'test_title_empty', 'The title area should override the title if the result is empty.'); $view->destroy(); diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaViewTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaViewTest.php index 89fe49e9..6eaba132 100644 --- a/core/modules/views/tests/src/Kernel/Handler/AreaViewTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/AreaViewTest.php @@ -18,14 +18,14 @@ class AreaViewTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('user'); + public static $modules = ['user']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_simple_argument', 'test_area_view'); + public static $testViews = ['test_simple_argument', 'test_area_view']; /** * Tests the view area handler. @@ -44,7 +44,7 @@ public function testViewArea() { $this->assertTrue(strpos($output, 'js-view-dom-id-' . $view->dom_id) !== FALSE, 'The test view is correctly embedded.'); $view->destroy(); - $view->setArguments(array(27)); + $view->setArguments([27]); $this->executeView($view); $output = $view->render(); $output = $renderer->renderRoot($output); diff --git a/core/modules/views/tests/src/Kernel/Handler/ArgumentDateTest.php b/core/modules/views/tests/src/Kernel/Handler/ArgumentDateTest.php index 527bd724..db26e11a 100644 --- a/core/modules/views/tests/src/Kernel/Handler/ArgumentDateTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/ArgumentDateTest.php @@ -18,16 +18,16 @@ class ArgumentDateTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_argument_date'); + public static $testViews = ['test_argument_date']; /** * Stores the column map for this testCase. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'id' => 'id', - ); + ]; /** * {@inheritdoc} @@ -35,14 +35,14 @@ class ArgumentDateTest extends ViewsKernelTestBase { public function viewsData() { $data = parent::viewsData(); - $date_plugins = array( + $date_plugins = [ 'date_fulldate', 'date_day', 'date_month', 'date_week', 'date_year', 'date_year_month', - ); + ]; foreach ($date_plugins as $plugin_id) { $data['views_test_data'][$plugin_id] = $data['views_test_data']['created']; $data['views_test_data'][$plugin_id]['real field'] = 'created'; @@ -59,25 +59,25 @@ public function viewsData() { public function testCreatedFullDateHandler() { $view = Views::getView('test_argument_date'); $view->setDisplay('default'); - $this->executeView($view, array('20000102')); - $expected = array(); - $expected[] = array('id' => 2); + $this->executeView($view, ['20000102']); + $expected = []; + $expected[] = ['id' => 2]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('default'); - $this->executeView($view, array('20000101')); - $expected = array(); - $expected[] = array('id' => 1); - $expected[] = array('id' => 3); - $expected[] = array('id' => 4); - $expected[] = array('id' => 5); + $this->executeView($view, ['20000101']); + $expected = []; + $expected[] = ['id' => 1]; + $expected[] = ['id' => 3]; + $expected[] = ['id' => 4]; + $expected[] = ['id' => 5]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('default'); - $this->executeView($view, array('20001023')); - $expected = array(); + $this->executeView($view, ['20001023']); + $expected = []; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); } @@ -90,25 +90,25 @@ public function testCreatedFullDateHandler() { public function testDayHandler() { $view = Views::getView('test_argument_date'); $view->setDisplay('embed_1'); - $this->executeView($view, array('02')); - $expected = array(); - $expected[] = array('id' => 2); + $this->executeView($view, ['02']); + $expected = []; + $expected[] = ['id' => 2]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_1'); - $this->executeView($view, array('01')); - $expected = array(); - $expected[] = array('id' => 1); - $expected[] = array('id' => 3); - $expected[] = array('id' => 4); - $expected[] = array('id' => 5); + $this->executeView($view, ['01']); + $expected = []; + $expected[] = ['id' => 1]; + $expected[] = ['id' => 3]; + $expected[] = ['id' => 4]; + $expected[] = ['id' => 5]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_1'); - $this->executeView($view, array('23')); - $expected = array(); + $this->executeView($view, ['23']); + $expected = []; $this->assertIdenticalResultset($view, $expected, $this->columnMap); } @@ -120,19 +120,19 @@ public function testDayHandler() { public function testMonthHandler() { $view = Views::getView('test_argument_date'); $view->setDisplay('embed_2'); - $this->executeView($view, array('01')); - $expected = array(); - $expected[] = array('id' => 1); - $expected[] = array('id' => 2); - $expected[] = array('id' => 3); - $expected[] = array('id' => 4); - $expected[] = array('id' => 5); + $this->executeView($view, ['01']); + $expected = []; + $expected[] = ['id' => 1]; + $expected[] = ['id' => 2]; + $expected[] = ['id' => 3]; + $expected[] = ['id' => 4]; + $expected[] = ['id' => 5]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_2'); - $this->executeView($view, array('12')); - $expected = array(); + $this->executeView($view, ['12']); + $expected = []; $this->assertIdenticalResultset($view, $expected, $this->columnMap); } @@ -143,27 +143,27 @@ public function testMonthHandler() { */ public function testWeekHandler() { $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 9, 26, 2008))) + ->fields(['created' => gmmktime(0, 0, 0, 9, 26, 2008)]) ->condition('id', 1) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 2, 29, 2004))) + ->fields(['created' => gmmktime(0, 0, 0, 2, 29, 2004)]) ->condition('id', 2) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 1, 1, 2000))) + ->fields(['created' => gmmktime(0, 0, 0, 1, 1, 2000)]) ->condition('id', 3) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 1, 10, 2000))) + ->fields(['created' => gmmktime(0, 0, 0, 1, 10, 2000)]) ->condition('id', 4) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 2, 1, 2000))) + ->fields(['created' => gmmktime(0, 0, 0, 2, 1, 2000)]) ->condition('id', 5) ->execute(); @@ -171,46 +171,46 @@ public function testWeekHandler() { $view->setDisplay('embed_3'); // Check the week calculation for a leap year. // @see http://wikipedia.org/wiki/ISO_week_date#Calculation - $this->executeView($view, array('39')); - $expected = array(); - $expected[] = array('id' => 1); + $this->executeView($view, ['39']); + $expected = []; + $expected[] = ['id' => 1]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_3'); // Check the week calculation for the 29th of February in a leap year. // @see http://wikipedia.org/wiki/ISO_week_date#Calculation - $this->executeView($view, array('09')); - $expected = array(); - $expected[] = array('id' => 2); + $this->executeView($view, ['09']); + $expected = []; + $expected[] = ['id' => 2]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_3'); // The first jan 2000 was still in the last week of the previous year. - $this->executeView($view, array('52')); - $expected = array(); - $expected[] = array('id' => 3); + $this->executeView($view, ['52']); + $expected = []; + $expected[] = ['id' => 3]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_3'); - $this->executeView($view, array('02')); - $expected = array(); - $expected[] = array('id' => 4); + $this->executeView($view, ['02']); + $expected = []; + $expected[] = ['id' => 4]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_3'); - $this->executeView($view, array('05')); - $expected = array(); - $expected[] = array('id' => 5); + $this->executeView($view, ['05']); + $expected = []; + $expected[] = ['id' => 5]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_3'); - $this->executeView($view, array('23')); - $expected = array(); + $this->executeView($view, ['23']); + $expected = []; $this->assertIdenticalResultset($view, $expected, $this->columnMap); } @@ -221,47 +221,47 @@ public function testWeekHandler() { */ public function testYearHandler() { $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 1, 1, 2001))) + ->fields(['created' => gmmktime(0, 0, 0, 1, 1, 2001)]) ->condition('id', 3) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 1, 1, 2002))) + ->fields(['created' => gmmktime(0, 0, 0, 1, 1, 2002)]) ->condition('id', 4) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 1, 1, 2002))) + ->fields(['created' => gmmktime(0, 0, 0, 1, 1, 2002)]) ->condition('id', 5) ->execute(); $view = Views::getView('test_argument_date'); $view->setDisplay('embed_4'); - $this->executeView($view, array('2000')); - $expected = array(); - $expected[] = array('id' => 1); - $expected[] = array('id' => 2); + $this->executeView($view, ['2000']); + $expected = []; + $expected[] = ['id' => 1]; + $expected[] = ['id' => 2]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_4'); - $this->executeView($view, array('2001')); - $expected = array(); - $expected[] = array('id' => 3); + $this->executeView($view, ['2001']); + $expected = []; + $expected[] = ['id' => 3]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_4'); - $this->executeView($view, array('2002')); - $expected = array(); - $expected[] = array('id' => 4); - $expected[] = array('id' => 5); + $this->executeView($view, ['2002']); + $expected = []; + $expected[] = ['id' => 4]; + $expected[] = ['id' => 5]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_4'); - $this->executeView($view, array('23')); - $expected = array(); + $this->executeView($view, ['23']); + $expected = []; $this->assertIdenticalResultset($view, $expected, $this->columnMap); } @@ -272,47 +272,47 @@ public function testYearHandler() { */ public function testYearMonthHandler() { $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 1, 1, 2001))) + ->fields(['created' => gmmktime(0, 0, 0, 1, 1, 2001)]) ->condition('id', 3) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 4, 1, 2001))) + ->fields(['created' => gmmktime(0, 0, 0, 4, 1, 2001)]) ->condition('id', 4) ->execute(); $this->container->get('database')->update('views_test_data') - ->fields(array('created' => gmmktime(0, 0, 0, 4, 1, 2001))) + ->fields(['created' => gmmktime(0, 0, 0, 4, 1, 2001)]) ->condition('id', 5) ->execute(); $view = Views::getView('test_argument_date'); $view->setDisplay('embed_5'); - $this->executeView($view, array('200001')); - $expected = array(); - $expected[] = array('id' => 1); - $expected[] = array('id' => 2); + $this->executeView($view, ['200001']); + $expected = []; + $expected[] = ['id' => 1]; + $expected[] = ['id' => 2]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_5'); - $this->executeView($view, array('200101')); - $expected = array(); - $expected[] = array('id' => 3); + $this->executeView($view, ['200101']); + $expected = []; + $expected[] = ['id' => 3]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_5'); - $this->executeView($view, array('200104')); - $expected = array(); - $expected[] = array('id' => 4); - $expected[] = array('id' => 5); + $this->executeView($view, ['200104']); + $expected = []; + $expected[] = ['id' => 4]; + $expected[] = ['id' => 5]; $this->assertIdenticalResultset($view, $expected, $this->columnMap); $view->destroy(); $view->setDisplay('embed_5'); - $this->executeView($view, array('201301')); - $expected = array(); + $this->executeView($view, ['201301']); + $expected = []; $this->assertIdenticalResultset($view, $expected, $this->columnMap); } diff --git a/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php b/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php index e90ec855..933a0009 100644 --- a/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php @@ -17,9 +17,9 @@ class ArgumentNullTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['id']['argument']['id'] = 'null'; @@ -32,13 +32,13 @@ public function testAreaText() { $view->setDisplay(); // Add a null argument. - $view->displayHandlers->get('default')->overrideOption('arguments', array( - 'null' => array( + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'null' => [ 'id' => 'null', 'table' => 'views', 'field' => 'null', - ), - )); + ], + ]); $this->executeView($view); @@ -57,15 +57,15 @@ public function testAreaText() { $view->setDisplay(); // Add a argument, which has null as handler. - $view->displayHandlers->get('default')->overrideOption('arguments', array( - 'id' => array( + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'id' => [ 'id' => 'id', 'table' => 'views_test_data', 'field' => 'id', - ), - )); + ], + ]); - $this->executeView($view, array(26)); + $this->executeView($view, [26]); // The argument should be ignored, so every result should return. $this->assertEqual(5, count($view->result)); diff --git a/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php b/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php new file mode 100644 index 00000000..8f85f690 --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php @@ -0,0 +1,57 @@ +installEntitySchema('entity_test_computed_field'); + } + + /** + * Test the computed field handler. + */ + public function testComputedFieldHandler() { + \Drupal::state()->set('entity_test_computed_field_item_list_value', ['computed string']); + + $entity = EntityTestComputedField::create([]); + $entity->save(); + + $view = Views::getView('computed_field_view'); + + $rendered_view = $view->preview(); + $output = $this->container->get('renderer')->renderRoot($rendered_view); + $this->assertContains('computed string', (string) $output); + } + +} diff --git a/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php b/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php index 3492ff15..ee219ab7 100644 --- a/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php @@ -1,6 +1,7 @@ setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', - ), - )); + ], + ]); $this->executeView($view); @@ -70,7 +70,7 @@ public function testFieldBoolean() { $this->assertEqual('✔', $view->field['age']->advancedRender($view->result[1])); // Set a custom output format. - $view->field['age']->formats['test'] = array(t('Test-True'), t('Test-False')); + $view->field['age']->formats['test'] = [t('Test-True'), t('Test-False')]; $view->field['age']->options['type'] = 'test'; $this->assertEqual(t('Test-False'), $view->field['age']->advancedRender($view->result[0])); $this->assertEqual(t('Test-True'), $view->field['age']->advancedRender($view->result[1])); diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php index 12f68ede..b5c52fef 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php @@ -17,77 +17,77 @@ class FieldCounterTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('user'); + public static $modules = ['user']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; - function testSimple() { + public function testSimple() { $view = Views::getView('test_view'); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'counter' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'counter' => [ 'id' => 'counter', 'table' => 'views', 'field' => 'counter', 'relationship' => 'none', - ), - 'name' => array( + ], + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - ), - )); + ], + ]); $view->preview(); $counter = $view->style_plugin->getField(0, 'counter'); - $this->assertEqual($counter, '1', format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => 1, '@counter' => $counter))); + $this->assertEqual($counter, '1', format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', ['@expected' => 1, '@counter' => $counter])); $counter = $view->style_plugin->getField(1, 'counter'); - $this->assertEqual($counter, '2', format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => 2, '@counter' => $counter))); + $this->assertEqual($counter, '2', format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', ['@expected' => 2, '@counter' => $counter])); $counter = $view->style_plugin->getField(2, 'counter'); - $this->assertEqual($counter, '3', format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => 3, '@counter' => $counter))); + $this->assertEqual($counter, '3', format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', ['@expected' => 3, '@counter' => $counter])); $view->destroy(); $view->storage->invalidateCaches(); $view->setDisplay(); $rand_start = rand(5, 10); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'counter' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'counter' => [ 'id' => 'counter', 'table' => 'views', 'field' => 'counter', 'relationship' => 'none', 'counter_start' => $rand_start - ), - 'name' => array( + ], + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - ), - )); + ], + ]); $view->preview(); $counter = $view->style_plugin->getField(0, 'counter'); $expected_number = 0 + $rand_start; - $this->assertEqual($counter, (string) $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => $expected_number, '@counter' => $counter))); + $this->assertEqual($counter, (string) $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', ['@expected' => $expected_number, '@counter' => $counter])); $counter = $view->style_plugin->getField(1, 'counter'); $expected_number = 1 + $rand_start; - $this->assertEqual($counter, (string) $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => $expected_number, '@counter' => $counter))); + $this->assertEqual($counter, (string) $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', ['@expected' => $expected_number, '@counter' => $counter])); $counter = $view->style_plugin->getField(2, 'counter'); $expected_number = 2 + $rand_start; - $this->assertEqual($counter, (string) $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => $expected_number, '@counter' => $counter))); + $this->assertEqual($counter, (string) $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', ['@expected' => $expected_number, '@counter' => $counter])); } /** * @todo: Write tests for pager. */ - function testPager() { + public function testPager() { } } diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldCustomTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldCustomTest.php index af7bc1bc..599052dc 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldCustomTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldCustomTest.php @@ -18,12 +18,12 @@ class FieldCustomTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * {@inheritdoc} */ - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['name']['field']['id'] = 'custom'; return $data; @@ -38,17 +38,17 @@ public function testFieldCustom() { // Alter the text of the field to a random string. $random = '
              ' . $this->randomMachineName() . '
              '; - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - 'alter' => array( + 'alter' => [ 'text' => $random, - ), - ), - )); + ], + ], + ]); $this->executeView($view); @@ -98,17 +98,17 @@ public function testCustomFieldXss() { // Alter the text of the field to include XSS. $text = ''; - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - 'alter' => array( + 'alter' => [ 'text' => $text, - ), - ), - )); + ], + ], + ]); $this->executeView($view); $this->assertEqual(Xss::filter($text), $view->style_plugin->getField(0, 'name')); } diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldDateTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldDateTest.php index cb30bf7f..833b5c99 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldDateTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldDateTest.php @@ -17,20 +17,20 @@ class FieldDateTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * {@inheritdoc} */ public function schemaDefinition() { $schema = parent::schemaDefinition(); - $schema['views_test_data']['fields']['destroyed'] = array( + $schema['views_test_data']['fields']['destroyed'] = [ 'description' => "The destruction date of this record", 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'default' => 0, - ); + ]; return $schema; } @@ -40,14 +40,14 @@ public function schemaDefinition() { public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['created']['field']['id'] = 'date'; - $data['views_test_data']['destroyed'] = array( + $data['views_test_data']['destroyed'] = [ 'title' => 'Destroyed', 'help' => 'Date in future this will be destroyed.', - 'field' => array('id' => 'date'), - 'argument' => array('id' => 'date'), - 'filter' => array('id' => 'date'), - 'sort' => array('id' => 'date'), - ); + 'field' => ['id' => 'date'], + 'argument' => ['id' => 'date'], + 'filter' => ['id' => 'date'], + 'sort' => ['id' => 'date'], + ]; return $data; } @@ -69,36 +69,36 @@ public function testFieldDate() { $view = Views::getView('test_view'); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'created' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'created' => [ 'id' => 'created', 'table' => 'views_test_data', 'field' => 'created', 'relationship' => 'none', // ISO 8601 format, see http://php.net/manual/function.date.php 'custom_date_format' => 'c', - ), - 'destroyed' => array( + ], + 'destroyed' => [ 'id' => 'destroyed', 'table' => 'views_test_data', 'field' => 'destroyed', 'relationship' => 'none', 'custom_date_format' => 'c', - ), - )); + ], + ]); $time = gmmktime(0, 0, 0, 1, 1, 2000); $this->executeView($view); - $timezones = array( + $timezones = [ NULL, 'UTC', 'America/New_York', - ); + ]; // Check each date/time in various timezones. foreach ($timezones as $timezone) { - $dates = array( + $dates = [ 'short' => format_date($time, 'short', '', $timezone), 'medium' => format_date($time, 'medium', '', $timezone), 'long' => format_date($time, 'long', '', $timezone), @@ -111,30 +111,30 @@ public function testFieldDate() { 'html_week' => format_date($time, 'html_week', '', $timezone), 'html_year' => format_date($time, 'html_year', '', $timezone), 'html_yearless_date' => format_date($time, 'html_yearless_date', '', $timezone), - ); + ]; $this->assertRenderedDatesEqual($view, $dates, $timezone); } // Check times in the past. $time_since = $this->container->get('date.formatter')->formatTimeDiffSince($time); - $intervals = array( + $intervals = [ 'raw time ago' => $time_since, - 'time ago' => t('%time ago', array('%time' => $time_since)), + 'time ago' => t('%time ago', ['%time' => $time_since]), 'raw time span' => $time_since, 'inverse time span' => "-$time_since", - 'time span' => t('%time ago', array('%time' => $time_since)), - ); + 'time span' => t('%time ago', ['%time' => $time_since]), + ]; $this->assertRenderedDatesEqual($view, $intervals); // Check times in the future. $time = gmmktime(0, 0, 0, 1, 1, 2050); $formatted = $this->container->get('date.formatter')->formatTimeDiffUntil($time); - $intervals = array( + $intervals = [ 'raw time span' => "-$formatted", - 'time span' => t('%time hence', array( + 'time span' => t('%time hence', [ '%time' => $formatted, - )), - ); + ]), + ]; $this->assertRenderedFutureDatesEqual($view, $intervals); } @@ -151,10 +151,10 @@ public function testFieldDate() { protected function assertRenderedDatesEqual($view, $map, $timezone = NULL) { foreach ($map as $date_format => $expected_result) { $view->field['created']->options['date_format'] = $date_format; - $t_args = array( + $t_args = [ '%value' => $expected_result, '%format' => $date_format, - ); + ]; if (isset($timezone)) { $t_args['%timezone'] = $timezone; $message = t('Value %value in %format format for timezone %timezone matches.', $t_args); @@ -180,11 +180,11 @@ protected function assertRenderedFutureDatesEqual($view, $map) { foreach ($map as $format => $result) { $view->field['destroyed']->options['date_format'] = $format; $view_result = $view->field['destroyed']->advancedRender($view->result[0]); - $t_args = array( + $t_args = [ '%value' => $result, '%format' => $format, '%actual' => $view_result, - ); + ]; $message = t('Value %value in %format matches %actual', $t_args); $this->assertEqual($view_result, $result, $message); } diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldEntityLinkTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldEntityLinkTest.php index 8f53f6a3..874f03d4 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldEntityLinkTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldEntityLinkTest.php @@ -23,14 +23,14 @@ class FieldEntityLinkTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_entity_test_link'); + public static $testViews = ['test_entity_test_link']; /** * Modules to enable. * * @var array */ - public static $modules = array('user', 'entity_test'); + public static $modules = ['user', 'entity_test']; /** * An admin user account. diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldFieldTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldFieldTest.php index 1a9df822..1d304f53 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldFieldTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldFieldTest.php @@ -8,7 +8,7 @@ use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\user\Entity\User; -use Drupal\views\Plugin\views\field\Field; +use Drupal\views\Plugin\views\field\EntityField; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; use Drupal\views\Tests\ViewTestData; use Drupal\views\Views; @@ -16,7 +16,7 @@ /** * Provides some integration tests for the Field handler. * - * @see \Drupal\views\Plugin\views\field\Field + * @see \Drupal\views\Plugin\views\field\EntityField * @group views */ class FieldFieldTest extends ViewsKernelTestBase { @@ -70,7 +70,7 @@ protected function setUp($import_test_views = TRUE) { $this->installEntitySchema('entity_test'); $this->installEntitySchema('entity_test_rev'); - ViewTestData::createTestViews(get_class($this), array('views_test_config')); + ViewTestData::createTestViews(get_class($this), ['views_test_config']); // Bypass any field access. $this->adminUser = User::create(['name' => $this->randomString()]); @@ -229,8 +229,8 @@ public function testSimpleExecute() { $executable = Views::getView('test_field_field_test'); $executable->execute(); - $this->assertTrue($executable->field['id'] instanceof Field); - $this->assertTrue($executable->field['field_test'] instanceof Field); + $this->assertTrue($executable->field['id'] instanceof EntityField); + $this->assertTrue($executable->field['field_test'] instanceof EntityField); $this->assertIdenticalResultset($executable, [ @@ -299,9 +299,9 @@ public function testFieldAlias() { $executable = Views::getView('test_field_alias_test'); $executable->execute(); - $this->assertTrue($executable->field['id'] instanceof Field); - $this->assertTrue($executable->field['name'] instanceof Field); - $this->assertTrue($executable->field['name_alias'] instanceof Field); + $this->assertTrue($executable->field['id'] instanceof EntityField); + $this->assertTrue($executable->field['name'] instanceof EntityField); + $this->assertTrue($executable->field['name_alias'] instanceof EntityField); $this->assertIdenticalResultset($executable, [ @@ -348,10 +348,10 @@ public function testComplexExecute() { $timezones[] = $user->getTimeZone(); } - $this->assertTrue($executable->field['field_test_multiple'] instanceof Field); - $this->assertTrue($executable->field['field_test_multiple_1'] instanceof Field); - $this->assertTrue($executable->field['field_test_multiple_2'] instanceof Field); - $this->assertTrue($executable->field['timezone'] instanceof Field); + $this->assertTrue($executable->field['field_test_multiple'] instanceof EntityField); + $this->assertTrue($executable->field['field_test_multiple_1'] instanceof EntityField); + $this->assertTrue($executable->field['field_test_multiple_2'] instanceof EntityField); + $this->assertTrue($executable->field['timezone'] instanceof EntityField); $this->assertIdenticalResultset($executable, [ @@ -421,8 +421,8 @@ public function testRevisionExecute() { $executable = Views::getView('test_field_field_revision_test'); $executable->execute(); - $this->assertTrue($executable->field['name'] instanceof Field); - $this->assertTrue($executable->field['field_test'] instanceof Field); + $this->assertTrue($executable->field['name'] instanceof EntityField); + $this->assertTrue($executable->field['field_test'] instanceof EntityField); $this->assertIdenticalResultset($executable, [ @@ -475,12 +475,12 @@ public function testRevisionComplexExecute() { $timezones[] = $user->getTimeZone(); } - $this->assertTrue($executable->field['id'] instanceof Field); - $this->assertTrue($executable->field['revision_id'] instanceof Field); - $this->assertTrue($executable->field['timezone'] instanceof Field); - $this->assertTrue($executable->field['field_test_multiple'] instanceof Field); - $this->assertTrue($executable->field['field_test_multiple_1'] instanceof Field); - $this->assertTrue($executable->field['field_test_multiple_2'] instanceof Field); + $this->assertTrue($executable->field['id'] instanceof EntityField); + $this->assertTrue($executable->field['revision_id'] instanceof EntityField); + $this->assertTrue($executable->field['timezone'] instanceof EntityField); + $this->assertTrue($executable->field['field_test_multiple'] instanceof EntityField); + $this->assertTrue($executable->field['field_test_multiple_1'] instanceof EntityField); + $this->assertTrue($executable->field['field_test_multiple_2'] instanceof EntityField); $this->assertIdenticalResultset($executable, [ @@ -551,7 +551,7 @@ public function testMissingBundleFieldRender() { } /** - * Tests \Drupal\views\Plugin\views\field\Field::getValue + * Tests \Drupal\views\Plugin\views\field\EntityField::getValue */ public function testGetValueMethod() { $bundle = 'test_bundle'; diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php index 2f60e34b..892e82fc 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php @@ -18,9 +18,9 @@ class FieldFileSizeTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; - function dataSet() { + public function dataSet() { $data = parent::dataSet(); $data[0]['age'] = 0; $data[1]['age'] = 10; @@ -30,7 +30,7 @@ function dataSet() { return $data; } - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['age']['field']['id'] = 'file_size'; @@ -41,13 +41,13 @@ public function testFieldFileSize() { $view = Views::getView('test_view'); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', - ), - )); + ], + ]); $this->executeView($view); diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php index be8a4f13..677a3f5e 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldKernelTest.php @@ -15,23 +15,23 @@ */ class FieldKernelTest extends ViewsKernelTestBase { - public static $modules = array('user'); + public static $modules = ['user']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view', 'test_field_tokens', 'test_field_argument_tokens', 'test_field_output'); + public static $testViews = ['test_view', 'test_field_tokens', 'test_field_argument_tokens', 'test_field_output']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', - ); + ]; /** * {@inheritdoc} @@ -73,7 +73,7 @@ public function testQuery() { $id_field = $view->field['id']; $id_field->additional_fields['job'] = 'job'; // Choose also a field alias key which doesn't match to the table field. - $id_field->additional_fields['created_test'] = array('table' => 'views_test_data', 'field' => 'created'); + $id_field->additional_fields['created_test'] = ['table' => 'views_test_data', 'field' => 'created']; $view->build(); // Make sure the field aliases have the expected value. @@ -412,7 +412,7 @@ public function testExclude() { /** * Tests everything related to empty output of a field. */ - function testEmpty() { + public function testEmpty() { $this->_testHideIfEmpty(); $this->_testEmptyText(); } @@ -423,7 +423,7 @@ function testEmpty() { * This tests alters the result to get easier and less coupled results. It is * important that assertIdentical() is used in this test since in PHP 0 == ''. */ - function _testHideIfEmpty() { + public function _testHideIfEmpty() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); @@ -704,7 +704,7 @@ function _testHideIfEmpty() { /** * Tests the usage of the empty text. */ - function _testEmptyText() { + public function _testEmptyText() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = \Drupal::service('renderer'); @@ -754,7 +754,7 @@ function _testEmptyText() { /** * Tests views_handler_field::isValueEmpty(). */ - function testIsValueEmpty() { + public function testIsValueEmpty() { $view = Views::getView('test_view'); $view->initHandlers(); $field = $view->field['name']; @@ -778,10 +778,10 @@ function testIsValueEmpty() { */ public function testClickSortable() { // Test that clickSortable is TRUE by default. - $item = array( + $item = [ 'table' => 'views_test_data', 'field' => 'name', - ); + ]; $plugin = $this->container->get('plugin.manager.views.field')->getHandler($item); $this->assertTrue($plugin->clickSortable(), 'TRUE as a default value is correct.'); @@ -801,7 +801,7 @@ public function testClickSortable() { */ public function testTrimText() { // Test unicode. See https://www.drupal.org/node/513396#comment-2839416. - $text = array( + $text = [ 'Tuy nhiên, những hi vá»ng', 'Giả sá»­ chúng tôi có 3 Apple', 'siêu nhá» này là bá»™ xá»­ lý', @@ -810,12 +810,12 @@ public function testTrimText() { 'cá»§a hãng bao gồm ba dòng', 'Ñд аÑд аÑд аÑ', 'аÑд аÑд аÑд аÑ' - ); + ]; // Just test maxlength without word boundary. - $alter = array( + $alter = [ 'max_length' => 10, - ); - $expect = array( + ]; + $expect = [ 'Tuy nhiên,', 'Giả sá»­ chú', 'siêu nhá» n', @@ -824,7 +824,7 @@ public function testTrimText() { 'cá»§a hãng b', 'Ñд аÑд аÑд', 'аÑд аÑд аÑ', - ); + ]; foreach ($text as $key => $line) { $result_text = FieldPluginBase::trimText($alter, $line); @@ -833,7 +833,7 @@ public function testTrimText() { // Test also word_boundary $alter['word_boundary'] = TRUE; - $expect = array( + $expect = [ 'Tuy nhiên', 'Giả sá»­', 'siêu nhá»', @@ -842,7 +842,7 @@ public function testTrimText() { 'cá»§a hãng', 'Ñд аÑд', 'аÑд аÑд', - ); + ]; foreach ($text as $key => $line) { $result_text = FieldPluginBase::trimText($alter, $line); diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldNumericTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldNumericTest.php new file mode 100644 index 00000000..6cb4817e --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/FieldNumericTest.php @@ -0,0 +1,164 @@ +setDisplay(); + + if (!empty($field_settings)) { + $view->displayHandlers->get('default')->overrideOption('fields', ['age' => $field_settings]); + } + $this->executeView($view); + + foreach ($values as $key => $value) { + $view->result[0]->views_test_data_age = $value; + $this->assertSame($expected_values[$key], $view->field['age']->advancedRender($view->result[0])); + } + } + + /** + * Data provider for testFieldNumeric. + * + * @return array + * The data set containing field settings, values to set and expected + * values. + */ + public function providerTestFieldNumeric() { + return [ + 'no-formating' => [ + [], + [0, 0.1234, -0.1234, 1000.1234, -1000.1234], + ['0', '0.1234', '-0.1234', '1,000.1234', '-1,000.1234'], + ], + 'precision_2-hide_empty-hide_zero' => [ + [ + 'hide_empty' => TRUE, + 'precision' => 2, + 'set_precision' => TRUE, + 'empty_zero' => TRUE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + ], + [0, 0.1234, -0.1234, 1000.1234, -1000.1234, 0.0001, -0.0001, NULL, ''], + ['', '0.12', '-0.12', '1,000.12', '-1,000.12', '', '', '', ''], + ], + 'decimal-separator' => [ + [ + 'hide_empty' => TRUE, + 'decimal' => ',', + 'separator' => '.', + 'empty_zero' => TRUE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + ], + [0.1234, -0.1234, 1000.1234, -1000.1234], + ['0,1234', '-0,1234', '1.000,1234', '-1.000,1234'], + ], + 'precision_2-no_separator' => [ + [ + 'hide_empty' => TRUE, + 'precision' => 2, + 'set_precision' => TRUE, + 'decimal' => ',', + 'separator' => '', + 'empty_zero' => TRUE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + ], + [1234, 1234.01, -1234, -1234.01], + ['1234,00', '1234,01', '-1234,00', '-1234,01'], + ], + 'precision_0-no_separator' => [ + [ + 'hide_empty' => TRUE, + 'precision' => 0, + 'set_precision' => TRUE, + 'separator' => '', + 'empty_zero' => TRUE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + ], + [1234, 1234.01, -1234, -1234.01], + ['1234', '1234', '-1234', '-1234'], + ], + 'precision_0-hide_empty-zero_empty' => [ + [ + 'hide_empty' => TRUE, + 'precision' => 0, + 'set_precision' => TRUE, + 'empty_zero' => TRUE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + 'prefix' => 'test: ', + ], + [0, 0.1234, -0.1234, 1000.1234, -1000.1234], + ['', '', '', 'test: 1,000', 'test: -1,000'], + ], + 'precision_0-hide_empty-not_zero_empty' => [ + [ + 'hide_empty' => TRUE, + 'precision' => 0, + 'set_precision' => TRUE, + 'empty_zero' => FALSE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + 'prefix' => '', + ], + [0, 0.1234, -0.1234], + ['0', '0', '0'], + ], + 'precision_2-hide_empty-not_zero_empty' => [ + [ + 'hide_empty' => TRUE, + 'precision' => 2, + 'set_precision' => TRUE, + 'empty_zero' => FALSE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + 'prefix' => '', + ], + [0, 0.001234, -0.001234, NULL], + ['0.00', '0.00', '0.00', ''], + ], + ]; + } + +} diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php index bfb764d4..0814402c 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php @@ -13,16 +13,16 @@ */ class FieldUrlTest extends ViewsKernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['name']['field']['id'] = 'url'; return $data; @@ -32,15 +32,15 @@ public function testFieldUrl() { $view = Views::getView('test_view'); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'display_as_link' => FALSE, - ), - )); + ], + ]); $this->executeView($view); @@ -50,14 +50,14 @@ public function testFieldUrl() { $view->destroy(); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - ), - )); + ], + ]); $this->executeView($view); diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorDefaultTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorDefaultTest.php new file mode 100644 index 00000000..7beceb9b --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorDefaultTest.php @@ -0,0 +1,56 @@ +setDisplay(); + + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'status' => [ + 'id' => 'status', + 'field' => 'status', + 'table' => 'views_test_data', + 'value' => 0, + ], + ]); + $this->executeView($view); + $this->assertCount(2, $view->result); + } + +} diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorStringTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorStringTest.php index 5bd2157a..325da510 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorStringTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorStringTest.php @@ -19,23 +19,23 @@ class FilterBooleanOperatorStringTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_id' => 'id', - ); + ]; /** * {@inheritdoc} @@ -43,13 +43,13 @@ class FilterBooleanOperatorStringTest extends ViewsKernelTestBase { protected function schemaDefinition() { $schema = parent::schemaDefinition(); - $schema['views_test_data']['fields']['status'] = array( + $schema['views_test_data']['fields']['status'] = [ 'description' => 'The status of this record', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ); + ]; return $schema; } @@ -91,20 +91,20 @@ public function testFilterBooleanOperatorString() { $view->setDisplay(); // Add a the status boolean filter. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'status' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'status' => [ 'id' => 'status', 'field' => 'status', 'table' => 'views_test_data', 'value' => 0, - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array('id' => 2), - array('id' => 4), - ); + $expected_result = [ + ['id' => 2], + ['id' => 4], + ]; $this->assertEqual(2, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -113,21 +113,21 @@ public function testFilterBooleanOperatorString() { $view->setDisplay(); // Add the status boolean filter. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'status' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'status' => [ 'id' => 'status', 'field' => 'status', 'table' => 'views_test_data', 'value' => 1, - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array('id' => 1), - array('id' => 3), - array('id' => 5), - ); + $expected_result = [ + ['id' => 1], + ['id' => 3], + ['id' => 5], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -140,32 +140,32 @@ public function testFilterGroupedExposed() { $filters = $this->getGroupedExposedFilters(); $view = Views::getView('test_view'); - $view->setExposedInput(array('status' => 1)); + $view->setExposedInput(['status' => 1]); $view->setDisplay(); $view->displayHandlers->get('default')->overrideOption('filters', $filters); $this->executeView($view); - $expected_result = array( - array('id' => 1), - array('id' => 3), - array('id' => 5), - ); + $expected_result = [ + ['id' => 1], + ['id' => 3], + ['id' => 5], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); $view->destroy(); - $view->setExposedInput(array('status' => 2)); + $view->setExposedInput(['status' => 2]); $view->setDisplay(); $view->displayHandlers->get('default')->overrideOption('filters', $filters); $this->executeView($view); - $expected_result = array( - array('id' => 2), - array('id' => 4), - ); + $expected_result = [ + ['id' => 2], + ['id' => 4], + ]; $this->assertEqual(2, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -178,38 +178,38 @@ public function testFilterGroupedExposed() { * Returns the filter configuration for exposed filters. */ protected function getGroupedExposedFilters() { - $filters = array( - 'status' => array( + $filters = [ + 'status' => [ 'id' => 'status', 'table' => 'views_test_data', 'field' => 'status', 'relationship' => 'none', 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'status_op', 'label' => 'status', 'identifier' => 'status', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'status', 'identifier' => 'status', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Active', 'operator' => '=', 'value' => '1', - ), - 2 => array( + ], + 2 => [ 'title' => 'Blocked', 'operator' => '=', 'value' => '0', - ), - ), - ), - ), - ); + ], + ], + ], + ], + ]; return $filters; } diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorTest.php index 7a88066e..7cdd41f5 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterBooleanOperatorTest.php @@ -18,23 +18,23 @@ class FilterBooleanOperatorTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_id' => 'id', - ); + ]; /** * Tests the BooleanOperator filter. @@ -44,20 +44,20 @@ public function testFilterBooleanOperator() { $view->setDisplay(); // Add a the status boolean filter. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'status' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'status' => [ 'id' => 'status', 'field' => 'status', 'table' => 'views_test_data', 'value' => 0, - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array('id' => 2), - array('id' => 4), - ); + $expected_result = [ + ['id' => 2], + ['id' => 4], + ]; $this->assertEqual(2, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -66,21 +66,21 @@ public function testFilterBooleanOperator() { $view->setDisplay(); // Add the status boolean filter. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'status' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'status' => [ 'id' => 'status', 'field' => 'status', 'table' => 'views_test_data', 'value' => 1, - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array('id' => 1), - array('id' => 3), - array('id' => 5), - ); + $expected_result = [ + ['id' => 1], + ['id' => 3], + ['id' => 5], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -89,22 +89,22 @@ public function testFilterBooleanOperator() { $view->setDisplay(); // Testing the same scenario but using the reverse status and operation. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'status' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'status' => [ 'id' => 'status', 'field' => 'status', 'table' => 'views_test_data', 'value' => 0, 'operator' => '!=', - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array('id' => 1), - array('id' => 3), - array('id' => 5), - ); + $expected_result = [ + ['id' => 1], + ['id' => 3], + ['id' => 5], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -117,32 +117,32 @@ public function testFilterGroupedExposed() { $filters = $this->getGroupedExposedFilters(); $view = Views::getView('test_view'); - $view->setExposedInput(array('status' => 1)); + $view->setExposedInput(['status' => 1]); $view->setDisplay(); $view->displayHandlers->get('default')->overrideOption('filters', $filters); $this->executeView($view); - $expected_result = array( - array('id' => 1), - array('id' => 3), - array('id' => 5), - ); + $expected_result = [ + ['id' => 1], + ['id' => 3], + ['id' => 5], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); $view->destroy(); - $view->setExposedInput(array('status' => 2)); + $view->setExposedInput(['status' => 2]); $view->setDisplay(); $view->displayHandlers->get('default')->overrideOption('filters', $filters); $this->executeView($view); - $expected_result = array( - array('id' => 2), - array('id' => 4), - ); + $expected_result = [ + ['id' => 2], + ['id' => 4], + ]; $this->assertEqual(2, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -156,11 +156,11 @@ public function testFilterGroupedExposed() { $this->executeView($view); - $expected_result = array( - array('id' => 1), - array('id' => 3), - array('id' => 5), - ); + $expected_result = [ + ['id' => 1], + ['id' => 3], + ['id' => 5], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -172,45 +172,45 @@ public function testFilterGroupedExposed() { * @return array */ protected function getGroupedExposedFilters() { - $filters = array( - 'status' => array( + $filters = [ + 'status' => [ 'id' => 'status', 'table' => 'views_test_data', 'field' => 'status', 'relationship' => 'none', 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'status_op', 'label' => 'status', 'identifier' => 'status', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'status', 'identifier' => 'status', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Active', 'operator' => '=', 'value' => '1', - ), - 2 => array( + ], + 2 => [ 'title' => 'Blocked', 'operator' => '=', 'value' => '0', - ), + ], // This group should return the same results as group 1, because it // is the negation of group 2. - 3 => array( + 3 => [ 'title' => 'Active (reverse)', 'operator' => '!=', 'value' => '0', - ), - ), - ), - ), - ); + ], + ], + ], + ], + ]; return $filters; } diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php index 04242638..feffbafd 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php @@ -15,24 +15,24 @@ class FilterCombineTest extends ViewsKernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('entity_test'); + public static $modules = ['entity_test']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view', 'entity_test_fields'); + public static $testViews = ['test_view', 'entity_test_fields']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', 'views_test_data_job' => 'job', - ); + ]; /** * {@inheritdoc} @@ -48,50 +48,50 @@ public function testFilterCombineContains() { $view->setDisplay(); $fields = $view->displayHandlers->get('default')->getOption('fields'); - $view->displayHandlers->get('default')->overrideOption('fields', $fields + array( - 'job' => array( + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'job' => [ 'id' => 'job', 'table' => 'views_test_data', 'field' => 'job', 'relationship' => 'none', - ), - )); + ], + ]); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'combine', 'table' => 'views', 'field' => 'combine', 'relationship' => 'none', 'operator' => 'contains', - 'fields' => array( + 'fields' => [ 'name', 'job', - ), + ], 'value' => 'ing', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'job' => 'Singer', - ), - array( + ], + [ 'name' => 'George', 'job' => 'Singer', - ), - array( + ], + [ 'name' => 'Ringo', 'job' => 'Drummer', - ), - array( + ], + [ 'name' => 'Ginger', 'job' => NULL, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -103,46 +103,46 @@ public function testFilterCombineWord() { $view->setDisplay(); $fields = $view->displayHandlers->get('default')->getOption('fields'); - $view->displayHandlers->get('default')->overrideOption('fields', $fields + array( - 'job' => array( + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'job' => [ 'id' => 'job', 'table' => 'views_test_data', 'field' => 'job', 'relationship' => 'none', - ), - )); + ], + ]); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'combine', 'table' => 'views', 'field' => 'combine', 'relationship' => 'none', 'operator' => 'word', - 'fields' => array( + 'fields' => [ 'name', 'job', - ), + ], 'value' => 'singer ringo', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'job' => 'Singer', - ), - array( + ], + [ 'name' => 'George', 'job' => 'Singer', - ), - array( + ], + [ 'name' => 'Ringo', 'job' => 'Drummer', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -154,39 +154,39 @@ public function testFilterCombineAllWords() { $view->setDisplay(); $fields = $view->displayHandlers->get('default')->getOption('fields'); - $view->displayHandlers->get('default')->overrideOption('fields', $fields + array( - 'job' => array( + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'job' => [ 'id' => 'job', 'table' => 'views_test_data', 'field' => 'job', 'relationship' => 'none', - ), - )); + ], + ]); // Set the filtering to allwords and simulate searching for a phrase. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'combine', 'table' => 'views', 'field' => 'combine', 'relationship' => 'none', 'operator' => 'allwords', - 'fields' => array( + 'fields' => [ 'name', 'job', 'age', - ), + ], 'value' => '25 "john singer"', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'job' => 'Singer', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -202,40 +202,40 @@ public function testFilterCombineContainsFieldsOverwritten() { $view->setDisplay(); $fields = $view->displayHandlers->get('default')->getOption('fields'); - $view->displayHandlers->get('default')->overrideOption('fields', $fields + array( - 'job' => array( + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'job' => [ 'id' => 'job', 'table' => 'views_test_data', 'field' => 'job', 'relationship' => 'none', - ), - )); + ], + ]); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'combine', 'table' => 'views', 'field' => 'combine', 'relationship' => 'none', 'operator' => 'contains', - 'fields' => array( + 'fields' => [ 'name', 'job', // Add a dummy field to the combined fields to simulate // a removed or deleted field. 'dummy', - ), + ], 'value' => 'ing', - ), - )); + ], + ]); $this->executeView($view); // Make sure this view will not get displayed. $this->assertTrue($view->build_info['fail'], "View build has been marked as failed."); // Make sure this view does not pass validation with the right error. $errors = $view->validate(); - $this->assertEquals(t('Field %field set in %filter is not set in display %display.', array('%field' => 'dummy', '%filter' => 'Global: Combine fields filter', '%display' => 'Master')), reset($errors['default'])); + $this->assertEquals(t('Field %field set in %filter is not set in display %display.', ['%field' => 'dummy', '%filter' => 'Global: Combine fields filter', '%display' => 'Master']), reset($errors['default'])); } /** @@ -247,30 +247,30 @@ public function testNonFieldsRow() { $view->setDisplay(); // Set the rows to a plugin type that doesn't support fields. - $view->displayHandlers->get('default')->overrideOption('row', array( + $view->displayHandlers->get('default')->overrideOption('row', [ 'type' => 'entity:entity_test', - 'options' => array( + 'options' => [ 'view_mode' => 'teaser', - ), - )); + ], + ]); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'combine', 'table' => 'views', 'field' => 'combine', 'relationship' => 'none', 'operator' => 'contains', - 'fields' => array( + 'fields' => [ 'name', - ), + ], 'value' => 'ing', - ), - )); + ], + ]); $this->executeView($view); $errors = $view->validate(); // Check that the right error is shown. - $this->assertEquals(t('%display: %filter can only be used on displays that use fields. Set the style or row format for that display to one using fields to use the combine field filter.', array('%filter' => 'Global: Combine fields filter', '%display' => 'Master')), reset($errors['default'])); + $this->assertEquals(t('%display: %filter can only be used on displays that use fields. Set the style or row format for that display to one using fields to use the combine field filter.', ['%filter' => 'Global: Combine fields filter', '%display' => 'Master']), reset($errors['default'])); } /** @@ -278,18 +278,20 @@ public function testNonFieldsRow() { */ protected function dataSet() { $data_set = parent::dataSet(); - $data_set[] = array( + $data_set[] = [ 'name' => 'Ginger', 'age' => 25, 'job' => NULL, 'created' => gmmktime(0, 0, 0, 1, 2, 2000), 'status' => 1, - ); + ]; return $data_set; } /** * Allow {views_test_data}.job to be NULL. + * + * @internal */ protected function schemaDefinition() { $schema = parent::schemaDefinition(); diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php index a4bd6c84..d78f7c92 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php @@ -12,52 +12,52 @@ */ class FilterEqualityTest extends ViewsKernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', - ); + ]; - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['name']['filter']['id'] = 'equality'; return $data; } - function testEqual() { + public function testEqual() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => '=', 'value' => 'Ringo', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -74,45 +74,45 @@ public function testEqualGroupedExposed() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testNotEqual() { + public function testNotEqual() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => '!=', 'value' => 'Ringo', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Paul', - ), - array( + ], + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -129,27 +129,27 @@ public function testEqualGroupedNotExposed() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Paul', - ), - array( + ], + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } protected function getGroupedExposedFilters() { - $filters = array( - 'name' => array( + $filters = [ + 'name' => [ 'id' => 'name', 'plugin_id' => 'equality', 'table' => 'views_test_data', @@ -157,31 +157,31 @@ protected function getGroupedExposedFilters() { 'relationship' => 'none', 'group' => 1, 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'name_op', 'label' => 'name', 'identifier' => 'name', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'name', 'identifier' => 'name', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Name is equal to Ringo', 'operator' => '=', 'value' => 'Ringo', - ), - 2 => array( + ], + 2 => [ 'title' => 'Name is not equal to Ringo', 'operator' => '!=', 'value' => 'Ringo', - ), - ), - ), - ), - ); + ], + ], + ], + ], + ]; return $filters; } diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php index 9ab08e1c..e02a8430 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php @@ -12,26 +12,26 @@ */ class FilterInOperatorTest extends ViewsKernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - ); + ]; - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['age']['filter']['id'] = 'in_operator'; return $data; @@ -42,28 +42,28 @@ public function testFilterInOperatorSimple() { $view->setDisplay(); // Add a in_operator ordering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'field' => 'age', 'table' => 'views_test_data', - 'value' => array(26, 30), + 'value' => [26, 30], 'operator' => 'in', - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array( + $expected_result = [ + [ 'name' => 'Paul', 'age' => 26, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, - ), - ); + ], + ]; $this->assertEqual(2, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -72,32 +72,32 @@ public function testFilterInOperatorSimple() { $view->setDisplay(); // Add a in_operator ordering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'field' => 'age', 'table' => 'views_test_data', - 'value' => array(26, 30), + 'value' => [26, 30], 'operator' => 'not in', - ), - )); + ], + ]); $this->executeView($view); - $expected_result = array( - array( + $expected_result = [ + [ 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, - ), - ); + ], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -114,16 +114,16 @@ public function testFilterInOperatorGroupedExposedSimple() { $this->executeView($view); - $expected_result = array( - array( + $expected_result = [ + [ 'name' => 'Paul', 'age' => 26, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, - ), - ); + ], + ]; $this->assertEqual(2, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); @@ -140,58 +140,58 @@ public function testFilterNotInOperatorGroupedExposedSimple() { $this->executeView($view); - $expected_result = array( - array( + $expected_result = [ + [ 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, - ), - ); + ], + ]; $this->assertEqual(3, count($view->result)); $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); } protected function getGroupedExposedFilters() { - $filters = array( - 'age' => array( + $filters = [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'age_op', 'label' => 'age', 'identifier' => 'age', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'age', 'identifier' => 'age', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Age is one of 26, 30', 'operator' => 'in', - 'value' => array(26, 30), - ), - 2 => array( + 'value' => [26, 30], + ], + 2 => [ 'title' => 'Age is not one of 26, 30', 'operator' => 'not in', - 'value' => array(26, 30), - ), - ), - ), - ), - ); + 'value' => [26, 30], + ], + ], + ], + ], + ]; return $filters; } diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php index c4c978a1..e1093e47 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php @@ -12,26 +12,26 @@ */ class FilterNumericTest extends ViewsKernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - ); + ]; - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['age']['filter']['allow empty'] = TRUE; $data['views_test_data']['id']['filter']['allow empty'] = FALSE; @@ -44,24 +44,24 @@ public function testFilterNumericSimple() { $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'operator' => '=', - 'value' => array('value' => 28), - ), - )); + 'value' => ['value' => 28], + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', 'age' => 28, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -78,12 +78,12 @@ public function testFilterNumericExposedGroupedSimple() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', 'age' => 28, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -92,35 +92,35 @@ public function testFilterNumericBetween() { $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'operator' => 'between', - 'value' => array( + 'value' => [ 'min' => 26, 'max' => 29, - ), - ), - )); + ], + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, - ), - array( + ], + [ 'name' => 'Paul', 'age' => 26, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); // test not between @@ -128,31 +128,31 @@ public function testFilterNumericBetween() { $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'operator' => 'not between', - 'value' => array( + 'value' => [ 'min' => 26, 'max' => 29, - ), - ), - )); + ], + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -169,20 +169,20 @@ public function testFilterNumericExposedGroupedBetween() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, - ), - array( + ], + [ 'name' => 'Paul', 'age' => 26, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -199,16 +199,76 @@ public function testFilterNumericExposedGroupedNotBetween() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, - ), - ); + ], + ]; + $this->assertIdenticalResultset($view, $resultset, $this->columnMap); + } + + /** + * Tests the numeric filter handler with the 'regular_expression' operator. + */ + public function testFilterNumericRegularExpression() { + $view = Views::getView('test_view'); + $view->setDisplay(); + + // Filtering by regular expression pattern. + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'relationship' => 'none', + 'operator' => 'regular_expression', + 'value' => [ + 'value' => '2[8]', + ], + ], + ]); + + $this->executeView($view); + $resultset = [ + [ + 'name' => 'Ringo', + 'age' => 28, + ], + ]; + $this->assertIdenticalResultset($view, $resultset, $this->columnMap); + } + + /** + * Tests the numeric filter handler with the 'regular_expression' operator + * to grouped exposed filters. + */ + public function testFilterNumericExposedGroupedRegularExpression() { + $filters = $this->getGroupedExposedFilters(); + $view = Views::getView('test_view'); + $view->newDisplay('page', 'Page', 'page_1'); + + // Filter: Age, Operator: regular_expression, Value: 2[7-8] + $filters['age']['group_info']['default_group'] = 6; + $view->setDisplay('page_1'); + $view->displayHandlers->get('page_1')->overrideOption('filters', $filters); + $view->save(); + + $this->executeView($view); + $resultset = [ + [ + 'name' => 'George', + 'age' => 27, + ], + [ + 'name' => 'Ringo', + 'age' => 28, + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -217,58 +277,57 @@ public function testFilterNumericEmpty() { $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'operator' => 'empty', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - ); + $resultset = []; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); $view->destroy(); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'operator' => 'not empty', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, - ), - array( + ], + [ 'name' => 'Paul', 'age' => 26, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -285,8 +344,7 @@ public function testFilterNumericExposedGroupedEmpty() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - ); + $resultset = []; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -303,28 +361,28 @@ public function testFilterNumericExposedGroupedNotEmpty() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', 'age' => 25, - ), - array( + ], + [ 'name' => 'George', 'age' => 27, - ), - array( + ], + [ 'name' => 'Ringo', 'age' => 28, - ), - array( + ], + [ 'name' => 'Paul', 'age' => 26, - ), - array( + ], + [ 'name' => 'Meredith', 'age' => 30, - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } @@ -332,20 +390,20 @@ public function testAllowEmpty() { $view = Views::getView('test_view'); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'id' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'id' => [ 'id' => 'id', 'table' => 'views_test_data', 'field' => 'id', 'relationship' => 'none', - ), - 'age' => array( + ], + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', - ), - )); + ], + ]); $view->initHandlers(); @@ -359,58 +417,65 @@ public function testAllowEmpty() { } protected function getGroupedExposedFilters() { - $filters = array( - 'age' => array( + $filters = [ + 'age' => [ 'id' => 'age', 'plugin_id' => 'numeric', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'age_op', 'label' => 'age', 'identifier' => 'age', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'age', 'identifier' => 'age', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Age is 28', 'operator' => '=', - 'value' => array('value' => 28), - ), - 2 => array( + 'value' => ['value' => 28], + ], + 2 => [ 'title' => 'Age is between 26 and 29', 'operator' => 'between', - 'value' => array( + 'value' => [ 'min' => 26, 'max' => 29, - ), - ), - 3 => array( + ], + ], + 3 => [ 'title' => 'Age is not between 26 and 29', 'operator' => 'not between', - 'value' => array( + 'value' => [ 'min' => 26, 'max' => 29, - ), - ), - 4 => array( + ], + ], + 4 => [ 'title' => 'Age is empty', 'operator' => 'empty', - ), - 5 => array( + ], + 5 => [ 'title' => 'Age is not empty', 'operator' => 'not empty', - ), - ), - ), - ), - ); + ], + 6 => [ + 'title' => 'Age is regexp 2[7-8]', + 'operator' => 'regular_expression', + 'value' => [ + 'value' => '2[7-8]', + ], + ], + ], + ], + ], + ]; return $filters; } diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php index 5dd47ecb..03c1b878 100644 --- a/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php @@ -12,25 +12,25 @@ */ class FilterStringTest extends ViewsKernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Map column names. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', - ); + ]; - function viewsData() { + public function viewsData() { $data = parent::viewsData(); $data['views_test_data']['name']['filter']['allow empty'] = TRUE; $data['views_test_data']['job']['filter']['allow empty'] = FALSE; @@ -39,14 +39,17 @@ function viewsData() { return $data; } + /** + * {@inheritdoc} + */ protected function schemaDefinition() { $schema = parent::schemaDefinition(); - $schema['views_test_data']['fields']['description'] = array( + $schema['views_test_data']['fields']['description'] = [ 'description' => "A person's description", 'type' => 'text', 'not null' => FALSE, 'size' => 'big', - ); + ]; return $schema; } @@ -81,32 +84,32 @@ protected function getBasicPageView() { return $view; } - function testFilterStringEqual() { + public function testFilterStringEqual() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => '=', 'value' => 'Ringo', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedEqual() { + public function testFilterStringGroupedExposedEqual() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -119,50 +122,50 @@ function testFilterStringGroupedExposedEqual() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringNotEqual() { + public function testFilterStringNotEqual() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => '!=', 'value' => 'Ringo', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Paul', - ), - array( + ], + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedNotEqual() { + public function testFilterStringGroupedExposedNotEqual() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -176,51 +179,51 @@ function testFilterStringGroupedExposedNotEqual() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Paul', - ), - array( + ], + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringContains() { + public function testFilterStringContains() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => 'contains', 'value' => 'ing', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedContains() { + public function testFilterStringGroupedExposedContains() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -233,41 +236,41 @@ function testFilterStringGroupedExposedContains() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringWord() { + public function testFilterStringWord() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'word', 'value' => 'actor', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); $view->destroy(); @@ -275,28 +278,64 @@ function testFilterStringWord() { $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'allwords', 'value' => 'Richard Starkey', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); + $view->destroy(); + + $view = Views::getView('test_view'); + $view->setDisplay(); + + // Change the filtering to a sting containing only illegal characters. + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ + 'id' => 'description', + 'table' => 'views_test_data', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'allwords', + 'value' => ':-)', + ], + ]); + + $this->executeView($view); + $resultset = [ + [ + 'name' => 'Ringo', + ], + [ + 'name' => 'John', + ], + [ + 'name' => 'George', + ], + [ + 'name' => 'Paul', + ], + [ + 'name' => 'Meredith', + ], + ]; + $this->assertIdenticalResultset($view, $resultset); } - function testFilterStringGroupedExposedWord() { + public function testFilterStringGroupedExposedWord() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -309,11 +348,11 @@ function testFilterStringGroupedExposedWord() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); $view->destroy(); @@ -327,43 +366,43 @@ function testFilterStringGroupedExposedWord() { $view->displayHandlers->get('page_1')->overrideOption('filters', $filters); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringStarts() { + public function testFilterStringStarts() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'starts', 'value' => 'George', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedStarts() { + public function testFilterStringGroupedExposedStarts() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -376,47 +415,47 @@ function testFilterStringGroupedExposedStarts() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringNotStarts() { + public function testFilterStringNotStarts() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'not_starts', 'value' => 'George', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Ringo', - ), - array( + ], + [ 'name' => 'Paul', - ), + ], // There is no Meredith returned because his description is empty - ); + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedNotStarts() { + public function testFilterStringGroupedExposedNotStarts() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -429,50 +468,50 @@ function testFilterStringGroupedExposedNotStarts() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Ringo', - ), - array( + ], + [ 'name' => 'Paul', - ), + ], // There is no Meredith returned because his description is empty - ); + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringEnds() { + public function testFilterStringEnds() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'ends', 'value' => 'Beatles.', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedEnds() { + public function testFilterStringGroupedExposedEnds() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -485,47 +524,47 @@ function testFilterStringGroupedExposedEnds() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'George', - ), - array( + ], + [ 'name' => 'Ringo', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringNotEnds() { + public function testFilterStringNotEnds() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'not_ends', 'value' => 'Beatles.', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Paul', - ), + ], // There is no Meredith returned because his description is empty - ); + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedNotEnds() { + public function testFilterStringGroupedExposedNotEnds() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -538,49 +577,49 @@ function testFilterStringGroupedExposedNotEnds() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Paul', - ), + ], // There is no Meredith returned because his description is empty - ); + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringNot() { + public function testFilterStringNot() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'not', 'value' => 'Beatles.', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Paul', - ), + ], // There is no Meredith returned because his description is empty - ); + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedNot() { + public function testFilterStringGroupedExposedNot() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -593,48 +632,48 @@ function testFilterStringGroupedExposedNot() { $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Paul', - ), + ], // There is no Meredith returned because his description is empty - ); + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringShorter() { + public function testFilterStringShorter() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => 'shorterthan', 'value' => 5, - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Paul', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedShorter() { + public function testFilterStringGroupedExposedShorter() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -646,43 +685,43 @@ function testFilterStringGroupedExposedShorter() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'John', - ), - array( + ], + [ 'name' => 'Paul', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringLonger() { + public function testFilterStringLonger() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'operator' => 'longerthan', 'value' => 7, - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedLonger() { + public function testFilterStringGroupedExposedLonger() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -694,40 +733,40 @@ function testFilterStringGroupedExposedLonger() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringEmpty() { + public function testFilterStringEmpty() { $view = Views::getView('test_view'); $view->setDisplay(); // Change the filtering - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'description' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'description' => [ 'id' => 'description', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'operator' => 'empty', - ), - )); + ], + ]); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } - function testFilterStringGroupedExposedEmpty() { + public function testFilterStringGroupedExposedEmpty() { $filters = $this->getGroupedExposedFilters(); $view = $this->getBasicPageView(); @@ -739,119 +778,119 @@ function testFilterStringGroupedExposedEmpty() { $this->container->get('router.builder')->rebuild(); $this->executeView($view); - $resultset = array( - array( + $resultset = [ + [ 'name' => 'Meredith', - ), - ); + ], + ]; $this->assertIdenticalResultset($view, $resultset, $this->columnMap); } protected function getGroupedExposedFilters() { - $filters = array( - 'name' => array( + $filters = [ + 'name' => [ 'id' => 'name', 'plugin_id' => 'string', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'name_op', 'label' => 'name', 'identifier' => 'name', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'name', 'identifier' => 'name', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Is Ringo', 'operator' => '=', 'value' => 'Ringo', - ), - 2 => array( + ], + 2 => [ 'title' => 'Is not Ringo', 'operator' => '!=', 'value' => 'Ringo', - ), - 3 => array( + ], + 3 => [ 'title' => 'Contains ing', 'operator' => 'contains', 'value' => 'ing', - ), - 4 => array( + ], + 4 => [ 'title' => 'Shorter than 5 letters', 'operator' => 'shorterthan', 'value' => 5, - ), - 5 => array( + ], + 5 => [ 'title' => 'Longer than 7 letters', 'operator' => 'longerthan', 'value' => 7, - ), - ), - ), - ), - 'description' => array( + ], + ], + ], + ], + 'description' => [ 'id' => 'description', 'plugin_id' => 'string', 'table' => 'views_test_data', 'field' => 'description', 'relationship' => 'none', 'exposed' => TRUE, - 'expose' => array( + 'expose' => [ 'operator' => 'description_op', 'label' => 'description', 'identifier' => 'description', - ), + ], 'is_grouped' => TRUE, - 'group_info' => array( + 'group_info' => [ 'label' => 'description', 'identifier' => 'description', 'default_group' => 'All', - 'group_items' => array( - 1 => array( + 'group_items' => [ + 1 => [ 'title' => 'Contains the word: Actor', 'operator' => 'word', 'value' => 'actor', - ), - 2 => array( + ], + 2 => [ 'title' => 'Starts with George', 'operator' => 'starts', 'value' => 'George', - ), - 3 => array( + ], + 3 => [ 'title' => 'Not Starts with: George', 'operator' => 'not_starts', 'value' => 'George', - ), - 4 => array( + ], + 4 => [ 'title' => 'Ends with: Beatles', 'operator' => 'ends', 'value' => 'Beatles.', - ), - 5 => array( + ], + 5 => [ 'title' => 'Not Ends with: Beatles', 'operator' => 'not_ends', 'value' => 'Beatles.', - ), - 6 => array( + ], + 6 => [ 'title' => 'Does not contain: Beatles', 'operator' => 'not', 'value' => 'Beatles.', - ), - 7 => array( + ], + 7 => [ 'title' => 'Empty description', 'operator' => 'empty', 'value' => '', - ), - ), - ), - ), - ); + ], + ], + ], + ], + ]; return $filters; } diff --git a/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php b/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php index 48f4e3d4..53d25b38 100644 --- a/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php @@ -12,14 +12,14 @@ */ class HandlerAliasTest extends ViewsKernelTestBase { - public static $modules = array('user'); + public static $modules = ['user']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_filter', 'test_alias'); + public static $testViews = ['test_filter', 'test_alias']; protected function setUp($import_test_views = TRUE) { parent::setUp(); @@ -45,16 +45,16 @@ public function testPluginAliases() { $view->initDisplay(); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_filter', 'table' => 'views_test_data_alias', 'field' => 'name_alias', 'operator' => '=', 'value' => 'John', 'group' => 0, - ), - )); + ], + ]); $this->executeView($view); diff --git a/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php b/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php index 4a137541..2d1a2fcc 100644 --- a/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php @@ -18,123 +18,123 @@ class SortDateTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; protected function expectedResultSet($granularity, $reverse = TRUE) { - $expected = array(); + $expected = []; if (!$reverse) { switch ($granularity) { case 'second': - $expected = array( - array('name' => 'John'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - array('name' => 'Ringo'), - array('name' => 'George'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ['name' => 'Ringo'], + ['name' => 'George'], + ]; break; case 'minute': - $expected = array( - array('name' => 'John'), - array('name' => 'Paul'), - array('name' => 'Ringo'), - array('name' => 'Meredith'), - array('name' => 'George'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'Paul'], + ['name' => 'Ringo'], + ['name' => 'Meredith'], + ['name' => 'George'], + ]; break; case 'hour': - $expected = array( - array('name' => 'John'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - array('name' => 'George'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ['name' => 'George'], + ]; break; case 'day': - $expected = array( - array('name' => 'John'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - array('name' => 'George'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ['name' => 'George'], + ]; break; case 'month': - $expected = array( - array('name' => 'John'), - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ]; break; case 'year': - $expected = array( - array('name' => 'John'), - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ]; break; } } else { switch ($granularity) { case 'second': - $expected = array( - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Meredith'), - array('name' => 'Paul'), - array('name' => 'John'), - ); + $expected = [ + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Meredith'], + ['name' => 'Paul'], + ['name' => 'John'], + ]; break; case 'minute': - $expected = array( - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Meredith'), - array('name' => 'Paul'), - array('name' => 'John'), - ); + $expected = [ + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Meredith'], + ['name' => 'Paul'], + ['name' => 'John'], + ]; break; case 'hour': - $expected = array( - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - array('name' => 'John'), - ); + $expected = [ + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ['name' => 'John'], + ]; break; case 'day': - $expected = array( - array('name' => 'George'), - array('name' => 'John'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - ); + $expected = [ + ['name' => 'George'], + ['name' => 'John'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ]; break; case 'month': - $expected = array( - array('name' => 'John'), - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ]; break; case 'year': - $expected = array( - array('name' => 'John'), - array('name' => 'George'), - array('name' => 'Ringo'), - array('name' => 'Paul'), - array('name' => 'Meredith'), - ); + $expected = [ + ['name' => 'John'], + ['name' => 'George'], + ['name' => 'Ringo'], + ['name' => 'Paul'], + ['name' => 'Meredith'], + ]; break; } } @@ -146,54 +146,54 @@ protected function expectedResultSet($granularity, $reverse = TRUE) { * Tests numeric ordering of the result set. */ public function testDateOrdering() { - foreach (array('second', 'minute', 'hour', 'day', 'month', 'year') as $granularity) { - foreach (array(FALSE, TRUE) as $reverse) { + foreach (['second', 'minute', 'hour', 'day', 'month', 'year'] as $granularity) { + foreach ([FALSE, TRUE] as $reverse) { $view = Views::getView('test_view'); $view->setDisplay(); // Change the fields. - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'name' => [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - ), - 'created' => array( + ], + 'created' => [ 'id' => 'created', 'table' => 'views_test_data', 'field' => 'created', 'relationship' => 'none', - ), - )); + ], + ]); // Change the ordering - $view->displayHandlers->get('default')->overrideOption('sorts', array( - 'created' => array( + $view->displayHandlers->get('default')->overrideOption('sorts', [ + 'created' => [ 'id' => 'created', 'table' => 'views_test_data', 'field' => 'created', 'relationship' => 'none', 'granularity' => $granularity, 'order' => $reverse ? 'DESC' : 'ASC', - ), - 'id' => array( + ], + 'id' => [ 'id' => 'id', 'table' => 'views_test_data', 'field' => 'id', 'relationship' => 'none', 'order' => 'ASC', - ), - )); + ], + ]); // Execute the view. $this->executeView($view); // Verify the result. $this->assertEqual(count($this->dataSet()), count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->expectedResultSet($granularity, $reverse), array( + $this->assertIdenticalResultset($view, $this->expectedResultSet($granularity, $reverse), [ 'views_test_data_name' => 'name', - ), SafeMarkup::format('Result is returned correctly when ordering by granularity @granularity, @reverse.', array('@granularity' => $granularity, '@reverse' => $reverse ? 'reverse' : 'forward'))); + ], SafeMarkup::format('Result is returned correctly when ordering by granularity @granularity, @reverse.', ['@granularity' => $granularity, '@reverse' => $reverse ? 'reverse' : 'forward'])); $view->destroy(); unset($view); } diff --git a/core/modules/views/tests/src/Kernel/Handler/SortRandomTest.php b/core/modules/views/tests/src/Kernel/Handler/SortRandomTest.php index 97b27073..941ed8d9 100644 --- a/core/modules/views/tests/src/Kernel/Handler/SortRandomTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/SortRandomTest.php @@ -19,7 +19,7 @@ class SortRandomTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Add more items to the test set, to make the order tests more robust. @@ -34,13 +34,13 @@ class SortRandomTest extends ViewsKernelTestBase { protected function dataSet() { $data = parent::dataSet(); for ($i = 0; $i < 55; $i++) { - $data[] = array( + $data[] = [ 'name' => 'name_' . $i, 'age' => $i, 'job' => 'job_' . $i, 'created' => rand(0, time()), 'status' => 1, - ); + ]; } return $data; } @@ -53,13 +53,13 @@ protected function getBasicRandomView() { $view->setDisplay(); // Add a random ordering. - $view->displayHandlers->get('default')->overrideOption('sorts', array( - 'random' => array( + $view->displayHandlers->get('default')->overrideOption('sorts', [ + 'random' => [ 'id' => 'random', 'field' => 'random', 'table' => 'views', - ), - )); + ], + ]); return $view; } @@ -76,28 +76,28 @@ public function testRandomOrdering() { // Verify the result. $this->assertEqual(count($this->dataSet()), count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->dataSet(), array( + $this->assertIdenticalResultset($view, $this->dataSet(), [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); // Execute a random view, we expect the result set to be different. $view_random = $this->getBasicRandomView(); $this->executeView($view_random); $this->assertEqual(count($this->dataSet()), count($view_random->result), 'The number of returned rows match.'); - $this->assertNotIdenticalResultset($view_random, $view->result, array( + $this->assertNotIdenticalResultset($view_random, $view->result, [ 'views_test_data_name' => 'views_test_data_name', 'views_test_data_age' => 'views_test_data_name', - )); + ]); // Execute a second random view, we expect the result set to be different again. $view_random_2 = $this->getBasicRandomView(); $this->executeView($view_random_2); $this->assertEqual(count($this->dataSet()), count($view_random_2->result), 'The number of returned rows match.'); - $this->assertNotIdenticalResultset($view_random, $view->result, array( + $this->assertNotIdenticalResultset($view_random, $view->result, [ 'views_test_data_name' => 'views_test_data_name', 'views_test_data_age' => 'views_test_data_name', - )); + ]); } /** diff --git a/core/modules/views/tests/src/Kernel/Handler/SortTest.php b/core/modules/views/tests/src/Kernel/Handler/SortTest.php index 38cbcd1a..91560495 100644 --- a/core/modules/views/tests/src/Kernel/Handler/SortTest.php +++ b/core/modules/views/tests/src/Kernel/Handler/SortTest.php @@ -17,7 +17,7 @@ class SortTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Tests numeric ordering of the result set. @@ -27,49 +27,49 @@ public function testNumericOrdering() { $view->setDisplay(); // Change the ordering - $view->displayHandlers->get('default')->overrideOption('sorts', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('sorts', [ + 'age' => [ 'order' => 'ASC', 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', - ), - )); + ], + ]); // Execute the view. $this->executeView($view); // Verify the result. $this->assertEqual(count($this->dataSet()), count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'age'), array( + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'age'), [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); $view->destroy(); $view->setDisplay(); // Reverse the ordering - $view->displayHandlers->get('default')->overrideOption('sorts', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('sorts', [ + 'age' => [ 'order' => 'DESC', 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', - ), - )); + ], + ]); // Execute the view. $this->executeView($view); // Verify the result. $this->assertEqual(count($this->dataSet()), count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'age', TRUE), array( + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'age', TRUE), [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); } /** @@ -80,49 +80,49 @@ public function testStringOrdering() { $view->setDisplay(); // Change the ordering - $view->displayHandlers->get('default')->overrideOption('sorts', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('sorts', [ + 'name' => [ 'order' => 'ASC', 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - ), - )); + ], + ]); // Execute the view. $this->executeView($view); // Verify the result. $this->assertEqual(count($this->dataSet()), count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'name'), array( + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'name'), [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); $view->destroy(); $view->setDisplay(); // Reverse the ordering - $view->displayHandlers->get('default')->overrideOption('sorts', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('sorts', [ + 'name' => [ 'order' => 'DESC', 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'relationship' => 'none', - ), - )); + ], + ]); // Execute the view. $this->executeView($view); // Verify the result. $this->assertEqual(count($this->dataSet()), count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'name', TRUE), array( + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'name', TRUE), [ 'views_test_data_name' => 'name', 'views_test_data_age' => 'age', - )); + ]); } } diff --git a/core/modules/views/tests/src/Kernel/Handler/SortTranslationTest.php b/core/modules/views/tests/src/Kernel/Handler/SortTranslationTest.php new file mode 100644 index 00000000..e49ef7a2 --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/SortTranslationTest.php @@ -0,0 +1,152 @@ +save(); + $this->installSchema('node', 'node_access'); + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + + // $this->installConfig('node'); + $this->container->get('kernel')->rebuildContainer(); + + $node_type = NodeType::create(['type' => 'article']); + $node_type->save(); + + FieldStorageConfig::create([ + 'field_name' => 'text', + 'entity_type' => 'node', + 'type' => 'string', + ])->save(); + + FieldConfig::create([ + 'field_name' => 'text', + 'entity_type' => 'node', + 'bundle' => 'article', + 'label' => 'Translated text', + 'translatable' => TRUE + ])->save(); + + FieldStorageConfig::create([ + 'field_name' => 'weight', + 'entity_type' => 'node', + 'type' => 'integer', + ])->save(); + + FieldConfig::create([ + 'field_name' => 'weight', + 'entity_type' => 'node', + 'bundle' => 'article', + 'translatable' => FALSE, + ])->save(); + + for ($i = 0; $i < 3; $i++) { + $node = Node::create([ + 'type' => 'article', + 'title' => 'Title en ' . $i, + 'weight' => ['value' => 3 - $i], + 'text' => ['value' => 'moo en ' . $i], + 'langcode' => 'en', + ]); + $node->save(); + + $translation = $node->addTranslation('de'); + $translation->title->value = 'Title DE ' . $i; + $translation->text->value = 'moo DE ' . $i; + $translation->save(); + $nodes[] = $node; + } + } + + /** + * Test sorting on an untranslated field. + */ + public function testSortbyUntranslatedIntegerField() { + $map = [ + 'nid' => 'nid', + 'node_field_data_langcode' => 'langcode', + ]; + + $view = Views::getView('test_view_sort_translation'); + $view->setDisplay('default'); + $this->executeView($view); + + // With ascending sort, the nodes should come out in reverse order. + $expected = [ + [ + 'nid' => 3, + 'langcode' => 'en', + ], + [ + 'nid' => 2, + 'langcode' => 'en', + ], + [ + 'nid' => 1, + 'langcode' => 'en', + ], + ]; + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + + $view = Views::getView('test_view_sort_translation'); + $view->setDisplay('display_de'); + $this->executeView($view); + + $expected = [ + [ + 'nid' => 3, + 'langcode' => 'de', + ], + [ + 'nid' => 2, + 'langcode' => 'de', + ], + [ + 'nid' => 1, + 'langcode' => 'de', + ], + ]; + + // The weight field is not translated, we sort by it so the nodes + // should come out in the same order in both languages. + $this->assertIdenticalResultset($view, $expected, $map); + $view->destroy(); + } + +} diff --git a/core/modules/views/tests/src/Kernel/ModuleTest.php b/core/modules/views/tests/src/Kernel/ModuleTest.php index 204433dc..9fe9df64 100644 --- a/core/modules/views/tests/src/Kernel/ModuleTest.php +++ b/core/modules/views/tests/src/Kernel/ModuleTest.php @@ -19,7 +19,7 @@ class ModuleTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view_status', 'test_view', 'test_argument'); + public static $testViews = ['test_view_status', 'test_view', 'test_argument']; /** * Modules to enable. @@ -43,27 +43,27 @@ class ModuleTest extends ViewsKernelTestBase { * @see views_get_handler() */ public function testViewsGetHandler() { - $types = array('field', 'area', 'filter'); + $types = ['field', 'area', 'filter']; foreach ($types as $type) { - $item = array( + $item = [ 'table' => $this->randomMachineName(), 'field' => $this->randomMachineName(), - ); + ]; $handler = $this->container->get('plugin.manager.views.' . $type)->getHandler($item); $this->assertEqual('Drupal\views\Plugin\views\\' . $type . '\Broken', get_class($handler), new FormattableMarkup('Make sure that a broken handler of type: @type is created.', ['@type' => $type])); } $views_data = $this->viewsData(); - $test_tables = array('views_test_data' => array('id', 'name')); + $test_tables = ['views_test_data' => ['id', 'name']]; foreach ($test_tables as $table => $fields) { foreach ($fields as $field) { $data = $views_data[$table][$field]; - $item = array( + $item = [ 'table' => $table, 'field' => $field, - ); + ]; foreach ($data as $id => $field_data) { - if (!in_array($id, array('title', 'help'))) { + if (!in_array($id, ['title', 'help'])) { $handler = $this->container->get('plugin.manager.views.' . $id)->getHandler($item); $this->assertInstanceHandler($handler, $table, $field, $id); } @@ -72,10 +72,10 @@ public function testViewsGetHandler() { } // Test the override handler feature. - $item = array( + $item = [ 'table' => 'views_test_data', 'field' => 'job', - ); + ]; $handler = $this->container->get('plugin.manager.views.filter')->getHandler($item, 'standard'); $this->assertTrue($handler instanceof Standard); @@ -84,29 +84,29 @@ public function testViewsGetHandler() { return; // Test non-existent tables/fields. - set_error_handler(array($this, 'customErrorHandler')); - $item = array( + set_error_handler([$this, 'customErrorHandler']); + $item = [ 'table' => 'views_test_data', 'field' => 'field_invalid', - ); + ]; $this->container->get('plugin.manager.views.field')->getHandler($item); - $this->assertTrue(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'views_test_data', '@field' => 'field_invalid', '@type' => 'field'))) !== FALSE, 'An invalid field name throws a debug message.'); + $this->assertTrue(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", ['@table' => 'views_test_data', '@field' => 'field_invalid', '@type' => 'field'])) !== FALSE, 'An invalid field name throws a debug message.'); unset($this->lastErrorMessage); - $item = array( + $item = [ 'table' => 'table_invalid', 'field' => 'id', - ); + ]; $this->container->get('plugin.manager.views.filter')->getHandler($item); - $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.'); + $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", ['@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'])) !== FALSE, 'An invalid table name throws a debug message.'); unset($this->lastErrorMessage); - $item = array( + $item = [ 'table' => 'table_invalid', 'field' => 'id', - ); + ]; $this->container->get('plugin.manager.views.filter')->getHandler($item); - $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", array('@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'))) !== FALSE, 'An invalid table name throws a debug message.'); + $this->assertEqual(strpos($this->lastErrorMessage, format_string("Missing handler: @table @field @type", ['@table' => 'table_invalid', '@field' => 'id', '@type' => 'filter'])) !== FALSE, 'An invalid table name throws a debug message.'); unset($this->lastErrorMessage); restore_error_handler(); @@ -139,8 +139,8 @@ public function customErrorHandler($error_level, $message, $filename, $line, $co * Tests the load wrapper/helper functions. */ public function testLoadFunctions() { - $this->enableModules(array('text', 'node')); - $this->installConfig(array('node')); + $this->enableModules(['text', 'node']); + $this->installConfig(['node']); $storage = $this->container->get('entity.manager')->getStorage('view'); // Test views_view_is_enabled/disabled. @@ -158,13 +158,13 @@ public function testLoadFunctions() { $this->assertEquals(array_keys($all_views), array_keys(Views::getAllViews()), 'Views::getAllViews works as expected.'); // Test Views::getEnabledViews(). - $expected_enabled = array_filter($all_views, function($view) { + $expected_enabled = array_filter($all_views, function ($view) { return views_view_is_enabled($view); }); $this->assertEquals(array_keys($expected_enabled), array_keys(Views::getEnabledViews()), 'Expected enabled views returned.'); // Test Views::getDisabledViews(). - $expected_disabled = array_filter($all_views, function($view) { + $expected_disabled = array_filter($all_views, function ($view) { return views_view_is_disabled($view); }); $this->assertEquals(array_keys($expected_disabled), array_keys(Views::getDisabledViews()), 'Expected disabled views returned.'); @@ -172,7 +172,7 @@ public function testLoadFunctions() { // Test Views::getViewsAsOptions(). // Test the $views_only parameter. $this->assertIdentical(array_keys($all_views), array_keys(Views::getViewsAsOptions(TRUE)), 'Expected option keys for all views were returned.'); - $expected_options = array(); + $expected_options = []; foreach ($all_views as $id => $view) { $expected_options[$id] = $view->label(); } @@ -196,10 +196,10 @@ public function testLoadFunctions() { $this->assertFalse(array_key_exists('archive', Views::getViewsAsOptions(TRUE, 'all', $archive->getExecutable())), 'View excluded from options based on object'); // Test the $opt_group parameter. - $expected_opt_groups = array(); + $expected_opt_groups = []; foreach ($all_views as $view) { foreach ($view->get('display') as $display) { - $expected_opt_groups[$view->id()][$view->id() . ':' . $display['id']] = (string) t('@view : @display', array('@view' => $view->id(), '@display' => $display['id'])); + $expected_opt_groups[$view->id()][$view->id() . ':' . $display['id']] = (string) t('@view : @display', ['@view' => $view->id(), '@display' => $display['id']]); } } $this->assertIdentical($expected_opt_groups, $this->castSafeStrings(Views::getViewsAsOptions(FALSE, 'all', NULL, TRUE)), 'Expected option array for an option group returned.'); @@ -208,7 +208,7 @@ public function testLoadFunctions() { /** * Tests view enable and disable procedural wrapper functions. */ - function testStatusFunctions() { + public function testStatusFunctions() { $view = Views::getView('test_view_status')->storage; $this->assertFalse($view->status(), 'The view status is disabled.'); @@ -229,7 +229,7 @@ public function testViewsFetchPluginNames() { // All style plugins should be returned, as we have not specified a type. $plugins = Views::fetchPluginNames('style'); $definitions = $this->container->get('plugin.manager.views.style')->getDefinitions(); - $expected = array(); + $expected = []; foreach ($definitions as $id => $definition) { $expected[$id] = $definition['title']; } @@ -239,11 +239,11 @@ public function testViewsFetchPluginNames() { // Test using the 'test' style plugin type only returns the test_style and // mapping_test plugins. $plugins = Views::fetchPluginNames('style', 'test'); - $this->assertIdentical(array_keys($plugins), array('mapping_test', 'test_style', 'test_template_style')); + $this->assertIdentical(array_keys($plugins), ['mapping_test', 'test_style', 'test_template_style']); // Test a non existent style plugin type returns no plugins. $plugins = Views::fetchPluginNames('style', $this->randomString()); - $this->assertIdentical($plugins, array()); + $this->assertIdentical($plugins, []); } /** @@ -252,11 +252,11 @@ public function testViewsFetchPluginNames() { public function testViewsPluginList() { $plugin_list = Views::pluginList(); // Only plugins used by 'test_view' should be in the plugin list. - foreach (array('display:default', 'pager:none') as $key) { + foreach (['display:default', 'pager:none'] as $key) { list($plugin_type, $plugin_id) = explode(':', $key); $plugin_def = $this->container->get("plugin.manager.views.$plugin_type")->getDefinition($plugin_id); - $this->assertTrue(isset($plugin_list[$key]), SafeMarkup::format('The expected @key plugin list key was found.', array('@key' => $key))); + $this->assertTrue(isset($plugin_list[$key]), SafeMarkup::format('The expected @key plugin list key was found.', ['@key' => $key])); $plugin_details = $plugin_list[$key]; $this->assertEqual($plugin_details['type'], $plugin_type, 'The expected plugin type was found.'); @@ -303,35 +303,35 @@ public function testViewsPreview() { $this->assertEqual(count($result['#view']->result), 5); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('0' => 1)); + $result = $view->preview('default', ['0' => 1]); $this->assertEqual(count($result['#view']->result), 1); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('3' => 1)); + $result = $view->preview('default', ['3' => 1]); $this->assertEqual(count($result['#view']->result), 1); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('0' => '1,2')); + $result = $view->preview('default', ['0' => '1,2']); $this->assertEqual(count($result['#view']->result), 2); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('3' => '1,2')); + $result = $view->preview('default', ['3' => '1,2']); $this->assertEqual(count($result['#view']->result), 2); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('0' => '1,2', '1' => 'John')); + $result = $view->preview('default', ['0' => '1,2', '1' => 'John']); $this->assertEqual(count($result['#view']->result), 1); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('3' => '1,2', '4' => 'John')); + $result = $view->preview('default', ['3' => '1,2', '4' => 'John']); $this->assertEqual(count($result['#view']->result), 1); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('0' => '1,2', '1' => 'John,George')); + $result = $view->preview('default', ['0' => '1,2', '1' => 'John,George']); $this->assertEqual(count($result['#view']->result), 2); $view = Views::getView('test_argument'); - $result = $view->preview('default', array('3' => '1,2', '4' => 'John,George')); + $result = $view->preview('default', ['3' => '1,2', '4' => 'John,George']); $this->assertEqual(count($result['#view']->result), 2); } @@ -345,12 +345,12 @@ public function testViewsPreview() { * @return array * A formatted options array that matches the expected output. */ - protected function formatViewOptions(array $views = array()) { - $expected_options = array(); + protected function formatViewOptions(array $views = []) { + $expected_options = []; foreach ($views as $view) { foreach ($view->get('display') as $display) { $expected_options[$view->id() . ':' . $display['id']] = (string) t('View: @view - Display: @display', - array('@view' => $view->id(), '@display' => $display['id'])); + ['@view' => $view->id(), '@display' => $display['id']]); } } @@ -360,7 +360,7 @@ protected function formatViewOptions(array $views = array()) { /** * Ensure that a certain handler is a instance of a certain table/field. */ - function assertInstanceHandler($handler, $table, $field, $id) { + public function assertInstanceHandler($handler, $table, $field, $id) { $table_data = $this->container->get('views.views_data')->get($table); $field_data = $table_data[$field][$id]; diff --git a/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php b/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php index cac79855..34d426dc 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php @@ -20,7 +20,7 @@ class ArgumentValidatorTest extends ViewsKernelTestBase { */ public static $testViews = ['test_view_argument_validate_numeric', 'test_view']; - function testArgumentValidateNumeric() { + public function testArgumentValidateNumeric() { $view = Views::getView('test_view_argument_validate_numeric'); $view->initHandlers(); $this->assertFalse($view->argument['null']->validateArgument($this->randomString())); diff --git a/core/modules/views/tests/src/Kernel/Plugin/BlockDependenciesTest.php b/core/modules/views/tests/src/Kernel/Plugin/BlockDependenciesTest.php index 6b5de6e6..1a9f32ef 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/BlockDependenciesTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/BlockDependenciesTest.php @@ -17,14 +17,14 @@ class BlockDependenciesTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_exposed_block'); + public static $testViews = ['test_exposed_block']; /** * Modules to enable. * * @var array */ - public static $modules = array('node', 'block', 'user', 'field'); + public static $modules = ['node', 'block', 'user', 'field']; /** * Tests that exposed filter blocks have the correct dependencies. @@ -34,11 +34,11 @@ class BlockDependenciesTest extends ViewsKernelTestBase { public function testExposedBlock() { $block = $this->createBlock('views_exposed_filter_block:test_exposed_block-page_1'); $dependencies = $block->calculateDependencies()->getDependencies(); - $expected = array( - 'config' => array('views.view.test_exposed_block'), - 'module' => array('views'), - 'theme' => array('stark') - ); + $expected = [ + 'config' => ['views.view.test_exposed_block'], + 'module' => ['views'], + 'theme' => ['stark'] + ]; $this->assertIdentical($expected, $dependencies); } @@ -50,11 +50,11 @@ public function testExposedBlock() { public function testViewsBlock() { $block = $this->createBlock('views_block:content_recent-block_1'); $dependencies = $block->calculateDependencies()->getDependencies(); - $expected = array( - 'config' => array('views.view.content_recent'), - 'module' => array('views'), - 'theme' => array('stark') - ); + $expected = [ + 'config' => ['views.view.content_recent'], + 'module' => ['views'], + 'theme' => ['stark'] + ]; $this->assertIdentical($expected, $dependencies); } @@ -82,18 +82,18 @@ public function testViewsBlock() { * @return \Drupal\block\Entity\Block * The block entity. */ - protected function createBlock($plugin_id, array $settings = array()) { - $settings += array( + protected function createBlock($plugin_id, array $settings = []) { + $settings += [ 'plugin' => $plugin_id, 'region' => 'sidebar_first', 'id' => strtolower($this->randomMachineName(8)), 'theme' => $this->config('system.theme')->get('default'), 'label' => $this->randomMachineName(8), - 'visibility' => array(), + 'visibility' => [], 'weight' => 0, - ); + ]; $values = []; - foreach (array('region', 'id', 'theme', 'plugin', 'weight', 'visibility') as $key) { + foreach (['region', 'id', 'theme', 'plugin', 'weight', 'visibility'] as $key) { $values[$key] = $settings[$key]; // Remove extra values that do not belong in the settings array. unset($settings[$key]); diff --git a/core/modules/views/tests/src/Kernel/Plugin/CacheTest.php b/core/modules/views/tests/src/Kernel/Plugin/CacheTest.php index 31805d8d..9f6066ef 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/CacheTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/CacheTest.php @@ -21,14 +21,14 @@ class CacheTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view', 'test_cache', 'test_groupwise_term_ui', 'test_display', 'test_filter'); + public static $testViews = ['test_view', 'test_cache', 'test_groupwise_term_ui', 'test_display', 'test_filter']; /** * Modules to enable. * * @var array */ - public static $modules = array('taxonomy', 'text', 'user', 'node'); + public static $modules = ['taxonomy', 'text', 'user', 'node']; /** * {@inheritdoc} @@ -70,13 +70,13 @@ protected function viewsData() { public function testTimeResultCaching() { $view = Views::getView('test_cache'); $view->setDisplay(); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'time', - 'options' => array( + 'options' => [ 'results_lifespan' => '3600', 'output_lifespan' => '3600', - ) - )); + ] + ]); // Test the default (non-paged) display. $this->executeView($view); @@ -84,11 +84,11 @@ public function testTimeResultCaching() { $this->assertEqual(5, count($view->result), 'The number of returned rows match.'); // Add another man to the beatles. - $record = array( + $record = [ 'name' => 'Rod Davis', 'age' => 29, 'job' => 'Banjo', - ); + ]; db_insert('views_test_data')->fields($record)->execute(); // The result should be the same as before, because of the caching. (Note @@ -112,25 +112,25 @@ public function testTimeResultCachingWithFilter() { $view = Views::getView('test_filter'); $view->initDisplay(); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'time', - 'options' => array( + 'options' => [ 'results_lifespan' => '3600', 'output_lifespan' => '3600', - ), - )); + ], + ]); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_filter', 'table' => 'views_test_data', 'field' => 'name', 'operator' => '=', 'value' => 'John', 'group' => 0, - ), - )); + ], + ]); $this->executeView($view); @@ -138,29 +138,29 @@ public function testTimeResultCachingWithFilter() { $cid1 = $view->display_handler->getPlugin('cache')->generateResultsKey(); // Build the expected result. - $dataset = array(array('name' => 'John')); + $dataset = [['name' => 'John']]; // Verify the result. $this->assertEqual(1, count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultSet($view, $dataset, array( + $this->assertIdenticalResultSet($view, $dataset, [ 'views_test_data_name' => 'name', - )); + ]); $view->destroy(); $view->initDisplay(); // Change the filtering. - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'test_filter' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'test_filter' => [ 'id' => 'test_filter', 'table' => 'views_test_data', 'field' => 'name', 'operator' => '=', 'value' => 'Ringo', 'group' => 0, - ), - )); + ], + ]); $this->executeView($view); @@ -169,13 +169,13 @@ public function testTimeResultCachingWithFilter() { $this->assertNotEqual($cid1, $cid2, "Results keys are different."); // Build the expected result. - $dataset = array(array('name' => 'Ringo')); + $dataset = [['name' => 'Ringo']]; // Verify the result. $this->assertEqual(1, count($view->result), 'The number of returned rows match.'); - $this->assertIdenticalResultSet($view, $dataset, array( + $this->assertIdenticalResultSet($view, $dataset, [ 'views_test_data_name' => 'name', - )); + ]); } /** @@ -184,13 +184,13 @@ public function testTimeResultCachingWithFilter() { public function testTimeResultCachingWithPager() { $view = Views::getView('test_cache'); $view->setDisplay(); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'time', - 'options' => array( + 'options' => [ 'results_lifespan' => '3600', 'output_lifespan' => '3600', - ) - )); + ] + ]); $mapping = ['views_test_data_name' => 'name']; @@ -224,34 +224,34 @@ public function testTimeResultCachingWithPager() { * * @see views_plugin_cache_time */ - function testNoneResultCaching() { + public function testNoneResultCaching() { // Create a basic result which just 2 results. $view = Views::getView('test_cache'); $view->setDisplay(); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'none', - 'options' => array(), - )); + 'options' => [], + ]); $this->executeView($view); // Verify the result. $this->assertEqual(5, count($view->result), 'The number of returned rows match.'); // Add another man to the beatles. - $record = array( + $record = [ 'name' => 'Rod Davis', 'age' => 29, 'job' => 'Banjo', - ); + ]; db_insert('views_test_data')->fields($record)->execute(); // The Result changes, because the view is not cached. $view = Views::getView('test_cache'); $view->setDisplay(); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'none', - 'options' => array(), - )); + 'options' => [], + ]); $this->executeView($view); // Verify the result. @@ -261,19 +261,19 @@ function testNoneResultCaching() { /** * Tests css/js storage and restoring mechanism. */ - function testHeaderStorage() { + public function testHeaderStorage() { // Create a view with output caching enabled. // Some hook_views_pre_render in views_test_data.module adds the test css/js file. // so they should be added to the css/js storage. $view = Views::getView('test_view'); $view->setDisplay(); $view->storage->set('id', 'test_cache_header_storage'); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'time', - 'options' => array( + 'options' => [ 'output_lifespan' => '3600', - ) - )); + ] + ]); $output = $view->buildRenderable(); /** @var \Drupal\Core\Render\RendererInterface $renderer */ @@ -326,13 +326,13 @@ public function testCacheData() { $view = Views::getView('test_display'); $view->setDisplay(); - $view->display_handler->overrideOption('cache', array( + $view->display_handler->overrideOption('cache', [ 'type' => 'time', - 'options' => array( + 'options' => [ 'results_lifespan' => '3600', 'output_lifespan' => '3600', - ) - )); + ] + ]); $this->executeView($view); // Get the cache item. @@ -383,4 +383,30 @@ public function testCacheContextIntegration() { $this->assertIdenticalResultset($view, [['name' => 'Paul']], $map); } + /** + * Tests that cacheability metadata is carried over from argument defaults. + */ + public function testArgumentDefaultCache() { + $view = Views::getView('test_view'); + + // Add a new argument and set the test plugin for the argument_default. + $options = [ + 'default_argument_type' => 'argument_default_test', + 'default_argument_options' => [ + 'value' => 'John' + ], + 'default_action' => 'default' + ]; + $view->addHandler('default', 'argument', 'views_test_data', 'name', $options); + $view->initHandlers(); + + $output = $view->preview(); + + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = \Drupal::service('renderer'); + + $renderer->renderPlain($output); + $this->assertEquals(['config:views.view.test_view', 'example_tag'], $output['#cache']['tags']); + } + } diff --git a/core/modules/views/tests/src/Kernel/Plugin/Display/ViewsMenuLinkTest.php b/core/modules/views/tests/src/Kernel/Plugin/Display/ViewsMenuLinkTest.php index 9e05ebcf..d08adaac 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/Display/ViewsMenuLinkTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/Display/ViewsMenuLinkTest.php @@ -30,7 +30,7 @@ class ViewsMenuLinkTest extends ViewsKernelTestBase { * * @var \Drupal\Core\Entity\EntityManagerInterface */ - protected $entityManger; + protected $entityManager; /** * The menu link manager. @@ -52,7 +52,7 @@ class ViewsMenuLinkTest extends ViewsKernelTestBase { protected function setUp($import_test_views = TRUE) { parent::setUp($import_test_views); - $this->entityManger = $this->container->get('entity.manager'); + $this->entityManager = $this->container->get('entity.manager'); $this->menuLinkManager = $this->container->get('plugin.manager.menu.link'); $this->menuLinkOverrides = $this->container->get('menu_link.static.overrides'); } diff --git a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php similarity index 79% rename from core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php rename to core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php index 33c3713c..6f7154d1 100644 --- a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php @@ -1,7 +1,8 @@ enableViewsTestModule(); - } + public static $testViews = ['test_view']; /** * Test display extenders. */ public function testDisplayExtenders() { - $this->config('views.settings')->set('display_extenders', array('display_extender_test'))->save(); + $this->config('views.settings')->set('display_extenders', ['display_extender_test'])->save(); $this->assertEqual(count(Views::getEnabledDisplayExtenders()), 1, 'Make sure that there is only one enabled display extender.'); $view = Views::getView('test_view'); diff --git a/core/modules/views/tests/src/Kernel/Plugin/DisplayKernelTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayKernelTest.php index 156b0611..69666cf3 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/DisplayKernelTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayKernelTest.php @@ -24,14 +24,14 @@ class DisplayKernelTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('block', 'node', 'field', 'user'); + public static $modules = ['block', 'node', 'field', 'user']; /** * Views plugin types to test. * * @var array */ - protected $pluginTypes = array( + protected $pluginTypes = [ 'access', 'cache', 'query', @@ -39,24 +39,24 @@ class DisplayKernelTest extends ViewsKernelTestBase { 'pager', 'style', 'row', - ); + ]; /** * Views handler types to test. * * @var array */ - protected $handlerTypes = array( + protected $handlerTypes = [ 'fields', 'sorts', - ); + ]; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_display_defaults'); + public static $testViews = ['test_display_defaults']; /** * Tests the default display options. diff --git a/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php index 5e4724a8..3232ecb8 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php @@ -4,6 +4,7 @@ use Drupal\Core\Menu\MenuTreeParameters; use Drupal\Core\Session\AnonymousUserSession; +use Drupal\views\Entity\View; use Drupal\views\Views; use Drupal\Tests\views\Kernel\ViewsKernelTestBase; use Symfony\Component\HttpFoundation\Request; @@ -22,14 +23,14 @@ class DisplayPageTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_page_display', 'test_page_display_route', 'test_page_display_menu'); + public static $testViews = ['test_page_display', 'test_page_display_route', 'test_page_display_menu', 'test_display_more']; /** * Modules to enable. * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; /** * The router dumper to get all routes. @@ -149,4 +150,71 @@ public function testDependencies() { $this->assertIdentical($expected, $view->getDependencies()); } + /** + * Tests the readmore functionality. + */ + public function testReadMore() { + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = $this->container->get('renderer'); + + $expected_more_text = 'custom more text'; + + $view = Views::getView('test_display_more'); + $this->executeView($view); + + $output = $view->preview(); + $output = $renderer->renderRoot($output); + + $this->setRawContent($output); + $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']); + $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.'); + $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.'); + + // Test the renderMoreLink method directly. This could be directly unit + // tested. + $more_link = $view->display_handler->renderMoreLink(); + $more_link = $renderer->renderRoot($more_link); + $this->setRawContent($more_link); + $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']); + $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.'); + $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.'); + + // Test the useMoreText method directly. This could be directly unit + // tested. + $more_text = $view->display_handler->useMoreText(); + $this->assertEqual($more_text, $expected_more_text, 'The right more text is chosen.'); + + $view = Views::getView('test_display_more'); + $view->setDisplay(); + $view->display_handler->setOption('use_more', 0); + $this->executeView($view); + $output = $view->preview(); + $output = $renderer->renderRoot($output); + $this->setRawContent($output); + $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']); + $this->assertTrue(empty($result), 'The more link is not shown.'); + + $view = Views::getView('test_display_more'); + $view->setDisplay(); + $view->display_handler->setOption('use_more', 0); + $view->display_handler->setOption('use_more_always', 0); + $view->display_handler->setOption('pager', [ + 'type' => 'some', + 'options' => [ + 'items_per_page' => 1, + 'offset' => 0, + ], + ]); + $this->executeView($view); + $output = $view->preview(); + $output = $renderer->renderRoot($output); + $this->setRawContent($output); + $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']); + $this->assertTrue(empty($result), 'The more link is not shown when view has more records.'); + + // Test the default value of use_more_always. + $view = View::create()->getExecutable(); + $this->assertTrue($view->getDisplay()->getOption('use_more_always'), 'Always display the more link by default.'); + } + } diff --git a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php new file mode 100644 index 00000000..6767fffe --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php @@ -0,0 +1,55 @@ +installEntitySchema('node'); + } + + /** + * Tests the exposed form markup. + */ + public function testExposedFormRender() { + $view = Views::getView('test_exposed_form_buttons'); + $this->executeView($view); + $exposed_form = $view->display_handler->getPlugin('exposed_form'); + $output = $exposed_form->renderExposedForm(); + $this->setRawContent(\Drupal::service('renderer')->renderRoot($output)); + + $this->assertFieldByXpath('//form/@id', Html::cleanCssIdentifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display), 'Expected form ID found.'); + + $view->setDisplay('page_1'); + $expected_action = $view->display_handler->getUrlInfo()->toString(); + $this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.'); + // Make sure the description is shown. + $result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', [':id' => 'edit-type--description', ':description' => t('Exposed description')]); + $this->assertEqual(count($result), 1, 'Filter description was found.'); + } + +} diff --git a/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php b/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php new file mode 100644 index 00000000..940ab7ac --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php @@ -0,0 +1,209 @@ +manager = $this->container->get('plugin.manager.views.join'); + } + + /** + * Tests base join functionality. + * + * This duplicates parts of + * \Drupal\Tests\views\Kernel\Plugin\JoinTest::testBasePlugin() to ensure that + * no functionality provided by the base join plugin is broken. + */ + public function testBase() { + // Setup a simple join and test the result sql. + $view = Views::getView('test_view'); + $view->initDisplay(); + $view->initQuery(); + + // First define a simple join without an extra condition. + // Set the various options on the join object. + $configuration = [ + 'left_table' => 'views_test_data', + 'left_field' => 'uid', + 'table' => 'users_field_data', + 'field' => 'uid', + 'adjusted' => TRUE, + ]; + $join = $this->manager->createInstance($this->pluginId, $configuration); + $this->assertTrue($join instanceof FieldOrLanguageJoin); + $this->assertNull($join->extra); + $this->assertTrue($join->adjusted); + + $join_info = $this->buildJoin($view, $configuration, 'users_field_data'); + $this->assertSame($join_info['join type'], 'LEFT'); + $this->assertSame($join_info['table'], $configuration['table']); + $this->assertSame($join_info['alias'], 'users_field_data'); + $this->assertSame($join_info['condition'], 'views_test_data.uid = users_field_data.uid'); + + // Set a different alias and make sure table info is as expected. + $join_info = $this->buildJoin($view, $configuration, 'users1'); + $this->assertSame($join_info['alias'], 'users1'); + + // Set a different join type (INNER) and make sure it is used. + $configuration['type'] = 'INNER'; + $join_info = $this->buildJoin($view, $configuration, 'users2'); + $this->assertSame($join_info['join type'], 'INNER'); + + // Setup addition conditions and make sure it is used. + $random_name_1 = $this->randomMachineName(); + $random_name_2 = $this->randomMachineName(); + $configuration['extra'] = [ + [ + 'field' => 'name', + 'value' => $random_name_1 + ], + [ + 'field' => 'name', + 'value' => $random_name_2, + 'operator' => '<>' + ], + ]; + $join_info = $this->buildJoin($view, $configuration, 'users3'); + $this->assertContains('views_test_data.uid = users3.uid', $join_info['condition']); + $this->assertContains('users3.name = :views_join_condition_0', $join_info['condition']); + $this->assertContains('users3.name <> :views_join_condition_1', $join_info['condition']); + $this->assertSame(array_values($join_info['arguments']), [$random_name_1, $random_name_2]); + + // Test that 'IN' conditions are properly built. + $random_name_1 = $this->randomMachineName(); + $random_name_2 = $this->randomMachineName(); + $random_name_3 = $this->randomMachineName(); + $random_name_4 = $this->randomMachineName(); + $configuration['extra'] = [ + [ + 'field' => 'name', + 'value' => $random_name_1 + ], + [ + 'field' => 'name', + 'value' => [$random_name_2, $random_name_3, $random_name_4], + ], + ]; + $join_info = $this->buildJoin($view, $configuration, 'users4'); + $this->assertContains('views_test_data.uid = users4.uid', $join_info['condition']); + $this->assertContains('users4.name = :views_join_condition_0', $join_info['condition']); + $this->assertContains('users4.name IN ( :views_join_condition_1[] )', $join_info['condition']); + $this->assertSame($join_info['arguments'][':views_join_condition_1[]'], [$random_name_2, $random_name_3, $random_name_4]); + } + + /** + * Tests the adding of conditions by the join plugin. + */ + public function testLanguageBundleConditions() { + // Setup a simple join and test the result sql. + $view = Views::getView('test_view'); + $view->initDisplay(); + $view->initQuery(); + + // Set the various options on the join object with only a langcode + // condition. + $configuration = [ + 'table' => 'node__field_tags', + 'left_table' => 'node', + 'left_field' => 'nid', + 'field' => 'entity_id', + 'extra' => [ + [ + 'left_field' => 'langcode', + 'field' => 'langcode', + ], + ], + ]; + $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); + $this->assertContains('AND (node__field_tags.langcode = .langcode)', $join_info['condition']); + + array_unshift($configuration['extra'], [ + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ]); + $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); + $this->assertContains('AND (node__field_tags.langcode = .langcode)', $join_info['condition']); + + // Replace the language condition with a bundle condition. + $configuration['extra'][1] = [ + 'field' => 'bundle', + 'value' => ['page'], + ]; + $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); + $this->assertContains('AND (node__field_tags.bundle = :views_join_condition_1)', $join_info['condition']); + + // Now re-add a language condition to make sure the bundle and language + // conditions are combined with an OR. + $configuration['extra'][] = [ + 'left_field' => 'langcode', + 'field' => 'langcode', + ]; + $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); + $this->assertContains('AND (node__field_tags.bundle = :views_join_condition_1 OR node__field_tags.langcode = .langcode)', $join_info['condition']); + } + + /** + * Builds a join using the given configuration. + * + * @param \Drupal\views\ViewExecutable $view + * The view used in this test. + * @param $configuration + * The join plugin configuration. + * @param $table_alias + * The table alias to use for the join. + * + * @return array + * The join information for the joined table. See + * \Drupal\Core\Database\Query\Select::$tables for more information on the + * structure of the array. + */ + protected function buildJoin($view, $configuration, $table_alias) { + // Build the actual join values and read them back from the query object. + $query = \Drupal::database()->select('node'); + + $join = $this->manager->createInstance('field_or_language_join', $configuration); + $this->assertInstanceOf(FieldOrLanguageJoin::class, $join, 'The correct join class got loaded.'); + + $table = ['alias' => $table_alias]; + $join->buildJoin($query, $table, $view->query); + + $tables = $query->getTables(); + $join_info = $tables[$table['alias']]; + return $join_info; + } + +} diff --git a/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php b/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php index db0262a1..1c196a1d 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php @@ -6,7 +6,6 @@ use Drupal\views\Plugin\views\join\JoinPluginBase; use Drupal\views\Views; - /** * Tests the join plugin. * @@ -21,7 +20,7 @@ class JoinTest extends RelationshipJoinTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * A plugin manager which handlers the instances of joins. @@ -47,12 +46,12 @@ public function testExamplePlugin() { $view->initDisplay(); $view->initQuery(); - $configuration = array( + $configuration = [ 'left_table' => 'views_test_data', 'left_field' => 'uid', 'table' => 'users_field_data', 'field' => 'uid', - ); + ]; $join = $this->manager->createInstance('join_test', $configuration); $this->assertTrue($join instanceof JoinTestPlugin, 'The correct join class got loaded.'); @@ -60,7 +59,7 @@ public function testExamplePlugin() { $join->setJoinValue($rand_int); $query = db_select('views_test_data'); - $table = array('alias' => 'users_field_data'); + $table = ['alias' => 'users_field_data']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -80,13 +79,13 @@ public function testBasePlugin() { // First define a simple join without an extra condition. // Set the various options on the join object. - $configuration = array( + $configuration = [ 'left_table' => 'views_test_data', 'left_field' => 'uid', 'table' => 'users_field_data', 'field' => 'uid', 'adjusted' => TRUE, - ); + ]; $join = $this->manager->createInstance('standard', $configuration); $this->assertTrue($join instanceof JoinPluginBase, 'The correct join class got loaded.'); $this->assertNull($join->extra, 'The field extra was not overridden.'); @@ -95,7 +94,7 @@ public function testBasePlugin() { // Build the actual join values and read them back from the dbtng query // object. $query = db_select('views_test_data'); - $table = array('alias' => 'users_field_data'); + $table = ['alias' => 'users_field_data']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -107,7 +106,7 @@ public function testBasePlugin() { // Set a different alias and make sure table info is as expected. $join = $this->manager->createInstance('standard', $configuration); - $table = array('alias' => 'users1'); + $table = ['alias' => 'users1']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -117,7 +116,7 @@ public function testBasePlugin() { // Set a different join type (INNER) and make sure it is used. $configuration['type'] = 'INNER'; $join = $this->manager->createInstance('standard', $configuration); - $table = array('alias' => 'users2'); + $table = ['alias' => 'users2']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -127,19 +126,19 @@ public function testBasePlugin() { // Setup addition conditions and make sure it is used. $random_name_1 = $this->randomMachineName(); $random_name_2 = $this->randomMachineName(); - $configuration['extra'] = array( - array( + $configuration['extra'] = [ + [ 'field' => 'name', 'value' => $random_name_1 - ), - array( + ], + [ 'field' => 'name', 'value' => $random_name_2, 'operator' => '<>' - ), - ); + ], + ]; $join = $this->manager->createInstance('standard', $configuration); - $table = array('alias' => 'users3'); + $table = ['alias' => 'users3']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -147,25 +146,25 @@ public function testBasePlugin() { $this->assertTrue(strpos($join_info['condition'], "views_test_data.uid = users3.uid") !== FALSE, 'Make sure the join condition appears in the query.'); $this->assertTrue(strpos($join_info['condition'], "users3.name = :views_join_condition_0") !== FALSE, 'Make sure the first extra join condition appears in the query and uses the first placeholder.'); $this->assertTrue(strpos($join_info['condition'], "users3.name <> :views_join_condition_1") !== FALSE, 'Make sure the second extra join condition appears in the query and uses the second placeholder.'); - $this->assertEqual(array_values($join_info['arguments']), array($random_name_1, $random_name_2), 'Make sure the arguments are in the right order'); + $this->assertEqual(array_values($join_info['arguments']), [$random_name_1, $random_name_2], 'Make sure the arguments are in the right order'); // Test that 'IN' conditions are properly built. $random_name_1 = $this->randomMachineName(); $random_name_2 = $this->randomMachineName(); $random_name_3 = $this->randomMachineName(); $random_name_4 = $this->randomMachineName(); - $configuration['extra'] = array( - array( + $configuration['extra'] = [ + [ 'field' => 'name', 'value' => $random_name_1 - ), - array( + ], + [ 'field' => 'name', - 'value' => array($random_name_2, $random_name_3, $random_name_4), - ), - ); + 'value' => [$random_name_2, $random_name_3, $random_name_4], + ], + ]; $join = $this->manager->createInstance('standard', $configuration); - $table = array('alias' => 'users4'); + $table = ['alias' => 'users4']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -173,26 +172,26 @@ public function testBasePlugin() { $this->assertTrue(strpos($join_info['condition'], "views_test_data.uid = users4.uid") !== FALSE, 'Make sure the join condition appears in the query.'); $this->assertTrue(strpos($join_info['condition'], "users4.name = :views_join_condition_2") !== FALSE, 'Make sure the first extra join condition appears in the query.'); $this->assertTrue(strpos($join_info['condition'], "users4.name IN ( :views_join_condition_3[] )") !== FALSE, 'The IN condition for the join is properly formed.'); - $this->assertEqual($join_info['arguments'][':views_join_condition_3[]'], array($random_name_2, $random_name_3, $random_name_4), 'Make sure the IN arguments are still part of an array.'); + $this->assertEqual($join_info['arguments'][':views_join_condition_3[]'], [$random_name_2, $random_name_3, $random_name_4], 'Make sure the IN arguments are still part of an array.'); // Test that all the conditions are properly built. - $configuration['extra'] = array( - array( + $configuration['extra'] = [ + [ 'field' => 'langcode', 'value' => 'en' - ), - array( + ], + [ 'left_field' => 'status', 'value' => 0, 'numeric' => TRUE, - ), - array( + ], + [ 'field' => 'name', 'left_field' => 'name' - ), - ); + ], + ]; $join = $this->manager->createInstance('standard', $configuration); - $table = array('alias' => 'users5'); + $table = ['alias' => 'users5']; $join->buildJoin($query, $table, $view->query); $tables = $query->getTables(); @@ -201,7 +200,7 @@ public function testBasePlugin() { $this->assertTrue(strpos($join_info['condition'], "users5.langcode = :views_join_condition_4") !== FALSE, 'Make sure the first extra join condition appears in the query.'); $this->assertTrue(strpos($join_info['condition'], "views_test_data.status = :views_join_condition_5") !== FALSE, 'Make sure the second extra join condition appears in the query.'); $this->assertTrue(strpos($join_info['condition'], "users5.name = views_test_data.name") !== FALSE, 'Make sure the third extra join condition appears in the query.'); - $this->assertEqual(array_values($join_info['arguments']), array('en', 0), 'Make sure the arguments are in the right order'); + $this->assertEqual(array_values($join_info['arguments']), ['en', 0], 'Make sure the arguments are in the right order'); } } diff --git a/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php b/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php index 2422deda..02548b25 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php @@ -18,7 +18,7 @@ class QueryTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; protected function viewsData() { $data = parent::viewsData(); diff --git a/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php b/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php new file mode 100644 index 00000000..82b787ce --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php @@ -0,0 +1,130 @@ + 'name', + 'users_field_data_views_test_data_uid' => 'uid', + ]; + + /** + * Tests the query result of a view with a relationship with an IN condition. + */ + public function testRelationshipInQuery() { + // Update the first two Beatles to be authored by Kristiaan. + $account_k = $this->createUser([], 'Kristiaan'); + db_query("UPDATE {views_test_data} SET uid = :uid WHERE id IN (1,2)", [':uid' => $account_k->id()]); + + // Update the other two Beatles to be authored by Django. + $account_d = $this->createUser([], 'Django'); + db_query("UPDATE {views_test_data} SET uid = :uid WHERE id IN (3,4)", [':uid' => $account_d->id()]); + + // Update Meredith to be authored by Silvie. + $account_s = $this->createUser([], 'Silvie'); + db_query("UPDATE {views_test_data} SET uid = :uid WHERE id = 5", [':uid' => $account_s->id()]); + + $view = Views::getView('test_view'); + $view->setDisplay(); + + $view->displayHandlers->get('default')->overrideOption('relationships', [ + 'uid' => [ + 'id' => 'uid', + 'table' => 'views_test_data', + 'field' => 'uid', + 'required' => TRUE, + ], + ]); + + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'uid' => [ + 'id' => 'uid', + 'table' => 'users_field_data', + 'field' => 'uid', + 'relationship' => 'uid', + ], + ]); + + $fields = $view->displayHandlers->get('default')->getOption('fields'); + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'uid' => [ + 'id' => 'uid', + 'table' => 'users_field_data', + 'field' => 'uid', + 'relationship' => 'uid', + ], + ]); + + // Check for all beatles created by Kristiaan. + $view->initHandlers(); + $view->filter['uid']->value = [$account_k->id()]; + $this->executeView($view); + + $expected_result = [ + ['name' => 'John', 'uid' => $account_k->id()], + ['name' => 'George', 'uid' => $account_k->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); + $view->destroy(); + + // Check for all beatles created by Django. This should not return anything + // as the 'extra' option on the join prohibits relating to any authors but + // Kristiaan or Silvie. + $view->initHandlers(); + $view->filter['uid']->value = [$account_d->id()]; + $this->executeView($view); + + $expected_result = []; + $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); + $view->destroy(); + + // Check for all people created by anyone. + $view->initHandlers(); + $this->executeView($view); + $expected_result = [ + ['name' => 'John', 'uid' => $account_k->id()], + ['name' => 'George', 'uid' => $account_k->id()], + ['name' => 'Meredith', 'uid' => $account_s->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); + $view->destroy(); + } + + /** + * Adds an IN condition for the user name. + */ + protected function viewsData() { + $data = parent::viewsData(); + // Only relate if the author's name is Kristiaan or Silvie. + $data['views_test_data']['uid']['relationship']['extra'][] = [ + 'field' => 'name', + 'value' => ['Kristiaan', 'Silvie'], + ]; + return $data; + } + +} diff --git a/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinTestBase.php b/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinTestBase.php index cf604f93..19d5e955 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinTestBase.php +++ b/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinTestBase.php @@ -18,7 +18,7 @@ abstract class RelationshipJoinTestBase extends PluginKernelTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field'); + public static $modules = ['system', 'user', 'field']; /** * @var \Drupal\user\Entity\User @@ -30,7 +30,7 @@ abstract class RelationshipJoinTestBase extends PluginKernelTestBase { */ protected function setUpFixtures() { $this->installEntitySchema('user'); - $this->installConfig(array('user')); + $this->installConfig(['user']); parent::setUpFixtures(); // Create a record for uid 1. @@ -44,17 +44,19 @@ protected function setUpFixtures() { * Overrides \Drupal\views\Tests\ViewTestBase::schemaDefinition(). * * Adds a uid column to test the relationships. + * + * @internal */ protected function schemaDefinition() { $schema = parent::schemaDefinition(); - $schema['views_test_data']['fields']['uid'] = array( + $schema['views_test_data']['fields']['uid'] = [ 'description' => "The {users_field_data}.uid of the author of the beatle entry.", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0 - ); + ]; return $schema; } @@ -66,15 +68,15 @@ protected function schemaDefinition() { */ protected function viewsData() { $data = parent::viewsData(); - $data['views_test_data']['uid'] = array( + $data['views_test_data']['uid'] = [ 'title' => t('UID'), 'help' => t('The test data UID'), - 'relationship' => array( + 'relationship' => [ 'id' => 'standard', 'base' => 'users_field_data', 'base field' => 'uid' - ) - ); + ] + ]; return $data; } diff --git a/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php b/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php index 846da660..802befe1 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php @@ -19,17 +19,17 @@ class RelationshipTest extends RelationshipJoinTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Maps between the key in the expected result and the query result. * * @var array */ - protected $columnMap = array( + protected $columnMap = [ 'views_test_data_name' => 'name', 'users_field_data_views_test_data_uid' => 'uid', - ); + ]; /** * Tests the query result of a view with a relationship. @@ -42,53 +42,53 @@ public function testRelationshipQuery() { $view = Views::getView('test_view'); $view->setDisplay(); - $view->displayHandlers->get('default')->overrideOption('relationships', array( - 'uid' => array( + $view->displayHandlers->get('default')->overrideOption('relationships', [ + 'uid' => [ 'id' => 'uid', 'table' => 'views_test_data', 'field' => 'uid', - ), - )); + ], + ]); - $view->displayHandlers->get('default')->overrideOption('filters', array( - 'uid' => array( + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'uid' => [ 'id' => 'uid', 'table' => 'users_field_data', 'field' => 'uid', 'relationship' => 'uid', - ), - )); + ], + ]); $fields = $view->displayHandlers->get('default')->getOption('fields'); - $view->displayHandlers->get('default')->overrideOption('fields', $fields + array( - 'uid' => array( + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'uid' => [ 'id' => 'uid', 'table' => 'users_field_data', 'field' => 'uid', 'relationship' => 'uid', - ), - )); + ], + ]); $view->initHandlers(); // Check for all beatles created by admin. - $view->filter['uid']->value = array(1); + $view->filter['uid']->value = [1]; $this->executeView($view); - $expected_result = array( - array( + $expected_result = [ + [ 'name' => 'John', 'uid' => 1 - ) - ); + ] + ]; $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); $view->destroy(); // Check for all beatles created by another user, which so doesn't exist. $view->initHandlers(); - $view->filter['uid']->value = array(3); + $view->filter['uid']->value = [3]; $this->executeView($view); - $expected_result = array(); + $expected_result = []; $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); $view->destroy(); @@ -98,12 +98,12 @@ public function testRelationshipQuery() { $view->relationship['uid']->options['required'] = TRUE; $this->executeView($view); - $expected_result = array( - array( + $expected_result = [ + [ 'name' => 'John', 'uid' => 1 - ) - ); + ] + ]; $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); $view->destroy(); diff --git a/core/modules/views/tests/src/Kernel/Plugin/RowEntityTest.php b/core/modules/views/tests/src/Kernel/Plugin/RowEntityTest.php index 8d2d8663..208a6f0e 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/RowEntityTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/RowEntityTest.php @@ -28,7 +28,7 @@ class RowEntityTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_entity_row'); + public static $testViews = ['test_entity_row']; /** * {@inheritdoc} @@ -37,7 +37,7 @@ protected function setUp($import_test_views = TRUE) { parent::setUp(); $this->installEntitySchema('taxonomy_term'); - $this->installConfig(array('taxonomy')); + $this->installConfig(['taxonomy']); \Drupal::service('router.builder')->rebuild(); } @@ -47,7 +47,7 @@ protected function setUp($import_test_views = TRUE) { public function testEntityRow() { $vocab = Vocabulary::create(['name' => $this->randomMachineName(), 'vid' => strtolower($this->randomMachineName())]); $vocab->save(); - $term = Term::create(['name' => $this->randomMachineName(), 'vid' => $vocab->id() ]); + $term = Term::create(['name' => $this->randomMachineName(), 'vid' => $vocab->id()]); $term->save(); $view = Views::getView('test_entity_row'); @@ -57,7 +57,7 @@ public function testEntityRow() { $this->assertText($term->getName(), 'The rendered entity appears as row in the view.'); // Tests the available view mode options. - $form = array(); + $form = []; $form_state = new FormState(); $form_state->set('view', $view->storage); $view->rowPlugin->buildOptionsForm($form, $form_state); diff --git a/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php b/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php index ac85c77a..223963e2 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/RowRenderCacheTest.php @@ -24,14 +24,14 @@ class RowRenderCacheTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('user', 'node'); + public static $modules = ['user', 'node']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_row_render_cache', 'test_row_render_cache_none'); + public static $testViews = ['test_row_render_cache', 'test_row_render_cache_none']; /** * An editor user account. diff --git a/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php b/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php index 339638ce..3e3bbaca 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php @@ -37,7 +37,7 @@ protected function setUp($import_test_views = TRUE) { $this->installSchema('node', 'node_access'); } - public function testViewWithNonDefaultForwardRevision() { + public function testViewWithNonDefaultPendingRevision() { $node_type = NodeType::create([ 'type' => 'page', ]); diff --git a/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php b/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php index ca7ba5bc..6846f776 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/SqlQueryTest.php @@ -18,7 +18,7 @@ class SqlQueryTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * {@inheritdoc} @@ -26,7 +26,7 @@ class SqlQueryTest extends ViewsKernelTestBase { protected function viewsData() { $data = parent::viewsData(); $data['views_test_data']['table']['base']['access query tag'] = 'test_tag'; - $data['views_test_data']['table']['base']['query metadata'] = array('key1' => 'test_metadata', 'key2' => 'test_metadata2'); + $data['views_test_data']['table']['base']['query metadata'] = ['key1' => 'test_metadata', 'key2' => 'test_metadata2']; return $data; } @@ -45,7 +45,7 @@ public function testExecuteMetadata() { /** @var \Drupal\Core\Database\Query\Select $count_query */ $count_query = $view->build_info['count_query']; - foreach (array($main_query, $count_query) as $query) { + foreach ([$main_query, $count_query] as $query) { // Check query access tags. $this->assertTrue($query->hasTag('test_tag')); @@ -69,7 +69,7 @@ public function testExecuteMetadata() { /** @var \Drupal\Core\Database\Query\Select $count_query */ $count_query = $view->build_info['count_query']; - foreach (array($main_query, $count_query) as $query) { + foreach ([$main_query, $count_query] as $query) { // Check query access tags. $this->assertFalse($query->hasTag('test_tag')); diff --git a/core/modules/views/src/Tests/Plugin/StyleGridTest.php b/core/modules/views/tests/src/Kernel/Plugin/StyleGridTest.php similarity index 80% rename from core/modules/views/src/Tests/Plugin/StyleGridTest.php rename to core/modules/views/tests/src/Kernel/Plugin/StyleGridTest.php index 49bf67d4..1495399e 100644 --- a/core/modules/views/src/Tests/Plugin/StyleGridTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/StyleGridTest.php @@ -1,6 +1,6 @@ enableViewsTestModule(); - } + protected $alignmentsTested = []; /** * Tests the grid style. */ public function testGrid() { $view = Views::getView('test_grid'); - foreach (array('horizontal', 'vertical') as $alignment) { + foreach (['horizontal', 'vertical'] as $alignment) { $this->assertGrid($view, $alignment, 5); $this->assertGrid($view, $alignment, 4); $this->assertGrid($view, $alignment, 3); $this->assertGrid($view, $alignment, 2); $this->assertGrid($view, $alignment, 1); } - - // Ensure styles are properly added for grid views. - $this->drupalGet('test-grid'); - $this->assertRaw('stable/css/views/views.module.css'); } /** @@ -73,7 +63,7 @@ protected function assertGrid(ViewExecutable $view, $alignment, $columns) { $output = \Drupal::service('renderer')->renderRoot($output); $this->setRawContent($output); if (!in_array($alignment, $this->alignmentsTested)) { - $result = $this->xpath('//div[contains(@class, "views-view-grid") and contains(@class, :alignment) and contains(@class, :columns)]', array(':alignment' => $alignment, ':columns' => 'cols-' . $columns)); + $result = $this->xpath('//div[contains(@class, "views-view-grid") and contains(@class, :alignment) and contains(@class, :columns)]', [':alignment' => $alignment, ':columns' => 'cols-' . $columns]); $this->assertTrue(count($result), ucfirst($alignment) . " grid markup detected."); $this->alignmentsTested[] = $alignment; } @@ -86,10 +76,10 @@ protected function assertGrid(ViewExecutable $view, $alignment, $columns) { case 1: $width = '100'; break; } // Ensure last column exists. - $result = $this->xpath('//div[contains(@class, "views-col") and contains(@class, :columns) and starts-with(@style, :width)]', array(':columns' => 'col-' . $columns, ':width' => 'width: ' . $width)); + $result = $this->xpath('//div[contains(@class, "views-col") and contains(@class, :columns) and starts-with(@style, :width)]', [':columns' => 'col-' . $columns, ':width' => 'width: ' . $width]); $this->assertTrue(count($result), ucfirst($alignment) . " $columns column grid: last column exists and automatic width calculated correctly."); // Ensure no extra columns were generated. - $result = $this->xpath('//div[contains(@class, "views-col") and contains(@class, :columns)]', array(':columns' => 'col-' . ($columns + 1))); + $result = $this->xpath('//div[contains(@class, "views-col") and contains(@class, :columns)]', [':columns' => 'col-' . ($columns + 1)]); $this->assertFalse(count($result), ucfirst($alignment) . " $columns column grid: no extraneous columns exist."); // Ensure tokens are being replaced in custom row/column classes. $result = $this->xpath('//div[contains(@class, "views-col") and contains(@class, "name-John")]'); diff --git a/core/modules/views/tests/src/Kernel/Plugin/StyleHtmlListTest.php b/core/modules/views/tests/src/Kernel/Plugin/StyleHtmlListTest.php index f1f1fb1a..0e99439e 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/StyleHtmlListTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/StyleHtmlListTest.php @@ -18,12 +18,12 @@ class StyleHtmlListTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_style_html_list'); + public static $testViews = ['test_style_html_list']; /** * Make sure that the HTML list style markup is correct. */ - function testDefaultRowClasses() { + public function testDefaultRowClasses() { $view = Views::getView('test_style_html_list'); $output = $view->preview(); $output = \Drupal::service('renderer')->renderRoot($output); diff --git a/core/modules/views/tests/src/Kernel/Plugin/StyleMappingTest.php b/core/modules/views/tests/src/Kernel/Plugin/StyleMappingTest.php index 1cb44000..d0683deb 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/StyleMappingTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/StyleMappingTest.php @@ -11,14 +11,14 @@ */ class StyleMappingTest extends StyleTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_style_mapping'); + public static $testViews = ['test_style_mapping']; /** * Verifies that the fields were mapped correctly. @@ -68,7 +68,7 @@ protected function mappedOutputHelper($view) { // separated by ':'. $expected_result = $name . ':' . $data_set[$count][$field_id]; $actual_result = (string) $field; - $this->assertIdentical($expected_result, $actual_result, format_string('The fields were mapped successfully: %name => %field_id', array('%name' => $name, '%field_id' => $field_id))); + $this->assertIdentical($expected_result, $actual_result, format_string('The fields were mapped successfully: %name => %field_id', ['%name' => $name, '%field_id' => $field_id])); } $count++; diff --git a/core/modules/views/tests/src/Kernel/Plugin/StyleTableUnitTest.php b/core/modules/views/tests/src/Kernel/Plugin/StyleTableUnitTest.php index f7ede520..365b0c78 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/StyleTableUnitTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/StyleTableUnitTest.php @@ -19,7 +19,7 @@ class StyleTableUnitTest extends PluginKernelTestBase { * * @var array */ - public static $testViews = array('test_table'); + public static $testViews = ['test_table']; /** * Tests the table style. @@ -101,7 +101,7 @@ public function testTable() { $view->destroy(); // Use a existing field, and sort both ascending and descending. - foreach (array('asc', 'desc') as $order) { + foreach (['asc', 'desc'] as $order) { $this->prepareView($view); $style_plugin = $view->style_plugin; $request->query->set('sort', $order); @@ -133,7 +133,7 @@ public function testTable() { // Render an empty result, and ensure that the area handler is rendered. $view->setDisplay('default'); $view->executed = TRUE; - $view->result = array(); + $view->result = []; $output = $view->preview(); $output = \Drupal::service('renderer')->renderRoot($output); diff --git a/core/modules/views/tests/src/Kernel/Plugin/StyleTestBase.php b/core/modules/views/tests/src/Kernel/Plugin/StyleTestBase.php index 00dd9f98..91900cea 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/StyleTestBase.php +++ b/core/modules/views/tests/src/Kernel/Plugin/StyleTestBase.php @@ -20,7 +20,7 @@ abstract class StyleTestBase extends ViewsKernelTestBase { /** * Stores a view output in the elements. */ - function storeViewPreview($output) { + public function storeViewPreview($output) { $html5 = new HTML5(); $htmlDom = $html5->loadHTML('' . $output . ''); if ($htmlDom) { diff --git a/core/modules/views/tests/src/Kernel/Plugin/StyleUnformattedTest.php b/core/modules/views/tests/src/Kernel/Plugin/StyleUnformattedTest.php index 14e58955..af58b700 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/StyleUnformattedTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/StyleUnformattedTest.php @@ -16,12 +16,12 @@ class StyleUnformattedTest extends StyleTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Make sure that the default css classes works as expected. */ - function testDefaultRowClasses() { + public function testDefaultRowClasses() { $view = Views::getView('test_view'); $view->setDisplay(); $output = $view->preview(); diff --git a/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php b/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php index d06ae66b..879f6d44 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/ViewsBlockTest.php @@ -19,14 +19,14 @@ class ViewsBlockTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('block', 'block_test_views'); + public static $modules = ['block', 'block_test_views']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view_block'); + public static $testViews = ['test_view_block']; /** * {@inheritdoc} @@ -34,7 +34,7 @@ class ViewsBlockTest extends ViewsKernelTestBase { protected function setUp($import_test_views = TRUE) { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('block_test_views')); + ViewTestData::createTestViews(get_class($this), ['block_test_views']); } /** @@ -43,11 +43,11 @@ protected function setUp($import_test_views = TRUE) { * @see \Drupal\views\Plugin\Block::getmachineNameSuggestion() */ public function testMachineNameSuggestion() { - $plugin_definition = array( + $plugin_definition = [ 'provider' => 'views', - ); + ]; $plugin_id = 'views_block:test_view_block-block_1'; - $views_block = ViewsBlock::create($this->container, array(), $plugin_id, $plugin_definition); + $views_block = ViewsBlock::create($this->container, [], $plugin_id, $plugin_definition); $this->assertEqual($views_block->getMachineNameSuggestion(), 'views_block__test_view_block_block_1'); } @@ -96,8 +96,8 @@ public function testBuildWithTitleOverride() { $view->setDisplay(); // Add a fixed argument that sets a title and save the view. - $view->displayHandlers->get('default')->overrideOption('arguments', array( - 'name' => array( + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'name' => [ 'default_action' => 'default', 'title_enable' => TRUE, 'title' => 'Overridden title', @@ -105,16 +105,16 @@ public function testBuildWithTitleOverride() { 'default_argument_options' => [ 'argument' => 'fixed' ], - 'validate' => array( + 'validate' => [ 'type' => 'none', 'fail' => 'not found', - ), + ], 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'plugin_id' => 'string', - ) - )); + ] + ]); $view->save(); $plugin_definition = [ diff --git a/core/modules/views/tests/src/Kernel/PluginInstanceTest.php b/core/modules/views/tests/src/Kernel/PluginInstanceTest.php index f5c61ee3..b1204006 100644 --- a/core/modules/views/tests/src/Kernel/PluginInstanceTest.php +++ b/core/modules/views/tests/src/Kernel/PluginInstanceTest.php @@ -16,7 +16,7 @@ class PluginInstanceTest extends ViewsKernelTestBase { * * @var array */ - protected $pluginTypes = array( + protected $pluginTypes = [ 'access', 'area', 'argument', @@ -36,7 +36,7 @@ class PluginInstanceTest extends ViewsKernelTestBase { 'sort', 'style', 'wizard', - ); + ]; /** * An array of plugin definitions, keyed by plugin type. @@ -60,8 +60,8 @@ public function testPluginData() { // Check all plugin types. foreach ($this->pluginTypes as $type) { - $this->assertTrue(array_key_exists($type, $this->definitions), format_string('Key for plugin type @type found.', array('@type' => $type))); - $this->assertTrue(is_array($this->definitions[$type]) && !empty($this->definitions[$type]), format_string('Plugin type @type has an array of plugins.', array('@type' => $type))); + $this->assertTrue(array_key_exists($type, $this->definitions), format_string('Key for plugin type @type found.', ['@type' => $type])); + $this->assertTrue(is_array($this->definitions[$type]) && !empty($this->definitions[$type]), format_string('Plugin type @type has an array of plugins.', ['@type' => $type])); } // Tests that the plugin list has not missed any types. @@ -87,7 +87,7 @@ public function testPluginInstances() { // good to check they can be created but for throwing any notices for // method signatures etc. too. $instance = $manager->createInstance($id); - $this->assertTrue($instance instanceof $definition['class'], format_string('Instance of @type:@id created', array('@type' => $type, '@id' => $id))); + $this->assertTrue($instance instanceof $definition['class'], format_string('Instance of @type:@id created', ['@type' => $type, '@id' => $id])); } } } diff --git a/core/modules/views/tests/src/Kernel/QueryGroupByTest.php b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php index 594bd625..e4a08845 100644 --- a/core/modules/views/tests/src/Kernel/QueryGroupByTest.php +++ b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php @@ -20,14 +20,14 @@ class QueryGroupByTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_group_by_in_filters', 'test_aggregate_count', 'test_group_by_count', 'test_group_by_count_multicardinality', 'test_group_by_field_not_within_bundle'); + public static $testViews = ['test_group_by_in_filters', 'test_aggregate_count', 'test_group_by_count', 'test_group_by_count_multicardinality', 'test_group_by_field_not_within_bundle']; /** * Modules to enable. * * @var array */ - public static $modules = array('entity_test', 'system', 'field', 'user', 'language'); + public static $modules = ['entity_test', 'system', 'field', 'user', 'language']; /** * The storage for the test entity type. @@ -63,7 +63,7 @@ public function testAggregateCount() { $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); - $types = array(); + $types = []; foreach ($view->result as $item) { // num_records is a alias for id. $types[$item->entity_test_name] = $item->num_records; @@ -101,12 +101,12 @@ public function groupByTestHelper($aggregation_function, $values) { $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); // Group by name to identify the right count. - $results = array(); + $results = []; foreach ($view->result as $item) { $results[$item->entity_test_name] = $item->id; } - $this->assertEqual($results['name1'], $values[0], format_string('Aggregation with @aggregation_function and groupby name: name1 returned the expected amount of results', array('@aggregation_function' => $aggregation_function))); - $this->assertEqual($results['name2'], $values[1], format_string('Aggregation with @aggregation_function and groupby name: name2 returned the expected amount of results', array('@aggregation_function' => $aggregation_function))); + $this->assertEqual($results['name1'], $values[0], format_string('Aggregation with @aggregation_function and groupby name: name1 returned the expected amount of results', ['@aggregation_function' => $aggregation_function])); + $this->assertEqual($results['name2'], $values[1], format_string('Aggregation with @aggregation_function and groupby name: name2 returned the expected amount of results', ['@aggregation_function' => $aggregation_function])); } /** @@ -114,18 +114,18 @@ public function groupByTestHelper($aggregation_function, $values) { */ protected function setupTestEntities() { // Create 4 entities with name1 and 3 entities with name2. - $entity_1 = array( + $entity_1 = [ 'name' => 'name1', - ); + ]; $this->storage->create($entity_1)->save(); $this->storage->create($entity_1)->save(); $this->storage->create($entity_1)->save(); $this->storage->create($entity_1)->save(); - $entity_2 = array( + $entity_2 = [ 'name' => 'name2', - ); + ]; $this->storage->create($entity_2)->save(); $this->storage->create($entity_2)->save(); $this->storage->create($entity_2)->save(); @@ -135,42 +135,42 @@ protected function setupTestEntities() { * Tests the count aggregation function. */ public function testGroupByCount() { - $this->groupByTestHelper('count', array(4, 3)); + $this->groupByTestHelper('count', [4, 3]); } /** * Tests the sum aggregation function. */ public function testGroupBySum() { - $this->groupByTestHelper('sum', array(10, 18)); + $this->groupByTestHelper('sum', [10, 18]); } /** * Tests the average aggregation function. */ public function testGroupByAverage() { - $this->groupByTestHelper('avg', array(2.5, 6)); + $this->groupByTestHelper('avg', [2.5, 6]); } /** * Tests the min aggregation function. */ public function testGroupByMin() { - $this->groupByTestHelper('min', array(1, 5)); + $this->groupByTestHelper('min', [1, 5]); } /** * Tests the max aggregation function. */ public function testGroupByMax() { - $this->groupByTestHelper('max', array(4, 7)); + $this->groupByTestHelper('max', [4, 7]); } /** * Tests aggregation with no specific function. */ public function testGroupByNone() { - $this->groupByTestHelper(NULL, array(1, 5)); + $this->groupByTestHelper(NULL, [1, 5]); } /** @@ -181,7 +181,7 @@ public function testGroupByCountOnlyFilters() { // doesn't display SUM, COUNT, MAX, etc. functions in SELECT statement. for ($x = 0; $x < 10; $x++) { - $this->storage->create(array('name' => 'name1'))->save(); + $this->storage->create(['name' => 'name1'])->save(); } $view = Views::getView('test_group_by_in_filters'); diff --git a/core/modules/views/tests/src/Kernel/RenderCacheIntegrationTest.php b/core/modules/views/tests/src/Kernel/RenderCacheIntegrationTest.php index a2bec23a..ace42048 100644 --- a/core/modules/views/tests/src/Kernel/RenderCacheIntegrationTest.php +++ b/core/modules/views/tests/src/Kernel/RenderCacheIntegrationTest.php @@ -164,7 +164,7 @@ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) { $this->pass('Test arguments'); // Custom assert for a single result row. - $single_entity_assertions = function(array $build, EntityInterface $entity) { + $single_entity_assertions = function (array $build, EntityInterface $entity) { $this->setRawContent($build['#markup']); $result = $this->cssSelect('div.views-row'); diff --git a/core/modules/views/tests/src/Kernel/TestViewsTest.php b/core/modules/views/tests/src/Kernel/TestViewsTest.php index f67b5e8d..dcd1859b 100644 --- a/core/modules/views/tests/src/Kernel/TestViewsTest.php +++ b/core/modules/views/tests/src/Kernel/TestViewsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\views\Kernel; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\config_test\TestInstallStorage; use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\TypedConfigManager; @@ -22,7 +22,7 @@ class TestViewsTest extends KernelTestBase { * * @var array */ - public static $modules = array('views_test_data'); + public static $modules = ['views_test_data']; /** * Tests default configuration data type. @@ -34,7 +34,8 @@ public function testDefaultConfig() { \Drupal::service('config.storage'), new TestInstallStorage(InstallStorage::CONFIG_SCHEMA_DIRECTORY), \Drupal::service('cache.discovery'), - \Drupal::service('module_handler') + \Drupal::service('module_handler'), + \Drupal::service('class_resolver') ); // Create a configuration storage with access to default configuration in diff --git a/core/modules/views/tests/src/Kernel/TokenReplaceTest.php b/core/modules/views/tests/src/Kernel/TokenReplaceTest.php index 5cf40ad5..4b1cfc36 100644 --- a/core/modules/views/tests/src/Kernel/TokenReplaceTest.php +++ b/core/modules/views/tests/src/Kernel/TokenReplaceTest.php @@ -12,14 +12,14 @@ */ class TokenReplaceTest extends ViewsKernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_tokens', 'test_invalid_tokens'); + public static $testViews = ['test_tokens', 'test_invalid_tokens']; protected function setUp($import_test_views = TRUE) { parent::setUp(); @@ -29,25 +29,27 @@ protected function setUp($import_test_views = TRUE) { /** * Tests core token replacements generated from a view. */ - function testTokenReplacement() { + public function testTokenReplacement() { $token_handler = \Drupal::token(); $view = Views::getView('test_tokens'); $view->setDisplay('page_1'); + // Force the view to span more than one page to better test page_count. + $view->display_handler->getPlugin('pager')->setItemsPerPage(4); $this->executeView($view); - $expected = array( + $expected = [ '[view:label]' => 'Test tokens', '[view:description]' => 'Test view to token replacement tests.', '[view:id]' => 'test_tokens', '[view:title]' => 'Test token page', '[view:url]' => $view->getUrl(NULL, 'page_1')->setAbsolute(TRUE)->toString(), - '[view:total-rows]' => (string) $view->total_rows, + '[view:total-rows]' => '5', '[view:base-table]' => 'views_test_data', '[view:base-field]' => 'id', - '[view:items-per-page]' => '10', + '[view:items-per-page]' => '4', '[view:current-page]' => '1', - '[view:page-count]' => '1', - ); + '[view:page-count]' => '2', + ]; $base_bubbleable_metadata = BubbleableMetadata::createFromObject($view->storage); $metadata_tests = []; @@ -65,47 +67,84 @@ function testTokenReplacement() { foreach ($expected as $token => $expected_output) { $bubbleable_metadata = new BubbleableMetadata(); - $output = $token_handler->replace($token, array('view' => $view), [], $bubbleable_metadata); - $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token))); + $output = $token_handler->replace($token, ['view' => $view], [], $bubbleable_metadata); + $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', ['%token' => $token])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$token]); } } + /** + * Tests core token replacements generated from a view. + */ + public function testTokenReplacementWithMiniPager() { + $token_handler = \Drupal::token(); + $view = Views::getView('test_tokens'); + $view->setDisplay('page_3'); + $this->executeView($view); + + $this->assertSame(TRUE, $view->get_total_rows, 'The query was set to calculate the total number of rows.'); + + $expected = [ + '[view:label]' => 'Test tokens', + '[view:description]' => 'Test view to token replacement tests.', + '[view:id]' => 'test_tokens', + '[view:title]' => 'Test token page with minipager', + '[view:url]' => $view->getUrl(NULL, 'page_3') + ->setAbsolute(TRUE) + ->toString(), + '[view:total-rows]' => '5', + '[view:base-table]' => 'views_test_data', + '[view:base-field]' => 'id', + '[view:items-per-page]' => '2', + '[view:current-page]' => '1', + '[view:page-count]' => '3', + ]; + + $base_bubbleable_metadata = BubbleableMetadata::createFromObject($view->storage); + + foreach ($expected as $token => $expected_output) { + $bubbleable_metadata = new BubbleableMetadata(); + $output = $token_handler->replace($token, ['view' => $view], [], $bubbleable_metadata); + $this->assertSame($expected_output, $output, sprintf('Token %s replaced correctly.', $token)); + $this->assertEquals($base_bubbleable_metadata, $bubbleable_metadata); + } + } + /** * Tests core token replacements generated from a view without results. */ - function testTokenReplacementNoResults() { + public function testTokenReplacementNoResults() { $token_handler = \Drupal::token(); $view = Views::getView('test_tokens'); $view->setDisplay('page_2'); $this->executeView($view); - $expected = array( + $expected = [ '[view:page-count]' => '1', - ); + ]; foreach ($expected as $token => $expected_output) { - $output = $token_handler->replace($token, array('view' => $view)); - $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token))); + $output = $token_handler->replace($token, ['view' => $view]); + $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', ['%token' => $token])); } } /** * Tests path token replacements generated from a view without a path. */ - function testTokenReplacementNoPath() { + public function testTokenReplacementNoPath() { $token_handler = \Drupal::token(); $view = Views::getView('test_invalid_tokens'); $view->setDisplay('block_1'); $this->executeView($view); - $expected = array( + $expected = [ '[view:url]' => '', - ); + ]; foreach ($expected as $token => $expected_output) { - $output = $token_handler->replace($token, array('view' => $view)); - $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token))); + $output = $token_handler->replace($token, ['view' => $view]); + $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', ['%token' => $token])); } } diff --git a/core/modules/views/tests/src/Kernel/ViewElementTest.php b/core/modules/views/tests/src/Kernel/ViewElementTest.php new file mode 100644 index 00000000..c6149e90 --- /dev/null +++ b/core/modules/views/tests/src/Kernel/ViewElementTest.php @@ -0,0 +1,129 @@ +container->get('renderer'); + $view = Views::getView('test_view_embed'); + + // Get the render array, #embed must be FALSE since this is the default + // display. + $render = $view->buildRenderable(); + $this->assertEqual($render['#embed'], FALSE); + $this->setRawContent($renderer->renderRoot($render)); + + $xpath = $this->xpath('//div[@class="views-element-container"]'); + $this->assertTrue($xpath, 'The view container has been found in the rendered output.'); + + // There should be 5 rows in the results. + $xpath = $this->xpath('//div[@class="views-row"]'); + $this->assertEqual(count($xpath), 5); + + // Add an argument and save the view. + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'age' => [ + 'default_action' => 'ignore', + 'title' => '', + 'default_argument_type' => 'fixed', + 'validate' => [ + 'type' => 'none', + 'fail' => 'not found', + ], + 'break_phrase' => FALSE, + 'not' => FALSE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'plugin_id' => 'numeric', + ], + ]); + $view->save(); + + // Test the render array again. + $view = Views::getView('test_view_embed'); + $render = $view->buildRenderable(NULL, [25]); + $this->setRawContent($renderer->renderRoot($render)); + // There should be 1 row in the results, 'John' arg 25. + $xpath = $this->xpath('//div[@class="views-row"]'); + $this->assertEqual(count($xpath), 1); + } + + /** + * Tests the rendered output and form output of a view element, using the + * embed display plugin. + */ + public function testViewElementEmbed() { + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = $this->container->get('renderer'); + $view = Views::getView('test_view_embed'); + + // Get the render array, #embed must be TRUE since this is an embed display. + $render = $view->buildRenderable('embed_1'); + $this->assertEqual($render['#embed'], TRUE); + $this->setRawContent($renderer->renderRoot($render)); + + $xpath = $this->xpath('//div[@class="views-element-container"]'); + $this->assertTrue($xpath, 'The view container has been found in the rendered output.'); + + // There should be 5 rows in the results. + $xpath = $this->xpath('//div[@class="views-row"]'); + $this->assertEqual(count($xpath), 5); + + // Add an argument and save the view. + $view->displayHandlers->get('default')->overrideOption('arguments', [ + 'age' => [ + 'default_action' => 'ignore', + 'title' => '', + 'default_argument_type' => 'fixed', + 'validate' => [ + 'type' => 'none', + 'fail' => 'not found', + ], + 'break_phrase' => FALSE, + 'not' => FALSE, + 'id' => 'age', + 'table' => 'views_test_data', + 'field' => 'age', + 'plugin_id' => 'numeric', + ], + ]); + $view->save(); + + // Test the render array again. + $view = Views::getView('test_view_embed'); + $render = $view->buildRenderable('embed_1', [25]); + $this->setRawContent($renderer->renderRoot($render)); + // There should be 1 row in the results, 'John' arg 25. + $xpath = $this->xpath('//div[@class="views-row"]'); + $this->assertEqual(count($xpath), 1); + + // Tests the render array with an exposed filter. + $view = Views::getView('test_view_embed'); + $render = $view->buildRenderable('embed_2'); + $this->setRawContent($renderer->renderRoot($render)); + + // Ensure that the exposed form is rendered. + $this->assertEqual(1, count($this->xpath('//form[@class="views-exposed-form"]'))); + } + +} diff --git a/core/modules/views/tests/src/Kernel/ViewExecutableTest.php b/core/modules/views/tests/src/Kernel/ViewExecutableTest.php index 01057b47..73902140 100644 --- a/core/modules/views/tests/src/Kernel/ViewExecutableTest.php +++ b/core/modules/views/tests/src/Kernel/ViewExecutableTest.php @@ -38,14 +38,14 @@ class ViewExecutableTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_destroy', 'test_executable_displays'); + public static $testViews = ['test_destroy', 'test_executable_displays']; /** * Properties that should be stored in the configuration. * * @var array */ - protected $configProperties = array( + protected $configProperties = [ 'disabled', 'name', 'description', @@ -54,14 +54,14 @@ class ViewExecutableTest extends ViewsKernelTestBase { 'label', 'core', 'display', - ); + ]; /** * Properties that should be stored in the executable. * * @var array */ - protected $executableProperties = array( + protected $executableProperties = [ 'storage', 'built', 'executed', @@ -74,14 +74,14 @@ class ViewExecutableTest extends ViewsKernelTestBase { 'exposed_raw_input', 'old_view', 'parent_views', - ); + ]; protected function setUpFixtures() { $this->installEntitySchema('user'); $this->installEntitySchema('node'); $this->installEntitySchema('comment'); - $this->installSchema('comment', array('comment_entity_statistics')); - $this->installConfig(array('system', 'field', 'node', 'comment')); + $this->installSchema('comment', ['comment_entity_statistics']); + $this->installConfig(['system', 'field', 'node', 'comment']); NodeType::create([ 'type' => 'page', @@ -90,7 +90,7 @@ protected function setUpFixtures() { $this->addDefaultCommentField('node', 'page'); parent::setUpFixtures(); - $this->installConfig(array('filter')); + $this->installConfig(['filter']); } /** @@ -123,7 +123,7 @@ public function testInitMethods() { if ($type == 'relationship') { continue; } - $this->assertTrue(count($view->$type), format_string('Make sure a %type instance got instantiated.', array('%type' => $type))); + $this->assertTrue(count($view->$type), format_string('Make sure a %type instance got instantiated.', ['%type' => $type])); } // initHandlers() should create display handlers automatically as well. @@ -196,8 +196,13 @@ public function testSetDisplayWithInvalidDisplay() { $view->initDisplay(); // Error is triggered while calling the wrong display. - $this->setExpectedException(\PHPUnit_Framework_Error::class); - $view->setDisplay('invalid'); + try { + $view->setDisplay('invalid'); + $this->fail('Expected error, when setDisplay() called with invalid display ID'); + } + catch (\PHPUnit_Framework_Error_Warning $e) { + $this->assertEquals('setDisplay() called with invalid display ID "invalid".', $e->getMessage()); + } $this->assertEqual($view->current_display, 'default', 'If setDisplay is called with an invalid display id the default display should be used.'); $this->assertEqual(spl_object_hash($view->display_handler), spl_object_hash($view->displayHandlers->get('default'))); @@ -256,7 +261,7 @@ public function testDisplays() { $this->assertTrue($view->rowPlugin instanceof Fields); // Test the newDisplay() method. - $view = $this->container->get('entity.manager')->getStorage('view')->create(array('id' => 'test_executable_displays')); + $view = $this->container->get('entity.manager')->getStorage('view')->create(['id' => 'test_executable_displays']); $executable = $view->getExecutable(); $executable->newDisplay('page'); @@ -289,10 +294,10 @@ public function testPropertyMethods() { $this->assertNull($view->usePager()); // Add a pager, initialize, and test. - $view->displayHandlers->get('default')->overrideOption('pager', array( + $view->displayHandlers->get('default')->overrideOption('pager', [ 'type' => 'full', - 'options' => array('items_per_page' => 10), - )); + 'options' => ['items_per_page' => 10], + ]); $view->initPager(); $this->assertTrue($view->usePager()); @@ -302,10 +307,10 @@ public function testPropertyMethods() { $this->assertEqual($view->getOffset(), $rand); // Test the getBaseTable() method. - $expected = array( + $expected = [ 'views_test_data' => TRUE, '#global' => TRUE, - ); + ]; $this->assertIdentical($view->getBaseTables(), $expected); // Test response methods. @@ -386,7 +391,7 @@ protected function getProtectedProperty($instance, $property) { */ public function testGetHandlerTypes() { $types = ViewExecutable::getHandlerTypes(); - foreach (array('field', 'filter', 'argument', 'sort', 'header', 'footer', 'empty') as $type) { + foreach (['field', 'filter', 'argument', 'sort', 'header', 'footer', 'empty'] as $type) { $this->assertTrue(isset($types[$type])); // @todo The key on the display should be footers, headers and empties // or something similar instead of the singular, but so long check for @@ -427,10 +432,10 @@ public function testValidate() { $count = 0; foreach ($view->displayHandlers as $id => $display) { - $match = function($value) use ($display) { + $match = function ($value) use ($display) { return strpos($value, $display->display['display_title']) !== FALSE; }; - $this->assertTrue(array_filter($validate[$id], $match), format_string('Error message found for @id display', array('@id' => $id))); + $this->assertTrue(array_filter($validate[$id], $match), format_string('Error message found for @id display', ['@id' => $id])); $count++; } @@ -487,6 +492,37 @@ public function testSerialization() { $this->assertIdentical($unserialized->current_display, 'page_1', 'The expected display was set on the unserialized view.'); $this->assertIdentical($unserialized->args, ['test'], 'The expected argument was set on the unserialized view.'); $this->assertIdentical($unserialized->getCurrentPage(), 2, 'The expected current page was set on the unserialized view.'); + + // Get the definition of node's nid field, for example. Only get it not from + // the field manager directly, but from the item data definition. It should + // be the same base field definition object (the field and item definitions + // refer to each other). + // See https://bugs.php.net/bug.php?id=66052 + $field_manager = $this->container->get('entity_field.manager'); + $nid_definition_before = $field_manager->getBaseFieldDefinitions('node')['nid'] + ->getItemDefinition() + ->getFieldDefinition(); + + // Load and execute a view. + $view_entity = View::load('content'); + $view_executable = $view_entity->getExecutable(); + $view_executable->execute('page_1'); + + // Reset the static cache. Don't use clearCachedFieldDefinitions() since + // that clears the persistent cache and we need to get the serialized cache + // data. + $field_manager->useCaches(FALSE); + $field_manager->useCaches(TRUE); + + // Serialize the ViewExecutable as part of other data. + unserialize(serialize(['SOMETHING UNEXPECTED', $view_executable])); + + // Make sure the serialisation of the ViewExecutable didn't influence the + // field definitions. + $nid_definition_after = $field_manager->getBaseFieldDefinitions('node')['nid'] + ->getItemDefinition() + ->getFieldDefinition(); + $this->assertEquals($nid_definition_before->getPropertyDefinitions(), $nid_definition_after->getPropertyDefinitions()); } } diff --git a/core/modules/views/tests/src/Kernel/ViewStorageTest.php b/core/modules/views/tests/src/Kernel/ViewStorageTest.php index fa264bd7..7cf953af 100644 --- a/core/modules/views/tests/src/Kernel/ViewStorageTest.php +++ b/core/modules/views/tests/src/Kernel/ViewStorageTest.php @@ -21,7 +21,7 @@ class ViewStorageTest extends ViewsKernelTestBase { * * @var array */ - protected $configProperties = array( + protected $configProperties = [ 'status', 'module', 'id', @@ -31,7 +31,7 @@ class ViewStorageTest extends ViewsKernelTestBase { 'label', 'core', 'display', - ); + ]; /** * The entity type definition. @@ -52,12 +52,12 @@ class ViewStorageTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view_storage'); + public static $testViews = ['test_view_storage']; /** * Tests CRUD operations. */ - function testConfigurationEntityCRUD() { + public function testConfigurationEntityCRUD() { // Get the configuration entity type and controller. $this->entityType = \Drupal::entityManager()->getDefinition('view'); $this->controller = $this->container->get('entity.manager')->getStorage('view'); @@ -85,11 +85,11 @@ protected function loadTests() { // expected properties. $this->assertTrue($view instanceof View, 'Single View instance loaded.'); foreach ($this->configProperties as $property) { - $this->assertTrue($view->get($property) !== NULL, format_string('Property: @property loaded onto View.', array('@property' => $property))); + $this->assertTrue($view->get($property) !== NULL, format_string('Property: @property loaded onto View.', ['@property' => $property])); } // Check the displays have been loaded correctly from config display data. - $expected_displays = array('default', 'block_1', 'page_1'); + $expected_displays = ['default', 'block_1', 'page_1']; $this->assertEqual(array_keys($view->get('display')), $expected_displays, 'The correct display names are present.'); // Check each ViewDisplay object and confirm that it has the correct key and @@ -101,7 +101,7 @@ protected function loadTests() { // exists. $original_options = $data['display'][$key]; foreach ($original_options as $orig_key => $value) { - $this->assertIdentical($display[$orig_key], $value, format_string('@key is identical to saved data', array('@key' => $key))); + $this->assertIdentical($display[$orig_key], $value, format_string('@key is identical to saved data', ['@key' => $key])); } } @@ -115,12 +115,12 @@ protected function loadTests() { */ protected function createTests() { // Create a new View instance with empty values. - $created = $this->controller->create(array()); + $created = $this->controller->create([]); $this->assertTrue($created instanceof View, 'Created object is a View.'); // Check that the View contains all of the properties. foreach ($this->configProperties as $property) { - $this->assertTrue(property_exists($created, $property), format_string('Property: @property created on View.', array('@property' => $property))); + $this->assertTrue(property_exists($created, $property), format_string('Property: @property created on View.', ['@property' => $property])); } // Create a new View instance with config values. @@ -137,8 +137,8 @@ protected function createTests() { // Test all properties except displays. foreach ($properties as $property) { - $this->assertTrue($created->get($property) !== NULL, format_string('Property: @property created on View.', array('@property' => $property))); - $this->assertIdentical($values[$property], $created->get($property), format_string('Property value: @property matches configuration value.', array('@property' => $property))); + $this->assertTrue($created->get($property) !== NULL, format_string('Property: @property created on View.', ['@property' => $property])); + $this->assertIdentical($values[$property], $created->get($property), format_string('Property value: @property matches configuration value.', ['@property' => $property])); } // Check the UUID of the loaded View. @@ -177,44 +177,44 @@ protected function displayTests() { * Tests the display related functions like getDisplaysList(). */ protected function displayMethodTests() { - $config['display'] = array( - 'page_1' => array( - 'display_options' => array('path' => 'test'), + $config['display'] = [ + 'page_1' => [ + 'display_options' => ['path' => 'test'], 'display_plugin' => 'page', 'id' => 'page_2', 'display_title' => 'Page 1', 'position' => 1 - ), - 'feed_1' => array( - 'display_options' => array('path' => 'test.xml'), + ], + 'feed_1' => [ + 'display_options' => ['path' => 'test.xml'], 'display_plugin' => 'feed', 'id' => 'feed', 'display_title' => 'Feed', 'position' => 2 - ), - 'page_2' => array( - 'display_options' => array('path' => 'test/%/extra'), + ], + 'page_2' => [ + 'display_options' => ['path' => 'test/%/extra'], 'display_plugin' => 'page', 'id' => 'page_2', 'display_title' => 'Page 2', 'position' => 3 - ) - ); + ] + ]; $view = $this->controller->create($config); // Tests Drupal\views\Entity\View::addDisplay() - $view = $this->controller->create(array()); + $view = $this->controller->create([]); $random_title = $this->randomMachineName(); $id = $view->addDisplay('page', $random_title); - $this->assertEqual($id, 'page_1', format_string('Make sure the first display (%id_new) has the expected ID (%id)', array('%id_new' => $id, '%id' => 'page_1'))); + $this->assertEqual($id, 'page_1', format_string('Make sure the first display (%id_new) has the expected ID (%id)', ['%id_new' => $id, '%id' => 'page_1'])); $display = $view->get('display'); $this->assertEqual($display[$id]['display_title'], $random_title); $random_title = $this->randomMachineName(); $id = $view->addDisplay('page', $random_title); $display = $view->get('display'); - $this->assertEqual($id, 'page_2', format_string('Make sure the second display (%id_new) has the expected ID (%id)', array('%id_new' => $id, '%id' => 'page_2'))); + $this->assertEqual($id, 'page_2', format_string('Make sure the second display (%id_new) has the expected ID (%id)', ['%id_new' => $id, '%id' => 'page_2'])); $this->assertEqual($display[$id]['display_title'], $random_title); $id = $view->addDisplay('page'); @@ -233,7 +233,7 @@ protected function displayMethodTests() { // Tests Drupal\views\Entity\View::generateDisplayId(). Since // generateDisplayId() is protected, we have to use reflection to unit-test // it. - $view = $this->controller->create(array()); + $view = $this->controller->create([]); $ref_generate_display_id = new \ReflectionMethod($view, 'generateDisplayId'); $ref_generate_display_id->setAccessible(TRUE); $this->assertEqual( @@ -254,38 +254,38 @@ protected function displayMethodTests() { ); // Tests item related methods(). - $view = $this->controller->create(array('base_table' => 'views_test_data')); + $view = $this->controller->create(['base_table' => 'views_test_data']); $view->addDisplay('default'); $view = $view->getExecutable(); $display_id = 'default'; - $expected_items = array(); + $expected_items = []; // Tests addHandler with getItem. // Therefore add one item without any options and one item with some // options. $id1 = $view->addHandler($display_id, 'field', 'views_test_data', 'id'); $item1 = $view->getHandler($display_id, 'field', 'id'); - $expected_items[$id1] = $expected_item = array( + $expected_items[$id1] = $expected_item = [ 'id' => 'id', 'table' => 'views_test_data', 'field' => 'id', 'plugin_id' => 'numeric', - ); + ]; $this->assertEqual($item1, $expected_item); - $options = array( - 'alter' => array( + $options = [ + 'alter' => [ 'text' => $this->randomMachineName() - ) - ); + ] + ]; $id2 = $view->addHandler($display_id, 'field', 'views_test_data', 'name', $options); $item2 = $view->getHandler($display_id, 'field', 'name'); - $expected_items[$id2] = $expected_item = array( + $expected_items[$id2] = $expected_item = [ 'id' => 'name', 'table' => 'views_test_data', 'field' => 'name', 'plugin_id' => 'standard', - ) + $options; + ] + $options; $this->assertEqual($item2, $expected_item); // Tests the expected fields from the previous additions. @@ -293,11 +293,11 @@ protected function displayMethodTests() { // Alter an existing item via setItem and check the result via getItem // and getItems. - $item = array( - 'alter' => array( + $item = [ + 'alter' => [ 'text' => $this->randomMachineName(), - ) - ) + $item1; + ] + ] + $item1; $expected_items[$id1] = $item; $view->setHandler($display_id, 'field', $id1, $item); $this->assertEqual($view->getHandler($display_id, 'field', 'id'), $item); @@ -327,24 +327,24 @@ public function testCreateDuplicate() { // Check the other properties. // @todo Create a reusable property on the base test class for these? - $config_properties = array( + $config_properties = [ 'disabled', 'description', 'tag', 'base_table', 'label', 'core', - ); + ]; foreach ($config_properties as $property) { - $this->assertIdentical($view->storage->get($property), $copy->get($property), format_string('@property property is identical.', array('@property' => $property))); + $this->assertIdentical($view->storage->get($property), $copy->get($property), format_string('@property property is identical.', ['@property' => $property])); } // Check the displays are the same. $copy_display = $copy->get('display'); foreach ($view->storage->get('display') as $id => $display) { // assertIdentical will not work here. - $this->assertEqual($display, $copy_display[$id], format_string('The @display display has been copied correctly.', array('@display' => $id))); + $this->assertEqual($display, $copy_display[$id], format_string('The @display display has been copied correctly.', ['@display' => $id])); } } diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php index f5a2e39a..294bb0f4 100644 --- a/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php @@ -5,6 +5,7 @@ use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\image\Entity\ImageStyle; +use Drupal\user\Entity\Role; use Drupal\views\Entity\View; /** @@ -17,13 +18,23 @@ class ViewsConfigDependenciesIntegrationTest extends ViewsKernelTestBase { /** * {@inheritdoc} */ - public static $modules = ['field', 'file', 'image', 'entity_test']; + public static $modules = ['field', 'file', 'image', 'entity_test', 'user', 'text']; /** * {@inheritdoc} */ public static $testViews = ['entity_test_fields']; + /** + * {@inheritdoc} + */ + protected function setUp($import_test_views = TRUE) { + parent::setUp($import_test_views); + + $this->installEntitySchema('user'); + $this->installSchema('user', ['users_data']); + } + /** * Tests integration with image module. */ @@ -69,7 +80,81 @@ public function testImage() { // Delete the 'foo' image style. $style->delete(); + $view = View::load('entity_test_fields'); + + // Checks that the view has not been deleted too. + $this->assertNotNull(View::load('entity_test_fields')); + + // Checks that the image field was removed from the View. + $display = $view->getDisplay('default'); + $this->assertFalse(isset($display['display_options']['fields']['bar'])); + + // Checks that the view has been disabled. + $this->assertFalse($view->status()); + + $dependencies = $view->getDependencies() + ['config' => []]; + // Checks that the dependency on style 'foo' has been removed. + $this->assertFalse(in_array('image.style.foo', $dependencies['config'])); + } + + /** + * Tests removing a config dependency that deletes the View. + */ + public function testConfigRemovalRole() { + // Create a role we can add to the View and delete. + $role = Role::create([ + 'id' => 'dummy', + 'label' => 'dummy', + ]); + + $role->save(); + + /** @var \Drupal\views\ViewEntityInterface $view */ + $view = View::load('entity_test_fields'); + $display = &$view->getDisplay('default'); + + // Set the access to be restricted by the dummy role. + $display['display_options']['access'] = [ + 'type' => 'role', + 'options' => [ + 'role' => [ + $role->id() => $role->id(), + ], + ], + ]; + $view->save(); + + // Check that the View now has a dependency on the Role. + $dependencies = $view->getDependencies() + ['config' => []]; + $this->assertTrue(in_array('user.role.dummy', $dependencies['config'])); + + // Delete the role. + $role->delete(); + + $view = View::load('entity_test_fields'); + // Checks that the view has been deleted too. + $this->assertNull($view); + } + + /** + * Tests uninstalling a module that provides a base table for a View. + */ + public function testConfigRemovalBaseTable() { + // Find all the entity types provided by the entity_test module and install + // the schema for them so we can uninstall them. + $entities = \Drupal::entityTypeManager()->getDefinitions(); + foreach ($entities as $entity_type_id => $definition) { + if ($definition->getProvider() == 'entity_test') { + $this->installEntitySchema($entity_type_id); + }; + } + + // Check that removing the module that provides the base table for a View, + // deletes the View. + $this->assertNotNull(View::load('entity_test_fields')); + $this->container->get('module_installer')->uninstall(['entity_test']); + // Check that the View has been deleted. $this->assertNull(View::load('entity_test_fields')); } diff --git a/core/modules/views/tests/src/Kernel/ViewsHooksTest.php b/core/modules/views/tests/src/Kernel/ViewsHooksTest.php index e0484543..b61a5d9d 100644 --- a/core/modules/views/tests/src/Kernel/ViewsHooksTest.php +++ b/core/modules/views/tests/src/Kernel/ViewsHooksTest.php @@ -19,14 +19,14 @@ class ViewsHooksTest extends ViewsKernelTestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * An array of available views hooks to test. * * @var array */ - protected static $hooks = array ( + protected static $hooks = [ 'views_data' => 'all', 'views_data_alter' => 'alter', 'views_query_substitutions' => 'view', @@ -41,7 +41,7 @@ class ViewsHooksTest extends ViewsKernelTestBase { 'views_post_render' => 'view', 'views_query_alter' => 'view', 'views_invalidate_cache' => 'all', - ); + ]; /** * The module handler to use for invoking hooks. @@ -65,28 +65,28 @@ public function testHooks() { // Test each hook is found in the implementations array and is invoked. foreach (static::$hooks as $hook => $type) { - $this->assertTrue($this->moduleHandler->implementsHook('views_test_data', $hook), format_string('The hook @hook was registered.', array('@hook' => $hook))); + $this->assertTrue($this->moduleHandler->implementsHook('views_test_data', $hook), format_string('The hook @hook was registered.', ['@hook' => $hook])); if ($hook == 'views_post_render') { - $this->moduleHandler->invoke('views_test_data', $hook, array($view, &$view->display_handler->output, $view->display_handler->getPlugin('cache'))); + $this->moduleHandler->invoke('views_test_data', $hook, [$view, &$view->display_handler->output, $view->display_handler->getPlugin('cache')]); continue; } switch ($type) { case 'view': - $this->moduleHandler->invoke('views_test_data', $hook, array($view)); + $this->moduleHandler->invoke('views_test_data', $hook, [$view]); break; case 'alter': - $data = array(); - $this->moduleHandler->invoke('views_test_data', $hook, array($data)); + $data = []; + $this->moduleHandler->invoke('views_test_data', $hook, [$data]); break; default: $this->moduleHandler->invoke('views_test_data', $hook); } - $this->assertTrue($this->container->get('state')->get('views_hook_test_' . $hook), format_string('The %hook hook was invoked.', array('%hook' => $hook))); + $this->assertTrue($this->container->get('state')->get('views_hook_test_' . $hook), format_string('The %hook hook was invoked.', ['%hook' => $hook])); // Reset the module implementations cache, so we ensure that the // .views.inc file is loaded actively. $this->moduleHandler->resetImplementations(); @@ -106,7 +106,7 @@ public function testViewsPreRenderViewsFormViewsForm() { ], '#substitutions' => ['#value' => []], ]; - $element = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function() use ($element) { + $element = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($element) { return views_pre_render_views_form_views_form($element); }); $this->setRawContent((string) $element['output']['#markup']); diff --git a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php index f149b7fb..4bbe4028 100644 --- a/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php +++ b/core/modules/views/tests/src/Kernel/ViewsKernelTestBase.php @@ -129,6 +129,8 @@ protected function executeView($view, array $args = []) { /** * Returns the schema definition. + * + * @internal */ protected function schemaDefinition() { return ViewTestData::schemaDefinition(); diff --git a/core/modules/views/tests/src/Kernel/Wizard/WizardPluginBaseKernelTest.php b/core/modules/views/tests/src/Kernel/Wizard/WizardPluginBaseKernelTest.php index 27f21c22..beb7b486 100644 --- a/core/modules/views/tests/src/Kernel/Wizard/WizardPluginBaseKernelTest.php +++ b/core/modules/views/tests/src/Kernel/Wizard/WizardPluginBaseKernelTest.php @@ -20,7 +20,7 @@ class WizardPluginBaseKernelTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('language', 'system', 'user', 'views_ui'); + public static $modules = ['language', 'system', 'user', 'views_ui']; /** * Contains thw wizard plugin manager. @@ -32,9 +32,9 @@ class WizardPluginBaseKernelTest extends ViewsKernelTestBase { protected function setUp($import_test_views = TRUE) { parent::setUp(); - $this->installConfig(array('language')); + $this->installConfig(['language']); - $this->wizard = $this->container->get('plugin.manager.views.wizard')->createInstance('standard:views_test_data', array()); + $this->wizard = $this->container->get('plugin.manager.views.wizard')->createInstance('standard:views_test_data', []); } /** @@ -43,7 +43,7 @@ protected function setUp($import_test_views = TRUE) { * @see \Drupal\views\Plugin\views\wizard\WizardPluginBase */ public function testCreateView() { - $form = array(); + $form = []; $form_state = new FormState(); $form = $this->wizard->buildForm($form, $form_state); $random_id = strtolower($this->randomMachineName()); diff --git a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php index d6b2a1e7..d65acaab 100644 --- a/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php +++ b/core/modules/views/tests/src/Unit/Controller/ViewAjaxControllerTest.php @@ -9,6 +9,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * @coversDefaultClass \Drupal\views\Controller\ViewAjaxController @@ -16,6 +18,9 @@ */ class ViewAjaxControllerTest extends UnitTestCase { + const USE_AJAX = TRUE; + const USE_NO_AJAX = FALSE; + /** * The mocked view entity storage. * @@ -69,7 +74,7 @@ protected function setUp() { $this->renderer = $this->getMock('\Drupal\Core\Render\RendererInterface'); $this->renderer->expects($this->any()) ->method('render') - ->will($this->returnCallback(function(array &$elements) { + ->will($this->returnCallback(function (array &$elements) { $elements['#attached'] = []; return isset($elements['#markup']) ? $elements['#markup'] : ''; })); @@ -113,18 +118,15 @@ protected function setUp() { /** * Tests missing view_name and view_display_id - * - * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ public function testMissingViewName() { $request = new Request(); + $this->setExpectedException(NotFoundHttpException::class); $this->viewAjaxController->ajaxView($request); } /** * Tests with view_name and view_display_id but not existing view. - * - * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ public function testMissingView() { $request = new Request(); @@ -136,13 +138,12 @@ public function testMissingView() { ->with('test_view') ->will($this->returnValue(FALSE)); + $this->setExpectedException(NotFoundHttpException::class); $this->viewAjaxController->ajaxView($request); } /** * Tests a view without having access to it. - * - * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException */ public function testAccessDeniedView() { $request = new Request(); @@ -170,6 +171,7 @@ public function testAccessDeniedView() { ->with($view) ->will($this->returnValue($executable)); + $this->setExpectedException(AccessDeniedHttpException::class); $this->viewAjaxController->ajaxView($request); } @@ -187,23 +189,6 @@ public function testAjaxView() { list($view, $executable) = $this->setupValidMocks(); - $display_handler = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase') - ->disableOriginalConstructor() - ->getMock(); - // Ensure that the pager element is not set. - $display_handler->expects($this->never()) - ->method('setOption'); - - $display_collection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection') - ->disableOriginalConstructor() - ->getMock(); - $display_collection->expects($this->any()) - ->method('get') - ->with('page_1') - ->will($this->returnValue($display_handler)); - - $executable->displayHandlers = $display_collection; - $this->redirectDestination->expects($this->atLeastOnce()) ->method('set') ->with('/test-page?type=article'); @@ -216,6 +201,24 @@ public function testAjaxView() { $this->assertViewResultCommand($response); } + /** + * Tests a valid view without ajax enabled. + */ + public function testAjaxViewWithoutAjax() { + $request = new Request(); + $request->request->set('view_name', 'test_view'); + $request->request->set('view_display_id', 'page_1'); + $request->request->set('view_path', '/test-page'); + $request->request->set('_wrapper_format', 'ajax'); + $request->request->set('ajax_page_state', 'drupal.settings[]'); + $request->request->set('type', 'article'); + + $this->setupValidMocks(static::USE_NO_AJAX); + + $this->setExpectedException(AccessDeniedHttpException::class); + $this->viewAjaxController->ajaxView($request); + } + /** * Tests a valid view with arguments. */ @@ -228,7 +231,7 @@ public function testAjaxViewWithArguments() { list($view, $executable) = $this->setupValidMocks(); $executable->expects($this->once()) ->method('preview') - ->with('page_1', array('arg1', 'arg2')); + ->with('page_1', ['arg1', 'arg2']); $response = $this->viewAjaxController->ajaxView($request); $this->assertTrue($response instanceof ViewAjaxResponse); @@ -249,7 +252,7 @@ public function testAjaxViewWithEmptyArguments() { list($view, $executable) = $this->setupValidMocks(); $executable->expects($this->once()) ->method('preview') - ->with('page_1', $this->identicalTo(array('arg1', NULL))); + ->with('page_1', $this->identicalTo(['arg1', NULL])); $response = $this->viewAjaxController->ajaxView($request); $this->assertTrue($response instanceof ViewAjaxResponse); @@ -298,8 +301,15 @@ public function testAjaxViewWithPager() { /** * Sets up a bunch of valid mocks like the view entity and executable. + * + * @param bool $use_ajax + * Whether the 'use_ajax' option is set on the view display. Defaults to + * using ajax (TRUE). + * + * @return array + * A pair of view storage entity and executable. */ - protected function setupValidMocks() { + protected function setupValidMocks($use_ajax = self::USE_AJAX) { $view = $this->getMockBuilder('Drupal\views\Entity\View') ->disableOriginalConstructor() ->getMock(); @@ -315,16 +325,40 @@ protected function setupValidMocks() { $executable->expects($this->once()) ->method('access') ->will($this->returnValue(TRUE)); - $executable->expects($this->once()) + $executable->expects($this->any()) + ->method('setDisplay') + ->willReturn(TRUE); + $executable->expects($this->atMost(1)) ->method('preview') - ->will($this->returnValue(array('#markup' => 'View result'))); + ->will($this->returnValue(['#markup' => 'View result'])); $this->executableFactory->expects($this->once()) ->method('get') ->with($view) ->will($this->returnValue($executable)); - return array($view, $executable); + $display_handler = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase') + ->disableOriginalConstructor() + ->getMock(); + // Ensure that the pager element is not set. + $display_handler->expects($this->never()) + ->method('setOption'); + $display_handler->expects($this->any()) + ->method('ajaxEnabled') + ->willReturn($use_ajax); + + $display_collection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection') + ->disableOriginalConstructor() + ->getMock(); + $display_collection->expects($this->any()) + ->method('get') + ->with('page_1') + ->will($this->returnValue($display_handler)); + + $executable->display_handler = $display_handler; + $executable->displayHandlers = $display_collection; + + return [$view, $executable]; } /** diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php index 60ba8e57..99bf037a 100644 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php @@ -9,7 +9,6 @@ use Drupal\Core\Config\Entity\ConfigEntityType; use Drupal\Core\Entity\ContentEntityType; -use Drupal\Core\Entity\EntityType; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Sql\DefaultTableMapping; use Drupal\Core\Field\BaseFieldDefinition; @@ -87,8 +86,14 @@ protected function setUp() { $typed_data_manager = $this->getMock(TypedDataManagerInterface::class); $typed_data_manager->expects($this->any()) - ->method('createDataDefinition') - ->willReturn($this->getMock('Drupal\Core\TypedData\DataDefinitionInterface')); + ->method('createDataDefinition') + ->willReturn($this->getMock('Drupal\Core\TypedData\DataDefinitionInterface')); + + $typed_data_manager->expects($this->any()) + ->method('getDefinition') + ->with($this->equalTo('field_item:string_long')) + ->willReturn(['class' => '\Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem']); + $this->baseEntityType = new TestEntityType([ 'base_table' => 'entity_test', 'id' => 'entity_test', @@ -142,16 +147,16 @@ protected function setupBaseFields(array $base_fields) { ->setLabel('Description') ->setDescription('A description of the term.') ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'text_default', 'weight' => 0, - )) + ]) ->setDisplayConfigurable('view', TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'text_textfield', 'weight' => 0, - )) + ]) ->setDisplayConfigurable('form', TRUE); // Add a URL field; this example is from the Comment entity. @@ -237,8 +242,7 @@ public function testRevisionTableWithoutDataTable() { ->set('revision_table', 'entity_test_mulrev_revision') ->set('revision_data_table', NULL) ->set('id', 'entity_test_mulrev') - ->setKey('revision', 'revision_id') - ; + ->setKey('revision', 'revision_id'); $this->viewsData->setEntityType($entity_type); $data = $this->viewsData->getViewsData(); @@ -273,8 +277,7 @@ public function testRevisionTableWithRevisionDataTableAndDataTable() { ->set('revision_data_table', 'entity_test_mulrev_property_revision') ->set('id', 'entity_test_mulrev') ->set('translatable', TRUE) - ->setKey('revision', 'revision_id') - ; + ->setKey('revision', 'revision_id'); $this->viewsData->setEntityType($entity_type); $data = $this->viewsData->getViewsData(); @@ -293,7 +296,9 @@ public function testRevisionTableWithRevisionDataTableAndDataTable() { $this->assertCount(1, $revision_field_data['table']['join']); $this->assertEquals([ 'entity_test_mul_property_data' => [ - 'left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER' + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', ], ], $revision_field_data['table']['join']); @@ -301,7 +306,9 @@ public function testRevisionTableWithRevisionDataTableAndDataTable() { $this->assertCount(1, $revision_base_data['table']['join']); $this->assertEquals([ 'entity_test_mulrev_property_revision' => [ - 'left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER' + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', ], ], $revision_base_data['table']['join']); @@ -317,8 +324,7 @@ public function testRevisionTableWithRevisionDataTable() { ->set('revision_data_table', 'entity_test_mulrev_property_revision') ->set('id', 'entity_test_mulrev') ->set('translatable', TRUE) - ->setKey('revision', 'revision_id') - ; + ->setKey('revision', 'revision_id'); $this->viewsData->setEntityType($entity_type); $data = $this->viewsData->getViewsData(); @@ -337,7 +343,9 @@ public function testRevisionTableWithRevisionDataTable() { $this->assertCount(1, $revision_field_data['table']['join']); $this->assertEquals([ 'entity_test_mulrev_field_data' => [ - 'left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER' + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', ], ], $revision_field_data['table']['join']); @@ -345,7 +353,9 @@ public function testRevisionTableWithRevisionDataTable() { $this->assertCount(1, $revision_base_data['table']['join']); $this->assertEquals([ 'entity_test_mulrev_property_revision' => [ - 'left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER' + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', ], ], $revision_base_data['table']['join']); $this->assertFalse(isset($data['data_table'])); @@ -527,10 +537,11 @@ public function testBaseTableFields() { 'left_field' => 'id', 'field' => 'entity_id', 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ]], + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], ], $data['entity_test__string']['table']['join']['entity_test']); } @@ -542,8 +553,7 @@ public function testDataTableFields() { ->set('data_table', 'entity_test_mul_property_data') ->set('base_table', 'entity_test_mul') ->set('id', 'entity_test_mul') - ->setKey('bundle', 'type') - ; + ->setKey('bundle', 'type'); $base_field_definitions = $this->setupBaseFields(EntityTestMul::baseFieldDefinitions($this->baseEntityType)); $base_field_definitions['type'] = BaseFieldDefinition::create('entity_reference') ->setLabel('entity test type') @@ -598,7 +608,7 @@ public function testDataTableFields() { $table_mapping->expects($this->any()) ->method('getFieldTableName') - ->willReturnCallback(function($field) { + ->willReturnCallback(function ($field) { if ($field == 'uuid') { return 'entity_test_mul'; } @@ -682,10 +692,11 @@ public function testDataTableFields() { 'left_field' => 'id', 'field' => 'entity_id', 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ]], + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], ], $data['entity_test_mul__string']['table']['join']['entity_test_mul']); } @@ -771,7 +782,7 @@ public function testRevisionTableFields() { $table_mapping->expects($this->any()) ->method('getFieldTableName') - ->willReturnCallback(function($field) { + ->willReturnCallback(function ($field) { if ($field == 'uuid') { return 'entity_test_mulrev'; } @@ -867,10 +878,11 @@ public function testRevisionTableFields() { 'left_field' => 'id', 'field' => 'entity_id', 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ]], + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], ], $data['entity_test_mulrev__string']['table']['join']['entity_test_mulrev_property_data']); $this->assertStringField($data['entity_test_mulrev_revision__string']['string']); @@ -879,10 +891,11 @@ public function testRevisionTableFields() { 'left_field' => 'revision_id', 'field' => 'entity_id', 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ]], + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], ], $data['entity_test_mulrev_revision__string']['table']['join']['entity_test_mulrev_property_revision']); } @@ -1081,7 +1094,7 @@ public function setEntityType(EntityTypeInterface $entity_type) { } -class TestEntityType extends EntityType { +class TestEntityType extends ContentEntityType { /** * Sets a specific entity key. @@ -1107,3 +1120,12 @@ function t($string, array $args = []) { return strtr($string, $args); } } + + +namespace Drupal\Core\Entity; + +if (!function_exists('t')) { + function t($string, array $args = []) { + return strtr($string, $args); + } +} diff --git a/core/modules/views/tests/src/Unit/EventSubscriber/RouteSubscriberTest.php b/core/modules/views/tests/src/Unit/EventSubscriber/RouteSubscriberTest.php index f9d3add2..927551f7 100644 --- a/core/modules/views/tests/src/Unit/EventSubscriber/RouteSubscriberTest.php +++ b/core/modules/views/tests/src/Unit/EventSubscriber/RouteSubscriberTest.php @@ -68,16 +68,16 @@ public function testRouteRebuildFinished() { $display_1->expects($this->once()) ->method('collectRoutes') - ->will($this->returnValue(array('test_id.page_1' => 'views.test_id.page_1'))); + ->will($this->returnValue(['test_id.page_1' => 'views.test_id.page_1'])); $display_2->expects($this->once()) ->method('collectRoutes') - ->will($this->returnValue(array('test_id.page_2' => 'views.test_id.page_2'))); + ->will($this->returnValue(['test_id.page_2' => 'views.test_id.page_2'])); $this->routeSubscriber->routes(); $this->state->expects($this->once()) ->method('set') - ->with('views.view_route_names', array('test_id.page_1' => 'views.test_id.page_1', 'test_id.page_2' => 'views.test_id.page_2')); + ->with('views.view_route_names', ['test_id.page_1' => 'views.test_id.page_1', 'test_id.page_2' => 'views.test_id.page_2']); $this->routeSubscriber->routeRebuildFinished(); } @@ -89,8 +89,8 @@ public function testRouteRebuildFinished() { public function testOnAlterRoutes() { $collection = new RouteCollection(); // The first route will be overridden later. - $collection->add('test_route', new Route('test_route', array('_controller' => 'Drupal\Tests\Core\Controller\TestController'))); - $route_2 = new Route('test_route/example', array('_controller' => 'Drupal\Tests\Core\Controller\TestController')); + $collection->add('test_route', new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController'])); + $route_2 = new Route('test_route/example', ['_controller' => 'Drupal\Tests\Core\Controller\TestController']); $collection->add('test_route_2', $route_2); $route_event = new RouteBuildEvent($collection, 'views'); @@ -101,7 +101,7 @@ public function testOnAlterRoutes() { // should only call the second display. $display_1->expects($this->once()) ->method('collectRoutes') - ->willReturnCallback(function() use ($collection) { + ->willReturnCallback(function () use ($collection) { $collection->add('views.test_id.page_1', new Route('test_route', ['_controller' => 'Drupal\views\Routing\ViewPageController'])); return ['test_id.page_1' => 'views.test_id.page_1']; }); @@ -111,7 +111,7 @@ public function testOnAlterRoutes() { $display_2->expects($this->once()) ->method('collectRoutes') - ->willReturnCallback(function() use ($collection) { + ->willReturnCallback(function () use ($collection) { $collection->add('views.test_id.page_2', new Route('test_route', ['_controller' => 'Drupal\views\Routing\ViewPageController'])); return ['test_id.page_2' => 'views.test_id.page_2']; }); @@ -128,7 +128,7 @@ public function testOnAlterRoutes() { $this->state->expects($this->once()) ->method('set') - ->with('views.view_route_names', array('test_id.page_1' => 'test_route', 'test_id.page_2' => 'views.test_id.page_2')); + ->with('views.view_route_names', ['test_id.page_1' => 'test_route', 'test_id.page_2' => 'views.test_id.page_2']); $collection = $route_event->getRouteCollection(); $this->assertEquals(['test_route', 'test_route_2', 'views.test_id.page_2'], array_keys($collection->all())); @@ -139,8 +139,8 @@ public function testOnAlterRoutes() { /** * Sets up mocks of Views objects needed for testing. * - * @return array \Drupal\views\Plugin\views\display\DisplayRouterInterface[]|\PHPUnit_Framework_MockObject_MockObject[] - * An array of two mocked view displays + * @return \Drupal\views\Plugin\views\display\DisplayRouterInterface[]|\PHPUnit_Framework_MockObject_MockObject[] + * An array of two mocked view displays. */ protected function setupMocks() { $executable = $this->getMockBuilder('Drupal\views\ViewExecutable') @@ -163,11 +163,11 @@ protected function setupMocks() { $executable->expects($this->any()) ->method('setDisplay') - ->will($this->returnValueMap(array( - array('page_1', TRUE), - array('page_2', TRUE), - array('page_3', FALSE), - ))); + ->will($this->returnValueMap([ + ['page_1', TRUE], + ['page_2', TRUE], + ['page_3', FALSE], + ])); // Ensure that only the first two displays are actually called. $display_1 = $this->getMock('Drupal\views\Plugin\views\display\DisplayRouterInterface'); @@ -178,18 +178,18 @@ protected function setupMocks() { ->getMock(); $display_collection->expects($this->any()) ->method('get') - ->will($this->returnValueMap(array( - array('page_1', $display_1), - array('page_2', $display_2), - ))); + ->will($this->returnValueMap([ + ['page_1', $display_1], + ['page_2', $display_2], + ])); $executable->displayHandlers = $display_collection; - $this->routeSubscriber->applicableViews = array(); - $this->routeSubscriber->applicableViews[] = array('test_id', 'page_1'); - $this->routeSubscriber->applicableViews[] = array('test_id', 'page_2'); - $this->routeSubscriber->applicableViews[] = array('test_id', 'page_3'); + $this->routeSubscriber->applicableViews = []; + $this->routeSubscriber->applicableViews[] = ['test_id', 'page_1']; + $this->routeSubscriber->applicableViews[] = ['test_id', 'page_2']; + $this->routeSubscriber->applicableViews[] = ['test_id', 'page_3']; - return array($display_1, $display_2); + return [$display_1, $display_2]; } } diff --git a/core/modules/views/tests/src/Unit/Plugin/Block/ViewsBlockTest.php b/core/modules/views/tests/src/Unit/Plugin/Block/ViewsBlockTest.php index bf4b1226..9323b044 100644 --- a/core/modules/views/tests/src/Unit/Plugin/Block/ViewsBlockTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/Block/ViewsBlockTest.php @@ -6,11 +6,6 @@ use Drupal\Tests\UnitTestCase; use Drupal\views\Plugin\Block\ViewsBlock; -// @todo Remove this once the constant got converted. -if (!defined('BLOCK_LABEL_VISIBLE')) { - define('BLOCK_LABEL_VISIBLE', 'visible'); -} - /** * @coversDefaultClass \Drupal\views\Plugin\block\ViewsBlock * @group views @@ -63,11 +58,12 @@ class ViewsBlockTest extends UnitTestCase { * {@inheritdoc} */ protected function setUp() { - parent::setUp(); // TODO: Change the autogenerated stub + // TODO: Change the autogenerated stub. + parent::setUp(); $condition_plugin_manager = $this->getMock('Drupal\Core\Executable\ExecutableManagerInterface'); $condition_plugin_manager->expects($this->any()) ->method('getDefinitions') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $container = new ContainerBuilder(); $container->set('plugin.manager.condition', $condition_plugin_manager); \Drupal::setContainer($container); @@ -116,6 +112,11 @@ protected function setUp() { $this->displayHandler->expects($this->any()) ->method('getPluginId') ->willReturn('block'); + + $this->displayHandler->expects($this->any()) + ->method('getHandlers') + ->willReturn([]); + $this->executable->display_handler = $this->displayHandler; $this->storage = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigEntityStorage') @@ -136,15 +137,15 @@ protected function setUp() { */ public function testBuild() { $output = $this->randomMachineName(100); - $build = array('view_build' => $output, '#view_id' => 'test_view', '#view_display_plugin_class' => '\Drupal\views\Plugin\views\display\Block', '#view_display_show_admin_links' => FALSE, '#view_display_plugin_id' => 'block', '#pre_rendered' => TRUE); + $build = ['view_build' => $output, '#view_id' => 'test_view', '#view_display_plugin_class' => '\Drupal\views\Plugin\views\display\Block', '#view_display_show_admin_links' => FALSE, '#view_display_plugin_id' => 'block', '#pre_rendered' => TRUE]; $this->executable->expects($this->once()) ->method('buildRenderable') ->with('block_1', []) ->willReturn($build); $block_id = 'views_block:test_view-block_1'; - $config = array(); - $definition = array(); + $config = []; + $definition = []; $definition['provider'] = 'views'; $plugin = new ViewsBlock($config, $block_id, $definition, $this->executableFactory, $this->storage, $this->account); @@ -187,13 +188,13 @@ public function testBuildFailed() { ->willReturn($output); $block_id = 'views_block:test_view-block_1'; - $config = array(); - $definition = array(); + $config = []; + $definition = []; $definition['provider'] = 'views'; $plugin = new ViewsBlock($config, $block_id, $definition, $this->executableFactory, $this->storage, $this->account); - $this->assertEquals(array(), $plugin->build()); + $this->assertEquals([], $plugin->build()); } } diff --git a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php index af9a683f..7ecf9ef0 100644 --- a/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/Derivative/ViewsLocalTaskTest.php @@ -37,10 +37,10 @@ class ViewsLocalTaskTest extends UnitTestCase { */ protected $viewStorage; - protected $baseDefinition = array( + protected $baseDefinition = [ 'class' => '\Drupal\views\Plugin\Menu\LocalTask\ViewsLocalTask', 'deriver' => '\Drupal\views\Plugin\Derivative\ViewsLocalTask' - ); + ]; /** * The tested local task derivative class. @@ -63,11 +63,11 @@ protected function setUp() { * @see \Drupal\views\Plugin\Derivative\ViewsLocalTask::getDerivativeDefinitions() */ public function testGetDerivativeDefinitionsWithoutHookMenuViews() { - $result = array(); + $result = []; $this->localTaskDerivative->setApplicableMenuViews($result); $definitions = $this->localTaskDerivative->getDerivativeDefinitions($this->baseDefinition); - $this->assertEquals(array(), $definitions); + $this->assertEquals([], $definitions); } /** @@ -78,13 +78,13 @@ public function testGetDerivativeDefinitionsWithoutLocalTask() { ->disableOriginalConstructor() ->getMock(); $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setMethods(array('getOption')) + ->setMethods(['getOption']) ->disableOriginalConstructor() ->getMockForAbstractClass(); $display_plugin->expects($this->once()) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'normal'))); + ->will($this->returnValue(['type' => 'normal'])); $executable->display_handler = $display_plugin; $storage = $this->getMockBuilder('Drupal\views\Entity\View') @@ -106,7 +106,7 @@ public function testGetDerivativeDefinitionsWithoutLocalTask() { $this->localTaskDerivative->setApplicableMenuViews($result); $definitions = $this->localTaskDerivative->getDerivativeDefinitions($this->baseDefinition); - $this->assertEquals(array(), $definitions); + $this->assertEquals([], $definitions); } /** @@ -133,20 +133,20 @@ public function testGetDerivativeDefinitionsWithLocalTask() { ->willReturn($storage); $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setMethods(array('getOption')) + ->setMethods(['getOption']) ->disableOriginalConstructor() ->getMockForAbstractClass(); $display_plugin->expects($this->once()) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'tab', 'weight' => 12, 'title' => 'Example title'))); + ->will($this->returnValue(['type' => 'tab', 'weight' => 12, 'title' => 'Example title'])); $executable->display_handler = $display_plugin; $result = [['example_view', 'page_1']]; $this->localTaskDerivative->setApplicableMenuViews($result); // Mock the view route names state. - $view_route_names = array(); + $view_route_names = []; $view_route_names['example_view.page_1'] = 'view.example_view.page_1'; $this->state->expects($this->once()) ->method('get') @@ -186,20 +186,20 @@ public function testGetDerivativeDefinitionsWithOverrideRoute() { ->willReturn($storage); $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setMethods(array('getOption')) + ->setMethods(['getOption']) ->disableOriginalConstructor() ->getMockForAbstractClass(); $display_plugin->expects($this->once()) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'tab', 'weight' => 12))); + ->will($this->returnValue(['type' => 'tab', 'weight' => 12])); $executable->display_handler = $display_plugin; $result = [['example_view', 'page_1']]; $this->localTaskDerivative->setApplicableMenuViews($result); // Mock the view route names state. - $view_route_names = array(); + $view_route_names = []; // Setup a view which overrides an existing route. $view_route_names['example_view.page_1'] = 'example_overridden_route'; $this->state->expects($this->once()) @@ -235,20 +235,20 @@ public function testGetDerivativeDefinitionsWithDefaultLocalTask() { ->willReturn($storage); $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setMethods(array('getOption')) + ->setMethods(['getOption']) ->disableOriginalConstructor() ->getMockForAbstractClass(); $display_plugin->expects($this->exactly(2)) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'default tab', 'weight' => 12, 'title' => 'Example title'))); + ->will($this->returnValue(['type' => 'default tab', 'weight' => 12, 'title' => 'Example title'])); $executable->display_handler = $display_plugin; $result = [['example_view', 'page_1']]; $this->localTaskDerivative->setApplicableMenuViews($result); // Mock the view route names state. - $view_route_names = array(); + $view_route_names = []; $view_route_names['example_view.page_1'] = 'view.example_view.page_1'; $this->state->expects($this->exactly(2)) ->method('get') @@ -304,13 +304,13 @@ public function testGetDerivativeDefinitionsWithExistingLocalTask() { ->willReturn($storage); $display_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setMethods(array('getOption', 'getPath')) + ->setMethods(['getOption', 'getPath']) ->disableOriginalConstructor() ->getMockForAbstractClass(); $display_plugin->expects($this->exactly(2)) ->method('getOption') ->with('menu') - ->will($this->returnValue(array('type' => 'tab', 'weight' => 12, 'title' => 'Example title'))); + ->will($this->returnValue(['type' => 'tab', 'weight' => 12, 'title' => 'Example title'])); $display_plugin->expects($this->once()) ->method('getPath') ->will($this->returnValue('path/example')); @@ -320,7 +320,7 @@ public function testGetDerivativeDefinitionsWithExistingLocalTask() { $this->localTaskDerivative->setApplicableMenuViews($result); // Mock the view route names state. - $view_route_names = array(); + $view_route_names = []; $view_route_names['example_view.page_1'] = 'view.example_view.page_1'; $this->state->expects($this->exactly(2)) ->method('get') @@ -336,11 +336,11 @@ public function testGetDerivativeDefinitionsWithExistingLocalTask() { ->will($this->returnValue($route_collection)); // Setup the existing local task of the test_route. - $definitions['test_route_tab'] = $other_tab = array( + $definitions['test_route_tab'] = $other_tab = [ 'route_name' => 'test_route', 'title' => 'Test route', 'base_route' => 'test_route', - ); + ]; $definitions += $this->localTaskDerivative->getDerivativeDefinitions($this->baseDefinition); diff --git a/core/modules/views/tests/src/Unit/Plugin/HandlerBaseTest.php b/core/modules/views/tests/src/Unit/Plugin/HandlerBaseTest.php index 12b7ca19..ac5a1fe4 100644 --- a/core/modules/views/tests/src/Unit/Plugin/HandlerBaseTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/HandlerBaseTest.php @@ -73,18 +73,22 @@ public function testGetEntityTypeForFieldWithRelationship() { $this->viewsData->expects($this->any()) ->method('get') ->willReturnMap([ - ['test_entity_type_table', [ - 'table' => ['entity type' => 'test_entity_type'], - 'test_relationship' => [ - 'relationship' => [ - 'base' => 'test_other_entity_type_table', - 'base field' => 'id', + [ + 'test_entity_type_table', + [ + 'table' => ['entity type' => 'test_entity_type'], + 'test_relationship' => [ + 'relationship' => [ + 'base' => 'test_other_entity_type_table', + 'base field' => 'id', + ], ], ], - ]], - ['test_other_entity_type_table', [ - 'table' => ['entity type' => 'test_other_entity_type'], - ]], + ], + [ + 'test_other_entity_type_table', + ['table' => ['entity type' => 'test_other_entity_type']], + ], ]); $handler->setViewsData($this->viewsData); diff --git a/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php b/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php index 3b0aebf1..556aef91 100644 --- a/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/area/EntityTest.php @@ -82,7 +82,7 @@ protected function setUp() { ->getMock(); $this->executable->style_plugin = $this->stylePlugin; - $this->entityHandler = new Entity(array(), 'entity', array('entity_type' => 'entity_test'), $this->entityManager); + $this->entityHandler = new Entity([], 'entity', ['entity_type' => 'entity_test'], $this->entityManager); $this->display->expects($this->any()) ->method('getPlugin') diff --git a/core/modules/views/tests/src/Unit/Plugin/area/MessagesTest.php b/core/modules/views/tests/src/Unit/Plugin/area/MessagesTest.php index 07dca650..1c6728da 100644 --- a/core/modules/views/tests/src/Unit/Plugin/area/MessagesTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/area/MessagesTest.php @@ -31,7 +31,7 @@ class MessagesTest extends UnitTestCase { protected function setUp() { parent::setUp(); - $this->messagesHandler = new Messages(array(), 'result', array()); + $this->messagesHandler = new Messages([], 'result', []); } /** @@ -43,15 +43,15 @@ protected function setUp() { public function testRender() { // The handler is configured to show with empty views by default, so should // appear. - $this->assertSame(array('#type' => 'status_messages'), $this->messagesHandler->render()); + $this->assertSame(['#type' => 'status_messages'], $this->messagesHandler->render()); // Turn empty off, and make sure it isn't rendered. $this->messagesHandler->options['empty'] = FALSE; // $empty parameter passed to render will still be FALSE, so should still // appear. - $this->assertSame(array('#type' => 'status_messages'), $this->messagesHandler->render()); + $this->assertSame(['#type' => 'status_messages'], $this->messagesHandler->render()); // Should now be empty as both the empty option and parameter are empty. - $this->assertSame(array(), $this->messagesHandler->render(TRUE)); + $this->assertSame([], $this->messagesHandler->render(TRUE)); } } diff --git a/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php b/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php index 164d4110..a94b672a 100644 --- a/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php @@ -79,7 +79,7 @@ public function testQuery() { public function testResultArea($content, $expected, $items_per_page = 0) { $this->setupViewPager($items_per_page); $this->resultHandler->options['content'] = $content; - $this->assertEquals(array('#markup' => $expected), $this->resultHandler->render()); + $this->assertEquals(['#markup' => $expected], $this->resultHandler->render()); } /** @@ -88,25 +88,25 @@ public function testResultArea($content, $expected, $items_per_page = 0) { * @return array */ public function providerTestResultArea() { - return array( - array('@label', 'ResultTest'), - array('@start', '1'), - array('@start', '1', 1), - array('@end', '100'), - array('@end', '1', 1), - array('@total', '100'), - array('@total', '100', 1), - array('@per_page', '0'), - array('@per_page', '1', 1), - array('@current_page', '1'), - array('@current_page', '1', 1), - array('@current_record_count', '100'), - array('@current_record_count', '1', 1), - array('@page_count', '1'), - array('@page_count', '100', 1), - array('@start | @end | @total', '1 | 100 | 100'), - array('@start | @end | @total', '1 | 1 | 100', 1), - ); + return [ + ['@label', 'ResultTest'], + ['@start', '1'], + ['@start', '1', 1], + ['@end', '100'], + ['@end', '1', 1], + ['@total', '100'], + ['@total', '100', 1], + ['@per_page', '0'], + ['@per_page', '1', 1], + ['@current_page', '1'], + ['@current_page', '1', 1], + ['@current_record_count', '100'], + ['@current_record_count', '1', 1], + ['@page_count', '1'], + ['@page_count', '100', 1], + ['@start | @end | @total', '1 | 100 | 100'], + ['@start | @end | @total', '1 | 1 | 100', 1], + ]; } /** @@ -127,7 +127,7 @@ protected function setupViewPager($items_per_page = 0) { $this->view->pager = $pager->reveal(); $this->view->style_plugin = new \stdClass(); $this->view->total_rows = 100; - $this->view->result = array(1, 2, 3, 4, 5); + $this->view->result = [1, 2, 3, 4, 5]; } } diff --git a/core/modules/views/tests/src/Unit/Plugin/area/ViewTest.php b/core/modules/views/tests/src/Unit/Plugin/area/ViewTest.php index f472ab28..91d52829 100644 --- a/core/modules/views/tests/src/Unit/Plugin/area/ViewTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/area/ViewTest.php @@ -31,7 +31,7 @@ class ViewTest extends UnitTestCase { protected function setUp() { parent::setUp(); $this->entityStorage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); - $this->viewHandler = new ViewAreaPlugin(array(), 'view', array(), $this->entityStorage); + $this->viewHandler = new ViewAreaPlugin([], 'view', [], $this->entityStorage); $this->viewHandler->view = $this->getMockBuilder('Drupal\views\ViewExecutable') ->disableOriginalConstructor() ->getMock(); @@ -60,10 +60,10 @@ public function testCalculateDependencies() { $this->viewHandler->options['view_to_insert'] = 'other:default'; - $this->assertArrayEquals(array('config' => array('view.other')), $this->viewHandler->calculateDependencies()); + $this->assertArrayEquals(['config' => ['view.other']], $this->viewHandler->calculateDependencies()); $this->viewHandler->options['view_to_insert'] = 'this:default'; - $this->assertArrayEquals(array(), $this->viewHandler->calculateDependencies()); + $this->assertArrayEquals([], $this->viewHandler->calculateDependencies()); } } diff --git a/core/modules/views/tests/src/Unit/Plugin/argument_default/QueryParameterTest.php b/core/modules/views/tests/src/Unit/Plugin/argument_default/QueryParameterTest.php index 40016941..8bacd3dc 100644 --- a/core/modules/views/tests/src/Unit/Plugin/argument_default/QueryParameterTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/argument_default/QueryParameterTest.php @@ -28,7 +28,7 @@ public function testGetArgument($options, Request $request, $expected) { ->disableOriginalConstructor() ->getMock(); - $raw = new QueryParameter(array(), 'query_parameter', array()); + $raw = new QueryParameter([], 'query_parameter', []); $raw->init($view, $display_plugin, $options); $this->assertEquals($expected, $raw->getArgument()); } diff --git a/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php b/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php index 365e4694..62c89a9a 100644 --- a/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/argument_default/RawTest.php @@ -39,34 +39,34 @@ public function testGetArgument() { // Don't use aliases. Check against NULL and nonexistent path component // values in addition to valid ones. - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => FALSE, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals(NULL, $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => FALSE, 'index' => 0, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals('test', $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => FALSE, 'index' => 1, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals('example', $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => FALSE, 'index' => 2, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals(NULL, $raw->getArgument()); @@ -77,34 +77,34 @@ public function testGetArgument() { ->with($this->equalTo('/test/example')) ->will($this->returnValue('/other/example')); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => TRUE, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals(NULL, $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => TRUE, 'index' => 0, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals('other', $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => TRUE, 'index' => 1, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals('example', $raw->getArgument()); - $raw = new Raw(array(), 'raw', array(), $alias_manager, $current_path); - $options = array( + $raw = new Raw([], 'raw', [], $alias_manager, $current_path); + $options = [ 'use_alias' => TRUE, 'index' => 2, - ); + ]; $raw->init($view, $display_plugin, $options); $this->assertEquals(NULL, $raw->getArgument()); } diff --git a/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php b/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php index f9ca7d87..13a7bc95 100644 --- a/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/argument_validator/EntityTest.php @@ -47,43 +47,43 @@ protected function setUp() { $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); - $mock_entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(), '', FALSE, TRUE, TRUE, array('bundle', 'access')); + $mock_entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', [], '', FALSE, TRUE, TRUE, ['bundle', 'access']); $mock_entity->expects($this->any()) ->method('bundle') ->will($this->returnValue('test_bundle')); $mock_entity->expects($this->any()) ->method('access') - ->will($this->returnValueMap(array( - array('test_op', NULL, FALSE, TRUE), - array('test_op_2', NULL, FALSE, FALSE), - array('test_op_3', NULL, FALSE, TRUE), - ))); + ->will($this->returnValueMap([ + ['test_op', NULL, FALSE, TRUE], + ['test_op_2', NULL, FALSE, FALSE], + ['test_op_3', NULL, FALSE, TRUE], + ])); - $mock_entity_bundle_2 = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(), '', FALSE, TRUE, TRUE, array('bundle', 'access')); + $mock_entity_bundle_2 = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', [], '', FALSE, TRUE, TRUE, ['bundle', 'access']); $mock_entity_bundle_2->expects($this->any()) ->method('bundle') ->will($this->returnValue('test_bundle_2')); $mock_entity_bundle_2->expects($this->any()) ->method('access') - ->will($this->returnValueMap(array( - array('test_op', NULL, FALSE, FALSE), - array('test_op_2', NULL, FALSE, FALSE), - array('test_op_3', NULL, FALSE, TRUE), - ))); + ->will($this->returnValueMap([ + ['test_op', NULL, FALSE, FALSE], + ['test_op_2', NULL, FALSE, FALSE], + ['test_op_3', NULL, FALSE, TRUE], + ])); $storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); // Setup values for IDs passed as strings or numbers. - $value_map = array( - array(array(), array()), - array(array(1), array(1 => $mock_entity)), - array(array('1'), array(1 => $mock_entity)), - array(array(1, 2), array(1 => $mock_entity, 2 => $mock_entity_bundle_2)), - array(array('1', '2'), array(1 => $mock_entity, 2 => $mock_entity_bundle_2)), - array(array(2), array(2 => $mock_entity_bundle_2)), - array(array('2'), array(2 => $mock_entity_bundle_2)), - ); + $value_map = [ + [[], []], + [[1], [1 => $mock_entity]], + [['1'], [1 => $mock_entity]], + [[1, 2], [1 => $mock_entity, 2 => $mock_entity_bundle_2]], + [['1', '2'], [1 => $mock_entity, 2 => $mock_entity_bundle_2]], + [[2], [2 => $mock_entity_bundle_2]], + [['2'], [2 => $mock_entity_bundle_2]], + ]; $storage->expects($this->any()) ->method('loadMultiple') ->will($this->returnValueMap($value_map)); @@ -100,11 +100,11 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); - $definition = array( + $definition = [ 'entity_type' => 'entity_test', - ); + ]; - $this->argumentValidator = new Entity(array(), 'entity_test', $definition, $this->entityManager); + $this->argumentValidator = new Entity([], 'entity_test', $definition, $this->entityManager); } /** @@ -113,9 +113,9 @@ protected function setUp() { * @see \Drupal\views\Plugin\views\argument_validator\Entity::validateArgument() */ public function testValidateArgumentNoAccess() { - $options = array(); + $options = []; $options['access'] = FALSE; - $options['bundles'] = array(); + $options['bundles'] = []; $this->argumentValidator->init($this->executable, $this->display, $options); $this->assertFalse($this->argumentValidator->validateArgument(3)); @@ -132,9 +132,9 @@ public function testValidateArgumentNoAccess() { * @see \Drupal\views\Plugin\views\argument_validator\Entity::validateArgument() */ public function testValidateArgumentAccess() { - $options = array(); + $options = []; $options['access'] = TRUE; - $options['bundles'] = array(); + $options['bundles'] = []; $options['operation'] = 'test_op'; $this->argumentValidator->init($this->executable, $this->display, $options); @@ -143,9 +143,9 @@ public function testValidateArgumentAccess() { $this->assertTrue($this->argumentValidator->validateArgument(1)); - $options = array(); + $options = []; $options['access'] = TRUE; - $options['bundles'] = array(); + $options['bundles'] = []; $options['operation'] = 'test_op_2'; $this->argumentValidator->init($this->executable, $this->display, $options); @@ -160,9 +160,9 @@ public function testValidateArgumentAccess() { * Tests the validate argument method with bundle checking. */ public function testValidateArgumentBundle() { - $options = array(); + $options = []; $options['access'] = FALSE; - $options['bundles'] = array('test_bundle' => 1); + $options['bundles'] = ['test_bundle' => 1]; $this->argumentValidator->init($this->executable, $this->display, $options); $this->assertTrue($this->argumentValidator->validateArgument(1)); @@ -208,10 +208,10 @@ public function testCalculateDependencies() { ->willReturn($storage); // Set up the argument validator. - $argumentValidator = new Entity(array(), 'entity_test', ['entity_type' => 'entity_test'], $entityManager); - $options = array(); + $argumentValidator = new Entity([], 'entity_test', ['entity_type' => 'entity_test'], $entityManager); + $options = []; $options['access'] = FALSE; - $options['bundles'] = array('test_bundle' => 1); + $options['bundles'] = ['test_bundle' => 1]; $argumentValidator->init($this->executable, $this->display, $options); $this->assertEquals(['config' => ['test_bundle']], $argumentValidator->calculateDependencies()); @@ -221,9 +221,9 @@ public function testCalculateDependencies() { * Tests the validate argument method with multiple argument splitting. */ public function testValidateArgumentMultiple() { - $options = array(); + $options = []; $options['access'] = TRUE; - $options['bundles'] = array(); + $options['bundles'] = []; $options['operation'] = 'test_op'; $options['multiple'] = TRUE; $this->argumentValidator->init($this->executable, $this->display, $options); @@ -234,9 +234,9 @@ public function testValidateArgumentMultiple() { $this->assertFalse($this->argumentValidator->validateArgument('1,2')); $this->assertFalse($this->argumentValidator->validateArgument('1+2')); - $options = array(); + $options = []; $options['access'] = TRUE; - $options['bundles'] = array(); + $options['bundles'] = []; $options['operation'] = 'test_op_3'; $options['multiple'] = TRUE; $this->argumentValidator->init($this->executable, $this->display, $options); diff --git a/core/modules/views/tests/src/Unit/Plugin/display/PageTest.php b/core/modules/views/tests/src/Unit/Plugin/display/PageTest.php index 55ead477..f0091839 100644 --- a/core/modules/views/tests/src/Unit/Plugin/display/PageTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/display/PageTest.php @@ -30,9 +30,9 @@ public function testBuildBasicRenderable() { /** * @covers ::buildBasicRenderable - * @expectedException \BadFunctionCallException */ public function testBuildBasicRenderableWithMissingRoute() { + $this->setExpectedException(\BadFunctionCallException::class); Page::buildBasicRenderable('test_view', 'page_1', []); } diff --git a/core/modules/views/tests/src/Unit/Plugin/display/PathPluginBaseTest.php b/core/modules/views/tests/src/Unit/Plugin/display/PathPluginBaseTest.php index 9241a353..08ec780d 100644 --- a/core/modules/views/tests/src/Unit/Plugin/display/PathPluginBaseTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/display/PathPluginBaseTest.php @@ -55,7 +55,7 @@ protected function setUp() { $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface'); $this->state = $this->getMock('\Drupal\Core\State\StateInterface'); $this->pathPlugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setConstructorArgs(array(array(), 'path_base', array(), $this->routeProvider, $this->state)) + ->setConstructorArgs([[], 'path_base', [], $this->routeProvider, $this->state]) ->setMethods(NULL) ->getMock(); $this->setupContainer(); @@ -71,12 +71,12 @@ public function setupContainer() { $container = new ContainerBuilder(); $container->set('plugin.manager.views.access', $this->accessPluginManager); - $config = array( - 'views.settings' => array( + $config = [ + 'views.settings' => [ 'skip_cache' => TRUE, - 'display_extenders' => array(), - ), - ); + 'display_extenders' => [], + ], + ]; $container->set('config.factory', $this->getConfigFactoryStub($config)); @@ -91,17 +91,17 @@ public function setupContainer() { public function testCollectRoutes() { list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $collection = new RouteCollection(); $result = $this->pathPlugin->collectRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'view.test_id.page_1'), $result); + $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result); $route = $collection->get('view.test_id.page_1'); $this->assertTrue($route instanceof Route); @@ -119,14 +119,14 @@ public function testCollectRoutes() { public function testCollectRoutesWithDisplayReturnResponse() { list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route', - ); + ]; $this->pathPlugin = $this->getMockBuilder('Drupal\views\Plugin\views\display\PathPluginBase') - ->setConstructorArgs(array(array(), 'path_base', array('returns_response' => TRUE), $this->routeProvider, $this->state)) + ->setConstructorArgs([[], 'path_base', ['returns_response' => TRUE], $this->routeProvider, $this->state]) ->setMethods(NULL) ->getMock(); $this->pathPlugin->initDisplay($view, $display); @@ -146,23 +146,23 @@ public function testCollectRoutesWithDisplayReturnResponse() { public function testCollectRoutesWithArguments() { list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route/%/example', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $collection = new RouteCollection(); $result = $this->pathPlugin->collectRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'view.test_id.page_1'), $result); + $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result); $route = $collection->get('view.test_id.page_1'); $this->assertTrue($route instanceof Route); $this->assertEquals('test_id', $route->getDefault('view_id')); $this->assertEquals('page_1', $route->getDefault('display_id')); - $this->assertEquals(array('arg_0' => 'arg_0'), $route->getOption('_view_argument_map')); + $this->assertEquals(['arg_0' => 'arg_0'], $route->getOption('_view_argument_map')); $this->assertEquals('my views title', $route->getDefault('_title')); } @@ -174,26 +174,26 @@ public function testCollectRoutesWithArguments() { public function testCollectRoutesWithArgumentsNotSpecifiedInPath() { list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_with_arguments', - ); - $display['display_options']['arguments'] = array( - 'test_id' => array(), - ); + ]; + $display['display_options']['arguments'] = [ + 'test_id' => [], + ]; $this->pathPlugin->initDisplay($view, $display); $collection = new RouteCollection(); $result = $this->pathPlugin->collectRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'view.test_id.page_1'), $result); + $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result); $route = $collection->get('view.test_id.page_1'); $this->assertTrue($route instanceof Route); $this->assertEquals('test_id', $route->getDefault('view_id')); $this->assertEquals('page_1', $route->getDefault('display_id')); - $this->assertEquals(array('arg_0' => 'arg_0'), $route->getOption('_view_argument_map')); + $this->assertEquals(['arg_0' => 'arg_0'], $route->getOption('_view_argument_map')); $this->assertEquals('my views title', $route->getDefault('_title')); } @@ -203,18 +203,18 @@ public function testCollectRoutesWithArgumentsNotSpecifiedInPath() { public function testCollectRoutesWithSpecialRouteName() { list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route', 'route_name' => 'test_route', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $collection = new RouteCollection(); $result = $this->pathPlugin->collectRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'test_route'), $result); + $this->assertEquals(['test_id.page_1' => 'test_route'], $result); $route = $collection->get('test_route'); $this->assertTrue($route instanceof Route); @@ -228,22 +228,22 @@ public function testCollectRoutesWithSpecialRouteName() { */ public function testAlterRoute() { $collection = new RouteCollection(); - $collection->add('test_route', new Route('test_route', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content'))); - $route_2 = new Route('test_route/example', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content')); + $collection->add('test_route', new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content'])); + $route_2 = new Route('test_route/example', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']); $collection->add('test_route_2', $route_2); list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $view_route_names = $this->pathPlugin->alterRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'test_route'), $view_route_names); + $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names); // Ensure that the test_route is overridden. $route = $collection->get('test_route'); @@ -263,7 +263,7 @@ public function testAlterRoute() { /** * Tests the altering of a REST route. */ - public function testAlterRestRoute() { + public function testAlterPostRestRoute() { $collection = new RouteCollection(); $route = new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']); $route->setMethods(['POST']); @@ -298,27 +298,66 @@ public function testAlterRestRoute() { $this->assertEquals('my views title', $route->getDefault('_title')); } + /** + * Tests the altering of a REST route. + */ + public function testGetRestRoute() { + $collection = new RouteCollection(); + $route = new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']); + $route->setMethods(['GET']); + $route->setRequirement('_format', 'json'); + $collection->add('test_route', $route); + + list($view) = $this->setupViewExecutableAccessPlugin(); + + $display = []; + $display['display_plugin'] = 'page'; + $display['id'] = 'page_1'; + $display['display_options'] = [ + 'path' => 'test_route', + ]; + $this->pathPlugin->initDisplay($view, $display); + + $this->pathPlugin->collectRoutes($collection); + $view_route_names = $this->pathPlugin->alterRoutes($collection); + $this->assertEquals([], $view_route_names); + + // Ensure that the test_route is not overridden. + $this->assertCount(2, $collection); + $route = $collection->get('test_route'); + $this->assertTrue($route instanceof Route); + $this->assertFalse($route->hasDefault('view_id')); + $this->assertFalse($route->hasDefault('display_id')); + $this->assertSame($collection->get('test_route'), $route); + + $route = $collection->get('view.test_id.page_1'); + $this->assertTrue($route instanceof Route); + $this->assertEquals('test_id', $route->getDefault('view_id')); + $this->assertEquals('page_1', $route->getDefault('display_id')); + $this->assertEquals('my views title', $route->getDefault('_title')); + } + /** * Tests the alter route method with preexisting title callback. */ public function testAlterRouteWithAlterCallback() { $collection = new RouteCollection(); - $collection->add('test_route', new Route('test_route', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content', '_title_callback' => '\Drupal\Tests\views\Unit\Plugin\display\TestController::testTitle'))); - $route_2 = new Route('test_route/example', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content')); + $collection->add('test_route', new Route('test_route', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content', '_title_callback' => '\Drupal\Tests\views\Unit\Plugin\display\TestController::testTitle'])); + $route_2 = new Route('test_route/example', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content']); $collection->add('test_route_2', $route_2); list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $view_route_names = $this->pathPlugin->alterRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'test_route'), $view_route_names); + $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names); // Ensure that the test_route is overridden. $route = $collection->get('test_route'); @@ -345,22 +384,22 @@ public function testCollectRoutesWithNamedParameters() { /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */ list($view) = $this->setupViewExecutableAccessPlugin(); - $view->argument = array(); + $view->argument = []; $view->argument['nid'] = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase') ->disableOriginalConstructor() ->getMock(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route/%node/example', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $collection = new RouteCollection(); $result = $this->pathPlugin->collectRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'view.test_id.page_1'), $result); + $this->assertEquals(['test_id.page_1' => 'view.test_id.page_1'], $result); $route = $collection->get('view.test_id.page_1'); $this->assertTrue($route instanceof Route); @@ -368,7 +407,7 @@ public function testCollectRoutesWithNamedParameters() { $this->assertEquals('test_id', $route->getDefault('view_id')); $this->assertEquals('page_1', $route->getDefault('display_id')); $this->assertEquals('my views title', $route->getDefault('_title')); - $this->assertEquals(array('arg_0' => 'node'), $route->getOption('_view_argument_map')); + $this->assertEquals(['arg_0' => 'node'], $route->getOption('_view_argument_map')); } /** @@ -376,7 +415,7 @@ public function testCollectRoutesWithNamedParameters() { */ public function testAlterRoutesWithParameters() { $collection = new RouteCollection(); - $collection->add('test_route', new Route('test_route/{parameter}', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content'))); + $collection->add('test_route', new Route('test_route/{parameter}', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content'])); list($view) = $this->setupViewExecutableAccessPlugin(); @@ -386,16 +425,16 @@ public function testAlterRoutesWithParameters() { ->getMock(); $view->argument['test_id'] = $argument; - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route/%', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $view_route_names = $this->pathPlugin->alterRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'test_route'), $view_route_names); + $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names); // Ensure that the test_route is overridden. $route = $collection->get('test_route'); @@ -404,7 +443,7 @@ public function testAlterRoutesWithParameters() { $this->assertEquals('page_1', $route->getDefault('display_id')); // Ensure that the path did not changed and placeholders are respected. $this->assertEquals('/test_route/{parameter}', $route->getPath()); - $this->assertEquals(array('arg_0' => 'parameter'), $route->getOption('_view_argument_map')); + $this->assertEquals(['arg_0' => 'parameter'], $route->getOption('_view_argument_map')); $this->assertEquals('my views title', $route->getDefault('_title')); } @@ -423,7 +462,7 @@ public function testAlterRoutesWithParametersAndUpcasting() { ->getMock(); $view->argument['test_id'] = $argument; - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; $display['display_options'] = [ @@ -451,24 +490,24 @@ public function testAlterRoutesWithParametersAndUpcasting() { */ public function testAlterRoutesWithOptionalParameters() { $collection = new RouteCollection(); - $collection->add('test_route', new Route('test_route/{parameter}', array('_controller' => 'Drupal\Tests\Core\Controller\TestController::content'))); + $collection->add('test_route', new Route('test_route/{parameter}', ['_controller' => 'Drupal\Tests\Core\Controller\TestController::content'])); list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route/%', - ); - $display['display_options']['arguments'] = array( - 'test_id' => array(), - 'test_id2' => array(), - ); + ]; + $display['display_options']['arguments'] = [ + 'test_id' => [], + 'test_id2' => [], + ]; $this->pathPlugin->initDisplay($view, $display); $view_route_names = $this->pathPlugin->alterRoutes($collection); - $this->assertEquals(array('test_id.page_1' => 'test_route'), $view_route_names); + $this->assertEquals(['test_id.page_1' => 'test_route'], $view_route_names); // Ensure that the test_route is overridden. $route = $collection->get('test_route'); @@ -477,7 +516,7 @@ public function testAlterRoutesWithOptionalParameters() { $this->assertEquals('page_1', $route->getDefault('display_id')); // Ensure that the path did not changed and placeholders are respected. $this->assertEquals('/test_route/{parameter}/{arg_1}', $route->getPath()); - $this->assertEquals(array('arg_0' => 'parameter'), $route->getOption('_view_argument_map')); + $this->assertEquals(['arg_0' => 'parameter'], $route->getOption('_view_argument_map')); $this->assertEquals('my views title', $route->getDefault('_title')); } @@ -487,12 +526,12 @@ public function testAlterRoutesWithOptionalParameters() { public function testGetRouteName() { list($view) = $this->setupViewExecutableAccessPlugin(); - $display = array(); + $display = []; $display['display_plugin'] = 'page'; $display['id'] = 'page_1'; - $display['display_options'] = array( + $display['display_options'] = [ 'path' => 'test_route', - ); + ]; $this->pathPlugin->initDisplay($view, $display); $route_name = $this->pathPlugin->getRouteName(); // Ensure that the expected routename is returned. @@ -529,7 +568,7 @@ protected function setupViewExecutableAccessPlugin() { ->method('createInstance') ->will($this->returnValue($access_plugin)); - return array($view, $view_entity, $access_plugin); + return [$view, $view_entity, $access_plugin]; } } diff --git a/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php b/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php index e6afa89a..4d67c00d 100644 --- a/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php @@ -41,7 +41,7 @@ class CounterTest extends UnitTestCase { * * @var array */ - protected $testData = array(); + protected $testData = []; /** * The handler definition of the counter field. @@ -57,12 +57,12 @@ protected function setUp() { parent::setUp(); // Setup basic stuff like the view and the display. - $config = array(); - $config['display']['default'] = array( + $config = []; + $config['display']['default'] = [ 'id' => 'default', 'display_plugin' => 'default', 'display_title' => 'Default', - ); + ]; $storage = new View($config, 'view'); $user = $this->getMock('Drupal\Core\Session\AccountInterface'); @@ -70,7 +70,7 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface'); - $this->view = $this->getMock('Drupal\views\ViewExecutable', NULL, array($storage, $user, $views_data, $route_provider)); + $this->view = $this->getMock('Drupal\views\ViewExecutable', NULL, [$storage, $user, $views_data, $route_provider]); $this->display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase') ->disableOriginalConstructor() @@ -88,7 +88,7 @@ protected function setUp() { $this->testData[] = new ResultRow($set + ['index' => $index]); } - $this->definition = array('title' => 'counter field', 'plugin_type' => 'field'); + $this->definition = ['title' => 'counter field', 'plugin_type' => 'field']; } /** @@ -98,11 +98,11 @@ protected function setUp() { * Returns an array of row index to test. */ public function providerRowIndexes() { - return array( - array(0), - array(1), - array(2), - ); + return [ + [0], + [1], + [2], + ]; } /** @@ -111,8 +111,8 @@ public function providerRowIndexes() { * @dataProvider providerRowIndexes */ public function testSimpleCounter($i) { - $counter_handler = new Counter(array(), 'counter', $this->definition); - $options = array(); + $counter_handler = new Counter([], 'counter', $this->definition); + $options = []; $counter_handler->init($this->view, $this->display, $options); $this->view->row_index = $i; @@ -135,10 +135,10 @@ public function testSimpleCounter($i) { public function testCounterRandomStart($i) { // Setup a counter field with a random start. $rand_start = rand(5, 10); - $counter_handler = new Counter(array(), 'counter', $this->definition); - $options = array( + $counter_handler = new Counter([], 'counter', $this->definition); + $options = [ 'counter_start' => $rand_start, - ); + ]; $counter_handler->init($this->view, $this->display, $options); $this->view->row_index = $i; @@ -164,10 +164,10 @@ public function testCounterRandomPagerOffset($i) { $this->pager->setOffset($offset); $rand_start = rand(5, 10); - $counter_handler = new Counter(array(), 'counter', $this->definition); - $options = array( + $counter_handler = new Counter([], 'counter', $this->definition); + $options = [ 'counter_start' => $rand_start, - ); + ]; $counter_handler->init($this->view, $this->display, $options); $this->view->row_index = $i; @@ -197,10 +197,10 @@ public function testCounterSecondPage($i) { $this->pager->setCurrentPage($current_page); $rand_start = rand(5, 10); - $counter_handler = new Counter(array(), 'counter', $this->definition); - $options = array( + $counter_handler = new Counter([], 'counter', $this->definition); + $options = [ 'counter_start' => $rand_start, - ); + ]; $counter_handler->init($this->view, $this->display, $options); $this->view->row_index = $i; diff --git a/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php b/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php index 0b33a589..a7bcf81d 100644 --- a/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php @@ -548,7 +548,7 @@ public function testRenderAsLinkWithPathAndTokens($path, $tokens, $link_html) { '#type' => 'inline_template', '#template' => 'test-path/' . explode('/', $path)[1], '#context' => ['foo' => 123], - '#post_render' => [function() {}], + '#post_render' => [function () {}], ]; $this->renderer->expects($this->once()) @@ -612,7 +612,7 @@ public function testRenderAsExternalLinkWithPathAndTokens($path, $tokens, $link_ '#type' => 'inline_template', '#template' => $path, '#context' => ['foo' => $context['context_path']], - '#post_render' => [function() {}], + '#post_render' => [function () {}], ]; $this->renderer->expects($this->once()) @@ -717,6 +717,50 @@ public function testGetRenderTokensWithArguments() { $this->assertEquals($expected, $field->getRenderTokens([])); } + /** + * Ensures proper token replacement when generating CSS classes. + * + * @covers ::elementClasses + * @covers ::elementLabelClasses + * @covers ::elementWrapperClasses + */ + public function testElementClassesWithTokens() { + $functions = [ + 'elementClasses' => 'element_class', + 'elementLabelClasses' => 'element_label_class', + 'elementWrapperClasses' => 'element_wrapper_class', + ]; + + $tokens = ['test_token' => 'foo']; + $test_class = 'test-class-without-token test-class-with-{{ test_token }}-token'; + $expected_result = 'test-class-without-token test-class-with-foo-token'; + + // Inline template to render the tokens. + $build = [ + '#type' => 'inline_template', + '#template' => $test_class, + '#context' => $tokens, + '#post_render' => [function () {}], + ]; + + // We're not testing the token rendering itself, just that the function + // being tested correctly handles tokens when generating the element's class + // attribute. + $this->renderer->expects($this->any()) + ->method('renderPlain') + ->with($build) + ->willReturn($expected_result); + + foreach ($functions as $callable => $option_name) { + $field = $this->setupTestField([$option_name => $test_class]); + $field->view->style_plugin = new \stdClass(); + $field->view->style_plugin->render_tokens[] = $tokens; + + $result = $field->{$callable}(0); + $this->assertEquals($expected_result, $result); + } + } + } class FieldPluginBaseTestField extends FieldPluginBase { diff --git a/core/modules/views/tests/src/Unit/Plugin/field/FieldTest.php b/core/modules/views/tests/src/Unit/Plugin/field/FieldTest.php index 90bd2ccb..2b929f36 100644 --- a/core/modules/views/tests/src/Unit/Plugin/field/FieldTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/field/FieldTest.php @@ -10,12 +10,12 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Tests\UnitTestCase; use Drupal\Tests\views\Unit\Plugin\HandlerTestTrait; -use Drupal\views\Plugin\views\field\Field; +use Drupal\views\Plugin\views\field\EntityField; use Drupal\views\ResultRow; use Symfony\Component\DependencyInjection\ContainerBuilder; /** - * @coversDefaultClass \Drupal\views\Plugin\views\field\Field + * @coversDefaultClass \Drupal\views\Plugin\views\field\EntityField * @group views */ class FieldTest extends UnitTestCase { @@ -107,7 +107,7 @@ public function testConstruct() { // provides it. 'entity field' => 'title', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $this->assertEquals('title', $handler->definition['field_name']); } @@ -120,7 +120,7 @@ public function testDefineOptionsWithNoOptions() { 'entity_type' => 'test_entity', 'field_name' => 'title' ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); // Setup the entity manager to allow fetching the storage definitions. $title_storage = $this->getBaseFieldStorage(); @@ -149,7 +149,7 @@ public function testDefineOptionsWithDefaultFormatterOnFieldDefinition() { 'default_formatter' => 'test_example', 'default_formatter_settings' => ['link_to_entity' => TRUE] ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); // Setup the entity manager to allow fetching the storage definitions. $title_storage = $this->getBaseFieldStorage(); @@ -176,7 +176,7 @@ public function testDefineOptionsWithDefaultFormatterOnFieldType() { 'field_name' => 'title', 'default_formatter_settings' => ['link_to_entity' => TRUE] ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); // Setup the entity manager to allow fetching the storage definitions. $title_storage = $this->getBaseFieldStorage(); @@ -202,7 +202,7 @@ public function testCalculateDependenciesWithBaseField() { 'entity_type' => 'test_entity', 'field_name' => 'title' ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $title_storage = $this->getBaseFieldStorage(); $this->entityManager->expects($this->atLeastOnce()) @@ -224,7 +224,7 @@ public function testCalculateDependenciesWithConfiguredField() { 'entity_type' => 'test_entity', 'field_name' => 'body' ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $body_storage = $this->getConfigFieldStorage(); $this->entityManager->expects($this->atLeastOnce()) @@ -250,7 +250,7 @@ public function testAccess() { 'entity_type' => 'test_entity', 'field_name' => 'title', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $handler->setViewsData($this->viewsData); @@ -301,7 +301,7 @@ public function testClickSortWithOutConfiguredColumn($order) { 'entity_type' => 'test_entity', 'field_name' => 'title', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $this->entityManager->expects($this->never()) @@ -323,7 +323,7 @@ public function testClickSortWithBaseField($order) { 'entity_type' => 'test_entity', 'field_name' => 'title', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $field_storage = $this->getBaseFieldStorage(); @@ -383,7 +383,7 @@ public function testClickSortWithConfiguredField($order) { 'entity_type' => 'test_entity', 'field_name' => 'body', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $field_storage = $this->getConfigFieldStorage(); @@ -438,7 +438,7 @@ public function testQueryWithGroupByForBaseField() { 'entity_type' => 'test_entity', 'field_name' => 'title', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $handler->view->field = [$handler]; @@ -500,7 +500,7 @@ public function testQueryWithGroupByForConfigField() { 'entity_type' => 'test_entity', 'field_name' => 'body', ]; - $handler = new Field([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new EntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $handler->view->field = [$handler]; @@ -564,7 +564,7 @@ public function testPrepareItemsByDelta(array $options, array $expected_values) 'entity_type' => 'test_entity', 'field_name' => 'integer', ]; - $handler = new FieldTestField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); + $handler = new FieldTestEntityField([], 'field', $definition, $this->entityManager, $this->formatterPluginManager, $this->fieldTypePluginManager, $this->languageManager, $this->renderer); $handler->view = $this->executable; $handler->view->field = [$handler]; @@ -688,12 +688,12 @@ public function providerSortOrders() { /** * Setup the mock data needed to make language renderers work. * - * @param \Drupal\views\Plugin\views\field\Field $handler + * @param \Drupal\views\Plugin\views\field\EntityField $handler * The field handler. * @param $definition * An array with entity type definition data. */ - protected function setupLanguageRenderer(Field $handler, $definition) { + protected function setupLanguageRenderer(EntityField $handler, $definition) { $display_handler = $this->getMockBuilder('\Drupal\views\Plugin\views\display\DisplayPluginBase') ->disableOriginalConstructor() ->getMock(); @@ -724,7 +724,7 @@ protected function setupLanguageRenderer(Field $handler, $definition) { } -class FieldTestField extends Field { +class FieldTestEntityField extends EntityField { public function executePrepareItemsByDelta(array $all_values) { return $this->prepareItemsByDelta($all_values); diff --git a/core/modules/views/tests/src/Unit/Plugin/pager/PagerPluginBaseTest.php b/core/modules/views/tests/src/Unit/Plugin/pager/PagerPluginBaseTest.php index f137105d..ef0e812a 100644 --- a/core/modules/views/tests/src/Unit/Plugin/pager/PagerPluginBaseTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/pager/PagerPluginBaseTest.php @@ -9,6 +9,7 @@ use Drupal\Tests\UnitTestCase; use Drupal\Core\Database\StatementInterface; +use Drupal\Core\Database\Query\Select; /** * @coversDefaultClass \Drupal\views\Plugin\views\pager\PagerPluginBase @@ -35,10 +36,10 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); - $options = array( + $options = [ 'items_per_page' => 5, 'offset' => 1, - ); + ]; $this->pager->init($view, $display, $options); @@ -183,20 +184,20 @@ public function testHasMoreRecords($items_per_page, $total_items, $current_page, * @see self::testHasMoreRecords */ public function providerTestHasMoreRecords() { - return array( + return [ // No items per page, so there can't be more available records. - array(0, 0, 0, FALSE), - array(0, 10, 0, FALSE), + [0, 0, 0, FALSE], + [0, 10, 0, FALSE], // The amount of total items equals the items per page, so there is no // next page available. - array(5, 5, 0, FALSE), + [5, 5, 0, FALSE], // There is one more item, and we are at the first page. - array(5, 6, 0, TRUE), + [5, 6, 0, TRUE], // Now we are on the second page, which has just a single one left. - array(5, 6, 1, FALSE), + [5, 6, 1, FALSE], // Increase the total items, so we have some available on the third page. - array(5, 12, 1, TRUE) - ); + [5, 12, 1, TRUE] + ]; } /** @@ -247,6 +248,30 @@ public function testExecuteCountQueryWithOffset() { $this->assertEquals(1, $this->pager->executeCountQuery($query)); } + /** + * Tests the executeCountQuery method with an offset larger than result count. + * + * @see \Drupal\views\Plugin\views\pager\PagerPluginBase::executeCountQuery() + */ + public function testExecuteCountQueryWithOffsetLargerThanResult() { + $statement = $this->getMock(TestStatementInterface::class); + + $statement->expects($this->once()) + ->method('fetchField') + ->will($this->returnValue(2)); + + $query = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $query->expects($this->once()) + ->method('execute') + ->will($this->returnValue($statement)); + + $this->pager->setOffset(3); + $this->assertEquals(0, $this->pager->executeCountQuery($query)); + } + } /** diff --git a/core/modules/views/tests/src/Unit/Plugin/query/SqlTest.php b/core/modules/views/tests/src/Unit/Plugin/query/SqlTest.php index 02a5ce64..bae90240 100644 --- a/core/modules/views/tests/src/Unit/Plugin/query/SqlTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/query/SqlTest.php @@ -139,7 +139,7 @@ protected function setupEntityTypeManager(EntityTypeManagerInterface $entity_typ * * @param \Drupal\Core\Entity\EntityInterface[][] $entities_by_type * Test entities keyed by entity type and entity ID. - * @param \Drupal\Core\Entity\EntityInterface[][] $entities_by_type + * @param \Drupal\Core\Entity\EntityInterface[][] $entity_revisions_by_type * Test entities keyed by entity type and revision ID. * * @return \Prophecy\Prophecy\ObjectProphecy diff --git a/core/modules/views/tests/src/Unit/Plugin/views/display/BlockTest.php b/core/modules/views/tests/src/Unit/Plugin/views/display/BlockTest.php index a3e86a1f..21af7bf3 100644 --- a/core/modules/views/tests/src/Unit/Plugin/views/display/BlockTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/views/display/BlockTest.php @@ -39,7 +39,7 @@ protected function setUp() { $this->executable = $this->getMockBuilder('Drupal\views\ViewExecutable') ->disableOriginalConstructor() - ->setMethods(array('executeDisplay', 'setDisplay', 'setItemsPerPage')) + ->setMethods(['executeDisplay', 'setDisplay', 'setItemsPerPage']) ->getMock(); $this->executable->expects($this->any()) ->method('setDisplay') @@ -67,7 +67,7 @@ public function testBuildNoOverride() { $this->blockPlugin->expects($this->once()) ->method('getConfiguration') - ->will($this->returnValue(array('items_per_page' => 'none'))); + ->will($this->returnValue(['items_per_page' => 'none'])); $this->blockDisplay->preBlockBuild($this->blockPlugin); } @@ -82,7 +82,7 @@ public function testBuildOverride() { $this->blockPlugin->expects($this->once()) ->method('getConfiguration') - ->will($this->returnValue(array('items_per_page' => 5))); + ->will($this->returnValue(['items_per_page' => 5])); $this->blockDisplay->preBlockBuild($this->blockPlugin); } diff --git a/core/modules/views/tests/src/Unit/Plugin/views/field/EntityOperationsUnitTest.php b/core/modules/views/tests/src/Unit/Plugin/views/field/EntityOperationsUnitTest.php index 5457baa6..0900df69 100644 --- a/core/modules/views/tests/src/Unit/Plugin/views/field/EntityOperationsUnitTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/views/field/EntityOperationsUnitTest.php @@ -42,11 +42,11 @@ protected function setUp() { $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface'); $this->languageManager = $this->getMock('\Drupal\Core\Language\LanguageManagerInterface'); - $configuration = array(); + $configuration = []; $plugin_id = $this->randomMachineName(); - $plugin_definition = array( + $plugin_definition = [ 'title' => $this->randomMachineName(), - ); + ]; $this->plugin = new EntityOperations($configuration, $plugin_id, $plugin_definition, $this->entityManager, $this->languageManager); $redirect_service = $this->getMock('Drupal\Core\Routing\RedirectDestinationInterface'); @@ -93,11 +93,11 @@ public function testRenderWithDestination() { ->method('getEntityTypeId') ->will($this->returnValue($entity_type_id)); - $operations = array( - 'foo' => array( + $operations = [ + 'foo' => [ 'title' => $this->randomMachineName(), - ), - ); + ], + ]; $list_builder = $this->getMock('\Drupal\Core\Entity\EntityListBuilderInterface'); $list_builder->expects($this->once()) ->method('getOperations') @@ -114,10 +114,10 @@ public function testRenderWithDestination() { $result = new ResultRow(); $result->_entity = $entity; - $expected_build = array( + $expected_build = [ '#type' => 'operations', '#links' => $operations - ); + ]; $expected_build['#links']['foo']['query'] = ['destination' => 'foobar']; $build = $this->plugin->render($result); $this->assertSame($expected_build, $build); @@ -135,11 +135,11 @@ public function testRenderWithoutDestination() { ->method('getEntityTypeId') ->will($this->returnValue($entity_type_id)); - $operations = array( - 'foo' => array( + $operations = [ + 'foo' => [ 'title' => $this->randomMachineName(), - ), - ); + ], + ]; $list_builder = $this->getMock('\Drupal\Core\Entity\EntityListBuilderInterface'); $list_builder->expects($this->once()) ->method('getOperations') @@ -156,10 +156,10 @@ public function testRenderWithoutDestination() { $result = new ResultRow(); $result->_entity = $entity; - $expected_build = array( + $expected_build = [ '#type' => 'operations', '#links' => $operations - ); + ]; $build = $this->plugin->render($result); $this->assertSame($expected_build, $build); } diff --git a/core/modules/views/tests/src/Unit/PluginBaseTest.php b/core/modules/views/tests/src/Unit/PluginBaseTest.php index ef19e116..622b42a8 100644 --- a/core/modules/views/tests/src/Unit/PluginBaseTest.php +++ b/core/modules/views/tests/src/Unit/PluginBaseTest.php @@ -24,7 +24,7 @@ class PluginBaseTest extends UnitTestCase { protected function setUp() { parent::setUp(); - $this->testHelperPlugin = new TestHelperPlugin(array(), 'default', array()); + $this->testHelperPlugin = new TestHelperPlugin([], 'default', []); } /** @@ -73,148 +73,145 @@ public function testSetOptionDefault($storage, $definition, $expected) { * @return array */ public function providerTestUnpackOptions() { - $test_parameters = array(); + $test_parameters = []; // Set a storage but no value, so the storage value should be kept. - $test_parameters[] = array( - 'storage' => array( + $test_parameters[] = [ + 'storage' => [ 'key' => 'value', - ), - 'options' => array( - ), - 'definition' => array( - 'key' => array('default' => 'value2'), - ), - 'expected' => array( + ], + 'options' => [], + 'definition' => [ + 'key' => ['default' => 'value2'], + ], + 'expected' => [ 'key' => 'value', - ), - ); + ], + ]; // Set a storage and a option value, so the option value should be kept. - $test_parameters[] = array( - 'storage' => array( + $test_parameters[] = [ + 'storage' => [ 'key' => 'value', - ), - 'options' => array( + ], + 'options' => [ 'key' => 'value2', - ), - 'definition' => array( - 'key' => array('default' => 'value3'), - ), - 'expected' => array( + ], + 'definition' => [ + 'key' => ['default' => 'value3'], + ], + 'expected' => [ 'key' => 'value2', - ), + ], '' - ); + ]; // Set no storage but an options value, so the options value should be kept. - $test_parameters[] = array( - 'storage' => array(), - 'options' => array( + $test_parameters[] = [ + 'storage' => [], + 'options' => [ 'key' => 'value', - ), - 'definition' => array( - 'key' => array('default' => 'value2'), - ), - 'expected' => array( + ], + 'definition' => [ + 'key' => ['default' => 'value2'], + ], + 'expected' => [ 'key' => 'value', - ), - ); + ], + ]; // Set additional options, which aren't part of the definition, so they // should be ignored if all is set. - $test_parameters[] = array( - 'storage' => array(), - 'options' => array( + $test_parameters[] = [ + 'storage' => [], + 'options' => [ 'key' => 'value', 'key2' => 'value2', - ), - 'definition' => array( - 'key' => array('default' => 'value2'), - ), - 'expected' => array( + ], + 'definition' => [ + 'key' => ['default' => 'value2'], + ], + 'expected' => [ 'key' => 'value', - ), - ); - $test_parameters[] = array( - 'storage' => array(), - 'options' => array( + ], + ]; + $test_parameters[] = [ + 'storage' => [], + 'options' => [ 'key' => 'value', 'key2' => 'value2', - ), - 'definition' => array( - 'key' => array('default' => 'value2'), - ), - 'expected' => array( + ], + 'definition' => [ + 'key' => ['default' => 'value2'], + ], + 'expected' => [ 'key' => 'value', 'key2' => 'value2', - ), + ], 'all' => TRUE, - ); + ]; // Provide multiple options with their corresponding definition. - $test_parameters[] = array( - 'storage' => array(), - 'options' => array( + $test_parameters[] = [ + 'storage' => [], + 'options' => [ 'key' => 'value', 'key2' => 'value2', - ), - 'definition' => array( - 'key' => array('default' => 'value2'), - 'key2' => array('default' => 'value3'), - ), - 'expected' => array( + ], + 'definition' => [ + 'key' => ['default' => 'value2'], + 'key2' => ['default' => 'value3'], + ], + 'expected' => [ 'key' => 'value', 'key2' => 'value2', - ), - ); + ], + ]; // Set a complex definition structure with a zero and a one level structure. - $test_parameters[] = array( - 'storage' => array(), - 'options' => array( + $test_parameters[] = [ + 'storage' => [], + 'options' => [ 'key0' => 'value', - 'key1' => array('key1:1' => 'value1', 'key1:2' => 'value2'), - ), - 'definition' => array( - 'key0' => array('default' => 'value0'), - 'key1' => array('contains' => array( - 'key1:1' => array('default' => 'value1:1'), - )), - ), - 'expected' => array( + 'key1' => ['key1:1' => 'value1', 'key1:2' => 'value2'], + ], + 'definition' => [ + 'key0' => ['default' => 'value0'], + 'key1' => ['contains' => ['key1:1' => ['default' => 'value1:1']]], + ], + 'expected' => [ 'key0' => 'value', - 'key1' => array('key1:1' => 'value1'), - ), - ); + 'key1' => ['key1:1' => 'value1'], + ], + ]; // Setup a two level structure. - $test_parameters[] = array( - 'storage' => array(), - 'options' => array( - 'key2' => array( - 'key2:1' => array( + $test_parameters[] = [ + 'storage' => [], + 'options' => [ + 'key2' => [ + 'key2:1' => [ 'key2:1:1' => 'value0', - 'key2:1:2' => array( - 'key2:1:2:1' => 'value1', - ), - ), - ), - ), - 'definition' => array( - 'key2' => array('contains' => array( - 'key2:1' => array('contains' => array( - 'key2:1:1' => array('default' => 'value2:1:2:1'), - 'key2:1:2' => array('contains' => array( - 'key2:1:2:1' => array('default' => 'value2:1:2:1'), - )), - )), - )), - ), - 'expected' => array( - 'key2' => array( - 'key2:1' => array( + 'key2:1:2' => ['key2:1:2:1' => 'value1'], + ], + ], + ], + 'definition' => [ + 'key2' => [ + 'contains' => [ + 'key2:1' => [ + 'contains' => [ + 'key2:1:1' => ['default' => 'value2:1:2:1'], + 'key2:1:2' => [ + 'contains' => ['key2:1:2:1' => ['default' => 'value2:1:2:1']], + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'key2' => [ + 'key2:1' => [ 'key2:1:1' => 'value0', - 'key2:1:2' => array( - 'key2:1:2:1' => 'value1', - ), - ), - ), - ), - ); + 'key2:1:2' => ['key2:1:2:1' => 'value1'], + ], + ], + ], + ]; return $test_parameters; } @@ -225,55 +222,57 @@ public function providerTestUnpackOptions() { * @return array */ public function providerTestSetOptionDefault() { - $test_parameters = array(); + $test_parameters = []; // No definition should change anything on the storage. - $test_parameters[] = array( - 'storage' => array(), - 'definition' => array(), - 'expected' => array(), - ); + $test_parameters[] = [ + 'storage' => [], + 'definition' => [], + 'expected' => [], + ]; // Set a single definition, which should be picked up. - $test_parameters[] = array( - 'storage' => array(), - 'definition' => array( - 'key' => array('default' => 'value'), - ), - 'expected' => array( + $test_parameters[] = [ + 'storage' => [], + 'definition' => [ + 'key' => ['default' => 'value'], + ], + 'expected' => [ 'key' => 'value', - ), - ); + ], + ]; // Set multiple keys, all should be picked up. - $test_parameters[] = array( - 'storage' => array(), - 'definition' => array( - 'key' => array('default' => 'value'), - 'key2' => array('default' => 'value2'), - 'key3' => array('default' => 'value3'), - ), - 'expected' => array( + $test_parameters[] = [ + 'storage' => [], + 'definition' => [ + 'key' => ['default' => 'value'], + 'key2' => ['default' => 'value2'], + 'key3' => ['default' => 'value3'], + ], + 'expected' => [ 'key' => 'value', 'key2' => 'value2', 'key3' => 'value3', - ), - ); + ], + ]; // Setup a definition with multiple levels. - $test_parameters[] = array( - 'storage' => array(), - 'definition' => array( - 'key' => array('default' => 'value'), - 'key2' => array('contains' => array( - 'key2:1' => array('default' => 'value2:1'), - 'key2:2' => array('default' => 'value2:2'), - )), - ), - 'expected' => array( + $test_parameters[] = [ + 'storage' => [], + 'definition' => [ + 'key' => ['default' => 'value'], + 'key2' => [ + 'contains' => [ + 'key2:1' => ['default' => 'value2:1'], + 'key2:2' => ['default' => 'value2:2'], + ], + ], + ], + 'expected' => [ 'key' => 'value', - 'key2' => array( + 'key2' => [ 'key2:1' => 'value2:1', 'key2:2' => 'value2:2', - ), - ), - ); + ], + ], + ]; return $test_parameters; } diff --git a/core/modules/views/tests/src/Unit/PluginTypeListTest.php b/core/modules/views/tests/src/Unit/PluginTypeListTest.php index 32b46d51..29da6b3a 100644 --- a/core/modules/views/tests/src/Unit/PluginTypeListTest.php +++ b/core/modules/views/tests/src/Unit/PluginTypeListTest.php @@ -16,7 +16,7 @@ class PluginTypeListTest extends UnitTestCase { * Tests the plugins list is correct. */ public function testPluginList() { - $plugin_list = array( + $plugin_list = [ 'access', 'area', 'argument', @@ -36,7 +36,7 @@ public function testPluginList() { 'sort', 'style', 'wizard', - ); + ]; $diff = array_diff($plugin_list, ViewExecutable::getPluginTypes()); $this->assertTrue(empty($diff), 'The plugin list is correct'); diff --git a/core/modules/views/tests/src/Unit/Routing/ViewPageControllerTest.php b/core/modules/views/tests/src/Unit/Routing/ViewPageControllerTest.php index 971c1c49..9242545b 100644 --- a/core/modules/views/tests/src/Unit/Routing/ViewPageControllerTest.php +++ b/core/modules/views/tests/src/Unit/Routing/ViewPageControllerTest.php @@ -148,7 +148,7 @@ public function testHandleWithArgumentsOnOverriddenRouteWithUpcasting() { $request->attributes->set('display_id', 'page_1'); // Add the argument to the request. $request->attributes->set('test_entity', $this->getMock('Drupal\Core\Entity\EntityInterface')); - $raw_variables = new ParameterBag(array('test_entity' => 'example_id')); + $raw_variables = new ParameterBag(['test_entity' => 'example_id']); $request->attributes->set('_raw_variables', $raw_variables); $options = [ '_view_argument_map' => [ diff --git a/core/modules/views/tests/src/Unit/ViewExecutableTest.php b/core/modules/views/tests/src/Unit/ViewExecutableTest.php index fe64ec27..b6d3c912 100644 --- a/core/modules/views/tests/src/Unit/ViewExecutableTest.php +++ b/core/modules/views/tests/src/Unit/ViewExecutableTest.php @@ -182,8 +182,6 @@ public function testGetUrlWithPathNoPlaceholders() { } /** - * @expectedException \InvalidArgumentException - * * @covers ::getUrl */ public function testGetUrlWithoutRouterDisplay() { @@ -193,6 +191,7 @@ public function testGetUrlWithoutRouterDisplay() { ->willReturn($this->displayHandler); $this->executable->display_handler = $this->displayHandler; + $this->setExpectedException(\InvalidArgumentException::class); $this->executable->getUrl(); } @@ -312,7 +311,7 @@ public function testBuildThemeFunctions() { ]; $this->assertEquals($expected, $view->buildThemeFunctions('test_hook')); - //Change the name of the display plugin and make sure that is in the array. + // Change the name of the display plugin and make sure that is in the array. $view->display_handler->display['display_plugin'] = 'default2'; $expected = [ @@ -363,14 +362,16 @@ public function testAddHandler() { foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) { $display->expects($this->atLeastOnce()) ->method('setOption') - ->with($this->callback(function($argument) { + ->with($this->callback(function ($argument) { return $argument; - }), ['test_field' => [ - 'id' => 'test_field', - 'table' => 'test_entity', - 'field' => 'test_field', - 'plugin_id' => 'standard', - ]]); + }), [ + 'test_field' => [ + 'id' => 'test_field', + 'table' => 'test_entity', + 'field' => 'test_field', + 'plugin_id' => 'standard', + ], + ]); } foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) { @@ -404,16 +405,18 @@ public function testAddHandlerWithEntityField() { foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) { $display->expects($this->atLeastOnce()) ->method('setOption') - ->with($this->callback(function($argument) { + ->with($this->callback(function ($argument) { return $argument; - }), ['test_field' => [ - 'id' => 'test_field', - 'table' => 'test_entity', - 'field' => 'test_field', - 'entity_type' => 'test_entity_type', - 'entity_field' => 'test_field', - 'plugin_id' => 'standard', - ]]); + }), [ + 'test_field' => [ + 'id' => 'test_field', + 'table' => 'test_entity', + 'field' => 'test_field', + 'entity_type' => 'test_entity_type', + 'entity_field' => 'test_field', + 'plugin_id' => 'standard', + ], + ]); } foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) { @@ -476,7 +479,7 @@ public function testAttachDisplays() { * Returns the view executable and default display. */ protected function setupBaseViewAndDisplay() { - $config = array( + $config = [ 'id' => 'test_view', 'tag' => 'OnE, TWO, and three', 'display' => [ @@ -486,7 +489,7 @@ protected function setupBaseViewAndDisplay() { 'display_title' => 'Default', ], ], - ); + ]; $storage = new View($config, 'view'); $view = new ViewExecutable($storage, $this->user, $this->viewsData, $this->routeProvider); @@ -516,7 +519,7 @@ protected function setupBaseViewAndDisplay() { $view->$type = []; } - return array($view, $display); + return [$view, $display]; } /** diff --git a/core/modules/views/tests/src/Unit/ViewsDataHelperTest.php b/core/modules/views/tests/src/Unit/ViewsDataHelperTest.php index 97153f5c..b08938c2 100644 --- a/core/modules/views/tests/src/Unit/ViewsDataHelperTest.php +++ b/core/modules/views/tests/src/Unit/ViewsDataHelperTest.php @@ -30,7 +30,7 @@ protected function viewsData() { $data['views_test_data']['age']['area']['id'] = 'text'; $data['views_test_data']['age']['area']['sub_type'] = 'header'; $data['views_test_data']['job']['area']['id'] = 'text'; - $data['views_test_data']['job']['area']['sub_type'] = array('header', 'footer'); + $data['views_test_data']['job']['area']['sub_type'] = ['header', 'footer']; return $data; } @@ -48,67 +48,67 @@ public function testFetchFields() { $data_helper = new ViewsDataHelper($views_data); - $expected = array( - 'field' => array( + $expected = [ + 'field' => [ 'age', 'created', 'job', 'name', 'status', - ), - 'argument' => array( + ], + 'argument' => [ 'age', 'created', 'id', 'job', - ), - 'filter' => array( + ], + 'filter' => [ 'created', 'id', 'job', 'name', 'status', - ), - 'sort' => array( + ], + 'sort' => [ 'age', 'created', 'id', 'name', 'status', - ), - 'area' => array( + ], + 'area' => [ 'age', 'created', 'job', - ), - 'header' => array( + ], + 'header' => [ 'age', 'created', 'job', - ), - 'footer' => array( + ], + 'footer' => [ 'age', 'created', 'job', - ), - ); + ], + ]; - $handler_types = array('field', 'argument', 'filter', 'sort', 'area'); + $handler_types = ['field', 'argument', 'filter', 'sort', 'area']; foreach ($handler_types as $handler_type) { $fields = $data_helper->fetchFields('views_test_data', $handler_type); $expected_keys = $expected[$handler_type]; - array_walk($expected_keys, function(&$item) { + array_walk($expected_keys, function (&$item) { $item = "views_test_data.$item"; }); $this->assertEquals($expected_keys, array_keys($fields), "Handlers of type $handler_type are not listed as expected"); } // Check for subtype filtering, so header and footer. - foreach (array('header', 'footer') as $sub_type) { + foreach (['header', 'footer'] as $sub_type) { $fields = $data_helper->fetchFields('views_test_data', 'area', FALSE, $sub_type); $expected_keys = $expected[$sub_type]; - array_walk($expected_keys, function(&$item) { + array_walk($expected_keys, function (&$item) { $item = "views_test_data.$item"; }); $this->assertEquals($expected_keys, array_keys($fields), "Sub_type $sub_type is not filtered as expected."); diff --git a/core/modules/views/tests/src/Unit/ViewsDataTest.php b/core/modules/views/tests/src/Unit/ViewsDataTest.php index 23518921..a145538a 100644 --- a/core/modules/views/tests/src/Unit/ViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/ViewsDataTest.php @@ -63,14 +63,14 @@ protected function setUp() { $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); $this->getContainerWithCacheTagsInvalidator($this->cacheTagsInvalidator); - $configs = array(); + $configs = []; $configs['views.settings']['skip_cache'] = FALSE; $this->configFactory = $this->getConfigFactoryStub($configs); $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface'); $this->languageManager->expects($this->any()) ->method('getCurrentLanguage') - ->will($this->returnValue(new Language(array('id' => 'en')))); + ->will($this->returnValue(new Language(['id' => 'en']))); $this->viewsData = new ViewsData($this->cacheBackend, $this->configFactory, $this->moduleHandler, $this->languageManager); } @@ -90,7 +90,7 @@ protected function viewsData() { $data['views_test_data']['age']['area']['id'] = 'text'; $data['views_test_data']['age']['area']['sub_type'] = 'header'; $data['views_test_data']['job']['area']['id'] = 'text'; - $data['views_test_data']['job']['area']['sub_type'] = array('header', 'footer'); + $data['views_test_data']['job']['area']['sub_type'] = ['header', 'footer']; // Duplicate the example views test data for different weight, different title, // and matching data. @@ -136,7 +136,7 @@ protected function setupMockedModuleHandler() { $this->moduleHandler->expects($this->at(0)) ->method('getImplementations') ->with('views_data') - ->willReturn(array('views_test_data')); + ->willReturn(['views_test_data']); $this->moduleHandler->expects($this->at(1)) ->method('invoke') ->with('views_test_data', 'views_data') @@ -167,11 +167,11 @@ public function testFetchBaseTables() { } // Test the values returned for each base table. - $defaults = array( + $defaults = [ 'title' => '', 'help' => '', 'weight' => 0, - ); + ]; foreach ($base_tables as $base_table => $info) { // Merge in default values as in fetchBaseTables(). $expected = $data[$base_table]['table']['base'] += $defaults; @@ -215,7 +215,7 @@ public function testFullAndTableGetCache() { $this->moduleHandler->expects($this->at(0)) ->method('getImplementations') ->with('views_data') - ->willReturn(array('views_test_data')); + ->willReturn(['views_test_data']); $this->moduleHandler->expects($this->at(1)) ->method('invoke') ->with('views_test_data', 'views_data') @@ -227,7 +227,7 @@ public function testFullAndTableGetCache() { $this->moduleHandler->expects($this->at(3)) ->method('getImplementations') ->with('views_data') - ->willReturn(array('views_test_data')); + ->willReturn(['views_test_data']); $this->moduleHandler->expects($this->at(4)) ->method('invoke') ->with('views_test_data', 'views_data') @@ -252,7 +252,7 @@ public function testFullAndTableGetCache() { ->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(3)) ->method('set') - ->with("views_data:$random_table_name:en", array()); + ->with("views_data:$random_table_name:en", []); $this->cacheTagsInvalidator->expects($this->once()) ->method('invalidateTags') ->with(['views_data']); @@ -269,7 +269,7 @@ public function testFullAndTableGetCache() { ->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(7)) ->method('set') - ->with("views_data:$random_table_name:en", array()); + ->with("views_data:$random_table_name:en", []); $views_data = $this->viewsData->getAll(); $this->assertSame($expected_views_data, $views_data); @@ -283,7 +283,7 @@ public function testFullAndTableGetCache() { $this->assertSame($expected_views_data[$table_name_2], $views_data); $views_data = $this->viewsData->get($random_table_name); - $this->assertSame(array(), $views_data); + $this->assertSame([], $views_data); $this->viewsData->clear(); @@ -379,11 +379,11 @@ public function testNonExistingTableGetCache() { // All views data should be requested on the first try. $views_data = $this->viewsData->get($random_table_name); - $this->assertSame(array(), $views_data, 'Make sure fetching views data for an invalid table returns an empty array.'); + $this->assertSame([], $views_data, 'Make sure fetching views data for an invalid table returns an empty array.'); // Test no data is rebuilt when requesting an invalid table again. $views_data = $this->viewsData->get($random_table_name); - $this->assertSame(array(), $views_data, 'Make sure fetching views data for an invalid table returns an empty array.'); + $this->assertSame([], $views_data, 'Make sure fetching views data for an invalid table returns an empty array.'); } /** @@ -433,7 +433,7 @@ public function testCacheCallsWithSameTableMultipleTimesAndWarmCache() { $this->cacheBackend->expects($this->once()) ->method('get') ->with('views_data:views_test_data:en') - ->will($this->returnValue((object) array('data' => $expected_views_data['views_test_data']))); + ->will($this->returnValue((object) ['data' => $expected_views_data['views_test_data']])); $this->cacheBackend->expects($this->never()) ->method('set'); @@ -466,7 +466,7 @@ public function testCacheCallsWithWarmCacheAndDifferentTable() { $this->cacheBackend->expects($this->at(1)) ->method('get') ->with('views_data:en') - ->will($this->returnValue((object) array('data' => $expected_views_data))); + ->will($this->returnValue((object) ['data' => $expected_views_data])); $this->cacheBackend->expects($this->at(2)) ->method('set') ->with('views_data:views_test_data_2:en', $expected_views_data['views_test_data_2']); @@ -502,10 +502,10 @@ public function testCacheCallsWithWarmCacheAndInvalidTable() { $this->cacheBackend->expects($this->at(1)) ->method('get') ->with('views_data:en') - ->will($this->returnValue((object) array('data' => $expected_views_data))); + ->will($this->returnValue((object) ['data' => $expected_views_data])); $this->cacheBackend->expects($this->at(2)) ->method('set') - ->with("views_data:$non_existing_table:en", array()); + ->with("views_data:$non_existing_table:en", []); // Initialize the views data cache and request a non-existing table. This // will result in the same cache requests as we explicitly write an empty @@ -514,7 +514,7 @@ public function testCacheCallsWithWarmCacheAndInvalidTable() { // check if the table does exist or not. for ($i = 0; $i < 5; $i++) { $views_data = $this->viewsData->get($non_existing_table); - $this->assertSame(array(), $views_data); + $this->assertSame([], $views_data); } } @@ -535,7 +535,7 @@ public function testCacheCallsWithWarmCacheForInvalidTable() { $this->cacheBackend->expects($this->once()) ->method('get') ->with("views_data:$non_existing_table:en") - ->will($this->returnValue((object) array('data' => array()))); + ->will($this->returnValue((object) ['data' => []])); $this->cacheBackend->expects($this->never()) ->method('set'); @@ -546,7 +546,7 @@ public function testCacheCallsWithWarmCacheForInvalidTable() { // check if the table does exist or not. for ($i = 0; $i < 5; $i++) { $views_data = $this->viewsData->get($non_existing_table); - $this->assertSame(array(), $views_data); + $this->assertSame([], $views_data); } } @@ -588,7 +588,7 @@ public function testCacheCallsWithWarmCacheAndGetAllTables() { $this->cacheBackend->expects($this->once()) ->method('get') ->with("views_data:en") - ->will($this->returnValue((object) array('data' => $expected_views_data))); + ->will($this->returnValue((object) ['data' => $expected_views_data])); $this->cacheBackend->expects($this->never()) ->method('set'); @@ -618,7 +618,7 @@ public function testCacheCallsWithoutWarmCacheAndGetMultipleTables() { $this->cacheBackend->expects($this->at(1)) ->method('get') ->with('views_data:en') - ->will($this->returnValue((object) array('data' => $expected_views_data))); + ->will($this->returnValue((object) ['data' => $expected_views_data])); $this->cacheBackend->expects($this->at(2)) ->method('set') ->with("views_data:$table_name:en", $expected_views_data[$table_name]); diff --git a/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php b/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php index efbbe49e..c181b943 100644 --- a/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php +++ b/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php @@ -48,7 +48,7 @@ protected function setUp() { ->getMock(); $cache_backend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); - $this->handlerManager = new ViewsHandlerManager('test', new \ArrayObject(array()), $this->viewsData, $cache_backend, $this->moduleHandler); + $this->handlerManager = new ViewsHandlerManager('test', new \ArrayObject([]), $this->viewsData, $cache_backend, $this->moduleHandler); } /** @@ -72,7 +72,7 @@ protected function setupMockedFactory() { public function testAlterHookInvocation() { $this->moduleHandler->expects($this->once()) ->method('alter') - ->with('views_plugins_test', array()); + ->with('views_plugins_test', []); $this->handlerManager->getDefinitions(); } diff --git a/core/modules/views/tests/src/Unit/ViewsTest.php b/core/modules/views/tests/src/Unit/ViewsTest.php index 4924154c..00476c50 100644 --- a/core/modules/views/tests/src/Unit/ViewsTest.php +++ b/core/modules/views/tests/src/Unit/ViewsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\views\Unit; -use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Tests\UnitTestCase; use Drupal\views\Views; use Drupal\views\Entity\View; @@ -154,12 +154,12 @@ public function testGetApplicableViews($applicable_type, $expected) { ->with(['test_view_1', 'test_view_2', 'test_view_3']) ->will($this->returnValue(['test_view_1' => $view_1, 'test_view_2' => $view_2, 'test_view_3' => $view_3])); - $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); - $entity_manager->expects($this->exactly(2)) + $entity_type_manager = $this->getMock(EntityTypeManagerInterface::class); + $entity_type_manager->expects($this->exactly(2)) ->method('getStorage') ->with('view') ->will($this->returnValue($view_storage)); - $this->container->set('entity.manager', $entity_manager); + $this->container->set('entity_type.manager', $entity_type_manager); $definitions = [ 'type_a' => [ @@ -178,9 +178,6 @@ public function testGetApplicableViews($applicable_type, $expected) { ->willReturn($definitions); $this->container->set('plugin.manager.views.display', $display_manager); - $entity_query = new QueryFactory($entity_manager); - $this->container->set('entity.query', $entity_query); - $result = Views::getApplicableViews($applicable_type); $this->assertEquals($expected, $result); } diff --git a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml b/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml index 3f3c7d26..24d3a352 100644 --- a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml +++ b/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml @@ -4,8 +4,8 @@ description: Theme for testing Views rendering of checkboxes. # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme b/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme index cab52ac7..393c6cbd 100644 --- a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme +++ b/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme @@ -11,5 +11,10 @@ use Drupal\Core\Form\FormStateInterface; * Changes an exposed "type" filter from a multi-select to checkboxes. */ function views_test_checkboxes_theme_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) { - $form['type']['#type'] = 'checkboxes'; + if (isset($form['type'])) { + $form['type']['#type'] = 'checkboxes'; + } + if (isset($form['tid'])) { + $form['tid']['#type'] = 'checkboxes'; + } } diff --git a/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml b/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml index f4182b09..ebf06c32 100644 --- a/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml +++ b/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml @@ -4,8 +4,8 @@ description: Theme for testing Views functionality. # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/views.api.php b/core/modules/views/views.api.php index ed9f2dbf..e6af1982 100644 --- a/core/modules/views/views.api.php +++ b/core/modules/views/views.api.php @@ -93,7 +93,7 @@ * to the user following analysis of the view. */ function hook_views_analyze(Drupal\views\ViewExecutable $view) { - $messages = array(); + $messages = []; if ($view->display_handler->options['pager']['type'] == 'none') { $messages[] = Drupal\views\Analyzer::formatMessage(t('This view has no pager. This could cause performance issues when the view contains many items.'), 'warning'); @@ -144,15 +144,15 @@ function hook_views_data() { // ); // Define the return array. - $data = array(); + $data = []; // The outermost keys of $data are Views table names, which should usually // be the same as the hook_schema() table names. - $data['example_table'] = array(); + $data['example_table'] = []; // The value corresponding to key 'table' gives properties of the table // itself. - $data['example_table']['table'] = array(); + $data['example_table']['table'] = []; // Within 'table', the value of 'group' (translated string) is used as a // prefix in Views UI for this table's fields, filters, etc. When adding @@ -169,7 +169,7 @@ function hook_views_data() { // for views. Non-base tables can only be brought in via relationships in // views based on other tables. To define a table to be a base table, add // key 'base' to the 'table' array: - $data['example_table']['table']['base'] = array( + $data['example_table']['table']['base'] = [ // Identifier (primary) field in this table for Views. 'field' => 'nid', // Label in the UI. @@ -177,7 +177,7 @@ function hook_views_data() { // Longer description in the UI. Required. 'help' => t('Example table contains example content and can be related to nodes.'), 'weight' => -10, - ); + ]; // Some tables have an implicit, automatic relationship to other tables, // meaning that when the other table is available in a view (either as the @@ -196,7 +196,7 @@ function hook_views_data() { // ... FROM example_table et ... JOIN node_field_data nfd // ON et.nid = nfd.nid AND ('extra' clauses will be here) ... // although the table aliases will be different. - $data['example_table']['table']['join'] = array( + $data['example_table']['table']['join'] = [ // Within the 'join' section, list one or more tables to automatically // join to. In this example, every time 'node_field_data' is available in // a view, 'example_table' will be too. The array keys here are the array @@ -204,36 +204,36 @@ function hook_views_data() { // implementations. If the table listed here is from another module's // hook_views_data() implementation, make sure your module depends on that // other module. - 'node_field_data' => array( + 'node_field_data' => [ // Primary key field in node_field_data to use in the join. 'left_field' => 'nid', // Foreign key field in example_table to use in the join. 'field' => 'nid', // 'extra' is an array of additional conditions on the join. - 'extra' => array( - 0 => array( + 'extra' => [ + 0 => [ // Adds AND node_field_data.published = TRUE to the join. 'field' => 'published', 'value' => TRUE, - ), - 1 => array( + ], + 1 => [ // Adds AND example_table.numeric_field = 1 to the join. 'left_field' => 'numeric_field', 'value' => 1, // If true, the value will not be surrounded in quotes. 'numeric' => TRUE, - ), - 2 => array( + ], + 2 => [ // Adds AND example_table.boolean_field <> // node_field_data.published to the join. 'field' => 'published', 'left_field' => 'boolean_field', // The operator used, Defaults to "=". 'operator' => '!=', - ), - ), - ), - ); + ], + ], + ], + ]; // You can also do a more complex join, where in order to get to a certain // base table defined in a hook_views_data() implementation, you will join @@ -248,7 +248,7 @@ function hook_views_data() { // JOIN node_field_data nfd ON (definition of the join from the foo // module goes here) ... // although the table aliases will be different. - $data['example_table']['table']['join']['node_field_data'] = array( + $data['example_table']['table']['join']['node_field_data'] = [ // 'node_field_data' above is the base we're joining to in Views. // 'left_table' is the table we're actually joining to, in order to get to // 'node_field_data'. It has to be something that Views knows how to join @@ -257,16 +257,16 @@ function hook_views_data() { 'left_field' => 'nid', 'field' => 'nid', // 'extra' is an array of additional conditions on the join. - 'extra' => array( + 'extra' => [ // This syntax matches additional fields in the two tables: // ... AND foo.langcode = example_table.langcode ... - array('left_field' => 'langcode', 'field' => 'langcode'), + ['left_field' => 'langcode', 'field' => 'langcode'], // This syntax adds a condition on our table. 'operator' defaults to // '=' for non-array values, or 'IN' for array values. // ... AND example_table.numeric_field > 0 ... - array('field' => 'numeric_field', 'value' => 0, 'numeric' => TRUE, 'operator' => '>'), - ), - ); + ['field' => 'numeric_field', 'value' => 0, 'numeric' => TRUE, 'operator' => '>'], + ], + ]; // Other array elements at the top level of your table's array describe // individual database table fields made available to Views. The array keys @@ -296,7 +296,7 @@ function hook_views_data() { // Node ID field, exposed as relationship only, since it is a foreign key // in this table. - $data['example_table']['nid'] = array( + $data['example_table']['nid'] = [ 'title' => t('Example content'), 'help' => t('Relate example content to the node content'), @@ -306,7 +306,7 @@ function hook_views_data() { // - Use hook_views_data_alter() -- see the function body example on that // hook for details. // - Use the implicit join method described above. - 'relationship' => array( + 'relationship' => [ // Views name of the table to join to for the relationship. 'base' => 'node_field_data', // Database field name in the other table to join on. @@ -315,78 +315,78 @@ function hook_views_data() { 'id' => 'standard', // Default label for relationship in the UI. 'label' => t('Example node'), - ), - ); + ], + ]; // Plain text field, exposed as a field, sort, filter, and argument. - $data['example_table']['plain_text_field'] = array( + $data['example_table']['plain_text_field'] = [ 'title' => t('Plain text field'), 'help' => t('Just a plain text field.'), - 'field' => array( + 'field' => [ // ID of field handler plugin to use. 'id' => 'standard', - ), + ], - 'sort' => array( + 'sort' => [ // ID of sort handler plugin to use. 'id' => 'standard', - ), + ], - 'filter' => array( + 'filter' => [ // ID of filter handler plugin to use. 'id' => 'string', - ), + ], - 'argument' => array( + 'argument' => [ // ID of argument handler plugin to use. 'id' => 'string', - ), - ); + ], + ]; // Numeric field, exposed as a field, sort, filter, and argument. - $data['example_table']['numeric_field'] = array( + $data['example_table']['numeric_field'] = [ 'title' => t('Numeric field'), 'help' => t('Just a numeric field.'), - 'field' => array( + 'field' => [ // ID of field handler plugin to use. 'id' => 'numeric', - ), + ], - 'sort' => array( + 'sort' => [ // ID of sort handler plugin to use. 'id' => 'standard', - ), + ], - 'filter' => array( + 'filter' => [ // ID of filter handler plugin to use. 'id' => 'numeric', - ), + ], - 'argument' => array( + 'argument' => [ // ID of argument handler plugin to use. 'id' => 'numeric', - ), - ); + ], + ]; // Boolean field, exposed as a field, sort, and filter. The filter section // illustrates overriding various settings. - $data['example_table']['boolean_field'] = array( + $data['example_table']['boolean_field'] = [ 'title' => t('Boolean field'), 'help' => t('Just an on/off field.'), - 'field' => array( + 'field' => [ // ID of field handler plugin to use. 'id' => 'boolean', - ), + ], - 'sort' => array( + 'sort' => [ // ID of sort handler plugin to use. 'id' => 'standard', - ), + ], - 'filter' => array( + 'filter' => [ // ID of filter handler plugin to use. 'id' => 'boolean', // Override the generic field title, so that the filter uses a different @@ -398,43 +398,43 @@ function hook_views_data() { // Override the default Boolean filter handler's 'use_equal' setting, to // make the query use 'boolean_field = 1' instead of 'boolean_field <> 0'. 'use_equal' => TRUE, - ), - ); + ], + ]; // Integer timestamp field, exposed as a field, sort, and filter. - $data['example_table']['timestamp_field'] = array( + $data['example_table']['timestamp_field'] = [ 'title' => t('Timestamp field'), 'help' => t('Just a timestamp field.'), - 'field' => array( + 'field' => [ // ID of field handler plugin to use. 'id' => 'date', - ), + ], - 'sort' => array( + 'sort' => [ // ID of sort handler plugin to use. 'id' => 'date', - ), + ], - 'filter' => array( + 'filter' => [ // ID of filter handler plugin to use. 'id' => 'date', - ), - ); + ], + ]; // Area example. Areas are not generally associated with actual data // tables and fields. This example is from views_views_data(), which defines // the "Global" table (not really a table, but a group of Fields, Filters, // etc. that are grouped into section "Global" in the UI). Here's the // definition of the generic "Text area": - $data['views']['area'] = array( + $data['views']['area'] = [ 'title' => t('Text area'), 'help' => t('Provide markup text for the area.'), - 'area' => array( + 'area' => [ // ID of the area handler plugin to use. 'id' => 'text', - ), - ); + ], + ]; return $data; } @@ -453,15 +453,15 @@ function hook_views_data_alter(array &$data) { $data['node_field_data']['nid']['title'] = t('Node-Nid'); // Add an additional field to the users_field_data table. - $data['users_field_data']['example_field'] = array( + $data['users_field_data']['example_field'] = [ 'title' => t('Example field'), 'help' => t('Some example content that references a user'), - 'field' => array( + 'field' => [ // ID of the field handler to use. 'id' => 'example_field', - ), - ); + ], + ]; // Change the handler of the node title field, presumably to a handler plugin // you define in your module. Give the ID of this plugin. @@ -479,11 +479,11 @@ function hook_views_data_alter(array &$data) { // rather than adding this relationship directly to the $data['foo']['fid'] // field entry, which could overwrite an existing relationship, we define // a dummy field key to handle the relationship. - $data['foo']['unique_dummy_name'] = array( + $data['foo']['unique_dummy_name'] = [ 'title' => t('Title seen while adding relationship'), 'help' => t('More information about the relationship'), - 'relationship' => array( + 'relationship' => [ // Views name of the table being joined to from foo. 'base' => 'example_table', // Database field name in example_table for the join. @@ -494,8 +494,8 @@ function hook_views_data_alter(array &$data) { // ID of relationship handler plugin to use. 'id' => 'standard', 'label' => t('Default label for relationship'), - ), - ); + ], + ]; // Note that the $data array is not returned – it is modified by reference. } @@ -525,12 +525,12 @@ function hook_field_views_data(\Drupal\field\FieldStorageConfigInterface $field_ $data = views_field_default_views_data($field_storage); foreach ($data as $table_name => $table_data) { // Add the relationship only on the target_id field. - $data[$table_name][$field_storage->getName() . '_target_id']['relationship'] = array( + $data[$table_name][$field_storage->getName() . '_target_id']['relationship'] = [ 'id' => 'standard', 'base' => 'file_managed', 'base field' => 'target_id', - 'label' => t('image from @field_name', array('@field_name' => $field_storage->getName())), - ); + 'label' => t('image from @field_name', ['@field_name' => $field_storage->getName()]), + ]; } return $data; @@ -544,11 +544,11 @@ function hook_field_views_data(\Drupal\field\FieldStorageConfigInterface $field_ * default data that views_field_default_views_data() supplies for the * field storage. * - * @param array $data - * The views data for the field storage. This has the same format as the - * return value of hook_views_data(). - * @param \Drupal\field\FieldStorageConfigInterface $field_storage - * The field storage config entity. + * @param array $data + * The views data for the field storage. This has the same format as the + * return value of hook_views_data(). + * @param \Drupal\field\FieldStorageConfigInterface $field_storage + * The field storage config entity. * * @see views_views_data() * @see hook_field_views_data() @@ -563,9 +563,9 @@ function hook_field_views_data_alter(array &$data, \Drupal\field\FieldStorageCon list($label) = views_entity_field_label($entity_type_id, $field_name); - $data['file_managed'][$pseudo_field_name]['relationship'] = array( - 'title' => t('@entity using @field', array('@entity' => $entity_type->getLabel(), '@field' => $label)), - 'help' => t('Relate each @entity with a @field set to the image.', array('@entity' => $entity_type->getLabel(), '@field' => $label)), + $data['file_managed'][$pseudo_field_name]['relationship'] = [ + 'title' => t('@entity using @field', ['@entity' => $entity_type->getLabel(), '@field' => $label]), + 'help' => t('Relate each @entity with a @field set to the image.', ['@entity' => $entity_type->getLabel(), '@field' => $label]), 'id' => 'entity_reverse', 'field_name' => $field_name, 'entity_type' => $entity_type_id, @@ -574,14 +574,14 @@ function hook_field_views_data_alter(array &$data, \Drupal\field\FieldStorageCon 'base' => $entity_type->getBaseTable(), 'base field' => $entity_type->getKey('id'), 'label' => $field_name, - 'join_extra' => array( - 0 => array( + 'join_extra' => [ + 0 => [ 'field' => 'deleted', 'value' => 0, 'numeric' => TRUE, - ), - ), - ); + ], + ], + ]; } /** @@ -620,9 +620,9 @@ function hook_field_views_data_views_data_alter(array &$data, \Drupal\field\Fiel $table_mapping = \Drupal::entityManager()->getStorage($entity_type_id)->getTableMapping(); // Views data for this field is in $data[$data_key]. - $data[$data_key][$pseudo_field_name]['relationship'] = array( - 'title' => t('@entity using @field', array('@entity' => $entity_type->getLabel(), '@field' => $label)), - 'help' => t('Relate each @entity with a @field set to the term.', array('@entity' => $entity_type->getLabel(), '@field' => $label)), + $data[$data_key][$pseudo_field_name]['relationship'] = [ + 'title' => t('@entity using @field', ['@entity' => $entity_type->getLabel(), '@field' => $label]), + 'help' => t('Relate each @entity with a @field set to the term.', ['@entity' => $entity_type->getLabel(), '@field' => $label]), 'id' => 'entity_reverse', 'field_name' => $field_name, 'entity_type' => $entity_type_id, @@ -631,14 +631,14 @@ function hook_field_views_data_views_data_alter(array &$data, \Drupal\field\Fiel 'base' => $entity_type->getBaseTable(), 'base field' => $entity_type->getKey('id'), 'label' => $field_name, - 'join_extra' => array( - 0 => array( + 'join_extra' => [ + 0 => [ 'field' => 'deleted', 'value' => 0, 'numeric' => TRUE, - ), - ), - ); + ], + ], + ]; } /** @@ -659,12 +659,12 @@ function hook_field_views_data_views_data_alter(array &$data, \Drupal\field\Fiel */ function hook_views_query_substitutions(ViewExecutable $view) { // Example from views_views_query_substitutions(). - return array( + return [ '***CURRENT_VERSION***' => \Drupal::VERSION, '***CURRENT_TIME***' => REQUEST_TIME, '***LANGUAGE_language_content***' => \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(), PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT => \Drupal::languageManager()->getDefaultLanguage()->getId(), - ); + ]; } /** @@ -676,9 +676,9 @@ function hook_views_query_substitutions(ViewExecutable $view) { * is already marked safe. */ function hook_views_form_substitutions() { - return array( + return [ '' => 'Example Substitution', - ); + ]; } /** @@ -771,7 +771,7 @@ function hook_views_pre_execute(ViewExecutable $view) { $account = \Drupal::currentUser(); if (count($view->query->tables) > 2 && $account->hasPermission('administer views')) { - drupal_set_message(t('The view %view may be heavy to execute.', array('%view' => $view->id())), 'warning'); + drupal_set_message(t('The view %view may be heavy to execute.', ['%view' => $view->id()]), 'warning'); } } @@ -882,11 +882,11 @@ function hook_views_query_alter(ViewExecutable $view, QueryPluginBase $query) { // If this is the part of the query filtering on title, chang the // condition to filter on node ID. if ($condition['field'] == 'node.title') { - $condition = array( + $condition = [ 'field' => 'node.nid', 'value' => $view->exposed_raw_input['title'], 'operator' => '=', - ); + ]; } } } @@ -915,10 +915,10 @@ function hook_views_query_alter(ViewExecutable $view, QueryPluginBase $query) { function hook_views_preview_info_alter(array &$rows, ViewExecutable $view) { // Adds information about the tables being queried by the view to the query // part of the info box. - $rows['query'][] = array( + $rows['query'][] = [ t('Table queue'), count($view->query->table_queue) . ': (' . implode(', ', array_keys($view->query->table_queue)) . ')', - ); + ]; } /** @@ -938,7 +938,7 @@ function hook_views_preview_info_alter(array &$rows, ViewExecutable $view) { function hook_views_ui_display_top_links_alter(array &$links, ViewExecutable $view, $display_id) { // Put the export link first in the list. if (isset($links['export'])) { - $links = array('export' => $links['export']) + $links; + $links = ['export' => $links['export']] + $links; } } @@ -953,7 +953,7 @@ function hook_views_ui_display_top_links_alter(array &$links, ViewExecutable $vi * @see views_invalidate_cache() */ function hook_views_invalidate_cache() { - \Drupal\Core\Cache\Cache::invalidateTags(array('views')); + \Drupal\Core\Cache\Cache::invalidateTags(['views']); } /** @@ -1085,7 +1085,7 @@ function hook_views_plugins_join_alter(array &$plugins) { } /** - * Modify the list of available views join plugins. + * Modify the list of available views pager plugins. * * This hook may be used to modify plugin properties after they have been * specified by other modules. diff --git a/core/modules/views/views.info.yml b/core/modules/views/views.info.yml index 709a0468..3c63eacb 100644 --- a/core/modules/views/views.info.yml +++ b/core/modules/views/views.info.yml @@ -7,8 +7,8 @@ package: Core dependencies: - filter -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views/views.install b/core/modules/views/views.install index 8801a93b..f542416b 100644 --- a/core/modules/views/views.install +++ b/core/modules/views/views.install @@ -12,11 +12,6 @@ function views_install() { module_set_weight('views', 10); } -/** - * @addtogroup updates-8.0.0-beta - * @{ - */ - /** * Update views field plugins. */ @@ -310,15 +305,6 @@ function _views_update_argument_map($displays) { return $argument_map; } -/** - * @} End of "addtogroup updates-8.0.0-beta". - */ - -/** - * @addtogroup updates-8.0.0-rc - * @{ - */ - /** * Clear caches to fix entity operations field. */ @@ -328,15 +314,6 @@ function views_update_8003() { // field. } -/** - * @} End of "addtogroup updates-8.0.0-rc". - */ - -/** - * @addtogroup updates-8.0.x - * @{ - */ - /** * Clear caches due to updated entity views data. */ @@ -344,15 +321,6 @@ function views_update_8004() { // Empty update to cause a cache flush so that views data is rebuilt. } -/** - * @} End of "addtogroup updates-8.0.x". - */ - -/** - * @addtogroup updates-8.1.0 - * @{ - */ - /** * Clear views data cache. */ @@ -389,15 +357,6 @@ function views_update_8101() { } } -/** - * @} End of "addtogroup updates-8.1.0". - */ - -/** - * @addtogroup updates-8.2.0 - * @{ - */ - /** * Rebuild the container to add a new container parameter. */ @@ -411,7 +370,3 @@ function views_update_8200() { function views_update_8201() { // Empty update to cause a cache rebuild so that config schema get refreshed. } - -/** - * @} End of "addtogroup updates-8.2.0". - */ diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 96e6dd3d..8b707644 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -17,7 +17,6 @@ use Drupal\views\ViewExecutable; use Drupal\views\Entity\View; use Drupal\views\Render\ViewsRenderPipelineMarkup; use Drupal\views\Views; -use Drupal\field\FieldConfigInterface; /** * Implements hook_help(). @@ -28,14 +27,14 @@ function views_help($route_name, RouteMatchInterface $route_match) { $output = ''; $output .= '

              ' . t('About') . '

              '; $output .= '

              ' . t('The Views module provides a back end to fetch information from content, user accounts, taxonomy terms, and other entities from the database and present it to the user as a grid, HTML list, table, unformatted list, etc. The resulting displays are known generally as views.') . '

              '; - $output .= '

              ' . t('For more information, see the online documentation for the Views module.', array(':views' => 'https://www.drupal.org/documentation/modules/views')) . '

              '; - $output .= '

              ' . t('In order to create and modify your own views using the administration and configuration user interface, you will need to enable either the Views UI module in core or a contributed module that provides a user interface for Views. See the Views UI module help page for more information.', array(':views-ui' => (\Drupal::moduleHandler()->moduleExists('views_ui')) ? \Drupal::url('help.page', array('name' => 'views_ui')) : '#')) . '

              '; + $output .= '

              ' . t('For more information, see the online documentation for the Views module.', [':views' => 'https://www.drupal.org/documentation/modules/views']) . '

              '; + $output .= '

              ' . t('In order to create and modify your own views using the administration and configuration user interface, you will need to enable either the Views UI module in core or a contributed module that provides a user interface for Views. See the Views UI module help page for more information.', [':views-ui' => (\Drupal::moduleHandler()->moduleExists('views_ui')) ? \Drupal::url('help.page', ['name' => 'views_ui']) : '#']) . '

              '; $output .= '

              ' . t('Uses') . '

              '; $output .= '
              '; $output .= '
              ' . t('Adding functionality to administrative pages') . '
              '; $output .= '
              ' . t('The Views module adds functionality to some core administration pages. For example, admin/content uses Views to filter and sort content. With Views uninstalled, admin/content is more limited.') . '
              '; $output .= '
              ' . t('Expanding Views functionality') . '
              '; - $output .= '
              ' . t('Contributed projects that support the Views module can be found in the online documentation for Views-related contributed modules.', array(':node' => 'https://www.drupal.org/documentation/modules/views/add-ons')) . '
              '; + $output .= '
              ' . t('Contributed projects that support the Views module can be found in the online documentation for Views-related contributed modules.', [':node' => 'https://www.drupal.org/documentation/modules/views/add-ons']) . '
              '; $output .= '
              ' . t('Improving table accessibility') . '
              '; $output .= '
              ' . t('Views tables include semantic markup to improve accessibility. Data cells are automatically associated with header cells through id and header attributes. To improve the accessibility of your tables you can add descriptive elements within the Views table settings. The caption element can introduce context for a table, making it easier to understand. The summary element can provide an overview of how the data has been organized and how to navigate the table. Both the caption and summary are visible by default and also implemented according to HTML5 guidelines.') . '
              '; $output .= '
              ' . t('Working with multilingual views') . '
              '; @@ -53,10 +52,10 @@ function views_help($route_name, RouteMatchInterface $route_match) { function views_views_pre_render($view) { // If using AJAX, send identifying data about this view. if ($view->ajaxEnabled() && empty($view->is_attachment) && empty($view->live_preview)) { - $view->element['#attached']['drupalSettings']['views'] = array( + $view->element['#attached']['drupalSettings']['views'] = [ 'ajax_path' => \Drupal::url('views.ajax'), - 'ajaxViews' => array( - 'views_dom_id:' . $view->dom_id => array( + 'ajaxViews' => [ + 'views_dom_id:' . $view->dom_id => [ 'view_name' => $view->storage->id(), 'view_display_id' => $view->current_display, 'view_args' => Html::escape(implode('/', $view->args)), @@ -66,9 +65,9 @@ function views_views_pre_render($view) { // To fit multiple views on a page, the programmer may have // overridden the display's pager_element. 'pager_element' => isset($view->pager) ? $view->pager->getPagerId() : 0, - ), - ), - ); + ], + ], + ]; $view->element['#attached']['library'][] = 'views/views.ajax'; } @@ -85,50 +84,54 @@ function views_theme($existing, $type, $theme, $path) { \Drupal::moduleHandler()->loadInclude('views', 'inc', 'views.theme'); // Some quasi clever array merging here. - $base = array( + $base = [ 'file' => 'views.theme.inc', - ); + ]; // Our extra version of pager from pager.inc - $hooks['views_mini_pager'] = $base + array( - 'variables' => array('tags' => array(), 'quantity' => 9, 'element' => 0, 'parameters' => array()), - ); + $hooks['views_mini_pager'] = $base + [ + 'variables' => ['tags' => [], 'quantity' => 9, 'element' => 0, 'parameters' => []], + ]; - $variables = array( + $variables = [ // For displays, we pass in a dummy array as the first parameter, since // $view is an object but the core contextual_preprocess() function only // attaches contextual links when the primary theme argument is an array. - 'display' => array( - 'view_array' => array(), + 'display' => [ + 'view_array' => [], 'view' => NULL, - 'rows' => array(), - 'header' => array(), - 'footer' => array(), - 'empty' => array(), - 'exposed' => array(), - 'more' => array(), - 'feed_icons' => array(), - 'pager' => array(), + 'rows' => [], + 'header' => [], + 'footer' => [], + 'empty' => [], + 'exposed' => [], + 'more' => [], + 'feed_icons' => [], + 'pager' => [], 'title' => '', - 'attachment_before' => array(), - 'attachment_after' => array(), - ), - 'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL), - 'row' => array('view' => NULL, 'options' => NULL, 'row' => NULL, 'field_alias' => NULL), - 'exposed_form' => array('view' => NULL, 'options' => NULL), - 'pager' => array( - 'view' => NULL, 'options' => NULL, - 'tags' => array(), 'quantity' => 9, 'element' => 0, 'parameters' => array() - ), - ); + 'attachment_before' => [], + 'attachment_after' => [], + ], + 'style' => ['view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL], + 'row' => ['view' => NULL, 'options' => NULL, 'row' => NULL, 'field_alias' => NULL], + 'exposed_form' => ['view' => NULL, 'options' => NULL], + 'pager' => [ + 'view' => NULL, + 'options' => NULL, + 'tags' => [], + 'quantity' => 9, + 'element' => 0, + 'parameters' => [], + ], + ]; // Default view themes - $hooks['views_view_field'] = $base + array( - 'variables' => array('view' => NULL, 'field' => NULL, 'row' => NULL), - ); - $hooks['views_view_grouping'] = $base + array( - 'variables' => array('view' => NULL, 'grouping' => NULL, 'grouping_level' => NULL, 'rows' => NULL, 'title' => NULL), - ); + $hooks['views_view_field'] = $base + [ + 'variables' => ['view' => NULL, 'field' => NULL, 'row' => NULL], + ]; + $hooks['views_view_grouping'] = $base + [ + 'variables' => ['view' => NULL, 'grouping' => NULL, 'grouping_level' => NULL, 'rows' => NULL, 'title' => NULL], + ]; // Only display, pager, row, and style plugins can provide theme hooks. $plugin_types = [ @@ -138,7 +141,7 @@ function views_theme($existing, $type, $theme, $path) { 'style', 'exposed_form', ]; - $plugins = array(); + $plugins = []; foreach ($plugin_types as $plugin_type) { $plugins[$plugin_type] = Views::pluginManager($plugin_type)->getDefinitions(); } @@ -164,9 +167,9 @@ function views_theme($existing, $type, $theme, $path) { continue; } - $hooks[$def['theme']] = array( + $hooks[$def['theme']] = [ 'variables' => $variables[$type], - ); + ]; // We always use the module directory as base dir. $module_dir = drupal_get_path('module', $def['provider']); @@ -175,7 +178,7 @@ function views_theme($existing, $type, $theme, $path) { // For the views module we ensure views.theme.inc is included. if ($def['provider'] == 'views') { if (!isset($hooks[$def['theme']]['includes'])) { - $hooks[$def['theme']]['includes'] = array(); + $hooks[$def['theme']]['includes'] = []; } if (!in_array('views.theme.inc', $hooks[$def['theme']]['includes'])) { $hooks[$def['theme']]['includes'][] = $module_dir . '/views.theme.inc'; @@ -210,13 +213,13 @@ function views_theme($existing, $type, $theme, $path) { } } - $hooks['views_form_views_form'] = $base + array( + $hooks['views_form_views_form'] = $base + [ 'render element' => 'form', - ); + ]; - $hooks['views_exposed_form'] = $base + array( + $hooks['views_exposed_form'] = $base + [ 'render element' => 'form', - ); + ]; return $hooks; } @@ -378,13 +381,13 @@ function views_add_contextual_links(&$render_element, $location, $display_id, ar // set 'contextual_links_locations' to, e.g., {""}.) if (!isset($plugin['contextual_links_locations'])) { - $plugin['contextual_links_locations'] = array('view'); + $plugin['contextual_links_locations'] = ['view']; } - elseif ($plugin['contextual_links_locations'] == array() || $plugin['contextual_links_locations'] == array('')) { - $plugin['contextual_links_locations'] = array(); + elseif ($plugin['contextual_links_locations'] == [] || $plugin['contextual_links_locations'] == ['']) { + $plugin['contextual_links_locations'] = []; } else { - $plugin += array('contextual_links_locations' => array('view')); + $plugin += ['contextual_links_locations' => ['view']]; } // On exposed_forms blocks contextual links should always be visible. @@ -392,7 +395,7 @@ function views_add_contextual_links(&$render_element, $location, $display_id, ar $has_links = !empty($plugin['contextual links']) && !empty($plugin['contextual_links_locations']); if ($has_links && in_array($location, $plugin['contextual_links_locations'])) { foreach ($plugin['contextual links'] as $group => $link) { - $args = array(); + $args = []; $valid = TRUE; if (!empty($link['route_parameters_names'])) { $view_storage = \Drupal::entityManager() @@ -416,14 +419,14 @@ function views_add_contextual_links(&$render_element, $location, $display_id, ar // array. if ($valid) { $render_element['#views_contextual_links'] = TRUE; - $render_element['#contextual_links'][$group] = array( + $render_element['#contextual_links'][$group] = [ 'route_parameters' => $args, - 'metadata' => array( + 'metadata' => [ 'location' => $location, 'name' => $view_id, 'display_id' => $display_id, - ), - ); + ], + ]; // If we're setting contextual links on a page, for a page view, for a // user that may use contextual links, attach Views' contextual links // JavaScript. @@ -437,21 +440,42 @@ function views_add_contextual_links(&$render_element, $location, $display_id, ar /** * Implements hook_ENTITY_TYPE_insert() for 'field_config'. */ -function views_field_config_insert(FieldConfigInterface $field) { +function views_field_config_insert(EntityInterface $field) { Views::viewsData()->clear(); } /** * Implements hook_ENTITY_TYPE_update() for 'field_config'. */ -function views_field_config_update(FieldConfigInterface $field) { +function views_field_config_update(EntityInterface $entity) { Views::viewsData()->clear(); } /** * Implements hook_ENTITY_TYPE_delete() for 'field_config'. */ -function views_field_config_delete(FieldConfigInterface $field) { +function views_field_config_delete(EntityInterface $entity) { + Views::viewsData()->clear(); +} + +/** + * Implements hook_ENTITY_TYPE_insert(). + */ +function views_base_field_override_insert(EntityInterface $entity) { + Views::viewsData()->clear(); +} + +/** + * Implements hook_ENTITY_TYPE_update(). + */ +function views_base_field_override_update(EntityInterface $entity) { + Views::viewsData()->clear(); +} + +/** + * Implements hook_ENTITY_TYPE_delete(). + */ +function views_base_field_override_delete(EntityInterface $entity) { Views::viewsData()->clear(); } @@ -508,23 +532,23 @@ function &views_get_current_view() { * Implements hook_hook_info(). */ function views_hook_info() { - $hooks = array(); + $hooks = []; - $hooks += array_fill_keys(array( + $hooks += array_fill_keys([ 'views_data', 'views_data_alter', 'views_analyze', 'views_invalidate_cache', - ), array('group' => 'views')); + ], ['group' => 'views']); // Register a views_plugins alter hook for all plugin types. foreach (ViewExecutable::getPluginTypes() as $type) { - $hooks['views_plugins_' . $type . '_alter'] = array( + $hooks['views_plugins_' . $type . '_alter'] = [ 'group' => 'views', - ); + ]; } - $hooks += array_fill_keys(array( + $hooks += array_fill_keys([ 'views_query_substitutions', 'views_form_substitutions', 'views_pre_view', @@ -535,14 +559,14 @@ function views_hook_info() { 'views_pre_render', 'views_post_render', 'views_query_alter', - ), array('group' => 'views_execution')); + ], ['group' => 'views_execution']); - $hooks['field_views_data'] = array( + $hooks['field_views_data'] = [ 'group' => 'views', - ); - $hooks['field_views_data_alter'] = array( + ]; + $hooks['field_views_data_alter'] = [ 'group' => 'views', - ); + ]; return $hooks; } @@ -605,8 +629,8 @@ function views_disable_view(View $view) { */ function views_pre_render_views_form_views_form($element) { // Placeholders and their substitutions (usually rendered form elements). - $search = array(); - $replace = array(); + $search = []; + $replace = []; // Add in substitutions provided by the form. foreach ($element['#substitutions']['#value'] as $substitution) { @@ -614,7 +638,7 @@ function views_pre_render_views_form_views_form($element) { $row_id = $substitution['row_id']; $search[] = $substitution['placeholder']; - $replace[] = isset($element[$field_name][$row_id]) ? drupal_render($element[$field_name][$row_id]) : ''; + $replace[] = isset($element[$field_name][$row_id]) ? \Drupal::service('renderer')->render($element[$field_name][$row_id]) : ''; } // Add in substitutions from hook_views_form_substitutions(). $substitutions = \Drupal::moduleHandler()->invokeAll('views_form_substitutions'); @@ -628,7 +652,7 @@ function views_pre_render_views_form_views_form($element) { } // Apply substitutions to the rendered output. - $output = str_replace($search, $replace, drupal_render($element['output'])); + $output = str_replace($search, $replace, \Drupal::service('renderer')->render($element['output'])); $element['output'] = ['#markup' => ViewsRenderPipelineMarkup::create($output)]; return $element; @@ -660,8 +684,17 @@ function views_query_views_alter(AlterableInterface $query) { // Replaces substitutions in tables. foreach ($tables as $table_name => $table_metadata) { foreach ($table_metadata['arguments'] as $replacement_key => $value) { - if (isset($substitutions[$value])) { - $tables[$table_name]['arguments'][$replacement_key] = $substitutions[$value]; + if (!is_array($value)) { + if (isset($substitutions[$value])) { + $tables[$table_name]['arguments'][$replacement_key] = $substitutions[$value]; + } + } + else { + foreach ($value as $sub_key => $sub_value) { + if (isset($substitutions[$sub_value])) { + $tables[$table_name]['arguments'][$replacement_key][$sub_key] = $substitutions[$sub_value]; + } + } } } } @@ -788,7 +821,7 @@ function views_get_view_result($name, $display_id = NULL) { return $view->result; } else { - return array(); + return []; } } diff --git a/core/modules/views/views.post_update.php b/core/modules/views/views.post_update.php index a4da9401..b77d5ceb 100644 --- a/core/modules/views/views.post_update.php +++ b/core/modules/views/views.post_update.php @@ -9,11 +9,6 @@ use Drupal\views\Entity\View; use Drupal\views\Views; -/** - * @addtogroup updates-8.0.0-beta - * @{ - */ - /** * Update the cacheability metadata for all views. */ @@ -35,15 +30,6 @@ function views_post_update_update_cacheability_metadata() { } -/** - * @} End of "addtogroup updates-8.0.0-beta". - */ - -/** - * @addtogroup updates-8.0.0-rc - * @{ - */ - /** * Update some views fields that were previously duplicated. */ @@ -137,40 +123,22 @@ function views_post_update_cleanup_duplicate_views_data() { return $message; } -/** - * @} End of "addtogroup updates-8.0.0-rc". - */ - -/** - * @addtogroup updates-8.0.x - * @{ - */ - /** * Include field formatter dependencies in a view when the formatter is used. */ function views_post_update_field_formatter_dependencies() { $views = View::loadMultiple(); - array_walk($views, function(View $view) { + array_walk($views, function (View $view) { $view->save(); }); } -/** - * @} End of "addtogroup updates-8.0.x". - */ - -/** - * @addtogroup updates-8.1.x - * @{ - */ - /** * Fix views with dependencies on taxonomy terms that don't exist. */ function views_post_update_taxonomy_index_tid() { $views = View::loadMultiple(); - array_walk($views, function(View $view) { + array_walk($views, function (View $view) { $old_dependencies = $view->getDependencies(); $new_dependencies = $view->calculateDependencies()->getDependencies(); if ($old_dependencies !== $new_dependencies) { @@ -179,21 +147,12 @@ function views_post_update_taxonomy_index_tid() { }); } -/** - * @} End of "addtogroup updates-8.1.x". - */ - -/** - * @addtogroup updates-8.2.x - * @{ - */ - /** * Fix views with serializer dependencies. */ function views_post_update_serializer_dependencies() { $views = View::loadMultiple(); - array_walk($views, function(View $view) { + array_walk($views, function (View $view) { $old_dependencies = $view->getDependencies(); $new_dependencies = $view->calculateDependencies()->getDependencies(); if ($old_dependencies !== $new_dependencies) { @@ -237,5 +196,20 @@ function views_post_update_boolean_filter_values() { } /** - * @} End of "addtogroup updates-8.2.x". + * Rebuild caches to ensure schema changes are read in. */ +function views_post_update_grouped_filters() { + // Empty update to cause a cache rebuild so that the schema changes are read. +} + +/** + * Fix table names for revision metadata fields. + */ +function views_post_update_revision_metadata_fields() { + // The table names are fixed automatically in + // \Drupal\views\Entity\View::preSave(), so we just need to re-save all views. + $views = View::loadMultiple(); + array_walk($views, function (View $view) { + $view->save(); + }); +} diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml index 1a01543c..28f8d0d3 100644 --- a/core/modules/views/views.services.yml +++ b/core/modules/views/views.services.yml @@ -58,7 +58,7 @@ services: arguments: [wizard, '@container.namespaces', '@cache.discovery', '@module_handler'] views.views_data: class: Drupal\views\ViewsData - arguments: ['@cache.discovery', '@config.factory', '@module_handler', '@language_manager'] + arguments: ['@cache.default', '@config.factory', '@module_handler', '@language_manager'] views.views_data_helper: class: Drupal\views\ViewsDataHelper arguments: ['@views.views_data'] diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc index 94c519e7..a26742b9 100644 --- a/core/modules/views/views.theme.inc +++ b/core/modules/views/views.theme.inc @@ -90,7 +90,8 @@ function template_preprocess_views_view_fields(&$variables) { // Loop through the fields for this view. $previous_inline = FALSE; - $variables['fields'] = array(); // ensure it's at least an empty array. + // Ensure it's at least an empty array. + $variables['fields'] = []; /** @var \Drupal\views\ResultRow $row */ $row = $variables['row']; foreach ($view->field as $id => $field) { @@ -107,7 +108,7 @@ function template_preprocess_views_view_fields(&$variables) { $object->element_type = $object->handler->elementType(TRUE, !$variables['options']['default_field_elements'], $object->inline); if ($object->element_type) { - $attributes = array(); + $attributes = []; if ($object->handler->options['element_default_classes']) { $attributes['class'][] = 'field-content'; } @@ -123,7 +124,8 @@ function template_preprocess_views_view_fields(&$variables) { $object->raw = $row->{$view->field[$id]->field_alias}; } else { - $object->raw = NULL; // make sure it exists to reduce NOTICE + // Make sure it exists to reduce NOTICE. + $object->raw = NULL; } if (!empty($variables['options']['separator']) && $previous_inline && $object->inline && $object->content) { @@ -141,7 +143,7 @@ function template_preprocess_views_view_fields(&$variables) { // Set up field wrapper attributes if field wrapper was set. if ($object->wrapper_element) { - $attributes = array(); + $attributes = []; if ($object->handler->options['element_default_classes']) { $attributes['class'][] = 'views-field'; $attributes['class'][] = 'views-field-' . $object->class; @@ -169,7 +171,7 @@ function template_preprocess_views_view_fields(&$variables) { // Set up label attributes. if ($object->label_element) { - $attributes = array(); + $attributes = []; if ($object->handler->options['element_default_classes']) { $attributes['class'][] = 'views-label'; $attributes['class'][] = 'views-label-' . $object->class; @@ -241,13 +243,13 @@ function template_preprocess_views_view_summary(&$variables) { $view = $variables['view']; $argument = $view->argument[$view->build_info['summary_level']]; - $url_options = array(); + $url_options = []; if (!empty($view->exposed_raw_input)) { $url_options['query'] = $view->exposed_raw_input; } - $active_urls = array( + $active_urls = [ // Force system path. \Drupal::url('', [], ['alias' => TRUE]), // Force system path. @@ -256,13 +258,13 @@ function template_preprocess_views_view_summary(&$variables) { \Drupal::url(''), // Could be an alias. Url::fromRouteMatch(\Drupal::routeMatch())->toString(), - ); + ]; $active_urls = array_combine($active_urls, $active_urls); // Collect all arguments foreach row, to be able to alter them for example // by the validator. This is not done per single argument value, because this // could cause performance problems. - $row_args = array(); + $row_args = []; foreach ($variables['rows'] as $id => $row) { $row_args[$id] = $argument->summaryArgument($row); @@ -270,7 +272,7 @@ function template_preprocess_views_view_summary(&$variables) { $argument->processSummaryArguments($row_args); foreach ($variables['rows'] as $id => $row) { - $variables['rows'][$id]->attributes = array(); + $variables['rows'][$id]->attributes = []; $variables['rows'][$id]->link = $argument->summaryName($row); $args = $view->args; $args[$argument->position] = $row_args[$id]; @@ -329,25 +331,25 @@ function template_preprocess_views_view_summary_unformatted(&$variables) { $view = $variables['view']; $argument = $view->argument[$view->build_info['summary_level']]; - $url_options = array(); + $url_options = []; if (!empty($view->exposed_raw_input)) { $url_options['query'] = $view->exposed_raw_input; } $count = 0; - $active_urls = array( + $active_urls = [ // Force system path. \Drupal::url('', [], ['alias' => TRUE]), // Could be an alias. \Drupal::url(''), - ); + ]; $active_urls = array_combine($active_urls, $active_urls); // Collect all arguments for each row, to be able to alter them for example // by the validator. This is not done per single argument value, because // this could cause performance problems. - $row_args = array(); + $row_args = []; foreach ($variables['rows'] as $id => $row) { $row_args[$id] = $argument->summaryArgument($row); } @@ -358,7 +360,7 @@ function template_preprocess_views_view_summary_unformatted(&$variables) { if ($count++) { $variables['rows'][$id]->separator = Xss::filterAdmin($variables['options']['separator']); } - $variables['rows'][$id]->attributes = array(); + $variables['rows'][$id]->attributes = []; $variables['rows'][$id]->link = $argument->summaryName($row); $args = $view->args; $args[$argument->position] = $row_args[$id]; @@ -417,8 +419,8 @@ function template_preprocess_views_view_table(&$variables) { // so that it can get rebuilt. // Store rows so that they may be used by further preprocess functions. $result = $variables['result'] = $variables['rows']; - $variables['rows'] = array(); - $variables['header'] = array(); + $variables['rows'] = []; + $variables['header'] = []; $options = $view->style_plugin->options; $handler = $view->style_plugin; @@ -466,19 +468,19 @@ function template_preprocess_views_view_table(&$variables) { $initial = ($order == 'asc') ? 'desc' : 'asc'; } - $title = t('sort by @s', array('@s' => $label)); + $title = t('sort by @s', ['@s' => $label]); if ($active == $field) { - $variables['header'][$field]['sort_indicator'] = array( + $variables['header'][$field]['sort_indicator'] = [ '#theme' => 'tablesort_indicator', '#style' => $initial, - ); + ]; } $query['order'] = $field; $query['sort'] = $initial; - $link_options = array( + $link_options = [ 'query' => $query, - ); + ]; $url = new Url($route_name, [], $link_options); $variables['header'][$field]['url'] = $url->toString(); $variables['header'][$field]['content'] = $label; @@ -487,7 +489,7 @@ function template_preprocess_views_view_table(&$variables) { $variables['header'][$field]['default_classes'] = $fields[$field]->options['element_default_classes']; // Set up the header label class. - $variables['header'][$field]['attributes'] = array(); + $variables['header'][$field]['attributes'] = []; $class = $fields[$field]->elementLabelClasses(0); if ($class) { $variables['header'][$field]['attributes']['class'][] = $class; @@ -543,7 +545,7 @@ function template_preprocess_views_view_table(&$variables) { // Add field classes. if (!isset($column_reference['attributes'])) { - $column_reference['attributes'] = array(); + $column_reference['attributes'] = []; } if ($classes = $fields[$field]->elementClasses($num)) { @@ -557,7 +559,7 @@ function template_preprocess_views_view_table(&$variables) { // Improves accessibility of complex tables. if (isset($variables['header'][$field]['attributes']['id'])) { - $column_reference['attributes']['headers'] = array($variables['header'][$field]['attributes']['id']); + $column_reference['attributes']['headers'] = [$variables['header'][$field]['attributes']['id']]; } if (!empty($fields[$field])) { @@ -604,11 +606,11 @@ function template_preprocess_views_view_table(&$variables) { // Hide table header if all labels are empty. if (!$has_header_labels) { - $variables['header'] = array(); + $variables['header'] = []; } foreach ($variables['rows'] as $num => $row) { - $variables['rows'][$num]['attributes'] = array(); + $variables['rows'][$num]['attributes'] = []; if ($row_class = $handler->getRowClass($num)) { $variables['rows'][$num]['attributes']['class'][] = $row_class; } @@ -618,12 +620,12 @@ function template_preprocess_views_view_table(&$variables) { if (empty($variables['rows']) && !empty($options['empty_table'])) { $build = $view->display_handler->renderArea('empty'); $variables['rows'][0]['columns'][0]['content'][0]['field_output'] = $build; - $variables['rows'][0]['attributes'] = new Attribute(array('class' => 'odd')); + $variables['rows'][0]['attributes'] = new Attribute(['class' => ['odd']]); // Calculate the amounts of rows with output. - $variables['rows'][0]['columns'][0]['attributes'] = new Attribute(array( + $variables['rows'][0]['columns'][0]['attributes'] = new Attribute([ 'colspan' => count($variables['header']), - 'class' => 'views-empty', - )); + 'class' => ['views-empty'], + ]); } $variables['sticky'] = FALSE; @@ -678,7 +680,7 @@ function template_preprocess_views_view_grid(&$variables) { $col = 0; $row = 0; - $items = array(); + $items = []; $remainders = count($variables['rows']) % $options['columns']; $num_rows = floor(count($variables['rows']) / $options['columns']); @@ -695,7 +697,7 @@ function template_preprocess_views_view_grid(&$variables) { // Create attributes for rows. if (!$horizontal || ($horizontal && empty($items[$row]['attributes']))) { - $row_attributes = array('class' => array()); + $row_attributes = ['class' => []]; // Add custom row classes. $row_class = array_filter(explode(' ', $variables['view']->style_plugin->getCustomClass($result_index, 'row'))); if (!empty($row_class)) { @@ -712,7 +714,7 @@ function template_preprocess_views_view_grid(&$variables) { // Create attributes for columns. if ($horizontal || (!$horizontal && empty($items[$col]['attributes']))) { - $col_attributes = array('class' => array()); + $col_attributes = ['class' => []]; // Add default views column classes. // Add custom column classes. $col_class = array_filter(explode(' ', $variables['view']->style_plugin->getCustomClass($result_index, 'col'))); @@ -781,7 +783,7 @@ function template_preprocess_views_view_unformatted(&$variables) { $variables['default_row_class'] = !empty($options['default_row_class']); foreach ($rows as $id => $row) { - $variables['rows'][$id] = array(); + $variables['rows'][$id] = []; $variables['rows'][$id]['content'] = $row; $variables['rows'][$id]['attributes'] = new Attribute(); if ($row_class = $view->style_plugin->getRowClass($id)) { @@ -808,7 +810,7 @@ function template_preprocess_views_view_list(&$variables) { $class = array_map('\Drupal\Component\Utility\Html::cleanCssIdentifier', $class); // Initialize a new attribute class for $class. - $variables['list']['attributes'] = new Attribute(array('class' => $class)); + $variables['list']['attributes'] = new Attribute(['class' => $class]); } // Fetch wrapper classes from handler options. @@ -858,13 +860,14 @@ function template_preprocess_views_view_rss(&$variables) { // Figure out which display which has a path we're using for this feed. If // there isn't one, use the global $base_url $link_display_id = $view->display_handler->getLinkDisplay(); - if ($link_display_id && $display = $view->displayHandlers->get($link_display_id)) { + /** @var \Drupal\views\Plugin\views\display\DisplayPluginBase $display */ + if ($link_display_id && ($display = $view->displayHandlers->get($link_display_id)) && $display->isEnabled()) { $url = $view->getUrl(NULL, $link_display_id); } /** @var \Drupal\Core\Url $url */ - if ($url) { - $url_options = array('absolute' => TRUE); + if (!empty($url)) { + $url_options = ['absolute' => TRUE]; if (!empty($view->exposed_raw_input)) { $url_options['query'] = $view->exposed_raw_input; } @@ -913,7 +916,7 @@ function template_preprocess_views_view_row_rss(&$variables) { $variables['description'] = (string) \Drupal::service('renderer')->render($item->description); } - $variables['item_elements'] = array(); + $variables['item_elements'] = []; foreach ($item->elements as $element) { if (isset($element['attributes']) && is_array($element['attributes'])) { $element['attributes'] = new Attribute($element['attributes']); @@ -1022,9 +1025,9 @@ function template_preprocess_views_mini_pager(&$variables) { $variables['items']['current'] = $pager_page_array[$element] + 1; if ($pager_total[$element] > 1 && $pager_page_array[$element] > 0) { - $options = array( + $options = [ 'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] - 1), - ); + ]; $variables['items']['previous']['href'] = \Drupal::url('', [], $options); if (isset($tags[1])) { $variables['items']['previous']['text'] = $tags[1]; @@ -1033,9 +1036,9 @@ function template_preprocess_views_mini_pager(&$variables) { } if ($pager_page_array[$element] < ($pager_total[$element] - 1)) { - $options = array( + $options = [ 'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1), - ); + ]; $variables['items']['next']['href'] = \Drupal::url('', [], $options); if (isset($tags[3])) { $variables['items']['next']['text'] = $tags[3]; diff --git a/core/modules/views/views.tokens.inc b/core/modules/views/views.tokens.inc index a0929552..9bf5470a 100644 --- a/core/modules/views/views.tokens.inc +++ b/core/modules/views/views.tokens.inc @@ -11,56 +11,56 @@ use Drupal\Core\Render\BubbleableMetadata; * Implements hook_token_info(). */ function views_token_info() { - $info['types']['view'] = array( + $info['types']['view'] = [ 'name' => t('View', [], ['context' => 'View entity type']), 'description' => t('Tokens related to views.'), 'needs-data' => 'view', - ); - $info['tokens']['view']['label'] = array( + ]; + $info['tokens']['view']['label'] = [ 'name' => t('Label'), 'description' => t('The label of the view.'), - ); - $info['tokens']['view']['description'] = array( + ]; + $info['tokens']['view']['description'] = [ 'name' => t('Description'), 'description' => t('The description of the view.'), - ); - $info['tokens']['view']['id'] = array( + ]; + $info['tokens']['view']['id'] = [ 'name' => t('ID'), 'description' => t('The machine-readable ID of the view.'), - ); - $info['tokens']['view']['title'] = array( + ]; + $info['tokens']['view']['title'] = [ 'name' => t('Title'), 'description' => t('The title of current display of the view.'), - ); - $info['tokens']['view']['url'] = array( + ]; + $info['tokens']['view']['url'] = [ 'name' => t('URL'), 'description' => t('The URL of the view.'), 'type' => 'url', - ); - $info['tokens']['view']['base-table'] = array( + ]; + $info['tokens']['view']['base-table'] = [ 'name' => t('Base table'), 'description' => t('The base table used for this view.'), - ); - $info['tokens']['view']['base-field'] = array( + ]; + $info['tokens']['view']['base-field'] = [ 'name' => t('Base field'), 'description' => t('The base field used for this view.'), - ); - $info['tokens']['view']['total-rows'] = array( + ]; + $info['tokens']['view']['total-rows'] = [ 'name' => t('Total rows'), 'description' => t('The total amount of results returned from the view. The current display will be used.'), - ); - $info['tokens']['view']['items-per-page'] = array( + ]; + $info['tokens']['view']['items-per-page'] = [ 'name' => t('Items per page'), 'description' => t('The number of items per page.'), - ); - $info['tokens']['view']['current-page'] = array( + ]; + $info['tokens']['view']['current-page'] = [ 'name' => t('Current page'), 'description' => t('The current page of results the view is on.'), - ); - $info['tokens']['view']['page-count'] = array( + ]; + $info['tokens']['view']['page-count'] = [ 'name' => t('Page count'), 'description' => t('The total page count.'), - ); + ]; return $info; } @@ -69,11 +69,11 @@ function views_token_info() { * Implements hook_tokens(). */ function views_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { - $url_options = array('absolute' => TRUE); + $url_options = ['absolute' => TRUE]; if (isset($options['language'])) { $url_options['language'] = $options['language']; } - $replacements = array(); + $replacements = []; if ($type == 'view' && !empty($data['view'])) { /** @var \Drupal\views\ViewExecutable $view */ @@ -119,7 +119,7 @@ function views_tokens($type, $tokens, array $data, array $options, BubbleableMet $replacements[$original] = $view->storage->get('base_field'); break; case 'total-rows': - $replacements[$original] = count($view->result); + $replacements[$original] = (int) $view->total_rows; break; case 'items-per-page': $replacements[$original] = (int) $view->getItemsPerPage(); @@ -130,7 +130,7 @@ function views_tokens($type, $tokens, array $data, array $options, BubbleableMet case 'page-count': // If there are no items per page, set this to 1 for the division. $per_page = $view->getItemsPerPage() ?: 1; - $replacements[$original] = max(1, (int) ceil(count($view->result) / $per_page)); + $replacements[$original] = max(1, (int) ceil($view->total_rows / $per_page)); break; } } diff --git a/core/modules/views/views.views.inc b/core/modules/views/views.views.inc index 93a659cd..526f350f 100644 --- a/core/modules/views/views.views.inc +++ b/core/modules/views/views.views.inc @@ -9,6 +9,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Render\Markup; +use Drupal\field\Entity\FieldConfig; use Drupal\field\FieldConfigInterface; use Drupal\field\FieldStorageConfigInterface; use Drupal\system\ActionConfigEntityInterface; @@ -18,129 +19,129 @@ use Drupal\system\ActionConfigEntityInterface; */ function views_views_data() { $data['views']['table']['group'] = t('Global'); - $data['views']['table']['join'] = array( + $data['views']['table']['join'] = [ // #global is a special flag which allows a table to appear all the time. - '#global' => array(), - ); + '#global' => [], + ]; - $data['views']['random'] = array( + $data['views']['random'] = [ 'title' => t('Random'), 'help' => t('Randomize the display order.'), - 'sort' => array( + 'sort' => [ 'id' => 'random', - ), - ); + ], + ]; - $data['views']['null'] = array( + $data['views']['null'] = [ 'title' => t('Null'), 'help' => t('Allow a contextual filter value to be ignored. The query will not be altered by this contextual filter value. Can be used when contextual filter values come from the URL, and a part of the URL needs to be ignored.'), - 'argument' => array( + 'argument' => [ 'id' => 'null', - ), - ); + ], + ]; - $data['views']['nothing'] = array( + $data['views']['nothing'] = [ 'title' => t('Custom text'), 'help' => t('Provide custom text or link.'), - 'field' => array( + 'field' => [ 'id' => 'custom', - ), - ); + ], + ]; - $data['views']['counter'] = array( + $data['views']['counter'] = [ 'title' => t('View result counter'), 'help' => t('Displays the actual position of the view result'), - 'field' => array( + 'field' => [ 'id' => 'counter', - ), - ); + ], + ]; - $data['views']['area'] = array( + $data['views']['area'] = [ 'title' => t('Text area'), 'help' => t('Provide markup text for the area.'), - 'area' => array( + 'area' => [ 'id' => 'text', - ), - ); + ], + ]; - $data['views']['area_text_custom'] = array( + $data['views']['area_text_custom'] = [ 'title' => t('Unfiltered text'), 'help' => t('Add unrestricted, custom text or markup. This is similar to the custom text field.'), - 'area' => array( + 'area' => [ 'id' => 'text_custom', - ), - ); + ], + ]; - $data['views']['title'] = array( + $data['views']['title'] = [ 'title' => t('Title override'), 'help' => t('Override the default view title for this view. This is useful to display an alternative title when a view is empty.'), - 'area' => array( + 'area' => [ 'id' => 'title', 'sub_type' => 'empty', - ), - ); + ], + ]; - $data['views']['view'] = array( + $data['views']['view'] = [ 'title' => t('View area'), 'help' => t('Insert a view inside an area.'), - 'area' => array( + 'area' => [ 'id' => 'view', - ), - ); + ], + ]; - $data['views']['result'] = array( + $data['views']['result'] = [ 'title' => t('Result summary'), 'help' => t('Shows result summary, for example the items per page.'), - 'area' => array( + 'area' => [ 'id' => 'result', - ), - ); + ], + ]; - $data['views']['messages'] = array( + $data['views']['messages'] = [ 'title' => t('Messages'), 'help' => t('Displays messages in an area.'), - 'area' => array( + 'area' => [ 'id' => 'messages', - ), - ); + ], + ]; - $data['views']['http_status_code'] = array( + $data['views']['http_status_code'] = [ 'title' => t('Response status code'), 'help' => t('Alter the HTTP response status code used by this view, mostly helpful for empty results.'), - 'area' => array( + 'area' => [ 'id' => 'http_status_code', - ), - ); + ], + ]; - $data['views']['combine'] = array( + $data['views']['combine'] = [ 'title' => t('Combine fields filter'), 'help' => t('Combine multiple fields together and search by them.'), - 'filter' => array( + 'filter' => [ 'id' => 'combine', - ), - ); + ], + ]; - $data['views']['dropbutton'] = array( + $data['views']['dropbutton'] = [ 'title' => t('Dropbutton'), 'help' => t('Display fields in a dropbutton.'), - 'field' => array( + 'field' => [ 'id' => 'dropbutton', - ), - ); + ], + ]; // Registers an entity area handler per entity type. foreach (\Drupal::entityManager()->getDefinitions() as $entity_type_id => $entity_type) { // Excludes entity types, which cannot be rendered. if ($entity_type->hasViewBuilderClass()) { $label = $entity_type->getLabel(); - $data['views']['entity_' . $entity_type_id] = array( - 'title' => t('Rendered entity - @label', array('@label' => $label)), - 'help' => t('Displays a rendered @label entity in an area.', array('@label' => $label)), - 'area' => array( + $data['views']['entity_' . $entity_type_id] = [ + 'title' => t('Rendered entity - @label', ['@label' => $label]), + 'help' => t('Displays a rendered @label entity in an area.', ['@label' => $label]), + 'area' => [ 'entity_type' => $entity_type_id, 'id' => 'entity', - ), - ); + ], + ]; } } @@ -152,13 +153,13 @@ function views_views_data() { if (empty($actions)) { continue; } - $data[$entity_info->getBaseTable()][$entity_type . '_bulk_form'] = array( + $data[$entity_info->getBaseTable()][$entity_type . '_bulk_form'] = [ 'title' => t('Bulk update'), 'help' => t('Allows users to apply an action to one or more items.'), - 'field' => array( + 'field' => [ 'id' => 'bulk_form', - ), - ); + ], + ]; } // Registers views data for the entity itself. @@ -180,7 +181,7 @@ function views_views_data() { /** @var \Drupal\field\FieldStorageConfigInterface $field_storage */ foreach ($entity_manager->getStorage('field_storage_config')->loadMultiple() as $field_storage) { if (_views_field_get_entity_type_storage($field_storage)) { - $result = (array) $module_handler->invoke($field_storage->getTypeProvider(), 'field_views_data', array($field_storage)); + $result = (array) $module_handler->invoke($field_storage->getTypeProvider(), 'field_views_data', [$field_storage]); if (empty($result)) { $result = views_field_default_views_data($field_storage); } @@ -245,8 +246,8 @@ function _views_field_get_entity_type_storage(FieldStorageConfigInterface $field * Therefore it looks up in all bundles to find the most used field. */ function views_entity_field_label($entity_type, $field_name) { - $label_counter = array(); - $all_labels = array(); + $label_counter = []; + $all_labels = []; // Count the amount of fields per label per field storage. foreach (array_keys(\Drupal::entityManager()->getBundleInfo($entity_type)) as $bundle) { $bundle_fields = array_filter(\Drupal::entityManager()->getFieldDefinitions($entity_type, $bundle), function ($field_definition) { @@ -260,19 +261,19 @@ function views_entity_field_label($entity_type, $field_name) { } } if (empty($label_counter)) { - return array($field_name, $all_labels); + return [$field_name, $all_labels]; } // Sort the field labels by it most used label and return the most used one. // If the counts are equal, sort by the label to ensure the result is // deterministic. - uksort($label_counter, function($a, $b) use ($label_counter) { + uksort($label_counter, function ($a, $b) use ($label_counter) { if ($label_counter[$a] === $label_counter[$b]) { return strcmp($a, $b); } return $label_counter[$a] > $label_counter[$b] ? -1 : 1; }); $label_counter = array_keys($label_counter); - return array($label_counter[0], $all_labels); + return [$label_counter[0], $all_labels]; } /** @@ -285,7 +286,7 @@ function views_entity_field_label($entity_type, $field_name) { * The default views data for the field. */ function views_field_default_views_data(FieldStorageConfigInterface $field_storage) { - $data = array(); + $data = []; // Check the field type is available. if (!\Drupal::service('plugin.manager.field.field_type')->hasDefinition($field_storage->getType())) { @@ -319,7 +320,7 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora // We cannot do anything if for some reason there is no base table. return $data; } - $entity_tables = array($base_table => $entity_type_id); + $entity_tables = [$base_table => $entity_type_id]; // Some entities may not have a data table. $data_table = $entity_type->getDataTable(); if ($data_table) { @@ -339,69 +340,145 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora // @todo Generalize this code to make it work with any table layout. See // https://www.drupal.org/node/2079019. $table_mapping = $storage->getTableMapping(); - $field_tables = array( - EntityStorageInterface::FIELD_LOAD_CURRENT => array( + $field_tables = [ + EntityStorageInterface::FIELD_LOAD_CURRENT => [ 'table' => $table_mapping->getDedicatedDataTableName($field_storage), 'alias' => "{$entity_type_id}__{$field_name}", - ), - ); + ], + ]; if ($supports_revisions) { - $field_tables[EntityStorageInterface::FIELD_LOAD_REVISION] = array( + $field_tables[EntityStorageInterface::FIELD_LOAD_REVISION] = [ 'table' => $table_mapping->getDedicatedRevisionTableName($field_storage), 'alias' => "{$entity_type_id}_revision__{$field_name}", - ); + ]; + } + + // Determine if the fields are translatable. + $bundles_names = $field_storage->getBundles(); + $translation_join_type = FALSE; + $fields = []; + $translatable_configs = []; + $untranslatable_configs = []; + $untranslatable_config_bundles = []; + + foreach ($bundles_names as $bundle) { + $fields[$bundle] = FieldConfig::loadByName($entity_type->id(), $bundle, $field_name); + } + foreach ($fields as $bundle => $config_entity) { + if (!empty($config_entity)) { + if ($config_entity->isTranslatable()) { + $translatable_configs[$bundle] = $config_entity; + } + else { + $untranslatable_configs[$bundle] = $config_entity; + } + } + else { + // https://www.drupal.org/node/2451657#comment-11462881 + \Drupal::logger('views')->error( + t('A non-existent config entity name returned by FieldStorageConfigInterface::getBundles(): field name: %field, bundle: %bundle', + ['%field' => $field_name, '%bundle' => $bundle] + )); + } + } + + // If the field is translatable on all the bundles, there will be a join on + // the langcode. + if (!empty($translatable_configs) && empty($untranslatable_configs)) { + $translation_join_type = 'language'; + } + // If the field is translatable only on certain bundles, there will be a join + // on langcode OR bundle name. + elseif (!empty($translatable_configs) && !empty($untranslatable_configs)) { + foreach ($untranslatable_configs as $config) { + $untranslatable_config_bundles[] = $config->getTargetBundle(); + } + $translation_join_type = 'language_bundle'; } // Build the relationships between the field table and the entity tables. $table_alias = $field_tables[EntityStorageInterface::FIELD_LOAD_CURRENT]['alias']; if ($data_table) { // Tell Views how to join to the base table, via the data table. - $data[$table_alias]['table']['join'][$data_table] = array( + $data[$table_alias]['table']['join'][$data_table] = [ 'table' => $table_mapping->getDedicatedDataTableName($field_storage), 'left_field' => $entity_type->getKey('id'), 'field' => 'entity_id', - 'extra' => array( - array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), - array('left_field' => 'langcode', 'field' => 'langcode'), - ), - ); + 'extra' => [ + ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], + ], + ]; } else { // If there is no data table, just join directly. - $data[$table_alias]['table']['join'][$base_table] = array( + $data[$table_alias]['table']['join'][$base_table] = [ 'table' => $table_mapping->getDedicatedDataTableName($field_storage), 'left_field' => $entity_type->getKey('id'), 'field' => 'entity_id', - 'extra' => array( - array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), - ), - ); + 'extra' => [ + ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], + ], + ]; + } + + if ($translation_join_type === 'language_bundle') { + $data[$table_alias]['table']['join'][$data_table]['join_id'] = 'field_or_language_join'; + $data[$table_alias]['table']['join'][$data_table]['extra'][] = [ + 'left_field' => 'langcode', + 'field' => 'langcode', + ]; + $data[$table_alias]['table']['join'][$data_table]['extra'][] = [ + 'field' => 'bundle', + 'value' => $untranslatable_config_bundles, + ]; + } + elseif ($translation_join_type === 'language') { + $data[$table_alias]['table']['join'][$data_table]['extra'][] = [ + 'left_field' => 'langcode', + 'field' => 'langcode', + ]; } if ($supports_revisions) { $table_alias = $field_tables[EntityStorageInterface::FIELD_LOAD_REVISION]['alias']; if ($entity_revision_data_table) { // Tell Views how to join to the revision table, via the data table. - $data[$table_alias]['table']['join'][$entity_revision_data_table] = array( + $data[$table_alias]['table']['join'][$entity_revision_data_table] = [ 'table' => $table_mapping->getDedicatedRevisionTableName($field_storage), 'left_field' => $entity_type->getKey('revision'), 'field' => 'revision_id', - 'extra' => array( - array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), - array('left_field' => 'langcode', 'field' => 'langcode'), - ), - ); + 'extra' => [ + ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], + ], + ]; } else { // If there is no data table, just join directly. - $data[$table_alias]['table']['join'][$entity_revision_table] = array( + $data[$table_alias]['table']['join'][$entity_revision_table] = [ 'table' => $table_mapping->getDedicatedRevisionTableName($field_storage), 'left_field' => $entity_type->getKey('revision'), 'field' => 'revision_id', - 'extra' => array( - array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), - ), - ); + 'extra' => [ + ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], + ], + ]; + } + if ($translation_join_type === 'language_bundle') { + $data[$table_alias]['table']['join'][$entity_revision_data_table]['join_id'] = 'field_or_language_join'; + $data[$table_alias]['table']['join'][$entity_revision_data_table]['extra'][] = [ + 'left_field' => 'langcode', + 'field' => 'langcode', + ]; + $data[$table_alias]['table']['join'][$entity_revision_data_table]['extra'][] = [ + 'value' => $untranslatable_config_bundles, + 'field' => 'bundle', + ]; + } + elseif ($translation_join_type === 'language') { + $data[$table_alias]['table']['join'][$entity_revision_data_table]['extra'][] = [ + 'left_field' => 'langcode', + 'field' => 'langcode', + ]; } } @@ -409,7 +486,7 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora // Get the list of bundles the field appears in. $bundles_names = $field_storage->getBundles(); // Build the list of additional fields to add to queries. - $add_fields = array('delta', 'langcode', 'bundle'); + $add_fields = ['delta', 'langcode', 'bundle']; foreach (array_keys($field_columns) as $column) { $add_fields[] = $table_mapping->getFieldColumnName($field_storage, $column); } @@ -428,41 +505,41 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora $field_alias = $field_name; } else { - $group = t('@group (historical data)', array('@group' => $group_name)); + $group = t('@group (historical data)', ['@group' => $group_name]); $field_alias = $field_name . '-revision_id'; } - $data[$table_alias][$field_alias] = array( + $data[$table_alias][$field_alias] = [ 'group' => $group, 'title' => $label, 'title short' => $label, - 'help' => t('Appears in: @bundles.', array('@bundles' => implode(', ', $bundles_names))), - ); + 'help' => t('Appears in: @bundles.', ['@bundles' => implode(', ', $bundles_names)]), + ]; // Go through and create a list of aliases for all possible combinations of // entity type + name. - $aliases = array(); - $also_known = array(); + $aliases = []; + $also_known = []; foreach ($all_labels as $label_name => $true) { if ($type == EntityStorageInterface::FIELD_LOAD_CURRENT) { if ($label != $label_name) { - $aliases[] = array( + $aliases[] = [ 'base' => $base_table, 'group' => $group_name, 'title' => $label_name, - 'help' => t('This is an alias of @group: @field.', array('@group' => $group_name, '@field' => $label)), - ); - $also_known[] = t('@group: @field', array('@group' => $group_name, '@field' => $label_name)); + 'help' => t('This is an alias of @group: @field.', ['@group' => $group_name, '@field' => $label]), + ]; + $also_known[] = t('@group: @field', ['@group' => $group_name, '@field' => $label_name]); } } elseif ($supports_revisions && $label != $label_name) { - $aliases[] = array( + $aliases[] = [ 'base' => $table, - 'group' => t('@group (historical data)', array('@group' => $group_name)), + 'group' => t('@group (historical data)', ['@group' => $group_name]), 'title' => $label_name, - 'help' => t('This is an alias of @group: @field.', array('@group' => $group_name, '@field' => $label)), - ); - $also_known[] = t('@group (historical data): @field', array('@group' => $group_name, '@field' => $label_name)); + 'help' => t('This is an alias of @group: @field.', ['@group' => $group_name, '@field' => $label]), + ]; + $also_known[] = t('@group (historical data): @field', ['@group' => $group_name, '@field' => $label_name]); } } if ($aliases) { @@ -481,7 +558,7 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora $keys = array_keys($field_columns); $real_field = reset($keys); - $data[$table_alias][$field_alias]['field'] = array( + $data[$table_alias][$field_alias]['field'] = [ 'table' => $table, 'id' => 'field', 'field_name' => $field_name, @@ -492,7 +569,7 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora // Default the element type to div, let the UI change it if necessary. 'element type' => 'div', 'is revision' => $type == EntityStorageInterface::FIELD_LOAD_REVISION, - ); + ]; } // Expose data for each field property individually. @@ -527,12 +604,12 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora } if (count($field_columns) == 1 || $column == 'value') { - $title = t('@label (@name)', array('@label' => $label, '@name' => $field_name)); + $title = t('@label (@name)', ['@label' => $label, '@name' => $field_name]); $title_short = $label; } else { - $title = t('@label (@name:@column)', array('@label' => $label, '@name' => $field_name, '@column' => $column)); - $title_short = t('@label:@column', array('@label' => $label, '@column' => $column)); + $title = t('@label (@name:@column)', ['@label' => $label, '@name' => $field_name, '@column' => $column]); + $title_short = t('@label:@column', ['@label' => $label, '@column' => $column]); } // Expose data for the property. @@ -544,38 +621,38 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora $group = $group_name; } else { - $group = t('@group (historical data)', array('@group' => $group_name)); + $group = t('@group (historical data)', ['@group' => $group_name]); } $column_real_name = $table_mapping->getFieldColumnName($field_storage, $column); // Load all the fields from the table by default. $additional_fields = $table_mapping->getAllColumns($table); - $data[$table_alias][$column_real_name] = array( + $data[$table_alias][$column_real_name] = [ 'group' => $group, 'title' => $title, 'title short' => $title_short, - 'help' => t('Appears in: @bundles.', array('@bundles' => implode(', ', $bundles_names))), - ); + 'help' => t('Appears in: @bundles.', ['@bundles' => implode(', ', $bundles_names)]), + ]; // Go through and create a list of aliases for all possible combinations of // entity type + name. - $aliases = array(); - $also_known = array(); + $aliases = []; + $also_known = []; foreach ($all_labels as $label_name => $true) { if ($label != $label_name) { if (count($field_columns) == 1 || $column == 'value') { - $alias_title = t('@label (@name)', array('@label' => $label_name, '@name' => $field_name)); + $alias_title = t('@label (@name)', ['@label' => $label_name, '@name' => $field_name]); } else { - $alias_title = t('@label (@name:@column)', array('@label' => $label_name, '@name' => $field_name, '@column' => $column)); + $alias_title = t('@label (@name:@column)', ['@label' => $label_name, '@name' => $field_name, '@column' => $column]); } - $aliases[] = array( + $aliases[] = [ 'group' => $group_name, 'title' => $alias_title, - 'help' => t('This is an alias of @group: @field.', array('@group' => $group_name, '@field' => $title)), - ); - $also_known[] = t('@group: @field', array('@group' => $group_name, '@field' => $title)); + 'help' => t('This is an alias of @group: @field.', ['@group' => $group_name, '@field' => $title]), + ]; + $also_known[] = t('@group: @field', ['@group' => $group_name, '@field' => $title]); } } if ($aliases) { @@ -592,7 +669,7 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora $data[$table_alias][$column_real_name]['help'] = Markup::create($data[$table_alias][$column_real_name]['help'] . ' ' . t('Also known as:') . ' ' . implode(', ', $also_known)); } - $data[$table_alias][$column_real_name]['argument'] = array( + $data[$table_alias][$column_real_name]['argument'] = [ 'field' => $column_real_name, 'table' => $table, 'id' => $argument, @@ -600,8 +677,8 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora 'field_name' => $field_name, 'entity_type' => $entity_type_id, 'empty field name' => t('- No value -'), - ); - $data[$table_alias][$column_real_name]['filter'] = array( + ]; + $data[$table_alias][$column_real_name]['filter'] = [ 'field' => $column_real_name, 'table' => $table, 'id' => $filter, @@ -609,16 +686,16 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora 'field_name' => $field_name, 'entity_type' => $entity_type_id, 'allow empty' => TRUE, - ); + ]; if (!empty($allow_sort)) { - $data[$table_alias][$column_real_name]['sort'] = array( + $data[$table_alias][$column_real_name]['sort'] = [ 'field' => $column_real_name, 'table' => $table, 'id' => $sort, 'additional fields' => $additional_fields, 'field_name' => $field_name, 'entity_type' => $entity_type_id, - ); + ]; } // Set click sortable if there is a field definition. @@ -628,19 +705,19 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora // Expose additional delta column for multiple value fields. if ($field_storage->isMultiple()) { - $title_delta = t('@label (@name:delta)', array('@label' => $label, '@name' => $field_name)); - $title_short_delta = t('@label:delta', array('@label' => $label)); + $title_delta = t('@label (@name:delta)', ['@label' => $label, '@name' => $field_name]); + $title_short_delta = t('@label:delta', ['@label' => $label]); - $data[$table_alias]['delta'] = array( + $data[$table_alias]['delta'] = [ 'group' => $group, 'title' => $title_delta, 'title short' => $title_short_delta, - 'help' => t('Delta - Appears in: @bundles.', array('@bundles' => implode(', ', $bundles_names))), - ); - $data[$table_alias]['delta']['field'] = array( + 'help' => t('Delta - Appears in: @bundles.', ['@bundles' => implode(', ', $bundles_names)]), + ]; + $data[$table_alias]['delta']['field'] = [ 'id' => 'numeric', - ); - $data[$table_alias]['delta']['argument'] = array( + ]; + $data[$table_alias]['delta']['argument'] = [ 'field' => 'delta', 'table' => $table, 'id' => 'numeric', @@ -648,8 +725,8 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora 'empty field name' => t('- No value -'), 'field_name' => $field_name, 'entity_type' => $entity_type_id, - ); - $data[$table_alias]['delta']['filter'] = array( + ]; + $data[$table_alias]['delta']['filter'] = [ 'field' => 'delta', 'table' => $table, 'id' => 'numeric', @@ -657,15 +734,15 @@ function views_field_default_views_data(FieldStorageConfigInterface $field_stora 'field_name' => $field_name, 'entity_type' => $entity_type_id, 'allow empty' => TRUE, - ); - $data[$table_alias]['delta']['sort'] = array( + ]; + $data[$table_alias]['delta']['sort'] = [ 'field' => 'delta', 'table' => $table, 'id' => 'standard', 'additional fields' => $additional_fields, 'field_name' => $field_name, 'entity_type' => $entity_type_id, - ); + ]; } } } @@ -704,30 +781,30 @@ function core_field_views_data(FieldStorageConfigInterface $field_storage) { // Provide a relationship for the entity type with the entity reference // field. - $args = array( + $args = [ '@label' => $target_entity_type->getLabel(), '@field_name' => $field_name, - ); - $data[$table_name][$field_name]['relationship'] = array( + ]; + $data[$table_name][$field_name]['relationship'] = [ 'title' => t('@label referenced from @field_name', $args), 'label' => t('@field_name: @label', $args), 'group' => $entity_type->getLabel(), - 'help' => t('Appears in: @bundles.', array('@bundles' => implode(', ', $field_storage->getBundles()))), + 'help' => t('Appears in: @bundles.', ['@bundles' => implode(', ', $field_storage->getBundles())]), 'id' => 'standard', 'base' => $target_base_table, 'entity type' => $target_entity_type_id, 'base field' => $target_entity_type->getKey('id'), 'relationship field' => $field_name . '_target_id', - ); + ]; // Provide a reverse relationship for the entity type that is referenced by // the field. $args['@entity'] = $entity_type->getLabel(); $args['@label'] = $target_entity_type->getLowercaseLabel(); $pseudo_field_name = 'reverse__' . $entity_type_id . '__' . $field_name; - $data[$target_base_table][$pseudo_field_name]['relationship'] = array( + $data[$target_base_table][$pseudo_field_name]['relationship'] = [ 'title' => t('@entity using @field_name', $args), - 'label' => t('@field_name', array('@field_name' => $field_name)), + 'label' => t('@field_name', ['@field_name' => $field_name]), 'group' => $target_entity_type->getLabel(), 'help' => t('Relate each @entity with a @field_name set to the @label.', $args), 'id' => 'entity_reverse', @@ -737,14 +814,14 @@ function core_field_views_data(FieldStorageConfigInterface $field_storage) { 'field_name' => $field_name, 'field table' => $table_mapping->getDedicatedDataTableName($field_storage), 'field field' => $field_name . '_target_id', - 'join_extra' => array( - array( + 'join_extra' => [ + [ 'field' => 'deleted', 'value' => 0, 'numeric' => TRUE, - ), - ), - ); + ], + ], + ]; } return $data; diff --git a/core/modules/views/views.views_execution.inc b/core/modules/views/views.views_execution.inc index 91dead53..8b324a35 100644 --- a/core/modules/views/views.views_execution.inc +++ b/core/modules/views/views.views_execution.inc @@ -18,10 +18,10 @@ use Drupal\views\Plugin\views\PluginBase; * \Drupal\views\Plugin\views\PluginBase::listLanguages(). */ function views_views_query_substitutions(ViewExecutable $view) { - $substitutions = array( + $substitutions = [ '***CURRENT_VERSION***' => \Drupal::VERSION, '***CURRENT_TIME***' => REQUEST_TIME, - ) + PluginBase::queryLanguageSubstitutions(); + ] + PluginBase::queryLanguageSubstitutions(); return $substitutions; } diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc index fd031d24..1b8b88ff 100644 --- a/core/modules/views_ui/admin.inc +++ b/core/modules/views_ui/admin.inc @@ -41,8 +41,8 @@ use Drupal\Core\Url; * array('dynamic_content', 'section') for this parameter. */ function views_ui_add_ajax_trigger(&$wrapping_element, $trigger_key, $refresh_parents) { - $seen_ids = &drupal_static(__FUNCTION__ . ':seen_ids', array()); - $seen_buttons = &drupal_static(__FUNCTION__ . ':seen_buttons', array()); + $seen_ids = &drupal_static(__FUNCTION__ . ':seen_ids', []); + $seen_buttons = &drupal_static(__FUNCTION__ . ':seen_buttons', []); // Add the AJAX behavior to the triggering element. $triggering_element = &$wrapping_element[$trigger_key]; @@ -60,28 +60,28 @@ function views_ui_add_ajax_trigger(&$wrapping_element, $trigger_key, $refresh_pa // should be displayed next to the triggering element on the form. $button_key = $trigger_key . '_trigger_update'; $element_info = \Drupal::service('element_info'); - $wrapping_element[$button_key] = array( + $wrapping_element[$button_key] = [ '#type' => 'submit', // Hide this button when JavaScript is enabled. - '#attributes' => array('class' => array('js-hide')), - '#submit' => array('views_ui_nojs_submit'), + '#attributes' => ['class' => ['js-hide']], + '#submit' => ['views_ui_nojs_submit'], // Add a process function to limit this button's validation errors to the // triggering element only. We have to do this in #process since until the // form API has added the #parents property to the triggering element for // us, we don't have any (easy) way to find out where its submitted values // will eventually appear in $form_state->getValues(). - '#process' => array_merge(array('views_ui_add_limited_validation'), $element_info->getInfoProperty('submit', '#process', array())), + '#process' => array_merge(['views_ui_add_limited_validation'], $element_info->getInfoProperty('submit', '#process', [])), // Add an after-build function that inserts a wrapper around the region of // the form that needs to be refreshed by AJAX (so that the AJAX system can // detect and dynamically update it). This is done in #after_build because // it's a convenient place where we have automatic access to the complete // form array, but also to minimize the chance that the HTML we add will // get clobbered by code that runs after we have added it. - '#after_build' => array_merge($element_info->getInfoProperty('submit', '#after_build', array()), array('views_ui_add_ajax_wrapper')), - ); + '#after_build' => array_merge($element_info->getInfoProperty('submit', '#after_build', []), ['views_ui_add_ajax_wrapper']), + ]; // Copy #weight and #access from the triggering element to the button, so // that the two elements will be displayed together. - foreach (array('#weight', '#access') as $property) { + foreach (['#weight', '#access'] as $property) { if (isset($triggering_element[$property])) { $wrapping_element[$button_key][$property] = $triggering_element[$property]; } @@ -92,25 +92,25 @@ function views_ui_add_ajax_trigger(&$wrapping_element, $trigger_key, $refresh_pa // key and it may be a TranslatableMarkup. $button_title = !empty($triggering_element['#title']) ? (string) $triggering_element['#title'] : $trigger_key; if (empty($seen_buttons[$button_title])) { - $wrapping_element[$button_key]['#value'] = t('Update "@title" choice', array( + $wrapping_element[$button_key]['#value'] = t('Update "@title" choice', [ '@title' => $button_title, - )); + ]); $seen_buttons[$button_title] = 1; } else { - $wrapping_element[$button_key]['#value'] = t('Update "@title" choice (@number)', array( + $wrapping_element[$button_key]['#value'] = t('Update "@title" choice (@number)', [ '@title' => $button_title, '@number' => ++$seen_buttons[$button_title], - )); + ]); } // Attach custom data to the triggering element and submit button, so we can // use it in both the process function and AJAX callback. - $ajax_data = array( + $ajax_data = [ 'wrapper' => $triggering_element['#ajax']['wrapper'], 'trigger_key' => $trigger_key, 'refresh_parents' => $refresh_parents, - ); + ]; $seen_ids[$triggering_element['#ajax']['wrapper']] = TRUE; $triggering_element['#views_ui_ajax_data'] = $ajax_data; $wrapping_element[$button_key]['#views_ui_ajax_data'] = $ajax_data; @@ -132,7 +132,7 @@ function views_ui_add_limited_validation($element, FormStateInterface $form_stat // Limit this button's validation to the AJAX triggering element, so it can // update the form for that change without requiring that the rest of the // form be filled out properly yet. - $element['#limit_validation_errors'] = array($ajax_triggering_element['#parents']); + $element['#limit_validation_errors'] = [$ajax_triggering_element['#parents']]; // If we are in the process of a form submission and this is the button that // was clicked, the form API workflow in \Drupal::formBuilder()->doBuildForm() @@ -165,10 +165,10 @@ function views_ui_add_ajax_wrapper($element, FormStateInterface $form_state) { // The HTML ID that AJAX expects was also stored in a property on the // element, so use that information to insert the wrapper
              here. $id = $element['#views_ui_ajax_data']['wrapper']; - $refresh_element += array( + $refresh_element += [ '#prefix' => '', '#suffix' => '', - ); + ]; $refresh_element['#prefix'] = '
              ' . $refresh_element['#prefix']; $refresh_element['#suffix'] .= '
              '; @@ -213,16 +213,16 @@ function views_ui_standard_display_dropdown(&$form, FormStateInterface $form_sta // @todo Move this to a separate function if it's needed on any forms that // don't have the display dropdown. - $form['override'] = array( + $form['override'] = [ '#prefix' => '
              ', '#suffix' => '
              ', '#weight' => -1000, '#tree' => TRUE, - ); + ]; // Add the "2 of 3" progress indicator. if ($form_progress = $view->getFormProgress()) { - $form['progress']['#markup'] = '
              ' . t('@current of @total', array('@current' => $form_progress['current'], '@total' => $form_progress['total'])) . '
              '; + $form['progress']['#markup'] = '
              ' . t('@current of @total', ['@current' => $form_progress['current'], '@total' => $form_progress['total']]) . '
              '; $form['progress']['#weight'] = -1001; } @@ -247,17 +247,18 @@ function views_ui_standard_display_dropdown(&$form, FormStateInterface $form_sta } $display_dropdown['default'] = ($section_overrides ? t('All displays (except overridden)') : t('All displays')); - $display_dropdown[$display_id] = t('This @display_type (override)', array('@display_type' => $current_display->getPluginId())); + $display_dropdown[$display_id] = t('This @display_type (override)', ['@display_type' => $current_display->getPluginId()]); // Only display the revert option if we are in a overridden section. if (!$section_defaulted) { $display_dropdown['default_revert'] = t('Revert to default'); } - $form['override']['dropdown'] = array( + $form['override']['dropdown'] = [ '#type' => 'select', - '#title' => t('For'), // @TODO: Translators may need more context than this. + // @TODO: Translators may need more context than this. + '#title' => t('For'), '#options' => $display_dropdown, - ); + ]; if ($current_display->isDefaulted($section)) { $form['override']['dropdown']['#default_value'] = 'defaults'; } diff --git a/core/modules/views_ui/css/views_ui.admin.css b/core/modules/views_ui/css/views_ui.admin.css index e932af13..3d1db05d 100644 --- a/core/modules/views_ui/css/views_ui.admin.css +++ b/core/modules/views_ui/css/views_ui.admin.css @@ -147,7 +147,7 @@ margin-bottom: 2em; } -@media screen and (min-width:45em) { /* 720px */ +@media screen and (min-width: 45em) { /* 720px */ .views-display-columns > * { float: left; /* LTR */ margin-left: 2%; /* LTR */ diff --git a/core/modules/views_ui/css/views_ui.admin.theme.css b/core/modules/views_ui/css/views_ui.admin.theme.css index 4ab55c46..30616f05 100644 --- a/core/modules/views_ui/css/views_ui.admin.theme.css +++ b/core/modules/views_ui/css/views_ui.admin.theme.css @@ -158,7 +158,7 @@ details.box-padding { /* Hide 'remove' checkboxes. */ .views-remove-checkbox { - display: none; + display: none; } /* sizes the labels of checkboxes and radio button to the height of the text */ @@ -170,9 +170,9 @@ details.box-padding { margin-bottom: 6px; margin-top: 6px; } -.views-ui-view-title { +.views-ui-view-name h3 { font-weight: bold; - margin-top: 0; + margin: 0.25em 0; } .view-changed { margin-bottom: 21px; @@ -183,22 +183,33 @@ details.box-padding { margin-bottom: 0; margin-top: 18px; } +.views-ui-view-displays ul { + margin-left: 0; /* LTR */ + padding-left: 0; /* LTR */ + list-style: none; +} +[dir="rtl"] .views-ui-view-displays ul { + margin-right: 0; + padding-right: 0; + margin-left: inherit; + padding-left: inherit; +} /* These header classes are ambiguous and should be scoped to th elements */ .views-ui-name { - width: 18%; + width: 20%; } .views-ui-description { - width: 26%; + width: 30%; } -.views-ui-tag { - width: 8%; +.views-ui-machine-name { + width: 15%; } -.views-ui-path { - width: auto; +.views-ui-displays { + width: 25%; } .views-ui-operations { - width: 24%; + width: 10%; } /** @@ -334,7 +345,7 @@ td.group-title { padding: 0; width: auto; } -.views-displays .tabs li.add ul.action-list li{ +.views-displays .tabs li.add ul.action-list li { margin: 0; } .views-displays .tabs.secondary li { @@ -391,7 +402,7 @@ td.group-title { color: #0074bd; background-color: #f1f1f1; } -.views-displays .tabs .action-list li { +.views-displays .tabs .action-list li { background-color: #f1f1f1; border-color: #cbcbcb; border-style: solid; @@ -401,10 +412,10 @@ td.group-title { .views-displays .tabs .action-list li:first-child { border-width: 1px 1px 0; } -.views-displays .action-list li:last-child { +.views-displays .action-list li:last-child { border-width: 0 1px 1px; } -.views-displays .tabs .action-list li:last-child { +.views-displays .tabs .action-list li:last-child { border-width: 0 1px 1px; } .views-displays .tabs .action-list input.form-submit { @@ -472,7 +483,7 @@ td.group-title { .view-preview-form .form-actions { vertical-align: top; } -@media screen and (min-width:45em) { /* 720px */ +@media screen and (min-width: 45em) { /* 720px */ .view-preview-form .form-type-textfield .description { white-space: nowrap; } diff --git a/core/modules/views_ui/js/ajax.es6.js b/core/modules/views_ui/js/ajax.es6.js new file mode 100644 index 00000000..73f2b967 --- /dev/null +++ b/core/modules/views_ui/js/ajax.es6.js @@ -0,0 +1,244 @@ +/** + * @file + * Handles AJAX submission and response in Views UI. + */ + +(function ($, Drupal, drupalSettings) { + /** + * Ajax command for highlighting elements. + * + * @param {Drupal.Ajax} [ajax] + * An Ajax object. + * @param {object} response + * The Ajax response. + * @param {string} response.selector + * The selector in question. + * @param {number} [status] + * The HTTP status code. + */ + Drupal.AjaxCommands.prototype.viewsHighlight = function (ajax, response, status) { + $('.hilited').removeClass('hilited'); + $(response.selector).addClass('hilited'); + }; + + /** + * Ajax command to set the form submit action in the views modal edit form. + * + * @param {Drupal.Ajax} [ajax] + * An Ajax object. + * @param {object} response + * The Ajax response. Contains .url + * @param {string} [status] + * The XHR status code? + */ + Drupal.AjaxCommands.prototype.viewsSetForm = function (ajax, response, status) { + const $form = $('.js-views-ui-dialog form'); + // Identify the button that was clicked so that .ajaxSubmit() can use it. + // We need to do this for both .click() and .mousedown() since JavaScript + // code might trigger either behavior. + const $submit_buttons = $form.find('input[type=submit].js-form-submit, button.js-form-submit').once('views-ajax-submit'); + $submit_buttons.on('click mousedown', function () { + this.form.clk = this; + }); + $form.once('views-ajax-submit').each(function () { + const $form = $(this); + const element_settings = { + url: response.url, + event: 'submit', + base: $form.attr('id'), + element: this, + }; + const ajaxForm = Drupal.ajax(element_settings); + ajaxForm.$form = $form; + }); + }; + + /** + * Ajax command to show certain buttons in the views edit form. + * + * @param {Drupal.Ajax} [ajax] + * An Ajax object. + * @param {object} response + * The Ajax response. + * @param {bool} response.changed + * Whether the state changed for the buttons or not. + * @param {number} [status] + * The HTTP status code. + */ + Drupal.AjaxCommands.prototype.viewsShowButtons = function (ajax, response, status) { + $('div.views-edit-view div.form-actions').removeClass('js-hide'); + if (response.changed) { + $('div.views-edit-view div.view-changed.messages').removeClass('js-hide'); + } + }; + + /** + * Ajax command for triggering preview. + * + * @param {Drupal.Ajax} [ajax] + * An Ajax object. + * @param {object} [response] + * The Ajax response. + * @param {number} [status] + * The HTTP status code. + */ + Drupal.AjaxCommands.prototype.viewsTriggerPreview = function (ajax, response, status) { + if ($('input#edit-displays-live-preview').is(':checked')) { + $('#preview-submit').trigger('click'); + } + }; + + /** + * Ajax command to replace the title of a page. + * + * @param {Drupal.Ajax} [ajax] + * An Ajax object. + * @param {object} response + * The Ajax response. + * @param {string} response.siteName + * The site name. + * @param {string} response.title + * The new page title. + * @param {number} [status] + * The HTTP status code. + */ + Drupal.AjaxCommands.prototype.viewsReplaceTitle = function (ajax, response, status) { + const doc = document; + // For the element, make a best-effort attempt to replace the page + // title and leave the site name alone. If the theme doesn't use the site + // name in the <title> element, this will fail. + const oldTitle = doc.title; + // Escape the site name, in case it has special characters in it, so we can + // use it in our regex. + const escapedSiteName = response.siteName.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + const re = new RegExp(`.+ (.) ${escapedSiteName}`); + doc.title = oldTitle.replace(re, `${response.title} $1 ${response.siteName}`); + + $('h1.page-title').text(response.title); + }; + + /** + * Get rid of irritating tabledrag messages. + * + * @return {Array} + * An array of messages. Always empty array, to get rid of the messages. + */ + Drupal.theme.tableDragChangedWarning = function () { + return []; + }; + + /** + * Trigger preview when the "live preview" checkbox is checked. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches behavior to trigger live preview if the live preview option is + * checked. + */ + Drupal.behaviors.livePreview = { + attach(context) { + $('input#edit-displays-live-preview', context).once('views-ajax').on('click', function () { + if ($(this).is(':checked')) { + $('#preview-submit').trigger('click'); + } + }); + }, + }; + + /** + * Sync preview display. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches behavior to sync the preview display when needed. + */ + Drupal.behaviors.syncPreviewDisplay = { + attach(context) { + $('#views-tabset a').once('views-ajax').on('click', function () { + const href = $(this).attr('href'); + // Cut of #views-tabset. + const display_id = href.substr(11); + // Set the form element. + $('#views-live-preview #preview-display-id').val(display_id); + }); + }, + }; + + /** + * Ajax behaviors for the views_ui module. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches ajax behaviors to the elements with the classes in question. + */ + Drupal.behaviors.viewsAjax = { + collapseReplaced: false, + attach(context, settings) { + const base_element_settings = { + event: 'click', + progress: { type: 'fullscreen' }, + }; + // Bind AJAX behaviors to all items showing the class. + $('a.views-ajax-link', context).once('views-ajax').each(function () { + const element_settings = base_element_settings; + element_settings.base = $(this).attr('id'); + element_settings.element = this; + // Set the URL to go to the anchor. + if ($(this).attr('href')) { + element_settings.url = $(this).attr('href'); + } + Drupal.ajax(element_settings); + }); + + $('div#views-live-preview a') + .once('views-ajax').each(function () { + // We don't bind to links without a URL. + if (!$(this).attr('href')) { + return true; + } + + const element_settings = base_element_settings; + // Set the URL to go to the anchor. + element_settings.url = $(this).attr('href'); + if (Drupal.Views.getPath(element_settings.url).substring(0, 21) !== 'admin/structure/views') { + return true; + } + + element_settings.wrapper = 'views-preview-wrapper'; + element_settings.method = 'replaceWith'; + element_settings.base = $(this).attr('id'); + element_settings.element = this; + Drupal.ajax(element_settings); + }); + + // Within a live preview, make exposed widget form buttons re-trigger the + // Preview button. + // @todo Revisit this after fixing Views UI to display a Preview outside + // of the main Edit form. + $('div#views-live-preview input[type=submit]') + .once('views-ajax').each(function (event) { + $(this).on('click', function () { + this.form.clk = this; + return true; + }); + const element_settings = base_element_settings; + // Set the URL to go to the anchor. + element_settings.url = $(this.form).attr('action'); + if (Drupal.Views.getPath(element_settings.url).substring(0, 21) !== 'admin/structure/views') { + return true; + } + + element_settings.wrapper = 'views-preview-wrapper'; + element_settings.method = 'replaceWith'; + element_settings.event = 'click'; + element_settings.base = $(this).attr('id'); + element_settings.element = this; + + Drupal.ajax(element_settings); + }); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/views_ui/js/ajax.js b/core/modules/views_ui/js/ajax.js index b044688c..00024f57 100644 --- a/core/modules/views_ui/js/ajax.js +++ b/core/modules/views_ui/js/ajax.js @@ -1,44 +1,19 @@ /** - * @file - * Handles AJAX submission and response in Views UI. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * Ajax command for highlighting elements. - * - * @param {Drupal.Ajax} [ajax] - * An Ajax object. - * @param {object} response - * The Ajax response. - * @param {string} response.selector - * The selector in question. - * @param {number} [status] - * The HTTP status code. - */ Drupal.AjaxCommands.prototype.viewsHighlight = function (ajax, response, status) { $('.hilited').removeClass('hilited'); $(response.selector).addClass('hilited'); }; - /** - * Ajax command to set the form submit action in the views modal edit form. - * - * @param {Drupal.Ajax} [ajax] - * An Ajax object. - * @param {object} response - * The Ajax response. Contains .url - * @param {string} [status] - * The XHR status code? - */ Drupal.AjaxCommands.prototype.viewsSetForm = function (ajax, response, status) { var $form = $('.js-views-ui-dialog form'); - // Identify the button that was clicked so that .ajaxSubmit() can use it. - // We need to do this for both .click() and .mousedown() since JavaScript - // code might trigger either behavior. + var $submit_buttons = $form.find('input[type=submit].js-form-submit, button.js-form-submit').once('views-ajax-submit'); $submit_buttons.on('click mousedown', function () { this.form.clk = this; @@ -56,18 +31,6 @@ }); }; - /** - * Ajax command to show certain buttons in the views edit form. - * - * @param {Drupal.Ajax} [ajax] - * An Ajax object. - * @param {object} response - * The Ajax response. - * @param {bool} response.changed - * Whether the state changed for the buttons or not. - * @param {number} [status] - * The HTTP status code. - */ Drupal.AjaxCommands.prototype.viewsShowButtons = function (ajax, response, status) { $('div.views-edit-view div.form-actions').removeClass('js-hide'); if (response.changed) { @@ -75,44 +38,17 @@ } }; - /** - * Ajax command for triggering preview. - * - * @param {Drupal.Ajax} [ajax] - * An Ajax object. - * @param {object} [response] - * The Ajax response. - * @param {number} [status] - * The HTTP status code. - */ Drupal.AjaxCommands.prototype.viewsTriggerPreview = function (ajax, response, status) { if ($('input#edit-displays-live-preview').is(':checked')) { $('#preview-submit').trigger('click'); } }; - /** - * Ajax command to replace the title of a page. - * - * @param {Drupal.Ajax} [ajax] - * An Ajax object. - * @param {object} response - * The Ajax response. - * @param {string} response.siteName - * The site name. - * @param {string} response.title - * The new page title. - * @param {number} [status] - * The HTTP status code. - */ Drupal.AjaxCommands.prototype.viewsReplaceTitle = function (ajax, response, status) { var doc = document; - // For the <title> element, make a best-effort attempt to replace the page - // title and leave the site name alone. If the theme doesn't use the site - // name in the <title> element, this will fail. + var oldTitle = doc.title; - // Escape the site name, in case it has special characters in it, so we can - // use it in our regex. + var escapedSiteName = response.siteName.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); var re = new RegExp('.+ (.) ' + escapedSiteName); doc.title = oldTitle.replace(re, response.title + ' $1 ' + response.siteName); @@ -120,27 +56,12 @@ $('h1.page-title').text(response.title); }; - /** - * Get rid of irritating tabledrag messages. - * - * @return {Array} - * An array of messages. Always empty array, to get rid of the messages. - */ Drupal.theme.tableDragChangedWarning = function () { return []; }; - /** - * Trigger preview when the "live preview" checkbox is checked. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches behavior to trigger live preview if the live preview option is - * checked. - */ Drupal.behaviors.livePreview = { - attach: function (context) { + attach: function attach(context) { $('input#edit-displays-live-preview', context).once('views-ajax').on('click', function () { if ($(this).is(':checked')) { $('#preview-submit').trigger('click'); @@ -149,104 +70,76 @@ } }; - /** - * Sync preview display. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches behavior to sync the preview display when needed. - */ Drupal.behaviors.syncPreviewDisplay = { - attach: function (context) { + attach: function attach(context) { $('#views-tabset a').once('views-ajax').on('click', function () { var href = $(this).attr('href'); - // Cut of #views-tabset. + var display_id = href.substr(11); - // Set the form element. + $('#views-live-preview #preview-display-id').val(display_id); }); } }; - /** - * Ajax behaviors for the views_ui module. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches ajax behaviors to the elements with the classes in question. - */ Drupal.behaviors.viewsAjax = { collapseReplaced: false, - attach: function (context, settings) { + attach: function attach(context, settings) { var base_element_settings = { event: 'click', - progress: {type: 'fullscreen'} + progress: { type: 'fullscreen' } }; - // Bind AJAX behaviors to all items showing the class. + $('a.views-ajax-link', context).once('views-ajax').each(function () { var element_settings = base_element_settings; - element_settings.base = base; + element_settings.base = $(this).attr('id'); element_settings.element = this; - // Set the URL to go to the anchor. + if ($(this).attr('href')) { element_settings.url = $(this).attr('href'); } - var base = $(this).attr('id'); Drupal.ajax(element_settings); }); - $('div#views-live-preview a') - .once('views-ajax').each(function () { - // We don't bind to links without a URL. - if (!$(this).attr('href')) { - return true; - } + $('div#views-live-preview a').once('views-ajax').each(function () { + if (!$(this).attr('href')) { + return true; + } - var element_settings = base_element_settings; - // Set the URL to go to the anchor. - element_settings.url = $(this).attr('href'); - if (Drupal.Views.getPath(element_settings.url).substring(0, 21) !== 'admin/structure/views') { - return true; - } - - element_settings.wrapper = 'views-preview-wrapper'; - element_settings.method = 'replaceWith'; - element_settings.base = base; - element_settings.element = this; - var base = $(this).attr('id'); - Drupal.ajax(element_settings); - }); + var element_settings = base_element_settings; + + element_settings.url = $(this).attr('href'); + if (Drupal.Views.getPath(element_settings.url).substring(0, 21) !== 'admin/structure/views') { + return true; + } - // Within a live preview, make exposed widget form buttons re-trigger the - // Preview button. - // @todo Revisit this after fixing Views UI to display a Preview outside - // of the main Edit form. - $('div#views-live-preview input[type=submit]') - .once('views-ajax').each(function (event) { - $(this).on('click', function () { - this.form.clk = this; - return true; - }); - var element_settings = base_element_settings; - // Set the URL to go to the anchor. - element_settings.url = $(this.form).attr('action'); - if (Drupal.Views.getPath(element_settings.url).substring(0, 21) !== 'admin/structure/views') { - return true; - } - - element_settings.wrapper = 'views-preview-wrapper'; - element_settings.method = 'replaceWith'; - element_settings.event = 'click'; - element_settings.base = base; - element_settings.element = this; - - var base = $(this).attr('id'); - Drupal.ajax(element_settings); + element_settings.wrapper = 'views-preview-wrapper'; + element_settings.method = 'replaceWith'; + element_settings.base = $(this).attr('id'); + element_settings.element = this; + Drupal.ajax(element_settings); + }); + + $('div#views-live-preview input[type=submit]').once('views-ajax').each(function (event) { + $(this).on('click', function () { + this.form.clk = this; + return true; }); + var element_settings = base_element_settings; + element_settings.url = $(this.form).attr('action'); + if (Drupal.Views.getPath(element_settings.url).substring(0, 21) !== 'admin/structure/views') { + return true; + } + + element_settings.wrapper = 'views-preview-wrapper'; + element_settings.method = 'replaceWith'; + element_settings.event = 'click'; + element_settings.base = $(this).attr('id'); + element_settings.element = this; + + Drupal.ajax(element_settings); + }); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/views_ui/js/dialog.views.es6.js b/core/modules/views_ui/js/dialog.views.es6.js new file mode 100644 index 00000000..15f937f5 --- /dev/null +++ b/core/modules/views_ui/js/dialog.views.es6.js @@ -0,0 +1,56 @@ +/** + * @file + * Views dialog behaviors. + */ + +(function ($, Drupal, drupalSettings) { + function handleDialogResize(e) { + const $modal = $(e.currentTarget); + const $viewsOverride = $modal.find('[data-drupal-views-offset]'); + const $scroll = $modal.find('[data-drupal-views-scroll]'); + let offset = 0; + let modalHeight; + if ($scroll.length) { + // Add a class to do some styles adjustments. + $modal.closest('.views-ui-dialog').addClass('views-ui-dialog-scroll'); + // Let scroll element take all the height available. + $scroll.css({ overflow: 'visible', height: 'auto' }); + modalHeight = $modal.height(); + $viewsOverride.each(function () { + offset += $(this).outerHeight(); + }); + + // Take internal padding into account. + const scrollOffset = $scroll.outerHeight() - $scroll.height(); + $scroll.height(modalHeight - offset - scrollOffset); + // Reset scrolling properties. + $modal.css('overflow', 'hidden'); + $scroll.css('overflow', 'auto'); + } + } + + /** + * Functionality for views modals. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches modal functionality for views. + * @prop {Drupal~behaviorDetach} detach + * Detaches the modal functionality. + */ + Drupal.behaviors.viewsModalContent = { + attach(context) { + $('body').once('viewsDialog').on('dialogContentResize.viewsDialog', '.ui-dialog-content', handleDialogResize); + // When expanding details, make sure the modal is resized. + $(context).find('.scroll').once('detailsUpdate').on('click', 'summary', (e) => { + $(e.currentTarget).trigger('dialogContentResize'); + }); + }, + detach(context, settings, trigger) { + if (trigger === 'unload') { + $('body').removeOnce('viewsDialog').off('.viewsDialog'); + } + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/views_ui/js/dialog.views.js b/core/modules/views_ui/js/dialog.views.js index 3f40b4ad..fde19353 100644 --- a/core/modules/views_ui/js/dialog.views.js +++ b/core/modules/views_ui/js/dialog.views.js @@ -1,58 +1,46 @@ /** - * @file - * Views dialog behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - function handleDialogResize(e) { var $modal = $(e.currentTarget); var $viewsOverride = $modal.find('[data-drupal-views-offset]'); var $scroll = $modal.find('[data-drupal-views-scroll]'); var offset = 0; - var modalHeight; + var modalHeight = void 0; if ($scroll.length) { - // Add a class to do some styles adjustments. $modal.closest('.views-ui-dialog').addClass('views-ui-dialog-scroll'); - // Let scroll element take all the height available. - $scroll.css({overflow: 'visible', height: 'auto'}); + + $scroll.css({ overflow: 'visible', height: 'auto' }); modalHeight = $modal.height(); - $viewsOverride.each(function () { offset += $(this).outerHeight(); }); + $viewsOverride.each(function () { + offset += $(this).outerHeight(); + }); - // Take internal padding into account. var scrollOffset = $scroll.outerHeight() - $scroll.height(); $scroll.height(modalHeight - offset - scrollOffset); - // Reset scrolling properties. + $modal.css('overflow', 'hidden'); $scroll.css('overflow', 'auto'); } } - /** - * Functionality for views modals. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches modal functionality for views. - * @prop {Drupal~behaviorDetach} detach - * Detaches the modal functionality. - */ Drupal.behaviors.viewsModalContent = { - attach: function (context) { + attach: function attach(context) { $('body').once('viewsDialog').on('dialogContentResize.viewsDialog', '.ui-dialog-content', handleDialogResize); - // When expanding details, make sure the modal is resized. + $(context).find('.scroll').once('detailsUpdate').on('click', 'summary', function (e) { $(e.currentTarget).trigger('dialogContentResize'); }); }, - detach: function (context, settings, trigger) { + detach: function detach(context, settings, trigger) { if (trigger === 'unload') { $('body').removeOnce('viewsDialog').off('.viewsDialog'); } } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/views_ui/js/views-admin.es6.js b/core/modules/views_ui/js/views-admin.es6.js new file mode 100644 index 00000000..1078209c --- /dev/null +++ b/core/modules/views_ui/js/views-admin.es6.js @@ -0,0 +1,1184 @@ +/** + * @file + * Some basic behaviors and utility functions for Views UI. + */ + +(function ($, Drupal, drupalSettings) { + /** + * @namespace + */ + Drupal.viewsUi = {}; + + /** + * Improve the user experience of the views edit interface. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches toggling of SQL rewrite warning on the corresponding checkbox. + */ + Drupal.behaviors.viewsUiEditView = { + attach() { + // Only show the SQL rewrite warning when the user has chosen the + // corresponding checkbox. + $('[data-drupal-selector="edit-query-options-disable-sql-rewrite"]').on('click', () => { + $('.sql-rewrite-warning').toggleClass('js-hide'); + }); + }, + }; + + /** + * In the add view wizard, use the view name to prepopulate form fields such + * as page title and menu link. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches behavior for prepopulating page title and menu links, based on + * view name. + */ + Drupal.behaviors.viewsUiAddView = { + attach(context) { + const $context = $(context); + // Set up regular expressions to allow only numbers, letters, and dashes. + const exclude = new RegExp('[^a-z0-9\\-]+', 'g'); + const replace = '-'; + let suffix; + + // The page title, block title, and menu link fields can all be + // prepopulated with the view name - no regular expression needed. + const $fields = $context.find('[id^="edit-page-title"], [id^="edit-block-title"], [id^="edit-page-link-properties-title"]'); + if ($fields.length) { + if (!this.fieldsFiller) { + this.fieldsFiller = new Drupal.viewsUi.FormFieldFiller($fields); + } + else { + // After an AJAX response, this.fieldsFiller will still have event + // handlers bound to the old version of the form fields (which don't + // exist anymore). The event handlers need to be unbound and then + // rebound to the new markup. Note that jQuery.live is difficult to + // make work in this case because the IDs of the form fields change + // on every AJAX response. + this.fieldsFiller.rebind($fields); + } + } + + // Prepopulate the path field with a URLified version of the view name. + const $pathField = $context.find('[id^="edit-page-path"]'); + if ($pathField.length) { + if (!this.pathFiller) { + this.pathFiller = new Drupal.viewsUi.FormFieldFiller($pathField, exclude, replace); + } + else { + this.pathFiller.rebind($pathField); + } + } + + // Populate the RSS feed field with a URLified version of the view name, + // and an .xml suffix (to make it unique). + const $feedField = $context.find('[id^="edit-page-feed-properties-path"]'); + if ($feedField.length) { + if (!this.feedFiller) { + suffix = '.xml'; + this.feedFiller = new Drupal.viewsUi.FormFieldFiller($feedField, exclude, replace, suffix); + } + else { + this.feedFiller.rebind($feedField); + } + } + }, + }; + + /** + * Constructor for the {@link Drupal.viewsUi.FormFieldFiller} object. + * + * Prepopulates a form field based on the view name. + * + * @constructor + * + * @param {jQuery} $target + * A jQuery object representing the form field or fields to prepopulate. + * @param {bool} [exclude=false] + * A regular expression representing characters to exclude from + * the target field. + * @param {string} [replace=''] + * A string to use as the replacement value for disallowed characters. + * @param {string} [suffix=''] + * A suffix to append at the end of the target field content. + */ + Drupal.viewsUi.FormFieldFiller = function ($target, exclude, replace, suffix) { + /** + * + * @type {jQuery} + */ + this.source = $('#edit-label'); + + /** + * + * @type {jQuery} + */ + this.target = $target; + + /** + * + * @type {bool} + */ + this.exclude = exclude || false; + + /** + * + * @type {string} + */ + this.replace = replace || ''; + + /** + * + * @type {string} + */ + this.suffix = suffix || ''; + + // Create bound versions of this instance's object methods to use as event + // handlers. This will let us easily unbind those specific handlers later + // on. NOTE: jQuery.proxy will not work for this because it assumes we want + // only one bound version of an object method, whereas we need one version + // per object instance. + const self = this; + + /** + * Populate the target form field with the altered source field value. + * + * @return {*} + * The result of the _populate call, which should be undefined. + */ + this.populate = function () { + return self._populate.call(self); + }; + + /** + * Stop prepopulating the form fields. + * + * @return {*} + * The result of the _unbind call, which should be undefined. + */ + this.unbind = function () { + return self._unbind.call(self); + }; + + this.bind(); + // Object constructor; no return value. + }; + + $.extend(Drupal.viewsUi.FormFieldFiller.prototype, /** @lends Drupal.viewsUi.FormFieldFiller# */{ + + /** + * Bind the form-filling behavior. + */ + bind() { + this.unbind(); + // Populate the form field when the source changes. + this.source.on('keyup.viewsUi change.viewsUi', this.populate); + // Quit populating the field as soon as it gets focus. + this.target.on('focus.viewsUi', this.unbind); + }, + + /** + * Get the source form field value as altered by the passed-in parameters. + * + * @return {string} + * The source form field value. + */ + getTransliterated() { + let from = this.source.val(); + if (this.exclude) { + from = from.toLowerCase().replace(this.exclude, this.replace); + } + return from; + }, + + /** + * Populate the target form field with the altered source field value. + */ + _populate() { + const transliterated = this.getTransliterated(); + const suffix = this.suffix; + this.target.each(function (i) { + // Ensure that the maxlength is not exceeded by prepopulating the field. + const maxlength = $(this).attr('maxlength') - suffix.length; + $(this).val(transliterated.substr(0, maxlength) + suffix); + }); + }, + + /** + * Stop prepopulating the form fields. + */ + _unbind() { + this.source.off('keyup.viewsUi change.viewsUi', this.populate); + this.target.off('focus.viewsUi', this.unbind); + }, + + /** + * Bind event handlers to new form fields, after they're replaced via Ajax. + * + * @param {jQuery} $fields + * Fields to rebind functionality to. + */ + rebind($fields) { + this.target = $fields; + this.bind(); + }, + }); + + /** + * Adds functionality for the add item form. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the functionality in {@link Drupal.viewsUi.AddItemForm} to the + * forms in question. + */ + Drupal.behaviors.addItemForm = { + attach(context) { + const $context = $(context); + let $form = $context; + // The add handler form may have an id of views-ui-add-handler-form--n. + if (!$context.is('form[id^="views-ui-add-handler-form"]')) { + $form = $context.find('form[id^="views-ui-add-handler-form"]'); + } + if ($form.once('views-ui-add-handler-form').length) { + // If we we have an unprocessed views-ui-add-handler-form, let's + // instantiate. + new Drupal.viewsUi.AddItemForm($form); + } + }, + }; + + /** + * Constructs a new AddItemForm. + * + * @constructor + * + * @param {jQuery} $form + * The form element used. + */ + Drupal.viewsUi.AddItemForm = function ($form) { + /** + * + * @type {jQuery} + */ + this.$form = $form; + this.$form.find('.views-filterable-options :checkbox').on('click', $.proxy(this.handleCheck, this)); + + /** + * Find the wrapper of the displayed text. + */ + this.$selected_div = this.$form.find('.views-selected-options').parent(); + this.$selected_div.hide(); + + /** + * + * @type {Array} + */ + this.checkedItems = []; + }; + + /** + * Handles a checkbox check. + * + * @param {jQuery.Event} event + * The event triggered. + */ + Drupal.viewsUi.AddItemForm.prototype.handleCheck = function (event) { + const $target = $(event.target); + const label = $.trim($target.closest('td').next().html()); + // Add/remove the checked item to the list. + if ($target.is(':checked')) { + this.$selected_div.show().css('display', 'block'); + this.checkedItems.push(label); + } + else { + const position = $.inArray(label, this.checkedItems); + // Delete the item from the list and make sure that the list doesn't have + // undefined items left. + for (let i = 0; i < this.checkedItems.length; i++) { + if (i === position) { + this.checkedItems.splice(i, 1); + i--; + break; + } + } + // Hide it again if none item is selected. + if (this.checkedItems.length === 0) { + this.$selected_div.hide(); + } + } + this.refreshCheckedItems(); + }; + + /** + * Refresh the display of the checked items. + */ + Drupal.viewsUi.AddItemForm.prototype.refreshCheckedItems = function () { + // Perhaps we should precache the text div, too. + this.$selected_div.find('.views-selected-options') + .html(this.checkedItems.join(', ')) + .trigger('dialogContentResize'); + }; + + /** + * The input field items that add displays must be rendered as `<input>` + * elements. The following behavior detaches the `<input>` elements from the + * DOM, wraps them in an unordered list, then appends them to the list of + * tabs. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Fixes the input elements needed. + */ + Drupal.behaviors.viewsUiRenderAddViewButton = { + attach(context) { + // Build the add display menu and pull the display input buttons into it. + const $menu = $(context).find('#views-display-menu-tabs').once('views-ui-render-add-view-button'); + if (!$menu.length) { + return; + } + + const $addDisplayDropdown = $(`<li class="add"><a href="#"><span class="icon add"></span>${Drupal.t('Add')}</a><ul class="action-list" style="display:none;"></ul></li>`); + const $displayButtons = $menu.nextAll('input.add-display').detach(); + $displayButtons.appendTo($addDisplayDropdown.find('.action-list')).wrap('<li>') + .parent().eq(0).addClass('first').end().eq(-1).addClass('last'); + // Remove the 'Add ' prefix from the button labels since they're being + // placed in an 'Add' dropdown. @todo This assumes English, but so does + // $addDisplayDropdown above. Add support for translation. + $displayButtons.each(function () { + const label = $(this).val(); + if (label.substr(0, 4) === 'Add ') { + $(this).val(label.substr(4)); + } + }); + $addDisplayDropdown.appendTo($menu); + + // Add the click handler for the add display button. + $menu.find('li.add > a').on('click', function (event) { + event.preventDefault(); + const $trigger = $(this); + Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu($trigger); + }); + // Add a mouseleave handler to close the dropdown when the user mouses + // away from the item. We use mouseleave instead of mouseout because + // the user is going to trigger mouseout when she moves from the trigger + // link to the sub menu items. + // We use the live binder because the open class on this item will be + // toggled on and off and we want the handler to take effect in the cases + // that the class is present, but not when it isn't. + $('li.add', $menu).on('mouseleave', function (event) { + const $this = $(this); + const $trigger = $this.children('a[href="#"]'); + if ($this.children('.action-list').is(':visible')) { + Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu($trigger); + } + }); + }, + }; + + /** + * Toggle menu visibility. + * + * @param {jQuery} $trigger + * The element where the toggle was triggered. + * + * + * @note [@jessebeach] I feel like the following should be a more generic + * function and not written specifically for this UI, but I'm not sure + * where to put it. + */ + Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu = function ($trigger) { + $trigger.parent().toggleClass('open'); + $trigger.next().slideToggle('fast'); + }; + + /** + * Add search options to the views ui. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches {@link Drupal.viewsUi.OptionsSearch} to the views ui filter + * options. + */ + Drupal.behaviors.viewsUiSearchOptions = { + attach(context) { + const $context = $(context); + let $form = $context; + // The add handler form may have an id of views-ui-add-handler-form--n. + if (!$context.is('form[id^="views-ui-add-handler-form"]')) { + $form = $context.find('form[id^="views-ui-add-handler-form"]'); + } + // Make sure we don't add more than one event handler to the same form. + if ($form.once('views-ui-filter-options').length) { + new Drupal.viewsUi.OptionsSearch($form); + } + }, + }; + + /** + * Constructor for the viewsUi.OptionsSearch object. + * + * The OptionsSearch object filters the available options on a form according + * to the user's search term. Typing in "taxonomy" will show only those + * options containing "taxonomy" in their label. + * + * @constructor + * + * @param {jQuery} $form + * The form element. + */ + Drupal.viewsUi.OptionsSearch = function ($form) { + /** + * + * @type {jQuery} + */ + this.$form = $form; + + // Click on the title checks the box. + this.$form.on('click', 'td.title', (event) => { + const $target = $(event.currentTarget); + $target.closest('tr').find('input').trigger('click'); + }); + + const searchBoxSelector = '[data-drupal-selector="edit-override-controls-options-search"]'; + const controlGroupSelector = '[data-drupal-selector="edit-override-controls-group"]'; + this.$form.on('formUpdated', `${searchBoxSelector},${controlGroupSelector}`, $.proxy(this.handleFilter, this)); + + this.$searchBox = this.$form.find(searchBoxSelector); + this.$controlGroup = this.$form.find(controlGroupSelector); + + /** + * Get a list of option labels and their corresponding divs and maintain it + * in memory, so we have as little overhead as possible at keyup time. + */ + this.options = this.getOptions(this.$form.find('.filterable-option')); + + // Trap the ENTER key in the search box so that it doesn't submit the form. + this.$searchBox.on('keypress', (event) => { + if (event.which === 13) { + event.preventDefault(); + } + }); + }; + + $.extend(Drupal.viewsUi.OptionsSearch.prototype, /** @lends Drupal.viewsUi.OptionsSearch# */{ + + /** + * Assemble a list of all the filterable options on the form. + * + * @param {jQuery} $allOptions + * A jQuery object representing the rows of filterable options to be + * shown and hidden depending on the user's search terms. + * + * @return {Array} + * An array of all the filterable options. + */ + getOptions($allOptions) { + let $title; + let $description; + let $option; + const options = []; + const length = $allOptions.length; + for (let i = 0; i < length; i++) { + $option = $($allOptions[i]); + $title = $option.find('.title'); + $description = $option.find('.description'); + options[i] = { + // Search on the lowercase version of the title text + description. + searchText: `${$title.text().toLowerCase()} ${$description.text().toLowerCase()}`, + // Maintain a reference to the jQuery object for each row, so we don't + // have to create a new object inside the performance-sensitive keyup + // handler. + $div: $option, + }; + } + return options; + }, + + /** + * Filter handler for the search box and type select that hides or shows the relevant + * options. + * + * @param {jQuery.Event} event + * The formUpdated event. + */ + handleFilter(event) { + // Determine the user's search query. The search text has been converted + // to lowercase. + const search = this.$searchBox.val().toLowerCase(); + const words = search.split(' '); + // Get selected Group + const group = this.$controlGroup.val(); + + // Search through the search texts in the form for matching text. + this.options.forEach((option) => { + function hasWord(word) { + return option.searchText.indexOf(word) !== -1; + } + + let found = true; + // Each word in the search string has to match the item in order for the + // item to be shown. + if (search) { + found = words.every(hasWord); + } + if (found && group !== 'all') { + found = option.$div.hasClass(group); + } + + option.$div.toggle(found); + }); + + // Adapt dialog to content size. + $(event.target).trigger('dialogContentResize'); + }, + }); + + /** + * Preview functionality in the views edit form. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the preview functionality to the view edit form. + */ + Drupal.behaviors.viewsUiPreview = { + attach(context) { + // Only act on the edit view form. + const $contextualFiltersBucket = $(context).find('.views-display-column .views-ui-display-tab-bucket.argument'); + if ($contextualFiltersBucket.length === 0) { + return; + } + + // If the display has no contextual filters, hide the form where you + // enter the contextual filters for the live preview. If it has contextual + // filters, show the form. + const $contextualFilters = $contextualFiltersBucket.find('.views-display-setting a'); + if ($contextualFilters.length) { + $('#preview-args').parent().show(); + } + else { + $('#preview-args').parent().hide(); + } + + // Executes an initial preview. + if ($('#edit-displays-live-preview').once('edit-displays-live-preview').is(':checked')) { + $('#preview-submit').once('edit-displays-live-preview').trigger('click'); + } + }, + }; + + /** + * Rearranges the filters. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attach handlers to make it possible to rearange the filters in the form + * in question. + * @see Drupal.viewsUi.RearrangeFilterHandler + */ + Drupal.behaviors.viewsUiRearrangeFilter = { + attach(context) { + // Only act on the rearrange filter form. + if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag['views-rearrange-filters'] === 'undefined') { + return; + } + const $context = $(context); + const $table = $context.find('#views-rearrange-filters').once('views-rearrange-filters'); + const $operator = $context.find('.js-form-item-filter-groups-operator').once('views-rearrange-filters'); + if ($table.length) { + new Drupal.viewsUi.RearrangeFilterHandler($table, $operator); + } + }, + }; + + /** + * Improve the UI of the rearrange filters dialog box. + * + * @constructor + * + * @param {jQuery} $table + * The table in the filter form. + * @param {jQuery} $operator + * The filter groups operator element. + */ + Drupal.viewsUi.RearrangeFilterHandler = function ($table, $operator) { + /** + * Keep a reference to the `<table>` being altered and to the div containing + * the filter groups operator dropdown (if it exists). + */ + this.table = $table; + + /** + * + * @type {jQuery} + */ + this.operator = $operator; + + /** + * + * @type {bool} + */ + this.hasGroupOperator = this.operator.length > 0; + + /** + * Keep a reference to all draggable rows within the table. + * + * @type {jQuery} + */ + this.draggableRows = $table.find('.draggable'); + + /** + * Keep a reference to the buttons for adding and removing filter groups. + * + * @type {jQuery} + */ + this.addGroupButton = $('input#views-add-group'); + + /** + * @type {jQuery} + */ + this.removeGroupButtons = $table.find('input.views-remove-group'); + + // Add links that duplicate the functionality of the (hidden) add and remove + // buttons. + this.insertAddRemoveFilterGroupLinks(); + + // When there is a filter groups operator dropdown on the page, create + // duplicates of the dropdown between each pair of filter groups. + if (this.hasGroupOperator) { + /** + * @type {jQuery} + */ + this.dropdowns = this.duplicateGroupsOperator(); + this.syncGroupsOperators(); + } + + // Add methods to the tableDrag instance to account for operator cells + // (which span multiple rows), the operator labels next to each filter + // (e.g., "And" or "Or"), the filter groups, and other special aspects of + // this tableDrag instance. + this.modifyTableDrag(); + + // Initialize the operator labels (e.g., "And" or "Or") that are displayed + // next to the filters in each group, and bind a handler so that they change + // based on the values of the operator dropdown within that group. + this.redrawOperatorLabels(); + $table.find('.views-group-title select') + .once('views-rearrange-filter-handler') + .on('change.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); + + // Bind handlers so that when a "Remove" link is clicked, we: + // - Update the rowspans of cells containing an operator dropdown (since + // they need to change to reflect the number of rows in each group). + // - Redraw the operator labels next to the filters in the group (since the + // filter that is currently displayed last in each group is not supposed + // to have a label display next to it). + $table.find('a.views-groups-remove-link') + .once('views-rearrange-filter-handler') + .on('click.views-rearrange-filter-handler', $.proxy(this, 'updateRowspans')) + .on('click.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); + }; + + $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, /** @lends Drupal.viewsUi.RearrangeFilterHandler# */{ + + /** + * Insert links that allow filter groups to be added and removed. + */ + insertAddRemoveFilterGroupLinks() { + // Insert a link for adding a new group at the top of the page, and make + // it match the action link styling used in a typical page.html.twig. + // Since Drupal does not provide a theme function for this markup this is + // the best we can do. + $(`<ul class="action-links"><li><a id="views-add-group-link" href="#">${this.addGroupButton.val()}</a></li></ul>`) + .prependTo(this.table.parent()) + // When the link is clicked, dynamically click the hidden form button + // for adding a new filter group. + .once('views-rearrange-filter-handler') + .find('#views-add-group-link') + .on('click.views-rearrange-filter-handler', $.proxy(this, 'clickAddGroupButton')); + + // Find each (visually hidden) button for removing a filter group and + // insert a link next to it. + const length = this.removeGroupButtons.length; + let i; + for (i = 0; i < length; i++) { + const $removeGroupButton = $(this.removeGroupButtons[i]); + const buttonId = $removeGroupButton.attr('id'); + $(`<a href="#" class="views-remove-group-link">${Drupal.t('Remove group')}</a>`) + .insertBefore($removeGroupButton) + // When the link is clicked, dynamically click the corresponding form + // button. + .once('views-rearrange-filter-handler') + .on('click.views-rearrange-filter-handler', { buttonId }, $.proxy(this, 'clickRemoveGroupButton')); + } + }, + + /** + * Dynamically click the button that adds a new filter group. + * + * @param {jQuery.Event} event + * The event triggered. + */ + clickAddGroupButton(event) { + this.addGroupButton.trigger('mousedown'); + event.preventDefault(); + }, + + /** + * Dynamically click a button for removing a filter group. + * + * @param {jQuery.Event} event + * Event being triggered, with event.data.buttonId set to the ID of the + * form button that should be clicked. + */ + clickRemoveGroupButton(event) { + this.table.find(`#${event.data.buttonId}`).trigger('mousedown'); + event.preventDefault(); + }, + + /** + * Move the groups operator so that it's between the first two groups, and + * duplicate it between any subsequent groups. + * + * @return {jQuery} + * An operator element. + */ + duplicateGroupsOperator() { + let dropdowns; + let newRow; + let titleRow; + + const titleRows = $('tr.views-group-title').once('duplicateGroupsOperator'); + + if (!titleRows.length) { + return this.operator; + } + + // Get rid of the explanatory text around the operator; its placement is + // explanatory enough. + this.operator.find('label').add('div.description').addClass('visually-hidden'); + this.operator.find('select').addClass('form-select'); + + // Keep a list of the operator dropdowns, so we can sync their behavior + // later. + dropdowns = this.operator; + + // Move the operator to a new row just above the second group. + titleRow = $('tr#views-group-title-2'); + newRow = $('<tr class="filter-group-operator-row"><td colspan="5"></td></tr>'); + newRow.find('td').append(this.operator); + newRow.insertBefore(titleRow); + const length = titleRows.length; + // Starting with the third group, copy the operator to a new row above the + // group title. + for (let i = 2; i < length; i++) { + titleRow = $(titleRows[i]); + // Make a copy of the operator dropdown and put it in a new table row. + const fakeOperator = this.operator.clone(); + fakeOperator.attr('id', ''); + newRow = $('<tr class="filter-group-operator-row"><td colspan="5"></td></tr>'); + newRow.find('td').append(fakeOperator); + newRow.insertBefore(titleRow); + dropdowns.add(fakeOperator); + } + + return dropdowns; + }, + + /** + * Make the duplicated groups operators change in sync with each other. + */ + syncGroupsOperators() { + if (this.dropdowns.length < 2) { + // We only have one dropdown (or none at all), so there's nothing to + // sync. + return; + } + + this.dropdowns.on('change', $.proxy(this, 'operatorChangeHandler')); + }, + + /** + * Click handler for the operators that appear between filter groups. + * + * Forces all operator dropdowns to have the same value. + * + * @param {jQuery.Event} event + * The event triggered. + */ + operatorChangeHandler(event) { + const $target = $(event.target); + const operators = this.dropdowns.find('select').not($target); + + // Change the other operators to match this new value. + operators.val($target.val()); + }, + + /** + * @method + */ + modifyTableDrag() { + const tableDrag = Drupal.tableDrag['views-rearrange-filters']; + const filterHandler = this; + + /** + * Override the row.onSwap method from tabledrag.js. + * + * When a row is dragged to another place in the table, several things + * need to occur. + * - The row needs to be moved so that it's within one of the filter + * groups. + * - The operator cells that span multiple rows need their rowspan + * attributes updated to reflect the number of rows in each group. + * - The operator labels that are displayed next to each filter need to + * be redrawn, to account for the row's new location. + */ + tableDrag.row.prototype.onSwap = function () { + if (filterHandler.hasGroupOperator) { + // Make sure the row that just got moved (this.group) is inside one + // of the filter groups (i.e. below an empty marker row or a + // draggable). If it isn't, move it down one. + const thisRow = $(this.group); + const previousRow = thisRow.prev('tr'); + if (previousRow.length && !previousRow.hasClass('group-message') && !previousRow.hasClass('draggable')) { + // Move the dragged row down one. + const next = thisRow.next(); + if (next.is('tr')) { + this.swap('after', next); + } + } + filterHandler.updateRowspans(); + } + // Redraw the operator labels that are displayed next to each filter, to + // account for the row's new location. + filterHandler.redrawOperatorLabels(); + }; + + /** + * Override the onDrop method from tabledrag.js. + */ + tableDrag.onDrop = function () { + // If the tabledrag change marker (i.e., the "*") has been inserted + // inside a row after the operator label (i.e., "And" or "Or") + // rearrange the items so the operator label continues to appear last. + const changeMarker = $(this.oldRowElement).find('.tabledrag-changed'); + if (changeMarker.length) { + // Search for occurrences of the operator label before the change + // marker, and reverse them. + const operatorLabel = changeMarker.prevAll('.views-operator-label'); + if (operatorLabel.length) { + operatorLabel.insertAfter(changeMarker); + } + } + + // Make sure the "group" dropdown is properly updated when rows are + // dragged into an empty filter group. This is borrowed heavily from + // the block.js implementation of tableDrag.onDrop(). + const groupRow = $(this.rowObject.element).prevAll('tr.group-message').get(0); + const groupName = groupRow.className.replace(/([^ ]+[ ]+)*group-([^ ]+)-message([ ]+[^ ]+)*/, '$2'); + const groupField = $('select.views-group-select', this.rowObject.element); + if ($(this.rowObject.element).prev('tr').is('.group-message') && !groupField.is(`.views-group-select-${groupName}`)) { + const oldGroupName = groupField.attr('class').replace(/([^ ]+[ ]+)*views-group-select-([^ ]+)([ ]+[^ ]+)*/, '$2'); + groupField.removeClass(`views-group-select-${oldGroupName}`).addClass(`views-group-select-${groupName}`); + groupField.val(groupName); + } + }; + }, + + /** + * Redraw the operator labels that are displayed next to each filter. + */ + redrawOperatorLabels() { + for (let i = 0; i < this.draggableRows.length; i++) { + // Within the row, the operator labels are displayed inside the first + // table cell (next to the filter name). + const $draggableRow = $(this.draggableRows[i]); + const $firstCell = $draggableRow.find('td').eq(0); + if ($firstCell.length) { + // The value of the operator label ("And" or "Or") is taken from the + // first operator dropdown we encounter, going backwards from the + // current row. This dropdown is the one associated with the current + // row's filter group. + const operatorValue = $draggableRow.prevAll('.views-group-title').find('option:selected').html(); + const operatorLabel = `<span class="views-operator-label">${operatorValue}</span>`; + // If the next visible row after this one is a draggable filter row, + // display the operator label next to the current row. (Checking for + // visibility is necessary here since the "Remove" links hide the + // removed row but don't actually remove it from the document). + const $nextRow = $draggableRow.nextAll(':visible').eq(0); + const $existingOperatorLabel = $firstCell.find('.views-operator-label'); + if ($nextRow.hasClass('draggable')) { + // If an operator label was already there, replace it with the new + // one. + if ($existingOperatorLabel.length) { + $existingOperatorLabel.replaceWith(operatorLabel); + } + // Otherwise, append the operator label to the end of the table + // cell. + else { + $firstCell.append(operatorLabel); + } + } + // If the next row doesn't contain a filter, then this is the last row + // in the group. We don't want to display the operator there (since + // operators should only display between two related filters, e.g. + // "filter1 AND filter2 AND filter3"). So we remove any existing label + // that this row has. + else { + $existingOperatorLabel.remove(); + } + } + } + }, + + /** + * Update the rowspan attribute of each cell containing an operator + * dropdown. + */ + updateRowspans() { + let $row; + let $currentEmptyRow; + let draggableCount; + let $operatorCell; + const rows = $(this.table).find('tr'); + const length = rows.length; + for (let i = 0; i < length; i++) { + $row = $(rows[i]); + if ($row.hasClass('views-group-title')) { + // This row is a title row. + // Keep a reference to the cell containing the dropdown operator. + $operatorCell = $row.find('td.group-operator'); + // Assume this filter group is empty, until we find otherwise. + draggableCount = 0; + $currentEmptyRow = $row.next('tr'); + $currentEmptyRow.removeClass('group-populated').addClass('group-empty'); + // The cell with the dropdown operator should span the title row and + // the "this group is empty" row. + $operatorCell.attr('rowspan', 2); + } + else if ($row.hasClass('draggable') && $row.is(':visible')) { + // We've found a visible filter row, so we now know the group isn't + // empty. + draggableCount++; + $currentEmptyRow.removeClass('group-empty').addClass('group-populated'); + // The operator cell should span all draggable rows, plus the title. + $operatorCell.attr('rowspan', draggableCount + 1); + } + } + }, + }); + + /** + * Add a select all checkbox, which checks each checkbox at once. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches select all functionality to the views filter form. + */ + Drupal.behaviors.viewsFilterConfigSelectAll = { + attach(context) { + const $context = $(context); + + const $selectAll = $context.find('.js-form-item-options-value-all').once('filterConfigSelectAll'); + const $selectAllCheckbox = $selectAll.find('input[type=checkbox]'); + const $checkboxes = $selectAll.closest('.form-checkboxes').find('.js-form-type-checkbox:not(.js-form-item-options-value-all) input[type="checkbox"]'); + + if ($selectAll.length) { + // Show the select all checkbox. + $selectAll.show(); + $selectAllCheckbox.on('click', function () { + // Update all checkbox beside the select all checkbox. + $checkboxes.prop('checked', $(this).is(':checked')); + }); + + // Uncheck the select all checkbox if any of the others are unchecked. + $checkboxes.on('click', function () { + if ($(this).is('checked') === false) { + $selectAllCheckbox.prop('checked', false); + } + }); + } + }, + }; + + /** + * Remove icon class from elements that are themed as buttons or dropbuttons. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Removes the icon class from certain views elements. + */ + Drupal.behaviors.viewsRemoveIconClass = { + attach(context) { + $(context).find('.dropbutton').once('dropbutton-icon').find('.icon').removeClass('icon'); + }, + }; + + /** + * Change "Expose filter" buttons into checkboxes. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Changes buttons into checkboxes via {@link Drupal.viewsUi.Checkboxifier}. + */ + Drupal.behaviors.viewsUiCheckboxify = { + attach(context, settings) { + const $buttons = $('[data-drupal-selector="edit-options-expose-button-button"], [data-drupal-selector="edit-options-group-button-button"]').once('views-ui-checkboxify'); + const length = $buttons.length; + let i; + for (i = 0; i < length; i++) { + new Drupal.viewsUi.Checkboxifier($buttons[i]); + } + }, + }; + + /** + * Change the default widget to select the default group according to the + * selected widget for the exposed group. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Changes the default widget based on user input. + */ + Drupal.behaviors.viewsUiChangeDefaultWidget = { + attach(context) { + const $context = $(context); + + function changeDefaultWidget(event) { + if ($(event.target).prop('checked')) { + $context.find('input.default-radios').parent().hide(); + $context.find('td.any-default-radios-row').parent().hide(); + $context.find('input.default-checkboxes').parent().show(); + } + else { + $context.find('input.default-checkboxes').parent().hide(); + $context.find('td.any-default-radios-row').parent().show(); + $context.find('input.default-radios').parent().show(); + } + } + + // Update on widget change. + $context.find('input[name="options[group_info][multiple]"]') + .on('change', changeDefaultWidget) + // Update the first time the form is rendered. + .trigger('change'); + }, + }; + + /** + * Attaches expose filter button to a checkbox that triggers its click event. + * + * @constructor + * + * @param {HTMLElement} button + * The DOM object representing the button to be checkboxified. + */ + Drupal.viewsUi.Checkboxifier = function (button) { + this.$button = $(button); + this.$parent = this.$button.parent('div.views-expose, div.views-grouped'); + this.$input = this.$parent.find('input:checkbox, input:radio'); + // Hide the button and its description. + this.$button.hide(); + this.$parent.find('.exposed-description, .grouped-description').hide(); + + this.$input.on('click', $.proxy(this, 'clickHandler')); + }; + + /** + * When the checkbox is checked or unchecked, simulate a button press. + * + * @param {jQuery.Event} e + * The event triggered. + */ + Drupal.viewsUi.Checkboxifier.prototype.clickHandler = function (e) { + this.$button + .trigger('click') + .trigger('submit'); + }; + + /** + * Change the Apply button text based upon the override select state. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches behavior to change the Apply button according to the current + * state. + */ + Drupal.behaviors.viewsUiOverrideSelect = { + attach(context) { + $(context).find('[data-drupal-selector="edit-override-dropdown"]').once('views-ui-override-button-text').each(function () { + // Closures! :( + const $context = $(context); + const $submit = $context.find('[id^=edit-submit]'); + const old_value = $submit.val(); + + $submit.once('views-ui-override-button-text') + .on('mouseup', function () { + $(this).val(old_value); + return true; + }); + + $(this).on('change', function () { + const $this = $(this); + if ($this.val() === 'default') { + $submit.val(Drupal.t('Apply (all displays)')); + } + else if ($this.val() === 'default_revert') { + $submit.val(Drupal.t('Revert to default')); + } + else { + $submit.val(Drupal.t('Apply (this display)')); + } + const $dialog = $context.closest('.ui-dialog-content'); + $dialog.trigger('dialogButtonsChange'); + }) + .trigger('change'); + }); + }, + }; + + /** + * Functionality for the remove link in the views UI. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches behavior for the remove view and remove display links. + */ + Drupal.behaviors.viewsUiHandlerRemoveLink = { + attach(context) { + const $context = $(context); + // Handle handler deletion by looking for the hidden checkbox and hiding + // the row. + $context.find('a.views-remove-link').once('views').on('click', function (event) { + const id = $(this).attr('id').replace('views-remove-link-', ''); + $context.find(`#views-row-${id}`).hide(); + $context.find(`#views-removed-${id}`).prop('checked', true); + event.preventDefault(); + }); + + // Handle display deletion by looking for the hidden checkbox and hiding + // the row. + $context.find('a.display-remove-link').once('display').on('click', function (event) { + const id = $(this).attr('id').replace('display-remove-link-', ''); + $context.find(`#display-row-${id}`).hide(); + $context.find(`#display-removed-${id}`).prop('checked', true); + event.preventDefault(); + }); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/views_ui/js/views-admin.js b/core/modules/views_ui/js/views-admin.js index 761185ed..10fa4307 100644 --- a/core/modules/views_ui/js/views-admin.js +++ b/core/modules/views_ui/js/views-admin.js @@ -1,306 +1,150 @@ /** - * @file - * Some basic behaviors and utility functions for Views UI. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * @namespace - */ Drupal.viewsUi = {}; - /** - * Improve the user experience of the views edit interface. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches toggling of SQL rewrite warning on the corresponding checkbox. - */ Drupal.behaviors.viewsUiEditView = { - attach: function () { - // Only show the SQL rewrite warning when the user has chosen the - // corresponding checkbox. + attach: function attach() { $('[data-drupal-selector="edit-query-options-disable-sql-rewrite"]').on('click', function () { $('.sql-rewrite-warning').toggleClass('js-hide'); }); } }; - /** - * In the add view wizard, use the view name to prepopulate form fields such - * as page title and menu link. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches behavior for prepopulating page title and menu links, based on - * view name. - */ Drupal.behaviors.viewsUiAddView = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); - // Set up regular expressions to allow only numbers, letters, and dashes. + var exclude = new RegExp('[^a-z0-9\\-]+', 'g'); var replace = '-'; - var suffix; + var suffix = void 0; - // The page title, block title, and menu link fields can all be - // prepopulated with the view name - no regular expression needed. var $fields = $context.find('[id^="edit-page-title"], [id^="edit-block-title"], [id^="edit-page-link-properties-title"]'); if ($fields.length) { if (!this.fieldsFiller) { this.fieldsFiller = new Drupal.viewsUi.FormFieldFiller($fields); - } - else { - // After an AJAX response, this.fieldsFiller will still have event - // handlers bound to the old version of the form fields (which don't - // exist anymore). The event handlers need to be unbound and then - // rebound to the new markup. Note that jQuery.live is difficult to - // make work in this case because the IDs of the form fields change - // on every AJAX response. + } else { this.fieldsFiller.rebind($fields); } } - // Prepopulate the path field with a URLified version of the view name. var $pathField = $context.find('[id^="edit-page-path"]'); if ($pathField.length) { if (!this.pathFiller) { this.pathFiller = new Drupal.viewsUi.FormFieldFiller($pathField, exclude, replace); - } - else { + } else { this.pathFiller.rebind($pathField); } } - // Populate the RSS feed field with a URLified version of the view name, - // and an .xml suffix (to make it unique). var $feedField = $context.find('[id^="edit-page-feed-properties-path"]'); if ($feedField.length) { if (!this.feedFiller) { suffix = '.xml'; this.feedFiller = new Drupal.viewsUi.FormFieldFiller($feedField, exclude, replace, suffix); - } - else { + } else { this.feedFiller.rebind($feedField); } } } }; - /** - * Constructor for the {@link Drupal.viewsUi.FormFieldFiller} object. - * - * Prepopulates a form field based on the view name. - * - * @constructor - * - * @param {jQuery} $target - * A jQuery object representing the form field or fields to prepopulate. - * @param {bool} [exclude=false] - * A regular expression representing characters to exclude from - * the target field. - * @param {string} [replace=''] - * A string to use as the replacement value for disallowed characters. - * @param {string} [suffix=''] - * A suffix to append at the end of the target field content. - */ Drupal.viewsUi.FormFieldFiller = function ($target, exclude, replace, suffix) { - - /** - * - * @type {jQuery} - */ this.source = $('#edit-label'); - /** - * - * @type {jQuery} - */ this.target = $target; - /** - * - * @type {bool} - */ this.exclude = exclude || false; - /** - * - * @type {string} - */ this.replace = replace || ''; - /** - * - * @type {string} - */ this.suffix = suffix || ''; - // Create bound versions of this instance's object methods to use as event - // handlers. This will let us easily unbind those specific handlers later - // on. NOTE: jQuery.proxy will not work for this because it assumes we want - // only one bound version of an object method, whereas we need one version - // per object instance. var self = this; - /** - * Populate the target form field with the altered source field value. - * - * @return {*} - * The result of the _populate call, which should be undefined. - */ - this.populate = function () { return self._populate.call(self); }; - - /** - * Stop prepopulating the form fields. - * - * @return {*} - * The result of the _unbind call, which should be undefined. - */ - this.unbind = function () { return self._unbind.call(self); }; + this.populate = function () { + return self._populate.call(self); + }; + + this.unbind = function () { + return self._unbind.call(self); + }; this.bind(); - // Object constructor; no return value. }; - $.extend(Drupal.viewsUi.FormFieldFiller.prototype, /** @lends Drupal.viewsUi.FormFieldFiller# */{ - - /** - * Bind the form-filling behavior. - */ - bind: function () { + $.extend(Drupal.viewsUi.FormFieldFiller.prototype, { + bind: function bind() { this.unbind(); - // Populate the form field when the source changes. + this.source.on('keyup.viewsUi change.viewsUi', this.populate); - // Quit populating the field as soon as it gets focus. + this.target.on('focus.viewsUi', this.unbind); }, - - /** - * Get the source form field value as altered by the passed-in parameters. - * - * @return {string} - * The source form field value. - */ - getTransliterated: function () { + getTransliterated: function getTransliterated() { var from = this.source.val(); if (this.exclude) { from = from.toLowerCase().replace(this.exclude, this.replace); } return from; }, - - /** - * Populate the target form field with the altered source field value. - */ - _populate: function () { + _populate: function _populate() { var transliterated = this.getTransliterated(); var suffix = this.suffix; this.target.each(function (i) { - // Ensure that the maxlength is not exceeded by prepopulating the field. var maxlength = $(this).attr('maxlength') - suffix.length; $(this).val(transliterated.substr(0, maxlength) + suffix); }); }, - - /** - * Stop prepopulating the form fields. - */ - _unbind: function () { + _unbind: function _unbind() { this.source.off('keyup.viewsUi change.viewsUi', this.populate); this.target.off('focus.viewsUi', this.unbind); }, - - /** - * Bind event handlers to new form fields, after they're replaced via Ajax. - * - * @param {jQuery} $fields - * Fields to rebind functionality to. - */ - rebind: function ($fields) { + rebind: function rebind($fields) { this.target = $fields; this.bind(); } }); - /** - * Adds functionality for the add item form. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the functionality in {@link Drupal.viewsUi.AddItemForm} to the - * forms in question. - */ Drupal.behaviors.addItemForm = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); var $form = $context; - // The add handler form may have an id of views-ui-add-handler-form--n. + if (!$context.is('form[id^="views-ui-add-handler-form"]')) { $form = $context.find('form[id^="views-ui-add-handler-form"]'); } if ($form.once('views-ui-add-handler-form').length) { - // If we we have an unprocessed views-ui-add-handler-form, let's - // instantiate. new Drupal.viewsUi.AddItemForm($form); } } }; - /** - * Constructs a new AddItemForm. - * - * @constructor - * - * @param {jQuery} $form - * The form element used. - */ Drupal.viewsUi.AddItemForm = function ($form) { - - /** - * - * @type {jQuery} - */ this.$form = $form; this.$form.find('.views-filterable-options :checkbox').on('click', $.proxy(this.handleCheck, this)); - /** - * Find the wrapper of the displayed text. - */ this.$selected_div = this.$form.find('.views-selected-options').parent(); this.$selected_div.hide(); - /** - * - * @type {Array} - */ this.checkedItems = []; }; - /** - * Handles a checkbox check. - * - * @param {jQuery.Event} event - * The event triggered. - */ Drupal.viewsUi.AddItemForm.prototype.handleCheck = function (event) { var $target = $(event.target); var label = $.trim($target.closest('td').next().html()); - // Add/remove the checked item to the list. + if ($target.is(':checked')) { this.$selected_div.show().css('display', 'block'); this.checkedItems.push(label); - } - else { + } else { var position = $.inArray(label, this.checkedItems); - // Delete the item from the list and make sure that the list doesn't have - // undefined items left. + for (var i = 0; i < this.checkedItems.length; i++) { if (i === position) { this.checkedItems.splice(i, 1); @@ -308,7 +152,7 @@ break; } } - // Hide it again if none item is selected. + if (this.checkedItems.length === 0) { this.$selected_div.hide(); } @@ -316,30 +160,12 @@ this.refreshCheckedItems(); }; - /** - * Refresh the display of the checked items. - */ Drupal.viewsUi.AddItemForm.prototype.refreshCheckedItems = function () { - // Perhaps we should precache the text div, too. - this.$selected_div.find('.views-selected-options') - .html(this.checkedItems.join(', ')) - .trigger('dialogContentResize'); + this.$selected_div.find('.views-selected-options').html(this.checkedItems.join(', ')).trigger('dialogContentResize'); }; - /** - * The input field items that add displays must be rendered as `<input>` - * elements. The following behavior detaches the `<input>` elements from the - * DOM, wraps them in an unordered list, then appends them to the list of - * tabs. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Fixes the input elements needed. - */ Drupal.behaviors.viewsUiRenderAddViewButton = { - attach: function (context) { - // Build the add display menu and pull the display input buttons into it. + attach: function attach(context) { var $menu = $(context).find('#views-display-menu-tabs').once('views-ui-render-add-view-button'); if (!$menu.length) { return; @@ -347,11 +173,8 @@ var $addDisplayDropdown = $('<li class="add"><a href="#"><span class="icon add"></span>' + Drupal.t('Add') + '</a><ul class="action-list" style="display:none;"></ul></li>'); var $displayButtons = $menu.nextAll('input.add-display').detach(); - $displayButtons.appendTo($addDisplayDropdown.find('.action-list')).wrap('<li>') - .parent().eq(0).addClass('first').end().eq(-1).addClass('last'); - // Remove the 'Add ' prefix from the button labels since they're being - // placed in an 'Add' dropdown. @todo This assumes English, but so does - // $addDisplayDropdown above. Add support for translation. + $displayButtons.appendTo($addDisplayDropdown.find('.action-list')).wrap('<li>').parent().eq(0).addClass('first').end().eq(-1).addClass('last'); + $displayButtons.each(function () { var label = $(this).val(); if (label.substr(0, 4) === 'Add ') { @@ -360,19 +183,12 @@ }); $addDisplayDropdown.appendTo($menu); - // Add the click handler for the add display button. $menu.find('li.add > a').on('click', function (event) { event.preventDefault(); var $trigger = $(this); Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu($trigger); }); - // Add a mouseleave handler to close the dropdown when the user mouses - // away from the item. We use mouseleave instead of mouseout because - // the user is going to trigger mouseout when she moves from the trigger - // link to the sub menu items. - // We use the live binder because the open class on this item will be - // toggled on and off and we want the handler to take effect in the cases - // that the class is present, but not when it isn't. + $('li.add', $menu).on('mouseleave', function (event) { var $this = $(this); var $trigger = $this.children('a[href="#"]'); @@ -383,67 +199,29 @@ } }; - /** - * Toggle menu visibility. - * - * @param {jQuery} $trigger - * The element where the toggle was triggered. - * - * - * @note [@jessebeach] I feel like the following should be a more generic - * function and not written specifically for this UI, but I'm not sure - * where to put it. - */ Drupal.behaviors.viewsUiRenderAddViewButton.toggleMenu = function ($trigger) { $trigger.parent().toggleClass('open'); $trigger.next().slideToggle('fast'); }; - /** - * Add search options to the views ui. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches {@link Drupal.viewsUi.OptionsSearch} to the views ui filter - * options. - */ Drupal.behaviors.viewsUiSearchOptions = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); var $form = $context; - // The add handler form may have an id of views-ui-add-handler-form--n. + if (!$context.is('form[id^="views-ui-add-handler-form"]')) { $form = $context.find('form[id^="views-ui-add-handler-form"]'); } - // Make sure we don't add more than one event handler to the same form. + if ($form.once('views-ui-filter-options').length) { new Drupal.viewsUi.OptionsSearch($form); } } }; - /** - * Constructor for the viewsUi.OptionsSearch object. - * - * The OptionsSearch object filters the available options on a form according - * to the user's search term. Typing in "taxonomy" will show only those - * options containing "taxonomy" in their label. - * - * @constructor - * - * @param {jQuery} $form - * The form element. - */ Drupal.viewsUi.OptionsSearch = function ($form) { - - /** - * - * @type {jQuery} - */ this.$form = $form; - // Click on the title checks the box. this.$form.on('click', 'td.title', function (event) { var $target = $(event.currentTarget); $target.closest('tr').find('input').trigger('click'); @@ -456,13 +234,8 @@ this.$searchBox = this.$form.find(searchBoxSelector); this.$controlGroup = this.$form.find(controlGroupSelector); - /** - * Get a list of option labels and their corresponding divs and maintain it - * in memory, so we have as little overhead as possible at keyup time. - */ this.options = this.getOptions(this.$form.find('.filterable-option')); - // Trap the ENTER key in the search box so that it doesn't submit the form. this.$searchBox.on('keypress', function (event) { if (event.which === 13) { event.preventDefault(); @@ -470,64 +243,38 @@ }); }; - $.extend(Drupal.viewsUi.OptionsSearch.prototype, /** @lends Drupal.viewsUi.OptionsSearch# */{ - - /** - * Assemble a list of all the filterable options on the form. - * - * @param {jQuery} $allOptions - * A jQuery object representing the rows of filterable options to be - * shown and hidden depending on the user's search terms. - * - * @return {Array} - * An array of all the filterable options. - */ - getOptions: function ($allOptions) { - var $label; - var $description; - var $option; + $.extend(Drupal.viewsUi.OptionsSearch.prototype, { + getOptions: function getOptions($allOptions) { + var $title = void 0; + var $description = void 0; + var $option = void 0; var options = []; var length = $allOptions.length; for (var i = 0; i < length; i++) { $option = $($allOptions[i]); - $label = $option.find('label'); + $title = $option.find('.title'); $description = $option.find('.description'); options[i] = { - // Search on the lowercase version of the label text + description. - searchText: $label.text().toLowerCase() + ' ' + $description.text().toLowerCase(), - // Maintain a reference to the jQuery object for each row, so we don't - // have to create a new object inside the performance-sensitive keyup - // handler. + searchText: $title.text().toLowerCase() + ' ' + $description.text().toLowerCase(), + $div: $option }; } return options; }, - - /** - * Filter handler for the search box and type select that hides or shows the relevant - * options. - * - * @param {jQuery.Event} event - * The formUpdated event. - */ - handleFilter: function (event) { - // Determine the user's search query. The search text has been converted - // to lowercase. + handleFilter: function handleFilter(event) { var search = this.$searchBox.val().toLowerCase(); var words = search.split(' '); - // Get selected Group + var group = this.$controlGroup.val(); - // Search through the search texts in the form for matching text. this.options.forEach(function (option) { function hasWord(word) { return option.searchText.indexOf(word) !== -1; } var found = true; - // Each word in the search string has to match the item in order for the - // item to be shown. + if (search) { found = words.every(hasWord); } @@ -538,58 +285,32 @@ option.$div.toggle(found); }); - // Adapt dialog to content size. $(event.target).trigger('dialogContentResize'); } }); - /** - * Preview functionality in the views edit form. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the preview functionality to the view edit form. - */ Drupal.behaviors.viewsUiPreview = { - attach: function (context) { - // Only act on the edit view form. + attach: function attach(context) { var $contextualFiltersBucket = $(context).find('.views-display-column .views-ui-display-tab-bucket.argument'); if ($contextualFiltersBucket.length === 0) { return; } - // If the display has no contextual filters, hide the form where you - // enter the contextual filters for the live preview. If it has contextual - // filters, show the form. var $contextualFilters = $contextualFiltersBucket.find('.views-display-setting a'); if ($contextualFilters.length) { $('#preview-args').parent().show(); - } - else { + } else { $('#preview-args').parent().hide(); } - // Executes an initial preview. if ($('#edit-displays-live-preview').once('edit-displays-live-preview').is(':checked')) { $('#preview-submit').once('edit-displays-live-preview').trigger('click'); } } }; - /** - * Rearranges the filters. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attach handlers to make it possible to rearange the filters in the form - * in question. - * @see Drupal.viewsUi.RearrangeFilterHandler - */ Drupal.behaviors.viewsUiRearrangeFilter = { - attach: function (context) { - // Only act on the rearrange filter form. + attach: function attach(context) { if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag['views-rearrange-filters'] === 'undefined') { return; } @@ -602,164 +323,58 @@ } }; - /** - * Improve the UI of the rearrange filters dialog box. - * - * @constructor - * - * @param {jQuery} $table - * The table in the filter form. - * @param {jQuery} $operator - * The filter groups operator element. - */ Drupal.viewsUi.RearrangeFilterHandler = function ($table, $operator) { - - /** - * Keep a reference to the `<table>` being altered and to the div containing - * the filter groups operator dropdown (if it exists). - */ this.table = $table; - /** - * - * @type {jQuery} - */ this.operator = $operator; - /** - * - * @type {bool} - */ this.hasGroupOperator = this.operator.length > 0; - /** - * Keep a reference to all draggable rows within the table. - * - * @type {jQuery} - */ this.draggableRows = $table.find('.draggable'); - /** - * Keep a reference to the buttons for adding and removing filter groups. - * - * @type {jQuery} - */ this.addGroupButton = $('input#views-add-group'); - /** - * @type {jQuery} - */ this.removeGroupButtons = $table.find('input.views-remove-group'); - // Add links that duplicate the functionality of the (hidden) add and remove - // buttons. this.insertAddRemoveFilterGroupLinks(); - // When there is a filter groups operator dropdown on the page, create - // duplicates of the dropdown between each pair of filter groups. if (this.hasGroupOperator) { - - /** - * @type {jQuery} - */ this.dropdowns = this.duplicateGroupsOperator(); this.syncGroupsOperators(); } - // Add methods to the tableDrag instance to account for operator cells - // (which span multiple rows), the operator labels next to each filter - // (e.g., "And" or "Or"), the filter groups, and other special aspects of - // this tableDrag instance. this.modifyTableDrag(); - // Initialize the operator labels (e.g., "And" or "Or") that are displayed - // next to the filters in each group, and bind a handler so that they change - // based on the values of the operator dropdown within that group. this.redrawOperatorLabels(); - $table.find('.views-group-title select') - .once('views-rearrange-filter-handler') - .on('change.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); - - // Bind handlers so that when a "Remove" link is clicked, we: - // - Update the rowspans of cells containing an operator dropdown (since - // they need to change to reflect the number of rows in each group). - // - Redraw the operator labels next to the filters in the group (since the - // filter that is currently displayed last in each group is not supposed - // to have a label display next to it). - $table.find('a.views-groups-remove-link') - .once('views-rearrange-filter-handler') - .on('click.views-rearrange-filter-handler', $.proxy(this, 'updateRowspans')) - .on('click.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); + $table.find('.views-group-title select').once('views-rearrange-filter-handler').on('change.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); + + $table.find('a.views-groups-remove-link').once('views-rearrange-filter-handler').on('click.views-rearrange-filter-handler', $.proxy(this, 'updateRowspans')).on('click.views-rearrange-filter-handler', $.proxy(this, 'redrawOperatorLabels')); }; - $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, /** @lends Drupal.viewsUi.RearrangeFilterHandler# */{ - - /** - * Insert links that allow filter groups to be added and removed. - */ - insertAddRemoveFilterGroupLinks: function () { - - // Insert a link for adding a new group at the top of the page, and make - // it match the action link styling used in a typical page.html.twig. - // Since Drupal does not provide a theme function for this markup this is - // the best we can do. - $('<ul class="action-links"><li><a id="views-add-group-link" href="#">' + this.addGroupButton.val() + '</a></li></ul>') - .prependTo(this.table.parent()) - // When the link is clicked, dynamically click the hidden form button - // for adding a new filter group. - .once('views-rearrange-filter-handler') - .on('click.views-rearrange-filter-handler', $.proxy(this, 'clickAddGroupButton')); - - // Find each (visually hidden) button for removing a filter group and - // insert a link next to it. + $.extend(Drupal.viewsUi.RearrangeFilterHandler.prototype, { + insertAddRemoveFilterGroupLinks: function insertAddRemoveFilterGroupLinks() { + $('<ul class="action-links"><li><a id="views-add-group-link" href="#">' + this.addGroupButton.val() + '</a></li></ul>').prependTo(this.table.parent()).once('views-rearrange-filter-handler').find('#views-add-group-link').on('click.views-rearrange-filter-handler', $.proxy(this, 'clickAddGroupButton')); + var length = this.removeGroupButtons.length; - var i; + var i = void 0; for (i = 0; i < length; i++) { var $removeGroupButton = $(this.removeGroupButtons[i]); var buttonId = $removeGroupButton.attr('id'); - $('<a href="#" class="views-remove-group-link">' + Drupal.t('Remove group') + '</a>') - .insertBefore($removeGroupButton) - // When the link is clicked, dynamically click the corresponding form - // button. - .once('views-rearrange-filter-handler') - .on('click.views-rearrange-filter-handler', {buttonId: buttonId}, $.proxy(this, 'clickRemoveGroupButton')); + $('<a href="#" class="views-remove-group-link">' + Drupal.t('Remove group') + '</a>').insertBefore($removeGroupButton).once('views-rearrange-filter-handler').on('click.views-rearrange-filter-handler', { buttonId: buttonId }, $.proxy(this, 'clickRemoveGroupButton')); } }, - - /** - * Dynamically click the button that adds a new filter group. - * - * @param {jQuery.Event} event - * The event triggered. - */ - clickAddGroupButton: function (event) { + clickAddGroupButton: function clickAddGroupButton(event) { this.addGroupButton.trigger('mousedown'); event.preventDefault(); }, - - /** - * Dynamically click a button for removing a filter group. - * - * @param {jQuery.Event} event - * Event being triggered, with event.data.buttonId set to the ID of the - * form button that should be clicked. - */ - clickRemoveGroupButton: function (event) { + clickRemoveGroupButton: function clickRemoveGroupButton(event) { this.table.find('#' + event.data.buttonId).trigger('mousedown'); event.preventDefault(); }, - - /** - * Move the groups operator so that it's between the first two groups, and - * duplicate it between any subsequent groups. - * - * @return {jQuery} - * An operator element. - */ - duplicateGroupsOperator: function () { - var dropdowns; - var newRow; - var titleRow; + duplicateGroupsOperator: function duplicateGroupsOperator() { + var dropdowns = void 0; + var newRow = void 0; + var titleRow = void 0; var titleRows = $('tr.views-group-title').once('duplicateGroupsOperator'); @@ -767,26 +382,20 @@ return this.operator; } - // Get rid of the explanatory text around the operator; its placement is - // explanatory enough. this.operator.find('label').add('div.description').addClass('visually-hidden'); this.operator.find('select').addClass('form-select'); - // Keep a list of the operator dropdowns, so we can sync their behavior - // later. dropdowns = this.operator; - // Move the operator to a new row just above the second group. titleRow = $('tr#views-group-title-2'); newRow = $('<tr class="filter-group-operator-row"><td colspan="5"></td></tr>'); newRow.find('td').append(this.operator); newRow.insertBefore(titleRow); var length = titleRows.length; - // Starting with the third group, copy the operator to a new row above the - // group title. + for (var i = 2; i < length; i++) { titleRow = $(titleRows[i]); - // Make a copy of the operator dropdown and put it in a new table row. + var fakeOperator = this.operator.clone(); fakeOperator.attr('id', ''); newRow = $('<tr class="filter-group-operator-row"><td colspan="5"></td></tr>'); @@ -797,64 +406,28 @@ return dropdowns; }, - - /** - * Make the duplicated groups operators change in sync with each other. - */ - syncGroupsOperators: function () { + syncGroupsOperators: function syncGroupsOperators() { if (this.dropdowns.length < 2) { - // We only have one dropdown (or none at all), so there's nothing to - // sync. return; } this.dropdowns.on('change', $.proxy(this, 'operatorChangeHandler')); }, - - /** - * Click handler for the operators that appear between filter groups. - * - * Forces all operator dropdowns to have the same value. - * - * @param {jQuery.Event} event - * The event triggered. - */ - operatorChangeHandler: function (event) { + operatorChangeHandler: function operatorChangeHandler(event) { var $target = $(event.target); var operators = this.dropdowns.find('select').not($target); - // Change the other operators to match this new value. operators.val($target.val()); }, - - /** - * @method - */ - modifyTableDrag: function () { + modifyTableDrag: function modifyTableDrag() { var tableDrag = Drupal.tableDrag['views-rearrange-filters']; var filterHandler = this; - /** - * Override the row.onSwap method from tabledrag.js. - * - * When a row is dragged to another place in the table, several things - * need to occur. - * - The row needs to be moved so that it's within one of the filter - * groups. - * - The operator cells that span multiple rows need their rowspan - * attributes updated to reflect the number of rows in each group. - * - The operator labels that are displayed next to each filter need to - * be redrawn, to account for the row's new location. - */ tableDrag.row.prototype.onSwap = function () { if (filterHandler.hasGroupOperator) { - // Make sure the row that just got moved (this.group) is inside one - // of the filter groups (i.e. below an empty marker row or a - // draggable). If it isn't, move it down one. var thisRow = $(this.group); var previousRow = thisRow.prev('tr'); if (previousRow.length && !previousRow.hasClass('group-message') && !previousRow.hasClass('draggable')) { - // Move the dragged row down one. var next = thisRow.next(); if (next.is('tr')) { this.swap('after', next); @@ -862,31 +435,19 @@ } filterHandler.updateRowspans(); } - // Redraw the operator labels that are displayed next to each filter, to - // account for the row's new location. + filterHandler.redrawOperatorLabels(); }; - /** - * Override the onDrop method from tabledrag.js. - */ tableDrag.onDrop = function () { - // If the tabledrag change marker (i.e., the "*") has been inserted - // inside a row after the operator label (i.e., "And" or "Or") - // rearrange the items so the operator label continues to appear last. var changeMarker = $(this.oldRowElement).find('.tabledrag-changed'); if (changeMarker.length) { - // Search for occurrences of the operator label before the change - // marker, and reverse them. var operatorLabel = changeMarker.prevAll('.views-operator-label'); if (operatorLabel.length) { operatorLabel.insertAfter(changeMarker); } } - // Make sure the "group" dropdown is properly updated when rows are - // dragged into an empty filter group. This is borrowed heavily from - // the block.js implementation of tableDrag.onDrop(). var groupRow = $(this.rowObject.element).prevAll('tr.group-message').get(0); var groupName = groupRow.className.replace(/([^ ]+[ ]+)*group-([^ ]+)-message([ ]+[^ ]+)*/, '$2'); var groupField = $('select.views-group-select', this.rowObject.element); @@ -897,100 +458,57 @@ } }; }, - - /** - * Redraw the operator labels that are displayed next to each filter. - */ - redrawOperatorLabels: function () { + redrawOperatorLabels: function redrawOperatorLabels() { for (var i = 0; i < this.draggableRows.length; i++) { - // Within the row, the operator labels are displayed inside the first - // table cell (next to the filter name). var $draggableRow = $(this.draggableRows[i]); var $firstCell = $draggableRow.find('td').eq(0); if ($firstCell.length) { - // The value of the operator label ("And" or "Or") is taken from the - // first operator dropdown we encounter, going backwards from the - // current row. This dropdown is the one associated with the current - // row's filter group. var operatorValue = $draggableRow.prevAll('.views-group-title').find('option:selected').html(); var operatorLabel = '<span class="views-operator-label">' + operatorValue + '</span>'; - // If the next visible row after this one is a draggable filter row, - // display the operator label next to the current row. (Checking for - // visibility is necessary here since the "Remove" links hide the - // removed row but don't actually remove it from the document). + var $nextRow = $draggableRow.nextAll(':visible').eq(0); var $existingOperatorLabel = $firstCell.find('.views-operator-label'); if ($nextRow.hasClass('draggable')) { - // If an operator label was already there, replace it with the new - // one. if ($existingOperatorLabel.length) { $existingOperatorLabel.replaceWith(operatorLabel); + } else { + $firstCell.append(operatorLabel); + } + } else { + $existingOperatorLabel.remove(); } - // Otherwise, append the operator label to the end of the table - // cell. - else { - $firstCell.append(operatorLabel); - } - } - // If the next row doesn't contain a filter, then this is the last row - // in the group. We don't want to display the operator there (since - // operators should only display between two related filters, e.g. - // "filter1 AND filter2 AND filter3"). So we remove any existing label - // that this row has. - else { - $existingOperatorLabel.remove(); - } } } }, - - /** - * Update the rowspan attribute of each cell containing an operator - * dropdown. - */ - updateRowspans: function () { - var $row; - var $currentEmptyRow; - var draggableCount; - var $operatorCell; + updateRowspans: function updateRowspans() { + var $row = void 0; + var $currentEmptyRow = void 0; + var draggableCount = void 0; + var $operatorCell = void 0; var rows = $(this.table).find('tr'); var length = rows.length; for (var i = 0; i < length; i++) { $row = $(rows[i]); if ($row.hasClass('views-group-title')) { - // This row is a title row. - // Keep a reference to the cell containing the dropdown operator. $operatorCell = $row.find('td.group-operator'); - // Assume this filter group is empty, until we find otherwise. + draggableCount = 0; $currentEmptyRow = $row.next('tr'); $currentEmptyRow.removeClass('group-populated').addClass('group-empty'); - // The cell with the dropdown operator should span the title row and - // the "this group is empty" row. + $operatorCell.attr('rowspan', 2); - } - else if ($row.hasClass('draggable') && $row.is(':visible')) { - // We've found a visible filter row, so we now know the group isn't - // empty. + } else if ($row.hasClass('draggable') && $row.is(':visible')) { draggableCount++; $currentEmptyRow.removeClass('group-empty').addClass('group-populated'); - // The operator cell should span all draggable rows, plus the title. + $operatorCell.attr('rowspan', draggableCount + 1); } } } }); - /** - * Add a select all checkbox, which checks each checkbox at once. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches select all functionality to the views filter form. - */ Drupal.behaviors.viewsFilterConfigSelectAll = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); var $selectAll = $context.find('.js-form-item-options-value-all').once('filterConfigSelectAll'); @@ -998,14 +516,11 @@ var $checkboxes = $selectAll.closest('.form-checkboxes').find('.js-form-type-checkbox:not(.js-form-item-options-value-all) input[type="checkbox"]'); if ($selectAll.length) { - // Show the select all checkbox. $selectAll.show(); $selectAllCheckbox.on('click', function () { - // Update all checkbox beside the select all checkbox. $checkboxes.prop('checked', $(this).is(':checked')); }); - // Uncheck the select all checkbox if any of the others are unchecked. $checkboxes.on('click', function () { if ($(this).is('checked') === false) { $selectAllCheckbox.prop('checked', false); @@ -1015,50 +530,25 @@ } }; - /** - * Remove icon class from elements that are themed as buttons or dropbuttons. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Removes the icon class from certain views elements. - */ Drupal.behaviors.viewsRemoveIconClass = { - attach: function (context) { + attach: function attach(context) { $(context).find('.dropbutton').once('dropbutton-icon').find('.icon').removeClass('icon'); } }; - /** - * Change "Expose filter" buttons into checkboxes. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Changes buttons into checkboxes via {@link Drupal.viewsUi.Checkboxifier}. - */ Drupal.behaviors.viewsUiCheckboxify = { - attach: function (context, settings) { + attach: function attach(context, settings) { var $buttons = $('[data-drupal-selector="edit-options-expose-button-button"], [data-drupal-selector="edit-options-group-button-button"]').once('views-ui-checkboxify'); var length = $buttons.length; - var i; + var i = void 0; for (i = 0; i < length; i++) { new Drupal.viewsUi.Checkboxifier($buttons[i]); } } }; - /** - * Change the default widget to select the default group according to the - * selected widget for the exposed group. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Changes the default widget based on user input. - */ Drupal.behaviors.viewsUiChangeDefaultWidget = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); function changeDefaultWidget(event) { @@ -1066,110 +556,64 @@ $context.find('input.default-radios').parent().hide(); $context.find('td.any-default-radios-row').parent().hide(); $context.find('input.default-checkboxes').parent().show(); - } - else { + } else { $context.find('input.default-checkboxes').parent().hide(); $context.find('td.any-default-radios-row').parent().show(); $context.find('input.default-radios').parent().show(); } } - // Update on widget change. - $context.find('input[name="options[group_info][multiple]"]') - .on('change', changeDefaultWidget) - // Update the first time the form is rendered. - .trigger('change'); + $context.find('input[name="options[group_info][multiple]"]').on('change', changeDefaultWidget).trigger('change'); } }; - /** - * Attaches expose filter button to a checkbox that triggers its click event. - * - * @constructor - * - * @param {HTMLElement} button - * The DOM object representing the button to be checkboxified. - */ Drupal.viewsUi.Checkboxifier = function (button) { this.$button = $(button); this.$parent = this.$button.parent('div.views-expose, div.views-grouped'); this.$input = this.$parent.find('input:checkbox, input:radio'); - // Hide the button and its description. + this.$button.hide(); this.$parent.find('.exposed-description, .grouped-description').hide(); this.$input.on('click', $.proxy(this, 'clickHandler')); - }; - /** - * When the checkbox is checked or unchecked, simulate a button press. - * - * @param {jQuery.Event} e - * The event triggered. - */ Drupal.viewsUi.Checkboxifier.prototype.clickHandler = function (e) { - this.$button - .trigger('click') - .trigger('submit'); + this.$button.trigger('click').trigger('submit'); }; - /** - * Change the Apply button text based upon the override select state. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches behavior to change the Apply button according to the current - * state. - */ Drupal.behaviors.viewsUiOverrideSelect = { - attach: function (context) { + attach: function attach(context) { $(context).find('[data-drupal-selector="edit-override-dropdown"]').once('views-ui-override-button-text').each(function () { - // Closures! :( var $context = $(context); var $submit = $context.find('[id^=edit-submit]'); var old_value = $submit.val(); - $submit.once('views-ui-override-button-text') - .on('mouseup', function () { - $(this).val(old_value); - return true; - }); + $submit.once('views-ui-override-button-text').on('mouseup', function () { + $(this).val(old_value); + return true; + }); $(this).on('change', function () { var $this = $(this); if ($this.val() === 'default') { $submit.val(Drupal.t('Apply (all displays)')); - } - else if ($this.val() === 'default_revert') { + } else if ($this.val() === 'default_revert') { $submit.val(Drupal.t('Revert to default')); - } - else { + } else { $submit.val(Drupal.t('Apply (this display)')); } var $dialog = $context.closest('.ui-dialog-content'); $dialog.trigger('dialogButtonsChange'); - }) - .trigger('change'); + }).trigger('change'); }); - } }; - /** - * Functionality for the remove link in the views UI. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches behavior for the remove view and remove display links. - */ Drupal.behaviors.viewsUiHandlerRemoveLink = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); - // Handle handler deletion by looking for the hidden checkbox and hiding - // the row. + $context.find('a.views-remove-link').once('views').on('click', function (event) { var id = $(this).attr('id').replace('views-remove-link-', ''); $context.find('#views-row-' + id).hide(); @@ -1177,8 +621,6 @@ event.preventDefault(); }); - // Handle display deletion by looking for the hidden checkbox and hiding - // the row. $context.find('a.display-remove-link').once('display').on('click', function (event) { var id = $(this).attr('id').replace('display-remove-link-', ''); $context.find('#display-row-' + id).hide(); @@ -1187,5 +629,4 @@ }); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/views_ui/js/views_ui.listing.es6.js b/core/modules/views_ui/js/views_ui.listing.es6.js new file mode 100644 index 00000000..61a66661 --- /dev/null +++ b/core/modules/views_ui/js/views_ui.listing.es6.js @@ -0,0 +1,50 @@ +/** + * @file + * Views listing behaviors. + */ + +(function ($, Drupal) { + /** + * Filters the view listing tables by a text input search string. + * + * Text search input: input.views-filter-text + * Target table: input.views-filter-text[data-table] + * Source text: [data-drupal-selector="views-table-filter-text-source"] + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the filter functionality to the views admin text search field. + */ + Drupal.behaviors.viewTableFilterByText = { + attach(context, settings) { + const $input = $('input.views-filter-text').once('views-filter-text'); + const $table = $($input.attr('data-table')); + let $rows; + + function filterViewList(e) { + const query = $(e.target).val().toLowerCase(); + + function showViewRow(index, row) { + const $row = $(row); + const $sources = $row.find('[data-drupal-selector="views-table-filter-text-source"]'); + const textMatch = $sources.text().toLowerCase().indexOf(query) !== -1; + $row.closest('tr').toggle(textMatch); + } + + // Filter if the length of the query is at least 2 characters. + if (query.length >= 2) { + $rows.each(showViewRow); + } + else { + $rows.show(); + } + } + + if ($table.length) { + $rows = $table.find('tbody tr'); + $input.on('keyup', filterViewList); + } + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/views_ui/js/views_ui.listing.js b/core/modules/views_ui/js/views_ui.listing.js index 7d19cd49..4da04058 100644 --- a/core/modules/views_ui/js/views_ui.listing.js +++ b/core/modules/views_ui/js/views_ui.listing.js @@ -1,29 +1,16 @@ /** - * @file - * Views listing behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Filters the view listing tables by a text input search string. - * - * Text search input: input.views-filter-text - * Target table: input.views-filter-text[data-table] - * Source text: [data-drupal-selector="views-table-filter-text-source"] - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the filter functionality to the views admin text search field. - */ Drupal.behaviors.viewTableFilterByText = { - attach: function (context, settings) { + attach: function attach(context, settings) { var $input = $('input.views-filter-text').once('views-filter-text'); var $table = $($input.attr('data-table')); - var $rows; + var $rows = void 0; function filterViewList(e) { var query = $(e.target).val().toLowerCase(); @@ -35,11 +22,9 @@ $row.closest('tr').toggle(textMatch); } - // Filter if the length of the query is at least 2 characters. if (query.length >= 2) { $rows.each(showViewRow); - } - else { + } else { $rows.show(); } } @@ -50,5 +35,4 @@ } } }; - -}(jQuery, Drupal)); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/views_ui/src/Ajax/SetFormCommand.php b/core/modules/views_ui/src/Ajax/SetFormCommand.php index ffafde6c..3910eb21 100644 --- a/core/modules/views_ui/src/Ajax/SetFormCommand.php +++ b/core/modules/views_ui/src/Ajax/SetFormCommand.php @@ -32,10 +32,10 @@ public function __construct($url) { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => 'viewsSetForm', 'url' => $this->url, - ); + ]; } } diff --git a/core/modules/views_ui/src/Controller/ViewsUIController.php b/core/modules/views_ui/src/Controller/ViewsUIController.php index f36e912a..97947620 100644 --- a/core/modules/views_ui/src/Controller/ViewsUIController.php +++ b/core/modules/views_ui/src/Controller/ViewsUIController.php @@ -58,7 +58,7 @@ public function reportFields() { // Fetch all fieldapi fields which are used in views // Therefore search in all views, displays and handler-types. - $fields = array(); + $fields = []; $handler_types = ViewExecutable::getHandlerTypes(); foreach ($views as $view) { $executable = $view->getExecutable(); @@ -81,12 +81,12 @@ public function reportFields() { } } - $header = array(t('Field name'), t('Used in')); - $rows = array(); + $header = [t('Field name'), t('Used in')]; + $rows = []; foreach ($fields as $field_name => $views) { $rows[$field_name]['data'][0]['data']['#plain_text'] = $field_name; foreach ($views as $view) { - $rows[$field_name]['data'][1][] = $this->l($view, new Url('entity.view.edit_form', array('view' => $view))); + $rows[$field_name]['data'][1][] = $this->l($view, new Url('entity.view.edit_form', ['view' => $view])); } $item_list = [ '#theme' => 'item_list', @@ -98,12 +98,12 @@ public function reportFields() { // Sort rows by field name. ksort($rows); - $output = array( + $output = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, '#empty' => t('No fields have been used in views yet.'), - ); + ]; return $output; } @@ -120,7 +120,7 @@ public function reportPlugins() { $views = []; // Link each view name to the view itself. foreach ($row['views'] as $row_name => $view) { - $views[] = $this->l($view, new Url('entity.view.edit_form', array('view' => $view))); + $views[] = $this->l($view, new Url('entity.view.edit_form', ['view' => $view])); } unset($row['views']); $row['views']['data'] = [ @@ -132,12 +132,12 @@ public function reportPlugins() { // Sort rows by field name. ksort($rows); - return array( + return [ '#type' => 'table', - '#header' => array(t('Type'), t('Name'), t('Provided by'), t('Used in')), + '#header' => [t('Type'), t('Name'), t('Provided by'), t('Used in')], '#rows' => $rows, '#empty' => t('There are no enabled views.'), - ); + ]; } /** @@ -180,7 +180,7 @@ public function ajaxOperation(ViewEntityInterface $view, $op, Request $request) * A JSON response containing the autocomplete suggestions for Views tags. */ public function autocompleteTag(Request $request) { - $matches = array(); + $matches = []; $string = $request->query->get('q'); // Get matches from default views. $views = $this->entityManager()->getStorage('view')->loadMultiple(); @@ -223,8 +223,8 @@ public function edit(ViewUI $view, $display_id = NULL) { } $build['#title'] = $name; - $build['edit'] = $this->entityFormBuilder()->getForm($view, 'edit', array('display_id' => $display_id)); - $build['preview'] = $this->entityFormBuilder()->getForm($view, 'preview', array('display_id' => $display_id)); + $build['edit'] = $this->entityFormBuilder()->getForm($view, 'edit', ['display_id' => $display_id]); + $build['preview'] = $this->entityFormBuilder()->getForm($view, 'preview', ['display_id' => $display_id]); return $build; } diff --git a/core/modules/views_ui/src/Form/AdvancedSettingsForm.php b/core/modules/views_ui/src/Form/AdvancedSettingsForm.php index 88661a77..36f34c26 100644 --- a/core/modules/views_ui/src/Form/AdvancedSettingsForm.php +++ b/core/modules/views_ui/src/Form/AdvancedSettingsForm.php @@ -32,52 +32,52 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form = parent::buildForm($form, $form_state); $config = $this->config('views.settings'); - $form['cache'] = array( + $form['cache'] = [ '#type' => 'details', '#title' => $this->t('Caching'), '#open' => TRUE, - ); + ]; - $form['cache']['skip_cache'] = array( + $form['cache']['skip_cache'] = [ '#type' => 'checkbox', '#title' => $this->t('Disable views data caching'), '#description' => $this->t("Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site."), '#default_value' => $config->get('skip_cache'), - ); + ]; - $form['cache']['clear_cache'] = array( + $form['cache']['clear_cache'] = [ '#type' => 'submit', '#value' => $this->t("Clear Views' cache"), - '#submit' => array('::cacheSubmit'), - ); + '#submit' => ['::cacheSubmit'], + ]; - $form['debug'] = array( + $form['debug'] = [ '#type' => 'details', '#title' => $this->t('Debugging'), '#open' => TRUE, - ); + ]; - $form['debug']['sql_signature'] = array( + $form['debug']['sql_signature'] = [ '#type' => 'checkbox', '#title' => $this->t('Add Views signature to all SQL queries'), '#description' => $this->t("All Views-generated queries will include the name of the views and display 'view-name:display-name' as a string at the end of the SELECT clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting."), '#default_value' => $config->get('sql_signature'), - ); + ]; $options = Views::fetchPluginNames('display_extender'); if (!empty($options)) { - $form['extenders'] = array( + $form['extenders'] = [ '#type' => 'details', '#open' => TRUE, - ); - $form['extenders']['display_extenders'] = array( + ]; + $form['extenders']['display_extenders'] = [ '#title' => $this->t('Display extenders'), '#default_value' => array_filter($config->get('display_extenders')), '#options' => $options, '#type' => 'checkboxes', '#description' => $this->t('Select extensions of the views interface.') - ); + ]; } return $form; @@ -90,7 +90,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->config('views.settings') ->set('skip_cache', $form_state->getValue('skip_cache')) ->set('sql_signature', $form_state->getValue('sql_signature')) - ->set('display_extenders', $form_state->getValue('display_extenders', array())) + ->set('display_extenders', $form_state->getValue('display_extenders', [])) ->save(); parent::submitForm($form, $form_state); diff --git a/core/modules/views_ui/src/Form/Ajax/AddHandler.php b/core/modules/views_ui/src/Form/Ajax/AddHandler.php index ada0ccd3..ec0c6554 100644 --- a/core/modules/views_ui/src/Form/Ajax/AddHandler.php +++ b/core/modules/views_ui/src/Form/Ajax/AddHandler.php @@ -49,16 +49,16 @@ public function buildForm(array $form, FormStateInterface $form_state) { $display_id = $form_state->get('display_id'); $type = $form_state->get('type'); - $form = array( - 'options' => array( - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE), - ), - ); + $form = [ + 'options' => [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE], + ], + ]; $executable = $view->getExecutable(); if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } $display = &$executable->displayHandlers->get($display_id); @@ -71,7 +71,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $type = $types[$type]['type']; } - $form['#title'] = $this->t('Add @type', array('@type' => $ltitle)); + $form['#title'] = $this->t('Add @type', ['@type' => $ltitle]); $form['#section'] = $display_id . 'add-handler'; // Add the display override dropdown. @@ -82,36 +82,36 @@ public function buildForm(array $form, FormStateInterface $form_state) { $options = Views::viewsDataHelper()->fetchFields(array_keys($base_tables), $type, $display->useGroupBy(), $form_state->get('type')); if (!empty($options)) { - $form['override']['controls'] = array( - '#theme_wrappers' => array('container'), + $form['override']['controls'] = [ + '#theme_wrappers' => ['container'], '#id' => 'views-filterable-options-controls', '#attributes' => ['class' => ['form--inline', 'views-filterable-options-controls']], - ); - $form['override']['controls']['options_search'] = array( + ]; + $form['override']['controls']['options_search'] = [ '#type' => 'textfield', '#title' => $this->t('Search'), - ); + ]; - $groups = array('all' => $this->t('- All -')); - $form['override']['controls']['group'] = array( + $groups = ['all' => $this->t('- All -')]; + $form['override']['controls']['group'] = [ '#type' => 'select', '#title' => $this->t('Category'), - '#options' => array(), - ); + '#options' => [], + ]; - $form['options']['name'] = array( + $form['options']['name'] = [ '#prefix' => '<div class="views-radio-box form-checkboxes views-filterable-options">', '#suffix' => '</div>', '#type' => 'tableselect', - '#header' => array( + '#header' => [ 'title' => $this->t('Title'), 'group' => $this->t('Category'), 'help' => $this->t('Description'), - ), + ], '#js_select' => FALSE, - ); + ]; - $grouped_options = array(); + $grouped_options = []; foreach ($options as $key => $option) { $group = preg_replace('/[^a-z0-9]/', '-', strtolower($option['group'])); $groups[$group] = $option['group']; @@ -136,50 +136,50 @@ public function buildForm(array $form, FormStateInterface $form_state) { foreach ($grouped_options as $group => $group_options) { foreach ($group_options as $key => $option) { - $form['options']['name']['#options'][$key] = array( - '#attributes' => array( - 'class' => array('filterable-option', $group), - ), - 'title' => array( - 'data' => array( + $form['options']['name']['#options'][$key] = [ + '#attributes' => [ + 'class' => ['filterable-option', $group], + ], + 'title' => [ + 'data' => [ '#title' => $option['title'], '#plain_text' => $option['title'], - ), - 'class' => array('title'), - ), + ], + 'class' => ['title'], + ], 'group' => $option['group'], - 'help' => array( + 'help' => [ 'data' => $option['help'], - 'class' => array('description'), - ), - ); + 'class' => ['description'], + ], + ]; } } $form['override']['controls']['group']['#options'] = $groups; } else { - $form['options']['markup'] = array( - '#markup' => '<div class="js-form-item form-item">' . $this->t('There are no @types available to add.', array('@types' => $ltitle)) . '</div>', - ); + $form['options']['markup'] = [ + '#markup' => '<div class="js-form-item form-item">' . $this->t('There are no @types available to add.', ['@types' => $ltitle]) . '</div>', + ]; } // Add a div to show the selected items - $form['selected'] = array( + $form['selected'] = [ '#type' => 'item', '#markup' => '<span class="views-ui-view-title">' . $this->t('Selected:') . '</span> ' . '<div class="views-selected-options"></div>', - '#theme_wrappers' => array('form_element', 'views_ui_container'), - '#attributes' => array( - 'class' => array('container-inline', 'views-add-form-selected', 'views-offset-bottom'), + '#theme_wrappers' => ['form_element', 'views_ui_container'], + '#attributes' => [ + 'class' => ['container-inline', 'views-add-form-selected', 'views-offset-bottom'], 'data-drupal-views-offset' => 'bottom', - ), - ); - $view->getStandardButtons($form, $form_state, 'views_ui_add_handler_form', $this->t('Add and configure @types', array('@types' => $ltitle))); + ], + ]; + $view->getStandardButtons($form, $form_state, 'views_ui_add_handler_form', $this->t('Add and configure @types', ['@types' => $ltitle])); // Remove the default submit function. - $form['actions']['submit']['#submit'] = array_filter($form['actions']['submit']['#submit'], function($var) { + $form['actions']['submit']['#submit'] = array_filter($form['actions']['submit']['#submit'], function ($var) { return !(is_array($var) && isset($var[1]) && $var[1] == 'standardSubmit'); }); - $form['actions']['submit']['#submit'][] = array($view, 'submitItemAdd'); + $form['actions']['submit']['#submit'][] = [$view, 'submitItemAdd']; return $form; } diff --git a/core/modules/views_ui/src/Form/Ajax/Analyze.php b/core/modules/views_ui/src/Form/Ajax/Analyze.php index 458575d3..52784d3d 100644 --- a/core/modules/views_ui/src/Form/Ajax/Analyze.php +++ b/core/modules/views_ui/src/Form/Ajax/Analyze.php @@ -36,11 +36,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { $analyzer = Views::analyzer(); $messages = $analyzer->getMessages($view->getExecutable()); - $form['analysis'] = array( + $form['analysis'] = [ '#prefix' => '<div class="js-form-item form-item">', '#suffix' => '</div>', '#markup' => $analyzer->formatMessages($messages), - ); + ]; // Inform the standard button function that we want an OK button. $form_state->set('ok_button', TRUE); diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php index 819cb755..972b4b94 100644 --- a/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php +++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php @@ -54,17 +54,17 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ $type = $form_state->get('type'); $id = $form_state->get('id'); - $form = array( - 'options' => array( + $form = [ + 'options' => [ '#tree' => TRUE, - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE), - ), - ); + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE], + ], + ]; $executable = $view->getExecutable(); $save_ui_cache = FALSE; if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } $item = $executable->getHandler($display_id, $type, $id); @@ -72,7 +72,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ if ($item) { $handler = $executable->display_handler->getHandler($type, $id); if (empty($handler)) { - $form['markup'] = array('#markup' => $this->t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + $form['markup'] = ['#markup' => $this->t("Error: handler for @table > @field doesn't exist!", ['@table' => $item['table'], '@field' => $item['field']])]; } else { $types = ViewExecutable::getHandlerTypes(); @@ -88,7 +88,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ // A whole bunch of code to figure out what relationships are valid for // this item. $relationships = $executable->display_handler->getOption('relationships'); - $relationship_options = array(); + $relationship_options = []; foreach ($relationships as $relationship) { // relationships can't link back to self. But also, due to ordering, @@ -118,7 +118,7 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ // it to none. $base_fields = Views::viewsDataHelper()->fetchFields($view->get('base_table'), $type, $executable->display_handler->useGroupBy()); if (isset($base_fields[$item['table'] . '.' . $item['field']])) { - $relationship_options = array_merge(array('none' => $this->t('Do not use a relationship')), $relationship_options); + $relationship_options = array_merge(['none' => $this->t('Do not use a relationship')], $relationship_options); } $rel = empty($item['relationship']) ? 'none' : $item['relationship']; if (empty($relationship_options[$rel])) { @@ -133,30 +133,30 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ $handler->init($executable, $executable->display_handler, $item); } - $form['options']['relationship'] = array( + $form['options']['relationship'] = [ '#type' => 'select', '#title' => $this->t('Relationship'), '#options' => $relationship_options, '#default_value' => $rel, '#weight' => -500, - ); + ]; } else { - $form['options']['relationship'] = array( + $form['options']['relationship'] = [ '#type' => 'value', '#value' => 'none', - ); + ]; } - $form['#title'] = $this->t('Configure @type: @item', array('@type' => $types[$type]['lstitle'], '@item' => $handler->adminLabel())); + $form['#title'] = $this->t('Configure @type: @item', ['@type' => $types[$type]['lstitle'], '@item' => $handler->adminLabel()]); if (!empty($handler->definition['help'])) { - $form['options']['form_description'] = array( + $form['options']['form_description'] = [ '#markup' => $handler->definition['help'], - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('js-form-item form-item description')), + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['js-form-item form-item description']], '#weight' => -1000, - ); + ]; } $form['#section'] = $display_id . '-' . $type . '-' . $id; @@ -170,13 +170,13 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $ $view->getStandardButtons($form, $form_state, 'views_ui_config_item_form', $name); // Add a 'remove' button. - $form['actions']['remove'] = array( + $form['actions']['remove'] = [ '#type' => 'submit', '#value' => $this->t('Remove'), - '#submit' => array(array($this, 'remove')), - '#limit_validation_errors' => array(array('override')), + '#submit' => [[$this, 'remove']], + '#limit_validation_errors' => [['override']], '#button_type' => 'danger', - ); + ]; } if ($save_ui_cache) { diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php index 0c10fb1f..a79d0314 100644 --- a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php +++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php @@ -51,16 +51,16 @@ public function buildForm(array $form, FormStateInterface $form_state) { $type = $form_state->get('type'); $id = $form_state->get('id'); - $form = array( - 'options' => array( + $form = [ + 'options' => [ '#tree' => TRUE, - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE), - ), - ); + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE], + ], + ]; $executable = $view->getExecutable(); if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } $item = $executable->getHandler($display_id, $type, $id); @@ -68,13 +68,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { if ($item) { $handler = $executable->display_handler->getHandler($type, $id); if (empty($handler)) { - $form['markup'] = array('#markup' => $this->t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + $form['markup'] = ['#markup' => $this->t("Error: handler for @table > @field doesn't exist!", ['@table' => $item['table'], '@field' => $item['field']])]; } else { $handler->init($executable, $executable->display_handler, $item); $types = ViewExecutable::getHandlerTypes(); - $form['#title'] = $this->t('Configure extra settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel())); + $form['#title'] = $this->t('Configure extra settings for @type %item', ['@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel()]); $form['#section'] = $display_id . '-' . $type . '-' . $id; diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php index e7c7a839..b4d0f136 100644 --- a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php +++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerGroup.php @@ -52,16 +52,16 @@ public function buildForm(array $form, FormStateInterface $form_state) { $type = $form_state->get('type'); $id = $form_state->get('id'); - $form = array( - 'options' => array( + $form = [ + 'options' => [ '#tree' => TRUE, - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE), - ), - ); + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE], + ], + ]; $executable = $view->getExecutable(); if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } @@ -72,13 +72,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { if ($item) { $handler = $executable->display_handler->getHandler($type, $id); if (empty($handler)) { - $form['markup'] = array('#markup' => $this->t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + $form['markup'] = ['#markup' => $this->t("Error: handler for @table > @field doesn't exist!", ['@table' => $item['table'], '@field' => $item['field']])]; } else { $handler->init($executable, $executable->display_handler, $item); $types = ViewExecutable::getHandlerTypes(); - $form['#title'] = $this->t('Configure aggregation settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel())); + $form['#title'] = $this->t('Configure aggregation settings for @type %item', ['@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel()]); $handler->buildGroupByForm($form['options'], $form_state); $form_state->set('handler', $handler); diff --git a/core/modules/views_ui/src/Form/Ajax/Display.php b/core/modules/views_ui/src/Form/Ajax/Display.php index bd129af1..302d7595 100644 --- a/core/modules/views_ui/src/Form/Ajax/Display.php +++ b/core/modules/views_ui/src/Form/Ajax/Display.php @@ -60,15 +60,15 @@ public function buildForm(array $form, FormStateInterface $form_state) { $executable = $view->getExecutable(); if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } // Get form from the handler. - $form['options'] = array( - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE), - ); + $form['options'] = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE], + ]; $executable->display_handler->buildOptionsForm($form['options'], $form_state); // The handler options form sets $form['#title'], which we need on the entire diff --git a/core/modules/views_ui/src/Form/Ajax/EditDetails.php b/core/modules/views_ui/src/Form/Ajax/EditDetails.php index ced40442..07b1625a 100644 --- a/core/modules/views_ui/src/Form/Ajax/EditDetails.php +++ b/core/modules/views_ui/src/Form/Ajax/EditDetails.php @@ -33,33 +33,33 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['#title'] = $this->t('Name and description'); $form['#section'] = 'details'; - $form['details'] = array( - '#theme_wrappers' => array('container'), - '#attributes' => array('class' => array('scroll'), 'data-drupal-views-scroll' => TRUE), - ); - $form['details']['label'] = array( + $form['details'] = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['scroll'], 'data-drupal-views-scroll' => TRUE], + ]; + $form['details']['label'] = [ '#type' => 'textfield', '#title' => t('Administrative name'), '#default_value' => $view->label(), - ); - $form['details']['langcode'] = array( + ]; + $form['details']['langcode'] = [ '#type' => 'language_select', '#title' => $this->t('View language'), '#description' => $this->t('Language of labels and other textual elements in this view.'), '#default_value' => $view->get('langcode'), - ); - $form['details']['description'] = array( + ]; + $form['details']['description'] = [ '#type' => 'textfield', '#title' => t('Administrative description'), '#default_value' => $view->get('description'), - ); - $form['details']['tag'] = array( + ]; + $form['details']['tag'] = [ '#type' => 'textfield', '#title' => t('Administrative tags'), '#description' => t('Enter a comma-separated list of words to describe your view.'), '#default_value' => $view->get('tag'), '#autocomplete_route_name' => 'views_ui.autocomplete', - ); + ]; $view->getStandardButtons($form, $form_state, 'views_ui_edit_details_form'); return $form; diff --git a/core/modules/views_ui/src/Form/Ajax/Rearrange.php b/core/modules/views_ui/src/Form/Ajax/Rearrange.php index 04877695..1ffb710c 100644 --- a/core/modules/views_ui/src/Form/Ajax/Rearrange.php +++ b/core/modules/views_ui/src/Form/Ajax/Rearrange.php @@ -53,11 +53,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { $types = ViewExecutable::getHandlerTypes(); $executable = $view->getExecutable(); if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } $display = &$executable->displayHandlers->get($display_id); - $form['#title'] = $this->t('Rearrange @type', array('@type' => $types[$type]['ltitle'])); + $form['#title'] = $this->t('Rearrange @type', ['@type' => $types[$type]['ltitle']]); $form['#section'] = $display_id . 'rearrange-item'; if ($display->defaultableSections($types[$type]['plural'])) { @@ -69,31 +69,31 @@ public function buildForm(array $form, FormStateInterface $form_state) { $count = 0; // Get relationship labels - $relationships = array(); + $relationships = []; foreach ($display->getHandlers('relationship') as $id => $handler) { $relationships[$id] = $handler->adminLabel(); } - $form['fields'] = array( + $form['fields'] = [ '#type' => 'table', - '#header' => array('', $this->t('Weight'), $this->t('Remove')), + '#header' => ['', $this->t('Weight'), $this->t('Remove')], '#empty' => $this->t('No fields available.'), - '#tabledrag' => array( - array( + '#tabledrag' => [ + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'weight', - ) - ), + ] + ], '#tree' => TRUE, '#prefix' => '<div class="scroll" data-drupal-views-scroll>', '#suffix' => '</div>', - ); + ]; foreach ($display->getOption($types[$type]['plural']) as $id => $field) { - $form['fields'][$id] = array(); + $form['fields'][$id] = []; - $form['fields'][$id]['#attributes'] = array('class' => array('draggable'), 'id' => 'views-row-' . $id); + $form['fields'][$id]['#attributes'] = ['class' => ['draggable'], 'id' => 'views-row-' . $id]; $handler = $display->getHandler($type, $id); if ($handler) { @@ -105,34 +105,36 @@ public function buildForm(array $form, FormStateInterface $form_state) { } else { $name = $id; - $markup = $this->t('Broken field @id', array('@id' => $id)); + $markup = $this->t('Broken field @id', ['@id' => $id]); } - $form['fields'][$id]['name'] = array('#markup' => $markup); + $form['fields'][$id]['name'] = ['#markup' => $markup]; - $form['fields'][$id]['weight'] = array( + $form['fields'][$id]['weight'] = [ '#type' => 'textfield', '#default_value' => ++$count, - '#attributes' => array('class' => array('weight')), - '#title' => t('Weight for @title', array('@title' => $name)), + '#attributes' => ['class' => ['weight']], + '#title' => t('Weight for @title', ['@title' => $name]), '#title_display' => 'invisible', - ); + ]; - $form['fields'][$id]['removed'] = array( + $form['fields'][$id]['removed'] = [ '#type' => 'checkbox', - '#title' => t('Remove @title', array('@title' => $name)), + '#title' => t('Remove @title', ['@title' => $name]), '#title_display' => 'invisible', '#id' => 'views-removed-' . $id, - '#attributes' => array('class' => array('views-remove-checkbox')), + '#attributes' => ['class' => ['views-remove-checkbox']], '#default_value' => 0, - '#suffix' => \Drupal::l(SafeMarkup::format('<span>@text</span>', array('@text' => $this->t('Remove'))), - Url::fromRoute('<none>', array(), array('attributes' => array( - 'id' => 'views-remove-link-' . $id, - 'class' => array('views-hidden', 'views-button-remove', 'views-remove-link'), - 'alt' => $this->t('Remove this item'), - 'title' => $this->t('Remove this item')), - )) + '#suffix' => \Drupal::l(SafeMarkup::format('<span>@text</span>', ['@text' => $this->t('Remove')]), + Url::fromRoute('<none>', [], [ + 'attributes' => [ + 'id' => 'views-remove-link-' . $id, + 'class' => ['views-hidden', 'views-button-remove', 'views-remove-link'], + 'alt' => $this->t('Remove this item'), + 'title' => $this->t('Remove this item'), + ], + ]) ), - ); + ]; } $view->getStandardButtons($form, $form_state, 'views_ui_rearrange_form'); @@ -152,7 +154,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $display = &$view->getExecutable()->displayHandlers->get($display_id); $old_fields = $display->getOption($types[$type]['plural']); - $new_fields = $order = array(); + $new_fields = $order = []; // Make an array with the weights foreach ($form_state->getValue('fields') as $field => $info) { diff --git a/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php b/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php index ea2235b7..98eb8288 100644 --- a/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php +++ b/core/modules/views_ui/src/Form/Ajax/RearrangeFilter.php @@ -43,12 +43,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { $types = ViewExecutable::getHandlerTypes(); $executable = $view->getExecutable(); if (!$executable->setDisplay($display_id)) { - $form['markup'] = array('#markup' => $this->t('Invalid display id @display', array('@display' => $display_id))); + $form['markup'] = ['#markup' => $this->t('Invalid display id @display', ['@display' => $display_id])]; return $form; } $display = $executable->displayHandlers->get($display_id); $form['#title'] = Html::escape($display->display['display_title']) . ': '; - $form['#title'] .= $this->t('Rearrange @type', array('@type' => $types[$type]['ltitle'])); + $form['#title'] .= $this->t('Rearrange @type', ['@type' => $types[$type]['ltitle']]); $form['#section'] = $display_id . 'rearrange-item'; if ($display->defaultableSections($types[$type]['plural'])) { @@ -68,12 +68,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { $count = 0; // Get relationship labels - $relationships = array(); + $relationships = []; foreach ($display->getHandlers('relationship') as $id => $handler) { $relationships[$id] = $handler->adminLabel(); } - $group_options = array(); + $group_options = []; /** * Filter groups is an array that contains: @@ -88,59 +88,60 @@ public function buildForm(array $form, FormStateInterface $form_state) { $grouping = count(array_keys($groups['groups'])) > 1; $form['filter_groups']['#tree'] = TRUE; - $form['filter_groups']['operator'] = array( + $form['filter_groups']['operator'] = [ '#type' => 'select', - '#options' => array( + '#options' => [ 'AND' => $this->t('And'), 'OR' => $this->t('Or'), - ), + ], '#default_value' => $groups['operator'], - '#attributes' => array( - 'class' => array('warning-on-change'), - ), + '#attributes' => [ + 'class' => ['warning-on-change'], + ], '#title' => $this->t('Operator to use on all groups'), '#description' => $this->t('Either "group 0 AND group 1 AND group 2" or "group 0 OR group 1 OR group 2", etc'), '#access' => $grouping, - ); + ]; $form['remove_groups']['#tree'] = TRUE; foreach ($groups['groups'] as $id => $group) { - $form['filter_groups']['groups'][$id] = array( + $form['filter_groups']['groups'][$id] = [ '#title' => $this->t('Operator'), '#type' => 'select', - '#options' => array( + '#options' => [ 'AND' => $this->t('And'), 'OR' => $this->t('Or'), - ), + ], '#default_value' => $group, - '#attributes' => array( - 'class' => array('warning-on-change'), - ), - ); + '#attributes' => [ + 'class' => ['warning-on-change'], + ], + ]; - $form['remove_groups'][$id] = array(); // to prevent a notice + // To prevent a notice. + $form['remove_groups'][$id] = []; if ($id != 1) { - $form['remove_groups'][$id] = array( + $form['remove_groups'][$id] = [ '#type' => 'submit', - '#value' => $this->t('Remove group @group', array('@group' => $id)), + '#value' => $this->t('Remove group @group', ['@group' => $id]), '#id' => "views-remove-group-$id", - '#attributes' => array( - 'class' => array('views-remove-group'), - ), + '#attributes' => [ + 'class' => ['views-remove-group'], + ], '#group' => $id, '#ajax' => ['url' => NULL], - ); + ]; } - $group_options[$id] = $id == 1 ? $this->t('Default group') : $this->t('Group @group', array('@group' => $id)); - $form['#group_renders'][$id] = array(); + $group_options[$id] = $id == 1 ? $this->t('Default group') : $this->t('Group @group', ['@group' => $id]); + $form['#group_renders'][$id] = []; } $form['#group_options'] = $group_options; $form['#groups'] = $groups; // We don't use getHandlers() because we want items without handlers to // appear and show up as 'broken' so that the user can see them. - $form['filters'] = array('#tree' => TRUE); + $form['filters'] = ['#tree' => TRUE]; foreach ($handlers as $id => $field) { // If the group does not exist, move the filters to the default group. if (empty($field['group']) || empty($groups['groups'][$field['group']])) { @@ -162,24 +163,24 @@ public function buildForm(array $form, FormStateInterface $form_state) { // Place this item into the proper group for rendering. $form['#group_renders'][$field['group']][] = $id; - $form['filters'][$id]['weight'] = array( - '#title' => t('Weight for @id', array('@id' => $id)), + $form['filters'][$id]['weight'] = [ + '#title' => t('Weight for @id', ['@id' => $id]), '#title_display' => 'invisible', '#type' => 'textfield', '#default_value' => ++$count, '#size' => 8, - ); - $form['filters'][$id]['group'] = array( - '#title' => t('Group for @id', array('@id' => $id)), + ]; + $form['filters'][$id]['group'] = [ + '#title' => t('Group for @id', ['@id' => $id]), '#title_display' => 'invisible', '#type' => 'select', '#options' => $group_options, '#default_value' => $field['group'], - '#attributes' => array( - 'class' => array('views-region-select', 'views-region-' . $id), - ), + '#attributes' => [ + 'class' => ['views-region-select', 'views-region-' . $id], + ], '#access' => $field['group'] !== 'ungroupable', - ); + ]; if ($handler) { $name = $handler->adminLabel() . ' ' . $handler->adminSummary(); @@ -187,34 +188,34 @@ public function buildForm(array $form, FormStateInterface $form_state) { $name = '(' . $relationships[$field['relationship']] . ') ' . $name; } - $form['filters'][$id]['name'] = array( + $form['filters'][$id]['name'] = [ '#markup' => $name, - ); + ]; } else { - $form['filters'][$id]['name'] = array('#markup' => $this->t('Broken field @id', array('@id' => $id))); + $form['filters'][$id]['name'] = ['#markup' => $this->t('Broken field @id', ['@id' => $id])]; } - $form['filters'][$id]['removed'] = array( - '#title' => t('Remove @id', array('@id' => $id)), + $form['filters'][$id]['removed'] = [ + '#title' => t('Remove @id', ['@id' => $id]), '#title_display' => 'invisible', '#type' => 'checkbox', '#id' => 'views-removed-' . $id, - '#attributes' => array('class' => array('views-remove-checkbox')), + '#attributes' => ['class' => ['views-remove-checkbox']], '#default_value' => 0, - ); + ]; } $view->getStandardButtons($form, $form_state, 'views_ui_rearrange_filter_form'); - $form['actions']['add_group'] = array( + $form['actions']['add_group'] = [ '#type' => 'submit', '#value' => $this->t('Create new filter group'), '#id' => 'views-add-group', '#group' => 'add', - '#attributes' => array( - 'class' => array('views-add-group'), - ), + '#attributes' => [ + 'class' => ['views-add-group'], + ], '#ajax' => ['url' => NULL], - ); + ]; return $form; } @@ -226,7 +227,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $types = ViewExecutable::getHandlerTypes(); $view = $form_state->get('view'); $display = &$view->getExecutable()->displayHandlers->get($form_state->get('display_id')); - $remember_groups = array(); + $remember_groups = []; if (!empty($view->form_cache)) { $old_fields = $view->form_cache['handlers']; @@ -237,7 +238,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $groups = $form_state->getValue('filter_groups'); // Whatever button was clicked, re-calculate field information. - $new_fields = $order = array(); + $new_fields = $order = []; // Make an array with the weights foreach ($form_state->getValue('filters') as $field => $info) { diff --git a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php index 7d1285f8..377a3d55 100644 --- a/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php +++ b/core/modules/views_ui/src/Form/Ajax/ReorderDisplays.php @@ -40,10 +40,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { 'view' => $view->id(), 'display_id' => $display_id, ]); - $form['view'] = array( + $form['view'] = [ '#type' => 'value', '#value' => $view - ); + ]; $displays = $view->get('display'); $count = count($displays); @@ -56,82 +56,82 @@ public function buildForm(array $form, FormStateInterface $form_state) { return 0; }); - $form['displays'] = array( + $form['displays'] = [ '#type' => 'table', '#id' => 'reorder-displays', - '#header' => array($this->t('Display'), $this->t('Weight'), $this->t('Remove')), + '#header' => [$this->t('Display'), $this->t('Weight'), $this->t('Remove')], '#empty' => $this->t('No displays available.'), - '#tabledrag' => array( - array( + '#tabledrag' => [ + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'weight', - ) - ), + ] + ], '#tree' => TRUE, '#prefix' => '<div class="scroll" data-drupal-views-scroll>', '#suffix' => '</div>', - ); + ]; foreach ($displays as $id => $display) { - $form['displays'][$id] = array( + $form['displays'][$id] = [ '#display' => $display, - '#attributes' => array( + '#attributes' => [ 'id' => 'display-row-' . $id, - ), + ], '#weight' => $display['position'], - ); + ]; // Only make row draggable if it's not the default display. if ($id !== 'default') { $form['displays'][$id]['#attributes']['class'][] = 'draggable'; } - $form['displays'][$id]['title'] = array( + $form['displays'][$id]['title'] = [ '#markup' => $display['display_title'], - ); + ]; - $form['displays'][$id]['weight'] = array( + $form['displays'][$id]['weight'] = [ '#type' => 'weight', '#value' => $display['position'], '#delta' => $count, - '#title' => $this->t('Weight for @display', array('@display' => $display['display_title'])), + '#title' => $this->t('Weight for @display', ['@display' => $display['display_title']]), '#title_display' => 'invisible', - '#attributes' => array( - 'class' => array('weight'), - ), - ); - - $form['displays'][$id]['removed'] = array( - 'checkbox' => array( - '#title' => t('Remove @id', array('@id' => $id)), + '#attributes' => [ + 'class' => ['weight'], + ], + ]; + + $form['displays'][$id]['removed'] = [ + 'checkbox' => [ + '#title' => t('Remove @id', ['@id' => $id]), '#title_display' => 'invisible', '#type' => 'checkbox', '#id' => 'display-removed-' . $id, - '#attributes' => array( - 'class' => array('views-remove-checkbox'), - ), + '#attributes' => [ + 'class' => ['views-remove-checkbox'], + ], '#default_value' => !empty($display['deleted']), - ), - 'link' => array( + ], + 'link' => [ '#type' => 'link', - '#title' => SafeMarkup::format('<span>@text</span>', array('@text' => $this->t('Remove'))), + '#title' => SafeMarkup::format('<span>@text</span>', ['@text' => $this->t('Remove')]), '#url' => Url::fromRoute('<none>'), - '#attributes' => array( + '#attributes' => [ 'id' => 'display-remove-link-' . $id, - 'class' => array('views-button-remove', 'display-remove-link'), + 'class' => ['views-button-remove', 'display-remove-link'], 'alt' => $this->t('Remove this display'), 'title' => $this->t('Remove this display'), - ), - ), + ], + ], '#access' => ($id !== 'default'), - ); + ]; if (!empty($display['deleted'])) { - $form['displays'][$id]['deleted'] = array( + $form['displays'][$id]['deleted'] = [ '#type' => 'value', '#value' => TRUE, - ); + ]; $form['displays'][$id]['#attributes']['class'][] = 'hidden'; } @@ -149,7 +149,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { /** @var $view \Drupal\views_ui\ViewUI */ $view = $form_state->get('view'); - $order = array(); + $order = []; $user_input = $form_state->getUserInput(); foreach ($user_input['displays'] as $display => $info) { diff --git a/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php b/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php index 93bd0498..375766a4 100644 --- a/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php +++ b/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php @@ -108,7 +108,7 @@ public function getForm(ViewEntityInterface $view, $display_id, $js) { unset($view->stack[$key]); if (array_shift($top) != $identifier) { - $view->stack = array(); + $view->stack = []; } } @@ -138,7 +138,7 @@ public function getForm(ViewEntityInterface $view, $display_id, $js) { $form_state = $reflection->newInstanceArgs(array_slice($top, 3, 2))->getFormState($view, $top[2], $form_state->get('ajax')); $form_class = get_class($form_state->getFormObject()); - $form_state->setUserInput(array()); + $form_state->setUserInput([]); $form_url = views_ui_build_form_url($form_state); if (!$form_state->get('ajax')) { return new RedirectResponse($form_url->setAbsolute()->toString()); @@ -234,16 +234,16 @@ protected function ajaxFormWrapper($form_class, FormStateInterface &$form_state) $response->setAttachments($form['#attached']); $display = ''; - $status_messages = array('#type' => 'status_messages'); + $status_messages = ['#type' => 'status_messages']; if ($messages = $renderer->renderRoot($status_messages)) { $display = '<div class="views-messages">' . $messages . '</div>'; } $display .= $output; - $options = array( + $options = [ 'dialogClass' => 'views-ui-dialog js-views-ui-dialog', 'width' => '75%', - ); + ]; $response->addCommand(new OpenModalDialogCommand($title, $display, $options)); diff --git a/core/modules/views_ui/src/Form/BasicSettingsForm.php b/core/modules/views_ui/src/Form/BasicSettingsForm.php index 61501960..bcd53366 100644 --- a/core/modules/views_ui/src/Form/BasicSettingsForm.php +++ b/core/modules/views_ui/src/Form/BasicSettingsForm.php @@ -65,7 +65,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form = parent::buildForm($form, $form_state); $config = $this->config('views.settings'); - $options = array(); + $options = []; foreach ($this->themeHandler->listInfo() as $name => $theme) { if ($theme->status) { $options[$name] = $theme->info['name']; @@ -74,94 +74,94 @@ public function buildForm(array $form, FormStateInterface $form_state) { // This is not currently a fieldset but we may want it to be later, // so this will make it easier to change if we do. - $form['basic'] = array(); + $form['basic'] = []; - $form['basic']['ui_show_master_display'] = array( + $form['basic']['ui_show_master_display'] = [ '#type' => 'checkbox', '#title' => $this->t('Always show the master (default) display'), '#default_value' => $config->get('ui.show.master_display'), - ); + ]; - $form['basic']['ui_show_advanced_column'] = array( + $form['basic']['ui_show_advanced_column'] = [ '#type' => 'checkbox', '#title' => $this->t('Always show advanced display settings'), '#default_value' => $config->get('ui.show.advanced_column'), - ); + ]; - $form['basic']['ui_show_display_embed'] = array( + $form['basic']['ui_show_display_embed'] = [ '#type' => 'checkbox', '#title' => t('Allow embedded displays'), '#description' => t('Embedded displays can be used in code via views_embed_view().'), '#default_value' => $config->get('ui.show.display_embed'), - ); + ]; - $form['basic']['ui_exposed_filter_any_label'] = array( + $form['basic']['ui_exposed_filter_any_label'] = [ '#type' => 'select', '#title' => $this->t('Label for "Any" value on non-required single-select exposed filters'), - '#options' => array('old_any' => '<Any>', 'new_any' => $this->t('- Any -')), + '#options' => ['old_any' => '<Any>', 'new_any' => $this->t('- Any -')], '#default_value' => $config->get('ui.exposed_filter_any_label'), - ); + ]; - $form['live_preview'] = array( + $form['live_preview'] = [ '#type' => 'details', '#title' => $this->t('Live preview settings'), '#open' => TRUE, - ); + ]; - $form['live_preview']['ui_always_live_preview'] = array( + $form['live_preview']['ui_always_live_preview'] = [ '#type' => 'checkbox', '#title' => $this->t('Automatically update preview on changes'), '#default_value' => $config->get('ui.always_live_preview'), - ); + ]; - $form['live_preview']['ui_show_preview_information'] = array( + $form['live_preview']['ui_show_preview_information'] = [ '#type' => 'checkbox', '#title' => $this->t('Show information and statistics about the view during live preview'), '#default_value' => $config->get('ui.show.preview_information'), - ); + ]; - $form['live_preview']['options'] = array( + $form['live_preview']['options'] = [ '#type' => 'container', - '#states' => array( - 'visible' => array( - ':input[name="ui_show_preview_information"]' => array('checked' => TRUE), - ), - ), - ); - - $form['live_preview']['options']['ui_show_sql_query_enabled'] = array( + '#states' => [ + 'visible' => [ + ':input[name="ui_show_preview_information"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['live_preview']['options']['ui_show_sql_query_enabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Show the SQL query'), '#default_value' => $config->get('ui.show.sql_query.enabled'), - ); + ]; - $form['live_preview']['options']['ui_show_sql_query_where'] = array( + $form['live_preview']['options']['ui_show_sql_query_where'] = [ '#type' => 'radios', - '#states' => array( - 'visible' => array( - ':input[name="ui_show_sql_query_enabled"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="ui_show_sql_query_enabled"]' => ['checked' => TRUE], + ], + ], '#title' => t('Show SQL query'), - '#options' => array( + '#options' => [ 'above' => $this->t('Above the preview'), 'below' => $this->t('Below the preview'), - ), + ], '#default_value' => $config->get('ui.show.sql_query.where'), - ); + ]; - $form['live_preview']['options']['ui_show_performance_statistics'] = array( + $form['live_preview']['options']['ui_show_performance_statistics'] = [ '#type' => 'checkbox', '#title' => $this->t('Show performance statistics'), '#default_value' => $config->get('ui.show.performance_statistics'), - ); + ]; - $form['live_preview']['options']['ui_show_additional_queries'] = array( + $form['live_preview']['options']['ui_show_additional_queries'] = [ '#type' => 'checkbox', '#title' => $this->t('Show other queries run during render during live preview'), '#description' => $this->t("Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview."), '#default_value' => $config->get('ui.show.additional_queries'), - ); + ]; return $form; } diff --git a/core/modules/views_ui/src/Form/BreakLockForm.php b/core/modules/views_ui/src/Form/BreakLockForm.php index 12a3e3ef..b73e618c 100644 --- a/core/modules/views_ui/src/Form/BreakLockForm.php +++ b/core/modules/views_ui/src/Form/BreakLockForm.php @@ -61,7 +61,7 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Do you want to break the lock on view %name?', array('%name' => $this->entity->id())); + return $this->t('Do you want to break the lock on view %name?', ['%name' => $this->entity->id()]); } /** @@ -70,11 +70,11 @@ public function getQuestion() { public function getDescription() { $locked = $this->tempStore->getMetadata($this->entity->id()); $account = $this->entityManager->getStorage('user')->load($locked->owner); - $username = array( + $username = [ '#theme' => 'username', '#account' => $account, - ); - return $this->t('By breaking this lock, any unsaved changes made by @user will be lost.', array('@user' => drupal_render($username))); + ]; + return $this->t('By breaking this lock, any unsaved changes made by @user will be lost.', ['@user' => \Drupal::service('renderer')->render($username)]); } /** @@ -96,7 +96,7 @@ public function getConfirmText() { */ public function buildForm(array $form, FormStateInterface $form_state) { if (!$this->tempStore->getMetadata($this->entity->id())) { - $form['message']['#markup'] = $this->t('There is no lock on view %name to break.', array('%name' => $this->entity->id())); + $form['message']['#markup'] = $this->t('There is no lock on view %name to break.', ['%name' => $this->entity->id()]); return $form; } return parent::buildForm($form, $form_state); diff --git a/core/modules/views_ui/src/Tests/AnalyzeTest.php b/core/modules/views_ui/src/Tests/AnalyzeTest.php deleted file mode 100644 index 6cc9203d..00000000 --- a/core/modules/views_ui/src/Tests/AnalyzeTest.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\views\Tests\ViewTestBase; - -/** - * Tests the views analyze system. - * - * @group views_ui - */ -class AnalyzeTest extends ViewTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('views_ui'); - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_view'); - - protected function setUp() { - parent::setUp(); - - $this->enableViewsTestModule(); - - // Add an admin user will full rights; - $this->admin = $this->drupalCreateUser(array('administer views')); - } - - /** - * Tests that analyze works in general. - */ - function testAnalyzeBasic() { - $this->drupalLogin($this->admin); - - $this->drupalGet('admin/structure/views/view/test_view/edit'); - $this->assertLink(t('Analyze view')); - - // This redirects the user to the analyze form. - $this->clickLink(t('Analyze view')); - $this->assertText(t('View analysis')); - - foreach (array('ok', 'warning', 'error') as $type) { - $xpath = $this->xpath('//div[contains(@class, :class)]', array(':class' => $type)); - $this->assertTrue(count($xpath), format_string('Analyse messages with @type found', array('@type' => $type))); - } - - // This redirects the user back to the main views edit page. - $this->drupalPostForm(NULL, array(), t('Ok')); - } - -} diff --git a/core/modules/views_ui/src/Tests/DefaultViewsTest.php b/core/modules/views_ui/src/Tests/DefaultViewsTest.php deleted file mode 100644 index 3b3f2a73..00000000 --- a/core/modules/views_ui/src/Tests/DefaultViewsTest.php +++ /dev/null @@ -1,247 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\Core\Url; -use Drupal\user\Entity\Role; -use Drupal\user\RoleInterface; - -/** - * Tests enabling, disabling, and reverting default views via the listing page. - * - * @group views_ui - */ -class DefaultViewsTest extends UITestBase { - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_view_status', 'test_page_display_menu', 'test_page_display_arguments'); - - - protected function setUp() { - parent::setUp(); - - $this->drupalPlaceBlock('page_title_block'); - } - - /** - * Tests default views. - */ - function testDefaultViews() { - // Make sure the view starts off as disabled (does not appear on the listing - // page). - $edit_href = 'admin/structure/views/view/glossary'; - $this->drupalGet('admin/structure/views'); - // @todo Disabled default views do now appear on the front page. Test this - // behavior with templates instead. - // $this->assertNoLinkByHref($edit_href); - - // Enable the view, and make sure it is now visible on the main listing - // page. - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Enable'), '/glossary/'); - $this->assertUrl('admin/structure/views'); - $this->assertLinkByHref($edit_href); - - // It should not be possible to revert the view yet. - // @todo Figure out how to handle this with the new configuration system. - // $this->assertNoLink(t('Revert')); - // $revert_href = 'admin/structure/views/view/glossary/revert'; - // $this->assertNoLinkByHref($revert_href); - - // Edit the view and change the title. Make sure that the new title is - // displayed. - $new_title = $this->randomMachineName(16); - $edit = array('title' => $new_title); - $this->drupalPostForm('admin/structure/views/nojs/display/glossary/page_1/title', $edit, t('Apply')); - $this->drupalPostForm('admin/structure/views/view/glossary/edit/page_1', array(), t('Save')); - $this->drupalGet('glossary'); - $this->assertResponse(200); - $this->assertText($new_title); - - // Save another view in the UI. - $this->drupalPostForm('admin/structure/views/nojs/display/archive/page_1/title', array(), t('Apply')); - $this->drupalPostForm('admin/structure/views/view/archive/edit/page_1', array(), t('Save')); - - // Check there is an enable link. i.e. The view has not been enabled after - // editing. - $this->drupalGet('admin/structure/views'); - $this->assertLinkByHref('admin/structure/views/view/archive/enable'); - // Enable it again so it can be tested for access permissions. - $this->clickViewsOperationLink(t('Enable'), '/archive/'); - - // It should now be possible to revert the view. Do that, and make sure the - // view title we added above no longer is displayed. - // $this->drupalGet('admin/structure/views'); - // $this->assertLink(t('Revert')); - // $this->assertLinkByHref($revert_href); - // $this->drupalPostForm($revert_href, array(), t('Revert')); - // $this->drupalGet('glossary'); - // $this->assertNoText($new_title); - - // Duplicate the view and check that the normal schema of duplicated views is used. - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Duplicate'), '/glossary'); - $edit = array( - 'id' => 'duplicate_of_glossary', - ); - $this->assertTitle(t('Duplicate of @label | @site-name', array('@label' => 'Glossary', '@site-name' => $this->config('system.site')->get('name')))); - $this->drupalPostForm(NULL, $edit, t('Duplicate')); - $this->assertUrl('admin/structure/views/view/duplicate_of_glossary', array(), 'The normal duplicating name schema is applied.'); - - // Duplicate a view and set a custom name. - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Duplicate'), '/glossary'); - $random_name = strtolower($this->randomMachineName()); - $this->drupalPostForm(NULL, array('id' => $random_name), t('Duplicate')); - $this->assertUrl("admin/structure/views/view/$random_name", array(), 'The custom view name got saved.'); - - // Now disable the view, and make sure it stops appearing on the main view - // listing page but instead goes back to displaying on the disabled views - // listing page. - // @todo Test this behavior with templates instead. - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Disable'), '/glossary/'); - // $this->assertUrl('admin/structure/views'); - // $this->assertNoLinkByHref($edit_href); - // The easiest way to verify it appears on the disabled views listing page - // is to try to click the "enable" link from there again. - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Enable'), '/glossary/'); - $this->assertUrl('admin/structure/views'); - $this->assertLinkByHref($edit_href); - - // Clear permissions for anonymous users to check access for default views. - Role::load(RoleInterface::ANONYMOUS_ID)->revokePermission('access content')->save(); - - // Test the default views disclose no data by default. - $this->drupalLogout(); - $this->drupalGet('glossary'); - $this->assertResponse(403); - $this->drupalGet('archive'); - $this->assertResponse(403); - - // Test deleting a view. - $this->drupalLogin($this->fullAdminUser); - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Delete'), '/glossary/'); - // Submit the confirmation form. - $this->drupalPostForm(NULL, array(), t('Delete')); - // Ensure the view is no longer listed. - $this->assertUrl('admin/structure/views'); - $this->assertNoLinkByHref($edit_href); - // Ensure the view is no longer available. - $this->drupalGet($edit_href); - $this->assertResponse(404); - $this->assertText('Page not found'); - - // Delete all duplicated Glossary views. - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Delete'), 'duplicate_of_glossary'); - // Submit the confirmation form. - $this->drupalPostForm(NULL, array(), t('Delete')); - - $this->drupalGet('glossary'); - $this->assertResponse(200); - - $this->drupalGet('admin/structure/views'); - $this->clickViewsOperationLink(t('Delete'), $random_name); - // Submit the confirmation form. - $this->drupalPostForm(NULL, array(), t('Delete')); - $this->drupalGet('glossary'); - $this->assertResponse(404); - $this->assertText('Page not found'); - } - - /** - * Tests that enabling views moves them to the correct table. - */ - function testSplitListing() { - // Build a re-usable xpath query. - $xpath = '//div[@id="views-entity-list"]/div[@class = :status]/table//tr[@title = :title]'; - $arguments = array( - ':status' => 'views-list-section enabled', - ':title' => t('Machine name: test_view_status'), - ); - - $this->drupalGet('admin/structure/views'); - - $elements = $this->xpath($xpath, $arguments); - $this->assertIdentical(count($elements), 0, 'A disabled view is not found in the enabled views table.'); - - $arguments[':status'] = 'views-list-section disabled'; - $elements = $this->xpath($xpath, $arguments); - $this->assertIdentical(count($elements), 1, 'A disabled view is found in the disabled views table.'); - - // Enable the view. - $this->clickViewsOperationLink(t('Enable'), '/test_view_status/'); - - $elements = $this->xpath($xpath, $arguments); - $this->assertIdentical(count($elements), 0, 'After enabling a view, it is not found in the disabled views table.'); - - $arguments[':status'] = 'views-list-section enabled'; - $elements = $this->xpath($xpath, $arguments); - $this->assertIdentical(count($elements), 1, 'After enabling a view, it is found in the enabled views table.'); - - // Attempt to disable the view by path directly, with no token. - $this->drupalGet('admin/structure/views/view/test_view_status/disable'); - $this->assertResponse(403); - } - - /** - * Tests that page displays show the correct path. - */ - public function testPathDestination() { - $this->drupalGet('admin/structure/views'); - - // Check that links to views on default tabs are rendered correctly. - $this->assertLinkByHref('test_page_display_menu'); - $this->assertNoLinkByHref('test_page_display_menu/default'); - $this->assertLinkByHref('test_page_display_menu/local'); - - // Check that a dynamic path is shown as text. - $this->assertRaw('test_route_with_suffix/%/suffix'); - $this->assertNoLinkByHref(Url::fromUri('base:test_route_with_suffix/%/suffix')->toString()); - } - - /** - * Click a link to perform an operation on a view. - * - * In general, we expect lots of links titled "enable" or "disable" on the - * various views listing pages, and they might have tokens in them. So we - * need special code to find the correct one to click. - * - * @param $label - * Text between the anchor tags of the desired link. - * @param $unique_href_part - * A unique string that is expected to occur within the href of the desired - * link. For example, if the link URL is expected to look like - * "admin/structure/views/view/glossary/*", then "/glossary/" could be - * passed as the expected unique string. - * - * @return - * The page content that results from clicking on the link, or FALSE on - * failure. Failure also results in a failed assertion. - */ - function clickViewsOperationLink($label, $unique_href_part) { - $links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label)); - foreach ($links as $link_index => $link) { - $position = strpos($link['href'], $unique_href_part); - if ($position !== FALSE) { - $index = $link_index; - break; - } - } - $this->assertTrue(isset($index), format_string('Link to "@label" containing @part found.', array('@label' => $label, '@part' => $unique_href_part))); - if (isset($index)) { - return $this->clickLink($label, $index); - } - else { - return FALSE; - } - } - -} diff --git a/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php b/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php deleted file mode 100644 index fbacb145..00000000 --- a/core/modules/views_ui/src/Tests/DisplayAttachmentTest.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\views\Views; - -/** - * Tests the UI for the attachment display plugin. - * - * @group views_ui - * @see \Drupal\views\Plugin\views\display\Attachment - */ -class DisplayAttachmentTest extends UITestBase { - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_attachment_ui'); - - /** - * Tests the attachment UI. - */ - public function testAttachmentUI() { - $this->drupalGet('admin/structure/views/view/test_attachment_ui/edit/attachment_1'); - $this->assertText(t('Not defined'), 'The right text appears if there is no attachment selection yet.'); - - $attachment_display_url = 'admin/structure/views/nojs/display/test_attachment_ui/attachment_1/displays'; - $this->drupalGet($attachment_display_url); - // Display labels should be escaped. - $this->assertEscaped('<em>Page</em>'); - - foreach (array('default', 'page-1') as $display_id) { - $this->assertNoFieldChecked("edit-displays-$display_id", format_string('Make sure the @display_id can be marked as attached', array('@display_id' => $display_id))); - } - - // Save the attachments and test the value on the view. - $this->drupalPostForm($attachment_display_url, array('displays[page_1]' => 1), t('Apply')); - // Options summary should be escaped. - $this->assertEscaped('<em>Page</em>'); - $this->assertNoRaw('<em>Page</em>'); - $result = $this->xpath('//a[@id = :id]', array(':id' => 'views-attachment-1-displays')); - $this->assertEqual($result[0]->attributes()->title, t('Page')); - $this->drupalPostForm(NULL, array(), t('Save')); - - $view = Views::getView('test_attachment_ui'); - $view->initDisplay(); - $this->assertEqual(array_keys(array_filter($view->displayHandlers->get('attachment_1')->getOption('displays'))), array('page_1'), 'The attached displays got saved as expected'); - - $this->drupalPostForm($attachment_display_url, array('displays[default]' => 1, 'displays[page_1]' => 1), t('Apply')); - $result = $this->xpath('//a[@id = :id]', array(':id' => 'views-attachment-1-displays')); - $this->assertEqual($result[0]->attributes()->title, t('Multiple displays')); - $this->drupalPostForm(NULL, array(), t('Save')); - - $view = Views::getView('test_attachment_ui'); - $view->initDisplay(); - $this->assertEqual(array_keys($view->displayHandlers->get('attachment_1')->getOption('displays')), array('default', 'page_1'), 'The attached displays got saved as expected'); - } - -} diff --git a/core/modules/views_ui/src/Tests/DisplayTest.php b/core/modules/views_ui/src/Tests/DisplayTest.php deleted file mode 100644 index 7f5f1254..00000000 --- a/core/modules/views_ui/src/Tests/DisplayTest.php +++ /dev/null @@ -1,331 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\Component\Serialization\Json; -use Drupal\Component\Utility\SafeMarkup; -use Drupal\Core\Template\Attribute; -use Drupal\views\Entity\View; -use Drupal\views\Views; - -/** - * Tests the display UI. - * - * @group views_ui - */ -class DisplayTest extends UITestBase { - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_display'); - - /** - * Modules to enable - * - * @var array - */ - public static $modules = array('contextual'); - - /** - * Tests adding a display. - */ - public function testAddDisplay() { - $view = $this->randomView(); - $this->assertNoText('Block'); - $this->assertNoText('Block 2'); - - $this->drupalPostForm(NULL, [], t('Add @display', ['@display' => 'Block'])); - $this->assertText('Block'); - $this->assertNoText('Block 2'); - - // Views has special form handling in views_ui_form_button_was_clicked() - // to be able to change the submit button text via JS, this simulates what - // the JS is doing. - $this->drupalPostForm(NULL, [], NULL, [], [], NULL, '&op=Block'); - $this->assertText('Block'); - $this->assertText('Block 2'); - } - - /** - * Tests reordering of displays. - */ - public function testReorderDisplay() { - $view = array( - 'block[create]' => TRUE - ); - $view = $this->randomView($view); - - $this->clickLink(t('Reorder displays')); - $this->assertTrue($this->xpath('//tr[@id="display-row-default"]'), 'Make sure the default display appears on the reorder listing'); - $this->assertTrue($this->xpath('//tr[@id="display-row-page_1"]'), 'Make sure the page display appears on the reorder listing'); - $this->assertTrue($this->xpath('//tr[@id="display-row-block_1"]'), 'Make sure the block display appears on the reorder listing'); - - // Ensure the view displays are in the expected order in configuration. - $expected_display_order = array('default', 'block_1', 'page_1'); - $this->assertEqual(array_keys(Views::getView($view['id'])->storage->get('display')), $expected_display_order, 'The correct display names are present.'); - // Put the block display in front of the page display. - $edit = array( - 'displays[page_1][weight]' => 2, - 'displays[block_1][weight]' => 1 - ); - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); - - $view = Views::getView($view['id']); - $displays = $view->storage->get('display'); - $this->assertEqual($displays['default']['position'], 0, 'Make sure the master display comes first.'); - $this->assertEqual($displays['block_1']['position'], 1, 'Make sure the block display comes before the page display.'); - $this->assertEqual($displays['page_1']['position'], 2, 'Make sure the page display comes after the block display.'); - - // Ensure the view displays are in the expected order in configuration. - $this->assertEqual(array_keys($view->storage->get('display')), $expected_display_order, 'The correct display names are present.'); - } - - /** - * Tests disabling of a display. - */ - public function testDisableDisplay() { - $view = $this->randomView(); - $path_prefix = 'admin/structure/views/view/' . $view['id'] . '/edit'; - - $this->drupalGet($path_prefix); - $this->assertFalse($this->xpath('//div[contains(@class, :class)]', array(':class' => 'views-display-disabled')), 'Make sure the disabled display css class does not appear after initial adding of a view.'); - - $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', '', 'Make sure the disable button is visible.'); - $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', '', 'Make sure the enable button is not visible.'); - $this->drupalPostForm(NULL, array(), 'Disable Page'); - $this->assertTrue($this->xpath('//div[contains(@class, :class)]', array(':class' => 'views-display-disabled')), 'Make sure the disabled display css class appears once the display is marked as such.'); - - $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', '', 'Make sure the disable button is not visible.'); - $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', '', 'Make sure the enable button is visible.'); - $this->drupalPostForm(NULL, array(), 'Enable Page'); - $this->assertFalse($this->xpath('//div[contains(@class, :class)]', array(':class' => 'views-display-disabled')), 'Make sure the disabled display css class does not appears once the display is enabled again.'); - } - - /** - * Tests views_ui_views_plugins_display_alter is altering plugin definitions. - */ - public function testDisplayPluginsAlter() { - $definitions = Views::pluginManager('display')->getDefinitions(); - - $expected = array( - 'route_name' => 'entity.view.edit_form', - 'route_parameters_names' => array('view' => 'id'), - ); - - // Test the expected views_ui array exists on each definition. - foreach ($definitions as $definition) { - $this->assertIdentical($definition['contextual links']['entity.view.edit_form'], $expected, 'Expected views_ui array found in plugin definition.'); - } - } - - /** - * Tests display areas. - */ - public function testDisplayAreas() { - // Show the advanced column. - $this->config('views.settings')->set('ui.show.advanced_column', TRUE)->save(); - - // Add a new data display to the view. - $view = Views::getView('test_display'); - $view->storage->addDisplay('display_no_area_test'); - $view->save(); - - $this->drupalGet('admin/structure/views/view/test_display/edit/display_no_area_test_1'); - - $areas = array( - 'header', - 'footer', - 'empty', - ); - - // Assert that the expected text is found in each area category. - foreach ($areas as $type) { - $element = $this->xpath('//div[contains(@class, :class)]/div', array(':class' => $type)); - $this->assertEqual((string) $element[0], SafeMarkup::format('The selected display type does not use @type plugins', array('@type' => $type))); - } - } - - /** - * Tests the link-display setting. - */ - public function testLinkDisplay() { - // Test setting the link display in the UI form. - $path = 'admin/structure/views/view/test_display/edit/block_1'; - $link_display_path = 'admin/structure/views/nojs/display/test_display/block_1/link_display'; - - // Test the link text displays 'None' and not 'Block 1' - $this->drupalGet($path); - $result = $this->xpath("//a[contains(@href, :path)]", array(':path' => $link_display_path)); - $this->assertEqual($result[0], t('None'), 'Make sure that the link option summary shows "None" by default.'); - - $this->drupalGet($link_display_path); - $this->assertFieldChecked('edit-link-display-0'); - - // Test the default radio option on the link display form. - $this->drupalPostForm($link_display_path, array('link_display' => 'page_1'), t('Apply')); - // The form redirects to the master display. - $this->drupalGet($path); - - $result = $this->xpath("//a[contains(@href, :path)]", array(':path' => $link_display_path)); - $this->assertEqual($result[0], 'Page', 'Make sure that the link option summary shows the right linked display.'); - - $this->drupalPostForm($link_display_path, array('link_display' => 'custom_url', 'link_url' => 'a-custom-url'), t('Apply')); - // The form redirects to the master display. - $this->drupalGet($path); - - $this->assertLink(t('Custom URL'), 0, 'The link option has custom URL as summary.'); - - // Test the default link_url value for new display - $this->drupalPostForm(NULL, array(), t('Add Block')); - $this->assertUrl('admin/structure/views/view/test_display/edit/block_2'); - $this->clickLink(t('Custom URL')); - $this->assertFieldByName('link_url', 'a-custom-url'); - } - - /** - * Tests contextual links on Views page displays. - */ - public function testPageContextualLinks() { - $this->drupalLogin($this->drupalCreateUser(array('administer views', 'access contextual links'))); - $view = View::load('test_display'); - $view->enable()->save(); - $this->container->get('router.builder')->rebuildIfNeeded(); - - // When no "main content" block is placed, we find a contextual link - // placeholder for editing just the view. - $this->drupalGet('test-display'); - $id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en'; - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() - $this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); - - // Get server-rendered contextual links. - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks() - $post = array('ids[0]' => $id); - $response = $this->drupalPostWithFormat('contextual/render', 'json', $post, array('query' => array('destination' => 'test-display'))); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical($json[$id], '<ul class="contextual-links"><li class="entityviewedit-form"><a href="' . base_path() . 'admin/structure/views/view/test_display/edit/page_1">Edit view</a></li></ul>'); - - // When a "main content" is placed, we still find a contextual link - // placeholder for editing just the view (not the main content block). - // @see system_block_view_system_main_block_alter() - $this->drupalPlaceBlock('system_main_block', ['id' => 'main_content']); - $this->drupalGet('test-display'); - $id = 'entity.view.edit_form:view=test_display:location=page&name=test_display&display_id=page_1&langcode=en'; - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() - $this->assertRaw('<div' . new Attribute(array('data-contextual-id' => $id)) . '></div>', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); - } - - /** - * Tests that the view status is correctly reflected on the edit form. - */ - public function testViewStatus() { - $view = $this->randomView(); - $id = $view['id']; - - // The view should initially have the enabled class on it's form wrapper. - $this->drupalGet('admin/structure/views/view/' . $id); - $elements = $this->xpath('//div[contains(@class, :edit) and contains(@class, :status)]', array(':edit' => 'views-edit-view', ':status' => 'enabled')); - $this->assertTrue($elements, 'The enabled class was found on the form wrapper'); - - $view = Views::getView($id); - $view->storage->disable()->save(); - - $this->drupalGet('admin/structure/views/view/' . $id); - $elements = $this->xpath('//div[contains(@class, :edit) and contains(@class, :status)]', array(':edit' => 'views-edit-view', ':status' => 'disabled')); - $this->assertTrue($elements, 'The disabled class was found on the form wrapper.'); - } - - /** - * Ensures that no XSS is possible for buttons. - */ - public function testDisplayTitleInButtonsXss() { - $xss_markup = '"><script>alert(123)</script>'; - $view = $this->randomView(); - $view = View::load($view['id']); - \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.master_display', TRUE)->save(); - - foreach ([$xss_markup, '"><script>alert(123)</script>'] as $input) { - $display =& $view->getDisplay('page_1'); - $display['display_title'] = $input; - $view->save(); - - $this->drupalGet("admin/structure/views/view/{$view->id()}"); - $escaped = views_ui_truncate($input, 25); - $this->assertEscaped($escaped); - $this->assertNoRaw($xss_markup); - - $this->drupalGet("admin/structure/views/view/{$view->id()}/edit/page_1"); - $this->assertEscaped("View $escaped"); - $this->assertNoRaw("View $xss_markup"); - $this->assertEscaped("Duplicate $escaped"); - $this->assertNoRaw("Duplicate $xss_markup"); - $this->assertEscaped("Delete $escaped"); - $this->assertNoRaw("Delete $xss_markup"); - } - } - - /** - * Tests the action links on the edit display UI. - */ - public function testActionLinks() { - // Change the display title of a display so it contains characters that will - // be escaped when rendered. - $display_title = "'<test>'"; - $this->drupalGet('admin/structure/views/view/test_display'); - $display_title_path = 'admin/structure/views/nojs/display/test_display/block_1/display_title'; - $this->drupalPostForm($display_title_path, array('display_title' => $display_title), t('Apply')); - - // Ensure that the title is escaped as expected. - $this->assertEscaped($display_title); - $this->assertNoRaw($display_title); - - // Ensure that the dropdown buttons are displayed correctly. - $this->assertFieldByXpath('//input[@type="submit"]', 'Duplicate ' . $display_title); - $this->assertFieldByXpath('//input[@type="submit"]', 'Delete ' . $display_title); - $this->assertFieldByXpath('//input[@type="submit"]', 'Disable ' . $display_title); - $this->assertNoFieldByXpath('//input[@type="submit"]', 'Enable ' . $display_title); - - // Disable the display so we can test the rendering of the "Enable" button. - $this->drupalPostForm(NULL, NULL, 'Disable ' . $display_title); - $this->assertFieldByXpath('//input[@type="submit"]', 'Enable ' . $display_title); - $this->assertNoFieldByXpath('//input[@type="submit"]', 'Disable ' . $display_title); - - // Ensure that the title is escaped as expected. - $this->assertEscaped($display_title); - $this->assertNoRaw($display_title); - } - - /** - * Tests that the override option is hidden when it's not needed. - */ - public function testHideDisplayOverride() { - // Test that the override option appears with two displays. - $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); - $this->assertText('All displays'); - - // Remove a display and test if the override option is hidden. - $this->drupalPostForm('admin/structure/views/view/test_display/edit/block_1', [], t('Delete @display', ['@display' => 'Block'])); - $this->drupalPostForm(NULL, [], t('Save')); - - $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); - $this->assertNoText('All displays'); - - // Test that the override option is shown when display master is on. - \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.master_display', TRUE)->save(); - $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); - $this->assertText('All displays'); - - // Test that the override option is shown if the current display is - // overridden so that the option to revert is available. - $this->drupalPostForm(NULL, ['override[dropdown]' => 'page_1'], t('Apply')); - \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.master_display', FALSE)->save(); - $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); - $this->assertText('Revert to default'); - } - -} diff --git a/core/modules/views_ui/src/Tests/DuplicateTest.php b/core/modules/views_ui/src/Tests/DuplicateTest.php deleted file mode 100644 index a6948f00..00000000 --- a/core/modules/views_ui/src/Tests/DuplicateTest.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -/** - * Tests the UI for view duplicate tool. - * - * @group views_ui - */ -class DuplicateTest extends UITestBase { - - protected function setUp() { - parent::setUp(); - - $this->drupalPlaceBlock('page_title_block'); - } - - /** - * Checks if duplicated view exists and has correct label. - */ - public function testDuplicateView() { - - // Create random view. - $random_view = $this->randomView(); - - // Initialize array for duplicated view. - $view = array(); - - // Generate random label and id for new view. - $view['label'] = $this->randomMachineName(255); - $view['id'] = strtolower($this->randomMachineName(128)); - - // Duplicate view. - $this->drupalPostForm('admin/structure/views/view/' . $random_view['id'] . '/duplicate', $view, t('Duplicate')); - - // Assert that the page url is correct. - $this->assertUrl('admin/structure/views/view/' . $view['id'], array(), 'Make sure the view saving was successful and the browser got redirected to the edit page.'); - - // Assert that the page title is correctly displayed. - $this->assertText($view['label']); - } - -} diff --git a/core/modules/views_ui/src/Tests/ExposedFormUITest.php b/core/modules/views_ui/src/Tests/ExposedFormUITest.php deleted file mode 100644 index 66280b1b..00000000 --- a/core/modules/views_ui/src/Tests/ExposedFormUITest.php +++ /dev/null @@ -1,268 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\views\Entity\View; - -/** - * Tests exposed forms UI functionality. - * - * @group views_ui - */ -class ExposedFormUITest extends UITestBase { - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_exposed_admin_ui'); - - /** - * {@inheritdoc} - */ - public static $modules = array('node', 'views_ui', 'block', 'taxonomy', 'field_ui', 'datetime'); - - /** - * Array of error message strings raised by the grouped form. - * - * @var array - * - * @see FilterPluginBase::buildGroupValidate - */ - protected $groupFormUiErrors = []; - - protected function setUp() { - parent::setUp(); - - $this->drupalCreateContentType(array('type' => 'article')); - $this->drupalCreateContentType(array('type' => 'page')); - - // Create some random nodes. - for ($i = 0; $i < 5; $i++) { - $this->drupalCreateNode(); - } - - // Error strings used in the grouped filter form validation. - $this->groupFormUiErrors['missing_value'] = t('A value is required if the label for this item is defined.'); - $this->groupFormUiErrors['missing_title'] = t('A label is required if the value for this item is defined.'); - $this->groupFormUiErrors['missing_title_empty_operator'] = t('A label is required for the specified operator.'); - } - - /** - * Tests the admin interface of exposed filter and sort items. - */ - function testExposedAdminUi() { - $edit = array(); - - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - // Be sure that the button is called exposed. - $this->helperButtonHasLabel('edit-options-expose-button-button', t('Expose filter')); - - // The first time the filter UI is displayed, the operator and the - // value forms should be shown. - $this->assertFieldById('edit-options-operator-in', '', 'Operator In exists'); - $this->assertFieldById('edit-options-operator-not-in', '', 'Operator Not In exists'); - $this->assertFieldById('edit-options-value-page', '', 'Checkbox for Page exists'); - $this->assertFieldById('edit-options-value-article', '', 'Checkbox for Article exists'); - - // Click the Expose filter button. - $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', $edit, t('Expose filter')); - // Check the label of the expose button. - $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide filter')); - - // After exposing the filter, Operator and Value should be still here. - $this->assertFieldById('edit-options-operator-in', '', 'Operator In exists'); - $this->assertFieldById('edit-options-operator-not-in', '', 'Operator Not In exists'); - $this->assertFieldById('edit-options-value-page', '', 'Checkbox for Page exists'); - $this->assertFieldById('edit-options-value-article', '', 'Checkbox for Article exists'); - - // Check the validations of the filter handler. - $edit = array(); - $edit['options[expose][identifier]'] = ''; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertText(t('The identifier is required if the filter is exposed.')); - - $edit = array(); - $edit['options[expose][identifier]'] = 'value'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertText(t('This identifier is not allowed.')); - - // Now check the sort criteria. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/sort/created'); - $this->helperButtonHasLabel('edit-options-expose-button-button', t('Expose sort')); - $this->assertNoFieldById('edit-options-expose-label', '', 'Make sure no label field is shown'); - - // Un-expose the filter. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - $this->drupalPostForm(NULL, array(), t('Hide filter')); - - // After Un-exposing the filter, Operator and Value should be shown again. - $this->assertFieldById('edit-options-operator-in', '', 'Operator In exists after hide filter'); - $this->assertFieldById('edit-options-operator-not-in', '', 'Operator Not In exists after hide filter'); - $this->assertFieldById('edit-options-value-page', '', 'Checkbox for Page exists after hide filter'); - $this->assertFieldById('edit-options-value-article', '', 'Checkbox for Article exists after hide filter'); - - // Click the Expose sort button. - $edit = array(); - $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/sort/created', $edit, t('Expose sort')); - // Check the label of the expose button. - $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide sort')); - $this->assertFieldById('edit-options-expose-label', '', 'Make sure a label field is shown'); - - // Test adding a new exposed sort criteria. - $view_id = $this->randomView()['id']; - $this->drupalGet("admin/structure/views/nojs/add-handler/$view_id/default/sort"); - $this->drupalPostForm(NULL, ['name[node_field_data.created]' => 1], t('Add and configure @handler', ['@handler' => t('sort criteria')])); - $this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'ASC', 'The default order is set.'); - // Change the order and expose the sort. - $this->drupalPostForm(NULL, ['options[order]' => 'DESC'], t('Apply')); - $this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/sort/created", [], t('Expose sort')); - $this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'DESC'); - $this->assertFieldByName('options[expose][label]', 'Authored on', 'The default label is set.'); - // Change the label and save the view. - $edit = ['options[expose][label]' => $this->randomString()]; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->drupalPostForm(NULL, [], t('Save')); - // Check that the values were saved. - $display = View::load($view_id)->getDisplay('default'); - $this->assertTrue($display['display_options']['sorts']['created']['exposed']); - $this->assertEqual($display['display_options']['sorts']['created']['expose'], ['label' => $edit['options[expose][label]']]); - $this->assertEqual($display['display_options']['sorts']['created']['order'], 'DESC'); - } - - /** - * Tests the admin interface of exposed grouped filters. - */ - function testGroupedFilterAdminUi() { - $edit = array(); - - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - - // Click the Expose filter button. - $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', $edit, t('Expose filter')); - // Check the label of the grouped filters button. - $this->helperButtonHasLabel('edit-options-group-button-button', t('Grouped filters')); - - // Click the Grouped Filters button. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - $this->drupalPostForm(NULL, array(), t('Grouped filters')); - - // After click on 'Grouped Filters', the standard operator and value should - // not be displayed. - $this->assertNoFieldById('edit-options-operator-in', '', 'Operator In not exists'); - $this->assertNoFieldById('edit-options-operator-not-in', '', 'Operator Not In not exists'); - $this->assertNoFieldById('edit-options-value-page', '', 'Checkbox for Page not exists'); - $this->assertNoFieldById('edit-options-value-article', '', 'Checkbox for Article not exists'); - - // Check that after click on 'Grouped Filters', a new button is shown to - // add more items to the list. - $this->helperButtonHasLabel('edit-options-group-info-add-group', t('Add another item')); - - // Validate a single entry for a grouped filter. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - $edit = array(); - $edit["options[group_info][group_items][1][title]"] = 'Is Article'; - $edit["options[group_info][group_items][1][value][article]"] = 'article'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default'); - $this->assertNoGroupedFilterErrors(); - - // Validate multiple entries for grouped filters. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - $edit = array(); - $edit["options[group_info][group_items][1][title]"] = 'Is Article'; - $edit["options[group_info][group_items][1][value][article]"] = 'article'; - $edit["options[group_info][group_items][2][title]"] = 'Is Page'; - $edit["options[group_info][group_items][2][value][page]"] = 'page'; - $edit["options[group_info][group_items][3][title]"] = 'Is Page and Article'; - $edit["options[group_info][group_items][3][value][article]"] = 'article'; - $edit["options[group_info][group_items][3][value][page]"] = 'page'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', array(), 'Correct validation of the node type filter.'); - $this->assertNoGroupedFilterErrors(); - - // Validate an "is empty" filter -- title without value is valid. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/body_value'); - $edit = array(); - $edit["options[group_info][group_items][1][title]"] = 'No body'; - $edit["options[group_info][group_items][1][operator]"] = 'empty'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', array(), 'The "empty" operator validates correctly.'); - $this->assertNoGroupedFilterErrors(); - - // Ensure the string "0" can be used as a value for numeric filters. - $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_exposed_admin_ui/default/filter', array('name[node_field_data.nid]' => TRUE), t('Add and configure @handler', array('@handler' => t('filter criteria')))); - $this->drupalPostForm(NULL, array(), t('Expose filter')); - $this->drupalPostForm(NULL, array(), t('Grouped filters')); - $edit = array(); - $edit['options[group_info][group_items][1][title]'] = 'Testing zero'; - $edit['options[group_info][group_items][1][operator]'] = '>'; - $edit['options[group_info][group_items][1][value][value]'] = '0'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', array(), 'A string "0" is a valid value.'); - $this->assertNoGroupedFilterErrors(); - - // Ensure "between" filters validate correctly. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/nid'); - $edit['options[group_info][group_items][1][title]'] = 'ID between test'; - $edit['options[group_info][group_items][1][operator]'] = 'between'; - $edit['options[group_info][group_items][1][value][min]'] = '0'; - $edit['options[group_info][group_items][1][value][max]'] = '10'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', array(), 'The "between" filter validates correctly.'); - $this->assertNoGroupedFilterErrors(); - } - - public function testGroupedFilterAdminUiErrors() { - // Select the empty operator without a title specified. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/body_value'); - $edit = array(); - $edit["options[group_info][group_items][1][title]"] = ''; - $edit["options[group_info][group_items][1][operator]"] = 'empty'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertText($this->groupFormUiErrors['missing_title_empty_operator']); - - // Specify a title without a value. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', [], t('Expose filter')); - $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', [], t('Grouped filters')); - $edit = array(); - $edit["options[group_info][group_items][1][title]"] = 'Is Article'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertText($this->groupFormUiErrors['missing_value']); - - // Specify a value without a title. - $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); - $edit = array(); - $edit["options[group_info][group_items][1][title]"] = ''; - $edit["options[group_info][group_items][1][value][article]"] = 'article'; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->assertText($this->groupFormUiErrors['missing_title']); - } - - /** - * Asserts that there are no Grouped Filters errors. - * - * @param string $message - * The assert message. - * @param string $group - * The assertion group. - * - * @return bool - * Result of the assertion. - */ - protected function assertNoGroupedFilterErrors($message = '', $group = 'Other') { - foreach ($this->groupFormUiErrors as $error) { - $err_message = $message; - if (empty($err_message)) { - $err_message = "Verify that '$error' is not in the HTML output."; - } - if (empty($message)) { - return $this->assertNoRaw($error, $err_message, $group); - } - } - return TRUE; - } - -} diff --git a/core/modules/views_ui/src/Tests/FilterNumericWebTest.php b/core/modules/views_ui/src/Tests/FilterNumericWebTest.php deleted file mode 100644 index 9182ca9d..00000000 --- a/core/modules/views_ui/src/Tests/FilterNumericWebTest.php +++ /dev/null @@ -1,112 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\config\Tests\SchemaCheckTestTrait; - -/** - * Tests the numeric filter UI. - * - * @group views_ui - * @see \Drupal\views\Plugin\views\filter\NumericFilter - */ -class FilterNumericWebTest extends UITestBase { - use SchemaCheckTestTrait; - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_view'); - - /** - * Tests the filter numeric UI. - */ - public function testFilterNumericUI() { - $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_view/default/filter', array('name[views_test_data.age]' => TRUE), t('Add and configure @handler', array('@handler' => t('filter criteria')))); - - $this->drupalPostForm(NULL, array(), t('Expose filter')); - $this->drupalPostForm(NULL, array(), t('Grouped filters')); - - $edit = array(); - $edit['options[group_info][group_items][1][title]'] = 'Old'; - $edit['options[group_info][group_items][1][operator]'] = '>'; - $edit['options[group_info][group_items][1][value][value]'] = 27; - $edit['options[group_info][group_items][2][title]'] = 'Young'; - $edit['options[group_info][group_items][2][operator]'] = '<='; - $edit['options[group_info][group_items][2][value][value]'] = 27; - $edit['options[group_info][group_items][3][title]'] = 'From 26 to 28'; - $edit['options[group_info][group_items][3][operator]'] = 'between'; - $edit['options[group_info][group_items][3][value][min]'] = 26; - $edit['options[group_info][group_items][3][value][max]'] = 28; - - $this->drupalPostForm(NULL, $edit, t('Apply')); - - $this->drupalGet('admin/structure/views/nojs/handler/test_view/default/filter/age'); - foreach ($edit as $name => $value) { - $this->assertFieldByName($name, $value); - } - - $this->drupalPostForm('admin/structure/views/view/test_view', array(), t('Save')); - $this->assertConfigSchemaByName('views.view.test_view'); - - // Test that the exposed filter works as expected. - $this->drupalPostForm(NULL, array(), t('Update preview')); - $this->assertText('John'); - $this->assertText('Paul'); - $this->assertText('Ringo'); - $this->assertText('George'); - $this->assertText('Meredith'); - $this->drupalPostForm(NULL, array('age' => '2'), t('Update preview')); - $this->assertText('John'); - $this->assertText('Paul'); - $this->assertNoText('Ringo'); - $this->assertText('George'); - $this->assertNoText('Meredith'); - - // Change the filter to a single filter to test the schema when the operator - // is not exposed. - $this->drupalPostForm('admin/structure/views/nojs/handler/test_view/default/filter/age', array(), t('Single filter')); - $edit = array(); - $edit['options[value][value]'] = 25; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->drupalPostForm('admin/structure/views/view/test_view', array(), t('Save')); - $this->assertConfigSchemaByName('views.view.test_view'); - - // Test that the filter works as expected. - $this->drupalPostForm(NULL, array(), t('Update preview')); - $this->assertText('John'); - $this->assertNoText('Paul'); - $this->assertNoText('Ringo'); - $this->assertNoText('George'); - $this->assertNoText('Meredith'); - $this->drupalPostForm(NULL, array('age' => '26'), t('Update preview')); - $this->assertNoText('John'); - $this->assertText('Paul'); - $this->assertNoText('Ringo'); - $this->assertNoText('George'); - $this->assertNoText('Meredith'); - - // Change the filter to a 'between' filter to test if the label and - // description are set for the 'minimum' filter element. - $this->drupalGet('admin/structure/views/nojs/handler/test_view/default/filter/age'); - $edit = array(); - $edit['options[expose][label]'] = 'Age between'; - $edit['options[expose][description]'] = 'Description of the exposed filter'; - $edit['options[operator]'] = 'between'; - $edit['options[value][min]'] = 26; - $edit['options[value][max]'] = 28; - $this->drupalPostForm(NULL, $edit, t('Apply')); - $this->drupalPostForm('admin/structure/views/view/test_view', array(), t('Save')); - $this->assertConfigSchemaByName('views.view.test_view'); - - $this->drupalPostForm(NULL, array(), t('Update preview')); - // Check the max field label. - $this->assertRaw('<label for="edit-age-max">And</label>', 'Max field label found'); - $this->assertRaw('<label for="edit-age-min">Age between</label>', 'Min field label found'); - // Check that the description is shown in the right place. - $this->assertEqual(trim($this->cssSelect('.form-item-age-min .description')[0]), 'Description of the exposed filter'); - } - -} diff --git a/core/modules/views_ui/src/Tests/HandlerTest.php b/core/modules/views_ui/src/Tests/HandlerTest.php deleted file mode 100644 index bc61a370..00000000 --- a/core/modules/views_ui/src/Tests/HandlerTest.php +++ /dev/null @@ -1,282 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\Component\Utility\SafeMarkup; -use Drupal\field\Entity\FieldConfig; -use Drupal\field\Entity\FieldStorageConfig; -use Drupal\views\Tests\ViewTestData; -use Drupal\views\ViewExecutable; - -/** - * Tests handler UI for views. - * - * @group views_ui - * @see \Drupal\views\Plugin\views\HandlerBase - */ -class HandlerTest extends UITestBase { - - /** - * {@inheritdoc} - */ - public static $modules = array('node_test_views'); - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_view_empty', 'test_view_broken', 'node', 'test_node_view'); - - /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - - $this->drupalPlaceBlock('page_title_block'); - ViewTestData::createTestViews(get_class($this), array('node_test_views')); - } - - /** - * Overrides \Drupal\views\Tests\ViewTestBase::schemaDefinition(). - * - * Adds a uid column to test the relationships. - */ - protected function schemaDefinition() { - $schema = parent::schemaDefinition(); - - $schema['views_test_data']['fields']['uid'] = array( - 'description' => "The {users}.uid of the author of the beatle entry.", - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0 - ); - - return $schema; - } - - /** - * Overrides \Drupal\views\Tests\ViewTestBase::viewsData(). - * - * Adds: - * - a relationship for the uid column. - * - a dummy field with no help text. - */ - protected function viewsData() { - $data = parent::viewsData(); - $data['views_test_data']['uid'] = array( - 'title' => t('UID'), - 'help' => t('The test data UID'), - 'relationship' => array( - 'id' => 'standard', - 'base' => 'users_field_data', - 'base field' => 'uid' - ) - ); - - // Create a dummy field with no help text. - $data['views_test_data']['no_help'] = $data['views_test_data']['name']; - $data['views_test_data']['no_help']['field']['title'] = t('No help'); - $data['views_test_data']['no_help']['field']['real field'] = 'name'; - unset($data['views_test_data']['no_help']['help']); - - return $data; - } - - /** - * Tests UI CRUD. - */ - public function testUICRUD() { - $handler_types = ViewExecutable::getHandlerTypes(); - foreach ($handler_types as $type => $type_info) { - // Test adding handlers. - $add_handler_url = "admin/structure/views/nojs/add-handler/test_view_empty/default/$type"; - - // Area handler types need to use a different handler. - if (in_array($type, array('header', 'footer', 'empty'))) { - $this->drupalPostForm($add_handler_url, array('name[views.area]' => TRUE), t('Add and configure @handler', array('@handler' => $type_info['ltitle']))); - $id = 'area'; - $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/$type/$id"; - } - elseif ($type == 'relationship') { - $this->drupalPostForm($add_handler_url, array('name[views_test_data.uid]' => TRUE), t('Add and configure @handler', array('@handler' => $type_info['ltitle']))); - $id = 'uid'; - $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/$type/$id"; - } - else { - $this->drupalPostForm($add_handler_url, array('name[views_test_data.job]' => TRUE), t('Add and configure @handler', array('@handler' => $type_info['ltitle']))); - $id = 'job'; - $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/$type/$id"; - } - - $this->assertUrl($edit_handler_url, array(), 'The user got redirected to the handler edit form.'); - $random_label = $this->randomMachineName(); - $this->drupalPostForm(NULL, array('options[admin_label]' => $random_label), t('Apply')); - - $this->assertUrl('admin/structure/views/view/test_view_empty/edit/default', array(), 'The user got redirected to the views edit form.'); - - $this->assertLinkByHref($edit_handler_url, 0, 'The handler edit link appears in the UI.'); - $links = $this->xpath('//a[starts-with(normalize-space(text()), :label)]', array(':label' => $random_label)); - $this->assertTrue(isset($links[0]), 'The handler edit link has the right label'); - - // Save the view and have a look whether the handler was added as expected. - $this->drupalPostForm(NULL, array(), t('Save')); - $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view_empty'); - $display = $view->getDisplay('default'); - $this->assertTrue(isset($display['display_options'][$type_info['plural']][$id]), 'Ensure the field was added to the view itself.'); - - // Remove the item and check that it's removed - $this->drupalPostForm($edit_handler_url, array(), t('Remove')); - $this->assertNoLinkByHref($edit_handler_url, 0, 'The handler edit link does not appears in the UI after removing.'); - - $this->drupalPostForm(NULL, array(), t('Save')); - $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view_empty'); - $display = $view->getDisplay('default'); - $this->assertFalse(isset($display['display_options'][$type_info['plural']][$id]), 'Ensure the field was removed from the view itself.'); - } - - // Test adding a field of the user table using the uid relationship. - $type_info = $handler_types['relationship']; - $add_handler_url = "admin/structure/views/nojs/add-handler/test_view_empty/default/relationship"; - $this->drupalPostForm($add_handler_url, array('name[views_test_data.uid]' => TRUE), t('Add and configure @handler', array('@handler' => $type_info['ltitle']))); - - $add_handler_url = "admin/structure/views/nojs/add-handler/test_view_empty/default/field"; - $type_info = $handler_types['field']; - $this->drupalPostForm($add_handler_url, array('name[users_field_data.name]' => TRUE), t('Add and configure @handler', array('@handler' => $type_info['ltitle']))); - $id = 'name'; - $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/field/$id"; - - $this->assertUrl($edit_handler_url, array(), 'The user got redirected to the handler edit form.'); - $this->assertFieldByName('options[relationship]', 'uid', 'Ensure the relationship select is filled with the UID relationship.'); - $this->drupalPostForm(NULL, array(), t('Apply')); - - $this->drupalPostForm(NULL, array(), t('Save')); - $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view_empty'); - $display = $view->getDisplay('default'); - $this->assertTrue(isset($display['display_options'][$type_info['plural']][$id]), 'Ensure the field was added to the view itself.'); - } - - /** - * Tests escaping of field labels in help text. - */ - public function testHandlerHelpEscaping() { - // Setup a field with two instances using a different label. - // Ensure that the label is escaped properly. - - $this->drupalCreateContentType(['type' => 'article']); - $this->drupalCreateContentType(['type' => 'page']); - - FieldStorageConfig::create([ - 'field_name' => 'field_test', - 'entity_type' => 'node', - 'type' => 'string', - ])->save(); - - FieldConfig::create([ - 'field_name' => 'field_test', - 'entity_type' => 'node', - 'bundle' => 'page', - 'label' => 'The giraffe" label' - ])->save(); - - FieldConfig::create([ - 'field_name' => 'field_test', - 'entity_type' => 'node', - 'bundle' => 'article', - 'label' => 'The <em>giraffe"</em> label <script>alert("the return of the xss")</script>' - ])->save(); - - $this->drupalGet('admin/structure/views/nojs/add-handler/content/default/field'); - $this->assertEscaped('The <em>giraffe"</em> label <script>alert("the return of the xss")</script>'); - $this->assertEscaped('Appears in: page, article. Also known as: Content: The giraffe" label'); - } - - /** - * Tests broken handlers. - */ - public function testBrokenHandlers() { - $handler_types = ViewExecutable::getHandlerTypes(); - foreach ($handler_types as $type => $type_info) { - $this->drupalGet('admin/structure/views/view/test_view_broken/edit'); - - $href = "admin/structure/views/nojs/handler/test_view_broken/default/$type/id_broken"; - - $result = $this->xpath('//a[contains(@href, :href)]', array(':href' => $href)); - $this->assertEqual(count($result), 1, SafeMarkup::format('Handler (%type) edit link found.', array('%type' => $type))); - - $text = 'Broken/missing handler'; - - $this->assertIdentical((string) $result[0], $text, 'Ensure the broken handler text was found.'); - - $this->drupalGet($href); - $result = $this->xpath('//h1[@class="page-title"]'); - $this->assertTrue(strpos((string) $result[0], $text) !== FALSE, 'Ensure the broken handler text was found.'); - - $original_configuration = [ - 'field' => 'id_broken', - 'id' => 'id_broken', - 'relationship' => 'none', - 'table' => 'views_test_data', - 'plugin_id' => 'numeric', - ]; - - foreach ($original_configuration as $key => $value) { - $this->assertText(SafeMarkup::format('@key: @value', array('@key' => $key, '@value' => $value))); - } - } - } - - /** - * Ensures that neither node type or node ID appears multiple times. - * - * @see \Drupal\views\EntityViewsData - */ - public function testNoDuplicateFields() { - $handler_types = ['field', 'filter', 'sort', 'argument']; - - foreach ($handler_types as $handler_type) { - $add_handler_url = 'admin/structure/views/nojs/add-handler/test_node_view/default/' . $handler_type; - $this->drupalGet($add_handler_url); - - $this->assertNoDuplicateField('ID', 'Content'); - $this->assertNoDuplicateField('ID', 'Content revision'); - $this->assertNoDuplicateField('Content type', 'Content'); - $this->assertNoDuplicateField('UUID', 'Content'); - $this->assertNoDuplicateField('Revision ID', 'Content'); - $this->assertNoDuplicateField('Revision ID', 'Content revision'); - } - } - - /** - * Ensures that no missing help text is shown. - * - * @see \Drupal\views\EntityViewsData - */ - public function testErrorMissingHelp() { - // Test that the error message is not shown for entity fields but an empty - // description field is shown instead. - $this->drupalGet('admin/structure/views/nojs/add-handler/test_node_view/default/field'); - $this->assertNoText('Error: missing help'); - $this->assertRaw('<td class="description"></td>', 'Empty description found'); - - // Test that no error message is shown for other fields. - $this->drupalGet('admin/structure/views/nojs/add-handler/test_view_empty/default/field'); - $this->assertNoText('Error: missing help'); - } - - /** - * Asserts that fields only appear once. - * - * @param string $field_name - * The field name. - * @param string $entity_type - * The entity type to which the field belongs. - */ - public function assertNoDuplicateField($field_name, $entity_type) { - $elements = $this->xpath('//td[.=:entity_type]/preceding-sibling::td[@class="title" and .=:title]', [':title' => $field_name, ':entity_type' => $entity_type]); - $this->assertEqual(1, count($elements), $field_name . ' appears just once in ' . $entity_type . '.'); - } - -} diff --git a/core/modules/views_ui/src/Tests/NewViewConfigSchemaTest.php b/core/modules/views_ui/src/Tests/NewViewConfigSchemaTest.php deleted file mode 100644 index a01e24bd..00000000 --- a/core/modules/views_ui/src/Tests/NewViewConfigSchemaTest.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php - -namespace Drupal\views_ui\Tests; - -use Drupal\simpletest\WebTestBase; - -/** - * Tests configuration schema against new views. - * - * @group views_ui - */ -class NewViewConfigSchemaTest extends WebTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('views_ui', 'node', 'comment', 'file', 'taxonomy', 'dblog', 'aggregator'); - - /** - * Tests creating brand new views. - */ - public function testNewViews() { - $this->drupalLogin($this->drupalCreateUser(array('administer views'))); - - // Create views with all core Views wizards. - $wizards = array( - // Wizard with their own classes. - 'node', - 'node_revision', - 'users', - 'comment', - 'file_managed', - 'taxonomy_term', - 'watchdog', - // Standard derivative classes. - 'standard:aggregator_feed', - 'standard:aggregator_item', - ); - foreach ($wizards as $wizard_key) { - $edit = array(); - $edit['label'] = $this->randomString(); - $edit['id'] = strtolower($this->randomMachineName()); - $edit['show[wizard_key]'] = $wizard_key; - $edit['description'] = $this->randomString(); - $this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit')); - } - } - -} diff --git a/core/modules/views_ui/src/Tests/PreviewTest.php b/core/modules/views_ui/src/Tests/PreviewTest.php index 3b4dd9bf..c723cb3b 100644 --- a/core/modules/views_ui/src/Tests/PreviewTest.php +++ b/core/modules/views_ui/src/Tests/PreviewTest.php @@ -17,23 +17,23 @@ class PreviewTest extends UITestBase { * * @var array */ - public static $testViews = array('test_preview', 'test_preview_error', 'test_pager_full', 'test_mini_pager', 'test_click_sort'); + public static $testViews = ['test_preview', 'test_preview_error', 'test_pager_full', 'test_mini_pager', 'test_click_sort']; /** * Tests contextual links in the preview form. */ public function testPreviewContextual() { - \Drupal::service('module_installer')->install(array('contextual')); + \Drupal::service('module_installer')->install(['contextual']); $this->resetAll(); $this->drupalGet('admin/structure/views/view/test_preview/edit'); $this->assertResponse(200); - $this->drupalPostForm(NULL, $edit = array(), t('Update preview')); + $this->drupalPostForm(NULL, $edit = [], t('Update preview')); - $elements = $this->xpath('//div[@id="views-live-preview"]//ul[contains(@class, :ul-class)]/li[contains(@class, :li-class)]', array(':ul-class' => 'contextual-links', ':li-class' => 'filter-add')); + $elements = $this->xpath('//div[@id="views-live-preview"]//ul[contains(@class, :ul-class)]/li[contains(@class, :li-class)]', [':ul-class' => 'contextual-links', ':li-class' => 'filter-add']); $this->assertEqual(count($elements), 1, 'The contextual link to add a new field is shown.'); - $this->drupalPostForm(NULL, $edit = array('view_args' => '100'), t('Update preview')); + $this->drupalPostForm(NULL, $edit = ['view_args' => '100'], t('Update preview')); // Test that area text and exposed filters are present and rendered. $this->assertFieldByName('id', NULL, 'ID exposed filter field found.'); @@ -45,23 +45,23 @@ public function testPreviewContextual() { /** * Tests arguments in the preview form. */ - function testPreviewUI() { + public function testPreviewUI() { $this->drupalGet('admin/structure/views/view/test_preview/edit'); $this->assertResponse(200); - $this->drupalPostForm(NULL, $edit = array(), t('Update preview')); + $this->drupalPostForm(NULL, $edit = [], t('Update preview')); $elements = $this->xpath('//div[@class = "view-content"]/div[contains(@class, views-row)]'); $this->assertEqual(count($elements), 5); // Filter just the first result. - $this->drupalPostForm(NULL, $edit = array('view_args' => '1'), t('Update preview')); + $this->drupalPostForm(NULL, $edit = ['view_args' => '1'], t('Update preview')); $elements = $this->xpath('//div[@class = "view-content"]/div[contains(@class, views-row)]'); $this->assertEqual(count($elements), 1); // Filter for no results. - $this->drupalPostForm(NULL, $edit = array('view_args' => '100'), t('Update preview')); + $this->drupalPostForm(NULL, $edit = ['view_args' => '100'], t('Update preview')); $elements = $this->xpath('//div[@class = "view-content"]/div[contains(@class, views-row)]'); $this->assertEqual(count($elements), 0); @@ -73,7 +73,7 @@ function testPreviewUI() { $this->assertText('Test empty text', 'Rendered empty text found.'); // Test feed preview. - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['page[create]'] = 1; @@ -83,7 +83,7 @@ function testPreviewUI() { $view['page[feed_properties][path]'] = $this->randomMachineName(16); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); $this->clickLink(t('Feed')); - $this->drupalPostForm(NULL, array(), t('Update preview')); + $this->drupalPostForm(NULL, [], t('Update preview')); $result = $this->xpath('//div[@id="views-live-preview"]/pre'); $this->assertTrue(strpos($result[0], '<title>' . $view['page[title]'] . ''), 'The Feed RSS preview was rendered.'); @@ -92,7 +92,7 @@ function testPreviewUI() { $settings = \Drupal::configFactory()->getEditable('views.settings'); $settings->set('ui.show.performance_statistics', TRUE)->save(); $this->drupalGet('admin/structure/views/view/test_preview/edit'); - $this->drupalPostForm(NULL, $edit = array('view_args' => '100'), t('Update preview')); + $this->drupalPostForm(NULL, $edit = ['view_args' => '100'], t('Update preview')); $this->assertText(t('Query build time')); $this->assertText(t('Query execute time')); $this->assertText(t('View render time')); @@ -100,20 +100,26 @@ function testPreviewUI() { // Statistics and query. $settings->set('ui.show.sql_query.enabled', TRUE)->save(); - $this->drupalPostForm(NULL, $edit = array('view_args' => '100'), t('Update preview')); + $this->drupalPostForm(NULL, $edit = ['view_args' => '100'], t('Update preview')); $this->assertText(t('Query build time')); $this->assertText(t('Query execute time')); $this->assertText(t('View render time')); $this->assertRaw('Query'); - $this->assertText("SELECT views_test_data.name AS views_test_data_name\nFROM \n{views_test_data} views_test_data\nWHERE (( (views_test_data.id = '100' ) ))"); + $this->assertText("SELECT views_test_data.name AS views_test_data_name\nFROM \n{views_test_data} views_test_data\nWHERE (views_test_data.id = '100' )"); // Test that the statistics and query are rendered above the preview. $this->assertTrue(strpos($this->getRawContent(), 'views-query-info') < strpos($this->getRawContent(), 'view-test-preview'), 'Statistics shown above the preview.'); // Test that statistics and query rendered below the preview. $settings->set('ui.show.sql_query.where', 'below')->save(); - $this->drupalPostForm(NULL, $edit = array('view_args' => '100'), t('Update preview')); + $this->drupalPostForm(NULL, $edit = ['view_args' => '100'], t('Update preview')); $this->assertTrue(strpos($this->getRawContent(), 'view-test-preview') < strpos($this->getRawContent(), 'views-query-info'), 'Statistics shown below the preview.'); + + // Test that the preview title isn't double escaped. + $this->drupalPostForm("admin/structure/views/nojs/display/test_preview/default/title", $edit = ['title' => 'Double & escaped'], t('Apply')); + $this->drupalPostForm(NULL, [], t('Update preview')); + $elements = $this->xpath('//div[@id="views-live-preview"]/div[contains(@class, views-query-info)]//td[text()=:text]', [':text' => t('Double & escaped')]); + $this->assertEqual(1, count($elements)); } /** @@ -124,7 +130,7 @@ function testPreviewUI() { * @see https://www.drupal.org/node/2452659 */ public function testTaxonomyAJAX() { - \Drupal::service('module_installer')->install(array('taxonomy')); + \Drupal::service('module_installer')->install(['taxonomy']); $this->getPreviewAJAX('taxonomy_term', 'page_1', 0); } @@ -134,7 +140,7 @@ public function testTaxonomyAJAX() { public function testPreviewWithPagersUI() { // Create 11 nodes and make sure that everyone is returned. - $this->drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); for ($i = 0; $i < 11; $i++) { $this->drupalCreateNode(); } @@ -143,7 +149,7 @@ public function testPreviewWithPagersUI() { $this->getPreviewAJAX('test_pager_full', 'default', 5); // Test that the pager is present and rendered. - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); $this->assertTrue(!empty($elements), 'Full pager found.'); // Verify elements and links to pages. @@ -165,11 +171,11 @@ public function testPreviewWithPagersUI() { $this->assertTrue($elements[4]->a, 'Link to last page found.'); // Navigate to next page. - $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--next')); + $elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--next']); $this->clickPreviewLinkAJAX($elements[0]['href'], 5); // Test that the pager is present and rendered. - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); $this->assertTrue(!empty($elements), 'Full pager found.'); // Verify elements and links to pages. @@ -201,7 +207,7 @@ public function testPreviewWithPagersUI() { $this->getPreviewAJAX('test_mini_pager', 'default', 3); // Test that the pager is present and rendered. - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); $this->assertTrue(!empty($elements), 'Mini pager found.'); // Verify elements and links to pages. @@ -213,11 +219,11 @@ public function testPreviewWithPagersUI() { $this->assertTrue($elements[1]->a, 'Link to next page found.'); // Navigate to next page. - $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--next')); + $elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--next']); $this->clickPreviewLinkAJAX($elements[0]['href'], 3); // Test that the pager is present and rendered. - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); $this->assertTrue(!empty($elements), 'Mini pager found.'); // Verify elements and links to pages. @@ -237,17 +243,17 @@ public function testPreviewWithPagersUI() { * Tests the additional information query info area. */ public function testPreviewAdditionalInfo() { - \Drupal::service('module_installer')->install(array('views_ui_test')); + \Drupal::service('module_installer')->install(['views_ui_test']); $this->resetAll(); $this->drupalGet('admin/structure/views/view/test_preview/edit'); $this->assertResponse(200); - $this->drupalPostForm(NULL, $edit = array(), t('Update preview')); + $this->drupalPostForm(NULL, $edit = [], t('Update preview')); // Check for implementation of hook_views_preview_info_alter(). // @see views_ui_test.module - $elements = $this->xpath('//div[@id="views-live-preview"]/div[contains(@class, views-query-info)]//td[text()=:text]', array(':text' => t('Test row count'))); + $elements = $this->xpath('//div[@id="views-live-preview"]/div[contains(@class, views-query-info)]//td[text()=:text]', [':text' => t('Test row count')]); $this->assertEqual(count($elements), 1, 'Views Query Preview Info area altered.'); // Check that additional assets are attached. $this->assertTrue(strpos($this->getDrupalSettings()['ajaxPageState']['libraries'], 'views_ui_test/views_ui_test.test') !== FALSE, 'Attached library found.'); @@ -261,7 +267,7 @@ public function testPreviewError() { $this->drupalGet('admin/structure/views/view/test_preview_error/edit'); $this->assertResponse(200); - $this->drupalPostForm(NULL, $edit = array(), t('Update preview')); + $this->drupalPostForm(NULL, $edit = [], t('Update preview')); $this->assertText('Unable to preview due to validation errors.', 'Preview error text found.'); } @@ -275,7 +281,7 @@ public function testPreviewSortLink() { $this->getPreviewAJAX('test_click_sort', 'page_1', 0); // Test that the header label is present. - $elements = $this->xpath('//th[contains(@class, :class)]/a', array(':class' => 'views-field views-field-name')); + $elements = $this->xpath('//th[contains(@class, :class)]/a', [':class' => 'views-field views-field-name']); $this->assertTrue(!empty($elements), 'The header label is present.'); // Verify link. @@ -285,7 +291,7 @@ public function testPreviewSortLink() { $this->clickPreviewLinkAJAX($elements[0]['href'], 0); // Test that the header label is present. - $elements = $this->xpath('//th[contains(@class, :class)]/a', array(':class' => 'views-field views-field-name is-active')); + $elements = $this->xpath('//th[contains(@class, :class)]/a', [':class' => 'views-field views-field-name is-active']); $this->assertTrue(!empty($elements), 'The header label is present.'); // Verify link. @@ -304,7 +310,7 @@ public function testPreviewSortLink() { */ protected function getPreviewAJAX($view_name, $panel_id, $row_count) { $this->drupalGet('admin/structure/views/view/' . $view_name . '/preview/' . $panel_id); - $result = $this->drupalPostAjaxForm(NULL, array(), array('op' => t('Update preview'))); + $result = $this->drupalPostAjaxForm(NULL, [], ['op' => t('Update preview')]); $this->assertPreviewAJAX($result, $row_count); } @@ -319,12 +325,12 @@ protected function getPreviewAJAX($view_name, $panel_id, $row_count) { protected function clickPreviewLinkAJAX($url, $row_count) { $content = $this->content; $drupal_settings = $this->drupalSettings; - $ajax_settings = array( + $ajax_settings = [ 'wrapper' => 'views-preview-wrapper', 'method' => 'replaceWith', - ); + ]; $url = $this->getAbsoluteUrl($url); - $post = array('js' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['js' => 'true'] + $this->getAjaxPageStatePostData(); $result = Json::decode($this->drupalPost($url, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']])); if (!empty($result)) { $this->drupalProcessAjaxResponse($content, $result, $ajax_settings, $drupal_settings); @@ -343,7 +349,7 @@ protected function clickPreviewLinkAJAX($url, $row_count) { protected function assertPreviewAJAX($result, $row_count) { // Has AJAX callback replied with an insert command? If so, we can // assume that the page content was updated with AJAX returned data. - $result_commands = array(); + $result_commands = []; foreach ($result as $command) { $result_commands[$command['command']] = $command; } diff --git a/core/modules/views_ui/src/Tests/RedirectTest.php b/core/modules/views_ui/src/Tests/RedirectTest.php deleted file mode 100644 index 7a019597..00000000 --- a/core/modules/views_ui/src/Tests/RedirectTest.php +++ /dev/null @@ -1,45 +0,0 @@ -randomMachineName(); - $edit_path = "admin/structure/views/view/$view_name/edit"; - - $this->drupalPostForm($edit_path, array(), t('Save'), array('query' => array('destination' => $random_destination))); - $this->assertUrl($random_destination, array(), 'Make sure the user got redirected to the expected page defined in the destination.'); - - // Setup a view with a certain page display path. If you change the path - // but have the old url in the destination the user should be redirected to - // the new path. - $view_name = 'test_redirect_view'; - $new_path = $this->randomMachineName(); - - $edit_path = "admin/structure/views/view/$view_name/edit"; - $path_edit_path = "admin/structure/views/nojs/display/$view_name/page_1/path"; - - $this->drupalPostForm($path_edit_path, array('path' => $new_path), t('Apply')); - $this->drupalPostForm($edit_path, array(), t('Save'), array('query' => array('destination' => 'test-redirect-view'))); - $this->assertUrl($new_path, array(), 'Make sure the user got redirected to the expected page after changing the URL of a page display.'); - } - -} diff --git a/core/modules/views_ui/src/Tests/ReportTest.php b/core/modules/views_ui/src/Tests/ReportTest.php deleted file mode 100644 index d7228f17..00000000 --- a/core/modules/views_ui/src/Tests/ReportTest.php +++ /dev/null @@ -1,43 +0,0 @@ -adminUser = $this->drupalCreateUser(array('administer views')); - } - - /** - * Tests the existence of the views plugin report. - */ - public function testReport() { - $this->drupalLogin($this->adminUser); - - // Test the report page. - $this->drupalGet('admin/reports/views-plugins'); - $this->assertResponse(200, "Views report page exists"); - } - -} diff --git a/core/modules/views_ui/src/Tests/RowUITest.php b/core/modules/views_ui/src/Tests/RowUITest.php index 188e0b51..56890097 100644 --- a/core/modules/views_ui/src/Tests/RowUITest.php +++ b/core/modules/views_ui/src/Tests/RowUITest.php @@ -18,7 +18,7 @@ class RowUITest extends UITestBase { * * @var array */ - public static $testViews = array('test_view'); + public static $testViews = ['test_view']; /** * Tests changing the row plugin and changing some options of a row. @@ -33,20 +33,20 @@ public function testRowUI() { $this->drupalGet($row_plugin_url); $this->assertFieldByName('row[type]', 'fields', 'The default row plugin selected in the UI should be fields.'); - $edit = array( + $edit = [ 'row[type]' => 'test_row' - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply')); $this->assertFieldByName('row_options[test_option]', NULL, 'Make sure the custom settings form from the test plugin appears.'); $random_name = $this->randomMachineName(); - $edit = array( + $edit = [ 'row_options[test_option]' => $random_name - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply')); $this->drupalGet($row_options_url); $this->assertFieldByName('row_options[test_option]', $random_name, 'Make sure the custom settings form field has the expected value stored.'); - $this->drupalPostForm($view_edit_url, array(), t('Save')); + $this->drupalPostForm($view_edit_url, [], t('Save')); $this->assertLink(t('Test row plugin'), 0, 'Make sure the test row plugin is shown in the UI'); $view = Views::getView($view_name); diff --git a/core/modules/views_ui/src/Tests/StorageTest.php b/core/modules/views_ui/src/Tests/StorageTest.php deleted file mode 100644 index f01a136c..00000000 --- a/core/modules/views_ui/src/Tests/StorageTest.php +++ /dev/null @@ -1,56 +0,0 @@ -save(); - - $edit = array( - 'label' => $this->randomMachineName(), - 'tag' => $this->randomMachineName(), - 'description' => $this->randomMachineName(30), - 'langcode' => 'fr', - ); - - $this->drupalPostForm("admin/structure/views/nojs/edit-details/$view_name/default", $edit, t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); - - $view = Views::getView($view_name); - - foreach (array('label', 'tag', 'description', 'langcode') as $property) { - $this->assertEqual($view->storage->get($property), $edit[$property], format_string('Make sure the property @property got probably saved.', array('@property' => $property))); - } - } - -} diff --git a/core/modules/views_ui/src/Tests/StyleTableTest.php b/core/modules/views_ui/src/Tests/StyleTableTest.php deleted file mode 100644 index 7eb757cb..00000000 --- a/core/modules/views_ui/src/Tests/StyleTableTest.php +++ /dev/null @@ -1,35 +0,0 @@ -randomMachineName(16); - $view['id'] = strtolower($this->randomMachineName(16)); - $view['show[wizard_key]'] = 'node'; - $view['page[create]'] = TRUE; - $view['page[style][style_plugin]'] = 'table'; - $view['page[title]'] = $this->randomMachineName(16); - $view['page[path]'] = $view['id']; - $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - - $view = Views::getView($view['id']); - $view->initHandlers(); - $this->assertEqual($view->field['title']->options['label'], 'Title', 'The field label for table styles is not empty.'); - } - -} diff --git a/core/modules/views_ui/src/Tests/UITestBase.php b/core/modules/views_ui/src/Tests/UITestBase.php index 74b6f4ff..83f2f859 100644 --- a/core/modules/views_ui/src/Tests/UITestBase.php +++ b/core/modules/views_ui/src/Tests/UITestBase.php @@ -6,6 +6,9 @@ /** * Provides a base class for testing the Views UI. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.x. + * Use \Drupal\Tests\views_ui\Functional\UITestBase. */ abstract class UITestBase extends ViewTestBase { @@ -28,7 +31,7 @@ abstract class UITestBase extends ViewTestBase { * * @var array */ - public static $modules = array('node', 'views_ui', 'block', 'taxonomy'); + public static $modules = ['node', 'views_ui', 'block', 'taxonomy']; /** * {@inheritdoc} @@ -38,24 +41,26 @@ protected function setUp() { $this->enableViewsTestModule(); - $this->adminUser = $this->drupalCreateUser(array('administer views')); + $this->adminUser = $this->drupalCreateUser(['administer views']); - $this->fullAdminUser = $this->drupalCreateUser(array('administer views', + $this->fullAdminUser = $this->drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions', 'administer permissions', - )); + ]); $this->drupalLogin($this->fullAdminUser); + + @trigger_error('\Drupal\views_ui\Tests\UITestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.x. Instead, use \Drupal\Tests\views_ui\Functional\UITestBase', E_USER_DEPRECATED); } /** * A helper method which creates a random view. */ - public function randomView(array $view = array()) { + public function randomView(array $view = []) { // Create a new view in the UI. - $default = array(); + $default = []; $default['label'] = $this->randomMachineName(16); $default['id'] = strtolower($this->randomMachineName(16)); $default['description'] = $this->randomMachineName(16); @@ -72,7 +77,7 @@ public function randomView(array $view = array()) { /** * {@inheritdoc} */ - protected function drupalGet($path, array $options = array(), array $headers = array()) { + protected function drupalGet($path, array $options = [], array $headers = []) { $url = $this->buildUrl($path, $options); // Ensure that each nojs page is accessible via ajax as well. diff --git a/core/modules/views_ui/src/Tests/WizardTest.php b/core/modules/views_ui/src/Tests/WizardTest.php deleted file mode 100644 index 58cf97c8..00000000 --- a/core/modules/views_ui/src/Tests/WizardTest.php +++ /dev/null @@ -1,62 +0,0 @@ -randomMachineName(256); - $view['id'] = strtolower($this->randomMachineName(129)); - $view['page[create]'] = TRUE; - $view['page[path]'] = $this->randomMachineName(255); - $view['page[title]'] = $this->randomMachineName(256); - $view['page[feed]'] = TRUE; - $view['page[feed_properties][path]'] = $this->randomMachineName(255); - $view['block[create]'] = TRUE; - $view['block[title]'] = $this->randomMachineName(256); - $view['rest_export[create]'] = TRUE; - $view['rest_export[path]'] = $this->randomMachineName(255); - - $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - - $this->assertText('Machine-readable name cannot be longer than 128 characters but is currently 129 characters long.'); - $this->assertText('Path cannot be longer than 254 characters but is currently 255 characters long.'); - $this->assertText('Page title cannot be longer than 255 characters but is currently 256 characters long.'); - $this->assertText('View name cannot be longer than 255 characters but is currently 256 characters long.'); - $this->assertText('Feed path cannot be longer than 254 characters but is currently 255 characters long.'); - $this->assertText('Block title cannot be longer than 255 characters but is currently 256 characters long.'); - $this->assertText('REST export path cannot be longer than 254 characters but is currently 255 characters long.'); - - $view['label'] = $this->randomMachineName(255); - $view['id'] = strtolower($this->randomMachineName(128)); - $view['page[create]'] = TRUE; - $view['page[path]'] = $this->randomMachineName(254); - $view['page[title]'] = $this->randomMachineName(255); - $view['page[feed]'] = TRUE; - $view['page[feed_properties][path]'] = $this->randomMachineName(254); - $view['block[create]'] = TRUE; - $view['block[title]'] = $this->randomMachineName(255); - $view['rest_export[create]'] = TRUE; - $view['rest_export[path]'] = $this->randomMachineName(254); - - $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - $this->assertUrl('admin/structure/views/view/' . $view['id'], array(), 'Make sure the view saving was successful and the browser got redirected to the edit page.'); - // Assert that the page title is correctly truncated. - $this->assertText(views_ui_truncate($view['page[title]'], 32)); - } - -} diff --git a/core/modules/views_ui/src/ViewAddForm.php b/core/modules/views_ui/src/ViewAddForm.php index c3d5c77c..429032c8 100644 --- a/core/modules/views_ui/src/ViewAddForm.php +++ b/core/modules/views_ui/src/ViewAddForm.php @@ -51,83 +51,83 @@ protected function prepareEntity() { */ public function form(array $form, FormStateInterface $form_state) { $form['#attached']['library'][] = 'views_ui/views_ui.admin'; - $form['#attributes']['class'] = array('views-admin'); + $form['#attributes']['class'] = ['views-admin']; - $form['name'] = array( + $form['name'] = [ '#type' => 'fieldset', '#title' => t('View basic information'), - '#attributes' => array('class' => array('fieldset-no-legend')), - ); + '#attributes' => ['class' => ['fieldset-no-legend']], + ]; - $form['name']['label'] = array( + $form['name']['label'] = [ '#type' => 'textfield', '#title' => $this->t('View name'), '#required' => TRUE, '#size' => 32, '#default_value' => '', '#maxlength' => 255, - ); - $form['name']['id'] = array( + ]; + $form['name']['id'] = [ '#type' => 'machine_name', '#maxlength' => 128, - '#machine_name' => array( + '#machine_name' => [ 'exists' => '\Drupal\views\Views::getView', - 'source' => array('name', 'label'), - ), + 'source' => ['name', 'label'], + ], '#description' => $this->t('A unique machine-readable name for this View. It must only contain lowercase letters, numbers, and underscores.'), - ); + ]; - $form['name']['description_enable'] = array( + $form['name']['description_enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Description'), - ); - $form['name']['description'] = array( + ]; + $form['name']['description'] = [ '#type' => 'textfield', '#title' => $this->t('Provide description'), '#title_display' => 'invisible', '#size' => 64, '#default_value' => '', - '#states' => array( - 'visible' => array( - ':input[name="description_enable"]' => array('checked' => TRUE), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="description_enable"]' => ['checked' => TRUE], + ], + ], + ]; // Create a wrapper for the entire dynamic portion of the form. Everything // that can be updated by AJAX goes somewhere inside here. For example, this // is needed by "Show" dropdown (below); it changes the base table of the // view and therefore potentially requires all options on the form to be // dynamically updated. - $form['displays'] = array(); + $form['displays'] = []; // Create the part of the form that allows the user to select the basic // properties of what the view will display. - $form['displays']['show'] = array( + $form['displays']['show'] = [ '#type' => 'fieldset', '#title' => t('View settings'), '#tree' => TRUE, - '#attributes' => array('class' => array('container-inline')), - ); + '#attributes' => ['class' => ['container-inline']], + ]; // Create the "Show" dropdown, which allows the base table of the view to be // selected. $wizard_plugins = $this->wizardManager->getDefinitions(); - $options = array(); + $options = []; foreach ($wizard_plugins as $key => $wizard) { $options[$key] = $wizard['title']; } - $form['displays']['show']['wizard_key'] = array( + $form['displays']['show']['wizard_key'] = [ '#type' => 'select', '#title' => $this->t('Show'), '#options' => $options, - ); + ]; $show_form = &$form['displays']['show']; $default_value = \Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'users'; - $show_form['wizard_key']['#default_value'] = WizardPluginBase::getSelected($form_state, array('show', 'wizard_key'), $default_value, $show_form['wizard_key']); + $show_form['wizard_key']['#default_value'] = WizardPluginBase::getSelected($form_state, ['show', 'wizard_key'], $default_value, $show_form['wizard_key']); // Changing this dropdown updates the entire content of $form['displays'] via // AJAX. - views_ui_add_ajax_trigger($show_form, 'wizard_key', array('displays')); + views_ui_add_ajax_trigger($show_form, 'wizard_key', ['displays']); // Build the rest of the form based on the currently selected wizard plugin. $wizard_key = $show_form['wizard_key']['#default_value']; @@ -144,13 +144,13 @@ protected function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); $actions['submit']['#value'] = $this->t('Save and edit'); // Remove EntityFormController::save() form the submission handlers. - $actions['submit']['#submit'] = array(array($this, 'submitForm')); - $actions['cancel'] = array( + $actions['submit']['#submit'] = [[$this, 'submitForm']]; + $actions['cancel'] = [ '#type' => 'submit', '#value' => $this->t('Cancel'), - '#submit' => array('::cancel'), - '#limit_validation_errors' => array(), - ); + '#submit' => ['::cancel'], + '#limit_validation_errors' => [], + ]; return $actions; } @@ -158,7 +158,7 @@ protected function actions(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { - $wizard_type = $form_state->getValue(array('show', 'wizard_key')); + $wizard_type = $form_state->getValue(['show', 'wizard_key']); $wizard_instance = $this->wizardManager->createInstance($wizard_type); $form_state->set('wizard', $wizard_instance->getPluginDefinition()); $form_state->set('wizard_instance', $wizard_instance); @@ -187,7 +187,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { return; } $this->entity->save(); - drupal_set_message($this->t('The view %name has been saved.', array('%name' => $form_state->getValue('label')))); + drupal_set_message($this->t('The view %name has been saved.', ['%name' => $form_state->getValue('label')])); $form_state->setRedirectUrl($this->entity->urlInfo('edit-form')); } diff --git a/core/modules/views_ui/src/ViewDuplicateForm.php b/core/modules/views_ui/src/ViewDuplicateForm.php index 9870d8e8..fa2db608 100644 --- a/core/modules/views_ui/src/ViewDuplicateForm.php +++ b/core/modules/views_ui/src/ViewDuplicateForm.php @@ -22,26 +22,26 @@ protected function prepareEntity() { public function form(array $form, FormStateInterface $form_state) { parent::form($form, $form_state); - $form['#title'] = $this->t('Duplicate of @label', array('@label' => $this->entity->label())); + $form['#title'] = $this->t('Duplicate of @label', ['@label' => $this->entity->label()]); - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('View name'), '#required' => TRUE, '#size' => 32, '#maxlength' => 255, - '#default_value' => $this->t('Duplicate of @label', array('@label' => $this->entity->label())), - ); - $form['id'] = array( + '#default_value' => $this->t('Duplicate of @label', ['@label' => $this->entity->label()]), + ]; + $form['id'] = [ '#type' => 'machine_name', '#maxlength' => 128, - '#machine_name' => array( + '#machine_name' => [ 'exists' => '\Drupal\views\Views::getView', - 'source' => array('label'), - ), + 'source' => ['label'], + ], '#default_value' => '', '#description' => $this->t('A unique machine-readable name for this View. It must only contain lowercase letters, numbers, and underscores.'), - ); + ]; return $form; } @@ -50,10 +50,10 @@ public function form(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ protected function actions(array $form, FormStateInterface $form_state) { - $actions['submit'] = array( + $actions['submit'] = [ '#type' => 'submit', '#value' => $this->t('Duplicate'), - ); + ]; return $actions; } diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php index 106fdb8b..e5831613 100644 --- a/core/modules/views_ui/src/ViewEditForm.php +++ b/core/modules/views_ui/src/ViewEditForm.php @@ -98,7 +98,7 @@ public function form(array $form, FormStateInterface $form_state) { if ($display_id) { if (!$view->getExecutable()->setDisplay($display_id)) { - $form['#markup'] = $this->t('Invalid display id @display', array('@display' => $display_id)); + $form['#markup'] = $this->t('Invalid display id @display', ['@display' => $display_id]); return $form; } } @@ -112,55 +112,55 @@ public function form(array $form, FormStateInterface $form_state) { $form['#attached']['library'][] = 'views_ui/views_ui.admin'; $form['#attached']['library'][] = 'views_ui/admin.styling'; - $form += array( + $form += [ '#prefix' => '', '#suffix' => '', - ); + ]; $view_status = $view->status() ? 'enabled' : 'disabled'; $form['#prefix'] .= '
              '; $form['#suffix'] = '
              ' . $form['#suffix']; - $form['#attributes']['class'] = array('form-edit'); + $form['#attributes']['class'] = ['form-edit']; if ($view->isLocked()) { - $username = array( + $username = [ '#theme' => 'username', '#account' => $this->entityManager->getStorage('user')->load($view->lock->owner), - ); - $lock_message_substitutions = array( - '@user' => drupal_render($username), + ]; + $lock_message_substitutions = [ + '@user' => \Drupal::service('renderer')->render($username), '@age' => $this->dateFormatter->formatTimeDiffSince($view->lock->updated), ':url' => $view->url('break-lock-form'), - ); - $form['locked'] = array( + ]; + $form['locked'] = [ '#type' => 'container', - '#attributes' => array('class' => array('view-locked', 'messages', 'messages--warning')), + '#attributes' => ['class' => ['view-locked', 'messages', 'messages--warning']], '#children' => $this->t('This view is being edited by user @user, and is therefore locked from editing by others. This lock is @age old. Click here to break this lock.', $lock_message_substitutions), '#weight' => -10, - ); + ]; } else { - $form['changed'] = array( + $form['changed'] = [ '#type' => 'container', - '#attributes' => array('class' => array('view-changed', 'messages', 'messages--warning')), + '#attributes' => ['class' => ['view-changed', 'messages', 'messages--warning']], '#children' => $this->t('You have unsaved changes.'), '#weight' => -10, - ); + ]; if (empty($view->changed)) { $form['changed']['#attributes']['class'][] = 'js-hide'; } } - $form['displays'] = array( + $form['displays'] = [ '#prefix' => '

              ' . $this->t('Displays') . '

              ', '#type' => 'container', - '#attributes' => array( - 'class' => array( + '#attributes' => [ + 'class' => [ 'views-displays', - ), - ), - ); + ], + ], + ]; $form['displays']['top'] = $this->renderDisplayTop($view); @@ -170,13 +170,13 @@ public function form(array $form, FormStateInterface $form_state) { $form_state->set('display_id', $display_id); // The part of the page where editing will take place. - $form['displays']['settings'] = array( + $form['displays']['settings'] = [ '#type' => 'container', '#id' => 'edit-display-settings', - '#attributes' => array( - 'class' => array('edit-display-settings'), - ), - ); + '#attributes' => [ + 'class' => ['edit-display-settings'], + ], + ]; // Add a text that the display is disabled. if ($view->getExecutable()->displayHandlers->has($display_id)) { @@ -187,8 +187,8 @@ public function form(array $form, FormStateInterface $form_state) { // Add the edit display content $tab_content = $this->getDisplayTab($view); - $tab_content['#theme_wrappers'] = array('container'); - $tab_content['#attributes'] = array('class' => array('views-display-tab')); + $tab_content['#theme_wrappers'] = ['container']; + $tab_content['#attributes'] = ['class' => ['views-display-tab']]; $tab_content['#id'] = 'views-tab-' . $display_id; // Mark deleted displays as such. $display = $view->get('display'); @@ -200,10 +200,10 @@ public function form(array $form, FormStateInterface $form_state) { if ($view->getExecutable()->displayHandlers->has($display_id) && !$view->getExecutable()->displayHandlers->get($display_id)->isEnabled()) { $tab_content['#attributes']['class'][] = 'views-display-disabled'; } - $form['displays']['settings']['settings_content'] = array( + $form['displays']['settings']['settings_content'] = [ '#type' => 'container', 'tab_content' => $tab_content, - ); + ]; } return $form; @@ -216,12 +216,12 @@ protected function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); unset($actions['delete']); - $actions['cancel'] = array( + $actions['cancel'] = [ '#type' => 'submit', '#value' => $this->t('Cancel'), - '#submit' => array('::cancel'), - '#limit_validation_errors' => array(), - ); + '#submit' => ['::cancel'], + '#limit_validation_errors' => [], + ]; if ($this->entity->isLocked()) { $actions['submit']['#access'] = FALSE; $actions['cancel']['#access'] = FALSE; @@ -258,6 +258,16 @@ public function save(array $form, FormStateInterface $form_state) { $displays = $view->get('display'); foreach ($displays as $id => $display) { if (!empty($display['deleted'])) { + // Remove view display from view attachment under the attachments + // options. + $display_handler = $executable->displayHandlers->get($id); + if ($attachments = $display_handler->getAttachedDisplays()) { + foreach ($attachments as $attachment) { + $attached_options = $executable->displayHandlers->get($attachment)->getOption('displays'); + unset($attached_options[$id]); + $executable->displayHandlers->get($attachment)->setOption('displays', $attached_options); + } + } $executable->displayHandlers->remove($id); unset($displays[$id]); } @@ -265,7 +275,7 @@ public function save(array $form, FormStateInterface $form_state) { // Rename display ids if needed. foreach ($executable->displayHandlers as $id => $display) { - if (!empty($display->display['new_id']) && empty($display->display['deleted'])) { + if (!empty($display->display['new_id']) && $display->display['new_id'] !== $display->display['id'] && empty($display->display['deleted'])) { $new_id = $display->display['new_id']; $display->display['id'] = $new_id; unset($display->display['new_id']); @@ -275,10 +285,13 @@ public function save(array $form, FormStateInterface $form_state) { unset($displays[$id]); // Redirect the user to the renamed display to be sure that the page itself exists and doesn't throw errors. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $new_id, - )); + ]); + } + elseif (isset($display->display['new_id'])) { + unset($display->display['new_id']); } } $view->set('display', $displays); @@ -310,7 +323,7 @@ public function save(array $form, FormStateInterface $form_state) { $view->save(); - drupal_set_message($this->t('The view %name has been saved.', array('%name' => $view->label()))); + drupal_set_message($this->t('The view %name has been saved.', ['%name' => $view->label()])); // Remove this view from cache so we can edit it properly. $this->tempStore->delete($view->id()); @@ -335,14 +348,14 @@ public function cancel(array $form, FormStateInterface $form_state) { * Returns a renderable array representing the edit page for one display. */ public function getDisplayTab($view) { - $build = array(); + $build = []; $display_id = $this->displayID; $display = $view->getExecutable()->displayHandlers->get($display_id); // If the plugin doesn't exist, display an error message instead of an edit // page. if (empty($display)) { // @TODO: Improved UX for the case where a plugin is missing. - $build['#markup'] = $this->t("Error: Display @display refers to a plugin named '@plugin', but that plugin is not available.", array('@display' => $display->display['id'], '@plugin' => $display->display['display_plugin'])); + $build['#markup'] = $this->t("Error: Display @display refers to a plugin named '@plugin', but that plugin is not available.", ['@display' => $display->display['id'], '@plugin' => $display->display['display_plugin']]); } // Build the content of the edit page. else { @@ -364,10 +377,10 @@ public function getDisplayTab($view) { */ public function getDisplayDetails($view, $display) { $display_title = $this->getDisplayLabel($view, $display['id'], FALSE); - $build = array( - '#theme_wrappers' => array('container'), - '#attributes' => array('id' => 'edit-display-settings-details'), - ); + $build = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['id' => 'edit-display-settings-details'], + ]; $is_display_deleted = !empty($display['deleted']); // The master display cannot be duplicated. @@ -376,14 +389,14 @@ public function getDisplayDetails($view, $display) { $is_enabled = $view->getExecutable()->displayHandlers->get($display['id'])->isEnabled(); if ($display['id'] != 'default') { - $build['top']['#theme_wrappers'] = array('container'); + $build['top']['#theme_wrappers'] = ['container']; $build['top']['#attributes']['id'] = 'edit-display-settings-top'; - $build['top']['#attributes']['class'] = array('views-ui-display-tab-actions', 'edit-display-settings-top', 'views-ui-display-tab-bucket', 'clearfix'); + $build['top']['#attributes']['class'] = ['views-ui-display-tab-actions', 'edit-display-settings-top', 'views-ui-display-tab-bucket', 'clearfix']; // The Delete, Duplicate and Undo Delete buttons. - $build['top']['actions'] = array( - '#theme_wrappers' => array('dropbutton_wrapper'), - ); + $build['top']['actions'] = [ + '#theme_wrappers' => ['dropbutton_wrapper'], + ]; // Because some of the 'links' are actually submit buttons, we have to // manually wrap each item in
            • and the whole list in
                . @@ -391,14 +404,14 @@ public function getDisplayDetails($view, $display) { if (!$is_display_deleted) { if (!$is_enabled) { - $build['top']['actions']['enable'] = array( + $build['top']['actions']['enable'] = [ '#type' => 'submit', '#value' => $this->t('Enable @display_title', ['@display_title' => $display_title]), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDisplayEnable', '::submitDelayDestination'), + '#limit_validation_errors' => [], + '#submit' => ['::submitDisplayEnable', '::submitDelayDestination'], '#prefix' => '
              • ', "#suffix" => '
              • ', - ); + ]; } // Add a link to view the page unless the view is disabled or has no // path. @@ -413,118 +426,118 @@ public function getDisplayDetails($view, $display) { else { $url = Url::fromUri("base:$path"); } - $build['top']['actions']['path'] = array( + $build['top']['actions']['path'] = [ '#type' => 'link', '#title' => $this->t('View @display_title', ['@display_title' => $display_title]), - '#options' => array('alt' => array($this->t("Go to the real page for this display"))), + '#options' => ['alt' => [$this->t("Go to the real page for this display")]], '#url' => $url, '#prefix' => '
              • ', "#suffix" => '
              • ', - ); + ]; } } if (!$is_default) { - $build['top']['actions']['duplicate'] = array( + $build['top']['actions']['duplicate'] = [ '#type' => 'submit', '#value' => $this->t('Duplicate @display_title', ['@display_title' => $display_title]), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDisplayDuplicate', '::submitDelayDestination'), + '#limit_validation_errors' => [], + '#submit' => ['::submitDisplayDuplicate', '::submitDelayDestination'], '#prefix' => '
              • ', "#suffix" => '
              • ', - ); + ]; } // Always allow a display to be deleted. - $build['top']['actions']['delete'] = array( + $build['top']['actions']['delete'] = [ '#type' => 'submit', '#value' => $this->t('Delete @display_title', ['@display_title' => $display_title]), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDisplayDelete', '::submitDelayDestination'), + '#limit_validation_errors' => [], + '#submit' => ['::submitDisplayDelete', '::submitDelayDestination'], '#prefix' => '
              • ', "#suffix" => '
              • ', - ); + ]; - foreach (Views::fetchPluginNames('display', NULL, array($view->get('storage')->get('base_table'))) as $type => $label) { + foreach (Views::fetchPluginNames('display', NULL, [$view->get('storage')->get('base_table')]) as $type => $label) { if ($type == $display['display_plugin']) { continue; } - $build['top']['actions']['duplicate_as'][$type] = array( + $build['top']['actions']['duplicate_as'][$type] = [ '#type' => 'submit', '#value' => $this->t('Duplicate as @type', ['@type' => $label]), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDuplicateDisplayAsType', '::submitDelayDestination'), + '#limit_validation_errors' => [], + '#submit' => ['::submitDuplicateDisplayAsType', '::submitDelayDestination'], '#prefix' => '
              • ', '#suffix' => '
              • ', - ); + ]; } } else { - $build['top']['actions']['undo_delete'] = array( + $build['top']['actions']['undo_delete'] = [ '#type' => 'submit', '#value' => $this->t('Undo delete of @display_title', ['@display_title' => $display_title]), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDisplayUndoDelete', '::submitDelayDestination'), + '#limit_validation_errors' => [], + '#submit' => ['::submitDisplayUndoDelete', '::submitDelayDestination'], '#prefix' => '
              • ', "#suffix" => '
              • ', - ); + ]; } if ($is_enabled) { - $build['top']['actions']['disable'] = array( + $build['top']['actions']['disable'] = [ '#type' => 'submit', '#value' => $this->t('Disable @display_title', ['@display_title' => $display_title]), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDisplayDisable', '::submitDelayDestination'), + '#limit_validation_errors' => [], + '#submit' => ['::submitDisplayDisable', '::submitDelayDestination'], '#prefix' => '
              • ', "#suffix" => '
              • ', - ); + ]; } $build['top']['actions']['suffix']['#markup'] = '
              '; // The area above the three columns. - $build['top']['display_title'] = array( + $build['top']['display_title'] = [ '#theme' => 'views_ui_display_tab_setting', '#description' => $this->t('Display name'), '#link' => $view->getExecutable()->displayHandlers->get($display['id'])->optionLink($display_title, 'display_title'), - ); + ]; } - $build['columns'] = array(); - $build['columns']['#theme_wrappers'] = array('container'); - $build['columns']['#attributes'] = array('id' => 'edit-display-settings-main', 'class' => array('clearfix', 'views-display-columns')); + $build['columns'] = []; + $build['columns']['#theme_wrappers'] = ['container']; + $build['columns']['#attributes'] = ['id' => 'edit-display-settings-main', 'class' => ['clearfix', 'views-display-columns']]; - $build['columns']['first']['#theme_wrappers'] = array('container'); - $build['columns']['first']['#attributes'] = array('class' => array('views-display-column', 'first')); + $build['columns']['first']['#theme_wrappers'] = ['container']; + $build['columns']['first']['#attributes'] = ['class' => ['views-display-column', 'first']]; - $build['columns']['second']['#theme_wrappers'] = array('container'); - $build['columns']['second']['#attributes'] = array('class' => array('views-display-column', 'second')); + $build['columns']['second']['#theme_wrappers'] = ['container']; + $build['columns']['second']['#attributes'] = ['class' => ['views-display-column', 'second']]; - $build['columns']['second']['settings'] = array(); - $build['columns']['second']['header'] = array(); - $build['columns']['second']['footer'] = array(); - $build['columns']['second']['empty'] = array(); - $build['columns']['second']['pager'] = array(); + $build['columns']['second']['settings'] = []; + $build['columns']['second']['header'] = []; + $build['columns']['second']['footer'] = []; + $build['columns']['second']['empty'] = []; + $build['columns']['second']['pager'] = []; // The third column buckets are wrapped in details. - $build['columns']['third'] = array( + $build['columns']['third'] = [ '#type' => 'details', '#title' => $this->t('Advanced'), - '#theme_wrappers' => array('details'), - '#attributes' => array( - 'class' => array( + '#theme_wrappers' => ['details'], + '#attributes' => [ + 'class' => [ 'views-display-column', 'third', - ), - ), - ); + ], + ], + ]; // Collapse the details by default. $build['columns']['third']['#open'] = \Drupal::config('views.settings')->get('ui.show.advanced_column'); // Each option (e.g. title, access, display as grid/table/list) fits into one // of several "buckets," or boxes (Format, Fields, Sort, and so on). - $buckets = array(); + $buckets = []; // Fetch options from the display plugin, with a list of buckets they go into. - $options = array(); + $options = []; $view->getExecutable()->displayHandlers->get($display['id'])->optionsSummary($buckets, $options); // Place each option into its bucket. @@ -579,10 +592,10 @@ public function submitDisplayUndoDelete($form, FormStateInterface $form_state) { $view->cacheSet(); // Redirect to the top-level edit page. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $id, - )); + ]); } /** @@ -598,10 +611,10 @@ public function submitDisplayEnable($form, FormStateInterface $form_state) { $view->cacheSet(); // Redirect to the top-level edit page. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $id, - )); + ]); } /** @@ -616,10 +629,10 @@ public function submitDisplayDisable($form, FormStateInterface $form_state) { $view->cacheSet(); // Redirect to the top-level edit page. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $id, - )); + ]); } /** @@ -671,43 +684,43 @@ public function rebuildCurrentTab(ViewUI $view, AjaxResponse $response, $display public function renderDisplayTop(ViewUI $view) { $display_id = $this->displayID; $element['#theme_wrappers'][] = 'views_ui_container'; - $element['#attributes']['class'] = array('views-display-top', 'clearfix'); - $element['#attributes']['id'] = array('views-display-top'); + $element['#attributes']['class'] = ['views-display-top', 'clearfix']; + $element['#attributes']['id'] = ['views-display-top']; // Extra actions for the display - $element['extra_actions'] = array( + $element['extra_actions'] = [ '#type' => 'dropbutton', - '#attributes' => array( + '#attributes' => [ 'id' => 'views-display-extra-actions', - ), - '#links' => array( - 'edit-details' => array( + ], + '#links' => [ + 'edit-details' => [ 'title' => $this->t('Edit view name/description'), 'url' => Url::fromRoute('views_ui.form_edit_details', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display_id]), - 'attributes' => array('class' => array('views-ajax-link')), - ), - 'analyze' => array( + 'attributes' => ['class' => ['views-ajax-link']], + ], + 'analyze' => [ 'title' => $this->t('Analyze view'), 'url' => Url::fromRoute('views_ui.form_analyze', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display_id]), - 'attributes' => array('class' => array('views-ajax-link')), - ), - 'duplicate' => array( + 'attributes' => ['class' => ['views-ajax-link']], + ], + 'duplicate' => [ 'title' => $this->t('Duplicate view'), 'url' => $view->urlInfo('duplicate-form'), - ), - 'reorder' => array( + ], + 'reorder' => [ 'title' => $this->t('Reorder displays'), 'url' => Url::fromRoute('views_ui.form_reorder_displays', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display_id]), - 'attributes' => array('class' => array('views-ajax-link')), - ), - ), - ); + 'attributes' => ['class' => ['views-ajax-link']], + ], + ], + ]; if ($view->access('delete')) { - $element['extra_actions']['#links']['delete'] = array( + $element['extra_actions']['#links']['delete'] = [ 'title' => $this->t('Delete view'), 'url' => $view->urlInfo('delete-form'), - ); + ]; } // Let other modules add additional links here. @@ -715,17 +728,17 @@ public function renderDisplayTop(ViewUI $view) { if (isset($view->type) && $view->type != $this->t('Default')) { if ($view->type == $this->t('Overridden')) { - $element['extra_actions']['#links']['revert'] = array( + $element['extra_actions']['#links']['revert'] = [ 'title' => $this->t('Revert view'), 'href' => "admin/structure/views/view/{$view->id()}/revert", - 'query' => array('destination' => $view->url('edit-form')), - ); + 'query' => ['destination' => $view->url('edit-form')], + ]; } else { - $element['extra_actions']['#links']['delete'] = array( + $element['extra_actions']['#links']['delete'] = [ 'title' => $this->t('Delete view'), 'url' => $view->urlInfo('delete-form'), - ); + ]; } } @@ -740,18 +753,18 @@ public function renderDisplayTop(ViewUI $view) { } // Buttons for adding a new display. - foreach (Views::fetchPluginNames('display', NULL, array($view->get('base_table'))) as $type => $label) { - $element['add_display'][$type] = array( + foreach (Views::fetchPluginNames('display', NULL, [$view->get('base_table')]) as $type => $label) { + $element['add_display'][$type] = [ '#type' => 'submit', - '#value' => $this->t('Add @display', array('@display' => $label)), - '#limit_validation_errors' => array(), - '#submit' => array('::submitDisplayAdd', '::submitDelayDestination'), - '#attributes' => array('class' => array('add-display')), + '#value' => $this->t('Add @display', ['@display' => $label]), + '#limit_validation_errors' => [], + '#submit' => ['::submitDisplayAdd', '::submitDelayDestination'], + '#attributes' => ['class' => ['add-display']], // Allow JavaScript to remove the 'Add ' prefix from the button label when // placing the button in a "Add" dropdown menu. - '#process' => array_merge(array('views_ui_form_button_was_clicked'), $this->elementInfo->getInfoProperty('submit', '#process', array())), - '#values' => array($this->t('Add @display', array('@display' => $label)), $label), - ); + '#process' => array_merge(['views_ui_form_button_was_clicked'], $this->elementInfo->getInfoProperty('submit', '#process', [])), + '#values' => [$this->t('Add @display', ['@display' => $label]), $label], + ]; } return $element; @@ -814,10 +827,10 @@ public function submitDisplayDuplicate($form, FormStateInterface $form_state) { $view->cacheSet(); // Redirect to the new display's edit page. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $new_display_id, - )); + ]); } /** @@ -836,10 +849,10 @@ public function submitDisplayAdd($form, FormStateInterface $form_state) { $view->cacheSet(); // Redirect to the new display's edit page. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $display_id, - )); + ]); } /** @@ -862,10 +875,10 @@ public function submitDuplicateDisplayAsType($form, FormStateInterface $form_sta $view->cacheSet(); // Redirect to the new display's edit page. - $form_state->setRedirect('entity.view.edit_display_form', array( + $form_state->setRedirect('entity.view.edit_display_form', [ 'view' => $view->id(), 'display_id' => $new_display_id, - )); + ]); } /** @@ -875,14 +888,14 @@ public function submitDuplicateDisplayAsType($form, FormStateInterface $form_sta * object emerges out of refactoring. */ public function buildOptionForm(ViewUI $view, $id, $option, $display) { - $option_build = array(); + $option_build = []; $option_build['#theme'] = 'views_ui_display_tab_setting'; $option_build['#description'] = $option['title']; $option_build['#link'] = $view->getExecutable()->displayHandlers->get($display['id'])->optionLink($option['value'], $id, '', empty($option['desc']) ? '' : $option['desc']); - $option_build['#links'] = array(); + $option_build['#links'] = []; if (!empty($option['links']) && is_array($option['links'])) { foreach ($option['links'] as $link_id => $link_value) { $option_build['#settings_links'][] = $view->getExecutable()->displayHandlers->get($display['id'])->optionLink($option['setting'], $link_id, 'views-button-configure', $link_value); @@ -915,9 +928,9 @@ public function getFormBucket(ViewUI $view, $type, $display) { $types = $executable->getHandlerTypes(); - $build = array( - '#theme_wrappers' => array('views_ui_display_tab_bucket'), - ); + $build = [ + '#theme_wrappers' => ['views_ui_display_tab_bucket'], + ]; $build['#overridden'] = FALSE; $build['#defaulted'] = FALSE; @@ -943,11 +956,11 @@ public function getFormBucket(ViewUI $view, $type, $display) { $style_plugin = $executable->style_plugin; $uses_fields = $style_plugin && $style_plugin->usesFields(); if (!$uses_fields) { - $build['fields'][] = array( + $build['fields'][] = [ '#markup' => $this->t('The selected style or row format does not use fields.'), - '#theme_wrappers' => array('views_ui_container'), - '#attributes' => array('class' => array('views-display-setting')), - ); + '#theme_wrappers' => ['views_ui_container'], + '#attributes' => ['class' => ['views-display-setting']], + ]; return $build; } break; @@ -955,47 +968,47 @@ public function getFormBucket(ViewUI $view, $type, $display) { case 'footer': case 'empty': if (!$executable->display_handler->usesAreas()) { - $build[$type][] = array( - '#markup' => $this->t('The selected display type does not use @type plugins', array('@type' => $type)), - '#theme_wrappers' => array('views_ui_container'), - '#attributes' => array('class' => array('views-display-setting')), - ); + $build[$type][] = [ + '#markup' => $this->t('The selected display type does not use @type plugins', ['@type' => $type]), + '#theme_wrappers' => ['views_ui_container'], + '#attributes' => ['class' => ['views-display-setting']], + ]; return $build; } break; } // Create an array of actions to pass to links template. - $actions = array(); + $actions = []; $count_handlers = count($executable->display_handler->getHandlers($type)); // Create the add text variable for the add action. - $add_text = $this->t('Add @type', array('@type' => $types[$type]['ltitle'])); + $add_text = $this->t('Add @type', ['@type' => $types[$type]['ltitle']]); - $actions['add'] = array( + $actions['add'] = [ 'title' => $add_text, 'url' => Url::fromRoute('views_ui.form_add_handler', ['js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type]), - 'attributes' => array('class' => array('icon compact add', 'views-ajax-link'), 'id' => 'views-add-' . $type), - ); + 'attributes' => ['class' => ['icon compact add', 'views-ajax-link'], 'id' => 'views-add-' . $type], + ]; if ($count_handlers > 0) { // Create the rearrange text variable for the rearrange action. - $rearrange_text = $type == 'filter' ? $this->t('And/Or Rearrange filter criteria') : $this->t('Rearrange @type', array('@type' => $types[$type]['ltitle'])); + $rearrange_text = $type == 'filter' ? $this->t('And/Or Rearrange filter criteria') : $this->t('Rearrange @type', ['@type' => $types[$type]['ltitle']]); - $actions['rearrange'] = array( + $actions['rearrange'] = [ 'title' => $rearrange_text, 'url' => $rearrange_url, - 'attributes' => array('class' => array($class, 'views-ajax-link'), 'id' => 'views-rearrange-' . $type), - ); + 'attributes' => ['class' => [$class, 'views-ajax-link'], 'id' => 'views-rearrange-' . $type], + ]; } // Render the array of links - $build['#actions'] = array( + $build['#actions'] = [ '#type' => 'dropbutton', '#links' => $actions, - '#attributes' => array( - 'class' => array('views-ui-settings-bucket-operations'), - ), - ); + '#attributes' => [ + 'class' => ['views-ui-settings-bucket-operations'], + ], + ]; if (!$executable->display_handler->isDefaultDisplay()) { if (!$executable->display_handler->isDefaulted($types[$type]['plural'])) { @@ -1009,14 +1022,14 @@ public function getFormBucket(ViewUI $view, $type, $display) { static $relationships = NULL; if (!isset($relationships)) { // Get relationship labels. - $relationships = array(); + $relationships = []; foreach ($executable->display_handler->getHandlers('relationship') as $id => $handler) { $relationships[$id] = $handler->adminLabel(); } } // Filters can now be grouped so we do a little bit extra: - $groups = array(); + $groups = []; $grouping = FALSE; if ($type == 'filter') { $group_info = $executable->display_handler->getOption('filter_groups'); @@ -1025,28 +1038,28 @@ public function getFormBucket(ViewUI $view, $type, $display) { // "OR" label next to items within the group. if (!empty($group_info['groups']) && (count($group_info['groups']) > 1 || current($group_info['groups']) == 'OR')) { $grouping = TRUE; - $groups = array(0 => array()); + $groups = [0 => []]; } } - $build['fields'] = array(); + $build['fields'] = []; foreach ($executable->display_handler->getOption($types[$type]['plural']) as $id => $field) { // Build the option link for this handler ("Node: ID = article"). - $build['fields'][$id] = array(); + $build['fields'][$id] = []; $build['fields'][$id]['#theme'] = 'views_ui_display_tab_setting'; $handler = $executable->display_handler->getHandler($type, $id); if ($handler->broken()) { $build['fields'][$id]['#class'][] = 'broken'; $field_name = $handler->adminLabel(); - $build['fields'][$id]['#link'] = $this->l($field_name, new Url('views_ui.form_handler', array( + $build['fields'][$id]['#link'] = $this->l($field_name, new Url('views_ui.form_handler', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ), array('attributes' => array('class' => array('views-ajax-link'))))); + ], ['attributes' => ['class' => ['views-ajax-link']]])); continue; } @@ -1057,39 +1070,39 @@ public function getFormBucket(ViewUI $view, $type, $display) { $description = $handler->adminSummary(); $link_text = $field_name . (empty($description) ? '' : " ($description)"); - $link_attributes = array('class' => array('views-ajax-link')); + $link_attributes = ['class' => ['views-ajax-link']]; if (!empty($field['exclude'])) { $link_attributes['class'][] = 'views-field-excluded'; // Add a [hidden] marker, if the field is excluded. $link_text .= ' [' . $this->t('hidden') . ']'; } - $build['fields'][$id]['#link'] = $this->l($link_text, new Url('views_ui.form_handler', array( + $build['fields'][$id]['#link'] = $this->l($link_text, new Url('views_ui.form_handler', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ), array('attributes' => $link_attributes))); + ], ['attributes' => $link_attributes])); $build['fields'][$id]['#class'][] = Html::cleanCssIdentifier($display['id'] . '-' . $type . '-' . $id); if ($executable->display_handler->useGroupBy() && $handler->usesGroupBy()) { - $build['fields'][$id]['#settings_links'][] = $this->l(SafeMarkup::format('@text', array('@text' => $this->t('Aggregation settings'))), new Url('views_ui.form_handler_group', array( + $build['fields'][$id]['#settings_links'][] = $this->l(SafeMarkup::format('@text', ['@text' => $this->t('Aggregation settings')]), new Url('views_ui.form_handler_group', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ), array('attributes' => array('class' => array('views-button-configure', 'views-ajax-link'), 'title' => $this->t('Aggregation settings'))))); + ], ['attributes' => ['class' => ['views-button-configure', 'views-ajax-link'], 'title' => $this->t('Aggregation settings')]])); } if ($handler->hasExtraOptions()) { - $build['fields'][$id]['#settings_links'][] = $this->l(SafeMarkup::format('@text', array('@text' => $this->t('Settings'))), new Url('views_ui.form_handler_extra', array( + $build['fields'][$id]['#settings_links'][] = $this->l(SafeMarkup::format('@text', ['@text' => $this->t('Settings')]), new Url('views_ui.form_handler_extra', [ 'js' => 'nojs', 'view' => $view->id(), 'display_id' => $display['id'], 'type' => $type, 'id' => $id, - ), array('attributes' => array('class' => array('views-button-configure', 'views-ajax-link'), 'title' => $this->t('Settings'))))); + ], ['attributes' => ['class' => ['views-button-configure', 'views-ajax-link'], 'title' => $this->t('Settings')]])); } if ($grouping) { @@ -1106,15 +1119,15 @@ public function getFormBucket(ViewUI $view, $type, $display) { // If using grouping, re-order fields so that they show up properly in the list. if ($type == 'filter' && $grouping) { $store = $build['fields']; - $build['fields'] = array(); + $build['fields'] = []; foreach ($groups as $gid => $contents) { // Display an operator between each group. if (!empty($build['fields'])) { - $build['fields'][] = array( + $build['fields'][] = [ '#theme' => 'views_ui_display_tab_setting', - '#class' => array('views-group-text'), + '#class' => ['views-group-text'], '#link' => ($group_info['operator'] == 'OR' ? $this->t('OR') : $this->t('AND')), - ); + ]; } // Display an operator between each pair of filters within the group. $keys = array_keys($contents); diff --git a/core/modules/views_ui/src/ViewFormBase.php b/core/modules/views_ui/src/ViewFormBase.php index 1533b80c..49cdc495 100644 --- a/core/modules/views_ui/src/ViewFormBase.php +++ b/core/modules/views_ui/src/ViewFormBase.php @@ -88,7 +88,7 @@ public function getDisplayTabs(ViewUI $view) { $executable = $view->getExecutable(); $executable->initDisplay(); $display_id = $this->displayID; - $tabs = array(); + $tabs = []; // Create a tab for each display. foreach ($view->get('display') as $id => $display) { @@ -99,15 +99,15 @@ public function getDisplayTabs(ViewUI $view) { continue; } - $tabs[$id] = array( + $tabs[$id] = [ '#theme' => 'menu_local_task', '#weight' => $display['position'], - '#link' => array( + '#link' => [ 'title' => $this->getDisplayLabel($view, $id), - 'localized_options' => array(), + 'localized_options' => [], 'url' => $view->urlInfo('edit-display-form')->setRouteParameter('display_id', $id), - ), - ); + ], + ]; if (!empty($display['deleted'])) { $tabs[$id]['#link']['localized_options']['attributes']['class'][] = 'views-display-deleted-link'; } diff --git a/core/modules/views_ui/src/ViewListBuilder.php b/core/modules/views_ui/src/ViewListBuilder.php index 112e1c45..42166be1 100644 --- a/core/modules/views_ui/src/ViewListBuilder.php +++ b/core/modules/views_ui/src/ViewListBuilder.php @@ -45,7 +45,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type definition. - * @param \Drupal\Core\Entity\EntityStorageInterface $storage. + * @param \Drupal\Core\Entity\EntityStorageInterface $storage * The entity storage class. * @param \Drupal\Component\Plugin\PluginManagerInterface $display_manager * The views display plugin manager to use. @@ -65,10 +65,10 @@ public function __construct(EntityTypeInterface $entity_type, EntityStorageInter * {@inheritdoc} */ public function load() { - $entities = array( - 'enabled' => array(), - 'disabled' => array(), - ); + $entities = [ + 'enabled' => [], + 'disabled' => [], + ]; foreach (parent::load() as $entity) { if ($entity->status()) { $entities['enabled'][] = $entity; @@ -85,67 +85,73 @@ public function load() { */ public function buildRow(EntityInterface $view) { $row = parent::buildRow($view); - return array( - 'data' => array( - 'view_name' => array( - 'data' => array( - '#theme' => 'views_ui_view_info', - '#view' => $view, - '#displays' => $this->getDisplaysList($view) - ), - ), - 'description' => array( - 'data' => array( + return [ + 'data' => [ + 'view_name' => [ + 'data' => [ + '#plain_text' => $view->label(), + ], + ], + 'machine_name' => [ + 'data' => [ + '#plain_text' => $view->id(), + ], + ], + 'description' => [ + 'data' => [ '#plain_text' => $view->get('description'), - ), - 'data-drupal-selector' => 'views-table-filter-text-source', - ), - 'tag' => array( - 'data' => array( - '#plain_text' => $view->get('tag'), - ), - 'data-drupal-selector' => 'views-table-filter-text-source', - ), - 'path' => array( - 'data' => array( - '#theme' => 'item_list', - '#items' => $this->getDisplayPaths($view), - '#context' => ['list_style' => 'comma-list'], - ), - ), + ], + ], + 'displays' => [ + 'data' => [ + '#theme' => 'views_ui_view_displays_list', + '#displays' => $this->getDisplaysList($view), + ], + ], 'operations' => $row['operations'], - ), - 'title' => $this->t('Machine name: @name', array('@name' => $view->id())), - 'class' => array($view->status() ? 'views-ui-list-enabled' : 'views-ui-list-disabled'), - ); + ], + '#attributes' => [ + 'class' => [$view->status() ? 'views-ui-list-enabled' : 'views-ui-list-disabled'], + ], + ]; } /** * {@inheritdoc} */ public function buildHeader() { - return array( - 'view_name' => array( + return [ + 'view_name' => [ 'data' => $this->t('View name'), - 'class' => array('views-ui-name'), - ), - 'description' => array( + '#attributes' => [ + 'class' => ['views-ui-name'], + ], + ], + 'machine_name' => [ + 'data' => $this->t('Machine name'), + '#attributes' => [ + 'class' => ['views-ui-machine-name'], + ], + ], + 'description' => [ 'data' => $this->t('Description'), - 'class' => array('views-ui-description'), - ), - 'tag' => array( - 'data' => $this->t('Tag'), - 'class' => array('views-ui-tag'), - ), - 'path' => array( - 'data' => $this->t('Path'), - 'class' => array('views-ui-path'), - ), - 'operations' => array( + '#attributes' => [ + 'class' => ['views-ui-description'], + ], + ], + 'displays' => [ + 'data' => $this->t('Displays'), + '#attributes' => [ + 'class' => ['views-ui-displays'], + ], + ], + 'operations' => [ 'data' => $this->t('Operations'), - 'class' => array('views-ui-operations'), - ), - ); + '#attributes' => [ + 'class' => ['views-ui-operations'], + ], + ], + ]; } /** @@ -155,15 +161,15 @@ public function getDefaultOperations(EntityInterface $entity) { $operations = parent::getDefaultOperations($entity); if ($entity->hasLinkTemplate('duplicate-form')) { - $operations['duplicate'] = array( + $operations['duplicate'] = [ 'title' => $this->t('Duplicate'), 'weight' => 15, 'url' => $entity->urlInfo('duplicate-form'), - ); + ]; } // Add AJAX functionality to enable/disable operations. - foreach (array('enable', 'disable') as $op) { + foreach (['enable', 'disable'] as $op) { if (isset($operations[$op])) { $operations[$op]['url'] = $entity->urlInfo($op); // Enable and disable operations should use AJAX. @@ -185,40 +191,37 @@ public function render() { $list['#attached']['library'][] = 'core/drupal.ajax'; $list['#attached']['library'][] = 'views_ui/views_ui.listing'; - $form['filters'] = array( + $form['filters'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('table-filter', 'js-show'), - ), - ); + '#attributes' => [ + 'class' => ['table-filter', 'js-show'], + ], + ]; - $list['filters']['text'] = array( + $list['filters']['text'] = [ '#type' => 'search', '#title' => $this->t('Filter'), '#title_display' => 'invisible', - '#size' => 40, - '#placeholder' => $this->t('Filter by view name or description'), - '#attributes' => array( - 'class' => array('views-filter-text'), + '#size' => 60, + '#placeholder' => $this->t('Filter by view name, machine name, description, or display path'), + '#attributes' => [ + 'class' => ['views-filter-text'], 'data-table' => '.views-listing-table', 'autocomplete' => 'off', - 'title' => $this->t('Enter a part of the view name or description to filter by.'), - ), - ); + 'title' => $this->t('Enter a part of the view name, machine name, description, or display path to filter by.'), + ], + ]; - $list['enabled']['heading']['#markup'] = '

              ' . $this->t('Enabled', array(), array('context' => 'Plural')) . '

              '; - $list['disabled']['heading']['#markup'] = '

              ' . $this->t('Disabled', array(), array('context' => 'Plural')) . '

              '; - foreach (array('enabled', 'disabled') as $status) { + $list['enabled']['heading']['#markup'] = '

              ' . $this->t('Enabled', [], ['context' => 'Plural']) . '

              '; + $list['disabled']['heading']['#markup'] = '

              ' . $this->t('Disabled', [], ['context' => 'Plural']) . '

              '; + foreach (['enabled', 'disabled'] as $status) { $list[$status]['#type'] = 'container'; - $list[$status]['#attributes'] = array('class' => array('views-list-section', $status)); - $list[$status]['table'] = array( - '#type' => 'table', - '#attributes' => array( - 'class' => array('views-listing-table'), - ), - '#header' => $this->buildHeader(), - '#rows' => array(), - ); + $list[$status]['#attributes'] = ['class' => ['views-list-section', $status]]; + $list[$status]['table'] = [ + '#theme' => 'views_ui_views_listing_table', + '#headers' => $this->buildHeader(), + '#attributes' => ['class' => ['views-listing-table', $status]], + ]; foreach ($entities[$status] as $entity) { $list[$status]['table']['#rows'][$entity->id()] = $this->buildRow($entity); } @@ -241,47 +244,34 @@ public function render() { * An array of display types that this view includes. */ protected function getDisplaysList(EntityInterface $view) { - $displays = array(); - foreach ($view->get('display') as $display) { - $definition = $this->displayManager->getDefinition($display['display_plugin']); - if (!empty($definition['admin'])) { - // Cast the admin label to a string since it is an object. - // @see \Drupal\Core\StringTranslation\TranslatableMarkup - $displays[] = (string) $definition['admin']; - } - } - - sort($displays); - return $displays; - } + $displays = []; - /** - * Gets a list of paths assigned to the view. - * - * @param \Drupal\Core\Entity\EntityInterface $view - * The view entity. - * - * @return array - * An array of paths for this view. - */ - protected function getDisplayPaths(EntityInterface $view) { - $all_paths = array(); $executable = $view->getExecutable(); $executable->initDisplay(); foreach ($executable->displayHandlers as $display) { - if ($display->hasPath()) { - $path = $display->getPath(); - if ($view->status() && strpos($path, '%') === FALSE) { - // @todo Views should expect and store a leading /. See: - // https://www.drupal.org/node/2423913 - $all_paths[] = \Drupal::l('/' . $path, Url::fromUserInput('/' . $path)); - } - else { - $all_paths[] = '/' . $path; + $rendered_path = FALSE; + $definition = $display->getPluginDefinition(); + if (!empty($definition['admin'])) { + if ($display->hasPath()) { + $path = $display->getPath(); + if ($view->status() && strpos($path, '%') === FALSE) { + // @todo Views should expect and store a leading /. See: + // https://www.drupal.org/node/2423913 + $rendered_path = \Drupal::l('/' . $path, Url::fromUserInput('/' . $path)); + } + else { + $rendered_path = '/' . $path; + } } + $displays[] = [ + 'display' => $definition['admin'], + 'path' => $rendered_path, + ]; } } - return array_unique($all_paths); + + sort($displays); + return $displays; } } diff --git a/core/modules/views_ui/src/ViewPreviewForm.php b/core/modules/views_ui/src/ViewPreviewForm.php index 48e22c5b..2cc25332 100644 --- a/core/modules/views_ui/src/ViewPreviewForm.php +++ b/core/modules/views_ui/src/ViewPreviewForm.php @@ -22,43 +22,43 @@ public function form(array $form, FormStateInterface $form_state) { $form_state->disableCache(); - $form['controls']['#attributes'] = array('class' => array('clearfix')); + $form['controls']['#attributes'] = ['class' => ['clearfix']]; - $form['controls']['title'] = array( + $form['controls']['title'] = [ '#prefix' => '

              ', '#markup' => $this->t('Preview'), '#suffix' => '

              ', - ); + ]; // Add a checkbox controlling whether or not this display auto-previews. - $form['controls']['live_preview'] = array( + $form['controls']['live_preview'] = [ '#type' => 'checkbox', '#id' => 'edit-displays-live-preview', '#title' => $this->t('Auto preview'), '#default_value' => \Drupal::config('views.settings')->get('ui.always_live_preview'), - ); + ]; // Add the arguments textfield - $form['controls']['view_args'] = array( + $form['controls']['view_args'] = [ '#type' => 'textfield', '#title' => $this->t('Preview with contextual filters:'), - '#description' => $this->t('Separate contextual filter values with a "/". For example, %example.', array('%example' => '40/12/10')), + '#description' => $this->t('Separate contextual filter values with a "/". For example, %example.', ['%example' => '40/12/10']), '#id' => 'preview-args', - ); + ]; - $args = array(); + $args = []; if (!$form_state->isValueEmpty('view_args')) { $args = explode('/', $form_state->getValue('view_args')); } $user_input = $form_state->getUserInput(); if ($form_state->get('show_preview') || !empty($user_input['js'])) { - $form['preview'] = array( + $form['preview'] = [ '#weight' => 110, - '#theme_wrappers' => array('container'), - '#attributes' => array('id' => 'views-live-preview', 'class' => 'views-live-preview'), + '#theme_wrappers' => ['container'], + '#attributes' => ['id' => 'views-live-preview', 'class' => ['views-live-preview']], 'preview' => $view->renderPreview($this->displayID, $args), - ); + ]; } $uri = $view->urlInfo('preview-form'); $uri->setRouteParameter('display_id', $this->displayID); @@ -72,27 +72,27 @@ public function form(array $form, FormStateInterface $form_state) { */ protected function actions(array $form, FormStateInterface $form_state) { $view = $this->entity; - return array( - '#attributes' => array( + return [ + '#attributes' => [ 'id' => 'preview-submit-wrapper', - 'class' => array('preview-submit-wrapper') - ), - 'button' => array( + 'class' => ['preview-submit-wrapper'] + ], + 'button' => [ '#type' => 'submit', '#value' => $this->t('Update preview'), - '#attributes' => array('class' => array('arguments-preview')), - '#submit' => array('::submitPreview'), + '#attributes' => ['class' => ['arguments-preview']], + '#submit' => ['::submitPreview'], '#id' => 'preview-submit', - '#ajax' => array( + '#ajax' => [ 'url' => Url::fromRoute('entity.view.preview_form', ['view' => $view->id(), 'display_id' => $this->displayID]), 'wrapper' => 'views-preview-wrapper', 'event' => 'click', - 'progress' => array('type' => 'fullscreen'), + 'progress' => ['type' => 'fullscreen'], 'method' => 'replaceWith', 'disable-refocus' => TRUE, - ), - ), - ); + ], + ], + ]; } /** diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php index cb222b0b..2e7fabd6 100644 --- a/core/modules/views_ui/src/ViewUI.php +++ b/core/modules/views_ui/src/ViewUI.php @@ -4,7 +4,6 @@ use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Timer; -use Drupal\Component\Utility\Xss; use Drupal\Core\EventSubscriber\AjaxResponseSubscriber; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Views; @@ -107,7 +106,7 @@ class ViewUI implements ViewEntityInterface { * * @var array */ - public static $forms = array( + public static $forms = [ 'add-handler' => '\Drupal\views_ui\Form\Ajax\AddItem', 'analyze' => '\Drupal\views_ui\Form\Ajax\Analyze', 'handler' => '\Drupal\views_ui\Form\Ajax\ConfigHandler', @@ -118,7 +117,7 @@ class ViewUI implements ViewEntityInterface { 'rearrange' => '\Drupal\views_ui\Form\Ajax\Rearrange', 'rearrange-filter' => '\Drupal\views_ui\Form\Ajax\RearrangeFilter', 'reorder-displays' => '\Drupal\views_ui\Form\Ajax\ReorderDisplays', - ); + ]; /** * Whether the config is being created, updated or deleted through the @@ -277,22 +276,22 @@ public function standardCancel($form, FormStateInterface $form_state) { * docblock outdated? */ public function getStandardButtons(&$form, FormStateInterface $form_state, $form_id, $name = NULL) { - $form['actions'] = array( + $form['actions'] = [ '#type' => 'actions', - ); + ]; if (empty($name)) { $name = t('Apply'); if (!empty($this->stack) && count($this->stack) > 1) { $name = t('Apply and continue'); } - $names = array(t('Apply'), t('Apply and continue')); + $names = [t('Apply'), t('Apply and continue')]; } // Forms that are purely informational set an ok_button flag, so we know not // to create an "Apply" button for them. if (!$form_state->get('ok_button')) { - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $name, '#id' => 'edit-submit-' . Html::getUniqueId($form_id), @@ -301,9 +300,9 @@ public function getStandardButtons(&$form, FormStateInterface $form_state, $form // the current display. Since we have no way of knowing at this point // which display the user wants to update, views_ui_standard_submit will // take care of running the regular submit handler as appropriate. - '#submit' => array(array($this, 'standardSubmit')), + '#submit' => [[$this, 'standardSubmit']], '#button_type' => 'primary', - ); + ]; // Form API button click detection requires the button's #value to be the // same between the form build of the initial page request, and the // initial form build of the request processing the form submission. @@ -315,21 +314,21 @@ public function getStandardButtons(&$form, FormStateInterface $form_state, $form // button labels. if (isset($names)) { $form['actions']['submit']['#values'] = $names; - $form['actions']['submit']['#process'] = array_merge(array('views_ui_form_button_was_clicked'), \Drupal::service('element_info')->getInfoProperty($form['actions']['submit']['#type'], '#process', array())); + $form['actions']['submit']['#process'] = array_merge(['views_ui_form_button_was_clicked'], \Drupal::service('element_info')->getInfoProperty($form['actions']['submit']['#type'], '#process', [])); } // If a validation handler exists for the form, assign it to this button. $form['actions']['submit']['#validate'][] = [$form_state->getFormObject(), 'validateForm']; } // Create a "Cancel" button. For purely informational forms, label it "OK". - $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : array($this, 'standardCancel'); - $form['actions']['cancel'] = array( + $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : [$this, 'standardCancel']; + $form['actions']['cancel'] = [ '#type' => 'submit', '#value' => !$form_state->get('ok_button') ? t('Cancel') : t('Ok'), - '#submit' => array($cancel_submit), - '#validate' => array(), - '#limit_validation_errors' => array(), - ); + '#submit' => [$cancel_submit], + '#validate' => [], + '#limit_validation_errors' => [], + ]; // Compatibility, to be removed later: // TODO: When is "later"? // We used to set these items on the form, but now we want them on the $form_state: @@ -348,11 +347,11 @@ public function getStandardButtons(&$form, FormStateInterface $form_state, $form */ public function getOverrideValues($form, FormStateInterface $form_state) { // Make sure the dropdown exists in the first place. - if ($form_state->hasValue(array('override', 'dropdown'))) { + if ($form_state->hasValue(['override', 'dropdown'])) { // #default_value is used to determine whether it was the default value or not. // So the available options are: $display, 'default' and 'default_revert', not 'defaults'. $was_defaulted = ($form['override']['dropdown']['#default_value'] === 'defaults'); - $dropdown = $form_state->getValue(array('override', 'dropdown')); + $dropdown = $form_state->getValue(['override', 'dropdown']); $is_defaulted = ($dropdown === 'default'); $revert = ($dropdown === 'default_revert'); @@ -369,7 +368,7 @@ public function getOverrideValues($form, FormStateInterface $form_state) { $revert = FALSE; } - return array($was_defaulted, $is_defaulted, $revert); + return [$was_defaulted, $is_defaulted, $revert]; } /** @@ -383,10 +382,10 @@ public function addFormToStack($key, $display_id, $type, $id = NULL, $top = FALS Html::resetSeenIds(); if (empty($this->stack)) { - $this->stack = array(); + $this->stack = []; } - $stack = array(implode('-', array_filter(array($key, $this->id(), $display_id, $type, $id))), $key, $display_id, $type, $id); + $stack = [implode('-', array_filter([$key, $this->id(), $display_id, $type, $id])), $key, $display_id, $type, $id]; // If we're being asked to add this form to the bottom of the stack, no // special logic is required. Our work is equally easy if we were asked to add // to the top of the stack, but there's nothing in it yet. @@ -463,10 +462,10 @@ public function submitItemAdd($form, FormStateInterface $form_state) { if (isset($types[$type]['type'])) { $key = $types[$type]['type']; } - $item = array( + $item = [ 'table' => $table, 'field' => $field, - ); + ]; $handler = Views::handlerManager($key)->getHandler($item); if ($this->getExecutable()->displayHandlers->get('default')->useGroupBy() && $handler->usesGroupBy()) { $this->addFormToStack('handler-group', $display_id, $type, $id); @@ -512,7 +511,7 @@ public function endQueryCapture() { $this->additionalQueries = $queries; } - public function renderPreview($display_id, $args = array()) { + public function renderPreview($display_id, $args = []) { // Save the current path so it can be restored before returning from this function. $request_stack = \Drupal::requestStack(); $current_request = $request_stack->getCurrentRequest(); @@ -531,7 +530,7 @@ public function renderPreview($display_id, $args = array()) { $combined = $show_query && $show_stats; - $rows = array('query' => array(), 'statistics' => array()); + $rows = ['query' => [], 'statistics' => []]; $errors = $executable->validate(); $executable->destroy(); @@ -545,7 +544,7 @@ public function renderPreview($display_id, $args = array()) { // have some input in the query parameters, so we merge request() and // query() to ensure we get it all. $exposed_input = array_merge(\Drupal::request()->request->all(), \Drupal::request()->query->all()); - foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER, 'ajax_page_state', 'form_id', 'form_build_id', 'form_token') as $key) { + foreach (['view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER, 'ajax_page_state', 'form_id', 'form_build_id', 'form_token'] as $key) { if (isset($exposed_input[$key])) { unset($exposed_input[$key]); } @@ -554,7 +553,7 @@ public function renderPreview($display_id, $args = array()) { if (!$executable->setDisplay($display_id)) { return [ - '#markup' => t('Invalid display id @display', array('@display' => $display_id)), + '#markup' => t('Invalid display id @display', ['@display' => $display_id]), ]; } @@ -620,76 +619,80 @@ public function renderPreview($display_id, $args = array()) { if ($show_query) { $query_string = $executable->build_info['query']; // Only the sql default class has a method getArguments. - $quoted = array(); + $quoted = []; if ($executable->query instanceof Sql) { $quoted = $query_string->getArguments(); $connection = Database::getConnection(); foreach ($quoted as $key => $val) { if (is_array($val)) { - $quoted[$key] = implode(', ', array_map(array($connection, 'quote'), $val)); + $quoted[$key] = implode(', ', array_map([$connection, 'quote'], $val)); } else { $quoted[$key] = $connection->quote($val); } } } - $rows['query'][] = array( - array( - 'data' => array( + $rows['query'][] = [ + [ + 'data' => [ '#type' => 'inline_template', '#template' => "{% trans 'Query' %}", - ), - ), - array( - 'data' => array( + ], + ], + [ + 'data' => [ '#type' => 'inline_template', '#template' => '
              {{ query }}
              ', - '#context' => array('query' => strtr($query_string, $quoted)), - ), - ), - ); + '#context' => ['query' => strtr($query_string, $quoted)], + ], + ], + ]; if (!empty($this->additionalQueries)) { - $queries[] = array( + $queries[] = [ '#prefix' => '', '#markup' => t('These queries were run during view rendering:'), '#suffix' => '', - ); + ]; foreach ($this->additionalQueries as $query) { $query_string = strtr($query['query'], $query['args']); - $queries[] = array( + $queries[] = [ '#prefix' => "\n", - '#markup' => t('[@time ms] @query', array('@time' => round($query['time'] * 100000, 1) / 100000.0, '@query' => $query_string)), - ); + '#markup' => t('[@time ms] @query', ['@time' => round($query['time'] * 100000, 1) / 100000.0, '@query' => $query_string]), + ]; } - $rows['query'][] = array( - array( - 'data' => array( + $rows['query'][] = [ + [ + 'data' => [ '#type' => 'inline_template', '#template' => "{% trans 'Other queries' %}", - ), - ), - array( - 'data' => array( + ], + ], + [ + 'data' => [ '#prefix' => '
              ',
                                    'queries' => $queries,
                                    '#suffix' => '
              ', - ), - ), - ); + ], + ], + ]; } } if ($show_info) { - $rows['query'][] = array( - array( - 'data' => array( + $rows['query'][] = [ + [ + 'data' => [ '#type' => 'inline_template', '#template' => "{% trans 'Title' %}", - ), - ), - Xss::filterAdmin($executable->getTitle()), - ); + ], + ], + [ + 'data' => [ + '#markup' => $executable->getTitle(), + ], + ], + ]; if (isset($path)) { // @todo Views should expect and store a leading /. See: // https://www.drupal.org/node/2423913 @@ -698,51 +701,51 @@ public function renderPreview($display_id, $args = array()) { else { $path = t('This display has no path.'); } - $rows['query'][] = array( - array( - 'data' => array( + $rows['query'][] = [ + [ + 'data' => [ '#prefix' => '', '#markup' => t('Path'), '#suffix' => '', - ), - ), - array( - 'data' => array( + ], + ], + [ + 'data' => [ '#markup' => $path, - ), - ) - ); + ], + ] + ]; } if ($show_stats) { - $rows['statistics'][] = array( - array( - 'data' => array( + $rows['statistics'][] = [ + [ + 'data' => [ '#type' => 'inline_template', '#template' => "{% trans 'Query build time' %}", - ), - ), - t('@time ms', array('@time' => intval($executable->build_time * 100000) / 100)), - ); - - $rows['statistics'][] = array( - array( - 'data' => array( + ], + ], + t('@time ms', ['@time' => intval($executable->build_time * 100000) / 100]), + ]; + + $rows['statistics'][] = [ + [ + 'data' => [ '#type' => 'inline_template', '#template' => "{% trans 'Query execute time' %}", - ), - ), - t('@time ms', array('@time' => intval($executable->execute_time * 100000) / 100)), - ); - - $rows['statistics'][] = array( - array( - 'data' => array( + ], + ], + t('@time ms', ['@time' => intval($executable->execute_time * 100000) / 100]), + ]; + + $rows['statistics'][] = [ + [ + 'data' => [ '#type' => 'inline_template', '#template' => "{% trans 'View render time' %}", - ), - ), - t('@time ms', array('@time' => intval($this->render_time * 100) / 100)), - ); + ], + ], + t('@time ms', ['@time' => intval($this->render_time * 100) / 100]), + ]; } \Drupal::moduleHandler()->alter('views_preview_info', $rows, $executable); } @@ -750,36 +753,36 @@ public function renderPreview($display_id, $args = array()) { // No query was run. Display that information in place of either the // query or the performance statistics, whichever comes first. if ($combined || ($show_location === 'above')) { - $rows['query'][] = array( - array( - 'data' => array( + $rows['query'][] = [ + [ + 'data' => [ '#prefix' => '', '#markup' => t('Query'), '#suffix' => '', - ), - ), - array( - 'data' => array( + ], + ], + [ + 'data' => [ '#markup' => t('No query was run'), - ), - ), - ); + ], + ], + ]; } else { - $rows['statistics'][] = array( - array( - 'data' => array( + $rows['statistics'][] = [ + [ + 'data' => [ '#prefix' => '', '#markup' => t('Query'), '#suffix' => '', - ), - ), - array( - 'data' => array( + ], + ], + [ + 'data' => [ '#markup' => t('No query was run'), - ), - ), - ); + ], + ], + ]; } } } @@ -795,12 +798,12 @@ public function renderPreview($display_id, $args = array()) { // Assemble the preview, the query info, and the query statistics in the // requested order. - $table = array( + $table = [ '#type' => 'table', '#prefix' => '
              ', '#suffix' => '
              ', '#rows' => array_merge($rows['query'], $rows['statistics']), - ); + ]; if ($show_location == 'above') { $output = [ @@ -843,7 +846,7 @@ public function getFormProgress() { $current = reset($keys) + 1; $total = end($keys) + 1; if ($total > 1) { - $progress = array(); + $progress = []; $progress['current'] = $current; $progress['total'] = $total; } @@ -892,7 +895,7 @@ public function isLocked() { * Passes through all unknown calls onto the storage object. */ public function __call($method, $args) { - return call_user_func_array(array($this->storage, $method), $args); + return call_user_func_array([$this->storage, $method], $args); } /** @@ -968,7 +971,7 @@ public static function loadMultiple(array $ids = NULL) { /** * {@inheritdoc} */ - public static function create(array $values = array()) { + public static function create(array $values = []) { return View::create($values); } @@ -1167,7 +1170,7 @@ public function referencedEntities() { /** * {@inheritdoc} */ - public function url($rel = 'edit-form', $options = array()) { + public function url($rel = 'edit-form', $options = []) { return $this->storage->url($rel, $options); } diff --git a/core/modules/views_ui/templates/views-ui-view-displays-list.html.twig b/core/modules/views_ui/templates/views-ui-view-displays-list.html.twig new file mode 100644 index 00000000..1c7d6210 --- /dev/null +++ b/core/modules/views_ui/templates/views-ui-view-displays-list.html.twig @@ -0,0 +1,24 @@ +{# +/** + * @file + * Default theme implementation for views displays on the views listing page. + * + * Available variables: + * - displays: Contains multiple display instances. Each display contains: + * - display: Display name. + * - path: Path to display, if any. + * + * @ingroup themeable + */ +#} +
                + {% for display in displays %} +
              • + {% if display.path %} + {{ display.display }} ({{ display.path }}) + {% else %} + {{ display.display }} + {% endif %} +
              • + {% endfor %} +
              diff --git a/core/modules/views_ui/templates/views-ui-views-listing-table.html.twig b/core/modules/views_ui/templates/views-ui-views-listing-table.html.twig new file mode 100644 index 00000000..207462e8 --- /dev/null +++ b/core/modules/views_ui/templates/views-ui-views-listing-table.html.twig @@ -0,0 +1,49 @@ +{# +/** + * @file + * Default theme implementation for views listing table. + * + * Available variables: + * - headers: Contains table headers. + * - rows: Contains multiple rows. Each row contains: + * - view_name: The human-readable name of the view. + * - machine_name: Machine name of the view. + * - description: The description of the view. + * - displays: List of displays attached to the view. + * - operations: List of available operations. + * + * @see template_preprocess_views_ui_views_listing_table() + * + * @ingroup themeable + */ +#} + +
    + + {% for header in headers %} + {{ header.data }} + {% endfor %} + + + + {% for row in rows %} + + + + + + + + {% endfor %} + +
    ', ' + * Drupal.quickedit.EditorView.prototype.initialize.call(this, options); + * + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * An object with the following keys: + * @param {Drupal.quickedit.EditorModel} options.model + * The in-place editor state model. + * @param {Drupal.quickedit.FieldModel} options.fieldModel + * The field model. + * + * @see Drupal.quickedit.EditorModel + * @see Drupal.quickedit.editors.plain_text + */ + initialize(options) { + this.fieldModel = options.fieldModel; + this.listenTo(this.fieldModel, 'change:state', this.stateChange); + }, + + /** + * @inheritdoc + */ + remove() { + // The el property is the field, which should not be removed. Remove the + // pointer to it, then call Backbone.View.prototype.remove(). + this.setElement(); + Backbone.View.prototype.remove.call(this); + }, + + /** + * Returns the edited element. + * + * For some single cardinality fields, it may be necessary or useful to + * not in-place edit (and hence decorate) the DOM element with the + * data-quickedit-field-id attribute (which is the field's wrapper), but a + * specific element within the field's wrapper. + * e.g. using a WYSIWYG editor on a body field should happen on the DOM + * element containing the text itself, not on the field wrapper. + * + * @return {jQuery} + * A jQuery-wrapped DOM element. + * + * @see Drupal.quickedit.editors.plain_text + */ + getEditedElement() { + return this.$el; + }, + + /** + * + * @return {object} + * Returns 3 Quick Edit UI settings that depend on the in-place editor: + * - Boolean padding: indicates whether padding should be applied to the + * edited element, to guarantee legibility of text. + * - Boolean unifiedToolbar: provides the in-place editor with the ability + * to insert its own toolbar UI into Quick Edit's tightly integrated + * toolbar. + * - Boolean fullWidthToolbar: indicates whether Quick Edit's tightly + * integrated toolbar should consume the full width of the element, + * rather than being just long enough to accommodate a label. + */ + getQuickEditUISettings() { + return { padding: false, unifiedToolbar: false, fullWidthToolbar: false, popup: false }; + }, + + /** + * Determines the actions to take given a change of state. + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * The quickedit `FieldModel` that holds the state. + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.FieldModel.states}. + */ + stateChange(fieldModel, state) { + const from = fieldModel.previous('state'); + const to = state; + switch (to) { + case 'inactive': + // An in-place editor view will not yet exist in this state, hence + // this will never be reached. Listed for sake of completeness. + break; + + case 'candidate': + // Nothing to do for the typical in-place editor: it should not be + // visible yet. Except when we come from the 'invalid' state, then we + // clean up. + if (from === 'invalid') { + this.removeValidationErrors(); + } + break; + + case 'highlighted': + // Nothing to do for the typical in-place editor: it should not be + // visible yet. + break; + + case 'activating': + // The user has indicated he wants to do in-place editing: if + // something needs to be loaded (CSS/JavaScript/server data/…), then + // do so at this stage, and once the in-place editor is ready, + // set the 'active' state. A "loading" indicator will be shown in the + // UI for as long as the field remains in this state. + var loadDependencies = function (callback) { + // Do the loading here. + callback(); + }; + loadDependencies(() => { + fieldModel.set('state', 'active'); + }); + break; + + case 'active': + // The user can now actually use the in-place editor. + break; + + case 'changed': + // Nothing to do for the typical in-place editor. The UI will show an + // indicator that the field has changed. + break; + + case 'saving': + // When the user has indicated he wants to save his changes to this + // field, this state will be entered. If the previous saving attempt + // resulted in validation errors, the previous state will be + // 'invalid'. Clean up those validation errors while the user is + // saving. + if (from === 'invalid') { + this.removeValidationErrors(); + } + this.save(); + break; + + case 'saved': + // Nothing to do for the typical in-place editor. Immediately after + // being saved, a field will go to the 'candidate' state, where it + // should no longer be visible (after all, the field will then again + // just be a *candidate* to be in-place edited). + break; + + case 'invalid': + // The modified field value was attempted to be saved, but there were + // validation errors. + this.showValidationErrors(); + break; + } + }, + + /** + * Reverts the modified value to the original, before editing started. + */ + revert() { + // A no-op by default; each editor should implement reverting itself. + // Note that if the in-place editor does not cause the FieldModel's + // element to be modified, then nothing needs to happen. + }, + + /** + * Saves the modified value in the in-place editor for this field. + */ + save() { + const fieldModel = this.fieldModel; + const editorModel = this.model; + const backstageId = `quickedit_backstage-${this.fieldModel.id.replace(/[\/\[\]\_\s]/g, '-')}`; + + function fillAndSubmitForm(value) { + const $form = $(`#${backstageId}`).find('form'); + // Fill in the value in any that isn't hidden or a submit + // button. + $form.find(':input[type!="hidden"][type!="submit"]:not(select)') + // Don't mess with the node summary. + .not('[name$="\\[summary\\]"]').val(value); + // Submit the form. + $form.find('.quickedit-form-submit').trigger('click.quickedit'); + } + + const formOptions = { + fieldID: this.fieldModel.get('fieldID'), + $el: this.$el, + nocssjs: true, + other_view_modes: fieldModel.findOtherViewModes(), + // Reset an existing entry for this entity in the PrivateTempStore (if + // any) when saving the field. Logically speaking, this should happen in + // a separate request because this is an entity-level operation, not a + // field-level operation. But that would require an additional request, + // that might not even be necessary: it is only when a user saves a + // first changed field for an entity that this needs to happen: + // precisely now! + reset: !this.fieldModel.get('entity').get('inTempStore'), + }; + + const self = this; + Drupal.quickedit.util.form.load(formOptions, (form, ajax) => { + // Create a backstage area for storing forms that are hidden from view + // (hence "backstage" — since the editing doesn't happen in the form, it + // happens "directly" in the content, the form is only used for saving). + const $backstage = $(Drupal.theme('quickeditBackstage', { id: backstageId })).appendTo('body'); + // Hidden forms are stuffed into the backstage container for this field. + const $form = $(form).appendTo($backstage); + // Disable the browser's HTML5 validation; we only care about server- + // side validation. (Not disabling this will actually cause problems + // because browsers don't like to set HTML5 validation errors on hidden + // forms.) + $form.prop('novalidate', true); + const $submit = $form.find('.quickedit-form-submit'); + self.formSaveAjax = Drupal.quickedit.util.form.ajaxifySaving(formOptions, $submit); + + function removeHiddenForm() { + Drupal.quickedit.util.form.unajaxifySaving(self.formSaveAjax); + delete self.formSaveAjax; + $backstage.remove(); + } + + // Successfully saved. + self.formSaveAjax.commands.quickeditFieldFormSaved = function (ajax, response, status) { + removeHiddenForm(); + // First, transition the state to 'saved'. + fieldModel.set('state', 'saved'); + // Second, set the 'htmlForOtherViewModes' attribute, so that when + // this field is rerendered, the change can be propagated to other + // instances of this field, which may be displayed in different view + // modes. + fieldModel.set('htmlForOtherViewModes', response.other_view_modes); + // Finally, set the 'html' attribute on the field model. This will + // cause the field to be rerendered. + fieldModel.set('html', response.data); + }; + + // Unsuccessfully saved; validation errors. + self.formSaveAjax.commands.quickeditFieldFormValidationErrors = function (ajax, response, status) { + removeHiddenForm(); + editorModel.set('validationErrors', response.data); + fieldModel.set('state', 'invalid'); + }; + + // The quickeditFieldForm AJAX command is only called upon loading the + // form for the first time, and when there are validation errors in the + // form; Form API then marks which form items have errors. This is + // useful for the form-based in-place editor, but pointless for any + // other: the form itself won't be visible at all anyway! So, we just + // ignore it. + self.formSaveAjax.commands.quickeditFieldForm = function () {}; + + fillAndSubmitForm(editorModel.get('currentValue')); + }); + }, + + /** + * Shows validation error messages. + * + * Should be called when the state is changed to 'invalid'. + */ + showValidationErrors() { + const $errors = $('
    ') + .append(this.model.get('validationErrors')); + this.getEditedElement() + .addClass('quickedit-validation-error') + .after($errors); + }, + + /** + * Cleans up validation error messages. + * + * Should be called when the state is changed to 'candidate' or 'saving'. In + * the case of the latter: the user has modified the value in the in-place + * editor again to attempt to save again. In the case of the latter: the + * invalid value was discarded. + */ + removeValidationErrors() { + this.getEditedElement() + .removeClass('quickedit-validation-error') + .next('.quickedit-validation-errors') + .remove(); + }, + + }); +}(jQuery, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/views/EditorView.js b/core/modules/quickedit/js/views/EditorView.js index 5e041db0..ad5c1317 100644 --- a/core/modules/quickedit/js/views/EditorView.js +++ b/core/modules/quickedit/js/views/EditorView.js @@ -1,134 +1,44 @@ /** - * @file - * An abstract Backbone View that controls an in-place editor. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Backbone, Drupal) { - - 'use strict'; - - Drupal.quickedit.EditorView = Backbone.View.extend(/** @lends Drupal.quickedit.EditorView# */{ - - /** - * A base implementation that outlines the structure for in-place editors. - * - * Specific in-place editor implementations should subclass (extend) this - * View and override whichever method they deem necessary to override. - * - * Typically you would want to override this method to set the - * originalValue attribute in the FieldModel to such a value that your - * in-place editor can revert to the original value when necessary. - * - * @example - * - * Drupal.quickedit.EditorView.prototype.initialize.call(this, options); - * - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * An object with the following keys: - * @param {Drupal.quickedit.EditorModel} options.model - * The in-place editor state model. - * @param {Drupal.quickedit.FieldModel} options.fieldModel - * The field model. - * - * @see Drupal.quickedit.EditorModel - * @see Drupal.quickedit.editors.plain_text - */ - initialize: function (options) { + Drupal.quickedit.EditorView = Backbone.View.extend({ + initialize: function initialize(options) { this.fieldModel = options.fieldModel; this.listenTo(this.fieldModel, 'change:state', this.stateChange); }, - - /** - * @inheritdoc - */ - remove: function () { - // The el property is the field, which should not be removed. Remove the - // pointer to it, then call Backbone.View.prototype.remove(). + remove: function remove() { this.setElement(); Backbone.View.prototype.remove.call(this); }, - - /** - * Returns the edited element. - * - * For some single cardinality fields, it may be necessary or useful to - * not in-place edit (and hence decorate) the DOM element with the - * data-quickedit-field-id attribute (which is the field's wrapper), but a - * specific element within the field's wrapper. - * e.g. using a WYSIWYG editor on a body field should happen on the DOM - * element containing the text itself, not on the field wrapper. - * - * @return {jQuery} - * A jQuery-wrapped DOM element. - * - * @see Drupal.quickedit.editors.plain_text - */ - getEditedElement: function () { + getEditedElement: function getEditedElement() { return this.$el; }, - - /** - * - * @return {object} - * Returns 3 Quick Edit UI settings that depend on the in-place editor: - * - Boolean padding: indicates whether padding should be applied to the - * edited element, to guarantee legibility of text. - * - Boolean unifiedToolbar: provides the in-place editor with the ability - * to insert its own toolbar UI into Quick Edit's tightly integrated - * toolbar. - * - Boolean fullWidthToolbar: indicates whether Quick Edit's tightly - * integrated toolbar should consume the full width of the element, - * rather than being just long enough to accommodate a label. - */ - getQuickEditUISettings: function () { - return {padding: false, unifiedToolbar: false, fullWidthToolbar: false, popup: false}; + getQuickEditUISettings: function getQuickEditUISettings() { + return { padding: false, unifiedToolbar: false, fullWidthToolbar: false, popup: false }; }, - - /** - * Determines the actions to take given a change of state. - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * The quickedit `FieldModel` that holds the state. - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.FieldModel.states}. - */ - stateChange: function (fieldModel, state) { + stateChange: function stateChange(fieldModel, state) { var from = fieldModel.previous('state'); var to = state; switch (to) { case 'inactive': - // An in-place editor view will not yet exist in this state, hence - // this will never be reached. Listed for sake of completeness. break; case 'candidate': - // Nothing to do for the typical in-place editor: it should not be - // visible yet. Except when we come from the 'invalid' state, then we - // clean up. if (from === 'invalid') { this.removeValidationErrors(); } break; case 'highlighted': - // Nothing to do for the typical in-place editor: it should not be - // visible yet. break; case 'activating': - // The user has indicated he wants to do in-place editing: if - // something needs to be loaded (CSS/JavaScript/server data/…), then - // do so at this stage, and once the in-place editor is ready, - // set the 'active' state. A "loading" indicator will be shown in the - // UI for as long as the field remains in this state. - var loadDependencies = function (callback) { - // Do the loading here. + var loadDependencies = function loadDependencies(callback) { callback(); }; loadDependencies(function () { @@ -137,20 +47,12 @@ break; case 'active': - // The user can now actually use the in-place editor. break; case 'changed': - // Nothing to do for the typical in-place editor. The UI will show an - // indicator that the field has changed. break; case 'saving': - // When the user has indicated he wants to save his changes to this - // field, this state will be entered. If the previous saving attempt - // resulted in validation errors, the previous state will be - // 'invalid'. Clean up those validation errors while the user is - // saving. if (from === 'invalid') { this.removeValidationErrors(); } @@ -158,45 +60,24 @@ break; case 'saved': - // Nothing to do for the typical in-place editor. Immediately after - // being saved, a field will go to the 'candidate' state, where it - // should no longer be visible (after all, the field will then again - // just be a *candidate* to be in-place edited). break; case 'invalid': - // The modified field value was attempted to be saved, but there were - // validation errors. this.showValidationErrors(); break; } }, - - /** - * Reverts the modified value to the original, before editing started. - */ - revert: function () { - // A no-op by default; each editor should implement reverting itself. - // Note that if the in-place editor does not cause the FieldModel's - // element to be modified, then nothing needs to happen. - }, - - /** - * Saves the modified value in the in-place editor for this field. - */ - save: function () { + revert: function revert() {}, + save: function save() { var fieldModel = this.fieldModel; var editorModel = this.model; var backstageId = 'quickedit_backstage-' + this.fieldModel.id.replace(/[\/\[\]\_\s]/g, '-'); function fillAndSubmitForm(value) { var $form = $('#' + backstageId).find('form'); - // Fill in the value in any that isn't hidden or a submit - // button. - $form.find(':input[type!="hidden"][type!="submit"]:not(select)') - // Don't mess with the node summary. - .not('[name$="\\[summary\\]"]').val(value); - // Submit the form. + + $form.find(':input[type!="hidden"][type!="submit"]:not(select)').not('[name$="\\[summary\\]"]').val(value); + $form.find('.quickedit-form-submit').trigger('click.quickedit'); } @@ -205,28 +86,16 @@ $el: this.$el, nocssjs: true, other_view_modes: fieldModel.findOtherViewModes(), - // Reset an existing entry for this entity in the PrivateTempStore (if - // any) when saving the field. Logically speaking, this should happen in - // a separate request because this is an entity-level operation, not a - // field-level operation. But that would require an additional request, - // that might not even be necessary: it is only when a user saves a - // first changed field for an entity that this needs to happen: - // precisely now! + reset: !this.fieldModel.get('entity').get('inTempStore') }; var self = this; Drupal.quickedit.util.form.load(formOptions, function (form, ajax) { - // Create a backstage area for storing forms that are hidden from view - // (hence "backstage" — since the editing doesn't happen in the form, it - // happens "directly" in the content, the form is only used for saving). - var $backstage = $(Drupal.theme('quickeditBackstage', {id: backstageId})).appendTo('body'); - // Hidden forms are stuffed into the backstage container for this field. + var $backstage = $(Drupal.theme('quickeditBackstage', { id: backstageId })).appendTo('body'); + var $form = $(form).appendTo($backstage); - // Disable the browser's HTML5 validation; we only care about server- - // side validation. (Not disabling this will actually cause problems - // because browsers don't like to set HTML5 validation errors on hidden - // forms.) + $form.prop('novalidate', true); var $submit = $form.find('.quickedit-form-submit'); self.formSaveAjax = Drupal.quickedit.util.form.ajaxifySaving(formOptions, $submit); @@ -237,68 +106,33 @@ $backstage.remove(); } - // Successfully saved. self.formSaveAjax.commands.quickeditFieldFormSaved = function (ajax, response, status) { removeHiddenForm(); - // First, transition the state to 'saved'. + fieldModel.set('state', 'saved'); - // Second, set the 'htmlForOtherViewModes' attribute, so that when - // this field is rerendered, the change can be propagated to other - // instances of this field, which may be displayed in different view - // modes. + fieldModel.set('htmlForOtherViewModes', response.other_view_modes); - // Finally, set the 'html' attribute on the field model. This will - // cause the field to be rerendered. + fieldModel.set('html', response.data); }; - // Unsuccessfully saved; validation errors. self.formSaveAjax.commands.quickeditFieldFormValidationErrors = function (ajax, response, status) { removeHiddenForm(); editorModel.set('validationErrors', response.data); fieldModel.set('state', 'invalid'); }; - // The quickeditFieldForm AJAX command is only called upon loading the - // form for the first time, and when there are validation errors in the - // form; Form API then marks which form items have errors. This is - // useful for the form-based in-place editor, but pointless for any - // other: the form itself won't be visible at all anyway! So, we just - // ignore it. self.formSaveAjax.commands.quickeditFieldForm = function () {}; fillAndSubmitForm(editorModel.get('currentValue')); }); }, - - /** - * Shows validation error messages. - * - * Should be called when the state is changed to 'invalid'. - */ - showValidationErrors: function () { - var $errors = $('
    ') - .append(this.model.get('validationErrors')); - this.getEditedElement() - .addClass('quickedit-validation-error') - .after($errors); + showValidationErrors: function showValidationErrors() { + var $errors = $('
    ').append(this.model.get('validationErrors')); + this.getEditedElement().addClass('quickedit-validation-error').after($errors); }, - - /** - * Cleans up validation error messages. - * - * Should be called when the state is changed to 'candidate' or 'saving'. In - * the case of the latter: the user has modified the value in the in-place - * editor again to attempt to save again. In the case of the latter: the - * invalid value was discarded. - */ - removeValidationErrors: function () { - this.getEditedElement() - .removeClass('quickedit-validation-error') - .next('.quickedit-validation-errors') - .remove(); + removeValidationErrors: function removeValidationErrors() { + this.getEditedElement().removeClass('quickedit-validation-error').next('.quickedit-validation-errors').remove(); } - }); - -}(jQuery, Backbone, Drupal)); +})(jQuery, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/EntityDecorationView.es6.js b/core/modules/quickedit/js/views/EntityDecorationView.es6.js new file mode 100644 index 00000000..263a6d27 --- /dev/null +++ b/core/modules/quickedit/js/views/EntityDecorationView.es6.js @@ -0,0 +1,36 @@ +/** + * @file + * A Backbone view that decorates the in-place editable entity. + */ + +(function (Drupal, $, Backbone) { + Drupal.quickedit.EntityDecorationView = Backbone.View.extend(/** @lends Drupal.quickedit.EntityDecorationView# */{ + + /** + * Associated with the DOM root node of an editable entity. + * + * @constructs + * + * @augments Backbone.View + */ + initialize() { + this.listenTo(this.model, 'change', this.render); + }, + + /** + * @inheritdoc + */ + render() { + this.$el.toggleClass('quickedit-entity-active', this.model.get('isActive')); + }, + + /** + * @inheritdoc + */ + remove() { + this.setElement(null); + Backbone.View.prototype.remove.call(this); + }, + + }); +}(Drupal, jQuery, Backbone)); diff --git a/core/modules/quickedit/js/views/EntityDecorationView.js b/core/modules/quickedit/js/views/EntityDecorationView.js index ff090fe4..aeaf6e36 100644 --- a/core/modules/quickedit/js/views/EntityDecorationView.js +++ b/core/modules/quickedit/js/views/EntityDecorationView.js @@ -1,40 +1,21 @@ /** - * @file - * A Backbone view that decorates the in-place editable entity. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (Drupal, $, Backbone) { - - 'use strict'; - - Drupal.quickedit.EntityDecorationView = Backbone.View.extend(/** @lends Drupal.quickedit.EntityDecorationView# */{ - - /** - * Associated with the DOM root node of an editable entity. - * - * @constructs - * - * @augments Backbone.View - */ - initialize: function () { + Drupal.quickedit.EntityDecorationView = Backbone.View.extend({ + initialize: function initialize() { this.listenTo(this.model, 'change', this.render); }, - - /** - * @inheritdoc - */ - render: function () { + render: function render() { this.$el.toggleClass('quickedit-entity-active', this.model.get('isActive')); }, - - /** - * @inheritdoc - */ - remove: function () { + remove: function remove() { this.setElement(null); Backbone.View.prototype.remove.call(this); } - }); - -}(Drupal, jQuery, Backbone)); +})(Drupal, jQuery, Backbone); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/EntityToolbarView.es6.js b/core/modules/quickedit/js/views/EntityToolbarView.es6.js new file mode 100644 index 00000000..4c87d087 --- /dev/null +++ b/core/modules/quickedit/js/views/EntityToolbarView.es6.js @@ -0,0 +1,524 @@ +/** + * @file + * A Backbone View that provides an entity level toolbar. + */ + +(function ($, _, Backbone, Drupal, debounce) { + Drupal.quickedit.EntityToolbarView = Backbone.View.extend(/** @lends Drupal.quickedit.EntityToolbarView# */{ + + /** + * @type {jQuery} + */ + _fieldToolbarRoot: null, + + /** + * @return {object} + * A map of events. + */ + events() { + const map = { + 'click button.action-save': 'onClickSave', + 'click button.action-cancel': 'onClickCancel', + mouseenter: 'onMouseenter', + }; + return map; + }, + + /** + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * Options to construct the view. + * @param {Drupal.quickedit.AppModel} options.appModel + * A quickedit `AppModel` to use in the view. + */ + initialize(options) { + const that = this; + this.appModel = options.appModel; + this.$entity = $(this.model.get('el')); + + // Rerender whenever the entity state changes. + this.listenTo(this.model, 'change:isActive change:isDirty change:state', this.render); + // Also rerender whenever a different field is highlighted or activated. + this.listenTo(this.appModel, 'change:highlightedField change:activeField', this.render); + // Rerender when a field of the entity changes state. + this.listenTo(this.model.get('fields'), 'change:state', this.fieldStateChange); + + // Reposition the entity toolbar as the viewport and the position within + // the viewport changes. + $(window).on('resize.quickedit scroll.quickedit drupalViewportOffsetChange.quickedit', debounce($.proxy(this.windowChangeHandler, this), 150)); + + // Adjust the fence placement within which the entity toolbar may be + // positioned. + $(document).on('drupalViewportOffsetChange.quickedit', (event, offsets) => { + if (that.$fence) { + that.$fence.css(offsets); + } + }); + + // Set the entity toolbar DOM element as the el for this view. + const $toolbar = this.buildToolbarEl(); + this.setElement($toolbar); + this._fieldToolbarRoot = $toolbar.find('.quickedit-toolbar-field').get(0); + + // Initial render. + this.render(); + }, + + /** + * @inheritdoc + * + * @return {Drupal.quickedit.EntityToolbarView} + * The entity toolbar view. + */ + render() { + if (this.model.get('isActive')) { + // If the toolbar container doesn't exist, create it. + const $body = $('body'); + if ($body.children('#quickedit-entity-toolbar').length === 0) { + $body.append(this.$el); + } + // The fence will define a area on the screen that the entity toolbar + // will be position within. + if ($body.children('#quickedit-toolbar-fence').length === 0) { + this.$fence = $(Drupal.theme('quickeditEntityToolbarFence')) + .css(Drupal.displace()) + .appendTo($body); + } + // Adds the entity title to the toolbar. + this.label(); + + // Show the save and cancel buttons. + this.show('ops'); + // If render is being called and the toolbar is already visible, just + // reposition it. + this.position(); + } + + // The save button text and state varies with the state of the entity + // model. + const $button = this.$el.find('.quickedit-button.action-save'); + const isDirty = this.model.get('isDirty'); + // Adjust the save button according to the state of the model. + switch (this.model.get('state')) { + // Quick editing is active, but no field is being edited. + case 'opened': + // The saving throbber is not managed by AJAX system. The + // EntityToolbarView manages this visual element. + $button + .removeClass('action-saving icon-throbber icon-end') + .text(Drupal.t('Save')) + .removeAttr('disabled') + .attr('aria-hidden', !isDirty); + break; + + // The changes to the fields of the entity are being committed. + case 'committing': + $button + .addClass('action-saving icon-throbber icon-end') + .text(Drupal.t('Saving')) + .attr('disabled', 'disabled'); + break; + + default: + $button.attr('aria-hidden', true); + break; + } + + return this; + }, + + /** + * @inheritdoc + */ + remove() { + // Remove additional DOM elements controlled by this View. + this.$fence.remove(); + + // Stop listening to additional events. + $(window).off('resize.quickedit scroll.quickedit drupalViewportOffsetChange.quickedit'); + $(document).off('drupalViewportOffsetChange.quickedit'); + + Backbone.View.prototype.remove.call(this); + }, + + /** + * Repositions the entity toolbar on window scroll and resize. + * + * @param {jQuery.Event} event + * The scroll or resize event. + */ + windowChangeHandler(event) { + this.position(); + }, + + /** + * Determines the actions to take given a change of state. + * + * @param {Drupal.quickedit.FieldModel} model + * The `FieldModel` model. + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.FieldModel.states}. + */ + fieldStateChange(model, state) { + switch (state) { + case 'active': + this.render(); + break; + + case 'invalid': + this.render(); + break; + } + }, + + /** + * Uses the jQuery.ui.position() method to position the entity toolbar. + * + * @param {HTMLElement} [element] + * The element against which the entity toolbar is positioned. + */ + position(element) { + clearTimeout(this.timer); + + const that = this; + // Vary the edge of the positioning according to the direction of language + // in the document. + const edge = (document.documentElement.dir === 'rtl') ? 'right' : 'left'; + // A time unit to wait until the entity toolbar is repositioned. + let delay = 0; + // Determines what check in the series of checks below should be + // evaluated. + let check = 0; + // When positioned against an active field that has padding, we should + // ignore that padding when positioning the toolbar, to not unnecessarily + // move the toolbar horizontally, which feels annoying. + let horizontalPadding = 0; + let of; + let activeField; + let highlightedField; + // There are several elements in the page that the entity toolbar might be + // positioned against. They are considered below in a priority order. + do { + switch (check) { + case 0: + // Position against a specific element. + of = element; + break; + + case 1: + // Position against a form container. + activeField = Drupal.quickedit.app.model.get('activeField'); + of = activeField && activeField.editorView && activeField.editorView.$formContainer && activeField.editorView.$formContainer.find('.quickedit-form'); + break; + + case 2: + // Position against an active field. + of = activeField && activeField.editorView && activeField.editorView.getEditedElement(); + if (activeField && activeField.editorView && activeField.editorView.getQuickEditUISettings().padding) { + horizontalPadding = 5; + } + break; + + case 3: + // Position against a highlighted field. + highlightedField = Drupal.quickedit.app.model.get('highlightedField'); + of = highlightedField && highlightedField.editorView && highlightedField.editorView.getEditedElement(); + delay = 250; + break; + + default: + var fieldModels = this.model.get('fields').models; + var topMostPosition = 1000000; + var topMostField = null; + // Position against the topmost field. + for (let i = 0; i < fieldModels.length; i++) { + const pos = fieldModels[i].get('el').getBoundingClientRect().top; + if (pos < topMostPosition) { + topMostPosition = pos; + topMostField = fieldModels[i]; + } + } + of = topMostField.get('el'); + delay = 50; + break; + } + // Prepare to check the next possible element to position against. + check++; + } while (!of); + + /** + * Refines the positioning algorithm of jquery.ui.position(). + * + * Invoked as the 'using' callback of jquery.ui.position() in + * positionToolbar(). + * + * @param {*} view + * The view the positions will be calculated from. + * @param {object} suggested + * A hash of top and left values for the position that should be set. It + * can be forwarded to .css() or .animate(). + * @param {object} info + * The position and dimensions of both the 'my' element and the 'of' + * elements, as well as calculations to their relative position. This + * object contains the following properties: + * @param {object} info.element + * A hash that contains information about the HTML element that will be + * positioned. Also known as the 'my' element. + * @param {object} info.target + * A hash that contains information about the HTML element that the + * 'my' element will be positioned against. Also known as the 'of' + * element. + */ + function refinePosition(view, suggested, info) { + // Determine if the pointer should be on the top or bottom. + const isBelow = suggested.top > info.target.top; + info.element.element.toggleClass('quickedit-toolbar-pointer-top', isBelow); + // Don't position the toolbar past the first or last editable field if + // the entity is the target. + if (view.$entity[0] === info.target.element[0]) { + // Get the first or last field according to whether the toolbar is + // above or below the entity. + const $field = view.$entity.find('.quickedit-editable').eq((isBelow) ? -1 : 0); + if ($field.length > 0) { + suggested.top = (isBelow) ? ($field.offset().top + $field.outerHeight(true)) : $field.offset().top - info.element.element.outerHeight(true); + } + } + // Don't let the toolbar go outside the fence. + const fenceTop = view.$fence.offset().top; + const fenceHeight = view.$fence.height(); + const toolbarHeight = info.element.element.outerHeight(true); + if (suggested.top < fenceTop) { + suggested.top = fenceTop; + } + else if ((suggested.top + toolbarHeight) > (fenceTop + fenceHeight)) { + suggested.top = fenceTop + fenceHeight - toolbarHeight; + } + // Position the toolbar. + info.element.element.css({ + left: Math.floor(suggested.left), + top: Math.floor(suggested.top), + }); + } + + /** + * Calls the jquery.ui.position() method on the $el of this view. + */ + function positionToolbar() { + that.$el + .position({ + my: `${edge} bottom`, + // Move the toolbar 1px towards the start edge of the 'of' element, + // plus any horizontal padding that may have been added to the + // element that is being added, to prevent unwanted horizontal + // movement. + at: `${edge}+${1 + horizontalPadding} top`, + of, + collision: 'flipfit', + using: refinePosition.bind(null, that), + within: that.$fence, + }) + // Resize the toolbar to match the dimensions of the field, up to a + // maximum width that is equal to 90% of the field's width. + .css({ + 'max-width': (document.documentElement.clientWidth < 450) ? document.documentElement.clientWidth : 450, + // Set a minimum width of 240px for the entity toolbar, or the width + // of the client if it is less than 240px, so that the toolbar + // never folds up into a squashed and jumbled mess. + 'min-width': (document.documentElement.clientWidth < 240) ? document.documentElement.clientWidth : 240, + width: '100%', + }); + } + + // Uses the jQuery.ui.position() method. Use a timeout to move the toolbar + // only after the user has focused on an editable for 250ms. This prevents + // the toolbar from jumping around the screen. + this.timer = setTimeout(() => { + // Render the position in the next execution cycle, so that animations + // on the field have time to process. This is not strictly speaking, a + // guarantee that all animations will be finished, but it's a simple + // way to get better positioning without too much additional code. + _.defer(positionToolbar); + }, delay); + }, + + /** + * Set the model state to 'saving' when the save button is clicked. + * + * @param {jQuery.Event} event + * The click event. + */ + onClickSave(event) { + event.stopPropagation(); + event.preventDefault(); + // Save the model. + this.model.set('state', 'committing'); + }, + + /** + * Sets the model state to candidate when the cancel button is clicked. + * + * @param {jQuery.Event} event + * The click event. + */ + onClickCancel(event) { + event.preventDefault(); + this.model.set('state', 'deactivating'); + }, + + /** + * Clears the timeout that will eventually reposition the entity toolbar. + * + * Without this, it may reposition itself, away from the user's cursor! + * + * @param {jQuery.Event} event + * The mouse event. + */ + onMouseenter(event) { + clearTimeout(this.timer); + }, + + /** + * Builds the entity toolbar HTML; attaches to DOM; sets starting position. + * + * @return {jQuery} + * The toolbar element. + */ + buildToolbarEl() { + const $toolbar = $(Drupal.theme('quickeditEntityToolbar', { + id: 'quickedit-entity-toolbar', + })); + + $toolbar + .find('.quickedit-toolbar-entity') + // Append the "ops" toolgroup into the toolbar. + .prepend(Drupal.theme('quickeditToolgroup', { + classes: ['ops'], + buttons: [ + { + label: Drupal.t('Save'), + type: 'submit', + classes: 'action-save quickedit-button icon', + attributes: { + 'aria-hidden': true, + }, + }, + { + label: Drupal.t('Close'), + classes: 'action-cancel quickedit-button icon icon-close icon-only', + }, + ], + })); + + // Give the toolbar a sensible starting position so that it doesn't + // animate on to the screen from a far off corner. + $toolbar + .css({ + left: this.$entity.offset().left, + top: this.$entity.offset().top, + }); + + return $toolbar; + }, + + /** + * Returns the DOM element that fields will attach their toolbars to. + * + * @return {jQuery} + * The DOM element that fields will attach their toolbars to. + */ + getToolbarRoot() { + return this._fieldToolbarRoot; + }, + + /** + * Generates a state-dependent label for the entity toolbar. + */ + label() { + // The entity label. + let label = ''; + const entityLabel = this.model.get('label'); + + // Label of an active field, if it exists. + const activeField = Drupal.quickedit.app.model.get('activeField'); + const activeFieldLabel = activeField && activeField.get('metadata').label; + // Label of a highlighted field, if it exists. + const highlightedField = Drupal.quickedit.app.model.get('highlightedField'); + const highlightedFieldLabel = highlightedField && highlightedField.get('metadata').label; + // The label is constructed in a priority order. + if (activeFieldLabel) { + label = Drupal.theme('quickeditEntityToolbarLabel', { + entityLabel, + fieldLabel: activeFieldLabel, + }); + } + else if (highlightedFieldLabel) { + label = Drupal.theme('quickeditEntityToolbarLabel', { + entityLabel, + fieldLabel: highlightedFieldLabel, + }); + } + else { + // @todo Add XSS regression test coverage in https://www.drupal.org/node/2547437 + label = Drupal.checkPlain(entityLabel); + } + + this.$el + .find('.quickedit-toolbar-label') + .html(label); + }, + + /** + * Adds classes to a toolgroup. + * + * @param {string} toolgroup + * A toolgroup name. + * @param {string} classes + * A string of space-delimited class names that will be applied to the + * wrapping element of the toolbar group. + */ + addClass(toolgroup, classes) { + this._find(toolgroup).addClass(classes); + }, + + /** + * Removes classes from a toolgroup. + * + * @param {string} toolgroup + * A toolgroup name. + * @param {string} classes + * A string of space-delimited class names that will be removed from the + * wrapping element of the toolbar group. + */ + removeClass(toolgroup, classes) { + this._find(toolgroup).removeClass(classes); + }, + + /** + * Finds a toolgroup. + * + * @param {string} toolgroup + * A toolgroup name. + * + * @return {jQuery} + * The toolgroup DOM element. + */ + _find(toolgroup) { + return this.$el.find(`.quickedit-toolbar .quickedit-toolgroup.${toolgroup}`); + }, + + /** + * Shows a toolgroup. + * + * @param {string} toolgroup + * A toolgroup name. + */ + show(toolgroup) { + this.$el.removeClass('quickedit-animate-invisible'); + }, + + }); +}(jQuery, _, Backbone, Drupal, Drupal.debounce)); diff --git a/core/modules/quickedit/js/views/EntityToolbarView.js b/core/modules/quickedit/js/views/EntityToolbarView.js index 4e8e913d..bc5ab75d 100644 --- a/core/modules/quickedit/js/views/EntityToolbarView.js +++ b/core/modules/quickedit/js/views/EntityToolbarView.js @@ -1,128 +1,75 @@ /** - * @file - * A Backbone View that provides an entity level toolbar. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, _, Backbone, Drupal, debounce) { - - 'use strict'; - - Drupal.quickedit.EntityToolbarView = Backbone.View.extend(/** @lends Drupal.quickedit.EntityToolbarView# */{ - - /** - * @type {jQuery} - */ + Drupal.quickedit.EntityToolbarView = Backbone.View.extend({ _fieldToolbarRoot: null, - /** - * @return {object} - * A map of events. - */ - events: function () { + events: function events() { var map = { 'click button.action-save': 'onClickSave', 'click button.action-cancel': 'onClickCancel', - 'mouseenter': 'onMouseenter' + mouseenter: 'onMouseenter' }; return map; }, - - /** - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * Options to construct the view. - * @param {Drupal.quickedit.AppModel} options.appModel - * A quickedit `AppModel` to use in the view. - */ - initialize: function (options) { + initialize: function initialize(options) { var that = this; this.appModel = options.appModel; this.$entity = $(this.model.get('el')); - // Rerender whenever the entity state changes. this.listenTo(this.model, 'change:isActive change:isDirty change:state', this.render); - // Also rerender whenever a different field is highlighted or activated. + this.listenTo(this.appModel, 'change:highlightedField change:activeField', this.render); - // Rerender when a field of the entity changes state. + this.listenTo(this.model.get('fields'), 'change:state', this.fieldStateChange); - // Reposition the entity toolbar as the viewport and the position within - // the viewport changes. - $(window).on('resize.quickedit scroll.quickedit', debounce($.proxy(this.windowChangeHandler, this), 150)); + $(window).on('resize.quickedit scroll.quickedit drupalViewportOffsetChange.quickedit', debounce($.proxy(this.windowChangeHandler, this), 150)); - // Adjust the fence placement within which the entity toolbar may be - // positioned. $(document).on('drupalViewportOffsetChange.quickedit', function (event, offsets) { if (that.$fence) { that.$fence.css(offsets); } }); - // Set the entity toolbar DOM element as the el for this view. var $toolbar = this.buildToolbarEl(); this.setElement($toolbar); this._fieldToolbarRoot = $toolbar.find('.quickedit-toolbar-field').get(0); - // Initial render. this.render(); }, - - /** - * @inheritdoc - * - * @return {Drupal.quickedit.EntityToolbarView} - * The entity toolbar view. - */ - render: function () { + render: function render() { if (this.model.get('isActive')) { - // If the toolbar container doesn't exist, create it. var $body = $('body'); if ($body.children('#quickedit-entity-toolbar').length === 0) { $body.append(this.$el); } - // The fence will define a area on the screen that the entity toolbar - // will be position within. + if ($body.children('#quickedit-toolbar-fence').length === 0) { - this.$fence = $(Drupal.theme('quickeditEntityToolbarFence')) - .css(Drupal.displace()) - .appendTo($body); + this.$fence = $(Drupal.theme('quickeditEntityToolbarFence')).css(Drupal.displace()).appendTo($body); } - // Adds the entity title to the toolbar. + this.label(); - // Show the save and cancel buttons. this.show('ops'); - // If render is being called and the toolbar is already visible, just - // reposition it. + this.position(); } - // The save button text and state varies with the state of the entity - // model. var $button = this.$el.find('.quickedit-button.action-save'); var isDirty = this.model.get('isDirty'); - // Adjust the save button according to the state of the model. + switch (this.model.get('state')) { - // Quick editing is active, but no field is being edited. case 'opened': - // The saving throbber is not managed by AJAX system. The - // EntityToolbarView manages this visual element. - $button - .removeClass('action-saving icon-throbber icon-end') - .text(Drupal.t('Save')) - .removeAttr('disabled') - .attr('aria-hidden', !isDirty); + $button.removeClass('action-saving icon-throbber icon-end').text(Drupal.t('Save')).removeAttr('disabled').attr('aria-hidden', !isDirty); break; - // The changes to the fields of the entity are being committed. case 'committing': - $button - .addClass('action-saving icon-throbber icon-end') - .text(Drupal.t('Saving')) - .attr('disabled', 'disabled'); + $button.addClass('action-saving icon-throbber icon-end').text(Drupal.t('Saving')).attr('disabled', 'disabled'); break; default: @@ -132,41 +79,18 @@ return this; }, - - /** - * @inheritdoc - */ - remove: function () { - // Remove additional DOM elements controlled by this View. + remove: function remove() { this.$fence.remove(); - // Stop listening to additional events. - $(window).off('resize.quickedit scroll.quickedit'); + $(window).off('resize.quickedit scroll.quickedit drupalViewportOffsetChange.quickedit'); $(document).off('drupalViewportOffsetChange.quickedit'); Backbone.View.prototype.remove.call(this); }, - - /** - * Repositions the entity toolbar on window scroll and resize. - * - * @param {jQuery.Event} event - * The scroll or resize event. - */ - windowChangeHandler: function (event) { + windowChangeHandler: function windowChangeHandler(event) { this.position(); }, - - /** - * Determines the actions to take given a change of state. - * - * @param {Drupal.quickedit.FieldModel} model - * The `FieldModel` model. - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.FieldModel.states}. - */ - fieldStateChange: function (model, state) { + fieldStateChange: function fieldStateChange(model, state) { switch (state) { case 'active': this.render(); @@ -177,49 +101,34 @@ break; } }, - - /** - * Uses the jQuery.ui.position() method to position the entity toolbar. - * - * @param {HTMLElement} [element] - * The element against which the entity toolbar is positioned. - */ - position: function (element) { + position: function position(element) { clearTimeout(this.timer); var that = this; - // Vary the edge of the positioning according to the direction of language - // in the document. - var edge = (document.documentElement.dir === 'rtl') ? 'right' : 'left'; - // A time unit to wait until the entity toolbar is repositioned. + + var edge = document.documentElement.dir === 'rtl' ? 'right' : 'left'; + var delay = 0; - // Determines what check in the series of checks below should be - // evaluated. + var check = 0; - // When positioned against an active field that has padding, we should - // ignore that padding when positioning the toolbar, to not unnecessarily - // move the toolbar horizontally, which feels annoying. + var horizontalPadding = 0; - var of; - var activeField; - var highlightedField; - // There are several elements in the page that the entity toolbar might be - // positioned against. They are considered below in a priority order. + var of = void 0; + var activeField = void 0; + var highlightedField = void 0; + do { switch (check) { case 0: - // Position against a specific element. of = element; break; case 1: - // Position against a form container. activeField = Drupal.quickedit.app.model.get('activeField'); of = activeField && activeField.editorView && activeField.editorView.$formContainer && activeField.editorView.$formContainer.find('.quickedit-form'); break; case 2: - // Position against an active field. of = activeField && activeField.editorView && activeField.editorView.getEditedElement(); if (activeField && activeField.editorView && activeField.editorView.getQuickEditUISettings().padding) { horizontalPadding = 5; @@ -227,7 +136,6 @@ break; case 3: - // Position against a highlighted field. highlightedField = Drupal.quickedit.app.model.get('highlightedField'); of = highlightedField && highlightedField.editorView && highlightedField.editorView.getEditedElement(); delay = 250; @@ -237,7 +145,7 @@ var fieldModels = this.model.get('fields').models; var topMostPosition = 1000000; var topMostField = null; - // Position against the topmost field. + for (var i = 0; i < fieldModels.length; i++) { var pos = fieldModels[i].get('el').getBoundingClientRect().top; if (pos < topMostPosition) { @@ -249,280 +157,137 @@ delay = 50; break; } - // Prepare to check the next possible element to position against. + check++; } while (!of); - /** - * Refines the positioning algorithm of jquery.ui.position(). - * - * Invoked as the 'using' callback of jquery.ui.position() in - * positionToolbar(). - * - * @param {*} view - * The view the positions will be calculated from. - * @param {object} suggested - * A hash of top and left values for the position that should be set. It - * can be forwarded to .css() or .animate(). - * @param {object} info - * The position and dimensions of both the 'my' element and the 'of' - * elements, as well as calculations to their relative position. This - * object contains the following properties: - * @param {object} info.element - * A hash that contains information about the HTML element that will be - * positioned. Also known as the 'my' element. - * @param {object} info.target - * A hash that contains information about the HTML element that the - * 'my' element will be positioned against. Also known as the 'of' - * element. - */ function refinePosition(view, suggested, info) { - // Determine if the pointer should be on the top or bottom. var isBelow = suggested.top > info.target.top; info.element.element.toggleClass('quickedit-toolbar-pointer-top', isBelow); - // Don't position the toolbar past the first or last editable field if - // the entity is the target. + if (view.$entity[0] === info.target.element[0]) { - // Get the first or last field according to whether the toolbar is - // above or below the entity. - var $field = view.$entity.find('.quickedit-editable').eq((isBelow) ? -1 : 0); + var $field = view.$entity.find('.quickedit-editable').eq(isBelow ? -1 : 0); if ($field.length > 0) { - suggested.top = (isBelow) ? ($field.offset().top + $field.outerHeight(true)) : $field.offset().top - info.element.element.outerHeight(true); + suggested.top = isBelow ? $field.offset().top + $field.outerHeight(true) : $field.offset().top - info.element.element.outerHeight(true); } } - // Don't let the toolbar go outside the fence. + var fenceTop = view.$fence.offset().top; var fenceHeight = view.$fence.height(); var toolbarHeight = info.element.element.outerHeight(true); if (suggested.top < fenceTop) { suggested.top = fenceTop; - } - else if ((suggested.top + toolbarHeight) > (fenceTop + fenceHeight)) { + } else if (suggested.top + toolbarHeight > fenceTop + fenceHeight) { suggested.top = fenceTop + fenceHeight - toolbarHeight; } - // Position the toolbar. + info.element.element.css({ left: Math.floor(suggested.left), top: Math.floor(suggested.top) }); } - /** - * Calls the jquery.ui.position() method on the $el of this view. - */ function positionToolbar() { - that.$el - .position({ - my: edge + ' bottom', - // Move the toolbar 1px towards the start edge of the 'of' element, - // plus any horizontal padding that may have been added to the - // element that is being added, to prevent unwanted horizontal - // movement. - at: edge + '+' + (1 + horizontalPadding) + ' top', - of: of, - collision: 'flipfit', - using: refinePosition.bind(null, that), - within: that.$fence - }) - // Resize the toolbar to match the dimensions of the field, up to a - // maximum width that is equal to 90% of the field's width. - .css({ - 'max-width': (document.documentElement.clientWidth < 450) ? document.documentElement.clientWidth : 450, - // Set a minimum width of 240px for the entity toolbar, or the width - // of the client if it is less than 240px, so that the toolbar - // never folds up into a squashed and jumbled mess. - 'min-width': (document.documentElement.clientWidth < 240) ? document.documentElement.clientWidth : 240, - 'width': '100%' - }); + that.$el.position({ + my: edge + ' bottom', + + at: edge + '+' + (1 + horizontalPadding) + ' top', + of: of, + collision: 'flipfit', + using: refinePosition.bind(null, that), + within: that.$fence + }).css({ + 'max-width': document.documentElement.clientWidth < 450 ? document.documentElement.clientWidth : 450, + + 'min-width': document.documentElement.clientWidth < 240 ? document.documentElement.clientWidth : 240, + width: '100%' + }); } - // Uses the jQuery.ui.position() method. Use a timeout to move the toolbar - // only after the user has focused on an editable for 250ms. This prevents - // the toolbar from jumping around the screen. this.timer = setTimeout(function () { - // Render the position in the next execution cycle, so that animations - // on the field have time to process. This is not strictly speaking, a - // guarantee that all animations will be finished, but it's a simple - // way to get better positioning without too much additional code. _.defer(positionToolbar); }, delay); }, - - /** - * Set the model state to 'saving' when the save button is clicked. - * - * @param {jQuery.Event} event - * The click event. - */ - onClickSave: function (event) { + onClickSave: function onClickSave(event) { event.stopPropagation(); event.preventDefault(); - // Save the model. + this.model.set('state', 'committing'); }, - - /** - * Sets the model state to candidate when the cancel button is clicked. - * - * @param {jQuery.Event} event - * The click event. - */ - onClickCancel: function (event) { + onClickCancel: function onClickCancel(event) { event.preventDefault(); this.model.set('state', 'deactivating'); }, - - /** - * Clears the timeout that will eventually reposition the entity toolbar. - * - * Without this, it may reposition itself, away from the user's cursor! - * - * @param {jQuery.Event} event - * The mouse event. - */ - onMouseenter: function (event) { + onMouseenter: function onMouseenter(event) { clearTimeout(this.timer); }, - - /** - * Builds the entity toolbar HTML; attaches to DOM; sets starting position. - * - * @return {jQuery} - * The toolbar element. - */ - buildToolbarEl: function () { + buildToolbarEl: function buildToolbarEl() { var $toolbar = $(Drupal.theme('quickeditEntityToolbar', { id: 'quickedit-entity-toolbar' })); - $toolbar - .find('.quickedit-toolbar-entity') - // Append the "ops" toolgroup into the toolbar. - .prepend(Drupal.theme('quickeditToolgroup', { - classes: ['ops'], - buttons: [ - { - label: Drupal.t('Save'), - type: 'submit', - classes: 'action-save quickedit-button icon', - attributes: { - 'aria-hidden': true - } - }, - { - label: Drupal.t('Close'), - classes: 'action-cancel quickedit-button icon icon-close icon-only' - } - ] - })); - - // Give the toolbar a sensible starting position so that it doesn't - // animate on to the screen from a far off corner. - $toolbar - .css({ - left: this.$entity.offset().left, - top: this.$entity.offset().top - }); + $toolbar.find('.quickedit-toolbar-entity').prepend(Drupal.theme('quickeditToolgroup', { + classes: ['ops'], + buttons: [{ + label: Drupal.t('Save'), + type: 'submit', + classes: 'action-save quickedit-button icon', + attributes: { + 'aria-hidden': true + } + }, { + label: Drupal.t('Close'), + classes: 'action-cancel quickedit-button icon icon-close icon-only' + }] + })); + + $toolbar.css({ + left: this.$entity.offset().left, + top: this.$entity.offset().top + }); return $toolbar; }, - - /** - * Returns the DOM element that fields will attach their toolbars to. - * - * @return {jQuery} - * The DOM element that fields will attach their toolbars to. - */ - getToolbarRoot: function () { + getToolbarRoot: function getToolbarRoot() { return this._fieldToolbarRoot; }, - - /** - * Generates a state-dependent label for the entity toolbar. - */ - label: function () { - // The entity label. + label: function label() { var label = ''; var entityLabel = this.model.get('label'); - // Label of an active field, if it exists. var activeField = Drupal.quickedit.app.model.get('activeField'); var activeFieldLabel = activeField && activeField.get('metadata').label; - // Label of a highlighted field, if it exists. + var highlightedField = Drupal.quickedit.app.model.get('highlightedField'); var highlightedFieldLabel = highlightedField && highlightedField.get('metadata').label; - // The label is constructed in a priority order. + if (activeFieldLabel) { label = Drupal.theme('quickeditEntityToolbarLabel', { entityLabel: entityLabel, fieldLabel: activeFieldLabel }); - } - else if (highlightedFieldLabel) { + } else if (highlightedFieldLabel) { label = Drupal.theme('quickeditEntityToolbarLabel', { entityLabel: entityLabel, fieldLabel: highlightedFieldLabel }); - } - else { - // @todo Add XSS regression test coverage in https://www.drupal.org/node/2547437 + } else { label = Drupal.checkPlain(entityLabel); } - this.$el - .find('.quickedit-toolbar-label') - .html(label); + this.$el.find('.quickedit-toolbar-label').html(label); }, - - /** - * Adds classes to a toolgroup. - * - * @param {string} toolgroup - * A toolgroup name. - * @param {string} classes - * A string of space-delimited class names that will be applied to the - * wrapping element of the toolbar group. - */ - addClass: function (toolgroup, classes) { + addClass: function addClass(toolgroup, classes) { this._find(toolgroup).addClass(classes); }, - - /** - * Removes classes from a toolgroup. - * - * @param {string} toolgroup - * A toolgroup name. - * @param {string} classes - * A string of space-delimited class names that will be removed from the - * wrapping element of the toolbar group. - */ - removeClass: function (toolgroup, classes) { + removeClass: function removeClass(toolgroup, classes) { this._find(toolgroup).removeClass(classes); }, - - /** - * Finds a toolgroup. - * - * @param {string} toolgroup - * A toolgroup name. - * - * @return {jQuery} - * The toolgroup DOM element. - */ - _find: function (toolgroup) { + _find: function _find(toolgroup) { return this.$el.find('.quickedit-toolbar .quickedit-toolgroup.' + toolgroup); }, - - /** - * Shows a toolgroup. - * - * @param {string} toolgroup - * A toolgroup name. - */ - show: function (toolgroup) { + show: function show(toolgroup) { this.$el.removeClass('quickedit-animate-invisible'); } - }); - -})(jQuery, _, Backbone, Drupal, Drupal.debounce); +})(jQuery, _, Backbone, Drupal, Drupal.debounce); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/FieldDecorationView.es6.js b/core/modules/quickedit/js/views/FieldDecorationView.es6.js new file mode 100644 index 00000000..d65cbf35 --- /dev/null +++ b/core/modules/quickedit/js/views/FieldDecorationView.es6.js @@ -0,0 +1,356 @@ +/** + * @file + * A Backbone View that decorates the in-place edited element. + */ + +(function ($, Backbone, Drupal) { + Drupal.quickedit.FieldDecorationView = Backbone.View.extend(/** @lends Drupal.quickedit.FieldDecorationView# */{ + + /** + * @type {null} + */ + _widthAttributeIsEmpty: null, + + /** + * @type {object} + */ + events: { + 'mouseenter.quickedit': 'onMouseEnter', + 'mouseleave.quickedit': 'onMouseLeave', + click: 'onClick', + 'tabIn.quickedit': 'onMouseEnter', + 'tabOut.quickedit': 'onMouseLeave', + }, + + /** + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * An object with the following keys: + * @param {Drupal.quickedit.EditorView} options.editorView + * The editor object view. + */ + initialize(options) { + this.editorView = options.editorView; + + this.listenTo(this.model, 'change:state', this.stateChange); + this.listenTo(this.model, 'change:isChanged change:inTempStore', this.renderChanged); + }, + + /** + * @inheritdoc + */ + remove() { + // The el property is the field, which should not be removed. Remove the + // pointer to it, then call Backbone.View.prototype.remove(). + this.setElement(); + Backbone.View.prototype.remove.call(this); + }, + + /** + * Determines the actions to take given a change of state. + * + * @param {Drupal.quickedit.FieldModel} model + * The `FieldModel` model. + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.FieldModel.states}. + */ + stateChange(model, state) { + const from = model.previous('state'); + const to = state; + switch (to) { + case 'inactive': + this.undecorate(); + break; + + case 'candidate': + this.decorate(); + if (from !== 'inactive') { + this.stopHighlight(); + if (from !== 'highlighted') { + this.model.set('isChanged', false); + this.stopEdit(); + } + } + this._unpad(); + break; + + case 'highlighted': + this.startHighlight(); + break; + + case 'activating': + // NOTE: this state is not used by every editor! It's only used by + // those that need to interact with the server. + this.prepareEdit(); + break; + + case 'active': + if (from !== 'activating') { + this.prepareEdit(); + } + if (this.editorView.getQuickEditUISettings().padding) { + this._pad(); + } + break; + + case 'changed': + this.model.set('isChanged', true); + break; + + case 'saving': + break; + + case 'saved': + break; + + case 'invalid': + break; + } + }, + + /** + * Adds a class to the edited element that indicates whether the field has + * been changed by the user (i.e. locally) or the field has already been + * changed and stored before by the user (i.e. remotely, stored in + * PrivateTempStore). + */ + renderChanged() { + this.$el.toggleClass('quickedit-changed', this.model.get('isChanged') || this.model.get('inTempStore')); + }, + + /** + * Starts hover; transitions to 'highlight' state. + * + * @param {jQuery.Event} event + * The mouse event. + */ + onMouseEnter(event) { + const that = this; + that.model.set('state', 'highlighted'); + event.stopPropagation(); + }, + + /** + * Stops hover; transitions to 'candidate' state. + * + * @param {jQuery.Event} event + * The mouse event. + */ + onMouseLeave(event) { + const that = this; + that.model.set('state', 'candidate', { reason: 'mouseleave' }); + event.stopPropagation(); + }, + + /** + * Transition to 'activating' stage. + * + * @param {jQuery.Event} event + * The click event. + */ + onClick(event) { + this.model.set('state', 'activating'); + event.preventDefault(); + event.stopPropagation(); + }, + + /** + * Adds classes used to indicate an elements editable state. + */ + decorate() { + this.$el.addClass('quickedit-candidate quickedit-editable'); + }, + + /** + * Removes classes used to indicate an elements editable state. + */ + undecorate() { + this.$el.removeClass('quickedit-candidate quickedit-editable quickedit-highlighted quickedit-editing'); + }, + + /** + * Adds that class that indicates that an element is highlighted. + */ + startHighlight() { + // Animations. + const that = this; + // Use a timeout to grab the next available animation frame. + that.$el.addClass('quickedit-highlighted'); + }, + + /** + * Removes the class that indicates that an element is highlighted. + */ + stopHighlight() { + this.$el.removeClass('quickedit-highlighted'); + }, + + /** + * Removes the class that indicates that an element as editable. + */ + prepareEdit() { + this.$el.addClass('quickedit-editing'); + + // Allow the field to be styled differently while editing in a pop-up + // in-place editor. + if (this.editorView.getQuickEditUISettings().popup) { + this.$el.addClass('quickedit-editor-is-popup'); + } + }, + + /** + * Removes the class that indicates that an element is being edited. + * + * Reapplies the class that indicates that a candidate editable element is + * again available to be edited. + */ + stopEdit() { + this.$el.removeClass('quickedit-highlighted quickedit-editing'); + + // Done editing in a pop-up in-place editor; remove the class. + if (this.editorView.getQuickEditUISettings().popup) { + this.$el.removeClass('quickedit-editor-is-popup'); + } + + // Make the other editors show up again. + $('.quickedit-candidate').addClass('quickedit-editable'); + }, + + /** + * Adds padding around the editable element to make it pop visually. + */ + _pad() { + // Early return if the element has already been padded. + if (this.$el.data('quickedit-padded')) { + return; + } + const self = this; + + // Add 5px padding for readability. This means we'll freeze the current + // width and *then* add 5px padding, hence ensuring the padding is added + // "on the outside". + // 1) Freeze the width (if it's not already set); don't use animations. + if (this.$el[0].style.width === '') { + this._widthAttributeIsEmpty = true; + this.$el + .addClass('quickedit-animate-disable-width') + .css('width', this.$el.width()); + } + + // 2) Add padding; use animations. + const posProp = this._getPositionProperties(this.$el); + setTimeout(() => { + // Re-enable width animations (padding changes affect width too!). + self.$el.removeClass('quickedit-animate-disable-width'); + + // Pad the editable. + self.$el + .css({ + position: 'relative', + top: `${posProp.top - 5}px`, + left: `${posProp.left - 5}px`, + 'padding-top': `${posProp['padding-top'] + 5}px`, + 'padding-left': `${posProp['padding-left'] + 5}px`, + 'padding-right': `${posProp['padding-right'] + 5}px`, + 'padding-bottom': `${posProp['padding-bottom'] + 5}px`, + 'margin-bottom': `${posProp['margin-bottom'] - 10}px`, + }) + .data('quickedit-padded', true); + }, 0); + }, + + /** + * Removes the padding around the element being edited when editing ceases. + */ + _unpad() { + // Early return if the element has not been padded. + if (!this.$el.data('quickedit-padded')) { + return; + } + const self = this; + + // 1) Set the empty width again. + if (this._widthAttributeIsEmpty) { + this.$el + .addClass('quickedit-animate-disable-width') + .css('width', ''); + } + + // 2) Remove padding; use animations (these will run simultaneously with) + // the fading out of the toolbar as its gets removed). + const posProp = this._getPositionProperties(this.$el); + setTimeout(() => { + // Re-enable width animations (padding changes affect width too!). + self.$el.removeClass('quickedit-animate-disable-width'); + + // Unpad the editable. + self.$el + .css({ + position: 'relative', + top: `${posProp.top + 5}px`, + left: `${posProp.left + 5}px`, + 'padding-top': `${posProp['padding-top'] - 5}px`, + 'padding-left': `${posProp['padding-left'] - 5}px`, + 'padding-right': `${posProp['padding-right'] - 5}px`, + 'padding-bottom': `${posProp['padding-bottom'] - 5}px`, + 'margin-bottom': `${posProp['margin-bottom'] + 10}px`, + }); + }, 0); + // Remove the marker that indicates that this field has padding. This is + // done outside the timed out function above so that we don't get numerous + // queued functions that will remove padding before the data marker has + // been removed. + this.$el.removeData('quickedit-padded'); + }, + + /** + * Gets the top and left properties of an element. + * + * Convert extraneous values and information into numbers ready for + * subtraction. + * + * @param {jQuery} $e + * The element to get position properties from. + * + * @return {object} + * An object containing css values for the needed properties. + */ + _getPositionProperties($e) { + let p; + const r = {}; + const props = [ + 'top', 'left', 'bottom', 'right', + 'padding-top', 'padding-left', 'padding-right', 'padding-bottom', + 'margin-bottom', + ]; + + const propCount = props.length; + for (let i = 0; i < propCount; i++) { + p = props[i]; + r[p] = parseInt(this._replaceBlankPosition($e.css(p)), 10); + } + return r; + }, + + /** + * Replaces blank or 'auto' CSS `position: ` values with "0px". + * + * @param {string} [pos] + * The value for a CSS position declaration. + * + * @return {string} + * A CSS value that is valid for `position`. + */ + _replaceBlankPosition(pos) { + if (pos === 'auto' || !pos) { + pos = '0px'; + } + return pos; + }, + + }); +}(jQuery, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/views/FieldDecorationView.js b/core/modules/quickedit/js/views/FieldDecorationView.js index 966e2b9f..b235d81b 100644 --- a/core/modules/quickedit/js/views/FieldDecorationView.js +++ b/core/modules/quickedit/js/views/FieldDecorationView.js @@ -1,67 +1,33 @@ /** - * @file - * A Backbone View that decorates the in-place edited element. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Backbone, Drupal) { - - 'use strict'; - - Drupal.quickedit.FieldDecorationView = Backbone.View.extend(/** @lends Drupal.quickedit.FieldDecorationView# */{ - - /** - * @type {null} - */ + Drupal.quickedit.FieldDecorationView = Backbone.View.extend({ _widthAttributeIsEmpty: null, - /** - * @type {object} - */ events: { 'mouseenter.quickedit': 'onMouseEnter', 'mouseleave.quickedit': 'onMouseLeave', - 'click': 'onClick', + click: 'onClick', 'tabIn.quickedit': 'onMouseEnter', 'tabOut.quickedit': 'onMouseLeave' }, - /** - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * An object with the following keys: - * @param {Drupal.quickedit.EditorView} options.editorView - * The editor object view. - */ - initialize: function (options) { + initialize: function initialize(options) { this.editorView = options.editorView; this.listenTo(this.model, 'change:state', this.stateChange); this.listenTo(this.model, 'change:isChanged change:inTempStore', this.renderChanged); }, - - /** - * @inheritdoc - */ - remove: function () { - // The el property is the field, which should not be removed. Remove the - // pointer to it, then call Backbone.View.prototype.remove(). + remove: function remove() { this.setElement(); Backbone.View.prototype.remove.call(this); }, - - /** - * Determines the actions to take given a change of state. - * - * @param {Drupal.quickedit.FieldModel} model - * The `FieldModel` model. - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.FieldModel.states}. - */ - stateChange: function (model, state) { + stateChange: function stateChange(model, state) { var from = model.previous('state'); var to = state; switch (to) { @@ -86,8 +52,6 @@ break; case 'activating': - // NOTE: this state is not used by every editor! It's only used by - // those that need to interact with the server. this.prepareEdit(); break; @@ -114,222 +78,113 @@ break; } }, - - /** - * Adds a class to the edited element that indicates whether the field has - * been changed by the user (i.e. locally) or the field has already been - * changed and stored before by the user (i.e. remotely, stored in - * PrivateTempStore). - */ - renderChanged: function () { + renderChanged: function renderChanged() { this.$el.toggleClass('quickedit-changed', this.model.get('isChanged') || this.model.get('inTempStore')); }, - - /** - * Starts hover; transitions to 'highlight' state. - * - * @param {jQuery.Event} event - * The mouse event. - */ - onMouseEnter: function (event) { + onMouseEnter: function onMouseEnter(event) { var that = this; that.model.set('state', 'highlighted'); event.stopPropagation(); }, - - /** - * Stops hover; transitions to 'candidate' state. - * - * @param {jQuery.Event} event - * The mouse event. - */ - onMouseLeave: function (event) { + onMouseLeave: function onMouseLeave(event) { var that = this; - that.model.set('state', 'candidate', {reason: 'mouseleave'}); + that.model.set('state', 'candidate', { reason: 'mouseleave' }); event.stopPropagation(); }, - - /** - * Transition to 'activating' stage. - * - * @param {jQuery.Event} event - * The click event. - */ - onClick: function (event) { + onClick: function onClick(event) { this.model.set('state', 'activating'); event.preventDefault(); event.stopPropagation(); }, - - /** - * Adds classes used to indicate an elements editable state. - */ - decorate: function () { + decorate: function decorate() { this.$el.addClass('quickedit-candidate quickedit-editable'); }, - - /** - * Removes classes used to indicate an elements editable state. - */ - undecorate: function () { + undecorate: function undecorate() { this.$el.removeClass('quickedit-candidate quickedit-editable quickedit-highlighted quickedit-editing'); }, - - /** - * Adds that class that indicates that an element is highlighted. - */ - startHighlight: function () { - // Animations. + startHighlight: function startHighlight() { var that = this; - // Use a timeout to grab the next available animation frame. + that.$el.addClass('quickedit-highlighted'); }, - - /** - * Removes the class that indicates that an element is highlighted. - */ - stopHighlight: function () { + stopHighlight: function stopHighlight() { this.$el.removeClass('quickedit-highlighted'); }, - - /** - * Removes the class that indicates that an element as editable. - */ - prepareEdit: function () { + prepareEdit: function prepareEdit() { this.$el.addClass('quickedit-editing'); - // Allow the field to be styled differently while editing in a pop-up - // in-place editor. if (this.editorView.getQuickEditUISettings().popup) { this.$el.addClass('quickedit-editor-is-popup'); } }, - - /** - * Removes the class that indicates that an element is being edited. - * - * Reapplies the class that indicates that a candidate editable element is - * again available to be edited. - */ - stopEdit: function () { + stopEdit: function stopEdit() { this.$el.removeClass('quickedit-highlighted quickedit-editing'); - // Done editing in a pop-up in-place editor; remove the class. if (this.editorView.getQuickEditUISettings().popup) { this.$el.removeClass('quickedit-editor-is-popup'); } - // Make the other editors show up again. $('.quickedit-candidate').addClass('quickedit-editable'); }, - - /** - * Adds padding around the editable element to make it pop visually. - */ - _pad: function () { - // Early return if the element has already been padded. + _pad: function _pad() { if (this.$el.data('quickedit-padded')) { return; } var self = this; - // Add 5px padding for readability. This means we'll freeze the current - // width and *then* add 5px padding, hence ensuring the padding is added - // "on the outside". - // 1) Freeze the width (if it's not already set); don't use animations. if (this.$el[0].style.width === '') { this._widthAttributeIsEmpty = true; - this.$el - .addClass('quickedit-animate-disable-width') - .css('width', this.$el.width()); + this.$el.addClass('quickedit-animate-disable-width').css('width', this.$el.width()); } - // 2) Add padding; use animations. var posProp = this._getPositionProperties(this.$el); setTimeout(function () { - // Re-enable width animations (padding changes affect width too!). self.$el.removeClass('quickedit-animate-disable-width'); - // Pad the editable. - self.$el - .css({ - 'position': 'relative', - 'top': posProp.top - 5 + 'px', - 'left': posProp.left - 5 + 'px', - 'padding-top': posProp['padding-top'] + 5 + 'px', - 'padding-left': posProp['padding-left'] + 5 + 'px', - 'padding-right': posProp['padding-right'] + 5 + 'px', - 'padding-bottom': posProp['padding-bottom'] + 5 + 'px', - 'margin-bottom': posProp['margin-bottom'] - 10 + 'px' - }) - .data('quickedit-padded', true); + self.$el.css({ + position: 'relative', + top: posProp.top - 5 + 'px', + left: posProp.left - 5 + 'px', + 'padding-top': posProp['padding-top'] + 5 + 'px', + 'padding-left': posProp['padding-left'] + 5 + 'px', + 'padding-right': posProp['padding-right'] + 5 + 'px', + 'padding-bottom': posProp['padding-bottom'] + 5 + 'px', + 'margin-bottom': posProp['margin-bottom'] - 10 + 'px' + }).data('quickedit-padded', true); }, 0); }, - - /** - * Removes the padding around the element being edited when editing ceases. - */ - _unpad: function () { - // Early return if the element has not been padded. + _unpad: function _unpad() { if (!this.$el.data('quickedit-padded')) { return; } var self = this; - // 1) Set the empty width again. if (this._widthAttributeIsEmpty) { - this.$el - .addClass('quickedit-animate-disable-width') - .css('width', ''); + this.$el.addClass('quickedit-animate-disable-width').css('width', ''); } - // 2) Remove padding; use animations (these will run simultaneously with) - // the fading out of the toolbar as its gets removed). var posProp = this._getPositionProperties(this.$el); setTimeout(function () { - // Re-enable width animations (padding changes affect width too!). self.$el.removeClass('quickedit-animate-disable-width'); - // Unpad the editable. - self.$el - .css({ - 'position': 'relative', - 'top': posProp.top + 5 + 'px', - 'left': posProp.left + 5 + 'px', - 'padding-top': posProp['padding-top'] - 5 + 'px', - 'padding-left': posProp['padding-left'] - 5 + 'px', - 'padding-right': posProp['padding-right'] - 5 + 'px', - 'padding-bottom': posProp['padding-bottom'] - 5 + 'px', - 'margin-bottom': posProp['margin-bottom'] + 10 + 'px' - }); + self.$el.css({ + position: 'relative', + top: posProp.top + 5 + 'px', + left: posProp.left + 5 + 'px', + 'padding-top': posProp['padding-top'] - 5 + 'px', + 'padding-left': posProp['padding-left'] - 5 + 'px', + 'padding-right': posProp['padding-right'] - 5 + 'px', + 'padding-bottom': posProp['padding-bottom'] - 5 + 'px', + 'margin-bottom': posProp['margin-bottom'] + 10 + 'px' + }); }, 0); - // Remove the marker that indicates that this field has padding. This is - // done outside the timed out function above so that we don't get numerous - // queued functions that will remove padding before the data marker has - // been removed. + this.$el.removeData('quickedit-padded'); }, - - /** - * Gets the top and left properties of an element. - * - * Convert extraneous values and information into numbers ready for - * subtraction. - * - * @param {jQuery} $e - * The element to get position properties from. - * - * @return {object} - * An object containing css values for the needed properties. - */ - _getPositionProperties: function ($e) { - var p; + _getPositionProperties: function _getPositionProperties($e) { + var p = void 0; var r = {}; - var props = [ - 'top', 'left', 'bottom', 'right', - 'padding-top', 'padding-left', 'padding-right', 'padding-bottom', - 'margin-bottom' - ]; + var props = ['top', 'left', 'bottom', 'right', 'padding-top', 'padding-left', 'padding-right', 'padding-bottom', 'margin-bottom']; var propCount = props.length; for (var i = 0; i < propCount; i++) { @@ -338,23 +193,11 @@ } return r; }, - - /** - * Replaces blank or 'auto' CSS `position: ` values with "0px". - * - * @param {string} [pos] - * The value for a CSS position declaration. - * - * @return {string} - * A CSS value that is valid for `position`. - */ - _replaceBlankPosition: function (pos) { + _replaceBlankPosition: function _replaceBlankPosition(pos) { if (pos === 'auto' || !pos) { pos = '0px'; } return pos; } - }); - -})(jQuery, Backbone, Drupal); +})(jQuery, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/FieldToolbarView.es6.js b/core/modules/quickedit/js/views/FieldToolbarView.es6.js new file mode 100644 index 00000000..13e0457b --- /dev/null +++ b/core/modules/quickedit/js/views/FieldToolbarView.es6.js @@ -0,0 +1,223 @@ +/** + * @file + * A Backbone View that provides an interactive toolbar (1 per in-place editor). + */ + +(function ($, _, Backbone, Drupal) { + Drupal.quickedit.FieldToolbarView = Backbone.View.extend(/** @lends Drupal.quickedit.FieldToolbarView# */{ + + /** + * The edited element, as indicated by EditorView.getEditedElement. + * + * @type {jQuery} + */ + $editedElement: null, + + /** + * A reference to the in-place editor. + * + * @type {Drupal.quickedit.EditorView} + */ + editorView: null, + + /** + * @type {string} + */ + _id: null, + + /** + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * Options object to construct the field toolbar. + * @param {jQuery} options.$editedElement + * The element being edited. + * @param {Drupal.quickedit.EditorView} options.editorView + * The EditorView the toolbar belongs to. + */ + initialize(options) { + this.$editedElement = options.$editedElement; + this.editorView = options.editorView; + + /** + * @type {jQuery} + */ + this.$root = this.$el; + + // Generate a DOM-compatible ID for the form container DOM element. + this._id = `quickedit-toolbar-for-${this.model.id.replace(/[\/\[\]]/g, '_')}`; + + this.listenTo(this.model, 'change:state', this.stateChange); + }, + + /** + * @inheritdoc + * + * @return {Drupal.quickedit.FieldToolbarView} + * The current FieldToolbarView. + */ + render() { + // Render toolbar and set it as the view's element. + this.setElement($(Drupal.theme('quickeditFieldToolbar', { + id: this._id, + }))); + + // Attach to the field toolbar $root element in the entity toolbar. + this.$el.prependTo(this.$root); + + return this; + }, + + /** + * Determines the actions to take given a change of state. + * + * @param {Drupal.quickedit.FieldModel} model + * The quickedit FieldModel + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.FieldModel.states}. + */ + stateChange(model, state) { + const from = model.previous('state'); + const to = state; + switch (to) { + case 'inactive': + break; + + case 'candidate': + // Remove the view's existing element if we went to the 'activating' + // state or later, because it will be recreated. Not doing this would + // result in memory leaks. + if (from !== 'inactive' && from !== 'highlighted') { + this.$el.remove(); + this.setElement(); + } + break; + + case 'highlighted': + break; + + case 'activating': + this.render(); + + if (this.editorView.getQuickEditUISettings().fullWidthToolbar) { + this.$el.addClass('quickedit-toolbar-fullwidth'); + } + + if (this.editorView.getQuickEditUISettings().unifiedToolbar) { + this.insertWYSIWYGToolGroups(); + } + break; + + case 'active': + break; + + case 'changed': + break; + + case 'saving': + break; + + case 'saved': + break; + + case 'invalid': + break; + } + }, + + /** + * Insert WYSIWYG markup into the associated toolbar. + */ + insertWYSIWYGToolGroups() { + this.$el + .append(Drupal.theme('quickeditToolgroup', { + id: this.getFloatedWysiwygToolgroupId(), + classes: ['wysiwyg-floated', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'], + buttons: [], + })) + .append(Drupal.theme('quickeditToolgroup', { + id: this.getMainWysiwygToolgroupId(), + classes: ['wysiwyg-main', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'], + buttons: [], + })); + + // Animate the toolgroups into visibility. + this.show('wysiwyg-floated'); + this.show('wysiwyg-main'); + }, + + /** + * Retrieves the ID for this toolbar's container. + * + * Only used to make sane hovering behavior possible. + * + * @return {string} + * A string that can be used as the ID for this toolbar's container. + */ + getId() { + return `quickedit-toolbar-for-${this._id}`; + }, + + /** + * Retrieves the ID for this toolbar's floating WYSIWYG toolgroup. + * + * Used to provide an abstraction for any WYSIWYG editor to plug in. + * + * @return {string} + * A string that can be used as the ID. + */ + getFloatedWysiwygToolgroupId() { + return `quickedit-wysiwyg-floated-toolgroup-for-${this._id}`; + }, + + /** + * Retrieves the ID for this toolbar's main WYSIWYG toolgroup. + * + * Used to provide an abstraction for any WYSIWYG editor to plug in. + * + * @return {string} + * A string that can be used as the ID. + */ + getMainWysiwygToolgroupId() { + return `quickedit-wysiwyg-main-toolgroup-for-${this._id}`; + }, + + /** + * Finds a toolgroup. + * + * @param {string} toolgroup + * A toolgroup name. + * + * @return {jQuery} + * The toolgroup element. + */ + _find(toolgroup) { + return this.$el.find(`.quickedit-toolgroup.${toolgroup}`); + }, + + /** + * Shows a toolgroup. + * + * @param {string} toolgroup + * A toolgroup name. + */ + show(toolgroup) { + const $group = this._find(toolgroup); + // Attach a transitionEnd event handler to the toolbar group so that + // update events can be triggered after the animations have ended. + $group.on(Drupal.quickedit.util.constants.transitionEnd, (event) => { + $group.off(Drupal.quickedit.util.constants.transitionEnd); + }); + // The call to remove the class and start the animation must be started in + // the next animation frame or the event handler attached above won't be + // triggered. + window.setTimeout(() => { + $group.removeClass('quickedit-animate-invisible'); + }, 0); + }, + + }); +}(jQuery, _, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/views/FieldToolbarView.js b/core/modules/quickedit/js/views/FieldToolbarView.js index dbd531f4..578526b2 100644 --- a/core/modules/quickedit/js/views/FieldToolbarView.js +++ b/core/modules/quickedit/js/views/FieldToolbarView.js @@ -1,88 +1,38 @@ /** - * @file - * A Backbone View that provides an interactive toolbar (1 per in-place editor). - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, _, Backbone, Drupal) { - - 'use strict'; - - Drupal.quickedit.FieldToolbarView = Backbone.View.extend(/** @lends Drupal.quickedit.FieldToolbarView# */{ - - /** - * The edited element, as indicated by EditorView.getEditedElement. - * - * @type {jQuery} - */ + Drupal.quickedit.FieldToolbarView = Backbone.View.extend({ $editedElement: null, - /** - * A reference to the in-place editor. - * - * @type {Drupal.quickedit.EditorView} - */ editorView: null, - /** - * @type {string} - */ _id: null, - /** - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * Options object to construct the field toolbar. - * @param {jQuery} options.$editedElement - * The element being edited. - * @param {Drupal.quickedit.EditorView} options.editorView - * The EditorView the toolbar belongs to. - */ - initialize: function (options) { + initialize: function initialize(options) { this.$editedElement = options.$editedElement; this.editorView = options.editorView; - /** - * @type {jQuery} - */ this.$root = this.$el; - // Generate a DOM-compatible ID for the form container DOM element. this._id = 'quickedit-toolbar-for-' + this.model.id.replace(/[\/\[\]]/g, '_'); this.listenTo(this.model, 'change:state', this.stateChange); }, - - /** - * @inheritdoc - * - * @return {Drupal.quickedit.FieldToolbarView} - * The current FieldToolbarView. - */ - render: function () { - // Render toolbar and set it as the view's element. + render: function render() { this.setElement($(Drupal.theme('quickeditFieldToolbar', { id: this._id }))); - // Attach to the field toolbar $root element in the entity toolbar. this.$el.prependTo(this.$root); return this; }, - - /** - * Determines the actions to take given a change of state. - * - * @param {Drupal.quickedit.FieldModel} model - * The quickedit FieldModel - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.FieldModel.states}. - */ - stateChange: function (model, state) { + stateChange: function stateChange(model, state) { var from = model.previous('state'); var to = state; switch (to) { @@ -90,9 +40,6 @@ break; case 'candidate': - // Remove the view's existing element if we went to the 'activating' - // state or later, because it will be recreated. Not doing this would - // result in memory leaks. if (from !== 'inactive' && from !== 'highlighted') { this.$el.remove(); this.setElement(); @@ -130,98 +77,42 @@ break; } }, + insertWYSIWYGToolGroups: function insertWYSIWYGToolGroups() { + this.$el.append(Drupal.theme('quickeditToolgroup', { + id: this.getFloatedWysiwygToolgroupId(), + classes: ['wysiwyg-floated', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'], + buttons: [] + })).append(Drupal.theme('quickeditToolgroup', { + id: this.getMainWysiwygToolgroupId(), + classes: ['wysiwyg-main', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'], + buttons: [] + })); - /** - * Insert WYSIWYG markup into the associated toolbar. - */ - insertWYSIWYGToolGroups: function () { - this.$el - .append(Drupal.theme('quickeditToolgroup', { - id: this.getFloatedWysiwygToolgroupId(), - classes: ['wysiwyg-floated', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'], - buttons: [] - })) - .append(Drupal.theme('quickeditToolgroup', { - id: this.getMainWysiwygToolgroupId(), - classes: ['wysiwyg-main', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'], - buttons: [] - })); - - // Animate the toolgroups into visibility. this.show('wysiwyg-floated'); this.show('wysiwyg-main'); }, - - /** - * Retrieves the ID for this toolbar's container. - * - * Only used to make sane hovering behavior possible. - * - * @return {string} - * A string that can be used as the ID for this toolbar's container. - */ - getId: function () { + getId: function getId() { return 'quickedit-toolbar-for-' + this._id; }, - - /** - * Retrieves the ID for this toolbar's floating WYSIWYG toolgroup. - * - * Used to provide an abstraction for any WYSIWYG editor to plug in. - * - * @return {string} - * A string that can be used as the ID. - */ - getFloatedWysiwygToolgroupId: function () { + getFloatedWysiwygToolgroupId: function getFloatedWysiwygToolgroupId() { return 'quickedit-wysiwyg-floated-toolgroup-for-' + this._id; }, - - /** - * Retrieves the ID for this toolbar's main WYSIWYG toolgroup. - * - * Used to provide an abstraction for any WYSIWYG editor to plug in. - * - * @return {string} - * A string that can be used as the ID. - */ - getMainWysiwygToolgroupId: function () { + getMainWysiwygToolgroupId: function getMainWysiwygToolgroupId() { return 'quickedit-wysiwyg-main-toolgroup-for-' + this._id; }, - - /** - * Finds a toolgroup. - * - * @param {string} toolgroup - * A toolgroup name. - * - * @return {jQuery} - * The toolgroup element. - */ - _find: function (toolgroup) { + _find: function _find(toolgroup) { return this.$el.find('.quickedit-toolgroup.' + toolgroup); }, - - /** - * Shows a toolgroup. - * - * @param {string} toolgroup - * A toolgroup name. - */ - show: function (toolgroup) { + show: function show(toolgroup) { var $group = this._find(toolgroup); - // Attach a transitionEnd event handler to the toolbar group so that - // update events can be triggered after the animations have ended. + $group.on(Drupal.quickedit.util.constants.transitionEnd, function (event) { $group.off(Drupal.quickedit.util.constants.transitionEnd); }); - // The call to remove the class and start the animation must be started in - // the next animation frame or the event handler attached above won't be - // triggered. + window.setTimeout(function () { $group.removeClass('quickedit-animate-invisible'); }, 0); } - }); - -})(jQuery, _, Backbone, Drupal); +})(jQuery, _, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/quickedit.api.php b/core/modules/quickedit/quickedit.api.php index 8e6a2a8e..581b5616 100644 --- a/core/modules/quickedit/quickedit.api.php +++ b/core/modules/quickedit/quickedit.api.php @@ -70,11 +70,11 @@ function hook_quickedit_editor_alter(&$editors) { * @see \Drupal\Core\Field\FieldItemListInterface::view() */ function hook_quickedit_render_field(Drupal\Core\Entity\EntityInterface $entity, $field_name, $view_mode_id, $langcode) { - return array( + return [ '#prefix' => '
    ', 'field' => $entity->getTranslation($langcode)->get($field_name)->view($view_mode_id), '#suffix' => '
    ', - ); + ]; } /** diff --git a/core/modules/quickedit/quickedit.info.yml b/core/modules/quickedit/quickedit.info.yml index df0d4a21..657ba9a5 100644 --- a/core/modules/quickedit/quickedit.info.yml +++ b/core/modules/quickedit/quickedit.info.yml @@ -9,8 +9,8 @@ dependencies: - field - filter -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/quickedit/quickedit.module b/core/modules/quickedit/quickedit.module index 2d69a66e..3d270500 100644 --- a/core/modules/quickedit/quickedit.module +++ b/core/modules/quickedit/quickedit.module @@ -11,6 +11,7 @@ * entities, enabling them for in-place editing. */ +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Routing\RouteMatchInterface; @@ -22,12 +23,12 @@ function quickedit_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.quickedit': $output = '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Quick Edit module allows users with the Access in-place editing and Use contextual links permissions to edit field content without visiting a separate page. For more information, see the online documentation for the Quick Edit module.', array(':handbook_url' => 'https://www.drupal.org/documentation/modules/edit', ':quickedit_permission' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-quickedit')), ':contextual_permission' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-contextual')))) . '

    '; + $output .= '

    ' . t('The Quick Edit module allows users with the Access in-place editing and Use contextual links permissions to edit field content without visiting a separate page. For more information, see the online documentation for the Quick Edit module.', [':handbook_url' => 'https://www.drupal.org/documentation/modules/edit', ':quickedit_permission' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-quickedit']), ':contextual_permission' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-contextual'])]) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Editing content in-place') . '
    '; $output .= '
    '; - $output .= '

    ' . t('To edit content in place, you need to activate quick edit mode for a content item. Activate quick edit mode by choosing Quick edit from the contextual links for an area displaying the content (see the Contextual Links module help for more information about how to use contextual links).', array(':contextual' => \Drupal::url('help.page', array('name' => 'contextual')))) . '

    '; + $output .= '

    ' . t('To edit content in place, you need to activate quick edit mode for a content item. Activate quick edit mode by choosing Quick edit from the contextual links for an area displaying the content (see the Contextual Links module help for more information about how to use contextual links).', [':contextual' => \Drupal::url('help.page', ['name' => 'contextual'])]) . '

    '; $output .= '

    ' . t('Once quick edit mode is activated, you will be able to edit the individual fields of your content. In the default theme, with a JavaScript-enabled browser and a mouse, the output of different fields in your content is outlined in blue, a pop-up gives the field name as you hover over the field output, and clicking on a field activates the editor. Closing the pop-up window ends quick edit mode.') . '

    '; $output .= '
    '; $output .= '
    '; @@ -76,7 +77,7 @@ function quickedit_library_info_alter(&$libraries, $extension) { $theme = Drupal::config('system.theme')->get('admin'); // First let the base theme modify the library, then the actual theme. - $alter_library = function(&$library, $theme) use (&$alter_library) { + $alter_library = function (&$library, $theme) use (&$alter_library) { if (isset($theme) && $theme_path = drupal_get_path('theme', $theme)) { $info = system_get_info('theme', $theme); // Recurse to process base theme(s) first. @@ -108,7 +109,7 @@ function quickedit_field_formatter_info_alter(&$info) { foreach ($info as $key => $settings) { // Set in-place editor to 'form' if none is supplied. if (empty($settings['quickedit'])) { - $info[$key]['quickedit'] = array('editor' => 'form'); + $info[$key]['quickedit'] = ['editor' => 'form']; } } } @@ -117,7 +118,10 @@ function quickedit_field_formatter_info_alter(&$info) { * Implements hook_preprocess_HOOK() for the page title template. */ function quickedit_preprocess_page_title(&$variables) { - $variables['title_attributes']['class'][] = 'js-quickedit-page-title'; + $variables['#cache']['contexts'][] = 'user.permissions'; + if (\Drupal::currentUser()->hasPermission('access in-place editing')) { + $variables['title_attributes']['class'][] = 'js-quickedit-page-title'; + } } /** @@ -125,14 +129,14 @@ function quickedit_preprocess_page_title(&$variables) { */ function quickedit_preprocess_field(&$variables) { $variables['#cache']['contexts'][] = 'user.permissions'; - if (!\Drupal::currentUser()->hasPermission('access in-place editing')) { - return; - } - $element = $variables['element']; /** @var $entity \Drupal\Core\Entity\EntityInterface */ $entity = $element['#object']; + if (!\Drupal::currentUser()->hasPermission('access in-place editing') || !_quickedit_entity_is_latest_revision($entity)) { + return; + } + // Quick Edit module only supports view modes, not dynamically defined // "display options" (which \Drupal\Core\Field\FieldItemListInterface::view() // always names the "_custom" view mode). @@ -154,9 +158,40 @@ function quickedit_preprocess_field(&$variables) { */ function quickedit_entity_view_alter(&$build, EntityInterface $entity, EntityViewDisplayInterface $display) { $build['#cache']['contexts'][] = 'user.permissions'; - if (!\Drupal::currentUser()->hasPermission('access in-place editing')) { + if (!\Drupal::currentUser()->hasPermission('access in-place editing') || !_quickedit_entity_is_latest_revision($entity)) { return; } $build['#attributes']['data-quickedit-entity-id'] = $entity->getEntityTypeId() . '/' . $entity->id(); } + +/** + * Check if a loaded entity is the latest revision. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity to check. + * + * @return bool + * TRUE if the loaded entity is the latest revision, FALSE otherwise. + * + * @todo Remove this method once better support for pending revisions is added + * to core https://www.drupal.org/node/2784201. + * + * @internal + */ +function _quickedit_entity_is_latest_revision(ContentEntityInterface $entity) { + $entity_type_manager = \Drupal::entityTypeManager(); + $entity_definition = $entity_type_manager->getDefinition($entity->getEntityTypeId()); + if (!$entity_definition->isRevisionable()) { + return TRUE; + } + $revision_ids = $entity_type_manager + ->getStorage($entity->getEntityTypeId()) + ->getQuery() + ->allRevisions() + ->condition($entity_definition->getKey('id'), $entity->id()) + ->sort($entity_definition->getKey('revision'), 'DESC') + ->range(0, 1) + ->execute(); + return $entity->getLoadedRevisionId() == array_keys($revision_ids)[0]; +} diff --git a/core/modules/quickedit/quickedit.services.yml b/core/modules/quickedit/quickedit.services.yml index 692ba2f4..3d7d9343 100644 --- a/core/modules/quickedit/quickedit.services.yml +++ b/core/modules/quickedit/quickedit.services.yml @@ -3,7 +3,7 @@ services: class: Drupal\quickedit\Plugin\InPlaceEditorManager parent: default_plugin_manager access_check.quickedit.entity_field: - class: Drupal\quickedit\Access\EditEntityFieldAccessCheck + class: Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck tags: - { name: access_check, applies_to: _access_quickedit_entity_field } quickedit.editor.selector: diff --git a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php index 7b388383..f9379086 100644 --- a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php +++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php @@ -2,61 +2,9 @@ namespace Drupal\quickedit\Access; -use Drupal\Core\Access\AccessResult; -use Drupal\Core\Routing\Access\AccessInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\Core\Entity\EntityInterface; - /** - * Access check for editing entity fields. + * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. */ -class EditEntityFieldAccessCheck implements AccessInterface, EditEntityFieldAccessCheckInterface { - - /** - * Checks Quick Edit access to the field. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity containing the field. - * @param string $field_name - * The field name. - * @param string $langcode - * The langcode. - * @param \Drupal\Core\Session\AccountInterface $account - * The currently logged in account. - * - * @return \Drupal\Core\Access\AccessResultInterface - * The access result. - * - * @todo Use the $account argument: https://www.drupal.org/node/2266809. - */ - public function access(EntityInterface $entity, $field_name, $langcode, AccountInterface $account) { - if (!$this->validateRequestAttributes($entity, $field_name, $langcode)) { - return AccessResult::forbidden(); - } - - return $this->accessEditEntityField($entity, $field_name); - } - - /** - * {@inheritdoc} - */ - public function accessEditEntityField(EntityInterface $entity, $field_name) { - return $entity->access('update', NULL, TRUE)->andIf($entity->get($field_name)->access('edit', NULL, TRUE)); - } - - /** - * Validates request attributes. - */ - protected function validateRequestAttributes(EntityInterface $entity, $field_name, $langcode) { - // Validate the field name and language. - if (!$field_name || !$entity->hasField($field_name)) { - return FALSE; - } - if (!$langcode || !$entity->hasTranslation($langcode)) { - return FALSE; - } - - return TRUE; - } +class EditEntityFieldAccessCheck extends QuickEditEntityFieldAccessCheck { } diff --git a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php index c7f14e26..cfdb32df 100644 --- a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php +++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php @@ -2,24 +2,9 @@ namespace Drupal\quickedit\Access; -use Drupal\Core\Entity\EntityInterface; - /** - * Access check for editing entity fields. + * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. */ -interface EditEntityFieldAccessCheckInterface { - - /** - * Checks access to edit the requested field of the requested entity. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity. - * @param string $field_name - * The field name. - * - * @return \Drupal\Core\Access\AccessResultInterface - * The access result. - */ - public function accessEditEntityField(EntityInterface $entity, $field_name); +interface EditEntityFieldAccessCheckInterface extends QuickEditEntityFieldAccessCheckInterface { } diff --git a/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php new file mode 100644 index 00000000..5404b048 --- /dev/null +++ b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php @@ -0,0 +1,62 @@ +validateRequestAttributes($entity, $field_name, $langcode)) { + return AccessResult::forbidden(); + } + + return $this->accessEditEntityField($entity, $field_name); + } + + /** + * {@inheritdoc} + */ + public function accessEditEntityField(EntityInterface $entity, $field_name) { + return $entity->access('update', NULL, TRUE)->andIf($entity->get($field_name)->access('edit', NULL, TRUE)); + } + + /** + * Validates request attributes. + */ + protected function validateRequestAttributes(EntityInterface $entity, $field_name, $langcode) { + // Validate the field name and language. + if (!$field_name || !$entity->hasField($field_name)) { + return FALSE; + } + if (!$langcode || !$entity->hasTranslation($langcode)) { + return FALSE; + } + + return TRUE; + } + +} diff --git a/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php new file mode 100644 index 00000000..1428b482 --- /dev/null +++ b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php @@ -0,0 +1,25 @@ +other_view_modes = $other_view_modes; @@ -37,11 +37,11 @@ public function __construct($data, $other_view_modes = array()) { * {@inheritdoc} */ public function render() { - return array( + return [ 'command' => $this->command, 'data' => $this->data, 'other_view_modes' => $this->other_view_modes, - ); + ]; } } diff --git a/core/modules/quickedit/src/EditorSelector.php b/core/modules/quickedit/src/EditorSelector.php index a531b1a4..9149786f 100644 --- a/core/modules/quickedit/src/EditorSelector.php +++ b/core/modules/quickedit/src/EditorSelector.php @@ -65,7 +65,7 @@ public function getEditor($formatter_type, FieldItemListInterface $items) { } // No early return, so create a list of all choices. - $editor_choices = array($editor_id); + $editor_choices = [$editor_id]; if (isset($this->alternatives[$editor_id])) { $editor_choices = array_merge($editor_choices, $this->alternatives[$editor_id]); } @@ -86,7 +86,7 @@ public function getEditor($formatter_type, FieldItemListInterface $items) { * {@inheritdoc} */ public function getEditorAttachments(array $editor_ids) { - $attachments = array(); + $attachments = []; $editor_ids = array_unique($editor_ids); // Editor plugins' attachments. diff --git a/core/modules/quickedit/src/Form/QuickEditFieldForm.php b/core/modules/quickedit/src/Form/QuickEditFieldForm.php index e64f3f2d..ba2dac38 100644 --- a/core/modules/quickedit/src/Form/QuickEditFieldForm.php +++ b/core/modules/quickedit/src/Form/QuickEditFieldForm.php @@ -100,19 +100,19 @@ public function buildForm(array $form, FormStateInterface $form_state, EntityInt // Add a dummy changed timestamp field to attach form errors to. if ($entity instanceof EntityChangedInterface) { - $form['changed_field'] = array( + $form['changed_field'] = [ '#type' => 'hidden', '#value' => $entity->getChangedTime(), - ); + ]; } // Add a submit button. Give it a class for easy JavaScript targeting. - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => t('Save'), - '#attributes' => array('class' => array('quickedit-form-submit')), - ); + '#attributes' => ['class' => ['quickedit-form-submit']], + ]; // Simplify it for optimal in-place use. $this->simplify($form, $form_state); @@ -183,7 +183,7 @@ protected function buildEntity(array $form, FormStateInterface $form_state) { // @todo Refine automated log messages and abstract them to all entity // types: https://www.drupal.org/node/1678002. if ($entity->getEntityTypeId() == 'node' && $entity->isNewRevision() && $entity->revision_log->isEmpty()) { - $entity->revision_log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $entity->get($field_name)->getFieldDefinition()->getLabel())); + $entity->revision_log = t('Updated the %field-name field through in-place editing.', ['%field-name' => $entity->get($field_name)->getFieldDefinition()->getLabel()]); } return $entity; diff --git a/core/modules/quickedit/src/MetadataGenerator.php b/core/modules/quickedit/src/MetadataGenerator.php index a22bf65a..f01256fc 100644 --- a/core/modules/quickedit/src/MetadataGenerator.php +++ b/core/modules/quickedit/src/MetadataGenerator.php @@ -5,7 +5,7 @@ use Drupal\Component\Plugin\PluginManagerInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldItemListInterface; -use Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface; +use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface; use Drupal\Core\Entity\Entity\EntityViewDisplay; /** @@ -16,7 +16,7 @@ class MetadataGenerator implements MetadataGeneratorInterface { /** * An object that checks if a user has access to edit a given entity field. * - * @var \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface + * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface */ protected $accessChecker; @@ -37,14 +37,14 @@ class MetadataGenerator implements MetadataGeneratorInterface { /** * Constructs a new MetadataGenerator. * - * @param \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface $access_checker + * @param \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface $access_checker * An object that checks if a user has access to edit a given field. * @param \Drupal\quickedit\EditorSelectorInterface $editor_selector * An object that determines which editor to attach to a given field. * @param \Drupal\Component\Plugin\PluginManagerInterface $editor_manager * The manager for editor plugins. */ - public function __construct(EditEntityFieldAccessCheckInterface $access_checker, EditorSelectorInterface $editor_selector, PluginManagerInterface $editor_manager) { + public function __construct(QuickEditEntityFieldAccessCheckInterface $access_checker, EditorSelectorInterface $editor_selector, PluginManagerInterface $editor_manager) { $this->accessChecker = $access_checker; $this->editorSelector = $editor_selector; $this->editorManager = $editor_manager; @@ -54,9 +54,9 @@ public function __construct(EditEntityFieldAccessCheckInterface $access_checker, * {@inheritdoc} */ public function generateEntityMetadata(EntityInterface $entity) { - return array( + return [ 'label' => $entity->label(), - ); + ]; } /** @@ -69,24 +69,24 @@ public function generateFieldMetadata(FieldItemListInterface $items, $view_mode) // Early-return if user does not have access. $access = $this->accessChecker->accessEditEntityField($entity, $field_name); if (!$access) { - return array('access' => FALSE); + return ['access' => FALSE]; } // Early-return if no editor is available. $formatter_id = EntityViewDisplay::collectRenderDisplay($entity, $view_mode)->getRenderer($field_name)->getPluginId(); $editor_id = $this->editorSelector->getEditor($formatter_id, $items); if (!isset($editor_id)) { - return array('access' => FALSE); + return ['access' => FALSE]; } // Gather metadata, allow the editor to add additional metadata of its own. $label = $items->getFieldDefinition()->getLabel(); $editor = $this->editorManager->createInstance($editor_id); - $metadata = array( + $metadata = [ 'label' => $label, 'access' => TRUE, 'editor' => $editor_id, - ); + ]; $custom_metadata = $editor->getMetadata($items); if (count($custom_metadata)) { $metadata['custom'] = $custom_metadata; diff --git a/core/modules/quickedit/src/Plugin/InPlaceEditor/FormEditor.php b/core/modules/quickedit/src/Plugin/InPlaceEditor/FormEditor.php index 6a990708..83ab1b46 100644 --- a/core/modules/quickedit/src/Plugin/InPlaceEditor/FormEditor.php +++ b/core/modules/quickedit/src/Plugin/InPlaceEditor/FormEditor.php @@ -25,11 +25,11 @@ public function isCompatible(FieldItemListInterface $items) { * {@inheritdoc} */ public function getAttachments() { - return array( - 'library' => array( + return [ + 'library' => [ 'quickedit/quickedit.inPlaceEditor.form', - ), - ); + ], + ]; } } diff --git a/core/modules/quickedit/src/Plugin/InPlaceEditor/PlainTextEditor.php b/core/modules/quickedit/src/Plugin/InPlaceEditor/PlainTextEditor.php index 1f61a562..5217c20f 100644 --- a/core/modules/quickedit/src/Plugin/InPlaceEditor/PlainTextEditor.php +++ b/core/modules/quickedit/src/Plugin/InPlaceEditor/PlainTextEditor.php @@ -28,11 +28,11 @@ public function isCompatible(FieldItemListInterface $items) { * {@inheritdoc} */ public function getAttachments() { - return array( - 'library' => array( + return [ + 'library' => [ 'quickedit/quickedit.inPlaceEditor.plainText', - ), - ); + ], + ]; } } diff --git a/core/modules/quickedit/src/Plugin/InPlaceEditorBase.php b/core/modules/quickedit/src/Plugin/InPlaceEditorBase.php index d09c38e1..005f41fb 100644 --- a/core/modules/quickedit/src/Plugin/InPlaceEditorBase.php +++ b/core/modules/quickedit/src/Plugin/InPlaceEditorBase.php @@ -18,8 +18,8 @@ abstract class InPlaceEditorBase extends PluginBase implements InPlaceEditorInte /** * {@inheritdoc} */ - function getMetadata(FieldItemListInterface $items) { - return array(); + public function getMetadata(FieldItemListInterface $items) { + return []; } } diff --git a/core/modules/quickedit/src/QuickEditController.php b/core/modules/quickedit/src/QuickEditController.php index a42bcd09..2b1e4b23 100644 --- a/core/modules/quickedit/src/QuickEditController.php +++ b/core/modules/quickedit/src/QuickEditController.php @@ -98,7 +98,7 @@ public function metadata(Request $request) { } $entities = $request->request->get('entities'); - $metadata = array(); + $metadata = []; foreach ($fields as $field) { list($entity_type, $entity_id, $field_name, $langcode, $view_mode) = explode('/', $field); @@ -205,7 +205,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view // Re-render the updated field for other view modes (i.e. for other // instances of the same logical field on the user's page). - $other_view_mode_ids = $request->request->get('other_view_modes') ?: array(); + $other_view_mode_ids = $request->request->get('other_view_modes') ?: []; $other_view_modes = array_map($render_field_in_view_mode, array_combine($other_view_mode_ids, $other_view_mode_ids)); $response->addCommand(new FieldFormSavedCommand($output, $other_view_modes)); @@ -220,9 +220,9 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view $errors = $form_state->getErrors(); if (count($errors)) { - $status_messages = array( + $status_messages = [ '#type' => 'status_messages' - ); + ]; $response->addCommand(new FieldFormValidationErrorsCommand($this->renderer->renderRoot($status_messages))); } } @@ -266,7 +266,7 @@ protected function renderField(EntityInterface $entity, $field_name, $langcode, // by a dash; the first part must be the module name. $mode_id_parts = explode('-', $view_mode_id, 2); $module = reset($mode_id_parts); - $args = array($entity, $field_name, $view_mode_id, $langcode); + $args = [$entity, $field_name, $view_mode_id, $langcode]; $output = $this->moduleHandler()->invoke($module, 'quickedit_render_field', $args); } @@ -291,10 +291,10 @@ public function entitySave(EntityInterface $entity) { // Return information about the entity that allows a front end application // to identify it. - $output = array( + $output = [ 'entity_type' => $entity->getEntityTypeId(), 'entity_id' => $entity->id() - ); + ]; // Respond to client that the entity was saved properly. $response = new AjaxResponse(); diff --git a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php index 1eedb1c6..a1ef6cd2 100644 --- a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php +++ b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php @@ -25,7 +25,7 @@ class QuickEditAutocompleteTermTest extends WebTestBase { * * @var array */ - public static $modules = array('node', 'taxonomy', 'quickedit'); + public static $modules = ['node', 'taxonomy', 'quickedit']; /** * Stores the node used for the tests. @@ -72,9 +72,9 @@ class QuickEditAutocompleteTermTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->drupalCreateContentType(array( + $this->drupalCreateContentType([ 'type' => 'article', - )); + ]); // Create the vocabulary for the tag field. $this->vocabulary = Vocabulary::create([ 'name' => 'quickedit testing tags', @@ -83,12 +83,12 @@ protected function setUp() { $this->vocabulary->save(); $this->fieldName = 'field_' . $this->vocabulary->id(); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') @@ -114,7 +114,7 @@ protected function setUp() { $this->term1 = $this->createTerm(); $this->term2 = $this->createTerm(); - $node = array(); + $node = []; $node['type'] = 'article'; $node[$this->fieldName][]['target_id'] = $this->term1->id(); $node[$this->fieldName][]['target_id'] = $this->term2->id(); @@ -130,7 +130,7 @@ public function testAutocompleteQuickEdit() { $this->drupalLogin($this->editorUser); $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full'; - $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $ajax_commands = Json::decode($response); @@ -140,13 +140,13 @@ public function testAutocompleteQuickEdit() { $this->assertTrue($form_tokens_found, 'Form tokens found in output.'); if ($form_tokens_found) { - $post = array( + $post = [ 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], - $this->fieldName . '[target_id]' => implode(', ', array($this->term1->getName(), 'new term', $this->term2->getName())), + $this->fieldName . '[target_id]' => implode(', ', [$this->term1->getName(), 'new term', $this->term2->getName()]), 'op' => t('Save'), - ); + ]; // Submit field form and check response. Should render back all the terms. $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); @@ -161,7 +161,7 @@ public function testAutocompleteQuickEdit() { // Load the form again, which should now get it back from // PrivateTempStore. $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full'; - $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $ajax_commands = Json::decode($response); @@ -170,15 +170,15 @@ public function testAutocompleteQuickEdit() { // taxonomy terms, including the one that has just been newly created and // which is not yet stored. $this->setRawContent($ajax_commands[0]['data']); - $expected = array( + $expected = [ $this->term1->getName() . ' (' . $this->term1->id() . ')', 'new term', $this->term2->getName() . ' (' . $this->term2->id() . ')', - ); + ]; $this->assertFieldByName($this->fieldName . '[target_id]', implode(', ', $expected)); // Save the entity. - $post = array('nocssjs' => 'true'); + $post = ['nocssjs' => 'true']; $response = $this->drupalPostWithFormat('quickedit/entity/node/' . $this->node->id(), 'json', $post); $this->assertResponse(200); diff --git a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php index 2a91feca..9ca558a3 100644 --- a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php +++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php @@ -27,13 +27,13 @@ class QuickEditLoadingTest extends WebTestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'contextual', 'quickedit', 'filter', 'node', 'image', - ); + ]; /** * An user with permissions to create and edit articles. @@ -42,6 +42,13 @@ class QuickEditLoadingTest extends WebTestBase { */ protected $authorUser; + /** + * A test node. + * + * @var \Drupal\node\NodeInterface + */ + protected $testNode; + /** * A author user with permissions to access in-place editor. * @@ -53,19 +60,19 @@ protected function setUp() { parent::setUp(); // Create a text format. - $filtered_html_format = FilterFormat::create(array( + $filtered_html_format = FilterFormat::create([ 'format' => 'filtered_html', 'name' => 'Filtered HTML', 'weight' => 0, - 'filters' => array(), - )); + 'filters' => [], + ]); $filtered_html_format->save(); // Create a node type. - $this->drupalCreateContentType(array( + $this->drupalCreateContentType([ 'type' => 'article', 'name' => 'Article', - )); + ]); // Set the node type to initially not have revisions. // Testing with revisions will be done later. @@ -74,22 +81,22 @@ protected function setUp() { $node_type->save(); // Create one node of the above node type using the above text format. - $this->drupalCreateNode(array( + $this->testNode = $this->drupalCreateNode([ 'type' => 'article', - 'body' => array( - 0 => array( + 'body' => [ + 0 => [ 'value' => '

    How are you?

    ', 'format' => 'filtered_html', - ) - ), + ] + ], 'revision_log' => $this->randomString(), - )); + ]); // Create 2 users, the only difference being the ability to use in-place // editing - $basic_permissions = array('access content', 'create article content', 'edit any article content', 'use text format filtered_html', 'access contextual links'); + $basic_permissions = ['access content', 'create article content', 'edit any article content', 'use text format filtered_html', 'access contextual links']; $this->authorUser = $this->drupalCreateUser($basic_permissions); - $this->editorUser = $this->drupalCreateUser(array_merge($basic_permissions, array('access in-place editing'))); + $this->editorUser = $this->drupalCreateUser(array_merge($basic_permissions, ['access in-place editing'])); } /** @@ -103,29 +110,31 @@ public function testUserWithoutPermission() { $this->assertNoRaw('core/modules/quickedit/js/quickedit.js', 'Quick Edit library not loaded.'); $this->assertNoRaw('core/modules/quickedit/js/editors/formEditor.js', "'form' in-place editor not loaded."); - // HTML annotation does not exist for users without permission to in-place - // edit. + // HTML annotation and title class does not exist for users without + // permission to in-place edit. $this->assertNoRaw('data-quickedit-entity-id="node/1"'); $this->assertNoRaw('data-quickedit-field-id="node/1/body/en/full"'); + $this->assertNoFieldByXPath('//h1[contains(@class, "js-quickedit-page-title")]'); // Retrieving the metadata should result in an empty 403 response. - $post = array('fields[0]' => 'node/1/body/en/full'); + $post = ['fields[0]' => 'node/1/body/en/full']; $response = $this->drupalPostWithFormat(Url::fromRoute('quickedit.metadata'), 'json', $post); - $this->assertIdentical('{"message":""}', $response); + $this->assertIdentical(Json::encode(['message' => "The 'access in-place editing' permission is required."]), $response); $this->assertResponse(403); - // Quick Edit's JavaScript would SearchRankingTestnever hit these endpoints if the metadata + // Quick Edit's JavaScript would never hit these endpoints if the metadata // was empty as above, but we need to make sure that malicious users aren't // able to use any of the other endpoints either. - $post = array('editors[0]' => 'form') + $this->getAjaxPageStatePostData(); + $post = ['editors[0]' => 'form'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/attachments', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); - $this->assertIdentical('{}', $response); + $message = Json::encode(['message' => "The 'access in-place editing' permission is required."]); + $this->assertIdentical($message, $response); $this->assertResponse(403); - $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); - $this->assertIdentical('{}', $response); + $this->assertIdentical($message, $response); $this->assertResponse(403); - $edit = array(); + $edit = []; $edit['form_id'] = 'quickedit_field_form'; $edit['form_token'] = 'xIOzMjuc-PULKsRn_KxFn7xzNk5Bx7XKXLfQfw1qOnA'; $edit['form_build_id'] = 'form-kVmovBpyX-SJfTT5kY0pjTV35TV-znor--a64dEnMR8'; @@ -134,11 +143,11 @@ public function testUserWithoutPermission() { $edit['body[0][format]'] = 'filtered_html'; $edit['op'] = t('Save'); $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $edit, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); - $this->assertIdentical('{}', $response); + $this->assertIdentical($message, $response); $this->assertResponse(403); - $post = array('nocssjs' => 'true'); + $post = ['nocssjs' => 'true']; $response = $this->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post); - $this->assertIdentical('{"message":""}', $response); + $this->assertIdentical(Json::encode(['message' => "The 'access in-place editing' permission is required."]), $response); $this->assertResponse(403); } @@ -157,9 +166,11 @@ public function testUserWithPermission() { $this->assertTrue(in_array('quickedit/quickedit', $libraries), 'Quick Edit library loaded.'); $this->assertFalse(in_array('quickedit/quickedit.inPlaceEditor.form', $libraries), "'form' in-place editor not loaded."); - // HTML annotation must always exist (to not break the render cache). + // HTML annotation and title class must always exist (to not break the + // render cache). $this->assertRaw('data-quickedit-entity-id="node/1"'); $this->assertRaw('data-quickedit-field-id="node/1/body/en/full"'); + $this->assertFieldByXPath('//h1[contains(@class, "js-quickedit-page-title")]'); // There should be only one revision so far. $node = Node::load(1); @@ -169,16 +180,16 @@ public function testUserWithPermission() { // Retrieving the metadata should result in a 200 JSON response. $htmlPageDrupalSettings = $this->drupalSettings; - $post = array('fields[0]' => 'node/1/body/en/full'); + $post = ['fields[0]' => 'node/1/body/en/full']; $response = $this->drupalPostWithFormat('quickedit/metadata', 'json', $post); $this->assertResponse(200); - $expected = array( - 'node/1/body/en/full' => array( + $expected = [ + 'node/1/body/en/full' => [ 'label' => 'Body', 'access' => TRUE, 'editor' => 'form', - ) - ); + ] + ]; $this->assertIdentical(Json::decode($response), $expected, 'The metadata HTTP request answers with the correct JSON response.'); // Restore drupalSettings to build the next requests; simpletest wipes them // after a JSON response. @@ -187,7 +198,7 @@ public function testUserWithPermission() { // Retrieving the attachments should result in a 200 response, containing: // 1. a settings command with useless metadata: AjaxController is dumb // 2. an insert command that loads the required in-place editors - $post = array('editors[0]' => 'form') + $this->getAjaxPageStatePostData(); + $post = ['editors[0]' => 'form'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/attachments', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $ajax_commands = Json::decode($response); $this->assertIdentical(2, count($ajax_commands), 'The attachments HTTP request results in two AJAX commands.'); @@ -199,7 +210,7 @@ public function testUserWithPermission() { // Retrieving the form for this field should result in a 200 response, // containing only a quickeditFieldForm command. - $post = array('nocssjs' => 'true', 'reset' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true', 'reset' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -213,17 +224,17 @@ public function testUserWithPermission() { $this->assertTrue($form_tokens_found, 'Form tokens found in output.'); if ($form_tokens_found) { - $edit = array( + $edit = [ 'body[0][summary]' => '', 'body[0][value]' => '

    Fine thanks.

    ', 'body[0][format]' => 'filtered_html', 'op' => t('Save'), - ); - $post = array( + ]; + $post = [ 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], - ); + ]; $post += $edit + $this->getAjaxPageStatePostData(); // Submit field form and check response. This should store the updated @@ -234,14 +245,14 @@ public function testUserWithPermission() { $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.'); $this->assertIdentical('quickeditFieldFormSaved', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldFormSaved command.'); $this->assertTrue(strpos($ajax_commands[0]['data'], 'Fine thanks.'), 'Form value saved and printed back.'); - $this->assertIdentical($ajax_commands[0]['other_view_modes'], array(), 'Field was not rendered in any other view mode.'); + $this->assertIdentical($ajax_commands[0]['other_view_modes'], [], 'Field was not rendered in any other view mode.'); // Ensure the text on the original node did not change yet. $this->drupalGet('node/1'); $this->assertText('How are you?'); // Save the entity by moving the PrivateTempStore values to entity storage. - $post = array('nocssjs' => 'true'); + $post = ['nocssjs' => 'true']; $response = $this->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -269,7 +280,7 @@ public function testUserWithPermission() { $node_type->save(); // Retrieve field form. - $post = array('nocssjs' => 'true', 'reset' => 'true'); + $post = ['nocssjs' => 'true', 'reset' => 'true']; $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -281,11 +292,11 @@ public function testUserWithPermission() { preg_match('/\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match); preg_match('/\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match); $edit['body[0][value]'] = '

    kthxbye

    '; - $post = array( + $post = [ 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], - ); + ]; $post += $edit + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $this->assertResponse(200); @@ -295,7 +306,7 @@ public function testUserWithPermission() { $this->assertTrue(strpos($ajax_commands[0]['data'], 'kthxbye'), 'Form value saved and printed back.'); // Save the entity. - $post = array('nocssjs' => 'true'); + $post = ['nocssjs' => 'true']; $response = $this->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -313,6 +324,26 @@ public function testUserWithPermission() { } } + /** + * Test quickedit does not appear for entities with pending revisions. + */ + public function testWithPendingRevision() { + $this->drupalLogin($this->editorUser); + + $this->drupalGet('node/' . $this->testNode->id()); + $this->assertRaw('data-quickedit-entity-id="node/' . $this->testNode->id() . '"'); + $this->assertRaw('data-quickedit-field-id="node/' . $this->testNode->id() . '/title/' . $this->testNode->language()->getId() . '/full"'); + + $this->testNode->title = 'Updated node'; + $this->testNode->setNewRevision(TRUE); + $this->testNode->isDefaultRevision(FALSE); + $this->testNode->save(); + + $this->drupalGet('node/' . $this->testNode->id()); + $this->assertNoRaw('data-quickedit-entity-id="node/' . $this->testNode->id() . '"'); + $this->assertNoRaw('data-quickedit-field-id="node/' . $this->testNode->id() . '/title/' . $this->testNode->language()->getId() . '/full"'); + } + /** * Tests the loading of Quick Edit for the title base field. */ @@ -322,21 +353,21 @@ public function testTitleBaseField() { // Ensure that the full page title is actually in-place editable $node = Node::load(1); - $elements = $this->xpath('//h1/span[@data-quickedit-field-id="node/1/title/en/full" and normalize-space(text())=:title]', array(':title' => $node->label())); + $elements = $this->xpath('//h1/span[@data-quickedit-field-id="node/1/title/en/full" and normalize-space(text())=:title]', [':title' => $node->label()]); $this->assertTrue(!empty($elements), 'Title with data-quickedit-field-id attribute found.'); // Retrieving the metadata should result in a 200 JSON response. $htmlPageDrupalSettings = $this->drupalSettings; - $post = array('fields[0]' => 'node/1/title/en/full'); + $post = ['fields[0]' => 'node/1/title/en/full']; $response = $this->drupalPostWithFormat('quickedit/metadata', 'json', $post); $this->assertResponse(200); - $expected = array( - 'node/1/title/en/full' => array( + $expected = [ + 'node/1/title/en/full' => [ 'label' => 'Title', 'access' => TRUE, 'editor' => 'plain_text', - ) - ); + ] + ]; $this->assertIdentical(Json::decode($response), $expected, 'The metadata HTTP request answers with the correct JSON response.'); // Restore drupalSettings to build the next requests; simpletest wipes them // after a JSON response. @@ -344,7 +375,7 @@ public function testTitleBaseField() { // Retrieving the form for this field should result in a 200 response, // containing only a quickeditFieldForm command. - $post = array('nocssjs' => 'true', 'reset' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true', 'reset' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/form/' . 'node/1/title/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -359,15 +390,15 @@ public function testTitleBaseField() { $this->assertTrue($form_tokens_found, 'Form tokens found in output.'); if ($form_tokens_found) { - $edit = array( + $edit = [ 'title[0][value]' => 'Obligatory question', 'op' => t('Save'), - ); - $post = array( + ]; + $post = [ 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], - ); + ]; $post += $edit + $this->getAjaxPageStatePostData(); // Submit field form and check response. This should store the @@ -384,7 +415,7 @@ public function testTitleBaseField() { $this->assertNoText('Obligatory question'); // Save the entity by moving the PrivateTempStore values to entity storage. - $post = array('nocssjs' => 'true'); + $post = ['nocssjs' => 'true']; $response = $this->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -405,9 +436,9 @@ public function testTitleBaseField() { */ public function testDisplayOptions() { $node = Node::load('1'); - $display_settings = array( + $display_settings = [ 'label' => 'inline', - ); + ]; $build = $node->body->view($display_settings); $output = \Drupal::service('renderer')->renderRoot($build); $this->assertFalse(strpos($output, 'data-quickedit-field-id'), 'data-quickedit-field-id attribute not added when rendering field using dynamic display options.'); @@ -417,13 +448,13 @@ public function testDisplayOptions() { * Tests that Quick Edit works with custom render pipelines. */ public function testCustomPipeline() { - \Drupal::service('module_installer')->install(array('quickedit_test')); + \Drupal::service('module_installer')->install(['quickedit_test']); $custom_render_url = 'quickedit/form/node/1/body/en/quickedit_test-custom-render-data'; $this->drupalLogin($this->editorUser); // Request editing to render results with the custom render pipeline. - $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost($custom_render_url, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $ajax_commands = Json::decode($response); @@ -433,7 +464,7 @@ public function testCustomPipeline() { $this->assertTrue($form_tokens_found, 'Form tokens found in output.'); if ($form_tokens_found) { - $post = array( + $post = [ 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], 'form_build_id' => $build_id_match[1], @@ -441,10 +472,10 @@ public function testCustomPipeline() { 'body[0][value]' => '

    Fine thanks.

    ', 'body[0][format]' => 'filtered_html', 'op' => t('Save'), - ); + ]; // Assume there is another field on this page, which doesn't use a custom // render pipeline, but the default one, and it uses the "full" view mode. - $post += array('other_view_modes[]' => 'full'); + $post += ['other_view_modes[]' => 'full']; // Submit field form and check response. Should render with the custom // render pipeline. @@ -455,7 +486,7 @@ public function testCustomPipeline() { $this->assertIdentical('quickeditFieldFormSaved', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldFormSaved command.'); $this->assertTrue(strpos($ajax_commands[0]['data'], 'Fine thanks.'), 'Form value saved and printed back.'); $this->assertTrue(strpos($ajax_commands[0]['data'], '
    ') !== FALSE, 'Custom render pipeline used to render the value.'); - $this->assertIdentical(array_keys($ajax_commands[0]['other_view_modes']), array('full'), 'Field was also rendered in the "full" view mode.'); + $this->assertIdentical(array_keys($ajax_commands[0]['other_view_modes']), ['full'], 'Field was also rendered in the "full" view mode.'); $this->assertTrue(strpos($ajax_commands[0]['other_view_modes']['full'], 'Fine thanks.'), '"full" version of field contains the form value.'); } } @@ -467,7 +498,7 @@ public function testCustomPipeline() { public function testConcurrentEdit() { $this->drupalLogin($this->editorUser); - $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData(); + $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(); $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]); $this->assertResponse(200); $ajax_commands = Json::decode($response); @@ -478,7 +509,7 @@ public function testConcurrentEdit() { $this->assertTrue($form_tokens_found, 'Form tokens found in output.'); if ($form_tokens_found) { - $post = array( + $post = [ 'nocssjs' => 'true', 'form_id' => 'quickedit_field_form', 'form_token' => $token_match[1], @@ -487,10 +518,10 @@ public function testConcurrentEdit() { 'body[0][value]' => '

    Fine thanks.

    ', 'body[0][format]' => 'filtered_html', 'op' => t('Save'), - ); + ]; // Save the node on the regular node edit form. - $this->drupalPostForm('node/1/edit', array(), t('Save')); + $this->drupalPostForm('node/1/edit', [], t('Save')); // Ensure different save timestamps for field editing. sleep(2); @@ -509,7 +540,7 @@ public function testConcurrentEdit() { * Tests that Quick Edit's data- attributes are present for content blocks. */ public function testContentBlock() { - \Drupal::service('module_installer')->install(array('block_content')); + \Drupal::service('module_installer')->install(['block_content']); // Create and place a content_block block. $block = BlockContent::create([ diff --git a/core/modules/quickedit/tests/modules/quickedit_test.info.yml b/core/modules/quickedit/tests/modules/quickedit_test.info.yml index 7fd816d0..26e676f1 100644 --- a/core/modules/quickedit/tests/modules/quickedit_test.info.yml +++ b/core/modules/quickedit/tests/modules/quickedit_test.info.yml @@ -5,8 +5,8 @@ description: 'Support module for the Quick Edit module tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/quickedit/tests/modules/quickedit_test.module b/core/modules/quickedit/tests/modules/quickedit_test.module index 3d2106d3..b6199a6e 100644 --- a/core/modules/quickedit/tests/modules/quickedit_test.module +++ b/core/modules/quickedit/tests/modules/quickedit_test.module @@ -12,11 +12,11 @@ use Drupal\Core\Entity\EntityInterface; */ function quickedit_test_quickedit_render_field(EntityInterface $entity, $field_name, $view_mode_id, $langcode) { $entity = \Drupal::entityManager()->getTranslationFromContext($entity, $langcode); - return array( + return [ '#prefix' => '
    ', 'field' => $entity->get($field_name)->view($view_mode_id), '#suffix' => '
    ', - ); + ]; } /** diff --git a/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php index b5d94564..7596aa87 100644 --- a/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php +++ b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php @@ -2,19 +2,9 @@ namespace Drupal\quickedit_test; -use Drupal\Core\Entity\EntityInterface; -use Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface; - /** - * Access check for editing entity fields. + * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. */ -class MockEditEntityFieldAccessCheck implements EditEntityFieldAccessCheckInterface { - - /** - * {@inheritdoc} - */ - public function accessEditEntityField(EntityInterface $entity, $field_name) { - return TRUE; - } +class MockEditEntityFieldAccessCheck extends MockQuickEditEntityFieldAccessCheck { } diff --git a/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php b/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php new file mode 100644 index 00000000..2459c50f --- /dev/null +++ b/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php @@ -0,0 +1,20 @@ + array( + return [ + 'library' => [ 'quickedit_test/not-existing-wysiwyg', - ), - ); + ], + ]; } } diff --git a/core/modules/quickedit/tests/src/Kernel/EditorSelectionTest.php b/core/modules/quickedit/tests/src/Kernel/EditorSelectionTest.php index 0b3820ce..08a8fe04 100644 --- a/core/modules/quickedit/tests/src/Kernel/EditorSelectionTest.php +++ b/core/modules/quickedit/tests/src/Kernel/EditorSelectionTest.php @@ -53,13 +53,13 @@ public function testText() { $this->createFieldWithStorage( $field_name, 'string', 1, 'Simple text field', // Instance settings. - array(), + [], // Widget type & settings. 'string_textfield', - array('size' => 42), + ['size' => 42], // 'default' formatter type & settings. 'string', - array() + [] ); // Create an entity with values for this text field. @@ -84,7 +84,7 @@ public function testText() { */ public function testTextWysiwyg() { // Enable edit_test module so that the 'wysiwyg' editor becomes available. - $this->enableModules(array('quickedit_test')); + $this->enableModules(['quickedit_test']); $this->editorManager = $this->container->get('plugin.manager.quickedit.editor'); $this->editorSelector = new EditorSelector($this->editorManager, $this->container->get('plugin.manager.field.formatter')); @@ -92,13 +92,13 @@ public function testTextWysiwyg() { $this->createFieldWithStorage( $field_name, 'text', 1, 'Long text field', // Instance settings. - array(), + [], // Widget type & settings. 'text_textarea', - array('size' => 42), + ['size' => 42], // 'default' formatter type & settings. 'text_default', - array() + [] ); // Create an entity with values for this text field. @@ -129,13 +129,13 @@ public function testNumber() { $this->createFieldWithStorage( $field_name, 'integer', 1, 'Simple number field', // Instance settings. - array(), + [], // Widget type & settings. 'number', - array(), + [], // 'default' formatter type & settings. 'number_integer', - array() + [] ); // Create an entity with values for this text field. diff --git a/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php b/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php index 7fdc8fbf..42c4103d 100644 --- a/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php +++ b/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php @@ -5,7 +5,7 @@ use Drupal\entity_test\Entity\EntityTest; use Drupal\quickedit\EditorSelector; use Drupal\quickedit\MetadataGenerator; -use Drupal\quickedit_test\MockEditEntityFieldAccessCheck; +use Drupal\quickedit_test\MockQuickEditEntityFieldAccessCheck; use Drupal\filter\Entity\FilterFormat; /** @@ -18,7 +18,7 @@ class MetadataGeneratorTest extends QuickEditTestBase { /** * {@inheritdoc} */ - public static $modules = array('quickedit_test'); + public static $modules = ['quickedit_test']; /** * The manager for editor plugins. @@ -44,7 +44,7 @@ class MetadataGeneratorTest extends QuickEditTestBase { /** * The access checker object to be used by the metadata generator object. * - * @var \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface + * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface */ protected $accessChecker; @@ -52,7 +52,7 @@ protected function setUp() { parent::setUp(); $this->editorManager = $this->container->get('plugin.manager.quickedit.editor'); - $this->accessChecker = new MockEditEntityFieldAccessCheck(); + $this->accessChecker = new MockQuickEditEntityFieldAccessCheck(); $this->editorSelector = new EditorSelector($this->editorManager, $this->container->get('plugin.manager.field.formatter')); $this->metadataGenerator = new MetadataGenerator($this->accessChecker, $this->editorSelector, $this->editorManager); } @@ -66,26 +66,26 @@ public function testSimpleEntityType() { $this->createFieldWithStorage( $field_1_name, 'string', 1, $field_1_label, // Instance settings. - array(), + [], // Widget type & settings. 'string_textfield', - array('size' => 42), + ['size' => 42], // 'default' formatter type & settings. 'string', - array() + [] ); $field_2_name = 'field_nr'; $field_2_label = 'Simple number field'; $this->createFieldWithStorage( $field_2_name, 'integer', 1, $field_2_label, // Instance settings. - array(), + [], // Widget type & settings. 'number', - array(), + [], // 'default' formatter type & settings. 'number_integer', - array() + [] ); // Create an entity with values for this text field. @@ -98,21 +98,21 @@ public function testSimpleEntityType() { // Verify metadata for field 1. $items_1 = $entity->get($field_1_name); $metadata_1 = $this->metadataGenerator->generateFieldMetadata($items_1, 'default'); - $expected_1 = array( + $expected_1 = [ 'access' => TRUE, 'label' => 'Plain text field', 'editor' => 'plain_text', - ); + ]; $this->assertEqual($expected_1, $metadata_1, 'The correct metadata is generated for the first field.'); // Verify metadata for field 2. $items_2 = $entity->get($field_2_name); $metadata_2 = $this->metadataGenerator->generateFieldMetadata($items_2, 'default'); - $expected_2 = array( + $expected_2 = [ 'access' => TRUE, 'label' => 'Simple number field', 'editor' => 'form', - ); + ]; $this->assertEqual($expected_2, $metadata_2, 'The correct metadata is generated for the second field.'); } @@ -134,24 +134,24 @@ public function testEditorWithCustomMetadata() { $this->createFieldWithStorage( $field_name, 'text', 1, $field_label, // Instance settings. - array(), + [], // Widget type & settings. 'text_textfield', - array('size' => 42), + ['size' => 42], // 'default' formatter type & settings. 'text_default', - array() + [] ); // Create a text format. - $full_html_format = FilterFormat::create(array( + $full_html_format = FilterFormat::create([ 'format' => 'full_html', 'name' => 'Full HTML', 'weight' => 1, - 'filters' => array( - 'filter_htmlcorrector' => array('status' => 1), - ), - )); + 'filters' => [ + 'filter_htmlcorrector' => ['status' => 1], + ], + ]); $full_html_format->save(); // Create an entity with values for this rich text field. @@ -164,15 +164,15 @@ public function testEditorWithCustomMetadata() { // Verify metadata. $items = $entity->get($field_name); $metadata = $this->metadataGenerator->generateFieldMetadata($items, 'default'); - $expected = array( + $expected = [ 'access' => TRUE, 'label' => 'Rich text field', 'editor' => 'wysiwyg', - 'custom' => array( + 'custom' => [ 'format' => 'full_html' - ), - ); - $this->assertEqual($expected, $metadata); //, 'The correct metadata (including custom metadata) is generated.'); + ], + ]; + $this->assertEqual($expected, $metadata, 'The correct metadata (including custom metadata) is generated.'); } } diff --git a/core/modules/quickedit/tests/src/Kernel/QuickEditTestBase.php b/core/modules/quickedit/tests/src/Kernel/QuickEditTestBase.php index bfdb229f..29437485 100644 --- a/core/modules/quickedit/tests/src/Kernel/QuickEditTestBase.php +++ b/core/modules/quickedit/tests/src/Kernel/QuickEditTestBase.php @@ -37,11 +37,11 @@ abstract class QuickEditTestBase extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->fields = new \ArrayObject(array(), \ArrayObject::ARRAY_AS_PROPS); + $this->fields = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); $this->installEntitySchema('user'); $this->installEntitySchema('entity_test'); - $this->installConfig(array('field', 'filter')); + $this->installConfig(['field', 'filter']); } /** @@ -67,12 +67,12 @@ protected function setUp() { */ protected function createFieldWithStorage($field_name, $type, $cardinality, $label, $field_settings, $widget_type, $widget_settings, $formatter_type, $formatter_settings) { $field_storage = $field_name . '_field_storage'; - $this->fields->$field_storage = FieldStorageConfig::create(array( + $this->fields->$field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => $type, 'cardinality' => $cardinality, - )); + ]); $this->fields->$field_storage->save(); $field = $field_name . '_field'; @@ -87,18 +87,18 @@ protected function createFieldWithStorage($field_name, $type, $cardinality, $lab $this->fields->$field->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => $widget_type, 'settings' => $widget_settings, - )) + ]) ->save(); entity_get_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'label' => 'above', 'type' => $formatter_type, 'settings' => $formatter_settings - )) + ]) ->save(); } diff --git a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php deleted file mode 100644 index d7ceb59b..00000000 --- a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php +++ /dev/null @@ -1,149 +0,0 @@ -editAccessCheck = new EditEntityFieldAccessCheck(); - - $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); - $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); - $cache_contexts_manager->reveal(); - $container = new Container(); - $container->set('cache_contexts_manager', $cache_contexts_manager); - \Drupal::setContainer($container); - } - - /** - * Provides test data for testAccess(). - * - * @see \Drupal\Tests\edit\Unit\quickedit\Access\EditEntityFieldAccessCheckTest::testAccess() - */ - public function providerTestAccess() { - $data = array(); - $data[] = array(TRUE, TRUE, AccessResult::allowed()); - $data[] = array(FALSE, TRUE, AccessResult::neutral()); - $data[] = array(TRUE, FALSE, AccessResult::neutral()); - $data[] = array(FALSE, FALSE, AccessResult::neutral()); - - return $data; - } - - /** - * Tests the method for checking access to routes. - * - * @param bool $entity_is_editable - * Whether the subject entity is editable. - * @param bool $field_storage_is_accessible - * Whether the user has access to the field storage entity. - * @param \Drupal\Core\Access\AccessResult $expected_result - * The expected result of the access call. - * - * @dataProvider providerTestAccess - */ - public function testAccess($entity_is_editable, $field_storage_is_accessible, AccessResult $expected_result) { - $entity = $this->createMockEntity(); - $entity->expects($this->any()) - ->method('access') - ->willReturn(AccessResult::allowedIf($entity_is_editable)->cachePerPermissions()); - - $field_storage = $this->getMock('Drupal\field\FieldStorageConfigInterface'); - $field_storage->expects($this->any()) - ->method('access') - ->willReturn(AccessResult::allowedIf($field_storage_is_accessible)); - - $expected_result->cachePerPermissions(); - - $field_name = 'valid'; - $entity_with_field = clone $entity; - $entity_with_field->expects($this->any()) - ->method('get') - ->with($field_name) - ->will($this->returnValue($field_storage)); - $entity_with_field->expects($this->once()) - ->method('hasTranslation') - ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED) - ->will($this->returnValue(TRUE)); - - $account = $this->getMock('Drupal\Core\Session\AccountInterface'); - $access = $this->editAccessCheck->access($entity_with_field, $field_name, LanguageInterface::LANGCODE_NOT_SPECIFIED, $account); - $this->assertEquals($expected_result, $access); - } - - /** - * Tests checking access to routes that result in AccessResult::isForbidden(). - * - * @dataProvider providerTestAccessForbidden - */ - public function testAccessForbidden($field_name, $langcode) { - $account = $this->getMock('Drupal\Core\Session\AccountInterface'); - $entity = $this->createMockEntity(); - $this->assertEquals(AccessResult::forbidden(), $this->editAccessCheck->access($entity, $field_name, $langcode, $account)); - } - - /** - * Provides test data for testAccessForbidden. - */ - public function providerTestAccessForbidden() { - $data = array(); - // Tests the access method without a field_name. - $data[] = array(NULL, LanguageInterface::LANGCODE_NOT_SPECIFIED); - // Tests the access method with a non-existent field. - $data[] = array('not_valid', LanguageInterface::LANGCODE_NOT_SPECIFIED); - // Tests the access method without a langcode. - $data[] = array('valid', NULL); - // Tests the access method with an invalid langcode. - $data[] = array('valid', 'xx-lolspeak'); - return $data; - } - - /** - * Returns a mock entity. - * - * @return \Drupal\Core\Entity\EntityInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected function createMockEntity() { - $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') - ->disableOriginalConstructor() - ->getMock(); - - $entity->expects($this->any()) - ->method('hasTranslation') - ->will($this->returnValueMap(array( - array(LanguageInterface::LANGCODE_NOT_SPECIFIED, TRUE), - array('xx-lolspeak', FALSE), - ))); - $entity->expects($this->any()) - ->method('hasField') - ->will($this->returnValueMap(array( - array('valid', TRUE), - array('not_valid', FALSE), - ))); - - return $entity; - } - -} diff --git a/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php b/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php new file mode 100644 index 00000000..08274369 --- /dev/null +++ b/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php @@ -0,0 +1,149 @@ +editAccessCheck = new QuickEditEntityFieldAccessCheck(); + + $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); + $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); + $cache_contexts_manager->reveal(); + $container = new Container(); + $container->set('cache_contexts_manager', $cache_contexts_manager); + \Drupal::setContainer($container); + } + + /** + * Provides test data for testAccess(). + * + * @see \Drupal\Tests\edit\Unit\quickedit\Access\QuickEditEntityFieldAccessCheckTest::testAccess() + */ + public function providerTestAccess() { + $data = []; + $data[] = [TRUE, TRUE, AccessResult::allowed()]; + $data[] = [FALSE, TRUE, AccessResult::neutral()]; + $data[] = [TRUE, FALSE, AccessResult::neutral()]; + $data[] = [FALSE, FALSE, AccessResult::neutral()]; + + return $data; + } + + /** + * Tests the method for checking access to routes. + * + * @param bool $entity_is_editable + * Whether the subject entity is editable. + * @param bool $field_storage_is_accessible + * Whether the user has access to the field storage entity. + * @param \Drupal\Core\Access\AccessResult $expected_result + * The expected result of the access call. + * + * @dataProvider providerTestAccess + */ + public function testAccess($entity_is_editable, $field_storage_is_accessible, AccessResult $expected_result) { + $entity = $this->createMockEntity(); + $entity->expects($this->any()) + ->method('access') + ->willReturn(AccessResult::allowedIf($entity_is_editable)->cachePerPermissions()); + + $field_storage = $this->getMock('Drupal\field\FieldStorageConfigInterface'); + $field_storage->expects($this->any()) + ->method('access') + ->willReturn(AccessResult::allowedIf($field_storage_is_accessible)); + + $expected_result->cachePerPermissions(); + + $field_name = 'valid'; + $entity_with_field = clone $entity; + $entity_with_field->expects($this->any()) + ->method('get') + ->with($field_name) + ->will($this->returnValue($field_storage)); + $entity_with_field->expects($this->once()) + ->method('hasTranslation') + ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED) + ->will($this->returnValue(TRUE)); + + $account = $this->getMock('Drupal\Core\Session\AccountInterface'); + $access = $this->editAccessCheck->access($entity_with_field, $field_name, LanguageInterface::LANGCODE_NOT_SPECIFIED, $account); + $this->assertEquals($expected_result, $access); + } + + /** + * Tests checking access to routes that result in AccessResult::isForbidden(). + * + * @dataProvider providerTestAccessForbidden + */ + public function testAccessForbidden($field_name, $langcode) { + $account = $this->getMock('Drupal\Core\Session\AccountInterface'); + $entity = $this->createMockEntity(); + $this->assertEquals(AccessResult::forbidden(), $this->editAccessCheck->access($entity, $field_name, $langcode, $account)); + } + + /** + * Provides test data for testAccessForbidden. + */ + public function providerTestAccessForbidden() { + $data = []; + // Tests the access method without a field_name. + $data[] = [NULL, LanguageInterface::LANGCODE_NOT_SPECIFIED]; + // Tests the access method with a non-existent field. + $data[] = ['not_valid', LanguageInterface::LANGCODE_NOT_SPECIFIED]; + // Tests the access method without a langcode. + $data[] = ['valid', NULL]; + // Tests the access method with an invalid langcode. + $data[] = ['valid', 'xx-lolspeak']; + return $data; + } + + /** + * Returns a mock entity. + * + * @return \Drupal\Core\Entity\EntityInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected function createMockEntity() { + $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest') + ->disableOriginalConstructor() + ->getMock(); + + $entity->expects($this->any()) + ->method('hasTranslation') + ->will($this->returnValueMap([ + [LanguageInterface::LANGCODE_NOT_SPECIFIED, TRUE], + ['xx-lolspeak', FALSE], + ])); + $entity->expects($this->any()) + ->method('hasField') + ->will($this->returnValueMap([ + ['valid', TRUE], + ['not_valid', FALSE], + ])); + + return $entity; + } + +} diff --git a/core/modules/rdf/rdf.api.php b/core/modules/rdf/rdf.api.php index 3dbe7d1e..dd7ae222 100644 --- a/core/modules/rdf/rdf.api.php +++ b/core/modules/rdf/rdf.api.php @@ -25,7 +25,7 @@ * @ingroup rdf */ function hook_rdf_namespaces() { - return array( + return [ 'content' => 'http://purl.org/rss/1.0/modules/content/', 'dc' => 'http://purl.org/dc/terms/', 'foaf' => 'http://xmlns.com/foaf/0.1/', @@ -35,7 +35,7 @@ function hook_rdf_namespaces() { 'sioct' => 'http://rdfs.org/sioc/types#', 'skos' => 'http://www.w3.org/2004/02/skos/core#', 'xsd' => 'http://www.w3.org/2001/XMLSchema#', - ); + ]; } /** diff --git a/core/modules/rdf/rdf.info.yml b/core/modules/rdf/rdf.info.yml index 89c832f7..cba9fd75 100644 --- a/core/modules/rdf/rdf.info.yml +++ b/core/modules/rdf/rdf.info.yml @@ -5,8 +5,8 @@ package: Core # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 3108ee12..8d432988 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -17,7 +17,7 @@ function rdf_help($route_name, RouteMatchInterface $route_match) { case 'help.page.rdf': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The RDF module enriches your content with metadata to let other applications (e.g., search engines, aggregators, and so on) better understand its relationships and attributes. This semantically enriched, machine-readable output for your website uses the RDFa specification, which allows RDF data to be embedded in HTML markup. Other modules can define mappings of their data to RDF terms, and the RDF module makes this RDF data available to the theme. The core modules define RDF mappings for their data model, and the core themes output this RDF metadata information along with the human-readable visual information. For more information, see the online documentation for the RDF module.', array(':rdfa' => 'http://www.w3.org/TR/xhtml-rdfa-primer/', ':rdf' => 'https://www.drupal.org/documentation/modules/rdf')) . '

    '; + $output .= '

    ' . t('The RDF module enriches your content with metadata to let other applications (e.g., search engines, aggregators, and so on) better understand its relationships and attributes. This semantically enriched, machine-readable output for your website uses the RDFa specification, which allows RDF data to be embedded in HTML markup. Other modules can define mappings of their data to RDF terms, and the RDF module makes this RDF data available to the theme. The core modules define RDF mappings for their data model, and the core themes output this RDF metadata information along with the human-readable visual information. For more information, see the online documentation for the RDF module.', [':rdfa' => 'http://www.w3.org/TR/xhtml-rdfa-primer/', ':rdf' => 'https://www.drupal.org/documentation/modules/rdf']) . '

    '; return $output; } } @@ -74,10 +74,10 @@ function rdf_get_mapping($entity_type, $bundle) { // If not found, create a fresh mapping object. if (!$mapping) { - $mapping = RdfMapping::create(array( + $mapping = RdfMapping::create([ 'targetEntityType' => $entity_type, 'bundle' => $bundle, - )); + ]); } return $mapping; @@ -87,7 +87,7 @@ function rdf_get_mapping($entity_type, $bundle) { * Implements hook_rdf_namespaces(). */ function rdf_rdf_namespaces() { - return array( + return [ 'content' => 'http://purl.org/rss/1.0/modules/content/', 'dc' => 'http://purl.org/dc/terms/', 'foaf' => 'http://xmlns.com/foaf/0.1/', @@ -98,7 +98,7 @@ function rdf_rdf_namespaces() { 'sioct' => 'http://rdfs.org/sioc/types#', 'skos' => 'http://www.w3.org/2004/02/skos/core#', 'xsd' => 'http://www.w3.org/2001/XMLSchema#', - ); + ]; } /** @@ -108,14 +108,14 @@ function rdf_rdf_namespaces() { * implement it. */ function rdf_get_namespaces() { - $namespaces = array(); + $namespaces = []; // In order to resolve duplicate namespaces by using the earliest defined // namespace, do not use \Drupal::moduleHandler()->invokeAll(). foreach (\Drupal::moduleHandler()->getImplementations('rdf_namespaces') as $module) { $function = $module . '_rdf_namespaces'; foreach ($function() as $prefix => $namespace) { if (array_key_exists($prefix, $namespaces) && $namespace !== $namespaces[$prefix]) { - throw new Exception(t('Tried to map @prefix to @namespace, but @prefix is already mapped to @orig_namespace.', array('@prefix' => $prefix, '@namespace' => $namespace, '@orig_namespace' => $namespaces[$prefix]))); + throw new Exception(t('Tried to map @prefix to @namespace, but @prefix is already mapped to @orig_namespace.', ['@prefix' => $prefix, '@namespace' => $namespace, '@orig_namespace' => $namespaces[$prefix]])); } else { $namespaces[$prefix] = $namespace; @@ -165,7 +165,7 @@ function rdf_get_namespaces() { * RDFa attributes suitable for Drupal\Core\Template\Attribute. */ function rdf_rdfa_attributes($mapping, $data = NULL) { - $attributes = array(); + $attributes = []; // The type of mapping defaults to 'property'. $type = isset($mapping['mapping_type']) ? $mapping['mapping_type'] : 'property'; @@ -249,14 +249,14 @@ function rdf_comment_storage_load($comments) { * Implements hook_theme(). */ function rdf_theme() { - return array( - 'rdf_wrapper' => array( - 'variables' => array('attributes' => array(), 'content' => NULL), - ), - 'rdf_metadata' => array( - 'variables' => array('metadata' => array()), - ), - ); + return [ + 'rdf_wrapper' => [ + 'variables' => ['attributes' => [], 'content' => NULL], + ], + 'rdf_metadata' => [ + 'variables' => ['metadata' => []], + ], + ]; } /** @@ -266,7 +266,7 @@ function rdf_preprocess_html(&$variables) { // Adds RDF namespace prefix bindings in the form of an RDFa 1.1 prefix // attribute inside the html element. if (!isset($variables['html_attributes']['prefix'])) { - $variables['html_attributes']['prefix'] = array(); + $variables['html_attributes']['prefix'] = []; } foreach (rdf_get_namespaces() as $prefix => $uri) { $variables['html_attributes']['prefix'][] = $prefix . ': ' . $uri . " "; @@ -315,21 +315,21 @@ function rdf_preprocess_node(&$variables) { if ($title_mapping) { $title_attributes['property'] = empty($title_mapping['properties']) ? NULL : $title_mapping['properties']; $title_attributes['content'] = $variables['node']->label(); - $variables['title_suffix']['rdf_meta_title'] = array( + $variables['title_suffix']['rdf_meta_title'] = [ '#theme' => 'rdf_metadata', - '#metadata' => array($title_attributes), - ); + '#metadata' => [$title_attributes], + ]; } // Adds RDFa markup for the date. $created_mapping = $mapping->getPreparedFieldMapping('created'); if (!empty($created_mapping) && $variables['display_submitted']) { $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->get('created')->first()->toArray()); - $rdf_metadata = array( + $rdf_metadata = [ '#theme' => 'rdf_metadata', - '#metadata' => array($date_attributes), - ); - $variables['metadata'] = drupal_render($rdf_metadata); + '#metadata' => [$date_attributes], + ]; + $variables['metadata'] = \Drupal::service('renderer')->render($rdf_metadata); } // Adds RDFa markup annotating the number of comments a node has. @@ -345,10 +345,10 @@ function rdf_preprocess_node(&$variables) { // Adds RDFa markup for the comment count near the node title as // metadata. $comment_count_attributes = rdf_rdfa_attributes($comment_count_mapping, $variables['node']->get($field_name)->comment_count); - $variables['title_suffix']['rdf_meta_comment_count'] = array( + $variables['title_suffix']['rdf_meta_comment_count'] = [ '#theme' => 'rdf_metadata', - '#metadata' => array($comment_count_attributes), - ); + '#metadata' => [$comment_count_attributes], + ]; } } } @@ -377,15 +377,15 @@ function rdf_preprocess_user(&$variables) { // rdf_preprocess_username(). $name_mapping = $mapping->getPreparedFieldMapping('name'); if (!empty($name_mapping['properties'])) { - $username_meta = array( + $username_meta = [ '#tag' => 'meta', - '#attributes' => array( + '#attributes' => [ 'about' => $account->url(), 'property' => $name_mapping['properties'], 'content' => $account->getDisplayName(), 'lang' => '', - ), - ); + ], + ]; $variables['#attached']['html_head'][] = [$username_meta, 'rdf_user_username']; } } @@ -482,10 +482,10 @@ function rdf_preprocess_comment(&$variables) { // cached as part of the entity. $date_attributes = $comment->rdf_data['date']; - $rdf_metadata = array( + $rdf_metadata = [ '#theme' => 'rdf_metadata', - '#metadata' => array($date_attributes), - ); + '#metadata' => [$date_attributes], + ]; // Ensure the original variable is represented as a render array. $created = !is_array($variables['created']) ? ['#markup' => $variables['created']] : $variables['created']; $submitted = !is_array($variables['submitted']) ? ['#markup' => $variables['submitted']] : $variables['submitted']; @@ -527,14 +527,14 @@ function rdf_preprocess_comment(&$variables) { } // Adds RDF metadata markup above comment body if any. if (!empty($variables['rdf_metadata_attributes']) && isset($variables['content']['comment_body'])) { - $rdf_metadata = array( + $rdf_metadata = [ '#theme' => 'rdf_metadata', '#metadata' => $variables['rdf_metadata_attributes'], - ); + ]; if (!empty($variables['content']['comment_body']['#prefix'])) { $rdf_metadata['#suffix'] = $variables['content']['comment_body']['#prefix']; } - $variables['content']['comment_body']['#prefix'] = drupal_render($rdf_metadata); + $variables['content']['comment_body']['#prefix'] = \Drupal::service('renderer')->render($rdf_metadata); } } @@ -555,14 +555,14 @@ function rdf_preprocess_taxonomy_term(&$variables) { // Add RDFa markup for the taxonomy term name as metadata, if present. $name_field_mapping = $mapping->getPreparedFieldMapping('name'); if (!empty($name_field_mapping) && !empty($name_field_mapping['properties'])) { - $name_attributes = array( + $name_attributes = [ 'property' => $name_field_mapping['properties'], 'content' => $term->getName(), - ); - $variables['title_suffix']['taxonomy_term_rdfa'] = array( + ]; + $variables['title_suffix']['taxonomy_term_rdfa'] = [ '#theme' => 'rdf_metadata', - '#metadata' => array($name_attributes), - ); + '#metadata' => [$name_attributes], + ]; } } @@ -573,7 +573,7 @@ function rdf_preprocess_image(&$variables) { // Adds the RDF type for image. We cannot use the usual entity-based mapping // to get 'foaf:Image' because image does not have its own entity type or // bundle. - $variables['attributes']['typeof'] = array('foaf:Image'); + $variables['attributes']['typeof'] = ['foaf:Image']; } /** diff --git a/core/modules/rdf/src/Entity/RdfMapping.php b/core/modules/rdf/src/Entity/RdfMapping.php index 6ac95abd..a4f268f8 100644 --- a/core/modules/rdf/src/Entity/RdfMapping.php +++ b/core/modules/rdf/src/Entity/RdfMapping.php @@ -12,10 +12,17 @@ * @ConfigEntityType( * id = "rdf_mapping", * label = @Translation("RDF mapping"), + * label_singular = @Translation("RDF mapping item"), + * label_plural = @Translation("RDF mappings items"), + * label_count = @PluralTranslation( + * singular = "@count RDF mapping item", + * plural = "@count RDF mapping items", + * ), * config_prefix = "mapping", * entity_keys = { * "id" = "id" * }, + * admin_permission = "administer site configuration", * config_export = { * "id", * "targetEntityType", @@ -53,20 +60,20 @@ class RdfMapping extends ConfigEntityBase implements RdfMappingInterface { * * @var array */ - protected $types = array(); + protected $types = []; /** * The mappings for fields on this bundle. * * @var array */ - protected $fieldMappings = array(); + protected $fieldMappings = []; /** * {@inheritdoc} */ public function getPreparedBundleMapping() { - return array('types' => $this->types); + return ['types' => $this->types]; } /** @@ -74,9 +81,9 @@ public function getPreparedBundleMapping() { */ public function getBundleMapping() { if (!empty($this->types)) { - return array('types' => $this->types); + return ['types' => $this->types]; } - return array(); + return []; } /** @@ -94,16 +101,16 @@ public function setBundleMapping(array $mapping) { * {@inheritdoc} */ public function getPreparedFieldMapping($field_name) { - $field_mapping = array( + $field_mapping = [ 'properties' => NULL, 'datatype' => NULL, 'datatype_callback' => NULL, 'mapping_type' => NULL, - ); + ]; if (isset($this->fieldMappings[$field_name])) { $field_mapping = array_merge($field_mapping, $this->fieldMappings[$field_name]); } - return empty($field_mapping['properties']) ? array() : $field_mapping; + return empty($field_mapping['properties']) ? [] : $field_mapping; } /** @@ -113,13 +120,13 @@ public function getFieldMapping($field_name) { if (isset($this->fieldMappings[$field_name])) { return $this->fieldMappings[$field_name]; } - return array(); + return []; } /** * {@inheritdoc} */ - public function setFieldMapping($field_name, array $mapping = array()) { + public function setFieldMapping($field_name, array $mapping = []) { $this->fieldMappings[$field_name] = $mapping; return $this; } diff --git a/core/modules/rdf/src/RdfMappingInterface.php b/core/modules/rdf/src/RdfMappingInterface.php index fa8def26..ce012884 100644 --- a/core/modules/rdf/src/RdfMappingInterface.php +++ b/core/modules/rdf/src/RdfMappingInterface.php @@ -102,6 +102,6 @@ public function getFieldMapping($field_name); * @return \Drupal\rdf\Entity\RdfMapping * The RdfMapping object. */ - public function setFieldMapping($field_name, array $mapping = array()); + public function setFieldMapping($field_name, array $mapping = []); } diff --git a/core/modules/rdf/src/SchemaOrgDataConverter.php b/core/modules/rdf/src/SchemaOrgDataConverter.php index dc040484..d20a4261 100644 --- a/core/modules/rdf/src/SchemaOrgDataConverter.php +++ b/core/modules/rdf/src/SchemaOrgDataConverter.php @@ -22,7 +22,7 @@ class SchemaOrgDataConverter { * * @see http://schema.org/UserInteraction */ - static function interactionCount($count, $arguments) { + public static function interactionCount($count, $arguments) { $interaction_type = $arguments['interaction_type']; return "$interaction_type:$count"; } diff --git a/core/modules/rdf/src/Tests/CommentAttributesTest.php b/core/modules/rdf/src/Tests/CommentAttributesTest.php index 5febcb98..8ca5798c 100644 --- a/core/modules/rdf/src/Tests/CommentAttributesTest.php +++ b/core/modules/rdf/src/Tests/CommentAttributesTest.php @@ -20,7 +20,7 @@ class CommentAttributesTest extends CommentTestBase { * * @var array */ - public static $modules = array('views', 'node', 'comment', 'rdf'); + public static $modules = ['views', 'node', 'comment', 'rdf']; /** * URI of the front page of the Drupal site. @@ -40,11 +40,11 @@ protected function setUp() { parent::setUp(); // Enables anonymous user comments. - user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array( + user_role_change_permissions(RoleInterface::ANONYMOUS_ID, [ 'access comments' => TRUE, 'post comments' => TRUE, 'skip comment approval' => TRUE, - )); + ]); // Allows anonymous to leave their contact information. $this->setCommentAnonymous(COMMENT_ANONYMOUS_MAY_CONTACT); $this->setCommentPreview(DRUPAL_OPTIONAL); @@ -58,53 +58,53 @@ protected function setUp() { // Set relation between node and comment. $article_mapping = rdf_get_mapping('node', 'article'); - $comment_count_mapping = array( - 'properties' => array('sioc:num_replies'), + $comment_count_mapping = [ + 'properties' => ['sioc:num_replies'], 'datatype' => 'xsd:integer', - 'datatype_callback' => array('callable' => 'Drupal\rdf\CommonDataConverter::rawValue'), - ); + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::rawValue'], + ]; $article_mapping->setFieldMapping('comment_count', $comment_count_mapping)->save(); // Save user mapping. $user_mapping = rdf_get_mapping('user', 'user'); - $username_mapping = array( - 'properties' => array('foaf:name'), - ); + $username_mapping = [ + 'properties' => ['foaf:name'], + ]; $user_mapping->setFieldMapping('name', $username_mapping)->save(); - $user_mapping->setFieldMapping('homepage', array('properties' => array('foaf:page'), 'mapping_type' => 'rel'))->save(); + $user_mapping->setFieldMapping('homepage', ['properties' => ['foaf:page'], 'mapping_type' => 'rel'])->save(); // Save comment mapping. $mapping = rdf_get_mapping('comment', 'comment'); - $mapping->setBundleMapping(array('types' => array('sioc:Post', 'sioct:Comment')))->save(); - $field_mappings = array( - 'subject' => array( - 'properties' => array('dc:title'), - ), - 'created' => array( - 'properties' => array('dc:date', 'dc:created'), + $mapping->setBundleMapping(['types' => ['sioc:Post', 'sioct:Comment']])->save(); + $field_mappings = [ + 'subject' => [ + 'properties' => ['dc:title'], + ], + 'created' => [ + 'properties' => ['dc:date', 'dc:created'], 'datatype' => 'xsd:dateTime', - 'datatype_callback' => array('callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'), - ), - 'changed' => array( - 'properties' => array('dc:modified'), + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'], + ], + 'changed' => [ + 'properties' => ['dc:modified'], 'datatype' => 'xsd:dateTime', - 'datatype_callback' => array('callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'), - ), - 'comment_body' => array( - 'properties' => array('content:encoded'), - ), - 'pid' => array( - 'properties' => array('sioc:reply_of'), + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'], + ], + 'comment_body' => [ + 'properties' => ['content:encoded'], + ], + 'pid' => [ + 'properties' => ['sioc:reply_of'], 'mapping_type' => 'rel', - ), - 'uid' => array( - 'properties' => array('sioc:has_creator'), + ], + 'uid' => [ + 'properties' => ['sioc:has_creator'], 'mapping_type' => 'rel', - ), - 'name' => array( - 'properties' => array('foaf:name'), - ), - ); + ], + 'name' => [ + 'properties' => ['foaf:name'], + ], + ]; // Iterate over shared field mappings and save. foreach ($field_mappings as $field_name => $field_mapping) { $mapping->setFieldMapping($field_name, $field_mapping)->save(); @@ -126,11 +126,11 @@ public function testNumberOfCommentsRdfaMarkup() { $parser->parse($graph, $this->drupalGet('node'), 'rdfa', $this->baseUri); // Number of comments. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => 2, 'datatype' => 'http://www.w3.org/2001/XMLSchema#integer', - ); + ]; $this->assertTrue($graph->hasProperty($this->nodeUri, 'http://rdfs.org/sioc/ns#num_replies', $expected_value), 'Number of comments found in RDF output of teaser view (sioc:num_replies).'); // Tests number of comments in full node view, expected value is the same. @@ -183,7 +183,7 @@ public function testCommentRdfaMarkup() { $this->_testBasicCommentRdfaMarkup($graph, $comment1); // Posts comment #2 as anonymous user. - $anonymous_user = array(); + $anonymous_user = []; $anonymous_user['name'] = $this->randomMachineName(); $anonymous_user['mail'] = 'tester@simpletest.org'; $anonymous_user['homepage'] = 'http://example.org/'; @@ -222,22 +222,22 @@ public function testCommentReplyOfRdfaMarkup() { $parser->parse($graph, $this->drupalGet('node/' . $this->node->id()), 'rdfa', $this->baseUri); // Tests the reply_of relationship of a first level comment. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->nodeUri, - ); + ]; $this->assertTrue($graph->hasProperty($comment_1_uri, 'http://rdfs.org/sioc/ns#reply_of', $expected_value), 'Comment relation to its node found in RDF output (sioc:reply_of).'); // Tests the reply_of relationship of a second level comment. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->nodeUri, - ); + ]; $this->assertTrue($graph->hasProperty($comment_2_uri, 'http://rdfs.org/sioc/ns#reply_of', $expected_value), 'Comment relation to its node found in RDF output (sioc:reply_of).'); - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $comment_1_uri, - ); + ]; $this->assertTrue($graph->hasProperty($comment_2_uri, 'http://rdfs.org/sioc/ns#reply_of', $expected_value), 'Comment relation to its parent comment found in RDF output (sioc:reply_of).'); } @@ -251,61 +251,61 @@ public function testCommentReplyOfRdfaMarkup() { * @param $account * An array containing information about an anonymous user. */ - function _testBasicCommentRdfaMarkup($graph, CommentInterface $comment, $account = array()) { - $comment_uri = $comment->url('canonical', array('absolute' => TRUE)); + public function _testBasicCommentRdfaMarkup($graph, CommentInterface $comment, $account = []) { + $comment_uri = $comment->url('canonical', ['absolute' => TRUE]); // Comment type. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://rdfs.org/sioc/types#Comment', - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Comment type found in RDF output (sioct:Comment).'); // Comment type. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://rdfs.org/sioc/ns#Post', - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Comment type found in RDF output (sioc:Post).'); // Comment title. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $comment->getSubject(), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://purl.org/dc/terms/title', $expected_value), 'Comment subject found in RDF output (dc:title).'); // Comment date. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => format_date($comment->getCreatedTime(), 'custom', 'c', 'UTC'), 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime', - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://purl.org/dc/terms/date', $expected_value), 'Comment date found in RDF output (dc:date).'); // Comment date. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => format_date($comment->getCreatedTime(), 'custom', 'c', 'UTC'), 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime', - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://purl.org/dc/terms/created', $expected_value), 'Comment date found in RDF output (dc:created).'); // Comment body. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $comment->comment_body->value . "\n", 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://purl.org/rss/1.0/modules/content/encoded', $expected_value), 'Comment body found in RDF output (content:encoded).'); // The comment author can be a registered user or an anonymous user. if ($comment->getOwnerId() > 0) { - $author_uri = \Drupal::url('entity.user.canonical', ['user' => $comment->getOwnerId()], array('absolute' => TRUE)); + $author_uri = \Drupal::url('entity.user.canonical', ['user' => $comment->getOwnerId()], ['absolute' => TRUE]); // Comment relation to author. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $author_uri, - ); + ]; $this->assertTrue($graph->hasProperty($comment_uri, 'http://rdfs.org/sioc/ns#has_creator', $expected_value), 'Comment relation to author found in RDF output (sioc:has_creator).'); } else { @@ -321,18 +321,18 @@ function _testBasicCommentRdfaMarkup($graph, CommentInterface $comment, $account // Author name. $name = empty($account["name"]) ? $this->webUser->getUsername() : $account["name"] . " (not verified)"; - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $name, - ); + ]; $this->assertTrue($graph->hasProperty($author_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'Comment author name found in RDF output (foaf:name).'); // Comment author homepage (only for anonymous authors). if ($comment->getOwnerId() == 0) { - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://example.org/', - ); + ]; $this->assertTrue($graph->hasProperty($author_uri, 'http://xmlns.com/foaf/0.1/page', $expected_value), 'Comment author link found in RDF output (foaf:page).'); } } @@ -353,8 +353,8 @@ function _testBasicCommentRdfaMarkup($graph, CommentInterface $comment, $account * @return \Drupal\comment\Entity\Comment * The saved comment. */ - function saveComment($nid, $uid, $contact = NULL, $pid = 0) { - $values = array( + public function saveComment($nid, $uid, $contact = NULL, $pid = 0) { + $values = [ 'entity_id' => $nid, 'entity_type' => 'node', 'field_name' => 'comment', @@ -363,7 +363,7 @@ function saveComment($nid, $uid, $contact = NULL, $pid = 0) { 'subject' => $this->randomMachineName(), 'comment_body' => $this->randomMachineName(), 'status' => 1, - ); + ]; if ($contact) { $values += $contact; } diff --git a/core/modules/rdf/src/Tests/EntityReferenceFieldAttributesTest.php b/core/modules/rdf/src/Tests/EntityReferenceFieldAttributesTest.php deleted file mode 100644 index 48653a5f..00000000 --- a/core/modules/rdf/src/Tests/EntityReferenceFieldAttributesTest.php +++ /dev/null @@ -1,147 +0,0 @@ -drupalCreateUser(array('bypass node access', 'administer taxonomy')); - $this->drupalLogin($web_user); - $this->vocabulary = $this->createVocabulary(); - - // Create the field. - $this->fieldName = 'field_taxonomy_test'; - $handler_settings = array( - 'target_bundles' => array( - $this->vocabulary->id() => $this->vocabulary->id(), - ), - 'auto_create' => TRUE, - ); - $this->createEntityReferenceField('node', 'article', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - - entity_get_form_display('node', 'article', 'default') - ->setComponent($this->fieldName, array('type' => 'options_select')) - ->save(); - entity_get_display('node', 'article', 'full') - ->setComponent($this->fieldName, array('type' => 'entity_reference_label')) - ->save(); - - // Set the RDF mapping for the new field. - rdf_get_mapping('node', 'article') - ->setFieldMapping($this->fieldName, array( - 'properties' => array('dc:subject'), - 'mapping_type' => 'rel', - )) - ->save(); - - rdf_get_mapping('taxonomy_term', $this->vocabulary->id()) - ->setBundleMapping(array('types' => array('skos:Concept'))) - ->setFieldMapping('name', array('properties' => array('rdfs:label'))) - ->save(); - } - - /** - * Tests if file fields in teasers have correct resources. - * - * Ensure that file fields have the correct resource as the object in RDFa - * when displayed as a teaser. - */ - function testNodeTeaser() { - // Set the teaser display to show this field. - entity_get_display('node', 'article', 'teaser') - ->setComponent($this->fieldName, array('type' => 'entity_reference_label')) - ->save(); - - // Create a term in each vocabulary. - $term1 = $this->createTerm($this->vocabulary); - $term2 = $this->createTerm($this->vocabulary); - $taxonomy_term_1_uri = $term1->url('canonical', ['absolute' => TRUE]); - $taxonomy_term_2_uri = $term2->url('canonical', ['absolute' => TRUE]); - - // Create the node. - $node = $this->drupalCreateNode(array('type' => 'article')); - $node->set($this->fieldName, array( - array('target_id' => $term1->id()), - array('target_id' => $term2->id()), - )); - - // Render the node. - $node_render_array = entity_view_multiple(array($node), 'teaser'); - $html = \Drupal::service('renderer')->renderRoot($node_render_array); - - // Parse the teaser. - $parser = new \EasyRdf_Parser_Rdfa(); - $graph = new \EasyRdf_Graph(); - $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); - $parser->parse($graph, $html, 'rdfa', $base_uri); - - // Node relations to taxonomy terms. - $node_uri = $node->url('canonical', ['absolute' => TRUE]); - $expected_value = array( - 'type' => 'uri', - 'value' => $taxonomy_term_1_uri, - ); - $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/subject', $expected_value), 'Node to term relation found in RDF output (dc:subject).'); - $expected_value = array( - 'type' => 'uri', - 'value' => $taxonomy_term_2_uri, - ); - $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/subject', $expected_value), 'Node to term relation found in RDF output (dc:subject).'); - // Taxonomy terms triples. - // Term 1. - $expected_value = array( - 'type' => 'uri', - 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', - ); - // @todo Enable with https://www.drupal.org/node/2072791. - //$this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Taxonomy term type found in RDF output (skos:Concept).'); - $expected_value = array( - 'type' => 'literal', - 'value' => $term1->getName(), - ); - //$this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); - // Term 2. - $expected_value = array( - 'type' => 'uri', - 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', - ); - //$this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Taxonomy term type found in RDF output (skos:Concept).'); - $expected_value = array( - 'type' => 'literal', - 'value' => $term2->getName(), - ); - //$this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); - } - -} diff --git a/core/modules/rdf/src/Tests/Field/TestDataConverter.php b/core/modules/rdf/src/Tests/Field/TestDataConverter.php index e314f67c..fd30b278 100644 --- a/core/modules/rdf/src/Tests/Field/TestDataConverter.php +++ b/core/modules/rdf/src/Tests/Field/TestDataConverter.php @@ -16,7 +16,7 @@ class TestDataConverter { * @return string * Returns the data. */ - static function convertFoo($data) { + public static function convertFoo($data) { return 'foo' . $data['value']; } diff --git a/core/modules/rdf/src/Tests/GetNamespacesTest.php b/core/modules/rdf/src/Tests/GetNamespacesTest.php index 8aeaf799..ca46c5cd 100644 --- a/core/modules/rdf/src/Tests/GetNamespacesTest.php +++ b/core/modules/rdf/src/Tests/GetNamespacesTest.php @@ -17,33 +17,33 @@ class GetNamespacesTest extends WebTestBase { * * @var array */ - public static $modules = array('rdf', 'rdf_test_namespaces'); + public static $modules = ['rdf', 'rdf_test_namespaces']; /** * Tests RDF namespaces. */ - function testGetRdfNamespaces() { + public function testGetRdfNamespaces() { // Fetches the front page and extracts RDFa 1.1 prefixes. $this->drupalGet(''); - $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', array( + $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', [ ':prefix_binding' => 'rdfs: http://www.w3.org/2000/01/rdf-schema#', - )); + ]); $this->assertTrue(!empty($element), 'A prefix declared once is displayed.'); - $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', array( + $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', [ ':prefix_binding' => 'foaf: http://xmlns.com/foaf/0.1/', - )); + ]); $this->assertTrue(!empty($element), 'The same prefix declared in several implementations of hook_rdf_namespaces() is valid as long as all the namespaces are the same.'); - $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', array( + $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', [ ':prefix_binding' => 'foaf1: http://xmlns.com/foaf/0.1/', - )); + ]); $this->assertTrue(!empty($element), 'Two prefixes can be assigned the same namespace.'); - $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', array( + $element = $this->xpath('//html[contains(@prefix, :prefix_binding)]', [ ':prefix_binding' => 'dc: http://purl.org/dc/terms/', - )); + ]); $this->assertTrue(!empty($element), 'When a prefix has conflicting namespaces, the first declared one is used.'); } diff --git a/core/modules/rdf/src/Tests/ImageFieldAttributesTest.php b/core/modules/rdf/src/Tests/ImageFieldAttributesTest.php index cce663ba..d4d7d359 100644 --- a/core/modules/rdf/src/Tests/ImageFieldAttributesTest.php +++ b/core/modules/rdf/src/Tests/ImageFieldAttributesTest.php @@ -19,7 +19,7 @@ class ImageFieldAttributesTest extends ImageFieldTestBase { * * @var array */ - public static $modules = array('rdf', 'image'); + public static $modules = ['rdf', 'image']; /** * The name of the image field used in the test. @@ -52,11 +52,11 @@ protected function setUp() { // Set the RDF mapping for the new field. rdf_get_mapping('node', 'article') - ->setFieldMapping($this->fieldName, array( - 'properties' => array('og:image'), + ->setFieldMapping($this->fieldName, [ + 'properties' => ['og:image'], 'mapping_type' => 'rel', - )) - ->setBundleMapping(array('types' => array())) + ]) + ->setBundleMapping(['types' => []]) ->save(); // Get the test image that simpletest provides. @@ -71,12 +71,12 @@ protected function setUp() { /** * Tests that image fields in teasers have correct resources. */ - function testNodeTeaser() { + public function testNodeTeaser() { // Set the display options for the teaser. - $display_options = array( + $display_options = [ 'type' => 'image', - 'settings' => array('image_style' => 'medium', 'image_link' => 'content'), - ); + 'settings' => ['image_style' => 'medium', 'image_link' => 'content'], + ]; $display = entity_get_display('node', 'article', 'teaser'); $display->setComponent($this->fieldName, $display_options) ->save(); @@ -96,17 +96,17 @@ function testNodeTeaser() { $image_uri = ImageStyle::load('medium')->buildUrl($this->file->getFileUri()); // Test relations from node to image. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $image_uri, - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://ogp.me/ns#image', $expected_value), 'Node to file relation found in RDF output (og:image).'); // Test image type. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://xmlns.com/foaf/0.1/Image', - ); + ]; $this->assertTrue($graph->hasProperty($image_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Image type found in RDF output (foaf:Image).'); } diff --git a/core/modules/rdf/src/Tests/UserAttributesTest.php b/core/modules/rdf/src/Tests/UserAttributesTest.php deleted file mode 100644 index 232b5b2e..00000000 --- a/core/modules/rdf/src/Tests/UserAttributesTest.php +++ /dev/null @@ -1,108 +0,0 @@ -setBundleMapping(array( - 'types' => array('sioc:UserAccount'), - )) - ->setFieldMapping('name', array( - 'properties' => array('foaf:name'), - )) - ->save(); - } - - /** - * Tests if default mapping for user is being used. - * - * Creates a random user and ensures the default mapping for the user is - * being used. - */ - function testUserAttributesInMarkup() { - // Creates users that should and should not be truncated - // by template_preprocess_username (20 characters) - // one of these users tests right on the cusp (20). - $user1 = $this->drupalCreateUser(array('access user profiles')); - - $authors = array( - $this->drupalCreateUser(array(), $this->randomMachineName(30)), - $this->drupalCreateUser(array(), $this->randomMachineName(20)), - $this->drupalCreateUser(array(), $this->randomMachineName(5)) - ); - - $this->drupalLogin($user1); - - $this->drupalCreateContentType(array('type' => 'article')); - - /** @var \Drupal\user\UserInterface[] $authors */ - foreach ($authors as $author) { - $account_uri = $author->url('canonical', ['absolute' => TRUE]); - - // Parses the user profile page where the default bundle mapping for user - // should be used. - $parser = new \EasyRdf_Parser_Rdfa(); - $graph = new \EasyRdf_Graph(); - $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); - $parser->parse($graph, $this->drupalGet('user/' . $author->id()), 'rdfa', $base_uri); - - // Inspects RDF graph output. - // User type. - $expected_value = array( - 'type' => 'uri', - 'value' => 'http://rdfs.org/sioc/ns#UserAccount', - ); - $this->assertTrue($graph->hasProperty($account_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'User type found in RDF output (sioc:UserAccount).'); - // User name. - $expected_value = array( - 'type' => 'literal', - 'value' => $author->getUsername(), - ); - $this->assertTrue($graph->hasProperty($account_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'User name found in RDF output (foaf:name).'); - - // User creates a node. - $this->drupalLogin($author); - $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); - $this->drupalLogin($user1); - - // Parses the node created by the user. - $parser = new \EasyRdf_Parser_Rdfa(); - $graph = new \EasyRdf_Graph(); - $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); - $parser->parse($graph, $this->drupalGet('node/' . $node->id()), 'rdfa', $base_uri); - - // Ensures the default bundle mapping for user is used on the Authored By - // information on the node. - $expected_value = array( - 'type' => 'uri', - 'value' => 'http://rdfs.org/sioc/ns#UserAccount', - ); - $this->assertTrue($graph->hasProperty($account_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'User type found in RDF output (sioc:UserAccount).'); - // User name. - $expected_value = array( - 'type' => 'literal', - 'value' => $author->getUsername(), - ); - $this->assertTrue($graph->hasProperty($account_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'User name found in RDF output (foaf:name).'); - - } - } - -} diff --git a/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.info.yml b/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.info.yml index 20ccb3c6..a1cd4790 100644 --- a/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.info.yml +++ b/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - rdf -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.module b/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.module index 2fbdba4a..ddaf5cbe 100644 --- a/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.module +++ b/core/modules/rdf/tests/rdf_conflicting_namespaces/rdf_conflicting_namespaces.module @@ -9,7 +9,7 @@ * Implements hook_rdf_namespaces(). */ function rdf_conflicting_namespaces_rdf_namespaces() { - return array( + return [ 'dc' => 'http://purl.org/conflicting/namespace', - ); + ]; } diff --git a/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info.yml b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info.yml index 295bd3a9..0d6bc567 100644 --- a/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info.yml +++ b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - rdf -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module index d44c5197..327bd5bc 100644 --- a/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module +++ b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module @@ -9,8 +9,8 @@ * Implements hook_rdf_namespaces(). */ function rdf_test_namespaces_rdf_namespaces() { - return array( + return [ 'foaf' => 'http://xmlns.com/foaf/0.1/', 'foaf1' => 'http://xmlns.com/foaf/0.1/', - ); + ]; } diff --git a/core/modules/rdf/tests/src/Functional/EntityReferenceFieldAttributesTest.php b/core/modules/rdf/tests/src/Functional/EntityReferenceFieldAttributesTest.php new file mode 100644 index 00000000..b91215db --- /dev/null +++ b/core/modules/rdf/tests/src/Functional/EntityReferenceFieldAttributesTest.php @@ -0,0 +1,147 @@ +drupalCreateUser(['bypass node access', 'administer taxonomy']); + $this->drupalLogin($web_user); + $this->vocabulary = $this->createVocabulary(); + + // Create the field. + $this->fieldName = 'field_taxonomy_test'; + $handler_settings = [ + 'target_bundles' => [ + $this->vocabulary->id() => $this->vocabulary->id(), + ], + 'auto_create' => TRUE, + ]; + $this->createEntityReferenceField('node', 'article', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + + entity_get_form_display('node', 'article', 'default') + ->setComponent($this->fieldName, ['type' => 'options_select']) + ->save(); + entity_get_display('node', 'article', 'full') + ->setComponent($this->fieldName, ['type' => 'entity_reference_label']) + ->save(); + + // Set the RDF mapping for the new field. + rdf_get_mapping('node', 'article') + ->setFieldMapping($this->fieldName, [ + 'properties' => ['dc:subject'], + 'mapping_type' => 'rel', + ]) + ->save(); + + rdf_get_mapping('taxonomy_term', $this->vocabulary->id()) + ->setBundleMapping(['types' => ['skos:Concept']]) + ->setFieldMapping('name', ['properties' => ['rdfs:label']]) + ->save(); + } + + /** + * Tests if file fields in teasers have correct resources. + * + * Ensure that file fields have the correct resource as the object in RDFa + * when displayed as a teaser. + */ + public function testNodeTeaser() { + // Set the teaser display to show this field. + entity_get_display('node', 'article', 'teaser') + ->setComponent($this->fieldName, ['type' => 'entity_reference_label']) + ->save(); + + // Create a term in each vocabulary. + $term1 = $this->createTerm($this->vocabulary); + $term2 = $this->createTerm($this->vocabulary); + $taxonomy_term_1_uri = $term1->url('canonical', ['absolute' => TRUE]); + $taxonomy_term_2_uri = $term2->url('canonical', ['absolute' => TRUE]); + + // Create the node. + $node = $this->drupalCreateNode(['type' => 'article']); + $node->set($this->fieldName, [ + ['target_id' => $term1->id()], + ['target_id' => $term2->id()], + ]); + + // Render the node. + $node_render_array = entity_view_multiple([$node], 'teaser'); + $html = \Drupal::service('renderer')->renderRoot($node_render_array); + + // Parse the teaser. + $parser = new \EasyRdf_Parser_Rdfa(); + $graph = new \EasyRdf_Graph(); + $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); + $parser->parse($graph, $html, 'rdfa', $base_uri); + + // Node relations to taxonomy terms. + $node_uri = $node->url('canonical', ['absolute' => TRUE]); + $expected_value = [ + 'type' => 'uri', + 'value' => $taxonomy_term_1_uri, + ]; + $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/subject', $expected_value), 'Node to term relation found in RDF output (dc:subject).'); + $expected_value = [ + 'type' => 'uri', + 'value' => $taxonomy_term_2_uri, + ]; + $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/subject', $expected_value), 'Node to term relation found in RDF output (dc:subject).'); + // Taxonomy terms triples. + // Term 1. + $expected_value = [ + 'type' => 'uri', + 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', + ]; + // @todo Enable with https://www.drupal.org/node/2072791. + // $this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Taxonomy term type found in RDF output (skos:Concept).'); + $expected_value = [ + 'type' => 'literal', + 'value' => $term1->getName(), + ]; + // $this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); + // Term 2. + $expected_value = [ + 'type' => 'uri', + 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', + ]; + // $this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Taxonomy term type found in RDF output (skos:Concept).'); + $expected_value = [ + 'type' => 'literal', + 'value' => $term2->getName(), + ]; + // $this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); + } + +} diff --git a/core/modules/rdf/src/Tests/FileFieldAttributesTest.php b/core/modules/rdf/tests/src/Functional/FileFieldAttributesTest.php similarity index 83% rename from core/modules/rdf/src/Tests/FileFieldAttributesTest.php rename to core/modules/rdf/tests/src/Functional/FileFieldAttributesTest.php index 34e76ae3..ad743580 100644 --- a/core/modules/rdf/src/Tests/FileFieldAttributesTest.php +++ b/core/modules/rdf/tests/src/Functional/FileFieldAttributesTest.php @@ -1,6 +1,6 @@ setComponent($this->fieldName, array('type' => 'file_default')) + ->setComponent($this->fieldName, ['type' => 'file_default']) ->save(); // Set the RDF mapping for the new field. $mapping = rdf_get_mapping('node', 'article'); - $mapping->setFieldMapping($this->fieldName, array('properties' => array('rdfs:seeAlso'), 'mapping_type' => 'rel'))->save(); + $mapping->setFieldMapping($this->fieldName, ['properties' => ['rdfs:seeAlso'], 'mapping_type' => 'rel'])->save(); $test_file = $this->getTestFile('text'); // Create a new node with the uploaded file. $nid = $this->uploadNodeFile($test_file, $this->fieldName, $type_name); - $node_storage->resetCache(array($nid)); + $node_storage->resetCache([$nid]); $this->node = $node_storage->load($nid); $this->file = File::load($this->node->{$this->fieldName}->target_id); } @@ -73,9 +73,9 @@ protected function setUp() { * Ensure that file fields have the correct resource as the object in RDFa * when displayed as a teaser. */ - function testNodeTeaser() { + public function testNodeTeaser() { // Render the teaser. - $node_render_array = entity_view_multiple(array($this->node), 'teaser'); + $node_render_array = entity_view_multiple([$this->node], 'teaser'); $html = \Drupal::service('renderer')->renderRoot($node_render_array); // Parses front page where the node is displayed in its teaser form. @@ -88,10 +88,10 @@ function testNodeTeaser() { $file_uri = file_create_url($this->file->getFileUri()); // Node relation to attached file. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $file_uri, - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://www.w3.org/2000/01/rdf-schema#seeAlso', $expected_value), 'Node to file relation found in RDF output (rdfs:seeAlso).'); $this->drupalGet('node'); } diff --git a/core/modules/rdf/src/Tests/GetRdfNamespacesTest.php b/core/modules/rdf/tests/src/Functional/GetRdfNamespacesTest.php similarity index 76% rename from core/modules/rdf/src/Tests/GetRdfNamespacesTest.php rename to core/modules/rdf/tests/src/Functional/GetRdfNamespacesTest.php index 7fde6f0c..5d31d3ac 100644 --- a/core/modules/rdf/src/Tests/GetRdfNamespacesTest.php +++ b/core/modules/rdf/tests/src/Functional/GetRdfNamespacesTest.php @@ -1,27 +1,27 @@ install(array('rdf_conflicting_namespaces'), TRUE); + \Drupal::service('module_installer')->install(['rdf_conflicting_namespaces'], TRUE); try { $ns = rdf_get_namespaces(); $this->fail('Expected exception not thrown for conflicting namespace declaration.'); diff --git a/core/modules/rdf/src/Tests/NodeAttributesTest.php b/core/modules/rdf/tests/src/Functional/NodeAttributesTest.php similarity index 78% rename from core/modules/rdf/src/Tests/NodeAttributesTest.php rename to core/modules/rdf/tests/src/Functional/NodeAttributesTest.php index 5c6b2676..87067bd6 100644 --- a/core/modules/rdf/src/Tests/NodeAttributesTest.php +++ b/core/modules/rdf/tests/src/Functional/NodeAttributesTest.php @@ -1,6 +1,6 @@ setBundleMapping(array( - 'types' => array('sioc:Item', 'foaf:Document'), - )) - ->setFieldMapping('title', array( - 'properties' => array('dc:title'), - )) - ->setFieldMapping('created', array( - 'properties' => array('dc:date', 'dc:created'), + ->setBundleMapping([ + 'types' => ['sioc:Item', 'foaf:Document'], + ]) + ->setFieldMapping('title', [ + 'properties' => ['dc:title'], + ]) + ->setFieldMapping('created', [ + 'properties' => ['dc:date', 'dc:created'], 'datatype' => 'xsd:dateTime', - 'datatype_callback' => array('callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'), - )) + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'], + ]) ->save(); } /** * Creates a node of type article and tests its RDFa markup. */ - function testNodeAttributes() { + public function testNodeAttributes() { // Create node with single quotation mark title to ensure it does not get // escaped more than once. - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'type' => 'article', 'title' => $this->randomMachineName(8) . "'", - )); + ]); $node_uri = $node->url('canonical', ['absolute' => TRUE]); $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); @@ -57,37 +57,37 @@ function testNodeAttributes() { // Inspects RDF graph output. // Node type. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://rdfs.org/sioc/ns#Item', - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Node type found in RDF output (sioc:Item).'); // Node type. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://xmlns.com/foaf/0.1/Document', - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Node type found in RDF output (foaf:Document).'); // Node title. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $node->getTitle(), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/title', $expected_value), 'Node title found in RDF output (dc:title).'); // Node date (date format must be UTC). - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => \Drupal::service('date.formatter')->format($node->getCreatedTime(), 'custom', 'c', 'UTC'), 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime', - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/date', $expected_value), 'Node date found in RDF output (dc:date).'); // Node date (date format must be UTC). - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => \Drupal::service('date.formatter')->format($node->getCreatedTime(), 'custom', 'c', 'UTC'), 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime', - ); + ]; $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/created', $expected_value), 'Node date found in RDF output (dc:created).'); } diff --git a/core/modules/rdf/src/Tests/StandardProfileTest.php b/core/modules/rdf/tests/src/Functional/StandardProfileTest.php similarity index 87% rename from core/modules/rdf/src/Tests/StandardProfileTest.php rename to core/modules/rdf/tests/src/Functional/StandardProfileTest.php index e6c358de..8662b9da 100644 --- a/core/modules/rdf/src/Tests/StandardProfileTest.php +++ b/core/modules/rdf/tests/src/Functional/StandardProfileTest.php @@ -1,13 +1,13 @@ install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); $this->baseUri = \Drupal::url('', [], ['absolute' => TRUE]); // Create two test users. - $this->adminUser = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser([ 'administer content types', 'administer comments', 'access comments', 'access content', - )); - $this->webUser = $this->drupalCreateUser(array( + ]); + $this->webUser = $this->drupalCreateUser([ 'access comments', 'post comments', 'skip comment approval', 'access content', - )); + ]); $this->drupalLogin($this->adminUser); @@ -141,46 +141,46 @@ protected function setUp() { $this->image->save(); // Create article. - $article_settings = array( + $article_settings = [ 'type' => 'article', - 'promote' => NODE_PROMOTED, - 'field_image' => array( - array( + 'promote' => NodeInterface::PROMOTED, + 'field_image' => [ + [ 'target_id' => $this->image->id(), - ), - ), - 'field_tags' => array( - array( + ], + ], + 'field_tags' => [ + [ 'target_id' => $this->term->id(), - ), - ), - ); + ], + ], + ]; $this->article = $this->drupalCreateNode($article_settings); // Create second article to test teaser list. - $this->drupalCreateNode(array('type' => 'article', 'promote' => NODE_PROMOTED,)); + $this->drupalCreateNode(['type' => 'article', 'promote' => NodeInterface::PROMOTED]); // Create article comment. $this->articleComment = $this->saveComment($this->article->id(), $this->webUser->id(), NULL, 0); // Create page. - $this->page = $this->drupalCreateNode(array('type' => 'page')); + $this->page = $this->drupalCreateNode(['type' => 'page']); // Set URIs. // Image. $image_file = $this->article->get('field_image')->entity; $this->imageUri = ImageStyle::load('large')->buildUrl($image_file->getFileUri()); // Term. - $this->termUri = $this->term->url('canonical', array('absolute' => TRUE)); + $this->termUri = $this->term->url('canonical', ['absolute' => TRUE]); // Article. - $this->articleUri = $this->article->url('canonical', array('absolute' => TRUE)); + $this->articleUri = $this->article->url('canonical', ['absolute' => TRUE]); // Page. - $this->pageUri = $this->page->url('canonical', array('absolute' => TRUE)); + $this->pageUri = $this->page->url('canonical', ['absolute' => TRUE]); // Author. - $this->authorUri = $this->adminUser->url('canonical', array('absolute' => TRUE)); + $this->authorUri = $this->adminUser->url('canonical', ['absolute' => TRUE]); // Comment. - $this->articleCommentUri = $this->articleComment->url('canonical', array('absolute' => TRUE)); + $this->articleCommentUri = $this->articleComment->url('canonical', ['absolute' => TRUE]); // Commenter. - $this->commenterUri = $this->webUser->url('canonical', array('absolute' => TRUE)); + $this->commenterUri = $this->webUser->url('canonical', ['absolute' => TRUE]); $this->drupalLogout(); } @@ -211,11 +211,11 @@ protected function doFrontPageRdfaTests() { $this->assertEqual(2, count($graph->allOfType('http://schema.org/Article')), 'Two articles found on front page.'); // Test interaction count. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => 'UserComments:1', 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/interactionCount', $expected_value), "Teaser comment count was found (schema:interactionCount)."); // Test the properties that are common between pages and articles and are @@ -228,10 +228,10 @@ protected function doFrontPageRdfaTests() { // image, move this to testArticleProperties(). $image_file = $this->article->get('field_image')->entity; $image_uri = ImageStyle::load('medium')->buildUrl($image_file->getFileUri()); - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $image_uri, - ); + ]; $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/image', $expected_value), "Teaser image was found (schema:image)."); } @@ -258,10 +258,10 @@ protected function doArticleRdfaTests() { // @todo Once the image points to the original instead of the processed // image, move this to testArticleProperties(). - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->imageUri, - ); + ]; $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/image', $expected_value), "Article image was found (schema:image)."); } @@ -303,10 +303,10 @@ protected function doUserRdfaTests() { $this->assertEqual($graph->type($this->authorUri), 'schema:Person', "User type was found (schema:Person) on user page."); // User name. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $this->adminUser->label(), - ); + ]; $this->assertTrue($graph->hasProperty($this->authorUri, 'http://schema.org/name', $expected_value), "User name was found (schema:name) on user page."); $this->drupalLogout(); @@ -323,11 +323,11 @@ protected function doTermRdfaTests() { $this->assertEqual($graph->type($this->termUri), 'schema:Thing', "Term type was found (schema:Thing) on term page."); // Term name. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $this->term->getName(), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "Term name was found (schema:name) on term page."); // @todo Add test for term description once it is a field: @@ -345,47 +345,47 @@ protected function doTermRdfaTests() { * The word to use in the test assertion message. */ protected function assertRdfaCommonNodeProperties($graph, NodeInterface $node, $message_prefix) { - $uri = $node->url('canonical', array('absolute' => TRUE)); + $uri = $node->url('canonical', ['absolute' => TRUE]); // Title. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $node->get('title')->value, 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/name', $expected_value), "$message_prefix title was found (schema:name)."); // Created date. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => format_date($node->get('created')->value, 'custom', 'c', 'UTC'), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/dateCreated', $expected_value), "$message_prefix created date was found (schema:dateCreated) in teaser."); // Body. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $node->get('body')->value, 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/text', $expected_value), "$message_prefix body was found (schema:text) in teaser."); // Author. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->authorUri, - ); + ]; $this->assertTrue($graph->hasProperty($uri, 'http://schema.org/author', $expected_value), "$message_prefix author was found (schema:author) in teaser."); // Author type. $this->assertEqual($graph->type($this->authorUri), 'schema:Person', "$message_prefix author type was found (schema:Person)."); // Author name. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $this->adminUser->label(), - ); + ]; $this->assertTrue($graph->hasProperty($this->authorUri, 'http://schema.org/name', $expected_value), "$message_prefix author name was found (schema:name)."); } @@ -399,24 +399,24 @@ protected function assertRdfaCommonNodeProperties($graph, NodeInterface $node, $ */ protected function assertRdfaArticleProperties($graph, $message_prefix) { // Tags. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->termUri, - ); + ]; $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/about', $expected_value), "$message_prefix tag was found (schema:about)."); // Tag type. // @todo Enable with https://www.drupal.org/node/2072791. - //$this->assertEqual($graph->type($this->termUri), 'schema:Thing', 'Tag type was found (schema:Thing).'); + // $this->assertEqual($graph->type($this->termUri), 'schema:Thing', 'Tag type was found (schema:Thing).'); // Tag name. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $this->term->getName(), 'lang' => 'en', - ); + ]; // @todo Enable with https://www.drupal.org/node/2072791. - //$this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "$message_prefix name was found (schema:name)."); + // $this->assertTrue($graph->hasProperty($this->termUri, 'http://schema.org/name', $expected_value), "$message_prefix name was found (schema:name)."); } /** @@ -427,58 +427,58 @@ protected function assertRdfaArticleProperties($graph, $message_prefix) { */ protected function assertRdfaNodeCommentProperties($graph) { // Relationship between node and comment. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->articleCommentUri, - ); + ]; $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/comment', $expected_value), 'Relationship between node and comment found (schema:comment).'); // Comment type. $this->assertEqual($graph->type($this->articleCommentUri), 'schema:Comment', 'Comment type was found (schema:Comment).'); // Comment title. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $this->articleComment->get('subject')->value, 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/name', $expected_value), 'Article comment title was found (schema:name).'); // Comment created date. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => format_date($this->articleComment->get('created')->value, 'custom', 'c', 'UTC'), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/dateCreated', $expected_value), 'Article comment created date was found (schema:dateCreated).'); // Comment body. $text = $this->articleComment->get('comment_body')->value; - $expected_value = array( + $expected_value = [ 'type' => 'literal', // There is an extra carriage return in the when parsing comments as // output by Bartik, so it must be added to the expected value. 'value' => "$text ", 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/text', $expected_value), 'Article comment body was found (schema:text).'); // Comment uid. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => $this->commenterUri, - ); + ]; $this->assertTrue($graph->hasProperty($this->articleCommentUri, 'http://schema.org/author', $expected_value), 'Article comment author was found (schema:author).'); // Comment author type. $this->assertEqual($graph->type($this->commenterUri), 'schema:Person', 'Comment author type was found (schema:Person).'); // Comment author name. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $this->webUser->getUsername(), - ); + ]; $this->assertTrue($graph->hasProperty($this->commenterUri, 'http://schema.org/name', $expected_value), 'Comment author name was found (schema:name).'); } @@ -499,7 +499,7 @@ protected function assertRdfaNodeCommentProperties($graph) { * The saved comment. */ protected function saveComment($nid, $uid, $contact = NULL, $pid = 0) { - $values = array( + $values = [ 'entity_id' => $nid, 'entity_type' => 'node', 'field_name' => 'comment', @@ -508,7 +508,7 @@ protected function saveComment($nid, $uid, $contact = NULL, $pid = 0) { 'subject' => $this->randomMachineName(), 'comment_body' => $this->randomMachineName(), 'status' => 1, - ); + ]; if ($contact) { $values += $contact; } diff --git a/core/modules/rdf/src/Tests/TaxonomyAttributesTest.php b/core/modules/rdf/tests/src/Functional/TaxonomyAttributesTest.php similarity index 81% rename from core/modules/rdf/src/Tests/TaxonomyAttributesTest.php rename to core/modules/rdf/tests/src/Functional/TaxonomyAttributesTest.php index 6be2c5bc..346ffb7e 100644 --- a/core/modules/rdf/src/Tests/TaxonomyAttributesTest.php +++ b/core/modules/rdf/tests/src/Functional/TaxonomyAttributesTest.php @@ -1,8 +1,8 @@ vocabulary->id()) - ->setBundleMapping(array('types' => array('skos:Concept'))) - ->setFieldMapping('name', array( - 'properties' => array('rdfs:label', 'skos:prefLabel'), - )) + ->setBundleMapping(['types' => ['skos:Concept']]) + ->setFieldMapping('name', [ + 'properties' => ['rdfs:label', 'skos:prefLabel'], + ]) ->save(); } /** * Creates a random term and ensures the RDF output is correct. */ - function testTaxonomyTermRdfaAttributes() { + public function testTaxonomyTermRdfaAttributes() { $term = $this->createTerm($this->vocabulary); $term_uri = $term->url('canonical', ['absolute' => TRUE]); @@ -54,24 +54,24 @@ function testTaxonomyTermRdfaAttributes() { // Inspects RDF graph output. // Term type. - $expected_value = array( + $expected_value = [ 'type' => 'uri', 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', - ); + ]; $this->assertTrue($graph->hasProperty($term_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Term type found in RDF output (skos:Concept).'); // Term label. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $term->getName(), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($term_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Term label found in RDF output (rdfs:label).'); // Term label. - $expected_value = array( + $expected_value = [ 'type' => 'literal', 'value' => $term->getName(), 'lang' => 'en', - ); + ]; $this->assertTrue($graph->hasProperty($term_uri, 'http://www.w3.org/2004/02/skos/core#prefLabel', $expected_value), 'Term label found in RDF output (skos:prefLabel).'); // @todo Add test for term description once it is a field: diff --git a/core/modules/rdf/tests/src/Functional/UserAttributesTest.php b/core/modules/rdf/tests/src/Functional/UserAttributesTest.php new file mode 100644 index 00000000..7e982860 --- /dev/null +++ b/core/modules/rdf/tests/src/Functional/UserAttributesTest.php @@ -0,0 +1,108 @@ +setBundleMapping([ + 'types' => ['sioc:UserAccount'], + ]) + ->setFieldMapping('name', [ + 'properties' => ['foaf:name'], + ]) + ->save(); + } + + /** + * Tests if default mapping for user is being used. + * + * Creates a random user and ensures the default mapping for the user is + * being used. + */ + public function testUserAttributesInMarkup() { + // Creates users that should and should not be truncated + // by template_preprocess_username (20 characters) + // one of these users tests right on the cusp (20). + $user1 = $this->drupalCreateUser(['access user profiles']); + + $authors = [ + $this->drupalCreateUser([], $this->randomMachineName(30)), + $this->drupalCreateUser([], $this->randomMachineName(20)), + $this->drupalCreateUser([], $this->randomMachineName(5)) + ]; + + $this->drupalLogin($user1); + + $this->drupalCreateContentType(['type' => 'article']); + + /** @var \Drupal\user\UserInterface[] $authors */ + foreach ($authors as $author) { + $account_uri = $author->url('canonical', ['absolute' => TRUE]); + + // Parses the user profile page where the default bundle mapping for user + // should be used. + $parser = new \EasyRdf_Parser_Rdfa(); + $graph = new \EasyRdf_Graph(); + $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); + $parser->parse($graph, $this->drupalGet('user/' . $author->id()), 'rdfa', $base_uri); + + // Inspects RDF graph output. + // User type. + $expected_value = [ + 'type' => 'uri', + 'value' => 'http://rdfs.org/sioc/ns#UserAccount', + ]; + $this->assertTrue($graph->hasProperty($account_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'User type found in RDF output (sioc:UserAccount).'); + // User name. + $expected_value = [ + 'type' => 'literal', + 'value' => $author->getUsername(), + ]; + $this->assertTrue($graph->hasProperty($account_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'User name found in RDF output (foaf:name).'); + + // User creates a node. + $this->drupalLogin($author); + $node = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]); + $this->drupalLogin($user1); + + // Parses the node created by the user. + $parser = new \EasyRdf_Parser_Rdfa(); + $graph = new \EasyRdf_Graph(); + $base_uri = \Drupal::url('', [], ['absolute' => TRUE]); + $parser->parse($graph, $this->drupalGet('node/' . $node->id()), 'rdfa', $base_uri); + + // Ensures the default bundle mapping for user is used on the Authored By + // information on the node. + $expected_value = [ + 'type' => 'uri', + 'value' => 'http://rdfs.org/sioc/ns#UserAccount', + ]; + $this->assertTrue($graph->hasProperty($account_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'User type found in RDF output (sioc:UserAccount).'); + // User name. + $expected_value = [ + 'type' => 'literal', + 'value' => $author->getUsername(), + ]; + $this->assertTrue($graph->hasProperty($account_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'User name found in RDF output (foaf:name).'); + + } + } + +} diff --git a/core/modules/rdf/tests/src/Kernel/CrudTest.php b/core/modules/rdf/tests/src/Kernel/CrudTest.php index 60b4208d..f8292a38 100644 --- a/core/modules/rdf/tests/src/Kernel/CrudTest.php +++ b/core/modules/rdf/tests/src/Kernel/CrudTest.php @@ -16,7 +16,7 @@ class CrudTest extends KernelTestBase { * * @var array */ - public static $modules = array('entity_test', 'rdf', 'system'); + public static $modules = ['entity_test', 'rdf', 'system']; /** * @var string @@ -42,7 +42,7 @@ protected function setUp() { /** * Tests creation of RDF mapping. */ - function testMappingCreation() { + public function testMappingCreation() { $mapping_config_name = "{$this->prefix}.{$this->entityType}.{$this->bundle}"; // Save bundle mapping config. @@ -55,20 +55,20 @@ function testMappingCreation() { /** * Test the handling of bundle mappings. */ - function testBundleMapping() { + public function testBundleMapping() { // Test that the bundle mapping can be saved. - $types = array('sioc:Post', 'foaf:Document'); + $types = ['sioc:Post', 'foaf:Document']; rdf_get_mapping($this->entityType, $this->bundle) - ->setBundleMapping(array('types' => $types)) + ->setBundleMapping(['types' => $types]) ->save(); $bundle_mapping = rdf_get_mapping($this->entityType, $this->bundle) ->getBundleMapping(); $this->assertEqual($types, $bundle_mapping['types'], 'Bundle mapping saved.'); // Test that the bundle mapping can be edited. - $types = array('schema:BlogPosting'); + $types = ['schema:BlogPosting']; rdf_get_mapping($this->entityType, $this->bundle) - ->setBundleMapping(array('types' => $types)) + ->setBundleMapping(['types' => $types]) ->save(); $bundle_mapping = rdf_get_mapping($this->entityType, $this->bundle) ->getBundleMapping(); @@ -78,15 +78,15 @@ function testBundleMapping() { /** * Test the handling of field mappings. */ - function testFieldMapping() { + public function testFieldMapping() { $field_name = 'created'; // Test that the field mapping can be saved. - $mapping = array( - 'properties' => array('dc:created'), + $mapping = [ + 'properties' => ['dc:created'], 'datatype' => 'xsd:dateTime', - 'datatype_callback' => array('callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'), - ); + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'], + ]; rdf_get_mapping($this->entityType, $this->bundle) ->setFieldMapping($field_name, $mapping) ->save(); @@ -95,11 +95,11 @@ function testFieldMapping() { $this->assertEqual($mapping, $field_mapping, 'Field mapping saved.'); // Test that the field mapping can be edited. - $mapping = array( - 'properties' => array('dc:date'), + $mapping = [ + 'properties' => ['dc:date'], 'datatype' => 'foo:bar', - 'datatype_callback' => array('callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'), - ); + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'], + ]; rdf_get_mapping($this->entityType, $this->bundle) ->setFieldMapping($field_name, $mapping) ->save(); diff --git a/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php index a35a9c43..fc78691b 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php @@ -26,7 +26,7 @@ class DateTimeFieldRdfaTest extends FieldRdfaTestBase { /** * {@inheritdoc} */ - public static $modules = array('datetime'); + public static $modules = ['datetime']; protected function setUp() { parent::setUp(); @@ -35,12 +35,12 @@ protected function setUp() { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:dateCreated'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:dateCreated'], + ])->save(); // Set up test entity. - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->value = $this->testValue; } @@ -48,7 +48,7 @@ protected function setUp() { * Tests the default formatter. */ public function testDefaultFormatter() { - $this->assertFormatterRdfa(array('type' => 'datetime_default'), 'http://schema.org/dateCreated', array('value' => $this->testValue . 'Z', 'type' => 'literal', 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime')); + $this->assertFormatterRdfa(['type' => 'datetime_default'], 'http://schema.org/dateCreated', ['value' => $this->testValue . 'Z', 'type' => 'literal', 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime']); } } diff --git a/core/modules/rdf/tests/src/Kernel/Field/EmailFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/EmailFieldRdfaTest.php index c1217516..85ae8881 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/EmailFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/EmailFieldRdfaTest.php @@ -19,7 +19,7 @@ class EmailFieldRdfaTest extends FieldRdfaTestBase { /** * {@inheritdoc} */ - public static $modules = array('text'); + public static $modules = ['text']; protected function setUp() { parent::setUp(); @@ -28,13 +28,13 @@ protected function setUp() { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:email'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:email'], + ])->save(); // Set up test values. $this->testValue = 'test@example.com'; - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->value = $this->testValue; } @@ -43,9 +43,9 @@ protected function setUp() { */ public function testAllFormatters() { // Test the plain formatter. - $this->assertFormatterRdfa(array('type' => 'string'), 'http://schema.org/email', array('value' => $this->testValue)); + $this->assertFormatterRdfa(['type' => 'string'], 'http://schema.org/email', ['value' => $this->testValue]); // Test the mailto formatter. - $this->assertFormatterRdfa(array('type' => 'email_mailto'), 'http://schema.org/email', array('value' => $this->testValue)); + $this->assertFormatterRdfa(['type' => 'email_mailto'], 'http://schema.org/email', ['value' => $this->testValue]); } } diff --git a/core/modules/rdf/tests/src/Kernel/Field/EntityReferenceRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/EntityReferenceRdfaTest.php index cefa7e0f..9312fbc9 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/EntityReferenceRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/EntityReferenceRdfaTest.php @@ -52,7 +52,7 @@ protected function setUp() { $this->installEntitySchema('entity_test_rev'); // Give anonymous users permission to view test entities. - $this->installConfig(array('user')); + $this->installConfig(['user']); Role::load(RoleInterface::ANONYMOUS_ID) ->grantPermission('view test entity') ->save(); @@ -61,20 +61,20 @@ protected function setUp() { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:knows'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:knows'], + ])->save(); // Create the entity to be referenced. $this->targetEntity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('name' => $this->randomMachineName())); + ->create(['name' => $this->randomMachineName()]); $this->targetEntity->save(); // Create the entity that will have the entity reference field. $this->entity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('name' => $this->randomMachineName())); + ->create(['name' => $this->randomMachineName()]); $this->entity->save(); $this->entity->{$this->fieldName}->entity = $this->targetEntity; $this->uri = $this->getAbsoluteUri($this->entity); @@ -87,9 +87,9 @@ public function testAllFormatters() { $entity_uri = $this->getAbsoluteUri($this->targetEntity); // Tests the label formatter. - $this->assertFormatterRdfa(array('type' => 'entity_reference_label'), 'http://schema.org/knows', array('value' => $entity_uri, 'type' => 'uri')); + $this->assertFormatterRdfa(['type' => 'entity_reference_label'], 'http://schema.org/knows', ['value' => $entity_uri, 'type' => 'uri']); // Tests the entity formatter. - $this->assertFormatterRdfa(array('type' => 'entity_reference_entity_view'), 'http://schema.org/knows', array('value' => $entity_uri, 'type' => 'uri')); + $this->assertFormatterRdfa(['type' => 'entity_reference_entity_view'], 'http://schema.org/knows', ['value' => $entity_uri, 'type' => 'uri']); } } diff --git a/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaDatatypeCallbackTest.php b/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaDatatypeCallbackTest.php index 1e1a809f..94f7f24d 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaDatatypeCallbackTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaDatatypeCallbackTest.php @@ -19,23 +19,23 @@ class FieldRdfaDatatypeCallbackTest extends FieldRdfaTestBase { /** * {@inheritdoc} */ - public static $modules = array('text', 'filter'); + public static $modules = ['text', 'filter']; protected function setUp() { parent::setUp(); $this->createTestField(); - $this->installConfig(array('filter')); + $this->installConfig(['filter']); // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:interactionCount'), - 'datatype_callback' => array( + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:interactionCount'], + 'datatype_callback' => [ 'callable' => 'Drupal\rdf\Tests\Field\TestDataConverter::convertFoo', - ), - ))->save(); + ], + ])->save(); // Set up test values. $this->testValue = $this->randomMachineName(); @@ -51,7 +51,7 @@ protected function setUp() { */ public function testDefaultFormatter() { // Expected value is the output of the datatype callback, not the raw value. - $this->assertFormatterRdfa(array('type' => 'text_default'), 'http://schema.org/interactionCount', array('value' => 'foo' . $this->testValue)); + $this->assertFormatterRdfa(['type' => 'text_default'], 'http://schema.org/interactionCount', ['value' => 'foo' . $this->testValue]); } } diff --git a/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaTestBase.php b/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaTestBase.php index 74311850..82ea9efd 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaTestBase.php +++ b/core/modules/rdf/tests/src/Kernel/Field/FieldRdfaTestBase.php @@ -48,7 +48,7 @@ abstract class FieldRdfaTestBase extends FieldKernelTestBase { * * @var array */ - public static $modules = array('rdf'); + public static $modules = ['rdf']; /** * @var string @@ -83,7 +83,7 @@ protected function setUp() { * - datatype: (optional) The datatype of the value (e.g. xsd:dateTime). */ protected function assertFormatterRdfa($formatter, $property, $expected_rdf_value) { - $expected_rdf_value += array('type' => 'literal'); + $expected_rdf_value += ['type' => 'literal']; // The field formatter will be rendered inside the entity. Set the field // formatter in the entity display options before rendering the entity. @@ -111,12 +111,12 @@ protected function assertFormatterRdfa($formatter, $property, $expected_rdf_valu * @param array $field_settings * (optional) An array of field settings. */ - protected function createTestField($field_settings = array()) { - FieldStorageConfig::create(array( + protected function createTestField($field_settings = []) { + FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'entity_test', 'type' => $this->fieldType, - ))->save(); + ])->save(); FieldConfig::create([ 'entity_type' => 'entity_test', 'field_name' => $this->fieldName, @@ -135,7 +135,7 @@ protected function createTestField($field_settings = array()) { * The absolute URI. */ protected function getAbsoluteUri($entity) { - return $entity->url('canonical', array('absolute' => TRUE)); + return $entity->url('canonical', ['absolute' => TRUE]); } /** @@ -172,14 +172,14 @@ protected function parseContent($content) { * format and return values see the SimpleXML documentation, * http://php.net/manual/function.simplexml-element-xpath.php. */ - protected function xpathContent($content, $xpath, array $arguments = array()) { + protected function xpathContent($content, $xpath, array $arguments = []) { if ($elements = $this->parseContent($content)) { $xpath = $this->buildXPathQuery($xpath, $arguments); $result = $elements->xpath($xpath); // Some combinations of PHP / libxml versions return an empty array // instead of the documented FALSE. Forcefully convert any falsish values // to an empty array to allow foreach(...) constructions. - return $result ? $result : array(); + return $result ? $result : []; } else { return FALSE; diff --git a/core/modules/rdf/tests/src/Kernel/Field/LinkFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/LinkFieldRdfaTest.php index d4e1cf0f..30735e3a 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/LinkFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/LinkFieldRdfaTest.php @@ -19,7 +19,7 @@ class LinkFieldRdfaTest extends FieldRdfaTestBase { /** * {@inheritdoc} */ - public static $modules = array('link', 'text'); + public static $modules = ['link', 'text']; /** * {@inheritdoc} @@ -31,9 +31,9 @@ protected function setUp() { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:link'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:link'], + ])->save(); } @@ -43,14 +43,14 @@ protected function setUp() { public function testAllFormattersExternal() { // Set up test values. $this->testValue = 'http://test.me/foo/bar/neque/porro/quisquam/est/qui-dolorem?foo/bar/neque/porro/quisquam/est/qui-dolorem'; - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->uri = $this->testValue; // Set up the expected result. - $expected_rdf = array( + $expected_rdf = [ 'value' => $this->testValue, 'type' => 'uri', - ); + ]; $this->runTestAllFormatters($expected_rdf, 'external'); } @@ -61,15 +61,15 @@ public function testAllFormattersExternal() { public function testAllFormattersInternal() { // Set up test values. $this->testValue = 'admin'; - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->uri = 'internal:/admin'; // Set up the expected result. // AssertFormatterRdfa looks for a full path. - $expected_rdf = array( + $expected_rdf = [ 'value' => $this->uri . '/' . $this->testValue, 'type' => 'uri', - ); + ]; $this->runTestAllFormatters($expected_rdf, 'internal'); } @@ -80,14 +80,14 @@ public function testAllFormattersInternal() { public function testAllFormattersFront() { // Set up test values. $this->testValue = '/'; - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->uri = 'internal:/'; // Set up the expected result. - $expected_rdf = array( + $expected_rdf = [ 'value' => $this->uri . '/', 'type' => 'uri', - ); + ]; $this->runTestAllFormatters($expected_rdf, 'front'); } @@ -98,86 +98,86 @@ public function testAllFormattersFront() { public function runTestAllFormatters($expected_rdf, $type = NULL) { // Test the link formatter: trim at 80, no other settings. - $formatter = array( + $formatter = [ 'type' => 'link', - 'settings' => array( + 'settings' => [ 'trim_length' => 80, 'url_only' => FALSE, 'url_plain' => FALSE, 'rel' => '', 'target' => '', - ), - ); + ], + ]; $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); // Test the link formatter: trim at 40, nofollow, new window. - $formatter = array( + $formatter = [ 'type' => 'link', - 'settings' => array( + 'settings' => [ 'trim_length' => 40, 'url_only' => FALSE, 'url_plain' => FALSE, 'rel' => 'nofollow', 'target' => '_blank', - ), - ); + ], + ]; $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); // Test the link formatter: trim at 40, URL only (not plaintext) nofollow, // new window. - $formatter = array( + $formatter = [ 'type' => 'link', - 'settings' => array( + 'settings' => [ 'trim_length' => 40, 'url_only' => TRUE, 'url_plain' => FALSE, 'rel' => 'nofollow', 'target' => '_blank', - ), - ); + ], + ]; $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); // Test the link_separate formatter: trim at 40, nofollow, new window. - $formatter = array( + $formatter = [ 'type' => 'link_separate', - 'settings' => array( + 'settings' => [ 'trim_length' => 40, 'rel' => 'nofollow', 'target' => '_blank', - ), - ); + ], + ]; $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); // Change the expected value here to literal. When formatted as plaintext // then the RDF is expecting a 'literal' not a 'uri'. - $expected_rdf = array( + $expected_rdf = [ 'value' => $this->testValue, 'type' => 'literal', - ); + ]; // Test the link formatter: trim at 20, url only (as plaintext.) - $formatter = array( + $formatter = [ 'type' => 'link', - 'settings' => array( + 'settings' => [ 'trim_length' => 20, 'url_only' => TRUE, 'url_plain' => TRUE, 'rel' => '0', 'target' => '0', - ), - ); + ], + ]; $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); // Test the link formatter: do not trim, url only (as plaintext.) - $formatter = array( + $formatter = [ 'type' => 'link', - 'settings' => array( + 'settings' => [ 'trim_length' => 0, 'url_only' => TRUE, 'url_plain' => TRUE, 'rel' => '0', 'target' => '0', - ), - ); + ], + ]; $this->assertFormatterRdfa($formatter, 'http://schema.org/link', $expected_rdf); } diff --git a/core/modules/rdf/tests/src/Kernel/Field/NumberFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/NumberFieldRdfaTest.php index 514ca9d6..5c7d3856 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/NumberFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/NumberFieldRdfaTest.php @@ -19,7 +19,7 @@ public function testIntegerFormatter() { $testValue = 3; $this->createTestField(); $this->createTestEntity($testValue); - $this->assertFormatterRdfa(array('type' => 'number_integer'), 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa(['type' => 'number_integer'], 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is not created. $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__items") and @content]'); @@ -31,26 +31,26 @@ public function testIntegerFormatter() { */ public function testIntegerFormatterWithSettings() { \Drupal::service('theme_handler')->install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); $this->fieldType = 'integer'; - $formatter = array( + $formatter = [ 'type' => 'number_integer', - 'settings' => array( + 'settings' => [ 'thousand_separator' => '.', 'prefix_suffix' => TRUE, - ), - ); + ], + ]; $testValue = 3333333.33; - $field_settings = array( + $field_settings = [ 'prefix' => '#', 'suffix' => ' llamas.', - ); + ]; $this->createTestField($field_settings); $this->createTestEntity($testValue); - $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is created. - $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', array(':testValue' => $testValue)); + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', [':testValue' => $testValue]); $this->assertTrue($result); } @@ -62,7 +62,7 @@ public function testFloatFormatter() { $testValue = 3.33; $this->createTestField(); $this->createTestEntity($testValue); - $this->assertFormatterRdfa(array('type' => 'number_unformatted'), 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa(['type' => 'number_unformatted'], 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is not created. $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__items") and @content]'); @@ -74,27 +74,27 @@ public function testFloatFormatter() { */ public function testFloatFormatterWithSettings() { \Drupal::service('theme_handler')->install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); $this->fieldType = 'float'; - $formatter = array( + $formatter = [ 'type' => 'number_decimal', - 'settings' => array( + 'settings' => [ 'thousand_separator' => '.', 'decimal_separator' => ',', 'prefix_suffix' => TRUE, - ), - ); + ], + ]; $testValue = 3333333.33; - $field_settings = array( + $field_settings = [ 'prefix' => '$', 'suffix' => ' more.', - ); + ]; $this->createTestField($field_settings); $this->createTestEntity($testValue); - $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is created. - $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', array(':testValue' => $testValue)); + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', [':testValue' => $testValue]); $this->assertTrue($result); } @@ -103,16 +103,16 @@ public function testFloatFormatterWithSettings() { */ public function testFloatFormatterWithScale() { $this->fieldType = 'float'; - $formatter = array( + $formatter = [ 'type' => 'number_decimal', - 'settings' => array( + 'settings' => [ 'scale' => 5, - ), - ); + ], + ]; $testValue = 3.33; $this->createTestField(); $this->createTestEntity($testValue); - $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is not created. $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__items") and @content]'); @@ -124,21 +124,21 @@ public function testFloatFormatterWithScale() { */ public function testFloatFormatterWithScaleExercised() { \Drupal::service('theme_handler')->install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); $this->fieldType = 'float'; - $formatter = array( + $formatter = [ 'type' => 'number_decimal', - 'settings' => array( + 'settings' => [ 'scale' => 5, - ), - ); + ], + ]; $testValue = 3.1234567; $this->createTestField(); $this->createTestEntity($testValue); - $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is created. - $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', array(':testValue' => $testValue)); + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', [':testValue' => $testValue]); $this->assertTrue($result); } @@ -150,7 +150,7 @@ public function testDecimalFormatter() { $testValue = 3.33; $this->createTestField(); $this->createTestEntity($testValue); - $this->assertFormatterRdfa(array('type' => 'number_decimal'), 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa(['type' => 'number_decimal'], 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is not created. $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__items") and @content]'); @@ -162,27 +162,27 @@ public function testDecimalFormatter() { */ public function testDecimalFormatterWithSettings() { \Drupal::service('theme_handler')->install(['classy']); - \Drupal::service('theme_handler')->setDefault('classy'); + $this->config('system.theme')->set('default', 'classy')->save(); $this->fieldType = 'decimal'; - $formatter = array( + $formatter = [ 'type' => 'number_decimal', - 'settings' => array( + 'settings' => [ 'thousand_separator' => 't', 'decimal_separator' => '#', 'prefix_suffix' => TRUE, - ), - ); + ], + ]; $testValue = 3333333.33; - $field_settings = array( + $field_settings = [ 'prefix' => '$', 'suffix' => ' more.', - ); + ]; $this->createTestField($field_settings); $this->createTestEntity($testValue); - $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', ['value' => $testValue]); // Test that the content attribute is created. - $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', array(':testValue' => $testValue)); + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field__item") and @content=:testValue]', [':testValue' => $testValue]); $this->assertTrue($result); } @@ -192,12 +192,12 @@ public function testDecimalFormatterWithSettings() { protected function createTestEntity($testValue) { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:baseSalary'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:baseSalary'], + ])->save(); // Set up test entity. - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->value = $testValue; } diff --git a/core/modules/rdf/tests/src/Kernel/Field/StringFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/StringFieldRdfaTest.php index a0b28e94..738e40c0 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/StringFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/StringFieldRdfaTest.php @@ -37,9 +37,9 @@ protected function setUp() { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:text'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:text'], + ])->save(); // Set up test entity. $this->entity = EntityTest::create(); @@ -52,7 +52,7 @@ protected function setUp() { */ public function testStringFormatters() { // Tests the string formatter. - $this->assertFormatterRdfa(array('type' => 'string'), 'http://schema.org/text', array('value' => $this->testValue)); + $this->assertFormatterRdfa(['type' => 'string'], 'http://schema.org/text', ['value' => $this->testValue]); } } diff --git a/core/modules/rdf/tests/src/Kernel/Field/TelephoneFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/TelephoneFieldRdfaTest.php index 97412560..d705b210 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/TelephoneFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/TelephoneFieldRdfaTest.php @@ -26,7 +26,7 @@ class TelephoneFieldRdfaTest extends FieldRdfaTestBase { /** * {@inheritdoc} */ - public static $modules = array('telephone', 'text'); + public static $modules = ['telephone', 'text']; protected function setUp() { parent::setUp(); @@ -35,13 +35,13 @@ protected function setUp() { // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:telephone'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:telephone'], + ])->save(); // Set up test values. $this->testValue = '555-555-5555'; - $this->entity = EntityTest::create(array()); + $this->entity = EntityTest::create([]); $this->entity->{$this->fieldName}->value = $this->testValue; } @@ -50,18 +50,18 @@ protected function setUp() { */ public function testAllFormatters() { // Tests the plain formatter. - $this->assertFormatterRdfa(array('type' => 'string'), 'http://schema.org/telephone', array('value' => $this->testValue)); + $this->assertFormatterRdfa(['type' => 'string'], 'http://schema.org/telephone', ['value' => $this->testValue]); // Tests the telephone link formatter. - $this->assertFormatterRdfa(array('type' => 'telephone_link'), 'http://schema.org/telephone', array('value' => 'tel:' . $this->testValue, 'type' => 'uri')); + $this->assertFormatterRdfa(['type' => 'telephone_link'], 'http://schema.org/telephone', ['value' => 'tel:' . $this->testValue, 'type' => 'uri']); - $formatter = array( + $formatter = [ 'type' => 'telephone_link', - 'settings' => array('title' => 'Contact us'), - ); - $expected_rdf_value = array( + 'settings' => ['title' => 'Contact us'], + ]; + $expected_rdf_value = [ 'value' => 'tel:' . $this->testValue, 'type' => 'uri', - ); + ]; // Tests the telephone link formatter with custom title. $this->assertFormatterRdfa($formatter, 'http://schema.org/telephone', $expected_rdf_value); } diff --git a/core/modules/rdf/tests/src/Kernel/Field/TextFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/TextFieldRdfaTest.php index cce34995..48bc5b8f 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/TextFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/TextFieldRdfaTest.php @@ -33,20 +33,20 @@ class TextFieldRdfaTest extends FieldRdfaTestBase { /** * {@inheritdoc} */ - public static $modules = array('text', 'filter'); + public static $modules = ['text', 'filter']; protected function setUp() { parent::setUp(); - $this->installConfig(array('filter')); + $this->installConfig(['filter']); $this->createTestField(); // Add the mapping. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping($this->fieldName, array( - 'properties' => array('schema:text'), - ))->save(); + $mapping->setFieldMapping($this->fieldName, [ + 'properties' => ['schema:text'], + ])->save(); // Set up test entity. $this->entity = EntityTest::create(); @@ -63,11 +63,11 @@ public function testAllFormatters() { $formatted_value = strip_tags($this->entity->{$this->fieldName}->processed); // Tests the default formatter. - $this->assertFormatterRdfa(array('type' => 'text_default'), 'http://schema.org/text', array('value' => $formatted_value)); + $this->assertFormatterRdfa(['type' => 'text_default'], 'http://schema.org/text', ['value' => $formatted_value]); // Tests the summary formatter. - $this->assertFormatterRdfa(array('type' => 'text_summary_or_trimmed'), 'http://schema.org/text', array('value' => $formatted_value)); + $this->assertFormatterRdfa(['type' => 'text_summary_or_trimmed'], 'http://schema.org/text', ['value' => $formatted_value]); // Tests the trimmed formatter. - $this->assertFormatterRdfa(array('type' => 'text_trimmed'), 'http://schema.org/text', array('value' => $formatted_value)); + $this->assertFormatterRdfa(['type' => 'text_trimmed'], 'http://schema.org/text', ['value' => $formatted_value]); } } diff --git a/core/modules/rdf/tests/src/Kernel/RdfaAttributesTest.php b/core/modules/rdf/tests/src/Kernel/RdfaAttributesTest.php index 42a4dc44..39f48312 100644 --- a/core/modules/rdf/tests/src/Kernel/RdfaAttributesTest.php +++ b/core/modules/rdf/tests/src/Kernel/RdfaAttributesTest.php @@ -16,16 +16,16 @@ class RdfaAttributesTest extends KernelTestBase { * * @var array */ - public static $modules = array('rdf'); + public static $modules = ['rdf']; /** * Test attribute creation for mappings which use 'property'. */ - function testProperty() { - $properties = array('dc:title'); + public function testProperty() { + $properties = ['dc:title']; - $mapping = array('properties' => $properties); - $expected_attributes = array('property' => $properties); + $mapping = ['properties' => $properties]; + $expected_attributes = ['property' => $properties]; $this->_testAttributes($expected_attributes, $mapping); } @@ -33,18 +33,18 @@ function testProperty() { /** * Test attribute creation for mappings which use 'datatype'. */ - function testDatatype() { - $properties = array('foo:bar1'); + public function testDatatype() { + $properties = ['foo:bar1']; $datatype = 'foo:bar1type'; - $mapping = array( + $mapping = [ 'datatype' => $datatype, 'properties' => $properties, - ); - $expected_attributes = array( + ]; + $expected_attributes = [ 'datatype' => $datatype, 'property' => $properties, - ); + ]; $this->_testAttributes($expected_attributes, $mapping); } @@ -52,23 +52,23 @@ function testDatatype() { /** * Test attribute creation for mappings which override human-readable content. */ - function testDatatypeCallback() { - $properties = array('dc:created'); + public function testDatatypeCallback() { + $properties = ['dc:created']; $datatype = 'xsd:dateTime'; $date = 1252750327; $iso_date = date('c', $date); - $mapping = array( + $mapping = [ 'datatype' => $datatype, 'properties' => $properties, - 'datatype_callback' => array('callable' => 'date_iso8601'), - ); - $expected_attributes = array( + 'datatype_callback' => ['callable' => 'date_iso8601'], + ]; + $expected_attributes = [ 'datatype' => $datatype, 'property' => $properties, 'content' => $iso_date, - ); + ]; $this->_testAttributes($expected_attributes, $mapping, $date); } @@ -77,23 +77,23 @@ function testDatatypeCallback() { /** * Test attribute creation for mappings which use data converters. */ - function testDatatypeCallbackWithConverter() { - $properties = array('schema:interactionCount'); + public function testDatatypeCallbackWithConverter() { + $properties = ['schema:interactionCount']; $data = "23"; $content = "UserComments:23"; - $mapping = array( + $mapping = [ 'properties' => $properties, - 'datatype_callback' => array( + 'datatype_callback' => [ 'callable' => 'Drupal\rdf\SchemaOrgDataConverter::interactionCount', - 'arguments' => array('interaction_type' => 'UserComments'), - ), - ); - $expected_attributes = array( + 'arguments' => ['interaction_type' => 'UserComments'], + ], + ]; + $expected_attributes = [ 'property' => $properties, 'content' => $content, - ); + ]; $this->_testAttributes($expected_attributes, $mapping, $data); } @@ -101,14 +101,14 @@ function testDatatypeCallbackWithConverter() { /** * Test attribute creation for mappings which use 'rel'. */ - function testRel() { - $properties = array('sioc:has_creator', 'dc:creator'); + public function testRel() { + $properties = ['sioc:has_creator', 'dc:creator']; - $mapping = array( + $mapping = [ 'properties' => $properties, 'mapping_type' => 'rel', - ); - $expected_attributes = array('rel' => $properties); + ]; + $expected_attributes = ['rel' => $properties]; $this->_testAttributes($expected_attributes, $mapping); } diff --git a/core/modules/rdf/tests/src/Unit/RdfMappingConfigEntityUnitTest.php b/core/modules/rdf/tests/src/Unit/RdfMappingConfigEntityUnitTest.php index 5b66d42f..5908ee72 100644 --- a/core/modules/rdf/tests/src/Unit/RdfMappingConfigEntityUnitTest.php +++ b/core/modules/rdf/tests/src/Unit/RdfMappingConfigEntityUnitTest.php @@ -72,7 +72,7 @@ public function testCalculateDependencies() { $target_entity_type->expects($this->any()) ->method('getProvider') ->will($this->returnValue('test_module')); - $values = array('targetEntityType' => $target_entity_type_id); + $values = ['targetEntityType' => $target_entity_type_id]; $target_entity_type->expects($this->any()) ->method('getBundleEntityType') ->will($this->returnValue(NULL)); @@ -99,23 +99,23 @@ public function testCalculateDependenciesWithEntityBundle() { $target_entity_type_id = $this->randomMachineName(16); $target_entity_type = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface'); $target_entity_type->expects($this->any()) - ->method('getProvider') - ->will($this->returnValue('test_module')); + ->method('getProvider') + ->will($this->returnValue('test_module')); $bundle_id = $this->randomMachineName(10); - $values = array('targetEntityType' => $target_entity_type_id , 'bundle' => $bundle_id); + $values = ['targetEntityType' => $target_entity_type_id , 'bundle' => $bundle_id]; $target_entity_type->expects($this->any()) ->method('getBundleConfigDependency') - ->will($this->returnValue(array('type' => 'config', 'name' => 'test_module.type.' . $bundle_id))); + ->will($this->returnValue(['type' => 'config', 'name' => 'test_module.type.' . $bundle_id])); $this->entityManager->expects($this->at(0)) - ->method('getDefinition') - ->with($target_entity_type_id) - ->will($this->returnValue($target_entity_type)); + ->method('getDefinition') + ->with($target_entity_type_id) + ->will($this->returnValue($target_entity_type)); $this->entityManager->expects($this->at(1)) - ->method('getDefinition') - ->with($this->entityTypeId) - ->will($this->returnValue($this->entityType)); + ->method('getDefinition') + ->with($this->entityTypeId) + ->will($this->returnValue($this->entityType)); $entity = new RdfMapping($values, $this->entityTypeId); $dependencies = $entity->calculateDependencies()->getDependencies(); diff --git a/core/modules/responsive_image/js/responsive_image.ajax.es6.js b/core/modules/responsive_image/js/responsive_image.ajax.es6.js new file mode 100644 index 00000000..64f630d6 --- /dev/null +++ b/core/modules/responsive_image/js/responsive_image.ajax.es6.js @@ -0,0 +1,12 @@ +(function (Drupal) { + /** + * Call picturefill so newly added responsive images are processed. + */ + Drupal.behaviors.responsiveImageAJAX = { + attach() { + if (window.picturefill) { + window.picturefill(); + } + }, + }; +}(Drupal)); diff --git a/core/modules/responsive_image/js/responsive_image.ajax.js b/core/modules/responsive_image/js/responsive_image.ajax.js index 52093193..145adcf0 100644 --- a/core/modules/responsive_image/js/responsive_image.ajax.js +++ b/core/modules/responsive_image/js/responsive_image.ajax.js @@ -1,16 +1,16 @@ -(function (Drupal) { - - 'use strict'; +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ - /** - * Call picturefill so newly added responsive images are processed. - */ +(function (Drupal) { Drupal.behaviors.responsiveImageAJAX = { - attach: function () { + attach: function attach() { if (window.picturefill) { window.picturefill(); } } }; - -})(Drupal); +})(Drupal); \ No newline at end of file diff --git a/core/modules/responsive_image/responsive_image.info.yml b/core/modules/responsive_image/responsive_image.info.yml index 8d9d6c2d..76e4b380 100644 --- a/core/modules/responsive_image/responsive_image.info.yml +++ b/core/modules/responsive_image/responsive_image.info.yml @@ -9,8 +9,8 @@ dependencies: - image configure: entity.responsive_image_style.collection -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module index e88dac08..54dc56c8 100644 --- a/core/modules/responsive_image/responsive_image.module +++ b/core/modules/responsive_image/responsive_image.module @@ -16,8 +16,24 @@ use Drupal\breakpoint\BreakpointInterface; /** * The machine name for the empty image breakpoint image style option. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use + * Drupal\responsive_image\ResponsiveImageStyleInterface::EMPTY_IMAGE + * instead. + * + * @see https://www.drupal.org/node/2831620 */ const RESPONSIVE_IMAGE_EMPTY_IMAGE = '_empty image_'; + +/** + * The machine name for the original image breakpoint image style option. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use + * \Drupal\responsive_image\ResponsiveImageStyleInterface::ORIGINAL_IMAGE + * instead. + * + * @see https://www.drupal.org/node/2831620 + */ const RESPONSIVE_IMAGE_ORIGINAL_IMAGE = '_original image_'; /** @@ -28,25 +44,25 @@ function responsive_image_help($route_name, RouteMatchInterface $route_match) { case 'help.page.responsive_image': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Responsive Image module provides an image formatter that allows browsers to select which image file to display based on media queries or which image file types the browser supports, using the HTML 5 picture and source elements and/or the sizes, srcset and type attributes. For more information, see the online documentation for the Responsive Image module.', array( ':responsive_image' => 'https://www.drupal.org/documentation/modules/responsive_image')) . '

    '; + $output .= '

    ' . t('The Responsive Image module provides an image formatter that allows browsers to select which image file to display based on media queries or which image file types the browser supports, using the HTML 5 picture and source elements and/or the sizes, srcset and type attributes. For more information, see the online documentation for the Responsive Image module.', [':responsive_image' => 'https://www.drupal.org/documentation/modules/responsive_image']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Defining responsive image styles') . '
    '; - $output .= '
    ' . t('By creating responsive image styles you define which options the browser has in selecting which image file to display. In most cases this means providing different image sizes based on the viewport size. On the Responsive image styles page, click Add responsive image style to create a new style. First choose a label, a fallback image style and a breakpoint group and click Save.', array(':responsive_image_style' => \Drupal::url('entity.responsive_image_style.collection'))) . '
    '; + $output .= '
    ' . t('By creating responsive image styles you define which options the browser has in selecting which image file to display. In most cases this means providing different image sizes based on the viewport size. On the Responsive image styles page, click Add responsive image style to create a new style. First choose a label, a fallback image style and a breakpoint group and click Save.', [':responsive_image_style' => \Drupal::url('entity.responsive_image_style.collection')]) . '
    '; $output .= '
    '; $output .= '
    ' . t('Fallback image style') . '
    '; $output .= '
    ' . t('The fallback image style is typically the smallest size image you expect to appear in this space. Because the responsive images module uses the Picturefill library so that responsive images can work in older browsers, the fallback image should only appear on a site if an error occurs.') . '
    '; $output .= '
    ' . t('Breakpoint groups: viewport sizing vs art direction') . '
    '; - $output .= '
    ' . t('The breakpoint group typically only needs a single breakpoint with an empty media query in order to do viewport sizing. Multiple breakpoints are used for changing the crop or aspect ratio of images at different viewport sizes, which is often referred to as art direction. Once you select a breakpoint group, you can choose which breakpoints to use for the responsive image style. By default, the option do not use this breakpoint is selected for each breakpoint. See the help page of the Breakpoint module for more information.', array(':breakpoint_help' => \Drupal::url('help.page', array('name' => 'breakpoint')))) . '
    '; + $output .= '
    ' . t('The breakpoint group typically only needs a single breakpoint with an empty media query in order to do viewport sizing. Multiple breakpoints are used for changing the crop or aspect ratio of images at different viewport sizes, which is often referred to as art direction. Once you select a breakpoint group, you can choose which breakpoints to use for the responsive image style. By default, the option do not use this breakpoint is selected for each breakpoint. See the help page of the Breakpoint module for more information.', [':breakpoint_help' => \Drupal::url('help.page', ['name' => 'breakpoint'])]) . '
    '; $output .= '
    ' . t('Breakpoint settings: sizes vs image styles') . '
    '; $output .= '
    ' . t('While you have the option to provide only one image style per breakpoint, the sizes option allows you to provide more options to browsers as to which image file it can display, even when using multiple breakpoints for art direction. Breakpoints are defined in the configuration files of the theme.') . '
    '; $output .= '
    ' . t('Sizes field') . '
    '; $output .= '
    ' . t('Once the sizes option is selected, you can let the browser know the size of this image in relation to the site layout, using the Sizes field. For a hero image that always fills the entire screen, you could simply enter 100vw, which means 100% of the viewport width. For an image that fills 90% of the screen for small viewports, but only fills 40% of the screen when the viewport is larger than 40em (typically 640px), you could enter "(min-width: 40em) 40vw, 90vw" in the Sizes field. The last item in the comma-separated list is the smallest viewport size: other items in the comma-separated list should have a media condition paired with an image width. Media conditions are similar to a media query, often a min-width paired with a viewport width using em or px units: e.g. (min-width: 640px) or (min-width: 40em). This is paired with the image width at that viewport size using px, em or vw units. The vw unit is viewport width and is used instead of a percentage because the percentage always refers to the width of the entire viewport.') . '
    '; $output .= '
    ' . t('Image styles for sizes') . '
    '; - $output .= '
    ' . t('Below the Sizes field you can choose multiple image styles so the browser can choose the best image file size to fill the space defined in the Sizes field. Typically you will want to use image styles that resize your image to have options that range from the smallest px width possible for the space the image will appear in to the largest px width possible, with a variety of widths in between. You may want to provide image styles with widths that are 1.5x to 2x the space available in the layout to account for high resolution screens. Image styles can be defined on the Image styles page that is provided by the Image module.', array(':image_styles' => \Drupal::url('entity.image_style.collection'), ':image_help' => \Drupal::url('help.page', array('name' => 'image')))) . '
    '; + $output .= '
    ' . t('Below the Sizes field you can choose multiple image styles so the browser can choose the best image file size to fill the space defined in the Sizes field. Typically you will want to use image styles that resize your image to have options that range from the smallest px width possible for the space the image will appear in to the largest px width possible, with a variety of widths in between. You may want to provide image styles with widths that are 1.5x to 2x the space available in the layout to account for high resolution screens. Image styles can be defined on the Image styles page that is provided by the Image module.', [':image_styles' => \Drupal::url('entity.image_style.collection'), ':image_help' => \Drupal::url('help.page', ['name' => 'image'])]) . '
    '; $output .= '
    '; $output .= '
    ' . t('Using responsive image styles in Image fields') . '
    '; - $output .= '
    ' . t('After defining responsive image styles, you can use them in the display settings for your Image fields, so that the site displays responsive images using the HTML5 picture tag. Open the Manage display page for the entity type (content type, taxonomy vocabulary, etc.) that the Image field is attached to. Choose the format Responsive image, click the Edit icon, and select one of the responsive image styles that you have created. For general information on how to manage fields and their display see the Field UI module help page. For background information about entities and fields see the Field module help page.', array(':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#', ':field_help' => \Drupal::url('help.page', array('name' => 'field')))) . '
    '; + $output .= '
    ' . t('After defining responsive image styles, you can use them in the display settings for your Image fields, so that the site displays responsive images using the HTML5 picture tag. Open the Manage display page for the entity type (content type, taxonomy vocabulary, etc.) that the Image field is attached to. Choose the format Responsive image, click the Edit icon, and select one of the responsive image styles that you have created. For general information on how to manage fields and their display see the Field UI module help page. For background information about entities and fields see the Field module help page.', [':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#', ':field_help' => \Drupal::url('help.page', ['name' => 'field'])]) . '
    '; $output .= '
    '; return $output; @@ -59,25 +75,25 @@ function responsive_image_help($route_name, RouteMatchInterface $route_match) { * Implements hook_theme(). */ function responsive_image_theme() { - return array( - 'responsive_image' => array( - 'variables' => array( + return [ + 'responsive_image' => [ + 'variables' => [ 'uri' => NULL, - 'attributes' => array(), - 'responsive_image_style_id' => array(), + 'attributes' => [], + 'responsive_image_style_id' => [], 'height' => NULL, 'width' => NULL, - ), - ), - 'responsive_image_formatter' => array( - 'variables' => array( + ], + ], + 'responsive_image_formatter' => [ + 'variables' => [ 'item' => NULL, 'item_attributes' => NULL, 'url' => NULL, 'responsive_image_style_id' => NULL, - ), - ), - ); + ], + ], + ]; } /** @@ -98,18 +114,18 @@ function template_preprocess_responsive_image_formatter(&$variables) { // provided in the responsive image formatter. $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']); if ($responsive_image_style) { - $variables['responsive_image'] = array( + $variables['responsive_image'] = [ '#type' => 'responsive_image', '#responsive_image_style_id' => $variables['responsive_image_style_id'], - ); + ]; } else { - $variables['responsive_image'] = array( + $variables['responsive_image'] = [ '#theme' => 'image', - ); + ]; } $item = $variables['item']; - $attributes = array(); + $attributes = []; // Do not output an empty 'title' attribute. if (Unicode::strlen($item->title) != 0) { $attributes['title'] = $item->title; @@ -126,7 +142,7 @@ function template_preprocess_responsive_image_formatter(&$variables) { $variables['responsive_image']['#uri'] = $item->uri; } - foreach (array('width', 'height') as $key) { + foreach (['width', 'height'] as $key) { $variables['responsive_image']["#$key"] = $item->$key; } $variables['responsive_image']['#attributes'] = $attributes; @@ -189,25 +205,21 @@ function template_preprocess_responsive_image(&$variables) { $variables['attributes'][$attribute] = $value; } } - $variables['img_element'] = array( + $variables['img_element'] = [ '#theme' => 'image', '#uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $variables['uri']), - ); + ]; } else { $variables['output_image_tag'] = FALSE; - // Prepare the fallback image. Use srcset in the fallback image to avoid - // unnecessary preloading of images in older browsers. See - // http://scottjehl.github.io/picturefill/#using-picture and - // http://scottjehl.github.io/picturefill/#gotchas for more information. - $variables['img_element'] = array( + // Prepare the fallback image. We use the src attribute, which might cause + // double downloads in browsers that don't support the picture tag (might, + // because when picturefill kicks in, it cancels the download and triggers + // the download for the correct image). + $variables['img_element'] = [ '#theme' => 'image', - '#srcset' => array( - array( - 'uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $variables['uri']), - ), - ), - ); + '#uri' => _responsive_image_image_style_url($responsive_image_style->getFallbackImageStyle(), $variables['uri']), + ]; } if (isset($variables['attributes'])) { @@ -290,7 +302,7 @@ function responsive_image_build_source_attributes(ImageInterface $image, array $ * * * - * + * * * @endcode * @@ -319,7 +331,7 @@ function responsive_image_build_source_attributes(ImageInterface $image, array $ * * * - * + * * * @endcode * This way a browser can decide which tag is preferred based on the @@ -397,9 +409,9 @@ function _responsive_image_build_source_attributes(array $variables, BreakpointI $height = $variables['height']; } $extension = pathinfo($variables['uri'], PATHINFO_EXTENSION); - $sizes = array(); - $srcset = array(); - $derivative_mime_types = array(); + $sizes = []; + $srcset = []; + $derivative_mime_types = []; foreach ($multipliers as $multiplier => $image_style_mapping) { switch ($image_style_mapping['image_mapping_type']) { // Create a tag with the 'sizes' attribute. @@ -407,7 +419,7 @@ function _responsive_image_build_source_attributes(array $variables, BreakpointI // Loop through the image styles for this breakpoint and multiplier. foreach ($image_style_mapping['image_mapping']['sizes_image_styles'] as $image_style_name) { // Get the dimensions. - $dimensions = responsive_image_get_image_dimensions($image_style_name, array('width' => $width, 'height' => $height), $variables['uri']); + $dimensions = responsive_image_get_image_dimensions($image_style_name, ['width' => $width, 'height' => $height], $variables['uri']); // Get MIME type. $derivative_mime_type = responsive_image_get_mime_type($image_style_name, $extension); $derivative_mime_types[] = $derivative_mime_type; @@ -443,9 +455,9 @@ function _responsive_image_build_source_attributes(array $variables, BreakpointI } // Sort the srcset from small to large image width or multiplier. ksort($srcset); - $source_attributes = new Attribute(array( + $source_attributes = new Attribute([ 'srcset' => implode(', ', array_unique($srcset)), - )); + ]); $media_query = trim($breakpoint->getMediaQuery()); if (!empty($media_query)) { $source_attributes->setAttribute('media', $media_query); @@ -478,10 +490,10 @@ function _responsive_image_build_source_attributes(array $variables, BreakpointI function responsive_image_get_image_dimensions($image_style_name, array $dimensions, $uri) { // Determine the dimensions of the styled image. if ($image_style_name == RESPONSIVE_IMAGE_EMPTY_IMAGE) { - $dimensions = array( + $dimensions = [ 'width' => 1, 'height' => 1, - ); + ]; } elseif ($entity = ImageStyle::load($image_style_name)) { $entity->transformDimensions($dimensions, $uri); diff --git a/core/modules/responsive_image/responsive_image.post_update.php b/core/modules/responsive_image/responsive_image.post_update.php index d6767f72..de9424f0 100644 --- a/core/modules/responsive_image/responsive_image.post_update.php +++ b/core/modules/responsive_image/responsive_image.post_update.php @@ -8,17 +8,12 @@ use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\Entity\EntityViewDisplay; -/** - * @addtogroup updates-8.1.x - * @{ - */ - /** * Make responsive image formatters dependent on responsive image styles. */ function responsive_image_post_update_recreate_dependencies() { $displays = EntityViewDisplay::loadMultiple(); - array_walk($displays, function(EntityViewDisplayInterface $entity_view_display) { + array_walk($displays, function (EntityViewDisplayInterface $entity_view_display) { $old_dependencies = $entity_view_display->getDependencies(); $new_dependencies = $entity_view_display->calculateDependencies()->getDependencies(); if ($old_dependencies !== $new_dependencies) { @@ -26,7 +21,3 @@ function responsive_image_post_update_recreate_dependencies() { } }); } - -/** - * @} End of "addtogroup updates-8.1.x". - */ diff --git a/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php b/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php index fabfc60d..5ad9d953 100644 --- a/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php +++ b/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php @@ -68,7 +68,7 @@ class ResponsiveImageStyle extends ConfigEntityBase implements ResponsiveImageSt * * @var array */ - protected $image_style_mappings = array(); + protected $image_style_mappings = []; /** * @var array @@ -103,18 +103,18 @@ public function addImageStyleMapping($breakpoint_id, $multiplier, array $image_s // If there is an existing mapping, overwrite it. foreach ($this->image_style_mappings as &$mapping) { if ($mapping['breakpoint_id'] === $breakpoint_id && $mapping['multiplier'] === $multiplier) { - $mapping = array( + $mapping = [ 'breakpoint_id' => $breakpoint_id, 'multiplier' => $multiplier, - ) + $image_style_mapping; + ] + $image_style_mapping; $this->keyedImageStyleMappings = NULL; return $this; } } - $this->image_style_mappings[] = array( + $this->image_style_mappings[] = [ 'breakpoint_id' => $breakpoint_id, 'multiplier' => $multiplier, - ) + $image_style_mapping; + ] + $image_style_mapping; $this->keyedImageStyleMappings = NULL; return $this; } @@ -132,7 +132,7 @@ public function hasImageStyleMappings() { */ public function getKeyedImageStyleMappings() { if (!$this->keyedImageStyleMappings) { - $this->keyedImageStyleMappings = array(); + $this->keyedImageStyleMappings = []; foreach ($this->image_style_mappings as $mapping) { if (!static::isEmptyImageStyleMapping($mapping)) { $this->keyedImageStyleMappings[$mapping['breakpoint_id']][$mapping['multiplier']] = $mapping; @@ -188,7 +188,7 @@ public function getFallbackImageStyle() { * {@inheritdoc} */ public function removeImageStyleMappings() { - $this->image_style_mappings = array(); + $this->image_style_mappings = []; $this->keyedImageStyleMappings = NULL; return $this; } diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php index ff91e686..6d9b7fa2 100644 --- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php +++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php @@ -23,6 +23,9 @@ * label = @Translation("Responsive image"), * field_types = { * "image", + * }, + * quickedit = { + * "editor" = "image" * } * ) */ @@ -112,17 +115,17 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public static function defaultSettings() { - return array( + return [ 'responsive_image_style' => '', 'image_link' => '', - ) + parent::defaultSettings(); + ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { - $responsive_image_options = array(); + $responsive_image_options = []; $responsive_image_styles = $this->responsiveImageStyleStorage->loadMultiple(); if ($responsive_image_styles && !empty($responsive_image_styles)) { foreach ($responsive_image_styles as $machine_name => $responsive_image_style) { @@ -132,29 +135,29 @@ public function settingsForm(array $form, FormStateInterface $form_state) { } } - $elements['responsive_image_style'] = array( + $elements['responsive_image_style'] = [ '#title' => t('Responsive image style'), '#type' => 'select', '#default_value' => $this->getSetting('responsive_image_style'), '#required' => TRUE, '#options' => $responsive_image_options, - '#description' => array( + '#description' => [ '#markup' => $this->linkGenerator->generate($this->t('Configure Responsive Image Styles'), new Url('entity.responsive_image_style.collection')), '#access' => $this->currentUser->hasPermission('administer responsive image styles'), - ), - ); + ], + ]; - $link_types = array( + $link_types = [ 'content' => t('Content'), 'file' => t('File'), - ); - $elements['image_link'] = array( + ]; + $elements['image_link'] = [ '#title' => t('Link image to'), '#type' => 'select', '#default_value' => $this->getSetting('image_link'), '#empty_option' => t('Nothing'), '#options' => $link_types, - ); + ]; return $elements; } @@ -163,16 +166,16 @@ public function settingsForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function settingsSummary() { - $summary = array(); + $summary = []; $responsive_image_style = $this->responsiveImageStyleStorage->load($this->getSetting('responsive_image_style')); if ($responsive_image_style) { - $summary[] = t('Responsive image style: @responsive_image_style', array('@responsive_image_style' => $responsive_image_style->label())); + $summary[] = t('Responsive image style: @responsive_image_style', ['@responsive_image_style' => $responsive_image_style->label()]); - $link_types = array( + $link_types = [ 'content' => t('Linked to content'), 'file' => t('Linked to file'), - ); + ]; // Display this setting only if image is linked. if (isset($link_types[$this->getSetting('image_link')])) { $summary[] = $link_types[$this->getSetting('image_link')]; @@ -189,7 +192,7 @@ public function settingsSummary() { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $elements = array(); + $elements = []; $files = $this->getEntitiesToView($items, $langcode); // Early opt-out if the field is empty. @@ -211,7 +214,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { // Collect cache tags to be added for each item in the field. $responsive_image_style = $this->responsiveImageStyleStorage->load($this->getSetting('responsive_image_style')); - $image_styles_to_load = array(); + $image_styles_to_load = []; $cache_tags = []; if ($responsive_image_style) { $cache_tags = Cache::mergeTags($cache_tags, $responsive_image_style->getCacheTags()); @@ -234,16 +237,16 @@ public function viewElements(FieldItemListInterface $items, $langcode) { $item_attributes = $item->_attributes; unset($item->_attributes); - $elements[$delta] = array( + $elements[$delta] = [ '#theme' => 'responsive_image_formatter', '#item' => $item, '#item_attributes' => $item_attributes, '#responsive_image_style_id' => $responsive_image_style ? $responsive_image_style->id() : '', '#url' => $url, - '#cache' => array( + '#cache' => [ 'tags' => $cache_tags, - ), - ); + ], + ]; } return $elements; } diff --git a/core/modules/responsive_image/src/ResponsiveImageStyleForm.php b/core/modules/responsive_image/src/ResponsiveImageStyleForm.php index 3e5b051a..8ad0e6a6 100644 --- a/core/modules/responsive_image/src/ResponsiveImageStyleForm.php +++ b/core/modules/responsive_image/src/ResponsiveImageStyleForm.php @@ -51,32 +51,32 @@ public function __construct(BreakpointManagerInterface $breakpoint_manager) { */ public function form(array $form, FormStateInterface $form_state) { if ($this->operation == 'duplicate') { - $form['#title'] = $this->t('Duplicate responsive image style @label', array('@label' => $this->entity->label())); + $form['#title'] = $this->t('Duplicate responsive image style @label', ['@label' => $this->entity->label()]); $this->entity = $this->entity->createDuplicate(); } if ($this->operation == 'edit') { - $form['#title'] = $this->t('Edit responsive image style @label', array('@label' => $this->entity->label())); + $form['#title'] = $this->t('Edit responsive image style @label', ['@label' => $this->entity->label()]); } /** @var \Drupal\responsive_image\ResponsiveImageStyleInterface $responsive_image_style */ $responsive_image_style = $this->entity; - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $responsive_image_style->label(), '#description' => $this->t("Example: 'Hero image' or 'Author image'."), '#required' => TRUE, - ); - $form['id'] = array( + ]; + $form['id'] = [ '#type' => 'machine_name', '#default_value' => $responsive_image_style->id(), - '#machine_name' => array( + '#machine_name' => [ 'exists' => '\Drupal\responsive_image\Entity\ResponsiveImageStyle::load', - 'source' => array('label'), - ), + 'source' => ['label'], + ], '#disabled' => (bool) $responsive_image_style->id() && $this->operation != 'duplicate', - ); + ]; $image_styles = image_style_options(TRUE); $image_styles[RESPONSIVE_IMAGE_ORIGINAL_IMAGE] = $this->t('- None (original image) -'); @@ -89,25 +89,25 @@ public function form(array $form, FormStateInterface $form_state) { $description = $this->t('Select a breakpoint group from the installed themes and modules.'); } - $form['breakpoint_group'] = array( + $form['breakpoint_group'] = [ '#type' => 'select', '#title' => $this->t('Breakpoint group'), '#default_value' => $responsive_image_style->getBreakpointGroup() ?: 'responsive_image', '#options' => $this->breakpointManager->getGroups(), '#required' => TRUE, '#description' => $description, - '#ajax' => array( + '#ajax' => [ 'callback' => '::breakpointMappingFormAjax', 'wrapper' => 'responsive-image-style-breakpoints-wrapper', - ), - ); + ], + ]; - $form['keyed_styles'] = array( + $form['keyed_styles'] = [ '#type' => 'container', - '#attributes' => array( + '#attributes' => [ 'id' => 'responsive-image-style-breakpoints-wrapper', - ), - ); + ], + ]; // By default, breakpoints are ordered from smallest weight to largest: // the smallest weight is expected to have the smallest breakpoint width, @@ -119,69 +119,69 @@ public function form(array $form, FormStateInterface $form_state) { foreach ($breakpoints as $breakpoint_id => $breakpoint) { foreach ($breakpoint->getMultipliers() as $multiplier) { $label = $multiplier . ' ' . $breakpoint->getLabel() . ' [' . $breakpoint->getMediaQuery() . ']'; - $form['keyed_styles'][$breakpoint_id][$multiplier] = array( + $form['keyed_styles'][$breakpoint_id][$multiplier] = [ '#type' => 'details', '#title' => $label, - ); + ]; $image_style_mapping = $responsive_image_style->getImageStyleMapping($breakpoint_id, $multiplier); if (\Drupal::moduleHandler()->moduleExists('help')) { - $description = $this->t('See the Responsive Image help page for information on the sizes attribute.', array(':responsive_image_help' => \Drupal::url('help.page', array('name' => 'responsive_image')))); + $description = $this->t('See the Responsive Image help page for information on the sizes attribute.', [':responsive_image_help' => \Drupal::url('help.page', ['name' => 'responsive_image'])]); } else { $description = $this->t('Enable the Help module for more information on the sizes attribute.'); } - $form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping_type'] = array( + $form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping_type'] = [ '#title' => $this->t('Type'), '#type' => 'radios', - '#options' => array( + '#options' => [ 'sizes' => $this->t('Select multiple image styles and use the sizes attribute.'), 'image_style' => $this->t('Select a single image style.'), '_none' => $this->t('Do not use this breakpoint.'), - ), + ], '#default_value' => isset($image_style_mapping['image_mapping_type']) ? $image_style_mapping['image_mapping_type'] : '_none', '#description' => $description, - ); - $form['keyed_styles'][$breakpoint_id][$multiplier]['image_style'] = array( + ]; + $form['keyed_styles'][$breakpoint_id][$multiplier]['image_style'] = [ '#type' => 'select', '#title' => $this->t('Image style'), '#options' => $image_styles, '#default_value' => isset($image_style_mapping['image_mapping']) && is_string($image_style_mapping['image_mapping']) ? $image_style_mapping['image_mapping'] : '', '#description' => $this->t('Select an image style for this breakpoint.'), - '#states' => array( - 'visible' => array( - ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'image_style'), - ), - ), - ); - $form['keyed_styles'][$breakpoint_id][$multiplier]['sizes'] = array( + '#states' => [ + 'visible' => [ + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => ['value' => 'image_style'], + ], + ], + ]; + $form['keyed_styles'][$breakpoint_id][$multiplier]['sizes'] = [ '#type' => 'textfield', '#title' => $this->t('Sizes'), '#default_value' => isset($image_style_mapping['image_mapping']['sizes']) ? $image_style_mapping['image_mapping']['sizes'] : '100vw', '#description' => $this->t('Enter the value for the sizes attribute, for example: %example_sizes.', ['%example_sizes' => '(min-width:700px) 700px, 100vw']), - '#states' => array( - 'visible' => array( - ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'sizes'), - ), - 'required' => array( - ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'sizes'), - ), - ), - ); - $form['keyed_styles'][$breakpoint_id][$multiplier]['sizes_image_styles'] = array( + '#states' => [ + 'visible' => [ + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => ['value' => 'sizes'], + ], + 'required' => [ + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => ['value' => 'sizes'], + ], + ], + ]; + $form['keyed_styles'][$breakpoint_id][$multiplier]['sizes_image_styles'] = [ '#title' => $this->t('Image styles'), '#type' => 'checkboxes', - '#options' => array_diff_key($image_styles, array('' => '')), + '#options' => array_diff_key($image_styles, ['' => '']), '#description' => $this->t('Select image styles with widths that range from the smallest amount of space this image will take up in the layout to the largest, bearing in mind that high resolution screens will need images 1.5x to 2x larger.'), - '#default_value' => isset($image_style_mapping['image_mapping']['sizes_image_styles']) ? $image_style_mapping['image_mapping']['sizes_image_styles'] : array(), - '#states' => array( - 'visible' => array( - ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'sizes'), - ), - 'required' => array( - ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'sizes'), - ), - ), - ); + '#default_value' => isset($image_style_mapping['image_mapping']['sizes_image_styles']) ? $image_style_mapping['image_mapping']['sizes_image_styles'] : [], + '#states' => [ + 'visible' => [ + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => ['value' => 'sizes'], + ], + 'required' => [ + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => ['value' => 'sizes'], + ], + ], + ]; // Expand the details if "do not use this breakpoint" was not selected. if ($form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping_type']['#default_value'] != '_none') { @@ -190,14 +190,14 @@ public function form(array $form, FormStateInterface $form_state) { } } - $form['fallback_image_style'] = array( + $form['fallback_image_style'] = [ '#title' => $this->t('Fallback image style'), '#type' => 'select', '#default_value' => $responsive_image_style->getFallbackImageStyle(), '#options' => $image_styles, '#required' => TRUE, '#description' => t('Select the smallest image style you expect to appear in this space. The fallback image style should only appear on the site if an error occurs.'), - ); + ]; $form['#tree'] = TRUE; @@ -252,20 +252,20 @@ public function save(array $form, FormStateInterface $form_state) { foreach ($form_state->getValue('keyed_styles') as $breakpoint_id => $multipliers) { foreach ($multipliers as $multiplier => $image_style_mapping) { if ($image_style_mapping['image_mapping_type'] === 'sizes') { - $mapping = array( + $mapping = [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => $image_style_mapping['sizes'], 'sizes_image_styles' => array_keys(array_filter($image_style_mapping['sizes_image_styles'])), - ) - ); + ] + ]; $responsive_image_style->addImageStyleMapping($breakpoint_id, $multiplier, $mapping); } elseif ($image_style_mapping['image_mapping_type'] === 'image_style') { - $mapping = array( + $mapping = [ 'image_mapping_type' => 'image_style', 'image_mapping' => $image_style_mapping['image_style'], - ); + ]; $responsive_image_style->addImageStyleMapping($breakpoint_id, $multiplier, $mapping); } } @@ -273,15 +273,15 @@ public function save(array $form, FormStateInterface $form_state) { } $responsive_image_style->save(); - $this->logger('responsive_image')->notice('Responsive image style @label saved.', array('@label' => $responsive_image_style->label())); - drupal_set_message($this->t('Responsive image style %label saved.', array('%label' => $responsive_image_style->label()))); + $this->logger('responsive_image')->notice('Responsive image style @label saved.', ['@label' => $responsive_image_style->label()]); + drupal_set_message($this->t('Responsive image style %label saved.', ['%label' => $responsive_image_style->label()])); // Redirect to edit form after creating a new responsive image style or // after selecting another breakpoint group. if (!$responsive_image_style->hasImageStyleMappings()) { $form_state->setRedirect( 'entity.responsive_image_style.edit_form', - array('responsive_image_style' => $responsive_image_style->id()) + ['responsive_image_style' => $responsive_image_style->id()] ); } else { diff --git a/core/modules/responsive_image/src/ResponsiveImageStyleInterface.php b/core/modules/responsive_image/src/ResponsiveImageStyleInterface.php index a3fbc717..22679718 100644 --- a/core/modules/responsive_image/src/ResponsiveImageStyleInterface.php +++ b/core/modules/responsive_image/src/ResponsiveImageStyleInterface.php @@ -9,6 +9,16 @@ */ interface ResponsiveImageStyleInterface extends ConfigEntityInterface { + /** + * The machine name for the empty image breakpoint image style option. + */ + const EMPTY_IMAGE = '_empty image_'; + + /** + * The machine name for the original image breakpoint image style option. + */ + const ORIGINAL_IMAGE = '_original image_'; + /** * Checks if there is at least one mapping defined. * diff --git a/core/modules/responsive_image/src/ResponsiveImageStyleListBuilder.php b/core/modules/responsive_image/src/ResponsiveImageStyleListBuilder.php index 648a171b..1b4ded00 100644 --- a/core/modules/responsive_image/src/ResponsiveImageStyleListBuilder.php +++ b/core/modules/responsive_image/src/ResponsiveImageStyleListBuilder.php @@ -33,11 +33,11 @@ public function buildRow(EntityInterface $entity) { */ public function getDefaultOperations(EntityInterface $entity) { $operations = parent::getDefaultOperations($entity); - $operations['duplicate'] = array( + $operations['duplicate'] = [ 'title' => t('Duplicate'), 'weight' => 15, 'url' => $entity->urlInfo('duplicate-form'), - ); + ]; return $operations; } diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php index f5b277dc..b50d71be 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php +++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php @@ -32,7 +32,7 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase { * * @var array */ - public static $modules = array('field_ui', 'responsive_image', 'responsive_image_test_module'); + public static $modules = ['field_ui', 'responsive_image', 'responsive_image_test_module']; /** * Drupal\simpletest\WebTestBase\setUp(). @@ -41,7 +41,7 @@ protected function setUp() { parent::setUp(); // Create user. - $this->adminUser = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser([ 'administer responsive images', 'access content', 'access administration pages', @@ -53,15 +53,15 @@ protected function setUp() { 'edit any article content', 'delete any article content', 'administer image styles' - )); + ]); $this->drupalLogin($this->adminUser); // Add responsive image style. - $this->responsiveImgStyle = ResponsiveImageStyle::create(array( + $this->responsiveImgStyle = ResponsiveImageStyle::create([ 'id' => 'style_one', 'label' => 'Style One', 'breakpoint_group' => 'responsive_image_test_module', 'fallback_image_style' => 'large', - )); + ]); } /** @@ -78,7 +78,7 @@ public function testResponsiveImageFieldFormattersPublic() { public function testResponsiveImageFieldFormattersPrivate() { $this->addTestImageStyleMappings(); // Remove access content permission from anonymous users. - user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array('access content' => FALSE)); + user_role_change_permissions(RoleInterface::ANONYMOUS_ID, ['access content' => FALSE]); $this->doTestResponsiveImageFieldFormatters('private'); } @@ -99,56 +99,56 @@ public function testResponsiveImageFieldFormattersEmptyStyle() { protected function addTestImageStyleMappings($empty_styles = FALSE) { if ($empty_styles) { $this->responsiveImgStyle - ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => '', - )) - ->addImageStyleMapping('responsive_image_test_module.narrow', '1x', array( + ]) + ->addImageStyleMapping('responsive_image_test_module.narrow', '1x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width: 700px) 700px, 100vw', - 'sizes_image_styles' => array(), - ), - )) - ->addImageStyleMapping('responsive_image_test_module.wide', '1x', array( + 'sizes_image_styles' => [], + ], + ]) + ->addImageStyleMapping('responsive_image_test_module.wide', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => '', - )) + ]) ->save(); } else { $this->responsiveImgStyle // Test the output of an empty image. - ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => RESPONSIVE_IMAGE_EMPTY_IMAGE, - )) + ]) // Test the output with a 1.5x multiplier. - ->addImageStyleMapping('responsive_image_test_module.mobile', '1.5x', array( + ->addImageStyleMapping('responsive_image_test_module.mobile', '1.5x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )) + ]) // Test the output of the 'sizes' attribute. - ->addImageStyleMapping('responsive_image_test_module.narrow', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.narrow', '1x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width: 700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large', 'medium', - ), - ), - )) + ], + ], + ]) // Test the normal output of mapping to an image style. - ->addImageStyleMapping('responsive_image_test_module.wide', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.wide', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )) + ]) // Test the output of the original image. - ->addImageStyleMapping('responsive_image_test_module.wide', '3x', array( + ->addImageStyleMapping('responsive_image_test_module.wide', '3x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => RESPONSIVE_IMAGE_ORIGINAL_IMAGE, - )) + ]) ->save(); } } @@ -169,7 +169,7 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $renderer = $this->container->get('renderer'); $node_storage = $this->container->get('entity.manager')->getStorage('node'); $field_name = Unicode::strtolower($this->randomMachineName()); - $this->createImageField($field_name, 'article', array('uri_scheme' => $scheme)); + $this->createImageField($field_name, 'article', ['uri_scheme' => $scheme]); // Create a new node with an image attached. Make sure we use a large image // so the scale effects of the image styles always have an effect. $test_image = current($this->drupalGetTestFiles('image', 39325)); @@ -178,26 +178,26 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $alt = $this->randomMachineName(); $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $alt); - $node_storage->resetCache(array($nid)); + $node_storage->resetCache([$nid]); $node = $node_storage->load($nid); // Test that the default formatter is being used. $image_uri = File::load($node->{$field_name}->target_id)->getFileUri(); - $image = array( + $image = [ '#theme' => 'image', '#uri' => $image_uri, '#width' => 360, '#height' => 240, '#alt' => $alt, - ); + ]; $default_output = str_replace("\n", NULL, $renderer->renderRoot($image)); $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.'); // Test field not being configured. This should not cause a fatal error. - $display_options = array( + $display_options = [ 'type' => 'responsive_image_test', 'settings' => ResponsiveImageFormatter::defaultSettings(), - ); + ]; $display = $this->container->get('entity.manager') ->getStorage('entity_view_display') ->load('node.article.default'); @@ -215,13 +215,13 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $this->drupalGet('node/' . $nid); // Test theme function for responsive image, but using the test formatter. - $display_options = array( + $display_options = [ 'type' => 'responsive_image_test', - 'settings' => array( + 'settings' => [ 'image_link' => 'file', 'responsive_image_style' => 'style_one', - ), - ); + ], + ]; $display = entity_get_display('node', 'article', 'default'); $display->setComponent($field_name, $display_options) ->save(); @@ -229,13 +229,13 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = $this->drupalGet('node/' . $nid); // Use the responsive image formatter linked to file formatter. - $display_options = array( + $display_options = [ 'type' => 'responsive_image', - 'settings' => array( + 'settings' => [ 'image_link' => 'file', 'responsive_image_style' => 'style_one', - ), - ); + ], + ]; $display = entity_get_display('node', 'article', 'default'); $display->setComponent($field_name, $display_options) ->save(); @@ -312,15 +312,11 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles = // Test the fallback image style. $image = \Drupal::service('image.factory')->get($image_uri); - $fallback_image = array( + $fallback_image = [ '#theme' => 'image', '#alt' => $alt, - '#srcset' => array( - array( - 'uri' => file_url_transform_relative($large_style->buildUrl($image->getSource())), - ), - ), - ); + '#uri' => file_url_transform_relative($large_style->buildUrl($image->getSource())), + ]; // The image.html.twig template has a newline after the tag but // responsive-image.html.twig doesn't have one after the fallback image, so // we remove it here. @@ -359,32 +355,32 @@ public function testResponsiveImageFieldFormattersLinkToNode() { public function testResponsiveImageFieldFormattersEmptyMediaQuery() { $this->responsiveImgStyle // Test the output of an empty media query. - ->addImageStyleMapping('responsive_image_test_module.empty', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.empty', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => RESPONSIVE_IMAGE_EMPTY_IMAGE, - )) + ]) // Test the output with a 1.5x multiplier. - ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )) + ]) ->save(); $node_storage = $this->container->get('entity.manager')->getStorage('node'); $field_name = Unicode::strtolower($this->randomMachineName()); - $this->createImageField($field_name, 'article', array('uri_scheme' => 'public')); + $this->createImageField($field_name, 'article', ['uri_scheme' => 'public']); // Create a new node with an image attached. $test_image = current($this->drupalGetTestFiles('image')); $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $this->randomMachineName()); - $node_storage->resetCache(array($nid)); + $node_storage->resetCache([$nid]); // Use the responsive image formatter linked to file formatter. - $display_options = array( + $display_options = [ 'type' => 'responsive_image', - 'settings' => array( + 'settings' => [ 'image_link' => '', 'responsive_image_style' => 'style_one', - ), - ); + ], + ]; $display = entity_get_display('node', 'article', 'default'); $display->setComponent($field_name, $display_options) ->save(); @@ -408,31 +404,31 @@ public function testResponsiveImageFieldFormattersEmptyMediaQuery() { public function testResponsiveImageFieldFormattersOneSource() { $this->responsiveImgStyle // Test the output of an empty media query. - ->addImageStyleMapping('responsive_image_test_module.empty', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.empty', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'medium', - )) - ->addImageStyleMapping('responsive_image_test_module.empty', '2x', array( + ]) + ->addImageStyleMapping('responsive_image_test_module.empty', '2x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )) + ]) ->save(); $node_storage = $this->container->get('entity.manager')->getStorage('node'); $field_name = Unicode::strtolower($this->randomMachineName()); - $this->createImageField($field_name, 'article', array('uri_scheme' => 'public')); + $this->createImageField($field_name, 'article', ['uri_scheme' => 'public']); // Create a new node with an image attached. $test_image = current($this->drupalGetTestFiles('image')); $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $this->randomMachineName()); - $node_storage->resetCache(array($nid)); + $node_storage->resetCache([$nid]); // Use the responsive image formatter linked to file formatter. - $display_options = array( + $display_options = [ 'type' => 'responsive_image', - 'settings' => array( + 'settings' => [ 'image_link' => '', 'responsive_image_style' => 'style_one', - ), - ); + ], + ]; $display = entity_get_display('node', 'article', 'default'); $display->setComponent($field_name, $display_options) ->save(); @@ -456,19 +452,19 @@ public function testResponsiveImageFieldFormattersOneSource() { */ private function assertResponsiveImageFieldFormattersLink($link_type) { $field_name = Unicode::strtolower($this->randomMachineName()); - $field_settings = array('alt_field_required' => 0); - $this->createImageField($field_name, 'article', array('uri_scheme' => 'public'), $field_settings); + $field_settings = ['alt_field_required' => 0]; + $this->createImageField($field_name, 'article', ['uri_scheme' => 'public'], $field_settings); // Create a new node with an image attached. $test_image = current($this->drupalGetTestFiles('image')); // Test the image linked to file formatter. - $display_options = array( + $display_options = [ 'type' => 'responsive_image', - 'settings' => array( + 'settings' => [ 'image_link' => $link_type, 'responsive_image_style' => 'style_one', - ), - ); + ], + ]; entity_get_display('node', 'article', 'default') ->setComponent($field_name, $display_options) ->save(); @@ -479,17 +475,17 @@ private function assertResponsiveImageFieldFormattersLink($link_type) { $this->assertPattern('/picture/'); $nid = $this->uploadNodeImage($test_image, $field_name, 'article'); - $this->container->get('entity.manager')->getStorage('node')->resetCache(array($nid)); + $this->container->get('entity.manager')->getStorage('node')->resetCache([$nid]); $node = Node::load($nid); // Use the responsive image formatter linked to file formatter. - $display_options = array( + $display_options = [ 'type' => 'responsive_image', - 'settings' => array( + 'settings' => [ 'image_link' => $link_type, 'responsive_image_style' => 'style_one', - ), - ); + ], + ]; entity_get_display('node', 'article', 'default') ->setComponent($field_name, $display_options) ->save(); diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldUiTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldUiTest.php index 8b1030f3..c879e72c 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldUiTest.php +++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldUiTest.php @@ -2,7 +2,6 @@ namespace Drupal\responsive_image\Tests; - use Drupal\field_ui\Tests\FieldUiTestTrait; use Drupal\simpletest\WebTestBase; use Drupal\responsive_image\Entity\ResponsiveImageStyle; @@ -21,7 +20,7 @@ class ResponsiveImageFieldUiTest extends WebTestBase { * * @var array */ - public static $modules = array('node', 'field_ui', 'image', 'responsive_image', 'responsive_image_test_module', 'block'); + public static $modules = ['node', 'field_ui', 'image', 'responsive_image', 'responsive_image_test_module', 'block']; /** * {@inheritdoc} @@ -30,19 +29,19 @@ protected function setUp() { parent::setUp(); $this->drupalPlaceBlock('system_breadcrumb_block'); // Create a test user. - $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'bypass node access')); + $admin_user = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'bypass node access']); $this->drupalLogin($admin_user); // Create content type, with underscores. $type_name = strtolower($this->randomMachineName(8)) . '_test'; - $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name)); + $type = $this->drupalCreateContentType(['name' => $type_name, 'type' => $type_name]); $this->type = $type->id(); } /** * Tests formatter settings. */ - function testResponsiveImageFormatterUI() { + public function testResponsiveImageFormatterUI() { $manage_fields = 'admin/structure/types/manage/' . $this->type; $manage_display = $manage_fields . '/display'; @@ -52,35 +51,39 @@ function testResponsiveImageFormatterUI() { $this->drupalGet($manage_display); // Change the formatter and check that the summary is updated. - $edit = array('fields[field_image][type]' => 'responsive_image', 'refresh_rows' => 'field_image'); - $this->drupalPostAjaxForm(NULL, $edit, array('op' => t('Refresh'))); + $edit = [ + 'fields[field_image][type]' => 'responsive_image', + 'fields[field_image][region]' => 'content', + 'refresh_rows' => 'field_image', + ]; + $this->drupalPostAjaxForm(NULL, $edit, ['op' => t('Refresh')]); $this->assertText("Select a responsive image style.", 'The expected summary is displayed.'); // Submit the form. - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertText("Select a responsive image style.", 'The expected summary is displayed.'); // Create responsive image styles. - $responsive_image_style = ResponsiveImageStyle::create(array( + $responsive_image_style = ResponsiveImageStyle::create([ 'id' => 'style_one', 'label' => 'Style One', 'breakpoint_group' => 'responsive_image_test_module', 'fallback_image_style' => 'thumbnail', - )); + ]); $responsive_image_style - ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.mobile', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )) - ->addImageStyleMapping('responsive_image_test_module.narrow', '1x', array( + ]) + ->addImageStyleMapping('responsive_image_test_module.narrow', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'medium' - )) + ]) // Test the normal output of mapping to an image style. - ->addImageStyleMapping('responsive_image_test_module.wide', '1x', array( + ->addImageStyleMapping('responsive_image_test_module.wide', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )) + ]) ->save(); \Drupal::entityManager()->clearCachedFieldDefinitions(); // Refresh the page. @@ -89,38 +92,38 @@ function testResponsiveImageFormatterUI() { // Click on the formatter settings button to open the formatter settings // form. - $this->drupalPostAjaxForm(NULL, array(), "field_image_settings_edit"); + $this->drupalPostAjaxForm(NULL, [], "field_image_settings_edit"); // Assert that the correct fields are present. - $fieldnames = array( + $fieldnames = [ 'fields[field_image][settings_edit_form][settings][responsive_image_style]', 'fields[field_image][settings_edit_form][settings][image_link]', - ); + ]; foreach ($fieldnames as $fieldname) { $this->assertField($fieldname); } - $edit = array( + $edit = [ 'fields[field_image][settings_edit_form][settings][responsive_image_style]' => 'style_one', 'fields[field_image][settings_edit_form][settings][image_link]' => 'content', - ); + ]; $this->drupalPostAjaxForm(NULL, $edit, "field_image_plugin_settings_update"); // Save the form to save the settings. - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertText('Responsive image style: Style One'); $this->assertText('Linked to content'); // Click on the formatter settings button to open the formatter settings // form. - $this->drupalPostAjaxForm(NULL, array(), "field_image_settings_edit"); - $edit = array( + $this->drupalPostAjaxForm(NULL, [], "field_image_settings_edit"); + $edit = [ 'fields[field_image][settings_edit_form][settings][responsive_image_style]' => 'style_one', 'fields[field_image][settings_edit_form][settings][image_link]' => 'file', - ); + ]; $this->drupalPostAjaxForm(NULL, $edit, "field_image_plugin_settings_update"); // Save the form to save the third party settings. - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertText('Responsive image style: Style One'); $this->assertText('Linked to file'); } diff --git a/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml index ddce7449..56a671dc 100644 --- a/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml +++ b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml @@ -6,8 +6,8 @@ package: Testing # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageAdminUITest.php similarity index 90% rename from core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php rename to core/modules/responsive_image/tests/src/Functional/ResponsiveImageAdminUITest.php index 8f8b5058..eeaf793f 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php +++ b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageAdminUITest.php @@ -1,22 +1,22 @@ assertFieldByName('breakpoint_group', 'responsive_image'); // Create a new group. - $edit = array( + $edit = [ 'label' => 'Style One', 'id' => 'style_one', 'breakpoint_group' => 'responsive_image_test_module', 'fallback_image_style' => 'thumbnail', - ); + ]; $this->drupalPostForm('admin/config/media/responsive-image-style/add', $edit, t('Save')); // Check if the new group is created. @@ -64,25 +64,25 @@ public function testResponsiveImageAdmin() { $this->assertFieldByName('breakpoint_group', 'responsive_image_test_module'); $this->assertFieldByName('fallback_image_style', 'thumbnail'); - $cases = array( - array('mobile', '1x'), - array('mobile', '2x'), - array('narrow', '1x'), - array('narrow', '2x'), - array('wide', '1x'), - array('wide', '2x'), - ); + $cases = [ + ['mobile', '1x'], + ['mobile', '2x'], + ['narrow', '1x'], + ['narrow', '2x'], + ['wide', '1x'], + ['wide', '2x'], + ]; $image_styles = array_merge( [RESPONSIVE_IMAGE_EMPTY_IMAGE, RESPONSIVE_IMAGE_ORIGINAL_IMAGE], array_keys(image_style_options(FALSE)) ); foreach ($cases as $case) { // Check if the radio buttons are present. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_mapping_type]', ''); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_mapping_type]', NULL); // Check if the image style dropdowns are present. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_style]', ''); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_style]', NULL); // Check if the sizes textfields are present. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][sizes]', ''); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][sizes]', NULL); foreach ($image_styles as $image_style_name) { // Check if the image styles are available in the dropdowns. @@ -99,7 +99,7 @@ public function testResponsiveImageAdmin() { } // Save styles for 1x variant only. - $edit = array( + $edit = [ 'label' => 'Style One', 'breakpoint_group' => 'responsive_image_test_module', 'fallback_image_style' => 'thumbnail', @@ -111,7 +111,7 @@ public function testResponsiveImageAdmin() { 'keyed_styles[responsive_image_test_module.narrow][1x][sizes_image_styles][medium]' => 'medium', 'keyed_styles[responsive_image_test_module.wide][1x][image_mapping_type]' => 'image_style', 'keyed_styles[responsive_image_test_module.wide][1x][image_style]' => 'large', - ); + ]; $this->drupalPostForm('admin/config/media/responsive-image-style/style_one', $edit, t('Save')); $this->drupalGet('admin/config/media/responsive-image-style/style_one'); @@ -135,7 +135,7 @@ public function testResponsiveImageAdmin() { // Delete the style. $this->drupalGet('admin/config/media/responsive-image-style/style_one/delete'); - $this->drupalPostForm(NULL, array(), t('Delete')); + $this->drupalPostForm(NULL, [], t('Delete')); $this->drupalGet('admin/config/media/responsive-image-style'); $this->assertText('There is no Responsive image style yet.'); } diff --git a/core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php b/core/modules/responsive_image/tests/src/Functional/Update/ResponsiveImageUpdateTest.php similarity index 89% rename from core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php rename to core/modules/responsive_image/tests/src/Functional/Update/ResponsiveImageUpdateTest.php index 1a82bb7b..17608098 100644 --- a/core/modules/responsive_image/src/Tests/Update/ResponsiveImageUpdateTest.php +++ b/core/modules/responsive_image/tests/src/Functional/Update/ResponsiveImageUpdateTest.php @@ -1,10 +1,10 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', ]; } @@ -47,7 +47,7 @@ protected function setUp() { */ public function testPostUpdateDependency() { // Installing the 'wide' responsive image style. - $wide_image_style = Yaml::decode(file_get_contents(__DIR__ . '/../../../../../profiles/standard/config/optional/responsive_image.styles.wide.yml')); + $wide_image_style = Yaml::decode(file_get_contents(__DIR__ . '/../../../../../../profiles/standard/config/optional/responsive_image.styles.wide.yml')); $this->config('responsive_image.styles.wide')->setData($wide_image_style)->save(TRUE); // Change 'field_image' formatter to a responsive image formatter. diff --git a/core/modules/responsive_image/tests/src/Unit/ResponsiveImageStyleConfigEntityUnitTest.php b/core/modules/responsive_image/tests/src/Unit/ResponsiveImageStyleConfigEntityUnitTest.php index 3911aad4..bc9663dc 100644 --- a/core/modules/responsive_image/tests/src/Unit/ResponsiveImageStyleConfigEntityUnitTest.php +++ b/core/modules/responsive_image/tests/src/Unit/ResponsiveImageStyleConfigEntityUnitTest.php @@ -39,8 +39,8 @@ class ResponsiveImageStyleConfigEntityUnitTest extends UnitTestCase { protected function setUp() { $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface'); $this->entityType->expects($this->any()) - ->method('getProvider') - ->will($this->returnValue('responsive_image')); + ->method('getProvider') + ->will($this->returnValue('responsive_image')); $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface'); $this->entityManager->expects($this->any()) @@ -101,7 +101,7 @@ public function testCalculateDependencies() { $this->breakpointManager->expects($this->any()) ->method('getGroupProviders') ->with('test_group') - ->willReturn(array('bartik' => 'theme', 'toolbar' => 'module')); + ->willReturn(['bartik' => 'theme', 'toolbar' => 'module']); $dependencies = $entity->calculateDependencies()->getDependencies(); $this->assertEquals(['toolbar'], $dependencies['module']); @@ -114,49 +114,49 @@ public function testCalculateDependencies() { * @covers ::hasImageStyleMappings */ public function testHasImageStyleMappings() { - $entity = new ResponsiveImageStyle(array()); + $entity = new ResponsiveImageStyle([]); $this->assertFalse($entity->hasImageStyleMappings()); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => '', - )); + ]); $this->assertFalse($entity->hasImageStyleMappings()); $entity->removeImageStyleMappings(); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array(), - ), - )); + 'sizes_image_styles' => [], + ], + ]); $this->assertFalse($entity->hasImageStyleMappings()); $entity->removeImageStyleMappings(); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - )); + ], + ], + ]); $this->assertFalse($entity->hasImageStyleMappings()); $entity->removeImageStyleMappings(); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); + ]); $this->assertTrue($entity->hasImageStyleMappings()); $entity->removeImageStyleMappings(); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - )); + ], + ], + ]); $this->assertTrue($entity->hasImageStyleMappings()); } @@ -165,17 +165,17 @@ public function testHasImageStyleMappings() { * @covers ::getImageStyleMapping */ public function testGetImageStyleMapping() { - $entity = new ResponsiveImageStyle(array('')); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity = new ResponsiveImageStyle(['']); + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); - $expected = array( + ]); + $expected = [ 'breakpoint_id' => 'test_breakpoint', 'multiplier' => '1x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - ); + ]; $this->assertEquals($expected, $entity->getImageStyleMapping('test_breakpoint', '1x')); $this->assertNull($entity->getImageStyleMapping('test_unknown_breakpoint', '1x')); } @@ -185,90 +185,90 @@ public function testGetImageStyleMapping() { * @covers ::getKeyedImageStyleMappings */ public function testGetKeyedImageStyleMappings() { - $entity = new ResponsiveImageStyle(array('')); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity = new ResponsiveImageStyle(['']); + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); - $entity->addImageStyleMapping('test_breakpoint', '2x', array( + ]); + $entity->addImageStyleMapping('test_breakpoint', '2x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - )); - $entity->addImageStyleMapping('test_breakpoint2', '1x', array( + ], + ], + ]); + $entity->addImageStyleMapping('test_breakpoint2', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )); - $entity->addImageStyleMapping('test_breakpoint2', '2x', array( + ]); + $entity->addImageStyleMapping('test_breakpoint2', '2x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => '_original image_', - )); + ]); - $expected = array( - 'test_breakpoint' => array( - '1x' => array( + $expected = [ + 'test_breakpoint' => [ + '1x' => [ 'breakpoint_id' => 'test_breakpoint', 'multiplier' => '1x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - ), - '2x' => array( + ], + '2x' => [ 'breakpoint_id' => 'test_breakpoint', 'multiplier' => '2x', 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - ), - ), - 'test_breakpoint2' => array( - '1x' => array( + ], + ], + ], + ], + 'test_breakpoint2' => [ + '1x' => [ 'breakpoint_id' => 'test_breakpoint2', 'multiplier' => '1x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - ), - '2x' => array( + ], + '2x' => [ 'breakpoint_id' => 'test_breakpoint2', 'multiplier' => '2x', 'image_mapping_type' => 'image_style', 'image_mapping' => '_original image_', - ), - ) - ); + ], + ] + ]; $this->assertEquals($expected, $entity->getKeyedImageStyleMappings()); // Add another mapping to ensure keyed mapping static cache is rebuilt. - $entity->addImageStyleMapping('test_breakpoint2', '2x', array( + $entity->addImageStyleMapping('test_breakpoint2', '2x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'medium', - )); - $expected['test_breakpoint2']['2x'] = array( + ]); + $expected['test_breakpoint2']['2x'] = [ 'breakpoint_id' => 'test_breakpoint2', 'multiplier' => '2x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'medium', - ); + ]; $this->assertEquals($expected, $entity->getKeyedImageStyleMappings()); // Overwrite a mapping to ensure keyed mapping static cache is rebuilt. - $entity->addImageStyleMapping('test_breakpoint2', '2x', array( + $entity->addImageStyleMapping('test_breakpoint2', '2x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); - $expected['test_breakpoint2']['2x'] = array( + ]); + $expected['test_breakpoint2']['2x'] = [ 'breakpoint_id' => 'test_breakpoint2', 'multiplier' => '2x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - ); + ]; $this->assertEquals($expected, $entity->getKeyedImageStyleMappings()); } @@ -277,50 +277,50 @@ public function testGetKeyedImageStyleMappings() { * @covers ::getImageStyleMappings */ public function testGetImageStyleMappings() { - $entity = new ResponsiveImageStyle(array('')); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity = new ResponsiveImageStyle(['']); + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); - $entity->addImageStyleMapping('test_breakpoint', '2x', array( + ]); + $entity->addImageStyleMapping('test_breakpoint', '2x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - )); - $entity->addImageStyleMapping('test_breakpoint2', '1x', array( + ], + ], + ]); + $entity->addImageStyleMapping('test_breakpoint2', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )); + ]); - $expected = array( - array( + $expected = [ + [ 'breakpoint_id' => 'test_breakpoint', 'multiplier' => '1x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - ), - array( + ], + [ 'breakpoint_id' => 'test_breakpoint', 'multiplier' => '2x', 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - ), - array( + ], + ], + ], + [ 'breakpoint_id' => 'test_breakpoint2', 'multiplier' => '1x', 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - ), - ); + ], + ]; $this->assertEquals($expected, $entity->getImageStyleMappings()); } @@ -329,24 +329,24 @@ public function testGetImageStyleMappings() { * @covers ::removeImageStyleMappings */ public function testRemoveImageStyleMappings() { - $entity = new ResponsiveImageStyle(array('')); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity = new ResponsiveImageStyle(['']); + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); - $entity->addImageStyleMapping('test_breakpoint', '2x', array( + ]); + $entity->addImageStyleMapping('test_breakpoint', '2x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - )); - $entity->addImageStyleMapping('test_breakpoint2', '1x', array( + ], + ], + ]); + $entity->addImageStyleMapping('test_breakpoint2', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )); + ]); $this->assertTrue($entity->hasImageStyleMappings()); $entity->removeImageStyleMappings(); @@ -360,24 +360,24 @@ public function testRemoveImageStyleMappings() { * @covers ::getBreakpointGroup */ public function testSetBreakpointGroup() { - $entity = new ResponsiveImageStyle(array('breakpoint_group' => 'test_group')); - $entity->addImageStyleMapping('test_breakpoint', '1x', array( + $entity = new ResponsiveImageStyle(['breakpoint_group' => 'test_group']); + $entity->addImageStyleMapping('test_breakpoint', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'large', - )); - $entity->addImageStyleMapping('test_breakpoint', '2x', array( + ]); + $entity->addImageStyleMapping('test_breakpoint', '2x', [ 'image_mapping_type' => 'sizes', - 'image_mapping' => array( + 'image_mapping' => [ 'sizes' => '(min-width:700px) 700px, 100vw', - 'sizes_image_styles' => array( + 'sizes_image_styles' => [ 'large' => 'large', - ), - ), - )); - $entity->addImageStyleMapping('test_breakpoint2', '1x', array( + ], + ], + ]); + $entity->addImageStyleMapping('test_breakpoint2', '1x', [ 'image_mapping_type' => 'image_style', 'image_mapping' => 'thumbnail', - )); + ]); // Ensure that setting to same group does not remove mappings. $entity->setBreakpointGroup('test_group'); diff --git a/core/modules/rest/config/install/rest.settings.yml b/core/modules/rest/config/install/rest.settings.yml index eb3da2df..8f70c699 100644 --- a/core/modules/rest/config/install/rest.settings.yml +++ b/core/modules/rest/config/install/rest.settings.yml @@ -1,7 +1,3 @@ -# Set the domain for REST type and relation links. -# If left blank, the site's domain will be used. -link_domain: ~ - # Before Drupal 8.2, EntityResource used permissions as well as the entity # access system for access checking. This was confusing, and it only did this # for historical reasons. New Drupal installations opt out from this by default diff --git a/core/modules/rest/config/schema/rest.schema.yml b/core/modules/rest/config/schema/rest.schema.yml index 2c255ab8..98b35ae6 100644 --- a/core/modules/rest/config/schema/rest.schema.yml +++ b/core/modules/rest/config/schema/rest.schema.yml @@ -3,6 +3,8 @@ rest.settings: type: config_object label: 'REST settings' mapping: + # @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + # @see https://www.drupal.org/node/2830467 link_domain: type: string label: 'Domain of the relation' @@ -14,18 +16,33 @@ rest.settings: rest_resource.method: type: mapping mapping: + HEAD: + type: rest_request + label: 'HEAD method settings' GET: type: rest_request label: 'GET method settings' POST: type: rest_request label: 'POST method settings' - PATCH: + PUT: type: rest_request - label: 'PATCH method settings' + label: 'PUT method settings' DELETE: type: rest_request label: 'DELETE method settings' + TRACE: + type: rest_request + label: 'TRACE method settings' + OPTIONS: + type: rest_request + label: 'OPTIONS method settings' + CONNECT: + type: rest_request + label: 'CONNECT method settings' + PATCH: + type: rest_request + label: 'PATCH method settings' # Resource-level granularity of REST resource configuration. rest_resource.resource: diff --git a/core/modules/rest/rest.api.php b/core/modules/rest/rest.api.php index fb8993d2..6c09bbff 100644 --- a/core/modules/rest/rest.api.php +++ b/core/modules/rest/rest.api.php @@ -31,6 +31,11 @@ function hook_rest_resource_alter(&$definitions) { /** * Alter the REST type URI. * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use + * hook_serialization_type_uri_alter() instead. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + * * Modules may wish to alter the type URI generated for a resource based on the * context of the serializer/normalizer operation. * @@ -44,9 +49,9 @@ function hook_rest_resource_alter(&$definitions) { * @see \Symfony\Component\Serializer\NormalizerInterface::normalize() * @see \Symfony\Component\Serializer\DenormalizerInterface::denormalize() */ -function hook_rest_type_uri_alter(&$uri, $context = array()) { +function hook_rest_type_uri_alter(&$uri, $context = []) { if ($context['mymodule'] == TRUE) { - $base = \Drupal::config('rest.settings')->get('link_domain'); + $base = \Drupal::config('serialization.settings')->get('link_domain'); $uri = str_replace($base, 'http://mymodule.domain', $uri); } } @@ -55,6 +60,11 @@ function hook_rest_type_uri_alter(&$uri, $context = array()) { /** * Alter the REST relation URI. * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use + * hook_serialization_relation_uri_alter() instead. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + * * Modules may wish to alter the relation URI generated for a resource based on * the context of the serializer/normalizer operation. * @@ -68,9 +78,9 @@ function hook_rest_type_uri_alter(&$uri, $context = array()) { * @see \Symfony\Component\Serializer\NormalizerInterface::normalize() * @see \Symfony\Component\Serializer\DenormalizerInterface::denormalize() */ -function hook_rest_relation_uri_alter(&$uri, $context = array()) { +function hook_rest_relation_uri_alter(&$uri, $context = []) { if ($context['mymodule'] == TRUE) { - $base = \Drupal::config('rest.settings')->get('link_domain'); + $base = \Drupal::config('serialization.settings')->get('link_domain'); $uri = str_replace($base, 'http://mymodule.domain', $uri); } } diff --git a/core/modules/rest/rest.info.yml b/core/modules/rest/rest.info.yml index d554d6fb..6631828b 100644 --- a/core/modules/rest/rest.info.yml +++ b/core/modules/rest/rest.info.yml @@ -7,8 +7,8 @@ package: Web services dependencies: - serialization -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rest/rest.install b/core/modules/rest/rest.install index af6664e0..2113b0bb 100644 --- a/core/modules/rest/rest.install +++ b/core/modules/rest/rest.install @@ -12,25 +12,19 @@ use Drupal\Core\StringTranslation\TranslatableMarkup; * Implements hook_requirements(). */ function rest_requirements($phase) { - $requirements = array(); + $requirements = []; if (version_compare(PHP_VERSION, '5.6.0', '>=') && version_compare(PHP_VERSION, '7', '<') && ini_get('always_populate_raw_post_data') != -1) { - $requirements['always_populate_raw_post_data'] = array( + $requirements['always_populate_raw_post_data'] = [ 'title' => t('always_populate_raw_post_data PHP setting'), 'value' => t('Not set to -1.'), 'severity' => REQUIREMENT_ERROR, 'description' => t('The always_populate_raw_post_data PHP setting should be set to -1 in PHP version 5.6. Please check the PHP manual for information on how to correct this.'), - ); + ]; } return $requirements; } -/** - * @defgroup updates-8.1.x-to-8.2.x - * @{ - * Update functions from 8.1.x to 8.2.x. - */ - /** * Install the REST config entity type and fix old settings-based config. * @@ -92,5 +86,37 @@ function rest_update_8203() { } /** - * @} End of "defgroup updates-8.1.x-to-8.2.x". + * Ensure the right REST authentication method is used. + * + * This fixes the bug in https://www.drupal.org/node/2825204. */ +function rest_update_8401() { + $config_factory = \Drupal::configFactory(); + $auth_providers = \Drupal::service('authentication_collector')->getSortedProviders(); + $process_auth = function ($auth_option) use ($auth_providers) { + foreach ($auth_providers as $provider_id => $provider_data) { + // The provider belongs to the module that declares it as a service. + if (strtok($provider_data->_serviceId, '.') === $auth_option) { + return $provider_id; + } + } + + return $auth_option; + }; + + foreach ($config_factory->listAll('views.view.') as $view_config_name) { + $save = FALSE; + $view = $config_factory->getEditable($view_config_name); + $displays = $view->get('display'); + foreach ($displays as $display_name => $display) { + if ('rest_export' === $display['display_plugin'] && !empty($display['display_options']['auth'])) { + $displays[$display_name]['display_options']['auth'] = array_map($process_auth, $display['display_options']['auth']); + $save = TRUE; + } + } + if ($save) { + $view->set('display', $displays); + $view->save(TRUE); + } + } +} diff --git a/core/modules/rest/rest.module b/core/modules/rest/rest.module index 24e1c5f7..ba61a17f 100644 --- a/core/modules/rest/rest.module +++ b/core/modules/rest/rest.module @@ -6,6 +6,7 @@ */ use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\views\ViewEntityInterface; /** * Implements hook_help(). @@ -15,15 +16,42 @@ function rest_help($route_name, RouteMatchInterface $route_match) { case 'help.page.rest': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The RESTful Web Services module provides a framework for exposing REST resources on your site. It provides support for content entities (see the Field module help page for more information about entities) such as content, users, taxonomy terms, etc.; REST support for content items of the Node module is enabled by default, and support for other types of content entities can be enabled. Other modules may add support for other types of REST resources. For more information, see the online documentation for the RESTful Web Services module.', array(':rest' => 'https://www.drupal.org/documentation/modules/rest', ':field' => (\Drupal::moduleHandler()->moduleExists('field')) ? \Drupal::url('help.page', array('name' => 'field')) : '#')) . '

    '; + $output .= '

    ' . t('The RESTful Web Services module provides a framework for exposing REST resources on your site. It provides support for content entity types such as the main site content, comments, custom blocks, taxonomy terms, and user accounts, etc. (see the Field module help page for more information about entities). REST support for content items of the Node module is enabled by default, and support for other types of content entities can be enabled. Other modules may add support for other types of REST resources. For more information, see the online documentation for the RESTful Web Services module.', [':rest' => 'https://www.drupal.org/documentation/modules/rest', ':field' => (\Drupal::moduleHandler()->moduleExists('field')) ? \Drupal::url('help.page', ['name' => 'field']) : '#']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Installing supporting modules') . '
    '; - $output .= '
    ' . t('In order to use REST on a web site, you need to install modules that provide serialization and authentication services. You can use the Core module HAL for serialization and HTTP Basic Authentication for authentication, or install a contributed or custom module.', array(':hal' => (\Drupal::moduleHandler()->moduleExists('hal')) ? \Drupal::url('help.page', array('name' => 'hal')) : '#', ':basic_auth' => (\Drupal::moduleHandler()->moduleExists('basic_auth')) ? \Drupal::url('help.page', array('name' => 'basic_auth')) : '#')) . '
    '; + $output .= '
    ' . t('In order to use REST on a web site, you need to install modules that provide serialization and authentication services. You can use the Core module HAL for serialization and HTTP Basic Authentication for authentication, or install a contributed or custom module.', [':hal' => (\Drupal::moduleHandler()->moduleExists('hal')) ? \Drupal::url('help.page', ['name' => 'hal']) : '#', ':basic_auth' => (\Drupal::moduleHandler()->moduleExists('basic_auth')) ? \Drupal::url('help.page', ['name' => 'basic_auth']) : '#']) . '
    '; $output .= '
    ' . t('Enabling REST support for an entity type') . '
    '; - $output .= '
    ' . t('REST support for content items of the Node module is enabled by default, and support for other types of content entities can be enabled. To enable support, you can use a process based on configuration editing or the contributed Rest UI module.', array(':config' => 'https://www.drupal.org/documentation/modules/rest', ':restui' => 'https://www.drupal.org/project/restui')) . '
    '; + $output .= '
    ' . t('REST support for content types (provided by the Node module) is enabled by default. To enable support for other content entity types, you can use a process based on configuration editing or the contributed REST UI module.', [':node' => (\Drupal::moduleHandler()->moduleExists('node')) ? \Drupal::url('help.page', ['name' => 'node']) : '#', ':config' => 'https://www.drupal.org/documentation/modules/rest', ':restui' => 'https://www.drupal.org/project/restui']) . '
    '; $output .= '
    ' . t('You will also need to grant anonymous users permission to perform each of the REST operations you want to be available, and set up authentication properly to authorize web requests.') . '
    '; $output .= '
    '; return $output; } } + +/** + * Implements hook_view_presave(). + * + * @see rest_update_8401() + */ +function rest_view_presave(ViewEntityInterface $view) { + // Fix the auth options on import, much like what rest_update_8401() does. + $auth_providers = \Drupal::service('authentication_collector')->getSortedProviders(); + $process_auth = function ($auth_option) use ($auth_providers) { + foreach ($auth_providers as $provider_id => $provider_data) { + // The provider belongs to the module that declares it as a service. + if (strtok($provider_data->_serviceId, '.') === $auth_option) { + return $provider_id; + } + } + + return $auth_option; + }; + + foreach (array_keys($view->get('display')) as $display_id) { + $display = &$view->getDisplay($display_id); + if ($display['display_plugin'] === 'rest_export' && !empty($display['display_options']['auth'])) { + $display['display_options']['auth'] = array_map($process_auth, $display['display_options']['auth']); + } + } +} diff --git a/core/modules/rest/rest.post_update.php b/core/modules/rest/rest.post_update.php index ecbc73c4..6d451788 100644 --- a/core/modules/rest/rest.post_update.php +++ b/core/modules/rest/rest.post_update.php @@ -8,11 +8,6 @@ use Drupal\rest\Entity\RestResourceConfig; use Drupal\rest\RestResourceConfigInterface; -/** - * @addtogroup updates-8.1.x-to-8.2.x - * @{ - */ - /** * Create REST resource configuration entities. * @@ -66,8 +61,3 @@ function rest_post_update_resource_granularity() { } } } - - -/** - * @} End of "addtogroup updates-8.1.x-to-8.2.x". - */ diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml index 1cc34c14..080a681a 100644 --- a/core/modules/rest/rest.services.yml +++ b/core/modules/rest/rest.services.yml @@ -11,15 +11,6 @@ services: # @todo Remove this service in Drupal 9.0.0. access_check.rest.csrf: alias: access_check.header.csrf - rest.link_manager: - class: Drupal\rest\LinkManager\LinkManager - arguments: ['@rest.link_manager.type', '@rest.link_manager.relation'] - rest.link_manager.type: - class: Drupal\rest\LinkManager\TypeLinkManager - arguments: ['@cache.default', '@module_handler', '@config.factory', '@request_stack', '@entity_type.bundle.info'] - rest.link_manager.relation: - class: Drupal\rest\LinkManager\RelationLinkManager - arguments: ['@cache.default', '@entity.manager', '@module_handler', '@config.factory', '@request_stack'] rest.resource_routes: class: Drupal\rest\Routing\ResourceRoutes arguments: ['@plugin.manager.rest', '@entity_type.manager', '@logger.channel.rest'] @@ -28,3 +19,27 @@ services: logger.channel.rest: parent: logger.channel_base arguments: ['rest'] + + # Event subscribers. + rest.resource_response.subscriber: + class: Drupal\rest\EventSubscriber\ResourceResponseSubscriber + tags: + - { name: event_subscriber } + arguments: ['@serializer', '@renderer', '@current_route_match'] + rest.config_subscriber: + class: Drupal\rest\EventSubscriber\RestConfigSubscriber + arguments: ['@router.builder'] + tags: + - { name: event_subscriber } + rest.resource.entity.post_route.subscriber: + class: \Drupal\rest\EventSubscriber\EntityResourcePostRouteSubscriber + arguments: ['@entity_type.manager'] + tags: + - { name: event_subscriber } + + # @todo Remove in Drupal 9.0.0. + rest.path_processor_entity_resource_bc: + class: \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC + arguments: ['@entity_type.manager'] + tags: + - { name: path_processor_inbound } diff --git a/core/modules/rest/src/Annotation/RestResource.php b/core/modules/rest/src/Annotation/RestResource.php index 0af11a84..f525ff1c 100644 --- a/core/modules/rest/src/Annotation/RestResource.php +++ b/core/modules/rest/src/Annotation/RestResource.php @@ -2,7 +2,7 @@ namespace Drupal\rest\Annotation; -use \Drupal\Component\Annotation\Plugin; +use Drupal\Component\Annotation\Plugin; /** * Defines a REST resource annotation object. @@ -23,14 +23,14 @@ class RestResource extends Plugin { /** - * The resource plugin ID. + * The REST resource plugin ID. * * @var string */ public $id; /** - * The human-readable name of the resource plugin. + * The human-readable name of the REST resource plugin. * * @ingroup plugin_translatable * @@ -41,8 +41,22 @@ class RestResource extends Plugin { /** * The serialization class to deserialize serialized data into. * + * @see \Symfony\Component\Serializer\SerializerInterface's "type" parameter. + * * @var string (optional) */ public $serialization_class; + /** + * The URI paths that this REST resource plugin provides. + * + * Key-value pairs, with link relation type plugin IDs as keys, and URL + * templates as values. + * + * @see core/core.link_relation_types.yml + * + * @var string[] + */ + public $uri_paths = []; + } diff --git a/core/modules/rest/src/Entity/RestResourceConfig.php b/core/modules/rest/src/Entity/RestResourceConfig.php index bb835841..12bd846e 100644 --- a/core/modules/rest/src/Entity/RestResourceConfig.php +++ b/core/modules/rest/src/Entity/RestResourceConfig.php @@ -3,6 +3,7 @@ namespace Drupal\rest\Entity; use Drupal\Core\Config\Entity\ConfigEntityBase; +use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection; use Drupal\rest\RestResourceConfigInterface; @@ -255,4 +256,22 @@ protected function normalizeRestMethod($method) { return strtoupper($method); } + /** + * {@inheritdoc} + */ + public function postSave(EntityStorageInterface $storage, $update = TRUE) { + parent::postSave($storage, $update); + + \Drupal::service('router.builder')->setRebuildNeeded(); + } + + /** + * {@inheritdoc} + */ + public static function postDelete(EntityStorageInterface $storage, array $entities) { + parent::postDelete($storage, $entities); + + \Drupal::service('router.builder')->setRebuildNeeded(); + } + } diff --git a/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php new file mode 100644 index 00000000..36a3f731 --- /dev/null +++ b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php @@ -0,0 +1,74 @@ +resourceConfigStorage = $entity_type_manager->getStorage('rest_resource_config'); + } + + /** + * Provides routes on route rebuild time. + * + * @param \Drupal\Core\Routing\RouteBuildEvent $event + * The route build event. + */ + public function onDynamicRouteEvent(RouteBuildEvent $event) { + $route_collection = $event->getRouteCollection(); + + $resource_configs = $this->resourceConfigStorage->loadMultiple(); + // Iterate over all REST resource config entities. + foreach ($resource_configs as $resource_config) { + // We only care about REST resource config entities for the + // \Drupal\rest\Plugin\rest\resource\EntityResource plugin. + $plugin_id = $resource_config->toArray()['plugin_id']; + if (substr($plugin_id, 0, 6) !== 'entity') { + continue; + } + + $entity_type_id = substr($plugin_id, 7); + $rest_post_route_name = "rest.entity.$entity_type_id.POST"; + if ($rest_post_route = $route_collection->get($rest_post_route_name)) { + // Create a route for the 'create' link relation type for this entity + // type that uses the same route definition as the REST 'POST' route + // which use that entity type. + // @see \Drupal\Core\Entity\Entity::toUrl() + $entity_create_route_name = "entity.$entity_type_id.create"; + $route_collection->add($entity_create_route_name, $rest_post_route); + } + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + // Priority -10, to run after \Drupal\rest\Routing\ResourceRoutes, which has + // priority 0. + $events[RoutingEvents::DYNAMIC][] = ['onDynamicRouteEvent', -10]; + return $events; + } + +} diff --git a/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php b/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php new file mode 100644 index 00000000..df77281f --- /dev/null +++ b/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php @@ -0,0 +1,205 @@ +serializer = $serializer; + $this->renderer = $renderer; + $this->routeMatch = $route_match; + } + + /** + * Serializes ResourceResponse responses' data, and removes that data. + * + * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event + * The event to process. + */ + public function onResponse(FilterResponseEvent $event) { + $response = $event->getResponse(); + if (!$response instanceof ResourceResponseInterface) { + return; + } + + $request = $event->getRequest(); + $format = $this->getResponseFormat($this->routeMatch, $request); + $this->renderResponseBody($request, $response, $this->serializer, $format); + $event->setResponse($this->flattenResponse($response)); + } + + /** + * Determines the format to respond in. + * + * Respects the requested format if one is specified. However, it is common to + * forget to specify a request format in case of a POST or PATCH. Rather than + * simply throwing an error, we apply the robustness principle: when POSTing + * or PATCHing using a certain format, you probably expect a response in that + * same format. + * + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The current route match. + * @param \Symfony\Component\HttpFoundation\Request $request + * The current request. + * + * @return string + * The response format. + */ + public function getResponseFormat(RouteMatchInterface $route_match, Request $request) { + $route = $route_match->getRouteObject(); + $acceptable_request_formats = $route->hasRequirement('_format') ? explode('|', $route->getRequirement('_format')) : []; + $acceptable_content_type_formats = $route->hasRequirement('_content_type_format') ? explode('|', $route->getRequirement('_content_type_format')) : []; + $acceptable_formats = $request->isMethodCacheable() ? $acceptable_request_formats : $acceptable_content_type_formats; + + $requested_format = $request->getRequestFormat(); + $content_type_format = $request->getContentType(); + + // If an acceptable format is requested, then use that. Otherwise, including + // and particularly when the client forgot to specify a format, then use + // heuristics to select the format that is most likely expected. + if (in_array($requested_format, $acceptable_formats)) { + return $requested_format; + } + // If a request body is present, then use the format corresponding to the + // request body's Content-Type for the response, if it's an acceptable + // format for the request. + elseif (!empty($request->getContent()) && in_array($content_type_format, $acceptable_content_type_formats)) { + return $content_type_format; + } + // Otherwise, use the first acceptable format. + elseif (!empty($acceptable_formats)) { + return $acceptable_formats[0]; + } + // Sometimes, there are no acceptable formats, e.g. DELETE routes. + else { + return NULL; + } + } + + /** + * Renders a resource response body. + * + * Serialization can invoke rendering (e.g., generating URLs), but the + * serialization API does not provide a mechanism to collect the + * bubbleable metadata associated with that (e.g., language and other + * contexts), so instead, allow those to "leak" and collect them here in + * a render context. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * @param \Drupal\rest\ResourceResponseInterface $response + * The response from the REST resource. + * @param \Symfony\Component\Serializer\SerializerInterface $serializer + * The serializer to use. + * @param string|null $format + * The response format, or NULL in case the response does not need a format, + * for example for the response to a DELETE request. + * + * @todo Add test coverage for language negotiation contexts in + * https://www.drupal.org/node/2135829. + */ + protected function renderResponseBody(Request $request, ResourceResponseInterface $response, SerializerInterface $serializer, $format) { + $data = $response->getResponseData(); + + // If there is data to send, serialize and set it as the response body. + if ($data !== NULL) { + $context = new RenderContext(); + $output = $this->renderer + ->executeInRenderContext($context, function () use ($serializer, $data, $format) { + return $serializer->serialize($data, $format); + }); + + if ($response instanceof CacheableResponseInterface && !$context->isEmpty()) { + $response->addCacheableDependency($context->pop()); + } + + $response->setContent($output); + $response->headers->set('Content-Type', $request->getMimeType($format)); + } + } + + /** + * Flattens a fully rendered resource response. + * + * Ensures that complex data structures in ResourceResponse::getResponseData() + * are not serialized. Not doing this means that caching this response object + * requires unserializing the PHP data when reading this response object from + * cache, which can be very costly, and is unnecessary. + * + * @param \Drupal\rest\ResourceResponseInterface $response + * A fully rendered resource response. + * + * @return \Drupal\Core\Cache\CacheableResponse|\Symfony\Component\HttpFoundation\Response + * The flattened response. + */ + protected function flattenResponse(ResourceResponseInterface $response) { + $final_response = ($response instanceof CacheableResponseInterface) ? new CacheableResponse() : new Response(); + $final_response->setContent($response->getContent()); + $final_response->setStatusCode($response->getStatusCode()); + $final_response->setProtocolVersion($response->getProtocolVersion()); + $final_response->setCharset($response->getCharset()); + $final_response->headers = clone $response->headers; + if ($final_response instanceof CacheableResponseInterface) { + $final_response->addCacheableDependency($response->getCacheableMetadata()); + } + return $final_response; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + // Run before \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber + // (priority 100), so that Dynamic Page Cache can cache flattened responses. + $events[KernelEvents::RESPONSE][] = ['onResponse', 128]; + return $events; + } + +} diff --git a/core/modules/rest/src/EventSubscriber/RestConfigSubscriber.php b/core/modules/rest/src/EventSubscriber/RestConfigSubscriber.php new file mode 100644 index 00000000..d199545f --- /dev/null +++ b/core/modules/rest/src/EventSubscriber/RestConfigSubscriber.php @@ -0,0 +1,53 @@ +routerBuilder = $router_builder; + } + + /** + * Informs the router builder a rebuild is needed when necessary. + * + * @param \Drupal\Core\Config\ConfigCrudEvent $event + * The Event to process. + */ + public function onSave(ConfigCrudEvent $event) { + $saved_config = $event->getConfig(); + if ($saved_config->getName() === 'rest.settings' && $event->isChanged('bc_entity_resource_permissions')) { + $this->routerBuilder->setRebuildNeeded(); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[ConfigEvents::SAVE][] = ['onSave']; + return $events; + } + +} diff --git a/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php b/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php index c2eb1f13..e5214591 100644 --- a/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php +++ b/core/modules/rest/src/LinkManager/ConfigurableLinkManagerInterface.php @@ -2,19 +2,12 @@ namespace Drupal\rest\LinkManager; +use Drupal\hal\LinkManager\ConfigurableLinkManagerInterface as MovedConfigurableLinkManagerInterface; + /** - * Defines an interface for a link manager with a configurable domain. + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 */ -interface ConfigurableLinkManagerInterface { - - /** - * Sets the link domain used in constructing link URIs. - * - * @param string $domain - * The link domain to use for constructing link URIs. - * - * @return $this - */ - public function setLinkDomain($domain); - -} +interface ConfigurableLinkManagerInterface extends MovedConfigurableLinkManagerInterface {} diff --git a/core/modules/rest/src/LinkManager/LinkManager.php b/core/modules/rest/src/LinkManager/LinkManager.php index bd94a658..4586c62e 100644 --- a/core/modules/rest/src/LinkManager/LinkManager.php +++ b/core/modules/rest/src/LinkManager/LinkManager.php @@ -2,70 +2,12 @@ namespace Drupal\rest\LinkManager; -class LinkManager implements LinkManagerInterface { - - /** - * The type link manager. - * - * @var \Drupal\rest\LinkManager\TypeLinkManagerInterface - */ - protected $typeLinkManager; - - /** - * The relation link manager. - * - * @var \Drupal\rest\LinkManager\RelationLinkManagerInterface - */ - protected $relationLinkManager; - - /** - * Constructor. - * - * @param \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_link_manager - * Manager for handling bundle URIs. - * @param \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_link_manager - * Manager for handling bundle URIs. - */ - public function __construct(TypeLinkManagerInterface $type_link_manager, RelationLinkManagerInterface $relation_link_manager) { - $this->typeLinkManager = $type_link_manager; - $this->relationLinkManager = $relation_link_manager; - } - - /** - * {@inheritdoc} - */ - public function getTypeUri($entity_type, $bundle, $context = array()) { - return $this->typeLinkManager->getTypeUri($entity_type, $bundle, $context); - } - - /** - * {@inheritdoc} - */ - public function getTypeInternalIds($type_uri, $context = array()) { - return $this->typeLinkManager->getTypeInternalIds($type_uri, $context); - } - - /** - * {@inheritdoc} - */ - public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) { - return $this->relationLinkManager->getRelationUri($entity_type, $bundle, $field_name, $context); - } - - /** - * {@inheritdoc} - */ - public function getRelationInternalIds($relation_uri) { - return $this->relationLinkManager->getRelationInternalIds($relation_uri); - } - - /** - * {@inheritdoc} - */ - public function setLinkDomain($domain) { - $this->relationLinkManager->setLinkDomain($domain); - $this->typeLinkManager->setLinkDomain($domain); - return $this; - } - -} +use Drupal\hal\LinkManager\LinkManager as MovedLinkManager; + +/** + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + */ +class LinkManager extends MovedLinkManager implements LinkManagerInterface {} diff --git a/core/modules/rest/src/LinkManager/LinkManagerBase.php b/core/modules/rest/src/LinkManager/LinkManagerBase.php index 0896a80f..85eb7b70 100644 --- a/core/modules/rest/src/LinkManager/LinkManagerBase.php +++ b/core/modules/rest/src/LinkManager/LinkManagerBase.php @@ -2,57 +2,12 @@ namespace Drupal\rest\LinkManager; +use Drupal\hal\LinkManager\LinkManagerBase as MovedLinkManagerBase; + /** - * Defines an abstract base-class for REST link manager objects. + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 */ -abstract class LinkManagerBase { - - /** - * Link domain used for type links URIs. - * - * @var string - */ - protected $linkDomain; - - /** - * Config factory service. - * - * @var \Drupal\Core\Config\ConfigFactoryInterface - */ - protected $configFactory; - - /** - * The request stack. - * - * @var \Symfony\Component\HttpFoundation\RequestStack - */ - protected $requestStack; - - /** - * {@inheritdoc} - */ - public function setLinkDomain($domain) { - $this->linkDomain = rtrim($domain, '/'); - return $this; - } - - /** - * Gets the link domain. - * - * @return string - * The link domain. - */ - protected function getLinkDomain() { - if (empty($this->linkDomain)) { - if ($domain = $this->configFactory->get('rest.settings')->get('link_domain')) { - $this->linkDomain = rtrim($domain, '/'); - } - else { - $request = $this->requestStack->getCurrentRequest(); - $this->linkDomain = $request->getSchemeAndHttpHost() . $request->getBasePath(); - } - } - return $this->linkDomain; - } - -} +abstract class LinkManagerBase extends MovedLinkManagerBase {} diff --git a/core/modules/rest/src/LinkManager/LinkManagerInterface.php b/core/modules/rest/src/LinkManager/LinkManagerInterface.php index 1bd04ff5..9f5d2f2d 100644 --- a/core/modules/rest/src/LinkManager/LinkManagerInterface.php +++ b/core/modules/rest/src/LinkManager/LinkManagerInterface.php @@ -2,17 +2,12 @@ namespace Drupal\rest\LinkManager; +use Drupal\hal\LinkManager\LinkManagerInterface as MovedLinkManagerInterface; + /** - * Interface implemented by link managers. - * - * There are no explicit methods on the manager interface. Instead link managers - * broker the interactions of the different components, and therefore must - * implement each component interface, which is enforced by this interface - * extending all of the component ones. + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. * - * While a link manager may directly implement these interface methods with - * custom logic, it is expected to be more common for plugin managers to proxy - * the method invocations to the respective components. + * @see https://www.drupal.org/node/2830467 */ -interface LinkManagerInterface extends TypeLinkManagerInterface, RelationLinkManagerInterface { -} +interface LinkManagerInterface extends MovedLinkManagerInterface {} diff --git a/core/modules/rest/src/LinkManager/RelationLinkManager.php b/core/modules/rest/src/LinkManager/RelationLinkManager.php index 297ffd9a..6690e210 100644 --- a/core/modules/rest/src/LinkManager/RelationLinkManager.php +++ b/core/modules/rest/src/LinkManager/RelationLinkManager.php @@ -2,141 +2,12 @@ namespace Drupal\rest\LinkManager; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Cache\CacheBackendInterface; -use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Entity\ContentEntityTypeInterface; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; -use Symfony\Component\HttpFoundation\RequestStack; - -class RelationLinkManager extends LinkManagerBase implements RelationLinkManagerInterface { - - /** - * @var \Drupal\Core\Cache\CacheBackendInterface; - */ - protected $cache; - - /** - * Entity manager. - * - * @var \Drupal\Core\Entity\EntityManagerInterface - */ - protected $entityManager; - - /** - * Module handler service. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ - protected $moduleHandler; - - /** - * Constructor. - * - * @param \Drupal\Core\Cache\CacheBackendInterface $cache - * The cache of relation URIs and their associated Typed Data IDs. - * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler service. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The config factory service. - * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack - * The request stack. - */ - public function __construct(CacheBackendInterface $cache, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack) { - $this->cache = $cache; - $this->entityManager = $entity_manager; - $this->configFactory = $config_factory; - $this->moduleHandler = $module_handler; - $this->requestStack = $request_stack; - } - - /** - * {@inheritdoc} - */ - public function getRelationUri($entity_type, $bundle, $field_name, $context = array()) { - // Per the interface documention of this method, the returned URI may - // optionally also serve as the URL of a documentation page about this - // field. However, the REST module does not currently implement such - // a documentation page. Therefore, we return a URI assembled relative to - // the site's base URL, which is sufficient to uniquely identify the site's - // entity type + bundle + field for use in hypermedia formats, but we do - // not take into account unclean URLs, language prefixing, or anything else - // that would be required for Drupal to be able to respond with content - // at this URL. If a module is installed that adds such content, but - // requires this URL to be different (e.g., include a language prefix), - // then the module must also override the RelationLinkManager class/service - // to return the desired URL. - $uri = $this->getLinkDomain() . "/rest/relation/$entity_type/$bundle/$field_name"; - $this->moduleHandler->alter('rest_relation_uri', $uri, $context); - return $uri; - } - - /** - * {@inheritdoc} - */ - public function getRelationInternalIds($relation_uri, $context = array()) { - $relations = $this->getRelations($context); - if (isset($relations[$relation_uri])) { - return $relations[$relation_uri]; - } - return FALSE; - } - - /** - * Get the array of relation links. - * - * Any field can be handled as a relation simply by changing how it is - * normalized. Therefore, there is no prior knowledge that can be used here - * to determine which fields to assign relation URIs. Instead, each field, - * even primitives, are given a relation URI. It is up to the caller to - * determine which URIs to use. - * - * @param array $context - * Context from the normalizer/serializer operation. - * - * @return array - * An array of typed data ids (entity_type, bundle, and field name) keyed - * by corresponding relation URI. - */ - protected function getRelations($context = array()) { - $cid = 'rest:links:relations'; - $cache = $this->cache->get($cid); - if (!$cache) { - $this->writeCache($context); - $cache = $this->cache->get($cid); - } - return $cache->data; - } - - /** - * Writes the cache of relation links. - * - * @param array $context - * Context from the normalizer/serializer operation. - */ - protected function writeCache($context = array()) { - $data = array(); - - foreach ($this->entityManager->getDefinitions() as $entity_type) { - if ($entity_type instanceof ContentEntityTypeInterface) { - foreach ($this->entityManager->getBundleInfo($entity_type->id()) as $bundle => $bundle_info) { - foreach ($this->entityManager->getFieldDefinitions($entity_type->id(), $bundle) as $field_definition) { - $relation_uri = $this->getRelationUri($entity_type->id(), $bundle, $field_definition->getName(), $context); - $data[$relation_uri] = array( - 'entity_type' => $entity_type, - 'bundle' => $bundle, - 'field_name' => $field_definition->getName(), - ); - } - } - } - } - // These URIs only change when field info changes, so cache it permanently - // and only clear it when the fields cache is cleared. - $this->cache->set('rest:links:relations', $data, Cache::PERMANENT, array('entity_field_info')); - } - -} +use Drupal\hal\LinkManager\RelationLinkManager as MovedLinkRelationManager; + +/** + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + */ +class RelationLinkManager extends MovedLinkRelationManager implements RelationLinkManagerInterface {} diff --git a/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php b/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php index 53cd0399..c2eec346 100644 --- a/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php +++ b/core/modules/rest/src/LinkManager/RelationLinkManagerInterface.php @@ -2,38 +2,12 @@ namespace Drupal\rest\LinkManager; -interface RelationLinkManagerInterface extends ConfigurableLinkManagerInterface { - - /** - * Gets the URI that corresponds to a field. - * - * When using hypermedia formats, this URI can be used to indicate which - * field the data represents. Documentation about this field can also be - * provided at this URI. - * - * @param string $entity_type - * The bundle's entity type. - * @param string $bundle - * The bundle name. - * @param string $field_name - * The field name. - * @param array $context - * (optional) Optional serializer/normalizer context. - * - * @return string - * The corresponding URI for the field. - */ - public function getRelationUri($entity_type, $bundle, $field_name, $context = array()); - - /** - * Translates a REST URI into internal IDs. - * - * @param string $relation_uri - * Relation URI to transform into internal IDs - * - * @return array - * Array with keys 'entity_type', 'bundle' and 'field_name'. - */ - public function getRelationInternalIds($relation_uri); - -} +use Drupal\hal\LinkManager\RelationLinkManagerInterface as MovedRelationLinkManagerInterface; + +/** + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + */ +interface RelationLinkManagerInterface extends MovedRelationLinkManagerInterface {} diff --git a/core/modules/rest/src/LinkManager/TypeLinkManager.php b/core/modules/rest/src/LinkManager/TypeLinkManager.php index 6752f620..6d7ba03e 100644 --- a/core/modules/rest/src/LinkManager/TypeLinkManager.php +++ b/core/modules/rest/src/LinkManager/TypeLinkManager.php @@ -2,147 +2,12 @@ namespace Drupal\rest\LinkManager; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Cache\CacheBackendInterface; -use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Entity\EntityTypeBundleInfoInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; -use Symfony\Component\HttpFoundation\RequestStack; - -class TypeLinkManager extends LinkManagerBase implements TypeLinkManagerInterface { - - /** - * Injected cache backend. - * - * @var \Drupal\Core\Cache\CacheBackendInterface; - */ - protected $cache; - - /** - * Module handler service. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ - protected $moduleHandler; - - /** - * The bundle info service. - * - * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface - */ - protected $bundleInfoService; - - /** - * Constructor. - * - * @param \Drupal\Core\Cache\CacheBackendInterface $cache - * The injected cache backend for caching type URIs. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler service. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The config factory service. - * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack - * The request stack. - * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info_service - * The bundle info service. - */ - public function __construct(CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, RequestStack $request_stack, EntityTypeBundleInfoInterface $bundle_info_service) { - $this->cache = $cache; - $this->configFactory = $config_factory; - $this->moduleHandler = $module_handler; - $this->requestStack = $request_stack; - $this->bundleInfoService = $bundle_info_service; - } - - /** - * {@inheritdoc} - */ - public function getTypeUri($entity_type, $bundle, $context = array()) { - // Per the interface documention of this method, the returned URI may - // optionally also serve as the URL of a documentation page about this - // bundle. However, the REST module does not currently implement such - // a documentation page. Therefore, we return a URI assembled relative to - // the site's base URL, which is sufficient to uniquely identify the site's - // entity type and bundle for use in hypermedia formats, but we do not - // take into account unclean URLs, language prefixing, or anything else - // that would be required for Drupal to be able to respond with content - // at this URL. If a module is installed that adds such content, but - // requires this URL to be different (e.g., include a language prefix), - // then the module must also override the TypeLinkManager class/service to - // return the desired URL. - $uri = $this->getLinkDomain() . "/rest/type/$entity_type/$bundle"; - $this->moduleHandler->alter('rest_type_uri', $uri, $context); - return $uri; - } - - /** - * {@inheritdoc} - */ - public function getTypeInternalIds($type_uri, $context = array()) { - $types = $this->getTypes($context); - if (isset($types[$type_uri])) { - return $types[$type_uri]; - } - return FALSE; - } - - /** - * Get the array of type links. - * - * @param array $context - * Context from the normalizer/serializer operation. - * - * @return array - * An array of typed data ids (entity_type and bundle) keyed by - * corresponding type URI. - */ - protected function getTypes($context = array()) { - $cid = 'rest:links:types'; - $cache = $this->cache->get($cid); - if (!$cache) { - $data = $this->writeCache($context); - } - else { - $data = $cache->data; - } - return $data; - } - - /** - * Writes the cache of type links. - * - * @param array $context - * Context from the normalizer/serializer operation. - * - * @return array - * An array of typed data ids (entity_type and bundle) keyed by - * corresponding type URI. - */ - protected function writeCache($context = array()) { - $data = array(); - - // Type URIs correspond to bundles. Iterate through the bundles to get the - // URI and data for them. - $entity_types = \Drupal::entityManager()->getDefinitions(); - foreach ($this->bundleInfoService->getAllBundleInfo() as $entity_type_id => $bundles) { - // Only content entities are supported currently. - // @todo Consider supporting config entities. - if ($entity_types[$entity_type_id]->isSubclassOf('\Drupal\Core\Config\Entity\ConfigEntityInterface')) { - continue; - } - foreach ($bundles as $bundle => $bundle_info) { - // Get a type URI for the bundle. - $bundle_uri = $this->getTypeUri($entity_type_id, $bundle, $context); - $data[$bundle_uri] = array( - 'entity_type' => $entity_type_id, - 'bundle' => $bundle, - ); - } - } - // These URIs only change when entity info changes, so cache it permanently - // and only clear it when entity_info is cleared. - $this->cache->set('rest:links:types', $data, Cache::PERMANENT, array('entity_types')); - return $data; - } - -} +use Drupal\hal\LinkManager\TypeLinkManager as MovedTypeLinkManager; + +/** + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + */ +class TypeLinkManager extends MovedTypeLinkManager implements TypeLinkManagerInterface {} diff --git a/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php b/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php index 484ca76f..9a37049e 100644 --- a/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php +++ b/core/modules/rest/src/LinkManager/TypeLinkManagerInterface.php @@ -2,39 +2,12 @@ namespace Drupal\rest\LinkManager; -interface TypeLinkManagerInterface extends ConfigurableLinkManagerInterface { - - /** - * Gets the URI that corresponds to a bundle. - * - * When using hypermedia formats, this URI can be used to indicate which - * bundle the data represents. Documentation about required and optional - * fields can also be provided at this URI. - * - * @param $entity_type - * The bundle's entity type. - * @param $bundle - * The bundle name. - * @param array $context - * (optional) Optional serializer/normalizer context. - * - * @return string - * The corresponding URI for the bundle. - */ - public function getTypeUri($entity_type, $bundle, $context = array()); - - /** - * Get a bundle's Typed Data IDs based on a URI. - * - * @param string $type_uri - * The type URI. - * @param array $context - * Context from the normalizer/serializer operation. - * - * @return array | boolean - * If the URI matches a bundle, returns an array containing entity_type and - * bundle. Otherwise, returns false. - */ - public function getTypeInternalIds($type_uri, $context = array()); - -} +use Drupal\hal\LinkManager\TypeLinkManagerInterface as MovedTypeLinkManagerInterface; + +/** + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has + * been moved to the hal module. This exists solely for BC. + * + * @see https://www.drupal.org/node/2830467 + */ +interface TypeLinkManagerInterface extends MovedTypeLinkManagerInterface {} diff --git a/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php b/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php new file mode 100644 index 00000000..1f68691a --- /dev/null +++ b/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php @@ -0,0 +1,55 @@ +entityTypeManager = $entity_type_manager; + } + + /** + * {@inheritdoc} + */ + public function processInbound($path, Request $request) { + if ($request->getMethod() === 'POST' && strpos($path, '/entity/') === 0) { + $parts = explode('/', $path); + $entity_type_id = array_pop($parts); + + // Until Drupal 8.3, no entity types specified a link template for the + // 'create' link relation type. As of Drupal 8.3, all core content entity + // types provide this link relation type. This inbound path processor + // provides automatic backwards compatibility: it allows both the old + // default from \Drupal\rest\Plugin\rest\resource\EntityResource, i.e. + // "/entity/{entity_type}" and the link template specified in a particular + // entity type. The former is rewritten to the latter + // specific one if it exists. + $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); + if ($entity_type->hasLinkTemplate('create')) { + return $entity_type->getLinkTemplate('create'); + } + } + return $path; + } + +} diff --git a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php index 6a6ddae9..a74e8b2a 100644 --- a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php +++ b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php @@ -65,17 +65,17 @@ public function getDerivativeDefinitions($base_plugin_definition) { if (!isset($this->derivatives)) { // Add in the default plugin configuration and the resource type. foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { - $this->derivatives[$entity_type_id] = array( + $this->derivatives[$entity_type_id] = [ 'id' => 'entity:' . $entity_type_id, 'entity_type' => $entity_type_id, 'serialization_class' => $entity_type->getClass(), 'label' => $entity_type->getLabel(), - ); + ]; - $default_uris = array( + $default_uris = [ 'canonical' => "/entity/$entity_type_id/" . '{' . $entity_type_id . '}', - 'https://www.drupal.org/link-relations/create' => "/entity/$entity_type_id", - ); + 'create' => "/entity/$entity_type_id", + ]; foreach ($default_uris as $link_relation => $default_uri) { // Check if there are link templates defined for the entity type and diff --git a/core/modules/rest/src/Plugin/ResourceBase.php b/core/modules/rest/src/Plugin/ResourceBase.php index 93684dbb..b40a0310 100644 --- a/core/modules/rest/src/Plugin/ResourceBase.php +++ b/core/modules/rest/src/Plugin/ResourceBase.php @@ -31,7 +31,7 @@ abstract class ResourceBase extends PluginBase implements ContainerFactoryPlugin * * @var array */ - protected $serializerFormats = array(); + protected $serializerFormats = []; /** * A logger instance. @@ -81,13 +81,13 @@ public static function create(ContainerInterface $container, array $configuratio * resource". */ public function permissions() { - $permissions = array(); + $permissions = []; $definition = $this->getPluginDefinition(); foreach ($this->availableMethods() as $method) { $lowered_method = strtolower($method); - $permissions["restful $lowered_method $this->pluginId"] = array( - 'title' => $this->t('Access @method on %label resource', array('@method' => $method, '%label' => $definition['label'])), - ); + $permissions["restful $lowered_method $this->pluginId"] = [ + 'title' => $this->t('Access @method on %label resource', ['@method' => $method, '%label' => $definition['label']]), + ]; } return $permissions; } @@ -100,7 +100,15 @@ public function routes() { $definition = $this->getPluginDefinition(); $canonical_path = isset($definition['uri_paths']['canonical']) ? $definition['uri_paths']['canonical'] : '/' . strtr($this->pluginId, ':', '/') . '/{id}'; - $create_path = isset($definition['uri_paths']['https://www.drupal.org/link-relations/create']) ? $definition['uri_paths']['https://www.drupal.org/link-relations/create'] : '/' . strtr($this->pluginId, ':', '/'); + $create_path = isset($definition['uri_paths']['create']) ? $definition['uri_paths']['create'] : '/' . strtr($this->pluginId, ':', '/'); + // BC: the REST module originally created the POST URL for a resource by + // reading the 'https://www.drupal.org/link-relations/create' URI path from + // the plugin annotation. For consistency with entity type definitions, that + // then changed to reading the 'create' URI path. For any REST Resource + // plugins that were using the old mechanism, we continue to support that. + if (!isset($definition['uri_paths']['create']) && isset($definition['uri_paths']['https://www.drupal.org/link-relations/create'])) { + $create_path = $definition['uri_paths']['https://www.drupal.org/link-relations/create']; + } $route_name = strtr($this->pluginId, ':', '.'); @@ -111,16 +119,6 @@ public function routes() { switch ($method) { case 'POST': $route->setPath($create_path); - // Restrict the incoming HTTP Content-type header to the known - // serialization formats. - $route->addRequirements(array('_content_type_format' => implode('|', $this->serializerFormats))); - $collection->add("$route_name.$method", $route); - break; - - case 'PATCH': - // Restrict the incoming HTTP Content-type header to the known - // serialization formats. - $route->addRequirements(array('_content_type_format' => implode('|', $this->serializerFormats))); $collection->add("$route_name.$method", $route); break; @@ -131,7 +129,7 @@ public function routes() { foreach ($this->serializerFormats as $format_name) { // Expose one route per available format. $format_route = clone $route; - $format_route->addRequirements(array('_format' => $format_name)); + $format_route->addRequirements(['_format' => $format_name]); $collection->add("$route_name.$method.$format_name", $format_route); } break; @@ -155,7 +153,7 @@ public function routes() { * The list of allowed HTTP request method strings. */ protected function requestMethods() { - return array( + return [ 'HEAD', 'GET', 'POST', @@ -165,7 +163,7 @@ protected function requestMethods() { 'OPTIONS', 'CONNECT', 'PATCH', - ); + ]; } /** @@ -173,7 +171,7 @@ protected function requestMethods() { */ public function availableMethods() { $methods = $this->requestMethods(); - $available = array(); + $available = []; foreach ($methods as $method) { // Only expose methods where the HTTP request method exists on the plugin. if (method_exists($this, strtolower($method))) { @@ -195,15 +193,15 @@ public function availableMethods() { * The created base route. */ protected function getBaseRoute($canonical_path, $method) { - return new Route($canonical_path, array( + return new Route($canonical_path, [ '_controller' => 'Drupal\rest\RequestHandler::handle', - ), + ], $this->getBaseRouteRequirements($method), - array(), + [], '', - array(), + [], // The HTTP method is a requirement for this route. - array($method) + [$method] ); } diff --git a/core/modules/rest/src/Plugin/Type/ResourcePluginManager.php b/core/modules/rest/src/Plugin/Type/ResourcePluginManager.php index 4aa46b20..3ba73331 100644 --- a/core/modules/rest/src/Plugin/Type/ResourcePluginManager.php +++ b/core/modules/rest/src/Plugin/Type/ResourcePluginManager.php @@ -40,6 +40,8 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac * @deprecated in Drupal 8.2.0. * Use Drupal\rest\Plugin\Type\ResourcePluginManager::createInstance() * instead. + * + * @see https://www.drupal.org/node/2874934 */ public function getInstance(array $options){ if (isset($options['id'])) { diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php index 91ce482e..5d9849de 100644 --- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php +++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php @@ -3,17 +3,22 @@ namespace Drupal\rest\Plugin\rest\resource; use Drupal\Component\Plugin\DependentPluginInterface; +use Drupal\Component\Plugin\PluginManagerInterface; +use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\Config\Entity\ConfigEntityType; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageException; +use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\TypedData\PrimitiveInterface; use Drupal\rest\Plugin\ResourceBase; use Drupal\rest\ResourceResponse; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\rest\ModifiedResourceResponse; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -30,12 +35,15 @@ * deriver = "Drupal\rest\Plugin\Deriver\EntityDeriver", * uri_paths = { * "canonical" = "/entity/{entity_type}/{entity}", - * "https://www.drupal.org/link-relations/create" = "/entity/{entity_type}" + * "create" = "/entity/{entity_type}" * } * ) */ class EntityResource extends ResourceBase implements DependentPluginInterface { + use EntityResourceValidationTrait; + use EntityResourceAccessTrait; + /** * The entity type targeted by this resource. * @@ -50,6 +58,13 @@ class EntityResource extends ResourceBase implements DependentPluginInterface { */ protected $configFactory; + /** + * The link relation type manager used to create HTTP header links. + * + * @var \Drupal\Component\Plugin\PluginManagerInterface + */ + protected $linkRelationTypeManager; + /** * Constructs a Drupal\rest\Plugin\rest\resource\EntityResource object. * @@ -67,11 +82,14 @@ class EntityResource extends ResourceBase implements DependentPluginInterface { * A logger instance. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory. + * @param \Drupal\Component\Plugin\PluginManagerInterface $link_relation_type_manager + * The link relation type manager. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, $serializer_formats, LoggerInterface $logger, ConfigFactoryInterface $config_factory) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, $serializer_formats, LoggerInterface $logger, ConfigFactoryInterface $config_factory, PluginManagerInterface $link_relation_type_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); $this->entityType = $entity_type_manager->getDefinition($plugin_definition['entity_type']); $this->configFactory = $config_factory; + $this->linkRelationTypeManager = $link_relation_type_manager; } /** @@ -85,7 +103,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->getParameter('serializer.formats'), $container->get('logger.factory')->get('rest'), - $container->get('config.factory') + $container->get('config.factory'), + $container->get('plugin.manager.link_relation_type') ); } @@ -103,7 +122,7 @@ public static function create(ContainerInterface $container, array $configuratio public function get(EntityInterface $entity) { $entity_access = $entity->access('view', NULL, TRUE); if (!$entity_access->isAllowed()) { - throw new AccessDeniedHttpException(); + throw new AccessDeniedHttpException($entity_access->getReason() ?: $this->generateFallbackAccessDeniedMessage($entity, 'view')); } $response = new ResourceResponse($entity, 200); @@ -122,6 +141,8 @@ public function get(EntityInterface $entity) { } } + $this->addLinkHeaders($entity, $response); + return $response; } @@ -141,8 +162,9 @@ public function post(EntityInterface $entity = NULL) { throw new BadRequestHttpException('No entity content received.'); } - if (!$entity->access('create')) { - throw new AccessDeniedHttpException(); + $entity_access = $entity->access('create', NULL, TRUE); + if (!$entity_access->isAllowed()) { + throw new AccessDeniedHttpException($entity_access->getReason() ?: $this->generateFallbackAccessDeniedMessage($entity, 'create')); } $definition = $this->getPluginDefinition(); // Verify that the deserialized entity is of the type that we expect to @@ -156,33 +178,64 @@ public function post(EntityInterface $entity = NULL) { throw new BadRequestHttpException('Only new entities can be created'); } - // Only check 'edit' permissions for fields that were actually - // submitted by the user. Field access makes no difference between 'create' - // and 'update', so the 'edit' operation is used here. - foreach ($entity->_restSubmittedFields as $key => $field_name) { - if (!$entity->get($field_name)->access('edit')) { - throw new AccessDeniedHttpException("Access denied on creating field '$field_name'"); - } - } + $this->checkEditFieldAccess($entity); // Validate the received data before saving. $this->validate($entity); try { $entity->save(); - $this->logger->notice('Created entity %type with ID %id.', array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id())); + $this->logger->notice('Created entity %type with ID %id.', ['%type' => $entity->getEntityTypeId(), '%id' => $entity->id()]); // 201 Created responses return the newly created entity in the response // body. These responses are not cacheable, so we add no cacheability // metadata here. - $url = $entity->urlInfo('canonical', ['absolute' => TRUE])->toString(TRUE); - $response = new ModifiedResourceResponse($entity, 201, ['Location' => $url->getGeneratedUrl()]); - return $response; + $headers = []; + if (in_array('canonical', $entity->uriRelationships(), TRUE)) { + $url = $entity->urlInfo('canonical', ['absolute' => TRUE])->toString(TRUE); + $headers['Location'] = $url->getGeneratedUrl(); + } + return new ModifiedResourceResponse($entity, 201, $headers); } catch (EntityStorageException $e) { throw new HttpException(500, 'Internal Server Error', $e); } } + /** + * Gets the values from the field item list casted to the correct type. + * + * Values are casted to the correct type so we can determine whether or not + * something has changed. REST formats such as JSON support typed data but + * Drupal's database API will return values as strings. Currently, only + * primitive data types know how to cast their values to the correct type. + * + * @param \Drupal\Core\Field\FieldItemListInterface $field_item_list + * The field item list to retrieve its data from. + * + * @return mixed[][] + * The values from the field item list casted to the correct type. The array + * of values returned is a multidimensional array keyed by delta and the + * property name. + */ + protected function getCastedValueFromFieldItemList(FieldItemListInterface $field_item_list) { + $value = $field_item_list->getValue(); + + foreach ($value as $delta => $field_item_value) { + /** @var \Drupal\Core\Field\FieldItemInterface $field_item */ + $field_item = $field_item_list->get($delta); + $properties = $field_item->getProperties(TRUE); + // Foreach field value we check whether we know the underlying property. + // If we exists we try to cast the value. + foreach ($field_item_value as $property_name => $property_value) { + if (isset($properties[$property_name]) && ($property = $field_item->get($property_name)) && $property instanceof PrimitiveInterface) { + $value[$delta][$property_name] = $property->getCastedValue(); + } + } + } + + return $value; + } + /** * Responds to entity PATCH requests. * @@ -204,8 +257,9 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity if ($entity->getEntityTypeId() != $definition['entity_type']) { throw new BadRequestHttpException('Invalid entity type'); } - if (!$original_entity->access('update')) { - throw new AccessDeniedHttpException(); + $entity_access = $original_entity->access('update', NULL, TRUE); + if (!$entity_access->isAllowed()) { + throw new AccessDeniedHttpException($entity_access->getReason() ?: $this->generateFallbackAccessDeniedMessage($entity, 'update')); } // Overwrite the received properties. @@ -218,8 +272,15 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity // them. However, rather than throwing an error, we just ignore them as // long as their specified values match their current values. if (in_array($field_name, $entity_keys, TRUE)) { + // @todo Work around the wrong assumption that entity keys need special + // treatment, when only read-only fields need it. + // This will be fixed in https://www.drupal.org/node/2824851. + if ($entity->getEntityTypeId() == 'comment' && $field_name == 'status' && !$original_entity->get($field_name)->access('edit')) { + throw new AccessDeniedHttpException("Access denied on updating field '$field_name'."); + } + // Unchanged values for entity keys don't need access checking. - if ($original_entity->get($field_name)->getValue() === $entity->get($field_name)->getValue()) { + if ($this->getCastedValueFromFieldItemList($original_entity->get($field_name)) === $this->getCastedValueFromFieldItemList($entity->get($field_name))) { continue; } // It is not possible to set the language to NULL as it is automatically @@ -239,7 +300,7 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity $this->validate($original_entity); try { $original_entity->save(); - $this->logger->notice('Updated entity %type with ID %id.', array('%type' => $original_entity->getEntityTypeId(), '%id' => $original_entity->id())); + $this->logger->notice('Updated entity %type with ID %id.', ['%type' => $original_entity->getEntityTypeId(), '%id' => $original_entity->id()]); // Return the updated entity in the response body. return new ModifiedResourceResponse($original_entity, 200); @@ -261,12 +322,13 @@ public function patch(EntityInterface $original_entity, EntityInterface $entity * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function delete(EntityInterface $entity) { - if (!$entity->access('delete')) { - throw new AccessDeniedHttpException(); + $entity_access = $entity->access('delete', NULL, TRUE); + if (!$entity_access->isAllowed()) { + throw new AccessDeniedHttpException($entity_access->getReason() ?: $this->generateFallbackAccessDeniedMessage($entity, 'delete')); } try { $entity->delete(); - $this->logger->notice('Deleted entity %type with ID %id.', array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id())); + $this->logger->notice('Deleted entity %type with ID %id.', ['%type' => $entity->getEntityTypeId(), '%id' => $entity->id()]); // DELETE responses have an empty body. return new ModifiedResourceResponse(NULL, 204); @@ -277,36 +339,23 @@ public function delete(EntityInterface $entity) { } /** - * Verifies that the whole entity does not violate any validation constraints. + * Generates a fallback access denied message, when no specific reason is set. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object. + * @param string $operation + * The disallowed entity operation. * - * @throws \Symfony\Component\HttpKernel\Exception\HttpException - * If validation errors are found. + * @return string + * The proper message to display in the AccessDeniedHttpException. */ - protected function validate(EntityInterface $entity) { - // @todo Remove when https://www.drupal.org/node/2164373 is committed. - if (!$entity instanceof FieldableEntityInterface) { - return; - } - $violations = $entity->validate(); + protected function generateFallbackAccessDeniedMessage(EntityInterface $entity, $operation) { + $message = "You are not authorized to {$operation} this {$entity->getEntityTypeId()} entity"; - // Remove violations of inaccessible fields as they cannot stem from our - // changes. - $violations->filterByFieldAccess(); - - if (count($violations) > 0) { - $message = "Unprocessable Entity: validation failed.\n"; - foreach ($violations as $violation) { - $message .= $violation->getPropertyPath() . ': ' . $violation->getMessage() . "\n"; - } - // Instead of returning a generic 400 response we use the more specific - // 422 Unprocessable Entity code from RFC 4918. That way clients can - // distinguish between general syntax errors in bad serializations (code - // 400) and semantic errors in well-formed requests (code 422). - throw new HttpException(422, $message); + if ($entity->bundle() !== $entity->getEntityTypeId()) { + $message .= " of bundle {$entity->bundle()}"; } + return "{$message}."; } /** @@ -331,7 +380,7 @@ protected function getBaseRoute($canonical_path, $method) { $route = parent::getBaseRoute($canonical_path, $method); $definition = $this->getPluginDefinition(); - $parameters = $route->getOption('parameters') ?: array(); + $parameters = $route->getOption('parameters') ?: []; $parameters[$definition['entity_type']]['type'] = 'entity:' . $definition['entity_type']; $route->setOption('parameters', $parameters); @@ -371,4 +420,38 @@ public function calculateDependencies() { } } + /** + * Adds link headers to a response. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity. + * @param \Symfony\Component\HttpFoundation\Response $response + * The response. + * + * @see https://tools.ietf.org/html/rfc5988#section-5 + */ + protected function addLinkHeaders(EntityInterface $entity, Response $response) { + foreach ($entity->uriRelationships() as $relation_name) { + if ($this->linkRelationTypeManager->hasDefinition($relation_name)) { + /** @var \Drupal\Core\Http\LinkRelationTypeInterface $link_relation_type */ + $link_relation_type = $this->linkRelationTypeManager->createInstance($relation_name); + + $generator_url = $entity->toUrl($relation_name) + ->setAbsolute(TRUE) + ->toString(TRUE); + if ($response instanceof CacheableResponseInterface) { + $response->addCacheableDependency($generator_url); + } + $uri = $generator_url->getGeneratedUrl(); + + $relationship = $link_relation_type->isRegistered() + ? $link_relation_type->getRegisteredName() + : $link_relation_type->getExtensionUri(); + + $link_header = '<' . $uri . '>; rel="' . $relationship . '"'; + $response->headers->set('Link', $link_header, FALSE); + } + } + } + } diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResourceAccessTrait.php b/core/modules/rest/src/Plugin/rest/resource/EntityResourceAccessTrait.php new file mode 100644 index 00000000..7bf8e824 --- /dev/null +++ b/core/modules/rest/src/Plugin/rest/resource/EntityResourceAccessTrait.php @@ -0,0 +1,35 @@ +_restSubmittedFields as $key => $field_name) { + if (!$entity->get($field_name)->access('edit')) { + throw new AccessDeniedHttpException("Access denied on creating field '$field_name'."); + } + } + } + +} diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResourceValidationTrait.php b/core/modules/rest/src/Plugin/rest/resource/EntityResourceValidationTrait.php new file mode 100644 index 00000000..09b4b64b --- /dev/null +++ b/core/modules/rest/src/Plugin/rest/resource/EntityResourceValidationTrait.php @@ -0,0 +1,47 @@ +validate(); + + // Remove violations of inaccessible fields as they cannot stem from our + // changes. + $violations->filterByFieldAccess(); + + if ($violations->count() > 0) { + $message = "Unprocessable Entity: validation failed.\n"; + foreach ($violations as $violation) { + // We strip every HTML from the error message to have a nicer to read + // message on REST responses. + $message .= $violation->getPropertyPath() . ': ' . PlainTextOutput::renderFromHtml($violation->getMessage()) . "\n"; + } + throw new UnprocessableEntityHttpException($message); + } + } + +} diff --git a/core/modules/rest/src/Plugin/views/display/RestExport.php b/core/modules/rest/src/Plugin/views/display/RestExport.php index 1a7a7f1a..2b59af51 100644 --- a/core/modules/rest/src/Plugin/views/display/RestExport.php +++ b/core/modules/rest/src/Plugin/views/display/RestExport.php @@ -14,6 +14,7 @@ use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\PathPluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; /** @@ -86,7 +87,23 @@ class RestExport extends PathPluginBase implements ResponseDisplayPluginInterfac protected $authenticationCollector; /** - * The authentication providers, keyed by ID. + * The authentication providers, like 'cookie' and 'basic_auth'. + * + * @var string[] + */ + protected $authenticationProviderIds; + + /** + * The authentication providers' modules, keyed by provider ID. + * + * Authentication providers like 'cookie' and 'basic_auth' are the array + * keys. The array values are the module names, e.g.: + * @code + * ['cookie' => 'user', 'basic_auth' => 'basic_auth'] + * @endcode + * + * @deprecated as of 8.4.x, will be removed in before Drupal 9.0.0, see + * https://www.drupal.org/node/2825204. * * @var string[] */ @@ -114,6 +131,13 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition parent::__construct($configuration, $plugin_id, $plugin_definition, $route_provider, $state); $this->renderer = $renderer; + // $authentication_providers as defined in + // \Drupal\Core\DependencyInjection\Compiler\AuthenticationProviderPass + // and as such it is an array, with authentication providers (cookie, + // basic_auth) as keys and modules providing those as values (user, + // basic_auth). + $this->authenticationProviderIds = array_keys($authentication_providers); + // For BC reasons we keep around authenticationProviders as before. $this->authenticationProviders = $authentication_providers; } @@ -226,7 +250,7 @@ public function getContentType() { * An array to use as value for "#options" in the form element. */ public function getAuthOptions() { - return array_combine($this->authenticationProviders, $this->authenticationProviders); + return array_combine($this->authenticationProviderIds, $this->authenticationProviderIds); } /** @@ -265,21 +289,21 @@ public function optionsSummary(&$categories, &$options) { // Hide some settings, as they aren't useful for pure data output. unset($options['show_admin_links'], $options['analyze-theme']); - $categories['path'] = array( + $categories['path'] = [ 'title' => $this->t('Path settings'), 'column' => 'second', - 'build' => array( + 'build' => [ '#weight' => -10, - ), - ); + ], + ]; $options['path']['category'] = 'path'; $options['path']['title'] = $this->t('Path'); - $options['auth'] = array( + $options['auth'] = [ 'category' => 'path', 'title' => $this->t('Authentication'), 'value' => views_ui_truncate($auth, 24), - ); + ]; // Remove css/exposed form settings, as they are not used for the data // display. @@ -295,13 +319,13 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); if ($form_state->get('section') === 'auth') { $form['#title'] .= $this->t('The supported authentication methods for this view'); - $form['auth'] = array( + $form['auth'] = [ '#type' => 'checkboxes', '#title' => $this->t('Authentication methods'), - '#description' => $this->t('These are the supported authentication providers for this view. When this view is requested, the client will be forced to authenticate with one of the selected providers. Make sure you set the appropiate requirements at the Access section since the Authentication System will fallback to the anonymous user if it fails to authenticate. For example: require Access: Role | Authenticated User.'), + '#description' => $this->t('These are the supported authentication providers for this view. When this view is requested, the client will be forced to authenticate with one of the selected providers. Make sure you set the appropriate requirements at the Access section since the Authentication System will fallback to the anonymous user if it fails to authenticate. For example: require Access: Role | Authenticated User.'), '#options' => $this->getAuthOptions(), '#default_value' => $this->getOption('auth'), - ); + ]; } } @@ -347,6 +371,26 @@ public function collectRoutes(RouteCollection $collection) { } } + /** + * Determines whether the view overrides the given route. + * + * @param string $view_path + * The path of the view. + * @param \Symfony\Component\Routing\Route $view_route + * The route of the view. + * @param \Symfony\Component\Routing\Route $route + * The route itself. + * + * @return bool + * TRUE, when the view should override the given route. + */ + protected function overrideApplies($view_path, Route $view_route, Route $route) { + $route_formats = explode('|', $route->getRequirement('_format')); + $view_route_formats = explode('|', $view_route->getRequirement('_format')); + return $this->overrideAppliesPathAndMethod($view_path, $view_route, $route) + && (!$route->hasRequirement('_format') || array_intersect($route_formats, $view_route_formats) != []); + } + /** * {@inheritdoc} */ @@ -385,8 +429,8 @@ public function execute() { * {@inheritdoc} */ public function render() { - $build = array(); - $build['#markup'] = $this->renderer->executeInRenderContext(new RenderContext(), function() { + $build = []; + $build['#markup'] = $this->renderer->executeInRenderContext(new RenderContext(), function () { return $this->view->style_plugin->render(); }); @@ -414,7 +458,7 @@ public function render() { $build['#markup'] = ViewsRenderPipelineMarkup::create($build['#markup']); } - parent::applyDisplayCachablityMetadata($build); + parent::applyDisplayCacheabilityMetadata($build); return $build; } @@ -436,10 +480,14 @@ public function calculateDependencies() { $dependencies = parent::calculateDependencies(); $dependencies += ['module' => []]; - $modules = array_map(function ($authentication_provider) { - return $this->authenticationProviders[$authentication_provider]; - }, $this->getOption('auth')); - $dependencies['module'] = array_merge($dependencies['module'], $modules); + $dependencies['module'] = array_merge($dependencies['module'], array_filter(array_map(function ($provider) { + // During the update path the provider options might be wrong. This can + // happen when any update function, like block_update_8300() triggers a + // view to be saved. + return isset($this->authenticationProviderIds[$provider]) + ? $this->authenticationProviderIds[$provider] + : NULL; + }, $this->getOption('auth')))); return $dependencies; } diff --git a/core/modules/rest/src/Plugin/views/row/DataFieldRow.php b/core/modules/rest/src/Plugin/views/row/DataFieldRow.php index 8cebb738..c511877c 100644 --- a/core/modules/rest/src/Plugin/views/row/DataFieldRow.php +++ b/core/modules/rest/src/Plugin/views/row/DataFieldRow.php @@ -31,14 +31,14 @@ class DataFieldRow extends RowPluginBase { * * @var array */ - protected $replacementAliases = array(); + protected $replacementAliases = []; /** * Stores an array of options to determine if the raw field output is used. * * @var array */ - protected $rawOutputOptions = array(); + protected $rawOutputOptions = []; /** * {@inheritdoc} @@ -61,7 +61,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o */ protected function defineOptions() { $options = parent::defineOptions(); - $options['field_options'] = array('default' => array()); + $options['field_options'] = ['default' => []]; return $options; } @@ -72,12 +72,12 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['field_options'] = array( + $form['field_options'] = [ '#type' => 'table', - '#header' => array($this->t('Field'), $this->t('Alias'), $this->t('Raw output')), + '#header' => [$this->t('Field'), $this->t('Alias'), $this->t('Raw output')], '#empty' => $this->t('You have no fields. Add some to your view.'), '#tree' => TRUE, - ); + ]; $options = $this->options['field_options']; @@ -87,22 +87,22 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if (!empty($field['exclude'])) { continue; } - $form['field_options'][$id]['field'] = array( + $form['field_options'][$id]['field'] = [ '#markup' => $id, - ); - $form['field_options'][$id]['alias'] = array( - '#title' => $this->t('Alias for @id', array('@id' => $id)), + ]; + $form['field_options'][$id]['alias'] = [ + '#title' => $this->t('Alias for @id', ['@id' => $id]), '#title_display' => 'invisible', '#type' => 'textfield', '#default_value' => isset($options[$id]['alias']) ? $options[$id]['alias'] : '', - '#element_validate' => array(array($this, 'validateAliasName')), - ); - $form['field_options'][$id]['raw_output'] = array( - '#title' => $this->t('Raw output for @id', array('@id' => $id)), + '#element_validate' => [[$this, 'validateAliasName']], + ]; + $form['field_options'][$id]['raw_output'] = [ + '#title' => $this->t('Raw output for @id', ['@id' => $id]), '#title_display' => 'invisible', '#type' => 'checkbox', '#default_value' => isset($options[$id]['raw_output']) ? $options[$id]['raw_output'] : '', - ); + ]; } } } @@ -121,7 +121,7 @@ public function validateAliasName($element, FormStateInterface $form_state) { */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { // Collect an array of aliases to validate. - $aliases = static::extractFromOptionsArray('alias', $form_state->getValue(array('row_options', 'field_options'))); + $aliases = static::extractFromOptionsArray('alias', $form_state->getValue(['row_options', 'field_options'])); // If array filter returns empty, no values have been entered. Unique keys // should only be validated if we have some. @@ -134,7 +134,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function render($row) { - $output = array(); + $output = []; foreach ($this->view->field as $id => $field) { // If the raw output option has been set, just get the raw value. @@ -184,7 +184,7 @@ public function getFieldKeyAlias($id) { * A regular one dimensional array of values. */ protected static function extractFromOptionsArray($key, $options) { - return array_map(function($item) use ($key) { + return array_map(function ($item) use ($key) { return isset($item[$key]) ? $item[$key] : NULL; }, $options); } diff --git a/core/modules/rest/src/Plugin/views/style/Serializer.php b/core/modules/rest/src/Plugin/views/style/Serializer.php index 7e9b4331..895b9fe1 100644 --- a/core/modules/rest/src/Plugin/views/style/Serializer.php +++ b/core/modules/rest/src/Plugin/views/style/Serializer.php @@ -45,7 +45,7 @@ class Serializer extends StylePluginBase implements CacheableDependencyInterface * * @var array */ - protected $formats = array(); + protected $formats = []; /** * The serialization format providers, keyed by format. @@ -85,7 +85,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition */ protected function defineOptions() { $options = parent::defineOptions(); - $options['formats'] = array('default' => array()); + $options['formats'] = ['default' => []]; return $options; } @@ -96,13 +96,13 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['formats'] = array( + $form['formats'] = [ '#type' => 'checkboxes', '#title' => $this->t('Accepted request formats'), '#description' => $this->t('Request formats that will be allowed in responses. If none are selected all formats will be allowed.'), '#options' => $this->getFormatOptions(), '#default_value' => $this->options['formats'], - ); + ]; } /** @@ -111,15 +111,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function submitOptionsForm(&$form, FormStateInterface $form_state) { parent::submitOptionsForm($form, $form_state); - $formats = $form_state->getValue(array('style_options', 'formats')); - $form_state->setValue(array('style_options', 'formats'), array_filter($formats)); + $formats = $form_state->getValue(['style_options', 'formats']); + $form_state->setValue(['style_options', 'formats'], array_filter($formats)); } /** * {@inheritdoc} */ public function render() { - $rows = array(); + $rows = []; // If the Data Entity row plugin is used, this will be an array of entities // which will pass through Serializer to one of the registered Normalizers, // which will transform it to arrays/scalars. If the Data field row plugin diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php index 088dca29..e5437ccb 100644 --- a/core/modules/rest/src/RequestHandler.php +++ b/core/modules/rest/src/RequestHandler.php @@ -2,22 +2,23 @@ namespace Drupal\rest; +use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityStorageInterface; -use Drupal\Core\Cache\CacheableResponseInterface; -use Drupal\Core\Render\RenderContext; use Drupal\Core\Routing\RouteMatchInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; -use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\Serializer\Exception\InvalidArgumentException; /** * Acts as intermediate request forwarder for resource plugins. + * + * @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber */ class RequestHandler implements ContainerAwareInterface, ContainerInjectionInterface { @@ -59,22 +60,20 @@ public static function create(ContainerInterface $container) { * The response object. */ public function handle(RouteMatchInterface $route_match, Request $request) { - $method = strtolower($request->getMethod()); - // Symfony is built to transparently map HEAD requests to a GET request. In // the case of the REST module's RequestHandler though, we essentially have // our own light-weight routing system on top of the Drupal/symfony routing - // system. So, we have to do the same as what the UrlMatcher does: map HEAD - // requests to the logic for GET. This also guarantees response headers for - // HEAD requests are identical to those for GET requests, because we just - // return a GET response. Response::prepare() will transform it to a HEAD - // response at the very last moment. + // system. So, we have to respect the decision that the routing system made: + // we look not at the request method, but at the route's method. All REST + // routes are guaranteed to have _method set. + // Response::prepare() will transform it to a HEAD response at the very last + // moment. // @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 // @see \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection() // @see \Symfony\Component\HttpFoundation\Response::prepare() - if ($method === 'head') { - $method = 'get'; - } + $method = strtolower($route_match->getRouteObject()->getMethods()[0]); + assert(count($route_match->getRouteObject()->getMethods()) === 1); + $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config'); /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */ @@ -89,38 +88,39 @@ public function handle(RouteMatchInterface $route_match, Request $request) { if (!empty($received)) { $format = $request->getContentType(); - // Only allow serialization formats that are explicitly configured. If no - // formats are configured allow all and hope that the serializer knows the - // format. If the serializer cannot handle it an exception will be thrown - // that bubbles up to the client. - $request_method = $request->getMethod(); - if (in_array($format, $resource_config->getFormats($request_method))) { - $definition = $resource->getPluginDefinition(); + $definition = $resource->getPluginDefinition(); + + // First decode the request data. We can then determine if the + // serialized data was malformed. + try { + $unserialized = $serializer->decode($received, $format, ['request_method' => $method]); + } + catch (UnexpectedValueException $e) { + // If an exception was thrown at this stage, there was a problem + // decoding the data. Throw a 400 http exception. + throw new BadRequestHttpException($e->getMessage()); + } + + // Then attempt to denormalize if there is a serialization class. + if (!empty($definition['serialization_class'])) { try { - if (!empty($definition['serialization_class'])) { - $unserialized = $serializer->deserialize($received, $definition['serialization_class'], $format, array('request_method' => $method)); - } - // If the plugin does not specify a serialization class just decode - // the received data. - else { - $unserialized = $serializer->decode($received, $format, array('request_method' => $method)); - } + $unserialized = $serializer->denormalize($unserialized, $definition['serialization_class'], $format, ['request_method' => $method]); } + // These two serialization exception types mean there was a problem + // with the structure of the decoded data and it's not valid. catch (UnexpectedValueException $e) { - $error['error'] = $e->getMessage(); - $content = $serializer->serialize($error, $format); - return new Response($content, 400, array('Content-Type' => $request->getMimeType($format))); + throw new UnprocessableEntityHttpException($e->getMessage()); + } + catch (InvalidArgumentException $e) { + throw new UnprocessableEntityHttpException($e->getMessage()); } - } - else { - throw new UnsupportedMediaTypeHttpException(); } } // Determine the request parameters that should be passed to the resource // plugin. $route_parameters = $route_match->getParameters(); - $parameters = array(); + $parameters = []; // Filter out all internal parameters starting with "_". foreach ($route_parameters as $key => $parameter) { if ($key{0} !== '_') { @@ -129,118 +129,13 @@ public function handle(RouteMatchInterface $route_match, Request $request) { } // Invoke the operation on the resource plugin. - $format = $this->getResponseFormat($route_match, $request); - $response = call_user_func_array(array($resource, $method), array_merge($parameters, array($unserialized, $request))); - - return $response instanceof ResourceResponseInterface ? - $this->renderResponse($request, $response, $serializer, $format, $resource_config) : - $response; - } - - /** - * Determines the format to respond in. - * - * Respects the requested format if one is specified. However, it is common to - * forget to specify a request format in case of a POST or PATCH. Rather than - * simply throwing an error, we apply the robustness principle: when POSTing - * or PATCHing using a certain format, you probably expect a response in that - * same format. - * - * @param \Drupal\Core\Routing\RouteMatchInterface $route_match - * The current route match. - * @param \Symfony\Component\HttpFoundation\Request $request - * The current request. - * - * @return string - * The response format. - */ - protected function getResponseFormat(RouteMatchInterface $route_match, Request $request) { - $route = $route_match->getRouteObject(); - $acceptable_request_formats = $route->hasRequirement('_format') ? explode('|', $route->getRequirement('_format')) : []; - $acceptable_content_type_formats = $route->hasRequirement('_content_type_format') ? explode('|', $route->getRequirement('_content_type_format')) : []; - $acceptable_formats = $request->isMethodSafe() ? $acceptable_request_formats : $acceptable_content_type_formats; - - $requested_format = $request->getRequestFormat(); - $content_type_format = $request->getContentType(); - - // If an acceptable format is requested, then use that. Otherwise, including - // and particularly when the client forgot to specify a format, then use - // heuristics to select the format that is most likely expected. - if (in_array($requested_format, $acceptable_formats)) { - return $requested_format; - } - // If a request body is present, then use the format corresponding to the - // request body's Content-Type for the response, if it's an acceptable - // format for the request. - elseif (!empty($request->getContent()) && in_array($content_type_format, $acceptable_content_type_formats)) { - return $content_type_format; - } - // Otherwise, use the first acceptable format. - elseif (!empty($acceptable_formats)) { - return $acceptable_formats[0]; - } - // Sometimes, there are no acceptable formats, e.g. DELETE routes. - else { - return NULL; - } - } - - /** - * Renders a resource response. - * - * Serialization can invoke rendering (e.g., generating URLs), but the - * serialization API does not provide a mechanism to collect the - * bubbleable metadata associated with that (e.g., language and other - * contexts), so instead, allow those to "leak" and collect them here in - * a render context. - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. - * @param \Drupal\rest\ResourceResponseInterface $response - * The response from the REST resource. - * @param \Symfony\Component\Serializer\SerializerInterface $serializer - * The serializer to use. - * @param string|null $format - * The response format, or NULL in case the response does not need a format, - * for example for the response to a DELETE request. - * @param \Drupal\rest\RestResourceConfigInterface $resource_config - * The resource config. - * - * @return \Drupal\rest\ResourceResponse - * The altered response. - * - * @todo Add test coverage for language negotiation contexts in - * https://www.drupal.org/node/2135829. - */ - protected function renderResponse(Request $request, ResourceResponseInterface $response, SerializerInterface $serializer, $format, RestResourceConfigInterface $resource_config) { - $data = $response->getResponseData(); + $response = call_user_func_array([$resource, $method], array_merge($parameters, [$unserialized, $request])); if ($response instanceof CacheableResponseInterface) { // Add rest config's cache tags. $response->addCacheableDependency($resource_config); } - // If there is data to send, serialize and set it as the response body. - if ($data !== NULL) { - if ($response instanceof CacheableResponseInterface) { - $context = new RenderContext(); - $output = $this->container->get('renderer') - ->executeInRenderContext($context, function () use ($serializer, $data, $format) { - return $serializer->serialize($data, $format); - }); - - if (!$context->isEmpty()) { - $response->addCacheableDependency($context->pop()); - } - } - else { - $output = $serializer->serialize($data, $format); - } - - $response->setContent($output); - $response->headers->set('Content-Type', $request->getMimeType($format)); - } - return $response; } diff --git a/core/modules/rest/src/ResourceResponse.php b/core/modules/rest/src/ResourceResponse.php index d4279a4c..eb955c29 100644 --- a/core/modules/rest/src/ResourceResponse.php +++ b/core/modules/rest/src/ResourceResponse.php @@ -31,7 +31,7 @@ class ResourceResponse extends Response implements CacheableResponseInterface, R * @param array $headers * An array of response headers. */ - public function __construct($data = NULL, $status = 200, $headers = array()) { + public function __construct($data = NULL, $status = 200, $headers = []) { $this->responseData = $data; parent::__construct('', $status, $headers); } diff --git a/core/modules/rest/src/ResourceResponseTrait.php b/core/modules/rest/src/ResourceResponseTrait.php index d16bc198..c61e4e63 100644 --- a/core/modules/rest/src/ResourceResponseTrait.php +++ b/core/modules/rest/src/ResourceResponseTrait.php @@ -2,7 +2,6 @@ namespace Drupal\rest; - trait ResourceResponseTrait { /** diff --git a/core/modules/rest/src/RestServiceProvider.php b/core/modules/rest/src/RestServiceProvider.php new file mode 100644 index 00000000..e705de41 --- /dev/null +++ b/core/modules/rest/src/RestServiceProvider.php @@ -0,0 +1,51 @@ +getParameter(('container.modules')); + if (isset($modules['hal'])) { + // @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + // Use hal.link_manager instead. + // @see https://www.drupal.org/node/2830467 + $service_definition = new DefinitionDecorator(new Reference('hal.link_manager')); + $service_definition->setClass(LinkManager::class); + $container->setDefinition('rest.link_manager', $service_definition); + + // @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + // Use hal.link_manager.type instead. + // @see https://www.drupal.org/node/2830467 + $service_definition = new DefinitionDecorator(new Reference('hal.link_manager.type')); + $service_definition->setClass(TypeLinkManager::class); + $container->setDefinition('rest.link_manager.type', $service_definition); + + // @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. + // Use hal.link_manager.relation instead. + // @see https://www.drupal.org/node/2830467 + $service_definition = new DefinitionDecorator(new Reference('hal.link_manager.relation')); + $service_definition->setClass(RelationLinkManager::class); + $container->setDefinition('rest.link_manager.relation', $service_definition); + } + } + +} diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php index 8aedfba5..5ba4c5da 100644 --- a/core/modules/rest/src/Routing/ResourceRoutes.php +++ b/core/modules/rest/src/Routing/ResourceRoutes.php @@ -3,16 +3,18 @@ namespace Drupal\rest\Routing; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Routing\RouteSubscriberBase; +use Drupal\Core\Routing\RouteBuildEvent; +use Drupal\Core\Routing\RoutingEvents; use Drupal\rest\Plugin\Type\ResourcePluginManager; use Drupal\rest\RestResourceConfigInterface; use Psr\Log\LoggerInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Routing\RouteCollection; /** * Subscriber for REST-style routes. */ -class ResourceRoutes extends RouteSubscriberBase { +class ResourceRoutes implements EventSubscriberInterface { /** * The plugin manager for REST plugins. @@ -54,18 +56,19 @@ public function __construct(ResourcePluginManager $manager, EntityTypeManagerInt /** * Alters existing routes for a specific collection. * - * @param \Symfony\Component\Routing\RouteCollection $collection - * The route collection for adding routes. + * @param \Drupal\Core\Routing\RouteBuildEvent $event + * The route build event. * @return array */ - protected function alterRoutes(RouteCollection $collection) { - // Iterate over all enabled REST resource configs. + public function onDynamicRouteEvent(RouteBuildEvent $event) { + // Iterate over all enabled REST resource config entities. /** @var \Drupal\rest\RestResourceConfigInterface[] $resource_configs */ $resource_configs = $this->resourceConfigStorage->loadMultiple(); - // Iterate over all enabled resource plugins. foreach ($resource_configs as $resource_config) { - $resource_routes = $this->getRoutesForResourceConfig($resource_config); - $collection->addCollection($resource_routes); + if ($resource_config->status()) { + $resource_routes = $this->getRoutesForResourceConfig($resource_config); + $event->getRouteCollection()->addCollection($resource_routes); + } } } @@ -95,13 +98,13 @@ protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_ // Check that authentication providers are defined. if (empty($rest_resource_config->getAuthenticationProviders($method))) { - $this->logger->error('At least one authentication provider must be defined for resource @id', array(':id' => $rest_resource_config->id())); + $this->logger->error('At least one authentication provider must be defined for resource @id', [':id' => $rest_resource_config->id()]); continue; } // Check that formats are defined. if (empty($rest_resource_config->getFormats($method))) { - $this->logger->error('At least one format must be defined for resource @id', array(':id' => $rest_resource_config->id())); + $this->logger->error('At least one format must be defined for resource @id', [':id' => $rest_resource_config->id()]); continue; } @@ -112,8 +115,15 @@ protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_ continue; } - // The configuration seems legit at this point, so we set the - // authentication provider and add the route. + // The configuration has been validated, so we update the route to: + // - set the allowed request body content types/formats for methods that + // allow request bodies to be sent + // - set the allowed authentication providers + if (in_array($method, ['POST', 'PATCH', 'PUT'], TRUE)) { + // Restrict the incoming HTTP Content-type header to the allowed + // formats. + $route->addRequirements(['_content_type_format' => implode('|', $rest_resource_config->getFormats($method))]); + } $route->setOption('_auth', $rest_resource_config->getAuthenticationProviders($method)); $route->setDefault('_rest_resource_config', $rest_resource_config->id()); $collection->add("rest.$name", $route); @@ -123,4 +133,12 @@ protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_ return $collection; } + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::DYNAMIC] = 'onDynamicRouteEvent'; + return $events; + } + } diff --git a/core/modules/rest/src/Tests/RESTTestBase.php b/core/modules/rest/src/Tests/RESTTestBase.php index c755967e..3f97e469 100644 --- a/core/modules/rest/src/Tests/RESTTestBase.php +++ b/core/modules/rest/src/Tests/RESTTestBase.php @@ -2,10 +2,13 @@ namespace Drupal\rest\Tests; +use Drupal\Component\Utility\NestedArray; use Drupal\Core\Config\Entity\ConfigEntityType; use Drupal\node\NodeInterface; use Drupal\rest\RestResourceConfigInterface; use Drupal\simpletest\WebTestBase; +use GuzzleHttp\Cookie\FileCookieJar; +use GuzzleHttp\Cookie\SetCookie; /** * Test helper class that provides a REST client method to send HTTP requests. @@ -62,18 +65,57 @@ abstract class RESTTestBase extends WebTestBase { * * @var array */ - public static $modules = array('rest', 'entity_test'); + public static $modules = ['rest', 'entity_test']; + + /** + * The last response. + * + * @var \Psr\Http\Message\ResponseInterface + */ + protected $response; protected function setUp() { parent::setUp(); $this->defaultFormat = 'hal_json'; $this->defaultMimeType = 'application/hal+json'; - $this->defaultAuth = array('cookie'); + $this->defaultAuth = ['cookie']; $this->resourceConfigStorage = $this->container->get('entity_type.manager')->getStorage('rest_resource_config'); // Create a test content type for node testing. if (in_array('node', static::$modules)) { - $this->drupalCreateContentType(array('name' => 'resttest', 'type' => 'resttest')); + $this->drupalCreateContentType(['name' => 'resttest', 'type' => 'resttest']); } + + $this->cookieFile = $this->publicFilesDirectory . '/cookie.jar'; + } + + /** + * Calculates cookies used by guzzle later. + * + * @return \GuzzleHttp\Cookie\CookieJarInterface + * The used CURL options in guzzle. + */ + protected function cookies() { + $cookies = []; + + foreach ($this->cookies as $key => $cookie) { + $cookies[$key][] = $cookie['value']; + } + + $request = \Drupal::request(); + $cookies = NestedArray::mergeDeep($cookies, $this->extractCookiesFromRequest($request)); + + $cookie_jar = new FileCookieJar($this->cookieFile); + foreach ($cookies as $key => $cookie_values) { + foreach ($cookie_values as $cookie_value) { + // setcookie() sets the value of a cookie to be deleted, when its gonna + // be removed. + if ($cookie_value !== 'deleted') { + $cookie_jar->setCookie(new SetCookie(['Name' => $key, 'Value' => $cookie_value, 'Domain' => $request->getHost()])); + } + } + } + + return $cookie_jar; } /** @@ -100,118 +142,137 @@ protected function httpRequest($url, $method, $body = NULL, $mime_type = NULL, $ if (!isset($mime_type)) { $mime_type = $this->defaultMimeType; } - if (!in_array($method, array('GET', 'HEAD', 'OPTIONS', 'TRACE'))) { + if (!in_array($method, ['GET', 'HEAD', 'OPTIONS', 'TRACE'])) { // GET the CSRF token first for writing requests. $requested_token = $this->drupalGet('session/token'); } + $client = \Drupal::httpClient(); $url = $this->buildUrl($url); - $curl_options = array(); + $options = [ + 'http_errors' => FALSE, + 'cookies' => $this->cookies(), + 'curl' => [ + CURLOPT_HEADERFUNCTION => [&$this, 'curlHeaderCallback'], + ], + ]; switch ($method) { case 'GET': - // Set query if there are additional GET parameters. - $curl_options = array( - CURLOPT_HTTPGET => TRUE, - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_URL => $url, - CURLOPT_NOBODY => FALSE, - CURLOPT_HTTPHEADER => array('Accept: ' . $mime_type), - ); + $options += [ + 'headers' => [ + 'Accept' => $mime_type, + ], + ]; + $response = $client->get($url, $options); break; case 'HEAD': - $curl_options = array( - CURLOPT_HTTPGET => FALSE, - CURLOPT_CUSTOMREQUEST => 'HEAD', - CURLOPT_URL => $url, - CURLOPT_NOBODY => TRUE, - CURLOPT_HTTPHEADER => array('Accept: ' . $mime_type), - ); + $response = $client->head($url, $options); break; case 'POST': - $curl_options = array( - CURLOPT_HTTPGET => FALSE, - CURLOPT_POST => TRUE, - CURLOPT_POSTFIELDS => $body, - CURLOPT_URL => $url, - CURLOPT_NOBODY => FALSE, - CURLOPT_HTTPHEADER => $csrf_token !== FALSE ? array( - 'Content-Type: ' . $mime_type, - 'X-CSRF-Token: ' . ($csrf_token === NULL ? $requested_token : $csrf_token), - ) : array( - 'Content-Type: ' . $mime_type, - ), - ); + $options += [ + 'headers' => $csrf_token !== FALSE ? [ + 'Content-Type' => $mime_type, + 'X-CSRF-Token' => ($csrf_token === NULL ? $requested_token : $csrf_token), + ] : [ + 'Content-Type' => $mime_type, + ], + 'body' => $body, + ]; + $response = $client->post($url, $options); break; case 'PUT': - $curl_options = array( - CURLOPT_HTTPGET => FALSE, - CURLOPT_CUSTOMREQUEST => 'PUT', - CURLOPT_POSTFIELDS => $body, - CURLOPT_URL => $url, - CURLOPT_NOBODY => FALSE, - CURLOPT_HTTPHEADER => $csrf_token !== FALSE ? array( - 'Content-Type: ' . $mime_type, - 'X-CSRF-Token: ' . ($csrf_token === NULL ? $requested_token : $csrf_token), - ) : array( - 'Content-Type: ' . $mime_type, - ), - ); + $options += [ + 'headers' => $csrf_token !== FALSE ? [ + 'Content-Type' => $mime_type, + 'X-CSRF-Token' => ($csrf_token === NULL ? $requested_token : $csrf_token), + ] : [ + 'Content-Type' => $mime_type, + ], + 'body' => $body, + ]; + $response = $client->put($url, $options); break; case 'PATCH': - $curl_options = array( - CURLOPT_HTTPGET => FALSE, - CURLOPT_CUSTOMREQUEST => 'PATCH', - CURLOPT_POSTFIELDS => $body, - CURLOPT_URL => $url, - CURLOPT_NOBODY => FALSE, - CURLOPT_HTTPHEADER => $csrf_token !== FALSE ? array( - 'Content-Type: ' . $mime_type, - 'X-CSRF-Token: ' . ($csrf_token === NULL ? $requested_token : $csrf_token), - ) : array( - 'Content-Type: ' . $mime_type, - ), - ); + $options += [ + 'headers' => $csrf_token !== FALSE ? [ + 'Content-Type' => $mime_type, + 'X-CSRF-Token' => ($csrf_token === NULL ? $requested_token : $csrf_token), + ] : [ + 'Content-Type' => $mime_type, + ], + 'body' => $body, + ]; + $response = $client->patch($url, $options); break; case 'DELETE': - $curl_options = array( - CURLOPT_HTTPGET => FALSE, - CURLOPT_CUSTOMREQUEST => 'DELETE', - CURLOPT_URL => $url, - CURLOPT_NOBODY => FALSE, - CURLOPT_HTTPHEADER => $csrf_token !== FALSE ? array( - 'X-CSRF-Token: ' . ($csrf_token === NULL ? $requested_token : $csrf_token), - ) : array(), - ); + $options += [ + 'headers' => $csrf_token !== FALSE ? [ + 'Content-Type' => $mime_type, + 'X-CSRF-Token' => ($csrf_token === NULL ? $requested_token : $csrf_token), + ] : [], + ]; + $response = $client->delete($url, $options); break; } - if ($mime_type === 'none') { - unset($curl_options[CURLOPT_HTTPHEADER]['Content-Type']); - } - - $this->responseBody = $this->curlExec($curl_options); + $this->response = $response; + $this->responseBody = (string) $response->getBody(); + $this->setRawContent($this->responseBody); // Ensure that any changes to variables in the other thread are picked up. $this->refreshVariables(); - $headers = $this->drupalGetHeaders(); - $this->verbose($method . ' request to: ' . $url . - '
    Code: ' . curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE) . - (isset($curl_options[CURLOPT_HTTPHEADER]) ? '
    Request headers: ' . nl2br(print_r($curl_options[CURLOPT_HTTPHEADER], TRUE)) : '' ) . - (isset($curl_options[CURLOPT_POSTFIELDS]) ? '
    Request body: ' . nl2br(print_r($curl_options[CURLOPT_POSTFIELDS], TRUE)) : '' ) . - '
    Response headers: ' . nl2br(print_r($headers, TRUE)) . + '
    Code: ' . $this->response->getStatusCode() . + (isset($options['headers']) ? '
    Request headers: ' . nl2br(print_r($options['headers'], TRUE)) : '') . + (isset($options['body']) ? '
    Request body: ' . nl2br(print_r($options['body'], TRUE)) : '') . + '
    Response headers: ' . nl2br(print_r($response->getHeaders(), TRUE)) . '
    Response body: ' . $this->responseBody); return $this->responseBody; } + /** + * {@inheritdoc} + */ + protected function assertResponse($code, $message = '', $group = 'Browser') { + if (!isset($this->response)) { + return parent::assertResponse($code, $message, $group); + } + return $this->assertEqual($code, $this->response->getStatusCode(), $message ? $message : "HTTP response expected $code, actual {$this->response->getStatusCode()}", $group); + } + + /** + * {@inheritdoc} + */ + protected function drupalGetHeaders($all_requests = FALSE) { + if (!isset($this->response)) { + return parent::drupalGetHeaders($all_requests); + } + $lowercased_keys = array_map('strtolower', array_keys($this->response->getHeaders())); + return array_map(function (array $header) { + return implode(', ', $header); + }, array_combine($lowercased_keys, array_values($this->response->getHeaders()))); + } + + /** + * {@inheritdoc} + */ + protected function drupalGetHeader($name, $all_requests = FALSE) { + if (!isset($this->response)) { + return parent::drupalGetHeader($name, $all_requests); + } + if ($header = $this->response->getHeader($name)) { + return implode(', ', $header); + } + } + /** * Creates entity objects based on their types. * @@ -242,28 +303,30 @@ protected function entityCreate($entity_type) { protected function entityValues($entity_type_id) { switch ($entity_type_id) { case 'entity_test': - return array( + return [ 'name' => $this->randomMachineName(), 'user_id' => 1, - 'field_test_text' => array(0 => array( - 'value' => $this->randomString(), - 'format' => 'plain_text', - )), - ); + 'field_test_text' => [ + 0 => [ + 'value' => $this->randomString(), + 'format' => 'plain_text', + ], + ], + ]; case 'config_test': return [ 'id' => $this->randomMachineName(), 'label' => 'Test label', ]; case 'node': - return array('title' => $this->randomString(), 'type' => 'resttest'); + return ['title' => $this->randomString(), 'type' => 'resttest']; case 'node_type': - return array( + return [ 'type' => 'article', 'name' => $this->randomMachineName(), - ); + ]; case 'user': - return array('name' => $this->randomMachineName()); + return ['name' => $this->randomMachineName()]; case 'comment': return [ @@ -279,11 +342,20 @@ protected function entityValues($entity_type_id) { 'vid' => 'tags', 'name' => $this->randomMachineName(), ]; + case 'block': + // Block placements depend on themes, ensure Bartik is installed. + $this->container->get('theme_installer')->install(['bartik']); + return [ + 'id' => strtolower($this->randomMachineName(8)), + 'plugin' => 'system_powered_by_block', + 'theme' => 'bartik', + 'region' => 'header', + ]; default: if ($this->isConfigEntity($entity_type_id)) { return $this->configEntityValues($entity_type_id); } - return array(); + return []; } } @@ -350,8 +422,7 @@ protected function enableService($resource_type, $method = 'GET', $format = NULL * Rebuilds routing caches. */ protected function rebuildCache() { - // Rebuild routing cache, so that the REST API paths are available. - $this->container->get('router.builder')->rebuild(); + $this->container->get('router.builder')->rebuildIfNeeded(); } /** @@ -362,6 +433,8 @@ protected function rebuildCache() { * override it every time it is omitted. */ protected function curlExec($curl_options, $redirect = FALSE) { + unset($this->response); + if (!isset($curl_options[CURLOPT_CUSTOMREQUEST])) { if (!empty($curl_options[CURLOPT_HTTPGET])) { $curl_options[CURLOPT_CUSTOMREQUEST] = 'GET'; @@ -389,22 +462,22 @@ protected function entityPermissions($entity_type_id, $operation) { case 'entity_test': switch ($operation) { case 'view': - return array('view test entity'); + return ['view test entity']; case 'create': case 'update': case 'delete': - return array('administer entity_test content'); + return ['administer entity_test content']; } case 'node': switch ($operation) { case 'view': - return array('access content'); + return ['access content']; case 'create': - return array('create resttest content'); + return ['create resttest content']; case 'update': - return array('edit any resttest content'); + return ['edit any resttest content']; case 'delete': - return array('delete any resttest content'); + return ['delete any resttest content']; } case 'comment': @@ -502,7 +575,7 @@ protected function removeNodeFieldsForNonAdminUsers(NodeInterface $node) { * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertResponseBody($expected, $message = '', $group = 'REST Response') { - return $this->assertIdentical($expected, $this->responseBody, $message ? $message : strtr('Response body @expected (expected) is equal to @response (actual).', array('@expected' => var_export($expected, TRUE), '@response' => var_export($this->responseBody, TRUE))), $group); + return $this->assertIdentical($expected, $this->responseBody, $message ? $message : strtr('Response body @expected (expected) is equal to @response (actual).', ['@expected' => var_export($expected, TRUE), '@response' => var_export($this->responseBody, TRUE)]), $group); } /** diff --git a/core/modules/rest/src/Tests/ResourceTest.php b/core/modules/rest/src/Tests/ResourceTest.php deleted file mode 100644 index 72bed0f4..00000000 --- a/core/modules/rest/src/Tests/ResourceTest.php +++ /dev/null @@ -1,130 +0,0 @@ -entity = $this->entityCreate('entity_test'); - $this->entity->save(); - - Role::load(AccountInterface::ANONYMOUS_ROLE) - ->grantPermission('view test entity') - ->save(); - } - - /** - * Tests that a resource without formats cannot be enabled. - */ - public function testFormats() { - $this->resourceConfigStorage->create([ - 'id' => 'entity.entity_test', - 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY, - 'configuration' => [ - 'GET' => [ - 'supported_auth' => [ - 'basic_auth', - ], - ], - ], - ])->save(); - - // Verify that accessing the resource returns 406. - $response = $this->httpRequest($this->entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET'); - // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical, - // non-REST route a match, but a lower quality one: no format restrictions - // means there's always a match and hence when there is no matching REST - // route, the non-REST route is used, but can't render into - // application/hal+json, so it returns a 406. - $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.'); - $this->curlClose(); - } - - /** - * Tests that a resource without authentication cannot be enabled. - */ - public function testAuthentication() { - $this->resourceConfigStorage->create([ - 'id' => 'entity.entity_test', - 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY, - 'configuration' => [ - 'GET' => [ - 'supported_formats' => [ - 'hal_json', - ], - ], - ], - ])->save(); - - // Verify that accessing the resource returns 401. - $response = $this->httpRequest($this->entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET'); - // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical, - // non-REST route a match, but a lower quality one: no format restrictions - // means there's always a match and hence when there is no matching REST - // route, the non-REST route is used, but can't render into - // application/hal+json, so it returns a 406. - $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.'); - $this->curlClose(); - } - - /** - * Tests that serialization_class is optional. - */ - public function testSerializationClassIsOptional() { - $this->enableService('serialization_test', 'POST', 'json'); - - Role::load(RoleInterface::ANONYMOUS_ID) - ->grantPermission('restful post serialization_test') - ->save(); - - $serialized = $this->container->get('serializer')->serialize(['foo', 'bar'], 'json'); - $this->httpRequest('serialization_test', 'POST', $serialized, 'application/json'); - $this->assertResponse(200); - $this->assertResponseBody('["foo","bar"]'); - } - - /** - * Tests that resource URI paths are formatted properly. - */ - public function testUriPaths() { - $this->enableService('entity:entity_test'); - /** @var \Drupal\rest\Plugin\Type\ResourcePluginManager $manager */ - $manager = \Drupal::service('plugin.manager.rest'); - - foreach ($manager->getDefinitions() as $resource => $definition) { - foreach ($definition['uri_paths'] as $key => $uri_path) { - $this->assertFalse(strpos($uri_path, '//'), 'The resource URI path does not have duplicate slashes.'); - } - } - } - -} diff --git a/core/modules/rest/src/Tests/Update/RestExportAuthCorrectionUpdateTest.php b/core/modules/rest/src/Tests/Update/RestExportAuthCorrectionUpdateTest.php new file mode 100644 index 00000000..aeca71f6 --- /dev/null +++ b/core/modules/rest/src/Tests/Update/RestExportAuthCorrectionUpdateTest.php @@ -0,0 +1,36 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../tests/fixtures/update/rest-export-with-authentication-correction.php', + ]; + } + + /** + * Ensures that update hook is run for "rest" module. + */ + public function testUpdate() { + $this->runUpdates(); + + // Get particular view. + $view = \Drupal::entityTypeManager()->getStorage('view')->load('rest_export_with_authorization_correction'); + $displays = $view->get('display'); + $this->assertIdentical($displays['rest_export_1']['display_options']['auth'], ['cookie'], 'Cookie is used for authentication'); + } + +} diff --git a/core/modules/rest/src/Tests/Update/RestExportAuthUpdateTest.php b/core/modules/rest/src/Tests/Update/RestExportAuthUpdateTest.php deleted file mode 100644 index 92cc917f..00000000 --- a/core/modules/rest/src/Tests/Update/RestExportAuthUpdateTest.php +++ /dev/null @@ -1,36 +0,0 @@ -databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/rest-export-with-authentication.php', - ]; - } - - /** - * Ensures that update hook is run for rest module. - */ - public function testUpdate() { - $this->runUpdates(); - - // Get particular view. - $view = \Drupal::entityTypeManager()->getStorage('view')->load('rest_export_with_authorization'); - $displays = $view->get('display'); - $this->assertIdentical($displays['rest_export_1']['display_options']['auth']['basic_auth'], 'basic_auth', 'Basic authentication is set as authentication method.'); - } - -} diff --git a/core/modules/rest/tests/fixtures/update/rest-export-with-authentication-correction.php b/core/modules/rest/tests/fixtures/update/rest-export-with-authentication-correction.php new file mode 100644 index 00000000..6cbd04e8 --- /dev/null +++ b/core/modules/rest/tests/fixtures/update/rest-export-with-authentication-correction.php @@ -0,0 +1,63 @@ +insert('key_value') + ->fields([ + 'collection' => 'system.schema', + 'name' => 'rest', + 'value' => 'i:8000;', + ]) + ->execute(); + +// Update core.extension. +$extensions = $connection->select('config') + ->fields('config', ['data']) + ->condition('collection', '') + ->condition('name', 'core.extension') + ->execute() + ->fetchField(); +$extensions = unserialize($extensions); +$extensions['module']['rest'] = 0; +$extensions['module']['serialization'] = 0; +$extensions['module']['basic_auth'] = 0; +$connection->update('config') + ->fields([ + 'data' => serialize($extensions), + ]) + ->condition('collection', '') + ->condition('name', 'core.extension') + ->execute(); + +$connection->insert('config') + ->fields([ + 'name' => 'rest.settings', + 'data' => serialize([ + 'link_domain' => '~', + ]), + 'collection' => '', + ]) + ->execute(); + +$connection->insert('config') + ->fields([ + 'name' => 'views.view.rest_export_with_authorization_correction', + ]) + ->execute(); + +$connection->merge('config') + ->condition('name', 'views.view.rest_export_with_authorization_correction') + ->condition('collection', '') + ->fields([ + 'data' => serialize(Yaml::decode(file_get_contents('core/modules/views/tests/modules/views_test_config/test_views/views.view.rest_export_with_authorization_correction.yml'))), + ]) + ->execute(); diff --git a/core/modules/rest/tests/modules/config_test_rest/config_test_rest.info.yml b/core/modules/rest/tests/modules/config_test_rest/config_test_rest.info.yml index 47853ec2..0bcf9882 100644 --- a/core/modules/rest/tests/modules/config_test_rest/config_test_rest.info.yml +++ b/core/modules/rest/tests/modules/config_test_rest/config_test_rest.info.yml @@ -6,8 +6,8 @@ package: Testing dependencies: - config_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rest/tests/modules/rest_test/rest_test.info.yml b/core/modules/rest/tests/modules/rest_test/rest_test.info.yml index 59b49b09..1ba7d084 100644 --- a/core/modules/rest/tests/modules/rest_test/rest_test.info.yml +++ b/core/modules/rest/tests/modules/rest_test/rest_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - rest -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rest/tests/modules/rest_test/rest_test.module b/core/modules/rest/tests/modules/rest_test/rest_test.module index 01511ea1..7df28637 100644 --- a/core/modules/rest/tests/modules/rest_test/rest_test.module +++ b/core/modules/rest/tests/modules/rest_test/rest_test.module @@ -10,24 +10,6 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Access\AccessResult; -/** - * Implements hook_rest_type_uri_alter(). - */ -function rest_test_rest_type_uri_alter(&$uri, $context = array()) { - if (!empty($context['rest_test'])) { - $uri = 'rest_test_type'; - } -} - -/** - * Implements hook_rest_relation_uri_alter(). - */ -function rest_test_rest_relation_uri_alter(&$uri, $context = array()) { - if (!empty($context['rest_test'])) { - $uri = 'rest_test_relation'; - } -} - /** * Implements hook_entity_field_access(). * diff --git a/core/modules/rest/tests/modules/rest_test/rest_test.services.yml b/core/modules/rest/tests/modules/rest_test/rest_test.services.yml new file mode 100644 index 00000000..ccdbeae7 --- /dev/null +++ b/core/modules/rest/tests/modules/rest_test/rest_test.services.yml @@ -0,0 +1,9 @@ +services: + rest_test.authentication.test_auth: + class: Drupal\rest_test\Authentication\Provider\TestAuth + tags: + - { name: authentication_provider, provider_id: 'rest_test_auth' } + rest_test.authentication.test_auth_global: + class: Drupal\rest_test\Authentication\Provider\TestAuthGlobal + tags: + - { name: authentication_provider, provider_id: 'rest_test_auth_global', global: TRUE } diff --git a/core/modules/rest/tests/modules/rest_test/src/Authentication/Provider/TestAuth.php b/core/modules/rest/tests/modules/rest_test/src/Authentication/Provider/TestAuth.php new file mode 100644 index 00000000..36302acb --- /dev/null +++ b/core/modules/rest/tests/modules/rest_test/src/Authentication/Provider/TestAuth.php @@ -0,0 +1,27 @@ +headers->has('REST-test-auth'); + } + + /** + * {@inheritdoc} + */ + public function authenticate(Request $request) { + return NULL; + } + +} diff --git a/core/modules/rest/tests/modules/rest_test/src/Authentication/Provider/TestAuthGlobal.php b/core/modules/rest/tests/modules/rest_test/src/Authentication/Provider/TestAuthGlobal.php new file mode 100644 index 00000000..8ca91741 --- /dev/null +++ b/core/modules/rest/tests/modules/rest_test/src/Authentication/Provider/TestAuthGlobal.php @@ -0,0 +1,27 @@ +headers->has('REST-test-auth-global'); + } + + /** + * {@inheritdoc} + */ + public function authenticate(Request $request) { + return NULL; + } + +} diff --git a/core/modules/rest/tests/modules/rest_test_views/rest_test_views.info.yml b/core/modules/rest/tests/modules/rest_test_views/rest_test_views.info.yml index d2e23d11..29c58c0c 100644 --- a/core/modules/rest/tests/modules/rest_test_views/rest_test_views.info.yml +++ b/core/modules/rest/tests/modules/rest_test_views/rest_test_views.info.yml @@ -8,8 +8,8 @@ dependencies: - rest - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/rest/tests/src/Functional/BcTimestampNormalizerUnixTestTrait.php b/core/modules/rest/tests/src/Functional/BcTimestampNormalizerUnixTestTrait.php new file mode 100644 index 00000000..a275f646 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/BcTimestampNormalizerUnixTestTrait.php @@ -0,0 +1,43 @@ +config('serialization.settings')->get('bc_timestamp_normalizer_unix')) { + return ['value' => $timestamp]; + } + + // Otherwise, format the date string to the same that + // \Drupal\serialization\Normalizer\TimestampItemNormalizer will produce. + $date = new \DateTime(); + $date->setTimestamp($timestamp); + $date->setTimezone(new \DateTimeZone('UTC')); + + // Format is also added to the expected return values. + return [ + 'value' => $date->format(\DateTime::RFC3339), + 'format' => \DateTime::RFC3339, + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php b/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php index 18dc296b..3b7c3b48 100644 --- a/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php +++ b/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php @@ -53,10 +53,8 @@ trait CookieResourceTestTrait { * {@inheritdoc} */ protected function initAuthentication() { - // @todo Remove hardcoded use of the 'json' format, and use static::$format - // + static::$mimeType instead in https://www.drupal.org/node/2820888. $user_login_url = Url::fromRoute('user.login.http') - ->setRouteParameter('_format', 'json'); + ->setRouteParameter('_format', static::$format); $request_body = [ 'name' => $this->account->name->value, @@ -64,14 +62,16 @@ protected function initAuthentication() { ]; $request_options[RequestOptions::BODY] = $this->serializer->encode($request_body, 'json'); - $request_options[RequestOptions::HEADERS]['Accept'] = 'application/json'; + $request_options[RequestOptions::HEADERS] = [ + 'Content-Type' => static::$mimeType, + ]; $response = $this->request('POST', $user_login_url, $request_options); // Parse and store the session cookie. $this->sessionCookie = explode(';', $response->getHeader('Set-Cookie')[0], 2)[0]; // Parse and store the CSRF token and logout token. - $data = $this->serializer->decode((string)$response->getBody(), static::$format); + $data = $this->serializer->decode((string) $response->getBody(), static::$format); $this->csrfToken = $data['csrf_token']; $this->logoutToken = $data['logout_token']; } @@ -92,7 +92,10 @@ protected function getAuthenticationRequestOptions($method) { * {@inheritdoc} */ protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) { - $this->assertResourceErrorResponse(403, '', $response); + // Requests needing cookie authentication but missing it results in a 403 + // response. The cookie authentication mechanism sets no response message. + // @todo https://www.drupal.org/node/2847623 + $this->assertResourceErrorResponse(403, FALSE, $response); } /** diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Action/ActionJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Action/ActionJsonAnonTest.php new file mode 100644 index 00000000..4d55c25b --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Action/ActionJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer actions']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $action = Action::create([ + 'id' => 'user_add_role_action.' . RoleInterface::ANONYMOUS_ID, + 'type' => 'user', + 'label' => t('Add the anonymous role to the selected users'), + 'configuration' => [ + 'rid' => RoleInterface::ANONYMOUS_ID, + ], + 'plugin' => 'user_add_role_action', + ]); + $action->save(); + + return $action; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'configuration' => [ + 'rid' => 'anonymous', + ], + 'dependencies' => [ + 'config' => ['user.role.anonymous'], + 'module' => ['user'], + ], + 'id' => 'user_add_role_action.anonymous', + 'label' => 'Add the anonymous role to the selected users', + 'langcode' => 'en', + 'plugin' => 'user_add_role_action', + 'status' => TRUE, + 'type' => 'user', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/BaseFieldOverride/BaseFieldOverrideJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/BaseFieldOverride/BaseFieldOverrideJsonAnonTest.php new file mode 100644 index 00000000..e16284d0 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/BaseFieldOverride/BaseFieldOverrideJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer node fields']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $camelids = NodeType::create([ + 'name' => 'Camelids', + 'type' => 'camelids', + ]); + $camelids->save(); + + $entity = BaseFieldOverride::create([ + 'field_name' => 'promote', + 'entity_type' => 'node', + 'bundle' => 'camelids', + ]); + $entity->save(); + + return $entity; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'bundle' => 'camelids', + 'default_value' => [], + 'default_value_callback' => '', + 'dependencies' => [ + 'config' => [ + 'node.type.camelids', + ], + ], + 'description' => '', + 'entity_type' => 'node', + 'field_name' => 'promote', + 'field_type' => 'boolean', + 'id' => 'node.camelids.promote', + 'label' => NULL, + 'langcode' => 'en', + 'required' => FALSE, + 'settings' => [ + 'on_label' => 'On', + 'off_label' => 'Off', + ], + 'status' => TRUE, + 'translatable' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'administer node fields' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonAnonTest.php index 9c764bda..2312de02 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonAnonTest.php @@ -21,9 +21,4 @@ class BlockJsonAnonTest extends BlockResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonBasicAuthTest.php index f191e124..ea690b49 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Block; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class BlockJsonBasicAuthTest extends BlockResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonCookieTest.php index f609448f..c15ff8f2 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockJsonCookieTest.php @@ -21,11 +21,6 @@ class BlockJsonCookieTest extends BlockResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php index 94c0b047..d86f9b1c 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php @@ -113,7 +113,7 @@ protected function getNormalizedPostEntity() { */ protected function getExpectedCacheContexts() { // @see ::createEntity() - return []; + return ['url.site']; } /** @@ -122,9 +122,23 @@ protected function getExpectedCacheContexts() { protected function getExpectedCacheTags() { // Because the 'user.permissions' cache context is missing, the cache tag // for the anonymous user role is never added automatically. - return array_filter(parent::getExpectedCacheTags(), function ($tag) { - return $tag !== 'config:user.role.anonymous'; - }); + return array_values(array_diff(parent::getExpectedCacheTags(), ['config:user.role.anonymous'])); + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "You are not authorized to view this block entity."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } } } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/BlockContentType/BlockContentTypeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/BlockContentType/BlockContentTypeJsonAnonTest.php new file mode 100644 index 00000000..9671708a --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/BlockContentType/BlockContentTypeJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer blocks']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $block_content_type = BlockContentType::create([ + 'id' => 'pascal', + 'label' => 'Pascal', + 'revision' => FALSE, + 'description' => 'Provides a competitive alternative to the "basic" type', + ]); + + $block_content_type->save(); + + return $block_content_type; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'description' => 'Provides a competitive alternative to the "basic" type', + 'id' => 'pascal', + 'label' => 'Pascal', + 'langcode' => 'en', + 'revision' => 0, + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonAnonTest.php index 6ce580d0..5aef7cf2 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonAnonTest.php @@ -21,11 +21,6 @@ class CommentJsonAnonTest extends CommentResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} * diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonBasicAuthTest.php index 0ab51384..e05d733f 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Comment; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class CommentJsonBasicAuthTest extends CommentResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonCookieTest.php index 967baa5d..945b34a0 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentJsonCookieTest.php @@ -21,11 +21,6 @@ class CommentJsonCookieTest extends CommentResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php index 5529fb24..bade2a76 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php @@ -6,13 +6,14 @@ use Drupal\comment\Entity\CommentType; use Drupal\comment\Tests\CommentTestTrait; use Drupal\entity_test\Entity\EntityTest; +use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait; use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; use Drupal\user\Entity\User; use GuzzleHttp\RequestOptions; abstract class CommentResourceTestBase extends EntityResourceTestBase { - use CommentTestTrait; + use CommentTestTrait, BcTimestampNormalizerUnixTestTrait; /** * {@inheritdoc} @@ -28,6 +29,7 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase { * {@inheritdoc} */ protected static $patchProtectedFieldNames = [ + 'status', 'pid', 'entity_id', 'uid', @@ -35,7 +37,6 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase { 'homepage', 'created', 'changed', - 'status', 'thread', 'entity_type', 'field_name', @@ -87,10 +88,10 @@ protected function createEntity() { $this->addDefaultCommentField('entity_test', 'bar', 'comment'); // Create a "Camelids" test entity that the comment will be assigned to. - $commented_entity = EntityTest::create(array( + $commented_entity = EntityTest::create([ 'name' => 'Camelids', 'type' => 'bar', - )); + ]); $commented_entity->save(); // Create a "Llama" comment. @@ -144,18 +145,14 @@ protected function getExpectedNormalizedEntity() { ], 'status' => [ [ - 'value' => 1, + 'value' => TRUE, ], ], 'created' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues(123456789), ], 'changed' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()), ], 'default_langcode' => [ [ @@ -164,7 +161,7 @@ protected function getExpectedNormalizedEntity() { ], 'uid' => [ [ - 'target_id' => $author->id(), + 'target_id' => (int) $author->id(), 'target_type' => 'user', 'target_uuid' => $author->uuid(), 'url' => base_path() . 'user/' . $author->id(), @@ -178,7 +175,7 @@ protected function getExpectedNormalizedEntity() { ], 'entity_id' => [ [ - 'target_id' => '1', + 'target_id' => 1, 'target_type' => 'entity_test', 'target_uuid' => EntityTest::load(1)->uuid(), 'url' => base_path() . 'entity_test/1', @@ -222,7 +219,7 @@ protected function getNormalizedPostEntity() { ], 'entity_id' => [ [ - 'target_id' => EntityTest::load(1)->id(), + 'target_id' => (int) EntityTest::load(1)->id(), ], ], 'field_name' => [ @@ -269,7 +266,7 @@ public function testPostDxWithoutCriticalBaseFields() { $this->provisionEntityResource(); $this->setUpAuthorization('POST'); - $url = $this->getPostUrl()->setOption('query', ['_format' => static::$format]); + $url = $this->getEntityResourcePostUrl()->setOption('query', ['_format' => static::$format]); $request_options = []; $request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType; $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType; @@ -278,9 +275,11 @@ public function testPostDxWithoutCriticalBaseFields() { // DX: 422 when missing 'entity_type' field. $request_options[RequestOptions::BODY] = $this->serializer->encode(array_diff_key($this->getNormalizedPostEntity(), ['entity_type' => TRUE]), static::$format); $response = $this->request('POST', $url, $request_options); - // @todo Uncomment, remove next line in https://www.drupal.org/node/2820364. - $this->assertResourceErrorResponse(500, 'A fatal error occurred: Internal Server Error', $response); - //$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nentity_type: This value should not be null.\n", $response); + // @todo Uncomment, remove next 3 lines in https://www.drupal.org/node/2820364. + $this->assertSame(500, $response->getStatusCode()); + $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type')); + $this->assertStringStartsWith('The website encountered an unexpected error. Please try again later.

    Symfony\Component\HttpKernel\Exception\HttpException: Internal Server Error in Drupal\rest\Plugin\rest\resource\EntityResource->post()', (string) $response->getBody()); + // $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nentity_type: This value should not be null.\n", $response); // DX: 422 when missing 'entity_id' field. $request_options[RequestOptions::BODY] = $this->serializer->encode(array_diff_key($this->getNormalizedPostEntity(), ['entity_id' => TRUE]), static::$format); @@ -289,21 +288,73 @@ public function testPostDxWithoutCriticalBaseFields() { try { $response = $this->request('POST', $url, $request_options); // This happens on DrupalCI. - //$this->assertSame(500, $response->getStatusCode()); + // $this->assertSame(500, $response->getStatusCode()); } catch (\Exception $e) { // This happens on Wim's local machine. - //$this->assertSame("Error: Call to a member function get() on null\nDrupal\\comment\\Plugin\\Validation\\Constraint\\CommentNameConstraintValidator->getAnonymousContactDetailsSetting()() (Line: 96)\n", $e->getMessage()); + // $this->assertSame("Error: Call to a member function get() on null\nDrupal\\comment\\Plugin\\Validation\\Constraint\\CommentNameConstraintValidator->getAnonymousContactDetailsSetting()() (Line: 96)\n", $e->getMessage()); } - //$response = $this->request('POST', $url, $request_options); - //$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nentity_type: This value should not be null.\n", $response); + // $response = $this->request('POST', $url, $request_options); + // $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nentity_type: This value should not be null.\n", $response); // DX: 422 when missing 'entity_type' field. $request_options[RequestOptions::BODY] = $this->serializer->encode(array_diff_key($this->getNormalizedPostEntity(), ['field_name' => TRUE]), static::$format); $response = $this->request('POST', $url, $request_options); - // @todo Uncomment, remove next line in https://www.drupal.org/node/2820364. - $this->assertResourceErrorResponse(500, 'A fatal error occurred: Field is unknown.', $response); - //$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nfield_name: This value should not be null.\n", $response); + // @todo Uncomment, remove next 2 lines in https://www.drupal.org/node/2820364. + $this->assertSame(500, $response->getStatusCode()); + $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type')); + // $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nfield_name: This value should not be null.\n", $response); + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET'; + return "The 'access comments' permission is required and the comment must be published."; + case 'POST'; + return "The 'post comments' permission is required."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + + /** + * Tests POSTing a comment with and without 'skip comment approval' + */ + public function testPostSkipCommentApproval() { + $this->initAuthentication(); + $this->provisionEntityResource(); + $this->setUpAuthorization('POST'); + + // Create request. + $request_options = []; + $request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType; + $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType; + $request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('POST')); + $request_options[RequestOptions::BODY] = $this->serializer->encode($this->getNormalizedPostEntity(), static::$format); + + $url = $this->getEntityResourcePostUrl()->setOption('query', ['_format' => static::$format]); + + // Status should be FALSE when posting as anonymous. + $response = $this->request('POST', $url, $request_options); + $unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format); + $this->assertResourceResponse(201, FALSE, $response); + $this->assertFalse($unserialized->getStatus()); + + // Grant anonymous permission to skip comment approval. + $this->grantPermissionsToTestedRole(['skip comment approval']); + + // Status should be TRUE when posting as anonymous and skip comment approval. + $response = $this->request('POST', $url, $request_options); + $unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format); + $this->assertResourceResponse(201, FALSE, $response); + $this->assertTrue($unserialized->getStatus()); } } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/CommentType/CommentTypeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/CommentType/CommentTypeJsonAnonTest.php new file mode 100644 index 00000000..ac27de00 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/CommentType/CommentTypeJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer comment types']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" comment type. + $camelids = CommentType::create([ + 'id' => 'camelids', + 'label' => 'Camelids', + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'target_entity_type_id' => 'node', + ]); + + $camelids->save(); + + return $camelids; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'id' => 'camelids', + 'label' => 'Camelids', + 'langcode' => 'en', + 'status' => TRUE, + 'target_entity_type_id' => 'node', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonAnonTest.php index db79e6c0..32997dc1 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonAnonTest.php @@ -21,9 +21,4 @@ class ConfigTestJsonAnonTest extends ConfigTestResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonBasicAuthTest.php index 309a8f12..1144e76a 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\ConfigTest; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class ConfigTestJsonBasicAuthTest extends ConfigTestResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonCookieTest.php index c243bde9..fe257863 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/ConfigTest/ConfigTestJsonCookieTest.php @@ -21,11 +21,6 @@ class ConfigTestJsonCookieTest extends ConfigTestResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ConfigurableLanguage/ConfigurableLanguageJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ConfigurableLanguage/ConfigurableLanguageJsonAnonTest.php new file mode 100644 index 00000000..debfa4cd --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/ConfigurableLanguage/ConfigurableLanguageJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer languages']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $configurable_language = ConfigurableLanguage::create([ + 'id' => 'll', + 'label' => 'Llama Language', + ]); + $configurable_language->save(); + + return $configurable_language; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'direction' => 'ltr', + 'id' => 'll', + 'label' => 'Llama Language', + 'langcode' => 'en', + 'locked' => FALSE, + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + 'weight' => 0, + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['languages:language_interface']); + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ContactForm/ContactFormJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ContactForm/ContactFormJsonAnonTest.php new file mode 100644 index 00000000..a5f36021 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/ContactForm/ContactFormJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access site-wide contact form']); + default: + $this->grantPermissionsToTestedRole(['administer contact forms']); + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $contact_form = ContactForm::create([ + 'id' => 'llama', + 'label' => 'Llama', + 'message' => 'Let us know what you think about llamas', + 'reply' => 'Llamas are indeed awesome!', + 'recipients' => [ + 'llama@example.com', + 'contact@example.com', + ], + ]); + $contact_form->save(); + + return $contact_form; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'id' => 'llama', + 'label' => 'Llama', + 'langcode' => 'en', + 'message' => 'Let us know what you think about llamas', + 'recipients' => [ + 'llama@example.com', + 'contact@example.com', + ], + 'redirect' => NULL, + 'reply' => 'Llamas are indeed awesome!', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + 'weight' => 0, + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'access site-wide contact form' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ContentLanguageSettings/ContentLanguageSettingsJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ContentLanguageSettings/ContentLanguageSettingsJsonAnonTest.php new file mode 100644 index 00000000..344c7335 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/ContentLanguageSettings/ContentLanguageSettingsJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer languages']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" node type. + $camelids = NodeType::create([ + 'name' => 'Camelids', + 'type' => 'camelids', + ]); + $camelids->save(); + + $entity = ContentLanguageSettings::create([ + 'target_entity_type_id' => 'node', + 'target_bundle' => 'camelids', + ]); + $entity->setDefaultLangcode('site_default') + ->save(); + + return $entity; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'default_langcode' => 'site_default', + 'dependencies' => [ + 'config' => [ + 'node.type.camelids', + ], + ], + 'id' => 'node.camelids', + 'langcode' => 'en', + 'language_alterable' => FALSE, + 'status' => TRUE, + 'target_bundle' => 'camelids', + 'target_entity_type_id' => 'node', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'languages:language_interface', + 'user.permissions', + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php new file mode 100644 index 00000000..9fe8ea22 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer site configuration']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a date format. + $date_format = DateFormat::create([ + 'id' => 'llama', + 'label' => 'Llama', + 'pattern' => 'F d, Y', + ]); + + $date_format->save(); + + return $date_format; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'id' => 'llama', + 'label' => 'Llama', + 'langcode' => 'en', + 'locked' => FALSE, + 'pattern' => 'F d, Y', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Editor/EditorJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Editor/EditorJsonAnonTest.php new file mode 100644 index 00000000..b01ac2ac --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Editor/EditorJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer filters']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Llama" filter format. + $llama_format = FilterFormat::create([ + 'name' => 'Llama', + 'format' => 'llama', + 'langcode' => 'es', + 'filters' => [ + 'filter_html' => [ + 'status' => TRUE, + 'settings' => [ + 'allowed_html' => '

    ', + ], + ], + ], + ]); + + $llama_format->save(); + + // Create a "Camelids" editor. + $camelids = Editor::create([ + 'format' => 'llama', + 'editor' => 'ckeditor', + ]); + $camelids + ->setImageUploadSettings([ + 'status' => FALSE, + 'scheme' => file_default_scheme(), + 'directory' => 'inline-images', + 'max_size' => '', + 'max_dimensions' => [ + 'width' => '', + 'height' => '', + ], + ]) + ->save(); + + return $camelids; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [ + 'config' => [ + 'filter.format.llama', + ], + 'module' => [ + 'ckeditor', + ], + ], + 'editor' => 'ckeditor', + 'format' => 'llama', + 'image_upload' => [ + 'status' => FALSE, + 'scheme' => 'public', + 'directory' => 'inline-images', + 'max_size' => '', + 'max_dimensions' => [ + 'width' => NULL, + 'height' => NULL, + ], + ], + 'langcode' => 'en', + 'settings' => [ + 'toolbar' => [ + 'rows' => [ + [ + [ + 'name' => 'Formatting', + 'items' => [ + 'Bold', + 'Italic', + ], + ], + [ + 'name' => 'Links', + 'items' => [ + 'DrupalLink', + 'DrupalUnlink', + ], + ], + [ + 'name' => 'Lists', + 'items' => [ + 'BulletedList', + 'NumberedList', + ], + ], + [ + 'name' => 'Media', + 'items' => [ + 'Blockquote', + 'DrupalImage', + ], + ], + [ + 'name' => 'Tools', + 'items' => [ + 'Source', + ], + ], + ], + ], + ], + 'plugins' => [ + 'language' => [ + 'language_list' => 'un', + ], + ], + ], + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + // @see ::createEntity() + return ['user.permissions']; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'administer filters' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityFormMode/EntityFormModeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityFormMode/EntityFormModeJsonAnonTest.php new file mode 100644 index 00000000..bdb4dfac --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityFormMode/EntityFormModeJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer display modes']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $entity_form_mode = EntityFormMode::create([ + 'id' => 'user.test', + 'label' => 'Test', + 'targetEntityType' => 'user', + ]); + $entity_form_mode->save(); + return $entity_form_mode; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'cache' => TRUE, + 'dependencies' => [ + 'module' => [ + 'user', + ], + ], + 'id' => 'user.test', + 'label' => 'Test', + 'langcode' => 'en', + 'status' => TRUE, + 'targetEntityType' => 'user', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php index 6dd0bb0c..fe4ebb83 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php @@ -4,12 +4,13 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\Cache; +use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\Config\Entity\ConfigEntityInterface; -use Drupal\Core\Entity\EntityChangedInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Url; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; +use Drupal\rest\ResourceResponseInterface; use Drupal\Tests\rest\Functional\ResourceTestBase; use GuzzleHttp\RequestOptions; use Psr\Http\Message\ResponseInterface; @@ -43,10 +44,9 @@ * (permissions or perhaps custom access control handling, such as node * grants), plus * 2. a concrete subclass extending the abstract entity type-specific subclass - * that specifies the exact @code $format @endcode, @code $mimeType @endcode, - * @code $expectedErrorMimeType @endcode and @code $auth @endcode for this - * concrete test. Usually that's all that's necessary: most concrete - * subclasses will be very thin. + * that specifies the exact @code $format @endcode, @code $mimeType @endcode + * and @code $auth @endcode for this concrete test. Usually that's all that's + * necessary: most concrete subclasses will be very thin. * * For every of these concrete subclasses, a comprehensive test scenario will * run per HTTP method: @@ -111,11 +111,6 @@ abstract class EntityResourceTestBase extends ResourceTestBase { */ protected static $secondCreatedEntityId = 3; - /** - * @var \GuzzleHttp\ClientInterface - */ - protected $httpClient; - /** * The main entity used for testing. * @@ -138,13 +133,13 @@ abstract class EntityResourceTestBase extends ResourceTestBase { public static $modules = ['rest_test', 'text']; /** - * {@inheritdoc} + * Provides an entity resource. */ protected function provisionEntityResource() { // It's possible to not have any authentication providers enabled, when // testing public (anonymous) usage of a REST resource. $auth = isset(static::$auth) ? [static::$auth] : []; - $this->provisionResource('entity.' . static::$entityTypeId, [static::$format], $auth); + $this->provisionResource([static::$format], $auth); } /** @@ -153,14 +148,12 @@ protected function provisionEntityResource() { public function setUp() { parent::setUp(); - $this->serializer = $this->container->get('serializer'); + // Calculate REST Resource config entity ID. + static::$resourceConfigId = 'entity.' . static::$entityTypeId; + $this->entityStorage = $this->container->get('entity_type.manager') ->getStorage(static::$entityTypeId); - // Set up a HTTP client that accepts relative URLs. - $this->httpClient = $this->container->get('http_client_factory') - ->fromOptions(['base_uri' => $this->baseUrl]); - // Create an entity. $this->entity = $this->createEntity(); @@ -187,18 +180,8 @@ public function setUp() { // Set a default value on the field. $this->entity->set('field_rest_test', ['value' => 'All the faith he had had had had no effect on the outcome of his life.']); - // @todo Remove in this if-test in https://www.drupal.org/node/2808335. - if ($this->entity instanceof EntityChangedInterface) { - $changed = $this->entity->getChangedTime(); - $this->entity->setChangedTime(42); - $this->entity->save(); - $this->entity->setChangedTime($changed); - } $this->entity->save(); } - - // @todo Remove this in https://www.drupal.org/node/2815845. - drupal_flush_all_caches(); } /** @@ -241,6 +224,36 @@ protected function getNormalizedPatchEntity() { return $this->getNormalizedPostEntity(); } + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + $permission = $this->entity->getEntityType()->getAdminPermission(); + if ($permission !== FALSE) { + return "The '{$permission}' permission is required."; + } + + $http_method_to_entity_operation = [ + 'GET' => 'view', + 'POST' => 'create', + 'PATCH' => 'update', + 'DELETE' => 'delete', + ]; + $operation = $http_method_to_entity_operation[$method]; + $message = sprintf('You are not authorized to %s this %s entity', $operation, $this->entity->getEntityTypeId()); + + if ($this->entity->bundle() !== $this->entity->getEntityTypeId()) { + $message .= ' of bundle ' . $this->entity->bundle(); + } + + return "$message."; + } + /** * The expected cache tags for the GET/HEAD response of the test entity. * @@ -255,6 +268,7 @@ protected function getExpectedCacheTags() { if (!static::$auth) { $expected_cache_tags[] = 'config:user.role.anonymous'; } + $expected_cache_tags[] = 'http_response'; return Cache::mergeTags($expected_cache_tags, $this->entity->getCacheTags()); } @@ -267,6 +281,7 @@ protected function getExpectedCacheTags() { */ protected function getExpectedCacheContexts() { return [ + 'url.site', 'user.permissions', ]; } @@ -283,7 +298,7 @@ public function testGet() { // - to first test all mistakes a developer might make, and assert that the // error responses provide a good DX // - to eventually result in a well-formed request that succeeds. - $url = $this->getUrl(); + $url = $this->getEntityResourceUrl(); $request_options = []; @@ -301,10 +316,10 @@ public function testGet() { // response because ?_format query string is present. $response = $this->request('GET', $url, $request_options); if ($has_canonical_url) { - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response); } else { - $this->assertResourceErrorResponse(404, 'No route found for "GET ' . str_replace($this->baseUrl, '', $this->getUrl()->setAbsolute()->toString()) . '"', $response); + $this->assertResourceErrorResponse(404, 'No route found for "GET ' . str_replace($this->baseUrl, '', $this->getEntityResourceUrl()->setAbsolute()->toString()) . '"', $response); } @@ -313,7 +328,6 @@ public function testGet() { $url->setOption('query', []); - // DX: 406 when ?_format is missing, except when requesting a canonical HTML // route. $response = $this->request('GET', $url, $request_options); @@ -335,13 +349,27 @@ public function testGet() { $this->assertResponseWhenMissingAuthentication($response); } + $request_options[RequestOptions::HEADERS]['REST-test-auth'] = '1'; + + // DX: 403 when attempting to use unallowed authentication provider. + $response = $this->request('GET', $url, $request_options); + $this->assertResourceErrorResponse(403, 'The used authentication method is not allowed on this route.', $response); + + unset($request_options[RequestOptions::HEADERS]['REST-test-auth']); + $request_options[RequestOptions::HEADERS]['REST-test-auth-global'] = '1'; + + // DX: 403 when attempting to use unallowed global authentication provider. + $response = $this->request('GET', $url, $request_options); + $this->assertResourceErrorResponse(403, 'The used authentication method is not allowed on this route.', $response); + + unset($request_options[RequestOptions::HEADERS]['REST-test-auth-global']); $request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions('GET')); // DX: 403 when unauthorized. $response = $this->request('GET', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response); + $this->assertArrayNotHasKey('Link', $response->getHeaders()); $this->setUpAuthorization('GET'); @@ -350,6 +378,18 @@ public function testGet() { // 200 for well-formed HEAD request. $response = $this->request('HEAD', $url, $request_options); $this->assertResourceResponse(200, '', $response); + // @todo Entity resources with URLs that begin with '/admin/' are marked as + // administrative (see https://www.drupal.org/node/2874938), which + // excludes them from Dynamic Page Cache (see + // https://www.drupal.org/node/2877528). When either of those issues is + // fixed, remove the if-test and the 'else' block. + if (strpos($this->entity->getEntityType()->getLinkTemplate('canonical'), '/admin/') !== 0) { + $this->assertTrue($response->hasHeader('X-Drupal-Dynamic-Cache')); + $this->assertSame(['MISS'], $response->getHeader('X-Drupal-Dynamic-Cache')); + } + else { + $this->assertFalse($response->hasHeader('X-Drupal-Dynamic-Cache')); + } if (!$this->account) { $this->assertSame(['MISS'], $response->getHeader('X-Drupal-Cache')); } @@ -359,27 +399,90 @@ public function testGet() { $head_headers = $response->getHeaders(); // 200 for well-formed GET request. Page Cache hit because of HEAD request. + // Same for Dynamic Page Cache hit. $response = $this->request('GET', $url, $request_options); $this->assertResourceResponse(200, FALSE, $response); - if (!static::$auth) { - $this->assertSame(['HIT'], $response->getHeader('X-Drupal-Cache')); + // @todo Entity resources with URLs that begin with '/admin/' are marked as + // administrative (see https://www.drupal.org/node/2874938), which + // excludes them from Dynamic Page Cache (see + // https://www.drupal.org/node/2877528). When either of those issues is + // fixed, remove the if-test and the 'else' block. + if (strpos($this->entity->getEntityType()->getLinkTemplate('canonical'), '/admin/') !== 0) { + $this->assertTrue($response->hasHeader('X-Drupal-Dynamic-Cache')); + if (!static::$auth) { + $this->assertSame(['HIT'], $response->getHeader('X-Drupal-Cache')); + $this->assertSame(['MISS'], $response->getHeader('X-Drupal-Dynamic-Cache')); + } + else { + $this->assertFalse($response->hasHeader('X-Drupal-Cache')); + $this->assertSame(['HIT'], $response->getHeader('X-Drupal-Dynamic-Cache')); + // Assert that Dynamic Page Cache did not store a ResourceResponse object, + // which needs serialization after every cache hit. Instead, it should + // contain a flattened response. Otherwise performance suffers. + // @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::flattenResponse() + $cache_items = $this->container->get('database') + ->query("SELECT cid, data FROM {cache_dynamic_page_cache} WHERE cid LIKE :pattern", [ + ':pattern' => '%[route]=rest.%', + ]) + ->fetchAllAssoc('cid'); + $this->assertCount(2, $cache_items); + $found_cache_redirect = FALSE; + $found_cached_response = FALSE; + foreach ($cache_items as $cid => $cache_item) { + $cached_data = unserialize($cache_item->data); + if (!isset($cached_data['#cache_redirect'])) { + $found_cached_response = TRUE; + $cached_response = $cached_data['#response']; + $this->assertNotInstanceOf(ResourceResponseInterface::class, $cached_response); + $this->assertInstanceOf(CacheableResponseInterface::class, $cached_response); + } + else { + $found_cache_redirect = TRUE; + } + } + $this->assertTrue($found_cache_redirect); + $this->assertTrue($found_cached_response); + } } else { - $this->assertFalse($response->hasHeader('X-Drupal-Cache')); + $this->assertFalse($response->hasHeader('X-Drupal-Dynamic-Cache')); } $cache_tags_header_value = $response->getHeader('X-Drupal-Cache-Tags')[0]; $this->assertEquals($this->getExpectedCacheTags(), empty($cache_tags_header_value) ? [] : explode(' ', $cache_tags_header_value)); $cache_contexts_header_value = $response->getHeader('X-Drupal-Cache-Contexts')[0]; $this->assertEquals($this->getExpectedCacheContexts(), empty($cache_contexts_header_value) ? [] : explode(' ', $cache_contexts_header_value)); - // Comparing the exact serialization is pointless, because the order of - // fields does not matter (at least not yet). That's why we only compare the - // normalized entity with the decoded response: it's comparing PHP arrays - // instead of strings. - $this->assertEquals($this->getExpectedNormalizedEntity(), $this->serializer->decode((string) $response->getBody(), static::$format)); + // Sort the serialization data first so we can do an identical comparison + // for the keys with the array order the same (it needs to match with + // identical comparison). + $expected = $this->getExpectedNormalizedEntity(); + static::recursiveKSort($expected); + $actual = $this->serializer->decode((string) $response->getBody(), static::$format); + static::recursiveKSort($actual); + $this->assertSame($expected, $actual); + // Not only assert the normalization, also assert deserialization of the // response results in the expected object. $unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format); $this->assertSame($unserialized->uuid(), $this->entity->uuid()); + // Finally, assert that the expected 'Link' headers are present. + if ($this->entity->getEntityType()->getLinkTemplates()) { + $this->assertArrayHasKey('Link', $response->getHeaders()); + $link_relation_type_manager = $this->container->get('plugin.manager.link_relation_type'); + $expected_link_relation_headers = array_map(function ($relation_name) use ($link_relation_type_manager) { + $link_relation_type = $link_relation_type_manager->createInstance($relation_name); + return $link_relation_type->isRegistered() + ? $link_relation_type->getRegisteredName() + : $link_relation_type->getExtensionUri(); + }, array_keys($this->entity->getEntityType()->getLinkTemplates())); + $parse_rel_from_link_header = function ($value) use ($link_relation_type_manager) { + $matches = []; + if (preg_match('/rel="([^"]+)"/', $value, $matches) === 1) { + return $matches[1]; + } + return FALSE; + }; + $this->assertSame($expected_link_relation_headers, array_map($parse_rel_from_link_header, $response->getHeader('Link'))); + } $get_headers = $response->getHeaders(); // Verify that the GET and HEAD responses are the same. The only difference @@ -394,16 +497,82 @@ public function testGet() { } $this->assertSame($get_headers, $head_headers); + // BC: serialization_update_8302(). + // Only run this for fieldable entities. It doesn't make sense for config + // entities as config values are already casted. They also run through the + // ConfigEntityNormalizer, which doesn't deal with fields individually. + if ($this->entity instanceof FieldableEntityInterface) { + // Test primitive data casting BC (strings). + $this->config('serialization.settings')->set('bc_primitives_as_strings', TRUE)->save(TRUE); + // Rebuild the container so new config is reflected in the addition of the + // PrimitiveDataNormalizer. + $this->rebuildAll(); + + $response = $this->request('GET', $url, $request_options); + $this->assertResourceResponse(200, FALSE, $response); + + + // Again do an identical comparison, but this time transform the expected + // normalized entity's values to strings. This ensures the BC layer for + // bc_primitives_as_strings works as expected. + $expected = $this->getExpectedNormalizedEntity(); + // Config entities are not affected. + // @see \Drupal\serialization\Normalizer\ConfigEntityNormalizer::normalize() + $expected = static::castToString($expected); + static::recursiveKSort($expected); + $actual = $this->serializer->decode((string) $response->getBody(), static::$format); + static::recursiveKSort($actual); + $this->assertSame($expected, $actual); + + // Reset the config value and rebuild. + $this->config('serialization.settings')->set('bc_primitives_as_strings', FALSE)->save(TRUE); + $this->rebuildAll(); + } + + // BC: serialization_update_8401(). + // Only run this for fieldable entities. It doesn't make sense for config + // entities as config values always use the raw values (as per the config + // schema), returned directly from the ConfigEntityNormalizer, which + // doesn't deal with fields individually. + if ($this->entity instanceof FieldableEntityInterface) { + // Test the BC settings for timestamp values. + $this->config('serialization.settings')->set('bc_timestamp_normalizer_unix', TRUE)->save(TRUE); + // Rebuild the container so new config is reflected in the addition of the + // TimestampItemNormalizer. + $this->rebuildAll(); + + + $response = $this->request('GET', $url, $request_options); + $this->assertResourceResponse(200, FALSE, $response); + + + // This ensures the BC layer for bc_timestamp_normalizer_unix works as + // expected. This method should be using + // ::formatExpectedTimestampValue() to generate the timestamp value. This + // will take into account the above config setting. + $expected = $this->getExpectedNormalizedEntity(); + // Config entities are not affected. + // @see \Drupal\serialization\Normalizer\ConfigEntityNormalizer::normalize() + static::recursiveKSort($expected); + $actual = $this->serializer->decode((string) $response->getBody(), static::$format); + static::recursiveKSort($actual); + $this->assertSame($expected, $actual); + + // Reset the config value and rebuild. + $this->config('serialization.settings')->set('bc_timestamp_normalizer_unix', FALSE)->save(TRUE); + $this->rebuildAll(); + } + + + // BC: rest_update_8203(). $this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE); - // @todo Remove this in https://www.drupal.org/node/2815845. - drupal_flush_all_caches(); + $this->refreshTestStateAfterRestConfigChange(); // DX: 403 when unauthorized. $response = $this->request('GET', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response); $this->grantPermissionsToTestedRole(['restful get entity:' . static::$entityTypeId]); @@ -414,23 +583,49 @@ public function testGet() { $this->assertResourceResponse(200, FALSE, $response); + $this->resourceConfigStorage->load(static::$resourceConfigId)->disable()->save(); + $this->refreshTestStateAfterRestConfigChange(); + + + // DX: upon disabling a resource, it's immediately no longer available. + $this->assertResourceNotAvailable($url, $request_options); + + + $this->resourceConfigStorage->load(static::$resourceConfigId)->enable()->save(); + $this->refreshTestStateAfterRestConfigChange(); + + + // DX: upon re-enabling a resource, immediate 200. + $response = $this->request('GET', $url, $request_options); + $this->assertResourceResponse(200, FALSE, $response); + + + $this->resourceConfigStorage->load(static::$resourceConfigId)->delete(); + $this->refreshTestStateAfterRestConfigChange(); + + + // DX: upon deleting a resource, it's immediately no longer available. + $this->assertResourceNotAvailable($url, $request_options); + + + $this->provisionEntityResource(); $url->setOption('query', ['_format' => 'non_existing_format']); // DX: 406 when requesting unsupported format. $response = $this->request('GET', $url, $request_options); $this->assert406Response($response); - $this->assertNotSame([static::$expectedErrorMimeType], $response->getHeader('Content-Type')); + $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type')); $request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType; - // DX: 406 when requesting unsupported format but specifying Accept header. - // @todo Update in https://www.drupal.org/node/2825347. + // DX: 406 when requesting unsupported format but specifying Accept header: + // should result in a text/plain response. $response = $this->request('GET', $url, $request_options); $this->assert406Response($response); - $this->assertSame([static::$expectedErrorMimeType], $response->getHeader('Content-Type')); + $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type')); $url = Url::fromRoute('rest.entity.' . static::$entityTypeId . '.GET.' . static::$format); @@ -445,6 +640,51 @@ public function testGet() { $this->assertResourceErrorResponse(404, $message, $response); } + /** + * Transforms a normalization: casts all non-string types to strings. + * + * @param array $normalization + * A normalization to transform. + * + * @return array + * The transformed normalization. + */ + protected static function castToString(array $normalization) { + foreach ($normalization as $key => $value) { + if (is_bool($value)) { + $normalization[$key] = (string) (int) $value; + } + elseif (is_int($value) || is_float($value)) { + $normalization[$key] = (string) $value; + } + elseif (is_array($value)) { + $normalization[$key] = static::castToString($value); + } + } + return $normalization; + } + + /** + * Recursively sorts an array by key. + * + * @param array $array + * An array to sort. + * + * @return array + * The sorted array. + */ + protected static function recursiveKSort(array &$array) { + // First, sort the main array. + ksort($array); + + // Then check for child arrays. + foreach ($array as $key => &$value) { + if (is_array($value)) { + static::recursiveKSort($value); + } + } + } + /** * Tests a POST request for an entity, plus edge cases to ensure good DX. */ @@ -463,8 +703,7 @@ public function testPost() { $parseable_valid_request_body = $this->serializer->encode($this->getNormalizedPostEntity(), static::$format); $parseable_valid_request_body_2 = $this->serializer->encode($this->getNormalizedPostEntity(), static::$format); $parseable_invalid_request_body = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPostEntity()), static::$format); - // @todo Change to ['uuid' => UUID] in https://www.drupal.org/node/2820743. - $parseable_invalid_request_body_2 = $this->serializer->encode($this->getNormalizedPostEntity() + ['uuid' => [['value' => $this->randomMachineName(129)]]], static::$format); + $parseable_invalid_request_body_2 = $this->serializer->encode($this->getNormalizedPostEntity() + ['uuid' => [$this->randomMachineName(129)]], static::$format); $parseable_invalid_request_body_3 = $this->serializer->encode($this->getNormalizedPostEntity() + ['field_rest_test' => [['value' => $this->randomString()]]], static::$format); // The URL and Guzzle request options that will be used in this test. The @@ -472,19 +711,15 @@ public function testPost() { // - to first test all mistakes a developer might make, and assert that the // error responses provide a good DX // - to eventually result in a well-formed request that succeeds. - $url = $this->getPostUrl(); + $url = $this->getEntityResourcePostUrl(); $request_options = []; - // DX: 404 when resource not provisioned, but HTML if canonical route. + // DX: 404 when resource not provisioned. HTML response because missing + // ?_format query string. $response = $this->request('POST', $url, $request_options); - if ($has_canonical_url) { - $this->assertSame(404, $response->getStatusCode()); - $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); - } - else { - $this->assertResourceErrorResponse(404, 'No route found for "GET ' . str_replace($this->baseUrl, '', $this->getUrl()->setAbsolute()->toString()) . '"', $response); - } + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); $url->setOption('query', ['_format' => static::$format]); @@ -492,7 +727,7 @@ public function testPost() { // DX: 404 when resource not provisioned. $response = $this->request('POST', $url, $request_options); - $this->assertResourceErrorResponse(404, 'No route found for "POST ' . str_replace($this->baseUrl, '', $this->getPostUrl()->setAbsolute()->toString()) . '"', $response); + $this->assertResourceErrorResponse(404, 'No route found for "POST ' . str_replace($this->baseUrl, '', $this->getEntityResourcePostUrl()->setAbsolute()->toString()) . '"', $response); $this->provisionEntityResource(); @@ -500,16 +735,12 @@ public function testPost() { $url->setOption('query', []); - // DX: 415 when no Content-Type request header, but HTML if canonical route. + // DX: 415 when no Content-Type request header. HTML response because + // missing ?_format query string. $response = $this->request('POST', $url, $request_options); - if ($has_canonical_url) { - $this->assertSame(415, $response->getStatusCode()); - $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); - $this->assertContains(htmlspecialchars('No "Content-Type" request header specified'), (string) $response->getBody()); - } - else { - $this->assertResourceErrorResponse(415, 'No "Content-Type" request header specified', $response); - } + $this->assertSame(415, $response->getStatusCode()); + $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); + $this->assertContains('A client error happened', (string) $response->getBody()); $url->setOption('query', ['_format' => static::$format]); @@ -533,12 +764,7 @@ public function testPost() { // DX: 400 when unparseable request body. $response = $this->request('POST', $url, $request_options); - // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853. - // $this->assertResourceErrorResponse(400, 'Syntax error', $response); - $this->assertSame(400, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['error' => 'Syntax error'], static::$format), (string) $response->getBody()); - + $this->assertResourceErrorResponse(400, 'Syntax error', $response); $request_options[RequestOptions::BODY] = $parseable_invalid_request_body; @@ -557,8 +783,7 @@ public function testPost() { // DX: 403 when unauthorized. $response = $this->request('POST', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('POST'), $response); $this->setUpAuthorization('POST'); @@ -567,24 +792,19 @@ public function testPost() { // DX: 422 when invalid entity: multiple values sent for single-value field. $response = $this->request('POST', $url, $request_options); $label_field = $this->entity->getEntityType()->hasKey('label') ? $this->entity->getEntityType()->getKey('label') : static::$labelFieldName; - $label_field_capitalized = ucfirst($label_field); - // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813755. - // $this->assertErrorResponse(422, "Unprocessable Entity: validation failed.\ntitle: Title: this field cannot hold more than 1 values.\n", $response); - $this->assertSame(422, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\n$label_field: $label_field_capitalized: this field cannot hold more than 1 values.\n"], static::$format), (string) $response->getBody()); + $label_field_capitalized = $this->entity->getFieldDefinition($label_field)->getLabel(); + $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\n$label_field: $label_field_capitalized: this field cannot hold more than 1 values.\n", $response); $request_options[RequestOptions::BODY] = $parseable_invalid_request_body_2; // DX: 422 when invalid entity: UUID field too long. - $response = $this->request('POST', $url, $request_options); - // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813755. - // $this->assertErrorResponse(422, "Unprocessable Entity: validation failed.\nuuid.0.value: UUID: may not be longer than 128 characters.\n", $response); - $this->assertSame(422, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\nuuid.0.value: UUID: may not be longer than 128 characters.\n"], static::$format), (string) $response->getBody()); + // @todo Fix this in https://www.drupal.org/node/2149851. + if ($this->entity->getEntityType()->hasKey('uuid')) { + $response = $this->request('POST', $url, $request_options); + $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nuuid.0.value: UUID: may not be longer than 128 characters.\n", $response); + } $request_options[RequestOptions::BODY] = $parseable_invalid_request_body_3; @@ -592,8 +812,7 @@ public function testPost() { // DX: 403 when entity contains field without 'edit' access. $response = $this->request('POST', $url, $request_options); - // @todo Add trailing period in https://www.drupal.org/node/2821013. - $this->assertResourceErrorResponse(403, "Access denied on creating field 'field_rest_test'", $response); + $this->assertResourceErrorResponse(403, "Access denied on creating field 'field_rest_test'.", $response); $request_options[RequestOptions::BODY] = $parseable_valid_request_body; @@ -610,10 +829,7 @@ public function testPost() { // DX: 415 when request body in existing but not allowed format. $response = $this->request('POST', $url, $request_options); - // @todo Update this in https://www.drupal.org/node/2826407. Also move it - // higher, before the "no request body" test. That's impossible right now, - // because the format validation happens too late. - $this->assertResourceErrorResponse(415, '', $response); + $this->assertResourceErrorResponse(415, 'No route found that matches "Content-Type: text/xml"', $response); $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType; @@ -622,30 +838,72 @@ public function testPost() { // 201 for well-formed request. $response = $this->request('POST', $url, $request_options); $this->assertResourceResponse(201, FALSE, $response); - $this->assertSame([str_replace($this->entity->id(), static::$firstCreatedEntityId, $this->entity->toUrl('canonical')->setAbsolute(TRUE)->toString())], $response->getHeader('Location')); + if ($has_canonical_url) { + $location = $this->entityStorage->load(static::$firstCreatedEntityId)->toUrl('canonical')->setAbsolute(TRUE)->toString(); + $this->assertSame([$location], $response->getHeader('Location')); + } + else { + $this->assertSame([], $response->getHeader('Location')); + } $this->assertFalse($response->hasHeader('X-Drupal-Cache')); + // Assert that the entity was indeed created, and that the response body + // contains the serialized created entity. + $created_entity = $this->entityStorage->loadUnchanged(static::$firstCreatedEntityId); + $created_entity_normalization = $this->serializer->normalize($created_entity, static::$format, ['account' => $this->account]); + // @todo Remove this if-test in https://www.drupal.org/node/2543726: execute + // its body unconditionally. + if (static::$entityTypeId !== 'taxonomy_term') { + $this->assertSame($created_entity_normalization, $this->serializer->decode((string) $response->getBody(), static::$format)); + } + // Assert that the entity was indeed created using the POSTed values. + foreach ($this->getNormalizedPostEntity() as $field_name => $field_normalization) { + // Some top-level keys in the normalization may not be fields on the + // entity (for example '_links' and '_embedded' in the HAL normalization). + if ($created_entity->hasField($field_name)) { + // Subset, not same, because we can e.g. send just the target_id for the + // bundle in a POST request; the response will include more properties. + $this->assertArraySubset(static::castToString($field_normalization), $created_entity->get($field_name)->getValue(), TRUE); + } + } $this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE); + $this->refreshTestStateAfterRestConfigChange(); $request_options[RequestOptions::BODY] = $parseable_valid_request_body_2; - // @todo Remove this in https://www.drupal.org/node/2815845. - drupal_flush_all_caches(); // DX: 403 when unauthorized. $response = $this->request('POST', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('POST'), $response); $this->grantPermissionsToTestedRole(['restful post entity:' . static::$entityTypeId]); // 201 for well-formed request. + // Delete the first created entity in case there is a uniqueness constraint. + $this->entityStorage->load(static::$firstCreatedEntityId)->delete(); $response = $this->request('POST', $url, $request_options); $this->assertResourceResponse(201, FALSE, $response); - $this->assertSame([str_replace($this->entity->id(), static::$secondCreatedEntityId, $this->entity->toUrl('canonical')->setAbsolute(TRUE)->toString())], $response->getHeader('Location')); + if ($has_canonical_url) { + $location = $this->entityStorage->load(static::$secondCreatedEntityId)->toUrl('canonical')->setAbsolute(TRUE)->toString(); + $this->assertSame([$location], $response->getHeader('Location')); + } + else { + $this->assertSame([], $response->getHeader('Location')); + } $this->assertFalse($response->hasHeader('X-Drupal-Cache')); + + // BC: old default POST URLs have their path updated by the inbound path + // processor \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC to the + // new URL, which is derived from the 'create' link template if an entity + // type specifies it. + if ($this->entity->getEntityType()->hasLinkTemplate('create')) { + $this->entityStorage->load(static::$secondCreatedEntityId)->delete(); + $old_url = Url::fromUri('base:entity/' . static::$entityTypeId); + $response = $this->request('POST', $old_url, $request_options); + $this->assertResourceResponse(201, FALSE, $response); + } } /** @@ -673,27 +931,36 @@ public function testPatch() { // - to first test all mistakes a developer might make, and assert that the // error responses provide a good DX // - to eventually result in a well-formed request that succeeds. - $url = $this->getUrl(); + $url = $this->getEntityResourceUrl(); $request_options = []; - // DX: 405 when resource not provisioned, but HTML if canonical route. + // DX: 404 when resource not provisioned, 405 if canonical route. Plain text + // or HTML response because missing ?_format query string. $response = $this->request('PATCH', $url, $request_options); if ($has_canonical_url) { $this->assertSame(405, $response->getStatusCode()); + $this->assertSame(['GET, POST, HEAD'], $response->getHeader('Allow')); $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); + $this->assertContains('A client error happened', (string) $response->getBody()); } else { - $this->assertResourceErrorResponse(404, 'No route found for "PATCH ' . str_replace($this->baseUrl, '', $this->getUrl()->setAbsolute()->toString()) . '"', $response); + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); } $url->setOption('query', ['_format' => static::$format]); - // DX: 405 when resource not provisioned. + // DX: 404 when resource not provisioned, 405 if canonical route. $response = $this->request('PATCH', $url, $request_options); - $this->assertResourceErrorResponse(405, 'No route found for "PATCH ' . str_replace($this->baseUrl, '', $this->getUrl()->setAbsolute()->toString()) . '": Method Not Allowed (Allow: GET, POST, HEAD)', $response); + if ($has_canonical_url) { + $this->assertResourceErrorResponse(405, 'No route found for "PATCH ' . str_replace($this->baseUrl, '', $this->getEntityResourceUrl()->setAbsolute()->toString()) . '": Method Not Allowed (Allow: GET, POST, HEAD)', $response); + } + else { + $this->assertResourceErrorResponse(404, 'No route found for "PATCH ' . str_replace($this->baseUrl, '', $this->getEntityResourceUrl()->setAbsolute()->toString()) . '"', $response); + } $this->provisionEntityResource(); @@ -701,16 +968,11 @@ public function testPatch() { $url->setOption('query', []); - // DX: 415 when no Content-Type request header, but HTML if canonical route. + // DX: 415 when no Content-Type request header. $response = $this->request('PATCH', $url, $request_options); - if ($has_canonical_url) { - $this->assertSame(415, $response->getStatusCode()); - $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); - $this->assertTrue(FALSE !== strpos((string) $response->getBody(), htmlspecialchars('No "Content-Type" request header specified'))); - } - else { - $this->assertResourceErrorResponse(415, 'No "Content-Type" request header specified', $response); - } + $this->assertSame(415, $response->getStatusCode()); + $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); + $this->assertContains('A client error happened', (string) $response->getBody()); $url->setOption('query', ['_format' => static::$format]); @@ -734,12 +996,7 @@ public function testPatch() { // DX: 400 when unparseable request body. $response = $this->request('PATCH', $url, $request_options); - // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853. - // $this->assertResourceErrorResponse(400, 'Syntax error', $response); - $this->assertSame(400, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['error' => 'Syntax error'], static::$format), (string) $response->getBody()); - + $this->assertResourceErrorResponse(400, 'Syntax error', $response); $request_options[RequestOptions::BODY] = $parseable_invalid_request_body; @@ -758,8 +1015,7 @@ public function testPatch() { // DX: 403 when unauthorized. $response = $this->request('PATCH', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('PATCH'), $response); $this->setUpAuthorization('PATCH'); @@ -768,12 +1024,8 @@ public function testPatch() { // DX: 422 when invalid entity: multiple values sent for single-value field. $response = $this->request('PATCH', $url, $request_options); $label_field = $this->entity->getEntityType()->hasKey('label') ? $this->entity->getEntityType()->getKey('label') : static::$labelFieldName; - $label_field_capitalized = ucfirst($label_field); - // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813755. - // $this->assertErrorResponse(422, "Unprocessable Entity: validation failed.\ntitle: Title: this field cannot hold more than 1 values.\n", $response); - // $this->assertSame(422, $response->getStatusCode()); - // $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\n$label_field: $label_field_capitalized: this field cannot hold more than 1 values.\n"], static::$format), (string) $response->getBody()); + $label_field_capitalized = $this->entity->getFieldDefinition($label_field)->getLabel(); + $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\n$label_field: $label_field_capitalized: this field cannot hold more than 1 values.\n", $response); $request_options[RequestOptions::BODY] = $parseable_invalid_request_body_2; @@ -818,10 +1070,7 @@ public function testPatch() { // DX: 415 when request body in existing but not allowed format. $response = $this->request('PATCH', $url, $request_options); - // @todo Update this in https://www.drupal.org/node/2826407. Also move it - // higher, before the "no request body" test. That's impossible right now, - // because the format validation happens too late. - $this->assertResourceErrorResponse(415, '', $response); + $this->assertResourceErrorResponse(415, 'No route found that matches "Content-Type: text/xml"', $response); $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType; @@ -831,22 +1080,35 @@ public function testPatch() { $response = $this->request('PATCH', $url, $request_options); $this->assertResourceResponse(200, FALSE, $response); $this->assertFalse($response->hasHeader('X-Drupal-Cache')); + // Assert that the entity was indeed updated, and that the response body + // contains the serialized updated entity. + $updated_entity = $this->entityStorage->loadUnchanged($this->entity->id()); + $updated_entity_normalization = $this->serializer->normalize($updated_entity, static::$format, ['account' => $this->account]); + $this->assertSame($updated_entity_normalization, $this->serializer->decode((string) $response->getBody(), static::$format)); + // Assert that the entity was indeed created using the PATCHed values. + foreach ($this->getNormalizedPatchEntity() as $field_name => $field_normalization) { + // Some top-level keys in the normalization may not be fields on the + // entity (for example '_links' and '_embedded' in the HAL normalization). + if ($updated_entity->hasField($field_name)) { + // Subset, not same, because we can e.g. send just the target_id for the + // bundle in a PATCH request; the response will include more properties. + $this->assertArraySubset(static::castToString($field_normalization), $updated_entity->get($field_name)->getValue(), TRUE); + } + } // Ensure that fields do not get deleted if they're not present in the PATCH // request. Test this using the configurable field that we added, but which // is not sent in the PATCH request. - $this->assertSame('All the faith he had had had had no effect on the outcome of his life.', $this->entityStorage->loadUnchanged($this->entity->id())->get('field_rest_test')->value); + $this->assertSame('All the faith he had had had had no effect on the outcome of his life.', $updated_entity->get('field_rest_test')->value); $this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE); + $this->refreshTestStateAfterRestConfigChange(); $request_options[RequestOptions::BODY] = $parseable_valid_request_body_2; - // @todo Remove this in https://www.drupal.org/node/2815845. - drupal_flush_all_caches(); // DX: 403 when unauthorized. $response = $this->request('PATCH', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('PATCH'), $response); $this->grantPermissionsToTestedRole(['restful patch entity:' . static::$entityTypeId]); @@ -876,28 +1138,37 @@ public function testDelete() { // - to first test all mistakes a developer might make, and assert that the // error responses provide a good DX // - to eventually result in a well-formed request that succeeds. - $url = $this->getUrl(); + $url = $this->getEntityResourceUrl(); $request_options = []; - // DX: 405 when resource not provisioned, but HTML if canonical route. + // DX: 404 when resource not provisioned, but 405 if canonical route. Plain + // text or HTML response because missing ?_format query string. $response = $this->request('DELETE', $url, $request_options); if ($has_canonical_url) { $this->assertSame(405, $response->getStatusCode()); + $this->assertSame(['GET, POST, HEAD'], $response->getHeader('Allow')); $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); + $this->assertContains('A client error happened', (string) $response->getBody()); } else { - $this->assertResourceErrorResponse(404, 'No route found for "DELETE ' . str_replace($this->baseUrl, '', $this->getUrl()->setAbsolute()->toString()) . '"', $response); + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type')); } $url->setOption('query', ['_format' => static::$format]); - // DX: 405 when resource not provisioned. + // DX: 404 when resource not provisioned, 405 if canonical route. $response = $this->request('DELETE', $url, $request_options); - $this->assertResourceErrorResponse(405, 'No route found for "DELETE ' . str_replace($this->baseUrl, '', $this->getUrl()->setAbsolute()->toString()) . '": Method Not Allowed (Allow: GET, POST, HEAD)', $response); - + if ($has_canonical_url) { + $this->assertSame(['GET, POST, HEAD'], $response->getHeader('Allow')); + $this->assertResourceErrorResponse(405, 'No route found for "DELETE ' . str_replace($this->baseUrl, '', $this->getEntityResourceUrl()->setAbsolute()->toString()) . '": Method Not Allowed (Allow: GET, POST, HEAD)', $response); + } + else { + $this->assertResourceErrorResponse(404, 'No route found for "DELETE ' . str_replace($this->baseUrl, '', $this->getEntityResourceUrl()->setAbsolute()->toString()) . '"', $response); + } $this->provisionEntityResource(); @@ -915,8 +1186,7 @@ public function testDelete() { // DX: 403 when unauthorized. $response = $this->request('DELETE', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('DELETE'), $response); $this->setUpAuthorization('DELETE'); @@ -930,23 +1200,24 @@ public function testDelete() { // 204 for well-formed request. $response = $this->request('DELETE', $url, $request_options); $this->assertSame(204, $response->getStatusCode()); - // @todo Uncomment the following line when https://www.drupal.org/node/2821711 is fixed. + // DELETE responses should not include a Content-Type header. But Apache + // sets it to 'text/html' by default. We also cannot detect the presence of + // Apache either here in the CLI. For now having this documented here is all + // we can do. // $this->assertSame(FALSE, $response->hasHeader('Content-Type')); $this->assertSame('', (string) $response->getBody()); $this->assertFalse($response->hasHeader('X-Drupal-Cache')); $this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE); - // @todo Remove this in https://www.drupal.org/node/2815845. - drupal_flush_all_caches(); + $this->refreshTestStateAfterRestConfigChange(); $this->entity = $this->createEntity(); - $url = $this->getUrl()->setOption('query', $url->getOption('query')); + $url = $this->getEntityResourceUrl()->setOption('query', $url->getOption('query')); // DX: 403 when unauthorized. $response = $this->request('DELETE', $url, $request_options); - // @todo Update the message in https://www.drupal.org/node/2808233. - $this->assertResourceErrorResponse(403, '', $response); + $this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('DELETE'), $response); $this->grantPermissionsToTestedRole(['restful delete entity:' . static::$entityTypeId]); @@ -979,14 +1250,9 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); - // DX: 400 when incorrect entity type bundle is specified. - // @todo Change to 422 in https://www.drupal.org/node/2827084. + // DX: 422 when incorrect entity type bundle is specified. $response = $this->request($method, $url, $request_options); - // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813853 lands. - // $this->assertResourceErrorResponse(400, '"bad_bundle_name" is not a valid bundle type for denormalization.', $response); - $this->assertSame(400, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['error' => '"bad_bundle_name" is not a valid bundle type for denormalization.'], static::$format), (string) $response->getBody()); + $this->assertResourceErrorResponse(422, '"bad_bundle_name" is not a valid bundle type for denormalization.', $response); } @@ -994,14 +1260,9 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); - // DX: 400 when no entity type bundle is specified. - // @todo Change to 422 in https://www.drupal.org/node/2827084. + // DX: 422 when no entity type bundle is specified. $response = $this->request($method, $url, $request_options); - // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813853 lands. - // $this->assertResourceErrorResponse(400, 'A string must be provided as a bundle value.', $response); - $this->assertSame(400, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['error' => 'A string must be provided as a bundle value.'], static::$format), (string) $response->getBody()); + $this->assertResourceErrorResponse(422, sprintf('Could not determine entity type bundle: "%s" field is missing.', $bundle_field_name), $response); } } @@ -1011,9 +1272,12 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques * @return \Drupal\Core\Url * The URL to GET/PATCH/DELETE. */ - protected function getUrl() { + protected function getEntityResourceUrl() { $has_canonical_url = $this->entity->hasLinkTemplate('canonical'); - return $has_canonical_url ? $this->entity->toUrl() : Url::fromUri('base:entity/' . static::$entityTypeId . '/' . $this->entity->id()); + // Note that the 'canonical' link relation type must be specified explicitly + // in the call to ::toUrl(). 'canonical' is the default for + // \Drupal\Core\Entity\Entity::toUrl(), but ConfigEntityBase overrides this. + return $has_canonical_url ? $this->entity->toUrl('canonical') : Url::fromUri('base:entity/' . static::$entityTypeId . '/' . $this->entity->id()); } /** @@ -1022,9 +1286,9 @@ protected function getUrl() { * @return \Drupal\Core\Url * The URL to POST to. */ - protected function getPostUrl() { - $has_canonical_url = $this->entity->hasLinkTemplate('https://www.drupal.org/link-relations/create'); - return $has_canonical_url ? $this->entity->toUrl() : Url::fromUri('base:entity/' . static::$entityTypeId); + protected function getEntityResourcePostUrl() { + $has_create_url = $this->entity->hasLinkTemplate('create'); + return $has_create_url ? Url::fromUri('internal:' . $this->entity->getEntityType()->getLinkTemplate('create')) : Url::fromUri('base:entity/' . static::$entityTypeId); } /** @@ -1090,4 +1354,23 @@ protected function assert406Response(ResponseInterface $response) { } } + /** + * Asserts that a resource is unavailable: 404, 406 if it has canonical route. + * + * @param \Drupal\Core\Url $url + * URL to request. + * @param array $request_options + * Request options to apply. + */ + protected function assertResourceNotAvailable(Url $url, array $request_options) { + $has_canonical_url = $this->entity->hasLinkTemplate('canonical'); + $response = $this->request('GET', $url, $request_options); + if (!$has_canonical_url) { + $this->assertSame(404, $response->getStatusCode()); + } + else { + $this->assert406Response($response); + } + } + } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonAnonTest.php index a7e44205..ff047d40 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonAnonTest.php @@ -21,9 +21,4 @@ class EntityTestJsonAnonTest extends EntityTestResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonBasicAuthTest.php index be757841..aff854ed 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class EntityTestJsonBasicAuthTest extends EntityTestResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonCookieTest.php index 84079220..c0090d5d 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestJsonCookieTest.php @@ -21,11 +21,6 @@ class EntityTestJsonCookieTest extends EntityTestResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestResourceTestBase.php index da86d000..e2c0ccdf 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestResourceTestBase.php @@ -3,11 +3,14 @@ namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest; use Drupal\entity_test\Entity\EntityTest; +use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait; use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; use Drupal\user\Entity\User; abstract class EntityTestResourceTestBase extends EntityResourceTestBase { + use BcTimestampNormalizerUnixTestTrait; + /** * {@inheritdoc} */ @@ -73,7 +76,7 @@ protected function getExpectedNormalizedEntity() { ], 'id' => [ [ - 'value' => '1', + 'value' => 1, ], ], 'langcode' => [ @@ -92,13 +95,11 @@ protected function getExpectedNormalizedEntity() { ] ], 'created' => [ - [ - 'value' => $this->entity->get('created')->value, - ] + $this->formatExpectedTimestampItemValues((int) $this->entity->get('created')->value) ], 'user_id' => [ [ - 'target_id' => $author->id(), + 'target_id' => (int) $author->id(), 'target_type' => 'user', 'target_uuid' => $author->uuid(), 'url' => $author->toUrl()->toString(), @@ -115,7 +116,11 @@ protected function getExpectedNormalizedEntity() { */ protected function getNormalizedPostEntity() { return [ - 'type' => 'entity_test', + 'type' => [ + [ + 'value' => 'entity_test', + ], + ], 'name' => [ [ 'value' => 'Dramallama', @@ -124,4 +129,22 @@ protected function getNormalizedPostEntity() { ]; } + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'view test entity' permission is required."; + case 'POST': + return "The following permissions are required: 'administer entity_test content' OR 'administer entity_test_with_bundle content' OR 'create entity_test entity_test_with_bundle entities'."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTestBundle/EntityTestBundleJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTestBundle/EntityTestBundleJsonAnonTest.php new file mode 100644 index 00000000..1df26f38 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTestBundle/EntityTestBundleJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer entity_test_bundle content']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $entity_test_bundle = EntityTestBundle::create([ + 'id' => 'camelids', + 'label' => 'Camelids', + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + ]); + $entity_test_bundle->save(); + + return $entity_test_bundle; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'id' => 'camelids', + 'label' => 'Camelids', + 'langcode' => 'en', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTestLabel/EntityTestLabelJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTestLabel/EntityTestLabelJsonAnonTest.php new file mode 100644 index 00000000..10c4ec49 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTestLabel/EntityTestLabelJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['view test entity']); + break; + case 'POST': + $this->grantPermissionsToTestedRole([ + 'administer entity_test content', + 'administer entity_test_with_bundle content', + 'create entity_test entity_test_with_bundle entities', + ]); + break; + case 'PATCH': + case 'DELETE': + $this->grantPermissionsToTestedRole(['administer entity_test content']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $entity_test_label = EntityTestLabel::create([ + 'name' => 'label_llama', + ]); + $entity_test_label->setOwnerId(0); + $entity_test_label->save(); + return $entity_test_label; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + $author = User::load(0); + $normalization = [ + 'uuid' => [ + [ + 'value' => $this->entity->uuid(), + ], + ], + 'id' => [ + [ + 'value' => (int) $this->entity->id(), + ], + ], + 'langcode' => [ + [ + 'value' => 'en', + ], + ], + 'type' => [ + [ + 'value' => 'entity_test_label', + ], + ], + 'name' => [ + [ + 'value' => 'label_llama', + ], + ], + 'created' => [ + $this->formatExpectedTimestampItemValues((int) $this->entity->get('created')->value), + ], + 'user_id' => [ + [ + 'target_id' => (int) $author->id(), + 'target_type' => 'user', + 'target_uuid' => $author->uuid(), + 'url' => $author->toUrl()->toString(), + ], + ], + ]; + + return $normalization; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return [ + 'type' => [ + [ + 'value' => 'entity_test_label', + ], + ], + 'name' => [ + [ + 'value' => 'label_llama', + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return ['user.permissions']; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'view test entity' permission is required."; + case 'POST': + return "The following permissions are required: 'administer entity_test content' OR 'administer entity_test_with_bundle content' OR 'create entity_test_label entity_test_with_bundle entities'."; + case 'PATCH': + case 'DELETE': + return "The 'administer entity_test content' permission is required."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityViewMode/EntityViewModeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityViewMode/EntityViewModeJsonAnonTest.php new file mode 100644 index 00000000..b74b8258 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityViewMode/EntityViewModeJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer display modes']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $entity_view_mode = EntityViewMode::create([ + 'id' => 'user.test', + 'label' => 'Test', + 'targetEntityType' => 'user', + ]); + $entity_view_mode->save(); + return $entity_view_mode; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'cache' => TRUE, + 'dependencies' => [ + 'module' => [ + 'user', + ], + ], + 'id' => 'user.test', + 'label' => 'Test', + 'langcode' => 'en', + 'status' => TRUE, + 'targetEntityType' => 'user', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Feed/FeedJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Feed/FeedJsonAnonTest.php new file mode 100644 index 00000000..a4b8e0dc --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Feed/FeedJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access news feeds']); + break; + case 'POST': + case 'PATCH': + case 'DELETE': + $this->grantPermissionsToTestedRole(['administer news feeds']); + break; + } + } + + /** + * {@inheritdoc} + */ + public function createEntity() { + $feed = Feed::create(); + $feed->set('fid', 1) + ->set('uuid', 'abcdefg') + ->setTitle('Feed') + ->setUrl('http://example.com/rss.xml') + ->setDescription('Feed Resource Test 1') + ->setRefreshRate(900) + ->setLastCheckedTime(123456789) + ->setQueuedTime(123456789) + ->setWebsiteUrl('http://example.com') + ->setImage('http://example.com/feed_logo') + ->setHash('abcdefg') + ->setEtag('hijklmn') + ->setLastModified(123456789) + ->save(); + + return $feed; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'uuid' => [ + [ + 'value' => 'abcdefg' + ] + ], + 'fid' => [ + [ + 'value' => 1 + ] + ], + 'langcode' => [ + [ + 'value' => 'en' + ] + ], + 'url' => [ + [ + 'value' => 'http://example.com/rss.xml' + ] + ], + 'title' => [ + [ + 'value' => 'Feed' + ] + ], + 'refresh' => [ + [ + 'value' => 900 + ] + ], + 'checked' => [ + $this->formatExpectedTimestampItemValues(123456789), + ], + 'queued' => [ + $this->formatExpectedTimestampItemValues(123456789), + ], + 'link' => [ + [ + 'value' => 'http://example.com' + ] + ], + 'description' => [ + [ + 'value' => 'Feed Resource Test 1' + ] + ], + 'image' => [ + [ + 'value' => 'http://example.com/feed_logo' + ] + ], + 'hash' => [ + [ + 'value' => 'abcdefg' + ] + ], + 'etag' => [ + [ + 'value' => 'hijklmn' + ] + ], + 'modified' => [ + $this->formatExpectedTimestampItemValues(123456789), + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return [ + 'title' => [ + [ + 'value' => 'Feed Resource Post Test' + ] + ], + 'url' => [ + [ + 'value' => 'http://example.com/feed' + ] + ], + 'refresh' => [ + [ + 'value' => 900 + ] + ], + 'description' => [ + [ + 'value' => 'Feed Resource Post Test Description' + ] + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'access news feeds' permission is required."; + case 'POST': + case 'PATCH': + case 'DELETE': + return "The 'administer news feeds' permission is required."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FieldConfig/FieldConfigJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/FieldConfig/FieldConfigJsonAnonTest.php new file mode 100644 index 00000000..0e6883a5 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/FieldConfig/FieldConfigJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer node fields']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $camelids = NodeType::create([ + 'name' => 'Camelids', + 'type' => 'camelids', + ]); + $camelids->save(); + + $field_storage = FieldStorageConfig::create([ + 'field_name' => 'field_llama', + 'entity_type' => 'node', + 'type' => 'text', + ]); + $field_storage->save(); + + $entity = FieldConfig::create([ + 'field_storage' => $field_storage, + 'bundle' => 'camelids', + ]); + $entity->save(); + + return $entity; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'bundle' => 'camelids', + 'default_value' => [], + 'default_value_callback' => '', + 'dependencies' => [ + 'config' => [ + 'field.storage.node.field_llama', + 'node.type.camelids', + ], + 'module' => [ + 'text', + ], + ], + 'description' => '', + 'entity_type' => 'node', + 'field_name' => 'field_llama', + 'field_type' => 'text', + 'id' => 'node.camelids.field_llama', + 'label' => 'field_llama', + 'langcode' => 'en', + 'required' => FALSE, + 'settings' => [], + 'status' => TRUE, + 'translatable' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'administer node fields' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonAnonTest.php new file mode 100644 index 00000000..582a0b0e --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer node fields']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $field_storage = FieldStorageConfig::create([ + 'field_name' => 'true_llama', + 'entity_type' => 'node', + 'type' => 'boolean', + ]); + $field_storage->save(); + return $field_storage; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'cardinality' => 1, + 'custom_storage' => FALSE, + 'dependencies' => [ + 'module' => ['node'], + ], + 'entity_type' => 'node', + 'field_name' => 'true_llama', + 'id' => 'node.true_llama', + 'indexes' => [], + 'langcode' => 'en', + 'locked' => FALSE, + 'module' => 'core', + 'persist_with_no_fields' => FALSE, + 'settings' => [], + 'status' => TRUE, + 'translatable' => TRUE, + 'type' => 'boolean', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'administer node fields' permission is required."; + + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FilterFormat/FilterFormatJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/FilterFormat/FilterFormatJsonAnonTest.php new file mode 100644 index 00000000..60a24fb9 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/FilterFormat/FilterFormatJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer filters']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $pablo_format = FilterFormat::create([ + 'name' => 'Pablo Piccasso', + 'format' => 'pablo', + 'langcode' => 'es', + 'filters' => [ + 'filter_html' => [ + 'status' => TRUE, + 'settings' => [ + 'allowed_html' => '

    ', + ], + ], + ], + ]); + $pablo_format->save(); + return $pablo_format; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'filters' => [ + 'filter_html' => [ + 'id' => 'filter_html', + 'provider' => 'filter', + 'status' => TRUE, + 'weight' => -10, + 'settings' => [ + 'allowed_html' => '

    ', + 'filter_html_help' => TRUE, + 'filter_html_nofollow' => FALSE, + ], + ], + ], + 'format' => 'pablo', + 'langcode' => 'es', + 'name' => 'Pablo Piccasso', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + 'weight' => 0, + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ImageStyle/ImageStyleJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ImageStyle/ImageStyleJsonAnonTest.php new file mode 100644 index 00000000..0089f8ed --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/ImageStyle/ImageStyleJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer image styles']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" image style. + $camelids = ImageStyle::create([ + 'name' => 'camelids', + 'label' => 'Camelids', + ]); + + // Add an image effect. + $effect = [ + 'id' => 'image_scale_and_crop', + 'data' => [ + 'width' => 120, + 'height' => 121, + ], + 'weight' => 0, + ]; + $this->effectUuid = $camelids->addImageEffect($effect); + + $camelids->save(); + + return $camelids; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'effects' => [ + $this->effectUuid => [ + 'uuid' => $this->effectUuid, + 'id' => 'image_scale_and_crop', + 'weight' => 0, + 'data' => [ + 'width' => 120, + 'height' => 121, + ], + ], + ], + 'label' => 'Camelids', + 'langcode' => 'en', + 'name' => 'camelids', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'administer image styles' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Item/ItemJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Item/ItemJsonAnonTest.php new file mode 100644 index 00000000..dac1b0a6 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Item/ItemJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access news feeds']); + break; + + case 'POST': + case 'PATCH': + case 'DELETE': + $this->grantPermissionsToTestedRole(['administer news feeds']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" feed. + $feed = Feed::create([ + 'title' => 'Camelids', + 'url' => 'https://groups.drupal.org/not_used/167169', + 'refresh' => 900, + 'checked' => 1389919932, + 'description' => 'Drupal Core Group feed', + ]); + $feed->save(); + + // Create a "Llama" item. + $item = Item::create(); + $item->setTitle('Llama') + ->setFeedId($feed->id()) + ->setLink('https://www.drupal.org/') + ->setPostedTime(123456789) + ->save(); + + return $item; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + $feed = Feed::load($this->entity->getFeedId()); + + return [ + 'iid' => [ + [ + 'value' => 1, + ], + ], + 'langcode' => [ + [ + 'value' => 'en', + ], + ], + 'fid' => [ + [ + 'target_id' => 1, + 'target_type' => 'aggregator_feed', + 'target_uuid' => $feed->uuid(), + 'url' => base_path() . 'aggregator/sources/1', + ], + ], + 'title' => [ + [ + 'value' => 'Llama', + ], + ], + 'link' => [ + [ + 'value' => 'https://www.drupal.org/', + ], + ], + 'author' => [], + 'description' => [], + 'timestamp' => [ + $this->formatExpectedTimestampItemValues(123456789), + ], + 'guid' => [], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return [ + 'fid' => [ + [ + 'target_id' => 1, + ], + ], + 'title' => [ + [ + 'value' => 'Llama', + ], + ], + 'link' => [ + [ + 'value' => 'https://www.drupal.org/', + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + // @see ::createEntity() + return ['user.permissions']; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'access news feeds' permission is required."; + + case 'POST': + case 'PATCH': + case 'DELETE': + return "The 'administer news feeds' permission is required."; + + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaJsonAnonTest.php new file mode 100644 index 00000000..d9a3550d --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Media/MediaJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['view media']); + break; + + case 'POST': + $this->grantPermissionsToTestedRole(['create media']); + break; + + case 'PATCH': + $this->grantPermissionsToTestedRole(['update any media']); + break; + + case 'DELETE': + $this->grantPermissionsToTestedRole(['delete any media']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + if (!MediaType::load('camelids')) { + // Create a "Camelids" media type. + $media_type = MediaType::create([ + 'name' => 'Camelids', + 'id' => 'camelids', + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'source' => 'file', + ]); + $media_type->save(); + // Create the source field. + $source_field = $media_type->getSource()->createSourceField($media_type); + $source_field->getFieldStorageDefinition()->save(); + $source_field->save(); + $media_type + ->set('source_configuration', [ + 'source_field' => $source_field->getName(), + ]) + ->save(); + } + + // Create a file to upload. + $file = File::create([ + 'uri' => 'public://llama.txt', + ]); + $file->setPermanent(); + $file->save(); + + // Create a "Llama" media item. + $media = Media::create([ + 'bundle' => 'camelids', + 'field_media_file_1' => [ + 'target_id' => $file->id(), + ], + ]); + $media + ->setName('Llama') + ->setPublished(TRUE) + ->setCreatedTime(123456789) + ->setOwnerId(static::$auth ? $this->account->id() : 0) + ->setRevisionUserId(static::$auth ? $this->account->id() : 0) + ->save(); + + return $media; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + $file = File::load(1); + $thumbnail = File::load(2); + $author = User::load($this->entity->getOwnerId()); + return [ + 'mid' => [ + [ + 'value' => 1, + ], + ], + 'uuid' => [ + [ + 'value' => $this->entity->uuid(), + ], + ], + 'vid' => [ + [ + 'value' => 1, + ], + ], + 'langcode' => [ + [ + 'value' => 'en', + ], + ], + 'bundle' => [ + [ + 'target_id' => 'camelids', + 'target_type' => 'media_type', + 'target_uuid' => MediaType::load('camelids')->uuid(), + ], + ], + 'name' => [ + [ + 'value' => 'Llama', + ], + ], + 'field_media_file_1' => [ + [ + 'description' => NULL, + 'display' => NULL, + 'target_id' => (int) $file->id(), + 'target_type' => 'file', + 'target_uuid' => $file->uuid(), + 'url' => $file->url(), + ], + ], + 'thumbnail' => [ + [ + 'alt' => 'Thumbnail', + 'width' => 180, + 'height' => 180, + 'target_id' => (int) $thumbnail->id(), + 'target_type' => 'file', + 'target_uuid' => $thumbnail->uuid(), + 'title' => 'Llama', + 'url' => $thumbnail->url(), + ], + ], + 'status' => [ + [ + 'value' => TRUE, + ], + ], + 'created' => [ + $this->formatExpectedTimestampItemValues(123456789), + ], + 'changed' => [ + $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()), + ], + 'revision_created' => [ + $this->formatExpectedTimestampItemValues((int) $this->entity->getRevisionCreationTime()), + ], + 'default_langcode' => [ + [ + 'value' => TRUE, + ], + ], + 'uid' => [ + [ + 'target_id' => (int) $author->id(), + 'target_type' => 'user', + 'target_uuid' => $author->uuid(), + 'url' => base_path() . 'user/' . $author->id(), + ], + ], + 'revision_user' => [ + [ + 'target_id' => (int) $author->id(), + 'target_type' => 'user', + 'target_uuid' => $author->uuid(), + 'url' => base_path() . 'user/' . $author->id(), + ], + ], + 'revision_log_message' => [], + 'revision_translation_affected' => [ + [ + 'value' => TRUE, + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return [ + 'bundle' => [ + [ + 'target_id' => 'camelids', + ], + ], + 'name' => [ + [ + 'value' => 'Dramallama', + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET'; + return "The 'view media' permission is required and the media item must be published."; + + case 'PATCH': + return 'You are not authorized to update this media entity of bundle camelids.'; + + case 'DELETE': + return 'You are not authorized to delete this media entity of bundle camelids.'; + + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + + /** + * {@inheritdoc} + */ + public function testPost() { + $this->markTestSkipped('POSTing File Media items is not supported until https://www.drupal.org/node/1927648 is solved.'); + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/MediaType/MediaTypeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/MediaType/MediaTypeJsonAnonTest.php new file mode 100644 index 00000000..2e4b6309 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/MediaType/MediaTypeJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer media types']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" media type. + $camelids = MediaType::create([ + 'name' => 'Camelids', + 'id' => 'camelids', + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'source' => 'file', + ]); + + $camelids->save(); + + return $camelids; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'field_map' => [], + 'id' => 'camelids', + 'label' => NULL, + 'langcode' => 'en', + 'new_revision' => FALSE, + 'queue_thumbnail_downloads' => FALSE, + 'source' => 'file', + 'source_configuration' => [ + 'source_field' => '', + ], + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Menu/MenuJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Menu/MenuJsonAnonTest.php new file mode 100644 index 00000000..9a83ce9f --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Menu/MenuJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer menu']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $menu = Menu::create([ + 'id' => 'menu', + 'label' => 'Menu', + 'description' => 'Menu', + ]); + $menu->save(); + + return $menu; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'description' => 'Menu', + 'id' => 'menu', + 'label' => 'Menu', + 'langcode' => 'en', + 'locked' => FALSE, + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/MenuLinkContent/MenuLinkContentJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/MenuLinkContent/MenuLinkContentJsonAnonTest.php new file mode 100644 index 00000000..219cc53c --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/MenuLinkContent/MenuLinkContentJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer menu']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $menu_link = MenuLinkContent::create([ + 'id' => 'llama', + 'title' => 'Llama Gabilondo', + 'description' => 'Llama Gabilondo', + 'link' => 'https://nl.wikipedia.org/wiki/Llama', + 'weight' => 0, + 'menu_name' => 'main', + ]); + $menu_link->save(); + + return $menu_link; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return [ + 'title' => [ + [ + 'value' => 'Dramallama', + ], + ], + 'link' => [ + [ + 'uri' => 'http://www.urbandictionary.com/define.php?term=drama%20llama', + ], + ], + 'bundle' => [ + [ + 'value' => 'menu_link_content', + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'uuid' => [ + [ + 'value' => $this->entity->uuid(), + ], + ], + 'id' => [ + [ + 'value' => 1, + ], + ], + 'title' => [ + [ + 'value' => 'Llama Gabilondo', + ], + ], + 'link' => [ + [ + 'uri' => 'https://nl.wikipedia.org/wiki/Llama', + 'title' => NULL, + 'options' => [], + ], + ], + 'weight' => [ + [ + 'value' => 0, + ], + ], + 'menu_name' => [ + [ + 'value' => 'main', + ], + ], + 'langcode' => [ + [ + 'value' => 'en', + ], + ], + 'bundle' => [ + [ + 'value' => 'menu_link_content', + ], + ], + 'description' => [ + [ + 'value' => 'Llama Gabilondo', + ], + ], + 'external' => [ + [ + 'value' => FALSE, + ], + ], + 'rediscover' => [ + [ + 'value' => FALSE, + ], + ], + 'expanded' => [ + [ + 'value' => FALSE, + ], + ], + 'enabled' => [ + [ + 'value' => TRUE, + ], + ], + 'changed' => [ + $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()), + ], + 'default_langcode' => [ + [ + 'value' => TRUE, + ], + ], + 'parent' => [], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'DELETE': + return "You are not authorized to delete this menu_link_content entity."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonAnonTest.php index 24d47c49..47239dba 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonAnonTest.php @@ -21,9 +21,4 @@ class NodeJsonAnonTest extends NodeResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonBasicAuthTest.php index b71d1d57..ff7746d7 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Node; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class NodeJsonBasicAuthTest extends NodeResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonCookieTest.php index f0bd6534..490155e7 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeJsonCookieTest.php @@ -21,11 +21,6 @@ class NodeJsonCookieTest extends NodeResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php index d7651c4b..492ff642 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php @@ -4,15 +4,19 @@ use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; +use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait; use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; use Drupal\user\Entity\User; +use GuzzleHttp\RequestOptions; abstract class NodeResourceTestBase extends EntityResourceTestBase { + use BcTimestampNormalizerUnixTestTrait; + /** * {@inheritdoc} */ - public static $modules = ['node']; + public static $modules = ['node', 'path']; /** * {@inheritdoc} @@ -23,13 +27,13 @@ abstract class NodeResourceTestBase extends EntityResourceTestBase { * {@inheritdoc} */ protected static $patchProtectedFieldNames = [ - 'uid', + 'revision_timestamp', + 'revision_uid', 'created', 'changed', 'promote', 'sticky', - 'revision_timestamp', - 'revision_uid', + 'path', ]; /** @@ -49,6 +53,10 @@ protected function setUpAuthorization($method) { $this->grantPermissionsToTestedRole(['access content', 'create camelids content']); break; case 'PATCH': + // Do not grant the 'create url aliases' permission to test the case + // when the path field is protected/not accessible, see + // \Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase + // for a positive test. $this->grantPermissionsToTestedRole(['access content', 'edit any camelids content']); break; case 'DELETE': @@ -77,6 +85,7 @@ protected function createEntity() { ->setCreatedTime(123456789) ->setChangedTime(123456789) ->setRevisionCreationTime(123456789) + ->set('path', '/llama') ->save(); return $node; @@ -116,33 +125,27 @@ protected function getExpectedNormalizedEntity() { ], 'status' => [ [ - 'value' => 1, + 'value' => TRUE, ], ], 'created' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues(123456789), ], 'changed' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()), ], 'promote' => [ [ - 'value' => 1, + 'value' => TRUE, ], ], 'sticky' => [ [ - 'value' => '0', + 'value' => FALSE, ], ], 'revision_timestamp' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues(123456789), ], 'revision_translation_affected' => [ [ @@ -156,7 +159,7 @@ protected function getExpectedNormalizedEntity() { ], 'uid' => [ [ - 'target_id' => $author->id(), + 'target_id' => (int) $author->id(), 'target_type' => 'user', 'target_uuid' => $author->uuid(), 'url' => base_path() . 'user/' . $author->id(), @@ -164,13 +167,19 @@ protected function getExpectedNormalizedEntity() { ], 'revision_uid' => [ [ - 'target_id' => $author->id(), + 'target_id' => (int) $author->id(), 'target_type' => 'user', 'target_uuid' => $author->uuid(), 'url' => base_path() . 'user/' . $author->id(), ], ], - 'revision_log' => [ + 'revision_log' => [], + 'path' => [ + [ + 'alias' => '/llama', + 'pid' => 1, + 'langcode' => 'en', + ], ], ]; } @@ -193,4 +202,74 @@ protected function getNormalizedPostEntity() { ]; } + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + if ($method === 'GET' || $method == 'PATCH' || $method == 'DELETE') { + return "The 'access content' permission is required."; + } + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + /** + * Tests PATCHing a node's path with and without 'create url aliases'. + * + * For a positive test, see the similar test coverage for Term. + * + * @see \Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase::testPatchPath() + */ + public function testPatchPath() { + $this->initAuthentication(); + $this->provisionEntityResource(); + $this->setUpAuthorization('GET'); + $this->setUpAuthorization('PATCH'); + + $url = $this->getEntityResourceUrl()->setOption('query', ['_format' => static::$format]); + + // GET node's current normalization. + $response = $this->request('GET', $url, $this->getAuthenticationRequestOptions('GET')); + $normalization = $this->serializer->decode((string) $response->getBody(), static::$format); + + // @todo In https://www.drupal.org/node/2824851, we will be able to stop + // unsetting these fields from the normalization, because + // EntityResource::patch() will ignore any fields that are sent that + // match the current value (and obviously we're sending the current + // value). + $normalization = $this->removeFieldsFromNormalization($normalization, [ + 'revision_timestamp', + 'revision_uid', + 'created', + 'changed', + 'promote', + 'sticky', + ]); + + // Change node's path alias. + $normalization['path'][0]['alias'] .= 's-rule-the-world'; + + // Create node PATCH request. + $request_options = []; + $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType; + $request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH')); + $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); + + // PATCH request: 403 when creating URL aliases unauthorized. + $response = $this->request('PATCH', $url, $request_options); + $this->assertResourceErrorResponse(403, "Access denied on updating field 'path'.", $response); + + // Grant permission to create URL aliases. + $this->grantPermissionsToTestedRole(['create url aliases']); + + // Repeat PATCH request: 200. + $response = $this->request('PATCH', $url, $request_options); + $this->assertResourceResponse(200, FALSE, $response); + $updated_normalization = $this->serializer->decode((string) $response->getBody(), static::$format); + $this->assertSame($normalization['path'], $updated_normalization['path']); + } + } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/NodeType/NodeTypeJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/NodeType/NodeTypeJsonAnonTest.php new file mode 100644 index 00000000..7050ff1e --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/NodeType/NodeTypeJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer content types', 'access content']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" node type. + $camelids = NodeType::create([ + 'name' => 'Camelids', + 'type' => 'camelids', + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + ]); + + $camelids->save(); + + return $camelids; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'description' => 'Camelids are large, strictly herbivorous animals with slender necks and long legs.', + 'display_submitted' => TRUE, + 'help' => NULL, + 'langcode' => 'en', + 'name' => 'Camelids', + 'new_revision' => TRUE, + 'preview_mode' => 1, + 'status' => TRUE, + 'type' => 'camelids', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'access content' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/RdfMapping/RdfMappingJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/RdfMapping/RdfMappingJsonAnonTest.php new file mode 100644 index 00000000..d1d89ae6 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/RdfMapping/RdfMappingJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer site configuration']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" node type. + $camelids = NodeType::create([ + 'name' => 'Camelids', + 'type' => 'camelids', + ]); + + $camelids->save(); + + // Create the RDF mapping. + $llama = RdfMapping::create([ + 'targetEntityType' => 'node', + 'bundle' => 'camelids', + ]); + $llama->setBundleMapping([ + 'types' => ['sioc:Item', 'foaf:Document'], + ]) + ->setFieldMapping('title', [ + 'properties' => ['dc:title'], + ]) + ->setFieldMapping('created', [ + 'properties' => ['dc:date', 'dc:created'], + 'datatype' => 'xsd:dateTime', + 'datatype_callback' => ['callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value'], + ]) + ->save(); + + return $llama; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'bundle' => 'camelids', + 'dependencies' => [ + 'config' => [ + 'node.type.camelids', + ], + 'module' => [ + 'node', + ], + ], + 'fieldMappings' => [ + 'title' => [ + 'properties' => [ + 'dc:title', + ], + ], + 'created' => [ + 'properties' => [ + 'dc:date', + 'dc:created', + ], + 'datatype' => 'xsd:dateTime', + 'datatype_callback' => [ + 'callable' => 'Drupal\rdf\CommonDataConverter::dateIso8601Value', + ], + ], + ], + 'id' => 'node.camelids', + 'langcode' => 'en', + 'status' => TRUE, + 'targetEntityType' => 'node', + 'types' => [ + 'sioc:Item', + 'foaf:Document', + ], + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ResponsiveImageStyle/ResponsiveImageStyleJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ResponsiveImageStyle/ResponsiveImageStyleJsonAnonTest.php new file mode 100644 index 00000000..7aafd1f1 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/ResponsiveImageStyle/ResponsiveImageStyleJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer responsive images']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create a "Camelids" responsive image style. + $camelids = ResponsiveImageStyle::create([ + 'id' => 'camelids', + 'label' => 'Camelids', + ]); + $camelids->setBreakpointGroup('test_group'); + $camelids->setFallbackImageStyle('fallback'); + $camelids->addImageStyleMapping('test_breakpoint', '1x', [ + 'image_mapping_type' => 'image_style', + 'image_mapping' => 'small', + ]); + $camelids->addImageStyleMapping('test_breakpoint', '2x', [ + 'image_mapping_type' => 'sizes', + 'image_mapping' => [ + 'sizes' => '(min-width:700px) 700px, 100vw', + 'sizes_image_styles' => [ + 'medium' => 'medium', + 'large' => 'large', + ], + ], + ]); + $camelids->save(); + + return $camelids; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'breakpoint_group' => 'test_group', + 'dependencies' => [ + 'config' => [ + 'image.style.large', + 'image.style.medium', + ], + ], + 'fallback_image_style' => 'fallback', + 'id' => 'camelids', + 'image_style_mappings' => [ + 0 => [ + 'breakpoint_id' => 'test_breakpoint', + 'image_mapping' => 'small', + 'image_mapping_type' => 'image_style', + 'multiplier' => '1x', + ], + 1 => [ + 'breakpoint_id' => 'test_breakpoint', + 'image_mapping' => [ + 'sizes' => '(min-width:700px) 700px, 100vw', + 'sizes_image_styles' => [ + 'large' => 'large', + 'medium' => 'medium', + ], + ], + 'image_mapping_type' => 'sizes', + 'multiplier' => '2x', + ], + ], + 'label' => 'Camelids', + 'langcode' => 'en', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The 'administer responsive images' permission is required."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/RestResourceConfig/RestResourceConfigJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/RestResourceConfig/RestResourceConfigJsonAnonTest.php new file mode 100644 index 00000000..df071409 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/RestResourceConfig/RestResourceConfigJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer rest resources']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $rest_resource_config = RestResourceConfig::create([ + 'id' => 'llama', + 'plugin_id' => 'dblog', + 'granularity' => 'method', + 'configuration' => [ + 'GET' => [ + 'supported_formats' => [ + 'json', + ], + 'supported_auth' => [ + 'cookie', + ], + ], + ], + ]); + $rest_resource_config->save(); + + return $rest_resource_config; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'uuid' => $this->entity->uuid(), + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => [ + 'module' => [ + 'dblog', + 'serialization', + 'user', + ], + ], + 'id' => 'llama', + 'plugin_id' => 'dblog', + 'granularity' => 'method', + 'configuration' => [ + 'GET' => [ + 'supported_formats' => [ + 'json', + ], + 'supported_auth' => [ + 'cookie', + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonAnonTest.php index 3ec96eb7..eb0b05fb 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonAnonTest.php @@ -21,9 +21,4 @@ class RoleJsonAnonTest extends RoleResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonBasicAuthTest.php index 75fcd080..267a3b89 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Role; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Psr\Http\Message\ResponseInterface; /** * @group rest @@ -27,22 +26,9 @@ class RoleJsonBasicAuthTest extends RoleResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - /** - * {@inheritdoc} - */ - protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) { - $this->assertSame(401, $response->getStatusCode()); - $this->assertSame('{"message":"A fatal error occurred: No authentication credentials provided."}', (string) $response->getBody()); - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonCookieTest.php index 9f4ec073..87403168 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Role/RoleJsonCookieTest.php @@ -21,11 +21,6 @@ class RoleJsonCookieTest extends RoleResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/SearchPage/SearchPageJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/SearchPage/SearchPageJsonAnonTest.php new file mode 100644 index 00000000..a3aff54e --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/SearchPage/SearchPageJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access content']); + break; + + case 'POST': + case 'PATCH': + case 'DELETE': + $this->grantPermissionsToTestedRole(['administer search']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $search_page = SearchPage::create([ + 'id' => 'hinode_search', + 'plugin' => 'node_search', + 'label' => 'Search of magnetic activity of the Sun', + 'path' => 'sun', + ]); + $search_page->save(); + return $search_page; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'configuration' => [ + 'rankings' => [], + ], + 'dependencies' => [ + 'module' => ['node'], + ], + 'id' => 'hinode_search', + 'label' => 'Search of magnetic activity of the Sun', + 'langcode' => 'en', + 'path' => 'sun', + 'plugin' => 'node_search', + 'status' => TRUE, + 'uuid' => $this->entity->uuid(), + 'weight' => 0, + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'access content' permission is required."; + + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonAnonTest.php new file mode 100644 index 00000000..8f317b3c --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access shortcuts', 'customize shortcut links']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + // Create shortcut. + $shortcut = Shortcut::create([ + 'shortcut_set' => 'default', + 'title' => t('Comments'), + 'weight' => -20, + 'link' => [ + 'uri' => 'internal:/admin/content/comment', + ], + ]); + $shortcut->save(); + + return $shortcut; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'uuid' => [ + [ + 'value' => $this->entity->uuid(), + ], + ], + 'id' => [ + [ + 'value' => (int) $this->entity->id(), + ], + ], + 'title' => [ + [ + 'value' => 'Comments', + ], + ], + 'shortcut_set' => [ + [ + 'target_id' => 'default', + 'target_type' => 'shortcut_set', + 'target_uuid' => ShortcutSet::load('default')->uuid(), + ], + ], + 'link' => [ + [ + 'uri' => 'internal:/admin/content/comment', + 'title' => NULL, + 'options' => [], + ], + ], + 'weight' => [ + [ + 'value' => -20, + ], + ], + 'langcode' => [ + [ + 'value' => 'en', + ], + ], + 'default_langcode' => [ + [ + 'value' => TRUE, + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return [ + 'title' => [ + [ + 'value' => 'Comments', + ], + ], + 'link' => [ + [ + 'uri' => 'internal:/', + ], + ], + 'shortcut_set' => [ + [ + 'target_id' => 'default', + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + case 'POST': + case 'PATCH': + case 'DELETE': + return "The shortcut set must be the currently displayed set for the user and the user must have 'access shortcuts' AND 'customize shortcut links' permissions."; + + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonAnonTest.php new file mode 100644 index 00000000..3720ac60 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access shortcuts']); + break; + + case 'POST': + case 'PATCH': + $this->grantPermissionsToTestedRole(['access shortcuts', 'customize shortcut links']); + break; + + case 'DELETE': + $this->grantPermissionsToTestedRole(['administer shortcuts']); + break; + } + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $set = ShortcutSet::create([ + 'id' => 'llama_set', + 'label' => 'Llama Set', + ]); + $set->save(); + return $set; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'id' => 'llama_set', + 'uuid' => $this->entity->uuid(), + 'label' => 'Llama Set', + 'status' => TRUE, + 'langcode' => 'en', + 'dependencies' => [], + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonAnonTest.php index 6e01c031..90a85e72 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonAnonTest.php @@ -21,9 +21,4 @@ class TermJsonAnonTest extends TermResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonBasicAuthTest.php index 6befa3a9..97df5c84 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Term; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class TermJsonBasicAuthTest extends TermResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonCookieTest.php index 6268a747..ccf066b7 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermJsonCookieTest.php @@ -21,11 +21,6 @@ class TermJsonCookieTest extends TermResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php index b6dce4f4..7b9ee5cd 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php @@ -4,14 +4,18 @@ use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; +use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait; use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; +use GuzzleHttp\RequestOptions; abstract class TermResourceTestBase extends EntityResourceTestBase { + use BcTimestampNormalizerUnixTestTrait; + /** * {@inheritdoc} */ - public static $modules = ['taxonomy']; + public static $modules = ['taxonomy', 'path']; /** * {@inheritdoc} @@ -41,8 +45,12 @@ protected function setUpAuthorization($method) { case 'POST': case 'PATCH': case 'DELETE': + // Grant the 'create url aliases' permission to test the case when + // the path field is accessible, see + // \Drupal\Tests\rest\Functional\EntityResource\Node\NodeResourceTestBase + // for a negative test. // @todo Update once https://www.drupal.org/node/2824408 lands. - $this->grantPermissionsToTestedRole(['administer taxonomy']); + $this->grantPermissionsToTestedRole(['administer taxonomy', 'create url aliases']); break; } } @@ -64,7 +72,8 @@ protected function createEntity() { // Create a "Llama" taxonomy term. $term = Term::create(['vid' => $vocabulary->id()]) ->setName('Llama') - ->setChangedTime(123456789); + ->setChangedTime(123456789) + ->set('path', '/llama'); $term->save(); return $term; @@ -107,15 +116,20 @@ protected function getExpectedNormalizedEntity() { ], ], 'changed' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()), ], 'default_langcode' => [ [ 'value' => TRUE, ], ], + 'path' => [ + [ + 'alias' => '/llama', + 'pid' => 1, + 'langcode' => 'en', + ], + ], ]; } @@ -134,7 +148,79 @@ protected function getNormalizedPostEntity() { 'value' => 'Dramallama', ], ], + 'description' => [ + [ + 'value' => 'Dramallamas are the coolest camelids.', + 'format' => NULL, + ], + ], ]; } + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'access content' permission is required."; + case 'POST': + return "The 'administer taxonomy' permission is required."; + case 'PATCH': + return "The following permissions are required: 'edit terms in camelids' OR 'administer taxonomy'."; + case 'DELETE': + return "The following permissions are required: 'delete terms in camelids' OR 'administer taxonomy'."; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + + /** + * Tests PATCHing a term's path. + * + * For a negative test, see the similar test coverage for Node. + * + * @see \Drupal\Tests\rest\Functional\EntityResource\Node\NodeResourceTestBase::testPatchPath() + */ + public function testPatchPath() { + $this->initAuthentication(); + $this->provisionEntityResource(); + $this->setUpAuthorization('GET'); + $this->setUpAuthorization('PATCH'); + + $url = $this->getEntityResourceUrl()->setOption('query', ['_format' => static::$format]); + + // GET term's current normalization. + $response = $this->request('GET', $url, $this->getAuthenticationRequestOptions('GET')); + $normalization = $this->serializer->decode((string) $response->getBody(), static::$format); + + // @todo In https://www.drupal.org/node/2824851, we will be able to stop + // unsetting these fields from the normalization, because + // EntityResource::patch() will ignore any fields that are sent that + // match the current value (and obviously we're sending the current + // value). + $normalization = $this->removeFieldsFromNormalization($normalization, [ + 'changed', + ]); + + // Change term's path alias. + $normalization['path'][0]['alias'] .= 's-rule-the-world'; + + // Create term PATCH request. + $request_options = []; + $request_options[RequestOptions::HEADERS]['Content-Type'] = static::$mimeType; + $request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH')); + $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); + + // PATCH request: 200. + $response = $this->request('PATCH', $url, $request_options); + $this->assertResourceResponse(200, FALSE, $response); + $updated_normalization = $this->serializer->decode((string) $response->getBody(), static::$format); + $this->assertSame($normalization['path'], $updated_normalization['path']); + } + } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Tour/TourJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Tour/TourJsonAnonTest.php new file mode 100644 index 00000000..0551a0b6 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Tour/TourJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['access tour']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $tour = Tour::create([ + 'id' => 'tour-llama', + 'label' => 'Llama tour', + 'langcode' => 'en', + 'module' => 'tour', + 'routes' => [ + [ + 'route_name' => '', + ], + ], + 'tips' => [ + 'tour-llama-1' => [ + 'id' => 'tour-llama-1', + 'plugin' => 'text', + 'label' => 'Llama', + 'body' => 'Who handle the awesomeness of llamas?', + 'weight' => 100, + 'attributes' => [ + 'data-id' => 'tour-llama-1', + ], + ], + ], + ]); + $tour->save(); + + return $tour; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'dependencies' => [], + 'id' => 'tour-llama', + 'label' => 'Llama tour', + 'langcode' => 'en', + 'module' => 'tour', + 'routes' => [ + [ + 'route_name' => '', + ], + ], + 'status' => TRUE, + 'tips' => [ + 'tour-llama-1' => [ + 'id' => 'tour-llama-1', + 'plugin' => 'text', + 'label' => 'Llama', + 'body' => 'Who handle the awesomeness of llamas?', + 'weight' => 100, + 'attributes' => [ + 'data-id' => 'tour-llama-1', + ], + ], + ], + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + return "The following permissions are required: 'access tour' OR 'administer site configuration'."; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonAnonTest.php index a20aff83..176f3be1 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonAnonTest.php @@ -21,9 +21,4 @@ class UserJsonAnonTest extends UserResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonBasicAuthTest.php index f67e0a67..ea6ddea2 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\User; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class UserJsonBasicAuthTest extends UserResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonCookieTest.php index 12ee0c91..9fae07d8 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/User/UserJsonCookieTest.php @@ -21,11 +21,6 @@ class UserJsonCookieTest extends UserResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/EntityResource/User/UserResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/User/UserResourceTestBase.php index 31cf083a..caf29097 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/User/UserResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/User/UserResourceTestBase.php @@ -3,12 +3,15 @@ namespace Drupal\Tests\rest\Functional\EntityResource\User; use Drupal\Core\Url; +use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait; use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase; use Drupal\user\Entity\User; use GuzzleHttp\RequestOptions; abstract class UserResourceTestBase extends EntityResourceTestBase { + use BcTimestampNormalizerUnixTestTrait; + /** * {@inheritdoc} */ @@ -82,7 +85,7 @@ protected function createEntity() { protected function getExpectedNormalizedEntity() { return [ 'uid' => [ - ['value' => '3'], + ['value' => 3], ], 'uuid' => [ ['value' => $this->entity->uuid()], @@ -98,14 +101,10 @@ protected function getExpectedNormalizedEntity() { ], ], 'created' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues(123456789), ], 'changed' => [ - [ - 'value' => '123456789', - ], + $this->formatExpectedTimestampItemValues($this->entity->getChangedTime()), ], 'default_langcode' => [ [ @@ -122,7 +121,7 @@ protected function getNormalizedPostEntity() { return [ 'name' => [ [ - 'value' => 'Dramallama ' . $this->randomMachineName(), + 'value' => 'Dramallama', ], ], ]; @@ -139,11 +138,11 @@ public function testPatchDxForSecuritySensitiveBaseFields() { $this->initAuthentication(); $this->provisionEntityResource(); - $this->setUpAuthorization('PATCH'); /** @var \Drupal\user\UserInterface $user */ $user = static::$auth ? $this->account : User::load(0); - $original_normalization = array_diff_key($this->serializer->normalize($user, static::$format), ['changed' => TRUE]); + // @todo Remove the array_diff_key() call in https://www.drupal.org/node/2821077. + $original_normalization = array_diff_key($this->serializer->normalize($user, static::$format), ['created' => TRUE, 'changed' => TRUE, 'name' => TRUE]); // Since this test must be performed by the user that is being modified, @@ -163,11 +162,7 @@ public function testPatchDxForSecuritySensitiveBaseFields() { // DX: 422 when changing email without providing the password. $response = $this->request('PATCH', $url, $request_options); - // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813755 lands. - // $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response); - $this->assertSame(422, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n"], static::$format), (string) $response->getBody()); + $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response); $normalization['pass'] = [['existing' => 'wrong']]; @@ -175,11 +170,7 @@ public function testPatchDxForSecuritySensitiveBaseFields() { // DX: 422 when changing email while providing a wrong password. $response = $this->request('PATCH', $url, $request_options); - // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813755 lands. - // $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response); - $this->assertSame(422, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n"], static::$format), (string) $response->getBody()); + $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nmail: Your current password is missing or incorrect; it's required to change the Email.\n", $response); $normalization['pass'] = [['existing' => $this->account->passRaw]]; @@ -200,11 +191,7 @@ public function testPatchDxForSecuritySensitiveBaseFields() { // DX: 422 when changing password without providing the current password. $response = $this->request('PATCH', $url, $request_options); - // @todo use this commented line instead of the 3 lines thereafter once https://www.drupal.org/node/2813755 lands. - // $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\npass: Your current password is missing or incorrect; it's required to change the Password.\n", $response); - $this->assertSame(422, $response->getStatusCode()); - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - $this->assertSame($this->serializer->encode(['message' => "Unprocessable Entity: validation failed.\npass: Your current password is missing or incorrect; it's required to change the Password.\n"], static::$format), (string) $response->getBody()); + $this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\npass: Your current password is missing or incorrect; it's required to change the Password.\n", $response); $normalization['pass'][0]['existing'] = $this->account->pass_raw; @@ -217,16 +204,79 @@ public function testPatchDxForSecuritySensitiveBaseFields() { // Verify that we can log in with the new password. + $this->assertRpcLogin($user->getAccountName(), $new_password); + + + // Update password in $this->account, prepare for future requests. + $this->account->passRaw = $new_password; + $this->initAuthentication(); + $request_options = [ + RequestOptions::HEADERS => ['Content-Type' => static::$mimeType], + ]; + $request_options = array_merge_recursive($request_options, $this->getAuthenticationRequestOptions('PATCH')); + + + // Test case 3: changing name. + $normalization = $original_normalization; + $normalization['name'] = [['value' => 'Cooler Llama']]; + $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); + + + // DX: 403 when modifying username without required permission. + $response = $this->request('PATCH', $url, $request_options); + $this->assertResourceErrorResponse(403, "Access denied on updating field 'name'.", $response); + + + $this->grantPermissionsToTestedRole(['change own username']); + + + // 200 for well-formed request. + $response = $this->request('PATCH', $url, $request_options); + $this->assertResourceResponse(200, FALSE, $response); + + // Verify that we can log in with the new username. + $this->assertRpcLogin('Cooler Llama', $new_password); + } + + /** + * Verifies that logging in with the given username and password works. + * + * @param string $username + * The username to log in with. + * @param string $password + * The password to log in with. + */ + protected function assertRpcLogin($username, $password) { $request_body = [ - 'name' => $user->getAccountName(), - 'pass' => $new_password, + 'name' => $username, + 'pass' => $password, ]; $request_options = [ RequestOptions::HEADERS => [], RequestOptions::BODY => $this->serializer->encode($request_body, 'json'), ]; - $response = $this->httpClient->request('POST', Url::fromRoute('user.login.http')->setRouteParameter('_format', 'json')->toString(), $request_options); + $response = $this->request('POST', Url::fromRoute('user.login.http')->setRouteParameter('_format', 'json'), $request_options); $this->assertSame(200, $response->getStatusCode()); } + /** + * {@inheritdoc} + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) { + return parent::getExpectedUnauthorizedAccessMessage($method); + } + + switch ($method) { + case 'GET': + return "The 'access user profiles' permission is required and the user must be active."; + case 'PATCH': + return "You are not authorized to update this user entity."; + case 'DELETE': + return 'You are not authorized to delete this user entity.'; + default: + return parent::getExpectedUnauthorizedAccessMessage($method); + } + } + } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/View/ViewJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/View/ViewJsonAnonTest.php new file mode 100644 index 00000000..3cfd4b14 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/View/ViewJsonAnonTest.php @@ -0,0 +1,24 @@ +grantPermissionsToTestedRole(['administer views']); + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + $view = View::create([ + 'id' => 'test_rest', + 'label' => 'Test REST', + ]); + $view->save(); + return $view; + } + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + return [ + 'base_field' => 'nid', + 'base_table' => 'node', + 'core' => '8.x', + 'dependencies' => [], + 'description' => '', + 'display' => [ + 'default' => [ + 'display_plugin' => 'default', + 'id' => 'default', + 'display_title' => 'Master', + 'position' => 0, + 'display_options' => [ + 'display_extenders' => [], + ], + 'cache_metadata' => [ + 'max-age' => -1, + 'contexts' => [ + 'languages:language_interface', + 'url.query_args', + ], + 'tags' => [], + ], + ], + ], + 'id' => 'test_rest', + 'label' => 'Test REST', + 'langcode' => 'en', + 'module' => 'views', + 'status' => TRUE, + 'tag' => '', + 'uuid' => $this->entity->uuid(), + ]; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + // @todo Update in https://www.drupal.org/node/2300677. + } + + /** + * {@inheritdoc} + */ + protected function getExpectedCacheContexts() { + return [ + 'user.permissions', + ]; + } + +} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonAnonTest.php index 4e291069..40f26ab7 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonAnonTest.php @@ -21,11 +21,6 @@ class VocabularyJsonAnonTest extends VocabularyResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * Disable the GET test coverage due to bug in taxonomy module. * @todo Fix in https://www.drupal.org/node/2805281: remove this override. diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonBasicAuthTest.php index 10600500..492a8add 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonBasicAuthTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonBasicAuthTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Vocabulary; use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; -use Drupal\Tests\rest\Functional\JsonBasicAuthWorkaroundFor2805281Trait; /** * @group rest @@ -27,19 +26,9 @@ class VocabularyJsonBasicAuthTest extends VocabularyResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ protected static $auth = 'basic_auth'; - // @todo Fix in https://www.drupal.org/node/2805281: remove this trait usage. - use JsonBasicAuthWorkaroundFor2805281Trait { - JsonBasicAuthWorkaroundFor2805281Trait::assertResponseWhenMissingAuthentication insteadof BasicAuthResourceTestTrait; - } - } diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonCookieTest.php index f8939c68..db8b6571 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonCookieTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Vocabulary/VocabularyJsonCookieTest.php @@ -21,11 +21,6 @@ class VocabularyJsonCookieTest extends VocabularyResourceTestBase { */ protected static $mimeType = 'application/json'; - /** - * {@inheritdoc} - */ - protected static $expectedErrorMimeType = 'application/json'; - /** * {@inheritdoc} */ diff --git a/core/modules/rest/tests/src/Functional/JsonBasicAuthWorkaroundFor2805281Trait.php b/core/modules/rest/tests/src/Functional/JsonBasicAuthWorkaroundFor2805281Trait.php deleted file mode 100644 index 495bf5ae..00000000 --- a/core/modules/rest/tests/src/Functional/JsonBasicAuthWorkaroundFor2805281Trait.php +++ /dev/null @@ -1,25 +0,0 @@ -assertSame(401, $response->getStatusCode()); - $this->assertSame([static::$expectedErrorMimeType], $response->getHeader('Content-Type')); - // Note that strange 'A fatal error occurred: ' prefix, that should not - // exist. - // @todo Fix in https://www.drupal.org/node/2805281. - $this->assertSame('{"message":"A fatal error occurred: No authentication credentials provided."}', (string) $response->getBody()); - } - -} diff --git a/core/modules/rest/tests/src/Functional/ResourceTest.php b/core/modules/rest/tests/src/Functional/ResourceTest.php new file mode 100644 index 00000000..1e8babe0 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/ResourceTest.php @@ -0,0 +1,160 @@ +entity = EntityTest::create([ + 'name' => $this->randomMachineName(), + 'user_id' => 1, + 'field_test_text' => [ + 0 => [ + 'value' => $this->randomString(), + 'format' => 'plain_text', + ], + ], + ]); + $this->entity->save(); + + Role::load(AccountInterface::ANONYMOUS_ROLE) + ->grantPermission('view test entity') + ->save(); + } + + /** + * Tests that a resource without formats cannot be enabled. + */ + public function testFormats() { + RestResourceConfig::create([ + 'id' => 'entity.entity_test', + 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY, + 'configuration' => [ + 'GET' => [ + 'supported_auth' => [ + 'basic_auth', + ], + ], + ], + ])->save(); + + // Verify that accessing the resource returns 406. + $this->drupalGet($this->entity->urlInfo()->setRouteParameter('_format', 'hal_json')); + // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical, + // non-REST route a match, but a lower quality one: no format restrictions + // means there's always a match and hence when there is no matching REST + // route, the non-REST route is used, but can't render into + // application/hal+json, so it returns a 406. + $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.'); + } + + /** + * Tests that a resource without authentication cannot be enabled. + */ + public function testAuthentication() { + RestResourceConfig::create([ + 'id' => 'entity.entity_test', + 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY, + 'configuration' => [ + 'GET' => [ + 'supported_formats' => [ + 'hal_json', + ], + ], + ], + ])->save(); + + // Verify that accessing the resource returns 401. + $this->drupalGet($this->entity->urlInfo()->setRouteParameter('_format', 'hal_json')); + // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical, + // non-REST route a match, but a lower quality one: no format restrictions + // means there's always a match and hence when there is no matching REST + // route, the non-REST route is used, but can't render into + // application/hal+json, so it returns a 406. + $this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.'); + } + + /** + * Tests that serialization_class is optional. + */ + public function testSerializationClassIsOptional() { + RestResourceConfig::create([ + 'id' => 'serialization_test', + 'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY, + 'configuration' => [ + 'POST' => [ + 'supported_formats' => [ + 'json', + ], + 'supported_auth' => [ + 'cookie', + ] + ], + ], + ])->save(); + \Drupal::service('router.builder')->rebuildIfNeeded(); + + Role::load(RoleInterface::ANONYMOUS_ID) + ->grantPermission('restful post serialization_test') + ->save(); + + $serialized = $this->container->get('serializer')->serialize(['foo', 'bar'], 'json'); + $request_options = [ + RequestOptions::HEADERS => ['Content-Type' => 'application/json'], + RequestOptions::BODY => $serialized, + ]; + /** @var \GuzzleHttp\ClientInterface $client */ + $client = $this->getSession()->getDriver()->getClient()->getClient(); + $response = $client->request('POST', $this->buildUrl('serialization_test', ['query' => ['_format' => 'json']]), $request_options); + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('["foo","bar"]', (string) $response->getBody()); + } + + /** + * Tests that resource URI paths are formatted properly. + */ + public function testUriPaths() { + /** @var \Drupal\rest\Plugin\Type\ResourcePluginManager $manager */ + $manager = \Drupal::service('plugin.manager.rest'); + + foreach ($manager->getDefinitions() as $resource => $definition) { + foreach ($definition['uri_paths'] as $key => $uri_path) { + $this->assertFalse(strpos($uri_path, '//'), 'The resource URI path does not have duplicate slashes.'); + } + } + } + +} diff --git a/core/modules/rest/tests/src/Functional/ResourceTestBase.php b/core/modules/rest/tests/src/Functional/ResourceTestBase.php index f1f0458d..0a0e34c3 100644 --- a/core/modules/rest/tests/src/Functional/ResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/ResourceTestBase.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\rest\Functional; +use Behat\Mink\Driver\BrowserKitDriver; use Drupal\Core\Url; use Drupal\rest\RestResourceConfigInterface; use Drupal\Tests\BrowserTestBase; @@ -47,24 +48,24 @@ abstract class ResourceTestBase extends BrowserTestBase { protected static $mimeType = 'application/json'; /** - * The expected MIME type in case of 4xx error responses. + * The authentication mechanism to use in this test. * - * (Can be different, when $mimeType for example encodes a particular - * normalization, such as 'application/hal+json': its error response MIME - * type is 'application/json'.) + * (The default is 'cookie' because that doesn't depend on any module.) * * @var string */ - protected static $expectedErrorMimeType = 'application/json'; + protected static $auth = FALSE; /** - * The authentication mechanism to use in this test. + * The REST Resource Config entity ID under test (i.e. a resource type). * - * (The default is 'cookie' because that doesn't depend on any module.) + * The REST Resource plugin ID can be calculated from this. * * @var string + * + * @see \Drupal\rest\Entity\RestResourceConfig::__construct() */ - protected static $auth = FALSE; + protected static $resourceConfigId = NULL; /** * The account to use for authentication, if any. @@ -100,6 +101,8 @@ abstract class ResourceTestBase extends BrowserTestBase { public function setUp() { parent::setUp(); + $this->serializer = $this->container->get('serializer'); + // Ensure the anonymous user role has no permissions at all. $user_role = Role::load(RoleInterface::ANONYMOUS_ID); foreach ($user_role->getPermissions() as $permission) { @@ -130,30 +133,62 @@ public function setUp() { // Ensure there's a clean slate: delete all REST resource config entities. $this->resourceConfigStorage->delete($this->resourceConfigStorage->loadMultiple()); + $this->refreshTestStateAfterRestConfigChange(); } /** - * Provisions a REST resource. + * Provisions the REST resource under test. * - * @param string $resource_type - * The resource type (REST resource plugin ID). * @param string[] $formats * The allowed formats for this resource. * @param string[] $authentication * The allowed authentication providers for this resource. */ - protected function provisionResource($resource_type, $formats = [], $authentication = []) { + protected function provisionResource($formats = [], $authentication = []) { $this->resourceConfigStorage->create([ - 'id' => $resource_type, + 'id' => static::$resourceConfigId, 'granularity' => RestResourceConfigInterface::RESOURCE_GRANULARITY, 'configuration' => [ 'methods' => ['GET', 'POST', 'PATCH', 'DELETE'], 'formats' => $formats, 'authentication' => $authentication, - ] + ], + 'status' => TRUE, ])->save(); - // @todo Remove this in https://www.drupal.org/node/2815845. - drupal_flush_all_caches(); + $this->refreshTestStateAfterRestConfigChange(); + } + + /** + * Refreshes the state of the tester to be in sync with the testee. + * + * Should be called after every change made to: + * - RestResourceConfig entities + * - the 'rest.settings' simple configuration + */ + protected function refreshTestStateAfterRestConfigChange() { + // Ensure that the cache tags invalidator has its internal values reset. + // Otherwise the http_response cache tag invalidation won't work. + $this->refreshVariables(); + + // Tests using this base class may trigger route rebuilds due to changes to + // RestResourceConfig entities or 'rest.settings'. Ensure the test generates + // routes using an up-to-date router. + \Drupal::service('router.builder')->rebuildIfNeeded(); + } + + /** + * Return the expected error message. + * + * @param string $method + * The HTTP method (GET, POST, PATCH, DELETE). + * + * @return string + * The error string. + */ + protected function getExpectedUnauthorizedAccessMessage($method) { + $resource_plugin_id = str_replace('.', ':', static::$resourceConfigId); + $permission = 'restful ' . strtolower($method) . ' ' . $resource_plugin_id; + return "The '$permission' permission is required."; } /** @@ -282,6 +317,9 @@ protected function grantPermissionsToTestedRole(array $permissions) { * 'http_errors = FALSE' request option, nor do we want them to have to * convert Drupal Url objects to strings. * + * We also don't want to follow redirects automatically, to ensure these tests + * are able to detect when redirects are added or removed. + * * @see \GuzzleHttp\ClientInterface::request() * * @param string $method @@ -295,16 +333,15 @@ protected function grantPermissionsToTestedRole(array $permissions) { */ protected function request($method, Url $url, array $request_options) { $request_options[RequestOptions::HTTP_ERRORS] = FALSE; - return $this->httpClient->request($method, $url->toString(), $request_options); + $request_options[RequestOptions::ALLOW_REDIRECTS] = FALSE; + $request_options = $this->decorateWithXdebugCookie($request_options); + $client = $this->getSession()->getDriver()->getClient()->getClient(); + return $client->request($method, $url->setAbsolute(TRUE)->toString(), $request_options); } /** * Asserts that a resource response has the given status code and body. * - * (Also asserts that the expected error MIME type is present, but this is - * defined globally for the test via static::$expectedErrorMimeType, because - * all error responses should use the same MIME type.) - * * @param int $expected_status_code * The expected response status. * @param string|false $expected_body @@ -314,12 +351,7 @@ protected function request($method, Url $url, array $request_options) { */ protected function assertResourceResponse($expected_status_code, $expected_body, ResponseInterface $response) { $this->assertSame($expected_status_code, $response->getStatusCode()); - if ($expected_status_code < 400) { - $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); - } - else { - $this->assertSame([static::$expectedErrorMimeType], $response->getHeader('Content-Type')); - } + $this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); if ($expected_body !== FALSE) { $this->assertSame($expected_body, (string) $response->getBody()); } @@ -328,10 +360,6 @@ protected function assertResourceResponse($expected_status_code, $expected_body, /** * Asserts that a resource error response has the given message. * - * (Also asserts that the expected error MIME type is present, but this is - * defined globally for the test via static::$expectedErrorMimeType, because - * all error responses should use the same MIME type.) - * * @param int $expected_status_code * The expected response status. * @param string $expected_message @@ -340,10 +368,34 @@ protected function assertResourceResponse($expected_status_code, $expected_body, * The error response to assert. */ protected function assertResourceErrorResponse($expected_status_code, $expected_message, ResponseInterface $response) { - // @todo Fix this in https://www.drupal.org/node/2813755. - $encode_options = ['json_encode_options' => JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT]; - $expected_body = $this->serializer->encode(['message' => $expected_message], static::$format, $encode_options); + $expected_body = ($expected_message !== FALSE) ? $this->serializer->encode(['message' => $expected_message], static::$format) : FALSE; $this->assertResourceResponse($expected_status_code, $expected_body, $response); } + /** + * Adds the Xdebug cookie to the request options. + * + * @param array $request_options + * The request options. + * + * @return array + * Request options updated with the Xdebug cookie if present. + */ + protected function decorateWithXdebugCookie(array $request_options) { + $session = $this->getSession(); + $driver = $session->getDriver(); + if ($driver instanceof BrowserKitDriver) { + $client = $driver->getClient(); + foreach ($client->getCookieJar()->all() as $cookie) { + if (isset($request_options[RequestOptions::HEADERS]['Cookie'])) { + $request_options[RequestOptions::HEADERS]['Cookie'] .= '; ' . $cookie->getName() . '=' . $cookie->getValue(); + } + else { + $request_options[RequestOptions::HEADERS]['Cookie'] = $cookie->getName() . '=' . $cookie->getValue(); + } + } + } + return $request_options; + } + } diff --git a/core/modules/rest/src/Tests/Update/EntityResourcePermissionsUpdateTest.php b/core/modules/rest/tests/src/Functional/Update/EntityResourcePermissionsUpdateTest.php similarity index 86% rename from core/modules/rest/src/Tests/Update/EntityResourcePermissionsUpdateTest.php rename to core/modules/rest/tests/src/Functional/Update/EntityResourcePermissionsUpdateTest.php index 989159e1..9add9c5d 100644 --- a/core/modules/rest/src/Tests/Update/EntityResourcePermissionsUpdateTest.php +++ b/core/modules/rest/tests/src/Functional/Update/EntityResourcePermissionsUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../rest/tests/fixtures/update/drupal-8.rest-rest_update_8203.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/drupal-8.rest-rest_update_8203.php', ]; } diff --git a/core/modules/rest/src/Tests/Update/ResourceGranularityUpdateTest.php b/core/modules/rest/tests/src/Functional/Update/ResourceGranularityUpdateTest.php similarity index 90% rename from core/modules/rest/src/Tests/Update/ResourceGranularityUpdateTest.php rename to core/modules/rest/tests/src/Functional/Update/ResourceGranularityUpdateTest.php index c8cf89af..19ef5458 100644 --- a/core/modules/rest/src/Tests/Update/ResourceGranularityUpdateTest.php +++ b/core/modules/rest/tests/src/Functional/Update/ResourceGranularityUpdateTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../rest/tests/fixtures/update/drupal-8.rest-rest_post_update_resource_granularity.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/drupal-8.rest-rest_post_update_resource_granularity.php', ]; } diff --git a/core/modules/rest/src/Tests/Update/RestConfigurationEntitiesUpdateTest.php b/core/modules/rest/tests/src/Functional/Update/RestConfigurationEntitiesUpdateTest.php similarity index 89% rename from core/modules/rest/src/Tests/Update/RestConfigurationEntitiesUpdateTest.php rename to core/modules/rest/tests/src/Functional/Update/RestConfigurationEntitiesUpdateTest.php index 097da35b..f4d8199a 100644 --- a/core/modules/rest/src/Tests/Update/RestConfigurationEntitiesUpdateTest.php +++ b/core/modules/rest/tests/src/Functional/Update/RestConfigurationEntitiesUpdateTest.php @@ -1,9 +1,9 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../rest/tests/fixtures/update/drupal-8.rest-rest_update_8201.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../fixtures/update/drupal-8.rest-rest_update_8201.php', ]; } diff --git a/core/modules/rest/tests/src/Functional/Update/RestExportAuthUpdateTest.php b/core/modules/rest/tests/src/Functional/Update/RestExportAuthUpdateTest.php new file mode 100644 index 00000000..87cd5dbf --- /dev/null +++ b/core/modules/rest/tests/src/Functional/Update/RestExportAuthUpdateTest.php @@ -0,0 +1,36 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/rest-export-with-authentication.php', + ]; + } + + /** + * Ensures that update hook is run for rest module. + */ + public function testUpdate() { + $this->runUpdates(); + + // Get particular view. + $view = \Drupal::entityTypeManager()->getStorage('view')->load('rest_export_with_authorization'); + $displays = $view->get('display'); + $this->assertIdentical($displays['rest_export_1']['display_options']['auth']['basic_auth'], 'basic_auth', 'Basic authentication is set as authentication method.'); + } + +} diff --git a/core/modules/rest/src/Tests/Views/ExcludedFieldTokenTest.php b/core/modules/rest/tests/src/Functional/Views/ExcludedFieldTokenTest.php similarity index 86% rename from core/modules/rest/src/Tests/Views/ExcludedFieldTokenTest.php rename to core/modules/rest/tests/src/Functional/Views/ExcludedFieldTokenTest.php index 2a910fe2..cf9913d8 100644 --- a/core/modules/rest/src/Tests/Views/ExcludedFieldTokenTest.php +++ b/core/modules/rest/tests/src/Functional/Views/ExcludedFieldTokenTest.php @@ -1,9 +1,9 @@ drupalGetWithFormat($this->view->getPath(), 'json'); + $actual_json = $this->drupalGet($this->view->getPath(), ['query' => ['_format' => 'json']]); $this->assertResponse(200); $expected = [ @@ -84,5 +84,4 @@ public function testExcludedTitleTokenDisplay() { $this->assertIdentical($actual_json, json_encode($expected)); } - } diff --git a/core/modules/rest/tests/src/Functional/Views/RestExportAuthTest.php b/core/modules/rest/tests/src/Functional/Views/RestExportAuthTest.php new file mode 100644 index 00000000..24546089 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/Views/RestExportAuthTest.php @@ -0,0 +1,67 @@ +drupalLogin($this->drupalCreateUser(['administer views'])); + } + + /** + * Checks that correct authentication providers are available for choosing. + * + * @link https://www.drupal.org/node/2825204 + */ + public function testAuthProvidersOptions() { + $view_id = 'test_view_rest_export'; + $view_label = 'Test view (REST export)'; + $view_display = 'rest_export_1'; + $view_rest_path = 'test-view/rest-export'; + + // Create new view. + $this->drupalPostForm('admin/structure/views/add', [ + 'id' => $view_id, + 'label' => $view_label, + 'show[wizard_key]' => 'users', + 'rest_export[path]' => $view_rest_path, + 'rest_export[create]' => TRUE, + ], t('Save and edit')); + + $this->drupalGet("admin/structure/views/nojs/display/$view_id/$view_display/auth"); + // The "basic_auth" will always be available since module, + // providing it, has the same name. + $this->assertField('edit-auth-basic-auth', 'Basic auth is available for choosing.'); + // The "cookie" authentication provider defined by "user" module. + $this->assertField('edit-auth-cookie', 'Cookie-based auth can be chosen.'); + // Wrong behavior in "getAuthOptions()" method makes this option available + // instead of "cookie". + // @see \Drupal\rest\Plugin\views\display\RestExport::getAuthOptions() + $this->assertNoField('edit-auth-user', 'Wrong authentication option is unavailable.'); + + $this->drupalPostForm(NULL, ['auth[basic_auth]' => 1, 'auth[cookie]' => 1], 'Apply'); + $this->drupalPostForm(NULL, [], 'Save'); + + $view = View::load($view_id); + $this->assertEquals(['basic_auth', 'cookie'], $view->getDisplay('rest_export_1')['display_options']['auth']); + } + +} diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/tests/src/Functional/Views/StyleSerializerTest.php similarity index 78% rename from core/modules/rest/src/Tests/Views/StyleSerializerTest.php rename to core/modules/rest/tests/src/Functional/Views/StyleSerializerTest.php index 4c004fca..a1545870 100644 --- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php +++ b/core/modules/rest/tests/src/Functional/Views/StyleSerializerTest.php @@ -1,7 +1,8 @@ adminUser = $this->drupalCreateUser(array('administer views', 'administer entity_test content', 'access user profiles', 'view test entity')); + $this->adminUser = $this->drupalCreateUser(['administer views', 'administer entity_test content', 'access user profiles', 'view test entity']); // Save some entity_test entities. for ($i = 1; $i <= 10; $i++) { - EntityTest::create(array('name' => 'test_' . $i, 'user_id' => $this->adminUser->id()))->save(); + EntityTest::create(['name' => 'test_' . $i, 'user_id' => $this->adminUser->id()])->save(); } $this->enableViewsTestModule(); @@ -74,13 +70,13 @@ protected function setUp() { */ public function testRestViewsAuthentication() { // Assume the view is hidden behind a permission. - $this->drupalGetWithFormat('test/serialize/auth_with_perm', 'json'); + $this->drupalGet('test/serialize/auth_with_perm', ['query' => ['_format' => 'json']]); $this->assertResponse(401); // Not even logging in would make it possible to see the view, because then // we are denied based on authentication method (cookie). $this->drupalLogin($this->adminUser); - $this->drupalGetWithFormat('test/serialize/auth_with_perm', 'json'); + $this->drupalGet('test/serialize/auth_with_perm', ['query' => ['_format' => 'json']]); $this->assertResponse(403); $this->drupalLogout(); @@ -94,11 +90,6 @@ public function testRestViewsAuthentication() { // Ensure that any changes to variables in the other thread are picked up. $this->refreshVariables(); - $headers = $response->getHeaders(); - $this->verbose('GET request to: ' . $url . - '


    Code: ' . curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE) . - '
    Response headers: ' . nl2br(print_r($headers, TRUE)) . - '
    Response body: ' . (string) $response->getBody()); $this->assertResponse(200); } @@ -111,7 +102,7 @@ public function testSerializerResponses() { $view->initDisplay(); $this->executeView($view); - $actual_json = $this->drupalGetWithFormat('test/serialize/field', 'json'); + $actual_json = $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]); $this->assertResponse(200); $this->assertCacheTags($view->getCacheTags()); $this->assertCacheContexts(['languages:language_interface', 'theme', 'request_format']); @@ -120,11 +111,11 @@ public function testSerializerResponses() { // Test the http Content-type. $headers = $this->drupalGetHeaders(); - $this->assertEqual($headers['content-type'], 'application/json', 'The header Content-type is correct.'); + $this->assertSame(['application/json'], $headers['Content-Type']); - $expected = array(); + $expected = []; foreach ($view->result as $row) { - $expected_row = array(); + $expected_row = []; foreach ($view->field as $id => $field) { $expected_row[$id] = $field->render($row); } @@ -154,14 +145,14 @@ public function testSerializerResponses() { // Get the serializer service. $serializer = $this->container->get('serializer'); - $entities = array(); + $entities = []; foreach ($view->result as $row) { $entities[] = $row->_entity; } $expected = $serializer->serialize($entities, 'json'); - $actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'json'); + $actual_json = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]); $this->assertResponse(200); $this->assertIdentical($actual_json, $expected, 'The expected JSON output was found.'); $expected_cache_tags = $view->getCacheTags(); @@ -174,52 +165,52 @@ public function testSerializerResponses() { $this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']); $expected = $serializer->serialize($entities, 'hal_json'); - $actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'hal_json'); + $actual_json = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'hal_json']]); $this->assertIdentical($actual_json, $expected, 'The expected HAL output was found.'); $this->assertCacheTags($expected_cache_tags); // Change the default format to xml. $view->setDisplay('rest_export_1'); - $view->getDisplay()->setOption('style', array( + $view->getDisplay()->setOption('style', [ 'type' => 'serializer', - 'options' => array( + 'options' => [ 'uses_fields' => FALSE, - 'formats' => array( + 'formats' => [ 'xml' => 'xml', - ), - ), - )); + ], + ], + ]); $view->save(); $expected = $serializer->serialize($entities, 'xml'); - $actual_xml = $this->drupalGet('test/serialize/entity'); - $this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.'); + $actual_xml = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'xml']]); + $this->assertSame(trim($expected), $actual_xml); $this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']); // Allow multiple formats. $view->setDisplay('rest_export_1'); - $view->getDisplay()->setOption('style', array( + $view->getDisplay()->setOption('style', [ 'type' => 'serializer', - 'options' => array( + 'options' => [ 'uses_fields' => FALSE, - 'formats' => array( + 'formats' => [ 'xml' => 'xml', 'json' => 'json', - ), - ), - )); + ], + ], + ]); $view->save(); $expected = $serializer->serialize($entities, 'json'); - $actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'json'); + $actual_json = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]); $this->assertIdentical($actual_json, $expected, 'The expected JSON output was found.'); $expected = $serializer->serialize($entities, 'xml'); - $actual_xml = $this->drupalGetWithFormat('test/serialize/entity', 'xml'); - $this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.'); + $actual_xml = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'xml']]); + $this->assertSame(trim($expected), $actual_xml); } /** * Verifies site maintenance mode functionality. */ - protected function testSiteMaintenance() { + public function testSiteMaintenance() { $view = Views::getView('test_serializer_display_field'); $view->initDisplay(); $this->executeView($view); @@ -227,7 +218,7 @@ protected function testSiteMaintenance() { // Set the site to maintenance mode. $this->container->get('state')->set('system.maintenance_mode', TRUE); - $this->drupalGetWithFormat('test/serialize/entity', 'json'); + $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]); // Verify that the endpoint is unavailable for anonymous users. $this->assertResponse(503); } @@ -294,14 +285,14 @@ public function testRestRenderCaching() { // Request the page, once in XML and once in JSON to ensure that the caching // varies by it. - $result1 = $this->drupalGetJSON('test/serialize/entity'); + $result1 = Json::decode($this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']])); $this->addRequestWithFormat('json'); $this->assertHeader('content-type', 'application/json'); $this->assertCacheContexts($cache_contexts); $this->assertCacheTags($cache_tags); $this->assertTrue($render_cache->get($original)); - $result_xml = $this->drupalGetWithFormat('test/serialize/entity', 'xml'); + $result_xml = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'xml']]); $this->addRequestWithFormat('xml'); $this->assertHeader('content-type', 'text/xml; charset=UTF-8'); $this->assertCacheContexts($cache_contexts); @@ -312,7 +303,7 @@ public function testRestRenderCaching() { $this->assertNotEqual($result1, $result_xml); // Ensure that the cached page works. - $result2 = $this->drupalGetJSON('test/serialize/entity'); + $result2 = Json::decode($this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']])); $this->addRequestWithFormat('json'); $this->assertHeader('content-type', 'application/json'); $this->assertEqual($result2, $result1); @@ -322,7 +313,7 @@ public function testRestRenderCaching() { // Create a new entity and ensure that the cache tags are taken over. EntityTest::create(['name' => 'test_11', 'user_id' => $this->adminUser->id()])->save(); - $result3 = $this->drupalGetJSON('test/serialize/entity'); + $result3 = Json::decode($this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']])); $this->addRequestWithFormat('json'); $this->assertHeader('content-type', 'application/json'); $this->assertNotEqual($result3, $result2); @@ -346,21 +337,21 @@ public function testResponseFormatConfiguration() { $style_options = 'admin/structure/views/nojs/display/test_serializer_display_field/rest_export_1/style_options'; // Select only 'xml' as an accepted format. - $this->drupalPostForm($style_options, array('style_options[formats][xml]' => 'xml'), t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm($style_options, ['style_options[formats][xml]' => 'xml'], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); // Should return a 406. - $this->drupalGetWithFormat('test/serialize/field', 'json'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]); $this->assertHeader('content-type', 'application/json'); $this->assertResponse(406, 'A 406 response was returned when JSON was requested.'); // Should return a 200. - $this->drupalGetWithFormat('test/serialize/field', 'xml'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'xml']]); $this->assertHeader('content-type', 'text/xml; charset=UTF-8'); $this->assertResponse(200, 'A 200 response was returned when XML was requested.'); // Add 'json' as an accepted format, so we have multiple. - $this->drupalPostForm($style_options, array('style_options[formats][json]' => 'json'), t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm($style_options, ['style_options[formats][json]' => 'json'], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); // Should return a 200. // @todo This should be fixed when we have better content negotiation. @@ -369,42 +360,42 @@ public function testResponseFormatConfiguration() { $this->assertResponse(200, 'A 200 response was returned when any format was requested.'); // Should return a 200. Emulates a sample Firefox header. - $this->drupalGet('test/serialize/field', array(), array('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')); + $this->drupalGet('test/serialize/field', [], ['Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8']); $this->assertHeader('content-type', 'application/json'); $this->assertResponse(200, 'A 200 response was returned when a browser accept header was requested.'); // Should return a 200. - $this->drupalGetWithFormat('test/serialize/field', 'json'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]); $this->assertHeader('content-type', 'application/json'); $this->assertResponse(200, 'A 200 response was returned when JSON was requested.'); $headers = $this->drupalGetHeaders(); - $this->assertEqual($headers['content-type'], 'application/json', 'The header Content-type is correct.'); + $this->assertEqual($headers['Content-Type'], ['application/json'], 'The header Content-type is correct.'); // Should return a 200. - $this->drupalGetWithFormat('test/serialize/field', 'xml'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'xml']]); $this->assertHeader('content-type', 'text/xml; charset=UTF-8'); $this->assertResponse(200, 'A 200 response was returned when XML was requested'); $headers = $this->drupalGetHeaders(); - $this->assertTrue(strpos($headers['content-type'], 'text/xml') !== FALSE, 'The header Content-type is correct.'); + $this->assertSame(['text/xml; charset=UTF-8'], $headers['Content-Type']); // Should return a 406. - $this->drupalGetWithFormat('test/serialize/field', 'html'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'html']]); // We want to show the first format by default, see // \Drupal\rest\Plugin\views\style\Serializer::render. $this->assertHeader('content-type', 'application/json'); $this->assertResponse(200, 'A 200 response was returned when HTML was requested.'); // Now configure now format, so all of them should be allowed. - $this->drupalPostForm($style_options, array('style_options[formats][json]' => '0', 'style_options[formats][xml]' => '0'), t('Apply')); + $this->drupalPostForm($style_options, ['style_options[formats][json]' => '0', 'style_options[formats][xml]' => '0'], t('Apply')); // Should return a 200. - $this->drupalGetWithFormat('test/serialize/field', 'json'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]); $this->assertHeader('content-type', 'application/json'); $this->assertResponse(200, 'A 200 response was returned when JSON was requested.'); // Should return a 200. - $this->drupalGetWithFormat('test/serialize/field', 'xml'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'xml']]); $this->assertHeader('content-type', 'text/xml; charset=UTF-8'); $this->assertResponse(200, 'A 200 response was returned when XML was requested'); // Should return a 200. - $this->drupalGetWithFormat('test/serialize/field', 'html'); + $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'html']]); // We want to show the first format by default, see // \Drupal\rest\Plugin\views\style\Serializer::render. $this->assertHeader('content-type', 'application/json'); @@ -424,58 +415,58 @@ public function testUIFieldAlias() { // Test an empty string for an alias, this should not be used. This also // tests that the form can be submitted with no aliases. - $this->drupalPostForm($row_options, array('row_options[field_options][name][alias]' => ''), t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm($row_options, ['row_options[field_options][name][alias]' => ''], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); $view = Views::getView('test_serializer_display_field'); $view->setDisplay('rest_export_1'); $this->executeView($view); - $expected = array(); + $expected = []; foreach ($view->result as $row) { - $expected_row = array(); + $expected_row = []; foreach ($view->field as $id => $field) { $expected_row[$id] = $field->render($row); } $expected[] = $expected_row; } - $this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected)); + $this->assertIdentical(Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])), $this->castSafeStrings($expected)); // Test a random aliases for fields, they should be replaced. - $alias_map = array( + $alias_map = [ 'name' => $this->randomMachineName(), // Use # to produce an invalid character for the validation. 'nothing' => '#' . $this->randomMachineName(), 'created' => 'created', - ); + ]; - $edit = array('row_options[field_options][name][alias]' => $alias_map['name'], 'row_options[field_options][nothing][alias]' => $alias_map['nothing']); + $edit = ['row_options[field_options][name][alias]' => $alias_map['name'], 'row_options[field_options][nothing][alias]' => $alias_map['nothing']]; $this->drupalPostForm($row_options, $edit, t('Apply')); $this->assertText(t('The machine-readable name must contain only letters, numbers, dashes and underscores.')); // Change the map alias value to a valid one. $alias_map['nothing'] = $this->randomMachineName(); - $edit = array('row_options[field_options][name][alias]' => $alias_map['name'], 'row_options[field_options][nothing][alias]' => $alias_map['nothing']); + $edit = ['row_options[field_options][name][alias]' => $alias_map['name'], 'row_options[field_options][nothing][alias]' => $alias_map['nothing']]; $this->drupalPostForm($row_options, $edit, t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $view = Views::getView('test_serializer_display_field'); $view->setDisplay('rest_export_1'); $this->executeView($view); - $expected = array(); + $expected = []; foreach ($view->result as $row) { - $expected_row = array(); + $expected_row = []; foreach ($view->field as $id => $field) { $expected_row[$alias_map[$id]] = $field->render($row); } $expected[] = $expected_row; } - $this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected)); + $this->assertIdentical(Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])), $this->castSafeStrings($expected)); } /** @@ -491,12 +482,12 @@ public function testFieldRawOutput() { // Test an empty string for an alias, this should not be used. This also // tests that the form can be submitted with no aliases. - $values = array( + $values = [ 'row_options[field_options][created][raw_output]' => '1', 'row_options[field_options][name][raw_output]' => '1', - ); + ]; $this->drupalPostForm($row_options, $values, t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $view = Views::getView('test_serializer_display_field'); $view->setDisplay('rest_export_1'); @@ -512,7 +503,7 @@ public function testFieldRawOutput() { } // Just test the raw 'created' value against each row. - foreach ($this->drupalGetJSON('test/serialize/field') as $index => $values) { + foreach (Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])) as $index => $values) { $this->assertIdentical($values['created'], $view->result[$index]->views_test_data_created, 'Expected raw created value found.'); $this->assertIdentical($values['name'], $view->result[$index]->views_test_data_name, 'Expected raw name value found.'); } @@ -536,7 +527,7 @@ public function testFieldRawOutput() { ]); $view->save(); $this->executeView($view); - foreach ($this->drupalGetJSON('test/serialize/field') as $index => $values) { + foreach (Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])) as $index => $values) { $this->assertTrue(!isset($values['created']), 'Excluded value not found.'); } // Test that the excluded field is not shown in the row options. @@ -562,7 +553,7 @@ public function testLivePreview() { // Get the serializer service. $serializer = $this->container->get('serializer'); - $entities = array(); + $entities = []; foreach ($view->result as $row) { $entities[] = $row->_entity; } @@ -580,15 +571,15 @@ public function testLivePreview() { // Change the request format to xml. $view->setDisplay('rest_export_1'); - $view->getDisplay()->setOption('style', array( + $view->getDisplay()->setOption('style', [ 'type' => 'serializer', - 'options' => array( + 'options' => [ 'uses_fields' => FALSE, - 'formats' => array( + 'formats' => [ 'xml' => 'xml', - ), - ), - )); + ], + ], + ]); $this->executeView($view); $build = $view->preview(); @@ -602,21 +593,22 @@ public function testLivePreview() { public function testSerializerViewsUI() { $this->drupalLogin($this->adminUser); // Click the "Update preview button". - $this->drupalPostForm('admin/structure/views/view/test_serializer_display_field/edit/rest_export_1', $edit = array(), t('Update preview')); + $this->drupalPostForm('admin/structure/views/view/test_serializer_display_field/edit/rest_export_1', $edit = [], t('Update preview')); $this->assertResponse(200); // Check if we receive the expected result. $result = $this->xpath('//div[@id="views-live-preview"]/pre'); - $this->assertIdentical($this->drupalGet('test/serialize/field'), (string) $result[0], 'The expected JSON preview output was found.'); + $json_preview = $result[0]->getText(); + $this->assertSame($json_preview, $this->drupalGet('test/serialize/field'), 'The expected JSON preview output was found.'); } /** * Tests the field row style using fieldapi fields. */ public function testFieldapiField() { - $this->drupalCreateContentType(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); $node = $this->drupalCreateNode(); - $result = $this->drupalGetJSON('test/serialize/node-field'); + $result = Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']])); $this->assertEqual($result[0]['nid'], $node->id()); $this->assertEqual($result[0]['body'], $node->body->processed); @@ -627,7 +619,7 @@ public function testFieldapiField() { 'format' => filter_default_format(), ]; $node->save(); - $result = $this->drupalGetJSON('test/serialize/node-field'); + $result = Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']])); $this->assertEqual($result[1]['nid'], $node->id()); $this->assertTrue(strpos($this->getRawContent(), "executeView($view); // Test the raw 'created' value against each row. - foreach ($this->drupalGetJSON('test/serialize/node-field') as $index => $values) { + foreach (Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']])) as $index => $values) { $this->assertIdentical($values['title'], $view->result[$index]->_entity->title->value, 'Expected raw title value found.'); } @@ -673,9 +665,11 @@ public function testFieldapiField() { $view->setDisplay('rest_export_1'); $this->executeView($view); - $result = $this->drupalGetJSON('test/serialize/node-field'); + $result = Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']])); $this->assertEqual(count($result[2]['body']), $node->body->count(), 'Expected count of values'); - $this->assertEqual($result[2]['body'], array_map(function($item) { return $item['value']; }, $node->body->getValue()), 'Expected raw body values found.'); + $this->assertEqual($result[2]['body'], array_map(function ($item) { + return $item['value']; + }, $node->body->getValue()), 'Expected raw body values found.'); } /** @@ -749,44 +743,44 @@ public function testGroupRows() { * the value provided. */ public function testRestViewExposedFilter() { - $this->drupalCreateContentType(array('type' => 'page')); - $node0 = $this->drupalCreateNode(array('title' => 'Node 1')); - $node1 = $this->drupalCreateNode(array('title' => 'Node 11')); - $node2 = $this->drupalCreateNode(array('title' => 'Node 111')); + $this->drupalCreateContentType(['type' => 'page']); + $node0 = $this->drupalCreateNode(['title' => 'Node 1']); + $node1 = $this->drupalCreateNode(['title' => 'Node 11']); + $node2 = $this->drupalCreateNode(['title' => 'Node 111']); // Test that no filter brings back all three nodes. - $result = $this->drupalGetJSON('test/serialize/node-exposed-filter'); + $result = Json::decode($this->drupalGet('test/serialize/node-exposed-filter', ['query' => ['_format' => 'json']])); - $expected = array( - 0 => array( + $expected = [ + 0 => [ 'nid' => $node0->id(), 'body' => $node0->body->processed, - ), - 1 => array( + ], + 1 => [ 'nid' => $node1->id(), 'body' => $node1->body->processed, - ), - 2 => array( + ], + 2 => [ 'nid' => $node2->id(), 'body' => $node2->body->processed, - ), - ); + ], + ]; $this->assertEqual($result, $expected, 'Querying a view with no exposed filter returns all nodes.'); // Test that title starts with 'Node 11' query finds 2 of the 3 nodes. - $result = $this->drupalGetJSON('test/serialize/node-exposed-filter', ['query' => ['title' => 'Node 11']]); + $result = Json::decode($this->drupalGet('test/serialize/node-exposed-filter', ['query' => ['_format' => 'json', 'title' => 'Node 11']])); - $expected = array( - 0 => array( + $expected = [ + 0 => [ 'nid' => $node1->id(), 'body' => $node1->body->processed, - ), - 1 => array( + ], + 1 => [ 'nid' => $node2->id(), 'body' => $node2->body->processed, - ), - ); + ], + ]; $cache_contexts = [ 'languages:language_content', @@ -822,7 +816,7 @@ public function testMulEntityRows() { $entity->addTranslation('l1', ['name' => 'mul-l2-l1'])->save(); // Get the names of the output. - $json = $this->drupalGetWithFormat('test/serialize/translated_entity', 'json'); + $json = $this->drupalGet('test/serialize/translated_entity', ['query' => ['_format' => 'json']]); $decoded = $this->container->get('serializer')->decode($json, 'hal_json'); $names = []; foreach ($decoded as $item) { diff --git a/core/modules/rest/tests/src/Kernel/Entity/ConfigDependenciesTest.php b/core/modules/rest/tests/src/Kernel/Entity/ConfigDependenciesTest.php index f62ee03f..51ad3e97 100644 --- a/core/modules/rest/tests/src/Kernel/Entity/ConfigDependenciesTest.php +++ b/core/modules/rest/tests/src/Kernel/Entity/ConfigDependenciesTest.php @@ -30,9 +30,9 @@ public function testCalculateDependencies(array $configuration) { $rest_config = RestResourceConfig::create($configuration); $result = $config_dependencies->calculateDependencies($rest_config); - $this->assertEquals(['module' => [ - 'basic_auth', 'serialization', 'hal', - ]], $result); + $this->assertEquals([ + 'module' => ['basic_auth', 'serialization', 'hal'], + ], $result); } /** diff --git a/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php b/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php index 905b449a..2b885591 100644 --- a/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php +++ b/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\rest\Kernel; -use Drupal\Component\Serialization\Json; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Routing\RouteMatch; use Drupal\KernelTests\KernelTestBase; @@ -10,8 +9,6 @@ use Drupal\rest\RequestHandler; use Drupal\rest\ResourceResponse; use Drupal\rest\RestResourceConfigInterface; -use Prophecy\Argument; -use Prophecy\Prophecy\MethodProphecy; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; @@ -48,13 +45,11 @@ public function setUp() { } /** - * Assert some basic handler method logic. - * * @covers ::handle */ - public function testBaseHandler() { + public function testHandle() { $request = new Request(); - $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_format' => 'json'])); + $route_match = new RouteMatch('test', (new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_format' => 'json']))->setMethods(['GET'])); $resource = $this->prophesize(StubRequestHandlerResourcePlugin::class); $resource->get(NULL, $request) @@ -81,7 +76,7 @@ public function testBaseHandler() { $this->assertEquals($response, $handler_response); // We will call the patch method this time. - $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_content_type_format' => 'json'])); + $route_match = new RouteMatch('test', (new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_content_type_format' => 'json']))->setMethods(['PATCH'])); $request->setMethod('PATCH'); $response = new ResourceResponse([]); $resource->patch(NULL, $request) @@ -91,249 +86,6 @@ public function testBaseHandler() { $this->assertEquals($response, $handler_response); } - /** - * Test that given structured data, the request handler will serialize it. - * - * @dataProvider providerTestSerialization - * @covers ::handle - */ - public function testSerialization($data, $expected_response = FALSE) { - $request = new Request(); - $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_format' => 'json'])); - - $resource = $this->prophesize(StubRequestHandlerResourcePlugin::class); - - // Mock the configuration. - $config = $this->prophesize(RestResourceConfigInterface::class); - $config->getResourcePlugin()->willReturn($resource->reveal()); - $config->getCacheContexts()->willReturn([]); - $config->getCacheTags()->willReturn([]); - $config->getCacheMaxAge()->willReturn(12); - $this->entityStorage->load('restplugin')->willReturn($config->reveal()); - - $response = new ResourceResponse($data); - $resource->get(NULL, $request) - ->willReturn($response); - $handler_response = $this->requestHandler->handle($route_match, $request); - // Content is a serialized version of the data we provided. - $this->assertEquals($expected_response !== FALSE ? $expected_response : json_encode($data), $handler_response->getContent()); - } - - public function providerTestSerialization() { - return [ - // The default data for \Drupal\rest\ResourceResponse. - [NULL, ''], - [''], - ['string'], - ['Complex \ string $%^&@ with unicode ΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΣὨ'], - [[]], - [['test']], - [['test' => 'foobar']], - [TRUE], - [FALSE], - // @todo Not supported. https://www.drupal.org/node/2427811 - // [new \stdClass()], - // [(object) ['test' => 'foobar']], - ]; - } - - /** - * @covers ::getResponseFormat - * - * Note this does *not* need to test formats being requested that are not - * accepted by the server, because the routing system would have already - * prevented those from reaching RequestHandler. - * - * @param string[] $methods - * The HTTP methods to test. - * @param string[] $supported_formats - * The supported formats for the REST route to be tested. - * @param string|false $request_format - * The value for the ?_format URL query argument, if any. - * @param string[] $request_headers - * The request headers to send, if any. - * @param string|null $request_body - * The request body to send, if any. - * @param string|null $expected_response_content_type - * The expected MIME type of the response, if any. - * @param string $expected_response_content - * The expected content of the response. - * - * @dataProvider providerTestResponseFormat - */ - public function testResponseFormat($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_content_type, $expected_response_content) { - $rest_config_name = $this->randomMachineName(); - - $parameters = []; - if ($request_format !== FALSE) { - $parameters['_format'] = $request_format; - } - - foreach ($request_headers as $key => $value) { - unset($request_headers[$key]); - $key = strtoupper(str_replace('-', '_', $key)); - $request_headers[$key] = $value; - } - - foreach ($methods as $method) { - $request = Request::create('/rest/test', $method, $parameters, [], [], $request_headers, $request_body); - $route_requirement_key_format = $request->isMethodSafe() ? '_format' : '_content_type_format'; - $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $rest_config_name], [$route_requirement_key_format => implode('|', $supported_formats)])); - - $resource = $this->prophesize(StubRequestHandlerResourcePlugin::class); - - // Mock the configuration. - $config = $this->prophesize(RestResourceConfigInterface::class); - $config->getFormats($method)->willReturn($supported_formats); - $config->getResourcePlugin()->willReturn($resource->reveal()); - $config->getCacheContexts()->willReturn([]); - $config->getCacheTags()->willReturn([]); - $config->getCacheMaxAge()->willReturn(12); - $this->entityStorage->load($rest_config_name)->willReturn($config->reveal()); - - // Mock the resource plugin. - $response = new ResourceResponse($method !== 'DELETE' ? ['REST' => 'Drupal'] : NULL); - $resource->getPluginDefinition()->willReturn([]); - $method_prophecy = new MethodProphecy($resource, strtolower($method), [Argument::any(), $request]); - $method_prophecy->willReturn($response); - $resource->addMethodProphecy($method_prophecy); - - // Test the request handler. - $handler_response = $this->requestHandler->handle($route_match, $request); - $this->assertSame($expected_response_content_type, $handler_response->headers->get('Content-Type')); - $this->assertEquals($expected_response_content, $handler_response->getContent()); - } - } - - /** - * @return array - * 0. methods to test - * 1. supported formats for route requirements - * 2. request format - * 3. request headers - * 4. request body - * 5. expected response content type - * 6. expected response body - */ - public function providerTestResponseFormat() { - $json_encoded = Json::encode(['REST' => 'Drupal']); - $xml_encoded = "\nDrupal\n"; - - $safe_method_test_cases = [ - 'safe methods: client requested format (JSON)' => [ - // @todo add 'HEAD' in https://www.drupal.org/node/2752325 - ['GET'], - ['xml', 'json'], - 'json', - [], - NULL, - 'application/json', - $json_encoded, - ], - 'safe methods: client requested format (XML)' => [ - // @todo add 'HEAD' in https://www.drupal.org/node/2752325 - ['GET'], - ['xml', 'json'], - 'xml', - [], - NULL, - 'text/xml', - $xml_encoded, - ], - 'safe methods: client requested no format: response should use the first configured format (JSON)' => [ - // @todo add 'HEAD' in https://www.drupal.org/node/2752325 - ['GET'], - ['json', 'xml'], - FALSE, - [], - NULL, - 'application/json', - $json_encoded, - ], - 'safe methods: client requested no format: response should use the first configured format (XML)' => [ - // @todo add 'HEAD' in https://www.drupal.org/node/2752325 - ['GET'], - ['xml', 'json'], - FALSE, - [], - NULL, - 'text/xml', - $xml_encoded, - ], - ]; - - $unsafe_method_bodied_test_cases = [ - 'unsafe methods with response (POST, PATCH): client requested no format, response should use request body format (JSON)' => [ - ['POST', 'PATCH'], - ['xml', 'json'], - FALSE, - ['Content-Type' => 'application/json'], - $json_encoded, - 'application/json', - $json_encoded, - ], - 'unsafe methods with response (POST, PATCH): client requested no format, response should use request body format (XML)' => [ - ['POST', 'PATCH'], - ['xml', 'json'], - FALSE, - ['Content-Type' => 'text/xml'], - $xml_encoded, - 'text/xml', - $xml_encoded, - ], - 'unsafe methods with response (POST, PATCH): client requested format other than request body format (JSON): response format should use requested format (XML)' => [ - ['POST', 'PATCH'], - ['xml', 'json'], - 'xml', - ['Content-Type' => 'application/json'], - $json_encoded, - 'text/xml', - $xml_encoded, - ], - 'unsafe methods with response (POST, PATCH): client requested format other than request body format (XML), but is allowed for the request body (JSON)' => [ - ['POST', 'PATCH'], - ['xml', 'json'], - 'json', - ['Content-Type' => 'text/xml'], - $xml_encoded, - 'application/json', - $json_encoded, - ], - ]; - - $unsafe_method_bodyless_test_cases = [ - 'unsafe methods with response bodies (DELETE): client requested no format, response should have no format' => [ - ['DELETE'], - ['xml', 'json'], - FALSE, - ['Content-Type' => 'application/json'], - $json_encoded, - NULL, - '', - ], - 'unsafe methods with response bodies (DELETE): client requested format (XML), response should have no format' => [ - ['DELETE'], - ['xml', 'json'], - 'xml', - ['Content-Type' => 'application/json'], - $json_encoded, - NULL, - '', - ], - 'unsafe methods with response bodies (DELETE): client requested format (JSON), response should have no format' => [ - ['DELETE'], - ['xml', 'json'], - 'json', - ['Content-Type' => 'application/json'], - $json_encoded, - NULL, - '', - ], - ]; - - return $safe_method_test_cases + $unsafe_method_bodied_test_cases + $unsafe_method_bodyless_test_cases; - } - } /** @@ -341,9 +93,9 @@ public function providerTestResponseFormat() { */ class StubRequestHandlerResourcePlugin extends ResourceBase { - function get() {} - function post() {} - function patch() {} - function delete() {} + public function get() {} + public function post() {} + public function patch() {} + public function delete() {} } diff --git a/core/modules/rest/tests/src/Kernel/RestLinkManagerTest.php b/core/modules/rest/tests/src/Kernel/RestLinkManagerTest.php deleted file mode 100644 index ab558e57..00000000 --- a/core/modules/rest/tests/src/Kernel/RestLinkManagerTest.php +++ /dev/null @@ -1,85 +0,0 @@ -rebuild(); - } - - /** - * Tests that type hooks work as expected. - */ - public function testRestLinkManagers() { - \Drupal::moduleHandler()->invoke('rest', 'install'); - /* @var \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_manager */ - $type_manager = \Drupal::service('rest.link_manager.type'); - $base = Url::fromRoute('', [], ['absolute' => TRUE])->toString(); - $link = $type_manager->getTypeUri('node', 'page'); - $this->assertEqual($link, $base . 'rest/type/node/page'); - // Now with optional context. - $link = $type_manager->getTypeUri('node', 'page', ['rest_test' => TRUE]); - $this->assertEqual($link, 'rest_test_type'); - - /* @var \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_manager */ - $relation_manager = \Drupal::service('rest.link_manager.relation'); - $link = $relation_manager->getRelationUri('node', 'page', 'field_ref'); - $this->assertEqual($link, $base . 'rest/relation/node/page/field_ref'); - // Now with optional context. - $link = $relation_manager->getRelationUri('node', 'page', 'foobar', ['rest_test' => TRUE]); - $this->assertEqual($link, 'rest_test_relation'); - } - - /** - * Tests that type hooks work as expected even without install hook. - */ - public function testRestLinkManagersNoInstallHook() { - /* @var \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_manager */ - $type_manager = \Drupal::service('rest.link_manager.type'); - $base = Url::fromRoute('', [], ['absolute' => TRUE])->toString(); - $link = $type_manager->getTypeUri('node', 'page'); - $this->assertEqual($link, $base . 'rest/type/node/page'); - // Now with optional context. - $link = $type_manager->getTypeUri('node', 'page', ['rest_test' => TRUE]); - $this->assertEqual($link, 'rest_test_type'); - - /* @var \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_manager */ - $relation_manager = \Drupal::service('rest.link_manager.relation'); - $link = $relation_manager->getRelationUri('node', 'page', 'field_ref'); - $this->assertEqual($link, $base . 'rest/relation/node/page/field_ref'); - // Now with optional context. - $link = $relation_manager->getRelationUri('node', 'page', 'foobar', ['rest_test' => TRUE]); - $this->assertEqual($link, 'rest_test_relation'); - } - - /** - * Tests \Drupal\rest\LinkManager\LinkManager::setLinkDomain(). - */ - public function testRestLinkManagersSetLinkDomain() { - /* @var \Drupal\rest\LinkManager\LinkManager $link_manager */ - $link_manager = \Drupal::service('rest.link_manager'); - $link_manager->setLinkDomain('http://example.com/'); - $link = $link_manager->getTypeUri('node', 'page'); - $this->assertEqual($link, 'http://example.com/rest/type/node/page'); - $link = $link_manager->getRelationUri('node', 'page', 'field_ref'); - $this->assertEqual($link, 'http://example.com/rest/relation/node/page/field_ref'); - } - -} diff --git a/core/modules/rest/tests/src/Kernel/Views/RestExportAuthTest.php b/core/modules/rest/tests/src/Kernel/Views/RestExportAuthTest.php new file mode 100644 index 00000000..9d32f7fc --- /dev/null +++ b/core/modules/rest/tests/src/Kernel/Views/RestExportAuthTest.php @@ -0,0 +1,59 @@ +installConfig(['user']); + } + + /** + * Ensures that rest export auth settings are automatically corrected. + * + * @see rest_update_8401() + * @see rest_views_presave() + * @see \Drupal\rest\Tests\Update\RestExportAuthCorrectionUpdateTest + */ + public function testAuthCorrection() { + // Get particular view. + $view = \Drupal::entityTypeManager() + ->getStorage('view') + ->load('rest_export_with_authorization_correction'); + $displays = $view->get('display'); + $this->assertSame($displays['rest_export_1']['display_options']['auth'], ['cookie'], 'Cookie is used for authentication'); + } + +} diff --git a/core/modules/rest/tests/src/Unit/CollectRoutesTest.php b/core/modules/rest/tests/src/Unit/CollectRoutesTest.php index c55ea3bb..3b1c1f7f 100644 --- a/core/modules/rest/tests/src/Unit/CollectRoutesTest.php +++ b/core/modules/rest/tests/src/Unit/CollectRoutesTest.php @@ -39,18 +39,18 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); - $this->view = $this->getMock('\Drupal\views\Entity\View', array('initHandlers'), array( - array('id' => 'test_view'), + $this->view = $this->getMock('\Drupal\views\Entity\View', ['initHandlers'], [ + ['id' => 'test_view'], 'view', - )); + ]); - $view_executable = $this->getMock('\Drupal\views\ViewExecutable', array('initHandlers', 'getTitle'), array(), '', FALSE); + $view_executable = $this->getMock('\Drupal\views\ViewExecutable', ['initHandlers', 'getTitle'], [], '', FALSE); $view_executable->expects($this->any()) ->method('getTitle') ->willReturn('View title'); $view_executable->storage = $this->view; - $view_executable->argument = array(); + $view_executable->argument = []; $display_manager = $this->getMockBuilder('\Drupal\views\Plugin\ViewsPluginManager') ->disableOriginalConstructor() @@ -86,21 +86,21 @@ protected function setUp() { \Drupal::setContainer($container); - $this->restExport = RestExport::create($container, array(), "test_routes", array()); + $this->restExport = RestExport::create($container, [], "test_routes", []); $this->restExport->view = $view_executable; // Initialize a display. - $this->restExport->display = array('id' => 'page_1'); + $this->restExport->display = ['id' => 'page_1']; // Set the style option. - $this->restExport->setOption('style', array('type' => 'serializer')); + $this->restExport->setOption('style', ['type' => 'serializer']); // Set the auth option. $this->restExport->setOption('auth', ['basic_auth']); $display_manager->expects($this->once()) ->method('getDefinition') - ->will($this->returnValue(array('id' => 'test', 'provider' => 'test'))); + ->will($this->returnValue(['id' => 'test', 'provider' => 'test'])); $none = $this->getMockBuilder('\Drupal\views\Plugin\views\access\None') ->disableOriginalConstructor() @@ -110,11 +110,11 @@ protected function setUp() { ->method('createInstance') ->will($this->returnValue($none)); - $style_plugin = $this->getMock('\Drupal\rest\Plugin\views\style\Serializer', array('getFormats', 'init'), array(), '', FALSE); + $style_plugin = $this->getMock('\Drupal\rest\Plugin\views\style\Serializer', ['getFormats', 'init'], [], '', FALSE); $style_plugin->expects($this->once()) ->method('getFormats') - ->will($this->returnValue(array('json'))); + ->will($this->returnValue(['json'])); $style_plugin->expects($this->once()) ->method('init') @@ -141,8 +141,8 @@ public function testRoutesRequirements() { $requirements_1 = $this->routes->get('test_1')->getRequirements(); $requirements_2 = $this->routes->get('view.test_view.page_1')->getRequirements(); - $this->assertEquals(count($requirements_1), 0, 'First route has no requirement.'); - $this->assertEquals(count($requirements_2), 2, 'Views route with rest export had the format and method requirements added.'); + $this->assertEquals(0, count($requirements_1), 'First route has no requirement.'); + $this->assertEquals(1, count($requirements_2), 'Views route with rest export had the format requirement added.'); // Check auth options. $auth = $this->routes->get('view.test_view.page_1')->getOption('_auth'); diff --git a/core/modules/rest/tests/src/Unit/EntityResourceValidationTraitTest.php b/core/modules/rest/tests/src/Unit/EntityResourceValidationTraitTest.php new file mode 100644 index 00000000..8c9758e8 --- /dev/null +++ b/core/modules/rest/tests/src/Unit/EntityResourceValidationTraitTest.php @@ -0,0 +1,72 @@ +getMockForTrait('Drupal\rest\Plugin\rest\resource\EntityResourceValidationTrait'); + + $method = new \ReflectionMethod($trait, 'validate'); + $method->setAccessible(TRUE); + + $violations = $this->prophesize(EntityConstraintViolationList::class); + $violations->filterByFieldAccess()->shouldBeCalled()->willReturn([]); + $violations->count()->shouldBeCalled()->willReturn(0); + + $entity = $this->prophesize(Node::class); + $entity->validate()->shouldBeCalled()->willReturn($violations->reveal()); + + $method->invoke($trait, $entity->reveal()); + } + + /** + * @covers ::validate + */ + public function testFailedValidate() { + $violation1 = $this->prophesize(ConstraintViolationInterface::class); + $violation1->getPropertyPath()->willReturn('property_path'); + $violation1->getMessage()->willReturn('message'); + + $violation2 = $this->prophesize(ConstraintViolationInterface::class); + $violation2->getPropertyPath()->willReturn('property_path'); + $violation2->getMessage()->willReturn('message'); + + $entity = $this->prophesize(User::class); + + $violations = $this->getMockBuilder(EntityConstraintViolationList::class) + ->setConstructorArgs([$entity->reveal(), [$violation1->reveal(), $violation2->reveal()]]) + ->setMethods(['filterByFieldAccess']) + ->getMock(); + + $violations->expects($this->once()) + ->method('filterByFieldAccess') + ->will($this->returnValue([])); + + $entity->validate()->willReturn($violations); + + $trait = $this->getMockForTrait('Drupal\rest\Plugin\rest\resource\EntityResourceValidationTrait'); + + $method = new \ReflectionMethod($trait, 'validate'); + $method->setAccessible(TRUE); + + $this->setExpectedException(UnprocessableEntityHttpException::class); + + $method->invoke($trait, $entity->reveal()); + } + +} diff --git a/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php b/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php new file mode 100644 index 00000000..d09fdced --- /dev/null +++ b/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php @@ -0,0 +1,371 @@ + 'restplugin'], ['_format' => 'json'])); + + $handler_response = new ResourceResponse($data); + $resource_response_subscriber = $this->getFunctioningResourceResponseSubscriber($route_match); + $event = new FilterResponseEvent( + $this->prophesize(HttpKernelInterface::class)->reveal(), + $request, + HttpKernelInterface::MASTER_REQUEST, + $handler_response + ); + $resource_response_subscriber->onResponse($event); + + // Content is a serialized version of the data we provided. + $this->assertEquals($expected_response !== FALSE ? $expected_response : Json::encode($data), $event->getResponse()->getContent()); + } + + public function providerTestSerialization() { + return [ + // The default data for \Drupal\rest\ResourceResponse. + 'default' => [NULL, ''], + 'empty string' => [''], + 'simple string' => ['string'], + 'complex string' => ['Complex \ string $%^&@ with unicode ΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΣὨ'], + 'empty array' => [[]], + 'numeric array' => [['test']], + 'associative array' => [['test' => 'foobar']], + 'boolean true' => [TRUE], + 'boolean false' => [FALSE], + // @todo Not supported. https://www.drupal.org/node/2427811 + // [new \stdClass()], + // [(object) ['test' => 'foobar']], + ]; + } + + /** + * @covers ::getResponseFormat + * + * Note this does *not* need to test formats being requested that are not + * accepted by the server, because the routing system would have already + * prevented those from reaching the controller. + * + * @dataProvider providerTestResponseFormat + */ + public function testResponseFormat($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_format, $expected_response_content_type, $expected_response_content) { + foreach ($request_headers as $key => $value) { + unset($request_headers[$key]); + $key = strtoupper(str_replace('-', '_', $key)); + $request_headers[$key] = $value; + } + + foreach ($methods as $method) { + $request = Request::create('/rest/test', $method, [], [], [], $request_headers, $request_body); + // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care + // of this so we'll hard code it here. + if ($request_format) { + $request->setRequestFormat($request_format); + } + $route_requirement_key_format = $request->isMethodCacheable() ? '_format' : '_content_type_format'; + $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $this->randomMachineName()], [$route_requirement_key_format => implode('|', $supported_formats)])); + + $resource_response_subscriber = new ResourceResponseSubscriber( + $this->prophesize(SerializerInterface::class)->reveal(), + $this->prophesize(RendererInterface::class)->reveal(), + $route_match + ); + + $this->assertSame($expected_response_format, $resource_response_subscriber->getResponseFormat($route_match, $request)); + } + } + + /** + * @covers ::onResponse + * @covers ::getResponseFormat + * @covers ::renderResponseBody + * @covers ::flattenResponse + * + * @dataProvider providerTestResponseFormat + */ + public function testOnResponseWithCacheableResponse($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_format, $expected_response_content_type, $expected_response_content) { + $rest_config_name = $this->randomMachineName(); + + foreach ($request_headers as $key => $value) { + unset($request_headers[$key]); + $key = strtoupper(str_replace('-', '_', $key)); + $request_headers[$key] = $value; + } + + foreach ($methods as $method) { + $request = Request::create('/rest/test', $method, [], [], [], $request_headers, $request_body); + // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care + // of this so we'll hard code it here. + if ($request_format) { + $request->setRequestFormat($request_format); + } + $route_requirement_key_format = $request->isMethodCacheable() ? '_format' : '_content_type_format'; + $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $rest_config_name], [$route_requirement_key_format => implode('|', $supported_formats)])); + + // The RequestHandler must return a ResourceResponseInterface object. + $handler_response = new ResourceResponse($method !== 'DELETE' ? ['REST' => 'Drupal'] : NULL); + $this->assertInstanceOf(ResourceResponseInterface::class, $handler_response); + $this->assertInstanceOf(CacheableResponseInterface::class, $handler_response); + + // The ResourceResponseSubscriber must then generate a response body and + // transform it to a plain CacheableResponse object. + $resource_response_subscriber = $this->getFunctioningResourceResponseSubscriber($route_match); + $event = new FilterResponseEvent( + $this->prophesize(HttpKernelInterface::class)->reveal(), + $request, + HttpKernelInterface::MASTER_REQUEST, + $handler_response + ); + $resource_response_subscriber->onResponse($event); + $final_response = $event->getResponse(); + $this->assertNotInstanceOf(ResourceResponseInterface::class, $final_response); + $this->assertInstanceOf(CacheableResponseInterface::class, $final_response); + $this->assertSame($expected_response_content_type, $final_response->headers->get('Content-Type')); + $this->assertEquals($expected_response_content, $final_response->getContent()); + } + } + + /** + * @covers ::onResponse + * @covers ::getResponseFormat + * @covers ::renderResponseBody + * @covers ::flattenResponse + * + * @dataProvider providerTestResponseFormat + */ + public function testOnResponseWithUncacheableResponse($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_format, $expected_response_content_type, $expected_response_content) { + $rest_config_name = $this->randomMachineName(); + + foreach ($request_headers as $key => $value) { + unset($request_headers[$key]); + $key = strtoupper(str_replace('-', '_', $key)); + $request_headers[$key] = $value; + } + + foreach ($methods as $method) { + $request = Request::create('/rest/test', $method, [], [], [], $request_headers, $request_body); + // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care + // of this so we'll hard code it here. + if ($request_format) { + $request->setRequestFormat($request_format); + } + $route_requirement_key_format = $request->isMethodCacheable() ? '_format' : '_content_type_format'; + $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $rest_config_name], [$route_requirement_key_format => implode('|', $supported_formats)])); + + // The RequestHandler must return a ResourceResponseInterface object. + $handler_response = new ModifiedResourceResponse($method !== 'DELETE' ? ['REST' => 'Drupal'] : NULL); + $this->assertInstanceOf(ResourceResponseInterface::class, $handler_response); + $this->assertNotInstanceOf(CacheableResponseInterface::class, $handler_response); + + // The ResourceResponseSubscriber must then generate a response body and + // transform it to a plain Response object. + $resource_response_subscriber = $this->getFunctioningResourceResponseSubscriber($route_match); + $event = new FilterResponseEvent( + $this->prophesize(HttpKernelInterface::class)->reveal(), + $request, + HttpKernelInterface::MASTER_REQUEST, + $handler_response + ); + $resource_response_subscriber->onResponse($event); + $final_response = $event->getResponse(); + $this->assertNotInstanceOf(ResourceResponseInterface::class, $final_response); + $this->assertNotInstanceOf(CacheableResponseInterface::class, $final_response); + $this->assertSame($expected_response_content_type, $final_response->headers->get('Content-Type')); + $this->assertEquals($expected_response_content, $final_response->getContent()); + } + } + + /** + * @return array + * 0. methods to test + * 1. supported formats for route requirements + * 2. request format + * 3. request headers + * 4. request body + * 5. expected response format + * 6. expected response content type + * 7. expected response body + */ + public function providerTestResponseFormat() { + $json_encoded = Json::encode(['REST' => 'Drupal']); + $xml_encoded = "\nDrupal\n"; + + $safe_method_test_cases = [ + 'safe methods: client requested format (JSON)' => [ + // @todo add 'HEAD' in https://www.drupal.org/node/2752325 + ['GET'], + ['xml', 'json'], + 'json', + [], + NULL, + 'json', + 'application/json', + $json_encoded, + ], + 'safe methods: client requested format (XML)' => [ + // @todo add 'HEAD' in https://www.drupal.org/node/2752325 + ['GET'], + ['xml', 'json'], + 'xml', + [], + NULL, + 'xml', + 'text/xml', + $xml_encoded, + ], + 'safe methods: client requested no format: response should use the first configured format (JSON)' => [ + // @todo add 'HEAD' in https://www.drupal.org/node/2752325 + ['GET'], + ['json', 'xml'], + FALSE, + [], + NULL, + 'json', + 'application/json', + $json_encoded, + ], + 'safe methods: client requested no format: response should use the first configured format (XML)' => [ + // @todo add 'HEAD' in https://www.drupal.org/node/2752325 + ['GET'], + ['xml', 'json'], + FALSE, + [], + NULL, + 'xml', + 'text/xml', + $xml_encoded, + ], + ]; + + $unsafe_method_bodied_test_cases = [ + 'unsafe methods with response (POST, PATCH): client requested no format, response should use request body format (JSON)' => [ + ['POST', 'PATCH'], + ['xml', 'json'], + FALSE, + ['Content-Type' => 'application/json'], + $json_encoded, + 'json', + 'application/json', + $json_encoded, + ], + 'unsafe methods with response (POST, PATCH): client requested no format, response should use request body format (XML)' => [ + ['POST', 'PATCH'], + ['xml', 'json'], + FALSE, + ['Content-Type' => 'text/xml'], + $xml_encoded, + 'xml', + 'text/xml', + $xml_encoded, + ], + 'unsafe methods with response (POST, PATCH): client requested format other than request body format (JSON): response format should use requested format (XML)' => [ + ['POST', 'PATCH'], + ['xml', 'json'], + 'xml', + ['Content-Type' => 'application/json'], + $json_encoded, + 'xml', + 'text/xml', + $xml_encoded, + ], + 'unsafe methods with response (POST, PATCH): client requested format other than request body format (XML), but is allowed for the request body (JSON)' => [ + ['POST', 'PATCH'], + ['xml', 'json'], + 'json', + ['Content-Type' => 'text/xml'], + $xml_encoded, + 'json', + 'application/json', + $json_encoded, + ], + ]; + + $unsafe_method_bodyless_test_cases = [ + 'unsafe methods with response bodies (DELETE): client requested no format, response should have no format' => [ + ['DELETE'], + ['xml', 'json'], + FALSE, + ['Content-Type' => 'application/json'], + NULL, + 'xml', + NULL, + '', + ], + 'unsafe methods with response bodies (DELETE): client requested format (XML), response should have no format' => [ + ['DELETE'], + ['xml', 'json'], + 'xml', + ['Content-Type' => 'application/json'], + NULL, + 'xml', + NULL, + '', + ], + 'unsafe methods with response bodies (DELETE): client requested format (JSON), response should have no format' => [ + ['DELETE'], + ['xml', 'json'], + 'json', + ['Content-Type' => 'application/json'], + NULL, + 'json', + NULL, + '', + ], + ]; + + return $safe_method_test_cases + $unsafe_method_bodied_test_cases + $unsafe_method_bodyless_test_cases; + } + + /** + * @return \Drupal\rest\EventSubscriber\ResourceResponseSubscriber + */ + protected function getFunctioningResourceResponseSubscriber(RouteMatchInterface $route_match) { + // Create a dummy of the renderer service. + $renderer = $this->prophesize(RendererInterface::class); + $renderer->executeInRenderContext(Argument::type(RenderContext::class), Argument::type('callable')) + ->will(function ($args) { + $callable = $args[1]; + return $callable(); + }); + + // Instantiate the ResourceResponseSubscriber we will test. + $resource_response_subscriber = new ResourceResponseSubscriber( + new Serializer([], [new JsonEncoder(), new XmlEncoder()]), + $renderer->reveal(), + $route_match + ); + + return $resource_response_subscriber; + } + +} diff --git a/core/modules/search/migration_templates/d6_search_settings.yml b/core/modules/search/migration_templates/d6_search_settings.yml index 28f86006..1500a3f0 100644 --- a/core/modules/search/migration_templates/d6_search_settings.yml +++ b/core/modules/search/migration_templates/d6_search_settings.yml @@ -10,6 +10,7 @@ source: - minimum_word_size - overlap_cjk - search_cron_limit + source_module: search process: 'index/minimum_word_size': minimum_word_size 'index/overlap_cjk': overlap_cjk diff --git a/core/modules/search/migration_templates/d7_search_settings.yml b/core/modules/search/migration_templates/d7_search_settings.yml index 57db8b94..74f0ef71 100644 --- a/core/modules/search/migration_templates/d7_search_settings.yml +++ b/core/modules/search/migration_templates/d7_search_settings.yml @@ -13,6 +13,7 @@ source: - search_tag_weights - search_and_or_limit - search_default_module + source_module: search process: 'index/minimum_word_size': minimum_word_size 'index/overlap_cjk': overlap_cjk diff --git a/core/modules/search/migration_templates/search_page.yml b/core/modules/search/migration_templates/search_page.yml index 8ddc02ac..fc9b410a 100644 --- a/core/modules/search/migration_templates/search_page.yml +++ b/core/modules/search/migration_templates/search_page.yml @@ -16,6 +16,7 @@ source: id: node_search path: node plugin: node_search + source_module: search process: id: 'constants/id' path: 'constants/path' diff --git a/core/modules/search/search.info.yml b/core/modules/search/search.info.yml index 18bb86d8..3ba0e8df 100644 --- a/core/modules/search/search.info.yml +++ b/core/modules/search/search.info.yml @@ -6,8 +6,8 @@ package: Core # core: 8.x configure: entity.search_page.collection -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/search/search.install b/core/modules/search/search.install index f920aa5a..d55c4d2f 100644 --- a/core/modules/search/search.install +++ b/core/modules/search/search.install @@ -9,116 +9,116 @@ * Implements hook_schema(). */ function search_schema() { - $schema['search_dataset'] = array( + $schema['search_dataset'] = [ 'description' => 'Stores items that will be searched.', - 'fields' => array( - 'sid' => array( + 'fields' => [ + 'sid' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'Search item ID, e.g. node ID for nodes.', - ), - 'langcode' => array( + ], + 'langcode' => [ 'type' => 'varchar_ascii', 'length' => '12', 'not null' => TRUE, 'description' => 'The {languages}.langcode of the item variant.', 'default' => '', - ), - 'type' => array( + ], + 'type' => [ 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'description' => 'Type of item, e.g. node.', - ), - 'data' => array( + ], + 'data' => [ 'type' => 'text', 'not null' => TRUE, 'size' => 'big', 'description' => 'List of space-separated words from the item.', - ), - 'reindex' => array( + ], + 'reindex' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'Set to force node reindexing.', - ), - ), - 'primary key' => array('sid', 'langcode', 'type'), - ); + ], + ], + 'primary key' => ['sid', 'langcode', 'type'], + ]; - $schema['search_index'] = array( + $schema['search_index'] = [ 'description' => 'Stores the search index, associating words, items and scores.', - 'fields' => array( - 'word' => array( + 'fields' => [ + 'word' => [ 'type' => 'varchar', 'length' => 50, 'not null' => TRUE, 'default' => '', 'description' => 'The {search_total}.word that is associated with the search item.', - ), - 'sid' => array( + ], + 'sid' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'The {search_dataset}.sid of the searchable item to which the word belongs.', - ), - 'langcode' => array( + ], + 'langcode' => [ 'type' => 'varchar_ascii', 'length' => '12', 'not null' => TRUE, 'description' => 'The {languages}.langcode of the item variant.', 'default' => '', - ), - 'type' => array( + ], + 'type' => [ 'type' => 'varchar_ascii', 'length' => 64, 'not null' => TRUE, 'description' => 'The {search_dataset}.type of the searchable item to which the word belongs.', - ), - 'score' => array( + ], + 'score' => [ 'type' => 'float', 'not null' => FALSE, 'description' => 'The numeric score of the word, higher being more important.', - ), - ), - 'indexes' => array( - 'sid_type' => array('sid', 'langcode', 'type'), - ), - 'foreign keys' => array( - 'search_dataset' => array( + ], + ], + 'indexes' => [ + 'sid_type' => ['sid', 'langcode', 'type'], + ], + 'foreign keys' => [ + 'search_dataset' => [ 'table' => 'search_dataset', - 'columns' => array( + 'columns' => [ 'sid' => 'sid', 'langcode' => 'langcode', 'type' => 'type', - ), - ), - ), - 'primary key' => array('word', 'sid', 'langcode', 'type'), - ); + ], + ], + ], + 'primary key' => ['word', 'sid', 'langcode', 'type'], + ]; - $schema['search_total'] = array( + $schema['search_total'] = [ 'description' => 'Stores search totals for words.', - 'fields' => array( - 'word' => array( + 'fields' => [ + 'word' => [ 'description' => 'Primary Key: Unique word in the search index.', 'type' => 'varchar', 'length' => 50, 'not null' => TRUE, 'default' => '', - ), - 'count' => array( + ], + 'count' => [ 'description' => "The count of the word in the index using Zipf's law to equalize the probability distribution.", 'type' => 'float', 'not null' => FALSE, - ), - ), - 'primary key' => array('word'), - ); + ], + ], + 'primary key' => ['word'], + ]; return $schema; } @@ -129,7 +129,7 @@ function search_schema() { * For the Status Report, return information about search index status. */ function search_requirements($phase) { - $requirements = array(); + $requirements = []; if ($phase == 'runtime') { $remaining = 0; @@ -145,11 +145,11 @@ function search_requirements($phase) { // Use floor() to calculate the percentage, so if it is not quite 100%, it // will show as 99%, to indicate "almost done". $percent = ($total > 0 ? floor(100 * $done / $total) : 100); - $requirements['search_status'] = array( + $requirements['search_status'] = [ 'title' => t('Search index progress'), - 'value' => t('@percent% (@remaining remaining)', array('@percent' => $percent, '@remaining' => $remaining)), + 'value' => t('@percent% (@remaining remaining)', ['@percent' => $percent, '@remaining' => $remaining]), 'severity' => REQUIREMENT_INFO, - ); + ]; } return $requirements; diff --git a/core/modules/search/search.module b/core/modules/search/search.module index c36aa443..33171ae0 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -8,6 +8,7 @@ use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; use Drupal\Core\Cache\Cache; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; @@ -74,20 +75,20 @@ function search_help($route_name, RouteMatchInterface $route_match) { case 'help.page.search': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '
    '; + $output .= '

    ' . t('The Search module provides the ability to set up search pages based on plugins provided by other modules. In Drupal core, there are two page-type plugins: the Content page type provides keyword searching for content managed by the Node module, and the Users page type provides keyword searching for registered users. Contributed modules may provide other page-type plugins. For more information, see the online documentation for the Search module.', [':search-module' => 'https://www.drupal.org/documentation/modules/search']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Configuring search pages') . '
    '; - $output .= '
    ' . t('To configure search pages, visit the Search pages page. In the Search pages section, you can add a new search page, edit the configuration of existing search pages, enable and disable search pages, and choose the default search page. Each enabled search page has a URL path starting with search, and each will appear as a tab or local task link on the search page; you can configure the text that is shown in the tab. In addition, some search page plugins have additional settings that you can configure for each search page.', array(':search-settings' => \Drupal::url('entity.search_page.collection'), ':search-url' => \Drupal::url('search.view'))) . '
    '; + $output .= '
    ' . t('To configure search pages, visit the Search pages page. In the Search pages section, you can add a new search page, edit the configuration of existing search pages, enable and disable search pages, and choose the default search page. Each enabled search page has a URL path starting with search, and each will appear as a tab or local task link on the search page; you can configure the text that is shown in the tab. In addition, some search page plugins have additional settings that you can configure for each search page.', [':search-settings' => \Drupal::url('entity.search_page.collection'), ':search-url' => \Drupal::url('search.view')]) . '
    '; $output .= '
    ' . t('Managing the search index') . '
    '; - $output .= '
    ' . t('Some search page plugins, such as the core Content search page, index searchable text using the Drupal core search index, and will not work unless content is indexed. Indexing is done during cron runs, so it requires a cron maintenance task to be set up. There are also several settings affecting indexing that can be configured on the Search pages page: the number of items to index per cron run, the minimum word length to index, and how to handle Chinese, Japanese, and Korean characters.', array(':cron' => \Drupal::url('system.cron_settings'), ':search-settings' => \Drupal::url('entity.search_page.collection'))) . '
    '; - $output .= '
    ' . t('Modules providing search page plugins generally ensure that content-related actions on your site (creating, editing, or deleting content and comments) automatically cause affected content items to be marked for indexing or reindexing at the next cron run. When content is marked for reindexing, the previous content remains in the index until cron runs, at which time it is replaced by the new content. However, there are some actions related to the structure of your site that do not cause affected content to be marked for reindexing. Examples of structure-related actions that affect content include deleting or editing taxonomy terms, enabling or disabling modules that add text to content (such as Taxonomy, Comment, and field-providing modules), and modifying the fields or display parameters of your content types. If you take one of these actions and you want to ensure that the search index is updated to reflect your changed site structure, you can mark all content for reindexing by clicking the "Re-index site" button on the Search pages page. If you have a lot of content on your site, it may take several cron runs for the content to be reindexed.', array(':search-settings' => \Drupal::url('entity.search_page.collection'))) . '
    '; + $output .= '
    ' . t('Some search page plugins, such as the core Content search page, index searchable text using the Drupal core search index, and will not work unless content is indexed. Indexing is done during cron runs, so it requires a cron maintenance task to be set up. There are also several settings affecting indexing that can be configured on the Search pages page: the number of items to index per cron run, the minimum word length to index, and how to handle Chinese, Japanese, and Korean characters.', [':cron' => \Drupal::url('system.cron_settings'), ':search-settings' => \Drupal::url('entity.search_page.collection')]) . '
    '; + $output .= '
    ' . t('Modules providing search page plugins generally ensure that content-related actions on your site (creating, editing, or deleting content and comments) automatically cause affected content items to be marked for indexing or reindexing at the next cron run. When content is marked for reindexing, the previous content remains in the index until cron runs, at which time it is replaced by the new content. However, there are some actions related to the structure of your site that do not cause affected content to be marked for reindexing. Examples of structure-related actions that affect content include deleting or editing taxonomy terms, enabling or disabling modules that add text to content (such as Taxonomy, Comment, and field-providing modules), and modifying the fields or display parameters of your content types. If you take one of these actions and you want to ensure that the search index is updated to reflect your changed site structure, you can mark all content for reindexing by clicking the "Re-index site" button on the Search pages page. If you have a lot of content on your site, it may take several cron runs for the content to be reindexed.', [':search-settings' => \Drupal::url('entity.search_page.collection')]) . '
    '; $output .= '
    ' . t('Displaying the Search block') . '
    '; - $output .= '
    ' . t('The Search module includes a block, which can be enabled and configured on the Block layout page, if you have the Block module enabled; the default block title is Search, and it is the Search form block in the Forms category, if you wish to add another instance. The block is available to users with the Use search permission, and it performs a search using the configured default search page.', array(':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#', ':search_permission' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-search')))) . '
    '; + $output .= '
    ' . t('The Search module includes a block, which can be enabled and configured on the Block layout page, if you have the Block module enabled; the default block title is Search, and it is the Search form block in the Forms category, if you wish to add another instance. The block is available to users with the Use search permission, and it performs a search using the configured default search page.', [':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#', ':search_permission' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-search'])]) . '
    '; $output .= '
    ' . t('Searching your site') . '
    '; - $output .= '
    ' . t('Users with Use search permission can use the Search block and Search page. Users with the View published content permission can use configured search pages of type Content to search for content containing exact keywords; in addition, users with Use advanced search permission can use more complex search filtering. Users with the View user information permission can use configured search pages of type Users to search for active users containing the keyword anywhere in the username, and users with the Administer users permission can search for active and blocked users, by email address or username keyword.', array(':search' => \Drupal::url('search.view'), ':search_permission' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-search')), ':node_permission' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-node')), ':user_permission' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-user')))) . '
    '; + $output .= '
    ' . t('Users with Use search permission can use the Search block and Search page. Users with the View published content permission can use configured search pages of type Content to search for content containing exact keywords; in addition, users with Use advanced search permission can use more complex search filtering. Users with the View user information permission can use configured search pages of type Users to search for active users containing the keyword anywhere in the username, and users with the Administer users permission can search for active and blocked users, by email address or username keyword.', [':search' => \Drupal::url('search.view'), ':search_permission' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-search']), ':node_permission' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-node']), ':user_permission' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-user'])]) . '
    '; $output .= '
    ' . t('Extending the Search module') . '
    '; - $output .= '
    ' . t('By default, the Search module only supports exact keyword matching in content searches. You can modify this behavior by installing a language-specific stemming module for your language (such as Porter Stemmer for American English), which allows words such as walk, walking, and walked to be matched in the Search module. Another approach is to use a third-party search technology with stemming or partial word matching features built in, such as Apache Solr or Sphinx. There are also contributed modules that provide additional search pages. These and other search-related contributed modules can be downloaded by visiting Drupal.org.', array(':contrib-search' => 'https://www.drupal.org/project/project_module?f[2]=im_vid_3%3A105', ':porterstemmer_url' => 'https://www.drupal.org/project/porterstemmer', ':solr_url' => 'https://www.drupal.org/project/apachesolr', ':sphinx_url' => 'https://www.drupal.org/project/sphinx')) . '
    '; + $output .= '
    ' . t('By default, the Search module only supports exact keyword matching in content searches. You can modify this behavior by installing a language-specific stemming module for your language (such as Porter Stemmer for American English), which allows words such as walk, walking, and walked to be matched in the Search module. Another approach is to use a third-party search technology with stemming or partial word matching features built in, such as Apache Solr or Sphinx. There are also contributed modules that provide additional search pages. These and other search-related contributed modules can be downloaded by visiting Drupal.org.', [':contrib-search' => 'https://www.drupal.org/project/project_module?f[2]=im_vid_3%3A105', ':porterstemmer_url' => 'https://www.drupal.org/project/porterstemmer', ':solr_url' => 'https://www.drupal.org/project/apachesolr', ':sphinx_url' => 'https://www.drupal.org/project/sphinx']) . '
    '; $output .= '
    '; return $output; } @@ -97,12 +98,12 @@ function search_help($route_name, RouteMatchInterface $route_match) { * Implements hook_theme(). */ function search_theme() { - return array( - 'search_result' => array( - 'variables' => array('result' => NULL, 'plugin_id' => NULL), + return [ + 'search_result' => [ + 'variables' => ['result' => NULL, 'plugin_id' => NULL], 'file' => 'search.pages.inc', - ), - ); + ], + ]; } /** @@ -167,7 +168,7 @@ function search_index_clear($type = NULL, $sid = NULL, $langcode = NULL) { * total counts in the search_total table, and need to be recounted. */ function search_dirty($word = NULL) { - $dirty = &drupal_static(__FUNCTION__, array()); + $dirty = &drupal_static(__FUNCTION__, []); if ($word !== NULL) { $dirty[$word] = TRUE; } @@ -206,19 +207,19 @@ function search_update_totals() { // Update word IDF (Inverse Document Frequency) counts for new/changed words. foreach (search_dirty() as $word => $dummy) { // Get total count - $total = db_query("SELECT SUM(score) FROM {search_index} WHERE word = :word", array(':word' => $word), array('target' => 'replica'))->fetchField(); + $total = db_query("SELECT SUM(score) FROM {search_index} WHERE word = :word", [':word' => $word], ['target' => 'replica'])->fetchField(); // Apply Zipf's law to equalize the probability distribution. $total = log10(1 + 1 / (max(1, $total))); db_merge('search_total') ->key('word', $word) - ->fields(array('count' => $total)) + ->fields(['count' => $total]) ->execute(); } // Find words that were deleted from search_index, but are still in // search_total. We use a LEFT JOIN between the two tables and keep only the // rows which fail to join. - $result = db_query("SELECT t.word AS realword, i.word FROM {search_total} t LEFT JOIN {search_index} i ON t.word = i.word WHERE i.word IS NULL", array(), array('target' => 'replica')); - $or = db_or(); + $result = db_query("SELECT t.word AS realword, i.word FROM {search_total} t LEFT JOIN {search_index} i ON t.word = i.word WHERE i.word IS NULL", [], ['target' => 'replica']); + $or = new Condition('OR'); foreach ($result as $word) { $or->condition('word', $word->realword); } @@ -329,7 +330,7 @@ function search_expand_cjk($matches) { } $tokens = ' '; // Build a FIFO queue of characters. - $chars = array(); + $chars = []; for ($i = 0; $i < $length; $i++) { // Add the next character off the beginning of the string to the queue. $current = Unicode::substr($str, 0, 1); @@ -382,7 +383,7 @@ function search_index_split($text, $langcode = NULL) { function _search_index_truncate(&$text) { // Use a static array to avoid re-truncating text we've done before. // The same words may often be passed in during excerpt generation. - static $truncated = array(); + static $truncated = []; if (isset($truncated[$text])) { $text = $truncated[$text]; return; @@ -408,7 +409,7 @@ function _search_index_truncate(&$text) { */ function search_invoke_preprocess(&$text, $langcode = NULL) { foreach (\Drupal::moduleHandler()->getImplementations('search_preprocess') as $module) { - $text = \Drupal::moduleHandler()->invoke($module, 'search_preprocess', array($text, $langcode)); + $text = \Drupal::moduleHandler()->invoke($module, 'search_preprocess', [$text, $langcode]); } } @@ -437,7 +438,7 @@ function search_index($type, $sid, $langcode, $text) { // Strip off all ignored tags to speed up processing, but insert space before // and after them to keep word boundaries. - $text = str_replace(array('<', '>'), array(' <', '> '), $text); + $text = str_replace(['<', '>'], [' <', '> '], $text); $text = strip_tags($text, '<' . implode('><', array_keys($tags)) . '>'); // Split HTML tags from plain text. @@ -445,14 +446,21 @@ function search_index($type, $sid, $langcode, $text) { // Note: PHP ensures the array consists of alternating delimiters and literals // and begins and ends with a literal (inserting $null as required). - $tag = FALSE; // Odd/even counter. Tag or no tag. - $score = 1; // Starting score per word - $accum = ' '; // Accumulator for cleaned up data - $tagstack = array(); // Stack with open tags - $tagwords = 0; // Counter for consecutive words - $focus = 1; // Focus state - - $scored_words = array(); // Accumulator for words for index + // Odd/even counter. Tag or no tag. + $tag = FALSE; + // Starting score per word. + $score = 1; + // Accumulator for cleaned up data. + $accum = ' '; + // Stack with open tags. + $tagstack = []; + // Counter for consecutive words. + $tagwords = 0; + // Focus state. + $focus = 1; + + // Accumulator for words for index. + $scored_words = []; foreach ($split as $value) { if ($tag) { @@ -464,7 +472,7 @@ function search_index($type, $sid, $langcode, $text) { $tagname = substr($tagname, 1); // If we encounter unexpected tags, reset score to avoid incorrect boosting. if (!count($tagstack) || $tagstack[0] != $tagname) { - $tagstack = array(); + $tagstack = []; $score = 1; } else { @@ -476,7 +484,7 @@ function search_index($type, $sid, $langcode, $text) { if (isset($tagstack[0]) && $tagstack[0] == $tagname) { // None of the tags we look for make sense when nested identically. // If they are, it's probably broken HTML. - $tagstack = array(); + $tagstack = []; $score = 1; } else { @@ -508,7 +516,7 @@ function search_index($type, $sid, $langcode, $text) { $tagwords++; // Too many words inside a single tag probably mean a tag was accidentally left open. if (count($tagstack) && $tagwords >= 15) { - $tagstack = array(); + $tagstack = []; $score = 1; } } @@ -523,13 +531,13 @@ function search_index($type, $sid, $langcode, $text) { // Insert cleaned up data into dataset db_insert('search_dataset') - ->fields(array( + ->fields([ 'sid' => $sid, 'langcode' => $langcode, 'type' => $type, 'data' => $accum, 'reindex' => 0, - )) + ]) ->execute(); // Insert results into search index @@ -538,14 +546,14 @@ function search_index($type, $sid, $langcode, $text) { // appropriately. If not, we create a new record with the appropriate // starting score. db_merge('search_index') - ->keys(array( + ->keys([ 'word' => $word, 'sid' => $sid, 'langcode' => $langcode, 'type' => $type, - )) - ->fields(array('score' => $score)) - ->expression('score', 'score + :score', array(':score' => $score)) + ]) + ->fields(['score' => $score]) + ->expression('score', 'score + :score', [':score' => $score]) ->execute(); search_dirty($word); } @@ -571,7 +579,7 @@ function search_index($type, $sid, $langcode, $text) { */ function search_mark_for_reindex($type = NULL, $sid = NULL, $langcode = NULL) { $query = db_update('search_dataset') - ->fields(array('reindex' => REQUEST_TIME)) + ->fields(['reindex' => REQUEST_TIME]) // Only mark items that were not previously marked for reindex, so that // marked items maintain their priority by request time. ->condition('reindex', 0); @@ -650,14 +658,14 @@ function search_excerpt($keys, $text, $langcode = NULL) { $keys = array_merge($matches[2], $matches[3]); // Prepare text by stripping HTML tags and decoding HTML entities. - $text = strip_tags(str_replace(array('<', '>'), array(' <', '> '), $text)); + $text = strip_tags(str_replace(['<', '>'], [' <', '> '], $text)); $text = Html::decodeEntities($text); $text_length = strlen($text); // Make a list of unique keywords that are actually found in the text, // which could be items in $keys or replacements that are equivalent through // search_simplify(). - $temp_keys = array(); + $temp_keys = []; foreach ($keys as $key) { $key = _search_find_match_with_simplify($key, $text, $boundary_character, $langcode); if (isset($key)) { @@ -672,13 +680,13 @@ function search_excerpt($keys, $text, $langcode = NULL) { // Extract fragments of about 60 characters around keywords, bounded by word // boundary characters. Try to reach 256 characters, using second occurrences // if necessary. - $ranges = array(); + $ranges = []; $length = 0; - $look_start = array(); + $look_start = []; $remaining_keys = $keys; while ($length < 256 && !empty($remaining_keys)) { - $found_keys = array(); + $found_keys = []; foreach ($remaining_keys as $key) { if ($length >= 256) { break; @@ -693,7 +701,7 @@ function search_excerpt($keys, $text, $langcode = NULL) { // See if we can find $key after where we found it the last time. Since // we are requiring a match on a word boundary, make sure $text starts // and ends with a space. - $matches = array(); + $matches = []; if (preg_match('/' . $preceded_by_boundary . $key . $followed_by_boundary . '/iu', ' ' . $text . ' ', $matches, PREG_OFFSET_CAPTURE, $look_start[$key])) { $found_position = $matches[0][1]; $look_start[$key] = $found_position + 1; @@ -741,7 +749,7 @@ function search_excerpt($keys, $text, $langcode = NULL) { ksort($ranges); // Collapse overlapping text ranges into one. The sorting makes it O(n). - $new_ranges = array(); + $new_ranges = []; $max_end = 0; foreach ($ranges as $this_from => $this_to) { $max_end = max($max_end, $this_to); @@ -766,7 +774,7 @@ function search_excerpt($keys, $text, $langcode = NULL) { $new_ranges[$working_from] = $working_to; // Fetch text within the combined ranges we found. - $out = array(); + $out = []; foreach ($new_ranges as $from => $to) { $out[] = substr($text, $from, $to - $from); } @@ -846,7 +854,7 @@ function _search_find_match_with_simplify($key, $text, $boundary, $langcode = NU // Split $text into words, keeping track of where the word boundaries are. $words = preg_split('/' . $boundary . '+/u', $text, NULL, PREG_SPLIT_OFFSET_CAPTURE); // Add an entry pointing to the end of the string, for the loop below. - $words[] = array('', strlen($text)); + $words[] = ['', strlen($text)]; // Using a binary search, find the earliest possible ending position in // $text where it will still match the keyword after applying diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc index a161a9bf..9467dd82 100644 --- a/core/modules/search/search.pages.inc +++ b/core/modules/search/search.pages.inc @@ -12,7 +12,7 @@ use Drupal\Core\Language\LanguageInterface; * Implements hook_theme_suggestions_HOOK(). */ function search_theme_suggestions_search_result(array $variables) { - return array('search_result__' . $variables['plugin_id']); + return ['search_result__' . $variables['plugin_id']]; } /** @@ -42,7 +42,7 @@ function template_preprocess_search_result(&$variables) { $variables['content_attributes']['lang'] = $result['language']; } - $info = array(); + $info = []; if (!empty($result['plugin_id'])) { $info['plugin_id'] = $result['plugin_id']; } @@ -59,9 +59,9 @@ function template_preprocess_search_result(&$variables) { $variables['snippet'] = isset($result['snippet']) ? $result['snippet'] : ''; // Provide separated and grouped meta information.. $variables['info_split'] = $info; - $variables['info'] = array( + $variables['info'] = [ '#type' => 'inline_template', '#template' => '{{ info|safe_join(" - ") }}', - '#context' => array('info' => $info), - ); + '#context' => ['info' => $info], + ]; } diff --git a/core/modules/search/search.routing.yml b/core/modules/search/search.routing.yml index ec273f16..98969a6e 100644 --- a/core/modules/search/search.routing.yml +++ b/core/modules/search/search.routing.yml @@ -37,6 +37,7 @@ entity.search_page.enable: op: 'enable' requirements: _entity_access: 'search_page.update' + _csrf_token: 'TRUE' entity.search_page.disable: path: '/admin/config/search/pages/manage/{search_page}/disable' @@ -45,6 +46,7 @@ entity.search_page.disable: op: 'disable' requirements: _entity_access: 'search_page.disable' + _csrf_token: 'TRUE' entity.search_page.set_default: path: '/admin/config/search/pages/manage/{search_page}/set-default' @@ -52,6 +54,7 @@ entity.search_page.set_default: _controller: '\Drupal\search\Controller\SearchController::setAsDefault' requirements: _entity_access: 'search_page.update' + _csrf_token: 'TRUE' entity.search_page.delete_form: path: '/admin/config/search/pages/manage/{search_page}/delete' diff --git a/core/modules/search/src/Controller/SearchController.php b/core/modules/search/src/Controller/SearchController.php index 3460c320..e0b6466a 100644 --- a/core/modules/search/src/Controller/SearchController.php +++ b/core/modules/search/src/Controller/SearchController.php @@ -5,6 +5,7 @@ use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Render\RendererInterface; +use Drupal\search\Form\SearchPageForm; use Drupal\search\SearchPageInterface; use Drupal\search\SearchPageRepositoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -72,7 +73,7 @@ public static function create(ContainerInterface $container) { * The search form and search results build array. */ public function view(Request $request, SearchPageInterface $entity) { - $build = array(); + $build = []; $plugin = $entity->getPlugin(); // Build the form first, because it may redirect during the submit, @@ -84,17 +85,17 @@ public function view(Request $request, SearchPageInterface $entity) { } $build['#title'] = $plugin->suggestedTitle(); - $build['search_form'] = $this->entityFormBuilder()->getForm($entity, 'search'); + $build['search_form'] = $this->formBuilder()->getForm(SearchPageForm::class, $entity); // Build search results, if keywords or other search parameters are in the // GET parameters. Note that we need to try the search if 'keys' is in // there at all, vs. being empty, due to advanced search. - $results = array(); + $results = []; if ($request->query->has('keys')) { if ($plugin->isSearchExecutable()) { // Log the search. if ($this->config('search.settings')->get('logging')) { - $this->logger->notice('Searched %type for %keys.', array('%keys' => $keys, '%type' => $entity->label())); + $this->logger->notice('Searched %type for %keys.', ['%keys' => $keys, '%type' => $entity->label()]); } // Collect the search results. @@ -108,22 +109,22 @@ public function view(Request $request, SearchPageInterface $entity) { } if (count($results)) { - $build['search_results_title'] = array( + $build['search_results_title'] = [ '#markup' => '

    ' . $this->t('Search results') . '

    ', - ); + ]; } - $build['search_results'] = array( - '#theme' => array('item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'), + $build['search_results'] = [ + '#theme' => ['item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'], '#items' => $results, - '#empty' => array( + '#empty' => [ '#markup' => '

    ' . $this->t('Your search yielded no results.') . '

    ', - ), + ], '#list_type' => 'ol', - '#context' => array( + '#context' => [ 'plugin' => $plugin->getPluginId(), - ), - ); + ], + ]; $this->renderer->addCacheableDependency($build, $entity); if ($plugin instanceof CacheableDependencyInterface) { @@ -138,9 +139,9 @@ public function view(Request $request, SearchPageInterface $entity) { $build['search_results']['#cache']['tags'][] = 'search_index:' . $plugin->getType(); } - $build['pager'] = array( + $build['pager'] = [ '#type' => 'pager', - ); + ]; return $build; } @@ -148,8 +149,6 @@ public function view(Request $request, SearchPageInterface $entity) { /** * Creates a render array for the search help page. * - * @param \Symfony\Component\HttpFoundation\Request $request - * The request object. * @param \Drupal\search\SearchPageInterface $entity * The search page entity. * @@ -157,7 +156,7 @@ public function view(Request $request, SearchPageInterface $entity) { * The search help page. */ public function searchHelp(SearchPageInterface $entity) { - $build = array(); + $build = []; $build['search_help'] = $entity->getPlugin()->getHelp(); @@ -189,7 +188,7 @@ public function redirectSearchPage(SearchPageInterface $entity) { * The title for the search page edit form. */ public function editTitle(SearchPageInterface $search_page) { - return $this->t('Edit %label search page', array('%label' => $search_page->label())); + return $this->t('Edit %label search page', ['%label' => $search_page->label()]); } /** @@ -207,10 +206,10 @@ public function performOperation(SearchPageInterface $search_page, $op) { $search_page->$op()->save(); if ($op == 'enable') { - drupal_set_message($this->t('The %label search page has been enabled.', array('%label' => $search_page->label()))); + drupal_set_message($this->t('The %label search page has been enabled.', ['%label' => $search_page->label()])); } elseif ($op == 'disable') { - drupal_set_message($this->t('The %label search page has been disabled.', array('%label' => $search_page->label()))); + drupal_set_message($this->t('The %label search page has been disabled.', ['%label' => $search_page->label()])); } $url = $search_page->urlInfo('collection'); @@ -230,7 +229,7 @@ public function setAsDefault(SearchPageInterface $search_page) { // Set the default page to this search page. $this->searchPageRepository->setDefaultSearchPage($search_page); - drupal_set_message($this->t('The default search page is now %label. Be sure to check the ordering of your search pages.', array('%label' => $search_page->label()))); + drupal_set_message($this->t('The default search page is now %label. Be sure to check the ordering of your search pages.', ['%label' => $search_page->label()])); return $this->redirect('entity.search_page.collection'); } diff --git a/core/modules/search/src/Entity/SearchPage.php b/core/modules/search/src/Entity/SearchPage.php index 1cb2f892..85ddc260 100644 --- a/core/modules/search/src/Entity/SearchPage.php +++ b/core/modules/search/src/Entity/SearchPage.php @@ -22,7 +22,6 @@ * "form" = { * "add" = "Drupal\search\Form\SearchPageAddForm", * "edit" = "Drupal\search\Form\SearchPageEditForm", - * "search" = "Drupal\search\Form\SearchPageForm", * "delete" = "Drupal\Core\Entity\EntityDeleteForm" * } * }, @@ -73,7 +72,7 @@ class SearchPage extends ConfigEntityBase implements SearchPageInterface, Entity * * @var array */ - protected $configuration = array(); + protected $configuration = []; /** * The search plugin ID. @@ -129,7 +128,7 @@ protected function getPluginCollection() { * {@inheritdoc} */ public function getPluginCollections() { - return array('configuration' => $this->getPluginCollection()); + return ['configuration' => $this->getPluginCollection()]; } /** diff --git a/core/modules/search/src/Form/SearchBlockForm.php b/core/modules/search/src/Form/SearchBlockForm.php index cd198fd7..7a9405fd 100644 --- a/core/modules/search/src/Form/SearchBlockForm.php +++ b/core/modules/search/src/Form/SearchBlockForm.php @@ -75,10 +75,18 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { // Set up the form to submit using GET to the correct search page. $entity_id = $this->searchPageRepository->getDefaultSearchPage(); + + // SearchPageRepository::getDefaultSearchPage() depends on search.settings. + // The dependency needs to be added before the conditional return, otherwise + // the block would get cached without the necessary cacheablity metadata in + // case there is no default search page and would not be invalidated if that + // changes. + $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings')); + if (!$entity_id) { - $form['message'] = array( + $form['message'] = [ '#markup' => $this->t('Search is currently disabled'), - ); + ]; return $form; } @@ -86,25 +94,22 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['#action'] = $this->url($route); $form['#method'] = 'get'; - $form['keys'] = array( + $form['keys'] = [ '#type' => 'search', '#title' => $this->t('Search'), '#title_display' => 'invisible', '#size' => 15, '#default_value' => '', - '#attributes' => array('title' => $this->t('Enter the terms you wish to search for.')), - ); + '#attributes' => ['title' => $this->t('Enter the terms you wish to search for.')], + ]; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Search'), // Prevent op from showing up in the query string. '#name' => '', - ); - - // SearchPageRepository::getDefaultSearchPage() depends on search.settings. - $this->renderer->addCacheableDependency($form, $this->configFactory->get('search.settings')); + ]; return $form; } diff --git a/core/modules/search/src/Form/SearchPageAddForm.php b/core/modules/search/src/Form/SearchPageAddForm.php index a97f1fa5..d5bc7850 100644 --- a/core/modules/search/src/Form/SearchPageAddForm.php +++ b/core/modules/search/src/Form/SearchPageAddForm.php @@ -39,7 +39,7 @@ public function save(array $form, FormStateInterface $form_state) { parent::save($form, $form_state); - drupal_set_message($this->t('The %label search page has been added.', array('%label' => $this->entity->label()))); + drupal_set_message($this->t('The %label search page has been added.', ['%label' => $this->entity->label()])); } } diff --git a/core/modules/search/src/Form/SearchPageEditForm.php b/core/modules/search/src/Form/SearchPageEditForm.php index 694b8567..9d082eb5 100644 --- a/core/modules/search/src/Form/SearchPageEditForm.php +++ b/core/modules/search/src/Form/SearchPageEditForm.php @@ -24,7 +24,7 @@ protected function actions(array $form, FormStateInterface $form_state) { public function save(array $form, FormStateInterface $form_state) { parent::save($form, $form_state); - drupal_set_message($this->t('The %label search page has been updated.', array('%label' => $this->entity->label()))); + drupal_set_message($this->t('The %label search page has been updated.', ['%label' => $this->entity->label()])); } } diff --git a/core/modules/search/src/Form/SearchPageForm.php b/core/modules/search/src/Form/SearchPageForm.php index 1521beb6..e46195ba 100644 --- a/core/modules/search/src/Form/SearchPageForm.php +++ b/core/modules/search/src/Form/SearchPageForm.php @@ -2,9 +2,10 @@ namespace Drupal\search\Form; -use Drupal\Core\Entity\EntityForm; +use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; +use Drupal\search\SearchPageInterface; /** * Provides a search form for site wide search. @@ -15,10 +16,10 @@ * trigger the search being processed by the controller, and adding in any * additional query parameters they need to execute search. */ -class SearchPageForm extends EntityForm { +class SearchPageForm extends FormBase { /** - * {@inheritdoc} + * The search page entity. * * @var \Drupal\search\SearchPageInterface */ @@ -34,54 +35,47 @@ public function getFormId() { /** * {@inheritdoc} */ - public function form(array $form, FormStateInterface $form_state) { + public function buildForm(array $form, FormStateInterface $form_state, SearchPageInterface $search_page = NULL) { + $this->entity = $search_page; + $plugin = $this->entity->getPlugin(); $form_state->set('search_page_id', $this->entity->id()); - $form['basic'] = array( + $form['basic'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('container-inline'), - ), - ); - $form['basic']['keys'] = array( + '#attributes' => [ + 'class' => ['container-inline'], + ], + ]; + $form['basic']['keys'] = [ '#type' => 'search', '#title' => $this->t('Enter your keywords'), '#default_value' => $plugin->getKeywords(), '#size' => 30, '#maxlength' => 255, - ); + ]; // processed_keys is used to coordinate keyword passing between other forms // that hook into the basic search form. - $form['basic']['processed_keys'] = array( + $form['basic']['processed_keys'] = [ '#type' => 'value', '#value' => '', - ); - $form['basic']['submit'] = array( + ]; + $form['basic']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Search'), - ); + ]; - $form['help_link'] = array( + $form['help_link'] = [ '#type' => 'link', '#url' => new Url('search.help_' . $this->entity->id()), '#title' => $this->t('Search help'), - '#options' => array('attributes' => array('class' => 'search-help-link')), - ); + '#options' => ['attributes' => ['class' => 'search-help-link']], + ]; // Allow the plugin to add to or alter the search form. $plugin->searchFormAlter($form, $form_state); - - return parent::form($form, $form_state); - } - - /** - * {@inheritdoc} - */ - protected function actions(array $form, FormStateInterface $form_state) { - // The submit button is added in the form directly. - return array(); + return $form; } /** @@ -97,8 +91,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $route = 'search.view_' . $form_state->get('search_page_id'); $form_state->setRedirect( $route, - array(), - array('query' => $query) + [], + ['query' => $query] ); } diff --git a/core/modules/search/src/Form/SearchPageFormBase.php b/core/modules/search/src/Form/SearchPageFormBase.php index 92b4fbe0..1638f90a 100644 --- a/core/modules/search/src/Form/SearchPageFormBase.php +++ b/core/modules/search/src/Form/SearchPageFormBase.php @@ -3,7 +3,6 @@ namespace Drupal\search\Form; use Drupal\Core\Entity\EntityForm; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\search\SearchPageRepositoryInterface; @@ -28,13 +27,6 @@ abstract class SearchPageFormBase extends EntityForm { */ protected $plugin; - /** - * The entity query factory. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $entityQuery; - /** * The search page repository. * @@ -45,13 +37,10 @@ abstract class SearchPageFormBase extends EntityForm { /** * Constructs a new search form. * - * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query - * The entity query. * @param \Drupal\search\SearchPageRepositoryInterface $search_page_repository * The search page repository. */ - public function __construct(QueryFactory $entity_query, SearchPageRepositoryInterface $search_page_repository) { - $this->entityQuery = $entity_query; + public function __construct(SearchPageRepositoryInterface $search_page_repository) { $this->searchPageRepository = $search_page_repository; } @@ -60,7 +49,6 @@ public function __construct(QueryFactory $entity_query, SearchPageRepositoryInte */ public static function create(ContainerInterface $container) { return new static( - $container->get('entity.query'), $container->get('search.search_page_repository') ); } @@ -84,35 +72,35 @@ public function buildForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Label'), '#description' => $this->t('The label for this search page.'), '#default_value' => $this->entity->label(), '#maxlength' => '255', - ); + ]; - $form['id'] = array( + $form['id'] = [ '#type' => 'machine_name', '#default_value' => $this->entity->id(), '#disabled' => !$this->entity->isNew(), '#maxlength' => 64, - '#machine_name' => array( - 'exists' => array($this, 'exists'), - ), - ); - $form['path'] = array( + '#machine_name' => [ + 'exists' => [$this, 'exists'], + ], + ]; + $form['path'] = [ '#type' => 'textfield', '#title' => $this->t('Path'), '#field_prefix' => 'search/', '#default_value' => $this->entity->getPath(), '#maxlength' => '255', '#required' => TRUE, - ); - $form['plugin'] = array( + ]; + $form['plugin'] = [ '#type' => 'value', '#value' => $this->entity->get('plugin'), - ); + ]; if ($this->plugin instanceof PluginFormInterface) { $form += $this->plugin->buildConfigurationForm($form, $form_state); @@ -131,7 +119,7 @@ public function form(array $form, FormStateInterface $form_state) { * TRUE if the search configuration exists, FALSE otherwise. */ public function exists($id) { - $entity = $this->entityQuery->get('search_page') + $entity = $this->entityTypeManager->getStorage('search_page')->getQuery() ->condition('id', $id) ->execute(); return (bool) $entity; @@ -144,7 +132,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { parent::validateForm($form, $form_state); // Ensure each path is unique. - $path = $this->entityQuery->get('search_page') + $path = $this->entityTypeManager->getStorage('search_page')->getQuery() ->condition('path', $form_state->getValue('path')) ->condition('id', $form_state->getValue('id'), '<>') ->execute(); diff --git a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php index 3a39cbc1..7ad95f16 100644 --- a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php +++ b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php @@ -23,14 +23,14 @@ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements public function __construct(array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $this->configuration); + $this->setConfiguration($configuration); } /** * {@inheritdoc} */ public function defaultConfiguration() { - return array(); + return []; } /** @@ -44,7 +44,7 @@ public function getConfiguration() { * {@inheritdoc} */ public function setConfiguration(array $configuration) { - $this->configuration = $configuration; + $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration); } /** @@ -57,7 +57,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form * {@inheritdoc} */ public function calculateDependencies() { - return array(); + return []; } /** diff --git a/core/modules/search/src/Plugin/Derivative/SearchLocalTask.php b/core/modules/search/src/Plugin/Derivative/SearchLocalTask.php index adc356e9..9f62a375 100644 --- a/core/modules/search/src/Plugin/Derivative/SearchLocalTask.php +++ b/core/modules/search/src/Plugin/Derivative/SearchLocalTask.php @@ -42,17 +42,17 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $this->derivatives = array(); + $this->derivatives = []; if ($default = $this->searchPageRepository->getDefaultSearchPage()) { $active_search_pages = $this->searchPageRepository->getActiveSearchPages(); foreach ($this->searchPageRepository->sortSearchPages($active_search_pages) as $entity_id => $entity) { - $this->derivatives[$entity_id] = array( + $this->derivatives[$entity_id] = [ 'title' => $entity->label(), 'route_name' => 'search.view_' . $entity_id, 'base_route' => 'search.plugins:' . $default, 'weight' => $entity->getWeight(), - ); + ]; } } return $this->derivatives; diff --git a/core/modules/search/src/Plugin/SearchInterface.php b/core/modules/search/src/Plugin/SearchInterface.php index 2f2403c2..8f95ce82 100644 --- a/core/modules/search/src/Plugin/SearchInterface.php +++ b/core/modules/search/src/Plugin/SearchInterface.php @@ -110,7 +110,7 @@ public function getHelp(); * * The core search module only invokes this method on active module plugins * when building a form for them in - * \Drupal\search\Form\SearchPageForm::form(). A plugin implementing this + * \Drupal\search\Form\SearchPageForm::buildForm(). A plugin implementing this * will also need to implement the buildSearchUrlQuery() method. * * @param array $form diff --git a/core/modules/search/src/Plugin/SearchPluginBase.php b/core/modules/search/src/Plugin/SearchPluginBase.php index d253972c..7312df49 100644 --- a/core/modules/search/src/Plugin/SearchPluginBase.php +++ b/core/modules/search/src/Plugin/SearchPluginBase.php @@ -97,13 +97,13 @@ public function getType() { public function buildResults() { $results = $this->execute(); - $built = array(); + $built = []; foreach ($results as $result) { - $built[] = array( + $built[] = [ '#theme' => 'search_result', '#result' => $result, '#plugin_id' => $this->getPluginId(), - ); + ]; } return $built; @@ -123,7 +123,7 @@ public function suggestedTitle() { // If the user entered a search string, truncate it and append it to the // title. if (!empty($this->keywords)) { - return $this->t('Search for @keywords', array('@keywords' => Unicode::truncate($this->keywords, 60, TRUE, TRUE))); + return $this->t('Search for @keywords', ['@keywords' => Unicode::truncate($this->keywords, 60, TRUE, TRUE)]); } // Use the default 'Search' title. return $this->t('Search'); @@ -135,7 +135,7 @@ public function suggestedTitle() { public function buildSearchUrlQuery(FormStateInterface $form_state) { // Grab the keywords entered in the form and put them as 'keys' in the GET. $keys = trim($form_state->getValue('keys')); - $query = array('keys' => $keys); + $query = ['keys' => $keys]; return $query; } @@ -146,16 +146,18 @@ public function buildSearchUrlQuery(FormStateInterface $form_state) { public function getHelp() { // This default search help is appropriate for plugins like NodeSearch // that use the SearchQuery class. - $help = array('list' => array( - '#theme' => 'item_list', - '#items' => array( - $this->t('Search looks for exact, case-insensitive keywords; keywords shorter than a minimum length are ignored.'), - $this->t('Use upper-case OR to get more results. Example: cat OR dog (content contains either "cat" or "dog").'), - $this->t('You can use upper-case AND to require all words, but this is the same as the default behavior. Example: cat AND dog (same as cat dog, content must contain both "cat" and "dog").'), - $this->t('Use quotes to search for a phrase. Example: "the cat eats mice".'), - $this->t('You can precede keywords by - to exclude them; you must still have at least one "positive" keyword. Example: cat -dog (content must contain cat and cannot contain dog).'), - ), - )); + $help = [ + 'list' => [ + '#theme' => 'item_list', + '#items' => [ + $this->t('Search looks for exact, case-insensitive keywords; keywords shorter than a minimum length are ignored.'), + $this->t('Use upper-case OR to get more results. Example: cat OR dog (content contains either "cat" or "dog").'), + $this->t('You can use upper-case AND to require all words, but this is the same as the default behavior. Example: cat AND dog (same as cat dog, content must contain both "cat" and "dog").'), + $this->t('Use quotes to search for a phrase. Example: "the cat eats mice".'), + $this->t('You can precede keywords by - to exclude them; you must still have at least one "positive" keyword. Example: cat -dog (content must contain cat and cannot contain dog).'), + ], + ], + ]; return $help; } diff --git a/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php b/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php index f021df68..8199215c 100644 --- a/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php +++ b/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php @@ -21,7 +21,7 @@ class SearchConfigurationRankings extends ProcessPluginBase { * Generate the configuration rankings. */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $return = array(); + $return = []; foreach ($row->getSource() as $name => $rank) { if (substr($name, 0, 10) == 'node_rank_' && is_numeric($rank)) { $return[substr($name, 10)] = $rank; diff --git a/core/modules/search/src/Plugin/migrate/process/d6/SearchConfigurationRankings.php b/core/modules/search/src/Plugin/migrate/process/d6/SearchConfigurationRankings.php index 6c1d16b0..206f1f80 100644 --- a/core/modules/search/src/Plugin/migrate/process/d6/SearchConfigurationRankings.php +++ b/core/modules/search/src/Plugin/migrate/process/d6/SearchConfigurationRankings.php @@ -21,7 +21,7 @@ class SearchConfigurationRankings extends ProcessPluginBase { * Generate the configuration rankings. */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $return = array(); + $return = []; foreach ($row->getSource() as $name => $rank) { if (substr($name, 0, 10) == 'node_rank_' && $rank) { $return[substr($name, 10)] = $rank; diff --git a/core/modules/search/src/Plugin/views/argument/Search.php b/core/modules/search/src/Plugin/views/argument/Search.php index 9c3d6bb3..f9cd9a14 100644 --- a/core/modules/search/src/Plugin/views/argument/Search.php +++ b/core/modules/search/src/Plugin/views/argument/Search.php @@ -2,6 +2,7 @@ namespace Drupal\search\Plugin\views\argument; +use Drupal\Core\Database\Query\Condition; use Drupal\views\Plugin\views\argument\ArgumentPluginBase; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ViewExecutable; @@ -47,7 +48,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o */ protected function queryParseSearchExpression($input) { if (!isset($this->searchQuery)) { - $this->searchQuery = db_select('search_index', 'i', array('target' => 'replica'))->extend('Drupal\search\ViewsSearchQuery'); + $this->searchQuery = db_select('search_index', 'i', ['target' => 'replica'])->extend('Drupal\search\ViewsSearchQuery'); $this->searchQuery->searchExpression($input, $this->searchType); $this->searchQuery->publicParseSearchExpression(); } @@ -76,27 +77,27 @@ public function query($group_by = FALSE) { else { $search_index = $this->ensureMyTable(); - $search_condition = db_and(); + $search_condition = new Condition('AND'); // Create a new join to relate the 'search_total' table to our current 'search_index' table. - $definition = array( + $definition = [ 'table' => 'search_total', 'field' => 'word', 'left_table' => $search_index, 'left_field' => 'word', - ); + ]; $join = Views::pluginManager('join')->createInstance('standard', $definition); $search_total = $this->query->addRelationship('search_total', $join, $search_index); // Add the search score field to the query. - $this->search_score = $this->query->addField('', "$search_index.score * $search_total.count", 'score', array('function' => 'sum')); + $this->search_score = $this->query->addField('', "$search_index.score * $search_total.count", 'score', ['function' => 'sum']); // Add the conditions set up by the search query to the views query. $search_condition->condition("$search_index.type", $this->searchType); $search_dataset = $this->query->addTable('node_search_dataset'); $conditions = $this->searchQuery->conditions(); $condition_conditions =& $conditions->conditions(); - foreach ($condition_conditions as $key => &$condition) { + foreach ($condition_conditions as $key => &$condition) { // Make sure we just look at real conditions. if (is_numeric($key)) { // Replace the conditions with the table alias of views. @@ -109,7 +110,7 @@ public function query($group_by = FALSE) { // Add the keyword conditions, as is done in // SearchQuery::prepareAndNormalize(), but simplified because we are // only concerned with relevance ranking so we do not need to normalize. - $or = db_or(); + $or = new Condition('OR'); foreach ($words as $word) { $or->condition("$search_index.word", $word); } @@ -120,7 +121,7 @@ public function query($group_by = FALSE) { $this->query->addGroupBy("$search_index.sid"); $matches = $this->searchQuery->matches(); $placeholder = $this->placeholder(); - $this->query->addHavingExpression(0, "COUNT(*) >= $placeholder", array($placeholder => $matches)); + $this->query->addHavingExpression(0, "COUNT(*) >= $placeholder", [$placeholder => $matches]); } // Set to NULL to prevent PDO exception when views object is cached diff --git a/core/modules/search/src/Plugin/views/filter/Search.php b/core/modules/search/src/Plugin/views/filter/Search.php index ea52e1ce..b1884d5a 100644 --- a/core/modules/search/src/Plugin/views/filter/Search.php +++ b/core/modules/search/src/Plugin/views/filter/Search.php @@ -2,6 +2,7 @@ namespace Drupal\search\Plugin\views\filter; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\filter\FilterPluginBase; use Drupal\views\Plugin\views\display\DisplayPluginBase; @@ -67,28 +68,28 @@ protected function defineOptions() { * {@inheritdoc} */ protected function operatorForm(&$form, FormStateInterface $form_state) { - $form['operator'] = array( + $form['operator'] = [ '#type' => 'radios', '#title' => $this->t('On empty input'), '#default_value' => $this->operator, - '#options' => array( + '#options' => [ 'optional' => $this->t('Show All'), 'required' => $this->t('Show None'), - ), - ); + ], + ]; } /** * {@inheritdoc} */ protected function valueForm(&$form, FormStateInterface $form_state) { - $form['value'] = array( + $form['value'] = [ '#type' => 'textfield', '#size' => 15, '#default_value' => $this->value, - '#attributes' => array('title' => $this->t('Search keywords')), + '#attributes' => ['title' => $this->t('Search keywords')], '#title' => !$form_state->get('exposed') ? $this->t('Keywords') : '', - ); + ]; } /** @@ -117,7 +118,7 @@ public function validateExposed(&$form, FormStateInterface $form_state) { protected function queryParseSearchExpression($input) { if (!isset($this->searchQuery)) { $this->parsed = TRUE; - $this->searchQuery = db_select('search_index', 'i', array('target' => 'replica'))->extend('Drupal\search\ViewsSearchQuery'); + $this->searchQuery = db_select('search_index', 'i', ['target' => 'replica'])->extend('Drupal\search\ViewsSearchQuery'); $this->searchQuery->searchExpression($input, $this->searchType); $this->searchQuery->publicParseSearchExpression(); } @@ -150,28 +151,28 @@ public function query() { else { $search_index = $this->ensureMyTable(); - $search_condition = db_and(); + $search_condition = new Condition('AND'); // Create a new join to relate the 'search_total' table to our current // 'search_index' table. - $definition = array( + $definition = [ 'table' => 'search_total', 'field' => 'word', 'left_table' => $search_index, 'left_field' => 'word', - ); + ]; $join = Views::pluginManager('join')->createInstance('standard', $definition); $search_total = $this->query->addRelationship('search_total', $join, $search_index); // Add the search score field to the query. - $this->search_score = $this->query->addField('', "$search_index.score * $search_total.count", 'score', array('function' => 'sum')); + $this->search_score = $this->query->addField('', "$search_index.score * $search_total.count", 'score', ['function' => 'sum']); // Add the conditions set up by the search query to the views query. $search_condition->condition("$search_index.type", $this->searchType); $search_dataset = $this->query->addTable('node_search_dataset'); $conditions = $this->searchQuery->conditions(); $condition_conditions =& $conditions->conditions(); - foreach ($condition_conditions as $key => &$condition) { + foreach ($condition_conditions as $key => &$condition) { // Make sure we just look at real conditions. if (is_numeric($key)) { // Replace the conditions with the table alias of views. @@ -184,7 +185,7 @@ public function query() { // Add the keyword conditions, as is done in // SearchQuery::prepareAndNormalize(), but simplified because we are // only concerned with relevance ranking so we do not need to normalize. - $or = db_or(); + $or = new Condition('OR'); foreach ($words as $word) { $or->condition("$search_index.word", $word); } @@ -196,7 +197,7 @@ public function query() { $this->query->addGroupBy("$search_index.sid"); $matches = $this->searchQuery->matches(); $placeholder = $this->placeholder(); - $this->query->addHavingExpression($this->options['group'], "COUNT(*) >= $placeholder", array($placeholder => $matches)); + $this->query->addHavingExpression($this->options['group'], "COUNT(*) >= $placeholder", [$placeholder => $matches]); } // Set to NULL to prevent PDO exception when views object is cached. $this->searchQuery = NULL; diff --git a/core/modules/search/src/Plugin/views/row/SearchRow.php b/core/modules/search/src/Plugin/views/row/SearchRow.php index 51f78536..29e150d5 100644 --- a/core/modules/search/src/Plugin/views/row/SearchRow.php +++ b/core/modules/search/src/Plugin/views/row/SearchRow.php @@ -22,7 +22,7 @@ class SearchRow extends RowPluginBase { protected function defineOptions() { $options = parent::defineOptions(); - $options['score'] = array('default' => TRUE); + $options['score'] = ['default' => TRUE]; return $options; } @@ -31,23 +31,23 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['score'] = array( + $form['score'] = [ '#type' => 'checkbox', '#title' => $this->t('Display score'), '#default_value' => $this->options['score'], - ); + ]; } /** * {@inheritdoc} */ public function render($row) { - return array( + return [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#row' => $row, - ); + ]; } } diff --git a/core/modules/search/src/Plugin/views/sort/Score.php b/core/modules/search/src/Plugin/views/sort/Score.php index 7a7bbf0f..f5910f0d 100644 --- a/core/modules/search/src/Plugin/views/sort/Score.php +++ b/core/modules/search/src/Plugin/views/sort/Score.php @@ -21,7 +21,7 @@ public function query() { // Our filter stores it as $handler->search_score -- and we also // need to check its relationship to make sure that we're using the same // one or obviously this won't work. - foreach (array('filter', 'argument') as $type) { + foreach (['filter', 'argument'] as $type) { foreach ($this->view->{$type} as $handler) { if (isset($handler->search_score) && $handler->relationship == $this->relationship) { $this->query->addOrderBy(NULL, NULL, $this->options['order'], $handler->search_score); diff --git a/core/modules/search/src/Routing/SearchPageRoutes.php b/core/modules/search/src/Routing/SearchPageRoutes.php index b85cbe8f..6e199d3d 100644 --- a/core/modules/search/src/Routing/SearchPageRoutes.php +++ b/core/modules/search/src/Routing/SearchPageRoutes.php @@ -45,70 +45,70 @@ public static function create(ContainerInterface $container) { * An array of route objects. */ public function routes() { - $routes = array(); + $routes = []; // @todo Decide if /search should continue to redirect to /search/$default, // or just perform the appropriate search. if ($default_page = $this->searchPageRepository->getDefaultSearchPage()) { $routes['search.view'] = new Route( '/search', - array( + [ '_controller' => 'Drupal\search\Controller\SearchController::redirectSearchPage', '_title' => 'Search', 'entity' => $default_page, - ), - array( + ], + [ '_entity_access' => 'entity.view', '_permission' => 'search content', - ), - array( - 'parameters' => array( - 'entity' => array( + ], + [ + 'parameters' => [ + 'entity' => [ 'type' => 'entity:search_page', - ), - ), - ) + ], + ], + ] ); } $active_pages = $this->searchPageRepository->getActiveSearchPages(); foreach ($active_pages as $entity_id => $entity) { $routes["search.view_$entity_id"] = new Route( '/search/' . $entity->getPath(), - array( + [ '_controller' => 'Drupal\search\Controller\SearchController::view', '_title' => 'Search', 'entity' => $entity_id, - ), - array( + ], + [ '_entity_access' => 'entity.view', '_permission' => 'search content', - ), - array( - 'parameters' => array( - 'entity' => array( + ], + [ + 'parameters' => [ + 'entity' => [ 'type' => 'entity:search_page', - ), - ), - ) + ], + ], + ] ); $routes["search.help_$entity_id"] = new Route( '/search/' . $entity->getPath() . '/help', - array( + [ '_controller' => 'Drupal\search\Controller\SearchController::searchHelp', '_title' => 'Search help', 'entity' => $entity_id, - ), - array( + ], + [ '_entity_access' => 'entity.view', '_permission' => 'search content', - ), - array( - 'parameters' => array( - 'entity' => array( + ], + [ + 'parameters' => [ + 'entity' => [ 'type' => 'entity:search_page', - ), - ), - ) + ], + ], + ] ); } return $routes; diff --git a/core/modules/search/src/SearchPageAccessControlHandler.php b/core/modules/search/src/SearchPageAccessControlHandler.php index be135bc8..2627f51e 100644 --- a/core/modules/search/src/SearchPageAccessControlHandler.php +++ b/core/modules/search/src/SearchPageAccessControlHandler.php @@ -20,7 +20,7 @@ class SearchPageAccessControlHandler extends EntityAccessControlHandler { */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { /** @var $entity \Drupal\search\SearchPageInterface */ - if (in_array($operation, array('delete', 'disable'))) { + if (in_array($operation, ['delete', 'disable'])) { if ($entity->isDefaultSearch()) { return AccessResult::forbidden()->addCacheableDependency($entity); } diff --git a/core/modules/search/src/SearchPageListBuilder.php b/core/modules/search/src/SearchPageListBuilder.php index c76a999a..9a8f6deb 100644 --- a/core/modules/search/src/SearchPageListBuilder.php +++ b/core/modules/search/src/SearchPageListBuilder.php @@ -26,7 +26,7 @@ class SearchPageListBuilder extends DraggableListBuilder implements FormInterfac * * @var \Drupal\search\SearchPageInterface[] */ - protected $entities = array(); + protected $entities = []; /** * Stores the configuration factory. @@ -90,24 +90,24 @@ protected function getEditableConfigNames() { * {@inheritdoc} */ public function buildHeader() { - $header['label'] = array( + $header['label'] = [ 'data' => $this->t('Label'), - ); - $header['url'] = array( + ]; + $header['url'] = [ 'data' => $this->t('URL'), - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ); - $header['plugin'] = array( + 'class' => [RESPONSIVE_PRIORITY_LOW], + ]; + $header['plugin'] = [ 'data' => $this->t('Type'), - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ); - $header['status'] = array( + 'class' => [RESPONSIVE_PRIORITY_LOW], + ]; + $header['status'] = [ 'data' => $this->t('Status'), - ); - $header['progress'] = array( + ]; + $header['progress'] = [ 'data' => $this->t('Indexing progress'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ); + 'class' => [RESPONSIVE_PRIORITY_MEDIUM], + ]; return $header + parent::buildHeader(); } @@ -120,11 +120,11 @@ public function buildRow(EntityInterface $entity) { $row['url']['#markup'] = 'search/' . $entity->getPath(); // If the search page is active, link to it. if ($entity->status()) { - $row['url'] = array( + $row['url'] = [ '#type' => 'link', '#title' => $row['url'], '#url' => Url::fromRoute('search.view_' . $entity->id()), - ); + ]; } $definition = $entity->getPlugin()->getPluginDefinition(); @@ -143,10 +143,10 @@ public function buildRow(EntityInterface $entity) { if ($entity->isIndexable()) { $status = $entity->getPlugin()->indexStatus(); - $row['progress']['#markup'] = $this->t('%num_indexed of %num_total indexed', array( + $row['progress']['#markup'] = $this->t('%num_indexed of %num_total indexed', [ '%num_indexed' => $status['total'] - $status['remaining'], '%num_total' => $status['total'] - )); + ]); } else { $row['progress']['#markup'] = $this->t('Does not use index'); @@ -178,102 +178,102 @@ public function buildForm(array $form, FormStateInterface $form_state) { // will show as 99%, to indicate "almost done". $percentage = $total > 0 ? floor(100 * $done / $total) : 100; $percentage .= '%'; - $status = '

    ' . $this->t('%percentage of the site has been indexed.', array('%percentage' => $percentage)) . ' ' . $count . '

    '; - $form['status'] = array( + $status = '

    ' . $this->t('%percentage of the site has been indexed.', ['%percentage' => $percentage]) . ' ' . $count . '

    '; + $form['status'] = [ '#type' => 'details', '#title' => $this->t('Indexing progress'), '#open' => TRUE, - '#description' => $this->t('Only items in the index will appear in search results. To build and maintain the index, a correctly configured cron maintenance task is required.', array(':cron' => \Drupal::url('system.cron_settings'))), - ); - $form['status']['status'] = array('#markup' => $status); - $form['status']['wipe'] = array( + '#description' => $this->t('Only items in the index will appear in search results. To build and maintain the index, a correctly configured cron maintenance task is required.', [':cron' => \Drupal::url('system.cron_settings')]), + ]; + $form['status']['status'] = ['#markup' => $status]; + $form['status']['wipe'] = [ '#type' => 'submit', '#value' => $this->t('Re-index site'), - '#submit' => array('::searchAdminReindexSubmit'), - ); + '#submit' => ['::searchAdminReindexSubmit'], + ]; - $items = array(10, 20, 50, 100, 200, 500); + $items = [10, 20, 50, 100, 200, 500]; $items = array_combine($items, $items); // Indexing throttle: - $form['indexing_throttle'] = array( + $form['indexing_throttle'] = [ '#type' => 'details', '#title' => $this->t('Indexing throttle'), '#open' => TRUE, - ); - $form['indexing_throttle']['cron_limit'] = array( + ]; + $form['indexing_throttle']['cron_limit'] = [ '#type' => 'select', '#title' => $this->t('Number of items to index per cron run'), '#default_value' => $search_settings->get('index.cron_limit'), '#options' => $items, - '#description' => $this->t('The maximum number of items indexed in each run of the cron maintenance task. If necessary, reduce the number of items to prevent timeouts and memory errors while indexing. Some search page types may have their own setting for this.', array(':cron' => \Drupal::url('system.cron_settings'))), - ); + '#description' => $this->t('The maximum number of items indexed in each run of the cron maintenance task. If necessary, reduce the number of items to prevent timeouts and memory errors while indexing. Some search page types may have their own setting for this.', [':cron' => \Drupal::url('system.cron_settings')]), + ]; // Indexing settings: - $form['indexing_settings'] = array( + $form['indexing_settings'] = [ '#type' => 'details', '#title' => $this->t('Default indexing settings'), '#open' => TRUE, - ); - $form['indexing_settings']['info'] = array( + ]; + $form['indexing_settings']['info'] = [ '#markup' => $this->t("

    Search pages that use an index may use the default index provided by the Search module, or they may use a different indexing mechanism. These settings are for the default index. Changing these settings will cause the default search index to be rebuilt to reflect the new settings. Searching will continue to work, based on the existing index, but new content won't be indexed until all existing content has been re-indexed.

    The default settings should be appropriate for the majority of sites.

    ") - ); - $form['indexing_settings']['minimum_word_size'] = array( + ]; + $form['indexing_settings']['minimum_word_size'] = [ '#type' => 'number', '#title' => $this->t('Minimum word length to index'), '#default_value' => $search_settings->get('index.minimum_word_size'), '#min' => 1, '#max' => 1000, '#description' => $this->t('The minimum character length for a word to be added to the index. Searches must include a keyword of at least this length.'), - ); - $form['indexing_settings']['overlap_cjk'] = array( + ]; + $form['indexing_settings']['overlap_cjk'] = [ '#type' => 'checkbox', '#title' => $this->t('Simple CJK handling'), '#default_value' => $search_settings->get('index.overlap_cjk'), '#description' => $this->t('Whether to apply a simple Chinese/Japanese/Korean tokenizer based on overlapping sequences. Turn this off if you want to use an external preprocessor for this instead. Does not affect other languages.') - ); + ]; // Indexing settings: - $form['logging'] = array( + $form['logging'] = [ '#type' => 'details', '#title' => $this->t('Logging'), '#open' => TRUE, - ); + ]; - $form['logging']['logging'] = array( + $form['logging']['logging'] = [ '#type' => 'checkbox', '#title' => $this->t('Log searches'), '#default_value' => $search_settings->get('logging'), '#description' => $this->t('If checked, all searches will be logged. Uncheck to skip logging. Logging may affect performance.'), - ); + ]; - $form['search_pages'] = array( + $form['search_pages'] = [ '#type' => 'details', '#title' => $this->t('Search pages'), '#open' => TRUE, - ); - $form['search_pages']['add_page'] = array( + ]; + $form['search_pages']['add_page'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('container-inline'), - ), - ); + '#attributes' => [ + 'class' => ['container-inline'], + ], + ]; // In order to prevent validation errors for the parent form, this cannot be // required, see self::validateAddSearchPage(). - $form['search_pages']['add_page']['search_type'] = array( + $form['search_pages']['add_page']['search_type'] = [ '#type' => 'select', '#title' => $this->t('Search page type'), '#empty_option' => $this->t('- Choose page type -'), '#options' => array_map(function ($definition) { return $definition['title']; }, $this->searchManager->getDefinitions()), - ); - $form['search_pages']['add_page']['add_search_submit'] = array( + ]; + $form['search_pages']['add_page']['add_search_submit'] = [ '#type' => 'submit', '#value' => $this->t('Add search page'), - '#validate' => array('::validateAddSearchPage'), - '#submit' => array('::submitAddSearchPage'), - '#limit_validation_errors' => array(array('search_type')), - ); + '#validate' => ['::validateAddSearchPage'], + '#submit' => ['::submitAddSearchPage'], + '#limit_validation_errors' => [['search_type']], + ]; // Move the listing into the search_pages element. $form['search_pages'][$this->entitiesKey] = $form[$this->entitiesKey]; @@ -281,11 +281,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { unset($form[$this->entitiesKey]); $form['actions']['#type'] = 'actions'; - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save configuration'), '#button_type' => 'primary', - ); + ]; return $form; } @@ -302,13 +302,13 @@ public function getDefaultOperations(EntityInterface $entity) { unset($operations['disable'], $operations['delete']); } else { - $operations['default'] = array( + $operations['default'] = [ 'title' => $this->t('Set as default'), 'url' => Url::fromRoute('entity.search_page.set_default', [ 'search_page' => $entity->id(), ]), 'weight' => 50, - ); + ]; } return $operations; @@ -369,7 +369,7 @@ public function validateAddSearchPage(array &$form, FormStateInterface $form_sta public function submitAddSearchPage(array &$form, FormStateInterface $form_state) { $form_state->setRedirect( 'search.add_type', - array('search_plugin_id' => $form_state->getValue('search_type')) + ['search_plugin_id' => $form_state->getValue('search_type')] ); } diff --git a/core/modules/search/src/SearchPageRepository.php b/core/modules/search/src/SearchPageRepository.php index 459ea578..6f4dc64d 100644 --- a/core/modules/search/src/SearchPageRepository.php +++ b/core/modules/search/src/SearchPageRepository.php @@ -105,7 +105,7 @@ public function setDefaultSearchPage(SearchPageInterface $search_page) { */ public function sortSearchPages($search_pages) { $entity_type = $this->storage->getEntityType(); - uasort($search_pages, array($entity_type->getClass(), 'sort')); + uasort($search_pages, [$entity_type->getClass(), 'sort']); return $search_pages; } diff --git a/core/modules/search/src/SearchQuery.php b/core/modules/search/src/SearchQuery.php index 2ca2bda3..cc0b65e0 100644 --- a/core/modules/search/src/SearchQuery.php +++ b/core/modules/search/src/SearchQuery.php @@ -2,6 +2,7 @@ namespace Drupal\search; +use Drupal\Core\Database\Query\Condition; use Drupal\Component\Utility\Unicode; use Drupal\Core\Database\Query\SelectExtender; use Drupal\Core\Database\Query\SelectInterface; @@ -96,7 +97,7 @@ class SearchQuery extends SelectExtender { * * @var array */ - protected $keys = array('positive' => array(), 'negative' => array()); + protected $keys = ['positive' => [], 'negative' => []]; /** * Indicates whether the query conditions are simple or complex (LIKE). @@ -129,7 +130,7 @@ class SearchQuery extends SelectExtender { * * @var array */ - protected $words = array(); + protected $words = []; /** * Multiplier to normalize the keyword score. @@ -164,14 +165,14 @@ class SearchQuery extends SelectExtender { * * @see SearchQuery::addScore() */ - protected $scores = array(); + protected $scores = []; /** * Arguments for the score expressions. * * @var array */ - protected $scoresArguments = array(); + protected $scoresArguments = []; /** * The number of 'i.relevance' occurrences in score expressions. @@ -185,7 +186,7 @@ class SearchQuery extends SelectExtender { * * @var array */ - protected $multiply = array(); + protected $multiply = []; /** * Sets the search query expression. @@ -205,7 +206,7 @@ public function searchExpression($expression, $type) { $this->addTag('search_' . $type); // Initialize conditions and status. - $this->conditions = db_and(); + $this->conditions = new Condition('AND'); $this->status = 0; return $this; @@ -258,7 +259,7 @@ protected function parseSearchExpression() { $words = search_simplify($match[2]); // Re-explode in case simplification added more words, except when // matching a phrase. - $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY); + $words = $phrase ? [$words] : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY); // Negative matches. if ($match[1] == '-') { $this->keys['negative'] = array_merge($this->keys['negative'], $words); @@ -269,7 +270,7 @@ protected function parseSearchExpression() { $last = array_pop($this->keys['positive']); // Starting a new OR? if (!is_array($last)) { - $last = array($last); + $last = [$last]; } $this->keys['positive'][] = $last; $in_or = TRUE; @@ -313,7 +314,7 @@ protected function parseSearchExpression() { } $has_or = TRUE; $has_new_scores = FALSE; - $queryor = db_or(); + $queryor = new Condition('OR'); foreach ($key as $or) { list($num_new_scores) = $this->parseWord($or); $has_new_scores |= $num_new_scores; @@ -373,7 +374,7 @@ protected function parseWord($word) { } // Return matching snippet and number of added words. - return array($num_new_scores, $num_valid_words); + return [$num_new_scores, $num_valid_words]; } /** @@ -401,7 +402,7 @@ public function prepareAndNormalize() { } // Build the basic search query: match the entered keywords. - $or = db_or(); + $or = new Condition('OR'); foreach ($this->words as $word) { $or->condition('i.word', $word); } @@ -419,7 +420,7 @@ public function prepareAndNormalize() { // simple queries, this condition could lead to incorrectly deciding not // to continue with the full query. if ($this->simple) { - $this->having('COUNT(*) >= :matches', array(':matches' => $this->matches)); + $this->having('COUNT(*) >= :matches', [':matches' => $this->matches]); } // Clone the query object to calculate normalization. @@ -498,7 +499,7 @@ public function preExecute(SelectInterface $query = NULL) { * * @return $this */ - public function addScore($score, $arguments = array(), $multiply = FALSE) { + public function addScore($score, $arguments = [], $multiply = FALSE) { if ($multiply) { $i = count($this->multiply); // Modify the score expression so it is multiplied by the multiplier, @@ -573,7 +574,7 @@ public function execute() { // Add arguments for the keyword relevance normalization number. $normalization = 1.0 / $this->normalize; - for ($i = 0; $i < $this->relevance_count; $i++ ) { + for ($i = 0; $i < $this->relevance_count; $i++) { $this->scoresArguments[':normalization_' . $i] = $normalization; } @@ -589,7 +590,7 @@ public function execute() { // Add query metadata. $this ->addMetaData('normalize', $this->normalize) - ->fields('i', array('type', 'sid')); + ->fields('i', ['type', 'sid']); return $this->query->execute(); } @@ -617,12 +618,12 @@ public function countQuery() { // Remove existing fields and expressions, they are not needed for a count // query. $fields =& $inner->getFields(); - $fields = array(); + $fields = []; $expressions =& $inner->getExpressions(); - $expressions = array(); + $expressions = []; // Add sid as the only field and count them as a subquery. - $count = db_select($inner->fields('i', array('sid')), NULL, array('target' => 'replica')); + $count = db_select($inner->fields('i', ['sid']), NULL, ['target' => 'replica']); // Add the COUNT() expression. $count->addExpression('COUNT(*)'); diff --git a/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php b/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php index 9bd13bdc..ad00b525 100644 --- a/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php +++ b/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php @@ -19,7 +19,7 @@ class SearchAdvancedSearchFormTest extends SearchTestBase { protected function setUp() { parent::setUp(); // Create and log in user. - $test_user = $this->drupalCreateUser(array('access content', 'search content', 'use advanced search', 'administer nodes')); + $test_user = $this->drupalCreateUser(['access content', 'search content', 'use advanced search', 'administer nodes']); $this->drupalLogin($test_user); // Create initial node. @@ -37,44 +37,44 @@ protected function setUp() { /** * Tests advanced search by node type. */ - function testNodeType() { + public function testNodeType() { // Verify some properties of the node that was created. $this->assertTrue($this->node->getType() == 'page', 'Node type is Basic page.'); $dummy_title = 'Lorem ipsum'; $this->assertNotEqual($dummy_title, $this->node->label(), "Dummy title doesn't equal node title."); // Search for the dummy title with a GET query. - $this->drupalGet('search/node', array('query' => array('keys' => $dummy_title))); + $this->drupalGet('search/node', ['query' => ['keys' => $dummy_title]]); $this->assertNoText($this->node->label(), 'Basic page node is not found with dummy title.'); // Search for the title of the node with a GET query. - $this->drupalGet('search/node', array('query' => array('keys' => $this->node->label()))); + $this->drupalGet('search/node', ['query' => ['keys' => $this->node->label()]]); $this->assertText($this->node->label(), 'Basic page node is found with GET query.'); // Search for the title of the node with a POST query. - $edit = array('or' => $this->node->label()); + $edit = ['or' => $this->node->label()]; $this->drupalPostForm('search/node', $edit, t('Advanced search')); $this->assertText($this->node->label(), 'Basic page node is found with POST query.'); // Search by node type. - $this->drupalPostForm('search/node', array_merge($edit, array('type[page]' => 'page')), t('Advanced search')); + $this->drupalPostForm('search/node', array_merge($edit, ['type[page]' => 'page']), t('Advanced search')); $this->assertText($this->node->label(), 'Basic page node is found with POST query and type:page.'); - $this->drupalPostForm('search/node', array_merge($edit, array('type[article]' => 'article')), t('Advanced search')); + $this->drupalPostForm('search/node', array_merge($edit, ['type[article]' => 'article']), t('Advanced search')); $this->assertText('search yielded no results', 'Article node is not found with POST query and type:article.'); } /** * Tests that after submitting the advanced search form, the form is refilled. */ - function testFormRefill() { - $edit = array( + public function testFormRefill() { + $edit = [ 'keys' => 'cat', 'or' => 'dog gerbil', 'phrase' => 'pets are nice', 'negative' => 'fish snake', 'type[page]' => 'page', - ); + ]; $this->drupalPostForm('search/node', $edit, t('Advanced search')); // Test that the encoded query appears in the page title. Only test the @@ -85,11 +85,11 @@ function testFormRefill() { // Verify that all of the form fields are filled out. foreach ($edit as $key => $value) { if ($key != 'type[page]') { - $elements = $this->xpath('//input[@name=:name]', array(':name' => $key)); + $elements = $this->xpath('//input[@name=:name]', [':name' => $key]); $this->assertTrue(isset($elements[0]) && $elements[0]['value'] == $value, "Field $key is set to $value"); } else { - $elements = $this->xpath('//input[@name=:name]', array(':name' => $key)); + $elements = $this->xpath('//input[@name=:name]', [':name' => $key]); $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), "Field $key is checked"); } } @@ -97,12 +97,12 @@ function testFormRefill() { // Now test by submitting the or/not part of the query in the main // search box, and verify that the advanced form is not filled out. // (It shouldn't be filled out unless you submit values in those fields.) - $edit2 = array('keys' => 'cat dog OR gerbil -fish -snake'); + $edit2 = ['keys' => 'cat dog OR gerbil -fish -snake']; $this->drupalPostForm('search/node', $edit2, t('Advanced search')); $this->assertText('Search for cat dog OR gerbil -fish -snake'); foreach ($edit as $key => $value) { if ($key != 'type[page]') { - $elements = $this->xpath('//input[@name=:name]', array(':name' => $key)); + $elements = $this->xpath('//input[@name=:name]', [':name' => $key]); $this->assertFalse(isset($elements[0]) && $elements[0]['value'] == $value, "Field $key is not set to $value"); } } diff --git a/core/modules/search/src/Tests/SearchBlockTest.php b/core/modules/search/src/Tests/SearchBlockTest.php index 7d42a85a..21afda7f 100644 --- a/core/modules/search/src/Tests/SearchBlockTest.php +++ b/core/modules/search/src/Tests/SearchBlockTest.php @@ -14,13 +14,13 @@ class SearchBlockTest extends SearchTestBase { * * @var array */ - public static $modules = array('block'); + public static $modules = ['block']; protected function setUp() { parent::setUp(); // Create and log in user. - $admin_user = $this->drupalCreateUser(array('administer blocks', 'search content')); + $admin_user = $this->drupalCreateUser(['administer blocks', 'search content']); $this->drupalLogin($admin_user); } @@ -46,7 +46,7 @@ public function testSearchFormBlock() { $this->assertTrue(empty($elements), 'The search input field does not have empty name attribute.'); // Test a normal search via the block form, from the front page. - $terms = array('keys' => 'test'); + $terms = ['keys' => 'test']; $this->submitGetForm('', $terms, t('Search')); $this->assertResponse(200); $this->assertText('Your search yielded no results'); @@ -72,12 +72,12 @@ public function testSearchFormBlock() { $entity_id = $search_page_repository->getDefaultSearchPage(); $this->assertEqual( $this->getUrl(), - \Drupal::url('search.view_' . $entity_id, array(), array('query' => array('keys' => $terms['keys']), 'absolute' => TRUE)), + \Drupal::url('search.view_' . $entity_id, [], ['query' => ['keys' => $terms['keys']], 'absolute' => TRUE]), 'Submitted to correct URL.' ); // Test an empty search via the block form, from the front page. - $terms = array('keys' => ''); + $terms = ['keys' => '']; $this->submitGetForm('', $terms, t('Search')); $this->assertResponse(200); $this->assertText('Please enter some keywords'); @@ -86,22 +86,22 @@ public function testSearchFormBlock() { // submitted empty. $this->assertEqual( $this->getUrl(), - \Drupal::url('search.view_' . $entity_id, array(), array('query' => array('keys' => ''), 'absolute' => TRUE)), + \Drupal::url('search.view_' . $entity_id, [], ['query' => ['keys' => ''], 'absolute' => TRUE]), 'Redirected to correct URL.' ); // Test that after entering a too-short keyword in the form, you can then // search again with a longer keyword. First test using the block form. - $this->submitGetForm('node', array('keys' => $this->randomMachineName(1)), t('Search')); + $this->submitGetForm('node', ['keys' => $this->randomMachineName(1)], t('Search')); $this->assertText('You must include at least one keyword to match in the content', 'Keyword message is displayed when searching for short word'); $this->assertNoText(t('Please enter some keywords'), 'With short word entered, no keywords message is not displayed'); - $this->submitGetForm(NULL, array('keys' => $this->randomMachineName()), t('Search'), 'search-block-form'); + $this->submitGetForm(NULL, ['keys' => $this->randomMachineName()], t('Search'), 'search-block-form'); $this->assertNoText('You must include at least one keyword to match in the content', 'Keyword message is not displayed when searching for long word after short word search'); // Same test again, using the search page form for the second search this // time. - $this->submitGetForm('node', array('keys' => $this->randomMachineName(1)), t('Search')); - $this->drupalPostForm(NULL, array('keys' => $this->randomMachineName()), t('Search'), array(), array(), 'search-form'); + $this->submitGetForm('node', ['keys' => $this->randomMachineName(1)], t('Search')); + $this->drupalPostForm(NULL, ['keys' => $this->randomMachineName()], t('Search'), [], [], 'search-form'); $this->assertNoText('You must include at least one keyword to match in the content', 'Keyword message is not displayed when searching for long word after short word search'); } diff --git a/core/modules/search/src/Tests/SearchCommentTest.php b/core/modules/search/src/Tests/SearchCommentTest.php index f67637ff..70474292 100644 --- a/core/modules/search/src/Tests/SearchCommentTest.php +++ b/core/modules/search/src/Tests/SearchCommentTest.php @@ -22,7 +22,7 @@ class SearchCommentTest extends SearchTestBase { * * @var array */ - public static $modules = array('filter', 'node', 'comment'); + public static $modules = ['filter', 'node', 'comment']; /** * Test subject for comments. @@ -55,17 +55,17 @@ class SearchCommentTest extends SearchTestBase { protected function setUp() { parent::setUp(); - $full_html_format = FilterFormat::create(array( + $full_html_format = FilterFormat::create([ 'format' => 'full_html', 'name' => 'Full HTML', 'weight' => 1, - 'filters' => array(), - )); + 'filters' => [], + ]); $full_html_format->save(); // Create and log in an administrative user having access to the Full HTML // text format. - $permissions = array( + $permissions = [ 'administer filters', $full_html_format->getPermissionName(), 'administer permissions', @@ -73,7 +73,7 @@ protected function setUp() { 'post comments', 'skip comment approval', 'access comments', - ); + ]; $this->adminUser = $this->drupalCreateUser($permissions); $this->drupalLogin($this->adminUser); // Add a comment field. @@ -83,18 +83,18 @@ protected function setUp() { /** * Verify that comments are rendered using proper format in search results. */ - function testSearchResultsComment() { + public function testSearchResultsComment() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); // Create basic_html format that escapes all HTML. - $basic_html_format = FilterFormat::create(array( + $basic_html_format = FilterFormat::create([ 'format' => 'basic_html', 'name' => 'Basic HTML', 'weight' => 1, - 'filters' => array( - 'filter_html_escape' => array('status' => 1), - ), - 'roles' => array(RoleInterface::AUTHENTICATED_ID), - )); + 'filters' => [ + 'filter_html_escape' => ['status' => 1], + ], + 'roles' => [RoleInterface::AUTHENTICATED_ID], + ]); $basic_html_format->save(); $comment_body = 'Test comment body'; @@ -105,17 +105,17 @@ function testSearchResultsComment() { $field->save(); // Allow anonymous users to search content. - $edit = array( + $edit = [ RoleInterface::ANONYMOUS_ID . '[search content]' => 1, RoleInterface::ANONYMOUS_ID . '[access comments]' => 1, RoleInterface::ANONYMOUS_ID . '[post comments]' => 1, - ); + ]; $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions')); // Create a node. - $node = $this->drupalCreateNode(array('type' => 'article')); + $node = $this->drupalCreateNode(['type' => 'article']); // Post a comment using 'Full HTML' text format. - $edit_comment = array(); + $edit_comment = []; $edit_comment['subject[0][value]'] = 'Test comment subject'; $edit_comment['comment_body[0][value]'] = '

    ' . $comment_body . '

    '; $full_html_format_id = 'full_html'; @@ -125,7 +125,7 @@ function testSearchResultsComment() { // Post a comment with an evil script tag in the comment subject and a // script tag nearby a keyword in the comment body. Use the 'FULL HTML' text // format so the script tag stored. - $edit_comment2 = array(); + $edit_comment2 = []; $edit_comment2['subject[0][value]'] = ""; $edit_comment2['comment_body[0][value]'] = "nearbykeyword"; $edit_comment2['comment_body[0][format]'] = $full_html_format_id; @@ -133,7 +133,7 @@ function testSearchResultsComment() { // Post a comment with a keyword inside an evil script tag in the comment // body. Use the 'FULL HTML' text format so the script tag is stored. - $edit_comment3 = array(); + $edit_comment3 = []; $edit_comment3['subject[0][value]'] = 'asubject'; $edit_comment3['comment_body[0][value]'] = ""; $edit_comment3['comment_body[0][format]'] = $full_html_format_id; @@ -144,19 +144,19 @@ function testSearchResultsComment() { $this->cronRun(); // Search for the comment subject. - $edit = array( + $edit = [ 'keys' => "'" . $edit_comment['subject[0][value]'] . "'", - ); + ]; $this->drupalPostForm('search/node', $edit, t('Search')); - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $node2 = $node_storage->load($node->id()); $this->assertText($node2->label(), 'Node found in search results.'); $this->assertText($edit_comment['subject[0][value]'], 'Comment subject found in search results.'); // Search for the comment body. - $edit = array( + $edit = [ 'keys' => "'" . $comment_body . "'", - ); + ]; $this->drupalPostForm(NULL, $edit, t('Search')); $this->assertText($node2->label(), 'Node found in search results.'); @@ -166,9 +166,9 @@ function testSearchResultsComment() { $this->assertNoEscaped($edit_comment['comment_body[0][value]'], 'HTML in comment body is not escaped.'); // Search for the evil script comment subject. - $edit = array( + $edit = [ 'keys' => 'subjectkeyword', - ); + ]; $this->drupalPostForm('search/node', $edit, t('Search')); // Verify the evil comment subject is escaped in search results. @@ -215,7 +215,7 @@ function testSearchResultsComment() { /** * Verify access rules for comment indexing with different permissions. */ - function testSearchResultsCommentAccess() { + public function testSearchResultsCommentAccess() { $comment_body = 'Test comment body'; $this->commentSubject = 'Test comment subject'; $roles = $this->adminUser->getRoles(TRUE); @@ -226,10 +226,10 @@ function testSearchResultsCommentAccess() { $field = FieldConfig::loadByName('node', 'article', 'comment'); $field->setSetting('preview', DRUPAL_OPTIONAL); $field->save(); - $this->node = $this->drupalCreateNode(array('type' => 'article')); + $this->node = $this->drupalCreateNode(['type' => 'article']); // Post a comment using 'Full HTML' text format. - $edit_comment = array(); + $edit_comment = []; $edit_comment['subject[0][value]'] = $this->commentSubject; $edit_comment['comment_body[0][value]'] = '

    ' . $comment_body . '

    '; $this->drupalPostForm('comment/reply/node/' . $this->node->id() . '/comment', $edit_comment, t('Save')); @@ -276,26 +276,26 @@ function testSearchResultsCommentAccess() { /** * Set permissions for role. */ - function setRolePermissions($rid, $access_comments = FALSE, $search_content = TRUE) { - $permissions = array( + public function setRolePermissions($rid, $access_comments = FALSE, $search_content = TRUE) { + $permissions = [ 'access comments' => $access_comments, 'search content' => $search_content, - ); + ]; user_role_change_permissions($rid, $permissions); } /** * Update search index and search for comment. */ - function assertCommentAccess($assume_access, $message) { + public function assertCommentAccess($assume_access, $message) { // Invoke search index update. search_mark_for_reindex('node_search', $this->node->id()); $this->cronRun(); // Search for the comment subject. - $edit = array( + $edit = [ 'keys' => "'" . $this->commentSubject . "'", - ); + ]; $this->drupalPostForm('search/node', $edit, t('Search')); if ($assume_access) { @@ -312,21 +312,21 @@ function assertCommentAccess($assume_access, $message) { /** * Verify that 'add new comment' does not appear in search results or index. */ - function testAddNewComment() { + public function testAddNewComment() { // Create a node with a short body. - $settings = array( + $settings = [ 'type' => 'article', 'title' => 'short title', - 'body' => array(array('value' => 'short body text')), - ); + 'body' => [['value' => 'short body text']], + ]; - $user = $this->drupalCreateUser(array( + $user = $this->drupalCreateUser([ 'search content', 'create article content', 'access content', 'post comments', 'access comments', - )); + ]); $this->drupalLogin($user); $node = $this->drupalCreateNode($settings); @@ -341,12 +341,12 @@ function testAddNewComment() { // Search for 'comment'. Should be no results. $this->drupalLogin($user); - $this->drupalPostForm('search/node', array('keys' => 'comment'), t('Search')); + $this->drupalPostForm('search/node', ['keys' => 'comment'], t('Search')); $this->assertText(t('Your search yielded no results')); // Search for the node title. Should be found, and 'Add new comment' should // not be part of the search snippet. - $this->drupalPostForm('search/node', array('keys' => 'short'), t('Search')); + $this->drupalPostForm('search/node', ['keys' => 'short'], t('Search')); $this->assertText($node->label(), 'Search for keyword worked'); $this->assertNoText(t('Add new comment')); } diff --git a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php index 9ca87d61..b081b857 100644 --- a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php +++ b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php @@ -17,7 +17,7 @@ class SearchConfigSettingsFormTest extends SearchTestBase { * * @var array */ - public static $modules = array('block', 'search_extra_type', 'test_page_test'); + public static $modules = ['block', 'search_extra_type', 'test_page_test']; /** * User who can search and administer search. @@ -37,7 +37,7 @@ protected function setUp() { parent::setUp(); // Log in as a user that can create and search content. - $this->searchUser = $this->drupalCreateUser(array('search content', 'administer search', 'administer nodes', 'bypass node access', 'access user profiles', 'administer users', 'administer blocks', 'access site reports')); + $this->searchUser = $this->drupalCreateUser(['search content', 'administer search', 'administer nodes', 'bypass node access', 'access user profiles', 'administer users', 'administer blocks', 'access site reports']); $this->drupalLogin($this->searchUser); // Add a single piece of content and index it. @@ -47,7 +47,7 @@ protected function setUp() { // also needs the word "pizza" so we can use it as the search keyword. $body_key = 'body[0][value]'; $edit[$body_key] = \Drupal::l($node->label(), $node->urlInfo()) . ' pizza sandwich'; - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); search_update_totals(); @@ -61,42 +61,42 @@ protected function setUp() { /** * Verifies the search settings form. */ - function testSearchSettingsPage() { + public function testSearchSettingsPage() { // Test that the settings form displays the correct count of items left to index. $this->drupalGet('admin/config/search/pages'); - $this->assertText(t('There are @count items left to index.', array('@count' => 0))); + $this->assertText(t('There are @count items left to index.', ['@count' => 0])); // Test the re-index button. - $this->drupalPostForm('admin/config/search/pages', array(), t('Re-index site')); + $this->drupalPostForm('admin/config/search/pages', [], t('Re-index site')); $this->assertText(t('Are you sure you want to re-index the site')); - $this->drupalPostForm('admin/config/search/pages/reindex', array(), t('Re-index site')); + $this->drupalPostForm('admin/config/search/pages/reindex', [], t('Re-index site')); $this->assertText(t('All search indexes will be rebuilt')); $this->drupalGet('admin/config/search/pages'); $this->assertText(t('There is 1 item left to index.')); // Test that the form saves with the default values. - $this->drupalPostForm('admin/config/search/pages', array(), t('Save configuration')); + $this->drupalPostForm('admin/config/search/pages', [], t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), 'Form saves with the default values.'); // Test that the form does not save with an invalid word length. - $edit = array( + $edit = [ 'minimum_word_size' => $this->randomMachineName(3), - ); + ]; $this->drupalPostForm('admin/config/search/pages', $edit, t('Save configuration')); $this->assertNoText(t('The configuration options have been saved.'), 'Form does not save with an invalid word length.'); // Test logging setting. It should be off by default. $text = $this->randomMachineName(5); - $this->drupalPostForm('search/node', array('keys' => $text), t('Search')); + $this->drupalPostForm('search/node', ['keys' => $text], t('Search')); $this->drupalGet('admin/reports/dblog'); $this->assertNoLink('Searched Content for ' . $text . '.', 'Search was not logged'); // Turn on logging. - $edit = array('logging' => TRUE); + $edit = ['logging' => TRUE]; $this->drupalPostForm('admin/config/search/pages', $edit, t('Save configuration')); $text = $this->randomMachineName(5); - $this->drupalPostForm('search/node', array('keys' => $text), t('Search')); + $this->drupalPostForm('search/node', ['keys' => $text], t('Search')); $this->drupalGet('admin/reports/dblog'); $this->assertLink('Searched Content for ' . $text . '.', 0, 'Search was logged'); @@ -105,7 +105,7 @@ function testSearchSettingsPage() { /** * Verifies plugin-supplied settings form. */ - function testSearchModuleSettingsPage() { + public function testSearchModuleSettingsPage() { $this->drupalGet('admin/config/search/pages'); $this->clickLink(t('Edit'), 1); @@ -113,13 +113,13 @@ function testSearchModuleSettingsPage() { $this->assertTrue($this->xpath('//select[@id="edit-extra-type-settings-boost"]//option[@value="bi" and @selected="selected"]'), 'Module specific settings are picked up from the default config'); // Change extra type setting and also modify a common search setting. - $edit = array( + $edit = [ 'extra_type_settings[boost]' => 'ii', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save search page')); // Ensure that the modifications took effect. - $this->assertRaw(t('The %label search page has been updated.', array('%label' => 'Dummy search type'))); + $this->assertRaw(t('The %label search page has been updated.', ['%label' => 'Dummy search type'])); $this->drupalGet('admin/config/search/pages/manage/dummy_search_type'); $this->assertTrue($this->xpath('//select[@id="edit-extra-type-settings-boost"]//option[@value="ii" and @selected="selected"]'), 'Module specific settings can be changed'); } @@ -127,23 +127,23 @@ function testSearchModuleSettingsPage() { /** * Verifies that you can disable individual search plugins. */ - function testSearchModuleDisabling() { + public function testSearchModuleDisabling() { // Array of search plugins to test: 'keys' are the keywords to search for, // and 'text' is the text to assert is on the results page. - $plugin_info = array( - 'node_search' => array( + $plugin_info = [ + 'node_search' => [ 'keys' => 'pizza', 'text' => $this->searchNode->label(), - ), - 'user_search' => array( + ], + 'user_search' => [ 'keys' => $this->searchUser->getUsername(), 'text' => $this->searchUser->getEmail(), - ), - 'dummy_search_type' => array( + ], + 'dummy_search_type' => [ 'keys' => 'foo', 'text' => 'Dummy search snippet to display', - ), - ); + ], + ]; $plugins = array_keys($plugin_info); /** @var $entities \Drupal\search\SearchPageInterface[] */ $entities = SearchPage::loadMultiple(); @@ -154,12 +154,11 @@ function testSearchModuleDisabling() { // Test each plugin if it's enabled as the only search plugin. foreach ($entities as $entity_id => $entity) { - // Set this as default. - $this->drupalGet("admin/config/search/pages/manage/$entity_id/set-default"); + $this->setDefaultThroughUi($entity_id); // Run a search from the correct search URL. $info = $plugin_info[$entity_id]; - $this->drupalGet('search/' . $entity->getPath(), array('query' => array('keys' => $info['keys']))); + $this->drupalGet('search/' . $entity->getPath(), ['query' => ['keys' => $info['keys']]]); $this->assertResponse(200); $this->assertNoText('no results', $entity->label() . ' search found results'); $this->assertText($info['text'], 'Correct search text found'); @@ -174,11 +173,11 @@ function testSearchModuleDisabling() { // Run a search from the search block on the node page. Verify you get // to this plugin's search results page. - $terms = array('keys' => $info['keys']); + $terms = ['keys' => $info['keys']]; $this->submitGetForm('node', $terms, t('Search')); $current = $this->getURL(); - $expected = \Drupal::url('search.view_' . $entity->id(), array(), array('query' => array('keys' => $info['keys']), 'absolute' => TRUE)); - $this->assertEqual( $current, $expected, 'Block redirected to right search page'); + $expected = \Drupal::url('search.view_' . $entity->id(), [], ['query' => ['keys' => $info['keys']], 'absolute' => TRUE]); + $this->assertEqual($current, $expected, 'Block redirected to right search page'); // Try an invalid search path, which should 404. $this->drupalGet('search/not_a_plugin_path'); @@ -187,24 +186,27 @@ function testSearchModuleDisabling() { $entity->disable()->save(); } + // Set the node search as default. + $this->setDefaultThroughUi('node_search'); + // Test with all search plugins enabled. When you go to the search // page or run search, all plugins should be shown. foreach ($entities as $entity) { $entity->enable()->save(); } - // Set the node search as default. - $this->drupalGet('admin/config/search/pages/manage/node_search/set-default'); - $paths = array( - array('path' => 'search/node', 'options' => array('query' => array('keys' => 'pizza'))), - array('path' => 'search/node', 'options' => array()), - ); + \Drupal::service('router.builder')->rebuild(); + + $paths = [ + ['path' => 'search/node', 'options' => ['query' => ['keys' => 'pizza']]], + ['path' => 'search/node', 'options' => []], + ]; foreach ($paths as $item) { $this->drupalGet($item['path'], $item['options']); foreach ($plugins as $entity_id) { $label = $entities[$entity_id]->label(); - $this->assertText($label, format_string('%label search tab is shown', array('%label' => $label))); + $this->assertText($label, format_string('%label search tab is shown', ['%label' => $label])); } } } @@ -214,7 +216,7 @@ function testSearchModuleDisabling() { */ public function testDefaultSearchPageOrdering() { $this->drupalGet('search'); - $elements = $this->xpath('//*[contains(@class, :class)]//a', array(':class' => 'tabs primary')); + $elements = $this->xpath('//*[contains(@class, :class)]//a', [':class' => 'tabs primary']); $this->assertIdentical((string) $elements[0]['href'], \Drupal::url('search.view_node_search')); $this->assertIdentical((string) $elements[1]['href'], \Drupal::url('search.view_dummy_search_type')); $this->assertIdentical((string) $elements[2]['href'], \Drupal::url('search.view_user_search')); @@ -235,24 +237,24 @@ public function testMultipleSearchPages() { $this->assertText(t('No search pages have been configured.')); // Add a search page. - $edit = array(); + $edit = []; $edit['search_type'] = 'search_extra_type_search'; $this->drupalPostForm(NULL, $edit, t('Add search page')); $this->assertTitle('Add new search page | Drupal'); - $first = array(); + $first = []; $first['label'] = $this->randomString(); $first_id = $first['id'] = strtolower($this->randomMachineName(8)); $first['path'] = strtolower($this->randomMachineName(8)); $this->drupalPostForm(NULL, $first, t('Save')); $this->assertDefaultSearch($first_id, 'The default page matches the only search page.'); - $this->assertRaw(t('The %label search page has been added.', array('%label' => $first['label']))); + $this->assertRaw(t('The %label search page has been added.', ['%label' => $first['label']])); // Attempt to add a search page with an existing path. - $edit = array(); + $edit = []; $edit['search_type'] = 'search_extra_type_search'; $this->drupalPostForm(NULL, $edit, t('Add search page')); - $edit = array(); + $edit = []; $edit['label'] = $this->randomString(); $edit['id'] = strtolower($this->randomMachineName(8)); $edit['path'] = $first['path']; @@ -260,7 +262,7 @@ public function testMultipleSearchPages() { $this->assertText(t('The search page path must be unique.')); // Add a second search page. - $second = array(); + $second = []; $second['label'] = $this->randomString(); $second_id = $second['id'] = strtolower($this->randomMachineName(8)); $second['path'] = strtolower($this->randomMachineName(8)); @@ -269,18 +271,18 @@ public function testMultipleSearchPages() { // Ensure both search pages have their tabs displayed. $this->drupalGet('search'); - $elements = $this->xpath('//*[contains(@class, :class)]//a', array(':class' => 'tabs primary')); + $elements = $this->xpath('//*[contains(@class, :class)]//a', [':class' => 'tabs primary']); $this->assertIdentical((string) $elements[0]['href'], Url::fromRoute('search.view_' . $first_id)->toString()); $this->assertIdentical((string) $elements[1]['href'], Url::fromRoute('search.view_' . $second_id)->toString()); // Switch the weight of the search pages and check the order of the tabs. - $edit = array( + $edit = [ 'entities[' . $first_id . '][weight]' => 10, 'entities[' . $second_id . '][weight]' => -10, - ); + ]; $this->drupalPostForm('admin/config/search/pages', $edit, t('Save configuration')); $this->drupalGet('search'); - $elements = $this->xpath('//*[contains(@class, :class)]//a', array(':class' => 'tabs primary')); + $elements = $this->xpath('//*[contains(@class, :class)]//a', [':class' => 'tabs primary']); $this->assertIdentical((string) $elements[0]['href'], Url::fromRoute('search.view_' . $second_id)->toString()); $this->assertIdentical((string) $elements[1]['href'], Url::fromRoute('search.view_' . $first_id)->toString()); @@ -291,7 +293,7 @@ public function testMultipleSearchPages() { // Change the default search page. $this->clickLink(t('Set as default')); - $this->assertRaw(t('The default search page is now %label. Be sure to check the ordering of your search pages.', array('%label' => $second['label']))); + $this->assertRaw(t('The default search page is now %label. Be sure to check the ordering of your search pages.', ['%label' => $second['label']])); $this->verifySearchPageOperations($first_id, TRUE, TRUE, TRUE, FALSE); $this->verifySearchPageOperations($second_id, TRUE, FALSE, FALSE, FALSE); @@ -310,12 +312,25 @@ public function testMultipleSearchPages() { // Test deleting. $this->clickLink(t('Delete')); - $this->assertRaw(t('Are you sure you want to delete the search page %label?', array('%label' => $first['label']))); - $this->drupalPostForm(NULL, array(), t('Delete')); - $this->assertRaw(t('The search page %label has been deleted.', array('%label' => $first['label']))); + $this->assertRaw(t('Are you sure you want to delete the search page %label?', ['%label' => $first['label']])); + $this->drupalPostForm(NULL, [], t('Delete')); + $this->assertRaw(t('The search page %label has been deleted.', ['%label' => $first['label']])); $this->verifySearchPageOperations($first_id, FALSE, FALSE, FALSE, FALSE); } + /** + * Tests that the enable/disable/default routes are protected from CSRF. + */ + public function testRouteProtection() { + // Ensure that the enable and disable routes are protected. + $this->drupalGet('admin/config/search/pages/manage/node_search/enable'); + $this->assertResponse(403); + $this->drupalGet('admin/config/search/pages/manage/node_search/disable'); + $this->assertResponse(403); + $this->drupalGet('admin/config/search/pages/manage/node_search/set-default'); + $this->assertResponse(403); + } + /** * Checks that the search page operations match expectations. * @@ -373,4 +388,17 @@ protected function assertDefaultSearch($expected, $message = '', $group = 'Other $this->assertIdentical($search_page_repository->getDefaultSearchPage(), $expected, $message, $group); } + /** + * Sets a search page as the default in the UI. + * + * @param string $entity_id + * The search page entity ID to enable. + */ + protected function setDefaultThroughUi($entity_id) { + $this->drupalGet('admin/config/search/pages'); + preg_match('|href="([^"]+' . $entity_id . '/set-default[^"]+)"|', $this->getRawContent(), $matches); + + $this->drupalGet($this->getAbsoluteUrl($matches[1])); + } + } diff --git a/core/modules/search/src/Tests/SearchEmbedFormTest.php b/core/modules/search/src/Tests/SearchEmbedFormTest.php index 22da9b61..5f3fbea3 100644 --- a/core/modules/search/src/Tests/SearchEmbedFormTest.php +++ b/core/modules/search/src/Tests/SearchEmbedFormTest.php @@ -14,7 +14,7 @@ class SearchEmbedFormTest extends SearchTestBase { * * @var array */ - public static $modules = array('search_embedded_form'); + public static $modules = ['search_embedded_form']; /** * Node used for testing. @@ -34,7 +34,7 @@ protected function setUp() { parent::setUp(); // Create a user and a node, and update the search index. - $test_user = $this->drupalCreateUser(array('access content', 'search content', 'administer nodes')); + $test_user = $this->drupalCreateUser(['access content', 'search content', 'administer nodes']); $this->drupalLogin($test_user); $this->node = $this->drupalCreateNode(); @@ -50,10 +50,10 @@ protected function setUp() { /** * Tests that the embedded form appears and can be submitted. */ - function testEmbeddedForm() { + public function testEmbeddedForm() { // First verify we can submit the form from the module's page. $this->drupalPostForm('search_embedded_form', - array('name' => 'John'), + ['name' => 'John'], t('Send away')); $this->assertText(t('Test form was submitted'), 'Form message appears'); $count = \Drupal::state()->get('search_embedded_form.submit_count'); @@ -61,10 +61,10 @@ function testEmbeddedForm() { $this->submitCount = $count; // Now verify that we can see and submit the form from the search results. - $this->drupalGet('search/node', array('query' => array('keys' => $this->node->label()))); + $this->drupalGet('search/node', ['query' => ['keys' => $this->node->label()]]); $this->assertText(t('Your name'), 'Form is visible'); $this->drupalPostForm(NULL, - array('name' => 'John'), + ['name' => 'John'], t('Send away')); $this->assertText(t('Test form was submitted'), 'Form message appears'); $count = \Drupal::state()->get('search_embedded_form.submit_count'); @@ -74,7 +74,7 @@ function testEmbeddedForm() { // Now verify that if we submit the search form, it doesn't count as // our form being submitted. $this->drupalPostForm('search', - array('keys' => 'foo'), + ['keys' => 'foo'], t('Search')); $this->assertNoText(t('Test form was submitted'), 'Form message does not appear'); $count = \Drupal::state()->get('search_embedded_form.submit_count'); diff --git a/core/modules/search/src/Tests/SearchKeywordsConditionsTest.php b/core/modules/search/src/Tests/SearchKeywordsConditionsTest.php deleted file mode 100644 index 1625d8de..00000000 --- a/core/modules/search/src/Tests/SearchKeywordsConditionsTest.php +++ /dev/null @@ -1,62 +0,0 @@ -searchingUser = $this->drupalCreateUser(array('search content', 'access content', 'access comments', 'skip comment approval')); - // Log in with sufficient privileges. - $this->drupalLogin($this->searchingUser); - } - - /** - * Verify the keywords are captured and conditions respected. - */ - function testSearchKeywordsConditions() { - // No keys, not conditions - no results. - $this->drupalGet('search/dummy_path'); - $this->assertNoText('Dummy search snippet to display'); - // With keys - get results. - $keys = 'bike shed ' . $this->randomMachineName(); - $this->drupalGet("search/dummy_path", array('query' => array('keys' => $keys))); - $this->assertText("Dummy search snippet to display. Keywords: {$keys}"); - $keys = 'blue drop ' . $this->randomMachineName(); - $this->drupalGet("search/dummy_path", array('query' => array('keys' => $keys))); - $this->assertText("Dummy search snippet to display. Keywords: {$keys}"); - // Add some conditions and keys. - $keys = 'moving drop ' . $this->randomMachineName(); - $this->drupalGet("search/dummy_path", array('query' => array('keys' => 'bike', 'search_conditions' => $keys))); - $this->assertText("Dummy search snippet to display."); - $this->assertRaw(Html::escape(print_r(array('keys' => 'bike', 'search_conditions' => $keys), TRUE))); - } - -} diff --git a/core/modules/search/src/Tests/SearchLanguageTest.php b/core/modules/search/src/Tests/SearchLanguageTest.php index cdd0bd4c..ec150855 100644 --- a/core/modules/search/src/Tests/SearchLanguageTest.php +++ b/core/modules/search/src/Tests/SearchLanguageTest.php @@ -17,7 +17,7 @@ class SearchLanguageTest extends SearchTestBase { * * @var array */ - public static $modules = array('language'); + public static $modules = ['language']; /** * Array of nodes available to search. @@ -30,7 +30,7 @@ protected function setUp() { parent::setUp(); // Create and log in user. - $test_user = $this->drupalCreateUser(array('access content', 'search content', 'use advanced search', 'administer nodes', 'administer languages', 'access administration pages', 'administer site configuration')); + $test_user = $this->drupalCreateUser(['access content', 'search content', 'use advanced search', 'administer nodes', 'administer languages', 'access administration pages', 'administer site configuration']); $this->drupalLogin($test_user); // Add a new language. @@ -45,38 +45,38 @@ protected function setUp() { // Create a few page nodes with multilingual body values. $default_format = filter_default_format(); - $nodes = array( - array( + $nodes = [ + [ 'title' => 'First node en', 'type' => 'page', - 'body' => array(array('value' => $this->randomMachineName(32), 'format' => $default_format)), + 'body' => [['value' => $this->randomMachineName(32), 'format' => $default_format]], 'langcode' => 'en', - ), - array( + ], + [ 'title' => 'Second node this is the Spanish title', 'type' => 'page', - 'body' => array(array('value' => $this->randomMachineName(32), 'format' => $default_format)), + 'body' => [['value' => $this->randomMachineName(32), 'format' => $default_format]], 'langcode' => 'es', - ), - array( + ], + [ 'title' => 'Third node en', 'type' => 'page', - 'body' => array(array('value' => $this->randomMachineName(32), 'format' => $default_format)), + 'body' => [['value' => $this->randomMachineName(32), 'format' => $default_format]], 'langcode' => 'en', - ), - ); + ], + ]; $this->searchableNodes = []; foreach ($nodes as $setting) { $this->searchableNodes[] = $this->drupalCreateNode($setting); } // Add English translation to the second node. - $translation = $this->searchableNodes[1]->addTranslation('en', array('title' => 'Second node en')); + $translation = $this->searchableNodes[1]->addTranslation('en', ['title' => 'Second node en']); $translation->body->value = $this->randomMachineName(32); $this->searchableNodes[1]->save(); // Add Spanish translation to the third node. - $translation = $this->searchableNodes[2]->addTranslation('es', array('title' => 'Third node es')); + $translation = $this->searchableNodes[2]->addTranslation('es', ['title' => 'Third node es']); $translation->body->value = $this->randomMachineName(32); $this->searchableNodes[2]->save(); @@ -86,9 +86,9 @@ protected function setUp() { search_update_totals(); } - function testLanguages() { + public function testLanguages() { // Add predefined language. - $edit = array('predefined_langcode' => 'fr'); + $edit = ['predefined_langcode' => 'fr']; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); $this->assertText('French', 'Language added successfully.'); @@ -99,11 +99,11 @@ function testLanguages() { $this->assertText(t('French'), 'French is a possible choice.'); // Ensure selecting no language does not make the query different. - $this->drupalPostForm('search/node', array(), t('Advanced search')); + $this->drupalPostForm('search/node', [], t('Advanced search')); $this->assertUrl(\Drupal::url('search.view_node_search', [], ['query' => ['keys' => ''], 'absolute' => TRUE]), [], 'Correct page redirection, no language filtering.'); // Pick French and ensure it is selected. - $edit = array('language[fr]' => TRUE); + $edit = ['language[fr]' => TRUE]; $this->drupalPostForm('search/node', $edit, t('Advanced search')); // Get the redirected URL. $url = $this->getUrl(); @@ -112,7 +112,7 @@ function testLanguages() { $this->assertTrue(strpos($query_string, '=language:fr') !== FALSE, 'Language filter language:fr add to the query string.'); // Search for keyword node and language filter as Spanish. - $edit = array('keys' => 'node', 'language[es]' => TRUE); + $edit = ['keys' => 'node', 'language[es]' => TRUE]; $this->drupalPostForm('search/node', $edit, t('Advanced search')); // Check for Spanish results. $this->assertLink('Second node this is the Spanish title', 0, 'Second node Spanish title found in search results'); @@ -126,12 +126,12 @@ function testLanguages() { $path = 'admin/config/regional/language'; $this->drupalGet($path); $this->assertFieldChecked('edit-site-default-language-en', 'Default language updated.'); - $edit = array( + $edit = [ 'site_default_language' => 'fr', - ); + ]; $this->drupalPostForm($path, $edit, t('Save configuration')); $this->assertNoFieldChecked('edit-site-default-language-en', 'Default language updated.'); - $this->drupalPostForm('admin/config/regional/language/delete/en', array(), t('Delete')); + $this->drupalPostForm('admin/config/regional/language/delete/en', [], t('Delete')); } } diff --git a/core/modules/search/src/Tests/SearchNodePunctuationTest.php b/core/modules/search/src/Tests/SearchNodePunctuationTest.php deleted file mode 100644 index c185aeac..00000000 --- a/core/modules/search/src/Tests/SearchNodePunctuationTest.php +++ /dev/null @@ -1,63 +0,0 @@ -testUser = $this->drupalCreateUser(array('access content', 'search content', 'use advanced search', 'access user profiles')); - $this->drupalLogin($this->testUser); - } - - /** - * Tests that search works with punctuation and HTML entities. - */ - function testPhraseSearchPunctuation() { - $node = $this->drupalCreateNode(array('body' => array(array('value' => "The bunny's ears were fluffy.")))); - $node2 = $this->drupalCreateNode(array('body' => array(array('value' => 'Dignissim Aliquam & Quieligo meus natu quae quia te. Damnum© erat— neo pneum. Facilisi feugiat ibidem ratis.')))); - - // Update the search index. - $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); - search_update_totals(); - - // Refresh variables after the treatment. - $this->refreshVariables(); - - // Submit a phrase wrapped in double quotes to include the punctuation. - $edit = array('keys' => '"bunny\'s"'); - $this->drupalPostForm('search/node', $edit, t('Search')); - $this->assertText($node->label()); - - // Check if the author is linked correctly to the user profile page. - $username = $node->getOwner()->getUsername(); - $this->assertLink($username); - - // Search for "&" and verify entities are not broken up in the output. - $edit = array('keys' => '&'); - $this->drupalPostForm('search/node', $edit, t('Search')); - $this->assertNoRaw('&amp;'); - $this->assertText('You must include at least one keyword'); - - $edit = array('keys' => '&'); - $this->drupalPostForm('search/node', $edit, t('Search')); - $this->assertNoRaw('&amp;'); - $this->assertText('You must include at least one keyword'); - } - -} diff --git a/core/modules/search/src/Tests/SearchNodeUpdateAndDeletionTest.php b/core/modules/search/src/Tests/SearchNodeUpdateAndDeletionTest.php index e73ca862..c19814e0 100644 --- a/core/modules/search/src/Tests/SearchNodeUpdateAndDeletionTest.php +++ b/core/modules/search/src/Tests/SearchNodeUpdateAndDeletionTest.php @@ -14,7 +14,7 @@ class SearchNodeUpdateAndDeletionTest extends SearchTestBase { * * @var array */ - public static $modules = array(); + public static $modules = []; /** * A user with permission to access and search content. @@ -27,19 +27,20 @@ protected function setUp() { parent::setUp(); // Create a test user and log in. - $this->testUser = $this->drupalCreateUser(array('access content', 'search content')); + $this->testUser = $this->drupalCreateUser(['access content', 'search content']); $this->drupalLogin($this->testUser); } /** * Tests that the search index info is properly updated when a node changes. */ - function testSearchIndexUpdateOnNodeChange() { + public function testSearchIndexUpdateOnNodeChange() { // Create a node. - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'title' => 'Someone who says Ni!', - 'body' => array(array('value' => "We are the knights who say Ni!")), - 'type' => 'page')); + 'body' => [['value' => "We are the knights who say Ni!"]], + 'type' => 'page', + ]); $node_search_plugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); // Update the search index. @@ -47,7 +48,7 @@ function testSearchIndexUpdateOnNodeChange() { search_update_totals(); // Search the node to verify it appears in search results - $edit = array('keys' => 'knights'); + $edit = ['keys' => 'knights']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText($node->label()); @@ -60,7 +61,7 @@ function testSearchIndexUpdateOnNodeChange() { search_update_totals(); // Search again to verify the new text appears in test results. - $edit = array('keys' => 'shrubbery'); + $edit = ['keys' => 'shrubbery']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText($node->label()); } @@ -68,12 +69,13 @@ function testSearchIndexUpdateOnNodeChange() { /** * Tests that the search index info is updated when a node is deleted. */ - function testSearchIndexUpdateOnNodeDeletion() { + public function testSearchIndexUpdateOnNodeDeletion() { // Create a node. - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'title' => 'No dragons here', - 'body' => array(array('value' => 'Again: No dragons here')), - 'type' => 'page')); + 'body' => [['value' => 'Again: No dragons here']], + 'type' => 'page', + ]); $node_search_plugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); // Update the search index. @@ -81,12 +83,12 @@ function testSearchIndexUpdateOnNodeDeletion() { search_update_totals(); // Search the node to verify it appears in search results - $edit = array('keys' => 'dragons'); + $edit = ['keys' => 'dragons']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText($node->label()); // Get the node info from the search index tables. - $search_index_dataset = db_query("SELECT sid FROM {search_index} WHERE type = 'node_search' AND word = :word", array(':word' => 'dragons')) + $search_index_dataset = db_query("SELECT sid FROM {search_index} WHERE type = 'node_search' AND word = :word", [':word' => 'dragons']) ->fetchField(); $this->assertNotEqual($search_index_dataset, FALSE, t('Node info found on the search_index')); @@ -94,7 +96,7 @@ function testSearchIndexUpdateOnNodeDeletion() { $node->delete(); // Check if the node info is gone from the search table. - $search_index_dataset = db_query("SELECT sid FROM {search_index} WHERE type = 'node_search' AND word = :word", array(':word' => 'dragons')) + $search_index_dataset = db_query("SELECT sid FROM {search_index} WHERE type = 'node_search' AND word = :word", [':word' => 'dragons']) ->fetchField(); $this->assertFalse($search_index_dataset, t('Node info successfully removed from search_index')); diff --git a/core/modules/search/src/Tests/SearchNumberMatchingTest.php b/core/modules/search/src/Tests/SearchNumberMatchingTest.php index a6ad0572..7671c7b1 100644 --- a/core/modules/search/src/Tests/SearchNumberMatchingTest.php +++ b/core/modules/search/src/Tests/SearchNumberMatchingTest.php @@ -27,7 +27,7 @@ class SearchNumberMatchingTest extends SearchTestBase { * * @var string[] */ - protected $numbers = array( + protected $numbers = [ '123456789', '12/34/56789', '12.3456789', @@ -35,7 +35,7 @@ class SearchNumberMatchingTest extends SearchTestBase { '123,456,789', '-123456789', '0123456789', - ); + ]; /** * An array of nodes created for testing purposes. @@ -47,15 +47,15 @@ class SearchNumberMatchingTest extends SearchTestBase { protected function setUp() { parent::setUp(); - $this->testUser = $this->drupalCreateUser(array('search content', 'access content', 'administer nodes', 'access site reports')); + $this->testUser = $this->drupalCreateUser(['search content', 'access content', 'administer nodes', 'access site reports']); $this->drupalLogin($this->testUser); foreach ($this->numbers as $num) { - $info = array( - 'body' => array(array('value' => $num)), + $info = [ + 'body' => [['value' => $num]], 'type' => 'page', 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ); + ]; $this->nodes[] = $this->drupalCreateNode($info); } @@ -68,16 +68,16 @@ protected function setUp() { /** * Tests that all the numbers can be searched. */ - function testNumberSearching() { + public function testNumberSearching() { for ($i = 0; $i < count($this->numbers); $i++) { $node = $this->nodes[$i]; // Verify that the node title does not appear on the search page // with a dummy search. $this->drupalPostForm('search/node', - array('keys' => 'foo'), + ['keys' => 'foo'], t('Search')); - $this->assertNoText($node->label(), format_string('%number: node title not shown in dummy search', array('%number' => $i))); + $this->assertNoText($node->label(), format_string('%number: node title not shown in dummy search', ['%number' => $i])); // Now verify that we can find node i by searching for any of the // numbers. @@ -88,9 +88,9 @@ function testNumberSearching() { $number = ltrim($number, '-'); $this->drupalPostForm('search/node', - array('keys' => $number), + ['keys' => $number], t('Search')); - $this->assertText($node->label(), format_string('%i: node title shown (search found the node) in search for number %number', array('%i' => $i, '%number' => $number))); + $this->assertText($node->label(), format_string('%i: node title shown (search found the node) in search for number %number', ['%i' => $i, '%number' => $number])); } } diff --git a/core/modules/search/src/Tests/SearchNumbersTest.php b/core/modules/search/src/Tests/SearchNumbersTest.php index 30d3906f..dbb50396 100644 --- a/core/modules/search/src/Tests/SearchNumbersTest.php +++ b/core/modules/search/src/Tests/SearchNumbersTest.php @@ -26,7 +26,7 @@ class SearchNumbersTest extends SearchTestBase { * * @var string[] */ - protected $numbers = array( + protected $numbers = [ 'ISBN' => '978-0446365383', 'UPC' => '036000 291452', 'EAN bar code' => '5901234123457', @@ -41,7 +41,7 @@ class SearchNumbersTest extends SearchTestBase { 'over fifty characters' => '666666666666666666666666666666666666666666666666666666666666', 'date' => '01/02/2009', 'commas' => '987,654,321', - ); + ]; /** * An array of nodes created for testing purposes. @@ -53,16 +53,16 @@ class SearchNumbersTest extends SearchTestBase { protected function setUp() { parent::setUp(); - $this->testUser = $this->drupalCreateUser(array('search content', 'access content', 'administer nodes', 'access site reports')); + $this->testUser = $this->drupalCreateUser(['search content', 'access content', 'administer nodes', 'access site reports']); $this->drupalLogin($this->testUser); foreach ($this->numbers as $doc => $num) { - $info = array( - 'body' => array(array('value' => $num)), + $info = [ + 'body' => [['value' => $num]], 'type' => 'page', 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'title' => $doc . ' number', - ); + ]; $this->nodes[$doc] = $this->drupalCreateNode($info); } @@ -75,7 +75,7 @@ protected function setUp() { /** * Tests that all the numbers can be searched. */ - function testNumberSearching() { + public function testNumberSearching() { $types = array_keys($this->numbers); foreach ($types as $type) { @@ -88,16 +88,16 @@ function testNumberSearching() { // Verify that the node title does not appear on the search page // with a dummy search. $this->drupalPostForm('search/node', - array('keys' => 'foo'), + ['keys' => 'foo'], t('Search')); $this->assertNoText($node->label(), $type . ': node title not shown in dummy search'); // Verify that the node title does appear as a link on the search page // when searching for the number. $this->drupalPostForm('search/node', - array('keys' => $number), + ['keys' => $number], t('Search')); - $this->assertText($node->label(), format_string('%type: node title shown (search found the node) in search for number %number.', array('%type' => $type, '%number' => $number))); + $this->assertText($node->label(), format_string('%type: node title shown (search found the node) in search for number %number.', ['%type' => $type, '%number' => $number])); } } diff --git a/core/modules/search/src/Tests/SearchPageCacheTagsTest.php b/core/modules/search/src/Tests/SearchPageCacheTagsTest.php index 3a7bc67e..417d9918 100644 --- a/core/modules/search/src/Tests/SearchPageCacheTagsTest.php +++ b/core/modules/search/src/Tests/SearchPageCacheTagsTest.php @@ -37,7 +37,7 @@ protected function setUp() { parent::setUp(); // Create user. - $this->searchingUser = $this->drupalCreateUser(array('search content', 'access user profiles')); + $this->searchingUser = $this->drupalCreateUser(['search content', 'access user profiles']); // Create a node and update the search index. $this->node = $this->drupalCreateNode(['title' => 'bike shed shop']); @@ -50,7 +50,7 @@ protected function setUp() { /** * Tests the presence of the expected cache tag in various situations. */ - function testSearchText() { + public function testSearchText() { $this->drupalLogin($this->searchingUser); // Initial page for searching nodes. @@ -60,7 +60,7 @@ function testSearchText() { $this->assertCacheTag('node_list'); // Node search results. - $edit = array(); + $edit = []; $edit['keys'] = 'bike shed'; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText('bike shed shop'); @@ -70,6 +70,7 @@ function testSearchText() { $this->assertCacheTag('node:1'); $this->assertCacheTag('user:2'); $this->assertCacheTag('rendered'); + $this->assertCacheTag('http_response'); $this->assertCacheTag('node_list'); // Updating a node should invalidate the search plugin's index cache tag. @@ -83,6 +84,7 @@ function testSearchText() { $this->assertCacheTag('node:1'); $this->assertCacheTag('user:2'); $this->assertCacheTag('rendered'); + $this->assertCacheTag('http_response'); $this->assertCacheTag('node_list'); // Deleting a node should invalidate the search plugin's index cache tag. @@ -172,6 +174,7 @@ public function testSearchTagsBubbling() { 'config:search.page.node_search', 'search_index', 'search_index:node_search', + 'http_response', 'rendered', 'node_list', ]; @@ -179,7 +182,7 @@ public function testSearchTagsBubbling() { // Node search results for shop, should return node:1 (bike shed shop) and // node:2 (Llama shop). The related authors cache tags should be visible as // well. - $edit = array(); + $edit = []; $edit['keys'] = 'shop'; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText('bike shed shop'); @@ -192,13 +195,12 @@ public function testSearchTagsBubbling() { 'node_view', 'config:filter.format.plain_text', ]); - $cache_tags = $this->drupalGetHeader('X-Drupal-Cache-Tags'); - $this->assertEqual(explode(' ', $cache_tags), $expected_cache_tags); + $this->assertCacheTags($expected_cache_tags); // Only get the new node in the search results, should result in node:1, // node:2 and user:3 as cache tags even though only node:1 is shown. This is // because node:2 is reference in node:1 as an entity reference. - $edit = array(); + $edit = []; $edit['keys'] = 'Llama'; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText('Llama shop'); @@ -208,8 +210,7 @@ public function testSearchTagsBubbling() { 'user:3', 'node_view', ]); - $cache_tags = $this->drupalGetHeader('X-Drupal-Cache-Tags'); - $this->assertEqual(explode(' ', $cache_tags), $expected_cache_tags); + $this->assertCacheTags($expected_cache_tags); } } diff --git a/core/modules/search/src/Tests/SearchPageOverrideTest.php b/core/modules/search/src/Tests/SearchPageOverrideTest.php deleted file mode 100644 index 97689045..00000000 --- a/core/modules/search/src/Tests/SearchPageOverrideTest.php +++ /dev/null @@ -1,44 +0,0 @@ -searchUser = $this->drupalCreateUser(array('search content', 'administer search')); - $this->drupalLogin($this->searchUser); - } - - function testSearchPageHook() { - $keys = 'bike shed ' . $this->randomMachineName(); - $this->drupalGet("search/dummy_path", array('query' => array('keys' => $keys))); - $this->assertText('Dummy search snippet', 'Dummy search snippet is shown'); - $this->assertText('Test page text is here', 'Page override is working'); - } - -} diff --git a/core/modules/search/src/Tests/SearchPageTextTest.php b/core/modules/search/src/Tests/SearchPageTextTest.php index db33d85c..95d097d2 100644 --- a/core/modules/search/src/Tests/SearchPageTextTest.php +++ b/core/modules/search/src/Tests/SearchPageTextTest.php @@ -32,7 +32,7 @@ protected function setUp() { parent::setUp(); // Create user. - $this->searchingUser = $this->drupalCreateUser(array('search content', 'access user profiles', 'use advanced search')); + $this->searchingUser = $this->drupalCreateUser(['search content', 'access user profiles', 'use advanced search']); $this->drupalPlaceBlock('local_tasks_block'); $this->drupalPlaceBlock('page_title_block'); } @@ -42,8 +42,8 @@ protected function setUp() { * * This is a regression test for https://www.drupal.org/node/2338081 */ - function testSearchLabelXSS() { - $this->drupalLogin($this->drupalCreateUser(array('administer search'))); + public function testSearchLabelXSS() { + $this->drupalLogin($this->drupalCreateUser(['administer search'])); $keys['label'] = ''; $this->drupalPostForm('admin/config/search/pages/manage/node_search', $keys, t('Save search page')); @@ -56,21 +56,21 @@ function testSearchLabelXSS() { /** * Tests the failed search text, and various other text on the search page. */ - function testSearchText() { + public function testSearchText() { $this->drupalLogin($this->searchingUser); $this->drupalGet('search/node'); $this->assertText(t('Enter your keywords')); $this->assertText(t('Search')); $this->assertTitle(t('Search') . ' | Drupal', 'Search page title is correct'); - $edit = array(); + $edit = []; $search_terms = 'bike shed ' . $this->randomMachineName(); $edit['keys'] = $search_terms; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText('search yielded no results'); $this->assertText(t('Search')); $title_source = 'Search for @keywords | Drupal'; - $this->assertTitle(t($title_source, array('@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE))), 'Search page title is correct'); + $this->assertTitle(t($title_source, ['@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE)]), 'Search page title is correct'); $this->assertNoText('Node', 'Erroneous tab and breadcrumb text is not present'); $this->assertNoText(t('Node'), 'Erroneous translated tab and breadcrumb text is not present'); $this->assertText(t('Content'), 'Tab and breadcrumb text is present'); @@ -80,23 +80,23 @@ function testSearchText() { $this->assertText('Use upper-case OR to get more results', 'Correct text is on content search help page'); // Search for a longer text, and see that it is in the title, truncated. - $edit = array(); + $edit = []; $search_terms = 'Every word is like an unnecessary stain on silence and nothingness.'; $edit['keys'] = $search_terms; $this->drupalPostForm('search/node', $edit, t('Search')); - $this->assertTitle(t($title_source, array('@keywords' => 'Every word is like an unnecessary stain on silence and…')), 'Search page title is correct'); + $this->assertTitle(t($title_source, ['@keywords' => 'Every word is like an unnecessary stain on silence and…']), 'Search page title is correct'); // Search for a string with a lot of special characters. $search_terms = 'Hear nothing > "see nothing" `feel' . " '1982."; $edit['keys'] = $search_terms; $this->drupalPostForm('search/node', $edit, t('Search')); $actual_title = (string) current($this->xpath('//title')); - $this->assertEqual($actual_title, Html::decodeEntities(t($title_source, array('@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE)))), 'Search page title is correct'); + $this->assertEqual($actual_title, Html::decodeEntities(t($title_source, ['@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE)])), 'Search page title is correct'); $edit['keys'] = $this->searchingUser->getUsername(); $this->drupalPostForm('search/user', $edit, t('Search')); $this->assertText(t('Search')); - $this->assertTitle(t($title_source, array('@keywords' => Unicode::truncate($this->searchingUser->getUsername(), 60, TRUE, TRUE)))); + $this->assertTitle(t($title_source, ['@keywords' => Unicode::truncate($this->searchingUser->getUsername(), 60, TRUE, TRUE)])); $this->clickLink('Search help'); $this->assertText('Search help', 'Correct title is on search help page'); @@ -105,14 +105,14 @@ function testSearchText() { // Test that search keywords containing slashes are correctly loaded // from the GET params and displayed in the search form. $arg = $this->randomMachineName() . '/' . $this->randomMachineName(); - $this->drupalGet('search/node', array('query' => array('keys' => $arg))); + $this->drupalGet('search/node', ['query' => ['keys' => $arg]]); $input = $this->xpath("//input[@id='edit-keys' and @value='{$arg}']"); $this->assertFalse(empty($input), 'Search keys with a / are correctly set as the default value in the search box.'); // Test a search input exceeding the limit of AND/OR combinations to test // the Denial-of-Service protection. $limit = $this->config('search.settings')->get('and_or_limit'); - $keys = array(); + $keys = []; for ($i = 0; $i < $limit + 1; $i++) { // Use a key of 4 characters to ensure we never generate 'AND' or 'OR'. $keys[] = $this->randomMachineName(4); @@ -122,40 +122,40 @@ function testSearchText() { } $edit['keys'] = implode(' ', $keys); $this->drupalPostForm('search/node', $edit, t('Search')); - $this->assertRaw(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => $limit))); + $this->assertRaw(t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', ['@count' => $limit])); // Test that a search on Node or User with no keywords entered generates // the "Please enter some keywords" message. - $this->drupalPostForm('search/node', array(), t('Search')); + $this->drupalPostForm('search/node', [], t('Search')); $this->assertText(t('Please enter some keywords'), 'With no keywords entered, message is displayed on node page'); - $this->drupalPostForm('search/user', array(), t('Search')); + $this->drupalPostForm('search/user', [], t('Search')); $this->assertText(t('Please enter some keywords'), 'With no keywords entered, message is displayed on user page'); // Make sure the "Please enter some keywords" message is NOT displayed if // you use "or" words or phrases in Advanced Search. - $this->drupalPostForm('search/node', array('or' => $this->randomMachineName() . ' ' . $this->randomMachineName()), t('Advanced search')); + $this->drupalPostForm('search/node', ['or' => $this->randomMachineName() . ' ' . $this->randomMachineName()], t('Advanced search')); $this->assertNoText(t('Please enter some keywords'), 'With advanced OR keywords entered, no keywords message is not displayed on node page'); - $this->drupalPostForm('search/node', array('phrase' => '"' . $this->randomMachineName() . '" "' . $this->randomMachineName() . '"'), t('Advanced search')); + $this->drupalPostForm('search/node', ['phrase' => '"' . $this->randomMachineName() . '" "' . $this->randomMachineName() . '"'], t('Advanced search')); $this->assertNoText(t('Please enter some keywords'), 'With advanced phrase entered, no keywords message is not displayed on node page'); // Verify that if you search for a too-short keyword, you get the right // message, and that if after that you search for a longer keyword, you // do not still see the message. - $this->drupalPostForm('search/node', array('keys' => $this->randomMachineName(1)), t('Search')); + $this->drupalPostForm('search/node', ['keys' => $this->randomMachineName(1)], t('Search')); $this->assertText('You must include at least one keyword', 'Keyword message is displayed when searching for short word'); $this->assertNoText(t('Please enter some keywords'), 'With short word entered, no keywords message is not displayed'); - $this->drupalPostForm(NULL, array('keys' => $this->randomMachineName()), t('Search')); + $this->drupalPostForm(NULL, ['keys' => $this->randomMachineName()], t('Search')); $this->assertNoText('You must include at least one keyword', 'Keyword message is not displayed when searching for long word after short word search'); // Test that if you search for a URL with .. in it, you still end up at // the search page. See issue https://www.drupal.org/node/890058. - $this->drupalPostForm('search/node', array('keys' => '../../admin'), t('Search')); + $this->drupalPostForm('search/node', ['keys' => '../../admin'], t('Search')); $this->assertResponse(200, 'Searching for ../../admin with non-admin user does not lead to a 403 error'); $this->assertText('no results', 'Searching for ../../admin with non-admin user gives you a no search results page'); // Test that if you search for a URL starting with "./", you still end up // at the search page. See issue https://www.drupal.org/node/1421560. - $this->drupalPostForm('search/node', array('keys' => '.something'), t('Search')); + $this->drupalPostForm('search/node', ['keys' => '.something'], t('Search')); $this->assertResponse(200, 'Searching for .something does not lead to a 403 error'); $this->assertText('no results', 'Searching for .something gives you a no search results page'); } diff --git a/core/modules/search/src/Tests/SearchPreprocessLangcodeTest.php b/core/modules/search/src/Tests/SearchPreprocessLangcodeTest.php index 38cb3508..ab264a1a 100644 --- a/core/modules/search/src/Tests/SearchPreprocessLangcodeTest.php +++ b/core/modules/search/src/Tests/SearchPreprocessLangcodeTest.php @@ -14,7 +14,7 @@ class SearchPreprocessLangcodeTest extends SearchTestBase { * * @var array */ - public static $modules = array('search_langcode_test'); + public static $modules = ['search_langcode_test']; /** * Test node for searching. @@ -26,21 +26,21 @@ class SearchPreprocessLangcodeTest extends SearchTestBase { protected function setUp() { parent::setUp(); - $web_user = $this->drupalCreateUser(array( + $web_user = $this->drupalCreateUser([ 'create page content', 'edit own page content', 'search content', 'use advanced search', - )); + ]); $this->drupalLogin($web_user); } /** * Tests that hook_search_preprocess() returns the correct langcode. */ - function testPreprocessLangcode() { + public function testPreprocessLangcode() { // Create a node. - $this->node = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'en')); + $this->node = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'en']); // First update the index. This does the initial processing. $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); @@ -53,7 +53,7 @@ function testPreprocessLangcode() { // Search for the additional text that is added by the preprocess // function. If you search for text that is in the node, preprocess is // not invoked on the node during the search excerpt generation. - $edit = array('or' => 'Additional text'); + $edit = ['or' => 'Additional text']; $this->drupalPostForm('search/node', $edit, t('Advanced search')); // Checks if the langcode message has been set by hook_search_preprocess(). @@ -63,13 +63,13 @@ function testPreprocessLangcode() { /** * Tests stemming for hook_search_preprocess(). */ - function testPreprocessStemming() { + public function testPreprocessStemming() { // Create a node. - $this->node = $this->drupalCreateNode(array( + $this->node = $this->drupalCreateNode([ 'title' => 'we are testing', - 'body' => array(array()), + 'body' => [[]], 'langcode' => 'en', - )); + ]); // First update the index. This does the initial processing. $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); @@ -80,7 +80,7 @@ function testPreprocessStemming() { search_update_totals(); // Search for the title of the node with a POST query. - $edit = array('or' => 'testing'); + $edit = ['or' => 'testing']; $this->drupalPostForm('search/node', $edit, t('Advanced search')); // Check if the node has been found. @@ -88,7 +88,7 @@ function testPreprocessStemming() { $this->assertText('we are testing'); // Search for the same node using a different query. - $edit = array('or' => 'test'); + $edit = ['or' => 'test']; $this->drupalPostForm('search/node', $edit, t('Advanced search')); // Check if the node has been found. diff --git a/core/modules/search/src/Tests/SearchQueryAlterTest.php b/core/modules/search/src/Tests/SearchQueryAlterTest.php index 0cb473f5..66269dd6 100644 --- a/core/modules/search/src/Tests/SearchQueryAlterTest.php +++ b/core/modules/search/src/Tests/SearchQueryAlterTest.php @@ -13,22 +13,22 @@ class SearchQueryAlterTest extends SearchTestBase { * * @var array */ - public static $modules = array('search_query_alter'); + public static $modules = ['search_query_alter']; /** * Tests that the query alter works. */ - function testQueryAlter() { + public function testQueryAlter() { // Log in with sufficient privileges. - $this->drupalLogin($this->drupalCreateUser(array('create page content', 'search content'))); + $this->drupalLogin($this->drupalCreateUser(['create page content', 'search content'])); // Create a node and an article with the same keyword. The query alter // test module will alter the query so only articles should be returned. - $data = array( + $data = [ 'type' => 'page', 'title' => 'test page', - 'body' => array(array('value' => 'pizza')), - ); + 'body' => [['value' => 'pizza']], + ]; $this->drupalCreateNode($data); $data['type'] = 'article'; @@ -40,7 +40,7 @@ function testQueryAlter() { search_update_totals(); // Search for the body keyword 'pizza'. - $this->drupalPostForm('search/node', array('keys' => 'pizza'), t('Search')); + $this->drupalPostForm('search/node', ['keys' => 'pizza'], t('Search')); // The article should be there but not the page. $this->assertText('article', 'Article is in search results'); $this->assertNoText('page', 'Page is not in search results'); diff --git a/core/modules/search/src/Tests/SearchRankingTest.php b/core/modules/search/src/Tests/SearchRankingTest.php index 2045233e..55da9acb 100644 --- a/core/modules/search/src/Tests/SearchRankingTest.php +++ b/core/modules/search/src/Tests/SearchRankingTest.php @@ -29,7 +29,7 @@ class SearchRankingTest extends SearchTestBase { * * @var array */ - public static $modules = array('statistics', 'comment'); + public static $modules = ['statistics', 'comment']; protected function setUp() { parent::setUp(); @@ -38,7 +38,7 @@ protected function setUp() { $this->nodeSearch = SearchPage::load('node_search'); // Log in with sufficient privileges. - $this->drupalLogin($this->drupalCreateUser(array('post comments', 'skip comment approval', 'create page content', 'administer search'))); + $this->drupalLogin($this->drupalCreateUser(['post comments', 'skip comment approval', 'create page content', 'administer search'])); } public function testRankings() { @@ -46,24 +46,24 @@ public function testRankings() { $this->addDefaultCommentField('node', 'page'); // Build a list of the rankings to test. - $node_ranks = array('sticky', 'promote', 'relevance', 'recent', 'comments', 'views'); + $node_ranks = ['sticky', 'promote', 'relevance', 'recent', 'comments', 'views']; // Create nodes for testing. - $nodes = array(); + $nodes = []; foreach ($node_ranks as $node_rank) { - $settings = array( + $settings = [ 'type' => 'page', - 'comment' => array(array( - 'status' => CommentItemInterface::HIDDEN, - )), + 'comment' => [ + ['status' => CommentItemInterface::HIDDEN], + ], 'title' => 'Drupal rocks', - 'body' => array(array('value' => "Drupal's search rocks")), + 'body' => [['value' => "Drupal's search rocks"]], // Node is one day old. 'created' => REQUEST_TIME - 24 * 3600, 'sticky' => 0, 'promote' => 0, - ); - foreach (array(0, 1) as $num) { + ]; + foreach ([0, 1] as $num) { if ($num == 1) { switch ($node_rank) { case 'sticky': @@ -87,7 +87,7 @@ public function testRankings() { } // Add a comment to one of the nodes. - $edit = array(); + $edit = []; $edit['subject[0][value]'] = 'my comment title'; $edit['comment_body[0][value]'] = 'some random comment'; $this->drupalGet('comment/reply/node/' . $nodes['comments'][1]->id() . '/comment'); @@ -102,7 +102,7 @@ public function testRankings() { // counter for this node. $nid = $nodes['views'][1]->id(); db_insert('node_counter') - ->fields(array('totalcount' => 5, 'daycount' => 5, 'timestamp' => REQUEST_TIME, 'nid' => $nid)) + ->fields(['totalcount' => 5, 'daycount' => 5, 'timestamp' => REQUEST_TIME, 'nid' => $nid]) ->execute(); // Run cron to update the search index and comment/statistics totals. @@ -118,7 +118,7 @@ public function testRankings() { } // Test each of the possible rankings. - $edit = array(); + $edit = []; foreach ($node_ranks as $node_rank) { // Enable the ranking we are testing. $edit['rankings[' . $node_rank . '][value]'] = 10; @@ -129,7 +129,7 @@ public function testRankings() { // Reload the plugin to get the up-to-date values. $this->nodeSearch = SearchPage::load('node_search'); // Do the search and assert the results. - $this->nodeSearch->getPlugin()->setSearch('rocks', array(), array()); + $this->nodeSearch->getPlugin()->setSearch('rocks', [], []); $set = $this->nodeSearch->getPlugin()->execute(); $this->assertEqual($set[0]['node']->id(), $nodes[$node_rank][1]->id(), 'Search ranking "' . $node_rank . '" order.'); @@ -147,14 +147,14 @@ public function testRankings() { // Try with sticky, then promoted. This is a test for issue // https://www.drupal.org/node/771596. - $node_ranks = array( + $node_ranks = [ 'sticky' => 10, 'promote' => 1, 'relevance' => 0, 'recent' => 0, 'comments' => 0, 'views' => 0, - ); + ]; $configuration = $this->nodeSearch->getPlugin()->getConfiguration(); foreach ($node_ranks as $var => $value) { $configuration['rankings'][$var] = $value; @@ -164,7 +164,7 @@ public function testRankings() { // Do the search and assert the results. The sticky node should show up // first, then the promoted node, then all the rest. - $this->nodeSearch->getPlugin()->setSearch('rocks', array(), array()); + $this->nodeSearch->getPlugin()->setSearch('rocks', [], []); $set = $this->nodeSearch->getPlugin()->execute(); $this->assertEqual($set[0]['node']->id(), $nodes['sticky'][1]->id(), 'Search ranking for sticky first worked.'); $this->assertEqual($set[1]['node']->id(), $nodes['promote'][1]->id(), 'Search ranking for promoted second worked.'); @@ -172,14 +172,14 @@ public function testRankings() { // Try with recent, then comments. This is a test for issues // https://www.drupal.org/node/771596 and // https://www.drupal.org/node/303574. - $node_ranks = array( + $node_ranks = [ 'sticky' => 0, 'promote' => 0, 'relevance' => 0, 'recent' => 10, 'comments' => 1, 'views' => 0, - ); + ]; $configuration = $this->nodeSearch->getPlugin()->getConfiguration(); foreach ($node_ranks as $var => $value) { $configuration['rankings'][$var] = $value; @@ -189,7 +189,7 @@ public function testRankings() { // Do the search and assert the results. The recent node should show up // first, then the commented node, then all the rest. - $this->nodeSearch->getPlugin()->setSearch('rocks', array(), array()); + $this->nodeSearch->getPlugin()->setSearch('rocks', [], []); $set = $this->nodeSearch->getPlugin()->execute(); $this->assertEqual($set[0]['node']->id(), $nodes['recent'][1]->id(), 'Search ranking for recent first worked.'); $this->assertEqual($set[1]['node']->id(), $nodes['comments'][1]->id(), 'Search ranking for comments second worked.'); @@ -200,33 +200,33 @@ public function testRankings() { * Test rankings of HTML tags. */ public function testHTMLRankings() { - $full_html_format = FilterFormat::create(array( + $full_html_format = FilterFormat::create([ 'format' => 'full_html', 'name' => 'Full HTML', - )); + ]); $full_html_format->save(); // Test HTML tags with different weights. - $sorted_tags = array('h1', 'h2', 'h3', 'h4', 'a', 'h5', 'h6', 'notag'); + $sorted_tags = ['h1', 'h2', 'h3', 'h4', 'a', 'h5', 'h6', 'notag']; $shuffled_tags = $sorted_tags; // Shuffle tags to ensure HTML tags are ranked properly. shuffle($shuffled_tags); - $settings = array( + $settings = [ 'type' => 'page', 'title' => 'Simple node', - ); - $nodes = array(); + ]; + $nodes = []; foreach ($shuffled_tags as $tag) { switch ($tag) { case 'a': - $settings['body'] = array(array('value' => \Drupal::l('Drupal Rocks', new Url('')), 'format' => 'full_html')); + $settings['body'] = [['value' => \Drupal::l('Drupal Rocks', new Url('')), 'format' => 'full_html']]; break; case 'notag': - $settings['body'] = array(array('value' => 'Drupal Rocks')); + $settings['body'] = [['value' => 'Drupal Rocks']]; break; default: - $settings['body'] = array(array('value' => "<$tag>Drupal Rocks", 'format' => 'full_html')); + $settings['body'] = [['value' => "<$tag>Drupal Rocks", 'format' => 'full_html']]; break; } $nodes[$tag] = $this->drupalCreateNode($settings); @@ -236,7 +236,7 @@ public function testHTMLRankings() { $this->nodeSearch->getPlugin()->updateIndex(); search_update_totals(); - $this->nodeSearch->getPlugin()->setSearch('rocks', array(), array()); + $this->nodeSearch->getPlugin()->setSearch('rocks', [], []); // Do the search and assert the results. $set = $this->nodeSearch->getPlugin()->execute(); @@ -252,16 +252,16 @@ public function testHTMLRankings() { } // Test tags with the same weight against the sorted tags. - $unsorted_tags = array('u', 'b', 'i', 'strong', 'em'); + $unsorted_tags = ['u', 'b', 'i', 'strong', 'em']; foreach ($unsorted_tags as $tag) { - $settings['body'] = array(array('value' => "<$tag>Drupal Rocks", 'format' => 'full_html')); + $settings['body'] = [['value' => "<$tag>Drupal Rocks", 'format' => 'full_html']]; $node = $this->drupalCreateNode($settings); // Update the search index. $this->nodeSearch->getPlugin()->updateIndex(); search_update_totals(); - $this->nodeSearch->getPlugin()->setSearch('rocks', array(), array()); + $this->nodeSearch->getPlugin()->setSearch('rocks', [], []); // Do the search and assert the results. $set = $this->nodeSearch->getPlugin()->execute(); diff --git a/core/modules/search/src/Tests/SearchTestBase.php b/core/modules/search/src/Tests/SearchTestBase.php index 83967b3a..1c157b6d 100644 --- a/core/modules/search/src/Tests/SearchTestBase.php +++ b/core/modules/search/src/Tests/SearchTestBase.php @@ -7,6 +7,9 @@ /** * Defines the common search test code. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\search\Functional\SearchTestBase instead. */ abstract class SearchTestBase extends WebTestBase { @@ -15,15 +18,15 @@ abstract class SearchTestBase extends WebTestBase { * * @var array */ - public static $modules = array('node', 'search', 'dblog'); + public static $modules = ['node', 'search', 'dblog']; protected function setUp() { parent::setUp(); // Create Basic page and Article node types. if ($this->profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); } } @@ -68,13 +71,13 @@ protected function submitGetForm($path, $edit, $submit, $form_html_id = NULL) { foreach ($forms as $form) { // Try to set the fields of this form as specified in $edit. $edit = $edit_save; - $post = array(); - $upload = array(); + $post = []; + $upload = []; $submit_matches = $this->handleForm($post, $edit, $upload, $submit, $form); if (!$edit && $submit_matches) { // Everything matched, so "submit" the form. $action = isset($form['action']) ? $this->getAbsoluteUrl((string) $form['action']) : NULL; - $this->drupalGet($action, array('query' => $post)); + $this->drupalGet($action, ['query' => $post]); return; } } @@ -82,10 +85,10 @@ protected function submitGetForm($path, $edit, $submit, $form_html_id = NULL) { // We have not found a form which contained all fields of $edit and // the submit button. foreach ($edit as $name => $value) { - $this->fail(SafeMarkup::format('Failed to set field @name to @value', array('@name' => $name, '@value' => $value))); + $this->fail(SafeMarkup::format('Failed to set field @name to @value', ['@name' => $name, '@value' => $value])); } - $this->assertTrue($submit_matches, format_string('Found the @submit button', array('@submit' => $submit))); - $this->fail(format_string('Found the requested form fields at @path', array('@path' => $path))); + $this->assertTrue($submit_matches, format_string('Found the @submit button', ['@submit' => $submit])); + $this->fail(format_string('Found the requested form fields at @path', ['@path' => $path])); } } diff --git a/core/modules/search/src/ViewsSearchQuery.php b/core/modules/search/src/ViewsSearchQuery.php index fc67ed17..ca804a88 100644 --- a/core/modules/search/src/ViewsSearchQuery.php +++ b/core/modules/search/src/ViewsSearchQuery.php @@ -69,13 +69,13 @@ public function publicParseSearchExpression() { * item from a \Drupal\Core\Database\Query\Condition::conditions array, * which must have a 'field' element. */ - function conditionReplaceString($search, $replace, &$condition) { + public function conditionReplaceString($search, $replace, &$condition) { if ($condition['field'] instanceof Condition) { $conditions =& $condition['field']->conditions(); foreach ($conditions as $key => &$subcondition) { if (is_numeric($key)) { - // As conditions can have subconditions, for example db_or(), the - // function has to be called recursively. + // As conditions can be nested, the function has to be called + // recursively. $this->conditionReplaceString($search, $replace, $subcondition); } } diff --git a/core/modules/search/tests/modules/search_date_query_alter/search_date_query_alter.info.yml b/core/modules/search/tests/modules/search_date_query_alter/search_date_query_alter.info.yml index 214e944f..2750e384 100644 --- a/core/modules/search/tests/modules/search_date_query_alter/search_date_query_alter.info.yml +++ b/core/modules/search/tests/modules/search_date_query_alter/search_date_query_alter.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.info.yml b/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.info.yml index a3b7b494..e93e752c 100644 --- a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.info.yml +++ b/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/search/tests/modules/search_embedded_form/src/Form/SearchEmbeddedForm.php b/core/modules/search/tests/modules/search_embedded_form/src/Form/SearchEmbeddedForm.php index 29c047d0..64d9418f 100644 --- a/core/modules/search/tests/modules/search_embedded_form/src/Form/SearchEmbeddedForm.php +++ b/core/modules/search/tests/modules/search_embedded_form/src/Form/SearchEmbeddedForm.php @@ -23,20 +23,20 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { $count = \Drupal::state()->get('search_embedded_form.submit_count'); - $form['name'] = array( + $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Your name'), '#maxlength' => 255, '#default_value' => '', '#required' => TRUE, - '#description' => $this->t('Times form has been submitted: %count', array('%count' => $count)), - ); + '#description' => $this->t('Times form has been submitted: %count', ['%count' => $count]), + ]; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Send away'), - ); + ]; return $form; } diff --git a/core/modules/search/tests/modules/search_extra_type/search_extra_type.info.yml b/core/modules/search/tests/modules/search_extra_type/search_extra_type.info.yml index b40ea9f3..31e8affe 100644 --- a/core/modules/search/tests/modules/search_extra_type/search_extra_type.info.yml +++ b/core/modules/search/tests/modules/search_extra_type/search_extra_type.info.yml @@ -8,8 +8,8 @@ dependencies: - test_page_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php b/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php index d02fd81a..899986ae 100644 --- a/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php +++ b/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php @@ -50,18 +50,18 @@ public function isSearchExecutable() { * A structured list of search results */ public function execute() { - $results = array(); + $results = []; if (!$this->isSearchExecutable()) { return $results; } - return array( - array( + return [ + [ 'link' => Url::fromRoute('test_page_test.test_page')->toString(), 'type' => 'Dummy result type', 'title' => 'Dummy title', 'snippet' => SafeMarkup::format("Dummy search snippet to display. Keywords: @keywords\n\nConditions: @search_parameters", ['@keywords' => $this->keywords, '@search_parameters' => print_r($this->searchParameters, TRUE)]), - ), - ); + ], + ]; } /** @@ -72,16 +72,16 @@ public function buildResults() { $output['prefix']['#markup'] = '

    Test page text is here

      '; foreach ($results as $entry) { - $output[] = array( + $output[] = [ '#theme' => 'search_result', '#result' => $entry, '#plugin_id' => 'search_extra_type_search', - ); + ]; } - $pager = array( + $pager = [ '#type' => 'pager', - ); - $output['suffix']['#markup'] = '
    ' . drupal_render($pager); + ]; + $output['suffix']['#markup'] = '' . \Drupal::service('renderer')->render($pager); return $output; } @@ -91,21 +91,21 @@ public function buildResults() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { // Output form for defining rank factor weights. - $form['extra_type_settings'] = array( + $form['extra_type_settings'] = [ '#type' => 'fieldset', '#title' => t('Extra type settings'), '#tree' => TRUE, - ); + ]; - $form['extra_type_settings']['boost'] = array( + $form['extra_type_settings']['boost'] = [ '#type' => 'select', '#title' => t('Boost method'), - '#options' => array( + '#options' => [ 'bi' => t('Bistromathic'), 'ii' => t('Infinite Improbability'), - ), + ], '#default_value' => $this->configuration['boost'], - ); + ]; return $form; } @@ -113,16 +113,16 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { - $this->configuration['boost'] = $form_state->getValue(array('extra_type_settings', 'boost')); + $this->configuration['boost'] = $form_state->getValue(['extra_type_settings', 'boost']); } /** * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'boost' => 'bi', - ); + ]; } } diff --git a/core/modules/search/tests/modules/search_langcode_test/search_langcode_test.info.yml b/core/modules/search/tests/modules/search_langcode_test/search_langcode_test.info.yml index 6a23ae2a..fb12f454 100644 --- a/core/modules/search/tests/modules/search_langcode_test/search_langcode_test.info.yml +++ b/core/modules/search/tests/modules/search_langcode_test/search_langcode_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/search/tests/modules/search_query_alter/search_query_alter.info.yml b/core/modules/search/tests/modules/search_query_alter/search_query_alter.info.yml index 21627f92..6bb566f8 100644 --- a/core/modules/search/tests/modules/search_query_alter/search_query_alter.info.yml +++ b/core/modules/search/tests/modules/search_query_alter/search_query_alter.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/search/src/Tests/SearchCommentCountToggleTest.php b/core/modules/search/tests/src/Functional/SearchCommentCountToggleTest.php similarity index 90% rename from core/modules/search/src/Tests/SearchCommentCountToggleTest.php rename to core/modules/search/tests/src/Functional/SearchCommentCountToggleTest.php index 48f8bb64..7cd9f856 100644 --- a/core/modules/search/src/Tests/SearchCommentCountToggleTest.php +++ b/core/modules/search/tests/src/Functional/SearchCommentCountToggleTest.php @@ -1,6 +1,6 @@ searchingUser = $this->drupalCreateUser(array('search content', 'access content', 'access comments', 'post comments', 'skip comment approval')); + $this->searchingUser = $this->drupalCreateUser(['search content', 'access content', 'access comments', 'post comments', 'skip comment approval']); // Log in with sufficient privileges. $this->drupalLogin($this->searchingUser); @@ -54,13 +54,13 @@ protected function setUp() { // Add a comment field. $this->addDefaultCommentField('node', 'article'); // Create initial nodes. - $node_params = array('type' => 'article', 'body' => array(array('value' => 'SearchCommentToggleTestCase'))); + $node_params = ['type' => 'article', 'body' => [['value' => 'SearchCommentToggleTestCase']]]; $this->searchableNodes['1 comment'] = $this->drupalCreateNode($node_params); $this->searchableNodes['0 comments'] = $this->drupalCreateNode($node_params); // Create a comment array - $edit_comment = array(); + $edit_comment = []; $edit_comment['subject[0][value]'] = $this->randomMachineName(); $edit_comment['comment_body[0][value]'] = $this->randomMachineName(); @@ -79,11 +79,11 @@ protected function setUp() { /** * Verify that comment count display toggles properly on comment status of node */ - function testSearchCommentCountToggle() { + public function testSearchCommentCountToggle() { // Search for the nodes by string in the node body. - $edit = array( + $edit = [ 'keys' => "'SearchCommentToggleTestCase'", - ); + ]; $this->drupalGet('search/node'); // Test comment count display for nodes with comment status set to Open diff --git a/core/modules/search/src/Tests/SearchDateIntervalTest.php b/core/modules/search/tests/src/Functional/SearchDateIntervalTest.php similarity index 93% rename from core/modules/search/src/Tests/SearchDateIntervalTest.php rename to core/modules/search/tests/src/Functional/SearchDateIntervalTest.php index 967f1f53..82769139 100644 --- a/core/modules/search/src/Tests/SearchDateIntervalTest.php +++ b/core/modules/search/tests/src/Functional/SearchDateIntervalTest.php @@ -1,6 +1,6 @@ $default_format, ], 'langcode' => 'en', - 'created' => $created_time_en->format('U'), + 'created' => $created_time_en->getTimestamp(), ]); // Add Spanish translation to the node. $translation = $node->addTranslation('es', ['title' => 'Node ES']); $translation->body->value = $this->randomMachineName(32); - $translation->created->value = $created_time_es->format('U'); + $translation->created->value = $created_time_es->getTimestamp(); $node->save(); // Update the index. diff --git a/core/modules/search/src/Tests/SearchExactTest.php b/core/modules/search/tests/src/Functional/SearchExactTest.php similarity index 84% rename from core/modules/search/src/Tests/SearchExactTest.php rename to core/modules/search/tests/src/Functional/SearchExactTest.php index d17646bb..04163918 100644 --- a/core/modules/search/src/Tests/SearchExactTest.php +++ b/core/modules/search/tests/src/Functional/SearchExactTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('create page content', 'search content')); + $user = $this->drupalCreateUser(['create page content', 'search content']); $this->drupalLogin($user); - $settings = array( + $settings = [ 'type' => 'page', 'title' => 'Simple Node', - ); + ]; // Create nodes with exact phrase. for ($i = 0; $i <= 17; $i++) { - $settings['body'] = array(array('value' => 'love pizza')); + $settings['body'] = [['value' => 'love pizza']]; $this->drupalCreateNode($settings); } // Create nodes containing keywords. for ($i = 0; $i <= 17; $i++) { - $settings['body'] = array(array('value' => 'love cheesy pizza')); + $settings['body'] = [['value' => 'love cheesy pizza']]; $this->drupalCreateNode($settings); } // Create another node and save it for later. - $settings['body'] = array(array('value' => 'Druplicon')); + $settings['body'] = [['value' => 'Druplicon']]; $node = $this->drupalCreateNode($settings); // Update the search index. @@ -42,7 +42,7 @@ function testExactQuery() { $this->refreshVariables(); // Test that the correct number of pager links are found for keyword search. - $edit = array('keys' => 'love pizza'); + $edit = ['keys' => 'love pizza']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertLinkByHref('page=1', 0, '2nd page link is found for keyword search.'); $this->assertLinkByHref('page=2', 0, '3rd page link is found for keyword search.'); @@ -50,7 +50,7 @@ function testExactQuery() { $this->assertNoLinkByHref('page=4', '5th page link is not found for keyword search.'); // Test that the correct number of pager links are found for exact phrase search. - $edit = array('keys' => '"love pizza"'); + $edit = ['keys' => '"love pizza"']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertLinkByHref('page=1', 0, '2nd page link is found for exact phrase search.'); $this->assertNoLinkByHref('page=2', '3rd page link is not found for exact phrase search.'); @@ -60,7 +60,7 @@ function testExactQuery() { $node_type_config->set('display_submitted', TRUE); $node_type_config->save(); - $edit = array('keys' => 'Druplicon'); + $edit = ['keys' => 'Druplicon']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertText($user->getUsername(), 'Basic page node displays author name when post settings are on.'); $this->assertText(format_date($node->getChangedTime(), 'short'), 'Basic page node displays post date when post settings are on.'); @@ -69,7 +69,7 @@ function testExactQuery() { // information is not displayed. $node_type_config->set('display_submitted', FALSE); $node_type_config->save(); - $edit = array('keys' => 'Druplicon'); + $edit = ['keys' => 'Druplicon']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertNoText($user->getUsername(), 'Basic page node does not display author name when post settings are off.'); $this->assertNoText(format_date($node->getChangedTime(), 'short'), 'Basic page node does not display post date when post settings are off.'); diff --git a/core/modules/search/tests/src/Functional/SearchKeywordsConditionsTest.php b/core/modules/search/tests/src/Functional/SearchKeywordsConditionsTest.php new file mode 100644 index 00000000..26bff66b --- /dev/null +++ b/core/modules/search/tests/src/Functional/SearchKeywordsConditionsTest.php @@ -0,0 +1,62 @@ +searchingUser = $this->drupalCreateUser(['search content', 'access content', 'access comments', 'skip comment approval']); + // Log in with sufficient privileges. + $this->drupalLogin($this->searchingUser); + } + + /** + * Verify the keywords are captured and conditions respected. + */ + public function testSearchKeywordsConditions() { + // No keys, not conditions - no results. + $this->drupalGet('search/dummy_path'); + $this->assertNoText('Dummy search snippet to display'); + // With keys - get results. + $keys = 'bike shed ' . $this->randomMachineName(); + $this->drupalGet("search/dummy_path", ['query' => ['keys' => $keys]]); + $this->assertText("Dummy search snippet to display. Keywords: {$keys}"); + $keys = 'blue drop ' . $this->randomMachineName(); + $this->drupalGet("search/dummy_path", ['query' => ['keys' => $keys]]); + $this->assertText("Dummy search snippet to display. Keywords: {$keys}"); + // Add some conditions and keys. + $keys = 'moving drop ' . $this->randomMachineName(); + $this->drupalGet("search/dummy_path", ['query' => ['keys' => 'bike', 'search_conditions' => $keys]]); + $this->assertText("Dummy search snippet to display."); + $this->assertRaw(Html::escape(print_r(['keys' => 'bike', 'search_conditions' => $keys], TRUE))); + } + +} diff --git a/core/modules/search/src/Tests/SearchMultilingualEntityTest.php b/core/modules/search/tests/src/Functional/SearchMultilingualEntityTest.php similarity index 86% rename from core/modules/search/src/Tests/SearchMultilingualEntityTest.php rename to core/modules/search/tests/src/Functional/SearchMultilingualEntityTest.php index e133101d..9b3a6ddc 100644 --- a/core/modules/search/src/Tests/SearchMultilingualEntityTest.php +++ b/core/modules/search/tests/src/Functional/SearchMultilingualEntityTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('administer search', 'search content', 'use advanced search', 'access content', 'access site reports', 'administer site configuration')); + $user = $this->drupalCreateUser(['administer search', 'search content', 'use advanced search', 'access content', 'access site reports', 'administer site configuration']); $this->drupalLogin($user); // Set up the search plugin. @@ -56,53 +56,48 @@ protected function setUp() { // Create a few page nodes with multilingual body values. $default_format = filter_default_format(); - $nodes = array( - array( + $nodes = [ + [ 'title' => 'First node en', 'type' => 'page', - 'body' => array(array('value' => $this->randomMachineName(32), 'format' => $default_format)), + 'body' => [['value' => $this->randomMachineName(32), 'format' => $default_format]], 'langcode' => 'en', - ), - array( + ], + [ 'title' => 'Second node this is the English title', 'type' => 'page', - 'body' => array(array('value' => $this->randomMachineName(32), 'format' => $default_format)), + 'body' => [['value' => $this->randomMachineName(32), 'format' => $default_format]], 'langcode' => 'en', - ), - array( + ], + [ 'title' => 'Third node en', 'type' => 'page', - 'body' => array(array('value' => $this->randomMachineName(32), 'format' => $default_format)), + 'body' => [['value' => $this->randomMachineName(32), 'format' => $default_format]], 'langcode' => 'en', - ), + ], // After the third node, we don't care what the settings are. But we // need to have at least 5 to make sure the throttling is working // correctly. So, let's make 8 total. - array( - ), - array( - ), - array( - ), - array( - ), - array( - ), - ); - $this->searchableNodes = array(); + [], + [], + [], + [], + [], + ]; + $this->searchableNodes = []; foreach ($nodes as $setting) { $this->searchableNodes[] = $this->drupalCreateNode($setting); } // Add a single translation to the second node. - $translation = $this->searchableNodes[1]->addTranslation('hu', array('title' => 'Second node hu')); + $translation = $this->searchableNodes[1]->addTranslation('hu', ['title' => 'Second node hu']); $translation->body->value = $this->randomMachineName(32); $this->searchableNodes[1]->save(); // Add two translations to the third node. - $translation = $this->searchableNodes[2]->addTranslation('hu', array('title' => 'Third node this is the Hungarian title')); + $translation = $this->searchableNodes[2]->addTranslation('hu', ['title' => 'Third node this is the Hungarian title']); $translation->body->value = $this->randomMachineName(32); - $translation = $this->searchableNodes[2]->addTranslation('sv', array('title' => 'Third node sv')); + $translation = $this->searchableNodes[2]->addTranslation('sv', ['title' => 'Third node sv']); $translation->body->value = $this->randomMachineName(32); $this->searchableNodes[2]->save(); @@ -114,7 +109,7 @@ protected function setUp() { /** * Tests the indexing throttle and search results with multilingual nodes. */ - function testMultilingualSearch() { + public function testMultilingualSearch() { // Index only 2 nodes per cron run. We cannot do this setting in the UI, // because it doesn't go this low. $this->config('search.settings')->set('index.cron_limit', 2)->save(); @@ -132,7 +127,7 @@ function testMultilingualSearch() { // Now index the rest of the nodes. // Make sure index throttle is high enough, via the UI. - $this->drupalPostForm('admin/config/search/pages', array('cron_limit' => 20), t('Save configuration')); + $this->drupalPostForm('admin/config/search/pages', ['cron_limit' => 20], t('Save configuration')); $this->assertEqual(20, $this->config('search.settings')->get('index.cron_limit', 100), 'Config setting was saved correctly'); // Get a new search plugin, to make sure it has this setting. $this->plugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); @@ -143,8 +138,8 @@ function testMultilingualSearch() { $this->assertDatabaseCounts(8, 0, 'after updating fully'); // Click the reindex button on the admin page, verify counts, and reindex. - $this->drupalPostForm('admin/config/search/pages', array(), t('Re-index site')); - $this->drupalPostForm(NULL, array(), t('Re-index site')); + $this->drupalPostForm('admin/config/search/pages', [], t('Re-index site')); + $this->drupalPostForm(NULL, [], t('Re-index site')); $this->assertIndexCounts(8, 8, 'after reindex'); $this->assertDatabaseCounts(8, 0, 'after reindex'); $this->plugin->updateIndex(); @@ -153,30 +148,30 @@ function testMultilingualSearch() { // Test search results. // This should find two results for the second and third node. - $this->plugin->setSearch('English OR Hungarian', array(), array()); + $this->plugin->setSearch('English OR Hungarian', [], []); $search_result = $this->plugin->execute(); $this->assertEqual(count($search_result), 2, 'Found two results.'); // Nodes are saved directly after each other and have the same created time // so testing for the order is not possible. - $results = array($search_result[0]['title'], $search_result[1]['title']); + $results = [$search_result[0]['title'], $search_result[1]['title']]; $this->assertTrue(in_array('Third node this is the Hungarian title', $results), 'The search finds the correct Hungarian title.'); $this->assertTrue(in_array('Second node this is the English title', $results), 'The search finds the correct English title.'); // Now filter for Hungarian results only. - $this->plugin->setSearch('English OR Hungarian', array('f' => array('language:hu')), array()); + $this->plugin->setSearch('English OR Hungarian', ['f' => ['language:hu']], []); $search_result = $this->plugin->execute(); $this->assertEqual(count($search_result), 1, 'The search found only one result'); $this->assertEqual($search_result[0]['title'], 'Third node this is the Hungarian title', 'The search finds the correct Hungarian title.'); // Test for search with common key word across multiple languages. - $this->plugin->setSearch('node', array(), array()); + $this->plugin->setSearch('node', [], []); $search_result = $this->plugin->execute(); $this->assertEqual(count($search_result), 6, 'The search found total six results'); // Test with language filters and common key word. - $this->plugin->setSearch('node', array('f' => array('language:hu')), array()); + $this->plugin->setSearch('node', ['f' => ['language:hu']], []); $search_result = $this->plugin->execute(); $this->assertEqual(count($search_result), 2, 'The search found 2 results'); @@ -207,14 +202,14 @@ function testMultilingualSearch() { $current = REQUEST_TIME; $old = $current - 10; db_update('search_dataset') - ->fields(array('reindex' => $old)) + ->fields(['reindex' => $old]) ->condition('reindex', $current, '>=') ->execute(); // Save the node again. Verify that the request time on it is not updated. $this->searchableNodes[1]->save(); $result = db_select('search_dataset', 'd') - ->fields('d', array('reindex')) + ->fields('d', ['reindex']) ->condition('type', 'node_search') ->condition('sid', $this->searchableNodes[1]->id()) ->execute() @@ -302,7 +297,7 @@ protected function assertIndexCounts($remaining, $total, $message) { protected function assertDatabaseCounts($count_node, $count_foo, $message) { // Count number of distinct nodes by ID. $results = db_select('search_dataset', 'i') - ->fields('i', array('sid')) + ->fields('i', ['sid']) ->condition('type', 'node_search') ->groupBy('sid') ->execute() @@ -311,7 +306,7 @@ protected function assertDatabaseCounts($count_node, $count_foo, $message) { // Count number of "foo" records. $results = db_select('search_dataset', 'i') - ->fields('i', array('sid')) + ->fields('i', ['sid']) ->condition('type', 'foo') ->execute() ->fetchCol(); diff --git a/core/modules/search/src/Tests/SearchNodeDiacriticsTest.php b/core/modules/search/tests/src/Functional/SearchNodeDiacriticsTest.php similarity index 75% rename from core/modules/search/src/Tests/SearchNodeDiacriticsTest.php rename to core/modules/search/tests/src/Functional/SearchNodeDiacriticsTest.php index a8b45a57..848e3576 100644 --- a/core/modules/search/src/Tests/SearchNodeDiacriticsTest.php +++ b/core/modules/search/tests/src/Functional/SearchNodeDiacriticsTest.php @@ -1,6 +1,6 @@ testUser = $this->drupalCreateUser(array('access content', 'search content', 'use advanced search', 'access user profiles')); + $this->testUser = $this->drupalCreateUser(['access content', 'search content', 'use advanced search', 'access user profiles']); $this->drupalLogin($this->testUser); } /** * Tests that search returns results with diacritics in the search phrase. */ - function testPhraseSearchPunctuation() { + public function testPhraseSearchPunctuation() { $body_text = 'The Enricþment Center is cómmīŦŧęđ to the well BɆĬŇĜ of æll påŔťıçȉpǎǹţș. '; $body_text .= 'Also meklÄ“t (see #731298)'; - $this->drupalCreateNode(array('body' => array(array('value' => $body_text)))); + $this->drupalCreateNode(['body' => [['value' => $body_text]]]); // Update the search index. $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); @@ -40,39 +40,39 @@ function testPhraseSearchPunctuation() { // Refresh variables after the treatment. $this->refreshVariables(); - $edit = array('keys' => 'meklet'); + $edit = ['keys' => 'meklet']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertRaw('meklÄ“t'); - $edit = array('keys' => 'meklÄ“t'); + $edit = ['keys' => 'meklÄ“t']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertRaw('meklÄ“t'); - $edit = array('keys' => 'cómmīŦŧęđ BɆĬŇĜ påŔťıçȉpǎǹţș'); + $edit = ['keys' => 'cómmīŦŧęđ BɆĬŇĜ påŔťıçȉpǎǹţș']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertRaw('cómmīŦŧęđ'); $this->assertRaw('BɆĬŇĜ'); $this->assertRaw('påŔťıçȉpǎǹţș'); - $edit = array('keys' => 'committed being participants'); + $edit = ['keys' => 'committed being participants']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertRaw('cómmīŦŧęđ'); $this->assertRaw('BɆĬŇĜ'); $this->assertRaw('påŔťıçȉpǎǹţș'); - $edit = array('keys' => 'Enricþment'); + $edit = ['keys' => 'Enricþment']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertRaw('Enricþment'); - $edit = array('keys' => 'Enritchment'); + $edit = ['keys' => 'Enritchment']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertNoRaw('Enricþment'); - $edit = array('keys' => 'æll'); + $edit = ['keys' => 'æll']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertRaw('æll'); - $edit = array('keys' => 'all'); + $edit = ['keys' => 'all']; $this->drupalPostForm('search/node', $edit, t('Search')); $this->assertNoRaw('æll'); } diff --git a/core/modules/search/tests/src/Functional/SearchNodePunctuationTest.php b/core/modules/search/tests/src/Functional/SearchNodePunctuationTest.php new file mode 100644 index 00000000..59354460 --- /dev/null +++ b/core/modules/search/tests/src/Functional/SearchNodePunctuationTest.php @@ -0,0 +1,63 @@ +testUser = $this->drupalCreateUser(['access content', 'search content', 'use advanced search', 'access user profiles']); + $this->drupalLogin($this->testUser); + } + + /** + * Tests that search works with punctuation and HTML entities. + */ + public function testPhraseSearchPunctuation() { + $node = $this->drupalCreateNode(['body' => [['value' => "The bunny's ears were fluffy."]]]); + $node2 = $this->drupalCreateNode(['body' => [['value' => 'Dignissim Aliquam & Quieligo meus natu quae quia te. Damnum© erat— neo pneum. Facilisi feugiat ibidem ratis.']]]); + + // Update the search index. + $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); + search_update_totals(); + + // Refresh variables after the treatment. + $this->refreshVariables(); + + // Submit a phrase wrapped in double quotes to include the punctuation. + $edit = ['keys' => '"bunny\'s"']; + $this->drupalPostForm('search/node', $edit, t('Search')); + $this->assertText($node->label()); + + // Check if the author is linked correctly to the user profile page. + $username = $node->getOwner()->getUsername(); + $this->assertLink($username); + + // Search for "&" and verify entities are not broken up in the output. + $edit = ['keys' => '&']; + $this->drupalPostForm('search/node', $edit, t('Search')); + $this->assertNoRaw('&amp;'); + $this->assertText('You must include at least one keyword'); + + $edit = ['keys' => '&']; + $this->drupalPostForm('search/node', $edit, t('Search')); + $this->assertNoRaw('&amp;'); + $this->assertText('You must include at least one keyword'); + } + +} diff --git a/core/modules/search/tests/src/Functional/SearchPageOverrideTest.php b/core/modules/search/tests/src/Functional/SearchPageOverrideTest.php new file mode 100644 index 00000000..4dfca49d --- /dev/null +++ b/core/modules/search/tests/src/Functional/SearchPageOverrideTest.php @@ -0,0 +1,44 @@ +searchUser = $this->drupalCreateUser(['search content', 'administer search']); + $this->drupalLogin($this->searchUser); + } + + public function testSearchPageHook() { + $keys = 'bike shed ' . $this->randomMachineName(); + $this->drupalGet("search/dummy_path", ['query' => ['keys' => $keys]]); + $this->assertText('Dummy search snippet', 'Dummy search snippet is shown'); + $this->assertText('Test page text is here', 'Page override is working'); + } + +} diff --git a/core/modules/search/src/Tests/SearchSetLocaleTest.php b/core/modules/search/tests/src/Functional/SearchSetLocaleTest.php similarity index 83% rename from core/modules/search/src/Tests/SearchSetLocaleTest.php rename to core/modules/search/tests/src/Functional/SearchSetLocaleTest.php index 0ec41378..f6923f43 100644 --- a/core/modules/search/src/Tests/SearchSetLocaleTest.php +++ b/core/modules/search/tests/src/Functional/SearchSetLocaleTest.php @@ -1,6 +1,6 @@ nodeSearchPlugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); // Create a node with a very simple body. - $this->drupalCreateNode(array('body' => array(array('value' => 'tapir')))); + $this->drupalCreateNode(['body' => [['value' => 'tapir']]]); // Update the search index. $this->nodeSearchPlugin->updateIndex(); search_update_totals(); @@ -41,7 +41,7 @@ protected function setUp() { public function testSearchWithNumericLocale() { // French decimal point is comma. setlocale(LC_NUMERIC, 'fr_FR'); - $this->nodeSearchPlugin->setSearch('tapir', array(), array()); + $this->nodeSearchPlugin->setSearch('tapir', [], []); // The call to execute will throw an exception if a float in the wrong // format is passed in the query to the database, so an assertion is not // necessary here. diff --git a/core/modules/search/src/Tests/SearchSimplifyTest.php b/core/modules/search/tests/src/Functional/SearchSimplifyTest.php similarity index 82% rename from core/modules/search/src/Tests/SearchSimplifyTest.php rename to core/modules/search/tests/src/Functional/SearchSimplifyTest.php index bdb96c93..c3061199 100644 --- a/core/modules/search/src/Tests/SearchSimplifyTest.php +++ b/core/modules/search/tests/src/Functional/SearchSimplifyTest.php @@ -1,6 +1,7 @@ $string) { if ($key % 2) { // Even line - should simplify down to a space. @@ -64,13 +65,13 @@ function testSearchSimplifyUnicode() { /** * Tests that search_simplify() does the right thing with punctuation. */ - function testSearchSimplifyPunctuation() { - $cases = array( - array('20.03/94-28,876', '20039428876', 'Punctuation removed from numbers'), - array('great...drupal--module', 'great drupal module', 'Multiple dot and dashes are word boundaries'), - array('very_great-drupal.module', 'verygreatdrupalmodule', 'Single dot, dash, underscore are removed'), - array('regular,punctuation;word', 'regular punctuation word', 'Punctuation is a word boundary'), - ); + public function testSearchSimplifyPunctuation() { + $cases = [ + ['20.03/94-28,876', '20039428876', 'Punctuation removed from numbers'], + ['great...drupal--module', 'great drupal module', 'Multiple dot and dashes are word boundaries'], + ['very_great-drupal.module', 'verygreatdrupalmodule', 'Single dot, dash, underscore are removed'], + ['regular,punctuation;word', 'regular punctuation word', 'Punctuation is a word boundary'], + ]; foreach ($cases as $case) { $out = trim(search_simplify($case[0])); diff --git a/core/modules/search/tests/src/Functional/SearchTestBase.php b/core/modules/search/tests/src/Functional/SearchTestBase.php new file mode 100644 index 00000000..3739b570 --- /dev/null +++ b/core/modules/search/tests/src/Functional/SearchTestBase.php @@ -0,0 +1,92 @@ +profile != 'standard') { + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + } + } + + /** + * Simulates submission of a form using GET instead of POST. + * + * Forms that use the GET method cannot be submitted with + * WebTestBase::drupalPostForm(), which explicitly uses POST to submit the + * form. So this method finds the form, verifies that it has input fields and + * a submit button matching the inputs to this method, and then calls + * WebTestBase::drupalGet() to simulate the form submission to the 'action' + * URL of the form (if set, or the current URL if not). + * + * See WebTestBase::drupalPostForm() for more detailed documentation of the + * function parameters. + * + * @param string $path + * Location of the form to be submitted: either a Drupal path, absolute + * path, or NULL to use the current page. + * @param array $edit + * Form field data to submit. Unlike drupalPostForm(), this does not support + * file uploads. + * @param string $submit + * Value of the submit button to submit clicking. Unlike drupalPostForm(), + * this does not support AJAX. + * @param string $form_html_id + * (optional) HTML ID of the form, to disambiguate. + */ + protected function submitGetForm($path, $edit, $submit, $form_html_id = NULL) { + if (isset($path)) { + $this->drupalGet($path); + } + + if ($this->parse()) { + // Iterate over forms to find one that matches $edit and $submit. + $edit_save = $edit; + $xpath = '//form'; + if (!empty($form_html_id)) { + $xpath .= "[@id='" . $form_html_id . "']"; + } + $forms = $this->xpath($xpath); + foreach ($forms as $form) { + // Try to set the fields of this form as specified in $edit. + $edit = $edit_save; + $post = []; + $upload = []; + $submit_matches = $this->handleForm($post, $edit, $upload, $submit, $form); + if (!$edit && $submit_matches) { + // Everything matched, so "submit" the form. + $action = isset($form['action']) ? $this->getAbsoluteUrl((string) $form['action']) : NULL; + $this->drupalGet($action, ['query' => $post]); + return; + } + } + + // We have not found a form which contained all fields of $edit and + // the submit button. + foreach ($edit as $name => $value) { + $this->fail(SafeMarkup::format('Failed to set field @name to @value', ['@name' => $name, '@value' => $value])); + } + $this->assertTrue($submit_matches, format_string('Found the @submit button', ['@submit' => $submit])); + $this->fail(format_string('Found the requested form fields at @path', ['@path' => $path])); + } + } + +} diff --git a/core/modules/search/src/Tests/SearchTokenizerTest.php b/core/modules/search/tests/src/Functional/SearchTokenizerTest.php similarity index 94% rename from core/modules/search/src/Tests/SearchTokenizerTest.php rename to core/modules/search/tests/src/Functional/SearchTokenizerTest.php index f8b3ccbe..218ec185 100644 --- a/core/modules/search/src/Tests/SearchTokenizerTest.php +++ b/core/modules/search/tests/src/Functional/SearchTokenizerTest.php @@ -1,6 +1,7 @@ config('search.settings') @@ -31,7 +32,7 @@ function testTokenizer() { // the Unicode tables. // Beginnings of the character ranges. - $starts = array( + $starts = [ 'CJK unified' => 0x4e00, 'CJK Ext A' => 0x3400, 'CJK Compat' => 0xf900, @@ -52,10 +53,10 @@ function testTokenizer() { 'Bomofo Ext' => 0x31a0, 'Lisu' => 0xa4d0, 'Yi' => 0xa000, - ); + ]; // Ends of the character ranges. - $ends = array( + $ends = [ 'CJK unified' => 0x9fcf, 'CJK Ext A' => 0x4dbf, 'CJK Compat' => 0xfaff, @@ -76,11 +77,11 @@ function testTokenizer() { 'Bomofo Ext' => 0x31b7, 'Lisu' => 0xa4fd, 'Yi' => 0xa48f, - ); + ]; // Generate characters consisting of starts, midpoints, and ends. - $chars = array(); - $charcodes = array(); + $chars = []; + $charcodes = []; foreach ($starts as $key => $value) { $charcodes[] = $starts[$key]; $chars[] = $this->code2utf($starts[$key]); @@ -106,7 +107,7 @@ function testTokenizer() { * This is just a sanity check - it verifies that strings of letters are * not tokenized. */ - function testNoTokenizer() { + public function testNoTokenizer() { // Set the minimum word size to 1 (to split all CJK characters) and make // sure CJK tokenizing is turned on. $this->config('search.settings') @@ -128,7 +129,7 @@ function testNoTokenizer() { * converts a number to the corresponding unicode character. Adapted from * functions supplied in comments on several functions on php.net. */ - function code2utf($num) { + public function code2utf($num) { if ($num < 128) { return chr($num); } diff --git a/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchPageTest.php b/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchPageTest.php index bcbc40e0..a70114a6 100644 --- a/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchPageTest.php +++ b/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchPageTest.php @@ -35,20 +35,20 @@ public function testSearchPage() { $search_page = SearchPage::load($id); $this->assertIdentical($id, $search_page->id()); $configuration = $search_page->getPlugin()->getConfiguration(); - $this->assertIdentical($configuration['rankings'], array( + $this->assertIdentical($configuration['rankings'], [ 'comments' => 5, 'promote' => 0, 'recent' => 0, 'relevance' => 2, 'sticky' => 8, 'views' => 1, - )); + ]); $this->assertIdentical('node', $search_page->getPath()); // Test that we can re-import using the EntitySearchPage destination. Database::getConnection('default', 'migrate') ->update('variable') - ->fields(array('value' => serialize(4))) + ->fields(['value' => serialize(4)]) ->condition('name', 'node_rank_comments') ->execute(); diff --git a/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchSettingsTest.php b/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchSettingsTest.php index e480fec5..d28bbd82 100644 --- a/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchSettingsTest.php +++ b/core/modules/search/tests/src/Kernel/Migrate/d6/MigrateSearchSettingsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\search\Kernel\Migrate\d6; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** diff --git a/core/modules/search/tests/src/Kernel/Migrate/d7/MigrateSearchPageTest.php b/core/modules/search/tests/src/Kernel/Migrate/d7/MigrateSearchPageTest.php index d7dae3e8..86d3b220 100644 --- a/core/modules/search/tests/src/Kernel/Migrate/d7/MigrateSearchPageTest.php +++ b/core/modules/search/tests/src/Kernel/Migrate/d7/MigrateSearchPageTest.php @@ -18,7 +18,7 @@ class MigrateSearchPageTest extends MigrateDrupal7TestBase { * * {@inheritdoc} */ - public static $modules = array('node', 'search'); + public static $modules = ['node', 'search']; /** * {@inheritdoc} @@ -37,20 +37,20 @@ public function testSearchPage() { $search_page = SearchPage::load($id); $this->assertIdentical($id, $search_page->id()); $configuration = $search_page->getPlugin()->getConfiguration(); - $expected_rankings = array( + $expected_rankings = [ 'comments' => 0, 'promote' => 0, 'relevance' => 2, 'sticky' => 0, 'views' => 0, - ); + ]; $this->assertIdentical($expected_rankings, $configuration['rankings']); $this->assertIdentical('node', $search_page->getPath()); // Test that we can re-import using the EntitySearchPage destination. Database::getConnection('default', 'migrate') ->update('variable') - ->fields(array('value' => serialize(4))) + ->fields(['value' => serialize(4)]) ->condition('name', 'node_rank_comments') ->execute(); diff --git a/core/modules/search/tests/src/Kernel/SearchExcerptTest.php b/core/modules/search/tests/src/Kernel/SearchExcerptTest.php index 85c09174..e10075d0 100644 --- a/core/modules/search/tests/src/Kernel/SearchExcerptTest.php +++ b/core/modules/search/tests/src/Kernel/SearchExcerptTest.php @@ -16,7 +16,7 @@ class SearchExcerptTest extends KernelTestBase { * * @var array */ - public static $modules = array('search', 'search_langcode_test'); + public static $modules = ['search', 'search_langcode_test']; /** * Tests search_excerpt() with several simulated search keywords. @@ -27,7 +27,7 @@ class SearchExcerptTest extends KernelTestBase { * contains either highlighted keywords or the original marked * up string if no keywords matched the string. */ - function testSearchExcerpt() { + public function testSearchExcerpt() { // Make some text with entities and tags. $text = 'The quick brown fox & jumps

    over

    the lazy dog'; $expected = 'The quick brown fox & jumps over the lazy dog'; @@ -74,7 +74,7 @@ function testSearchExcerpt() { * search_simplify(). This test passes keywords that match simplified words * and compares them with strings that contain the original unsimplified word. */ - function testSearchExcerptSimplified() { + public function testSearchExcerptSimplified() { $start_time = microtime(TRUE); $lorem1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae arcu at leo cursus laoreet. Curabitur dui tortor, adipiscing malesuada tempor in, bibendum ac diam. Cras non tellus a libero pellentesque condimentum. What is a Drupalism? Suspendisse ac lacus libero. Ut non est vel nisl faucibus interdum nec sed leo. Pellentesque sem risus, vulputate eu semper eget, auctor in libero.'; diff --git a/core/modules/search/tests/src/Kernel/SearchMatchTest.php b/core/modules/search/tests/src/Kernel/SearchMatchTest.php index 0a17f717..7037646b 100644 --- a/core/modules/search/tests/src/Kernel/SearchMatchTest.php +++ b/core/modules/search/tests/src/Kernel/SearchMatchTest.php @@ -37,7 +37,7 @@ protected function setUp() { /** * Test search indexing. */ - function testMatching() { + public function testMatching() { $this->_setup(); $this->_testQueries(); } @@ -45,7 +45,7 @@ function testMatching() { /** * Set up a small index of items to test against. */ - function _setup() { + public function _setup() { $this->config('search.settings')->set('index.minimum_word_size', 3)->save(); for ($i = 1; $i <= 7; ++$i) { @@ -55,11 +55,11 @@ function _setup() { search_index(static::SEARCH_TYPE_2, $i + 7, LanguageInterface::LANGCODE_NOT_SPECIFIED, $this->getText2($i)); } // No getText builder function for Japanese text; just a simple array. - foreach (array( + foreach ([ 13 => '以呂波耳・ã»ã¸ã¨ã¡ã€‚リヌルヲ。', 14 => 'ドルーパルãŒå¤§å¥½ãよï¼', 15 => 'コーヒーã¨ã‚±ãƒ¼ã‚­', - ) as $i => $jpn) { + ] as $i => $jpn) { search_index(static::SEARCH_TYPE_JPN, $i, LanguageInterface::LANGCODE_NOT_SPECIFIED, $jpn); } search_update_totals(); @@ -77,7 +77,7 @@ function _setup() { * 6 enim am minim veniam es cillum * 7 am minim veniam es cillum dolore eu */ - function getText($n) { + public function getText($n) { $words = explode(' ', "Ipsum dolore sit am. Ut enim am minim veniam. Es cillum dolore eu."); return implode(' ', array_slice($words, $n - 1, $n)); } @@ -92,7 +92,7 @@ function getText($n) { * 11 came over from germany * 12 over from germany swimming */ - function getText2($n) { + public function getText2($n) { $words = explode(' ', "Dear King Philip came over from Germany swimming."); return implode(' ', array_slice($words, $n - 1, $n)); } @@ -100,7 +100,7 @@ function getText2($n) { /** * Run predefine queries looking for indexed terms. */ - function _testQueries() { + public function _testQueries() { // Note: OR queries that include short words in OR groups are only accepted // if the ORed terms are ANDed with at least one long word in the rest of // the query. Examples: @@ -108,106 +108,106 @@ function _testQueries() { // is good, and // dolore OR ut = (dolore) OR (ut) // is bad. This is a design limitation to avoid full table scans. - $queries = array( + $queries = [ // Simple AND queries. - 'ipsum' => array(1), - 'enim' => array(4, 5, 6), - 'xxxxx' => array(), - 'enim minim' => array(5, 6), - 'enim xxxxx' => array(), - 'dolore eu' => array(7), - 'dolore xx' => array(), - 'ut minim' => array(5), - 'xx minim' => array(), - 'enim veniam am minim ut' => array(5), + 'ipsum' => [1], + 'enim' => [4, 5, 6], + 'xxxxx' => [], + 'enim minim' => [5, 6], + 'enim xxxxx' => [], + 'dolore eu' => [7], + 'dolore xx' => [], + 'ut minim' => [5], + 'xx minim' => [], + 'enim veniam am minim ut' => [5], // Simple OR and AND/OR queries. - 'dolore OR ipsum' => array(1, 2, 7), - 'dolore OR xxxxx' => array(2, 7), - 'dolore OR ipsum OR enim' => array(1, 2, 4, 5, 6, 7), - 'ipsum OR dolore sit OR cillum' => array(2, 7), - 'minim dolore OR ipsum' => array(7), - 'dolore OR ipsum veniam' => array(7), - 'minim dolore OR ipsum OR enim' => array(5, 6, 7), - 'dolore xx OR yy' => array(), - 'xxxxx dolore OR ipsum' => array(), + 'dolore OR ipsum' => [1, 2, 7], + 'dolore OR xxxxx' => [2, 7], + 'dolore OR ipsum OR enim' => [1, 2, 4, 5, 6, 7], + 'ipsum OR dolore sit OR cillum' => [2, 7], + 'minim dolore OR ipsum' => [7], + 'dolore OR ipsum veniam' => [7], + 'minim dolore OR ipsum OR enim' => [5, 6, 7], + 'dolore xx OR yy' => [], + 'xxxxx dolore OR ipsum' => [], // Sequence of OR queries. - 'minim' => array(5, 6, 7), - 'minim OR xxxx' => array(5, 6, 7), - 'minim OR xxxx OR minim' => array(5, 6, 7), - 'minim OR xxxx minim' => array(5, 6, 7), - 'minim OR xxxx minim OR yyyy' => array(5, 6, 7), - 'minim OR xxxx minim OR cillum' => array(6, 7, 5), - 'minim OR xxxx minim OR xxxx' => array(5, 6, 7), + 'minim' => [5, 6, 7], + 'minim OR xxxx' => [5, 6, 7], + 'minim OR xxxx OR minim' => [5, 6, 7], + 'minim OR xxxx minim' => [5, 6, 7], + 'minim OR xxxx minim OR yyyy' => [5, 6, 7], + 'minim OR xxxx minim OR cillum' => [6, 7, 5], + 'minim OR xxxx minim OR xxxx' => [5, 6, 7], // Negative queries. - 'dolore -sit' => array(7), - 'dolore -eu' => array(2), - 'dolore -xxxxx' => array(2, 7), - 'dolore -xx' => array(2, 7), + 'dolore -sit' => [7], + 'dolore -eu' => [2], + 'dolore -xxxxx' => [2, 7], + 'dolore -xx' => [2, 7], // Phrase queries. - '"dolore sit"' => array(2), - '"sit dolore"' => array(), - '"am minim veniam es"' => array(6, 7), - '"minim am veniam es"' => array(), + '"dolore sit"' => [2], + '"sit dolore"' => [], + '"am minim veniam es"' => [6, 7], + '"minim am veniam es"' => [], // Mixed queries. - '"am minim veniam es" OR dolore' => array(2, 6, 7), - '"minim am veniam es" OR "dolore sit"' => array(2), - '"minim am veniam es" OR "sit dolore"' => array(), - '"am minim veniam es" -eu' => array(6), - '"am minim veniam" -"cillum dolore"' => array(5, 6), - '"am minim veniam" -"dolore cillum"' => array(5, 6, 7), - 'xxxxx "minim am veniam es" OR dolore' => array(), - 'xx "minim am veniam es" OR dolore' => array() - ); + '"am minim veniam es" OR dolore' => [2, 6, 7], + '"minim am veniam es" OR "dolore sit"' => [2], + '"minim am veniam es" OR "sit dolore"' => [], + '"am minim veniam es" -eu' => [6], + '"am minim veniam" -"cillum dolore"' => [5, 6], + '"am minim veniam" -"dolore cillum"' => [5, 6, 7], + 'xxxxx "minim am veniam es" OR dolore' => [], + 'xx "minim am veniam es" OR dolore' => [] + ]; foreach ($queries as $query => $results) { $result = db_select('search_index', 'i') ->extend('Drupal\search\SearchQuery') ->searchExpression($query, static::SEARCH_TYPE) ->execute(); - $set = $result ? $result->fetchAll() : array(); + $set = $result ? $result->fetchAll() : []; $this->_testQueryMatching($query, $set, $results); $this->_testQueryScores($query, $set, $results); } // These queries are run against the second index type, SEARCH_TYPE_2. - $queries = array( + $queries = [ // Simple AND queries. - 'ipsum' => array(), - 'enim' => array(), - 'enim minim' => array(), - 'dear' => array(8), - 'germany' => array(11, 12), - ); + 'ipsum' => [], + 'enim' => [], + 'enim minim' => [], + 'dear' => [8], + 'germany' => [11, 12], + ]; foreach ($queries as $query => $results) { $result = db_select('search_index', 'i') ->extend('Drupal\search\SearchQuery') ->searchExpression($query, static::SEARCH_TYPE_2) ->execute(); - $set = $result ? $result->fetchAll() : array(); + $set = $result ? $result->fetchAll() : []; $this->_testQueryMatching($query, $set, $results); $this->_testQueryScores($query, $set, $results); } // These queries are run against the third index type, SEARCH_TYPE_JPN. - $queries = array( + $queries = [ // Simple AND queries. - '呂波耳' => array(13), - '以呂波耳' => array(13), - 'ã»ã¸ã¨ã€€ãƒŒãƒ«ãƒ²' => array(13), - 'ã¨ã¡ãƒª' => array(), - 'ドルーパル' => array(14), - 'パルãŒå¤§' => array(14), - 'コーヒー' => array(15), - 'ヒーキ' => array(), - ); + '呂波耳' => [13], + '以呂波耳' => [13], + 'ã»ã¸ã¨ã€€ãƒŒãƒ«ãƒ²' => [13], + 'ã¨ã¡ãƒª' => [], + 'ドルーパル' => [14], + 'パルãŒå¤§' => [14], + 'コーヒー' => [15], + 'ヒーキ' => [], + ]; foreach ($queries as $query => $results) { $result = db_select('search_index', 'i') ->extend('Drupal\search\SearchQuery') ->searchExpression($query, static::SEARCH_TYPE_JPN) ->execute(); - $set = $result ? $result->fetchAll() : array(); + $set = $result ? $result->fetchAll() : []; $this->_testQueryMatching($query, $set, $results); $this->_testQueryScores($query, $set, $results); } @@ -218,9 +218,9 @@ function _testQueries() { * * Verify if a query produces the correct results. */ - function _testQueryMatching($query, $set, $results) { + public function _testQueryMatching($query, $set, $results) { // Get result IDs. - $found = array(); + $found = []; foreach ($set as $item) { $found[] = $item->sid; } @@ -236,9 +236,9 @@ function _testQueryMatching($query, $set, $results) { * * Verify if a query produces normalized, monotonous scores. */ - function _testQueryScores($query, $set, $results) { + public function _testQueryScores($query, $set, $results) { // Get result scores. - $scores = array(); + $scores = []; foreach ($set as $item) { $scores[] = $item->calculated_score; } diff --git a/core/modules/search/tests/src/Unit/SearchPageRepositoryTest.php b/core/modules/search/tests/src/Unit/SearchPageRepositoryTest.php index d634207b..69dffd87 100644 --- a/core/modules/search/tests/src/Unit/SearchPageRepositoryTest.php +++ b/core/modules/search/tests/src/Unit/SearchPageRepositoryTest.php @@ -75,14 +75,14 @@ public function testGetActiveSearchPages() { ->will($this->returnValue($this->query)); $this->query->expects($this->once()) ->method('execute') - ->will($this->returnValue(array('test' => 'test', 'other_test' => 'other_test'))); + ->will($this->returnValue(['test' => 'test', 'other_test' => 'other_test'])); - $entities = array(); + $entities = []; $entities['test'] = $this->getMock('Drupal\search\SearchPageInterface'); $entities['other_test'] = $this->getMock('Drupal\search\SearchPageInterface'); $this->storage->expects($this->once()) ->method('loadMultiple') - ->with(array('test' => 'test', 'other_test' => 'other_test')) + ->with(['test' => 'test', 'other_test' => 'other_test']) ->will($this->returnValue($entities)); $result = $this->searchPageRepository->getActiveSearchPages(); @@ -103,7 +103,7 @@ public function testIsSearchActive() { ->will($this->returnValue($this->query)); $this->query->expects($this->once()) ->method('execute') - ->will($this->returnValue(array('test' => 'test'))); + ->will($this->returnValue(['test' => 'test'])); $this->assertSame(TRUE, $this->searchPageRepository->isSearchActive()); } @@ -118,9 +118,9 @@ public function testGetIndexableSearchPages() { ->will($this->returnValue($this->query)); $this->query->expects($this->once()) ->method('execute') - ->will($this->returnValue(array('test' => 'test', 'other_test' => 'other_test'))); + ->will($this->returnValue(['test' => 'test', 'other_test' => 'other_test'])); - $entities = array(); + $entities = []; $entities['test'] = $this->getMock('Drupal\search\SearchPageInterface'); $entities['test']->expects($this->once()) ->method('isIndexable') @@ -131,7 +131,7 @@ public function testGetIndexableSearchPages() { ->will($this->returnValue(FALSE)); $this->storage->expects($this->once()) ->method('loadMultiple') - ->with(array('test' => 'test', 'other_test' => 'other_test')) + ->with(['test' => 'test', 'other_test' => 'other_test']) ->will($this->returnValue($entities)); $result = $this->searchPageRepository->getIndexableSearchPages(); @@ -167,7 +167,7 @@ public function testGetDefaultSearchPageWithActiveDefault() { ->will($this->returnValue($this->query)); $this->query->expects($this->once()) ->method('execute') - ->will($this->returnValue(array('test' => 'test', 'other_test' => 'other_test'))); + ->will($this->returnValue(['test' => 'test', 'other_test' => 'other_test'])); $config = $this->getMockBuilder('Drupal\Core\Config\Config') ->disableOriginalConstructor() @@ -194,7 +194,7 @@ public function testGetDefaultSearchPageWithInactiveDefault() { ->will($this->returnValue($this->query)); $this->query->expects($this->once()) ->method('execute') - ->will($this->returnValue(array('test' => 'test'))); + ->will($this->returnValue(['test' => 'test'])); $config = $this->getMockBuilder('Drupal\Core\Config\Config') ->disableOriginalConstructor() @@ -259,10 +259,10 @@ public function testSortSearchPages() { // Declare entities out of their expected order so we can be sure they were // sorted. We cannot mock these because of uasort(), see // https://bugs.php.net/bug.php?id=50688. - $unsorted_entities['test4'] = new TestSearchPage(array('weight' => 0, 'status' => FALSE, 'label' => 'Test4')); - $unsorted_entities['test3'] = new TestSearchPage(array('weight' => 10, 'status' => TRUE, 'label' => 'Test3')); - $unsorted_entities['test2'] = new TestSearchPage(array('weight' => 0, 'status' => TRUE, 'label' => 'Test2')); - $unsorted_entities['test1'] = new TestSearchPage(array('weight' => 0, 'status' => TRUE, 'label' => 'Test1')); + $unsorted_entities['test4'] = new TestSearchPage(['weight' => 0, 'status' => FALSE, 'label' => 'Test4']); + $unsorted_entities['test3'] = new TestSearchPage(['weight' => 10, 'status' => TRUE, 'label' => 'Test3']); + $unsorted_entities['test2'] = new TestSearchPage(['weight' => 0, 'status' => TRUE, 'label' => 'Test2']); + $unsorted_entities['test1'] = new TestSearchPage(['weight' => 0, 'status' => TRUE, 'label' => 'Test1']); $expected = $unsorted_entities; ksort($expected); diff --git a/core/modules/search/tests/src/Unit/SearchPluginCollectionTest.php b/core/modules/search/tests/src/Unit/SearchPluginCollectionTest.php index 19221f26..25ab8735 100644 --- a/core/modules/search/tests/src/Unit/SearchPluginCollectionTest.php +++ b/core/modules/search/tests/src/Unit/SearchPluginCollectionTest.php @@ -37,7 +37,7 @@ class SearchPluginCollectionTest extends UnitTestCase { */ protected function setUp() { $this->pluginManager = $this->getMock('Drupal\Component\Plugin\PluginManagerInterface'); - $this->searchPluginCollection = new SearchPluginCollection($this->pluginManager, 'banana', array('id' => 'banana', 'color' => 'yellow'), 'fruit_stand'); + $this->searchPluginCollection = new SearchPluginCollection($this->pluginManager, 'banana', ['id' => 'banana', 'color' => 'yellow'], 'fruit_stand'); } /** diff --git a/core/modules/serialization/config/install/serialization.settings.yml b/core/modules/serialization/config/install/serialization.settings.yml new file mode 100644 index 00000000..a2758c2d --- /dev/null +++ b/core/modules/serialization/config/install/serialization.settings.yml @@ -0,0 +1,11 @@ +# Before Drupal 8.3, typed data primitive values were normalized as strings, as +# this was usually returned from database storage. A primitive data normalizer +# has been introduced to get the casted value instead. +bc_primitives_as_strings: false +# Before Drupal 8.3, timestamps were always returned as Unix timestamps, which +# are not a universal format for interchange. Now, RFC3339 timestamps are +# returned. New Drupal installations opt out from this by default (hence this +# is set to false), existing installations opt in to it. +# @see serialization_update_8301() +# @see https://www.drupal.org/node/2768651 +bc_timestamp_normalizer_unix: false diff --git a/core/modules/serialization/config/schema/serialization.schema.yml b/core/modules/serialization/config/schema/serialization.schema.yml new file mode 100644 index 00000000..1d44b3dc --- /dev/null +++ b/core/modules/serialization/config/schema/serialization.schema.yml @@ -0,0 +1,10 @@ +serialization.settings: + type: config_object + label: 'Serialization settings' + mapping: + bc_primitives_as_strings: + type: boolean + label: 'Whether to retain pre Drupal 8.3 behavior of serializing all primitive items as strings.' + bc_timestamp_normalizer_unix: + type: boolean + label: 'Whether the pre Drupal 8.4 behavior of returning Unix timestamps instead of RFC3339 timestamps for TimestampItem fields is enabled or not.' diff --git a/core/modules/serialization/serialization.info.yml b/core/modules/serialization/serialization.info.yml index 57765201..0f7c543c 100644 --- a/core/modules/serialization/serialization.info.yml +++ b/core/modules/serialization/serialization.info.yml @@ -5,8 +5,8 @@ package: Web services # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/serialization/serialization.install b/core/modules/serialization/serialization.install new file mode 100644 index 00000000..afc3311b --- /dev/null +++ b/core/modules/serialization/serialization.install @@ -0,0 +1,57 @@ + t('Serialized data types'), + 'severity' => REQUIREMENT_INFO, + ]; + + if (\Drupal::config('serialization.settings')->get('bc_primitives_as_strings')) { + $requirements['serialization_as_strings']['value'] = t('Enabled'); + $requirements['serialization_as_strings']['description'] = t('The Serialization API is configured to output only string values for REST and other applications (instead of integers or Booleans when appropriate). Disabling this backwards compatibility mode is recommended unless your sites or applications require string output.'); + } + else { + $requirements['serialization_as_strings']['value'] = t('Not enabled'); + $requirements['serialization_as_strings']['description'] = t('The Serialization API is configured with the recommended default and outputs typed values (integers, Booleans, or strings as appropriate) for REST and other applications. If your site or applications require string output, you can enable backwards compatibility mode.'); + } + } + + return $requirements; +} + +/** + * @see hal_update_8301() + */ +function serialization_update_8301() {} + +/** + * Add serialization.settings::bc_primitives_as_strings configuration. + */ +function serialization_update_8302() { + $config_factory = \Drupal::configFactory(); + $config_factory->getEditable('serialization.settings') + ->set('bc_primitives_as_strings', FALSE) + ->save(TRUE); + + return t('The REST API will no longer output all values as strings. Integers/booleans will be used where appropriate. If your site depends on these value being strings, read the change record to learn how to enable the BC mode.'); +} + +/** + * Enable BC for timestamp formatting: continue to return UNIX timestamps. + */ +function serialization_update_8401() { + $config_factory = \Drupal::configFactory(); + $serialization_settings = $config_factory->getEditable('serialization.settings'); + $serialization_settings->set('bc_timestamp_normalizer_unix', TRUE)->save(TRUE); +} diff --git a/core/modules/serialization/serialization.module b/core/modules/serialization/serialization.module index 39c5fbfa..4b2db100 100644 --- a/core/modules/serialization/serialization.module +++ b/core/modules/serialization/serialization.module @@ -18,8 +18,8 @@ function serialization_help($route_name, RouteMatchInterface $route_match) { $output .= '

    ' . t('The Serialization module provides a service for serializing and deserializing data to and from formats such as JSON and XML.') . '

    '; $output .= '

    ' . t('Serialization is the process of converting data structures like arrays and objects into a string. This allows the data to be represented in a way that is easy to exchange and store (for example, for transmission over the Internet or for storage in a local file system). These representations can then be deserialized to get back to the original data structures.') . '

    '; $output .= '

    ' . t('The serializer splits this process into two parts. Normalization converts an object to a normalized array structure. Encoding takes that array and converts it to a string.') . '

    '; - $output .= '

    ' . t('This module does not have a user interface. It is used by other modules which need to serialize data, such as REST.', array(':rest' => (\Drupal::moduleHandler()->moduleExists('rest')) ? \Drupal::url('help.page', array('name' => 'rest')) : '#')) . '

    '; - $output .= '

    ' . t('For more information, see the online documentation for the Serialization module.', array(':doc_url' => 'https://www.drupal.org/documentation/modules/serialization')) . '

    '; + $output .= '

    ' . t('This module does not have a user interface. It is used by other modules which need to serialize data, such as REST.', [':rest' => (\Drupal::moduleHandler()->moduleExists('rest')) ? \Drupal::url('help.page', ['name' => 'rest']) : '#']) . '

    '; + $output .= '

    ' . t('For more information, see the online documentation for the Serialization module.', [':doc_url' => 'https://www.drupal.org/documentation/modules/serialization']) . '

    '; return $output; } } diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml index 8b570c07..dca60947 100644 --- a/core/modules/serialization/serialization.services.yml +++ b/core/modules/serialization/serialization.services.yml @@ -17,6 +17,10 @@ services: tags: - { name: normalizer } arguments: ['@entity.manager'] + serializer.normalizer.primitive_data: + class: Drupal\serialization\Normalizer\PrimitiveDataNormalizer + tags: + - { name: normalizer, priority: 5, bc: bc_primitives_as_strings, bc_config_name: 'serialization.settings' } serializer.normalizer.complex_data: class: Drupal\serialization\Normalizer\ComplexDataNormalizer tags: @@ -25,13 +29,35 @@ services: class: Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer tags: # Set the priority lower than the hal entity reference field item - # normalizer, so that we do not replace that for hal_json. + # normalizer, so that we do not replace that for hal_json but higher than + # this modules generic field item normalizer. # @todo Find a better way for this in https://www.drupal.org/node/2575761. - - { name: normalizer, priority: 5 } + - { name: normalizer, priority: 8 } + arguments: ['@entity.repository'] + serialization.normalizer.field_item: + class: Drupal\serialization\Normalizer\FieldItemNormalizer + tags: + # Priority must be lower than serializer.normalizer.field_item.hal and any + # field type specific normalizer such as + # serializer.normalizer.entity_reference_field_item. + - { name: normalizer, priority: 6 } + serialization.normalizer.field: + class: Drupal\serialization\Normalizer\FieldNormalizer + tags: + # Priority must be lower than serializer.normalizer.field.hal. + - { name: normalizer, priority: 6 } serializer.normalizer.list: class: Drupal\serialization\Normalizer\ListNormalizer tags: - - { name: normalizer } + # Priority must be higher than serialization.normalizer.field but less + # than hal field normalizer. + - { name: normalizer, priority: 9 } + serializer.normalizer.timestamp_item: + class: Drupal\serialization\Normalizer\TimestampItemNormalizer + tags: + # Priority must be higher than serializer.normalizer.field_item and lower + # than hal normalizers. + - { name: normalizer, priority: 8, bc: bc_timestamp_normalizer_unix, bc_config_name: 'serialization.settings' } serializer.normalizer.password_field_item: class: Drupal\serialization\Normalizer\NullNormalizer arguments: ['Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem'] @@ -73,4 +99,9 @@ services: class: Drupal\serialization\EventSubscriber\UserRouteAlterSubscriber tags: - { name: event_subscriber } - arguments: ['@serializer', '%serializer.formats%'] + arguments: ['%serializer.formats%'] + serialization.bc_config_subscriber: + class: Drupal\serialization\EventSubscriber\BcConfigSubscriber + tags: + - { name: event_subscriber } + arguments: ['@kernel'] diff --git a/core/modules/serialization/src/Encoder/JsonEncoder.php b/core/modules/serialization/src/Encoder/JsonEncoder.php index 63e1ddbd..ad085ac0 100644 --- a/core/modules/serialization/src/Encoder/JsonEncoder.php +++ b/core/modules/serialization/src/Encoder/JsonEncoder.php @@ -4,6 +4,8 @@ use Symfony\Component\Serializer\Encoder\DecoderInterface; use Symfony\Component\Serializer\Encoder\EncoderInterface; +use Symfony\Component\Serializer\Encoder\JsonDecode; +use Symfony\Component\Serializer\Encoder\JsonEncode; use Symfony\Component\Serializer\Encoder\JsonEncoder as BaseJsonEncoder; /** @@ -16,7 +18,19 @@ class JsonEncoder extends BaseJsonEncoder implements EncoderInterface, DecoderIn * * @var array */ - protected static $format = array('json', 'ajax'); + protected static $format = ['json', 'ajax']; + + /** + * {@inheritdoc} + */ + public function __construct(JsonEncode $encodingImpl = NULL, JsonDecode $decodingImpl = NULL) { + // Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be + // embedded into HTML. + // @see \Symfony\Component\HttpFoundation\JsonResponse + $json_encoding_options = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT; + $this->encodingImpl = $encodingImpl ?: new JsonEncode($json_encoding_options); + $this->decodingImpl = $decodingImpl ?: new JsonDecode(TRUE); + } /** * {@inheritdoc} diff --git a/core/modules/serialization/src/Encoder/XmlEncoder.php b/core/modules/serialization/src/Encoder/XmlEncoder.php index abd78968..9db6ecde 100644 --- a/core/modules/serialization/src/Encoder/XmlEncoder.php +++ b/core/modules/serialization/src/Encoder/XmlEncoder.php @@ -4,6 +4,7 @@ use Symfony\Component\Serializer\Encoder\EncoderInterface; use Symfony\Component\Serializer\Encoder\DecoderInterface; +use Symfony\Component\Serializer\Encoder\SerializerAwareEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder as BaseXmlEncoder; /** @@ -12,14 +13,14 @@ * This acts as a wrapper class for Symfony's XmlEncoder so that it is not * implementing NormalizationAwareInterface, and can be normalized externally. */ -class XmlEncoder implements EncoderInterface, DecoderInterface { +class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, DecoderInterface { /** * The formats that this Encoder supports. * * @var array */ - static protected $format = array('xml'); + static protected $format = ['xml']; /** * An instance of the Symfony XmlEncoder to perform the actual encoding. @@ -37,6 +38,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface { public function getBaseEncoder() { if (!isset($this->baseEncoder)) { $this->baseEncoder = new BaseXmlEncoder(); + $this->baseEncoder->setSerializer($this->serializer); } return $this->baseEncoder; @@ -54,7 +56,7 @@ public function setBaseEncoder($encoder) { /** * {@inheritdoc} */ - public function encode($data, $format, array $context = array()){ + public function encode($data, $format, array $context = []){ return $this->getBaseEncoder()->encode($data, $format, $context); } @@ -68,7 +70,7 @@ public function supportsEncoding($format) { /** * {@inheritdoc} */ - public function decode($data, $format, array $context = array()){ + public function decode($data, $format, array $context = []){ return $this->getBaseEncoder()->decode($data, $format, $context); } diff --git a/core/modules/serialization/src/EntityResolver/ChainEntityResolver.php b/core/modules/serialization/src/EntityResolver/ChainEntityResolver.php index 6ab87945..7f24901f 100644 --- a/core/modules/serialization/src/EntityResolver/ChainEntityResolver.php +++ b/core/modules/serialization/src/EntityResolver/ChainEntityResolver.php @@ -14,7 +14,7 @@ class ChainEntityResolver implements ChainEntityResolverInterface { * * @var \Drupal\serialization\EntityResolver\EntityResolverInterface[] */ - protected $resolvers = array(); + protected $resolvers = []; /** * Constructs a ChainEntityResolver object. @@ -22,7 +22,7 @@ class ChainEntityResolver implements ChainEntityResolverInterface { * @param \Drupal\serialization\EntityResolver\EntityResolverInterface[] $resolvers * The array of concrete resolvers. */ - public function __construct(array $resolvers = array()) { + public function __construct(array $resolvers = []) { $this->resolvers = $resolvers; } diff --git a/core/modules/serialization/src/EventSubscriber/BcConfigSubscriber.php b/core/modules/serialization/src/EventSubscriber/BcConfigSubscriber.php new file mode 100644 index 00000000..4cb794ff --- /dev/null +++ b/core/modules/serialization/src/EventSubscriber/BcConfigSubscriber.php @@ -0,0 +1,55 @@ +kernel = $kernel; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[ConfigEvents::SAVE][] = 'onConfigSave'; + return $events; + } + + /** + * Invalidates the service container if serialization BC config gets updated. + * + * @param \Drupal\Core\Config\ConfigCrudEvent $event + */ + public function onConfigSave(ConfigCrudEvent $event) { + $saved_config = $event->getConfig(); + + if ($saved_config->getName() === 'serialization.settings') { + if ($event->isChanged('bc_primitives_as_strings') || $event->isChanged('bc_timestamp_normalizer_unix')) { + $this->kernel->invalidateContainer(); + } + } + } + +} diff --git a/core/modules/serialization/src/EventSubscriber/DefaultExceptionSubscriber.php b/core/modules/serialization/src/EventSubscriber/DefaultExceptionSubscriber.php index ba918363..a1e7bad2 100644 --- a/core/modules/serialization/src/EventSubscriber/DefaultExceptionSubscriber.php +++ b/core/modules/serialization/src/EventSubscriber/DefaultExceptionSubscriber.php @@ -56,88 +56,25 @@ protected static function getPriority() { } /** - * Handles a 400 error for HTTP. + * Handles all 4xx errors for all serialization failures. * * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event * The event to process. */ - public function on400(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_BAD_REQUEST); - } + public function on4xx(GetResponseForExceptionEvent $event) { + /** @var \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $exception */ + $exception = $event->getException(); + $request = $event->getRequest(); - /** - * Handles a 403 error for HTTP. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The event to process. - */ - public function on403(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_FORBIDDEN); - } - - /** - * Handles a 404 error for HTTP. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The event to process. - */ - public function on404(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_NOT_FOUND); - } - - /** - * Handles a 405 error for HTTP. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The event to process. - */ - public function on405(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_METHOD_NOT_ALLOWED); - } - - /** - * Handles a 406 error for HTTP. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The event to process. - */ - public function on406(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_NOT_ACCEPTABLE); - } - - /** - * Handles a 422 error for HTTP. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The event to process. - */ - public function on422(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_UNPROCESSABLE_ENTITY); - } - - /** - * Handles a 429 error for HTTP. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The event to process. - */ - public function on429(GetResponseForExceptionEvent $event) { - $this->setEventResponse($event, Response::HTTP_TOO_MANY_REQUESTS); - } - - /** - * Sets the Response for the exception event. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event - * The current exception event. - * @param int $status - * The HTTP status code to set for the response. - */ - protected function setEventResponse(GetResponseForExceptionEvent $event, $status) { - $format = $event->getRequest()->getRequestFormat(); + $format = $request->getRequestFormat(); $content = ['message' => $event->getException()->getMessage()]; $encoded_content = $this->serializer->serialize($content, $format); - $response = new Response($encoded_content, $status); + $headers = $exception->getHeaders(); + + // Add the MIME type from the request to send back in the header. + $headers['Content-Type'] = $request->getMimeType($format); + + $response = new Response($encoded_content, $exception->getStatusCode(), $headers); $event->setResponse($response); } diff --git a/core/modules/serialization/src/EventSubscriber/UserRouteAlterSubscriber.php b/core/modules/serialization/src/EventSubscriber/UserRouteAlterSubscriber.php index 013402c5..147b593a 100644 --- a/core/modules/serialization/src/EventSubscriber/UserRouteAlterSubscriber.php +++ b/core/modules/serialization/src/EventSubscriber/UserRouteAlterSubscriber.php @@ -5,20 +5,12 @@ use Drupal\Core\Routing\RouteBuildEvent; use Drupal\Core\Routing\RoutingEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Serializer\SerializerInterface; /** * Alters user authentication routes to support additional serialization formats. */ class UserRouteAlterSubscriber implements EventSubscriberInterface { - /** - * The serializer. - * - * @var \Symfony\Component\Serializer\Serializer - */ - protected $serializer; - /** * The available serialization formats. * @@ -29,13 +21,10 @@ class UserRouteAlterSubscriber implements EventSubscriberInterface { /** * UserRouteAlterSubscriber constructor. * - * @param \Symfony\Component\Serializer\SerializerInterface $serializer - * The serializer service. * @param array $serializer_formats * The available serializer formats. */ - public function __construct(SerializerInterface $serializer, array $serializer_formats) { - $this->serializer = $serializer; + public function __construct(array $serializer_formats) { $this->serializerFormats = $serializer_formats; } @@ -58,6 +47,7 @@ public function onRoutingAlterAddFormats(RouteBuildEvent $event) { 'user.login_status.http', 'user.login.http', 'user.logout.http', + 'user.pass.http', ]; $routes = $event->getRouteCollection(); foreach ($route_names as $route_name) { diff --git a/core/modules/serialization/src/Normalizer/ComplexDataNormalizer.php b/core/modules/serialization/src/Normalizer/ComplexDataNormalizer.php index 5062738e..33beb373 100644 --- a/core/modules/serialization/src/Normalizer/ComplexDataNormalizer.php +++ b/core/modules/serialization/src/Normalizer/ComplexDataNormalizer.php @@ -24,10 +24,11 @@ class ComplexDataNormalizer extends NormalizerBase { /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { - $attributes = array(); - foreach ($object as $name => $field) { - $attributes[$name] = $this->serializer->normalize($field, $format, $context); + public function normalize($object, $format = NULL, array $context = []) { + $attributes = []; + /** @var \Drupal\Core\TypedData\TypedDataInterface $property */ + foreach ($object as $name => $property) { + $attributes[$name] = $this->serializer->normalize($property, $format, $context); } return $attributes; } diff --git a/core/modules/serialization/src/Normalizer/ConfigEntityNormalizer.php b/core/modules/serialization/src/Normalizer/ConfigEntityNormalizer.php index d17005c1..344bcc33 100644 --- a/core/modules/serialization/src/Normalizer/ConfigEntityNormalizer.php +++ b/core/modules/serialization/src/Normalizer/ConfigEntityNormalizer.php @@ -12,12 +12,12 @@ class ConfigEntityNormalizer extends EntityNormalizer { * * @var array */ - protected $supportedInterfaceOrClass = array('Drupal\Core\Config\Entity\ConfigEntityInterface'); + protected $supportedInterfaceOrClass = ['Drupal\Core\Config\Entity\ConfigEntityInterface']; /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { + public function normalize($object, $format = NULL, array $context = []) { return $object->toArray(); } diff --git a/core/modules/serialization/src/Normalizer/ContentEntityNormalizer.php b/core/modules/serialization/src/Normalizer/ContentEntityNormalizer.php index 0fb5300a..d3abef6f 100644 --- a/core/modules/serialization/src/Normalizer/ContentEntityNormalizer.php +++ b/core/modules/serialization/src/Normalizer/ContentEntityNormalizer.php @@ -8,24 +8,22 @@ class ContentEntityNormalizer extends EntityNormalizer { /** - * The interface or class that this Normalizer supports. - * - * @var array + * {@inheritdoc} */ protected $supportedInterfaceOrClass = ['Drupal\Core\Entity\ContentEntityInterface']; /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { - $context += array( + public function normalize($entity, $format = NULL, array $context = []) { + $context += [ 'account' => NULL, - ); + ]; $attributes = []; - foreach ($object as $name => $field) { - if ($field->access('view', $context['account'])) { - $attributes[$name] = $this->serializer->normalize($field, $format, $context); + foreach ($entity as $name => $field_items) { + if ($field_items->access('view', $context['account'])) { + $attributes[$name] = $this->serializer->normalize($field_items, $format, $context); } } diff --git a/core/modules/serialization/src/Normalizer/EntityNormalizer.php b/core/modules/serialization/src/Normalizer/EntityNormalizer.php index b800e812..4103d1dd 100644 --- a/core/modules/serialization/src/Normalizer/EntityNormalizer.php +++ b/core/modules/serialization/src/Normalizer/EntityNormalizer.php @@ -2,8 +2,9 @@ namespace Drupal\serialization\Normalizer; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; -use Symfony\Component\Serializer\Exception\UnexpectedValueException; +use Drupal\Core\Entity\FieldableEntityInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; /** @@ -11,19 +12,14 @@ */ class EntityNormalizer extends ComplexDataNormalizer implements DenormalizerInterface { + use FieldableEntityNormalizerTrait; + /** * The interface or class that this Normalizer supports. * * @var array */ - protected $supportedInterfaceOrClass = array('Drupal\Core\Entity\EntityInterface'); - - /** - * The entity manager. - * - * @var \Drupal\Core\Entity\EntityManagerInterface - */ - protected $entityManager; + protected $supportedInterfaceOrClass = [EntityInterface::class]; /** * Constructs an EntityNormalizer object. @@ -39,49 +35,33 @@ public function __construct(EntityManagerInterface $entity_manager) { * {@inheritdoc} */ public function denormalize($data, $class, $format = NULL, array $context = []) { - // Get the entity type ID while letting context override the $class param. - $entity_type_id = !empty($context['entity_type']) ? $context['entity_type'] : $this->entityManager->getEntityTypeFromClass($class); + $entity_type_id = $this->determineEntityTypeId($class, $context); + $entity_type_definition = $this->getEntityTypeDefinition($entity_type_id); + + // The bundle property will be required to denormalize a bundleable + // fieldable entity. + if ($entity_type_definition->isSubclassOf(FieldableEntityInterface::class)) { + // Extract bundle data to pass into entity creation if the entity type uses + // bundles. + if ($entity_type_definition->hasKey('bundle')) { + // Get an array containing the bundle only. This also remove the bundle + // key from the $data array. + $create_params = $this->extractBundleData($data, $entity_type_definition); + } + else { + $create_params = []; + } - /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type_definition */ - // Get the entity type definition. - $entity_type_definition = $this->entityManager->getDefinition($entity_type_id, FALSE); + // Create the entity from bundle data only, then apply field values after. + $entity = $this->entityManager->getStorage($entity_type_id)->create($create_params); - // Don't try to create an entity without an entity type id. - if (!$entity_type_definition) { - throw new UnexpectedValueException(sprintf('The specified entity type "%s" does not exist. A valid etnity type is required for denormalization', $entity_type_id)); + $this->denormalizeFieldData($data, $entity, $format, $context); } - - // The bundle property will be required to denormalize a bundleable entity. - if ($entity_type_definition->hasKey('bundle')) { - $bundle_key = $entity_type_definition->getKey('bundle'); - // Get the base field definitions for this entity type. - $base_field_definitions = $this->entityManager->getBaseFieldDefinitions($entity_type_id); - - // Get the ID key from the base field definition for the bundle key or - // default to 'value'. - $key_id = isset($base_field_definitions[$bundle_key]) ? $base_field_definitions[$bundle_key]->getFieldStorageDefinition()->getMainPropertyName() : 'value'; - - // Normalize the bundle if it is not explicitly set. - $data[$bundle_key] = isset($data[$bundle_key][0][$key_id]) ? $data[$bundle_key][0][$key_id] : (isset($data[$bundle_key]) ? $data[$bundle_key] : NULL); - - // Get the bundle entity type from the entity type definition. - $bundle_type_id = $entity_type_definition->getBundleEntityType(); - $bundle_types = $bundle_type_id ? $this->entityManager->getStorage($bundle_type_id)->getQuery()->execute() : []; - - // Make sure a bundle has been provided. - if (!is_string($data[$bundle_key])) { - throw new UnexpectedValueException('A string must be provided as a bundle value.'); - } - - // Make sure the submitted bundle is a valid bundle for the entity type. - if ($bundle_types && !in_array($data[$bundle_key], $bundle_types)) { - throw new UnexpectedValueException(sprintf('"%s" is not a valid bundle type for denormalization.', $data[$bundle_key])); - } + else { + // Create the entity from all data. + $entity = $this->entityManager->getStorage($entity_type_id)->create($data); } - // Create the entity from data. - $entity = $this->entityManager->getStorage($entity_type_id)->create($data); - // Pass the names of the fields whose values can be merged. // @todo https://www.drupal.org/node/2456257 remove this. $entity->_restSubmittedFields = array_keys($data); diff --git a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php index 4706bf40..ea2e020b 100644 --- a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php +++ b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php @@ -2,12 +2,15 @@ namespace Drupal\serialization\Normalizer; +use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; /** * Adds the file URI to embedded file entities. */ -class EntityReferenceFieldItemNormalizer extends ComplexDataNormalizer { +class EntityReferenceFieldItemNormalizer extends FieldItemNormalizer { /** * The interface or class that this Normalizer supports. @@ -16,6 +19,23 @@ class EntityReferenceFieldItemNormalizer extends ComplexDataNormalizer { */ protected $supportedInterfaceOrClass = EntityReferenceItem::class; + /** + * The entity repository. + * + * @var \Drupal\Core\Entity\EntityRepositoryInterface + */ + protected $entityRepository; + + /** + * Constructs a EntityReferenceFieldItemNormalizer object. + * + * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository + * The entity repository. + */ + public function __construct(EntityRepositoryInterface $entity_repository) { + $this->entityRepository = $entity_repository; + } + /** * {@inheritdoc} */ @@ -35,8 +55,32 @@ public function normalize($field_item, $format = NULL, array $context = []) { $values['url'] = $url; } } - return $values; } + /** + * {@inheritdoc} + */ + protected function constructValue($data, $context) { + if (isset($data['target_uuid'])) { + /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $field_item */ + $field_item = $context['target_instance']; + if (empty($data['target_uuid'])) { + throw new InvalidArgumentException(sprintf('If provided "target_uuid" cannot be empty for field "%s".', $data['target_type'], $data['target_uuid'], $field_item->getName())); + } + $target_type = $field_item->getFieldDefinition()->getSetting('target_type'); + if (!empty($data['target_type']) && $target_type !== $data['target_type']) { + throw new UnexpectedValueException(sprintf('The field "%s" property "target_type" must be set to "%s" or omitted.', $field_item->getFieldDefinition()->getName(), $target_type)); + } + if ($entity = $this->entityRepository->loadEntityByUuid($target_type, $data['target_uuid'])) { + return ['target_id' => $entity->id()]; + } + else { + // Unable to load entity by uuid. + throw new InvalidArgumentException(sprintf('No "%s" entity found with UUID "%s" for field "%s".', $data['target_type'], $data['target_uuid'], $field_item->getName())); + } + } + return parent::constructValue($data, $context); + } + } diff --git a/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php b/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php new file mode 100644 index 00000000..decca432 --- /dev/null +++ b/core/modules/serialization/src/Normalizer/FieldItemNormalizer.php @@ -0,0 +1,57 @@ +getParent() == NULL) { + throw new InvalidArgumentException('The field item passed in via $context[\'target_instance\'] must have a parent set.'); + } + + /** @var \Drupal\Core\Field\FieldItemInterface $field_item */ + $field_item = $context['target_instance']; + + $field_item->setValue($this->constructValue($data, $context)); + return $field_item; + } + + /** + * Build the field item value using the incoming data. + * + * Most normalizers that extend this class can simply use this method to + * construct the denormalized value without having to override denormalize() + * and reimplementing its validation logic or its call to set the field value. + * + * @param mixed $data + * The incoming data for this field item. + * @param array $context + * The context passed into the Normalizer. + * + * @return mixed + * The value to use in Entity::setValue(). + */ + protected function constructValue($data, $context) { + return $data; + } + +} diff --git a/core/modules/serialization/src/Normalizer/FieldNormalizer.php b/core/modules/serialization/src/Normalizer/FieldNormalizer.php new file mode 100644 index 00000000..a5051cfb --- /dev/null +++ b/core/modules/serialization/src/Normalizer/FieldNormalizer.php @@ -0,0 +1,57 @@ +getParent() == NULL) { + throw new InvalidArgumentException('The field passed in via $context[\'target_instance\'] must have a parent set.'); + } + + /** @var FieldItemListInterface $items */ + $items = $context['target_instance']; + $item_class = $items->getItemDefinition()->getClass(); + + if (!is_array($data)) { + throw new UnexpectedValueException(sprintf('Field values for "%s" must use an array structure', $items->getName())); + } + + foreach ($data as $item_data) { + // Create a new item and pass it as the target for the unserialization of + // $item_data. All items in field should have removed before this method + // was called. + // @see \Drupal\serialization\Normalizer\ContentEntityNormalizer::denormalize(). + $context['target_instance'] = $items->appendItem(); + $this->serializer->denormalize($item_data, $item_class, $format, $context); + } + return $items; + } + +} diff --git a/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php b/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php new file mode 100644 index 00000000..c8211a8d --- /dev/null +++ b/core/modules/serialization/src/Normalizer/FieldableEntityNormalizerTrait.php @@ -0,0 +1,140 @@ +entityManager->getEntityTypeFromClass($class); + } + + /** + * Gets the entity type definition. + * + * @param string $entity_type_id + * The entity type ID to load the definition for. + * + * @return \Drupal\Core\Entity\EntityTypeInterface + * The loaded entity type definition. + * + * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException + */ + protected function getEntityTypeDefinition($entity_type_id) { + /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type_definition */ + // Get the entity type definition. + $entity_type_definition = $this->entityManager->getDefinition($entity_type_id, FALSE); + + // Don't try to create an entity without an entity type id. + if (!$entity_type_definition) { + throw new UnexpectedValueException(sprintf('The specified entity type "%s" does not exist. A valid entity type is required for denormalization', $entity_type_id)); + } + + return $entity_type_definition; + } + + /** + * Denormalizes the bundle property so entity creation can use it. + * + * @param array $data + * The data being denormalized. + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type_definition + * The entity type definition. + * + * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException + * + * @return string + * The valid bundle name. + */ + protected function extractBundleData(array &$data, EntityTypeInterface $entity_type_definition) { + $bundle_key = $entity_type_definition->getKey('bundle'); + // Get the base field definitions for this entity type. + $base_field_definitions = $this->entityManager->getBaseFieldDefinitions($entity_type_definition->id()); + + // Get the ID key from the base field definition for the bundle key or + // default to 'value'. + $key_id = isset($base_field_definitions[$bundle_key]) ? $base_field_definitions[$bundle_key]->getFieldStorageDefinition()->getMainPropertyName() : 'value'; + + // Normalize the bundle if it is not explicitly set. + $bundle_value = isset($data[$bundle_key][0][$key_id]) ? $data[$bundle_key][0][$key_id] : (isset($data[$bundle_key]) ? $data[$bundle_key] : NULL); + // Unset the bundle from the data. + unset($data[$bundle_key]); + + // Get the bundle entity type from the entity type definition. + $bundle_type_id = $entity_type_definition->getBundleEntityType(); + $bundle_types = $bundle_type_id ? $this->entityManager->getStorage($bundle_type_id)->getQuery()->execute() : []; + + // Make sure a bundle has been provided. + if (!is_string($bundle_value)) { + throw new UnexpectedValueException(sprintf('Could not determine entity type bundle: "%s" field is missing.', $bundle_key)); + } + + // Make sure the submitted bundle is a valid bundle for the entity type. + if ($bundle_types && !in_array($bundle_value, $bundle_types)) { + throw new UnexpectedValueException(sprintf('"%s" is not a valid bundle type for denormalization.', $bundle_value)); + } + + return [$bundle_key => $bundle_value]; + } + + /** + * Denormalizes entity data by denormalizing each field individually. + * + * @param array $data + * The data to denormalize. + * @param \Drupal\Core\Entity\FieldableEntityInterface $entity + * The fieldable entity to set field values for. + * @param string $format + * The serialization format. + * @param array $context + * The context data. + */ + protected function denormalizeFieldData(array $data, FieldableEntityInterface $entity, $format, array $context) { + foreach ($data as $field_name => $field_data) { + $field_item_list = $entity->get($field_name); + + // Remove any values that were set as a part of entity creation (e.g + // uuid). If the incoming field data is set to an empty array, this will + // also have the effect of emptying the field in REST module. + $field_item_list->setValue([]); + $field_item_list_class = get_class($field_item_list); + + if ($field_data) { + // The field instance must be passed in the context so that the field + // denormalizer can update field values for the parent entity. + $context['target_instance'] = $field_item_list; + $this->serializer->denormalize($field_data, $field_item_list_class, $format, $context); + } + } + } + +} diff --git a/core/modules/serialization/src/Normalizer/ListNormalizer.php b/core/modules/serialization/src/Normalizer/ListNormalizer.php index 1729cfce..471886e8 100644 --- a/core/modules/serialization/src/Normalizer/ListNormalizer.php +++ b/core/modules/serialization/src/Normalizer/ListNormalizer.php @@ -23,8 +23,8 @@ class ListNormalizer extends NormalizerBase { /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { - $attributes = array(); + public function normalize($object, $format = NULL, array $context = []) { + $attributes = []; foreach ($object as $fieldItem) { $attributes[] = $this->serializer->normalize($fieldItem, $format, $context); } diff --git a/core/modules/serialization/src/Normalizer/MarkupNormalizer.php b/core/modules/serialization/src/Normalizer/MarkupNormalizer.php index 9cb3cd9c..f4c197b6 100644 --- a/core/modules/serialization/src/Normalizer/MarkupNormalizer.php +++ b/core/modules/serialization/src/Normalizer/MarkupNormalizer.php @@ -12,12 +12,12 @@ class MarkupNormalizer extends NormalizerBase { * * @var array */ - protected $supportedInterfaceOrClass = array('Drupal\Component\Render\MarkupInterface'); + protected $supportedInterfaceOrClass = ['Drupal\Component\Render\MarkupInterface']; /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { + public function normalize($object, $format = NULL, array $context = []) { return (string) $object; } diff --git a/core/modules/serialization/src/Normalizer/NormalizerBase.php b/core/modules/serialization/src/Normalizer/NormalizerBase.php index 90d9b752..5e829f65 100644 --- a/core/modules/serialization/src/Normalizer/NormalizerBase.php +++ b/core/modules/serialization/src/Normalizer/NormalizerBase.php @@ -17,6 +17,13 @@ abstract class NormalizerBase extends SerializerAwareNormalizer implements Norma */ protected $supportedInterfaceOrClass; + /** + * List of formats which supports (de-)normalization. + * + * @var string|string[] + */ + protected $format; + /** * {@inheritdoc} */ @@ -29,7 +36,7 @@ public function supportsNormalization($data, $format = NULL) { $supported = (array) $this->supportedInterfaceOrClass; - return (bool) array_filter($supported, function($name) use ($data) { + return (bool) array_filter($supported, function ($name) use ($data) { return $data instanceof $name; }); } @@ -49,7 +56,7 @@ public function supportsDenormalization($data, $type, $format = NULL) { $supported = (array) $this->supportedInterfaceOrClass; - $subclass_check = function($name) use ($type) { + $subclass_check = function ($name) use ($type) { return (class_exists($name) || interface_exists($name)) && is_subclass_of($type, $name, TRUE); }; @@ -71,7 +78,7 @@ protected function checkFormat($format = NULL) { return TRUE; } - return in_array($format, (array) $this->format); + return in_array($format, (array) $this->format, TRUE); } } diff --git a/core/modules/serialization/src/Normalizer/NullNormalizer.php b/core/modules/serialization/src/Normalizer/NullNormalizer.php index c6a8de5f..dbc61f78 100644 --- a/core/modules/serialization/src/Normalizer/NullNormalizer.php +++ b/core/modules/serialization/src/Normalizer/NullNormalizer.php @@ -20,7 +20,7 @@ public function __construct($supported_interface_of_class) { /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { + public function normalize($object, $format = NULL, array $context = []) { return NULL; } diff --git a/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php b/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php new file mode 100644 index 00000000..cce108ca --- /dev/null +++ b/core/modules/serialization/src/Normalizer/PrimitiveDataNormalizer.php @@ -0,0 +1,32 @@ +getValue() === NULL ? NULL : $object->getCastedValue(); + } + +} diff --git a/core/modules/serialization/src/Normalizer/TimeStampItemNormalizerTrait.php b/core/modules/serialization/src/Normalizer/TimeStampItemNormalizerTrait.php new file mode 100644 index 00000000..78f6030e --- /dev/null +++ b/core/modules/serialization/src/Normalizer/TimeStampItemNormalizerTrait.php @@ -0,0 +1,87 @@ + 'U', + 'ISO 8601' => \DateTime::ISO8601, + 'RFC 3339' => \DateTime::RFC3339, + ]; + + /** + * Processes normalized timestamp values to add a formatted date and format. + * + * @param array $normalized + * The normalized field data to process. + * @return array + * The processed data. + */ + protected function processNormalizedValues(array $normalized) { + // Use a RFC 3339 timestamp with the time zone set to UTC to replace the + // timestamp value. + $date = new \DateTime(); + $date->setTimestamp($normalized['value']); + $date->setTimezone(new \DateTimeZone('UTC')); + $normalized['value'] = $date->format(\DateTime::RFC3339); + // 'format' is not a property on TimestampItem fields. This is present to + // assist consumers of this data. + $normalized['format'] = \DateTime::RFC3339; + + return $normalized; + } + + /** + * {@inheritdoc} + */ + protected function constructValue($data, $context) { + // Loop through the allowed formats and create a TimestampItem from the + // input data if it matches the defined pattern. Since the formats are + // unambiguous (i.e., they reference an absolute time with a defined time + // zone), only one will ever match. + $timezone = new \DateTimeZone('UTC'); + + // First check for a provided format. + if (!empty($data['format']) && in_array($data['format'], $this->allowedFormats)) { + $date = \DateTime::createFromFormat($data['format'], $data['value'], $timezone); + return ['value' => $date->getTimestamp()]; + } + // Otherwise, loop through formats. + else { + foreach ($this->allowedFormats as $format) { + if (($date = \DateTime::createFromFormat($format, $data['value'], $timezone)) !== FALSE) { + return ['value' => $date->getTimestamp()]; + } + } + } + + $format_strings = []; + + foreach ($this->allowedFormats as $label => $format) { + $format_strings[] = "\"$format\" ($label)"; + } + + $formats = implode(', ', $format_strings); + throw new UnexpectedValueException(sprintf('The specified date "%s" is not in an accepted format: %s.', $data['value'], $formats)); + } + +} diff --git a/core/modules/serialization/src/Normalizer/TimestampItemNormalizer.php b/core/modules/serialization/src/Normalizer/TimestampItemNormalizer.php new file mode 100644 index 00000000..704b22f7 --- /dev/null +++ b/core/modules/serialization/src/Normalizer/TimestampItemNormalizer.php @@ -0,0 +1,42 @@ +processNormalizedValues($data); + } + + /** + * {@inheritdoc} + */ + public function denormalize($data, $class, $format = NULL, array $context = []) { + if (empty($data['value'])) { + throw new InvalidArgumentException('No "value" attribute present'); + } + + return parent::denormalize($data, $class, $format, $context); + } + +} diff --git a/core/modules/serialization/src/Normalizer/TypedDataNormalizer.php b/core/modules/serialization/src/Normalizer/TypedDataNormalizer.php index 53a62df4..60ce7d08 100644 --- a/core/modules/serialization/src/Normalizer/TypedDataNormalizer.php +++ b/core/modules/serialization/src/Normalizer/TypedDataNormalizer.php @@ -17,7 +17,7 @@ class TypedDataNormalizer extends NormalizerBase { /** * {@inheritdoc} */ - public function normalize($object, $format = NULL, array $context = array()) { + public function normalize($object, $format = NULL, array $context = []) { return $object->getValue(); } diff --git a/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php b/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php index 90a2c26a..47c2be03 100644 --- a/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php +++ b/core/modules/serialization/src/RegisterEntityResolversCompilerPass.php @@ -19,7 +19,7 @@ class RegisterEntityResolversCompilerPass implements CompilerPassInterface { */ public function process(ContainerBuilder $container) { $definition = $container->getDefinition('serializer.entity_resolver'); - $resolvers = array(); + $resolvers = []; // Retrieve registered Normalizers and Encoders from the container. foreach ($container->findTaggedServiceIds('entity_resolver') as $id => $attributes) { @@ -29,7 +29,7 @@ public function process(ContainerBuilder $container) { // Add the registered concrete EntityResolvers to the ChainEntityResolver. foreach ($this->sort($resolvers) as $resolver) { - $definition->addMethodCall('addResolver', array($resolver)); + $definition->addMethodCall('addResolver', [$resolver]); } } @@ -48,7 +48,7 @@ public function process(ContainerBuilder $container) { * to low priority. */ protected function sort($services) { - $sorted = array(); + $sorted = []; krsort($services); // Flatten the array. diff --git a/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php b/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php index f4611f3f..10474d17 100644 --- a/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php +++ b/core/modules/serialization/src/RegisterSerializationClassesCompilerPass.php @@ -2,6 +2,7 @@ namespace Drupal\serialization; +use Drupal\Core\Config\BootstrapConfigStorageFactory; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -22,6 +23,12 @@ public function process(ContainerBuilder $container) { // Retrieve registered Normalizers and Encoders from the container. foreach ($container->findTaggedServiceIds('normalizer') as $id => $attributes) { + // If there is a BC key present, pass this to determine if the normalizer + // should be skipped. + if (isset($attributes[0]['bc']) && $this->normalizerBcSettingIsEnabled($attributes[0]['bc'], $attributes[0]['bc_config_name'])) { + continue; + } + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; $normalizers[$priority][] = new Reference($id); } @@ -39,7 +46,7 @@ public function process(ContainerBuilder $container) { } // Find all serialization formats known. - $formats = array(); + $formats = []; $format_providers = []; foreach ($container->findTaggedServiceIds('encoder') as $service_id => $attributes) { $format = $attributes[0]['format']; @@ -53,6 +60,18 @@ public function process(ContainerBuilder $container) { $container->setParameter('serializer.format_providers', $format_providers); } + /** + * Returns whether a normalizer BC setting is disabled or not. + * + * @param string $key + * + * @return bool + */ + protected function normalizerBcSettingIsEnabled($key, $config_name) { + $settings = BootstrapConfigStorageFactory::get()->read($config_name); + return !empty($settings[$key]); + } + /** * Sorts by priority. * @@ -68,7 +87,7 @@ public function process(ContainerBuilder $container) { * to low priority. */ protected function sort($services) { - $sorted = array(); + $sorted = []; krsort($services); // Flatten the array. diff --git a/core/modules/serialization/src/Tests/NormalizerTestBase.php b/core/modules/serialization/src/Tests/NormalizerTestBase.php index 1dec036b..0adbae76 100644 --- a/core/modules/serialization/src/Tests/NormalizerTestBase.php +++ b/core/modules/serialization/src/Tests/NormalizerTestBase.php @@ -10,4 +10,4 @@ * @deprecated Scheduled for removal in Drupal 9.0.0. * Use \Drupal\Tests\serialization\Kernel\NormalizerTestBase instead. */ -abstract class NormalizerTestBase extends SerializationNormalizerTestBase { } +abstract class NormalizerTestBase extends SerializationNormalizerTestBase {} diff --git a/core/modules/serialization/tests/modules/entity_serialization_test/entity_serialization_test.info.yml b/core/modules/serialization/tests/modules/entity_serialization_test/entity_serialization_test.info.yml index 1eb728e0..429ef56b 100644 --- a/core/modules/serialization/tests/modules/entity_serialization_test/entity_serialization_test.info.yml +++ b/core/modules/serialization/tests/modules/entity_serialization_test/entity_serialization_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/serialization/tests/modules/field_normalization_test/field_normalization_test.info.yml b/core/modules/serialization/tests/modules/field_normalization_test/field_normalization_test.info.yml new file mode 100644 index 00000000..b096a521 --- /dev/null +++ b/core/modules/serialization/tests/modules/field_normalization_test/field_normalization_test.info.yml @@ -0,0 +1,12 @@ +name: 'FieldItem normalization test support' +type: module +description: 'Provides test support for fieldItem normalization test support.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/serialization/tests/modules/field_normalization_test/field_normalization_test.services.yml b/core/modules/serialization/tests/modules/field_normalization_test/field_normalization_test.services.yml new file mode 100644 index 00000000..36243e79 --- /dev/null +++ b/core/modules/serialization/tests/modules/field_normalization_test/field_normalization_test.services.yml @@ -0,0 +1,6 @@ +services: + serializer.normalizer.silly_fielditem: + class: Drupal\field_normalization_test\Normalization\TextItemSillyNormalizer + tags: + # The priority must be higher than serialization.normalizer.field_item. + - { name: normalizer , priority: 9 } diff --git a/core/modules/serialization/tests/modules/field_normalization_test/src/Normalization/TextItemSillyNormalizer.php b/core/modules/serialization/tests/modules/field_normalization_test/src/Normalization/TextItemSillyNormalizer.php new file mode 100644 index 00000000..45438f40 --- /dev/null +++ b/core/modules/serialization/tests/modules/field_normalization_test/src/Normalization/TextItemSillyNormalizer.php @@ -0,0 +1,36 @@ +rebuild(); // Create the test field storage. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'entity_type' => 'entity_test_mulrev', 'field_name' => 'field_test_entity_reference', 'type' => 'entity_reference', - 'settings' => array( + 'settings' => [ 'target_type' => 'entity_test_mulrev', - ), - ))->save(); + ], + ])->save(); // Create the test field. FieldConfig::create([ @@ -54,41 +54,41 @@ protected function setUp() { /** * Test that fields referencing UUIDs can be denormalized. */ - function testUuidEntityResolver() { + public function testUuidEntityResolver() { // Create an entity to get the UUID from. - $entity = EntityTestMulRev::create(array('type' => 'entity_test_mulrev')); + $entity = EntityTestMulRev::create(['type' => 'entity_test_mulrev']); $entity->set('name', 'foobar'); - $entity->set('field_test_entity_reference', array(array('target_id' => 1))); + $entity->set('field_test_entity_reference', [['target_id' => 1]]); $entity->save(); - $field_uri = Url::fromUri('base:rest/relation/entity_test_mulrev/entity_test_mulrev/field_test_entity_reference', array('absolute' => TRUE))->toString(); + $field_uri = Url::fromUri('base:rest/relation/entity_test_mulrev/entity_test_mulrev/field_test_entity_reference', ['absolute' => TRUE])->toString(); - $data = array( - '_links' => array( - 'type' => array( - 'href' => Url::fromUri('base:rest/type/entity_test_mulrev/entity_test_mulrev', array('absolute' => TRUE))->toString(), - ), - $field_uri => array( - array( + $data = [ + '_links' => [ + 'type' => [ + 'href' => Url::fromUri('base:rest/type/entity_test_mulrev/entity_test_mulrev', ['absolute' => TRUE])->toString(), + ], + $field_uri => [ + [ 'href' => $entity->url(), - ), - ), - ), - '_embedded' => array( - $field_uri => array( - array( - '_links' => array( + ], + ], + ], + '_embedded' => [ + $field_uri => [ + [ + '_links' => [ 'self' => $entity->url(), - ), - 'uuid' => array( - array( + ], + 'uuid' => [ + [ 'value' => $entity->uuid(), - ), - ), - ), - ), - ), - ); + ], + ], + ], + ], + ], + ]; $denormalized = $this->container->get('serializer')->denormalize($data, 'Drupal\entity_test\Entity\EntityTestMulRev', $this->format); $field_value = $denormalized->get('field_test_entity_reference')->getValue(); diff --git a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php index 0f84d3d7..5b71b93b 100644 --- a/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php +++ b/core/modules/serialization/tests/src/Kernel/EntitySerializationTest.php @@ -4,6 +4,7 @@ use Drupal\Component\Utility\SafeMarkup; use Drupal\entity_test\Entity\EntityTestMulRev; +use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait; /** * Tests that entities can be serialized to supported core formats. @@ -12,12 +13,14 @@ */ class EntitySerializationTest extends NormalizerTestBase { + use BcTimestampNormalizerUnixTestTrait; + /** * Modules to install. * * @var array */ - public static $modules = array('serialization', 'system', 'field', 'entity_test', 'text', 'filter', 'user', 'entity_serialization_test'); + public static $modules = ['serialization', 'system', 'field', 'entity_test', 'text', 'filter', 'user', 'entity_serialization_test']; /** * The test values. @@ -29,7 +32,7 @@ class EntitySerializationTest extends NormalizerTestBase { /** * The test entity. * - * @var \Drupal\Core\Entity\ContentEntityBase + * @var \Drupal\Core\Entity\ContentEntityInterface */ protected $entity; @@ -58,7 +61,7 @@ protected function setUp() { parent::setUp(); // User create needs sequence table. - $this->installSchema('system', array('sequences')); + $this->installSchema('system', ['sequences']); // Create a test user to use as the entity owner. $this->user = \Drupal::entityManager()->getStorage('user')->create([ @@ -69,74 +72,78 @@ protected function setUp() { $this->user->save(); // Create a test entity to serialize. - $this->values = array( + $this->values = [ 'name' => $this->randomMachineName(), 'user_id' => $this->user->id(), - 'field_test_text' => array( + 'field_test_text' => [ 'value' => $this->randomMachineName(), 'format' => 'full_html', - ), - ); + ], + ]; $this->entity = EntityTestMulRev::create($this->values); $this->entity->save(); $this->serializer = $this->container->get('serializer'); - $this->installConfig(array('field')); + $this->installConfig(['field']); } /** * Test the normalize function. */ public function testNormalize() { - $expected = array( - 'id' => array( - array('value' => 1), - ), - 'uuid' => array( - array('value' => $this->entity->uuid()), - ), - 'langcode' => array( - array('value' => 'en'), - ), - 'name' => array( - array('value' => $this->values['name']), - ), - 'type' => array( - array('value' => 'entity_test_mulrev'), - ), - 'created' => array( - array('value' => $this->entity->created->value), - ), - 'user_id' => array( - array( - 'target_id' => $this->user->id(), + $expected = [ + 'id' => [ + ['value' => 1], + ], + 'uuid' => [ + ['value' => $this->entity->uuid()], + ], + 'langcode' => [ + ['value' => 'en'], + ], + 'name' => [ + ['value' => $this->values['name']], + ], + 'type' => [ + ['value' => 'entity_test_mulrev'], + ], + 'created' => [ + $this->formatExpectedTimestampItemValues($this->entity->created->value), + ], + 'user_id' => [ + [ + // id() will return the string value as it comes from the database. + 'target_id' => (int) $this->user->id(), 'target_type' => $this->user->getEntityTypeId(), 'target_uuid' => $this->user->uuid(), 'url' => $this->user->url(), - ), - ), - 'revision_id' => array( - array('value' => 1), - ), - 'default_langcode' => array( - array('value' => TRUE), - ), - 'non_rev_field' => array(), - 'field_test_text' => array( - array( + ], + ], + 'revision_id' => [ + ['value' => 1], + ], + 'default_langcode' => [ + ['value' => TRUE], + ], + 'revision_translation_affected' => [ + ['value' => TRUE], + ], + 'non_rev_field' => [], + 'field_test_text' => [ + [ 'value' => $this->values['field_test_text']['value'], 'format' => $this->values['field_test_text']['format'], - ), - ), - ); + ], + ], + ]; $normalized = $this->serializer->normalize($this->entity); foreach (array_keys($expected) as $fieldName) { - $this->assertEqual($expected[$fieldName], $normalized[$fieldName], "ComplexDataNormalizer produces expected array for $fieldName."); + $this->assertSame($expected[$fieldName], $normalized[$fieldName], "Normalization produces expected array for $fieldName."); } - $this->assertEqual(array_diff_key($normalized, $expected), array(), 'No unexpected data is added to the normalized array.'); + $this->assertEqual(array_diff_key($normalized, $expected), [], 'No unexpected data is added to the normalized array.'); } /** @@ -181,19 +188,22 @@ public function testSerialize() { // Generate the expected xml in a way that allows changes to entity property // order. - $expected = array( + $expected_created = $this->formatExpectedTimestampItemValues($this->entity->created->value); + + $expected = [ 'id' => '' . $this->entity->id() . '', 'uuid' => '' . $this->entity->uuid() . '', 'langcode' => 'en', 'name' => '' . $this->values['name'] . '', 'type' => 'entity_test_mulrev', - 'created' => '' . $this->entity->created->value . '', + 'created' => '' . $expected_created['value'] . '' . $expected_created['format'] . '', 'user_id' => '' . $this->user->id() . '' . $this->user->getEntityTypeId() . '' . $this->user->uuid() . '' . $this->user->url() . '', 'revision_id' => '' . $this->entity->getRevisionId() . '', 'default_langcode' => '1', + 'revision_translation_affected' => '1', 'non_rev_field' => '', 'field_test_text' => '' . $this->values['field_test_text']['value'] . '' . $this->values['field_test_text']['format'] . '', - ); + ]; // Sort it in the same order as normalised. $expected = array_merge($normalized, $expected); // Add header and footer. @@ -214,9 +224,9 @@ public function testSerialize() { public function testDenormalize() { $normalized = $this->serializer->normalize($this->entity); - foreach (array('json', 'xml') as $type) { - $denormalized = $this->serializer->denormalize($normalized, $this->entityClass, $type, array('entity_type' => 'entity_test_mulrev')); - $this->assertTrue($denormalized instanceof $this->entityClass, SafeMarkup::format('Denormalized entity is an instance of @class', array('@class' => $this->entityClass))); + foreach (['json', 'xml'] as $type) { + $denormalized = $this->serializer->denormalize($normalized, $this->entityClass, $type, ['entity_type' => 'entity_test_mulrev']); + $this->assertTrue($denormalized instanceof $this->entityClass, SafeMarkup::format('Denormalized entity is an instance of @class', ['@class' => $this->entityClass])); $this->assertIdentical($denormalized->getEntityTypeId(), $this->entity->getEntityTypeId(), 'Expected entity type found.'); $this->assertIdentical($denormalized->bundle(), $this->entity->bundle(), 'Expected entity bundle found.'); $this->assertIdentical($denormalized->uuid(), $this->entity->uuid(), 'Expected entity UUID found.'); diff --git a/core/modules/serialization/tests/src/Kernel/FieldItemSerializationTest.php b/core/modules/serialization/tests/src/Kernel/FieldItemSerializationTest.php new file mode 100644 index 00000000..3e41d630 --- /dev/null +++ b/core/modules/serialization/tests/src/Kernel/FieldItemSerializationTest.php @@ -0,0 +1,135 @@ + 'entity_test_mulrev', + 'field_name' => 'field_test_text_default', + 'type' => 'text', + 'cardinality' => 1, + 'translatable' => FALSE, + ])->save(); + FieldConfig::create([ + 'entity_type' => 'entity_test_mulrev', + 'field_name' => 'field_test_text_default', + 'bundle' => 'entity_test_mulrev', + 'label' => 'Test text-field with default', + 'default_value' => [ + [ + 'value' => 'This is the default', + 'format' => 'full_html', + ], + ], + 'widget' => [ + 'type' => 'text_textfield', + 'weight' => 0, + ], + ])->save(); + + // Create a test entity to serialize. + $this->values = [ + 'name' => $this->randomMachineName(), + 'field_test_text' => [ + 'value' => $this->randomMachineName(), + 'format' => 'full_html', + ], + ]; + $this->entity = EntityTestMulRev::create($this->values); + $this->entity->save(); + + $this->serializer = $this->container->get('serializer'); + + $this->installConfig(['field']); + } + + /** + * Tests normalizing and denormalizing an entity with field item normalizer. + */ + public function testFieldNormalizeDenormalize() { + $normalized = $this->serializer->normalize($this->entity, 'json'); + + $expected_field_value = $this->entity->field_test_text[0]->getValue()['value'] . '::silly_suffix'; + $this->assertEquals($expected_field_value, $normalized['field_test_text'][0]['value'], 'Text field item normalized'); + $denormalized = $this->serializer->denormalize($normalized, $this->entityClass, 'json'); + + $this->assertEquals($denormalized->field_test_text[0]->getValue(), $this->entity->field_test_text[0]->getValue(), 'Text field item denormalized.'); + $this->assertEquals($denormalized->field_test_text_default[0]->getValue(), $this->entity->field_test_text_default[0]->getValue(), 'Text field item with default denormalized.'); + + // Unset the values for text field that has a default value. + unset($normalized['field_test_text_default']); + $denormalized_without_all_fields = $this->serializer->denormalize($normalized, $this->entityClass, 'json'); + // Check that denormalized entity is still the same even if not all fields + // are not provided. + $this->assertEquals($denormalized_without_all_fields->field_test_text[0]->getValue(), $this->entity->field_test_text[0]->getValue(), 'Text field item denormalized.'); + // Even though field_test_text_default value was unset before + // denormalization it should still have the default values for the field. + $this->assertEquals($denormalized_without_all_fields->field_test_text_default[0]->getValue(), $this->entity->field_test_text_default[0]->getValue(), 'Text field item with default denormalized.'); + } + + /** + * Tests denormalizing using a scalar field value. + */ + public function testFieldDenormalizeWithScalarValue() { + $this->setExpectedException(UnexpectedValueException::class, 'Field values for "uuid" must use an array structure'); + + $normalized = $this->serializer->normalize($this->entity, 'json'); + + // Change the UUID value to use the UUID directly. No array structure. + $normalized['uuid'] = $normalized['uuid'][0]['value']; + + $this->serializer->denormalize($normalized, $this->entityClass, 'json'); + } + +} diff --git a/core/modules/serialization/tests/src/Kernel/NormalizerTestBase.php b/core/modules/serialization/tests/src/Kernel/NormalizerTestBase.php index 7706b6d1..25299b16 100644 --- a/core/modules/serialization/tests/src/Kernel/NormalizerTestBase.php +++ b/core/modules/serialization/tests/src/Kernel/NormalizerTestBase.php @@ -16,35 +16,35 @@ abstract class NormalizerTestBase extends KernelTestBase { * * @var array */ - public static $modules = array('serialization', 'system', 'field', 'entity_test', 'text', 'filter', 'user'); + public static $modules = ['serialization', 'system', 'field', 'entity_test', 'text', 'filter', 'user']; protected function setUp() { parent::setUp(); $this->installEntitySchema('entity_test_mulrev'); $this->installEntitySchema('user'); - $this->installConfig(array('field')); + $this->installConfig(['field']); \Drupal::service('router.builder')->rebuild(); \Drupal::moduleHandler()->invoke('rest', 'install'); // Auto-create a field for testing. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'entity_type' => 'entity_test_mulrev', 'field_name' => 'field_test_text', 'type' => 'text', 'cardinality' => 1, 'translatable' => FALSE, - ))->save(); - FieldConfig::create(array( + ])->save(); + FieldConfig::create([ 'entity_type' => 'entity_test_mulrev', 'field_name' => 'field_test_text', 'bundle' => 'entity_test_mulrev', 'label' => 'Test text-field', - 'widget' => array( + 'widget' => [ 'type' => 'text_textfield', 'weight' => 0, - ), - ))->save(); + ], + ])->save(); } } diff --git a/core/modules/serialization/tests/src/Kernel/SerializationTest.php b/core/modules/serialization/tests/src/Kernel/SerializationTest.php index 8b700a32..a7ad145e 100644 --- a/core/modules/serialization/tests/src/Kernel/SerializationTest.php +++ b/core/modules/serialization/tests/src/Kernel/SerializationTest.php @@ -17,7 +17,7 @@ class SerializationTest extends KernelTestBase { * * @var array */ - public static $modules = array('serialization', 'serialization_test'); + public static $modules = ['serialization', 'serialization_test']; /** * The serializer service to test. diff --git a/core/modules/serialization/src/Tests/RegisterSerializationClassesCompilerPassTest.php b/core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php similarity index 91% rename from core/modules/serialization/src/Tests/RegisterSerializationClassesCompilerPassTest.php rename to core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php index 6406bbba..f9a5b772 100644 --- a/core/modules/serialization/src/Tests/RegisterSerializationClassesCompilerPassTest.php +++ b/core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php @@ -1,9 +1,10 @@ 'test'); + protected $testArray = ['test' => 'test']; protected function setUp() { - $this->baseEncoder = $this->getMock('Symfony\Component\Serializer\Encoder\XmlEncoder'); + $this->baseEncoder = $this->getMock(BaseXmlEncoder::class); $this->encoder = new XmlEncoder(); $this->encoder->setBaseEncoder($this->baseEncoder); } @@ -58,7 +61,7 @@ public function testSupportsDecoding() { public function testEncode() { $this->baseEncoder->expects($this->once()) ->method('encode') - ->with($this->testArray, 'test', array()) + ->with($this->testArray, 'test', []) ->will($this->returnValue('test')); $this->assertEquals('test', $this->encoder->encode($this->testArray, 'test')); @@ -70,10 +73,32 @@ public function testEncode() { public function testDecode() { $this->baseEncoder->expects($this->once()) ->method('decode') - ->with('test', 'test', array()) + ->with('test', 'test', []) ->will($this->returnValue($this->testArray)); $this->assertEquals($this->testArray, $this->encoder->decode('test', 'test')); } + /** + * @covers ::getBaseEncoder + */ + public function testDefaultEncoderHasSerializer() { + // The serializer should be set on the Drupal encoder, which should then + // set it on our default encoder. + $encoder = new XmlEncoder(); + $serialzer = new Serializer([new GetSetMethodNormalizer()]); + $encoder->setSerializer($serialzer); + $base_encoder = $encoder->getBaseEncoder(); + $this->assertInstanceOf(BaseXmlEncoder::class, $base_encoder); + // Test the encoder. + $base_encoder->encode(['a' => new TestObject()], 'xml'); + } + +} + +class TestObject { + public function getA() { + return 'A'; + } + } diff --git a/core/modules/serialization/tests/src/Unit/EntityResolver/ChainEntityResolverTest.php b/core/modules/serialization/tests/src/Unit/EntityResolver/ChainEntityResolverTest.php index 38819e11..64e73b69 100644 --- a/core/modules/serialization/tests/src/Unit/EntityResolver/ChainEntityResolverTest.php +++ b/core/modules/serialization/tests/src/Unit/EntityResolver/ChainEntityResolverTest.php @@ -47,10 +47,10 @@ protected function setUp() { * @covers ::resolve */ public function testResolverWithNoneResolved() { - $resolvers = array( + $resolvers = [ $this->createEntityResolverMock(), $this->createEntityResolverMock(), - ); + ]; $resolver = new ChainEntityResolver($resolvers); @@ -78,10 +78,10 @@ public function testResolverWithNoneResolvedUsingAddResolver() { * @covers ::resolve */ public function testResolverWithFirstResolved() { - $resolvers = array( + $resolvers = [ $this->createEntityResolverMock(10), $this->createEntityResolverMock(NULL, FALSE), - ); + ]; $resolver = new ChainEntityResolver($resolvers); @@ -95,10 +95,10 @@ public function testResolverWithFirstResolved() { * @covers ::resolve */ public function testResolverWithLastResolved() { - $resolvers = array( + $resolvers = [ $this->createEntityResolverMock(), $this->createEntityResolverMock(10), - ); + ]; $resolver = new ChainEntityResolver($resolvers); @@ -112,10 +112,10 @@ public function testResolverWithLastResolved() { * @covers ::resolve */ public function testResolverWithResolvedToZero() { - $resolvers = array( + $resolvers = [ $this->createEntityResolverMock(0), $this->createEntityResolverMock(NULL, FALSE), - ); + ]; $resolver = new ChainEntityResolver($resolvers); diff --git a/core/modules/serialization/tests/src/Unit/EntityResolver/UuidResolverTest.php b/core/modules/serialization/tests/src/Unit/EntityResolver/UuidResolverTest.php index a05d417a..81239256 100644 --- a/core/modules/serialization/tests/src/Unit/EntityResolver/UuidResolverTest.php +++ b/core/modules/serialization/tests/src/Unit/EntityResolver/UuidResolverTest.php @@ -44,7 +44,7 @@ public function testResolveNotInInterface() { ->method('loadEntityByUuid'); $normalizer = $this->getMock('Symfony\Component\Serializer\Normalizer\NormalizerInterface'); - $this->assertNull($this->resolver->resolve($normalizer, array(), 'test_type')); + $this->assertNull($this->resolver->resolve($normalizer, [], 'test_type')); } /** @@ -57,9 +57,9 @@ public function testResolveNoUuid() { $normalizer = $this->getMock('Drupal\serialization\EntityResolver\UuidReferenceInterface'); $normalizer->expects($this->once()) ->method('getUuid') - ->with(array()) + ->with([]) ->will($this->returnValue(NULL)); - $this->assertNull($this->resolver->resolve($normalizer, array(), 'test_type')); + $this->assertNull($this->resolver->resolve($normalizer, [], 'test_type')); } /** @@ -76,10 +76,10 @@ public function testResolveNoEntity() { $normalizer = $this->getMock('Drupal\serialization\EntityResolver\UuidReferenceInterface'); $normalizer->expects($this->once()) ->method('getUuid') - ->with(array()) + ->with([]) ->will($this->returnValue($uuid)); - $this->assertNull($this->resolver->resolve($normalizer, array(), 'test_type')); + $this->assertNull($this->resolver->resolve($normalizer, [], 'test_type')); } /** @@ -101,9 +101,9 @@ public function testResolveWithEntity() { $normalizer = $this->getMock('Drupal\serialization\EntityResolver\UuidReferenceInterface'); $normalizer->expects($this->once()) ->method('getUuid') - ->with(array()) + ->with([]) ->will($this->returnValue($uuid)); - $this->assertSame(1, $this->resolver->resolve($normalizer, array(), 'test_type')); + $this->assertSame(1, $this->resolver->resolve($normalizer, [], 'test_type')); } } diff --git a/core/modules/serialization/tests/src/Unit/EventSubscriber/DefaultExceptionSubscriberTest.php b/core/modules/serialization/tests/src/Unit/EventSubscriber/DefaultExceptionSubscriberTest.php new file mode 100644 index 00000000..e20f6f7f --- /dev/null +++ b/core/modules/serialization/tests/src/Unit/EventSubscriber/DefaultExceptionSubscriberTest.php @@ -0,0 +1,42 @@ +prophesize(HttpKernelInterface::class); + $request = Request::create('/test'); + $request->setRequestFormat('json'); + + $e = new MethodNotAllowedHttpException(['POST', 'PUT'], 'test message'); + $event = new GetResponseForExceptionEvent($kernel->reveal(), $request, 'GET', $e); + $subscriber = new DefaultExceptionSubscriber(new Serializer([], [new JsonEncoder()]), []); + $subscriber->on4xx($event); + $response = $event->getResponse(); + + $this->assertInstanceOf(Response::class, $response); + $this->assertEquals('{"message":"test message"}', $response->getContent()); + $this->assertEquals(405, $response->getStatusCode()); + $this->assertEquals('POST, PUT', $response->headers->get('Allow')); + $this->assertEquals('application/json', $response->headers->get('Content-Type')); + } + +} diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/ConfigEntityNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/ConfigEntityNormalizerTest.php index ec9a4d07..371450a5 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/ConfigEntityNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/ConfigEntityNormalizerTest.php @@ -17,7 +17,7 @@ class ConfigEntityNormalizerTest extends UnitTestCase { * @covers ::normalize */ public function testNormalize() { - $test_export_properties = array('test' => 'test'); + $test_export_properties = ['test' => 'test']; $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); $normalizer = new ConfigEntityNormalizer($entity_manager); diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/ContentEntityNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/ContentEntityNormalizerTest.php index 9613fdbb..4beecf42 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/ContentEntityNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/ContentEntityNormalizerTest.php @@ -40,7 +40,7 @@ protected function setUp() { $this->contentEntityNormalizer = new ContentEntityNormalizer($this->entityManager); $this->serializer = $this->getMockBuilder('Symfony\Component\Serializer\Serializer') ->disableOriginalConstructor() - ->setMethods(array('normalize')) + ->setMethods(['normalize']) ->getMock(); $this->contentEntityNormalizer->setSerializer($this->serializer); } @@ -66,10 +66,10 @@ public function testNormalize() { ->with($this->containsOnlyInstancesOf('Drupal\Core\Field\FieldItemListInterface'), 'test_format', ['account' => NULL]) ->will($this->returnValue('test')); - $definitions = array( + $definitions = [ 'field_1' => $this->createMockFieldListItem(), 'field_2' => $this->createMockFieldListItem(FALSE), - ); + ]; $content_entity_mock = $this->createMockForContentEntity($definitions); $normalized = $this->contentEntityNormalizer->normalize($content_entity_mock, 'test_format'); @@ -98,10 +98,10 @@ public function testNormalizeWithAccountContext() { // The mock account should get passed directly into the access() method on // field items from $context['account']. - $definitions = array( + $definitions = [ 'field_1' => $this->createMockFieldListItem(TRUE, $mock_account), 'field_2' => $this->createMockFieldListItem(FALSE, $mock_account), - ); + ]; $content_entity_mock = $this->createMockForContentEntity($definitions); $normalized = $this->contentEntityNormalizer->normalize($content_entity_mock, 'test_format', $context); @@ -121,7 +121,7 @@ public function testNormalizeWithAccountContext() { public function createMockForContentEntity($definitions) { $content_entity_mock = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase') ->disableOriginalConstructor() - ->setMethods(array('getFields')) + ->setMethods(['getFields']) ->getMockForAbstractClass(); $content_entity_mock->expects($this->once()) ->method('getFields') diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityNormalizerTest.php index 70210701..689d654b 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/EntityNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityNormalizerTest.php @@ -2,8 +2,11 @@ namespace Drupal\Tests\serialization\Unit\Normalizer; +use Drupal\Core\Entity\FieldableEntityInterface; +use Drupal\Core\Field\FieldItemListInterface; use Drupal\serialization\Normalizer\EntityNormalizer; use Drupal\Tests\UnitTestCase; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; /** * @coversDefaultClass \Drupal\serialization\Normalizer\EntityNormalizer @@ -49,14 +52,14 @@ public function testNormalize() { $list_item_1 = $this->getMock('Drupal\Core\TypedData\TypedDataInterface'); $list_item_2 = $this->getMock('Drupal\Core\TypedData\TypedDataInterface'); - $definitions = array( + $definitions = [ 'field_1' => $list_item_1, 'field_2' => $list_item_2, - ); + ]; $content_entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase') ->disableOriginalConstructor() - ->setMethods(array('getFields')) + ->setMethods(['getFields']) ->getMockForAbstractClass(); $content_entity->expects($this->once()) ->method('getFields') @@ -64,7 +67,7 @@ public function testNormalize() { $serializer = $this->getMockBuilder('Symfony\Component\Serializer\Serializer') ->disableOriginalConstructor() - ->setMethods(array('normalize')) + ->setMethods(['normalize']) ->getMock(); $serializer->expects($this->at(0)) ->method('normalize') @@ -82,11 +85,10 @@ public function testNormalize() { * Tests the denormalize() method with no entity type provided in context. * * @covers ::denormalize - * - * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException */ public function testDenormalizeWithNoEntityType() { - $this->entityNormalizer->denormalize(array(), 'Drupal\Core\Entity\ContentEntityBase'); + $this->setExpectedException(UnexpectedValueException::class); + $this->entityNormalizer->denormalize([], 'Drupal\Core\Entity\ContentEntityBase'); } /** @@ -104,6 +106,10 @@ public function testDenormalizeWithValidBundle() { ]; $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + + $entity_type->expects($this->once()) + ->method('id') + ->willReturn('test'); $entity_type->expects($this->once()) ->method('hasKey') ->with('bundle') @@ -112,6 +118,11 @@ public function testDenormalizeWithValidBundle() { ->method('getKey') ->with('bundle') ->will($this->returnValue('test_type')); + $entity_type->expects($this->once()) + ->method('isSubClassOf') + ->with(FieldableEntityInterface::class) + ->willReturn(TRUE); + $entity_type->expects($this->once()) ->method('getBundleEntityType') ->will($this->returnValue('test_bundle')); @@ -154,32 +165,56 @@ public function testDenormalizeWithValidBundle() { ->with('test_bundle') ->will($this->returnValue($entity_type_storage)); - // The expected test data should have a modified test_type property. - $expected_test_data = array( - 'key_1' => 'value_1', - 'key_2' => 'value_2', - 'test_type' => 'test_bundle', - ); + $key_1 = $this->getMock(FieldItemListInterface::class); + $key_2 = $this->getMock(FieldItemListInterface::class); + + $entity = $this->getMock(FieldableEntityInterface::class); + $entity->expects($this->at(0)) + ->method('get') + ->with('key_1') + ->willReturn($key_1); + $entity->expects($this->at(1)) + ->method('get') + ->with('key_2') + ->willReturn($key_2); $storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); + // Create should only be called with the bundle property at first. + $expected_test_data = [ + 'test_type' => 'test_bundle', + ]; + $storage->expects($this->once()) ->method('create') ->with($expected_test_data) - ->will($this->returnValue($this->getMock('Drupal\Core\Entity\EntityInterface'))); + ->will($this->returnValue($entity)); $this->entityManager->expects($this->at(3)) ->method('getStorage') ->with('test') ->will($this->returnValue($storage)); + // Setup expectations for the serializer. This will be called for each field + // item. + $serializer = $this->getMockBuilder('Symfony\Component\Serializer\Serializer') + ->disableOriginalConstructor() + ->setMethods(['denormalize']) + ->getMock(); + $serializer->expects($this->at(0)) + ->method('denormalize') + ->with('value_1', get_class($key_1), NULL, ['target_instance' => $key_1, 'entity_type' => 'test']); + $serializer->expects($this->at(1)) + ->method('denormalize') + ->with('value_2', get_class($key_2), NULL, ['target_instance' => $key_2, 'entity_type' => 'test']); + + $this->entityNormalizer->setSerializer($serializer); + $this->assertNotNull($this->entityNormalizer->denormalize($test_data, 'Drupal\Core\Entity\ContentEntityBase', NULL, ['entity_type' => 'test'])); } /** * Tests the denormalize method with a bundle property. * - * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException - * * @covers ::denormalize */ public function testDenormalizeWithInvalidBundle() { @@ -192,6 +227,10 @@ public function testDenormalizeWithInvalidBundle() { ]; $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + + $entity_type->expects($this->once()) + ->method('id') + ->willReturn('test'); $entity_type->expects($this->once()) ->method('hasKey') ->with('bundle') @@ -200,6 +239,11 @@ public function testDenormalizeWithInvalidBundle() { ->method('getKey') ->with('bundle') ->will($this->returnValue('test_type')); + $entity_type->expects($this->once()) + ->method('isSubClassOf') + ->with(FieldableEntityInterface::class) + ->willReturn(TRUE); + $entity_type->expects($this->once()) ->method('getBundleEntityType') ->will($this->returnValue('test_bundle')); @@ -242,7 +286,7 @@ public function testDenormalizeWithInvalidBundle() { ->with('test_bundle') ->will($this->returnValue($entity_type_storage)); - + $this->setExpectedException(UnexpectedValueException::class); $this->entityNormalizer->denormalize($test_data, 'Drupal\Core\Entity\ContentEntityBase', NULL, ['entity_type' => 'test']); } @@ -252,12 +296,16 @@ public function testDenormalizeWithInvalidBundle() { * @covers ::denormalize */ public function testDenormalizeWithNoBundle() { - $test_data = array( + $test_data = [ 'key_1' => 'value_1', 'key_2' => 'value_2', - ); + ]; $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->once()) + ->method('isSubClassOf') + ->with(FieldableEntityInterface::class) + ->willReturn(TRUE); $entity_type->expects($this->once()) ->method('hasKey') ->with('bundle') @@ -270,6 +318,76 @@ public function testDenormalizeWithNoBundle() { ->with('test') ->will($this->returnValue($entity_type)); + $key_1 = $this->getMock(FieldItemListInterface::class); + $key_2 = $this->getMock(FieldItemListInterface::class); + + $entity = $this->getMock(FieldableEntityInterface::class); + $entity->expects($this->at(0)) + ->method('get') + ->with('key_1') + ->willReturn($key_1); + $entity->expects($this->at(1)) + ->method('get') + ->with('key_2') + ->willReturn($key_2); + + $storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); + $storage->expects($this->once()) + ->method('create') + ->with([]) + ->will($this->returnValue($entity)); + + $this->entityManager->expects($this->once()) + ->method('getStorage') + ->with('test') + ->will($this->returnValue($storage)); + + $this->entityManager->expects($this->never()) + ->method('getBaseFieldDefinitions'); + + // Setup expectations for the serializer. This will be called for each field + // item. + $serializer = $this->getMockBuilder('Symfony\Component\Serializer\Serializer') + ->disableOriginalConstructor() + ->setMethods(['denormalize']) + ->getMock(); + $serializer->expects($this->at(0)) + ->method('denormalize') + ->with('value_1', get_class($key_1), NULL, ['target_instance' => $key_1, 'entity_type' => 'test']); + $serializer->expects($this->at(1)) + ->method('denormalize') + ->with('value_2', get_class($key_2), NULL, ['target_instance' => $key_2, 'entity_type' => 'test']); + + $this->entityNormalizer->setSerializer($serializer); + + $this->assertNotNull($this->entityNormalizer->denormalize($test_data, 'Drupal\Core\Entity\ContentEntityBase', NULL, ['entity_type' => 'test'])); + } + + /** + * Tests the denormalize method with no bundle defined. + * + * @covers ::denormalize + */ + public function testDenormalizeWithNoFieldableEntityType() { + $test_data = [ + 'key_1' => 'value_1', + 'key_2' => 'value_2', + ]; + + $entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface'); + $entity_type->expects($this->once()) + ->method('isSubClassOf') + ->with(FieldableEntityInterface::class) + ->willReturn(FALSE); + + $entity_type->expects($this->never()) + ->method('getKey'); + + $this->entityManager->expects($this->once()) + ->method('getDefinition') + ->with('test') + ->will($this->returnValue($entity_type)); + $storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface'); $storage->expects($this->once()) ->method('create') @@ -284,7 +402,7 @@ public function testDenormalizeWithNoBundle() { $this->entityManager->expects($this->never()) ->method('getBaseFieldDefinitions'); - $this->assertNotNull($this->entityNormalizer->denormalize($test_data, 'Drupal\Core\Entity\ContentEntityBase', NULL, array('entity_type' => 'test'))); + $this->assertNotNull($this->entityNormalizer->denormalize($test_data, 'Drupal\Core\Entity\ContentEntityBase', NULL, ['entity_type' => 'test'])); } } diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php index d010a049..e0561a10 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php @@ -3,11 +3,18 @@ namespace Drupal\Tests\serialization\Unit\Normalizer; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; +use Drupal\Core\Entity\EntityRepositoryInterface; +use Drupal\Core\Entity\FieldableEntityInterface; +use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; use Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer; use Drupal\Tests\UnitTestCase; use Prophecy\Argument; +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Serializer; /** @@ -37,11 +44,26 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase { */ protected $fieldItem; + /** + * The mock entity repository. + * + * @var \Drupal\Core\Entity\EntityRepositoryInterface|\Prophecy\Prophecy\ObjectProphecy + */ + protected $entityRepository; + + /** + * The mock field definition. + * + * @var \Drupal\Core\Field\FieldDefinitionInterface|\Prophecy\Prophecy\ObjectProphecy + */ + protected $fieldDefinition; + /** * {@inheritdoc} */ protected function setUp() { - $this->normalizer = new EntityReferenceFieldItemNormalizer(); + $this->entityRepository = $this->prophesize(EntityRepositoryInterface::class); + $this->normalizer = new EntityReferenceFieldItemNormalizer($this->entityRepository->reveal()); $this->serializer = $this->prophesize(Serializer::class); // Set up the serializer to return an entity property. @@ -53,6 +75,9 @@ protected function setUp() { $this->fieldItem = $this->prophesize(EntityReferenceItem::class); $this->fieldItem->getIterator() ->willReturn(new \ArrayIterator(['target_id' => []])); + + $this->fieldDefinition = $this->prophesize(FieldDefinitionInterface::class); + } /** @@ -63,6 +88,14 @@ public function testSupportsNormalization() { $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); } + /** + * @covers ::supportsDenormalization + */ + public function testSupportsDenormalization() { + $this->assertTrue($this->normalizer->supportsDenormalization([], EntityReferenceItem::class)); + $this->assertFalse($this->normalizer->supportsDenormalization([], FieldItemInterface::class)); + } + /** * @covers ::normalize */ @@ -121,4 +154,149 @@ public function testNormalizeWithNoEntity() { $this->assertSame($expected, $normalized); } + /** + * @covers ::denormalize + */ + public function testDenormalizeWithTypeAndUuid() { + $data = [ + 'target_id' => ['value' => 'test'], + 'target_type' => 'test_type', + 'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb', + ]; + + $entity = $this->prophesize(FieldableEntityInterface::class); + $entity->id() + ->willReturn('test') + ->shouldBeCalled(); + $this->entityRepository + ->loadEntityByUuid($data['target_type'], $data['target_uuid']) + ->willReturn($entity) + ->shouldBeCalled(); + + $this->fieldItem->setValue(['target_id' => 'test'])->shouldBeCalled(); + + $this->assertDenormalize($data); + } + + /** + * @covers ::denormalize + */ + public function testDenormalizeWithUuidWithoutType() { + $data = [ + 'target_id' => ['value' => 'test'], + 'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb', + ]; + + $entity = $this->prophesize(FieldableEntityInterface::class); + $entity->id() + ->willReturn('test') + ->shouldBeCalled(); + $this->entityRepository + ->loadEntityByUuid('test_type', $data['target_uuid']) + ->willReturn($entity) + ->shouldBeCalled(); + + $this->fieldItem->setValue(['target_id' => 'test'])->shouldBeCalled(); + + $this->assertDenormalize($data); + } + + /** + * @covers ::denormalize + */ + public function testDenormalizeWithUuidWithIncorrectType() { + $this->setExpectedException(UnexpectedValueException::class, 'The field "field_reference" property "target_type" must be set to "test_type" or omitted.'); + + $data = [ + 'target_id' => ['value' => 'test'], + 'target_type' => 'wrong_type', + 'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb', + ]; + + $this->fieldDefinition + ->getName() + ->willReturn('field_reference') + ->shouldBeCalled(); + + $this->assertDenormalize($data); + } + + /** + * @covers ::denormalize + */ + public function testDenormalizeWithTypeWithIncorrectUuid() { + $this->setExpectedException(InvalidArgumentException::class, 'No "test_type" entity found with UUID "unique-but-none-non-existent" for field "field_reference"'); + + $data = [ + 'target_id' => ['value' => 'test'], + 'target_type' => 'test_type', + 'target_uuid' => 'unique-but-none-non-existent', + ]; + $this->entityRepository + ->loadEntityByUuid($data['target_type'], $data['target_uuid']) + ->willReturn(NULL) + ->shouldBeCalled(); + $this->fieldItem + ->getName() + ->willReturn('field_reference') + ->shouldBeCalled(); + + + $this->assertDenormalize($data); + } + + /** + * @covers ::denormalize + */ + public function testDenormalizeWithEmtpyUuid() { + $this->setExpectedException(InvalidArgumentException::class, 'If provided "target_uuid" cannot be empty for field "test_type".'); + + $data = [ + 'target_id' => ['value' => 'test'], + 'target_type' => 'test_type', + 'target_uuid' => '', + ]; + $this->fieldItem + ->getName() + ->willReturn('field_reference') + ->shouldBeCalled(); + + + $this->assertDenormalize($data); + } + + /** + * @covers ::denormalize + */ + public function testDenormalizeWithId() { + $data = [ + 'target_id' => ['value' => 'test'], + ]; + $this->fieldItem->setValue($data)->shouldBeCalled(); + + $this->assertDenormalize($data); + } + + /** + * Asserts denormalization process is correct for give data. + * + * @param array $data + * The data to denormalize. + */ + protected function assertDenormalize(array $data) { + $this->fieldItem->getParent() + ->willReturn($this->prophesize(FieldItemListInterface::class)->reveal()); + $this->fieldItem->getFieldDefinition()->willReturn($this->fieldDefinition->reveal()); + if (!empty($data['target_uuid'])) { + $this->fieldDefinition + ->getSetting('target_type') + ->willReturn('test_type') + ->shouldBeCalled(); + } + + $context = ['target_instance' => $this->fieldItem->reveal()]; + $denormalized = $this->normalizer->denormalize($data, EntityReferenceItem::class, 'json', $context); + $this->assertSame($context['target_instance'], $denormalized); + } + } diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/ListNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/ListNormalizerTest.php index bbc7c110..fccc6dba 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/ListNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/ListNormalizerTest.php @@ -34,7 +34,7 @@ class ListNormalizerTest extends UnitTestCase { * * @var array */ - protected $expectedListValues = array('test', 'test', 'test'); + protected $expectedListValues = ['test', 'test', 'test']; /** * The mocked typed data. @@ -54,7 +54,7 @@ protected function setUp() { // Set up a mock container as ItemList() will call for the 'typed_data_manager' // service. $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->setMethods(array('get')) + ->setMethods(['get']) ->getMock(); $container->expects($this->any()) ->method('get') diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/NormalizerBaseTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/NormalizerBaseTest.php index e77882ac..63b9bf71 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/NormalizerBaseTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/NormalizerBaseTest.php @@ -26,7 +26,7 @@ class NormalizerBaseTest extends UnitTestCase { * @param mixed $data * The data passed to supportsNormalization. * @param string $supported_interface_or_class - * (optional) the supported interface or class to set on the normalizer. + * (optional) The supported interface or class to set on the normalizer. */ public function testSupportsNormalization($expected_return, $data, $supported_interface_or_class = NULL) { $normalizer_base = $this->getMockForAbstractClass('Drupal\Tests\serialization\Unit\Normalizer\TestNormalizerBase'); @@ -45,20 +45,20 @@ public function testSupportsNormalization($expected_return, $data, $supported_in * An array of provider data for testSupportsNormalization. */ public function providerTestSupportsNormalization() { - return array( + return [ // Something that is not an object should return FALSE immediately. - array(FALSE, array()), + [FALSE, []], // An object with no class set should return FALSE. - array(FALSE, new \stdClass()), + [FALSE, new \stdClass()], // Set a supported Class. - array(TRUE, new \stdClass(), 'stdClass'), + [TRUE, new \stdClass(), 'stdClass'], // Set a supported interface. - array(TRUE, new \RecursiveArrayIterator(), 'RecursiveIterator'), + [TRUE, new \RecursiveArrayIterator(), 'RecursiveIterator'], // Set a different class. - array(FALSE, new \stdClass(), 'ArrayIterator'), + [FALSE, new \stdClass(), 'ArrayIterator'], // Set a different interface. - array(FALSE, new \stdClass(), 'RecursiveIterator'), - ); + [FALSE, new \stdClass(), 'RecursiveIterator'], + ]; } } diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/PrimitiveDataNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/PrimitiveDataNormalizerTest.php new file mode 100644 index 00000000..acdc6daa --- /dev/null +++ b/core/modules/serialization/tests/src/Unit/Normalizer/PrimitiveDataNormalizerTest.php @@ -0,0 +1,101 @@ +normalizer = new PrimitiveDataNormalizer(); + } + + /** + * @covers ::supportsNormalization + * @dataProvider dataProviderPrimitiveData + */ + public function testSupportsNormalization($primitive_data, $expected) { + $this->assertTrue($this->normalizer->supportsNormalization($primitive_data)); + } + + /** + * @covers ::supportsNormalization + */ + public function testSupportsNormalizationFail() { + // Test that an object not implementing PrimitiveInterface fails. + $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); + } + + /** + * @covers ::normalize + * @dataProvider dataProviderPrimitiveData + */ + public function testNormalize($primitive_data, $expected) { + $this->assertSame($expected, $this->normalizer->normalize($primitive_data)); + } + + /** + * Data provider for testNormalize(). + */ + public function dataProviderPrimitiveData() { + $data = []; + + $definition = DataDefinition::createFromDataType('string'); + $string = new StringData($definition, 'string'); + $string->setValue('test'); + + $data['string'] = [$string, 'test']; + + $definition = DataDefinition::createFromDataType('string'); + $string = new StringData($definition, 'string'); + $string->setValue(NULL); + + $data['string-null'] = [$string, NULL]; + + $definition = DataDefinition::createFromDataType('integer'); + $integer = new IntegerData($definition, 'integer'); + $integer->setValue(5); + + $data['integer'] = [$integer, 5]; + + $definition = DataDefinition::createFromDataType('integer'); + $integer = new IntegerData($definition, 'integer'); + $integer->setValue(NULL); + + $data['integer-null'] = [$integer, NULL]; + + $definition = DataDefinition::createFromDataType('boolean'); + $boolean = new BooleanData($definition, 'boolean'); + $boolean->setValue(TRUE); + + $data['boolean'] = [$boolean, TRUE]; + + $definition = DataDefinition::createFromDataType('boolean'); + $boolean = new BooleanData($definition, 'boolean'); + $boolean->setValue(NULL); + + $data['boolean-null'] = [$boolean, NULL]; + + return $data; + } + +} diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php new file mode 100644 index 00000000..fd1fc9ce --- /dev/null +++ b/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php @@ -0,0 +1,156 @@ +normalizer = new TimestampItemNormalizer(); + } + + /** + * @covers ::supportsNormalization + */ + public function testSupportsNormalization() { + $timestamp_item = $this->createTimestampItemProphecy(); + $this->assertTrue($this->normalizer->supportsNormalization($timestamp_item->reveal())); + + $entity_ref_item = $this->prophesize(EntityReferenceItem::class); + $this->assertFalse($this->normalizer->supportsNormalization($entity_ref_item->reveal())); + } + + /** + * @covers ::supportsDenormalization + */ + public function testSupportsDenormalization() { + $timestamp_item = $this->createTimestampItemProphecy(); + $this->assertTrue($this->normalizer->supportsDenormalization($timestamp_item->reveal(), TimestampItem::class)); + + // CreatedItem extends regular TimestampItem. + $timestamp_item = $this->prophesize(CreatedItem::class); + $this->assertTrue($this->normalizer->supportsDenormalization($timestamp_item->reveal(), TimestampItem::class)); + + $entity_ref_item = $this->prophesize(EntityReferenceItem::class); + $this->assertFalse($this->normalizer->supportsNormalization($entity_ref_item->reveal(), TimestampItem::class)); + } + + /** + * Tests the normalize function. + * + * @covers ::normalize + */ + public function testNormalize() { + $expected = ['value' => '2016-11-06T09:02:00+00:00', 'format' => \DateTime::RFC3339]; + + $timestamp_item = $this->createTimestampItemProphecy(); + $timestamp_item->getIterator() + ->willReturn(new \ArrayIterator(['value' => 1478422920])); + + $serializer = new Serializer(); + $this->normalizer->setSerializer($serializer); + + $normalized = $this->normalizer->normalize($timestamp_item->reveal()); + $this->assertSame($expected, $normalized); + } + + /** + * Tests the denormalize function with good data. + * + * @covers ::denormalize + * @dataProvider providerTestDenormalizeValidFormats + */ + public function testDenormalizeValidFormats($value, $expected) { + $normalized = ['value' => $value]; + + $timestamp_item = $this->createTimestampItemProphecy(); + // The field item should be set with the expected timestamp. + $timestamp_item->setValue(['value' => $expected]) + ->shouldBeCalled(); + + $context = ['target_instance' => $timestamp_item->reveal()]; + + $denormalized = $this->normalizer->denormalize($normalized, TimestampItem::class, NULL, $context); + $this->assertTrue($denormalized instanceof TimestampItem); + } + + /** + * Data provider for testDenormalizeValidFormats. + * + * @return array + */ + public function providerTestDenormalizeValidFormats() { + $expected_stamp = 1478422920; + + $data = []; + + $data['U'] = [$expected_stamp, $expected_stamp]; + $data['RFC3339'] = ['2016-11-06T09:02:00+00:00', $expected_stamp]; + $data['RFC3339 +0100'] = ['2016-11-06T09:02:00+01:00', $expected_stamp - 1 * 3600]; + $data['RFC3339 -0600'] = ['2016-11-06T09:02:00-06:00', $expected_stamp + 6 * 3600]; + + $data['ISO8601'] = ['2016-11-06T09:02:00+0000', $expected_stamp]; + $data['ISO8601 +0100'] = ['2016-11-06T09:02:00+0100', $expected_stamp - 1 * 3600]; + $data['ISO8601 -0600'] = ['2016-11-06T09:02:00-0600', $expected_stamp + 6 * 3600]; + + return $data; + } + + /** + * Tests the denormalize function with bad data. + * + * @covers ::denormalize + */ + public function testDenormalizeException() { + $this->setExpectedException(UnexpectedValueException::class, 'The specified date "2016/11/06 09:02am GMT" is not in an accepted format: "U" (UNIX timestamp), "Y-m-d\TH:i:sO" (ISO 8601), "Y-m-d\TH:i:sP" (RFC 3339).'); + + $context = ['target_instance' => $this->createTimestampItemProphecy()->reveal()]; + + $normalized = ['value' => '2016/11/06 09:02am GMT']; + $this->normalizer->denormalize($normalized, TimestampItem::class, NULL, $context); + } + + /** + * Creates a TimestampItem prophecy. + * + * @return \Prophecy\Prophecy\ObjectProphecy|\Drupal\Core\Field\Plugin\Field\FieldType\TimestampItem + */ + protected function createTimestampItemProphecy() { + $timestamp_item = $this->prophesize(TimestampItem::class); + $timestamp_item->getParent() + ->willReturn(TRUE); + + return $timestamp_item; + } + +} diff --git a/core/modules/settings_tray/css/off-canvas.base.css b/core/modules/settings_tray/css/off-canvas.base.css new file mode 100644 index 00000000..aaa713db --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.base.css @@ -0,0 +1,238 @@ +/** + * @file + * Set base styles for the settings tray. + */ + +/* Set some global attributes. */ +#drupal-off-canvas *, +#drupal-off-canvas *:not(div) { + background: #444; + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; + color: #ddd; +} + +/* Generic elements. */ +#drupal-off-canvas a, +#drupal-off-canvas .link { + border-bottom: none; + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; + font-size: inherit; + font-weight: normal; + color: #85bef4; + text-decoration: none; + transition: color .5s ease; +} + +#drupal-off-canvas a:focus, +#drupal-off-canvas .link:focus, +#drupal-off-canvas a:hover, +#drupal-off-canvas .link:hover { + outline: none; + color: #46a0f5; +} +#drupal-off-canvas hr { + height: 1px; + background: #cccccc; +} +#drupal-off-canvas summary, +#drupal-off-canvas .fieldgroup:not(.form-composite) > legend { + font-weight: bold; +} +#drupal-off-canvas h1, +#drupal-off-canvas .heading-a { + display: block; + font-weight: bold; + font-size: 1.625em; + line-height: 1.875em; +} +#drupal-off-canvas h2, +#drupal-off-canvas .heading-b { + display: block; + font-weight: bold; + margin: 10px 0; + font-size: 1.385em; +} +#drupal-off-canvas h3, +#drupal-off-canvas .heading-c { + display: block; + font-weight: bold; + margin: 10px 0; + font-size: 1.231em; +} +#drupal-off-canvas h4, +#drupal-off-canvas .heading-d { + display: block; + font-weight: bold; + margin: 10px 0; + font-size: 1.154em; +} +#drupal-off-canvas h5, +#drupal-off-canvas .heading-e { + display: block; + font-weight: bold; + margin: 10px 0; + font-size: 1.077em; +} +#drupal-off-canvas h6, +#drupal-off-canvas .heading-f { + display: block; + font-weight: bold; + margin: 10px 0; + font-size: 1.077em; +} +#drupal-off-canvas p { + margin: 1em 0; +} +#drupal-off-canvas dl { + margin: 0 0 20px; +} +#drupal-off-canvas dl dd, +#drupal-off-canvas dl dl { + margin-left: 20px; /* LTR */ + margin-bottom: 10px; +} +[dir="rtl"] #drupal-off-canvas dl dd, +[dir="rtl"] #drupal-off-canvas dl dl { + margin-right: 20px; +} +#drupal-off-canvas blockquote { + margin: 1em 40px; +} +#drupal-off-canvas address { + font-style: italic; +} +#drupal-off-canvas u, +#drupal-off-canvas ins { + text-decoration: underline; +} +#drupal-off-canvas s, +#drupal-off-canvas strike, +#drupal-off-canvas del { + text-decoration: line-through; +} +#drupal-off-canvas big { + font-size: larger; +} +#drupal-off-canvas small { + font-size: smaller; +} +#drupal-off-canvas sub { + vertical-align: sub; + font-size: smaller; + line-height: normal; +} +#drupal-off-canvas sup { + vertical-align: super; + font-size: smaller; + line-height: normal; +} +#drupal-off-canvas nobr { + white-space: nowrap; +} +#drupal-off-canvas abbr, +#drupal-off-canvas acronym { + border-bottom: dotted 1px; + background: transparent; +} + +#drupal-off-canvas ul { + list-style-type: disc; + list-style-image: none; +} +[dir="rtl"] #drupal-off-canvas .messages__list { + margin-right: 0; +} +#drupal-off-canvas ol { + list-style-type: decimal; +} +#drupal-off-canvas ul li, +#drupal-off-canvas ol li { + display: block; +} +#drupal-off-canvas quote, +#drupal-off-canvas code { + margin: 20px 0; +} +#drupal-off-canvas pre { + margin: 20px 0; + white-space: pre-wrap; +} + +/* Classes for hidden and visually hidden elements. See hidden.module.css. */ +#drupal-off-canvas .hidden { + display: none; +} +#drupal-off-canvas .visually-hidden { + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); + overflow: hidden; + height: 1px; + width: 1px; + word-wrap: normal; +} +#drupal-off-canvas .visually-hidden.focusable:active, +#drupal-off-canvas .visually-hidden.focusable:focus { + position: static !important; + clip: auto; + overflow: visible; + height: auto; + width: auto; +} +#drupal-off-canvas .invisible { + visibility: hidden; +} + +/* Some system classes. See system.admin.css. */ +#drupal-off-canvas .panel { + padding: 5px 5px 15px; +} +#drupal-off-canvas .panel__description { + margin: 0 0 3px; + padding: 2px 0 3px 0; +} +#drupal-off-canvas .compact-link { + margin: 0 0 10px 0; +} +#drupal-off-canvas small .admin-link:before { + content: ' ['; +} +#drupal-off-canvas small .admin-link:after { + content: ']'; +} + +/* Override jQuery UI */ +#drupal-off-canvas .ui-widget-content a { + color: #85bef4 !important; +} + +/* Message styles */ +#drupal-off-canvas .messages { + background: no-repeat 10px 17px; +} +[dir="rtl"] #drupal-off-canvas .messages { + background-position: right 10px top 17px; +} +#drupal-off-canvas .messages abbr { + color: #444; +} +#drupal-off-canvas .messages--status { + background-color: #f3faef; + background-image: url(../../../misc/icons/73b355/check.svg); + color: #325e1c; +} +#drupal-off-canvas .messages--warning { + background-color: #fdf8ed; + background-image: url(../../../misc/icons/e29700/warning.svg); + color: #734c00; +} + +#drupal-off-canvas .messages--error { + background-color: #fcf4f2; + background-image: url(../../../misc/icons/e32700/error.svg); + color: #a51b00; +} + +#drupal-off-canvas .messages--error div[role="alert"] { + background: transparent; + color: inherit; +} diff --git a/core/modules/settings_tray/css/off-canvas.button.css b/core/modules/settings_tray/css/off-canvas.button.css new file mode 100644 index 00000000..2b734f8a --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.button.css @@ -0,0 +1,118 @@ +/** + * @file + * Visual styling for buttons in the off canvas tray. + * + * See seven/css/components/buttons.css + */ + +#drupal-off-canvas button, +#drupal-off-canvas .button { + -webkit-appearance: none; + -moz-appearance: none; + margin: 0 0 10px; + padding: 0; + border: 0; + box-shadow: none; + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; + line-height: normal; + text-transform: none; + text-decoration: none; + cursor: pointer; +} +#drupal-off-canvas button.link { + display: inline; + background: transparent; + font-size: 14px; + color: #85bef4; + transition: color .5s ease; +} +#drupal-off-canvas button.link:hover, +#drupal-off-canvas button.link:focus { + color: #46a0f5; + text-decoration: none; +} +#drupal-off-canvas input[type="submit"].button { + display: inline-block; + position: relative; + width: 100%; + height: auto; + padding: 4px 20px; + border: 0; + border-radius: 20em; + background: #777; + font-weight: 600; + font-size: 14px; + color: #f5f5f5; + text-align: center; + cursor: pointer; + transition: background .5s ease; +} +#drupal-off-canvas input[type="submit"].button:hover, +#drupal-off-canvas input[type="submit"].button:focus, +#drupal-off-canvas input[type="submit"].button:active { + border: 0; + color: #fff; + text-decoration: none; + outline: none; + z-index: 10; +} +#drupal-off-canvas input[type="submit"].button:focus, +#drupal-off-canvas input[type="submit"].button:active { + box-shadow: 0 3px 3px 2px rgba(0,0,0,0.1); +} +#drupal-off-canvas input[type="submit"].button--primary { + border: 0; + background: #277abd; + color: #fff; + margin-top: 15px; +} +#drupal-off-canvas input[type="submit"].button--primary:hover, +#drupal-off-canvas input[type="submit"].button--primary:focus, +#drupal-off-canvas input[type="submit"].button--primary:active { + background: #2b8bd8; + outline: none; +} +#drupal-off-canvas .button-action:before { + margin-left: -0.2em; /* LTR */ + padding-right: 0.2em; /* LTR */ + font-size: 14px; + line-height: 16px; +} +[dir="rtl"] #drupal-off-canvas .button-action:before { + margin-right: -0.2em; + margin-left: 0; + padding-right: 0; + padding-left: 0.2em; +} +#drupal-off-canvas .no-touchevents .button--small { + font-size: 13px; + padding: 2px 1em; +} +#drupal-off-canvas .button:disabled, +#drupal-off-canvas .button:disabled:active, +#drupal-off-canvas .button.is-disabled, +#drupal-off-canvas .button.is-disabled:active { + border: 0; + background: #555; + color: #5c5c5c; + font-weight: normal; + cursor: default; +} +#drupal-off-canvas .button--danger { + border-radius: 0; + color: #c72100; + font-weight: 400; + text-decoration: none; +} +#drupal-off-canvas .button--danger:hover, +#drupal-off-canvas .button--danger:focus, +#drupal-off-canvas .button--danger:active { + color: #ff2a00; + text-decoration: none; + text-shadow: none; +} +#drupal-off-canvas .button--danger:disabled, +#drupal-off-canvas .button--danger.is-disabled { + color: #737373; + cursor: default; +} diff --git a/core/modules/settings_tray/css/off-canvas.css b/core/modules/settings_tray/css/off-canvas.css new file mode 100644 index 00000000..d7f3258b --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.css @@ -0,0 +1,57 @@ +/** + * @file + * CSS for off-canvas dialog. + * + * @todo Move CSS into core dialog library https://www.drupal.org/node/2784443. + */ + +/* Position the off-canvas dialog container outside the right of the viewport. */ +.ui-dialog-off-canvas { + box-sizing: border-box; + height: 100%; + overflow: visible; +} + +/* Wrap the form that's inside the off-canvas dialog. */ +.ui-dialog-off-canvas .ui-dialog-content { + padding: 0 20px; + /* Prevent horizontal scrollbar. */ + overflow-x: hidden; + overflow-y: auto; +} +[dir="rtl"] .ui-dialog-off-canvas .ui-dialog-content { + text-align: right; +} + +/* Position the dialog-off-canvas tray container outside the right of the viewport. */ +.ui-dialog-off-canvas { + box-sizing: border-box; + height: 100%; + overflow: visible; +} + +/* Wrap the form that's inside the dialog-off-canvas tray. */ +.ui-dialog-off-canvas #drupal-off-canvas { + padding: 0 20px; + /* Prevent horizontal scrollbar. */ + overflow-x: hidden; + overflow-y: auto; +} +[dir="rtl"] .ui-dialog-off-canvas #drupal-off-canvas { + text-align: right; +} + +/* + * Force the tray to be 100% width at the same breakpoint the dialog system uses + * to expand dialog widths. + */ +@media all and (max-width: 48em) { /* 768px */ + .ui-dialog.ui-dialog-off-canvas { + width: 100% !important; + } + /* When tray is at 100% width stop the body from scrolling */ + .js-tray-open { + height: 100%; + overflow-y: hidden; + } +} diff --git a/core/modules/settings_tray/css/off-canvas.details.css b/core/modules/settings_tray/css/off-canvas.details.css new file mode 100644 index 00000000..dcac6a5b --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.details.css @@ -0,0 +1,61 @@ +/** + * @file + * Visual styling for summary and details in the Settings Tray module's off canvas tray. + */ + +#drupal-off-canvas details, +#drupal-off-canvas summary { + display: block; + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; +} +#drupal-off-canvas details, +#drupal-off-canvas summary, +#drupal-off-canvas .ui-dialog-content { + background: #474747; + color: #ddd; +} +#drupal-off-canvas summary a { + color: #ddd; + padding-top: 0; + padding-bottom: 0; +} +#drupal-off-canvas summary a:hover, +#drupal-off-canvas summary a:focus { + color: #fff; +} +#drupal-off-canvas details, +#drupal-off-canvas summary, +#drupal-off-canvas .details-wrapper { + border-width: 0; + /* Cancel out the padding of the parent. */ + margin: 0 -20px; + padding: 0 20px; +} +#drupal-off-canvas summary { + text-shadow: none; + padding: 10px 20px; + font-size: 14px; + transition: all .5s ease; +} +#drupal-off-canvas summary:hover, +#drupal-off-canvas summary:focus { + background-color: #222; + outline: none; +} +#drupal-off-canvas details[open] { + padding-bottom: 10px; +} +#drupal-off-canvas details[open] > summary { + background-color: #333; + color: #eee; +} +#drupal-off-canvas details[open] > summary:hover { + background-color: #222; + color: #fff; +} +#drupal-off-canvas details .placeholder { + font: inherit; + color: inherit; + font-style: italic; + background: transparent; +} diff --git a/core/modules/settings_tray/css/off-canvas.dropbutton.css b/core/modules/settings_tray/css/off-canvas.dropbutton.css new file mode 100644 index 00000000..e467a4f3 --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.dropbutton.css @@ -0,0 +1,291 @@ +/** + * @file + * Styles for dropbuttons in the off-canvas tray. + */ + +#drupal-off-canvas .dropbutton-wrapper, +#drupal-off-canvas .dropbutton-widget { + -webkit-appearance: none; + -moz-appearance: none; + display: block; + position: static; + transition: none; +} +#drupal-off-canvas .dropbutton-widget { + margin: 0; + padding: 0; + border: 0; + background: #277abd; + border-radius: 1em; + font-weight: 600; + color: #fff; + text-transform: none; + text-decoration: none; + text-align: center; + line-height: normal; + cursor: pointer; + transition: background .5s ease; +} +#drupal-off-canvas .dropbutton-widget:hover { + background: #2b8bd8; +} + +/* + * Style dropbutton single. + */ + +#drupal-off-canvas .dropbutton-single .dropbutton-action a { + padding: 0; + /* Overlap icon for trigger. */ + margin-top: -2em; + height: 2.2em; + cursor: pointer; +} +#drupal-off-canvas .dropbutton-single .dropbutton-action:hover, +#drupal-off-canvas .dropbutton-single .dropbutton-action:focus, +#drupal-off-canvas .dropbutton-single .dropbutton-action a:hover, +#drupal-off-canvas .dropbutton-single .dropbutton-action a:focus { + text-decoration: none; + outline: none; +} +#drupal-off-canvas .dropbutton-widget .dropbutton { + margin: 0; + overflow: hidden; + padding: 0; +} +#drupal-off-canvas .dropbutton li, +#drupal-off-canvas .dropbutton a { + display: block; + width: auto; + padding: 4px 0; + text-align: left; + color: #555; + outline: none; +} +#drupal-off-canvas .dropbutton li:hover, +#drupal-off-canvas .dropbutton li:focus, +#drupal-off-canvas .dropbutton a:hover, +#drupal-off-canvas .dropbutton a:focus { + background: transparent; + color: #333; + outline: none; +} + +/* + * Style dropbutton multiple. + */ + +#drupal-off-canvas .dropbutton-multiple .dropbutton-widget { + width: 2em; + height: 2em; +} +#drupal-off-canvas .dropbutton-multiple .dropbutton-widget:hover { + background-color: #2b8bd8; +} + +/* Hide the other actions until the dropbutton is triggered. */ +#drupal-off-canvas .dropbutton-multiple .dropbutton .secondary-action { + display: none; +} + +/* The toggle to expand the button. */ +#drupal-off-canvas .dropbutton-toggle { + position: absolute; + top: 0; + right: 0; /* LTR */ + bottom: 0; + display: block; + width: 2em; + color: #fff; + text-indent: 110%; + white-space: nowrap; +} +#drupal-off-canvas .dropbutton-toggle button { + display: block; + height: 100%; + width: 100%; + margin: 0; + padding: 0; + border: 0 solid transparent; + border-bottom-right-radius: 1em; /* LTR */ + border-top-right-radius: 1em; /* LTR */ + cursor: pointer; +} +#drupal-off-canvas .dropbutton-toggle button:hover, +#drupal-off-canvas .dropbutton-toggle button:focus { + outline: none; +} + +/* The toggle arrow. */ +#drupal-off-canvas .dropbutton-arrow { + position: absolute; + display: block; + height: 0; + width: 0; + margin-top: 0; + border-bottom-color: transparent; + border-left-color: transparent; + border-right-color: transparent; + border-style: solid; + border-width: 0.3333em 0.3333em 0; + color: #fff; + line-height: 0; + overflow: hidden; +} +#drupal-off-canvas span.dropbutton-arrow { + top: 7px; + right: 7px; /* LTR */ + background: transparent; +} +#drupal-off-canvas span.dropbutton-arrow:hover { + background: transparent; +} + +#drupal-off-canvas .dropbutton-action > .js-form-submit.form-submit, +#drupal-off-canvas .dropbutton-toggle button { + position: relative; + text-shadow: none; +} + +/* + * Dropbuttons when in a table cell. + */ + +/* Make sure table cell doesn't collapse around absolute positioned dropbutton. */ +#drupal-off-canvas td .dropbutton-single { + min-width: 2em; +} +#drupal-off-canvas td .dropbutton-multiple { + min-width: 2em; + padding-right: 0; + padding-left: 0; + margin-right: 0; + margin-left: 0; + border: 0; +} +#drupal-off-canvas td .dropbutton-multiple .dropbutton-action a, +#drupal-off-canvas td .dropbutton-multiple .dropbutton-action input, +#drupal-off-canvas td .dropbutton-multiple .dropbutton-action button { + width: auto; + padding: 0; + font-size: inherit; +} +#drupal-off-canvas td .dropbutton-wrapper { + margin-bottom: 0; +} + +/* Push the widget to the right so text expands left. */ +#drupal-off-canvas td .dropbutton-widget { + position: absolute; + right: 12px; /* LTR */ + padding: 0; + background: #277abd none; +} + +/* Push the wrapper to the right edge of the td. */ +#drupal-off-canvas td .dropbutton-single, +#drupal-off-canvas td .dropbutton-multiple { + float: right; /* LTR */ + padding-right: 0; + margin-right: 0; + max-width: initial; + min-width: initial; + position: relative; +} +#drupal-off-canvas td .dropbutton-widget .dropbutton { + margin: 0; + width: 2em; + height: 2em; + overflow: hidden; + background: transparent; +} + +/* Push text out of the way. */ +#drupal-off-canvas td .dropbutton-multiple li, +#drupal-off-canvas td .dropbutton-multiple a { + margin-left: -9999px; + background: transparent; +} +#drupal-off-canvas td .dropbutton-multiple.open .dropbutton li, +#drupal-off-canvas td .dropbutton-multiple.open .dropbutton a { + margin-left: 0; + width: auto; + color: #fff; +} + +/* Collapse the button to a circle. */ +#drupal-off-canvas td .dropbutton-toggle { + width: 2em; + height: 2em; + border-radius: 1em; +} +#drupal-off-canvas td .dropbutton-wrapper .dropbutton-widget .dropbutton-toggle button { + border: 0; + background: transparent; +} + +/* Prevent list item from expanding it's container. */ +#drupal-off-canvas td ul.dropbutton li.edit { + width: 2em; + height: 2em; +} + +/* Make li text transparent above icon so it's clickable. */ +#drupal-off-canvas td .dropbutton-single li.edit.dropbutton-action > a { + color: transparent; + z-index: 1; +} + +/* Put pencil icon in place of hidden 'edit' text on single buttons. */ +#drupal-off-canvas td .dropbutton-single .edit:before { + content: '.'; + display: block; + color: transparent; + background: transparent url(../../../misc/icons/ffffff/pencil.svg) no-repeat center; + background-size: 14px; +} + +/* Dropbutton when triggered expands to show secondary items. */ +#drupal-off-canvas .dropbutton-multiple.open { + z-index: 100; +} + +/* Create visual separation if there is an adjacent button. */ +#drupal-off-canvas .dropbutton-multiple.open .dropbutton-widget { + box-shadow: 0 3px 3px 2px rgba(0,0,0,0.5); +} + +/* Triggered dropbutton expands to show secondary items. */ +#drupal-off-canvas .dropbutton-multiple.open, +#drupal-off-canvas .dropbutton-multiple.open .dropbutton-widget { + display: block; + width: auto; + height: auto; + max-width: none; + min-width: 0; + padding: 0; + overflow: visible; +} + +/* Triggered dropbutton in td expands to show secondary items. */ +#drupal-off-canvas td .dropbutton-multiple.open .dropbutton, +#drupal-off-canvas .dropbutton-multiple.open .dropbutton .secondary-action { + display: block; + width: auto; + height: auto; + padding-right: 1em; /* LTR */ +} +[dir="rtl"] #drupal-off-canvas td .dropbutton-multiple.open .dropbutton { + padding-left: 1em; + padding-right: inherit; +} +#drupal-off-canvas .dropbutton-multiple.open .dropbutton li a { + padding: 2px 1em; +} + +/* When open, the toggle arrow points upward. */ +#drupal-off-canvas .dropbutton-multiple.open span.dropbutton-arrow { + border-bottom: 0.3333em solid; + border-top-color: transparent; + top: 2px; +} diff --git a/core/modules/settings_tray/css/off-canvas.form.css b/core/modules/settings_tray/css/off-canvas.form.css new file mode 100644 index 00000000..254b2c74 --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.form.css @@ -0,0 +1,136 @@ +/** + * @file + * Visual styling for forms in the Settings Tray module's off canvas tray. + */ + +#drupal-off-canvas form { + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; + color: #ddd; +} +#drupal-off-canvas input[type="checkbox"] { + -webkit-appearance: checkbox; +} +#drupal-off-canvas input[type="radio"] { + -webkit-appearance: radio; +} +#drupal-off-canvas select { + -webkit-appearance: menulist; + -moz-appearance: menulist; +} +#drupal-off-canvas option { + display: block; + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; +} +#drupal-off-canvas label { + line-height: normal; + font-family: inherit; + font-size: 12px; + font-weight: bold; + color: #ddd; +} +#drupal-off-canvas .visually-hidden { + opacity: 0; + height: 0; + width: 0; + letter-spacing: -2em; +} +#drupal-off-canvas .description, +#drupal-off-canvas .form-item .description, +#drupal-off-canvas .details-description { + color: #ddd; + margin-top: 5px; + font-family: inherit; + font-size: 12px; + font-style: normal; +} +#drupal-off-canvas .details-wrapper .description { + color: #bbb; +} +#drupal-off-canvas .form-item { + margin-bottom: 10px; + margin-top: 10px; +} +/* Set size and position for all inputs. */ +#drupal-off-canvas .form-select, +#drupal-off-canvas .form-text, +#drupal-off-canvas .form-tel, +#drupal-off-canvas .form-email, +#drupal-off-canvas .form-url, +#drupal-off-canvas .form-search, +#drupal-off-canvas .form-number, +#drupal-off-canvas .form-color, +#drupal-off-canvas .form-file, +#drupal-off-canvas .form-textarea, +#drupal-off-canvas .form-date, +#drupal-off-canvas .form-time { + box-sizing: border-box; + max-width: 100%; + padding: 6px; + margin: 5px 0 0 0; + border-width: 1px; + border-radius: 2px; + display: block; + font-family: inherit; + font-size: 14px; + color: #333; + line-height: 16px; +} +/* Reduce contrast for fields against dark background. */ +#drupal-off-canvas .form-text, +#drupal-off-canvas .form-tel, +#drupal-off-canvas .form-email, +#drupal-off-canvas .form-url, +#drupal-off-canvas .form-search, +#drupal-off-canvas .form-number, +#drupal-off-canvas .form-color, +#drupal-off-canvas .form-file, +#drupal-off-canvas .form-textarea, +#drupal-off-canvas .form-date, +#drupal-off-canvas .form-time { + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .125); + background-color: #eee; + border-color: #333; + color: #595959; +} +#drupal-off-canvas .form-text:focus, +#drupal-off-canvas .form-tel:focus, +#drupal-off-canvas .form-email:focus, +#drupal-off-canvas .form-url:focus, +#drupal-off-canvas .form-search:focus, +#drupal-off-canvas .form-number:focus, +#drupal-off-canvas .form-color:focus, +#drupal-off-canvas .form-file:focus, +#drupal-off-canvas .form-textarea:focus, +#drupal-off-canvas .form-date:focus, +#drupal-off-canvas .form-time:focus { + border-color: #40b6ff; + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .125), 0 0 8px #40b6ff; + background-color: #fff; +} +#drupal-off-canvas td .form-item, +#drupal-off-canvas td .form-select { + margin: 0; +} +#drupal-off-canvas .form-file { + margin-bottom: 5px; + width: 100%; +} +#drupal-off-canvas .form-actions { + text-align: center; + margin: 10px 0; +} +#drupal-off-canvas .ui-autocomplete { + background-color: white; + position: absolute; + top: 0; + left: 0; + cursor: default; +} +#drupal-off-canvas .ui-autocomplete li { + display: block; +} +#drupal-off-canvas .ui-autocomplete li a { + color: #595959 !important; + cursor: pointer; + padding: 5px; +} diff --git a/core/modules/settings_tray/css/off-canvas.motion.css b/core/modules/settings_tray/css/off-canvas.motion.css new file mode 100644 index 00000000..ae261870 --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.motion.css @@ -0,0 +1,15 @@ +/** + * @file + * Motion effects for off-canvas dialog. + * + * Motion effects are in a separate file so that they can be easily turned off + * to improve performance if desired. + * + * @todo Move motion effects file into a core Off-Canvas library and add a + * configuration option for browser rendering performance to disable this + * file: https://www.drupal.org/node/2784443. + */ + +.dialog-off-canvas__main-canvas { + transition: all .7s ease; +} diff --git a/core/modules/settings_tray/css/off-canvas.reset.css b/core/modules/settings_tray/css/off-canvas.reset.css new file mode 100644 index 00000000..ee12792f --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.reset.css @@ -0,0 +1,388 @@ +/** + * @file + * Reset most HTML elements styles for the off-canvas dialog. + * + * This is a generic reset. Drupal-specific classes are reset in components. + */ + +/** + * Do not include div in then initial overrides because including div will + * cause the need for many more overrides in this file. + */ +#drupal-off-canvas *:not(div), +#drupal-off-canvas *:not(svg *), +#drupal-off-canvas *:after, +#drupal-off-canvas *:before { + all: initial; + box-sizing: border-box; + text-shadow: none; + -webkit-font-smoothing: antialiased; + -webkit-tap-highlight-color: initial; +} + +/* Reset size and position on elements. */ +#drupal-off-canvas a, +#drupal-off-canvas abbr, +#drupal-off-canvas acronym, +#drupal-off-canvas address, +#drupal-off-canvas applet, +#drupal-off-canvas article, +#drupal-off-canvas aside, +#drupal-off-canvas audio, +#drupal-off-canvas b, +#drupal-off-canvas big, +#drupal-off-canvas blockquote, +#drupal-off-canvas body, +#drupal-off-canvas canvas, +#drupal-off-canvas caption, +#drupal-off-canvas cite, +#drupal-off-canvas code, +#drupal-off-canvas dd, +#drupal-off-canvas del, +#drupal-off-canvas dfn, +#drupal-off-canvas dialog, +#drupal-off-canvas dl, +#drupal-off-canvas dt, +#drupal-off-canvas em, +#drupal-off-canvas embed, +#drupal-off-canvas fieldset, +#drupal-off-canvas figcaption, +#drupal-off-canvas figure, +#drupal-off-canvas footer, +#drupal-off-canvas form, +#drupal-off-canvas h1, +#drupal-off-canvas h2, +#drupal-off-canvas h3, +#drupal-off-canvas h4, +#drupal-off-canvas h5, +#drupal-off-canvas h6, +#drupal-off-canvas header, +#drupal-off-canvas hgroup, +#drupal-off-canvas hr, +#drupal-off-canvas html, +#drupal-off-canvas i, +#drupal-off-canvas iframe, +#drupal-off-canvas img, +#drupal-off-canvas ins, +#drupal-off-canvas kbd, +#drupal-off-canvas label, +#drupal-off-canvas legend, +#drupal-off-canvas li, +#drupal-off-canvas main, +#drupal-off-canvas mark, +#drupal-off-canvas menu, +#drupal-off-canvas meter, +#drupal-off-canvas nav, +#drupal-off-canvas object, +#drupal-off-canvas ol, +#drupal-off-canvas output, +#drupal-off-canvas p, +#drupal-off-canvas pre, +#drupal-off-canvas progress, +#drupal-off-canvas q, +#drupal-off-canvas rp, +#drupal-off-canvas rt, +#drupal-off-canvas s, +#drupal-off-canvas samp, +#drupal-off-canvas section, +#drupal-off-canvas small, +#drupal-off-canvas span, +#drupal-off-canvas strike, +#drupal-off-canvas strong, +#drupal-off-canvas sub, +#drupal-off-canvas sup, +#drupal-off-canvas table, +#drupal-off-canvas tbody, +#drupal-off-canvas td, +#drupal-off-canvas tfoot, +#drupal-off-canvas th, +#drupal-off-canvas thead, +#drupal-off-canvas time, +#drupal-off-canvas tr, +#drupal-off-canvas tt, +#drupal-off-canvas u, +#drupal-off-canvas ul, +#drupal-off-canvas var, +#drupal-off-canvas video, +#drupal-off-canvas xmp { + border: 0; + margin: 0; + padding: 0; + font-size: 100%; +} + +/* + * Override the default (display: inline) for browsers that do not recognize HTML5 tags. + * IE8 (and lower) requires a shiv: http://ejohn.org/blog/html5-shiv + */ +#drupal-off-canvas article, +#drupal-off-canvas aside, +#drupal-off-canvas figcaption, +#drupal-off-canvas figure, +#drupal-off-canvas footer, +#drupal-off-canvas header, +#drupal-off-canvas hgroup, +#drupal-off-canvas main, +#drupal-off-canvas menu, +#drupal-off-canvas nav, +#drupal-off-canvas section { + display: block; + line-height: normal; + border-radius: 0; +} + +/* + * Makes browsers agree. + * IE + Opera = font-weight: bold. + * Gecko + WebKit = font-weight: bolder. + */ +#drupal-off-canvas b, +#drupal-off-canvas strong { + font-weight: bold; +} + +#drupal-off-canvas em, +#drupal-off-canvas i { + font-style: italic; +} + +#drupal-off-canvas img { + color: transparent; + font-size: 0; + vertical-align: middle; +} + +#drupal-off-canvas ul, +#drupal-off-canvas ol { + list-style: none; +} + +/* reset table styling. */ +#drupal-off-canvas table { + border-collapse: collapse; + border-spacing: 0; +} +#drupal-off-canvas table thead, +#drupal-off-canvas table tbody, +#drupal-off-canvas table tbody tr:nth-child(even), +#drupal-off-canvas table tbody tr:nth-child(odd), +#drupal-off-canvas table tfoot { + border: 0; + background: transparent none; +} +#drupal-off-canvas th, +#drupal-off-canvas td, +#drupal-off-canvas caption { + font-weight: normal; +} +#drupal-off-canvas q { + quotes: none; +} +#drupal-off-canvas q:before, +#drupal-off-canvas q:after { + content: none; +} +#drupal-off-canvas sub, +#drupal-off-canvas sup, +#drupal-off-canvas small { + font-size: 75%; +} +#drupal-off-canvas sub, +#drupal-off-canvas sup { + line-height: 0; + position: relative; + vertical-align: baseline; +} +#drupal-off-canvas sub { + bottom: -0.25em; +} +#drupal-off-canvas sup { + top: -0.5em; +} + +/* + * For IE9. Without, occasionally draws shapes + * outside the boundaries of rectangle. + */ +#drupal-off-canvas svg { + overflow: hidden; +} + +/* Specific resets for inputs. */ +#drupal-off-canvas input[type="search"]::-webkit-search-decoration { + display: none; +} +#drupal-off-canvas input { + margin: 0; + padding: 0; +} +#drupal-off-canvas input[type="checkbox"], +#drupal-off-canvas input[type="radio"] { + position: static; + margin: 0; +} +#drupal-off-canvas input:invalid, +#drupal-off-canvas button:invalid, +#drupal-off-canvas select:invalid, +#drupal-off-canvas textarea:invalid, +#drupal-off-canvas input:focus, +#drupal-off-canvas button:focus, +#drupal-off-canvas select:focus, +#drupal-off-canvas textarea:focus, +#drupal-off-canvas input[type="file"]:focus, +#drupal-off-canvas input[type="file"]:active, +#drupal-off-canvas input[type="radio"]:focus, +#drupal-off-canvas input[type="radio"]:active, +#drupal-off-canvas input[type="checkbox"]:focus, +#drupal-off-canvas input[type="checkbox"]:active { + box-shadow: none; + z-index: 1; +} +#drupal-off-canvas input[role="button"] { + cursor: pointer; +} +#drupal-off-canvas button, +#drupal-off-canvas input[type="reset"], +#drupal-off-canvas input[type="submit"], +#drupal-off-canvas input[type="button"] { + -webkit-appearance: none; + -moz-appearance: none; + display: inline-block; + background-image: none; + border: 0; + outline: 0; + overflow: visible; + text-shadow: none; + text-decoration: none; + vertical-align: middle; + cursor: pointer; +} +#drupal-off-canvas button:hover, +#drupal-off-canvas input[type="reset"]:hover, +#drupal-off-canvas input[type="submit"]:hover, +#drupal-off-canvas input[type="button"]:hover { + background-image: none; + text-decoration: none; +} +#drupal-off-canvas button:active, +#drupal-off-canvas input[type="reset"]:active, +#drupal-off-canvas input[type="submit"]:active, +#drupal-off-canvas input[type="button"]:active { + background-image: none; + box-shadow: none; + border-color: grey; +} +#drupal-off-canvas button::-moz-focus-inner, +#drupal-off-canvas input[type="reset"]::-moz-focus-inner, +#drupal-off-canvas input[type="submit"]::-moz-focus-inner, +#drupal-off-canvas input[type="button"]::-moz-focus-inner { + border: 0; + padding: 0; +} +#drupal-off-canvas textarea, +#drupal-off-canvas select, +#drupal-off-canvas input[type="date"], +#drupal-off-canvas input[type="datetime"], +#drupal-off-canvas input[type="datetime-local"], +#drupal-off-canvas input[type="email"], +#drupal-off-canvas input[type="month"], +#drupal-off-canvas input[type="number"], +#drupal-off-canvas input[type="password"], +#drupal-off-canvas input[type="search"], +#drupal-off-canvas input[type="tel"], +#drupal-off-canvas input[type="text"], +#drupal-off-canvas input[type="time"], +#drupal-off-canvas input[type="url"], +#drupal-off-canvas input[type="week"] { + height: auto; + vertical-align: middle; + border-radius: 0; +} +#drupal-off-canvas textarea[disabled], +#drupal-off-canvas select[disabled], +#drupal-off-canvas input[type="date"][disabled], +#drupal-off-canvas input[type="datetime"][disabled], +#drupal-off-canvas input[type="datetime-local"][disabled], +#drupal-off-canvas input[type="email"][disabled], +#drupal-off-canvas input[type="month"][disabled], +#drupal-off-canvas input[type="number"][disabled], +#drupal-off-canvas input[type="password"][disabled], +#drupal-off-canvas input[type="search"][disabled], +#drupal-off-canvas input[type="tel"][disabled], +#drupal-off-canvas input[type="text"][disabled], +#drupal-off-canvas input[type="time"][disabled], +#drupal-off-canvas input[type="url"][disabled], +#drupal-off-canvas input[type="week"][disabled] { + background-color: grey; +} +#drupal-off-canvas input[type="hidden"] { + visibility: hidden; +} +#drupal-off-canvas button[disabled], +#drupal-off-canvas input[disabled], +#drupal-off-canvas select[disabled], +#drupal-off-canvas select[disabled] option, +#drupal-off-canvas select[disabled] optgroup, +#drupal-off-canvas textarea[disabled] { + box-shadow: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: default; +} +#drupal-off-canvas input:placeholder, +#drupal-off-canvas textarea:placeholder { + color: grey; +} +#drupal-off-canvas textarea, +#drupal-off-canvas select[size], +#drupal-off-canvas select[multiple] { + height: auto; +} +#drupal-off-canvas select[size="0"], +#drupal-off-canvas select[size="1"] { + height: auto; +} +#drupal-off-canvas textarea { + min-height: 40px; + overflow: auto; + resize: vertical; + width: 100%; +} +#drupal-off-canvas optgroup { + color: black; + font-style: normal; + font-weight: normal; +} +#drupal-off-canvas optgroup::-moz-focus-inner { + border: 0; + padding: 0; +} +#drupal-off-canvas * button { + background: none; + border: 1px solid grey; + color: black; + padding: 0; + text-decoration: none; + overflow: visible; + vertical-align: middle; + width: auto; +} +#drupal-off-canvas * textarea, +#drupal-off-canvas * select, +#drupal-off-canvas *:not(div) textarea, +#drupal-off-canvas *:not(div) select { + background: white; + border: 1px solid grey; + color: black; + padding: 0; + vertical-align: top; +} + +/* To standardize off-canvas selection color. */ +#drupal-off-canvas ::-moz-selection, +#drupal-off-canvas ::selection { + background-color: rgba(175,175,175,0.5); + color: inherit; +} diff --git a/core/modules/settings_tray/css/off-canvas.table.css b/core/modules/settings_tray/css/off-canvas.table.css new file mode 100644 index 00000000..24d2b4c0 --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.table.css @@ -0,0 +1,90 @@ +/** + * @file + * Visual styling for tables in the Settings Tray module's off canvas tray. + */ + +#drupal-off-canvas table * { + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; +} +#drupal-off-canvas table { + display: table; + width: 100%; + min-width: calc(100% + 40px); + /* Cancel out the padding of the parent to make the table full width. */ + margin: 0 -20px -10px -20px; + border: 0; + border-collapse: collapse; + font-size: 12px; + color: #ddd; +} +#drupal-off-canvas table thead { + display: table-header-group; +} +#drupal-off-canvas table tbody { + display: table-row-group; +} +#drupal-off-canvas tr { + display: table-row; +} +#drupal-off-canvas tr:hover td { + background-color: transparent; +} + +#drupal-off-canvas td, +#drupal-off-canvas th { + display: table-cell; + height: auto; + width: auto; + padding: 2px 8px; + vertical-align: middle; + border-bottom: 1px solid #777; + background-color: transparent; +} +[dir="rtl"] #drupal-off-canvas th, +[dir="rtl"] #drupal-off-canvas td { + text-align: right; +} +#drupal-off-canvas th { + font-weight: bold; + color: #bbb; +} +#drupal-off-canvas th.checkbox, +#drupal-off-canvas td.checkbox { + width: 20px; + padding: 0; + text-align: center; +} +#drupal-off-canvas div.checkbox.menu-enabled { + position: static; + display: inline; + width: auto; +} +#drupal-off-canvas th:first-child, +#drupal-off-canvas td:first-child { + width: 150px; +} +/* For lack of a better class, using this to grab the operations th. */ +#drupal-off-canvas .tabledrag-has-colspan { + text-align: right; + padding-right: 20px; +} +#drupal-off-canvas td { + padding: 6px 8px; + color: #ddd; +} +/* Hide overflow with ellipsis for links. */ +#drupal-off-canvas td a { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + background: transparent; +} +#drupal-off-canvas tr td:first-child, +#drupal-off-canvas tr th:first-child { + padding-left: 20px; /* LTR */ +} +[dir="rtl"] #drupal-off-canvas tr td:first-child, +[dir="rtl"] #drupal-off-canvas tr th:first-child { + padding-right: 20px; +} diff --git a/core/modules/settings_tray/css/off-canvas.tabledrag.css b/core/modules/settings_tray/css/off-canvas.tabledrag.css new file mode 100644 index 00000000..20f97954 --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.tabledrag.css @@ -0,0 +1,122 @@ +/** + * @file + * Table drag behavior for Settings Tray module. + * + * @see tabledrag.js + */ + +#drupal-off-canvas .drag { + cursor: move; +} +#drupal-off-canvas tr.region-title { + font-weight: normal; +} +#drupal-off-canvas table .region-message { + color: #fff; +} +#drupal-off-canvas table .region-populated { + display: none; +} +#drupal-off-canvas .add-new .tabledrag-changed { + display: none; +} +#drupal-off-canvas .draggable a.tabledrag-handle { + background-image: none; + margin: 0 5px 0 0; + height: auto; + min-width: 20px; + padding: 0; + overflow: hidden; + float: left; /* LTR */ + text-decoration: none; + cursor: move; +} +[dir="rtl"] #drupal-off-canvas .draggable a.tabledrag-handle { + float: right; + margin-right: 0; + margin-left: 5px; +} +#drupal-off-canvas a.tabledrag-handle .handle { + /* Use lighter drag icon against dark background. */ + background-color: transparent; + background-image: url(../../../misc/icons/bebebe/move.svg); + background-repeat: no-repeat; + background-position: center; + height: auto; + margin: 0; + padding: 0; + width: auto; +} +#drupal-off-canvas .draggable a.tabledrag-handle:hover .handle, +#drupal-off-canvas .draggable a.tabledrag-handle:focus .handle { + background-image: url(../../../misc/icons/787878/move.svg); + text-decoration: none; +} +#drupal-off-canvas tr td { + transition: background .3s ease; +} + +#drupal-off-canvas tr td abbr { + margin-left: 5px; /* LTR */ +} + +[dir="rtl"] #drupal-off-canvas tr td abbr { + margin-left: 0; + margin-right: 5px; +} +#drupal-off-canvas tr:hover td { + background: #222; +} +#drupal-off-canvas tr.drag td { + background: #111; +} +#drupal-off-canvas tr.drag-previous td { + background: #000; +} +#drupal-off-canvas tr.drag-previous:hover td { + background: #222; +} +body div.tabledrag-changed-warning { + margin-bottom: 0.5em; + font-size: 14px; +} +#drupal-off-canvas .touchevents .draggable td { + padding: 0 10px; +} +#drupal-off-canvas .touchevents .draggable .menu-item__link { + display: inline-block; + padding: 10px 0; +} +#drupal-off-canvas .touchevents a.tabledrag-handle { + height: 44px; + width: 40px; +} +#drupal-off-canvas .touchevents a.tabledrag-handle .handle { + background-position: 40% 19px; /* LTR */ + height: 21px; +} +[dir="rtl"] #drupal-off-canvas .touch a.tabledrag-handle .handle { + background-position: right 40% top 19px; +} +#drupal-off-canvas .touchevents .draggable.drag a.tabledrag-handle .handle { + background-position: 50% -32px; +} +#drupal-off-canvas .tabledrag-toggle-weight-wrapper { + padding-top: 10px; + text-align: right; /* LTR */ +} +[dir="rtl"] #drupal-off-canvas .tabledrag-toggle-weight-wrapper { + text-align: left; +} +#drupal-off-canvas .indentation { + float: left; /* LTR */ + height: auto; + margin: 0 3px 0 -10px; /* LTR */ + padding: 0 0 0 10px; /* LTR */ + width: auto; +} +[dir="rtl"] #drupal-off-canvas .indentation { + float: right; + margin: 0 -10px 0 3px; + padding: 0 10px 0 0; +} diff --git a/core/modules/settings_tray/css/off-canvas.theme.css b/core/modules/settings_tray/css/off-canvas.theme.css new file mode 100644 index 00000000..0493e3ce --- /dev/null +++ b/core/modules/settings_tray/css/off-canvas.theme.css @@ -0,0 +1,93 @@ +/** + * @file + * Styling for the off-canvas ui dialog. Including overrides for jQuery UI. + */ + +/* Style the dialog-off-canvas container. */ +.ui-dialog.ui-dialog-off-canvas { + background: #444; + border: 0 solid transparent; + border-radius: 0; + box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.3333); + padding: 0; + color: #ddd; + /* Layer the dialog just under the toolbar. */ + z-index: 501; +} + +/* Style the tray header. */ +.ui-dialog.ui-dialog-off-canvas .ui-dialog-titlebar { + padding: 1em; + background: #2d2d2d; + border: 0; + border-bottom: 1px solid #000; + border-radius: 0; + font-weight: normal; + color: #fff; +} +/* Hide the default jQuery UI dialog close button. */ +.ui-dialog.ui-dialog-off-canvas .ui-dialog-titlebar-close .ui-icon { + visibility: hidden; +} +.ui-dialog.ui-dialog-off-canvas .ui-dialog-titlebar-close { + background-image: url(../../../misc/icons/bebebe/ex.svg); + background-position: center center; + background-repeat: no-repeat; + background-color: transparent; + border: 0; + position: absolute; + right: 1em; + transition: background .5s ease; +} +.ui-dialog.ui-dialog-off-canvas .ui-dialog-titlebar-close:hover { + background-image: url(../../../misc/icons/ffffff/ex.svg); +} +[dir="rtl"] .ui-dialog.ui-dialog-off-canvas .ui-dialog-titlebar-close { + left: 1em; + right: auto; +} +.ui-dialog.ui-dialog-off-canvas .ui-dialog-title { + margin: 0; + /* Push the text away from the icon. */ + padding-left: 30px; /* LTR */ + padding-right: 0; /* LTR */ + /* Ensure that long titles do not overlap the close button. */ + max-width: 210px; + font-size: 16px; + font-family: "Lucida Grande", 'Lucida Sans Unicode', 'liberation sans', sans-serif; + text-align: left; /* LTR */ +} +[dir="rtl"] .ui-dialog.ui-dialog-off-canvas .ui-dialog-title { + float: right; + text-align: right; + padding-left: 0; + padding-right: 30px; +} +.ui-dialog.ui-dialog-off-canvas .ui-dialog-title:before { + background: transparent url(../../../misc/icons/ffffff/pencil.svg) no-repeat scroll center center; + background-size: 100% auto; + content: ''; + display: block; + height: 100%; + position: absolute; + left: 1em; /* LTR */ + top: 0; + width: 20px; +} +[dir="rtl"] .ui-dialog.ui-dialog-off-canvas .ui-dialog-title:before { + left: auto; + right: 1em; +} + +/* Override default styling from jQuery UI. */ +#drupal-off-canvas .ui-state-default, +#drupal-off-canvas .ui-widget-content .ui-state-default, +#drupal-off-canvas .ui-widget-header .ui-state-default { + border: 0; + font-weight: normal; + font-size: 14px; + color: #333; +} +#drupal-off-canvas .ui-widget-content a { + color: #85bef4; +} diff --git a/core/modules/settings_tray/css/settings_tray.module.css b/core/modules/settings_tray/css/settings_tray.module.css new file mode 100644 index 00000000..05b5bee4 --- /dev/null +++ b/core/modules/settings_tray/css/settings_tray.module.css @@ -0,0 +1,23 @@ +/** + * @file + * Styling for Settings Tray module. + */ +/* + * Position the edit toolbar tab. + * @todo Move changes into contextual module when Settings Tray is not + * experimental: https://www.drupal.org/node/2784591. + */ +.toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab { + float: left; +} +[dir="rtl"] .toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab { + float: right; +} + +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode a, +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode input { + pointer-events: none; +} +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode .contextual-links a { + pointer-events: inherit; +} diff --git a/core/modules/settings_tray/css/settings_tray.motion.css b/core/modules/settings_tray/css/settings_tray.motion.css new file mode 100644 index 00000000..03639cb1 --- /dev/null +++ b/core/modules/settings_tray/css/settings_tray.motion.css @@ -0,0 +1,19 @@ +/** + * @file + * Motion effects for Settings Tray module. + * + * Motion effects are in a separate file so that they can be easily turned off + * to improve performance if desired. + */ + +/* Transition the edit icon in the toolbar. */ +#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { + transition: all .7s ease; +} + +/* Transition the editables on the page, their contextual links and their hover states. */ +.dialog-off-canvas__main-canvas .contextual, +.dialog-off-canvas__main-canvas .js-settings-tray-edit-mode .settings-tray-editable, +.dialog-off-canvas__main-canvas.js-tray-open .js-settings-tray-edit-mode .settings-tray-editable { + transition: all .7s ease; +} diff --git a/core/modules/settings_tray/css/settings_tray.theme.css b/core/modules/settings_tray/css/settings_tray.theme.css new file mode 100644 index 00000000..9c40c74d --- /dev/null +++ b/core/modules/settings_tray/css/settings_tray.theme.css @@ -0,0 +1,70 @@ +/** + * @file + * Visual styling for Settings Tray module. + */ + +/* @todo remove the @imports when we find a better way to load these styles last. + * https://www.drupal.org/node/1945262. + */ + +/* Style the edit mode toolbar and tabs. */ +#toolbar-bar.js-settings-tray-edit-mode { + background-image: linear-gradient(to bottom,#0c97ed,#1f86c7); +} +.js-settings-tray-edit-mode .toolbar-item:not(.toolbar-icon-edit) { + color: #999; +} +.js-settings-tray-edit-mode .toolbar-item:not(.toolbar-icon-edit) .is-active { + color: #333; +} + +/* Style both the edit and editing states of the contextual links toggle tab. */ +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item, +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active, +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:focus { + background-color: #50a0e9; + background-image: linear-gradient(to bottom, #007bc6, #0071b8); + color: #ddd; + text-shadow: none; + font-weight: bold; + outline: none; +} +/* Make the hover of the inactive state the same as the active state. */ +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:hover, +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active { + background-image: linear-gradient(to bottom, #0c97ed, #1f86c7); + color: #fff; +} +/* Make the hover of the active state the same as the inactive state. */ +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:hover { + background-color: #2369a6; + background-image: linear-gradient(to bottom, #007bc6, #0071b8); + color: #fff; +} +/* Make the inactive icon grey. */ +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:before { + background-image: url(../../../misc/icons/bebebe/pencil.svg); +} +/* Make the active icon white. */ +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:before { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:hover:before { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} +.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:hover > .toolbar-icon-edit:before { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} +.toolbar-tab > .button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} + +/* Style the editables while in edit mode. */ +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode .settings-tray-editable { + outline: 1px dashed rgba(0,0,0,0.5); + box-shadow: 0 0 0 1px rgba(255,255,255,0.7); +} +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode .settings-tray-editable:hover, +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode .settings-tray-editable.settings-tray-active-editable { + background-color: rgba(0,0,0,0.2); +} diff --git a/core/modules/settings_tray/css/settings_tray.toolbar.css b/core/modules/settings_tray/css/settings_tray.toolbar.css new file mode 100644 index 00000000..8a2278c2 --- /dev/null +++ b/core/modules/settings_tray/css/settings_tray.toolbar.css @@ -0,0 +1,67 @@ +/** + * @file + * Visual styling for the toolbar when Settings Tray module is enabled. + */ + +/* @todo Move this into toolbar when module is not experimental: + * https://www.drupal.org/node/2784593. + */ + +/* Style the edit mode toolbar and tabs. */ +#toolbar-bar.js-settings-tray-edit-mode { + background-color: #fff; +} +#toolbar-bar.js-settings-tray-edit-mode .toolbar-item { + color: #999; +} +#toolbar-bar.js-settings-tray-edit-mode .toolbar-item .is-active { + color: #333; +} + +/* Style both the edit and editing states of the contextual links toggle tab. */ +.toolbar-icon-edit.toolbar-item { + background-color: #50a0e9; + background-image: linear-gradient(to bottom, #007bc6, #0071b8); + color: #eee; + text-shadow: 0 1px hsla(0, 0%, 0%, 0.5); + font-weight: 700; + -webkit-font-smoothing: antialiased; +} +.toolbar-icon-edit.toolbar-item.is-active { + background-color: #50a0e9; + background-image: linear-gradient(to bottom, #007bc6, #0071b8); + color: #eee; + text-shadow: 0 1px hsla(0, 0%, 0%, 0.5); + font-weight: 700; + -webkit-font-smoothing: antialiased; +} +.toolbar-tab:hover > .toolbar-icon-edit, +.toolbar-icon-edit:focus .toolbar-item { + background-color: #2369a6; + background-image: linear-gradient(to bottom, #0c97ed, #1f86c7); + border-color: #1e5c90; + color: #fff; + outline: none; +} +.toolbar-icon.toolbar-icon-edit.toolbar-item:before, +button.toolbar-icon.toolbar-icon-edit.toolbar-item:before { + background-image: url(../../../misc/icons/bebebe/pencil.svg); +} +.toolbar-icon.toolbar-icon-edit.toolbar-item:before:hover, +button.toolbar-icon.toolbar-icon-edit.toolbar-item:before:focus { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} +.toolbar-icon.toolbar-icon-edit.toolbar-item:hover > .toolbar-icon-edit:before { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} +#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { + background-image: url(../../../misc/icons/ffffff/pencil.svg); +} + +#toolbar-bar.js-settings-tray-edit-mode button.toolbar-icon.toolbar-icon-edit.toolbar-item.is-active { + background-image: none; + color: #fff; +} +#toolbar-bar.js-settings-tray-edit-mode button.toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:hover { + background-image: linear-gradient(to bottom, #0094f0, #0e69be); +} diff --git a/core/modules/settings_tray/js/off-canvas.es6.js b/core/modules/settings_tray/js/off-canvas.es6.js new file mode 100644 index 00000000..1cb740c3 --- /dev/null +++ b/core/modules/settings_tray/js/off-canvas.es6.js @@ -0,0 +1,270 @@ +/** + * @file + * Drupal's off-canvas library. + * + * @todo This functionality should extracted into a new core library or a part + * of the current drupal.dialog.ajax library. + * https://www.drupal.org/node/2784443 + * + * @private + */ + +(($, Drupal, debounce, displace) => { + /** + * Off-canvas dialog implementation using jQuery Dialog. + * + * Transforms the regular dialogs created using Drupal.dialog when the dialog + * element equals '#drupal-off-canvas' into an side-loading dialog. + * + * @namespace + */ + Drupal.offCanvas = { + + /** + * The minimum width to use body displace needs to match the width at which + * the tray will be %100 width. @see settings_tray.module.css + * @type {Number} + */ + minDisplaceWidth: 768, + + /** + * Wrapper used to position off-canvas dialog. + * @type {jQuery} + */ + $mainCanvasWrapper: $('[data-off-canvas-main-canvas]'), + + /** + * Determines if an element is an off-canvas dialog. + * + * @param {jQuery} $element + * The dialog element. + * @return {bool} + * True this is currently an off-canvas dialog. + */ + isOffCanvas($element) { + return $element.is('#drupal-off-canvas'); + }, + + /** + * Remove off-canvas dialog events. + * + * @param {jQuery} $element + * The target element. + */ + removeOffCanvasEvents($element) { + $element.off('.off-canvas'); + $(document).off('.off-canvas'); + $(window).off('.off-canvas'); + }, + + /** + * Handler fired before an off-canvas dialog has been opened. + * @param {Object} settings + * Settings related to the composition of the dialog. + * @return {undefined} + */ + beforeCreate({ settings, $element }) { + // Clean up previous dialog event handlers. + Drupal.offCanvas.removeOffCanvasEvents($element); + + $('body').addClass('js-tray-open'); + settings.dialogClass += ' ui-dialog-off-canvas'; + // @see http://api.jqueryui.com/position/ + settings.position = { + my: 'left top', + at: `${Drupal.offCanvas.getEdge()} top`, + of: window, + }; + + /** + * Applies initial height to dialog based on window height. + * @see http://api.jqueryui.com/dialog for all dialog options. + */ + settings.height = $(window).height(); + }, + + /** + * Handler fired after an off-canvas dialog has been closed. + * @return {undefined} + */ + beforeClose({ $element }) { + $('body').removeClass('js-tray-open'); + // Remove all *.off-canvas events + Drupal.offCanvas.removeOffCanvasEvents($element); + + Drupal.offCanvas.$mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`, 0); + }, + + /** + * Handler fired when an off-canvas dialog has been opened. + * @param {jQuery} $element + * The off-canvas dialog element. + * @param {Object} settings + * Settings related to the composition of the dialog. + * @return {undefined} + */ + afterCreate({ $element, settings }) { + const eventData = { settings, $element, offCanvasDialog: this }; + + $element + .on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.handleDialogResize) + .on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.bodyPadding); + + Drupal.offCanvas.getContainer($element).attr(`data-offset-${Drupal.offCanvas.getEdge()}`, ''); + + $(window) + .on('resize.off-canvas', eventData, debounce(Drupal.offCanvas.resetSize, 100)) + .trigger('resize.off-canvas'); + }, + + /** + * Toggle classes based on title existence. + * Called with Drupal.offCanvas.afterCreate. + * @param {Object} settings + * Settings related to the composition of the dialog. + * @return {undefined} + */ + render({ settings }) { + $('.ui-dialog-off-canvas, .ui-dialog-off-canvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title); + }, + + /** + * Adjusts the dialog on resize. + * + * @param {jQuery.Event} event + * The event triggered. + * @param {object} event.data + * Data attached to the event. + */ + handleDialogResize(event) { + const $element = event.data.$element; + const $container = Drupal.offCanvas.getContainer($element); + + const $offsets = $container.find('> :not(#drupal-off-canvas, .ui-resizable-handle)'); + let offset = 0; + + // Let scroll element take all the height available. + $element.css({ height: 'auto' }); + const modalHeight = $container.height(); + + $offsets.each((i, e) => { + offset += $(e).outerHeight(); + }); + + // Take internal padding into account. + const scrollOffset = $element.outerHeight() - $element.height(); + $element.height(modalHeight - offset - scrollOffset); + }, + + /** + * Resets the size of the dialog. + * + * @param {jQuery.Event} event + * The event triggered. + * @param {object} event.data + * Data attached to the event. + */ + resetSize(event) { + const offsets = displace.offsets; + const $element = event.data.$element; + const container = Drupal.offCanvas.getContainer($element); + + const topPosition = (offsets.top !== 0 ? `+${offsets.top}` : ''); + const adjustedOptions = { + // @see http://api.jqueryui.com/position/ + position: { + my: `${Drupal.offCanvas.getEdge()} top`, + at: `${Drupal.offCanvas.getEdge()} top${topPosition}`, + of: window, + }, + }; + + container.css({ + position: 'fixed', + height: `${$(window).height() - (offsets.top + offsets.bottom)}px`, + }); + + $element + .dialog('option', adjustedOptions) + .trigger('dialogContentResize.off-canvas'); + }, + + /** + * Adjusts the body padding when the dialog is resized. + * + * @param {jQuery.Event} event + * The event triggered. + * @param {object} event.data + * Data attached to the event. + */ + bodyPadding(event) { + if ($('body').outerWidth() < Drupal.offCanvas.minDisplaceWidth) { + return; + } + const $element = event.data.$element; + const $container = Drupal.offCanvas.getContainer($element); + const $mainCanvasWrapper = Drupal.offCanvas.$mainCanvasWrapper; + + const width = $container.outerWidth(); + const mainCanvasPadding = $mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`); + if (width !== mainCanvasPadding) { + $mainCanvasWrapper.css(`padding-${Drupal.offCanvas.getEdge()}`, `${width}px`); + $container.attr(`data-offset-${Drupal.offCanvas.getEdge()}`, width); + displace(); + } + }, + + /** + * The HTML element that surrounds the dialog. + * @param {HTMLElement} $element + * The dialog element. + * + * @return {HTMLElement} + * The containing element. + */ + getContainer($element) { + return $element.dialog('widget'); + }, + + /** + * The edge of the screen that the dialog should appear on. + * + * @return {string} + * The edge the tray will be shown on, left or right. + */ + getEdge() { + return document.documentElement.dir === 'rtl' ? 'left' : 'right'; + }, + }; + + /** + * Attaches off-canvas dialog behaviors. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches event listeners for off-canvas dialogs. + */ + Drupal.behaviors.offCanvasEvents = { + attach: () => { + $(window).once('off-canvas').on({ + 'dialog:beforecreate': (event, dialog, $element, settings) => { + if (Drupal.offCanvas.isOffCanvas($element)) { + Drupal.offCanvas.beforeCreate({ dialog, $element, settings }); + } + }, + 'dialog:aftercreate': (event, dialog, $element, settings) => { + if (Drupal.offCanvas.isOffCanvas($element)) { + Drupal.offCanvas.render({ dialog, $element, settings }); + Drupal.offCanvas.afterCreate({ $element, settings }); + } + }, + 'dialog:beforeclose': (event, dialog, $element) => { + if (Drupal.offCanvas.isOffCanvas($element)) { + Drupal.offCanvas.beforeClose({ dialog, $element }); + } + }, + }); + }, + }; +})(jQuery, Drupal, Drupal.debounce, Drupal.displace); diff --git a/core/modules/settings_tray/js/off-canvas.js b/core/modules/settings_tray/js/off-canvas.js new file mode 100644 index 00000000..800fd8eb --- /dev/null +++ b/core/modules/settings_tray/js/off-canvas.js @@ -0,0 +1,149 @@ +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ + +(function ($, Drupal, debounce, displace) { + Drupal.offCanvas = { + minDisplaceWidth: 768, + + $mainCanvasWrapper: $('[data-off-canvas-main-canvas]'), + + isOffCanvas: function isOffCanvas($element) { + return $element.is('#drupal-off-canvas'); + }, + removeOffCanvasEvents: function removeOffCanvasEvents($element) { + $element.off('.off-canvas'); + $(document).off('.off-canvas'); + $(window).off('.off-canvas'); + }, + beforeCreate: function beforeCreate(_ref) { + var settings = _ref.settings, + $element = _ref.$element; + + Drupal.offCanvas.removeOffCanvasEvents($element); + + $('body').addClass('js-tray-open'); + settings.dialogClass += ' ui-dialog-off-canvas'; + + settings.position = { + my: 'left top', + at: Drupal.offCanvas.getEdge() + ' top', + of: window + }; + + settings.height = $(window).height(); + }, + beforeClose: function beforeClose(_ref2) { + var $element = _ref2.$element; + + $('body').removeClass('js-tray-open'); + + Drupal.offCanvas.removeOffCanvasEvents($element); + + Drupal.offCanvas.$mainCanvasWrapper.css('padding-' + Drupal.offCanvas.getEdge(), 0); + }, + afterCreate: function afterCreate(_ref3) { + var $element = _ref3.$element, + settings = _ref3.settings; + + var eventData = { settings: settings, $element: $element, offCanvasDialog: this }; + + $element.on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.handleDialogResize).on('dialogContentResize.off-canvas', eventData, Drupal.offCanvas.bodyPadding); + + Drupal.offCanvas.getContainer($element).attr('data-offset-' + Drupal.offCanvas.getEdge(), ''); + + $(window).on('resize.off-canvas', eventData, debounce(Drupal.offCanvas.resetSize, 100)).trigger('resize.off-canvas'); + }, + render: function render(_ref4) { + var settings = _ref4.settings; + + $('.ui-dialog-off-canvas, .ui-dialog-off-canvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title); + }, + handleDialogResize: function handleDialogResize(event) { + var $element = event.data.$element; + var $container = Drupal.offCanvas.getContainer($element); + + var $offsets = $container.find('> :not(#drupal-off-canvas, .ui-resizable-handle)'); + var offset = 0; + + $element.css({ height: 'auto' }); + var modalHeight = $container.height(); + + $offsets.each(function (i, e) { + offset += $(e).outerHeight(); + }); + + var scrollOffset = $element.outerHeight() - $element.height(); + $element.height(modalHeight - offset - scrollOffset); + }, + resetSize: function resetSize(event) { + var offsets = displace.offsets; + var $element = event.data.$element; + var container = Drupal.offCanvas.getContainer($element); + + var topPosition = offsets.top !== 0 ? '+' + offsets.top : ''; + var adjustedOptions = { + position: { + my: Drupal.offCanvas.getEdge() + ' top', + at: Drupal.offCanvas.getEdge() + ' top' + topPosition, + of: window + } + }; + + container.css({ + position: 'fixed', + height: $(window).height() - (offsets.top + offsets.bottom) + 'px' + }); + + $element.dialog('option', adjustedOptions).trigger('dialogContentResize.off-canvas'); + }, + bodyPadding: function bodyPadding(event) { + if ($('body').outerWidth() < Drupal.offCanvas.minDisplaceWidth) { + return; + } + var $element = event.data.$element; + var $container = Drupal.offCanvas.getContainer($element); + var $mainCanvasWrapper = Drupal.offCanvas.$mainCanvasWrapper; + + var width = $container.outerWidth(); + var mainCanvasPadding = $mainCanvasWrapper.css('padding-' + Drupal.offCanvas.getEdge()); + if (width !== mainCanvasPadding) { + $mainCanvasWrapper.css('padding-' + Drupal.offCanvas.getEdge(), width + 'px'); + $container.attr('data-offset-' + Drupal.offCanvas.getEdge(), width); + displace(); + } + }, + getContainer: function getContainer($element) { + return $element.dialog('widget'); + }, + getEdge: function getEdge() { + return document.documentElement.dir === 'rtl' ? 'left' : 'right'; + } + }; + + Drupal.behaviors.offCanvasEvents = { + attach: function attach() { + $(window).once('off-canvas').on({ + 'dialog:beforecreate': function dialogBeforecreate(event, dialog, $element, settings) { + if (Drupal.offCanvas.isOffCanvas($element)) { + Drupal.offCanvas.beforeCreate({ dialog: dialog, $element: $element, settings: settings }); + } + }, + 'dialog:aftercreate': function dialogAftercreate(event, dialog, $element, settings) { + if (Drupal.offCanvas.isOffCanvas($element)) { + Drupal.offCanvas.render({ dialog: dialog, $element: $element, settings: settings }); + Drupal.offCanvas.afterCreate({ $element: $element, settings: settings }); + } + }, + 'dialog:beforeclose': function dialogBeforeclose(event, dialog, $element) { + if (Drupal.offCanvas.isOffCanvas($element)) { + Drupal.offCanvas.beforeClose({ dialog: dialog, $element: $element }); + } + } + }); + } + }; +})(jQuery, Drupal, Drupal.debounce, Drupal.displace); \ No newline at end of file diff --git a/core/modules/settings_tray/js/settings_tray.es6.js b/core/modules/settings_tray/js/settings_tray.es6.js new file mode 100644 index 00000000..b4edd840 --- /dev/null +++ b/core/modules/settings_tray/js/settings_tray.es6.js @@ -0,0 +1,250 @@ +/** + * @file + * Drupal's Settings Tray library. + * + * @private + */ + +(function ($, Drupal) { + const blockConfigureSelector = '[data-settings-tray-edit]'; + const toggleEditSelector = '[data-drupal-settingstray="toggle"]'; + const itemsToToggleSelector = '[data-off-canvas-main-canvas], #toolbar-bar, [data-drupal-settingstray="editable"] a, [data-drupal-settingstray="editable"] button'; + const contextualItemsSelector = '[data-contextual-id] a, [data-contextual-id] button'; + const quickEditItemSelector = '[data-quickedit-entity-id]'; + + /** + * Prevent default click events except contextual links. + * + * In edit mode the default action of click events is suppressed. + * + * @param {jQuery.Event} event + * The click event. + */ + function preventClick(event) { + // Do not prevent contextual links. + if ($(event.target).closest('.contextual-links').length) { + return; + } + event.preventDefault(); + } + + /** + * Close any active toolbar tray before entering edit mode. + */ + function closeToolbarTrays() { + $(Drupal.toolbar.models.toolbarModel.get('activeTab')).trigger('click'); + } + + /** + * Disables the QuickEdit module editor if open. + */ + function disableQuickEdit() { + $('.quickedit-toolbar button.action-cancel').trigger('click'); + } + + /** + * Closes/removes off-canvas. + */ + function closeOffCanvas() { + $('.ui-dialog-off-canvas .ui-dialog-titlebar-close').trigger('click'); + } + + /** + * Gets all items that should be toggled with class during edit mode. + * + * @return {jQuery} + * Items that should be toggled. + */ + function getItemsToToggle() { + return $(itemsToToggleSelector).not(contextualItemsSelector); + } + + /** + * Helper to switch edit mode state. + * + * @param {boolean} editMode + * True enable edit mode, false disable edit mode. + */ + function setEditModeState(editMode) { + if (!document.querySelector('[data-off-canvas-main-canvas]')) { + throw new Error('data-off-canvas-main-canvas is missing from settings-tray-page-wrapper.html.twig'); + } + editMode = !!editMode; + const $editButton = $(toggleEditSelector); + let $editables; + // Turn on edit mode. + if (editMode) { + $editButton.text(Drupal.t('Editing')); + closeToolbarTrays(); + + $editables = $('[data-drupal-settingstray="editable"]').once('settingstray'); + if ($editables.length) { + // Use event capture to prevent clicks on links. + document.querySelector('[data-off-canvas-main-canvas]').addEventListener('click', preventClick, true); + + // When a click occurs try and find the settings-tray edit link + // and click it. + $editables + .not(contextualItemsSelector) + .on('click.settingstray', (e) => { + // Contextual links are allowed to function in Edit mode. + if ($(e.target).closest('.contextual').length || !localStorage.getItem('Drupal.contextualToolbar.isViewing')) { + return; + } + $(e.currentTarget).find(blockConfigureSelector).trigger('click'); + disableQuickEdit(); + }); + $(quickEditItemSelector) + .not(contextualItemsSelector) + .on('click.settingstray', (e) => { + /** + * For all non-contextual links or the contextual QuickEdit link + * close the off-canvas dialog. + */ + if (!$(e.target).parent().hasClass('contextual') || $(e.target).parent().hasClass('quickedit')) { + closeOffCanvas(); + } + // Do not trigger if target is quick edit link to avoid loop. + if ($(e.target).parent().hasClass('contextual') || $(e.target).parent().hasClass('quickedit')) { + return; + } + $(e.currentTarget).find('li.quickedit a').trigger('click'); + }); + } + } + // Disable edit mode. + else { + $editables = $('[data-drupal-settingstray="editable"]').removeOnce('settingstray'); + if ($editables.length) { + document.querySelector('[data-off-canvas-main-canvas]').removeEventListener('click', preventClick, true); + $editables.off('.settingstray'); + $(quickEditItemSelector).off('.settingstray'); + } + + $editButton.text(Drupal.t('Edit')); + closeOffCanvas(); + disableQuickEdit(); + } + getItemsToToggle().toggleClass('js-settings-tray-edit-mode', editMode); + $('.edit-mode-inactive').toggleClass('visually-hidden', editMode); + } + + /** + * Helper to check the state of the settings-tray mode. + * + * @todo don't use a class for this. + * + * @return {boolean} + * State of the settings-tray edit mode. + */ + function isInEditMode() { + return $('#toolbar-bar').hasClass('js-settings-tray-edit-mode'); + } + + /** + * Helper to toggle Edit mode. + */ + function toggleEditMode() { + setEditModeState(!isInEditMode()); + } + + /** + * Reacts to contextual links being added. + * + * @param {jQuery.Event} event + * The `drupalContextualLinkAdded` event. + * @param {object} data + * An object containing the data relevant to the event. + * + * @listens event:drupalContextualLinkAdded + */ + $(document).on('drupalContextualLinkAdded', (event, data) => { + + // When the first contextual link is added to the page set Edit Mode. + $('body').once('settings_tray.edit_mode_init').each(() => { + const editMode = localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false'; + if (editMode) { + setEditModeState(true); + } + }); + + /** + * Bind Ajax behaviors to all items showing the class. + * @todo Fix contextual links to work with use-ajax links in + * https://www.drupal.org/node/2764931. + */ + Drupal.attachBehaviors(data.$el[0]); + /** + * Bind a listener to all 'Quick edit' links for blocks. Click "Edit" button + * in toolbar to force Contextual Edit which starts Settings Tray edit + * mode also. + */ + data.$el.find(blockConfigureSelector) + .on('click.settingstray', () => { + if (!isInEditMode()) { + $(toggleEditSelector).trigger('click').trigger('click.settings_tray'); + } + /** + * Always disable QuickEdit regardless of whether "EditMode" was just + * enabled. + */ + disableQuickEdit(); + }); + }); + + $(document).on('keyup.settingstray', (e) => { + if (isInEditMode() && e.keyCode === 27) { + Drupal.announce( + Drupal.t('Exited edit mode.'), + ); + toggleEditMode(); + } + }); + + /** + * Toggle the js-settings-tray-edit-mode class on items that we want to disable while in edit mode. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Toggle the js-settings-tray-edit-mode class. + */ + Drupal.behaviors.toggleEditMode = { + attach() { + $(toggleEditSelector).once('settingstray').on('click.settingstray', toggleEditMode); + // Find all Ajax instances that use the 'off_canvas' renderer. + Drupal.ajax.instances + // If there is an element and the renderer is 'off_canvas' then we want + // to add our changes. + .filter(instance => instance && $(instance.element).attr('data-dialog-renderer') === 'off_canvas') + // Loop through all Ajax instances that use the 'off_canvas' renderer to + // set active editable ID. + .forEach((instance) => { + // Check to make sure existing dialogOptions aren't overridden. + if (!('dialogOptions' in instance.options.data)) { + instance.options.data.dialogOptions = {}; + } + instance.options.data.dialogOptions.settingsTrayActiveEditableId = $(instance.element).parents('.settings-tray-editable').attr('id'); + instance.progress = { type: 'fullscreen' }; + }); + }, + }; + + // Manage Active editable class on opening and closing of the dialog. + $(window).on({ + 'dialog:beforecreate': (event, dialog, $element, settings) => { + if ($element.is('#drupal-off-canvas')) { + $('body .settings-tray-active-editable').removeClass('settings-tray-active-editable'); + const $activeElement = $(`#${settings.settingsTrayActiveEditableId}`); + if ($activeElement.length) { + $activeElement.addClass('settings-tray-active-editable'); + } + } + }, + 'dialog:beforeclose': (event, dialog, $element) => { + if ($element.is('#drupal-off-canvas')) { + $('body .settings-tray-active-editable').removeClass('settings-tray-active-editable'); + } + }, + }); +}(jQuery, Drupal)); diff --git a/core/modules/settings_tray/js/settings_tray.js b/core/modules/settings_tray/js/settings_tray.js new file mode 100644 index 00000000..88cbb0eb --- /dev/null +++ b/core/modules/settings_tray/js/settings_tray.js @@ -0,0 +1,154 @@ +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ + +(function ($, Drupal) { + var blockConfigureSelector = '[data-settings-tray-edit]'; + var toggleEditSelector = '[data-drupal-settingstray="toggle"]'; + var itemsToToggleSelector = '[data-off-canvas-main-canvas], #toolbar-bar, [data-drupal-settingstray="editable"] a, [data-drupal-settingstray="editable"] button'; + var contextualItemsSelector = '[data-contextual-id] a, [data-contextual-id] button'; + var quickEditItemSelector = '[data-quickedit-entity-id]'; + + function preventClick(event) { + if ($(event.target).closest('.contextual-links').length) { + return; + } + event.preventDefault(); + } + + function closeToolbarTrays() { + $(Drupal.toolbar.models.toolbarModel.get('activeTab')).trigger('click'); + } + + function disableQuickEdit() { + $('.quickedit-toolbar button.action-cancel').trigger('click'); + } + + function closeOffCanvas() { + $('.ui-dialog-off-canvas .ui-dialog-titlebar-close').trigger('click'); + } + + function getItemsToToggle() { + return $(itemsToToggleSelector).not(contextualItemsSelector); + } + + function setEditModeState(editMode) { + if (!document.querySelector('[data-off-canvas-main-canvas]')) { + throw new Error('data-off-canvas-main-canvas is missing from settings-tray-page-wrapper.html.twig'); + } + editMode = !!editMode; + var $editButton = $(toggleEditSelector); + var $editables = void 0; + + if (editMode) { + $editButton.text(Drupal.t('Editing')); + closeToolbarTrays(); + + $editables = $('[data-drupal-settingstray="editable"]').once('settingstray'); + if ($editables.length) { + document.querySelector('[data-off-canvas-main-canvas]').addEventListener('click', preventClick, true); + + $editables.not(contextualItemsSelector).on('click.settingstray', function (e) { + if ($(e.target).closest('.contextual').length || !localStorage.getItem('Drupal.contextualToolbar.isViewing')) { + return; + } + $(e.currentTarget).find(blockConfigureSelector).trigger('click'); + disableQuickEdit(); + }); + $(quickEditItemSelector).not(contextualItemsSelector).on('click.settingstray', function (e) { + if (!$(e.target).parent().hasClass('contextual') || $(e.target).parent().hasClass('quickedit')) { + closeOffCanvas(); + } + + if ($(e.target).parent().hasClass('contextual') || $(e.target).parent().hasClass('quickedit')) { + return; + } + $(e.currentTarget).find('li.quickedit a').trigger('click'); + }); + } + } else { + $editables = $('[data-drupal-settingstray="editable"]').removeOnce('settingstray'); + if ($editables.length) { + document.querySelector('[data-off-canvas-main-canvas]').removeEventListener('click', preventClick, true); + $editables.off('.settingstray'); + $(quickEditItemSelector).off('.settingstray'); + } + + $editButton.text(Drupal.t('Edit')); + closeOffCanvas(); + disableQuickEdit(); + } + getItemsToToggle().toggleClass('js-settings-tray-edit-mode', editMode); + $('.edit-mode-inactive').toggleClass('visually-hidden', editMode); + } + + function isInEditMode() { + return $('#toolbar-bar').hasClass('js-settings-tray-edit-mode'); + } + + function toggleEditMode() { + setEditModeState(!isInEditMode()); + } + + $(document).on('drupalContextualLinkAdded', function (event, data) { + $('body').once('settings_tray.edit_mode_init').each(function () { + var editMode = localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false'; + if (editMode) { + setEditModeState(true); + } + }); + + Drupal.attachBehaviors(data.$el[0]); + + data.$el.find(blockConfigureSelector).on('click.settingstray', function () { + if (!isInEditMode()) { + $(toggleEditSelector).trigger('click').trigger('click.settings_tray'); + } + + disableQuickEdit(); + }); + }); + + $(document).on('keyup.settingstray', function (e) { + if (isInEditMode() && e.keyCode === 27) { + Drupal.announce(Drupal.t('Exited edit mode.')); + toggleEditMode(); + } + }); + + Drupal.behaviors.toggleEditMode = { + attach: function attach() { + $(toggleEditSelector).once('settingstray').on('click.settingstray', toggleEditMode); + + Drupal.ajax.instances.filter(function (instance) { + return instance && $(instance.element).attr('data-dialog-renderer') === 'off_canvas'; + }).forEach(function (instance) { + if (!('dialogOptions' in instance.options.data)) { + instance.options.data.dialogOptions = {}; + } + instance.options.data.dialogOptions.settingsTrayActiveEditableId = $(instance.element).parents('.settings-tray-editable').attr('id'); + instance.progress = { type: 'fullscreen' }; + }); + } + }; + + $(window).on({ + 'dialog:beforecreate': function dialogBeforecreate(event, dialog, $element, settings) { + if ($element.is('#drupal-off-canvas')) { + $('body .settings-tray-active-editable').removeClass('settings-tray-active-editable'); + var $activeElement = $('#' + settings.settingsTrayActiveEditableId); + if ($activeElement.length) { + $activeElement.addClass('settings-tray-active-editable'); + } + } + }, + 'dialog:beforeclose': function dialogBeforeclose(event, dialog, $element) { + if ($element.is('#drupal-off-canvas')) { + $('body .settings-tray-active-editable').removeClass('settings-tray-active-editable'); + } + } + }); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/settings_tray/settings_tray.api.php b/core/modules/settings_tray/settings_tray.api.php new file mode 100644 index 00000000..05297f0d --- /dev/null +++ b/core/modules/settings_tray/settings_tray.api.php @@ -0,0 +1,61 @@ +deleteAll(); +} diff --git a/core/modules/settings_tray/settings_tray.libraries.yml b/core/modules/settings_tray/settings_tray.libraries.yml new file mode 100644 index 00000000..672800d4 --- /dev/null +++ b/core/modules/settings_tray/settings_tray.libraries.yml @@ -0,0 +1,45 @@ +drupal.settings_tray: + version: VERSION + js: + js/settings_tray.js: {} + css: + component: + css/settings_tray.module.css: {} + css/settings_tray.motion.css: {} + css/settings_tray.toolbar.css: {} + theme: + # @todo Set the group higher than CSS_AGGREGATE_THEME so that it overrides + # both jQuery UI and Classy's dialog.css, remove in + # https://www.drupal.org/node/1945262. + css/settings_tray.theme.css: { group: 200 } + dependencies: + - core/jquery + - core/drupal + - core/jquery.once + - core/drupal.ajax +drupal.off_canvas: + version: VERSION + js: + js/off-canvas.js: {} + css: + base: + css/off-canvas.reset.css: {} + css/off-canvas.base.css: {} + css/off-canvas.css: {} + css/off-canvas.theme.css: { group: 200 } + component: + css/off-canvas.motion.css: {} + css/off-canvas.button.css: {} + css/off-canvas.form.css: {} + css/off-canvas.table.css: {} + css/off-canvas.details.css: {} + css/off-canvas.tabledrag.css: {} + css/off-canvas.dropbutton.css: {} + + dependencies: + - core/jquery + - core/drupal + - core/drupal.ajax + - core/drupal.announce + - core/drupal.dialog + - core/drupal.dialog.ajax diff --git a/core/modules/settings_tray/settings_tray.links.contextual.yml b/core/modules/settings_tray/settings_tray.links.contextual.yml new file mode 100644 index 00000000..5534ab27 --- /dev/null +++ b/core/modules/settings_tray/settings_tray.links.contextual.yml @@ -0,0 +1,10 @@ +settings_tray.block_configure: + title: 'Quick edit' + route_name: 'entity.block.off_canvas_form' + group: 'block' + options: + attributes: + class: ['use-ajax'] + data-dialog-type: dialog + data-dialog-renderer: off_canvas + data-settings-tray-edit: true diff --git a/core/modules/settings_tray/settings_tray.module b/core/modules/settings_tray/settings_tray.module new file mode 100644 index 00000000..70174394 --- /dev/null +++ b/core/modules/settings_tray/settings_tray.module @@ -0,0 +1,212 @@ +' . t('About') . ''; + $output .= '

    ' . t('The Settings Tray module provides an \'edit mode\' in which clicking on a block opens a slide-out tray which allows configuration to be altered without leaving the page.For more information, see the online documentation for the Settings Tray module.', [':settings-tray-documentation' => 'https://www.drupal.org/documentation/modules/settings_tray']) . '

    '; + $output .= '

    ' . t('Uses') . '

    '; + $output .= '
    '; + $output .= '
    ' . t('Editing blocks on the same page in the slide-out tray') . '
    '; + $output .= '
    '; + return ['#markup' => $output]; + } +} + +/** + * Implements hook_contextual_links_view_alter(). + * + * Change Configure Blocks into off_canvas links. + */ +function settings_tray_contextual_links_view_alter(&$element, $items) { + if (isset($element['#links']['settings-trayblock-configure'])) { + // Place settings_tray link first. + $settings_tray_link = $element['#links']['settings-trayblock-configure']; + unset($element['#links']['settings-trayblock-configure']); + $element['#links'] = ['settings-trayblock-configure' => $settings_tray_link] + $element['#links']; + + // If this is content block change title to avoid duplicate "Quick Edit". + if (isset($element['#links']['block-contentblock-edit'])) { + $element['#links']['settings-trayblock-configure']['title'] = t('Quick edit settings'); + } + + $element['#attached']['library'][] = 'settings_tray/drupal.off_canvas'; + } +} + +/** + * Implements hook_block_view_alter(). + */ +function settings_tray_block_view_alter(array &$build) { + // Force a new 'data-contextual-id' attribute on blocks when this module is + // enabled so as not to reuse stale data cached client-side. + // @todo Remove when https://www.drupal.org/node/2773591 is fixed. + $build['#contextual_links']['settings_tray'] = [ + 'route_parameters' => [], + ]; +} + +/** + * Implements hook_element_info_alter(). + */ +function settings_tray_element_info_alter(&$type) { + if (isset($type['page'])) { + $type['page']['#theme_wrappers']['settings_tray_page_wrapper'] = ['#weight' => -1000]; + } +} + +/** + * Implements hook_theme(). + */ +function settings_tray_theme() { + return [ + 'settings_tray_page_wrapper' => [ + 'variables' => ['children' => NULL], + ], + ]; +} + +/** + * Implements hook_entity_type_build(). + */ +function settings_tray_entity_type_build(array &$entity_types) { + /* @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */ + $entity_types['block'] + ->setFormClass('off_canvas', BlockEntityOffCanvasForm::class) + ->setLinkTemplate('off_canvas-form', '/admin/structure/block/manage/{block}/off-canvas'); +} + +/** + * Implements hook_preprocess_HOOK() for block templates. + */ +function settings_tray_preprocess_block(&$variables) { + // Only blocks that have an settings_tray form will have a "Quick Edit" link. + // We could wait for the contextual links to be initialized on the client + // side, and then add the class and data- attribute below there (via + // JavaScript). But that would mean that it would be impossible to show + // Settings Tray's clickable regions immediately when the page loads. When + // latency is high, this will cause flicker. + // @see \Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck + /** @var \Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck $access_checker */ + $access_checker = \Drupal::service('access_check.settings_tray.block.settings_tray_form'); + /** @var \Drupal\Core\Block\BlockManagerInterface $block_plugin_manager */ + $block_plugin_manager = \Drupal::service('plugin.manager.block'); + /** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */ + $block_plugin = $block_plugin_manager->createInstance($variables['plugin_id']); + if ($access_checker->accessBlockPlugin($block_plugin)->isAllowed()) { + // Add class and attributes to all blocks to allow Javascript to target. + $variables['attributes']['class'][] = 'settings-tray-editable'; + $variables['attributes']['data-drupal-settingstray'] = 'editable'; + } +} + +/** + * Implements hook_toolbar_alter(). + * + * Alters the 'contextual' toolbar tab if it exists (meaning the user is allowed + * to use contextual links) and if they can administer blocks. + * + * @todo Remove the "administer blocks" requirement in + * https://www.drupal.org/node/2822965. + * + * @see contextual_toolbar() + */ +function settings_tray_toolbar_alter(&$items) { + $items['contextual']['#cache']['contexts'][] = 'user.permissions'; + if (isset($items['contextual']['tab']) && \Drupal::currentUser()->hasPermission('administer blocks')) { + $items['contextual']['#weight'] = -1000; + $items['contextual']['#attached']['library'][] = 'settings_tray/drupal.settings_tray'; + $items['contextual']['tab']['#attributes']['data-drupal-settingstray'] = 'toggle'; + + // Set a class on items to mark whether they should be active in edit mode. + // @todo Create a dynamic method for modules to set their own items. + // https://www.drupal.org/node/2784589. + $edit_mode_items = ['contextual', 'block_place']; + foreach ($items as $key => $item) { + if (!in_array($key, $edit_mode_items) && (!isset($items[$key]['#wrapper_attributes']['class']) || !in_array('hidden', $items[$key]['#wrapper_attributes']['class']))) { + $items[$key]['#wrapper_attributes']['class'][] = 'edit-mode-inactive'; + } + } + } +} + +/** + * Implements hook_block_alter(). + * + * Ensures every block plugin definition has an 'settings_tray' form specified. + * + * @see \Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck + */ +function settings_tray_block_alter(&$definitions) { + foreach ($definitions as &$definition) { + // If a block plugin already defines its own 'settings_tray' form, use that + // form instead of specifying one here. + if (isset($definition['forms']['settings_tray'])) { + continue; + } + + switch ($definition['id']) { + // Use specialized forms for certain blocks that do not yet provide the + // form with their own annotation. + // @todo Move these into the corresponding block plugin annotations in + // https://www.drupal.org/node/2896356. + case 'system_menu_block': + $definition['forms']['settings_tray'] = SystemMenuOffCanvasForm::class; + break; + + case 'system_branding_block': + $definition['forms']['settings_tray'] = SystemBrandingOffCanvasForm::class; + break; + + // No off-canvas form for the page title block, despite it having + // contextual links: it's too confusing that you're editing configuration, + // not content, so the title itself cannot actually be changed. + // @todo Move these into the corresponding block plugin annotations in + // https://www.drupal.org/node/2896356. + case 'page_title_block': + $definition['forms']['settings_tray'] = FALSE; + break; + + case 'system_main_block': + $definition['forms']['settings_tray'] = FALSE; + break; + + case 'help_block': + $definition['forms']['settings_tray'] = FALSE; + break; + + // Otherwise, use the block plugin's normal form rather than + // a custom form for Settings Tray. + default: + $definition['forms']['settings_tray'] = $definition['class']; + break; + } + } +} + +/** + * Implements hook_css_alter(). + */ +function settings_tray_css_alter(&$css, AttachedAssetsInterface $assets) { + // @todo Remove once conditional ordering is introduced in + // https://www.drupal.org/node/1945262. + $path = drupal_get_path('module', 'settings_tray') . '/css/settings_tray.theme.css'; + if (isset($css[$path])) { + // Use 200 to come after CSS_AGGREGATE_THEME. + $css[$path]['group'] = 200; + } +} diff --git a/core/modules/settings_tray/settings_tray.routing.yml b/core/modules/settings_tray/settings_tray.routing.yml new file mode 100644 index 00000000..01109e4c --- /dev/null +++ b/core/modules/settings_tray/settings_tray.routing.yml @@ -0,0 +1,8 @@ +entity.block.off_canvas_form: + path: '/admin/structure/block/manage/{block}/off-canvas' + defaults: + _entity_form: 'block.off_canvas' + _title_callback: '\Drupal\settings_tray\Block\BlockEntityOffCanvasForm::title' + requirements: + _permission: 'administer blocks' + _access_block_plugin_has_settings_tray_form: 'TRUE' diff --git a/core/modules/settings_tray/settings_tray.services.yml b/core/modules/settings_tray/settings_tray.services.yml new file mode 100644 index 00000000..aeaaf57e --- /dev/null +++ b/core/modules/settings_tray/settings_tray.services.yml @@ -0,0 +1,11 @@ +services: + main_content_renderer.off_canvas: + class: Drupal\settings_tray\Render\MainContent\OffCanvasRenderer + arguments: ['@title_resolver', '@renderer'] + tags: + - { name: render.main_content_renderer, format: drupal_dialog.off_canvas } + + access_check.settings_tray.block.settings_tray_form: + class: Drupal\settings_tray\Access\BlockPluginHasSettingsTrayFormAccessCheck + tags: + - { name: access_check, applies_to: _access_block_plugin_has_settings_tray_form } diff --git a/core/modules/settings_tray/src/Access/BlockPluginHasSettingsTrayFormAccessCheck.php b/core/modules/settings_tray/src/Access/BlockPluginHasSettingsTrayFormAccessCheck.php new file mode 100644 index 00000000..01a99a07 --- /dev/null +++ b/core/modules/settings_tray/src/Access/BlockPluginHasSettingsTrayFormAccessCheck.php @@ -0,0 +1,48 @@ +getPlugin(); + return $this->accessBlockPlugin($block_plugin); + } + + /** + * Checks access for accessing a block plugin's 'settings_tray' form. + * + * @param \Drupal\Core\Block\BlockPluginInterface $block_plugin + * The block plugin whose 'settings_tray' form is being accessed. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. + * + * @see settings_tray_preprocess_block() + */ + public function accessBlockPlugin(BlockPluginInterface $block_plugin) { + return AccessResult::allowedIf($block_plugin instanceof PluginWithFormsInterface && $block_plugin->hasFormClass('settings_tray')); + } + +} diff --git a/core/modules/settings_tray/src/Ajax/OpenOffCanvasDialogCommand.php b/core/modules/settings_tray/src/Ajax/OpenOffCanvasDialogCommand.php new file mode 100644 index 00000000..c49c42e0 --- /dev/null +++ b/core/modules/settings_tray/src/Ajax/OpenOffCanvasDialogCommand.php @@ -0,0 +1,73 @@ +dialogOptions['modal'] = FALSE; + $this->dialogOptions['autoResize'] = FALSE; + $this->dialogOptions['resizable'] = 'w'; + $this->dialogOptions['draggable'] = FALSE; + $this->dialogOptions['drupalAutoButtons'] = FALSE; + // @todo drupal.ajax.js does not respect drupalAutoButtons properly, pass an + // empty set of buttons until https://www.drupal.org/node/2793343 is in. + $this->dialogOptions['buttons'] = []; + if (empty($dialog_options['dialogClass'])) { + $this->dialogOptions['dialogClass'] = 'ui-dialog-off-canvas'; + } + // If no width option is provided then use the default width to avoid the + // dialog staying at the width of the previous instance when opened + // more than once, with different widths, on a single page. + if (!isset($this->dialogOptions['width'])) { + $this->dialogOptions['width'] = static::DEFAULT_DIALOG_WIDTH; + } + } + + /** + * {@inheritdoc} + */ + public function render() { + $build = parent::render(); + $build['effect'] = 'fade'; + $build['speed'] = 1000; + return $build; + } + +} diff --git a/core/modules/settings_tray/src/Block/BlockEntityOffCanvasForm.php b/core/modules/settings_tray/src/Block/BlockEntityOffCanvasForm.php new file mode 100644 index 00000000..2c6f80d6 --- /dev/null +++ b/core/modules/settings_tray/src/Block/BlockEntityOffCanvasForm.php @@ -0,0 +1,194 @@ + once + // https://www.drupal.org/node/2359901 is fixed. + return $this->t('Configure @block', ['@block' => $block->getPlugin()->getPluginDefinition()['admin_label']]); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, FormStateInterface $form_state) { + $form = parent::form($form, $form_state); + + // Create link to full block form. + $query = []; + if ($destination = $this->getRequest()->query->get('destination')) { + $query['destination'] = $destination; + } + $form['advanced_link'] = [ + '#type' => 'link', + '#title' => $this->t('Advanced block options'), + '#url' => $this->entity->toUrl('edit-form', ['query' => $query]), + '#weight' => 1000, + ]; + + // Remove the ID and region elements. + unset($form['id'], $form['region'], $form['settings']['admin_label']); + + if (isset($form['settings']['label_display']) && isset($form['settings']['label'])) { + // Only show the label input if the label will be shown on the page. + $form['settings']['label_display']['#weight'] = -100; + $form['settings']['label']['#states']['visible'] = [ + ':input[name="settings[label_display]"]' => ['checked' => TRUE], + ]; + + // Relabel to "Block title" because on the front-end this may be confused + // with page title. + $form['settings']['label']['#title'] = $this->t("Block title"); + $form['settings']['label_display']['#title'] = $this->t("Display block title"); + } + return $form; + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, FormStateInterface $form_state) { + $actions = parent::actions($form, $form_state); + $actions['submit']['#value'] = $this->t('Save @block', ['@block' => $this->entity->getPlugin()->getPluginDefinition()['admin_label']]); + $actions['delete']['#access'] = FALSE; + return $actions; + } + + /** + * {@inheritdoc} + */ + protected function buildVisibilityInterface(array $form, FormStateInterface $form_state) { + // Do not display the visibility. + return []; + } + + /** + * {@inheritdoc} + */ + protected function validateVisibility(array $form, FormStateInterface $form_state) { + // Intentionally empty. + } + + /** + * {@inheritdoc} + */ + protected function submitVisibility(array $form, FormStateInterface $form_state) { + // Intentionally empty. + } + + /** + * {@inheritdoc} + */ + protected function getPluginForm(BlockPluginInterface $block) { + if ($block instanceof PluginWithFormsInterface) { + return $this->pluginFormFactory->createInstance($block, 'settings_tray', 'configure'); + } + return $block; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $form = parent::buildForm($form, $form_state); + $form['actions']['submit']['#ajax'] = [ + 'callback' => '::submitFormDialog', + ]; + $form['#attached']['library'][] = 'core/drupal.dialog.ajax'; + + // static::submitFormDialog() requires data-drupal-selector to be the same + // between the various Ajax requests. A bug in + // \Drupal\Core\Form\FormBuilder prevents that from happening unless + // $form['#id'] is also the same. Normally, #id is set to a unique HTML ID + // via Html::getUniqueId(), but here we bypass that in order to work around + // the data-drupal-selector bug. This is okay so long as we assume that this + // form only ever occurs once on a page. + // @todo Remove this workaround once https://www.drupal.org/node/2897377 is + // fixed. + $form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']); + + return $form; + } + + /** + * Submit form dialog #ajax callback. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * + * @return \Drupal\Core\Ajax\AjaxResponse + * An AJAX response that display validation error messages or redirects + * to a URL + * + * @todo Repalce this callback with generic trait in + * https://www.drupal.org/node/2896535. + */ + public function submitFormDialog(array &$form, FormStateInterface $form_state) { + $response = new AjaxResponse(); + if ($form_state->hasAnyErrors()) { + $form['status_messages'] = [ + '#type' => 'status_messages', + '#weight' => -1000, + ]; + $command = new ReplaceCommand('[data-drupal-selector="' . $form['#attributes']['data-drupal-selector'] . '"]', $form); + } + else { + if ($redirect_url = $this->getRedirectUrl()) { + $command = new RedirectCommand($redirect_url->setAbsolute()->toString()); + } + else { + // Settings Tray always provides a destination. + throw new \Exception("No destination provided by Settings Tray form"); + } + } + return $response->addCommand($command); + } + + /** + * Gets the form's redirect URL from 'destination' provide in the request. + * + * @return \Drupal\Core\Url|null + * The redirect URL or NULL if dialog should just be closed. + */ + protected function getRedirectUrl() { + // \Drupal\Core\Routing\RedirectDestination::get() cannot be used directly + // because it will use if 'destination' is not in the query + // string. + if ($this->getRequest()->query->has('destination') && $destination = $this->getRedirectDestination()->get()) { + return Url::fromUserInput('/' . $destination); + } + } + +} diff --git a/core/modules/outside_in/src/Form/SystemBrandingOffCanvasForm.php b/core/modules/settings_tray/src/Form/SystemBrandingOffCanvasForm.php similarity index 97% rename from core/modules/outside_in/src/Form/SystemBrandingOffCanvasForm.php rename to core/modules/settings_tray/src/Form/SystemBrandingOffCanvasForm.php index 063041d1..0b4290e2 100644 --- a/core/modules/outside_in/src/Form/SystemBrandingOffCanvasForm.php +++ b/core/modules/settings_tray/src/Form/SystemBrandingOffCanvasForm.php @@ -1,6 +1,6 @@ 'details', - '#title' => $this->t('Edit menu %label', array('%label' => $this->entity->label())), + '#title' => $this->t('Edit menu %label', ['%label' => $this->menu->label()]), '#open' => TRUE, ]; - $form['entity_form'] += $this->getEntityForm($this->entity)->buildForm([], $form_state); + $form['entity_form'] += $this->getEntityForm($this->menu)->buildForm([], $form_state); // Print the menu link titles as text instead of a link. if (!empty($form['entity_form']['links']['links'])) { @@ -111,7 +115,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { $this->plugin->validateConfigurationForm($form, $form_state); - $this->getEntityForm($this->entity)->validateForm($form, $form_state); + $this->getEntityForm($this->menu)->validateForm($form, $form_state); } /** @@ -119,22 +123,22 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { $this->plugin->submitConfigurationForm($form, $form_state); - $this->getEntityForm($this->entity)->submitForm($form, $form_state); - $this->entity->save(); + $this->getEntityForm($this->menu)->submitForm($form, $form_state); + $this->menu->save(); } /** * Gets the entity form for this menu. * - * @param \Drupal\system\MenuInterface $entity + * @param \Drupal\system\MenuInterface $menu * The menu entity. * * @return \Drupal\Core\Entity\EntityFormInterface * The entity form. */ - protected function getEntityForm(MenuInterface $entity) { + protected function getEntityForm(MenuInterface $menu) { $entity_form = $this->entityTypeManager->getFormObject('menu', 'edit'); - $entity_form->setEntity($entity); + $entity_form->setEntity($menu); return $entity_form; } @@ -143,7 +147,7 @@ protected function getEntityForm(MenuInterface $entity) { */ public function setPlugin(PluginInspectionInterface $plugin) { $this->plugin = $plugin; - $this->entity = $this->menuStorage->load($this->plugin->getDerivativeId()); + $this->menu = $this->menuStorage->load($this->plugin->getDerivativeId()); } } diff --git a/core/modules/settings_tray/src/Render/MainContent/OffCanvasRenderer.php b/core/modules/settings_tray/src/Render/MainContent/OffCanvasRenderer.php new file mode 100644 index 00000000..83550301 --- /dev/null +++ b/core/modules/settings_tray/src/Render/MainContent/OffCanvasRenderer.php @@ -0,0 +1,63 @@ +renderer = $renderer; + } + + /** + * {@inheritdoc} + */ + public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) { + $response = new AjaxResponse(); + + // First render the main content, because it might provide a title. + $content = $this->renderer->renderRoot($main_content); + // Attach the library necessary for using the OpenOffCanvasDialogCommand and + // set the attachments for this Ajax response. + $main_content['#attached']['library'][] = 'settings_tray/drupal.off_canvas'; + $response->setAttachments($main_content['#attached']); + + // If the main content doesn't provide a title, use the title resolver. + $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject()); + + // Determine the title: use the title provided by the main content if any, + // otherwise get it from the routing information. + $options = $request->request->get('dialogOptions', []); + $response->addCommand(new OpenOffCanvasDialogCommand($title, $content, $options)); + return $response; + } + +} diff --git a/core/modules/settings_tray/templates/settings-tray-page-wrapper.html.twig b/core/modules/settings_tray/templates/settings-tray-page-wrapper.html.twig new file mode 100644 index 00000000..af84f4fa --- /dev/null +++ b/core/modules/settings_tray/templates/settings-tray-page-wrapper.html.twig @@ -0,0 +1,26 @@ +{# +/** + * @file + * Default theme implementation for a page wrapper. + * + * For consistent wrapping to {{ page }} render in all themes. The + * "data-off-canvas-main-canvas" attribute is required by the off-canvas dialog. + * This is used by the settings_tray/drupal.off_canvas library to select the + * "main canvas" page element as opposed to the "off canvas" which is the tray + * itself. The "main canvas" element must be resized according to the width of + * the "off canvas" tray so that no portion of the "main canvas" is obstructed + * by the tray. The tray can vary in width when opened and can be resized by the + * user. The "data-off-canvas-main-canvas" attribute cannot be removed without + * breaking the off-canvas dialog functionality. + * + * Available variables: + * - children: Contains the child elements of the page. + * + * @ingroup themeable + */ +#} +{% if children %} +
    + {{ children }} +
    +{% endif %} diff --git a/core/modules/settings_tray/tests/modules/off_canvas_test/off_canvas_test.info.yml b/core/modules/settings_tray/tests/modules/off_canvas_test/off_canvas_test.info.yml new file mode 100644 index 00000000..efe1d170 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/off_canvas_test/off_canvas_test.info.yml @@ -0,0 +1,15 @@ +name: 'Off-canvas tests' +type: module +description: 'Provides off-canvas test links.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - block + - settings_tray + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/settings_tray/tests/modules/off_canvas_test/off_canvas_test.routing.yml b/core/modules/settings_tray/tests/modules/off_canvas_test/off_canvas_test.routing.yml new file mode 100644 index 00000000..4ae56c4e --- /dev/null +++ b/core/modules/settings_tray/tests/modules/off_canvas_test/off_canvas_test.routing.yml @@ -0,0 +1,29 @@ +off_canvas_test.links: + path: '/off-canvas-test-links' + defaults: + _controller: '\Drupal\off_canvas_test\Controller\TestController::linksDisplay' + _title: 'Links' + requirements: + _access: 'TRUE' + +off_canvas_test.thing1: + path: '/off-canvas-thing1' + defaults: + _controller: '\Drupal\off_canvas_test\Controller\TestController::thing1' + _title: 'Thing 1' + requirements: + _access: 'TRUE' + +off_canvas_test.thing2: + path: '/off-canvas-thing2' + defaults: + _controller: '\Drupal\off_canvas_test\Controller\TestController::thing2' + requirements: + _access: 'TRUE' + +off_canvas_test.dialog_links: + path: '/off-canvas-dialog-links' + defaults: + _controller: '\Drupal\off_canvas_test\Controller\TestController::otherDialogLinks' + requirements: + _access: 'TRUE' diff --git a/core/modules/settings_tray/tests/modules/off_canvas_test/src/Controller/TestController.php b/core/modules/settings_tray/tests/modules/off_canvas_test/src/Controller/TestController.php new file mode 100644 index 00000000..3658bfd6 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/off_canvas_test/src/Controller/TestController.php @@ -0,0 +1,140 @@ + 'markup', + '#markup' => 'Thing 1 says hello', + ]; + } + + /** + * Thing2. + * + * @return string + * Return Hello string. + */ + public function thing2() { + return [ + '#type' => 'markup', + '#markup' => 'Thing 2 says hello', + ]; + } + + /** + * Displays test links that will open in off-canvas dialog. + * + * @return array + * Render array with links. + */ + public function linksDisplay() { + return [ + 'off_canvas_link_1' => [ + '#title' => 'Click Me 1!', + '#type' => 'link', + '#url' => Url::fromRoute('off_canvas_test.thing1'), + '#attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'dialog', + 'data-dialog-renderer' => 'off_canvas', + ], + '#attached' => [ + 'library' => [ + 'settings_tray/drupal.settings_tray', + ], + ], + ], + 'off_canvas_link_2' => [ + '#title' => 'Click Me 2!', + '#type' => 'link', + '#url' => Url::fromRoute('off_canvas_test.thing2'), + '#attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'dialog', + 'data-dialog-renderer' => 'off_canvas', + 'data-dialog-options' => Json::encode([ + 'width' => 555, + ]), + ], + '#attached' => [ + 'library' => [ + 'settings_tray/drupal.settings_tray', + ], + ], + ], + 'other_dialog_links' => [ + '#title' => 'Display more links!', + '#type' => 'link', + '#url' => Url::fromRoute('off_canvas_test.dialog_links'), + '#attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'dialog', + 'data-dialog-renderer' => 'off_canvas', + ], + '#attached' => [ + 'library' => [ + 'settings_tray/drupal.settings_tray', + ], + ], + ], + ]; + } + + /** + * Displays dialogs links to be displayed inside the off-canvas dialog. + * + * This links are used to test opening a modal and another off_canvas link from + * inside the off-canvas dialog. + * + * @todo Update tests to check these links work in the off-canvas dialog. + * https://www.drupal.org/node/2790073 + * + * @return array + * Render array with links. + */ + public function otherDialogLinks() { + return [ + '#theme' => 'links', + '#links' => [ + 'modal_link' => [ + 'title' => 'Open modal!', + 'url' => Url::fromRoute('off_canvas_test.thing2'), + 'attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + ], + ], + 'off_canvas_link' => [ + 'title' => 'Off_canvas link!', + 'url' => Url::fromRoute('off_canvas_test.thing2'), + 'attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'dialog', + 'data-dialog-renderer' => 'off_canvas', + ], + ], + ], + '#attached' => [ + 'library' => [ + 'settings_tray/drupal.settings_tray', + ], + ], + ]; + } + +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test/settings_tray_test.info.yml b/core/modules/settings_tray/tests/modules/settings_tray_test/settings_tray_test.info.yml new file mode 100644 index 00000000..ad88bd4d --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test/settings_tray_test.info.yml @@ -0,0 +1,15 @@ +name: 'Settings Tray Test' +type: module +description: 'Provides Settings Tray test functionality.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - block + - settings_tray + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test/src/Form/SettingsTrayFormAnnotationIsClassBlockForm.php b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Form/SettingsTrayFormAnnotationIsClassBlockForm.php new file mode 100644 index 00000000..f0fae68c --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Form/SettingsTrayFormAnnotationIsClassBlockForm.php @@ -0,0 +1,44 @@ +plugin->buildConfigurationForm($form, $form_state); + + $form['some_setting'] = [ + '#type' => 'select', + '#title' => t('Some setting'), + '#options' => [ + 'a' => 'A', + 'b' => 'B', + ], + '#required' => TRUE, + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {} + +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationIsClassBlock.php b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationIsClassBlock.php new file mode 100644 index 00000000..699a09a5 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationIsClassBlock.php @@ -0,0 +1,27 @@ + 'class']; + } + +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationIsFalseBlock.php b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationIsFalseBlock.php new file mode 100644 index 00000000..47bb6113 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationIsFalseBlock.php @@ -0,0 +1,27 @@ + 'FALSE']; + } + +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationNoneBlock.php b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationNoneBlock.php new file mode 100644 index 00000000..5b6eb923 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/SettingsTrayFormAnnotationNoneBlock.php @@ -0,0 +1,24 @@ + 'none']; + } + +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/ValidationErrorBlock.php b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/ValidationErrorBlock.php new file mode 100644 index 00000000..f54b1a3f --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test/src/Plugin/Block/ValidationErrorBlock.php @@ -0,0 +1,33 @@ + 'If I had more time this would be very witty :(.']; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + parent::validateConfigurationForm($form, $form_state); + $form_state->setError($form['label'], 'Sorry system error. Please save again.'); + } + +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css b/core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css new file mode 100644 index 00000000..071afce2 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test_css/css/css_fix.theme.css @@ -0,0 +1,27 @@ +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode a, +.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode input { + pointer-events: inherit !important; +} +/** + * Remove all transitions for testing. + */ +* { + /* CSS transitions. */ + -o-transition-property: none !important; + -moz-transition-property: none !important; + -ms-transition-property: none !important; + -webkit-transition-property: none !important; + transition-property: none !important; + /* CSS transforms. */ + -o-transform: none !important; + -moz-transform: none !important; + -ms-transform: none !important; + -webkit-transform: none !important; + transform: none !important; + /* CSS animations. */ + -webkit-animation: none !important; + -moz-animation: none !important; + -o-animation: none !important; + -ms-animation: none !important; + animation: none !important; +} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.info.yml b/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.info.yml new file mode 100644 index 00000000..e30ee01e --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.info.yml @@ -0,0 +1,14 @@ +name: 'CSS Test fix' +type: module +description: 'Provides CSS fixes for tests.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: +- settings_tray + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.libraries.yml b/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.libraries.yml similarity index 100% rename from core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.libraries.yml rename to core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.libraries.yml diff --git a/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.module b/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.module new file mode 100644 index 00000000..33753993 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_test_css/settings_tray_test_css.module @@ -0,0 +1,16 @@ +drupalLogin($this->drupalCreateUser(['administer contact forms'])); + // Ensure the elements render without notices or exceptions. + $this->drupalGet('ajax-test/dialog'); + + // Set up variables for this test. + $dialog_renderable = AjaxTestController::dialogContents(); + $dialog_contents = \Drupal::service('renderer')->renderRoot($dialog_renderable); + + $off_canvas_expected_response = [ + 'command' => 'openDialog', + 'selector' => '#drupal-off-canvas', + 'settings' => NULL, + 'data' => $dialog_contents, + 'dialogOptions' => + [ + 'title' => 'AJAX Dialog & contents', + 'modal' => FALSE, + 'autoResize' => FALSE, + 'resizable' => 'w', + 'draggable' => FALSE, + 'drupalAutoButtons' => FALSE, + 'buttons' => [], + 'dialogClass' => 'ui-dialog-off-canvas', + 'width' => 300, + ], + 'effect' => 'fade', + 'speed' => 1000, + ]; + + // Emulate going to the JS version of the page and check the JSON response. + $ajax_result = $this->drupalGet('ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog.off_canvas']]); + $ajax_result = Json::decode($ajax_result); + $this->assertEqual($off_canvas_expected_response, $ajax_result[3], 'off-canvas dialog JSON response matches.'); + } + +} diff --git a/core/modules/settings_tray/tests/src/Functional/SettingsTrayTest.php b/core/modules/settings_tray/tests/src/Functional/SettingsTrayTest.php new file mode 100644 index 00000000..aec0392d --- /dev/null +++ b/core/modules/settings_tray/tests/src/Functional/SettingsTrayTest.php @@ -0,0 +1,109 @@ +id(); + } + + /** + * Tests the 3 possible forms[settings_tray] annotations: class, FALSE, none. + * + * There is also functional JS test coverage to ensure that the two blocks + * that support Settings Tray (the "class" and "none" cases) do work + * correctly. + * + * @see SettingsTrayBlockFormTest::testBlocks() + */ + public function testPossibleAnnotations() { + $test_block_plugin_ids = [ + // Block that explicitly provides an "settings_tray" form class. + 'settings_tray_test_class', + // Block that explicitly provides no "settings_tray" form, thus opting out. + 'settings_tray_test_false', + // Block that does nothing explicit for Settings Tray. + 'settings_tray_test_none', + ]; + + $placed_blocks = []; + foreach ($test_block_plugin_ids as $plugin_id) { + $placed_blocks[$plugin_id] = $this->placeBlock($plugin_id); + } + + $this->drupalGet(''); + $web_assert = $this->assertSession(); + foreach ($placed_blocks as $plugin_id => $placed_block) { + $block_selector = $this->getBlockSelector($placed_block); + + // All blocks are rendered. + $web_assert->elementExists('css', $block_selector); + + // All blocks except 'settings_tray_test_false' are editable. For more + // detailed test coverage, which requires JS execution, see + // \Drupal\Tests\settings_tray\FunctionalJavascript\SettingsTrayBlockFormTest::testBlocks(). + if ($plugin_id === 'settings_tray_test_false') { + $web_assert->elementNotExists('css', "{$block_selector}[data-drupal-settingstray=\"editable\"]"); + } + else { + $web_assert->elementExists('css', "{$block_selector}[data-drupal-settingstray=\"editable\"]"); + } + } + } + + /** + * Tests that certain blocks opt out from Settings Tray. + */ + public function testOptOut() { + $web_assert = $this->assertSession(); + + $non_excluded_block = $this->placeBlock('system_powered_by_block'); + $excluded_block_plugin_ids = ['page_title_block', 'system_main_block', 'settings_tray_test_false']; + $block_selectors = []; + // Place blocks that should be excluded. + foreach ($excluded_block_plugin_ids as $excluded_block_plugin_id) { + // The block HTML 'id' attribute will be "block-[block_id]". + $block_selectors[] = $this->getBlockSelector($this->placeBlock($excluded_block_plugin_id)); + } + $this->drupalGet(''); + // Assert that block has been marked as "editable" and contextual that + // should exist does. + $web_assert->elementExists('css', $this->getBlockSelector($non_excluded_block) . "[data-drupal-settingstray=\"editable\"]"); + // Assert that each block that has a "forms[settings_tray] = FALSE" annotation: + // - is still rendered on the page + // - but is not marked as "editable" by settings_tray_preprocess_block() + // - and does not have the Settings Tray contextual link. + foreach ($block_selectors as $block_selector) { + $web_assert->elementExists('css', $block_selector); + $web_assert->elementNotExists('css', "{$block_selector}[data-drupal-settingstray=\"editable\"]"); + $web_assert->elementNotExists('css', "$block_selector [data-settings-tray-edit]"); + } + } + +} diff --git a/core/modules/settings_tray/tests/src/FunctionalJavascript/OffCanvasTest.php b/core/modules/settings_tray/tests/src/FunctionalJavascript/OffCanvasTest.php new file mode 100644 index 00000000..347eaeae --- /dev/null +++ b/core/modules/settings_tray/tests/src/FunctionalJavascript/OffCanvasTest.php @@ -0,0 +1,123 @@ +getTestThemes() as $theme) { + $this->enableTheme($theme); + $this->drupalGet('/off-canvas-test-links'); + + $page = $this->getSession()->getPage(); + $web_assert = $this->assertSession(); + + // Make sure off-canvas dialog is on page when first loaded. + $web_assert->elementNotExists('css', '#drupal-off-canvas'); + + // Check opening and closing with two separate links. + // Make sure tray updates to new content. + // Check the first link again to make sure the empty title class is + // removed. + foreach (['1', '2', '1'] as $link_index) { + // Click the first test like that should open the page. + $page->clickLink("Click Me $link_index!"); + $this->waitForOffCanvasToOpen(); + + // Check that the canvas is not on the page. + $web_assert->elementExists('css', '#drupal-off-canvas'); + // Check that response text is on page. + $web_assert->pageTextContains("Thing $link_index says hello"); + $off_canvas_tray = $this->getTray(); + + // Check that tray is visible. + $this->assertEquals(TRUE, $off_canvas_tray->isVisible()); + $header_text = $off_canvas_tray->find('css', '.ui-dialog-title')->getText(); + + $tray_text = $off_canvas_tray->findById('drupal-off-canvas')->getText(); + $this->assertEquals("Thing $link_index says hello", $tray_text); + + if ($link_index == '2') { + // Check no title behavior. + $web_assert->elementExists('css', '.ui-dialog-empty-title'); + $this->assertEquals("\xc2\xa0", $header_text); + + $style = $page->find('css', '.ui-dialog-off-canvas')->getAttribute('style'); + $this->assertTrue(strstr($style, 'width: 555px;') !== FALSE, 'Dialog width respected.'); + $page->clickLink("Click Me 1!"); + $this->waitForOffCanvasToOpen(); + $style = $page->find('css', '.ui-dialog-off-canvas')->getAttribute('style'); + $this->assertTrue(strstr($style, 'width: 555px;') === FALSE, 'Dialog width reset to default.'); + } + else { + // Check that header is correct. + $this->assertEquals("Thing $link_index", $header_text); + $web_assert->elementNotExists('css', '.ui-dialog-empty-title'); + } + } + } + } + + /** + * Tests the body displacement behaves differently at a narrow width. + */ + public function testNarrowWidth() { + $narrow_width_breakpoint = 768; + $offset = 20; + $height = 800; + $page = $this->getSession()->getPage(); + $web_assert = $this->assertSession(); + + // Test the same functionality on multiple themes. + foreach ($this->getTestThemes() as $theme) { + $this->enableTheme($theme); + // Testing at the wider width. + $this->getSession()->resizeWindow($narrow_width_breakpoint + $offset, $height); + $this->drupalGet('/off-canvas-test-links'); + $this->assertFalse($page->find('css', '.dialog-off-canvas__main-canvas')->hasAttribute('style'), 'Body not padded on wide page load.'); + $page->clickLink("Click Me 1!"); + $this->waitForOffCanvasToOpen(); + // Check that the main canvas is padded when page is not narrow width and + // tray is open. + $web_assert->elementAttributeContains('css', '.dialog-off-canvas__main-canvas', 'style', 'padding-right'); + + // Testing at the narrower width. + $this->getSession()->resizeWindow($narrow_width_breakpoint - $offset, $height); + $this->drupalGet('/off-canvas-test-links'); + $this->assertFalse($page->find('css', '.dialog-off-canvas__main-canvas')->hasAttribute('style'), 'Body not padded on narrow page load.'); + $page->clickLink("Click Me 1!"); + $this->waitForOffCanvasToOpen(); + $this->assertFalse($page->find('css', '.dialog-off-canvas__main-canvas')->hasAttribute('style'), 'Body not padded on narrow page with tray open.'); + } + } + + /** + * {@inheritdoc} + */ + protected function getTestThemes() { + // Add 'seven' theme. Setting Tray "Edit Mode" will not work with 'seven' + // because it removes all contextual links the off-canvas dialog should. + return array_merge(parent::getTestThemes(), ['seven']); + } + +} diff --git a/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php new file mode 100644 index 00000000..d4d858eb --- /dev/null +++ b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php @@ -0,0 +1,568 @@ +createBlockContentType('basic', TRUE); + $block_content = $this->createBlockContent('Custom Block', 'basic', TRUE); + $user = $this->createUser([ + 'administer blocks', + 'access contextual links', + 'access toolbar', + 'administer nodes', + 'access in-place editing', + 'search content', + ]); + $this->drupalLogin($user); + $this->placeBlock('block_content:' . $block_content->uuid(), ['id' => 'custom']); + } + + /** + * Tests opening off-canvas dialog by click blocks and elements in the blocks. + * + * @dataProvider providerTestBlocks + */ + public function testBlocks($theme, $block_plugin, $new_page_text, $element_selector, $label_selector, $button_text, $toolbar_item) { + $web_assert = $this->assertSession(); + $page = $this->getSession()->getPage(); + $this->enableTheme($theme); + $block = $this->placeBlock($block_plugin); + $block_selector = str_replace('_', '-', $this->getBlockSelector($block)); + $block_id = $block->id(); + $this->drupalGet('user'); + + $link = $page->find('css', "$block_selector .contextual-links li a"); + $this->assertEquals('Quick edit', $link->getText(), "'Quick edit' is the first contextual link for the block."); + $this->assertContains("/admin/structure/block/manage/$block_id/off-canvas?destination=user/2", $link->getAttribute('href')); + + if (isset($toolbar_item)) { + // Check that you can open a toolbar tray and it will be closed after + // entering edit mode. + if ($element = $page->find('css', "#toolbar-administration a.is-active")) { + // If a tray was open from page load close it. + $element->click(); + $this->waitForNoElement("#toolbar-administration a.is-active"); + } + $page->find('css', $toolbar_item)->click(); + $this->assertElementVisibleAfterWait('css', "{$toolbar_item}.is-active"); + } + $this->enableEditMode(); + if (isset($toolbar_item)) { + $this->waitForNoElement("{$toolbar_item}.is-active"); + } + $this->openBlockForm($block_selector); + switch ($block_plugin) { + case 'system_powered_by_block': + // Confirm "Display Title" is not checked. + $web_assert->checkboxNotChecked('settings[label_display]'); + // Confirm Title is not visible. + $this->assertEquals($this->isLabelInputVisible(), FALSE, 'Label is not visible'); + $page->checkField('settings[label_display]'); + $this->assertEquals($this->isLabelInputVisible(), TRUE, 'Label is visible'); + // Fill out form, save the form. + $page->fillField('settings[label]', $new_page_text); + + break; + + case 'system_branding_block': + // Fill out form, save the form. + $page->fillField('settings[site_information][site_name]', $new_page_text); + break; + + case 'settings_tray_test_class': + $web_assert->elementExists('css', '[data-drupal-selector="edit-settings-some-setting"]'); + break; + } + + if (isset($new_page_text)) { + $page->pressButton($button_text); + // Make sure the changes are present. + $new_page_text_locator = "$block_selector $label_selector:contains($new_page_text)"; + $this->assertElementVisibleAfterWait('css', $new_page_text_locator); + // The page is loaded with the new change but make sure page is + // completely loaded. + $this->assertPageLoadComplete(); + } + + $this->openBlockForm($block_selector); + + $this->disableEditMode(); + // Canvas should close when editing module is closed. + $this->waitForOffCanvasToClose(); + + $this->enableEditMode(); + + // Open block form by clicking a element inside the block. + // This confirms that default action for links and form elements is + // suppressed. + $this->openBlockForm("$block_selector {$element_selector}", $block_selector); + $web_assert->elementTextContains('css', '.contextual-toolbar-tab button', 'Editing'); + $web_assert->elementAttributeContains('css', '.dialog-off-canvas__main-canvas', 'class', 'js-settings-tray-edit-mode'); + // Simulate press the Escape key. + $this->getSession()->executeScript('jQuery("body").trigger(jQuery.Event("keyup", { keyCode: 27 }));'); + $this->waitForOffCanvasToClose(); + $this->getSession()->wait(100); + $this->assertEditModeDisabled(); + $web_assert->elementTextContains('css', '#drupal-live-announce', 'Exited edit mode.'); + $web_assert->elementTextNotContains('css', '.contextual-toolbar-tab button', 'Editing'); + $web_assert->elementAttributeNotContains('css', '.dialog-off-canvas__main-canvas', 'class', 'js-settings-tray-edit-mode'); + } + + /** + * Dataprovider for testBlocks(). + */ + public function providerTestBlocks() { + $blocks = []; + foreach ($this->getTestThemes() as $theme) { + $blocks += [ + "$theme: block-powered" => [ + 'theme' => $theme, + 'block_plugin' => 'system_powered_by_block', + 'new_page_text' => 'Can you imagine anyone showing the label on this block', + 'element_selector' => 'span a', + 'label_selector' => 'h2', + 'button_text' => 'Save Powered by Drupal', + 'toolbar_item' => '#toolbar-item-user', + ], + "$theme: block-branding" => [ + 'theme' => $theme, + 'block_plugin' => 'system_branding_block', + 'new_page_text' => 'The site that will live a very short life', + 'element_selector' => "a[rel='home']:last-child", + 'label_selector' => "a[rel='home']:last-child", + 'button_text' => 'Save Site branding', + 'toolbar_item' => '#toolbar-item-administration', + ], + "$theme: block-search" => [ + 'theme' => $theme, + 'block_plugin' => 'search_form_block', + 'new_page_text' => NULL, + 'element_selector' => '#edit-submit', + 'label_selector' => 'h2', + 'button_text' => 'Save Search form', + 'toolbar_item' => NULL, + ], + // This is the functional JS test coverage accompanying + // \Drupal\Tests\settings_tray\Functional\SettingsTrayTest::testPossibleAnnotations(). + "$theme: " . SettingsTrayFormAnnotationIsClassBlock::class => [ + 'theme' => $theme, + 'block_plugin' => 'settings_tray_test_class', + 'new_page_text' => NULL, + 'element_selector' => 'span', + 'label_selector' => NULL, + 'button_text' => NULL, + 'toolbar_item' => NULL, + ], + // This is the functional JS test coverage accompanying + // \Drupal\Tests\settings_tray\Functional\SettingsTrayTest::testPossibleAnnotations(). + "$theme: " . SettingsTrayFormAnnotationNoneBlock::class => [ + 'theme' => $theme, + 'block_plugin' => 'settings_tray_test_none', + 'new_page_text' => NULL, + 'element_selector' => 'span', + 'label_selector' => NULL, + 'button_text' => NULL, + 'toolbar_item' => NULL, + ], + ]; + } + + return $blocks; + } + + /** + * Enables edit mode by pressing edit button in the toolbar. + */ + protected function enableEditMode() { + $this->pressToolbarEditButton(); + $this->assertEditModeEnabled(); + } + + /** + * Disables edit mode by pressing edit button in the toolbar. + */ + protected function disableEditMode() { + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->pressToolbarEditButton(); + $this->assertEditModeDisabled(); + } + + /** + * Asserts that Off-Canvas block form is valid. + */ + protected function assertOffCanvasBlockFormIsValid() { + $web_assert = $this->assertSession(); + // Confirm that Block title display label has been changed. + $web_assert->elementTextContains('css', '.form-item-settings-label-display label', 'Display block title'); + // Confirm Block title label is shown if checkbox is checked. + if ($this->getSession()->getPage()->find('css', 'input[name="settings[label_display]"]')->isChecked()) { + $this->assertEquals($this->isLabelInputVisible(), TRUE, 'Label is visible'); + $web_assert->elementTextContains('css', '.form-item-settings-label label', 'Block title'); + } + else { + $this->assertEquals($this->isLabelInputVisible(), FALSE, 'Label is not visible'); + } + + // Check that common block form elements exist. + $web_assert->elementExists('css', static::LABEL_INPUT_SELECTOR); + $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label-display"]'); + // Check that advanced block form elements do not exist. + $web_assert->elementNotExists('css', 'input[data-drupal-selector="edit-visibility-request-path-pages"]'); + $web_assert->elementNotExists('css', 'select[data-drupal-selector="edit-region"]'); + } + + /** + * Open block form by clicking the element found with a css selector. + * + * @param string $block_selector + * A css selector selects the block or an element within it. + * @param string $contextual_link_container + * The element that contains the contextual links. If none provide the + * $block_selector will be used. + */ + protected function openBlockForm($block_selector, $contextual_link_container = '') { + if (!$contextual_link_container) { + $contextual_link_container = $block_selector; + } + // Ensure that contextual link element is present because this is required + // to open the off-canvas dialog in edit mode. + $contextual_link = $this->assertSession()->waitForElement('css', "$contextual_link_container .contextual-links a"); + $this->assertNotEmpty($contextual_link); + // When page first loads Edit Mode is not triggered until first contextual + // link is added. + $this->assertElementVisibleAfterWait('css', '.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode'); + // Ensure that all other Ajax activity is completed. + $this->assertSession()->assertWaitOnAjaxRequest(); + $this->click($block_selector); + $this->waitForOffCanvasToOpen(); + $this->assertOffCanvasBlockFormIsValid(); + } + + /** + * Tests QuickEdit links behavior. + */ + public function testQuickEditLinks() { + $quick_edit_selector = '#quickedit-entity-toolbar'; + $node_selector = '[data-quickedit-entity-id="node/1"]'; + $body_selector = '[data-quickedit-field-id="node/1/body/en/full"]'; + $web_assert = $this->assertSession(); + // Create a Content type and two test nodes. + $this->createContentType(['type' => 'page']); + $auth_role = Role::load(Role::AUTHENTICATED_ID); + $this->grantPermissions($auth_role, [ + 'edit any page content', + 'access content', + ]); + $node = $this->createNode( + [ + 'title' => 'Page One', + 'type' => 'page', + 'body' => [ + [ + 'value' => 'Regular NODE body for the test.', + 'format' => 'plain_text', + ], + ], + ] + ); + $page = $this->getSession()->getPage(); + $block_plugin = 'system_powered_by_block'; + + foreach ($this->getTestThemes() as $theme) { + + $this->enableTheme($theme); + + $block = $this->placeBlock($block_plugin); + $block_selector = str_replace('_', '-', $this->getBlockSelector($block)); + // Load the same page twice. + foreach ([1, 2] as $page_load_times) { + $this->drupalGet('node/' . $node->id()); + // The 2nd page load we should already be in edit mode. + if ($page_load_times == 1) { + $this->enableEditMode(); + } + // In Edit mode clicking field should open QuickEdit toolbar. + $page->find('css', $body_selector)->click(); + $this->assertElementVisibleAfterWait('css', $quick_edit_selector); + + $this->disableEditMode(); + // Exiting Edit mode should close QuickEdit toolbar. + $web_assert->elementNotExists('css', $quick_edit_selector); + // When not in Edit mode QuickEdit toolbar should not open. + $page->find('css', $body_selector)->click(); + $web_assert->elementNotExists('css', $quick_edit_selector); + $this->enableEditMode(); + $this->openBlockForm($block_selector); + $page->find('css', $body_selector)->click(); + $this->assertElementVisibleAfterWait('css', $quick_edit_selector); + // Off-canvas dialog should be closed when opening QuickEdit toolbar. + $this->waitForOffCanvasToClose(); + + $this->openBlockForm($block_selector); + // QuickEdit toolbar should be closed when opening Off-canvas dialog. + $web_assert->elementNotExists('css', $quick_edit_selector); + } + // Check using contextual links to invoke QuickEdit and open the tray. + $this->drupalGet('node/' . $node->id()); + $web_assert->assertWaitOnAjaxRequest(); + $this->disableEditMode(); + // Open QuickEdit toolbar before going into Edit mode. + $this->clickContextualLink($node_selector, "Quick edit"); + $this->assertElementVisibleAfterWait('css', $quick_edit_selector); + // Open off-canvas and enter Edit mode via contextual link. + $this->clickContextualLink($block_selector, "Quick edit"); + $this->waitForOffCanvasToOpen(); + // QuickEdit toolbar should be closed when opening off-canvas dialog. + $web_assert->elementNotExists('css', $quick_edit_selector); + // Open QuickEdit toolbar via contextual link while in Edit mode. + $this->clickContextualLink($node_selector, "Quick edit", FALSE); + $this->waitForOffCanvasToClose(); + $this->assertElementVisibleAfterWait('css', $quick_edit_selector); + $this->disableEditMode(); + } + } + + /** + * Tests enabling and disabling Edit Mode. + */ + public function testEditModeEnableDisable() { + foreach ($this->getTestThemes() as $theme) { + $this->enableTheme($theme); + $block = $this->placeBlock('system_powered_by_block'); + foreach (['contextual_link', 'toolbar_link'] as $enable_option) { + $this->drupalGet('user'); + $this->assertEditModeDisabled(); + switch ($enable_option) { + // Enable Edit mode. + case 'contextual_link': + $this->clickContextualLink($this->getBlockSelector($block), "Quick edit"); + $this->waitForOffCanvasToOpen(); + $this->assertEditModeEnabled(); + break; + + case 'toolbar_link': + $this->enableEditMode(); + break; + } + $this->disableEditMode(); + + // Make another page request to ensure Edit mode is still disabled. + $this->drupalGet('user'); + $this->assertEditModeDisabled(); + // Make sure on this page request it also re-enables and disables + // correctly. + $this->enableEditMode(); + $this->disableEditMode(); + } + } + } + + /** + * Assert that edit mode has been properly enabled. + */ + protected function assertEditModeEnabled() { + $web_assert = $this->assertSession(); + // No contextual triggers should be hidden. + $web_assert->elementNotExists('css', '.contextual .trigger.visually-hidden'); + // The toolbar edit button should read "Editing". + $web_assert->elementContains('css', static::TOOLBAR_EDIT_LINK_SELECTOR, 'Editing'); + // The main canvas element should have the "js-settings-tray-edit-mode" class. + $web_assert->elementExists('css', '.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode'); + } + + /** + * Assert that edit mode has been properly disabled. + */ + protected function assertEditModeDisabled() { + $web_assert = $this->assertSession(); + // Contextual triggers should be hidden. + $web_assert->elementExists('css', '.contextual .trigger.visually-hidden'); + // No contextual triggers should be not hidden. + $web_assert->elementNotExists('css', '.contextual .trigger:not(.visually-hidden)'); + // The toolbar edit button should read "Edit". + $web_assert->elementContains('css', static::TOOLBAR_EDIT_LINK_SELECTOR, 'Edit'); + // The main canvas element should NOT have the "js-settings-tray-edit-mode" + // class. + $web_assert->elementNotExists('css', '.dialog-off-canvas__main-canvas.js-settings-tray-edit-mode'); + } + + /** + * Press the toolbar Edit button provided by the contextual module. + */ + protected function pressToolbarEditButton() { + $this->assertSession()->waitForElement('css', '[data-contextual-id] .contextual-links a'); + $edit_button = $this->getSession() + ->getPage() + ->find('css', static::TOOLBAR_EDIT_LINK_SELECTOR); + $edit_button->press(); + } + + /** + * Creates a custom block. + * + * @param bool|string $title + * (optional) Title of block. When no value is given uses a random name. + * Defaults to FALSE. + * @param string $bundle + * (optional) Bundle name. Defaults to 'basic'. + * @param bool $save + * (optional) Whether to save the block. Defaults to TRUE. + * + * @return \Drupal\block_content\Entity\BlockContent + * Created custom block. + */ + protected function createBlockContent($title = FALSE, $bundle = 'basic', $save = TRUE) { + $title = $title ?: $this->randomName(); + $block_content = BlockContent::create([ + 'info' => $title, + 'type' => $bundle, + 'langcode' => 'en', + 'body' => [ + 'value' => 'The name "llama" was adopted by European settlers from native Peruvians.', + 'format' => 'plain_text', + ], + ]); + if ($block_content && $save === TRUE) { + $block_content->save(); + } + return $block_content; + } + + /** + * Creates a custom block type (bundle). + * + * @param string $label + * The block type label. + * @param bool $create_body + * Whether or not to create the body field. + * + * @return \Drupal\block_content\Entity\BlockContentType + * Created custom block type. + */ + protected function createBlockContentType($label, $create_body = FALSE) { + $bundle = BlockContentType::create([ + 'id' => $label, + 'label' => $label, + 'revision' => FALSE, + ]); + $bundle->save(); + if ($create_body) { + block_content_add_body_field($bundle->id()); + } + return $bundle; + } + + /** + * Tests that contextual links in custom blocks are changed. + * + * "Quick edit" is quickedit.module link. + * "Quick edit settings" is settings_tray.module link. + */ + public function testCustomBlockLinks() { + $this->drupalGet('user'); + $page = $this->getSession()->getPage(); + $links = $page->findAll('css', "#block-custom .contextual-links li a"); + $link_labels = []; + /** @var \Behat\Mink\Element\NodeElement $link */ + foreach ($links as $link) { + $link_labels[$link->getAttribute('href')] = $link->getText(); + } + $href = array_search('Quick edit', $link_labels); + $this->assertEquals('', $href); + $href = array_search('Quick edit settings', $link_labels); + $this->assertTrue(strstr($href, '/admin/structure/block/manage/custom/off-canvas?destination=user/2') !== FALSE); + } + + /** + * Gets the block CSS selector. + * + * @param \Drupal\block\Entity\Block $block + * The block. + * + * @return string + * The CSS selector. + */ + public function getBlockSelector(Block $block) { + return '#block-' . $block->id(); + } + + /** + * Determines if the label input is visible. + * + * @return bool + * TRUE if the label is visible, FALSE if it is not. + */ + protected function isLabelInputVisible() { + return $this->getSession()->getPage()->find('css', static::LABEL_INPUT_SELECTOR)->isVisible(); + } + + /** + * Test that validation errors appear in the off-canvas dialog. + */ + public function testValidationMessages() { + $page = $this->getSession()->getPage(); + $web_assert = $this->assertSession(); + foreach ($this->getTestThemes() as $theme) { + $this->enableTheme($theme); + $block = $this->placeBlock('settings_tray_test_validation'); + $this->drupalGet('user'); + $this->enableEditMode(); + $this->openBlockForm($this->getBlockSelector($block)); + $page->pressButton('Save Block with validation error'); + $web_assert->assertWaitOnAjaxRequest(); + // The settings_tray_test_validation test plugin form always has a + // validation error. + $web_assert->elementContains('css', '#drupal-off-canvas', 'Sorry system error. Please save again'); + $this->disableEditMode(); + $block->delete(); + } + } + +} diff --git a/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayJavascriptTestBase.php b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayJavascriptTestBase.php new file mode 100644 index 00000000..6dd026c5 --- /dev/null +++ b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayJavascriptTestBase.php @@ -0,0 +1,126 @@ +assertPageLoadComplete(); + return $return; + } + + /** + * Assert the page is completely loaded. + * + * Ajax requests may happen after page loads. Also for users who have access + * to contextual links the contextual link placeholders will be filled after + * the page is received. + */ + protected function assertPageLoadComplete() { + $this->assertSession()->assertWaitOnAjaxRequest(); + if ($this->loggedInUser && $this->loggedInUser->hasPermission('access contextual links')) { + $this->assertAllContextualLinksLoaded(); + } + } + + /** + * Assert all contextual link areas have be loaded. + * + * Contextual link placeholders will be filled after + * the page is received. + * + * @todo Move this function to https://www.drupal.org/node/2821724. + */ + protected function assertAllContextualLinksLoaded() { + $this->waitForNoElement('[data-contextual-id]:empty'); + } + + /** + * Enables a theme. + * + * @param string $theme + * The theme. + */ + protected function enableTheme($theme) { + // Enable the theme. + \Drupal::service('theme_installer')->install([$theme]); + $theme_config = \Drupal::configFactory()->getEditable('system.theme'); + $theme_config->set('default', $theme); + $theme_config->save(); + } + + /** + * Waits for off-canvas dialog to open. + */ + protected function waitForOffCanvasToOpen() { + $web_assert = $this->assertSession(); + $web_assert->assertWaitOnAjaxRequest(); + $this->assertElementVisibleAfterWait('css', '#drupal-off-canvas'); + } + + /** + * Waits for off-canvas dialog to close. + */ + protected function waitForOffCanvasToClose() { + $this->waitForNoElement('#drupal-off-canvas'); + } + + /** + * Gets the off-canvas dialog element. + * + * @return \Behat\Mink\Element\NodeElement|null + */ + protected function getTray() { + $tray = $this->getSession()->getPage()->find('css', '.ui-dialog[aria-describedby="drupal-off-canvas"]'); + $this->assertEquals(FALSE, empty($tray), 'The tray was found.'); + return $tray; + } + + /** + * Waits for an element to be removed from the page. + * + * @param string $selector + * CSS selector. + * @param int $timeout + * (optional) Timeout in milliseconds, defaults to 10000. + */ + protected function waitForNoElement($selector, $timeout = 10000) { + $condition = "(typeof jQuery !== 'undefined' && jQuery('$selector').length === 0)"; + $this->assertJsCondition($condition, $timeout); + } + + /** + * Get themes to test. + * + * @return string[] + * Theme names to test. + */ + protected function getTestThemes() { + return ['bartik', 'stark', 'classy', 'stable']; + } + + /** + * Asserts the specified selector is visible after a wait. + * + * @param string $selector + * The selector engine name. See ElementInterface::findAll() for the + * supported selectors. + * @param string|array $locator + * The selector locator. + * @param int $timeout + * (Optional) Timeout in milliseconds, defaults to 10000. + */ + protected function assertElementVisibleAfterWait($selector, $locator, $timeout = 10000) { + $this->assertNotEmpty($this->assertSession()->waitForElementVisible($selector, $locator, $timeout)); + } + +} diff --git a/core/modules/settings_tray/tests/src/Unit/Access/BlockPluginHasSettingsTrayFormAccessCheckTest.php b/core/modules/settings_tray/tests/src/Unit/Access/BlockPluginHasSettingsTrayFormAccessCheckTest.php new file mode 100644 index 00000000..c89abfd9 --- /dev/null +++ b/core/modules/settings_tray/tests/src/Unit/Access/BlockPluginHasSettingsTrayFormAccessCheckTest.php @@ -0,0 +1,96 @@ +prophesize()->willImplement(BlockPluginInterface::class); + + if ($with_forms) { + $block_plugin->willImplement(PluginWithFormsInterface::class); + $block_plugin->hasFormClass(Argument::type('string'))->will(function ($arguments) use ($plugin_definition) { + return !empty($plugin_definition['forms'][$arguments[0]]); + }); + } + + $block = $this->prophesize(BlockInterface::class); + $block->getPlugin()->willReturn($block_plugin->reveal()); + + $access_check = new BlockPluginHasSettingsTrayFormAccessCheck(); + $this->assertEquals($expected_access_result, $access_check->access($block->reveal())); + $this->assertEquals($expected_access_result, $access_check->accessBlockPlugin($block_plugin->reveal())); + } + + /** + * Provides test data for ::testAccess(). + */ + public function providerTestAccess() { + $annotation_forms_settings_tray_class = [ + 'forms' => [ + 'settings_tray' => $this->randomMachineName(), + ], + ]; + $annotation_forms_settings_tray_not_set = []; + $annotation_forms_settings_tray_false = [ + 'forms' => [ + 'settings_tray' => FALSE, + ], + ]; + return [ + 'block plugin with forms, forms[settings_tray] set to class' => [ + TRUE, + $annotation_forms_settings_tray_class, + new AccessResultAllowed(), + ], + 'block plugin with forms, forms[settings_tray] not set' => [ + TRUE, + $annotation_forms_settings_tray_not_set, + new AccessResultNeutral(), + ], + 'block plugin with forms, forms[settings_tray] set to FALSE' => [ + TRUE, + $annotation_forms_settings_tray_false, + new AccessResultNeutral(), + ], + // In practice, all block plugins extend BlockBase, which means they all + // implement PluginWithFormsInterface, but this may change in the future. + // This ensures Settings Tray will continue to work correctly. + 'block plugin without forms, forms[settings_tray] set to class' => [ + FALSE, + $annotation_forms_settings_tray_class, + new AccessResultNeutral(), + ], + 'block plugin without forms, forms[settings_tray] not set' => [ + FALSE, + $annotation_forms_settings_tray_not_set, + new AccessResultNeutral(), + ], + 'block plugin without forms, forms[settings_tray] set to FALSE' => [ + FALSE, + $annotation_forms_settings_tray_false, + new AccessResultNeutral(), + ], + ]; + } + +} diff --git a/core/modules/settings_tray/tests/src/Unit/Ajax/OpenOffCanvasDialogCommandTest.php b/core/modules/settings_tray/tests/src/Unit/Ajax/OpenOffCanvasDialogCommandTest.php new file mode 100644 index 00000000..5985cbda --- /dev/null +++ b/core/modules/settings_tray/tests/src/Unit/Ajax/OpenOffCanvasDialogCommandTest.php @@ -0,0 +1,43 @@ +Text!

    ', ['url' => 'example']); + + $expected = [ + 'command' => 'openDialog', + 'selector' => '#drupal-off-canvas', + 'settings' => NULL, + 'data' => '

    Text!

    ', + 'dialogOptions' => [ + 'url' => 'example', + 'title' => 'Title', + 'modal' => FALSE, + 'autoResize' => FALSE, + 'resizable' => 'w', + 'draggable' => FALSE, + 'drupalAutoButtons' => FALSE, + 'buttons' => [], + 'dialogClass' => 'ui-dialog-off-canvas', + 'width' => 300, + ], + 'effect' => 'fade', + 'speed' => 1000, + ]; + $this->assertEquals($expected, $command->render()); + } + +} diff --git a/core/modules/shortcut/migration_templates/d7_shortcut.yml b/core/modules/shortcut/migration_templates/d7_shortcut.yml index da3d8949..dac93543 100644 --- a/core/modules/shortcut/migration_templates/d7_shortcut.yml +++ b/core/modules/shortcut/migration_templates/d7_shortcut.yml @@ -8,7 +8,7 @@ source: uri_scheme: 'internal:/' process: shortcut_set: - plugin: migration + plugin: migration_lookup migration: d7_shortcut_set source: menu_name title: link_title diff --git a/core/modules/shortcut/migration_templates/d7_shortcut_set_users.yml b/core/modules/shortcut/migration_templates/d7_shortcut_set_users.yml index a93c4bba..d0eb2199 100644 --- a/core/modules/shortcut/migration_templates/d7_shortcut_set_users.yml +++ b/core/modules/shortcut/migration_templates/d7_shortcut_set_users.yml @@ -7,14 +7,14 @@ source: process: uid: - - plugin: migration + plugin: migration_lookup migration: d7_user source: uid - plugin: skip_on_empty method: row set_name: - plugin: migration + plugin: migration_lookup migration: d7_shortcut_set source: set_name destination: diff --git a/core/modules/shortcut/shortcut.info.yml b/core/modules/shortcut/shortcut.info.yml index 90290bf8..f7cbbfb3 100644 --- a/core/modules/shortcut/shortcut.info.yml +++ b/core/modules/shortcut/shortcut.info.yml @@ -8,8 +8,8 @@ configure: entity.shortcut_set.collection dependencies: - link -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install index 8df408fe..21ebf519 100644 --- a/core/modules/shortcut/shortcut.install +++ b/core/modules/shortcut/shortcut.install @@ -9,39 +9,39 @@ * Implements hook_schema(). */ function shortcut_schema() { - $schema['shortcut_set_users'] = array( + $schema['shortcut_set_users'] = [ 'description' => 'Maps users to shortcut sets.', - 'fields' => array( - 'uid' => array( + 'fields' => [ + 'uid' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'The {users}.uid for this set.', - ), - 'set_name' => array( + ], + 'set_name' => [ 'type' => 'varchar_ascii', 'length' => 32, 'not null' => TRUE, 'default' => '', 'description' => "The {shortcut_set}.set_name that will be displayed for this user.", - ), - ), - 'primary key' => array('uid'), - 'indexes' => array( - 'set_name' => array('set_name'), - ), - 'foreign keys' => array( - 'set_user' => array( + ], + ], + 'primary key' => ['uid'], + 'indexes' => [ + 'set_name' => ['set_name'], + ], + 'foreign keys' => [ + 'set_user' => [ 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - 'set_name' => array( + 'columns' => ['uid' => 'uid'], + ], + 'set_name' => [ 'table' => 'shortcut_set', - 'columns' => array('set_name' => 'set_name'), - ), - ), - ); + 'columns' => ['set_name' => 'set_name'], + ], + ], + ]; return $schema; } diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index b7294ad6..8ace7bdb 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -20,16 +20,16 @@ function shortcut_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.shortcut': $output = '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Shortcut module allows users to create sets of shortcut links to commonly-visited pages of the site. Shortcuts are contained within sets. Each user with Select any shortcut set permission can select a shortcut set created by anyone at the site. For more information, see the online documentation for the Shortcut module.', array(':shortcut' => 'https://www.drupal.org/documentation/modules/shortcut')) . '

    '; + $output .= '

    ' . t('The Shortcut module allows users to create sets of shortcut links to commonly-visited pages of the site. Shortcuts are contained within sets. Each user with Select any shortcut set permission can select a shortcut set created by anyone at the site. For more information, see the online documentation for the Shortcut module.', [':shortcut' => 'https://www.drupal.org/documentation/modules/shortcut']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    ' . t('Administering shortcuts') . '
    '; - $output .= '
    ' . t('Users with the Administer shortcuts permission can manage shortcut sets and edit the shortcuts within sets from the Shortcuts administration page.', array(':shortcuts' => \Drupal::url('entity.shortcut_set.collection'))) . '
    '; + $output .= '
    ' . t('Users with the Administer shortcuts permission can manage shortcut sets and edit the shortcuts within sets from the Shortcuts administration page.', [':shortcuts' => \Drupal::url('entity.shortcut_set.collection')]) . '
    '; $output .= '
    ' . t('Choosing shortcut sets') . '
    '; $output .= '
    ' . t('Users with permission to switch shortcut sets can choose a shortcut set to use from the Shortcuts tab of their user account page.') . '
    '; $output .= '
    ' . t('Adding and removing shortcuts') . '
    '; $output .= '
    ' . t('The Shortcut module creates an add/remove link for each page on your site; the link lets you add or remove the current page from the currently-enabled set of shortcuts (if your theme displays it and you have permission to edit your shortcut set). The core Seven administration theme displays this link next to the page title, as a grey or yellow star. If you click on the grey star, you will add that page to your preferred set of shortcuts. If the page is already part of your shortcut set, the link will be a yellow star, and will allow you to remove the current page from your shortcut set.') . '
    '; $output .= '
    ' . t('Displaying shortcuts') . '
    '; - $output .= '
    ' . t('You can display your shortcuts by enabling the Shortcuts block on the Blocks administration page. Certain administrative modules also display your shortcuts; for example, the core Toolbar module provides a corresponding menu item.', array(':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#', ':toolbar-help' => (\Drupal::moduleHandler()->moduleExists('toolbar')) ? \Drupal::url('help.page', array('name' => 'toolbar')) : '#')) . '
    '; + $output .= '
    ' . t('You can display your shortcuts by enabling the Shortcuts block on the Blocks administration page. Certain administrative modules also display your shortcuts; for example, the core Toolbar module provides a corresponding menu item.', [':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#', ':toolbar-help' => (\Drupal::moduleHandler()->moduleExists('toolbar')) ? \Drupal::url('help.page', ['name' => 'toolbar']) : '#']) . '
    '; $output .= '
    '; return $output; @@ -38,7 +38,7 @@ function shortcut_help($route_name, RouteMatchInterface $route_match) { case 'entity.shortcut_set.edit_form': $user = \Drupal::currentUser(); if ($user->hasPermission('access shortcuts') && $user->hasPermission('switch shortcut sets')) { - $output = '

    ' . t('Define which shortcut set you are using on the Shortcuts tab of your account page.', array(':shortcut-link' => \Drupal::url('shortcut.set_switch', array('user' => $user->id())))) . '

    '; + $output = '

    ' . t('Define which shortcut set you are using on the Shortcuts tab of your account page.', [':shortcut-link' => \Drupal::url('shortcut.set_switch', ['user' => $user->id()])]) . '

    '; return $output; } } @@ -65,7 +65,11 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) { // Sufficiently-privileged users can edit their currently displayed shortcut // set, but not other sets. They must also be able to access shortcuts. $may_edit_current_shortcut_set = $account->hasPermission('customize shortcut links') && (!isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set()) && $account->hasPermission('access shortcuts'); - return AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions(); + $result = AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions(); + if (!$result->isAllowed()) { + $result->setReason("The shortcut set must be the currently displayed set for the user and the user must have 'access shortcuts' AND 'customize shortcut links' permissions."); + } + return $result; } /** @@ -162,7 +166,7 @@ function shortcut_set_unassign_user($account) { * the default set is returned. */ function shortcut_current_displayed_set($account = NULL) { - $shortcut_sets = &drupal_static(__FUNCTION__, array()); + $shortcut_sets = &drupal_static(__FUNCTION__, []); $user = \Drupal::currentUser(); if (!isset($account)) { $account = $user; @@ -209,7 +213,7 @@ function shortcut_default_set($account = NULL) { // have one, we allow the last module which returns a valid result to take // precedence. If no module returns a valid set, fall back on the site-wide // default, which is the lowest-numbered shortcut set. - $suggestions = array_reverse(\Drupal::moduleHandler()->invokeAll('shortcut_default_set', array($account))); + $suggestions = array_reverse(\Drupal::moduleHandler()->invokeAll('shortcut_default_set', [$account])); $suggestions[] = 'default'; foreach ($suggestions as $name) { if ($shortcut_set = ShortcutSet::load($name)) { @@ -252,37 +256,37 @@ function shortcut_set_title_exists($title) { * An array of shortcut links, in the format returned by the menu system. */ function shortcut_renderable_links($shortcut_set = NULL) { - $shortcut_links = array(); + $shortcut_links = []; if (!isset($shortcut_set)) { $shortcut_set = shortcut_current_displayed_set(); } - $cache_tags = array(); + $cache_tags = []; foreach ($shortcut_set->getShortcuts() as $shortcut) { $shortcut = \Drupal::entityManager()->getTranslationFromContext($shortcut); $url = $shortcut->getUrl(); if ($url->access()) { - $links[$shortcut->id()] = array( + $links[$shortcut->id()] = [ 'type' => 'link', 'title' => $shortcut->label(), 'url' => $shortcut->getUrl(), - ); + ]; $cache_tags = Cache::mergeTags($cache_tags, $shortcut->getCacheTags()); } } if (!empty($links)) { - $shortcut_links = array( + $shortcut_links = [ '#theme' => 'links__toolbar_shortcuts', '#links' => $links, - '#attributes' => array( - 'class' => array('toolbar-menu'), - ), - '#cache' => array( + '#attributes' => [ + 'class' => ['toolbar-menu'], + ], + '#cache' => [ 'tags' => $cache_tags, - ), - ); + ], + ]; } return $shortcut_links; @@ -313,15 +317,15 @@ function shortcut_preprocess_page_title(&$variables) { // string form, so we can set the default name for the shortcut. // Strip HTML tags from the title. $name = trim(strip_tags(render($variables['title']))); - $query = array( + $query = [ 'link' => $link, 'name' => $name, - ); + ]; $shortcut_set = shortcut_current_displayed_set(); // Check if $link is already a shortcut and set $link_mode accordingly. - $shortcuts = \Drupal::entityManager()->getStorage('shortcut')->loadByProperties(array('shortcut_set' => $shortcut_set->id())); + $shortcuts = \Drupal::entityManager()->getStorage('shortcut')->loadByProperties(['shortcut_set' => $shortcut_set->id()]); /** @var \Drupal\shortcut\ShortcutInterface $shortcut */ foreach ($shortcuts as $shortcut) { if (($shortcut_url = $shortcut->getUrl()) && $shortcut_url->isRouted() && $shortcut_url->getRouteName() == $route_match->getRouteName() && $shortcut_url->getRouteParameters() == $route_match->getRawParameters()->all()) { @@ -332,36 +336,36 @@ function shortcut_preprocess_page_title(&$variables) { $link_mode = isset($shortcut_id) ? "remove" : "add"; if ($link_mode == "add") { - $link_text = shortcut_set_switch_access()->isAllowed() ? t('Add to %shortcut_set shortcuts', array('%shortcut_set' => $shortcut_set->label())) : t('Add to shortcuts'); + $link_text = shortcut_set_switch_access()->isAllowed() ? t('Add to %shortcut_set shortcuts', ['%shortcut_set' => $shortcut_set->label()]) : t('Add to shortcuts'); $route_name = 'shortcut.link_add_inline'; - $route_parameters = array('shortcut_set' => $shortcut_set->id()); + $route_parameters = ['shortcut_set' => $shortcut_set->id()]; } else { $query['id'] = $shortcut_id; - $link_text = shortcut_set_switch_access()->isAllowed() ? t('Remove from %shortcut_set shortcuts', array('%shortcut_set' => $shortcut_set->label())) : t('Remove from shortcuts'); + $link_text = shortcut_set_switch_access()->isAllowed() ? t('Remove from %shortcut_set shortcuts', ['%shortcut_set' => $shortcut_set->label()]) : t('Remove from shortcuts'); $route_name = 'entity.shortcut.link_delete_inline'; - $route_parameters = array('shortcut' => $shortcut_id); + $route_parameters = ['shortcut' => $shortcut_id]; } if (theme_get_setting('third_party_settings.shortcut.module_link')) { $query += \Drupal::destination()->getAsArray(); - $variables['title_suffix']['add_or_remove_shortcut'] = array( - '#attached' => array( - 'library' => array( + $variables['title_suffix']['add_or_remove_shortcut'] = [ + '#attached' => [ + 'library' => [ 'shortcut/drupal.shortcut', - ), - ), + ], + ], '#type' => 'link', - '#title' => SafeMarkup::format('@text', array('@text' => $link_text)), + '#title' => SafeMarkup::format('@text', ['@text' => $link_text]), '#url' => Url::fromRoute($route_name, $route_parameters), - '#options' => array('query' => $query), - '#attributes' => array( - 'class' => array( + '#options' => ['query' => $query], + '#attributes' => [ + 'class' => [ 'shortcut-action', 'shortcut-action--' . $link_mode, - ), - ), - ); + ], + ], + ]; } } } @@ -390,37 +394,37 @@ function shortcut_toolbar() { \Drupal::service('renderer')->addCacheableDependency($items['shortcuts'], $shortcut_set); $configure_link = NULL; if (shortcut_set_edit_access($shortcut_set)->isAllowed()) { - $configure_link = array( + $configure_link = [ '#type' => 'link', '#title' => t('Edit shortcuts'), '#url' => Url::fromRoute('entity.shortcut_set.customize_form', ['shortcut_set' => $shortcut_set->id()]), - '#options' => array('attributes' => array('class' => array('edit-shortcuts'))), - ); + '#options' => ['attributes' => ['class' => ['edit-shortcuts']]], + ]; } if (!empty($links) || !empty($configure_link)) { - $items['shortcuts'] += array( + $items['shortcuts'] += [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => t('Shortcuts'), '#url' => $shortcut_set->urlInfo('collection'), - '#attributes' => array( + '#attributes' => [ 'title' => t('Shortcuts'), - 'class' => array('toolbar-icon', 'toolbar-icon-shortcut'), - ), - ), - 'tray' => array( + 'class' => ['toolbar-icon', 'toolbar-icon-shortcut'], + ], + ], + 'tray' => [ '#heading' => t('User-defined shortcuts'), 'shortcuts' => $links, 'configure' => $configure_link, - ), + ], '#weight' => -10, - '#attached' => array( - 'library' => array( + '#attached' => [ + 'library' => [ 'shortcut/drupal.shortcut', - ), - ), - ); + ], + ], + ]; } } diff --git a/core/modules/shortcut/src/Controller/ShortcutController.php b/core/modules/shortcut/src/Controller/ShortcutController.php index ff0e184c..4f33b0b5 100644 --- a/core/modules/shortcut/src/Controller/ShortcutController.php +++ b/core/modules/shortcut/src/Controller/ShortcutController.php @@ -21,7 +21,7 @@ class ShortcutController extends ControllerBase { * The shortcut add form. */ public function addForm(ShortcutSetInterface $shortcut_set) { - $shortcut = $this->entityManager()->getStorage('shortcut')->create(array('shortcut_set' => $shortcut_set->id())); + $shortcut = $this->entityManager()->getStorage('shortcut')->create(['shortcut_set' => $shortcut_set->id()]); return $this->entityFormBuilder()->getForm($shortcut, 'add'); } @@ -40,10 +40,10 @@ public function deleteShortcutLinkInline(ShortcutInterface $shortcut) { try { $shortcut->delete(); - drupal_set_message($this->t('The shortcut %title has been deleted.', array('%title' => $label))); + drupal_set_message($this->t('The shortcut %title has been deleted.', ['%title' => $label])); } catch (\Exception $e) { - drupal_set_message($this->t('Unable to delete the shortcut for %title.', array('%title' => $label)), 'error'); + drupal_set_message($this->t('Unable to delete the shortcut for %title.', ['%title' => $label]), 'error'); } return $this->redirect(''); diff --git a/core/modules/shortcut/src/Controller/ShortcutSetController.php b/core/modules/shortcut/src/Controller/ShortcutSetController.php index 8d84f9ab..58a68d70 100644 --- a/core/modules/shortcut/src/Controller/ShortcutSetController.php +++ b/core/modules/shortcut/src/Controller/ShortcutSetController.php @@ -55,20 +55,20 @@ public function addShortcutLinkInline(ShortcutSetInterface $shortcut_set, Reques $link = $request->query->get('link'); $name = $request->query->get('name'); if (parse_url($link, PHP_URL_SCHEME) === NULL && $this->pathValidator->isValid($link)) { - $shortcut = $this->entityManager()->getStorage('shortcut')->create(array( + $shortcut = $this->entityManager()->getStorage('shortcut')->create([ 'title' => $name, 'shortcut_set' => $shortcut_set->id(), - 'link' => array( + 'link' => [ 'uri' => 'internal:/' . $link, - ), - )); + ], + ]); try { $shortcut->save(); - drupal_set_message($this->t('Added a shortcut for %title.', array('%title' => $shortcut->label()))); + drupal_set_message($this->t('Added a shortcut for %title.', ['%title' => $shortcut->label()])); } catch (\Exception $e) { - drupal_set_message($this->t('Unable to add a shortcut for %title.', array('%title' => $shortcut->label())), 'error'); + drupal_set_message($this->t('Unable to add a shortcut for %title.', ['%title' => $shortcut->label()]), 'error'); } return $this->redirect(''); diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php index 6ddaf053..bba393ac 100644 --- a/core/modules/shortcut/src/Entity/Shortcut.php +++ b/core/modules/shortcut/src/Entity/Shortcut.php @@ -18,6 +18,7 @@ * @ContentEntityType( * id = "shortcut", * label = @Translation("Shortcut link"), + * bundle_label = @Translation("Shortcut set"), * handlers = { * "access" = "Drupal\shortcut\ShortcutAccessControlHandler", * "form" = { @@ -123,13 +124,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRequired(TRUE) ->setTranslatable(TRUE) ->setSetting('max_length', 255) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -10, - 'settings' => array( + 'settings' => [ 'size' => 40, - ), - )); + ], + ]); $fields['weight'] = BaseFieldDefinition::create('integer') ->setLabel(t('Weight')) @@ -139,14 +140,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Path')) ->setDescription(t('The location this shortcut points to.')) ->setRequired(TRUE) - ->setSettings(array( + ->setSettings([ 'link_type' => LinkItemInterface::LINK_INTERNAL, 'title' => DRUPAL_DISABLED, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'link_default', 'weight' => 0, - )) + ]) ->setDisplayConfigurable('form', TRUE); return $fields; diff --git a/core/modules/shortcut/src/Entity/ShortcutSet.php b/core/modules/shortcut/src/Entity/ShortcutSet.php index 7b42310e..3d3815db 100644 --- a/core/modules/shortcut/src/Entity/ShortcutSet.php +++ b/core/modules/shortcut/src/Entity/ShortcutSet.php @@ -116,8 +116,8 @@ public function resetLinkWeights() { * {@inheritdoc} */ public function getShortcuts() { - $shortcuts = \Drupal::entityManager()->getStorage('shortcut')->loadByProperties(array('shortcut_set' => $this->id())); - uasort($shortcuts, array('\Drupal\shortcut\Entity\Shortcut', 'sort')); + $shortcuts = \Drupal::entityManager()->getStorage('shortcut')->loadByProperties(['shortcut_set' => $this->id()]); + uasort($shortcuts, ['\Drupal\shortcut\Entity\Shortcut', 'sort']); return $shortcuts; } diff --git a/core/modules/shortcut/src/Form/SetCustomize.php b/core/modules/shortcut/src/Form/SetCustomize.php index 89e51232..6c975778 100644 --- a/core/modules/shortcut/src/Form/SetCustomize.php +++ b/core/modules/shortcut/src/Form/SetCustomize.php @@ -23,24 +23,24 @@ class SetCustomize extends EntityForm { */ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); - $form['shortcuts'] = array( + $form['shortcuts'] = [ '#tree' => TRUE, '#weight' => -20, - ); + ]; - $form['shortcuts']['links'] = array( + $form['shortcuts']['links'] = [ '#type' => 'table', - '#header' => array(t('Name'), t('Weight'), t('Operations')), - '#empty' => $this->t('No shortcuts available. Add a shortcut', array(':link' => $this->url('shortcut.link_add', array('shortcut_set' => $this->entity->id())))), - '#attributes' => array('id' => 'shortcuts'), - '#tabledrag' => array( - array( + '#header' => [t('Name'), t('Weight'), t('Operations')], + '#empty' => $this->t('No shortcuts available. Add a shortcut', [':link' => $this->url('shortcut.link_add', ['shortcut_set' => $this->entity->id()])]), + '#attributes' => ['id' => 'shortcuts'], + '#tabledrag' => [ + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'shortcut-weight', - ), - ), - ); + ], + ], + ]; foreach ($this->entity->getShortcuts() as $shortcut) { $id = $shortcut->id(); @@ -49,33 +49,33 @@ public function form(array $form, FormStateInterface $form_state) { continue; } $form['shortcuts']['links'][$id]['#attributes']['class'][] = 'draggable'; - $form['shortcuts']['links'][$id]['name'] = array( + $form['shortcuts']['links'][$id]['name'] = [ '#type' => 'link', '#title' => $shortcut->getTitle(), - ) + $url->toRenderArray(); + ] + $url->toRenderArray(); unset($form['shortcuts']['links'][$id]['name']['#access_callback']); $form['shortcuts']['links'][$id]['#weight'] = $shortcut->getWeight(); - $form['shortcuts']['links'][$id]['weight'] = array( + $form['shortcuts']['links'][$id]['weight'] = [ '#type' => 'weight', - '#title' => t('Weight for @title', array('@title' => $shortcut->getTitle())), + '#title' => t('Weight for @title', ['@title' => $shortcut->getTitle()]), '#title_display' => 'invisible', '#default_value' => $shortcut->getWeight(), - '#attributes' => array('class' => array('shortcut-weight')), - ); + '#attributes' => ['class' => ['shortcut-weight']], + ]; - $links['edit'] = array( + $links['edit'] = [ 'title' => t('Edit'), 'url' => $shortcut->urlInfo(), - ); - $links['delete'] = array( + ]; + $links['delete'] = [ 'title' => t('Delete'), 'url' => $shortcut->urlInfo('delete-form'), - ); - $form['shortcuts']['links'][$id]['operations'] = array( + ]; + $form['shortcuts']['links'][$id]['operations'] = [ '#type' => 'operations', '#links' => $links, '#access' => $url->access(), - ); + ]; } return $form; } @@ -85,14 +85,14 @@ public function form(array $form, FormStateInterface $form_state) { */ protected function actions(array $form, FormStateInterface $form_state) { // Only includes a Save action for the entity, no direct Delete button. - return array( - 'submit' => array( + return [ + 'submit' => [ '#type' => 'submit', '#value' => t('Save'), '#access' => (bool) Element::getVisibleChildren($form['shortcuts']['links']), - '#submit' => array('::submitForm', '::save'), - ), - ); + '#submit' => ['::submitForm', '::save'], + ], + ]; } /** @@ -100,7 +100,7 @@ protected function actions(array $form, FormStateInterface $form_state) { */ public function save(array $form, FormStateInterface $form_state) { foreach ($this->entity->getShortcuts() as $shortcut) { - $weight = $form_state->getValue(array('shortcuts', 'links', $shortcut->id(), 'weight')); + $weight = $form_state->getValue(['shortcuts', 'links', $shortcut->id(), 'weight']); $shortcut->setWeight($weight); $shortcut->save(); } diff --git a/core/modules/shortcut/src/Form/ShortcutDeleteForm.php b/core/modules/shortcut/src/Form/ShortcutDeleteForm.php index aee67880..fcabeec7 100644 --- a/core/modules/shortcut/src/Form/ShortcutDeleteForm.php +++ b/core/modules/shortcut/src/Form/ShortcutDeleteForm.php @@ -21,9 +21,9 @@ public function getFormId() { * {@inheritdoc} */ public function getCancelUrl() { - return new Url('entity.shortcut_set.customize_form', array( + return new Url('entity.shortcut_set.customize_form', [ 'shortcut_set' => $this->entity->bundle(), - )); + ]); } /** diff --git a/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php b/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php index 3c732d6b..c383627b 100644 --- a/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php +++ b/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php @@ -65,9 +65,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { $info .= '

    ' . t('If you have chosen this shortcut set as the default for some or all users, they may also be affected by deleting it.') . '

    '; } - $form['info'] = array( + $form['info'] = [ '#markup' => $info, - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/shortcut/src/Form/SwitchShortcutSet.php b/core/modules/shortcut/src/Form/SwitchShortcutSet.php index 220f49b9..649cef76 100644 --- a/core/modules/shortcut/src/Form/SwitchShortcutSet.php +++ b/core/modules/shortcut/src/Form/SwitchShortcutSet.php @@ -77,60 +77,60 @@ public function buildForm(array $form, FormStateInterface $form_state, UserInter $account_is_user = $this->user->id() == $account->id(); if (count($options) > 1) { - $form['set'] = array( + $form['set'] = [ '#type' => 'radios', '#title' => $account_is_user ? $this->t('Choose a set of shortcuts to use') : $this->t('Choose a set of shortcuts for this user'), '#options' => $options, '#default_value' => $current_set->id(), - ); + ]; - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Label'), '#description' => $this->t('The new set is created by copying items from your default shortcut set.'), '#access' => $add_access, - '#states' => array( - 'visible' => array( - ':input[name="set"]' => array('value' => 'new'), - ), - 'required' => array( - ':input[name="set"]' => array('value' => 'new'), - ), - ), - ); - $form['id'] = array( + '#states' => [ + 'visible' => [ + ':input[name="set"]' => ['value' => 'new'], + ], + 'required' => [ + ':input[name="set"]' => ['value' => 'new'], + ], + ], + ]; + $form['id'] = [ '#type' => 'machine_name', - '#machine_name' => array( - 'exists' => array($this, 'exists'), + '#machine_name' => [ + 'exists' => [$this, 'exists'], 'replace_pattern' => '[^a-z0-9-]+', 'replace' => '-', - ), + ], // This ID could be used for menu name. '#maxlength' => 23, - '#states' => array( - 'required' => array( - ':input[name="set"]' => array('value' => 'new'), - ), - ), + '#states' => [ + 'required' => [ + ':input[name="set"]' => ['value' => 'new'], + ], + ], '#required' => FALSE, - ); + ]; if (!$account_is_user) { $default_set = $this->shortcutSetStorage->getDefaultSet($this->user); - $form['new']['#description'] = $this->t('The new set is created by copying items from the %default set.', array('%default' => $default_set->label())); + $form['new']['#description'] = $this->t('The new set is created by copying items from the %default set.', ['%default' => $default_set->label()]); } - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Change set'), - ); + ]; } else { // There is only 1 option, so output a message in the $form array. - $form['info'] = array( - '#markup' => '

    ' . $this->t('You are currently using the %set-name shortcut set.', array('%set-name' => $current_set->label())) . '

    ', - ); + $form['info'] = [ + '#markup' => '

    ' . $this->t('You are currently using the %set-name shortcut set.', ['%set-name' => $current_set->label()]) . '

    ', + ]; } return $form; @@ -173,16 +173,16 @@ public function submitForm(array &$form, FormStateInterface $form_state) { if ($form_state->getValue('set') == 'new') { // Save a new shortcut set with links copied from the user's default set. /* @var \Drupal\shortcut\Entity\ShortcutSet $set */ - $set = $this->shortcutSetStorage->create(array( + $set = $this->shortcutSetStorage->create([ 'id' => $form_state->getValue('id'), 'label' => $form_state->getValue('label'), - )); + ]); $set->save(); - $replacements = array( + $replacements = [ '%user' => $this->user->label(), '%set_name' => $set->label(), ':switch-url' => $this->url(''), - ); + ]; if ($account_is_user) { // Only administrators can create new shortcut sets, so we know they have // access to switch back. @@ -193,17 +193,17 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } $form_state->setRedirect( 'entity.shortcut_set.customize_form', - array('shortcut_set' => $set->id()) + ['shortcut_set' => $set->id()] ); } else { // Switch to a different shortcut set. /* @var \Drupal\shortcut\Entity\ShortcutSet $set */ $set = $this->shortcutSetStorage->load($form_state->getValue('set')); - $replacements = array( + $replacements = [ '%user' => $this->user->getDisplayName(), '%set_name' => $set->label(), - ); + ]; drupal_set_message($account_is_user ? $this->t('You are now using the %set_name shortcut set.', $replacements) : $this->t('%user is now using the %set_name shortcut set.', $replacements)); } diff --git a/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php b/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php index 1678f6aa..ab2d57e4 100644 --- a/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php +++ b/core/modules/shortcut/src/Plugin/Block/ShortcutsBlock.php @@ -21,9 +21,9 @@ class ShortcutsBlock extends BlockBase { * {@inheritdoc} */ public function build() { - return array( + return [ shortcut_renderable_links(shortcut_current_displayed_set()), - ); + ]; } /** diff --git a/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php b/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php index cd86f0f5..0cb843be 100644 --- a/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php +++ b/core/modules/shortcut/src/Plugin/migrate/destination/ShortcutSetUsers.php @@ -60,14 +60,14 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function getIds() { - return array( - 'set_name' => array( + return [ + 'set_name' => [ 'type' => 'string', - ), - 'uid' => array( + ], + 'uid' => [ 'type' => 'integer', - ), - ); + ], + ]; } /** @@ -83,14 +83,14 @@ public function fields(MigrationInterface $migration = NULL) { /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { /** @var \Drupal\shortcut\ShortcutSetInterface $set */ $set = $this->shortcutSetStorage->load($row->getDestinationProperty('set_name')); /** @var \Drupal\user\UserInterface $account */ $account = User::load($row->getDestinationProperty('uid')); $this->shortcutSetStorage->assignUser($set, $account); - return array($set->id(), $account->id()); + return [$set->id(), $account->id()]; } } diff --git a/core/modules/shortcut/src/Plugin/migrate/source/d7/Shortcut.php b/core/modules/shortcut/src/Plugin/migrate/source/d7/Shortcut.php index c964e5c4..ac2c63f2 100644 --- a/core/modules/shortcut/src/Plugin/migrate/source/d7/Shortcut.php +++ b/core/modules/shortcut/src/Plugin/migrate/source/d7/Shortcut.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d7_shortcut", - * source_provider = "shortcut" + * source_module = "shortcut" * ) */ class Shortcut extends DrupalSqlBase { @@ -19,7 +19,7 @@ class Shortcut extends DrupalSqlBase { */ public function query() { return $this->select('menu_links', 'ml') - ->fields('ml', array('mlid', 'menu_name', 'link_path', 'link_title', 'weight')) + ->fields('ml', ['mlid', 'menu_name', 'link_path', 'link_title', 'weight']) ->condition('hidden', '0') ->condition('menu_name', 'shortcut-set-%', 'LIKE') ->orderBy('ml.mlid'); @@ -29,13 +29,13 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'mlid' => $this->t("The menu.mlid primary key for this menu item (= shortcut link)."), 'menu_name' => $this->t("The menu_name (= set name) for this shortcut link."), 'link_path' => $this->t("The link for this shortcut."), 'link_title' => $this->t("The title for this shortcut."), 'weight' => $this->t("The weight for this shortcut"), - ); + ]; } /** diff --git a/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSet.php b/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSet.php index 75f14543..7a3ed8ac 100644 --- a/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSet.php +++ b/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSet.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d7_shortcut_set", - * source_provider = "shortcut" + * source_module = "shortcut" * ) */ class ShortcutSet extends DrupalSqlBase { @@ -25,10 +25,10 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'set_name' => $this->t("The name under which the set's links are stored."), 'title' => $this->t("The title of the set."), - ); + ]; } /** diff --git a/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSetUsers.php b/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSetUsers.php index dd5a13fc..c4d54e9f 100644 --- a/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSetUsers.php +++ b/core/modules/shortcut/src/Plugin/migrate/source/d7/ShortcutSetUsers.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d7_shortcut_set_users", - * source_provider = "shortcut" + * source_module = "shortcut" * ) */ class ShortcutSetUsers extends DrupalSqlBase { @@ -25,24 +25,24 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'uid' => $this->t('The users.uid for this set.'), 'set_name' => $this->t('The shortcut_set.set_name that will be displayed for this user.'), - ); + ]; } /** * {@inheritdoc} */ public function getIds() { - return array( - 'set_name' => array( + return [ + 'set_name' => [ 'type' => 'string', - ), - 'uid' => array( + ], + 'uid' => [ 'type' => 'integer', - ), - ); + ], + ]; } } diff --git a/core/modules/shortcut/src/ShortcutForm.php b/core/modules/shortcut/src/ShortcutForm.php index b87db1bc..bfe3133e 100644 --- a/core/modules/shortcut/src/ShortcutForm.php +++ b/core/modules/shortcut/src/ShortcutForm.php @@ -35,16 +35,16 @@ public function save(array $form, FormStateInterface $form_state) { } if ($status == SAVED_UPDATED) { - $message = $this->t('The shortcut %link has been updated.', array('%link' => $view_link)); + $message = $this->t('The shortcut %link has been updated.', ['%link' => $view_link]); } else { - $message = $this->t('Added a shortcut for %title.', array('%title' => $view_link)); + $message = $this->t('Added a shortcut for %title.', ['%title' => $view_link]); } drupal_set_message($message); $form_state->setRedirect( 'entity.shortcut_set.customize_form', - array('shortcut_set' => $entity->bundle()) + ['shortcut_set' => $entity->bundle()] ); } diff --git a/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php b/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php index b5ce0e81..3a55f749 100644 --- a/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php +++ b/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php @@ -19,6 +19,8 @@ class ShortcutSetAccessControlHandler extends EntityAccessControlHandler { */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { switch ($operation) { + case 'view': + return AccessResult::allowedIf($account->hasPermission('access shortcuts'))->cachePerPermissions(); case 'update': if ($account->hasPermission('administer shortcuts')) { return AccessResult::allowed()->cachePerPermissions(); diff --git a/core/modules/shortcut/src/ShortcutSetForm.php b/core/modules/shortcut/src/ShortcutSetForm.php index 012de5fa..721d2517 100644 --- a/core/modules/shortcut/src/ShortcutSetForm.php +++ b/core/modules/shortcut/src/ShortcutSetForm.php @@ -17,25 +17,25 @@ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); $entity = $this->entity; - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => t('Set name'), '#description' => t('The new set is created by copying items from your default shortcut set.'), '#required' => TRUE, '#default_value' => $entity->label(), - ); - $form['id'] = array( + ]; + $form['id'] = [ '#type' => 'machine_name', - '#machine_name' => array( + '#machine_name' => [ 'exists' => '\Drupal\shortcut\Entity\ShortcutSet::load', - 'source' => array('label'), + 'source' => ['label'], 'replace_pattern' => '[^a-z0-9-]+', 'replace' => '-', - ), + ], '#default_value' => $entity->id(), // This id could be used for menu name. '#maxlength' => 23, - ); + ]; $form['actions']['submit']['#value'] = t('Create new set'); @@ -51,10 +51,10 @@ public function save(array $form, FormStateInterface $form_state) { $entity->save(); if ($is_new) { - drupal_set_message(t('The %set_name shortcut set has been created. You can edit it from this page.', array('%set_name' => $entity->label()))); + drupal_set_message(t('The %set_name shortcut set has been created. You can edit it from this page.', ['%set_name' => $entity->label()])); } else { - drupal_set_message(t('Updated set name to %set-name.', array('%set-name' => $entity->label()))); + drupal_set_message(t('Updated set name to %set-name.', ['%set-name' => $entity->label()])); } $form_state->setRedirectUrl($this->entity->urlInfo('customize-form')); } diff --git a/core/modules/shortcut/src/ShortcutSetListBuilder.php b/core/modules/shortcut/src/ShortcutSetListBuilder.php index 0e5d81d8..2cc582e9 100644 --- a/core/modules/shortcut/src/ShortcutSetListBuilder.php +++ b/core/modules/shortcut/src/ShortcutSetListBuilder.php @@ -30,10 +30,10 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['edit']['title'] = t('Edit shortcut set'); } - $operations['list'] = array( + $operations['list'] = [ 'title' => t('List links'), 'url' => $entity->urlInfo('customize-form'), - ); + ]; return $operations; } diff --git a/core/modules/shortcut/src/ShortcutSetStorage.php b/core/modules/shortcut/src/ShortcutSetStorage.php index d76c0c46..b136c2fb 100644 --- a/core/modules/shortcut/src/ShortcutSetStorage.php +++ b/core/modules/shortcut/src/ShortcutSetStorage.php @@ -73,7 +73,7 @@ public function deleteAssignedShortcutSets(ShortcutSetInterface $entity) { public function assignUser(ShortcutSetInterface $shortcut_set, $account) { db_merge('shortcut_set_users') ->key('uid', $account->id()) - ->fields(array('set_name' => $shortcut_set->id())) + ->fields(['set_name' => $shortcut_set->id()]) ->execute(); drupal_static_reset('shortcut_current_displayed_set'); } @@ -93,7 +93,7 @@ public function unassignUser($account) { */ public function getAssignedToUser($account) { $query = db_select('shortcut_set_users', 'ssu'); - $query->fields('ssu', array('set_name')); + $query->fields('ssu', ['set_name']); $query->condition('ssu.uid', $account->id()); return $query->execute()->fetchField(); } @@ -102,7 +102,7 @@ public function getAssignedToUser($account) { * {@inheritdoc} */ public function countAssignedUsers(ShortcutSetInterface $shortcut_set) { - return db_query('SELECT COUNT(*) FROM {shortcut_set_users} WHERE set_name = :name', array(':name' => $shortcut_set->id()))->fetchField(); + return db_query('SELECT COUNT(*) FROM {shortcut_set_users} WHERE set_name = :name', [':name' => $shortcut_set->id()])->fetchField(); } /** @@ -113,7 +113,7 @@ public function getDefaultSet(AccountInterface $account) { // have one, we allow the last module which returns a valid result to take // precedence. If no module returns a valid set, fall back on the site-wide // default, which is the lowest-numbered shortcut set. - $suggestions = array_reverse($this->moduleHandler->invokeAll('shortcut_default_set', array($account))); + $suggestions = array_reverse($this->moduleHandler->invokeAll('shortcut_default_set', [$account])); $suggestions[] = 'default'; $shortcut_set = NULL; foreach ($suggestions as $name) { diff --git a/core/modules/shortcut/src/Tests/ShortcutTestBase.php b/core/modules/shortcut/src/Tests/ShortcutTestBase.php index b32afb29..584a6154 100644 --- a/core/modules/shortcut/src/Tests/ShortcutTestBase.php +++ b/core/modules/shortcut/src/Tests/ShortcutTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\shortcut\Tests; +@trigger_error(__NAMESPACE__ . '\ShortcutTestBase is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\shortcut\Functional\ShortcutTestBase, see https://www.drupal.org/node/2906736.', E_USER_DEPRECATED); + use Drupal\shortcut\Entity\Shortcut; use Drupal\shortcut\Entity\ShortcutSet; use Drupal\shortcut\ShortcutSetInterface; @@ -9,6 +11,11 @@ /** * Defines base class for shortcut test cases. + * + * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\shortcut\Functional\ShortcutTestBase. + * + * @see https://www.drupal.org/node/2906736 */ abstract class ShortcutTestBase extends WebTestBase { @@ -17,7 +24,7 @@ abstract class ShortcutTestBase extends WebTestBase { * * @var array */ - public static $modules = array('node', 'toolbar', 'shortcut'); + public static $modules = ['node', 'toolbar', 'shortcut']; /** * User with permission to administer shortcuts. @@ -52,37 +59,37 @@ protected function setUp() { if ($this->profile != 'standard') { // Create Basic page and Article node types. - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); // Populate the default shortcut set. - $shortcut = Shortcut::create(array( + $shortcut = Shortcut::create([ 'shortcut_set' => 'default', 'title' => t('Add content'), 'weight' => -20, - 'link' => array( + 'link' => [ 'uri' => 'internal:/node/add', - ), - )); + ], + ]); $shortcut->save(); - $shortcut = Shortcut::create(array( + $shortcut = Shortcut::create([ 'shortcut_set' => 'default', 'title' => t('All content'), 'weight' => -19, - 'link' => array( + 'link' => [ 'uri' => 'internal:/admin/content', - ), - )); + ], + ]); $shortcut->save(); } // Create users. - $this->adminUser = $this->drupalCreateUser(array('access toolbar', 'administer shortcuts', 'view the administration theme', 'create article content', 'create page content', 'access content overview', 'administer users', 'link to any page', 'edit any article content')); - $this->shortcutUser = $this->drupalCreateUser(array('customize shortcut links', 'switch shortcut sets', 'access shortcuts', 'access content')); + $this->adminUser = $this->drupalCreateUser(['access toolbar', 'administer shortcuts', 'view the administration theme', 'create article content', 'create page content', 'access content overview', 'administer users', 'link to any page', 'edit any article content']); + $this->shortcutUser = $this->drupalCreateUser(['customize shortcut links', 'switch shortcut sets', 'access shortcuts', 'access content']); // Create a node. - $this->node = $this->drupalCreateNode(array('type' => 'article')); + $this->node = $this->drupalCreateNode(['type' => 'article']); // Log in as admin and grab the default shortcut set. $this->drupalLogin($this->adminUser); @@ -93,11 +100,11 @@ protected function setUp() { /** * Creates a generic shortcut set. */ - function generateShortcutSet($label = '', $id = NULL) { - $set = ShortcutSet::create(array( + public function generateShortcutSet($label = '', $id = NULL) { + $set = ShortcutSet::create([ 'id' => isset($id) ? $id : strtolower($this->randomMachineName()), 'label' => empty($label) ? $this->randomString() : $label, - )); + ]); $set->save(); return $set; } @@ -116,8 +123,8 @@ function generateShortcutSet($label = '', $id = NULL) { * @return array * Array of the requested information from each link. */ - function getShortcutInformation(ShortcutSetInterface $set, $key) { - $info = array(); + public function getShortcutInformation(ShortcutSetInterface $set, $key) { + $info = []; \Drupal::entityManager()->getStorage('shortcut')->resetCache(); foreach ($set->getShortcuts() as $shortcut) { if ($key == 'link') { diff --git a/core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php b/core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php similarity index 93% rename from core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php rename to core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php index a437ffb0..e2d6a226 100644 --- a/core/modules/shortcut/src/Tests/ShortcutCacheTagsTest.php +++ b/core/modules/shortcut/tests/src/Functional/ShortcutCacheTagsTest.php @@ -1,6 +1,6 @@ 'default', 'title' => t('Llama'), 'weight' => 0, 'link' => [['uri' => 'internal:/admin']], - )); + ]); $shortcut->save(); return $shortcut; diff --git a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php b/core/modules/shortcut/tests/src/Functional/ShortcutLinksTest.php similarity index 89% rename from core/modules/shortcut/src/Tests/ShortcutLinksTest.php rename to core/modules/shortcut/tests/src/Functional/ShortcutLinksTest.php index 679f89bb..e39f652e 100644 --- a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php +++ b/core/modules/shortcut/tests/src/Functional/ShortcutLinksTest.php @@ -1,6 +1,6 @@ set; // Create an alias for the node so we can test aliases. - $path = array( + $path = [ 'source' => '/node/' . $this->node->id(), 'alias' => '/' . $this->randomMachineName(8), - ); + ]; $this->container->get('path.alias_storage')->save($path['source'], $path['alias']); // Create some paths to test. @@ -65,13 +68,13 @@ public function testShortcutLinkAdd() { // Check that each new shortcut links where it should. foreach ($test_cases as $test_path) { $title = $this->randomMachineName(); - $form_data = array( + $form_data = [ 'title[0][value]' => $title, 'link[0][uri]' => $test_path, - ); + ]; $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save')); $this->assertResponse(200); - $this->assertText(t('Added a shortcut for @title.', array('@title' => $title))); + $this->assertText(t('Added a shortcut for @title.', ['@title' => $title])); $saved_set = ShortcutSet::load($set->id()); $paths = $this->getShortcutInformation($saved_set, 'link'); $this->assertTrue(in_array('internal:' . $test_path, $paths), 'Shortcut created: ' . $test_path); @@ -115,10 +118,10 @@ public function testShortcutLinkAdd() { // Create a new shortcut set and add a link to it. $this->drupalLogin($this->adminUser); - $edit = array( + $edit = [ 'label' => $this->randomMachineName(), 'id' => strtolower($this->randomMachineName()), - ); + ]; $this->drupalPostForm('admin/config/user-interface/shortcut/add-set', $edit, t('Save')); $title = $this->randomMachineName(); $form_data = [ @@ -133,7 +136,7 @@ public function testShortcutLinkAdd() { * Tests that the "add to shortcut" and "remove from shortcut" links work. */ public function testShortcutQuickLink() { - \Drupal::service('theme_handler')->install(array('seven')); + \Drupal::service('theme_handler')->install(['seven']); $this->config('system.theme')->set('admin', 'seven')->save(); $this->config('node.settings')->set('use_admin_theme', '1')->save(); $this->container->get('router.builder')->rebuild(); @@ -177,7 +180,7 @@ public function testShortcutQuickLink() { $this->assertText('Added a shortcut for Create Basic page.'); // Assure that Article does not have its shortcut indicated as set. $this->drupalGet('node/add/article'); - $link = $this->xpath('//a[normalize-space()=:label]', array(':label' => 'Remove from Default shortcuts')); + $link = $this->xpath('//a[normalize-space()=:label]', [':label' => 'Remove from Default shortcuts']); $this->assertTrue(empty($link), 'Link Remove to Default shortcuts not found for Create Article page.'); // Add Shortcut for Article. $this->clickLink('Add to Default shortcuts'); @@ -198,11 +201,11 @@ public function testShortcutQuickLink() { $this->assertShortcutQuickLink('Add to Default shortcuts'); \Drupal::service('module_installer')->install(['block_content']); - BlockContentType::create(array( + BlockContentType::create([ 'id' => 'basic', 'label' => 'Basic block', 'revision' => FALSE, - ))->save(); + ])->save(); // Test page with HTML tags in title. $this->drupalGet('admin/structure/block/block-content/manage/basic'); $page_title = new FormattableMarkup('Edit %label custom block type', ['%label' => 'Basic block']); @@ -226,12 +229,12 @@ public function testShortcutLinkRename() { $shortcuts = $set->getShortcuts(); $shortcut = reset($shortcuts); - $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $new_link_name), t('Save')); + $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), ['title[0][value]' => $new_link_name], t('Save')); $saved_set = ShortcutSet::load($set->id()); $titles = $this->getShortcutInformation($saved_set, 'title'); $this->assertTrue(in_array($new_link_name, $titles), 'Shortcut renamed: ' . $new_link_name); $this->assertLink($new_link_name, 0, 'Renamed shortcut link appears on the page.'); - $this->assertText(t('The shortcut @link has been updated.', array('@link' => $new_link_name))); + $this->assertText(t('The shortcut @link has been updated.', ['@link' => $new_link_name])); } /** @@ -245,12 +248,12 @@ public function testShortcutLinkChangePath() { $shortcuts = $set->getShortcuts(); $shortcut = reset($shortcuts); - $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'link[0][uri]' => $new_link_path), t('Save')); + $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), ['title[0][value]' => $shortcut->getTitle(), 'link[0][uri]' => $new_link_path], t('Save')); $saved_set = ShortcutSet::load($set->id()); $paths = $this->getShortcutInformation($saved_set, 'link'); $this->assertTrue(in_array('internal:' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path); $this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.'); - $this->assertText(t('The shortcut @link has been updated.', array('@link' => $shortcut->getTitle()))); + $this->assertText(t('The shortcut @link has been updated.', ['@link' => $shortcut->getTitle()])); } /** @@ -277,7 +280,7 @@ public function testShortcutLinkDelete() { $shortcuts = $set->getShortcuts(); $shortcut = reset($shortcuts); - $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id() . '/delete', array(), 'Delete'); + $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id() . '/delete', [], 'Delete'); $saved_set = ShortcutSet::load($set->id()); $ids = $this->getShortcutInformation($saved_set, 'id'); $this->assertFalse(in_array($shortcut->id(), $ids), 'Successfully deleted a shortcut.'); @@ -297,7 +300,7 @@ public function testShortcutLinkDelete() { */ public function testNoShortcutLink() { // Change to a theme that displays shortcuts. - \Drupal::service('theme_handler')->install(array('seven')); + \Drupal::service('theme_handler')->install(['seven']); $this->config('system.theme') ->set('default', 'seven') ->save(); @@ -328,7 +331,7 @@ public function testNoShortcutLink() { */ public function testAccessShortcutsPermission() { // Change to a theme that displays shortcuts. - \Drupal::service('theme_handler')->install(array('seven')); + \Drupal::service('theme_handler')->install(['seven']); $this->config('system.theme') ->set('default', 'seven') ->save(); @@ -340,20 +343,20 @@ public function testAccessShortcutsPermission() { // Verify that users without the 'access shortcuts' permission can't see the // shortcuts. - $this->drupalLogin($this->drupalCreateUser(array('access toolbar'))); + $this->drupalLogin($this->drupalCreateUser(['access toolbar'])); $this->assertNoLink('Shortcuts', 'Shortcut link not found on page.'); // Verify that users without the 'administer site configuration' permission // can't see the cron shortcuts. - $this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts'))); + $this->drupalLogin($this->drupalCreateUser(['access toolbar', 'access shortcuts'])); $this->assertNoLink('Shortcuts', 'Shortcut link not found on page.'); $this->assertNoLink('Cron', 'Cron shortcut link not found on page.'); // Verify that users with the 'access shortcuts' permission can see the // shortcuts. - $this->drupalLogin($this->drupalCreateUser(array( + $this->drupalLogin($this->drupalCreateUser([ 'access toolbar', 'access shortcuts', 'administer site configuration', - ))); + ])); $this->clickLink('Shortcuts', 0, 'Shortcut link found on page.'); $this->assertLink('Cron', 0, 'Cron shortcut link found on page.'); @@ -365,18 +368,18 @@ public function testAccessShortcutsPermission() { */ public function testShortcutLinkOrder() { // Ensure to give permissions to access the shortcuts. - $this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts', 'access content overview', 'administer content types'))); + $this->drupalLogin($this->drupalCreateUser(['access toolbar', 'access shortcuts', 'access content overview', 'administer content types'])); $this->drupalGet(Url::fromRoute('')); $shortcuts = $this->cssSelect('#toolbar-item-shortcuts-tray .toolbar-menu a'); - $this->assertEqual((string) $shortcuts[0], 'Add content'); - $this->assertEqual((string) $shortcuts[1], 'All content'); + $this->assertEqual($shortcuts[0]->getText(), 'Add content'); + $this->assertEqual($shortcuts[1]->getText(), 'All content'); foreach ($this->set->getShortcuts() as $shortcut) { $shortcut->setWeight($shortcut->getWeight() * -1)->save(); } $this->drupalGet(Url::fromRoute('')); $shortcuts = $this->cssSelect('#toolbar-item-shortcuts-tray .toolbar-menu a'); - $this->assertEqual((string) $shortcuts[0], 'All content'); - $this->assertEqual((string) $shortcuts[1], 'Add content'); + $this->assertEqual($shortcuts[0]->getText(), 'All content'); + $this->assertEqual($shortcuts[1]->getText(), 'Add content'); } /** @@ -386,24 +389,24 @@ public function testShortcutLinkOrder() { private function verifyAccessShortcutsPermissionForEditPages() { // Create a user with customize links and switch sets permissions but // without the 'access shortcuts' permission. - $test_permissions = array( + $test_permissions = [ 'customize shortcut links', 'switch shortcut sets', - ); + ]; $noaccess_user = $this->drupalCreateUser($test_permissions); $this->drupalLogin($noaccess_user); // Verify that set administration pages are inaccessible without the // 'access shortcuts' permission. - $edit_paths = array( + $edit_paths = [ 'admin/config/user-interface/shortcut/manage/default/customize', 'admin/config/user-interface/shortcut/manage/default', 'user/' . $noaccess_user->id() . '/shortcuts', - ); + ]; foreach ($edit_paths as $path) { $this->drupalGet($path); - $message = format_string('Access is denied on %s', array('%s' => $path)); + $message = format_string('Access is denied on %s', ['%s' => $path]); $this->assertResponse(403, $message); } } @@ -426,7 +429,7 @@ public function testShortcutBlockAccess() { // Verify that users without the 'access shortcuts' permission can see the // shortcut block. - $this->drupalLogin($this->drupalCreateUser(array())); + $this->drupalLogin($this->drupalCreateUser([])); $this->drupalGet(''); $this->assertNoBlockAppears($block); } @@ -454,8 +457,8 @@ public function testShortcutBlockAccess() { * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertShortcutQuickLink($label, $index = 0, $message = '', $group = 'Other') { - $links = $this->xpath('//a[normalize-space()=:label]', array(':label' => $label)); - $message = ($message ? $message : SafeMarkup::format('Shortcut quick link with label %label found.', array('%label' => $label))); + $links = $this->xpath('//a[normalize-space()=:label]', [':label' => $label]); + $message = ($message ? $message : SafeMarkup::format('Shortcut quick link with label %label found.', ['%label' => $label])); return $this->assert(isset($links[$index]), $message, $group); } diff --git a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php b/core/modules/shortcut/tests/src/Functional/ShortcutSetsTest.php similarity index 88% rename from core/modules/shortcut/src/Tests/ShortcutSetsTest.php rename to core/modules/shortcut/tests/src/Functional/ShortcutSetsTest.php index 3a047573..b897df75 100644 --- a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php +++ b/core/modules/shortcut/tests/src/Functional/ShortcutSetsTest.php @@ -1,6 +1,6 @@ drupalGet('admin/config/user-interface/shortcut'); $this->clickLink(t('Add shortcut set')); - $edit = array( + $edit = [ 'label' => $this->randomMachineName(), 'id' => strtolower($this->randomMachineName()), - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); $new_set = $this->container->get('entity.manager')->getStorage('shortcut_set')->load($edit['id']); $this->assertIdentical($new_set->id(), $edit['id'], 'Successfully created a shortcut set.'); @@ -47,7 +47,7 @@ function testShortcutSetAdd() { /** * Tests editing a shortcut set. */ - function testShortcutSetEdit() { + public function testShortcutSetEdit() { $set = $this->set; $shortcuts = $set->getShortcuts(); @@ -66,14 +66,14 @@ function testShortcutSetEdit() { $this->assertEqual(count($elements), 3, 'Correct number of table header cells found.'); // Test the contents of each th cell. - $expected_items = array(t('Name'), t('Weight'), t('Operations')); + $expected_items = [t('Name'), t('Weight'), t('Operations')]; foreach ($elements as $key => $element) { - $this->assertEqual((string) $element[0], $expected_items[$key]); + $this->assertEqual($element->getText(), $expected_items[$key]); } // Look for test shortcuts in the table. $weight = count($shortcuts); - $edit = array(); + $edit = []; foreach ($shortcuts as $shortcut) { $title = $shortcut->getTitle(); @@ -100,12 +100,12 @@ function testShortcutSetEdit() { /** * Tests switching a user's own shortcut set. */ - function testShortcutSetSwitchOwn() { + public function testShortcutSetSwitchOwn() { $new_set = $this->generateShortcutSet($this->randomMachineName()); // Attempt to switch the default shortcut set to the newly created shortcut // set. - $this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', array('set' => $new_set->id()), t('Change set')); + $this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', ['set' => $new_set->id()], t('Change set')); $this->assertResponse(200); $current_set = shortcut_current_displayed_set($this->adminUser); $this->assertTrue($new_set->id() == $current_set->id(), 'Successfully switched own shortcut set.'); @@ -114,7 +114,7 @@ function testShortcutSetSwitchOwn() { /** * Tests switching another user's shortcut set. */ - function testShortcutSetAssign() { + public function testShortcutSetAssign() { $new_set = $this->generateShortcutSet($this->randomMachineName()); \Drupal::entityManager()->getStorage('shortcut_set')->assignUser($new_set, $this->shortcutUser); @@ -125,12 +125,12 @@ function testShortcutSetAssign() { /** * Tests switching a user's shortcut set and creating one at the same time. */ - function testShortcutSetSwitchCreate() { - $edit = array( + public function testShortcutSetSwitchCreate() { + $edit = [ 'set' => 'new', 'id' => strtolower($this->randomMachineName()), 'label' => $this->randomString(), - ); + ]; $this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', $edit, t('Change set')); $current_set = shortcut_current_displayed_set($this->adminUser); $this->assertNotEqual($current_set->id(), $this->set->id(), 'A shortcut set can be switched to at the same time as it is created.'); @@ -140,8 +140,8 @@ function testShortcutSetSwitchCreate() { /** * Tests switching a user's shortcut set without providing a new set name. */ - function testShortcutSetSwitchNoSetName() { - $edit = array('set' => 'new'); + public function testShortcutSetSwitchNoSetName() { + $edit = ['set' => 'new']; $this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', $edit, t('Change set')); $this->assertText(t('The new set label is required.')); $current_set = shortcut_current_displayed_set($this->adminUser); @@ -152,13 +152,13 @@ function testShortcutSetSwitchNoSetName() { /** * Tests renaming a shortcut set. */ - function testShortcutSetRename() { + public function testShortcutSetRename() { $set = $this->set; $new_label = $this->randomMachineName(); $this->drupalGet('admin/config/user-interface/shortcut'); $this->clickLink(t('Edit shortcut set')); - $this->drupalPostForm(NULL, array('label' => $new_label), t('Save')); + $this->drupalPostForm(NULL, ['label' => $new_label], t('Save')); $set = ShortcutSet::load($set->id()); $this->assertTrue($set->label() == $new_label, 'Shortcut set has been successfully renamed.'); } @@ -166,7 +166,7 @@ function testShortcutSetRename() { /** * Tests unassigning a shortcut set. */ - function testShortcutSetUnassign() { + public function testShortcutSetUnassign() { $new_set = $this->generateShortcutSet($this->randomMachineName()); $shortcut_set_storage = \Drupal::entityManager()->getStorage('shortcut_set'); @@ -180,10 +180,10 @@ function testShortcutSetUnassign() { /** * Tests deleting a shortcut set. */ - function testShortcutSetDelete() { + public function testShortcutSetDelete() { $new_set = $this->generateShortcutSet($this->randomMachineName()); - $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $new_set->id() . '/delete', array(), t('Delete')); + $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $new_set->id() . '/delete', [], t('Delete')); $sets = ShortcutSet::loadMultiple(); $this->assertFalse(isset($sets[$new_set->id()]), 'Successfully deleted a shortcut set.'); } @@ -191,7 +191,7 @@ function testShortcutSetDelete() { /** * Tests deleting the default shortcut set. */ - function testShortcutSetDeleteDefault() { + public function testShortcutSetDeleteDefault() { $this->drupalGet('admin/config/user-interface/shortcut/manage/default/delete'); $this->assertResponse(403); } @@ -199,7 +199,7 @@ function testShortcutSetDeleteDefault() { /** * Tests creating a new shortcut set with a defined set name. */ - function testShortcutSetCreateWithSetName() { + public function testShortcutSetCreateWithSetName() { $random_name = $this->randomMachineName(); $new_set = $this->generateShortcutSet($random_name, $random_name); $sets = ShortcutSet::loadMultiple(); diff --git a/core/modules/shortcut/tests/src/Functional/ShortcutTestBase.php b/core/modules/shortcut/tests/src/Functional/ShortcutTestBase.php new file mode 100644 index 00000000..3f9cc87b --- /dev/null +++ b/core/modules/shortcut/tests/src/Functional/ShortcutTestBase.php @@ -0,0 +1,133 @@ +profile != 'standard') { + // Create Basic page and Article node types. + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + + // Populate the default shortcut set. + $shortcut = Shortcut::create([ + 'shortcut_set' => 'default', + 'title' => t('Add content'), + 'weight' => -20, + 'link' => [ + 'uri' => 'internal:/node/add', + ], + ]); + $shortcut->save(); + + $shortcut = Shortcut::create([ + 'shortcut_set' => 'default', + 'title' => t('All content'), + 'weight' => -19, + 'link' => [ + 'uri' => 'internal:/admin/content', + ], + ]); + $shortcut->save(); + } + + // Create users. + $this->adminUser = $this->drupalCreateUser(['access toolbar', 'administer shortcuts', 'view the administration theme', 'create article content', 'create page content', 'access content overview', 'administer users', 'link to any page', 'edit any article content']); + $this->shortcutUser = $this->drupalCreateUser(['customize shortcut links', 'switch shortcut sets', 'access shortcuts', 'access content']); + + // Create a node. + $this->node = $this->drupalCreateNode(['type' => 'article']); + + // Log in as admin and grab the default shortcut set. + $this->drupalLogin($this->adminUser); + $this->set = ShortcutSet::load('default'); + \Drupal::entityManager()->getStorage('shortcut_set')->assignUser($this->set, $this->adminUser); + } + + /** + * Creates a generic shortcut set. + */ + public function generateShortcutSet($label = '', $id = NULL) { + $set = ShortcutSet::create([ + 'id' => isset($id) ? $id : strtolower($this->randomMachineName()), + 'label' => empty($label) ? $this->randomString() : $label, + ]); + $set->save(); + return $set; + } + + /** + * Extracts information from shortcut set links. + * + * @param \Drupal\shortcut\ShortcutSetInterface $set + * The shortcut set object to extract information from. + * @param string $key + * The array key indicating what information to extract from each link: + * - 'title': Extract shortcut titles. + * - 'link': Extract shortcut paths. + * - 'id': Extract the shortcut ID. + * + * @return array + * Array of the requested information from each link. + */ + public function getShortcutInformation(ShortcutSetInterface $set, $key) { + $info = []; + \Drupal::entityManager()->getStorage('shortcut')->resetCache(); + foreach ($set->getShortcuts() as $shortcut) { + if ($key == 'link') { + $info[] = $shortcut->link->uri; + } + else { + $info[] = $shortcut->{$key}->value; + } + } + return $info; + } + +} diff --git a/core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php b/core/modules/shortcut/tests/src/Functional/ShortcutTranslationUITest.php similarity index 78% rename from core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php rename to core/modules/shortcut/tests/src/Functional/ShortcutTranslationUITest.php index 4be41c36..83bf47a4 100644 --- a/core/modules/shortcut/src/Tests/ShortcutTranslationUITest.php +++ b/core/modules/shortcut/tests/src/Functional/ShortcutTranslationUITest.php @@ -1,6 +1,6 @@ array(array('value' => $this->randomMachineName()))) + parent::getNewEntityValues($langcode); + return ['title' => [['value' => $this->randomMachineName()]]] + parent::getNewEntityValues($langcode); } protected function doTestBasicTranslation() { @@ -71,14 +71,14 @@ protected function doTestBasicTranslation() { $entity = $storage->load($this->entityId); foreach ($this->langcodes as $langcode) { if ($entity->hasTranslation($langcode)) { - $language = new Language(array('id' => $langcode)); + $language = new Language(['id' => $langcode]); // Request the front page in this language and assert that the right // translation shows up in the shortcut list with the right path. - $this->drupalGet('', array('language' => $language)); - $expected_path = \Drupal::urlGenerator()->generateFromRoute('user.page', array(), array('language' => $language)); + $this->drupalGet('', ['language' => $language]); + $expected_path = \Drupal::urlGenerator()->generateFromRoute('user.page', [], ['language' => $language]); $label = $entity->getTranslation($langcode)->label(); - $elements = $this->xpath('//nav[contains(@class, "toolbar-lining")]/ul[@class="toolbar-menu"]/li/a[contains(@href, :href) and normalize-space(text())=:label]', array(':href' => $expected_path, ':label' => $label)); - $this->assertTrue(!empty($elements), format_string('Translated @language shortcut link @label found.', array('@label' => $label, '@language' => $language->getName()))); + $elements = $this->xpath('//nav[contains(@class, "toolbar-lining")]/ul[@class="toolbar-menu"]/li/a[contains(@href, :href) and normalize-space(text())=:label]', [':href' => $expected_path, ':label' => $label]); + $this->assertTrue(!empty($elements), format_string('Translated @language shortcut link @label found.', ['@label' => $label, '@language' => $language->getName()])); } } } @@ -96,14 +96,14 @@ protected function doTestTranslationEdit() { foreach ($this->langcodes as $langcode) { // We only want to test the title for non-english translations. if ($langcode != 'en') { - $options = array('language' => $languages[$langcode]); + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); $this->drupalGet($url); - $title = t('@title [%language translation]', array( + $title = t('@title [%language translation]', [ '@title' => $entity->getTranslation($langcode)->label(), '%language' => $languages[$langcode]->getName(), - )); + ]); $this->assertRaw($title); } } @@ -120,7 +120,7 @@ protected function doTestTranslationChanged() { $this->assertFalse( $entity instanceof EntityChangedInterface, - format_string('%entity is not implementing EntityChangedInterface.', array('%entity' => $this->entityTypeId)) + format_string('%entity is not implementing EntityChangedInterface.', ['%entity' => $this->entityTypeId]) ); } diff --git a/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetTest.php b/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetTest.php index 86582864..b6543723 100644 --- a/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetTest.php +++ b/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetTest.php @@ -18,12 +18,12 @@ class MigrateShortcutSetTest extends MigrateDrupal7TestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'link', 'field', 'shortcut', 'menu_link_content', - ); + ]; /** * {@inheritdoc} diff --git a/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetUsersTest.php b/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetUsersTest.php index 1b15dcde..ae939569 100644 --- a/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetUsersTest.php +++ b/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutSetUsersTest.php @@ -17,12 +17,12 @@ class MigrateShortcutSetUsersTest extends MigrateDrupal7TestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'link', 'field', 'shortcut', 'menu_link_content', - ); + ]; /** * {@inheritdoc} diff --git a/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutTest.php b/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutTest.php index 18f55170..e685151a 100644 --- a/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutTest.php +++ b/core/modules/shortcut/tests/src/Kernel/Migrate/d7/MigrateShortcutTest.php @@ -18,12 +18,12 @@ class MigrateShortcutTest extends MigrateDrupal7TestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'link', 'field', 'shortcut', 'menu_link_content', - ); + ]; /** * {@inheritdoc} diff --git a/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php b/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php index f85a2cf4..09b6468a 100644 --- a/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php +++ b/core/modules/shortcut/tests/src/Unit/Menu/ShortcutLocalTasksTest.php @@ -12,10 +12,10 @@ class ShortcutLocalTasksTest extends LocalTaskIntegrationTestBase { protected function setUp() { - $this->directoryList = array( + $this->directoryList = [ 'shortcut' => 'core/modules/shortcut', 'user' => 'core/modules/user', - ); + ]; parent::setUp(); } @@ -25,9 +25,9 @@ protected function setUp() { * @dataProvider getShortcutPageRoutes */ public function testShortcutPageLocalTasks($route) { - $tasks = array( - 0 => array('shortcut.set_switch', 'entity.user.canonical', 'entity.user.edit_form',), - ); + $tasks = [ + 0 => ['shortcut.set_switch', 'entity.user.canonical', 'entity.user.edit_form'], + ]; $this->assertLocalTasks($route, $tasks); } @@ -35,11 +35,11 @@ public function testShortcutPageLocalTasks($route) { * Provides a list of routes to test. */ public function getShortcutPageRoutes() { - return array( - array('entity.user.canonical'), - array('entity.user.edit_form'), - array('shortcut.set_switch'), - ); + return [ + ['entity.user.canonical'], + ['entity.user.edit_form'], + ['shortcut.set_switch'], + ]; } } diff --git a/core/modules/statistics/config/install/statistics.settings.yml b/core/modules/statistics/config/install/statistics.settings.yml index f788bece..66860629 100644 --- a/core/modules/statistics/config/install/statistics.settings.yml +++ b/core/modules/statistics/config/install/statistics.settings.yml @@ -1,5 +1,2 @@ -access_log: - enabled: false - max_lifetime: 259200 count_content_views: 0 display_max_age: 3600 diff --git a/core/modules/statistics/config/schema/statistics.schema.yml b/core/modules/statistics/config/schema/statistics.schema.yml index d5e62008..c72a2272 100644 --- a/core/modules/statistics/config/schema/statistics.schema.yml +++ b/core/modules/statistics/config/schema/statistics.schema.yml @@ -4,16 +4,6 @@ statistics.settings: type: config_object label: 'Statistics settings' mapping: - access_log: - type: mapping - label: 'Access log settings' - mapping: - enabled: - type: boolean - label: 'Enable' - max_lifetime: - type: integer - label: 'Maximum lifetime' count_content_views: type: integer label: 'Count content views' diff --git a/core/modules/statistics/migration_templates/statistics_settings.yml b/core/modules/statistics/migration_templates/statistics_settings.yml index 62c2c061..429d7e11 100644 --- a/core/modules/statistics/migration_templates/statistics_settings.yml +++ b/core/modules/statistics/migration_templates/statistics_settings.yml @@ -9,9 +9,8 @@ source: - statistics_enable_access_log - statistics_flush_accesslog_timer - statistics_count_content_views + source_module: statistics process: - 'access_log/enabled': statistics_enable_access_log - 'access_log/max_lifetime': statistics_flush_accesslog_timer 'count_content_views': statistics_count_content_views destination: plugin: config diff --git a/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php b/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php new file mode 100644 index 00000000..dcb69833 --- /dev/null +++ b/core/modules/statistics/src/NodeStatisticsDatabaseStorage.php @@ -0,0 +1,148 @@ +connection = $connection; + $this->state = $state; + $this->requestStack = $request_stack; + } + + /** + * {@inheritdoc} + */ + public function recordView($id) { + return (bool) $this->connection + ->merge('node_counter') + ->key('nid', $id) + ->fields([ + 'daycount' => 1, + 'totalcount' => 1, + 'timestamp' => $this->getRequestTime(), + ]) + ->expression('daycount', 'daycount + 1') + ->expression('totalcount', 'totalcount + 1') + ->execute(); + } + + /** + * {@inheritdoc} + */ + public function fetchViews($ids) { + $views = $this->connection + ->select('node_counter', 'nc') + ->fields('nc', ['totalcount', 'daycount', 'timestamp']) + ->condition('nid', $ids, 'IN') + ->execute() + ->fetchAll(); + foreach ($views as $id => $view) { + $views[$id] = new StatisticsViewsResult($view->totalcount, $view->daycount, $view->timestamp); + } + return $views; + } + + /** + * {@inheritdoc} + */ + public function fetchView($id) { + $views = $this->fetchViews([$id]); + return reset($views); + } + + /** + * {@inheritdoc} + */ + public function fetchAll($order = 'totalcount', $limit = 5) { + assert(in_array($order, ['totalcount', 'daycount', 'timestamp']), "Invalid order argument."); + + return $this->connection + ->select('node_counter', 'nc') + ->fields('nc', ['nid']) + ->orderBy($order, 'DESC') + ->range(0, $limit) + ->execute() + ->fetchCol(); + } + + /** + * {@inheritdoc} + */ + public function deleteViews($id) { + return (bool) $this->connection + ->delete('node_counter') + ->condition('nid', $id) + ->execute(); + } + + /** + * {@inheritdoc} + */ + public function resetDayCount() { + $statistics_timestamp = $this->state->get('statistics.day_timestamp') ?: 0; + if (($this->getRequestTime() - $statistics_timestamp) >= 86400) { + $this->state->set('statistics.day_timestamp', $this->getRequestTime()); + $this->connection->update('node_counter') + ->fields(['daycount' => 0]) + ->execute(); + } + } + + /** + * {@inheritdoc} + */ + public function maxTotalCount() { + $query = $this->connection->select('node_counter', 'nc'); + $query->addExpression('MAX(totalcount)'); + $max_total_count = (int) $query->execute()->fetchField(); + return $max_total_count; + } + + /** + * Get current request time. + * + * @return int + * Unix timestamp for current server request time. + */ + protected function getRequestTime() { + return $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME'); + } + +} diff --git a/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php index 8f4384e2..1802a456 100644 --- a/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php +++ b/core/modules/statistics/src/Plugin/Block/StatisticsPopularBlock.php @@ -4,8 +4,14 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Block\BlockBase; +use Drupal\Core\Entity\EntityRepositoryInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\RendererInterface; use Drupal\Core\Session\AccountInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\statistics\StatisticsStorageInterface; /** * Provides a 'Popular content' block. @@ -15,17 +21,82 @@ * admin_label = @Translation("Popular content") * ) */ -class StatisticsPopularBlock extends BlockBase { +class StatisticsPopularBlock extends BlockBase implements ContainerFactoryPluginInterface { + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The entity repository service. + * + * @var \Drupal\Core\Entity\EntityRepositoryInterface + */ + protected $entityRepository; + + /** + * The storage for statistics. + * + * @var \Drupal\statistics\StatisticsStorageInterface + */ + protected $statisticsStorage; + + /** + * @var \Drupal\Core\Render\RendererInterface + */ + protected $renderer; + + /** + * Constructs an StatisticsPopularBlock object. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository + * The entity repository service + * @param \Drupal\statistics\StatisticsStorageInterface $statistics_storage + * The storage for statistics. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository, StatisticsStorageInterface $statistics_storage, RendererInterface $renderer) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->entityTypeManager = $entity_type_manager; + $this->entityRepository = $entity_repository; + $this->statisticsStorage = $statistics_storage; + $this->renderer = $renderer; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_type.manager'), + $container->get('entity.repository'), + $container->get('statistics.storage.node'), + $container->get('renderer') + ); + } /** * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'top_day_num' => 0, 'top_all_num' => 0, 'top_last_num' => 0 - ); + ]; } /** @@ -40,29 +111,29 @@ protected function blockAccess(AccountInterface $account) { */ public function blockForm($form, FormStateInterface $form_state) { // Popular content block settings. - $numbers = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40); - $numbers = array('0' => $this->t('Disabled')) + array_combine($numbers, $numbers); - $form['statistics_block_top_day_num'] = array( + $numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40]; + $numbers = ['0' => $this->t('Disabled')] + array_combine($numbers, $numbers); + $form['statistics_block_top_day_num'] = [ '#type' => 'select', '#title' => $this->t("Number of day's top views to display"), '#default_value' => $this->configuration['top_day_num'], '#options' => $numbers, '#description' => $this->t('How many content items to display in "day" list.'), - ); - $form['statistics_block_top_all_num'] = array( + ]; + $form['statistics_block_top_all_num'] = [ '#type' => 'select', '#title' => $this->t('Number of all time views to display'), '#default_value' => $this->configuration['top_all_num'], '#options' => $numbers, '#description' => $this->t('How many content items to display in "all time" list.'), - ); - $form['statistics_block_top_last_num'] = array( + ]; + $form['statistics_block_top_last_num'] = [ '#type' => 'select', '#title' => $this->t('Number of most recent views to display'), '#default_value' => $this->configuration['top_last_num'], '#options' => $numbers, '#description' => $this->t('How many content items to display in "recently viewed" list.'), - ); + ]; return $form; } @@ -79,31 +150,67 @@ public function blockSubmit($form, FormStateInterface $form_state) { * {@inheritdoc} */ public function build() { - $content = array(); + $content = []; if ($this->configuration['top_day_num'] > 0) { - $result = statistics_title_list('daycount', $this->configuration['top_day_num']); - if ($result) { - $content['top_day'] = node_title_list($result, $this->t("Today's:")); + $nids = $this->statisticsStorage->fetchAll('daycount', $this->configuration['top_day_num']); + if ($nids) { + $content['top_day'] = $this->nodeTitleList($nids, $this->t("Today's:")); $content['top_day']['#suffix'] = '
    '; } } if ($this->configuration['top_all_num'] > 0) { - $result = statistics_title_list('totalcount', $this->configuration['top_all_num']); - if ($result) { - $content['top_all'] = node_title_list($result, $this->t('All time:')); + $nids = $this->statisticsStorage->fetchAll('totalcount', $this->configuration['top_all_num']); + if ($nids) { + $content['top_all'] = $this->nodeTitleList($nids, $this->t('All time:')); $content['top_all']['#suffix'] = '
    '; } } if ($this->configuration['top_last_num'] > 0) { - $result = statistics_title_list('timestamp', $this->configuration['top_last_num']); - $content['top_last'] = node_title_list($result, $this->t('Last viewed:')); + $nids = $this->statisticsStorage->fetchAll('timestamp', $this->configuration['top_last_num']); + $content['top_last'] = $this->nodeTitleList($nids, $this->t('Last viewed:')); $content['top_last']['#suffix'] = '
    '; } return $content; } + /** + * Generates the ordered array of node links for build(). + * + * @param int[] $nids + * An ordered array of node ids. + * @param string $title + * The title for the list. + * + * @return array + * A render array for the list. + */ + protected function nodeTitleList(array $nids, $title) { + $nodes = $this->entityTypeManager->getStorage('node')->loadMultiple($nids); + + $items = []; + foreach ($nids as $nid) { + $node = $this->entityRepository->getTranslationFromContext($nodes[$nid]); + $item = [ + '#type' => 'link', + '#title' => $node->getTitle(), + '#url' => $node->urlInfo('canonical'), + ]; + $this->renderer->addCacheableDependency($item, $node); + $items[] = $item; + } + + return [ + '#theme' => 'item_list__node', + '#items' => $items, + '#title' => $title, + '#cache' => [ + 'tags' => $this->entityTypeManager->getDefinition('node')->getListCacheTags(), + ], + ]; + } + } diff --git a/core/modules/statistics/src/StatisticsSettingsForm.php b/core/modules/statistics/src/StatisticsSettingsForm.php index 2abb5642..4c06e0b1 100644 --- a/core/modules/statistics/src/StatisticsSettingsForm.php +++ b/core/modules/statistics/src/StatisticsSettingsForm.php @@ -21,7 +21,7 @@ class StatisticsSettingsForm extends ConfigFormBase { protected $moduleHandler; /** - * Constructs a \Drupal\user\StatisticsSettingsForm object. + * Constructs a \Drupal\statistics\StatisticsSettingsForm object. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The factory for configuration objects. @@ -65,17 +65,17 @@ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('statistics.settings'); // Content counter settings. - $form['content'] = array( + $form['content'] = [ '#type' => 'details', '#title' => t('Content viewing counter settings'), '#open' => TRUE, - ); - $form['content']['statistics_count_content_views'] = array( + ]; + $form['content']['statistics_count_content_views'] = [ '#type' => 'checkbox', '#title' => t('Count content views'), '#default_value' => $config->get('count_content_views'), '#description' => t('Increment a counter each time content is viewed.'), - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/statistics/src/StatisticsStorageInterface.php b/core/modules/statistics/src/StatisticsStorageInterface.php new file mode 100644 index 00000000..ad6d6d5d --- /dev/null +++ b/core/modules/statistics/src/StatisticsStorageInterface.php @@ -0,0 +1,90 @@ +totalCount = $total_count; + $this->dayCount = $day_count; + $this->timestamp = $timestamp; + } + + /** + * Total number of times the entity has been viewed. + * + * @return int + */ + public function getTotalCount() { + return $this->totalCount; + } + + + /** + * Total number of times the entity has been viewed "today". + * + * @return int + */ + public function getDayCount() { + return $this->dayCount; + } + + + /** + * Timestamp of when the entity was last viewed. + * + * @return int + */ + public function getTimestamp() { + return $this->timestamp; + } + +} diff --git a/core/modules/statistics/src/Tests/StatisticsReportsTest.php b/core/modules/statistics/src/Tests/StatisticsReportsTest.php deleted file mode 100644 index 40280741..00000000 --- a/core/modules/statistics/src/Tests/StatisticsReportsTest.php +++ /dev/null @@ -1,51 +0,0 @@ -container->get('plugin.manager.block')->clearCachedDefinitions(); - - // Visit a node to have something show up in the block. - $node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->blockingUser->id())); - $this->drupalGet('node/' . $node->id()); - // Manually calling statistics.php, simulating ajax behavior. - $nid = $node->id(); - $post = http_build_query(array('nid' => $nid)); - $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); - global $base_url; - $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; - $client = \Drupal::httpClient(); - $client->post($stats_path, array('headers' => $headers, 'body' => $post)); - - // Configure and save the block. - $this->drupalPlaceBlock('statistics_popular_block', array( - 'label' => 'Popular content', - 'top_day_num' => 3, - 'top_all_num' => 3, - 'top_last_num' => 3, - )); - - // Get some page and check if the block is displayed. - $this->drupalGet('user'); - $this->assertText('Popular content', 'Found the popular content block.'); - $this->assertText("Today's", "Found today's popular content."); - $this->assertText('All time', 'Found the all time popular content.'); - $this->assertText('Last viewed', 'Found the last viewed popular content.'); - - // statistics.module doesn't use node entities, prevent the node language - // from being added to the options. - $this->assertRaw(\Drupal::l($node->label(), $node->urlInfo('canonical', ['language' => NULL])), 'Found link to visited node.'); - } - -} diff --git a/core/modules/statistics/src/Tests/StatisticsTestBase.php b/core/modules/statistics/src/Tests/StatisticsTestBase.php index b18b0ac6..4f530cf9 100644 --- a/core/modules/statistics/src/Tests/StatisticsTestBase.php +++ b/core/modules/statistics/src/Tests/StatisticsTestBase.php @@ -6,6 +6,9 @@ /** * Defines a base class for testing the Statistics module. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\statistics\Functional\StatisticsTestBase instead. */ abstract class StatisticsTestBase extends WebTestBase { @@ -14,7 +17,7 @@ abstract class StatisticsTestBase extends WebTestBase { * * @var array */ - public static $modules = array('node', 'block', 'ban', 'statistics'); + public static $modules = ['node', 'block', 'ban', 'statistics']; /** * User with permissions to ban IP's. @@ -28,18 +31,18 @@ protected function setUp() { // Create Basic page node type. if ($this->profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); } // Create user. - $this->blockingUser = $this->drupalCreateUser(array( + $this->blockingUser = $this->drupalCreateUser([ 'access administration pages', 'access site reports', 'ban IP addresses', 'administer blocks', 'administer statistics', 'administer users', - )); + ]); $this->drupalLogin($this->blockingUser); // Enable logging. diff --git a/core/modules/statistics/src/Tests/StatisticsTokenReplaceTest.php b/core/modules/statistics/src/Tests/StatisticsTokenReplaceTest.php deleted file mode 100644 index e2e4533d..00000000 --- a/core/modules/statistics/src/Tests/StatisticsTokenReplaceTest.php +++ /dev/null @@ -1,51 +0,0 @@ -getCurrentLanguage(); - - // Create user and node. - $user = $this->drupalCreateUser(array('create page content')); - $this->drupalLogin($user); - $node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $user->id())); - - // Hit the node. - $this->drupalGet('node/' . $node->id()); - // Manually calling statistics.php, simulating ajax behavior. - $nid = $node->id(); - $post = http_build_query(array('nid' => $nid)); - $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); - global $base_url; - $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; - $client = \Drupal::httpClient(); - $client->post($stats_path, array('headers' => $headers, 'body' => $post)); - $statistics = statistics_get($node->id()); - - // Generate and test tokens. - $tests = array(); - $tests['[node:total-count]'] = 1; - $tests['[node:day-count]'] = 1; - $tests['[node:last-view]'] = format_date($statistics['timestamp']); - $tests['[node:last-view:short]'] = format_date($statistics['timestamp'], 'short'); - - // Test to make sure that we generated something for each token. - $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); - - foreach ($tests as $input => $expected) { - $output = \Drupal::token()->replace($input, array('node' => $node), array('langcode' => $language_interface->getId())); - $this->assertEqual($output, $expected, format_string('Statistics token %token replaced.', array('%token' => $input))); - } - } - -} diff --git a/core/modules/statistics/src/Tests/Views/IntegrationTest.php b/core/modules/statistics/src/Tests/Views/IntegrationTest.php index 7fe99f93..18f55815 100644 --- a/core/modules/statistics/src/Tests/Views/IntegrationTest.php +++ b/core/modules/statistics/src/Tests/Views/IntegrationTest.php @@ -19,7 +19,7 @@ class IntegrationTest extends ViewTestBase { * * @var array */ - public static $modules = array('statistics', 'statistics_test_views', 'node'); + public static $modules = ['statistics', 'statistics_test_views', 'node']; /** * Stores the user object that accesses the page. @@ -40,25 +40,24 @@ class IntegrationTest extends ViewTestBase { * * @var array */ - public static $testViews = array('test_statistics_integration'); + public static $testViews = ['test_statistics_integration']; protected function setUp() { parent::setUp(); - ViewTestData::createTestViews(get_class($this), array('statistics_test_views')); + ViewTestData::createTestViews(get_class($this), ['statistics_test_views']); // Create a new user for viewing nodes and statistics. - $this->webUser = $this->drupalCreateUser(array('access content', 'view post access counter')); + $this->webUser = $this->drupalCreateUser(['access content', 'view post access counter']); // Create a new user for viewing nodes only. - $this->deniedUser = $this->drupalCreateUser(array('access content')); + $this->deniedUser = $this->drupalCreateUser(['access content']); - $this->drupalCreateContentType(array('type' => 'page')); - $this->node = $this->drupalCreateNode(array('type' => 'page')); + $this->drupalCreateContentType(['type' => 'page']); + $this->node = $this->drupalCreateNode(['type' => 'page']); - // Enable access logging. + // Enable counting of content views. $this->config('statistics.settings') - ->set('access_log.enabled', 1) ->set('count_content_views', 1) ->save(); @@ -76,7 +75,7 @@ public function testNodeCounterIntegration() { global $base_url; $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; $client = \Drupal::httpClient(); - $client->post($stats_path, array('form_params' => array('nid' => $this->node->id()))); + $client->post($stats_path, ['form_params' => ['nid' => $this->node->id()]]); $this->drupalGet('test_statistics_integration'); $expected = statistics_get($this->node->id()); diff --git a/core/modules/statistics/statistics.es6.js b/core/modules/statistics/statistics.es6.js new file mode 100644 index 00000000..666536d3 --- /dev/null +++ b/core/modules/statistics/statistics.es6.js @@ -0,0 +1,15 @@ +/** + * @file + * Statistics functionality. + */ + +(function ($, Drupal, drupalSettings) { + $(document).ready(() => { + $.ajax({ + type: 'POST', + cache: false, + url: drupalSettings.statistics.url, + data: drupalSettings.statistics.data, + }); + }); +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/statistics/statistics.info.yml b/core/modules/statistics/statistics.info.yml index 09ce91cc..f5d9693d 100644 --- a/core/modules/statistics/statistics.info.yml +++ b/core/modules/statistics/statistics.info.yml @@ -8,8 +8,8 @@ configure: statistics.settings dependencies: - node -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/statistics/statistics.install b/core/modules/statistics/statistics.install index 11c72f4a..deac9010 100644 --- a/core/modules/statistics/statistics.install +++ b/core/modules/statistics/statistics.install @@ -18,42 +18,42 @@ function statistics_uninstall() { * Implements hook_schema(). */ function statistics_schema() { - $schema['node_counter'] = array( + $schema['node_counter'] = [ 'description' => 'Access statistics for {node}s.', - 'fields' => array( - 'nid' => array( + 'fields' => [ + 'nid' => [ 'description' => 'The {node}.nid for these statistics.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'totalcount' => array( + ], + 'totalcount' => [ 'description' => 'The total number of times the {node} has been viewed.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'big', - ), - 'daycount' => array( + ], + 'daycount' => [ 'description' => 'The total number of times the {node} has been viewed today.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'medium', - ), - 'timestamp' => array( + ], + 'timestamp' => [ 'description' => 'The most recent time the {node} has been viewed.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - ), - 'primary key' => array('nid'), - ); + ], + ], + 'primary key' => ['nid'], + ]; return $schema; } @@ -63,7 +63,7 @@ function statistics_schema() { */ function statistics_update_8001() { if (!\Drupal::moduleHandler()->moduleExists('node')) { - if (\Drupal::service('module_installer')->uninstall(array('statistics'), TRUE)) { + if (\Drupal::service('module_installer')->uninstall(['statistics'], TRUE)) { return 'The statistics module depends on the node module and has therefore been uninstalled.'; } else { @@ -79,3 +79,10 @@ function statistics_update_8002() { // Set the new configuration setting for max age to the initial value. \Drupal::configFactory()->getEditable('statistics.settings')->set('display_max_age', 3600)->save(); } + +/** + * Remove access_log settings. + */ +function statistics_update_8300() { + \Drupal::configFactory()->getEditable('statistics.settings')->clear('access_log')->save(); +} diff --git a/core/modules/statistics/statistics.js b/core/modules/statistics/statistics.js index 572cd456..44c1e8e9 100644 --- a/core/modules/statistics/statistics.js +++ b/core/modules/statistics/statistics.js @@ -1,12 +1,11 @@ /** - * @file - * Statistics functionality. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - $(document).ready(function () { $.ajax({ type: 'POST', @@ -15,4 +14,4 @@ data: drupalSettings.statistics.data }); }); -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module index 68d88f5a..4d7f42a3 100644 --- a/core/modules/statistics/statistics.module +++ b/core/modules/statistics/statistics.module @@ -10,6 +10,7 @@ use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; use Drupal\node\NodeInterface; +use Drupal\statistics\StatisticsViewsResult; /** * Implements hook_help(). @@ -19,13 +20,13 @@ function statistics_help($route_name, RouteMatchInterface $route_match) { case 'help.page.statistics': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Statistics module shows you how often content is viewed. This is useful in determining which pages of your site are most popular. For more information, see the online documentation for the Statistics module.', array(':statistics_do' => 'https://www.drupal.org/documentation/modules/statistics/')) . '

    '; + $output .= '

    ' . t('The Statistics module shows you how often content is viewed. This is useful in determining which pages of your site are most popular. For more information, see the online documentation for the Statistics module.', [':statistics_do' => 'https://www.drupal.org/documentation/modules/statistics/']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Displaying popular content') . '
    '; - $output .= '
    ' . t('The module includes a Popular content block that displays the most viewed pages today and for all time, and the last content viewed. To use the block, enable Count content views on the Statistics page, and then you can enable and configure the block on the Block layout page.', array(':statistics-settings' => \Drupal::url('statistics.settings'), ':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#')) . '
    '; + $output .= '
    ' . t('The module includes a Popular content block that displays the most viewed pages today and for all time, and the last content viewed. To use the block, enable Count content views on the Statistics page, and then you can enable and configure the block on the Block layout page.', [':statistics-settings' => \Drupal::url('statistics.settings'), ':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#']) . '
    '; $output .= '
    ' . t('Page view counter') . '
    '; - $output .= '
    ' . t('The Statistics module includes a counter for each page that increases whenever the page is viewed. To use the counter, enable Count content views on the Statistics page, and set the necessary permissions (View content hits) so that the counter is visible to the users.', array(':statistics-settings' => \Drupal::url('statistics.settings'), ':permissions' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-statistics')))) . '
    '; + $output .= '
    ' . t('The Statistics module includes a counter for each page that increases whenever the page is viewed. To use the counter, enable Count content views on the Statistics page, and set the necessary permissions (View content hits) so that the counter is visible to the users.', [':statistics-settings' => \Drupal::url('statistics.settings'), ':permissions' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-statistics'])]) . '
    '; $output .= '
    '; return $output; @@ -40,7 +41,7 @@ function statistics_help($route_name, RouteMatchInterface $route_match) { function statistics_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) { if (!$node->isNew() && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) { $build['#attached']['library'][] = 'statistics/drupal.statistics'; - $settings = array('data' => array('nid' => $node->id()), 'url' => Url::fromUri('base:' . drupal_get_path('module', 'statistics') . '/statistics.php')->toString()); + $settings = ['data' => ['nid' => $node->id()], 'url' => Url::fromUri('base:' . drupal_get_path('module', 'statistics') . '/statistics.php')->toString()]; $build['#attached']['drupalSettings']['statistics'] = $settings; } } @@ -52,14 +53,14 @@ function statistics_node_links_alter(array &$links, NodeInterface $entity, array if ($context['view_mode'] != 'rss') { $links['#cache']['contexts'][] = 'user.permissions'; if (\Drupal::currentUser()->hasPermission('view post access counter')) { - $statistics = statistics_get($entity->id()); + $statistics = \Drupal::service('statistics.storage.node')->fetchView($entity->id()); if ($statistics) { - $statistics_links['statistics_counter']['title'] = \Drupal::translation()->formatPlural($statistics['totalcount'], '1 view', '@count views'); - $links['statistics'] = array( + $statistics_links['statistics_counter']['title'] = \Drupal::translation()->formatPlural($statistics->getTotalCount(), '1 view', '@count views'); + $links['statistics'] = [ '#theme' => 'links__node__statistics', '#links' => $statistics_links, - '#attributes' => array('class' => array('links', 'inline')), - ); + '#attributes' => ['class' => ['links', 'inline']], + ]; } $links['#cache']['max-age'] = \Drupal::config('statistics.settings')->get('display_max_age'); } @@ -70,18 +71,10 @@ function statistics_node_links_alter(array &$links, NodeInterface $entity, array * Implements hook_cron(). */ function statistics_cron() { - $statistics_timestamp = \Drupal::state()->get('statistics.day_timestamp') ?: 0; - - if ((REQUEST_TIME - $statistics_timestamp) >= 86400) { - // Reset day counts. - db_update('node_counter') - ->fields(array('daycount' => 0)) - ->execute(); - \Drupal::state()->set('statistics.day_timestamp', REQUEST_TIME); - } - - // Calculate the maximum of node views, for node search ranking. - \Drupal::state()->set('statistics.node_counter_scale', 1.0 / max(1.0, db_query('SELECT MAX(totalcount) FROM {node_counter}')->fetchField())); + $storage = \Drupal::service('statistics.storage.node'); + $storage->resetDayCount(); + $max_total_count = $storage->maxTotalCount(); + \Drupal::state()->set('statistics.node_counter_scale', 1.0 / max(1.0, $max_total_count)); } /** @@ -101,15 +94,15 @@ function statistics_cron() { * be executed correctly. */ function statistics_title_list($dbfield, $dbrows) { - if (in_array($dbfield, array('totalcount', 'daycount', 'timestamp'))) { + if (in_array($dbfield, ['totalcount', 'daycount', 'timestamp'])) { $query = db_select('node_field_data', 'n'); $query->addTag('node_access'); $query->join('node_counter', 's', 'n.nid = s.nid'); $query->join('users_field_data', 'u', 'n.uid = u.uid'); return $query - ->fields('n', array('nid', 'title')) - ->fields('u', array('uid', 'name')) + ->fields('n', ['nid', 'title']) + ->fields('u', ['uid', 'name']) ->condition($dbfield, 0, '<>') ->condition('n.status', 1) // @todo This should be actually filtering on the desired node status @@ -123,26 +116,27 @@ function statistics_title_list($dbfield, $dbrows) { return FALSE; } - /** * Retrieves a node's "view statistics". * - * @param int $nid - * The node ID. - * - * @return array - * An associative array containing: - * - totalcount: Integer for the total number of times the node has been - * viewed. - * - daycount: Integer for the total number of times the node has been viewed - * "today". For the daycount to be reset, cron must be enabled. - * - timestamp: Integer for the timestamp of when the node was last viewed. + * @deprecated in Drupal 8.2.x, will be removed before Drupal 9.0.0. + * Use \Drupal::service('statistics.storage.node')->fetchView($id). */ -function statistics_get($nid) { - - if ($nid > 0) { - // Retrieve an array with both totalcount and daycount. - return db_query('SELECT totalcount, daycount, timestamp FROM {node_counter} WHERE nid = :nid', array(':nid' => $nid), array('target' => 'replica'))->fetchAssoc(); +function statistics_get($id) { + if ($id > 0) { + /** @var \Drupal\statistics\StatisticsViewsResult $statistics */ + $statistics = \Drupal::service('statistics.storage.node')->fetchView($id); + + // For backwards compatibility, return FALSE if an invalid node ID was + // passed in. + if (!($statistics instanceof StatisticsViewsResult)) { + return FALSE; + } + return [ + 'totalcount' => $statistics->getTotalCount(), + 'daycount' => $statistics->getDayCount(), + 'timestamp' => $statistics->getTimestamp(), + ]; } } @@ -151,9 +145,8 @@ function statistics_get($nid) { */ function statistics_node_predelete(EntityInterface $node) { // Clean up statistics table when node is deleted. - db_delete('node_counter') - ->condition('nid', $node->id()) - ->execute(); + $id = $node->id(); + return \Drupal::service('statistics.storage.node')->deleteViews($id); } /** @@ -161,15 +154,15 @@ function statistics_node_predelete(EntityInterface $node) { */ function statistics_ranking() { if (\Drupal::config('statistics.settings')->get('count_content_views')) { - return array( - 'views' => array( + return [ + 'views' => [ 'title' => t('Number of views'), - 'join' => array( + 'join' => [ 'type' => 'LEFT', 'table' => 'node_counter', 'alias' => 'node_counter', 'on' => 'node_counter.nid = i.sid', - ), + ], // Inverse law that maps the highest view count on the site to 1 and 0 // to 0. Note that the ROUND here is necessary for PostgreSQL and SQLite // in order to ensure that the :statistics_scale argument is treated as @@ -177,9 +170,9 @@ function statistics_ranking() { // values in as strings instead of numbers in complex expressions like // this. 'score' => '2.0 - 2.0 / (1.0 + node_counter.totalcount * (ROUND(:statistics_scale, 4)))', - 'arguments' => array(':statistics_scale' => \Drupal::state()->get('statistics.node_counter_scale') ?: 0), - ), - ); + 'arguments' => [':statistics_scale' => \Drupal::state()->get('statistics.node_counter_scale') ?: 0], + ], + ]; } } diff --git a/core/modules/statistics/statistics.php b/core/modules/statistics/statistics.php index a79af5f0..a43509ea 100644 --- a/core/modules/statistics/statistics.php +++ b/core/modules/statistics/statistics.php @@ -14,8 +14,9 @@ $kernel = DrupalKernel::createFromRequest(Request::createFromGlobals(), $autoloader, 'prod'); $kernel->boot(); +$container = $kernel->getContainer(); -$views = $kernel->getContainer() +$views = $container ->get('config.factory') ->get('statistics.settings') ->get('count_content_views'); @@ -23,15 +24,7 @@ if ($views) { $nid = filter_input(INPUT_POST, 'nid', FILTER_VALIDATE_INT); if ($nid) { - \Drupal::database()->merge('node_counter') - ->key('nid', $nid) - ->fields(array( - 'daycount' => 1, - 'totalcount' => 1, - 'timestamp' => REQUEST_TIME, - )) - ->expression('daycount', 'daycount + 1') - ->expression('totalcount', 'totalcount + 1') - ->execute(); + $container->get('request_stack')->push(Request::createFromGlobals()); + $container->get('statistics.storage.node')->recordView($nid); } } diff --git a/core/modules/statistics/statistics.services.yml b/core/modules/statistics/statistics.services.yml new file mode 100644 index 00000000..cf155730 --- /dev/null +++ b/core/modules/statistics/statistics.services.yml @@ -0,0 +1,6 @@ +services: + statistics.storage.node: + class: Drupal\statistics\NodeStatisticsDatabaseStorage + arguments: ['@database', '@state', '@request_stack'] + tags: + - { name: backend_overridable } diff --git a/core/modules/statistics/statistics.tokens.inc b/core/modules/statistics/statistics.tokens.inc index e9d8ded4..96500b89 100644 --- a/core/modules/statistics/statistics.tokens.inc +++ b/core/modules/statistics/statistics.tokens.inc @@ -11,23 +11,23 @@ use Drupal\Core\Render\BubbleableMetadata; * Implements hook_token_info(). */ function statistics_token_info() { - $node['total-count'] = array( + $node['total-count'] = [ 'name' => t("Number of views"), 'description' => t("The number of visitors who have read the node."), - ); - $node['day-count'] = array( + ]; + $node['day-count'] = [ 'name' => t("Views today"), 'description' => t("The number of visitors who have read the node today."), - ); - $node['last-view'] = array( + ]; + $node['last-view'] = [ 'name' => t("Last view"), 'description' => t("The date on which a visitor last read the node."), 'type' => 'date', - ); + ]; - return array( - 'tokens' => array('node' => $node), - ); + return [ + 'tokens' => ['node' => $node], + ]; } /** @@ -36,7 +36,7 @@ function statistics_token_info() { function statistics_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { $token_service = \Drupal::token(); - $replacements = array(); + $replacements = []; if ($type == 'node' & !empty($data['node'])) { $node = $data['node']; @@ -58,7 +58,7 @@ function statistics_tokens($type, $tokens, array $data, array $options, Bubbleab if ($created_tokens = $token_service->findWithPrefix($tokens, 'last-view')) { $statistics = statistics_get($node->id()); - $replacements += $token_service->generate('date', $created_tokens, array('date' => $statistics['timestamp']), $options, $bubbleable_metadata); + $replacements += $token_service->generate('date', $created_tokens, ['date' => $statistics['timestamp']], $options, $bubbleable_metadata); } } diff --git a/core/modules/statistics/statistics.views.inc b/core/modules/statistics/statistics.views.inc index e8512518..03e73ffc 100644 --- a/core/modules/statistics/statistics.views.inc +++ b/core/modules/statistics/statistics.views.inc @@ -11,66 +11,66 @@ function statistics_views_data() { $data['node_counter']['table']['group'] = t('Content statistics'); - $data['node_counter']['table']['join'] = array( - 'node_field_data' => array( + $data['node_counter']['table']['join'] = [ + 'node_field_data' => [ 'left_field' => 'nid', 'field' => 'nid', - ), - ); + ], + ]; - $data['node_counter']['totalcount'] = array( + $data['node_counter']['totalcount'] = [ 'title' => t('Total views'), 'help' => t('The total number of times the node has been viewed.'), - 'field' => array( + 'field' => [ 'id' => 'statistics_numeric', 'click sortable' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'numeric', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); + ], + ]; - $data['node_counter']['daycount'] = array( + $data['node_counter']['daycount'] = [ 'title' => t('Views today'), 'help' => t('The total number of times the node has been viewed today.'), - 'field' => array( + 'field' => [ 'id' => 'statistics_numeric', 'click sortable' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'numeric', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); + ], + ]; - $data['node_counter']['timestamp'] = array( + $data['node_counter']['timestamp'] = [ 'title' => t('Most recent view'), 'help' => t('The most recent time the node has been viewed.'), - 'field' => array( + 'field' => [ 'id' => 'node_counter_timestamp', 'click sortable' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'date', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'date', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'standard', - ), - ); + ], + ]; return $data; } diff --git a/core/modules/statistics/tests/modules/statistics_test_views/statistics_test_views.info.yml b/core/modules/statistics/tests/modules/statistics_test_views/statistics_test_views.info.yml index 31c4c6d8..70457d66 100644 --- a/core/modules/statistics/tests/modules/statistics_test_views/statistics_test_views.info.yml +++ b/core/modules/statistics/tests/modules/statistics_test_views/statistics_test_views.info.yml @@ -8,8 +8,8 @@ dependencies: - statistics - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/statistics/src/Tests/StatisticsAdminTest.php b/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php similarity index 78% rename from core/modules/statistics/src/Tests/StatisticsAdminTest.php rename to core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php index 6d87fd97..f4c22bd8 100644 --- a/core/modules/statistics/src/Tests/StatisticsAdminTest.php +++ b/core/modules/statistics/tests/src/Functional/StatisticsAdminTest.php @@ -1,22 +1,25 @@ profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); } - $this->privilegedUser = $this->drupalCreateUser(array('administer statistics', 'view post access counter', 'create page content')); + $this->privilegedUser = $this->drupalCreateUser(['administer statistics', 'view post access counter', 'create page content']); $this->drupalLogin($this->privilegedUser); - $this->testNode = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->privilegedUser->id())); + $this->testNode = $this->drupalCreateNode(['type' => 'page', 'uid' => $this->privilegedUser->id()]); $this->client = \Drupal::httpClient(); } /** * Verifies that the statistics settings page works. */ - function testStatisticsSettings() { + public function testStatisticsSettings() { $config = $this->config('statistics.settings'); $this->assertFalse($config->get('count_content_views'), 'Count content view log is disabled by default.'); @@ -72,19 +75,19 @@ function testStatisticsSettings() { $this->drupalGet('node/' . $this->testNode->id()); // Manually calling statistics.php, simulating ajax behavior. $nid = $this->testNode->id(); - $post = array('nid' => $nid); + $post = ['nid' => $nid]; global $base_url; $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); // Hit the node again (the counter is incremented after the hit, so // "1 view" will actually be shown when the node is hit the second time). $this->drupalGet('node/' . $this->testNode->id()); - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); $this->assertText('1 view', 'Node is viewed once.'); $this->drupalGet('node/' . $this->testNode->id()); - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); $this->assertText('2 views', 'Node is viewed 2 times.'); // Increase the max age to test that nodes are no longer immediately @@ -93,7 +96,7 @@ function testStatisticsSettings() { $this->drupalGet('node/' . $this->testNode->id()); $this->assertText('3 views', 'Node is viewed 3 times.'); - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); $this->drupalGet('node/' . $this->testNode->id()); $this->assertText('3 views', 'Views counter was not updated.'); } @@ -101,19 +104,19 @@ function testStatisticsSettings() { /** * Tests that when a node is deleted, the node counter is deleted too. */ - function testDeleteNode() { + public function testDeleteNode() { $this->config('statistics.settings')->set('count_content_views', 1)->save(); $this->drupalGet('node/' . $this->testNode->id()); // Manually calling statistics.php, simulating ajax behavior. $nid = $this->testNode->id(); - $post = array('nid' => $nid); + $post = ['nid' => $nid]; global $base_url; $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); $result = db_select('node_counter', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->condition('n.nid', $this->testNode->id()) ->execute() ->fetchAssoc(); @@ -122,7 +125,7 @@ function testDeleteNode() { $this->testNode->delete(); $result = db_select('node_counter', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->condition('n.nid', $this->testNode->id()) ->execute() ->fetchAssoc(); @@ -132,7 +135,7 @@ function testDeleteNode() { /** * Tests that cron clears day counts and expired access logs. */ - function testExpiredLogs() { + public function testExpiredLogs() { $this->config('statistics.settings') ->set('count_content_views', 1) ->save(); @@ -141,12 +144,12 @@ function testExpiredLogs() { $this->drupalGet('node/' . $this->testNode->id()); // Manually calling statistics.php, simulating ajax behavior. $nid = $this->testNode->id(); - $post = array('nid' => $nid); + $post = ['nid' => $nid]; global $base_url; $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); $this->drupalGet('node/' . $this->testNode->id()); - $this->client->post($stats_path, array('form_params' => $post)); + $this->client->post($stats_path, ['form_params' => $post]); $this->assertText('1 view', 'Node is viewed once.'); // statistics_cron() will subtract @@ -160,7 +163,7 @@ function testExpiredLogs() { $this->assertNoText('node/' . $this->testNode->id(), 'No hit URL found.'); $result = db_select('node_counter', 'nc') - ->fields('nc', array('daycount')) + ->fields('nc', ['daycount']) ->condition('nid', $this->testNode->id(), '=') ->execute() ->fetchField(); diff --git a/core/modules/statistics/src/Tests/StatisticsAttachedTest.php b/core/modules/statistics/tests/src/Functional/StatisticsAttachedTest.php similarity index 82% rename from core/modules/statistics/src/Tests/StatisticsAttachedTest.php rename to core/modules/statistics/tests/src/Functional/StatisticsAttachedTest.php index f869b2a8..787c35bf 100644 --- a/core/modules/statistics/src/Tests/StatisticsAttachedTest.php +++ b/core/modules/statistics/tests/src/Functional/StatisticsAttachedTest.php @@ -1,8 +1,8 @@ install(array($theme)); + \Drupal::service('theme_handler')->install([$theme]); $this->config('system.theme') ->set('default', $theme) ->save(); diff --git a/core/modules/statistics/src/Tests/StatisticsLoggingTest.php b/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php similarity index 76% rename from core/modules/statistics/src/Tests/StatisticsLoggingTest.php rename to core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php index 9aa3cc3f..09565aef 100644 --- a/core/modules/statistics/src/Tests/StatisticsLoggingTest.php +++ b/core/modules/statistics/tests/src/Functional/StatisticsLoggingTest.php @@ -1,8 +1,9 @@ profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); } - $this->authUser = $this->drupalCreateUser(array( + $this->authUser = $this->drupalCreateUser([ // For node creation. 'access content', 'create page content', @@ -58,21 +59,21 @@ protected function setUp() { // For language negotiation administration. 'administer languages', 'access administration pages', - )); + ]); // Ensure we have a node page to access. - $this->node = $this->drupalCreateNode(array('title' => $this->randomMachineName(255), 'uid' => $this->authUser->id())); + $this->node = $this->drupalCreateNode(['title' => $this->randomMachineName(255), 'uid' => $this->authUser->id()]); // Add a custom language and enable path-based language negotiation. $this->drupalLogin($this->authUser); - $this->language = array( + $this->language = [ 'predefined_langcode' => 'custom', 'langcode' => 'xx', 'label' => $this->randomMachineName(16), 'direction' => 'ltr', - ); + ]; $this->drupalPostForm('admin/config/regional/language/add', $this->language, t('Add custom language')); - $this->drupalPostForm('admin/config/regional/language/detection', array('language_interface[enabled][language-url]' => 1), t('Save settings')); + $this->drupalPostForm('admin/config/regional/language/detection', ['language_interface[enabled][language-url]' => 1], t('Save settings')); $this->drupalLogout(); // Enable access logging. @@ -88,7 +89,7 @@ protected function setUp() { /** * Verifies node hit counter logging and script placement. */ - function testLogging() { + public function testLogging() { $path = 'node/' . $this->node->id(); $module_path = drupal_get_path('module', 'statistics'); $stats_path = base_path() . $module_path . '/statistics.php'; @@ -121,10 +122,21 @@ function testLogging() { // Manually call statistics.php to simulate ajax data collection behavior. global $base_root; - $post = array('nid' => $this->node->id()); - $this->client->post($base_root . $stats_path, array('form_params' => $post)); + $post = ['nid' => $this->node->id()]; + $this->client->post($base_root . $stats_path, ['form_params' => $post]); $node_counter = statistics_get($this->node->id()); $this->assertIdentical($node_counter['totalcount'], '1'); + + // Try fetching statistics for an invalid node ID and verify it returns + // FALSE. + $node_id = 1000000; + $node = Node::load($node_id); + $this->assertNull($node); + + // This is a test specifically for the deprecated statistics_get() function + // and so should remain unconverted until that function is removed. + $result = statistics_get($node_id); + $this->assertIdentical($result, FALSE); } } diff --git a/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php new file mode 100644 index 00000000..0f169238 --- /dev/null +++ b/core/modules/statistics/tests/src/Functional/StatisticsReportsTest.php @@ -0,0 +1,63 @@ +container->get('plugin.manager.block')->clearCachedDefinitions(); + + // Visit a node to have something show up in the block. + $node = $this->drupalCreateNode(['type' => 'page', 'uid' => $this->blockingUser->id()]); + $this->drupalGet('node/' . $node->id()); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $node->id(); + $post = http_build_query(['nid' => $nid]); + $headers = ['Content-Type' => 'application/x-www-form-urlencoded']; + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; + $client = \Drupal::httpClient(); + $client->post($stats_path, ['headers' => $headers, 'body' => $post]); + + // Configure and save the block. + $block = $this->drupalPlaceBlock('statistics_popular_block', [ + 'label' => 'Popular content', + 'top_day_num' => 3, + 'top_all_num' => 3, + 'top_last_num' => 3, + ]); + + // Get some page and check if the block is displayed. + $this->drupalGet('user'); + $this->assertText('Popular content', 'Found the popular content block.'); + $this->assertText("Today's", "Found today's popular content."); + $this->assertText('All time', 'Found the all time popular content.'); + $this->assertText('Last viewed', 'Found the last viewed popular content.'); + + $tags = Cache::mergeTags($node->getCacheTags(), $block->getCacheTags()); + $tags = Cache::mergeTags($tags, $this->blockingUser->getCacheTags()); + $tags = Cache::mergeTags($tags, ['block_view', 'config:block_list', 'node_list', 'rendered', 'user_view']); + $this->assertCacheTags($tags); + $contexts = Cache::mergeContexts($node->getCacheContexts(), $block->getCacheContexts()); + $contexts = Cache::mergeContexts($contexts, ['url.query_args:_wrapper_format']); + $this->assertCacheContexts($contexts); + + // Check if the node link is displayed. + $this->assertRaw(\Drupal::l($node->label(), $node->urlInfo('canonical')), 'Found link to visited node.'); + } + +} diff --git a/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php b/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php new file mode 100644 index 00000000..3be95e2a --- /dev/null +++ b/core/modules/statistics/tests/src/Functional/StatisticsTestBase.php @@ -0,0 +1,51 @@ +profile != 'standard') { + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + } + + // Create user. + $this->blockingUser = $this->drupalCreateUser([ + 'access administration pages', + 'access site reports', + 'ban IP addresses', + 'administer blocks', + 'administer statistics', + 'administer users', + ]); + $this->drupalLogin($this->blockingUser); + + // Enable logging. + $this->config('statistics.settings') + ->set('count_content_views', 1) + ->save(); + } + +} diff --git a/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php new file mode 100644 index 00000000..8402d221 --- /dev/null +++ b/core/modules/statistics/tests/src/Functional/StatisticsTokenReplaceTest.php @@ -0,0 +1,51 @@ +getCurrentLanguage(); + + // Create user and node. + $user = $this->drupalCreateUser(['create page content']); + $this->drupalLogin($user); + $node = $this->drupalCreateNode(['type' => 'page', 'uid' => $user->id()]); + + // Hit the node. + $this->drupalGet('node/' . $node->id()); + // Manually calling statistics.php, simulating ajax behavior. + $nid = $node->id(); + $post = http_build_query(['nid' => $nid]); + $headers = ['Content-Type' => 'application/x-www-form-urlencoded']; + global $base_url; + $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; + $client = \Drupal::httpClient(); + $client->post($stats_path, ['headers' => $headers, 'body' => $post]); + $statistics = statistics_get($node->id()); + + // Generate and test tokens. + $tests = []; + $tests['[node:total-count]'] = 1; + $tests['[node:day-count]'] = 1; + $tests['[node:last-view]'] = format_date($statistics['timestamp']); + $tests['[node:last-view:short]'] = format_date($statistics['timestamp'], 'short'); + + // Test to make sure that we generated something for each token. + $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); + + foreach ($tests as $input => $expected) { + $output = \Drupal::token()->replace($input, ['node' => $node], ['langcode' => $language_interface->getId()]); + $this->assertEqual($output, $expected, format_string('Statistics token %token replaced.', ['%token' => $input])); + } + } + +} diff --git a/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php b/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php index 401a5e82..a9c18a73 100644 --- a/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php +++ b/core/modules/statistics/tests/src/Kernel/Migrate/d6/MigrateStatisticsConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\statistics\Kernel\Migrate\d6; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** @@ -17,7 +17,7 @@ class MigrateStatisticsConfigsTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('statistics'); + public static $modules = ['statistics']; /** * {@inheritdoc} @@ -32,9 +32,7 @@ protected function setUp() { */ public function testStatisticsSettings() { $config = $this->config('statistics.settings'); - $this->assertIdentical(FALSE, $config->get('access_log.enabled')); - $this->assertIdentical(259200, $config->get('access_log.max_lifetime')); - $this->assertIdentical(0, $config->get('count_content_views')); + $this->assertSame(1, $config->get('count_content_views')); $this->assertConfigSchema(\Drupal::service('config.typed'), 'statistics.settings', $config->get()); } diff --git a/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php b/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php index e5d3310a..36e270d8 100644 --- a/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php +++ b/core/modules/statistics/tests/src/Kernel/Migrate/d7/MigrateStatisticsConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\statistics\Kernel\Migrate\d7; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; /** @@ -17,7 +17,7 @@ class MigrateStatisticsConfigsTest extends MigrateDrupal7TestBase { /** * {@inheritdoc} */ - public static $modules = array('statistics'); + public static $modules = ['statistics']; /** * {@inheritdoc} @@ -32,8 +32,6 @@ protected function setUp() { */ public function testStatisticsSettings() { $config = $this->config('statistics.settings'); - $this->assertIdentical(TRUE, $config->get('access_log.enabled')); - $this->assertIdentical(3600, $config->get('access_log.max_lifetime')); $this->assertIdentical(1, $config->get('count_content_views')); $this->assertConfigSchema(\Drupal::service('config.typed'), 'statistics.settings', $config->get()); } diff --git a/core/modules/statistics/tests/themes/statistics_test_attached/statistics_test_attached.info.yml b/core/modules/statistics/tests/themes/statistics_test_attached/statistics_test_attached.info.yml index de5de0db..d59d65d2 100644 --- a/core/modules/statistics/tests/themes/statistics_test_attached/statistics_test_attached.info.yml +++ b/core/modules/statistics/tests/themes/statistics_test_attached/statistics_test_attached.info.yml @@ -4,8 +4,8 @@ description: 'Theme for testing attached library' # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/syslog/config/install/syslog.settings.yml b/core/modules/syslog/config/install/syslog.settings.yml index 1aa5b908..396b7517 100644 --- a/core/modules/syslog/config/install/syslog.settings.yml +++ b/core/modules/syslog/config/install/syslog.settings.yml @@ -1,3 +1,6 @@ identity: drupal -facility: '' +# The default facility setting depends on the operating system, and will be +# overwritten during installation. +# @see syslog_install(). +facility: 8 format: '!base_url|!timestamp|!type|!ip|!request_uri|!referer|!uid|!link|!message' diff --git a/core/modules/syslog/config/schema/syslog.schema.yml b/core/modules/syslog/config/schema/syslog.schema.yml index 5d2707a5..f980828f 100644 --- a/core/modules/syslog/config/schema/syslog.schema.yml +++ b/core/modules/syslog/config/schema/syslog.schema.yml @@ -8,7 +8,7 @@ syslog.settings: type: string label: 'Identity' facility: - type: string + type: integer label: 'Facility' format: type: string diff --git a/core/modules/syslog/migration_templates/d6_syslog_settings.yml b/core/modules/syslog/migration_templates/d6_syslog_settings.yml index 86a7017d..5426271b 100644 --- a/core/modules/syslog/migration_templates/d6_syslog_settings.yml +++ b/core/modules/syslog/migration_templates/d6_syslog_settings.yml @@ -7,6 +7,7 @@ source: variables: - syslog_identity - syslog_facility + source_module: syslog process: identity: syslog_identity facility: syslog_facility diff --git a/core/modules/syslog/migration_templates/d7_syslog_settings.yml b/core/modules/syslog/migration_templates/d7_syslog_settings.yml index 40005722..357b38a6 100644 --- a/core/modules/syslog/migration_templates/d7_syslog_settings.yml +++ b/core/modules/syslog/migration_templates/d7_syslog_settings.yml @@ -8,6 +8,7 @@ source: - syslog_facility - syslog_format - syslog_identity + source_module: syslog process: facility: syslog_facility format: syslog_format diff --git a/core/modules/syslog/src/Logger/SysLog.php b/core/modules/syslog/src/Logger/SysLog.php index 002ecde5..22b14fac 100644 --- a/core/modules/syslog/src/Logger/SysLog.php +++ b/core/modules/syslog/src/Logger/SysLog.php @@ -53,9 +53,6 @@ public function __construct(ConfigFactoryInterface $config_factory, LogMessagePa protected function openConnection() { if (!$this->connectionOpened) { $facility = $this->config->get('facility'); - if ($facility === '') { - $facility = defined('LOG_LOCAL0') ? LOG_LOCAL0 : LOG_USER; - } $this->connectionOpened = openlog($this->config->get('identity'), LOG_NDELAY, $facility); } } @@ -63,7 +60,7 @@ protected function openConnection() { /** * {@inheritdoc} */ - public function log($level, $message, array $context = array()) { + public function log($level, $message, array $context = []) { global $base_url; // Ensure we have a connection available. @@ -73,7 +70,7 @@ public function log($level, $message, array $context = array()) { $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context); $message = empty($message_placeholders) ? $message : strtr($message, $message_placeholders); - $entry = strtr($this->config->get('format'), array( + $entry = strtr($this->config->get('format'), [ '!base_url' => $base_url, '!timestamp' => $context['timestamp'], '!type' => $context['channel'], @@ -83,8 +80,20 @@ public function log($level, $message, array $context = array()) { '!uid' => $context['uid'], '!link' => strip_tags($context['link']), '!message' => strip_tags($message), - )); + ]); + $this->syslogWrapper($level, $entry); + } + + /** + * A syslog wrapper to make syslog functionality testable. + * + * @param int $level + * The syslog priority. + * @param string $entry + * The message to send to syslog function. + */ + protected function syslogWrapper($level, $entry) { syslog($level, $entry); } diff --git a/core/modules/syslog/src/Tests/SyslogTest.php b/core/modules/syslog/src/Tests/SyslogTest.php deleted file mode 100644 index a40847c2..00000000 --- a/core/modules/syslog/src/Tests/SyslogTest.php +++ /dev/null @@ -1,41 +0,0 @@ -drupalCreateUser(array('administer site configuration')); - $this->drupalLogin($admin_user); - - // If we're on Windows, there is no configuration form. - if (defined('LOG_LOCAL6')) { - $this->drupalPostForm('admin/config/development/logging', array('syslog_facility' => LOG_LOCAL6), t('Save configuration')); - $this->assertText(t('The configuration options have been saved.')); - - $this->drupalGet('admin/config/development/logging'); - if ($this->parse()) { - $field = $this->xpath('//option[@value=:value]', array(':value' => LOG_LOCAL6)); // Should be one field. - $this->assertTrue($field[0]['selected'] == 'selected', 'Facility value saved.'); - } - } - } - -} diff --git a/core/modules/syslog/syslog.info.yml b/core/modules/syslog/syslog.info.yml index 51622593..edfc6034 100644 --- a/core/modules/syslog/syslog.info.yml +++ b/core/modules/syslog/syslog.info.yml @@ -6,8 +6,8 @@ package: Core # core: 8.x configure: system.logging_settings -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/syslog/syslog.install b/core/modules/syslog/syslog.install index e3377c8a..f0ce5cc6 100644 --- a/core/modules/syslog/syslog.install +++ b/core/modules/syslog/syslog.install @@ -13,3 +13,12 @@ function syslog_install() { // to be set dynamically during installation. \Drupal::configFactory()->getEditable('syslog.settings')->set('facility', defined('LOG_LOCAL0') ? LOG_LOCAL0 : LOG_USER)->save(); } + +/** + * Convert syslog.settings.facility to an integer. + */ +function syslog_update_8400() { + $config = \Drupal::configFactory()->getEditable('syslog.settings'); + $facility = (int) $config->get('facility'); + $config->set('facility', $facility)->save(TRUE); +} diff --git a/core/modules/syslog/syslog.module b/core/modules/syslog/syslog.module index 68fe6145..2722702d 100644 --- a/core/modules/syslog/syslog.module +++ b/core/modules/syslog/syslog.module @@ -17,7 +17,7 @@ function syslog_help($route_name, RouteMatchInterface $route_match) { case 'help.page.syslog': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Syslog module logs events by sending messages to the logging facility of your web server\'s operating system. Syslog is an operating system administrative logging tool that provides valuable information for use in system management and security auditing. Most suited to medium and large sites, Syslog provides filtering tools that allow messages to be routed by type and severity. For more information, see the online documentation for the Syslog module, as well as PHP\'s documentation pages for the openlog and syslog functions.', array(':syslog' => 'https://www.drupal.org/documentation/modules/syslog')) . '

    '; + $output .= '

    ' . t('The Syslog module logs events by sending messages to the logging facility of your web server\'s operating system. Syslog is an operating system administrative logging tool that provides valuable information for use in system management and security auditing. Most suited to medium and large sites, Syslog provides filtering tools that allow messages to be routed by type and severity. For more information, see the online documentation for the Syslog module, as well as PHP\'s documentation pages for the openlog and syslog functions.', [':syslog' => 'https://www.drupal.org/documentation/modules/syslog']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Logging for UNIX, Linux, and Mac OS X') . '
    '; @@ -35,27 +35,27 @@ function syslog_help($route_name, RouteMatchInterface $route_match) { function syslog_form_system_logging_settings_alter(&$form, FormStateInterface $form_state) { $config = \Drupal::configFactory()->getEditable('syslog.settings'); $help = \Drupal::moduleHandler()->moduleExists('help') ? ' ' . \Drupal::l(t('More information'), new Url('help.page', ['name' => 'syslog'])) . '.' : NULL; - $form['syslog_identity'] = array( + $form['syslog_identity'] = [ '#type' => 'textfield', '#title' => t('Syslog identity'), '#default_value' => $config->get('identity'), '#description' => t('A string that will be prepended to every message logged to Syslog. If you have multiple sites logging to the same Syslog log file, a unique identity per site makes it easy to tell the log entries apart.') . $help, - ); + ]; if (defined('LOG_LOCAL0')) { - $form['syslog_facility'] = array( + $form['syslog_facility'] = [ '#type' => 'select', '#title' => t('Syslog facility'), '#default_value' => $config->get('facility'), '#options' => syslog_facility_list(), '#description' => t('Depending on the system configuration, Syslog and other logging tools use this code to identify or filter messages from within the entire system log.') . $help, - ); + ]; } - $form['syslog_format'] = array( + $form['syslog_format'] = [ '#type' => 'textarea', '#title' => t('Syslog format'), '#default_value' => $config->get('format'), '#description' => t('Specify the format of the syslog entry. Available variables are:
    !base_url
    Base URL of the site.
    !timestamp
    Unix timestamp of the log entry.
    !type
    The category to which this message belongs.
    !ip
    IP address of the user triggering the message.
    !request_uri
    The requested URI.
    !referer
    HTTP Referer if available.
    !uid
    User ID.
    !link
    A link to associate with the message.
    !message
    The message to store in the log.
    '), - ); + ]; $form['#submit'][] = 'syslog_logging_settings_submit'; } @@ -80,7 +80,7 @@ function syslog_logging_settings_submit($form, FormStateInterface $form_state) { * An array of syslog facilities for UNIX/Linux. */ function syslog_facility_list() { - return array( + return [ LOG_LOCAL0 => 'LOG_LOCAL0', LOG_LOCAL1 => 'LOG_LOCAL1', LOG_LOCAL2 => 'LOG_LOCAL2', @@ -89,5 +89,5 @@ function syslog_facility_list() { LOG_LOCAL5 => 'LOG_LOCAL5', LOG_LOCAL6 => 'LOG_LOCAL6', LOG_LOCAL7 => 'LOG_LOCAL7', - ); + ]; } diff --git a/core/modules/syslog/tests/modules/syslog_test/src/Logger/SysLogTest.php b/core/modules/syslog/tests/modules/syslog_test/src/Logger/SysLogTest.php new file mode 100644 index 00000000..c7abeb04 --- /dev/null +++ b/core/modules/syslog/tests/modules/syslog_test/src/Logger/SysLogTest.php @@ -0,0 +1,21 @@ +realpath('public://syslog.log'); + error_log($entry . PHP_EOL, 3, $log_path); + } + +} diff --git a/core/modules/syslog/tests/modules/syslog_test/syslog_test.info.yml b/core/modules/syslog/tests/modules/syslog_test/syslog_test.info.yml new file mode 100644 index 00000000..06b155ef --- /dev/null +++ b/core/modules/syslog/tests/modules/syslog_test/syslog_test.info.yml @@ -0,0 +1,14 @@ +name: 'Syslog test' +type: module +description: 'Provides a test logger for syslog module.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - syslog + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/syslog/tests/modules/syslog_test/syslog_test.services.yml b/core/modules/syslog/tests/modules/syslog_test/syslog_test.services.yml new file mode 100644 index 00000000..120387b5 --- /dev/null +++ b/core/modules/syslog/tests/modules/syslog_test/syslog_test.services.yml @@ -0,0 +1,7 @@ +services: + logger.syslog_test: + parent: logger.syslog + class: Drupal\syslog_test\Logger\SysLogTest + arguments: ['@config.factory', '@logger.log_message_parser'] + tags: + - { name: logger } diff --git a/core/modules/syslog/tests/src/Functional/SyslogTest.php b/core/modules/syslog/tests/src/Functional/SyslogTest.php new file mode 100644 index 00000000..11b577f2 --- /dev/null +++ b/core/modules/syslog/tests/src/Functional/SyslogTest.php @@ -0,0 +1,40 @@ +drupalCreateUser(['administer site configuration']); + $this->drupalLogin($admin_user); + + // If we're on Windows, there is no configuration form. + if (defined('LOG_LOCAL6')) { + $this->drupalPostForm('admin/config/development/logging', ['syslog_facility' => LOG_LOCAL6], t('Save configuration')); + $this->assertText(t('The configuration options have been saved.')); + + $this->drupalGet('admin/config/development/logging'); + // Should be one field. + $field = $this->xpath('//option[@value=:value]', [':value' => LOG_LOCAL6]); + $this->assertSame('selected', $field[0]->getAttribute('selected'), 'Facility value saved.'); + } + } + +} diff --git a/core/modules/syslog/tests/src/Functional/Update/SyslogUpdateTest.php b/core/modules/syslog/tests/src/Functional/Update/SyslogUpdateTest.php new file mode 100644 index 00000000..e5dfed68 --- /dev/null +++ b/core/modules/syslog/tests/src/Functional/Update/SyslogUpdateTest.php @@ -0,0 +1,39 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz', + ]; + } + + /** + * Tests that syslog.settings.facility has been converted from string to int. + * + * @see syslog_update_8400() + */ + public function testSyslogSettingsFacilityDataType() { + $config = $this->config('syslog.settings'); + $this->assertIdentical('128', $config->get('facility')); + + // Run updates. + $this->runUpdates(); + + $config = $this->config('syslog.settings'); + $this->assertIdentical(128, $config->get('facility')); + } + +} diff --git a/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php b/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php index f2bf8c9e..935af8d8 100644 --- a/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php +++ b/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\syslog\Kernel\Migrate\d6; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** @@ -17,7 +17,7 @@ class MigrateSyslogConfigsTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('syslog'); + public static $modules = ['syslog']; /** * {@inheritdoc} @@ -33,7 +33,7 @@ protected function setUp() { public function testSyslogSettings() { $config = $this->config('syslog.settings'); $this->assertIdentical('drupal', $config->get('identity')); - $this->assertIdentical('128', $config->get('facility')); + $this->assertIdentical(128, $config->get('facility')); $this->assertConfigSchema(\Drupal::service('config.typed'), 'syslog.settings', $config->get()); } diff --git a/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php b/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php index e81b821b..ef5d8c30 100644 --- a/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php +++ b/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\syslog\Kernel\Migrate\d7; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; /** @@ -36,7 +36,7 @@ protected function setUp() { public function testSyslogSettings() { $config = $this->config('syslog.settings'); // 8 == LOG_USER - $this->assertIdentical('8', $config->get('facility')); + $this->assertIdentical(8, $config->get('facility')); $this->assertIdentical('!base_url|!timestamp|!type|!ip|!request_uri|!referer|!uid|!link|!message', $config->get('format')); $this->assertIdentical('drupal', $config->get('identity')); } diff --git a/core/modules/syslog/tests/src/Kernel/SyslogTest.php b/core/modules/syslog/tests/src/Kernel/SyslogTest.php new file mode 100644 index 00000000..22547f3c --- /dev/null +++ b/core/modules/syslog/tests/src/Kernel/SyslogTest.php @@ -0,0 +1,57 @@ +installConfig(['syslog']); + } + + /** + * @covers ::log + */ + public function testSyslogWriting() { + + $request = Request::create('/page-not-found', 'GET', [], [], [], ['REMOTE_ADDR' => '1.2.3.4']); + $request->headers->set('Referer', 'other-site'); + \Drupal::requestStack()->push($request); + + $user = $this->getMockBuilder('Drupal\Core\Session\AccountInterface')->getMock(); + $user->method('id')->willReturn(42); + $this->container->set('current_user', $user); + + \Drupal::logger('my_module')->warning('My warning message.', ['link' => '/my-link']); + + $log_filename = $this->container->get('file_system')->realpath('public://syslog.log'); + $logs = explode(PHP_EOL, file_get_contents($log_filename)); + $log = explode('|', $logs[0]); + + global $base_url; + $this->assertEquals($base_url, $log[0]); + $this->assertEquals('my_module', $log[2]); + $this->assertEquals('1.2.3.4', $log[3]); + $this->assertEquals($base_url . '/page-not-found', $log[4]); + $this->assertEquals('other-site', $log[5]); + $this->assertEquals('42', $log[6]); + $this->assertEquals('/my-link', $log[7]); + $this->assertEquals('My warning message.', $log[8]); + } + +} diff --git a/core/modules/system/config/install/system.cron.yml b/core/modules/system/config/install/system.cron.yml index e6f30d3d..c27b41db 100644 --- a/core/modules/system/config/install/system.cron.yml +++ b/core/modules/system/config/install/system.cron.yml @@ -1,3 +1,4 @@ threshold: requirements_warning: 172800 requirements_error: 1209600 +logging: 1 diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml index e34d375c..a6f61b68 100644 --- a/core/modules/system/config/schema/system.schema.yml +++ b/core/modules/system/config/schema/system.schema.yml @@ -5,8 +5,11 @@ system.site: label: 'Site information' mapping: uuid: - type: string + type: uuid label: 'Site UUID' + constraints: + Uuid: [] + NotNull: [] name: type: label label: 'Site name' @@ -72,6 +75,9 @@ system.cron: requirements_error: type: integer label: 'Requirements error period' + logging: + type: integer + label: 'Detailed cron logging' system.date: type: config_object @@ -182,13 +188,6 @@ system.performance: gzip: type: boolean label: 'Compress JavaScript files.' - response: - type: mapping - label: 'Response performance settings' - mapping: - gzip: - type: boolean - label: 'Compress cached pages' stale_file_threshold: type: integer label: 'Stale file threshold' diff --git a/core/modules/system/css/components/system-status-counter.css b/core/modules/system/css/components/system-status-counter.css new file mode 100644 index 00000000..1f568f02 --- /dev/null +++ b/core/modules/system/css/components/system-status-counter.css @@ -0,0 +1,30 @@ +/** + * @file + * Styles for the system status counter component. + */ + +.system-status-counter__status-icon { + display: inline-block; + height: 25px; + width: 25px; + vertical-align: middle; +} +.system-status-counter__status-icon:before { + content: ""; + background-size: 16px; + background-position: center 2px; + background-repeat: no-repeat; + width: 100%; + height: 100%; + display: block; +} + +.system-status-counter__status-icon--error:before { + background-image: url(../../../../misc/icons/e32700/error.svg); +} +.system-status-counter__status-icon--warning:before { + background-image: url(../../../../misc/icons/e29700/warning.svg); +} +.system-status-counter__status-icon--checked:before { + background-image: url(../../../../misc/icons/73b355/check.svg); +} diff --git a/core/modules/system/css/components/system-status-report-counters.css b/core/modules/system/css/components/system-status-report-counters.css new file mode 100644 index 00000000..1a4e2400 --- /dev/null +++ b/core/modules/system/css/components/system-status-report-counters.css @@ -0,0 +1,27 @@ +/** + * @file + * Styles for the system status report counters. + */ + +.system-status-report-counters__item { + width: 100%; + padding: .5em 0; + text-align: center; + white-space: nowrap; + background-color: rgba(0, 0, 0, 0.063); + margin-bottom: .5em; +} + +@media screen and (min-width: 60em) { + .system-status-report-counters { + flex-wrap: wrap; + display: flex; + justify-content: space-between; + } + .system-status-report-counters__item--half-width { + width: 49%; + } + .system-status-report-counters__item--third-width { + width: 33%; + } +} diff --git a/core/modules/system/css/components/system-status-report-general-info.css b/core/modules/system/css/components/system-status-report-general-info.css new file mode 100644 index 00000000..8334d4d1 --- /dev/null +++ b/core/modules/system/css/components/system-status-report-general-info.css @@ -0,0 +1,14 @@ +/** + * @file + * Default styles for the System Status general info. + */ + +.system-status-general-info__item { + border: 1px solid #ccc; + margin-top: 1em; + padding: 0 1em 1em; +} + +.system-status-general-info__item-title { + border-bottom: 1px solid #ccc; +} diff --git a/core/modules/system/css/system.admin.css b/core/modules/system/css/system.admin.css index 6bfd6f80..7903b7e4 100644 --- a/core/modules/system/css/system.admin.css +++ b/core/modules/system/css/system.admin.css @@ -204,13 +204,14 @@ small .admin-link:after { .system-status-report__status-title { position: relative; vertical-align: top; - width: 25%; + width: 100%; padding: 10px 6px 10px 40px; /* LTR */ box-sizing: border-box; font-weight: normal; + background-color: transparent; } [dir="rtl"] .system-status-report__status-title { - padding: 10px 40px 10px 6px; + padding: 10px 40px 10px 6px; } .system-status-report__status-icon:before { content: ""; @@ -222,7 +223,7 @@ small .admin-link:after { left: 12px; /* LTR */ top: 12px; } -[dir="rtl"] .system-status-report__status-icon:before { +[dir="rtl"] .system-status-report__status-icon:before { left: auto; right: 12px; } @@ -232,6 +233,9 @@ small .admin-link:after { .system-status-report__status-icon--warning:before { background-image: url(../../../misc/icons/e29700/warning.svg); } +.system-status-report__entry__value { + padding: 1em .5em; +} /** * Appearance page. @@ -387,3 +391,11 @@ small .admin-link:after { [dir="rtl"] .system-themes-admin-form { clear: right; } +.cron-description__run-cron { + display: block; +} + +.system-cron-settings__link { + overflow-wrap: break-word; + word-wrap: break-word; +} diff --git a/core/modules/system/js/system.date.es6.js b/core/modules/system/js/system.date.es6.js new file mode 100644 index 00000000..962dde39 --- /dev/null +++ b/core/modules/system/js/system.date.es6.js @@ -0,0 +1,51 @@ +/** + * @file + * Provides date format preview feature. + */ + +(function ($, Drupal, drupalSettings) { + const dateFormats = drupalSettings.dateFormats; + + /** + * Display the preview for date format entered. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attach behavior for previewing date formats on input elements. + */ + Drupal.behaviors.dateFormat = { + attach(context) { + const $context = $(context); + const $source = $context.find('[data-drupal-date-formatter="source"]').once('dateFormat'); + const $target = $context.find('[data-drupal-date-formatter="preview"]').once('dateFormat'); + const $preview = $target.find('em'); + + // All elements have to exist. + if (!$source.length || !$target.length) { + return; + } + + /** + * Event handler that replaces date characters with value. + * + * @param {jQuery.Event} e + * The jQuery event triggered. + */ + function dateFormatHandler(e) { + const baseValue = $(e.target).val() || ''; + const dateString = baseValue.replace(/\\?(.?)/gi, (key, value) => dateFormats[key] ? dateFormats[key] : value); + + $preview.html(dateString); + $target.toggleClass('js-hide', !dateString.length); + } + + /** + * On given event triggers the date character replacement. + */ + $source.on('keyup.dateFormat change.dateFormat input.dateFormat', dateFormatHandler) + // Initialize preview. + .trigger('keyup'); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/system/js/system.date.js b/core/modules/system/js/system.date.js index 678614d9..1c80ad79 100644 --- a/core/modules/system/js/system.date.js +++ b/core/modules/system/js/system.date.js @@ -1,40 +1,24 @@ /** - * @file - * Provides date format preview feature. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - var dateFormats = drupalSettings.dateFormats; - /** - * Display the preview for date format entered. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attach behavior for previewing date formats on input elements. - */ Drupal.behaviors.dateFormat = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); var $source = $context.find('[data-drupal-date-formatter="source"]').once('dateFormat'); var $target = $context.find('[data-drupal-date-formatter="preview"]').once('dateFormat'); var $preview = $target.find('em'); - // All elements have to exist. if (!$source.length || !$target.length) { return; } - /** - * Event handler that replaces date characters with value. - * - * @param {jQuery.Event} e - * The jQuery event triggered. - */ function dateFormatHandler(e) { var baseValue = $(e.target).val() || ''; var dateString = baseValue.replace(/\\?(.?)/gi, function (key, value) { @@ -45,13 +29,7 @@ $target.toggleClass('js-hide', !dateString.length); } - /** - * On given event triggers the date character replacement. - */ - $source.on('keyup.dateFormat change.dateFormat input.dateFormat', dateFormatHandler) - // Initialize preview. - .trigger('keyup'); + $source.on('keyup.dateFormat change.dateFormat input.dateFormat', dateFormatHandler).trigger('keyup'); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/system/js/system.es6.js b/core/modules/system/js/system.es6.js new file mode 100644 index 00000000..18153b09 --- /dev/null +++ b/core/modules/system/js/system.es6.js @@ -0,0 +1,77 @@ +/** + * @file + * System behaviors. + */ + +(function ($, Drupal, drupalSettings) { + // Cache IDs in an array for ease of use. + const ids = []; + + /** + * Attaches field copy behavior from input fields to other input fields. + * + * When a field is filled out, apply its value to other fields that will + * likely use the same value. In the installer this is used to populate the + * administrator email address with the same value as the site email address. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the field copy behavior to an input field. + */ + Drupal.behaviors.copyFieldValue = { + attach(context) { + // List of fields IDs on which to bind the event listener. + // Create an array of IDs to use with jQuery. + for (const sourceId in drupalSettings.copyFieldValue) { + if (drupalSettings.copyFieldValue.hasOwnProperty(sourceId)) { + ids.push(sourceId); + } + } + if (ids.length) { + // Listen to value:copy events on all dependent fields. + // We have to use body and not document because of the way jQuery events + // bubble up the DOM tree. + $('body').once('copy-field-values').on('value:copy', this.valueTargetCopyHandler); + // Listen on all source elements. + $(`#${ids.join(', #')}`).once('copy-field-values').on('blur', this.valueSourceBlurHandler); + } + }, + detach(context, settings, trigger) { + if (trigger === 'unload' && ids.length) { + $('body').removeOnce('copy-field-values').off('value:copy'); + $(`#${ids.join(', #')}`).removeOnce('copy-field-values').off('blur'); + } + }, + + /** + * Event handler that fill the target element with the specified value. + * + * @param {jQuery.Event} e + * Event object. + * @param {string} value + * Custom value from jQuery trigger. + */ + valueTargetCopyHandler(e, value) { + const $target = $(e.target); + if ($target.val() === '') { + $target.val(value); + } + }, + + /** + * Handler for a Blur event on a source field. + * + * This event handler will trigger a 'value:copy' event on all dependent + * fields. + * + * @param {jQuery.Event} e + * The event triggered. + */ + valueSourceBlurHandler(e) { + const value = $(e.target).val(); + const targetIds = drupalSettings.copyFieldValue[e.target.id]; + $(`#${targetIds.join(', #')}`).trigger('value:copy', value); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/system/js/system.js b/core/modules/system/js/system.js index 82f0de66..d62cc074 100644 --- a/core/modules/system/js/system.js +++ b/core/modules/system/js/system.js @@ -1,81 +1,42 @@ /** - * @file - * System behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - // Cache IDs in an array for ease of use. var ids = []; - /** - * Attaches field copy behavior from input fields to other input fields. - * - * When a field is filled out, apply its value to other fields that will - * likely use the same value. In the installer this is used to populate the - * administrator email address with the same value as the site email address. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the field copy behavior to an input field. - */ Drupal.behaviors.copyFieldValue = { - attach: function (context) { - // List of fields IDs on which to bind the event listener. - // Create an array of IDs to use with jQuery. + attach: function attach(context) { for (var sourceId in drupalSettings.copyFieldValue) { if (drupalSettings.copyFieldValue.hasOwnProperty(sourceId)) { ids.push(sourceId); } } if (ids.length) { - // Listen to value:copy events on all dependent fields. - // We have to use body and not document because of the way jQuery events - // bubble up the DOM tree. $('body').once('copy-field-values').on('value:copy', this.valueTargetCopyHandler); - // Listen on all source elements. + $('#' + ids.join(', #')).once('copy-field-values').on('blur', this.valueSourceBlurHandler); } }, - detach: function (context, settings, trigger) { + detach: function detach(context, settings, trigger) { if (trigger === 'unload' && ids.length) { $('body').removeOnce('copy-field-values').off('value:copy'); $('#' + ids.join(', #')).removeOnce('copy-field-values').off('blur'); } }, - - /** - * Event handler that fill the target element with the specified value. - * - * @param {jQuery.Event} e - * Event object. - * @param {string} value - * Custom value from jQuery trigger. - */ - valueTargetCopyHandler: function (e, value) { + valueTargetCopyHandler: function valueTargetCopyHandler(e, value) { var $target = $(e.target); if ($target.val() === '') { $target.val(value); } }, - - /** - * Handler for a Blur event on a source field. - * - * This event handler will trigger a 'value:copy' event on all dependent - * fields. - * - * @param {jQuery.Event} e - * The event triggered. - */ - valueSourceBlurHandler: function (e) { + valueSourceBlurHandler: function valueSourceBlurHandler(e) { var value = $(e.target).val(); var targetIds = drupalSettings.copyFieldValue[e.target.id]; $('#' + targetIds.join(', #')).trigger('value:copy', value); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/system/js/system.modules.es6.js b/core/modules/system/js/system.modules.es6.js new file mode 100644 index 00000000..9472d3b2 --- /dev/null +++ b/core/modules/system/js/system.modules.es6.js @@ -0,0 +1,99 @@ +/** + * @file + * Module page behaviors. + */ + +(function ($, Drupal, debounce) { + /** + * Filters the module list table by a text input search string. + * + * Additionally accounts for multiple tables being wrapped in "package" details + * elements. + * + * Text search input: input.table-filter-text + * Target table: input.table-filter-text[data-table] + * Source text: .table-filter-text-source, .module-name, .module-description + * + * @type {Drupal~behavior} + */ + Drupal.behaviors.tableFilterByText = { + attach(context, settings) { + const $input = $('input.table-filter-text').once('table-filter-text'); + const $table = $($input.attr('data-table')); + let $rowsAndDetails; + let $rows; + let $details; + let searching = false; + + function hidePackageDetails(index, element) { + const $packDetails = $(element); + const $visibleRows = $packDetails.find('tbody tr:visible'); + $packDetails.toggle($visibleRows.length > 0); + } + + function filterModuleList(e) { + const query = $(e.target).val(); + // Case insensitive expression to find query at the beginning of a word. + const re = new RegExp(`\\b${query}`, 'i'); + + function showModuleRow(index, row) { + const $row = $(row); + const $sources = $row.find('.table-filter-text-source, .module-name, .module-description'); + const textMatch = $sources.text().search(re) !== -1; + $row.closest('tr').toggle(textMatch); + } + // Search over all rows and packages. + $rowsAndDetails.show(); + + // Filter if the length of the query is at least 2 characters. + if (query.length >= 2) { + searching = true; + $rows.each(showModuleRow); + + // Note that we first open all
    to be able to use ':visible'. + // Mark the
    elements that were closed before filtering, so + // they can be reclosed when filtering is removed. + $details.not('[open]').attr('data-drupal-system-state', 'forced-open'); + + // Hide the package
    if they don't have any visible rows. + // Note that we first show() all
    to be able to use ':visible'. + $details.attr('open', true).each(hidePackageDetails); + + Drupal.announce( + Drupal.t( + '!modules modules are available in the modified list.', + { '!modules': $rowsAndDetails.find('tbody tr:visible').length }, + ), + ); + } + else if (searching) { + searching = false; + $rowsAndDetails.show(); + // Return
    elements that had been closed before filtering + // to a closed state. + $details.filter('[data-drupal-system-state="forced-open"]') + .removeAttr('data-drupal-system-state') + .attr('open', false); + } + } + + function preventEnterKey(event) { + if (event.which === 13) { + event.preventDefault(); + event.stopPropagation(); + } + } + + if ($table.length) { + $rowsAndDetails = $table.find('tr, details'); + $rows = $table.find('tbody tr'); + $details = $rowsAndDetails.filter('.package-listing'); + + $input.on({ + keyup: debounce(filterModuleList, 200), + keydown: preventEnterKey, + }); + } + }, + }; +}(jQuery, Drupal, Drupal.debounce)); diff --git a/core/modules/system/js/system.modules.js b/core/modules/system/js/system.modules.js index d47ca703..375a7b80 100644 --- a/core/modules/system/js/system.modules.js +++ b/core/modules/system/js/system.modules.js @@ -1,31 +1,18 @@ /** - * @file - * Module page behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, debounce) { - - 'use strict'; - - /** - * Filters the module list table by a text input search string. - * - * Additionally accounts for multiple tables being wrapped in "package" details - * elements. - * - * Text search input: input.table-filter-text - * Target table: input.table-filter-text[data-table] - * Source text: .table-filter-text-source, .module-name, .module-description - * - * @type {Drupal~behavior} - */ Drupal.behaviors.tableFilterByText = { - attach: function (context, settings) { + attach: function attach(context, settings) { var $input = $('input.table-filter-text').once('table-filter-text'); var $table = $($input.attr('data-table')); - var $rowsAndDetails; - var $rows; - var $details; + var $rowsAndDetails = void 0; + var $rows = void 0; + var $details = void 0; var searching = false; function hidePackageDetails(index, element) { @@ -36,7 +23,7 @@ function filterModuleList(e) { var query = $(e.target).val(); - // Case insensitive expression to find query at the beginning of a word. + var re = new RegExp('\\b' + query, 'i'); function showModuleRow(index, row) { @@ -45,38 +32,23 @@ var textMatch = $sources.text().search(re) !== -1; $row.closest('tr').toggle(textMatch); } - // Search over all rows and packages. + $rowsAndDetails.show(); - // Filter if the length of the query is at least 2 characters. if (query.length >= 2) { searching = true; $rows.each(showModuleRow); - // Note that we first open all
    to be able to use ':visible'. - // Mark the
    elements that were closed before filtering, so - // they can be reclosed when filtering is removed. $details.not('[open]').attr('data-drupal-system-state', 'forced-open'); - // Hide the package
    if they don't have any visible rows. - // Note that we first show() all
    to be able to use ':visible'. $details.attr('open', true).each(hidePackageDetails); - Drupal.announce( - Drupal.t( - '!modules modules are available in the modified list.', - {'!modules': $rowsAndDetails.find('tbody tr:visible').length} - ) - ); - } - else if (searching) { + Drupal.announce(Drupal.t('!modules modules are available in the modified list.', { '!modules': $rowsAndDetails.find('tbody tr:visible').length })); + } else if (searching) { searching = false; $rowsAndDetails.show(); - // Return
    elements that had been closed before filtering - // to a closed state. - $details.filter('[data-drupal-system-state="forced-open"]') - .removeAttr('data-drupal-system-state') - .attr('open', false); + + $details.filter('[data-drupal-system-state="forced-open"]').removeAttr('data-drupal-system-state').attr('open', false); } } @@ -99,5 +71,4 @@ } } }; - -}(jQuery, Drupal, Drupal.debounce)); +})(jQuery, Drupal, Drupal.debounce); \ No newline at end of file diff --git a/core/modules/system/migration_templates/d6_date_formats.yml b/core/modules/system/migration_templates/d6_date_formats.yml index 71257d4f..b2812801 100644 --- a/core/modules/system/migration_templates/d6_date_formats.yml +++ b/core/modules/system/migration_templates/d6_date_formats.yml @@ -8,6 +8,7 @@ source: - date_format_long - date_format_medium - date_format_short + source_module: system process: id: plugin: static_map diff --git a/core/modules/system/migration_templates/d6_system_cron.yml b/core/modules/system/migration_templates/d6_system_cron.yml index 7dd3a2bc..bf1f6b33 100644 --- a/core/modules/system/migration_templates/d6_system_cron.yml +++ b/core/modules/system/migration_templates/d6_system_cron.yml @@ -8,6 +8,7 @@ source: - cron_threshold_warning - cron_threshold_error - cron_last + source_module: system process: 'threshold/requirements_warning': cron_threshold_warning 'threshold/requirements_error': cron_threshold_error diff --git a/core/modules/system/migration_templates/d6_system_date.yml b/core/modules/system/migration_templates/d6_system_date.yml index 25f6728a..7da96c34 100644 --- a/core/modules/system/migration_templates/d6_system_date.yml +++ b/core/modules/system/migration_templates/d6_system_date.yml @@ -8,6 +8,7 @@ source: - configurable_timezones - date_first_day - date_default_timezone + source_module: system process: 'timezone/user/configurable': configurable_timezones first_day: date_first_day diff --git a/core/modules/system/migration_templates/d6_system_file.yml b/core/modules/system/migration_templates/d6_system_file.yml index 60cd6160..902b0e44 100644 --- a/core/modules/system/migration_templates/d6_system_file.yml +++ b/core/modules/system/migration_templates/d6_system_file.yml @@ -7,6 +7,7 @@ source: variables: - file_directory_temp - allow_insecure_uploads + source_module: system process: 'path/temporary': file_directory_temp allow_insecure_uploads: diff --git a/core/modules/system/migration_templates/d6_system_performance.yml b/core/modules/system/migration_templates/d6_system_performance.yml index 6f9666e4..87811c36 100644 --- a/core/modules/system/migration_templates/d6_system_performance.yml +++ b/core/modules/system/migration_templates/d6_system_performance.yml @@ -10,11 +10,11 @@ source: - cache_lifetime - cache - page_compression + source_module: system process: 'css/preprocess': preprocess_css 'js/preprocess': preprocess_js 'cache/page/max_age': cache_lifetime - 'response/gzip': page_compression destination: plugin: config config_name: system.performance diff --git a/core/modules/system/migration_templates/d7_global_theme_settings.yml b/core/modules/system/migration_templates/d7_global_theme_settings.yml index 42c5177d..9b5ff83f 100644 --- a/core/modules/system/migration_templates/d7_global_theme_settings.yml +++ b/core/modules/system/migration_templates/d7_global_theme_settings.yml @@ -6,6 +6,7 @@ source: plugin: variable variables: - theme_settings + source_module: system process: 'features/logo': theme_settings/toggle_logo 'features/name': theme_settings/toggle_name diff --git a/core/modules/system/migration_templates/d7_system_authorize.yml b/core/modules/system/migration_templates/d7_system_authorize.yml index 420497b8..ca09567a 100644 --- a/core/modules/system/migration_templates/d7_system_authorize.yml +++ b/core/modules/system/migration_templates/d7_system_authorize.yml @@ -1,10 +1,12 @@ id: d7_system_authorize +label: Drupal 7 file transfer authorize configuration migration_tags: - Drupal 7 source: plugin: variable variables: - authorize_filetransfer_default + source_module: system process: filetransfer_default: authorize_filetransfer_default destination: diff --git a/core/modules/system/migration_templates/d7_system_cron.yml b/core/modules/system/migration_templates/d7_system_cron.yml index a603af3e..55021c9d 100644 --- a/core/modules/system/migration_templates/d7_system_cron.yml +++ b/core/modules/system/migration_templates/d7_system_cron.yml @@ -7,6 +7,7 @@ source: variables: - cron_threshold_warning - cron_threshold_error + source_module: system process: 'threshold/requirements_warning': cron_threshold_warning 'threshold/requirements_error': cron_threshold_error diff --git a/core/modules/system/migration_templates/d7_system_date.yml b/core/modules/system/migration_templates/d7_system_date.yml index b380c897..f860b07c 100644 --- a/core/modules/system/migration_templates/d7_system_date.yml +++ b/core/modules/system/migration_templates/d7_system_date.yml @@ -1,4 +1,5 @@ id: d7_system_date +label: Drupal 7 system date configuration migration_tags: - Drupal 7 source: @@ -10,6 +11,7 @@ source: - configurable_timezones - empty_timezone_message - user_default_timezone + source_module: system process: 'country/default': site_default_country first_day: date_first_day diff --git a/core/modules/system/migration_templates/d7_system_file.yml b/core/modules/system/migration_templates/d7_system_file.yml index 2295e0e1..9652cb0e 100644 --- a/core/modules/system/migration_templates/d7_system_file.yml +++ b/core/modules/system/migration_templates/d7_system_file.yml @@ -7,6 +7,7 @@ source: variables: - allow_insecure_uploads - file_temporary_path + source_module: system process: allow_insecure_uploads: plugin: static_map diff --git a/core/modules/system/migration_templates/d7_system_mail.yml b/core/modules/system/migration_templates/d7_system_mail.yml index d4a569cf..52043747 100644 --- a/core/modules/system/migration_templates/d7_system_mail.yml +++ b/core/modules/system/migration_templates/d7_system_mail.yml @@ -1,10 +1,12 @@ id: d7_system_mail +label: Drupal 7 system mail configuration migration_tags: - Drupal 7 source: plugin: variable variables: - mail_system + source_module: system process: 'interface/default': plugin: static_map diff --git a/core/modules/system/migration_templates/d7_system_performance.yml b/core/modules/system/migration_templates/d7_system_performance.yml index b41d75ec..0f28dbfc 100644 --- a/core/modules/system/migration_templates/d7_system_performance.yml +++ b/core/modules/system/migration_templates/d7_system_performance.yml @@ -9,11 +9,11 @@ source: - preprocess_js - cache_lifetime - page_compression + source_module: system process: 'css/preprocess': preprocess_css 'js/preprocess': preprocess_js 'cache/page/max_age': cache_lifetime - 'response/gzip': page_compression destination: plugin: config config_name: system.performance diff --git a/core/modules/system/migration_templates/d7_theme_settings.yml b/core/modules/system/migration_templates/d7_theme_settings.yml new file mode 100644 index 00000000..09f5fe1e --- /dev/null +++ b/core/modules/system/migration_templates/d7_theme_settings.yml @@ -0,0 +1,44 @@ +id: d7_theme_settings +label: D7 theme settings +migration_tags: + - Drupal 7 +source: + plugin: d7_theme_settings + constants: + config_suffix: '.settings' +process: + # Build the configuration name from the variable name, i.e. + # theme_bartik_settings becomes bartik.settings. + theme_name: + - + plugin: explode + source: name + delimiter: _ + - + plugin: extract + index: + - 1 + configuration_name: + plugin: concat + source: + - '@theme_name' + - constants/config_suffix + toggle_logo: theme_settings/toggle_logo + toggle_name: value/toggle_name + toggle_slogan: value/toggle_slogan + toggle_node_user_picture: value/toggle_node_user_picture + toggle_comment_user_picture: value/toggle_comment_user_picture + toggle_comment_user_verification: value/toggle_comment_user_verification + toggle_favicon: value/toggle_favicon + default_logo: value/default_logo + logo_path: value/logo_path + logo_upload: value/logo_upload + default_favicon: value/default_favicon + favicon_path: value/favicon_path + favicon_mimetype: value/favicon_mimetype +# Ignore settings not present in Drupal 8. +# value/favicon_upload +# value/toggle_main_menu +# value/toggle_secondary_menu +destination: + plugin: d7_theme_settings diff --git a/core/modules/system/migration_templates/system_image.yml b/core/modules/system/migration_templates/system_image.yml index 7bb16b1b..1f5612f7 100644 --- a/core/modules/system/migration_templates/system_image.yml +++ b/core/modules/system/migration_templates/system_image.yml @@ -7,6 +7,7 @@ source: plugin: variable variables: - image_toolkit + source_module: system process: toolkit: image_toolkit destination: diff --git a/core/modules/system/migration_templates/system_image_gd.yml b/core/modules/system/migration_templates/system_image_gd.yml index 685116ee..28e0ab71 100644 --- a/core/modules/system/migration_templates/system_image_gd.yml +++ b/core/modules/system/migration_templates/system_image_gd.yml @@ -7,6 +7,7 @@ source: plugin: variable variables: - image_jpeg_quality + source_module: system process: jpeg_quality: image_jpeg_quality destination: diff --git a/core/modules/system/migration_templates/system_logging.yml b/core/modules/system/migration_templates/system_logging.yml index c1e81141..eea3473b 100644 --- a/core/modules/system/migration_templates/system_logging.yml +++ b/core/modules/system/migration_templates/system_logging.yml @@ -7,6 +7,7 @@ source: plugin: variable variables: - error_level + source_module: system process: error_level: plugin: static_map diff --git a/core/modules/system/migration_templates/system_maintenance.yml b/core/modules/system/migration_templates/system_maintenance.yml index b9f6c348..183fa108 100644 --- a/core/modules/system/migration_templates/system_maintenance.yml +++ b/core/modules/system/migration_templates/system_maintenance.yml @@ -7,6 +7,7 @@ source: plugin: variable variables: - site_offline_message + source_module: system process: message: site_offline_message destination: diff --git a/core/modules/system/migration_templates/system_rss.yml b/core/modules/system/migration_templates/system_rss.yml index 92ce45a6..d6ff5bc4 100644 --- a/core/modules/system/migration_templates/system_rss.yml +++ b/core/modules/system/migration_templates/system_rss.yml @@ -8,6 +8,7 @@ source: variables: - feed_default_items - feed_item_length + source_module: system process: 'items/limit': feed_default_items 'items/view_mode': feed_item_length diff --git a/core/modules/system/migration_templates/system_site.yml b/core/modules/system/migration_templates/system_site.yml index c8fd8490..397823c2 100644 --- a/core/modules/system/migration_templates/system_site.yml +++ b/core/modules/system/migration_templates/system_site.yml @@ -16,6 +16,7 @@ source: - site_404 - drupal_weight_select_max - admin_compact_mode + source_module: system process: name: site_name mail: site_mail diff --git a/core/modules/system/src/Controller/AdminController.php b/core/modules/system/src/Controller/AdminController.php index 57c13f65..3da4b090 100644 --- a/core/modules/system/src/Controller/AdminController.php +++ b/core/modules/system/src/Controller/AdminController.php @@ -23,13 +23,13 @@ public function index() { } uasort($module_info, 'system_sort_modules_by_info_name'); - $menu_items = array(); + $menu_items = []; foreach ($module_info as $module => $info) { // Only display a section if there are any available tasks. if ($admin_tasks = system_get_module_admin_tasks($module, $info->info)) { // Sort links by title. - uasort($admin_tasks, array('\Drupal\Component\Utility\SortArray', 'sortByTitleElement')); + uasort($admin_tasks, ['\Drupal\Component\Utility\SortArray', 'sortByTitleElement']); // Move 'Configure permissions' links to the bottom of each section. $permission_key = "user.admin_permissions.$module"; if (isset($admin_tasks[$permission_key])) { @@ -38,14 +38,14 @@ public function index() { $admin_tasks[$permission_key] = $permission_task; } - $menu_items[$info->info['name']] = array($info->info['description'], $admin_tasks); + $menu_items[$info->info['name']] = [$info->info['description'], $admin_tasks]; } } - $output = array( + $output = [ '#theme' => 'system_admin_index', '#menu_items' => $menu_items, - ); + ]; return $output; } diff --git a/core/modules/system/src/Controller/BatchController.php b/core/modules/system/src/Controller/BatchController.php index 7975dcc4..2e01c5ba 100644 --- a/core/modules/system/src/Controller/BatchController.php +++ b/core/modules/system/src/Controller/BatchController.php @@ -61,11 +61,22 @@ public function batchPage(Request $request) { return $output; } elseif (isset($output)) { + $title = isset($output['#title']) ? $output['#title'] : NULL; $page = [ '#type' => 'page', + '#title' => $title, '#show_messages' => FALSE, 'content' => $output, ]; + + // Also inject title as a page header (if available). + if ($title) { + $page['header'] = [ + '#type' => 'page_title', + '#title' => $title, + ]; + } + return $page; } } diff --git a/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php index f378631a..9e0a374a 100644 --- a/core/modules/system/src/Controller/DbUpdateController.php +++ b/core/modules/system/src/Controller/DbUpdateController.php @@ -150,7 +150,7 @@ public function handle($op, Request $request) { $_SESSION['update_ignore_warnings'] = TRUE; } - $regions = array(); + $regions = []; $requirements = update_check_requirements(); $severity = drupal_requirements_severity($requirements); if ($severity == REQUIREMENT_ERROR || ($severity == REQUIREMENT_WARNING && empty($_SESSION['update_ignore_warnings']))) { @@ -212,32 +212,32 @@ protected function info(Request $request) { $this->keyValueExpirableFactory->get('update')->deleteAll(); $this->keyValueExpirableFactory->get('update_available_release')->deleteAll(); - $build['info_header'] = array( + $build['info_header'] = [ '#markup' => '

    ' . $this->t('Use this utility to update your database whenever a new release of Drupal or a module is installed.') . '

    ' . $this->t('For more detailed information, see the upgrading handbook. If you are unsure what these terms mean you should probably contact your hosting provider.') . '

    ', - ); + ]; $info[] = $this->t("Back up your code. Hint: when backing up module code, do not leave that backup in the 'modules' or 'sites/*/modules' directories as this may confuse Drupal's auto-discovery mechanism."); - $info[] = $this->t('Put your site into maintenance mode.', array( + $info[] = $this->t('Put your site into maintenance mode.', [ ':url' => Url::fromRoute('system.site_maintenance_mode')->toString(TRUE)->getGeneratedUrl(), - )); + ]); $info[] = $this->t('Back up your database. This process will change your database values and in case of emergency you may need to revert to a backup.'); $info[] = $this->t('Install your new files in the appropriate location, as described in the handbook.'); - $build['info'] = array( + $build['info'] = [ '#theme' => 'item_list', '#list_type' => 'ol', '#items' => $info, - ); - $build['info_footer'] = array( + ]; + $build['info_footer'] = [ '#markup' => '

    ' . $this->t('When you have performed the steps above, you may proceed.') . '

    ', - ); + ]; - $build['link'] = array( + $build['link'] = [ '#type' => 'link', '#title' => $this->t('Continue'), - '#attributes' => array('class' => array('button', 'button--primary')), + '#attributes' => ['class' => ['button', 'button--primary']], // @todo Revisit once https://www.drupal.org/node/2548095 is in. '#url' => Url::fromUri('base://selection'), - ); + ]; return $build; } @@ -256,15 +256,15 @@ protected function selection(Request $request) { $count = 0; $incompatible_count = 0; - $build['start'] = array( + $build['start'] = [ '#tree' => TRUE, '#type' => 'details', - ); + ]; // Ensure system.module's updates appear first. - $build['start']['system'] = array(); + $build['start']['system'] = []; - $starting_updates = array(); + $starting_updates = []; $incompatible_updates_exist = FALSE; $updates_per_module = []; foreach (['update', 'post_update'] as $update_type) { @@ -278,30 +278,30 @@ protected function selection(Request $request) { } foreach ($updates as $module => $update) { if (!isset($update['start'])) { - $build['start'][$module] = array( + $build['start'][$module] = [ '#type' => 'item', '#title' => $module . ' module', '#markup' => $update['warning'], '#prefix' => '
    ', '#suffix' => '
    ', - ); + ]; $incompatible_updates_exist = TRUE; continue; } if (!empty($update['pending'])) { $updates_per_module += [$module => []]; $updates_per_module[$module] = array_merge($updates_per_module[$module], $update['pending']); - $build['start'][$module] = array( + $build['start'][$module] = [ '#type' => 'hidden', '#value' => $update['start'], - ); + ]; // Store the previous items in order to merge normal updates and // post_update functions together. - $build['start'][$module] = array( + $build['start'][$module] = [ '#theme' => 'item_list', '#items' => $updates_per_module[$module], '#title' => $module . ' module', - ); + ]; if ($update_type === 'update') { $starting_updates[$module] = $update['start']; @@ -329,7 +329,7 @@ protected function selection(Request $request) { $build['start'][$module_update_key]['#items'][$data['number']] .= '
    ' . $text . '
    '; } // Move the module containing this update to the top of the list. - $build['start'] = array($module_update_key => $build['start'][$module_update_key]) + $build['start']; + $build['start'] = [$module_update_key => $build['start'][$module_update_key]] + $build['start']; } } @@ -341,25 +341,25 @@ protected function selection(Request $request) { if (empty($count)) { drupal_set_message($this->t('No pending updates.')); unset($build); - $build['links'] = array( + $build['links'] = [ '#theme' => 'links', '#links' => $this->helpfulLinks($request), - ); + ]; // No updates to run, so caches won't get flushed later. Clear them now. drupal_flush_all_caches(); } else { - $build['help'] = array( + $build['help'] = [ '#markup' => '

    ' . $this->t('The version of Drupal you are updating from has been automatically detected.') . '

    ', '#weight' => -5, - ); + ]; if ($incompatible_count) { $build['start']['#title'] = $this->formatPlural( $count, '1 pending update (@number_applied to be applied, @number_incompatible skipped)', '@count pending updates (@number_applied to be applied, @number_incompatible skipped)', - array('@number_applied' => $count - $incompatible_count, '@number_incompatible' => $incompatible_count) + ['@number_applied' => $count - $incompatible_count, '@number_incompatible' => $incompatible_count] ); } else { @@ -367,15 +367,15 @@ protected function selection(Request $request) { } // @todo Simplify with https://www.drupal.org/node/2548095 $base_url = str_replace('/update.php', '', $request->getBaseUrl()); - $url = (new Url('system.db_update', array('op' => 'run')))->setOption('base_url', $base_url); - $build['link'] = array( + $url = (new Url('system.db_update', ['op' => 'run']))->setOption('base_url', $base_url); + $build['link'] = [ '#type' => 'link', '#title' => $this->t('Apply pending updates'), - '#attributes' => array('class' => array('button', 'button--primary')), + '#attributes' => ['class' => ['button', 'button--primary']], '#weight' => 5, '#url' => $url, '#access' => $url->access($this->currentUser()), - ); + ]; } return $build; @@ -397,24 +397,24 @@ protected function results(Request $request) { // Report end result. $dblog_exists = $this->moduleHandler->moduleExists('dblog'); if ($dblog_exists && $this->account->hasPermission('access site reports')) { - $log_message = $this->t('All errors have been logged.', array( + $log_message = $this->t('All errors have been logged.', [ ':url' => Url::fromRoute('dblog.overview')->setOption('base_url', $base_url)->toString(TRUE)->getGeneratedUrl(), - )); + ]); } else { $log_message = $this->t('All errors have been logged.'); } if (!empty($_SESSION['update_success'])) { - $message = '

    ' . $this->t('Updates were attempted. If you see no failures below, you may proceed happily back to your site. Otherwise, you may need to update your database manually.', array(':url' => Url::fromRoute('')->setOption('base_url', $base_url)->toString(TRUE)->getGeneratedUrl())) . ' ' . $log_message . '

    '; + $message = '

    ' . $this->t('Updates were attempted. If you see no failures below, you may proceed happily back to your site. Otherwise, you may need to update your database manually.', [':url' => Url::fromRoute('')->setOption('base_url', $base_url)->toString(TRUE)->getGeneratedUrl()]) . ' ' . $log_message . '

    '; } else { $last = reset($_SESSION['updates_remaining']); list($module, $version) = array_pop($last); - $message = '

    ' . $this->t('The update process was aborted prematurely while running update #@version in @module.module.', array( + $message = '

    ' . $this->t('The update process was aborted prematurely while running update #@version in @module.module.', [ '@version' => $version, '@module' => $module, - )) . ' ' . $log_message; + ]) . ' ' . $log_message; if ($dblog_exists) { $message .= ' ' . $this->t('You may need to check the watchdog database table manually.'); } @@ -425,23 +425,23 @@ protected function results(Request $request) { $message .= '

    ' . $this->t("Reminder: don't forget to set the \$settings['update_free_access'] value in your settings.php file back to FALSE.") . '

    '; } - $build['message'] = array( + $build['message'] = [ '#markup' => $message, - ); - $build['links'] = array( + ]; + $build['links'] = [ '#theme' => 'links', '#links' => $this->helpfulLinks($request), - ); + ]; // Output a list of info messages. if (!empty($_SESSION['update_results'])) { - $all_messages = array(); + $all_messages = []; foreach ($_SESSION['update_results'] as $module => $updates) { if ($module != '#abort') { $module_has_message = FALSE; - $info_messages = array(); + $info_messages = []; foreach ($updates as $name => $queries) { - $messages = array(); + $messages = []; foreach ($queries as $query) { // If there is no message for this update, don't show anything. if (empty($query['query'])) { @@ -449,16 +449,16 @@ protected function results(Request $request) { } if ($query['success']) { - $messages[] = array( - '#wrapper_attributes' => array('class' => array('success')), + $messages[] = [ + '#wrapper_attributes' => ['class' => ['success']], '#markup' => $query['query'], - ); + ]; } else { - $messages[] = array( - '#wrapper_attributes' => array('class' => array('failure')), + $messages[] = [ + '#wrapper_attributes' => ['class' => ['failure']], '#markup' => '' . $this->t('Failed:') . ' ' . $query['query'], - ); + ]; } } @@ -470,32 +470,32 @@ protected function results(Request $request) { else { $title = $this->t('Update @name', ['@name' => trim($name, '_')]); } - $info_messages[] = array( + $info_messages[] = [ '#theme' => 'item_list', '#items' => $messages, '#title' => $title, - ); + ]; } } // If there were any messages then prefix them with the module name // and add it to the global message list. if ($module_has_message) { - $all_messages[] = array( + $all_messages[] = [ '#type' => 'container', - '#prefix' => '

    ' . $this->t('@module module', array('@module' => $module)) . '

    ', + '#prefix' => '

    ' . $this->t('@module module', ['@module' => $module]) . '

    ', '#children' => $info_messages, - ); + ]; } } } if ($all_messages) { - $build['query_messages'] = array( + $build['query_messages'] = [ '#type' => 'container', '#children' => $all_messages, - '#attributes' => array('class' => array('update-results')), + '#attributes' => ['class' => ['update-results']], '#prefix' => '

    ' . $this->t('The following updates returned messages:') . '

    ', - ); + ]; } } unset($_SESSION['update_results']); @@ -515,17 +515,17 @@ protected function results(Request $request) { * A render array. */ public function requirements($severity, array $requirements, Request $request) { - $options = $severity == REQUIREMENT_WARNING ? array('continue' => 1) : array(); + $options = $severity == REQUIREMENT_WARNING ? ['continue' => 1] : []; // @todo Revisit once https://www.drupal.org/node/2548095 is in. Something // like Url::fromRoute('system.db_update')->setOptions() should then be // possible. $try_again_url = Url::fromUri($request->getUriForPath(''))->setOptions(['query' => $options])->toString(TRUE)->getGeneratedUrl(); - $build['status_report'] = array( - '#theme' => 'status_report', + $build['status_report'] = [ + '#type' => 'status_report', '#requirements' => $requirements, - '#suffix' => $this->t('Check the messages and try again.', array(':url' => $try_again_url)) - ); + '#suffix' => $this->t('Check the messages and try again.', [':url' => $try_again_url]) + ]; $build['#title'] = $this->t('Requirements problem'); return $build; @@ -543,19 +543,19 @@ public function requirements($severity, array $requirements, Request $request) { */ protected function updateTasksList($active = NULL) { // Default list of tasks. - $tasks = array( + $tasks = [ 'requirements' => $this->t('Verify requirements'), 'info' => $this->t('Overview'), 'selection' => $this->t('Review updates'), 'run' => $this->t('Run updates'), 'results' => $this->t('Review log'), - ); + ]; - $task_list = array( + $task_list = [ '#theme' => 'maintenance_task_list', '#items' => $tasks, '#active' => $active, - ); + ]; return $task_list; } @@ -576,7 +576,7 @@ protected function triggerBatch(Request $request) { $this->state->set('system.maintenance_mode', TRUE); } - $operations = array(); + $operations = []; // Resolve any update dependencies to determine the actual updates that will // be run and the order they will be run in. @@ -587,9 +587,9 @@ protected function triggerBatch(Request $request) { // batch API can pass in to the batch operation each time it is called. (We // do not store the entire update dependency array here because it is // potentially very large.) - $dependency_map = array(); + $dependency_map = []; foreach ($updates as $function => $update) { - $dependency_map[$function] = !empty($update['reverse_paths']) ? array_keys($update['reverse_paths']) : array(); + $dependency_map[$function] = !empty($update['reverse_paths']) ? array_keys($update['reverse_paths']) : []; } // Determine updates to be performed. @@ -602,7 +602,7 @@ protected function triggerBatch(Request $request) { drupal_set_installed_schema_version($update['module'], $update['number'] - 1); unset($start[$update['module']]); } - $operations[] = array('update_do_one', array($update['module'], $update['number'], $dependency_map[$function])); + $operations[] = ['update_do_one', [$update['module'], $update['number'], $dependency_map[$function]]]; } } @@ -618,12 +618,12 @@ protected function triggerBatch(Request $request) { } $batch['operations'] = $operations; - $batch += array( + $batch += [ 'title' => $this->t('Updating'), 'init_message' => $this->t('Starting updates'), 'error_message' => $this->t('An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference.'), - 'finished' => array('\Drupal\system\Controller\DbUpdateController', 'batchFinished'), - ); + 'finished' => ['\Drupal\system\Controller\DbUpdateController', 'batchFinished'], + ]; batch_set($batch); // @todo Revisit once https://www.drupal.org/node/2548095 is in. @@ -673,15 +673,15 @@ public static function batchFinished($success, $results, $operations) { protected function helpfulLinks(Request $request) { // @todo Simplify with https://www.drupal.org/node/2548095 $base_url = str_replace('/update.php', '', $request->getBaseUrl()); - $links['front'] = array( + $links['front'] = [ 'title' => $this->t('Front page'), 'url' => Url::fromRoute('')->setOption('base_url', $base_url), - ); + ]; if ($this->account->hasPermission('access administration pages')) { - $links['admin-pages'] = array( + $links['admin-pages'] = [ 'title' => $this->t('Administration pages'), 'url' => Url::fromRoute('system.admin')->setOption('base_url', $base_url), - ); + ]; } return $links; } @@ -693,7 +693,7 @@ protected function helpfulLinks(Request $request) { * The module updates that can be performed. */ protected function getModuleUpdates() { - $return = array(); + $return = []; $updates = update_get_update_list(); foreach ($updates as $module => $update) { $return[$module] = $update['start']; diff --git a/core/modules/system/src/Controller/EntityAutocompleteController.php b/core/modules/system/src/Controller/EntityAutocompleteController.php index 53ec818f..974c2ded 100644 --- a/core/modules/system/src/Controller/EntityAutocompleteController.php +++ b/core/modules/system/src/Controller/EntityAutocompleteController.php @@ -77,7 +77,7 @@ public static function create(ContainerInterface $container) { * or if it does not match the stored data. */ public function handleAutocomplete(Request $request, $target_type, $selection_handler, $selection_settings_key) { - $matches = array(); + $matches = []; // Get the typed string from the URL, if it exists. if ($input = $request->query->get('q')) { $typed_string = Tags::explode($input); diff --git a/core/modules/system/src/Controller/Http4xxController.php b/core/modules/system/src/Controller/Http4xxController.php index 3724901c..ee8a9776 100644 --- a/core/modules/system/src/Controller/Http4xxController.php +++ b/core/modules/system/src/Controller/Http4xxController.php @@ -9,6 +9,18 @@ */ class Http4xxController extends ControllerBase { + /** + * The default 4xx error content. + * + * @return array + * A render array containing the message to display for 4xx errors. + */ + public function on4xx() { + return [ + '#markup' => $this->t('A client error happened'), + ]; + } + /** * The default 401 content. * @@ -25,7 +37,7 @@ public function on401() { * The default 403 content. * * @return array - * A render array containing the message to display for 404 pages. + * A render array containing the message to display for 403 pages. */ public function on403() { return [ diff --git a/core/modules/system/src/Controller/SystemController.php b/core/modules/system/src/Controller/SystemController.php index 41ed8246..4af1dcb8 100644 --- a/core/modules/system/src/Controller/SystemController.php +++ b/core/modules/system/src/Controller/SystemController.php @@ -4,7 +4,6 @@ use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Controller\ControllerBase; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Extension\ThemeHandlerInterface; use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Menu\MenuLinkTreeInterface; @@ -19,13 +18,6 @@ */ class SystemController extends ControllerBase { - /** - * The entity query factory object. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $queryFactory; - /** * System Manager Service. * @@ -66,8 +58,6 @@ class SystemController extends ControllerBase { * * @param \Drupal\system\SystemManager $systemManager * System manager service. - * @param \Drupal\Core\Entity\Query\QueryFactory $queryFactory - * The entity query object. * @param \Drupal\Core\Theme\ThemeAccessCheck $theme_access * The theme access checker service. * @param \Drupal\Core\Form\FormBuilderInterface $form_builder @@ -77,9 +67,8 @@ class SystemController extends ControllerBase { * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_link_tree * The menu link tree service. */ - public function __construct(SystemManager $systemManager, QueryFactory $queryFactory, ThemeAccessCheck $theme_access, FormBuilderInterface $form_builder, ThemeHandlerInterface $theme_handler, MenuLinkTreeInterface $menu_link_tree) { + public function __construct(SystemManager $systemManager, ThemeAccessCheck $theme_access, FormBuilderInterface $form_builder, ThemeHandlerInterface $theme_handler, MenuLinkTreeInterface $menu_link_tree) { $this->systemManager = $systemManager; - $this->queryFactory = $queryFactory; $this->themeAccess = $theme_access; $this->formBuilder = $form_builder; $this->themeHandler = $theme_handler; @@ -92,7 +81,6 @@ public function __construct(SystemManager $systemManager, QueryFactory $queryFac public static function create(ContainerInterface $container) { return new static( $container->get('system.manager'), - $container->get('entity.query'), $container->get('access_check.theme'), $container->get('form_builder'), $container->get('theme_handler'), @@ -112,19 +100,19 @@ public static function create(ContainerInterface $container) { public function overview($link_id) { // Check for status report errors. if ($this->systemManager->checkRequirements() && $this->currentUser()->hasPermission('administer site configuration')) { - drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the status report for more information.', array(':status' => $this->url('system.status'))), 'error'); + drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the status report for more information.', [':status' => $this->url('system.status')]), 'error'); } // Load all menu links below it. $parameters = new MenuTreeParameters(); $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks(); $tree = $this->menuLinkTree->load(NULL, $parameters); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'], + ]; $tree = $this->menuLinkTree->transform($tree, $manipulators); $tree_access_cacheability = new CacheableMetadata(); - $blocks = array(); + $blocks = []; foreach ($tree as $key => $element) { $tree_access_cacheability = $tree_access_cacheability->merge(CacheableMetadata::createFromObject($element->access)); @@ -136,10 +124,10 @@ public function overview($link_id) { $link = $element->link; $block['title'] = $link->getTitle(); $block['description'] = $link->getDescription(); - $block['content'] = array( + $block['content'] = [ '#theme' => 'admin_block_content', '#content' => $this->systemManager->getAdminBlock($link), - ); + ]; if (!empty($block['content']['#content'])) { $blocks[$key] = $block; @@ -173,7 +161,7 @@ public function overview($link_id) { * @return \Symfony\Component\HttpFoundation\RedirectResponse */ public function compactPage($mode) { - user_cookie_save(array('admin_compact_mode' => ($mode == 'on'))); + user_cookie_save(['admin_compact_mode' => ($mode == 'on')]); return $this->redirect(''); } @@ -199,9 +187,9 @@ public function themesPage() { uasort($themes, 'system_sort_modules_by_info_name'); $theme_default = $config->get('default'); - $theme_groups = array('installed' => array(), 'uninstalled' => array()); + $theme_groups = ['installed' => [], 'uninstalled' => []]; $admin_theme = $config->get('admin'); - $admin_theme_options = array(); + $admin_theme_options = []; foreach ($themes as &$theme) { if (!empty($theme->info['hidden'])) { @@ -218,17 +206,17 @@ public function themesPage() { $theme_keys[] = $theme->getName(); } else { - $theme_keys = array($theme->getName()); + $theme_keys = [$theme->getName()]; } // Look for a screenshot in the current theme or in its closest ancestor. foreach (array_reverse($theme_keys) as $theme_key) { if (isset($themes[$theme_key]) && file_exists($themes[$theme_key]->info['screenshot'])) { - $theme->screenshot = array( + $theme->screenshot = [ 'uri' => $themes[$theme_key]->info['screenshot'], - 'alt' => $this->t('Screenshot for @theme theme', array('@theme' => $theme->info['name'])), - 'title' => $this->t('Screenshot for @theme theme', array('@theme' => $theme->info['name'])), - 'attributes' => array('class' => array('screenshot')), - ); + 'alt' => $this->t('Screenshot for @theme theme', ['@theme' => $theme->info['name']]), + 'title' => $this->t('Screenshot for @theme theme', ['@theme' => $theme->info['name']]), + 'attributes' => ['class' => ['screenshot']], + ]; break; } } @@ -245,16 +233,16 @@ public function themesPage() { // Confirm that the theme engine is available. $theme->incompatible_engine = isset($theme->info['engine']) && !isset($theme->owner); } - $theme->operations = array(); + $theme->operations = []; if (!empty($theme->status) || !$theme->incompatible_core && !$theme->incompatible_php && !$theme->incompatible_base && !$theme->incompatible_engine) { // Create the operations links. $query['theme'] = $theme->getName(); if ($this->themeAccess->checkAccess($theme->getName())) { - $theme->operations[] = array( + $theme->operations[] = [ 'title' => $this->t('Settings'), 'url' => Url::fromRoute('system.theme_settings_theme', ['theme' => $theme->getName()]), - 'attributes' => array('title' => $this->t('Settings for @theme theme', array('@theme' => $theme->info['name']))), - ); + 'attributes' => ['title' => $this->t('Settings for @theme theme', ['@theme' => $theme->info['name']])], + ]; } if (!empty($theme->status)) { if (!$theme->is_default) { @@ -269,40 +257,40 @@ public function themesPage() { } } if ($theme_uninstallable) { - $theme->operations[] = array( + $theme->operations[] = [ 'title' => $this->t('Uninstall'), 'url' => Url::fromRoute('system.theme_uninstall'), 'query' => $query, - 'attributes' => array('title' => $this->t('Uninstall @theme theme', array('@theme' => $theme->info['name']))), - ); + 'attributes' => ['title' => $this->t('Uninstall @theme theme', ['@theme' => $theme->info['name']])], + ]; } - $theme->operations[] = array( + $theme->operations[] = [ 'title' => $this->t('Set as default'), 'url' => Url::fromRoute('system.theme_set_default'), 'query' => $query, - 'attributes' => array('title' => $this->t('Set @theme as default theme', array('@theme' => $theme->info['name']))), - ); + 'attributes' => ['title' => $this->t('Set @theme as default theme', ['@theme' => $theme->info['name']])], + ]; } $admin_theme_options[$theme->getName()] = $theme->info['name']; } else { - $theme->operations[] = array( + $theme->operations[] = [ 'title' => $this->t('Install'), 'url' => Url::fromRoute('system.theme_install'), 'query' => $query, - 'attributes' => array('title' => $this->t('Install @theme theme', array('@theme' => $theme->info['name']))), - ); - $theme->operations[] = array( + 'attributes' => ['title' => $this->t('Install @theme theme', ['@theme' => $theme->info['name']])], + ]; + $theme->operations[] = [ 'title' => $this->t('Install and set as default'), 'url' => Url::fromRoute('system.theme_set_default'), 'query' => $query, - 'attributes' => array('title' => $this->t('Install @theme as default theme', array('@theme' => $theme->info['name']))), - ); + 'attributes' => ['title' => $this->t('Install @theme as default theme', ['@theme' => $theme->info['name']])], + ]; } } // Add notes to default and administration theme. - $theme->notes = array(); + $theme->notes = []; if ($theme->is_default) { $theme->notes[] = $this->t('default theme'); } @@ -315,9 +303,9 @@ public function themesPage() { } // There are two possible theme groups. - $theme_group_titles = array( + $theme_group_titles = [ 'installed' => $this->formatPlural(count($theme_groups['installed']), 'Installed theme', 'Installed themes'), - ); + ]; if (!empty($theme_groups['uninstalled'])) { $theme_group_titles['uninstalled'] = $this->formatPlural(count($theme_groups['uninstalled']), 'Uninstalled theme', 'Uninstalled themes'); } @@ -325,12 +313,12 @@ public function themesPage() { uasort($theme_groups['installed'], 'system_sort_themes'); $this->moduleHandler()->alter('system_themes_page', $theme_groups); - $build = array(); - $build[] = array( + $build = []; + $build[] = [ '#theme' => 'system_themes_page', '#theme_groups' => $theme_groups, '#theme_group_titles' => $theme_group_titles, - ); + ]; $build[] = $this->formBuilder->getForm('Drupal\system\Form\ThemeAdminForm', $admin_theme_options); return $build; diff --git a/core/modules/system/src/Controller/SystemInfoController.php b/core/modules/system/src/Controller/SystemInfoController.php index aa9f1404..76c2c7a3 100644 --- a/core/modules/system/src/Controller/SystemInfoController.php +++ b/core/modules/system/src/Controller/SystemInfoController.php @@ -47,7 +47,7 @@ public function __construct(SystemManager $systemManager) { */ public function status() { $requirements = $this->systemManager->listRequirements(); - return array('#theme' => 'status_report', '#requirements' => $requirements); + return ['#type' => 'status_report_page', '#requirements' => $requirements]; } /** @@ -63,7 +63,7 @@ public function php() { $output = ob_get_clean(); } else { - $output = t('The phpinfo() function has been disabled for security reasons. For more information, visit Enabling and disabling phpinfo() handbook page.', array(':phpinfo' => 'https://www.drupal.org/node/243993')); + $output = t('The phpinfo() function has been disabled for security reasons. For more information, visit Enabling and disabling phpinfo() handbook page.', [':phpinfo' => 'https://www.drupal.org/node/243993']); } return new Response($output); } diff --git a/core/modules/system/src/Controller/ThemeController.php b/core/modules/system/src/Controller/ThemeController.php index e1353561..9160085b 100644 --- a/core/modules/system/src/Controller/ThemeController.php +++ b/core/modules/system/src/Controller/ThemeController.php @@ -71,15 +71,15 @@ public function uninstall(Request $request) { if (!empty($themes[$theme])) { // Do not uninstall the default or admin theme. if ($theme === $config->get('default') || $theme === $config->get('admin')) { - drupal_set_message($this->t('%theme is the default theme and cannot be uninstalled.', array('%theme' => $themes[$theme]->info['name'])), 'error'); + drupal_set_message($this->t('%theme is the default theme and cannot be uninstalled.', ['%theme' => $themes[$theme]->info['name']]), 'error'); } else { - $this->themeHandler->uninstall(array($theme)); - drupal_set_message($this->t('The %theme theme has been uninstalled.', array('%theme' => $themes[$theme]->info['name']))); + $this->themeHandler->uninstall([$theme]); + drupal_set_message($this->t('The %theme theme has been uninstalled.', ['%theme' => $themes[$theme]->info['name']])); } } else { - drupal_set_message($this->t('The %theme theme was not found.', array('%theme' => $theme)), 'error'); + drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error'); } return $this->redirect('system.themes_page'); @@ -106,12 +106,12 @@ public function install(Request $request) { if (isset($theme)) { try { - if ($this->themeHandler->install(array($theme))) { + if ($this->themeHandler->install([$theme])) { $themes = $this->themeHandler->listInfo(); - drupal_set_message($this->t('The %theme theme has been installed.', array('%theme' => $themes[$theme]->info['name']))); + drupal_set_message($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']])); } else { - drupal_set_message($this->t('The %theme theme was not found.', array('%theme' => $theme)), 'error'); + drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error'); } } catch (PreExistingConfigException $e) { @@ -121,10 +121,10 @@ public function install(Request $request) { count($config_objects), 'Unable to install @extension, %config_names already exists in active configuration.', 'Unable to install @extension, %config_names already exist in active configuration.', - array( + [ '%config_names' => implode(', ', $config_objects), '@extension' => $theme, - )), + ]), 'error' ); } @@ -160,7 +160,7 @@ public function setDefaultTheme(Request $request) { // Check if the specified theme is one recognized by the system. // Or try to install the theme. - if (isset($themes[$theme]) || $this->themeHandler->install(array($theme))) { + if (isset($themes[$theme]) || $this->themeHandler->install([$theme])) { $themes = $this->themeHandler->listInfo(); // Set the default theme. @@ -171,17 +171,17 @@ public function setDefaultTheme(Request $request) { // theme. $admin_theme = $config->get('admin'); if ($admin_theme != 0 && $admin_theme != $theme) { - drupal_set_message($this->t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', array( + drupal_set_message($this->t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', [ '%admin_theme' => $themes[$admin_theme]->info['name'], '%selected_theme' => $themes[$theme]->info['name'], - ))); + ])); } else { - drupal_set_message($this->t('%theme is now the default theme.', array('%theme' => $themes[$theme]->info['name']))); + drupal_set_message($this->t('%theme is now the default theme.', ['%theme' => $themes[$theme]->info['name']])); } } else { - drupal_set_message($this->t('The %theme theme was not found.', array('%theme' => $theme)), 'error'); + drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error'); } return $this->redirect('system.themes_page'); diff --git a/core/modules/system/src/DateFormatAccessControlHandler.php b/core/modules/system/src/DateFormatAccessControlHandler.php index 597d6cdb..e56fe92a 100644 --- a/core/modules/system/src/DateFormatAccessControlHandler.php +++ b/core/modules/system/src/DateFormatAccessControlHandler.php @@ -14,18 +14,23 @@ */ class DateFormatAccessControlHandler extends EntityAccessControlHandler { + /** + * {@inheritdoc} + */ + protected $viewLabelOperation = TRUE; + /** * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { - // There are no restrictions on viewing a date format. - if ($operation == 'view') { + // There are no restrictions on viewing the label of a date format. + if ($operation === 'view label') { return AccessResult::allowed(); } // Locked date formats cannot be updated or deleted. - elseif (in_array($operation, array('update', 'delete'))) { + elseif (in_array($operation, ['update', 'delete'])) { if ($entity->isLocked()) { - return AccessResult::forbidden()->addCacheableDependency($entity); + return AccessResult::forbidden('The DateFormat config entity is locked.')->addCacheableDependency($entity); } else { return parent::checkAccess($entity, $operation, $account)->addCacheableDependency($entity); diff --git a/core/modules/system/src/Element/StatusReportPage.php b/core/modules/system/src/Element/StatusReportPage.php new file mode 100644 index 00000000..1d8421b3 --- /dev/null +++ b/core/modules/system/src/Element/StatusReportPage.php @@ -0,0 +1,139 @@ + 'status_report_page', + '#pre_render' => [ + [$class, 'preRenderCounters'], + [$class, 'preRenderGeneralInfo'], + [$class, 'preRenderRequirements'], + ], + ]; + } + + /** + * #pre_render callback to get general info out of requirements. + */ + public static function preRenderGeneralInfo($element) { + $element['#general_info'] = [ + '#theme' => 'status_report_general_info', + ]; + // Loop through requirements and pull out items. + foreach ($element['#requirements'] as $key => $requirement) { + switch ($key) { + case 'cron': + foreach ($requirement['description'] as &$description_elements) { + foreach ($description_elements as &$description_element) { + if (isset($description_element['#url']) && $description_element['#url']->getRouteName() == 'system.run_cron') { + $description_element['#attributes']['class'][] = 'button'; + $description_element['#attributes']['class'][] = 'button--small'; + $description_element['#attributes']['class'][] = 'button--primary'; + $description_element['#attributes']['class'][] = 'system-status-general-info__run-cron'; + } + } + } + // Intentional fall-through. + + case 'drupal': + case 'webserver': + case 'database_system': + case 'database_system_version': + case 'php': + case 'php_memory_limit': + $element['#general_info']['#' . $key] = $requirement; + if (isset($requirement['severity']) && $requirement['severity'] < REQUIREMENT_WARNING) { + unset($element['#requirements'][$key]); + } + break; + } + } + + return $element; + } + + /** + * #pre_render callback to create counter elements. + */ + public static function preRenderCounters($element) { + // Count number of items with different severity for summary. + $counters = [ + 'error' => [ + 'amount' => 0, + 'text' => t('Error'), + 'text_plural' => t('Errors'), + ], + 'warning' => [ + 'amount' => 0, + 'text' => t('Warning'), + 'text_plural' => t('Warnings'), + ], + 'checked' => [ + 'amount' => 0, + 'text' => t('Checked'), + 'text_plural' => t('Checked'), + ], + ]; + + $severities = StatusReport::getSeverities(); + foreach ($element['#requirements'] as $key => &$requirement) { + $severity = $severities[REQUIREMENT_INFO]; + if (isset($requirement['severity'])) { + $severity = $severities[(int) $requirement['severity']]; + } + elseif (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'install') { + $severity = $severities[REQUIREMENT_OK]; + } + + if (isset($counters[$severity['status']])) { + $counters[$severity['status']]['amount']++; + } + } + + foreach ($counters as $key => $counter) { + if ($counter['amount'] === 0) { + continue; + } + + $text = new PluralTranslatableMarkup($counter['amount'], $counter['text'], $counter['text_plural']); + + $element['#counters'][$key] = [ + '#theme' => 'status_report_counter', + '#amount' => $counter['amount'], + '#text' => $text, + '#severity' => $key, + ]; + } + + return $element; + } + + /** + * #pre_render callback to create status report requirements. + */ + public static function preRenderRequirements($element) { + $element['#requirements'] = [ + '#type' => 'status_report', + '#requirements' => $element['#requirements'], + ]; + + return $element; + } + +} diff --git a/core/modules/system/src/Entity/Action.php b/core/modules/system/src/Entity/Action.php index 9b27616e..a4128384 100644 --- a/core/modules/system/src/Entity/Action.php +++ b/core/modules/system/src/Entity/Action.php @@ -57,7 +57,7 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface, En * * @var array */ - protected $configuration = array(); + protected $configuration = []; /** * The plugin ID of the action. @@ -90,7 +90,7 @@ protected function getPluginCollection() { * {@inheritdoc} */ public function getPluginCollections() { - return array('configuration' => $this->getPluginCollection()); + return ['configuration' => $this->getPluginCollection()]; } /** diff --git a/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php b/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php index 33eab022..b83fe7e1 100644 --- a/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php +++ b/core/modules/system/src/EventSubscriber/AdminRouteSubscriber.php @@ -31,7 +31,7 @@ public static function getSubscribedEvents() { // Use a lower priority than \Drupal\field_ui\Routing\RouteSubscriber or // \Drupal\views\EventSubscriber\RouteSubscriber to ensure we add the option // to their routes. - $events[RoutingEvents::ALTER] = array('onAlterRoutes', -200); + $events[RoutingEvents::ALTER] = ['onAlterRoutes', -200]; return $events; } diff --git a/core/modules/system/src/FileDownloadController.php b/core/modules/system/src/FileDownloadController.php index 8c95de2c..08b1632b 100644 --- a/core/modules/system/src/FileDownloadController.php +++ b/core/modules/system/src/FileDownloadController.php @@ -45,7 +45,7 @@ public function download(Request $request, $scheme = 'private') { if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) { // Let other modules provide headers and controls access to the file. - $headers = $this->moduleHandler()->invokeAll('file_download', array($uri)); + $headers = $this->moduleHandler()->invokeAll('file_download', [$uri]); foreach ($headers as $result) { if ($result == -1) { diff --git a/core/modules/system/src/Form/CronForm.php b/core/modules/system/src/Form/CronForm.php index af1623e9..3957060e 100644 --- a/core/modules/system/src/Form/CronForm.php +++ b/core/modules/system/src/Form/CronForm.php @@ -10,12 +10,15 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\State\StateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Form\ConfigFormBaseTrait; /** * Configure cron settings for this site. */ class CronForm extends FormBase { + use ConfigFormBaseTrait; + /** * Stores the state storage service. * @@ -40,7 +43,7 @@ class CronForm extends FormBase { /** * The module handler service. * - * @var \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler + * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected $moduleHandler; @@ -65,6 +68,13 @@ public function __construct(ConfigFactoryInterface $config_factory, StateInterfa $this->moduleHandler = $module_handler; } + /** + * {@inheritdoc} + */ + protected function getEditableConfigNames() { + return ['system.cron']; + } + /** * {@inheritdoc} */ @@ -89,44 +99,73 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['description'] = array( + $form['description'] = [ '#markup' => '

    ' . t('Cron takes care of running periodic tasks like checking for updates and indexing content for search.') . '

    ', - ); - $form['run'] = array( + ]; + $form['run'] = [ '#type' => 'submit', '#value' => t('Run cron'), - ); - $status = '

    ' . $this->t('Last run: %time ago.', array('%time' => $this->dateFormatter->formatTimeDiffSince($this->state->get('system.cron_last')))) . '

    '; - $form['status'] = array( + '#submit' => ['::runCron'], + ]; + $status = '

    ' . $this->t('Last run: %time ago.', ['%time' => $this->dateFormatter->formatTimeDiffSince($this->state->get('system.cron_last'))]) . '

    '; + $form['status'] = [ '#markup' => $status, - ); + ]; - $cron_url = $this->url('system.cron', array('key' => $this->state->get('system.cron_key')), array('absolute' => TRUE)); - $form['cron_url'] = array( - '#markup' => '

    ' . t('To run cron from outside the site, go to @cron', array(':cron' => $cron_url, '@cron' => $cron_url)) . '

    ', - ); + $cron_url = $this->url('system.cron', ['key' => $this->state->get('system.cron_key')], ['absolute' => TRUE]); + $form['cron_url'] = [ + '#markup' => '

    ' . t('To run cron from outside the site, go to @cron', [':cron' => $cron_url, '@cron' => $cron_url]) . '

    ', + ]; if (!$this->moduleHandler->moduleExists('automated_cron')) { - $form['cron'] = array( + $form['automated_cron'] = [ '#markup' => $this->t('Enable the Automated Cron module to allow cron execution at the end of a server response.'), - ); + ]; } + $form['cron'] = [ + '#title' => t('Cron settings'), + '#type' => 'details', + '#open' => TRUE, + ]; + + $form['cron']['logging'] = [ + '#type' => 'checkbox', + '#title' => t('Detailed cron logging'), + '#default_value' => $this->config('system.cron')->get('logging'), + '#description' => $this->t('Run times of individual cron jobs will be written to watchdog'), + ]; + + $form['actions']['#type'] = 'actions'; + $form['actions']['submit'] = [ + '#type' => 'submit', + '#value' => t('Save configuration'), + '#button_type' => 'primary', + ]; + return $form; } /** - * Runs cron and reloads the page. + * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - // Run cron manually from Cron form. + $this->config('system.cron') + ->set('logging', $form_state->getValue('logging')) + ->save(); + drupal_set_message(t('The configuration options have been saved.')); + } + + /** + * Form submission handler for running cron manually. + */ + public function runCron(array &$form, FormStateInterface $form_state) { if ($this->cron->run()) { - drupal_set_message(t('Cron ran successfully.')); + drupal_set_message($this->t('Cron ran successfully.')); } else { - drupal_set_message(t('Cron run failed.'), 'error'); + drupal_set_message($this->t('Cron run failed.'), 'error'); } - } } diff --git a/core/modules/system/src/Form/DateFormatDeleteForm.php b/core/modules/system/src/Form/DateFormatDeleteForm.php index a8e1c041..3d3047e7 100644 --- a/core/modules/system/src/Form/DateFormatDeleteForm.php +++ b/core/modules/system/src/Form/DateFormatDeleteForm.php @@ -41,10 +41,10 @@ public static function create(ContainerInterface $container) { * {@inheritdoc} */ public function getQuestion() { - return t('Are you sure you want to delete the format %name : %format?', array( + return t('Are you sure you want to delete the format %name : %format?', [ '%name' => $this->entity->label(), - '%format' => $this->dateFormatter->format(REQUEST_TIME, $this->entity->id())) - ); + '%format' => $this->dateFormatter->format(REQUEST_TIME, $this->entity->id()), + ]); } } diff --git a/core/modules/system/src/Form/DateFormatEditForm.php b/core/modules/system/src/Form/DateFormatEditForm.php index cec00208..c63c0d7a 100644 --- a/core/modules/system/src/Form/DateFormatEditForm.php +++ b/core/modules/system/src/Form/DateFormatEditForm.php @@ -15,7 +15,7 @@ class DateFormatEditForm extends DateFormatFormBase { public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); - $now = t('Displayed as %date', array('%date' => $this->dateFormatter->format(REQUEST_TIME, $this->entity->id()))); + $now = t('Displayed as %date', ['%date' => $this->dateFormatter->format(REQUEST_TIME, $this->entity->id())]); $form['date_format_pattern']['#field_suffix'] = ' ' . $now . ''; $form['date_format_pattern']['#default_value'] = $this->entity->getPattern(); diff --git a/core/modules/system/src/Form/DateFormatFormBase.php b/core/modules/system/src/Form/DateFormatFormBase.php index adb24fa4..ed6714fc 100644 --- a/core/modules/system/src/Form/DateFormatFormBase.php +++ b/core/modules/system/src/Form/DateFormatFormBase.php @@ -76,26 +76,26 @@ public function exists($entity_id, array $element) { * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => 'Name', '#maxlength' => 100, '#description' => t('Name of the date format'), '#default_value' => $this->entity->label(), - ); + ]; - $form['id'] = array( + $form['id'] = [ '#type' => 'machine_name', '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'), '#disabled' => !$this->entity->isNew(), '#default_value' => $this->entity->id(), - '#machine_name' => array( - 'exists' => array($this, 'exists'), + '#machine_name' => [ + 'exists' => [$this, 'exists'], 'replace_pattern' => '([^a-z0-9_]+)|(^custom$)', 'error' => $this->t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'), - ), - ); - $form['date_format_pattern'] = array( + ], + ]; + $form['date_format_pattern'] = [ '#type' => 'textfield', '#title' => t('Format string'), '#maxlength' => 100, @@ -105,14 +105,14 @@ public function form(array $form, FormStateInterface $form_state) { 'data-drupal-date-formatter' => 'source', ], '#field_suffix' => ' ' . $this->t('Displayed as %date_format', ['%date_format' => '']) . '', - ); + ]; - $form['langcode'] = array( + $form['langcode'] = [ '#type' => 'language_select', '#title' => t('Language'), '#languages' => LanguageInterface::STATE_ALL, '#default_value' => $this->entity->language()->getId(), - ); + ]; $form['#attached']['drupalSettings']['dateFormats'] = $this->dateFormatter->getSampleDateFormats(); $form['#attached']['library'][] = 'system/drupal.system.date'; return parent::form($form, $form_state); diff --git a/core/modules/system/src/Form/FileSystemForm.php b/core/modules/system/src/Form/FileSystemForm.php index 9271bf45..d3a6caed 100644 --- a/core/modules/system/src/Form/FileSystemForm.php +++ b/core/modules/system/src/Form/FileSystemForm.php @@ -77,59 +77,59 @@ protected function getEditableConfigNames() { */ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('system.file'); - $form['file_public_path'] = array( + $form['file_public_path'] = [ '#type' => 'item', '#title' => t('Public file system path'), '#markup' => PublicStream::basePath(), '#description' => t('A local file system path where public files will be stored. This directory must exist and be writable by Drupal. This directory must be relative to the Drupal installation directory and be accessible over the web. This must be changed in settings.php'), - ); + ]; - $form['file_public_base_url'] = array( + $form['file_public_base_url'] = [ '#type' => 'item', '#title' => t('Public file base URL'), '#markup' => PublicStream::baseUrl(), '#description' => t('The base URL that will be used for public file URLs. This can be changed in settings.php'), - ); + ]; - $form['file_private_path'] = array( + $form['file_private_path'] = [ '#type' => 'item', '#title' => t('Private file system path'), '#markup' => (PrivateStream::basePath() ? PrivateStream::basePath() : t('Not set')), '#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. This must be changed in settings.php'), - ); + ]; - $form['file_temporary_path'] = array( + $form['file_temporary_path'] = [ '#type' => 'textfield', '#title' => t('Temporary directory'), '#default_value' => $config->get('path.temporary'), '#maxlength' => 255, '#description' => t('A local file system path where temporary files will be stored. This directory should not be accessible over the web.'), - '#after_build' => array('system_check_directory'), - ); + '#after_build' => ['system_check_directory'], + ]; // Any visible, writeable wrapper can potentially be used for the files // directory, including a remote file system that integrates with a CDN. $options = $this->streamWrapperManager->getDescriptions(StreamWrapperInterface::WRITE_VISIBLE); if (!empty($options)) { - $form['file_default_scheme'] = array( + $form['file_default_scheme'] = [ '#type' => 'radios', '#title' => t('Default download method'), '#default_value' => $config->get('default_scheme'), '#options' => $options, '#description' => t('This setting is used as the preferred download method. The use of public files is more efficient, but does not provide any access control.'), - ); + ]; } - $intervals = array(0, 21600, 43200, 86400, 604800, 2419200, 7776000); - $period = array_combine($intervals, array_map(array($this->dateFormatter, 'formatInterval'), $intervals)); + $intervals = [0, 21600, 43200, 86400, 604800, 2419200, 7776000]; + $period = array_combine($intervals, array_map([$this->dateFormatter, 'formatInterval'], $intervals)); $period[0] = t('Never'); - $form['temporary_maximum_age'] = array( + $form['temporary_maximum_age'] = [ '#type' => 'select', - '#title' => t('Delete orphaned files after'), + '#title' => t('Delete temporary files after'), '#default_value' => $config->get('temporary_maximum_age'), '#options' => $period, - '#description' => t('Orphaned files are not referenced from any content but remain in the file system and may appear in administrative listings. Warning: If enabled, orphaned files will be permanently deleted and may not be recoverable.'), - ); + '#description' => t('Temporary files are not referenced, but are in the file system and therefore may show up in administrative lists. Warning: If enabled, temporary files will be permanently deleted and may not be recoverable.'), + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/system/src/Form/ImageToolkitForm.php b/core/modules/system/src/Form/ImageToolkitForm.php index 39634aea..0e70b47a 100644 --- a/core/modules/system/src/Form/ImageToolkitForm.php +++ b/core/modules/system/src/Form/ImageToolkitForm.php @@ -18,7 +18,7 @@ class ImageToolkitForm extends ConfigFormBase { * * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface[] */ - protected $availableToolkits = array(); + protected $availableToolkits = []; /** * Constructs a ImageToolkitForm object. @@ -66,30 +66,30 @@ protected function getEditableConfigNames() { public function buildForm(array $form, FormStateInterface $form_state) { $current_toolkit = $this->config('system.image')->get('toolkit'); - $form['image_toolkit'] = array( + $form['image_toolkit'] = [ '#type' => 'radios', '#title' => $this->t('Select an image processing toolkit'), '#default_value' => $current_toolkit, - '#options' => array(), - ); + '#options' => [], + ]; // If we have more than one image toolkit, allow the user to select the one // to use, and load each of the toolkits' settings form. foreach ($this->availableToolkits as $id => $toolkit) { $definition = $toolkit->getPluginDefinition(); $form['image_toolkit']['#options'][$id] = $definition['title']; - $form['image_toolkit_settings'][$id] = array( + $form['image_toolkit_settings'][$id] = [ '#type' => 'details', - '#title' => $this->t('@toolkit settings', array('@toolkit' => $definition['title'])), + '#title' => $this->t('@toolkit settings', ['@toolkit' => $definition['title']]), '#open' => TRUE, '#tree' => TRUE, - '#states' => array( - 'visible' => array( - ':radio[name="image_toolkit"]' => array('value' => $id), - ), - ), - ); - $form['image_toolkit_settings'][$id] += $toolkit->buildConfigurationForm(array(), $form_state); + '#states' => [ + 'visible' => [ + ':radio[name="image_toolkit"]' => ['value' => $id], + ], + ], + ]; + $form['image_toolkit_settings'][$id] += $toolkit->buildConfigurationForm([], $form_state); } return parent::buildForm($form, $form_state); diff --git a/core/modules/system/src/Form/LoggingForm.php b/core/modules/system/src/Form/LoggingForm.php index 22135e18..a305a4ff 100644 --- a/core/modules/system/src/Form/LoggingForm.php +++ b/core/modules/system/src/Form/LoggingForm.php @@ -29,18 +29,18 @@ protected function getEditableConfigNames() { */ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('system.logging'); - $form['error_level'] = array( + $form['error_level'] = [ '#type' => 'radios', '#title' => t('Error messages to display'), '#default_value' => $config->get('error_level'), - '#options' => array( + '#options' => [ ERROR_REPORTING_HIDE => t('None'), ERROR_REPORTING_DISPLAY_SOME => t('Errors and warnings'), ERROR_REPORTING_DISPLAY_ALL => t('All messages'), ERROR_REPORTING_DISPLAY_VERBOSE => t('All messages, with backtrace information'), - ), + ], '#description' => t('It is recommended that sites running on production environments do not display any errors.'), - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/system/src/Form/ModulesListConfirmForm.php b/core/modules/system/src/Form/ModulesListConfirmForm.php index 88452e06..50026606 100644 --- a/core/modules/system/src/Form/ModulesListConfirmForm.php +++ b/core/modules/system/src/Form/ModulesListConfirmForm.php @@ -36,7 +36,7 @@ class ModulesListConfirmForm extends ConfirmFormBase { * * @var array */ - protected $modules = array(); + protected $modules = []; /** * The module installer. @@ -120,10 +120,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { } $items = $this->buildMessageList(); - $form['message'] = array( + $form['message'] = [ '#theme' => 'item_list', '#items' => $items, - ); + ]; return parent::buildForm($form, $form_state); } @@ -177,10 +177,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) { count($config_objects), 'Unable to install @extension, %config_names already exists in active configuration.', 'Unable to install @extension, %config_names already exist in active configuration.', - array( + [ '%config_names' => implode(', ', $config_objects), '@extension' => $this->modules['install'][$e->getExtension()] - )), + ]), 'error' ); return; @@ -194,10 +194,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } $module_names = array_values($this->modules['install']); - drupal_set_message($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', array( + drupal_set_message($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', [ '%name' => $module_names[0], '%names' => implode(', ', $module_names), - ))); + ])); } $form_state->setRedirectUrl($this->getCancelUrl()); diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php index e74d898c..28ff7ef4 100644 --- a/core/modules/system/src/Form/ModulesListForm.php +++ b/core/modules/system/src/Form/ModulesListForm.php @@ -119,26 +119,26 @@ public function buildForm(array $form, FormStateInterface $form_state) { // Include system.admin.inc so we can use the sort callbacks. $this->moduleHandler->loadInclude('system', 'inc', 'system.admin'); - $form['filters'] = array( + $form['filters'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('table-filter', 'js-show'), - ), - ); + '#attributes' => [ + 'class' => ['table-filter', 'js-show'], + ], + ]; - $form['filters']['text'] = array( + $form['filters']['text'] = [ '#type' => 'search', '#title' => $this->t('Filter modules'), '#title_display' => 'invisible', '#size' => 30, '#placeholder' => $this->t('Filter by name or description'), '#description' => $this->t('Enter a part of the module name or description'), - '#attributes' => array( - 'class' => array('table-filter-text'), + '#attributes' => [ + 'class' => ['table-filter-text'], 'data-table' => '#system-modules', 'autocomplete' => 'off', - ), - ); + ], + ]; // Sort all modules by their names. $modules = system_rebuild_module_data(); @@ -150,20 +150,21 @@ public function buildForm(array $form, FormStateInterface $form_state) { if (empty($module->info['hidden'])) { $package = $module->info['package']; $form['modules'][$package][$filename] = $this->buildRow($modules, $module, $distribution); + $form['modules'][$package][$filename]['#parents'] = ['modules', $filename]; } } // Add a wrapper around every package. foreach (Element::children($form['modules']) as $package) { - $form['modules'][$package] += array( + $form['modules'][$package] += [ '#type' => 'details', '#title' => $this->t($package), '#open' => TRUE, '#theme' => 'system_modules_details', - '#attributes' => array('class' => array('package-listing')), + '#attributes' => ['class' => ['package-listing']], // Ensure that the "Core" package comes first. '#weight' => $package == 'Core' ? -10 : NULL, - ); + ]; } // If testing modules are shown, collapse the corresponding package by @@ -173,15 +174,15 @@ public function buildForm(array $form, FormStateInterface $form_state) { } // Lastly, sort all packages by title. - uasort($form['modules'], array('\Drupal\Component\Utility\SortArray', 'sortByTitleProperty')); + uasort($form['modules'], ['\Drupal\Component\Utility\SortArray', 'sortByTitleProperty']); $form['#attached']['library'][] = 'system/drupal.system.modules'; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Install'), '#button_type' => 'primary', - ); + ]; return $form; } @@ -200,9 +201,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { */ protected function buildRow(array $modules, Extension $module, $distribution) { // Set the basic properties. - $row['#required'] = array(); - $row['#requires'] = array(); - $row['#required_by'] = array(); + $row['#required'] = []; + $row['#requires'] = []; + $row['#required_by'] = []; $row['name']['#markup'] = $module->info['name']; $row['description']['#markup'] = $this->t($module->info['description']); @@ -212,48 +213,48 @@ protected function buildRow(array $modules, Extension $module, $distribution) { // implementation exists then the module provides an overview page, rather // than checking to see if the page exists, which is costly. if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) { - $row['links']['help'] = array( + $row['links']['help'] = [ '#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), - '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))), - ); + '#options' => ['attributes' => ['class' => ['module-link', 'module-link-help'], 'title' => $this->t('Help')]], + ]; } // Generate link for module's permission, if the user has access to it. if ($module->status && $this->currentUser->hasPermission('administer permissions') && $this->permissionHandler->moduleProvidesPermissions($module->getName())) { - $row['links']['permissions'] = array( + $row['links']['permissions'] = [ '#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), - '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))), - ); + '#options' => ['fragment' => 'module-' . $module->getName(), 'attributes' => ['class' => ['module-link', 'module-link-permissions'], 'title' => $this->t('Configure permissions')]], + ]; } // Generate link for module's configuration page, if it has one. if ($module->status && isset($module->info['configure'])) { - $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array(); + $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : []; if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) { - $row['links']['configure'] = array( + $row['links']['configure'] = [ '#type' => 'link', '#title' => $this->t('Configure the @module module', ['@module' => $module->info['name']]), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), - '#options' => array( - 'attributes' => array( - 'class' => array('module-link', 'module-link-configure'), - ), - ), - ); + '#options' => [ + 'attributes' => [ + 'class' => ['module-link', 'module-link-configure'], + ], + ], + ]; } } // Present a checkbox for installing and indicating the status of a module. - $row['enable'] = array( + $row['enable'] = [ '#type' => 'checkbox', '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status, - ); + ]; // Disable the checkbox for required modules. if (!empty($module->info['required'])) { @@ -267,24 +268,24 @@ protected function buildRow(array $modules, Extension $module, $distribution) { // Initialize an empty array of reasons why the module is incompatible. Add // each reason as a separate element of the array. - $reasons = array(); + $reasons = []; // Check the core compatibility. if ($module->info['core'] != \Drupal::CORE_COMPATIBILITY) { $compatible = FALSE; - $reasons[] = $this->t('This version is not compatible with Drupal @core_version and should be replaced.', array( + $reasons[] = $this->t('This version is not compatible with Drupal @core_version and should be replaced.', [ '@core_version' => \Drupal::CORE_COMPATIBILITY, - )); + ]); } // Ensure this module is compatible with the currently installed version of PHP. if (version_compare(phpversion(), $module->info['php']) < 0) { $compatible = FALSE; $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : ''); - $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version @php_version.', array( + $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version @php_version.', [ '@php_required' => $required, '@php_version' => phpversion(), - )); + ]); } // If this module is not compatible, disable the checkbox. @@ -298,7 +299,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) { // If this module requires other modules, add them to the array. foreach ($module->requires as $dependency => $version) { if (!isset($modules[$dependency])) { - $row['#requires'][$dependency] = $this->t('@module (missing)', array('@module' => Unicode::ucfirst($dependency))); + $row['#requires'][$dependency] = $this->t('@module (missing)', ['@module' => Unicode::ucfirst($dependency)]); $row['enable']['#disabled'] = TRUE; } // Only display visible modules. @@ -307,25 +308,25 @@ protected function buildRow(array $modules, Extension $module, $distribution) { // Disable the module's checkbox if it is incompatible with the // dependency's version. if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) { - $row['#requires'][$dependency] = $this->t('@module (incompatible with version @version)', array( + $row['#requires'][$dependency] = $this->t('@module (incompatible with version @version)', [ '@module' => $name . $incompatible_version, '@version' => $modules[$dependency]->info['version'], - )); + ]); $row['enable']['#disabled'] = TRUE; } // Disable the checkbox if the dependency is incompatible with this // version of Drupal core. elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) { - $row['#requires'][$dependency] = $this->t('@module (incompatible with this version of Drupal core)', array( + $row['#requires'][$dependency] = $this->t('@module (incompatible with this version of Drupal core)', [ '@module' => $name, - )); + ]); $row['enable']['#disabled'] = TRUE; } elseif ($modules[$dependency]->status) { - $row['#requires'][$dependency] = $this->t('@module', array('@module' => $name)); + $row['#requires'][$dependency] = $this->t('@module', ['@module' => $name]); } else { - $row['#requires'][$dependency] = $this->t('@module (disabled)', array('@module' => $name)); + $row['#requires'][$dependency] = $this->t('@module (disabled)', ['@module' => $name]); } } } @@ -335,11 +336,11 @@ protected function buildRow(array $modules, Extension $module, $distribution) { foreach ($module->required_by as $dependent => $version) { if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) { if ($modules[$dependent]->status == 1 && $module->status == 1) { - $row['#required_by'][$dependent] = $this->t('@module', array('@module' => $modules[$dependent]->info['name'])); + $row['#required_by'][$dependent] = $this->t('@module', ['@module' => $modules[$dependent]->info['name']]); $row['enable']['#disabled'] = TRUE; } else { - $row['#required_by'][$dependent] = $this->t('@module (disabled)', array('@module' => $modules[$dependent]->info['name'])); + $row['#required_by'][$dependent] = $this->t('@module (disabled)', ['@module' => $modules[$dependent]->info['name']]); } } } @@ -357,33 +358,29 @@ protected function buildRow(array $modules, Extension $module, $distribution) { * An array of modules to install and their dependencies. */ protected function buildModuleList(FormStateInterface $form_state) { - $packages = $form_state->getValue('modules'); - // Build a list of modules to install. - $modules = array( - 'install' => array(), - 'dependencies' => array(), + $modules = [ + 'install' => [], + 'dependencies' => [], 'experimental' => [], - ); + ]; - // Required modules have to be installed. - // @todo This should really not be handled here. $data = system_rebuild_module_data(); foreach ($data as $name => $module) { - if (!empty($module->required) && !$this->moduleHandler->moduleExists($name)) { + // If the module is installed there is nothing to do. + if ($this->moduleHandler->moduleExists($name)) { + continue; + } + // Required modules have to be installed. + if (!empty($module->required)) { $modules['install'][$name] = $module->info['name']; } - } - - // First, build a list of all modules that were selected. - foreach ($packages as $package => $items) { - foreach ($items as $name => $checkbox) { - if ($checkbox['enable'] && !$this->moduleHandler->moduleExists($name)) { - $modules['install'][$name] = $data[$name]->info['name']; - // Identify experimental modules. - if ($package == 'Core (Experimental)') { - $modules['experimental'][$name] = $data[$name]->info['name']; - } + // Selected modules should be installed. + elseif (($checkbox = $form_state->getValue(['modules', $name], FALSE)) && $checkbox['enable']) { + $modules['install'][$name] = $data[$name]->info['name']; + // Identify experimental modules. + if ($data[$name]->info['package'] == 'Core (Experimental)') { + $modules['experimental'][$name] = $data[$name]->info['name']; } } } @@ -450,10 +447,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) { try { $this->moduleInstaller->install(array_keys($modules['install'])); $module_names = array_values($modules['install']); - drupal_set_message($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', array( + drupal_set_message($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', [ '%name' => $module_names[0], '%names' => implode(', ', $module_names), - ))); + ])); } catch (PreExistingConfigException $e) { $config_objects = $e->flattenConfigObjects($e->getConfigObjects()); @@ -462,10 +459,10 @@ public function submitForm(array &$form, FormStateInterface $form_state) { count($config_objects), 'Unable to install @extension, %config_names already exists in active configuration.', 'Unable to install @extension, %config_names already exist in active configuration.', - array( + [ '%config_names' => implode(', ', $config_objects), '@extension' => $modules['install'][$e->getExtension()] - )), + ]), 'error' ); return; diff --git a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php index f4a48230..c72f240a 100644 --- a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php +++ b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php @@ -51,7 +51,7 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase { * * @var array */ - protected $modules = array(); + protected $modules = []; /** * Constructs a ModulesUninstallConfirmForm object. @@ -135,12 +135,12 @@ public function buildForm(array $form, FormStateInterface $form_state) { $data = system_rebuild_module_data(); $form['text']['#markup'] = '

    ' . $this->t('The following modules will be completely uninstalled from your site, and all data from these modules will be lost!') . '

    '; - $form['modules'] = array( + $form['modules'] = [ '#theme' => 'item_list', '#items' => array_map(function ($module) use ($data) { return $data[$module]->info['name']; }, $this->modules), - ); + ]; // List the dependent entities. $this->addDependencyListsToForm($form, 'module', $this->modules, $this->configManager, $this->entityManager); diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php index 92a15a78..80348c59 100644 --- a/core/modules/system/src/Form/ModulesUninstallForm.php +++ b/core/modules/system/src/Form/ModulesUninstallForm.php @@ -85,28 +85,28 @@ public function buildForm(array $form, FormStateInterface $form_state) { // Include system.admin.inc so we can use the sort callbacks. $this->moduleHandler->loadInclude('system', 'inc', 'system.admin'); - $form['filters'] = array( + $form['filters'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('table-filter', 'js-show'), - ), - ); + '#attributes' => [ + 'class' => ['table-filter', 'js-show'], + ], + ]; - $form['filters']['text'] = array( + $form['filters']['text'] = [ '#type' => 'search', '#title' => $this->t('Filter modules'), '#title_display' => 'invisible', '#size' => 30, '#placeholder' => $this->t('Filter by name or description'), '#description' => $this->t('Enter a part of the module name or description'), - '#attributes' => array( - 'class' => array('table-filter-text'), + '#attributes' => [ + 'class' => ['table-filter-text'], 'data-table' => '#system-modules-uninstall', 'autocomplete' => 'off', - ), - ); + ], + ]; - $form['modules'] = array(); + $form['modules'] = []; // Only build the rest of the form if there are any modules available to // uninstall; @@ -120,18 +120,18 @@ public function buildForm(array $form, FormStateInterface $form_state) { uasort($uninstallable, 'system_sort_modules_by_info_name'); $validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable)); - $form['uninstall'] = array('#tree' => TRUE); + $form['uninstall'] = ['#tree' => TRUE]; foreach ($uninstallable as $module_key => $module) { $name = $module->info['name'] ?: $module->getName(); $form['modules'][$module->getName()]['#module_name'] = $name; $form['modules'][$module->getName()]['name']['#markup'] = $name; $form['modules'][$module->getName()]['description']['#markup'] = $this->t($module->info['description']); - $form['uninstall'][$module->getName()] = array( + $form['uninstall'][$module->getName()] = [ '#type' => 'checkbox', - '#title' => $this->t('Uninstall @module module', array('@module' => $name)), + '#title' => $this->t('Uninstall @module module', ['@module' => $name]), '#title_display' => 'invisible', - ); + ]; // If a validator returns reasons not to uninstall a module, // list the reasons and disable the check box. @@ -152,11 +152,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { } $form['#attached']['library'][] = 'system/drupal.system.modules'; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Uninstall'), - ); + ]; return $form; } diff --git a/core/modules/system/src/Form/PerformanceForm.php b/core/modules/system/src/Form/PerformanceForm.php index d9e09179..33f99dbc 100644 --- a/core/modules/system/src/Form/PerformanceForm.php +++ b/core/modules/system/src/Form/PerformanceForm.php @@ -5,7 +5,6 @@ use Drupal\Core\Asset\AssetCollectionOptimizerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Datetime\DateFormatterInterface; use Drupal\Core\Form\FormStateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -15,13 +14,6 @@ */ class PerformanceForm extends ConfigFormBase { - /** - * The render cache bin. - * - * @var \Drupal\Core\Cache\CacheBackendInterface - */ - protected $renderCache; - /** * The date formatter service. * @@ -48,7 +40,6 @@ class PerformanceForm extends ConfigFormBase { * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The factory for configuration objects. - * @param \Drupal\Core\Cache\CacheBackendInterface $render_cache * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter * The date formatter service. * @param \Drupal\Core\Asset\AssetCollectionOptimizerInterface $css_collection_optimizer @@ -56,10 +47,9 @@ class PerformanceForm extends ConfigFormBase { * @param \Drupal\Core\Asset\AssetCollectionOptimizerInterface $js_collection_optimizer * The JavaScript asset collection optimizer service. */ - public function __construct(ConfigFactoryInterface $config_factory, CacheBackendInterface $render_cache, DateFormatterInterface $date_formatter, AssetCollectionOptimizerInterface $css_collection_optimizer, AssetCollectionOptimizerInterface $js_collection_optimizer) { + public function __construct(ConfigFactoryInterface $config_factory, DateFormatterInterface $date_formatter, AssetCollectionOptimizerInterface $css_collection_optimizer, AssetCollectionOptimizerInterface $js_collection_optimizer) { parent::__construct($config_factory); - $this->renderCache = $render_cache; $this->dateFormatter = $date_formatter; $this->cssCollectionOptimizer = $css_collection_optimizer; $this->jsCollectionOptimizer = $js_collection_optimizer; @@ -71,7 +61,6 @@ public function __construct(ConfigFactoryInterface $config_factory, CacheBackend public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('cache.render'), $container->get('date.formatter'), $container->get('asset.css.collection_optimizer'), $container->get('asset.js.collection_optimizer') @@ -100,64 +89,64 @@ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('system.performance'); - $form['clear_cache'] = array( + $form['clear_cache'] = [ '#type' => 'details', '#title' => t('Clear cache'), '#open' => TRUE, - ); + ]; - $form['clear_cache']['clear'] = array( + $form['clear_cache']['clear'] = [ '#type' => 'submit', '#value' => t('Clear all caches'), - '#submit' => array('::submitCacheClear'), - ); + '#submit' => ['::submitCacheClear'], + ]; - $form['caching'] = array( + $form['caching'] = [ '#type' => 'details', '#title' => t('Caching'), '#open' => TRUE, '#description' => $this->t('Note: Drupal provides an internal page cache module that is recommended for small to medium-sized websites.'), - ); + ]; // Identical options to the ones for block caching. // @see \Drupal\Core\Block\BlockBase::buildConfigurationForm() - $period = array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400); - $period = array_map(array($this->dateFormatter, 'formatInterval'), array_combine($period, $period)); + $period = [0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400]; + $period = array_map([$this->dateFormatter, 'formatInterval'], array_combine($period, $period)); $period[0] = '<' . t('no caching') . '>'; - $form['caching']['page_cache_maximum_age'] = array( + $form['caching']['page_cache_maximum_age'] = [ '#type' => 'select', '#title' => t('Page cache maximum age'), '#default_value' => $config->get('cache.page.max_age'), '#options' => $period, '#description' => t('The maximum time a page can be cached by browsers and proxies. This is used as the value for max-age in Cache-Control headers.'), - ); + ]; $directory = 'public://'; $is_writable = is_dir($directory) && is_writable($directory); $disabled = !$is_writable; $disabled_message = ''; if (!$is_writable) { - $disabled_message = ' ' . t('Set up the public files directory to make these optimizations available.', array(':file-system' => $this->url('system.file_system_settings'))); + $disabled_message = ' ' . t('Set up the public files directory to make these optimizations available.', [':file-system' => $this->url('system.file_system_settings')]); } - $form['bandwidth_optimization'] = array( + $form['bandwidth_optimization'] = [ '#type' => 'details', '#title' => t('Bandwidth optimization'), '#open' => TRUE, '#description' => t('External resources can be optimized automatically, which can reduce both the size and number of requests made to your website.') . $disabled_message, - ); + ]; - $form['bandwidth_optimization']['preprocess_css'] = array( + $form['bandwidth_optimization']['preprocess_css'] = [ '#type' => 'checkbox', '#title' => t('Aggregate CSS files'), '#default_value' => $config->get('css.preprocess'), '#disabled' => $disabled, - ); - $form['bandwidth_optimization']['preprocess_js'] = array( + ]; + $form['bandwidth_optimization']['preprocess_js'] = [ '#type' => 'checkbox', '#title' => t('Aggregate JavaScript files'), '#default_value' => $config->get('js.preprocess'), '#disabled' => $disabled, - ); + ]; return parent::buildForm($form, $form_state); } @@ -168,10 +157,6 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { $this->cssCollectionOptimizer->deleteAll(); $this->jsCollectionOptimizer->deleteAll(); - // This form allows page compression settings to be changed, which can - // invalidate cached pages in the render cache, so it needs to be cleared on - // form submit. - $this->renderCache->deleteAll(); $this->config('system.performance') ->set('cache.page.max_age', $form_state->getValue('page_cache_maximum_age')) diff --git a/core/modules/system/src/Form/RegionalForm.php b/core/modules/system/src/Form/RegionalForm.php index 9472a4cb..a66b26b1 100644 --- a/core/modules/system/src/Form/RegionalForm.php +++ b/core/modules/system/src/Form/RegionalForm.php @@ -65,78 +65,78 @@ public function buildForm(array $form, FormStateInterface $form_state) { $system_date = $this->config('system.date'); // Date settings: - $zones = system_time_zones(); + $zones = system_time_zones(NULL, TRUE); - $form['locale'] = array( + $form['locale'] = [ '#type' => 'details', '#title' => t('Locale'), '#open' => TRUE, - ); + ]; - $form['locale']['site_default_country'] = array( + $form['locale']['site_default_country'] = [ '#type' => 'select', '#title' => t('Default country'), '#empty_value' => '', '#default_value' => $system_date->get('country.default'), '#options' => $countries, - '#attributes' => array('class' => array('country-detect')), - ); + '#attributes' => ['class' => ['country-detect']], + ]; - $form['locale']['date_first_day'] = array( + $form['locale']['date_first_day'] = [ '#type' => 'select', '#title' => t('First day of week'), '#default_value' => $system_date->get('first_day'), - '#options' => array(0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'), 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday')), - ); + '#options' => [0 => t('Sunday'), 1 => t('Monday'), 2 => t('Tuesday'), 3 => t('Wednesday'), 4 => t('Thursday'), 5 => t('Friday'), 6 => t('Saturday')], + ]; - $form['timezone'] = array( + $form['timezone'] = [ '#type' => 'details', '#title' => t('Time zones'), '#open' => TRUE, - ); + ]; - $form['timezone']['date_default_timezone'] = array( + $form['timezone']['date_default_timezone'] = [ '#type' => 'select', '#title' => t('Default time zone'), '#default_value' => $system_date->get('timezone.default') ?: date_default_timezone_get(), '#options' => $zones, - ); + ]; $configurable_timezones = $system_date->get('timezone.user.configurable'); - $form['timezone']['configurable_timezones'] = array( + $form['timezone']['configurable_timezones'] = [ '#type' => 'checkbox', '#title' => t('Users may set their own time zone'), '#default_value' => $configurable_timezones, - ); + ]; - $form['timezone']['configurable_timezones_wrapper'] = array( + $form['timezone']['configurable_timezones_wrapper'] = [ '#type' => 'container', - '#states' => array( + '#states' => [ // Hide the user configured timezone settings when users are forced to use // the default setting. - 'invisible' => array( - 'input[name="configurable_timezones"]' => array('checked' => FALSE), - ), - ), - ); - $form['timezone']['configurable_timezones_wrapper']['empty_timezone_message'] = array( + 'invisible' => [ + 'input[name="configurable_timezones"]' => ['checked' => FALSE], + ], + ], + ]; + $form['timezone']['configurable_timezones_wrapper']['empty_timezone_message'] = [ '#type' => 'checkbox', '#title' => t('Remind users at login if their time zone is not set'), '#default_value' => $system_date->get('timezone.user.warn'), '#description' => t('Only applied if users may set their own time zone.') - ); + ]; - $form['timezone']['configurable_timezones_wrapper']['user_default_timezone'] = array( + $form['timezone']['configurable_timezones_wrapper']['user_default_timezone'] = [ '#type' => 'radios', '#title' => t('Time zone for new users'), '#default_value' => $system_date->get('timezone.user.default'), - '#options' => array( + '#options' => [ DRUPAL_USER_TIMEZONE_DEFAULT => t('Default time zone'), DRUPAL_USER_TIMEZONE_EMPTY => t('Empty time zone'), DRUPAL_USER_TIMEZONE_SELECT => t('Users may set their own time zone at registration'), - ), + ], '#description' => t('Only applied if users may set their own time zone.') - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/system/src/Form/RssFeedsForm.php b/core/modules/system/src/Form/RssFeedsForm.php index 79aa69ba..986ff114 100644 --- a/core/modules/system/src/Form/RssFeedsForm.php +++ b/core/modules/system/src/Form/RssFeedsForm.php @@ -29,31 +29,31 @@ protected function getEditableConfigNames() { */ public function buildForm(array $form, FormStateInterface $form_state) { $rss_config = $this->config('system.rss'); - $form['feed_description'] = array( + $form['feed_description'] = [ '#type' => 'textarea', '#title' => t('Feed description'), '#default_value' => $rss_config->get('channel.description'), '#description' => t('Description of your site, included in each feed.') - ); - $options = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30); - $form['feed_default_items'] = array( + ]; + $options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30]; + $form['feed_default_items'] = [ '#type' => 'select', '#title' => t('Number of items in each feed'), '#default_value' => $rss_config->get('items.limit'), '#options' => array_combine($options, $options), '#description' => t('Default number of items to include in each feed.') - ); - $form['feed_view_mode'] = array( + ]; + $form['feed_view_mode'] = [ '#type' => 'select', '#title' => t('Feed content'), '#default_value' => $rss_config->get('items.view_mode'), - '#options' => array( + '#options' => [ 'title' => t('Titles only'), 'teaser' => t('Titles plus teaser'), 'fulltext' => t('Full text'), - ), + ], '#description' => t('Global setting for the default display of content items in each feed.') - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/system/src/Form/SiteInformationForm.php b/core/modules/system/src/Form/SiteInformationForm.php index 92986d6d..7173ebe9 100644 --- a/core/modules/system/src/Form/SiteInformationForm.php +++ b/core/modules/system/src/Form/SiteInformationForm.php @@ -92,63 +92,63 @@ public function buildForm(array $form, FormStateInterface $form_state) { $site_mail = ini_get('sendmail_from'); } - $form['site_information'] = array( + $form['site_information'] = [ '#type' => 'details', '#title' => t('Site details'), '#open' => TRUE, - ); - $form['site_information']['site_name'] = array( + ]; + $form['site_information']['site_name'] = [ '#type' => 'textfield', '#title' => t('Site name'), '#default_value' => $site_config->get('name'), '#required' => TRUE, - ); - $form['site_information']['site_slogan'] = array( + ]; + $form['site_information']['site_slogan'] = [ '#type' => 'textfield', '#title' => t('Slogan'), '#default_value' => $site_config->get('slogan'), '#description' => t("How this is used depends on your site's theme."), - ); - $form['site_information']['site_mail'] = array( + ]; + $form['site_information']['site_mail'] = [ '#type' => 'email', '#title' => t('Email address'), '#default_value' => $site_mail, '#description' => t("The From address in automated emails sent during registration and new password requests, and other notifications. (Use an address ending in your site's domain to help prevent this email being flagged as spam.)"), '#required' => TRUE, - ); - $form['front_page'] = array( + ]; + $form['front_page'] = [ '#type' => 'details', '#title' => t('Front page'), '#open' => TRUE, - ); + ]; $front_page = $site_config->get('page.front') != '/user/login' ? $this->aliasManager->getAliasByPath($site_config->get('page.front')) : ''; - $form['front_page']['site_frontpage'] = array( + $form['front_page']['site_frontpage'] = [ '#type' => 'textfield', '#title' => t('Default front page'), '#default_value' => $front_page, '#size' => 40, '#description' => t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default front page.'), '#field_prefix' => $this->requestContext->getCompleteBaseUrl(), - ); - $form['error_page'] = array( + ]; + $form['error_page'] = [ '#type' => 'details', '#title' => t('Error pages'), '#open' => TRUE, - ); - $form['error_page']['site_403'] = array( + ]; + $form['error_page']['site_403'] = [ '#type' => 'textfield', '#title' => t('Default 403 (access denied) page'), '#default_value' => $site_config->get('page.403'), '#size' => 40, '#description' => t('This page is displayed when the requested document is denied to the current user. Leave blank to display a generic "access denied" page.'), - ); - $form['error_page']['site_404'] = array( + ]; + $form['error_page']['site_404'] = [ '#type' => 'textfield', '#title' => t('Default 404 (not found) page'), '#default_value' => $site_config->get('page.404'), '#size' => 40, '#description' => t('This page is displayed when no other content matches the requested document. Leave blank to display a generic "page not found" page.'), - ); + ]; return parent::buildForm($form, $form_state); } @@ -172,7 +172,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { } if (!$this->pathValidator->isValid($form_state->getValue('site_frontpage'))) { - $form_state->setErrorByName('site_frontpage', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_frontpage')))); + $form_state->setErrorByName('site_frontpage', $this->t("The path '%path' is either invalid or you do not have access to it.", ['%path' => $form_state->getValue('site_frontpage')])); } // Get the normal paths of both error pages. if (!$form_state->isValueEmpty('site_403')) { @@ -189,11 +189,11 @@ public function validateForm(array &$form, FormStateInterface $form_state) { } // Validate 403 error path. if (!$form_state->isValueEmpty('site_403') && !$this->pathValidator->isValid($form_state->getValue('site_403'))) { - $form_state->setErrorByName('site_403', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_403')))); + $form_state->setErrorByName('site_403', $this->t("The path '%path' is either invalid or you do not have access to it.", ['%path' => $form_state->getValue('site_403')])); } // Validate 404 error path. if (!$form_state->isValueEmpty('site_404') && !$this->pathValidator->isValid($form_state->getValue('site_404'))) { - $form_state->setErrorByName('site_404', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_404')))); + $form_state->setErrorByName('site_404', $this->t("The path '%path' is either invalid or you do not have access to it.", ['%path' => $form_state->getValue('site_404')])); } parent::validateForm($form, $form_state); diff --git a/core/modules/system/src/Form/SiteMaintenanceModeForm.php b/core/modules/system/src/Form/SiteMaintenanceModeForm.php index 02c5a9a3..fb509aaf 100644 --- a/core/modules/system/src/Form/SiteMaintenanceModeForm.php +++ b/core/modules/system/src/Form/SiteMaintenanceModeForm.php @@ -6,6 +6,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Form\ConfigFormBase; +use Drupal\user\PermissionHandlerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -20,6 +21,13 @@ class SiteMaintenanceModeForm extends ConfigFormBase { */ protected $state; + /** + * The permission handler. + * + * @var \Drupal\user\PermissionHandlerInterface + */ + protected $permissionHandler; + /** * Constructs a new SiteMaintenanceModeForm. * @@ -27,10 +35,13 @@ class SiteMaintenanceModeForm extends ConfigFormBase { * The factory for configuration objects. * @param \Drupal\Core\State\StateInterface $state * The state keyvalue collection to use. + * @param \Drupal\user\PermissionHandlerInterface $permission_handler + * The permission handler. */ - public function __construct(ConfigFactoryInterface $config_factory, StateInterface $state) { + public function __construct(ConfigFactoryInterface $config_factory, StateInterface $state, PermissionHandlerInterface $permission_handler) { parent::__construct($config_factory); $this->state = $state; + $this->permissionHandler = $permission_handler; } /** @@ -39,7 +50,8 @@ public function __construct(ConfigFactoryInterface $config_factory, StateInterfa public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), - $container->get('state') + $container->get('state'), + $container->get('user.permissions') ); } /** @@ -61,17 +73,19 @@ protected function getEditableConfigNames() { */ public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('system.maintenance'); - $form['maintenance_mode'] = array( + $permissions = $this->permissionHandler->getPermissions(); + $permission_label = $permissions['access site in maintenance mode']['title']; + $form['maintenance_mode'] = [ '#type' => 'checkbox', '#title' => t('Put site into maintenance mode'), '#default_value' => $this->state->get('system.maintenance_mode'), - '#description' => t('Visitors will only see the maintenance mode message. Only users with the "Access site in maintenance mode" permission will be able to access the site. Authorized users can log in directly via the user login page.', array(':permissions-url' => $this->url('user.admin_permissions'), ':user-login' => $this->url('user.login'))), - ); - $form['maintenance_mode_message'] = array( + '#description' => t('Visitors will only see the maintenance mode message. Only users with the "@permission-label" permission will be able to access the site. Authorized users can log in directly via the user login page.', ['@permission-label' => $permission_label, ':permissions-url' => $this->url('user.admin_permissions'), ':user-login' => $this->url('user.login')]), + ]; + $form['maintenance_mode_message'] = [ '#type' => 'textarea', '#title' => t('Message to display when in maintenance mode'), '#default_value' => $config->get('message'), - ); + ]; return parent::buildForm($form, $form_state); } diff --git a/core/modules/system/src/Form/ThemeAdminForm.php b/core/modules/system/src/Form/ThemeAdminForm.php index a3ec4191..e8d17edd 100644 --- a/core/modules/system/src/Form/ThemeAdminForm.php +++ b/core/modules/system/src/Form/ThemeAdminForm.php @@ -29,24 +29,24 @@ protected function getEditableConfigNames() { */ public function buildForm(array $form, FormStateInterface $form_state, array $theme_options = NULL) { // Administration theme settings. - $form['admin_theme'] = array( + $form['admin_theme'] = [ '#type' => 'details', '#title' => $this->t('Administration theme'), '#open' => TRUE, - ); - $form['admin_theme']['admin_theme'] = array( + ]; + $form['admin_theme']['admin_theme'] = [ '#type' => 'select', - '#options' => array(0 => $this->t('Default theme')) + $theme_options, + '#options' => [0 => $this->t('Default theme')] + $theme_options, '#title' => $this->t('Administration theme'), '#description' => $this->t('Choose "Default theme" to always use the same theme as the rest of the site.'), '#default_value' => $this->config('system.theme')->get('admin'), - ); - $form['admin_theme']['actions'] = array('#type' => 'actions'); - $form['admin_theme']['actions']['submit'] = array( + ]; + $form['admin_theme']['actions'] = ['#type' => 'actions']; + $form['admin_theme']['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save configuration'), '#button_type' => 'primary', - ); + ]; return $form; } diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php index 7e9893c3..2ad98931 100644 --- a/core/modules/system/src/Form/ThemeSettingsForm.php +++ b/core/modules/system/src/Form/ThemeSettingsForm.php @@ -12,6 +12,7 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; +use Drupal\Core\Theme\ThemeManagerInterface; /** * Displays theme configuration for entire site and individual themes. @@ -46,6 +47,13 @@ class ThemeSettingsForm extends ConfigFormBase { */ protected $editableConfig = []; + /** + * The theme manager. + * + * @var \Drupal\Core\Theme\ThemeManagerInterface + */ + protected $themeManager; + /** * Constructs a ThemeSettingsForm object. * @@ -58,12 +66,13 @@ class ThemeSettingsForm extends ConfigFormBase { * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser * The MIME type guesser instance to use. */ - public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, MimeTypeGuesserInterface $mime_type_guesser) { + public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, MimeTypeGuesserInterface $mime_type_guesser, ThemeManagerInterface $theme_manager) { parent::__construct($config_factory); $this->moduleHandler = $module_handler; $this->themeHandler = $theme_handler; $this->mimeTypeGuesser = $mime_type_guesser; + $this->themeManager = $theme_manager; } /** @@ -74,7 +83,8 @@ public static function create(ContainerInterface $container) { $container->get('config.factory'), $container->get('module_handler'), $container->get('theme_handler'), - $container->get('file.mime_type.guesser') + $container->get('file.mime_type.guesser'), + $container->get('theme.manager') ); } @@ -122,25 +132,25 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = // by https://www.drupal.org/node/2402467. $this->editableConfig = [$config_key]; - $form['var'] = array( + $form['var'] = [ '#type' => 'hidden', '#value' => $var - ); - $form['config_key'] = array( + ]; + $form['config_key'] = [ '#type' => 'hidden', '#value' => $config_key - ); + ]; // Toggle settings - $toggles = array( + $toggles = [ 'node_user_picture' => t('User pictures in posts'), 'comment_user_picture' => t('User pictures in comments'), 'comment_user_verification' => t('User verification status in comments'), 'favicon' => t('Shortcut icon'), - ); + ]; // Some features are not always available - $disabled = array(); + $disabled = []; if (!user_picture_enabled()) { $disabled['toggle_node_user_picture'] = TRUE; $disabled['toggle_comment_user_picture'] = TRUE; @@ -150,14 +160,14 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = $disabled['toggle_comment_user_verification'] = TRUE; } - $form['theme_settings'] = array( + $form['theme_settings'] = [ '#type' => 'details', '#title' => t('Page element display'), '#open' => TRUE, - ); + ]; foreach ($toggles as $name => $title) { if ((!$theme) || in_array($name, $features)) { - $form['theme_settings']['toggle_' . $name] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => theme_get_setting('features.' . $name, $theme)); + $form['theme_settings']['toggle_' . $name] = ['#type' => 'checkbox', '#title' => $title, '#default_value' => theme_get_setting('features.' . $name, $theme)]; // Disable checkboxes for features not supported in the current configuration. if (isset($disabled['toggle_' . $name])) { $form['theme_settings']['toggle_' . $name]['#disabled'] = TRUE; @@ -173,82 +183,82 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = // Logo settings, only available when file.module is enabled. if ((!$theme || in_array('logo', $features)) && $this->moduleHandler->moduleExists('file')) { - $form['logo'] = array( + $form['logo'] = [ '#type' => 'details', '#title' => t('Logo image'), '#open' => TRUE, - ); - $form['logo']['default_logo'] = array( + ]; + $form['logo']['default_logo'] = [ '#type' => 'checkbox', '#title' => t('Use the logo supplied by the theme'), '#default_value' => theme_get_setting('logo.use_default', $theme), '#tree' => FALSE, - ); - $form['logo']['settings'] = array( + ]; + $form['logo']['settings'] = [ '#type' => 'container', - '#states' => array( + '#states' => [ // Hide the logo settings when using the default logo. - 'invisible' => array( - 'input[name="default_logo"]' => array('checked' => TRUE), - ), - ), - ); - $form['logo']['settings']['logo_path'] = array( + 'invisible' => [ + 'input[name="default_logo"]' => ['checked' => TRUE], + ], + ], + ]; + $form['logo']['settings']['logo_path'] = [ '#type' => 'textfield', '#title' => t('Path to custom logo'), '#default_value' => theme_get_setting('logo.path', $theme), - ); - $form['logo']['settings']['logo_upload'] = array( + ]; + $form['logo']['settings']['logo_upload'] = [ '#type' => 'file', '#title' => t('Upload logo image'), '#maxlength' => 40, '#description' => t("If you don't have direct file access to the server, use this field to upload your logo.") - ); + ]; } if (((!$theme) || in_array('favicon', $features)) && $this->moduleHandler->moduleExists('file')) { - $form['favicon'] = array( + $form['favicon'] = [ '#type' => 'details', '#title' => t('Favicon'), '#open' => TRUE, '#description' => t("Your shortcut icon, or favicon, is displayed in the address bar and bookmarks of most browsers."), - '#states' => array( + '#states' => [ // Hide the shortcut icon settings fieldset when shortcut icon display // is disabled. - 'invisible' => array( - 'input[name="toggle_favicon"]' => array('checked' => FALSE), - ), - ), - ); - $form['favicon']['default_favicon'] = array( + 'invisible' => [ + 'input[name="toggle_favicon"]' => ['checked' => FALSE], + ], + ], + ]; + $form['favicon']['default_favicon'] = [ '#type' => 'checkbox', '#title' => t('Use the favicon supplied by the theme'), '#default_value' => theme_get_setting('favicon.use_default', $theme), - ); - $form['favicon']['settings'] = array( + ]; + $form['favicon']['settings'] = [ '#type' => 'container', - '#states' => array( + '#states' => [ // Hide the favicon settings when using the default favicon. - 'invisible' => array( - 'input[name="default_favicon"]' => array('checked' => TRUE), - ), - ), - ); - $form['favicon']['settings']['favicon_path'] = array( + 'invisible' => [ + 'input[name="default_favicon"]' => ['checked' => TRUE], + ], + ], + ]; + $form['favicon']['settings']['favicon_path'] = [ '#type' => 'textfield', '#title' => t('Path to custom icon'), '#default_value' => theme_get_setting('favicon.path', $theme), - ); - $form['favicon']['settings']['favicon_upload'] = array( + ]; + $form['favicon']['settings']['favicon_upload'] = [ '#type' => 'file', '#title' => t('Upload favicon image'), '#description' => t("If you don't have direct file access to the server, use this field to upload your shortcut icon.") - ); + ]; } // Inject human-friendly values and form element descriptions for logo and // favicon. - foreach (array('logo' => 'logo.svg', 'favicon' => 'favicon.ico') as $type => $default) { + foreach (['logo' => 'logo.svg', 'favicon' => 'favicon.ico'] as $type => $default) { if (isset($form[$type]['settings'][$type . '_path'])) { $element = &$form[$type]['settings'][$type . '_path']; @@ -263,20 +273,20 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = // Prepare local file path for description. if ($original_path && isset($friendly_path)) { - $local_file = strtr($original_path, array('public:/' => PublicStream::basePath())); + $local_file = strtr($original_path, ['public:/' => PublicStream::basePath()]); } elseif ($theme) { $local_file = drupal_get_path('theme', $theme) . '/' . $default; } else { - $local_file = \Drupal::theme()->getActiveTheme()->getPath() . '/' . $default; + $local_file = $this->themeManager->getActiveTheme()->getPath() . '/' . $default; } - $element['#description'] = t('Examples: @implicit-public-file (for a file in the public filesystem), @explicit-file, or @local-file.', array( + $element['#description'] = t('Examples: @implicit-public-file (for a file in the public filesystem), @explicit-file, or @local-file.', [ '@implicit-public-file' => isset($friendly_path) ? $friendly_path : $default, '@explicit-file' => file_uri_scheme($original_path) !== FALSE ? $original_path : 'public://' . $default, '@local-file' => $local_file, - )); + ]); } } @@ -284,12 +294,12 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = // Call engine-specific settings. $function = $themes[$theme]->prefix . '_engine_settings'; if (function_exists($function)) { - $form['engine_specific'] = array( + $form['engine_specific'] = [ '#type' => 'details', '#title' => t('Theme-engine-specific settings'), '#open' => TRUE, - '#description' => t('These settings only exist for the themes based on the %engine theme engine.', array('%engine' => $themes[$theme]->prefix)), - ); + '#description' => t('These settings only exist for the themes based on the %engine theme engine.', ['%engine' => $themes[$theme]->prefix]), + ]; $function($form, $form_state); } @@ -299,24 +309,36 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = $theme_keys[] = $theme; } else { - $theme_keys = array($theme); + $theme_keys = [$theme]; } // Save the name of the current theme (if any), so that we can temporarily // override the current theme and allow theme_get_setting() to work // without having to pass the theme name to it. - $default_active_theme = \Drupal::theme()->getActiveTheme(); + $default_active_theme = $this->themeManager->getActiveTheme(); $default_theme = $default_active_theme->getName(); /** @var \Drupal\Core\Theme\ThemeInitialization $theme_initialization */ $theme_initialization = \Drupal::service('theme.initialization'); - \Drupal::theme()->setActiveTheme($theme_initialization->getActiveThemeByName($theme)); + $this->themeManager->setActiveTheme($theme_initialization->getActiveThemeByName($theme)); // Process the theme and all its base themes. foreach ($theme_keys as $theme) { // Include the theme-settings.php file. - $filename = DRUPAL_ROOT . '/' . $themes[$theme]->getPath() . '/theme-settings.php'; - if (file_exists($filename)) { - require_once $filename; + $theme_path = drupal_get_path('theme', $theme); + $theme_settings_file = $theme_path . '/theme-settings.php'; + $theme_file = $theme_path . '/' . $theme . '.theme'; + $filenames = [$theme_settings_file, $theme_file]; + foreach ($filenames as $filename) { + if (file_exists($filename)) { + require_once $filename; + + // The file must be required for the cached form too. + $files = $form_state->getBuildInfo()['files']; + if (!in_array($filename, $files)) { + $files[] = $filename; + } + $form_state->addBuildInfo('files', $files); + } } // Call theme-specific settings. @@ -328,10 +350,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme = // Restore the original current theme. if (isset($default_theme)) { - \Drupal::theme()->setActiveTheme($default_active_theme); + $this->themeManager->setActiveTheme($default_active_theme); } else { - \Drupal::theme()->resetActiveTheme(); + $this->themeManager->resetActiveTheme(); } } @@ -346,7 +368,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { if ($this->moduleHandler->moduleExists('file')) { // Handle file uploads. - $validators = array('file_validate_is_image' => array()); + $validators = ['file_validate_is_image' => []]; // Check for a new uploaded logo. $file = file_save_upload('logo_upload', $validators, FALSE, 0); @@ -362,7 +384,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { } } - $validators = array('file_validate_extensions' => array('ico png gif jpg jpeg apng svg')); + $validators = ['file_validate_extensions' => ['ico png gif jpg jpeg apng svg']]; // Check for a new uploaded favicon. $file = file_save_upload('favicon_upload', $validators, FALSE, 0); diff --git a/core/modules/system/src/MenuAccessControlHandler.php b/core/modules/system/src/MenuAccessControlHandler.php index 034f45a0..86d7db13 100644 --- a/core/modules/system/src/MenuAccessControlHandler.php +++ b/core/modules/system/src/MenuAccessControlHandler.php @@ -14,17 +14,23 @@ */ class MenuAccessControlHandler extends EntityAccessControlHandler { + /** + * {@inheritdoc} + */ + protected $viewLabelOperation = TRUE; + /** * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { - if ($operation === 'view') { + // There are no restrictions on viewing the label of a date format. + if ($operation === 'view label') { return AccessResult::allowed(); } // Locked menus could not be deleted. - elseif ($operation == 'delete') { + elseif ($operation === 'delete') { if ($entity->isLocked()) { - return AccessResult::forbidden()->addCacheableDependency($entity); + return AccessResult::forbidden('The Menu config entity is locked.')->addCacheableDependency($entity); } else { return parent::checkAccess($entity, $operation, $account)->addCacheableDependency($entity); diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php index dcfc0732..ebc5df0b 100644 --- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php @@ -11,6 +11,7 @@ use Drupal\Core\Link; use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\Core\Path\CurrentPathStack; +use Drupal\Core\Path\PathMatcherInterface; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\Routing\RequestContext; use Drupal\Core\Routing\RouteMatch; @@ -52,7 +53,7 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { protected $router; /** - * The dynamic router service. + * The inbound path processor. * * @var \Drupal\Core\PathProcessor\InboundPathProcessorInterface */ @@ -79,6 +80,20 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { */ protected $currentUser; + /** + * The current path service. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + + /** + * The patch matcher service. + * + * @var \Drupal\Core\Path\PathMatcherInterface + */ + protected $pathMatcher; + /** * Constructs the PathBasedBreadcrumbBuilder. * @@ -98,8 +113,10 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { * The current user object. * @param \Drupal\Core\Path\CurrentPathStack $current_path * The current path. + * @param \Drupal\Core\Path\PathMatcherInterface $path_matcher + * The path matcher service. */ - public function __construct(RequestContext $context, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactoryInterface $config_factory, TitleResolverInterface $title_resolver, AccountInterface $current_user, CurrentPathStack $current_path) { + public function __construct(RequestContext $context, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactoryInterface $config_factory, TitleResolverInterface $title_resolver, AccountInterface $current_user, CurrentPathStack $current_path, PathMatcherInterface $path_matcher = NULL) { $this->context = $context; $this->accessManager = $access_manager; $this->router = $router; @@ -108,6 +125,7 @@ public function __construct(RequestContext $context, AccessManagerInterface $acc $this->titleResolver = $title_resolver; $this->currentUser = $current_user; $this->currentPath = $current_path; + $this->pathMatcher = $path_matcher ?: \Drupal::service('path.matcher'); } /** @@ -122,23 +140,29 @@ public function applies(RouteMatchInterface $route_match) { */ public function build(RouteMatchInterface $route_match) { $breadcrumb = new Breadcrumb(); - $links = array(); + $links = []; + + // Add the url.path.parent cache context. This code ignores the last path + // part so the result only depends on the path parents. + $breadcrumb->addCacheContexts(['url.path.parent']); + + // Do not display a breadcrumb on the frontpage. + if ($this->pathMatcher->isFrontPage()) { + return $breadcrumb; + } // General path-based breadcrumbs. Use the actual request path, prior to // resolving path aliases, so the breadcrumb can be defined by simply // creating a hierarchy of path aliases. $path = trim($this->context->getPathInfo(), '/'); $path_elements = explode('/', $path); - $exclude = array(); + $exclude = []; // Don't show a link to the front-page path. $front = $this->config->get('page.front'); $exclude[$front] = TRUE; // /user is just a redirect, so skip it. // @todo Find a better way to deal with /user. $exclude['/user'] = TRUE; - // Add the url.path.parent cache context. This code ignores the last path - // part so the result only depends on the path parents. - $breadcrumb->addCacheContexts(['url.path.parent']); while (count($path_elements) > 1) { array_pop($path_elements); // Copy the path elements for up-casting. @@ -154,19 +178,17 @@ public function build(RouteMatchInterface $route_match) { if (!isset($title)) { // Fallback to using the raw path component as the title if the // route is missing a _title or _title_callback attribute. - $title = str_replace(array('-', '_'), ' ', Unicode::ucfirst(end($path_elements))); + $title = str_replace(['-', '_'], ' ', Unicode::ucfirst(end($path_elements))); } $url = Url::fromRouteMatch($route_match); $links[] = new Link($title, $url); } } - - } - if ($path && '/' . $path != $front) { - // Add the Home link, except for the front page. - $links[] = Link::createFromRoute($this->t('Home'), ''); } + // Add the Home link. + $links[] = Link::createFromRoute($this->t('Home'), ''); + return $breadcrumb->setLinks(array_reverse($links)); } diff --git a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php index f6b0958c..33052852 100644 --- a/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemBrandingBlock.php @@ -60,12 +60,12 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'use_site_logo' => TRUE, 'use_site_name' => TRUE, 'use_site_slogan' => TRUE, 'label_display' => FALSE, - ); + ]; } /** @@ -77,15 +77,15 @@ public function blockForm($form, FormStateInterface $form_state) { // Get permissions. $url_system_theme_settings = new Url('system.theme_settings'); - $url_system_theme_settings_theme = new Url('system.theme_settings_theme', array('theme' => $theme)); + $url_system_theme_settings_theme = new Url('system.theme_settings_theme', ['theme' => $theme]); if ($url_system_theme_settings->access() && $url_system_theme_settings_theme->access()) { // Provide links to the Appearance Settings and Theme Settings pages // if the user has access to administer themes. - $site_logo_description = $this->t('Defined on the Appearance Settings or Theme Settings page.', array( + $site_logo_description = $this->t('Defined on the Appearance Settings or Theme Settings page.', [ ':appearance' => $url_system_theme_settings->toString(), ':theme' => $url_system_theme_settings_theme->toString(), - )); + ]); } else { // Explain that the user does not have access to the Appearance and Theme @@ -99,8 +99,8 @@ public function blockForm($form, FormStateInterface $form_state) { // Provide link to Site Information page if the user has access to // administer site configuration. - $site_name_description = $this->t('Defined on the Site Information page.', array(':information' => $site_information_url)); - $site_slogan_description = $this->t('Defined on the Site Information page.', array(':information' => $site_information_url)); + $site_name_description = $this->t('Defined on the Site Information page.', [':information' => $site_information_url]); + $site_slogan_description = $this->t('Defined on the Site Information page.', [':information' => $site_information_url]); } else { // Explain that the user does not have access to the Site Information @@ -109,30 +109,30 @@ public function blockForm($form, FormStateInterface $form_state) { $site_slogan_description = $this->t('Defined on the Site Information page. You do not have the appropriate permissions to change the site logo.'); } - $form['block_branding'] = array( + $form['block_branding'] = [ '#type' => 'fieldset', '#title' => $this->t('Toggle branding elements'), '#description' => $this->t('Choose which branding elements you want to show in this block instance.'), - ); - $form['block_branding']['use_site_logo'] = array( + ]; + $form['block_branding']['use_site_logo'] = [ '#type' => 'checkbox', '#title' => $this->t('Site logo'), '#description' => $site_logo_description, '#default_value' => $this->configuration['use_site_logo'], - ); + ]; - $form['block_branding']['use_site_name'] = array( + $form['block_branding']['use_site_name'] = [ '#type' => 'checkbox', '#title' => $this->t('Site name'), '#description' => $site_name_description, '#default_value' => $this->configuration['use_site_name'], - ); - $form['block_branding']['use_site_slogan'] = array( + ]; + $form['block_branding']['use_site_slogan'] = [ '#type' => 'checkbox', '#title' => $this->t('Site slogan'), '#description' => $site_slogan_description, '#default_value' => $this->configuration['use_site_slogan'], - ); + ]; return $form; } @@ -150,25 +150,25 @@ public function blockSubmit($form, FormStateInterface $form_state) { * {@inheritdoc} */ public function build() { - $build = array(); + $build = []; $site_config = $this->configFactory->get('system.site'); - $build['site_logo'] = array( + $build['site_logo'] = [ '#theme' => 'image', '#uri' => theme_get_setting('logo.url'), '#alt' => $this->t('Home'), '#access' => $this->configuration['use_site_logo'], - ); + ]; - $build['site_name'] = array( + $build['site_name'] = [ '#markup' => $site_config->get('name'), '#access' => $this->configuration['use_site_name'], - ); + ]; - $build['site_slogan'] = array( + $build['site_slogan'] = [ '#markup' => $site_config->get('slogan'), '#access' => $this->configuration['use_site_slogan'], - ); + ]; return $build; } diff --git a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php index de9ee797..849dee92 100644 --- a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php @@ -76,36 +76,36 @@ public function blockForm($form, FormStateInterface $form_state) { $config = $this->configuration; $defaults = $this->defaultConfiguration(); - $form['menu_levels'] = array( + $form['menu_levels'] = [ '#type' => 'details', '#title' => $this->t('Menu levels'), // Open if not set to defaults. '#open' => $defaults['level'] !== $config['level'] || $defaults['depth'] !== $config['depth'], '#process' => [[get_class(), 'processMenuLevelParents']], - ); + ]; $options = range(0, $this->menuTree->maxDepth()); unset($options[0]); - $form['menu_levels']['level'] = array( + $form['menu_levels']['level'] = [ '#type' => 'select', - '#title' => $this->t('Initial menu level'), + '#title' => $this->t('Initial visibility level'), '#default_value' => $config['level'], '#options' => $options, - '#description' => $this->t('The menu will only be visible if the menu item for the current page is at or below the selected starting level. Select level 1 to always keep this menu visible.'), + '#description' => $this->t('The menu is only visible if the menu item for the current page is at this level or below it. Use level 1 to always display this menu.'), '#required' => TRUE, - ); + ]; $options[0] = $this->t('Unlimited'); - $form['menu_levels']['depth'] = array( + $form['menu_levels']['depth'] = [ '#type' => 'select', - '#title' => $this->t('Maximum number of menu levels to display'), + '#title' => $this->t('Number of levels to display'), '#default_value' => $config['depth'], '#options' => $options, - '#description' => $this->t('The maximum number of menu levels to show, starting from the initial menu level. For example: with an initial level 2 and a maximum number of 3, menu levels 2, 3 and 4 can be displayed.'), + '#description' => $this->t('This maximum number includes the initial level.'), '#required' => TRUE, - ); + ]; return $form; } @@ -147,11 +147,30 @@ public function build() { $parameters->setMaxDepth(min($level + $depth - 1, $this->menuTree->maxDepth())); } + // For menu blocks with start level greater than 1, only show menu items + // from the current active trail. Adjust the root according to the current + // position in the menu in order to determine if we can show the subtree. + if ($level > 1) { + if (count($parameters->activeTrail) >= $level) { + // Active trail array is child-first. Reverse it, and pull the new menu + // root based on the parent of the configured start level. + $menu_trail_ids = array_reverse(array_values($parameters->activeTrail)); + $menu_root = $menu_trail_ids[$level - 1]; + $parameters->setRoot($menu_root)->setMinDepth(1); + if ($depth > 0) { + $parameters->setMaxDepth(min($level - 1 + $depth - 1, $this->menuTree->maxDepth())); + } + } + else { + return []; + } + } + $tree = $this->menuTree->load($menu_name, $parameters); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'], + ]; $tree = $this->menuTree->transform($tree, $manipulators); return $this->menuTree->build($tree); } diff --git a/core/modules/system/src/Plugin/Block/SystemMessagesBlock.php b/core/modules/system/src/Plugin/Block/SystemMessagesBlock.php index bbfb0369..0b6638f4 100644 --- a/core/modules/system/src/Plugin/Block/SystemMessagesBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemMessagesBlock.php @@ -22,9 +22,9 @@ class SystemMessagesBlock extends BlockBase implements MessagesBlockPluginInterf * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'label_display' => FALSE, - ); + ]; } /** diff --git a/core/modules/system/src/Plugin/Block/SystemPoweredByBlock.php b/core/modules/system/src/Plugin/Block/SystemPoweredByBlock.php index 132b0003..c1e0ba8b 100644 --- a/core/modules/system/src/Plugin/Block/SystemPoweredByBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemPoweredByBlock.php @@ -25,7 +25,7 @@ public function defaultConfiguration() { * {@inheritdoc} */ public function build() { - return array('#markup' => '' . $this->t('Powered by Drupal', array(':poweredby' => 'https://www.drupal.org')) . ''); + return ['#markup' => '' . $this->t('Powered by Drupal', [':poweredby' => 'https://www.drupal.org']) . '']; } } diff --git a/core/modules/system/src/Plugin/Condition/CurrentThemeCondition.php b/core/modules/system/src/Plugin/Condition/CurrentThemeCondition.php index 2f7375dc..d282963a 100644 --- a/core/modules/system/src/Plugin/Condition/CurrentThemeCondition.php +++ b/core/modules/system/src/Plugin/Condition/CurrentThemeCondition.php @@ -70,21 +70,21 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function defaultConfiguration() { - return array('theme' => '') + parent::defaultConfiguration(); + return ['theme' => ''] + parent::defaultConfiguration(); } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $form['theme'] = array( + $form['theme'] = [ '#type' => 'select', '#title' => $this->t('Theme'), '#default_value' => $this->configuration['theme'], '#options' => array_map(function ($theme_info) { return $theme_info->info['name']; }, $this->themeHandler->listInfo()), - ); + ]; return parent::buildConfigurationForm($form, $form_state); } @@ -112,10 +112,10 @@ public function evaluate() { */ public function summary() { if ($this->isNegated()) { - return $this->t('The current theme is not @theme', array('@theme' => $this->configuration['theme'])); + return $this->t('The current theme is not @theme', ['@theme' => $this->configuration['theme']]); } - return $this->t('The current theme is @theme', array('@theme' => $this->configuration['theme'])); + return $this->t('The current theme is @theme', ['@theme' => $this->configuration['theme']]); } /** diff --git a/core/modules/system/src/Plugin/Condition/RequestPath.php b/core/modules/system/src/Plugin/Condition/RequestPath.php index 17373cef..ae9d77da 100644 --- a/core/modules/system/src/Plugin/Condition/RequestPath.php +++ b/core/modules/system/src/Plugin/Condition/RequestPath.php @@ -94,22 +94,22 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function defaultConfiguration() { - return array('pages' => '') + parent::defaultConfiguration(); + return ['pages' => ''] + parent::defaultConfiguration(); } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $form['pages'] = array( + $form['pages'] = [ '#type' => 'textarea', '#title' => $this->t('Pages'), '#default_value' => $this->configuration['pages'], - '#description' => $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. An example path is %user-wildcard for every user page. %front is the front page.", array( + '#description' => $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. An example path is %user-wildcard for every user page. %front is the front page.", [ '%user-wildcard' => '/user/*', '%front' => '', - )), - ); + ]), + ]; return parent::buildConfigurationForm($form, $form_state); } @@ -128,9 +128,9 @@ public function summary() { $pages = array_map('trim', explode("\n", $this->configuration['pages'])); $pages = implode(', ', $pages); if (!empty($this->configuration['negate'])) { - return $this->t('Do not return true on the following pages: @pages', array('@pages' => $pages)); + return $this->t('Do not return true on the following pages: @pages', ['@pages' => $pages]); } - return $this->t('Return true on the following pages: @pages', array('@pages' => $pages)); + return $this->t('Return true on the following pages: @pages', ['@pages' => $pages]); } /** diff --git a/core/modules/system/src/Plugin/Derivative/SystemMenuBlock.php b/core/modules/system/src/Plugin/Derivative/SystemMenuBlock.php index 2f802e65..5da50271 100644 --- a/core/modules/system/src/Plugin/Derivative/SystemMenuBlock.php +++ b/core/modules/system/src/Plugin/Derivative/SystemMenuBlock.php @@ -47,7 +47,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { foreach ($this->menuStorage->loadMultiple() as $menu => $entity) { $this->derivatives[$menu] = $base_plugin_definition; $this->derivatives[$menu]['admin_label'] = $entity->label(); - $this->derivatives[$menu]['config_dependencies']['config'] = array($entity->getConfigDependencyName()); + $this->derivatives[$menu]['config_dependencies']['config'] = [$entity->getConfigDependencyName()]; } return $this->derivatives; } diff --git a/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php b/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php index 3ff29dcb..ab9f87d9 100644 --- a/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php +++ b/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php @@ -46,7 +46,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { if ($this->themeHandler->hasUi($theme_name)) { $this->derivatives[$theme_name] = $base_plugin_definition; $this->derivatives[$theme_name]['title'] = $theme->info['name']; - $this->derivatives[$theme_name]['route_parameters'] = array('theme' => $theme_name); + $this->derivatives[$theme_name]['route_parameters'] = ['theme' => $theme_name]; } } return $this->derivatives; diff --git a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php index 7b195cc9..818c5b5c 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php +++ b/core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php @@ -143,7 +143,7 @@ public function getResource() { * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $form['image_jpeg_quality'] = array( + $form['image_jpeg_quality'] = [ '#type' => 'number', '#title' => t('JPEG quality'), '#description' => t('Define the image quality for JPEG manipulations. Ranges from 0 to 100. Higher values mean better image quality but bigger files.'), @@ -151,7 +151,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#max' => 100, '#default_value' => $this->configFactory->getEditable('system.image.gd')->get('jpeg_quality', FALSE), '#field_suffix' => t('%'), - ); + ]; return $form; } @@ -160,7 +160,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { $this->configFactory->getEditable('system.image.gd') - ->set('jpeg_quality', $form_state->getValue(array('gd', 'image_jpeg_quality'))) + ->set('jpeg_quality', $form_state->getValue(['gd', 'image_jpeg_quality'])) ->save(); } @@ -186,13 +186,13 @@ protected function load() { // Convert indexed images to truecolor, copying the image to a new // truecolor resource, so that filters work correctly and don't result // in unnecessary dither. - $data = array( + $data = [ 'width' => imagesx($resource), 'height' => imagesy($resource), 'extension' => image_type_to_extension($this->getType(), FALSE), 'transparent_color' => $this->getTransparentColor(), 'is_temp' => TRUE, - ); + ]; if ($this->apply('create_new', $data)) { imagecopy($this->getResource(), $resource, 0, 0, 0, 0, imagesx($resource), imagesy($resource)); imagedestroy($resource); @@ -362,13 +362,13 @@ public function getMimeType() { * {@inheritdoc} */ public function getRequirements() { - $requirements = array(); + $requirements = []; $info = gd_info(); - $requirements['version'] = array( + $requirements['version'] = [ 'title' => t('GD library'), 'value' => $info['GD Version'], - ); + ]; // Check for filter and rotate support. if (!function_exists('imagefilter') || !function_exists('imagerotate')) { @@ -391,7 +391,7 @@ public static function isAvailable() { * {@inheritdoc} */ public static function getSupportedExtensions() { - $extensions = array(); + $extensions = []; foreach (static::supportedTypes() as $image_type) { // @todo Automatically fetch possible extensions for each mime type. // @see https://www.drupal.org/node/2311679 @@ -440,7 +440,7 @@ public function extensionToImageType($extension) { * IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG, IMAGETYPE_PNG, etc.). */ protected static function supportedTypes() { - return array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF); + return [IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF]; } } diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php index 7c5fca14..5404e2e0 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Convert.php @@ -19,11 +19,11 @@ class Convert extends GDImageToolkitOperationBase { * {@inheritdoc} */ protected function arguments() { - return array( - 'extension' => array( + return [ + 'extension' => [ 'description' => 'The new extension of the converted image', - ), - ); + ], + ]; } /** @@ -47,13 +47,13 @@ protected function execute(array $arguments) { $height = $this->getToolkit()->getHeight(); $original_resource = $this->getToolkit()->getResource(); $original_type = $this->getToolkit()->getType(); - $data = array( + $data = [ 'width' => $width, 'height' => $height, 'extension' => $arguments['extension'], 'transparent_color' => $this->getToolkit()->getTransparentColor(), 'is_temp' => TRUE, - ); + ]; if ($this->getToolkit()->apply('create_new', $data)) { if (imagecopyresampled($this->getToolkit()->getResource(), $original_resource, 0, 0, 0, 0, $width, $height, $width, $height)) { imagedestroy($original_resource); diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php index 0d1c5a61..cb57cc48 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/CreateNew.php @@ -21,29 +21,29 @@ class CreateNew extends GDImageToolkitOperationBase { * {@inheritdoc} */ protected function arguments() { - return array( - 'width' => array( + return [ + 'width' => [ 'description' => 'The width of the image, in pixels', - ), - 'height' => array( + ], + 'height' => [ 'description' => 'The height of the image, in pixels', - ), - 'extension' => array( + ], + 'extension' => [ 'description' => 'The extension of the image file (e.g. png, gif, etc.)', 'required' => FALSE, 'default' => 'png', - ), - 'transparent_color' => array( + ], + 'transparent_color' => [ 'description' => 'The RGB hex color for GIF transparency', 'required' => FALSE, 'default' => '#ffffff', - ), - 'is_temp' => array( + ], + 'is_temp' => [ 'description' => 'If TRUE, this operation is being used to create a temporary image by another GD operation. After performing its function, the caller is responsible for destroying the original GD resource.', 'required' => FALSE, 'default' => FALSE, - ), - ); + ], + ]; } /** diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php index e5ca672f..07a112b9 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Crop.php @@ -19,24 +19,24 @@ class Crop extends GDImageToolkitOperationBase { * {@inheritdoc} */ protected function arguments() { - return array( - 'x' => array( + return [ + 'x' => [ 'description' => 'The starting x offset at which to start the crop, in pixels', - ), - 'y' => array( + ], + 'y' => [ 'description' => 'The starting y offset at which to start the crop, in pixels', - ), - 'width' => array( + ], + 'width' => [ 'description' => 'The width of the cropped area, in pixels', 'required' => FALSE, 'default' => NULL, - ), - 'height' => array( + ], + 'height' => [ 'description' => 'The height of the cropped area, in pixels', 'required' => FALSE, 'default' => NULL, - ), - ); + ], + ]; } /** @@ -54,7 +54,7 @@ protected function validateArguments(array $arguments) { $arguments['width'] = empty($arguments['width']) ? $arguments['height'] / $aspect : $arguments['width']; // Assure integers for all arguments. - foreach (array('x', 'y', 'width', 'height') as $key) { + foreach (['x', 'y', 'width', 'height'] as $key) { $arguments[$key] = (int) round($arguments[$key]); } @@ -77,13 +77,13 @@ protected function execute(array $arguments) { // the original resource on it with resampling. Destroy the original // resource upon success. $original_resource = $this->getToolkit()->getResource(); - $data = array( + $data = [ 'width' => $arguments['width'], 'height' => $arguments['height'], 'extension' => image_type_to_extension($this->getToolkit()->getType(), FALSE), 'transparent_color' => $this->getToolkit()->getTransparentColor(), 'is_temp' => TRUE, - ); + ]; if ($this->getToolkit()->apply('create_new', $data)) { if (imagecopyresampled($this->getToolkit()->getResource(), $original_resource, 0, 0, $arguments['x'], $arguments['y'], $arguments['width'], $arguments['height'], $arguments['width'], $arguments['height'])) { imagedestroy($original_resource); diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php index bae8483e..54ed29b9 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Desaturate.php @@ -20,7 +20,7 @@ class Desaturate extends GDImageToolkitOperationBase { */ protected function arguments() { // This operation does not use any parameters. - return array(); + return []; } /** @@ -29,7 +29,7 @@ protected function arguments() { protected function execute(array $arguments) { // PHP installations using non-bundled GD do not have imagefilter. if (!function_exists('imagefilter')) { - $this->logger->notice("The image '@file' could not be desaturated because the imagefilter() function is not available in this PHP installation.", array('@file' => $this->getToolkit()->getSource())); + $this->logger->notice("The image '@file' could not be desaturated because the imagefilter() function is not available in this PHP installation.", ['@file' => $this->getToolkit()->getSource()]); return FALSE; } diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php index 51c5f53a..155bef24 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Resize.php @@ -19,14 +19,14 @@ class Resize extends GDImageToolkitOperationBase { * {@inheritdoc} */ protected function arguments() { - return array( - 'width' => array( + return [ + 'width' => [ 'description' => 'The new width of the resized image, in pixels', - ), - 'height' => array( + ], + 'height' => [ 'description' => 'The new height of the resized image, in pixels', - ), - ); + ], + ]; } /** @@ -51,18 +51,18 @@ protected function validateArguments(array $arguments) { /** * {@inheritdoc} */ - protected function execute(array $arguments = array()) { + protected function execute(array $arguments = []) { // Create a new resource of the required dimensions, and copy and resize // the original resource on it with resampling. Destroy the original // resource upon success. $original_resource = $this->getToolkit()->getResource(); - $data = array( + $data = [ 'width' => $arguments['width'], 'height' => $arguments['height'], 'extension' => image_type_to_extension($this->getToolkit()->getType(), FALSE), 'transparent_color' => $this->getToolkit()->getTransparentColor(), 'is_temp' => TRUE, - ); + ]; if ($this->getToolkit()->apply('create_new', $data)) { if (imagecopyresampled($this->getToolkit()->getResource(), $original_resource, 0, 0, 0, 0, $arguments['width'], $arguments['height'], imagesx($original_resource), imagesy($original_resource))) { imagedestroy($original_resource); diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php index 62a5405d..e567ea43 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php @@ -21,16 +21,16 @@ class Rotate extends GDImageToolkitOperationBase { * {@inheritdoc} */ protected function arguments() { - return array( - 'degrees' => array( + return [ + 'degrees' => [ 'description' => 'The number of (clockwise) degrees to rotate the image', - ), - 'background' => array( + ], + 'background' => [ 'description' => "A string specifying the hexadecimal color code to use as background for the uncovered area of the image after the rotation. E.g. '#000000' for black, '#ff00ff' for magenta, and '#ffffff' for white. For images that support transparency, this will default to transparent white", 'required' => FALSE, 'default' => NULL, - ), - ); + ], + ]; } /** @@ -45,11 +45,11 @@ protected function validateArguments(array $arguments) { // Validate or set background color argument. if (!empty($arguments['background'])) { // Validate the background color: Color::hexToRgb does so for us. - $background = Color::hexToRgb($arguments['background']) + array( 'alpha' => 0 ); + $background = Color::hexToRgb($arguments['background']) + ['alpha' => 0]; } else { // Background color is not specified: use transparent white as background. - $background = array('red' => 255, 'green' => 255, 'blue' => 255, 'alpha' => 127); + $background = ['red' => 255, 'green' => 255, 'blue' => 255, 'alpha' => 127]; } // Store the color index for the background as that is what GD uses. $arguments['background_idx'] = imagecolorallocatealpha($this->getToolkit()->getResource(), $background['red'], $background['green'], $background['blue'], $background['alpha']); @@ -89,7 +89,7 @@ protected function validateArguments(array $arguments) { protected function execute(array $arguments) { // PHP installations using non-bundled GD do not have imagerotate. if (!function_exists('imagerotate')) { - $this->logger->notice('The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', array('%file' => $this->getToolkit()->getSource())); + $this->logger->notice('The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', ['%file' => $this->getToolkit()->getSource()]); return FALSE; } diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php index bd7a9527..37097d86 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Scale.php @@ -19,23 +19,23 @@ class Scale extends Resize { * {@inheritdoc} */ protected function arguments() { - return array( - 'width' => array( + return [ + 'width' => [ 'description' => 'The target width, in pixels. This value is omitted then the scaling will based only on the height value', 'required' => FALSE, 'default' => NULL, - ), - 'height' => array( + ], + 'height' => [ 'description' => 'The target height, in pixels. This value is omitted then the scaling will based only on the width value', 'required' => FALSE, 'default' => NULL, - ), - 'upscale' => array( + ], + 'upscale' => [ 'description' => 'Boolean indicating that files smaller than the dimensions will be scaled up. This generally results in a low quality image', 'required' => FALSE, 'default' => FALSE, - ), - ); + ], + ]; } /** @@ -78,7 +78,7 @@ protected function validateArguments(array $arguments) { /** * {@inheritdoc} */ - protected function execute(array $arguments = array()) { + protected function execute(array $arguments = []) { // Don't scale if we don't change the dimensions at all. if ($arguments['width'] !== $this->getToolkit()->getWidth() || $arguments['height'] !== $this->getToolkit()->getHeight()) { // Don't upscale if the option isn't enabled. diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php index 8568823b..510020f8 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/ScaleAndCrop.php @@ -19,14 +19,14 @@ class ScaleAndCrop extends GDImageToolkitOperationBase { * {@inheritdoc} */ protected function arguments() { - return array( - 'width' => array( + return [ + 'width' => [ 'description' => 'The target width, in pixels', - ), - 'height' => array( + ], + 'height' => [ 'description' => 'The target height, in pixels', - ), - ); + ], + ]; } /** @@ -40,10 +40,10 @@ protected function validateArguments(array $arguments) { $arguments['x'] = (int) round(($actualWidth * $scaleFactor - $arguments['width']) / 2); $arguments['y'] = (int) round(($actualHeight * $scaleFactor - $arguments['height']) / 2); - $arguments['resize'] = array( + $arguments['resize'] = [ 'width' => (int) round($actualWidth * $scaleFactor), 'height' => (int) round($actualHeight * $scaleFactor), - ); + ]; // Fail when width or height are 0 or negative. if ($arguments['width'] <= 0) { @@ -59,7 +59,7 @@ protected function validateArguments(array $arguments) { /** * {@inheritdoc} */ - protected function execute(array $arguments = array()) { + protected function execute(array $arguments = []) { return $this->getToolkit()->apply('resize', $arguments['resize']) && $this->getToolkit()->apply('crop', $arguments); } diff --git a/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php b/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php new file mode 100644 index 00000000..55ac721d --- /dev/null +++ b/core/modules/system/src/Plugin/migrate/destination/d7/ThemeSettings.php @@ -0,0 +1,94 @@ +configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('config.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function import(Row $row, array $old_destination_id_values = []) { + $imported = FALSE; + $config = $this->configFactory->getEditable($row->getDestinationProperty('configuration_name')); + $theme_settings = $row->getDestination(); + // Remove keys not in theme settings. + unset($theme_settings['configuration_name']); + unset($theme_settings['theme_name']); + if (isset($theme_settings)) { + theme_settings_convert_to_config($theme_settings, $config); + $config->save(); + $imported = TRUE; + } + return $imported; + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['name']['type'] = 'string'; + return $ids; + } + + /** + * {@inheritdoc} + */ + public function fields(MigrationInterface $migration = NULL) { + // Theme settings vary by theme, so no specific fields are defined. + return []; + } + +} diff --git a/core/modules/system/src/Plugin/migrate/source/Menu.php b/core/modules/system/src/Plugin/migrate/source/Menu.php index 6dbf2e7a..a97878fa 100644 --- a/core/modules/system/src/Plugin/migrate/source/Menu.php +++ b/core/modules/system/src/Plugin/migrate/source/Menu.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "menu", - * source_provider = "menu" + * source_module = "menu" * ) */ class Menu extends DrupalSqlBase { @@ -25,11 +25,11 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'menu_name' => $this->t('The menu name. Primary key.'), 'title' => $this->t('The human-readable name of the menu.'), 'description' => $this->t('A description of the menu'), - ); + ]; } /** diff --git a/core/modules/system/src/Plugin/migrate/source/d7/ThemeSettings.php b/core/modules/system/src/Plugin/migrate/source/d7/ThemeSettings.php new file mode 100644 index 00000000..6ae17bea --- /dev/null +++ b/core/modules/system/src/Plugin/migrate/source/d7/ThemeSettings.php @@ -0,0 +1,44 @@ +select('variable', 'v') + ->fields('v', ['name', 'value']) + ->condition('name', 'theme_%_settings', 'LIKE'); + } + + /** + * {@inheritdoc} + */ + public function fields() { + return [ + 'name' => $this->t('Theme settings variable for a theme.'), + 'value' => $this->t('The theme settings variable value.'), + ]; + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['name']['type'] = 'string'; + return $ids; + } + +} diff --git a/core/modules/system/src/Plugin/views/field/BulkForm.php b/core/modules/system/src/Plugin/views/field/BulkForm.php index f9f581b4..65fdc51c 100644 --- a/core/modules/system/src/Plugin/views/field/BulkForm.php +++ b/core/modules/system/src/Plugin/views/field/BulkForm.php @@ -49,7 +49,7 @@ class BulkForm extends FieldPluginBase implements CacheableDependencyInterface { * * @var \Drupal\system\ActionConfigEntityInterface[] */ - protected $actions = array(); + protected $actions = []; /** * The language manager. @@ -162,13 +162,13 @@ protected function getView() { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['action_title'] = array('default' => $this->t('Action')); - $options['include_exclude'] = array( + $options['action_title'] = ['default' => $this->t('Action')]; + $options['include_exclude'] = [ 'default' => 'exclude', - ); - $options['selected_actions'] = array( - 'default' => array(), - ); + ]; + $options['selected_actions'] = [ + 'default' => [], + ]; return $options; } @@ -176,28 +176,28 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['action_title'] = array( + $form['action_title'] = [ '#type' => 'textfield', '#title' => $this->t('Action title'), '#default_value' => $this->options['action_title'], '#description' => $this->t('The title shown above the actions dropdown.'), - ); + ]; - $form['include_exclude'] = array( + $form['include_exclude'] = [ '#type' => 'radios', '#title' => $this->t('Available actions'), - '#options' => array( + '#options' => [ 'exclude' => $this->t('All actions, except selected'), 'include' => $this->t('Only selected actions'), - ), + ], '#default_value' => $this->options['include_exclude'], - ); - $form['selected_actions'] = array( + ]; + $form['selected_actions'] = [ '#type' => 'checkboxes', '#title' => $this->t('Selected actions'), '#options' => $this->getBulkOptions(FALSE), '#default_value' => $this->options['selected_actions'], - ); + ]; parent::buildOptionsForm($form, $form_state); } @@ -208,8 +208,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function validateOptionsForm(&$form, FormStateInterface $form_state) { parent::validateOptionsForm($form, $form_state); - $selected_actions = $form_state->getValue(array('options', 'selected_actions')); - $form_state->setValue(array('options', 'selected_actions'), array_values(array_filter($selected_actions))); + $selected_actions = $form_state->getValue(['options', 'selected_actions']); + $form_state->setValue(['options', 'selected_actions'], array_values(array_filter($selected_actions))); } /** @@ -259,7 +259,7 @@ public function viewsForm(&$form, FormStateInterface $form_state) { foreach ($this->view->result as $row_index => $row) { $entity = $this->getEntityTranslation($this->getEntity($row), $row); - $form[$this->options['id']][$row_index] = array( + $form[$this->options['id']][$row_index] = [ '#type' => 'checkbox', // We are not able to determine a main "title" for each row, so we can // only output a generic label. @@ -267,28 +267,28 @@ public function viewsForm(&$form, FormStateInterface $form_state) { '#title_display' => 'invisible', '#default_value' => !empty($form_state->getValue($this->options['id'])[$row_index]) ? 1 : NULL, '#return_value' => $this->calculateEntityBulkFormKey($entity, $use_revision), - ); + ]; } // Replace the form submit button label. $form['actions']['submit']['#value'] = $this->t('Apply to selected items'); // Ensure a consistent container for filters/operations in the view header. - $form['header'] = array( + $form['header'] = [ '#type' => 'container', '#weight' => -100, - ); + ]; // Build the bulk operations action widget for the header. // Allow themes to apply .container-inline on this separate container. - $form['header'][$this->options['id']] = array( + $form['header'][$this->options['id']] = [ '#type' => 'container', - ); - $form['header'][$this->options['id']]['action'] = array( + ]; + $form['header'][$this->options['id']]['action'] = [ '#type' => 'select', '#title' => $this->options['action_title'], '#options' => $this->getBulkOptions(), - ); + ]; // Duplicate the form actions into the action container in the header. $form['header'][$this->options['id']]['actions'] = $form['actions']; @@ -308,7 +308,7 @@ public function viewsForm(&$form, FormStateInterface $form_state) { * An associative array of operations, suitable for a select element. */ protected function getBulkOptions($filtered = TRUE) { - $options = array(); + $options = []; // Filter the action list. foreach ($this->actions as $id => $action) { if ($filtered) { @@ -344,9 +344,12 @@ protected function getBulkOptions($filtered = TRUE) { */ public function viewsFormSubmit(&$form, FormStateInterface $form_state) { if ($form_state->get('step') == 'views_form_views_form') { - // Filter only selected checkboxes. - $selected = array_filter($form_state->getValue($this->options['id'])); - $entities = array(); + // Filter only selected checkboxes. Use the actual user input rather than + // the raw form values array, since the site data may change before the + // bulk form is submitted, which can lead to data loss. + $user_input = $form_state->getUserInput(); + $selected = array_filter($user_input[$this->options['id']]); + $entities = []; $action = $this->actions[$form_state->getValue('action')]; $count = 0; @@ -372,18 +375,18 @@ public function viewsFormSubmit(&$form, FormStateInterface $form_state) { $operation_definition = $action->getPluginDefinition(); if (!empty($operation_definition['confirm_form_route_name'])) { - $options = array( + $options = [ 'query' => $this->getDestinationArray(), - ); - $form_state->setRedirect($operation_definition['confirm_form_route_name'], array(), $options); + ]; + $form_state->setRedirect($operation_definition['confirm_form_route_name'], [], $options); } else { // Don't display the message unless there are some elements affected and // there is no confirmation form. if ($count) { - drupal_set_message($this->formatPlural($count, '%action was applied to @count item.', '%action was applied to @count items.', array( + drupal_set_message($this->formatPlural($count, '%action was applied to @count item.', '%action was applied to @count items.', [ '%action' => $action->label(), - ))); + ])); } } } diff --git a/core/modules/system/src/SystemConfigSubscriber.php b/core/modules/system/src/SystemConfigSubscriber.php index 3c0de5fa..0ea851d5 100644 --- a/core/modules/system/src/SystemConfigSubscriber.php +++ b/core/modules/system/src/SystemConfigSubscriber.php @@ -25,7 +25,7 @@ class SystemConfigSubscriber implements EventSubscriberInterface { /** * Constructs the SystemConfigSubscriber. * - * @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder + * @param \Drupal\Core\Routing\RouteBuilderInterface $router_builder * The router builder service. */ public function __construct(RouteBuilderInterface $router_builder) { @@ -81,11 +81,11 @@ public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) { * {@inheritdoc} */ public static function getSubscribedEvents() { - $events[ConfigEvents::SAVE][] = array('onConfigSave', 0); + $events[ConfigEvents::SAVE][] = ['onConfigSave', 0]; // The empty check has a high priority so that it can stop propagation if // there is no configuration to import. - $events[ConfigEvents::IMPORT_VALIDATE][] = array('onConfigImporterValidateNotEmpty', 512); - $events[ConfigEvents::IMPORT_VALIDATE][] = array('onConfigImporterValidateSiteUUID', 256); + $events[ConfigEvents::IMPORT_VALIDATE][] = ['onConfigImporterValidateNotEmpty', 512]; + $events[ConfigEvents::IMPORT_VALIDATE][] = ['onConfigImporterValidateSiteUUID', 256]; return $events; } diff --git a/core/modules/system/src/SystemManager.php b/core/modules/system/src/SystemManager.php index e5d3a18b..3fc41829 100644 --- a/core/modules/system/src/SystemManager.php +++ b/core/modules/system/src/SystemManager.php @@ -109,8 +109,8 @@ public function listRequirements() { drupal_load_updates(); // Check run-time requirements and status information. - $requirements = $this->moduleHandler->invokeAll('requirements', array('runtime')); - usort($requirements, function($a, $b) { + $requirements = $this->moduleHandler->invokeAll('requirements', ['runtime']); + uasort($requirements, function ($a, $b) { if (!isset($a['weight'])) { if (!isset($b['weight'])) { return strcasecmp($a['title'], $b['title']); @@ -159,15 +159,15 @@ public function getBlockContents() { // or elsewhere could give us a blank block. $link = $this->menuActiveTrail->getActiveLink('admin'); if ($link && $content = $this->getAdminBlock($link)) { - $output = array( + $output = [ '#theme' => 'admin_block_content', '#content' => $content, - ); + ]; } else { - $output = array( + $output = [ '#markup' => t('You do not have any administrative items.'), - ); + ]; } return $output; } @@ -182,16 +182,16 @@ public function getBlockContents() { * An array of menu items, as expected by admin-block-content.html.twig. */ public function getAdminBlock(MenuLinkInterface $instance) { - $content = array(); + $content = []; // Only find the children of this link. $link_id = $instance->getPluginId(); $parameters = new MenuTreeParameters(); $parameters->setRoot($link_id)->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks(); $tree = $this->menuTree->load(NULL, $parameters); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'], + ]; $tree = $this->menuTree->transform($tree, $manipulators); foreach ($tree as $key => $element) { // Only render accessible links. diff --git a/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php b/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php deleted file mode 100644 index a537b73e..00000000 --- a/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php +++ /dev/null @@ -1,102 +0,0 @@ -config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - } - - /** - * Return the build id of the current form. - */ - protected function getFormBuildId() { - $build_id_fields = $this->xpath('//input[@name="form_build_id"]'); - $this->assertEqual(count($build_id_fields), 1, 'One form build id field on the page'); - return (string) $build_id_fields[0]['value']; - } - - /** - * Create a simple form, then submit the form via AJAX to change to it. - */ - public function testSimpleAJAXFormValue() { - $this->drupalGet('ajax_forms_test_get_form'); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); - $build_id_initial = $this->getFormBuildId(); - - $edit = ['select' => 'green']; - $commands = $this->drupalPostAjaxForm(NULL, $edit, 'select'); - $build_id_first_ajax = $this->getFormBuildId(); - $this->assertNotEqual($build_id_initial, $build_id_first_ajax, 'Build id is changed in the simpletest-DOM on first AJAX submission'); - $expected = [ - 'command' => 'update_build_id', - 'old' => $build_id_initial, - 'new' => $build_id_first_ajax, - ]; - $this->assertCommand($commands, $expected, 'Build id change command issued on first AJAX submission'); - - $edit = ['select' => 'red']; - $commands = $this->drupalPostAjaxForm(NULL, $edit, 'select'); - $build_id_second_ajax = $this->getFormBuildId(); - $this->assertNotEqual($build_id_first_ajax, $build_id_second_ajax, 'Build id changes on subsequent AJAX submissions'); - $expected = [ - 'command' => 'update_build_id', - 'old' => $build_id_first_ajax, - 'new' => $build_id_second_ajax, - ]; - $this->assertCommand($commands, $expected, 'Build id change command issued on subsequent AJAX submissions'); - - // Repeat the test sequence but this time with a page loaded from the cache. - $this->drupalGet('ajax_forms_test_get_form'); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $build_id_from_cache_initial = $this->getFormBuildId(); - $this->assertEqual($build_id_initial, $build_id_from_cache_initial, 'Build id is the same as on the first request'); - - $edit = ['select' => 'green']; - $commands = $this->drupalPostAjaxForm(NULL, $edit, 'select'); - $build_id_from_cache_first_ajax = $this->getFormBuildId(); - $this->assertNotEqual($build_id_from_cache_initial, $build_id_from_cache_first_ajax, 'Build id is changed in the simpletest-DOM on first AJAX submission'); - $this->assertNotEqual($build_id_first_ajax, $build_id_from_cache_first_ajax, 'Build id from first user is not reused'); - $expected = [ - 'command' => 'update_build_id', - 'old' => $build_id_from_cache_initial, - 'new' => $build_id_from_cache_first_ajax, - ]; - $this->assertCommand($commands, $expected, 'Build id change command issued on first AJAX submission'); - - $edit = ['select' => 'red']; - $commands = $this->drupalPostAjaxForm(NULL, $edit, 'select'); - $build_id_from_cache_second_ajax = $this->getFormBuildId(); - $this->assertNotEqual($build_id_from_cache_first_ajax, $build_id_from_cache_second_ajax, 'Build id changes on subsequent AJAX submissions'); - $expected = [ - 'command' => 'update_build_id', - 'old' => $build_id_from_cache_first_ajax, - 'new' => $build_id_from_cache_second_ajax, - ]; - $this->assertCommand($commands, $expected, 'Build id change command issued on subsequent AJAX submissions'); - } - - /** - * Tests a form that uses an #ajax callback. - * - * @see \Drupal\system\Tests\Ajax\ElementValidationTest::testAjaxElementValidation() - */ - public function testAjaxElementValidation() { - $edit = ['drivertext' => t('some dumb text')]; - $this->drupalPostAjaxForm('ajax_validation_test', $edit, 'drivertext'); - } - -} diff --git a/core/modules/system/src/Tests/Ajax/AjaxInGroupTest.php b/core/modules/system/src/Tests/Ajax/AjaxInGroupTest.php index 4ca7390a..4116f5f8 100644 --- a/core/modules/system/src/Tests/Ajax/AjaxInGroupTest.php +++ b/core/modules/system/src/Tests/Ajax/AjaxInGroupTest.php @@ -11,13 +11,13 @@ class AjaxInGroupTest extends AjaxTestBase { protected function setUp() { parent::setUp(); - $this->drupalLogin($this->drupalCreateUser(array('access content'))); + $this->drupalLogin($this->drupalCreateUser(['access content'])); } /** * Submits forms with select and checkbox elements via Ajax. */ - function testSimpleAjaxFormValue() { + public function testSimpleAjaxFormValue() { $this->drupalGet('/ajax_forms_test_get_form'); $this->assertText('Test group'); $this->assertText('AJAX checkbox in a group'); diff --git a/core/modules/system/src/Tests/Ajax/AjaxTestBase.php b/core/modules/system/src/Tests/Ajax/AjaxTestBase.php index e4db3bd9..66e06c88 100644 --- a/core/modules/system/src/Tests/Ajax/AjaxTestBase.php +++ b/core/modules/system/src/Tests/Ajax/AjaxTestBase.php @@ -14,7 +14,7 @@ abstract class AjaxTestBase extends WebTestBase { * * @var array */ - public static $modules = array('node', 'ajax_test', 'ajax_forms_test'); + public static $modules = ['node', 'ajax_test', 'ajax_forms_test']; /** * Asserts the array of Ajax commands contains the searched command. diff --git a/core/modules/system/src/Tests/Ajax/CommandsTest.php b/core/modules/system/src/Tests/Ajax/CommandsTest.php index 7e26fa39..6ae97ae1 100644 --- a/core/modules/system/src/Tests/Ajax/CommandsTest.php +++ b/core/modules/system/src/Tests/Ajax/CommandsTest.php @@ -32,91 +32,91 @@ class CommandsTest extends AjaxTestBase { /** * Tests the various Ajax Commands. */ - function testAjaxCommands() { + public function testAjaxCommands() { $form_path = 'ajax_forms_test_ajax_commands_form'; - $web_user = $this->drupalCreateUser(array('access content')); + $web_user = $this->drupalCreateUser(['access content']); $this->drupalLogin($web_user); - $edit = array(); + $edit = []; // Tests the 'add_css' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'add_css' command"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'add_css' command")]); $expected = new AddCssCommand('my/file.css'); $this->assertCommand($commands, $expected->render(), "'add_css' AJAX command issued with correct data."); // Tests the 'after' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'After': Click to put something after the div"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'After': Click to put something after the div")]); $expected = new AfterCommand('#after_div', 'This will be placed after'); $this->assertCommand($commands, $expected->render(), "'after' AJAX command issued with correct data."); // Tests the 'alert' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'Alert': Click to alert"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'Alert': Click to alert")]); $expected = new AlertCommand(t('Alert')); $this->assertCommand($commands, $expected->render(), "'alert' AJAX Command issued with correct text."); // Tests the 'append' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'Append': Click to append something"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'Append': Click to append something")]); $expected = new AppendCommand('#append_div', 'Appended text'); $this->assertCommand($commands, $expected->render(), "'append' AJAX command issued with correct data."); // Tests the 'before' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'before': Click to put something before the div"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'before': Click to put something before the div")]); $expected = new BeforeCommand('#before_div', 'Before text'); $this->assertCommand($commands, $expected->render(), "'before' AJAX command issued with correct data."); // Tests the 'changed' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX changed: Click to mark div changed."))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX changed: Click to mark div changed.")]); $expected = new ChangedCommand('#changed_div'); $this->assertCommand($commands, $expected->render(), "'changed' AJAX command issued with correct selector."); // Tests the 'changed' command using the second argument. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX changed: Click to mark div changed with asterisk."))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX changed: Click to mark div changed with asterisk.")]); $expected = new ChangedCommand('#changed_div', '#changed_div_mark_this'); $this->assertCommand($commands, $expected->render(), "'changed' AJAX command (with asterisk) issued with correct selector."); // Tests the 'css' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("Set the '#box' div to be blue."))); - $expected = new CssCommand('#css_div', array('background-color' => 'blue')); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("Set the '#box' div to be blue.")]); + $expected = new CssCommand('#css_div', ['background-color' => 'blue']); $this->assertCommand($commands, $expected->render(), "'css' AJAX command issued with correct selector."); // Tests the 'data' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX data command: Issue command."))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX data command: Issue command.")]); $expected = new DataCommand('#data_div', 'testkey', 'testvalue'); $this->assertCommand($commands, $expected->render(), "'data' AJAX command issued with correct key and value."); // Tests the 'html' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX html: Replace the HTML in a selector."))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX html: Replace the HTML in a selector.")]); $expected = new HtmlCommand('#html_div', 'replacement text'); $this->assertCommand($commands, $expected->render(), "'html' AJAX command issued with correct data."); // Tests the 'insert' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX insert: Let client insert based on #ajax['method']."))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX insert: Let client insert based on #ajax['method'].")]); $expected = new InsertCommand('#insert_div', 'insert replacement text'); $this->assertCommand($commands, $expected->render(), "'insert' AJAX command issued with correct data."); // Tests the 'invoke' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX invoke command: Invoke addClass() method."))); - $expected = new InvokeCommand('#invoke_div', 'addClass', array('error')); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX invoke command: Invoke addClass() method.")]); + $expected = new InvokeCommand('#invoke_div', 'addClass', ['error']); $this->assertCommand($commands, $expected->render(), "'invoke' AJAX command issued with correct method and argument."); // Tests the 'prepend' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'prepend': Click to prepend something"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'prepend': Click to prepend something")]); $expected = new PrependCommand('#prepend_div', 'prepended text'); $this->assertCommand($commands, $expected->render(), "'prepend' AJAX command issued with correct data."); // Tests the 'remove' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'remove': Click to remove text"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'remove': Click to remove text")]); $expected = new RemoveCommand('#remove_text'); $this->assertCommand($commands, $expected->render(), "'remove' AJAX command issued with correct command and selector."); // Tests the 'restripe' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'restripe' command"))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'restripe' command")]); $expected = new RestripeCommand('#restripe_table'); $this->assertCommand($commands, $expected->render(), "'restripe' AJAX command issued with correct selector."); // Tests the 'settings' command. - $commands = $this->drupalPostAjaxForm($form_path, $edit, array('op' => t("AJAX 'settings' command"))); - $expected = new SettingsCommand(array('ajax_forms_test' => array('foo' => 42))); + $commands = $this->drupalPostAjaxForm($form_path, $edit, ['op' => t("AJAX 'settings' command")]); + $expected = new SettingsCommand(['ajax_forms_test' => ['foo' => 42]]); $this->assertCommand($commands, $expected->render(), "'settings' AJAX command issued with correct data."); } @@ -124,7 +124,7 @@ function testAjaxCommands() { * Regression test: Settings command exists regardless of JS aggregation. */ public function testAttachedSettings() { - $assert = function($message) { + $assert = function ($message) { $response = new AjaxResponse(); $response->setAttachments([ 'library' => ['core/drupalSettings'], diff --git a/core/modules/system/src/Tests/Ajax/DialogTest.php b/core/modules/system/src/Tests/Ajax/DialogTest.php index 254f01d3..90c548b6 100644 --- a/core/modules/system/src/Tests/Ajax/DialogTest.php +++ b/core/modules/system/src/Tests/Ajax/DialogTest.php @@ -19,72 +19,72 @@ class DialogTest extends AjaxTestBase { * * @var array */ - public static $modules = array('ajax_test', 'ajax_forms_test', 'contact'); + public static $modules = ['ajax_test', 'ajax_forms_test', 'contact']; /** * Test sending non-JS and AJAX requests to open and manipulate modals. */ public function testDialog() { - $this->drupalLogin($this->drupalCreateUser(array('administer contact forms'))); + $this->drupalLogin($this->drupalCreateUser(['administer contact forms'])); // Ensure the elements render without notices or exceptions. $this->drupalGet('ajax-test/dialog'); // Set up variables for this test. $dialog_renderable = AjaxTestController::dialogContents(); $dialog_contents = \Drupal::service('renderer')->renderRoot($dialog_renderable); - $modal_expected_response = array( + $modal_expected_response = [ 'command' => 'openDialog', 'selector' => '#drupal-modal', 'settings' => NULL, 'data' => $dialog_contents, - 'dialogOptions' => array( + 'dialogOptions' => [ 'modal' => TRUE, 'title' => 'AJAX Dialog & contents', - ), - ); - $form_expected_response = array( + ], + ]; + $form_expected_response = [ 'command' => 'openDialog', 'selector' => '#drupal-modal', 'settings' => NULL, - 'dialogOptions' => array( + 'dialogOptions' => [ 'modal' => TRUE, 'title' => 'Ajax Form contents', - ), - ); - $entity_form_expected_response = array( + ], + ]; + $entity_form_expected_response = [ 'command' => 'openDialog', 'selector' => '#drupal-modal', 'settings' => NULL, - 'dialogOptions' => array( + 'dialogOptions' => [ 'modal' => TRUE, 'title' => 'Add contact form', - ), - ); - $normal_expected_response = array( + ], + ]; + $normal_expected_response = [ 'command' => 'openDialog', 'selector' => '#ajax-test-dialog-wrapper-1', 'settings' => NULL, 'data' => $dialog_contents, - 'dialogOptions' => array( + 'dialogOptions' => [ 'modal' => FALSE, 'title' => 'AJAX Dialog & contents', - ), - ); - $no_target_expected_response = array( + ], + ]; + $no_target_expected_response = [ 'command' => 'openDialog', 'selector' => '#drupal-dialog-ajax-testdialog-contents', 'settings' => NULL, 'data' => $dialog_contents, - 'dialogOptions' => array( + 'dialogOptions' => [ 'modal' => FALSE, 'title' => 'AJAX Dialog & contents', - ), - ); - $close_expected_response = array( + ], + ]; + $close_expected_response = [ 'command' => 'closeDialog', 'selector' => '#ajax-test-dialog-wrapper-1', 'persist' => FALSE, - ); + ]; // Check that requesting a modal dialog without JS goes to a page. $this->drupalGet('ajax-test/dialog-contents'); @@ -95,7 +95,7 @@ public function testDialog() { $this->assertRaw($dialog_contents, 'Modal dialog page on XMLHttpRequest present.'); // Emulate going to the JS version of the page and check the JSON response. - $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal'))); + $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]); $this->assertEqual($modal_expected_response, $ajax_result[3], 'Modal dialog JSON response matches.'); // Test the HTML escaping of & character. $this->assertEqual($ajax_result[3]['dialogOptions']['title'], 'AJAX Dialog & contents'); @@ -108,26 +108,26 @@ public function testDialog() { // Emulate going to the JS version of the page and check the JSON response. // This needs to use WebTestBase::drupalPostAjaxForm() so that the correct // dialog options are sent. - $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array( + $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [ // We have to mock a form element to make drupalPost submit from a link. 'textfield' => 'test', - ), array(), 'ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog')), array(), NULL, array( - 'submit' => array( + ], [], 'ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']], [], NULL, [ + 'submit' => [ 'dialogOptions[target]' => 'ajax-test-dialog-wrapper-1', - ) - )); + ] + ]); $this->assertEqual($normal_expected_response, $ajax_result[3], 'Normal dialog JSON response matches.'); // Emulate going to the JS version of the page and check the JSON response. // This needs to use WebTestBase::drupalPostAjaxForm() so that the correct // dialog options are sent. - $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array( + $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [ // We have to mock a form element to make drupalPost submit from a link. 'textfield' => 'test', - ), array(), 'ajax-test/dialog-contents', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog')), array(), NULL, array( + ], [], 'ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']], [], NULL, [ // Don't send a target. - 'submit' => array() - )); + 'submit' => [] + ]); // Make sure the selector ID starts with the right string. $this->assert(strpos($ajax_result[3]['selector'], $no_target_expected_response['selector']) === 0, 'Selector starts with right string.'); unset($ajax_result[3]['selector']); @@ -142,7 +142,7 @@ public function testDialog() { // Test submitting via a POST request through the button for modals. This // approach more accurately reflects the real responses by Drupal because // all of the necessary page variables are emulated. - $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array(), 'button1'); + $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [], 'button1'); // Check that CSS and JavaScript are "added" to the page dynamically. $this->assertTrue(in_array('core/drupal.dialog.ajax', explode(',', $ajax_result[0]['settings']['ajaxPageState']['libraries'])), 'core/drupal.dialog.ajax library is added to the page.'); @@ -159,7 +159,7 @@ public function testDialog() { $this->assertNotEqual($ajax_result[4]['dialogOptions']['title'], 'AJAX Dialog & contents'); // Abbreviated test for "normal" dialogs, testing only the difference. - $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', array(), 'button2'); + $ajax_result = $this->drupalPostAjaxForm('ajax-test/dialog', [], 'button2'); $this->assertEqual($normal_expected_response, $ajax_result[4], 'POST request normal dialog JSON response matches.'); // Check that requesting a form dialog without JS goes to a page. @@ -170,15 +170,17 @@ public function testDialog() { $this->assertTrue(!empty($form), 'Non-JS form page present.'); // Emulate going to the JS version of the form and check the JSON response. - $ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal'))); + $ajax_result = $this->drupalGetAjax('ajax-test/dialog-form', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]); $expected_ajax_settings = [ 'edit-preview' => [ 'callback' => '::preview', 'event' => 'click', - 'url' => Url::fromRoute('ajax_test.dialog_form', [], ['query' => [ + 'url' => Url::fromRoute('ajax_test.dialog_form', [], [ + 'query' => [ MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal', FormBuilderInterface::AJAX_FORM_REQUEST => TRUE, - ]])->toString(), + ], + ])->toString(), 'dialogType' => 'ajax', 'submit' => [ '_triggering_element_name' => 'op', @@ -202,7 +204,7 @@ public function testDialog() { $this->assertTrue(!empty($form), 'Non-JS entity form page present.'); // Emulate going to the JS version of the form and check the JSON response. - $ajax_result = $this->drupalGetAjax('admin/structure/contact/add', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal'))); + $ajax_result = $this->drupalGetAjax('admin/structure/contact/add', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal']]); $this->setRawContent($ajax_result[3]['data']); // Remove the data, the form build id and token will never match. unset($ajax_result[3]['data']); diff --git a/core/modules/system/src/Tests/Ajax/ElementValidationTest.php b/core/modules/system/src/Tests/Ajax/ElementValidationTest.php index 5133ce37..d20f453b 100644 --- a/core/modules/system/src/Tests/Ajax/ElementValidationTest.php +++ b/core/modules/system/src/Tests/Ajax/ElementValidationTest.php @@ -16,8 +16,8 @@ class ElementValidationTest extends AjaxTestBase { * filled in, and we want to see if the activation of the "drivertext" * Ajax-enabled field fails due to the required field being empty. */ - function testAjaxElementValidation() { - $edit = array('drivertext' => t('some dumb text')); + public function testAjaxElementValidation() { + $edit = ['drivertext' => t('some dumb text')]; // Post with 'drivertext' as the triggering element. $this->drupalPostAjaxForm('ajax_validation_test', $edit, 'drivertext'); @@ -26,7 +26,7 @@ function testAjaxElementValidation() { $this->assertText('ajax_forms_test_validation_form_callback invoked', 'The correct callback was invoked'); $this->drupalGet('ajax_validation_test'); - $edit = array('drivernumber' => 12345); + $edit = ['drivernumber' => 12345]; // Post with 'drivernumber' as the triggering element. $this->drupalPostAjaxForm('ajax_validation_test', $edit, 'drivernumber'); diff --git a/core/modules/system/src/Tests/Ajax/FormValuesTest.php b/core/modules/system/src/Tests/Ajax/FormValuesTest.php index 0a23db18..9f4b5217 100644 --- a/core/modules/system/src/Tests/Ajax/FormValuesTest.php +++ b/core/modules/system/src/Tests/Ajax/FormValuesTest.php @@ -13,28 +13,28 @@ class FormValuesTest extends AjaxTestBase { protected function setUp() { parent::setUp(); - $this->drupalLogin($this->drupalCreateUser(array('access content'))); + $this->drupalLogin($this->drupalCreateUser(['access content'])); } /** * Submits forms with select and checkbox elements via Ajax. */ - function testSimpleAjaxFormValue() { + public function testSimpleAjaxFormValue() { // Verify form values of a select element. - foreach (array('red', 'green', 'blue') as $item) { - $edit = array( + foreach (['red', 'green', 'blue'] as $item) { + $edit = [ 'select' => $item, - ); + ]; $commands = $this->drupalPostAjaxForm('ajax_forms_test_get_form', $edit, 'select'); $expected = new DataCommand('#ajax_selected_color', 'form_state_value_select', $item); $this->assertCommand($commands, $expected->render(), 'Verification of AJAX form values from a selectbox issued with a correct value.'); } // Verify form values of a checkbox element. - foreach (array(FALSE, TRUE) as $item) { - $edit = array( + foreach ([FALSE, TRUE] as $item) { + $edit = [ 'checkbox' => $item, - ); + ]; $commands = $this->drupalPostAjaxForm('ajax_forms_test_get_form', $edit, 'checkbox'); $expected = new DataCommand('#ajax_checkbox_value', 'form_state_value_select', (int) $item); $this->assertCommand($commands, $expected->render(), 'Verification of AJAX form values from a checkbox issued with a correct value.'); @@ -46,11 +46,11 @@ function testSimpleAjaxFormValue() { // We don't need to check for the X-Drupal-Ajax-Token header with these // invalid requests. $this->assertAjaxHeader = FALSE; - foreach (array('null', 'empty', 'nonexistent') as $key) { + foreach (['null', 'empty', 'nonexistent'] as $key) { $element_name = 'select_' . $key . '_callback'; - $edit = array( + $edit = [ $element_name => 'red', - ); + ]; $commands = $this->drupalPostAjaxForm('ajax_forms_test_get_form', $edit, $element_name); $this->assertResponse(500); } diff --git a/core/modules/system/src/Tests/Ajax/FrameworkTest.php b/core/modules/system/src/Tests/Ajax/FrameworkTest.php index fb59bcc5..14bae064 100644 --- a/core/modules/system/src/Tests/Ajax/FrameworkTest.php +++ b/core/modules/system/src/Tests/Ajax/FrameworkTest.php @@ -22,7 +22,7 @@ class FrameworkTest extends AjaxTestBase { public function testAJAXRender() { // Verify that settings command is generated if JavaScript settings exist. $commands = $this->drupalGetAjax('ajax-test/render'); - $expected = new SettingsCommand(array('ajax' => 'test'), TRUE); + $expected = new SettingsCommand(['ajax' => 'test'], TRUE); $this->assertCommand($commands, $expected->render(), 'JavaScript settings command is present.'); } @@ -30,14 +30,14 @@ public function testAJAXRender() { * Tests AjaxResponse::prepare() AJAX commands ordering. */ public function testOrder() { - $expected_commands = array(); + $expected_commands = []; // Expected commands, in a very specific order. $asset_resolver = \Drupal::service('asset.resolver'); $css_collection_renderer = \Drupal::service('asset.css.collection_renderer'); $js_collection_renderer = \Drupal::service('asset.js.collection_renderer'); $renderer = \Drupal::service('renderer'); - $expected_commands[0] = new SettingsCommand(array('ajax' => 'test'), TRUE); + $expected_commands[0] = new SettingsCommand(['ajax' => 'test'], TRUE); $build['#attached']['library'][] = 'ajax_test/order-css-command'; $assets = AttachedAssets::createFromRenderArray($build); $css_render_array = $css_collection_renderer->render($asset_resolver->getCssAssets($assets, FALSE)); @@ -65,7 +65,7 @@ public function testOrder() { // 3. JavaScript files in the header // 4. JavaScript files in the footer // 5. Any other AJAX commands, in whatever order they were added. - $commands = $this->drupalPostAjaxForm(NULL, array(), NULL, 'ajax-test/order', array(), array(), NULL, array()); + $commands = $this->drupalPostAjaxForm(NULL, [], NULL, 'ajax-test/order', [], [], NULL, []); $this->assertCommand(array_slice($commands, 0, 1), $expected_commands[0]->render(), 'Settings command is first.'); $this->assertCommand(array_slice($commands, 1, 1), $expected_commands[1]->render(), 'CSS command is second (and CSS files are ordered correctly).'); $this->assertCommand(array_slice($commands, 2, 1), $expected_commands[2]->render(), 'Header JS command is third.'); @@ -78,10 +78,10 @@ public function testOrder() { */ public function testAJAXRenderError() { // Verify custom error message. - $edit = array( + $edit = [ 'message' => 'Custom error message.', - ); - $commands = $this->drupalGetAjax('ajax-test/render-error', array('query' => $edit)); + ]; + $commands = $this->drupalGetAjax('ajax-test/render-error', ['query' => $edit]); $expected = new AlertCommand($edit['message']); $this->assertCommand($commands, $expected->render(), 'Custom error message is output.'); } @@ -95,12 +95,12 @@ public function testLazyLoad() { $js_collection_renderer = \Drupal::service('asset.js.collection_renderer'); $renderer = \Drupal::service('renderer'); - $expected = array( + $expected = [ 'setting_name' => 'ajax_forms_test_lazy_load_form_submit', 'setting_value' => 'executed', 'library_1' => 'system/admin', 'library_2' => 'system/drupal.system', - ); + ]; // Get the base page. $this->drupalGet('ajax_forms_test_lazy_load_form'); @@ -109,9 +109,9 @@ public function testLazyLoad() { // Verify that the base page doesn't have the settings and files that are to // be lazy loaded as part of the next requests. - $this->assertTrue(!isset($original_settings[$expected['setting_name']]), format_string('Page originally lacks the %setting, as expected.', array('%setting' => $expected['setting_name']))); - $this->assertTrue(!in_array($expected['library_1'], $original_libraries), format_string('Page originally lacks the %library library, as expected.', array('%library' => $expected['library_1']))); - $this->assertTrue(!in_array($expected['library_2'], $original_libraries), format_string('Page originally lacks the %library library, as expected.', array('%library' => $expected['library_2']))); + $this->assertTrue(!isset($original_settings[$expected['setting_name']]), format_string('Page originally lacks the %setting, as expected.', ['%setting' => $expected['setting_name']])); + $this->assertTrue(!in_array($expected['library_1'], $original_libraries), format_string('Page originally lacks the %library library, as expected.', ['%library' => $expected['library_1']])); + $this->assertTrue(!in_array($expected['library_2'], $original_libraries), format_string('Page originally lacks the %library library, as expected.', ['%library' => $expected['library_2']])); // Calculate the expected CSS and JS. $assets = new AttachedAssets(); @@ -128,14 +128,14 @@ public function testLazyLoad() { $expected_js_html = $renderer->renderRoot($js_render_array); // Submit the AJAX request without triggering files getting added. - $commands = $this->drupalPostAjaxForm(NULL, array('add_files' => FALSE), array('op' => t('Submit'))); + $commands = $this->drupalPostAjaxForm(NULL, ['add_files' => FALSE], ['op' => t('Submit')]); $new_settings = $this->getDrupalSettings(); $new_libraries = explode(',', $new_settings['ajaxPageState']['libraries']); // Verify the setting was not added when not expected. - $this->assertTrue(!isset($new_settings[$expected['setting_name']]), format_string('Page still lacks the %setting, as expected.', array('%setting' => $expected['setting_name']))); - $this->assertTrue(!in_array($expected['library_1'], $new_libraries), format_string('Page still lacks the %library library, as expected.', array('%library' => $expected['library_1']))); - $this->assertTrue(!in_array($expected['library_2'], $new_libraries), format_string('Page still lacks the %library library, as expected.', array('%library' => $expected['library_2']))); + $this->assertTrue(!isset($new_settings[$expected['setting_name']]), format_string('Page still lacks the %setting, as expected.', ['%setting' => $expected['setting_name']])); + $this->assertTrue(!in_array($expected['library_1'], $new_libraries), format_string('Page still lacks the %library library, as expected.', ['%library' => $expected['library_1']])); + $this->assertTrue(!in_array($expected['library_2'], $new_libraries), format_string('Page still lacks the %library library, as expected.', ['%library' => $expected['library_2']])); // Verify a settings command does not add CSS or scripts to drupalSettings // and no command inserts the corresponding tags on the page. $found_settings_command = FALSE; @@ -148,24 +148,24 @@ public function testLazyLoad() { $found_markup_command = TRUE; } } - $this->assertFalse($found_settings_command, format_string('Page state still lacks the %library_1 and %library_2 libraries, as expected.', array('%library_1' => $expected['library_1'], '%library_2' => $expected['library_2']))); - $this->assertFalse($found_markup_command, format_string('Page still lacks the %library_1 and %library_2 libraries, as expected.', array('%library_1' => $expected['library_1'], '%library_2' => $expected['library_2']))); + $this->assertFalse($found_settings_command, format_string('Page state still lacks the %library_1 and %library_2 libraries, as expected.', ['%library_1' => $expected['library_1'], '%library_2' => $expected['library_2']])); + $this->assertFalse($found_markup_command, format_string('Page still lacks the %library_1 and %library_2 libraries, as expected.', ['%library_1' => $expected['library_1'], '%library_2' => $expected['library_2']])); // Submit the AJAX request and trigger adding files. - $commands = $this->drupalPostAjaxForm(NULL, array('add_files' => TRUE), array('op' => t('Submit'))); + $commands = $this->drupalPostAjaxForm(NULL, ['add_files' => TRUE], ['op' => t('Submit')]); $new_settings = $this->getDrupalSettings(); $new_libraries = explode(',', $new_settings['ajaxPageState']['libraries']); // Verify the expected setting was added, both to drupalSettings, and as // the first AJAX command. - $this->assertIdentical($new_settings[$expected['setting_name']], $expected['setting_value'], format_string('Page now has the %setting.', array('%setting' => $expected['setting_name']))); - $expected_command = new SettingsCommand(array($expected['setting_name'] => $expected['setting_value']), TRUE); + $this->assertIdentical($new_settings[$expected['setting_name']], $expected['setting_value'], format_string('Page now has the %setting.', ['%setting' => $expected['setting_name']])); + $expected_command = new SettingsCommand([$expected['setting_name'] => $expected['setting_value']], TRUE); $this->assertCommand(array_slice($commands, 0, 1), $expected_command->render(), 'The settings command was first.'); // Verify the expected CSS file was added, both to drupalSettings, and as // the second AJAX command for inclusion into the HTML. - $this->assertTrue(in_array($expected['library_1'], $new_libraries), format_string('Page state now has the %library library.', array('%library' => $expected['library_1']))); - $this->assertCommand(array_slice($commands, 1, 1), array('data' => $expected_css_html), format_string('Page now has the %library library.', array('%library' => $expected['library_1']))); + $this->assertTrue(in_array($expected['library_1'], $new_libraries), format_string('Page state now has the %library library.', ['%library' => $expected['library_1']])); + $this->assertCommand(array_slice($commands, 1, 1), ['data' => $expected_css_html], format_string('Page now has the %library library.', ['%library' => $expected['library_1']])); // Verify the expected JS file was added, both to drupalSettings, and as // the third AJAX command for inclusion into the HTML. By testing for an @@ -173,15 +173,15 @@ public function testLazyLoad() { // unexpected JavaScript code, such as a jQuery.extend() that would // potentially clobber rather than properly merge settings, didn't // accidentally get added. - $this->assertTrue(in_array($expected['library_2'], $new_libraries), format_string('Page state now has the %library library.', array('%library' => $expected['library_2']))); - $this->assertCommand(array_slice($commands, 2, 1), array('data' => $expected_js_html), format_string('Page now has the %library library.', array('%library' => $expected['library_2']))); + $this->assertTrue(in_array($expected['library_2'], $new_libraries), format_string('Page state now has the %library library.', ['%library' => $expected['library_2']])); + $this->assertCommand(array_slice($commands, 2, 1), ['data' => $expected_js_html], format_string('Page now has the %library library.', ['%library' => $expected['library_2']])); } /** * Tests that drupalSettings.currentPath is not updated on AJAX requests. */ public function testCurrentPathChange() { - $commands = $this->drupalPostAjaxForm('ajax_forms_test_lazy_load_form', array('add_files' => FALSE), array('op' => t('Submit'))); + $commands = $this->drupalPostAjaxForm('ajax_forms_test_lazy_load_form', ['add_files' => FALSE], ['op' => t('Submit')]); foreach ($commands as $command) { if ($command['command'] == 'settings') { $this->assertFalse(isset($command['settings']['currentPath']), 'Value of drupalSettings.currentPath is not updated after an AJAX request.'); @@ -195,14 +195,14 @@ public function testCurrentPathChange() { public function testLazyLoadOverriddenCSS() { // The test theme overrides js.module.css without an implementation, // thereby removing it. - \Drupal::service('theme_handler')->install(array('test_theme')); + \Drupal::service('theme_handler')->install(['test_theme']); $this->config('system.theme') ->set('default', 'test_theme') ->save(); // This gets the form, and emulates an Ajax submission on it, including // adding markup to the HEAD and BODY for any lazy loaded JS/CSS files. - $this->drupalPostAjaxForm('ajax_forms_test_lazy_load_form', array('add_files' => TRUE), array('op' => t('Submit'))); + $this->drupalPostAjaxForm('ajax_forms_test_lazy_load_form', ['add_files' => TRUE], ['op' => t('Submit')]); // Verify that the resulting HTML does not load the overridden CSS file. // We add a "?" to the assertion, because drupalSettings may include diff --git a/core/modules/system/src/Tests/Ajax/MultiFormTest.php b/core/modules/system/src/Tests/Ajax/MultiFormTest.php index e07204cc..96844ed0 100644 --- a/core/modules/system/src/Tests/Ajax/MultiFormTest.php +++ b/core/modules/system/src/Tests/Ajax/MultiFormTest.php @@ -19,38 +19,38 @@ class MultiFormTest extends AjaxTestBase { * * @var array */ - public static $modules = array('form_test'); + public static $modules = ['form_test']; protected function setUp() { parent::setUp(); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']); // Create a multi-valued field for 'page' nodes to use for Ajax testing. $field_name = 'field_ajax_test'; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'entity_type' => 'node', 'field_name' => $field_name, 'type' => 'text', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $field_name, 'entity_type' => 'node', 'bundle' => 'page', ])->save(); entity_get_form_display('node', 'page', 'default') - ->setComponent($field_name, array('type' => 'text_textfield')) + ->setComponent($field_name, ['type' => 'text_textfield']) ->save(); // Log in a user who can create 'page' nodes. - $this->drupalLogin ($this->drupalCreateUser(array('create page content'))); + $this->drupalLogin($this->drupalCreateUser(['create page content'])); } /** * Tests that pages with the 'node_page_form' included twice work correctly. */ - function testMultiForm() { + public function testMultiForm() { // HTML IDs for elements within the field are potentially modified with // each Ajax submission, but these variables are stable and help target the // desired elements. @@ -84,7 +84,7 @@ function testMultiForm() { $forms = $this->xpath($form_xpath); foreach ($forms as $offset => $form) { $form_html_id = (string) $form['id']; - $this->drupalPostAjaxForm(NULL, array(), array($button_name => $button_value), NULL, array(), array(), $form_html_id); + $this->drupalPostAjaxForm(NULL, [], [$button_name => $button_value], NULL, [], [], $form_html_id); $form = $this->xpath($form_xpath)[$offset]; $field = $form->xpath('.' . $field_xpath); diff --git a/core/modules/system/src/Tests/Batch/PageTest.php b/core/modules/system/src/Tests/Batch/PageTest.php deleted file mode 100644 index f9948ed5..00000000 --- a/core/modules/system/src/Tests/Batch/PageTest.php +++ /dev/null @@ -1,74 +0,0 @@ -container->get('theme_handler')->install(array('seven', 'bartik')); - $this->config('system.theme') - ->set('default', 'bartik') - ->set('admin', 'seven') - ->save(); - - // Log in as an administrator who can see the administrative theme. - $admin_user = $this->drupalCreateUser(array('view the administration theme')); - $this->drupalLogin($admin_user); - // Visit an administrative page that runs a test batch, and check that the - // theme that was used during batch execution (which the batch callback - // function saved as a variable) matches the theme used on the - // administrative page. - $this->drupalGet('admin/batch-test/test-theme'); - // The stack should contain the name of the theme used on the progress - // page. - $this->assertEqual(batch_test_stack(), array('seven'), 'A progressive batch correctly uses the theme of the page that started the batch.'); - } - - /** - * Tests that the batch API progress page shows the title correctly. - */ - function testBatchProgressPageTitle() { - // Visit an administrative page that runs a test batch, and check that the - // title shown during batch execution (which the batch callback function - // saved as a variable) matches the theme used on the administrative page. - $this->drupalGet('batch-test/test-title'); - // The stack should contain the title shown on the progress page. - $this->assertEqual(batch_test_stack(), ['Batch Test'], 'The batch title is shown on the batch page.'); - $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); - } - - /** - * Tests that the progress messages are correct. - */ - function testBatchProgressMessages() { - // Go to the initial step only. - $this->maximumMetaRefreshCount = 0; - $this->drupalGet('batch-test/test-title'); - $this->assertRaw('
    Initializing.
     
    ', 'Initial progress message appears correctly.'); - $this->assertNoRaw('&nbsp;', 'Initial progress message is not double escaped.'); - // Now also go to the next step. - $this->maximumMetaRefreshCount = 1; - $this->drupalGet('batch-test/test-title'); - $this->assertRaw('
    Completed 1 of 1.
    ', 'Progress message for second step appears correctly.'); - } - -} diff --git a/core/modules/system/src/Tests/Bootstrap/ErrorContainer.php b/core/modules/system/src/Tests/Bootstrap/ErrorContainer.php index 9ee814f1..e8afa4b1 100644 --- a/core/modules/system/src/Tests/Bootstrap/ErrorContainer.php +++ b/core/modules/system/src/Tests/Bootstrap/ErrorContainer.php @@ -15,7 +15,7 @@ class ErrorContainer extends Container { public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) { if ($id === 'http_kernel') { // Enforce a recoverable error. - $callable = function(ErrorContainer $container) { + $callable = function (ErrorContainer $container) { }; $callable(1); } diff --git a/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php b/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php index 94ea1ac4..b115a61e 100644 --- a/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php +++ b/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php @@ -9,6 +9,12 @@ * Provides test assertions for testing page-level cache contexts & tags. * * Can be used by test classes that extend \Drupal\simpletest\WebTestBase. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. Use + * \Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait + * instead. + * + * @see https://www.drupal.org/node/2896632 */ trait AssertPageCacheContextsAndTagsTrait { @@ -89,9 +95,9 @@ protected function assertPageCacheContextsAndTags(Url $url, array $expected_cont $this->assertCacheContexts($expected_contexts); // Assert page cache item + expected cache tags. - $cid_parts = array($url->setAbsolute()->toString(), 'html'); + $cid_parts = [$url->setAbsolute()->toString(), 'html']; $cid = implode(':', $cid_parts); - $cache_entry = \Drupal::cache('render')->get($cid); + $cache_entry = \Drupal::cache('page')->get($cid); sort($cache_entry->tags); $this->assertEqual($cache_entry->tags, $expected_tags); $this->debugCacheTags($cache_entry->tags, $expected_tags); @@ -122,10 +128,14 @@ protected function debugCacheTags(array $actual_tags, array $expected_tags) { */ protected function assertCacheTags(array $expected_tags, $include_default_tags = TRUE) { // The anonymous role cache tag is only added if the user is anonymous. - if ($include_default_tags && \Drupal::currentUser()->isAnonymous()) { - $expected_tags = Cache::mergeTags($expected_tags, ['config:user.role.anonymous']); + if ($include_default_tags) { + if (\Drupal::currentUser()->isAnonymous()) { + $expected_tags = Cache::mergeTags($expected_tags, ['config:user.role.anonymous']); + } + $expected_tags[] = 'http_response'; } $actual_tags = $this->getCacheHeaderValues('X-Drupal-Cache-Tags'); + $expected_tags = array_unique($expected_tags); sort($expected_tags); sort($actual_tags); $this->assertIdentical($actual_tags, $expected_tags); diff --git a/core/modules/system/src/Tests/Cache/CacheTestBase.php b/core/modules/system/src/Tests/Cache/CacheTestBase.php index efca9fdf..e1bf7982 100644 --- a/core/modules/system/src/Tests/Cache/CacheTestBase.php +++ b/core/modules/system/src/Tests/Cache/CacheTestBase.php @@ -6,6 +6,9 @@ /** * Provides helper methods for cache tests. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\system\Functional\Cache\CacheTestBase instead. */ abstract class CacheTestBase extends WebTestBase { @@ -71,7 +74,7 @@ protected function assertCacheExists($message, $var = NULL, $cid = NULL, $bin = * @param $bin * The bin the cache item was stored in. */ - function assertCacheRemoved($message, $cid = NULL, $bin = NULL) { + public function assertCacheRemoved($message, $cid = NULL, $bin = NULL) { if ($bin == NULL) { $bin = $this->defaultBin; } diff --git a/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php b/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php index 6c3d98f7..c270f51c 100644 --- a/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php +++ b/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php @@ -69,7 +69,7 @@ protected function getTestBin() { * @return \Drupal\Core\Cache\CacheBackendInterface * Cache backend to test. */ - protected abstract function createCacheBackend($bin); + abstract protected function createCacheBackend($bin); /** * Allows specific implementation to change the environment before a test run. @@ -105,7 +105,7 @@ protected function getCacheBackend($bin = NULL) { } protected function setUp() { - $this->cachebackends = array(); + $this->cachebackends = []; $this->defaultValue = $this->randomMachineName(10); parent::setUp(); @@ -134,7 +134,7 @@ public function testSetGet() { $backend = $this->getCacheBackend(); $this->assertIdentical(FALSE, $backend->get('test1'), "Backend does not contain data for cache id test1."); - $with_backslash = array('foo' => '\Drupal\foo\Bar'); + $with_backslash = ['foo' => '\Drupal\foo\Bar']; $backend->set('test1', $with_backslash); $cached = $backend->get('test1'); $this->assert(is_object($cached), "Backend returned an object for cache id test1."); @@ -145,10 +145,10 @@ public function testSetGet() { $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.'); $this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2."); - $backend->set('test2', array('value' => 3), REQUEST_TIME + 3); + $backend->set('test2', ['value' => 3], REQUEST_TIME + 3); $cached = $backend->get('test2'); $this->assert(is_object($cached), "Backend returned an object for cache id test2."); - $this->assertIdentical(array('value' => 3), $cached->data); + $this->assertIdentical(['value' => 3], $cached->data); $this->assertTrue($cached->valid, 'Item is marked as valid.'); $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, REQUEST_TIME + 3, 'Expire time is correct.'); @@ -162,7 +162,7 @@ public function testSetGet() { $this->assertEqual($cached->expire, REQUEST_TIME - 3, 'Expire time is correct.'); $this->assertIdentical(FALSE, $backend->get('test4'), "Backend does not contain data for cache id test4."); - $with_eof = array('foo' => "\nEOF\ndata"); + $with_eof = ['foo' => "\nEOF\ndata"]; $backend->set('test4', $with_eof); $cached = $backend->get('test4'); $this->assert(is_object($cached), "Backend returned an object for cache id test4."); @@ -172,7 +172,7 @@ public function testSetGet() { $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.'); $this->assertIdentical(FALSE, $backend->get('test5'), "Backend does not contain data for cache id test5."); - $with_eof_and_semicolon = array('foo' => "\nEOF;\ndata"); + $with_eof_and_semicolon = ['foo' => "\nEOF;\ndata"]; $backend->set('test5', $with_eof_and_semicolon); $cached = $backend->get('test5'); $this->assert(is_object($cached), "Backend returned an object for cache id test5."); @@ -181,7 +181,7 @@ public function testSetGet() { $this->assertTrue($cached->created >= REQUEST_TIME && $cached->created <= round(microtime(TRUE), 3), 'Created time is correct.'); $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.'); - $with_variable = array('foo' => '$bar'); + $with_variable = ['foo' => '$bar']; $backend->set('test6', $with_variable); $cached = $backend->get('test6'); $this->assert(is_object($cached), "Backend returned an object for cache id test6."); @@ -260,14 +260,14 @@ public function testDelete() { public function testValueTypeIsKept() { $backend = $this->getCacheBackend(); - $variables = array( + $variables = [ 'test1' => 1, 'test2' => '0', 'test3' => '', 'test4' => 12.64, 'test5' => FALSE, - 'test6' => array(1, 2, 3), - ); + 'test6' => [1, 2, 3], + ]; // Create cache entries. foreach ($variables as $cid => $data) { @@ -300,14 +300,16 @@ public function testGetMultiple() { $backend->set($long_cid, 300); // Mismatch order for harder testing. - $reference = array( + $reference = [ 'test3', 'test7', - 'test21', // Cid does not exist. + // Cid does not exist. + 'test21', 'test6', - 'test19', // Cid does not exist until added before second getMultiple(). + // Cid does not exist until added before second getMultiple(). + 'test19', 'test2', - ); + ]; $cids = $reference; $ret = $backend->getMultiple($cids); @@ -367,7 +369,7 @@ public function testGetMultiple() { $this->assertFalse(in_array('test19', $cids), "Added cache id test19 is not in cids array."); // Test with a long $cid and non-numeric array key. - $cids = array('key:key' => $long_cid); + $cids = ['key:key' => $long_cid]; $return = $backend->getMultiple($cids); $this->assertEqual(300, $return[$long_cid]->data); $this->assertTrue(empty($cids)); @@ -383,13 +385,13 @@ public function testSetMultiple() { // Set multiple testing keys. $backend->set('cid_1', 'Some other value'); - $items = array( - 'cid_1' => array('data' => 1), - 'cid_2' => array('data' => 2), - 'cid_3' => array('data' => array(1, 2)), - 'cid_4' => array('data' => 1, 'expire' => $future_expiration), - 'cid_5' => array('data' => 1, 'tags' => array('test:a', 'test:b')), - ); + $items = [ + 'cid_1' => ['data' => 1], + 'cid_2' => ['data' => 2], + 'cid_3' => ['data' => [1, 2]], + 'cid_4' => ['data' => 1, 'expire' => $future_expiration], + 'cid_5' => ['data' => 1, 'tags' => ['test:a', 'test:b']], + ]; $backend->setMultiple($items); $cids = array_keys($items); $cached = $backend->getMultiple($cids); @@ -414,9 +416,9 @@ public function testSetMultiple() { // assertion. try { $items = [ - 'exception_test_1' => array('data' => 1, 'tags' => []), - 'exception_test_2' => array('data' => 2, 'tags' => ['valid']), - 'exception_test_3' => array('data' => 3, 'tags' => ['node' => [3, 5, 7]]), + 'exception_test_1' => ['data' => 1, 'tags' => []], + 'exception_test_2' => ['data' => 2, 'tags' => ['valid']], + 'exception_test_3' => ['data' => 3, 'tags' => ['node' => [3, 5, 7]]], ]; $backend->setMultiple($items); $this->fail('::setMultiple() was called with invalid cache tags, runtime assertion did not fail.'); @@ -443,14 +445,17 @@ public function testDeleteMultiple() { $backend->set('test7', 17); $backend->delete('test1'); - $backend->delete('test23'); // Nonexistent key should not cause an error. - $backend->deleteMultiple(array( + // Nonexistent key should not cause an error. + $backend->delete('test23'); + $backend->deleteMultiple([ 'test3', 'test5', 'test7', - 'test19', // Nonexistent key should not cause an error. - 'test21', // Nonexistent key should not cause an error. - )); + // Nonexistent key should not cause an error. + 'test19', + // Nonexistent key should not cause an error. + 'test21', + ]); // Test if expected keys have been deleted. $this->assertIdentical(FALSE, $backend->get('test1'), "Cache id test1 deleted."); @@ -468,7 +473,7 @@ public function testDeleteMultiple() { $this->assertIdentical(FALSE, $backend->get('test21'), "Cache id test21 does not exist."); // Calling deleteMultiple() with an empty array should not cause an error. - $this->assertFalse($backend->deleteMultiple(array())); + $this->assertFalse($backend->deleteMultiple([])); } /** @@ -494,21 +499,21 @@ public function testDeleteAll() { * Test Drupal\Core\Cache\CacheBackendInterface::invalidate() and * Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple(). */ - function testInvalidate() { + public function testInvalidate() { $backend = $this->getCacheBackend(); $backend->set('test1', 1); $backend->set('test2', 2); $backend->set('test3', 2); $backend->set('test4', 2); - $reference = array('test1', 'test2', 'test3', 'test4'); + $reference = ['test1', 'test2', 'test3', 'test4']; $cids = $reference; $ret = $backend->getMultiple($cids); $this->assertEqual(count($ret), 4, 'Four items returned.'); $backend->invalidate('test1'); - $backend->invalidateMultiple(array('test2', 'test3')); + $backend->invalidateMultiple(['test2', 'test3']); $cids = $reference; $ret = $backend->getMultiple($cids); @@ -520,55 +525,55 @@ function testInvalidate() { // Calling invalidateMultiple() with an empty array should not cause an // error. - $this->assertFalse($backend->invalidateMultiple(array())); + $this->assertFalse($backend->invalidateMultiple([])); } /** * Tests Drupal\Core\Cache\CacheBackendInterface::invalidateTags(). */ - function testInvalidateTags() { + public function testInvalidateTags() { $backend = $this->getCacheBackend(); // Create two cache entries with the same tag and tag value. - $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, array('test_tag:2')); - $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, array('test_tag:2')); + $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']); + $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Two cache items were created.'); // Invalidate test_tag of value 1. This should invalidate both entries. - Cache::invalidateTags(array('test_tag:2')); + Cache::invalidateTags(['test_tag:2']); $this->assertFalse($backend->get('test_cid_invalidate1') || $backend->get('test_cid_invalidate2'), 'Two cache items invalidated after invalidating a cache tag.'); $this->assertTrue($backend->get('test_cid_invalidate1', TRUE) && $backend->get('test_cid_invalidate2', TRUE), 'Cache items not deleted after invalidating a cache tag.'); // Create two cache entries with the same tag and an array tag value. - $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, array('test_tag:1')); - $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, array('test_tag:1')); + $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']); + $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Two cache items were created.'); // Invalidate test_tag of value 1. This should invalidate both entries. - Cache::invalidateTags(array('test_tag:1')); + Cache::invalidateTags(['test_tag:1']); $this->assertFalse($backend->get('test_cid_invalidate1') || $backend->get('test_cid_invalidate2'), 'Two caches removed after invalidating a cache tag.'); $this->assertTrue($backend->get('test_cid_invalidate1', TRUE) && $backend->get('test_cid_invalidate2', TRUE), 'Cache items not deleted after invalidating a cache tag.'); // Create three cache entries with a mix of tags and tag values. - $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, array('test_tag:1')); - $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, array('test_tag:2')); - $backend->set('test_cid_invalidate3', $this->defaultValue, Cache::PERMANENT, array('test_tag_foo:3')); + $backend->set('test_cid_invalidate1', $this->defaultValue, Cache::PERMANENT, ['test_tag:1']); + $backend->set('test_cid_invalidate2', $this->defaultValue, Cache::PERMANENT, ['test_tag:2']); + $backend->set('test_cid_invalidate3', $this->defaultValue, Cache::PERMANENT, ['test_tag_foo:3']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2') && $backend->get('test_cid_invalidate3'), 'Three cached items were created.'); - Cache::invalidateTags(array('test_tag_foo:3')); + Cache::invalidateTags(['test_tag_foo:3']); $this->assertTrue($backend->get('test_cid_invalidate1') && $backend->get('test_cid_invalidate2'), 'Cache items not matching the tag were not invalidated.'); $this->assertFalse($backend->get('test_cid_invalidated3'), 'Cached item matching the tag was removed.'); // Create cache entry in multiple bins. Two cache entries // (test_cid_invalidate1 and test_cid_invalidate2) still exist from previous // tests. - $tags = array('test_tag:1', 'test_tag:2', 'test_tag:3'); - $bins = array('path', 'bootstrap', 'page'); + $tags = ['test_tag:1', 'test_tag:2', 'test_tag:3']; + $bins = ['path', 'bootstrap', 'page']; foreach ($bins as $bin) { $this->getCacheBackend($bin)->set('test', $this->defaultValue, Cache::PERMANENT, $tags); $this->assertTrue($this->getCacheBackend($bin)->get('test'), 'Cache item was set in bin.'); } - Cache::invalidateTags(array('test_tag:2')); + Cache::invalidateTags(['test_tag:2']); // Test that the cache entry has been invalidated in multiple bins. foreach ($bins as $bin) { diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php b/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php index 2c778188..1e29e562 100644 --- a/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php @@ -8,6 +8,9 @@ /** * Provides helper methods for page cache tags tests. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\system\Functional\Cache\PageCacheTagsTestBase instead. */ abstract class PageCacheTagsTestBase extends WebTestBase { @@ -44,14 +47,14 @@ protected function setUp() { */ protected function verifyPageCache(Url $url, $hit_or_miss, $tags = FALSE) { $this->drupalGet($url); - $message = SafeMarkup::format('Page cache @hit_or_miss for %path.', array('@hit_or_miss' => $hit_or_miss, '%path' => $url->toString())); + $message = SafeMarkup::format('Page cache @hit_or_miss for %path.', ['@hit_or_miss' => $hit_or_miss, '%path' => $url->toString()]); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), $hit_or_miss, $message); if ($hit_or_miss === 'HIT' && is_array($tags)) { $absolute_url = $url->setAbsolute()->toString(); - $cid_parts = array($absolute_url, 'html'); + $cid_parts = [$absolute_url, 'html']; $cid = implode(':', $cid_parts); - $cache_entry = \Drupal::cache('render')->get($cid); + $cache_entry = \Drupal::cache('page')->get($cid); sort($cache_entry->tags); $tags = array_unique($tags); sort($tags); diff --git a/core/modules/system/src/Tests/Common/AddFeedTest.php b/core/modules/system/src/Tests/Common/AddFeedTest.php index b5392816..40ff215d 100644 --- a/core/modules/system/src/Tests/Common/AddFeedTest.php +++ b/core/modules/system/src/Tests/Common/AddFeedTest.php @@ -15,41 +15,41 @@ class AddFeedTest extends WebTestBase { /** * Tests attaching feeds with paths, URLs, and titles. */ - function testBasicFeedAddNoTitle() { + public function testBasicFeedAddNoTitle() { $path = $this->randomMachineName(12); $external_url = 'http://' . $this->randomMachineName(12) . '/' . $this->randomMachineName(12); - $fully_qualified_local_url = Url::fromUri('base:' . $this->randomMachineName(12), array('absolute' => TRUE))->toString(); + $fully_qualified_local_url = Url::fromUri('base:' . $this->randomMachineName(12), ['absolute' => TRUE])->toString(); $path_for_title = $this->randomMachineName(12); $external_for_title = 'http://' . $this->randomMachineName(12) . '/' . $this->randomMachineName(12); - $fully_qualified_for_title = Url::fromUri('base:' . $this->randomMachineName(12), array('absolute' => TRUE))->toString(); + $fully_qualified_for_title = Url::fromUri('base:' . $this->randomMachineName(12), ['absolute' => TRUE])->toString(); - $urls = array( - 'path without title' => array( - 'url' => Url::fromUri('base:' . $path, array('absolute' => TRUE))->toString(), + $urls = [ + 'path without title' => [ + 'url' => Url::fromUri('base:' . $path, ['absolute' => TRUE])->toString(), 'title' => '', - ), - 'external URL without title' => array( + ], + 'external URL without title' => [ 'url' => $external_url, 'title' => '', - ), - 'local URL without title' => array( + ], + 'local URL without title' => [ 'url' => $fully_qualified_local_url, 'title' => '', - ), - 'path with title' => array( - 'url' => Url::fromUri('base:' . $path_for_title, array('absolute' => TRUE))->toString(), + ], + 'path with title' => [ + 'url' => Url::fromUri('base:' . $path_for_title, ['absolute' => TRUE])->toString(), 'title' => $this->randomMachineName(12), - ), - 'external URL with title' => array( + ], + 'external URL with title' => [ 'url' => $external_for_title, 'title' => $this->randomMachineName(12), - ), - 'local URL with title' => array( + ], + 'local URL with title' => [ 'url' => $fully_qualified_for_title, 'title' => $this->randomMachineName(12), - ), - ); + ], + ]; $build = []; foreach ($urls as $feed_info) { @@ -63,14 +63,14 @@ function testBasicFeedAddNoTitle() { $this->setRawContent($response->getContent()); // Assert that the content contains the RSS links we specified. foreach ($urls as $description => $feed_info) { - $this->assertPattern($this->urlToRSSLinkPattern($feed_info['url'], $feed_info['title']), format_string('Found correct feed header for %description', array('%description' => $description))); + $this->assertPattern($this->urlToRSSLinkPattern($feed_info['url'], $feed_info['title']), format_string('Found correct feed header for %description', ['%description' => $description])); } } /** * Creates a pattern representing the RSS feed in the page. */ - function urlToRSSLinkPattern($url, $title = '') { + public function urlToRSSLinkPattern($url, $title = '') { // Escape any regular expression characters in the URL ('?' is the worst). $url = preg_replace('/([+?.*])/', '[$0]', $url); $generated_pattern = '%%'; @@ -82,12 +82,12 @@ function urlToRSSLinkPattern($url, $title = '') { * * @see https://www.drupal.org/node/1211668 */ - function testFeedIconEscaping() { - $variables = array( + public function testFeedIconEscaping() { + $variables = [ '#theme' => 'feed_icon', '#url' => 'node', '#title' => '<>&"\'', - ); + ]; $text = \Drupal::service('renderer')->renderRoot($variables); $this->assertEqual(trim(strip_tags($text)), 'Subscribe to <>&"'', 'feed_icon template escapes reserved HTML characters.'); } diff --git a/core/modules/system/src/Tests/Common/AlterTest.php b/core/modules/system/src/Tests/Common/AlterTest.php index 86bed7d2..863bd54d 100644 --- a/core/modules/system/src/Tests/Common/AlterTest.php +++ b/core/modules/system/src/Tests/Common/AlterTest.php @@ -16,24 +16,24 @@ class AlterTest extends WebTestBase { * * @var array */ - public static $modules = array('block', 'common_test'); + public static $modules = ['block', 'common_test']; /** * Tests if the theme has been altered. */ - function testDrupalAlter() { + public function testDrupalAlter() { // This test depends on Bartik, so make sure that it is always the current // active theme. - \Drupal::service('theme_handler')->install(array('bartik')); + \Drupal::service('theme_handler')->install(['bartik']); \Drupal::theme()->setActiveTheme(\Drupal::service('theme.initialization')->initTheme('bartik')); - $array = array('foo' => 'bar'); + $array = ['foo' => 'bar']; $entity = new \stdClass(); $entity->foo = 'bar'; // Verify alteration of a single argument. $array_copy = $array; - $array_expected = array('foo' => 'Drupal theme'); + $array_expected = ['foo' => 'Drupal theme']; \Drupal::moduleHandler()->alter('drupal_alter', $array_copy); \Drupal::theme()->alter('drupal_alter', $array_copy); $this->assertEqual($array_copy, $array_expected, 'Single array was altered.'); @@ -47,12 +47,12 @@ function testDrupalAlter() { // Verify alteration of multiple arguments. $array_copy = $array; - $array_expected = array('foo' => 'Drupal theme'); + $array_expected = ['foo' => 'Drupal theme']; $entity_copy = clone $entity; $entity_expected = clone $entity; $entity_expected->foo = 'Drupal theme'; $array2_copy = $array; - $array2_expected = array('foo' => 'Drupal theme'); + $array2_expected = ['foo' => 'Drupal theme']; \Drupal::moduleHandler()->alter('drupal_alter', $array_copy, $entity_copy, $array2_copy); \Drupal::theme()->alter('drupal_alter', $array_copy, $entity_copy, $array2_copy); $this->assertEqual($array_copy, $array_expected, 'First argument to \Drupal::moduleHandler->alter() was altered.'); @@ -63,9 +63,9 @@ function testDrupalAlter() { // common_test_module_implements_alter() places 'block' implementation after // other modules. $array_copy = $array; - $array_expected = array('foo' => 'Drupal block theme'); - \Drupal::moduleHandler()->alter(array('drupal_alter', 'drupal_alter_foo'), $array_copy); - \Drupal::theme()->alter(array('drupal_alter', 'drupal_alter_foo'), $array_copy); + $array_expected = ['foo' => 'Drupal block theme']; + \Drupal::moduleHandler()->alter(['drupal_alter', 'drupal_alter_foo'], $array_copy); + \Drupal::theme()->alter(['drupal_alter', 'drupal_alter_foo'], $array_copy); $this->assertEqual($array_copy, $array_expected, 'hook_TYPE_alter() implementations ran in correct order.'); } diff --git a/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php b/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php index 196d4631..1afdd4ee 100644 --- a/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php +++ b/core/modules/system/src/Tests/Common/EarlyRenderingControllerTest.php @@ -25,7 +25,7 @@ class EarlyRenderingControllerTest extends WebTestBase { /** * Tests theme preprocess functions being able to attach assets. */ - function testEarlyRendering() { + public function testEarlyRendering() { // Render array: non-early & early. $this->drupalGet(Url::fromRoute('early_rendering_controller_test.render_array')); $this->assertResponse(200); diff --git a/core/modules/system/src/Tests/Common/FormatDateTest.php b/core/modules/system/src/Tests/Common/FormatDateTest.php index cddf0a3f..c174e343 100644 --- a/core/modules/system/src/Tests/Common/FormatDateTest.php +++ b/core/modules/system/src/Tests/Common/FormatDateTest.php @@ -17,7 +17,7 @@ class FormatDateTest extends WebTestBase { * * @var array */ - public static $modules = array('language'); + public static $modules = ['language']; /** * Arbitrary langcode for a custom language. @@ -32,16 +32,16 @@ protected function setUp() { ->save(); $formats = $this->container->get('entity.manager') ->getStorage('date_format') - ->loadMultiple(array('long', 'medium', 'short')); + ->loadMultiple(['long', 'medium', 'short']); $formats['long']->setPattern('l, j. F Y - G:i')->save(); $formats['medium']->setPattern('j. F Y - G:i')->save(); $formats['short']->setPattern('Y M j - g:ia')->save(); $this->refreshVariables(); - $this->settingsSet('locale_custom_strings_' . self::LANGCODE, array( - '' => array('Sunday' => 'domingo'), - 'Long month name' => array('March' => 'marzo'), - )); + $this->settingsSet('locale_custom_strings_' . self::LANGCODE, [ + '' => ['Sunday' => 'domingo'], + 'Long month name' => ['March' => 'marzo'], + ]); ConfigurableLanguage::createFromLangcode(static::LANGCODE)->save(); $this->resetAll(); @@ -50,24 +50,24 @@ protected function setUp() { /** * Tests admin-defined formats in format_date(). */ - function testAdminDefinedFormatDate() { + public function testAdminDefinedFormatDate() { // Create and log in an admin user. - $this->drupalLogin($this->drupalCreateUser(array('administer site configuration'))); + $this->drupalLogin($this->drupalCreateUser(['administer site configuration'])); // Add new date format. - $edit = array( + $edit = [ 'id' => 'example_style', 'label' => 'Example Style', 'date_format_pattern' => 'j M y', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); // Add a second date format with a different case than the first. - $edit = array( + $edit = [ 'id' => 'example_style_uppercase', 'label' => 'Example Style Uppercase', 'date_format_pattern' => 'j M Y', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertText(t('Custom date format added.')); diff --git a/core/modules/system/src/Tests/Common/NoJavaScriptAnonymousTest.php b/core/modules/system/src/Tests/Common/NoJavaScriptAnonymousTest.php index 0e1e2983..e671f872 100644 --- a/core/modules/system/src/Tests/Common/NoJavaScriptAnonymousTest.php +++ b/core/modules/system/src/Tests/Common/NoJavaScriptAnonymousTest.php @@ -3,6 +3,7 @@ namespace Drupal\system\Tests\Common; use Drupal\simpletest\WebTestBase; +use Drupal\node\NodeInterface; /** * Tests that anonymous users are not served any JavaScript in the Standard @@ -18,7 +19,7 @@ protected function setUp() { parent::setUp(); // Grant the anonymous user the permission to look at user profiles. - user_role_grant_permissions('anonymous', array('access user profiles')); + user_role_grant_permissions('anonymous', ['access user profiles']); } /** @@ -26,9 +27,9 @@ protected function setUp() { */ public function testNoJavaScript() { // Create a node that is listed on the frontpage. - $this->drupalCreateNode(array( - 'promote' => NODE_PROMOTED, - )); + $this->drupalCreateNode([ + 'promote' => NodeInterface::PROMOTED, + ]); $user = $this->drupalCreateUser(); // Test frontpage. diff --git a/core/modules/system/src/Tests/Common/RenderWebTest.php b/core/modules/system/src/Tests/Common/RenderWebTest.php index fde7fa68..ed0e0864 100644 --- a/core/modules/system/src/Tests/Common/RenderWebTest.php +++ b/core/modules/system/src/Tests/Common/RenderWebTest.php @@ -19,12 +19,12 @@ class RenderWebTest extends WebTestBase { * * @var array */ - public static $modules = array('common_test'); + public static $modules = ['common_test']; /** * Asserts the cache context for the wrapper format is always present. */ - function testWrapperFormatCacheContext() { + public function testWrapperFormatCacheContext() { $this->drupalGet('common-test/type-link-active-class'); $this->assertIdentical(0, strpos($this->getRawContent(), "\nassertIdentical('text/html; charset=UTF-8', $this->drupalGetHeader('Content-Type')); @@ -43,135 +43,135 @@ function testWrapperFormatCacheContext() { * Tests rendering form elements without passing through * \Drupal::formBuilder()->doBuildForm(). */ - function testDrupalRenderFormElements() { + public function testDrupalRenderFormElements() { // Define a series of form elements. - $element = array( + $element = [ '#type' => 'button', '#value' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'submit')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'submit']); - $element = array( + $element = [ '#type' => 'textfield', '#title' => $this->randomMachineName(), '#value' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'text')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'text']); - $element = array( + $element = [ '#type' => 'password', '#title' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'password')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'password']); - $element = array( + $element = [ '#type' => 'textarea', '#title' => $this->randomMachineName(), '#value' => $this->randomMachineName(), - ); + ]; $this->assertRenderedElement($element, '//textarea'); - $element = array( + $element = [ '#type' => 'radio', '#title' => $this->randomMachineName(), '#value' => FALSE, - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'radio')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'radio']); - $element = array( + $element = [ '#type' => 'checkbox', '#title' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'checkbox')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'checkbox']); - $element = array( + $element = [ '#type' => 'select', '#title' => $this->randomMachineName(), - '#options' => array( + '#options' => [ 0 => $this->randomMachineName(), 1 => $this->randomMachineName(), - ), - ); + ], + ]; $this->assertRenderedElement($element, '//select'); - $element = array( + $element = [ '#type' => 'file', '#title' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'file')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'file']); - $element = array( + $element = [ '#type' => 'item', '#title' => $this->randomMachineName(), '#markup' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//div[contains(@class, :class) and contains(., :markup)]/label[contains(., :label)]', array( + ]; + $this->assertRenderedElement($element, '//div[contains(@class, :class) and contains(., :markup)]/label[contains(., :label)]', [ ':class' => 'js-form-type-item', ':markup' => $element['#markup'], ':label' => $element['#title'], - )); + ]); - $element = array( + $element = [ '#type' => 'hidden', '#title' => $this->randomMachineName(), '#value' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//input[@type=:type]', array(':type' => 'hidden')); + ]; + $this->assertRenderedElement($element, '//input[@type=:type]', [':type' => 'hidden']); - $element = array( + $element = [ '#type' => 'link', '#title' => $this->randomMachineName(), '#url' => Url::fromRoute('common_test.destination'), - '#options' => array( + '#options' => [ 'absolute' => TRUE, - ), - ); - $this->assertRenderedElement($element, '//a[@href=:href and contains(., :title)]', array( + ], + ]; + $this->assertRenderedElement($element, '//a[@href=:href and contains(., :title)]', [ ':href' => URL::fromRoute('common_test.destination')->setAbsolute()->toString(), ':title' => $element['#title'], - )); + ]); - $element = array( + $element = [ '#type' => 'details', '#open' => TRUE, '#title' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//details/summary[contains(., :title)]', array( + ]; + $this->assertRenderedElement($element, '//details/summary[contains(., :title)]', [ ':title' => $element['#title'], - )); + ]); - $element = array( + $element = [ '#type' => 'details', '#open' => TRUE, '#title' => $this->randomMachineName(), - ); + ]; $this->assertRenderedElement($element, '//details'); - $element['item'] = array( + $element['item'] = [ '#type' => 'item', '#title' => $this->randomMachineName(), '#markup' => $this->randomMachineName(), - ); - $this->assertRenderedElement($element, '//details/div/div[contains(@class, :class) and contains(., :markup)]', array( + ]; + $this->assertRenderedElement($element, '//details/div/div[contains(@class, :class) and contains(., :markup)]', [ ':class' => 'js-form-type-item', ':markup' => $element['item']['#markup'], - )); + ]); } /** * Tests that elements are rendered properly. */ - protected function assertRenderedElement(array $element, $xpath, array $xpath_args = array()) { + protected function assertRenderedElement(array $element, $xpath, array $xpath_args = []) { $original_element = $element; $this->setRawContent(drupal_render_root($element)); $this->verbose('
    ' . $this->getRawContent()); // @see \Drupal\simpletest\WebTestBase::xpath() $xpath = $this->buildXPathQuery($xpath, $xpath_args); - $element += array('#value' => NULL); - $this->assertFieldByXPath($xpath, $element['#value'], format_string('#type @type was properly rendered.', array( + $element += ['#value' => NULL]; + $this->assertFieldByXPath($xpath, $element['#value'], format_string('#type @type was properly rendered.', [ '@type' => var_export($element['#type'], TRUE), - ))); + ])); } } diff --git a/core/modules/system/src/Tests/Common/SimpleTestErrorCollectorTest.php b/core/modules/system/src/Tests/Common/SimpleTestErrorCollectorTest.php index 1be7e948..9af773b8 100644 --- a/core/modules/system/src/Tests/Common/SimpleTestErrorCollectorTest.php +++ b/core/modules/system/src/Tests/Common/SimpleTestErrorCollectorTest.php @@ -16,7 +16,7 @@ class SimpleTestErrorCollectorTest extends WebTestBase { * * @var array */ - public static $modules = array('system_test', 'error_test'); + public static $modules = ['system_test', 'error_test']; /** * Errors triggered during the test. @@ -26,13 +26,13 @@ class SimpleTestErrorCollectorTest extends WebTestBase { * * @var Array */ - protected $collectedErrors = array(); + protected $collectedErrors = []; /** * Tests that simpletest collects errors from the tested site. */ - function testErrorCollect() { - $this->collectedErrors = array(); + public function testErrorCollect() { + $this->collectedErrors = []; $this->drupalGet('error-test/generate-warnings-with-report'); $this->assertEqual(count($this->collectedErrors), 3, 'Three errors were collected'); @@ -71,23 +71,23 @@ protected function error($message = '', $group = 'Other', array $caller = NULL) } // Everything else should be collected but not propagated. else { - $this->collectedErrors[] = array( + $this->collectedErrors[] = [ 'message' => $message, 'group' => $group, 'caller' => $caller - ); + ]; } } /** * Asserts that a collected error matches what we are expecting. */ - function assertError($error, $group, $function, $file, $message = NULL) { - $this->assertEqual($error['group'], $group, format_string("Group was %group", array('%group' => $group))); - $this->assertEqual($error['caller']['function'], $function, format_string("Function was %function", array('%function' => $function))); - $this->assertEqual(drupal_basename($error['caller']['file']), $file, format_string("File was %file", array('%file' => $file))); + public function assertError($error, $group, $function, $file, $message = NULL) { + $this->assertEqual($error['group'], $group, format_string("Group was %group", ['%group' => $group])); + $this->assertEqual($error['caller']['function'], $function, format_string("Function was %function", ['%function' => $function])); + $this->assertEqual(drupal_basename($error['caller']['file']), $file, format_string("File was %file", ['%file' => $file])); if (isset($message)) { - $this->assertEqual($error['message'], $message, format_string("Message was %message", array('%message' => $message))); + $this->assertEqual($error['message'], $message, format_string("Message was %message", ['%message' => $message])); } } diff --git a/core/modules/system/src/Tests/Common/UrlTest.php b/core/modules/system/src/Tests/Common/UrlTest.php index 062e3e42..1092e1a0 100644 --- a/core/modules/system/src/Tests/Common/UrlTest.php +++ b/core/modules/system/src/Tests/Common/UrlTest.php @@ -20,19 +20,19 @@ */ class UrlTest extends WebTestBase { - public static $modules = array('common_test', 'url_alter_test'); + public static $modules = ['common_test', 'url_alter_test']; /** * Confirms that invalid URLs are filtered in link generating functions. */ - function testLinkXSS() { + public function testLinkXSS() { // Test \Drupal::l(). $text = $this->randomMachineName(); $path = ""; $encoded_path = "3CSCRIPT%3Ealert%28%27XSS%27%29%3C/SCRIPT%3E"; $link = \Drupal::l($text, Url::fromUserInput('/' . $path)); - $this->assertTrue(strpos($link, $encoded_path) !== FALSE && strpos($link, $path) === FALSE, format_string('XSS attack @path was filtered by \Drupal\Core\Utility\LinkGeneratorInterface::generate().', array('@path' => $path))); + $this->assertTrue(strpos($link, $encoded_path) !== FALSE && strpos($link, $path) === FALSE, format_string('XSS attack @path was filtered by \Drupal\Core\Utility\LinkGeneratorInterface::generate().', ['@path' => $path])); // Test \Drupal\Core\Url. $link = Url::fromUri('base:' . $path)->toString(); @@ -42,7 +42,7 @@ function testLinkXSS() { /** * Tests that #type=link bubbles outbound route/path processors' metadata. */ - function testLinkBubbleableMetadata() { + public function testLinkBubbleableMetadata() { $cases = [ ['Regular link', 'internal:/user', [], ['contexts' => [], 'tags' => [], 'max-age' => Cache::PERMANENT], []], ['Regular link, absolute', 'internal:/user', ['absolute' => TRUE], ['contexts' => ['url.site'], 'tags' => [], 'max-age' => Cache::PERMANENT], []], @@ -71,20 +71,20 @@ function testLinkBubbleableMetadata() { /** * Tests that default and custom attributes are handled correctly on links. */ - function testLinkAttributes() { + public function testLinkAttributes() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); // Test that hreflang is added when a link has a known language. - $language = new Language(array('id' => 'fr', 'name' => 'French')); - $hreflang_link = array( + $language = new Language(['id' => 'fr', 'name' => 'French']); + $hreflang_link = [ '#type' => 'link', - '#options' => array( + '#options' => [ 'language' => $language, - ), + ], '#url' => Url::fromUri('https://www.drupal.org'), '#title' => 'bar', - ); + ]; $langcode = $language->getId(); // Test that the default hreflang handling for links does not override a @@ -93,45 +93,45 @@ function testLinkAttributes() { $hreflang_override_link['#options']['attributes']['hreflang'] = 'foo'; $rendered = $renderer->renderRoot($hreflang_link); - $this->assertTrue($this->hasAttribute('hreflang', $rendered, $langcode), format_string('hreflang attribute with value @langcode is present on a rendered link when langcode is provided in the render array.', array('@langcode' => $langcode))); + $this->assertTrue($this->hasAttribute('hreflang', $rendered, $langcode), format_string('hreflang attribute with value @langcode is present on a rendered link when langcode is provided in the render array.', ['@langcode' => $langcode])); $rendered = $renderer->renderRoot($hreflang_override_link); - $this->assertTrue($this->hasAttribute('hreflang', $rendered, 'foo'), format_string('hreflang attribute with value @hreflang is present on a rendered link when @hreflang is provided in the render array.', array('@hreflang' => 'foo'))); + $this->assertTrue($this->hasAttribute('hreflang', $rendered, 'foo'), format_string('hreflang attribute with value @hreflang is present on a rendered link when @hreflang is provided in the render array.', ['@hreflang' => 'foo'])); // Test the active class in links produced by // \Drupal\Core\Utility\LinkGeneratorInterface::generate() and #type 'link'. - $options_no_query = array(); - $options_query = array( - 'query' => array( + $options_no_query = []; + $options_query = [ + 'query' => [ 'foo' => 'bar', 'one' => 'two', - ), - ); - $options_query_reverse = array( - 'query' => array( + ], + ]; + $options_query_reverse = [ + 'query' => [ 'one' => 'two', 'foo' => 'bar', - ), - ); + ], + ]; // Test #type link. $path = 'common-test/type-link-active-class'; $this->drupalGet($path, $options_no_query); - $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'is-active')); + $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', [':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'is-active']); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page is marked active.'); - $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'is-active')); + $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', [':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'is-active']); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page with a query string when the current page has no query string is not marked active.'); $this->drupalGet($path, $options_query); - $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'is-active')); + $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', [':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'is-active']); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page with a query string that matches the current query string is marked active.'); - $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query_reverse)->toString(), ':class' => 'is-active')); + $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', [':href' => Url::fromRoute('common_test.l_active_class', [], $options_query_reverse)->toString(), ':class' => 'is-active']); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page with a query string that has matching parameters to the current query string but in a different order is marked active.'); - $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'is-active')); + $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', [':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'is-active']); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page without a query string when the current page has a query string is not marked active.'); // Test adding a custom class in links produced by @@ -139,28 +139,28 @@ function testLinkAttributes() { // Test the link generator. $class_l = $this->randomMachineName(); $link_l = \Drupal::l($this->randomMachineName(), new Url('', [], ['attributes' => ['class' => [$class_l]]])); - $this->assertTrue($this->hasAttribute('class', $link_l, $class_l), format_string('Custom class @class is present on link when requested by l()', array('@class' => $class_l))); + $this->assertTrue($this->hasAttribute('class', $link_l, $class_l), format_string('Custom class @class is present on link when requested by l()', ['@class' => $class_l])); // Test #type. $class_theme = $this->randomMachineName(); - $type_link = array( + $type_link = [ '#type' => 'link', '#title' => $this->randomMachineName(), '#url' => Url::fromRoute(''), - '#options' => array( - 'attributes' => array( - 'class' => array($class_theme), - ), - ), - ); + '#options' => [ + 'attributes' => [ + 'class' => [$class_theme], + ], + ], + ]; $link_theme = $renderer->renderRoot($type_link); - $this->assertTrue($this->hasAttribute('class', $link_theme, $class_theme), format_string('Custom class @class is present on link when requested by #type', array('@class' => $class_theme))); + $this->assertTrue($this->hasAttribute('class', $link_theme, $class_theme), format_string('Custom class @class is present on link when requested by #type', ['@class' => $class_theme])); } /** * Tests that link functions support render arrays as 'text'. */ - function testLinkRenderArrayText() { + public function testLinkRenderArrayText() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); @@ -168,27 +168,27 @@ function testLinkRenderArrayText() { $l = \Drupal::l('foo', Url::fromUri('https://www.drupal.org')); // Test a renderable array passed to the link generator. - $renderer->executeInRenderContext(new RenderContext(), function() use ($renderer, $l) { - $renderable_text = array('#markup' => 'foo'); + $renderer->executeInRenderContext(new RenderContext(), function () use ($renderer, $l) { + $renderable_text = ['#markup' => 'foo']; $l_renderable_text = \Drupal::l($renderable_text, Url::fromUri('https://www.drupal.org')); $this->assertEqual($l_renderable_text, $l); }); // Test a themed link with plain text 'text'. - $type_link_plain_array = array( + $type_link_plain_array = [ '#type' => 'link', '#title' => 'foo', '#url' => Url::fromUri('https://www.drupal.org'), - ); + ]; $type_link_plain = $renderer->renderRoot($type_link_plain_array); $this->assertEqual($type_link_plain, $l); // Build a themed link with renderable 'text'. - $type_link_nested_array = array( + $type_link_nested_array = [ '#type' => 'link', - '#title' => array('#markup' => 'foo'), + '#title' => ['#markup' => 'foo'], '#url' => Url::fromUri('https://www.drupal.org'), - ); + ]; $type_link_nested = $renderer->renderRoot($type_link_nested_array); $this->assertEqual($type_link_nested, $l); } @@ -211,54 +211,54 @@ private function hasAttribute($attribute, $link, $class) { /** * Tests UrlHelper::filterQueryParameters(). */ - function testDrupalGetQueryParameters() { - $original = array( + public function testDrupalGetQueryParameters() { + $original = [ 'a' => 1, - 'b' => array( + 'b' => [ 'd' => 4, - 'e' => array( + 'e' => [ 'f' => 5, - ), - ), + ], + ], 'c' => 3, - ); + ]; // First-level exclusion. $result = $original; unset($result['b']); - $this->assertEqual(UrlHelper::filterQueryParameters($original, array('b')), $result, "'b' was removed."); + $this->assertEqual(UrlHelper::filterQueryParameters($original, ['b']), $result, "'b' was removed."); // Second-level exclusion. $result = $original; unset($result['b']['d']); - $this->assertEqual(UrlHelper::filterQueryParameters($original, array('b[d]')), $result, "'b[d]' was removed."); + $this->assertEqual(UrlHelper::filterQueryParameters($original, ['b[d]']), $result, "'b[d]' was removed."); // Third-level exclusion. $result = $original; unset($result['b']['e']['f']); - $this->assertEqual(UrlHelper::filterQueryParameters($original, array('b[e][f]')), $result, "'b[e][f]' was removed."); + $this->assertEqual(UrlHelper::filterQueryParameters($original, ['b[e][f]']), $result, "'b[e][f]' was removed."); // Multiple exclusions. $result = $original; unset($result['a'], $result['b']['e'], $result['c']); - $this->assertEqual(UrlHelper::filterQueryParameters($original, array('a', 'b[e]', 'c')), $result, "'a', 'b[e]', 'c' were removed."); + $this->assertEqual(UrlHelper::filterQueryParameters($original, ['a', 'b[e]', 'c']), $result, "'a', 'b[e]', 'c' were removed."); } /** * Tests UrlHelper::parse(). */ - function testDrupalParseUrl() { + public function testDrupalParseUrl() { // Relative, absolute, and external URLs, without/with explicit script path, // without/with Drupal path. - foreach (array('', '/', 'https://www.drupal.org/') as $absolute) { - foreach (array('', 'index.php/') as $script) { - foreach (array('', 'foo/bar') as $path) { + foreach (['', '/', 'https://www.drupal.org/'] as $absolute) { + foreach (['', 'index.php/'] as $script) { + foreach (['', 'foo/bar'] as $path) { $url = $absolute . $script . $path . '?foo=bar&bar=baz&baz#foo'; - $expected = array( + $expected = [ 'path' => $absolute . $script . $path, - 'query' => array('foo' => 'bar', 'bar' => 'baz', 'baz' => ''), + 'query' => ['foo' => 'bar', 'bar' => 'baz', 'baz' => ''], 'fragment' => 'foo', - ); + ]; $this->assertEqual(UrlHelper::parse($url), $expected, 'URL parsed correctly.'); } } @@ -266,11 +266,11 @@ function testDrupalParseUrl() { // Relative URL that is known to confuse parse_url(). $url = 'foo/bar:1'; - $result = array( + $result = [ 'path' => 'foo/bar:1', - 'query' => array(), + 'query' => [], 'fragment' => '', - ); + ]; $this->assertEqual(UrlHelper::parse($url), $result, 'Relative URL parsed correctly.'); // Test that drupal can recognize an absolute URL. Used to prevent attack vectors. @@ -285,7 +285,7 @@ function testDrupalParseUrl() { /** * Tests external URL handling. */ - function testExternalUrls() { + public function testExternalUrls() { $test_url = 'https://www.drupal.org/'; // Verify external URL can contain a fragment. @@ -296,7 +296,7 @@ function testExternalUrls() { // Verify fragment can be overridden in an external URL. $url = $test_url . '#drupal'; $fragment = $this->randomMachineName(10); - $result = Url::fromUri($url, array('fragment' => $fragment))->toString(); + $result = Url::fromUri($url, ['fragment' => $fragment])->toString(); $this->assertEqual($test_url . '#' . $fragment, $result, 'External URL fragment is overridden with a custom fragment in $options.'); // Verify external URL can contain a query string. @@ -306,14 +306,14 @@ function testExternalUrls() { // Verify external URL can be extended with a query string. $url = $test_url; - $query = array($this->randomMachineName(5) => $this->randomMachineName(5)); - $result = Url::fromUri($url, array('query' => $query))->toString(); + $query = [$this->randomMachineName(5) => $this->randomMachineName(5)]; + $result = Url::fromUri($url, ['query' => $query])->toString(); $this->assertEqual($url . '?' . http_build_query($query, '', '&'), $result, 'External URL can be extended with a query string in $options.'); // Verify query string can be extended in an external URL. $url = $test_url . '?drupal=awesome'; - $query = array($this->randomMachineName(5) => $this->randomMachineName(5)); - $result = Url::fromUri($url, array('query' => $query))->toString(); + $query = [$this->randomMachineName(5) => $this->randomMachineName(5)]; + $result = Url::fromUri($url, ['query' => $query])->toString(); $this->assertEqual($url . '&' . http_build_query($query, '', '&'), $result); } diff --git a/core/modules/system/src/Tests/Condition/ConditionFormTest.php b/core/modules/system/src/Tests/Condition/ConditionFormTest.php index 21d0fcb9..42945b25 100644 --- a/core/modules/system/src/Tests/Condition/ConditionFormTest.php +++ b/core/modules/system/src/Tests/Condition/ConditionFormTest.php @@ -16,14 +16,14 @@ */ class ConditionFormTest extends WebTestBase { - public static $modules = array('node', 'condition_test'); + public static $modules = ['node', 'condition_test']; /** * Submit the condition_node_type_test_form to test condition forms. */ - function testConfigForm() { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Page')); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + public function testConfigForm() { + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); $article = Node::create([ 'type' => 'article', @@ -34,7 +34,7 @@ function testConfigForm() { $this->drupalGet('condition_test'); $this->assertField('bundles[article]', 'There is an article bundle selector.'); $this->assertField('bundles[page]', 'There is a page bundle selector.'); - $this->drupalPostForm(NULL, array('bundles[page]' => 'page', 'bundles[article]' => 'article'), t('Submit')); + $this->drupalPostForm(NULL, ['bundles[page]' => 'page', 'bundles[article]' => 'article'], t('Submit')); // @see \Drupal\condition_test\FormController::submitForm() $this->assertText('Bundle: page'); $this->assertText('Bundle: article'); diff --git a/core/modules/system/src/Tests/Database/DatabaseWebTestBase.php b/core/modules/system/src/Tests/Database/DatabaseWebTestBase.php index d484d68f..8a250baf 100644 --- a/core/modules/system/src/Tests/Database/DatabaseWebTestBase.php +++ b/core/modules/system/src/Tests/Database/DatabaseWebTestBase.php @@ -2,11 +2,16 @@ namespace Drupal\system\Tests\Database; +@trigger_error(__NAMESPACE__ . '\DatabaseWebTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Database\DatabaseTestBase', E_USER_DEPRECATED); + use Drupal\KernelTests\Core\Database\DatabaseTestBase; use Drupal\simpletest\WebTestBase; /** * Base class for databases database tests. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead + * use \Drupal\Tests\system\Functional\Database\DatabaseTestBase. */ abstract class DatabaseWebTestBase extends WebTestBase { @@ -15,7 +20,7 @@ abstract class DatabaseWebTestBase extends WebTestBase { * * @var array */ - public static $modules = array('database_test'); + public static $modules = ['database_test']; protected function setUp() { parent::setUp(); diff --git a/core/modules/system/src/Tests/Database/FakeRecord.php b/core/modules/system/src/Tests/Database/FakeRecord.php index fce13668..375e60f2 100644 --- a/core/modules/system/src/Tests/Database/FakeRecord.php +++ b/core/modules/system/src/Tests/Database/FakeRecord.php @@ -2,11 +2,16 @@ namespace Drupal\system\Tests\Database; +@trigger_error(__NAMESPACE__ . '\FakeRecord is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Database\FakeRecord', E_USER_DEPRECATED); + /** * Fetches into a class. * * PDO supports using a new instance of an arbitrary class for records * rather than just a stdClass or array. This class is for testing that * functionality. (See testQueryFetchClass() below) + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead + * use \Drupal\Tests\system\Functional\Database\FakeRecord. */ -class FakeRecord { } +class FakeRecord {} diff --git a/core/modules/system/src/Tests/Database/SelectTableSortDefaultTest.php b/core/modules/system/src/Tests/Database/SelectTableSortDefaultTest.php deleted file mode 100644 index 7ccbbb5e..00000000 --- a/core/modules/system/src/Tests/Database/SelectTableSortDefaultTest.php +++ /dev/null @@ -1,87 +0,0 @@ - t('Task ID'), 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'), - array('field' => t('Task ID'), 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'), - array('field' => t('Task'), 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'), - array('field' => t('Task'), 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'), - // more elements here - - ); - - foreach ($sorts as $sort) { - $this->drupalGet('database_test/tablesort/', array('query' => array('order' => $sort['field'], 'sort' => $sort['sort']))); - $data = json_decode($this->getRawContent()); - - $first = array_shift($data->tasks); - $last = array_pop($data->tasks); - - $this->assertEqual($first->task, $sort['first'], 'Items appear in the correct order.'); - $this->assertEqual($last->task, $sort['last'], 'Items appear in the correct order.'); - } - } - - /** - * Confirms precedence of tablesorts headers. - * - * If a tablesort's orderByHeader is called before another orderBy, then its - * header happens first. - */ - function testTableSortQueryFirst() { - $sorts = array( - array('field' => t('Task ID'), 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'), - array('field' => t('Task ID'), 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'), - array('field' => t('Task'), 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'), - array('field' => t('Task'), 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'), - // more elements here - - ); - - foreach ($sorts as $sort) { - $this->drupalGet('database_test/tablesort_first/', array('query' => array('order' => $sort['field'], 'sort' => $sort['sort']))); - $data = json_decode($this->getRawContent()); - - $first = array_shift($data->tasks); - $last = array_pop($data->tasks); - - $this->assertEqual($first->task, $sort['first'], format_string('Items appear in the correct order sorting by @field @sort.', array('@field' => $sort['field'], '@sort' => $sort['sort']))); - $this->assertEqual($last->task, $sort['last'], format_string('Items appear in the correct order sorting by @field @sort.', array('@field' => $sort['field'], '@sort' => $sort['sort']))); - } - } - - /** - * Confirms that tableselect is rendered without error. - * - * Specifically that no sort is set in a tableselect, and that header links - * are correct. - */ - function testTableSortDefaultSort() { - $this->drupalGet('database_test/tablesort_default_sort'); - - // Verify that the table was displayed. Just the header is checked for - // because if there were any fatal errors or exceptions in displaying the - // sorted table, it would not print the table. - $this->assertText(t('Username')); - - // Verify that the header links are built properly. - $this->assertLinkByHref('database_test/tablesort_default_sort'); - $this->assertPattern('/\/'); - } - -} diff --git a/core/modules/system/src/Tests/DrupalKernel/ContainerRebuildWebTest.php b/core/modules/system/src/Tests/DrupalKernel/ContainerRebuildWebTest.php deleted file mode 100644 index c87e3ad8..00000000 --- a/core/modules/system/src/Tests/DrupalKernel/ContainerRebuildWebTest.php +++ /dev/null @@ -1,55 +0,0 @@ -drupalGet(''); - $this->assertHeader('container_rebuild_indicator', FALSE); - - $this->writeSettings(['settings' => ['deployment_identifier' => (object) ['value' => 'new-identifier', 'required' => TRUE]]]); - - $this->drupalGet(''); - - $this->assertHeader('container_rebuild_indicator', 'new-identifier'); - } - - /** - * Tests container invalidation. - */ - public function testContainerInvalidation() { - - // Ensure that parameter is not set. - $this->drupalGet(''); - $this->assertHeader('container_rebuild_test_parameter', FALSE); - - // Ensure that after setting the parameter, without a container rebuild the - // parameter is still not set. - $this->writeSettings(['settings' => ['container_rebuild_test_parameter' => (object) ['value' => 'rebuild_me_please', 'required' => TRUE]]]); - - $this->drupalGet(''); - $this->assertHeader('container_rebuild_test_parameter', FALSE); - - // Ensure that after container invalidation the parameter is set. - \Drupal::service('kernel')->invalidateContainer(); - $this->drupalGet(''); - $this->assertHeader('container_rebuild_test_parameter', 'rebuild_me_please'); - } - -} diff --git a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php index 9ecefad4..7f5c5e34 100644 --- a/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityCacheTagsTestBase.php @@ -16,6 +16,9 @@ /** * Provides helper methods for Entity cache tags tests. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\system\Functional\Entity\EntityCacheTagsTestBase instead. */ abstract class EntityCacheTagsTestBase extends PageCacheTagsTestBase { @@ -68,18 +71,18 @@ protected function setUp() { if ($this->entity->getEntityType()->get('field_ui_base_route')) { // Add field, so we can modify the field storage and field entities to // verify that changes to those indeed clear cache tags. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => 'configurable_field', 'entity_type' => $this->entity->getEntityTypeId(), 'type' => 'test_field', - 'settings' => array(), - ))->save(); + 'settings' => [], + ])->save(); FieldConfig::create([ 'entity_type' => $this->entity->getEntityTypeId(), 'bundle' => $this->entity->bundle(), 'field_name' => 'configurable_field', 'label' => 'Configurable field', - 'settings' => array(), + 'settings' => [], ])->save(); // Reload the entity now that a new field has been added to it. @@ -110,11 +113,11 @@ protected function setUp() { * @see \Drupal\simpletest\TestBase::getInfo() */ protected static function generateStandardizedInfo($entity_type_label, $group) { - return array( + return [ 'name' => "$entity_type_label entity cache tags", 'description' => "Test the $entity_type_label entity's cache tags.", 'group' => $group, - ); + ]; } /** @@ -170,7 +173,7 @@ protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) * @see \Drupal\system\Tests\Entity\EntityCacheTagsTestBase::createEntity() */ protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) { - return array(); + return []; } /** @@ -205,7 +208,7 @@ protected function getAdditionalCacheTagsForEntityListing() { protected function selectViewMode($entity_type) { $view_modes = \Drupal::entityManager() ->getStorage('entity_view_mode') - ->loadByProperties(array('targetEntityType' => $entity_type)); + ->loadByProperties(['targetEntityType' => $entity_type]); if (empty($view_modes)) { return 'default'; @@ -241,46 +244,46 @@ protected function createReferenceTestEntities($referenced_entity) { // Add a field of the given type to the given entity type's "foo" bundle. $field_name = $referenced_entity->getEntityTypeId() . '_reference'; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => $entity_type, 'type' => 'entity_reference', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - 'settings' => array( + 'settings' => [ 'target_type' => $referenced_entity->getEntityTypeId(), - ), - ))->save(); + ], + ])->save(); FieldConfig::create([ 'field_name' => $field_name, 'entity_type' => $entity_type, 'bundle' => $bundle, - 'settings' => array( + 'settings' => [ 'handler' => 'default', - 'handler_settings' => array( - 'target_bundles' => array( + 'handler_settings' => [ + 'target_bundles' => [ $referenced_entity->bundle() => $referenced_entity->bundle(), - ), - 'sort' => array('field' => '_none'), + ], + 'sort' => ['field' => '_none'], 'auto_create' => FALSE, - ), - ), + ], + ], ])->save(); if (!$this->entity->getEntityType()->hasHandlerClass('view_builder')) { entity_get_display($entity_type, $bundle, 'full') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } else { $referenced_entity_view_mode = $this->selectViewMode($this->entity->getEntityTypeId()); entity_get_display($entity_type, $bundle, 'full') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => 'entity_reference_entity_view', - 'settings' => array( + 'settings' => [ 'view_mode' => $referenced_entity_view_mode, - ), - )) + ], + ]) ->save(); } @@ -288,28 +291,28 @@ protected function createReferenceTestEntities($referenced_entity) { $label_key = \Drupal::entityManager()->getDefinition($entity_type)->getKey('label'); $referencing_entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ $label_key => 'Referencing ' . $entity_type, 'status' => 1, 'type' => $bundle, - $field_name => array('target_id' => $referenced_entity->id()), - )); + $field_name => ['target_id' => $referenced_entity->id()], + ]); $referencing_entity->save(); // Create an entity that does not reference the entity being tested. $non_referencing_entity = $this->container->get('entity_type.manager') ->getStorage($entity_type) - ->create(array( + ->create([ $label_key => 'Non-referencing ' . $entity_type, 'status' => 1, 'type' => $bundle, - )); + ]); $non_referencing_entity->save(); - return array( + return [ $referencing_entity, $non_referencing_entity, - ); + ]; } /** @@ -343,14 +346,14 @@ public function testReferencedEntity() { // 'user.permissions' is a required cache context, and responses that vary // by this cache context when requested by anonymous users automatically // also get this cache tag, to ensure correct invalidation. - $page_cache_tags = Cache::mergeTags(['rendered'], ['config:user.role.anonymous']); + $page_cache_tags = Cache::mergeTags(['http_response', 'rendered'], ['config:user.role.anonymous']); // If the block module is used, the Block page display variant is used, // which adds the block config entity type's list cache tags. $page_cache_tags = Cache::mergeTags($page_cache_tags, \Drupal::moduleHandler()->moduleExists('block') ? ['config:block_list'] : []); $page_cache_tags_referencing_entity = in_array('user.permissions', $this->getAccessCacheContextsForEntity($this->referencingEntity)) ? ['config:user.role.anonymous'] : []; - $view_cache_tag = array(); + $view_cache_tag = []; if ($this->entity->getEntityType()->hasHandlerClass('view_builder')) { $view_cache_tag = \Drupal::entityManager()->getViewBuilder($entity_type) ->getCacheTags(); @@ -641,7 +644,7 @@ public function testReferencedEntity() { // Verify cache hits. $referencing_entity_cache_tags = Cache::mergeTags($this->referencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags()); - $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['rendered']); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['http_response', 'rendered']); $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->getAdditionalCacheTagsForEntityListing()); $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags); diff --git a/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php b/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php index 0123597e..3b1e7bd6 100644 --- a/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php +++ b/core/modules/system/src/Tests/Entity/EntityDefinitionTestTrait.php @@ -37,6 +37,7 @@ protected function updateEntityTypeToRevisionable() { $keys = $entity_type->getKeys(); $keys['revision'] = 'revision_id'; $entity_type->set('entity_keys', $keys); + $entity_type->set('revision_table', 'entity_test_update_revision'); $this->state->set('entity_test_update.entity_type', $entity_type); } @@ -50,6 +51,7 @@ protected function updateEntityTypeToNotRevisionable() { $keys = $entity_type->getKeys(); unset($keys['revision']); $entity_type->set('entity_keys', $keys); + $entity_type->set('revision_table', NULL); $this->state->set('entity_test_update.entity_type', $entity_type); } @@ -86,6 +88,24 @@ protected function updateEntityTypeToNotTranslatable() { $this->state->set('entity_test_update.entity_type', $entity_type); } + /** + * Updates the 'entity_test_update' entity type to revisionable and + * translatable. + */ + protected function updateEntityTypeToRevisionableAndTranslatable() { + $entity_type = clone $this->entityManager->getDefinition('entity_test_update'); + + $keys = $entity_type->getKeys(); + $keys['revision'] = 'revision_id'; + $entity_type->set('entity_keys', $keys); + $entity_type->set('translatable', TRUE); + $entity_type->set('data_table', 'entity_test_update_data'); + $entity_type->set('revision_table', 'entity_test_update_revision'); + $entity_type->set('revision_data_table', 'entity_test_update_revision_data'); + + $this->state->set('entity_test_update.entity_type', $entity_type); + } + /** * Adds a new base field to the 'entity_test_update' entity type. * @@ -202,9 +222,9 @@ protected function removeBundleField() { * @see \Drupal\entity_test\EntityTestStorageSchema::getEntitySchema() */ protected function addEntityIndex() { - $indexes = array( - 'entity_test_update__new_index' => array('name', 'user_id'), - ); + $indexes = [ + 'entity_test_update__new_index' => ['name', 'test_single_property'], + ]; $this->state->set('entity_test_update.additional_entity_indexes', $indexes); } diff --git a/core/modules/system/src/Tests/Entity/EntityFormTest.php b/core/modules/system/src/Tests/Entity/EntityFormTest.php index 4e0ced51..2ebc3506 100644 --- a/core/modules/system/src/Tests/Entity/EntityFormTest.php +++ b/core/modules/system/src/Tests/Entity/EntityFormTest.php @@ -17,11 +17,11 @@ class EntityFormTest extends WebTestBase { * * @var array */ - public static $modules = array('entity_test', 'language'); + public static $modules = ['entity_test', 'language']; protected function setUp() { parent::setUp(); - $web_user = $this->drupalCreateUser(array('administer entity_test content', 'view test entity')); + $web_user = $this->drupalCreateUser(['administer entity_test content', 'view test entity']); $this->drupalLogin($web_user); // Add a language. @@ -31,7 +31,7 @@ protected function setUp() { /** * Tests basic form CRUD functionality. */ - function testFormCRUD() { + public function testFormCRUD() { // All entity variations have to have the same results. foreach (entity_test_entity_types() as $entity_type) { $this->doTestFormCRUD($entity_type); @@ -53,7 +53,7 @@ public function testMultilingualFormCRUD() { * * @see entity_test_entity_form_display_alter() */ - function testEntityFormDisplayAlter() { + public function testEntityFormDisplayAlter() { $this->drupalGet('entity_test/add'); $altered_field = $this->xpath('//input[@name="field_test_text[0][value]" and @size="42"]'); $this->assertTrue(count($altered_field) === 1, 'The altered field has the correct size value.'); @@ -69,28 +69,28 @@ protected function doTestFormCRUD($entity_type) { $name1 = $this->randomMachineName(8); $name2 = $this->randomMachineName(10); - $edit = array( + $edit = [ 'name[0][value]' => $name1, 'field_test_text[0][value]' => $this->randomMachineName(16), - ); + ]; $this->drupalPostForm($entity_type . '/add', $edit, t('Save')); $entity = $this->loadEntityByName($entity_type, $name1); - $this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', ['%entity_type' => $entity_type])); $edit['name[0][value]'] = $name2; $this->drupalPostForm($entity_type . '/manage/' . $entity->id() . '/edit', $edit, t('Save')); $entity = $this->loadEntityByName($entity_type, $name1); - $this->assertFalse($entity, format_string('%entity_type: The entity has been modified.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity, format_string('%entity_type: The entity has been modified.', ['%entity_type' => $entity_type])); $entity = $this->loadEntityByName($entity_type, $name2); - $this->assertTrue($entity, format_string('%entity_type: Modified entity found in the database.', array('%entity_type' => $entity_type))); - $this->assertNotEqual($entity->name->value, $name1, format_string('%entity_type: The entity name has been modified.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity, format_string('%entity_type: Modified entity found in the database.', ['%entity_type' => $entity_type])); + $this->assertNotEqual($entity->name->value, $name1, format_string('%entity_type: The entity name has been modified.', ['%entity_type' => $entity_type])); $this->drupalGet($entity_type . '/manage/' . $entity->id() . '/edit'); $this->clickLink(t('Delete')); - $this->drupalPostForm(NULL, array(), t('Delete')); + $this->drupalPostForm(NULL, [], t('Delete')); $entity = $this->loadEntityByName($entity_type, $name2); - $this->assertFalse($entity, format_string('%entity_type: Entity not found in the database.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity, format_string('%entity_type: Entity not found in the database.', ['%entity_type' => $entity_type])); } /** @@ -104,33 +104,33 @@ protected function doTestMultilingualFormCRUD($entity_type_id) { $name1_ro = $this->randomMachineName(9); $name2_ro = $this->randomMachineName(11); - $edit = array( + $edit = [ 'name[0][value]' => $name1, 'field_test_text[0][value]' => $this->randomMachineName(16), - ); + ]; $this->drupalPostForm($entity_type_id . '/add', $edit, t('Save')); $entity = $this->loadEntityByName($entity_type_id, $name1); - $this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', array('%entity_type' => $entity_type_id))); + $this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', ['%entity_type' => $entity_type_id])); // Add a translation to the newly created entity without using the Content // translation module. $entity->addTranslation('ro', ['name' => $name1_ro])->save(); $translated_entity = $this->loadEntityByName($entity_type_id, $name1)->getTranslation('ro'); - $this->assertEqual($translated_entity->name->value, $name1_ro, format_string('%entity_type: The translation has been added.', array('%entity_type' => $entity_type_id))); + $this->assertEqual($translated_entity->name->value, $name1_ro, format_string('%entity_type: The translation has been added.', ['%entity_type' => $entity_type_id])); $edit['name[0][value]'] = $name2_ro; $this->drupalPostForm('ro/' . $entity_type_id . '/manage/' . $entity->id() . '/edit', $edit, t('Save')); $translated_entity = $this->loadEntityByName($entity_type_id, $name1)->getTranslation('ro'); - $this->assertTrue($translated_entity, format_string('%entity_type: Modified translation found in the database.', array('%entity_type' => $entity_type_id))); - $this->assertEqual($translated_entity->name->value, $name2_ro, format_string('%entity_type: The name of the translation has been modified.', array('%entity_type' => $entity_type_id))); + $this->assertTrue($translated_entity, format_string('%entity_type: Modified translation found in the database.', ['%entity_type' => $entity_type_id])); + $this->assertEqual($translated_entity->name->value, $name2_ro, format_string('%entity_type: The name of the translation has been modified.', ['%entity_type' => $entity_type_id])); $this->drupalGet('ro/' . $entity_type_id . '/manage/' . $entity->id() . '/edit'); $this->clickLink(t('Delete')); - $this->drupalPostForm(NULL, array(), t('Delete Romanian translation')); + $this->drupalPostForm(NULL, [], t('Delete Romanian translation')); $entity = $this->loadEntityByName($entity_type_id, $name1); - $this->assertNotNull($entity, format_string('%entity_type: The original entity still exists.', array('%entity_type' => $entity_type_id))); - $this->assertFalse($entity->hasTranslation('ro'), format_string('%entity_type: Entity translation does not exist anymore.', array('%entity_type' => $entity_type_id))); + $this->assertNotNull($entity, format_string('%entity_type: The original entity still exists.', ['%entity_type' => $entity_type_id])); + $this->assertFalse($entity->hasTranslation('ro'), format_string('%entity_type: Entity translation does not exist anymore.', ['%entity_type' => $entity_type_id])); } /** @@ -141,7 +141,7 @@ protected function loadEntityByName($entity_type, $name) { // correctly picked up. $entity_storage = $this->container->get('entity.manager')->getStorage($entity_type); $entity_storage->resetCache(); - $entities = $entity_storage->loadByProperties(array('name' => $name)); + $entities = $entity_storage->loadByProperties(['name' => $name]); return $entities ? current($entities) : NULL; } diff --git a/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php b/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php deleted file mode 100644 index 86bc703c..00000000 --- a/core/modules/system/src/Tests/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php +++ /dev/null @@ -1,515 +0,0 @@ -drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); - } - - /** - * Checks that a selection plugin returns the expected results. - * - * @param array $selection_options - * An array of options as required by entity reference selection plugins. - * @param array $tests - * An array of tests to run. - * @param string $handler_name - * The name of the entity type selection handler being tested. - */ - protected function assertReferenceable(array $selection_options, $tests, $handler_name) { - $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options); - - foreach ($tests as $test) { - foreach ($test['arguments'] as $arguments) { - $result = call_user_func_array(array($handler, 'getReferenceableEntities'), $arguments); - $this->assertEqual($result, $test['result'], format_string('Valid result set returned by @handler.', array('@handler' => $handler_name))); - - $result = call_user_func_array(array($handler, 'countReferenceableEntities'), $arguments); - if (!empty($test['result'])) { - $bundle = key($test['result']); - $count = count($test['result'][$bundle]); - } - else { - $count = 0; - } - - $this->assertEqual($result, $count, format_string('Valid count returned by @handler.', array('@handler' => $handler_name))); - } - } - } - - /** - * Test the node-specific overrides of the entity handler. - */ - public function testNodeHandler() { - $selection_options = array( - 'target_type' => 'node', - 'handler' => 'default', - 'handler_settings' => array( - 'target_bundles' => NULL, - ), - ); - - // Build a set of test data. - // Titles contain HTML-special characters to test escaping. - $node_values = array( - 'published1' => array( - 'type' => 'article', - 'status' => NODE_PUBLISHED, - 'title' => 'Node published1 (<&>)', - 'uid' => 1, - ), - 'published2' => array( - 'type' => 'article', - 'status' => NODE_PUBLISHED, - 'title' => 'Node published2 (<&>)', - 'uid' => 1, - ), - 'unpublished' => array( - 'type' => 'article', - 'status' => NODE_NOT_PUBLISHED, - 'title' => 'Node unpublished (<&>)', - 'uid' => 1, - ), - ); - - $nodes = array(); - $node_labels = array(); - foreach ($node_values as $key => $values) { - $node = Node::create($values); - $node->save(); - $nodes[$key] = $node; - $node_labels[$key] = Html::escape($node->label()); - } - - // Test as a non-admin. - $normal_user = $this->drupalCreateUser(array('access content')); - \Drupal::currentUser()->setAccount($normal_user); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'article' => array( - $nodes['published1']->id() => $node_labels['published1'], - $nodes['published2']->id() => $node_labels['published2'], - ), - ), - ), - array( - 'arguments' => array( - array('published1', 'CONTAINS'), - array('Published1', 'CONTAINS'), - ), - 'result' => array( - 'article' => array( - $nodes['published1']->id() => $node_labels['published1'], - ), - ), - ), - array( - 'arguments' => array( - array('published2', 'CONTAINS'), - array('Published2', 'CONTAINS'), - ), - 'result' => array( - 'article' => array( - $nodes['published2']->id() => $node_labels['published2'], - ), - ), - ), - array( - 'arguments' => array( - array('invalid node', 'CONTAINS'), - ), - 'result' => array(), - ), - array( - 'arguments' => array( - array('Node unpublished', 'CONTAINS'), - ), - 'result' => array(), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler'); - - // Test as an admin. - $admin_user = $this->drupalCreateUser(array('access content', 'bypass node access')); - \Drupal::currentUser()->setAccount($admin_user); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'article' => array( - $nodes['published1']->id() => $node_labels['published1'], - $nodes['published2']->id() => $node_labels['published2'], - $nodes['unpublished']->id() => $node_labels['unpublished'], - ), - ), - ), - array( - 'arguments' => array( - array('Node unpublished', 'CONTAINS'), - ), - 'result' => array( - 'article' => array( - $nodes['unpublished']->id() => $node_labels['unpublished'], - ), - ), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)'); - } - - /** - * Test the user-specific overrides of the entity handler. - */ - public function testUserHandler() { - $selection_options = array( - 'target_type' => 'user', - 'handler' => 'default', - 'handler_settings' => array( - 'target_bundles' => NULL, - 'include_anonymous' => TRUE, - ), - ); - - // Build a set of test data. - $user_values = array( - 'anonymous' => User::load(0), - 'admin' => User::load(1), - 'non_admin' => array( - 'name' => 'non_admin <&>', - 'mail' => 'non_admin@example.com', - 'roles' => array(), - 'pass' => user_password(), - 'status' => 1, - ), - 'blocked' => array( - 'name' => 'blocked <&>', - 'mail' => 'blocked@example.com', - 'roles' => array(), - 'pass' => user_password(), - 'status' => 0, - ), - ); - - $user_values['anonymous']->name = $this->config('user.settings')->get('anonymous'); - $users = array(); - - $user_labels = array(); - foreach ($user_values as $key => $values) { - if (is_array($values)) { - $account = User::create($values); - $account->save(); - } - else { - $account = $values; - } - $users[$key] = $account; - $user_labels[$key] = Html::escape($account->getUsername()); - } - - // Test as a non-admin. - \Drupal::currentUser()->setAccount($users['non_admin']); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'user' => array( - $users['admin']->id() => $user_labels['admin'], - $users['non_admin']->id() => $user_labels['non_admin'], - ), - ), - ), - array( - 'arguments' => array( - array('non_admin', 'CONTAINS'), - array('NON_ADMIN', 'CONTAINS'), - ), - 'result' => array( - 'user' => array( - $users['non_admin']->id() => $user_labels['non_admin'], - ), - ), - ), - array( - 'arguments' => array( - array('invalid user', 'CONTAINS'), - ), - 'result' => array(), - ), - array( - 'arguments' => array( - array('blocked', 'CONTAINS'), - ), - 'result' => array(), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler'); - - \Drupal::currentUser()->setAccount($users['admin']); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'user' => array( - $users['anonymous']->id() => $user_labels['anonymous'], - $users['admin']->id() => $user_labels['admin'], - $users['non_admin']->id() => $user_labels['non_admin'], - $users['blocked']->id() => $user_labels['blocked'], - ), - ), - ), - array( - 'arguments' => array( - array('blocked', 'CONTAINS'), - ), - 'result' => array( - 'user' => array( - $users['blocked']->id() => $user_labels['blocked'], - ), - ), - ), - array( - 'arguments' => array( - array('Anonymous', 'CONTAINS'), - array('anonymous', 'CONTAINS'), - ), - 'result' => array( - 'user' => array( - $users['anonymous']->id() => $user_labels['anonymous'], - ), - ), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)'); - - // Test the 'include_anonymous' option. - $selection_options['handler_settings']['include_anonymous'] = FALSE; - $referenceable_tests = array( - array( - 'arguments' => array( - array('Anonymous', 'CONTAINS'), - array('anonymous', 'CONTAINS'), - ), - 'result' => array(), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)'); - - // Check that the Anonymous user is not included in the results when no - // label matching is done, for example when using the 'options_select' - // widget. - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL), - ), - 'result' => array( - 'user' => array( - $users['admin']->id() => $user_labels['admin'], - $users['non_admin']->id() => $user_labels['non_admin'], - $users['blocked']->id() => $user_labels['blocked'], - ), - ), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)'); - } - - /** - * Test the comment-specific overrides of the entity handler. - */ - public function testCommentHandler() { - $selection_options = array( - 'target_type' => 'comment', - 'handler' => 'default', - 'handler_settings' => array( - 'target_bundles' => NULL, - ), - ); - - // Build a set of test data. - $node_values = array( - 'published' => array( - 'type' => 'article', - 'status' => 1, - 'title' => 'Node published', - 'uid' => 1, - ), - 'unpublished' => array( - 'type' => 'article', - 'status' => 0, - 'title' => 'Node unpublished', - 'uid' => 1, - ), - ); - $nodes = array(); - foreach ($node_values as $key => $values) { - $node = Node::create($values); - $node->save(); - $nodes[$key] = $node; - } - - // Create comment field on article. - $this->addDefaultCommentField('node', 'article'); - - $comment_values = array( - 'published_published' => array( - 'entity_id' => $nodes['published']->id(), - 'entity_type' => 'node', - 'field_name' => 'comment', - 'uid' => 1, - 'cid' => NULL, - 'pid' => 0, - 'status' => CommentInterface::PUBLISHED, - 'subject' => 'Comment Published <&>', - 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ), - 'published_unpublished' => array( - 'entity_id' => $nodes['published']->id(), - 'entity_type' => 'node', - 'field_name' => 'comment', - 'uid' => 1, - 'cid' => NULL, - 'pid' => 0, - 'status' => CommentInterface::NOT_PUBLISHED, - 'subject' => 'Comment Unpublished <&>', - 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ), - 'unpublished_published' => array( - 'entity_id' => $nodes['unpublished']->id(), - 'entity_type' => 'node', - 'field_name' => 'comment', - 'uid' => 1, - 'cid' => NULL, - 'pid' => 0, - 'status' => CommentInterface::NOT_PUBLISHED, - 'subject' => 'Comment Published on Unpublished node <&>', - 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ), - ); - - $comments = array(); - $comment_labels = array(); - foreach ($comment_values as $key => $values) { - $comment = Comment::create($values); - $comment->save(); - $comments[$key] = $comment; - $comment_labels[$key] = Html::escape($comment->label()); - } - - // Test as a non-admin. - $normal_user = $this->drupalCreateUser(array('access content', 'access comments')); - \Drupal::currentUser()->setAccount($normal_user); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'comment' => array( - $comments['published_published']->cid->value => $comment_labels['published_published'], - ), - ), - ), - array( - 'arguments' => array( - array('Published', 'CONTAINS'), - ), - 'result' => array( - 'comment' => array( - $comments['published_published']->cid->value => $comment_labels['published_published'], - ), - ), - ), - array( - 'arguments' => array( - array('invalid comment', 'CONTAINS'), - ), - 'result' => array(), - ), - array( - 'arguments' => array( - array('Comment Unpublished', 'CONTAINS'), - ), - 'result' => array(), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler'); - - // Test as a comment admin. - $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments')); - \Drupal::currentUser()->setAccount($admin_user); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'comment' => array( - $comments['published_published']->cid->value => $comment_labels['published_published'], - $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'], - ), - ), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)'); - - // Test as a node and comment admin. - $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access')); - \Drupal::currentUser()->setAccount($admin_user); - $referenceable_tests = array( - array( - 'arguments' => array( - array(NULL, 'CONTAINS'), - ), - 'result' => array( - 'comment' => array( - $comments['published_published']->cid->value => $comment_labels['published_published'], - $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'], - $comments['unpublished_published']->cid->value => $comment_labels['unpublished_published'], - ), - ), - ), - ); - $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)'); - } - -} diff --git a/core/modules/system/src/Tests/Entity/EntityRevisionsTest.php b/core/modules/system/src/Tests/Entity/EntityRevisionsTest.php deleted file mode 100644 index 13847fa8..00000000 --- a/core/modules/system/src/Tests/Entity/EntityRevisionsTest.php +++ /dev/null @@ -1,161 +0,0 @@ -webUser = $this->drupalCreateUser(array( - 'administer entity_test content', - 'view test entity', - )); - $this->drupalLogin($this->webUser); - - // Enable an additional language. - ConfigurableLanguage::createFromLangcode('de')->save(); - } - - /** - * Check node revision related operations. - */ - public function testRevisions() { - - // All revisable entity variations have to have the same results. - foreach (entity_test_entity_types(ENTITY_TEST_TYPES_REVISABLE) as $entity_type) { - $this->runRevisionsTests($entity_type); - } - } - - /** - * Executes the revision tests for the given entity type. - * - * @param string $entity_type - * The entity type to run the tests with. - */ - protected function runRevisionsTests($entity_type) { - - // Create initial entity. - $entity = $this->container->get('entity_type.manager') - ->getStorage($entity_type) - ->create(array( - 'name' => 'foo', - 'user_id' => $this->webUser->id(), - )); - $entity->field_test_text->value = 'bar'; - $entity->save(); - - $names = array(); - $texts = array(); - $created = array(); - $revision_ids = array(); - - // Create three revisions. - $revision_count = 3; - for ($i = 0; $i < $revision_count; $i++) { - $legacy_revision_id = $entity->revision_id->value; - $legacy_name = $entity->name->value; - $legacy_text = $entity->field_test_text->value; - - $entity = $this->container->get('entity_type.manager') - ->getStorage($entity_type)->load($entity->id->value); - $entity->setNewRevision(TRUE); - $names[] = $entity->name->value = $this->randomMachineName(32); - $texts[] = $entity->field_test_text->value = $this->randomMachineName(32); - $created[] = $entity->created->value = time() + $i + 1; - $entity->save(); - $revision_ids[] = $entity->revision_id->value; - - // Check that the fields and properties contain new content. - $this->assertTrue($entity->revision_id->value > $legacy_revision_id, format_string('%entity_type: Revision ID changed.', array('%entity_type' => $entity_type))); - $this->assertNotEqual($entity->name->value, $legacy_name, format_string('%entity_type: Name changed.', array('%entity_type' => $entity_type))); - $this->assertNotEqual($entity->field_test_text->value, $legacy_text, format_string('%entity_type: Text changed.', array('%entity_type' => $entity_type))); - } - - for ($i = 0; $i < $revision_count; $i++) { - // Load specific revision. - $entity_revision = entity_revision_load($entity_type, $revision_ids[$i]); - - // Check if properties and fields contain the revision specific content. - $this->assertEqual($entity_revision->revision_id->value, $revision_ids[$i], format_string('%entity_type: Revision ID matches.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity_revision->name->value, $names[$i], format_string('%entity_type: Name matches.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity_revision->field_test_text->value, $texts[$i], format_string('%entity_type: Text matches.', array('%entity_type' => $entity_type))); - - // Check non-revisioned values are loaded. - $this->assertTrue(isset($entity_revision->created->value), format_string('%entity_type: Non-revisioned field is loaded.', array('%entity_type' => $entity_type))); - $this->assertEqual($entity_revision->created->value, $created[2], format_string('%entity_type: Non-revisioned field value is the same between revisions.', array('%entity_type' => $entity_type))); - } - - // Confirm the correct revision text appears in the edit form. - $entity = $this->container->get('entity_type.manager') - ->getStorage($entity_type) - ->load($entity->id->value); - $this->drupalGet($entity_type . '/manage/' . $entity->id->value . '/edit'); - $this->assertFieldById('edit-name-0-value', $entity->name->value, format_string('%entity_type: Name matches in UI.', array('%entity_type' => $entity_type))); - $this->assertFieldById('edit-field-test-text-0-value', $entity->field_test_text->value, format_string('%entity_type: Text matches in UI.', array('%entity_type' => $entity_type))); - } - - /** - * Tests that an entity revision is upcasted in the correct language. - */ - public function testEntityRevisionParamConverter() { - // Create a test entity with multiple revisions and translations for them. - $entity = EntityTestMulRev::create([ - 'name' => 'default revision - en', - 'user_id' => $this->webUser, - 'language' => 'en', - ]); - $entity->addTranslation('de', ['name' => 'default revision - de']); - $entity->save(); - - $forward_revision = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev')->loadUnchanged($entity->id()); - - $forward_revision->setNewRevision(); - $forward_revision->isDefaultRevision(FALSE); - - $forward_revision->name = 'forward revision - en'; - $forward_revision->save(); - - $forward_revision_translation = $forward_revision->getTranslation('de'); - $forward_revision_translation->name = 'forward revision - de'; - $forward_revision_translation->save(); - - // Check that the entity revision is upcasted in the correct language. - $revision_url = 'entity_test_mulrev/' . $entity->id() . '/revision/' . $forward_revision->getRevisionId() . '/view'; - - $this->drupalGet($revision_url); - $this->assertText('forward revision - en'); - $this->assertNoText('forward revision - de'); - - $this->drupalGet('de/' . $revision_url); - $this->assertText('forward revision - de'); - $this->assertNoText('forward revision - en'); - } - -} diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php index d64e0192..f5134249 100644 --- a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php +++ b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php @@ -19,7 +19,7 @@ class EntityTranslationFormTest extends WebTestBase { * * @var array */ - public static $modules = array('entity_test', 'language', 'node'); + public static $modules = ['entity_test', 'language', 'node']; protected $langcodes; @@ -29,12 +29,12 @@ protected function setUp() { \Drupal::state()->set('entity_test.translation', TRUE); // Create test languages. - $this->langcodes = array(); + $this->langcodes = []; for ($i = 0; $i < 2; ++$i) { - $language = ConfigurableLanguage::create(array( + $language = ConfigurableLanguage::create([ 'id' => 'l' . $i, 'label' => $this->randomString(), - )); + ]); $this->langcodes[$i] = $language->id(); $language->save(); } @@ -43,14 +43,14 @@ protected function setUp() { /** * Tests entity form language. */ - function testEntityFormLanguage() { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + public function testEntityFormLanguage() { + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); - $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer content types')); + $web_user = $this->drupalCreateUser(['create page content', 'edit own page content', 'administer content types']); $this->drupalLogin($web_user); // Create a node with language LanguageInterface::LANGCODE_NOT_SPECIFIED. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $this->drupalGet('node/add/page'); @@ -75,21 +75,21 @@ function testEntityFormLanguage() { // Enable language selector. $this->drupalGet('admin/structure/types/manage/page'); - $edit = array('language_configuration[language_alterable]' => TRUE, 'language_configuration[langcode]' => LanguageInterface::LANGCODE_NOT_SPECIFIED); + $edit = ['language_configuration[language_alterable]' => TRUE, 'language_configuration[langcode]' => LanguageInterface::LANGCODE_NOT_SPECIFIED]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); - $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.'); + $this->assertRaw(t('The content type %type has been updated.', ['%type' => 'Basic page']), 'Basic page content type has been updated.'); // Create a node with language. - $edit = array(); + $edit = []; $langcode = $this->langcodes[0]; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $edit['langcode[0][value]'] = $langcode; $this->drupalPostForm('node/add/page', $edit, t('Save')); - $this->assertText(t('Basic page @title has been created.', array('@title' => $edit['title[0][value]'])), 'Basic page created.'); + $this->assertText(t('Basic page @title has been created.', ['@title' => $edit['title[0][value]']]), 'Basic page created.'); // Verify that the creation message contains a link to a node. - $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'node/')); + $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']); $this->assert(isset($view_link), 'The message area contains a link to a node'); // Check to make sure the node was created. diff --git a/core/modules/system/src/Tests/Entity/EntityUnitTestBase.php b/core/modules/system/src/Tests/Entity/EntityUnitTestBase.php index 2ec64e8d..5d7dc6fd 100644 --- a/core/modules/system/src/Tests/Entity/EntityUnitTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityUnitTestBase.php @@ -34,7 +34,7 @@ abstract class EntityUnitTestBase extends KernelTestBase { * * @var array */ - protected $generatedIds = array(); + protected $generatedIds = []; /** * The state service. @@ -65,7 +65,7 @@ protected function setUp() { // Only check the modules, if the $modules property was not inherited. $rp = new \ReflectionProperty($class, 'modules'); if ($rp->class == $class) { - foreach (array_intersect(array('node', 'comment'), $class::$modules) as $module) { + foreach (array_intersect(['node', 'comment'], $class::$modules) as $module) { $this->installEntitySchema($module); } if (in_array('forum', $class::$modules, TRUE)) { @@ -82,7 +82,7 @@ protected function setUp() { $class = get_parent_class($class); } - $this->installConfig(array('field')); + $this->installConfig(['field']); } /** @@ -96,13 +96,13 @@ protected function setUp() { * @return \Drupal\user\Entity\User * The created user entity. */ - protected function createUser($values = array(), $permissions = array()) { + protected function createUser($values = [], $permissions = []) { if ($permissions) { // Create a new role and apply permissions to it. - $role = Role::create(array( + $role = Role::create([ 'id' => strtolower($this->randomMachineName(8)), 'label' => $this->randomMachineName(8), - )); + ]); $role->save(); user_role_grant_permissions($role->id(), $permissions); $values['roles'][] = $role->id(); @@ -128,7 +128,7 @@ protected function createUser($values = array(), $permissions = array()) { */ protected function reloadEntity(EntityInterface $entity) { $controller = $this->entityManager->getStorage($entity->getEntityTypeId()); - $controller->resetCache(array($entity->id())); + $controller->resetCache([$entity->id()]); return $controller->load($entity->id()); } @@ -141,7 +141,7 @@ protected function reloadEntity(EntityInterface $entity) { protected function getHooksInfo() { $key = 'entity_test.hooks'; $hooks = $this->state->get($key); - $this->state->set($key, array()); + $this->state->set($key, []); return $hooks; } @@ -152,7 +152,7 @@ protected function getHooksInfo() { * The module to install. */ protected function installModule($module) { - $this->enableModules(array($module)); + $this->enableModules([$module]); $this->refreshServices(); } @@ -163,7 +163,7 @@ protected function installModule($module) { * The module to uninstall. */ protected function uninstallModule($module) { - $this->disableModules(array($module)); + $this->disableModules([$module]); $this->refreshServices(); } diff --git a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php index f6da0a2d..74c11038 100644 --- a/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php +++ b/core/modules/system/src/Tests/Entity/EntityWithUriCacheTagsTestBase.php @@ -53,7 +53,7 @@ public function testEntityUri() { } $expected_cache_tags = Cache::mergeTags($cache_tag, $view_cache_tag); $expected_cache_tags = Cache::mergeTags($expected_cache_tags, $this->getAdditionalCacheTagsForEntity($this->entity)); - $expected_cache_tags = Cache::mergeTags($expected_cache_tags, array($render_cache_tag)); + $expected_cache_tags = Cache::mergeTags($expected_cache_tags, [$render_cache_tag]); $this->verifyRenderCache($cid, $expected_cache_tags, $redirected_cid); } diff --git a/core/modules/system/src/Tests/Entity/Update/LangcodeToAsciiUpdateFilledTest.php b/core/modules/system/src/Tests/Entity/Update/LangcodeToAsciiUpdateFilledTest.php deleted file mode 100644 index 898627c2..00000000 --- a/core/modules/system/src/Tests/Entity/Update/LangcodeToAsciiUpdateFilledTest.php +++ /dev/null @@ -1,21 +0,0 @@ -databaseDumpFiles = [ - __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz', - ]; - } - -} diff --git a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexFilledTest.php b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexFilledTest.php deleted file mode 100644 index 623e6c6c..00000000 --- a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexFilledTest.php +++ /dev/null @@ -1,20 +0,0 @@ -databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz'; - } - -} diff --git a/core/modules/system/src/Tests/FileTransfer/MockTestConnection.php b/core/modules/system/src/Tests/FileTransfer/MockTestConnection.php deleted file mode 100644 index 7e63dc78..00000000 --- a/core/modules/system/src/Tests/FileTransfer/MockTestConnection.php +++ /dev/null @@ -1,23 +0,0 @@ -commandsRun[] = $cmd; - } - - function flushCommands() { - $out = $this->commandsRun; - $this->commandsRun = array(); - return $out; - } - -} diff --git a/core/modules/system/src/Tests/FileTransfer/TestFileTransfer.php b/core/modules/system/src/Tests/FileTransfer/TestFileTransfer.php deleted file mode 100644 index eb73ebc9..00000000 --- a/core/modules/system/src/Tests/FileTransfer/TestFileTransfer.php +++ /dev/null @@ -1,65 +0,0 @@ -connection = new MockTestConnection(); - $this->connection->connectionString = 'test://' . urlencode($this->username) . ':' . urlencode($this->password) . "@$this->host:$this->port/"; - } - - function copyFileJailed($source, $destination) { - $this->connection->run("copyFile $source $destination"); - } - - protected function removeDirectoryJailed($directory) { - $this->connection->run("rmdir $directory"); - } - - function createDirectoryJailed($directory) { - $this->connection->run("mkdir $directory"); - } - - function removeFileJailed($destination) { - if (!ftp_delete($this->connection, $item)) { - throw new FileTransferException('Unable to remove to file @file.', NULL, array('@file' => $item)); - } - } - - function isDirectory($path) { - return $this->shouldIsDirectoryReturnTrue; - } - - function isFile($path) { - return FALSE; - } - - function chmodJailed($path, $mode, $recursive) { - return; - } - -} diff --git a/core/modules/system/src/Tests/Form/AlterTest.php b/core/modules/system/src/Tests/Form/AlterTest.php deleted file mode 100644 index ae307224..00000000 --- a/core/modules/system/src/Tests/Form/AlterTest.php +++ /dev/null @@ -1,39 +0,0 @@ -drupalGet('form-test/alter'); - // Ensure that the order is first by module, then for a given module, the - // id-specific one after the generic one. - $expected = array( - 'block_form_form_test_alter_form_alter() executed.', - 'form_test_form_alter() executed.', - 'form_test_form_form_test_alter_form_alter() executed.', - 'system_form_form_test_alter_form_alter() executed.', - ); - $content = preg_replace('/\s+/', ' ', Xss::filter($this->content, array())); - $this->assert(strpos($content, implode(' ', $expected)) !== FALSE, 'Form alter hooks executed in the expected order.'); - } - -} diff --git a/core/modules/system/src/Tests/Form/CheckboxTest.php b/core/modules/system/src/Tests/Form/CheckboxTest.php deleted file mode 100644 index ebeeeeae..00000000 --- a/core/modules/system/src/Tests/Form/CheckboxTest.php +++ /dev/null @@ -1,89 +0,0 @@ -getForm('\Drupal\form_test\Form\FormTestCheckboxTypeJugglingForm', $default_value, $return_value); - $form = \Drupal::service('renderer')->renderRoot($form_array); - if ($default_value === TRUE) { - $checked = TRUE; - } - elseif ($return_value === '0') { - $checked = ($default_value === '0'); - } - elseif ($return_value === '') { - $checked = ($default_value === ''); - } - elseif ($return_value === 1 || $return_value === '1') { - $checked = ($default_value === 1 || $default_value === '1'); - } - elseif ($return_value === 'foobar') { - $checked = ($default_value === 'foobar'); - } - elseif ($return_value === '1foobar') { - $checked = ($default_value === '1foobar'); - } - $checked_in_html = strpos($form, 'checked') !== FALSE; - $message = format_string('#default_value is %default_value #return_value is %return_value.', array('%default_value' => var_export($default_value, TRUE), '%return_value' => var_export($return_value, TRUE))); - $this->assertIdentical($checked, $checked_in_html, $message); - } - } - - // Ensure that $form_state->getValues() is populated correctly for a - // checkboxes group that includes a 0-indexed array of options. - $results = json_decode($this->drupalPostForm('form-test/checkboxes-zero/1', array(), 'Save')); - $this->assertIdentical($results->checkbox_off, array(0, 0, 0), 'All three in checkbox_off are zeroes: off.'); - $this->assertIdentical($results->checkbox_zero_default, array('0', 0, 0), 'The first choice is on in checkbox_zero_default'); - $this->assertIdentical($results->checkbox_string_zero_default, array('0', 0, 0), 'The first choice is on in checkbox_string_zero_default'); - $edit = array('checkbox_off[0]' => '0'); - $results = json_decode($this->drupalPostForm('form-test/checkboxes-zero/1', $edit, 'Save')); - $this->assertIdentical($results->checkbox_off, array('0', 0, 0), 'The first choice is on in checkbox_off but the rest is not'); - - // Ensure that each checkbox is rendered correctly for a checkboxes group - // that includes a 0-indexed array of options. - $this->drupalPostForm('form-test/checkboxes-zero/0', array(), 'Save'); - $checkboxes = $this->xpath('//input[@type="checkbox"]'); - - $this->assertIdentical(count($checkboxes), 9, 'Correct number of checkboxes found.'); - foreach ($checkboxes as $checkbox) { - $checked = isset($checkbox['checked']); - $name = (string) $checkbox['name']; - $this->assertIdentical($checked, $name == 'checkbox_zero_default[0]' || $name == 'checkbox_string_zero_default[0]', format_string('Checkbox %name correctly checked', array('%name' => $name))); - } - $edit = array('checkbox_off[0]' => '0'); - $this->drupalPostForm('form-test/checkboxes-zero/0', $edit, 'Save'); - $checkboxes = $this->xpath('//input[@type="checkbox"]'); - - $this->assertIdentical(count($checkboxes), 9, 'Correct number of checkboxes found.'); - foreach ($checkboxes as $checkbox) { - $checked = isset($checkbox['checked']); - $name = (string) $checkbox['name']; - $this->assertIdentical($checked, $name == 'checkbox_off[0]' || $name == 'checkbox_zero_default[0]' || $name == 'checkbox_string_zero_default[0]', format_string('Checkbox %name correctly checked', array('%name' => $name))); - } - } - -} diff --git a/core/modules/system/src/Tests/Form/ConfirmFormTest.php b/core/modules/system/src/Tests/Form/ConfirmFormTest.php deleted file mode 100644 index 312aa2ef..00000000 --- a/core/modules/system/src/Tests/Form/ConfirmFormTest.php +++ /dev/null @@ -1,86 +0,0 @@ -drupalGet('form-test/confirm-form'); - $site_name = $this->config('system.site')->get('name'); - $this->assertTitle(t('ConfirmFormTestForm::getQuestion(). | @site-name', array('@site-name' => $site_name)), 'The question was found as the page title.'); - $this->assertText(t('ConfirmFormTestForm::getDescription().'), 'The description was used.'); - $this->assertFieldByXPath('//input[@id="edit-submit"]', t('ConfirmFormTestForm::getConfirmText().'), 'The confirm text was used.'); - - // Test cancelling the form. - $this->clickLink(t('ConfirmFormTestForm::getCancelText().')); - $this->assertUrl('form-test/autocomplete', array(), "The form's cancel link was followed."); - - // Test submitting the form. - $this->drupalPostForm('form-test/confirm-form', NULL, t('ConfirmFormTestForm::getConfirmText().')); - $this->assertText('The ConfirmFormTestForm::submitForm() method was used for this form.'); - $this->assertUrl('', array(), "The form's redirect was followed."); - - // Test submitting the form with a destination. - $this->drupalPostForm('form-test/confirm-form', NULL, t('ConfirmFormTestForm::getConfirmText().'), array('query' => array('destination' => 'admin/config'))); - $this->assertUrl('admin/config', array(), "The form's redirect was not followed, the destination query string was followed."); - - // Test cancelling the form with a complex destination. - $this->drupalGet('form-test/confirm-form-array-path'); - $this->clickLink(t('ConfirmFormArrayPathTestForm::getCancelText().')); - $this->assertUrl('form-test/confirm-form', array('query' => array('destination' => 'admin/config')), "The form's complex cancel link was followed."); - } - - /** - * Tests that the confirm form does not use external destinations. - */ - public function testConfirmFormWithExternalDestination() { - $this->drupalGet('form-test/confirm-form'); - $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); - $this->drupalGet('form-test/confirm-form', array('query' => array('destination' => 'node'))); - $this->assertCancelLinkUrl(Url::fromUri('internal:/node')); - $this->drupalGet('form-test/confirm-form', array('query' => array('destination' => 'http://example.com'))); - $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); - $this->drupalGet('form-test/confirm-form', array('query' => array('destination' => ''))); - $this->assertCancelLinkUrl(Url::fromRoute('')); - // Other invalid destinations, should fall back to the form default. - $this->drupalGet('form-test/confirm-form', array('query' => array('destination' => '/http://example.com'))); - $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); - } - - /** - * Asserts that a cancel link is present pointing to the provided URL. - * - * @param \Drupal\Core\Url $url - * The url to check for. - * @param string $message - * The assert message. - * @param string $group - * The assertion group. - * - * @return bool - * Result of the assertion. - */ - public function assertCancelLinkUrl(Url $url, $message = '', $group = 'Other') { - $links = $this->xpath('//a[@href=:url]', [':url' => $url->toString()]); - $message = ($message ? $message : SafeMarkup::format('Cancel link with URL %url found.', ['%url' => $url->toString()])); - return $this->assertTrue(isset($links[0]), $message, $group); - } - -} diff --git a/core/modules/system/src/Tests/Form/ElementTest.php b/core/modules/system/src/Tests/Form/ElementTest.php deleted file mode 100644 index 0ae2edc4..00000000 --- a/core/modules/system/src/Tests/Form/ElementTest.php +++ /dev/null @@ -1,186 +0,0 @@ -drupalGet('form-test/placeholder-text'); - $expected = 'placeholder-text'; - // Test to make sure non-textarea elements have the proper placeholder text. - foreach (array('textfield', 'tel', 'url', 'password', 'email', 'number') as $type) { - $element = $this->xpath('//input[@id=:id and @placeholder=:expected]', array( - ':id' => 'edit-' . $type, - ':expected' => $expected, - )); - $this->assertTrue(!empty($element), format_string('Placeholder text placed in @type.', array('@type' => $type))); - } - - // Test to make sure textarea has the proper placeholder text. - $element = $this->xpath('//textarea[@id=:id and @placeholder=:expected]', array( - ':id' => 'edit-textarea', - ':expected' => $expected, - )); - $this->assertTrue(!empty($element), 'Placeholder text placed in textarea.'); - } - - /** - * Tests expansion of #options for #type checkboxes and radios. - */ - function testOptions() { - $this->drupalGet('form-test/checkboxes-radios'); - - // Verify that all options appear in their defined order. - foreach (array('checkbox', 'radio') as $type) { - $elements = $this->xpath('//input[@type=:type]', array(':type' => $type)); - $expected_values = array('0', 'foo', '1', 'bar', '>'); - foreach ($elements as $element) { - $expected = array_shift($expected_values); - $this->assertIdentical((string) $element['value'], $expected); - } - } - - // Verify that the choices are admin filtered as expected. - $this->assertRaw("Special Charalert('checkboxes');"); - $this->assertRaw("Special Charalert('radios');"); - $this->assertRaw('Bar - checkboxes'); - $this->assertRaw('Bar - radios'); - - // Enable customized option sub-elements. - $this->drupalGet('form-test/checkboxes-radios/customize'); - - // Verify that all options appear in their defined order, taking a custom - // #weight into account. - foreach (array('checkbox', 'radio') as $type) { - $elements = $this->xpath('//input[@type=:type]', array(':type' => $type)); - $expected_values = array('0', 'foo', 'bar', '>', '1'); - foreach ($elements as $element) { - $expected = array_shift($expected_values); - $this->assertIdentical((string) $element['value'], $expected); - } - } - // Verify that custom #description properties are output. - foreach (array('checkboxes', 'radios') as $type) { - $elements = $this->xpath('//input[@id=:id]/following-sibling::div[@class=:class]', array( - ':id' => 'edit-' . $type . '-foo', - ':class' => 'description', - )); - $this->assertTrue(count($elements), format_string('Custom %type option description found.', array( - '%type' => $type, - ))); - } - } - - /** - * Tests wrapper ids for checkboxes and radios. - */ - function testWrapperIds() { - $this->drupalGet('form-test/checkboxes-radios'); - - // Verify that wrapper id is different from element id. - foreach (array('checkboxes', 'radios') as $type) { - $element_ids = $this->xpath('//div[@id=:id]', array(':id' => 'edit-' . $type)); - $wrapper_ids = $this->xpath('//fieldset[@id=:id]', array(':id' => 'edit-' . $type . '--wrapper')); - $this->assertTrue(count($element_ids) == 1, format_string('A single element id found for type %type', array('%type' => $type))); - $this->assertTrue(count($wrapper_ids) == 1, format_string('A single wrapper id found for type %type', array('%type' => $type))); - } - } - - /** - * Tests button classes. - */ - function testButtonClasses() { - $this->drupalGet('form-test/button-class'); - // Just contains(@class, "button") won't do because then - // "button--foo" would contain "button". Instead, check - // " button ". Make sure it matches in the beginning and the end too - // by adding a space before and after. - $this->assertEqual(2, count($this->xpath('//*[contains(concat(" ", @class, " "), " button ")]'))); - $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " button--foo ")]'))); - $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " button--danger ")]'))); - } - - /** - * Tests the #group property. - */ - function testGroupElements() { - $this->drupalGet('form-test/group-details'); - $elements = $this->xpath('//div[@class="details-wrapper"]//div[@class="details-wrapper"]//label'); - $this->assertTrue(count($elements) == 1); - $this->drupalGet('form-test/group-container'); - $elements = $this->xpath('//div[@id="edit-container"]//div[@class="details-wrapper"]//label'); - $this->assertTrue(count($elements) == 1); - $this->drupalGet('form-test/group-fieldset'); - $elements = $this->xpath('//fieldset[@id="edit-fieldset"]//div[@id="edit-meta"]//label'); - $this->assertTrue(count($elements) == 1); - $this->drupalGet('form-test/group-vertical-tabs'); - $elements = $this->xpath('//div[@data-vertical-tabs-panes]//details[@id="edit-meta"]//label'); - $this->assertTrue(count($elements) == 1); - $elements = $this->xpath('//div[@data-vertical-tabs-panes]//details[@id="edit-meta-2"]//label'); - $this->assertTrue(count($elements) == 1); - } - - /** - * Tests the #required property on details and fieldset elements. - */ - public function testRequiredFieldsetsAndDetails() { - $this->drupalGet('form-test/group-details'); - $this->assertFalse($this->cssSelect('summary.form-required')); - $this->drupalGet('form-test/group-details/1'); - $this->assertTrue($this->cssSelect('summary.form-required')); - $this->drupalGet('form-test/group-fieldset'); - $this->assertFalse($this->cssSelect('span.form-required')); - $this->drupalGet('form-test/group-fieldset/1'); - $this->assertTrue($this->cssSelect('span.form-required')); - } - - /** - * Tests a form with a autocomplete setting.. - */ - public function testFormAutocomplete() { - $this->drupalGet('form-test/autocomplete'); - - $result = $this->xpath('//input[@id="edit-autocomplete-1" and contains(@data-autocomplete-path, "form-test/autocomplete-1")]'); - $this->assertEqual(count($result), 0, 'Ensure that the user does not have access to the autocompletion'); - $result = $this->xpath('//input[@id="edit-autocomplete-2" and contains(@data-autocomplete-path, "form-test/autocomplete-2/value")]'); - $this->assertEqual(count($result), 0, 'Ensure that the user does not have access to the autocompletion'); - - $user = $this->drupalCreateUser(array('access autocomplete test')); - $this->drupalLogin($user); - $this->drupalGet('form-test/autocomplete'); - - // Make sure that the autocomplete library is added. - $this->assertRaw('core/misc/autocomplete.js'); - - $result = $this->xpath('//input[@id="edit-autocomplete-1" and contains(@data-autocomplete-path, "form-test/autocomplete-1")]'); - $this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion'); - $result = $this->xpath('//input[@id="edit-autocomplete-2" and contains(@data-autocomplete-path, "form-test/autocomplete-2/value")]'); - $this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion'); - } - - /** - * Tests form element error messages. - */ - public function testFormElementErrors() { - $this->drupalPostForm('form_test/details-form', [], 'Submit'); - $this->assertText('I am an error on the details element.'); - } - -} diff --git a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php index 34a558cb..d335518a 100644 --- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php +++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php @@ -4,6 +4,7 @@ use Drupal\Core\Form\FormState; use Drupal\simpletest\WebTestBase; +use Drupal\Tests\system\Functional\Form\StubForm; /** * Tests the tableselect form element for expected behavior. @@ -17,12 +18,12 @@ class ElementsTableSelectTest extends WebTestBase { * * @var array */ - public static $modules = array('form_test'); + public static $modules = ['form_test']; /** * Test the display of checkboxes when #multiple is TRUE. */ - function testMultipleTrue() { + public function testMultipleTrue() { $this->drupalGet('form_test/tableselect/multiple-true'); @@ -31,37 +32,37 @@ function testMultipleTrue() { // Test for the presence of the Select all rows tableheader. $this->assertFieldByXPath('//th[@class="select-all"]', NULL, 'Presence of the "Select all" checkbox.'); - $rows = array('row1', 'row2', 'row3'); + $rows = ['row1', 'row2', 'row3']; foreach ($rows as $row) { - $this->assertFieldByXPath('//input[@type="checkbox"]', $row, format_string('Checkbox for value @row.', array('@row' => $row))); + $this->assertFieldByXPath('//input[@type="checkbox"]', $row, format_string('Checkbox for value @row.', ['@row' => $row])); } } /** * Test the presence of ajax functionality for all options. */ - function testAjax() { - $rows = array('row1', 'row2', 'row3'); + public function testAjax() { + $rows = ['row1', 'row2', 'row3']; // Test checkboxes (#multiple == TRUE). foreach ($rows as $row) { $element = 'tableselect[' . $row . ']'; - $edit = array($element => TRUE); + $edit = [$element => TRUE]; $result = $this->drupalPostAjaxForm('form_test/tableselect/multiple-true', $edit, $element); - $this->assertFalse(empty($result), t('Ajax triggers on checkbox for @row.', array('@row' => $row))); + $this->assertFalse(empty($result), t('Ajax triggers on checkbox for @row.', ['@row' => $row])); } // Test radios (#multiple == FALSE). $element = 'tableselect'; foreach ($rows as $row) { - $edit = array($element => $row); + $edit = [$element => $row]; $result = $this->drupalPostAjaxForm('form_test/tableselect/multiple-false', $edit, $element); - $this->assertFalse(empty($result), t('Ajax triggers on radio for @row.', array('@row' => $row))); + $this->assertFalse(empty($result), t('Ajax triggers on radio for @row.', ['@row' => $row])); } } /** * Test the display of radios when #multiple is FALSE. */ - function testMultipleFalse() { + public function testMultipleFalse() { $this->drupalGet('form_test/tableselect/multiple-false'); $this->assertNoText(t('Empty text.'), 'Empty text should not be displayed.'); @@ -69,16 +70,16 @@ function testMultipleFalse() { // Test for the absence of the Select all rows tableheader. $this->assertNoFieldByXPath('//th[@class="select-all"]', '', 'Absence of the "Select all" checkbox.'); - $rows = array('row1', 'row2', 'row3'); + $rows = ['row1', 'row2', 'row3']; foreach ($rows as $row) { - $this->assertFieldByXPath('//input[@type="radio"]', $row, format_string('Radio button for value @row.', array('@row' => $row))); + $this->assertFieldByXPath('//input[@type="radio"]', $row, format_string('Radio button for value @row.', ['@row' => $row])); } } /** * Tests the display when #colspan is set. */ - function testTableselectColSpan() { + public function testTableselectColSpan() { $this->drupalGet('form_test/tableselect/colspan'); $this->assertText(t('Three'), 'Presence of the third column'); @@ -92,8 +93,8 @@ function testTableselectColSpan() { // The first two body rows should each have 5 table cells: One for the // radio, one cell in the first column, one cell in the second column, // and two cells in the third column which has colspan 2. - for ( $i = 0; $i <= 1; $i++) { - $this->assertEqual(count($table_body[0]->tr[$i]->td), 5, format_string('There are five cells in row @row.', array('@row' => $i))); + for ($i = 0; $i <= 1; $i++) { + $this->assertEqual(count($table_body[0]->tr[$i]->td), 5, format_string('There are five cells in row @row.', ['@row' => $i])); } // The third row should have 3 cells, one for the radio, one spanning the // first and second column, and a third in column 3 (which has colspan 3). @@ -103,7 +104,7 @@ function testTableselectColSpan() { /** * Test the display of the #empty text when #options is an empty array. */ - function testEmptyText() { + public function testEmptyText() { $this->drupalGet('form_test/tableselect/empty-text'); $this->assertText(t('Empty text.'), 'Empty text should be displayed.'); } @@ -111,10 +112,10 @@ function testEmptyText() { /** * Test the submission of single and multiple values when #multiple is TRUE. */ - function testMultipleTrueSubmit() { + public function testMultipleTrueSubmit() { // Test a submission with one checkbox checked. - $edit = array(); + $edit = []; $edit['tableselect[row1]'] = TRUE; $this->drupalPostForm('form_test/tableselect/multiple-true', $edit, 'Submit'); @@ -136,7 +137,7 @@ function testMultipleTrueSubmit() { /** * Test submission of values when #multiple is FALSE. */ - function testMultipleFalseSubmit() { + public function testMultipleFalseSubmit() { $edit['tableselect'] = 'row1'; $this->drupalPostForm('form_test/tableselect/multiple-false', $edit, 'Submit'); $this->assertText(t('Submitted: row1'), 'Selected radio button'); @@ -145,7 +146,7 @@ function testMultipleFalseSubmit() { /** * Test the #js_select property. */ - function testAdvancedSelect() { + public function testAdvancedSelect() { // When #multiple = TRUE a Select all checkbox should be displayed by default. $this->drupalGet('form_test/tableselect/advanced-select/multiple-true-default'); $this->assertFieldByXPath('//th[@class="select-all"]', NULL, 'Display a "Select all" checkbox by default when #multiple is TRUE.'); @@ -166,22 +167,22 @@ function testAdvancedSelect() { /** * Test the whether the option checker gives an error on invalid tableselect values for checkboxes. */ - function testMultipleTrueOptionchecker() { + public function testMultipleTrueOptionchecker() { list($header, $options) = _form_test_tableselect_get_data(); - $form['tableselect'] = array( + $form['tableselect'] = [ '#type' => 'tableselect', '#header' => $header, '#options' => $options, - ); + ]; // Test with a valid value. - list(, , $errors) = $this->formSubmitHelper($form, array('tableselect' => array('row1' => 'row1'))); + list(, , $errors) = $this->formSubmitHelper($form, ['tableselect' => ['row1' => 'row1']]); $this->assertFalse(isset($errors['tableselect']), 'Option checker allows valid values for checkboxes.'); // Test with an invalid value. - list(, , $errors) = $this->formSubmitHelper($form, array('tableselect' => array('non_existing_value' => 'non_existing_value'))); + list(, , $errors) = $this->formSubmitHelper($form, ['tableselect' => ['non_existing_value' => 'non_existing_value']]); $this->assertTrue(isset($errors['tableselect']), 'Option checker disallows invalid values for checkboxes.'); } @@ -190,23 +191,23 @@ function testMultipleTrueOptionchecker() { /** * Test the whether the option checker gives an error on invalid tableselect values for radios. */ - function testMultipleFalseOptionchecker() { + public function testMultipleFalseOptionchecker() { list($header, $options) = _form_test_tableselect_get_data(); - $form['tableselect'] = array( + $form['tableselect'] = [ '#type' => 'tableselect', '#header' => $header, '#options' => $options, '#multiple' => FALSE, - ); + ]; // Test with a valid value. - list(, , $errors) = $this->formSubmitHelper($form, array('tableselect' => 'row1')); + list(, , $errors) = $this->formSubmitHelper($form, ['tableselect' => 'row1']); $this->assertFalse(isset($errors['tableselect']), 'Option checker allows valid values for radio buttons.'); // Test with an invalid value. - list(, , $errors) = $this->formSubmitHelper($form, array('tableselect' => 'non_existing_value')); + list(, , $errors) = $this->formSubmitHelper($form, ['tableselect' => 'non_existing_value']); $this->assertTrue(isset($errors['tableselect']), 'Option checker disallows invalid values for radio buttons.'); } @@ -226,7 +227,7 @@ private function formSubmitHelper($form, $edit) { $form_id = $this->randomMachineName(); $form_state = new FormState(); - $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); + $form['op'] = ['#type' => 'submit', '#value' => t('Submit')]; // The form token CSRF protection should not interfere with this test, so we // bypass it by setting the token to FALSE. $form['#token'] = FALSE; @@ -252,7 +253,7 @@ private function formSubmitHelper($form, $edit) { // Return the processed form together with form_state and errors // to allow the caller lowlevel access to the form. - return array($form, $form_state, $errors); + return [$form, $form_state, $errors]; } } diff --git a/core/modules/system/src/Tests/Form/ElementsVerticalTabsTest.php b/core/modules/system/src/Tests/Form/ElementsVerticalTabsTest.php deleted file mode 100644 index 2e630ccc..00000000 --- a/core/modules/system/src/Tests/Form/ElementsVerticalTabsTest.php +++ /dev/null @@ -1,89 +0,0 @@ -adminUser = $this->drupalCreateUser(array('access vertical_tab_test tabs')); - $this->webUser = $this->drupalCreateUser(); - $this->drupalLogin($this->adminUser); - } - - /** - * Ensures that vertical-tabs.js is included before collapse.js. - * - * Otherwise, collapse.js adds "SHOW" or "HIDE" labels to the tabs. - */ - function testJavaScriptOrdering() { - $this->drupalGet('form_test/vertical-tabs'); - $position1 = strpos($this->content, 'core/misc/vertical-tabs.js'); - $position2 = strpos($this->content, 'core/misc/collapse.js'); - $this->assertTrue($position1 !== FALSE && $position2 !== FALSE && $position1 < $position2, 'vertical-tabs.js is included before collapse.js'); - } - - /** - * Ensures that vertical tab markup is not shown if user has no tab access. - */ - function testWrapperNotShownWhenEmpty() { - // Test admin user can see vertical tabs and wrapper. - $this->drupalGet('form_test/vertical-tabs'); - $wrapper = $this->xpath("//div[@data-vertical-tabs-panes]"); - $this->assertTrue(isset($wrapper[0]), 'Vertical tab panes found.'); - - // Test wrapper markup not present for non-privileged web user. - $this->drupalLogin($this->webUser); - $this->drupalGet('form_test/vertical-tabs'); - $wrapper = $this->xpath("//div[@data-vertical-tabs-panes]"); - $this->assertFalse(isset($wrapper[0]), 'Vertical tab wrappers are not displayed to unprivileged users.'); - } - - /** - * Ensures that default vertical tab is correctly selected. - */ - function testDefaultTab() { - $this->drupalGet('form_test/vertical-tabs'); - $this->assertFieldByName('vertical_tabs__active_tab', 'edit-tab3', t('The default vertical tab is correctly selected.')); - } - - /** - * Ensures that vertical tab form values are cleaned. - */ - function testDefaultTabCleaned() { - $values = Json::decode($this->drupalPostForm('form_test/form-state-values-clean', [], t('Submit'))); - $this->assertFalse(isset($values['vertical_tabs__active_tab']), SafeMarkup::format('%element was removed.', ['%element' => 'vertical_tabs__active_tab'])); - } - -} diff --git a/core/modules/system/src/Tests/Form/EmailTest.php b/core/modules/system/src/Tests/Form/EmailTest.php deleted file mode 100644 index e53247f3..00000000 --- a/core/modules/system/src/Tests/Form/EmailTest.php +++ /dev/null @@ -1,49 +0,0 @@ -drupalPostForm('form-test/email', $edit, 'Submit'); - $this->assertRaw(t('The email address %mail is not valid.', array('%mail' => 'invalid'))); - $this->assertRaw(t('@name field is required.', array('@name' => 'Address'))); - - $edit = array(); - $edit['email_required'] = ' foo.bar@example.com '; - $values = Json::decode($this->drupalPostForm('form-test/email', $edit, 'Submit')); - $this->assertIdentical($values['email'], ''); - $this->assertEqual($values['email_required'], 'foo.bar@example.com'); - - $edit = array(); - $edit['email'] = 'foo@example.com'; - $edit['email_required'] = 'example@drupal.org'; - $values = Json::decode($this->drupalPostForm('form-test/email', $edit, 'Submit')); - $this->assertEqual($values['email'], 'foo@example.com'); - $this->assertEqual($values['email_required'], 'example@drupal.org'); - } - -} diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php deleted file mode 100644 index cf738369..00000000 --- a/core/modules/system/src/Tests/Form/FormTest.php +++ /dev/null @@ -1,749 +0,0 @@ - 'filtered_html', - 'name' => 'Filtered HTML', - )); - $filtered_html_format->save(); - - $filtered_html_permission = $filtered_html_format->getPermissionName(); - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array($filtered_html_permission)); - } - - /** - * Check several empty values for required forms elements. - * - * Carriage returns, tabs, spaces, and unchecked checkbox elements are not - * valid content for a required field. - * - * If the form field is found in $form_state->getErrors() then the test pass. - */ - function testRequiredFields() { - // Originates from https://www.drupal.org/node/117748. - // Sets of empty strings and arrays. - $empty_strings = array('""' => "", '"\n"' => "\n", '" "' => " ", '"\t"' => "\t", '" \n\t "' => " \n\t ", '"\n\n\n\n\n"' => "\n\n\n\n\n"); - $empty_arrays = array('array()' => array()); - $empty_checkbox = array(NULL); - - $elements['textfield']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'textfield'); - $elements['textfield']['empty_values'] = $empty_strings; - - $elements['telephone']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'tel'); - $elements['telephone']['empty_values'] = $empty_strings; - - $elements['url']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'url'); - $elements['url']['empty_values'] = $empty_strings; - - $elements['search']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'search'); - $elements['search']['empty_values'] = $empty_strings; - - $elements['password']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'password'); - $elements['password']['empty_values'] = $empty_strings; - - $elements['password_confirm']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'password_confirm'); - // Provide empty values for both password fields. - foreach ($empty_strings as $key => $value) { - $elements['password_confirm']['empty_values'][$key] = array('pass1' => $value, 'pass2' => $value); - } - - $elements['textarea']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'textarea'); - $elements['textarea']['empty_values'] = $empty_strings; - - $elements['radios']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'radios', '#options' => array('' => t('None'), $this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName())); - $elements['radios']['empty_values'] = $empty_arrays; - - $elements['checkbox']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'checkbox', '#required' => TRUE); - $elements['checkbox']['empty_values'] = $empty_checkbox; - - $elements['checkboxes']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'checkboxes', '#options' => array($this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName())); - $elements['checkboxes']['empty_values'] = $empty_arrays; - - $elements['select']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'select', '#options' => array('' => t('None'), $this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName())); - $elements['select']['empty_values'] = $empty_strings; - - $elements['file']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'file'); - $elements['file']['empty_values'] = $empty_strings; - - // Regular expression to find the expected marker on required elements. - $required_marker_preg = '@<.*?class=".*?js-form-required.*form-required.*?">@'; - // Go through all the elements and all the empty values for them. - foreach ($elements as $type => $data) { - foreach ($data['empty_values'] as $key => $empty) { - foreach (array(TRUE, FALSE) as $required) { - $form_id = $this->randomMachineName(); - $form = array(); - $form_state = new FormState(); - $form['op'] = array('#type' => 'submit', '#value' => t('Submit')); - $element = $data['element']['#title']; - $form[$element] = $data['element']; - $form[$element]['#required'] = $required; - $user_input[$element] = $empty; - $user_input['form_id'] = $form_id; - $form_state->setUserInput($user_input); - $form_state->setFormObject(new StubForm($form_id, $form)); - $form_state->setMethod('POST'); - // The form token CSRF protection should not interfere with this test, - // so we bypass it by setting the token to FALSE. - $form['#token'] = FALSE; - \Drupal::formBuilder()->prepareForm($form_id, $form, $form_state); - \Drupal::formBuilder()->processForm($form_id, $form, $form_state); - $errors = $form_state->getErrors(); - // Form elements of type 'radios' throw all sorts of PHP notices - // when you try to render them like this, so we ignore those for - // testing the required marker. - // @todo Fix this work-around (https://www.drupal.org/node/588438). - $form_output = ($type == 'radios') ? '' : \Drupal::service('renderer')->renderRoot($form); - if ($required) { - // Make sure we have a form error for this element. - $this->assertTrue(isset($errors[$element]), "Check empty($key) '$type' field '$element'"); - if (!empty($form_output)) { - // Make sure the form element is marked as required. - $this->assertTrue(preg_match($required_marker_preg, $form_output), "Required '$type' field is marked as required"); - } - } - else { - if (!empty($form_output)) { - // Make sure the form element is *not* marked as required. - $this->assertFalse(preg_match($required_marker_preg, $form_output), "Optional '$type' field is not marked as required"); - } - if ($type == 'select') { - // Select elements are going to have validation errors with empty - // input, since those are illegal choices. Just make sure the - // error is not "field is required". - $this->assertTrue((empty($errors[$element]) || strpos('field is required', (string) $errors[$element]) === FALSE), "Optional '$type' field '$element' is not treated as a required element"); - } - else { - // Make sure there is *no* form error for this element. - $this->assertTrue(empty($errors[$element]), "Optional '$type' field '$element' has no errors with empty input"); - } - } - } - } - } - // Clear the expected form error messages so they don't appear as exceptions. - drupal_get_messages(); - } - - /** - * Tests validation for required checkbox, select, and radio elements. - * - * Submits a test form containing several types of form elements. The form - * is submitted twice, first without values for required fields and then - * with values. Each submission is checked for relevant error messages. - * - * @see \Drupal\form_test\Form\FormTestValidateRequiredForm - */ - function testRequiredCheckboxesRadio() { - $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestValidateRequiredForm'); - - // Attempt to submit the form with no required fields set. - $edit = array(); - $this->drupalPostForm('form-test/validate-required', $edit, 'Submit'); - - // The only error messages that should appear are the relevant 'required' - // messages for each field. - $expected = array(); - foreach (array('textfield', 'checkboxes', 'select', 'radios') as $key) { - if (isset($form[$key]['#required_error'])) { - $expected[] = $form[$key]['#required_error']; - } - elseif (isset($form[$key]['#form_test_required_error'])) { - $expected[] = $form[$key]['#form_test_required_error']; - } - else { - $expected[] = t('@name field is required.', array('@name' => $form[$key]['#title'])); - } - } - - // Check the page for error messages. - $errors = $this->xpath('//div[contains(@class, "error")]//li'); - foreach ($errors as $error) { - $expected_key = array_search($error[0], $expected); - // If the error message is not one of the expected messages, fail. - if ($expected_key === FALSE) { - $this->fail(format_string("Unexpected error message: @error", array('@error' => $error[0]))); - } - // Remove the expected message from the list once it is found. - else { - unset($expected[$expected_key]); - } - } - - // Fail if any expected messages were not found. - foreach ($expected as $not_found) { - $this->fail(format_string("Found error message: @error", array('@error' => $not_found))); - } - - // Verify that input elements are still empty. - $this->assertFieldByName('textfield', ''); - $this->assertNoFieldChecked('edit-checkboxes-foo'); - $this->assertNoFieldChecked('edit-checkboxes-bar'); - $this->assertOptionSelected('edit-select', ''); - $this->assertNoFieldChecked('edit-radios-foo'); - $this->assertNoFieldChecked('edit-radios-bar'); - $this->assertNoFieldChecked('edit-radios-optional-foo'); - $this->assertNoFieldChecked('edit-radios-optional-bar'); - $this->assertNoFieldChecked('edit-radios-optional-default-value-false-foo'); - $this->assertNoFieldChecked('edit-radios-optional-default-value-false-bar'); - - // Submit again with required fields set and verify that there are no - // error messages. - $edit = array( - 'textfield' => $this->randomString(), - 'checkboxes[foo]' => TRUE, - 'select' => 'foo', - 'radios' => 'bar', - ); - $this->drupalPostForm(NULL, $edit, 'Submit'); - $this->assertNoFieldByXpath('//div[contains(@class, "error")]', FALSE, 'No error message is displayed when all required fields are filled.'); - $this->assertRaw("The form_test_validate_required_form form was submitted successfully.", 'Validation form submitted successfully.'); - } - - /** - * Tests that input is retained for safe elements even with an invalid token. - * - * Submits a test form containing several types of form elements. - */ - public function testInputWithInvalidToken() { - // We need to be logged in to have CSRF tokens. - $account = $this->createUser(); - $this->drupalLogin($account); - // Submit again with required fields set but an invalid form token and - // verify that all the values are retained. - $edit = array( - 'textfield' => $this->randomString(), - 'checkboxes[bar]' => TRUE, - 'select' => 'bar', - 'radios' => 'foo', - 'form_token' => 'invalid token', - ); - $this->drupalPostForm(Url::fromRoute('form_test.validate_required'), $edit, 'Submit'); - $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - // Verify that input elements retained the posted values. - $this->assertFieldByName('textfield', $edit['textfield']); - $this->assertNoFieldChecked('edit-checkboxes-foo'); - $this->assertFieldChecked('edit-checkboxes-bar'); - $this->assertOptionSelected('edit-select', 'bar'); - $this->assertFieldChecked('edit-radios-foo'); - - // Check another form that has a textarea input. - $edit = array( - 'textfield' => $this->randomString(), - 'textarea' => $this->randomString() . "\n", - 'form_token' => 'invalid token', - ); - $this->drupalPostForm(Url::fromRoute('form_test.required'), $edit, 'Submit'); - $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - $this->assertFieldByName('textfield', $edit['textfield']); - $this->assertFieldByName('textarea', $edit['textarea']); - - // Check another form that has a number input. - $edit = array( - 'integer_step' => mt_rand(1, 100), - 'form_token' => 'invalid token', - ); - $this->drupalPostForm(Url::fromRoute('form_test.number'), $edit, 'Submit'); - $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - $this->assertFieldByName('integer_step', $edit['integer_step']); - - // Check a form with a Url field - $edit = array( - 'url' => $this->randomString(), - 'form_token' => 'invalid token', - ); - $this->drupalPostForm(Url::fromRoute('form_test.url'), $edit, 'Submit'); - $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - $this->assertFieldByName('url', $edit['url']); - } - - /** - * CSRF tokens for GET forms should not be added by default. - */ - public function testGetFormsCsrfToken() { - // We need to be logged in to have CSRF tokens. - $account = $this->createUser(); - $this->drupalLogin($account); - - $this->drupalGet(Url::fromRoute('form_test.get_form')); - $this->assertNoRaw('form_token'); - } - - /** - * Tests validation for required textfield element without title. - * - * Submits a test form containing a textfield form element without title. - * The form is submitted twice, first without value for the required field - * and then with value. Each submission is checked for relevant error - * messages. - * - * @see \Drupal\form_test\Form\FormTestValidateRequiredNoTitleForm - */ - function testRequiredTextfieldNoTitle() { - // Attempt to submit the form with no required field set. - $edit = array(); - $this->drupalPostForm('form-test/validate-required-no-title', $edit, 'Submit'); - $this->assertNoRaw("The form_test_validate_required_form_no_title form was submitted successfully.", 'Validation form submitted successfully.'); - - // Check the page for the error class on the textfield. - $this->assertFieldByXPath('//input[contains(@class, "error")]', FALSE, 'Error input form element class found.'); - - // Check the page for the aria-invalid attribute on the textfield. - $this->assertFieldByXPath('//input[contains(@aria-invalid, "true")]', FALSE, 'Aria invalid attribute found.'); - - // Submit again with required fields set and verify that there are no - // error messages. - $edit = array( - 'textfield' => $this->randomString(), - ); - $this->drupalPostForm(NULL, $edit, 'Submit'); - $this->assertNoFieldByXpath('//input[contains(@class, "error")]', FALSE, 'No error input form element class found.'); - $this->assertRaw("The form_test_validate_required_form_no_title form was submitted successfully.", 'Validation form submitted successfully.'); - } - - /** - * Test default value handling for checkboxes. - * - * @see _form_test_checkbox() - */ - function testCheckboxProcessing() { - // First, try to submit without the required checkbox. - $edit = array(); - $this->drupalPostForm('form-test/checkbox', $edit, t('Submit')); - $this->assertRaw(t('@name field is required.', array('@name' => 'required_checkbox')), 'A required checkbox is actually mandatory'); - - // Now try to submit the form correctly. - $values = Json::decode($this->drupalPostForm(NULL, array('required_checkbox' => 1), t('Submit'))); - $expected_values = array( - 'disabled_checkbox_on' => 'disabled_checkbox_on', - 'disabled_checkbox_off' => '', - 'checkbox_on' => 'checkbox_on', - 'checkbox_off' => '', - 'zero_checkbox_on' => '0', - 'zero_checkbox_off' => '', - ); - foreach ($expected_values as $widget => $expected_value) { - $this->assertEqual($values[$widget], $expected_value, format_string('Checkbox %widget returns expected value (expected: %expected, got: %value)', array( - '%widget' => var_export($widget, TRUE), - '%expected' => var_export($expected_value, TRUE), - '%value' => var_export($values[$widget], TRUE), - ))); - } - } - - /** - * Tests validation of #type 'select' elements. - */ - function testSelect() { - $form = \Drupal::formBuilder()->getForm('Drupal\form_test\Form\FormTestSelectForm'); - $this->drupalGet('form-test/select'); - - // Verify that the options are escaped as expected. - $this->assertEscaped('four'); - $this->assertNoRaw('four'); - - // Posting without any values should throw validation errors. - $this->drupalPostForm(NULL, array(), 'Submit'); - $no_errors = array( - 'select', - 'select_required', - 'select_optional', - 'empty_value', - 'empty_value_one', - 'no_default_optional', - 'no_default_empty_option_optional', - 'no_default_empty_value_optional', - 'multiple', - 'multiple_no_default', - ); - foreach ($no_errors as $key) { - $this->assertNoText(t('@name field is required.', array('@name' => $form[$key]['#title']))); - } - - $expected_errors = array( - 'no_default', - 'no_default_empty_option', - 'no_default_empty_value', - 'no_default_empty_value_one', - 'multiple_no_default_required', - ); - foreach ($expected_errors as $key) { - $this->assertText(t('@name field is required.', array('@name' => $form[$key]['#title']))); - } - - // Post values for required fields. - $edit = array( - 'no_default' => 'three', - 'no_default_empty_option' => 'three', - 'no_default_empty_value' => 'three', - 'no_default_empty_value_one' => 'three', - 'multiple_no_default_required[]' => 'three', - ); - $this->drupalPostForm(NULL, $edit, 'Submit'); - $values = Json::decode($this->getRawContent()); - - // Verify expected values. - $expected = array( - 'select' => 'one', - 'empty_value' => 'one', - 'empty_value_one' => 'one', - 'no_default' => 'three', - 'no_default_optional' => 'one', - 'no_default_optional_empty_value' => '', - 'no_default_empty_option' => 'three', - 'no_default_empty_option_optional' => '', - 'no_default_empty_value' => 'three', - 'no_default_empty_value_one' => 'three', - 'no_default_empty_value_optional' => 0, - 'multiple' => array('two' => 'two'), - 'multiple_no_default' => array(), - 'multiple_no_default_required' => array('three' => 'three'), - ); - foreach ($expected as $key => $value) { - $this->assertIdentical($values[$key], $value, format_string('@name: @actual is equal to @expected.', array( - '@name' => $key, - '@actual' => var_export($values[$key], TRUE), - '@expected' => var_export($value, TRUE), - ))); - } - } - - /** - * Tests a select element when #options is not set. - */ - function testEmptySelect() { - $this->drupalGet('form-test/empty-select'); - $this->assertFieldByXPath("//select[1]", NULL, 'Select element found.'); - $this->assertNoFieldByXPath("//select[1]/option", NULL, 'No option element found.'); - } - - /** - * Tests validation of #type 'number' and 'range' elements. - */ - function testNumber() { - $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestNumberForm'); - - // Array with all the error messages to be checked. - $error_messages = array( - 'no_number' => '%name must be a number.', - 'too_low' => '%name must be higher than or equal to %min.', - 'too_high' => '%name must be lower than or equal to %max.', - 'step_mismatch' => '%name is not a valid number.', - ); - - // The expected errors. - $expected = array( - 'integer_no_number' => 'no_number', - 'integer_no_step' => 0, - 'integer_no_step_step_error' => 'step_mismatch', - 'integer_step' => 0, - 'integer_step_error' => 'step_mismatch', - 'integer_step_min' => 0, - 'integer_step_min_error' => 'too_low', - 'integer_step_max' => 0, - 'integer_step_max_error' => 'too_high', - 'integer_step_min_border' => 0, - 'integer_step_max_border' => 0, - 'integer_step_based_on_min' => 0, - 'integer_step_based_on_min_error' => 'step_mismatch', - 'float_small_step' => 0, - 'float_step_no_error' => 0, - 'float_step_error' => 'step_mismatch', - 'float_step_hard_no_error' => 0, - 'float_step_hard_error' => 'step_mismatch', - 'float_step_any_no_error' => 0, - ); - - // First test the number element type, then range. - foreach (array('form-test/number', 'form-test/number/range') as $path) { - // Post form and show errors. - $this->drupalPostForm($path, array(), 'Submit'); - - foreach ($expected as $element => $error) { - // Create placeholder array. - $placeholders = array( - '%name' => $form[$element]['#title'], - '%min' => isset($form[$element]['#min']) ? $form[$element]['#min'] : '0', - '%max' => isset($form[$element]['#max']) ? $form[$element]['#max'] : '0', - ); - - foreach ($error_messages as $id => $message) { - // Check if the error exists on the page, if the current message ID is - // expected. Otherwise ensure that the error message is not present. - if ($id === $error) { - $this->assertRaw(format_string($message, $placeholders)); - } - else { - $this->assertNoRaw(format_string($message, $placeholders)); - } - } - } - } - } - - /** - * Tests default value handling of #type 'range' elements. - */ - function testRange() { - $values = json_decode($this->drupalPostForm('form-test/range', array(), 'Submit')); - $this->assertEqual($values->with_default_value, 18); - $this->assertEqual($values->float, 10.5); - $this->assertEqual($values->integer, 6); - $this->assertEqual($values->offset, 6.9); - - $this->drupalPostForm('form-test/range/invalid', array(), 'Submit'); - $this->assertFieldByXPath('//input[@type="range" and contains(@class, "error")]', NULL, 'Range element has the error class.'); - } - - /** - * Tests validation of #type 'color' elements. - */ - function testColorValidation() { - // Keys are inputs, values are expected results. - $values = array( - '' => '#000000', - '#000' => '#000000', - 'AAA' => '#aaaaaa', - '#af0DEE' => '#af0dee', - '#99ccBc' => '#99ccbc', - '#aabbcc' => '#aabbcc', - '123456' => '#123456', - ); - - // Tests that valid values are properly normalized. - foreach ($values as $input => $expected) { - $edit = array( - 'color' => $input, - ); - $result = json_decode($this->drupalPostForm('form-test/color', $edit, 'Submit')); - $this->assertEqual($result->color, $expected); - } - - // Tests invalid values are rejected. - $values = array('#0008', '#1234', '#fffffg', '#abcdef22', '17', '#uaa'); - foreach ($values as $input) { - $edit = array( - 'color' => $input, - ); - $this->drupalPostForm('form-test/color', $edit, 'Submit'); - $this->assertRaw(t('%name must be a valid color.', array('%name' => 'Color'))); - } - } - - /** - * Test handling of disabled elements. - * - * @see _form_test_disabled_elements() - */ - function testDisabledElements() { - // Get the raw form in its original state. - $form_state = new FormState(); - $form = (new FormTestDisabledElementsForm())->buildForm(array(), $form_state); - - // Build a submission that tries to hijack the form by submitting input for - // elements that are disabled. - $edit = array(); - foreach (Element::children($form) as $key) { - if (isset($form[$key]['#test_hijack_value'])) { - if (is_array($form[$key]['#test_hijack_value'])) { - foreach ($form[$key]['#test_hijack_value'] as $subkey => $value) { - $edit[$key . '[' . $subkey . ']'] = $value; - } - } - else { - $edit[$key] = $form[$key]['#test_hijack_value']; - } - } - } - - // Submit the form with no input, as the browser does for disabled elements, - // and fetch the $form_state->getValues() that is passed to the submit handler. - $this->drupalPostForm('form-test/disabled-elements', array(), t('Submit')); - $returned_values['normal'] = Json::decode($this->content); - - // Do the same with input, as could happen if JavaScript un-disables an - // element. drupalPostForm() emulates a browser by not submitting input for - // disabled elements, so we need to un-disable those elements first. - $this->drupalGet('form-test/disabled-elements'); - $disabled_elements = array(); - foreach ($this->xpath('//*[@disabled]') as $element) { - $disabled_elements[] = (string) $element['name']; - unset($element['disabled']); - } - - // All the elements should be marked as disabled, including the ones below - // the disabled container. - $actual_count = count($disabled_elements); - $expected_count = 42; - $this->assertEqual($actual_count, $expected_count, SafeMarkup::format('Found @actual elements with disabled property (expected @expected).', array( - '@actual' => count($disabled_elements), - '@expected' => $expected_count, - ))); - - $this->drupalPostForm(NULL, $edit, t('Submit')); - $returned_values['hijacked'] = Json::decode($this->content); - - // Ensure that the returned values match the form's default values in both - // cases. - foreach ($returned_values as $values) { - $this->assertFormValuesDefault($values, $form); - } - } - - /** - * Assert that the values submitted to a form matches the default values of the elements. - */ - function assertFormValuesDefault($values, $form) { - foreach (Element::children($form) as $key) { - if (isset($form[$key]['#default_value'])) { - if (isset($form[$key]['#expected_value'])) { - $expected_value = $form[$key]['#expected_value']; - } - else { - $expected_value = $form[$key]['#default_value']; - } - - if ($key == 'checkboxes_multiple') { - // Checkboxes values are not filtered out. - $values[$key] = array_filter($values[$key]); - } - $this->assertIdentical($expected_value, $values[$key], format_string('Default value for %type: expected %expected, returned %returned.', array('%type' => $key, '%expected' => var_export($expected_value, TRUE), '%returned' => var_export($values[$key], TRUE)))); - } - - // Recurse children. - $this->assertFormValuesDefault($values, $form[$key]); - } - } - - /** - * Verify markup for disabled form elements. - * - * @see _form_test_disabled_elements() - */ - function testDisabledMarkup() { - $this->drupalGet('form-test/disabled-elements'); - $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestDisabledElementsForm'); - $type_map = array( - 'textarea' => 'textarea', - 'select' => 'select', - 'weight' => 'select', - 'datetime' => 'datetime', - ); - - foreach ($form as $name => $item) { - // Skip special #types. - if (!isset($item['#type']) || in_array($item['#type'], array('hidden', 'text_format'))) { - continue; - } - // Setup XPath and CSS class depending on #type. - if (in_array($item['#type'], array('button', 'submit'))) { - $path = "//!type[contains(@class, :div-class) and @value=:value]"; - $class = 'is-disabled'; - } - elseif (in_array($item['#type'], array('image_button'))) { - $path = "//!type[contains(@class, :div-class) and @value=:value]"; - $class = 'is-disabled'; - } - else { - // starts-with() required for checkboxes. - $path = "//div[contains(@class, :div-class)]/descendant::!type[starts-with(@name, :name)]"; - $class = 'form-disabled'; - } - // Replace DOM element name in $path according to #type. - $type = 'input'; - if (isset($type_map[$item['#type']])) { - $type = $type_map[$item['#type']]; - } - $path = strtr($path, array('!type' => $type)); - // Verify that the element exists. - $element = $this->xpath($path, array( - ':name' => Html::escape($name), - ':div-class' => $class, - ':value' => isset($item['#value']) ? $item['#value'] : '', - )); - $this->assertTrue(isset($element[0]), format_string('Disabled form element class found for #type %type.', array('%type' => $item['#type']))); - } - - // Verify special element #type text-format. - $element = $this->xpath('//div[contains(@class, :div-class)]/descendant::textarea[@name=:name]', array( - ':name' => 'text_format[value]', - ':div-class' => 'form-disabled', - )); - $this->assertTrue(isset($element[0]), format_string('Disabled form element class found for #type %type.', array('%type' => 'text_format[value]'))); - $element = $this->xpath('//div[contains(@class, :div-class)]/descendant::select[@name=:name]', array( - ':name' => 'text_format[format]', - ':div-class' => 'form-disabled', - )); - $this->assertTrue(isset($element[0]), format_string('Disabled form element class found for #type %type.', array('%type' => 'text_format[format]'))); - } - - /** - * Test Form API protections against input forgery. - * - * @see _form_test_input_forgery() - */ - function testInputForgery() { - $this->drupalGet('form-test/input-forgery'); - $checkbox = $this->xpath('//input[@name="checkboxes[two]"]'); - $checkbox[0]['value'] = 'FORGERY'; - $this->drupalPostForm(NULL, array('checkboxes[one]' => TRUE, 'checkboxes[two]' => TRUE), t('Submit')); - $this->assertText('An illegal choice has been detected.', 'Input forgery was detected.'); - } - - /** - * Tests required attribute. - */ - function testRequiredAttribute() { - $this->drupalGet('form-test/required-attribute'); - $expected = 'required'; - // Test to make sure the elements have the proper required attribute. - foreach (array('textfield', 'password') as $type) { - $element = $this->xpath('//input[@id=:id and @required=:expected]', array( - ':id' => 'edit-' . $type, - ':expected' => $expected, - )); - $this->assertTrue(!empty($element), format_string('The @type has the proper required attribute.', array('@type' => $type))); - } - - // Test to make sure textarea has the proper required attribute. - $element = $this->xpath('//textarea[@id=:id and @required=:expected]', array( - ':id' => 'edit-textarea', - ':expected' => $expected, - )); - $this->assertTrue(!empty($element), 'The textarea has the proper required attribute.'); - } - -} diff --git a/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php b/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php deleted file mode 100644 index 7b3d73cb..00000000 --- a/core/modules/system/src/Tests/Form/LanguageSelectElementTest.php +++ /dev/null @@ -1,117 +0,0 @@ - 'aaa', - 'label' => $this->randomMachineName(), - ))->save(); - - ConfigurableLanguage::create(array( - 'id' => 'bbb', - 'label' => $this->randomMachineName(), - ))->save(); - - \Drupal::languageManager()->reset(); - - $this->drupalGet('form-test/language_select'); - // Check that the language fields were rendered on the page. - $ids = array( - 'edit-languages-all' => LanguageInterface::STATE_ALL, - 'edit-languages-configurable' => LanguageInterface::STATE_CONFIGURABLE, - 'edit-languages-locked' => LanguageInterface::STATE_LOCKED, - 'edit-languages-config-and-locked' => LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_LOCKED - ); - foreach ($ids as $id => $flags) { - $this->assertField($id, format_string('The @id field was found on the page.', array('@id' => $id))); - $options = array(); - /* @var $language_manager \Drupal\Core\Language\LanguageManagerInterface */ - $language_manager = $this->container->get('language_manager'); - foreach ($language_manager->getLanguages($flags) as $langcode => $language) { - $options[$langcode] = $language->isLocked() ? t('- @name -', array('@name' => $language->getName())) : $language->getName(); - } - $this->_testLanguageSelectElementOptions($id, $options); - } - - // Test that the #options were not altered by #languages. - $this->assertField('edit-language-custom-options', format_string('The @id field was found on the page.', array('@id' => 'edit-language-custom-options'))); - $this->_testLanguageSelectElementOptions('edit-language-custom-options', array('opt1' => 'First option', 'opt2' => 'Second option', 'opt3' => 'Third option')); - } - - /** - * Tests the case when the language select elements should not be printed. - * - * This happens when the language module is disabled. - */ - function testHiddenLanguageSelectElement() { - // Disable the language module, so that the language select field will not - // be rendered. - $this->container->get('module_installer')->uninstall(array('language')); - $this->drupalGet('form-test/language_select'); - // Check that the language fields were rendered on the page. - $ids = array('edit-languages-all', 'edit-languages-configurable', 'edit-languages-locked', 'edit-languages-config-and-locked'); - foreach ($ids as $id) { - $this->assertNoField($id, format_string('The @id field was not found on the page.', array('@id' => $id))); - } - - // Check that the submitted values were the default values of the language - // field elements. - $edit = array(); - $this->drupalPostForm(NULL, $edit, t('Submit')); - $values = Json::decode($this->getRawContent()); - $this->assertEqual($values['languages_all'], 'xx'); - $this->assertEqual($values['languages_configurable'], 'en'); - $this->assertEqual($values['languages_locked'], LanguageInterface::LANGCODE_NOT_SPECIFIED); - $this->assertEqual($values['languages_config_and_locked'], 'dummy_value'); - $this->assertEqual($values['language_custom_options'], 'opt2'); - } - - /** - * Helper function to check the options of a language select form element. - * - * @param string $id - * The id of the language select element to check. - * - * @param array $options - * An array with options to compare with. - */ - protected function _testLanguageSelectElementOptions($id, $options) { - // Check that the options in the language field are exactly the same, - // including the order, as the languages sent as a parameter. - $elements = $this->xpath("//select[@id='" . $id . "']"); - $count = 0; - foreach ($elements[0]->option as $option) { - $count++; - $option_title = current($options); - $this->assertEqual((string) $option, $option_title); - next($options); - } - $this->assertEqual($count, count($options), format_string('The number of languages and the number of options shown by the language element are the same: @languages languages, @number options', array('@languages' => count($options), '@number' => $count))); - } - -} diff --git a/core/modules/system/src/Tests/Form/ProgrammaticTest.php b/core/modules/system/src/Tests/Form/ProgrammaticTest.php deleted file mode 100644 index 5fbefb5e..00000000 --- a/core/modules/system/src/Tests/Form/ProgrammaticTest.php +++ /dev/null @@ -1,119 +0,0 @@ -submitForm(array(), FALSE); - $this->submitForm(array('textfield' => 'test 1'), TRUE); - $this->submitForm(array(), FALSE); - $this->submitForm(array('textfield' => 'test 2'), TRUE); - - // Test that a programmatic form submission can turn on and off checkboxes - // which are, by default, checked. - $this->submitForm(array('textfield' => 'dummy value', 'checkboxes' => array(1 => 1, 2 => 2)), TRUE); - $this->submitForm(array('textfield' => 'dummy value', 'checkboxes' => array(1 => 1, 2 => NULL)), TRUE); - $this->submitForm(array('textfield' => 'dummy value', 'checkboxes' => array(1 => NULL, 2 => 2)), TRUE); - $this->submitForm(array('textfield' => 'dummy value', 'checkboxes' => array(1 => NULL, 2 => NULL)), TRUE); - - // Test that a programmatic form submission can correctly click a button - // that limits validation errors based on user input. Since we do not - // submit any values for "textfield" here and the textfield is required, we - // only expect form validation to pass when validation is limited to a - // different field. - $this->submitForm(array('op' => 'Submit with limited validation', 'field_to_validate' => 'all'), FALSE); - $this->submitForm(array('op' => 'Submit with limited validation', 'field_to_validate' => 'textfield'), FALSE); - $this->submitForm(array('op' => 'Submit with limited validation', 'field_to_validate' => 'field_to_validate'), TRUE); - - // Restore the current batch status. - $batch = $current_batch; - } - - /** - * Helper function used to programmatically submit the form defined in - * form_test.module with the given values. - * - * @param $values - * An array of field values to be submitted. - * @param $valid_input - * A boolean indicating whether or not the form submission is expected to - * be valid. - */ - private function submitForm($values, $valid_input) { - // Programmatically submit the given values. - $form_state = (new FormState())->setValues($values); - \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state); - - // Check that the form returns an error when expected, and vice versa. - $errors = $form_state->getErrors(); - $valid_form = empty($errors); - $args = array( - '%values' => print_r($values, TRUE), - '%errors' => $valid_form ? t('None') : implode(' ', $errors), - ); - $this->assertTrue($valid_input == $valid_form, format_string('Input values: %values
    Validation handler errors: %errors', $args)); - - // We check submitted values only if we have a valid input. - if ($valid_input) { - // Fetching the values that were set in the submission handler. - $stored_values = $form_state->get('programmatic_form_submit'); - foreach ($values as $key => $value) { - $this->assertEqual($stored_values[$key], $value, format_string('Submission handler correctly executed: %stored_key is %stored_value', array('%stored_key' => $key, '%stored_value' => print_r($value, TRUE)))); - } - } - } - - /** - * Test the programmed_bypass_access_check flag. - */ - public function testProgrammaticAccessBypass() { - $form_state = (new FormState())->setValues([ - 'textfield' => 'dummy value', - 'field_restricted' => 'dummy value' - ]); - - // Programmatically submit the form with a value for the restricted field. - // Since programmed_bypass_access_check is set to TRUE by default, the - // field is accessible and can be set. - \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state); - $values = $form_state->get('programmatic_form_submit'); - $this->assertEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is stored correctly.'); - - // Programmatically submit the form with a value for the restricted field - // with programmed_bypass_access_check set to FALSE. Since access - // restrictions apply, the restricted field is inaccessible, and the value - // should not be stored. - $form_state->setProgrammedBypassAccessCheck(FALSE); - \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state); - $values = $form_state->get('programmatic_form_submit'); - $this->assertNotEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is not stored.'); - - } - -} diff --git a/core/modules/system/src/Tests/Form/RebuildTest.php b/core/modules/system/src/Tests/Form/RebuildTest.php index bee15fe1..2e138bdf 100644 --- a/core/modules/system/src/Tests/Form/RebuildTest.php +++ b/core/modules/system/src/Tests/Form/RebuildTest.php @@ -21,7 +21,7 @@ class RebuildTest extends WebTestBase { * * @var array */ - public static $modules = array('node', 'form_test'); + public static $modules = ['node', 'form_test']; /** * A user for testing. @@ -33,21 +33,21 @@ class RebuildTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); - $this->webUser = $this->drupalCreateUser(array('access content')); + $this->webUser = $this->drupalCreateUser(['access content']); $this->drupalLogin($this->webUser); } /** * Tests preservation of values. */ - function testRebuildPreservesValues() { - $edit = array( + public function testRebuildPreservesValues() { + $edit = [ 'checkbox_1_default_off' => TRUE, 'checkbox_1_default_on' => FALSE, 'text_1' => 'foo', - ); + ]; $this->drupalPostForm('form-test/form-rebuild-preserve-values', $edit, 'Add more'); // Verify that initial elements retained their submitted values. @@ -67,33 +67,33 @@ function testRebuildPreservesValues() { * The 'action' attribute of a form should not change after an Ajax submission * followed by a non-Ajax submission, which triggers a validation error. */ - function testPreserveFormActionAfterAJAX() { + public function testPreserveFormActionAfterAJAX() { // Create a multi-valued field for 'page' nodes to use for Ajax testing. $field_name = 'field_ajax_test'; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'node', 'type' => 'text', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $field_name, 'entity_type' => 'node', 'bundle' => 'page', ])->save(); entity_get_form_display('node', 'page', 'default') - ->setComponent($field_name, array('type' => 'text_textfield')) + ->setComponent($field_name, ['type' => 'text_textfield']) ->save(); // Log in a user who can create 'page' nodes. - $this->webUser = $this->drupalCreateUser(array('create page content')); + $this->webUser = $this->drupalCreateUser(['create page content']); $this->drupalLogin($this->webUser); // Get the form for adding a 'page' node. Submit an "add another item" Ajax // submission and verify it worked by ensuring the updated page has two text // field items in the field for which we just added an item. $this->drupalGet('node/add/page'); - $this->drupalPostAjaxForm(NULL, array(), array('field_ajax_test_add_more' => t('Add another item')), NULL, array(), array(), 'node-page-form'); + $this->drupalPostAjaxForm(NULL, [], ['field_ajax_test_add_more' => t('Add another item')], NULL, [], [], 'node-page-form'); $this->assert(count($this->xpath('//div[contains(@class, "field--name-field-ajax-test")]//input[@type="text"]')) == 2, 'AJAX submission succeeded.'); // Submit the form with the non-Ajax "Save" button, leaving the title field @@ -101,7 +101,7 @@ function testPreserveFormActionAfterAJAX() { // occurred, because this test is for testing what happens when a form is // re-rendered without being re-built, which is what happens when there's // a validation error. - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertText('Title field is required.', 'Non-AJAX submission correctly triggered a validation error.'); // Ensure that the form contains two items in the multi-valued field, so we diff --git a/core/modules/system/src/Tests/Form/RedirectTest.php b/core/modules/system/src/Tests/Form/RedirectTest.php deleted file mode 100644 index 6b6d3600..00000000 --- a/core/modules/system/src/Tests/Form/RedirectTest.php +++ /dev/null @@ -1,106 +0,0 @@ - array('foo' => 'bar')); - $options['absolute'] = TRUE; - - // Test basic redirection. - $edit = array( - 'redirection' => TRUE, - 'destination' => $this->randomMachineName(), - ); - $this->drupalPostForm($path, $edit, t('Submit')); - $this->assertUrl($edit['destination'], array(), 'Basic redirection works.'); - - - // Test without redirection. - $edit = array( - 'redirection' => FALSE, - ); - $this->drupalPostForm($path, $edit, t('Submit')); - $this->assertUrl($path, array(), 'When redirect is set to FALSE, there should be no redirection.'); - - // Test redirection with query parameters. - $edit = array( - 'redirection' => TRUE, - 'destination' => $this->randomMachineName(), - ); - $this->drupalPostForm($path, $edit, t('Submit'), $options); - $this->assertUrl($edit['destination'], array(), 'Redirection with query parameters works.'); - - // Test without redirection but with query parameters. - $edit = array( - 'redirection' => FALSE, - ); - $this->drupalPostForm($path, $edit, t('Submit'), $options); - $this->assertUrl($path, $options, 'When redirect is set to FALSE, there should be no redirection, and the query parameters should be passed along.'); - - // Test redirection back to the original path. - $edit = array( - 'redirection' => TRUE, - 'destination' => '', - ); - $this->drupalPostForm($path, $edit, t('Submit')); - $this->assertUrl($path, array(), 'When using an empty redirection string, there should be no redirection.'); - - // Test redirection back to the original path with query parameters. - $edit = array( - 'redirection' => TRUE, - 'destination' => '', - ); - $this->drupalPostForm($path, $edit, t('Submit'), $options); - $this->assertUrl($path, $options, 'When using an empty redirection string, there should be no redirection, and the query parameters should be passed along.'); - } - - /** - * Tests form redirection from 404/403 pages with the Block form. - */ - public function testRedirectFromErrorPages() { - // Make sure the block containing the redirect form is placed. - $this->drupalPlaceBlock('redirect_form_block'); - - // Create a user that does not have permission to administer blocks. - $user = $this->drupalCreateUser(array('administer themes')); - $this->drupalLogin($user); - - // Visit page 'foo' (404 page) and submit the form. Verify it ends up - // at the right URL. - $expected = \Drupal::url('form_test.route1', array(), array('query' => array('test1' => 'test2'), 'absolute' => TRUE)); - $this->drupalGet('foo'); - $this->assertResponse(404); - $this->drupalPostForm(NULL, array(), t('Submit')); - $this->assertResponse(200); - $this->assertUrl($expected, [], 'Redirected to correct URL/query.'); - - // Visit the block admin page (403 page) and submit the form. Verify it - // ends up at the right URL. - $this->drupalGet('admin/structure/block'); - $this->assertResponse(403); - $this->drupalPostForm(NULL, array(), t('Submit')); - $this->assertResponse(200); - $this->assertUrl($expected, [], 'Redirected to correct URL/query.'); - } - -} diff --git a/core/modules/system/src/Tests/Form/ResponseTest.php b/core/modules/system/src/Tests/Form/ResponseTest.php deleted file mode 100644 index 658b6726..00000000 --- a/core/modules/system/src/Tests/Form/ResponseTest.php +++ /dev/null @@ -1,47 +0,0 @@ - $this->randomString(), - 'status' => 200, - ]; - $content = Json::decode($this->drupalPostForm('form-test/response', $edit, 'Submit')); - $this->assertResponse(200); - $this->assertIdentical($edit['content'], $content, 'Response content matches'); - $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Response-Event'), 'Response handled by kernel response subscriber'); - $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Stack-Middleware'), 'Response handled by kernel middleware'); - - $edit = [ - 'content' => $this->randomString(), - 'status' => 418, - ]; - $content = Json::decode($this->drupalPostForm('form-test/response', $edit, 'Submit')); - $this->assertResponse(418); - $this->assertIdentical($edit['content'], $content, 'Response content matches'); - $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Response-Event'), 'Response handled by kernel response subscriber'); - $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Stack-Middleware'), 'Response handled by kernel middleware'); - } - -} diff --git a/core/modules/system/src/Tests/Form/StateValuesCleanAdvancedTest.php b/core/modules/system/src/Tests/Form/StateValuesCleanAdvancedTest.php deleted file mode 100644 index eb53244a..00000000 --- a/core/modules/system/src/Tests/Form/StateValuesCleanAdvancedTest.php +++ /dev/null @@ -1,51 +0,0 @@ -drupalGetTestFiles('image'); - $this->image = current($image_files); - - // Check if the physical file is there. - $this->assertTrue(is_file($this->image->uri), "The image file we're going to upload exists."); - - // "Browse" for the desired file. - $edit = array('files[image]' => drupal_realpath($this->image->uri)); - - // Post the form. - $this->drupalPostForm('form_test/form-state-values-clean-advanced', $edit, t('Submit')); - - // Expecting a 200 HTTP code. - $this->assertResponse(200, 'Received a 200 response for posted test file.'); - $this->assertRaw(t('You WIN!'), 'Found the success message.'); - } - -} diff --git a/core/modules/system/src/Tests/Form/StateValuesCleanTest.php b/core/modules/system/src/Tests/Form/StateValuesCleanTest.php deleted file mode 100644 index 7761bd8a..00000000 --- a/core/modules/system/src/Tests/Form/StateValuesCleanTest.php +++ /dev/null @@ -1,58 +0,0 @@ -drupalPostForm('form_test/form-state-values-clean', array(), t('Submit'))); - - // Setup the expected result. - $result = array( - 'beer' => 1000, - 'baz' => array('beer' => 2000), - ); - - // Verify that all internal Form API elements were removed. - $this->assertFalse(isset($values['form_id']), format_string('%element was removed.', array('%element' => 'form_id'))); - $this->assertFalse(isset($values['form_token']), format_string('%element was removed.', array('%element' => 'form_token'))); - $this->assertFalse(isset($values['form_build_id']), format_string('%element was removed.', array('%element' => 'form_build_id'))); - $this->assertFalse(isset($values['op']), format_string('%element was removed.', array('%element' => 'op'))); - - // Verify that all buttons were removed. - $this->assertFalse(isset($values['foo']), format_string('%element was removed.', array('%element' => 'foo'))); - $this->assertFalse(isset($values['bar']), format_string('%element was removed.', array('%element' => 'bar'))); - $this->assertFalse(isset($values['baz']['foo']), format_string('%element was removed.', array('%element' => 'foo'))); - $this->assertFalse(isset($values['baz']['baz']), format_string('%element was removed.', array('%element' => 'baz'))); - - // Verify values manually added for cleaning were removed. - $this->assertFalse(isset($values['wine']), SafeMarkup::format('%element was removed.', ['%element' => 'wine'])); - - // Verify that nested form value still exists. - $this->assertTrue(isset($values['baz']['beer']), 'Nested form value still exists.'); - - // Verify that actual form values equal resulting form values. - $this->assertEqual($values, $result, 'Expected form values equal actual form values.'); - } - -} diff --git a/core/modules/system/src/Tests/Form/StorageTest.php b/core/modules/system/src/Tests/Form/StorageTest.php index d29f36b6..a1f7fee3 100644 --- a/core/modules/system/src/Tests/Form/StorageTest.php +++ b/core/modules/system/src/Tests/Form/StorageTest.php @@ -23,22 +23,22 @@ class StorageTest extends WebTestBase { * * @var array */ - public static $modules = array('form_test', 'dblog'); + public static $modules = ['form_test', 'dblog']; protected function setUp() { parent::setUp(); - $this->drupalLogin ($this->drupalCreateUser()); + $this->drupalLogin($this->drupalCreateUser()); } /** * Tests using the form in a usual way. */ - function testForm() { + public function testForm() { $this->drupalGet('form_test/form-storage'); $this->assertText('Form constructions: 1'); - $edit = array('title' => 'new', 'value' => 'value_is_set'); + $edit = ['title' => 'new', 'value' => 'value_is_set']; // Use form rebuilding triggered by a submit button. $this->drupalPostForm(NULL, $edit, 'Continue submit'); @@ -47,7 +47,7 @@ function testForm() { // Reset the form to the values of the storage, using a form rebuild // triggered by button of type button. - $this->drupalPostForm(NULL, array('title' => 'changed'), 'Reset'); + $this->drupalPostForm(NULL, ['title' => 'changed'], 'Reset'); $this->assertFieldByName('title', 'new', 'Values have been reset.'); // After rebuilding, the form has been cached. $this->assertText('Form constructions: 4'); @@ -60,11 +60,11 @@ function testForm() { /** * Tests using the form after calling $form_state->setCached(). */ - function testFormCached() { - $this->drupalGet('form_test/form-storage', array('query' => array('cache' => 1))); + public function testFormCached() { + $this->drupalGet('form_test/form-storage', ['query' => ['cache' => 1]]); $this->assertText('Form constructions: 1'); - $edit = array('title' => 'new', 'value' => 'value_is_set'); + $edit = ['title' => 'new', 'value' => 'value_is_set']; // Use form rebuilding triggered by a submit button. $this->drupalPostForm(NULL, $edit, 'Continue submit'); @@ -75,7 +75,7 @@ function testFormCached() { // Reset the form to the values of the storage, using a form rebuild // triggered by button of type button. - $this->drupalPostForm(NULL, array('title' => 'changed'), 'Reset'); + $this->drupalPostForm(NULL, ['title' => 'changed'], 'Reset'); $this->assertFieldByName('title', 'new', 'Values have been reset.'); $this->assertText('Form constructions: 4'); @@ -87,8 +87,8 @@ function testFormCached() { /** * Tests validation when form storage is used. */ - function testValidation() { - $this->drupalPostForm('form_test/form-storage', array('title' => '', 'value' => 'value_is_set'), 'Continue submit'); + public function testValidation() { + $this->drupalPostForm('form_test/form-storage', ['title' => '', 'value' => 'value_is_set'], 'Continue submit'); $this->assertPattern('/value_is_set/', 'The input values have been kept.'); } @@ -102,28 +102,28 @@ function testValidation() { * during form validation, while another, required element in the form * triggers a form validation error. */ - function testCachedFormStorageValidation() { + public function testCachedFormStorageValidation() { // Request the form with 'cache' query parameter to enable form caching. - $this->drupalGet('form_test/form-storage', array('query' => array('cache' => 1))); + $this->drupalGet('form_test/form-storage', ['query' => ['cache' => 1]]); // Skip step 1 of the multi-step form, since the first step copies over // 'title' into form storage, but we want to verify that changes in the form // storage are updated in the cache during form validation. - $edit = array('title' => 'foo'); + $edit = ['title' => 'foo']; $this->drupalPostForm(NULL, $edit, 'Continue submit'); // In step 2, trigger a validation error for the required 'title' field, and // post the special 'change_title' value for the 'value' field, which // conditionally invokes the #element_validate handler to update the form // storage. - $edit = array('title' => '', 'value' => 'change_title'); + $edit = ['title' => '', 'value' => 'change_title']; $this->drupalPostForm(NULL, $edit, 'Save'); // At this point, the form storage should contain updated values, but we do // not see them, because the form has not been rebuilt yet due to the // validation error. Post again and verify that the rebuilt form contains // the values of the updated form storage. - $this->drupalPostForm(NULL, array('title' => 'foo', 'value' => 'bar'), 'Save'); + $this->drupalPostForm(NULL, ['title' => 'foo', 'value' => 'bar'], 'Save'); $this->assertText("The thing has been changed.", 'The altered form storage value was updated in cache and taken over.'); } diff --git a/core/modules/system/src/Tests/Form/SystemConfigFormTest.php b/core/modules/system/src/Tests/Form/SystemConfigFormTest.php deleted file mode 100644 index 69a7f7e6..00000000 --- a/core/modules/system/src/Tests/Form/SystemConfigFormTest.php +++ /dev/null @@ -1,32 +0,0 @@ -drupalGet('form-test/system-config-form'); - $element = $this->xpath('//div[@id = :id]/input[contains(@class, :class)]', array(':id' => 'edit-actions', ':class' => 'button--primary')); - $this->assertTrue($element, 'The primary action submit button was found.'); - $this->drupalPostForm(NULL, array(), t('Save configuration')); - $this->assertText(t('The configuration options have been saved.')); - } - -} diff --git a/core/modules/system/src/Tests/Form/TriggeringElementTest.php b/core/modules/system/src/Tests/Form/TriggeringElementTest.php index 5d8a1808..fb59cb5e 100644 --- a/core/modules/system/src/Tests/Form/TriggeringElementTest.php +++ b/core/modules/system/src/Tests/Form/TriggeringElementTest.php @@ -16,36 +16,36 @@ class TriggeringElementTest extends WebTestBase { * * @var array */ - public static $modules = array('form_test'); + public static $modules = ['form_test']; /** * Test the determination of the triggering element when no button * information is included in the POST data, as is sometimes the case when * the ENTER key is pressed in a textfield in Internet Explorer. */ - function testNoButtonInfoInPost() { + public function testNoButtonInfoInPost() { $path = 'form-test/clicked-button'; - $edit = array(); + $edit = []; $form_html_id = 'form-test-clicked-button'; // Ensure submitting a form with no buttons results in no triggering element // and the form submit handler not running. - $this->drupalPostForm($path, $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path, $edit, NULL, [], [], $form_html_id); $this->assertText('There is no clicked button.', '$form_state->getTriggeringElement() set to NULL.'); $this->assertNoText('Submit handler for form_test_clicked_button executed.', 'Form submit handler did not execute.'); // Ensure submitting a form with one or more submit buttons results in the // triggering element being set to the first one the user has access to. An // argument with 'r' in it indicates a restricted (#access=FALSE) button. - $this->drupalPostForm($path . '/s', $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path . '/s', $edit, NULL, [], [], $form_html_id); $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to only button.'); $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.'); - $this->drupalPostForm($path . '/s/s', $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path . '/s/s', $edit, NULL, [], [], $form_html_id); $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.'); $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.'); - $this->drupalPostForm($path . '/rs/s', $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path . '/rs/s', $edit, NULL, [], [], $form_html_id); $this->assertText('The clicked button is button2.', '$form_state->getTriggeringElement() set to first available button.'); $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.'); @@ -53,15 +53,15 @@ function testNoButtonInfoInPost() { // triggering element being set to the first button, regardless of type. For // the FAPI 'button' type, this should result in the submit handler not // executing. The types are 's'(ubmit), 'b'(utton), and 'i'(mage_button). - $this->drupalPostForm($path . '/s/b/i', $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path . '/s/b/i', $edit, NULL, [], [], $form_html_id); $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.'); $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.'); - $this->drupalPostForm($path . '/b/s/i', $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path . '/b/s/i', $edit, NULL, [], [], $form_html_id); $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.'); $this->assertNoText('Submit handler for form_test_clicked_button executed.', 'Form submit handler did not execute.'); - $this->drupalPostForm($path . '/i/s/b', $edit, NULL, array(), array(), $form_html_id); + $this->drupalPostForm($path . '/i/s/b', $edit, NULL, [], [], $form_html_id); $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.'); $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.'); } @@ -70,7 +70,7 @@ function testNoButtonInfoInPost() { * Test that the triggering element does not get set to a button with * #access=FALSE. */ - function testAttemptAccessControlBypass() { + public function testAttemptAccessControlBypass() { $path = 'form-test/clicked-button'; $form_html_id = 'form-test-clicked-button'; @@ -84,12 +84,12 @@ function testAttemptAccessControlBypass() { // data we want into \Drupal::request()->request. $elements = $this->xpath('//form[@id="' . $form_html_id . '"]//input[@name="text"]'); $elements[0]['name'] = 'button1'; - $this->drupalPostForm(NULL, array('button1' => 'button1'), NULL, array(), array(), $form_html_id); + $this->drupalPostForm(NULL, ['button1' => 'button1'], NULL, [], [], $form_html_id); // Ensure that the triggering element was not set to the restricted button. // Do this with both a negative and positive assertion, because negative // assertions alone can be brittle. See testNoButtonInfoInPost() for why the - //triggering element gets set to 'button2'. + // triggering element gets set to 'button2'. $this->assertNoText('The clicked button is button1.', '$form_state->getTriggeringElement() not set to a restricted button.'); $this->assertText('The clicked button is button2.', '$form_state->getTriggeringElement() not set to a restricted button.'); } diff --git a/core/modules/system/src/Tests/Form/UrlTest.php b/core/modules/system/src/Tests/Form/UrlTest.php deleted file mode 100644 index 4bf6f608..00000000 --- a/core/modules/system/src/Tests/Form/UrlTest.php +++ /dev/null @@ -1,50 +0,0 @@ -drupalPostForm('form-test/url', $edit, 'Submit'); - $this->assertRaw(t('The URL %url is not valid.', array('%url' => 'http://'))); - $this->assertRaw(t('@name field is required.', array('@name' => 'Required URL'))); - - $edit = array(); - $edit['url'] = "\n"; - $edit['url_required'] = 'http://example.com/ '; - $values = Json::decode($this->drupalPostForm('form-test/url', $edit, 'Submit')); - $this->assertIdentical($values['url'], ''); - $this->assertEqual($values['url_required'], 'http://example.com/'); - - $edit = array(); - $edit['url'] = 'http://foo.bar.example.com/'; - $edit['url_required'] = 'https://www.drupal.org/node/1174630?page=0&foo=bar#new'; - $values = Json::decode($this->drupalPostForm('form-test/url', $edit, 'Submit')); - $this->assertEqual($values['url'], $edit['url']); - $this->assertEqual($values['url_required'], $edit['url_required']); - } - -} diff --git a/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php b/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php deleted file mode 100644 index 66989de0..00000000 --- a/core/modules/system/src/Tests/Image/ToolkitSetupFormTest.php +++ /dev/null @@ -1,74 +0,0 @@ -adminUser = $this->drupalCreateUser(array( - 'administer site configuration', - )); - $this->drupalLogin($this->adminUser); - } - - /** - * Test Image toolkit setup form. - */ - function testToolkitSetupForm() { - // Get form. - $this->drupalGet('admin/config/media/image-toolkit'); - - // Test that default toolkit is GD. - $this->assertFieldByName('image_toolkit', 'gd', 'The default image toolkit is GD.'); - - // Test changing the jpeg image quality. - $edit = array('gd[image_jpeg_quality]' => '70'); - $this->drupalPostForm(NULL, $edit, 'Save configuration'); - $this->assertEqual($this->config('system.image.gd')->get('jpeg_quality'), '70'); - - // Test changing the toolkit. - $edit = array('image_toolkit' => 'test'); - $this->drupalPostForm(NULL, $edit, 'Save configuration'); - $this->assertEqual($this->config('system.image')->get('toolkit'), 'test'); - $this->assertFieldByName('test[test_parameter]', '10'); - - // Test changing the test toolkit parameter. - $edit = array('test[test_parameter]' => '0'); - $this->drupalPostForm(NULL, $edit, 'Save configuration'); - $this->assertText(t('Test parameter should be different from 0.'), 'Validation error displayed.'); - $edit = array('test[test_parameter]' => '20'); - $this->drupalPostForm(NULL, $edit, 'Save configuration'); - $this->assertEqual($this->config('system.image.test_toolkit')->get('test_parameter'), '20'); - - // Test access without the permission 'administer site configuration'. - $this->drupalLogin($this->drupalCreateUser(array('access administration pages'))); - $this->drupalGet('admin/config/media/image-toolkit'); - $this->assertResponse(403); - } - -} diff --git a/core/modules/system/src/Tests/Image/ToolkitTestBase.php b/core/modules/system/src/Tests/Image/ToolkitTestBase.php index 53ede0dc..6c5ce54f 100644 --- a/core/modules/system/src/Tests/Image/ToolkitTestBase.php +++ b/core/modules/system/src/Tests/Image/ToolkitTestBase.php @@ -2,11 +2,18 @@ namespace Drupal\system\Tests\Image; +@trigger_error(__FILE__ . ' is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use Drupal\FunctionalTests\Image\ToolkitTestBase instead. See https://www.drupal.org/node/2862641.', E_USER_DEPRECATED); + use Drupal\simpletest\WebTestBase; use Drupal\Component\Utility\SafeMarkup; /** * Base class for image manipulation testing. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use Drupal\FunctionalTests\Image\ToolkitTestBase instead. + * + * @see https://www.drupal.org/node/2862641 */ abstract class ToolkitTestBase extends WebTestBase { @@ -15,7 +22,7 @@ abstract class ToolkitTestBase extends WebTestBase { * * @var array */ - public static $modules = array('image_test'); + public static $modules = ['image_test']; /** * The URI for the file. @@ -75,10 +82,10 @@ protected function getImage() { * Array with string containing with the operation name, e.g. 'load', * 'save', 'crop', etc. */ - function assertToolkitOperationsCalled(array $expected) { + public function assertToolkitOperationsCalled(array $expected) { // If one of the image operations is expected, apply should be expected as // well. - $operations = array( + $operations = [ 'resize', 'rotate', 'crop', @@ -88,7 +95,7 @@ function assertToolkitOperationsCalled(array $expected) { 'scale_and_crop', 'my_operation', 'convert', - ); + ]; if (count(array_intersect($expected, $operations)) > 0 && !in_array('apply', $expected)) { $expected[] = 'apply'; } @@ -99,10 +106,10 @@ function assertToolkitOperationsCalled(array $expected) { // Determine if there were any expected that were not called. $uncalled = array_diff($expected, $actual); if (count($uncalled)) { - $this->assertTrue(FALSE, SafeMarkup::format('Expected operations %expected to be called but %uncalled was not called.', array('%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)))); + $this->assertTrue(FALSE, SafeMarkup::format('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)])); } else { - $this->assertTrue(TRUE, SafeMarkup::format('All the expected operations were called: %expected', array('%expected' => implode(', ', $expected)))); + $this->assertTrue(TRUE, SafeMarkup::format('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)])); } // Determine if there were any unexpected calls. @@ -110,7 +117,7 @@ function assertToolkitOperationsCalled(array $expected) { // count it as an error. $unexpected = array_diff($actual, $expected); if (count($unexpected) && (!in_array('apply', $expected) || count(array_intersect($unexpected, $operations)) !== count($unexpected))) { - $this->assertTrue(FALSE, SafeMarkup::format('Unexpected operations were called: %unexpected.', array('%unexpected' => implode(', ', $unexpected)))); + $this->assertTrue(FALSE, SafeMarkup::format('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)])); } else { $this->assertTrue(TRUE, 'No unexpected operations were called.'); @@ -120,22 +127,22 @@ function assertToolkitOperationsCalled(array $expected) { /** * Resets/initializes the history of calls to the test toolkit functions. */ - function imageTestReset() { + public function imageTestReset() { // Keep track of calls to these operations - $results = array( - 'parseFile' => array(), - 'save' => array(), - 'settings' => array(), - 'apply' => array(), - 'resize' => array(), - 'rotate' => array(), - 'crop' => array(), - 'desaturate' => array(), - 'create_new' => array(), - 'scale' => array(), - 'scale_and_crop' => array(), - 'convert' => array(), - ); + $results = [ + 'parseFile' => [], + 'save' => [], + 'settings' => [], + 'apply' => [], + 'resize' => [], + 'rotate' => [], + 'crop' => [], + 'desaturate' => [], + 'create_new' => [], + 'scale' => [], + 'scale_and_crop' => [], + 'convert' => [], + ]; \Drupal::state()->set('image_test.results', $results); } @@ -147,8 +154,8 @@ function imageTestReset() { * 'resize', 'rotate', 'crop', 'desaturate') with values being arrays of * parameters passed to each call. */ - function imageTestGetAllCalls() { - return \Drupal::state()->get('image_test.results') ?: array(); + public function imageTestGetAllCalls() { + return \Drupal::state()->get('image_test.results') ?: []; } } diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileExistingSettingsTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileExistingSettingsTest.php new file mode 100644 index 00000000..48b9fcb7 --- /dev/null +++ b/core/modules/system/src/Tests/Installer/DistributionProfileExistingSettingsTest.php @@ -0,0 +1,131 @@ +info = [ + 'type' => 'profile', + 'core' => \Drupal::CORE_COMPATIBILITY, + 'name' => 'Distribution profile', + 'distribution' => [ + 'name' => 'My Distribution', + 'install' => [ + 'theme' => 'bartik', + ], + ], + ]; + // File API functions are not available yet. + $path = $this->siteDirectory . '/profiles/mydistro'; + mkdir($path, 0777, TRUE); + file_put_contents("$path/mydistro.info.yml", Yaml::encode($this->info)); + + // Pre-configure hash salt. + // Any string is valid, so simply use the class name of this test. + $this->settings['settings']['hash_salt'] = (object) [ + 'value' => __CLASS__, + 'required' => TRUE, + ]; + + // Pre-configure database credentials. + $connection_info = Database::getConnectionInfo(); + unset($connection_info['default']['pdo']); + unset($connection_info['default']['init_commands']); + + $this->settings['databases']['default'] = (object) [ + 'value' => $connection_info, + 'required' => TRUE, + ]; + + // Use the kernel to find the site path because the site.path service should + // not be available at this point in the install process. + $site_path = DrupalKernel::findSitePath(Request::createFromGlobals()); + // Pre-configure config directories. + $this->settings['config_directories'] = [ + CONFIG_SYNC_DIRECTORY => (object) [ + 'value' => $site_path . '/files/config_staging', + 'required' => TRUE, + ], + ]; + mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE); + parent::setUp(); + } + + /** + * {@inheritdoc} + */ + protected function setUpLanguage() { + // Make settings file not writable. + $filename = $this->siteDirectory . '/settings.php'; + // Make the settings file read-only. + // Not using File API; a potential error must trigger a PHP warning. + chmod($filename, 0444); + + // Verify that the distribution name appears. + $this->assertRaw($this->info['distribution']['name']); + // Verify that the requested theme is used. + $this->assertRaw($this->info['distribution']['install']['theme']); + // Verify that the "Choose profile" step does not appear. + $this->assertNoText('profile'); + + parent::setUpLanguage(); + } + + /** + * {@inheritdoc} + */ + protected function setUpProfile() { + // This step is skipped, because there is a distribution profile. + } + + /** + * {@inheritdoc} + */ + protected function setUpSettings() { + // This step should not appear, since settings.php is fully configured + // already. + } + + /** + * Confirms that the installation succeeded. + */ + public function testInstalled() { + $this->assertUrl('user/1'); + $this->assertResponse(200); + // Confirm that we are logged-in after installation. + $this->assertText($this->rootUser->getUsername()); + + // Confirm that Drupal recognizes this distribution as the current profile. + $this->assertEqual(\Drupal::installProfile(), 'mydistro'); + $this->assertNull(Settings::get('install_profile'), 'The install profile has not been written to settings.php.'); + $this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.'); + + $this->rebuildContainer(); + $this->pass('Container can be rebuilt even though distribution is not written to settings.php.'); + $this->assertEqual(\Drupal::installProfile(), 'mydistro'); + } + +} diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTest.php index 0bb47acb..e52b0469 100644 --- a/core/modules/system/src/Tests/Installer/DistributionProfileTest.php +++ b/core/modules/system/src/Tests/Installer/DistributionProfileTest.php @@ -3,6 +3,7 @@ namespace Drupal\system\Tests\Installer; use Drupal\Core\Serialization\Yaml; +use Drupal\Core\Site\Settings; use Drupal\simpletest\InstallerTestBase; /** @@ -20,17 +21,17 @@ class DistributionProfileTest extends InstallerTestBase { protected $info; protected function setUp() { - $this->info = array( + $this->info = [ 'type' => 'profile', 'core' => \Drupal::CORE_COMPATIBILITY, 'name' => 'Distribution profile', - 'distribution' => array( + 'distribution' => [ 'name' => 'My Distribution', - 'install' => array( + 'install' => [ 'theme' => 'bartik', - ), - ), - ); + ], + ], + ]; // File API functions are not available yet. $path = $this->siteDirectory . '/profiles/mydistro'; mkdir($path, 0777, TRUE); @@ -68,6 +69,11 @@ public function testInstalled() { $this->assertResponse(200); // Confirm that we are logged-in after installation. $this->assertText($this->rootUser->getUsername()); + + // Confirm that Drupal recognizes this distribution as the current profile. + $this->assertEqual(\Drupal::installProfile(), 'mydistro'); + $this->assertEqual(Settings::get('install_profile'), 'mydistro', 'The install profile has been written to settings.php.'); + $this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.'); } } diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php index b8658fbb..1b686835 100644 --- a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php +++ b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationQueryTest.php @@ -30,18 +30,18 @@ class DistributionProfileTranslationQueryTest extends InstallerTestBase { * {@inheritdoc} */ protected function setUp() { - $this->info = array( + $this->info = [ 'type' => 'profile', 'core' => \Drupal::CORE_COMPATIBILITY, 'name' => 'Distribution profile', - 'distribution' => array( + 'distribution' => [ 'name' => 'My Distribution', 'langcode' => $this->langcode, - 'install' => array( + 'install' => [ 'theme' => 'bartik', - ), - ), - ); + ], + ], + ]; // File API functions are not available yet. $path = $this->siteDirectory . '/profiles/mydistro'; mkdir($path, 0777, TRUE); diff --git a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php index 29b9b3cc..799affe3 100644 --- a/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php +++ b/core/modules/system/src/Tests/Installer/DistributionProfileTranslationTest.php @@ -30,18 +30,18 @@ class DistributionProfileTranslationTest extends InstallerTestBase { * {@inheritdoc} */ protected function setUp() { - $this->info = array( + $this->info = [ 'type' => 'profile', 'core' => \Drupal::CORE_COMPATIBILITY, 'name' => 'Distribution profile', - 'distribution' => array( + 'distribution' => [ 'name' => 'My Distribution', 'langcode' => $this->langcode, - 'install' => array( + 'install' => [ 'theme' => 'bartik', - ), - ), - ); + ], + ], + ]; // File API functions are not available yet. $path = $this->siteDirectory . '/profiles/mydistro'; mkdir($path, 0777, TRUE); diff --git a/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryErrorTest.php b/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryErrorTest.php index eb50a0d8..2ab980fe 100644 --- a/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryErrorTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryErrorTest.php @@ -24,10 +24,10 @@ class InstallerConfigDirectorySetNoDirectoryErrorTest extends InstallerTestBase */ protected function setUp() { $this->configDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64(); - $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) array( + $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [ 'value' => $this->configDirectory . '/sync', 'required' => TRUE, - ); + ]; // Create the files directory early so we can test the error case. mkdir($this->publicFilesDirectory); // Create a file so the directory can not be created. diff --git a/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryTest.php b/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryTest.php index 4daa45cc..11febf2d 100644 --- a/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerConfigDirectorySetNoDirectoryTest.php @@ -24,15 +24,15 @@ class InstallerConfigDirectorySetNoDirectoryTest extends InstallerTestBase { */ protected function setUp() { $this->syncDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64() . '/sync'; - $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) array( + $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [ 'value' => $this->syncDirectory, 'required' => TRUE, - ); + ]; // Other directories will be created too. - $this->settings['config_directories']['custom'] = (object) array( + $this->settings['config_directories']['custom'] = (object) [ 'value' => $this->publicFilesDirectory . '/config_custom', 'required' => TRUE, - ); + ]; parent::setUp(); } diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingConfigDirectoryTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingConfigDirectoryTest.php index ae6b6069..b06b4caf 100644 --- a/core/modules/system/src/Tests/Installer/InstallerExistingConfigDirectoryTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerExistingConfigDirectoryTest.php @@ -24,10 +24,10 @@ class InstallerExistingConfigDirectoryTest extends InstallerTestBase { protected function setUp() { mkdir($this->siteDirectory . '/config_read_only', 0444); $this->expectedFilePerms = fileperms($this->siteDirectory . '/config_read_only'); - $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) array( + $this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [ 'value' => $this->siteDirectory . '/config_read_only', 'required' => TRUE, - ); + ]; parent::setUp(); } diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingDatabaseSettingsTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingDatabaseSettingsTest.php index 733f6bc4..63d3ce40 100644 --- a/core/modules/system/src/Tests/Installer/InstallerExistingDatabaseSettingsTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerExistingDatabaseSettingsTest.php @@ -22,10 +22,10 @@ protected function setUp() { unset($connection_info['default']['pdo']); unset($connection_info['default']['init_commands']); - $this->settings['databases']['default'] = (object) array( + $this->settings['databases']['default'] = (object) [ 'value' => $connection_info, 'required' => TRUE, - ); + ]; parent::setUp(); } @@ -40,13 +40,13 @@ protected function setUpSettings() { // All database settings should be pre-configured, except password. $values = $this->parameters['forms']['install_settings_form']; $driver = $values['driver']; - $edit = array(); + $edit = []; if (isset($values[$driver]['password']) && $values[$driver]['password'] !== '') { - $edit = $this->translatePostValues(array( - $driver => array( + $edit = $this->translatePostValues([ + $driver => [ 'password' => $values[$driver]['password'], - ), - )); + ], + ]); } $this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']); } diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsMismatchProfileBrokenTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsMismatchProfileBrokenTest.php new file mode 100644 index 00000000..6d866f0c --- /dev/null +++ b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsMismatchProfileBrokenTest.php @@ -0,0 +1,108 @@ +settings['settings']['hash_salt'] = (object) [ + 'value' => __CLASS__, + 'required' => TRUE, + ]; + + // Pre-configure database credentials. + $connection_info = Database::getConnectionInfo(); + unset($connection_info['default']['pdo']); + unset($connection_info['default']['init_commands']); + + $this->settings['databases']['default'] = (object) [ + 'value' => $connection_info, + 'required' => TRUE, + ]; + + // During interactive install we'll change this to a different profile and + // this test will ensure that the new value is written to settings.php. + $this->settings['settings']['install_profile'] = (object) [ + 'value' => 'minimal', + 'required' => TRUE, + ]; + + // Pre-configure config directories. + $site_path = DrupalKernel::findSitePath(Request::createFromGlobals()); + $this->settings['config_directories'] = [ + CONFIG_SYNC_DIRECTORY => (object) [ + 'value' => $site_path . '/files/config_staging', + 'required' => TRUE, + ], + ]; + mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE); + + parent::setUp(); + } + + /** + * {@inheritdoc} + */ + protected function visitInstaller() { + // Make settings file not writable. This will break the installer. + $filename = $this->siteDirectory . '/settings.php'; + // Make the settings file read-only. + // Not using File API; a potential error must trigger a PHP warning. + chmod($filename, 0444); + + $this->drupalGet($GLOBALS['base_url'] . '/core/install.php?langcode=en&profile=testing'); + } + + /** + * {@inheritdoc} + */ + protected function setUpLanguage() { + // This step is skipped, because there is a lagcode as a query param. + } + + /** + * {@inheritdoc} + */ + protected function setUpProfile() { + // This step is skipped, because there is a profile as a query param. + } + + /** + * {@inheritdoc} + */ + protected function setUpSettings() { + // This step should not appear, since settings.php is fully configured + // already. + } + + protected function setUpSite() { + // This step should not appear, since settings.php could not be written. + } + + /** + * Verifies that installation did not succeed. + */ + public function testBrokenInstaller() { + $this->assertTitle('Install profile mismatch | Drupal'); + $this->assertText("The selected profile testing does not match the install_profile setting, which is minimal. Cannot write updated setting to {$this->siteDirectory}/settings.php."); + } + +} diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsMismatchProfileTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsMismatchProfileTest.php new file mode 100644 index 00000000..0349fe51 --- /dev/null +++ b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsMismatchProfileTest.php @@ -0,0 +1,101 @@ +settings['settings']['hash_salt'] = (object) [ + 'value' => __CLASS__, + 'required' => TRUE, + ]; + + // Pre-configure database credentials. + $connection_info = Database::getConnectionInfo(); + unset($connection_info['default']['pdo']); + unset($connection_info['default']['init_commands']); + + $this->settings['databases']['default'] = (object) [ + 'value' => $connection_info, + 'required' => TRUE, + ]; + + // During interactive install we'll change this to a different profile and + // this test will ensure that the new value is written to settings.php. + $this->settings['settings']['install_profile'] = (object) [ + 'value' => 'minimal', + 'required' => TRUE, + ]; + + // Pre-configure config directories. + $this->settings['config_directories'] = [ + CONFIG_SYNC_DIRECTORY => (object) [ + 'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync', + 'required' => TRUE, + ], + ]; + mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE); + + parent::setUp(); + } + + /** + * {@inheritdoc} + */ + protected function visitInstaller() { + // Provide profile and language in query string to skip these pages. + $this->drupalGet($GLOBALS['base_url'] . '/core/install.php?langcode=en&profile=testing'); + } + + /** + * {@inheritdoc} + */ + protected function setUpLanguage() { + // This step is skipped, because there is a lagcode as a query param. + } + + /** + * {@inheritdoc} + */ + protected function setUpProfile() { + // This step is skipped, because there is a profile as a query param. + } + + /** + * {@inheritdoc} + */ + protected function setUpSettings() { + // This step should not appear, since settings.php is fully configured + // already. + } + + /** + * Verifies that installation succeeded. + */ + public function testInstaller() { + $this->assertUrl('user/1'); + $this->assertResponse(200); + $this->assertEqual('testing', \Drupal::installProfile()); + $this->assertEqual('testing', Settings::get('install_profile'), 'Profile was correctly changed to testing in Settings.php'); + } + +} diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php index 84f861a7..3405cb59 100644 --- a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsNoProfileTest.php @@ -3,7 +3,6 @@ namespace Drupal\system\Tests\Installer; use Drupal\Core\DrupalKernel; -use Drupal\Core\Site\Settings; use Drupal\simpletest\InstallerTestBase; use Drupal\Core\Database\Database; use Symfony\Component\HttpFoundation\Request; @@ -24,28 +23,28 @@ class InstallerExistingSettingsNoProfileTest extends InstallerTestBase { protected function setUp() { // Pre-configure hash salt. // Any string is valid, so simply use the class name of this test. - $this->settings['settings']['hash_salt'] = (object) array( + $this->settings['settings']['hash_salt'] = (object) [ 'value' => __CLASS__, 'required' => TRUE, - ); + ]; // Pre-configure database credentials. $connection_info = Database::getConnectionInfo(); unset($connection_info['default']['pdo']); unset($connection_info['default']['init_commands']); - $this->settings['databases']['default'] = (object) array( + $this->settings['databases']['default'] = (object) [ 'value' => $connection_info, 'required' => TRUE, - ); + ]; // Pre-configure config directories. - $this->settings['config_directories'] = array( - CONFIG_SYNC_DIRECTORY => (object) array( + $this->settings['config_directories'] = [ + CONFIG_SYNC_DIRECTORY => (object) [ 'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync', 'required' => TRUE, - ), - ); + ], + ]; mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE); parent::setUp(); @@ -65,7 +64,7 @@ protected function setUpSettings() { public function testInstaller() { $this->assertUrl('user/1'); $this->assertResponse(200); - $this->assertEqual('testing', Settings::get('install_profile')); + $this->assertEqual('testing', \Drupal::installProfile()); } } diff --git a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsTest.php b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsTest.php index 6ecd9fdf..4f09b6b7 100644 --- a/core/modules/system/src/Tests/Installer/InstallerExistingSettingsTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerExistingSettingsTest.php @@ -2,6 +2,7 @@ namespace Drupal\system\Tests\Installer; +use Drupal\Core\Site\Settings; use Drupal\simpletest\InstallerTestBase; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; @@ -23,38 +24,38 @@ class InstallerExistingSettingsTest extends InstallerTestBase { protected function setUp() { // Pre-configure hash salt. // Any string is valid, so simply use the class name of this test. - $this->settings['settings']['hash_salt'] = (object) array( + $this->settings['settings']['hash_salt'] = (object) [ 'value' => __CLASS__, 'required' => TRUE, - ); + ]; // During interactive install we'll change this to a different profile and // this test will ensure that the new value is written to settings.php. - $this->settings['settings']['install_profile'] = (object) array( + $this->settings['settings']['install_profile'] = (object) [ 'value' => 'minimal', 'required' => TRUE, - ); + ]; // Pre-configure database credentials. $connection_info = Database::getConnectionInfo(); unset($connection_info['default']['pdo']); unset($connection_info['default']['init_commands']); - $this->settings['databases']['default'] = (object) array( + $this->settings['databases']['default'] = (object) [ 'value' => $connection_info, 'required' => TRUE, - ); + ]; // Use the kernel to find the site path because the site.path service should // not be available at this point in the install process. $site_path = DrupalKernel::findSitePath(Request::createFromGlobals()); // Pre-configure config directories. - $this->settings['config_directories'] = array( - CONFIG_SYNC_DIRECTORY => (object) array( + $this->settings['config_directories'] = [ + CONFIG_SYNC_DIRECTORY => (object) [ 'value' => $site_path . '/files/config_sync', 'required' => TRUE, - ), - ); + ], + ]; mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE); parent::setUp(); @@ -74,7 +75,8 @@ protected function setUpSettings() { public function testInstaller() { $this->assertUrl('user/1'); $this->assertResponse(200); - $this->assertEqual('testing', drupal_get_profile(), 'Profile was changed from minimal to testing during interactive install.'); + $this->assertEqual('testing', \Drupal::installProfile(), 'Profile was changed from minimal to testing during interactive install.'); + $this->assertEqual('testing', Settings::get('install_profile'), 'Profile was correctly changed to testing in Settings.php'); } } diff --git a/core/modules/system/src/Tests/Installer/InstallerTest.php b/core/modules/system/src/Tests/Installer/InstallerTest.php index 7a145f86..be51057a 100644 --- a/core/modules/system/src/Tests/Installer/InstallerTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerTest.php @@ -22,9 +22,13 @@ public function testInstaller() { // Verify that the confirmation message appears. require_once \Drupal::root() . '/core/includes/install.inc'; - $this->assertRaw(t('Congratulations, you installed @drupal!', array( + $this->assertRaw(t('Congratulations, you installed @drupal!', [ '@drupal' => drupal_install_profile_distribution_name(), - ))); + ])); + + // Ensure that the timezone is correct for sites under test after installing + // interactively. + $this->assertEqual($this->config('system.date')->get('timezone.default'), 'Australia/Sydney'); } /** @@ -48,7 +52,7 @@ protected function setUpLanguage() { protected function setUpProfile() { // Assert that the expected title is present. $this->assertEqual('Select an installation profile', $this->cssSelect('main h2')[0]); - $result = $this->xpath('//span[contains(@class, :class) and contains(text(), :text)]', array(':class' => 'visually-hidden', ':text' => 'Select an installation profile')); + $result = $this->xpath('//span[contains(@class, :class) and contains(text(), :text)]', [':class' => 'visually-hidden', ':text' => 'Select an installation profile']); $this->assertEqual(count($result), 1, "Title/Label not displayed when '#title_display' => 'invisible' attribute is set"); parent::setUpProfile(); diff --git a/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php b/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php index 84dfad3e..a608cada 100644 --- a/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerTranslationMultipleLanguageTest.php @@ -116,10 +116,10 @@ public function testTranslationsLoaded() { // Activate a module, to make sure that config is not overridden by module // installation. - $edit = array( - 'modules[Core][views][enable]' => TRUE, - 'modules[Core][filter][enable]' => TRUE, - ); + $edit = [ + 'modules[views][enable]' => TRUE, + 'modules[filter][enable]' => TRUE, + ]; $this->drupalPostForm('admin/modules', $edit, t('Install')); // Verify the strings from the translation are still as expected. @@ -149,7 +149,7 @@ protected function verifyImportedStringsTranslated() { foreach ($test_samples as $sample) { foreach ($langcodes as $langcode) { - $edit = array(); + $edit = []; $edit['langcode'] = $langcode; $edit['translation'] = 'translated'; $edit['string'] = $sample; diff --git a/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php b/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php index fd6e0019..7a803e70 100644 --- a/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php +++ b/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php @@ -84,11 +84,11 @@ public function testInstaller() { $this->assertEqual($account->language()->getId(), 'de', 'New user is German.'); // Ensure that we can enable basic_auth on a non-english site. - $this->drupalPostForm('admin/modules', array('modules[Web services][basic_auth][enable]' => TRUE), t('Install')); + $this->drupalPostForm('admin/modules', ['modules[basic_auth][enable]' => TRUE], t('Install')); $this->assertResponse(200); // Assert that the theme CSS was added to the page. - $edit = array('preprocess_css' => FALSE); + $edit = ['preprocess_css' => FALSE]; $this->drupalPostForm('admin/config/development/performance', $edit, t('Save configuration')); $this->drupalGet(''); $this->assertRaw('classy/css/components/action-links.css'); @@ -96,7 +96,7 @@ public function testInstaller() { // Verify the strings from the translation files were imported. $test_samples = ['Save and continue', 'Anonymous']; foreach ($test_samples as $sample) { - $edit = array(); + $edit = []; $edit['langcode'] = 'de'; $edit['translation'] = 'translated'; $edit['string'] = $sample; diff --git a/core/modules/system/src/Tests/Installer/MultipleDistributionsProfileTest.php b/core/modules/system/src/Tests/Installer/MultipleDistributionsProfileTest.php new file mode 100644 index 00000000..171a0afc --- /dev/null +++ b/core/modules/system/src/Tests/Installer/MultipleDistributionsProfileTest.php @@ -0,0 +1,91 @@ + 'profile', + 'core' => \Drupal::CORE_COMPATIBILITY, + 'name' => $name . ' profile', + 'distribution' => [ + 'name' => $name, + 'install' => [ + 'theme' => 'bartik', + ], + ], + ]; + // File API functions are not available yet. + $path = $this->siteDirectory . '/profiles/' . $name; + mkdir($path, 0777, TRUE); + file_put_contents("$path/$name.info.yml", Yaml::encode($info)); + } + // Install the first distribution. + $this->profile = 'distribution_one'; + + parent::setUp(); + } + + /** + * {@inheritdoc} + */ + protected function setUpLanguage() { + // Verify that the distribution name appears. + $this->assertRaw('distribution_one'); + // Verify that the requested theme is used. + $this->assertRaw('bartik'); + // Verify that the "Choose profile" step does not appear. + $this->assertNoText('profile'); + + parent::setUpLanguage(); + } + + /** + * {@inheritdoc} + */ + protected function setUpProfile() { + // This step is skipped, because there is a distribution profile. + } + + /** + * Confirms that the installation succeeded. + */ + public function testInstalled() { + $this->assertUrl('user/1'); + $this->assertResponse(200); + // Confirm that we are logged-in after installation. + $this->assertText($this->rootUser->getUsername()); + + // Confirm that Drupal recognizes this distribution as the current profile. + $this->assertEqual(\Drupal::installProfile(), 'distribution_one'); + $this->assertEqual(Settings::get('install_profile'), 'distribution_one', 'The install profile has been written to settings.php.'); + $this->assertEqual($this->config('core.extension')->get('profile'), 'distribution_one', 'The install profile has been written to core.extension configuration.'); + + $this->rebuildContainer(); + $this->pass('Container can be rebuilt as distribution is written to configuration.'); + $this->assertEqual(\Drupal::installProfile(), 'distribution_one'); + } + +} diff --git a/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php b/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php index b54c4113..91af34a2 100644 --- a/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php +++ b/core/modules/system/src/Tests/Installer/SingleVisibleProfileTest.php @@ -29,12 +29,12 @@ class SingleVisibleProfileTest extends InstallerTestBase { protected $info; protected function setUp() { - $this->info = array( + $this->info = [ 'type' => 'profile', 'core' => \Drupal::CORE_COMPATIBILITY, 'name' => 'Override standard', 'hidden' => TRUE, - ); + ]; // File API functions are not available yet. $path = $this->siteDirectory . '/profiles/standard'; mkdir($path, 0777, TRUE); diff --git a/core/modules/system/src/Tests/Installer/SiteNameTest.php b/core/modules/system/src/Tests/Installer/SiteNameTest.php index ec4c0e13..081dfb16 100644 --- a/core/modules/system/src/Tests/Installer/SiteNameTest.php +++ b/core/modules/system/src/Tests/Installer/SiteNameTest.php @@ -31,7 +31,7 @@ protected function installParameters() { /** * Tests that the desired site name appears on the page after installation. */ - function testSiteName() { + public function testSiteName() { $this->drupalGet(''); $this->assertRaw($this->siteName, 'The site name that was set during the installation appears on the front page after installation.'); } diff --git a/core/modules/system/src/Tests/Installer/StandardInstallerTest.php b/core/modules/system/src/Tests/Installer/StandardInstallerTest.php index 61e7c84d..b0ceef94 100644 --- a/core/modules/system/src/Tests/Installer/StandardInstallerTest.php +++ b/core/modules/system/src/Tests/Installer/StandardInstallerTest.php @@ -20,9 +20,9 @@ class StandardInstallerTest extends ConfigAfterInstallerTestBase { public function testInstaller() { // Verify that the confirmation message appears. require_once \Drupal::root() . '/core/includes/install.inc'; - $this->assertRaw(t('Congratulations, you installed @drupal!', array( + $this->assertRaw(t('Congratulations, you installed @drupal!', [ '@drupal' => drupal_install_profile_distribution_name(), - ))); + ])); } /** diff --git a/core/modules/system/src/Tests/Menu/AssertBreadcrumbTrait.php b/core/modules/system/src/Tests/Menu/AssertBreadcrumbTrait.php index f9c35eec..41634b11 100644 --- a/core/modules/system/src/Tests/Menu/AssertBreadcrumbTrait.php +++ b/core/modules/system/src/Tests/Menu/AssertBreadcrumbTrait.php @@ -2,11 +2,16 @@ namespace Drupal\system\Tests\Menu; +@trigger_error(__NAMESPACE__ . '\AssertBreadcrumbTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait', E_USER_DEPRECATED); + use Drupal\Component\Utility\Html; use Drupal\Core\Url; /** * Provides test assertions for verifying breadcrumbs. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait instead. */ trait AssertBreadcrumbTrait { @@ -32,7 +37,7 @@ trait AssertBreadcrumbTrait { * (optional) Whether the last link in $tree is expected to be active (TRUE) * or just to be in the active trail (FALSE). */ - protected function assertBreadcrumb($goto, array $trail, $page_title = NULL, array $tree = array(), $last_active = TRUE) { + protected function assertBreadcrumb($goto, array $trail, $page_title = NULL, array $tree = [], $last_active = TRUE) { if (isset($goto)) { $this->drupalGet($goto); } @@ -40,7 +45,7 @@ protected function assertBreadcrumb($goto, array $trail, $page_title = NULL, arr // Additionally assert page title, if given. if (isset($page_title)) { - $this->assertTitle(strtr('@title | Drupal', array('@title' => $page_title))); + $this->assertTitle(strtr('@title | Drupal', ['@title' => $page_title])); } // Additionally assert active trail in a menu tree output, if given. @@ -84,25 +89,25 @@ protected function assertBreadcrumbParts($trail) { // No parts must be left, or an expected "Home" will always pass. $pass = ($pass && empty($parts)); - $this->assertTrue($pass, format_string('Breadcrumb %parts found on @path.', array( + $this->assertTrue($pass, format_string('Breadcrumb %parts found on @path.', [ '%parts' => implode(' » ', $trail), '@path' => $this->getUrl(), - ))); + ])); } /** * Returns the breadcrumb contents of the current page in the internal browser. */ protected function getBreadcrumbParts() { - $parts = array(); + $parts = []; $elements = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a'); if (!empty($elements)) { foreach ($elements as $element) { - $parts[] = array( + $parts[] = [ 'text' => (string) $element, 'href' => (string) $element['href'], 'title' => (string) $element['title'], - ); + ]; } } return $parts; diff --git a/core/modules/system/src/Tests/Menu/AssertMenuActiveTrailTrait.php b/core/modules/system/src/Tests/Menu/AssertMenuActiveTrailTrait.php index 4313b4cf..e64177a8 100644 --- a/core/modules/system/src/Tests/Menu/AssertMenuActiveTrailTrait.php +++ b/core/modules/system/src/Tests/Menu/AssertMenuActiveTrailTrait.php @@ -2,10 +2,15 @@ namespace Drupal\system\Tests\Menu; +@trigger_error(__NAMESPACE__ . '\AssertMenuActiveTrailTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Menu\AssertMenuActiveTrailTrait', E_USER_DEPRECATED); + use Drupal\Core\Url; /** * Provides test assertions for verifying the active menu trail. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\system\Functional\Menu\AssertMenuActiveTrailTrait instead. */ trait AssertMenuActiveTrailTrait { @@ -30,11 +35,11 @@ protected function assertMenuActiveTrail($tree, $last_active) { foreach ($tree as $link_path => $link_title) { $part_xpath = (!$i ? '//' : '/following-sibling::ul/descendant::'); $part_xpath .= 'li[contains(@class, :class)]/a[contains(@href, :href) and contains(text(), :title)]'; - $part_args = array( + $part_args = [ ':class' => 'menu-item--active-trail', ':href' => Url::fromUri('base:' . $link_path)->toString(), ':title' => $link_title, - ); + ]; $xpath .= $this->buildXPathQuery($part_xpath, $part_args); $i++; } @@ -49,17 +54,17 @@ protected function assertMenuActiveTrail($tree, $last_active) { } $xpath_last_active = ($last_active ? 'and contains(@class, :class-active)' : ''); $xpath .= 'li[contains(@class, :class-trail)]/a[contains(@href, :href) ' . $xpath_last_active . 'and contains(text(), :title)]'; - $args = array( + $args = [ ':class-trail' => 'menu-item--active-trail', ':class-active' => 'is-active', ':href' => Url::fromUri('base:' . $active_link_path)->toString(), ':title' => $active_link_title, - ); + ]; $elements = $this->xpath($xpath, $args); - $this->assertTrue(!empty($elements), format_string('Active link %title was found in menu tree, including active trail links %tree.', array( + $this->assertTrue(!empty($elements), format_string('Active link %title was found in menu tree, including active trail links %tree.', [ '%title' => $active_link_title, '%tree' => implode(' » ', $tree), - ))); + ])); } } diff --git a/core/modules/system/src/Tests/Menu/MenuTestBase.php b/core/modules/system/src/Tests/Menu/MenuTestBase.php index f791eecb..c77f079c 100644 --- a/core/modules/system/src/Tests/Menu/MenuTestBase.php +++ b/core/modules/system/src/Tests/Menu/MenuTestBase.php @@ -2,8 +2,16 @@ namespace Drupal\system\Tests\Menu; +@trigger_error(__NAMESPACE__ . '\MenuTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\BrowserTestBase', E_USER_DEPRECATED); + use Drupal\simpletest\WebTestBase; +/** + * Base class for Menu tests. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\BrowserTestBase instead. + */ abstract class MenuTestBase extends WebTestBase { use AssertBreadcrumbTrait; diff --git a/core/modules/system/src/Tests/Module/DependencyTest.php b/core/modules/system/src/Tests/Module/DependencyTest.php index 8b219b27..173380eb 100644 --- a/core/modules/system/src/Tests/Module/DependencyTest.php +++ b/core/modules/system/src/Tests/Module/DependencyTest.php @@ -1,6 +1,7 @@ TRUE, - ); + public function testProjectNamespaceForDependencies() { + $edit = [ + 'modules[filter][enable]' => TRUE, + ]; $this->drupalPostForm('admin/modules', $edit, t('Install')); // Enable module with project namespace to ensure nothing breaks. - $edit = array( - 'modules[Testing][system_project_namespace_test][enable]' => TRUE, - ); + $edit = [ + 'modules[system_project_namespace_test][enable]' => TRUE, + ]; $this->drupalPostForm('admin/modules', $edit, t('Install')); - $this->assertModules(array('system_project_namespace_test'), TRUE); + $this->assertModules(['system_project_namespace_test'], TRUE); } /** * Attempts to enable the Content Translation module without Language enabled. */ - function testEnableWithoutDependency() { + public function testEnableWithoutDependency() { // Attempt to enable Content Translation without Language enabled. - $edit = array(); - $edit['modules[Multilingual][content_translation][enable]'] = 'content_translation'; + $edit = []; + $edit['modules[content_translation][enable]'] = 'content_translation'; $this->drupalPostForm('admin/modules', $edit, t('Install')); $this->assertText(t('Some required modules must be enabled'), 'Dependency required.'); - $this->assertModules(array('content_translation', 'language'), FALSE); + $this->assertModules(['content_translation', 'language'], FALSE); // Assert that the language tables weren't enabled. $this->assertTableCount('language', FALSE); $this->drupalPostForm(NULL, NULL, t('Continue')); $this->assertText(t('2 modules have been enabled: Content Translation, Language.'), 'Modules status has been updated.'); - $this->assertModules(array('content_translation', 'language'), TRUE); + $this->assertModules(['content_translation', 'language'], TRUE); // Assert that the language YAML files were created. $storage = $this->container->get('config.storage'); @@ -52,67 +53,77 @@ function testEnableWithoutDependency() { /** * Attempts to enable a module with a missing dependency. */ - function testMissingModules() { + public function testMissingModules() { // Test that the system_dependencies_test module is marked // as missing a dependency. $this->drupalGet('admin/modules'); - $this->assertRaw(t('@module (missing)', array('@module' => Unicode::ucfirst('_missing_dependency'))), 'A module with missing dependencies is marked as such.'); - $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_dependencies_test][enable]"]'); + $this->assertRaw(t('@module (missing)', ['@module' => Unicode::ucfirst('_missing_dependency')]), 'A module with missing dependencies is marked as such.'); + $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_dependencies_test][enable]"]'); $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.'); } /** * Tests enabling a module that depends on an incompatible version of a module. */ - function testIncompatibleModuleVersionDependency() { + public function testIncompatibleModuleVersionDependency() { // Test that the system_incompatible_module_version_dependencies_test is // marked as having an incompatible dependency. $this->drupalGet('admin/modules'); - $this->assertRaw(t('@module (incompatible with version @version)', array( + $this->assertRaw(t('@module (incompatible with version @version)', [ '@module' => 'System incompatible module version test (>2.0)', '@version' => '1.0', - )), 'A module that depends on an incompatible version of a module is marked as such.'); - $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_module_version_dependencies_test][enable]"]'); + ]), 'A module that depends on an incompatible version of a module is marked as such.'); + $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_incompatible_module_version_dependencies_test][enable]"]'); $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.'); } /** * Tests enabling a module that depends on a module with an incompatible core version. */ - function testIncompatibleCoreVersionDependency() { + public function testIncompatibleCoreVersionDependency() { // Test that the system_incompatible_core_version_dependencies_test is // marked as having an incompatible dependency. $this->drupalGet('admin/modules'); - $this->assertRaw(t('@module (incompatible with this version of Drupal core)', array( + $this->assertRaw(t('@module (incompatible with this version of Drupal core)', [ '@module' => 'System incompatible core version test', - )), 'A module that depends on a module with an incompatible core version is marked as such.'); - $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_core_version_dependencies_test][enable]"]'); + ]), 'A module that depends on a module with an incompatible core version is marked as such.'); + $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_incompatible_core_version_dependencies_test][enable]"]'); + $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.'); + } + + /** + * Tests failing PHP version requirements. + */ + public function testIncompatiblePhpVersionDependency() { + $this->drupalGet('admin/modules'); + $this->assertRaw('This module requires PHP version 6502.* and is incompatible with PHP version ' . phpversion() . '.', 'User is informed when the PHP dependency requirement of a module is not met.'); + $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[system_incompatible_php_version_test][enable]"]'); $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.'); } /** * Tests enabling a module that depends on a module which fails hook_requirements(). */ - function testEnableRequirementsFailureDependency() { - \Drupal::service('module_installer')->install(array('comment')); + public function testEnableRequirementsFailureDependency() { + \Drupal::service('module_installer')->install(['comment']); - $this->assertModules(array('requirements1_test'), FALSE); - $this->assertModules(array('requirements2_test'), FALSE); + $this->assertModules(['requirements1_test'], FALSE); + $this->assertModules(['requirements2_test'], FALSE); // Attempt to install both modules at the same time. - $edit = array(); - $edit['modules[Testing][requirements1_test][enable]'] = 'requirements1_test'; - $edit['modules[Testing][requirements2_test][enable]'] = 'requirements2_test'; + $edit = []; + $edit['modules[requirements1_test][enable]'] = 'requirements1_test'; + $edit['modules[requirements2_test][enable]'] = 'requirements2_test'; $this->drupalPostForm('admin/modules', $edit, t('Install')); // Makes sure the modules were NOT installed. $this->assertText(t('Requirements 1 Test failed requirements'), 'Modules status has been updated.'); - $this->assertModules(array('requirements1_test'), FALSE); - $this->assertModules(array('requirements2_test'), FALSE); + $this->assertModules(['requirements1_test'], FALSE); + $this->assertModules(['requirements2_test'], FALSE); // Makes sure that already enabled modules the failing modules depend on // were not disabled. - $this->assertModules(array('comment'), TRUE); + $this->assertModules(['comment'], TRUE); } /** @@ -120,45 +131,45 @@ function testEnableRequirementsFailureDependency() { * * Dependencies should be enabled before their dependents. */ - function testModuleEnableOrder() { - \Drupal::service('module_installer')->install(array('module_test'), FALSE); + public function testModuleEnableOrder() { + \Drupal::service('module_installer')->install(['module_test'], FALSE); $this->resetAll(); - $this->assertModules(array('module_test'), TRUE); + $this->assertModules(['module_test'], TRUE); \Drupal::state()->set('module_test.dependency', 'dependency'); // module_test creates a dependency chain: // - color depends on config // - config depends on help - $expected_order = array('help', 'config', 'color'); + $expected_order = ['help', 'config', 'color']; // Enable the modules through the UI, verifying that the dependency chain // is correct. - $edit = array(); - $edit['modules[Core][color][enable]'] = 'color'; + $edit = []; + $edit['modules[color][enable]'] = 'color'; $this->drupalPostForm('admin/modules', $edit, t('Install')); - $this->assertModules(array('color'), FALSE); + $this->assertModules(['color'], FALSE); // Note that dependencies are sorted alphabetically in the confirmation // message. $this->assertText(t('You must enable the Configuration Manager, Help modules to install Color.')); - $edit['modules[Core][config][enable]'] = 'config'; - $edit['modules[Core][help][enable]'] = 'help'; + $edit['modules[config][enable]'] = 'config'; + $edit['modules[help][enable]'] = 'help'; $this->drupalPostForm('admin/modules', $edit, t('Install')); - $this->assertModules(array('color', 'config', 'help'), TRUE); + $this->assertModules(['color', 'config', 'help'], TRUE); // Check the actual order which is saved by module_test_modules_enabled(). - $module_order = \Drupal::state()->get('module_test.install_order') ?: array(); + $module_order = \Drupal::state()->get('module_test.install_order') ?: []; $this->assertIdentical($module_order, $expected_order); } /** * Tests attempting to uninstall a module that has installed dependents. */ - function testUninstallDependents() { + public function testUninstallDependents() { // Enable the forum module. - $edit = array('modules[Core][forum][enable]' => 'forum'); + $edit = ['modules[forum][enable]' => 'forum']; $this->drupalPostForm('admin/modules', $edit, t('Install')); - $this->drupalPostForm(NULL, array(), t('Continue')); - $this->assertModules(array('forum'), TRUE); + $this->drupalPostForm(NULL, [], t('Continue')); + $this->assertModules(['forum'], TRUE); // Check that the comment module cannot be uninstalled. $this->drupalGet('admin/modules/uninstall'); @@ -176,13 +187,13 @@ function testUninstallDependents() { } // Uninstall the forum module, and check that taxonomy now can also be // uninstalled. - $edit = array('uninstall[forum]' => 'forum'); + $edit = ['uninstall[forum]' => 'forum']; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); $this->drupalPostForm(NULL, NULL, t('Uninstall')); $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.'); // Uninstall comment module. - $edit = array('uninstall[comment]' => 'comment'); + $edit = ['uninstall[comment]' => 'comment']; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); $this->drupalPostForm(NULL, NULL, t('Uninstall')); $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.'); diff --git a/core/modules/system/src/Tests/Module/HookRequirementsTest.php b/core/modules/system/src/Tests/Module/HookRequirementsTest.php index ccbbff98..c89c206c 100644 --- a/core/modules/system/src/Tests/Module/HookRequirementsTest.php +++ b/core/modules/system/src/Tests/Module/HookRequirementsTest.php @@ -11,17 +11,17 @@ class HookRequirementsTest extends ModuleTestBase { /** * Assert that a module cannot be installed if it fails hook_requirements(). */ - function testHookRequirementsFailure() { - $this->assertModules(array('requirements1_test'), FALSE); + public function testHookRequirementsFailure() { + $this->assertModules(['requirements1_test'], FALSE); // Attempt to install the requirements1_test module. - $edit = array(); - $edit['modules[Testing][requirements1_test][enable]'] = 'requirements1_test'; + $edit = []; + $edit['modules[requirements1_test][enable]'] = 'requirements1_test'; $this->drupalPostForm('admin/modules', $edit, t('Install')); // Makes sure the module was NOT installed. $this->assertText(t('Requirements 1 Test failed requirements'), 'Modules status has been updated.'); - $this->assertModules(array('requirements1_test'), FALSE); + $this->assertModules(['requirements1_test'], FALSE); } } diff --git a/core/modules/system/src/Tests/Module/InstallUninstallTest.php b/core/modules/system/src/Tests/Module/InstallUninstallTest.php index d8d625ba..a78918bc 100644 --- a/core/modules/system/src/Tests/Module/InstallUninstallTest.php +++ b/core/modules/system/src/Tests/Module/InstallUninstallTest.php @@ -15,7 +15,7 @@ class InstallUninstallTest extends ModuleTestBase { /** * {@inheritdoc} */ - public static $modules = array('system_test', 'dblog', 'taxonomy', 'update_test_postupdate'); + public static $modules = ['system_test', 'dblog', 'taxonomy', 'update_test_postupdate']; /** * Tests that a fixed set of modules can be installed and uninstalled. @@ -27,9 +27,9 @@ public function testInstallUninstall() { // Install and uninstall module_test to ensure hook_preinstall_module and // hook_preuninstall_module are fired as expected. - $this->container->get('module_installer')->install(array('module_test')); + $this->container->get('module_installer')->install(['module_test']); $this->assertEqual($this->container->get('state')->get('system_test_preinstall_module'), 'module_test'); - $this->container->get('module_installer')->uninstall(array('module_test')); + $this->container->get('module_installer')->uninstall(['module_test']); $this->assertEqual($this->container->get('state')->get('system_test_preuninstall_module'), 'module_test'); $this->resetAll(); @@ -58,9 +58,8 @@ public function testInstallUninstall() { // Install the Help module, and verify it installed successfully. unset($all_modules['help']); $this->assertModuleNotInstalled('help'); - $edit = array(); - $package = $required_modules['help']->info['package']; - $edit["modules[$package][help][enable]"] = TRUE; + $edit = []; + $edit["modules[help][enable]"] = TRUE; $this->drupalPostForm('admin/modules', $edit, t('Install')); $this->assertText('has been enabled', 'Modules status has been updated.'); $this->assertText(t('hook_modules_installed fired for help')); @@ -77,7 +76,7 @@ public function testInstallUninstall() { $was_installed_list = \Drupal::moduleHandler()->getModuleList(); // Start a list of modules that we expect to be installed this time. - $modules_to_install = array($name); + $modules_to_install = [$name]; foreach (array_keys($module->requires) as $dependency) { if (isset($all_modules[$dependency])) { $modules_to_install[] = $dependency; @@ -91,9 +90,9 @@ public function testInstallUninstall() { } // Install the module. - $edit = array(); + $edit = []; $package = $module->info['package']; - $edit["modules[$package][$name][enable]"] = TRUE; + $edit['modules[' . $name . '][enable]'] = TRUE; $this->drupalPostForm('admin/modules', $edit, t('Install')); // Handle experimental modules, which require a confirmation screen. @@ -105,7 +104,7 @@ public function testInstallUninstall() { // indicating they need to be enabled. $this->assertText('You must enable'); } - $this->drupalPostForm(NULL, array(), t('Continue')); + $this->drupalPostForm(NULL, [], t('Continue')); } // Handle the case where modules were installed along with this one and // where we therefore hit a confirmation screen. @@ -114,26 +113,26 @@ public function testInstallUninstall() { // about enabling dependencies appears. $this->assertText('Some required modules must be enabled'); $this->assertText('You must enable'); - $this->drupalPostForm(NULL, array(), t('Continue')); + $this->drupalPostForm(NULL, [], t('Continue')); } // List the module display names to check the confirmation message. - $module_names = array(); + $module_names = []; foreach ($modules_to_install as $module_to_install) { $module_names[] = $all_modules[$module_to_install]->info['name']; } - $expected_text = \Drupal::translation()->formatPlural(count($module_names), 'Module @name has been enabled.', '@count modules have been enabled: @names.', array( + $expected_text = \Drupal::translation()->formatPlural(count($module_names), 'Module @name has been enabled.', '@count modules have been enabled: @names.', [ '@name' => $module_names[0], '@names' => implode(', ', $module_names), - )); + ]); $this->assertText($expected_text, 'Modules status has been updated.'); // Check that hook_modules_installed() was invoked with the expected list // of modules, that each module's database tables now exist, and that // appropriate messages appear in the logs. foreach ($modules_to_install as $module_to_install) { - $this->assertText(t('hook_modules_installed fired for @module', array('@module' => $module_to_install))); - $this->assertLogMessage('system', "%module module installed.", array('%module' => $module_to_install), RfcLogLevel::INFO); + $this->assertText(t('hook_modules_installed fired for @module', ['@module' => $module_to_install])); + $this->assertLogMessage('system', "%module module installed.", ['%module' => $module_to_install], RfcLogLevel::INFO); $this->assertInstallModuleUpdates($module_to_install); $this->assertModuleSuccessfullyInstalled($module_to_install); } @@ -164,7 +163,7 @@ public function testInstallUninstall() { // This one is eligible for being uninstalled. $package = $all_modules[$to_uninstall]->info['package']; $this->assertSuccessfulUninstall($to_uninstall, $package); - $added_modules = array_diff($added_modules, array($to_uninstall)); + $added_modules = array_diff($added_modules, [$to_uninstall]); } } @@ -188,10 +187,10 @@ public function testInstallUninstall() { // uninstalled. // - That enabling more than one module at the same time does not lead to // any errors. - $edit = array(); + $edit = []; $experimental = FALSE; foreach ($all_modules as $name => $module) { - $edit['modules[' . $module->info['package'] . '][' . $name . '][enable]'] = TRUE; + $edit['modules[' . $name . '][enable]'] = TRUE; // Track whether there is at least one experimental module. if ($module->info['package'] == 'Core (Experimental)') { $experimental = TRUE; @@ -202,12 +201,12 @@ public function testInstallUninstall() { // If there are experimental modules, click the confirm form. if ($experimental) { $this->assertText('Are you sure you wish to enable experimental modules?'); - $this->drupalPostForm(NULL, array(), t('Continue')); + $this->drupalPostForm(NULL, [], t('Continue')); } // The string tested here is translatable but we are only using a part of it // so using a translated string is wrong. Doing so would create a new string // to translate. - $this->assertText(new FormattableMarkup('@count modules have been enabled: ', array('@count' => count($all_modules))), 'Modules status has been updated.'); + $this->assertText(new FormattableMarkup('@count modules have been enabled: ', ['@count' => count($all_modules)]), 'Modules status has been updated.'); } /** @@ -217,7 +216,7 @@ public function testInstallUninstall() { * Name of the module to check. */ protected function assertModuleNotInstalled($name) { - $this->assertModules(array($name), FALSE); + $this->assertModules([$name], FALSE); $this->assertModuleTablesDoNotExist($name); } @@ -228,7 +227,7 @@ protected function assertModuleNotInstalled($name) { * Name of the module to check. */ protected function assertModuleSuccessfullyInstalled($name) { - $this->assertModules(array($name), TRUE); + $this->assertModules([$name], TRUE); $this->assertModuleTablesExist($name); $this->assertModuleConfig($name); } @@ -243,19 +242,19 @@ protected function assertModuleSuccessfullyInstalled($name) { * to 'Core'. */ protected function assertSuccessfulUninstall($module, $package = 'Core') { - $edit = array(); + $edit = []; $edit['uninstall[' . $module . ']'] = TRUE; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); $this->drupalPostForm(NULL, NULL, t('Uninstall')); $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.'); - $this->assertModules(array($module), FALSE); + $this->assertModules([$module], FALSE); // Check that the appropriate hook was fired and the appropriate log // message appears. (But don't check for the log message if the dblog // module was just uninstalled, since the {watchdog} table won't be there // anymore.) - $this->assertText(t('hook_modules_uninstalled fired for @module', array('@module' => $module))); - $this->assertLogMessage('system', "%module module uninstalled.", array('%module' => $module), RfcLogLevel::INFO); + $this->assertText(t('hook_modules_uninstalled fired for @module', ['@module' => $module])); + $this->assertLogMessage('system', "%module module uninstalled.", ['%module' => $module], RfcLogLevel::INFO); // Check that the module's database tables no longer exist. $this->assertModuleTablesDoNotExist($module); @@ -276,7 +275,7 @@ protected function assertInstallModuleUpdates($module) { $all_update_functions = $post_update_registry->getPendingUpdateFunctions(); $empty_result = TRUE; foreach ($all_update_functions as $function) { - list($function_module, ) = explode('_post_update_', $function); + list($function_module,) = explode('_post_update_', $function); if ($module === $function_module) { $empty_result = FALSE; break; diff --git a/core/modules/system/src/Tests/Module/ModuleTestBase.php b/core/modules/system/src/Tests/Module/ModuleTestBase.php index e2126170..cc5a7ef2 100644 --- a/core/modules/system/src/Tests/Module/ModuleTestBase.php +++ b/core/modules/system/src/Tests/Module/ModuleTestBase.php @@ -10,6 +10,9 @@ /** * Helper class for module test cases. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\system\Functional\Module\ModuleTestBase instead. */ abstract class ModuleTestBase extends WebTestBase { @@ -18,14 +21,14 @@ abstract class ModuleTestBase extends WebTestBase { * * @var array */ - public static $modules = array('system_test'); + public static $modules = ['system_test']; protected $adminUser; protected function setUp() { parent::setUp(); - $this->adminUser = $this->drupalCreateUser(array('access administration pages', 'administer modules')); + $this->adminUser = $this->drupalCreateUser(['access administration pages', 'administer modules']); $this->drupalLogin($this->adminUser); } @@ -38,13 +41,13 @@ protected function setUp() { * (optional) Whether or not to assert that there are tables that match the * specified base table. Defaults to TRUE. */ - function assertTableCount($base_table, $count = TRUE) { + public function assertTableCount($base_table, $count = TRUE) { $tables = db_find_tables(Database::getConnection()->prefixTables('{' . $base_table . '}') . '%'); if ($count) { - return $this->assertTrue($tables, format_string('Tables matching "@base_table" found.', array('@base_table' => $base_table))); + return $this->assertTrue($tables, format_string('Tables matching "@base_table" found.', ['@base_table' => $base_table])); } - return $this->assertFalse($tables, format_string('Tables matching "@base_table" not found.', array('@base_table' => $base_table))); + return $this->assertFalse($tables, format_string('Tables matching "@base_table" not found.', ['@base_table' => $base_table])); } /** @@ -53,7 +56,7 @@ function assertTableCount($base_table, $count = TRUE) { * @param $module * The name of the module. */ - function assertModuleTablesExist($module) { + public function assertModuleTablesExist($module) { $tables = array_keys(drupal_get_module_schema($module)); $tables_exist = TRUE; foreach ($tables as $table) { @@ -61,7 +64,7 @@ function assertModuleTablesExist($module) { $tables_exist = FALSE; } } - return $this->assertTrue($tables_exist, format_string('All database tables defined by the @module module exist.', array('@module' => $module))); + return $this->assertTrue($tables_exist, format_string('All database tables defined by the @module module exist.', ['@module' => $module])); } /** @@ -70,7 +73,7 @@ function assertModuleTablesExist($module) { * @param $module * The name of the module. */ - function assertModuleTablesDoNotExist($module) { + public function assertModuleTablesDoNotExist($module) { $tables = array_keys(drupal_get_module_schema($module)); $tables_exist = FALSE; foreach ($tables as $table) { @@ -78,7 +81,7 @@ function assertModuleTablesDoNotExist($module) { $tables_exist = TRUE; } } - return $this->assertFalse($tables_exist, format_string('None of the database tables defined by the @module module exist.', array('@module' => $module))); + return $this->assertFalse($tables_exist, format_string('None of the database tables defined by the @module module exist.', ['@module' => $module])); } /** @@ -87,10 +90,12 @@ function assertModuleTablesDoNotExist($module) { * @param string $module * The name of the module. * - * @return bool - * TRUE if configuration has been installed, FALSE otherwise. + * @return bool|null + * TRUE if configuration has been installed, FALSE otherwise. Returns NULL + * if the module configuration directory does not exist or does not contain + * any configuration files. */ - function assertModuleConfig($module) { + public function assertModuleConfig($module) { $module_config_dir = drupal_get_path('module', $module) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY; if (!is_dir($module_config_dir)) { return; @@ -120,7 +125,7 @@ function assertModuleConfig($module) { } // Verify that all configuration has been installed (which means that $names // is empty). - return $this->assertFalse($names, format_string('All default configuration of @module module found.', array('@module' => $module))); + return $this->assertFalse($names, format_string('All default configuration of @module module found.', ['@module' => $module])); } /** @@ -132,9 +137,9 @@ function assertModuleConfig($module) { * @return bool * TRUE if no configuration was found, FALSE otherwise. */ - function assertNoModuleConfig($module) { + public function assertNoModuleConfig($module) { $names = \Drupal::configFactory()->listAll($module . '.'); - return $this->assertFalse($names, format_string('No configuration found for @module module.', array('@module' => $module))); + return $this->assertFalse($names, format_string('No configuration found for @module module.', ['@module' => $module])); } /** @@ -145,7 +150,7 @@ function assertNoModuleConfig($module) { * @param $enabled * Expected module state. */ - function assertModules(array $modules, $enabled) { + public function assertModules(array $modules, $enabled) { $this->rebuildContainer(); foreach ($modules as $module) { if ($enabled) { @@ -154,7 +159,7 @@ function assertModules(array $modules, $enabled) { else { $message = 'Module "@module" is not enabled.'; } - $this->assertEqual($this->container->get('module_handler')->moduleExists($module), $enabled, format_string($message, array('@module' => $module))); + $this->assertEqual($this->container->get('module_handler')->moduleExists($module), $enabled, format_string($message, ['@module' => $module])); } } @@ -178,7 +183,7 @@ function assertModules(array $modules, $enabled) { * @param $link * A link to associate with the message. */ - function assertLogMessage($type, $message, $variables = array(), $severity = RfcLogLevel::NOTICE, $link = '') { + public function assertLogMessage($type, $message, $variables = [], $severity = RfcLogLevel::NOTICE, $link = '') { $count = db_select('watchdog', 'w') ->condition('type', $type) ->condition('message', $message) @@ -188,7 +193,7 @@ function assertLogMessage($type, $message, $variables = array(), $severity = Rfc ->countQuery() ->execute() ->fetchField(); - $this->assertTrue($count > 0, format_string('watchdog table contains @count rows for @message', array('@count' => $count, '@message' => format_string($message, $variables)))); + $this->assertTrue($count > 0, format_string('watchdog table contains @count rows for @message', ['@count' => $count, '@message' => format_string($message, $variables)])); } } diff --git a/core/modules/system/src/Tests/Module/RequiredTest.php b/core/modules/system/src/Tests/Module/RequiredTest.php index 004854ba..a2f3560a 100644 --- a/core/modules/system/src/Tests/Module/RequiredTest.php +++ b/core/modules/system/src/Tests/Module/RequiredTest.php @@ -11,16 +11,16 @@ class RequiredTest extends ModuleTestBase { /** * Assert that core required modules cannot be disabled. */ - function testDisableRequired() { + public function testDisableRequired() { $module_info = system_get_info('module'); $this->drupalGet('admin/modules'); foreach ($module_info as $module => $info) { // Check to make sure the checkbox for each required module is disabled // and checked (or absent from the page if the module is also hidden). if (!empty($info['required'])) { - $field_name = "modules[{$info['package']}][$module][enable]"; + $field_name = 'modules[' . $module . '][enable]'; if (empty($info['hidden'])) { - $this->assertFieldByXPath("//input[@name='$field_name' and @disabled='disabled' and @checked='checked']", '', format_string('Field @name was disabled and checked.', array('@name' => $field_name))); + $this->assertFieldByXPath("//input[@name='$field_name' and @disabled='disabled' and @checked='checked']", '', format_string('Field @name was disabled and checked.', ['@name' => $field_name])); } else { $this->assertNoFieldByName($field_name); diff --git a/core/modules/system/src/Tests/Module/VersionTest.php b/core/modules/system/src/Tests/Module/VersionTest.php index 031d4bad..daad1a66 100644 --- a/core/modules/system/src/Tests/Module/VersionTest.php +++ b/core/modules/system/src/Tests/Module/VersionTest.php @@ -12,8 +12,8 @@ class VersionTest extends ModuleTestBase { /** * Test version dependencies. */ - function testModuleVersions() { - $dependencies = array( + public function testModuleVersions() { + $dependencies = [ // Alternating between being compatible and incompatible with 8.x-2.4-beta3. // The first is always a compatible. 'common_test', @@ -43,12 +43,12 @@ function testModuleVersions() { 'common_test (>2.4-beta2)', // Testing extra version. Incompatible. 'common_test (>2.4-rc0)', - ); + ]; \Drupal::state()->set('system_test.dependencies', $dependencies); $n = count($dependencies); for ($i = 0; $i < $n; $i++) { $this->drupalGet('admin/modules'); - $checkbox = $this->xpath('//input[@id="edit-modules-testing-module-test-enable"]'); + $checkbox = $this->xpath('//input[@id="edit-modules-module-test-enable"]'); $this->assertEqual(!empty($checkbox[0]['disabled']), $i % 2, $dependencies[$i]); } } diff --git a/core/modules/system/src/Tests/Pager/PagerTest.php b/core/modules/system/src/Tests/Pager/PagerTest.php index 4c13c0fa..71413f28 100644 --- a/core/modules/system/src/Tests/Pager/PagerTest.php +++ b/core/modules/system/src/Tests/Pager/PagerTest.php @@ -16,7 +16,7 @@ class PagerTest extends WebTestBase { * * @var array */ - public static $modules = array('dblog', 'pager_test'); + public static $modules = ['dblog', 'pager_test']; /** * A user with permission to access site reports. @@ -36,16 +36,16 @@ protected function setUp() { $logger->debug($this->randomString()); } - $this->adminUser = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser([ 'access site reports', - )); + ]); $this->drupalLogin($this->adminUser); } /** * Tests markup and CSS classes of pager links. */ - function testActiveClass() { + public function testActiveClass() { // Verify first page. $this->drupalGet('admin/reports/dblog'); $current_page = 0; @@ -53,21 +53,21 @@ function testActiveClass() { // Verify any page but first/last. $current_page++; - $this->drupalGet('admin/reports/dblog', array('query' => array('page' => $current_page))); + $this->drupalGet('admin/reports/dblog', ['query' => ['page' => $current_page]]); $this->assertPagerItems($current_page); // Verify last page. - $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--last')); + $elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--last']); preg_match('@page=(\d+)@', $elements[0]['href'], $matches); $current_page = (int) $matches[1]; - $this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], array('external' => TRUE)); + $this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], ['external' => TRUE]); $this->assertPagerItems($current_page); } /** * Test proper functioning of the query parameters and the pager cache context. */ - protected function testPagerQueryParametersAndCacheContext() { + public function testPagerQueryParametersAndCacheContext() { // First page. $this->drupalGet('pager-test/query-parameters'); $this->assertText(t('Pager calls: 0'), 'Initial call to pager shows 0 calls.'); @@ -75,16 +75,16 @@ protected function testPagerQueryParametersAndCacheContext() { $this->assertCacheContext('url.query_args'); // Go to last page, the count of pager calls need to go to 1. - $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--last')); + $elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--last']); $this->drupalGet($this->getAbsoluteUrl($elements[0]['href'])); $this->assertText(t('Pager calls: 1'), 'First link call to pager shows 1 calls.'); $this->assertText('[url.query_args.pagers:0]=0.60'); $this->assertCacheContext('url.query_args'); // Go back to first page, the count of pager calls need to go to 2. - $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--first')); + $elements = $this->xpath('//li[contains(@class, :class)]/a', [':class' => 'pager__item--first']); $this->drupalGet($this->getAbsoluteUrl($elements[0]['href'])); - $this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], array('external' => TRUE)); + $this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], ['external' => TRUE]); $this->assertText(t('Pager calls: 2'), 'Second link call to pager shows 2 calls.'); $this->assertText('[url.query_args.pagers:0]=0.0'); $this->assertCacheContext('url.query_args'); @@ -93,7 +93,7 @@ protected function testPagerQueryParametersAndCacheContext() { /** * Test proper functioning of multiple pagers. */ - protected function testMultiplePagers() { + public function testMultiplePagers() { // First page. $this->drupalGet('pager-test/multiple-pagers'); @@ -203,7 +203,7 @@ public function testPagerEllipsis() { * The current pager page the internal browser is on. */ protected function assertPagerItems($current_page) { - $elements = $this->xpath('//ul[contains(@class, :class)]/li', array(':class' => 'pager__items')); + $elements = $this->xpath('//ul[contains(@class, :class)]/li', [':class' => 'pager__items']); $this->assertTrue(!empty($elements), 'Pager found.'); // Make current page 1-based. diff --git a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php index a527fc5f..71cd7363 100644 --- a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php +++ b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php @@ -47,28 +47,28 @@ public function dropTables(Connection $connection) { * @return array of URL alias definitions. */ public function sampleUrlAliases() { - return array( - array( + return [ + [ 'source' => '/node/1', 'alias' => '/alias_for_node_1_en', 'langcode' => 'en' - ), - array( + ], + [ 'source' => '/node/2', 'alias' => '/alias_for_node_2_en', 'langcode' => 'en' - ), - array( + ], + [ 'source' => '/node/1', 'alias' => '/alias_for_node_1_fr', 'langcode' => 'fr' - ), - array( + ], + [ 'source' => '/node/1', 'alias' => '/alias_for_node_1_und', 'langcode' => 'und' - ) - ); + ] + ]; } @@ -79,7 +79,7 @@ public function sampleUrlAliases() { * Table definitions. */ public function tableDefinition() { - $tables = array(); + $tables = []; // Prime the drupal_get_filename() cache with the location of the system // module as its location is known and shouldn't change. diff --git a/core/modules/system/src/Tests/Render/DisplayVariantTest.php b/core/modules/system/src/Tests/Render/DisplayVariantTest.php deleted file mode 100644 index 09f54d9a..00000000 --- a/core/modules/system/src/Tests/Render/DisplayVariantTest.php +++ /dev/null @@ -1,34 +0,0 @@ -drupalGet(''); - $this->assertRaw('A very important, required value.'); - $this->assertRaw('Explicitly passed in context.'); - $this->assertCacheTag('custom_cache_tag'); - } - -} diff --git a/core/modules/system/src/Tests/Routing/MockAliasManager.php b/core/modules/system/src/Tests/Routing/MockAliasManager.php index 7c7920f4..09f36366 100644 --- a/core/modules/system/src/Tests/Routing/MockAliasManager.php +++ b/core/modules/system/src/Tests/Routing/MockAliasManager.php @@ -14,21 +14,21 @@ class MockAliasManager implements AliasManagerInterface { * * @var array */ - protected $aliases = array(); + protected $aliases = []; /** * Array of mocked aliases. Keys are aliases, followed by language. * * @var array */ - protected $systemPaths = array(); + protected $systemPaths = []; /** * An index of aliases that have been requested. * * @var array */ - protected $lookedUp = array(); + protected $lookedUp = []; /** * The language to assume a path alias is for if not specified. diff --git a/core/modules/system/src/Tests/Routing/MockRouteProvider.php b/core/modules/system/src/Tests/Routing/MockRouteProvider.php index 689fc068..37f88122 100644 --- a/core/modules/system/src/Tests/Routing/MockRouteProvider.php +++ b/core/modules/system/src/Tests/Routing/MockRouteProvider.php @@ -43,7 +43,7 @@ public function getRouteCollectionForRequest(Request $request) { * {@inheritdoc} */ public function getRouteByName($name) { - $routes = $this->getRoutesByNames(array($name)); + $routes = $this->getRoutesByNames([$name]); if (empty($routes)) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); } @@ -62,7 +62,7 @@ public function preLoadRoutes($names) { * {@inheritdoc} */ public function getRoutesByNames($names) { - $routes = array(); + $routes = []; foreach ($names as $name) { $routes[] = $this->routes->get($name); } @@ -88,7 +88,7 @@ public function getAllRoutes() { * {@inheritdoc} */ public function reset() { - $this->routes = array(); + $this->routes = []; } } diff --git a/core/modules/system/src/Tests/Routing/RouterTest.php b/core/modules/system/src/Tests/Routing/RouterTest.php index 1b33bafd..38d7ecbe 100644 --- a/core/modules/system/src/Tests/Routing/RouterTest.php +++ b/core/modules/system/src/Tests/Routing/RouterTest.php @@ -21,7 +21,7 @@ class RouterTest extends WebTestBase { * * @var array */ - public static $modules = array('router_test'); + public static $modules = ['router_test']; /** * Confirms that our FinishResponseSubscriber logic works properly. @@ -45,7 +45,7 @@ public function testFinishResponseSubscriber() { // Check expected headers from FinishResponseSubscriber. $headers = $this->drupalGetHeaders(); $this->assertEqual($headers['x-drupal-cache-contexts'], implode(' ', $expected_cache_contexts)); - $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous rendered'); + $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous http_response rendered'); // Confirm that the page wrapping is being added, so we're not getting a // raw body returned. $this->assertRaw('', 'Page markup was found.'); @@ -60,12 +60,12 @@ public function testFinishResponseSubscriber() { $this->drupalGet('router_test/test18'); $headers = $this->drupalGetHeaders(); $this->assertEqual($headers['x-drupal-cache-contexts'], implode(' ', Cache::mergeContexts($renderer_required_cache_contexts, ['url']))); - $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous foo rendered'); + $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous foo http_response rendered'); // 2. controller result: render array, per-role cacheable route access. $this->drupalGet('router_test/test19'); $headers = $this->drupalGetHeaders(); $this->assertEqual($headers['x-drupal-cache-contexts'], implode(' ', Cache::mergeContexts($renderer_required_cache_contexts, ['url', 'user.roles']))); - $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous foo rendered'); + $this->assertEqual($headers['x-drupal-cache-tags'], 'config:user.role.anonymous foo http_response rendered'); // 3. controller result: Response object, globally cacheable route access. $this->drupalGet('router_test/test1'); $headers = $this->drupalGetHeaders(); @@ -80,12 +80,12 @@ public function testFinishResponseSubscriber() { $this->drupalGet('router_test/test21'); $headers = $this->drupalGetHeaders(); $this->assertEqual($headers['x-drupal-cache-contexts'], ''); - $this->assertEqual($headers['x-drupal-cache-tags'], ''); + $this->assertEqual($headers['x-drupal-cache-tags'], 'http_response'); // 6. controller result: CacheableResponse object, per-role cacheable route access. $this->drupalGet('router_test/test22'); $headers = $this->drupalGetHeaders(); $this->assertEqual($headers['x-drupal-cache-contexts'], 'user.roles'); - $this->assertEqual($headers['x-drupal-cache-tags'], ''); + $this->assertEqual($headers['x-drupal-cache-tags'], 'http_response'); // Finally, verify that the X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags // headers are not sent when their container parameter is set to FALSE. @@ -100,12 +100,40 @@ public function testFinishResponseSubscriber() { $this->assertFalse(isset($headers['x-drupal-cache-tags'])); } + /** + * Confirms that multiple routes with the same path do not cause an error. + */ + public function testDuplicateRoutePaths() { + // Tests two routes with exactly the same path. The route with the maximum + // fit and lowest sorting route name will match, regardless of the order the + // routes are declared. + // @see \Drupal\Core\Routing\RouteProvider::getRoutesByPath() + $this->drupalGet('router-test/duplicate-path2'); + $this->assertResponse(200); + $this->assertRaw('router_test.two_duplicate1'); + + // Tests three routes with same the path. One of the routes the path has a + // different case. + $this->drupalGet('router-test/case-sensitive-duplicate-path3'); + $this->assertResponse(200); + $this->assertRaw('router_test.case_sensitive_duplicate1'); + // While case-insensitive matching works, exact matches are preferred. + $this->drupalGet('router-test/case-sensitive-Duplicate-PATH3'); + $this->assertResponse(200); + $this->assertRaw('router_test.case_sensitive_duplicate2'); + // Test that case-insensitive matching works, falling back to the first + // route defined. + $this->drupalGet('router-test/case-sensitive-Duplicate-Path3'); + $this->assertResponse(200); + $this->assertRaw('router_test.case_sensitive_duplicate1'); + } + /** * Confirms that placeholders in paths work correctly. */ public function testControllerPlaceholders() { // Test with 0 and a random value. - $values = array("0", $this->randomMachineName()); + $values = ["0", $this->randomMachineName()]; foreach ($values as $value) { $this->drupalGet('router_test/test3/' . $value); $this->assertResponse(200); @@ -261,7 +289,7 @@ public function testControllerResolutionAjax() { * Tests that routes no longer exist for a module that has been uninstalled. */ public function testRouterUninstallInstall() { - \Drupal::service('module_installer')->uninstall(array('router_test')); + \Drupal::service('module_installer')->uninstall(['router_test']); \Drupal::service('router.builder')->rebuild(); try { \Drupal::service('router.route_provider')->getRouteByName('router_test.1'); @@ -271,7 +299,7 @@ public function testRouterUninstallInstall() { $this->pass('Route was delete on uninstall.'); } // Install the module again. - \Drupal::service('module_installer')->install(array('router_test')); + \Drupal::service('module_installer')->install(['router_test']); \Drupal::service('router.builder')->rebuild(); $route = \Drupal::service('router.route_provider')->getRouteByName('router_test.1'); $this->assertNotNull($route, 'Route exists after module installation'); diff --git a/core/modules/system/src/Tests/Session/SessionHttpsTest.php b/core/modules/system/src/Tests/Session/SessionHttpsTest.php index 8e25fd26..6ba70da5 100644 --- a/core/modules/system/src/Tests/Session/SessionHttpsTest.php +++ b/core/modules/system/src/Tests/Session/SessionHttpsTest.php @@ -33,7 +33,7 @@ class SessionHttpsTest extends WebTestBase { * * @var array */ - public static $modules = array('session_test'); + public static $modules = ['session_test']; protected function setUp() { parent::setUp(); @@ -50,7 +50,7 @@ protected function setUp() { } public function testHttpsSession() { - $user = $this->drupalCreateUser(array('access administration pages')); + $user = $this->drupalCreateUser(['access administration pages']); // Test HTTPS session handling by altering the form action to submit the // login form through https.php, which creates a mock HTTPS request. @@ -58,7 +58,7 @@ public function testHttpsSession() { // Test a second concurrent session. $this->curlClose(); - $this->curlCookies = array(); + $this->curlCookies = []; $this->loginHttps($user); // Check secure cookie on secure page. @@ -80,7 +80,7 @@ public function testHttpsSession() { // Verify that empty SID cannot be used on the non-secure site. $this->curlClose(); - $this->curlCookies = array($this->insecureSessionName . '='); + $this->curlCookies = [$this->insecureSessionName . '=']; $this->drupalGet($this->httpUrl('admin/config')); $this->assertResponse(403); @@ -88,7 +88,7 @@ public function testHttpsSession() { // login form through http.php, which creates a mock HTTP request on HTTPS // test environments. $this->curlClose(); - $this->curlCookies = array(); + $this->curlCookies = []; $this->loginHttp($user); $this->drupalGet($this->httpUrl('admin/config')); $this->assertResponse(200); @@ -97,12 +97,12 @@ public function testHttpsSession() { // Verify that empty secure SID cannot be used on the secure site. $this->curlClose(); - $this->curlCookies = array($this->secureSessionName . '='); + $this->curlCookies = [$this->secureSessionName . '=']; $this->drupalGet($this->httpsUrl('admin/config')); $this->assertResponse(403); // Clear browser cookie jar. - $this->cookies = array(); + $this->cookies = []; } /** @@ -117,7 +117,7 @@ protected function loginHttp(AccountInterface $account) { // creates a mock HTTP request on HTTPS test environments. $form = $this->xpath('//form[@id="user-login-form"]'); $form[0]['action'] = $this->httpUrl('user/login'); - $edit = array('name' => $account->getUsername(), 'pass' => $account->pass_raw); + $edit = ['name' => $account->getUsername(), 'pass' => $account->pass_raw]; // When posting directly to the HTTP or HTTPS mock front controller, the // location header on the returned response is an absolute URL. That URL @@ -148,7 +148,7 @@ protected function loginHttps(AccountInterface $account) { // creates a mock HTTPS request on HTTP test environments. $form = $this->xpath('//form[@id="user-login-form"]'); $form[0]['action'] = $this->httpsUrl('user/login'); - $edit = array('name' => $account->getUsername(), 'pass' => $account->pass_raw); + $edit = ['name' => $account->getUsername(), 'pass' => $account->pass_raw]; // When posting directly to the HTTP or HTTPS mock front controller, the // location header on the returned response is an absolute URL. That URL @@ -168,7 +168,7 @@ protected function loginHttps(AccountInterface $account) { // necessary to manually collect the session cookie and add it to the // curlCookies property such that it will be used on subsequent requests via // the HTTPS mock. - $this->curlCookies = array($this->secureSessionName . '=' . $this->cookies[$this->secureSessionName]['value']); + $this->curlCookies = [$this->secureSessionName . '=' . $this->cookies[$this->secureSessionName]['value']]; // Follow the location header. $path = $this->getPathFromLocationHeader(TRUE); @@ -215,9 +215,9 @@ protected function getPathFromLocationHeader($https = FALSE, $response_code = 30 * has the given insecure and secure session IDs. */ protected function assertSessionIds($sid, $assertion_text) { - $args = array( + $args = [ ':sid' => Crypt::hashBase64($sid), - ); + ]; return $this->assertTrue(db_query('SELECT timestamp FROM {sessions} WHERE sid = :sid', $args)->fetchField(), $assertion_text); } diff --git a/core/modules/system/src/Tests/Session/SessionTest.php b/core/modules/system/src/Tests/Session/SessionTest.php index 139fba51..1be9561b 100644 --- a/core/modules/system/src/Tests/Session/SessionTest.php +++ b/core/modules/system/src/Tests/Session/SessionTest.php @@ -16,7 +16,7 @@ class SessionTest extends WebTestBase { * * @var array */ - public static $modules = array('session_test'); + public static $modules = ['session_test']; protected $dumpHeaders = TRUE; @@ -24,7 +24,7 @@ class SessionTest extends WebTestBase { * Tests for \Drupal\Core\Session\WriteSafeSessionHandler::setSessionWritable() * ::isSessionWritable and \Drupal\Core\Session\SessionManager::regenerate(). */ - function testSessionSaveRegenerate() { + public function testSessionSaveRegenerate() { $session_handler = $this->container->get('session_handler.write_safe'); $this->assertTrue($session_handler->isSessionWritable(), 'session_handler->isSessionWritable() initially returns TRUE.'); $session_handler->setSessionWritable(FALSE); @@ -48,24 +48,24 @@ function testSessionSaveRegenerate() { $user->name = 'session_test_user'; $user->save(); $this->drupalGet('session-test/id'); - $matches = array(); + $matches = []; preg_match('/\s*session_id:(.*)\n/', $this->getRawContent(), $matches); $this->assertTrue(!empty($matches[1]), 'Found session ID before logging in.'); $original_session = $matches[1]; // We cannot use $this->drupalLogin($user); because we exit in // session_test_user_login() which breaks a normal assertion. - $edit = array( + $edit = [ 'name' => $user->getUsername(), 'pass' => $user->pass_raw - ); + ]; $this->drupalPostForm('user/login', $edit, t('Log in')); $this->drupalGet('user'); - $pass = $this->assertText($user->getUsername(), format_string('Found name: %name', array('%name' => $user->getUsername())), 'User login'); + $pass = $this->assertText($user->getUsername(), format_string('Found name: %name', ['%name' => $user->getUsername()]), 'User login'); $this->_logged_in = $pass; $this->drupalGet('session-test/id'); - $matches = array(); + $matches = []; preg_match('/\s*session_id:(.*)\n/', $this->getRawContent(), $matches); $this->assertTrue(!empty($matches[1]), 'Found session ID after logging in.'); $this->assertTrue($matches[1] != $original_session, 'Session ID changed after login.'); @@ -74,8 +74,8 @@ function testSessionSaveRegenerate() { /** * Test data persistence via the session_test module callbacks. */ - function testDataPersistence() { - $user = $this->drupalCreateUser(array()); + public function testDataPersistence() { + $user = $this->drupalCreateUser([]); // Enable sessions. $this->sessionReset($user->id()); @@ -127,7 +127,7 @@ function testDataPersistence() { $this->assertNoText($value_1, 'Session has persisted for an authenticated user after logging out and then back in.', 'Session'); // Change session and create another user. - $user2 = $this->drupalCreateUser(array()); + $user2 = $this->drupalCreateUser([]); $this->sessionReset($user2->id()); $this->drupalLogin($user2); } @@ -147,7 +147,7 @@ public function testSessionPersistenceOnLogin() { /** * Test that empty anonymous sessions are destroyed. */ - function testEmptyAnonymousSession() { + public function testEmptyAnonymousSession() { // Disable the dynamic_page_cache module; it'd cause session_test's debug // output (that is added in // SessionTestSubscriber::onKernelResponseSessionTest()) to not be added. @@ -210,12 +210,12 @@ function testEmptyAnonymousSession() { /** * Test that sessions are only saved when necessary. */ - function testSessionWrite() { - $user = $this->drupalCreateUser(array()); + public function testSessionWrite() { + $user = $this->drupalCreateUser([]); $this->drupalLogin($user); $sql = 'SELECT u.access, s.timestamp FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.uid = :uid'; - $times1 = db_query($sql, array(':uid' => $user->id()))->fetchObject(); + $times1 = db_query($sql, [':uid' => $user->id()])->fetchObject(); // Before every request we sleep one second to make sure that if the session // is saved, its timestamp will change. @@ -223,34 +223,34 @@ function testSessionWrite() { // Modify the session. sleep(1); $this->drupalGet('session-test/set/foo'); - $times2 = db_query($sql, array(':uid' => $user->id()))->fetchObject(); + $times2 = db_query($sql, [':uid' => $user->id()])->fetchObject(); $this->assertEqual($times2->access, $times1->access, 'Users table was not updated.'); $this->assertNotEqual($times2->timestamp, $times1->timestamp, 'Sessions table was updated.'); // Write the same value again, i.e. do not modify the session. sleep(1); $this->drupalGet('session-test/set/foo'); - $times3 = db_query($sql, array(':uid' => $user->id()))->fetchObject(); + $times3 = db_query($sql, [':uid' => $user->id()])->fetchObject(); $this->assertEqual($times3->access, $times1->access, 'Users table was not updated.'); $this->assertEqual($times3->timestamp, $times2->timestamp, 'Sessions table was not updated.'); // Do not change the session. sleep(1); $this->drupalGet(''); - $times4 = db_query($sql, array(':uid' => $user->id()))->fetchObject(); + $times4 = db_query($sql, [':uid' => $user->id()])->fetchObject(); $this->assertEqual($times4->access, $times3->access, 'Users table was not updated.'); $this->assertEqual($times4->timestamp, $times3->timestamp, 'Sessions table was not updated.'); // Force updating of users and sessions table once per second. $this->settingsSet('session_write_interval', 0); // Write that value also into the test settings.php file. - $settings['settings']['session_write_interval'] = (object) array( + $settings['settings']['session_write_interval'] = (object) [ 'value' => 0, 'required' => TRUE, - ); + ]; $this->writeSettings($settings); $this->drupalGet(''); - $times5 = db_query($sql, array(':uid' => $user->id()))->fetchObject(); + $times5 = db_query($sql, [':uid' => $user->id()])->fetchObject(); $this->assertNotEqual($times5->access, $times4->access, 'Users table was updated.'); $this->assertNotEqual($times5->timestamp, $times4->timestamp, 'Sessions table was updated.'); } @@ -258,15 +258,15 @@ function testSessionWrite() { /** * Test that empty session IDs are not allowed. */ - function testEmptySessionID() { - $user = $this->drupalCreateUser(array()); + public function testEmptySessionID() { + $user = $this->drupalCreateUser([]); $this->drupalLogin($user); $this->drupalGet('session-test/is-logged-in'); $this->assertResponse(200, 'User is logged in.'); // Reset the sid in {sessions} to a blank string. This may exist in the // wild in some cases, although we normally prevent it from happening. - db_query("UPDATE {sessions} SET sid = '' WHERE uid = :uid", array(':uid' => $user->id())); + db_query("UPDATE {sessions} SET sid = '' WHERE uid = :uid", [':uid' => $user->id()]); // Send a blank sid in the session cookie, and the session should no longer // be valid. Closing the curl handler will stop the previous session ID // from persisting. @@ -282,9 +282,10 @@ function testEmptySessionID() { /** * Reset the cookie file so that it refers to the specified user. * - * @param $uid User id to set as the active session. + * @param $uid + * User id to set as the active session. */ - function sessionReset($uid = 0) { + public function sessionReset($uid = 0) { // Close the internal browser. $this->curlClose(); $this->loggedInUser = FALSE; @@ -300,7 +301,7 @@ function sessionReset($uid = 0) { /** * Assert whether the SimpleTest browser sent a session cookie. */ - function assertSessionCookie($sent) { + public function assertSessionCookie($sent) { if ($sent) { $this->assertNotNull($this->sessionId, 'Session cookie was sent.'); } @@ -312,7 +313,7 @@ function assertSessionCookie($sent) { /** * Assert whether $_SESSION is empty at the beginning of the request. */ - function assertSessionEmpty($empty) { + public function assertSessionEmpty($empty) { if ($empty) { $this->assertIdentical($this->drupalGetHeader('X-Session-Empty'), '1', 'Session was empty.'); } diff --git a/core/modules/system/src/Tests/Session/StackSessionHandlerIntegrationTest.php b/core/modules/system/src/Tests/Session/StackSessionHandlerIntegrationTest.php index af962fa5..ac368685 100644 --- a/core/modules/system/src/Tests/Session/StackSessionHandlerIntegrationTest.php +++ b/core/modules/system/src/Tests/Session/StackSessionHandlerIntegrationTest.php @@ -16,7 +16,7 @@ class StackSessionHandlerIntegrationTest extends WebTestBase { * * @var array */ - public static $modules = array('session_test'); + public static $modules = ['session_test']; /** * Tests a request. diff --git a/core/modules/system/src/Tests/System/AccessDeniedTest.php b/core/modules/system/src/Tests/System/AccessDeniedTest.php index 81f9fad1..ba1d5996 100644 --- a/core/modules/system/src/Tests/System/AccessDeniedTest.php +++ b/core/modules/system/src/Tests/System/AccessDeniedTest.php @@ -32,11 +32,11 @@ protected function setUp() { $this->adminUser->roles[] = 'administrator'; $this->adminUser->save(); - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access user profiles')); - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access user profiles')); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access user profiles']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access user profiles']); } - function testAccessDenied() { + public function testAccessDenied() { $this->drupalGet('admin'); $this->assertText(t('Access denied'), 'Found the default 403 page'); $this->assertResponse(403); @@ -65,7 +65,7 @@ function testAccessDenied() { $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration')); // Enable the user login block. - $this->drupalPlaceBlock('user_login_block', array('id' => 'login')); + $block = $this->drupalPlaceBlock('user_login_block', ['id' => 'login']); // Log out and check that the user login block is shown on custom 403 pages. $this->drupalLogout(); @@ -90,17 +90,14 @@ function testAccessDenied() { // Log back in, set the custom 403 page to /user/login and remove the block $this->drupalLogin($this->adminUser); $this->config('system.site')->set('page.403', '/user/login')->save(); - $edit = [ - 'region' => -1, - ]; - $this->drupalPostForm('admin/structure/block/manage/login', $edit, t('Save block')); + $block->disable()->save(); // Check that we can log in from the 403 page. $this->drupalLogout(); - $edit = array( + $edit = [ 'name' => $this->adminUser->getUsername(), 'pass' => $this->adminUser->pass_raw, - ); + ]; $this->drupalPostForm('admin/config/system/site-information', $edit, t('Log in')); // Check that we're still on the same page. diff --git a/core/modules/system/src/Tests/System/AdminMetaTagTest.php b/core/modules/system/src/Tests/System/AdminMetaTagTest.php deleted file mode 100644 index ea92bd93..00000000 --- a/core/modules/system/src/Tests/System/AdminMetaTagTest.php +++ /dev/null @@ -1,23 +0,0 @@ -'; - $this->drupalGet('node'); - $this->assertRaw($string, 'Fingerprinting meta tag generated correctly.', 'System'); - } - -} diff --git a/core/modules/system/src/Tests/System/AdminTest.php b/core/modules/system/src/Tests/System/AdminTest.php index 8921ad0a..7921e1c4 100644 --- a/core/modules/system/src/Tests/System/AdminTest.php +++ b/core/modules/system/src/Tests/System/AdminTest.php @@ -31,7 +31,7 @@ class AdminTest extends WebTestBase { * * @var array */ - public static $modules = array('locale'); + public static $modules = ['locale']; protected function setUp() { // testAdminPages() requires Locale module. @@ -41,17 +41,17 @@ protected function setUp() { // who can only access administration pages and perform some Locale module // administrative tasks, but not all of them. $this->adminUser = $this->drupalCreateUser(array_keys(\Drupal::service('user.permissions')->getPermissions())); - $this->webUser = $this->drupalCreateUser(array( + $this->webUser = $this->drupalCreateUser([ 'access administration pages', 'translate interface', - )); + ]); $this->drupalLogin($this->adminUser); } /** * Tests output on administrative listing pages. */ - function testAdminPages() { + public function testAdminPages() { // Go to Administration. $this->drupalGet('admin'); @@ -69,11 +69,11 @@ function testAdminPages() { // but no links to its individual sub-configuration pages. Also verify that // a user with access to only some Locale module administration pages only // sees links to the pages they have access to. - $admin_list_pages = array( + $admin_list_pages = [ 'admin/index', 'admin/config', 'admin/config/regional', - ); + ]; foreach ($admin_list_pages as $page) { // For the administrator, verify that there are links to Locale's primary @@ -125,14 +125,14 @@ protected function getTopLevelMenuLinks() { $parameters = new MenuTreeParameters(); $parameters->setRoot('system.admin')->excludeRoot()->setTopLevelOnly()->onlyEnabledLinks(); $tree = $menu_tree->load(NULL, $parameters); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:flatten'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:flatten'], + ]; $tree = $menu_tree->transform($tree, $manipulators); // Transform the tree to a list of menu links. - $menu_links = array(); + $menu_links = []; foreach ($tree as $element) { $menu_links[] = $element->link; } @@ -143,7 +143,7 @@ protected function getTopLevelMenuLinks() { /** * Test compact mode. */ - function testCompactMode() { + public function testCompactMode() { // The front page defaults to 'user/login', which redirects to 'user/{user}' // for authenticated users. We cannot use '', since this does not // match the redirected url. @@ -151,7 +151,7 @@ function testCompactMode() { $this->drupalGet('admin/compact/on'); $this->assertResponse(200, 'A valid page is returned after turning on compact mode.'); - $this->assertUrl($frontpage_url, array(), 'The user is redirected to the front page after turning on compact mode.'); + $this->assertUrl($frontpage_url, [], 'The user is redirected to the front page after turning on compact mode.'); $this->assertTrue($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'Compact mode turns on.'); $this->drupalGet('admin/compact/on'); $this->assertTrue($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'Compact mode remains on after a repeat call.'); @@ -160,7 +160,7 @@ function testCompactMode() { $this->drupalGet('admin/compact/off'); $this->assertResponse(200, 'A valid page is returned after turning off compact mode.'); - $this->assertUrl($frontpage_url, array(), 'The user is redirected to the front page after turning off compact mode.'); + $this->assertUrl($frontpage_url, [], 'The user is redirected to the front page after turning off compact mode.'); $this->assertEqual($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'deleted', 'Compact mode turns off.'); $this->drupalGet('admin/compact/off'); $this->assertEqual($this->cookies['Drupal.visitor.admin_compact_mode']['value'], 'deleted', 'Compact mode remains off after a repeat call.'); diff --git a/core/modules/system/src/Tests/System/CronRunTest.php b/core/modules/system/src/Tests/System/CronRunTest.php index ec35b72b..ec4e649b 100644 --- a/core/modules/system/src/Tests/System/CronRunTest.php +++ b/core/modules/system/src/Tests/System/CronRunTest.php @@ -21,7 +21,7 @@ class CronRunTest extends WebTestBase { /** * Test cron runs. */ - function testCronRun() { + public function testCronRun() { // Run cron anonymously without any cron key. $this->drupalGet('cron'); $this->assertResponse(404); @@ -43,11 +43,11 @@ function testCronRun() { * In these tests we do not use REQUEST_TIME to track start time, because we * need the exact time when cron is triggered. */ - function testAutomatedCron() { + public function testAutomatedCron() { // Test with a logged in user; anonymous users likely don't cause Drupal to // fully bootstrap, because of the internal page cache or an external // reverse proxy. Reuse this user for disabling cron later in the test. - $admin_user = $this->drupalCreateUser(array('administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); // Ensure cron does not run when a non-zero cron interval is specified and @@ -83,7 +83,7 @@ function testAutomatedCron() { /** * Make sure exceptions thrown on hook_cron() don't affect other modules. */ - function testCronExceptions() { + public function testCronExceptions() { \Drupal::state()->delete('common_test.cron'); // The common_test module throws an exception. If it isn't caught, the tests // won't finish successfully. @@ -96,8 +96,8 @@ function testCronExceptions() { /** * Make sure the cron UI reads from the state storage. */ - function testCronUI() { - $admin_user = $this->drupalCreateUser(array('administer site configuration')); + public function testCronUI() { + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); $this->drupalGet('admin/config/system/cron'); // Don't use REQUEST to calculate the exact time, because that will @@ -105,23 +105,33 @@ function testCronUI() { // the time will start at 1 January 1970. $this->assertNoText('years'); - $this->drupalPostForm(NULL, [], t('Save configuration')); - $this->assertText(t('The configuration options have been saved.')); + $cron_last = time() - 200; + \Drupal::state()->set('system.cron_last', $cron_last); + + $this->drupalPostForm(NULL, [], 'Save configuration'); + $this->assertText('The configuration options have been saved.'); $this->assertUrl('admin/config/system/cron'); + + // Check that cron does not run when saving the configuration form. + $this->assertEqual($cron_last, \Drupal::state()->get('system.cron_last'), 'Cron does not run when saving the configuration form.'); + + // Check that cron runs when triggered manually. + $this->drupalPostForm(NULL, [], 'Run cron'); + $this->assertTrue($cron_last < \Drupal::state()->get('system.cron_last'), 'Cron runs when triggered manually.'); } /** * Ensure that the manual cron run is working. */ public function testManualCron() { - $admin_user = $this->drupalCreateUser(array('administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); $this->drupalGet('admin/reports/status/run-cron'); $this->assertResponse(403); $this->drupalGet('admin/reports/status'); - $this->clickLink(t('run cron manually')); + $this->clickLink(t('Run cron')); $this->assertResponse(200); $this->assertText(t('Cron ran successfully.')); } diff --git a/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php b/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php index 98d82d36..3edfb7bb 100644 --- a/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php +++ b/core/modules/system/src/Tests/System/DefaultMobileMetaTagsTest.php @@ -20,9 +20,9 @@ class DefaultMobileMetaTagsTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->defaultMetaTags = array( + $this->defaultMetaTags = [ 'viewport' => '', - ); + ]; } /** @@ -31,7 +31,7 @@ protected function setUp() { public function testDefaultMetaTagsExist() { $this->drupalGet(''); foreach ($this->defaultMetaTags as $name => $metatag) { - $this->assertRaw($metatag, SafeMarkup::format('Default Mobile meta tag "@name" displayed properly.', array('@name' => $name)), 'System'); + $this->assertRaw($metatag, SafeMarkup::format('Default Mobile meta tag "@name" displayed properly.', ['@name' => $name]), 'System'); } } @@ -39,10 +39,10 @@ public function testDefaultMetaTagsExist() { * Verifies that the default mobile meta tags can be removed. */ public function testRemovingDefaultMetaTags() { - \Drupal::service('module_installer')->install(array('system_module_test')); + \Drupal::service('module_installer')->install(['system_module_test']); $this->drupalGet(''); foreach ($this->defaultMetaTags as $name => $metatag) { - $this->assertNoRaw($metatag, SafeMarkup::format('Default Mobile meta tag "@name" removed properly.', array('@name' => $name)), 'System'); + $this->assertNoRaw($metatag, SafeMarkup::format('Default Mobile meta tag "@name" removed properly.', ['@name' => $name]), 'System'); } } diff --git a/core/modules/system/src/Tests/System/ErrorHandlerTest.php b/core/modules/system/src/Tests/System/ErrorHandlerTest.php index 113d4955..dc661fec 100644 --- a/core/modules/system/src/Tests/System/ErrorHandlerTest.php +++ b/core/modules/system/src/Tests/System/ErrorHandlerTest.php @@ -17,36 +17,36 @@ class ErrorHandlerTest extends WebTestBase { * * @var array */ - public static $modules = array('error_test'); + public static $modules = ['error_test']; /** * Test the error handler. */ - function testErrorHandler() { + public function testErrorHandler() { $config = $this->config('system.logging'); - $error_notice = array( + $error_notice = [ '%type' => 'Notice', '@message' => 'Undefined variable: bananas', '%function' => 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()', '%file' => drupal_get_path('module', 'error_test') . '/error_test.module', - ); - $error_warning = array( + ]; + $error_warning = [ '%type' => 'Warning', '@message' => 'Division by zero', '%function' => 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()', '%file' => drupal_get_path('module', 'error_test') . '/error_test.module', - ); - $error_user_notice = array( + ]; + $error_user_notice = [ '%type' => 'User warning', '@message' => 'Drupal & awesome', '%function' => 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()', '%file' => drupal_get_path('module', 'error_test') . '/error_test.module', - ); - $fatal_error = array( + ]; + $fatal_error = [ '%type' => 'Recoverable fatal error', '%function' => 'Drupal\error_test\Controller\ErrorTestController->Drupal\error_test\Controller\{closure}()', '@message' => 'Argument 1 passed to Drupal\error_test\Controller\ErrorTestController::Drupal\error_test\Controller\{closure}() must be of the type array, string given, called in ' . \Drupal::root() . '/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php on line 62 and defined', - ); + ]; if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0) { // In PHP 7, instead of a recoverable fatal error we get a TypeError. $fatal_error['%type'] = 'TypeError'; @@ -121,31 +121,31 @@ function testErrorHandler() { /** * Test the exception handler. */ - function testExceptionHandler() { + public function testExceptionHandler() { // Ensure the test error log is empty before these tests. $this->assertNoErrorsLogged(); - $error_exception = array( + $error_exception = [ '%type' => 'Exception', '@message' => 'Drupal & awesome', '%function' => 'Drupal\error_test\Controller\ErrorTestController->triggerException()', '%line' => 56, '%file' => drupal_get_path('module', 'error_test') . '/error_test.module', - ); - $error_pdo_exception = array( + ]; + $error_pdo_exception = [ '%type' => 'DatabaseExceptionWrapper', '@message' => 'SELECT * FROM bananas_are_awesome', '%function' => 'Drupal\error_test\Controller\ErrorTestController->triggerPDOException()', '%line' => 64, '%file' => drupal_get_path('module', 'error_test') . '/error_test.module', - ); - $error_renderer_exception = array( + ]; + $error_renderer_exception = [ '%type' => 'Exception', '@message' => 'This is an exception that occurs during rendering', '%function' => 'Drupal\error_test\Controller\ErrorTestController->Drupal\error_test\Controller\{closure}()', '%line' => 82, '%file' => drupal_get_path('module', 'error_test') . '/error_test.module', - ); + ]; $this->drupalGet('error-test/trigger-exception'); $this->assertTrue(strpos($this->drupalGetHeader(':status'), '500 Service unavailable (with message)'), 'Received expected HTTP status line.'); @@ -158,7 +158,7 @@ function testExceptionHandler() { $this->assertText($error_pdo_exception['%type'], format_string('Found %type in error page.', $error_pdo_exception)); $this->assertText($error_pdo_exception['@message'], format_string('Found @message in error page.', $error_pdo_exception)); $error_details = format_string('in %function (line ', $error_pdo_exception); - $this->assertRaw($error_details, format_string("Found '@message' in error page.", array('@message' => $error_details))); + $this->assertRaw($error_details, format_string("Found '@message' in error page.", ['@message' => $error_details])); $this->drupalGet('error-test/trigger-renderer-exception'); $this->assertTrue(strpos($this->drupalGetHeader(':status'), '500 Service unavailable (with message)'), 'Received expected HTTP status line.'); @@ -183,17 +183,17 @@ function testExceptionHandler() { /** * Helper function: assert that the error message is found. */ - function assertErrorMessage(array $error) { + public function assertErrorMessage(array $error) { $message = new FormattableMarkup('%type: @message in %function (line ', $error); - $this->assertRaw($message, format_string('Found error message: @message.', array('@message' => $message))); + $this->assertRaw($message, format_string('Found error message: @message.', ['@message' => $message])); } /** * Helper function: assert that the error message is not found. */ - function assertNoErrorMessage(array $error) { + public function assertNoErrorMessage(array $error) { $message = new FormattableMarkup('%type: @message in %function (line ', $error); - $this->assertNoRaw($message, format_string('Did not find error message: @message.', array('@message' => $message))); + $this->assertNoRaw($message, format_string('Did not find error message: @message.', ['@message' => $message])); } /** diff --git a/core/modules/system/src/Tests/System/FloodTest.php b/core/modules/system/src/Tests/System/FloodTest.php index a3a33683..bba30324 100644 --- a/core/modules/system/src/Tests/System/FloodTest.php +++ b/core/modules/system/src/Tests/System/FloodTest.php @@ -34,8 +34,9 @@ public function testCleanUp() { $window_expired = -1; $name = 'flood_test_cleanup'; - // Register expired event. $flood = \Drupal::flood(); + $this->assertTrue($flood->isAllowed($name, $threshold)); + // Register expired event. $flood->register($name, $window_expired); // Verify event is not allowed. $this->assertFalse($flood->isAllowed($name, $threshold)); @@ -62,6 +63,7 @@ public function testMemoryBackend() { $request_stack = \Drupal::service('request_stack'); $flood = new MemoryBackend($request_stack); + $this->assertTrue($flood->isAllowed($name, $threshold)); // Register expired event. $flood->register($name, $window_expired); // Verify event is not allowed. @@ -90,6 +92,7 @@ public function testDatabaseBackend() { $connection = \Drupal::service('database'); $request_stack = \Drupal::service('request_stack'); $flood = new DatabaseBackend($connection, $request_stack); + $this->assertTrue($flood->isAllowed($name, $threshold)); // Register expired event. $flood->register($name, $window_expired); // Verify event is not allowed. diff --git a/core/modules/system/src/Tests/System/FrontPageTest.php b/core/modules/system/src/Tests/System/FrontPageTest.php index 03666fdf..9f39b4b2 100644 --- a/core/modules/system/src/Tests/System/FrontPageTest.php +++ b/core/modules/system/src/Tests/System/FrontPageTest.php @@ -17,7 +17,7 @@ class FrontPageTest extends WebTestBase { * * @var array */ - public static $modules = array('node', 'system_test', 'views'); + public static $modules = ['node', 'system_test', 'views']; /** * The path to a node that is created for testing. @@ -30,12 +30,12 @@ protected function setUp() { parent::setUp(); // Create admin user, log in admin user, and create one node. - $this->drupalLogin ($this->drupalCreateUser(array( + $this->drupalLogin($this->drupalCreateUser([ 'access content', 'administer site configuration', - ))); - $this->drupalCreateContentType(array('type' => 'page')); - $this->nodePath = "node/" . $this->drupalCreateNode(array('promote' => 1))->id(); + ])); + $this->drupalCreateContentType(['type' => 'page']); + $this->nodePath = "node/" . $this->drupalCreateNode(['promote' => 1])->id(); // Configure 'node' as front page. $this->config('system.site')->set('page.front', '/node')->save(); @@ -48,10 +48,10 @@ protected function setUp() { */ public function testDrupalFrontPage() { // Create a promoted node to test the tag on the front page view. - $settings = array( + $settings = [ 'title' => $this->randomMachineName(8), 'promote' => 1, - ); + ]; $this->drupalCreateNode($settings); $this->drupalGet(''); $this->assertTitle('Home | Drupal'); @@ -63,9 +63,9 @@ public function testDrupalFrontPage() { $this->assertNoText(t('On front page.'), 'Path is not the front page.'); // Change the front page to an invalid path. - $edit = array('site_frontpage' => '/kittens'); + $edit = ['site_frontpage' => '/kittens']; $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration')); - $this->assertText(t("The path '@path' is either invalid or you do not have access to it.", array('@path' => $edit['site_frontpage']))); + $this->assertText(t("The path '@path' is either invalid or you do not have access to it.", ['@path' => $edit['site_frontpage']])); // Change the front page to a path without a starting slash. $edit = ['site_frontpage' => $this->nodePath]; diff --git a/core/modules/system/src/Tests/System/HtaccessTest.php b/core/modules/system/src/Tests/System/HtaccessTest.php index ad6e09ee..fab7a37a 100644 --- a/core/modules/system/src/Tests/System/HtaccessTest.php +++ b/core/modules/system/src/Tests/System/HtaccessTest.php @@ -16,7 +16,7 @@ class HtaccessTest extends WebTestBase { * * @var array */ - public static $modules = array('node', 'path'); + public static $modules = ['node', 'path']; /** * Get an array of file paths for access testing. diff --git a/core/modules/system/src/Tests/System/IndexPhpTest.php b/core/modules/system/src/Tests/System/IndexPhpTest.php deleted file mode 100644 index 72811a8a..00000000 --- a/core/modules/system/src/Tests/System/IndexPhpTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -namespace Drupal\system\Tests\System; - -use Drupal\simpletest\WebTestBase; - -/** - * Tests the handling of requests containing 'index.php'. - * - * @group system - */ -class IndexPhpTest extends WebTestBase { - protected function setUp() { - parent::setUp(); - } - - /** - * Test index.php handling. - */ - function testIndexPhpHandling() { - $index_php = $GLOBALS['base_url'] . '/index.php'; - - $this->drupalGet($index_php, array('external' => TRUE)); - $this->assertResponse(200, 'Make sure index.php returns a valid page.'); - - $this->drupalGet($index_php . '/user', array('external' => TRUE)); - $this->assertResponse(200, 'Make sure index.php/user returns a valid page.'); - } - -} diff --git a/core/modules/system/src/Tests/System/PageNotFoundTest.php b/core/modules/system/src/Tests/System/PageNotFoundTest.php index f289f0e4..b1a88d82 100644 --- a/core/modules/system/src/Tests/System/PageNotFoundTest.php +++ b/core/modules/system/src/Tests/System/PageNotFoundTest.php @@ -26,15 +26,15 @@ protected function setUp() { parent::setUp(); // Create an administrative user. - $this->adminUser = $this->drupalCreateUser(array('administer site configuration', 'link to any page')); + $this->adminUser = $this->drupalCreateUser(['administer site configuration', 'link to any page']); $this->adminUser->roles[] = 'administrator'; $this->adminUser->save(); - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access user profiles')); - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access user profiles')); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access user profiles']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access user profiles']); } - function testPageNotFound() { + public function testPageNotFound() { $this->drupalLogin($this->adminUser); $this->drupalGet($this->randomMachineName(10)); $this->assertText(t('Page not found'), 'Found the default 404 page'); @@ -47,9 +47,9 @@ function testPageNotFound() { $this->assertRaw(SafeMarkup::format("The path '%path' has to start with a slash.", ['%path' => $edit['site_404']])); // Use a custom 404 page. - $edit = array( + $edit = [ 'site_404' => '/user/' . $this->adminUser->id(), - ); + ]; $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration')); $this->drupalGet($this->randomMachineName(10)); diff --git a/core/modules/system/src/Tests/System/PageTitleTest.php b/core/modules/system/src/Tests/System/PageTitleTest.php index 848eacc8..44e33cb6 100644 --- a/core/modules/system/src/Tests/System/PageTitleTest.php +++ b/core/modules/system/src/Tests/System/PageTitleTest.php @@ -29,24 +29,24 @@ class PageTitleTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); $this->drupalPlaceBlock('page_title_block'); - $this->contentUser = $this->drupalCreateUser(array('create page content', 'access content', 'administer themes', 'administer site configuration', 'link to any page')); + $this->contentUser = $this->drupalCreateUser(['create page content', 'access content', 'administer themes', 'administer site configuration', 'link to any page']); $this->drupalLogin($this->contentUser); } /** * Tests the handling of HTML in node titles. */ - function testTitleTags() { + public function testTitleTags() { $title = "string with <em>HTML</em>"; // Generate node content. - $edit = array( + $edit = [ 'title[0][value]' => '!SimpleTest! ' . $title . $this->randomMachineName(20), 'body[0][value]' => '!SimpleTest! test body' . $this->randomMachineName(200), - ); + ]; // Create the node with HTML in the title. $this->drupalPostForm('node/add/page', $edit, t('Save')); @@ -60,7 +60,7 @@ function testTitleTags() { /** * Test if the title of the site is XSS proof. */ - function testTitleXSS() { + public function testTitleXSS() { // Set some title with JavaScript and HTML chars to escape. $title = ' & < > " \' '; $title_filtered = Html::escape($title); @@ -69,10 +69,10 @@ function testTitleXSS() { $slogan_filtered = Xss::filterAdmin($slogan); // Set title and slogan. - $edit = array( + $edit = [ 'site_name' => $title, 'site_slogan' => $slogan, - ); + ]; $this->drupalPostForm('admin/config/system/site-information', $edit, t('Save configuration')); // Place branding block with site name and slogan into header region. @@ -113,9 +113,9 @@ public function testRoutingTitle() { $this->assertEqual('Test dynamic title', (string) $result[0]); // Set some custom translated strings. - $this->addCustomTranslations('en', array('' => array( - 'Static title' => 'Static title translated' - ))); + $this->addCustomTranslations('en', [ + '' => ['Static title' => 'Static title translated'], + ]); $this->writeCustomTranslations(); // Ensure that the title got translated. diff --git a/core/modules/system/src/Tests/System/ResponseGeneratorTest.php b/core/modules/system/src/Tests/System/ResponseGeneratorTest.php index f54c6516..a535b66c 100644 --- a/core/modules/system/src/Tests/System/ResponseGeneratorTest.php +++ b/core/modules/system/src/Tests/System/ResponseGeneratorTest.php @@ -16,14 +16,14 @@ class ResponseGeneratorTest extends RESTTestBase { * * @var array */ - public static $modules = array('hal', 'rest', 'node', 'basic_auth'); + public static $modules = ['hal', 'rest', 'node', 'basic_auth']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); $permissions = $this->entityPermissions('node', 'view'); $account = $this->drupalCreateUser($permissions); @@ -33,7 +33,7 @@ protected function setUp() { /** * Test to see if generator header is added. */ - function testGeneratorHeaderAdded() { + public function testGeneratorHeaderAdded() { $node = $this->drupalCreateNode(); diff --git a/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php b/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php index 99839aba..50fae036 100644 --- a/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php +++ b/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php @@ -16,7 +16,7 @@ class ShutdownFunctionsTest extends WebTestBase { * * @var array */ - public static $modules = array('system_test'); + public static $modules = ['system_test']; protected function tearDown() { // This test intentionally throws an exception in a PHP shutdown function. @@ -29,7 +29,7 @@ protected function tearDown() { /** * Test shutdown functions. */ - function testShutdownFunctions() { + public function testShutdownFunctions() { $arg1 = $this->randomMachineName(); $arg2 = $this->randomMachineName(); $this->drupalGet('system-test/shutdown-functions/' . $arg1 . '/' . $arg2); @@ -42,8 +42,8 @@ function testShutdownFunctions() { // We need to wait to ensure that the shutdown functions have fired. sleep(1); } - $this->assertEqual(\Drupal::state()->get('_system_test_first_shutdown_function'), array($arg1, $arg2)); - $this->assertEqual(\Drupal::state()->get('_system_test_second_shutdown_function'), array($arg1, $arg2)); + $this->assertEqual(\Drupal::state()->get('_system_test_first_shutdown_function'), [$arg1, $arg2]); + $this->assertEqual(\Drupal::state()->get('_system_test_second_shutdown_function'), [$arg1, $arg2]); if (!$server_using_fastcgi) { // Make sure exceptions displayed through diff --git a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php index 49aff66e..e269a6c7 100644 --- a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php +++ b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php @@ -17,7 +17,7 @@ class SiteMaintenanceTest extends WebTestBase { * * @var array */ - public static $modules = array('node'); + public static $modules = ['node']; protected $adminUser; @@ -29,33 +29,42 @@ protected function setUp() { $this->config('system.performance')->set('js.preprocess', 1)->save(); // Create a user allowed to access site in maintenance mode. - $this->user = $this->drupalCreateUser(array('access site in maintenance mode')); + $this->user = $this->drupalCreateUser(['access site in maintenance mode']); // Create an administrative user. - $this->adminUser = $this->drupalCreateUser(array('administer site configuration', 'access site in maintenance mode')); + $this->adminUser = $this->drupalCreateUser(['administer site configuration', 'access site in maintenance mode']); $this->drupalLogin($this->adminUser); } /** * Verifies site maintenance mode functionality. */ - protected function testSiteMaintenance() { + public function testSiteMaintenance() { + + // Verify that permission message is displayed. + $permission_handler = $this->container->get('user.permissions'); + $permissions = $permission_handler->getPermissions(); + $permission_label = $permissions['access site in maintenance mode']['title']; + $permission_message = t('Visitors will only see the maintenance mode message. Only users with the "@permission-label" permission will be able to access the site. Authorized users can log in directly via the user login page.', ['@permission-label' => $permission_label, ':permissions-url' => \Drupal::url('user.admin_permissions'), ':user-login' => \Drupal::url('user.login')]); + $this->drupalGet(Url::fromRoute('system.site_maintenance_mode')); + $this->assertRaw($permission_message, 'Found the permission message.'); + $this->drupalGet(Url::fromRoute('user.page')); // JS should be aggregated, so drupal.js is not in the page source. - $links = $this->xpath('//script[contains(@src, :href)]', array(':href' => '/core/misc/drupal.js')); + $links = $this->xpath('//script[contains(@src, :href)]', [':href' => '/core/misc/drupal.js']); $this->assertFalse(isset($links[0]), 'script /core/misc/drupal.js not in page'); // Turn on maintenance mode. - $edit = array( + $edit = [ 'maintenance_mode' => 1, - ); + ]; $this->drupalPostForm('admin/config/development/maintenance', $edit, t('Save configuration')); - $admin_message = t('Operating in maintenance mode. Go online.', array(':url' => \Drupal::url('system.site_maintenance_mode'))); + $admin_message = t('Operating in maintenance mode. Go online.', [':url' => \Drupal::url('system.site_maintenance_mode')]); $user_message = t('Operating in maintenance mode.'); - $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => $this->config('system.site')->get('name'))); + $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', ['@site' => $this->config('system.site')->get('name')]); $this->drupalGet(Url::fromRoute('user.page')); // JS should not be aggregated, so drupal.js is expected in the page source. - $links = $this->xpath('//script[contains(@src, :href)]', array(':href' => '/core/misc/drupal.js')); + $links = $this->xpath('//script[contains(@src, :href)]', [':href' => '/core/misc/drupal.js']); $this->assertTrue(isset($links[0]), 'script /core/misc/drupal.js in page'); $this->assertRaw($admin_message, 'Found the site maintenance mode message.'); @@ -79,10 +88,10 @@ protected function testSiteMaintenance() { // Log in user and verify that maintenance mode message is displayed // directly after login. - $edit = array( + $edit = [ 'name' => $this->user->getUsername(), 'pass' => $this->user->pass_raw, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Log in')); $this->assertText($user_message); @@ -93,9 +102,9 @@ protected function testSiteMaintenance() { $this->assertNoRaw($admin_message, 'Site maintenance mode message not displayed.'); $offline_message = 'Sorry, not online.'; - $edit = array( + $edit = [ 'maintenance_mode_message' => $offline_message, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save configuration')); // Logout and verify that custom site offline message is displayed. @@ -109,21 +118,21 @@ protected function testSiteMaintenance() { $this->assertText(t('Username or email address'), 'Anonymous users can access user/password'); // Submit password reset form. - $edit = array( + $edit = [ 'name' => $this->user->getUsername(), - ); + ]; $this->drupalPostForm('user/password', $edit, t('Submit')); $mails = $this->drupalGetMails(); $start = strpos($mails[0]['body'], 'user/reset/' . $this->user->id()); $path = substr($mails[0]['body'], $start, 66 + strlen($this->user->id())); // Log in with temporary login link. - $this->drupalPostForm($path, array(), t('Log in')); + $this->drupalPostForm($path, [], t('Log in')); $this->assertText($user_message); // Regression test to check if title displays in Bartik on maintenance page. - \Drupal::service('theme_handler')->install(array('bartik')); - \Drupal::service('theme_handler')->setDefault('bartik'); + \Drupal::service('theme_handler')->install(['bartik']); + $this->config('system.theme')->set('default', 'bartik')->save(); // Logout and verify that offline message is displayed in Bartik. $this->drupalLogout(); diff --git a/core/modules/system/src/Tests/System/StatusTest.php b/core/modules/system/src/Tests/System/StatusTest.php deleted file mode 100644 index c1703166..00000000 --- a/core/modules/system/src/Tests/System/StatusTest.php +++ /dev/null @@ -1,94 +0,0 @@ - (object) array( - 'value' => '', - 'required' => TRUE, - ), - ); - $this->writeSettings($settings); - - $admin_user = $this->drupalCreateUser(array( - 'administer site configuration', - )); - $this->drupalLogin($admin_user); - } - - /** - * Tests that the status page returns. - */ - public function testStatusPage() { - // Go to Administration. - $this->drupalGet('admin/reports/status'); - $this->assertResponse(200, 'The status page is reachable.'); - - $phpversion = phpversion(); - $this->assertText($phpversion, 'Php version is shown on the page.'); - - // Checks if the suggestion to update to php 5.5.21 or 5.6.5 for disabling - // multiple statements is present when necessary. - if (\Drupal::database()->driver() === 'mysql' && !SystemRequirements::phpVersionWithPdoDisallowMultipleStatements($phpversion)) { - $this->assertText(t('PHP (multiple statement disabling)')); - } - else { - $this->assertNoText(t('PHP (multiple statement disabling)')); - } - - if (function_exists('phpinfo')) { - $this->assertLinkByHref(Url::fromRoute('system.php')->toString()); - } - else { - $this->assertNoLinkByHref(Url::fromRoute('system.php')->toString()); - } - - // If a module is fully installed no pending updates exists. - $this->assertNoText(t('Out of date')); - - // The global $config_directories is not properly formed. - $this->assertRaw(t('Your %file file must define the $config_directories variable as an array containing the names of directories in which configuration files can be found. It must contain a %sync_key key.', array('%file' => $this->siteDirectory . '/settings.php', '%sync_key' => CONFIG_SYNC_DIRECTORY))); - - // Set the schema version of update_test_postupdate to a lower version, so - // update_test_postupdate_update_8001() needs to be executed. - drupal_set_installed_schema_version('update_test_postupdate', 8000); - $this->drupalGet('admin/reports/status'); - $this->assertText(t('Out of date')); - - // Now cleanup the executed post update functions. - drupal_set_installed_schema_version('update_test_postupdate', 8001); - /** @var \Drupal\Core\Update\UpdateRegistry $post_update_registry */ - $post_update_registry = \Drupal::service('update.post_update_registry'); - $post_update_registry->filterOutInvokedUpdatesByModule('update_test_postupdate'); - $this->drupalGet('admin/reports/status'); - $this->assertText(t('Out of date')); - - $this->drupalGet('admin/reports/status/php'); - $this->assertResponse(200, 'The phpinfo page is reachable.'); - } - -} diff --git a/core/modules/system/src/Tests/System/SystemConfigFormTestBase.php b/core/modules/system/src/Tests/System/SystemConfigFormTestBase.php index 08f741d8..a14fd310 100644 --- a/core/modules/system/src/Tests/System/SystemConfigFormTestBase.php +++ b/core/modules/system/src/Tests/System/SystemConfigFormTestBase.php @@ -43,7 +43,7 @@ abstract class SystemConfigFormTestBase extends WebTestBase { */ public function testConfigForm() { // Programmatically submit the given values. - $values = array(); + $values = []; foreach ($this->values as $form_key => $data) { $values[$form_key] = $data['#value']; } @@ -53,10 +53,10 @@ public function testConfigForm() { // Check that the form returns an error when expected, and vice versa. $errors = $form_state->getErrors(); $valid_form = empty($errors); - $args = array( + $args = [ '%values' => print_r($values, TRUE), '%errors' => $valid_form ? t('None') : implode(' ', $errors), - ); + ]; $this->assertTrue($valid_form, format_string('Input values: %values
    Validation handler errors: %errors', $args)); foreach ($this->values as $data) { diff --git a/core/modules/system/src/Tests/System/ThemeTest.php b/core/modules/system/src/Tests/System/ThemeTest.php index e01f28a4..29d88a37 100644 --- a/core/modules/system/src/Tests/System/ThemeTest.php +++ b/core/modules/system/src/Tests/System/ThemeTest.php @@ -30,9 +30,9 @@ class ThemeTest extends WebTestBase { protected function setUp() { parent::setUp(); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); - $this->adminUser = $this->drupalCreateUser(array('access administration pages', 'view the administration theme', 'administer themes', 'bypass node access', 'administer blocks')); + $this->adminUser = $this->drupalCreateUser(['access administration pages', 'view the administration theme', 'administer themes', 'bypass node access', 'administer blocks']); $this->drupalLogin($this->adminUser); $this->node = $this->drupalCreateNode(); $this->drupalPlaceBlock('local_tasks_block'); @@ -41,7 +41,7 @@ protected function setUp() { /** * Test the theme settings form. */ - function testThemeSettings() { + public function testThemeSettings() { // Ensure invalid theme settings form URLs return a proper 404. $this->drupalGet('admin/appearance/settings/bartik'); $this->assertResponse(404, 'The theme settings form URL for a uninstalled theme could not be found.'); @@ -53,50 +53,50 @@ function testThemeSettings() { // Specify a filesystem path to be used for the logo. $file = current($this->drupalGetTestFiles('image')); - $file_relative = strtr($file->uri, array('public:/' => PublicStream::basePath())); + $file_relative = strtr($file->uri, ['public:/' => PublicStream::basePath()]); $default_theme_path = 'core/themes/classy'; - $supported_paths = array( + $supported_paths = [ // Raw stream wrapper URI. - $file->uri => array( + $file->uri => [ 'form' => file_uri_target($file->uri), 'src' => file_url_transform_relative(file_create_url($file->uri)), - ), + ], // Relative path within the public filesystem. - file_uri_target($file->uri) => array( + file_uri_target($file->uri) => [ 'form' => file_uri_target($file->uri), 'src' => file_url_transform_relative(file_create_url($file->uri)), - ), + ], // Relative path to a public file. - $file_relative => array( + $file_relative => [ 'form' => $file_relative, 'src' => file_url_transform_relative(file_create_url($file->uri)), - ), + ], // Relative path to an arbitrary file. - 'core/misc/druplicon.png' => array( + 'core/misc/druplicon.png' => [ 'form' => 'core/misc/druplicon.png', 'src' => base_path() . 'core/misc/druplicon.png', - ), + ], // Relative path to a file in a theme. - $default_theme_path . '/logo.svg' => array( + $default_theme_path . '/logo.svg' => [ 'form' => $default_theme_path . '/logo.svg', 'src' => base_path() . $default_theme_path . '/logo.svg', - ), - ); + ], + ]; foreach ($supported_paths as $input => $expected) { - $edit = array( + $edit = [ 'default_logo' => FALSE, 'logo_path' => $input, - ); + ]; $this->drupalPostForm('admin/appearance/settings', $edit, t('Save configuration')); $this->assertNoText('The custom logo path is invalid.'); $this->assertFieldByName('logo_path', $expected['form']); // Verify logo path examples. - $elements = $this->xpath('//div[contains(@class, :item)]/div[@class=:description]/code', array( + $elements = $this->xpath('//div[contains(@class, :item)]/div[@class=:description]/code', [ ':item' => 'js-form-item-logo-path', ':description' => 'description', - )); + ]); // Expected default values (if all else fails). $implicit_public_file = 'logo.svg'; $explicit_file = 'public://logo.svg'; @@ -105,7 +105,7 @@ function testThemeSettings() { if (file_uri_scheme($input) == 'public') { $implicit_public_file = file_uri_target($input); $explicit_file = $input; - $local_file = strtr($input, array('public:/' => PublicStream::basePath())); + $local_file = strtr($input, ['public:/' => PublicStream::basePath()]); } // Adjust for fully qualified stream wrapper URI elsewhere. elseif (file_uri_scheme($input) !== FALSE) { @@ -125,13 +125,13 @@ function testThemeSettings() { // branding block. $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']); $this->drupalGet(''); - $elements = $this->xpath('//header//a[@rel=:rel]/img', array( + $elements = $this->xpath('//header//a[@rel=:rel]/img', [ ':rel' => 'home', - ) + ] ); $this->assertEqual((string) $elements[0]['src'], $expected['src']); } - $unsupported_paths = array( + $unsupported_paths = [ // Stream wrapper URI to non-existing file. 'public://whatever.png', 'private://whatever.png', @@ -153,23 +153,23 @@ function testThemeSettings() { '/core/misc/whatever.png', // Absolute paths to any local file (even if it exists). drupal_realpath($file->uri), - ); + ]; $this->drupalGet('admin/appearance/settings'); foreach ($unsupported_paths as $path) { - $edit = array( + $edit = [ 'default_logo' => FALSE, 'logo_path' => $path, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save configuration')); $this->assertText('The custom logo path is invalid.'); } // Upload a file to use for the logo. - $edit = array( + $edit = [ 'default_logo' => FALSE, 'logo_path' => '', 'files[logo_upload]' => drupal_realpath($file->uri), - ); + ]; $this->drupalPostForm('admin/appearance/settings', $edit, t('Save configuration')); $fields = $this->xpath($this->constructFieldXpath('name', 'logo_path')); @@ -177,13 +177,13 @@ function testThemeSettings() { $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']); $this->drupalGet(''); - $elements = $this->xpath('//header//a[@rel=:rel]/img', array( + $elements = $this->xpath('//header//a[@rel=:rel]/img', [ ':rel' => 'home', - ) + ] ); $this->assertEqual($elements[0]['src'], file_url_transform_relative(file_create_url($uploaded_filename))); - $this->container->get('theme_handler')->install(array('bartik')); + $this->container->get('theme_handler')->install(['bartik']); // Ensure only valid themes are listed in the local tasks. $this->drupalPlaceBlock('local_tasks_block', ['region' => 'header']); @@ -218,7 +218,7 @@ function testThemeSettings() { /** * Test the theme settings logo form. */ - function testThemeSettingsLogo() { + public function testThemeSettingsLogo() { // Visit Bartik's theme settings page to replace the logo. $this->container->get('theme_handler')->install(['bartik']); $this->drupalGet('admin/appearance/settings/bartik'); @@ -241,14 +241,14 @@ function testThemeSettingsLogo() { /** * Test the administration theme functionality. */ - function testAdministrationTheme() { - $this->container->get('theme_handler')->install(array('seven')); + public function testAdministrationTheme() { + $this->container->get('theme_handler')->install(['seven']); // Install an administration theme and show it on the node admin pages. - $edit = array( + $edit = [ 'admin_theme' => 'seven', 'use_admin_theme' => TRUE, - ); + ]; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); $this->drupalGet('admin/config'); @@ -264,9 +264,9 @@ function testAdministrationTheme() { $this->assertRaw('core/themes/seven', 'Administration theme used on the edit content page.'); // Disable the admin theme on the node admin pages. - $edit = array( + $edit = [ 'use_admin_theme' => FALSE, - ); + ]; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); $this->drupalGet('admin/config'); @@ -284,10 +284,10 @@ function testAdministrationTheme() { $this->assertRaw('core/themes/classy', 'Site default theme used on the add content page.'); // Reset to the default theme settings. - $edit = array( + $edit = [ 'admin_theme' => '0', 'use_admin_theme' => FALSE, - ); + ]; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); $this->drupalGet('admin'); @@ -300,15 +300,15 @@ function testAdministrationTheme() { /** * Test switching the default theme. */ - function testSwitchDefaultTheme() { + public function testSwitchDefaultTheme() { /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */ $theme_handler = \Drupal::service('theme_handler'); // First, install Stark and set it as the default theme programmatically. - $theme_handler->install(array('stark')); - $theme_handler->setDefault('stark'); + $theme_handler->install(['stark']); + $this->config('system.theme')->set('default', 'stark')->save(); // Install Bartik and set it as the default theme. - $theme_handler->install(array('bartik')); + $theme_handler->install(['bartik']); $this->drupalGet('admin/appearance'); $this->clickLink(t('Set as default')); $this->assertEqual($this->config('system.theme')->get('default'), 'bartik'); @@ -330,15 +330,15 @@ function testSwitchDefaultTheme() { * Include test for themes that have a missing base theme somewhere further up * the chain than the immediate base theme. */ - function testInvalidTheme() { + public function testInvalidTheme() { // theme_page_test_system_info_alter() un-hides all hidden themes. - $this->container->get('module_installer')->install(array('theme_page_test')); + $this->container->get('module_installer')->install(['theme_page_test']); // Clear the system_list() and theme listing cache to pick up the change. $this->container->get('theme_handler')->reset(); $this->drupalGet('admin/appearance'); - $this->assertText(t('This theme requires the base theme @base_theme to operate correctly.', array('@base_theme' => 'not_real_test_basetheme'))); - $this->assertText(t('This theme requires the base theme @base_theme to operate correctly.', array('@base_theme' => 'test_invalid_basetheme'))); - $this->assertText(t('This theme requires the theme engine @theme_engine to operate correctly.', array('@theme_engine' => 'not_real_engine'))); + $this->assertText(t('This theme requires the base theme @base_theme to operate correctly.', ['@base_theme' => 'not_real_test_basetheme'])); + $this->assertText(t('This theme requires the base theme @base_theme to operate correctly.', ['@base_theme' => 'test_invalid_basetheme'])); + $this->assertText(t('This theme requires the theme engine @theme_engine to operate correctly.', ['@theme_engine' => 'not_real_engine'])); // Check for the error text of a theme with the wrong core version. $this->assertText("This theme is not compatible with Drupal 8.x. Check that the .info.yml file contains the correct 'core' value."); // Check for the error text of a theme without a content region. @@ -348,15 +348,15 @@ function testInvalidTheme() { /** * Test uninstalling of themes works. */ - function testUninstallingThemes() { + public function testUninstallingThemes() { // Install Bartik and set it as the default theme. - \Drupal::service('theme_handler')->install(array('bartik')); + \Drupal::service('theme_handler')->install(['bartik']); // Set up seven as the admin theme. - \Drupal::service('theme_handler')->install(array('seven')); - $edit = array( + \Drupal::service('theme_handler')->install(['seven']); + $edit = [ 'admin_theme' => 'seven', 'use_admin_theme' => TRUE, - ); + ]; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); $this->drupalGet('admin/appearance'); $this->clickLink(t('Set as default')); @@ -370,12 +370,12 @@ function testUninstallingThemes() { $this->assertNoRaw('Uninstall Classy theme', 'A link to uninstall the Classy theme does not appear on the theme settings page.'); // Install Stark and set it as the default theme. - \Drupal::service('theme_handler')->install(array('stark')); + \Drupal::service('theme_handler')->install(['stark']); - $edit = array( + $edit = [ 'admin_theme' => 'stark', 'use_admin_theme' => TRUE, - ); + ]; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); // Check that seven can be uninstalled now. @@ -408,7 +408,7 @@ function testUninstallingThemes() { /** * Tests installing a theme and setting it as default. */ - function testInstallAndSetAsDefault() { + public function testInstallAndSetAsDefault() { $this->drupalGet('admin/appearance'); // Bartik is uninstalled in the test profile and has the third "Install and // set as default" link. diff --git a/core/modules/system/src/Tests/System/UncaughtExceptionTest.php b/core/modules/system/src/Tests/System/UncaughtExceptionTest.php index a0641526..02c09562 100644 --- a/core/modules/system/src/Tests/System/UncaughtExceptionTest.php +++ b/core/modules/system/src/Tests/System/UncaughtExceptionTest.php @@ -2,7 +2,6 @@ namespace Drupal\system\Tests\System; - use Drupal\simpletest\WebTestBase; /** @@ -24,7 +23,7 @@ class UncaughtExceptionTest extends WebTestBase { * * @var array */ - public static $modules = array('error_service_test'); + public static $modules = ['error_service_test']; /** * {@inheritdoc} @@ -224,20 +223,20 @@ public function testLostDatabaseConnection() { // We simulate a broken database connection by rewrite settings.php to no // longer have the proper data. - $settings['databases']['default']['default']['username'] = (object) array( + $settings['databases']['default']['default']['username'] = (object) [ 'value' => $incorrect_username, 'required' => TRUE, - ); - $settings['databases']['default']['default']['passowrd'] = (object) array( + ]; + $settings['databases']['default']['default']['password'] = (object) [ 'value' => $this->randomMachineName(16), 'required' => TRUE, - ); + ]; $this->writeSettings($settings); $this->drupalGet(''); $this->assertResponse(500); - $this->assertRaw('PDOException'); + $this->assertRaw('DatabaseAccessDeniedException'); $this->assertErrorLogged($this->expectedExceptionMessage); } diff --git a/core/modules/system/src/Tests/Theme/EngineNyanCatTest.php b/core/modules/system/src/Tests/Theme/EngineNyanCatTest.php deleted file mode 100644 index 0eb43b7d..00000000 --- a/core/modules/system/src/Tests/Theme/EngineNyanCatTest.php +++ /dev/null @@ -1,37 +0,0 @@ -install(array('test_theme_nyan_cat_engine')); - } - - /** - * Ensures a theme's template is overridable based on the 'template' filename. - */ - function testTemplateOverride() { - $this->config('system.theme') - ->set('default', 'test_theme_nyan_cat_engine') - ->save(); - $this->drupalGet('theme-test/template-test'); - $this->assertText('Success: Template overridden with Nyan Cat theme. All of them', 'Template overridden by Nyan Cat file.'); - } - -} diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php index 51d092d4..ffff75fc 100644 --- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php +++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php @@ -18,17 +18,17 @@ class EngineTwigTest extends WebTestBase { * * @var array */ - public static $modules = array('theme_test', 'twig_theme_test'); + public static $modules = ['theme_test', 'twig_theme_test']; protected function setUp() { parent::setUp(); - \Drupal::service('theme_handler')->install(array('test_theme')); + \Drupal::service('theme_handler')->install(['test_theme']); } /** * Tests that the Twig engine handles PHP data correctly. */ - function testTwigVariableDataTypes() { + public function testTwigVariableDataTypes() { $this->config('system.theme') ->set('default', 'test_theme') ->save(); @@ -45,13 +45,13 @@ public function testTwigUrlGenerator() { $this->drupalGet('twig-theme-test/url-generator'); // Find the absolute URL of the current site. $url_generator = $this->container->get('url_generator'); - $expected = array( + $expected = [ 'path (as route) not absolute: ' . $url_generator->generateFromRoute('user.register'), - 'url (as route) absolute: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE)), - 'path (as route) not absolute with fragment: ' . $url_generator->generateFromRoute('user.register', array(), array('fragment' => 'bottom')), - 'url (as route) absolute despite option: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE)), - 'url (as route) absolute with fragment: ' . $url_generator->generateFromRoute('user.register', array(), array('absolute' => TRUE, 'fragment' => 'bottom')), - ); + 'url (as route) absolute: ' . $url_generator->generateFromRoute('user.register', [], ['absolute' => TRUE]), + 'path (as route) not absolute with fragment: ' . $url_generator->generateFromRoute('user.register', [], ['fragment' => 'bottom']), + 'url (as route) absolute despite option: ' . $url_generator->generateFromRoute('user.register', [], ['absolute' => TRUE]), + 'url (as route) absolute with fragment: ' . $url_generator->generateFromRoute('user.register', [], ['absolute' => TRUE, 'fragment' => 'bottom']), + ]; // Verify that url() has the ability to bubble cacheability metadata: // absolute URLs should bubble the 'url.site' cache context. (This only @@ -86,6 +86,7 @@ public function testTwigLinkGenerator() { 'link via the linkgenerator: ' . $link_generator->generate('register', new Url('user.register', [], ['attributes' => ['class' => ['llama', 'kitten', 'panda']]])), 'link via the linkgenerator: ' . $link_generator->generate(Markup::create('register'), new Url('user.register', [], ['absolute' => TRUE])), 'link via the linkgenerator: register', + 'link via the linkgenerator: ' . $link_generator->generate('register', new Url('user.register', [], ['attributes' => ['foo' => 'bar']])) . ' ' . $link_generator->generate('register', new Url('user.register', [], ['attributes' => ['foo' => 'bar']])), ]; // Verify that link() has the ability to bubble cacheability metadata: diff --git a/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php b/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php index cc4af2a8..10eda618 100644 --- a/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php +++ b/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php @@ -6,6 +6,7 @@ use Drupal\Core\Extension\ExtensionDiscovery; use Drupal\comment\CommentInterface; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\node\NodeInterface; use Drupal\simpletest\WebTestBase; use Drupal\comment\Entity\Comment; use Drupal\taxonomy\Entity\Term; @@ -84,7 +85,7 @@ protected function setUp() { \Drupal::service('theme_handler')->install(array_keys($this->themes)); // Create a test user. - $this->user = $this->drupalCreateUser(array('access content', 'access user profiles')); + $this->user = $this->drupalCreateUser(['access content', 'access user profiles']); $this->user->name = $this->xssLabel; $this->user->save(); $this->drupalLogin($this->user); @@ -99,36 +100,36 @@ protected function setUp() { // Add a comment field. $this->addDefaultCommentField('node', 'article', 'comment', CommentItemInterface::OPEN); // Create a test node tagged with the test term. - $this->node = $this->drupalCreateNode(array( + $this->node = $this->drupalCreateNode([ 'title' => $this->xssLabel, 'type' => 'article', - 'promote' => NODE_PROMOTED, - 'field_tags' => array(array('target_id' => $this->term->id())), - )); + 'promote' => NodeInterface::PROMOTED, + 'field_tags' => [['target_id' => $this->term->id()]], + ]); // Create a test comment on the test node. - $this->comment = Comment::create(array( + $this->comment = Comment::create([ 'entity_id' => $this->node->id(), 'entity_type' => 'node', 'field_name' => 'comment', 'status' => CommentInterface::PUBLISHED, 'subject' => $this->xssLabel, - 'comment_body' => array($this->randomMachineName()), - )); + 'comment_body' => [$this->randomMachineName()], + ]); $this->comment->save(); } /** * Checks each themed entity for XSS filtering in available themes. */ - function testThemedEntity() { + public function testThemedEntity() { // Check paths where various view modes of the entities are rendered. - $paths = array( + $paths = [ 'user', 'node', 'node/' . $this->node->id(), 'taxonomy/term/' . $this->term->id(), - ); + ]; // Check each path in all available themes. foreach ($this->themes as $name => $theme) { diff --git a/core/modules/system/src/Tests/Theme/FastTest.php b/core/modules/system/src/Tests/Theme/FastTest.php deleted file mode 100644 index a05666fe..00000000 --- a/core/modules/system/src/Tests/Theme/FastTest.php +++ /dev/null @@ -1,36 +0,0 @@ -account = $this->drupalCreateUser(array('access user profiles')); - } - - /** - * Tests access to user autocompletion and verify the correct results. - */ - function testUserAutocomplete() { - $this->drupalLogin($this->account); - $this->drupalGet('user/autocomplete', array('query' => array('q' => $this->account->getUsername()))); - $this->assertRaw($this->account->getUsername()); - $this->assertNoText('registry initialized', 'The registry was not initialized'); - } - -} diff --git a/core/modules/system/src/Tests/Theme/FunctionsTest.php b/core/modules/system/src/Tests/Theme/FunctionsTest.php index fa5a2ac4..82583485 100644 --- a/core/modules/system/src/Tests/Theme/FunctionsTest.php +++ b/core/modules/system/src/Tests/Theme/FunctionsTest.php @@ -21,117 +21,117 @@ class FunctionsTest extends WebTestBase { * * @var array */ - public static $modules = array('router_test'); + public static $modules = ['router_test']; /** * Tests item-list.html.twig. */ - function testItemList() { + public function testItemList() { // Verify that empty items produce no output. - $variables = array(); + $variables = []; $expected = ''; $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates no output.'); // Verify that empty items with title produce no output. - $variables = array(); + $variables = []; $variables['title'] = 'Some title'; $expected = ''; $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback with title generates no output.'); // Verify that empty items produce the empty string. - $variables = array(); + $variables = []; $variables['empty'] = 'No items found.'; $expected = '
    No items found.
    '; $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string.'); // Verify that empty items produce the empty string with title. - $variables = array(); + $variables = []; $variables['title'] = 'Some title'; $variables['empty'] = 'No items found.'; $expected = '

    Some title

    No items found.
    '; $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string with title.'); // Verify that title set to 0 is output. - $variables = array(); + $variables = []; $variables['title'] = 0; $variables['empty'] = 'No items found.'; $expected = '

    0

    No items found.
    '; $this->assertThemeOutput('item_list', $variables, $expected, '%callback with title set to 0 generates a title.'); // Verify that title set to a render array is output. - $variables = array(); - $variables['title'] = array( + $variables = []; + $variables['title'] = [ '#markup' => 'Render array', - ); + ]; $variables['empty'] = 'No items found.'; $expected = '

    Render array

    No items found.
    '; $this->assertThemeOutput('item_list', $variables, $expected, '%callback with title set to a render array generates a title.'); // Verify that empty text is not displayed when there are list items. - $variables = array(); + $variables = []; $variables['title'] = 'Some title'; $variables['empty'] = 'No items found.'; - $variables['items'] = array('Un', 'Deux', 'Trois'); + $variables['items'] = ['Un', 'Deux', 'Trois']; $expected = '

    Some title

    • Un
    • Deux
    • Trois
    '; $this->assertThemeOutput('item_list', $variables, $expected, '%callback does not print empty text when there are list items.'); // Verify nested item lists. - $variables = array(); + $variables = []; $variables['title'] = 'Some title'; - $variables['attributes'] = array( + $variables['attributes'] = [ 'id' => 'parentlist', - ); - $variables['items'] = array( + ]; + $variables['items'] = [ // A plain string value forms an own item. 'a', // Items can be fully-fledged render arrays with their own attributes. - array( - '#wrapper_attributes' => array( + [ + '#wrapper_attributes' => [ 'id' => 'item-id-b', - ), + ], '#markup' => 'b', - 'childlist' => array( + 'childlist' => [ '#theme' => 'item_list', - '#attributes' => array('id' => 'blist'), + '#attributes' => ['id' => 'blist'], '#list_type' => 'ol', - '#items' => array( + '#items' => [ 'ba', - array( + [ '#markup' => 'bb', - '#wrapper_attributes' => array('class' => array('item-class-bb')), - ), - ), - ), - ), + '#wrapper_attributes' => ['class' => ['item-class-bb']], + ], + ], + ], + ], // However, items can also be child #items. - array( + [ '#markup' => 'c', - 'childlist' => array( - '#attributes' => array('id' => 'clist'), + 'childlist' => [ + '#attributes' => ['id' => 'clist'], 'ca', - array( + [ '#markup' => 'cb', - '#wrapper_attributes' => array('class' => array('item-class-cb')), - 'children' => array( + '#wrapper_attributes' => ['class' => ['item-class-cb']], + 'children' => [ 'cba', 'cbb', - ), - ), + ], + ], 'cc', - ), - ), + ], + ], // Use #markup to be able to specify #wrapper_attributes. - array( + [ '#markup' => 'd', - '#wrapper_attributes' => array('id' => 'item-id-d'), - ), + '#wrapper_attributes' => ['id' => 'item-id-d'], + ], // An empty item with attributes. - array( - '#wrapper_attributes' => array('id' => 'item-id-e'), - ), + [ + '#wrapper_attributes' => ['id' => 'item-id-e'], + ], // Lastly, another plain string item. 'f', - ); + ]; $inner_b = '
      '; $inner_b .= '
    1. ba
    2. '; @@ -166,52 +166,52 @@ function testItemList() { /** * Tests links.html.twig. */ - function testLinks() { + public function testLinks() { // Turn off the query for the // \Drupal\Core\Utility\LinkGeneratorInterface::generate() method to compare // the active link correctly. $original_query = \Drupal::request()->query->all(); - \Drupal::request()->query->replace(array()); + \Drupal::request()->query->replace([]); // Verify that empty variables produce no output. - $variables = array(); + $variables = []; $expected = ''; $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback generates no output.'); - $variables = array(); + $variables = []; $variables['heading'] = 'Some title'; $expected = ''; $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback with heading generates no output.'); // Verify that a list of links is properly rendered. - $variables = array(); - $variables['attributes'] = array('id' => 'somelinks'); - $variables['links'] = array( - 'a link' => array( + $variables = []; + $variables['attributes'] = ['id' => 'somelinks']; + $variables['links'] = [ + 'a link' => [ 'title' => 'A ', 'url' => Url::fromUri('base:a/link'), - ), - 'plain text' => array( + ], + 'plain text' => [ 'title' => 'Plain "text"', - ), - 'html text' => array( - 'title' => SafeMarkup::format('@text', array('@text' => 'potentially unsafe text that be escaped')), - ), - 'front page' => array( + ], + 'html text' => [ + 'title' => SafeMarkup::format('@text', ['@text' => 'potentially unsafe text that be escaped']), + ], + 'front page' => [ 'title' => 'Front page', 'url' => Url::fromRoute(''), - ), - 'router-test' => array( + ], + 'router-test' => [ 'title' => 'Test route', 'url' => Url::fromRoute('router_test.1'), - ), - 'query-test' => array( + ], + 'query-test' => [ 'title' => 'Query test route', 'url' => Url::fromRoute('router_test.1'), - 'query' => array( + 'query' => [ 'key' => 'value', - ) - ), - ); + ] + ], + ]; $expected_links = ''; $expected_links .= ''; @@ -234,25 +234,25 @@ function testLinks() { \Drupal::request()->query->replace($original_query); // Verify that passing an array as heading works (core support). - $variables['heading'] = array( + $variables['heading'] = [ 'text' => 'Links heading', 'level' => 'h3', - 'attributes' => array('class' => array('heading')), - ); + 'attributes' => ['class' => ['heading']], + ]; $expected_heading = '

      Links heading

      '; $expected = $expected_heading . $expected_links; $this->assertThemeOutput('links', $variables, $expected); // Verify that passing attributes for the heading works. - $variables['heading'] = array('text' => 'Links heading', 'level' => 'h3', 'attributes' => array('id' => 'heading')); + $variables['heading'] = ['text' => 'Links heading', 'level' => 'h3', 'attributes' => ['id' => 'heading']]; $expected_heading = '

      Links heading

      '; $expected = $expected_heading . $expected_links; $this->assertThemeOutput('links', $variables, $expected); // Verify that passing attributes for the links work. - $variables['links']['plain text']['attributes'] = array( - 'class' => array('a/class'), - ); + $variables['links']['plain text']['attributes'] = [ + 'class' => ['a/class'], + ]; $expected_links = ''; $expected_links .= ''; $expected = $expected_heading . $expected_links; $this->assertThemeOutput('links', $variables, $expected); // Verify the data- attributes for setting the "active" class on links. - \Drupal::currentUser()->setAccount(new UserSession(array('uid' => 1))); + \Drupal::currentUser()->setAccount(new UserSession(['uid' => 1])); $variables['set_active_class'] = TRUE; $expected_links = ''; $expected_links .= ''; @@ -287,7 +287,7 @@ function testLinks() { /** * Tests links.html.twig using links with indexed keys. */ - function testIndexedKeyedLinks() { + public function testIndexedKeyedLinks() { // Turn off the query for the // \Drupal\Core\Utility\LinkGeneratorInterface::generate() method to compare // the active link correctly. @@ -306,33 +306,33 @@ function testIndexedKeyedLinks() { // Verify that a list of links is properly rendered. $variables = []; $variables['attributes'] = ['id' => 'somelinks']; - $variables['links'] = array( - array( + $variables['links'] = [ + [ 'title' => 'A ', 'url' => Url::fromUri('base:a/link'), - ), - array( + ], + [ 'title' => 'Plain "text"', - ), - array( - 'title' => SafeMarkup::format('@text', array('@text' => 'potentially unsafe text that be escaped')), - ), - array( + ], + [ + 'title' => SafeMarkup::format('@text', ['@text' => 'potentially unsafe text that be escaped']), + ], + [ 'title' => 'Front page', 'url' => Url::fromRoute(''), - ), - array( + ], + [ 'title' => 'Test route', 'url' => Url::fromRoute('router_test.1'), - ), - array( + ], + [ 'title' => 'Query test route', 'url' => Url::fromRoute('router_test.1'), - 'query' => array( + 'query' => [ 'key' => 'value', - ) - ), - ); + ] + ], + ]; $expected_links = ''; $expected_links .= '
    +{% endif %} diff --git a/core/modules/system/templates/status-report-counter.html.twig b/core/modules/system/templates/status-report-counter.html.twig new file mode 100644 index 00000000..8489e495 --- /dev/null +++ b/core/modules/system/templates/status-report-counter.html.twig @@ -0,0 +1,16 @@ +{# +/** + * @file + * Default theme implementation for the status report counter. + * + * Available variables: + * - amount: The number shown on counter. + * - text: The text shown on counter. + * - severity: The severity of the counter. + * + * @ingroup themable + */ +#} + +{{ amount }} {{ text }} +{{ text }} Details diff --git a/core/modules/system/templates/status-report-general-info.html.twig b/core/modules/system/templates/status-report-general-info.html.twig new file mode 100644 index 00000000..d4d5054d --- /dev/null +++ b/core/modules/system/templates/status-report-general-info.html.twig @@ -0,0 +1,81 @@ +{# +/** + * @file + * Default theme implementation for the status report general info. + * + * Available variables: + * - drupal: The status of Drupal installation: + * - value: The current status of Drupal installation. + * - description: The description for current status of Drupal installation. + * - cron: The status of cron: + * - value: The current status of cron. + * - description: The description for current status of cron. + * - cron.run_cron: An array to render a button for running cron. + * - database_system: The status of database system: + * - value: The current status of database sytem. + * - description: The description for current status of cron. + * - database_system_version: The info about current database version: + * - value: The current version of database. + * - description: The description for current version of database. + * - php: The current version of PHP: + * - value: The status of currently installed PHP version. + * - description: The description for current installed PHP version. + * - php_memory_limit: The info about current PHP memory limit: + * - value: The status of currently set PHP memory limit. + * - description: The description for currently set PHP memory limit. + * - webserver: The info about currently installed web server: + * - value: The status of currently installed web server. + * - description: The description for the status of currently installed web + * server. + */ +#} + +

    {{ 'General System Information'|t }}

    +
    +

    {{ 'Drupal Version'|t }}

    + {{ drupal.value }} + {% if drupal.description %} + {{ drupal.description }} + {% endif %} +
    +
    +

    {{ 'Last Cron Run'|t }}

    + {{ cron.value }} + {% if cron.run_cron %} + {{ cron.run_cron }} + {% endif %} + {% if cron.description %} + {{ cron.description }} + {% endif %} +
    +
    +

    {{ 'Web Server'|t }}

    + {{ webserver.value }} + {% if webserver.description %} + {{ webserver.description }} + {% endif %} +
    +
    +

    {{ 'PHP'|t }}

    +

    {{ 'Version'|t }}

    {{ php.value }} + {% if php.description %} + {{ php.description }} + {% endif %} + +

    {{ 'Memory limit'|t }}

    {{ php_memory_limit.value }} + {% if php_memory_limit.description %} + {{ php_memory_limit.description }} + {% endif %} +
    +
    +

    {{ 'Database'|t }}

    +

    {{ 'Version'|t }}

    {{ database_system_version.value }} + {% if database_system_version.description %} + {{ database_system_version.description }} + {% endif %} + +

    {{ 'System'|t }}

    {{ database_system.value }} + {% if database_system.description %} + {{ database_system.description }} + {% endif %} +
    diff --git a/core/modules/system/templates/status-report-grouped.html.twig b/core/modules/system/templates/status-report-grouped.html.twig new file mode 100644 index 00000000..bd34e5af --- /dev/null +++ b/core/modules/system/templates/status-report-grouped.html.twig @@ -0,0 +1,49 @@ +{# +/** + * @file + * Default theme implementation of grouped status report requirements. + * + * - grouped_requirements: Contains grouped requirements. + * Each group contains: + * - title: The title of the group. + * - type: The severity of the group. + * - items: The requirement instances. + * Each requirement item contains: + * - title: The title of the requirement. + * - value: (optional) The requirement's status. + * - description: (optional) The requirement's description. + * - severity_title: The title of the severity. + * - severity_status: Indicates the severity status. + */ +#} +{{ attach_library('core/drupal.collapse') }} + +
    + {% for group in grouped_requirements %} +
    +

    {{ group.title }}

    + {% for requirement in group.items %} +
    + {% + set summary_classes = [ + 'system-status-report__status-title', + group.type in ['warning', 'error'] ? 'system-status-report__status-icon system-status-report__status-icon--' ~ group.type + ] + %} + + {% if requirement.severity_title %} + {{ requirement.severity_title }} + {% endif %} + {{ requirement.title }} + +
    + {{ requirement.value }} + {% if requirement.description %} +
    {{ requirement.description }}
    + {% endif %} +
    +
    + {% endfor %} +
    + {% endfor %} +
    diff --git a/core/modules/system/templates/status-report-page.html.twig b/core/modules/system/templates/status-report-page.html.twig new file mode 100644 index 00000000..ed6d1ea5 --- /dev/null +++ b/core/modules/system/templates/status-report-page.html.twig @@ -0,0 +1,28 @@ +{# +/** + * @file + * Default theme implementation for the status report page. + * + * Available variables: + * - counters: The list of counter elements. + * - general_info: A render array to create general info element. + * - requirements: A render array to create requirements table. + * + * @see template_preprocess_status_report() + */ +#} +{% if counters|length == 3 %} + {% set element_width_class = ' system-status-report-counters__item--third-width' %} +{% elseif counters|length == 2 %} + {% set element_width_class = ' system-status-report-counters__item--half-width' %} +{% endif %} +
    + {% for counter in counters %} +
    + {{ counter }} +
    + {% endfor %} +
    + +{{ general_info }} +{{ requirements }} diff --git a/core/modules/system/templates/status-report.html.twig b/core/modules/system/templates/status-report.html.twig index b6ad7398..ca9cf2b6 100644 --- a/core/modules/system/templates/status-report.html.twig +++ b/core/modules/system/templates/status-report.html.twig @@ -2,40 +2,38 @@ /** * @file * Default theme implementation for the status report. - * - * Available variables: - * - requirements: Contains multiple requirement instances. - * Each requirement contains: - * - title: The title of the requirement. - * - value: (optional) The requirement's status. - * - description: (optional) The requirement's description. - * - severity_title: The title of the severity. - * - severity_status: Indicates the severity status. - * - * @see template_preprocess_status_report() - * - * @ingroup themeable - */ -#} -

    ' . t('The Search module provides the ability to set up search pages based on plugins provided by other modules. In Drupal core, there are two page-type plugins: the Content page type provides keyword searching for content managed by the Node module, and the Users page type provides keyword searching for registered users. Contributed modules may provide other page-type plugins. For more information, see the online documentation for the Search module.', array(':search-module' => 'https://www.drupal.org/documentation/modules/search')) . '

    ']; // DIV background-image. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#DIV_background-image - $data[] = array('
    ', '
    '); + $data[] = ['
    ', '
    ']; // DIV background-image with unicoded XSS exploit. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#DIV_background-image_with_unicoded_XSS_exploit - $data[] = array('
    ', '
    '); + $data[] = ['
    ', '
    ']; // DIV background-image plus extra characters. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#DIV_background-image_plus_extra_characters - $data[] = array('
    ', '
    '); + $data[] = ['
    ', '
    ']; // DIV expression. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#DIV_expression - $data[] = array('
    ', '
    '); + $data[] = ['
    ', '
    ']; // Downlevel-Hidden block. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Downlevel-Hidden_block - $data[] = array('', "\n alert('XSS');\n "); + ', + "\n alert('XSS');\n ", + ]; // BASE tag. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#BASE_tag - $data[] = array('', ''); + $data[] = ['', '']; // OBJECT tag. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#OBJECT_tag - $data[] = array('', ''); + $data[] = ['', '']; // Using an EMBED tag you can embed a Flash movie that contains XSS. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Using_an_EMBED_tag_you_can_embed_a_Flash_movie_that_contains_XSS - $data[] = array('', ''); + $data[] = ['', '']; // You can EMBED SVG which can contain your XSS vector. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#You_can_EMBED_SVG_which_can_contain_your_XSS_vector - $data[] = array('', ''); + $data[] = ['', '']; // XML data island with CDATA obfuscation. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#XML_data_island_with_CDATA_obfuscation - $data[] = array('', 'cript:alert(\'XSS\')">'); + $data[] = ['', 'cript:alert(\'XSS\')">']; // Locally hosted XML with embedded JavaScript that is generated using an XML data island. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Locally_hosted_XML_with_embedded_JavaScript_that_is_generated_using_an_XML_data_island @@ -472,11 +477,11 @@ public function providerTestFilterXss() { // HTML+TIME in XML. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#HTML.2BTIME_in_XML - $data[] = array('">', '<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"><?import namespace="t" implementation="#default#time2">alert("XSS")">'); + $data[] = ['">', '<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"><?import namespace="t" implementation="#default#time2">alert("XSS")">']; // Assuming you can only fit in a few characters and it filters against ".js". // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Assuming_you_can_only_fit_in_a_few_characters_and_it_filters_against_.22.js.22 - $data[] = array('', ''); + $data[] = ['', '']; // IMG Embedded commands. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#IMG_Embedded_commands @@ -485,7 +490,7 @@ public function providerTestFilterXss() { // Cookie manipulation. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Cookie_manipulation - $data[] = array('', 'alert(\'XSS\')">'); + $data[] = ['', 'alert(\'XSS\')">']; // UTF-7 encoding. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#UTF-7_encoding @@ -493,13 +498,13 @@ public function providerTestFilterXss() { // XSS using HTML quote encapsulation. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#XSS_using_HTML_quote_encapsulation - $data[] = array('', '" SRC="http://ha.ckers.org/xss.js">'); - $data[] = array('', '" SRC="http://ha.ckers.org/xss.js">'); - $data[] = array('', '" \'\' SRC="http://ha.ckers.org/xss.js">'); - $data[] = array('', '\'" SRC="http://ha.ckers.org/xss.js">'); - $data[] = array('', '` SRC="http://ha.ckers.org/xss.js">'); - $data[] = array('', '\'>" SRC="http://ha.ckers.org/xss.js">'); - $data[] = array('PT SRC="http://ha.ckers.org/xss.js">', 'document.write("PT SRC="http://ha.ckers.org/xss.js">'); + $data[] = ['', '" SRC="http://ha.ckers.org/xss.js">']; + $data[] = ['', '" SRC="http://ha.ckers.org/xss.js">']; + $data[] = ['', '" \'\' SRC="http://ha.ckers.org/xss.js">']; + $data[] = ['', '\'" SRC="http://ha.ckers.org/xss.js">']; + $data[] = ['', '` SRC="http://ha.ckers.org/xss.js">']; + $data[] = ['', '\'>" SRC="http://ha.ckers.org/xss.js">']; + $data[] = ['PT SRC="http://ha.ckers.org/xss.js">', 'document.write("PT SRC="http://ha.ckers.org/xss.js">']; // URL string evasion. // @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#URL_string_evasion @@ -511,12 +516,12 @@ public function providerTestFilterXss() { // @see \Drupal\editor\EditorXssFilter::filterXssDataAttributes() // The following two test cases verify that XSS attack vectors are filtered. - $data[] = array('', ''); - $data[] = array('', ''); + $data[] = ['', '']; + $data[] = ['', '']; // When including HTML-tags as visible content, they are double-escaped. // This test case ensures that we leave that content unchanged. - $data[] = array('', ''); + $data[] = ['', '']; return $data; } @@ -573,27 +578,27 @@ public function testBlacklistMode($value, $expected, $message, array $disallowed * - (optional) The disallowed HTML tags to be passed to \Drupal\Component\Utility\Xss::filter(). */ public function providerTestBlackListMode() { - return array( - array( + return [ + [ 'Pink Fairy Armadillo
    diff --git a/core/modules/media/tests/fixtures/example_1.jpeg b/core/modules/media/tests/fixtures/example_1.jpeg new file mode 100644 index 00000000..e04cde60 Binary files /dev/null and b/core/modules/media/tests/fixtures/example_1.jpeg differ diff --git a/core/modules/media/tests/fixtures/example_2.jpeg b/core/modules/media/tests/fixtures/example_2.jpeg new file mode 100644 index 00000000..c0b67c21 Binary files /dev/null and b/core/modules/media/tests/fixtures/example_2.jpeg differ diff --git a/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml b/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml new file mode 100644 index 00000000..089aeac3 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/config/schema/media_test_source.schema.yml @@ -0,0 +1,15 @@ +media.source.test: + type: media.source.field_aware + label: 'Test media source configuration' + mapping: + test_config_value: + type: string + label: 'Test config value' + +media.source.test_translation: + type: media.source.test + label: 'Test media source with translations' + +media.source.test_constraints: + type: media.source.test + label: 'Test media source with constraints configuration' diff --git a/core/modules/media/tests/modules/media_test_source/media_test_source.info.yml b/core/modules/media/tests/modules/media_test_source/media_test_source.info.yml new file mode 100644 index 00000000..d1ad240f --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/media_test_source.info.yml @@ -0,0 +1,12 @@ +name: 'Test media source' +type: module +description: 'Provides test media source to test configuration forms.' +# core: 8.x +package: Testing +# version: VERSION + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/Validation/Constraint/MediaTestConstraint.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/Validation/Constraint/MediaTestConstraint.php new file mode 100644 index 00000000..3d466b3e --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/Validation/Constraint/MediaTestConstraint.php @@ -0,0 +1,25 @@ +label(); + } + elseif ($value instanceof FieldItemListInterface) { + $string_to_test = $value->value; + } + else { + return; + } + + if (strpos($string_to_test, 'love Drupal') === FALSE) { + $this->context->addViolation($constraint->message); + } + } + +} diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php new file mode 100644 index 00000000..b7baaa55 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php @@ -0,0 +1,88 @@ +get('media_source_test_attributes', [ + 'attribute_1' => ['label' => $this->t('Attribute 1'), 'value' => 'Value 1'], + 'attribute_2' => ['label' => $this->t('Attribute 2'), 'value' => 'Value 1'], + ]); + return array_map(function ($item) { + return $item['label']; + }, $attributes); + } + + /** + * {@inheritdoc} + */ + public function getMetadata(MediaInterface $media, $attribute_name) { + $attributes = \Drupal::state()->get('media_source_test_attributes', [ + 'attribute_1' => ['label' => $this->t('Attribute 1'), 'value' => 'Value 1'], + 'attribute_2' => ['label' => $this->t('Attribute 2'), 'value' => 'Value 1'], + ]); + + if (in_array($attribute_name, array_keys($attributes))) { + return $attributes[$attribute_name]['value']; + } + + return parent::getMetadata($media, $attribute_name); + } + + /** + * {@inheritdoc} + */ + public function getPluginDefinition() { + return NestedArray::mergeDeep( + parent::getPluginDefinition(), + \Drupal::state()->get('media_source_test_definition', []) + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return parent::defaultConfiguration() + [ + 'test_config_value' => 'This is default value.', + ]; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $form = parent::buildConfigurationForm($form, $form_state); + + $form['test_config_value'] = [ + '#type' => 'textfield', + '#title' => $this->t('Test config value'), + '#default_value' => $this->configuration['test_config_value'], + ]; + + return $form; + } + +} diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php new file mode 100644 index 00000000..947f0673 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestTranslation.php @@ -0,0 +1,36 @@ +language()->getId() . '.png'; + } + + if ($attribute_name == 'test_thumbnail_alt') { + $langcode = $media->language()->getId(); + return $this->t('Test Thumbnail @language', ['@language' => $langcode], ['langcode' => $langcode]); + } + + return parent::getMetadata($media, $attribute_name); + } + +} diff --git a/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php new file mode 100644 index 00000000..98039ca2 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/TestWithConstraints.php @@ -0,0 +1,34 @@ +get('media_source_test_entity_constraints', []); + } + + /** + * {@inheritdoc} + */ + public function getSourceFieldConstraints() { + return \Drupal::state()->get('media_source_test_field_constraints', []); + } + +} diff --git a/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml b/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml new file mode 100644 index 00000000..96beb46e --- /dev/null +++ b/core/modules/media/tests/modules/media_test_type/config/install/media.type.test.yml @@ -0,0 +1,11 @@ +id: test +label: 'Test type' +description: 'Test type.' +source: test +source_configuration: + test_config_value: 'Kakec' +status: true +langcode: en +dependencies: { } +field_map: + metadata_attribute: 'field_attribute_config_test' diff --git a/core/modules/media/tests/modules/media_test_type/media_test_type.info.yml b/core/modules/media/tests/modules/media_test_type/media_test_type.info.yml new file mode 100644 index 00000000..0ca49ab7 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_type/media_test_type.info.yml @@ -0,0 +1,14 @@ +name: 'Media test type' +type: module +description: 'Provides test type for a media item.' +# core: 8.x +package: Testing +# version: VERSION +dependencies: + - media_test_source + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/media/tests/modules/media_test_views/media_test_views.info.yml b/core/modules/media/tests/modules/media_test_views/media_test_views.info.yml new file mode 100644 index 00000000..22a304a1 --- /dev/null +++ b/core/modules/media/tests/modules/media_test_views/media_test_views.info.yml @@ -0,0 +1,15 @@ +name: 'Media test views' +type: module +description: 'Provides default views for views media tests.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - media + - views + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/media/tests/src/Functional/MediaAccessTest.php b/core/modules/media/tests/src/Functional/MediaAccessTest.php new file mode 100644 index 00000000..d5c23041 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaAccessTest.php @@ -0,0 +1,134 @@ +assertSession(); + + $media_type = $this->createMediaType(); + + // Create media. + $media = Media::create([ + 'bundle' => $media_type->id(), + 'name' => 'Unnamed', + ]); + $media->save(); + $user_media = Media::create([ + 'bundle' => $media_type->id(), + 'name' => 'Unnamed', + 'uid' => $this->nonAdminUser->id(), + ]); + $user_media->save(); + + // We are logged in as admin, so test 'administer media' permission. + $this->drupalGet('media/add/' . $media_type->id()); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + $this->drupalGet('media/' . $user_media->id()); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + $this->drupalGet('media/' . $user_media->id() . '/edit'); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + $this->drupalGet('media/' . $user_media->id() . '/delete'); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + + $this->drupalLogin($this->nonAdminUser); + /** @var \Drupal\user\RoleInterface $role */ + $role = Role::load(RoleInterface::AUTHENTICATED_ID); + + // Test 'view media' permission. + user_role_revoke_permissions($role->id(), ['view media']); + $this->drupalGet('media/' . $media->id()); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(403); + $access_result = $media->access('view', NULL, TRUE); + $this->assertSame("The 'view media' permission is required and the media item must be published.", $access_result->getReason()); + $this->grantPermissions($role, ['view media']); + $this->drupalGet('media/' . $media->id()); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(200); + + // Test 'create media' permission. + $this->drupalGet('media/add/' . $media_type->id()); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(403); + $this->grantPermissions($role, ['create media']); + $this->drupalGet('media/add/' . $media_type->id()); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + + // Test 'update media' and 'delete media' permissions. + $this->drupalGet('media/' . $user_media->id() . '/edit'); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(403); + $this->drupalGet('media/' . $user_media->id() . '/delete'); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(403); + $this->grantPermissions($role, ['update media']); + $this->grantPermissions($role, ['delete media']); + $this->drupalGet('media/' . $user_media->id() . '/edit'); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(200); + $this->drupalGet('media/' . $user_media->id() . '/delete'); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(200); + + // Test 'update any media' and 'delete any media' permissions. + $this->drupalGet('media/' . $media->id() . '/edit'); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(403); + $this->drupalGet('media/' . $media->id() . '/delete'); + $this->assertCacheContext('user'); + $assert_session->statusCodeEquals(403); + $this->grantPermissions($role, ['update any media']); + $this->grantPermissions($role, ['delete any media']); + $this->drupalGet('media/' . $media->id() . '/edit'); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + $this->drupalGet('media/' . $media->id() . '/delete'); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + + // Test the 'access media overview' permission. + $this->grantPermissions($role, ['access content overview']); + $this->drupalGet('admin/content'); + $assert_session->linkByHrefNotExists('/admin/content/media'); + $this->assertCacheContext('user'); + + // Create a new role, which implicitly checks if the permission exists. + $mediaOverviewRole = $this->createRole(['access content overview', 'access media overview']); + $this->nonAdminUser->addRole($mediaOverviewRole); + $this->nonAdminUser->save(); + + $this->drupalGet('admin/content'); + $assert_session->linkByHrefExists('/admin/content/media'); + $this->clickLink('Media'); + $this->assertCacheContext('user.permissions'); + $assert_session->statusCodeEquals(200); + $assert_session->elementExists('css', '.view-media'); + $assert_session->pageTextContains($this->loggedInUser->getDisplayName()); + $assert_session->pageTextContains($this->nonAdminUser->getDisplayName()); + $assert_session->linkByHrefExists('/media/' . $media->id()); + $assert_session->linkByHrefExists('/media/' . $user_media->id()); + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php b/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php new file mode 100644 index 00000000..8da814b9 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaCacheTagsTest.php @@ -0,0 +1,62 @@ +createMediaType(); + + // Create a media item. + $media = Media::create([ + 'bundle' => $mediaType->id(), + 'name' => 'Unnamed', + ]); + $media->save(); + + return $media; + } + + /** + * {@inheritdoc} + */ + protected function getAdditionalCacheContextsForEntity(EntityInterface $media) { + return ['timezone']; + } + + /** + * {@inheritdoc} + */ + protected function getAdditionalCacheTagsForEntity(EntityInterface $media) { + // Each media item must have an author and a thumbnail. + return [ + 'user:' . $media->getOwnerId(), + 'config:image.style.thumbnail', + 'file:' . $media->get('thumbnail')->entity->id(), + ]; + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php b/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php new file mode 100644 index 00000000..017e725e --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaFunctionalTestBase.php @@ -0,0 +1,29 @@ +randomMachineName()); + } + else { + $id = $values['bundle']; + } + $values += [ + 'id' => $id, + 'label' => $id, + 'source' => $source, + 'source_configuration' => [], + 'field_map' => [], + 'new_revision' => FALSE, + ]; + + $media_type = MediaType::create($values); + $status = $media_type->save(); + + // @todo Rename to assertSame() when #1945040 is done. + // @see https://www.drupal.org/node/1945040 + $this->assertIdentical(SAVED_NEW, $status, 'Media type was created successfully.'); + + // Ensure that the source field exists. + $source = $media_type->getSource(); + $source_field = $source->getSourceFieldDefinition($media_type); + if (!$source_field) { + $source_field = $source->createSourceField($media_type); + /** @var \Drupal\field\FieldStorageConfigInterface $storage */ + $storage = $source_field->getFieldStorageDefinition(); + $storage->save(); + $source_field->save(); + + $media_type + ->set('source_configuration', [ + 'source_field' => $source_field->getName(), + ]) + ->save(); + } + + return $media_type; + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php b/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php new file mode 100644 index 00000000..d56e1565 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaFunctionalTestTrait.php @@ -0,0 +1,74 @@ +adminUser = $this->drupalCreateUser(static::$adminUserPermissions); + $this->nonAdminUser = $this->drupalCreateUser([]); + // Start off logged in as admin. + $this->drupalLogin($this->adminUser); + + $this->storage = $this->container->get('entity_type.manager')->getStorage('media'); + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaInstallTest.php b/core/modules/media/tests/src/Functional/MediaInstallTest.php new file mode 100644 index 00000000..d13c3f06 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaInstallTest.php @@ -0,0 +1,49 @@ +drupalLogin($this->drupalCreateUser(['administer modules'])); + } + + /** + * Tests reinstalling after being uninstalled. + */ + public function testReinstallAfterUninstall() { + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + + // Uninstall the media module. + $this->container->get('module_installer')->uninstall(['media'], FALSE); + + // Install the media module again, through a test module that depends on it. + // Note: We use a test module because in 8.4 the media module is hidden. + // @todo Simplify this in https://www.drupal.org/node/2897028 once it's + // shown again. + $this->drupalGet('/admin/modules'); + $page->checkField('modules[media_test_views][enable]'); + $page->pressButton('Install'); + $assert_session->pageTextContains('Some required modules must be enabled'); + $page->pressButton('Continue'); + $this->assertSession()->pageTextNotContains('could not be moved/copied because a file by that name already exists in the destination directory'); + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaRevisionTest.php b/core/modules/media/tests/src/Functional/MediaRevisionTest.php new file mode 100644 index 00000000..b8ff7c55 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaRevisionTest.php @@ -0,0 +1,199 @@ +assertSession(); + + /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $media_storage */ + $media_storage = $this->container->get('entity.manager')->getStorage('media'); + + // Create a media type and media item. + $media_type = $this->createMediaType(); + $media = $media_storage->create([ + 'bundle' => $media_type->id(), + 'name' => 'Unnamed', + ]); + $media->save(); + + // You can't access the revision page when there is only 1 revision. + $this->drupalGet('media/' . $media->id() . '/revisions/' . $media->getRevisionId() . '/view'); + $assert->statusCodeEquals(403); + + // Create some revisions. + $media_revisions = []; + $media_revisions[] = clone $media; + $revision_count = 3; + for ($i = 0; $i < $revision_count; $i++) { + $media->revision_log = $this->randomMachineName(32); + $media = $this->createMediaRevision($media); + $media_revisions[] = clone $media; + } + + // Get the last revision for simple checks. + /** @var \Drupal\media\MediaInterface $media */ + $media = end($media_revisions); + + // Test permissions. + $this->drupalLogin($this->nonAdminUser); + /** @var \Drupal\user\RoleInterface $role */ + $role = Role::load(RoleInterface::AUTHENTICATED_ID); + + // Test 'view all media revisions' permission ('view media' permission is + // needed as well). + user_role_revoke_permissions($role->id(), ['view media', 'view all media revisions']); + $this->drupalGet('media/' . $media->id() . '/revisions/' . $media->getRevisionId() . '/view'); + $assert->statusCodeEquals(403); + $this->grantPermissions($role, ['view media', 'view all media revisions']); + $this->drupalGet('media/' . $media->id() . '/revisions/' . $media->getRevisionId() . '/view'); + $assert->statusCodeEquals(200); + + // Confirm the revision page shows the correct title. + $assert->pageTextContains($media->getName()); + + // Confirm that the last revision is the default revision. + $this->assertTrue($media->isDefaultRevision(), 'Last revision is the default.'); + } + + /** + * Tests creating revisions of a File media item. + */ + public function testFileMediaRevision() { + $assert = $this->assertSession(); + + $uri = 'temporary://foo.txt'; + file_put_contents($uri, $this->randomString(128)); + + // Create a media item. + $this->drupalGet('/media/add/file'); + $page = $this->getSession()->getPage(); + $page->fillField('Name', 'Foobar'); + $page->attachFileToField('File', $this->container->get('file_system')->realpath($uri)); + $page->pressButton('Save'); + $assert->addressMatches('/^\/media\/[0-9]+$/'); + + // The media item was just created, so it should only have one revision. + $media = $this->container + ->get('entity_type.manager') + ->getStorage('media') + ->load(1); + $this->assertRevisionCount($media, 1); + + // If we edit the item, we should get a new revision. + $this->drupalGet('/media/1/edit'); + $assert->checkboxChecked('Create new revision'); + $page = $this->getSession()->getPage(); + $page->fillField('Name', 'Foobaz'); + $page->pressButton('Save'); + $this->assertRevisionCount($media, 2); + + // Confirm the correct revision title appears on "view revisions" page. + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged(1); + $this->drupalGet("media/" . $media->id() . "/revisions/" . $media->getRevisionId() . "/view"); + $assert->pageTextContains('Foobaz'); + } + + /** + * Tests creating revisions of a Image media item. + */ + public function testImageMediaRevision() { + $assert = $this->assertSession(); + + /** @var \Drupal\field\FieldConfigInterface $field */ + // Disable the alt text field, because this is not a JavaScript test and + // the alt text field will therefore not appear without a full page refresh. + $field = FieldConfig::load('media.image.field_media_image'); + $settings = $field->getSettings(); + $settings['alt_field'] = FALSE; + $settings['alt_field_required'] = FALSE; + $field->set('settings', $settings); + $field->save(); + + // Create a media item. + $this->drupalGet('/media/add/image'); + $page = $this->getSession()->getPage(); + $page->fillField('Name', 'Foobar'); + $page->attachFileToField('Image', \Drupal::root() . '/core/modules/media/tests/fixtures/example_1.jpeg'); + $page->pressButton('Save'); + $assert->addressMatches('/^\/media\/[0-9]+$/'); + + // The media item was just created, so it should only have one revision. + $media = $this->container + ->get('entity_type.manager') + ->getStorage('media') + ->load(1); + $this->assertRevisionCount($media, 1); + + // If we edit the item, we should get a new revision. + $this->drupalGet('/media/1/edit'); + $assert->checkboxChecked('Create new revision'); + $page = $this->getSession()->getPage(); + $page->fillField('Name', 'Foobaz'); + $page->pressButton('Save'); + $this->assertRevisionCount($media, 2); + + // Confirm the correct revision title appears on "view revisions" page. + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged(1); + $this->drupalGet("media/" . $media->id() . "/revisions/" . $media->getRevisionId() . "/view"); + $assert->pageTextContains('Foobaz'); + } + + /** + * Creates a new revision for a given media item. + * + * @param \Drupal\media\MediaInterface $media + * A media object. + * + * @return \Drupal\media\MediaInterface + * A media object with up to date revision information. + */ + protected function createMediaRevision(MediaInterface $media) { + $media->setName($this->randomMachineName()); + $media->setNewRevision(); + $media->save(); + return $media; + } + + /** + * Asserts that an entity has a certain number of revisions. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity in question. + * @param int $expected_revisions + * The expected number of revisions. + */ + protected function assertRevisionCount(EntityInterface $entity, $expected_revisions) { + $entity_type = $entity->getEntityType(); + + $count = $this->container + ->get('entity.query') + ->get($entity_type->id()) + ->count() + ->allRevisions() + ->condition($entity_type->getKey('id'), $entity->id()) + ->execute(); + + $this->assertSame($expected_revisions, (int) $count); + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaSourceFileTest.php b/core/modules/media/tests/src/Functional/MediaSourceFileTest.php new file mode 100644 index 00000000..b2e4f508 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaSourceFileTest.php @@ -0,0 +1,65 @@ +delete(); + } + + /** + * Test that it's possible to change the allowed file extensions. + */ + public function testSourceFieldSettingsEditing() { + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $media_type = $this->createMediaType([], 'file'); + $media_type_id = $media_type->id(); + $this->assertSame('txt doc docx pdf', FieldConfig::load("media.$media_type_id.field_media_file")->get('settings')['file_extensions']); + + $this->drupalGet("admin/structure/media/manage/$media_type_id/fields/media.$media_type_id.field_media_file"); + + // File extension field exists. + $assert_session->fieldExists('Allowed file extensions'); + + // Add another extension. + $page->fillField('settings[file_extensions]', 'txt, doc, docx, pdf, odt'); + + $page->pressButton('Save settings'); + $this->drupalGet("admin/structure/media/manage/$media_type_id/fields/media.$media_type_id.field_media_file"); + + // Verify that new extension is present. + $assert_session->fieldValueEquals('settings[file_extensions]', 'txt, doc, docx, pdf, odt'); + $this->assertSame('txt doc docx pdf odt', FieldConfig::load("media.$media_type_id.field_media_file")->get('settings')['file_extensions']); + } + + /** + * Ensure source field deletion is not possible. + */ + public function testPreventSourceFieldDeletion() { + $media_type = $this->createMediaType([], 'file'); + $media_type_id = $media_type->id(); + + $this->drupalGet("admin/structure/media/manage/$media_type_id/fields/media.$media_type_id.field_media_file/delete"); + $this->assertSession()->statusCodeEquals(403); + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaTemplateSuggestionsTest.php b/core/modules/media/tests/src/Functional/MediaTemplateSuggestionsTest.php new file mode 100644 index 00000000..e0e52941 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaTemplateSuggestionsTest.php @@ -0,0 +1,46 @@ +createMediaType([ + 'new_revision' => FALSE, + 'queue_thumbnail_downloads' => FALSE, + ]); + + // Create media item to be rendered. + $media = Media::create([ + 'bundle' => $media_type->id(), + 'name' => 'Unnamed', + ]); + $media->save(); + $view_mode = 'full'; + + // Simulate theming of the media item. + $build = \Drupal::entityTypeManager()->getViewBuilder('media')->view($media, $view_mode); + + $variables['elements'] = $build; + $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_media', [$variables]); + $this->assertEquals($suggestions, ['media__full', 'media__' . $media_type->id(), 'media__' . $media_type->id() . '__full'], 'Found expected media suggestions.'); + } + +} diff --git a/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php new file mode 100644 index 00000000..74ac67c2 --- /dev/null +++ b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php @@ -0,0 +1,182 @@ +drupalPlaceBlock('local_actions_block'); + $this->drupalPlaceBlock('local_tasks_block'); + + // We need to test without any default configuration in place. + // @TODO: Remove this when https://www.drupal.org/node/2883813 lands. + MediaType::load('file')->delete(); + MediaType::load('image')->delete(); + } + + /** + * Tests the media actions (add/edit/delete). + */ + public function testMediaWithOnlyOneMediaType() { + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $media_type = $this->createMediaType([ + 'new_revision' => FALSE, + 'queue_thumbnail_downloads' => FALSE, + ]); + + $this->drupalGet('media/add'); + $assert_session->statusCodeEquals(200); + $assert_session->addressEquals('media/add/' . $media_type->id()); + $assert_session->elementNotExists('css', '#edit-revision'); + + // Tests media add form. + $media_name = $this->randomMachineName(); + $page->fillField('name[0][value]', $media_name); + $revision_log_message = $this->randomString(); + $page->fillField('revision_log_message[0][value]', $revision_log_message); + $page->pressButton('Save'); + $media_id = $this->container->get('entity.query')->get('media')->execute(); + $media_id = reset($media_id); + /** @var \Drupal\media\MediaInterface $media */ + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged($media_id); + $this->assertEquals($media->getRevisionLogMessage(), $revision_log_message); + $this->assertEquals($media->getName(), $media_name); + $assert_session->titleEquals($media_name . ' | Drupal'); + + // Tests media edit form. + $media_type->setNewRevision(FALSE); + $media_type->save(); + $media_name2 = $this->randomMachineName(); + $this->drupalGet('media/' . $media_id . '/edit'); + $assert_session->checkboxNotChecked('edit-revision'); + $media_name = $this->randomMachineName(); + $page->fillField('name[0][value]', $media_name2); + $page->pressButton('Save'); + /** @var \Drupal\media\MediaInterface $media */ + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged($media_id); + $this->assertEquals($media->getName(), $media_name2); + $assert_session->titleEquals($media_name2 . ' | Drupal'); + + // Test that there is no empty vertical tabs element, if the container is + // empty (see #2750697). + // Make the "Publisher ID" and "Created" fields hidden. + $this->drupalGet('/admin/structure/media/manage/' . $media_type->id() . '/form-display'); + $page->selectFieldOption('fields[created][parent]', 'hidden'); + $page->selectFieldOption('fields[uid][parent]', 'hidden'); + $page->pressButton('Save'); + // Assure we are testing with a user without permission to manage revisions. + $this->drupalLogin($this->nonAdminUser); + // Check the container is not present. + $this->drupalGet('media/' . $media_id . '/edit'); + $assert_session->elementNotExists('css', 'input.vertical-tabs__active-tab'); + // Continue testing as admin. + $this->drupalLogin($this->adminUser); + + // Enable revisions by default. + $previous_revision_id = $media->getRevisionId(); + $media_type->setNewRevision(TRUE); + $media_type->save(); + $this->drupalGet('media/' . $media_id . '/edit'); + $assert_session->checkboxChecked('edit-revision'); + $page->fillField('name[0][value]', $media_name); + $page->fillField('revision_log_message[0][value]', $revision_log_message); + $page->pressButton('Save'); + $assert_session->titleEquals($media_name . ' | Drupal'); + /** @var \Drupal\media\MediaInterface $media */ + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged($media_id); + $this->assertEquals($media->getRevisionLogMessage(), $revision_log_message); + $this->assertNotEquals($previous_revision_id, $media->getRevisionId()); + + // Test the status checkbox. + $this->drupalGet('media/' . $media_id . '/edit'); + $page->uncheckField('status[value]'); + $page->pressButton('Save'); + /** @var \Drupal\media\MediaInterface $media */ + $media = $this->container->get('entity_type.manager') + ->getStorage('media') + ->loadUnchanged($media_id); + $this->assertFalse($media->isPublished()); + + // Tests media delete form. + $this->drupalGet('media/' . $media_id . '/edit'); + $page->clickLink('Delete'); + $assert_session->pageTextContains('This action cannot be undone'); + $page->pressButton('Delete'); + $media_id = \Drupal::entityQuery('media')->execute(); + $this->assertFalse($media_id); + } + + /** + * Tests the "media/add" and "media/mid" pages. + * + * Tests if the "media/add" page gives you a selecting option if there are + * multiple media types available. + */ + public function testMediaWithMultipleMediaTypes() { + $assert_session = $this->assertSession(); + + // Tests and creates the first media type. + $first_media_type = $this->createMediaType(['description' => $this->randomMachineName(32)]); + + // Test and create a second media type. + $second_media_type = $this->createMediaType(['description' => $this->randomMachineName(32)]); + + // Test if media/add displays two media type options. + $this->drupalGet('media/add'); + + // Checks for the first media type. + $assert_session->pageTextContains($first_media_type->label()); + $assert_session->pageTextContains($first_media_type->getDescription()); + // Checks for the second media type. + $assert_session->pageTextContains($second_media_type->label()); + $assert_session->pageTextContains($second_media_type->getDescription()); + + // Continue testing media type filter. + $first_media_item = Media::create(['bundle' => $first_media_type->id()]); + $first_media_item->save(); + $second_media_item = Media::create(['bundle' => $second_media_type->id()]); + $second_media_item->save(); + + // Go to first media item. + $this->drupalGet('media/' . $first_media_item->id()); + $assert_session->statusCodeEquals(200); + $assert_session->pageTextContains($first_media_item->getName()); + + // Go to second media item. + $this->drupalGet('media/' . $second_media_item->id()); + $assert_session->statusCodeEquals(200); + $assert_session->pageTextContains($second_media_item->getName()); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php b/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php new file mode 100644 index 00000000..7fc26ec9 --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaJavascriptTestBase.php @@ -0,0 +1,46 @@ + 0"; + $this->assertJsCondition($condition, $timeout, $message); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaSourceFileTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceFileTest.php new file mode 100644 index 00000000..c638f830 --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceFileTest.php @@ -0,0 +1,80 @@ +delete(); + } + + /** + * Tests the file media source. + */ + public function testMediaFileSource() { + $media_type_id = 'test_media_file_type'; + $source_field_id = 'field_media_file'; + + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $this->doTestCreateMediaType($media_type_id, 'file'); + + // Hide the name field widget to test default name generation. + $this->hideMediaTypeFieldWidget('name', $media_type_id); + + $test_filename = $this->randomMachineName() . '.txt'; + $test_filepath = 'public://' . $test_filename; + file_put_contents($test_filepath, $this->randomMachineName()); + + // Create a media item. + $this->drupalGet("media/add/{$media_type_id}"); + $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath)); + $result = $assert_session->waitForButton('Remove'); + $this->assertNotEmpty($result); + $page->pressButton('Save'); + + $assert_session->addressEquals('media/1'); + + // Make sure the thumbnail is displayed. + $assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', 'generic.png'); + + // Make sure checkbox changes the visibility of log message field. + $this->drupalGet("media/1/edit"); + $page->uncheckField('revision'); + $assert_session->elementAttributeContains('css', '.field--name-revision-log-message', 'style', 'display: none'); + $page->checkField('revision'); + $assert_session->elementAttributeNotContains('css', '.field--name-revision-log-message', 'style', 'display'); + + // Load the media and check if the label was properly populated. + $media = Media::load(1); + $this->assertEquals($test_filename, $media->getName()); + + // Test the MIME type icon. + $icon_base = \Drupal::config('media.settings')->get('icon_base_uri'); + file_unmanaged_copy($icon_base . '/generic.png', $icon_base . '/text--plain.png'); + $this->drupalGet("media/add/{$media_type_id}"); + $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::service('file_system')->realpath($test_filepath)); + $result = $assert_session->waitForButton('Remove'); + $this->assertNotEmpty($result); + $page->pressButton('Save'); + $assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', 'text--plain.png'); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaSourceImageTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceImageTest.php new file mode 100644 index 00000000..dd994428 --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceImageTest.php @@ -0,0 +1,80 @@ +delete(); + MediaType::load('image')->delete(); + } + + /** + * Tests the image media source. + */ + public function testMediaImageSource() { + $media_type_id = 'test_media_image_type'; + $source_field_id = 'field_media_image'; + $provided_fields = [ + Image::METADATA_ATTRIBUTE_WIDTH, + Image::METADATA_ATTRIBUTE_HEIGHT, + ]; + + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $this->doTestCreateMediaType($media_type_id, 'image', $provided_fields); + + // Create custom fields for the media type to store metadata attributes. + $fields = [ + 'field_string_width' => 'string', + 'field_string_height' => 'string', + ]; + $this->createMediaTypeFields($fields, $media_type_id); + + // Hide the name field widget to test default name generation. + $this->hideMediaTypeFieldWidget('name', $media_type_id); + + $this->drupalGet("admin/structure/media/manage/{$media_type_id}"); + $page->selectFieldOption("field_map[" . Image::METADATA_ATTRIBUTE_WIDTH . "]", 'field_string_width'); + $page->selectFieldOption("field_map[" . Image::METADATA_ATTRIBUTE_HEIGHT . "]", 'field_string_height'); + $page->pressButton('Save'); + + // Create a media item. + $this->drupalGet("media/add/{$media_type_id}"); + $page->attachFileToField("files[{$source_field_id}_0]", \Drupal::root() . '/core/modules/media/tests/fixtures/example_1.jpeg'); + $result = $assert_session->waitForButton('Remove'); + $this->assertNotEmpty($result); + $page->fillField("{$source_field_id}[0][alt]", 'Image Alt Text 1'); + $page->pressButton('Save'); + + $assert_session->addressEquals('media/1'); + + // Make sure the thumbnail is displayed from uploaded image. + $assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', 'example_1.jpeg'); + + // Load the media and check that all fields are properly populated. + $media = Media::load(1); + $this->assertEquals('example_1.jpeg', $media->getName()); + $this->assertEquals('200', $media->get('field_string_width')->value); + $this->assertEquals('89', $media->get('field_string_height')->value); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaSourceTestBase.php b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceTestBase.php new file mode 100644 index 00000000..ce0f185e --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaSourceTestBase.php @@ -0,0 +1,138 @@ + $field_name, + 'entity_type' => 'media', + 'type' => $field_type, + ]); + $storage->save(); + + FieldConfig::create([ + 'field_storage' => $storage, + 'bundle' => $media_type_id, + ])->save(); + + // Make the field widget visible in the form display. + $component = \Drupal::service('plugin.manager.field.widget') + ->prepareConfiguration($field_type, []); + + // @todo Replace entity_get_form_display() when #2367933 is done. + // https://www.drupal.org/node/2872159. + $entity_form_display = entity_get_form_display('media', $media_type_id, 'default'); + $entity_form_display->setComponent($field_name, $component) + ->save(); + + // Use the default formatter and settings. + $component = \Drupal::service('plugin.manager.field.formatter') + ->prepareConfiguration($field_type, []); + + // @todo Replace entity_get_display() when #2367933 is done. + // https://www.drupal.org/node/2872159. + $entity_display = entity_get_display('media', $media_type_id, 'default'); + $entity_display->setComponent($field_name, $component) + ->save(); + } + + /** + * Create a set of fields in a media type. + * + * @param array $fields + * An associative array where keys are field names and values field types. + * @param string $media_type_id + * The media type config entity ID. + */ + protected function createMediaTypeFields(array $fields, $media_type_id) { + foreach ($fields as $field_name => $field_type) { + $this->createMediaTypeField($field_name, $field_type, $media_type_id); + } + } + + /** + * Hides a widget in the default form display config. + * + * @param string $field_name + * The field name. + * @param string $media_type_id + * The media type config entity ID. + */ + protected function hideMediaTypeFieldWidget($field_name, $media_type_id) { + /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity_form_display */ + $entity_form_display = entity_get_form_display('media', $media_type_id, 'default'); + if ($entity_form_display->getComponent($field_name)) { + $entity_form_display->removeComponent($field_name)->save(); + } + } + + /** + * Test generic media type creation. + * + * @param string $media_type_id + * The media type config entity ID. + * @param string $source_id + * The media source ID. + * @param array $provided_fields + * (optional) An array of field machine names this type provides. + * + * @return \Drupal\media\MediaTypeInterface + * The created media type. + */ + public function doTestCreateMediaType($media_type_id, $source_id, array $provided_fields = []) { + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $this->drupalGet('admin/structure/media/add'); + $page->fillField('label', $media_type_id); + $this->getSession() + ->wait(5000, "jQuery('.machine-name-value').text() === '{$media_type_id}'"); + + // Make sure the source is available. + $assert_session->fieldExists('Media source'); + $assert_session->optionExists('Media source', $source_id); + $page->selectFieldOption('Media source', $source_id); + $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]'); + $this->assertNotEmpty($result); + + // Make sure the provided fields are visible on the form. + foreach ($provided_fields as $provided_field) { + $result = $assert_session->waitForElementVisible('css', 'select[name="field_map[' . $provided_field . ']"]'); + $this->assertNotEmpty($result); + } + + // Save the form to create the type. + $page->pressButton('Save'); + $assert_session->pageTextContains('The media type ' . $media_type_id . ' has been added.'); + $this->drupalGet('admin/structure/media'); + $assert_session->pageTextContains($media_type_id); + + // Bundle definitions are statically cached in the context of the test, we + // need to make sure we have updated information before proceeding with the + // actions on the UI. + \Drupal::service('entity_type.bundle.info')->clearCachedBundles(); + + return MediaType::load($media_type_id); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaTypeCreationTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaTypeCreationTest.php new file mode 100644 index 00000000..efbe2884 --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaTypeCreationTest.php @@ -0,0 +1,101 @@ +getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $label = 'Type with Default Field'; + $mediaTypeMachineName = str_replace(' ', '_', strtolower($label)); + + $this->drupalGet('admin/structure/media/add'); + + // Fill in a label to the media type. + $page->fillField('label', $label); + // Wait for machine name generation. Default: waitUntilVisible(), does not + // work properly. + $session->wait(5000, "jQuery('.machine-name-value').text() === '{$mediaTypeMachineName}'"); + + // Select the media source used by our media type. + $assert_session->fieldExists('Media source'); + $assert_session->optionExists('Media source', 'test'); + $page->selectFieldOption('Media source', 'test'); + $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]'); + $this->assertNotEmpty($result); + + $page->pressButton('Save'); + + // Check whether the source field was correctly created. + $this->drupalGet("admin/structure/media/manage/{$mediaTypeMachineName}/fields"); + + // Check 2nd column of first data row, to be machine name for field name. + $assert_session->elementContains('xpath', '(//table[@id="field-overview"]//tr)[2]//td[2]', 'field_media_test'); + // Check 3rd column of first data row, to be correct field type. + $assert_session->elementTextContains('xpath', '(//table[@id="field-overview"]//tr)[2]//td[3]', 'Text (plain)'); + + // Check that the source field is correctly assigned to media type. + $this->drupalGet("admin/structure/media/manage/{$mediaTypeMachineName}"); + + $assert_session->pageTextContains('Test source field is used to store the essential information about the media item.'); + } + + /** + * Test creation of media type, reusing an existing source field. + */ + public function testMediaTypeCreationReuseSourceField() { + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + // Create a new media type, which should create a new field we can reuse. + $this->drupalGet('/admin/structure/media/add'); + $page->fillField('label', 'Pastafazoul'); + $session->wait(5000, "jQuery('.machine-name-value').text() === 'pastafazoul'"); + $page->selectFieldOption('Media source', 'test'); + $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]'); + $this->assertNotEmpty($result); + $page->pressButton('Save'); + + $label = 'Type reusing Default Field'; + $mediaTypeMachineName = str_replace(' ', '_', strtolower($label)); + + $this->drupalGet('admin/structure/media/add'); + + // Fill in a label to the media type. + $page->fillField('label', $label); + + // Wait for machine name generation. Default: waitUntilVisible(), does not + // work properly. + $session->wait(5000, "jQuery('.machine-name-value').text() === '{$mediaTypeMachineName}'"); + + // Select the media source used by our media type. + $assert_session->fieldExists('Media source'); + $assert_session->optionExists('Media source', 'test'); + $page->selectFieldOption('Media source', 'test'); + $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]'); + $this->assertNotEmpty($result); + // Select the existing field for re-use. + $page->selectFieldOption('source_configuration[source_field]', 'field_media_test'); + $page->pressButton('Save'); + + // Check that no new fields were created. + $this->drupalGet("admin/structure/media/manage/{$mediaTypeMachineName}/fields"); + // The reused field should be present... + $assert_session->pageTextContains('field_media_test'); + // ...not a new, unique one. + $assert_session->pageTextNotContains('field_media_test_1'); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php new file mode 100644 index 00000000..981da61d --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaUiJavascriptTest.php @@ -0,0 +1,202 @@ +drupalPlaceBlock('local_actions_block'); + $this->drupalPlaceBlock('local_tasks_block'); + + // We need to test without any default configuration in place. + // @TODO: Remove this as part of https://www.drupal.org/node/2883813. + MediaType::load('file')->delete(); + MediaType::load('image')->delete(); + } + + /** + * Tests a media type administration. + */ + public function testMediaTypes() { + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $this->drupalGet('admin/structure/media'); + $assert_session->pageTextContains('No media types available. Add media type.'); + $assert_session->linkExists('Add media type'); + + // Test the creation of a media type using the UI. + $name = $this->randomMachineName(); + $description = $this->randomMachineName(); + $this->drupalGet('admin/structure/media/add'); + $page->fillField('label', $name); + $machine_name = strtolower($name); + $this->assertJsCondition("jQuery('.machine-name-value').html() == '$machine_name'"); + $page->selectFieldOption('source', 'test'); + $this->assertJsCondition("jQuery('.form-item-source-configuration-test-config-value').length > 0;"); + $page->fillField('description', $description); + $page->pressButton('Save'); + $assert_session->pageTextContains('The media type ' . $name . ' has been added.'); + $this->drupalGet('admin/structure/media'); + $assert_session->pageTextContains($name); + $assert_session->pageTextContains($description); + + // We need to clear the statically cached field definitions to account for + // fields that have been created by API calls in this test, since they exist + // in a separate memory space from the web server. + $this->container->get('entity_field.manager')->clearCachedFieldDefinitions(); + // Assert that the field and field storage were created. + $media_type = MediaType::load($machine_name); + $source = $media_type->getSource(); + /** @var \Drupal\field\FieldConfigInterface $source_field */ + $source_field = $source->getSourceFieldDefinition($media_type); + $this->assertInstanceOf(FieldConfigInterface::class, $source_field, 'Source field exists.'); + $this->assertFalse($source_field->isNew(), 'Source field was saved.'); + /** @var \Drupal\field\FieldStorageConfigInterface $storage */ + $storage = $source_field->getFieldStorageDefinition(); + $this->assertFalse($storage->isNew(), 'Source field storage definition was saved.'); + $this->assertFalse($storage->isLocked(), 'Source field storage definition was not locked.'); + + /** @var \Drupal\media\MediaTypeInterface $media_type_storage */ + $media_type_storage = $this->container->get('entity_type.manager')->getStorage('media_type'); + $this->testMediaType = $media_type_storage->load(strtolower($name)); + + // Check if all action links exist. + $assert_session->linkByHrefExists('admin/structure/media/add'); + $assert_session->linkByHrefExists('admin/structure/media/manage/' . $this->testMediaType->id()); + $assert_session->linkByHrefExists('admin/structure/media/manage/' . $this->testMediaType->id() . '/fields'); + $assert_session->linkByHrefExists('admin/structure/media/manage/' . $this->testMediaType->id() . '/form-display'); + $assert_session->linkByHrefExists('admin/structure/media/manage/' . $this->testMediaType->id() . '/display'); + + // Assert that fields have expected values before editing. + $page->clickLink('Edit'); + $assert_session->fieldValueEquals('label', $name); + $assert_session->fieldValueEquals('description', $description); + $assert_session->fieldValueEquals('source', 'test'); + $assert_session->fieldValueEquals('label', $name); + $assert_session->checkboxNotChecked('edit-options-new-revision'); + $assert_session->checkboxChecked('edit-options-status'); + $assert_session->checkboxNotChecked('edit-options-queue-thumbnail-downloads'); + $assert_session->pageTextContains('Create new revision'); + $assert_session->pageTextContains('Automatically create new revisions. Users with the "Administer media" permission will be able to override this option.'); + $assert_session->pageTextContains('Download thumbnails via a queue.'); + $assert_session->pageTextContains('Media will be automatically published when created.'); + $assert_session->pageTextContains('Media sources can provide metadata fields such as title, caption, size information, credits, etc. Media can automatically save this metadata information to entity fields, which can be configured below. Information will only be mapped if the entity field is empty.'); + + // Try to change media type and check if new configuration sub-form appears. + $page->selectFieldOption('source', 'test'); + $result = $assert_session->waitForElementVisible('css', 'fieldset[data-drupal-selector="edit-source-configuration"]'); + $this->assertNotEmpty($result); + $assert_session->fieldExists('Test config value'); + $assert_session->fieldValueEquals('Test config value', 'This is default value.'); + $assert_session->fieldExists('Attribute 1'); + $assert_session->fieldExists('Attribute 2'); + + // Test if the edit machine name is not editable. + $assert_session->fieldDisabled('Machine-readable name'); + + // Edit and save media type form fields with new values. + $new_name = $this->randomMachineName(); + $new_description = $this->randomMachineName(); + $page->fillField('label', $new_name); + $page->fillField('description', $new_description); + $page->selectFieldOption('source', 'test'); + $page->fillField('Test config value', 'This is new config value.'); + $page->selectFieldOption('field_map[attribute_1]', 'name'); + $page->checkField('options[new_revision]'); + $page->uncheckField('options[status]'); + $page->checkField('options[queue_thumbnail_downloads]'); + $page->pressButton('Save'); + $assert_session->pageTextContains("The media type $new_name has been updated."); + + // Test if edit worked and if new field values have been saved as expected. + $this->drupalGet('admin/structure/media/manage/' . $this->testMediaType->id()); + $assert_session->fieldValueEquals('label', $new_name); + $assert_session->fieldValueEquals('description', $new_description); + $assert_session->fieldValueEquals('source', 'test'); + $assert_session->checkboxChecked('options[new_revision]'); + $assert_session->checkboxNotChecked('options[status]'); + $assert_session->checkboxChecked('options[queue_thumbnail_downloads]'); + $assert_session->fieldValueEquals('Test config value', 'This is new config value.'); + $assert_session->fieldValueEquals('Attribute 1', 'name'); + $assert_session->fieldValueEquals('Attribute 2', MediaSourceInterface::METADATA_FIELD_EMPTY); + + /** @var \Drupal\media\MediaTypeInterface $loaded_media_type */ + $loaded_media_type = $this->container->get('entity_type.manager') + ->getStorage('media_type') + ->load($this->testMediaType->id()); + $this->assertEquals($loaded_media_type->id(), $this->testMediaType->id()); + $this->assertEquals($loaded_media_type->label(), $new_name); + $this->assertEquals($loaded_media_type->getDescription(), $new_description); + $this->assertEquals($loaded_media_type->getSource()->getPluginId(), 'test'); + $this->assertEquals($loaded_media_type->getSource()->getConfiguration()['test_config_value'], 'This is new config value.'); + $this->assertTrue($loaded_media_type->shouldCreateNewRevision()); + $this->assertTrue($loaded_media_type->thumbnailDownloadsAreQueued()); + $this->assertFalse($loaded_media_type->getStatus()); + $this->assertEquals($loaded_media_type->getFieldMap(), ['attribute_1' => 'name']); + + // We need to clear the statically cached field definitions to account for + // fields that have been created by API calls in this test, since they exist + // in a separate memory space from the web server. + $this->container->get('entity_field.manager')->clearCachedFieldDefinitions(); + + // Test that a media item being created with default status to "FALSE", + // will be created unpublished. + /** @var \Drupal\media\MediaInterface $unpublished_media */ + $unpublished_media = Media::create(['name' => 'unpublished test media', 'bundle' => $loaded_media_type->id()]); + $this->assertFalse($unpublished_media->isPublished()); + $unpublished_media->delete(); + + // Tests media type delete form. + $page->clickLink('Delete'); + $assert_session->addressEquals('admin/structure/media/manage/' . $this->testMediaType->id() . '/delete'); + $page->pressButton('Delete'); + $assert_session->addressEquals('admin/structure/media'); + $assert_session->pageTextContains('The media type ' . $new_name . ' has been deleted.'); + + // Test that the system for preventing the deletion of media types works + // (they cannot be deleted if there is media content of that type/bundle). + $media_type2 = $this->createMediaType(); + $label2 = $media_type2->label(); + $media = Media::create(['name' => 'lorem ipsum', 'bundle' => $media_type2->id()]); + $media->save(); + $this->drupalGet('admin/structure/media/manage/' . $media_type2->id()); + $page->clickLink('Delete'); + $assert_session->addressEquals('admin/structure/media/manage/' . $media_type2->id() . '/delete'); + $assert_session->buttonNotExists('edit-submit'); + $assert_session->pageTextContains("$label2 is used by 1 media item on your site. You can not remove this media type until you have removed all of the $label2 media items."); + } + +} diff --git a/core/modules/media/tests/src/FunctionalJavascript/MediaViewsWizardTest.php b/core/modules/media/tests/src/FunctionalJavascript/MediaViewsWizardTest.php new file mode 100644 index 00000000..94e89c6a --- /dev/null +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaViewsWizardTest.php @@ -0,0 +1,87 @@ +getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $view_id = strtolower($this->randomMachineName(16)); + $this->drupalGet('admin/structure/views/add'); + $page->fillField('label', $view_id); + $this->waitUntilVisible('.machine-name-value'); + $page->selectFieldOption('show[wizard_key]', 'media'); + $result = $assert_session->waitForElementVisible('css', 'select[data-drupal-selector="edit-show-type"]'); + $this->assertNotEmpty($result); + $page->checkField('page[create]'); + $page->fillField('page[path]', $this->randomMachineName(16)); + $page->pressButton('Save and edit'); + $this->assertEquals($session->getCurrentUrl(), $this->baseUrl . '/admin/structure/views/view/' . $view_id); + + $view = Views::getView($view_id); + $view->initHandlers(); + $row = $view->display_handler->getOption('row'); + $this->assertEquals($row['type'], 'fields'); + // Check for the default filters. + $this->assertEquals($view->filter['status']->table, 'media_field_data'); + $this->assertEquals($view->filter['status']->field, 'status'); + $this->assertTrue($view->filter['status']->value); + // Check for the default fields. + $this->assertEquals($view->field['name']->table, 'media_field_data'); + $this->assertEquals($view->field['name']->field, 'name'); + + } + + /** + * Tests adding a view of media revisions. + */ + public function testMediaRevisionWizard() { + $session = $this->getSession(); + $page = $session->getPage(); + $assert_session = $this->assertSession(); + + $view_id = strtolower($this->randomMachineName(16)); + $this->drupalGet('admin/structure/views/add'); + $page->fillField('label', $view_id); + $this->waitUntilVisible('.machine-name-value'); + $page->selectFieldOption('show[wizard_key]', 'media_revision'); + $assert_session->assertWaitOnAjaxRequest(); + $page->checkField('page[create]'); + $page->fillField('page[path]', $this->randomMachineName(16)); + $page->pressButton('Save and edit'); + $this->assertEquals($session->getCurrentUrl(), $this->baseUrl . '/admin/structure/views/view/' . $view_id); + + $view = Views::getView($view_id); + $view->initHandlers(); + $row = $view->display_handler->getOption('row'); + $this->assertEquals($row['type'], 'fields'); + + // Check for the default filters. + $this->assertEquals($view->filter['status']->table, 'media_field_revision'); + $this->assertEquals($view->filter['status']->field, 'status'); + $this->assertTrue($view->filter['status']->value); + + // Check for the default fields. + $this->assertEquals($view->field['name']->table, 'media_field_revision'); + $this->assertEquals($view->field['name']->field, 'name'); + $this->assertEquals($view->field['changed']->table, 'media_field_revision'); + $this->assertEquals($view->field['changed']->field, 'changed'); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaCreationTest.php b/core/modules/media/tests/src/Kernel/MediaCreationTest.php new file mode 100644 index 00000000..baf837f2 --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaCreationTest.php @@ -0,0 +1,58 @@ +container->get('entity_type.manager')->getStorage('media_type'); + + $this->assertInstanceOf(MediaTypeInterface::class, MediaType::load($this->testMediaType->id()), 'The new media type has not been correctly created in the database.'); + + // Test a media type created from default configuration. + $this->container->get('module_installer')->install(['media_test_type']); + $test_media_type = $media_type_storage->load('test'); + $this->assertInstanceOf(MediaTypeInterface::class, $test_media_type, 'The media type from default configuration has not been created in the database.'); + $this->assertEquals('Test type', $test_media_type->get('label'), 'Could not assure the correct type name.'); + $this->assertEquals('Test type.', $test_media_type->get('description'), 'Could not assure the correct type description.'); + $this->assertEquals('test', $test_media_type->get('source'), 'Could not assure the correct media source.'); + // Source field is not set on the media source, but it should never + // be created automatically when a config is being imported. + $this->assertEquals(['source_field' => '', 'test_config_value' => 'Kakec'], $test_media_type->get('source_configuration'), 'Could not assure the correct media source configuration.'); + $this->assertEquals(['metadata_attribute' => 'field_attribute_config_test'], $test_media_type->get('field_map'), 'Could not assure the correct field map.'); + } + + /** + * Tests creating a media item programmatically. + */ + public function testMediaEntityCreation() { + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'name' => 'Unnamed', + 'field_media_test' => 'Nation of sheep, ruled by wolves, owned by pigs.', + ]); + $media->save(); + + $this->assertNotInstanceOf(MediaInterface::class, Media::load(rand(1000, 9999)), 'Failed asserting a non-existent media.'); + + $this->assertInstanceOf(MediaInterface::class, Media::load($media->id()), 'The new media item has not been created in the database.'); + $this->assertEquals($this->testMediaType->id(), $media->bundle(), 'The media item was not created with the correct type.'); + $this->assertEquals('Unnamed', $media->getName(), 'The media item was not created with the correct name.'); + $source_field_name = $media->bundle->entity->getSource()->getSourceFieldDefinition($media->bundle->entity)->getName(); + $this->assertEquals('Nation of sheep, ruled by wolves, owned by pigs.', $media->get($source_field_name)->value, 'Source returns incorrect source field value.'); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaKernelTestBase.php b/core/modules/media/tests/src/Kernel/MediaKernelTestBase.php new file mode 100644 index 00000000..fa39962c --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaKernelTestBase.php @@ -0,0 +1,150 @@ +installEntitySchema('user'); + $this->installEntitySchema('file'); + $this->installSchema('file', 'file_usage'); + $this->installSchema('system', 'sequences'); + $this->installEntitySchema('media'); + $this->installConfig(['field', 'system', 'image', 'file', 'media']); + + // Create a test media type. + $this->testMediaType = $this->createMediaType('test'); + // Create a test media type with constraints. + $this->testConstraintsMediaType = $this->createMediaType('test_constraints'); + + $this->user = User::create([ + 'name' => 'username', + 'status' => 1, + ]); + $this->user->save(); + $this->container->get('current_user')->setAccount($this->user); + } + + /** + * Create a media type for a source plugin. + * + * @param string $media_source_name + * The name of the media source. + * + * @return \Drupal\media\MediaTypeInterface + * A media type. + */ + protected function createMediaType($media_source_name) { + $id = strtolower($this->randomMachineName()); + $media_type = MediaType::create([ + 'id' => $id, + 'label' => $id, + 'source' => $media_source_name, + 'new_revision' => FALSE, + ]); + $media_type->save(); + $source_field = $media_type->getSource()->createSourceField($media_type); + // The media type form creates a source field if it does not exist yet. The + // same must be done in a kernel test, since it does not use that form. + // @see \Drupal\media\MediaTypeForm::save() + $source_field->getFieldStorageDefinition()->save(); + // The source field storage has been created, now the field can be saved. + $source_field->save(); + $media_type->set('source_configuration', [ + 'source_field' => $source_field->getName(), + ])->save(); + return $media_type; + } + + /** + * Helper to generate media entity. + * + * @param string $filename + * String filename with extension. + * @param \Drupal\media\MediaTypeInterface $media_type + * The the media type. + * + * @return \Drupal\media\Entity\Media + * A media entity. + */ + protected function generateMedia($filename, MediaTypeInterface $media_type) { + vfsStream::setup('drupal_root'); + vfsStream::create([ + 'sites' => [ + 'default' => [ + 'files' => [ + $filename => str_repeat('a', 3000), + ], + ], + ], + ]); + + $file = File::create([ + 'uri' => 'vfs://drupal_root/sites/default/files/' . $filename, + 'uid' => $this->user->id(), + ]); + $file->setPermanent(); + $file->save(); + + return Media::create([ + 'bundle' => $media_type->id(), + 'name' => 'Mr. Jones', + 'field_media_file' => [ + 'target_id' => $file->id(), + ], + ]); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaLinkRelationsTest.php b/core/modules/media/tests/src/Kernel/MediaLinkRelationsTest.php new file mode 100644 index 00000000..164df60e --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaLinkRelationsTest.php @@ -0,0 +1,27 @@ +container->get('plugin.manager.link_relation_type'); + $media = Media::create(['bundle' => $this->testMediaType->id()]); + $media->save(); + foreach ($media->uriRelationships() as $relation_name) { + $this->assertTrue($link_relation_type_manager->hasDefinition($relation_name), "Link relationship '{$relation_name}' for Media entity"); + } + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaSourceFileTest.php b/core/modules/media/tests/src/Kernel/MediaSourceFileTest.php new file mode 100644 index 00000000..d716e15b --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaSourceFileTest.php @@ -0,0 +1,44 @@ +delete(); + MediaType::load('image')->delete(); + } + + /** + * Tests the file extension constraint. + */ + public function testFileExtensionConstraint() { + $mediaType = $this->createMediaType('file'); + // Create a random file that should fail. + $media = $this->generateMedia('test.patch', $mediaType); + $result = $media->validate(); + $this->assertCount(1, $result); + $this->assertEquals('field_media_file.0', $result->get(0)->getPropertyPath()); + $this->assertContains('Only files with the following extensions are allowed:', (string) $result->get(0)->getMessage()); + + // Create a random file that should pass. + $media = $this->generateMedia('test.txt', $mediaType); + $result = $media->validate(); + $this->assertCount(0, $result); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaSourceTest.php b/core/modules/media/tests/src/Kernel/MediaSourceTest.php new file mode 100644 index 00000000..fc30326f --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaSourceTest.php @@ -0,0 +1,445 @@ + $this->testMediaType->id()]); + $media_source = $media->getSource(); + $this->assertEquals('default_name', $media_source->getPluginDefinition()['default_name_metadata_attribute'], 'Default metadata attribute is not used for the default name.'); + $this->assertEquals('media:' . $media->bundle() . ':' . $media->uuid(), $media_source->getMetadata($media, 'default_name'), 'Value of the default name metadata attribute does not look correct.'); + $this->assertEquals('media:' . $media->bundle() . ':' . $media->uuid(), $media->getName(), 'Default name was not used correctly by getName().'); + $this->assertEquals($media->getName(), $media->label(), 'Default name and label are not the same.'); + $media->save(); + $this->assertEquals('media:' . $media->bundle() . ':' . $media->uuid(), $media->getName(), 'Default name was not saved correctly.'); + $this->assertEquals($media->getName(), $media->label(), 'The label changed during save.'); + + // Make sure that the user-supplied name is used. + /** @var \Drupal\media\MediaInterface $media */ + $name = 'User-supplied name'; + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'name' => $name, + ]); + $media_source = $media->getSource(); + $this->assertEquals('default_name', $media_source->getPluginDefinition()['default_name_metadata_attribute'], 'Default metadata attribute is not used for the default name.'); + $this->assertEquals('media:' . $media->bundle() . ':' . $media->uuid(), $media_source->getMetadata($media, 'default_name'), 'Value of the default name metadata attribute does not look correct.'); + $media->save(); + $this->assertEquals($name, $media->getName(), 'User-supplied name was not set correctly.'); + $this->assertEquals($media->getName(), $media->label(), 'The user-supplied name does not match the label.'); + + // Change the default name attribute and see if it is used to set the name. + $name = 'Old Major'; + \Drupal::state()->set('media_source_test_attributes', ['alternative_name' => ['title' => 'Alternative name', 'value' => $name]]); + \Drupal::state()->set('media_source_test_definition', ['default_name_metadata_attribute' => 'alternative_name']); + /** @var \Drupal\media\MediaInterface $media */ + $media = Media::create(['bundle' => $this->testMediaType->id()]); + $media_source = $media->getSource(); + $this->assertEquals('alternative_name', $media_source->getPluginDefinition()['default_name_metadata_attribute'], 'Correct metadata attribute is not used for the default name.'); + $this->assertEquals($name, $media_source->getMetadata($media, 'alternative_name'), 'Value of the default name metadata attribute does not look correct.'); + $media->save(); + $this->assertEquals($name, $media->getName(), 'Default name was not set correctly.'); + $this->assertEquals($media->getName(), $media->label(), 'The default name does not match the label.'); + } + + /** + * Tests metadata mapping functionality. + */ + public function testMetadataMapping() { + $field_name = 'field_to_map_to'; + $attribute_name = 'attribute_to_map'; + $storage = FieldStorageConfig::create([ + 'entity_type' => 'media', + 'field_name' => $field_name, + 'type' => 'string', + ]); + $storage->save(); + + FieldConfig::create([ + 'field_storage' => $storage, + 'bundle' => $this->testMediaType->id(), + 'label' => 'Field to map to', + ])->save(); + + // Save the entity without defining the metadata mapping and check that the + // field stays empty. + /** @var \Drupal\media\MediaInterface $media */ + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'field_media_test' => 'some_value', + ]); + $media->save(); + $this->assertEmpty($media->get($field_name)->value, 'Field stayed empty.'); + + // Make sure that source plugin returns NULL for non-existing fields. + $this->testMediaType->setFieldMap(['not_here_at_all' => $field_name])->save(); + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'field_media_test' => 'some_value', + ]); + $media_source = $media->getSource(); + $this->assertNull($media_source->getMetadata($media, 'not_here_at_all'), 'NULL is not returned if asking for a value of non-existing metadata.'); + $media->save(); + $this->assertTrue($media->get($field_name)->isEmpty(), 'Non-existing metadata attribute was wrongly mapped to the field.'); + + // Define mapping and make sure that the value was stored in the field. + \Drupal::state()->set('media_source_test_attributes', [ + $attribute_name => ['title' => 'Attribute to map', 'value' => 'Snowball'], + ]); + $this->testMediaType->setFieldMap([$attribute_name => $field_name])->save(); + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'field_media_test' => 'some_value', + ]); + $media_source = $media->getSource(); + $this->assertEquals('Snowball', $media_source->getMetadata($media, $attribute_name), 'Value of the metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('Snowball', $media->get($field_name)->value, 'Metadata attribute was not mapped to the field.'); + + // Change the metadata attribute value and re-save the entity. Field value + // should stay the same. + \Drupal::state()->set('media_source_test_attributes', [ + $attribute_name => ['title' => 'Attribute to map', 'value' => 'Pinkeye'], + ]); + $this->assertEquals('Pinkeye', $media_source->getMetadata($media, $attribute_name), 'Value of the metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('Snowball', $media->get($field_name)->value, 'Metadata attribute was not mapped to the field.'); + + // Now change the value of the source field and make sure that the mapped + // values update too. + $this->assertEquals('Pinkeye', $media_source->getMetadata($media, $attribute_name), 'Value of the metadata attribute is not correct.'); + $media->set('field_media_test', 'some_new_value'); + $media->save(); + $this->assertEquals('Pinkeye', $media->get($field_name)->value, 'Metadata attribute was not mapped to the field.'); + + // Remove the value of the mapped field and make sure that it is re-mapped + // on save. + \Drupal::state()->set('media_source_test_attributes', [ + $attribute_name => ['title' => 'Attribute to map', 'value' => 'Snowball'], + ]); + $media->{$field_name}->value = NULL; + $this->assertEquals('Snowball', $media_source->getMetadata($media, $attribute_name), 'Value of the metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('Snowball', $media->get($field_name)->value, 'Metadata attribute was not mapped to the field.'); + } + + /** + * Tests the thumbnail functionality. + */ + public function testThumbnail() { + file_put_contents('public://thumbnail1.jpg', ''); + file_put_contents('public://thumbnail2.jpg', ''); + + // Save a media entity and make sure thumbnail was added. + \Drupal::state()->set('media_source_test_attributes', [ + 'thumbnail_uri' => ['title' => 'Thumbnail', 'value' => 'public://thumbnail1.jpg'], + ]); + /** @var \Drupal\media\MediaInterface $media */ + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'name' => 'Mr. Jones', + 'field_media_test' => 'some_value', + ]); + $media_source = $media->getSource(); + $this->assertEquals('public://thumbnail1.jpg', $media_source->getMetadata($media, 'thumbnail_uri'), 'Value of the thumbnail metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('public://thumbnail1.jpg', $media->thumbnail->entity->getFileUri(), 'Thumbnail was not added to the media entity.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Now change the metadata attribute and make sure that the thumbnail stays + // the same. + \Drupal::state()->set('media_source_test_attributes', [ + 'thumbnail_uri' => ['title' => 'Thumbnail', 'value' => 'public://thumbnail2.jpg'], + ]); + $this->assertEquals('public://thumbnail2.jpg', $media_source->getMetadata($media, 'thumbnail_uri'), 'Value of the thumbnail metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('public://thumbnail1.jpg', $media->thumbnail->entity->getFileUri(), 'Thumbnail was not preserved.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Remove the thumbnail and make sure that it is auto-updated on save. + $media->thumbnail->target_id = NULL; + $this->assertEquals('public://thumbnail2.jpg', $media_source->getMetadata($media, 'thumbnail_uri'), 'Value of the thumbnail metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('public://thumbnail2.jpg', $media->thumbnail->entity->getFileUri(), 'New thumbnail was not added to the media entity.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Change the metadata attribute again, change the source field value too + // and make sure that the thumbnail updates. + \Drupal::state()->set('media_source_test_attributes', [ + 'thumbnail_uri' => ['title' => 'Thumbnail', 'value' => 'public://thumbnail1.jpg'], + ]); + $media->field_media_test->value = 'some_new_value'; + $this->assertEquals('public://thumbnail1.jpg', $media_source->getMetadata($media, 'thumbnail_uri'), 'Value of the thumbnail metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('public://thumbnail1.jpg', $media->thumbnail->entity->getFileUri(), 'New thumbnail was not added to the media entity.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Change the thumbnail metadata attribute and make sure that the thumbnail + // is set correctly. + \Drupal::state()->set('media_source_test_attributes', [ + 'thumbnail_uri' => ['title' => 'Should not be used', 'value' => 'public://thumbnail1.jpg'], + 'alternative_thumbnail_uri' => ['title' => 'Should be used', 'value' => 'public://thumbnail2.jpg'], + ]); + \Drupal::state()->set('media_source_test_definition', ['thumbnail_uri_metadata_attribute' => 'alternative_thumbnail_uri']); + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'name' => 'Mr. Jones', + 'field_media_test' => 'some_value', + ]); + $media_source = $media->getSource(); + $this->assertEquals('public://thumbnail1.jpg', $media_source->getMetadata($media, 'thumbnail_uri'), 'Value of the metadata attribute is not correct.'); + $this->assertEquals('public://thumbnail2.jpg', $media_source->getMetadata($media, 'alternative_thumbnail_uri'), 'Value of the thumbnail metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('public://thumbnail2.jpg', $media->thumbnail->entity->getFileUri(), 'Correct metadata attribute was not used for the thumbnail.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Enable queued thumbnails and make sure that the entity gets the default + // thumbnail initially. + \Drupal::state()->set('media_source_test_definition', []); + \Drupal::state()->set('media_source_test_attributes', [ + 'thumbnail_uri' => ['title' => 'Should not be used', 'value' => 'public://thumbnail1.jpg'], + ]); + $this->testMediaType->setQueueThumbnailDownloadsStatus(TRUE)->save(); + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'name' => 'Mr. Jones', + 'field_media_test' => 'some_value', + ]); + $this->assertEquals('public://thumbnail1.jpg', $media->getSource()->getMetadata($media, 'thumbnail_uri'), 'Value of the metadata attribute is not correct.'); + $media->save(); + $this->assertEquals('public://media-icons/generic/generic.png', $media->thumbnail->entity->getFileUri(), 'Default thumbnail was not set initially.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Process the queue item and make sure that the thumbnail was updated too. + $queue_name = 'media_entity_thumbnail'; + /** @var \Drupal\Core\Queue\QueueWorkerInterface $queue_worker */ + $queue_worker = \Drupal::service('plugin.manager.queue_worker')->createInstance($queue_name); + $queue = \Drupal::queue($queue_name); + $this->assertEquals(1, $queue->numberOfItems(), 'Item was not added to the queue.'); + + $item = $queue->claimItem(); + $this->assertEquals($media->id(), $item->data['id'], 'Queue item that was created does not belong to the correct entity.'); + + $queue_worker->processItem($item->data); + $queue->deleteItem($item); + $this->assertEquals(0, $queue->numberOfItems(), 'Item was not removed from the queue.'); + + $media = Media::load($media->id()); + $this->assertEquals('public://thumbnail1.jpg', $media->thumbnail->entity->getFileUri(), 'Thumbnail was not updated by the queue.'); + $this->assertEquals('Mr. Jones', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('Thumbnail', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + + // Set alt and title metadata attributes and make sure they are used for the + // thumbnail. + \Drupal::state()->set('media_source_test_definition', [ + 'thumbnail_alt_metadata_attribute' => 'alt', + 'thumbnail_title_metadata_attribute' => 'title', + ]); + \Drupal::state()->set('media_source_test_attributes', [ + 'alt' => ['title' => 'Alt text', 'value' => 'This will be alt.'], + 'title' => ['title' => 'Title text', 'value' => 'This will be title.'], + ]); + $media = Media::create([ + 'bundle' => $this->testMediaType->id(), + 'name' => 'Boxer', + 'field_media_test' => 'some_value', + ]); + $media->save(); + $this->assertEquals('Boxer', $media->getName(), 'Correct name was not set on the media entity.'); + $this->assertEquals('This will be title.', $media->thumbnail->title, 'Title text was not set on the thumbnail.'); + $this->assertEquals('This will be alt.', $media->thumbnail->alt, 'Alt text was not set on the thumbnail.'); + } + + /** + * Tests the media entity constraints functionality. + */ + public function testConstraints() { + // Test entity constraints. + \Drupal::state()->set('media_source_test_entity_constraints', [ + 'MediaTestConstraint' => [], + ]); + + // Create a media item media that uses a source plugin with constraints and + // make sure the constraints works as expected when validating. + /** @var \Drupal\media\MediaInterface $media */ + $media = Media::create([ + 'bundle' => $this->testConstraintsMediaType->id(), + 'name' => 'I do not like Drupal', + 'field_media_test_constraints' => 'Not checked', + ]); + + // Validate the entity and make sure violation is reported. + /** @var \Drupal\Core\Entity\EntityConstraintViolationListInterface $violations */ + $violations = $media->validate(); + $this->assertCount(1, $violations, 'Expected number of validations not found.'); + $this->assertEquals('Inappropriate text.', $violations->get(0)->getMessage(), 'Incorrect constraint validation message found.'); + + // Fix the violation and make sure it is not reported anymore. + $media->setName('I love Drupal!'); + $violations = $media->validate(); + $this->assertCount(0, $violations, 'Expected number of validations not found.'); + + // Save and make sure it succeeded. + $this->assertEmpty($media->id(), 'Entity ID was found.'); + $media->save(); + $this->assertNotEmpty($media->id(), 'Entity ID was not found.'); + $this->assertSame($media->getName(), 'I love Drupal!'); + + // Test source field constraints. + \Drupal::state()->set('media_source_test_field_constraints', [ + 'MediaTestConstraint' => [], + ]); + \Drupal::state()->set('media_source_test_entity_constraints', []); + + // Create media that uses source with constraints and make sure it can't + // be saved without validating them. + /** @var \Drupal\media\MediaInterface $media */ + $media = Media::create([ + 'bundle' => $this->testConstraintsMediaType->id(), + 'name' => 'Not checked', + 'field_media_test_constraints' => 'I do not like Drupal', + ]); + + // Validate the entity and make sure violation is reported. + /** @var \Drupal\Core\Entity\EntityConstraintViolationListInterface $violations */ + $violations = $media->validate(); + $this->assertCount(1, $violations, 'Expected number of validations not found.'); + $this->assertEquals('Inappropriate text.', $violations->get(0)->getMessage(), 'Incorrect constraint validation message found.'); + + // Fix the violation and make sure it is not reported anymore. + $media->set('field_media_test_constraints', 'I love Drupal!'); + $violations = $media->validate(); + $this->assertCount(0, $violations, 'Expected number of validations not found.'); + + // Save and make sure it succeeded. + $this->assertEmpty($media->id(), 'Entity ID was found.'); + $media->save(); + $this->assertNotEmpty($media->id(), 'Entity ID was not found.'); + } + + /** + * Tests logic related to the automated source field creation. + */ + public function testSourceFieldCreation() { + /** @var \Drupal\media\MediaTypeInterface $type */ + $type = MediaType::create([ + 'id' => 'test_type', + 'label' => 'Test type', + 'source' => 'test', + ]); + + /** @var \Drupal\field\Entity\FieldConfig $field */ + $field = $type->getSource()->createSourceField($type); + /** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */ + $field_storage = $field->getFieldStorageDefinition(); + + // Test field storage. + $this->assertTrue($field_storage->isNew(), 'Field storage is saved automatically.'); + $this->assertFalse($field_storage->isLocked(), 'Field storage is not locked.'); + $this->assertEquals('string', $field_storage->getType(), 'Field is not of correct type.'); + $this->assertEquals('field_media_test_1', $field_storage->getName(), 'Incorrect field name is used.'); + $this->assertEquals('media', $field_storage->getTargetEntityTypeId(), 'Field is not targeting media entities.'); + + // Test field. + $this->assertTrue($field->isNew(), 'Field is saved automatically.'); + $this->assertEquals('field_media_test_1', $field->getName(), 'Incorrect field name is used.'); + $this->assertEquals('string', $field->getType(), 'Field is of incorrect type.'); + $this->assertTrue($field->isRequired(), 'Field is not required.'); + $this->assertEquals('Test source', $field->label(), 'Incorrect label is used.'); + $this->assertEquals('test_type', $field->getTargetBundle(), 'Field is not targeting correct bundle.'); + + // Fields should be automatically saved only when creating the media type + // using the media type creation form. Make sure that they are not saved + // when creating a media type programmatically. + // Drupal\Tests\media\FunctionalJavascript\MediaTypeCreationTest is testing + // form part of the functionality. + $type->save(); + $storage = FieldStorageConfig::load('media.field_media_test_1'); + $this->assertNull($storage, 'Field storage was not saved.'); + $field = FieldConfig::load('media.test_type.field_media_test_1'); + $this->assertNull($field, 'Field storage was not saved.'); + + // Test the plugin with a different default source field type. + $type = MediaType::create([ + 'id' => 'test_constraints_type', + 'label' => 'Test type with constraints', + 'source' => 'test_constraints', + ]); + $field = $type->getSource()->createSourceField($type); + $field_storage = $field->getFieldStorageDefinition(); + + // Test field storage. + $this->assertTrue($field_storage->isNew(), 'Field storage is saved automatically.'); + $this->assertFalse($field_storage->isLocked(), 'Field storage is not locked.'); + $this->assertEquals('string_long', $field_storage->getType(), 'Field is of incorrect type.'); + $this->assertEquals('field_media_test_constraints_1', $field_storage->getName(), 'Incorrect field name is used.'); + $this->assertEquals('media', $field_storage->getTargetEntityTypeId(), 'Field is not targeting media entities.'); + + // Test field. + $this->assertTrue($field->isNew(), 'Field is saved automatically.'); + $this->assertEquals('field_media_test_constraints_1', $field->getName(), 'Incorrect field name is used.'); + $this->assertEquals('string_long', $field->getType(), 'Field is of incorrect type.'); + $this->assertTrue($field->isRequired(), 'Field is not required.'); + $this->assertEquals('Test source with constraints', $field->label(), 'Incorrect label is used.'); + $this->assertEquals('test_constraints_type', $field->getTargetBundle(), 'Field is not targeting correct bundle.'); + } + + /** + * Tests configuration form submit handler on the base media source plugin. + */ + public function testSourceConfigurationSubmit() { + /** @var \Drupal\media\MediaSourceManager $manager */ + $manager = $this->container->get('plugin.manager.media.source'); + $form = []; + $form_state = new FormState(); + $form_state->setValues(['test_config_value' => 'Somewhere over the rainbow.']); + + /** @var \Drupal\media\MediaSourceInterface $source */ + $source = $manager->createInstance('test', []); + $source->submitConfigurationForm($form, $form_state); + $expected = ['test_config_value' => 'Somewhere over the rainbow.', 'source_field' => 'field_media_test_1']; + $this->assertEquals($expected, $source->getConfiguration(), 'Submitted values were saved correctly.'); + + // Try to save a NULL value. + $form_state->setValue('test_config_value', NULL); + $source->submitConfigurationForm($form, $form_state); + $expected['test_config_value'] = NULL; + $this->assertEquals($expected, $source->getConfiguration(), 'Submitted values were saved correctly.'); + + // Make sure that the config keys are determined correctly even if the + // existing value is NULL. + $form_state->setValue('test_config_value', 'Somewhere over the rainbow.'); + $source->submitConfigurationForm($form, $form_state); + $expected['test_config_value'] = 'Somewhere over the rainbow.'; + $this->assertEquals($expected, $source->getConfiguration(), 'Submitted values were saved correctly.'); + + // Make sure that a non-relevant value will be skipped. + $form_state->setValue('not_relevant', 'Should not be saved in the plugin.'); + $source->submitConfigurationForm($form, $form_state); + $this->assertEquals($expected, $source->getConfiguration(), 'Submitted values were saved correctly.'); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaTest.php b/core/modules/media/tests/src/Kernel/MediaTest.php new file mode 100644 index 00000000..5971f653 --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaTest.php @@ -0,0 +1,23 @@ + $this->testMediaType->id()]); + + $this->assertSame($media, $media->setOwnerId($this->user->id()), 'setOwnerId() method returns its own entity.'); + } + +} diff --git a/core/modules/media/tests/src/Kernel/MediaTranslationTest.php b/core/modules/media/tests/src/Kernel/MediaTranslationTest.php new file mode 100644 index 00000000..009e7c4d --- /dev/null +++ b/core/modules/media/tests/src/Kernel/MediaTranslationTest.php @@ -0,0 +1,103 @@ +installConfig(['language']); + + // Create a test media type for translations. + $this->testTranslationMediaType = $this->createMediaType('test_translation'); + + for ($i = 0; $i < 3; ++$i) { + $language_id = 'l' . $i; + ConfigurableLanguage::create([ + 'id' => $language_id, + 'label' => $this->randomString(), + ])->save(); + file_put_contents('public://' . $language_id . '.png', ''); + } + } + + /** + * Test translatable fields storage/retrieval. + */ + public function testTranslatableFieldSaveLoad() { + /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */ + $entity_type = $this->container->get('entity_type.manager')->getDefinition('media'); + $this->assertTrue($entity_type->isTranslatable(), 'Media is translatable.'); + + // Prepare the field translations. + $source_field_definition = $this->testTranslationMediaType->getSource()->getSourceFieldDefinition($this->testTranslationMediaType); + $source_field_storage = $source_field_definition->getFieldStorageDefinition(); + /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $media_storage */ + $media_storage = $this->container->get('entity_type.manager')->getStorage('media'); + /** @var \Drupal\media\Entity\Media $media */ + $media = $media_storage->create([ + 'bundle' => $this->testTranslationMediaType->id(), + 'name' => 'Unnamed', + ]); + + $field_translations = []; + $available_langcodes = array_keys($this->container->get('language_manager')->getLanguages()); + $media->set('langcode', reset($available_langcodes)); + foreach ($available_langcodes as $langcode) { + $values = []; + for ($i = 0; $i < $source_field_storage->getCardinality(); $i++) { + $values[$i]['value'] = $this->randomString(); + } + $field_translations[$langcode] = $values; + $translation = $media->hasTranslation($langcode) ? $media->getTranslation($langcode) : $media->addTranslation($langcode); + $translation->{$source_field_definition->getName()}->setValue($field_translations[$langcode]); + } + + // Save and reload the field translations. + $media->save(); + $media_storage->resetCache(); + $media = $media_storage->load($media->id()); + + // Check if the correct source field values were saved/loaded. + foreach ($field_translations as $langcode => $items) { + /** @var \Drupal\media\MediaInterface $media_translation */ + $media_translation = $media->getTranslation($langcode); + $result = TRUE; + foreach ($items as $delta => $item) { + $result = $result && $item['value'] == $media_translation->{$source_field_definition->getName()}[$delta]->value; + } + $this->assertTrue($result, new FormattableMarkup('%language translation field value not correct.', ['%language' => $langcode])); + $this->assertEquals('public://' . $langcode . '.png', $media_translation->getSource()->getMetadata($media_translation, 'thumbnail_uri'), new FormattableMarkup('%language translation thumbnail metadata attribute is not correct.', ['%language' => $langcode])); + $this->assertEquals('public://' . $langcode . '.png', $media_translation->get('thumbnail')->entity->getFileUri(), new FormattableMarkup('%language translation thumbnail value is not correct.', ['%language' => $langcode])); + $this->assertEquals('Test Thumbnail ' . $langcode, $media_translation->getSource()->getMetadata($media_translation, 'test_thumbnail_alt'), new FormattableMarkup('%language translation thumbnail alt metadata attribute is not correct.', ['%language' => $langcode])); + $this->assertEquals('Test Thumbnail ' . $langcode, $media_translation->get('thumbnail')->alt, new FormattableMarkup('%language translation thumbnail alt value is not correct.', ['%language' => $langcode])); + } + } + +} diff --git a/core/modules/menu_link_content/menu_link_content.info.yml b/core/modules/menu_link_content/menu_link_content.info.yml index 48f55880..a62369af 100644 --- a/core/modules/menu_link_content/menu_link_content.info.yml +++ b/core/modules/menu_link_content/menu_link_content.info.yml @@ -7,8 +7,8 @@ package: Core dependencies: - link -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/menu_link_content/menu_link_content.module b/core/modules/menu_link_content/menu_link_content.module index 98357c6c..f94a139d 100644 --- a/core/modules/menu_link_content/menu_link_content.module +++ b/core/modules/menu_link_content/menu_link_content.module @@ -5,6 +5,7 @@ * Allows administrators to create custom menu links. */ +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\system\MenuInterface; @@ -18,10 +19,10 @@ function menu_link_content_help($route_name, RouteMatchInterface $route_match) { $output .= '

    ' . t('About') . '

    '; $output .= '

    ' . t('The Custom Menu Links module allows users to create menu links. These links can be translated if multiple languages are used for the site.'); if (\Drupal::moduleHandler()->moduleExists('menu_ui')) { - $output .= ' ' . t('It is required by the Menu UI module, which provides an interface for managing menus and menu links. For more information, see the Menu UI module help page and the online documentation for the Custom Menu Links module.', array(':menu-help' => \Drupal::url('help.page', array('name' => 'menu_ui')), ':drupal-org-help' => 'https://www.drupal.org/documentation/modules/menu_link')); + $output .= ' ' . t('It is required by the Menu UI module, which provides an interface for managing menus and menu links. For more information, see the Menu UI module help page and the online documentation for the Custom Menu Links module.', [':menu-help' => \Drupal::url('help.page', ['name' => 'menu_ui']), ':drupal-org-help' => 'https://www.drupal.org/documentation/modules/menu_link']); } else { - $output .= ' ' . t('For more information, see the online documentation for the Custom Menu Links module. If you enable the Menu UI module, it provides an interface for managing menus and menu links.', array(':drupal-org-help' => 'https://www.drupal.org/documentation/modules/menu_link')); + $output .= ' ' . t('For more information, see the online documentation for the Custom Menu Links module. If you enable the Menu UI module, it provides an interface for managing menus and menu links.', [':drupal-org-help' => 'https://www.drupal.org/documentation/modules/menu_link']); } $output .= '

    '; return $output; @@ -33,7 +34,7 @@ function menu_link_content_help($route_name, RouteMatchInterface $route_match) { */ function menu_link_content_menu_delete(MenuInterface $menu) { $storage = \Drupal::entityManager()->getStorage('menu_link_content'); - $menu_links = $storage->loadByProperties(array('menu_name' => $menu->id())); + $menu_links = $storage->loadByProperties(['menu_name' => $menu->id()]); $storage->delete($menu_links); } @@ -81,3 +82,24 @@ function menu_link_content_path_update($path) { function menu_link_content_path_delete($path) { _menu_link_content_update_path_alias($path['alias']); } + +/** + * Implements hook_entity_predelete(). + */ +function menu_link_content_entity_predelete(EntityInterface $entity) { + /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ + $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); + foreach ($entity->uriRelationships() as $rel) { + $url = $entity->toUrl($rel); + // Delete all MenuLinkContent links that point to this entity route. + $result = $menu_link_manager->loadLinksByRoute($url->getRouteName(), $url->getRouteParameters()); + + if ($result) { + foreach ($result as $id => $instance) { + if ($instance->isDeletable() && strpos($id, 'menu_link_content:') === 0) { + $instance->deleteLink(); + } + } + } + } +} diff --git a/core/modules/menu_link_content/migration_templates/d6_menu_links.yml b/core/modules/menu_link_content/migration_templates/d6_menu_links.yml index c418bfeb..2c8ad4a4 100644 --- a/core/modules/menu_link_content/migration_templates/d6_menu_links.yml +++ b/core/modules/menu_link_content/migration_templates/d6_menu_links.yml @@ -10,7 +10,7 @@ process: description: description menu_name: - - plugin: migration + plugin: migration_lookup # The menu migration is in the system module. migration: d6_menu source: menu_name diff --git a/core/modules/menu_link_content/migration_templates/d7_menu_links.yml b/core/modules/menu_link_content/migration_templates/d7_menu_links.yml index 7f049f7a..200a7920 100644 --- a/core/modules/menu_link_content/migration_templates/d7_menu_links.yml +++ b/core/modules/menu_link_content/migration_templates/d7_menu_links.yml @@ -13,7 +13,7 @@ process: description: description menu_name: - - plugin: migration + plugin: migration_lookup migration: d7_menu source: menu_name - diff --git a/core/modules/menu_link_content/src/Controller/MenuController.php b/core/modules/menu_link_content/src/Controller/MenuController.php index 6aaae646..be7879f9 100644 --- a/core/modules/menu_link_content/src/Controller/MenuController.php +++ b/core/modules/menu_link_content/src/Controller/MenuController.php @@ -20,12 +20,12 @@ class MenuController extends ControllerBase { * Returns the menu link creation form. */ public function addLink(MenuInterface $menu) { - $menu_link = $this->entityManager()->getStorage('menu_link_content')->create(array( + $menu_link = $this->entityManager()->getStorage('menu_link_content')->create([ 'id' => '', 'parent' => '', 'menu_name' => $menu->id(), 'bundle' => 'menu_link_content', - )); + ]); return $this->entityFormBuilder()->getForm($menu_link); } diff --git a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php index d23f876b..d53ba492 100644 --- a/core/modules/menu_link_content/src/Entity/MenuLinkContent.php +++ b/core/modules/menu_link_content/src/Entity/MenuLinkContent.php @@ -133,7 +133,7 @@ public function getWeight() { * {@inheritdoc} */ public function getPluginDefinition() { - $definition = array(); + $definition = []; $definition['class'] = 'Drupal\menu_link_content\Plugin\Menu\MenuLinkContent'; $definition['menu_name'] = $this->getMenuName(); @@ -155,7 +155,7 @@ public function getPluginDefinition() { $definition['description'] = $this->getDescription(); $definition['weight'] = $this->getWeight(); $definition['id'] = $this->getPluginId(); - $definition['metadata'] = array('entity_id' => $this->id()); + $definition['metadata'] = ['entity_id' => $this->id()]; $definition['form_class'] = '\Drupal\menu_link_content\Form\MenuLinkContentForm'; $definition['enabled'] = $this->isEnabled() ? 1 : 0; $definition['expanded'] = $this->isExpanded() ? 1 : 0; @@ -256,15 +256,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRequired(TRUE) ->setTranslatable(TRUE) ->setSetting('max_length', 255) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'string', 'weight' => -5, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -5, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['description'] = BaseFieldDefinition::create('string') @@ -272,15 +272,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('Shown when hovering over the menu link.')) ->setTranslatable(TRUE) ->setSetting('max_length', 255) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'string', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => 0, - )); + ]); $fields['menu_name'] = BaseFieldDefinition::create('string') ->setLabel(t('Menu name')) @@ -292,14 +292,14 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Link')) ->setDescription(t('The location this menu link points to.')) ->setRequired(TRUE) - ->setSettings(array( + ->setSettings([ 'link_type' => LinkItemInterface::LINK_GENERIC, 'title' => DRUPAL_DISABLED, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'link_default', 'weight' => -2, - )); + ]); $fields['external'] = BaseFieldDefinition::create('boolean') ->setLabel(t('External')) @@ -314,43 +314,43 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Weight')) ->setDescription(t('Link weight among links in the same menu at the same depth. In the menu, the links with high weight will sink and links with a low weight will be positioned nearer the top.')) ->setDefaultValue(0) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'integer', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'number', 'weight' => 20, - )); + ]); $fields['expanded'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Show as expanded')) ->setDescription(t('If selected and this menu link has children, the menu will always appear expanded.')) ->setDefaultValue(FALSE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'boolean', 'weight' => 0, - )) - ->setDisplayOptions('form', array( - 'settings' => array('display_label' => TRUE), + ]) + ->setDisplayOptions('form', [ + 'settings' => ['display_label' => TRUE], 'weight' => 0, - )); + ]); $fields['enabled'] = BaseFieldDefinition::create('boolean') ->setLabel(t('Enabled')) ->setDescription(t('A flag for whether the link should be enabled in menus or hidden.')) ->setDefaultValue(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'boolean', 'weight' => 0, - )) - ->setDisplayOptions('form', array( - 'settings' => array('display_label' => TRUE), + ]) + ->setDisplayOptions('form', [ + 'settings' => ['display_label' => TRUE], 'weight' => -1, - )); + ]); $fields['parent'] = BaseFieldDefinition::create('string') ->setLabel(t('Parent plugin ID')) diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php index b4caaff4..2b780c9e 100644 --- a/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php +++ b/core/modules/menu_link_content/src/Form/MenuLinkContentDeleteForm.php @@ -15,7 +15,7 @@ class MenuLinkContentDeleteForm extends ContentEntityDeleteForm { */ public function getCancelUrl() { if ($this->moduleHandler->moduleExists('menu_ui')) { - return new Url('entity.menu.edit_form', array('menu' => $this->entity->getMenuName())); + return new Url('entity.menu.edit_form', ['menu' => $this->entity->getMenuName()]); } return $this->entity->urlInfo(); } @@ -31,7 +31,7 @@ protected function getRedirectUrl() { * {@inheritdoc} */ protected function getDeletionMessage() { - return $this->t('The menu link %title has been deleted.', array('%title' => $this->entity->label())); + return $this->t('The menu link %title has been deleted.', ['%title' => $this->entity->label()]); } } diff --git a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php index ed372a92..4bdd6b9c 100644 --- a/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php +++ b/core/modules/menu_link_content/src/Form/MenuLinkContentForm.php @@ -2,8 +2,10 @@ namespace Drupal\menu_link_content\Form; +use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Menu\MenuParentFormSelectorInterface; @@ -47,9 +49,13 @@ class MenuLinkContentForm extends ContentEntityForm { * The language manager. * @param \Drupal\Core\Path\PathValidatorInterface $path_validator * The path validator. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info + * The entity type bundle service. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. */ - public function __construct(EntityManagerInterface $entity_manager, MenuParentFormSelectorInterface $menu_parent_selector, LanguageManagerInterface $language_manager, PathValidatorInterface $path_validator) { - parent::__construct($entity_manager, $language_manager); + public function __construct(EntityManagerInterface $entity_manager, MenuParentFormSelectorInterface $menu_parent_selector, LanguageManagerInterface $language_manager, PathValidatorInterface $path_validator, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL) { + parent::__construct($entity_manager, $entity_type_bundle_info, $time); $this->menuParentSelector = $menu_parent_selector; $this->pathValidator = $path_validator; } @@ -62,7 +68,9 @@ public static function create(ContainerInterface $container) { $container->get('entity.manager'), $container->get('menu.parent_form_selector'), $container->get('language_manager'), - $container->get('path.validator') + $container->get('path.validator'), + $container->get('entity_type.bundle.info'), + $container->get('datetime.time') ); } @@ -105,8 +113,8 @@ public function buildEntity(array $form, FormStateInterface $form_state) { $entity->parent->value = $parent; $entity->menu_name->value = $menu_name; - $entity->enabled->value = (!$form_state->isValueEmpty(array('enabled', 'value'))); - $entity->expanded->value = (!$form_state->isValueEmpty(array('expanded', 'value'))); + $entity->enabled->value = (!$form_state->isValueEmpty(['enabled', 'value'])); + $entity->expanded->value = (!$form_state->isValueEmpty(['expanded', 'value'])); return $entity; } @@ -123,7 +131,7 @@ public function save(array $form, FormStateInterface $form_state) { drupal_set_message($this->t('The menu link has been saved.')); $form_state->setRedirect( 'entity.menu_link_content.canonical', - array('menu_link_content' => $menu_link->id()) + ['menu_link_content' => $menu_link->id()] ); } else { diff --git a/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php b/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php index c9771d41..eadf0453 100644 --- a/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php +++ b/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php @@ -56,14 +56,15 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter case 'update': if (!$account->hasPermission('administer menu')) { - return AccessResult::neutral()->cachePerPermissions(); + return AccessResult::neutral("The 'administer menu' permission is required.")->cachePerPermissions(); } else { - // If there is a URL, this is an external link so always accessible. + // Assume that access is allowed. $access = AccessResult::allowed()->cachePerPermissions()->addCacheableDependency($entity); /** @var \Drupal\menu_link_content\MenuLinkContentInterface $entity */ - // We allow access, but only if the link is accessible as well. - if (($url_object = $entity->getUrlObject()) && $url_object->isRouted()) { + // If the link is routed determine whether the user has access unless + // they have the 'link to any page' permission. + if (!$account->hasPermission('link to any page') && ($url_object = $entity->getUrlObject()) && $url_object->isRouted()) { $link_access = $this->accessManager->checkNamedRoute($url_object->getRouteName(), $url_object->getRouteParameters(), $account, TRUE); $access = $access->andIf($link_access); } diff --git a/core/modules/menu_link_content/src/Plugin/Deriver/MenuLinkContentDeriver.php b/core/modules/menu_link_content/src/Plugin/Deriver/MenuLinkContentDeriver.php index e05fa215..c53f1327 100644 --- a/core/modules/menu_link_content/src/Plugin/Deriver/MenuLinkContentDeriver.php +++ b/core/modules/menu_link_content/src/Plugin/Deriver/MenuLinkContentDeriver.php @@ -4,7 +4,6 @@ use Drupal\Component\Plugin\Derivative\DeriverBase; use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Menu\MenuLinkManagerInterface; use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -17,13 +16,6 @@ */ class MenuLinkContentDeriver extends DeriverBase implements ContainerDeriverInterface { - /** - * The query factory. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $queryFactory; - /** * The entity manager. * @@ -41,15 +33,12 @@ class MenuLinkContentDeriver extends DeriverBase implements ContainerDeriverInte /** * Constructs a MenuLinkContentDeriver instance. * - * @param \Drupal\Core\Entity\Query\QueryFactory $query_factory - * The query factory. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager * The menu link manager. */ - public function __construct(QueryFactory $query_factory, EntityManagerInterface $entity_manager, MenuLinkManagerInterface $menu_link_manager) { - $this->queryFactory = $query_factory; + public function __construct(EntityManagerInterface $entity_manager, MenuLinkManagerInterface $menu_link_manager) { $this->entityManager = $entity_manager; $this->menuLinkManager = $menu_link_manager; } @@ -59,7 +48,6 @@ public function __construct(QueryFactory $query_factory, EntityManagerInterface */ public static function create(ContainerInterface $container, $base_plugin_id) { return new static( - $container->get('entity.query'), $container->get('entity.manager'), $container->get('plugin.manager.menu.link') ); @@ -70,7 +58,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) { */ public function getDerivativeDefinitions($base_plugin_definition) { // Get all custom menu links which should be rediscovered. - $entity_ids = $this->queryFactory->get('menu_link_content') + $entity_ids = $this->entityManager->getStorage('menu_link_content')->getQuery() ->condition('rediscover', TRUE) ->execute(); $plugin_definitions = []; diff --git a/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php b/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php index fea02112..98e8cdfc 100644 --- a/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php +++ b/core/modules/menu_link_content/src/Plugin/Menu/MenuLinkContent.php @@ -21,12 +21,12 @@ class MenuLinkContent extends MenuLinkBase implements ContainerFactoryPluginInte * * @var array */ - protected static $entityIdsToLoad = array(); + protected static $entityIdsToLoad = []; /** * {@inheritdoc} */ - protected $overrideAllowed = array( + protected $overrideAllowed = [ 'menu_name' => 1, 'parent' => 1, 'weight' => 1, @@ -38,7 +38,7 @@ class MenuLinkContent extends MenuLinkBase implements ContainerFactoryPluginInte 'route_parameters' => 1, 'url' => 1, 'options' => 1, - ); + ]; /** * The menu link content entity connected to this plugin instance. @@ -123,12 +123,12 @@ protected function getEntity() { static::$entityIdsToLoad[$entity_id] = $entity_id; $entities = $storage->loadMultiple(array_values(static::$entityIdsToLoad)); $entity = isset($entities[$entity_id]) ? $entities[$entity_id] : NULL; - static::$entityIdsToLoad = array(); + static::$entityIdsToLoad = []; } if (!$entity) { // Fallback to the loading by the UUID. $uuid = $this->getUuid(); - $loaded_entities = $storage->loadByProperties(array('uuid' => $uuid)); + $loaded_entities = $storage->loadByProperties(['uuid' => $uuid]); $entity = reset($loaded_entities); } if (!$entity) { diff --git a/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php b/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php index 839b6396..175566ee 100644 --- a/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php +++ b/core/modules/menu_link_content/src/Plugin/migrate/process/LinkUri.php @@ -5,6 +5,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Url; +use Drupal\migrate\MigrateException; use Drupal\migrate\MigrateExecutableInterface; use Drupal\migrate\ProcessPluginBase; use Drupal\migrate\Row; @@ -80,6 +81,9 @@ public function transform($value, MigrateExecutableInterface $migrate_executable } } } + else { + throw new MigrateException(sprintf('The path "%s" failed validation.', $path)); + } } return $path; } diff --git a/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php b/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php index 46b53a04..7467c72f 100644 --- a/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php +++ b/core/modules/menu_link_content/src/Plugin/migrate/process/d6/LinkUri.php @@ -2,12 +2,14 @@ namespace Drupal\menu_link_content\Plugin\migrate\process\d6; -use \Drupal\menu_link_content\Plugin\migrate\process\LinkUri as RealLinkUri; +use Drupal\menu_link_content\Plugin\migrate\process\LinkUri as RealLinkUri; /** * Processes a link path into an 'internal:' or 'entity:' URI. * * @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use * \Drupal\menu_link_content\Plugin\migrate\process\LinkUri instead. + * + * @see https://www.drupal.org/node/2761389 */ class LinkUri extends RealLinkUri {} diff --git a/core/modules/menu_link_content/src/Plugin/migrate/process/d7/InternalUri.php b/core/modules/menu_link_content/src/Plugin/migrate/process/d7/InternalUri.php index fc636758..2cb8aaf2 100644 --- a/core/modules/menu_link_content/src/Plugin/migrate/process/d7/InternalUri.php +++ b/core/modules/menu_link_content/src/Plugin/migrate/process/d7/InternalUri.php @@ -9,5 +9,7 @@ * * @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use * \Drupal\menu_link_content\Plugin\migrate\process\LinkUri instead. + * + * @see https://www.drupal.org/node/2761389 */ class InternalUri extends LinkUri {} diff --git a/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php b/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php index 067b1331..2efb8acf 100644 --- a/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php +++ b/core/modules/menu_link_content/src/Plugin/migrate/source/MenuLink.php @@ -11,6 +11,7 @@ * * @MigrateSource( * id = "menu_link", + * source_module = "menu" * ) */ class MenuLink extends DrupalSqlBase { @@ -39,7 +40,7 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'menu_name' => t("The menu name. All links with the same menu name (such as 'navigation') are part of the same menu."), 'mlid' => t('The menu link ID (mlid) is the integer primary key.'), 'plid' => t('The parent link ID (plid) is the mlid of the link above in the hierarchy, or zero if the link is at the top level in its menu.'), @@ -65,7 +66,7 @@ public function fields() { 'p8' => t('The eighth mlid in the materialized path. See p1.'), 'p9' => t('The ninth mlid in the materialized path. See p1.'), 'updated' => t('Flag that indicates that this link was generated during the update from Drupal 5.'), - ); + ]; } /** diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php b/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php deleted file mode 100644 index 1bdc927f..00000000 --- a/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php +++ /dev/null @@ -1,68 +0,0 @@ -drupalCreateUser(array('administer menu')); - $this->drupalLogin($web_user); - } - - /** - * Tests the MenuLinkContentForm class. - */ - public function testMenuLinkContentForm() { - $this->drupalGet('admin/structure/menu/manage/admin/add'); - $element = $this->xpath('//select[@id = :id]/option[@selected]', array(':id' => 'edit-menu-parent')); - $this->assertTrue($element, 'A default menu parent was found.'); - $this->assertEqual('admin:', $element[0]['value'], ' menu is the parent.'); - - $this->drupalPostForm( - NULL, - array( - 'title[0][value]' => t('Front page'), - 'link[0][uri]' => '', - ), - t('Save') - ); - $this->assertText(t('The menu link has been saved.')); - } - - /** - * Tests validation for the MenuLinkContentForm class. - */ - public function testMenuLinkContentFormValidation() { - $this->drupalGet('admin/structure/menu/manage/admin/add'); - $this->drupalPostForm( - NULL, - array( - 'title[0][value]' => t('Test page'), - 'link[0][uri]' => '', - ), - t('Save') - ); - $this->assertText(t('Manually entered paths should start with /, ? or #.')); - } - -} diff --git a/core/modules/menu_link_content/tests/menu_link_content_dynamic_route/menu_link_content_dynamic_route.info.yml b/core/modules/menu_link_content/tests/menu_link_content_dynamic_route/menu_link_content_dynamic_route.info.yml index 1701d63b..040e5406 100644 --- a/core/modules/menu_link_content/tests/menu_link_content_dynamic_route/menu_link_content_dynamic_route.info.yml +++ b/core/modules/menu_link_content/tests/menu_link_content_dynamic_route/menu_link_content_dynamic_route.info.yml @@ -5,8 +5,8 @@ hidden: true dependencies: - menu_link_content -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/menu_link_content/tests/outbound_processing_test/outbound_processing_test.info.yml b/core/modules/menu_link_content/tests/outbound_processing_test/outbound_processing_test.info.yml index 1998c3a5..4ec4c876 100644 --- a/core/modules/menu_link_content/tests/outbound_processing_test/outbound_processing_test.info.yml +++ b/core/modules/menu_link_content/tests/outbound_processing_test/outbound_processing_test.info.yml @@ -3,8 +3,8 @@ type: module # core: 8.x hidden: true -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/menu_link_content/src/Tests/LinksTest.php b/core/modules/menu_link_content/tests/src/Functional/LinksTest.php similarity index 75% rename from core/modules/menu_link_content/src/Tests/LinksTest.php rename to core/modules/menu_link_content/tests/src/Functional/LinksTest.php index 84fecde1..6a3d50b3 100644 --- a/core/modules/menu_link_content/src/Tests/LinksTest.php +++ b/core/modules/menu_link_content/tests/src/Functional/LinksTest.php @@ -1,30 +1,32 @@ menuLinkManager = \Drupal::service('plugin.manager.menu.link'); - Menu::create(array( + Menu::create([ 'id' => 'menu_test', 'label' => 'Test menu', 'description' => 'Description text', - ))->save(); + ])->save(); } /** * Create a simple hierarchy of links. */ - function createLinkHierarchy($module = 'menu_test') { + public function createLinkHierarchy($module = 'menu_test') { // First remove all the menu links in the menu. $this->menuLinkManager->deleteLinksInMenu('menu_test'); @@ -56,47 +58,47 @@ function createLinkHierarchy($module = 'menu_test') { // - child-1-1 // - child-1-2 // - child-2 - $base_options = array( + $base_options = [ 'title' => 'Menu link test', 'provider' => $module, 'menu_name' => 'menu_test', - ); + ]; - $parent = $base_options + array( + $parent = $base_options + [ 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent'], - ); + ]; $link = MenuLinkContent::create($parent); $link->save(); $links['parent'] = $link->getPluginId(); - $child_1 = $base_options + array( + $child_1 = $base_options + [ 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child'], 'parent' => $links['parent'], - ); + ]; $link = MenuLinkContent::create($child_1); $link->save(); $links['child-1'] = $link->getPluginId(); - $child_1_1 = $base_options + array( + $child_1_1 = $base_options + [ 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child2/child'], 'parent' => $links['child-1'], - ); + ]; $link = MenuLinkContent::create($child_1_1); $link->save(); $links['child-1-1'] = $link->getPluginId(); - $child_1_2 = $base_options + array( + $child_1_2 = $base_options + [ 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child2/child'], 'parent' => $links['child-1'], - ); + ]; $link = MenuLinkContent::create($child_1_2); $link->save(); $links['child-1-2'] = $link->getPluginId(); - $child_2 = $base_options + array( + $child_2 = $base_options + [ 'link' => ['uri' => 'internal:/menu-test/hierarchy/parent/child'], 'parent' => $links['parent'], - ); + ]; $link = MenuLinkContent::create($child_2); $link->save(); $links['child-2'] = $link->getPluginId(); @@ -107,13 +109,13 @@ function createLinkHierarchy($module = 'menu_test') { /** * Assert that at set of links is properly parented. */ - function assertMenuLinkParents($links, $expected_hierarchy) { + public function assertMenuLinkParents($links, $expected_hierarchy) { foreach ($expected_hierarchy as $id => $parent) { /* @var \Drupal\Core\Menu\MenuLinkInterface $menu_link_plugin */ $menu_link_plugin = $this->menuLinkManager->createInstance($links[$id]); $expected_parent = isset($links[$parent]) ? $links[$parent] : ''; - $this->assertEqual($menu_link_plugin->getParent(), $expected_parent, SafeMarkup::format('Menu link %id has parent of %parent, expected %expected_parent.', array('%id' => $id, '%parent' => $menu_link_plugin->getParent(), '%expected_parent' => $expected_parent))); + $this->assertEqual($menu_link_plugin->getParent(), $expected_parent, SafeMarkup::format('Menu link %id has parent of %parent, expected %expected_parent.', ['%id' => $id, '%parent' => $menu_link_plugin->getParent(), '%expected_parent' => $expected_parent])); } } @@ -121,18 +123,18 @@ function assertMenuLinkParents($links, $expected_hierarchy) { * Assert that a link entity's created timestamp is set. */ public function testCreateLink() { - $options = array( + $options = [ 'menu_name' => 'menu_test', 'bundle' => 'menu_link_content', 'link' => [['uri' => 'internal:/']], - ); + ]; $link = MenuLinkContent::create($options); $link->save(); // Make sure the changed timestamp is set. $this->assertEqual($link->getChangedTime(), REQUEST_TIME, 'Creating a menu link sets the "changed" timestamp.'); - $options = array( + $options = [ 'title' => 'Test Link', - ); + ]; $link->link->options = $options; $link->changed->value = 0; $link->save(); @@ -140,39 +142,54 @@ public function testCreateLink() { $this->assertEqual($link->getChangedTime(), REQUEST_TIME, 'Changing a menu link sets "changed" timestamp.'); } + /** + * Tests that menu link pointing to entities get removed on entity remove. + */ + public function testMenuLinkOnEntityDelete() { + $user = User::create(['name' => 'username']); + $user->save(); + $menu_link_content = MenuLinkContent::create(['menu_name' => 'menu_test', 'link' => [['uri' => 'entity:user/' . $user->id()]], 'bundle' => 'menu_test']); + $menu_link_content->save(); + $menu_tree_condition = (new MenuTreeParameters())->addCondition('route_name', 'entity.user.canonical'); + $this->assertCount(1, \Drupal::menuTree()->load('menu_test', $menu_tree_condition)); + + $user->delete(); + $this->assertCount(0, \Drupal::menuTree()->load('menu_test', $menu_tree_condition)); + } + /** * Test automatic reparenting of menu links. */ - function testMenuLinkReparenting($module = 'menu_test') { + public function testMenuLinkReparenting($module = 'menu_test') { // Check the initial hierarchy. $links = $this->createLinkHierarchy($module); - $expected_hierarchy = array( + $expected_hierarchy = [ 'parent' => '', 'child-1' => 'parent', 'child-1-1' => 'child-1', 'child-1-2' => 'child-1', 'child-2' => 'parent', - ); + ]; $this->assertMenuLinkParents($links, $expected_hierarchy); // Start over, and move child-1 under child-2, and check that all the // children of child-1 have been moved too. $links = $this->createLinkHierarchy($module); /* @var \Drupal\Core\Menu\MenuLinkInterface $menu_link_plugin */ - $this->menuLinkManager->updateDefinition($links['child-1'], array('parent' => $links['child-2'])); + $this->menuLinkManager->updateDefinition($links['child-1'], ['parent' => $links['child-2']]); // Verify that the entity was updated too. $menu_link_plugin = $this->menuLinkManager->createInstance($links['child-1']); $entity = \Drupal::entityManager()->loadEntityByUuid('menu_link_content', $menu_link_plugin->getDerivativeId()); $this->assertEqual($entity->getParentId(), $links['child-2']); - $expected_hierarchy = array( + $expected_hierarchy = [ 'parent' => '', 'child-1' => 'child-2', 'child-1-1' => 'child-1', 'child-1-2' => 'child-1', 'child-2' => 'parent', - ); + ]; $this->assertMenuLinkParents($links, $expected_hierarchy); // Start over, and delete child-1, and check that the children of child-1 @@ -180,12 +197,12 @@ function testMenuLinkReparenting($module = 'menu_test') { $links = $this->createLinkHierarchy($module); $this->menuLinkManager->removeDefinition($links['child-1']); - $expected_hierarchy = array( + $expected_hierarchy = [ 'parent' => FALSE, 'child-1-1' => 'parent', 'child-1-2' => 'parent', 'child-2' => 'parent', - ); + ]; $this->assertMenuLinkParents($links, $expected_hierarchy); // Try changing the parent at the entity level. @@ -194,12 +211,12 @@ function testMenuLinkReparenting($module = 'menu_test') { $entity->parent->value = ''; $entity->save(); - $expected_hierarchy = array( + $expected_hierarchy = [ 'parent' => '', 'child-1-1' => 'parent', 'child-1-2' => '', 'child-2' => 'parent', - ); + ]; $this->assertMenuLinkParents($links, $expected_hierarchy); // @todo Figure out what makes sense to test in terms of automatic @@ -210,7 +227,7 @@ function testMenuLinkReparenting($module = 'menu_test') { * Tests uninstalling a module providing default links. */ public function testModuleUninstalledMenuLinks() { - \Drupal::service('module_installer')->install(array('menu_test')); + \Drupal::service('module_installer')->install(['menu_test']); \Drupal::service('router.builder')->rebuild(); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test'); @@ -219,7 +236,7 @@ public function testModuleUninstalledMenuLinks() { $this->assertEqual($menu_link->getPluginId(), 'menu_test'); // Uninstall the module and ensure the menu link got removed. - \Drupal::service('module_installer')->uninstall(array('menu_test')); + \Drupal::service('module_installer')->uninstall(['menu_test']); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test'); $this->assertEqual(count($menu_links), 0); diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentDeleteFormTest.php b/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentDeleteFormTest.php similarity index 91% rename from core/modules/menu_link_content/src/Tests/MenuLinkContentDeleteFormTest.php rename to core/modules/menu_link_content/tests/src/Functional/MenuLinkContentDeleteFormTest.php index e6ec76e5..cb1e10da 100644 --- a/core/modules/menu_link_content/src/Tests/MenuLinkContentDeleteFormTest.php +++ b/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentDeleteFormTest.php @@ -1,17 +1,17 @@ adminUser = $this->drupalCreateUser(['administer menu', 'link to any page']); + $this->basicUser = $this->drupalCreateUser(['administer menu']); + $this->drupalLogin($this->adminUser); + } + + /** + * Tests the 'link to any page' permission for a restricted page. + */ + public function testMenuLinkContentFormLinkToAnyPage() { + $menu_link = MenuLinkContent::create([ + 'title' => 'Menu link test', + 'provider' => 'menu_link_content', + 'menu_name' => 'admin', + 'link' => ['uri' => 'internal:/user/login'], + ]); + $menu_link->save(); + + // The user should be able to edit a menu link to the page, even though + // the user cannot access the page itself. + $this->drupalGet('/admin/structure/menu/item/' . $menu_link->id() . '/edit'); + $this->assertResponse(200); + + $this->drupalLogin($this->basicUser); + + $this->drupalGet('/admin/structure/menu/item/' . $menu_link->id() . '/edit'); + $this->assertResponse(403); + } + + /** + * Tests the MenuLinkContentForm class. + */ + public function testMenuLinkContentForm() { + $this->drupalGet('admin/structure/menu/manage/admin/add'); + $element = $this->xpath('//select[@id = :id]/option[@selected]', [':id' => 'edit-menu-parent']); + $this->assertTrue($element, 'A default menu parent was found.'); + $this->assertEqual('admin:', $element[0]->getValue(), ' menu is the parent.'); + + $this->drupalPostForm( + NULL, + [ + 'title[0][value]' => t('Front page'), + 'link[0][uri]' => '', + ], + t('Save') + ); + $this->assertText(t('The menu link has been saved.')); + } + + /** + * Tests validation for the MenuLinkContentForm class. + */ + public function testMenuLinkContentFormValidation() { + $this->drupalGet('admin/structure/menu/manage/admin/add'); + $this->drupalPostForm( + NULL, + [ + 'title[0][value]' => t('Test page'), + 'link[0][uri]' => '', + ], + t('Save') + ); + $this->assertText(t('Manually entered paths should start with /, ? or #.')); + } + +} diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentTranslationUITest.php b/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php similarity index 82% rename from core/modules/menu_link_content/src/Tests/MenuLinkContentTranslationUITest.php rename to core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php index cf802b70..a2ba9930 100644 --- a/core/modules/menu_link_content/src/Tests/MenuLinkContentTranslationUITest.php +++ b/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php @@ -1,8 +1,8 @@ drupalLogin($this->administrator); - $entityId = $this->createEntity(array(), 'en'); + $entityId = $this->createEntity([], 'en'); // Set up Seven as the admin theme to test. - $this->container->get('theme_handler')->install(array('seven')); - $edit = array(); + $this->container->get('theme_handler')->install(['seven']); + $edit = []; $edit['admin_theme'] = 'seven'; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); $this->drupalGet('admin/structure/menu/item/' . $entityId . '/edit'); @@ -107,14 +107,14 @@ protected function doTestTranslationEdit() { foreach ($this->langcodes as $langcode) { // We only want to test the title for non-english translations. if ($langcode != 'en') { - $options = array('language' => $languages[$langcode]); + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); $this->drupalGet($url); - $title = t('@title [%language translation]', array( + $title = t('@title [%language translation]', [ '@title' => $entity->getTranslation($langcode)->label(), '%language' => $languages[$langcode]->getName(), - )); + ]); $this->assertRaw($title); } } diff --git a/core/modules/menu_link_content/tests/src/Kernel/Migrate/d6/MigrateMenuLinkTest.php b/core/modules/menu_link_content/tests/src/Kernel/Migrate/d6/MigrateMenuLinkTest.php index eea87dba..f1368ed4 100644 --- a/core/modules/menu_link_content/tests/src/Kernel/Migrate/d6/MigrateMenuLinkTest.php +++ b/core/modules/menu_link_content/tests/src/Kernel/Migrate/d6/MigrateMenuLinkTest.php @@ -15,7 +15,7 @@ class MigrateMenuLinkTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('menu_ui', 'menu_link_content'); + public static $modules = ['menu_ui', 'menu_link_content']; /** * {@inheritdoc} diff --git a/core/modules/menu_link_content/tests/src/Kernel/Migrate/d7/MigrateMenuLinkTest.php b/core/modules/menu_link_content/tests/src/Kernel/Migrate/d7/MigrateMenuLinkTest.php index 1d757a51..a5e8dd0e 100644 --- a/core/modules/menu_link_content/tests/src/Kernel/Migrate/d7/MigrateMenuLinkTest.php +++ b/core/modules/menu_link_content/tests/src/Kernel/Migrate/d7/MigrateMenuLinkTest.php @@ -19,7 +19,7 @@ class MigrateMenuLinkTest extends MigrateDrupal7TestBase { /** * {@inheritdoc} */ - public static $modules = array('link', 'menu_ui', 'menu_link_content', 'node'); + public static $modules = ['link', 'menu_ui', 'menu_link_content', 'node']; /** * {@inheritdoc} @@ -29,7 +29,7 @@ protected function setUp() { $this->installEntitySchema('menu_link_content'); $this->installEntitySchema('node'); $node = Node::create([ - 'nid' => 3, + 'nid' => 2, 'title' => 'node link test', 'type' => 'article', ]); @@ -90,8 +90,8 @@ public function testMenuLinks() { // Tests migrating an external link with an undefined title attribute. $this->assertEntity(470, 'Ask', static::MENU_NAME, NULL, TRUE, FALSE, [], 'http://ask.com', 0); $this->assertEntity(245, 'Home', 'main', NULL, TRUE, FALSE, [], 'internal:/', 0); - $this->assertEntity(478, 'custom link test', 'admin', NULL, TRUE, FALSE, ['attributes' => ['title' => '']], 'internal:/admin/content/book', 0); - $this->assertEntity(479, 'node link test', 'tools', 'node 3', TRUE, FALSE, ['attributes' => ['title' => 'node 3']], 'entity:node/3', 3); + $this->assertEntity(478, 'custom link test', 'admin', NULL, TRUE, FALSE, ['attributes' => ['title' => '']], 'internal:/admin/content', 0); + $this->assertEntity(479, 'node link test', 'tools', 'node 2', TRUE, FALSE, ['attributes' => ['title' => 'node 2']], 'entity:node/2', 3); $menu_link_tree_service = \Drupal::service('menu.link_tree'); $parameters = new MenuTreeParameters(); diff --git a/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/process/LinkUriTest.php b/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/process/LinkUriTest.php new file mode 100644 index 00000000..74e88d18 --- /dev/null +++ b/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/process/LinkUriTest.php @@ -0,0 +1,122 @@ +doTransform($value); + $this->assertSame($expected, $actual); + } + + /** + * Provides test cases for LinkUriTest::testTransform(). + * + * @return array + * An array of test cases, each which the following values: + * - The value array to pass to LinkUri::transform(). + * - The expected path returned by LinkUri::transform(). + */ + public function providerTestRouted() { + $tests = []; + + $value = ['http://example.com']; + $expected = 'http://example.com'; + $tests['with_scheme'] = [$value, $expected]; + + $value = ['']; + $expected = 'internal:/'; + $tests['front'] = [$value, $expected]; + + return $tests; + } + + /** + * Tests that Non routed URLs throws an exception. + * + * @param array $value + * The value to pass to LinkUri::transform(). + * @param string $exception_message + * The expected exception message. + * + * @dataProvider providerTestNotRouted + */ + public function testNotRouted(array $value, $exception_message) { + $this->setExpectedException(MigrateException::class, $exception_message); + $this->doTransform($value); + } + + /** + * Provides test cases for LinkUriTest::testNotRouted(). + * + * @return array + * An array of test cases, each which the following values: + * - The value array to pass to LinkUri::transform(). + * - The expected path returned by LinkUri::transform(). + * - (optional) A URL object that the path validator prophecy will return. + */ + public function providerTestNotRouted() { + $tests = []; + + $message = 'The path "%s" failed validation.'; + + $value = ['/test']; + $expected = 'internal:/test'; + $exception_message = sprintf($message, $expected); + $tests['leading_slash'] = [$value, $exception_message]; + + $value = ['test']; + $expected = 'internal:/test'; + $exception_message = sprintf($message, $expected); + $tests['without_scheme'] = [$value, $exception_message]; + + return $tests; + } + + /** + * Transforms a link path into an 'internal:' or 'entity:' URI. + * + * @param array $value + * The value to pass to LinkUri::transform(). + * + * @return string + * The transformed link. + */ + public function doTransform(array $value) { + $entityTypeManager = $this->container->get('entity_type.manager'); + $routeBuilder = $this->container->get('router.builder'); + $row = new Row(); + $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal(); + + $plugin = new LinkUri([], 'link_uri', [], $entityTypeManager, $routeBuilder); + $actual = $plugin->transform($value, $executable, $row, 'destinationproperty'); + + return $actual; + } + +} diff --git a/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/source/MenuLinkTest.php b/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/source/MenuLinkTest.php index db6c5472..7fb3a918 100644 --- a/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/source/MenuLinkTest.php +++ b/core/modules/menu_link_content/tests/src/Kernel/Plugin/migrate/source/MenuLinkTest.php @@ -35,7 +35,7 @@ public function providerSource() { 'link_path' => 'admin/config/system/cron', 'router_path' => 'admin/config/system/cron', 'link_title' => 'Cron', - 'options' => array(), + 'options' => [], 'module' => 'system', 'hidden' => 0, 'external' => 0, @@ -64,7 +64,7 @@ public function providerSource() { 'link_path' => 'node/141', 'router_path' => 'node/%', 'link_title' => 'Node 141', - 'options' => array(), + 'options' => [], 'module' => 'menu', 'hidden' => 0, 'external' => 0, @@ -93,7 +93,7 @@ public function providerSource() { 'link_path' => 'node/142', 'router_path' => 'node/%', 'link_title' => 'Node 142', - 'options' => array(), + 'options' => [], 'module' => 'menu', 'hidden' => 0, 'external' => 0, @@ -121,7 +121,7 @@ public function providerSource() { 'link_path' => 'admin', 'router_path' => 'admin', 'link_title' => 'Test 1', - 'options' => array('attributes' => array('title' => 'Test menu link 1')), + 'options' => ['attributes' => ['title' => 'Test menu link 1']], 'module' => 'menu', 'hidden' => 0, 'external' => 0, @@ -149,7 +149,7 @@ public function providerSource() { 'link_path' => 'admin/modules', 'router_path' => 'admin/modules', 'link_title' => 'Test 2', - 'options' => array('attributes' => array('title' => 'Test menu link 2')), + 'options' => ['attributes' => ['title' => 'Test menu link 2']], 'module' => 'menu', 'hidden' => 0, 'external' => 0, @@ -177,7 +177,7 @@ public function providerSource() { 'link_path' => 'admin/build/menu-customize/navigation', 'router_path' => 'admin/build/menu-customize/%', 'link_title' => 'Navigation', - 'options' => array(), + 'options' => [], 'module' => 'menu', 'hidden' => 0, 'external' => 0, diff --git a/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/LinkUriTest.php b/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/LinkUriTest.php deleted file mode 100644 index d6476125..00000000 --- a/core/modules/menu_link_content/tests/src/Unit/Plugin/migrate/process/LinkUriTest.php +++ /dev/null @@ -1,140 +0,0 @@ -entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class); - $this->entityTypeManager->getDefinitions()->willReturn([$this->entityTypeId => '']); - $this->processPlugin = new LinkUri([], 'link_uri', [], $this->entityTypeManager->reveal()); - - // Url::fromInternalUri() accesses the path validator from the global - // container. - // @see \Drupal\Core\Url::fromInternalUri() - $this->pathValidator = $this->prophesize(PathValidator::class); - $container = new ContainerBuilder(); - $container->set('path.validator', $this->pathValidator->reveal()); - \Drupal::setContainer($container); - } - - /** - * Tests LinkUri::transform(). - * - * @param array $value - * The value to pass to LinkUri::transform(). - * @param string $expected - * The expected return value of LinkUri::transform(). - * @param \Drupal\Core\Url $url - * (optional) The URL that the path validator prophecy will return. - * - * @dataProvider providerTestTransform - * - * @covers ::transform - */ - public function testTransform(array $value, $expected, Url $url = NULL) { - $migrate_executable = $this->prophesize(MigrateExecutableInterface::class); - $row = $this->prophesize(Row::class); - - if ($url) { - $this->pathValidator->getUrlIfValidWithoutAccessCheck(reset($value))->willReturn($url); - } - - $actual = $this->processPlugin->transform($value, $migrate_executable->reveal(), $row->reveal(), 'link/uri'); - $this->assertEquals($expected, $actual); - } - - /** - * Provides test cases for LinkUriTest::testTransform(). - * - * @return array - * An array of test cases, each which the following values: - * - The value array to pass to LinkUri::transform(). - * - The expected path returned by LinkUri::transform(). - * - (optional) A URL object that the path validator prophecy will return. - */ - public function providerTestTransform() { - $tests = []; - - $value = ['http://example.com']; - $expected = 'http://example.com'; - $tests['with_scheme'] = [$value, $expected]; - - $value = ['/test']; - $expected = 'internal:/test'; - $tests['leading_slash'] = [$value, $expected]; - - $value = ['test']; - $expected = 'internal:/test'; - $tests['without_scheme'] = [$value, $expected]; - - $value = ['']; - $expected = 'internal:/'; - $tests['front'] = [$value, $expected]; - - $url = Url::fromRoute('route_name'); - $tests['with_route'] = [$value, $expected, $url]; - - $url = Url::fromRoute('entity.not_an_entity_type_id.canonical'); - $tests['without_entity_type'] = [$value, $expected, $url]; - - $url = Url::fromRoute('entity.the_entity_type_id.canonical'); - $tests['without_route_parameter'] = [$value, $expected, $url]; - - $url = Url::fromRoute('entity.the_entity_type_id.canonical', ['the_entity_type_id' => 'the_entity_id']); - $expected = 'entity:the_entity_type_id/the_entity_id'; - $tests['entity_path'] = [$value, $expected, $url]; - - return $tests; - } - -} diff --git a/core/modules/menu_ui/menu_ui.admin.es6.js b/core/modules/menu_ui/menu_ui.admin.es6.js new file mode 100644 index 00000000..fabcec04 --- /dev/null +++ b/core/modules/menu_ui/menu_ui.admin.es6.js @@ -0,0 +1,64 @@ +/** + * @file + * Menu UI admin behaviors. + */ + +(function ($, Drupal) { + /** + * + * @type {Drupal~behavior} + */ + Drupal.behaviors.menuUiChangeParentItems = { + attach(context, settings) { + const $menu = $('#edit-menu').once('menu-parent'); + if ($menu.length) { + // Update the list of available parent menu items to match the initial + // available menus. + Drupal.menuUiUpdateParentList(); + + // Update list of available parent menu items. + $menu.on('change', 'input', Drupal.menuUiUpdateParentList); + } + }, + }; + + /** + * Function to set the options of the menu parent item dropdown. + */ + Drupal.menuUiUpdateParentList = function () { + const $menu = $('#edit-menu'); + const values = []; + + $menu.find('input:checked').each(function () { + // Get the names of all checked menus. + values.push(Drupal.checkPlain($.trim($(this).val()))); + }); + + $.ajax({ + url: `${location.protocol}//${location.host}${Drupal.url('admin/structure/menu/parents')}`, + type: 'POST', + data: { 'menus[]': values }, + dataType: 'json', + success(options) { + const $select = $('#edit-menu-parent'); + // Save key of last selected element. + const selected = $select.val(); + // Remove all existing options from dropdown. + $select.children().remove(); + // Add new options to dropdown. Keep a count of options for testing later. + let totalOptions = 0; + for (const machineName in options) { + if (options.hasOwnProperty(machineName)) { + $select.append( + $(``).val(machineName).text(options[machineName]), + ); + totalOptions++; + } + } + + // Hide the parent options if there are no options for it. + $select.closest('div').toggle(totalOptions > 0).attr('hidden', totalOptions === 0); + }, + }); + }; +}(jQuery, Drupal)); diff --git a/core/modules/menu_ui/menu_ui.admin.js b/core/modules/menu_ui/menu_ui.admin.js index 345138f1..324b567a 100644 --- a/core/modules/menu_ui/menu_ui.admin.js +++ b/core/modules/menu_ui/menu_ui.admin.js @@ -1,68 +1,52 @@ /** - * @file - * Menu UI admin behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * - * @type {Drupal~behavior} - */ Drupal.behaviors.menuUiChangeParentItems = { - attach: function (context, settings) { + attach: function attach(context, settings) { var $menu = $('#edit-menu').once('menu-parent'); if ($menu.length) { - // Update the list of available parent menu items to match the initial - // available menus. Drupal.menuUiUpdateParentList(); - // Update list of available parent menu items. $menu.on('change', 'input', Drupal.menuUiUpdateParentList); } } }; - /** - * Function to set the options of the menu parent item dropdown. - */ Drupal.menuUiUpdateParentList = function () { var $menu = $('#edit-menu'); var values = []; $menu.find('input:checked').each(function () { - // Get the names of all checked menus. values.push(Drupal.checkPlain($.trim($(this).val()))); }); $.ajax({ url: location.protocol + '//' + location.host + Drupal.url('admin/structure/menu/parents'), type: 'POST', - data: {'menus[]': values}, + data: { 'menus[]': values }, dataType: 'json', - success: function (options) { + success: function success(options) { var $select = $('#edit-menu-parent'); - // Save key of last selected element. + var selected = $select.val(); - // Remove all existing options from dropdown. + $select.children().remove(); - // Add new options to dropdown. Keep a count of options for testing later. + var totalOptions = 0; for (var machineName in options) { if (options.hasOwnProperty(machineName)) { - $select.append( - $('').val(machineName).text(options[machineName]) - ); + $select.append($('').val(machineName).text(options[machineName])); totalOptions++; } } - // Hide the parent options if there are no options for it. $select.closest('div').toggle(totalOptions > 0).attr('hidden', totalOptions === 0); } }); }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/menu_ui/menu_ui.es6.js b/core/modules/menu_ui/menu_ui.es6.js new file mode 100644 index 00000000..f384f111 --- /dev/null +++ b/core/modules/menu_ui/menu_ui.es6.js @@ -0,0 +1,86 @@ +/** + * @file + * Menu UI behaviors. + */ + +(function ($, Drupal) { + /** + * Set a summary on the menu link form. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Find the form and call `drupalSetSummary` on it. + */ + Drupal.behaviors.menuUiDetailsSummaries = { + attach(context) { + $(context).find('.menu-link-form').drupalSetSummary((context) => { + const $context = $(context); + if ($context.find('.js-form-item-menu-enabled input').is(':checked')) { + return Drupal.checkPlain($context.find('.js-form-item-menu-title input').val()); + } + + return Drupal.t('Not in menu'); + }); + }, + }; + + /** + * Automatically fill in a menu link title, if possible. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches change and keyup behavior for automatically filling out menu + * link titles. + */ + Drupal.behaviors.menuUiLinkAutomaticTitle = { + attach(context) { + const $context = $(context); + $context.find('.menu-link-form').each(function () { + const $this = $(this); + // Try to find menu settings widget elements as well as a 'title' field + // in the form, but play nicely with user permissions and form + // alterations. + const $checkbox = $this.find('.js-form-item-menu-enabled input'); + const $link_title = $context.find('.js-form-item-menu-title input'); + const $title = $this.closest('form').find('.js-form-item-title-0-value input'); + // Bail out if we do not have all required fields. + if (!($checkbox.length && $link_title.length && $title.length)) { + return; + } + // If there is a link title already, mark it as overridden. The user + // expects that toggling the checkbox twice will take over the node's + // title. + if ($checkbox.is(':checked') && $link_title.val().length) { + $link_title.data('menuLinkAutomaticTitleOverridden', true); + } + // Whenever the value is changed manually, disable this behavior. + $link_title.on('keyup', () => { + $link_title.data('menuLinkAutomaticTitleOverridden', true); + }); + // Global trigger on checkbox (do not fill-in a value when disabled). + $checkbox.on('change', () => { + if ($checkbox.is(':checked')) { + if (!$link_title.data('menuLinkAutomaticTitleOverridden')) { + $link_title.val($title.val()); + } + } + else { + $link_title.val(''); + $link_title.removeData('menuLinkAutomaticTitleOverridden'); + } + $checkbox.closest('.vertical-tabs-pane').trigger('summaryUpdated'); + $checkbox.trigger('formUpdated'); + }); + // Take over any title change. + $title.on('keyup', () => { + if (!$link_title.data('menuLinkAutomaticTitleOverridden') && $checkbox.is(':checked')) { + $link_title.val($title.val()); + $link_title.val($title.val()).trigger('formUpdated'); + } + }); + }); + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/menu_ui/menu_ui.info.yml b/core/modules/menu_ui/menu_ui.info.yml index f331d850..c8f3a31f 100644 --- a/core/modules/menu_ui/menu_ui.info.yml +++ b/core/modules/menu_ui/menu_ui.info.yml @@ -8,8 +8,8 @@ configure: entity.menu.collection dependencies: - menu_link_content -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/menu_ui/menu_ui.js b/core/modules/menu_ui/menu_ui.js index 5eb10e07..fe0feed9 100644 --- a/core/modules/menu_ui/menu_ui.js +++ b/core/modules/menu_ui/menu_ui.js @@ -1,83 +1,59 @@ /** - * @file - * Menu UI behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Set a summary on the menu link form. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Find the form and call `drupalSetSummary` on it. - */ Drupal.behaviors.menuUiDetailsSummaries = { - attach: function (context) { + attach: function attach(context) { $(context).find('.menu-link-form').drupalSetSummary(function (context) { var $context = $(context); if ($context.find('.js-form-item-menu-enabled input').is(':checked')) { return Drupal.checkPlain($context.find('.js-form-item-menu-title input').val()); } - else { - return Drupal.t('Not in menu'); - } + + return Drupal.t('Not in menu'); }); } }; - /** - * Automatically fill in a menu link title, if possible. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches change and keyup behavior for automatically filling out menu - * link titles. - */ Drupal.behaviors.menuUiLinkAutomaticTitle = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); $context.find('.menu-link-form').each(function () { var $this = $(this); - // Try to find menu settings widget elements as well as a 'title' field - // in the form, but play nicely with user permissions and form - // alterations. + var $checkbox = $this.find('.js-form-item-menu-enabled input'); var $link_title = $context.find('.js-form-item-menu-title input'); var $title = $this.closest('form').find('.js-form-item-title-0-value input'); - // Bail out if we do not have all required fields. + if (!($checkbox.length && $link_title.length && $title.length)) { return; } - // If there is a link title already, mark it as overridden. The user - // expects that toggling the checkbox twice will take over the node's - // title. + if ($checkbox.is(':checked') && $link_title.val().length) { $link_title.data('menuLinkAutomaticTitleOverridden', true); } - // Whenever the value is changed manually, disable this behavior. + $link_title.on('keyup', function () { $link_title.data('menuLinkAutomaticTitleOverridden', true); }); - // Global trigger on checkbox (do not fill-in a value when disabled). + $checkbox.on('change', function () { if ($checkbox.is(':checked')) { if (!$link_title.data('menuLinkAutomaticTitleOverridden')) { $link_title.val($title.val()); } - } - else { + } else { $link_title.val(''); $link_title.removeData('menuLinkAutomaticTitleOverridden'); } $checkbox.closest('.vertical-tabs-pane').trigger('summaryUpdated'); $checkbox.trigger('formUpdated'); }); - // Take over any title change. + $title.on('keyup', function () { if (!$link_title.data('menuLinkAutomaticTitleOverridden') && $checkbox.is(':checked')) { $link_title.val($title.val()); @@ -87,5 +63,4 @@ }); } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index 92254c2d..cb1e8530 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -10,7 +10,6 @@ use Drupal\Core\Breadcrumb\Breadcrumb; use Drupal\Core\Cache\CacheableMetadata; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Block\BlockPluginInterface; use Drupal\Core\Link; use Drupal\Core\Menu\MenuLinkInterface; @@ -22,8 +21,13 @@ use Drupal\system\Entity\Menu; use Drupal\node\NodeInterface; /** - * Maximum length of menu name as entered by the user. Database length is 32 - * and we add a menu- prefix. + * Maximum length of menu name as entered by the user. + * + * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. Use + * \Drupal\Core\Config\Entity\ConfigEntityStorage::MAX_ID_LENGTH because the + * menu name is a configuration entity ID. + * + * @see https://www.drupal.org/node/2831620 */ const MENU_MAX_MENU_NAME_LENGTH_UI = 27; @@ -35,21 +39,21 @@ function menu_ui_help($route_name, RouteMatchInterface $route_match) { case 'help.page.menu_ui': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Menu UI module provides an interface for managing menus. A menu is a hierarchical collection of links, which can be within or external to the site, generally used for navigation. For more information, see the online documentation for the Menu UI module.', array(':menu' => 'https://www.drupal.org/documentation/modules/menu/')) . '

    '; + $output .= '

    ' . t('The Menu UI module provides an interface for managing menus. A menu is a hierarchical collection of links, which can be within or external to the site, generally used for navigation. For more information, see the online documentation for the Menu UI module.', [':menu' => 'https://www.drupal.org/documentation/modules/menu/']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Managing menus') . '
    '; - $output .= '
    ' . t('Users with the Administer menus and menu items permission can add, edit, and delete custom menus on the Menus page. Custom menus can be special site menus, menus of external links, or any combination of internal and external links. You may create an unlimited number of additional menus, each of which will automatically have an associated block (if you have the Block module installed). By selecting Edit menu, you can add, edit, or delete links for a given menu. The links listing page provides a drag-and-drop interface for controlling the order of links, and creating a hierarchy within the menu.', array(':block_help' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('help.page', array('name' => 'block')) : '#', ':menu' => \Drupal::url('entity.menu.collection'))) . '
    '; + $output .= '
    ' . t('Users with the Administer menus and menu items permission can add, edit, and delete custom menus on the Menus page. Custom menus can be special site menus, menus of external links, or any combination of internal and external links. You may create an unlimited number of additional menus, each of which will automatically have an associated block (if you have the Block module installed). By selecting Edit menu, you can add, edit, or delete links for a given menu. The links listing page provides a drag-and-drop interface for controlling the order of links, and creating a hierarchy within the menu.', [':block_help' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('help.page', ['name' => 'block']) : '#', ':menu' => \Drupal::url('entity.menu.collection')]) . '
    '; $output .= '
    ' . t('Displaying menus') . '
    '; - $output .= '
    ' . t('If you have the Block module enabled, then each menu that you create is rendered in a block that you enable and position on the Block layout page. In some themes, the main menu and possibly the secondary menu will be output automatically; you may be able to disable this behavior on the theme\'s settings page.', array(':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#', ':themes' => \Drupal::url('system.themes_page'), ':theme_settings' => \Drupal::url('system.theme_settings'))) . '
    '; + $output .= '
    ' . t('If you have the Block module enabled, then each menu that you create is rendered in a block that you enable and position on the Block layout page. In some themes, the main menu and possibly the secondary menu will be output automatically; you may be able to disable this behavior on the theme\'s settings page.', [':blocks' => (\Drupal::moduleHandler()->moduleExists('block')) ? \Drupal::url('block.admin_display') : '#', ':themes' => \Drupal::url('system.themes_page'), ':theme_settings' => \Drupal::url('system.theme_settings')]) . '
    '; $output .= '
    '; return $output; } if ($route_name == 'entity.menu.add_form' && \Drupal::moduleHandler()->moduleExists('block') && \Drupal::currentUser()->hasPermission('administer blocks')) { - return '

    ' . t('You can enable the newly-created block for this menu on the Block layout page.', array(':blocks' => \Drupal::url('block.admin_display'))) . '

    '; + return '

    ' . t('You can enable the newly-created block for this menu on the Block layout page.', [':blocks' => \Drupal::url('block.admin_display')]) . '

    '; } elseif ($route_name == 'entity.menu.collection' && \Drupal::moduleHandler()->moduleExists('block') && \Drupal::currentUser()->hasPermission('administer blocks')) { - return '

    ' . t('Each menu has a corresponding block that is managed on the Block layout page.', array(':blocks' => \Drupal::url('block.admin_display'))) . '

    '; + return '

    ' . t('Each menu has a corresponding block that is managed on the Block layout page.', [':blocks' => \Drupal::url('block.admin_display')]) . '

    '; } } @@ -68,6 +72,10 @@ function menu_ui_entity_type_build(array &$entity_types) { ->setLinkTemplate('edit-form', '/admin/structure/menu/manage/{menu}') ->setLinkTemplate('add-link-form', '/admin/structure/menu/manage/{menu}/add') ->setLinkTemplate('collection', '/admin/structure/menu'); + + if (isset($entity_types['node'])) { + $entity_types['node']->addConstraint('MenuSettings', []); + } } /** @@ -120,9 +128,9 @@ function menu_ui_menu_delete(Menu $menu) { function menu_ui_block_view_system_menu_block_alter(array &$build, BlockPluginInterface $block) { if ($block->getBaseId() == 'system_menu_block') { $menu_name = $block->getDerivativeId(); - $build['#contextual_links']['menu'] = array( - 'route_parameters' => array('menu' => $menu_name), - ); + $build['#contextual_links']['menu'] = [ + 'route_parameters' => ['menu' => $menu_name], + ]; } } @@ -149,10 +157,10 @@ function _menu_ui_node_save(NodeInterface $node, array $values) { } else { // Create a new menu_link_content entity. - $entity = MenuLinkContent::create(array( + $entity = MenuLinkContent::create([ 'link' => ['uri' => 'entity:node/' . $node->id()], 'langcode' => $node->language()->getId(), - )); + ]); $entity->enabled->value = 1; } $entity->title->value = trim($values['title']); @@ -163,24 +171,6 @@ function _menu_ui_node_save(NodeInterface $node, array $values) { $entity->save(); } -/** - * Implements hook_ENTITY_TYPE_predelete() for node entities. - */ -function menu_ui_node_predelete(EntityInterface $node) { - // Delete all MenuLinkContent links that point to this node. - /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ - $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - $result = $menu_link_manager->loadLinksByRoute('entity.node.canonical', array('node' => $node->id())); - - if (!empty($result)) { - foreach ($result as $id => $instance) { - if ($instance->isDeletable() && strpos($id, 'menu_link_content:') === 0) { - $instance->deleteLink(); - } - } - } -} - /** * Returns the definition for a menu link for the given node. * @@ -199,7 +189,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { if ($node->id()) { $id = FALSE; // Give priority to the default menu - $type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', array('main')); + $type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', ['main']); if (in_array($menu_name, $type_menus)) { $query = \Drupal::entityQuery('menu_link_content') ->condition('link.uri', 'node/' . $node->id()) @@ -224,7 +214,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { if ($id) { $menu_link = MenuLinkContent::load($id); $menu_link = \Drupal::service('entity.repository')->getTranslationFromContext($menu_link); - $defaults = array( + $defaults = [ 'entity_id' => $menu_link->id(), 'id' => $menu_link->getPluginId(), 'title' => $menu_link->getTitle(), @@ -233,7 +223,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { 'menu_name' => $menu_link->getMenuName(), 'parent' => $menu_link->getParentId(), 'weight' => $menu_link->getWeight(), - ); + ]; } } @@ -242,7 +232,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { // definition. $field_definitions = \Drupal::entityManager()->getBaseFieldDefinitions('menu_link_content'); $max_length = $field_definitions['title']->getSetting('max_length'); - $defaults = array( + $defaults = [ 'entity_id' => 0, 'id' => '', 'title' => '', @@ -251,7 +241,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { 'menu_name' => $menu_name, 'parent' => '', 'weight' => 0, - ); + ]; } return $defaults; } @@ -273,8 +263,8 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) { /** @var \Drupal\Core\Menu\MenuParentFormSelectorInterface $menu_parent_selector */ $menu_parent_selector = \Drupal::service('menu.parent_form_selector'); $menu_names = menu_ui_get_menus(); - $type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', array('main')); - $available_menus = array(); + $type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', ['main']); + $available_menus = []; foreach ($type_menus as $menu) { $available_menus[$menu] = $menu_names[$menu]; } @@ -290,70 +280,79 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) { return; } - $form['menu'] = array( + $form['menu'] = [ '#type' => 'details', '#title' => t('Menu settings'), '#access' => \Drupal::currentUser()->hasPermission('administer menu'), '#open' => (bool) $defaults['id'], '#group' => 'advanced', - '#attached' => array( - 'library' => array('menu_ui/drupal.menu_ui'), - ), + '#attached' => [ + 'library' => ['menu_ui/drupal.menu_ui'], + ], '#tree' => TRUE, '#weight' => -2, - '#attributes' => array('class' => array('menu-link-form')), - ); - $form['menu']['enabled'] = array( + '#attributes' => ['class' => ['menu-link-form']], + ]; + $form['menu']['enabled'] = [ '#type' => 'checkbox', '#title' => t('Provide a menu link'), '#default_value' => (int) (bool) $defaults['id'], - ); - $form['menu']['link'] = array( + ]; + $form['menu']['link'] = [ '#type' => 'container', - '#parents' => array('menu'), - '#states' => array( - 'invisible' => array( - 'input[name="menu[enabled]"]' => array('checked' => FALSE), - ), - ), - ); + '#parents' => ['menu'], + '#states' => [ + 'invisible' => [ + 'input[name="menu[enabled]"]' => ['checked' => FALSE], + ], + ], + ]; // Populate the element with the link data. - foreach (array('id', 'entity_id') as $key) { - $form['menu']['link'][$key] = array('#type' => 'value', '#value' => $defaults[$key]); + foreach (['id', 'entity_id'] as $key) { + $form['menu']['link'][$key] = ['#type' => 'value', '#value' => $defaults[$key]]; } - $form['menu']['link']['title'] = array( + $form['menu']['link']['title'] = [ '#type' => 'textfield', '#title' => t('Menu link title'), '#default_value' => $defaults['title'], '#maxlength' => $defaults['title_max_length'], - ); + ]; - $form['menu']['link']['description'] = array( + $form['menu']['link']['description'] = [ '#type' => 'textarea', '#title' => t('Description'), '#default_value' => $defaults['description'], '#rows' => 1, '#description' => t('Shown when hovering over the menu link.'), - ); + ]; $form['menu']['link']['menu_parent'] = $parent_element; $form['menu']['link']['menu_parent']['#title'] = t('Parent item'); $form['menu']['link']['menu_parent']['#attributes']['class'][] = 'menu-parent-select'; - $form['menu']['link']['weight'] = array( + $form['menu']['link']['weight'] = [ '#type' => 'number', '#title' => t('Weight'), '#default_value' => $defaults['weight'], '#description' => t('Menu links with lower weights are displayed before links with higher weights.'), - ); + ]; foreach (array_keys($form['actions']) as $action) { if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') { $form['actions'][$action]['#submit'][] = 'menu_ui_form_node_form_submit'; } } + + $form['#entity_builders'][] = 'menu_ui_node_builder'; +} + +/** + * Entity form builder to add the menu information to the node. + */ +function menu_ui_node_builder($entity_type, NodeInterface $entity, &$form, FormStateInterface $form_state) { + $entity->menu = $form_state->getValue('menu'); } /** @@ -398,21 +397,21 @@ function menu_ui_form_node_type_form_alter(&$form, FormStateInterface $form_stat $menu_options = menu_ui_get_menus(); /** @var \Drupal\node\NodeTypeInterface $type */ $type = $form_state->getFormObject()->getEntity(); - $form['menu'] = array( + $form['menu'] = [ '#type' => 'details', '#title' => t('Menu settings'), - '#attached' => array( - 'library' => array('menu_ui/drupal.menu_ui.admin'), - ), + '#attached' => [ + 'library' => ['menu_ui/drupal.menu_ui.admin'], + ], '#group' => 'additional_settings', - ); - $form['menu']['menu_options'] = array( + ]; + $form['menu']['menu_options'] = [ '#type' => 'checkboxes', '#title' => t('Available menus'), - '#default_value' => $type->getThirdPartySetting('menu_ui', 'available_menus', array('main')), + '#default_value' => $type->getThirdPartySetting('menu_ui', 'available_menus', ['main']), '#options' => $menu_options, '#description' => t('The menus available to place links in for this content type.'), - ); + ]; // @todo See if we can avoid pre-loading all options by changing the form or // using a #process callback. https://www.drupal.org/node/2310319 // To avoid an 'illegal option' error after saving the form we have to load @@ -420,14 +419,14 @@ function menu_ui_form_node_type_form_alter(&$form, FormStateInterface $form_stat // add options to the list using ajax. $options_cacheability = new CacheableMetadata(); $options = $menu_parent_selector->getParentSelectOptions('', NULL, $options_cacheability); - $form['menu']['menu_parent'] = array( + $form['menu']['menu_parent'] = [ '#type' => 'select', '#title' => t('Default parent item'), '#default_value' => $type->getThirdPartySetting('menu_ui', 'parent', 'main:'), '#options' => $options, '#description' => t('Choose the menu item to be the default parent for a new link in the content authoring form.'), - '#attributes' => array('class' => array('menu-title-select')), - ); + '#attributes' => ['class' => ['menu-title-select']], + ]; $options_cacheability->applyTo($form['menu']['menu_parent']); $form['#validate'][] = 'menu_ui_form_node_type_form_validate'; diff --git a/core/modules/menu_ui/migration_templates/menu_settings.yml b/core/modules/menu_ui/migration_templates/menu_settings.yml index dee5f9ee..d3b1501c 100644 --- a/core/modules/menu_ui/migration_templates/menu_settings.yml +++ b/core/modules/menu_ui/migration_templates/menu_settings.yml @@ -8,6 +8,7 @@ source: plugin: variable variables: - menu_override_parent_selector + source_module: menu process: override_parent_selector: menu_override_parent_selector destination: diff --git a/core/modules/menu_ui/src/Controller/MenuController.php b/core/modules/menu_ui/src/Controller/MenuController.php index 39b0a32a..7958c101 100644 --- a/core/modules/menu_ui/src/Controller/MenuController.php +++ b/core/modules/menu_ui/src/Controller/MenuController.php @@ -49,7 +49,7 @@ public static function create(ContainerInterface $container) { * The available menu and menu items. */ public function getParentOptions(Request $request) { - $available_menus = array(); + $available_menus = []; if ($menus = $request->request->get('menus')) { foreach ($menus as $menu) { $available_menus[$menu] = $menu; diff --git a/core/modules/menu_ui/src/Form/MenuDeleteForm.php b/core/modules/menu_ui/src/Form/MenuDeleteForm.php index 22bfb0ac..1cebd909 100644 --- a/core/modules/menu_ui/src/Form/MenuDeleteForm.php +++ b/core/modules/menu_ui/src/Form/MenuDeleteForm.php @@ -57,7 +57,7 @@ public function getDescription() { $caption = ''; $num_links = $this->menuLinkManager->countMenuLinks($this->entity->id()); if ($num_links) { - $caption .= '

    ' . $this->formatPlural($num_links, 'Warning: There is currently 1 menu link in %title. It will be deleted (system-defined items will be reset).', 'Warning: There are currently @count menu links in %title. They will be deleted (system-defined links will be reset).', array('%title' => $this->entity->label())) . '

    '; + $caption .= '

    ' . $this->formatPlural($num_links, 'Warning: There is currently 1 menu link in %title. It will be deleted (system-defined items will be reset).', 'Warning: There are currently @count menu links in %title. They will be deleted (system-defined links will be reset).', ['%title' => $this->entity->label()]) . '

    '; } $caption .= '

    ' . t('This action cannot be undone.') . '

    '; return $caption; @@ -67,7 +67,7 @@ public function getDescription() { * {@inheritdoc} */ protected function logDeletionMessage() { - $this->logger('menu')->notice('Deleted custom menu %title and all its menu links.', array('%title' => $this->entity->label())); + $this->logger('menu')->notice('Deleted custom menu %title and all its menu links.', ['%title' => $this->entity->label()]); } /** @@ -85,7 +85,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // parameter that is being removed. Also, consider moving this to // menu_ui.module as part of a generic response to entity deletion. // https://www.drupal.org/node/2310329 - $menu_links = $this->menuLinkManager->loadLinksByRoute('entity.menu.edit_form', array('menu' => $this->entity->id()), TRUE); + $menu_links = $this->menuLinkManager->loadLinksByRoute('entity.menu.edit_form', ['menu' => $this->entity->id()], TRUE); foreach ($menu_links as $id => $link) { $this->menuLinkManager->removeDefinition($id); } diff --git a/core/modules/menu_ui/src/Form/MenuLinkEditForm.php b/core/modules/menu_ui/src/Form/MenuLinkEditForm.php index cf133cd5..2dbd6a5e 100644 --- a/core/modules/menu_ui/src/Form/MenuLinkEditForm.php +++ b/core/modules/menu_ui/src/Form/MenuLinkEditForm.php @@ -57,22 +57,22 @@ public function getFormId() { * The plugin instance to use for this form. */ public function buildForm(array $form, FormStateInterface $form_state, MenuLinkInterface $menu_link_plugin = NULL) { - $form['menu_link_id'] = array( + $form['menu_link_id'] = [ '#type' => 'value', '#value' => $menu_link_plugin->getPluginId(), - ); + ]; $class_name = $menu_link_plugin->getFormClass(); $form['#plugin_form'] = $this->classResolver->getInstanceFromDefinition($class_name); $form['#plugin_form']->setMenuLinkInstance($menu_link_plugin); $form += $form['#plugin_form']->buildConfigurationForm($form, $form_state); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), '#button_type' => 'primary', - ); + ]; return $form; } @@ -92,7 +92,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { drupal_set_message($this->t('The menu link has been saved.')); $form_state->setRedirect( 'entity.menu.edit_form', - array('menu' => $link->getMenuName()) + ['menu' => $link->getMenuName()] ); } diff --git a/core/modules/menu_ui/src/Form/MenuLinkResetForm.php b/core/modules/menu_ui/src/Form/MenuLinkResetForm.php index 6fbf6228..e37b16b0 100644 --- a/core/modules/menu_ui/src/Form/MenuLinkResetForm.php +++ b/core/modules/menu_ui/src/Form/MenuLinkResetForm.php @@ -59,16 +59,16 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to reset the link %item to its default values?', array('%item' => $this->link->getTitle())); + return $this->t('Are you sure you want to reset the link %item to its default values?', ['%item' => $this->link->getTitle()]); } /** * {@inheritdoc} */ public function getCancelUrl() { - return new Url('entity.menu.edit_form', array( + return new Url('entity.menu.edit_form', [ 'menu' => $this->link->getMenuName(), - )); + ]); } /** diff --git a/core/modules/menu_ui/src/MenuForm.php b/core/modules/menu_ui/src/MenuForm.php index 7e09fbf6..cb27b25d 100644 --- a/core/modules/menu_ui/src/MenuForm.php +++ b/core/modules/menu_ui/src/MenuForm.php @@ -5,7 +5,6 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Entity\EntityForm; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Link; @@ -23,13 +22,6 @@ */ class MenuForm extends EntityForm { - /** - * The factory for entity queries. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $entityQueryFactory; - /** * The menu link manager. * @@ -56,13 +48,11 @@ class MenuForm extends EntityForm { * * @var array */ - protected $overviewTreeForm = array('#tree' => TRUE); + protected $overviewTreeForm = ['#tree' => TRUE]; /** * Constructs a MenuForm object. * - * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory - * The factory for entity queries. * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager * The menu link manager. * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree @@ -70,8 +60,7 @@ class MenuForm extends EntityForm { * @param \Drupal\Core\Utility\LinkGeneratorInterface $link_generator * The link generator. */ - public function __construct(QueryFactory $entity_query_factory, MenuLinkManagerInterface $menu_link_manager, MenuLinkTreeInterface $menu_tree, LinkGeneratorInterface $link_generator) { - $this->entityQueryFactory = $entity_query_factory; + public function __construct(MenuLinkManagerInterface $menu_link_manager, MenuLinkTreeInterface $menu_tree, LinkGeneratorInterface $link_generator) { $this->menuLinkManager = $menu_link_manager; $this->menuTree = $menu_tree; $this->linkGenerator = $link_generator; @@ -82,7 +71,6 @@ public function __construct(QueryFactory $entity_query_factory, MenuLinkManagerI */ public static function create(ContainerInterface $container) { return new static( - $container->get('entity.query'), $container->get('plugin.manager.menu.link'), $container->get('menu.link_tree'), $container->get('link_generator') @@ -96,43 +84,43 @@ public function form(array $form, FormStateInterface $form_state) { $menu = $this->entity; if ($this->operation == 'edit') { - $form['#title'] = $this->t('Edit menu %label', array('%label' => $menu->label())); + $form['#title'] = $this->t('Edit menu %label', ['%label' => $menu->label()]); } - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => $this->t('Title'), '#default_value' => $menu->label(), '#required' => TRUE, - ); - $form['id'] = array( + ]; + $form['id'] = [ '#type' => 'machine_name', '#title' => $this->t('Menu name'), '#default_value' => $menu->id(), '#maxlength' => MENU_MAX_MENU_NAME_LENGTH_UI, '#description' => $this->t('A unique name to construct the URL for the menu. It must only contain lowercase letters, numbers and hyphens.'), - '#machine_name' => array( - 'exists' => array($this, 'menuNameExists'), - 'source' => array('label'), + '#machine_name' => [ + 'exists' => [$this, 'menuNameExists'], + 'source' => ['label'], 'replace_pattern' => '[^a-z0-9-]+', 'replace' => '-', - ), + ], // A menu's machine name cannot be changed. '#disabled' => !$menu->isNew() || $menu->isLocked(), - ); - $form['description'] = array( + ]; + $form['description'] = [ '#type' => 'textfield', '#title' => t('Administrative summary'), '#maxlength' => 512, '#default_value' => $menu->getDescription(), - ); + ]; - $form['langcode'] = array( + $form['langcode'] = [ '#type' => 'language_select', '#title' => t('Menu language'), '#languages' => LanguageInterface::STATE_ALL, '#default_value' => $menu->language()->getId(), - ); + ]; // Add menu links administration form for existing menus. if (!$menu->isNew() || $menu->isLocked()) { @@ -142,7 +130,7 @@ public function form(array $form, FormStateInterface $form_state) { // the parents of the form section. // @see self::submitOverviewForm() $form_state->set('menu_overview_form_parents', ['links']); - $form['links'] = array(); + $form['links'] = []; $form['links'] = $this->buildOverviewForm($form['links'], $form_state); } @@ -160,7 +148,7 @@ public function form(array $form, FormStateInterface $form_state) { */ public function menuNameExists($value) { // Check first to see if a menu with this ID exists. - if ($this->entityQueryFactory->get('menu')->condition('id', $value)->range(0, 1)->count()->execute()) { + if ($this->entityTypeManager->getStorage('menu')->getQuery()->condition('id', $value)->range(0, 1)->count()->execute()) { return TRUE; } @@ -176,12 +164,12 @@ public function save(array $form, FormStateInterface $form_state) { $status = $menu->save(); $edit_link = $this->entity->link($this->t('Edit')); if ($status == SAVED_UPDATED) { - drupal_set_message($this->t('Menu %label has been updated.', array('%label' => $menu->label()))); - $this->logger('menu')->notice('Menu %label has been updated.', array('%label' => $menu->label(), 'link' => $edit_link)); + drupal_set_message($this->t('Menu %label has been updated.', ['%label' => $menu->label()])); + $this->logger('menu')->notice('Menu %label has been updated.', ['%label' => $menu->label(), 'link' => $edit_link]); } else { - drupal_set_message($this->t('Menu %label has been added.', array('%label' => $menu->label()))); - $this->logger('menu')->notice('Menu %label has been added.', array('%label' => $menu->label(), 'link' => $edit_link)); + drupal_set_message($this->t('Menu %label has been added.', ['%label' => $menu->label()])); + $this->logger('menu')->notice('Menu %label has been added.', ['%label' => $menu->label(), 'link' => $edit_link]); } $form_state->setRedirectUrl($this->entity->urlInfo('edit-form')); @@ -225,15 +213,15 @@ protected function buildOverviewForm(array &$form, FormStateInterface $form_stat // We indicate that a menu administrator is running the menu access check. $this->getRequest()->attributes->set('_menu_admin', TRUE); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'], + ]; $tree = $this->menuTree->transform($tree, $manipulators); $this->getRequest()->attributes->set('_menu_admin', FALSE); // Determine the delta; the number of weights to be made available. - $count = function(array $tree) { + $count = function (array $tree) { $sum = function ($carry, MenuLinkTreeElement $item) { return $carry + $item->count(); }; @@ -241,26 +229,26 @@ protected function buildOverviewForm(array &$form, FormStateInterface $form_stat }; $delta = max($count($tree), 50); - $form['links'] = array( + $form['links'] = [ '#type' => 'table', '#theme' => 'table__menu_overview', - '#header' => array( + '#header' => [ $this->t('Menu link'), - array( + [ 'data' => $this->t('Enabled'), - 'class' => array('checkbox'), - ), + 'class' => ['checkbox'], + ], $this->t('Weight'), - array( + [ 'data' => $this->t('Operations'), 'colspan' => 3, - ), - ), - '#attributes' => array( + ], + ], + '#attributes' => [ 'id' => 'menu-overview', - ), - '#tabledrag' => array( - array( + ], + '#tabledrag' => [ + [ 'action' => 'match', 'relationship' => 'parent', 'group' => 'menu-parent', @@ -268,14 +256,14 @@ protected function buildOverviewForm(array &$form, FormStateInterface $form_stat 'source' => 'menu-id', 'hidden' => TRUE, 'limit' => \Drupal::menuTree()->maxDepth() - 1, - ), - array( + ], + [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'menu-weight', - ), - ), - ); + ], + ], + ]; $form['links']['#empty'] = $this->t('There are no menu links yet. Add link.', [ ':url' => $this->url('entity.menu.add_link_form', ['menu' => $this->entity->id()], [ @@ -297,19 +285,19 @@ protected function buildOverviewForm(array &$form, FormStateInterface $form_stat $form['links'][$id]['#weight'] = $element['#item']->link->getWeight(); // Add special classes to be used for tabledrag.js. - $element['parent']['#attributes']['class'] = array('menu-parent'); - $element['weight']['#attributes']['class'] = array('menu-weight'); - $element['id']['#attributes']['class'] = array('menu-id'); + $element['parent']['#attributes']['class'] = ['menu-parent']; + $element['weight']['#attributes']['class'] = ['menu-weight']; + $element['id']['#attributes']['class'] = ['menu-id']; - $form['links'][$id]['title'] = array( - array( + $form['links'][$id]['title'] = [ + [ '#theme' => 'indentation', '#size' => $element['#item']->depth - 1, - ), + ], $element['title'], - ); + ]; $form['links'][$id]['enabled'] = $element['enabled']; - $form['links'][$id]['enabled']['#wrapper_attributes']['class'] = array('checkbox', 'menu-enabled'); + $form['links'][$id]['enabled']['#wrapper_attributes']['class'] = ['checkbox', 'menu-enabled']; $form['links'][$id]['weight'] = $element['weight']; @@ -351,7 +339,7 @@ protected function buildOverviewTreeForm($tree, $delta) { if ($link) { $id = 'menu_plugin_id:' . $link->getPluginId(); $form[$id]['#item'] = $element; - $form[$id]['#attributes'] = $link->isEnabled() ? array('class' => array('menu-enabled')) : array('class' => array('menu-disabled')); + $form[$id]['#attributes'] = $link->isEnabled() ? ['class' => ['menu-enabled']] : ['class' => ['menu-disabled']]; $form[$id]['title'] = Link::fromTextAndUrl($link->getTitle(), $link->getUrlObject())->toRenderable(); if (!$link->isEnabled()) { $form[$id]['title']['#suffix'] = ' (' . $this->t('disabled') . ')'; @@ -365,32 +353,32 @@ protected function buildOverviewTreeForm($tree, $delta) { $form[$id]['title']['#suffix'] = ' (' . $this->t('logged in users only') . ')'; } - $form[$id]['enabled'] = array( + $form[$id]['enabled'] = [ '#type' => 'checkbox', - '#title' => $this->t('Enable @title menu link', array('@title' => $link->getTitle())), + '#title' => $this->t('Enable @title menu link', ['@title' => $link->getTitle()]), '#title_display' => 'invisible', '#default_value' => $link->isEnabled(), - ); - $form[$id]['weight'] = array( + ]; + $form[$id]['weight'] = [ '#type' => 'weight', '#delta' => $delta, '#default_value' => $link->getWeight(), - '#title' => $this->t('Weight for @title', array('@title' => $link->getTitle())), + '#title' => $this->t('Weight for @title', ['@title' => $link->getTitle()]), '#title_display' => 'invisible', - ); - $form[$id]['id'] = array( + ]; + $form[$id]['id'] = [ '#type' => 'hidden', '#value' => $link->getPluginId(), - ); - $form[$id]['parent'] = array( + ]; + $form[$id]['parent'] = [ '#type' => 'hidden', '#default_value' => $link->getParent(), - ); + ]; // Build a list of operations. - $operations = array(); - $operations['edit'] = array( + $operations = []; + $operations['edit'] = [ 'title' => $this->t('Edit'), - ); + ]; // Allow for a custom edit link per plugin. $edit_route = $link->getEditRoute(); if ($edit_route) { @@ -400,16 +388,16 @@ protected function buildOverviewTreeForm($tree, $delta) { } else { // Fall back to the standard edit link. - $operations['edit'] += array( + $operations['edit'] += [ 'url' => Url::fromRoute('menu_ui.link_edit', ['menu_link_plugin' => $link->getPluginId()]), - ); + ]; } // Links can either be reset or deleted, not both. if ($link->isResettable()) { - $operations['reset'] = array( + $operations['reset'] = [ 'title' => $this->t('Reset'), 'url' => Url::fromRoute('menu_ui.link_reset', ['menu_link_plugin' => $link->getPluginId()]), - ); + ]; } elseif ($delete_link = $link->getDeleteRoute()) { $operations['delete']['url'] = $delete_link; @@ -417,15 +405,15 @@ protected function buildOverviewTreeForm($tree, $delta) { $operations['delete']['title'] = $this->t('Delete'); } if ($link->isTranslatable()) { - $operations['translate'] = array( + $operations['translate'] = [ 'title' => $this->t('Translate'), 'url' => $link->getTranslateRoute(), - ); + ]; } - $form[$id]['operations'] = array( + $form[$id]['operations'] = [ '#type' => 'operations', '#links' => $operations, - ); + ]; } if ($element->subtree) { @@ -461,16 +449,16 @@ protected function submitOverviewForm(array $complete_form, FormStateInterface $ // parent. To prevent this, save items in the form in the same order they // are sent, ensuring parents are saved first, then their children. // See https://www.drupal.org/node/181126#comment-632270. - $order = is_array($input) ? array_flip(array_keys($input)) : array(); + $order = is_array($input) ? array_flip(array_keys($input)) : []; // Update our original form with the new order. $form = array_intersect_key(array_merge($order, $form), $form); - $fields = array('weight', 'parent', 'enabled'); + $fields = ['weight', 'parent', 'enabled']; $form_links = $form['links']; foreach (Element::children($form_links) as $id) { if (isset($form_links[$id]['#item'])) { $element = $form_links[$id]; - $updated_values = array(); + $updated_values = []; // Update any fields that have changed in this menu item. foreach ($fields as $field) { if ($element[$field]['#value'] != $element[$field]['#default_value']) { diff --git a/core/modules/menu_ui/src/MenuListBuilder.php b/core/modules/menu_ui/src/MenuListBuilder.php index 15342727..b694c8b9 100644 --- a/core/modules/menu_ui/src/MenuListBuilder.php +++ b/core/modules/menu_ui/src/MenuListBuilder.php @@ -18,10 +18,10 @@ class MenuListBuilder extends ConfigEntityListBuilder { */ public function buildHeader() { $header['title'] = t('Title'); - $header['description'] = array( + $header['description'] = [ 'data' => t('Description'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ); + 'class' => [RESPONSIVE_PRIORITY_MEDIUM], + ]; return $header + parent::buildHeader(); } @@ -29,10 +29,10 @@ public function buildHeader() { * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { - $row['title'] = array( + $row['title'] = [ 'data' => $entity->label(), - 'class' => array('menu-label'), - ); + 'class' => ['menu-label'], + ]; $row['description']['data'] = ['#markup' => $entity->getDescription()]; return $row + parent::buildRow($entity); } @@ -45,11 +45,11 @@ public function getDefaultOperations(EntityInterface $entity) { if (isset($operations['edit'])) { $operations['edit']['title'] = t('Edit menu'); - $operations['add'] = array( + $operations['add'] = [ 'title' => t('Add link'), 'weight' => 20, 'url' => $entity->urlInfo('add-link-form'), - ); + ]; } if (isset($operations['delete'])) { $operations['delete']['title'] = t('Delete menu'); diff --git a/core/modules/menu_ui/src/Plugin/Validation/Constraint/MenuSettingsConstraint.php b/core/modules/menu_ui/src/Plugin/Validation/Constraint/MenuSettingsConstraint.php new file mode 100644 index 00000000..35b29e92 --- /dev/null +++ b/core/modules/menu_ui/src/Plugin/Validation/Constraint/MenuSettingsConstraint.php @@ -0,0 +1,19 @@ +published
    version of this content.'; + +} diff --git a/core/modules/menu_ui/src/Plugin/Validation/Constraint/MenuSettingsConstraintValidator.php b/core/modules/menu_ui/src/Plugin/Validation/Constraint/MenuSettingsConstraintValidator.php new file mode 100644 index 00000000..85f7beec --- /dev/null +++ b/core/modules/menu_ui/src/Plugin/Validation/Constraint/MenuSettingsConstraintValidator.php @@ -0,0 +1,64 @@ +isNew() && !$entity->isDefaultRevision()) { + $defaults = menu_ui_get_menu_link_defaults($entity); + $values = $entity->menu; + $violation_path = NULL; + + if (trim($values['title']) && !empty($values['menu_parent'])) { + list($menu_name, $parent) = explode(':', $values['menu_parent'], 2); + $values['menu_name'] = $menu_name; + $values['parent'] = $parent; + } + + // Handle the case when a menu link is added to a pending revision. + if (!$defaults['entity_id'] && $values['enabled']) { + $violation_path = 'menu'; + } + // Handle the case when the menu link is deleted in a pending revision. + elseif (empty($values['enabled']) && $defaults['entity_id']) { + $violation_path = 'menu'; + } + // Handle all the other menu link changes in a pending revision. + elseif ($defaults['entity_id']) { + if (($values['title'] != $defaults['title'])) { + $violation_path = 'menu.title'; + } + elseif (($values['description'] != $defaults['description'])) { + $violation_path = 'menu.description'; + } + elseif ($defaults['entity_id'] && ($values['menu_name'] != $defaults['menu_name'])) { + $violation_path = 'menu.menu_parent'; + } + elseif (isset($values['parent']) && ($values['parent'] != $defaults['parent'])) { + $violation_path = 'menu.menu_parent'; + } + elseif (($values['weight'] != $defaults['weight'])) { + $violation_path = 'menu.weight'; + } + } + + if ($violation_path) { + $this->context->buildViolation($constraint->message) + ->atPath($violation_path) + ->setInvalidValue($entity) + ->addViolation(); + } + } + } + +} diff --git a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php b/core/modules/menu_ui/src/Tests/MenuLanguageTest.php index 72865ea0..4c48f05d 100644 --- a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php +++ b/core/modules/menu_ui/src/Tests/MenuLanguageTest.php @@ -21,36 +21,36 @@ class MenuLanguageTest extends MenuWebTestBase { * * @var array */ - public static $modules = array('language'); + public static $modules = ['language']; protected function setUp() { parent::setUp(); - $this->drupalLogin($this->drupalCreateUser(array('access administration pages', 'administer menu'))); + $this->drupalLogin($this->drupalCreateUser(['access administration pages', 'administer menu'])); // Add some custom languages. - foreach (array('aa', 'bb', 'cc', 'cs') as $language_code) { - ConfigurableLanguage::create(array( + foreach (['aa', 'bb', 'cc', 'cs'] as $language_code) { + ConfigurableLanguage::create([ 'id' => $language_code, 'label' => $this->randomMachineName(), - ))->save(); + ])->save(); } } /** * Tests menu language settings and the defaults for menu link items. */ - function testMenuLanguage() { + public function testMenuLanguage() { // Create a test menu to test the various language-related settings. // Machine name has to be lowercase. $menu_name = Unicode::strtolower($this->randomMachineName(16)); $label = $this->randomString(); - $edit = array( + $edit = [ 'id' => $menu_name, 'description' => '', 'label' => $label, 'langcode' => 'aa', - ); + ]; $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); ContentLanguageSettings::loadByEntityTypeBundle('menu_link_content', 'menu_link_content') ->setDefaultLangcode('bb') @@ -65,19 +65,19 @@ function testMenuLanguage() { // Add a menu link. $link_title = $this->randomString(); - $edit = array( + $edit = [ 'title[0][value]' => $link_title, 'link[0][uri]' => $link_path, - ); + ]; $this->drupalPostForm("admin/structure/menu/manage/$menu_name/add", $edit, t('Save')); // Check the link was added with the correct menu link default language. - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $link_title)); + $menu_links = entity_load_multiple_by_properties('menu_link_content', ['title' => $link_title]); $menu_link = reset($menu_links); - $this->assertMenuLink($menu_link->getPluginId(), array( + $this->assertMenuLink($menu_link->getPluginId(), [ 'menu_name' => $menu_name, 'route_name' => '', 'langcode' => 'bb', - )); + ]); // Edit menu link default, changing it to cc. ContentLanguageSettings::loadByEntityTypeBundle('menu_link_content', 'menu_link_content') @@ -87,30 +87,30 @@ function testMenuLanguage() { // Add a menu link. $link_title = $this->randomString(); - $edit = array( + $edit = [ 'title[0][value]' => $link_title, 'link[0][uri]' => $link_path, - ); + ]; $this->drupalPostForm("admin/structure/menu/manage/$menu_name/add", $edit, t('Save')); // Check the link was added with the correct new menu link default language. - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $link_title)); + $menu_links = entity_load_multiple_by_properties('menu_link_content', ['title' => $link_title]); $menu_link = reset($menu_links); - $this->assertMenuLink($menu_link->getPluginId(), array( + $this->assertMenuLink($menu_link->getPluginId(), [ 'menu_name' => $menu_name, 'route_name' => '', 'langcode' => 'cc', - )); + ]); // Now change the language of the new link to 'bb'. - $edit = array( + $edit = [ 'langcode[0][value]' => 'bb', - ); + ]; $this->drupalPostForm('admin/structure/menu/item/' . $menu_link->id() . '/edit', $edit, t('Save')); - $this->assertMenuLink($menu_link->getPluginId(), array( + $this->assertMenuLink($menu_link->getPluginId(), [ 'menu_name' => $menu_name, 'route_name' => '', 'langcode' => 'bb', - )); + ]); // Saving menu link items ends up on the edit menu page. To check the menu // link has the correct language default on edit, go to the menu link edit diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php index 3fc8423f..99900955 100644 --- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php +++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php @@ -26,7 +26,7 @@ class MenuNodeTest extends WebTestBase { * * @var array */ - public static $modules = array('menu_ui', 'test_page_test', 'node', 'block', 'locale', 'language', 'content_translation'); + public static $modules = ['menu_ui', 'test_page_test', 'node', 'block', 'locale', 'language', 'content_translation']; protected function setUp() { parent::setUp(); @@ -34,9 +34,9 @@ protected function setUp() { $this->drupalPlaceBlock('system_menu_block:main'); $this->drupalPlaceBlock('page_title_block'); - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); - $this->editor = $this->drupalCreateUser(array( + $this->editor = $this->drupalCreateUser([ 'access administration pages', 'administer content types', 'administer menu', @@ -47,14 +47,14 @@ protected function setUp() { 'update content translations', 'delete content translations', 'translate any entity', - )); + ]); $this->drupalLogin($this->editor); } /** * Test creating, editing, deleting menu links via node form widget. */ - function testMenuNodeFormWidget() { + public function testMenuNodeFormWidget() { // Verify that cacheability metadata is bubbled from the menu link tree // access checking that is performed when determining the "default parent // item" options in menu_ui_form_node_type_form_alter(). The "log out" link @@ -68,9 +68,9 @@ function testMenuNodeFormWidget() { $this->assertPattern('//', 'Menu link title field has correct maxlength in node add form.'); // Disable the default main menu, so that no menus are enabled. - $edit = array( + $edit = [ 'menu_options[main]' => FALSE, - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); // Verify that no menu settings are displayed and nodes can be created. @@ -78,47 +78,47 @@ function testMenuNodeFormWidget() { $this->assertText(t('Create Basic page')); $this->assertNoText(t('Menu settings')); $node_title = $this->randomMachineName(); - $edit = array( + $edit = [ 'title[0][value]' => $node_title, 'body[0][value]' => $this->randomString(), - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); $node = $this->drupalGetNodeByTitle($node_title); $this->assertEqual($node->getTitle(), $edit['title[0][value]']); // Test that we cannot set a menu item from a menu that is not set as // available. - $edit = array( + $edit = [ 'menu_options[tools]' => 1, 'menu_parent' => 'main:', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); $this->assertText(t('The selected menu item is not under one of the selected menus.')); - $this->assertNoRaw(t('The content type %name has been updated.', array('%name' => 'Basic page'))); + $this->assertNoRaw(t('The content type %name has been updated.', ['%name' => 'Basic page'])); // Enable Tools menu as available menu. - $edit = array( + $edit = [ 'menu_options[main]' => 1, 'menu_options[tools]' => 1, 'menu_parent' => 'main:', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); - $this->assertRaw(t('The content type %name has been updated.', array('%name' => 'Basic page'))); + $this->assertRaw(t('The content type %name has been updated.', ['%name' => 'Basic page'])); // Test that we can preview a node that will create a menu item. - $edit = array( + $edit = [ 'title[0][value]' => $node_title, 'menu[enabled]' => 1, 'menu[title]' => 'Test preview', - ); + ]; $this->drupalPostForm('node/add/page', $edit, t('Preview')); // Create a node. $node_title = $this->randomMachineName(); - $edit = array( + $edit = [ 'title[0][value]' => $node_title, 'body[0][value]' => $this->randomString(), - ); + ]; $this->drupalPostForm('node/add/page', $edit, t('Save')); $node = $this->drupalGetNodeByTitle($node_title); // Assert that there is no link for the node. @@ -126,16 +126,15 @@ function testMenuNodeFormWidget() { $this->assertNoLink($node_title); // Edit the node, enable the menu link setting, but skip the link title. - $edit = array( + $edit = [ 'menu[enabled]' => 1, - ); + ]; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Assert that there is no link for the node. $this->drupalGet('test-page'); $this->assertNoLink($node_title); - // Use not only the save button, but also the two special buttons: - // 'Save and publish' as well as 'Save and keep published'. + // Make sure the menu links only appear when the node is published. // These buttons just appear for 'administer nodes' users. $admin_user = $this->drupalCreateUser([ 'access administration pages', @@ -146,30 +145,29 @@ function testMenuNodeFormWidget() { 'edit any page content', ]); $this->drupalLogin($admin_user); - foreach (['Save and unpublish' => FALSE, 'Save and keep unpublished' => FALSE, 'Save and publish' => TRUE, 'Save and keep published' => TRUE] as $submit => $visible) { - $edit = [ - 'menu[enabled]' => 1, - 'menu[title]' => $node_title, - ]; - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, $submit); - // Assert that the link exists. - $this->drupalGet('test-page'); - if ($visible) { - $this->assertLink($node_title, 0, 'Found a menu link after submitted with ' . $submit); - } - else { - $this->assertNoLink($node_title, 'Found no menu link after submitted with ' . $submit); - } - } + // Assert that the link does not exist if unpublished. + $edit = [ + 'menu[enabled]' => 1, + 'menu[title]' => $node_title, + 'status[value]' => FALSE, + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save'); + $this->drupalGet('test-page'); + $this->assertNoLink($node_title, 'Found no menu link with the node unpublished'); + // Assert that the link exists if published. + $edit['status[value]'] = TRUE; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save'); + $this->drupalGet('test-page'); + $this->assertLink($node_title, 0, 'Found a menu link with the node published'); // Log back in as normal user. $this->drupalLogin($this->editor); // Edit the node and create a menu link. - $edit = array( + $edit = [ 'menu[enabled]' => 1, 'menu[title]' => $node_title, 'menu[weight]' => 17, - ); + ]; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Assert that the link exists. $this->drupalGet('test-page'); @@ -190,20 +188,20 @@ function testMenuNodeFormWidget() { $this->assertFalse($link->isEnabled(), 'Saving a node with a disabled menu link keeps the menu link disabled.'); // Edit the node and remove the menu link. - $edit = array( + $edit = [ 'menu[enabled]' => FALSE, - ); + ]; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Assert that there is no link for the node. $this->drupalGet('test-page'); $this->assertNoLink($node_title); // Add a menu link to the Administration menu. - $item = MenuLinkContent::create(array( + $item = MenuLinkContent::create([ 'link' => [['uri' => 'entity:node/' . $node->id()]], 'title' => $this->randomMachineName(16), 'menu_name' => 'admin', - )); + ]); $item->save(); // Assert that disabled Administration menu is not shown on the @@ -219,14 +217,14 @@ function testMenuNodeFormWidget() { $item->menu_name->value = 'tools'; $item->save(); // Create a second node. - $child_node = $this->drupalCreateNode(array('type' => 'article')); + $child_node = $this->drupalCreateNode(['type' => 'article']); // Assign a menu link to the second node, being a child of the first one. - $child_item = MenuLinkContent::create(array( + $child_item = MenuLinkContent::create([ 'link' => [['uri' => 'entity:node/' . $child_node->id()]], 'title' => $this->randomMachineName(16), 'parent' => $item->getPluginId(), 'menu_name' => $item->getMenuName(), - )); + ]); $child_item->save(); // Edit the first node. $this->drupalGet('node/' . $node->id() . '/edit'); @@ -240,9 +238,9 @@ function testMenuNodeFormWidget() { /** * Testing correct loading and saving of menu links via node form widget in a multilingual environment. */ - function testMultilingualMenuNodeFormWidget() { + public function testMultilingualMenuNodeFormWidget() { // Setup languages. - $langcodes = array('de'); + $langcodes = ['de']; foreach ($langcodes as $langcode) { ConfigurableLanguage::createFromLangcode($langcode)->save(); } @@ -257,7 +255,7 @@ function testMultilingualMenuNodeFormWidget() { $this->rebuildContainer(); - $languages = array(); + $languages = []; foreach ($langcodes as $langcode) { $languages[$langcode] = ConfigurableLanguage::load($langcode); } @@ -265,14 +263,14 @@ function testMultilingualMenuNodeFormWidget() { // Use a UI form submission to make the node type and menu link content entity translatable. $this->drupalLogout(); $this->drupalLogin($this->rootUser); - $edit = array( + $edit = [ 'entity_types[node]' => TRUE, 'entity_types[menu_link_content]' => TRUE, 'settings[node][page][settings][language][language_alterable]' => TRUE, 'settings[node][page][translatable]' => TRUE, 'settings[node][page][fields][title]' => TRUE, 'settings[menu_link_content][menu_link_content][translatable]' => TRUE, - ); + ]; $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); // Log out and back in as normal user. @@ -297,42 +295,42 @@ function testMultilingualMenuNodeFormWidget() { $node->save(); // Edit the node and create a menu link. - $edit = array( + $edit = [ 'menu[enabled]' => 1, 'menu[title]' => $node_title, 'menu[weight]' => 17, - ); - $options = array('language' => $languages[$langcodes[0]]); + ]; + $options = ['language' => $languages[$langcodes[0]]]; $url = $node->toUrl('edit-form', $options); $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); // Edit the node in a different language and translate the menu link. - $edit = array( + $edit = [ 'menu[enabled]' => 1, 'menu[title]' => $translated_node_title, 'menu[weight]' => 17, - ); - $options = array('language' => $languages[$langcodes[1]]); + ]; + $options = ['language' => $languages[$langcodes[1]]]; $url = $node->toUrl('edit-form', $options); $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); // Assert that the original link exists in the frontend. - $this->drupalGet('node/' . $node->id(), array('language' => $languages[$langcodes[0]])); + $this->drupalGet('node/' . $node->id(), ['language' => $languages[$langcodes[0]]]); $this->assertLink($node_title); // Assert that the translated link exists in the frontend. - $this->drupalGet('node/' . $node->id(), array('language' => $languages[$langcodes[1]])); + $this->drupalGet('node/' . $node->id(), ['language' => $languages[$langcodes[1]]]); $this->assertLink($translated_node_title); // Revisit the edit page in original language, check the loaded menu item title and save. - $options = array('language' => $languages[$langcodes[0]]); + $options = ['language' => $languages[$langcodes[0]]]; $url = $node->toUrl('edit-form', $options); $this->drupalGet($url); $this->assertFieldById('edit-menu-title', $node_title); $this->drupalPostForm(NULL, [], t('Save') . ' ' . t('(this translation)')); // Revisit the edit page of the translation and check the loaded menu item title. - $options = array('language' => $languages[$langcodes[1]]); + $options = ['language' => $languages[$langcodes[1]]]; $url = $node->toUrl('edit-form', $options); $this->drupalGet($url); $this->assertFieldById('edit-menu-title', $translated_node_title); diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php index e9464ab2..dde95027 100644 --- a/core/modules/menu_ui/src/Tests/MenuTest.php +++ b/core/modules/menu_ui/src/Tests/MenuTest.php @@ -10,6 +10,7 @@ use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\system\Entity\Menu; use Drupal\node\Entity\Node; +use Drupal\node\NodeInterface; /** * Add a custom menu, add menu links to the custom menu and Tools menu, check @@ -24,7 +25,7 @@ class MenuTest extends MenuWebTestBase { * * @var array */ - public static $modules = array('node', 'block', 'contextual', 'help', 'path', 'test_page_test'); + public static $modules = ['node', 'block', 'contextual', 'help', 'path', 'test_page_test']; /** * A user with administration rights. @@ -66,20 +67,20 @@ protected function setUp() { $this->drupalPlaceBlock('page_title_block'); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); // Create users. - $this->adminUser = $this->drupalCreateUser(array('access administration pages', 'administer blocks', 'administer menu', 'create article content')); - $this->authenticatedUser = $this->drupalCreateUser(array()); + $this->adminUser = $this->drupalCreateUser(['access administration pages', 'administer blocks', 'administer menu', 'create article content']); + $this->authenticatedUser = $this->drupalCreateUser([]); } /** * Tests menu functionality using the admin and user interfaces. */ - function testMenu() { + public function testMenu() { // Log in the user. $this->drupalLogin($this->adminUser); - $this->items = array(); + $this->items = []; $this->menu = $this->addCustomMenu(); $this->doMenuTests(); @@ -131,7 +132,7 @@ function testMenu() { $instance = $this->getStandardMenuLink(); $old_weight = $instance->getWeight(); // Edit the static menu link. - $edit = array(); + $edit = []; $edit['weight'] = 10; $id = $instance->getPluginId(); $this->drupalPostForm("admin/structure/menu/link/$id/edit", $edit, t('Save')); @@ -147,16 +148,16 @@ function testMenu() { /** * Adds a custom menu using CRUD functions. */ - function addCustomMenuCRUD() { + public function addCustomMenuCRUD() { // Add a new custom menu. $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI); $label = $this->randomMachineName(16); - $menu = Menu::create(array( + $menu = Menu::create([ 'id' => $menu_name, 'label' => $label, 'description' => 'Description text', - )); + ]); $menu->save(); // Assert the new menu. @@ -177,25 +178,25 @@ function addCustomMenuCRUD() { * @return \Drupal\system\Entity\Menu * The custom menu that has been created. */ - function addCustomMenu() { + public function addCustomMenu() { // Try adding a menu using a menu_name that is too long. $this->drupalGet('admin/structure/menu/add'); $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI + 1); $label = $this->randomMachineName(16); - $edit = array( + $edit = [ 'id' => $menu_name, 'description' => '', 'label' => $label, - ); + ]; $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); // Verify that using a menu_name that is too long results in a validation // message. - $this->assertRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', array( + $this->assertRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', [ '@name' => t('Menu name'), '%max' => MENU_MAX_MENU_NAME_LENGTH_UI, '%length' => Unicode::strlen($menu_name), - ))); + ])); // Change the menu_name so it no longer exceeds the maximum length. $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI); @@ -203,13 +204,13 @@ function addCustomMenu() { $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); // Verify that no validation error is given for menu_name length. - $this->assertNoRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', array( + $this->assertNoRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', [ '@name' => t('Menu name'), '%max' => MENU_MAX_MENU_NAME_LENGTH_UI, '%length' => Unicode::strlen($menu_name), - ))); + ])); // Verify that the confirmation message is displayed. - $this->assertRaw(t('Menu %label has been added.', array('%label' => $label))); + $this->assertRaw(t('Menu %label has been added.', ['%label' => $label])); $this->drupalGet('admin/structure/menu'); $this->assertText($label, 'Menu created'); @@ -230,18 +231,18 @@ function addCustomMenu() { * This deletes the custom menu that is stored in $this->menu and performs * tests on the menu delete user interface. */ - function deleteCustomMenu() { + public function deleteCustomMenu() { $menu_name = $this->menu->id(); $label = $this->menu->label(); // Delete custom menu. - $this->drupalPostForm("admin/structure/menu/manage/$menu_name/delete", array(), t('Delete')); + $this->drupalPostForm("admin/structure/menu/manage/$menu_name/delete", [], t('Delete')); $this->assertResponse(200); - $this->assertRaw(t('The menu %title has been deleted.', array('%title' => $label)), 'Custom menu was deleted'); + $this->assertRaw(t('The menu %title has been deleted.', ['%title' => $label]), 'Custom menu was deleted'); $this->assertNull(Menu::load($menu_name), 'Custom menu was deleted'); // Test if all menu links associated with the menu were removed from // database. - $result = entity_load_multiple_by_properties('menu_link_content', array('menu_name' => $menu_name)); + $result = entity_load_multiple_by_properties('menu_link_content', ['menu_name' => $menu_name]); $this->assertFalse($result, 'All menu links associated with the custom menu were deleted.'); // Make sure there's no delete button on system menus. @@ -256,7 +257,7 @@ function deleteCustomMenu() { /** * Tests menu functionality. */ - function doMenuTests() { + public function doMenuTests() { $menu_name = $this->menu->id(); // Test the 'Add link' local action. @@ -264,32 +265,32 @@ function doMenuTests() { $this->clickLink(t('Add link')); $link_title = $this->randomString(); - $this->drupalPostForm(NULL, array('link[0][uri]' => '/', 'title[0][value]' => $link_title), t('Save')); + $this->drupalPostForm(NULL, ['link[0][uri]' => '/', 'title[0][value]' => $link_title], t('Save')); $this->assertUrl(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); // Test the 'Edit' operation. $this->clickLink(t('Edit')); $this->assertFieldByName('title[0][value]', $link_title); $link_title = $this->randomString(); - $this->drupalPostForm(NULL, array('title[0][value]' => $link_title), t('Save')); + $this->drupalPostForm(NULL, ['title[0][value]' => $link_title], t('Save')); $this->assertUrl(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); // Test the 'Delete' operation. $this->clickLink(t('Delete')); - $this->assertRaw(t('Are you sure you want to delete the custom menu link %item?', array('%item' => $link_title))); - $this->drupalPostForm(NULL, array(), t('Delete')); + $this->assertRaw(t('Are you sure you want to delete the custom menu link %item?', ['%item' => $link_title])); + $this->drupalPostForm(NULL, [], t('Delete')); $this->assertUrl(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); // Add nodes to use as links for menu links. - $node1 = $this->drupalCreateNode(array('type' => 'article')); - $node2 = $this->drupalCreateNode(array('type' => 'article')); - $node3 = $this->drupalCreateNode(array('type' => 'article')); - $node4 = $this->drupalCreateNode(array('type' => 'article')); + $node1 = $this->drupalCreateNode(['type' => 'article']); + $node2 = $this->drupalCreateNode(['type' => 'article']); + $node3 = $this->drupalCreateNode(['type' => 'article']); + $node4 = $this->drupalCreateNode(['type' => 'article']); // Create a node with an alias. - $node5 = $this->drupalCreateNode(array( + $node5 = $this->drupalCreateNode([ 'type' => 'article', - 'path' => array( + 'path' => [ 'alias' => '/node5', - ), - )); + ], + ]); // Verify add link button. $this->drupalGet('admin/structure/menu'); @@ -309,25 +310,25 @@ function doMenuTests() { // -- item2 // --- item3 - $this->assertMenuLink($item1->getPluginId(), array( - 'children' => array($item2->getPluginId(), $item3->getPluginId()), - 'parents' => array($item1->getPluginId()), + $this->assertMenuLink($item1->getPluginId(), [ + 'children' => [$item2->getPluginId(), $item3->getPluginId()], + 'parents' => [$item1->getPluginId()], // We assert the language code here to make sure that the language // selection element degrades gracefully without the Language module. 'langcode' => 'en', - )); - $this->assertMenuLink($item2->getPluginId(), array( - 'children' => array($item3->getPluginId()), - 'parents' => array($item2->getPluginId(), $item1->getPluginId()), + ]); + $this->assertMenuLink($item2->getPluginId(), [ + 'children' => [$item3->getPluginId()], + 'parents' => [$item2->getPluginId(), $item1->getPluginId()], // See above. 'langcode' => 'en', - )); - $this->assertMenuLink($item3->getPluginId(), array( - 'children' => array(), - 'parents' => array($item3->getPluginId(), $item2->getPluginId(), $item1->getPluginId()), + ]); + $this->assertMenuLink($item3->getPluginId(), [ + 'children' => [], + 'parents' => [$item3->getPluginId(), $item2->getPluginId(), $item1->getPluginId()], // See above. 'langcode' => 'en', - )); + ]); // Verify menu links. $this->verifyMenuLink($item1, $node1); @@ -349,26 +350,26 @@ function doMenuTests() { // -- item5 // -- item6 - $this->assertMenuLink($item4->getPluginId(), array( - 'children' => array($item5->getPluginId(), $item6->getPluginId()), - 'parents' => array($item4->getPluginId()), + $this->assertMenuLink($item4->getPluginId(), [ + 'children' => [$item5->getPluginId(), $item6->getPluginId()], + 'parents' => [$item4->getPluginId()], // See above. 'langcode' => 'en', - )); - $this->assertMenuLink($item5->getPluginId(), array( - 'children' => array(), - 'parents' => array($item5->getPluginId(), $item4->getPluginId()), + ]); + $this->assertMenuLink($item5->getPluginId(), [ + 'children' => [], + 'parents' => [$item5->getPluginId(), $item4->getPluginId()], 'langcode' => 'en', - )); - $this->assertMenuLink($item6->getPluginId(), array( - 'children' => array(), - 'parents' => array($item6->getPluginId(), $item4->getPluginId()), + ]); + $this->assertMenuLink($item6->getPluginId(), [ + 'children' => [], + 'parents' => [$item6->getPluginId(), $item4->getPluginId()], 'route_name' => 'entity.node.canonical', - 'route_parameters' => array('node' => $node5->id()), + 'route_parameters' => ['node' => $node5->id()], 'url' => '', // See above. 'langcode' => 'en', - )); + ]); // Modify menu links. $this->modifyMenuLink($item1); @@ -389,49 +390,49 @@ function doMenuTests() { // ---- item3 // -- item6 - $this->assertMenuLink($item1->getPluginId(), array( - 'children' => array(), - 'parents' => array($item1->getPluginId()), + $this->assertMenuLink($item1->getPluginId(), [ + 'children' => [], + 'parents' => [$item1->getPluginId()], // See above. 'langcode' => 'en', - )); - $this->assertMenuLink($item4->getPluginId(), array( - 'children' => array($item5->getPluginId(), $item6->getPluginId(), $item2->getPluginId(), $item3->getPluginId()), - 'parents' => array($item4->getPluginId()), + ]); + $this->assertMenuLink($item4->getPluginId(), [ + 'children' => [$item5->getPluginId(), $item6->getPluginId(), $item2->getPluginId(), $item3->getPluginId()], + 'parents' => [$item4->getPluginId()], // See above. 'langcode' => 'en', - )); + ]); - $this->assertMenuLink($item5->getPluginId(), array( - 'children' => array($item2->getPluginId(), $item3->getPluginId()), - 'parents' => array($item5->getPluginId(), $item4->getPluginId()), + $this->assertMenuLink($item5->getPluginId(), [ + 'children' => [$item2->getPluginId(), $item3->getPluginId()], + 'parents' => [$item5->getPluginId(), $item4->getPluginId()], // See above. 'langcode' => 'en', - )); - $this->assertMenuLink($item2->getPluginId(), array( - 'children' => array($item3->getPluginId()), - 'parents' => array($item2->getPluginId(), $item5->getPluginId(), $item4->getPluginId()), + ]); + $this->assertMenuLink($item2->getPluginId(), [ + 'children' => [$item3->getPluginId()], + 'parents' => [$item2->getPluginId(), $item5->getPluginId(), $item4->getPluginId()], // See above. 'langcode' => 'en', - )); - $this->assertMenuLink($item3->getPluginId(), array( - 'children' => array(), - 'parents' => array($item3->getPluginId(), $item2->getPluginId(), $item5->getPluginId(), $item4->getPluginId()), + ]); + $this->assertMenuLink($item3->getPluginId(), [ + 'children' => [], + 'parents' => [$item3->getPluginId(), $item2->getPluginId(), $item5->getPluginId(), $item4->getPluginId()], // See above. 'langcode' => 'en', - )); + ]); // Add 102 menu links with increasing weights, then make sure the last-added // item's weight doesn't get changed because of the old hardcoded delta=50. - $items = array(); + $items = []; for ($i = -50; $i <= 51; $i++) { $items[$i] = $this->addMenuLink('', '/node/' . $node1->id(), $menu_name, TRUE, strval($i)); } - $this->assertMenuLink($items[51]->getPluginId(), array('weight' => '51')); + $this->assertMenuLink($items[51]->getPluginId(), ['weight' => '51']); // Disable a link and then re-enable the link via the overview form. $this->disableMenuLink($item1); - $edit = array(); + $edit = []; $edit['links[menu_plugin_id:' . $item1->getPluginId() . '][enabled]'] = TRUE; $this->drupalPostForm('admin/structure/menu/manage/' . $item1->getMenuName(), $edit, t('Save')); @@ -445,15 +446,15 @@ function doMenuTests() { $item5->save(); // Verify in the database. - $this->assertMenuLink($item1->getPluginId(), array('enabled' => 1)); + $this->assertMenuLink($item1->getPluginId(), ['enabled' => 1]); // Add an external link. $item7 = $this->addMenuLink('', 'https://www.drupal.org', $menu_name); - $this->assertMenuLink($item7->getPluginId(), array('url' => 'https://www.drupal.org')); + $this->assertMenuLink($item7->getPluginId(), ['url' => 'https://www.drupal.org']); // Add menu item. $item8 = $this->addMenuLink('', '/', $menu_name); - $this->assertMenuLink($item8->getPluginId(), array('route_name' => '')); + $this->assertMenuLink($item8->getPluginId(), ['route_name' => '']); $this->drupalGet(''); $this->assertResponse(200); // Make sure we get routed correctly. @@ -488,7 +489,7 @@ protected function doMenuLinkFormDefaultsTest() { /** * Adds and removes a menu link with a query string and fragment. */ - function testMenuQueryAndFragment() { + public function testMenuQueryAndFragment() { $this->drupalLogin($this->adminUser); // Make a path with query and fragment on. @@ -500,7 +501,7 @@ function testMenuQueryAndFragment() { // Now change the path to something without query and fragment. $path = '/test-page'; - $this->drupalPostForm('admin/structure/menu/item/' . $item->id() . '/edit', array('link[0][uri]' => $path), t('Save')); + $this->drupalPostForm('admin/structure/menu/item/' . $item->id() . '/edit', ['link[0][uri]' => $path], t('Save')); $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); $this->assertFieldByName('link[0][uri]', $path, 'Path no longer has query or fragment.'); @@ -511,7 +512,7 @@ function testMenuQueryAndFragment() { $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); $this->assertFieldByName('link[0][uri]', $path, 'Path is found with both query and fragment.'); - $this->drupalPostForm('admin/structure/menu/item/' . $item->id() . '/edit', array(), t('Save')); + $this->drupalPostForm('admin/structure/menu/item/' . $item->id() . '/edit', [], t('Save')); $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); $this->assertFieldByName('link[0][uri]', $path, 'Path is found with both query and fragment.'); @@ -520,11 +521,11 @@ function testMenuQueryAndFragment() { /** * Tests renaming the built-in menu. */ - function testSystemMenuRename() { + public function testSystemMenuRename() { $this->drupalLogin($this->adminUser); - $edit = array( + $edit = [ 'label' => $this->randomMachineName(16), - ); + ]; $this->drupalPostForm('admin/structure/menu/manage/main', $edit, t('Save')); // Make sure menu shows up with new name in block addition. @@ -537,13 +538,13 @@ function testSystemMenuRename() { /** * Tests that menu items pointing to unpublished nodes are editable. */ - function testUnpublishedNodeMenuItem() { - $this->drupalLogin($this->drupalCreateUser(array('access administration pages', 'administer blocks', 'administer menu', 'create article content', 'bypass node access'))); + public function testUnpublishedNodeMenuItem() { + $this->drupalLogin($this->drupalCreateUser(['access administration pages', 'administer blocks', 'administer menu', 'create article content', 'bypass node access'])); // Create an unpublished node. - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'type' => 'article', - 'status' => NODE_NOT_PUBLISHED, - )); + 'status' => NodeInterface::NOT_PUBLISHED, + ]); $item = $this->addMenuLink('', '/node/' . $node->id()); $this->modifyMenuLink($item); @@ -563,20 +564,20 @@ function testUnpublishedNodeMenuItem() { * Tests the contextual links on a menu block. */ public function testBlockContextualLinks() { - $this->drupalLogin($this->drupalCreateUser(array('administer menu', 'access contextual links', 'administer blocks'))); + $this->drupalLogin($this->drupalCreateUser(['administer menu', 'access contextual links', 'administer blocks'])); $custom_menu = $this->addCustomMenu(); $this->addMenuLink('', '/', $custom_menu->id()); - $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), array('label' => 'Custom menu', 'provider' => 'system')); + $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), ['label' => 'Custom menu', 'provider' => 'system']); $this->drupalGet('test-page'); $id = 'block:block=' . $block->id() . ':langcode=en|menu:menu=' . $custom_menu->id() . ':langcode=en'; // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() - $this->assertRaw('
    ', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); + $this->assertRaw('
    ', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id])); // Get server-rendered contextual links. // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks() - $post = array('ids[0]' => $id); - $response = $this->drupalPost('contextual/render', 'application/json', $post, array('query' => array('destination' => 'test-page'))); + $post = ['ids[0]' => $id]; + $response = $this->drupalPost('contextual/render', 'application/json', $post, ['query' => ['destination' => 'test-page']]); $this->assertResponse(200); $json = Json::decode($response); $this->assertIdentical($json[$id], ''); @@ -601,13 +602,13 @@ public function testBlockContextualLinks() { * @return \Drupal\menu_link_content\Entity\MenuLinkContent * A menu link entity. */ - function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded = FALSE, $weight = '0') { + public function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded = FALSE, $weight = '0') { // View add menu link page. $this->drupalGet("admin/structure/menu/manage/$menu_name/add"); $this->assertResponse(200); $title = '!link_' . $this->randomMachineName(16); - $edit = array( + $edit = [ 'link[0][uri]' => $path, 'title[0][value]' => $title, 'description[0][value]' => '', @@ -615,18 +616,18 @@ function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded 'expanded[value]' => $expanded, 'menu_parent' => $menu_name . ':' . $parent, 'weight[0][value]' => $weight, - ); + ]; // Add menu link. $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertResponse(200); $this->assertText('The menu link has been saved.'); - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $title)); + $menu_links = entity_load_multiple_by_properties('menu_link_content', ['title' => $title]); $menu_link = reset($menu_links); $this->assertTrue($menu_link, 'Menu link was found in database.'); - $this->assertMenuLink($menu_link->getPluginId(), array('menu_name' => $menu_name, 'children' => array(), 'parent' => $parent)); + $this->assertMenuLink($menu_link->getPluginId(), ['menu_name' => $menu_name, 'children' => [], 'parent' => $parent]); return $menu_link; } @@ -634,23 +635,23 @@ function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded /** * Attempts to add menu link with invalid path or no access permission. */ - function addInvalidMenuLink() { - foreach (array('access' => '/admin/people/permissions') as $type => $link_path) { - $edit = array( + public function addInvalidMenuLink() { + foreach (['access' => '/admin/people/permissions'] as $type => $link_path) { + $edit = [ 'link[0][uri]' => $link_path, 'title[0][value]' => 'title', - ); + ]; $this->drupalPostForm("admin/structure/menu/manage/{$this->menu->id()}/add", $edit, t('Save')); - $this->assertRaw(t("The path '@link_path' is inaccessible.", array('@link_path' => $link_path)), 'Menu link was not created'); + $this->assertRaw(t("The path '@link_path' is inaccessible.", ['@link_path' => $link_path]), 'Menu link was not created'); } } /** * Tests that parent options are limited by depth when adding menu links. */ - function checkInvalidParentMenuLinks() { + public function checkInvalidParentMenuLinks() { $last_link = NULL; - $created_links = array(); + $created_links = []; // Get the max depth of the tree. $menu_link_tree = \Drupal::service('menu.link_tree'); @@ -660,7 +661,7 @@ function checkInvalidParentMenuLinks() { for ($i = 0; $i <= $max_depth - 1; $i++) { $parent = $last_link ? 'tools:' . $last_link->getPluginId() : 'tools:'; $title = 'title' . $i; - $edit = array( + $edit = [ 'link[0][uri]' => '/', 'title[0][value]' => $title, 'menu_parent' => $parent, @@ -668,9 +669,9 @@ function checkInvalidParentMenuLinks() { 'enabled[value]' => 1, 'expanded[value]' => FALSE, 'weight[0][value]' => '0', - ); + ]; $this->drupalPostForm("admin/structure/menu/manage/{$this->menu->id()}/add", $edit, t('Save')); - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $title)); + $menu_links = entity_load_multiple_by_properties('menu_link_content', ['title' => $title]); $last_link = reset($menu_links); $created_links[] = 'tools:' . $last_link->getPluginId(); } @@ -699,7 +700,7 @@ function checkInvalidParentMenuLinks() { * @param object $parent_node * Parent menu link content node. */ - function verifyMenuLink(MenuLinkContent $item, $item_node, MenuLinkContent $parent = NULL, $parent_node = NULL) { + public function verifyMenuLink(MenuLinkContent $item, $item_node, MenuLinkContent $parent = NULL, $parent_node = NULL) { // View home page. $this->drupalGet(''); $this->assertResponse(200); @@ -713,7 +714,7 @@ function verifyMenuLink(MenuLinkContent $item, $item_node, MenuLinkContent $pare // Verify menu link link. $this->clickLink($title); $title = $parent_node->label(); - $this->assertTitle(t("@title | Drupal", array('@title' => $title)), 'Parent menu link link target was correct'); + $this->assertTitle(t("@title | Drupal", ['@title' => $title]), 'Parent menu link link target was correct'); } // Verify menu link. @@ -723,7 +724,7 @@ function verifyMenuLink(MenuLinkContent $item, $item_node, MenuLinkContent $pare // Verify menu link link. $this->clickLink($title); $title = $item_node->label(); - $this->assertTitle(t("@title | Drupal", array('@title' => $title)), 'Menu link link target was correct'); + $this->assertTitle(t("@title | Drupal", ['@title' => $title]), 'Menu link link target was correct'); } /** @@ -736,12 +737,12 @@ function verifyMenuLink(MenuLinkContent $item, $item_node, MenuLinkContent $pare * @param string $menu_name * The menu the menu link will be moved to. */ - function moveMenuLink(MenuLinkContent $item, $parent, $menu_name) { + public function moveMenuLink(MenuLinkContent $item, $parent, $menu_name) { $mlid = $item->id(); - $edit = array( + $edit = [ 'menu_parent' => $menu_name . ':' . $parent, - ); + ]; $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); $this->assertResponse(200); } @@ -752,14 +753,14 @@ function moveMenuLink(MenuLinkContent $item, $parent, $menu_name) { * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item * Menu link entity. */ - function modifyMenuLink(MenuLinkContent $item) { + public function modifyMenuLink(MenuLinkContent $item) { $item->title->value = $this->randomMachineName(16); $mlid = $item->id(); $title = $item->getTitle(); // Edit menu link. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $title; $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); $this->assertResponse(200); @@ -777,9 +778,9 @@ function modifyMenuLink(MenuLinkContent $item) { * @param int $old_weight * Original title for menu link. */ - function resetMenuLink(MenuLinkInterface $menu_link, $old_weight) { + public function resetMenuLink(MenuLinkInterface $menu_link, $old_weight) { // Reset menu link. - $this->drupalPostForm("admin/structure/menu/link/{$menu_link->getPluginId()}/reset", array(), t('Reset')); + $this->drupalPostForm("admin/structure/menu/link/{$menu_link->getPluginId()}/reset", [], t('Reset')); $this->assertResponse(200); $this->assertRaw(t('The menu link was reset to its default settings.'), 'Menu link was reset'); @@ -794,14 +795,14 @@ function resetMenuLink(MenuLinkInterface $menu_link, $old_weight) { * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item * Menu link. */ - function deleteMenuLink(MenuLinkContent $item) { + public function deleteMenuLink(MenuLinkContent $item) { $mlid = $item->id(); $title = $item->getTitle(); // Delete menu link. - $this->drupalPostForm("admin/structure/menu/item/$mlid/delete", array(), t('Delete')); + $this->drupalPostForm("admin/structure/menu/item/$mlid/delete", [], t('Delete')); $this->assertResponse(200); - $this->assertRaw(t('The menu link %title has been deleted.', array('%title' => $title)), 'Menu link was deleted'); + $this->assertRaw(t('The menu link %title has been deleted.', ['%title' => $title]), 'Menu link was deleted'); // Verify deletion. $this->drupalGet(''); @@ -814,7 +815,7 @@ function deleteMenuLink(MenuLinkContent $item) { * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item * Menu link. */ - function toggleMenuLink(MenuLinkContent $item) { + public function toggleMenuLink(MenuLinkContent $item) { $this->disableMenuLink($item); // Verify menu link is absent. @@ -833,14 +834,14 @@ function toggleMenuLink(MenuLinkContent $item) { * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item * Menu link. */ - function disableMenuLink(MenuLinkContent $item) { + public function disableMenuLink(MenuLinkContent $item) { $mlid = $item->id(); $edit['enabled[value]'] = FALSE; $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); // Unlike most other modules, there is no confirmation message displayed. // Verify in the database. - $this->assertMenuLink($item->getPluginId(), array('enabled' => 0)); + $this->assertMenuLink($item->getPluginId(), ['enabled' => 0]); } /** @@ -849,13 +850,13 @@ function disableMenuLink(MenuLinkContent $item) { * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item * Menu link. */ - function enableMenuLink(MenuLinkContent $item) { + public function enableMenuLink(MenuLinkContent $item) { $mlid = $item->id(); $edit['enabled[value]'] = TRUE; $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); // Verify in the database. - $this->assertMenuLink($item->getPluginId(), array('enabled' => 1)); + $this->assertMenuLink($item->getPluginId(), ['enabled' => 1]); } /** @@ -863,7 +864,7 @@ function enableMenuLink(MenuLinkContent $item) { * AJAX callback. */ public function testMenuParentsJsAccess() { - $admin = $this->drupalCreateUser(array('administer menu')); + $admin = $this->drupalCreateUser(['administer menu']); $this->drupalLogin($admin); // Just check access to the callback overall, the POST data is irrelevant. $this->drupalGetAjax('admin/structure/menu/parents'); diff --git a/core/modules/menu_ui/src/Tests/MenuUninstallTest.php b/core/modules/menu_ui/src/Tests/MenuUninstallTest.php deleted file mode 100644 index b1ea03c4..00000000 --- a/core/modules/menu_ui/src/Tests/MenuUninstallTest.php +++ /dev/null @@ -1,33 +0,0 @@ -uninstall(array('menu_ui')); - - \Drupal::entityManager()->getStorage('menu')->resetCache(array('admin')); - - $this->assertTrue(Menu::load('admin'), 'The \'admin\' menu still exists after uninstalling Menu UI module.'); - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuWebTestBase.php b/core/modules/menu_ui/src/Tests/MenuWebTestBase.php index c08fc142..e0ee98fb 100644 --- a/core/modules/menu_ui/src/Tests/MenuWebTestBase.php +++ b/core/modules/menu_ui/src/Tests/MenuWebTestBase.php @@ -14,7 +14,7 @@ abstract class MenuWebTestBase extends WebTestBase { * * @var array */ - public static $modules = array('menu_ui', 'menu_link_content'); + public static $modules = ['menu_ui', 'menu_link_content']; /** * Fetches the menu item from the database and compares it to expected item. @@ -24,7 +24,7 @@ abstract class MenuWebTestBase extends WebTestBase { * @param array $expected_item * Array containing properties to verify. */ - function assertMenuLink($menu_plugin_id, array $expected_item) { + public function assertMenuLink($menu_plugin_id, array $expected_item) { // Retrieve menu link. /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); diff --git a/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php b/core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php similarity index 86% rename from core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php rename to core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php index 3ad4ad1d..0b08ebd9 100644 --- a/core/modules/menu_ui/src/Tests/MenuCacheTagsTest.php +++ b/core/modules/menu_ui/tests/src/Functional/MenuCacheTagsTest.php @@ -1,6 +1,6 @@ 'llama', 'label' => 'Llama', 'description' => 'Description text', - )); + ]); $menu->save(); /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); // Move a link into the new menu. - $menu_link = $menu_link_manager->updateDefinition('test_page_test.test_page', array('menu_name' => 'llama', 'parent' => '')); - $block = $this->drupalPlaceBlock('system_menu_block:llama', array('label' => 'Llama', 'provider' => 'system', 'region' => 'footer')); + $menu_link = $menu_link_manager->updateDefinition('test_page_test.test_page', ['menu_name' => 'llama', 'parent' => '']); + $block = $this->drupalPlaceBlock('system_menu_block:llama', ['label' => 'Llama', 'provider' => 'system', 'region' => 'footer']); // Prime the page cache. $this->verifyPageCache($url, 'MISS'); // Verify a cache hit, but also the presence of the correct cache tags. - $expected_tags = array( + $expected_tags = [ + 'http_response', 'rendered', 'block_view', 'config:block_list', @@ -54,7 +55,7 @@ public function testMenuBlock() { // The cache contexts associated with the (in)accessible menu links are // bubbled. 'config:user.role.anonymous', - ); + ]; $this->verifyPageCache($url, 'HIT', $expected_tags); // Verify that after modifying the menu, there is a cache miss. @@ -67,7 +68,7 @@ public function testMenuBlock() { $this->verifyPageCache($url, 'HIT'); // Verify that after modifying the menu link weight, there is a cache miss. - $menu_link_manager->updateDefinition('test_page_test.test_page', array('weight' => -10)); + $menu_link_manager->updateDefinition('test_page_test.test_page', ['weight' => -10]); $this->pass('Test modification of menu link.', 'Debug'); $this->verifyPageCache($url, 'MISS'); @@ -76,16 +77,16 @@ public function testMenuBlock() { // Verify that after adding a menu link, there is a cache miss. $this->pass('Test addition of menu link.', 'Debug'); - $menu_link_2 = MenuLinkContent::create(array( + $menu_link_2 = MenuLinkContent::create([ 'id' => '', 'parent' => '', 'title' => 'Alpaca', 'menu_name' => 'llama', - 'link' => [[ - 'uri' => 'internal:/', - ]], + 'link' => [ + ['uri' => 'internal:/'], + ], 'bundle' => 'menu_name', - )); + ]); $menu_link_2->save(); $this->verifyPageCache($url, 'MISS'); @@ -107,7 +108,7 @@ public function testMenuBlock() { $this->verifyPageCache($url, 'MISS'); // Verify a cache hit. - $this->verifyPageCache($url, 'HIT', ['config:block_list', 'config:user.role.anonymous', 'rendered']); + $this->verifyPageCache($url, 'HIT', ['config:block_list', 'config:user.role.anonymous', 'http_response', 'rendered']); } } diff --git a/core/modules/menu_ui/src/Tests/MenuLinkReorderTest.php b/core/modules/menu_ui/tests/src/Functional/MenuLinkReorderTest.php similarity index 79% rename from core/modules/menu_ui/src/Tests/MenuLinkReorderTest.php rename to core/modules/menu_ui/tests/src/Functional/MenuLinkReorderTest.php index 0396f173..4d2bba60 100644 --- a/core/modules/menu_ui/src/Tests/MenuLinkReorderTest.php +++ b/core/modules/menu_ui/tests/src/Functional/MenuLinkReorderTest.php @@ -1,15 +1,15 @@ drupalPlaceBlock('system_menu_block:main'); @@ -38,17 +38,17 @@ function testDefaultMenuLinkReorder() { $this->assertLink('Home'); // The administrator user that can re-order menu links. - $this->administrator = $this->drupalCreateUser(array( + $this->administrator = $this->drupalCreateUser([ 'administer site configuration', 'access administration pages', 'administer menu', - )); + ]); $this->drupalLogin($this->administrator); // Change the weight of the link to a non default value. - $edit = array( + $edit = [ 'links[menu_plugin_id:test_page_test.front_page][weight]' => -10, - ); + ]; $this->drupalPostForm('admin/structure/menu/manage/main', $edit, t('Save')); // The link is still there. diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php new file mode 100644 index 00000000..be018f4c --- /dev/null +++ b/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php @@ -0,0 +1,164 @@ +drupalPlaceBlock('system_menu_block:main'); + + // Create a 'page' content type. + $this->drupalCreateContentType([ + 'type' => 'page', + 'name' => 'Basic page', + 'display_submitted' => FALSE, + ]); + + $workflow = Workflow::load('editorial'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page'); + $workflow->save(); + } + + /** + * Tests that node drafts can not modify the menu settings. + */ + public function testMenuUiWithPendingRevisions() { + $editor = $this->drupalCreateUser([ + 'administer nodes', + 'administer menu', + 'create page content', + 'edit any page content', + 'use editorial transition create_new_draft', + 'use editorial transition publish', + 'view latest version', + 'view any unpublished content', + ]); + $this->drupalLogin($editor); + + // Create a node. + $node = $this->drupalCreateNode(); + + // Publish the node with no changes. + $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save')); + $this->assertSession()->responseContains(t('Page %label has been updated.', ['%label' => $node->toLink($node->label())->toString()])); + + // Create a pending revision with no changes. + $edit = ['moderation_state[0][state]' => 'draft']; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + $this->assertSession()->responseContains(t('Page %label has been updated.', ['%label' => $node->toLink($node->label())->toString()])); + + // Add a menu link and save a new default (published) revision. + $edit = [ + 'menu[enabled]' => 1, + 'menu[title]' => 'Test menu link', + 'moderation_state[0][state]' => 'published', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + $this->assertSession()->linkExists('Test menu link'); + + // Try to change the menu link title and save a new non-default (draft) + // revision. + $edit = [ + 'menu[title]' => 'Test menu link draft', + 'moderation_state[0][state]' => 'draft', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + // Check that the menu settings were not applied. + $this->assertSession()->pageTextContains('You can only change the menu settings for the published version of this content.'); + $this->assertSession()->linkExists('Test menu link'); + $this->assertSession()->linkNotExists('Test menu link draft'); + + // Try to change the menu link description and save a new non-default + // (draft) revision. + $edit = [ + 'menu[description]' => 'Test menu link description', + 'moderation_state[0][state]' => 'draft', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + // Check that the menu settings were not applied. + $this->assertSession()->pageTextContains('You can only change the menu settings for the published version of this content.'); + + // Try to change the menu link weight and save a new non-default (draft) + // revision. + $edit = [ + 'menu[weight]' => 1, + 'moderation_state[0][state]' => 'draft', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + // Check that the menu settings were not applied. + $this->assertSession()->pageTextContains('You can only change the menu settings for the published version of this content.'); + + // Try to change the menu link parent and save a new non-default (draft) + // revision. + $edit = [ + 'menu[menu_parent]' => 'main:test_page_test.front_page', + 'moderation_state[0][state]' => 'draft', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + // Check that the menu settings were not applied. + $this->assertSession()->pageTextContains('You can only change the menu settings for the published version of this content.'); + + // Try to delete the menu link and save a new non-default (draft) revision. + $edit = [ + 'menu[enabled]' => 0, + 'moderation_state[0][state]' => 'draft', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + // Check that the menu settings were not applied. + $this->assertSession()->pageTextContains('You can only change the menu settings for the published version of this content.'); + $this->assertSession()->linkExists('Test menu link'); + + // Try to save a new non-default (draft) revision without any changes and + // check that the error message is not shown. + $edit = ['moderation_state[0][state]' => 'draft']; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + + // Check that the menu settings were not applied. + $this->assertSession()->pageTextNotContains('You can only change the menu settings for the published version of this content.'); + $this->assertSession()->linkExists('Test menu link'); + + // Create a node. + $node = $this->drupalCreateNode(); + + // Publish the node with no changes. + $edit = ['moderation_state[0][state]' => 'published']; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + $this->assertSession()->responseContains(t('Page %label has been updated.', ['%label' => $node->toLink($node->label())->toString()])); + + // Add a menu link and save and create a new non-default (draft) revision. + $edit = [ + 'menu[enabled]' => 1, + 'menu[title]' => 'Test menu link', + 'moderation_state[0][state]' => 'draft', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + $this->assertSession()->pageTextContains('You can only change the menu settings for the published version of this content.'); + } + +} diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUninstallTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUninstallTest.php new file mode 100644 index 00000000..a0320f44 --- /dev/null +++ b/core/modules/menu_ui/tests/src/Functional/MenuUninstallTest.php @@ -0,0 +1,33 @@ +uninstall(['menu_ui']); + + \Drupal::entityManager()->getStorage('menu')->resetCache(['admin']); + + $this->assertTrue(Menu::load('admin'), 'The \'admin\' menu still exists after uninstalling Menu UI module.'); + } + +} diff --git a/core/modules/menu_ui/tests/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php b/core/modules/menu_ui/tests/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php deleted file mode 100644 index f87bc5fe..00000000 --- a/core/modules/menu_ui/tests/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php +++ /dev/null @@ -1,29 +0,0 @@ -installConfig(['menu_ui']); - $this->executeMigration('menu_settings'); - } - - public function testMigration() { - $this->assertTrue(\Drupal::config('menu_ui.settings')->get('override_parent_selector')); - } - -} diff --git a/core/modules/migrate/migrate.api.php b/core/modules/migrate/migrate.api.php index aea0d77c..eefda3c3 100644 --- a/core/modules/migrate/migrate.api.php +++ b/core/modules/migrate/migrate.api.php @@ -103,7 +103,7 @@ */ function hook_migrate_prepare_row(Row $row, MigrateSourceInterface $source, MigrationInterface $migration) { if ($migration->id() == 'd6_filter_formats') { - $value = $source->getDatabase()->query('SELECT value FROM {variable} WHERE name = :name', array(':name' => 'mymodule_filter_foo_' . $row->getSourceProperty('format')))->fetchField(); + $value = $source->getDatabase()->query('SELECT value FROM {variable} WHERE name = :name', [':name' => 'mymodule_filter_foo_' . $row->getSourceProperty('format')])->fetchField(); if ($value) { $row->setSourceProperty('settings:mymodule:foo', unserialize($value)); } diff --git a/core/modules/migrate/migrate.info.yml b/core/modules/migrate/migrate.info.yml index b5b96ea6..1025e6ca 100644 --- a/core/modules/migrate/migrate.info.yml +++ b/core/modules/migrate/migrate.info.yml @@ -5,8 +5,8 @@ package: Core (Experimental) # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate/migrate.install b/core/modules/migrate/migrate.install index 5044726a..064b95ad 100644 --- a/core/modules/migrate/migrate.install +++ b/core/modules/migrate/migrate.install @@ -5,11 +5,6 @@ * Contains install and update functions for Migrate. */ -/** - * @addtogroup updates-8.0.0-beta - * @{ - */ - /** * Remove load plugin references from existing migrations. */ @@ -21,7 +16,3 @@ function migrate_update_8001() { $migration->save(TRUE); } } - -/** - * @} End of "addtogroup updates-8.0.0-beta". - */ diff --git a/core/modules/migrate/migrate.module b/core/modules/migrate/migrate.module index 9cec273c..3b924639 100644 --- a/core/modules/migrate/migrate.module +++ b/core/modules/migrate/migrate.module @@ -15,7 +15,7 @@ function migrate_help($route_name, RouteMatchInterface $route_match) { case 'help.page.migrate': $output = '

    ' . t('About') . '

    '; $output .= '

    '; - $output .= t('The Migrate module provides a framework for migrating data, usually from an external source into your site. It does not provide a user interface. For more information, see the online documentation for the Migrate module.', array(':migrate' => 'https://www.drupal.org/documentation/modules/migrate')); + $output .= t('The Migrate module provides a framework for migrating data, usually from an external source into your site. It does not provide a user interface. For more information, see the online documentation for the Migrate module.', [':migrate' => 'https://www.drupal.org/documentation/modules/migrate']); $output .= '

    '; return $output; } diff --git a/core/modules/migrate/migrate.services.yml b/core/modules/migrate/migrate.services.yml index 9273ac32..1a4f64d2 100644 --- a/core/modules/migrate/migrate.services.yml +++ b/core/modules/migrate/migrate.services.yml @@ -21,6 +21,12 @@ services: plugin.manager.migrate.id_map: class: Drupal\migrate\Plugin\MigratePluginManager arguments: [id_map, '@container.namespaces', '@cache.discovery', '@module_handler'] + cache.discovery_migration: + class: Drupal\Core\Cache\CacheBackendInterface + tags: + - { name: cache.bin } + factory: cache_factory:get + arguments: [discovery_migration] plugin.manager.migration: class: Drupal\migrate\Plugin\MigrationPluginManager - arguments: ['@module_handler', '@cache.discovery', '@language_manager'] + arguments: ['@module_handler', '@cache.discovery_migration', '@language_manager'] diff --git a/core/modules/migrate/src/Annotation/MigrateDestination.php b/core/modules/migrate/src/Annotation/MigrateDestination.php index 1fd51d70..4342ba72 100644 --- a/core/modules/migrate/src/Annotation/MigrateDestination.php +++ b/core/modules/migrate/src/Annotation/MigrateDestination.php @@ -43,4 +43,15 @@ class MigrateDestination extends Plugin { */ public $requirements_met = TRUE; + /** + * Identifies the system handling the data the destination plugin will write. + * + * The destination plugin itself determines how the value is used. For + * example, Migrate Drupal's destination plugins expect destination_module to + * be the name of a module that must be installed on the destination. + * + * @var string + */ + public $destination_module; + } diff --git a/core/modules/migrate/src/Annotation/MigrateSource.php b/core/modules/migrate/src/Annotation/MigrateSource.php index 95a24315..8445ca01 100644 --- a/core/modules/migrate/src/Annotation/MigrateSource.php +++ b/core/modules/migrate/src/Annotation/MigrateSource.php @@ -43,16 +43,15 @@ class MigrateSource extends Plugin implements MultipleProviderAnnotationInterfac /** * Identifies the system providing the data the source plugin will read. * - * This can be any type, and the source plugin itself determines how the value - * is used. For example, Migrate Drupal's source plugins expect - * source_provider to be the name of a module that must be installed and - * enabled in the source database. + * The source plugin itself determines how the value is used. For example, + * Migrate Drupal's source plugins expect source_module to be the name of a + * module that must be installed and enabled in the source database. * * @see \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase::checkRequirements * - * @var mixed + * @var string */ - public $source_provider; + public $source_module; /** * Specifies the minimum version of the source provider. @@ -60,7 +59,7 @@ class MigrateSource extends Plugin implements MultipleProviderAnnotationInterfac * This can be any type, and the source plugin itself determines how it is * used. For example, Migrate Drupal's source plugins expect this to be an * integer representing the minimum installed database schema version of the - * module specified by source_provider. + * module specified by source_module. * * @var mixed */ diff --git a/core/modules/migrate/src/Exception/RequirementsException.php b/core/modules/migrate/src/Exception/RequirementsException.php index 4c17dd61..93da7ee4 100644 --- a/core/modules/migrate/src/Exception/RequirementsException.php +++ b/core/modules/migrate/src/Exception/RequirementsException.php @@ -56,7 +56,7 @@ public function getRequirementsString() { $output = ''; foreach ($this->requirements as $requirement_type => $requirements) { if (!is_array($requirements)) { - $requirements = array($requirements); + $requirements = [$requirements]; } foreach ($requirements as $value) { diff --git a/core/modules/migrate/src/MigrateBuildDependencyInterface.php b/core/modules/migrate/src/MigrateBuildDependencyInterface.php index bb02c888..d5a900d7 100644 --- a/core/modules/migrate/src/MigrateBuildDependencyInterface.php +++ b/core/modules/migrate/src/MigrateBuildDependencyInterface.php @@ -2,7 +2,6 @@ namespace Drupal\migrate; - interface MigrateBuildDependencyInterface { /** diff --git a/core/modules/migrate/src/MigrateExecutable.php b/core/modules/migrate/src/MigrateExecutable.php index ff05dfec..01f33c28 100644 --- a/core/modules/migrate/src/MigrateExecutable.php +++ b/core/modules/migrate/src/MigrateExecutable.php @@ -65,7 +65,7 @@ class MigrateExecutable implements MigrateExecutableInterface { * * @var array */ - protected $counts = array(); + protected $counts = []; /** * The source. @@ -96,7 +96,7 @@ class MigrateExecutable implements MigrateExecutableInterface { * @param \Drupal\migrate\Plugin\MigrationInterface $migration * The migration to run. * @param \Drupal\migrate\MigrateMessageInterface $message - * The message to record. + * The migrate message service. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher * The event dispatcher. * @@ -151,10 +151,10 @@ public function import() { // Only begin the import operation if the migration is currently idle. if ($this->migration->getStatus() !== MigrationInterface::STATUS_IDLE) { $this->message->display($this->t('Migration @id is busy with another operation: @status', - array( + [ '@id' => $this->migration->id(), '@status' => $this->t($this->migration->getStatusLabel()), - )), 'error'); + ]), 'error'); return MigrationInterface::RESULT_FAILED; } $this->getEventDispatcher()->dispatch(MigrateEvents::PRE_IMPORT, new MigrateImportEvent($this->migration, $this->message)); @@ -167,11 +167,11 @@ public function import() { $this->message->display( $this->t( 'Migration @id did not meet the requirements. @message @requirements', - array( + [ '@id' => $this->migration->id(), '@message' => $e->getMessage(), '@requirements' => $e->getRequirementsString(), - ) + ] ), 'error' ); @@ -189,7 +189,7 @@ public function import() { } catch (\Exception $e) { $this->message->display( - $this->t('Migration failed with source plugin exception: @e', array('@e' => $e->getMessage())), 'error'); + $this->t('Migration failed with source plugin exception: @e', ['@e' => $e->getMessage()]), 'error'); $this->migration->setStatus(MigrationInterface::STATUS_IDLE); return MigrationInterface::RESULT_FAILED; } @@ -204,7 +204,7 @@ public function import() { $save = TRUE; } catch (MigrateException $e) { - $this->migration->getIdMap()->saveIdMapping($row, array(), $e->getStatus()); + $this->migration->getIdMap()->saveIdMapping($row, [], $e->getStatus()); $this->saveMessage($e->getMessage(), $e->getLevel()); $save = FALSE; } @@ -230,7 +230,7 @@ public function import() { } } else { - $id_map->saveIdMapping($row, array(), MigrateIdMapInterface::STATUS_FAILED); + $id_map->saveIdMapping($row, [], MigrateIdMapInterface::STATUS_FAILED); if (!$id_map->messageCount()) { $message = $this->t('New object was not saved, no error provided'); $this->saveMessage($message); @@ -239,11 +239,11 @@ public function import() { } } catch (MigrateException $e) { - $this->migration->getIdMap()->saveIdMapping($row, array(), $e->getStatus()); + $this->migration->getIdMap()->saveIdMapping($row, [], $e->getStatus()); $this->saveMessage($e->getMessage(), $e->getLevel()); } catch (\Exception $e) { - $this->migration->getIdMap()->saveIdMapping($row, array(), MigrateIdMapInterface::STATUS_FAILED); + $this->migration->getIdMap()->saveIdMapping($row, [], MigrateIdMapInterface::STATUS_FAILED); $this->handleException($e); } } @@ -268,7 +268,7 @@ public function import() { catch (\Exception $e) { $this->message->display( $this->t('Migration failed with source plugin exception: @e', - array('@e' => $e->getMessage())), 'error'); + ['@e' => $e->getMessage()]), 'error'); $this->migration->setStatus(MigrationInterface::STATUS_IDLE); return MigrationInterface::RESULT_FAILED; } @@ -356,9 +356,9 @@ public function processRow(Row $row, array $process = NULL, $value = NULL) { // plugin) and in this case the current value needs to be iterated // and each scalar separately transformed. if ($multiple && !$definition['handle_multiples']) { - $new_value = array(); + $new_value = []; if (!is_array($value)) { - throw new MigrateException(sprintf('Pipeline failed for destination %s: %s got instead of an array,', $destination, $value)); + throw new MigrateException(sprintf('Pipeline failed at %s plugin for destination %s: %s received instead of an array,', $plugin->getPluginId(), $destination, $value)); } $break = FALSE; foreach ($value as $scalar_value) { @@ -386,9 +386,14 @@ public function processRow(Row $row, array $process = NULL, $value = NULL) { $multiple = $plugin->multiple(); } } - // No plugins or no value means do not set. - if ($plugins && !is_null($value)) { - $row->setDestinationProperty($destination, $value); + // Ensure all values, including nulls, are migrated. + if ($plugins) { + if (isset($value)) { + $row->setDestinationProperty($destination, $value); + } + else { + $row->setEmptyDestinationProperty($destination); + } } // Reset the value. $value = NULL; @@ -460,11 +465,11 @@ protected function memoryExceeded() { $this->message->display( $this->t( 'Memory usage is @usage (@pct% of limit @limit), reclaiming memory.', - array( + [ '@pct' => round($pct_memory * 100), '@usage' => $this->formatSize($usage), '@limit' => $this->formatSize($this->memoryLimit), - ) + ] ), 'warning' ); @@ -476,11 +481,11 @@ protected function memoryExceeded() { $this->message->display( $this->t( 'Memory usage is now @usage (@pct% of limit @limit), not enough reclaimed, starting new batch', - array( + [ '@pct' => round($pct_memory * 100), '@usage' => $this->formatSize($usage), '@limit' => $this->formatSize($this->memoryLimit), - ) + ] ), 'warning' ); @@ -490,11 +495,11 @@ protected function memoryExceeded() { $this->message->display( $this->t( 'Memory usage is now @usage (@pct% of limit @limit), reclaimed enough, continuing', - array( + [ '@pct' => round($pct_memory * 100), '@usage' => $this->formatSize($usage), '@limit' => $this->formatSize($this->memoryLimit), - ) + ] ), 'warning'); return FALSE; @@ -534,6 +539,9 @@ protected function attemptMemoryReclaim() { // @TODO: explore resetting the container. + // Run garbage collector to further reduce memory. + gc_collect_cycles(); + return memory_get_usage(); } diff --git a/core/modules/migrate/src/MigrateMessage.php b/core/modules/migrate/src/MigrateMessage.php index b3c7634b..4cc166c8 100644 --- a/core/modules/migrate/src/MigrateMessage.php +++ b/core/modules/migrate/src/MigrateMessage.php @@ -14,10 +14,10 @@ class MigrateMessage implements MigrateMessageInterface { * * @var array */ - protected $map = array( + protected $map = [ 'status' => RfcLogLevel::INFO, 'error' => RfcLogLevel::ERROR, - ); + ]; /** * {@inheritdoc} diff --git a/core/modules/migrate/src/MigrateMessageInterface.php b/core/modules/migrate/src/MigrateMessageInterface.php index 628a684f..efb30da3 100644 --- a/core/modules/migrate/src/MigrateMessageInterface.php +++ b/core/modules/migrate/src/MigrateMessageInterface.php @@ -2,7 +2,6 @@ namespace Drupal\migrate; - interface MigrateMessageInterface { /** diff --git a/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php b/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php index ef7c0b63..0babe2fc 100644 --- a/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php +++ b/core/modules/migrate/src/Plugin/Derivative/MigrateEntity.php @@ -12,7 +12,7 @@ class MigrateEntity implements ContainerDeriverInterface { * * @var array */ - protected $derivatives = array(); + protected $derivatives = []; /** * The entity definitions @@ -59,12 +59,12 @@ public function getDerivativeDefinitions($base_plugin_definition) { $class = is_subclass_of($entity_info->getClass(), 'Drupal\Core\Config\Entity\ConfigEntityInterface') ? 'Drupal\migrate\Plugin\migrate\destination\EntityConfigBase' : 'Drupal\migrate\Plugin\migrate\destination\EntityContentBase'; - $this->derivatives[$entity_type] = array( + $this->derivatives[$entity_type] = [ 'id' => "entity:$entity_type", 'class' => $class, 'requirements_met' => 1, 'provider' => $entity_info->getProvider(), - ); + ]; } return $this->derivatives; } diff --git a/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php b/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php index 2925bd42..cee3b398 100644 --- a/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php +++ b/core/modules/migrate/src/Plugin/Derivative/MigrateEntityRevision.php @@ -12,7 +12,7 @@ class MigrateEntityRevision implements ContainerDeriverInterface { * * @var array */ - protected $derivatives = array(); + protected $derivatives = []; /** * The entity definitions @@ -57,12 +57,12 @@ public function getDerivativeDefinition($derivative_id, $base_plugin_definition) public function getDerivativeDefinitions($base_plugin_definition) { foreach ($this->entityDefinitions as $entity_type => $entity_info) { if ($entity_info->getKey('revision')) { - $this->derivatives[$entity_type] = array( + $this->derivatives[$entity_type] = [ 'id' => "entity_revision:$entity_type", 'class' => 'Drupal\migrate\Plugin\migrate\destination\EntityRevision', 'requirements_met' => 1, 'provider' => $entity_info->getProvider(), - ); + ]; } } return $this->derivatives; diff --git a/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php b/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php index c102bb89..180be0a3 100644 --- a/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php +++ b/core/modules/migrate/src/Plugin/Discovery/AnnotatedClassDiscoveryAutomatedProviders.php @@ -73,7 +73,7 @@ protected function prepareAnnotationDefinition(AnnotationInterface $annotation, * {@inheritdoc} */ public function getDefinitions() { - $definitions = array(); + $definitions = []; $reader = $this->getAnnotationReader(); diff --git a/core/modules/migrate/src/Plugin/Discovery/ProviderFilterDecorator.php b/core/modules/migrate/src/Plugin/Discovery/ProviderFilterDecorator.php index 8a2dfb89..2f657119 100644 --- a/core/modules/migrate/src/Plugin/Discovery/ProviderFilterDecorator.php +++ b/core/modules/migrate/src/Plugin/Discovery/ProviderFilterDecorator.php @@ -55,7 +55,7 @@ public function __construct(DiscoveryInterface $decorated, callable $provider_ex * A callable, gets passed a provider name, should return TRUE if the * provider exists and FALSE if not. * - * @return array|\mixed[] $definitions + * @return array|\mixed[] * An array of plugin definitions. If a definition is an array and has a * provider key that provider is guaranteed to exist. */ diff --git a/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php b/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php index 9c83baf2..a42d70f4 100644 --- a/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php +++ b/core/modules/migrate/src/Plugin/MigrateDestinationInterface.php @@ -106,7 +106,7 @@ public function fields(MigrationInterface $migration = NULL); * @return mixed * The entity ID or an indication of success. */ - public function import(Row $row, array $old_destination_id_values = array()); + public function import(Row $row, array $old_destination_id_values = []); /** * Delete the specified destination object from the target Drupal. @@ -133,4 +133,12 @@ public function supportsRollback(); */ public function rollbackAction(); + /** + * Gets the destination module handling the destination data. + * + * @return string|null + * The destination module or NULL if not found. + */ + public function getDestinationModule(); + } diff --git a/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php b/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php index 74100cf4..090efd04 100644 --- a/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php +++ b/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php @@ -54,7 +54,7 @@ public function __construct($type, \Traversable $namespaces, CacheBackendInterfa * * A specific createInstance method is necessary to pass the migration on. */ - public function createInstance($plugin_id, array $configuration = array(), MigrationInterface $migration = NULL) { + public function createInstance($plugin_id, array $configuration = [], MigrationInterface $migration = NULL) { if (substr($plugin_id, 0, 7) == 'entity:' && !$this->entityManager->getDefinition(substr($plugin_id, 7), FALSE)) { $plugin_id = 'null'; } diff --git a/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php b/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php index eafac296..31322a57 100644 --- a/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php +++ b/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php @@ -213,6 +213,8 @@ public function lookupSourceID(array $destination_id_values); * * @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.x. Use * lookupDestinationIds() instead. + * + * @see https://www.drupal.org/node/2725809 */ public function lookupDestinationId(array $source_id_values); @@ -227,7 +229,7 @@ public function lookupDestinationId(array $source_id_values); * If unkeyed, the first count($source_id_values) keys will be assumed. * * @return array - * An array of arrays of destination identifier values. + * An array of arrays of destination identifier values. * * @throws \Drupal\migrate\MigrateException * Thrown when $source_id_values contains unknown keys, or is the wrong @@ -266,10 +268,10 @@ public function destroy(); public function getQualifiedMapTableName(); /** - * Sets the migrate message. + * Sets the migrate message service. * * @param \Drupal\migrate\MigrateMessageInterface $message - * The message to display. + * The migrate message service. */ public function setMessage(MigrateMessageInterface $message); diff --git a/core/modules/migrate/src/Plugin/MigratePluginManager.php b/core/modules/migrate/src/Plugin/MigratePluginManager.php index 94c59859..b3645dbd 100644 --- a/core/modules/migrate/src/Plugin/MigratePluginManager.php +++ b/core/modules/migrate/src/Plugin/MigratePluginManager.php @@ -49,7 +49,7 @@ public function __construct($type, \Traversable $namespaces, CacheBackendInterfa /** * {@inheritdoc} */ - public function createInstance($plugin_id, array $configuration = array(), MigrationInterface $migration = NULL) { + public function createInstance($plugin_id, array $configuration = [], MigrationInterface $migration = NULL) { $plugin_definition = $this->getDefinition($plugin_id); $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition); // If the plugin provides a factory method, pass the container to it. diff --git a/core/modules/migrate/src/Plugin/MigrateSourceInterface.php b/core/modules/migrate/src/Plugin/MigrateSourceInterface.php index ef1785e6..a40af2e2 100644 --- a/core/modules/migrate/src/Plugin/MigrateSourceInterface.php +++ b/core/modules/migrate/src/Plugin/MigrateSourceInterface.php @@ -100,4 +100,12 @@ public function __toString(); */ public function getIds(); + /** + * Gets the source module providing the source data. + * + * @return string|null + * The source module or NULL if not found. + */ + public function getSourceModule(); + } diff --git a/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php index 2d127502..965da5dd 100644 --- a/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php +++ b/core/modules/migrate/src/Plugin/MigrateSourcePluginManager.php @@ -12,7 +12,7 @@ * Plugin manager for migrate source plugins. * * @see \Drupal\migrate\Plugin\MigrateSourceInterface - * @see \Drupal\migrate\Plugin\source\SourcePluginBase + * @see \Drupal\migrate\Plugin\migrate\source\SourcePluginBase * @see \Drupal\migrate\Annotation\MigrateSource * @see plugin_api * diff --git a/core/modules/migrate/src/Plugin/Migration.php b/core/modules/migrate/src/Plugin/Migration.php index be79d0df..c81d4984 100644 --- a/core/modules/migrate/src/Plugin/Migration.php +++ b/core/modules/migrate/src/Plugin/Migration.php @@ -312,6 +312,8 @@ public function label() { * * @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.x. Use * more specific getters instead. + * + * @see https://www.drupal.org/node/2873795 */ public function get($property) { return isset($this->$property) ? $this->$property : NULL; @@ -346,9 +348,9 @@ public function getProcessPlugins(array $process = NULL) { } $index = serialize($process); if (!isset($this->processPlugins[$index])) { - $this->processPlugins[$index] = array(); + $this->processPlugins[$index] = []; foreach ($this->getProcessNormalized($process) as $property => $configurations) { - $this->processPlugins[$index][$property] = array(); + $this->processPlugins[$index][$property] = []; foreach ($configurations as $configuration) { if (isset($configuration['source'])) { $this->processPlugins[$index][$property][] = $this->processPluginManager->createInstance('get', $configuration, $this); @@ -376,16 +378,16 @@ public function getProcessPlugins(array $process = NULL) { * The normalized process configuration. */ protected function getProcessNormalized(array $process) { - $normalized_configurations = array(); + $normalized_configurations = []; foreach ($process as $destination => $configuration) { if (is_string($configuration)) { - $configuration = array( + $configuration = [ 'plugin' => 'get', 'source' => $configuration, - ); + ]; } if (isset($configuration['plugin'])) { - $configuration = array($configuration); + $configuration = [$configuration]; } $normalized_configurations[$destination] = $configuration; } @@ -570,7 +572,7 @@ public function setProcessOfProperty($property, $process_of_property) { */ public function mergeProcessOfProperty($property, array $process_of_property) { // If we already have a process value then merge the incoming process array - //otherwise simply set it. + // otherwise simply set it. $current_process = $this->getProcess(); if (isset($current_process[$property])) { $this->process = NestedArray::mergeDeepArray([$current_process, $this->getProcessNormalized([$property => $process_of_property])], TRUE); diff --git a/core/modules/migrate/src/Plugin/MigrationInterface.php b/core/modules/migrate/src/Plugin/MigrationInterface.php index 3165d81b..a2a7fb2d 100644 --- a/core/modules/migrate/src/Plugin/MigrationInterface.php +++ b/core/modules/migrate/src/Plugin/MigrationInterface.php @@ -153,7 +153,7 @@ public function allRowsProcessed(); /** * Set the current migration status. * - * @param int $result + * @param int $status * One of the STATUS_* constants. */ public function setStatus($status); diff --git a/core/modules/migrate/src/Plugin/MigrationPluginManager.php b/core/modules/migrate/src/Plugin/MigrationPluginManager.php index 3ea5727d..b572bb5c 100644 --- a/core/modules/migrate/src/Plugin/MigrationPluginManager.php +++ b/core/modules/migrate/src/Plugin/MigrationPluginManager.php @@ -24,9 +24,9 @@ class MigrationPluginManager extends DefaultPluginManager implements MigrationPl * * @var array */ - protected $defaults = array( + protected $defaults = [ 'class' => '\Drupal\migrate\Plugin\Migration', - ); + ]; /** * The interface the plugins should implement. @@ -55,7 +55,7 @@ class MigrationPluginManager extends DefaultPluginManager implements MigrationPl public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager) { $this->factory = new ContainerFactory($this, $this->pluginInterface); $this->alterInfo('migration_plugins'); - $this->setCacheBackend($cache_backend, 'migration_plugins', array('migration_plugins')); + $this->setCacheBackend($cache_backend, 'migration_plugins', ['migration_plugins']); $this->moduleHandler = $module_handler; } @@ -64,7 +64,7 @@ public function __construct(ModuleHandlerInterface $module_handler, CacheBackend */ protected function getDiscovery() { if (!isset($this->discovery)) { - $directories = array_map(function($directory) { + $directories = array_map(function ($directory) { return [$directory . '/migration_templates', $directory . '/migrations']; }, $this->moduleHandler->getModuleDirectories()); @@ -85,7 +85,7 @@ protected function getDiscovery() { /** * {@inheritdoc} */ - public function createInstance($plugin_id, array $configuration = array()) { + public function createInstance($plugin_id, array $configuration = []) { $instances = $this->createInstances([$plugin_id], [$plugin_id => $configuration]); return reset($instances); } @@ -93,7 +93,7 @@ public function createInstance($plugin_id, array $configuration = array()) { /** * {@inheritdoc} */ - public function createInstances($migration_id, array $configuration = array()) { + public function createInstances($migration_id, array $configuration = []) { if (empty($migration_id)) { $migration_id = array_keys($this->getDefinitions()); } @@ -125,7 +125,7 @@ public function createInstances($migration_id, array $configuration = array()) { * An array of migration objects with the given tag. */ public function createInstancesByTag($tag) { - $migrations = array_filter($this->getDefinitions(), function($migration) use ($tag) { + $migrations = array_filter($this->getDefinitions(), function ($migration) use ($tag) { return !empty($migration['migration_tags']) && in_array($tag, $migration['migration_tags']); }); return $this->createInstances(array_keys($migrations)); @@ -222,9 +222,9 @@ public function buildDependencyMigration(array $migrations, array $dynamic_ids) * The dynamic ID mapping. */ protected function addDependency(array &$graph, $id, $dependency, $dynamic_ids) { - $dependencies = isset($dynamic_ids[$dependency]) ? $dynamic_ids[$dependency] : array($dependency); + $dependencies = isset($dynamic_ids[$dependency]) ? $dynamic_ids[$dependency] : [$dependency]; if (!isset($graph[$id]['edges'])) { - $graph[$id]['edges'] = array(); + $graph[$id]['edges'] = []; } $graph[$id]['edges'] += array_combine($dependencies, $dependencies); } diff --git a/core/modules/migrate/src/Plugin/MigrationPluginManagerInterface.php b/core/modules/migrate/src/Plugin/MigrationPluginManagerInterface.php index 0f977682..a0f64886 100644 --- a/core/modules/migrate/src/Plugin/MigrationPluginManagerInterface.php +++ b/core/modules/migrate/src/Plugin/MigrationPluginManagerInterface.php @@ -26,7 +26,7 @@ interface MigrationPluginManagerInterface extends PluginManagerInterface { * @throws \Drupal\Component\Plugin\Exception\PluginException * If an instance cannot be created, such as if the ID is invalid. */ - public function createInstances($id, array $configuration = array()); + public function createInstances($id, array $configuration = []); /** * Creates a stub migration plugin from a definition array. diff --git a/core/modules/migrate/src/Plugin/migrate/destination/ComponentEntityDisplayBase.php b/core/modules/migrate/src/Plugin/migrate/destination/ComponentEntityDisplayBase.php index a3b174a9..eaf3b54d 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/ComponentEntityDisplayBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/ComponentEntityDisplayBase.php @@ -15,8 +15,8 @@ abstract class ComponentEntityDisplayBase extends DestinationBase { /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { - $values = array(); + public function import(Row $row, array $old_destination_id_values = []) { + $values = []; // array_intersect_key() won't work because the order is important because // this is also the return value. foreach (array_keys($this->getIds()) as $id) { @@ -24,7 +24,7 @@ public function import(Row $row, array $old_destination_id_values = array()) { } $entity = $this->getEntity($values['entity_type'], $values['bundle'], $values[static::MODE_NAME]); if (!$row->getDestinationProperty('hidden')) { - $entity->setComponent($values['field_name'], $row->getDestinationProperty('options') ?: array()); + $entity->setComponent($values['field_name'], $row->getDestinationProperty('options') ?: []); } else { $entity->removeComponent($values['field_name']); @@ -64,6 +64,6 @@ public function fields(MigrationInterface $migration = NULL) { * @return \Drupal\Core\Entity\Display\EntityDisplayInterface * The entity display object. */ - protected abstract function getEntity($entity_type, $bundle, $mode); + abstract protected function getEntity($entity_type, $bundle, $mode); } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/Config.php b/core/modules/migrate/src/Plugin/migrate/destination/Config.php index 422037be..18d78a32 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/Config.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/Config.php @@ -14,10 +14,56 @@ /** * Provides Configuration Management destination plugin. * - * Persist data to the config system. + * Persists data to the config system. * - * When a property is NULL, the default is used unless the configuration option - * 'store null' is set to TRUE. + * Available configuration keys: + * - store null: (optional) Boolean, if TRUE, when a property is NULL, NULL is + * stored, otherwise the default is used. Defaults to FALSE. + * - translations: (optional) Boolean, if TRUE, the destination will be + * associated with the langcode provided by the source plugin. Defaults to + * FALSE. + * + * Destination properties expected in the imported row: + * - config_name: The machine name of the config. + * - langcode: (optional) The language code of the config. + * + * Examples: + * + * @code + * source: + * plugin: variable + * variables: + * - node_admin_theme + * process: + * use_admin_theme: node_admin_theme + * destination: + * plugin: config + * config_name: node.settings + * @endcode + * + * This will add the value of the variable "node_admin_theme" to the config with + * the machine name "node.settings" as "node.settings.use_admin_theme". + * + * @code + * source: + * plugin: i18n_variable + * variables: + * - site_offline_message + * process: + * langcode: language + * message: site_offline_message + * destination: + * plugin: config + * config_name: system.maintenance + * translations: true + * @endcode + * + * This will add the value of the variable "site_offline_message" to the config + * with the machine name "system.maintenance" as "system.maintenance.message", + * coupled with the relevant langcode as obtained from the "i18n_variable" + * source plugin. + * + * @see \Drupal\migrate_drupal\Plugin\migrate\source\d6\i18nVariable * * @MigrateDestination( * id = "config" @@ -83,7 +129,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { if ($this->isTranslationDestination()) { $this->config = $this->language_manager->getLanguageConfigOverride($row->getDestinationProperty('langcode'), $this->config->getName()); } @@ -149,4 +195,26 @@ public function rollback(array $destination_identifier) { } } + /** + * {@inheritdoc} + */ + public function getDestinationModule() { + if (!empty($this->configuration['destination_module'])) { + return $this->configuration['destination_module']; + } + if (!empty($this->pluginDefinition['destination_module'])) { + return $this->pluginDefinition['destination_module']; + } + // Config translations require the config_translation module so set the + // migration provider to 'config_translation'. The corresponding non + // translated configuration is expected to be handled in a separate + // migration. + if (isset($this->configuration['translations'])) { + return 'config_translation'; + } + // Get the module handling this configuration object from the config_name, + // which is of the form . + return !empty($this->configuration['config_name']) ? explode('.', $this->configuration['config_name'], 2)[0] : NULL; + } + } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/DestinationBase.php b/core/modules/migrate/src/Plugin/migrate/destination/DestinationBase.php index 18a95e6b..d6c30888 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/DestinationBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/DestinationBase.php @@ -110,4 +110,22 @@ protected function setRollbackAction(array $id_map, $update_action = MigrateIdMa } } + /** + * {@inheritdoc} + */ + public function getDestinationModule() { + if (!empty($this->configuration['destination_module'])) { + return $this->configuration['destination_module']; + } + if (!empty($this->pluginDefinition['destination_module'])) { + return $this->pluginDefinition['destination_module']; + } + if (is_string($this->migration->provider)) { + return $this->migration->provider; + } + else { + return reset($this->migration->provider); + } + } + } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php index 0cc00d60..708addf0 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php @@ -3,27 +3,126 @@ namespace Drupal\migrate\Plugin\migrate\destination; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\language\ConfigurableLanguageManager; +use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Row; +use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Class for importing configuration entities. + * Base destination class for importing configuration entities. * - * This class serves as the import class for most configuration entities. - * It can be necessary to provide a specific entity class if the configuration - * entity has a compound ID (see EntityFieldEntity) or it has specific setter - * methods (see EntityDateFormat). When implementing an entity destination for - * the latter case, make sure to add a test not only for importing but also - * for re-importing (if that is supported). + * Available configuration keys: + * - translations: (optional) Boolean, if TRUE, the destination will be + * associated with the langcode provided by the source plugin. Defaults to + * FALSE. + * + * Examples: + * + * @code + * source: + * plugin: d7_block_custom + * process: + * id: bid + * info: info + * langcode: language + * body: body + * destination: + * plugin: entity:block + * @endcode + * + * This will save the migrated, processed row as a block config entity. + * + * @code + * source: + * plugin: d6_i18n_profile_field + * constants: + * entity_type: user + * bundle: user + * process: + * langcode: language + * entity_type: 'constants/entity_type' + * bundle: 'constants/bundle' + * field_name: name + * ... + * translation: translation + * destination: + * plugin: entity:field_config + * translations: true + * @endcode + * + * Because the translations configuration is set to "true", this will save the + * migrated, processed row to a "field_config" entity associated with the + * designated langcode. */ class EntityConfigBase extends Entity { + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * The configuration factory. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface; + */ + protected $configFactory; + + /** + * Construct a new entity. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The migration. + * @param \Drupal\Core\Entity\EntityStorageInterface $storage + * The storage for this entity type. + * @param array $bundles + * The list of bundles this entity type has. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The configuration factory. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles); + $this->languageManager = $language_manager; + $this->configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + $entity_type_id = static::getEntityTypeId($plugin_id); + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('entity.manager')->getStorage($entity_type_id), + array_keys($container->get('entity.manager')->getBundleInfo($entity_type_id)), + $container->get('language_manager'), + $container->get('config.factory') + ); + } + /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { if ($row->isStub()) { throw new MigrateException('Config entities can not be stubbed.'); } @@ -39,17 +138,37 @@ public function import(Row $row, array $old_destination_id_values = array()) { } } $entity = $this->getEntity($row, $old_destination_id_values); - $entity->save(); + // Translations are already saved in updateEntity by configuration override. + if (!$this->isTranslationDestination()) { + $entity->save(); + } if (count($ids) > 1) { // This can only be a config entity, content entities have their ID key // and that's it. - $return = array(); + $return = []; foreach ($id_keys as $id_key) { - $return[] = $entity->get($id_key); + if (($this->isTranslationDestination()) && ($id_key == 'langcode')) { + // Config entities do not have a language property, get the language + // code from the destination. + $return[] = $row->getDestinationProperty($id_key); + } + else { + $return[] = $entity->get($id_key); + } } return $return; } - return array($entity->id()); + return [$entity->id()]; + } + + /** + * Get whether this destination is for translations. + * + * @return bool + * Whether this destination is for translations. + */ + protected function isTranslationDestination() { + return !empty($this->configuration['translations']); } /** @@ -58,6 +177,9 @@ public function import(Row $row, array $old_destination_id_values = array()) { public function getIds() { $id_key = $this->getKey('id'); $ids[$id_key]['type'] = 'string'; + if ($this->isTranslationDestination()) { + $ids['langcode']['type'] = 'string'; + } return $ids; } @@ -70,11 +192,28 @@ public function getIds() { * The row object to update from. */ protected function updateEntity(EntityInterface $entity, Row $row) { - foreach ($row->getRawDestination() as $property => $value) { - $this->updateEntityProperty($entity, explode(Row::PROPERTY_SEPARATOR, $property), $value); + // This is a translation if the language in the active config does not + // match the language of this row. + $translation = FALSE; + if ($row->hasDestinationProperty('langcode') && $this->languageManager instanceof ConfigurableLanguageManager) { + $config = $entity->getConfigDependencyName(); + $langcode = $this->configFactory->get('langcode'); + if ($langcode != $row->getDestinationProperty('langcode')) { + $translation = TRUE; + } } - $this->setRollbackAction($row->getIdMap()); + if ($translation) { + $config_override = $this->languageManager->getLanguageConfigOverride($row->getDestinationProperty('langcode'), $config); + $config_override->set(str_replace(Row::PROPERTY_SEPARATOR, '.', $row->getDestinationProperty('property')), $row->getDestinationProperty('translation')); + $config_override->save(); + } + else { + foreach ($row->getRawDestination() as $property => $value) { + $this->updateEntityProperty($entity, explode(Row::PROPERTY_SEPARATOR, $property), $value); + } + $this->setRollbackAction($row->getIdMap()); + } } /** @@ -111,11 +250,41 @@ protected function updateEntityProperty(EntityInterface $entity, array $parents, * The generated entity ID. */ protected function generateId(Row $row, array $ids) { - $id_values = array(); + $id_values = []; foreach ($ids as $id) { + if ($this->isTranslationDestination() && $id == 'langcode') { + continue; + } $id_values[] = $row->getDestinationProperty($id); } return implode('.', $id_values); } + /** + * {@inheritdoc} + */ + public function rollback(array $destination_identifier) { + if ($this->isTranslationDestination()) { + // The entity id does not include the langcode. + $id_values = []; + foreach ($destination_identifier as $key => $value) { + if ($this->isTranslationDestination() && $key == 'langcode') { + continue; + } + $id_values[] = $value; + } + $entity_id = implode('.', $id_values); + $language = $destination_identifier['langcode']; + + $config = $this->storage->load($entity_id)->getConfigDependencyName(); + $config_override = $this->languageManager->getLanguageConfigOverride($language, $config); + // Rollback the translation. + $config_override->delete(); + } + else { + $destination_identifier = implode('.', $destination_identifier); + parent::rollback([$destination_identifier]); + } + } + } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php index 9da3de6f..cf3ae1de 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php @@ -80,7 +80,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { $this->rollbackAction = MigrateIdMapInterface::ROLLBACK_DELETE; $entity = $this->getEntity($row, $old_destination_id_values); if (!$entity) { @@ -105,9 +105,9 @@ public function import(Row $row, array $old_destination_id_values = array()) { * @return array * An array containing the entity ID. */ - protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) { + protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) { $entity->save(); - return array($entity->id()); + return [$entity->id()]; } /** @@ -149,6 +149,7 @@ public function getIds() { * An updated entity, or NULL if it's the same as the one passed in. */ protected function updateEntity(EntityInterface $entity, Row $row) { + $empty_destinations = $row->getEmptyDestinationProperties(); // By default, an update will be preserved. $rollback_action = MigrateIdMapInterface::ROLLBACK_PRESERVE; @@ -171,6 +172,7 @@ protected function updateEntity(EntityInterface $entity, Row $row) { // clone the row with an empty set of destination values, and re-add only // the specified properties. if (isset($this->configuration['overwrite_properties'])) { + $empty_destinations = array_intersect($empty_destinations, $this->configuration['overwrite_properties']); $clone = $row->cloneWithoutDestination(); foreach ($this->configuration['overwrite_properties'] as $property) { $clone->setDestinationProperty($property, $row->getDestinationProperty($property)); @@ -184,6 +186,9 @@ protected function updateEntity(EntityInterface $entity, Row $row) { $field->setValue($values); } } + foreach ($empty_destinations as $field_name) { + $entity->$field_name = NULL; + } $this->setRollbackAction($row->getIdMap(), $rollback_action); diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php index 966cb370..a431c497 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldInstance.php @@ -18,15 +18,10 @@ public function getIds() { $ids['entity_type']['type'] = 'string'; $ids['bundle']['type'] = 'string'; $ids['field_name']['type'] = 'string'; + if ($this->isTranslationDestination()) { + $ids['langcode']['type'] = 'string'; + } return $ids; } - /** - * {@inheritdoc} - */ - public function rollback(array $destination_identifier) { - $destination_identifier = implode('.', $destination_identifier); - parent::rollback(array($destination_identifier)); - } - } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php index 7ad01045..9b781a3f 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityFieldStorageConfig.php @@ -25,7 +25,7 @@ public function getIds() { */ public function rollback(array $destination_identifier) { $destination_identifier = implode('.', $destination_identifier); - parent::rollback(array($destination_identifier)); + parent::rollback([$destination_identifier]); } } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php index 38197429..b0db4769 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php @@ -63,9 +63,9 @@ protected function getEntity(Row $row, array $old_destination_id_values) { /** * {@inheritdoc} */ - protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) { + protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) { $entity->save(); - return array($entity->getRevisionId()); + return [$entity->getRevisionId()]; } /** diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php index fad171b5..b2c25a45 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityViewMode.php @@ -5,6 +5,25 @@ /** * Provides entity view mode destination plugin. * + * See EntityConfigBase for the available configuration options. + * @see \Drupal\migrate\Plugin\migrate\destination\EntityConfigBase + * + * Example: + * + * @code + * source: + * plugin: d7_view_mode + * process: + * mode: view_mode + * label: view_mode + * targetEntityType: entity_type + * destination: + * plugin: entity:entity_view_mode + * @endcode + * + * This will add the results of the process ("mode", "label" and + * "targetEntityType") to an "entity_view_mode" entity. + * * @MigrateDestination( * id = "entity:entity_view_mode" * ) @@ -25,7 +44,7 @@ public function getIds() { */ public function rollback(array $destination_identifier) { $destination_identifier = implode('.', $destination_identifier); - parent::rollback(array($destination_identifier)); + parent::rollback([$destination_identifier]); } } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php b/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php index 878a1838..cfe47ead 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/NullDestination.php @@ -19,20 +19,20 @@ class NullDestination extends DestinationBase { * {@inheritdoc} */ public function getIds() { - return array(); + return []; } /** * {@inheritdoc} */ public function fields(MigrationInterface $migration = NULL) { - return array(); + return []; } /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { } } diff --git a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php index 835bbbbf..3b9a982f 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityDisplay.php @@ -5,6 +5,45 @@ /** * This class imports one component of an entity display. * + * Destination properties expected in the imported row: + * - entity_type: The entity type ID. + * - bundle: The entity bundle. + * - view_mode: The machine name of the view mode. + * - field_name: The machine name of the field to be imported into the display. + * - options: (optional) An array of options for displaying the field in this + * view mode. + * + * Examples: + * + * @code + * source: + * constants: + * entity_type: user + * bundle: user + * view_mode: default + * field_name: user_picture + * type: image + * options: + * label: hidden + * settings: + * image_style: '' + * image_link: content + * process: + * entity_type: 'constants/entity_type' + * bundle: 'constants/bundle' + * view_mode: 'constants/view_mode' + * field_name: 'constants/field_name' + * type: 'constants/type' + * options: 'constants/options' + * 'options/type': '@type' + * destination: + * plugin: component_entity_display + * @endcode + * + * This will add the "user_picture" image field to the "default" view mode of + * the "user" bundle of the "user" entity type with options as defined by the + * "options" constant, for example the label will be hidden. + * * @MigrateDestination( * id = "component_entity_display" * ) diff --git a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php index 02b1b62d..bd837f03 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/PerComponentEntityFormDisplay.php @@ -5,6 +5,38 @@ /** * This class imports one component of an entity form display. * + * Destination properties expected in the imported row: + * - entity_type: The entity type ID. + * - bundle: The entity bundle. + * - form_mode: The machine name of the form mode. + * - field_name: The machine name of the field to be imported into the display. + * - options: (optional) An array of options for displaying the field in this + * form mode. + * + * Examples: + * + * @code + * source: + * constants: + * entity_type: node + * field_name: comment + * form_mode: default + * options: + * type: comment_default + * weight: 20 + * process: + * entity_type: 'constants/entity_type' + * field_name: 'constants/field_name' + * form_mode: 'constants/form_mode' + * options: 'constants/options' + * bundle: node_type + * destination: + * plugin: component_entity_form_display + * @endcode + * + * This will add a "comment" field on the "default" form mode of the "node" + * entity type with options defined by the "options" constant. + * * @MigrateDestination( * id = "component_entity_form_display" * ) diff --git a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php index 962e05b2..6bdd51eb 100644 --- a/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php +++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php @@ -6,6 +6,7 @@ use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\PluginBase; +use Drupal\migrate\MigrateMessage; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Event\MigrateIdMapMessageEvent; use Drupal\migrate\MigrateException; @@ -55,7 +56,7 @@ class Sql extends PluginBase implements MigrateIdMapInterface, ContainerFactoryP protected $messageTableName; /** - * The migrate message. + * The migrate message service. * * @var \Drupal\migrate\MigrateMessageInterface */ @@ -115,14 +116,14 @@ class Sql extends PluginBase implements MigrateIdMapInterface, ContainerFactoryP * * @var array */ - protected $sourceIds = array(); + protected $sourceIds = []; /** * The destination identifiers. * * @var array */ - protected $destinationIds = array(); + protected $destinationIds = []; /** * The current row. @@ -136,7 +137,7 @@ class Sql extends PluginBase implements MigrateIdMapInterface, ContainerFactoryP * * @var array */ - protected $currentKey = array(); + protected $currentKey = []; /** * Constructs an SQL object. @@ -156,6 +157,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition parent::__construct($configuration, $plugin_id, $plugin_definition); $this->migration = $migration; $this->eventDispatcher = $event_dispatcher; + $this->message = new MigrateMessage(); } /** @@ -174,7 +176,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * Retrieves the hash of the source identifier values. * - * It is public only for testing purposes. + * @internal * * @param array $source_id_values * The source identifiers @@ -208,7 +210,7 @@ public function getSourceIDsHash(array $source_id_values) { protected function sourceIdFields() { if (!isset($this->sourceIdFields)) { // Build the source and destination identifier maps. - $this->sourceIdFields = array(); + $this->sourceIdFields = []; $count = 1; foreach ($this->migration->getSourcePlugin()->getIds() as $field => $schema) { $this->sourceIdFields[$field] = 'sourceid' . $count++; @@ -225,7 +227,7 @@ protected function sourceIdFields() { */ protected function destinationIdFields() { if (!isset($this->destinationIdFields)) { - $this->destinationIdFields = array(); + $this->destinationIdFields = []; $count = 1; foreach ($this->migration->getDestinationPlugin()->getIds() as $field => $schema) { $this->destinationIdFields[$field] = 'destid' . $count++; @@ -312,19 +314,21 @@ protected function ensureTables() { // Generate appropriate schema info for the map and message tables, // and map from the source field names to the map/msg field names. $count = 1; - $source_id_schema = array(); + $source_id_schema = []; + $indexes = []; foreach ($this->migration->getSourcePlugin()->getIds() as $id_definition) { $mapkey = 'sourceid' . $count++; + $indexes['source'][] = $mapkey; $source_id_schema[$mapkey] = $this->getFieldSchema($id_definition); $source_id_schema[$mapkey]['not null'] = TRUE; } - $source_ids_hash[static::SOURCE_IDS_HASH] = array( + $source_ids_hash[static::SOURCE_IDS_HASH] = [ 'type' => 'varchar', 'length' => '64', 'not null' => TRUE, 'description' => 'Hash of source ids. Used as primary key', - ); + ]; $fields = $source_ids_hash + $source_id_schema; // Add destination identifiers to map table. @@ -336,68 +340,69 @@ protected function ensureTables() { $fields[$mapkey] = $this->getFieldSchema($id_definition); $fields[$mapkey]['not null'] = FALSE; } - $fields['source_row_status'] = array( + $fields['source_row_status'] = [ 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => MigrateIdMapInterface::STATUS_IMPORTED, 'description' => 'Indicates current status of the source row', - ); - $fields['rollback_action'] = array( + ]; + $fields['rollback_action'] = [ 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => MigrateIdMapInterface::ROLLBACK_DELETE, 'description' => 'Flag indicating what to do for this item on rollback', - ); - $fields['last_imported'] = array( + ]; + $fields['last_imported'] = [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'UNIX timestamp of the last time this row was imported', - ); - $fields['hash'] = array( + ]; + $fields['hash'] = [ 'type' => 'varchar', 'length' => '64', 'not null' => FALSE, 'description' => 'Hash of source row data, for detecting changes', - ); - $schema = array( + ]; + $schema = [ 'description' => 'Mappings from source identifier value(s) to destination identifier value(s).', 'fields' => $fields, - 'primary key' => array(static::SOURCE_IDS_HASH), - ); + 'primary key' => [static::SOURCE_IDS_HASH], + 'indexes' => $indexes, + ]; $this->getDatabase()->schema()->createTable($this->mapTableName, $schema); // Now do the message table. if (!$this->getDatabase()->schema()->tableExists($this->messageTableName())) { - $fields = array(); - $fields['msgid'] = array( + $fields = []; + $fields['msgid'] = [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ); + ]; $fields += $source_ids_hash; - $fields['level'] = array( + $fields['level'] = [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1, - ); - $fields['message'] = array( + ]; + $fields['message'] = [ 'type' => 'text', 'size' => 'medium', 'not null' => TRUE, - ); - $schema = array( + ]; + $schema = [ 'description' => 'Messages generated during a migration process', 'fields' => $fields, - 'primary key' => array('msgid'), - ); + 'primary key' => ['msgid'], + ]; $this->getDatabase()->schema()->createTable($this->messageTableName(), $schema); } } @@ -406,33 +411,33 @@ protected function ensureTables() { if (!$this->getDatabase()->schema()->fieldExists($this->mapTableName, 'rollback_action')) { $this->getDatabase()->schema()->addField($this->mapTableName, 'rollback_action', - array( + [ 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'Flag indicating what to do for this item on rollback', - ) + ] ); } if (!$this->getDatabase()->schema()->fieldExists($this->mapTableName, 'hash')) { $this->getDatabase()->schema()->addField($this->mapTableName, 'hash', - array( + [ 'type' => 'varchar', 'length' => '64', 'not null' => FALSE, 'description' => 'Hash of source row data, for detecting changes', - ) + ] ); } if (!$this->getDatabase()->schema()->fieldExists($this->mapTableName, static::SOURCE_IDS_HASH)) { - $this->getDatabase()->schema()->addField($this->mapTableName, static::SOURCE_IDS_HASH, array( + $this->getDatabase()->schema()->addField($this->mapTableName, static::SOURCE_IDS_HASH, [ 'type' => 'varchar', 'length' => '64', 'not null' => TRUE, 'description' => 'Hash of source ids. Used as primary key', - )); + ]); } } } @@ -482,7 +487,7 @@ protected function getFieldSchema(array $id_definition) { */ public function getRowBySource(array $source_id_values) { $query = $this->getDatabase()->select($this->mapTableName(), 'map') - ->fields('map'); + ->fields('map'); $query->condition(static::SOURCE_IDS_HASH, $this->getSourceIDsHash($source_id_values)); $result = $query->execute(); return $result->fetchAssoc(); @@ -493,7 +498,7 @@ public function getRowBySource(array $source_id_values) { */ public function getRowByDestination(array $destination_id_values) { $query = $this->getDatabase()->select($this->mapTableName(), 'map') - ->fields('map'); + ->fields('map'); foreach ($this->destinationIdFields() as $field_name => $destination_id) { $query->condition("map.$destination_id", $destination_id_values[$field_name], '='); } @@ -505,12 +510,12 @@ public function getRowByDestination(array $destination_id_values) { * {@inheritdoc} */ public function getRowsNeedingUpdate($count) { - $rows = array(); + $rows = []; $result = $this->getDatabase()->select($this->mapTableName(), 'map') - ->fields('map') - ->condition('source_row_status', MigrateIdMapInterface::STATUS_NEEDS_UPDATE) - ->range(0, $count) - ->execute(); + ->fields('map') + ->condition('source_row_status', MigrateIdMapInterface::STATUS_NEEDS_UPDATE) + ->range(0, $count) + ->execute(); foreach ($result as $row) { $rows[] = $row; } @@ -538,7 +543,7 @@ public function lookupSourceID(array $destination_id_values) { */ public function lookupDestinationId(array $source_id_values) { $results = $this->lookupDestinationIds($source_id_values); - return $results ? reset($results) : array(); + return $results ? reset($results) : []; } /** @@ -546,7 +551,7 @@ public function lookupDestinationId(array $source_id_values) { */ public function lookupDestinationIds(array $source_id_values) { if (empty($source_id_values)) { - return array(); + return []; } // Canonicalize the keys into a hash of DB-field => value. @@ -602,7 +607,7 @@ public function saveIdMapping(Row $row, array $destination_id_values, $source_ro if (!isset($source_id_values[$field_name])) { $this->message->display($this->t( 'Did not save to map table due to NULL value for key field @field', - array('@field' => $field_name)), 'error'); + ['@field' => $field_name]), 'error'); return; } $fields[$key_name] = $source_id_values[$field_name]; @@ -612,11 +617,11 @@ public function saveIdMapping(Row $row, array $destination_id_values, $source_ro return; } - $fields += array( + $fields += [ 'source_row_status' => (int) $source_row_status, 'rollback_action' => (int) $rollback_action, 'hash' => $row->getHash(), - ); + ]; $count = 0; foreach ($destination_id_values as $dest_id) { $fields['destid' . ++$count] = $dest_id; @@ -680,7 +685,7 @@ public function getMessageIterator(array $source_id_values = [], $level = NULL) */ public function prepareUpdate() { $this->getDatabase()->update($this->mapTableName()) - ->fields(array('source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE)) + ->fields(['source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE]) ->execute(); } @@ -699,7 +704,7 @@ public function processedCount() { */ public function importedCount() { return $this->getDatabase()->select($this->mapTableName()) - ->condition('source_row_status', array(MigrateIdMapInterface::STATUS_IMPORTED, MigrateIdMapInterface::STATUS_NEEDS_UPDATE), 'IN') + ->condition('source_row_status', [MigrateIdMapInterface::STATUS_IMPORTED, MigrateIdMapInterface::STATUS_NEEDS_UPDATE], 'IN') ->countQuery() ->execute() ->fetchField(); @@ -794,7 +799,7 @@ public function setUpdate(array $source_id_values) { } $query = $this->getDatabase() ->update($this->mapTableName()) - ->fields(array('source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE)); + ->fields(['source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE]); foreach ($this->sourceIdFields() as $field_name => $source_id) { $query->condition($source_id, $source_id_values[$field_name]); @@ -818,13 +823,13 @@ public function destroy() { } /** - * Implementation of Iterator::rewind(). + * Implementation of \Iterator::rewind(). * * This is called before beginning a foreach loop. */ public function rewind() { $this->currentRow = NULL; - $fields = array(); + $fields = []; foreach ($this->sourceIdFields() as $field) { $fields[] = $field; } @@ -839,7 +844,7 @@ public function rewind() { } /** - * Implementation of Iterator::current(). + * Implementation of \Iterator::current(). * * This is called when entering a loop iteration, returning the current row. */ @@ -848,7 +853,7 @@ public function current() { } /** - * Implementation of Iterator::key(). + * Implementation of \Iterator::key(). * * This is called when entering a loop iteration, returning the key of the * current row. It must be a scalar - we will serialize to fulfill the @@ -863,7 +868,7 @@ public function key() { */ public function currentDestination() { if ($this->valid()) { - $result = array(); + $result = []; foreach ($this->destinationIdFields() as $destination_field_name => $idmap_field_name) { if (!is_null($this->currentRow[$idmap_field_name])) { $result[$destination_field_name] = $this->currentRow[$idmap_field_name]; @@ -881,7 +886,7 @@ public function currentDestination() { */ public function currentSource() { if ($this->valid()) { - $result = array(); + $result = []; foreach ($this->sourceIdFields() as $field_name => $source_id) { $result[$field_name] = $this->currentKey[$source_id]; } @@ -893,14 +898,14 @@ public function currentSource() { } /** - * Implementation of Iterator::next(). + * Implementation of \Iterator::next(). * * This is called at the bottom of the loop implicitly, as well as explicitly * from rewind(). */ public function next() { $this->currentRow = $this->result->fetchAssoc(); - $this->currentKey = array(); + $this->currentKey = []; if ($this->currentRow) { foreach ($this->sourceIdFields() as $map_field) { $this->currentKey[$map_field] = $this->currentRow[$map_field]; @@ -911,7 +916,7 @@ public function next() { } /** - * Implementation of Iterator::valid(). + * Implementation of \Iterator::valid(). * * This is called at the top of the loop, returning TRUE to process the loop * and FALSE to terminate it. diff --git a/core/modules/migrate/src/Plugin/migrate/process/Callback.php b/core/modules/migrate/src/Plugin/migrate/process/Callback.php index 618e05d4..8721899f 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Callback.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Callback.php @@ -7,15 +7,38 @@ use Drupal\migrate\Row; /** - * This plugin allows source value to be passed to a callback. + * Passes the source value to a callback. * - * The current value is passed to a callable that returns the processed value. - * This plugin allows simple processing of the value, such as strtolower(). The - * callable takes the value as the single mandatory argument. No additional - * arguments can be passed to the callback as this would make the migration YAML - * file too complex. + * The callback process plugin allows simple processing of the value, such as + * strtolower(). The callable takes the source value as the single mandatory + * argument. No additional arguments can be passed to the callback. * - * @link https://www.drupal.org/node/2181783 Online handbook documentation for callback process plugin @endlink + * Available configuration keys: + * - callable: The name of the callable method. + * + * Examples: + * + * @code + * process: + * destination_field: + * plugin: callback + * callable: strtolower + * source: source_field + * @endcode + * + * An example where the callable is a static method in a class: + * + * @code + * process: + * destination_field: + * plugin: callback + * callable: + * - '\Drupal\Component\Utility\Unicode' + * - strtolower + * source: source_field + * @endcode + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "callback" diff --git a/core/modules/migrate/src/Plugin/migrate/process/Concat.php b/core/modules/migrate/src/Plugin/migrate/process/Concat.php index c013bdc7..e3323b4b 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Concat.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Concat.php @@ -8,9 +8,48 @@ use Drupal\migrate\Row; /** - * Concatenates the strings in the current value. + * Concatenates a set of strings. * - * @link https://www.drupal.org/node/2345927 Online handbook documentation for concat process plugin @endlink + * The concat plugin is used to concatenate strings. For example, imploding a + * set of strings into a single string. + * + * Available configuration keys: + * - delimiter: (optional) A delimiter, or glue string, to insert between the + * strings. + * + * Examples: + * + * @code + * process: + * new_text_field: + * plugin: concat + * source: + * - foo + * - bar + * @endcode + * + * This will set new_text_field to the concatenation of the 'foo' and 'bar' + * source values. For example, if the 'foo' property is "wambooli" and the 'bar' + * property is "pastafazoul", new_text_field will be "wamboolipastafazoul". + * + * You can also specify a delimiter. + * + * @code + * process: + * new_text_field: + * plugin: concat + * source: + * - foo + * - bar + * delimiter: / + * @endcode + * + * This will set new_text_field to the concatenation of the 'foo' source value, + * the delimiter and the 'bar' source value. For example, using the values above + * and "/" as the delimiter, if the 'foo' property is "wambooli" and the 'bar' + * property is "pastafazoul", new_text_field will be "wambooli/pastafazoul". + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "concat", @@ -21,8 +60,6 @@ class Concat extends ProcessPluginBase { /** * {@inheritdoc} - * - * Concatenates the strings in the current value. */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if (is_array($value)) { diff --git a/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php b/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php index adaf7200..90801ebd 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php +++ b/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php @@ -2,11 +2,8 @@ namespace Drupal\migrate\Plugin\migrate\process; -use Drupal\migrate\ProcessPluginBase; -use Drupal\migrate\MigrateExecutableInterface; -use Drupal\migrate\Row; -use Drupal\migrate\MigrateException; -use Drupal\Component\Utility\Unicode; +@trigger_error('The ' . __NAMESPACE__ . ' \DedupeEntityBase is deprecated in +Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . ' \MakeUniqueEntityFieldBase', E_USER_DEPRECATED); /** * This abstract base contains the dedupe logic. @@ -17,41 +14,11 @@ * and incremented until a unique value is created. * * @link https://www.drupal.org/node/2345929 Online handbook documentation for dedupebase process plugin @endlink + * + * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use + * \Drupal\migrate\Plugin\migrate\process\MakeUniqueBase instead. + * + * @see https://www.drupal.org/node/2873762 */ -abstract class DedupeBase extends ProcessPluginBase { - - /** - * {@inheritdoc} - */ - public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $i = 1; - $postfix = isset($this->configuration['postfix']) ? $this->configuration['postfix'] : ''; - $start = isset($this->configuration['start']) ? $this->configuration['start'] : 0; - if (!is_int($start)) { - throw new MigrateException('The start position configuration key should be an integer. Omit this key to capture from the beginning of the string.'); - } - $length = isset($this->configuration['length']) ? $this->configuration['length'] : NULL; - if (!is_null($length) && !is_int($length)) { - throw new MigrateException('The character length configuration key should be an integer. Omit this key to capture the entire string.'); - } - // Use optional start or length to return a portion of deduplicated value. - $value = Unicode::substr($value, $start, $length); - $new_value = $value; - while ($this->exists($new_value)) { - $new_value = $value . $postfix . $i++; - } - return $new_value; - } - - /** - * This is a query checking the existence of some value. - * - * @param mixed $value - * The value to check. - * - * @return bool - * TRUE if the value exists. - */ - abstract protected function exists($value); - +abstract class DedupeBase extends MakeUniqueBase { } diff --git a/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php b/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php index a616c86c..e6359188 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php +++ b/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php @@ -2,10 +2,8 @@ namespace Drupal\migrate\Plugin\migrate\process; -use Drupal\Core\Entity\Query\QueryFactory; -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\migrate\Plugin\MigrationInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; +@trigger_error('The ' . __NAMESPACE__ . ' \DedupeEntity is deprecated in +Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . ' \MakeUniqueEntityField', E_USER_DEPRECATED); /** * Ensures value is not duplicated against an entity field. @@ -18,69 +16,10 @@ * @MigrateProcessPlugin( * id = "dedupe_entity" * ) + * + * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use + * \Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField instead. + * + * @see https://www.drupal.org/node/2873762 */ -class DedupeEntity extends DedupeBase implements ContainerFactoryPluginInterface { - - /** - * The entity query factory. - * - * @var \Drupal\Core\Entity\Query\QueryFactoryInterface - */ - protected $entityQueryFactory; - - /** - * The current migration. - * - * @var \Drupal\migrate\Plugin\MigrationInterface - */ - protected $migration; - - /** - * {@inheritdoc} - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, QueryFactory $entity_query_factory) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->migration = $migration; - $this->entityQueryFactory = $entity_query_factory; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $migration, - $container->get('entity.query') - ); - } - - /** - * {@inheritdoc} - */ - protected function exists($value) { - // Plugins are cached so for every run we need a new query object. - $query = $this - ->entityQueryFactory - ->get($this->configuration['entity_type'], 'AND') - ->condition($this->configuration['field'], $value); - if (!empty($this->configuration['migrated'])) { - // Check if each entity is in the ID map. - $idMap = $this->migration->getIdMap(); - foreach ($query->execute() as $id) { - $dest_id_values[$this->configuration['field']] = $id; - if ($idMap->lookupSourceID($dest_id_values)) { - return TRUE; - } - } - return FALSE; - } - else { - // Just check if any such entity exists. - return $query->count()->execute(); - } - } - -} +class DedupeEntity extends MakeUniqueEntityField {} diff --git a/core/modules/migrate/src/Plugin/migrate/process/DefaultValue.php b/core/modules/migrate/src/Plugin/migrate/process/DefaultValue.php index db216f6f..a5e63888 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/DefaultValue.php +++ b/core/modules/migrate/src/Plugin/migrate/process/DefaultValue.php @@ -7,9 +7,38 @@ use Drupal\migrate\Row; /** - * This plugin sets missing values on the destination. + * Returns a given default value if the input is empty. * - * @link https://www.drupal.org/node/2135313 Online handbook documentation for default_value process plugin @endlink + * The default_value process plugin provides the ability to set a fixed default + * value. The plugin returns a default value if the input value is considered + * empty (NULL, FALSE, 0, '0', an empty string, or an empty array). The strict + * configuration key can be used to set the default only when the incoming + * value is NULL. + * + * Available configuration keys: + * - default_value: The fixed default value to apply. + * - strict: (optional) Use strict value checking. Defaults to false. + * - FALSE: Apply default when input value is empty(). + * - TRUE: Apply default when input value is NULL. + * + * Example: + * + * @code + * process: + * uid: + * - + * plugin: migration_lookup + * migration: users + * source: author + * - + * plugin: default_value + * default_value: 44 + * @endcode + * + * This will look up the source value of author in the users migration and if + * not found, set the destination property uid to 44. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "default_value" diff --git a/core/modules/migrate/src/Plugin/migrate/process/Download.php b/core/modules/migrate/src/Plugin/migrate/process/Download.php index 2014085e..cfcba811 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Download.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Download.php @@ -12,7 +12,42 @@ use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Downloads a file from a remote location into the local file system. + * Downloads a file from a HTTP(S) remote location into the local file system. + * + * The source value is an array of two values: + * - source URL, e.g. 'http://www.example.com/img/foo.img' + * - destination URI, e.g. 'public://images/foo.img' + * + * Available configuration keys: + * - rename: (optional) If set, a unique destination URI is generated. If not + * set, the destination URI will be overwritten if it exists. + * - guzzle_options: (optional) + * @link http://docs.guzzlephp.org/en/latest/request-options.html Array of request options for Guzzle. @endlink + * + * Examples: + * + * @code + * process: + * plugin: download + * source: + * - source_url + * - destination_uri + * @endcode + * + * This will download source_url to destination_uri. + * + * @code + * process: + * plugin: download + * source: + * - source_url + * - destination_uri + * rename: true + * @endcode + * + * This will download source_url to destination_uri and ensure that the + * destination URI is unique. If a file with the same name exists at the + * destination, a numbered suffix like '_0' will be appended to make it unique. * * @MigrateProcessPlugin( * id = "download" diff --git a/core/modules/migrate/src/Plugin/migrate/process/EntityExists.php b/core/modules/migrate/src/Plugin/migrate/process/EntityExists.php new file mode 100644 index 00000000..72f2ec39 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/EntityExists.php @@ -0,0 +1,82 @@ +storage = $storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_type.manager')->getStorage($configuration['entity_type']) + ); + } + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + if (is_array($value)) { + $value = reset($value); + } + + $entity = $this->storage->load($value); + if ($entity instanceof EntityInterface) { + return $entity->id(); + } + return FALSE; + } + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/Explode.php b/core/modules/migrate/src/Plugin/migrate/process/Explode.php index fd3cc9cf..536a9e1b 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Explode.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Explode.php @@ -8,9 +8,84 @@ use Drupal\migrate\Row; /** - * This plugin explodes a delimited string into an array of values. + * Splits the source string into an array of strings, using a delimiter. * - * @link https://www.drupal.org/node/2674504 Online handbook documentation for explode process plugin @endlink + * This plugin creates an array of strings by splitting the source parameter on + * boundaries formed by the delimiter. + * + * Available configuration keys: + * - source: The source string. + * - limit: (optional) + * - If limit is set and positive, the returned array will contain a maximum + * of limit elements with the last element containing the rest of string. + * - If limit is set and negative, all components except the last -limit are + * returned. + * - If the limit parameter is zero, then this is treated as 1. + * - delimiter: The boundary string. + * - strict: (optional) When this boolean is TRUE, the source should be strictly + * a string. If FALSE is passed, the source value is casted to a string before + * being split. Also, in this case, the values casting to empty strings are + * converted to empty arrays, instead of an array with a single empty string + * item ['']. Defaults to TRUE. + * + * Example: + * + * @code + * process: + * bar: + * plugin: explode + * source: foo + * delimiter: / + * @endcode + * + * If foo is "node/1", then bar will be ['node', '1']. The PHP equivalent of + * this would be: + * + * @code + * $bar = explode('/', $foo); + * @endcode + * + * @code + * process: + * bar: + * plugin: explode + * source: foo + * limit: 1 + * delimiter: / + * @endcode + * + * If foo is "node/1/edit", then bar will be ['node', '1/edit']. The PHP + * equivalent of this would be: + * + * @code + * $bar = explode('/', $foo, 1); + * @endcode + * + * If the 'strict' configuration is set to FALSE, the input value is casted to a + * string before being spilt: + * + * @code + * process: + * bar: + * plugin: explode + * source: foo + * delimiter: / + * strict: false + * @endcode + * + * If foo is 123 (as integer), then bar will be ['123']. If foo is TRUE, then + * bar will be ['1']. The PHP equivalent of this would be: + * + * @code + * $bar = explode('/', (string) 123); + * $bar = explode('/', (string) TRUE); + * @endcode + * + * If the 'strict' configuration is set to FALSE, the source value casting to + * an empty string are converted to an empty array. For example, with the last + * configuration, if foo is '', NULL or FALSE, then bar will be []. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "explode" @@ -22,18 +97,29 @@ class Explode extends ProcessPluginBase { * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - if (is_string($value)) { - if (!empty($this->configuration['delimiter'])) { - $limit = isset($this->configuration['limit']) ? $this->configuration['limit'] : PHP_INT_MAX; - return explode($this->configuration['delimiter'], $value, $limit); - } - else { - throw new MigrateException('delimiter is empty'); - } + if (empty($this->configuration['delimiter'])) { + throw new MigrateException('delimiter is empty'); } - else { + + $strict = array_key_exists('strict', $this->configuration) ? $this->configuration['strict'] : TRUE; + if ($strict && !is_string($value)) { throw new MigrateException(sprintf('%s is not a string', var_export($value, TRUE))); } + elseif (!$strict) { + // Check if the incoming value can cast to a string. + $original = $value; + if (!is_string($original) && ($original != ($value = @strval($value)))) { + throw new MigrateException(sprintf('%s cannot be casted to a string', var_export($original, TRUE))); + } + // Empty strings should be exploded to empty arrays. + if ($value === '') { + return []; + } + } + + $limit = isset($this->configuration['limit']) ? $this->configuration['limit'] : PHP_INT_MAX; + + return explode($this->configuration['delimiter'], $value, $limit); } /** diff --git a/core/modules/migrate/src/Plugin/migrate/process/Extract.php b/core/modules/migrate/src/Plugin/migrate/process/Extract.php index 1ac88ca5..544c306c 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Extract.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Extract.php @@ -9,9 +9,52 @@ use Drupal\migrate\Row; /** - * This plugin extracts a value from an array. + * Extracts a value from an array. * - * @link https://www.drupal.org/node/2152731 Online handbook documentation for extract process plugin @endlink + * The extract process plugin is used to pull data from an input array, which + * may have multiple levels. One use case is extracting data from field arrays + * in previous versions of Drupal. For instance, in Drupal 7, a field array + * would be indexed first by language, then by delta, then finally a key such as + * 'value'. + * + * Available configuration keys: + * - source: The input value - must be an array. + * - index: The array of keys to access the value. + * - default: (optional) A default value to assign to the destination if the + * key does not exist. + * + * Examples: + * + * @code + * process: + * new_text_field: + * plugin: extract + * source: some_text_field + * index: + * - und + * - 0 + * - value + * @endcode + * + * The PHP equivalent of this would be: + * @code + * $destination['new_text_field'] = $source['some_text_field']['und'][0]['value']; + * @endcode + * If a default value is specified, it will be returned if the index does not + * exist in the input array. + * + * @code + * plugin: extract + * source: some_text_field + * default: 'Default title' + * index: + * - title + * @endcode + * + * If $source['some_text_field']['title'] doesn't exist, then the plugin will + * return "Default title". + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "extract", diff --git a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php index 9aa59006..f598b811 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php +++ b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php @@ -14,7 +14,35 @@ use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Copy a file from one place into another. + * Copies or moves a local file from one place into another. + * + * The file can be moved, reused, or set to be automatically renamed if a + * duplicate exists. + * + * The source value is an indexed array of two values: + * - The source path or URI, e.g. '/path/to/foo.txt' or 'public://bar.txt'. + * - The destination URI, e.g. 'public://foo.txt'. + * + * Available configuration keys: + * - move: (optional) Boolean, if TRUE, move the file, otherwise copy the file. + * Defaults to FALSE. + * - rename: (optional) Boolean, if TRUE, rename the file by appending a number + * until the name is unique. Defaults to FALSE. + * - reuse: (optional) Boolean, if TRUE, reuse the current file in its existing + * location rather than move/copy/rename the file. Defaults to FALSE. + * + * Examples: + * + * @code + * process: + * path_to_file: + * plugin: file_copy + * source: + * - /path/to/file.png + * - public://new/path/to/file.png + * @endcode + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "file_copy" @@ -60,11 +88,11 @@ class FileCopy extends ProcessPluginBase implements ContainerFactoryPluginInterf * An instance of the download plugin for handling remote URIs. */ public function __construct(array $configuration, $plugin_id, array $plugin_definition, StreamWrapperManagerInterface $stream_wrappers, FileSystemInterface $file_system, MigrateProcessInterface $download_plugin) { - $configuration += array( + $configuration += [ 'move' => FALSE, 'rename' => FALSE, 'reuse' => FALSE, - ); + ]; parent::__construct($configuration, $plugin_id, $plugin_definition); $this->streamWrapperManager = $stream_wrappers; $this->fileSystem = $file_system; diff --git a/core/modules/migrate/src/Plugin/migrate/process/Flatten.php b/core/modules/migrate/src/Plugin/migrate/process/Flatten.php index f663e4d9..324f0b92 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Flatten.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Flatten.php @@ -1,18 +1,40 @@ configuration['from_format'])) { + throw new MigrateException('Format date plugin is missing from_format configuration.'); + } + if (empty($this->configuration['to_format'])) { + throw new MigrateException('Format date plugin is missing to_format configuration.'); + } + + $fromFormat = $this->configuration['from_format']; + $toFormat = $this->configuration['to_format']; + $timezone = isset($this->configuration['timezone']) ? $this->configuration['timezone'] : NULL; + $settings = isset($this->configuration['settings']) ? $this->configuration['settings'] : []; + + // Attempts to transform the supplied date using the defined input format. + // DateTimePlus::createFromFormat can throw exceptions, so we need to + // explicitly check for problems. + try { + $transformed = DateTimePlus::createFromFormat($fromFormat, $value, $timezone, $settings)->format($toFormat); + } + catch (\InvalidArgumentException $e) { + throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s". Error: %s', $value, $fromFormat, $e->getMessage()), $e->getCode(), $e); + } + catch (\UnexpectedValueException $e) { + throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s". Error: %s', $value, $fromFormat, $e->getMessage()), $e->getCode(), $e); + } + + return $transformed; + } + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/Get.php b/core/modules/migrate/src/Plugin/migrate/process/Get.php index f6b3c34e..2322edb5 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Get.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Get.php @@ -7,9 +7,87 @@ use Drupal\migrate\Row; /** - * This plugin copies from the source to the destination. + * Gets the source value. * - * @link https://www.drupal.org/node/2135307 Online handbook documentation for get process plugin @endlink + * Available configuration keys: + * - source: Source property. + * + * The get plugin returns the value of the property given by the "source" + * configuration key. + * + * Examples: + * + * @code + * process: + * bar: + * plugin: get + * source: foo + * @endcode + * + * This copies the source value of foo to the destination property "bar". + * + * Since get is the default process plugin, it can be shorthanded like this: + * + * @code + * process: + * bar: foo + * @endcode + * + * get also supports a list of source properties. + * + * Example: + * + * @code + * process: + * bar: + * plugin: get + * source: + * - foo1 + * - foo2 + * @endcode + * + * This copies the array of source values [foo1, foo2] to the destination + * property "bar". + * + * If the list of source properties contains an empty element then the current + * value will be used. This makes it impossible to reach a source property with + * an empty string as its name. + * + * get also supports copying destination values. These are indicated by a + * starting @ sign. Values using @ must be wrapped in quotes. + * + * @code + * process: + * foo: + * plugin: machine_name + * source: baz + * bar: + * plugin: get + * source: '@foo' + * @endcode + * + * This will simply copy the destination value of foo to the destination + * property bar. foo configuration is included for illustration purposes. + * + * Because of this, if your source or destination property actually starts with + * a @ you need to double those starting characters up. This means that if a + * destination property happens to start with a @ and you want to refer it, + * you'll need to start with three @ characters -- one to indicate the + * destination and two for escaping the real @. + * + * @code + * process: + * @foo: + * plugin: machine_name + * source: baz + * bar: + * plugin: get + * source: '@@@foo' + * @endcode + * + * This should occur extremely rarely. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "get" @@ -29,8 +107,8 @@ class Get extends ProcessPluginBase { */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { $source = $this->configuration['source']; - $properties = is_string($source) ? array($source) : $source; - $return = array(); + $properties = is_string($source) ? [$source] : $source; + $return = []; foreach ($properties as $property) { if ($property || (string) $property === '0') { $is_source = TRUE; diff --git a/core/modules/migrate/src/Plugin/migrate/process/Iterator.php b/core/modules/migrate/src/Plugin/migrate/process/Iterator.php index 2a41c4a9..5400e187 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Iterator.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Iterator.php @@ -2,65 +2,20 @@ namespace Drupal\migrate\Plugin\migrate\process; -use Drupal\migrate\ProcessPluginBase; -use Drupal\migrate\MigrateExecutableInterface; -use Drupal\migrate\Row; +@trigger_error('The ' . __NAMESPACE__ . '\Iterator is deprecated in +Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\SubProcess', E_USER_DEPRECATED); /** - * This plugin iterates and processes an array. + * Iterates and processes an associative array. * - * @link https://www.drupal.org/node/2135345 Online handbook documentation for iterator process plugin @endlink + * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use + * \Drupal\migrate\Plugin\migrate\process\SubProcess instead. + * + * @see https://www.drupal.org/node/2880427 * * @MigrateProcessPlugin( * id = "iterator", * handle_multiples = TRUE * ) */ -class Iterator extends ProcessPluginBase { - - /** - * Runs a process pipeline on each destination property per list item. - */ - public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $return = []; - if (!is_null($value)) { - foreach ($value as $key => $new_value) { - $new_row = new Row($new_value, []); - $migrate_executable->processRow($new_row, $this->configuration['process']); - $destination = $new_row->getDestination(); - if (array_key_exists('key', $this->configuration)) { - $key = $this->transformKey($key, $migrate_executable, $new_row); - } - $return[$key] = $destination; - } - } - return $return; - } - - /** - * Runs the process pipeline for the current key. - * - * @param string|int $key - * The current key. - * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable - * The migrate executable helper class. - * @param \Drupal\migrate\Row $row - * The current row after processing. - * - * @return mixed - * The transformed key. - */ - protected function transformKey($key, MigrateExecutableInterface $migrate_executable, Row $row) { - $process = array('key' => $this->configuration['key']); - $migrate_executable->processRow($row, $process, $key); - return $row->getDestinationProperty('key'); - } - - /** - * {@inheritdoc} - */ - public function multiple() { - return TRUE; - } - -} +class Iterator extends SubProcess {} diff --git a/core/modules/migrate/src/Plugin/migrate/process/Log.php b/core/modules/migrate/src/Plugin/migrate/process/Log.php new file mode 100644 index 00000000..62088f60 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/Log.php @@ -0,0 +1,41 @@ +saveMessage($value); + + // Pass through the same value we received. + return $value; + } + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/MachineName.php b/core/modules/migrate/src/Plugin/migrate/process/MachineName.php index 15ed3567..5a4b4d50 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/MachineName.php +++ b/core/modules/migrate/src/Plugin/migrate/process/MachineName.php @@ -11,13 +11,28 @@ use Symfony\Component\DependencyInjection\ContainerInterface; /** - * This plugin creates a machine name. + * Creates a machine name. * - * The current value gets transliterated, non-alphanumeric characters removed - * and replaced by an underscore and multiple underscores are collapsed into - * one. + * The machine_name process plugin takes the source value and runs it through + * the transliteration service. This makes the source value lowercase, + * replaces anything that is not a number or a letter with an underscore, + * and removes duplicate underscores. * - * @link https://www.drupal.org/node/2135323 Online handbook documentation for machine_name process plugin @endlink + * Letters will have language decorations and accents removed. + * + * Example: + * + * @code + * process: + * bar: + * plugin: machine_name + * source: foo + * @endcode + * + * If the value of foo in the source is 'áéí!' then the destination value of bar + * will be 'aei_'. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "machine_name" diff --git a/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php b/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php new file mode 100644 index 00000000..a69fa654 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueBase.php @@ -0,0 +1,78 @@ +configuration['postfix']) ? $this->configuration['postfix'] : ''; + $start = isset($this->configuration['start']) ? $this->configuration['start'] : 0; + if (!is_int($start)) { + throw new MigrateException('The start position configuration key should be an integer. Omit this key to capture from the beginning of the string.'); + } + $length = isset($this->configuration['length']) ? $this->configuration['length'] : NULL; + if (!is_null($length) && !is_int($length)) { + throw new MigrateException('The character length configuration key should be an integer. Omit this key to capture the entire string.'); + } + // Use optional start or length to return a portion of the unique value. + $value = Unicode::substr($value, $start, $length); + $new_value = $value; + while ($this->exists($new_value)) { + $new_value = $value . $postfix . $i++; + } + return $new_value; + } + + /** + * This is a query checking the existence of some value. + * + * @param mixed $value + * The value to check. + * + * @return bool + * TRUE if the value exists. + */ + abstract protected function exists($value); + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueEntityField.php b/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueEntityField.php new file mode 100644 index 00000000..75090372 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/MakeUniqueEntityField.php @@ -0,0 +1,149 @@ +migration = $migration; + $this->entityTypeManager = $entity_type_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('entity_type.manager') + ); + } + + /** + * {@inheritdoc} + */ + protected function exists($value) { + // Plugins are cached so for every run we need a new query object. + $query = $this + ->entityTypeManager + ->getStorage($this->configuration['entity_type']) + ->getQuery() + ->condition($this->configuration['field'], $value); + if (!empty($this->configuration['migrated'])) { + // Check if each entity is in the ID map. + $idMap = $this->migration->getIdMap(); + foreach ($query->execute() as $id) { + $dest_id_values[$this->configuration['field']] = $id; + if ($idMap->lookupSourceID($dest_id_values)) { + return TRUE; + } + } + return FALSE; + } + else { + // Just check if any such entity exists. + return $query->count()->execute(); + } + } + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/Migration.php b/core/modules/migrate/src/Plugin/migrate/process/Migration.php index 8520a5ec..ef8ad72c 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Migration.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Migration.php @@ -2,16 +2,8 @@ namespace Drupal\migrate\Plugin\migrate\process; -use Drupal\Core\Plugin\ContainerFactoryPluginInterface; -use Drupal\migrate\MigrateSkipProcessException; -use Drupal\migrate\Plugin\MigratePluginManagerInterface; -use Drupal\migrate\Plugin\MigrationPluginManagerInterface; -use Drupal\migrate\Plugin\MigrateIdMapInterface; -use Drupal\migrate\ProcessPluginBase; -use Drupal\migrate\Plugin\MigrationInterface; -use Drupal\migrate\MigrateExecutableInterface; -use Drupal\migrate\Row; -use Symfony\Component\DependencyInjection\ContainerInterface; +@trigger_error('The ' . __NAMESPACE__ . '\Migration is deprecated in +Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookup', E_USER_DEPRECATED); /** * Calculates the value of a property based on a previous migration. @@ -21,156 +13,8 @@ * @MigrateProcessPlugin( * id = "migration" * ) + * + * @deprecated in Drupal 8.3.x and will be removed in Drupal 9.0.x. + * Use \Drupal\migrate\Plugin\migrate\process\MigrationLookup instead. */ -class Migration extends ProcessPluginBase implements ContainerFactoryPluginInterface { - - /** - * The process plugin manager. - * - * @var \Drupal\migrate\Plugin\MigratePluginManager - */ - protected $processPluginManager; - - /** - * The migration plugin manager. - * - * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface - */ - protected $migrationPluginManager; - - /** - * The migration to be executed. - * - * @var \Drupal\migrate\Plugin\MigrationInterface - */ - protected $migration; - - /** - * {@inheritdoc} - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrationPluginManagerInterface $migration_plugin_manager, MigratePluginManagerInterface $process_plugin_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->migrationPluginManager = $migration_plugin_manager; - $this->migration = $migration; - $this->processPluginManager = $process_plugin_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $migration, - $container->get('plugin.manager.migration'), - $container->get('plugin.manager.migrate.process') - ); - } - - /** - * {@inheritdoc} - */ - public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - $migration_ids = $this->configuration['migration']; - if (!is_array($migration_ids)) { - $migration_ids = array($migration_ids); - } - if (!is_array($value)) { - $value = array($value); - } - $this->skipOnEmpty($value); - $self = FALSE; - /** @var \Drupal\migrate\Plugin\MigrationInterface[] $migrations */ - $destination_ids = NULL; - $source_id_values = array(); - $migrations = $this->migrationPluginManager->createInstances($migration_ids); - foreach ($migrations as $migration_id => $migration) { - if ($migration_id == $this->migration->id()) { - $self = TRUE; - } - if (isset($this->configuration['source_ids'][$migration_id])) { - $configuration = array('source' => $this->configuration['source_ids'][$migration_id]); - $source_id_values[$migration_id] = $this->processPluginManager - ->createInstance('get', $configuration, $this->migration) - ->transform(NULL, $migrate_executable, $row, $destination_property); - } - else { - $source_id_values[$migration_id] = $value; - } - // Break out of the loop as soon as a destination ID is found. - if ($destination_ids = $migration->getIdMap()->lookupDestinationId($source_id_values[$migration_id])) { - break; - } - } - - if (!$destination_ids && !empty($this->configuration['no_stub'])) { - return NULL; - } - - if (!$destination_ids && ($self || isset($this->configuration['stub_id']) || count($migrations) == 1)) { - // If the lookup didn't succeed, figure out which migration will do the - // stubbing. - if ($self) { - $migration = $this->migration; - } - elseif (isset($this->configuration['stub_id'])) { - $migration = $migrations[$this->configuration['stub_id']]; - } - else { - $migration = reset($migrations); - } - $destination_plugin = $migration->getDestinationPlugin(TRUE); - // Only keep the process necessary to produce the destination ID. - $process = $migration->getProcess(); - - // We already have the source ID values but need to key them for the Row - // constructor. - $source_ids = $migration->getSourcePlugin()->getIds(); - $values = array(); - foreach (array_keys($source_ids) as $index => $source_id) { - $values[$source_id] = $source_id_values[$migration->id()][$index]; - } - - $stub_row = new Row($values + $migration->getSourceConfiguration(), $source_ids, TRUE); - - // Do a normal migration with the stub row. - $migrate_executable->processRow($stub_row, $process); - $destination_ids = array(); - try { - $destination_ids = $destination_plugin->import($stub_row); - } - catch (\Exception $e) { - $migration->getIdMap()->saveMessage($stub_row->getSourceIdValues(), $e->getMessage()); - } - - if ($destination_ids) { - $migration->getIdMap()->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE); - } - } - if ($destination_ids) { - if (count($destination_ids) == 1) { - return reset($destination_ids); - } - else { - return $destination_ids; - } - } - } - - /** - * Skips the migration process entirely if the value is FALSE. - * - * @param mixed $value - * The incoming value to transform. - * - * @throws \Drupal\migrate\MigrateSkipProcessException - */ - protected function skipOnEmpty(array $value) { - if (!array_filter($value)) { - throw new MigrateSkipProcessException(); - } - } - -} +class Migration extends MigrationLookup {} diff --git a/core/modules/migrate/src/Plugin/migrate/process/MigrationLookup.php b/core/modules/migrate/src/Plugin/migrate/process/MigrationLookup.php new file mode 100644 index 00000000..5f144a4d --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/MigrationLookup.php @@ -0,0 +1,280 @@ +migrationPluginManager = $migration_plugin_manager; + $this->migration = $migration; + $this->processPluginManager = $process_plugin_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('plugin.manager.migration'), + $container->get('plugin.manager.migrate.process') + ); + } + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + $migration_ids = $this->configuration['migration']; + if (!is_array($migration_ids)) { + $migration_ids = [$migration_ids]; + } + if (!is_array($value)) { + $value = [$value]; + } + $this->skipOnEmpty($value); + $self = FALSE; + /** @var \Drupal\migrate\Plugin\MigrationInterface[] $migrations */ + $destination_ids = NULL; + $source_id_values = []; + $migrations = $this->migrationPluginManager->createInstances($migration_ids); + foreach ($migrations as $migration_id => $migration) { + if ($migration_id == $this->migration->id()) { + $self = TRUE; + } + if (isset($this->configuration['source_ids'][$migration_id])) { + $configuration = ['source' => $this->configuration['source_ids'][$migration_id]]; + $source_id_values[$migration_id] = $this->processPluginManager + ->createInstance('get', $configuration, $this->migration) + ->transform(NULL, $migrate_executable, $row, $destination_property); + } + else { + $source_id_values[$migration_id] = $value; + } + // Break out of the loop as soon as a destination ID is found. + if ($destination_ids = $migration->getIdMap()->lookupDestinationId($source_id_values[$migration_id])) { + break; + } + } + + if (!$destination_ids && !empty($this->configuration['no_stub'])) { + return NULL; + } + + if (!$destination_ids && ($self || isset($this->configuration['stub_id']) || count($migrations) == 1)) { + // If the lookup didn't succeed, figure out which migration will do the + // stubbing. + if ($self) { + $migration = $this->migration; + } + elseif (isset($this->configuration['stub_id'])) { + $migration = $migrations[$this->configuration['stub_id']]; + } + else { + $migration = reset($migrations); + } + $destination_plugin = $migration->getDestinationPlugin(TRUE); + // Only keep the process necessary to produce the destination ID. + $process = $migration->getProcess(); + + // We already have the source ID values but need to key them for the Row + // constructor. + $source_ids = $migration->getSourcePlugin()->getIds(); + $values = []; + foreach (array_keys($source_ids) as $index => $source_id) { + $values[$source_id] = $source_id_values[$migration->id()][$index]; + } + + $stub_row = $this->createStubRow($values + $migration->getSourceConfiguration(), $source_ids); + + // Do a normal migration with the stub row. + $migrate_executable->processRow($stub_row, $process); + $destination_ids = []; + $id_map = $migration->getIdMap(); + try { + $destination_ids = $destination_plugin->import($stub_row); + } + catch (\Exception $e) { + $id_map->saveMessage($stub_row->getSourceIdValues(), $e->getMessage()); + } + + if ($destination_ids) { + $id_map->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE); + } + } + if ($destination_ids) { + if (count($destination_ids) == 1) { + return reset($destination_ids); + } + else { + return $destination_ids; + } + } + } + + /** + * Skips the migration process entirely if the value is FALSE. + * + * @param mixed $value + * The incoming value to transform. + * + * @throws \Drupal\migrate\MigrateSkipProcessException + */ + protected function skipOnEmpty(array $value) { + if (!array_filter($value)) { + throw new MigrateSkipProcessException(); + } + } + + /** + * Create a stub row source for later import as stub data. + * + * This simple wrapper of the Row constructor allows sub-classing plugins to + * have more control over the row. + * + * @param array $values + * An array of values to add as properties on the object. + * @param array $source_ids + * An array containing the IDs of the source using the keys as the field + * names. + * + * @return \Drupal\migrate\Row + * The stub row. + */ + protected function createStubRow(array $values, array $source_ids) { + return new Row($values, $source_ids, TRUE); + } + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/Route.php b/core/modules/migrate/src/Plugin/migrate/process/Route.php index 7ff47204..ebb9a4d6 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Route.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Route.php @@ -11,10 +11,47 @@ use Drupal\migrate\Row; /** + * Sets the destination route information based on the source link_path. * - * @link https://www.drupal.org/node/2750777 Online handbook documentation for route process plugin @endlink + * The source value is an array of two values: + * - link_path: The path or URL of the route. + * - options: An array of URL options, e.g. query string, attributes, etc. * - * * @MigrateProcessPlugin( + * Example: + * + * @code + * process: + * new_route_field: + * plugin: route + * source: + * - 'https://www.drupal.org' + * - + * attributes: + * title: Drupal + * @endcode + * + * This will set new_route_field to be a route with the URL + * "https://www.drupal.org" and title attribute "Drupal". + * + * Example: + * + * @code + * process: + * another_route_field: + * plugin: route + * source: + * - 'user/login' + * - + * query: + * destination: 'node/1' + * @endcode + * + * This will set another_route_field to be a route to the user login page + * (user/login) with a query string of "destination=node/1". + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface + * + * @MigrateProcessPlugin( * id = "route" * ) */ @@ -64,12 +101,12 @@ public function transform($value, MigrateExecutableInterface $migrate_executable } $extracted = $this->pathValidator->getUrlIfValidWithoutAccessCheck($link_path); - $route = array(); + $route = []; if ($extracted) { if ($extracted->isExternal()) { $route['route_name'] = NULL; - $route['route_parameters'] = array(); + $route['route_parameters'] = []; $route['options'] = $options; $route['url'] = $extracted->getUri(); } diff --git a/core/modules/migrate/src/Plugin/migrate/process/SkipOnEmpty.php b/core/modules/migrate/src/Plugin/migrate/process/SkipOnEmpty.php index 28b6df0d..c7d3ad5e 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/SkipOnEmpty.php +++ b/core/modules/migrate/src/Plugin/migrate/process/SkipOnEmpty.php @@ -9,9 +9,52 @@ use Drupal\migrate\MigrateSkipRowException; /** - * If the source evaluates to empty, we skip processing or the whole row. + * Skips processing the current row when the input value is empty. * - * @link https://www.drupal.org/node/2228793 Online handbook documentation for skip_on_empty process plugin @endlink + * The skip_on_empty process plugin checks to see if the current input value + * is empty (empty string, NULL, FALSE, 0, '0', or an empty array). If so, the + * further processing of the property or the entire row (depending on the chosen + * method) is skipped and will not be migrated. + * + * Available configuration keys: + * - method: (optional) What to do if the input value is empty. Possible values: + * - row: Skips the entire row when an empty value is encountered. + * - process: Prevents further processing of the input property when the value + * is empty. + * - message: (optional) A message to be logged in the {migrate_message_*} table + * for this row. Messages are only logged for the 'row' skip level. If not + * set, nothing is logged in the message table. + * + * Examples: + * + * @code + * process: + * field_type_exists: + * plugin: skip_on_empty + * method: row + * source: field_name + * message: 'Field field_name is missed' + * @endcode + * + * If field_name is empty, skips the entire row and the message 'Field + * field_name is missed' is logged in the message table. + * + * @code + * process: + * parent: + * - + * plugin: skip_on_empty + * method: process + * source: parent + * - + * plugin: migration + * migration: d6_taxonomy_term + * @endcode + * + * If parent is empty, any further processing of the property is skipped - thus, + * the next plugin (migration) will not be run. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "skip_on_empty" @@ -20,17 +63,52 @@ class SkipOnEmpty extends ProcessPluginBase { /** - * {@inheritdoc} + * Skips the current row when value is not set. + * + * @param mixed $value + * The input value. + * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable + * The migration in which this process is being executed. + * @param \Drupal\migrate\Row $row + * The row from the source to process. + * @param string $destination_property + * The destination property currently worked on. This is only used together + * with the $row above. + * + * @return mixed + * The input value, $value, if it is not empty. + * + * @throws \Drupal\migrate\MigrateSkipRowException + * Thrown if the source property is not set and the row should be skipped, + * records with STATUS_IGNORED status in the map. */ public function row($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if (!$value) { - throw new MigrateSkipRowException(); + $message = !empty($this->configuration['message']) ? $this->configuration['message'] : ''; + throw new MigrateSkipRowException($message); } return $value; } /** - * {@inheritdoc} + * Stops processing the current property when value is not set. + * + * @param mixed $value + * The input value. + * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable + * The migration in which this process is being executed. + * @param \Drupal\migrate\Row $row + * The row from the source to process. + * @param string $destination_property + * The destination property currently worked on. This is only used together + * with the $row above. + * + * @return mixed + * The input value, $value, if it is not empty. + * + * @throws \Drupal\migrate\MigrateSkipProcessException + * Thrown if the source property is not set and rest of the process should + * be skipped. */ public function process($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if (!$value) { diff --git a/core/modules/migrate/src/Plugin/migrate/process/SkipRowIfNotSet.php b/core/modules/migrate/src/Plugin/migrate/process/SkipRowIfNotSet.php index a6cffceb..fa9b3f61 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/SkipRowIfNotSet.php +++ b/core/modules/migrate/src/Plugin/migrate/process/SkipRowIfNotSet.php @@ -8,9 +8,34 @@ use Drupal\migrate\MigrateSkipRowException; /** - * If the source evaluates to empty, we skip the current row. + * Skips processing the current row when a source value is not set. * - * @link https://www.drupal.org/node/2345935 Online handbook documentation for skip_row_if_not_set process plugin @endlink + * The skip_row_if_not_set process plugin checks whether a value is set. If the + * value is set, it is returned. Otherwise, a MigrateSkipRowException + * is thrown. + * + * Available configuration keys: + * - index: The source property to check for. + * - message: (optional) A message to be logged in the {migrate_message_*} table + * for this row. If not set, nothing is logged in the message table. + * + * Example: + * + * @code + * process: + * settings: + * # Check if the "contact" key exists in the "data" array. + * plugin: skip_row_if_not_set + * index: contact + * source: data + * message: "Missed the 'data' key" + * @endcode + * + * This will return $data['contact'] if it exists. Otherwise, the row will be + * skipped and the message "Missed the 'data' key" will be logged in the + * message table. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "skip_row_if_not_set", @@ -24,7 +49,8 @@ class SkipRowIfNotSet extends ProcessPluginBase { */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if (!isset($value[$this->configuration['index']])) { - throw new MigrateSkipRowException(); + $message = !empty($this->configuration['message']) ? $this->configuration['message'] : ''; + throw new MigrateSkipRowException($message); } return $value[$this->configuration['index']]; } diff --git a/core/modules/migrate/src/Plugin/migrate/process/StaticMap.php b/core/modules/migrate/src/Plugin/migrate/process/StaticMap.php index 769da3b7..1d68f357 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/StaticMap.php +++ b/core/modules/migrate/src/Plugin/migrate/process/StaticMap.php @@ -10,9 +10,98 @@ use Drupal\migrate\MigrateSkipRowException; /** - * This plugin changes the current value based on a static lookup map. + * Changes the source value based on a static lookup map. * - * @link https://www.drupal.org/node/2143521 Online handbook documentation for static_map process plugin @endlink + * Maps the input value to another value using an associative array specified in + * the configuration. + * + * Available configuration keys: + * - source: The input value - either a scalar or an array. + * - map: An array (of 1 or more dimensions) that identifies the mapping between + * source values and destination values. + * - bypass: (optional) Whether the plugin should proceed when the source is not + * found in the map array. Defaults to FALSE. + * - TRUE: Return the unmodified input value, or another default value, if one + * is specified. + * - FALSE: Throw a MigrateSkipRowException. + * - default_value: (optional) The value to return if the source is not found in + * the map array. + * + * Examples: + * + * @code + * process: + * bar: + * plugin: static_map + * source: foo + * map: + * from: to + * this: that + * @endcode + * + * If the value of the source property foo was "from" then the value of the + * destination property bar will be "to". Similarly "this" becomes "that". + * static_map can do a lot more than this: it supports a list of source + * properties. This is super useful in module-delta to machine name conversions. + * + * @code + * process: + * id: + * plugin: static_map + * source: + * - module + * - delta + * map: + * filter: + * 0: filter_html_escape + * 1: filter_autop + * 2: filter_url + * 3: filter_htmlcorrector + * 4: filter_html_escape + * php: + * 0: php_code + * @endcode + * + * If the value of the source properties module and delta are "filter" and "2" + * respectively, then the returned value will be "filter_url". By default, if a + * value is not found in the map, an exception is thrown. + * + * When static_map is used to just rename a few things and leave the others, a + * "bypass: true" option can be added. In this case, the source value is used + * unchanged, e.g.: + * + * @code + * process: + * bar: + * plugin: static_map + * source: foo + * map: + * from: to + * this: that + * bypass: TRUE + * @endcode + * + * If the value of the source property "foo" is "from" then the returned value + * will be "to", but if the value of "foo" is "another" (a value that is not in + * the map) then the source value is used unchanged so the returned value will + * be "from" because "bypass" is set to TRUE. + * + * @code + * process: + * bar: + * plugin: static_map + * source: foo + * map: + * from: to + * this: that + * default_value: bar + * @endcode + * + * If the value of the source property "foo" is "yet_another" (a value that is + * not in the map) then the default_value is used so the returned value will + * be "bar". + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "static_map" @@ -31,7 +120,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable } } else { - $new_value = array($value); + $new_value = [$value]; } $new_value = NestedArray::getValue($this->configuration['map'], $new_value, $key_exists); if (!$key_exists) { diff --git a/core/modules/migrate/src/Plugin/migrate/process/SubProcess.php b/core/modules/migrate/src/Plugin/migrate/process/SubProcess.php new file mode 100644 index 00000000..5d999555 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/SubProcess.php @@ -0,0 +1,166 @@ + Array + * ( + * [0] => Array + * ( + * [fid] => 1 + * [list] => 0 + * [description] => "File number 1" + * ) + * [1] => Array + * ( + * [fid] => 2 + * [list] => 1 + * [description] => "File number 2" + * ) + * ) + * ) + * ... + * @endcode + * + * The sub_process process plugin will take these arrays one at a time and run + * its own process over each one: + * + * @code + * process: + * upload: + * plugin: sub_process + * source: upload + * process: + * target_id: + * plugin: migration_lookup + * migration: d6_file + * source: fid + * display: list + * description: description + * @endcode + * + * In this case, each item in the upload array will be processed by the + * sub_process process plugin. The target_id will be found by looking up the + * destination value from a previous migration. The display and description + * fields will simply be mapped. + * + * In the next example, normally the array returned from sub_process will have + * its original keys. If you need to change the key, it is possible for the + * returned array to be keyed by one of the transformed values in the sub-array. + * + * @code + * source: Array + * ( + * [format] => 1 + * [name] => Filtered HTML + * ... + * [filters] => Array + * ( + * [0] => Array + * ( + * [module] => filter + * [delta] => 2 + * [weight] => 0 + * ) + * [1] => Array + * ( + * [module] => filter + * [delta] => 0 + * [weight] => 1 + * ) + * ) + * ) + * ... + * + * process: + * filters: + * plugin: iterator + * source: filters + * key: "@id" + * process: + * id: + * plugin: concat + * source: + * - module + * - delta + * delimiter: _ + * @endcode + * + * In the above example, the keys of the returned array would be filter_2 and + * filter_0 + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface + * + * @MigrateProcessPlugin( + * id = "sub_process", + * handle_multiples = TRUE + * ) + */ +class SubProcess extends ProcessPluginBase { + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + $return = []; + if (is_array($value) || $value instanceof \Traversable) { + foreach ($value as $key => $new_value) { + $new_row = new Row($new_value, []); + $migrate_executable->processRow($new_row, $this->configuration['process']); + $destination = $new_row->getDestination(); + if (array_key_exists('key', $this->configuration)) { + $key = $this->transformKey($key, $migrate_executable, $new_row); + } + $return[$key] = $destination; + } + } + return $return; + } + + /** + * Runs the process pipeline for the key to determine its dynamic name. + * + * @param string|int $key + * The current key. + * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable + * The migrate executable helper class. + * @param \Drupal\migrate\Row $row + * The current row after processing. + * + * @return mixed + * The transformed key. + */ + protected function transformKey($key, MigrateExecutableInterface $migrate_executable, Row $row) { + $process = ['key' => $this->configuration['key']]; + $migrate_executable->processRow($row, $process, $key); + return $row->getDestinationProperty('key'); + } + + /** + * {@inheritdoc} + */ + public function multiple() { + return TRUE; + } + +} diff --git a/core/modules/migrate/src/Plugin/migrate/process/Substr.php b/core/modules/migrate/src/Plugin/migrate/process/Substr.php index 8ebc98c6..1f852a92 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Substr.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Substr.php @@ -9,9 +9,44 @@ use Drupal\Component\Utility\Unicode; /** - * This plugin returns a substring of the current value. + * Returns a substring of the input value. * - * @link https://www.drupal.org/node/2771965 Online handbook documentation for substr process plugin @endlink + * The substr process plugin returns the portion of the input value specified by + * the start and length parameters. This is a wrapper around the PHP substr() + * function. + * + * Available configuration keys: + * - start: (optional) The returned string will start this many characters after + * the beginning of the string. Defaults to NULL. + * - length: (optional) The maximum number of characters in the returned + * string. Defaults to NULL. + * + * If start is NULL and length is an integer, the start position is the + * beginning of the string. If start is an integer and length is NULL, the + * substring starting from the start position until the end of the string will + * be returned. If both start and length are NULL the entire string is returned. + * + * Example: + * + * @code + * process: + * new_text_field: + * plugin: substr + * source: some_text_field + * start: 6 + * length: 10 + * @endcode + * + * If some_text_field was 'Marie SkÅ‚odowska Curie' then + * $destination['new_text_field'] would be 'SkÅ‚odowska'. + * + * The PHP equivalent of this is: + * + * @code + * $destination['new_text_field'] = substr($source['some_text_field'], 6, 10); + * @endcode + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "substr" diff --git a/core/modules/migrate/src/Plugin/migrate/process/UrlEncode.php b/core/modules/migrate/src/Plugin/migrate/process/UrlEncode.php index b2c0d08e..4e385602 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/UrlEncode.php +++ b/core/modules/migrate/src/Plugin/migrate/process/UrlEncode.php @@ -9,10 +9,21 @@ use GuzzleHttp\Psr7\Uri; /** - * Apply urlencoding to a URI. + * URL-encodes the input value. * - * This is needed when the URI is to be opened by a later migration stage, and - * the source URI value is not already encoded. + * Example: + * + * @code + * process: + * new_url: + * plugin: urlencode + * source: 'http://example.com/a url with spaces.html' + * @endcode + * + * This will convert the source URL 'http://example.com/a url with spaces.html' + * into 'http://example.com/a%20url%20with%20spaces.html'. + * + * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( * id = "urlencode" @@ -33,7 +44,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable throw new MigrateException("Value '$value' is not a valid URL"); } // Iterate over specific pieces of the URL rawurlencoding each one. - $url_parts_to_encode = array('path', 'query', 'fragment'); + $url_parts_to_encode = ['path', 'query', 'fragment']; foreach ($parsed_url as $parsed_url_key => $parsed_url_value) { if (in_array($parsed_url_key, $url_parts_to_encode)) { // urlencode() would convert spaces to + signs. diff --git a/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php b/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php index 05be56da..8cee6ddb 100644 --- a/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php +++ b/core/modules/migrate/src/Plugin/migrate/source/EmbeddedDataSource.php @@ -1,10 +1,41 @@ t('ID'), - ); + ]; } /** * {@inheritdoc} */ public function initializeIterator() { - return new \ArrayIterator(array(array('id' => ''))); + return new \ArrayIterator([['id' => '']]); } /** diff --git a/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php b/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php index 5ce5fd39..429a1457 100644 --- a/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php +++ b/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php @@ -13,7 +13,49 @@ use Drupal\migrate\Row; /** - * The base class for all source plugins. + * The base class for source plugins. + * + * Available configuration keys: + * - cache_counts: (optional) If set, cache the source count. + * - skip_count: (optional) If set, do not attempt to count the source. + * - track_changes: (optional) If set, track changes to incoming data. + * - high_water_property: (optional) It is an array of name & alias values + * (optional table alias). This high_water_property is typically a timestamp + * or serial id showing what was the last imported record. Only content with a + * higher value will be imported. + * + * The high_water_property and track_changes are mutually exclusive. + * + * Example: + * + * @code + * source: + * plugin: some_source_plugin_name + * cache_counts: true + * track_changes: true + * @endcode + * + * This example uses the plugin "some_source_plugin_name" and caches the count + * of available source records to save calculating it every time count() is + * called. Changes to incoming data are watched (because track_changes is true), + * which can affect the result of prepareRow(). + * + * Example: + * + * @code + * source: + * plugin: some_source_plugin_name + * skip_count: true + * high_water_property: + * name: changed + * alias: n + * @endcode + * + * In this example, skip_count is true which means count() will not attempt to + * count the available source records, but just always return -1 instead. The + * high_water_property defines which field marks the last imported row of the + * migration. This will get converted into a SQL condition that looks like + * 'n.changed' or 'changed' if no alias. * * @see \Drupal\migrate\Plugin\MigratePluginManager * @see \Drupal\migrate\Annotation\MigrateSource @@ -177,7 +219,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition * @return array * An array of the data for this source. */ - protected abstract function initializeIterator(); + abstract protected function initializeIterator(); /** * Gets the module handler. @@ -198,8 +240,8 @@ protected function getModuleHandler() { public function prepareRow(Row $row) { $result = TRUE; try { - $result_hook = $this->getModuleHandler()->invokeAll('migrate_prepare_row', array($row, $this, $this->migration)); - $result_named_hook = $this->getModuleHandler()->invokeAll('migrate_' . $this->migration->id() . '_prepare_row', array($row, $this, $this->migration)); + $result_hook = $this->getModuleHandler()->invokeAll('migrate_prepare_row', [$row, $this, $this->migration]); + $result_named_hook = $this->getModuleHandler()->invokeAll('migrate_' . $this->migration->id() . '_prepare_row', [$row, $this, $this->migration]); // We will skip if any hook returned FALSE. $skip = ($result_hook && in_array(FALSE, $result_hook)) || ($result_named_hook && in_array(FALSE, $result_named_hook)); $save_to_map = TRUE; @@ -217,7 +259,7 @@ public function prepareRow(Row $row) { // Make sure we replace any previous messages for this item with any // new ones. if ($save_to_map) { - $this->idMap->saveIdMapping($row, array(), MigrateIdMapInterface::STATUS_IGNORED); + $this->idMap->saveIdMapping($row, [], MigrateIdMapInterface::STATUS_IGNORED); $this->currentRow = NULL; $this->currentSourceIds = NULL; } @@ -256,7 +298,7 @@ public function current() { /** * Gets the iterator key. * - * Implementation of Iterator::key - called when entering a loop iteration, + * Implementation of \Iterator::key() - called when entering a loop iteration, * returning the key of the current row. It must be a scalar - we will * serialize to fulfill the requirement, but using getCurrentIds() is * preferable. @@ -268,7 +310,7 @@ public function key() { /** * Checks whether the iterator is currently valid. * - * Implementation of Iterator::valid() - called at the top of the loop, + * Implementation of \Iterator::valid() - called at the top of the loop, * returning TRUE to process the loop and FALSE to terminate it. */ public function valid() { @@ -278,9 +320,9 @@ public function valid() { /** * Rewinds the iterator. * - * Implementation of Iterator::rewind() - subclasses of MigrateSource should - * implement performRewind() to do any class-specific setup for iterating - * source records. + * Implementation of \Iterator::rewind() - subclasses of SourcePluginBase + * should implement initializeIterator() to do any class-specific setup for + * iterating source records. */ public function rewind() { $this->getIterator()->rewind(); @@ -541,4 +583,17 @@ public function postRollback(MigrateRollbackEvent $event) { $this->saveHighWater(NULL); } + /** + * {@inheritdoc} + */ + public function getSourceModule() { + if (!empty($this->configuration['source_module'])) { + return $this->configuration['source_module']; + } + elseif (!empty($this->pluginDefinition['source_module'])) { + return $this->pluginDefinition['source_module']; + } + return NULL; + } + } diff --git a/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php b/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php index ee434514..881e2fbc 100644 --- a/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php +++ b/core/modules/migrate/src/Plugin/migrate/source/SqlBase.php @@ -2,25 +2,52 @@ namespace Drupal\migrate\Plugin\migrate\source; +use Drupal\Core\Database\ConnectionNotDefinedException; use Drupal\Core\Database\Database; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\State\StateInterface; +use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\migrate\id_map\Sql; use Drupal\migrate\Plugin\MigrateIdMapInterface; +use Drupal\migrate\Plugin\RequirementsInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Sources whose data may be fetched via DBTNG. + * Sources whose data may be fetched via a database connection. * - * By default, an existing database connection with key 'migrate' and target - * 'default' is used. These may be overridden with explicit 'key' and/or - * 'target' configuration keys. In addition, if the configuration key 'database' - * is present, it is used as a database connection information array to define - * the connection. + * Database configuration, which may appear either within the source plugin + * configuration or in state, is structured as follows: + * + * 'key' - The database key name (defaults to 'migrate'). + * 'target' - The database target name (defaults to 'default'). + * 'database' - Database connection information as accepted by + * Database::addConnectionInfo(). If not present, the key/target is assumed + * to already be defined (e.g., in settings.php). + * + * This configuration info is obtained in the following order: + * + * 1. If the source plugin configuration contains a key 'database_state_key', + * its value is taken as the name of a state key which contains an array + * with the above database configuration. + * 2. Otherwise, if the source plugin configuration contains 'key', the above + * database configuration is obtained directly from the plugin configuration. + * 3. Otherwise, if the state 'migrate.fallback_state_key' exists, its value is + * taken as the name of a state key which contains an array with the above + * database configuration. + * 4. Otherwise, if a connection named 'migrate' exists, that is used as the + * database connection. + * 5. Otherwise, RequirementsException is thrown. + * + * It is strongly recommended that database connections be explicitly defined + * via 'database_state_key' or in the source plugin configuration. Defining + * migrate.fallback_state_key or a 'migrate' connection affects not only any + * migrations intended to use that particular connection, but all + * SqlBase-derived source plugins which do not have explicit database + * configuration. */ -abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPluginInterface { +abstract class SqlBase extends SourcePluginBase implements ContainerFactoryPluginInterface, RequirementsInterface { /** * The query string. @@ -98,16 +125,21 @@ public function __toString() { */ public function getDatabase() { if (!isset($this->database)) { - // See if the database info is in state - if not, fallback to - // configuration. + // Look first for an explicit state key containing the configuration. if (isset($this->configuration['database_state_key'])) { $this->database = $this->setUpDatabase($this->state->get($this->configuration['database_state_key'])); } + // Next, use explicit configuration in the source plugin. + elseif (isset($this->configuration['key'])) { + $this->database = $this->setUpDatabase($this->configuration); + } + // Next, try falling back to the global state key. elseif (($fallback_state_key = $this->state->get('migrate.fallback_state_key'))) { $this->database = $this->setUpDatabase($this->state->get($fallback_state_key)); } + // If all else fails, let setUpDatabase() fallback to the 'migrate' key. else { - $this->database = $this->setUpDatabase($this->configuration); + $this->database = $this->setUpDatabase([]); } } return $this->database; @@ -127,12 +159,17 @@ public function getDatabase() { * * @return \Drupal\Core\Database\Connection * The connection to use for this plugin's queries. + * + * @throws \Drupal\migrate\Exception\RequirementsException + * Thrown if no source database connection is configured. */ protected function setUpDatabase(array $database_info) { if (isset($database_info['key'])) { $key = $database_info['key']; } else { + // If there is no explicit database configuration at all, fall back to a + // connection named 'migrate'. $key = 'migrate'; } if (isset($database_info['target'])) { @@ -144,13 +181,35 @@ protected function setUpDatabase(array $database_info) { if (isset($database_info['database'])) { Database::addConnectionInfo($key, $target, $database_info['database']); } - return Database::getConnection($target, $key); + try { + $connection = Database::getConnection($target, $key); + } + catch (ConnectionNotDefinedException $e) { + // If we fell back to the magic 'migrate' connection and it doesn't exist, + // treat the lack of the connection as a RequirementsException. + if ($key == 'migrate') { + throw new RequirementsException("No database connection configured for source plugin " . $this->pluginId, [], 0, $e); + } + else { + throw $e; + } + } + return $connection; + } + + /** + * {@inheritdoc} + */ + public function checkRequirements() { + if ($this->pluginDefinition['requirements_met'] === TRUE) { + $this->getDatabase(); + } } /** * Wrapper for database select. */ - protected function select($table, $alias = NULL, array $options = array()) { + protected function select($table, $alias = NULL, array $options = []) { $options['fetch'] = \PDO::FETCH_ASSOC; return $this->getDatabase()->select($table, $alias, $options); } @@ -171,10 +230,7 @@ protected function prepareQuery() { } /** - * Implementation of MigrateSource::performRewind(). - * - * We could simply execute the query and be functionally correct, but - * we will take advantage of the PDO-based API to optimize the query up-front. + * {@inheritdoc} */ protected function initializeIterator() { // Initialize the batch size. @@ -193,7 +249,7 @@ protected function initializeIterator() { $this->prepareQuery(); // Get the key values, for potential use in joining to the map table. - $keys = array(); + $keys = []; // The rules for determining what conditions to add to the query are as // follows (applying first applicable rule): @@ -207,6 +263,7 @@ protected function initializeIterator() { // OR above high water). $conditions = $this->query->orConditionGroup(); $condition_added = FALSE; + $added_fields = []; if (empty($this->configuration['ignore_map']) && $this->mapJoinable()) { // Build the join to the map table. Because the source key could have // multiple fields, we need to build things up. @@ -232,25 +289,44 @@ protected function initializeIterator() { for ($count = 1; $count <= $n; $count++) { $map_key = 'sourceid' . $count; $this->query->addField($alias, $map_key, "migrate_map_$map_key"); + $added_fields[] = "$alias.$map_key"; } if ($n = count($this->migration->getDestinationIds())) { for ($count = 1; $count <= $n; $count++) { $map_key = 'destid' . $count++; $this->query->addField($alias, $map_key, "migrate_map_$map_key"); + $added_fields[] = "$alias.$map_key"; } } $this->query->addField($alias, 'source_row_status', 'migrate_map_source_row_status'); + $added_fields[] = "$alias.source_row_status"; } // 2. If we are using high water marks, also include rows above the mark. // But, include all rows if the high water mark is not set. - if ($this->getHighWaterProperty() && ($high_water = $this->getHighWater()) !== '') { + if ($this->getHighWaterProperty()) { $high_water_field = $this->getHighWaterField(); - $conditions->condition($high_water_field, $high_water, '>'); + $high_water = $this->getHighWater(); + if ($high_water) { + $conditions->condition($high_water_field, $high_water, '>'); + $condition_added = TRUE; + } + // Always sort by the high water field, to ensure that the first run + // (before we have a high water value) also has the results in a + // consistent order. $this->query->orderBy($high_water_field); } if ($condition_added) { $this->query->condition($conditions); } + // If the query has a group by, our added fields need it too, to keep the + // query valid. + // @see https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html + $group_by = $this->query->getGroupBy(); + if ($group_by && $added_fields) { + foreach ($added_fields as $added_field) { + $this->query->groupBy($added_field); + } + } } // Download data in batches for performance. @@ -329,7 +405,15 @@ protected function mapJoinable() { return FALSE; } - foreach (array('username', 'password', 'host', 'port', 'namespace', 'driver') as $key) { + // FALSE if driver is PostgreSQL and database doesn't match. + if ($id_map_database_options['driver'] === 'pgsql' && + $source_database_options['driver'] === 'pgsql' && + $id_map_database_options['database'] != $source_database_options['database'] + ) { + return FALSE; + } + + foreach (['username', 'password', 'host', 'port', 'namespace', 'driver'] as $key) { if (isset($source_database_options[$key])) { if ($id_map_database_options[$key] != $source_database_options[$key]) { return FALSE; diff --git a/core/modules/migrate/src/Row.php b/core/modules/migrate/src/Row.php index ea70acdf..83e97b13 100644 --- a/core/modules/migrate/src/Row.php +++ b/core/modules/migrate/src/Row.php @@ -15,21 +15,21 @@ class Row { * * @var array */ - protected $source = array(); + protected $source = []; /** * The source identifiers. * * @var array */ - protected $sourceIds = array(); + protected $sourceIds = []; /** * The destination values. * * @var array */ - protected $destination = array(); + protected $destination = []; /** * Level separator of destination and source properties. @@ -41,11 +41,11 @@ class Row { * * @var array */ - protected $idMap = array( + protected $idMap = [ 'original_hash' => '', 'hash' => '', 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, - ); + ]; /** * Whether the source has been frozen already. @@ -77,6 +77,13 @@ class Row { */ protected $isStub = FALSE; + /** + * The empty destination properties. + * + * @var array + */ + protected $emptyDestinationProperties = []; + /** * Constructs a \Drupal\Migrate\Row object. * @@ -106,10 +113,11 @@ public function __construct(array $values = [], array $source_ids = [], $is_stub * Retrieves the values of the source identifiers. * * @return array - * An array containing the values of the source identifiers. + * An array containing the values of the source identifiers. Returns values + * in the same order as defined in $this->sourceIds. */ public function getSourceIdValues() { - return array_intersect_key($this->source, $this->sourceIds); + return array_merge($this->sourceIds, array_intersect_key($this->source, $this->sourceIds)); } /** @@ -228,6 +236,26 @@ public function removeDestinationProperty($property) { NestedArray::unsetValue($this->destination, explode(static::PROPERTY_SEPARATOR, $property)); } + /** + * Sets a destination to be empty. + * + * @param string $property + * The destination property. + */ + public function setEmptyDestinationProperty($property) { + $this->emptyDestinationProperties[] = $property; + } + + /** + * Gets the empty destination properties. + * + * @return array + * An array of destination properties. + */ + public function getEmptyDestinationProperties() { + return $this->emptyDestinationProperties; + } + /** * Returns the whole destination array. * diff --git a/core/modules/migrate/tests/modules/migrate_entity_test/migrate_entity_test.info.yml b/core/modules/migrate/tests/modules/migrate_entity_test/migrate_entity_test.info.yml index d2c93f3c..1a3c41e1 100644 --- a/core/modules/migrate/tests/modules/migrate_entity_test/migrate_entity_test.info.yml +++ b/core/modules/migrate/tests/modules/migrate_entity_test/migrate_entity_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate/tests/modules/migrate_events_test/migrate_events_test.info.yml b/core/modules/migrate/tests/modules/migrate_events_test/migrate_events_test.info.yml index 203ffff7..d426d806 100644 --- a/core/modules/migrate/tests/modules/migrate_events_test/migrate_events_test.info.yml +++ b/core/modules/migrate/tests/modules/migrate_events_test/migrate_events_test.info.yml @@ -4,8 +4,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php b/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php index 45420d3d..415d000b 100644 --- a/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php +++ b/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/destination/DummyDestination.php @@ -32,7 +32,7 @@ public function fields(MigrationInterface $migration = NULL) { /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { return ['value' => $row->getDestinationProperty('value')]; } diff --git a/core/modules/migrate/tests/modules/migrate_external_translated_test/migrate_external_translated_test.info.yml b/core/modules/migrate/tests/modules/migrate_external_translated_test/migrate_external_translated_test.info.yml index b0a2c50b..b0ecf4f1 100644 --- a/core/modules/migrate/tests/modules/migrate_external_translated_test/migrate_external_translated_test.info.yml +++ b/core/modules/migrate/tests/modules/migrate_external_translated_test/migrate_external_translated_test.info.yml @@ -7,8 +7,8 @@ dependencies: - node - migrate -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate/tests/modules/migrate_external_translated_test/migrations/migrate.migration.external_translated_test_node_translation.yml b/core/modules/migrate/tests/modules/migrate_external_translated_test/migrations/migrate.migration.external_translated_test_node_translation.yml index ff29084f..0363aa20 100644 --- a/core/modules/migrate/tests/modules/migrate_external_translated_test/migrations/migrate.migration.external_translated_test_node_translation.yml +++ b/core/modules/migrate/tests/modules/migrate_external_translated_test/migrations/migrate.migration.external_translated_test_node_translation.yml @@ -7,7 +7,7 @@ source: type: external_test process: nid: - plugin: migration + plugin: migration_lookup source: name migration: external_translated_test_node type: constants/type diff --git a/core/modules/migrate/tests/modules/migrate_external_translated_test/src/Plugin/migrate/source/MigrateExternalTranslatedTestSource.php b/core/modules/migrate/tests/modules/migrate_external_translated_test/src/Plugin/migrate/source/MigrateExternalTranslatedTestSource.php index ceda6d82..8edaeccd 100644 --- a/core/modules/migrate/tests/modules/migrate_external_translated_test/src/Plugin/migrate/source/MigrateExternalTranslatedTestSource.php +++ b/core/modules/migrate/tests/modules/migrate_external_translated_test/src/Plugin/migrate/source/MigrateExternalTranslatedTestSource.php @@ -8,7 +8,8 @@ * A simple migrate source for our tests. * * @MigrateSource( - * id = "migrate_external_translated_test" + * id = "migrate_external_translated_test", + * source_module = "migrate_external_translated_test" * ) */ class MigrateExternalTranslatedTestSource extends SourcePluginBase { diff --git a/core/modules/migrate/tests/modules/migrate_high_water_test/migrate_high_water_test.info.yml b/core/modules/migrate/tests/modules/migrate_high_water_test/migrate_high_water_test.info.yml new file mode 100644 index 00000000..6064932a --- /dev/null +++ b/core/modules/migrate/tests/modules/migrate_high_water_test/migrate_high_water_test.info.yml @@ -0,0 +1,13 @@ +type: module +name: Migration High Water Test +description: 'Provides test fixtures for testing high water marks.' +package: Testing +# core: 8.x +dependencies: + - migrate + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/migrate/tests/modules/migrate_high_water_test/migrate_sql_test.info.yml b/core/modules/migrate/tests/modules/migrate_high_water_test/migrate_sql_test.info.yml deleted file mode 100644 index 950e0e40..00000000 --- a/core/modules/migrate/tests/modules/migrate_high_water_test/migrate_sql_test.info.yml +++ /dev/null @@ -1,13 +0,0 @@ -type: module -name: Migrate SQL Source test -description: 'Provides a database table and records for SQL import testing.' -package: Testing -# core: 8.x -dependencies: - - migrate - -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' -core: '8.x' -project: 'drupal' -datestamp: 1485975642 diff --git a/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php b/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php index c4af3362..601bbd94 100644 --- a/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php +++ b/core/modules/migrate/tests/modules/migrate_high_water_test/src/Plugin/migrate/source/HighWaterTest.php @@ -1,6 +1,6 @@ fields()); $query = $this ->select('high_water_node', 'm') - ->fields('m', array_keys($this->fields())); + ->fields('m', $field_names); + foreach ($field_names as $field_name) { + $query->groupBy($field_name); + } return $query; } diff --git a/core/modules/migrate/tests/modules/migrate_prepare_row_test/migrate_prepare_row_test.info.yml b/core/modules/migrate/tests/modules/migrate_prepare_row_test/migrate_prepare_row_test.info.yml index 3b3f3990..a2b09532 100644 --- a/core/modules/migrate/tests/modules/migrate_prepare_row_test/migrate_prepare_row_test.info.yml +++ b/core/modules/migrate/tests/modules/migrate_prepare_row_test/migrate_prepare_row_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate/tests/modules/migrate_query_batch_test/migrate_query_batch_test.info.yml b/core/modules/migrate/tests/modules/migrate_query_batch_test/migrate_query_batch_test.info.yml index 2c3c98a7..69ad954e 100644 --- a/core/modules/migrate/tests/modules/migrate_query_batch_test/migrate_query_batch_test.info.yml +++ b/core/modules/migrate/tests/modules/migrate_query_batch_test/migrate_query_batch_test.info.yml @@ -6,8 +6,8 @@ package: Testing dependencies: - migrate -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate/tests/src/Kernel/HighWaterNotJoinableTest.php b/core/modules/migrate/tests/src/Kernel/HighWaterNotJoinableTest.php new file mode 100644 index 00000000..41985790 --- /dev/null +++ b/core/modules/migrate/tests/src/Kernel/HighWaterNotJoinableTest.php @@ -0,0 +1,117 @@ + 1, + 'title' => 'Item 1', + 'changed' => 1, + ], + [ + 'id' => 2, + 'title' => 'Item 2', + 'changed' => 2, + ], + [ + 'id' => 3, + 'title' => 'Item 3', + 'changed' => 3, + ], + ]; + + // The expected results. + $tests[0]['expected_data'] = [ + [ + 'id' => 2, + 'title' => 'Item 2', + 'changed' => 2, + ], + [ + 'id' => 3, + 'title' => 'Item 3', + 'changed' => 3, + ], + ]; + + // The expected count is the count returned by the query before the query + // is modified by SqlBase::initializeIterator(). + $tests[0]['expected_count'] = 3; + $tests[0]['configuration'] = [ + 'high_water_property' => [ + 'name' => 'changed', + ], + ]; + $tests[0]['high_water'] = $tests[0]['source_data']['high_water_node'][0]['changed']; + + // Test high water initialized to NULL. + $tests[1]['source_data'] = $tests[0]['source_data']; + $tests[1]['expected_data'] = [ + [ + 'id' => 1, + 'title' => 'Item 1', + 'changed' => 1, + ], + [ + 'id' => 2, + 'title' => 'Item 2', + 'changed' => 2, + ], + [ + 'id' => 3, + 'title' => 'Item 3', + 'changed' => 3, + ], + ]; + $tests[1]['expected_count'] = $tests[0]['expected_count']; + $tests[1]['configuration'] = $tests[0]['configuration']; + $tests[1]['high_water'] = NULL; + + // Test high water initialized to an empty string. + $tests[2]['source_data'] = $tests[0]['source_data']; + $tests[2]['expected_data'] = [ + [ + 'id' => 1, + 'title' => 'Item 1', + 'changed' => 1, + ], + [ + 'id' => 2, + 'title' => 'Item 2', + 'changed' => 2, + ], + [ + 'id' => 3, + 'title' => 'Item 3', + 'changed' => 3, + ], + ]; + $tests[2]['expected_count'] = $tests[0]['expected_count']; + $tests[2]['configuration'] = $tests[0]['configuration']; + $tests[2]['high_water'] = ''; + + return $tests; + } + +} diff --git a/core/modules/migrate/tests/src/Kernel/HighWaterTest.php b/core/modules/migrate/tests/src/Kernel/HighWaterTest.php index 0b6d3688..faffb663 100644 --- a/core/modules/migrate/tests/src/Kernel/HighWaterTest.php +++ b/core/modules/migrate/tests/src/Kernel/HighWaterTest.php @@ -17,7 +17,7 @@ class HighWaterTest extends MigrateTestBase { 'user', 'node', 'migrate', - 'migrate_sql_test', + 'migrate_high_water_test', 'field', ]; @@ -136,6 +136,64 @@ public function testHighWater() { $this->assertNodeDoesNotExist('Item 3'); } + /** + * Tests high water property of SqlBase when rows marked for update. + */ + public function testHighWaterUpdate() { + // Assert all of the nodes have been imported. + $this->assertNodeExists('Item 1'); + $this->assertNodeExists('Item 2'); + $this->assertNodeExists('Item 3'); + + // Update Item 1 setting its high_water_property to value that is below + // current high water mark. + $this->sourceDatabase->update('high_water_node') + ->fields([ + 'title' => 'Item 1 updated', + 'changed' => 2, + ]) + ->condition('title', 'Item 1') + ->execute(); + + // Update Item 2 setting its high_water_property to value equal to + // current high water mark. + $this->sourceDatabase->update('high_water_node') + ->fields([ + 'title' => 'Item 2 updated', + 'changed' => 3, + ]) + ->condition('title', 'Item 2') + ->execute(); + + // Update Item 3 setting its high_water_property to value that is above + // current high water mark. + $this->sourceDatabase->update('high_water_node') + ->fields([ + 'title' => 'Item 3 updated', + 'changed' => 4, + ]) + ->condition('title', 'Item 3') + ->execute(); + + // Set all rows as needing an update. + $id_map = $this->getMigration('high_water_test')->getIdMap(); + $id_map->prepareUpdate(); + + $this->executeMigration('high_water_test'); + + // Item with lower highwater should be updated. + $this->assertNodeExists('Item 1 updated'); + $this->assertNodeDoesNotExist('Item 1'); + + // Item with equal highwater should be updated. + $this->assertNodeExists('Item 2 updated'); + $this->assertNodeDoesNotExist('Item 2'); + + // Item with greater highwater should be updated. + $this->assertNodeExists('Item 3 updated'); + $this->assertNodeDoesNotExist('Item 3'); + } + /** * Assert that node with given title exists. * diff --git a/core/modules/migrate/tests/src/Kernel/MigrateBundleTest.php b/core/modules/migrate/tests/src/Kernel/MigrateBundleTest.php index 74632959..780cce84 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateBundleTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateBundleTest.php @@ -18,13 +18,14 @@ class MigrateBundleTest extends MigrateTestBase { * * @var array */ - public static $modules = ['taxonomy', 'text']; + public static $modules = ['taxonomy', 'text', 'user']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); + $this->installEntitySchema('user'); $this->installEntitySchema('taxonomy_vocabulary'); $this->installEntitySchema('taxonomy_term'); $this->installConfig(['taxonomy']); diff --git a/core/modules/migrate/tests/src/Kernel/MigrateEntityContentBaseTest.php b/core/modules/migrate/tests/src/Kernel/MigrateEntityContentBaseTest.php index 0ebc719e..7337e35e 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateEntityContentBaseTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateEntityContentBaseTest.php @@ -10,6 +10,7 @@ use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Row; +use Drupal\migrate_entity_test\Entity\StringIdEntityTest; /** * Tests the EntityContentBase destination. @@ -204,4 +205,65 @@ public function testEntityWithStringId() { $this->assertEquals(123456789012, $map_row['destid1']); } + /** + * Tests empty destinations. + */ + public function testEmptyDestinations() { + $this->enableModules(['migrate_entity_test']); + $this->installEntitySchema('migrate_string_id_entity_test'); + + $definition = [ + 'source' => [ + 'plugin' => 'embedded_data', + 'data_rows' => [ + ['id' => 123, 'version' => 'foo'], + // This integer needs an 'int' schema with 'big' size. If 'destid1' + // is not correctly taking the definition from the destination entity + // type, the import will fail with an SQL exception. + ['id' => 123456789012, 'version' => 'bar'], + ], + 'ids' => [ + 'id' => ['type' => 'integer', 'size' => 'big'], + 'version' => ['type' => 'string'], + ], + 'constants' => ['null' => NULL], + ], + 'process' => [ + 'id' => 'id', + 'version' => 'version', + ], + 'destination' => [ + 'plugin' => 'entity:migrate_string_id_entity_test', + ], + ]; + + $migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $executable = new MigrateExecutable($migration, new MigrateMessage()); + $executable->import(); + + /** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */ + $entity = StringIdEntityTest::load('123'); + $this->assertSame('foo', $entity->version->value); + $entity = StringIdEntityTest::load('123456789012'); + $this->assertSame('bar', $entity->version->value); + + // Rerun the migration forcing the version to NULL. + $definition['process'] = [ + 'id' => 'id', + 'version' => 'constants/null', + ]; + + $migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $executable = new MigrateExecutable($migration, new MigrateMessage()); + $executable->import(); + + /** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */ + $entity = StringIdEntityTest::load('123'); + $this->assertNull($entity->version->value); + $entity = StringIdEntityTest::load('123456789012'); + $this->assertNull($entity->version->value); + } + } diff --git a/core/modules/migrate/tests/src/Kernel/MigrateEventsTest.php b/core/modules/migrate/tests/src/Kernel/MigrateEventsTest.php index b332cbdb..4de21fde 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateEventsTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateEventsTest.php @@ -40,17 +40,17 @@ protected function setUp() { parent::setUp(); $this->state = \Drupal::state(); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::MAP_SAVE, - array($this, 'mapSaveEventRecorder')); + [$this, 'mapSaveEventRecorder']); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::MAP_DELETE, - array($this, 'mapDeleteEventRecorder')); + [$this, 'mapDeleteEventRecorder']); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::PRE_IMPORT, - array($this, 'preImportEventRecorder')); + [$this, 'preImportEventRecorder']); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_IMPORT, - array($this, 'postImportEventRecorder')); + [$this, 'postImportEventRecorder']); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::PRE_ROW_SAVE, - array($this, 'preRowSaveEventRecorder')); + [$this, 'preRowSaveEventRecorder']); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_SAVE, - array($this, 'postRowSaveEventRecorder')); + [$this, 'postRowSaveEventRecorder']); } /** @@ -129,11 +129,11 @@ public function testMigrateEvents() { * The event name. */ public function mapSaveEventRecorder(MigrateMapSaveEvent $event, $name) { - $this->state->set('migrate_events_test.map_save_event', array( + $this->state->set('migrate_events_test.map_save_event', [ 'event_name' => $name, 'map' => $event->getMap(), 'fields' => $event->getFields(), - )); + ]); } /** @@ -145,11 +145,11 @@ public function mapSaveEventRecorder(MigrateMapSaveEvent $event, $name) { * The event name. */ public function mapDeleteEventRecorder(MigrateMapDeleteEvent $event, $name) { - $this->state->set('migrate_events_test.map_delete_event', array( + $this->state->set('migrate_events_test.map_delete_event', [ 'event_name' => $name, 'map' => $event->getMap(), 'source_id' => $event->getSourceId(), - )); + ]); } /** @@ -161,10 +161,10 @@ public function mapDeleteEventRecorder(MigrateMapDeleteEvent $event, $name) { * The event name. */ public function preImportEventRecorder(MigrateImportEvent $event, $name) { - $this->state->set('migrate_events_test.pre_import_event', array( + $this->state->set('migrate_events_test.pre_import_event', [ 'event_name' => $name, 'migration' => $event->getMigration(), - )); + ]); } /** @@ -176,10 +176,10 @@ public function preImportEventRecorder(MigrateImportEvent $event, $name) { * The event name. */ public function postImportEventRecorder(MigrateImportEvent $event, $name) { - $this->state->set('migrate_events_test.post_import_event', array( + $this->state->set('migrate_events_test.post_import_event', [ 'event_name' => $name, 'migration' => $event->getMigration(), - )); + ]); } /** @@ -191,11 +191,11 @@ public function postImportEventRecorder(MigrateImportEvent $event, $name) { * The event name. */ public function preRowSaveEventRecorder(MigratePreRowSaveEvent $event, $name) { - $this->state->set('migrate_events_test.pre_row_save_event', array( + $this->state->set('migrate_events_test.pre_row_save_event', [ 'event_name' => $name, 'migration' => $event->getMigration(), 'row' => $event->getRow(), - )); + ]); } /** @@ -207,12 +207,12 @@ public function preRowSaveEventRecorder(MigratePreRowSaveEvent $event, $name) { * The event name. */ public function postRowSaveEventRecorder(MigratePostRowSaveEvent $event, $name) { - $this->state->set('migrate_events_test.post_row_save_event', array( + $this->state->set('migrate_events_test.post_row_save_event', [ 'event_name' => $name, 'migration' => $event->getMigration(), 'row' => $event->getRow(), 'destination_id_values' => $event->getDestinationIdValues(), - )); + ]); } } diff --git a/core/modules/migrate/tests/src/Kernel/MigrateExternalTranslatedTest.php b/core/modules/migrate/tests/src/Kernel/MigrateExternalTranslatedTest.php index ce9c0136..d9728f58 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateExternalTranslatedTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateExternalTranslatedTest.php @@ -18,11 +18,8 @@ class MigrateExternalTranslatedTest extends MigrateTestBase { /** * {@inheritdoc} - * - * @todo: Remove migrate_drupal when https://www.drupal.org/node/2560795 is - * fixed. */ - public static $modules = ['system', 'user', 'language', 'node', 'field', 'migrate_drupal', 'migrate_external_translated_test']; + public static $modules = ['system', 'user', 'language', 'node', 'field', 'migrate_external_translated_test']; /** * {@inheritdoc} @@ -30,7 +27,7 @@ class MigrateExternalTranslatedTest extends MigrateTestBase { public function setUp() { parent::setUp(); $this->installSchema('system', ['sequences']); - $this->installSchema('node', array('node_access')); + $this->installSchema('node', ['node_access']); $this->installEntitySchema('user'); $this->installEntitySchema('node'); diff --git a/core/modules/migrate/tests/src/Kernel/MigrateInterruptionTest.php b/core/modules/migrate/tests/src/Kernel/MigrateInterruptionTest.php index 9ff76f6a..d99329e1 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateInterruptionTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateInterruptionTest.php @@ -29,7 +29,7 @@ class MigrateInterruptionTest extends KernelTestBase { protected function setUp() { parent::setUp(); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_SAVE, - array($this, 'postRowSaveEventRecorder')); + [$this, 'postRowSaveEventRecorder']); } /** diff --git a/core/modules/migrate/tests/src/Kernel/MigrateMessageTest.php b/core/modules/migrate/tests/src/Kernel/MigrateMessageTest.php index 4f4af7da..33013367 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateMessageTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateMessageTest.php @@ -89,7 +89,7 @@ public function testMessagesNotTeed() { public function testMessagesTeed() { // Ask to receive any messages sent to the idmap. \Drupal::service('event_dispatcher')->addListener(MigrateEvents::IDMAP_MESSAGE, - array($this, 'mapMessageRecorder')); + [$this, 'mapMessageRecorder']); $executable = new MigrateExecutable($this->migration, $this); $executable->import(); $this->assertIdentical(count($this->messages), 1); diff --git a/core/modules/migrate/tests/src/Kernel/MigrateRollbackEntityConfigTest.php b/core/modules/migrate/tests/src/Kernel/MigrateRollbackEntityConfigTest.php new file mode 100644 index 00000000..a6399592 --- /dev/null +++ b/core/modules/migrate/tests/src/Kernel/MigrateRollbackEntityConfigTest.php @@ -0,0 +1,169 @@ +installEntitySchema('user'); + $this->installEntitySchema('taxonomy_vocabulary'); + $this->installEntitySchema('taxonomy_term'); + $this->installConfig(['taxonomy']); + } + + /** + * Tests rolling back configuration entity translations. + */ + public function testConfigEntityRollback() { + // We use vocabularies to demonstrate importing and rolling back + // configuration entities with translations. First, import vocabularies. + $vocabulary_data_rows = [ + ['id' => '1', 'name' => 'categories', 'weight' => '2'], + ['id' => '2', 'name' => 'tags', 'weight' => '1'], + ]; + $ids = ['id' => ['type' => 'integer']]; + $definition = [ + 'id' => 'vocabularies', + 'migration_tags' => ['Import and rollback test'], + 'source' => [ + 'plugin' => 'embedded_data', + 'data_rows' => $vocabulary_data_rows, + 'ids' => $ids, + ], + 'process' => [ + 'vid' => 'id', + 'name' => 'name', + 'weight' => 'weight', + ], + 'destination' => ['plugin' => 'entity:taxonomy_vocabulary'], + ]; + + /** @var \Drupal\migrate\Plugin\Migration $vocabulary_migration */ + $vocabulary_migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $vocabulary_id_map = $vocabulary_migration->getIdMap(); + + $this->assertTrue($vocabulary_migration->getDestinationPlugin() + ->supportsRollback()); + + // Import and validate vocabulary config entities were created. + $vocabulary_executable = new MigrateExecutable($vocabulary_migration, $this); + $vocabulary_executable->import(); + foreach ($vocabulary_data_rows as $row) { + /** @var \Drupal\taxonomy\Entity\Vocabulary $vocabulary */ + $vocabulary = Vocabulary::load($row['id']); + $this->assertTrue($vocabulary); + $map_row = $vocabulary_id_map->getRowBySource(['id' => $row['id']]); + $this->assertNotNull($map_row['destid1']); + } + + // Second, import translations of the vocabulary name property. + $vocabulary_i18n_data_rows = [ + [ + 'id' => '1', + 'name' => '1', + 'language' => 'fr', + 'property' => 'name', + 'translation' => 'fr - categories' + ], + [ + 'id' => '2', + 'name' => '2', + 'language' => 'fr', + 'property' => 'name', + 'translation' => 'fr - tags' + ], + ]; + $ids = [ + 'id' => ['type' => 'integer'], + 'language' => ['type' => 'string'], + ]; + $definition = [ + 'id' => 'i18n_vocabularies', + 'migration_tags' => ['Import and rollback test'], + 'source' => [ + 'plugin' => 'embedded_data', + 'data_rows' => $vocabulary_i18n_data_rows, + 'ids' => $ids, + 'constants' => [ + 'name' => 'name', + ] + ], + 'process' => [ + 'vid' => 'id', + 'langcode' => 'language', + 'property' => 'constants/name', + 'translation' => 'translation', + ], + 'destination' => [ + 'plugin' => 'entity:taxonomy_vocabulary', + 'translations' => 'true', + ], + ]; + + $vocabulary_i18n__migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($definition); + $vocabulary_i18n_id_map = $vocabulary_i18n__migration->getIdMap(); + + $this->assertTrue($vocabulary_i18n__migration->getDestinationPlugin() + ->supportsRollback()); + + // Import and validate vocabulary config entities were created. + $vocabulary_i18n_executable = new MigrateExecutable($vocabulary_i18n__migration, $this); + $vocabulary_i18n_executable->import(); + + $language_manager = \Drupal::service('language_manager'); + foreach ($vocabulary_i18n_data_rows as $row) { + $langcode = $row['language']; + $id = 'taxonomy.vocabulary.' . $row['id']; + /** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */ + $config_translation = $language_manager->getLanguageConfigOverride($langcode, $id); + $this->assertSame($row['translation'], $config_translation->get('name')); + $map_row = $vocabulary_i18n_id_map->getRowBySource(['id' => $row['id'], 'language' => $row['language']]); + $this->assertNotNull($map_row['destid1']); + } + + // Perform the rollback and confirm the translation was deleted and the map + // table row removed. + $vocabulary_i18n_executable->rollback(); + foreach ($vocabulary_i18n_data_rows as $row) { + $langcode = $row['language']; + $id = 'taxonomy.vocabulary.' . $row['id']; + /** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */ + $config_translation = $language_manager->getLanguageConfigOverride($langcode, $id); + $this->assertNull($config_translation->get('name')); + $map_row = $vocabulary_i18n_id_map->getRowBySource(['id' => $row['id'], 'language' => $row['language']]); + $this->assertFalse($map_row); + } + + // Confirm the original vocabulary still exists. + foreach ($vocabulary_data_rows as $row) { + /** @var \Drupal\taxonomy\Entity\Vocabulary $vocabulary */ + $vocabulary = Vocabulary::load($row['id']); + $this->assertTrue($vocabulary); + $map_row = $vocabulary_id_map->getRowBySource(['id' => $row['id']]); + $this->assertNotNull($map_row['destid1']); + } + + } + +} diff --git a/core/modules/migrate/tests/src/Kernel/MigrateRollbackTest.php b/core/modules/migrate/tests/src/Kernel/MigrateRollbackTest.php index 4b78e652..427f5bce 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateRollbackTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateRollbackTest.php @@ -20,13 +20,14 @@ class MigrateRollbackTest extends MigrateTestBase { * * @var array */ - public static $modules = ['field', 'taxonomy', 'text']; + public static $modules = ['field', 'taxonomy', 'text', 'user']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); + $this->installEntitySchema('user'); $this->installEntitySchema('taxonomy_vocabulary'); $this->installEntitySchema('taxonomy_term'); $this->installConfig(['taxonomy']); diff --git a/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php b/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php index e3b2f8c2..00f07a9e 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateSourceTestBase.php @@ -135,15 +135,25 @@ protected function getPlugin(array $configuration) { * value (like FALSE or 'nope'), the source plugin will not be counted. * @param array $configuration * (optional) Configuration for the source plugin. + * @param mixed $high_water + * (optional) The value of the high water field. * * @dataProvider providerSource */ - public function testSource(array $source_data, array $expected_data, $expected_count = NULL, array $configuration = []) { + public function testSource(array $source_data, array $expected_data, $expected_count = NULL, array $configuration = [], $high_water = NULL) { $plugin = $this->getPlugin($configuration); // All source plugins must define IDs. $this->assertNotEmpty($plugin->getIds()); + // If there is a high water mark, set it in the high water storage. + if (isset($high_water)) { + $this->container + ->get('keyvalue') + ->get('migrate:high_water') + ->set($this->migration->reveal()->id(), $high_water); + } + if (is_null($expected_count)) { $expected_count = count($expected_data); } @@ -175,6 +185,11 @@ public function testSource(array $source_data, array $expected_data, $expected_c } } } + // False positives occur if the foreach is not entered. So, confirm the + // foreach loop was entered if the expected count is greater than 0. + if ($expected_count > 0) { + $this->assertGreaterThan(0, $i); + } } } diff --git a/core/modules/migrate/tests/src/Kernel/MigrateSqlSourceTestBase.php b/core/modules/migrate/tests/src/Kernel/MigrateSqlSourceTestBase.php index f04183f3..d7058b1a 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateSqlSourceTestBase.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateSqlSourceTestBase.php @@ -39,7 +39,9 @@ protected function getDatabase(array $source_data) { ->createTable($table, [ // SQLite uses loose affinity typing, so it's OK for every field to // be a text field. - 'fields' => array_map(function() { return ['type' => 'text']; }, $pilot), + 'fields' => array_map(function () { + return ['type' => 'text']; + }, $pilot), ]); $fields = array_keys($pilot); @@ -63,12 +65,14 @@ protected function getDatabase(array $source_data) { * (optional) How many rows the source plugin is expected to return. * @param array $configuration * (optional) Configuration for the source plugin. + * @param mixed $high_water + * (optional) The value of the high water field. * * @dataProvider providerSource * * @requires extension pdo_sqlite */ - public function testSource(array $source_data, array $expected_data, $expected_count = NULL, array $configuration = []) { + public function testSource(array $source_data, array $expected_data, $expected_count = NULL, array $configuration = [], $high_water = NULL) { $plugin = $this->getPlugin($configuration); // Since we don't yet inject the database connection, we need to use a @@ -78,7 +82,7 @@ public function testSource(array $source_data, array $expected_data, $expected_c $property->setAccessible(TRUE); $property->setValue($plugin, $this->getDatabase($source_data)); - parent::testSource($source_data, $expected_data, $expected_count, $configuration); + parent::testSource($source_data, $expected_data, $expected_count, $configuration, $high_water); } } diff --git a/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php b/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php index b31a67ee..7dc0b5b9 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php @@ -33,13 +33,13 @@ public function testStatus() { $this->assertIdentical($status, MigrationInterface::STATUS_IDLE); // Test setting and retrieving all known status values. - $status_list = array( + $status_list = [ MigrationInterface::STATUS_IDLE, MigrationInterface::STATUS_IMPORTING, MigrationInterface::STATUS_ROLLING_BACK, MigrationInterface::STATUS_STOPPING, MigrationInterface::STATUS_DISABLED, - ); + ]; foreach ($status_list as $status) { $migration->setStatus($status); $this->assertIdentical($migration->getStatus(), $status); diff --git a/core/modules/migrate/tests/src/Kernel/MigrateTestBase.php b/core/modules/migrate/tests/src/Kernel/MigrateTestBase.php index 8494dc6a..51e61d40 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateTestBase.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateTestBase.php @@ -47,7 +47,7 @@ abstract class MigrateTestBase extends KernelTestBase implements MigrateMessageI */ protected $sourceDatabase; - public static $modules = array('migrate'); + public static $modules = ['migrate']; /** * {@inheritdoc} @@ -201,7 +201,7 @@ public function display($message, $type = 'status') { */ public function startCollectingMessages() { $this->collectMessages = TRUE; - $this->migrateMessages = array(); + $this->migrateMessages = []; } /** @@ -230,7 +230,9 @@ protected function mockFailure($migration, array $row, $status = MigrateIdMapInt $migration = $this->getMigration($migration); } /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ - $destination = array_map(function() { return NULL; }, $migration->getDestinationPlugin()->getIds()); + $destination = array_map(function () { + return NULL; + }, $migration->getDestinationPlugin()->getIds()); $row = new Row($row, $migration->getSourcePlugin()->getIds()); $migration->getIdMap()->saveIdMapping($row, $destination, $status); } diff --git a/core/modules/migrate/tests/src/Kernel/NodeCommentCombinationTrait.php b/core/modules/migrate/tests/src/Kernel/NodeCommentCombinationTrait.php new file mode 100644 index 00000000..6f04b3a4 --- /dev/null +++ b/core/modules/migrate/tests/src/Kernel/NodeCommentCombinationTrait.php @@ -0,0 +1,38 @@ + $node_type, + 'label' => $this->randomString(), + ])->save(); + + CommentType::create([ + 'id' => $comment_type, + 'label' => $this->randomString(), + 'target_entity_type_id' => 'node', + ])->save(); + } + +} diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/EntityExistsTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/EntityExistsTest.php new file mode 100644 index 00000000..dcd070c3 --- /dev/null +++ b/core/modules/migrate/tests/src/Kernel/Plugin/EntityExistsTest.php @@ -0,0 +1,61 @@ +installSchema('system', ['sequences']); + $this->installEntitySchema('user'); + } + + /** + * Test the EntityExists plugin. + */ + public function testEntityExists() { + $user = User::create([ + 'name' => $this->randomString(), + ]); + $user->save(); + $uid = $user->id(); + + $plugin = \Drupal::service('plugin.manager.migrate.process') + ->createInstance('entity_exists', [ + 'entity_type' => 'user', + ]); + $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal(); + $row = new Row(); + + // Ensure that the entity ID is returned if it really exists. + $value = $plugin->transform($uid, $executable, $row, 'buffalo'); + $this->assertSame($uid, $value); + + // Ensure that the plugin returns FALSE if the entity doesn't exist. + $value = $plugin->transform(420, $executable, $row, 'buffalo'); + $this->assertFalse($value); + + // Make sure the plugin can gracefully handle an array as input. + $value = $plugin->transform([$uid, 420], $executable, $row, 'buffalo'); + $this->assertSame($uid, $value); + } + +} diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php new file mode 100644 index 00000000..bb5d04db --- /dev/null +++ b/core/modules/migrate/tests/src/Kernel/Plugin/LogTest.php @@ -0,0 +1,36 @@ +createInstance('log'); + $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal(); + $row = new Row(); + $log_message = "Testing the log message"; + + // Ensure the log is getting saved. + $saved_message = $plugin->transform($log_message, $executable, $row, 'buffalo'); + $this->assertSame($log_message, $saved_message); + } + +} diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php index f732d9f9..62f3d19b 100644 --- a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php +++ b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationPluginListTest.php @@ -4,6 +4,9 @@ use Drupal\Core\Database\Database; use Drupal\KernelTests\KernelTestBase; +use Drupal\migrate\Exception\RequirementsException; +use Drupal\migrate\Plugin\migrate\source\SqlBase; +use Drupal\migrate\Plugin\RequirementsInterface; /** * Tests the migration plugin manager. @@ -79,6 +82,33 @@ public function testGetDefinitions() { // Enable migrate_drupal to test that the plugins can now be discovered. $this->enableModules(['migrate_drupal']); + + // Make sure retrieving these migration plugins in the absence of a database + // connection does not throw any errors. + $migration_plugins = $this->container->get('plugin.manager.migration')->createInstances([]); + // Any database-based source plugins should fail a requirements test in the + // absence of a source database connection (e.g., a connection with the + // 'migrate' key). + $source_plugins = array_map(function ($migration_plugin) { + return $migration_plugin->getSourcePlugin(); + }, $migration_plugins); + foreach ($source_plugins as $id => $source_plugin) { + if ($source_plugin instanceof RequirementsInterface) { + try { + $source_plugin->checkRequirements(); + } + catch (RequirementsException $e) { + unset($source_plugins[$id]); + } + } + } + + // Without a connection defined, no database-based plugins should be + // returned. + foreach ($source_plugins as $id => $source_plugin) { + $this->assertNotInstanceOf(SqlBase::class, $source_plugin); + } + // Set up a migrate database connection so that plugin discovery works. // Clone the current connection and replace the current prefix. $connection_info = Database::getConnectionInfo('migrate'); diff --git a/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php new file mode 100644 index 00000000..8e166998 --- /dev/null +++ b/core/modules/migrate/tests/src/Kernel/Plugin/MigrationProvidersExistTest.php @@ -0,0 +1,64 @@ +container->get('module_handler'); + $modules = $this->coreModuleListDataProvider(); + $modules_enabled = $module_handler->getModuleList(); + $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled)); + $this->enableModules($modules_to_enable); + + /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */ + $plugin_manager = $this->container->get('plugin.manager.migration'); + // Get all the migrations + $migrations = $plugin_manager->createInstances(array_keys($plugin_manager->getDefinitions())); + // Ensure the test module was enabled. + $this->assertTrue(array_key_exists('migration_provider_test', $migrations)); + $this->assertTrue(array_key_exists('migration_provider_no_annotation', $migrations)); + /** @var \Drupal\migrate\Plugin\Migration $migration */ + foreach ($migrations as $migration) { + $source_module = $migration->getSourcePlugin()->getSourceModule(); + $destination_module = $migration->getDestinationPlugin()->getDestinationModule(); + $migration_id = $migration->getPluginId(); + if ($migration_id == 'migration_provider_test') { + $this->assertFalse($source_module, new FormattableMarkup('Source module not found for @migration_id.', ['@migration_id' => $migration_id])); + $this->assertFalse($destination_module, new FormattableMarkup('Destination module not found for @migration_id.', ['@migration_id' => $migration_id])); + } + elseif ($migration_id == 'migration_provider_no_annotation') { + $this->assertFalse($source_module, new FormattableMarkup('Source module not found for @migration_id.', ['@migration_id' => $migration_id])); + $this->assertTrue($destination_module, new FormattableMarkup('Destination module found for @migration_id.', ['@migration_id' => $migration_id])); + } + else { + $this->assertTrue($source_module, new FormattableMarkup('Source module found for @migration_id.', ['@migration_id' => $migration_id])); + $this->assertTrue($destination_module, new FormattableMarkup('Destination module found for @migration_id.', ['@migration_id' => $migration_id])); + } + // Destination module can't be migrate or migrate_drupal or migrate_drupal_ui + $invalid_destinations = ['migrate', 'migrate_drupal', 'migrate_drupal_ui']; + $this->assertNotContains($destination_module, $invalid_destinations, new FormattableMarkup('Invalid destination for @migration_id.', ['@migration_id' => $migration_id])); + } + } + +} diff --git a/core/modules/migrate/tests/src/Kernel/SqlBaseTest.php b/core/modules/migrate/tests/src/Kernel/SqlBaseTest.php index a7b0dac1..7115860c 100644 --- a/core/modules/migrate/tests/src/Kernel/SqlBaseTest.php +++ b/core/modules/migrate/tests/src/Kernel/SqlBaseTest.php @@ -7,8 +7,12 @@ namespace Drupal\Tests\migrate\Kernel; -use Drupal\migrate\Plugin\migrate\source\TestSqlBase; +use Drupal\Core\Database\Query\ConditionInterface; +use Drupal\Core\Database\Query\SelectInterface; +use Drupal\migrate\Exception\RequirementsException; use Drupal\Core\Database\Database; +use Drupal\migrate\Plugin\migrate\source\SqlBase; +use Drupal\migrate\Plugin\MigrationInterface; /** * Tests the functionality of SqlBase. @@ -17,41 +21,71 @@ */ class SqlBaseTest extends MigrateTestBase { + /** + * The (probably mocked) migration under test. + * + * @var \Drupal\migrate\Plugin\MigrationInterface + */ + protected $migration; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->migration = $this->getMock(MigrationInterface::class); + $this->migration->method('id')->willReturn('fubar'); + } + /** * Tests different connection types. */ public function testConnectionTypes() { - $sql_base = new TestSqlBase(); + $sql_base = new TestSqlBase([], $this->migration); - // Check the default values. - $sql_base->setConfiguration([]); - $this->assertIdentical($sql_base->getDatabase()->getTarget(), 'default'); - $this->assertIdentical($sql_base->getDatabase()->getKey(), 'migrate'); + // Verify that falling back to the default 'migrate' connection (defined in + // the base class) works. + $this->assertSame($sql_base->getDatabase()->getTarget(), 'default'); + $this->assertSame($sql_base->getDatabase()->getKey(), 'migrate'); + // Verify the fallback state key overrides the 'migrate' connection. + $target = 'test_fallback_target'; + $key = 'test_fallback_key'; + $config = ['target' => $target, 'key' => $key]; + $database_state_key = 'test_fallback_state'; + \Drupal::state()->set($database_state_key, $config); + \Drupal::state()->set('migrate.fallback_state_key', $database_state_key); + // Create a test connection using the default database configuration. + Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']); + $this->assertSame($sql_base->getDatabase()->getTarget(), $target); + $this->assertSame($sql_base->getDatabase()->getKey(), $key); + + // Verify that setting explicit connection information overrides fallbacks. $target = 'test_db_target'; $key = 'test_migrate_connection'; - $config = array('target' => $target, 'key' => $key); + $config = ['target' => $target, 'key' => $key]; $sql_base->setConfiguration($config); Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']); // Validate we have injected our custom key and target. - $this->assertIdentical($sql_base->getDatabase()->getTarget(), $target); - $this->assertIdentical($sql_base->getDatabase()->getKey(), $key); + $this->assertSame($sql_base->getDatabase()->getTarget(), $target); + $this->assertSame($sql_base->getDatabase()->getKey(), $key); // Now test we can have SqlBase create the connection from an info array. - $sql_base = new TestSqlBase(); + $sql_base = new TestSqlBase([], $this->migration); $target = 'test_db_target2'; $key = 'test_migrate_connection2'; $database = Database::getConnectionInfo('default')['default']; - $config = array('target' => $target, 'key' => $key, 'database' => $database); + $config = ['target' => $target, 'key' => $key, 'database' => $database]; $sql_base->setConfiguration($config); // Call getDatabase() to get the connection defined. $sql_base->getDatabase(); // Validate the connection has been created with the right values. - $this->assertIdentical(Database::getConnectionInfo($key)[$target], $database); + $this->assertSame(Database::getConnectionInfo($key)[$target], $database); // Now, test this all works when using state to store db info. $target = 'test_state_db_target'; @@ -63,11 +97,11 @@ public function testConnectionTypes() { Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']); // Validate we have injected our custom key and target. - $this->assertIdentical($sql_base->getDatabase()->getTarget(), $target); - $this->assertIdentical($sql_base->getDatabase()->getKey(), $key); + $this->assertSame($sql_base->getDatabase()->getTarget(), $target); + $this->assertSame($sql_base->getDatabase()->getKey(), $key); // Now test we can have SqlBase create the connection from an info array. - $sql_base = new TestSqlBase(); + $sql_base = new TestSqlBase([], $this->migration); $target = 'test_state_db_target2'; $key = 'test_state_migrate_connection2'; @@ -81,12 +115,67 @@ public function testConnectionTypes() { $sql_base->getDatabase(); // Validate the connection has been created with the right values. - $this->assertIdentical(Database::getConnectionInfo($key)[$target], $database); + $this->assertSame(Database::getConnectionInfo($key)[$target], $database); + + // Verify that falling back to 'migrate' when the connection is not defined + // throws a RequirementsException. + \Drupal::state()->delete('migrate.fallback_state_key'); + $sql_base->setConfiguration([]); + Database::renameConnection('migrate', 'fallback_connection'); + $this->setExpectedException(RequirementsException::class, + 'No database connection configured for source plugin'); + $sql_base->getDatabase(); } -} + /** + * Tests that SqlBase respects high-water values. + * + * @param mixed $high_water + * (optional) The high-water value to set. + * @param array $query_result + * (optional) The expected query results. + * + * @dataProvider highWaterDataProvider + */ + public function testHighWater($high_water = NULL, array $query_result = []) { + $configuration = [ + 'high_water_property' => [ + 'name' => 'order', + ], + ]; + $source = new TestSqlBase($configuration, $this->migration); + + if ($high_water) { + $source->getHighWaterStorage()->set($this->migration->id(), $high_water); + } + + $query_result = new \ArrayIterator($query_result); -namespace Drupal\migrate\Plugin\migrate\source; + $query = $this->getMock(SelectInterface::class); + $query->method('execute')->willReturn($query_result); + $query->expects($this->atLeastOnce())->method('orderBy')->with('order', 'ASC'); + + $condition_group = $this->getMock(ConditionInterface::class); + $query->method('orConditionGroup')->willReturn($condition_group); + + $source->setQuery($query); + $source->rewind(); + } + + /** + * Data provider for ::testHighWater(). + * + * @return array + * The scenarios to test. + */ + public function highWaterDataProvider() { + return [ + 'no high-water value set' => [], + 'high-water value set' => [33], + ]; + } + +} /** * A dummy source to help with testing SqlBase. @@ -95,11 +184,23 @@ public function testConnectionTypes() { */ class TestSqlBase extends SqlBase { + /** + * The query to execute. + * + * @var \Drupal\Core\Database\Query\SelectInterface + */ + protected $query; + /** * Overrides the constructor so we can create one easily. + * + * @param array $configuration + * The plugin instance configuration. + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * (optional) The migration being run. */ - public function __construct() { - $this->state = \Drupal::state(); + public function __construct(array $configuration = [], MigrationInterface $migration = NULL) { + parent::__construct($configuration, 'sql_base', [], $migration, \Drupal::state()); } /** @@ -133,6 +234,25 @@ public function fields() {} /** * {@inheritdoc} */ - public function query() {} + public function query() { + return $this->query; + } + + /** + * Sets the query to execute. + * + * @param \Drupal\Core\Database\Query\SelectInterface $query + * The query to execute. + */ + public function setQuery(SelectInterface $query) { + $this->query = $query; + } + + /** + * {@inheritdoc} + */ + public function getHighWaterStorage() { + return parent::getHighWaterStorage(); + } } diff --git a/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php b/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php deleted file mode 100644 index ecd1bb14..00000000 --- a/core/modules/migrate/tests/src/Kernel/process/CopyFileTest.php +++ /dev/null @@ -1,218 +0,0 @@ -fileSystem = $this->container->get('file_system'); - $this->container->get('stream_wrapper_manager')->registerWrapper('temporary', 'Drupal\Core\StreamWrapper\TemporaryStream', StreamWrapperInterface::LOCAL_NORMAL); - } - - /** - * Test successful imports/copies. - */ - public function testSuccessfulCopies() { - $file = $this->createUri(NULL, NULL, 'temporary'); - $file_absolute = $this->fileSystem->realpath($file); - $data_sets = [ - // Test a local to local copy. - [ - $this->root . '/core/modules/simpletest/files/image-test.jpg', - 'public://file1.jpg' - ], - // Test a temporary file using an absolute path. - [ - $file_absolute, - 'temporary://test.jpg' - ], - // Test a temporary file using a relative path. - [ - $file_absolute, - 'temporary://core/modules/simpletest/files/test.jpg' - ], - ]; - foreach ($data_sets as $data) { - list($source_path, $destination_path) = $data; - $actual_destination = $this->doImport($source_path, $destination_path); - $message = sprintf('File %s exists', $destination_path); - $this->assertFileExists($destination_path, $message); - // Make sure we didn't accidentally do a move. - $this->assertFileExists($source_path, $message); - $this->assertSame($actual_destination, $destination_path, 'The import returned the copied filename.'); - } - } - - /** - * Test successful file reuse. - */ - public function testSuccessfulReuse() { - $source_path = $this->root . '/core/modules/simpletest/files/image-test.jpg'; - $destination_path = 'public://file1.jpg'; - $file_reuse = file_unmanaged_copy($source_path, $destination_path); - $timestamp = (new \SplFileInfo($file_reuse))->getMTime(); - $this->assertInternalType('int', $timestamp); - - // We need to make sure the modified timestamp on the file is sooner than - // the attempted migration. - sleep(1); - $configuration = ['reuse' => TRUE]; - $this->doImport($source_path, $destination_path, $configuration); - clearstatcache(TRUE, $destination_path); - $modified_timestamp = (new \SplFileInfo($destination_path))->getMTime(); - $this->assertEquals($timestamp, $modified_timestamp); - - $configuration = ['reuse' => FALSE]; - $this->doImport($source_path, $destination_path, $configuration); - clearstatcache(TRUE, $destination_path); - $modified_timestamp = (new \SplFileInfo($destination_path))->getMTime(); - $this->assertGreaterThan($timestamp, $modified_timestamp); - } - - /** - * Test successful moves. - */ - public function testSuccessfulMoves() { - $file_1 = $this->createUri(NULL, NULL, 'temporary'); - $file_1_absolute = $this->fileSystem->realpath($file_1); - $file_2 = $this->createUri(NULL, NULL, 'temporary'); - $file_2_absolute = $this->fileSystem->realpath($file_2); - $local_file = $this->createUri(NULL, NULL, 'public'); - $data_sets = [ - // Test a local to local copy. - [ - $local_file, - 'public://file1.jpg' - ], - // Test a temporary file using an absolute path. - [ - $file_1_absolute, - 'temporary://test.jpg' - ], - // Test a temporary file using a relative path. - [ - $file_2_absolute, - 'temporary://core/modules/simpletest/files/test.jpg' - ], - ]; - foreach ($data_sets as $data) { - list($source_path, $destination_path) = $data; - $actual_destination = $this->doImport($source_path, $destination_path, ['move' => TRUE]); - $message = sprintf('File %s exists', $destination_path); - $this->assertFileExists($destination_path, $message); - $message = sprintf('File %s does not exist', $source_path); - $this->assertFileNotExists($source_path, $message); - $this->assertSame($actual_destination, $destination_path, 'The importer returned the moved filename.'); - } - } - - /** - * Test that non-existent files throw an exception. - * - * @expectedException \Drupal\migrate\MigrateException - * - * @expectedExceptionMessage File '/non/existent/file' does not exist - */ - public function testNonExistentSourceFile() { - $source = '/non/existent/file'; - $this->doImport($source, 'public://wontmatter.jpg'); - } - - /** - * Test the 'rename' overwrite mode. - */ - public function testRenameFile() { - $source = $this->createUri(NULL, NULL, 'temporary'); - $destination = $this->createUri('foo.txt', NULL, 'public'); - $expected_destination = 'public://foo_0.txt'; - $actual_destination = $this->doImport($source, $destination, ['rename' => TRUE]); - $this->assertFileExists($expected_destination, 'File was renamed on import'); - $this->assertSame($actual_destination, $expected_destination, 'The importer returned the renamed filename.'); - } - - /** - * Do an import using the destination. - * - * @param string $source_path - * Source path to copy from. - * @param string $destination_path - * The destination path to copy to. - * @param array $configuration - * Process plugin configuration settings. - * - * @throws \Drupal\migrate\MigrateException - */ - protected function doImport($source_path, $destination_path, $configuration = []) { - $plugin = FileCopy::create($this->container, $configuration, 'file_copy', []); - $executable = $this->prophesize(MigrateExecutableInterface::class)->reveal(); - $row = new Row(); - - $result = $plugin->transform([$source_path, $destination_path], $executable, $row, 'foobaz'); - - // Return the imported file Uri. - return $result; - } - - /** - * Create a file and return the URI of it. - * - * @param $filepath - * Optional string specifying the file path. If none is provided then a - * randomly named file will be created in the site's files directory. - * @param $contents - * Optional contents to save into the file. If a NULL value is provided an - * arbitrary string will be used. - * @param $scheme - * Optional string indicating the stream scheme to use. Drupal core includes - * public, private, and temporary. The public wrapper is the default. - * @return - * File URI. - */ - protected function createUri($filepath = NULL, $contents = NULL, $scheme = NULL) { - if (!isset($filepath)) { - // Prefix with non-latin characters to ensure that all file-related - // tests work with international filenames. - $filepath = 'Файл Ð´Ð»Ñ Ñ‚ÐµÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ' . $this->randomMachineName(); - } - if (empty($scheme)) { - $scheme = file_default_scheme(); - } - $filepath = $scheme . '://' . $filepath; - - if (empty($contents)) { - $contents = "file_put_contents() doesn't seem to appreciate empty strings so let's put in some data."; - } - - file_put_contents($filepath, $contents); - $this->assertFileExists($filepath, t('The test file exists on the disk.')); - return $filepath; - } - -} diff --git a/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php b/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php index 451d832c..644371e5 100644 --- a/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php +++ b/core/modules/migrate/tests/src/Kernel/process/FileCopyTest.php @@ -74,6 +74,32 @@ public function testSuccessfulCopies() { } } + /** + * Test successful file reuse. + */ + public function testSuccessfulReuse() { + $source_path = $this->root . '/core/modules/simpletest/files/image-test.jpg'; + $destination_path = 'public://file1.jpg'; + $file_reuse = file_unmanaged_copy($source_path, $destination_path); + $timestamp = (new \SplFileInfo($file_reuse))->getMTime(); + $this->assertInternalType('int', $timestamp); + + // We need to make sure the modified timestamp on the file is sooner than + // the attempted migration. + sleep(1); + $configuration = ['reuse' => TRUE]; + $this->doTransform($source_path, $destination_path, $configuration); + clearstatcache(TRUE, $destination_path); + $modified_timestamp = (new \SplFileInfo($destination_path))->getMTime(); + $this->assertEquals($timestamp, $modified_timestamp); + + $configuration = ['reuse' => FALSE]; + $this->doTransform($source_path, $destination_path, $configuration); + clearstatcache(TRUE, $destination_path); + $modified_timestamp = (new \SplFileInfo($destination_path))->getMTime(); + $this->assertGreaterThan($timestamp, $modified_timestamp); + } + /** * Test successful moves. */ @@ -113,13 +139,10 @@ public function testSuccessfulMoves() { /** * Test that non-existent files throw an exception. - * - * @expectedException \Drupal\migrate\MigrateException - * - * @expectedExceptionMessage File '/non/existent/file' does not exist */ public function testNonExistentSourceFile() { $source = '/non/existent/file'; + $this->setExpectedException(MigrateException::class, "File '/non/existent/file' does not exist"); $this->doTransform($source, 'public://wontmatter.jpg'); } diff --git a/core/modules/migrate/tests/src/Kernel/process/RouteTest.php b/core/modules/migrate/tests/src/Kernel/process/RouteTest.php index 3de8d2d6..3f212356 100644 --- a/core/modules/migrate/tests/src/Kernel/process/RouteTest.php +++ b/core/modules/migrate/tests/src/Kernel/process/RouteTest.php @@ -259,7 +259,7 @@ public function providerTestRouteWithParamQuery() { * @param array|string $value * Source link path information. * - * @return array $actual + * @return array * The route information based on the source link_path. */ protected function doTransform($value) { diff --git a/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php b/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php index 6a52ed6e..b712d318 100644 --- a/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php +++ b/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php @@ -3,12 +3,13 @@ namespace Drupal\Tests\migrate\Unit\Event; use Drupal\migrate\Event\EventBase; +use Drupal\Tests\UnitTestCase; /** * @coversDefaultClass \Drupal\migrate\Event\EventBase * @group migrate */ -class EventBaseTest extends \PHPUnit_Framework_TestCase { +class EventBaseTest extends UnitTestCase { /** * Test getMigration method. diff --git a/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php b/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php index 480fe85a..d281433e 100644 --- a/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php +++ b/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php @@ -3,12 +3,13 @@ namespace Drupal\Tests\migrate\Unit\Event; use Drupal\migrate\Event\MigrateImportEvent; +use Drupal\Tests\UnitTestCase; /** * @coversDefaultClass \Drupal\migrate\Event\MigrateImportEvent * @group migrate */ -class MigrateImportEventTest extends \PHPUnit_Framework_TestCase { +class MigrateImportEventTest extends UnitTestCase { /** * Test getMigration method. diff --git a/core/modules/migrate/tests/src/Unit/Exception/RequirementsExceptionTest.php b/core/modules/migrate/tests/src/Unit/Exception/RequirementsExceptionTest.php index 72d37ed7..b3fafc8e 100644 --- a/core/modules/migrate/tests/src/Unit/Exception/RequirementsExceptionTest.php +++ b/core/modules/migrate/tests/src/Unit/Exception/RequirementsExceptionTest.php @@ -34,18 +34,18 @@ public function testGetExceptionString($expected, $message, $requirements) { * Provides a list of requirements to test. */ public function getRequirementsProvider() { - return array( - array( + return [ + [ 'requirements: random_jackson_pivot.', 'Single Requirement', - array('requirements' => $this->missingRequirements[0]), - ), - array( + ['requirements' => $this->missingRequirements[0]], + ], + [ 'requirements: random_jackson_pivot. requirements: 51_Eridani_b.', 'Multiple Requirements', - array('requirements' => $this->missingRequirements), - ), - ); + ['requirements' => $this->missingRequirements], + ], + ]; } } diff --git a/core/modules/migrate/tests/src/Unit/MigrateExecutableMemoryExceededTest.php b/core/modules/migrate/tests/src/Unit/MigrateExecutableMemoryExceededTest.php index 42d500d8..d14e54a4 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateExecutableMemoryExceededTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateExecutableMemoryExceededTest.php @@ -35,9 +35,9 @@ class MigrateExecutableMemoryExceededTest extends MigrateTestCase { * * @var array */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'test', - ); + ]; /** * The php.ini memory_limit value. diff --git a/core/modules/migrate/tests/src/Unit/MigrateExecutableTest.php b/core/modules/migrate/tests/src/Unit/MigrateExecutableTest.php index 60809a90..f199562b 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateExecutableTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateExecutableTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\migrate\Unit; use Drupal\Component\Utility\Html; +use Drupal\migrate\Plugin\MigrateProcessInterface; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\MigrateException; @@ -40,9 +41,9 @@ class MigrateExecutableTest extends MigrateTestCase { * * @var array */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'test', - ); + ]; /** * {@inheritdoc} @@ -91,12 +92,12 @@ public function testImportWithValidRow() { $row->expects($this->once()) ->method('getSourceIdValues') - ->will($this->returnValue(array('id' => 'test'))); + ->will($this->returnValue(['id' => 'test'])); $this->idMap->expects($this->once()) ->method('lookupDestinationId') - ->with(array('id' => 'test')) - ->will($this->returnValue(array('test'))); + ->with(['id' => 'test']) + ->will($this->returnValue(['test'])); $source->expects($this->once()) ->method('current') @@ -106,13 +107,13 @@ public function testImportWithValidRow() { $this->migration->expects($this->once()) ->method('getProcessPlugins') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $destination = $this->getMock('Drupal\migrate\Plugin\MigrateDestinationInterface'); $destination->expects($this->once()) ->method('import') - ->with($row, array('test')) - ->will($this->returnValue(array('id' => 'test'))); + ->with($row, ['test']) + ->will($this->returnValue(['id' => 'test'])); $this->migration ->method('getDestinationPlugin') @@ -133,12 +134,12 @@ public function testImportWithValidRowWithoutDestinationId() { $row->expects($this->once()) ->method('getSourceIdValues') - ->will($this->returnValue(array('id' => 'test'))); + ->will($this->returnValue(['id' => 'test'])); $this->idMap->expects($this->once()) ->method('lookupDestinationId') - ->with(array('id' => 'test')) - ->will($this->returnValue(array('test'))); + ->with(['id' => 'test']) + ->will($this->returnValue(['test'])); $source->expects($this->once()) ->method('current') @@ -148,12 +149,12 @@ public function testImportWithValidRowWithoutDestinationId() { $this->migration->expects($this->once()) ->method('getProcessPlugins') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $destination = $this->getMock('Drupal\migrate\Plugin\MigrateDestinationInterface'); $destination->expects($this->once()) ->method('import') - ->with($row, array('test')) + ->with($row, ['test']) ->will($this->returnValue(TRUE)); $this->migration @@ -178,7 +179,7 @@ public function testImportWithValidRowNoDestinationValues() { $row->expects($this->once()) ->method('getSourceIdValues') - ->will($this->returnValue(array('id' => 'test'))); + ->will($this->returnValue(['id' => 'test'])); $source->expects($this->once()) ->method('current') @@ -188,13 +189,13 @@ public function testImportWithValidRowNoDestinationValues() { $this->migration->expects($this->once()) ->method('getProcessPlugins') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $destination = $this->getMock('Drupal\migrate\Plugin\MigrateDestinationInterface'); $destination->expects($this->once()) ->method('import') - ->with($row, array('test')) - ->will($this->returnValue(array())); + ->with($row, ['test']) + ->will($this->returnValue([])); $this->migration ->method('getDestinationPlugin') @@ -202,7 +203,7 @@ public function testImportWithValidRowNoDestinationValues() { $this->idMap->expects($this->once()) ->method('saveIdMapping') - ->with($row, array(), MigrateIdMapInterface::STATUS_FAILED, NULL); + ->with($row, [], MigrateIdMapInterface::STATUS_FAILED, NULL); $this->idMap->expects($this->once()) ->method('messageCount') @@ -213,8 +214,8 @@ public function testImportWithValidRowNoDestinationValues() { $this->idMap->expects($this->once()) ->method('lookupDestinationId') - ->with(array('id' => 'test')) - ->will($this->returnValue(array('test'))); + ->with(['id' => 'test']) + ->will($this->returnValue(['test'])); $this->message->expects($this->once()) ->method('display') @@ -238,7 +239,7 @@ public function testImportWithValidRowWithDestinationMigrateException() { $row->expects($this->once()) ->method('getSourceIdValues') - ->will($this->returnValue(array('id' => 'test'))); + ->will($this->returnValue(['id' => 'test'])); $source->expects($this->once()) ->method('current') @@ -248,12 +249,12 @@ public function testImportWithValidRowWithDestinationMigrateException() { $this->migration->expects($this->once()) ->method('getProcessPlugins') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $destination = $this->getMock('Drupal\migrate\Plugin\MigrateDestinationInterface'); $destination->expects($this->once()) ->method('import') - ->with($row, array('test')) + ->with($row, ['test']) ->will($this->throwException(new MigrateException($exception_message))); $this->migration @@ -262,15 +263,15 @@ public function testImportWithValidRowWithDestinationMigrateException() { $this->idMap->expects($this->once()) ->method('saveIdMapping') - ->with($row, array(), MigrateIdMapInterface::STATUS_FAILED, NULL); + ->with($row, [], MigrateIdMapInterface::STATUS_FAILED, NULL); $this->idMap->expects($this->once()) ->method('saveMessage'); $this->idMap->expects($this->once()) ->method('lookupDestinationId') - ->with(array('id' => 'test')) - ->will($this->returnValue(array('test'))); + ->with(['id' => 'test']) + ->will($this->returnValue(['test'])); $this->assertSame(MigrationInterface::RESULT_COMPLETED, $this->executable->import()); } @@ -290,7 +291,7 @@ public function testImportWithValidRowWithProcesMigrateException() { $row->expects($this->once()) ->method('getSourceIdValues') - ->willReturn(array('id' => 'test')); + ->willReturn(['id' => 'test']); $source->expects($this->once()) ->method('current') @@ -312,7 +313,7 @@ public function testImportWithValidRowWithProcesMigrateException() { $this->idMap->expects($this->once()) ->method('saveIdMapping') - ->with($row, array(), MigrateIdMapInterface::STATUS_FAILED, NULL); + ->with($row, [], MigrateIdMapInterface::STATUS_FAILED, NULL); $this->idMap->expects($this->once()) ->method('saveMessage'); @@ -336,7 +337,7 @@ public function testImportWithValidRowWithException() { $row->expects($this->once()) ->method('getSourceIdValues') - ->will($this->returnValue(array('id' => 'test'))); + ->will($this->returnValue(['id' => 'test'])); $source->expects($this->once()) ->method('current') @@ -346,12 +347,12 @@ public function testImportWithValidRowWithException() { $this->migration->expects($this->once()) ->method('getProcessPlugins') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $destination = $this->getMock('Drupal\migrate\Plugin\MigrateDestinationInterface'); $destination->expects($this->once()) ->method('import') - ->with($row, array('test')) + ->with($row, ['test']) ->will($this->throwException(new \Exception($exception_message))); $this->migration @@ -360,15 +361,15 @@ public function testImportWithValidRowWithException() { $this->idMap->expects($this->once()) ->method('saveIdMapping') - ->with($row, array(), MigrateIdMapInterface::STATUS_FAILED, NULL); + ->with($row, [], MigrateIdMapInterface::STATUS_FAILED, NULL); $this->idMap->expects($this->once()) ->method('saveMessage'); $this->idMap->expects($this->once()) ->method('lookupDestinationId') - ->with(array('id' => 'test')) - ->will($this->returnValue(array('test'))); + ->with(['id' => 'test']) + ->will($this->returnValue(['test'])); $this->message->expects($this->once()) ->method('display') @@ -381,15 +382,15 @@ public function testImportWithValidRowWithException() { * Tests the processRow method. */ public function testProcessRow() { - $expected = array( + $expected = [ 'test' => 'test destination', 'test1' => 'test1 destination' - ); + ]; foreach ($expected as $key => $value) { $plugins[$key][0] = $this->getMock('Drupal\migrate\Plugin\MigrateProcessInterface'); $plugins[$key][0]->expects($this->once()) ->method('getPluginDefinition') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $plugins[$key][0]->expects($this->once()) ->method('transform') ->will($this->returnValue($value)); @@ -413,10 +414,56 @@ public function testProcessRowEmptyPipeline() { $this->migration->expects($this->once()) ->method('getProcessPlugins') ->with(NULL) - ->will($this->returnValue(array('test' => array()))); + ->will($this->returnValue(['test' => []])); + $row = new Row(); + $this->executable->processRow($row); + $this->assertSame($row->getDestination(), []); + } + + /** + * Tests the processRow pipeline exception. + */ + public function testProcessRowPipelineException() { $row = new Row(); + $plugin = $this->prophesize(MigrateProcessInterface::class); + $plugin->getPluginDefinition()->willReturn(['handle_multiples' => FALSE]); + $plugin->transform(NULL, $this->executable, $row, 'destination_id') + ->willReturn('transform_return_string'); + $plugin->multiple()->willReturn(TRUE); + $plugin->getPluginId()->willReturn('plugin_id'); + $plugin = $plugin->reveal(); + $plugins['destination_id'] = [$plugin, $plugin]; + $this->migration->method('getProcessPlugins')->willReturn($plugins); + + $this->setExpectedException(MigrateException::class, 'Pipeline failed at plugin_id plugin for destination destination_id: transform_return_string received instead of an array,'); $this->executable->processRow($row); - $this->assertSame($row->getDestination(), array()); + } + + /** + * Tests the processRow method. + */ + public function testProcessRowEmptyDestination() { + $expected = [ + 'test' => 'test destination', + 'test1' => 'test1 destination', + 'test2' => NULL, + ]; + $row = new Row(); + $plugins = []; + foreach ($expected as $key => $value) { + $plugin = $this->prophesize(MigrateProcessInterface::class); + $plugin->getPluginDefinition()->willReturn([]); + $plugin->transform(NULL, $this->executable, $row, $key)->willReturn($value); + $plugin->multiple()->willReturn(TRUE); + $plugins[$key][0] = $plugin->reveal(); + } + $this->migration->method('getProcessPlugins')->willReturn($plugins); + $this->executable->processRow($row); + foreach ($expected as $key => $value) { + $this->assertSame($value, $row->getDestinationProperty($key)); + } + $this->assertCount(2, $row->getDestination()); + $this->assertSame(['test2'], $row->getEmptyDestinationProperties()); } /** diff --git a/core/modules/migrate/tests/src/Unit/MigrateSourceTest.php b/core/modules/migrate/tests/src/Unit/MigrateSourceTest.php index 4a462e98..7f3d2937 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateSourceTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSourceTest.php @@ -12,6 +12,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\KeyValueStore\KeyValueFactoryInterface; use Drupal\Core\KeyValueStore\KeyValueStoreInterface; +use Drupal\migrate\MigrateException; use Drupal\migrate\MigrateExecutable; use Drupal\migrate\MigrateSkipRowException; use Drupal\migrate\Plugin\migrate\source\SourcePluginBase; @@ -149,10 +150,10 @@ protected function getSource($configuration = [], $migrate_config = [], $status /** * @covers ::__construct - * @expectedException \Drupal\migrate\MigrateException */ public function testHighwaterTrackChangesIncompatible() { $source_config = ['track_changes' => TRUE, 'high_water_property' => ['name' => 'something']]; + $this->setExpectedException(MigrateException::class); $this->getSource($source_config); } @@ -166,7 +167,7 @@ public function testCount() { $container = new ContainerBuilder(); $cache = $this->getMock(CacheBackendInterface::class); $cache->expects($this->any())->method('set') - ->with($this->isType('string'), $this->isType('int'), $this->isType('int')); + ->with($this->isType('string'), $this->isType('int'), $this->isType('int')); $container->set('cache.migrate', $cache); \Drupal::setContainer($container); @@ -204,7 +205,7 @@ public function testCountCacheKey() { $container = new ContainerBuilder(); $cache = $this->getMock(CacheBackendInterface::class); $cache->expects($this->any())->method('set') - ->with('test_key', $this->isType('int'), $this->isType('int')); + ->with('test_key', $this->isType('int'), $this->isType('int')); $container->set('cache.migrate', $cache); \Drupal::setContainer($container); diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapEnsureTablesTest.php b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapEnsureTablesTest.php index a898a6c8..3c3cba88 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapEnsureTablesTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapEnsureTablesTest.php @@ -16,63 +16,70 @@ class MigrateSqlIdMapEnsureTablesTest extends MigrateTestCase { * * @var array */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'sql_idmap_test', - ); + ]; /** * Tests the ensureTables method when the tables do not exist. */ public function testEnsureTablesNotExist() { - $fields['source_ids_hash'] = Array( + $fields['source_ids_hash'] = [ 'type' => 'varchar', 'length' => 64, 'not null' => 1, 'description' => 'Hash of source ids. Used as primary key' - ); - $fields['sourceid1'] = array( + ]; + $fields['sourceid1'] = [ 'type' => 'int', 'not null' => TRUE, - ); - $fields['destid1'] = array( + ]; + $fields['sourceid2'] = [ + 'type' => 'int', + 'not null' => TRUE, + ]; + $fields['destid1'] = [ 'type' => 'varchar', 'length' => 255, 'not null' => FALSE, - ); - $fields['source_row_status'] = array( + ]; + $fields['source_row_status'] = [ 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => MigrateIdMapInterface::STATUS_IMPORTED, 'description' => 'Indicates current status of the source row', - ); - $fields['rollback_action'] = array( + ]; + $fields['rollback_action'] = [ 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => MigrateIdMapInterface::ROLLBACK_DELETE, 'description' => 'Flag indicating what to do for this item on rollback', - ); - $fields['last_imported'] = array( + ]; + $fields['last_imported'] = [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'UNIX timestamp of the last time this row was imported', - ); - $fields['hash'] = array( + ]; + $fields['hash'] = [ 'type' => 'varchar', 'length' => '64', 'not null' => FALSE, 'description' => 'Hash of source row data, for detecting changes', - ); - $map_table_schema = array( + ]; + $map_table_schema = [ 'description' => 'Mappings from source identifier value(s) to destination identifier value(s).', 'fields' => $fields, - 'primary key' => array('source_ids_hash'), - ); + 'primary key' => ['source_ids_hash'], + 'indexes' => [ + 'source' => ['sourceid1', 'sourceid2'], + ], + ]; $schema = $this->getMockBuilder('Drupal\Core\Database\Schema') ->disableOriginalConstructor() ->getMock(); @@ -84,34 +91,34 @@ public function testEnsureTablesNotExist() { ->method('createTable') ->with('migrate_map_sql_idmap_test', $map_table_schema); // Now do the message table. - $fields = array(); - $fields['msgid'] = array( + $fields = []; + $fields['msgid'] = [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ); - $fields['source_ids_hash'] = Array( + ]; + $fields['source_ids_hash'] = [ 'type' => 'varchar', 'length' => 64, 'not null' => 1, 'description' => 'Hash of source ids. Used as primary key' - ); - $fields['level'] = array( + ]; + $fields['level'] = [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1, - ); - $fields['message'] = array( + ]; + $fields['message'] = [ 'type' => 'text', 'size' => 'medium', 'not null' => TRUE, - ); - $table_schema = array( + ]; + $table_schema = [ 'description' => 'Messages generated during a migration process', 'fields' => $fields, - 'primary key' => array('msgid'), - ); + 'primary key' => ['msgid'], + ]; $schema->expects($this->at(2)) ->method('tableExists') @@ -140,14 +147,14 @@ public function testEnsureTablesExist() { ->method('fieldExists') ->with('migrate_map_sql_idmap_test', 'rollback_action') ->will($this->returnValue(FALSE)); - $field_schema = array( + $field_schema = [ 'type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'Flag indicating what to do for this item on rollback', - ); + ]; $schema->expects($this->at(2)) ->method('addField') ->with('migrate_map_sql_idmap_test', 'rollback_action', $field_schema); @@ -155,12 +162,12 @@ public function testEnsureTablesExist() { ->method('fieldExists') ->with('migrate_map_sql_idmap_test', 'hash') ->will($this->returnValue(FALSE)); - $field_schema = array( + $field_schema = [ 'type' => 'varchar', 'length' => '64', 'not null' => FALSE, 'description' => 'Hash of source row data, for detecting changes', - ); + ]; $schema->expects($this->at(4)) ->method('addField') ->with('migrate_map_sql_idmap_test', 'hash', $field_schema); @@ -168,12 +175,12 @@ public function testEnsureTablesExist() { ->method('fieldExists') ->with('migrate_map_sql_idmap_test', 'source_ids_hash') ->will($this->returnValue(FALSE)); - $field_schema = array( + $field_schema = [ 'type' => 'varchar', 'length' => '64', 'not null' => TRUE, 'description' => 'Hash of source ids. Used as primary key', - ); + ]; $schema->expects($this->at(6)) ->method('addField') ->with('migrate_map_sql_idmap_test', 'source_ids_hash', $field_schema); @@ -201,28 +208,31 @@ protected function runEnsureTablesTest($schema) { $plugin = $this->getMock('Drupal\migrate\Plugin\MigrateSourceInterface'); $plugin->expects($this->any()) ->method('getIds') - ->willReturn(array( - 'source_id_property' => array( + ->willReturn([ + 'source_id_property' => [ + 'type' => 'integer', + ], + 'source_id_property_2' => [ 'type' => 'integer', - ), - )); + ], + ]); $migration->expects($this->any()) ->method('getSourcePlugin') ->willReturn($plugin); $plugin = $this->getMock('Drupal\migrate\Plugin\MigrateSourceInterface'); $plugin->expects($this->any()) ->method('getIds') - ->willReturn(array( - 'destination_id_property' => array( + ->willReturn([ + 'destination_id_property' => [ 'type' => 'string', - ), - )); + ], + ]); $migration->expects($this->any()) ->method('getDestinationPlugin') ->willReturn($plugin); /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher */ $event_dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); - $map = new TestSqlIdMap($database, array(), 'sql', array(), $migration, $event_dispatcher); + $map = new TestSqlIdMap($database, [], 'sql', [], $migration, $event_dispatcher); $map->getDatabase(); } diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php index e38e971b..2ad2b3dc 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php @@ -130,11 +130,11 @@ protected function getIdMap() { * - hash */ protected function idMapDefaults() { - $defaults = array( + $defaults = [ 'source_row_status' => MigrateIdMapInterface::STATUS_IMPORTED, 'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE, 'hash' => '', - ); + ]; // By default, the PDO SQLite driver strongly prefers to return strings // from SELECT queries. Even for columns that don't store strings. Even // if the connection's STRINGIFY_FETCHES attribute is FALSE. This can cause @@ -157,9 +157,9 @@ protected function idMapDefaults() { * - updating work. */ public function testSaveIdMapping() { - $source = array( + $source = [ 'source_id_property' => 'source_value', - ); + ]; $row = new Row($source, ['source_id_property' => []]); $id_map = $this->getIdMap(); $id_map->saveIdMapping($row, ['destination_id_property' => 2]); diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php b/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php index 962a75dc..5f0d550c 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php +++ b/core/modules/migrate/tests/src/Unit/MigrateSqlSourceTestCase.php @@ -33,7 +33,7 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase { * * @var array */ - protected $databaseContents = array(); + protected $databaseContents = []; /** * The plugin class under test. @@ -60,7 +60,7 @@ abstract class MigrateSqlSourceTestCase extends MigrateTestCase { * * @var array */ - protected $expectedResults = array(); + protected $expectedResults = []; /** * Expected count of source rows. @@ -106,13 +106,16 @@ protected function setUp() { \Drupal::setContainer($container); $migration = $this->getMigration(); - $migration->expects($this->any()) - ->method('getHighWater') - ->will($this->returnValue(static::ORIGINAL_HIGH_WATER)); + + // Set the high water value. + \Drupal::keyValue('migrate:high_water') + ->expects($this->any()) + ->method('get') + ->willReturn(static::ORIGINAL_HIGH_WATER); // Setup the plugin. $plugin_class = static::PLUGIN_CLASS; - $plugin = new $plugin_class($this->migrationConfiguration['source'], $this->migrationConfiguration['source']['plugin'], array(), $migration, $state, $entity_manager); + $plugin = new $plugin_class($this->migrationConfiguration['source'], $this->migrationConfiguration['source']['plugin'], [], $migration, $state, $entity_manager); // Do some reflection to set the database and moduleHandler. $plugin_reflection = new \ReflectionClass($plugin); @@ -122,7 +125,7 @@ protected function setUp() { $module_handler_property->setAccessible(TRUE); // Set the database and the module handler onto our plugin. - $database_property->setValue($plugin, $this->getDatabase($this->databaseContents + array('test_map' => array()))); + $database_property->setValue($plugin, $this->getDatabase($this->databaseContents + ['test_map' => []])); $module_handler_property->setValue($plugin, $module_handler); $plugin->setStringTranslation($this->getStringTranslationStub()); diff --git a/core/modules/migrate/tests/src/Unit/MigrateTestCase.php b/core/modules/migrate/tests/src/Unit/MigrateTestCase.php index 19db21a6..20d7662d 100644 --- a/core/modules/migrate/tests/src/Unit/MigrateTestCase.php +++ b/core/modules/migrate/tests/src/Unit/MigrateTestCase.php @@ -61,12 +61,12 @@ protected function getMigration() { // on the test class and use a return callback. $migration->expects($this->any()) ->method('getStatus') - ->willReturnCallback(function() { + ->willReturnCallback(function () { return $this->migrationStatus; }); $migration->expects($this->any()) ->method('setStatus') - ->willReturnCallback(function($status) { + ->willReturnCallback(function ($status) { $this->migrationStatus = $status; }); @@ -147,7 +147,9 @@ protected function getDatabase(array $database_contents, $connection_options = [ protected function createSchemaFromRow(array $row) { // SQLite uses loose ("affinity") typing, so it is OK for every column to be // a text field. - $fields = array_map(function() { return ['type' => 'text']; }, $row); + $fields = array_map(function () { + return ['type' => 'text']; + }, $row); return ['fields' => $fields]; } diff --git a/core/modules/migrate/tests/src/Unit/MigrationPluginManagerTest.php b/core/modules/migrate/tests/src/Unit/MigrationPluginManagerTest.php index 91351cfc..9dbe8501 100644 --- a/core/modules/migrate/tests/src/Unit/MigrationPluginManagerTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrationPluginManagerTest.php @@ -183,7 +183,7 @@ class TestMigrationMock extends Migration { /** * The values passed into set(). * - * @var array $set + * @var array */ public $set = []; diff --git a/core/modules/migrate/tests/src/Unit/MigrationTest.php b/core/modules/migrate/tests/src/Unit/MigrationTest.php index 57ff64c9..649104b3 100644 --- a/core/modules/migrate/tests/src/Unit/MigrationTest.php +++ b/core/modules/migrate/tests/src/Unit/MigrationTest.php @@ -27,9 +27,6 @@ class MigrationTest extends UnitTestCase { * Tests checking requirements for source plugins. * * @covers ::checkRequirements - * - * @expectedException \Drupal\migrate\Exception\RequirementsException - * @expectedExceptionMessage Missing source requirement */ public function testRequirementsForSourcePlugin() { $migration = new TestMigration(); @@ -43,6 +40,7 @@ public function testRequirementsForSourcePlugin() { $migration->setSourcePlugin($source_plugin); $migration->setDestinationPlugin($destination_plugin); + $this->setExpectedException(RequirementsException::class, 'Missing source requirement'); $migration->checkRequirements(); } @@ -50,9 +48,6 @@ public function testRequirementsForSourcePlugin() { * Tests checking requirements for destination plugins. * * @covers ::checkRequirements - * - * @expectedException \Drupal\migrate\Exception\RequirementsException - * @expectedExceptionMessage Missing destination requirement */ public function testRequirementsForDestinationPlugin() { $migration = new TestMigration(); @@ -66,6 +61,7 @@ public function testRequirementsForDestinationPlugin() { $migration->setSourcePlugin($source_plugin); $migration->setDestinationPlugin($destination_plugin); + $this->setExpectedException(RequirementsException::class, 'Missing destination requirement'); $migration->checkRequirements(); } @@ -73,9 +69,6 @@ public function testRequirementsForDestinationPlugin() { * Tests checking requirements for destination plugins. * * @covers ::checkRequirements - * - * @expectedException \Drupal\migrate\Exception\RequirementsException - * @expectedExceptionMessage Missing migrations test_a, test_c */ public function testRequirementsForMigrations() { $migration = new TestMigration(); @@ -112,6 +105,7 @@ public function testRequirementsForMigrations() { ->with(['test_a', 'test_b', 'test_c', 'test_d']) ->willReturn(['test_b' => $migration_b, 'test_c' => $migration_c, 'test_d' => $migration_d]); + $this->setExpectedException(RequirementsException::class, 'Missing migrations test_a, test_c'); $migration->checkRequirements(); } diff --git a/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php b/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php index e5d63c47..4fa08fed 100644 --- a/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php +++ b/core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityContentBaseTest.php @@ -13,6 +13,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Field\FieldTypePluginManagerInterface; +use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\migrate\destination\EntityContentBase; use Drupal\migrate\Plugin\MigrateIdMapInterface; @@ -84,8 +85,6 @@ public function testImport() { * Test row skipping when we can't get an entity to save. * * @covers ::import - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage Unable to get entity */ public function testImportEntityLoadFailure() { $bundles = []; @@ -96,14 +95,12 @@ public function testImportEntityLoadFailure() { $this->entityManager->reveal(), $this->prophesize(FieldTypePluginManagerInterface::class)->reveal()); $destination->setEntity(FALSE); + $this->setExpectedException(MigrateException::class, 'Unable to get entity'); $destination->import(new Row()); } /** * Test that translation destination fails for untranslatable entities. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage This entity type does not support translation */ public function testUntranslatable() { // An entity type without a language. @@ -116,7 +113,7 @@ public function testUntranslatable() { $this->storage->getEntityType()->willReturn($entity_type->reveal()); $destination = new EntityTestDestination( - [ 'translations' => TRUE ], + ['translations' => TRUE], '', [], $this->migration->reveal(), @@ -125,6 +122,7 @@ public function testUntranslatable() { $this->entityManager->reveal(), $this->prophesize(FieldTypePluginManagerInterface::class)->reveal() ); + $this->setExpectedException(MigrateException::class, 'This entity type does not support translation'); $destination->getIds(); } diff --git a/core/modules/migrate/tests/src/Unit/RowTest.php b/core/modules/migrate/tests/src/Unit/RowTest.php index ec04f826..9a20bda5 100644 --- a/core/modules/migrate/tests/src/Unit/RowTest.php +++ b/core/modules/migrate/tests/src/Unit/RowTest.php @@ -17,19 +17,19 @@ class RowTest extends UnitTestCase { * * @var array */ - protected $testSourceIds = array( + protected $testSourceIds = [ 'nid' => 'Node ID', - ); + ]; /** * The test values. * * @var array */ - protected $testValues = array( + protected $testValues = [ 'nid' => 1, 'title' => 'node 1', - ); + ]; /** * The test hash. @@ -50,7 +50,7 @@ class RowTest extends UnitTestCase { */ public function testRowWithoutData() { $row = new Row(); - $this->assertSame(array(), $row->getSource(), 'Empty row'); + $this->assertSame([], $row->getSource(), 'Empty row'); } /** @@ -65,28 +65,25 @@ public function testRowWithBasicData() { * Tests object creation: multiple source IDs. */ public function testRowWithMultipleSourceIds() { - $multi_source_ids = $this->testSourceIds + array('vid' => 'Node revision'); - $multi_source_ids_values = $this->testValues + array('vid' => 1); + $multi_source_ids = $this->testSourceIds + ['vid' => 'Node revision']; + $multi_source_ids_values = $this->testValues + ['vid' => 1]; $row = new Row($multi_source_ids_values, $multi_source_ids); $this->assertSame($multi_source_ids_values, $row->getSource(), 'Row with data, multifield id.'); } /** * Tests object creation: invalid values. - * - * @expectedException \Exception */ public function testRowWithInvalidData() { - $invalid_values = array( + $invalid_values = [ 'title' => 'node X', - ); + ]; + $this->setExpectedException(\Exception::class); $row = new Row($invalid_values, $this->testSourceIds); } /** * Tests source immutability after freeze. - * - * @expectedException \Exception */ public function testSourceFreeze() { $row = new Row($this->testValues, $this->testSourceIds); @@ -96,18 +93,17 @@ public function testSourceFreeze() { $row->rehash(); $this->assertSame($this->testHashMod, $row->getHash(), 'Hash changed correctly.'); $row->freezeSource(); + $this->setExpectedException(\Exception::class); $row->setSourceProperty('title', 'new title'); } /** * Tests setting on a frozen row. - * - * @expectedException \Exception - * @expectedExceptionMessage The source is frozen and can't be changed any more */ public function testSetFrozenRow() { $row = new Row($this->testValues, $this->testSourceIds); $row->freezeSource(); + $this->setExpectedException(\Exception::class, "The source is frozen and can't be changed any more"); $row->setSourceProperty('title', 'new title'); } @@ -123,11 +119,11 @@ public function testHashing() { $this->assertSame($this->testHash, $row->getHash(), 'Correct hash even doing it twice.'); // Set the map to needs update. - $test_id_map = array( + $test_id_map = [ 'original_hash' => '', 'hash' => '', 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, - ); + ]; $row->setIdMap($test_id_map); $this->assertTrue($row->needsUpdate()); @@ -143,30 +139,30 @@ public function testHashing() { $this->assertSame(64, strlen($row->getHash())); // Set the map to successfully imported. - $test_id_map = array( + $test_id_map = [ 'original_hash' => '', 'hash' => '', 'source_row_status' => MigrateIdMapInterface::STATUS_IMPORTED, - ); + ]; $row->setIdMap($test_id_map); $this->assertFalse($row->needsUpdate()); // Set the same hash value and ensure it was not changed. $random = $this->randomMachineName(); - $test_id_map = array( + $test_id_map = [ 'original_hash' => $random, 'hash' => $random, 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, - ); + ]; $row->setIdMap($test_id_map); $this->assertFalse($row->changed()); // Set different has values to ensure it is marked as changed. - $test_id_map = array( + $test_id_map = [ 'original_hash' => $this->randomMachineName(), 'hash' => $this->randomMachineName(), 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, - ); + ]; $row->setIdMap($test_id_map); $this->assertTrue($row->changed()); } @@ -179,11 +175,11 @@ public function testHashing() { */ public function testGetSetIdMap() { $row = new Row($this->testValues, $this->testSourceIds); - $test_id_map = array( + $test_id_map = [ 'original_hash' => '', 'hash' => '', 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, - ); + ]; $row->setIdMap($test_id_map); $this->assertEquals($test_id_map, $row->getIdMap()); } @@ -193,7 +189,40 @@ public function testGetSetIdMap() { */ public function testSourceIdValues() { $row = new Row($this->testValues, $this->testSourceIds); - $this->assertSame(array('nid' => $this->testValues['nid']), $row->getSourceIdValues()); + $this->assertSame(['nid' => $this->testValues['nid']], $row->getSourceIdValues()); + } + + /** + * Tests the multiple source IDs. + */ + public function testMultipleSourceIdValues() { + // Set values in same order as ids. + $multi_source_ids = $this->testSourceIds + [ + 'vid' => 'Node revision', + 'type' => 'Node type', + 'langcode' => 'Node language', + ]; + $multi_source_ids_values = $this->testValues + [ + 'vid' => 1, + 'type' => 'page', + 'langcode' => 'en', + ]; + $row = new Row($multi_source_ids_values, $multi_source_ids); + $this->assertSame(array_keys($multi_source_ids), array_keys($row->getSourceIdValues())); + + // Set values in different order. + $multi_source_ids = $this->testSourceIds + [ + 'vid' => 'Node revision', + 'type' => 'Node type', + 'langcode' => 'Node language', + ]; + $multi_source_ids_values = $this->testValues + [ + 'langcode' => 'en', + 'type' => 'page', + 'vid' => 1, + ]; + $row = new Row($multi_source_ids_values, $multi_source_ids); + $this->assertSame(array_keys($multi_source_ids), array_keys($row->getSourceIdValues())); } /** @@ -219,7 +248,7 @@ public function testDestination() { // Set a destination. $row->setDestinationProperty('nid', 2); $this->assertTrue($row->hasDestinationProperty('nid')); - $this->assertEquals(array('nid' => 2), $row->getDestination()); + $this->assertEquals(['nid' => 2], $row->getDestination()); } /** diff --git a/core/modules/migrate/tests/src/Unit/SqlBaseTest.php b/core/modules/migrate/tests/src/Unit/SqlBaseTest.php index b7dc5eda..b8097a3b 100644 --- a/core/modules/migrate/tests/src/Unit/SqlBaseTest.php +++ b/core/modules/migrate/tests/src/Unit/SqlBaseTest.php @@ -111,13 +111,14 @@ public function sqlBaseTestProvider() { ['driver' => 'mysql', 'username' => 'different_from_map', 'password' => 'different_from_map'], ['driver' => 'mysql', 'username' => 'different_from_source', 'password' => 'different_from_source'], ], - // Returns true because source and id map connection options are the same. + // Returns false because driver is pgsql and the databases are not the + // same. [ + FALSE, TRUE, TRUE, - TRUE, - ['driver' => 'pgsql', 'username' => 'same_value', 'password' => 'same_value'], - ['driver' => 'pgsql', 'username' => 'same_value', 'password' => 'same_value'], + ['driver' => 'pgsql', 'database' => '1.pgsql', 'username' => 'same_value', 'password' => 'same_value'], + ['driver' => 'pgsql', 'database' => '2.pgsql', 'username' => 'same_value', 'password' => 'same_value'], ], // Returns false because driver is sqlite and the databases are not the // same. diff --git a/core/modules/migrate/tests/src/Unit/TestSqlIdMap.php b/core/modules/migrate/tests/src/Unit/TestSqlIdMap.php index b64ca9b1..6d333384 100644 --- a/core/modules/migrate/tests/src/Unit/TestSqlIdMap.php +++ b/core/modules/migrate/tests/src/Unit/TestSqlIdMap.php @@ -55,21 +55,21 @@ public function getDatabase() { */ protected function getFieldSchema(array $id_definition) { if (!isset($id_definition['type'])) { - return array(); + return []; } switch ($id_definition['type']) { case 'integer': - return array( + return [ 'type' => 'int', 'not null' => TRUE, - ); + ]; case 'string': - return array( + return [ 'type' => 'varchar', 'length' => 255, 'not null' => FALSE, - ); + ]; default: throw new MigrateException($id_definition['type'] . ' not supported'); diff --git a/core/modules/migrate/tests/src/Unit/destination/ConfigTest.php b/core/modules/migrate/tests/src/Unit/destination/ConfigTest.php index 25eeebb1..b57cffea 100644 --- a/core/modules/migrate/tests/src/Unit/destination/ConfigTest.php +++ b/core/modules/migrate/tests/src/Unit/destination/ConfigTest.php @@ -16,9 +16,9 @@ class ConfigTest extends UnitTestCase { * Test the import method. */ public function testImport() { - $source = array( + $source = [ 'test' => 'x', - ); + ]; $migration = $this->getMockBuilder('Drupal\migrate\Plugin\Migration') ->disableOriginalConstructor() ->getMock(); @@ -54,7 +54,7 @@ public function testImport() { ->method('getLanguageConfigOverride') ->with('fr', 'd8_config') ->will($this->returnValue($config)); - $destination = new Config(array('config_name' => 'd8_config'), 'd8_config', array('pluginId' => 'd8_config'), $migration, $config_factory, $language_manager); + $destination = new Config(['config_name' => 'd8_config'], 'd8_config', ['pluginId' => 'd8_config'], $migration, $config_factory, $language_manager); $destination_id = $destination->import($row); $this->assertEquals($destination_id, ['d8_config']); } @@ -63,9 +63,9 @@ public function testImport() { * Test the import method. */ public function testLanguageImport() { - $source = array( + $source = [ 'langcode' => 'mi', - ); + ]; $migration = $this->getMockBuilder(MigrationInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -104,7 +104,7 @@ public function testLanguageImport() { ->method('getLanguageConfigOverride') ->with('mi', 'd8_config') ->will($this->returnValue($config)); - $destination = new Config(array('config_name' => 'd8_config', 'translations' => 'true'), 'd8_config', array('pluginId' => 'd8_config'), $migration, $config_factory, $language_manager); + $destination = new Config(['config_name' => 'd8_config', 'translations' => 'true'], 'd8_config', ['pluginId' => 'd8_config'], $migration, $config_factory, $language_manager); $destination_id = $destination->import($row); $this->assertEquals($destination_id, ['d8_config', 'mi']); } diff --git a/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php b/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php index 1886914b..f68c2bea 100644 --- a/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php +++ b/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php @@ -212,7 +212,7 @@ public function getEntity(Row $row, array $old_destination_id_values) { /** * Allow public access for testing. */ - public function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) { + public function save(ContentEntityInterface $entity, array $old_destination_id_values = []) { return parent::save($entity, $old_destination_id_values); } diff --git a/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityDisplayTest.php b/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityDisplayTest.php index 4782dc0f..6deaec88 100644 --- a/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityDisplayTest.php +++ b/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityDisplayTest.php @@ -22,13 +22,13 @@ class PerComponentEntityDisplayTest extends MigrateTestCase { * Tests the entity display import method. */ public function testImport() { - $values = array( + $values = [ 'entity_type' => 'entity_type_test', 'bundle' => 'bundle_test', 'view_mode' => 'view_mode_test', 'field_name' => 'field_name_test', - 'options' => array('test setting'), - ); + 'options' => ['test setting'], + ]; $row = new Row(); foreach ($values as $key => $value) { $row->setDestinationProperty($key, $value); @@ -38,14 +38,14 @@ public function testImport() { ->getMock(); $entity->expects($this->once()) ->method('setComponent') - ->with('field_name_test', array('test setting')) + ->with('field_name_test', ['test setting']) ->will($this->returnSelf()); $entity->expects($this->once()) ->method('save') ->with(); $plugin = new TestPerComponentEntityDisplay($entity); - $this->assertSame($plugin->import($row), array('entity_type_test', 'bundle_test', 'view_mode_test', 'field_name_test')); - $this->assertSame($plugin->getTestValues(), array('entity_type_test', 'bundle_test', 'view_mode_test')); + $this->assertSame($plugin->import($row), ['entity_type_test', 'bundle_test', 'view_mode_test', 'field_name_test']); + $this->assertSame($plugin->getTestValues(), ['entity_type_test', 'bundle_test', 'view_mode_test']); } } diff --git a/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityFormDisplayTest.php b/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityFormDisplayTest.php index 50cdbf6d..0424cebf 100644 --- a/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityFormDisplayTest.php +++ b/core/modules/migrate/tests/src/Unit/destination/PerComponentEntityFormDisplayTest.php @@ -22,13 +22,13 @@ class PerComponentEntityFormDisplayTest extends MigrateTestCase { * Tests the entity display import method. */ public function testImport() { - $values = array( + $values = [ 'entity_type' => 'entity_type_test', 'bundle' => 'bundle_test', 'form_mode' => 'form_mode_test', 'field_name' => 'field_name_test', - 'options' => array('test setting'), - ); + 'options' => ['test setting'], + ]; $row = new Row(); foreach ($values as $key => $value) { $row->setDestinationProperty($key, $value); @@ -38,14 +38,14 @@ public function testImport() { ->getMock(); $entity->expects($this->once()) ->method('setComponent') - ->with('field_name_test', array('test setting')) + ->with('field_name_test', ['test setting']) ->will($this->returnSelf()); $entity->expects($this->once()) ->method('save') ->with(); $plugin = new TestPerComponentEntityFormDisplay($entity); - $this->assertSame($plugin->import($row), array('entity_type_test', 'bundle_test', 'form_mode_test', 'field_name_test')); - $this->assertSame($plugin->getTestValues(), array('entity_type_test', 'bundle_test', 'form_mode_test')); + $this->assertSame($plugin->import($row), ['entity_type_test', 'bundle_test', 'form_mode_test', 'field_name_test']); + $this->assertSame($plugin->getTestValues(), ['entity_type_test', 'bundle_test', 'form_mode_test']); } } diff --git a/core/modules/migrate/tests/src/Unit/process/CallbackTest.php b/core/modules/migrate/tests/src/Unit/process/CallbackTest.php index 92d1f7c3..e3b8f277 100644 --- a/core/modules/migrate/tests/src/Unit/process/CallbackTest.php +++ b/core/modules/migrate/tests/src/Unit/process/CallbackTest.php @@ -37,7 +37,7 @@ public function testCallbackWithFunction() { * Test callback with a class method as callable. */ public function testCallbackWithClassMethod() { - $this->plugin->setCallable(array('\Drupal\Component\Utility\Unicode', 'strtolower')); + $this->plugin->setCallable(['\Drupal\Component\Utility\Unicode', 'strtolower']); $value = $this->plugin->transform('FooBar', $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertSame($value, 'foobar'); } diff --git a/core/modules/migrate/tests/src/Unit/process/ConcatTest.php b/core/modules/migrate/tests/src/Unit/process/ConcatTest.php index 1d0d4c37..ea93e464 100644 --- a/core/modules/migrate/tests/src/Unit/process/ConcatTest.php +++ b/core/modules/migrate/tests/src/Unit/process/ConcatTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\migrate\Unit\process; +use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\migrate\process\Concat; /** @@ -28,16 +29,15 @@ protected function setUp() { * Test concat works without a delimiter. */ public function testConcatWithoutDelimiter() { - $value = $this->plugin->transform(array('foo', 'bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $value = $this->plugin->transform(['foo', 'bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertSame($value, 'foobar'); } /** * Test concat fails properly on non-arrays. - * - * @expectedException \Drupal\migrate\MigrateException */ public function testConcatWithNonArray() { + $this->setExpectedException(MigrateException::class); $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty'); } @@ -46,7 +46,7 @@ public function testConcatWithNonArray() { */ public function testConcatWithDelimiter() { $this->plugin->setDelimiter('_'); - $value = $this->plugin->transform(array('foo', 'bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $value = $this->plugin->transform(['foo', 'bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertSame($value, 'foo_bar'); } diff --git a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php index 4fe8db3b..7b21eff3 100644 --- a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php +++ b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php @@ -2,6 +2,8 @@ namespace Drupal\Tests\migrate\Unit\process; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\Query\QueryInterface; use Drupal\migrate\Plugin\migrate\process\DedupeEntity; use Drupal\Component\Utility\Unicode; @@ -9,32 +11,32 @@ /** * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\DedupeEntity * @group migrate + * @group legacy */ class DedupeEntityTest extends MigrateProcessTestCase { /** * The mock entity query. * - * @var \Drupal\Core\Entity\Query\QueryInterface - * @var \Drupal\Core\Entity\Query\QueryFactory + * @var \Drupal\Core\Entity\Query\QueryInterface|\Drupal\Core\Entity\Query\QueryFactory */ protected $entityQuery; /** - * The mock entity query factory. + * The mocked entity type manager. * - * @var \Drupal\Core\Entity\Query\QueryFactory|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $entityQueryFactory; + protected $entityTypeManager; /** * The migration configuration, initialized to set the ID to test. * * @var array */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'test', - ); + ]; /** * {@inheritdoc} @@ -43,12 +45,16 @@ protected function setUp() { $this->entityQuery = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryInterface') ->disableOriginalConstructor() ->getMock(); - $this->entityQueryFactory = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryFactory') - ->disableOriginalConstructor() - ->getMock(); - $this->entityQueryFactory->expects($this->any()) - ->method('get') - ->will($this->returnValue($this->entityQuery)); + $this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class); + + $storage = $this->getMock(EntityStorageInterface::class); + $storage->expects($this->any()) + ->method('getQuery') + ->willReturn($this->entityQuery); + $this->entityTypeManager->expects($this->any()) + ->method('getStorage') + ->with('test_entity_type') + ->willReturn($storage); parent::setUp(); } @@ -58,16 +64,16 @@ protected function setUp() { * @dataProvider providerTestDedupe */ public function testDedupe($count, $postfix = '', $start = NULL, $length = NULL) { - $configuration = array( + $configuration = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', - ); + ]; if ($postfix) { $configuration['postfix'] = $postfix; } $configuration['start'] = isset($start) ? $start : NULL; $configuration['length'] = isset($length) ? $length : NULL; - $plugin = new DedupeEntity($configuration, 'dedupe_entity', array(), $this->getMigration(), $this->entityQueryFactory); + $plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager); $this->entityQueryExpects($count); $value = $this->randomMachineName(32); $actual = $plugin->transform($value, $this->migrateExecutable, $this->row, 'testproperty'); @@ -80,12 +86,12 @@ public function testDedupe($count, $postfix = '', $start = NULL, $length = NULL) * Tests that invalid start position throws an exception. */ public function testDedupeEntityInvalidStart() { - $configuration = array( + $configuration = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', 'start' => 'foobar', - ); - $plugin = new DedupeEntity($configuration, 'dedupe_entity', array(), $this->getMigration(), $this->entityQueryFactory); + ]; + $plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager); $this->setExpectedException('Drupal\migrate\MigrateException', 'The start position configuration key should be an integer. Omit this key to capture from the beginning of the string.'); $plugin->transform('test_start', $this->migrateExecutable, $this->row, 'testproperty'); } @@ -94,12 +100,12 @@ public function testDedupeEntityInvalidStart() { * Tests that invalid length option throws an exception. */ public function testDedupeEntityInvalidLength() { - $configuration = array( + $configuration = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', 'length' => 'foobar', - ); - $plugin = new DedupeEntity($configuration, 'dedupe_entity', array(), $this->getMigration(), $this->entityQueryFactory); + ]; + $plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager); $this->setExpectedException('Drupal\migrate\MigrateException', 'The character length configuration key should be an integer. Omit this key to capture the entire string.'); $plugin->transform('test_length', $this->migrateExecutable, $this->row, 'testproperty'); } @@ -108,40 +114,40 @@ public function testDedupeEntityInvalidLength() { * Data provider for testDedupe(). */ public function providerTestDedupe() { - return array( + return [ // Tests no duplication. - array(0), + [0], // Tests no duplication and start position. - array(0, NULL, 10), + [0, NULL, 10], // Tests no duplication, start position, and length. - array(0, NULL, 5, 10), + [0, NULL, 5, 10], // Tests no duplication and length. - array(0, NULL, NULL, 10), + [0, NULL, NULL, 10], // Tests duplication. - array(3), + [3], // Tests duplication and start position. - array(3, NULL, 10), + [3, NULL, 10], // Tests duplication, start position, and length. - array(3, NULL, 5, 10), + [3, NULL, 5, 10], // Tests duplication and length. - array(3, NULL, NULL, 10), + [3, NULL, NULL, 10], // Tests no duplication and postfix. - array(0, '_'), + [0, '_'], // Tests no duplication, postfix, and start position. - array(0, '_', 5), + [0, '_', 5], // Tests no duplication, postfix, start position, and length. - array(0, '_', 5, 10), + [0, '_', 5, 10], // Tests no duplication, postfix, and length. - array(0, '_', NULL, 10), + [0, '_', NULL, 10], // Tests duplication and postfix. - array(2, '_'), + [2, '_'], // Tests duplication, postfix, and start position. - array(2, '_', 5), + [2, '_', 5], // Tests duplication, postfix, start position, and length. - array(2, '_', 5, 10), + [2, '_', 5, 10], // Tests duplication, postfix, and length. - array(2, '_', NULL, 10), - ); + [2, '_', NULL, 10], + ]; } /** @@ -159,19 +165,21 @@ protected function entityQueryExpects($count) { ->will($this->returnValue($this->entityQuery)); $this->entityQuery->expects($this->exactly($count + 1)) ->method('execute') - ->will($this->returnCallback(function () use (&$count) { return $count--;})); + ->will($this->returnCallback(function () use (&$count) { + return $count--; + })); } /** * Test deduplicating only migrated entities. */ public function testDedupeMigrated() { - $configuration = array( + $configuration = [ 'entity_type' => 'test_entity_type', 'field' => 'test_field', 'migrated' => TRUE, - ); - $plugin = new DedupeEntity($configuration, 'dedupe_entity', array(), $this->getMigration(), $this->entityQueryFactory); + ]; + $plugin = new DedupeEntity($configuration, 'dedupe_entity', [], $this->getMigration(), $this->entityTypeManager); // Setup the entityQuery used in DedupeEntity::exists. The map, $map, is // an array consisting of the four input parameters to the query condition diff --git a/core/modules/migrate/tests/src/Unit/process/ExplodeTest.php b/core/modules/migrate/tests/src/Unit/process/ExplodeTest.php index 3245e60d..20bf3a03 100644 --- a/core/modules/migrate/tests/src/Unit/process/ExplodeTest.php +++ b/core/modules/migrate/tests/src/Unit/process/ExplodeTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\migrate\Unit\process; +use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\migrate\process\Explode; use Drupal\migrate\Plugin\migrate\process\Concat; @@ -53,23 +54,65 @@ public function testChainedTransform() { /** * Test explode fails properly on non-strings. - * - * @expectedException \Drupal\migrate\MigrateException - * - * @expectedExceptionMessage is not a string */ public function testExplodeWithNonString() { + $this->setExpectedException(MigrateException::class, 'is not a string'); $this->plugin->transform(['foo'], $this->migrateExecutable, $this->row, 'destinationproperty'); } /** - * Test explode fails with empty delimiter. + * Tests that explode works on non-strings but with strict set to FALSE. * - * @expectedException \Drupal\migrate\MigrateException - * - * @expectedExceptionMessage delimiter is empty + * @dataProvider providerExplodeWithNonStrictAndEmptySource + */ + public function testExplodeWithNonStrictAndEmptySource($value, $expected) { + $plugin = new Explode(['delimiter' => '|', 'strict' => FALSE], 'map', []); + + $processed = $plugin->transform($value, $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame($expected, $processed); + } + + /** + * Data provider for ::testExplodeWithNonStrictAndEmptySource(). + */ + public function providerExplodeWithNonStrictAndEmptySource() { + return [ + 'normal_string' => ['a|b|c', ['a', 'b', 'c']], + 'integer_cast_to_string' => [123, ['123']], + 'zero_integer_cast_to_string' => [0, ['0']], + 'true_cast_to_string' => [TRUE, ['1']], + 'null_empty_array' => [NULL, []], + 'false_empty_array' => [FALSE, []], + 'empty_string_empty_array' => ['', []], + ]; + } + + /** + * Tests that explode raises an exception when the value cannot be casted to + * string. + */ + public function testExplodeWithNonStrictAndNonCastable() { + $plugin = new Explode(['delimiter' => '|', 'strict' => FALSE], 'map', []); + $this->setExpectedException(MigrateException::class, 'cannot be casted to a string'); + $processed = $plugin->transform(['foo'], $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame(['foo'], $processed); + } + + /** + * Tests that explode with an empty string and strict check returns a + * non-empty array. + */ + public function testExplodeWithStrictAndEmptyString() { + $plugin = new Explode(['delimiter' => '|'], 'map', []); + $processed = $plugin->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame([''], $processed); + } + + /** + * Test explode fails with empty delimiter. */ public function testExplodeWithEmptyDelimiter() { + $this->setExpectedException(MigrateException::class, 'delimiter is empty'); $plugin = new Explode(['delimiter' => ''], 'map', []); $plugin->transform('foo,bar', $this->migrateExecutable, $this->row, 'destinationproperty'); } diff --git a/core/modules/migrate/tests/src/Unit/process/ExtractTest.php b/core/modules/migrate/tests/src/Unit/process/ExtractTest.php index 26c2cfe2..14f3f9af 100644 --- a/core/modules/migrate/tests/src/Unit/process/ExtractTest.php +++ b/core/modules/migrate/tests/src/Unit/process/ExtractTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\migrate\Unit\process; +use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\migrate\process\Extract; /** @@ -14,8 +15,8 @@ class ExtractTest extends MigrateProcessTestCase { * {@inheritdoc} */ protected function setUp() { - $configuration['index'] = array('foo'); - $this->plugin = new Extract($configuration, 'map', array()); + $configuration['index'] = ['foo']; + $this->plugin = new Extract($configuration, 'map', []); parent::setUp(); } @@ -23,28 +24,24 @@ protected function setUp() { * Tests successful extraction. */ public function testExtract() { - $value = $this->plugin->transform(array('foo' => 'bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $value = $this->plugin->transform(['foo' => 'bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertSame($value, 'bar'); } /** * Tests invalid input. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage Input should be an array. */ public function testExtractFromString() { + $this->setExpectedException(MigrateException::class, 'Input should be an array.'); $this->plugin->transform('bar', $this->migrateExecutable, $this->row, 'destinationproperty'); } /** * Tests unsuccessful extraction. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage Array index missing, extraction failed. */ public function testExtractFail() { - $this->plugin->transform(array('bar' => 'foo'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->setExpectedException(MigrateException::class, 'Array index missing, extraction failed.'); + $this->plugin->transform(['bar' => 'foo'], $this->migrateExecutable, $this->row, 'destinationproperty'); } /** diff --git a/core/modules/migrate/tests/src/Unit/process/FlattenTest.php b/core/modules/migrate/tests/src/Unit/process/FlattenTest.php index 52c19be2..73b20c23 100644 --- a/core/modules/migrate/tests/src/Unit/process/FlattenTest.php +++ b/core/modules/migrate/tests/src/Unit/process/FlattenTest.php @@ -1,8 +1,8 @@ transform(array(1, 2, array(3, 4, array(5)), array(), array(7, 8)), $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($flattened, array(1, 2, 3, 4, 5, 7, 8)); + $plugin = new Flatten([], 'flatten', []); + $flattened = $plugin->transform([1, 2, [3, 4, [5]], [], [7, 8]], $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame($flattened, [1, 2, 3, 4, 5, 7, 8]); } } diff --git a/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php new file mode 100644 index 00000000..c1e0c631 --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php @@ -0,0 +1,124 @@ + '', + 'to_format' => 'Y-m-d', + ]; + + $this->setExpectedException(MigrateException::class, 'Format date plugin is missing from_format configuration.'); + $this->plugin = new FormatDate($configuration, 'test_format_date', []); + $this->plugin->transform('01/05/1955', $this->migrateExecutable, $this->row, 'field_date'); + } + + /** + * Tests that missing configuration will throw an exception. + */ + public function testMigrateExceptionMissingToFormat() { + $configuration = [ + 'from_format' => 'm/d/Y', + 'to_format' => '', + ]; + + $this->setExpectedException(MigrateException::class, 'Format date plugin is missing to_format configuration.'); + $this->plugin = new FormatDate($configuration, 'test_format_date', []); + $this->plugin->transform('01/05/1955', $this->migrateExecutable, $this->row, 'field_date'); + } + + /** + * Tests that date format mismatches will throw an exception. + */ + public function testMigrateExceptionBadFormat() { + $configuration = [ + 'from_format' => 'm/d/Y', + 'to_format' => 'Y-m-d', + ]; + + $this->setExpectedException(MigrateException::class, 'Format date plugin could not transform "January 5, 1955" using the format "m/d/Y". Error: The date cannot be created from a format.'); + $this->plugin = new FormatDate($configuration, 'test_format_date', []); + $this->plugin->transform('January 5, 1955', $this->migrateExecutable, $this->row, 'field_date'); + } + + /** + * Tests transformation. + * + * @covers ::transform + * + * @dataProvider datesDataProvider + * + * @param $configuration + * The configuration of the migration process plugin. + * @param $value + * The source value for the migration process plugin. + * @param $expected + * The expected value of the migration process plugin. + */ + public function testTransform($configuration, $value, $expected) { + $this->plugin = new FormatDate($configuration, 'test_format_date', []); + $actual = $this->plugin->transform($value, $this->migrateExecutable, $this->row, 'field_date'); + + $this->assertEquals($expected, $actual); + } + + /** + * Data provider of test dates. + * + * @return array + * Array of date formats and actual/expected values. + */ + public function datesDataProvider() { + return [ + 'datetime_date' => [ + 'configuration' => [ + 'from_format' => 'm/d/Y', + 'to_format' => 'Y-m-d', + ], + 'value' => '01/05/1955', + 'expected' => '1955-01-05', + ], + 'datetime_datetime' => [ + 'configuration' => [ + 'from_format' => 'm/d/Y H:i:s', + 'to_format' => 'Y-m-d\TH:i:s', + ], + 'value' => '01/05/1955 10:43:22', + 'expected' => '1955-01-05T10:43:22', + ], + 'empty_values' => [ + 'configuration' => [ + 'from_format' => 'm/d/Y', + 'to_format' => 'Y-m-d', + ], + 'value' => '', + 'expected' => '', + ], + 'timezone' => [ + 'configuration' => [ + 'from_format' => 'Y-m-d\TH:i:sO', + 'to_format' => 'Y-m-d\TH:i:s', + 'timezone' => 'America/Managua', + ], + 'value' => '2004-12-19T10:19:42-0600', + 'expected' => '2004-12-19T10:19:42', + ], + ]; + } + +} diff --git a/core/modules/migrate/tests/src/Unit/process/GetTest.php b/core/modules/migrate/tests/src/Unit/process/GetTest.php index ae24d98c..59ce8b68 100644 --- a/core/modules/migrate/tests/src/Unit/process/GetTest.php +++ b/core/modules/migrate/tests/src/Unit/process/GetTest.php @@ -41,16 +41,18 @@ public function testTransformSourceString() { * Tests the Get plugin when source is an array. */ public function testTransformSourceArray() { - $map = array( + $map = [ 'test1' => 'source_value1', 'test2' => 'source_value2', - ); - $this->plugin->setSource(array('test1', 'test2')); + ]; + $this->plugin->setSource(['test1', 'test2']); $this->row->expects($this->exactly(2)) ->method('getSourceProperty') - ->will($this->returnCallback(function ($argument) use ($map) { return $map[$argument]; } )); + ->will($this->returnCallback(function ($argument) use ($map) { + return $map[$argument]; + })); $value = $this->plugin->transform(NULL, $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, array('source_value1', 'source_value2')); + $this->assertSame($value, ['source_value1', 'source_value2']); } /** @@ -70,18 +72,20 @@ public function testTransformSourceStringAt() { * Tests the Get plugin when source is an array pointing to destination. */ public function testTransformSourceArrayAt() { - $map = array( + $map = [ 'test1' => 'source_value1', '@test2' => 'source_value2', '@test3' => 'source_value3', 'test4' => 'source_value4', - ); - $this->plugin->setSource(array('test1', '@@test2', '@@test3', 'test4')); + ]; + $this->plugin->setSource(['test1', '@@test2', '@@test3', 'test4']); $this->row->expects($this->exactly(4)) ->method('getSourceProperty') - ->will($this->returnCallback(function ($argument) use ($map) { return $map[$argument]; } )); + ->will($this->returnCallback(function ($argument) use ($map) { + return $map[$argument]; + })); $value = $this->plugin->transform(NULL, $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, array('source_value1', 'source_value2', 'source_value3', 'source_value4')); + $this->assertSame($value, ['source_value1', 'source_value2', 'source_value3', 'source_value4']); } /** diff --git a/core/modules/migrate/tests/src/Unit/process/IteratorTest.php b/core/modules/migrate/tests/src/Unit/process/IteratorTest.php index cdffac07..46daadef 100644 --- a/core/modules/migrate/tests/src/Unit/process/IteratorTest.php +++ b/core/modules/migrate/tests/src/Unit/process/IteratorTest.php @@ -25,34 +25,36 @@ class IteratorTest extends MigrateTestCase { /** * @var array */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'test', - ); + ]; /** * Tests the iterator process plugin. + * + * @group legacy */ public function testIterator() { $migration = $this->getMigration(); // Set up the properties for the iterator. - $configuration = array( - 'process' => array( + $configuration = [ + 'process' => [ 'foo' => 'source_foo', 'id' => 'source_id', - ), + ], 'key' => '@id', - ); - $plugin = new Iterator($configuration, 'iterator', array()); + ]; + $plugin = new Iterator($configuration, 'iterator', []); // Manually create the plugins. Migration::getProcessPlugins does this // normally but the plugin system is not available. foreach ($configuration['process'] as $destination => $source) { - $iterator_plugins[$destination][] = new Get(array('source' => $source), 'get', array()); + $iterator_plugins[$destination][] = new Get(['source' => $source], 'get', []); } $migration->expects($this->at(1)) ->method('getProcessPlugins') ->will($this->returnValue($iterator_plugins)); // Set up the key plugins. - $key_plugin['key'][] = new Get(array('source' => '@id'), 'get', array()); + $key_plugin['key'][] = new Get(['source' => '@id'], 'get', []); $migration->expects($this->at(2)) ->method('getProcessPlugins') ->will($this->returnValue($key_plugin)); @@ -60,12 +62,12 @@ public function testIterator() { $migrate_executable = new MigrateExecutable($migration, $this->getMock('Drupal\migrate\MigrateMessageInterface'), $event_dispatcher); // The current value of the pipeline. - $current_value = array( - array( + $current_value = [ + [ 'source_foo' => 'test', 'source_id' => 42, - ), - ); + ], + ]; // This is not used but the interface requires it, so create an empty row. $row = new Row(); diff --git a/core/modules/migrate/tests/src/Unit/process/MachineNameTest.php b/core/modules/migrate/tests/src/Unit/process/MachineNameTest.php index 7f44157f..5bc91587 100644 --- a/core/modules/migrate/tests/src/Unit/process/MachineNameTest.php +++ b/core/modules/migrate/tests/src/Unit/process/MachineNameTest.php @@ -53,7 +53,7 @@ public function testMachineNames() { ->with($human_name) ->will($this->returnValue($human_name_ascii . 'aeo')); - $plugin = new MachineName(array(), 'machine_name', array(), $this->transliteration); + $plugin = new MachineName([], 'machine_name', [], $this->transliteration); $value = $plugin->transform($human_name, $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertEquals($expected_result, $value); } diff --git a/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php b/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php new file mode 100644 index 00000000..27557d18 --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/MakeUniqueEntityFieldTest.php @@ -0,0 +1,215 @@ + 'test', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + $this->entityQuery = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class); + + $storage = $this->getMock(EntityStorageInterface::class); + $storage->expects($this->any()) + ->method('getQuery') + ->willReturn($this->entityQuery); + $this->entityTypeManager->expects($this->any()) + ->method('getStorage') + ->with('test_entity_type') + ->willReturn($storage); + parent::setUp(); + } + + /** + * Tests making an entity field value unique. + * + * @dataProvider providerTestMakeUniqueEntityField + */ + public function testMakeUniqueEntityField($count, $postfix = '', $start = NULL, $length = NULL) { + $configuration = [ + 'entity_type' => 'test_entity_type', + 'field' => 'test_field', + ]; + if ($postfix) { + $configuration['postfix'] = $postfix; + } + $configuration['start'] = isset($start) ? $start : NULL; + $configuration['length'] = isset($length) ? $length : NULL; + $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager); + $this->entityQueryExpects($count); + $value = $this->randomMachineName(32); + $actual = $plugin->transform($value, $this->migrateExecutable, $this->row, 'testproperty'); + $expected = Unicode::substr($value, $start, $length); + $expected .= $count ? $postfix . $count : ''; + $this->assertSame($expected, $actual); + } + + /** + * Tests that invalid start position throws an exception. + */ + public function testMakeUniqueEntityFieldEntityInvalidStart() { + $configuration = [ + 'entity_type' => 'test_entity_type', + 'field' => 'test_field', + 'start' => 'foobar', + ]; + $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager); + $this->setExpectedException('Drupal\migrate\MigrateException', 'The start position configuration key should be an integer. Omit this key to capture from the beginning of the string.'); + $plugin->transform('test_start', $this->migrateExecutable, $this->row, 'testproperty'); + } + + /** + * Tests that invalid length option throws an exception. + */ + public function testMakeUniqueEntityFieldEntityInvalidLength() { + $configuration = [ + 'entity_type' => 'test_entity_type', + 'field' => 'test_field', + 'length' => 'foobar', + ]; + $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager); + $this->setExpectedException('Drupal\migrate\MigrateException', 'The character length configuration key should be an integer. Omit this key to capture the entire string.'); + $plugin->transform('test_length', $this->migrateExecutable, $this->row, 'testproperty'); + } + + /** + * Data provider for testMakeUniqueEntityField(). + */ + public function providerTestMakeUniqueEntityField() { + return [ + // Tests no duplication. + [0], + // Tests no duplication and start position. + [0, NULL, 10], + // Tests no duplication, start position, and length. + [0, NULL, 5, 10], + // Tests no duplication and length. + [0, NULL, NULL, 10], + // Tests duplication. + [3], + // Tests duplication and start position. + [3, NULL, 10], + // Tests duplication, start position, and length. + [3, NULL, 5, 10], + // Tests duplication and length. + [3, NULL, NULL, 10], + // Tests no duplication and postfix. + [0, '_'], + // Tests no duplication, postfix, and start position. + [0, '_', 5], + // Tests no duplication, postfix, start position, and length. + [0, '_', 5, 10], + // Tests no duplication, postfix, and length. + [0, '_', NULL, 10], + // Tests duplication and postfix. + [2, '_'], + // Tests duplication, postfix, and start position. + [2, '_', 5], + // Tests duplication, postfix, start position, and length. + [2, '_', 5, 10], + // Tests duplication, postfix, and length. + [2, '_', NULL, 10], + ]; + } + + /** + * Helper function to add expectations to the mock entity query object. + * + * @param int $count + * The number of unique values to be set up. + */ + protected function entityQueryExpects($count) { + $this->entityQuery->expects($this->exactly($count + 1)) + ->method('condition') + ->will($this->returnValue($this->entityQuery)); + $this->entityQuery->expects($this->exactly($count + 1)) + ->method('count') + ->will($this->returnValue($this->entityQuery)); + $this->entityQuery->expects($this->exactly($count + 1)) + ->method('execute') + ->will($this->returnCallback(function () use (&$count) { + return $count--; + })); + } + + /** + * Tests making an entity field value unique only for migrated entities. + */ + public function testMakeUniqueEntityFieldMigrated() { + $configuration = [ + 'entity_type' => 'test_entity_type', + 'field' => 'test_field', + 'migrated' => TRUE, + ]; + $plugin = new MakeUniqueEntityField($configuration, 'make_unique', [], $this->getMigration(), $this->entityTypeManager); + + // Setup the entityQuery used in MakeUniqueEntityFieldEntity::exists. The + // map, $map, is an array consisting of the four input parameters to the + // query condition method and then the query to return. Both 'forum' and + // 'test_vocab' are existing entities. There is no 'test_vocab1'. + $map = []; + foreach (['forums', 'test_vocab', 'test_vocab1'] as $id) { + $query = $this->prophesize(QueryInterface::class); + $query->willBeConstructedWith([]); + $query->execute()->willReturn($id === 'test_vocab1' ? [] : [$id]); + $map[] = ['test_field', $id, NULL, NULL, $query->reveal()]; + } + $this->entityQuery + ->method('condition') + ->will($this->returnValueMap($map)); + + // Entity 'forums' is pre-existing, entity 'test_vocab' was migrated. + $this->idMap + ->method('lookupSourceID') + ->will($this->returnValueMap([ + [['test_field' => 'forums'], FALSE], + [['test_field' => 'test_vocab'], ['source_id' => 42]], + ])); + + // Existing entity 'forums' was not migrated, value should not be unique. + $actual = $plugin->transform('forums', $this->migrateExecutable, $this->row, 'testproperty'); + $this->assertEquals('forums', $actual, 'Pre-existing name is re-used'); + + // Entity 'test_vocab' was migrated, value should be unique. + $actual = $plugin->transform('test_vocab', $this->migrateExecutable, $this->row, 'testproperty'); + $this->assertEquals('test_vocab1', $actual, 'Migrated name is deduplicated'); + } + +} diff --git a/core/modules/migrate/tests/src/Unit/process/MigrationLookupTest.php b/core/modules/migrate/tests/src/Unit/process/MigrationLookupTest.php new file mode 100644 index 00000000..dd18928d --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/MigrationLookupTest.php @@ -0,0 +1,241 @@ +prophesize(MigrationInterface::class); + $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); + $process_plugin_manager = $this->prophesize(MigratePluginManager::class); + + $destination_id_map = $this->prophesize(MigrateIdMapInterface::class); + $destination_migration = $this->prophesize(MigrationInterface::class); + $destination_migration->getIdMap()->willReturn($destination_id_map->reveal()); + $destination_id_map->lookupDestinationId([1])->willReturn(NULL); + + // Ensure the migration plugin manager returns our migration. + $migration_plugin_manager->createInstances(Argument::exact(['destination_migration'])) + ->willReturn(['destination_migration' => $destination_migration->reveal()]); + + $configuration = [ + 'no_stub' => TRUE, + 'migration' => 'destination_migration', + ]; + + $migration_plugin->id()->willReturn('actual_migration'); + $destination_migration->getDestinationPlugin(TRUE)->shouldNotBeCalled(); + + $migration = new MigrationLookup($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $result = $migration->transform(1, $this->migrateExecutable, $this->row, ''); + $this->assertNull($result); + } + + /** + * @covers ::transform + */ + public function testTransformWithStubbing() { + $migration_plugin = $this->prophesize(MigrationInterface::class); + $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); + $process_plugin_manager = $this->prophesize(MigratePluginManager::class); + + $destination_id_map = $this->prophesize(MigrateIdMapInterface::class); + $destination_migration = $this->prophesize('Drupal\migrate\Plugin\Migration'); + $destination_migration->getIdMap()->willReturn($destination_id_map->reveal()); + $migration_plugin_manager->createInstances(['destination_migration']) + ->willReturn(['destination_migration' => $destination_migration->reveal()]); + $destination_id_map->lookupDestinationId([1])->willReturn(NULL); + $destination_id_map->saveIdMapping(Argument::any(), Argument::any(), MigrateIdMapInterface::STATUS_NEEDS_UPDATE)->willReturn(NULL); + + $configuration = [ + 'no_stub' => FALSE, + 'migration' => 'destination_migration', + ]; + + $migration_plugin->id()->willReturn('actual_migration'); + $destination_migration->id()->willReturn('destination_migration'); + $destination_migration->getDestinationPlugin(TRUE)->shouldBeCalled(); + $destination_migration->getProcess()->willReturn([]); + $destination_migration->getSourceConfiguration()->willReturn([]); + + $source_plugin = $this->prophesize(MigrateSourceInterface::class); + $source_plugin->getIds()->willReturn(['nid']); + $destination_migration->getSourcePlugin()->willReturn($source_plugin->reveal()); + $destination_plugin = $this->prophesize(MigrateDestinationInterface::class); + $destination_plugin->import(Argument::any())->willReturn([2]); + $destination_migration->getDestinationPlugin(TRUE)->willReturn($destination_plugin->reveal()); + + $migration = new MigrationLookup($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $result = $migration->transform(1, $this->migrateExecutable, $this->row, ''); + $this->assertEquals(2, $result); + } + + /** + * Tests that processing is skipped when the input value is empty. + */ + public function testSkipOnEmpty() { + $migration_plugin = $this->prophesize(MigrationInterface::class); + $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); + $process_plugin_manager = $this->prophesize(MigratePluginManager::class); + + $configuration = [ + 'migration' => 'foobaz', + ]; + $migration_plugin->id()->willReturn(uniqid()); + $migration = new MigrationLookup($configuration, 'migration_lookup', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $this->setExpectedException(MigrateSkipProcessException::class); + $migration->transform(0, $this->migrateExecutable, $this->row, 'foo'); + } + + /** + * Tests a successful lookup. + * + * @dataProvider successfulLookupDataProvider + * + * @param array $source_id_values + * The source id(s) of the migration map. + * @param array $destination_id_values + * The destination id(s) of the migration map. + * @param string|array $source_value + * The source value(s) for the migration process plugin. + * @param string|array $expected_value + * The expected value(s) of the migration process plugin. + */ + public function testSuccessfulLookup($source_id_values, $destination_id_values, $source_value, $expected_value) { + $migration_plugin = $this->prophesize(MigrationInterface::class); + $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); + $process_plugin_manager = $this->prophesize(MigratePluginManager::class); + + $configuration = [ + 'migration' => 'foobaz', + ]; + $migration_plugin->id()->willReturn(uniqid()); + + $id_map = $this->prophesize(MigrateIdMapInterface::class); + $id_map->lookupDestinationId($source_id_values)->willReturn($destination_id_values); + $migration_plugin->getIdMap()->willReturn($id_map->reveal()); + + $migration_plugin_manager->createInstances(['foobaz']) + ->willReturn(['foobaz' => $migration_plugin->reveal()]); + + $migrationStorage = $this->prophesize(EntityStorageInterface::class); + $migrationStorage + ->loadMultiple(['foobaz']) + ->willReturn([$migration_plugin->reveal()]); + + $migration = new MigrationLookup($configuration, 'migration_lookup', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $this->assertSame($expected_value, $migration->transform($source_value, $this->migrateExecutable, $this->row, 'foo')); + } + + /** + * Provides data for the successful lookup test. + * + * @return array + */ + public function successfulLookupDataProvider() { + return [ + // Test data for scalar to scalar. + [ + // Source ID of the migration map. + [1], + // Destination ID of the migration map. + [3], + // Input value for the migration plugin. + 1, + // Expected output value of the migration plugin. + 3, + ], + // Test data for scalar to array. + [ + // Source ID of the migration map. + [1], + // Destination IDs of the migration map. + [3, 'foo'], + // Input value for the migration plugin. + 1, + // Expected output values of the migration plugin. + [3, 'foo'], + ], + // Test data for array to scalar. + [ + // Source IDs of the migration map. + [1, 3], + // Destination ID of the migration map. + ['foo'], + // Input values for the migration plugin. + [1, 3], + // Expected output value of the migration plugin. + 'foo', + ], + // Test data for array to array. + [ + // Source IDs of the migration map. + [1, 3], + // Destination IDs of the migration map. + [3, 'foo'], + // Input values for the migration plugin. + [1, 3], + // Expected output values of the migration plugin. + [3, 'foo'], + ], + ]; + } + + /** + * Tests that a message is successfully created if import fails. + */ + public function testImportException() { + $migration_plugin = $this->prophesize(MigrationInterface::class); + $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); + $process_plugin_manager = $this->prophesize(MigratePluginManager::class); + + $destination_id_map = $this->prophesize(MigrateIdMapInterface::class); + $destination_migration = $this->prophesize('Drupal\migrate\Plugin\Migration'); + $destination_migration->getIdMap()->willReturn($destination_id_map->reveal()); + $migration_plugin_manager->createInstances(['destination_migration']) + ->willReturn(['destination_migration' => $destination_migration->reveal()]); + $destination_id_map->lookupDestinationId([1])->willReturn(NULL); + $destination_id_map->saveMessage(Argument::any(), Argument::any())->willReturn(NULL); + $destination_id_map->saveIdMapping(Argument::any(), Argument::any(), Argument::any())->shouldNotBeCalled(); + + $configuration = [ + 'no_stub' => FALSE, + 'migration' => 'destination_migration', + ]; + + $destination_migration->id()->willReturn('destination_migration'); + $destination_migration->getDestinationPlugin(TRUE)->shouldBeCalled(); + $destination_migration->getProcess()->willReturn([]); + $destination_migration->getSourceConfiguration()->willReturn([]); + + $source_plugin = $this->prophesize(MigrateSourceInterface::class); + $source_plugin->getIds()->willReturn(['nid']); + $destination_migration->getSourcePlugin()->willReturn($source_plugin->reveal()); + $destination_plugin = $this->prophesize(MigrateDestinationInterface::class); + $e = new \Exception(); + $destination_plugin->import(Argument::any())->willThrow($e); + $destination_migration->getDestinationPlugin(TRUE)->willReturn($destination_plugin->reveal()); + + $migration = new MigrationLookup($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $migration->transform(1, $this->migrateExecutable, $this->row, ''); + } + +} diff --git a/core/modules/migrate/tests/src/Unit/process/MigrationTest.php b/core/modules/migrate/tests/src/Unit/process/MigrationTest.php index b62c1f93..cade905a 100644 --- a/core/modules/migrate/tests/src/Unit/process/MigrationTest.php +++ b/core/modules/migrate/tests/src/Unit/process/MigrationTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\migrate\Unit\process; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\migrate\MigrateSkipProcessException; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\migrate\process\Migration; use Drupal\migrate\Plugin\MigrateDestinationInterface; @@ -15,24 +16,45 @@ /** * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\Migration * @group migrate + * @group legacy */ class MigrationTest extends MigrateProcessTestCase { + /** + * @var \Drupal\migrate\Plugin\MigrationInterface + */ + protected $migration_plugin; + + /** + * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface + */ + protected $migration_plugin_manager; + + /** + * @var \Drupal\migrate\Plugin\MigratePluginManager + */ + protected $process_plugin_manager; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->migration_plugin = $this->prophesize(MigrationInterface::class); + $this->migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); + $this->process_plugin_manager = $this->prophesize(MigratePluginManager::class); + } + /** * @covers ::transform */ public function testTransformWithStubSkipping() { - $migration_plugin = $this->prophesize(MigrationInterface::class); - $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); - $process_plugin_manager = $this->prophesize(MigratePluginManager::class); - - $destination_id_map = $this->prophesize(MigrateIdMapInterface::class); - $destination_migration = $this->prophesize(MigrationInterface::class); - $destination_migration->getIdMap()->willReturn($destination_id_map->reveal()); - $destination_id_map->lookupDestinationId([1])->willReturn(NULL); + $destination_migration = $this->getMigration(); + $destination_migration->getDestinationPlugin(TRUE)->shouldNotBeCalled(); // Ensure the migration plugin manager returns our migration. - $migration_plugin_manager->createInstances(Argument::exact(['destination_migration'])) + $this->migration_plugin_manager->createInstances(Argument::exact(['destination_migration'])) ->willReturn(['destination_migration' => $destination_migration->reveal()]); $configuration = [ @@ -40,10 +62,9 @@ public function testTransformWithStubSkipping() { 'migration' => 'destination_migration', ]; - $migration_plugin->id()->willReturn('actual_migration'); - $destination_migration->getDestinationPlugin(TRUE)->shouldNotBeCalled(); + $this->migration_plugin->id()->willReturn('actual_migration'); - $migration = new Migration($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $migration = new Migration($configuration, '', [], $this->migration_plugin->reveal(), $this->migration_plugin_manager->reveal(), $this->process_plugin_manager->reveal()); $result = $migration->transform(1, $this->migrateExecutable, $this->row, ''); $this->assertNull($result); } @@ -52,24 +73,16 @@ public function testTransformWithStubSkipping() { * @covers ::transform */ public function testTransformWithStubbing() { - $migration_plugin = $this->prophesize(MigrationInterface::class); - $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); - $process_plugin_manager = $this->prophesize(MigratePluginManager::class); - - $destination_id_map = $this->prophesize(MigrateIdMapInterface::class); - $destination_migration = $this->prophesize('Drupal\migrate\Plugin\Migration'); - $destination_migration->getIdMap()->willReturn($destination_id_map->reveal()); - $migration_plugin_manager->createInstances(['destination_migration']) + $destination_migration = $this->getMigration(); + $this->migration_plugin_manager->createInstances(['destination_migration']) ->willReturn(['destination_migration' => $destination_migration->reveal()]); - $destination_id_map->lookupDestinationId([1])->willReturn(NULL); - $destination_id_map->saveIdMapping(Argument::any(), Argument::any(), MigrateIdMapInterface::STATUS_NEEDS_UPDATE)->willReturn(NULL); $configuration = [ 'no_stub' => FALSE, 'migration' => 'destination_migration', ]; - $migration_plugin->id()->willReturn('actual_migration'); + $this->migration_plugin->id()->willReturn('actual_migration'); $destination_migration->id()->willReturn('destination_migration'); $destination_migration->getDestinationPlugin(TRUE)->shouldBeCalled(); $destination_migration->getProcess()->willReturn([]); @@ -82,26 +95,37 @@ public function testTransformWithStubbing() { $destination_plugin->import(Argument::any())->willReturn([2]); $destination_migration->getDestinationPlugin(TRUE)->willReturn($destination_plugin->reveal()); - $migration = new Migration($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $migration = new Migration($configuration, '', [], $this->migration_plugin->reveal(), $this->migration_plugin_manager->reveal(), $this->process_plugin_manager->reveal()); $result = $migration->transform(1, $this->migrateExecutable, $this->row, ''); $this->assertEquals(2, $result); } /** - * Tests that processing is skipped when the input value is empty. + * Creates a mock Migration instance. * - * @expectedException \Drupal\migrate\MigrateSkipProcessException + * @return \Prophecy\Prophecy\ObjectProphecy + * A mock Migration instance. */ - public function testSkipOnEmpty() { - $migration_plugin = $this->prophesize(MigrationInterface::class); - $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); - $process_plugin_manager = $this->prophesize(MigratePluginManager::class); + protected function getMigration() { + $id_map = $this->prophesize(MigrateIdMapInterface::class); + $id_map->lookupDestinationId([1])->willReturn(NULL); + $id_map->saveIdMapping(Argument::any(), Argument::any(), MigrateIdMapInterface::STATUS_NEEDS_UPDATE)->willReturn(NULL); + $migration = $this->prophesize(MigrationInterface::class); + $migration->getIdMap()->willReturn($id_map->reveal()); + return $migration; + } + + /** + * Tests that processing is skipped when the input value is empty. + */ + public function testSkipOnEmpty() { $configuration = [ 'migration' => 'foobaz', ]; - $migration_plugin->id()->willReturn(uniqid()); - $migration = new Migration($configuration, 'migration', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $this->migration_plugin->id()->willReturn(uniqid()); + $migration = new Migration($configuration, 'migration', [], $this->migration_plugin->reveal(), $this->migration_plugin_manager->reveal(), $this->process_plugin_manager->reveal()); + $this->setExpectedException(MigrateSkipProcessException::class); $migration->transform(0, $this->migrateExecutable, $this->row, 'foo'); } @@ -120,28 +144,24 @@ public function testSkipOnEmpty() { * The expected value(s) of the migration process plugin. */ public function testSuccessfulLookup($source_id_values, $destination_id_values, $source_value, $expected_value) { - $migration_plugin = $this->prophesize(MigrationInterface::class); - $migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class); - $process_plugin_manager = $this->prophesize(MigratePluginManager::class); - $configuration = [ 'migration' => 'foobaz', ]; - $migration_plugin->id()->willReturn(uniqid()); + $this->migration_plugin->id()->willReturn(uniqid()); $id_map = $this->prophesize(MigrateIdMapInterface::class); $id_map->lookupDestinationId($source_id_values)->willReturn($destination_id_values); - $migration_plugin->getIdMap()->willReturn($id_map->reveal()); + $this->migration_plugin->getIdMap()->willReturn($id_map->reveal()); - $migration_plugin_manager->createInstances(['foobaz']) - ->willReturn(['foobaz' => $migration_plugin->reveal()]); + $this->migration_plugin_manager->createInstances(['foobaz']) + ->willReturn(['foobaz' => $this->migration_plugin->reveal()]); $migrationStorage = $this->prophesize(EntityStorageInterface::class); $migrationStorage ->loadMultiple(['foobaz']) - ->willReturn([$migration_plugin->reveal()]); + ->willReturn([$this->migration_plugin->reveal()]); - $migration = new Migration($configuration, 'migration', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal()); + $migration = new Migration($configuration, 'migration', [], $this->migration_plugin->reveal(), $this->migration_plugin_manager->reveal(), $this->process_plugin_manager->reveal()); $this->assertSame($expected_value, $migration->transform($source_value, $this->migrateExecutable, $this->row, 'foo')); } @@ -152,49 +172,29 @@ public function testSuccessfulLookup($source_id_values, $destination_id_values, */ public function successfulLookupDataProvider() { return [ - // Test data for scalar to scalar. - [ - // Source ID of the migration map. - [1], - // Destination ID of the migration map. - [3], - // Input value for the migration plugin. - 1, - // Expected output value of the migration plugin. - 3, + 'scalar_to_scalar' => [ + 'source_ids' => [1], + 'destination_ids' => [3], + 'input_value' => 1, + 'expected_value' => 3, ], - // Test data for scalar to array. - [ - // Source ID of the migration map. - [1], - // Destination IDs of the migration map. - [3, 'foo'], - // Input value for the migration plugin. - 1, - // Expected output values of the migration plugin. - [3, 'foo'], + 'scalar_to_array' => [ + 'source_ids' => [1], + 'destination_ids' => [3, 'foo'], + 'input_value' => 1, + 'expected_value' => [3, 'foo'], ], - // Test data for array to scalar. - [ - // Source IDs of the migration map. - [1, 3], - // Destination ID of the migration map. - ['foo'], - // Input values for the migration plugin. - [1, 3], - // Expected output value of the migration plugin. - 'foo', + 'array_to_scalar' => [ + 'source_ids' => [1, 3], + 'destination_ids' => ['foo'], + 'input_value' => [1, 3], + 'expected_value' => 'foo', ], - // Test data for array to array. - [ - // Source IDs of the migration map. - [1, 3], - // Destination IDs of the migration map. - [3, 'foo'], - // Input values for the migration plugin. - [1, 3], - // Expected output values of the migration plugin. - [3, 'foo'], + 'array_to_array' => [ + 'source_ids' => [1, 3], + 'destination_ids' => [3, 'foo'], + 'input_value' => [1, 3], + 'expected_value' => [3, 'foo'], ], ]; } diff --git a/core/modules/migrate/tests/src/Unit/process/SkipOnEmptyTest.php b/core/modules/migrate/tests/src/Unit/process/SkipOnEmptyTest.php index bf40dac7..08fbef23 100644 --- a/core/modules/migrate/tests/src/Unit/process/SkipOnEmptyTest.php +++ b/core/modules/migrate/tests/src/Unit/process/SkipOnEmptyTest.php @@ -1,6 +1,9 @@ setExpectedException(MigrateSkipProcessException::class); (new SkipOnEmpty($configuration, 'skip_on_empty', [])) ->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); } @@ -33,10 +36,10 @@ public function testProcessBypassesOnNonEmpty() { /** * @covers ::row - * @expectedException \Drupal\migrate\MigrateSkipRowException */ public function testRowSkipsOnEmpty() { $configuration['method'] = 'row'; + $this->setExpectedException(MigrateSkipRowException::class); (new SkipOnEmpty($configuration, 'skip_on_empty', [])) ->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); } @@ -51,4 +54,33 @@ public function testRowBypassesOnNonEmpty() { $this->assertSame($value, ' '); } + /** + * Tests that a skip row exception without a message is raised. + * + * @covers ::row + */ + public function testRowSkipWithoutMessage() { + $configuration = [ + 'method' => 'row', + ]; + $process = new SkipOnEmpty($configuration, 'skip_on_empty', []); + $this->setExpectedException(MigrateSkipRowException::class); + $process->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); + } + + /** + * Tests that a skip row exception with a message is raised. + * + * @covers ::row + */ + public function testRowSkipWithMessage() { + $configuration = [ + 'method' => 'row', + 'message' => 'The value is empty', + ]; + $process = new SkipOnEmpty($configuration, 'skip_on_empty', []); + $this->setExpectedException(MigrateSkipRowException::class, 'The value is empty'); + $process->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); + } + } diff --git a/core/modules/migrate/tests/src/Unit/process/SkipRowIfNotSetTest.php b/core/modules/migrate/tests/src/Unit/process/SkipRowIfNotSetTest.php new file mode 100644 index 00000000..26e5b3fb --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/SkipRowIfNotSetTest.php @@ -0,0 +1,45 @@ + 'some_key', + ]; + $process = new SkipRowIfNotSet($configuration, 'skip_row_if_not_set', []); + $this->setExpectedException(MigrateSkipRowException::class); + $process->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); + } + + /** + * Tests that a skip row exception with a message is raised. + * + * @covers ::transform + */ + public function testRowSkipWithMessage() { + $configuration = [ + 'index' => 'some_key', + 'message' => "The 'some_key' key is not set", + ]; + $process = new SkipRowIfNotSet($configuration, 'skip_row_if_not_set', []); + $this->setExpectedException(MigrateSkipRowException::class, "The 'some_key' key is not set"); + $process->transform('', $this->migrateExecutable, $this->row, 'destinationproperty'); + } + +} diff --git a/core/modules/migrate/tests/src/Unit/process/StaticMapTest.php b/core/modules/migrate/tests/src/Unit/process/StaticMapTest.php index 59db2e57..714d5f7c 100644 --- a/core/modules/migrate/tests/src/Unit/process/StaticMapTest.php +++ b/core/modules/migrate/tests/src/Unit/process/StaticMapTest.php @@ -2,6 +2,8 @@ namespace Drupal\Tests\migrate\Unit\process; +use Drupal\migrate\MigrateException; +use Drupal\migrate\MigrateSkipRowException; use Drupal\migrate\Plugin\migrate\process\StaticMap; /** @@ -16,7 +18,7 @@ class StaticMapTest extends MigrateProcessTestCase { */ protected function setUp() { $configuration['map']['foo']['bar'] = 'baz'; - $this->plugin = new StaticMap($configuration, 'map', array()); + $this->plugin = new StaticMap($configuration, 'map', []); parent::setUp(); } @@ -25,33 +27,31 @@ protected function setUp() { */ public function testMapWithSourceString() { $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, array('bar' => 'baz')); + $this->assertSame($value, ['bar' => 'baz']); } /** * Tests map when the source is a list. */ public function testMapWithSourceList() { - $value = $this->plugin->transform(array('foo', 'bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $value = $this->plugin->transform(['foo', 'bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertSame($value, 'baz'); } /** * Tests when the source is empty. - * - * @expectedException \Drupal\migrate\MigrateException */ public function testMapwithEmptySource() { - $this->plugin->transform(array(), $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->setExpectedException(MigrateException::class); + $this->plugin->transform([], $this->migrateExecutable, $this->row, 'destinationproperty'); } /** * Tests when the source is invalid. - * - * @expectedException \Drupal\migrate\MigrateSkipRowException */ public function testMapwithInvalidSource() { - $this->plugin->transform(array('bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->setExpectedException(MigrateSkipRowException::class); + $this->plugin->transform(['bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); } /** @@ -60,8 +60,8 @@ public function testMapwithInvalidSource() { public function testMapWithInvalidSourceWithADefaultValue() { $configuration['map']['foo']['bar'] = 'baz'; $configuration['default_value'] = 'test'; - $this->plugin = new StaticMap($configuration, 'map', array()); - $value = $this->plugin->transform(array('bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->plugin = new StaticMap($configuration, 'map', []); + $value = $this->plugin->transform(['bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertSame($value, 'test'); } @@ -72,22 +72,20 @@ public function testMapWithInvalidSourceWithANullDefaultValue() { $configuration['map']['foo']['bar'] = 'baz'; $configuration['default_value'] = NULL; $this->plugin = new StaticMap($configuration, 'map', []); - $value = $this->plugin->transform(array('bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $value = $this->plugin->transform(['bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); $this->assertNull($value); } /** * Tests when the source is invalid and bypass is enabled. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage Setting both default_value and bypass is invalid. */ public function testMapWithInvalidSourceAndBypass() { $configuration['map']['foo']['bar'] = 'baz'; $configuration['default_value'] = 'test'; $configuration['bypass'] = TRUE; - $this->plugin = new StaticMap($configuration, 'map', array()); - $this->plugin->transform(array('bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->plugin = new StaticMap($configuration, 'map', []); + $this->setExpectedException(MigrateException::class, 'Setting both default_value and bypass is invalid.'); + $this->plugin->transform(['bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); } } diff --git a/core/modules/migrate/tests/src/Unit/process/SubProcessTest.php b/core/modules/migrate/tests/src/Unit/process/SubProcessTest.php new file mode 100644 index 00000000..dfcdec3b --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/SubProcessTest.php @@ -0,0 +1,82 @@ + 'test', + ]; + + /** + * Tests the sub_process process plugin. + */ + public function testSubProcess() { + $migration = $this->getMigration(); + // Set up the properties for the sub_process. + $configuration = [ + 'process' => [ + 'foo' => 'source_foo', + 'id' => 'source_id', + ], + 'key' => '@id', + ]; + $plugin = new SubProcess($configuration, 'sub_process', []); + // Manually create the plugins. Migration::getProcessPlugins does this + // normally but the plugin system is not available. + foreach ($configuration['process'] as $destination => $source) { + $sub_process_plugins[$destination][] = new Get(['source' => $source], 'get', []); + } + $migration->expects($this->at(1)) + ->method('getProcessPlugins') + ->willReturn($sub_process_plugins); + // Set up the key plugins. + $key_plugin['key'][] = new Get(['source' => '@id'], 'get', []); + $migration->expects($this->at(2)) + ->method('getProcessPlugins') + ->will($this->returnValue($key_plugin)); + $event_dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $migrate_executable = new MigrateExecutable($migration, $this->getMock('Drupal\migrate\MigrateMessageInterface'), $event_dispatcher); + + // The current value of the pipeline. + $current_value = [ + [ + 'source_foo' => 'test', + 'source_id' => 42, + ], + ]; + // This is not used but the interface requires it, so create an empty row. + $row = new Row(); + + // After transformation, check to make sure that source_foo and source_id's + // values ended up in the proper destinations, and that the value of the + // key (@id) is the same as the destination ID (42). + $new_value = $plugin->transform($current_value, $migrate_executable, $row, 'test'); + $this->assertSame(count($new_value), 1); + $this->assertSame(count($new_value[42]), 2); + $this->assertSame($new_value[42]['foo'], 'test'); + $this->assertSame($new_value[42]['id'], 42); + } + +} diff --git a/core/modules/migrate/tests/src/Unit/process/SubstrTest.php b/core/modules/migrate/tests/src/Unit/process/SubstrTest.php index fb84509b..6a73905d 100644 --- a/core/modules/migrate/tests/src/Unit/process/SubstrTest.php +++ b/core/modules/migrate/tests/src/Unit/process/SubstrTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\migrate\Unit\process; +use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\migrate\process\Substr; /** @@ -55,37 +56,31 @@ public function providerTestSubstr() { /** * Tests invalid input type. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage The input value must be a string. */ public function testSubstrFail() { $configuration = []; $this->plugin = new Substr($configuration, 'map', []); + $this->setExpectedException(MigrateException::class, 'The input value must be a string.'); $this->plugin->transform(['Captain Janeway'], $this->migrateExecutable, $this->row, 'destinationproperty'); } /** * Tests that the start parameter is an integer. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage The start position configuration value should be an integer. Omit this key to capture from the beginning of the string. */ public function testStartIsString() { $configuration['start'] = '2'; $this->plugin = new Substr($configuration, 'map', []); + $this->setExpectedException(MigrateException::class, 'The start position configuration value should be an integer. Omit this key to capture from the beginning of the string.'); $this->plugin->transform(['foo'], $this->migrateExecutable, $this->row, 'destinationproperty'); } /** * Tests that the length parameter is an integer. - * - * @expectedException \Drupal\migrate\MigrateException - * @expectedExceptionMessage The character length configuration value should be an integer. Omit this key to capture from the start position to the end of the string. */ public function testLengthIsString() { $configuration['length'] = '1'; $this->plugin = new Substr($configuration, 'map', []); + $this->setExpectedException(MigrateException::class, 'The character length configuration value should be an integer. Omit this key to capture from the start position to the end of the string.'); $this->plugin->transform(['foo'], $this->migrateExecutable, $this->row, 'destinationproperty'); } diff --git a/core/modules/migrate/tests/src/Unit/process/UrlEncodeTest.php b/core/modules/migrate/tests/src/Unit/process/UrlEncodeTest.php index 78d89a16..1f7d94ae 100644 --- a/core/modules/migrate/tests/src/Unit/process/UrlEncodeTest.php +++ b/core/modules/migrate/tests/src/Unit/process/UrlEncodeTest.php @@ -28,14 +28,14 @@ class UrlEncodeTest extends MigrateTestCase { * An array of URLs to test. */ public function urlDataProvider() { - return array( - 'A URL with no characters requiring encoding' => array('http://example.com/normal_url.html', 'http://example.com/normal_url.html'), - 'The definitive use case - encoding spaces in URLs' => array('http://example.com/url with spaces.html', 'http://example.com/url%20with%20spaces.html'), - 'Definitive use case 2 - spaces in directories' => array('http://example.com/dir with spaces/foo.html', 'http://example.com/dir%20with%20spaces/foo.html'), - 'Local filespecs without spaces should not be transformed' => array('/tmp/normal.txt', '/tmp/normal.txt'), - 'Local filespecs with spaces should not be transformed' => array('/tmp/with spaces.txt', '/tmp/with spaces.txt'), - 'Make sure URL characters (:, ?, &) are not encoded but others are.' => array('https://example.com/?a=b@c&d=e+f%', 'https://example.com/?a%3Db%40c&d%3De%2Bf%25'), - ); + return [ + 'A URL with no characters requiring encoding' => ['http://example.com/normal_url.html', 'http://example.com/normal_url.html'], + 'The definitive use case - encoding spaces in URLs' => ['http://example.com/url with spaces.html', 'http://example.com/url%20with%20spaces.html'], + 'Definitive use case 2 - spaces in directories' => ['http://example.com/dir with spaces/foo.html', 'http://example.com/dir%20with%20spaces/foo.html'], + 'Local filespecs without spaces should not be transformed' => ['/tmp/normal.txt', '/tmp/normal.txt'], + 'Local filespecs with spaces should not be transformed' => ['/tmp/with spaces.txt', '/tmp/with spaces.txt'], + 'Make sure URL characters (:, ?, &) are not encoded but others are.' => ['https://example.com/?a=b@c&d=e+f%', 'https://example.com/?a%3Db%40c&d%3De%2Bf%25'], + ]; } /** diff --git a/core/modules/migrate_drupal/migrate_drupal.info.yml b/core/modules/migrate_drupal/migrate_drupal.info.yml index da68d4dc..a933e793 100644 --- a/core/modules/migrate_drupal/migrate_drupal.info.yml +++ b/core/modules/migrate_drupal/migrate_drupal.info.yml @@ -7,8 +7,8 @@ package: Core (Experimental) dependencies: - migrate -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate_drupal/migrate_drupal.module b/core/modules/migrate_drupal/migrate_drupal.module index dc3ab4ee..2de25951 100644 --- a/core/modules/migrate_drupal/migrate_drupal.module +++ b/core/modules/migrate_drupal/migrate_drupal.module @@ -20,7 +20,7 @@ function migrate_drupal_help($route_name, RouteMatchInterface $route_match) { case 'help.page.migrate_drupal': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Migrate Drupal module provides a framework based on the Migrate module to facilitate migration from a Drupal (6, 7, or 8) site to your website. It does not provide a user interface. For more information, see the online documentation for the Migrate Drupal module.', array(':migrate' => \Drupal::url('help.page', array('name' => 'migrate')), ':migrate_drupal' => 'https://www.drupal.org/documentation/modules/migrate_drupal')) . '

    '; + $output .= '

    ' . t('The Migrate Drupal module provides a framework based on the Migrate module to facilitate migration from a Drupal (6, 7, or 8) site to your website. It does not provide a user interface. For more information, see the online documentation for the Migrate Drupal module.', [':migrate' => \Drupal::url('help.page', ['name' => 'migrate']), ':migrate_drupal' => 'https://www.drupal.org/documentation/modules/migrate_drupal']) . '

    '; return $output; } } @@ -56,9 +56,17 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { $source_vid = $row->getSourceProperty('vid'); $plugin_ids = ['d6_term_node:' . $source_vid, 'd6_term_node_revision:' . $source_vid]; foreach ($plugin_ids as $plugin_id) { - if (isset($definitions[$plugin_id])) { - $definitions[$plugin_id]['process'][$row->getDestinationProperty('vid')] = 'tid'; - } + // Match the field name derivation in d6_vocabulary_field.yml. + $field_name = substr('field_' . $row->getDestinationProperty('vid'), 0, 32); + + // The Forum module is expecting 'taxonomy_forums' as the field name + // for the forum nodes. The 'forum_vocabulary' source property is + // evaluated in Drupal\taxonomy\Plugin\migrate\source\d6\Vocabulary + // and is set to true if the vocabulary vid being migrated is the + // same as the one in the 'forum_nav_vocabulary' variable on the + // source site. + $destination_vid = $row->getSourceProperty('forum_vocabulary') ? 'taxonomy_forums' : $field_name; + $definitions[$plugin_id]['process'][$destination_vid] = 'tid'; } } } diff --git a/core/modules/migrate_drupal/migrate_drupal.services.yml b/core/modules/migrate_drupal/migrate_drupal.services.yml index 71a0b277..23b3492b 100644 --- a/core/modules/migrate_drupal/migrate_drupal.services.yml +++ b/core/modules/migrate_drupal/migrate_drupal.services.yml @@ -1,4 +1,12 @@ services: + plugin.manager.migrate.field: + class: Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager + arguments: + - field + - '@container.namespaces' + - '@cache.discovery' + - '@module_handler' + - '\Drupal\migrate_drupal\Annotation\MigrateField' plugin.manager.migrate.cckfield: class: Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManager arguments: @@ -7,3 +15,4 @@ services: - '@cache.discovery' - '@module_handler' - '\Drupal\migrate_drupal\Annotation\MigrateCckField' + deprecated: The "%service_id%" service is deprecated. You should use the 'plugin.manager.migrate.field' service instead. See https://www.drupal.org/node/2751897 diff --git a/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php b/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php index 5e5a5004..20558200 100644 --- a/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php +++ b/core/modules/migrate_drupal/src/Annotation/MigrateCckField.php @@ -2,53 +2,20 @@ namespace Drupal\migrate_drupal\Annotation; -use Drupal\Component\Annotation\Plugin; +@trigger_error('MigrateCckField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField instead.', E_USER_DEPRECATED); /** - * Defines a cckfield plugin annotation object. + * Deprecated: Defines a cckfield plugin annotation object. * - * cckfield plugins are variously responsible for handling the migration of - * CCK fields from Drupal 6 to Drupal 8, and Field API fields from Drupal 7 - * to Drupal 8. They are allowed to alter CCK-related migrations when migrations - * are being generated, and can compute destination field types for individual - * fields during the actual migration process. + * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use + * \Drupal\migrate_drupal\Annotation\MigrateField instead. * * Plugin Namespace: Plugin\migrate\cckfield * + * @see https://www.drupal.org/node/2751897 + * * @Annotation */ -class MigrateCckField extends Plugin { - - /** - * @inheritdoc - */ - public function __construct($values) { - parent::__construct($values); - // Provide default value for core property, in case it's missing. - if (empty($this->definition['core'])) { - $this->definition['core'] = [6]; - } - } - - /** - * The plugin ID. - * - * @var string - */ - public $id; - - /** - * Map of D6 and D7 field types to D8 field type plugin IDs. - * - * @var string[] - */ - public $type_map = []; - - /** - * The Drupal core version(s) this plugin applies to. - * - * @var int[] - */ - public $core = []; +class MigrateCckField extends MigrateField { } diff --git a/core/modules/migrate_drupal/src/Annotation/MigrateField.php b/core/modules/migrate_drupal/src/Annotation/MigrateField.php new file mode 100644 index 00000000..ad78bc92 --- /dev/null +++ b/core/modules/migrate_drupal/src/Annotation/MigrateField.php @@ -0,0 +1,54 @@ +definition['core'])) { + $this->definition['core'] = [6]; + } + } + + /** + * The plugin ID. + * + * @var string + */ + public $id; + + /** + * Map of D6 and D7 field types to D8 field type plugin IDs. + * + * @var string[] + */ + public $type_map = []; + + /** + * The Drupal core version(s) this plugin applies to. + * + * @var int[] + */ + public $core = []; + +} diff --git a/core/modules/migrate_drupal/src/MigrationCreationTrait.php b/core/modules/migrate_drupal/src/MigrationCreationTrait.php index 7fa44bb1..7894e91c 100644 --- a/core/modules/migrate_drupal/src/MigrationCreationTrait.php +++ b/core/modules/migrate_drupal/src/MigrationCreationTrait.php @@ -2,10 +2,11 @@ namespace Drupal\migrate_drupal; - /** * @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.0. Use * \Drupal\migrate_drupal\MigrationConfigurationTrait instead. + * + * @see https://www.drupal.org/node/2873794 */ trait MigrationCreationTrait { use MigrationConfigurationTrait; diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php index b30b2b81..6dceeab7 100644 --- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php +++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php @@ -2,64 +2,19 @@ namespace Drupal\migrate_drupal\Plugin; -use Drupal\Component\Plugin\PluginInspectionInterface; +@trigger_error('MigrateCckFieldInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateField instead.', E_USER_DEPRECATED); + use Drupal\migrate\Plugin\MigrationInterface; -use Drupal\migrate\Row; /** * Provides an interface for all CCK field type plugins. + * + * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use + * \Drupal\migrate_drupal\Annotation\MigrateField instead. + * + * @see https://www.drupal.org/node/2751897 */ -interface MigrateCckFieldInterface extends PluginInspectionInterface { - - /** - * Apply any custom processing to the field migration. - * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * The migration entity. - */ - public function processField(MigrationInterface $migration); - - /** - * Apply any custom processing to the field instance migration. - * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * The migration entity. - */ - public function processFieldInstance(MigrationInterface $migration); - - /** - * Apply any custom processing to the field widget migration. - * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * The migration entity. - */ - public function processFieldWidget(MigrationInterface $migration); - - /** - * Apply any custom processing to the field formatter migration. - * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * The migration entity. - */ - public function processFieldFormatter(MigrationInterface $migration); - - /** - * Get a map between D6 formatters and D8 formatters for this field type. - * - * This is used by static::processFieldFormatter() in the base class. - * - * @return array - * The keys are D6 formatters and the values are D8 formatters. - */ - public function getFieldFormatterMap(); - - /** - * Get a map between D6 and D8 widgets for this field type. - * - * @return array - * The keys are D6 field widget types and the values D8 widgets. - */ - public function getFieldWidgetMap(); +interface MigrateCckFieldInterface extends MigrateFieldInterface { /** * Apply any custom processing to the cck bundle migrations. @@ -73,15 +28,4 @@ public function getFieldWidgetMap(); */ public function processCckFieldValues(MigrationInterface $migration, $field_name, $data); - /** - * Computes the destination type of a migrated field. - * - * @param \Drupal\migrate\Row $row - * The field being migrated. - * - * @return string - * The destination field type. - */ - public function getFieldType(Row $row); - } diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php index 56c7b5ba..515e71e0 100644 --- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php +++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManager.php @@ -2,54 +2,16 @@ namespace Drupal\migrate_drupal\Plugin; -use Drupal\Component\Plugin\Exception\PluginNotFoundException; -use Drupal\migrate\Plugin\MigratePluginManager; -use Drupal\migrate\Plugin\MigrationInterface; +@trigger_error('MigrateCckFieldPluginManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManager instead.', E_USER_DEPRECATED); /** - * Plugin manager for migrate cckfield plugins. + * Deprecated: Plugin manager for migrate field plugins. * - * @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface - * @see \Drupal\migrate\Annotation\MigrateCckField - * @see plugin_api + * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use + * \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManager instead. + * + * @see https://www.drupal.org/node/2751897 * * @ingroup migration */ -class MigrateCckFieldPluginManager extends MigratePluginManager implements MigrateCckFieldPluginManagerInterface { - - /** - * The default version of core to use for cck field plugins. - * - * These plugins were initially only built and used for Drupal 6 fields. - * Having been extended for Drupal 7 with a "core" annotation, we fall back to - * Drupal 6 where none exists. - */ - const DEFAULT_CORE_VERSION = 6; - - /** - * {@inheritdoc} - */ - public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL) { - $core = static::DEFAULT_CORE_VERSION; - if (!empty($configuration['core'])) { - $core = $configuration['core']; - } - elseif (!empty($migration->getPluginDefinition()['migration_tags'])) { - foreach ($migration->getPluginDefinition()['migration_tags'] as $tag) { - if ($tag == 'Drupal 7') { - $core = 7; - } - } - } - - foreach ($this->getDefinitions() as $plugin_id => $definition) { - if (in_array($core, $definition['core'])) { - if (array_key_exists($field_type, $definition['type_map']) || $field_type === $plugin_id) { - return $plugin_id; - } - } - } - throw new PluginNotFoundException($field_type); - } - -} +class MigrateCckFieldPluginManager extends MigrateFieldPluginManager implements MigrateCckFieldPluginManagerInterface {} diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php index a5371b9d..8eba728f 100644 --- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php +++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldPluginManagerInterface.php @@ -2,27 +2,14 @@ namespace Drupal\migrate_drupal\Plugin; -use Drupal\migrate\Plugin\MigratePluginManagerInterface; -use Drupal\migrate\Plugin\MigrationInterface; - -interface MigrateCckFieldPluginManagerInterface extends MigratePluginManagerInterface { - - /** - * Get the plugin ID from the field type. - * - * @param string $field_type - * The field type being migrated. - * @param array $configuration - * (optional) An array of configuration relevant to the plugin instance. - * @param \Drupal\migrate\Plugin\MigrationInterface|null $migration - * (optional) The current migration instance. - * - * @return string - * The ID of the plugin for the field_type if available. - * - * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException - * If the plugin cannot be determined, such as if the field type is invalid. - */ - public function getPluginIdFromFieldType($field_type, array $configuration = [], MigrationInterface $migration = NULL); - -} +@trigger_error('MigrateCckFieldPluginManagerInterface is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Annotation\MigrateFieldPluginManagerInterface instead.', E_USER_DEPRECATED); + +/** + * Provides an interface for cck field plugin manager. + * + * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use + * \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface instead. + * + * @see https://www.drupal.org/node/2751897 + */ +interface MigrateCckFieldPluginManagerInterface extends MigrateFieldPluginManagerInterface {} diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateFieldInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateFieldInterface.php new file mode 100644 index 00000000..2aac5d18 --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldInterface.php @@ -0,0 +1,109 @@ +getPluginDefinition()['migration_tags'])) { + foreach ($migration->getPluginDefinition()['migration_tags'] as $tag) { + if ($tag == 'Drupal 7') { + $core = 7; + } + } + } + + $definitions = $this->getDefinitions(); + foreach ($definitions as $plugin_id => $definition) { + if (in_array($core, $definition['core'])) { + if (array_key_exists($field_type, $definition['type_map']) || $field_type === $plugin_id) { + return $plugin_id; + } + } + } + throw new PluginNotFoundException($field_type); + } + +} diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManagerInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManagerInterface.php new file mode 100644 index 00000000..7219c2b3 --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/MigrateFieldPluginManagerInterface.php @@ -0,0 +1,28 @@ +cckPluginManager = $cck_manager; - } +class CckMigration extends FieldMigration { /** * {@inheritdoc} */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('plugin.manager.migrate.cckfield'), - $container->get('plugin.manager.migration'), - $container->get('plugin.manager.migrate.source'), - $container->get('plugin.manager.migrate.process'), - $container->get('plugin.manager.migrate.destination'), - $container->get('plugin.manager.migrate.id_map') - ); - } - - /** - * {@inheritdoc} - */ - public function getProcess() { - if (!$this->init) { - $this->init = TRUE; - $source_plugin = $this->migrationPluginManager->createInstance($this->pluginId)->getSourcePlugin(); - if ($source_plugin instanceof RequirementsInterface) { - try { - $source_plugin->checkRequirements(); - } - catch (RequirementsException $e) { - // Kill the rest of the method. - $source_plugin = []; - } - } - foreach ($source_plugin as $row) { - $field_type = $row->getSourceProperty('type'); - try { - $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this); - } - catch (PluginNotFoundException $ex) { - continue; - } - - if (!isset($this->processedFieldTypes[$field_type])) { - $this->processedFieldTypes[$field_type] = TRUE; - // Allow the cckfield plugin to alter the migration as necessary so - // that it knows how to handle fields of this type. - if (!isset($this->cckPluginCache[$field_type])) { - $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, [], $this); - } - call_user_func([$this->cckPluginCache[$field_type], $this->pluginDefinition['cck_plugin_method']], $this); - } - } - } - return parent::getProcess(); - } + const PLUGIN_METHOD = 'cck_plugin_method'; } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php b/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php new file mode 100644 index 00000000..3ca8f26a --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php @@ -0,0 +1,171 @@ +cckPluginManager = $cck_manager; + $this->fieldPluginManager = $field_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('plugin.manager.migrate.cckfield'), + $container->get('plugin.manager.migrate.field'), + $container->get('plugin.manager.migration'), + $container->get('plugin.manager.migrate.source'), + $container->get('plugin.manager.migrate.process'), + $container->get('plugin.manager.migrate.destination'), + $container->get('plugin.manager.migrate.id_map') + ); + } + + /** + * {@inheritdoc} + */ + public function getProcess() { + if (!$this->init) { + $this->init = TRUE; + $source_plugin = $this->migrationPluginManager->createInstance($this->pluginId)->getSourcePlugin(); + if ($source_plugin instanceof RequirementsInterface) { + try { + $source_plugin->checkRequirements(); + } + catch (RequirementsException $e) { + // Kill the rest of the method. + $source_plugin = []; + } + } + foreach ($source_plugin as $row) { + $field_type = $row->getSourceProperty('type'); + + try { + $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, [], $this); + $manager = $this->fieldPluginManager; + } + catch (PluginNotFoundException $ex) { + try { + $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, [], $this); + $manager = $this->cckPluginManager; + } + catch (PluginNotFoundException $ex) { + continue; + } + } + + if (!isset($this->processedFieldTypes[$field_type]) && $manager->hasDefinition($plugin_id)) { + $this->processedFieldTypes[$field_type] = TRUE; + // Allow the field plugin to alter the migration as necessary so that + // it knows how to handle fields of this type. + if (!isset($this->fieldPluginCache[$field_type])) { + $this->fieldPluginCache[$field_type] = $manager->createInstance($plugin_id, [], $this); + } + } + $method = $this->pluginDefinition[static::PLUGIN_METHOD]; + call_user_func([$this->fieldPluginCache[$field_type], $method], $this); + } + } + return parent::getProcess(); + } + +} diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php index d942bce2..220c8bbd 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/cckfield/CckFieldPluginBase.php @@ -2,82 +2,50 @@ namespace Drupal\migrate_drupal\Plugin\migrate\cckfield; -use Drupal\Core\Plugin\PluginBase; +@trigger_error('CckFieldPluginBase is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase instead.', E_USER_DEPRECATED); + use Drupal\migrate\Plugin\MigrationInterface; -use Drupal\migrate\Row; +use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase; use Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface; /** - * The base class for all cck field plugins. + * The base class for all field plugins. + * + * @deprecated in Drupal 8.4.x, to be removed before Drupal 9.0.x. Use + * \Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase instead. * - * @see \Drupal\migrate\Plugin\MigratePluginManager - * @see \Drupal\migrate_drupal\Annotation\MigrateCckField - * @see \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface - * @see plugin_api + * @see https://www.drupal.org/node/2751897 * * @ingroup migration */ -abstract class CckFieldPluginBase extends PluginBase implements MigrateCckFieldInterface { - - /** - * {@inheritdoc} - */ - public function processField(MigrationInterface $migration) { - $process[0]['map'][$this->pluginId][$this->pluginId] = $this->pluginId; - $migration->mergeProcessOfProperty('type', $process); - } - - /** - * {@inheritdoc} - */ - public function processFieldInstance(MigrationInterface $migration) { - // Nothing to do by default with field instances. - } +abstract class CckFieldPluginBase extends FieldPluginBase implements MigrateCckFieldInterface { /** - * {@inheritdoc} + * Apply any custom processing to the field bundle migrations. + * + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The migration entity. + * @param string $field_name + * The field name we're processing the value for. + * @param array $data + * The array of field data from FieldValues::fieldData(). */ - public function processFieldWidget(MigrationInterface $migration) { - $process = []; - foreach ($this->getFieldWidgetMap() as $source_widget => $destination_widget) { - $process['type']['map'][$source_widget] = $destination_widget; - } - $migration->mergeProcessOfProperty('options/type', $process); + public function processFieldValues(MigrationInterface $migration, $field_name, $data) { + // Provide a bridge to the old method declared on the interface and now an + // abstract method in this class. + return $this->processCckFieldValues($migration, $field_name, $data); } /** - * {@inheritdoc} + * Apply any custom processing to the field bundle migrations. + * + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The migration entity. + * @param string $field_name + * The field name we're processing the value for. + * @param array $data + * The array of field data from FieldValues::fieldData(). */ - public function getFieldWidgetMap() { - // By default, use the plugin ID for the widget types. - return [ - $this->pluginId => $this->pluginId . '_default', - ]; - } - - /** - * {@inheritdoc} - */ - public function processFieldFormatter(MigrationInterface $migration) { - $process = []; - foreach ($this->getFieldFormatterMap() as $source_format => $destination_format) { - $process[0]['map'][$this->pluginId][$source_format] = $destination_format; - } - $migration->mergeProcessOfProperty('options/type', $process); - } - - /** - * {@inheritdoc} - */ - public function getFieldType(Row $row) { - $field_type = $row->getSourceProperty('type'); - - if (isset($this->pluginDefinition['type_map'][$field_type])) { - return $this->pluginDefinition['type_map'][$field_type]; - } - else { - return $field_type; - } - } + abstract public function processCckFieldValues(MigrationInterface $migration, $field_name, $data); } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php index 169390a6..c5e631a0 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php @@ -2,8 +2,10 @@ namespace Drupal\migrate_drupal\Plugin\migrate\destination; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; +use Drupal\Core\Language\LanguageManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\migrate\destination\EntityFieldStorageConfig as BaseEntityFieldStorageConfig; @@ -45,11 +47,17 @@ class EntityFieldStorageConfig extends BaseEntityFieldStorageConfig { * The storage for this entity type. * @param array $bundles * The list of bundles this entity type has. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The configuration factory. * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager * The field type plugin manager. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, FieldTypePluginManagerInterface $field_type_plugin_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles); + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, FieldTypePluginManagerInterface $field_type_plugin_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $language_manager, $config_factory, $field_type_plugin_manager); + $this->languageManager = $language_manager; + $this->configFactory = $config_factory; $this->fieldTypePluginManager = $field_type_plugin_manager; } @@ -65,6 +73,8 @@ public static function create(ContainerInterface $container, array $configuratio $migration, $container->get('entity.manager')->getStorage($entity_type_id), array_keys($container->get('entity.manager')->getBundleInfo($entity_type_id)), + $container->get('language_manager'), + $container->get('config.factory'), $container->get('plugin.manager.field.field_type') ); } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/field/FieldPluginBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/field/FieldPluginBase.php new file mode 100644 index 00000000..dc115abc --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/field/FieldPluginBase.php @@ -0,0 +1,120 @@ +pluginId][$this->pluginId] = $this->pluginId; + $migration->mergeProcessOfProperty('type', $process); + } + + /** + * {@inheritdoc} + */ + public function processFieldInstance(MigrationInterface $migration) { + // Nothing to do by default with field instances. + } + + /** + * {@inheritdoc} + */ + public function processFieldWidget(MigrationInterface $migration) { + $process = []; + foreach ($this->getFieldWidgetMap() as $source_widget => $destination_widget) { + $process['type']['map'][$source_widget] = $destination_widget; + } + $migration->mergeProcessOfProperty('options/type', $process); + } + + /** + * {@inheritdoc} + */ + public function getFieldFormatterType(Row $row) { + return $row->getSourceProperty('formatter/type'); + } + + /** + * {@inheritdoc} + */ + public function getFieldFormatterMap() { + return []; + } + + /** + * {@inheritdoc} + */ + public function getFieldWidgetType(Row $row) { + return $row->getSourceProperty('widget/type'); + } + + /** + * {@inheritdoc} + */ + public function getFieldWidgetMap() { + // By default, use the plugin ID for the widget types. + return [ + $this->pluginId => $this->pluginId . '_default', + ]; + } + + /** + * {@inheritdoc} + */ + public function processFieldFormatter(MigrationInterface $migration) { + $process = []; + + // Some migrate field plugin IDs are prefixed with 'd6_' or 'd7_'. Since the + // plugin ID is used in the static map as the module name, we have to remove + // this prefix from the plugin ID. + $plugin_id = preg_replace('/d[67]_/', '', $this->pluginId); + foreach ($this->getFieldFormatterMap() as $source_format => $destination_format) { + $process[0]['map'][$plugin_id][$source_format] = $destination_format; + } + $migration->mergeProcessOfProperty('options/type', $process); + } + + /** + * {@inheritdoc} + */ + public function processFieldValues(MigrationInterface $migration, $field_name, $data) { + $process = [ + 'plugin' => 'get', + 'source' => $field_name, + ]; + $migration->mergeProcessOfProperty($field_name, $process); + } + + /** + * {@inheritdoc} + */ + public function getFieldType(Row $row) { + $field_type = $row->getSourceProperty('type'); + + if (isset($this->pluginDefinition['type_map'][$field_type])) { + return $this->pluginDefinition['type_map'][$field_type]; + } + else { + return $field_type; + } + } + +} diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php b/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php new file mode 100644 index 00000000..1579afad --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/field/NodeReference.php @@ -0,0 +1,36 @@ + 'iterator', + 'source' => $field_name, + 'process' => [ + 'target_id' => [ + 'plugin' => 'migration_lookup', + 'migration' => 'd6_node', + 'source' => 'nid', + ], + ], + ]; + $migration->setProcessOfProperty($field_name, $process); + } + +} diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php b/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php new file mode 100644 index 00000000..11df8ec2 --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/field/UserReference.php @@ -0,0 +1,36 @@ + 'iterator', + 'source' => $field_name, + 'process' => [ + 'target_id' => [ + 'plugin' => 'migration_lookup', + 'migration' => 'd6_user', + 'source' => 'uid', + ], + ], + ]; + $migration->setProcessOfProperty($field_name, $process); + } + +} diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php index 3af971cc..445441be 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/DrupalSqlBase.php @@ -10,7 +10,6 @@ use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\Plugin\migrate\source\SqlBase; -use Drupal\migrate\Plugin\RequirementsInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -19,7 +18,7 @@ * Mainly to let children retrieve information from the origin system in an * easier way. */ -abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginInterface, RequirementsInterface, DependentPluginInterface { +abstract class DrupalSqlBase extends SqlBase implements ContainerFactoryPluginInterface, DependentPluginInterface { use DependencyTrait; @@ -60,7 +59,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition */ public function getSystemData() { if (!isset($this->systemData)) { - $this->systemData = array(); + $this->systemData = []; try { $results = $this->select('system', 's') ->fields('s') @@ -95,17 +94,18 @@ public static function create(ContainerInterface $container, array $configuratio */ public function checkRequirements() { if ($this->pluginDefinition['requirements_met'] === TRUE) { - if (isset($this->pluginDefinition['source_provider'])) { - if ($this->moduleExists($this->pluginDefinition['source_provider'])) { - if (isset($this->pluginDefinition['minimum_schema_version']) && !$this->getModuleSchemaVersion($this->pluginDefinition['source_provider']) < $this->pluginDefinition['minimum_schema_version']) { + if (isset($this->pluginDefinition['source_module'])) { + if ($this->moduleExists($this->pluginDefinition['source_module'])) { + if (isset($this->pluginDefinition['minimum_schema_version']) && !$this->getModuleSchemaVersion($this->pluginDefinition['source_module']) < $this->pluginDefinition['minimum_schema_version']) { throw new RequirementsException('Required minimum schema version ' . $this->pluginDefinition['minimum_schema_version'], ['minimum_schema_version' => $this->pluginDefinition['minimum_schema_version']]); } } else { - throw new RequirementsException('The module ' . $this->pluginDefinition['source_provider'] . ' is not enabled in the source site.', ['source_provider' => $this->pluginDefinition['source_provider']]); + throw new RequirementsException('The module ' . $this->pluginDefinition['source_module'] . ' is not enabled in the source site.', ['source_module' => $this->pluginDefinition['source_module']]); } } } + parent::checkRequirements(); } /** @@ -149,7 +149,7 @@ protected function moduleExists($module) { protected function variableGet($name, $default) { try { $result = $this->select('variable', 'v') - ->fields('v', array('value')) + ->fields('v', ['value']) ->condition('name', $name) ->execute() ->fetchField(); diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php index 6792e5e0..e0acc4b5 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/EmptySource.php @@ -10,7 +10,6 @@ use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; - /** * Source returning an empty row with Drupal specific config dependencies. * diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php index 2d8c3ccd..410acec2 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/Variable.php @@ -37,7 +37,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition * {@inheritdoc} */ protected function initializeIterator() { - return new \ArrayIterator(array($this->values())); + return new \ArrayIterator([$this->values()]); } /** @@ -75,7 +75,7 @@ public function fields() { public function query() { return $this->getDatabase() ->select('variable', 'v') - ->fields('v', array('name', 'value')) + ->fields('v', ['name', 'value']) ->condition('name', $this->variables, 'IN'); } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php index 2ecea8d2..61da5eb3 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/VariableMultiRow.php @@ -21,7 +21,7 @@ class VariableMultiRow extends DrupalSqlBase { */ public function query() { return $this->select('variable', 'v') - ->fields('v', array('name', 'value')) + ->fields('v', ['name', 'value']) // Cast scalars to array so we can consistently use an IN condition. ->condition('name', (array) $this->configuration['variables'], 'IN'); } @@ -30,10 +30,10 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'name' => $this->t('Name'), 'value' => $this->t('Value'), - ); + ]; } /** diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php new file mode 100644 index 00000000..566a8402 --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/VariableTranslation.php @@ -0,0 +1,100 @@ +variables = $this->configuration['variables']; + } + + /** + * {@inheritdoc} + */ + protected function initializeIterator() { + return new \ArrayIterator($this->values()); + } + + /** + * Return the values of the variables specified in the plugin configuration. + * + * @return array + * An associative array where the keys are the variables specified in the + * plugin configuration and the values are the values found in the source. + * A key/value pair is added for the language code. Only those values are + * returned that are actually in the database. + */ + protected function values() { + $values = []; + $result = $this->prepareQuery()->execute()->FetchAllAssoc('language'); + foreach ($result as $i18n_variable) { + $values[]['language'] = $i18n_variable->language; + } + $result = $this->prepareQuery()->execute()->FetchAll(); + foreach ($result as $i18n_variable) { + foreach ($values as $key => $value) { + if ($values[$key]['language'] === $i18n_variable->language) { + $values[$key][$i18n_variable->name] = unserialize($i18n_variable->value); + break; + } + } + } + return $values; + } + + /** + * {@inheritdoc} + */ + public function count() { + return $this->initializeIterator()->count(); + } + + /** + * {@inheritdoc} + */ + public function fields() { + return array_combine($this->variables, $this->variables); + } + + /** + * {@inheritdoc} + */ + public function query() { + return $this->getDatabase() + ->select('i18n_variable', 'v') + ->fields('v') + ->condition('name', (array) $this->configuration['variables'], 'IN'); + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['language']['type'] = 'string'; + return $ids; + } + +} diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php index 93832aa7..dd8d0f07 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/i18nVariable.php @@ -2,10 +2,7 @@ namespace Drupal\migrate_drupal\Plugin\migrate\source\d6; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\State\StateInterface; -use Drupal\migrate\Plugin\MigrationInterface; -use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; +@trigger_error('The ' . __NAMESPACE__ . '\i18nVariable is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\VariableTranslation', E_USER_DEPRECATED); /** * Drupal i18n_variable source from database. @@ -13,88 +10,10 @@ * @MigrateSource( * id = "i18n_variable" * ) + * + * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use + * \Drupal\migrate_drupal\Plugin\migrate\source\d6\VariableTranslation instead. + * + * @see https://www.drupal.org/node/2898649 */ -class i18nVariable extends DrupalSqlBase { - - /** - * The variable names to fetch. - * - * @var array - */ - protected $variables; - - /** - * {@inheritdoc} - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager); - $this->variables = $this->configuration['variables']; - } - - /** - * {@inheritdoc} - */ - protected function initializeIterator() { - return new \ArrayIterator($this->values()); - } - - /** - * Return the values of the variables specified in the plugin configuration. - * - * @return array - * An associative array where the keys are the variables specified in the - * plugin configuration and the values are the values found in the source. - * A key/value pair is added for the language code. Only those values are - * returned that are actually in the database. - */ - protected function values() { - $values = []; - $result = $this->prepareQuery()->execute()->FetchAllAssoc('language'); - foreach ($result as $i18n_variable) { - $values[]['language'] = $i18n_variable->language; - } - $result = $this->prepareQuery()->execute()->FetchAll(); - foreach ($result as $i18n_variable) { - foreach ($values as $key => $value) { - if ($values[$key]['language'] === $i18n_variable->language) { - $values[$key][$i18n_variable->name] = unserialize($i18n_variable->value); - break; - } - } - } - return $values; - } - - /** - * {@inheritdoc} - */ - public function count() { - return $this->initializeIterator()->count(); - } - - /** - * {@inheritdoc} - */ - public function fields() { - return array_combine($this->variables, $this->variables); - } - - /** - * {@inheritdoc} - */ - public function query() { - return $this->getDatabase() - ->select('i18n_variable', 'v') - ->fields('v') - ->condition('name', (array) $this->configuration['variables'], 'IN'); - } - - /** - * {@inheritdoc} - */ - public function getIds() { - $ids['language']['type'] = 'string'; - return $ids; - } - -} +class i18nVariable extends VariableTranslation {} diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php index df3311f5..8d833877 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d8/Config.php @@ -19,7 +19,7 @@ class Config extends DrupalSqlBase { */ public function query() { $query = $this->select('config', 'c') - ->fields('c', array('collection', 'name', 'data')); + ->fields('c', ['collection', 'name', 'data']); if (!empty($this->configuration['collections'])) { $query->condition('collection', (array) $this->configuration['collections'], 'IN'); } diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php index f20fa0c0..4ca588b9 100644 --- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php +++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php @@ -43,6 +43,75 @@ 'mysql_character_set' => 'utf8', )); +$connection->schema()->createTable('accesslog', array( + 'fields' => array( + 'aid' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'size' => 'normal', + ), + 'sid' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '64', + 'default' => '', + ), + 'title' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'path' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'url' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'normal', + ), + 'hostname' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '128', + ), + 'uid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'timer' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'timestamp' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'aid', + ), + 'indexes' => array( + 'accesslog_timestamp' => array( + 'timestamp', + ), + 'uid' => array( + 'uid', + ), + ), + 'mysql_character_set' => 'utf8', +)); + $connection->schema()->createTable('actions', array( 'fields' => array( 'aid' => array( @@ -391,7 +460,7 @@ 'image' => 'http://b.thumbs.redditmedia.com/harEHsUUZVajabtC.png', 'etag' => '"213cc1365b96c310e92053c5551f0504"', 'modified' => '0', - 'block' => '5', + 'block' => '7', )) ->execute(); @@ -534,6 +603,21 @@ 'mysql_character_set' => 'utf8', )); +$connection->insert('batch') +->fields(array( + 'bid', + 'token', + 'timestamp', + 'batch', +)) +->values(array( + 'bid' => '1', + 'token' => '', + 'timestamp' => '1494966324', + 'batch' => NULL, +)) +->execute(); + $connection->schema()->createTable('blocks', array( 'fields' => array( 'bid' => array( @@ -641,7 +725,7 @@ 'delta' => '0', 'theme' => 'garland', 'status' => '1', - 'weight' => '0', + 'weight' => '-10', 'region' => 'left', 'custom' => '0', 'throttle' => '0', @@ -656,7 +740,7 @@ 'delta' => '1', 'theme' => 'garland', 'status' => '1', - 'weight' => '0', + 'weight' => '-11', 'region' => 'left', 'custom' => '0', 'throttle' => '0', @@ -746,7 +830,7 @@ 'delta' => '2', 'theme' => 'garland', 'status' => '1', - 'weight' => '-9', + 'weight' => '-11', 'region' => 'right', 'custom' => '0', 'throttle' => '0', @@ -761,7 +845,7 @@ 'delta' => '3', 'theme' => 'garland', 'status' => '1', - 'weight' => '-6', + 'weight' => '-10', 'region' => 'right', 'custom' => '0', 'throttle' => '0', @@ -835,9 +919,9 @@ 'module' => 'aggregator', 'delta' => 'feed-5', 'theme' => 'garland', - 'status' => '0', + 'status' => '1', 'weight' => '-2', - 'region' => '', + 'region' => 'right', 'custom' => '0', 'throttle' => '0', 'visibility' => '0', @@ -925,9 +1009,9 @@ 'module' => 'book', 'delta' => '0', 'theme' => 'garland', - 'status' => '0', + 'status' => '1', 'weight' => '-4', - 'region' => '', + 'region' => 'right', 'custom' => '0', 'throttle' => '0', 'visibility' => '0', @@ -950,6 +1034,51 @@ 'title' => '', 'cache' => '-1', )) +->values(array( + 'bid' => '22', + 'module' => 'forum', + 'delta' => '0', + 'theme' => 'garland', + 'status' => '1', + 'weight' => '-8', + 'region' => 'left', + 'custom' => '0', + 'throttle' => '0', + 'visibility' => '0', + 'pages' => '', + 'title' => '', + 'cache' => '1', +)) +->values(array( + 'bid' => '23', + 'module' => 'forum', + 'delta' => '1', + 'theme' => 'garland', + 'status' => '1', + 'weight' => '-9', + 'region' => 'left', + 'custom' => '0', + 'throttle' => '0', + 'visibility' => '0', + 'pages' => '', + 'title' => '', + 'cache' => '1', +)) +->values(array( + 'bid' => '24', + 'module' => 'statistics', + 'delta' => '0', + 'theme' => 'garland', + 'status' => '1', + 'weight' => '0', + 'region' => 'right', + 'custom' => '0', + 'throttle' => '0', + 'visibility' => '0', + 'pages' => '', + 'title' => '', + 'cache' => '-1', +)) ->execute(); $connection->schema()->createTable('blocks_roles', array( @@ -1772,7 +1901,7 @@ 'uid' => '0', 'subject' => 'The first comment.', 'comment' => 'The first comment body.', - 'hostname' => '127.0.0.1', + 'hostname' => '203.0.113.1', 'timestamp' => '1390264918', 'status' => '0', 'format' => '1', @@ -1788,7 +1917,7 @@ 'uid' => '0', 'subject' => 'The response to the second comment.', 'comment' => 'The second comment response body.', - 'hostname' => '127.0.0.1', + 'hostname' => '203.0.113.2', 'timestamp' => '1390264938', 'status' => '0', 'format' => '1', @@ -1804,7 +1933,7 @@ 'uid' => '0', 'subject' => 'The second comment.', 'comment' => 'The second comment body.', - 'hostname' => '127.0.0.1', + 'hostname' => '203.0.113.3', 'timestamp' => '1390264948', 'status' => '1', 'format' => '1', @@ -1813,6 +1942,54 @@ 'mail' => 'comment3@example.com', 'homepage' => 'https://www.drupal.org', )) +->values(array( + 'cid' => '4', + 'pid' => '0', + 'nid' => '19', + 'uid' => '1', + 'subject' => 'Subject 1', + 'comment' => 'Comment 1', + 'hostname' => '127.0.0.1', + 'timestamp' => '1501955780', + 'status' => '0', + 'format' => '1', + 'thread' => '01/', + 'name' => 'root', + 'mail' => '', + 'homepage' => '', +)) +->values(array( + 'cid' => '5', + 'pid' => '4', + 'nid' => '19', + 'uid' => '1', + 'subject' => 'Subject 2', + 'comment' => 'Comment 2', + 'hostname' => '127.0.0.1', + 'timestamp' => '1501955792', + 'status' => '0', + 'format' => '1', + 'thread' => '01.00/', + 'name' => 'root', + 'mail' => '', + 'homepage' => '', +)) +->values(array( + 'cid' => '6', + 'pid' => '5', + 'nid' => '19', + 'uid' => '1', + 'subject' => 'Subject 3', + 'comment' => 'Comment 3', + 'hostname' => '127.0.0.1', + 'timestamp' => '1501955803', + 'status' => '0', + 'format' => '1', + 'thread' => '01.00.00/', + 'name' => 'root', + 'mail' => '', + 'homepage' => '', +)) ->execute(); $connection->schema()->createTable('config', array( @@ -1933,6 +2110,72 @@ )) ->execute(); +$connection->schema()->createTable('content_field_company', array( + 'fields' => array( + 'vid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'nid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'field_company_nid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'vid', + 'delta', + ), + 'indexes' => array( + 'nid' => array( + 'nid', + ), + 'field_company_nid' => array( + 'field_company_nid', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('content_field_company') +->fields(array( + 'vid', + 'nid', + 'delta', + 'field_company_nid', +)) +->values(array( + 'vid' => '21', + 'nid' => '18', + 'delta' => '0', + 'field_company_nid' => '15', +)) +->values(array( + 'vid' => '21', + 'nid' => '18', + 'delta' => '1', + 'field_company_nid' => '16', +)) +->execute(); + $connection->schema()->createTable('content_field_image', array( 'fields' => array( 'vid' => array( @@ -2449,6 +2692,30 @@ 'active', 'locked', )) +->values(array( + 'field_name' => 'field_commander', + 'type' => 'userreference', + 'global_settings' => 'a:2:{s:19:"referenceable_roles";a:4:{i:2;i:2;i:3;i:0;i:4;i:0;i:5;i:0;}s:20:"referenceable_status";s:0:"";}', + 'required' => '0', + 'multiple' => '0', + 'db_storage' => '1', + 'module' => 'userreference', + 'db_columns' => 'a:1:{s:3:"uid";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:0;s:5:"index";b:1;}}', + 'active' => '1', + 'locked' => '0', +)) +->values(array( + 'field_name' => 'field_company', + 'type' => 'nodereference', + 'global_settings' => 'a:1:{s:19:"referenceable_types";a:10:{s:7:"company";s:7:"company";s:7:"article";i:0;s:8:"employee";i:0;s:5:"forum";i:0;s:10:"test_event";i:0;s:9:"test_page";i:0;s:11:"test_planet";i:0;s:10:"test_story";i:0;s:7:"sponsor";i:0;s:5:"story";i:0;}}', + 'required' => '0', + 'multiple' => '1', + 'db_storage' => '0', + 'module' => 'nodereference', + 'db_columns' => 'a:1:{s:3:"nid";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:0;s:5:"index";b:1;}}', + 'active' => '1', + 'locked' => '0', +)) ->values(array( 'field_name' => 'field_multivalue', 'type' => 'number_decimal', @@ -2488,24 +2755,24 @@ ->values(array( 'field_name' => 'field_test_datestamp', 'type' => 'datestamp', - 'global_settings' => 'a:7:{s:11:"granularity";a:5:{s:4:"year";s:4:"year";s:5:"month";s:5:"month";s:3:"day";s:3:"day";s:4:"hour";s:4:"hour";s:6:"minute";s:6:"minute";}s:11:"timezone_db";s:3:"UTC";s:11:"tz_handling";s:4:"site";s:6:"todate";s:0:"";s:6:"repeat";i:0;s:16:"repeat_collapsed";s:0:"";s:14:"default_format";s:6:"medium";}', + 'global_settings' => 'a:13:{s:11:"granularity";a:6:{s:4:"year";s:4:"year";s:5:"month";s:5:"month";s:3:"day";s:3:"day";s:4:"hour";s:4:"hour";s:6:"minute";s:6:"minute";s:6:"second";i:0;}s:11:"timezone_db";s:3:"UTC";s:11:"tz_handling";s:4:"site";s:6:"todate";s:0:"";s:6:"repeat";i:0;s:18:"output_format_date";s:5:"m/d/Y";s:20:"output_format_custom";s:0:"";s:23:"output_format_date_long";s:5:"m/d/Y";s:25:"output_format_custom_long";s:0:"";s:25:"output_format_date_medium";s:5:"m/d/Y";s:27:"output_format_custom_medium";s:0:"";s:24:"output_format_date_short";s:5:"m/d/Y";s:26:"output_format_custom_short";s:0:"";}', 'required' => '0', 'multiple' => '0', 'db_storage' => '1', 'module' => 'date', - 'db_columns' => 'a:1:{s:5:"value";a:4:{s:4:"type";s:3:"int";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}', + 'db_columns' => 'a:2:{s:5:"value";a:4:{s:4:"type";s:3:"int";s:6:"length";i:11;s:8:"not null";b:0;s:8:"sortable";b:1;}s:6:"value2";a:4:{s:4:"type";s:3:"int";s:6:"length";i:11;s:8:"not null";b:0;s:8:"sortable";b:1;}}', 'active' => '1', 'locked' => '0', )) ->values(array( 'field_name' => 'field_test_datetime', 'type' => 'datetime', - 'global_settings' => 'a:7:{s:11:"granularity";a:5:{s:4:"year";s:4:"year";s:5:"month";s:5:"month";s:3:"day";s:3:"day";s:4:"hour";s:4:"hour";s:6:"minute";s:6:"minute";}s:11:"timezone_db";s:3:"UTC";s:11:"tz_handling";s:4:"site";s:6:"todate";s:0:"";s:6:"repeat";i:0;s:16:"repeat_collapsed";s:0:"";s:14:"default_format";s:6:"medium";}', + 'global_settings' => 'a:13:{s:11:"granularity";a:6:{s:4:"year";s:4:"year";s:5:"month";s:5:"month";s:3:"day";s:3:"day";s:4:"hour";s:4:"hour";s:6:"minute";s:6:"minute";s:6:"second";i:0;}s:11:"timezone_db";s:3:"UTC";s:11:"tz_handling";s:4:"site";s:6:"todate";s:0:"";s:6:"repeat";i:0;s:18:"output_format_date";s:5:"m/d/Y";s:20:"output_format_custom";s:0:"";s:23:"output_format_date_long";s:5:"m/d/Y";s:25:"output_format_custom_long";s:0:"";s:25:"output_format_date_medium";s:5:"m/d/Y";s:27:"output_format_custom_medium";s:0:"";s:24:"output_format_date_short";s:5:"m/d/Y";s:26:"output_format_custom_short";s:0:"";}', 'required' => '0', 'multiple' => '0', 'db_storage' => '1', 'module' => 'date', - 'db_columns' => 'a:1:{s:5:"value";a:4:{s:4:"type";s:8:"datetime";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}', + 'db_columns' => 'a:2:{s:5:"value";a:3:{s:4:"type";s:8:"datetime";s:8:"not null";b:0;s:8:"sortable";b:1;}s:6:"value2";a:3:{s:4:"type";s:8:"datetime";s:8:"not null";b:0;s:8:"sortable";b:1;}}', 'active' => '1', 'locked' => '0', )) @@ -2783,6 +3050,30 @@ 'widget_module', 'widget_active', )) +->values(array( + 'field_name' => 'field_commander', + 'type_name' => 'employee', + 'weight' => '32', + 'label' => 'Commanding Officer', + 'widget_type' => 'userreference_select', + 'widget_settings' => 'a:5:{s:18:"autocomplete_match";s:8:"contains";s:4:"size";i:60;s:12:"reverse_link";i:0;s:13:"default_value";a:1:{i:0;a:1:{s:3:"uid";s:0:"";}}s:17:"default_value_php";N;}', + 'display_settings' => 'a:5:{s:5:"label";a:2:{s:6:"format";s:5:"above";s:7:"exclude";i:0;}i:5;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}', + 'description' => '', + 'widget_module' => 'userreference', + 'widget_active' => '1', +)) +->values(array( + 'field_name' => 'field_company', + 'type_name' => 'employee', + 'weight' => '31', + 'label' => 'Company', + 'widget_type' => 'nodereference_select', + 'widget_settings' => 'a:4:{s:18:"autocomplete_match";s:8:"contains";s:4:"size";i:60;s:13:"default_value";a:1:{i:0;a:1:{s:3:"nid";s:0:"";}}s:17:"default_value_php";N;}', + 'display_settings' => 'a:5:{s:5:"label";a:2:{s:6:"format";s:5:"above";s:7:"exclude";i:0;}i:5;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:6:"teaser";a:2:{s:6:"format";s:5:"plain";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}', + 'description' => '', + 'widget_module' => 'nodereference', + 'widget_active' => '1', +)) ->values(array( 'field_name' => 'field_multivalue', 'type_name' => 'test_planet', @@ -2836,7 +3127,7 @@ 'type_name' => 'story', 'weight' => '11', 'label' => 'Date Stamp Field', - 'widget_type' => 'date_select', + 'widget_type' => 'date_text', 'widget_settings' => 'a:10:{s:13:"default_value";s:5:"blank";s:18:"default_value_code";s:0:"";s:14:"default_value2";s:4:"same";s:19:"default_value_code2";s:0:"";s:12:"input_format";s:13:"m/d/Y - H:i:s";s:19:"input_format_custom";s:0:"";s:9:"increment";s:1:"1";s:10:"text_parts";a:0:{}s:10:"year_range";s:5:"-3:+3";s:14:"label_position";s:5:"above";}', 'display_settings' => 'a:7:{s:6:"weight";s:2:"11";s:6:"parent";s:0:"";i:5;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:6:"medium";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}', 'description' => 'An example date stamp field.', @@ -2848,8 +3139,8 @@ 'type_name' => 'story', 'weight' => '12', 'label' => 'Datetime Field', - 'widget_type' => 'date_select', - 'widget_settings' => 'a:10:{s:13:"default_value";s:5:"blank";s:18:"default_value_code";s:0:"";s:14:"default_value2";s:4:"same";s:19:"default_value_code2";s:0:"";s:12:"input_format";s:13:"m/d/Y - H:i:s";s:19:"input_format_custom";s:0:"";s:9:"increment";s:1:"1";s:10:"text_parts";a:0:{}s:10:"year_range";s:5:"-3:+3";s:14:"label_position";s:5:"above";}', + 'widget_type' => 'date_popup', + 'widget_settings' => 'a:10:{s:13:"default_value";s:5:"blank";s:18:"default_value_code";s:0:"";s:14:"default_value2";s:4:"same";s:19:"default_value_code2";s:0:"";s:12:"input_format";s:11:"d/m/Y H:i:s";s:19:"input_format_custom";s:0:"";s:9:"increment";s:1:"1";s:10:"text_parts";a:0:{}s:10:"year_range";s:5:"-3:+3";s:14:"label_position";s:5:"above";}', 'display_settings' => 'a:7:{s:6:"weight";s:2:"12";s:6:"parent";s:0:"";i:5;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:5:"short";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}', 'description' => 'An example datetime field.', 'widget_module' => 'date', @@ -3018,7 +3309,7 @@ 'label' => 'Text Single Checkbox Field', 'widget_type' => 'text_textfield', 'widget_settings' => 'a:4:{s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:1:"0";s:14:"_error_element";s:63:"default_value_widget][field_test_text_single_checkbox][0][value";}}s:17:"default_value_php";N;s:4:"rows";i:5;s:4:"size";s:3:"255";}', - 'display_settings' => 'a:7:{s:6:"weight";s:2:"17";s:6:"parent";s:0:"";i:5;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}', + 'display_settings' => 'a:7:{s:6:"weight";s:2:"32";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:6:"hidden";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:5;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}', 'description' => 'An example text field using a single on/off checkbox.', 'widget_module' => 'text', 'widget_active' => '1', @@ -3061,6 +3352,56 @@ )) ->execute(); +$connection->schema()->createTable('content_type_employee', array( + 'fields' => array( + 'vid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'nid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'field_commander_uid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'vid', + ), + 'indexes' => array( + 'nid' => array( + 'nid', + ), + 'field_commander_uid' => array( + 'field_commander_uid', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('content_type_employee') +->fields(array( + 'vid', + 'nid', + 'field_commander_uid', +)) +->values(array( + 'vid' => '21', + 'nid' => '18', + 'field_commander_uid' => '8', +)) +->execute(); + $connection->schema()->createTable('content_type_page', array( 'fields' => array( 'vid' => array( @@ -3237,6 +3578,16 @@ 'not null' => FALSE, 'size' => 'big', ), + 'field_test_datestamp_value2' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + ), + 'field_test_datetime_value2' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '100', + ), ), 'primary key' => array( 'vid', @@ -3278,6 +3629,8 @@ 'field_test_imagefield_list', 'field_test_imagefield_data', 'field_test_text_single_checkbox2_value', + 'field_test_datestamp_value2', + 'field_test_datetime_value2', )) ->values(array( 'nid' => '1', @@ -3289,10 +3642,10 @@ 'field_test_link_url' => 'https://www.drupal.org/project/drupal', 'field_test_link_title' => 'Drupal project page', 'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";', - 'field_test_date_value' => NULL, - 'field_test_datestamp_value' => NULL, - 'field_test_datetime_value' => NULL, - 'field_test_email_email' => NULL, + 'field_test_date_value' => '2013-01-02T04:05:00', + 'field_test_datestamp_value' => '1391357160', + 'field_test_datetime_value' => '2015-03-04 06:07:00', + 'field_test_email_email' => 'PrincessRuwenne@example.com', 'field_test_filefield_fid' => '5', 'field_test_filefield_list' => '1', 'field_test_filefield_data' => 'a:1:{s:11:"description";s:4:"desc";}', @@ -3307,6 +3660,8 @@ 'field_test_imagefield_list' => NULL, 'field_test_imagefield_data' => NULL, 'field_test_text_single_checkbox2_value' => 'Hello', + 'field_test_datestamp_value2' => NULL, + 'field_test_datetime_value2' => NULL, )) ->values(array( 'nid' => '1', @@ -3318,10 +3673,10 @@ 'field_test_link_url' => 'https://www.drupal.org/project/drupal', 'field_test_link_title' => 'Drupal project page', 'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";', - 'field_test_date_value' => NULL, - 'field_test_datestamp_value' => NULL, - 'field_test_datetime_value' => NULL, - 'field_test_email_email' => NULL, + 'field_test_date_value' => '2013-01-02T04:05:00', + 'field_test_datestamp_value' => '1391357160', + 'field_test_datetime_value' => '2015-03-04 06:07:00', + 'field_test_email_email' => 'PrincessRuwenne@example.com', 'field_test_filefield_fid' => NULL, 'field_test_filefield_list' => NULL, 'field_test_filefield_data' => NULL, @@ -3336,6 +3691,8 @@ 'field_test_imagefield_list' => NULL, 'field_test_imagefield_data' => NULL, 'field_test_text_single_checkbox2_value' => NULL, + 'field_test_datestamp_value2' => NULL, + 'field_test_datetime_value2' => NULL, )) ->values(array( 'nid' => '2', @@ -3365,6 +3722,8 @@ 'field_test_imagefield_list' => NULL, 'field_test_imagefield_data' => NULL, 'field_test_text_single_checkbox2_value' => NULL, + 'field_test_datestamp_value2' => NULL, + 'field_test_datetime_value2' => NULL, )) ->values(array( 'nid' => '2', @@ -3394,6 +3753,8 @@ 'field_test_imagefield_list' => NULL, 'field_test_imagefield_data' => NULL, 'field_test_text_single_checkbox2_value' => NULL, + 'field_test_datestamp_value2' => NULL, + 'field_test_datetime_value2' => NULL, )) ->values(array( 'nid' => '9', @@ -3422,7 +3783,9 @@ 'field_test_imagefield_fid' => NULL, 'field_test_imagefield_list' => NULL, 'field_test_imagefield_data' => NULL, - 'field_test_text_single_checkbox2_value' => NULL, + 'field_test_text_single_checkbox2_value' => 'Off', + 'field_test_datestamp_value2' => '1391357160', + 'field_test_datetime_value2' => '2015-03-04 06:07:00', )) ->execute(); @@ -7992,6 +8355,57 @@ 'mysql_character_set' => 'utf8', )); +$connection->schema()->createTable('forum', array( + 'fields' => array( + 'nid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'vid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + 'tid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'vid', + ), + 'indexes' => array( + 'nid' => array( + 'nid', + ), + 'tid' => array( + 'tid', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('forum') +->fields(array( + 'nid', + 'vid', + 'tid', +)) +->values(array( + 'nid' => '19', + 'vid' => '22', + 'tid' => '8', +)) +->execute(); + $connection->schema()->createTable('history', array( 'fields' => array( 'uid' => array( @@ -8046,6 +8460,36 @@ 'nid' => '13', 'timestamp' => '1468384931', )) +->values(array( + 'uid' => '1', + 'nid' => '14', + 'timestamp' => '1493066668', +)) +->values(array( + 'uid' => '1', + 'nid' => '15', + 'timestamp' => '1493066677', +)) +->values(array( + 'uid' => '1', + 'nid' => '16', + 'timestamp' => '1493066685', +)) +->values(array( + 'uid' => '1', + 'nid' => '17', + 'timestamp' => '1493066693', +)) +->values(array( + 'uid' => '1', + 'nid' => '18', + 'timestamp' => '1493066711', +)) +->values(array( + 'uid' => '1', + 'nid' => '19', + 'timestamp' => '1501955803', +)) ->execute(); $connection->schema()->createTable('i18n_blocks', array( @@ -9148,6 +9592,54 @@ 'objectindex' => '139', 'format' => '0', )) +->values(array( + 'lid' => '1664', + 'objectid' => 'forum', + 'type' => 'type', + 'property' => 'name', + 'objectindex' => '0', + 'format' => '0', +)) +->values(array( + 'lid' => '1665', + 'objectid' => 'forum', + 'type' => 'type', + 'property' => 'title', + 'objectindex' => '0', + 'format' => '0', +)) +->values(array( + 'lid' => '1666', + 'objectid' => 'forum', + 'type' => 'type', + 'property' => 'body', + 'objectindex' => '0', + 'format' => '0', +)) +->values(array( + 'lid' => '1667', + 'objectid' => 'forum', + 'type' => 'type', + 'property' => 'description', + 'objectindex' => '0', + 'format' => '0', +)) +->values(array( + 'lid' => '1672', + 'objectid' => '6', + 'type' => 'vocabulary', + 'property' => 'name', + 'objectindex' => '6', + 'format' => '0', +)) +->values(array( + 'lid' => '1673', + 'objectid' => '7', + 'type' => 'vocabulary', + 'property' => 'name', + 'objectindex' => '7', + 'format' => '0', +)) ->execute(); $connection->schema()->createTable('i18n_variable', array( @@ -9193,6 +9685,21 @@ 'language' => 'en', 'value' => 'a:2:{i:0;i:1;i:1;i:2;}', )) +->values(array( + 'name' => 'statistics_count_content_views', + 'language' => 'en', + 'value' => 's:1:"1";', +)) +->values(array( + 'name' => 'statistics_enable_access_log', + 'language' => 'en', + 'value' => 's:1:"0";', +)) +->values(array( + 'name' => 'statistics_flush_accesslog_timer', + 'language' => 'en', + 'value' => 's:6:"259200";', +)) ->values(array( 'name' => 'anonymous', 'language' => 'fr', @@ -12284,21 +12791,21 @@ )) ->values(array( 'lid' => '342', - 'location' => 'modules/nodereference/nodereference.module:60', + 'location' => 'modules/nodereference/nodereference.module:71', 'textgroup' => 'default', 'source' => 'Node reference', 'version' => 'none', )) ->values(array( 'lid' => '343', - 'location' => 'modules/nodereference/nodereference.module:61', + 'location' => 'modules/nodereference/nodereference.module:72', 'textgroup' => 'default', 'source' => 'Store the ID of a related node as an integer value.', 'version' => 'none', )) ->values(array( 'lid' => '344', - 'location' => 'nodereference.module:51', + 'location' => 'modules/nodereference/nodereference.module:90', 'textgroup' => 'default', 'source' => 'Content types that can be referenced', 'version' => 'none', @@ -12312,21 +12819,21 @@ )) ->values(array( 'lid' => '346', - 'location' => 'modules/nodereference/nodereference.module:100, modules/userreference/userreference.module:97', + 'location' => 'modules/nodereference/nodereference.module:101', 'textgroup' => 'default', 'source' => 'Existing Views', 'version' => 'none', )) ->values(array( 'lid' => '347', - 'location' => 'modules/nodereference/nodereference.module:97', + 'location' => 'modules/nodereference/nodereference.module:108', 'textgroup' => 'default', 'source' => 'Advanced - Nodes that can be referenced (View)', 'version' => 'none', )) ->values(array( 'lid' => '348', - 'location' => 'modules/nodereference/nodereference.module:104', + 'location' => 'modules/nodereference/nodereference.module:114', 'textgroup' => 'default', 'source' => 'View used to select the nodes', 'version' => 'none', @@ -12347,14 +12854,14 @@ )) ->values(array( 'lid' => '351', - 'location' => 'modules/nodereference/nodereference.module:122, modules/userreference/userreference.module:119', + 'location' => 'modules/nodereference/nodereference.module:121', 'textgroup' => 'default', 'source' => 'View arguments', 'version' => 'none', )) ->values(array( 'lid' => '352', - 'location' => 'modules/nodereference/nodereference.module:125, modules/userreference/userreference.module:122', + 'location' => 'modules/nodereference/nodereference.module:124', 'textgroup' => 'default', 'source' => 'Provide a comma separated list of arguments to pass to the view.', 'version' => 'none', @@ -12382,14 +12889,14 @@ )) ->values(array( 'lid' => '356', - 'location' => 'modules/nodereference/nodereference.module:242', + 'location' => 'modules/nodereference/nodereference.module:200', 'textgroup' => 'default', 'source' => 'Title (link)', 'version' => 'none', )) ->values(array( 'lid' => '357', - 'location' => 'modules/nodereference/nodereference.module:247', + 'location' => 'modules/nodereference/nodereference.module:205', 'textgroup' => 'default', 'source' => 'Title (no link)', 'version' => 'none', @@ -12466,7 +12973,7 @@ )) ->values(array( 'lid' => '368', - 'location' => 'nodereference.module:0', + 'location' => 'modules/nodereference/nodereference.module:0', 'textgroup' => 'default', 'source' => 'nodereference', 'version' => 'none', @@ -21529,6 +22036,76 @@ 'source' => 'Delete all translations', 'version' => '6.38-dev', )) +->values(array( + 'lid' => '1664', + 'location' => 'type:forum:name', + 'textgroup' => 'nodetype', + 'source' => 'Forum topic', + 'version' => '1', +)) +->values(array( + 'lid' => '1665', + 'location' => 'type:forum:title', + 'textgroup' => 'nodetype', + 'source' => 'Subject', + 'version' => '1', +)) +->values(array( + 'lid' => '1666', + 'location' => 'type:forum:body', + 'textgroup' => 'nodetype', + 'source' => 'Body', + 'version' => '1', +)) +->values(array( + 'lid' => '1667', + 'location' => 'type:forum:description', + 'textgroup' => 'nodetype', + 'source' => 'A forum topic is the initial post to a new discussion thread within a forum.', + 'version' => '1', +)) +->values(array( + 'lid' => '1668', + 'location' => 'modules/block/block.js', + 'textgroup' => 'default', + 'source' => 'The changes to these blocks will not be saved until the Save blocks button is clicked.', + 'version' => 'none', +)) +->values(array( + 'lid' => '1669', + 'location' => 'modules/nodereference/nodereference.module:117', + 'textgroup' => 'default', + 'source' => "Choose the \"Views module\" view that selects the nodes that can be referenced.
    Note:
    • Only views that have fields will work for this purpose.
    • This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.
    • Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.
    • Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.
    ", + 'version' => 'none', +)) +->values(array( + 'lid' => '1670', + 'location' => 'modules/nodereference/nodereference.module:175', + 'textgroup' => 'default', + 'source' => "%name: This post can't be referenced.", + 'version' => 'none', +)) +->values(array( + 'lid' => '1671', + 'location' => 'modules/nodereference/nodereference.module:518', + 'textgroup' => 'default', + 'source' => '%name: Title mismatch. Please check your selection.', + 'version' => 'none', +)) +->values(array( + 'lid' => '1672', + 'location' => 'vocabulary:6:name', + 'textgroup' => 'taxonomy', + 'source' => 'Type', + 'version' => '1', +)) +->values(array( + 'lid' => '1673', + 'location' => 'vocabulary:7:name', + 'textgroup' => 'taxonomy', + 'source' => 'Forums', + 'version' => '1', +)) ->execute(); $connection->schema()->createTable('locales_target', array( @@ -26549,6 +27126,30 @@ 'plural' => '0', 'i18n_status' => '0', )) +->values(array( + 'lid' => '1669', + 'translation' => "Choisissez la vue du module Views qui sélectionne les nœuds pouvant être référencés.
    Notez que :
    • seules les vues présentant des champs fonctionneront dans ce cadre 
    • ceci effacera les paramètres de \"Types de contenus\" figurant ci-dessus. Utilisez à la place la section \"filtres\" de la vue ;
    • utilisez la section \"champs\" de la vue pour afficher des informations supplémentaires sur les nÅ“uds candidats dans le formulaire de création/édition de nÅ“ud ;
    • utilisez la section \"critère de tri\" de la vue pour déterminer l'ordre d'affichage des nÅ“uds candidats.
    ", + 'language' => 'fr', + 'plid' => '0', + 'plural' => '0', + 'i18n_status' => '0', +)) +->values(array( + 'lid' => '1670', + 'translation' => "Champ '%name' : cette publication ne peut être référencée.", + 'language' => 'fr', + 'plid' => '0', + 'plural' => '0', + 'i18n_status' => '0', +)) +->values(array( + 'lid' => '1671', + 'translation' => "Champ '%name' : incohérence au niveau du titre. Merci de vérifier votre sélection.", + 'language' => 'fr', + 'plid' => '0', + 'plural' => '0', + 'i18n_status' => '0', +)) ->values(array( 'lid' => '66', 'translation' => 'zu - CCK - Aucune Intégration aux Vues', @@ -32562,6 +33163,492 @@ 'p9' => '0', 'updated' => '0', )) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '441', + 'plid' => '0', + 'link_path' => 'forum', + 'router_path' => 'forum', + 'link_title' => 'Forums', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '1', + 'customized' => '0', + 'p1' => '441', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '442', + 'plid' => '165', + 'link_path' => 'admin/reports/settings', + 'router_path' => 'admin/reports/settings', + 'link_title' => 'Access log settings', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:50:"Control details about what and how your site logs.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '3', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '165', + 'p3' => '442', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '443', + 'plid' => '158', + 'link_path' => 'node/add/forum', + 'router_path' => 'node/add/forum', + 'link_title' => 'Forum topic', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:85:"A forum topic is the initial post to a new discussion thread within a forum.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '2', + 'customized' => '0', + 'p1' => '158', + 'p2' => '443', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '444', + 'plid' => '157', + 'link_path' => 'admin/content/forum', + 'router_path' => 'admin/content/forum', + 'link_title' => 'Forums', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:61:"Control forums and their hierarchy and change forum settings.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '157', + 'p3' => '444', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '445', + 'plid' => '165', + 'link_path' => 'admin/reports/hits', + 'router_path' => 'admin/reports/hits', + 'link_title' => 'Recent hits', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:43:"View pages that have recently been visited.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '165', + 'p3' => '445', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '446', + 'plid' => '165', + 'link_path' => 'admin/reports/pages', + 'router_path' => 'admin/reports/pages', + 'link_title' => 'Top pages', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:41:"View pages that have been hit frequently.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '1', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '165', + 'p3' => '446', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '447', + 'plid' => '165', + 'link_path' => 'admin/reports/referrers', + 'router_path' => 'admin/reports/referrers', + 'link_title' => 'Top referrers', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:19:"View top referrers.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '165', + 'p3' => '447', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '448', + 'plid' => '165', + 'link_path' => 'admin/reports/visitors', + 'router_path' => 'admin/reports/visitors', + 'link_title' => 'Top visitors', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:34:"View visitors that hit many pages.";}}', + 'module' => 'system', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '2', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '165', + 'p3' => '448', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '449', + 'plid' => '165', + 'link_path' => 'admin/reports/access/%', + 'router_path' => 'admin/reports/access/%', + 'link_title' => 'Details', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:16:"View access log.";}}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '165', + 'p3' => '449', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '450', + 'plid' => '157', + 'link_path' => 'admin/content/node-type/forum', + 'router_path' => 'admin/content/node-type/forum', + 'link_title' => 'Forum topic', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '144', + 'p2' => '157', + 'p3' => '450', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '451', + 'plid' => '444', + 'link_path' => 'admin/content/forum/edit/%', + 'router_path' => 'admin/content/forum/edit/%', + 'link_title' => '', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '4', + 'customized' => '0', + 'p1' => '144', + 'p2' => '157', + 'p3' => '444', + 'p4' => '451', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '452', + 'plid' => '0', + 'link_path' => 'admin/content/node-type/forum/delete', + 'router_path' => 'admin/content/node-type/forum/delete', + 'link_title' => 'Delete', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '1', + 'customized' => '0', + 'p1' => '452', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '453', + 'plid' => '444', + 'link_path' => 'admin/content/forum/edit/container/%', + 'router_path' => 'admin/content/forum/edit/container/%', + 'link_title' => 'Edit container', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '4', + 'customized' => '0', + 'p1' => '144', + 'p2' => '157', + 'p3' => '444', + 'p4' => '453', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '454', + 'plid' => '444', + 'link_path' => 'admin/content/forum/edit/forum/%', + 'router_path' => 'admin/content/forum/edit/forum/%', + 'link_title' => 'Edit forum', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '4', + 'customized' => '0', + 'p1' => '144', + 'p2' => '157', + 'p3' => '444', + 'p4' => '454', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '455', + 'plid' => '0', + 'link_path' => 'nodereference/autocomplete', + 'router_path' => 'nodereference/autocomplete', + 'link_title' => 'Nodereference autocomplete', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '1', + 'customized' => '0', + 'p1' => '455', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '456', + 'plid' => '0', + 'link_path' => 'admin/content/node-type/employee/fields/field_company/remove', + 'router_path' => 'admin/content/node-type/employee/fields/field_company/remove', + 'link_title' => 'Remove field', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '1', + 'customized' => '0', + 'p1' => '456', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '457', + 'plid' => '0', + 'link_path' => 'userreference/autocomplete', + 'router_path' => 'userreference/autocomplete', + 'link_title' => 'Userreference autocomplete', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '1', + 'customized' => '0', + 'p1' => '457', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) +->values(array( + 'menu_name' => 'navigation', + 'mlid' => '458', + 'plid' => '0', + 'link_path' => 'admin/content/node-type/employee/fields/field_commander/remove', + 'router_path' => 'admin/content/node-type/employee/fields/field_commander/remove', + 'link_title' => 'Remove field', + 'options' => 'a:0:{}', + 'module' => 'system', + 'hidden' => '-1', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '1', + 'customized' => '0', + 'p1' => '458', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', +)) ->execute(); $connection->schema()->createTable('menu_router', array( @@ -32869,7 +33956,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_block_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/bluemarine/bluemarine.info";s:4:"name";s:10:"bluemarine";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:10:"Bluemarine";s:11:"description";s:66:"Table-based multi-column theme with a marine and ash color scheme.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/bluemarine/script.js";}s:10:"screenshot";s:32:"themes/bluemarine/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:6:"engine";s:11:"phptemplate";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/bluemarine/bluemarine.info";s:4:"name";s:10:"bluemarine";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:10:"Bluemarine";s:11:"description";s:66:"Table-based multi-column theme with a marine and ash color scheme.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/bluemarine/script.js";}s:10:"screenshot";s:32:"themes/bluemarine/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:6:"engine";s:11:"phptemplate";}}', 'page_callback' => 'block_admin_display', 'page_arguments' => 'a:1:{i:0;s:10:"bluemarine";}', 'fit' => '31', @@ -32891,7 +33978,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_block_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":11:{s:8:"filename";s:31:"themes/chameleon/chameleon.info";s:4:"name";s:9:"chameleon";s:4:"type";s:5:"theme";s:5:"owner";s:32:"themes/chameleon/chameleon.theme";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:10:{s:4:"name";s:9:"Chameleon";s:11:"description";s:42:"Minimalist tabled theme with light colors.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:8:"features";a:4:{i:0;s:4:"logo";i:1;s:7:"favicon";i:2;s:4:"name";i:3;s:6:"slogan";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:7:"scripts";a:1:{s:9:"script.js";s:26:"themes/chameleon/script.js";}s:10:"screenshot";s:31:"themes/chameleon/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":11:{s:8:"filename";s:31:"themes/chameleon/chameleon.info";s:4:"name";s:9:"chameleon";s:4:"type";s:5:"theme";s:5:"owner";s:32:"themes/chameleon/chameleon.theme";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:12:{s:4:"name";s:9:"Chameleon";s:11:"description";s:42:"Minimalist tabled theme with light colors.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:8:"features";a:4:{i:0;s:4:"logo";i:1;s:7:"favicon";i:2;s:4:"name";i:3;s:6:"slogan";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"scripts";a:1:{s:9:"script.js";s:26:"themes/chameleon/script.js";}s:10:"screenshot";s:31:"themes/chameleon/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}}}', 'page_callback' => 'block_admin_display', 'page_arguments' => 'a:1:{i:0;s:9:"chameleon";}', 'fit' => '31', @@ -32913,7 +34000,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_block_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:27:"themes/garland/garland.info";s:4:"name";s:7:"garland";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"1";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:7:"Garland";s:11:"description";s:66:"Tableless, recolorable, multi-column, fluid width theme (default).";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:24:"themes/garland/script.js";}s:10:"screenshot";s:29:"themes/garland/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:6:"engine";s:11:"phptemplate";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:27:"themes/garland/garland.info";s:4:"name";s:7:"garland";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"1";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:7:"Garland";s:11:"description";s:66:"Tableless, recolorable, multi-column, fluid width theme (default).";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:24:"themes/garland/script.js";}s:10:"screenshot";s:29:"themes/garland/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:6:"engine";s:11:"phptemplate";}}', 'page_callback' => 'block_admin_display', 'page_arguments' => 'a:1:{i:0;s:7:"garland";}', 'fit' => '31', @@ -32957,7 +34044,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_block_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:35:"themes/chameleon/marvin/marvin.info";s:4:"name";s:6:"marvin";s:4:"type";s:5:"theme";s:5:"owner";s:0:"";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:6:"Marvin";s:11:"description";s:31:"Boxy tabled theme in all grays.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"base theme";s:9:"chameleon";s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/chameleon/marvin/script.js";}s:10:"screenshot";s:38:"themes/chameleon/marvin/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:10:"base_theme";s:9:"chameleon";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:35:"themes/chameleon/marvin/marvin.info";s:4:"name";s:6:"marvin";s:4:"type";s:5:"theme";s:5:"owner";s:0:"";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:6:"Marvin";s:11:"description";s:31:"Boxy tabled theme in all grays.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:10:"base theme";s:9:"chameleon";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/chameleon/marvin/script.js";}s:10:"screenshot";s:38:"themes/chameleon/marvin/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:10:"base_theme";s:9:"chameleon";}}', 'page_callback' => 'block_admin_display', 'page_arguments' => 'a:1:{i:0;s:6:"marvin";}', 'fit' => '31', @@ -32979,7 +34066,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_block_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":13:{s:8:"filename";s:37:"themes/garland/minnelli/minnelli.info";s:4:"name";s:8:"minnelli";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:12:{s:4:"name";s:8:"Minnelli";s:11:"description";s:56:"Tableless, recolorable, multi-column, fixed width theme.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"base theme";s:7:"garland";s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/garland/minnelli/script.js";}s:10:"screenshot";s:38:"themes/garland/minnelli/screenshot.png";s:3:"php";s:5:"4.3.5";s:6:"engine";s:11:"phptemplate";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:6:"engine";s:11:"phptemplate";s:10:"base_theme";s:7:"garland";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":13:{s:8:"filename";s:37:"themes/garland/minnelli/minnelli.info";s:4:"name";s:8:"minnelli";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:14:{s:4:"name";s:8:"Minnelli";s:11:"description";s:56:"Tableless, recolorable, multi-column, fixed width theme.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:10:"base theme";s:7:"garland";s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/garland/minnelli/script.js";}s:10:"screenshot";s:38:"themes/garland/minnelli/screenshot.png";s:3:"php";s:5:"4.3.5";s:6:"engine";s:11:"phptemplate";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:6:"engine";s:11:"phptemplate";s:10:"base_theme";s:7:"garland";}}', 'page_callback' => 'block_admin_display', 'page_arguments' => 'a:1:{i:0;s:8:"minnelli";}', 'fit' => '31', @@ -33001,7 +34088,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_block_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/pushbutton/pushbutton.info";s:4:"name";s:10:"pushbutton";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:10:"Pushbutton";s:11:"description";s:52:"Tabled, multi-column theme in blue and orange tones.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/pushbutton/script.js";}s:10:"screenshot";s:32:"themes/pushbutton/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:6:"engine";s:11:"phptemplate";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/pushbutton/pushbutton.info";s:4:"name";s:10:"pushbutton";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:10:"Pushbutton";s:11:"description";s:52:"Tabled, multi-column theme in blue and orange tones.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/pushbutton/script.js";}s:10:"screenshot";s:32:"themes/pushbutton/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:6:"engine";s:11:"phptemplate";}}', 'page_callback' => 'block_admin_display', 'page_arguments' => 'a:1:{i:0;s:10:"pushbutton";}', 'fit' => '31', @@ -33705,7 +34792,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_system_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/bluemarine/bluemarine.info";s:4:"name";s:10:"bluemarine";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:10:"Bluemarine";s:11:"description";s:66:"Table-based multi-column theme with a marine and ash color scheme.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/bluemarine/script.js";}s:10:"screenshot";s:32:"themes/bluemarine/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:6:"engine";s:11:"phptemplate";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/bluemarine/bluemarine.info";s:4:"name";s:10:"bluemarine";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:10:"Bluemarine";s:11:"description";s:66:"Table-based multi-column theme with a marine and ash color scheme.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/bluemarine/script.js";}s:10:"screenshot";s:32:"themes/bluemarine/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:6:"engine";s:11:"phptemplate";}}', 'page_callback' => 'drupal_get_form', 'page_arguments' => 'a:2:{i:0;s:21:"system_theme_settings";i:1;s:10:"bluemarine";}', 'fit' => '31', @@ -33727,7 +34814,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_system_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":11:{s:8:"filename";s:31:"themes/chameleon/chameleon.info";s:4:"name";s:9:"chameleon";s:4:"type";s:5:"theme";s:5:"owner";s:32:"themes/chameleon/chameleon.theme";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:10:{s:4:"name";s:9:"Chameleon";s:11:"description";s:42:"Minimalist tabled theme with light colors.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:8:"features";a:4:{i:0;s:4:"logo";i:1;s:7:"favicon";i:2;s:4:"name";i:3;s:6:"slogan";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:7:"scripts";a:1:{s:9:"script.js";s:26:"themes/chameleon/script.js";}s:10:"screenshot";s:31:"themes/chameleon/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":11:{s:8:"filename";s:31:"themes/chameleon/chameleon.info";s:4:"name";s:9:"chameleon";s:4:"type";s:5:"theme";s:5:"owner";s:32:"themes/chameleon/chameleon.theme";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:12:{s:4:"name";s:9:"Chameleon";s:11:"description";s:42:"Minimalist tabled theme with light colors.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:8:"features";a:4:{i:0;s:4:"logo";i:1;s:7:"favicon";i:2;s:4:"name";i:3;s:6:"slogan";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"scripts";a:1:{s:9:"script.js";s:26:"themes/chameleon/script.js";}s:10:"screenshot";s:31:"themes/chameleon/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}}}', 'page_callback' => 'drupal_get_form', 'page_arguments' => 'a:2:{i:0;s:21:"system_theme_settings";i:1;s:9:"chameleon";}', 'fit' => '31', @@ -33749,7 +34836,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_system_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:27:"themes/garland/garland.info";s:4:"name";s:7:"garland";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"1";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:7:"Garland";s:11:"description";s:66:"Tableless, recolorable, multi-column, fluid width theme (default).";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:24:"themes/garland/script.js";}s:10:"screenshot";s:29:"themes/garland/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:6:"engine";s:11:"phptemplate";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:27:"themes/garland/garland.info";s:4:"name";s:7:"garland";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"1";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:7:"Garland";s:11:"description";s:66:"Tableless, recolorable, multi-column, fluid width theme (default).";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:24:"themes/garland/script.js";}s:10:"screenshot";s:29:"themes/garland/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:6:"engine";s:11:"phptemplate";}}', 'page_callback' => 'drupal_get_form', 'page_arguments' => 'a:2:{i:0;s:21:"system_theme_settings";i:1;s:7:"garland";}', 'fit' => '31', @@ -33793,7 +34880,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_system_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:35:"themes/chameleon/marvin/marvin.info";s:4:"name";s:6:"marvin";s:4:"type";s:5:"theme";s:5:"owner";s:0:"";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:6:"Marvin";s:11:"description";s:31:"Boxy tabled theme in all grays.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"base theme";s:9:"chameleon";s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/chameleon/marvin/script.js";}s:10:"screenshot";s:38:"themes/chameleon/marvin/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:10:"base_theme";s:9:"chameleon";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:35:"themes/chameleon/marvin/marvin.info";s:4:"name";s:6:"marvin";s:4:"type";s:5:"theme";s:5:"owner";s:0:"";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:6:"Marvin";s:11:"description";s:31:"Boxy tabled theme in all grays.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:10:"base theme";s:9:"chameleon";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/chameleon/marvin/script.js";}s:10:"screenshot";s:38:"themes/chameleon/marvin/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:10:"base_theme";s:9:"chameleon";}}', 'page_callback' => 'drupal_get_form', 'page_arguments' => 'a:2:{i:0;s:21:"system_theme_settings";i:1;s:6:"marvin";}', 'fit' => '31', @@ -33815,7 +34902,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_system_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":13:{s:8:"filename";s:37:"themes/garland/minnelli/minnelli.info";s:4:"name";s:8:"minnelli";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:12:{s:4:"name";s:8:"Minnelli";s:11:"description";s:56:"Tableless, recolorable, multi-column, fixed width theme.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"base theme";s:7:"garland";s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/garland/minnelli/script.js";}s:10:"screenshot";s:38:"themes/garland/minnelli/screenshot.png";s:3:"php";s:5:"4.3.5";s:6:"engine";s:11:"phptemplate";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:6:"engine";s:11:"phptemplate";s:10:"base_theme";s:7:"garland";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":13:{s:8:"filename";s:37:"themes/garland/minnelli/minnelli.info";s:4:"name";s:8:"minnelli";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:14:{s:4:"name";s:8:"Minnelli";s:11:"description";s:56:"Tableless, recolorable, multi-column, fixed width theme.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:10:"base theme";s:7:"garland";s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/garland/minnelli/script.js";}s:10:"screenshot";s:38:"themes/garland/minnelli/screenshot.png";s:3:"php";s:5:"4.3.5";s:6:"engine";s:11:"phptemplate";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:6:"engine";s:11:"phptemplate";s:10:"base_theme";s:7:"garland";}}', 'page_callback' => 'drupal_get_form', 'page_arguments' => 'a:2:{i:0;s:21:"system_theme_settings";i:1;s:8:"minnelli";}', 'fit' => '31', @@ -33837,7 +34924,7 @@ 'load_functions' => '', 'to_arg_functions' => '', 'access_callback' => '_system_themes_access', - 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/pushbutton/pushbutton.info";s:4:"name";s:10:"pushbutton";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:11:{s:4:"name";s:10:"Pushbutton";s:11:"description";s:52:"Tabled, multi-column theme in blue and orange tones.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/pushbutton/script.js";}s:10:"screenshot";s:32:"themes/pushbutton/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:6:"engine";s:11:"phptemplate";}}', + 'access_arguments' => 'a:1:{i:0;O:8:"stdClass":12:{s:8:"filename";s:33:"themes/pushbutton/pushbutton.info";s:4:"name";s:10:"pushbutton";s:4:"type";s:5:"theme";s:5:"owner";s:45:"themes/engines/phptemplate/phptemplate.engine";s:6:"status";s:1:"0";s:8:"throttle";s:1:"0";s:9:"bootstrap";s:1:"0";s:14:"schema_version";s:2:"-1";s:6:"weight";s:1:"0";s:4:"info";a:13:{s:4:"name";s:10:"Pushbutton";s:11:"description";s:52:"Tabled, multi-column theme in blue and orange tones.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/pushbutton/script.js";}s:10:"screenshot";s:32:"themes/pushbutton/screenshot.png";s:3:"php";s:5:"4.3.5";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:6:"engine";s:11:"phptemplate";}}', 'page_callback' => 'drupal_get_form', 'page_arguments' => 'a:2:{i:0;s:21:"system_theme_settings";i:1;s:10:"pushbutton";}', 'fit' => '31', @@ -34470,6 +35557,182 @@ 'weight' => '-10', 'file' => 'modules/comment/comment.admin.inc', )) +->values(array( + 'path' => 'admin/content/forum', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:1:{i:0;s:14:"forum_overview";}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'admin/content/forum', + 'title' => 'Forums', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '6', + 'block_callback' => '', + 'description' => 'Control forums and their hierarchy and change forum settings.', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/add/container', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'forum_form_main', + 'page_arguments' => 'a:1:{i:0;s:9:"container";}', + 'fit' => '31', + 'number_parts' => '5', + 'tab_parent' => 'admin/content/forum', + 'tab_root' => 'admin/content/forum', + 'title' => 'Add container', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/add/forum', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'forum_form_main', + 'page_arguments' => 'a:1:{i:0;s:5:"forum";}', + 'fit' => '31', + 'number_parts' => '5', + 'tab_parent' => 'admin/content/forum', + 'tab_root' => 'admin/content/forum', + 'title' => 'Add forum', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/edit/%', + 'load_functions' => 'a:1:{i:4;s:15:"forum_term_load";}', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'forum_form_main', + 'page_arguments' => 'a:0:{}', + 'fit' => '30', + 'number_parts' => '5', + 'tab_parent' => '', + 'tab_root' => 'admin/content/forum/edit/%', + 'title' => '', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/edit/container/%', + 'load_functions' => 'a:1:{i:5;s:15:"forum_term_load";}', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'forum_form_main', + 'page_arguments' => 'a:2:{i:0;s:9:"container";i:1;i:5;}', + 'fit' => '62', + 'number_parts' => '6', + 'tab_parent' => '', + 'tab_root' => 'admin/content/forum/edit/container/%', + 'title' => 'Edit container', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/edit/forum/%', + 'load_functions' => 'a:1:{i:5;s:15:"forum_term_load";}', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'forum_form_main', + 'page_arguments' => 'a:2:{i:0;s:5:"forum";i:1;i:5;}', + 'fit' => '62', + 'number_parts' => '6', + 'tab_parent' => '', + 'tab_root' => 'admin/content/forum/edit/forum/%', + 'title' => 'Edit forum', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/list', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:1:{i:0;s:14:"forum_overview";}', + 'fit' => '15', + 'number_parts' => '4', + 'tab_parent' => 'admin/content/forum', + 'tab_root' => 'admin/content/forum', + 'title' => 'List', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '136', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '-10', + 'file' => 'modules/forum/forum.admin.inc', +)) +->values(array( + 'path' => 'admin/content/forum/settings', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"administer forums";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:1:{i:0;s:20:"forum_admin_settings";}', + 'fit' => '15', + 'number_parts' => '4', + 'tab_parent' => 'admin/content/forum', + 'tab_root' => 'admin/content/forum', + 'title' => 'Settings', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '5', + 'file' => 'modules/forum/forum.admin.inc', +)) ->values(array( 'path' => 'admin/content/node', 'load_functions' => '', @@ -35064,6 +36327,270 @@ 'weight' => '1', 'file' => 'sites/all/modules/cck/includes/content.admin.inc', )) +->values(array( + 'path' => 'admin/content/node-type/employee/fields/field_commander', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:23:"content_field_edit_form";i:1;s:8:"employee";i:2;s:15:"field_commander";}', + 'fit' => '63', + 'number_parts' => '6', + 'tab_parent' => 'admin/content/node-type/employee/fields', + 'tab_root' => 'admin/content/node-type/employee', + 'title' => 'Commanding Officer', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/employee/fields/field_commander/remove', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:25:"content_field_remove_form";i:1;s:8:"employee";i:2;s:15:"field_commander";}', + 'fit' => '127', + 'number_parts' => '7', + 'tab_parent' => '', + 'tab_root' => 'admin/content/node-type/employee/fields/field_commander/remove', + 'title' => 'Remove field', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/employee/fields/field_company', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:23:"content_field_edit_form";i:1;s:8:"employee";i:2;s:13:"field_company";}', + 'fit' => '63', + 'number_parts' => '6', + 'tab_parent' => 'admin/content/node-type/employee/fields', + 'tab_root' => 'admin/content/node-type/employee', + 'title' => 'Company', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/employee/fields/field_company/remove', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:25:"content_field_remove_form";i:1;s:8:"employee";i:2;s:13:"field_company";}', + 'fit' => '127', + 'number_parts' => '7', + 'tab_parent' => '', + 'tab_root' => 'admin/content/node-type/employee/fields/field_company/remove', + 'title' => 'Remove field', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:2:{i:0;s:14:"node_type_form";i:1;O:8:"stdClass":15:{s:4:"name";s:11:"Forum topic";s:6:"module";s:5:"forum";s:11:"description";s:85:"A forum topic is the initial post to a new discussion thread within a forum.";s:11:"title_label";s:7:"Subject";s:4:"type";s:5:"forum";s:9:"has_title";b:1;s:8:"has_body";b:1;s:10:"body_label";s:4:"Body";s:4:"help";s:0:"";s:14:"min_word_count";i:0;s:6:"custom";b:0;s:8:"modified";b:0;s:6:"locked";b:1;s:9:"orig_type";s:5:"forum";s:6:"is_new";b:1;}}', + 'fit' => '15', + 'number_parts' => '4', + 'tab_parent' => '', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'Forum topic', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/node/content_types.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/delete', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:2:{i:0;s:24:"node_type_delete_confirm";i:1;O:8:"stdClass":15:{s:4:"name";s:11:"Forum topic";s:6:"module";s:5:"forum";s:11:"description";s:85:"A forum topic is the initial post to a new discussion thread within a forum.";s:11:"title_label";s:7:"Subject";s:4:"type";s:5:"forum";s:9:"has_title";b:1;s:8:"has_body";b:1;s:10:"body_label";s:4:"Body";s:4:"help";s:0:"";s:14:"min_word_count";i:0;s:6:"custom";b:0;s:8:"modified";b:0;s:6:"locked";b:1;s:9:"orig_type";s:5:"forum";s:6:"is_new";b:1;}}', + 'fit' => '31', + 'number_parts' => '5', + 'tab_parent' => '', + 'tab_root' => 'admin/content/node-type/forum/delete', + 'title' => 'Delete', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/node/content_types.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/display', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:2:{i:0;s:29:"content_display_overview_form";i:1;s:5:"forum";}', + 'fit' => '31', + 'number_parts' => '5', + 'tab_parent' => 'admin/content/node-type/forum', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'Display fields', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '2', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/display/basic', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:29:"content_display_overview_form";i:1;s:5:"forum";i:2;s:5:"basic";}', + 'fit' => '63', + 'number_parts' => '6', + 'tab_parent' => 'admin/content/node-type/forum/display', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'Basic', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '136', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/display/print', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:29:"content_display_overview_form";i:1;s:5:"forum";i:2;s:5:"print";}', + 'fit' => '63', + 'number_parts' => '6', + 'tab_parent' => 'admin/content/node-type/forum/display', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'Print', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '1', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/display/rss', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:3:{i:0;s:29:"content_display_overview_form";i:1;s:5:"forum";i:2;s:3:"rss";}', + 'fit' => '63', + 'number_parts' => '6', + 'tab_parent' => 'admin/content/node-type/forum/display', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'RSS', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '1', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/edit', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:2:{i:0;s:14:"node_type_form";i:1;O:8:"stdClass":15:{s:4:"name";s:11:"Forum topic";s:6:"module";s:5:"forum";s:11:"description";s:85:"A forum topic is the initial post to a new discussion thread within a forum.";s:11:"title_label";s:7:"Subject";s:4:"type";s:5:"forum";s:9:"has_title";b:1;s:8:"has_body";b:1;s:10:"body_label";s:4:"Body";s:4:"help";s:0:"";s:14:"min_word_count";i:0;s:6:"custom";b:0;s:8:"modified";b:0;s:6:"locked";b:1;s:9:"orig_type";s:5:"forum";s:6:"is_new";b:1;}}', + 'fit' => '31', + 'number_parts' => '5', + 'tab_parent' => 'admin/content/node-type/forum', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'Edit', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '136', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/node/content_types.inc', +)) +->values(array( + 'path' => 'admin/content/node-type/forum/fields', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:24:"administer content types";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:2:{i:0;s:27:"content_field_overview_form";i:1;s:5:"forum";}', + 'fit' => '31', + 'number_parts' => '5', + 'tab_parent' => 'admin/content/node-type/forum', + 'tab_root' => 'admin/content/node-type/forum', + 'title' => 'Manage fields', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '1', + 'file' => 'sites/all/modules/cck/includes/content.admin.inc', +)) ->values(array( 'path' => 'admin/content/node-type/sponsor', 'load_functions' => '', @@ -37484,6 +39011,116 @@ 'weight' => '5', 'file' => 'modules/system/system.admin.inc', )) +->values(array( + 'path' => 'admin/reports/access/%', + 'load_functions' => 'a:1:{i:3;N;}', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_access_log', + 'page_arguments' => 'a:1:{i:0;i:3;}', + 'fit' => '14', + 'number_parts' => '4', + 'tab_parent' => '', + 'tab_root' => 'admin/reports/access/%', + 'title' => 'Details', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => 'View access log.', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/statistics/statistics.admin.inc', +)) +->values(array( + 'path' => 'admin/reports/hits', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_recent_hits', + 'page_arguments' => 'a:0:{}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'admin/reports/hits', + 'title' => 'Recent hits', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '6', + 'block_callback' => '', + 'description' => 'View pages that have recently been visited.', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/statistics/statistics.admin.inc', +)) +->values(array( + 'path' => 'admin/reports/pages', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_top_pages', + 'page_arguments' => 'a:0:{}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'admin/reports/pages', + 'title' => 'Top pages', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '6', + 'block_callback' => '', + 'description' => 'View pages that have been hit frequently.', + 'position' => '', + 'weight' => '1', + 'file' => 'modules/statistics/statistics.admin.inc', +)) +->values(array( + 'path' => 'admin/reports/referrers', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_top_referrers', + 'page_arguments' => 'a:0:{}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'admin/reports/referrers', + 'title' => 'Top referrers', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '6', + 'block_callback' => '', + 'description' => 'View top referrers.', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/statistics/statistics.admin.inc', +)) +->values(array( + 'path' => 'admin/reports/settings', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:29:"administer site configuration";}', + 'page_callback' => 'drupal_get_form', + 'page_arguments' => 'a:1:{i:0;s:34:"statistics_access_logging_settings";}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'admin/reports/settings', + 'title' => 'Access log settings', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '6', + 'block_callback' => '', + 'description' => 'Control details about what and how your site logs.', + 'position' => '', + 'weight' => '3', + 'file' => 'modules/statistics/statistics.admin.inc', +)) ->values(array( 'path' => 'admin/reports/status', 'load_functions' => '', @@ -37572,6 +39209,28 @@ 'weight' => '0', 'file' => 'modules/system/system.admin.inc', )) +->values(array( + 'path' => 'admin/reports/visitors', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_top_visitors', + 'page_arguments' => 'a:0:{}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'admin/reports/visitors', + 'title' => 'Top visitors', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '6', + 'block_callback' => '', + 'description' => 'View visitors that hit many pages.', + 'position' => '', + 'weight' => '2', + 'file' => 'modules/statistics/statistics.admin.inc', +)) ->values(array( 'path' => 'admin/settings', 'load_functions' => '', @@ -38530,7 +40189,7 @@ 'number_parts' => '5', 'tab_parent' => 'admin/settings/language/i18n', 'tab_root' => 'admin/settings/language', - 'title' => 'Options', + 'title' => 'Multilingual system', 'title_callback' => 't', 'title_arguments' => '', 'type' => '136', @@ -38540,28 +40199,6 @@ 'weight' => '0', 'file' => 'sites/all/modules/i18n/i18n.admin.inc', )) -->values(array( - 'path' => 'admin/settings/language/i18n/variables', - 'load_functions' => '', - 'to_arg_functions' => '', - 'access_callback' => 'user_access', - 'access_arguments' => 'a:1:{i:0;s:29:"administer site configuration";}', - 'page_callback' => 'drupal_get_form', - 'page_arguments' => 'a:1:{i:0;s:25:"i18n_admin_variables_form";}', - 'fit' => '31', - 'number_parts' => '5', - 'tab_parent' => 'admin/settings/language/i18n', - 'tab_root' => 'admin/settings/language', - 'title' => 'Variables', - 'title_callback' => 't', - 'title_arguments' => '', - 'type' => '128', - 'block_callback' => '', - 'description' => 'Multilingual variables.', - 'position' => '', - 'weight' => '0', - 'file' => 'sites/all/modules/i18n/i18n.admin.inc', -)) ->values(array( 'path' => 'admin/settings/language/overview', 'load_functions' => '', @@ -39970,6 +41607,28 @@ 'weight' => '0', 'file' => 'modules/filter/filter.pages.inc', )) +->values(array( + 'path' => 'forum', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:14:"access content";}', + 'page_callback' => 'forum_page', + 'page_arguments' => 'a:0:{}', + 'fit' => '1', + 'number_parts' => '1', + 'tab_parent' => '', + 'tab_root' => 'forum', + 'title' => 'Forums', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '20', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/forum/forum.pages.inc', +)) ->values(array( 'path' => 'i18n/node/autocomplete', 'load_functions' => '', @@ -40278,6 +41937,28 @@ 'weight' => '0', 'file' => '', )) +->values(array( + 'path' => 'node/%/track', + 'load_functions' => 'a:1:{i:1;s:9:"node_load";}', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_node_tracker', + 'page_arguments' => 'a:0:{}', + 'fit' => '5', + 'number_parts' => '3', + 'tab_parent' => 'node/%', + 'tab_root' => 'node/%', + 'title' => 'Track', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '2', + 'file' => 'modules/statistics/statistics.pages.inc', +)) ->values(array( 'path' => 'node/%/translate', 'load_functions' => 'a:1:{i:1;s:9:"node_load";}', @@ -40410,6 +42091,28 @@ 'weight' => '0', 'file' => 'modules/node/node.pages.inc', )) +->values(array( + 'path' => 'node/add/forum', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'node_access', + 'access_arguments' => 'a:2:{i:0;s:6:"create";i:1;s:5:"forum";}', + 'page_callback' => 'i18ncontent_node_add', + 'page_arguments' => 'a:1:{i:0;i:2;}', + 'fit' => '7', + 'number_parts' => '3', + 'tab_parent' => '', + 'tab_root' => 'node/add/forum', + 'title' => 'Forum topic', + 'title_callback' => 'i18nstrings_title_callback', + 'title_arguments' => 'a:2:{i:0;s:24:"nodetype:type:forum:name";i:1;s:11:"Forum topic";}', + 'type' => '6', + 'block_callback' => '', + 'description' => 'A forum topic is the initial post to a new discussion thread within a forum.', + 'position' => '', + 'weight' => '0', + 'file' => 'modules/node/node.pages.inc', +)) ->values(array( 'path' => 'node/add/sponsor', 'load_functions' => '', @@ -40468,7 +42171,7 @@ 'tab_root' => 'node/add/test-event', 'title' => 'Migrate test event', 'title_callback' => 'i18nstrings_title_callback', - 'title_arguments' => 'a:2:{i:0;s:29:"nodetype:type:test_event:name";i:1;s:18:"Migrate test event";}', + 'title_arguments' => 'a:2:{i:0;s:29:"nodetype:type:test-event:name";i:1;s:18:"Migrate test event";}', 'type' => '6', 'block_callback' => '', 'description' => 'test event description here', @@ -40490,7 +42193,7 @@ 'tab_root' => 'node/add/test-page', 'title' => 'Migrate test page', 'title_callback' => 'i18nstrings_title_callback', - 'title_arguments' => 'a:2:{i:0;s:28:"nodetype:type:test_page:name";i:1;s:17:"Migrate test page";}', + 'title_arguments' => 'a:2:{i:0;s:28:"nodetype:type:test-page:name";i:1;s:17:"Migrate test page";}', 'type' => '6', 'block_callback' => '', 'description' => "A page, similar in form to a story, is a simple method for creating and displaying information that rarely changes, such as an \"About us\" section of a website. By default, a page entry does not allow visitor comments and is not featured on the site's initial home page.", @@ -40512,7 +42215,7 @@ 'tab_root' => 'node/add/test-planet', 'title' => 'Migrate test planet', 'title_callback' => 'i18nstrings_title_callback', - 'title_arguments' => 'a:2:{i:0;s:30:"nodetype:type:test_planet:name";i:1;s:19:"Migrate test planet";}', + 'title_arguments' => 'a:2:{i:0;s:30:"nodetype:type:test-planet:name";i:1;s:19:"Migrate test planet";}', 'type' => '6', 'block_callback' => '', 'description' => "A story, similar in form to a page, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a story entry. By default, a story entry is automatically featured on the site's initial home page, and provides the ability to post comments.", @@ -40534,7 +42237,7 @@ 'tab_root' => 'node/add/test-story', 'title' => 'Migrate test story', 'title_callback' => 'i18nstrings_title_callback', - 'title_arguments' => 'a:2:{i:0;s:29:"nodetype:type:test_story:name";i:1;s:18:"Migrate test story";}', + 'title_arguments' => 'a:2:{i:0;s:29:"nodetype:type:test-story:name";i:1;s:18:"Migrate test story";}', 'type' => '6', 'block_callback' => '', 'description' => "A story, similar in form to a page, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a story entry. By default, a story entry is automatically featured on the site's initial home page, and provides the ability to post comments.", @@ -40542,6 +42245,28 @@ 'weight' => '0', 'file' => 'modules/node/node.pages.inc', )) +->values(array( + 'path' => 'nodereference/autocomplete', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'nodereference_autocomplete_access', + 'access_arguments' => 'a:1:{i:0;i:2;}', + 'page_callback' => 'nodereference_autocomplete', + 'page_arguments' => 'a:0:{}', + 'fit' => '3', + 'number_parts' => '2', + 'tab_parent' => '', + 'tab_root' => 'nodereference/autocomplete', + 'title' => 'Nodereference autocomplete', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => '', +)) ->values(array( 'path' => 'profile', 'load_functions' => '', @@ -40916,6 +42641,28 @@ 'weight' => '3', 'file' => 'modules/user/user.pages.inc', )) +->values(array( + 'path' => 'user/%/track/navigation', + 'load_functions' => 'a:1:{i:1;s:9:"user_load";}', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:17:"access statistics";}', + 'page_callback' => 'statistics_user_tracker', + 'page_arguments' => 'a:0:{}', + 'fit' => '11', + 'number_parts' => '4', + 'tab_parent' => 'user/%', + 'tab_root' => 'user/%', + 'title' => 'Track page visits', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '128', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '2', + 'file' => 'modules/statistics/statistics.pages.inc', +)) ->values(array( 'path' => 'user/%/view', 'load_functions' => 'a:1:{i:1;s:9:"user_load";}', @@ -41070,6 +42817,28 @@ 'weight' => '0', 'file' => '', )) +->values(array( + 'path' => 'userreference/autocomplete', + 'load_functions' => '', + 'to_arg_functions' => '', + 'access_callback' => 'user_access', + 'access_arguments' => 'a:1:{i:0;s:14:"access content";}', + 'page_callback' => 'userreference_autocomplete', + 'page_arguments' => 'a:0:{}', + 'fit' => '3', + 'number_parts' => '2', + 'tab_parent' => '', + 'tab_root' => 'userreference/autocomplete', + 'title' => 'Userreference autocomplete', + 'title_callback' => 't', + 'title_arguments' => '', + 'type' => '4', + 'block_callback' => '', + 'description' => '', + 'position' => '', + 'weight' => '0', + 'file' => '', +)) ->execute(); $connection->schema()->createTable('node', array( @@ -41412,6 +43181,108 @@ 'tnid' => '12', 'translate' => '0', )) +->values(array( + 'nid' => '14', + 'vid' => '17', + 'type' => 'company', + 'language' => '', + 'title' => 'United Federation of Planets', + 'uid' => '1', + 'status' => '1', + 'created' => '1493066668', + 'changed' => '1493066668', + 'comment' => '2', + 'promote' => '1', + 'moderate' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) +->values(array( + 'nid' => '15', + 'vid' => '18', + 'type' => 'company', + 'language' => '', + 'title' => 'Klingon Empire', + 'uid' => '1', + 'status' => '1', + 'created' => '1493066677', + 'changed' => '1493066677', + 'comment' => '2', + 'promote' => '1', + 'moderate' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) +->values(array( + 'nid' => '16', + 'vid' => '19', + 'type' => 'company', + 'language' => '', + 'title' => 'Romulan Empire', + 'uid' => '1', + 'status' => '1', + 'created' => '1493066684', + 'changed' => '1493066684', + 'comment' => '2', + 'promote' => '1', + 'moderate' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) +->values(array( + 'nid' => '17', + 'vid' => '20', + 'type' => 'company', + 'language' => '', + 'title' => 'Ferengi Commerce Authority', + 'uid' => '1', + 'status' => '1', + 'created' => '1493066693', + 'changed' => '1493066693', + 'comment' => '2', + 'promote' => '1', + 'moderate' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) +->values(array( + 'nid' => '18', + 'vid' => '21', + 'type' => 'employee', + 'language' => '', + 'title' => 'Ambassador Sarek', + 'uid' => '1', + 'status' => '1', + 'created' => '1493066711', + 'changed' => '1494966544', + 'comment' => '2', + 'promote' => '1', + 'moderate' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) +->values(array( + 'nid' => '19', + 'vid' => '22', + 'type' => 'forum', + 'language' => '', + 'title' => 'New Forum Topic', + 'uid' => '1', + 'status' => '1', + 'created' => '1501955771', + 'changed' => '1501955771', + 'comment' => '2', + 'promote' => '0', + 'moderate' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) ->execute(); $connection->schema()->createTable('node_access', array( @@ -41576,6 +43447,48 @@ 'last_comment_uid' => '1', 'comment_count' => '0', )) +->values(array( + 'nid' => '14', + 'last_comment_timestamp' => '1493066668', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '15', + 'last_comment_timestamp' => '1493066677', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '16', + 'last_comment_timestamp' => '1493066684', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '17', + 'last_comment_timestamp' => '1493066693', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '18', + 'last_comment_timestamp' => '1493066711', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '19', + 'last_comment_timestamp' => '1501955803', + 'last_comment_name' => '', + 'last_comment_uid' => '1', + 'comment_count' => '3', +)) ->execute(); $connection->schema()->createTable('node_counter', array( @@ -41614,6 +43527,51 @@ 'mysql_character_set' => 'utf8', )); +$connection->insert('node_counter') +->fields(array( + 'nid', + 'totalcount', + 'daycount', + 'timestamp', +)) +->values(array( + 'nid' => '14', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1493066668', +)) +->values(array( + 'nid' => '15', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1493066677', +)) +->values(array( + 'nid' => '16', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1493066685', +)) +->values(array( + 'nid' => '17', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1493066693', +)) +->values(array( + 'nid' => '18', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1493066711', +)) +->values(array( + 'nid' => '19', + 'totalcount' => '4', + 'daycount' => '4', + 'timestamp' => '1501955803', +)) +->execute(); + $connection->schema()->createTable('node_revisions', array( 'fields' => array( 'nid' => array( @@ -41846,8 +43804,8 @@ 'vid' => '15', 'uid' => '1', 'title' => 'Abantu zulu', - 'body' => "Mr. Crusher, ready a collision course with the Borg ship.", - 'teaser' => "Mr. Crusher, ready a collision course with the Borg ship.", + 'body' => 'Mr. Crusher, ready a collision course with the Borg ship.', + 'teaser' => 'Mr. Crusher, ready a collision course with the Borg ship.', 'log' => '', 'timestamp' => '1444238808', 'format' => '1', @@ -41863,6 +43821,72 @@ 'timestamp' => '1444239050', 'format' => '1', )) +->values(array( + 'nid' => '14', + 'vid' => '17', + 'uid' => '1', + 'title' => 'United Federation of Planets', + 'body' => '', + 'teaser' => '', + 'log' => '', + 'timestamp' => '1493066668', + 'format' => '1', +)) +->values(array( + 'nid' => '15', + 'vid' => '18', + 'uid' => '1', + 'title' => 'Klingon Empire', + 'body' => '', + 'teaser' => '', + 'log' => '', + 'timestamp' => '1493066677', + 'format' => '1', +)) +->values(array( + 'nid' => '16', + 'vid' => '19', + 'uid' => '1', + 'title' => 'Romulan Empire', + 'body' => '', + 'teaser' => '', + 'log' => '', + 'timestamp' => '1493066684', + 'format' => '1', +)) +->values(array( + 'nid' => '17', + 'vid' => '20', + 'uid' => '1', + 'title' => 'Ferengi Commerce Authority', + 'body' => '', + 'teaser' => '', + 'log' => '', + 'timestamp' => '1493066693', + 'format' => '1', +)) +->values(array( + 'nid' => '18', + 'vid' => '21', + 'uid' => '1', + 'title' => 'Ambassador Sarek', + 'body' => "Yeah, I like animals better than people sometimes... Especially dogs. Dogs are the best. Every time you come home, they act like they haven't seen you in a year. And the good thing about dogs... is they got different dogs for different people. Like pit bulls. The dog of dogs. Pit bull can be the right man's best friend... or the wrong man's worst enemy. You going to give me a dog for a pet, give me a pit bull. Give me... Raoul. Right, Omar? Give me Raoul.", + 'teaser' => "Yeah, I like animals better than people sometimes... Especially dogs. Dogs are the best. Every time you come home, they act like they haven't seen you in a year. And the good thing about dogs... is they got different dogs for different people. Like pit bulls. The dog of dogs. Pit bull can be the right man's best friend... or the wrong man's worst enemy. You going to give me a dog for a pet, give me a pit bull. Give me... Raoul. Right, Omar?", + 'log' => '', + 'timestamp' => '1494966544', + 'format' => '1', +)) +->values(array( + 'nid' => '19', + 'vid' => '22', + 'uid' => '1', + 'title' => 'New Forum Topic', + 'body' => 'New Forum Body', + 'teaser' => 'New Forum Body', + 'log' => '', + 'timestamp' => '1501955771', + 'format' => '1', +)) ->execute(); $connection->schema()->createTable('node_type', array( @@ -42035,6 +44059,22 @@ 'locked' => '0', 'orig_type' => 'event', )) +->values(array( + 'type' => 'forum', + 'name' => 'Forum topic', + 'module' => 'forum', + 'description' => 'A forum topic is the initial post to a new discussion thread within a forum.', + 'help' => '', + 'has_title' => '1', + 'title_label' => 'Subject', + 'has_body' => '1', + 'body_label' => 'Body', + 'min_word_count' => '0', + 'custom' => '0', + 'modified' => '0', + 'locked' => '1', + 'orig_type' => 'forum', +)) ->values(array( 'type' => 'page', 'name' => 'Page', @@ -42753,9 +44793,9 @@ 'default' => '0', ), 'session' => array( - 'type' => 'text', + 'type' => 'blob', 'not null' => FALSE, - 'size' => 'normal', + 'size' => 'big', ), ), 'primary key' => array( @@ -42855,7 +44895,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:10:"Aggregator";s:11:"description";s:57:"Aggregates syndicated content (RSS, RDF, and Atom feeds).";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"Aggregator";s:11:"description";s:57:"Aggregates syndicated content (RSS, RDF, and Atom feeds).";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/block/block.module', @@ -42867,7 +44907,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:5:"Block";s:11:"description";s:62:"Controls the boxes that are displayed around the main content.";s:7:"package";s:15:"Core - required";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:5:"Block";s:11:"description";s:62:"Controls the boxes that are displayed around the main content.";s:7:"package";s:15:"Core - required";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/blog/blog.module', @@ -42879,7 +44919,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Blog";s:11:"description";s:69:"Enables keeping easily and regularly updated user web pages or blogs.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Blog";s:11:"description";s:69:"Enables keeping easily and regularly updated user web pages or blogs.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/blogapi/blogapi.module', @@ -42891,7 +44931,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:8:"Blog API";s:11:"description";s:79:"Allows users to post content using applications that support XML-RPC blog APIs.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:8:"Blog API";s:11:"description";s:79:"Allows users to post content using applications that support XML-RPC blog APIs.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/book/book.module', @@ -42903,7 +44943,7 @@ 'bootstrap' => '0', 'schema_version' => '6000', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Book";s:11:"description";s:63:"Allows users to structure site pages in a hierarchy or outline.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Book";s:11:"description";s:63:"Allows users to structure site pages in a hierarchy or outline.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/color/color.module', @@ -42915,7 +44955,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:5:"Color";s:11:"description";s:61:"Allows the user to change the color scheme of certain themes.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:5:"Color";s:11:"description";s:61:"Allows the user to change the color scheme of certain themes.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/comment/comment.module', @@ -42927,7 +44967,7 @@ 'bootstrap' => '0', 'schema_version' => '6005', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:7:"Comment";s:11:"description";s:57:"Allows users to comment on and discuss published content.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:7:"Comment";s:11:"description";s:57:"Allows users to comment on and discuss published content.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/contact/contact.module', @@ -42939,7 +44979,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:7:"Contact";s:11:"description";s:61:"Enables the use of both personal and site-wide contact forms.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:7:"Contact";s:11:"description";s:61:"Enables the use of both personal and site-wide contact forms.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/dblog/dblog.module', @@ -42951,7 +44991,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:16:"Database logging";s:11:"description";s:47:"Logs and records system events to the database.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:16:"Database logging";s:11:"description";s:47:"Logs and records system events to the database.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/filter/filter.module', @@ -42963,19 +45003,19 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"Filter";s:11:"description";s:60:"Handles the filtering of content in preparation for display.";s:7:"package";s:15:"Core - required";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"Filter";s:11:"description";s:60:"Handles the filtering of content in preparation for display.";s:7:"package";s:15:"Core - required";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/forum/forum.module', 'name' => 'forum', 'type' => 'module', 'owner' => '', - 'status' => '0', + 'status' => '1', 'throttle' => '0', 'bootstrap' => '0', - 'schema_version' => '-1', - 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:5:"Forum";s:11:"description";s:50:"Enables threaded discussions about general topics.";s:12:"dependencies";a:2:{i:0;s:8:"taxonomy";i:1;s:7:"comment";}s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'schema_version' => '6000', + 'weight' => '1', + 'info' => 'a:10:{s:4:"name";s:5:"Forum";s:11:"description";s:50:"Enables threaded discussions about general topics.";s:12:"dependencies";a:2:{i:0;s:8:"taxonomy";i:1;s:7:"comment";}s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/help/help.module', @@ -42987,7 +45027,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Help";s:11:"description";s:35:"Manages the display of online help.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Help";s:11:"description";s:35:"Manages the display of online help.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/locale/locale.module', @@ -42999,7 +45039,7 @@ 'bootstrap' => '0', 'schema_version' => '6007', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"Locale";s:11:"description";s:119:"Adds language handling functionality and enables the translation of the user interface to languages other than English.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"Locale";s:11:"description";s:119:"Adds language handling functionality and enables the translation of the user interface to languages other than English.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/menu/menu.module', @@ -43011,7 +45051,7 @@ 'bootstrap' => '0', 'schema_version' => '6000', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Menu";s:11:"description";s:60:"Allows administrators to customize the site navigation menu.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Menu";s:11:"description";s:60:"Allows administrators to customize the site navigation menu.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/node/node.module', @@ -43023,7 +45063,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Node";s:11:"description";s:66:"Allows content to be submitted to the site and displayed on pages.";s:7:"package";s:15:"Core - required";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Node";s:11:"description";s:66:"Allows content to be submitted to the site and displayed on pages.";s:7:"package";s:15:"Core - required";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/openid/openid.module', @@ -43035,7 +45075,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"OpenID";s:11:"description";s:48:"Allows users to log into your site using OpenID.";s:7:"version";s:8:"6.38-dev";s:7:"package";s:15:"Core - optional";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"OpenID";s:11:"description";s:48:"Allows users to log into your site using OpenID.";s:7:"version";s:4:"6.38";s:7:"package";s:15:"Core - optional";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/path/path.module', @@ -43047,7 +45087,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Path";s:11:"description";s:28:"Allows users to rename URLs.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Path";s:11:"description";s:28:"Allows users to rename URLs.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/php/php.module', @@ -43059,7 +45099,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:10:"PHP filter";s:11:"description";s:50:"Allows embedded PHP code/snippets to be evaluated.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"PHP filter";s:11:"description";s:50:"Allows embedded PHP code/snippets to be evaluated.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/ping/ping.module', @@ -43071,7 +45111,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Ping";s:11:"description";s:51:"Alerts other sites when your site has been updated.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Ping";s:11:"description";s:51:"Alerts other sites when your site has been updated.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/poll/poll.module', @@ -43083,7 +45123,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"Poll";s:11:"description";s:95:"Allows your site to capture votes on different topics in the form of multiple choice questions.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Poll";s:11:"description";s:95:"Allows your site to capture votes on different topics in the form of multiple choice questions.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/profile/profile.module', @@ -43095,7 +45135,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:7:"Profile";s:11:"description";s:36:"Supports configurable user profiles.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:7:"Profile";s:11:"description";s:36:"Supports configurable user profiles.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/search/search.module', @@ -43107,19 +45147,19 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"Search";s:11:"description";s:36:"Enables site-wide keyword searching.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"Search";s:11:"description";s:36:"Enables site-wide keyword searching.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/statistics/statistics.module', 'name' => 'statistics', 'type' => 'module', 'owner' => '', - 'status' => '0', + 'status' => '1', 'throttle' => '0', - 'bootstrap' => '0', - 'schema_version' => '-1', + 'bootstrap' => '1', + 'schema_version' => '6000', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:10:"Statistics";s:11:"description";s:37:"Logs access statistics for your site.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"Statistics";s:11:"description";s:37:"Logs access statistics for your site.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/syslog/syslog.module', @@ -43131,7 +45171,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"Syslog";s:11:"description";s:41:"Logs and records system events to syslog.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"Syslog";s:11:"description";s:41:"Logs and records system events to syslog.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/system/system.module', @@ -43141,9 +45181,9 @@ 'status' => '1', 'throttle' => '0', 'bootstrap' => '0', - 'schema_version' => '6055', + 'schema_version' => '6056', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"System";s:11:"description";s:54:"Handles general site configuration for administrators.";s:7:"package";s:15:"Core - required";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"System";s:11:"description";s:54:"Handles general site configuration for administrators.";s:7:"package";s:15:"Core - required";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/taxonomy/taxonomy.module', @@ -43155,7 +45195,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:8:"Taxonomy";s:11:"description";s:38:"Enables the categorization of content.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:8:"Taxonomy";s:11:"description";s:38:"Enables the categorization of content.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/throttle/throttle.module', @@ -43167,7 +45207,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:8:"Throttle";s:11:"description";s:66:"Handles the auto-throttling mechanism, to control site congestion.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:8:"Throttle";s:11:"description";s:66:"Handles the auto-throttling mechanism, to control site congestion.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/tracker/tracker.module', @@ -43179,7 +45219,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:7:"Tracker";s:11:"description";s:43:"Enables tracking of recent posts for users.";s:12:"dependencies";a:1:{i:0;s:7:"comment";}s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:7:"Tracker";s:11:"description";s:43:"Enables tracking of recent posts for users.";s:12:"dependencies";a:1:{i:0;s:7:"comment";}s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/translation/translation.module', @@ -43191,7 +45231,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:19:"Content translation";s:11:"description";s:57:"Allows content to be translated into different languages.";s:12:"dependencies";a:1:{i:0;s:6:"locale";}s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:19:"Content translation";s:11:"description";s:57:"Allows content to be translated into different languages.";s:12:"dependencies";a:1:{i:0;s:6:"locale";}s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/trigger/trigger.module', @@ -43203,7 +45243,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:7:"Trigger";s:11:"description";s:90:"Enables actions to be fired on certain system events, such as when new content is created.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:7:"Trigger";s:11:"description";s:90:"Enables actions to be fired on certain system events, such as when new content is created.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/update/update.module', @@ -43215,7 +45255,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:13:"Update status";s:11:"description";s:88:"Checks the status of available updates for Drupal and your installed modules and themes.";s:7:"version";s:8:"6.38-dev";s:7:"package";s:15:"Core - optional";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:13:"Update status";s:11:"description";s:88:"Checks the status of available updates for Drupal and your installed modules and themes.";s:7:"version";s:4:"6.38";s:7:"package";s:15:"Core - optional";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/upload/upload.module', @@ -43227,7 +45267,7 @@ 'bootstrap' => '0', 'schema_version' => '6000', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:6:"Upload";s:11:"description";s:51:"Allows users to upload and attach files to content.";s:7:"package";s:15:"Core - optional";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"Upload";s:11:"description";s:51:"Allows users to upload and attach files to content.";s:7:"package";s:15:"Core - optional";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'modules/user/user.module', @@ -43239,7 +45279,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:8:{s:4:"name";s:4:"User";s:11:"description";s:47:"Manages the user registration and login system.";s:7:"package";s:15:"Core - required";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"User";s:11:"description";s:47:"Manages the user registration and login system.";s:7:"package";s:15:"Core - required";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/content.module', @@ -43251,7 +45291,7 @@ 'bootstrap' => '0', 'schema_version' => '6010', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:7:"Content";s:11:"description";s:50:"Allows administrators to define new content types.";s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:7:"Content";s:11:"description";s:50:"Allows administrators to define new content types.";s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/content_copy/content_copy.module', @@ -43263,7 +45303,19 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:12:"Content Copy";s:11:"description";s:51:"Enables ability to import/export field definitions.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:12:"Content Copy";s:11:"description";s:51:"Enables ability to import/export field definitions.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', +)) +->values(array( + 'filename' => 'sites/all/modules/cck/modules/content_multigroup/content_multigroup.module', + 'name' => 'content_multigroup', + 'type' => 'module', + 'owner' => '', + 'status' => '0', + 'throttle' => '0', + 'bootstrap' => '0', + 'schema_version' => '-1', + 'weight' => '0', + 'info' => 'a:10:{s:4:"name";s:18:"Content Multigroup";s:11:"description";s:81:"Combine multiple CCK fields into repeating field collections that work in unison.";s:12:"dependencies";a:2:{i:0;s:7:"content";i:1;s:10:"fieldgroup";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:20:"6.x-3.0-alpha4+0-dev";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1435195093";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/content_permissions/content_permissions.module', @@ -43275,7 +45327,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:19:"Content Permissions";s:11:"description";s:43:"Set field-level permissions for CCK fields.";s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:19:"Content Permissions";s:11:"description";s:43:"Set field-level permissions for CCK fields.";s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/fieldgroup/fieldgroup.module', @@ -43287,19 +45339,19 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:10:"Fieldgroup";s:11:"description";s:37:"Create display groups for CCK fields.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"Fieldgroup";s:11:"description";s:37:"Create display groups for CCK fields.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/nodereference/nodereference.module', 'name' => 'nodereference', 'type' => 'module', 'owner' => '', - 'status' => '0', + 'status' => '1', 'throttle' => '0', 'bootstrap' => '0', - 'schema_version' => '-1', + 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:14:"Node Reference";s:11:"description";s:59:"Defines a field type for referencing one node from another.";s:12:"dependencies";a:3:{i:0;s:7:"content";i:1;s:4:"text";i:2;s:13:"optionwidgets";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:14:"Node Reference";s:11:"description";s:59:"Defines a field type for referencing one node from another.";s:12:"dependencies";a:3:{i:0;s:7:"content";i:1;s:4:"text";i:2;s:13:"optionwidgets";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/number/number.module', @@ -43311,7 +45363,7 @@ 'bootstrap' => '0', 'schema_version' => '6000', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:6:"Number";s:11:"description";s:28:"Defines numeric field types.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:6:"Number";s:11:"description";s:28:"Defines numeric field types.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/optionwidgets/optionwidgets.module', @@ -43323,7 +45375,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:14:"Option Widgets";s:11:"description";s:82:"Defines selection, check box and radio button widgets for text and numeric fields.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:14:"Option Widgets";s:11:"description";s:82:"Defines selection, check box and radio button widgets for text and numeric fields.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/text/text.module', @@ -43335,19 +45387,31 @@ 'bootstrap' => '0', 'schema_version' => '6003', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:4:"Text";s:11:"description";s:32:"Defines simple text field types.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Text";s:11:"description";s:32:"Defines simple text field types.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/cck/modules/userreference/userreference.module', 'name' => 'userreference', 'type' => 'module', 'owner' => '', + 'status' => '1', + 'throttle' => '0', + 'bootstrap' => '0', + 'schema_version' => '6002', + 'weight' => '0', + 'info' => 'a:10:{s:4:"name";s:14:"User Reference";s:11:"description";s:56:"Defines a field type for referencing a user from a node.";s:12:"dependencies";a:3:{i:0;s:7:"content";i:1;s:4:"text";i:2;s:13:"optionwidgets";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1434568159";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', +)) +->values(array( + 'filename' => 'sites/all/modules/cck/tests/content_test.module', + 'name' => 'content_test', + 'type' => 'module', + 'owner' => '', 'status' => '0', 'throttle' => '0', 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:14:"User Reference";s:11:"description";s:56:"Defines a field type for referencing a user from a node.";s:12:"dependencies";a:3:{i:0;s:7:"content";i:1;s:4:"text";i:2;s:13:"optionwidgets";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.9";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1294407979";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:12:{s:4:"name";s:12:"Content Test";s:11:"description";s:20:"Test module for CCK.";s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:12:"dependencies";a:1:{i:0;s:6:"schema";}s:6:"hidden";b:1;s:5:"files";a:1:{i:0;s:19:"content_test.module";}s:7:"version";s:20:"6.x-3.0-alpha4+0-dev";s:7:"project";s:3:"cck";s:9:"datestamp";s:10:"1435195093";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date/date.module', @@ -43359,7 +45423,7 @@ 'bootstrap' => '0', 'schema_version' => '6005', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:4:"Date";s:11:"description";s:41:"Defines CCK date/time fields and widgets.";s:12:"dependencies";a:3:{i:0;s:7:"content";i:1;s:8:"date_api";i:2;s:13:"date_timezone";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:4:"Date";s:11:"description";s:41:"Defines CCK date/time fields and widgets.";s:12:"dependencies";a:3:{i:0;s:7:"content";i:1;s:8:"date_api";i:2;s:13:"date_timezone";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_api.module', @@ -43371,7 +45435,7 @@ 'bootstrap' => '0', 'schema_version' => '6006', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:8:"Date API";s:11:"description";s:45:"A Date API that can be used by other modules.";s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:8:"Date API";s:11:"description";s:45:"A Date API that can be used by other modules.";s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_locale/date_locale.module', @@ -43383,7 +45447,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:11:"Date Locale";s:11:"description";s:124:"Allows the site admin to configure multiple formats for date/time display to tailor dates for a specific locale or audience.";s:7:"package";s:9:"Date/Time";s:12:"dependencies";a:2:{i:0;s:8:"date_api";i:1;s:6:"locale";}s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:11:"Date Locale";s:11:"description";s:124:"Allows the site admin to configure multiple formats for date/time display to tailor dates for a specific locale or audience.";s:7:"package";s:9:"Date/Time";s:12:"dependencies";a:2:{i:0;s:8:"date_api";i:1;s:6:"locale";}s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_php4/date_php4.module', @@ -43395,7 +45459,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:9:"Date PHP4";s:11:"description";s:134:"Emulate PHP 5.2 date functions in PHP 4.x, PHP 5.0, and PHP 5.1. Required when using the Date API with PHP versions less than PHP 5.2.";s:7:"package";s:9:"Date/Time";s:12:"dependencies";a:1:{i:0;s:8:"date_api";}s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:9:"Date PHP4";s:11:"description";s:134:"Emulate PHP 5.2 date functions in PHP 4.x, PHP 5.0, and PHP 5.1. Required when using the Date API with PHP versions less than PHP 5.2.";s:7:"package";s:9:"Date/Time";s:12:"dependencies";a:1:{i:0;s:8:"date_api";}s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_popup/date_popup.module', @@ -43407,7 +45471,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:10:"Date Popup";s:11:"description";s:84:"Enables jquery popup calendars and time entry widgets for selecting dates and times.";s:12:"dependencies";a:3:{i:0;s:8:"date_api";i:1;s:13:"date_timezone";i:2;s:9:"jquery_ui";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"Date Popup";s:11:"description";s:84:"Enables jquery popup calendars and time entry widgets for selecting dates and times.";s:12:"dependencies";a:2:{i:0;s:8:"date_api";i:1;s:13:"date_timezone";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_repeat/date_repeat.module', @@ -43419,7 +45483,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:15:"Date Repeat API";s:11:"description";s:73:"A Date Repeat API to calculate repeating dates and times from iCal rules.";s:12:"dependencies";a:1:{i:0;s:8:"date_api";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:15:"Date Repeat API";s:11:"description";s:73:"A Date Repeat API to calculate repeating dates and times from iCal rules.";s:12:"dependencies";a:1:{i:0;s:8:"date_api";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_timezone/date_timezone.module', @@ -43431,7 +45495,7 @@ 'bootstrap' => '0', 'schema_version' => '5200', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:13:"Date Timezone";s:11:"description";s:111:"Needed when using Date API. Overrides site and user timezone handling to set timezone names instead of offsets.";s:7:"package";s:9:"Date/Time";s:12:"dependencies";a:1:{i:0;s:8:"date_api";}s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:13:"Date Timezone";s:11:"description";s:111:"Needed when using Date API. Overrides site and user timezone handling to set timezone names instead of offsets.";s:7:"package";s:9:"Date/Time";s:12:"dependencies";a:1:{i:0;s:8:"date_api";}s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/date/date_tools/date_tools.module', @@ -43443,7 +45507,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:10:"Date Tools";s:11:"description";s:52:"Tools to import and auto-create dates and calendars.";s:12:"dependencies";a:2:{i:0;s:7:"content";i:1;s:4:"date";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.10";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1396284252";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"Date Tools";s:11:"description";s:52:"Tools to import and auto-create dates and calendars.";s:12:"dependencies";a:2:{i:0;s:7:"content";i:1;s:4:"date";}s:7:"package";s:9:"Date/Time";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-2.8";s:7:"project";s:4:"date";s:9:"datestamp";s:10:"1326285938";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/ddblock/ddblock.module', @@ -43551,7 +45615,7 @@ 'bootstrap' => '0', 'schema_version' => '6104', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:9:"FileField";s:11:"description";s:26:"Defines a file field type.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:3:"php";s:3:"5.0";s:7:"version";s:8:"6.x-3.13";s:7:"project";s:9:"filefield";s:9:"datestamp";s:10:"1405541029";s:10:"dependents";a:0:{}}', + 'info' => 'a:10:{s:4:"name";s:9:"FileField";s:11:"description";s:26:"Defines a file field type.";s:12:"dependencies";a:1:{i:0;s:7:"content";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:3:"php";s:3:"5.0";s:7:"version";s:8:"6.x-3.14";s:7:"project";s:9:"filefield";s:9:"datestamp";s:10:"1456327142";s:10:"dependents";a:0:{}}', )) ->values(array( 'filename' => 'sites/all/modules/filefield/filefield_meta/filefield_meta.module', @@ -43563,7 +45627,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:14:"FileField Meta";s:11:"description";s:48:"Add metadata gathering and storage to FileField.";s:12:"dependencies";a:2:{i:0;s:9:"filefield";i:1;s:6:"getid3";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:3:"php";s:3:"5.0";s:7:"version";s:8:"6.x-3.13";s:7:"project";s:9:"filefield";s:9:"datestamp";s:10:"1405541029";s:10:"dependents";a:0:{}}', + 'info' => 'a:10:{s:4:"name";s:14:"FileField Meta";s:11:"description";s:48:"Add metadata gathering and storage to FileField.";s:12:"dependencies";a:2:{i:0;s:9:"filefield";i:1;s:6:"getid3";}s:7:"package";s:3:"CCK";s:4:"core";s:3:"6.x";s:3:"php";s:3:"5.0";s:7:"version";s:8:"6.x-3.14";s:7:"project";s:9:"filefield";s:9:"datestamp";s:10:"1456327142";s:10:"dependents";a:0:{}}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18n.module', @@ -43575,7 +45639,7 @@ 'bootstrap' => '1', 'schema_version' => '9', 'weight' => '10', - 'info' => 'a:10:{s:4:"name";s:20:"Internationalization";s:11:"description";s:49:"Extends Drupal support for multilingual features.";s:12:"dependencies";a:2:{i:0;s:6:"locale";i:1;s:11:"translation";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:20:"Internationalization";s:11:"description";s:49:"Extends Drupal support for multilingual features.";s:12:"dependencies";a:2:{i:0;s:6:"locale";i:1;s:11:"translation";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18nblocks/i18nblocks.module', @@ -43587,7 +45651,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:17:"Block translation";s:11:"description";s:50:"Enables multilingual blocks and block translation.";s:12:"dependencies";a:2:{i:0;s:4:"i18n";i:1;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:17:"Block translation";s:11:"description";s:50:"Enables multilingual blocks and block translation.";s:12:"dependencies";a:2:{i:0;s:4:"i18n";i:1;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18ncck/i18ncck.module', @@ -43599,7 +45663,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:15:"CCK translation";s:11:"description";s:56:"Supports translatable custom CCK fields and fieldgroups.";s:12:"dependencies";a:3:{i:0;s:4:"i18n";i:1;s:7:"content";i:2;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:15:"CCK translation";s:11:"description";s:56:"Supports translatable custom CCK fields and fieldgroups.";s:12:"dependencies";a:3:{i:0;s:4:"i18n";i:1;s:7:"content";i:2;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18ncontent/i18ncontent.module', @@ -43611,7 +45675,7 @@ 'bootstrap' => '0', 'schema_version' => '6002', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:24:"Content type translation";s:11:"description";s:99:"Add multilingual options for content and translate related strings: name, description, help text...";s:12:"dependencies";a:1:{i:0;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:24:"Content type translation";s:11:"description";s:99:"Add multilingual options for content and translate related strings: name, description, help text...";s:12:"dependencies";a:1:{i:0;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18nmenu/i18nmenu.module', @@ -43623,7 +45687,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:16:"Menu translation";s:11:"description";s:40:"Supports translatable custom menu items.";s:12:"dependencies";a:4:{i:0;s:4:"i18n";i:1;s:4:"menu";i:2;s:10:"i18nblocks";i:3;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:16:"Menu translation";s:11:"description";s:40:"Supports translatable custom menu items.";s:12:"dependencies";a:4:{i:0;s:4:"i18n";i:1;s:4:"menu";i:2;s:10:"i18nblocks";i:3;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18npoll/i18npoll.module', @@ -43635,7 +45699,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:14:"Poll aggregate";s:11:"description";s:45:"Aggregates poll results for all translations.";s:12:"dependencies";a:2:{i:0;s:11:"translation";i:1;s:4:"poll";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:14:"Poll aggregate";s:11:"description";s:45:"Aggregates poll results for all translations.";s:12:"dependencies";a:2:{i:0;s:11:"translation";i:1;s:4:"poll";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18nprofile/i18nprofile.module', @@ -43647,7 +45711,7 @@ 'bootstrap' => '0', 'schema_version' => '2', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:19:"Profile translation";s:11:"description";s:36:"Enables multilingual profile fields.";s:12:"dependencies";a:2:{i:0;s:7:"profile";i:1;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:19:"Profile translation";s:11:"description";s:36:"Enables multilingual profile fields.";s:12:"dependencies";a:2:{i:0;s:7:"profile";i:1;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18nstrings/i18nstrings.module', @@ -43659,7 +45723,7 @@ 'bootstrap' => '0', 'schema_version' => '6006', 'weight' => '10', - 'info' => 'a:10:{s:4:"name";s:18:"String translation";s:11:"description";s:57:"Provides support for translation of user defined strings.";s:12:"dependencies";a:1:{i:0;s:6:"locale";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:18:"String translation";s:11:"description";s:57:"Provides support for translation of user defined strings.";s:12:"dependencies";a:1:{i:0;s:6:"locale";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18nsync/i18nsync.module', @@ -43671,7 +45735,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:24:"Synchronize translations";s:11:"description";s:74:"Synchronizes taxonomy and fields accross translations of the same content.";s:12:"dependencies";a:1:{i:0;s:4:"i18n";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:24:"Synchronize translations";s:11:"description";s:74:"Synchronizes taxonomy and fields accross translations of the same content.";s:12:"dependencies";a:1:{i:0;s:4:"i18n";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/i18ntaxonomy/i18ntaxonomy.module', @@ -43683,7 +45747,19 @@ 'bootstrap' => '0', 'schema_version' => '6002', 'weight' => '5', - 'info' => 'a:10:{s:4:"name";s:20:"Taxonomy translation";s:11:"description";s:30:"Enables multilingual taxonomy.";s:12:"dependencies";a:3:{i:0;s:4:"i18n";i:1;s:8:"taxonomy";i:2;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:20:"Taxonomy translation";s:11:"description";s:30:"Enables multilingual taxonomy.";s:12:"dependencies";a:3:{i:0;s:4:"i18n";i:1;s:8:"taxonomy";i:2;s:11:"i18nstrings";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', +)) +->values(array( + 'filename' => 'sites/all/modules/i18n/i18nviews/i18nviews.module', + 'name' => 'i18nviews', + 'type' => 'module', + 'owner' => '', + 'status' => '0', + 'throttle' => '0', + 'bootstrap' => '0', + 'schema_version' => '-1', + 'weight' => '0', + 'info' => 'a:10:{s:4:"name";s:17:"Views translation";s:11:"description";s:80:"Translation of views strings and content selection for views. Requires Views 3.x";s:12:"dependencies";a:3:{i:0;s:5:"views";i:1;s:11:"i18nstrings";i:2;s:12:"i18ntaxonomy";}s:7:"package";s:13:"Multilanguage";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/i18n/tests/i18n_test.module', @@ -43695,7 +45771,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:26:"Internationalization tests";s:11:"description";s:55:"Helper module for testing i18n (do not enable manually)";s:12:"dependencies";a:3:{i:0;s:6:"locale";i:1;s:11:"translation";i:2;s:4:"i18n";}s:7:"package";s:7:"Testing";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1318336004";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:26:"Internationalization tests";s:11:"description";s:55:"Helper module for testing i18n (do not enable manually)";s:12:"dependencies";a:3:{i:0;s:6:"locale";i:1;s:11:"translation";i:2;s:4:"i18n";}s:7:"package";s:5:"Devel";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-1.4";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1270669810";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/imageapi/imageapi.module', @@ -43707,7 +45783,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:8:"ImageAPI";s:11:"description";s:38:"ImageAPI supporting multiple toolkits.";s:7:"package";s:10:"ImageCache";s:4:"core";s:3:"6.x";s:3:"php";s:3:"5.1";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:8:"imageapi";s:9:"datestamp";s:10:"1305563215";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}}', + 'info' => 'a:10:{s:4:"name";s:8:"ImageAPI";s:11:"description";s:38:"ImageAPI supporting multiple toolkits.";s:7:"package";s:10:"ImageCache";s:4:"core";s:3:"6.x";s:3:"php";s:3:"5.1";s:7:"version";s:13:"6.x-1.9+4-dev";s:7:"project";s:8:"imageapi";s:9:"datestamp";s:10:"1380582658";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}}', )) ->values(array( 'filename' => 'sites/all/modules/imageapi/imageapi_gd.module', @@ -43719,7 +45795,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => "a:10:{s:4:\"name\";s:12:\"ImageAPI GD2\";s:11:\"description\";s:49:\"Uses PHP's built-in GD2 image processing support.\";s:7:\"package\";s:10:\"ImageCache\";s:4:\"core\";s:3:\"6.x\";s:7:\"version\";s:8:\"6.x-1.10\";s:7:\"project\";s:8:\"imageapi\";s:9:\"datestamp\";s:10:\"1305563215\";s:12:\"dependencies\";a:0:{}s:10:\"dependents\";a:0:{}s:3:\"php\";s:5:\"4.3.5\";}", + 'info' => "a:10:{s:4:\"name\";s:12:\"ImageAPI GD2\";s:11:\"description\";s:49:\"Uses PHP's built-in GD2 image processing support.\";s:7:\"package\";s:10:\"ImageCache\";s:4:\"core\";s:3:\"6.x\";s:7:\"version\";s:13:\"6.x-1.9+4-dev\";s:7:\"project\";s:8:\"imageapi\";s:9:\"datestamp\";s:10:\"1380582658\";s:12:\"dependencies\";a:0:{}s:10:\"dependents\";a:0:{}s:3:\"php\";s:5:\"4.3.5\";}", )) ->values(array( 'filename' => 'sites/all/modules/imageapi/imageapi_imagemagick.module', @@ -43731,7 +45807,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:20:"ImageAPI ImageMagick";s:11:"description";s:33:"Command Line ImageMagick support.";s:7:"package";s:10:"ImageCache";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-1.10";s:7:"project";s:8:"imageapi";s:9:"datestamp";s:10:"1305563215";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:20:"ImageAPI ImageMagick";s:11:"description";s:33:"Command Line ImageMagick support.";s:7:"package";s:10:"ImageCache";s:4:"core";s:3:"6.x";s:7:"version";s:13:"6.x-1.9+4-dev";s:7:"project";s:8:"imageapi";s:9:"datestamp";s:10:"1380582658";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/imagecache/imagecache.module', @@ -43743,7 +45819,7 @@ 'bootstrap' => '0', 'schema_version' => '6001', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:10:"ImageCache";s:11:"description";s:36:"Dynamic image manipulator and cache.";s:7:"package";s:10:"ImageCache";s:12:"dependencies";a:1:{i:0;s:8:"imageapi";}s:4:"core";s:3:"6.x";s:7:"version";s:11:"6.x-2.0-rc1";s:7:"project";s:10:"imagecache";s:9:"datestamp";s:10:"1337742655";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"ImageCache";s:11:"description";s:36:"Dynamic image manipulator and cache.";s:7:"package";s:10:"ImageCache";s:12:"dependencies";a:1:{i:0;s:8:"imageapi";}s:4:"core";s:3:"6.x";s:7:"version";s:18:"6.x-2.0-rc1+16-dev";s:7:"project";s:10:"imagecache";s:9:"datestamp";s:10:"1380582680";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/imagecache/imagecache_ui.module', @@ -43755,7 +45831,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:13:"ImageCache UI";s:11:"description";s:26:"ImageCache User Interface.";s:12:"dependencies";a:2:{i:0;s:10:"imagecache";i:1;s:8:"imageapi";}s:7:"package";s:10:"ImageCache";s:4:"core";s:3:"6.x";s:7:"version";s:11:"6.x-2.0-rc1";s:7:"project";s:10:"imagecache";s:9:"datestamp";s:10:"1337742655";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:13:"ImageCache UI";s:11:"description";s:26:"ImageCache User Interface.";s:12:"dependencies";a:2:{i:0;s:10:"imagecache";i:1;s:8:"imageapi";}s:7:"package";s:10:"ImageCache";s:4:"core";s:3:"6.x";s:7:"version";s:18:"6.x-2.0-rc1+16-dev";s:7:"project";s:10:"imagecache";s:9:"datestamp";s:10:"1380582680";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/imagefield/imagefield.module', @@ -43767,14 +45843,26 @@ 'bootstrap' => '0', 'schema_version' => '6006', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:10:"ImageField";s:11:"description";s:28:"Defines an image field type.";s:4:"core";s:3:"6.x";s:12:"dependencies";a:2:{i:0;s:7:"content";i:1;s:9:"filefield";}s:7:"package";s:3:"CCK";s:7:"version";s:8:"6.x-3.11";s:7:"project";s:10:"imagefield";s:9:"datestamp";s:10:"1365969012";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:10:"ImageField";s:11:"description";s:28:"Defines an image field type.";s:4:"core";s:3:"6.x";s:12:"dependencies";a:2:{i:0;s:7:"content";i:1;s:9:"filefield";}s:7:"package";s:3:"CCK";s:7:"version";s:7:"6.x-3.3";s:7:"project";s:10:"imagefield";s:9:"datestamp";s:10:"1273102211";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', +)) +->values(array( + 'filename' => 'sites/all/modules/jquery_ui/jquery_ui.module', + 'name' => 'jquery_ui', + 'type' => 'module', + 'owner' => '', + 'status' => '0', + 'throttle' => '0', + 'bootstrap' => '0', + 'schema_version' => '-1', + 'weight' => '0', + 'info' => 'a:8:{s:4:"name";s:9:"jQuery UI";s:11:"description";s:55:"Provides the jQuery UI plug-in to other Drupal modules.";s:7:"package";s:14:"User interface";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:7:"version";N;s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/link/link.module', 'name' => 'link', 'type' => 'module', 'owner' => '', - 'status' => '1', + 'status' => '0', 'throttle' => '0', 'bootstrap' => '0', 'schema_version' => '6002', @@ -43798,7 +45886,7 @@ 'name' => 'phone', 'type' => 'module', 'owner' => '', - 'status' => '1', + 'status' => '0', 'throttle' => '0', 'bootstrap' => '0', 'schema_version' => '6200', @@ -43815,7 +45903,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:7:{s:4:"name";s:12:"Variable API";s:11:"description";s:12:"Variable API";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:7:"version";N;s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:9:{s:4:"name";s:12:"Variable API";s:11:"description";s:12:"Variable API";s:4:"core";s:3:"6.x";s:7:"version";s:11:"6.x-1.x-dev";s:7:"project";s:8:"variable";s:9:"datestamp";s:10:"1406295528";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/variable/variable_admin/variable_admin.module', @@ -43827,7 +45915,7 @@ 'bootstrap' => '0', 'schema_version' => '0', 'weight' => '0', - 'info' => 'a:7:{s:4:"name";s:14:"Variable admin";s:11:"description";s:23:"Variable API - Admin UI";s:4:"core";s:3:"6.x";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:7:"version";N;s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:9:{s:4:"name";s:14:"Variable admin";s:11:"description";s:23:"Variable API - Admin UI";s:4:"core";s:3:"6.x";s:7:"version";s:11:"6.x-1.x-dev";s:7:"project";s:8:"variable";s:9:"datestamp";s:10:"1406295528";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/views/tests/views_test.module', @@ -43851,7 +45939,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:5:"Views";s:11:"description";s:55:"Create customized lists and queries from your database.";s:7:"package";s:5:"Views";s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.18";s:7:"project";s:5:"views";s:9:"datestamp";s:10:"1423647793";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:5:"Views";s:11:"description";s:55:"Create customized lists and queries from your database.";s:7:"package";s:5:"Views";s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-3.2";s:7:"project";s:5:"views";s:9:"datestamp";s:10:"1423647787";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/views/views_export/views_export.module', @@ -43863,7 +45951,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:14:"Views exporter";s:11:"description";s:40:"Allows exporting multiple views at once.";s:7:"package";s:5:"Views";s:12:"dependencies";a:1:{i:0;s:5:"views";}s:4:"core";s:3:"6.x";s:7:"version";s:8:"6.x-2.18";s:7:"project";s:5:"views";s:9:"datestamp";s:10:"1423647793";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:14:"Views exporter";s:11:"description";s:40:"Allows exporting multiple views at once.";s:7:"package";s:5:"Views";s:12:"dependencies";a:1:{i:0;s:5:"views";}s:4:"core";s:3:"6.x";s:7:"version";s:7:"6.x-3.2";s:7:"project";s:5:"views";s:9:"datestamp";s:10:"1423647787";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'sites/all/modules/views/views_ui.module', @@ -43875,7 +45963,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:8:"Views UI";s:11:"description";s:93:"Administrative interface to views. Without this module, you cannot create or edit your views.";s:7:"package";s:5:"Views";s:4:"core";s:3:"6.x";s:12:"dependencies";a:1:{i:0;s:5:"views";}s:7:"version";s:8:"6.x-2.18";s:7:"project";s:5:"views";s:9:"datestamp";s:10:"1423647793";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:10:{s:4:"name";s:8:"Views UI";s:11:"description";s:93:"Administrative interface to views. Without this module, you cannot create or edit your views.";s:7:"package";s:5:"Views";s:4:"core";s:3:"6.x";s:12:"dependencies";a:1:{i:0;s:5:"views";}s:7:"version";s:7:"6.x-3.2";s:7:"project";s:5:"views";s:9:"datestamp";s:10:"1423647787";s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'themes/bluemarine/bluemarine.info', @@ -43887,7 +45975,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:11:{s:4:"name";s:10:"Bluemarine";s:11:"description";s:66:"Table-based multi-column theme with a marine and ash color scheme.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/bluemarine/script.js";}s:10:"screenshot";s:32:"themes/bluemarine/screenshot.png";s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:13:{s:4:"name";s:10:"Bluemarine";s:11:"description";s:66:"Table-based multi-column theme with a marine and ash color scheme.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/bluemarine/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/bluemarine/script.js";}s:10:"screenshot";s:32:"themes/bluemarine/screenshot.png";s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'themes/chameleon/chameleon.info', @@ -43899,7 +45987,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:10:{s:4:"name";s:9:"Chameleon";s:11:"description";s:42:"Minimalist tabled theme with light colors.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:8:"features";a:4:{i:0;s:4:"logo";i:1;s:7:"favicon";i:2;s:4:"name";i:3;s:6:"slogan";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:7:"scripts";a:1:{s:9:"script.js";s:26:"themes/chameleon/script.js";}s:10:"screenshot";s:31:"themes/chameleon/screenshot.png";s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:12:{s:4:"name";s:9:"Chameleon";s:11:"description";s:42:"Minimalist tabled theme with light colors.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:8:"features";a:4:{i:0;s:4:"logo";i:1;s:7:"favicon";i:2;s:4:"name";i:3;s:6:"slogan";}s:11:"stylesheets";a:1:{s:3:"all";a:2:{s:9:"style.css";s:26:"themes/chameleon/style.css";s:10:"common.css";s:27:"themes/chameleon/common.css";}}s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"scripts";a:1:{s:9:"script.js";s:26:"themes/chameleon/script.js";}s:10:"screenshot";s:31:"themes/chameleon/screenshot.png";s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'themes/chameleon/marvin/marvin.info', @@ -43911,7 +45999,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:11:{s:4:"name";s:6:"Marvin";s:11:"description";s:31:"Boxy tabled theme in all grays.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"base theme";s:9:"chameleon";s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/chameleon/marvin/script.js";}s:10:"screenshot";s:38:"themes/chameleon/marvin/screenshot.png";s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:13:{s:4:"name";s:6:"Marvin";s:11:"description";s:31:"Boxy tabled theme in all grays.";s:7:"regions";a:2:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";}s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:10:"base theme";s:9:"chameleon";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:33:"themes/chameleon/marvin/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/chameleon/marvin/script.js";}s:10:"screenshot";s:38:"themes/chameleon/marvin/screenshot.png";s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'themes/garland/garland.info', @@ -43923,7 +46011,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:11:{s:4:"name";s:7:"Garland";s:11:"description";s:66:"Tableless, recolorable, multi-column, fluid width theme (default).";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:24:"themes/garland/script.js";}s:10:"screenshot";s:29:"themes/garland/screenshot.png";s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:13:{s:4:"name";s:7:"Garland";s:11:"description";s:66:"Tableless, recolorable, multi-column, fluid width theme (default).";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:11:"stylesheets";a:2:{s:3:"all";a:1:{s:9:"style.css";s:24:"themes/garland/style.css";}s:5:"print";a:1:{s:9:"print.css";s:24:"themes/garland/print.css";}}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:24:"themes/garland/script.js";}s:10:"screenshot";s:29:"themes/garland/screenshot.png";s:3:"php";s:5:"4.3.5";}', )) ->values(array( 'filename' => 'themes/garland/minnelli/minnelli.info', @@ -43935,7 +46023,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:12:{s:4:"name";s:8:"Minnelli";s:11:"description";s:56:"Tableless, recolorable, multi-column, fixed width theme.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:10:"base theme";s:7:"garland";s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/garland/minnelli/script.js";}s:10:"screenshot";s:38:"themes/garland/minnelli/screenshot.png";s:3:"php";s:5:"4.3.5";s:6:"engine";s:11:"phptemplate";}', + 'info' => 'a:14:{s:4:"name";s:8:"Minnelli";s:11:"description";s:56:"Tableless, recolorable, multi-column, fixed width theme.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:10:"base theme";s:7:"garland";s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:12:"minnelli.css";s:36:"themes/garland/minnelli/minnelli.css";}}s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:7:"scripts";a:1:{s:9:"script.js";s:33:"themes/garland/minnelli/script.js";}s:10:"screenshot";s:38:"themes/garland/minnelli/screenshot.png";s:3:"php";s:5:"4.3.5";s:6:"engine";s:11:"phptemplate";}', )) ->values(array( 'filename' => 'themes/pushbutton/pushbutton.info', @@ -43947,7 +46035,7 @@ 'bootstrap' => '0', 'schema_version' => '-1', 'weight' => '0', - 'info' => 'a:11:{s:4:"name";s:10:"Pushbutton";s:11:"description";s:52:"Tabled, multi-column theme in blue and orange tones.";s:7:"version";s:8:"6.38-dev";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/pushbutton/script.js";}s:10:"screenshot";s:32:"themes/pushbutton/screenshot.png";s:3:"php";s:5:"4.3.5";}', + 'info' => 'a:13:{s:4:"name";s:10:"Pushbutton";s:11:"description";s:52:"Tabled, multi-column theme in blue and orange tones.";s:7:"version";s:4:"6.38";s:4:"core";s:3:"6.x";s:6:"engine";s:11:"phptemplate";s:7:"project";s:6:"drupal";s:9:"datestamp";s:10:"1456343372";s:7:"regions";a:5:{s:4:"left";s:12:"Left sidebar";s:5:"right";s:13:"Right sidebar";s:7:"content";s:7:"Content";s:6:"header";s:6:"Header";s:6:"footer";s:6:"Footer";}s:8:"features";a:10:{i:0;s:20:"comment_user_picture";i:1;s:7:"favicon";i:2;s:7:"mission";i:3;s:4:"logo";i:4;s:4:"name";i:5;s:17:"node_user_picture";i:6;s:6:"search";i:7;s:6:"slogan";i:8;s:13:"primary_links";i:9;s:15:"secondary_links";}s:11:"stylesheets";a:1:{s:3:"all";a:1:{s:9:"style.css";s:27:"themes/pushbutton/style.css";}}s:7:"scripts";a:1:{s:9:"script.js";s:27:"themes/pushbutton/script.js";}s:10:"screenshot";s:32:"themes/pushbutton/screenshot.png";s:3:"php";s:5:"4.3.5";}', )) ->execute(); @@ -44015,28 +46103,28 @@ ->values(array( 'tid' => '1', 'vid' => '1', - 'name' => 'term 1 of vocabulary 1', - 'description' => 'description of term 1 of vocabulary 1', + 'name' => 'zu - term 1 of vocabulary 1', + 'description' => 'zu - description of term 1 of vocabulary 1', 'weight' => '0', - 'language' => '', + 'language' => 'zu', 'trid' => '0', )) ->values(array( 'tid' => '2', 'vid' => '2', - 'name' => 'term 2 of vocabulary 2', - 'description' => 'description of term 2 of vocabulary 2', + 'name' => 'fr - term 2 of vocabulary 2', + 'description' => 'fr - description of term 2 of vocabulary 2', 'weight' => '3', - 'language' => '', + 'language' => 'fr', 'trid' => '0', )) ->values(array( 'tid' => '3', 'vid' => '2', - 'name' => 'term 3 of vocabulary 2', - 'description' => 'description of term 3 of vocabulary 2', + 'name' => 'fr - term 3 of vocabulary 2', + 'description' => 'fr - description of term 3 of vocabulary 2', 'weight' => '4', - 'language' => '', + 'language' => 'fr', 'trid' => '0', )) ->values(array( @@ -44066,6 +46154,24 @@ 'language' => '', 'trid' => '0', )) +->values(array( + 'tid' => '7', + 'vid' => '1', + 'name' => 'fr - term 2 of vocabulary 1', + 'description' => 'fr - desc of term 2 vocab 1', + 'weight' => '0', + 'language' => 'fr', + 'trid' => '0', +)) +->values(array( + 'tid' => '8', + 'vid' => '7', + 'name' => 'General discussion', + 'description' => '', + 'weight' => '0', + 'language' => '', + 'trid' => '0', +)) ->execute(); $connection->schema()->createTable('term_hierarchy', array( @@ -44109,6 +46215,14 @@ 'tid' => '4', 'parent' => '0', )) +->values(array( + 'tid' => '7', + 'parent' => '0', +)) +->values(array( + 'tid' => '8', + 'parent' => '0', +)) ->values(array( 'tid' => '3', 'parent' => '2', @@ -44169,6 +46283,11 @@ 'vid' => '1', 'tid' => '1', )) +->values(array( + 'nid' => '1', + 'vid' => '1', + 'tid' => '2', +)) ->values(array( 'nid' => '2', 'vid' => '3', @@ -44189,6 +46308,11 @@ 'vid' => '2', 'tid' => '5', )) +->values(array( + 'nid' => '19', + 'vid' => '22', + 'tid' => '8', +)) ->execute(); $connection->schema()->createTable('term_relation', array( @@ -44613,8 +46737,8 @@ 'signature' => '', 'signature_format' => '0', 'created' => '0', - 'access' => '1468384823', - 'login' => '1468384420', + 'access' => '1494966478', + 'login' => '1494966280', 'status' => '1', 'timezone' => NULL, 'language' => '', @@ -44903,7 +47027,7 @@ )) ->values(array( 'name' => 'book_block_mode', - 'value' => 's:9:"all pages";', + 'value' => 's:10:"book pages";', )) ->values(array( 'name' => 'book_child_type', @@ -45261,6 +47385,10 @@ 'name' => 'contact_hourly_threshold', 'value' => 'i:3;', )) +->values(array( + 'name' => 'content_extra_weights_employee', + 'value' => 'a:11:{s:5:"title";s:2:"-5";s:10:"body_field";s:1:"0";s:20:"revision_information";s:2:"20";s:6:"author";s:2:"20";s:7:"options";s:2:"25";s:16:"comment_settings";s:2:"30";s:8:"language";s:1:"0";s:11:"translation";s:2:"30";s:4:"menu";s:2:"-2";s:4:"book";s:2:"10";s:4:"path";s:2:"30";}', +)) ->values(array( 'name' => 'content_extra_weights_story', 'value' => 'a:9:{s:5:"title";s:2:"-5";s:10:"body_field";s:2:"-2";s:20:"revision_information";s:2:"19";s:6:"author";s:2:"18";s:7:"options";s:2:"20";s:16:"comment_settings";s:2:"22";s:4:"menu";s:2:"-3";s:8:"taxonomy";s:2:"-4";s:11:"attachments";s:2:"21";}', @@ -45283,7 +47411,7 @@ )) ->values(array( 'name' => 'css_js_query_string', - 'value' => 's:20:"8SAkMTxRZndiw7000000";', + 'value' => 's:20:"y8SAkMTxRZndiw700000";', )) ->values(array( 'name' => 'date:story:4:field_test_datestamp_fromto', @@ -45651,11 +47779,11 @@ )) ->values(array( 'name' => 'forum_block_num_0', - 'value' => 's:1:"5";', + 'value' => 's:1:"3";', )) ->values(array( 'name' => 'forum_block_num_1', - 'value' => 's:1:"5";', + 'value' => 's:1:"4";', )) ->values(array( 'name' => 'forum_hot_topic', @@ -45663,7 +47791,7 @@ )) ->values(array( 'name' => 'forum_nav_vocabulary', - 'value' => 's:1:"1";', + 'value' => 's:1:"7";', )) ->values(array( 'name' => 'forum_order', @@ -45677,6 +47805,14 @@ 'name' => 'i18nstrings_allowed_formats', 'value' => 'a:2:{i:0;i:1;i:1;i:2;}', )) +->values(array( + 'name' => 'i18ntaxonomy_vocabulary', + 'value' => 'a:2:{i:1;s:1:"3";i:2;s:1:"2";}', +)) +->values(array( + 'name' => 'i18n_lock_node_article', + 'value' => 'i:1;', +)) ->values(array( 'name' => 'image_jpeg_quality', 'value' => 'i:75;', @@ -45687,7 +47823,7 @@ )) ->values(array( 'name' => 'javascript_parsed', - 'value' => 'a:21:{i:0;s:14:"misc/jquery.js";i:1;s:14:"misc/drupal.js";i:2;s:19:"misc/tableheader.js";i:3;s:16:"misc/collapse.js";i:4;s:16:"misc/textarea.js";i:5;s:20:"modules/user/user.js";i:6;s:17:"misc/tabledrag.js";i:7;s:26:"modules/profile/profile.js";i:8;s:12:"misc/form.js";i:9;s:19:"misc/tableselect.js";i:10;s:20:"misc/autocomplete.js";s:10:"refresh:ga";s:7:"waiting";s:10:"refresh:ab";s:7:"waiting";s:10:"refresh:ca";s:7:"waiting";s:10:"refresh:fi";s:7:"waiting";s:10:"refresh:es";s:7:"waiting";i:11;s:16:"misc/progress.js";i:12;s:13:"misc/batch.js";s:10:"refresh:nl";s:7:"waiting";s:10:"refresh:de";s:7:"waiting";s:10:"refresh:pl";s:7:"waiting";}', + 'value' => 'a:16:{i:0;s:14:"misc/jquery.js";i:1;s:14:"misc/drupal.js";i:2;s:19:"misc/tableheader.js";s:10:"refresh:fr";s:7:"waiting";s:10:"refresh:zu";s:7:"waiting";i:3;s:17:"misc/tabledrag.js";i:4;s:32:"sites/all/modules/cck/content.js";i:5;s:16:"misc/textarea.js";i:6;s:16:"misc/collapse.js";i:7;s:12:"misc/form.js";i:8;s:19:"misc/tableselect.js";i:9;s:20:"modules/user/user.js";i:10;s:20:"misc/autocomplete.js";i:11;s:19:"misc/jquery.form.js";i:12;s:12:"misc/ahah.js";i:13;s:14:"misc/teaser.js";}', )) ->values(array( 'name' => 'language_content_type_article', @@ -45697,10 +47833,6 @@ 'name' => 'language_content_type_employee', 'value' => 's:1:"2";', )) -->values(array( - 'name' => 'i18n_lock_node_article', - 'value' => 'i:1;', -)) ->values(array( 'name' => 'language_count', 'value' => 'i:11;', @@ -45721,6 +47853,10 @@ 'name' => 'locale_js_directory', 'value' => 's:9:"languages";', )) +->values(array( + 'name' => 'menu_default_node_menu', + 'value' => 's:10:"navigation";', +)) ->values(array( 'name' => 'menu_expanded', 'value' => 'a:1:{i:0;s:15:"secondary-links";}', @@ -45875,27 +48011,27 @@ )) ->values(array( 'name' => 'statistics_block_top_all_num', - 'value' => 'i:0;', + 'value' => 's:1:"8";', )) ->values(array( 'name' => 'statistics_block_top_day_num', - 'value' => 'i:0;', + 'value' => 's:1:"7";', )) ->values(array( 'name' => 'statistics_block_top_last_num', - 'value' => 'i:0;', + 'value' => 's:1:"9";', )) ->values(array( 'name' => 'statistics_count_content_views', - 'value' => 'i:0;', + 'value' => 's:1:"1";', )) ->values(array( 'name' => 'statistics_enable_access_log', - 'value' => 'i:0;', + 'value' => 's:1:"0";', )) ->values(array( 'name' => 'statistics_flush_accesslog_timer', - 'value' => 'i:259200;', + 'value' => 's:6:"259200";', )) ->values(array( 'name' => 'syslog_facility', @@ -45954,13 +48090,37 @@ 'value' => 's:1:"1";', )) ->values(array( - 'name' => 'upload_page', - 'value' => 'b:1;', + 'name' => 'upload_employee', + 'value' => 'b:0;', +)) +->values(array( + 'name' => 'upload_event', + 'value' => 'b:0;', +)) +->values(array( + 'name' => 'upload_sponsor', + 'value' => 'b:0;', )) ->values(array( 'name' => 'upload_story', 'value' => 'b:1;', )) +->values(array( + 'name' => 'upload_test_event', + 'value' => 'b:0;', +)) +->values(array( + 'name' => 'upload_test_page', + 'value' => 'b:0;', +)) +->values(array( + 'name' => 'upload_test_planet', + 'value' => 'b:0;', +)) +->values(array( + 'name' => 'upload_test_story', + 'value' => 'b:0;', +)) ->values(array( 'name' => 'user_block_max_list_count', 'value' => 's:2:"10";', @@ -46177,7 +48337,7 @@ 'tags' => '1', 'module' => 'taxonomy', 'weight' => '5', - 'language' => '', + 'language' => 'fr', )) ->values(array( 'vid' => '3', @@ -46221,6 +48381,34 @@ 'weight' => '7', 'language' => '', )) +->values(array( + 'vid' => '6', + 'name' => 'Type', + 'description' => '', + 'help' => '', + 'relations' => '1', + 'hierarchy' => '0', + 'multiple' => '0', + 'required' => '0', + 'tags' => '0', + 'module' => 'taxonomy', + 'weight' => '0', + 'language' => '', +)) +->values(array( + 'vid' => '7', + 'name' => 'Forums', + 'description' => '', + 'help' => '', + 'relations' => '1', + 'hierarchy' => '0', + 'multiple' => '0', + 'required' => '0', + 'tags' => '0', + 'module' => 'taxonomy', + 'weight' => '0', + 'language' => '', +)) ->execute(); $connection->schema()->createTable('vocabulary_node_types', array( @@ -46255,10 +48443,18 @@ 'vid' => '4', 'type' => 'article', )) +->values(array( + 'vid' => '7', + 'type' => 'forum', +)) ->values(array( 'vid' => '4', 'type' => 'page', )) +->values(array( + 'vid' => '6', + 'type' => 'sponsor', +)) ->values(array( 'vid' => '1', 'type' => 'story', diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php index a388f8e5..da9d4674 100644 --- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php +++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php @@ -2512,7 +2512,7 @@ 'nid' => '1', 'uid' => '1', 'subject' => 'A comment', - 'hostname' => '::1', + 'hostname' => '2001:db8:ffff:ffff:ffff:ffff:ffff:ffff', 'created' => '1421727536', 'changed' => '1421727536', 'status' => '1', @@ -3426,6 +3426,156 @@ 'translatable' => '0', 'deleted' => '0', )) +->values(array( + 'id' => '25', + 'field_name' => 'field_private_file', + 'type' => 'file', + 'module' => 'file', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:13:"display_field";i:0;s:15:"display_default";i:0;s:10:"uri_scheme";s:7:"private";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:29:"field_data_field_private_file";a:3:{s:3:"fid";s:22:"field_private_file_fid";s:7:"display";s:26:"field_private_file_display";s:11:"description";s:30:"field_private_file_description";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:33:"field_revision_field_private_file";a:3:{s:3:"fid";s:22:"field_private_file_fid";s:7:"display";s:26:"field_private_file_display";s:11:"description";s:30:"field_private_file_description";}}}}}s:12:"foreign keys";a:1:{s:3:"fid";a:2:{s:5:"table";s:12:"file_managed";s:7:"columns";a:1:{s:3:"fid";s:3:"fid";}}}s:7:"indexes";a:1:{s:3:"fid";a:1:{i:0;s:3:"fid";}}s:2:"id";s:2:"25";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '26', + 'field_name' => 'field_text_plain', + 'type' => 'text', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:1:{s:10:"max_length";s:3:"255";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:27:"field_data_field_text_plain";a:2:{s:5:"value";s:22:"field_text_plain_value";s:6:"format";s:23:"field_text_plain_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:31:"field_revision_field_text_plain";a:2:{s:5:"value";s:22:"field_text_plain_value";s:6:"format";s:23:"field_text_plain_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"26";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '27', + 'field_name' => 'field_text_filtered', + 'type' => 'text', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:1:{s:10:"max_length";s:3:"255";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:30:"field_data_field_text_filtered";a:2:{s:5:"value";s:25:"field_text_filtered_value";s:6:"format";s:26:"field_text_filtered_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:34:"field_revision_field_text_filtered";a:2:{s:5:"value";s:25:"field_text_filtered_value";s:6:"format";s:26:"field_text_filtered_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"27";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '28', + 'field_name' => 'field_text_plain_filtered', + 'type' => 'text', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:1:{s:10:"max_length";s:3:"255";}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:36:"field_data_field_text_plain_filtered";a:2:{s:5:"value";s:31:"field_text_plain_filtered_value";s:6:"format";s:32:"field_text_plain_filtered_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:40:"field_revision_field_text_plain_filtered";a:2:{s:5:"value";s:31:"field_text_plain_filtered_value";s:6:"format";s:32:"field_text_plain_filtered_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"28";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '29', + 'field_name' => 'field_text_long_plain', + 'type' => 'text_long', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:32:"field_data_field_text_long_plain";a:2:{s:5:"value";s:27:"field_text_long_plain_value";s:6:"format";s:28:"field_text_long_plain_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:36:"field_revision_field_text_long_plain";a:2:{s:5:"value";s:27:"field_text_long_plain_value";s:6:"format";s:28:"field_text_long_plain_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"29";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '30', + 'field_name' => 'field_text_long_filtered', + 'type' => 'text_long', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:35:"field_data_field_text_long_filtered";a:2:{s:5:"value";s:30:"field_text_long_filtered_value";s:6:"format";s:31:"field_text_long_filtered_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:39:"field_revision_field_text_long_filtered";a:2:{s:5:"value";s:30:"field_text_long_filtered_value";s:6:"format";s:31:"field_text_long_filtered_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"30";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '31', + 'field_name' => 'field_text_long_plain_filtered', + 'type' => 'text_long', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:41:"field_data_field_text_long_plain_filtered";a:2:{s:5:"value";s:36:"field_text_long_plain_filtered_value";s:6:"format";s:37:"field_text_long_plain_filtered_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:45:"field_revision_field_text_long_plain_filtered";a:2:{s:5:"value";s:36:"field_text_long_plain_filtered_value";s:6:"format";s:37:"field_text_long_plain_filtered_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"31";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '32', + 'field_name' => 'field_text_sum_plain', + 'type' => 'text_with_summary', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:31:"field_data_field_text_sum_plain";a:3:{s:5:"value";s:26:"field_text_sum_plain_value";s:7:"summary";s:28:"field_text_sum_plain_summary";s:6:"format";s:27:"field_text_sum_plain_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:35:"field_revision_field_text_sum_plain";a:3:{s:5:"value";s:26:"field_text_sum_plain_value";s:7:"summary";s:28:"field_text_sum_plain_summary";s:6:"format";s:27:"field_text_sum_plain_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"32";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '33', + 'field_name' => 'field_text_sum_filtered', + 'type' => 'text_with_summary', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:34:"field_data_field_text_sum_filtered";a:3:{s:5:"value";s:29:"field_text_sum_filtered_value";s:7:"summary";s:31:"field_text_sum_filtered_summary";s:6:"format";s:30:"field_text_sum_filtered_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:38:"field_revision_field_text_sum_filtered";a:3:{s:5:"value";s:29:"field_text_sum_filtered_value";s:7:"summary";s:31:"field_text_sum_filtered_summary";s:6:"format";s:30:"field_text_sum_filtered_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"33";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) +->values(array( + 'id' => '34', + 'field_name' => 'field_text_sum_plain_filtered', + 'type' => 'text_with_summary', + 'module' => 'text', + 'active' => '1', + 'storage_type' => 'field_sql_storage', + 'storage_module' => 'field_sql_storage', + 'storage_active' => '1', + 'locked' => '0', + 'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:0:{}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:39:"field_data_field_text_sum_plain_filtere";a:3:{s:5:"value";s:34:"field_text_sum_plain_filtere_value";s:7:"summary";s:36:"field_text_sum_plain_filtere_summary";s:6:"format";s:35:"field_text_sum_plain_filtere_format";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:43:"field_revision_field_text_sum_plain_filtere";a:3:{s:5:"value";s:34:"field_text_sum_plain_filtere_value";s:7:"summary";s:36:"field_text_sum_plain_filtere_summary";s:6:"format";s:35:"field_text_sum_plain_filtere_format";}}}}}s:12:"foreign keys";a:1:{s:6:"format";a:2:{s:5:"table";s:13:"filter_format";s:7:"columns";a:1:{s:6:"format";s:6:"format";}}}s:7:"indexes";a:1:{s:6:"format";a:1:{i:0;s:6:"format";}}s:2:"id";s:2:"34";}', + 'cardinality' => '1', + 'translatable' => '0', + 'deleted' => '0', +)) ->execute(); $connection->schema()->createTable('field_config_instance', array( @@ -3837,6 +3987,177 @@ 'data' => 'a:7:{s:5:"label";s:14:"Term Reference";s:6:"widget";a:5:{s:6:"weight";s:2:"14";s:4:"type";s:21:"taxonomy_autocomplete";s:6:"module";s:8:"taxonomy";s:6:"active";i:0;s:8:"settings";a:2:{s:4:"size";i:60;s:17:"autocomplete_path";s:21:"taxonomy/autocomplete";}}s:8:"settings";a:1:{s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:4:{s:5:"label";s:5:"above";s:4:"type";s:6:"hidden";s:6:"weight";s:2:"13";s:8:"settings";a:0:{}}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', 'deleted' => '0', )) +->values(array( + 'id' => '42', + 'field_id' => '25', + 'field_name' => 'field_private_file', + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'data' => 'a:6:{s:5:"label";s:12:"Private file";s:6:"widget";a:5:{s:6:"weight";s:2:"19";s:4:"type";s:12:"file_generic";s:6:"module";s:4:"file";s:6:"active";i:1;s:8:"settings";a:1:{s:18:"progress_indicator";s:8:"throbber";}}s:8:"settings";a:5:{s:14:"file_directory";s:0:"";s:15:"file_extensions";s:3:"txt";s:12:"max_filesize";s:0:"";s:17:"description_field";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"file_default";s:8:"settings";a:0:{}s:6:"module";s:4:"file";s:6:"weight";i:18;}}s:8:"required";i:0;s:11:"description";s:0:"";}', + 'deleted' => '0', +)) +->values(array( + 'id' => '43', + 'field_id' => '26', + 'field_name' => 'field_text_plain', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:10:"Text plain";s:6:"widget";a:5:{s:6:"weight";s:2:"11";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:11;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '44', + 'field_id' => '27', + 'field_name' => 'field_text_filtered', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:13:"Text filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"12";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"1";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:12;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '45', + 'field_id' => '28', + 'field_name' => 'field_text_plain_filtered', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:23:"Text plain and filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"13";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:13;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '46', + 'field_id' => '29', + 'field_name' => 'field_text_long_plain', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:15:"Text long plain";s:6:"widget";a:5:{s:6:"weight";s:2:"14";s:4:"type";s:13:"text_textarea";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"rows";s:1:"5";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:14;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '47', + 'field_id' => '30', + 'field_name' => 'field_text_long_filtered', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:18:"Text long filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"15";s:4:"type";s:13:"text_textarea";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"rows";s:1:"5";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"1";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:15;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '48', + 'field_id' => '31', + 'field_name' => 'field_text_long_plain_filtered', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:28:"Text long plain and filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"16";s:4:"type";s:13:"text_textarea";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"rows";s:1:"5";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:16;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '49', + 'field_id' => '32', + 'field_name' => 'field_text_sum_plain', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:18:"Text summary plain";s:6:"widget";a:5:{s:6:"weight";s:2:"17";s:4:"type";s:26:"text_textarea_with_summary";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:2:{s:4:"rows";s:2:"20";s:12:"summary_rows";i:5;}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"0";s:15:"display_summary";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:17;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '50', + 'field_id' => '33', + 'field_name' => 'field_text_sum_filtered', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:21:"Text summary filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"18";s:4:"type";s:26:"text_textarea_with_summary";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:2:{s:4:"rows";s:2:"20";s:12:"summary_rows";i:5;}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"1";s:15:"display_summary";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:18;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '51', + 'field_id' => '34', + 'field_name' => 'field_text_sum_plain_filtered', + 'entity_type' => 'node', + 'bundle' => 'article', + 'data' => 'a:7:{s:5:"label";s:31:"Text summary plain and filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"19";s:4:"type";s:26:"text_textarea_with_summary";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:2:{s:4:"rows";s:2:"20";s:12:"summary_rows";i:5;}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"0";s:15:"display_summary";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:19;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '52', + 'field_id' => '26', + 'field_name' => 'field_text_plain', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:10:"Text plain";s:6:"widget";a:5:{s:6:"weight";s:2:"-2";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:1;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '53', + 'field_id' => '27', + 'field_name' => 'field_text_filtered', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:13:"Text filtered";s:6:"widget";a:5:{s:6:"weight";s:1:"0";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"1";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:2;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '54', + 'field_id' => '28', + 'field_name' => 'field_text_plain_filtered', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:23:"Text plain and filtered";s:6:"widget";a:5:{s:6:"weight";s:1:"2";s:4:"type";s:14:"text_textfield";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"size";s:2:"60";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"1";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:3;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '55', + 'field_id' => '29', + 'field_name' => 'field_text_long_plain', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:15:"Text long plain";s:6:"widget";a:5:{s:6:"weight";s:1:"4";s:4:"type";s:13:"text_textarea";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"rows";s:1:"5";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"0";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:4;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '56', + 'field_id' => '30', + 'field_name' => 'field_text_long_filtered', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:18:"Text long filtered";s:6:"widget";a:5:{s:6:"weight";s:1:"6";s:4:"type";s:13:"text_textarea";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"rows";s:1:"5";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"1";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:5;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '57', + 'field_id' => '31', + 'field_name' => 'field_text_long_plain_filtered', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:28:"Text long plain and filtered";s:6:"widget";a:5:{s:6:"weight";s:1:"8";s:4:"type";s:13:"text_textarea";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:1:{s:4:"rows";s:1:"5";}}s:8:"settings";a:2:{s:15:"text_processing";s:1:"1";s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:6;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '58', + 'field_id' => '32', + 'field_name' => 'field_text_sum_plain', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:18:"Text summary plain";s:6:"widget";a:5:{s:6:"weight";s:2:"10";s:4:"type";s:26:"text_textarea_with_summary";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:2:{s:4:"rows";s:2:"20";s:12:"summary_rows";i:5;}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"0";s:15:"display_summary";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:7;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '59', + 'field_id' => '33', + 'field_name' => 'field_text_sum_filtered', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:21:"Text summary filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"12";s:4:"type";s:26:"text_textarea_with_summary";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:2:{s:4:"rows";s:2:"20";s:12:"summary_rows";i:5;}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"1";s:15:"display_summary";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:8;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) +->values(array( + 'id' => '60', + 'field_id' => '34', + 'field_name' => 'field_text_sum_plain_filtered', + 'entity_type' => 'node', + 'bundle' => 'page', + 'data' => 'a:7:{s:5:"label";s:31:"Text summary plain and filtered";s:6:"widget";a:5:{s:6:"weight";s:2:"14";s:4:"type";s:26:"text_textarea_with_summary";s:6:"module";s:4:"text";s:6:"active";i:1;s:8:"settings";a:2:{s:4:"rows";s:2:"20";s:12:"summary_rows";i:5;}}s:8:"settings";a:3:{s:15:"text_processing";s:1:"1";s:15:"display_summary";i:0;s:18:"user_register_form";b:0;}s:7:"display";a:1:{s:7:"default";a:5:{s:5:"label";s:5:"above";s:4:"type";s:12:"text_default";s:8:"settings";a:0:{}s:6:"module";s:4:"text";s:6:"weight";i:9;}}s:8:"required";i:0;s:11:"description";s:0:"";s:13:"default_value";N;}', + 'deleted' => '0', +)) ->execute(); $connection->schema()->createTable('field_data_body', array( @@ -5340,14 +5661,14 @@ 'bundle' => 'test_content_type', 'deleted' => '0', 'entity_id' => '1', - 'revision_id' => '1', + 'revision_id' => '6', 'language' => 'und', 'delta' => '0', 'field_phone_value' => '99-99-99-99', )) ->execute(); -$connection->schema()->createTable('field_data_field_tags', array( +$connection->schema()->createTable('field_data_field_private_file', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -5364,7 +5685,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -5391,24 +5712,59 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_tags_tid' => array( + 'field_private_file_fid' => array( 'type' => 'int', 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), + 'field_private_file_display' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '1', + 'unsigned' => TRUE, + ), + 'field_private_file_description' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'normal', + ), ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_private_file_fid' => array( + 'field_private_file_fid', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_data_field_tags') +$connection->insert('field_data_field_private_file') ->fields(array( 'entity_type', 'bundle', @@ -5417,71 +5773,25 @@ 'revision_id', 'language', 'delta', - 'field_tags_tid', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '0', - 'field_tags_tid' => '9', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '1', - 'field_tags_tid' => '14', + 'field_private_file_fid', + 'field_private_file_display', + 'field_private_file_description', )) ->values(array( 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '2', - 'field_tags_tid' => '17', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', + 'bundle' => 'test_content_type', 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', + 'entity_id' => '1', + 'revision_id' => '6', 'language' => 'und', 'delta' => '0', - 'field_tags_tid' => '9', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', - 'language' => 'und', - 'delta' => '1', - 'field_tags_tid' => '14', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', - 'language' => 'und', - 'delta' => '2', - 'field_tags_tid' => '17', + 'field_private_file_fid' => '4', + 'field_private_file_display' => '1', + 'field_private_file_description' => '', )) ->execute(); -$connection->schema()->createTable('field_data_field_term_entityreference', array( +$connection->schema()->createTable('field_data_field_tags', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -5498,7 +5808,141 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'tiny', + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_tags_tid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_data_field_tags') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_tags_tid', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '0', + 'field_tags_tid' => '9', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '1', + 'field_tags_tid' => '14', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '2', + 'field_tags_tid' => '17', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '0', + 'field_tags_tid' => '9', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '1', + 'field_tags_tid' => '14', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '2', + 'field_tags_tid' => '17', +)) +->execute(); + +$connection->schema()->createTable('field_data_field_term_entityreference', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -5782,6 +6226,94 @@ )) ->execute(); +$connection->schema()->createTable('field_data_field_text_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_filtered_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'field_text_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_filtered_format' => array( + 'field_text_filtered_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + $connection->schema()->createTable('field_data_field_text_list', array( 'fields' => array( 'entity_type' => array( @@ -5865,7 +6397,7 @@ )) ->execute(); -$connection->schema()->createTable('field_data_field_user_entityreference', array( +$connection->schema()->createTable('field_data_field_text_long_filtered', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -5909,11 +6441,15 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_user_entityreference_target_id' => array( - 'type' => 'int', - 'not null' => TRUE, - 'size' => 'normal', - 'unsigned' => TRUE, + 'field_text_long_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_long_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', ), ), 'primary key' => array( @@ -5942,37 +6478,14 @@ 'language' => array( 'language', ), - 'field_user_entityreference_target_id' => array( - 'field_user_entityreference_target_id', + 'field_text_long_filtered_format' => array( + 'field_text_long_filtered_format', ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_data_field_user_entityreference') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_user_entityreference_target_id', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_user_entityreference_target_id' => '2', -)) -->execute(); - -$connection->schema()->createTable('field_data_taxonomy_forums', array( +$connection->schema()->createTable('field_data_field_text_long_plain', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -5989,7 +6502,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6016,24 +6529,51 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'taxonomy_forums_tid' => array( - 'type' => 'int', + 'field_text_long_plain_value' => array( + 'type' => 'text', 'not null' => FALSE, - 'size' => 'normal', - 'unsigned' => TRUE, + 'size' => 'big', + ), + 'field_text_long_plain_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', ), ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_long_plain_format' => array( + 'field_text_long_plain_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->schema()->createTable('field_revision_body', array( +$connection->schema()->createTable('field_data_field_text_long_plain_filtered', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6050,7 +6590,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6061,7 +6601,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6077,17 +6617,12 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'body_value' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'normal', - ), - 'body_summary' => array( + 'field_text_long_plain_filtered_value' => array( 'type' => 'text', 'not null' => FALSE, - 'size' => 'normal', + 'size' => 'big', ), - 'body_format' => array( + 'field_text_long_plain_filtered_format' => array( 'type' => 'varchar', 'not null' => FALSE, 'length' => '255', @@ -6095,55 +6630,38 @@ ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_long_plain_filtered_format' => array( + 'field_text_long_plain_filtered_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_body') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'body_value', - 'body_summary', - 'body_format', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '0', - 'body_value' => "...is that it's the absolute best show ever. Trust me, I would know.", - 'body_summary' => '', - 'body_format' => 'filtered_html', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', - 'language' => 'und', - 'delta' => '0', - 'body_value' => "is - ...is that it's the absolute best show ever. Trust me, I would know.", - 'body_summary' => '', - 'body_format' => 'filtered_html', -)) -->execute(); - -$connection->schema()->createTable('field_revision_comment_body', array( +$connection->schema()->createTable('field_data_field_text_plain', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6160,7 +6678,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6171,7 +6689,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6187,12 +6705,12 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'comment_body_value' => array( - 'type' => 'text', + 'field_text_plain_value' => array( + 'type' => 'varchar', 'not null' => FALSE, - 'size' => 'normal', + 'length' => '255', ), - 'comment_body_format' => array( + 'field_text_plain_format' => array( 'type' => 'varchar', 'not null' => FALSE, 'length' => '255', @@ -6200,41 +6718,38 @@ ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_plain_format' => array( + 'field_text_plain_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_comment_body') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'comment_body_value', - 'comment_body_format', -)) -->values(array( - 'entity_type' => 'comment', - 'bundle' => 'comment_node_test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'comment_body_value' => 'This is a comment', - 'comment_body_format' => 'filtered_html', -)) -->execute(); - -$connection->schema()->createTable('field_revision_field_boolean', array( +$connection->schema()->createTable('field_data_field_text_plain_filtered', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6251,7 +6766,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6262,7 +6777,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6278,47 +6793,51 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_boolean_value' => array( - 'type' => 'int', + 'field_text_plain_filtered_value' => array( + 'type' => 'varchar', 'not null' => FALSE, - 'size' => 'normal', + 'length' => '255', + ), + 'field_text_plain_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', ), ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_plain_filtered_format' => array( + 'field_text_plain_filtered_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_boolean') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_boolean_value', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_boolean_value' => '1', -)) -->execute(); - -$connection->schema()->createTable('field_revision_field_date', array( +$connection->schema()->createTable('field_data_field_text_sum_filtered', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6335,7 +6854,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6346,7 +6865,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6362,47 +6881,56 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_date_value' => array( + 'field_text_sum_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_filtered_summary' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_filtered_format' => array( 'type' => 'varchar', 'not null' => FALSE, - 'length' => '100', + 'length' => '255', ), ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_sum_filtered_format' => array( + 'field_text_sum_filtered_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_date') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_date_value', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_date_value' => '2015-01-20 04:15:00', -)) -->execute(); - -$connection->schema()->createTable('field_revision_field_date_with_end_time', array( +$connection->schema()->createTable('field_data_field_text_sum_plain', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6419,7 +6947,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6430,7 +6958,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6446,54 +6974,56 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_date_with_end_time_value' => array( - 'type' => 'int', + 'field_text_sum_plain_value' => array( + 'type' => 'text', 'not null' => FALSE, - 'size' => 'normal', + 'size' => 'big', ), - 'field_date_with_end_time_value2' => array( - 'type' => 'int', + 'field_text_sum_plain_summary' => array( + 'type' => 'text', 'not null' => FALSE, - 'size' => 'normal', + 'size' => 'big', + ), + 'field_text_sum_plain_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', ), ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_sum_plain_format' => array( + 'field_text_sum_plain_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_date_with_end_time') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_date_with_end_time_value', - 'field_date_with_end_time_value2', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_date_with_end_time_value' => '1421727300', - 'field_date_with_end_time_value2' => '1421727300', -)) -->execute(); - -$connection->schema()->createTable('field_revision_field_email', array( +$connection->schema()->createTable('field_data_field_text_sum_plain_filtered', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6510,7 +7040,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6521,7 +7051,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6537,7 +7067,17 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_email_email' => array( + 'field_text_sum_plain_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_plain_filtered_summary' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_plain_filtered_format' => array( 'type' => 'varchar', 'not null' => FALSE, 'length' => '255', @@ -6545,49 +7085,38 @@ ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_sum_plain_filtered_format' => array( + 'field_text_sum_plain_filtered_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_email') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_email_email', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_email_email' => 'default@example.com', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '1', - 'field_email_email' => 'another@example.com', -)) -->execute(); - -$connection->schema()->createTable('field_revision_field_file', array( +$connection->schema()->createTable('field_data_field_user_entityreference', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6604,7 +7133,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'normal', + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -6615,7 +7144,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6631,37 +7160,47 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_file_fid' => array( - 'type' => 'int', - 'not null' => FALSE, - 'size' => 'normal', - 'unsigned' => TRUE, - ), - 'field_file_display' => array( + 'field_user_entityreference_target_id' => array( 'type' => 'int', 'not null' => TRUE, 'size' => 'normal', - 'default' => '1', 'unsigned' => TRUE, ), - 'field_file_description' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'normal', - ), ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', - 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_user_entityreference_target_id' => array( + 'field_user_entityreference_target_id', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_file') +$connection->insert('field_data_field_user_entityreference') ->fields(array( 'entity_type', 'bundle', @@ -6670,9 +7209,7 @@ 'revision_id', 'language', 'delta', - 'field_file_fid', - 'field_file_display', - 'field_file_description', + 'field_user_entityreference_target_id', )) ->values(array( 'entity_type' => 'node', @@ -6682,25 +7219,11 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_file_fid' => '2', - 'field_file_display' => '1', - 'field_file_description' => 'file desc', -)) -->values(array( - 'entity_type' => 'user', - 'bundle' => 'user', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '0', - 'field_file_fid' => '2', - 'field_file_display' => '1', - 'field_file_description' => 'file desc', + 'field_user_entityreference_target_id' => '2', )) ->execute(); -$connection->schema()->createTable('field_revision_field_float', array( +$connection->schema()->createTable('field_data_taxonomy_forums', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6728,7 +7251,7 @@ ), 'revision_id' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', 'unsigned' => TRUE, ), @@ -6744,25 +7267,24 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_float_value' => array( - 'type' => 'numeric', + 'taxonomy_forums_tid' => array( + 'type' => 'int', 'not null' => FALSE, - 'precision' => '10', - 'scale' => '0', + 'size' => 'normal', + 'unsigned' => TRUE, ), ), 'primary key' => array( 'entity_type', 'deleted', 'entity_id', - 'revision_id', 'language', 'delta', ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_float') +$connection->insert('field_data_taxonomy_forums') ->fields(array( 'entity_type', 'bundle', @@ -6771,21 +7293,31 @@ 'revision_id', 'language', 'delta', - 'field_float_value', + 'taxonomy_forums_tid', )) ->values(array( 'entity_type' => 'node', - 'bundle' => 'test_content_type', + 'bundle' => 'forum', 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', + 'entity_id' => '6', + 'revision_id' => '6', 'language' => 'und', 'delta' => '0', - 'field_float_value' => '1', + 'taxonomy_forums_tid' => '1', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'forum', + 'deleted' => '0', + 'entity_id' => '7', + 'revision_id' => '7', + 'language' => 'und', + 'delta' => '0', + 'taxonomy_forums_tid' => '1', )) ->execute(); -$connection->schema()->createTable('field_revision_field_image', array( +$connection->schema()->createTable('field_revision_body', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6829,33 +7361,20 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_image_fid' => array( - 'type' => 'int', + 'body_value' => array( + 'type' => 'text', 'not null' => FALSE, 'size' => 'normal', - 'unsigned' => TRUE, ), - 'field_image_alt' => array( - 'type' => 'varchar', - 'not null' => FALSE, - 'length' => '512', - ), - 'field_image_title' => array( - 'type' => 'varchar', - 'not null' => FALSE, - 'length' => '1024', - ), - 'field_image_width' => array( - 'type' => 'int', + 'body_summary' => array( + 'type' => 'text', 'not null' => FALSE, 'size' => 'normal', - 'unsigned' => TRUE, ), - 'field_image_height' => array( - 'type' => 'int', + 'body_format' => array( + 'type' => 'varchar', 'not null' => FALSE, - 'size' => 'normal', - 'unsigned' => TRUE, + 'length' => '255', ), ), 'primary key' => array( @@ -6869,7 +7388,70 @@ 'mysql_character_set' => 'utf8', )); -$connection->schema()->createTable('field_revision_field_images', array( +$connection->insert('field_revision_body') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'body_value', + 'body_summary', + 'body_format', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '0', + 'body_value' => "...is that it's the absolute best show ever. Trust me, I would know.", + 'body_summary' => '', + 'body_format' => 'filtered_html', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '0', + 'body_value' => "is - ...is that it's the absolute best show ever. Trust me, I would know.", + 'body_summary' => '', + 'body_format' => 'filtered_html', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '4', + 'revision_id' => '4', + 'language' => 'und', + 'delta' => '0', + 'body_value' => 'is - Is that is it awesome.', + 'body_summary' => '', + 'body_format' => 'filtered_html', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '5', + 'revision_id' => '5', + 'language' => 'und', + 'delta' => '0', + 'body_value' => 'en - Is that is it awesome.', + 'body_summary' => '', + 'body_format' => 'filtered_html', +)) +->execute(); + +$connection->schema()->createTable('field_revision_comment_body', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -6913,33 +7495,15 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_images_fid' => array( - 'type' => 'int', + 'comment_body_value' => array( + 'type' => 'text', 'not null' => FALSE, 'size' => 'normal', - 'unsigned' => TRUE, ), - 'field_images_alt' => array( - 'type' => 'varchar', - 'not null' => FALSE, - 'length' => '512', - ), - 'field_images_title' => array( + 'comment_body_format' => array( 'type' => 'varchar', 'not null' => FALSE, - 'length' => '1024', - ), - 'field_images_width' => array( - 'type' => 'int', - 'not null' => FALSE, - 'size' => 'normal', - 'unsigned' => TRUE, - ), - 'field_images_height' => array( - 'type' => 'int', - 'not null' => FALSE, - 'size' => 'normal', - 'unsigned' => TRUE, + 'length' => '255', ), ), 'primary key' => array( @@ -6953,7 +7517,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_images') +$connection->insert('field_revision_comment_body') ->fields(array( 'entity_type', 'bundle', @@ -6962,29 +7526,23 @@ 'revision_id', 'language', 'delta', - 'field_images_fid', - 'field_images_alt', - 'field_images_title', - 'field_images_width', - 'field_images_height', + 'comment_body_value', + 'comment_body_format', )) ->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', + 'entity_type' => 'comment', + 'bundle' => 'comment_node_test_content_type', 'deleted' => '0', 'entity_id' => '1', 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_images_fid' => '1', - 'field_images_alt' => 'alt text', - 'field_images_title' => 'title text', - 'field_images_width' => '93', - 'field_images_height' => '93', + 'comment_body_value' => 'This is a comment', + 'comment_body_format' => 'filtered_html', )) ->execute(); -$connection->schema()->createTable('field_revision_field_integer', array( +$connection->schema()->createTable('field_revision_field_boolean', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7028,7 +7586,7 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_integer_value' => array( + 'field_boolean_value' => array( 'type' => 'int', 'not null' => FALSE, 'size' => 'normal', @@ -7045,7 +7603,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_integer') +$connection->insert('field_revision_field_boolean') ->fields(array( 'entity_type', 'bundle', @@ -7054,7 +7612,7 @@ 'revision_id', 'language', 'delta', - 'field_integer_value', + 'field_boolean_value', )) ->values(array( 'entity_type' => 'node', @@ -7064,31 +7622,11 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_integer_value' => '5', -)) -->values(array( - 'entity_type' => 'user', - 'bundle' => 'user', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '0', - 'field_integer_value' => '99', -)) -->values(array( - 'entity_type' => 'taxonomy_term', - 'bundle' => 'test_vocabulary', - 'deleted' => '0', - 'entity_id' => '4', - 'revision_id' => '4', - 'language' => 'und', - 'delta' => '0', - 'field_integer_value' => '6', + 'field_boolean_value' => '1', )) ->execute(); -$connection->schema()->createTable('field_revision_field_integer_list', array( +$connection->schema()->createTable('field_revision_field_date', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7132,10 +7670,10 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_integer_list_value' => array( - 'type' => 'int', + 'field_date_value' => array( + 'type' => 'varchar', 'not null' => FALSE, - 'size' => 'normal', + 'length' => '100', ), ), 'primary key' => array( @@ -7149,7 +7687,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_integer_list') +$connection->insert('field_revision_field_date') ->fields(array( 'entity_type', 'bundle', @@ -7158,7 +7696,7 @@ 'revision_id', 'language', 'delta', - 'field_integer_list_value', + 'field_date_value', )) ->values(array( 'entity_type' => 'node', @@ -7168,11 +7706,11 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_integer_list_value' => '7', + 'field_date_value' => '2015-01-20 04:15:00', )) ->execute(); -$connection->schema()->createTable('field_revision_field_link', array( +$connection->schema()->createTable('field_revision_field_date_with_end_time', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7216,18 +7754,13 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_link_url' => array( - 'type' => 'varchar', - 'not null' => FALSE, - 'length' => '2048', - ), - 'field_link_title' => array( - 'type' => 'varchar', + 'field_date_with_end_time_value' => array( + 'type' => 'int', 'not null' => FALSE, - 'length' => '255', + 'size' => 'normal', ), - 'field_link_attributes' => array( - 'type' => 'text', + 'field_date_with_end_time_value2' => array( + 'type' => 'int', 'not null' => FALSE, 'size' => 'normal', ), @@ -7243,7 +7776,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_link') +$connection->insert('field_revision_field_date_with_end_time') ->fields(array( 'entity_type', 'bundle', @@ -7252,9 +7785,8 @@ 'revision_id', 'language', 'delta', - 'field_link_url', - 'field_link_title', - 'field_link_attributes', + 'field_date_with_end_time_value', + 'field_date_with_end_time_value2', )) ->values(array( 'entity_type' => 'node', @@ -7264,37 +7796,12 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_link_url' => 'http://google.com', - 'field_link_title' => 'Click Here', - 'field_link_attributes' => 'a:1:{s:5:"title";s:10:"Click Here";}', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '0', - 'field_link_url' => '', - 'field_link_title' => 'Home', - 'field_link_attributes' => 'a:0:{}', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', - 'language' => 'und', - 'delta' => '0', - 'field_link_url' => '', - 'field_link_title' => 'Home', - 'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}', + 'field_date_with_end_time_value' => '1421727300', + 'field_date_with_end_time_value2' => '1421727300', )) ->execute(); -$connection->schema()->createTable('field_revision_field_long_text', array( +$connection->schema()->createTable('field_revision_field_email', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7338,17 +7845,7 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_long_text_value' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'normal', - ), - 'field_long_text_summary' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'normal', - ), - 'field_long_text_format' => array( + 'field_email_email' => array( 'type' => 'varchar', 'not null' => FALSE, 'length' => '255', @@ -7365,7 +7862,40 @@ 'mysql_character_set' => 'utf8', )); -$connection->schema()->createTable('field_revision_field_node_entityreference', array( +$connection->insert('field_revision_field_email') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_email_email', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_email_email' => 'default@example.com', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '1', + 'field_email_email' => 'another@example.com', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_file', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7382,7 +7912,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'tiny', + 'size' => 'normal', 'default' => '0', ), 'entity_id' => array( @@ -7409,48 +7939,138 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_node_entityreference_target_id' => array( + 'field_file_fid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_file_display' => array( 'type' => 'int', 'not null' => TRUE, 'size' => 'normal', + 'default' => '1', 'unsigned' => TRUE, ), + 'field_file_description' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'normal', + ), ), 'primary key' => array( 'entity_type', + 'deleted', 'entity_id', 'revision_id', - 'deleted', - 'delta', 'language', + 'delta', ), - 'indexes' => array( + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_file') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_file_fid', + 'field_file_display', + 'field_file_description', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_file_fid' => '2', + 'field_file_display' => '1', + 'field_file_description' => 'file desc', +)) +->values(array( + 'entity_type' => 'user', + 'bundle' => 'user', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '0', + 'field_file_fid' => '2', + 'field_file_display' => '1', + 'field_file_description' => 'file desc', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_float', array( + 'fields' => array( 'entity_type' => array( - 'entity_type', + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', ), 'bundle' => array( - 'bundle', + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', ), 'deleted' => array( - 'deleted', + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', ), 'entity_id' => array( - 'entity_id', + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, ), 'revision_id' => array( - 'revision_id', + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, ), 'language' => array( - 'language', + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', ), - 'field_node_entityreference_target_id' => array( - 'field_node_entityreference_target_id', + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_float_value' => array( + 'type' => 'numeric', + 'not null' => FALSE, + 'precision' => '10', + 'scale' => '0', ), ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_node_entityreference') +$connection->insert('field_revision_field_float') ->fields(array( 'entity_type', 'bundle', @@ -7459,7 +8079,7 @@ 'revision_id', 'language', 'delta', - 'field_node_entityreference_target_id', + 'field_float_value', )) ->values(array( 'entity_type' => 'node', @@ -7469,11 +8089,11 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_node_entityreference_target_id' => '2', + 'field_float_value' => '1', )) ->execute(); -$connection->schema()->createTable('field_revision_field_phone', array( +$connection->schema()->createTable('field_revision_field_image', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7517,10 +8137,33 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_phone_value' => array( + 'field_image_fid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_image_alt' => array( 'type' => 'varchar', 'not null' => FALSE, - 'length' => '255', + 'length' => '512', + ), + 'field_image_title' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '1024', + ), + 'field_image_width' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_image_height' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, ), ), 'primary key' => array( @@ -7534,7 +8177,91 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_phone') +$connection->schema()->createTable('field_revision_field_images', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_images_fid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_images_alt' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '512', + ), + 'field_images_title' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '1024', + ), + 'field_images_width' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_images_height' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_images') ->fields(array( 'entity_type', 'bundle', @@ -7543,7 +8270,11 @@ 'revision_id', 'language', 'delta', - 'field_phone_value', + 'field_images_fid', + 'field_images_alt', + 'field_images_title', + 'field_images_width', + 'field_images_height', )) ->values(array( 'entity_type' => 'node', @@ -7553,11 +8284,15 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_phone_value' => '99-99-99-99', + 'field_images_fid' => '1', + 'field_images_alt' => 'alt text', + 'field_images_title' => 'title text', + 'field_images_width' => '93', + 'field_images_height' => '93', )) ->execute(); -$connection->schema()->createTable('field_revision_field_tags', array( +$connection->schema()->createTable('field_revision_field_integer', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7601,11 +8336,10 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_tags_tid' => array( + 'field_integer_value' => array( 'type' => 'int', 'not null' => FALSE, 'size' => 'normal', - 'unsigned' => TRUE, ), ), 'primary key' => array( @@ -7619,7 +8353,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_tags') +$connection->insert('field_revision_field_integer') ->fields(array( 'entity_type', 'bundle', @@ -7628,71 +8362,41 @@ 'revision_id', 'language', 'delta', - 'field_tags_tid', + 'field_integer_value', )) ->values(array( 'entity_type' => 'node', - 'bundle' => 'article', + 'bundle' => 'test_content_type', 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', + 'entity_id' => '1', + 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_tags_tid' => '9', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '2', - 'revision_id' => '2', - 'language' => 'und', - 'delta' => '1', - 'field_tags_tid' => '14', + 'field_integer_value' => '5', )) ->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', + 'entity_type' => 'user', + 'bundle' => 'user', 'deleted' => '0', 'entity_id' => '2', 'revision_id' => '2', 'language' => 'und', - 'delta' => '2', - 'field_tags_tid' => '17', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', - 'language' => 'und', 'delta' => '0', - 'field_tags_tid' => '9', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', - 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', - 'language' => 'und', - 'delta' => '1', - 'field_tags_tid' => '14', + 'field_integer_value' => '99', )) ->values(array( - 'entity_type' => 'node', - 'bundle' => 'article', + 'entity_type' => 'taxonomy_term', + 'bundle' => 'test_vocabulary', 'deleted' => '0', - 'entity_id' => '3', - 'revision_id' => '3', + 'entity_id' => '4', + 'revision_id' => '4', 'language' => 'und', - 'delta' => '2', - 'field_tags_tid' => '17', + 'delta' => '0', + 'field_integer_value' => '6', )) ->execute(); -$connection->schema()->createTable('field_revision_field_term_entityreference', array( +$connection->schema()->createTable('field_revision_field_integer_list', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7709,7 +8413,7 @@ 'deleted' => array( 'type' => 'int', 'not null' => TRUE, - 'size' => 'tiny', + 'size' => 'normal', 'default' => '0', ), 'entity_id' => array( @@ -7736,48 +8440,24 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_term_entityreference_target_id' => array( + 'field_integer_list_value' => array( 'type' => 'int', - 'not null' => TRUE, + 'not null' => FALSE, 'size' => 'normal', - 'unsigned' => TRUE, ), ), 'primary key' => array( 'entity_type', + 'deleted', 'entity_id', 'revision_id', - 'deleted', - 'delta', 'language', - ), - 'indexes' => array( - 'entity_type' => array( - 'entity_type', - ), - 'bundle' => array( - 'bundle', - ), - 'deleted' => array( - 'deleted', - ), - 'entity_id' => array( - 'entity_id', - ), - 'revision_id' => array( - 'revision_id', - ), - 'language' => array( - 'language', - ), - 'field_term_entityreference_target_id' => array( - 'field_term_entityreference_target_id', - ), + 'delta', ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_term_entityreference') +$connection->insert('field_revision_field_integer_list') ->fields(array( 'entity_type', 'bundle', @@ -7786,7 +8466,7 @@ 'revision_id', 'language', 'delta', - 'field_term_entityreference_target_id', + 'field_integer_list_value', )) ->values(array( 'entity_type' => 'node', @@ -7796,21 +8476,11 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_term_entityreference_target_id' => '17', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '1', - 'field_term_entityreference_target_id' => '15', + 'field_integer_list_value' => '7', )) ->execute(); -$connection->schema()->createTable('field_revision_field_term_reference', array( +$connection->schema()->createTable('field_revision_field_link', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7854,11 +8524,20 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_term_reference_tid' => array( - 'type' => 'int', + 'field_link_url' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '2048', + ), + 'field_link_title' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'field_link_attributes' => array( + 'type' => 'text', 'not null' => FALSE, 'size' => 'normal', - 'unsigned' => TRUE, ), ), 'primary key' => array( @@ -7872,7 +8551,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_term_reference') +$connection->insert('field_revision_field_link') ->fields(array( 'entity_type', 'bundle', @@ -7881,7 +8560,9 @@ 'revision_id', 'language', 'delta', - 'field_term_reference_tid', + 'field_link_url', + 'field_link_title', + 'field_link_attributes', )) ->values(array( 'entity_type' => 'node', @@ -7891,21 +8572,37 @@ 'revision_id' => '1', 'language' => 'und', 'delta' => '0', - 'field_term_reference_tid' => '4', + 'field_link_url' => 'http://google.com', + 'field_link_title' => 'Click Here', + 'field_link_attributes' => 'a:1:{s:5:"title";s:10:"Click Here";}', )) ->values(array( - 'entity_type' => 'taxonomy_term', - 'bundle' => 'test_vocabulary', + 'entity_type' => 'node', + 'bundle' => 'article', 'deleted' => '0', 'entity_id' => '2', 'revision_id' => '2', 'language' => 'und', 'delta' => '0', - 'field_term_reference_tid' => '3', + 'field_link_url' => '', + 'field_link_title' => 'Home', + 'field_link_attributes' => 'a:0:{}', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '0', + 'field_link_url' => '', + 'field_link_title' => 'Home', + 'field_link_attributes' => 'a:1:{s:5:"title";s:0:"";}', )) ->execute(); -$connection->schema()->createTable('field_revision_field_text', array( +$connection->schema()->createTable('field_revision_field_long_text', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -7949,12 +8646,17 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_text_value' => array( - 'type' => 'varchar', + 'field_long_text_value' => array( + 'type' => 'text', 'not null' => FALSE, - 'length' => '256', + 'size' => 'normal', ), - 'field_text_format' => array( + 'field_long_text_summary' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'normal', + ), + 'field_long_text_format' => array( 'type' => 'varchar', 'not null' => FALSE, 'length' => '255', @@ -7971,32 +8673,7 @@ 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_text') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_text_value', - 'field_text_format', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_text_value' => 'qwerty', - 'field_text_format' => NULL, -)) -->execute(); - -$connection->schema()->createTable('field_revision_field_text_list', array( +$connection->schema()->createTable('field_revision_field_node_entityreference', array( 'fields' => array( 'entity_type' => array( 'type' => 'varchar', @@ -8011,9 +8688,1580 @@ 'default' => '', ), 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( 'type' => 'int', 'not null' => TRUE, 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_node_entityreference_target_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_node_entityreference_target_id' => array( + 'field_node_entityreference_target_id', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_node_entityreference') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_node_entityreference_target_id', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_node_entityreference_target_id' => '2', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_phone', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_phone_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_phone') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_phone_value', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_phone_value' => '99-99-99-99', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '6', + 'language' => 'und', + 'delta' => '0', + 'field_phone_value' => '99-99-99-99', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_private_file', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_private_file_fid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_private_file_display' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '1', + 'unsigned' => TRUE, + ), + 'field_private_file_description' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'normal', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_private_file_fid' => array( + 'field_private_file_fid', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_private_file') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_private_file_fid', + 'field_private_file_display', + 'field_private_file_description', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '6', + 'language' => 'und', + 'delta' => '0', + 'field_private_file_fid' => '4', + 'field_private_file_display' => '1', + 'field_private_file_description' => '', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_tags', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_tags_tid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_tags') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_tags_tid', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '0', + 'field_tags_tid' => '9', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '0', + 'field_tags_tid' => '9', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '1', + 'field_tags_tid' => '14', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '1', + 'field_tags_tid' => '14', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '2', + 'field_tags_tid' => '17', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'article', + 'deleted' => '0', + 'entity_id' => '3', + 'revision_id' => '3', + 'language' => 'und', + 'delta' => '2', + 'field_tags_tid' => '17', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_term_entityreference', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_term_entityreference_target_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_term_entityreference_target_id' => array( + 'field_term_entityreference_target_id', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_term_entityreference') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_term_entityreference_target_id', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_term_entityreference_target_id' => '17', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '1', + 'field_term_entityreference_target_id' => '15', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_term_reference', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_term_reference_tid' => array( + 'type' => 'int', + 'not null' => FALSE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_term_reference') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_term_reference_tid', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_term_reference_tid' => '4', +)) +->values(array( + 'entity_type' => 'taxonomy_term', + 'bundle' => 'test_vocabulary', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'und', + 'delta' => '0', + 'field_term_reference_tid' => '3', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_text', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '256', + ), + 'field_text_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_text') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_text_value', + 'field_text_format', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_text_value' => 'qwerty', + 'field_text_format' => NULL, +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_text_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_filtered_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'field_text_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_filtered_format' => array( + 'field_text_filtered_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_list', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_list_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->insert('field_revision_field_text_list') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'field_text_list_value', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'test_content_type', + 'deleted' => '0', + 'entity_id' => '1', + 'revision_id' => '1', + 'language' => 'und', + 'delta' => '0', + 'field_text_list_value' => 'Some more text', +)) +->execute(); + +$connection->schema()->createTable('field_revision_field_text_long_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_long_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_long_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_long_filtered_format' => array( + 'field_text_long_filtered_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_long_plain', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_long_plain_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_long_plain_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_long_plain_format' => array( + 'field_text_long_plain_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_long_plain_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_long_plain_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_long_plain_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_long_plain_filtered_format' => array( + 'field_text_long_plain_filtered_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_plain', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_plain_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'field_text_plain_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_plain_format' => array( + 'field_text_plain_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_plain_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_plain_filtered_value' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + 'field_text_plain_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_plain_filtered_format' => array( + 'field_text_plain_filtered_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_sum_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_sum_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_filtered_summary' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_filtered_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_sum_filtered_format' => array( + 'field_text_sum_filtered_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_sum_plain', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', + 'default' => '0', + ), + 'entity_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'revision_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'language' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '32', + 'default' => '', + ), + 'delta' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'normal', + 'unsigned' => TRUE, + ), + 'field_text_sum_plain_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_plain_summary' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_plain_format' => array( + 'type' => 'varchar', + 'not null' => FALSE, + 'length' => '255', + ), + ), + 'primary key' => array( + 'entity_type', + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_sum_plain_format' => array( + 'field_text_sum_plain_format', + ), + ), + 'mysql_character_set' => 'utf8', +)); + +$connection->schema()->createTable('field_revision_field_text_sum_plain_filtered', array( + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'bundle' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'length' => '128', + 'default' => '', + ), + 'deleted' => array( + 'type' => 'int', + 'not null' => TRUE, + 'size' => 'tiny', 'default' => '0', ), 'entity_id' => array( @@ -8040,7 +10288,17 @@ 'size' => 'normal', 'unsigned' => TRUE, ), - 'field_text_list_value' => array( + 'field_text_sum_plain_filtered_value' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_plain_filtered_summary' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'field_text_sum_plain_filtered_format' => array( 'type' => 'varchar', 'not null' => FALSE, 'length' => '255', @@ -8048,38 +10306,38 @@ ), 'primary key' => array( 'entity_type', - 'deleted', 'entity_id', 'revision_id', - 'language', + 'deleted', 'delta', + 'language', + ), + 'indexes' => array( + 'entity_type' => array( + 'entity_type', + ), + 'bundle' => array( + 'bundle', + ), + 'deleted' => array( + 'deleted', + ), + 'entity_id' => array( + 'entity_id', + ), + 'revision_id' => array( + 'revision_id', + ), + 'language' => array( + 'language', + ), + 'field_text_sum_plain_filtered_format' => array( + 'field_text_sum_plain_filtered_format', + ), ), 'mysql_character_set' => 'utf8', )); -$connection->insert('field_revision_field_text_list') -->fields(array( - 'entity_type', - 'bundle', - 'deleted', - 'entity_id', - 'revision_id', - 'language', - 'delta', - 'field_text_list_value', -)) -->values(array( - 'entity_type' => 'node', - 'bundle' => 'test_content_type', - 'deleted' => '0', - 'entity_id' => '1', - 'revision_id' => '1', - 'language' => 'und', - 'delta' => '0', - 'field_text_list_value' => 'Some more text', -)) -->execute(); - $connection->schema()->createTable('field_revision_field_user_entityreference', array( 'fields' => array( 'entity_type' => array( @@ -8250,6 +10508,39 @@ 'mysql_character_set' => 'utf8', )); +$connection->insert('field_revision_taxonomy_forums') +->fields(array( + 'entity_type', + 'bundle', + 'deleted', + 'entity_id', + 'revision_id', + 'language', + 'delta', + 'taxonomy_forums_tid', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'forum', + 'deleted' => '0', + 'entity_id' => '6', + 'revision_id' => '6', + 'language' => 'und', + 'delta' => '0', + 'taxonomy_forums_tid' => '1', +)) +->values(array( + 'entity_type' => 'node', + 'bundle' => 'forum', + 'deleted' => '0', + 'entity_id' => '7', + 'revision_id' => '7', + 'language' => 'und', + 'delta' => '0', + 'taxonomy_forums_tid' => '1', +)) +->execute(); + $connection->schema()->createTable('file_managed', array( 'fields' => array( 'fid' => array( @@ -8341,6 +10632,16 @@ 'status' => '1', 'timestamp' => '1421727516', )) +->values(array( + 'fid' => '3', + 'uid' => '1', + 'filename' => 'Babylon5.txt', + 'uri' => 'private://Babylon5.txt', + 'filemime' => 'text/plain', + 'filesize' => '4', + 'status' => '1', + 'timestamp' => '1486104045', +)) ->execute(); $connection->schema()->createTable('file_usage', array( @@ -8400,14 +10701,14 @@ 'module' => 'file', 'type' => 'node', 'id' => '1', - 'count' => '2', + 'count' => '3', )) ->values(array( 'fid' => '2', 'module' => 'file', 'type' => 'node', 'id' => '1', - 'count' => '1', + 'count' => '2', )) ->values(array( 'fid' => '2', @@ -8416,6 +10717,13 @@ 'id' => '2', 'count' => '1', )) +->values(array( + 'fid' => '3', + 'module' => 'file', + 'type' => 'node', + 'id' => '1', + 'count' => '1', +)) ->execute(); $connection->schema()->createTable('filter', array( @@ -8833,6 +11141,24 @@ 'mysql_character_set' => 'utf8', )); +$connection->insert('forum') +->fields(array( + 'nid', + 'vid', + 'tid', +)) +->values(array( + 'nid' => '6', + 'vid' => '6', + 'tid' => '1', +)) +->values(array( + 'nid' => '7', + 'vid' => '7', + 'tid' => '1', +)) +->execute(); + $connection->schema()->createTable('forum_index', array( 'fields' => array( 'nid' => array( @@ -8885,6 +11211,36 @@ 'mysql_character_set' => 'utf8', )); +$connection->insert('forum_index') +->fields(array( + 'nid', + 'title', + 'tid', + 'sticky', + 'created', + 'last_comment_timestamp', + 'comment_count', +)) +->values(array( + 'nid' => '6', + 'title' => 'Comments are closed :-(', + 'tid' => '1', + 'sticky' => '0', + 'created' => '1504715414', + 'last_comment_timestamp' => '1504715414', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '7', + 'title' => 'Comments are open :-)', + 'tid' => '1', + 'sticky' => '0', + 'created' => '1504715432', + 'last_comment_timestamp' => '1504715432', + 'comment_count' => '0', +)) +->execute(); + $connection->schema()->createTable('history', array( 'fields' => array( 'uid' => array( @@ -20165,8 +22521,8 @@ 'menu_name' => 'management', 'mlid' => '478', 'plid' => '20', - 'link_path' => 'admin/content/book', - 'router_path' => 'admin/content/book', + 'link_path' => 'admin/content', + 'router_path' => 'admin/content', 'link_title' => 'custom link test', 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:0:"";}}', 'module' => 'menu', @@ -20192,10 +22548,10 @@ 'menu_name' => 'navigation', 'mlid' => '479', 'plid' => '0', - 'link_path' => 'node/3', - 'router_path' => 'node/3', + 'link_path' => 'node/2', + 'router_path' => 'node/2', 'link_title' => 'node link test', - 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:6:"node 3";}}', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:6:"node 2";}}', 'module' => 'menu', 'hidden' => '0', 'external' => '0', @@ -30945,6 +33301,70 @@ 'tnid' => '2', 'translate' => '0', )) +->values(array( + 'nid' => '4', + 'vid' => '4', + 'type' => 'article', + 'language' => 'is', + 'title' => 'is - The thing about Firefly', + 'uid' => '1', + 'status' => '1', + 'created' => '1478755274', + 'changed' => '1478755274', + 'comment' => '1', + 'promote' => '1', + 'sticky' => '0', + 'tnid' => '4', + 'translate' => '0', +)) +->values(array( + 'nid' => '5', + 'vid' => '5', + 'type' => 'article', + 'language' => 'en', + 'title' => 'en - The thing about Firefly', + 'uid' => '1', + 'status' => '1', + 'created' => '1478755314', + 'changed' => '1478755314', + 'comment' => '1', + 'promote' => '1', + 'sticky' => '0', + 'tnid' => '4', + 'translate' => '0', +)) +->values(array( + 'nid' => '6', + 'vid' => '6', + 'type' => 'forum', + 'language' => 'en', + 'title' => 'Comments are closed :-(', + 'uid' => '1', + 'status' => '1', + 'created' => '1504715414', + 'changed' => '1504715414', + 'comment' => '1', + 'promote' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) +->values(array( + 'nid' => '7', + 'vid' => '7', + 'type' => 'forum', + 'language' => 'en', + 'title' => 'Comments are open :-)', + 'uid' => '1', + 'status' => '1', + 'created' => '1504715432', + 'changed' => '1504715432', + 'comment' => '2', + 'promote' => '0', + 'sticky' => '0', + 'tnid' => '0', + 'translate' => '0', +)) ->execute(); $connection->schema()->createTable('node_access', array( @@ -31089,6 +33509,38 @@ 'last_comment_uid' => '1', 'comment_count' => '0', )) +->values(array( + 'nid' => '4', + 'cid' => '0', + 'last_comment_timestamp' => '1478755274', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '5', + 'cid' => '0', + 'last_comment_timestamp' => '1478755314', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '6', + 'cid' => '0', + 'last_comment_timestamp' => '1504715414', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) +->values(array( + 'nid' => '7', + 'cid' => '0', + 'last_comment_timestamp' => '1504715432', + 'last_comment_name' => NULL, + 'last_comment_uid' => '1', + 'comment_count' => '0', +)) ->execute(); $connection->schema()->createTable('node_counter', array( @@ -31143,15 +33595,39 @@ ->values(array( 'nid' => '2', 'totalcount' => '1', - 'daycount' => '1', + 'daycount' => '0', 'timestamp' => '1471428059', )) ->values(array( 'nid' => '3', 'totalcount' => '1', - 'daycount' => '1', + 'daycount' => '0', 'timestamp' => '1471428153', )) +->values(array( + 'nid' => '4', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1478755275', +)) +->values(array( + 'nid' => '5', + 'totalcount' => '1', + 'daycount' => '1', + 'timestamp' => '1478755314', +)) +->values(array( + 'nid' => '6', + 'totalcount' => '2', + 'daycount' => '2', + 'timestamp' => '1504715439', +)) +->values(array( + 'nid' => '7', + 'totalcount' => '2', + 'daycount' => '2', + 'timestamp' => '1504715438', +)) ->execute(); $connection->schema()->createTable('node_revision', array( @@ -31272,6 +33748,54 @@ 'promote' => '1', 'sticky' => '0', )) +->values(array( + 'nid' => '4', + 'vid' => '4', + 'uid' => '1', + 'title' => 'is - The thing about Firefly', + 'log' => '', + 'timestamp' => '1478755274', + 'status' => '1', + 'comment' => '1', + 'promote' => '1', + 'sticky' => '0', +)) +->values(array( + 'nid' => '5', + 'vid' => '5', + 'uid' => '1', + 'title' => 'en - The thing about Firefly', + 'log' => '', + 'timestamp' => '1478755314', + 'status' => '1', + 'comment' => '1', + 'promote' => '1', + 'sticky' => '0', +)) +->values(array( + 'nid' => '6', + 'vid' => '6', + 'uid' => '1', + 'title' => 'Comments are closed :-(', + 'log' => '', + 'timestamp' => '1504715414', + 'status' => '1', + 'comment' => '1', + 'promote' => '0', + 'sticky' => '0', +)) +->values(array( + 'nid' => '7', + 'vid' => '7', + 'uid' => '1', + 'title' => 'Comments are open :-)', + 'log' => '', + 'timestamp' => '1504715432', + 'status' => '1', + 'comment' => '2', + 'promote' => '0', + 'sticky' => '0', +)) ->execute(); $connection->schema()->createTable('node_type', array( @@ -42453,6 +44977,18 @@ 'sticky' => '0', 'created' => '1421727515', )) +->values(array( + 'nid' => '6', + 'tid' => '1', + 'sticky' => '0', + 'created' => '1504715414', +)) +->values(array( + 'nid' => '7', + 'tid' => '1', + 'sticky' => '0', + 'created' => '1504715432', +)) ->execute(); $connection->schema()->createTable('taxonomy_term_data', array( @@ -42829,8 +45365,8 @@ )) ->values(array( 'vid' => '2', - 'name' => 'Forums', - 'machine_name' => 'forums', + 'name' => 'Sujet de discussion', + 'machine_name' => 'sujet_de_discussion', 'description' => 'Forum navigation vocabulary', 'hierarchy' => '1', 'module' => 'forum', @@ -42845,6 +45381,15 @@ 'module' => 'taxonomy', 'weight' => '0', )) +->values(array( + 'vid' => '4', + 'name' => 'vocabulary name clearly different than machine name and much longer than thirty two characters', + 'machine_name' => 'vocabulary_name_much_longer_than_thirty_two_characters', + 'description' => 'description of vocabulary name much longer than thirty two characters', + 'hierarchy' => '1', + 'module' => 'taxonomy', + 'weight' => '0', +)) ->execute(); $connection->schema()->createTable('tracker_node', array( @@ -43027,6 +45572,30 @@ 'alias' => 'term33', 'language' => 'und', )) +->values(array( + 'pid' => '2', + 'source' => 'node/2', + 'alias' => 'deep-space-9', + 'language' => 'en', +)) +->values(array( + 'pid' => '3', + 'source' => 'node/3', + 'alias' => 'deep-space-9-is', + 'language' => 'is', +)) +->values(array( + 'pid' => '4', + 'source' => 'node/4', + 'alias' => 'firefly-is', + 'language' => 'is', +)) +->values(array( + 'pid' => '5', + 'source' => 'node/5', + 'alias' => 'firefly', + 'language' => 'en', +)) ->execute(); $connection->schema()->createTable('users', array( @@ -43577,7 +46146,7 @@ )) ->values(array( 'name' => 'comment_subject_field_test_content_type', - 'value' => 'i:1;', + 'value' => 'i:0;', )) ->values(array( 'name' => 'comment_test_content_type', @@ -43721,7 +46290,7 @@ )) ->values(array( 'name' => 'file_private_path', - 'value' => 's:0:"";', + 'value' => 's:21:"sites/default/private";', )) ->values(array( 'name' => 'file_public_path', @@ -44187,6 +46756,14 @@ 'name' => 'theme_settings', 'value' => 'a:16:{s:11:"toggle_logo";i:0;s:11:"toggle_name";i:1;s:13:"toggle_slogan";i:0;s:24:"toggle_node_user_picture";i:0;s:27:"toggle_comment_user_picture";i:0;s:32:"toggle_comment_user_verification";i:0;s:14:"toggle_favicon";i:0;s:16:"toggle_main_menu";i:0;s:21:"toggle_secondary_menu";i:0;s:12:"default_logo";i:1;s:9:"logo_path";s:23:"public://customlogo.png";s:11:"logo_upload";s:0:"";s:15:"default_favicon";i:0;s:12:"favicon_path";s:24:"public://somefavicon.png";s:14:"favicon_upload";s:0:"";s:16:"favicon_mimetype";s:9:"image/png";}', )) +->values(array( + 'name' => 'theme_bartik_settings', + 'value' => 'a:18:{s:11:"toggle_logo";i:1;s:11:"toggle_name";i:1;s:13:"toggle_slogan";i:1;s:24:"toggle_node_user_picture";i:1;s:27:"toggle_comment_user_picture";i:1;s:32:"toggle_comment_user_verification";i:1;s:14:"toggle_favicon";i:1;s:16:"toggle_main_menu";i:1;s:21:"toggle_secondary_menu";i:1;s:12:"default_logo";i:0;s:9:"logo_path";s:16:"public://gnu.png";s:15:"default_favicon";i:1;s:12:"favicon_path";s:0:"";s:14:"favicon_upload";s:0:"";s:6:"scheme";s:7:"default";s:7:"palette";a:9:{s:3:"top";s:7:"#0779bf";s:6:"bottom";s:7:"#48a9e4";s:2:"bg";s:7:"#ffffff";s:7:"sidebar";s:7:"#f6f6f2";s:14:"sidebarborders";s:7:"#f9f9f9";s:6:"footer";s:7:"#292929";s:11:"titleslogan";s:7:"#fffeff";s:4:"text";s:7:"#3b3b3b";s:4:"link";s:7:"#0071B3";}s:5:"theme";s:6:"bartik";s:4:"info";a:12:{s:6:"fields";a:9:{s:3:"top";s:10:"Header top";s:6:"bottom";s:13:"Header bottom";s:2:"bg";s:15:"Main background";s:7:"sidebar";s:18:"Sidebar background";s:14:"sidebarborders";s:15:"Sidebar borders";s:6:"footer";s:17:"Footer background";s:11:"titleslogan";s:16:"Title and slogan";s:4:"text";s:10:"Text color";s:4:"link";s:10:"Link color";}s:7:"schemes";a:6:{s:7:"default";a:2:{s:5:"title";s:21:"Blue Lagoon (default)";s:6:"colors";a:9:{s:3:"top";s:7:"#0779bf";s:6:"bottom";s:7:"#48a9e4";s:2:"bg";s:7:"#ffffff";s:7:"sidebar";s:7:"#f6f6f2";s:14:"sidebarborders";s:7:"#f9f9f9";s:6:"footer";s:7:"#292929";s:11:"titleslogan";s:7:"#fffeff";s:4:"text";s:7:"#3b3b3b";s:4:"link";s:7:"#0071B3";}}s:9:"firehouse";a:2:{s:5:"title";s:9:"Firehouse";s:6:"colors";a:9:{s:3:"top";s:7:"#cd2d2d";s:6:"bottom";s:7:"#cf3535";s:2:"bg";s:7:"#ffffff";s:7:"sidebar";s:7:"#f1f4f0";s:14:"sidebarborders";s:7:"#ededed";s:6:"footer";s:7:"#1f1d1c";s:11:"titleslogan";s:7:"#fffeff";s:4:"text";s:7:"#3b3b3b";s:4:"link";s:7:"#d6121f";}}s:3:"ice";a:2:{s:5:"title";s:3:"Ice";s:6:"colors";a:9:{s:3:"top";s:7:"#d0d0d0";s:6:"bottom";s:7:"#c2c4c5";s:2:"bg";s:7:"#ffffff";s:7:"sidebar";s:7:"#ffffff";s:14:"sidebarborders";s:7:"#cccccc";s:6:"footer";s:7:"#24272c";s:11:"titleslogan";s:7:"#000000";s:4:"text";s:7:"#4a4a4a";s:4:"link";s:7:"#019dbf";}}s:4:"plum";a:2:{s:5:"title";s:4:"Plum";s:6:"colors";a:9:{s:3:"top";s:7:"#4c1c58";s:6:"bottom";s:7:"#593662";s:2:"bg";s:7:"#fffdf7";s:7:"sidebar";s:7:"#edede7";s:14:"sidebarborders";s:7:"#e7e7e7";s:6:"footer";s:7:"#2c2c28";s:11:"titleslogan";s:7:"#ffffff";s:4:"text";s:7:"#301313";s:4:"link";s:7:"#9d408d";}}s:5:"slate";a:2:{s:5:"title";s:5:"Slate";s:6:"colors";a:9:{s:3:"top";s:7:"#4a4a4a";s:6:"bottom";s:7:"#4e4e4e";s:2:"bg";s:7:"#ffffff";s:7:"sidebar";s:7:"#ffffff";s:14:"sidebarborders";s:7:"#d0d0d0";s:6:"footer";s:7:"#161617";s:11:"titleslogan";s:7:"#ffffff";s:4:"text";s:7:"#3b3b3b";s:4:"link";s:7:"#0073b6";}}s:0:"";a:2:{s:5:"title";s:6:"Custom";s:6:"colors";a:0:{}}}s:3:"css";a:1:{i:0;s:14:"css/colors.css";}s:4:"copy";a:1:{i:0;s:8:"logo.png";}s:9:"gradients";a:1:{i:0;a:3:{s:9:"dimension";a:4:{i:0;i:0;i:1;i:0;i:2;i:0;i:3;i:0;}s:9:"direction";s:8:"vertical";s:6:"colors";a:2:{i:0;s:3:"top";i:1;s:6:"bottom";}}}s:4:"fill";a:0:{}s:6:"slices";a:0:{}s:12:"blend_target";s:7:"#ffffff";s:11:"preview_css";s:17:"color/preview.css";s:10:"preview_js";s:16:"color/preview.js";s:12:"preview_html";s:18:"color/preview.html";s:10:"base_image";s:14:"color/base.png";}}', +)) +->values(array( + 'name' => 'theme_seven_settings', + 'value' => 'a:15:{s:11:"toggle_logo";i:1;s:11:"toggle_name";i:1;s:13:"toggle_slogan";i:1;s:24:"toggle_node_user_picture";i:1;s:27:"toggle_comment_user_picture";i:0;s:32:"toggle_comment_user_verification";i:1;s:14:"toggle_favicon";i:1;s:16:"toggle_main_menu";i:1;s:21:"toggle_secondary_menu";i:0;s:12:"default_logo";i:1;s:9:"logo_path";s:0:"";s:11:"logo_upload";s:0:"";s:15:"default_favicon";i:1;s:12:"favicon_path";s:0:"";s:14:"favicon_upload";s:0:"";}', +)) ->values(array( 'name' => 'tracker_batch_size', 'value' => 'i:999;', diff --git a/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.info.yml b/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.info.yml index 004eedc3..84e6793d 100644 --- a/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.info.yml +++ b/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.module b/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.module new file mode 100644 index 00000000..0cb89be3 --- /dev/null +++ b/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/migrate_cckfield_plugin_manager_test.module @@ -0,0 +1,14 @@ +setProcessOfProperty($field_name, [ + 'class' => static::class, + ]); + } } diff --git a/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/src/Plugin/migrate/cckfield/D6NoCoreVersionSpecified.php b/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/src/Plugin/migrate/cckfield/D6NoCoreVersionSpecified.php index 16967db9..74dfd3bc 100644 --- a/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/src/Plugin/migrate/cckfield/D6NoCoreVersionSpecified.php +++ b/core/modules/migrate_drupal/tests/modules/migrate_cckfield_plugin_manager_test/src/Plugin/migrate/cckfield/D6NoCoreVersionSpecified.php @@ -12,11 +12,6 @@ */ class D6NoCoreVersionSpecified extends CckFieldPluginBase { - /** - * {@inheritdoc} - */ - public function getFieldFormatterMap() {} - /** * {@inheritdoc} */ diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.info.yml b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.info.yml new file mode 100644 index 00000000..e5ddbeb4 --- /dev/null +++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/migrate_field_plugin_manager_test.info.yml @@ -0,0 +1,12 @@ +name: 'Migrate field plugin manager test' +type: module +description: 'Example module demonstrating the field plugin manager in the Migrate API.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6FileField.php b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6FileField.php new file mode 100644 index 00000000..acb9d9cd --- /dev/null +++ b/core/modules/migrate_drupal/tests/modules/migrate_field_plugin_manager_test/src/Plugin/migrate/field/D6FileField.php @@ -0,0 +1,16 @@ +container + ->get('plugin.manager.migration') + ->getDefinition('d6_node:story'); + + $this->assertSame(D6FileField::class, $migration['process']['field_test_filefield']['class']); + } + +} diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateCckFieldPluginManagerTest.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateCckFieldPluginManagerTest.php index 1754cfef..7eb68ba3 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/MigrateCckFieldPluginManagerTest.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateCckFieldPluginManagerTest.php @@ -14,7 +14,7 @@ class MigrateCckFieldPluginManagerTest extends MigrateDrupalTestBase { /** * {@inheritdoc} */ - public static $modules = array('system', 'user', 'field', 'migrate_drupal', 'options', 'file', 'text', 'migrate_cckfield_plugin_manager_test'); + public static $modules = ['system', 'user', 'field', 'migrate_drupal', 'options', 'file', 'text', 'migrate_cckfield_plugin_manager_test']; /** * Tests that the correct MigrateCckField plugins are used. @@ -22,28 +22,20 @@ class MigrateCckFieldPluginManagerTest extends MigrateDrupalTestBase { public function testPluginSelection() { $plugin_manager = \Drupal::service('plugin.manager.migrate.cckfield'); - $plugin_id = $plugin_manager->getPluginIdFromFieldType('filefield', ['core' => 6]); - $this->assertIdentical('Drupal\\file\\Plugin\\migrate\\cckfield\\d6\\FileField', get_class($plugin_manager->createInstance($plugin_id, ['core' => 6]))); + $this->assertSame('d6_file', $plugin_manager->getPluginIdFromFieldType('file', ['core' => 6])); try { // If this test passes, getPluginIdFromFieldType will raise a // PluginNotFoundException and we'll never reach fail(). - $plugin_manager->getPluginIdFromFieldType('filefield', ['core' => 7]); + $plugin_manager->getPluginIdFromFieldType('d6_file', ['core' => 7]); $this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.'); } catch (PluginNotFoundException $e) { - $this->assertIdentical($e->getMessage(), "Plugin ID 'filefield' was not found."); + $this->assertSame($e->getMessage(), "Plugin ID 'd6_file' was not found."); } - $this->assertIdentical('image', $plugin_manager->getPluginIdFromFieldType('image', ['core' => 7])); - $this->assertIdentical('file', $plugin_manager->getPluginIdFromFieldType('file', ['core' => 7])); - $this->assertIdentical('d6_file', $plugin_manager->getPluginIdFromFieldType('file', ['core' => 6])); - - $this->assertIdentical('text', $plugin_manager->getPluginIdFromFieldType('text', ['core' => 6])); - $this->assertIdentical('text', $plugin_manager->getPluginIdFromFieldType('text', ['core' => 7])); - // Test fallback when no core version is specified. - $this->assertIdentical('d6_no_core_version_specified', $plugin_manager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 6])); + $this->assertSame('d6_no_core_version_specified', $plugin_manager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 6])); try { // If this test passes, getPluginIdFromFieldType will raise a @@ -52,7 +44,7 @@ public function testPluginSelection() { $this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.'); } catch (PluginNotFoundException $e) { - $this->assertIdentical($e->getMessage(), "Plugin ID 'd6_no_core_version_specified' was not found."); + $this->assertSame($e->getMessage(), "Plugin ID 'd6_no_core_version_specified' was not found."); } } diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php index 2cf4eb14..063c99cb 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php @@ -15,7 +15,7 @@ abstract class MigrateDrupalTestBase extends MigrateTestBase { * * @var array */ - public static $modules = array('system', 'user', 'field', 'migrate_drupal', 'options', 'file'); + public static $modules = ['system', 'user', 'field', 'migrate_drupal', 'options', 'file']; /** * {@inheritdoc} diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php new file mode 100644 index 00000000..7e36364e --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateFieldPluginManagerTest.php @@ -0,0 +1,57 @@ +container->get('plugin.manager.migrate.field'); + + try { + // If this test passes, getPluginIdFromFieldType will raise a + // PluginNotFoundException and we'll never reach fail(). + $plugin_manager->getPluginIdFromFieldType('filefield', ['core' => 7]); + $this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.'); + } + catch (PluginNotFoundException $e) { + $this->assertIdentical($e->getMessage(), "Plugin ID 'filefield' was not found."); + } + + $this->assertIdentical('link', $plugin_manager->getPluginIdFromFieldType('link', ['core' => 6])); + $this->assertIdentical('link_field', $plugin_manager->getPluginIdFromFieldType('link_field', ['core' => 7])); + $this->assertIdentical('image', $plugin_manager->getPluginIdFromFieldType('image', ['core' => 7])); + $this->assertIdentical('file', $plugin_manager->getPluginIdFromFieldType('file', ['core' => 7])); + $this->assertIdentical('d6_file', $plugin_manager->getPluginIdFromFieldType('file', ['core' => 6])); + $this->assertIdentical('d6_text', $plugin_manager->getPluginIdFromFieldType('text', ['core' => 6])); + $this->assertIdentical('d7_text', $plugin_manager->getPluginIdFromFieldType('text', ['core' => 7])); + + // Test fallback when no core version is specified. + $this->assertIdentical('d6_no_core_version_specified', $plugin_manager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 6])); + + try { + // If this test passes, getPluginIdFromFieldType will raise a + // PluginNotFoundException and we'll never reach fail(). + $plugin_manager->getPluginIdFromFieldType('d6_no_core_version_specified', ['core' => 7]); + $this->fail('Expected Drupal\Component\Plugin\Exception\PluginNotFoundException.'); + } + catch (PluginNotFoundException $e) { + $this->assertIdentical($e->getMessage(), "Plugin ID 'd6_no_core_version_specified' was not found."); + } + } + +} diff --git a/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/VariableMultiRowTest.php b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/VariableMultiRowTest.php new file mode 100644 index 00000000..932af990 --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/VariableMultiRowTest.php @@ -0,0 +1,57 @@ + 'foo', 'value' => 'i:1;'], + ['name' => 'bar', 'value' => 'b:0;'], + ]; + + // The expected results. + $tests[0]['expected_data'] = [ + [ + 'name' => 'foo', + 'value' => 1, + ], + [ + 'name' => 'bar', + 'value' => FALSE, + ], + ]; + + // The expected count. + $tests[0]['expected_count'] = NULL; + + // The source plugin configuration. + $tests[0]['configuration']['variables'] = [ + 'foo', + 'bar', + ]; + + return $tests; + } + +} diff --git a/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/VariableTest.php b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/VariableTest.php new file mode 100644 index 00000000..b68c4b46 --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/VariableTest.php @@ -0,0 +1,54 @@ + 'foo', 'value' => 'i:1;'], + ['name' => 'bar', 'value' => 'b:0;'], + ]; + + // The expected results. + $tests[0]['expected_data'] = [ + [ + 'id' => 'foo', + 'foo' => 1, + 'bar' => FALSE, + ], + ]; + + // The expected count. + $tests[0]['expected_count'] = NULL; + + // The source plugin configuration. + $tests[0]['configuration']['variables'] = [ + 'foo', + 'bar', + ]; + + return $tests; + } + +} diff --git a/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/d6/i18nVariableTest.php b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/d6/i18nVariableTest.php new file mode 100644 index 00000000..8c3e6044 --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Kernel/Plugin/migrate/source/d6/i18nVariableTest.php @@ -0,0 +1,77 @@ + 'site_slogan', + 'language' => 'fr', + 'value' => 's:19:"Migrate est génial";', + ], + [ + 'name' => 'site_name', + 'language' => 'fr', + 'value' => 's:11:"nom de site";', + ], + [ + 'name' => 'site_slogan', + 'language' => 'mi', + 'value' => 's:19:"Ko whakamataku heke";', + ], + [ + 'name' => 'site_name', + 'language' => 'mi', + 'value' => 's:9:"ingoa_pae";', + ], + ]; + + // The expected results. + $tests[0]['expected_data'] = [ + [ + 'language' => 'fr', + 'site_slogan' => 'Migrate est génial', + 'site_name' => 'nom de site', + ], + [ + 'language' => 'mi', + 'site_slogan' => 'Ko whakamataku heke', + 'site_name' => 'ingoa_pae', + ], + ]; + + // The expected count. + $tests[0]['expected_count'] = NULL; + + // The migration configuration. + $tests[0]['configuration']['variables'] = [ + 'site_slogan', + 'site_name', + ]; + + return $tests; + } + +} diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/EntityContentBaseTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/EntityContentBaseTest.php index 5074473c..6be7801b 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/d6/EntityContentBaseTest.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/EntityContentBaseTest.php @@ -44,12 +44,12 @@ protected function setUp() { 'uid' => 2, 'name' => 'Ford Prefect', 'mail' => 'ford.prefect@localhost', - 'signature' => array( - array( + 'signature' => [ + [ 'value' => 'Bring a towel.', 'format' => 'filtered_html', - ), - ), + ], + ], 'init' => 'proto@zo.an', ])->save(); @@ -114,7 +114,7 @@ public function testUntranslatable() { $message = $this->prophesize(MigrateMessageInterface::class); // Match the expected message. Can't use default argument types, because // we need to convert to string from TranslatableMarkup. - $argument = Argument::that(function($msg) { + $argument = Argument::that(function ($msg) { return strpos((string) $msg, "This entity type does not support translation") !== FALSE; }); $message->display($argument, Argument::any()) diff --git a/core/modules/migrate_drupal/tests/src/Kernel/dependencies/MigrateDependenciesTest.php b/core/modules/migrate_drupal/tests/src/Kernel/dependencies/MigrateDependenciesTest.php index 1b5736d9..1a30489d 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/dependencies/MigrateDependenciesTest.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/dependencies/MigrateDependenciesTest.php @@ -22,32 +22,33 @@ class MigrateDependenciesTest extends MigrateDrupal6TestBase { * Tests that the order is correct when loading several migrations. */ public function testMigrateDependenciesOrder() { - $migration_items = array('d6_comment', 'd6_filter_format', 'd6_node:page'); + $migration_items = ['d6_comment', 'd6_filter_format', 'd6_node:page']; $migrations = $this->container->get('plugin.manager.migration')->createInstances($migration_items); - $expected_order = array('d6_filter_format', 'd6_node:page', 'd6_comment'); + $expected_order = ['d6_filter_format', 'd6_node:page', 'd6_comment']; $this->assertIdentical(array_keys($migrations), $expected_order); - $expected_requirements = array( + $expected_requirements = [ // d6_comment depends on d6_node:*, which the deriver expands into every // variant of d6_node. 'd6_node:article', 'd6_node:company', 'd6_node:employee', 'd6_node:event', + 'd6_node:forum', 'd6_node:page', + 'd6_user', + 'd6_node_type', + 'd6_node_settings', + 'd6_filter_format', 'd6_node:sponsor', 'd6_node:story', 'd6_node:test_event', 'd6_node:test_page', 'd6_node:test_planet', 'd6_node:test_story', - 'd6_node_type', - 'd6_node_settings', - 'd6_filter_format', - 'd6_user', 'd6_comment_type', 'd6_comment_entity_display', 'd6_comment_entity_form_display', - ); + ]; // Migration dependencies for comment include dependencies for node // migration as well. $actual_requirements = $migrations['d6_comment']->get('requirements'); @@ -66,7 +67,7 @@ public function testAggregatorMigrateDependencies() { $executable = new MigrateExecutable($migration, $this); $this->startCollectingMessages(); $executable->import(); - $this->assertEqual($this->migrateMessages['error'], array(SafeMarkup::format('Migration @id did not meet the requirements. Missing migrations d6_aggregator_feed. requirements: d6_aggregator_feed.', array('@id' => $migration->id())))); + $this->assertEqual($this->migrateMessages['error'], [SafeMarkup::format('Migration @id did not meet the requirements. Missing migrations d6_aggregator_feed. requirements: d6_aggregator_feed.', ['@id' => $migration->id()])]); $this->collectMessages = FALSE; } diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/DrupalSqlBaseTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/DrupalSqlBaseTest.php index f2254dc4..ebd9334a 100644 --- a/core/modules/migrate_drupal/tests/src/Unit/source/DrupalSqlBaseTest.php +++ b/core/modules/migrate_drupal/tests/src/Unit/source/DrupalSqlBaseTest.php @@ -14,9 +14,9 @@ class DrupalSqlBaseTest extends MigrateTestCase { /** * Define bare minimum migration configuration. */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'DrupalSqlBase', - ); + ]; /** * @var \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase @@ -26,24 +26,24 @@ class DrupalSqlBaseTest extends MigrateTestCase { /** * Minimum database contents needed to test DrupalSqlBase. */ - protected $databaseContents = array( - 'system' => array( - array( + protected $databaseContents = [ + 'system' => [ + [ 'filename' => 'sites/all/modules/module1', 'name' => 'module1', 'type' => 'module', 'status' => 0, 'schema_version' => -1, - ), - ), - ); + ], + ], + ]; /** * @covers ::checkRequirements */ public function testSourceProviderNotActive() { $plugin_definition['requirements_met'] = TRUE; - $plugin_definition['source_provider'] = 'module1'; + $plugin_definition['source_module'] = 'module1'; /** @var \Drupal\Core\State\StateInterface $state */ $state = $this->getMock('Drupal\Core\State\StateInterface'); /** @var \Drupal\Core\Entity\EntityManagerInterface $entity_manager */ @@ -57,7 +57,7 @@ public function testSourceProviderNotActive() { } catch (RequirementsException $e) { // Ensure requirements are set on the exception. - $this->assertEquals(['source_provider' => 'module1'], $e->getRequirements()); + $this->assertEquals(['source_module' => 'module1'], $e->getRequirements()); // Re-throw so PHPUnit can assert the exception. throw $e; } diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/VariableMultiRowSourceWithHighwaterTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/VariableMultiRowSourceWithHighwaterTest.php deleted file mode 100644 index f97b7a71..00000000 --- a/core/modules/migrate_drupal/tests/src/Unit/source/VariableMultiRowSourceWithHighwaterTest.php +++ /dev/null @@ -1,20 +0,0 @@ -migrationConfiguration['highWaterProperty']['field'] = 'test'; - parent::setup(); - } - -} diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/VariableMultiRowTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/VariableMultiRowTest.php deleted file mode 100644 index 1ba95baf..00000000 --- a/core/modules/migrate_drupal/tests/src/Unit/source/VariableMultiRowTest.php +++ /dev/null @@ -1,12 +0,0 @@ - 'test', - 'source' => array( + 'source' => [ 'plugin' => 'd6_variable_multirow', - 'variables' => array( + 'variables' => [ 'foo', 'bar', - ), - ), - ); - - protected $expectedResults = array( - array('name' => 'foo', 'value' => 1), - array('name' => 'bar', 'value' => FALSE), - ); - - protected $databaseContents = array( - 'variable' => array( - array('name' => 'foo', 'value' => 'i:1;'), - array('name' => 'bar', 'value' => 'b:0;'), - ), - ); + ], + ], + ]; + + protected $expectedResults = [ + ['name' => 'foo', 'value' => 1], + ['name' => 'bar', 'value' => FALSE], + ]; + + protected $databaseContents = [ + 'variable' => [ + ['name' => 'foo', 'value' => 'i:1;'], + ['name' => 'bar', 'value' => 'b:0;'], + ], + ]; } diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/VariableTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/VariableTest.php index 18a30333..1b5abc36 100644 --- a/core/modules/migrate_drupal/tests/src/Unit/source/VariableTest.php +++ b/core/modules/migrate_drupal/tests/src/Unit/source/VariableTest.php @@ -13,31 +13,31 @@ class VariableTest extends MigrateSqlSourceTestCase { const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\Variable'; - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'test', - 'highWaterProperty' => array('field' => 'test'), - 'source' => array( + 'highWaterProperty' => ['field' => 'test'], + 'source' => [ 'plugin' => 'd6_variable', - 'variables' => array( + 'variables' => [ 'foo', 'bar', - ), - ), - ); + ], + ], + ]; - protected $expectedResults = array( - array( + protected $expectedResults = [ + [ 'id' => 'foo', 'foo' => 1, 'bar' => FALSE, - ), - ); - - protected $databaseContents = array( - 'variable' => array( - array('name' => 'foo', 'value' => 'i:1;'), - array('name' => 'bar', 'value' => 'b:0;'), - ), - ); + ], + ]; + + protected $databaseContents = [ + 'variable' => [ + ['name' => 'foo', 'value' => 'i:1;'], + ['name' => 'bar', 'value' => 'b:0;'], + ], + ]; } diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php index 845ce786..e8866d6f 100644 --- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php +++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/Drupal6SqlBaseTest.php @@ -19,9 +19,9 @@ class Drupal6SqlBaseTest extends MigrateTestCase { /** * Define bare minimum migration configuration. */ - protected $migrationConfiguration = array( + protected $migrationConfiguration = [ 'id' => 'Drupal6SqlBase', - ); + ]; /** * @var \Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase @@ -31,37 +31,37 @@ class Drupal6SqlBaseTest extends MigrateTestCase { /** * Minimum database contents needed to test Drupal6SqlBase. */ - protected $databaseContents = array( - 'system' => array( - array( + protected $databaseContents = [ + 'system' => [ + [ 'filename' => 'sites/all/modules/module1', 'name' => 'module1', 'type' => 'module', 'status' => 1, 'schema_version' => -1, - ), - array( + ], + [ 'filename' => 'sites/all/modules/module2', 'name' => 'module2', 'type' => 'module', 'status' => 0, 'schema_version' => 7201, - ), - array( + ], + [ 'filename' => 'sites/all/modules/test2', 'name' => 'test2', 'type' => 'theme', 'status' => 1, 'schema_version' => -1, - ), - ), - 'variable' => array( - array( + ], + ], + 'variable' => [ + [ 'name' => 'my_variable', 'value' => 'b:1;', - ), - ), - ); + ], + ], + ]; /** * {@inheritdoc} @@ -72,7 +72,7 @@ protected function setUp() { $state = $this->getMock('Drupal\Core\State\StateInterface'); /** @var \Drupal\Core\Entity\EntityManagerInterface $entity_manager */ $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); - $this->base = new TestDrupal6SqlBase($this->migrationConfiguration, $plugin, array(), $this->getMigration(), $state, $entity_manager); + $this->base = new TestDrupal6SqlBase($this->migrationConfiguration, $plugin, [], $this->getMigration(), $state, $entity_manager); $this->base->setDatabase($this->getDatabase($this->databaseContents)); } @@ -143,18 +143,18 @@ class TestDrupal6SqlBase extends DrupalSqlBase { * {@inheritdoc} */ public function fields() { - return array( + return [ 'filename' => t('The path of the primary file for this item.'), 'name' => t('The name of the item; e.g. node.'), 'type' => t('The type of the item, either module, theme, or theme_engine.'), 'owner' => t("A theme's 'parent'. Can be either a theme or an engine."), 'status' => t('Boolean indicating whether or not this item is enabled.'), 'throttle' => t('Boolean indicating whether this item is disabled when the throttle.module disables throttleable items.'), - 'bootstrap' => t('Boolean indicating whether this module is loaded during Drupal\'s early bootstrapping phase (e.g. even before the page cache is consulted).'), - 'schema_version' => t('The module\'s database schema version number.'), - 'weight' => t('The order in which this module\'s hooks should be invoked.'), - 'info' => t('A serialized array containing information from the module\'s .info file.'), - ); + 'bootstrap' => t("Boolean indicating whether this module is loaded during Drupal's early bootstrapping phase (e.g. even before the page cache is consulted)."), + 'schema_version' => t("The module's database schema version number."), + 'weight' => t("The order in which this module's hooks should be invoked."), + 'info' => t("A serialized array containing information from the module's .info file."), + ]; } /** @@ -163,7 +163,7 @@ public function fields() { public function query() { $query = $this->database ->select('system', 's') - ->fields('s', array('filename', 'name', 'schema_version')); + ->fields('s', ['filename', 'name', 'schema_version']); return $query; } @@ -216,7 +216,7 @@ public function variableGetWrapper($name, $default) { * {@inheritdoc} */ public function getIds() { - return array(); + return []; } } diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/VariableTranslationTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/VariableTranslationTest.php new file mode 100644 index 00000000..15270679 --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/VariableTranslationTest.php @@ -0,0 +1,61 @@ + 'test', + 'highWaterProperty' => ['field' => 'test'], + 'source' => [ + 'plugin' => 'variable_translation', + 'variables' => [ + 'site_slogan', + 'site_name', + ], + ], + ]; + + /** + * Expected results from the source. + */ + protected $expectedResults = [ + [ + 'language' => 'fr', + 'site_slogan' => 'Migrate est génial', + 'site_name' => 'nom de site', + ], + [ + 'language' => 'mi', + 'site_slogan' => 'Ko whakamataku heke', + 'site_name' => 'ingoa_pae', + ] + ]; + + /** + * Database contents for tests. + */ + protected $databaseContents = [ + 'i18n_variable' => [ + ['name' => 'site_slogan', 'language' => 'fr', 'value' => 's:19:"Migrate est génial";'], + ['name' => 'site_name', 'language' => 'fr', 'value' => 's:11:"nom de site";'], + ['name' => 'site_slogan', 'language' => 'mi', 'value' => 's:19:"Ko whakamataku heke";'], + ['name' => 'site_name', 'language' => 'mi', 'value' => 's:9:"ingoa_pae";'], + ], + ]; + +} diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/i18nVariableTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/i18nVariableTest.php index bcfb6c20..d1905b0e 100644 --- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/i18nVariableTest.php +++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/i18nVariableTest.php @@ -8,6 +8,7 @@ * Tests the variable source plugin. * * @group migrate_drupal + * @group legacy */ class i18nVariableTest extends MigrateSqlSourceTestCase { @@ -20,7 +21,7 @@ class i18nVariableTest extends MigrateSqlSourceTestCase { */ protected $migrationConfiguration = [ 'id' => 'test', - 'highWaterProperty' => array('field' => 'test'), + 'highWaterProperty' => ['field' => 'test'], 'source' => [ 'plugin' => 'i18n_variable', 'variables' => [ @@ -51,10 +52,10 @@ class i18nVariableTest extends MigrateSqlSourceTestCase { */ protected $databaseContents = [ 'i18n_variable' => [ - array('name' => 'site_slogan', 'language' => 'fr', 'value' => 's:19:"Migrate est génial";'), - array('name' => 'site_name', 'language' => 'fr', 'value' => 's:11:"nom de site";'), - array('name' => 'site_slogan', 'language' => 'mi', 'value' => 's:19:"Ko whakamataku heke";'), - array('name' => 'site_name', 'language' => 'mi', 'value' => 's:9:"ingoa_pae";'), + ['name' => 'site_slogan', 'language' => 'fr', 'value' => 's:19:"Migrate est génial";'], + ['name' => 'site_name', 'language' => 'fr', 'value' => 's:11:"nom de site";'], + ['name' => 'site_slogan', 'language' => 'mi', 'value' => 's:19:"Ko whakamataku heke";'], + ['name' => 'site_name', 'language' => 'mi', 'value' => 's:9:"ingoa_pae";'], ], ]; diff --git a/core/modules/migrate_drupal_ui/css/components/upgrade-analysis-report-tables.css b/core/modules/migrate_drupal_ui/css/components/upgrade-analysis-report-tables.css new file mode 100644 index 00000000..f15ff6a4 --- /dev/null +++ b/core/modules/migrate_drupal_ui/css/components/upgrade-analysis-report-tables.css @@ -0,0 +1,20 @@ +/** + * @file + * Styles for the upgrade analysis report tables. + */ +.upgrade-analysis-report__status-icon:before { + content: ""; + background-size: 16px; + background-position: left center; + background-repeat: no-repeat; + width: 32px; + height: 14px; + display: inline-block; +} + +.upgrade-analysis-report__status-icon--warning:before { + background-image: url(../../../../misc/icons/e29700/warning.svg); +} +.upgrade-analysis-report__status-icon--checked:before { + background-image: url(../../../../misc/icons/73b355/check.svg); +} diff --git a/core/modules/migrate_drupal_ui/migrate_drupal_ui.info.yml b/core/modules/migrate_drupal_ui/migrate_drupal_ui.info.yml index dd52194e..ddd64ae7 100644 --- a/core/modules/migrate_drupal_ui/migrate_drupal_ui.info.yml +++ b/core/modules/migrate_drupal_ui/migrate_drupal_ui.info.yml @@ -10,8 +10,8 @@ dependencies: - migrate_drupal - dblog -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/migrate_drupal_ui/migrate_drupal_ui.libraries.yml b/core/modules/migrate_drupal_ui/migrate_drupal_ui.libraries.yml new file mode 100644 index 00000000..824ee333 --- /dev/null +++ b/core/modules/migrate_drupal_ui/migrate_drupal_ui.libraries.yml @@ -0,0 +1,5 @@ +base: + version: VERSION + css: + component: + css/components/upgrade-analysis-report-tables.css: {} diff --git a/core/modules/migrate_drupal_ui/migrate_drupal_ui.links.menu.yml b/core/modules/migrate_drupal_ui/migrate_drupal_ui.links.menu.yml new file mode 100644 index 00000000..1cdd5592 --- /dev/null +++ b/core/modules/migrate_drupal_ui/migrate_drupal_ui.links.menu.yml @@ -0,0 +1,12 @@ +migrate_drupal_ui.upgrade: + title: 'Upgrade' + parent: system.admin_config_development + description: 'Upgrade content and configuration from either a Drupal 6 or a Drupal 7 site.' + route_name: migrate_drupal_ui.upgrade + +migrate_drupal_ui.log: + title: 'Upgrade log' + parent: system.admin_reports + description: 'View the upgrade log.' + route_name: migrate_drupal_ui.log + weight: 0 diff --git a/core/modules/migrate_drupal_ui/migrate_drupal_ui.module b/core/modules/migrate_drupal_ui/migrate_drupal_ui.module index b8d97817..5f06cdcc 100644 --- a/core/modules/migrate_drupal_ui/migrate_drupal_ui.module +++ b/core/modules/migrate_drupal_ui/migrate_drupal_ui.module @@ -6,6 +6,7 @@ */ use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Url; /** * Implements hook_help(). @@ -13,7 +14,28 @@ use Drupal\Core\Routing\RouteMatchInterface; function migrate_drupal_ui_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.migrate_drupal_ui': - $output = '

    ' . t('The Migrate Drupal UI module provides a one-click upgrade from an earlier version of Drupal. For details, see the online documentation for the Migrate Drupal UI module in the handbook on upgrading from previous versions.', [':migrate' => 'https://www.drupal.org/upgrade/migrate']) . '

    '; + $output = ''; + $output .= '

    ' . t('About') . '

    '; + $output .= '

    ' . t('The Migrate Drupal UI module provides a simple user interface to perform an upgrade from an earlier version of Drupal. For more information, see the online documentation for the Migrate Drupal UI module.', + [':migrate' => 'https://www.drupal.org/upgrade/migrate']) . '

    '; + $output .= '

    ' . t('Uses') . '

    '; + $output .= '
    '; + $output .= '
    ' . t('Preparing the site') . '
    '; + $output .= '
    ' . t('You need to enable all modules on this site that are enabled on the previous site. For example, if you have used the Book module on the previous site then you must enable the Book module on this site for that data to be available on this site.') . '
    '; + $output .= '
    ' . t('Performing the upgrade') . '
    '; + $output .= '
    ' . t('On the Upgrade page, you are guided through performing the upgrade in several steps.', + [':upgrade' => \Drupal::url('migrate_drupal_ui.upgrade')]) . '
    '; + $output .= '
    1. ' . t('You need to enter the database credentials of the Drupal site that you want to upgrade. You can also include its files directory in the upgrade.') . '
    2. '; + $output .= '
    3. ' . t('The next page then provides an overview of which upgrade paths are available or missing, before you proceed to perform the upgrade.') . '
    4. '; + $output .= '
    5. ' . t('Lastly, a message is displayed about the number of upgrade tasks that were successful or failed.') . '
    '; + $output .= '
    ' . t('Reviewing the upgrade log') . '
    '; + $output .= '
    ' . t('You can review a log of upgrade messages by clicking the link in the message provided after the upgrade or by filtering the messages for the type migrate_drupal_ui on the Recent log messages page.', + [':log' => \Drupal::url('migrate_drupal_ui.log'), ':messages' => \Drupal::url('dblog.overview')]) . '
    '; + $output .= '
    ' . t('Incremental upgrades') . '
    '; + $output .= '
    ' . t('Incremental upgrades are not yet supported through the user interface.') . '
    '; + $output .= '
    ' . t('Rolling back an upgrade') . '
    '; + $output .= '
    ' . t('Rolling back an upgrade is not yet supported through the user interface.') . '
    '; + $output .= '
    '; return $output; } } diff --git a/core/modules/migrate_drupal_ui/migrate_drupal_ui.routing.yml b/core/modules/migrate_drupal_ui/migrate_drupal_ui.routing.yml index 2d99abd7..d02ea98d 100644 --- a/core/modules/migrate_drupal_ui/migrate_drupal_ui.routing.yml +++ b/core/modules/migrate_drupal_ui/migrate_drupal_ui.routing.yml @@ -9,7 +9,7 @@ migrate_drupal_ui.upgrade: _admin_route: TRUE migrate_drupal_ui.log: - path: '/upgrade/log' + path: '/admin/reports/upgrade' defaults: _controller: '\Drupal\migrate_drupal_ui\Controller\MigrateController::showLog' requirements: diff --git a/core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php b/core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php index 8d9fd8f0..12dc5c1c 100644 --- a/core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php +++ b/core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php @@ -104,6 +104,9 @@ public static function run($initial_ids, $config, &$context) { // @todo Find a way to avoid this in https://www.drupal.org/node/2804611. if ($definition['destination']['plugin'] === 'entity:file') { // Make sure we have a single trailing slash. + if ($definition['source']['plugin'] === 'd7_file_private') { + $configuration['source']['constants']['source_base_path'] = rtrim($config['source_private_file_path'], '/') . '/'; + } $configuration['source']['constants']['source_base_path'] = rtrim($config['source_base_path'], '/') . '/'; } diff --git a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php index 90b0b61d..10234099 100644 --- a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php +++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php @@ -20,638 +20,6 @@ class MigrateUpgradeForm extends ConfirmFormBase { use MigrationConfigurationTrait; - /** - * Mapping of known migrations and their source and destination modules. - * - * @todo https://www.drupal.org/node/2569805 Hardcoding this information is - * not robust - the migrations themselves should hold the necessary - * information. - * - * @var array[] - */ - protected $moduleUpgradePaths = [ - 'action_settings' => [ - 'source_module' => 'system', - 'destination_module' => 'action', - ], - 'd6_aggregator_feed' => [ - 'source_module' => 'aggregator', - 'destination_module' => 'aggregator', - ], - 'd6_aggregator_item' => [ - 'source_module' => 'aggregator', - 'destination_module' => 'aggregator', - ], - 'd6_aggregator_settings' => [ - 'source_module' => 'aggregator', - 'destination_module' => 'aggregator', - ], - 'd7_aggregator_feed' => [ - 'source_module' => 'aggregator', - 'destination_module' => 'aggregator', - ], - 'd7_aggregator_item' => [ - 'source_module' => 'aggregator', - 'destination_module' => 'aggregator', - ], - 'd7_aggregator_settings' => [ - 'source_module' => 'aggregator', - 'destination_module' => 'aggregator', - ], - 'd7_blocked_ips' => [ - 'source_module' => 'system', - 'destination_module' => 'ban', - ], - 'd6_block' => [ - 'source_module' => 'block', - 'destination_module' => 'block', - ], - 'd7_block' => [ - 'source_module' => 'block', - 'destination_module' => 'block', - ], - 'block_content_body_field' => [ - 'source_module' => 'block', - 'destination_module' => 'block_content', - ], - 'block_content_type' => [ - 'source_module' => 'block', - 'destination_module' => 'block_content', - ], - 'd6_custom_block' => [ - 'source_module' => 'block', - 'destination_module' => 'block_content', - ], - 'd7_custom_block' => [ - 'source_module' => 'block', - 'destination_module' => 'block_content', - ], - 'd6_book' => [ - 'source_module' => 'book', - 'destination_module' => 'book', - ], - 'd6_book_settings' => [ - 'source_module' => 'book', - 'destination_module' => 'book', - ], - 'd6_comment' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd6_comment_entity_display' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd6_comment_entity_form_display' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd6_comment_entity_form_display_subject' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd6_comment_field' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd6_comment_field_instance' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd6_comment_type' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment_entity_display' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment_entity_form_display' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment_entity_form_display_subject' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment_field' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment_field_instance' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'd7_comment_type' => [ - 'source_module' => 'comment', - 'destination_module' => 'comment', - ], - 'contact_category' => [ - 'source_module' => 'contact', - 'destination_module' => 'contact', - ], - 'd6_contact_settings' => [ - 'source_module' => 'contact', - 'destination_module' => 'contact', - ], - 'd7_contact_settings' => [ - 'source_module' => 'contact', - 'destination_module' => 'contact', - ], - 'd6_dblog_settings' => [ - 'source_module' => 'dblog', - 'destination_module' => 'dblog', - ], - 'd7_dblog_settings' => [ - 'source_module' => 'dblog', - 'destination_module' => 'dblog', - ], - 'default_language' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'd6_field' => [ - 'source_module' => 'content', - 'destination_module' => 'field', - ], - 'd6_field_formatter_settings' => [ - 'source_module' => 'content', - 'destination_module' => 'field', - ], - 'd6_field_instance' => [ - 'source_module' => 'content', - 'destination_module' => 'field', - ], - 'd6_field_instance_widget_settings' => [ - 'source_module' => 'content', - 'destination_module' => 'field', - ], - 'd7_field' => [ - 'source_module' => 'field', - 'destination_module' => 'field', - ], - 'd7_field_formatter_settings' => [ - 'source_module' => 'field', - 'destination_module' => 'field', - ], - 'd7_field_instance' => [ - 'source_module' => 'field', - 'destination_module' => 'field', - ], - 'd7_field_instance_widget_settings' => [ - 'source_module' => 'field', - 'destination_module' => 'field', - ], - 'd7_view_modes' => [ - 'source_module' => 'field', - 'destination_module' => 'field', - ], - 'd6_file' => [ - 'source_module' => 'system', - 'destination_module' => 'file', - ], - 'file_settings' => [ - 'source_module' => 'system', - 'destination_module' => 'file', - ], - 'd6_upload' => [ - 'source_module' => 'upload', - 'destination_module' => 'file', - ], - 'd6_upload_entity_display' => [ - 'source_module' => 'upload', - 'destination_module' => 'file', - ], - 'd6_upload_entity_form_display' => [ - 'source_module' => 'upload', - 'destination_module' => 'file', - ], - 'd6_upload_field' => [ - 'source_module' => 'upload', - 'destination_module' => 'file', - ], - 'd6_upload_field_instance' => [ - 'source_module' => 'upload', - 'destination_module' => 'file', - ], - 'd7_file' => [ - 'source_module' => 'file', - 'destination_module' => 'file', - ], - 'd6_filter_format' => [ - 'source_module' => 'filter', - 'destination_module' => 'filter', - ], - 'd7_filter_format' => [ - 'source_module' => 'filter', - 'destination_module' => 'filter', - ], - 'd7_filter_settings' => [ - 'source_module' => 'filter', - 'destination_module' => 'filter', - ], - 'd6_forum_settings' => [ - 'source_module' => 'forum', - 'destination_module' => 'forum', - ], - 'd7_forum_settings' => [ - 'source_module' => 'forum', - 'destination_module' => 'forum', - ], - 'd7_global_theme_settings' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd6_imagecache_presets' => [ - 'source_module' => 'imagecache', - 'destination_module' => 'image', - ], - 'd7_image_settings' => [ - 'source_module' => 'image', - 'destination_module' => 'image', - ], - 'd7_image_styles' => [ - 'source_module' => 'image', - 'destination_module' => 'image', - ], - 'd6_language_content_settings' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'd7_language_content_settings' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'd6_language_negotiation_settings' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'd7_language_negotiation_settings' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'language_prefixes_and_domains' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'd6_language_types' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'language' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'd7_language_types' => [ - 'source_module' => 'locale', - 'destination_module' => 'language', - ], - 'locale_settings' => [ - 'source_module' => 'locale', - 'destination_module' => 'locale', - ], - 'd6_menu_links' => [ - 'source_module' => 'menu', - 'destination_module' => 'menu_link_content', - ], - 'menu_settings' => [ - 'source_module' => 'menu', - 'destination_module' => 'menu_ui', - ], - 'd7_menu_links' => [ - 'source_module' => 'menu', - 'destination_module' => 'menu_link_content', - ], - 'd6_node' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_node_translation' => [ - 'source_module' => 'translation', - 'destination_module' => 'content_translation', - ], - 'd6_node_revision' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_node_setting_promote' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_node_setting_status' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_node_setting_sticky' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_node_settings' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_node_type' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_view_modes' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd7_node' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd7_node_revision' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd7_node_settings' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd7_node_title_label' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd7_node_type' => [ - 'source_module' => 'node', - 'destination_module' => 'node', - ], - 'd6_url_alias' => [ - 'source_module' => 'path', - 'destination_module' => 'path', - ], - 'd7_url_alias' => [ - 'source_module' => 'path', - 'destination_module' => 'path', - ], - 'search_page' => [ - 'source_module' => 'search', - 'destination_module' => 'search', - ], - 'd6_search_settings' => [ - 'source_module' => 'search', - 'destination_module' => 'search', - ], - 'd7_search_settings' => [ - 'source_module' => 'search', - 'destination_module' => 'search', - ], - 'd7_shortcut' => [ - 'source_module' => 'shortcut', - 'destination_module' => 'shortcut', - ], - 'd7_shortcut_set' => [ - 'source_module' => 'shortcut', - 'destination_module' => 'shortcut', - ], - 'd7_shortcut_set_users' => [ - 'source_module' => 'shortcut', - 'destination_module' => 'shortcut', - ], - 'd6_simpletest_settings' => [ - 'source_module' => 'simpletest', - 'destination_module' => 'simpletest', - ], - 'd7_simpletest_settings' => [ - 'source_module' => 'simpletest', - 'destination_module' => 'simpletest', - ], - 'd6_statistics_settings' => [ - 'source_module' => 'statistics', - 'destination_module' => 'statistics', - ], - 'd6_syslog_settings' => [ - 'source_module' => 'syslog', - 'destination_module' => 'syslog', - ], - 'd7_syslog_settings' => [ - 'source_module' => 'syslog', - 'destination_module' => 'syslog', - ], - 'd6_date_formats' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd6_system_cron' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd6_system_date' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd6_system_file' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'system_image' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'system_image_gd' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'system_logging' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'system_maintenance' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd6_system_performance' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'system_rss' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'system_site' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd7_system_authorize' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd7_system_cron' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd7_system_date' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd7_system_file' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd7_system_mail' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd7_system_performance' => [ - 'source_module' => 'system', - 'destination_module' => 'system', - ], - 'd6_menu' => [ - 'source_module' => 'menu', - 'destination_module' => 'system', - ], - 'd7_menu' => [ - 'source_module' => 'menu', - 'destination_module' => 'system', - ], - 'taxonomy_settings' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_taxonomy_term' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_taxonomy_vocabulary' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_term_node' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_term_node_revision' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_vocabulary_entity_display' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_vocabulary_entity_form_display' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_vocabulary_field' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd6_vocabulary_field_instance' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd7_taxonomy_term' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'd7_taxonomy_vocabulary' => [ - 'source_module' => 'taxonomy', - 'destination_module' => 'taxonomy', - ], - 'text_settings' => [ - 'source_module' => 'text', - 'destination_module' => 'text', - ], - 'd7_tracker_node' => [ - 'source_module' => 'tracker', - 'destination_module' => 'tracker', - ], - 'd7_tracker_settings' => [ - 'source_module' => 'tracker', - 'destination_module' => 'tracker', - ], - 'd7_tracker_user' => [ - 'source_module' => 'tracker', - 'destination_module' => 'tracker', - ], - 'update_settings' => [ - 'source_module' => 'update', - 'destination_module' => 'update', - ], - 'd6_profile_values' => [ - 'source_module' => 'profile', - 'destination_module' => 'user', - ], - 'd6_user' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd6_user_contact_settings' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd6_user_mail' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd6_user_picture_file' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd6_user_role' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd6_user_settings' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd7_user' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd7_user_flood' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd7_user_mail' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'd7_user_role' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'user_picture_entity_display' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'user_picture_entity_form_display' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'user_picture_field' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'user_picture_field_instance' => [ - 'source_module' => 'user', - 'destination_module' => 'user', - ], - 'user_profile_entity_display' => [ - 'source_module' => 'profile', - 'destination_module' => 'user', - ], - 'user_profile_entity_form_display' => [ - 'source_module' => 'profile', - 'destination_module' => 'user', - ], - 'user_profile_field' => [ - 'source_module' => 'profile', - 'destination_module' => 'user', - ], - 'user_profile_field_instance' => [ - 'source_module' => 'profile', - 'destination_module' => 'user', - ], - ]; - /** * The state service. * @@ -774,27 +142,41 @@ public function buildOverviewForm(array $form, FormStateInterface $form_state) { } else { $form['info_header'] = [ - '#markup' => '

    ' . $this->t('Upgrade a site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the online documentation for Drupal site upgrades for more detailed information.', [ + '#markup' => '

    ' . $this->t('Upgrade a site by importing its database and files into a clean and empty new install of Drupal 8. See the Drupal site upgrades handbook for more information.', [ ':url' => 'https://www.drupal.org/upgrade/migrate', ]), ]; - $info[] = $this->t('Back up the database for this site. Upgrade will change the database for this site.'); - $info[] = $this->t('Make sure that the host this site is on has access to the database for your previous site.'); - $info[] = $this->t('If your previous site has private files to be migrated, a copy of your files directory must be accessible on the host this site is on.'); - $info[] = $this->t('In general, enable all modules on this site that are enabled on the previous site. For example, if you have used the book module on the previous site then you must enable the book module on this site for that data to be available on this site.'); + $legend[] = $this->t('Old site: the site you want to upgrade.'); + $legend[] = $this->t('New site: this empty Drupal 8 installation you will import the old site to.'); + + $form['legend'] = [ + '#theme' => 'item_list', + '#title' => $this->t('Definitions'), + '#list_type' => 'ul', + '#items' => $legend, + ]; + + $info[] = $this->t('You may need multiple tries for a successful upgrade so backup the database for this new site. The upgrade will change it and you may want to revert to its initial state.'); + $info[] = $this->t('Make sure that access to the database for the old site is available from this new site.'); + $info[] = $this->t('If the old site has private files, a copy of its files directory must also be accessible on the host of this new site.'); + $info[] = $this->t('Enable all modules on this new site that are enabled on the old site. For example, if the old site uses the book module, then enable the book module on this new site so that the existing data can be imported to it.'); + $info[] = $this->t('Do not add any content to the new site before upgrading. Any existing content is likely to be overwritten by the upgrade process. See the upgrade preparation guide.', [ + ':url' => 'https://www.drupal.org/docs/8/upgrade/preparing-an-upgrade#dont_create_content', + ]); $info[] = $this->t('Put this site into maintenance mode.', [ ':url' => Url::fromRoute('system.site_maintenance_mode')->toString(TRUE)->getGeneratedUrl(), ]); $form['info'] = [ '#theme' => 'item_list', + '#title' => $this->t('Steps to prepare for the upgrade'), '#list_type' => 'ol', '#items' => $info, ]; $form['info_footer'] = [ - '#markup' => '

    ' . $this->t('This upgrade can take a long time. It is better to import a local copy of your site instead of directly importing from your live site.'), + '#markup' => '

    ' . $this->t('The upgrade can take a long time. It is better to upgrade from a local copy of your site instead of directly from your live site.'), ]; $validate = []; @@ -854,6 +236,15 @@ public function buildCredentialForm(array $form, FormStateInterface $form_state) $default_options = []; + + $form['version'] = [ + '#type' => 'radios', + '#default_value' => 7, + '#title' => $this->t('Drupal version of the source site'), + '#options' => [6 => $this->t('Drupal 6'), 7 => $this->t('Drupal 7')], + '#required' => TRUE, + ]; + $form['database'] = [ '#type' => 'details', '#title' => $this->t('Source database'), @@ -907,10 +298,38 @@ public function buildCredentialForm(array $form, FormStateInterface $form_state) '#title' => $this->t('Source files'), '#open' => TRUE, ]; - $form['source']['source_base_path'] = [ + $form['source']['d6_source_base_path'] = [ '#type' => 'textfield', '#title' => $this->t('Files directory'), '#description' => $this->t('To import files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (for example http://example.com).'), + '#states' => [ + 'visible' => [ + ':input[name="version"]' => ['value' => 6], + ], + ], + ]; + + $form['source']['source_base_path'] = [ + '#type' => 'textfield', + '#title' => $this->t('Public files directory'), + '#description' => $this->t('To import public files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (for example http://example.com).'), + '#states' => [ + 'visible' => [ + ':input[name="version"]' => ['value' => 7], + ], + ], + ]; + + $form['source']['source_private_file_path'] = [ + '#type' => 'textfield', + '#title' => $this->t('Private file directory'), + '#default_value' => '', + '#description' => $this->t('To import private files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot).'), + '#states' => [ + 'visible' => [ + ':input[name="version"]' => ['value' => 7], + ], + ], ]; $form['actions'] = ['#type' => 'actions']; @@ -961,6 +380,12 @@ public function validateCredentialForm(array &$form, FormStateInterface $form_st if (!$version) { $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database does not contain a recognizable Drupal version.')); } + elseif ($version != $form_state->getValue('version')) { + $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database is Drupal version @version but version @selected was selected.', [ + '@version' => $version, + '@selected' => $form_state->getValue('version'), + ])); + } else { $this->createDatabaseStateSettings($database, $version); $migrations = $this->getMigrations('migrate_drupal_' . $version, $version); @@ -976,9 +401,15 @@ public function validateCredentialForm(array &$form, FormStateInterface $form_st } // Store the retrieved migration IDs in form storage. + $form_state->set('version', $version); $form_state->set('migrations', $migration_array); - $form_state->set('source_base_path', $form_state->getValue('source_base_path')); - + if ($version == 6) { + $form_state->set('source_base_path', $form_state->getValue('d6_source_base_path')); + } + else { + $form_state->set('source_base_path', $form_state->getValue('source_base_path')); + } + $form_state->set('source_private_file_path', $form_state->getValue('source_private_file_path')); // Store the retrived system data in form storage. $form_state->set('system_data', $system_data); } @@ -1024,19 +455,24 @@ public function buildConfirmForm(array $form, FormStateInterface $form_state) { $form['actions']['submit']['#value'] = $this->t('Perform upgrade'); + $version = $form_state->get('version'); + $migrations = $this->getMigrations('migrate_drupal_' . $version, $version); + $table_data = []; - $system_data = []; - foreach ($form_state->get('migrations') as $migration_id => $migration_label) { - // Fetch the system data at the first opportunity. - if (empty($system_data)) { - $system_data = $form_state->get('system_data'); + foreach ($migrations as $migration) { + $migration_id = $migration->getPluginId(); + $source_module = $migration->getSourcePlugin()->getSourceModule(); + if (!$source_module) { + drupal_set_message($this->t('Source module not found for @migration_id.', ['@migration_id' => $migration_id]), 'error'); + } + $destination_module = $migration->getDestinationPlugin()->getDestinationModule(); + if (!$destination_module) { + drupal_set_message($this->t('Destination module not found for @migration_id.', ['@migration_id' => $migration_id]), 'error'); } - // Handle derivatives. - list($migration_id,) = explode(':', $migration_id, 2); - $source_module = $this->moduleUpgradePaths[$migration_id]['source_module']; - $destination_module = $this->moduleUpgradePaths[$migration_id]['destination_module']; - $table_data[$source_module][$destination_module][$migration_id] = $migration_label; + if ($source_module && $destination_module) { + $table_data[$source_module][$destination_module][$migration_id] = $migration->label(); + } } // Sort the table by source module names and within that destination // module names. @@ -1044,19 +480,29 @@ public function buildConfirmForm(array $form, FormStateInterface $form_state) { foreach ($table_data as $source_module => $destination_module_info) { ksort($table_data[$source_module]); } + + // Fetch the system data at the first opportunity. + $system_data = $form_state->get('system_data'); $unmigrated_source_modules = array_diff_key($system_data['module'], $table_data); // Missing migrations. - $form['missing_module_list_title'] = [ - '#type' => 'item', - '#title' => $this->t('Missing upgrade paths'), - '#description' => $this->t('The following items will not be upgraded. For more information see Upgrading from Drupal 6 or 7 to Drupal 8.', array(':migrate' => 'https://www.drupal.org/upgrade/migrate')), + $missing_module_list = [ + '#type' => 'details', + '#open' => TRUE, + '#title' => [ + '#type' => 'html_tag', + '#tag' => 'span', + '#value' => $this->t('Missing upgrade paths'), + '#attributes' => ['id' => ['warning']], + ], + '#description' => $this->t('The following items will not be upgraded. For more information see Upgrading from Drupal 6 or 7 to Drupal 8.', [':migrate' => 'https://www.drupal.org/upgrade/migrate']), + '#weight' => 2, ]; - $form['missing_module_list'] = [ + $missing_module_list['module_list'] = [ '#type' => 'table', '#header' => [ - $this->t('Source'), - $this->t('Destination'), + $this->t('Source module: Drupal @version', ['@version' => $version]), + $this->t('Upgrade module: Drupal 8'), ], ]; $missing_count = 0; @@ -1064,24 +510,39 @@ public function buildConfirmForm(array $form, FormStateInterface $form_state) { foreach ($unmigrated_source_modules as $source_module => $module_data) { if ($module_data['status']) { $missing_count++; - $form['missing_module_list'][$source_module] = [ - 'source_module' => ['#plain_text' => $source_module], + $missing_module_list['module_list'][$source_module] = [ + 'source_module' => [ + '#type' => 'html_tag', + '#tag' => 'span', + '#value' => $source_module, + '#attributes' => [ + 'class' => [ + 'upgrade-analysis-report__status-icon', + 'upgrade-analysis-report__status-icon--warning', + ], + ], + ], 'destination_module' => ['#plain_text' => 'Missing'], ]; } } // Available migrations. - $form['available_module_list'] = [ - '#tree' => TRUE, + $available_module_list = [ '#type' => 'details', - '#title' => $this->t('Available upgrade paths'), + '#title' => [ + '#type' => 'html_tag', + '#tag' => 'span', + '#value' => $this->t('Available upgrade paths'), + '#attributes' => ['id' => ['checked']], + ], + '#weight' => 3, ]; - $form['available_module_list']['module_list'] = [ + $available_module_list['module_list'] = [ '#type' => 'table', '#header' => [ - $this->t('Source'), - $this->t('Destination'), + $this->t('Source module: Drupal @version', ['@version' => $version]), + $this->t('Upgrade module: Drupal 8'), ], ]; @@ -1095,21 +556,54 @@ public function buildConfirmForm(array $form, FormStateInterface $form_state) { '#plain_text' => $destination_module, ]; } - $form['available_module_list']['module_list'][$source_module] = [ - 'source_module' => ['#plain_text' => $source_module], + $available_module_list['module_list'][$source_module] = [ + 'source_module' => [ + '#type' => 'html_tag', + '#tag' => 'span', + '#value' => $source_module, + '#attributes' => [ + 'class' => [ + 'upgrade-analysis-report__status-icon', + 'upgrade-analysis-report__status-icon--checked', + ], + ], + ], 'destination_module' => $destination_details, ]; } - $form['counts'] = [ - '#title' => 'Upgrade analysis report', - '#theme' => 'item_list', - '#items' => [ - $this->formatPlural($available_count, '@count available upgrade path', '@count available upgrade paths'), - $this->formatPlural($missing_count, '@count missing upgrade path', '@count missing upgrade paths'), - ], - '#weight' => -15, + + $counters = []; + $general_info = []; + + if ($missing_count) { + $counters[] = [ + '#theme' => 'status_report_counter', + '#amount' => $missing_count, + '#text' => $this->formatPlural($missing_count, 'Missing upgrade path', 'Missing upgrade paths'), + '#severity' => 'warning', + '#weight' => 0, + ]; + $general_info[] = $missing_module_list; + } + if ($available_count) { + $counters[] = [ + '#theme' => 'status_report_counter', + '#amount' => $available_count, + '#text' => $this->formatPlural($available_count, 'Available upgrade path', 'Available upgrade paths'), + '#severity' => 'checked', + '#weight' => 1, + ]; + $general_info[] = $available_module_list; + } + + $form['status_report_page'] = [ + '#theme' => 'status_report_page', + '#counters' => $counters, + '#general_info' => $general_info, ]; + $form['#attached']['library'][] = 'migrate_drupal_ui/base'; + return $form; } @@ -1160,7 +654,7 @@ protected function getDatabaseTypes() { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure?'); + return $this->t('Upgrade analysis report'); } /** diff --git a/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php index c139291e..30e6ef23 100644 --- a/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php +++ b/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php @@ -2,6 +2,8 @@ namespace Drupal\migrate_drupal_ui\Tests; +@trigger_error('\Drupal\migrate_drupal_ui\Tests\MigrateUpgradeTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase instead.', E_USER_DEPRECATED); + use Drupal\Core\Database\Database; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate_drupal\MigrationConfigurationTrait; @@ -9,6 +11,9 @@ /** * Provides a base class for testing migration upgrades in the UI. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use + * \Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeTestBase instead. */ abstract class MigrateUpgradeTestBase extends WebTestBase { use MigrationConfigurationTrait; @@ -30,7 +35,17 @@ abstract class MigrateUpgradeTestBase extends WebTestBase { * * @var array */ - public static $modules = ['language', 'content_translation', 'migrate_drupal_ui', 'telephone']; + public static $modules = [ + 'language', + 'content_translation', + 'migrate_drupal_ui', + 'telephone', + 'aggregator', + 'book', + 'forum', + 'statistics', + 'modules_available_test', + ]; /** * {@inheritdoc} @@ -101,10 +116,10 @@ protected function tearDown() { /** * Executes all steps of migrations upgrade. */ - protected function testMigrateUpgrade() { + public function testMigrateUpgrade() { $connection_options = $this->sourceDatabase->getConnectionOptions(); $this->drupalGet('/upgrade'); - $this->assertText('Upgrade a site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the online documentation for Drupal site upgrades for more detailed information.'); + $this->assertText('Upgrade a site by importing its database and files into a clean and empty new install of Drupal 8.'); $this->drupalPostForm(NULL, [], t('Continue')); $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); @@ -134,7 +149,31 @@ protected function testMigrateUpgrade() { $this->drupalPostForm(NULL, $edits, t('Review upgrade')); $this->assertResponse(200); - $this->assertText('Are you sure?'); + $this->assertText('Upgrade analysis report'); + // Ensure we get errors about missing modules. + $this->assertText(t('Source module not found for module_no_annotation.')); + $this->assertText(t('Source module not found for modules_available_test.')); + $this->assertText(t('Destination module not found for modules_available_test')); + + // Uninstall the module causing the missing module error messages. + $this->container->get('module_installer')->uninstall(['modules_available_test'], TRUE); + + // Restart the upgrade process. + $this->drupalGet('/upgrade'); + $this->assertText('Upgrade a site by importing its database and files into a clean and empty new install of Drupal 8.'); + + $this->drupalPostForm(NULL, [], t('Continue')); + $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); + $this->assertFieldByName('mysql[host]'); + + $this->drupalPostForm(NULL, $edits, t('Review upgrade')); + $this->assertResponse(200); + $this->assertText('Upgrade analysis report'); + // Ensure there are no errors about the missing modules. + $this->assertNoText(t('Source module not found for module_no_annotation.')); + $this->assertNoText(t('Source module not found for modules_available_test.')); + $this->assertNoText(t('Destination module not found for modules_available_test')); + // Check for any missing module errors. $this->drupalPostForm(NULL, [], t('Perform upgrade')); $this->assertText(t('Congratulations, you upgraded Drupal!')); @@ -143,8 +182,9 @@ protected function testMigrateUpgrade() { $this->resetAll(); $expected_counts = $this->getEntityCounts(); - foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $entity_type) { - $real_count = count(\Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple()); + foreach (array_keys(\Drupal::entityTypeManager() + ->getDefinitions()) as $entity_type) { + $real_count = \Drupal::entityQuery($entity_type)->count()->execute(); $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0; $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count."); } @@ -162,7 +202,7 @@ protected function testMigrateUpgrade() { $source_id_values = array_values(unserialize($source_id)); $row = $id_map->getRowBySource($source_id_values); $destination = serialize($id_map->currentDestination()); - $message = "Successful migration of $source_id to $destination as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status']; + $message = "Migration of $source_id to $destination as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status']; // A completed migration should have maps with // MigrateIdMapInterface::STATUS_IGNORED or // MigrateIdMapInterface::STATUS_IMPORTED. @@ -175,6 +215,7 @@ protected function testMigrateUpgrade() { } } \Drupal::service('module_installer')->install(['forum']); + \Drupal::service('module_installer')->install(['book']); } /** diff --git a/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php deleted file mode 100644 index 50829f02..00000000 --- a/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php +++ /dev/null @@ -1,88 +0,0 @@ -loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php'); - } - - /** - * {@inheritdoc} - */ - protected function getSourceBasePath() { - return __DIR__ . '/files'; - } - - /** - * {@inheritdoc} - */ - protected function getEntityCounts() { - return [ - 'block' => 30, - 'block_content' => 2, - 'block_content_type' => 1, - 'comment' => 3, - 'comment_type' => 2, - 'contact_form' => 5, - 'configurable_language' => 5, - 'editor' => 2, - 'field_config' => 63, - 'field_storage_config' => 43, - 'file' => 7, - 'filter_format' => 7, - 'image_style' => 5, - 'language_content_settings' => 2, - 'migration' => 105, - 'node' => 11, - 'node_type' => 11, - 'rdf_mapping' => 5, - 'search_page' => 2, - 'shortcut' => 2, - 'shortcut_set' => 1, - 'action' => 22, - 'menu' => 8, - 'taxonomy_term' => 6, - 'taxonomy_vocabulary' => 5, - 'tour' => 4, - 'user' => 7, - 'user_role' => 6, - 'menu_link_content' => 4, - 'view' => 12, - 'date_format' => 11, - 'entity_form_display' => 15, - 'entity_form_mode' => 1, - 'entity_view_display' => 32, - 'entity_view_mode' => 12, - 'base_field_override' => 33, - ]; - } - - /** - * Executes all steps of migrations upgrade. - */ - protected function testMigrateUpgrade() { - parent::testMigrateUpgrade(); - - // Ensure migrated users can log in. - $user = User::load(2); - $user->pass_raw = 'john.doe_pass'; - $this->drupalLogin($user); - } - -} diff --git a/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php deleted file mode 100644 index 77bc2ab8..00000000 --- a/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php +++ /dev/null @@ -1,89 +0,0 @@ -loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php'); - } - - /** - * {@inheritdoc} - */ - protected function getSourceBasePath() { - return __DIR__ . '/files'; - } - - /** - * {@inheritdoc} - */ - protected function getEntityCounts() { - return [ - 'block' => 25, - 'block_content' => 1, - 'block_content_type' => 1, - 'comment' => 1, - 'comment_type' => 7, - // Module 'language' comes with 'en', 'und', 'zxx'. Migration adds 'is'. - 'configurable_language' => 4, - 'contact_form' => 3, - 'editor' => 2, - 'field_config' => 49, - 'field_storage_config' => 37, - 'file' => 2, - 'filter_format' => 7, - 'image_style' => 6, - 'language_content_settings' => 2, - 'migration' => 73, - 'node' => 3, - 'node_type' => 6, - 'rdf_mapping' => 5, - 'search_page' => 2, - 'shortcut' => 6, - 'shortcut_set' => 2, - 'action' => 16, - 'menu' => 6, - 'taxonomy_term' => 18, - 'taxonomy_vocabulary' => 3, - 'tour' => 4, - 'user' => 4, - 'user_role' => 3, - 'menu_link_content' => 7, - 'view' => 12, - 'date_format' => 11, - 'entity_form_display' => 16, - 'entity_form_mode' => 1, - 'entity_view_display' => 24, - 'entity_view_mode' => 11, - 'base_field_override' => 7, - ]; - } - - /** - * Executes all steps of migrations upgrade. - */ - protected function testMigrateUpgrade() { - parent::testMigrateUpgrade(); - - // Ensure migrated users can log in. - $user = User::load(2); - $user->pass_raw = 'a password'; - $this->drupalLogin($user); - } - -} diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_provider_test.info.yml b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_provider_test.info.yml new file mode 100644 index 00000000..620e8185 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_provider_test.info.yml @@ -0,0 +1,12 @@ +name: 'Migration provider missing' +type: module +description: 'Add a migration missing a source and destination migration provider and a source plugin missing a migration provider.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml new file mode 100644 index 00000000..bdc90666 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_no_annotation.yml @@ -0,0 +1,13 @@ +id: migration_provider_no_annotation +label: Missing source annotation +migration_tags: + - Drupal 6 + - Drupal 7 +source: +# Test plugin without a source_module annotation + plugin: no_source_module +process: + message: site_offline_message +destination: + plugin: config + config_name: test.settings diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_test.yml b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_test.yml new file mode 100644 index 00000000..d3afc665 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/migration_templates/migration_provider_test.yml @@ -0,0 +1,16 @@ +id: migration_provider_test +label: Missing source and destination provider +migration_tags: + - Drupal 6 + - Drupal 7 +source: + plugin: variable + variables: + - site_offline_message +# Do not add a provider for the test. +process: + message: site_offline_message +destination: + plugin: config +# An empty config_name will not have a destination provider. + config_name: \ No newline at end of file diff --git a/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/src/Plugin/migrate/source/NoSourceModule.php b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/src/Plugin/migrate/source/NoSourceModule.php new file mode 100644 index 00000000..0fc3063b --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/modules/migration_provider_test/src/Plugin/migrate/source/NoSourceModule.php @@ -0,0 +1,31 @@ +drupalLogin($this->rootUser); $this->drupalGet('upgrade'); $this->assertResponse(200); diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php new file mode 100644 index 00000000..0cbd9ce8 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php @@ -0,0 +1,262 @@ +createMigrationConnection(); + $this->sourceDatabase = Database::getConnection('default', 'migrate_drupal_ui'); + + // Log in as user 1. Migrations in the UI can only be performed as user 1. + $this->drupalLogin($this->rootUser); + } + + /** + * Loads a database fixture into the source database connection. + * + * @param string $path + * Path to the dump file. + */ + protected function loadFixture($path) { + $default_db = Database::getConnection()->getKey(); + Database::setActiveConnection($this->sourceDatabase->getKey()); + + if (substr($path, -3) == '.gz') { + $path = 'compress.zlib://' . $path; + } + require $path; + + Database::setActiveConnection($default_db); + } + + /** + * Changes the database connection to the prefixed one. + * + * @todo Remove when we don't use global. https://www.drupal.org/node/2552791 + */ + protected function createMigrationConnection() { + $connection_info = Database::getConnectionInfo('default')['default']; + if ($connection_info['driver'] === 'sqlite') { + // Create database file in the test site's public file directory so that + // \Drupal\simpletest\TestBase::restoreEnvironment() will delete this once + // the test is complete. + $file = $this->publicFilesDirectory . '/' . $this->testId . '-migrate.db.sqlite'; + touch($file); + $connection_info['database'] = $file; + $connection_info['prefix'] = ''; + } + else { + $prefix = is_array($connection_info['prefix']) ? $connection_info['prefix']['default'] : $connection_info['prefix']; + // Simpletest uses fixed length prefixes. Create a new prefix for the + // source database. Adding to the end of the prefix ensures that + // \Drupal\simpletest\TestBase::restoreEnvironment() will remove the + // additional tables. + $connection_info['prefix'] = $prefix . '0'; + } + + Database::addConnectionInfo('migrate_drupal_ui', 'default', $connection_info); + } + + /** + * {@inheritdoc} + */ + protected function tearDown() { + Database::removeConnection('migrate_drupal_ui'); + parent::tearDown(); + } + + /** + * Executes all steps of migrations upgrade. + */ + public function testMigrateUpgrade() { + $connection_options = $this->sourceDatabase->getConnectionOptions(); + $this->drupalGet('/upgrade'); + $this->assertSession()->responseContains('Upgrade a site by importing its database and files into a clean and empty new install of Drupal 8.'); + + $this->drupalPostForm(NULL, [], t('Continue')); + $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); + $this->assertFieldByName('mysql[host]'); + + $driver = $connection_options['driver']; + $connection_options['prefix'] = $connection_options['prefix']['default']; + + // Use the driver connection form to get the correct options out of the + // database settings. This supports all of the databases we test against. + $drivers = drupal_get_database_types(); + $form = $drivers[$driver]->getFormOptions($connection_options); + $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); + $version = $this->getLegacyDrupalVersion($this->sourceDatabase); + $edit = [ + $driver => $connection_options, + 'source_private_file_path' => $this->getSourceBasePath(), + 'version' => $version, + ]; + if ($version == 6) { + $edit['d6_source_base_path'] = $this->getSourceBasePath(); + } + else { + $edit['source_base_path'] = $this->getSourceBasePath(); + } + if (count($drivers) !== 1) { + $edit['driver'] = $driver; + } + $edits = $this->translatePostValues($edit); + + // Ensure submitting the form with invalid database credentials gives us a + // nice warning. + $this->drupalPostForm(NULL, [$driver . '[database]' => 'wrong'] + $edits, t('Review upgrade')); + $this->assertText('Resolve the issue below to continue the upgrade.'); + + $this->drupalPostForm(NULL, $edits, t('Review upgrade')); + $this->assertResponse(200); + $this->assertText('Upgrade analysis report'); + // Ensure we get errors about missing modules. + $this->assertSession()->pageTextContains(t('Source module not found for migration_provider_no_annotation.')); + $this->assertSession()->pageTextContains(t('Source module not found for migration_provider_test.')); + $this->assertSession()->pageTextContains(t('Destination module not found for migration_provider_test')); + + // Uninstall the module causing the missing module error messages. + $this->container->get('module_installer')->uninstall(['migration_provider_test'], TRUE); + + // Restart the upgrade process. + $this->drupalGet('/upgrade'); + $this->assertSession()->responseContains('Upgrade a site by importing its database and files into a clean and empty new install of Drupal 8.'); + + $this->drupalPostForm(NULL, [], t('Continue')); + $this->assertSession()->pageTextContains('Provide credentials for the database of the Drupal site you want to upgrade.'); + $this->assertSession()->fieldExists('mysql[host]'); + + $this->drupalPostForm(NULL, $edits, t('Review upgrade')); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextContains('Upgrade analysis report'); + // Ensure there are no errors about the missing modules from the test module. + $this->assertSession()->pageTextNotContains(t('Source module not found for migration_provider_no_annotation.')); + $this->assertSession()->pageTextNotContains(t('Source module not found for migration_provider_test.')); + $this->assertSession()->pageTextNotContains(t('Destination module not found for migration_provider_test')); + // Ensure there are no errors about any other missing migration providers. + $this->assertSession()->pageTextNotContains(t('module not found')); + $this->drupalPostForm(NULL, [], t('Perform upgrade')); + $this->assertText(t('Congratulations, you upgraded Drupal!')); + + // Have to reset all the statics after migration to ensure entities are + // loadable. + $this->resetAll(); + + $expected_counts = $this->getEntityCounts(); + foreach (array_keys(\Drupal::entityTypeManager() + ->getDefinitions()) as $entity_type) { + $real_count = \Drupal::entityQuery($entity_type)->count()->execute(); + $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0; + $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count."); + } + + $plugin_manager = \Drupal::service('plugin.manager.migration'); + /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */ + $all_migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version); + foreach ($all_migrations as $migration) { + $id_map = $migration->getIdMap(); + foreach ($id_map as $source_id => $map) { + // Convert $source_id into a keyless array so that + // \Drupal\migrate\Plugin\migrate\id_map\Sql::getSourceHash() works as + // expected. + $source_id_values = array_values(unserialize($source_id)); + $row = $id_map->getRowBySource($source_id_values); + $destination = serialize($id_map->currentDestination()); + $message = "Migration of $source_id to $destination as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status']; + // A completed migration should have maps with + // MigrateIdMapInterface::STATUS_IGNORED or + // MigrateIdMapInterface::STATUS_IMPORTED. + if ($row['source_row_status'] == MigrateIdMapInterface::STATUS_FAILED || $row['source_row_status'] == MigrateIdMapInterface::STATUS_NEEDS_UPDATE) { + $this->fail($message); + } + else { + $this->pass($message); + } + } + } + \Drupal::service('module_installer')->install(['forum']); + \Drupal::service('module_installer')->install(['book']); + } + + /** + * Transforms a nested array into a flat array suitable for BrowserTestBase::drupalPostForm(). + * + * @param array $values + * A multi-dimensional form values array to convert. + * + * @return array + * The flattened $edit array suitable for BrowserTestBase::drupalPostForm(). + */ + protected function translatePostValues(array $values) { + $edit = []; + // The easiest and most straightforward way to translate values suitable for + // BrowserTestBase::drupalPostForm() is to actually build the POST data string + // and convert the resulting key/value pairs back into a flat array. + $query = http_build_query($values); + foreach (explode('&', $query) as $item) { + list($key, $value) = explode('=', $item); + $edit[urldecode($key)] = urldecode($value); + } + return $edit; + } + + /** + * Gets the source base path for the concrete test. + * + * @return string + * The source base path. + */ + abstract protected function getSourceBasePath(); + + /** + * Gets the expected number of entities per entity type after migration. + * + * @return int[] + * An array of expected counts keyed by entity type ID. + */ + abstract protected function getEntityCounts(); + +} diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php new file mode 100644 index 00000000..d961faab --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php @@ -0,0 +1,94 @@ +loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php'); + } + + /** + * {@inheritdoc} + */ + protected function getSourceBasePath() { + return __DIR__ . '/files'; + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() { + return [ + 'aggregator_item' => 1, + 'aggregator_feed' => 1, + 'block' => 35, + 'block_content' => 2, + 'block_content_type' => 1, + 'comment' => 6, + // The 'standard' profile provides the 'comment' comment type, and the + // migration creates 12 comment types, one per node type. + 'comment_type' => 13, + 'contact_form' => 5, + 'configurable_language' => 5, + 'editor' => 2, + 'field_config' => 84, + 'field_storage_config' => 58, + 'file' => 7, + 'filter_format' => 7, + 'image_style' => 5, + 'language_content_settings' => 2, + 'migration' => 105, + 'node' => 17, + // The 'book' module provides the 'book' node type, and the migration + // creates 12 node types. + 'node_type' => 13, + 'rdf_mapping' => 7, + 'search_page' => 2, + 'shortcut' => 2, + 'shortcut_set' => 1, + 'action' => 23, + 'menu' => 8, + 'taxonomy_term' => 8, + 'taxonomy_vocabulary' => 7, + 'tour' => 4, + 'user' => 7, + 'user_role' => 6, + 'menu_link_content' => 4, + 'view' => 16, + 'date_format' => 11, + 'entity_form_display' => 29, + 'entity_form_mode' => 1, + 'entity_view_display' => 53, + 'entity_view_mode' => 14, + 'base_field_override' => 38, + ]; + } + + /** + * Executes all steps of migrations upgrade. + */ + public function testMigrateUpgrade() { + parent::testMigrateUpgrade(); + + // Ensure migrated users can log in. + $user = User::load(2); + $user->passRaw = 'john.doe_pass'; + $this->drupalLogin($user); + } + +} diff --git a/core/modules/migrate_drupal_ui/src/Tests/d6/files/tmp/some-temp-file.jpg b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/files/tmp/some-temp-file.jpg similarity index 100% rename from core/modules/migrate_drupal_ui/src/Tests/d6/files/tmp/some-temp-file.jpg rename to core/modules/migrate_drupal_ui/tests/src/Functional/d6/files/tmp/some-temp-file.jpg diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php new file mode 100644 index 00000000..f22a9f7a --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php @@ -0,0 +1,98 @@ +loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal7.php'); + } + + /** + * {@inheritdoc} + */ + protected function getSourceBasePath() { + return __DIR__ . '/files'; + } + + /** + * {@inheritdoc} + */ + protected function getEntityCounts() { + return [ + 'aggregator_item' => 10, + 'aggregator_feed' => 1, + 'block' => 25, + 'block_content' => 1, + 'block_content_type' => 1, + 'comment' => 1, + // The 'standard' profile provides the 'comment' comment type, and the + // migration creates 6 comment types, one per node type. + 'comment_type' => 7, + // Module 'language' comes with 'en', 'und', 'zxx'. Migration adds 'is'. + 'configurable_language' => 4, + 'contact_form' => 3, + 'editor' => 2, + 'field_config' => 61, + 'field_storage_config' => 44, + 'file' => 3, + 'filter_format' => 7, + 'image_style' => 6, + 'language_content_settings' => 2, + 'migration' => 73, + 'node' => 5, + 'node_type' => 6, + 'rdf_mapping' => 7, + 'search_page' => 2, + 'shortcut' => 6, + 'shortcut_set' => 2, + 'action' => 17, + 'menu' => 6, + 'taxonomy_term' => 18, + 'taxonomy_vocabulary' => 4, + 'tour' => 4, + 'user' => 4, + 'user_role' => 3, + 'menu_link_content' => 7, + 'view' => 16, + 'date_format' => 11, + 'entity_form_display' => 17, + 'entity_form_mode' => 1, + 'entity_view_display' => 28, + 'entity_view_mode' => 14, + 'base_field_override' => 9, + ]; + } + + /** + * Executes all steps of migrations upgrade. + */ + public function testMigrateUpgrade() { + parent::testMigrateUpgrade(); + + // Ensure migrated users can log in. + $user = User::load(2); + $user->passRaw = 'a password'; + $this->drupalLogin($user); + } + +} diff --git a/core/modules/migrate_drupal_ui/src/Tests/d7/files/sites/default/files/cube.jpeg b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/files/cube.jpeg similarity index 100% rename from core/modules/migrate_drupal_ui/src/Tests/d7/files/sites/default/files/cube.jpeg rename to core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/files/cube.jpeg diff --git a/core/modules/migrate_drupal_ui/src/Tests/d7/files/sites/default/files/ds9.txt b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/files/ds9.txt similarity index 100% rename from core/modules/migrate_drupal_ui/src/Tests/d7/files/sites/default/files/ds9.txt rename to core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/files/ds9.txt diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/private/Babylon5.txt b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/private/Babylon5.txt new file mode 100644 index 00000000..6a7e4527 --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/files/sites/default/private/Babylon5.txt @@ -0,0 +1 @@ +*** diff --git a/core/modules/migrate_drupal_ui/tests/src/Kernel/MigrationLabelExistTest.php b/core/modules/migrate_drupal_ui/tests/src/Kernel/MigrationLabelExistTest.php new file mode 100644 index 00000000..148c9bee --- /dev/null +++ b/core/modules/migrate_drupal_ui/tests/src/Kernel/MigrationLabelExistTest.php @@ -0,0 +1,40 @@ +container->get('module_handler'); + $modules = $this->coreModuleListDataProvider(); + $modules_enabled = $module_handler->getModuleList(); + $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled)); + $this->enableModules($modules_to_enable); + + /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */ + $plugin_manager = $this->container->get('plugin.manager.migration'); + // Get all the migrations + $migrations = $plugin_manager->createInstances(array_keys($plugin_manager->getDefinitions())); + /** @var \Drupal\migrate\Plugin\Migration $migration */ + foreach ($migrations as $migration) { + $migration_id = $migration->getPluginId(); + $this->assertNotEmpty($migration->label(), new FormattableMarkup('Label found for @migration_id.', ['@migration_id' => $migration_id])); + } + } + +} diff --git a/core/modules/node/config/optional/views.view.content.yml b/core/modules/node/config/optional/views.view.content.yml index eff173c1..cef43c7e 100644 --- a/core/modules/node/config/optional/views.view.content.yml +++ b/core/modules/node/config/optional/views.view.content.yml @@ -353,61 +353,46 @@ display: destination: true plugin_id: entity_operations filters: - status_extra: - id: status_extra - table: node_field_data - field: status_extra - operator: '=' - value: false - plugin_id: node_status - group: 1 - entity_type: node - status: - id: status + title: + id: title table: node_field_data - field: status + field: title relationship: none group_type: group admin_label: '' - operator: '=' - value: '1' + operator: contains + value: '' group: 1 exposed: true expose: - operator_id: '' - label: Status + operator_id: title_op + label: Title description: '' use_operator: false - operator: status_op - identifier: status + operator: title_op + identifier: title required: false remember: false multiple: false remember_roles: authenticated: authenticated - is_grouped: true + anonymous: '0' + administrator: '0' + is_grouped: false group_info: - label: 'Published status' + label: '' description: '' - identifier: status + identifier: '' optional: true widget: select multiple: false remember: false default_group: All default_group_multiple: { } - group_items: - 1: - title: Published - operator: '=' - value: '1' - 2: - title: Unpublished - operator: '=' - value: '0' - plugin_id: boolean + group_items: { } + plugin_id: string entity_type: node - entity_field: status + entity_field: title type: id: type table: node_field_data @@ -449,46 +434,52 @@ display: plugin_id: bundle entity_type: node entity_field: type - title: - id: title + status: + id: status table: node_field_data - field: title + field: status relationship: none group_type: group admin_label: '' - operator: contains - value: '' + operator: '=' + value: '1' group: 1 exposed: true expose: - operator_id: title_op - label: Title + operator_id: '' + label: Status description: '' use_operator: false - operator: title_op - identifier: title + operator: status_op + identifier: status required: false remember: false multiple: false remember_roles: authenticated: authenticated - anonymous: '0' - administrator: '0' - is_grouped: false + is_grouped: true group_info: - label: '' + label: 'Published status' description: '' - identifier: '' + identifier: status optional: true widget: select multiple: false remember: false default_group: All default_group_multiple: { } - group_items: { } - plugin_id: string + group_items: + 1: + title: Published + operator: '=' + value: '1' + 2: + title: Unpublished + operator: '=' + value: '0' + plugin_id: boolean entity_type: node - entity_field: title + entity_field: status langcode: id: langcode table: node_field_data @@ -530,6 +521,15 @@ display: plugin_id: language entity_type: node entity_field: langcode + status_extra: + id: status_extra + table: node_field_data + field: status_extra + operator: '=' + value: false + plugin_id: node_status + group: 1 + entity_type: node sorts: { } title: Content empty: diff --git a/core/modules/node/config/optional/views.view.content_recent.yml b/core/modules/node/config/optional/views.view.content_recent.yml index 39f4ecba..1db249ee 100644 --- a/core/modules/node/config/optional/views.view.content_recent.yml +++ b/core/modules/node/config/optional/views.view.content_recent.yml @@ -296,7 +296,7 @@ display: - user - 'user.node_grants:view' - user.permissions - max-age: 0 + max-age: -1 tags: { } block_1: display_plugin: block @@ -312,5 +312,5 @@ display: - user - 'user.node_grants:view' - user.permissions - max-age: 0 + max-age: -1 tags: { } diff --git a/core/modules/node/config/optional/views.view.glossary.yml b/core/modules/node/config/optional/views.view.glossary.yml index 2b4e3301..10f6d55a 100644 --- a/core/modules/node/config/optional/views.view.glossary.yml +++ b/core/modules/node/config/optional/views.view.glossary.yml @@ -1,6 +1,8 @@ langcode: en status: false dependencies: + config: + - system.menu.main module: - node - user diff --git a/core/modules/node/content_types.es6.js b/core/modules/node/content_types.es6.js new file mode 100644 index 00000000..e7c01dd8 --- /dev/null +++ b/core/modules/node/content_types.es6.js @@ -0,0 +1,58 @@ +/** + * @file + * Javascript for the node content editing form. + */ + +(function ($, Drupal) { + /** + * Behaviors for setting summaries on content type form. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches summary behaviors on content type edit forms. + */ + Drupal.behaviors.contentTypes = { + attach(context) { + const $context = $(context); + // Provide the vertical tab summaries. + $context.find('#edit-submission').drupalSetSummary((context) => { + const vals = []; + vals.push(Drupal.checkPlain($(context).find('#edit-title-label').val()) || Drupal.t('Requires a title')); + return vals.join(', '); + }); + $context.find('#edit-workflow').drupalSetSummary((context) => { + const vals = []; + $(context).find('input[name^="options"]:checked').next('label').each(function () { + vals.push(Drupal.checkPlain($(this).text())); + }); + if (!$(context).find('#edit-options-status').is(':checked')) { + vals.unshift(Drupal.t('Not published')); + } + return vals.join(', '); + }); + $('#edit-language', context).drupalSetSummary((context) => { + const vals = []; + + vals.push($('.js-form-item-language-configuration-langcode select option:selected', context).text()); + + $('input:checked', context).next('label').each(function () { + vals.push(Drupal.checkPlain($(this).text())); + }); + + return vals.join(', '); + }); + $context.find('#edit-display').drupalSetSummary((context) => { + const vals = []; + const $editContext = $(context); + $editContext.find('input:checked').next('label').each(function () { + vals.push(Drupal.checkPlain($(this).text())); + }); + if (!$editContext.find('#edit-display-submitted').is(':checked')) { + vals.unshift(Drupal.t("Don't display post information")); + } + return vals.join(', '); + }); + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/node/content_types.js b/core/modules/node/content_types.js index eed93f01..9d2f24e6 100644 --- a/core/modules/node/content_types.js +++ b/core/modules/node/content_types.js @@ -1,24 +1,15 @@ /** - * @file - * Javascript for the node content editing form. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Behaviors for setting summaries on content type form. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches summary behaviors on content type edit forms. - */ Drupal.behaviors.contentTypes = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); - // Provide the vertical tab summaries. + $context.find('#edit-submission').drupalSetSummary(function (context) { var vals = []; vals.push(Drupal.checkPlain($(context).find('#edit-title-label').val()) || Drupal.t('Requires a title')); @@ -26,7 +17,7 @@ }); $context.find('#edit-workflow').drupalSetSummary(function (context) { var vals = []; - $(context).find('input[name^="options"]:checked').parent().each(function () { + $(context).find('input[name^="options"]:checked').next('label').each(function () { vals.push(Drupal.checkPlain($(this).text())); }); if (!$(context).find('#edit-options-status').is(':checked')) { @@ -58,5 +49,4 @@ }); } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/node/migration_templates/d6_node.yml b/core/modules/node/migration_templates/d6_node.yml index 4e19bb40..56d0459a 100644 --- a/core/modules/node/migration_templates/d6_node.yml +++ b/core/modules/node/migration_templates/d6_node.yml @@ -25,7 +25,7 @@ process: promote: promote sticky: sticky 'body/format': - plugin: migration + plugin: migration_lookup migration: d6_filter_format source: format 'body/value': body diff --git a/core/modules/node/migration_templates/d6_node_revision.yml b/core/modules/node/migration_templates/d6_node_revision.yml index 046e9bbe..f4ff3011 100644 --- a/core/modules/node/migration_templates/d6_node_revision.yml +++ b/core/modules/node/migration_templates/d6_node_revision.yml @@ -22,7 +22,7 @@ process: promote: promote sticky: sticky 'body/format': - plugin: migration + plugin: migration_lookup migration: d6_filter_format source: format 'body/value': body diff --git a/core/modules/node/migration_templates/d6_node_settings.yml b/core/modules/node/migration_templates/d6_node_settings.yml index 17b08573..98b09fbc 100644 --- a/core/modules/node/migration_templates/d6_node_settings.yml +++ b/core/modules/node/migration_templates/d6_node_settings.yml @@ -6,6 +6,7 @@ source: plugin: variable variables: - node_admin_theme + source_module: node process: use_admin_theme: node_admin_theme destination: diff --git a/core/modules/node/migration_templates/d6_node_translation.yml b/core/modules/node/migration_templates/d6_node_translation.yml index 3b923d18..4bf36da7 100644 --- a/core/modules/node/migration_templates/d6_node_translation.yml +++ b/core/modules/node/migration_templates/d6_node_translation.yml @@ -6,6 +6,7 @@ deriver: Drupal\node\Plugin\migrate\D6NodeDeriver source: plugin: d6_node translations: true + source_module: translation process: # If you are using this file to build a custom migration consider removing # the nid field to allow incremental migrations. @@ -23,7 +24,7 @@ process: promote: promote sticky: sticky 'body/format': - plugin: migration + plugin: migration_lookup migration: d6_filter_format source: format 'body/value': body @@ -41,6 +42,7 @@ process: destination: plugin: entity:node translations: true + destination_module: content_translation migration_dependencies: required: - d6_user @@ -52,4 +54,3 @@ migration_dependencies: - d6_field_instance_widget_settings - d6_field_formatter_settings - d6_upload_field_instance -provider: migrate_drupal diff --git a/core/modules/node/migration_templates/d6_node_type.yml b/core/modules/node/migration_templates/d6_node_type.yml index 4c76f66a..5587ef51 100644 --- a/core/modules/node/migration_templates/d6_node_type.yml +++ b/core/modules/node/migration_templates/d6_node_type.yml @@ -20,5 +20,7 @@ process: 'settings/node/options': options create_body: has_body create_body_label: body_label + 'third_party_settings/menu_ui/available_menus': available_menus + 'third_party_settings/menu_ui/parent': parent destination: plugin: entity:node_type diff --git a/core/modules/node/migration_templates/d7_node.yml b/core/modules/node/migration_templates/d7_node.yml index 381f7ce7..359be81c 100644 --- a/core/modules/node/migration_templates/d7_node.yml +++ b/core/modules/node/migration_templates/d7_node.yml @@ -8,7 +8,10 @@ source: process: # If you are using this file to build a custom migration consider removing # the nid and vid fields to allow incremental migrations. - nid: nid + # In D7, nodes always have a tnid, but it's zero for untranslated nodes. + # We normalize it to equal the nid in that case. + # @see \Drupal\node\Plugin\migrate\source\d7\Node::prepareRow(). + nid: tnid vid: vid langcode: plugin: default_value @@ -32,3 +35,4 @@ migration_dependencies: - d7_node_type optional: - d7_field_instance + - d7_comment_field_instance diff --git a/core/modules/node/migration_templates/d7_node_settings.yml b/core/modules/node/migration_templates/d7_node_settings.yml index 04617544..46eec7c0 100644 --- a/core/modules/node/migration_templates/d7_node_settings.yml +++ b/core/modules/node/migration_templates/d7_node_settings.yml @@ -6,6 +6,7 @@ source: plugin: variable variables: - node_admin_theme + source_module: node process: use_admin_theme: node_admin_theme destination: diff --git a/core/modules/node/migration_templates/d7_node_translation.yml b/core/modules/node/migration_templates/d7_node_translation.yml new file mode 100644 index 00000000..856f3450 --- /dev/null +++ b/core/modules/node/migration_templates/d7_node_translation.yml @@ -0,0 +1,43 @@ +id: d7_node_translation +label: Node translations +migration_tags: + - Drupal 7 + - translation +deriver: Drupal\node\Plugin\migrate\D7NodeDeriver +source: + plugin: d7_node + translations: true + source_module: translation +process: + # If you are using this file to build a custom migration consider removing + # the nid field to allow incremental migrations. + nid: tnid + type: type + langcode: + plugin: default_value + source: language + default_value: "und" + title: title + uid: node_uid + status: status + created: created + changed: changed + promote: promote + sticky: sticky + revision_uid: revision_uid + revision_log: log + revision_timestamp: timestamp + content_translation_source: source_langcode +destination: + plugin: entity:node + translations: true + content_translation_update_definitions: + - node + destination_module: content_translation +migration_dependencies: + required: + - d7_user + - d7_node_type + - language + optional: + - d7_field_instance diff --git a/core/modules/node/migration_templates/d7_node_type.yml b/core/modules/node/migration_templates/d7_node_type.yml index 6cf8e783..f61bad8c 100644 --- a/core/modules/node/migration_templates/d7_node_type.yml +++ b/core/modules/node/migration_templates/d7_node_type.yml @@ -17,5 +17,7 @@ process: new_revision: 'options/revision' create_body: create_body create_body_label: body_label + 'third_party_settings/menu_ui/available_menus': available_menus + 'third_party_settings/menu_ui/parent': parent destination: plugin: entity:node_type diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc index d6ffd104..b96ee5af 100644 --- a/core/modules/node/node.admin.inc +++ b/core/modules/node/node.admin.inc @@ -6,7 +6,6 @@ */ use Drupal\node\NodeInterface; -use Drupal\node\Entity\Node; /** * Updates all nodes in the passed-in array with the passed-in field values. @@ -34,10 +33,10 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load // We use batch processing to prevent timeout when updating a large number // of nodes. if (count($nodes) > 10) { - $batch = array( - 'operations' => array( - array('_node_mass_update_batch_process', array($nodes, $updates, $langcode, $load, $revisions)) - ), + $batch = [ + 'operations' => [ + ['_node_mass_update_batch_process', [$nodes, $updates, $langcode, $load, $revisions]] + ], 'finished' => '_node_mass_update_batch_finished', 'title' => t('Processing'), // We use a single multi-pass operation, so the default @@ -47,16 +46,17 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load // The operations do not live in the .module file, so we need to // tell the batch engine which file to load before calling them. 'file' => drupal_get_path('module', 'node') . '/node.admin.inc', - ); + ]; batch_set($batch); } else { + $storage = \Drupal::entityTypeManager()->getStorage('node'); if ($load && !$revisions) { - $nodes = Node::loadMultiple($nodes); + $nodes = $storage->loadMultiple($nodes); } foreach ($nodes as $node) { if ($load && $revisions) { - $node = entity_revision_load('node', $node); + $node = $storage->loadRevision($node); } _node_mass_update_helper($node, $updates, $langcode); } @@ -81,7 +81,7 @@ function node_mass_update(array $nodes, array $updates, $langcode = NULL, $load * @see node_mass_update() */ function _node_mass_update_helper(NodeInterface $node, array $updates, $langcode = NULL) { - $langcodes = isset($langcode) ? array($langcode) : array_keys($node->getTranslationLanguages()); + $langcodes = isset($langcode) ? [$langcode] : array_keys($node->getTranslationLanguages()); // For efficiency manually save the original node before applying any changes. $node->original = clone $node; foreach ($langcodes as $langcode) { @@ -111,7 +111,7 @@ function _node_mass_update_helper(NodeInterface $node, array $updates, $langcode * @param bool $revisions * (optional) TRUE if $nodes contains an array of revision IDs instead of * node IDs. Defaults to FALSE; will be ignored if $load is FALSE. - * @param array|\ArrayAccess $context. + * @param array|\ArrayAccess $context * An array of contextual key/values. */ function _node_mass_update_batch_process(array $nodes, array $updates, $langcode, $load, $revisions, &$context) { @@ -122,13 +122,14 @@ function _node_mass_update_batch_process(array $nodes, array $updates, $langcode } // Process nodes by groups of 5. + $storage = \Drupal::entityTypeManager()->getStorage('node'); $count = min(5, count($context['sandbox']['nodes'])); for ($i = 1; $i <= $count; $i++) { // For each nid, load the node, reset the values, and save it. $node = array_shift($context['sandbox']['nodes']); if ($load) { $node = $revisions ? - entity_revision_load('node', $node) : Node::load($node); + $storage->loadRevision($node) : $storage->load($node); } $node = _node_mass_update_helper($node, $updates, $langcode); @@ -168,11 +169,11 @@ function _node_mass_update_batch_finished($success, $results, $operations) { else { drupal_set_message(t('An error occurred and processing did not complete.'), 'error'); $message = \Drupal::translation()->formatPlural(count($results), '1 item successfully processed:', '@count items successfully processed:'); - $item_list = array( + $item_list = [ '#theme' => 'item_list', '#items' => $results, - ); - $message .= drupal_render($item_list); + ]; + $message .= \Drupal::service('renderer')->render($item_list); drupal_set_message($message); } } diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php index a4937f74..dd151a4a 100644 --- a/core/modules/node/node.api.php +++ b/core/modules/node/node.api.php @@ -81,10 +81,10 @@ */ function hook_node_grants(\Drupal\Core\Session\AccountInterface $account, $op) { if ($account->hasPermission('access private content')) { - $grants['example'] = array(1); + $grants['example'] = [1]; } if ($account->id()) { - $grants['example_author'] = array($account->id()); + $grants['example_author'] = [$account->id()]; } return $grants; } @@ -158,33 +158,33 @@ function hook_node_access_records(\Drupal\node\NodeInterface $node) { // We only care about the node if it has been marked private. If not, it is // treated just like any other node and we completely ignore it. if ($node->private->value) { - $grants = array(); + $grants = []; // Only published Catalan translations of private nodes should be viewable // to all users. If we fail to check $node->isPublished(), all users would be able // to view an unpublished node. if ($node->isPublished()) { - $grants[] = array( + $grants[] = [ 'realm' => 'example', 'gid' => 1, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'langcode' => 'ca' - ); + ]; } // For the example_author array, the GID is equivalent to a UID, which // means there are many groups of just 1 user. // Note that an author can always view his or her nodes, even if they // have status unpublished. if ($node->getOwnerId()) { - $grants[] = array( + $grants[] = [ 'realm' => 'example_author', 'gid' => $node->getOwnerId(), 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1, 'langcode' => 'ca' - ); + ]; } return $grants; @@ -231,7 +231,7 @@ function hook_node_access_records_alter(&$grants, Drupal\node\NodeInterface $nod // Our module grants are set in $grants['example']. $temp = $grants['example']; // Now remove all module grants but our own. - $grants = array('example' => $temp); + $grants = ['example' => $temp]; } } @@ -280,7 +280,7 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface // Now check the roles for this account against the restrictions. foreach ($account->getRoles() as $rid) { if (in_array($rid, $restricted)) { - $grants = array(); + $grants = []; } } } @@ -320,7 +320,7 @@ function hook_node_grants_alter(&$grants, \Drupal\Core\Session\AccountInterface * The user object to perform the access check operation on. * * @return \Drupal\Core\Access\AccessResultInterface - * The access result. + * The access result. * * @ingroup node_access */ @@ -374,8 +374,8 @@ function hook_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Se * @ingroup entity_crud */ function hook_node_search_result(\Drupal\node\NodeInterface $node) { - $rating = db_query('SELECT SUM(points) FROM {my_rating} WHERE nid = :nid', array('nid' => $node->id()))->fetchField(); - return array('rating' => \Drupal::translation()->formatPlural($rating, '1 point', '@count points')); + $rating = db_query('SELECT SUM(points) FROM {my_rating} WHERE nid = :nid', ['nid' => $node->id()])->fetchField(); + return ['rating' => \Drupal::translation()->formatPlural($rating, '1 point', '@count points')]; } /** @@ -394,7 +394,7 @@ function hook_node_search_result(\Drupal\node\NodeInterface $node) { */ function hook_node_update_index(\Drupal\node\NodeInterface $node) { $text = ''; - $ratings = db_query('SELECT title, description FROM {my_ratings} WHERE nid = :nid', array(':nid' => $node->id())); + $ratings = db_query('SELECT title, description FROM {my_ratings} WHERE nid = :nid', [':nid' => $node->id()]); foreach ($ratings as $rating) { $text .= '

    ' . Html::escape($rating->title) . '

    ' . Xss::filter($rating->description); } @@ -447,24 +447,24 @@ function hook_node_update_index(\Drupal\node\NodeInterface $node) { function hook_ranking() { // If voting is disabled, we can avoid returning the array, no hard feelings. if (\Drupal::config('vote.settings')->get('node_enabled')) { - return array( - 'vote_average' => array( + return [ + 'vote_average' => [ 'title' => t('Average vote'), // Note that we use i.sid, the search index's search item id, rather than // n.nid. - 'join' => array( + 'join' => [ 'type' => 'LEFT', 'table' => 'vote_node_data', 'alias' => 'vote_node_data', 'on' => 'vote_node_data.nid = i.sid', - ), + ], // The highest possible score should be 1, and the lowest possible score, // always 0, should be 0. 'score' => 'vote_node_data.average / CAST(%f AS DECIMAL)', // Pass in the highest possible voting score as a decimal argument. - 'arguments' => array(\Drupal::config('vote.settings')->get('score_max')), - ), - ); + 'arguments' => [\Drupal::config('vote.settings')->get('score_max')], + ], + ]; } } @@ -486,16 +486,16 @@ function hook_ranking() { * @see entity_crud */ function hook_node_links_alter(array &$links, NodeInterface $entity, array &$context) { - $links['mymodule'] = array( + $links['mymodule'] = [ '#theme' => 'links__node__mymodule', - '#attributes' => array('class' => array('links', 'inline')), - '#links' => array( - 'node-report' => array( + '#attributes' => ['class' => ['links', 'inline']], + '#links' => [ + 'node-report' => [ 'title' => t('Report'), 'url' => Url::fromRoute('node_test.report', ['node' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("node/{$entity->id()}/report")]]), - ), - ), - ); + ], + ], + ]; } /** diff --git a/core/modules/node/node.es6.js b/core/modules/node/node.es6.js new file mode 100644 index 00000000..6d6beb92 --- /dev/null +++ b/core/modules/node/node.es6.js @@ -0,0 +1,50 @@ +/** + * @file + * Defines Javascript behaviors for the node module. + */ + +(function ($, Drupal, drupalSettings) { + /** + * Behaviors for tabs in the node edit form. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches summary behavior for tabs in the node edit form. + */ + Drupal.behaviors.nodeDetailsSummaries = { + attach(context) { + const $context = $(context); + + $context.find('.node-form-author').drupalSetSummary((context) => { + const $authorContext = $(context); + const name = $authorContext.find('.field--name-uid input').val(); + const date = $authorContext.find('.field--name-created input').val(); + + if (name && date) { + return Drupal.t('By @name on @date', { '@name': name, '@date': date }); + } + else if (name) { + return Drupal.t('By @name', { '@name': name }); + } + else if (date) { + return Drupal.t('Authored on @date', { '@date': date }); + } + }); + + $context.find('.node-form-options').drupalSetSummary((context) => { + const $optionsContext = $(context); + const vals = []; + + if ($optionsContext.find('input').is(':checked')) { + $optionsContext.find('input:checked').next('label').each(function () { + vals.push(Drupal.checkPlain($.trim($(this).text()))); + }); + return vals.join(', '); + } + + return Drupal.t('Not promoted'); + }); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/node/node.info.yml b/core/modules/node/node.info.yml index 2a74f64d..da113ca7 100644 --- a/core/modules/node/node.info.yml +++ b/core/modules/node/node.info.yml @@ -8,8 +8,8 @@ configure: entity.node_type.collection dependencies: - text -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/node.install b/core/modules/node/node.install index c754880f..6469245c 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -5,6 +5,7 @@ * Install, update and uninstall functions for the node module. */ +use Drupal\Core\Database\Database; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\user\RoleInterface; @@ -12,26 +13,26 @@ use Drupal\user\RoleInterface; * Implements hook_requirements(). */ function node_requirements($phase) { - $requirements = array(); + $requirements = []; if ($phase === 'runtime') { // Only show rebuild button if there are either 0, or 2 or more, rows // in the {node_access} table, or if there are modules that // implement hook_node_grants(). $grant_count = \Drupal::entityManager()->getAccessControlHandler('node')->countGrants(); if ($grant_count != 1 || count(\Drupal::moduleHandler()->getImplementations('node_grants')) > 0) { - $value = \Drupal::translation()->formatPlural($grant_count, 'One permission in use', '@count permissions in use', array('@count' => $grant_count)); + $value = \Drupal::translation()->formatPlural($grant_count, 'One permission in use', '@count permissions in use', ['@count' => $grant_count]); } else { $value = t('Disabled'); } - $requirements['node_access'] = array( + $requirements['node_access'] = [ 'title' => t('Node Access Permissions'), 'value' => $value, - 'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. Rebuild permissions', array( + 'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. Rebuild permissions', [ ':rebuild' => \Drupal::url('node.configure_rebuild_confirm'), - )), - ); + ]), + ]; } return $requirements; } @@ -40,77 +41,78 @@ function node_requirements($phase) { * Implements hook_schema(). */ function node_schema() { - $schema['node_access'] = array( + $schema['node_access'] = [ 'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.', - 'fields' => array( - 'nid' => array( + 'fields' => [ + 'nid' => [ 'description' => 'The {node}.nid this record affects.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'langcode' => array( + ], + 'langcode' => [ 'description' => 'The {language}.langcode of this node.', 'type' => 'varchar_ascii', 'length' => 12, 'not null' => TRUE, 'default' => '', - ), - 'fallback' => array( + ], + 'fallback' => [ 'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1, - ), - 'gid' => array( + 'size' => 'tiny', + ], + 'gid' => [ 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'realm' => array( - 'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.', + ], + 'realm' => [ + 'description' => 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().', 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'grant_view' => array( + ], + 'grant_view' => [ 'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', - ), - 'grant_update' => array( + ], + 'grant_update' => [ 'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', - ), - 'grant_delete' => array( + ], + 'grant_delete' => [ 'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'tiny', - ), - ), - 'primary key' => array('nid', 'gid', 'realm', 'langcode'), - 'foreign keys' => array( - 'affected_node' => array( + ], + ], + 'primary key' => ['nid', 'gid', 'realm', 'langcode'], + 'foreign keys' => [ + 'affected_node' => [ 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - ), - ); + 'columns' => ['nid' => 'nid'], + ], + ], + ]; return $schema; } @@ -127,20 +129,20 @@ function node_install() { // these permissions. Doing so also allows tests to continue to operate as // expected without first having to manually grant these default permissions. if (\Drupal::moduleHandler()->moduleExists('user')) { - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access content')); - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access content')); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access content']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access content']); } // Populate the node access table. db_insert('node_access') - ->fields(array( + ->fields([ 'nid' => 0, 'gid' => 0, 'realm' => 'all', 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, - )) + ]) ->execute(); } @@ -164,11 +166,11 @@ function node_update_8001() { // \Drupal::entityDefinitionUpdateManager()->updateFieldStorageDefinition() // with the new definition. $storage_definition = BaseFieldDefinition::create('boolean') - ->setLabel(t('Revision translation affected')) - ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.')) - ->setReadOnly(TRUE) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); + ->setLabel(t('Revision translation affected')) + ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.')) + ->setReadOnly(TRUE) + ->setRevisionable(TRUE) + ->setTranslatable(TRUE); \Drupal::entityDefinitionUpdateManager() ->installFieldStorageDefinition('revision_translation_affected', 'node', 'node', $storage_definition); @@ -214,7 +216,42 @@ function node_update_8003() { // changes. SqlContentEntityStorageSchema::onEntityTypeUpdate() should be // fixed to automatically handle this. // See https://www.drupal.org/node/2554245. - foreach (array('status', 'uid') as $field_name) { + foreach (['status', 'uid'] as $field_name) { $manager->updateFieldStorageDefinition($manager->getFieldStorageDefinition($field_name, 'node')); } } + +/** + * Change {node_access}.fallback from an int to a tinyint as it is a boolean. + */ +function node_update_8300() { + Database::getConnection()->schema()->changeField('node_access', 'fallback', 'fallback', [ + 'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 1, + 'size' => 'tiny', + ]); +} + +/** + * Set the 'published' entity key. + */ +function node_update_8301() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $entity_type = $definition_update_manager->getEntityType('node'); + $keys = $entity_type->getKeys(); + $keys['published'] = 'status'; + $entity_type->set('entity_keys', $keys); + $definition_update_manager->updateEntityType($entity_type); +} + +/** + * Fix realm column description on the node_access table. + */ +function node_update_8400() { + $schema = drupal_get_module_schema('node', 'node_access'); + $schema['fields']['realm']['description'] = 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().'; + Database::getConnection()->schema()->changeField('node_access', 'realm', 'realm', $schema['fields']['realm']); +} diff --git a/core/modules/node/node.js b/core/modules/node/node.js index 98af6fdc..fc2da881 100644 --- a/core/modules/node/node.js +++ b/core/modules/node/node.js @@ -1,38 +1,14 @@ /** - * @file - * Defines Javascript behaviors for the node module. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * Behaviors for tabs in the node edit form. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches summary behavior for tabs in the node edit form. - */ Drupal.behaviors.nodeDetailsSummaries = { - attach: function (context) { + attach: function attach(context) { var $context = $(context); - $context.find('.node-form-revision-information').drupalSetSummary(function (context) { - var $revisionContext = $(context); - var revisionCheckbox = $revisionContext.find('.js-form-item-revision input'); - - // Return 'New revision' if the 'Create new revision' checkbox is - // checked, or if the checkbox doesn't exist, but the revision log does. - // For users without the "Administer content" permission the checkbox - // won't appear, but the revision log will if the content type is set to - // auto-revision. - if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $revisionContext.find('.js-form-item-revision-log textarea').length)) { - return Drupal.t('New revision'); - } - - return Drupal.t('No revision'); - }); $context.find('.node-form-author').drupalSetSummary(function (context) { var $authorContext = $(context); @@ -40,13 +16,11 @@ var date = $authorContext.find('.field--name-created input').val(); if (name && date) { - return Drupal.t('By @name on @date', {'@name': name, '@date': date}); - } - else if (name) { - return Drupal.t('By @name', {'@name': name}); - } - else if (date) { - return Drupal.t('Authored on @date', {'@date': date}); + return Drupal.t('By @name on @date', { '@name': name, '@date': date }); + } else if (name) { + return Drupal.t('By @name', { '@name': name }); + } else if (date) { + return Drupal.t('Authored on @date', { '@date': date }); } }); @@ -60,27 +34,9 @@ }); return vals.join(', '); } - else { - return Drupal.t('Not promoted'); - } - }); - $context.find('fieldset.node-translation-options').drupalSetSummary(function (context) { - var $translationContext = $(context); - var translate; - var $checkbox = $translationContext.find('.js-form-item-translation-translate input'); - - if ($checkbox.size()) { - translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated'); - } - else { - $checkbox = $translationContext.find('.js-form-item-translation-retranslate input'); - translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated'); - } - - return translate; + return Drupal.t('Not promoted'); }); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/node/node.libraries.yml b/core/modules/node/node.libraries.yml index 22c93ac7..59947a23 100644 --- a/core/modules/node/node.libraries.yml +++ b/core/modules/node/node.libraries.yml @@ -6,10 +6,8 @@ drupal.node: js: node.js: {} dependencies: - - core/jquery - - core/drupal + - core/drupal.entity-form - core/drupalSettings - - core/drupal.form drupal.node.preview: version: VERSION diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 470ddfcb..b8eb7e64 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -31,31 +31,61 @@ use Drupal\node\NodeTypeInterface; /** * Denotes that the node is not published. + * + * @deprecated Scheduled for removal in Drupal 9.0.x. + * Use \Drupal\node\NodeInterface::NOT_PUBLISHED instead. + * + * @see https://www.drupal.org/node/2316145 */ const NODE_NOT_PUBLISHED = 0; /** * Denotes that the node is published. + * + * @deprecated Scheduled for removal in Drupal 9.0.x. + * Use \Drupal\node\NodeInterface::PUBLISHED instead. + * + * @see https://www.drupal.org/node/2316145 */ const NODE_PUBLISHED = 1; /** * Denotes that the node is not promoted to the front page. + * + * @deprecated Scheduled for removal in Drupal 9.0.x. + * Use \Drupal\node\NodeInterface::NOT_PROMOTED instead. + * + * @see https://www.drupal.org/node/2316145 */ const NODE_NOT_PROMOTED = 0; /** * Denotes that the node is promoted to the front page. + * + * @deprecated Scheduled for removal in Drupal 9.0.x. + * Use \Drupal\node\NodeInterface::PROMOTED instead. + * + * @see https://www.drupal.org/node/2316145 */ const NODE_PROMOTED = 1; /** * Denotes that the node is not sticky at the top of the page. + * + * @deprecated Scheduled for removal in Drupal 9.0.x. + * Use \Drupal\node\NodeInterface::NOT_STICKY instead. + * + * @see https://www.drupal.org/node/2316145 */ const NODE_NOT_STICKY = 0; /** * Denotes that the node is sticky at the top of the page. + * + * @deprecated Scheduled for removal in Drupal 9.0.x. + * Use \Drupal\node\NodeInterface::STICKY instead. + * + * @see https://www.drupal.org/node/2316145 */ const NODE_STICKY = 1; @@ -72,7 +102,7 @@ function node_help($route_name, RouteMatchInterface $route_match) { $message = t('The content access permissions need to be rebuilt.'); } else { - $message = t('The content access permissions need to be rebuilt. Rebuild permissions.', array(':node_access_rebuild' => \Drupal::url('node.configure_rebuild_confirm'))); + $message = t('The content access permissions need to be rebuilt. Rebuild permissions.', [':node_access_rebuild' => \Drupal::url('node.configure_rebuild_confirm')]); } drupal_set_message($message, 'error'); } @@ -81,19 +111,19 @@ function node_help($route_name, RouteMatchInterface $route_match) { case 'help.page.node': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Node module manages the creation, editing, deletion, settings, and display of the main site content. Content items managed by the Node module are typically displayed as pages on your site, and include a title, some meta-data (author, creation time, content type, etc.), and optional fields containing text or other data (fields are managed by the Field module). For more information, see the online documentation for the Node module.', array(':node' => 'https://www.drupal.org/documentation/modules/node', ':field' => \Drupal::url('help.page', array('name' => 'field')))) . '

    '; + $output .= '

    ' . t('The Node module manages the creation, editing, deletion, settings, and display of the main site content. Content items managed by the Node module are typically displayed as pages on your site, and include a title, some meta-data (author, creation time, content type, etc.), and optional fields containing text or other data (fields are managed by the Field module). For more information, see the online documentation for the Node module.', [':node' => 'https://www.drupal.org/documentation/modules/node', ':field' => \Drupal::url('help.page', ['name' => 'field'])]) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Creating content') . '
    '; - $output .= '
    ' . t('When new content is created, the Node module records basic information about the content, including the author, date of creation, and the Content type. It also manages the publishing options, which define whether or not the content is published, promoted to the front page of the site, and/or sticky at the top of content lists. Default settings can be configured for each type of content on your site.', array(':content-type' => \Drupal::url('entity.node_type.collection'))) . '
    '; + $output .= '
    ' . t('When new content is created, the Node module records basic information about the content, including the author, date of creation, and the Content type. It also manages the publishing options, which define whether or not the content is published, promoted to the front page of the site, and/or sticky at the top of content lists. Default settings can be configured for each type of content on your site.', [':content-type' => \Drupal::url('entity.node_type.collection')]) . '
    '; $output .= '
    ' . t('Creating custom content types') . '
    '; - $output .= '
    ' . t('The Node module gives users with the Administer content types permission the ability to create new content types in addition to the default ones already configured. Creating custom content types gives you the flexibility to add fields and configure default settings that suit the differing needs of various site content.', array(':content-new' => \Drupal::url('node.type_add'), ':field' => \Drupal::url('help.page', array('name' => 'field')))) . '
    '; + $output .= '
    ' . t('The Node module gives users with the Administer content types permission the ability to create new content types in addition to the default ones already configured. Creating custom content types gives you the flexibility to add fields and configure default settings that suit the differing needs of various site content.', [':content-new' => \Drupal::url('node.type_add'), ':field' => \Drupal::url('help.page', ['name' => 'field'])]) . '
    '; $output .= '
    ' . t('Administering content') . '
    '; - $output .= '
    ' . t('The Content page lists your content, allowing you add new content, filter, edit or delete existing content, or perform bulk operations on existing content.', array(':content' => \Drupal::url('system.admin_content'))) . '
    '; + $output .= '
    ' . t('The Content page lists your content, allowing you add new content, filter, edit or delete existing content, or perform bulk operations on existing content.', [':content' => \Drupal::url('system.admin_content')]) . '
    '; $output .= '
    ' . t('Creating revisions') . '
    '; $output .= '
    ' . t('The Node module also enables you to create multiple versions of any content, and revert to older versions using the Revision information settings.') . '
    '; $output .= '
    ' . t('User permissions') . '
    '; - $output .= '
    ' . t('The Node module makes a number of permissions available for each content type, which can be set by role on the permissions page.', array(':permissions' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-node')))) . '
    '; + $output .= '
    ' . t('The Node module makes a number of permissions available for each content type, which can be set by role on the permissions page.', [':permissions' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-node'])]) . '
    '; $output .= '
    '; return $output; @@ -103,13 +133,13 @@ function node_help($route_name, RouteMatchInterface $route_match) { case 'entity.entity_form_display.node.default': case 'entity.entity_form_display.node.form_mode': $type = $route_match->getParameter('node_type'); - return '

    ' . t('Content items can be edited using different form modes. Here, you can define which fields are shown and hidden when %type content is edited in each form mode, and define how the field form widgets are displayed in each form mode.', array('%type' => $type->label())) . '

    ' ; + return '

    ' . t('Content items can be edited using different form modes. Here, you can define which fields are shown and hidden when %type content is edited in each form mode, and define how the field form widgets are displayed in each form mode.', ['%type' => $type->label()]) . '

    ' ; case 'entity.entity_view_display.node.default': case 'entity.entity_view_display.node.view_mode': $type = $route_match->getParameter('node_type'); return '

    ' . t('Content items can be displayed using different view modes: Teaser, Full content, Print, RSS, etc. Teaser is a short format that is typically used in lists of multiple content items. Full content is typically used when the content is displayed on its own page.') . '

    ' . - '

    ' . t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', array('%type' => $type->label())) . '

    '; + '

    ' . t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', ['%type' => $type->label()]) . '

    '; case 'entity.node.version_history': return '

    ' . t('Revisions allow you to track differences between multiple versions of your content, and revert to older versions.') . '

    '; @@ -131,26 +161,26 @@ function node_help($route_name, RouteMatchInterface $route_match) { * Implements hook_theme(). */ function node_theme() { - return array( - 'node' => array( + return [ + 'node' => [ 'render element' => 'elements', - ), - 'node_add_list' => array( - 'variables' => array('content' => NULL), - ), - 'node_edit_form' => array( + ], + 'node_add_list' => [ + 'variables' => ['content' => NULL], + ], + 'node_edit_form' => [ 'render element' => 'form', - ), - 'field__node__title' => array( + ], + 'field__node__title' => [ 'base hook' => 'field', - ), - 'field__node__uid' => array( + ], + 'field__node__uid' => [ 'base hook' => 'field', - ), - 'field__node__created' => array( + ], + 'field__node__created' => [ 'base hook' => 'field', - ), - ); + ], + ]; } /** @@ -186,19 +216,19 @@ function node_entity_view_display_alter(EntityViewDisplayInterface $display, $co * $result, or FALSE if there are no rows in $result. */ function node_title_list(StatementInterface $result, $title = NULL) { - $items = array(); + $items = []; $num_rows = FALSE; $nids = []; foreach ($result as $row) { // Do not use $node->label() or $node->urlInfo() here, because we only have // database rows, not actual nodes. $nids[] = $row->nid; - $options = !empty($row->comment_count) ? array('attributes' => array('title' => \Drupal::translation()->formatPlural($row->comment_count, '1 comment', '@count comments'))) : array(); + $options = !empty($row->comment_count) ? ['attributes' => ['title' => \Drupal::translation()->formatPlural($row->comment_count, '1 comment', '@count comments')]] : []; $items[] = \Drupal::l($row->title, new Url('entity.node.canonical', ['node' => $row->nid], $options)); $num_rows = TRUE; } - return $num_rows ? array('#theme' => 'item_list__node', '#items' => $items, '#title' => $title, '#cache' => ['tags' => Cache::mergeTags(['node_list'], Cache::buildTags('node', $nids))]) : FALSE; + return $num_rows ? ['#theme' => 'item_list__node', '#items' => $items, '#title' => $title, '#cache' => ['tags' => Cache::mergeTags(['node_list'], Cache::buildTags('node', $nids))]] : FALSE; } /** @@ -214,7 +244,7 @@ function node_title_list(StatementInterface $result, $title = NULL) { */ function node_mark($nid, $timestamp) { - $cache = &drupal_static(__FUNCTION__, array()); + $cache = &drupal_static(__FUNCTION__, []); if (\Drupal::currentUser()->isAnonymous() || !\Drupal::moduleHandler()->moduleExists('history')) { return MARK_READ; @@ -328,23 +358,23 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { 'field_storage' => $field_storage, 'bundle' => $type->id(), 'label' => $label, - 'settings' => array('display_summary' => TRUE), + 'settings' => ['display_summary' => TRUE], ]); $field->save(); // Assign widget settings for the 'default' form mode. entity_get_form_display('node', $type->id(), 'default') - ->setComponent('body', array( + ->setComponent('body', [ 'type' => 'text_textarea_with_summary', - )) + ]) ->save(); // Assign display settings for the 'default' and 'teaser' view modes. entity_get_display('node', $type->id(), 'default') - ->setComponent('body', array( + ->setComponent('body', [ 'label' => 'hidden', 'type' => 'text_default', - )) + ]) ->save(); // The teaser view mode is created by the Standard profile and therefore @@ -352,10 +382,10 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { $view_modes = \Drupal::entityManager()->getViewModes('node'); if (isset($view_modes['teaser'])) { entity_get_display('node', $type->id(), 'teaser') - ->setComponent('body', array( + ->setComponent('body', [ 'label' => 'hidden', 'type' => 'text_summary_or_trimmed', - )) + ]) ->save(); } } @@ -367,15 +397,15 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { * Implements hook_entity_extra_field_info(). */ function node_entity_extra_field_info() { - $extra = array(); + $extra = []; $description = t('Node module element'); foreach (NodeType::loadMultiple() as $bundle) { - $extra['node'][$bundle->id()]['display']['links'] = array( + $extra['node'][$bundle->id()]['display']['links'] = [ 'label' => t('Links'), 'description' => $description, 'weight' => 100, 'visible' => TRUE, - ); + ]; } return $extra; @@ -442,7 +472,7 @@ function node_load_multiple(array $nids = NULL, $reset = FALSE) { */ function node_load($nid = NULL, $reset = FALSE) { if ($reset) { - \Drupal::entityManager()->getStorage('node')->resetCache(array($nid)); + \Drupal::entityManager()->getStorage('node')->resetCache([$nid]); } return Node::load($nid); } @@ -457,7 +487,7 @@ function node_load($nid = NULL, $reset = FALSE) { * A fully-populated node entity, or NULL if the node is not found. */ function node_revision_load($vid = NULL) { - return entity_revision_load('node', $vid); + return \Drupal::entityTypeManager()->getStorage('node')->loadRevision($vid); } /** @@ -499,16 +529,16 @@ function node_is_page(NodeInterface $node) { * @see node_add_page() */ function template_preprocess_node_add_list(&$variables) { - $variables['types'] = array(); + $variables['types'] = []; if (!empty($variables['content'])) { foreach ($variables['content'] as $type) { - $variables['types'][$type->id()] = array( + $variables['types'][$type->id()] = [ 'type' => $type->id(), - 'add_link' => \Drupal::l($type->label(), new Url('node.add', array('node_type' => $type->id()))), - 'description' => array( + 'add_link' => \Drupal::l($type->label(), new Url('node.add', ['node_type' => $type->id()])), + 'description' => [ '#markup' => $type->getDescription(), - ), - ); + ], + ]; } } } @@ -540,7 +570,7 @@ function node_preprocess_block(&$variables) { * Implements hook_theme_suggestions_HOOK(). */ function node_theme_suggestions_node(array $variables) { - $suggestions = array(); + $suggestions = []; $node = $variables['elements']['#node']; $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_'); @@ -575,23 +605,23 @@ function template_preprocess_node(&$variables) { $variables['node'] = $variables['elements']['#node']; /** @var \Drupal\node\NodeInterface $node */ $node = $variables['node']; - $variables['date'] = drupal_render($variables['elements']['created']); + $variables['date'] = \Drupal::service('renderer')->render($variables['elements']['created']); unset($variables['elements']['created']); - $variables['author_name'] = drupal_render($variables['elements']['uid']); + $variables['author_name'] = \Drupal::service('renderer')->render($variables['elements']['uid']); unset($variables['elements']['uid']); - $variables['url'] = $node->url('canonical', array( + $variables['url'] = $node->url('canonical', [ 'language' => $node->language(), - )); + ]); $variables['label'] = $variables['elements']['title']; unset($variables['elements']['title']); // The 'page' variable is set to TRUE in two occasions: // - The view mode is 'full' and we are on the 'node.view' route. // - The node is in preview and view mode is either 'full' or 'default'. - $variables['page'] = ($variables['view_mode'] == 'full' && (node_is_page($node)) || (isset($node->in_preview) && in_array($node->preview_view_mode, array('full', 'default')))); + $variables['page'] = ($variables['view_mode'] == 'full' && (node_is_page($node)) || (isset($node->in_preview) && in_array($node->preview_view_mode, ['full', 'default']))); // Helpful $content variable for templates. - $variables += array('content' => array()); + $variables += ['content' => []]; foreach (Element::children($variables['elements']) as $key) { $variables['content'][$key] = $variables['elements'][$key]; } @@ -630,10 +660,10 @@ function node_cron() { ->execute(); if (isset($result[0])) { // Make an array with definite keys and store it in the state system. - $array = array( + $array = [ 'min_created' => $result[0][$min_alias], 'max_created' => $result[0][$max_alias], - ); + ]; \Drupal::state()->set('node.min_max_update_time', $array); } } @@ -644,35 +674,35 @@ function node_cron() { */ function node_ranking() { // Create the ranking array and add the basic ranking options. - $ranking = array( - 'relevance' => array( + $ranking = [ + 'relevance' => [ 'title' => t('Keyword relevance'), // Average relevance values hover around 0.15 'score' => 'i.relevance', - ), - 'sticky' => array( + ], + 'sticky' => [ 'title' => t('Content is sticky at top of lists'), // The sticky flag is either 0 or 1, which is automatically normalized. 'score' => 'n.sticky', - ), - 'promote' => array( + ], + 'promote' => [ 'title' => t('Content is promoted to the front page'), // The promote flag is either 0 or 1, which is automatically normalized. 'score' => 'n.promote', - ), - ); + ], + ]; // Add relevance based on updated date, but only if it the scale values have // been calculated in node_cron(). if ($node_min_max = \Drupal::state()->get('node.min_max_update_time')) { - $ranking['recent'] = array( + $ranking['recent'] = [ 'title' => t('Recently created'), // Exponential decay with half life of 14% of the age range of nodes. 'score' => 'EXP(-5 * (1 - (n.created - :node_oldest) / :node_range))', - 'arguments' => array( + 'arguments' => [ ':node_oldest' => $node_min_max['min_created'], ':node_range' => max($node_min_max['max_created'] - $node_min_max['min_created'], 1), - ), - ); + ], + ]; } return $ranking; } @@ -688,17 +718,17 @@ function node_user_cancel($edit, $account, $method) { ->condition('uid', $account->id()) ->execute(); module_load_include('inc', 'node', 'node.admin'); - node_mass_update($nids, array('status' => 0), NULL, TRUE); + node_mass_update($nids, ['status' => 0], NULL, TRUE); break; case 'user_cancel_reassign': // Anonymize all of the nodes for this old account. module_load_include('inc', 'node', 'node.admin'); $vids = \Drupal::entityManager()->getStorage('node')->userRevisionIds($account); - node_mass_update($vids, array( + node_mass_update($vids, [ 'uid' => 0, 'revision_uid' => 0, - ), NULL, TRUE, TRUE); + ], NULL, TRUE, TRUE); break; } } @@ -711,6 +741,7 @@ function node_user_predelete($account) { // @todo Introduce node_mass_delete() or make node_mass_update() more flexible. $nids = \Drupal::entityQuery('node') ->condition('uid', $account->id()) + ->accessCheck(FALSE) ->execute(); entity_delete_multiple('node', $nids); // Delete old revisions. @@ -741,15 +772,15 @@ function node_get_recent($number = 10) { // have some unpublished nodes to view before adding the condition. $access_query = \Drupal::entityQuery('node') ->condition('uid', $account->id()) - ->condition('status', NODE_NOT_PUBLISHED); + ->condition('status', NodeInterface::NOT_PUBLISHED); if ($account->hasPermission('view own unpublished content') && ($own_unpublished = $access_query->execute())) { $query->orConditionGroup() - ->condition('status', NODE_PUBLISHED) + ->condition('status', NodeInterface::PUBLISHED) ->condition('nid', $own_unpublished, 'IN'); } else { // If not, restrict the query to published nodes. - $query->condition('status', NODE_PUBLISHED); + $query->condition('status', NodeInterface::PUBLISHED); } } $nids = $query @@ -760,7 +791,7 @@ function node_get_recent($number = 10) { $nodes = Node::loadMultiple($nids); - return $nodes ? $nodes : array(); + return $nodes ? $nodes : []; } /** @@ -806,12 +837,12 @@ function node_page_top(array &$page) { // Add 'Back to content editing' link on preview page. $route_match = \Drupal::routeMatch(); if ($route_match->getRouteName() == 'entity.node.preview') { - $page['page_top']['node_preview'] = array( + $page['page_top']['node_preview'] = [ '#type' => 'container', - '#attributes' => array( - 'class' => array('node-preview-container', 'container-inline') - ), - ); + '#attributes' => [ + 'class' => ['node-preview-container', 'container-inline'] + ], + ]; $form = \Drupal::formBuilder()->getForm('\Drupal\node\Form\NodePreviewForm', $route_match->getParameter('node_preview')); $page['page_top']['node_preview']['view_mode'] = $form; @@ -826,12 +857,12 @@ function node_page_top(array &$page) { * @see node_form_system_themes_admin_form_submit() */ function node_form_system_themes_admin_form_alter(&$form, FormStateInterface $form_state, $form_id) { - $form['admin_theme']['use_admin_theme'] = array( + $form['admin_theme']['use_admin_theme'] = [ '#type' => 'checkbox', '#title' => t('Use the administration theme when editing or creating content'), - '#description' => t('Control which roles can "View the administration theme" on the Permissions page.', array(':permissions' => Url::fromRoute('user.admin_permissions')->toString())), + '#description' => t('Control which roles can "View the administration theme" on the Permissions page.', [':permissions' => Url::fromRoute('user.admin_permissions')->toString()]), '#default_value' => \Drupal::configFactory()->getEditable('node.settings')->get('use_admin_theme'), - ); + ]; $form['#submit'][] = 'node_form_system_themes_admin_form_submit'; } @@ -951,11 +982,11 @@ function node_node_access(NodeInterface $node, $op, $account) { */ function node_access_grants($op, AccountInterface $account) { // Fetch node access grants from other modules. - $grants = \Drupal::moduleHandler()->invokeAll('node_grants', array($account, $op)); + $grants = \Drupal::moduleHandler()->invokeAll('node_grants', [$account, $op]); // Allow modules to alter the assigned grants. \Drupal::moduleHandler()->alter('node_grants', $grants, $account, $op); - return array_merge(array('all' => array(0)), $grants); + return array_merge(['all' => [0]], $grants); } /** @@ -1080,7 +1111,7 @@ function node_query_node_access_alter(AlterableInterface $query) { // context. $request = \Drupal::requestStack()->getCurrentRequest(); $renderer = \Drupal::service('renderer'); - if ($request->isMethodSafe() && $renderer->hasRenderContext()) { + if ($request->isMethodCacheable() && $renderer->hasRenderContext()) { $build = ['#cache' => ['contexts' => ['user.node_grants:' . $op]]]; $renderer->render($build); } @@ -1149,13 +1180,13 @@ function node_access_rebuild($batch_mode = FALSE) { // Only recalculate if the site is using a node_access module. if (count(\Drupal::moduleHandler()->getImplementations('node_grants'))) { if ($batch_mode) { - $batch = array( + $batch = [ 'title' => t('Rebuilding content access permissions'), - 'operations' => array( - array('_node_access_rebuild_batch_operation', array()), - ), + 'operations' => [ + ['_node_access_rebuild_batch_operation', []], + ], 'finished' => '_node_access_rebuild_batch_finished' - ); + ]; batch_set($batch); } else { @@ -1173,7 +1204,7 @@ function node_access_rebuild($batch_mode = FALSE) { $entity_query->accessCheck(FALSE); $nids = $entity_query->execute(); foreach ($nids as $nid) { - $node_storage->resetCache(array($nid)); + $node_storage->resetCache([$nid]); $node = Node::load($nid); // To preserve database integrity, only write grants if the node // loads successfully. diff --git a/core/modules/node/node.permissions.yml b/core/modules/node/node.permissions.yml index 753ed401..289227c7 100644 --- a/core/modules/node/node.permissions.yml +++ b/core/modules/node/node.permissions.yml @@ -18,12 +18,13 @@ view own unpublished content: title: 'View own unpublished content' view all revisions: title: 'View all revisions' + description: 'To view a revision, you also need permission to view the content item.' revert all revisions: title: 'Revert all revisions' - description: 'Role requires permission view revisions and edit rights for nodes in question or administer nodes.' + description: 'To revert a revision, you also need permission to edit the content item.' delete all revisions: title: 'Delete all revisions' - description: 'Role requires permission to view revisions and delete rights for nodes in question or administer nodes.' + description: 'To delete a revision, you also need permission to delete the content item.' permission_callbacks: - \Drupal\node\NodePermissions::nodeTypePermissions diff --git a/core/modules/node/node.post_update.php b/core/modules/node/node.post_update.php new file mode 100644 index 00000000..43e3cd6a --- /dev/null +++ b/core/modules/node/node.post_update.php @@ -0,0 +1,29 @@ +condition('targetEntityType', 'node'); + $ids = $query->execute(); + $form_displays = EntityFormDisplay::loadMultiple($ids); + + // Assign status settings for each 'node' target entity types with 'default' + // form mode. + foreach ($form_displays as $id => $form_display) { + /** @var \Drupal\Core\Entity\Display\EntityDisplayInterface $form_display */ + $form_display->setComponent('status', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ], + ])->save(); + } +} diff --git a/core/modules/node/node.preview.es6.js b/core/modules/node/node.preview.es6.js new file mode 100644 index 00000000..abd670ac --- /dev/null +++ b/core/modules/node/node.preview.es6.js @@ -0,0 +1,94 @@ +/** + * @file + * Preview behaviors. + */ + +(function ($, Drupal) { + /** + * Disables all non-relevant links in node previews. + * + * Destroys links (except local fragment identifiers such as href="#frag") in + * node previews to prevent users from leaving the page. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches confirmation prompt for clicking links in node preview mode. + * @prop {Drupal~behaviorDetach} detach + * Detaches confirmation prompt for clicking links in node preview mode. + */ + Drupal.behaviors.nodePreviewDestroyLinks = { + attach(context) { + function clickPreviewModal(event) { + // Only confirm leaving previews when left-clicking and user is not + // pressing the ALT, CTRL, META (Command key on the Macintosh keyboard) + // or SHIFT key. + if (event.button === 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { + event.preventDefault(); + const $previewDialog = $(`
    ${Drupal.theme('nodePreviewModal')}
    `).appendTo('body'); + Drupal.dialog($previewDialog, { + title: Drupal.t('Leave preview?'), + buttons: [ + { + text: Drupal.t('Cancel'), + click() { + $(this).dialog('close'); + }, + }, { + text: Drupal.t('Leave preview'), + click() { + window.top.location.href = event.target.href; + }, + }, + ], + }).showModal(); + } + } + + const $preview = $(context).find('.content').once('node-preview'); + if ($(context).find('.node-preview-container').length) { + $preview.on('click.preview', 'a:not([href^=#], #edit-backlink, #toolbar-administration a)', clickPreviewModal); + } + }, + detach(context, settings, trigger) { + if (trigger === 'unload') { + const $preview = $(context).find('.content').removeOnce('node-preview'); + if ($preview.length) { + $preview.off('click.preview'); + } + } + }, + }; + + /** + * Switch view mode. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches automatic submit on `formUpdated.preview` events. + */ + Drupal.behaviors.nodePreviewSwitchViewMode = { + attach(context) { + const $autosubmit = $(context).find('[data-drupal-autosubmit]').once('autosubmit'); + if ($autosubmit.length) { + $autosubmit.on('formUpdated.preview', function () { + $(this.form).trigger('submit'); + }); + } + }, + }; + + /** + * Theme function for node preview modal. + * + * @return {string} + * Markup for the node preview modal. + */ + Drupal.theme.nodePreviewModal = function () { + return `

    ${ + Drupal.t('Leaving the preview will cause unsaved changes to be lost. Are you sure you want to leave the preview?') + }

    ${ + Drupal.t('CTRL+Left click will prevent this dialog from showing and proceed to the clicked link.')}`; + }; +}(jQuery, Drupal)); diff --git a/core/modules/node/node.preview.js b/core/modules/node/node.preview.js index 4054183a..f18af286 100644 --- a/core/modules/node/node.preview.js +++ b/core/modules/node/node.preview.js @@ -1,50 +1,30 @@ /** - * @file - * Preview behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Disables all non-relevant links in node previews. - * - * Destroys links (except local fragment identifiers such as href="#frag") in - * node previews to prevent users from leaving the page. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches confirmation prompt for clicking links in node preview mode. - * @prop {Drupal~behaviorDetach} detach - * Detaches confirmation prompt for clicking links in node preview mode. - */ Drupal.behaviors.nodePreviewDestroyLinks = { - attach: function (context) { - + attach: function attach(context) { function clickPreviewModal(event) { - // Only confirm leaving previews when left-clicking and user is not - // pressing the ALT, CTRL, META (Command key on the Macintosh keyboard) - // or SHIFT key. if (event.button === 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { event.preventDefault(); var $previewDialog = $('
    ' + Drupal.theme('nodePreviewModal') + '
    ').appendTo('body'); Drupal.dialog($previewDialog, { title: Drupal.t('Leave preview?'), - buttons: [ - { - text: Drupal.t('Cancel'), - click: function () { - $(this).dialog('close'); - } - }, { - text: Drupal.t('Leave preview'), - click: function () { - window.top.location.href = event.target.href; - } + buttons: [{ + text: Drupal.t('Cancel'), + click: function click() { + $(this).dialog('close'); } - ] + }, { + text: Drupal.t('Leave preview'), + click: function click() { + window.top.location.href = event.target.href; + } + }] }).showModal(); } } @@ -54,7 +34,7 @@ $preview.on('click.preview', 'a:not([href^=#], #edit-backlink, #toolbar-administration a)', clickPreviewModal); } }, - detach: function (context, settings, trigger) { + detach: function detach(context, settings, trigger) { if (trigger === 'unload') { var $preview = $(context).find('.content').removeOnce('node-preview'); if ($preview.length) { @@ -64,16 +44,8 @@ } }; - /** - * Switch view mode. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches automatic submit on `formUpdated.preview` events. - */ Drupal.behaviors.nodePreviewSwitchViewMode = { - attach: function (context) { + attach: function attach(context) { var $autosubmit = $(context).find('[data-drupal-autosubmit]').once('autosubmit'); if ($autosubmit.length) { $autosubmit.on('formUpdated.preview', function () { @@ -83,17 +55,7 @@ } }; - /** - * Theme function for node preview modal. - * - * @return {string} - * Markup for the node preview modal. - */ Drupal.theme.nodePreviewModal = function () { - return '

    ' + - Drupal.t('Leaving the preview will cause unsaved changes to be lost. Are you sure you want to leave the preview?') + - '

    ' + - Drupal.t('CTRL+Left click will prevent this dialog from showing and proceed to the clicked link.') + ''; + return '

    ' + Drupal.t('Leaving the preview will cause unsaved changes to be lost. Are you sure you want to leave the preview?') + '

    ' + Drupal.t('CTRL+Left click will prevent this dialog from showing and proceed to the clicked link.') + ''; }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml index 7c942a2c..a016e3ac 100644 --- a/core/modules/node/node.routing.yml +++ b/core/modules/node/node.routing.yml @@ -113,6 +113,7 @@ entity.node_type.edit_form: path: '/admin/structure/types/manage/{node_type}' defaults: _entity_form: 'node_type.edit' + _title_callback: '\Drupal\Core\Entity\Controller\EntityController::title' requirements: _permission: 'administer content types' diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc index 81fa3f08..2fcf0ddf 100644 --- a/core/modules/node/node.tokens.inc +++ b/core/modules/node/node.tokens.inc @@ -14,71 +14,71 @@ use Drupal\user\Entity\User; * Implements hook_token_info(). */ function node_token_info() { - $type = array( + $type = [ 'name' => t('Nodes'), 'description' => t('Tokens related to individual content items, or "nodes".'), 'needs-data' => 'node', - ); + ]; // Core tokens for nodes. - $node['nid'] = array( + $node['nid'] = [ 'name' => t("Content ID"), 'description' => t('The unique ID of the content item, or "node".'), - ); - $node['vid'] = array( + ]; + $node['vid'] = [ 'name' => t("Revision ID"), 'description' => t("The unique ID of the node's latest revision."), - ); - $node['type'] = array( + ]; + $node['type'] = [ 'name' => t("Content type"), - ); - $node['type-name'] = array( + ]; + $node['type-name'] = [ 'name' => t("Content type name"), 'description' => t("The human-readable name of the node type."), - ); - $node['title'] = array( + ]; + $node['title'] = [ 'name' => t("Title"), - ); - $node['body'] = array( + ]; + $node['body'] = [ 'name' => t("Body"), 'description' => t("The main body text of the node."), - ); - $node['summary'] = array( + ]; + $node['summary'] = [ 'name' => t("Summary"), 'description' => t("The summary of the node's main body text."), - ); - $node['langcode'] = array( + ]; + $node['langcode'] = [ 'name' => t('Language code'), 'description' => t('The language code of the language the node is written in.'), - ); - $node['url'] = array( + ]; + $node['url'] = [ 'name' => t("URL"), 'description' => t("The URL of the node."), - ); - $node['edit-url'] = array( + ]; + $node['edit-url'] = [ 'name' => t("Edit URL"), 'description' => t("The URL of the node's edit page."), - ); + ]; // Chained tokens for nodes. - $node['created'] = array( + $node['created'] = [ 'name' => t("Date created"), 'type' => 'date', - ); - $node['changed'] = array( + ]; + $node['changed'] = [ 'name' => t("Date changed"), 'description' => t("The date the node was most recently updated."), 'type' => 'date', - ); - $node['author'] = array( + ]; + $node['author'] = [ 'name' => t("Author"), 'type' => 'user', - ); + ]; - return array( - 'types' => array('node' => $type), - 'tokens' => array('node' => $node), - ); + return [ + 'types' => ['node' => $type], + 'tokens' => ['node' => $node], + ]; } /** @@ -87,7 +87,7 @@ function node_token_info() { function node_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { $token_service = \Drupal::token(); - $url_options = array('absolute' => TRUE); + $url_options = ['absolute' => TRUE]; if (isset($options['langcode'])) { $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']); $langcode = $options['langcode']; @@ -95,7 +95,7 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta else { $langcode = LanguageInterface::LANGCODE_DEFAULT; } - $replacements = array(); + $replacements = []; if ($type == 'node' && !empty($data['node'])) { /** @var \Drupal\node\NodeInterface $node */ @@ -127,7 +127,7 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta case 'body': case 'summary': - $translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, array('operation' => 'node_tokens')); + $translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, ['operation' => 'node_tokens']); if ($translation->hasField('body') && ($items = $translation->get('body')) && !$items->isEmpty()) { $item = $items[0]; // If the summary was requested and is not empty, use it. @@ -195,15 +195,15 @@ function node_tokens($type, $tokens, array $data, array $options, BubbleableMeta } if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) { - $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getOwner()), $options, $bubbleable_metadata); + $replacements += $token_service->generate('user', $author_tokens, ['user' => $node->getOwner()], $options, $bubbleable_metadata); } if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) { - $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->getCreatedTime()), $options, $bubbleable_metadata); + $replacements += $token_service->generate('date', $created_tokens, ['date' => $node->getCreatedTime()], $options, $bubbleable_metadata); } if ($changed_tokens = $token_service->findWithPrefix($tokens, 'changed')) { - $replacements += $token_service->generate('date', $changed_tokens, array('date' => $node->getChangedTime()), $options, $bubbleable_metadata); + $replacements += $token_service->generate('date', $changed_tokens, ['date' => $node->getChangedTime()], $options, $bubbleable_metadata); } } diff --git a/core/modules/node/node.views_execution.inc b/core/modules/node/node.views_execution.inc index 193e4799..4d834a11 100644 --- a/core/modules/node/node.views_execution.inc +++ b/core/modules/node/node.views_execution.inc @@ -14,18 +14,18 @@ use Drupal\user\Entity\Role; */ function node_views_query_substitutions(ViewExecutable $view) { $account = \Drupal::currentUser(); - return array( + return [ '***ADMINISTER_NODES***' => intval($account->hasPermission('administer nodes')), '***VIEW_OWN_UNPUBLISHED_NODES***' => intval($account->hasPermission('view own unpublished content')), '***BYPASS_NODE_ACCESS***' => intval($account->hasPermission('bypass node access')), - ); + ]; } /** * Implements hook_views_analyze(). */ function node_views_analyze(ViewExecutable $view) { - $ret = array(); + $ret = []; // Check for something other than the default display: if ($view->storage->get('base_table') == 'node') { foreach ($view->displayHandlers as $display) { @@ -38,7 +38,7 @@ function node_views_analyze(ViewExecutable $view) { $authenticated_role = Role::load(RoleInterface::AUTHENTICATED_ID); $authenticated_has_access = $authenticated_role && $authenticated_role->hasPermission('access content'); if (!$anonymous_has_access || !$authenticated_has_access) { - $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display['display_title'])), 'warning'); + $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', ['%display' => $display->display['display_title']]), 'warning'); } $filters = $display->getOption('filters'); foreach ($filters as $filter) { @@ -46,7 +46,7 @@ function node_views_analyze(ViewExecutable $view) { continue 2; } } - $ret[] = Analyzer::formatMessage(t('Display %display has no access control but does not contain a filter for published nodes.', array('%display' => $display->display['display_title'])), 'warning'); + $ret[] = Analyzer::formatMessage(t('Display %display has no access control but does not contain a filter for published nodes.', ['%display' => $display->display['display_title']]), 'warning'); } } } @@ -54,7 +54,7 @@ function node_views_analyze(ViewExecutable $view) { foreach ($view->displayHandlers as $display) { if ($display->getPluginId() == 'page') { if ($display->getOption('path') == 'node/%') { - $ret[] = Analyzer::formatMessage(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', array('%display' => $display->display['display_title'])), 'warning'); + $ret[] = Analyzer::formatMessage(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', ['%display' => $display->display['display_title']]), 'warning'); } } } diff --git a/core/modules/node/src/Access/NodeRevisionAccessCheck.php b/core/modules/node/src/Access/NodeRevisionAccessCheck.php index 2005ec7e..b85d783a 100644 --- a/core/modules/node/src/Access/NodeRevisionAccessCheck.php +++ b/core/modules/node/src/Access/NodeRevisionAccessCheck.php @@ -35,7 +35,7 @@ class NodeRevisionAccessCheck implements AccessInterface { * * @var array */ - protected $access = array(); + protected $access = []; /** * Constructs a new NodeRevisionAccessCheck. @@ -90,17 +90,17 @@ public function access(Route $route, AccountInterface $account, $node_revision = * TRUE if the operation may be performed, FALSE otherwise. */ public function checkAccess(NodeInterface $node, AccountInterface $account, $op = 'view') { - $map = array( + $map = [ 'view' => 'view all revisions', 'update' => 'revert all revisions', 'delete' => 'delete all revisions', - ); + ]; $bundle = $node->bundle(); - $type_map = array( + $type_map = [ 'view' => "view $bundle revisions", 'update' => "revert $bundle revisions", 'delete' => "delete $bundle revisions", - ); + ]; if (!$node || !isset($map[$op]) || !isset($type_map[$op])) { // If there was no node to check against, or the $op was not one of the diff --git a/core/modules/node/src/ContextProvider/NodeRouteContext.php b/core/modules/node/src/ContextProvider/NodeRouteContext.php index 2b745e9e..2e10a8a6 100644 --- a/core/modules/node/src/ContextProvider/NodeRouteContext.php +++ b/core/modules/node/src/ContextProvider/NodeRouteContext.php @@ -48,7 +48,7 @@ public function getRuntimeContexts(array $unqualified_context_ids) { } elseif ($this->routeMatch->getRouteName() == 'node.add') { $node_type = $this->routeMatch->getParameter('node_type'); - $value = Node::create(array('type' => $node_type->id())); + $value = Node::create(['type' => $node_type->id()]); } $cacheability = new CacheableMetadata(); diff --git a/core/modules/node/src/Controller/NodeController.php b/core/modules/node/src/Controller/NodeController.php index 048b949c..48401475 100644 --- a/core/modules/node/src/Controller/NodeController.php +++ b/core/modules/node/src/Controller/NodeController.php @@ -74,7 +74,7 @@ public function addPage() { ], ]; - $content = array(); + $content = []; // Only use node types the user has access to. foreach ($this->entityManager()->getStorage('node_type')->loadMultiple() as $type) { @@ -88,7 +88,7 @@ public function addPage() { // Bypass the node/add listing if only one content type is available. if (count($content) == 1) { $type = array_shift($content); - return $this->redirect('node.add', array('node_type' => $type->id())); + return $this->redirect('node.add', ['node_type' => $type->id()]); } $build['#content'] = $content; @@ -106,9 +106,9 @@ public function addPage() { * A node submission form. */ public function add(NodeTypeInterface $node_type) { - $node = $this->entityManager()->getStorage('node')->create(array( + $node = $this->entityManager()->getStorage('node')->create([ 'type' => $node_type->id(), - )); + ]); $form = $this->entityFormBuilder()->getForm($node); @@ -144,7 +144,7 @@ public function revisionShow($node_revision) { */ public function revisionPageTitle($node_revision) { $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision); - return $this->t('Revision of %title from %date', array('%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime()))); + return $this->t('Revision of %title from %date', ['%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime())]); } /** @@ -166,12 +166,12 @@ public function revisionOverview(NodeInterface $node) { $type = $node->getType(); $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]); - $header = array($this->t('Revision'), $this->t('Operations')); + $header = [$this->t('Revision'), $this->t('Operations')]; $revert_permission = (($account->hasPermission("revert $type revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update')); $delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete')); - $rows = array(); + $rows = []; $default_revision = $node->getRevisionId(); foreach ($this->getRevisionIds($node, $node_storage) as $vid) { @@ -254,17 +254,17 @@ public function revisionOverview(NodeInterface $node) { } } - $build['node_revisions_table'] = array( + $build['node_revisions_table'] = [ '#theme' => 'table', '#rows' => $rows, '#header' => $header, - '#attached' => array( - 'library' => array('node/drupal.node.admin'), - ), + '#attached' => [ + 'library' => ['node/drupal.node.admin'], + ], '#attributes' => ['class' => 'node-revision-table'], - ); + ]; - $build['pager'] = array('#type' => 'pager'); + $build['pager'] = ['#type' => 'pager']; return $build; } @@ -279,7 +279,7 @@ public function revisionOverview(NodeInterface $node) { * The page title. */ public function addPageTitle(NodeTypeInterface $node_type) { - return $this->t('Create @name', array('@name' => $node_type->label())); + return $this->t('Create @name', ['@name' => $node_type->label()]); } /** diff --git a/core/modules/node/src/Controller/NodeViewController.php b/core/modules/node/src/Controller/NodeViewController.php index fce50e14..b8aa1e5a 100644 --- a/core/modules/node/src/Controller/NodeViewController.php +++ b/core/modules/node/src/Controller/NodeViewController.php @@ -68,24 +68,24 @@ public function view(EntityInterface $node, $view_mode = 'full', $langcode = NUL // metadata if we have to check access. if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) { // Set the node path as the canonical URL to prevent duplicate content. - $build['#attached']['html_head_link'][] = array( - array( + $build['#attached']['html_head_link'][] = [ + [ 'rel' => $rel, 'href' => $url->toString(), - ), + ], TRUE, - ); + ]; } if ($rel == 'canonical') { // Set the non-aliased canonical path as a default shortlink. - $build['#attached']['html_head_link'][] = array( - array( + $build['#attached']['html_head_link'][] = [ + [ 'rel' => 'shortlink', 'href' => $url->setOption('alias', TRUE)->toString(), - ), + ], TRUE, - ); + ]; } } diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php index bdb80500..368ce1b5 100644 --- a/core/modules/node/src/Entity/Node.php +++ b/core/modules/node/src/Entity/Node.php @@ -2,8 +2,7 @@ namespace Drupal\node\Entity; -use Drupal\Core\Entity\ContentEntityBase; -use Drupal\Core\Entity\EntityChangedTrait; +use Drupal\Core\Entity\EditorialContentEntityBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; @@ -17,6 +16,7 @@ * @ContentEntityType( * id = "node", * label = @Translation("Content"), + * label_collection = @Translation("Content"), * label_singular = @Translation("content item"), * label_plural = @Translation("content items"), * label_count = @PluralTranslation( @@ -45,6 +45,7 @@ * data_table = "node_field_data", * revision_table = "node_revision", * revision_data_table = "node_field_revision", + * show_revision_ui = TRUE, * translatable = TRUE, * list_cache_contexts = { "user.node_grants:view" }, * entity_keys = { @@ -55,8 +56,14 @@ * "langcode" = "langcode", * "uuid" = "uuid", * "status" = "status", + * "published" = "status", * "uid" = "uid", * }, + * revision_metadata_keys = { + * "revision_user" = "revision_uid", + * "revision_created" = "revision_timestamp", + * "revision_log_message" = "revision_log" + * }, * bundle_entity_type = "node_type", * field_ui_base_route = "entity.node_type.edit_form", * common_reference_target = TRUE, @@ -67,12 +74,11 @@ * "edit-form" = "/node/{node}/edit", * "version-history" = "/node/{node}/revisions", * "revision" = "/node/{node}/revisions/{node_revision}/view", + * "create" = "/node", * } * ) */ -class Node extends ContentEntityBase implements NodeInterface { - - use EntityChangedTrait; +class Node extends EditorialContentEntityBase implements NodeInterface { /** * Whether the node is being previewed or not. @@ -224,7 +230,7 @@ public function isPromoted() { * {@inheritdoc} */ public function setPromoted($promoted) { - $this->set('promote', $promoted ? NODE_PROMOTED : NODE_NOT_PROMOTED); + $this->set('promote', $promoted ? NodeInterface::PROMOTED : NodeInterface::NOT_PROMOTED); return $this; } @@ -239,21 +245,7 @@ public function isSticky() { * {@inheritdoc} */ public function setSticky($sticky) { - $this->set('sticky', $sticky ? NODE_STICKY : NODE_NOT_STICKY); - return $this; - } - /** - * {@inheritdoc} - */ - public function isPublished() { - return (bool) $this->getEntityKey('status'); - } - - /** - * {@inheritdoc} - */ - public function setPublished($published) { - $this->set('status', $published ? NODE_PUBLISHED : NODE_NOT_PUBLISHED); + $this->set('sticky', $sticky ? NodeInterface::STICKY : NodeInterface::NOT_STICKY); return $this; } @@ -287,21 +279,6 @@ public function setOwner(UserInterface $account) { return $this; } - /** - * {@inheritdoc} - */ - public function getRevisionCreationTime() { - return $this->get('revision_timestamp')->value; - } - - /** - * {@inheritdoc} - */ - public function setRevisionCreationTime($timestamp) { - $this->set('revision_timestamp', $timestamp); - return $this; - } - /** * {@inheritdoc} */ @@ -309,13 +286,6 @@ public function getRevisionAuthor() { return $this->getRevisionUser(); } - /** - * {@inheritdoc} - */ - public function getRevisionUser() { - return $this->get('revision_uid')->entity; - } - /** * {@inheritdoc} */ @@ -324,44 +294,6 @@ public function setRevisionAuthorId($uid) { return $this; } - /** - * {@inheritdoc} - */ - public function setRevisionUser(UserInterface $user) { - $this->set('revision_uid', $user); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRevisionUserId() { - return $this->get('revision_uid')->entity->id(); - } - - /** - * {@inheritdoc} - */ - public function setRevisionUserId($user_id) { - $this->set('revision_uid', $user_id); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRevisionLogMessage() { - return $this->get('revision_log')->value; - } - - /** - * {@inheritdoc} - */ - public function setRevisionLogMessage($revision_log_message) { - $this->set('revision_log', $revision_log_message); - return $this; - } - /** * {@inheritdoc} */ @@ -374,15 +306,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setTranslatable(TRUE) ->setRevisionable(TRUE) ->setSetting('max_length', 255) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'string', 'weight' => -5, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -5, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['uid'] = BaseFieldDefinition::create('entity_reference') @@ -392,43 +324,46 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setSetting('target_type', 'user') ->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId') ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'author', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 5, - 'settings' => array( + 'settings' => [ 'match_operator' => 'CONTAINS', 'size' => '60', 'placeholder' => '', - ), - )) + ], + ]) ->setDisplayConfigurable('form', TRUE); - $fields['status'] = BaseFieldDefinition::create('boolean') - ->setLabel(t('Publishing status')) - ->setDescription(t('A boolean indicating whether the node is published.')) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE) - ->setDefaultValue(TRUE); + $fields['status'] + ->setDisplayOptions('form', [ + 'type' => 'boolean_checkbox', + 'settings' => [ + 'display_label' => TRUE, + ], + 'weight' => 120, + ]) + ->setDisplayConfigurable('form', TRUE); $fields['created'] = BaseFieldDefinition::create('created') ->setLabel(t('Authored on')) ->setDescription(t('The time that the node was created.')) ->setRevisionable(TRUE) ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'timestamp', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'datetime_timestamp', 'weight' => 10, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['changed'] = BaseFieldDefinition::create('changed') @@ -442,13 +377,13 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDefaultValue(TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'boolean_checkbox', - 'settings' => array( + 'settings' => [ 'display_label' => TRUE, - ), + ], 'weight' => 15, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['sticky'] = BaseFieldDefinition::create('boolean') @@ -456,48 +391,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDefaultValue(FALSE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'boolean_checkbox', - 'settings' => array( + 'settings' => [ 'display_label' => TRUE, - ), + ], 'weight' => 16, - )) + ]) ->setDisplayConfigurable('form', TRUE); - $fields['revision_timestamp'] = BaseFieldDefinition::create('created') - ->setLabel(t('Revision timestamp')) - ->setDescription(t('The time that the current revision was created.')) - ->setQueryable(FALSE) - ->setRevisionable(TRUE); - - $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Revision user ID')) - ->setDescription(t('The user ID of the author of the current revision.')) - ->setSetting('target_type', 'user') - ->setQueryable(FALSE) - ->setRevisionable(TRUE); - - $fields['revision_log'] = BaseFieldDefinition::create('string_long') - ->setLabel(t('Revision log message')) - ->setDescription(t('Briefly describe the changes you have made.')) - ->setRevisionable(TRUE) - ->setDefaultValue('') - ->setDisplayOptions('form', array( - 'type' => 'string_textarea', - 'weight' => 25, - 'settings' => array( - 'rows' => 4, - ), - )); - - $fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean') - ->setLabel(t('Revision translation affected')) - ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.')) - ->setReadOnly(TRUE) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - return $fields; } @@ -510,7 +412,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { * An array of default values. */ public static function getCurrentUserId() { - return array(\Drupal::currentUser()->id()); + return [\Drupal::currentUser()->id()]; } } diff --git a/core/modules/node/src/Entity/NodeRouteProvider.php b/core/modules/node/src/Entity/NodeRouteProvider.php index 0803f1ef..6ac3ae1c 100644 --- a/core/modules/node/src/Entity/NodeRouteProvider.php +++ b/core/modules/node/src/Entity/NodeRouteProvider.php @@ -15,7 +15,7 @@ class NodeRouteProvider implements EntityRouteProviderInterface { /** * {@inheritdoc} */ - public function getRoutes( EntityTypeInterface $entity_type) { + public function getRoutes(EntityTypeInterface $entity_type) { $route_collection = new RouteCollection(); $route = (new Route('/node/{node}')) ->addDefaults([ diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php index 91d8a909..e4a4c3b6 100644 --- a/core/modules/node/src/Entity/NodeType.php +++ b/core/modules/node/src/Entity/NodeType.php @@ -182,10 +182,10 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { drupal_set_message(\Drupal::translation()->formatPlural($update_count, 'Changed the content type of 1 post from %old-type to %type.', 'Changed the content type of @count posts from %old-type to %type.', - array( + [ '%old-type' => $this->getOriginalId(), '%type' => $this->id(), - ))); + ])); } } if ($update) { @@ -205,4 +205,11 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti $storage->resetCache(array_keys($entities)); } + /** + * {@inheritdoc} + */ + public function shouldCreateNewRevision() { + return $this->isNewRevision(); + } + } diff --git a/core/modules/node/src/EventSubscriber/NodeTranslationExceptionSubscriber.php b/core/modules/node/src/EventSubscriber/NodeTranslationExceptionSubscriber.php new file mode 100644 index 00000000..795670fc --- /dev/null +++ b/core/modules/node/src/EventSubscriber/NodeTranslationExceptionSubscriber.php @@ -0,0 +1,128 @@ +keyValue = $key_value; + $this->languageManager = $language_manager; + $this->urlGenerator = $url_generator; + $this->state = $state; + } + + /** + * Redirects not found node translations using the key value collection. + * + * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event + * The exception event. + */ + public function onException(GetResponseForExceptionEvent $event) { + $exception = $event->getException(); + + // If this is not a 404, we don't need to check for a redirection. + if (!($exception instanceof NotFoundHttpException)) { + return; + } + + $previous_exception = $exception->getPrevious(); + if ($previous_exception instanceof ParamNotConvertedException) { + $route_name = $previous_exception->getRouteName(); + $parameters = $previous_exception->getRawParameters(); + if ($route_name === 'entity.node.canonical' && isset($parameters['node'])) { + // If the node_translation_redirect state is not set, we don't need to check + // for a redirection. + if (!$this->state->get('node_translation_redirect')) { + return; + } + $old_nid = $parameters['node']; + $collection = $this->keyValue->get('node_translation_redirect'); + if ($old_nid && $value = $collection->get($old_nid)) { + list($nid, $langcode) = $value; + $language = $this->languageManager->getLanguage($langcode); + $url = $this->urlGenerator->generateFromRoute('entity.node.canonical', ['node' => $nid], ['language' => $language]); + $response = new RedirectResponse($url, 301); + $event->setResponse($response); + } + } + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events = []; + + $events[KernelEvents::EXCEPTION] = ['onException']; + + return $events; + } + +} diff --git a/core/modules/node/src/EventSubscriber/NodeTranslationMigrateSubscriber.php b/core/modules/node/src/EventSubscriber/NodeTranslationMigrateSubscriber.php new file mode 100644 index 00000000..5911f0e0 --- /dev/null +++ b/core/modules/node/src/EventSubscriber/NodeTranslationMigrateSubscriber.php @@ -0,0 +1,113 @@ +keyValue = $key_value; + $this->state = $state; + } + + /** + * Helper method to check if we are migrating translated nodes. + * + * @param \Drupal\migrate\Event\EventBase $event + * The migrate event. + * + * @return bool + * True if we are migrating translated nodes, false otherwise. + */ + protected function isNodeTranslationsMigration(EventBase $event) { + $migration = $event->getMigration(); + $source_configuration = $migration->getSourceConfiguration(); + $destination_configuration = $migration->getDestinationConfiguration(); + return !empty($source_configuration['translations']) && $destination_configuration['plugin'] === 'entity:node'; + } + + /** + * Maps the old nid to the new one in the key value collection. + * + * @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event + * The migrate post row save event. + */ + public function onPostRowSave(MigratePostRowSaveEvent $event) { + if ($this->isNodeTranslationsMigration($event)) { + $row = $event->getRow(); + $source = $row->getSource(); + $destination = $row->getDestination(); + $collection = $this->keyValue->get('node_translation_redirect'); + $collection->set($source['nid'], [$destination['nid'], $destination['langcode']]); + } + } + + /** + * Set the node_translation_redirect state to enable the redirections. + * + * @param \Drupal\migrate\Event\MigrateImportEvent $event + * The migrate import event. + */ + public function onPostImport(MigrateImportEvent $event) { + if ($this->isNodeTranslationsMigration($event)) { + $this->state->set('node_translation_redirect', TRUE); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events = []; + + $events[MigrateEvents::POST_ROW_SAVE] = ['onPostRowSave']; + $events[MigrateEvents::POST_IMPORT] = ['onPostImport']; + + return $events; + } + +} diff --git a/core/modules/node/src/Form/DeleteMultiple.php b/core/modules/node/src/Form/DeleteMultiple.php index 7066b94c..91d8ad4a 100644 --- a/core/modules/node/src/Form/DeleteMultiple.php +++ b/core/modules/node/src/Form/DeleteMultiple.php @@ -20,7 +20,7 @@ class DeleteMultiple extends ConfirmFormBase { * * @var string[][] */ - protected $nodeInfo = array(); + protected $nodeInfo = []; /** * The tempstore factory. @@ -130,10 +130,10 @@ public function buildForm(array $form, FormStateInterface $form_state) { } } - $form['nodes'] = array( + $form['nodes'] = [ '#theme' => 'item_list', '#items' => $items, - ); + ]; $form = parent::buildForm($form, $form_state); return $form; @@ -167,7 +167,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { if ($delete_nodes) { $this->storage->delete($delete_nodes); - $this->logger('content')->notice('Deleted @count posts.', array('@count' => count($delete_nodes))); + $this->logger('content')->notice('Deleted @count posts.', ['@count' => count($delete_nodes)]); } if ($delete_translations) { @@ -182,7 +182,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } if ($count) { $total_count += $count; - $this->logger('content')->notice('Deleted @count content translations.', array('@count' => $count)); + $this->logger('content')->notice('Deleted @count content translations.', ['@count' => $count]); } } diff --git a/core/modules/node/src/Form/NodeDeleteForm.php b/core/modules/node/src/Form/NodeDeleteForm.php index 7afac867..da8c2025 100644 --- a/core/modules/node/src/Form/NodeDeleteForm.php +++ b/core/modules/node/src/Form/NodeDeleteForm.php @@ -27,10 +27,10 @@ protected function getDeletionMessage() { ]); } - return $this->t('The @type %title has been deleted.', array( + return $this->t('The @type %title has been deleted.', [ '@type' => $node_type, '%title' => $this->getEntity()->label(), - )); + ]); } /** diff --git a/core/modules/node/src/Form/NodePreviewForm.php b/core/modules/node/src/Form/NodePreviewForm.php index 829fee10..8b6125b8 100644 --- a/core/modules/node/src/Form/NodePreviewForm.php +++ b/core/modules/node/src/Form/NodePreviewForm.php @@ -72,18 +72,18 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $node = NULL) { $view_mode = $node->preview_view_mode; - $query_options = array('query' => array('uuid' => $node->uuid())); + $query_options = ['query' => ['uuid' => $node->uuid()]]; $query = $this->getRequest()->query; if ($query->has('destination')) { $query_options['query']['destination'] = $query->get('destination'); } - $form['backlink'] = array( + $form['backlink'] = [ '#type' => 'link', '#title' => $this->t('Back to content editing'), '#url' => $node->isNew() ? Url::fromRoute('node.add', ['node_type' => $node->bundle()]) : $node->urlInfo('edit-form'), - '#options' => array('attributes' => array('class' => array('node-preview-backlink'))) + $query_options, - ); + '#options' => ['attributes' => ['class' => ['node-preview-backlink']]] + $query_options, + ]; // Always show full as an option, even if the display is not enabled. $view_mode_options = ['full' => $this->t('Full')] + $this->entityManager->getViewModeOptionsByBundle('node', $node->bundle()); @@ -93,28 +93,28 @@ public function buildForm(array $form, FormStateInterface $form_state, EntityInt unset($view_mode_options['rss']); unset($view_mode_options['search_index']); - $form['uuid'] = array( + $form['uuid'] = [ '#type' => 'value', '#value' => $node->uuid(), - ); + ]; - $form['view_mode'] = array( + $form['view_mode'] = [ '#type' => 'select', '#title' => $this->t('View mode'), '#options' => $view_mode_options, '#default_value' => $view_mode, - '#attributes' => array( + '#attributes' => [ 'data-drupal-autosubmit' => TRUE, - ) - ); + ] + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Switch'), - '#attributes' => array( - 'class' => array('js-hide'), - ), - ); + '#attributes' => [ + 'class' => ['js-hide'], + ], + ]; return $form; } diff --git a/core/modules/node/src/Form/NodeRevisionDeleteForm.php b/core/modules/node/src/Form/NodeRevisionDeleteForm.php index 27eec48e..86e5b59c 100644 --- a/core/modules/node/src/Form/NodeRevisionDeleteForm.php +++ b/core/modules/node/src/Form/NodeRevisionDeleteForm.php @@ -81,14 +81,14 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()))); + return t('Are you sure you want to delete the revision from %revision-date?', ['%revision-date' => format_date($this->revision->getRevisionCreationTime())]); } /** * {@inheritdoc} */ public function getCancelUrl() { - return new Url('entity.node.version_history', array('node' => $this->revision->id())); + return new Url('entity.node.version_history', ['node' => $this->revision->id()]); } /** @@ -114,17 +114,17 @@ public function buildForm(array $form, FormStateInterface $form_state, $node_rev public function submitForm(array &$form, FormStateInterface $form_state) { $this->nodeStorage->deleteRevision($this->revision->getRevisionId()); - $this->logger('content')->notice('@type: deleted %title revision %revision.', array('@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId())); + $this->logger('content')->notice('@type: deleted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]); $node_type = $this->nodeTypeStorage->load($this->revision->bundle())->label(); - drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label()))); + drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', ['%revision-date' => format_date($this->revision->getRevisionCreationTime()), '@type' => $node_type, '%title' => $this->revision->label()])); $form_state->setRedirect( 'entity.node.canonical', - array('node' => $this->revision->id()) + ['node' => $this->revision->id()] ); - if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $this->revision->id()))->fetchField() > 1) { + if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $this->revision->id()])->fetchField() > 1) { $form_state->setRedirect( 'entity.node.version_history', - array('node' => $this->revision->id()) + ['node' => $this->revision->id()] ); } } diff --git a/core/modules/node/src/Form/NodeRevisionRevertForm.php b/core/modules/node/src/Form/NodeRevisionRevertForm.php index 275d55ba..8137c3f4 100644 --- a/core/modules/node/src/Form/NodeRevisionRevertForm.php +++ b/core/modules/node/src/Form/NodeRevisionRevertForm.php @@ -2,6 +2,7 @@ namespace Drupal\node\Form; +use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\Datetime\DateFormatterInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Form\ConfirmFormBase; @@ -36,6 +37,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase { */ protected $dateFormatter; + /** + * The time service. + * + * @var \Drupal\Component\Datetime\TimeInterface + */ + protected $time; + /** * Constructs a new NodeRevisionRevertForm. * @@ -43,10 +51,13 @@ class NodeRevisionRevertForm extends ConfirmFormBase { * The node storage. * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter * The date formatter service. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. */ - public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter) { + public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, TimeInterface $time) { $this->nodeStorage = $node_storage; $this->dateFormatter = $date_formatter; + $this->time = $time; } /** @@ -55,7 +66,8 @@ public function __construct(EntityStorageInterface $node_storage, DateFormatterI public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager')->getStorage('node'), - $container->get('date.formatter') + $container->get('date.formatter'), + $container->get('datetime.time') ); } @@ -77,7 +89,7 @@ public function getQuestion() { * {@inheritdoc} */ public function getCancelUrl() { - return new Url('entity.node.version_history', array('node' => $this->revision->id())); + return new Url('entity.node.version_history', ['node' => $this->revision->id()]); } /** @@ -114,13 +126,15 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->revision = $this->prepareRevertedRevision($this->revision, $form_state); $this->revision->revision_log = t('Copy of the revision from %date.', ['%date' => $this->dateFormatter->format($original_revision_timestamp)]); + $this->revision->setRevisionCreationTime($this->time->getRequestTime()); + $this->revision->setChangedTime($this->time->getRequestTime()); $this->revision->save(); $this->logger('content')->notice('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]); drupal_set_message(t('@type %title has been reverted to the revision from %revision-date.', ['@type' => node_get_type_label($this->revision), '%title' => $this->revision->label(), '%revision-date' => $this->dateFormatter->format($original_revision_timestamp)])); $form_state->setRedirect( 'entity.node.version_history', - array('node' => $this->revision->id()) + ['node' => $this->revision->id()] ); } diff --git a/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php b/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php index 05a4f6c4..d5da697a 100644 --- a/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php +++ b/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php @@ -2,6 +2,7 @@ namespace Drupal\node\Form; +use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\Datetime\DateFormatterInterface; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Form\FormStateInterface; @@ -37,9 +38,11 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm { * The date formatter service. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * The language manager. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. */ - public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager) { - parent::__construct($node_storage, $date_formatter); + public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager, TimeInterface $time) { + parent::__construct($node_storage, $date_formatter, $time); $this->languageManager = $language_manager; } @@ -50,7 +53,8 @@ public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager')->getStorage('node'), $container->get('date.formatter'), - $container->get('language_manager') + $container->get('language_manager'), + $container->get('datetime.time') ); } @@ -82,11 +86,11 @@ public function buildForm(array $form, FormStateInterface $form_state, $node_rev $this->langcode = $langcode; $form = parent::buildForm($form, $form_state, $node_revision); - $form['revert_untranslated_fields'] = array( + $form['revert_untranslated_fields'] = [ '#type' => 'checkbox', '#title' => $this->t('Revert content shared among translations'), '#default_value' => FALSE, - ); + ]; return $form; } diff --git a/core/modules/node/src/Form/NodeTypeDeleteConfirm.php b/core/modules/node/src/Form/NodeTypeDeleteConfirm.php index ada9fd55..e4bea83f 100644 --- a/core/modules/node/src/Form/NodeTypeDeleteConfirm.php +++ b/core/modules/node/src/Form/NodeTypeDeleteConfirm.php @@ -2,54 +2,26 @@ namespace Drupal\node\Form; -use Drupal\Core\Entity\Query\QueryFactory; use Drupal\Core\Entity\EntityDeleteForm; use Drupal\Core\Form\FormStateInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a form for content type deletion. */ class NodeTypeDeleteConfirm extends EntityDeleteForm { - /** - * The query factory to create entity queries. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $queryFactory; - - /** - * Constructs a new NodeTypeDeleteConfirm object. - * - * @param \Drupal\Core\Entity\Query\QueryFactory $query_factory - * The entity query object. - */ - public function __construct(QueryFactory $query_factory) { - $this->queryFactory = $query_factory; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.query') - ); - } - /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $num_nodes = $this->queryFactory->get('node') + $num_nodes = $this->entityTypeManager->getStorage('node')->getQuery() ->condition('type', $this->entity->id()) ->count() ->execute(); if ($num_nodes) { - $caption = '

    ' . $this->formatPlural($num_nodes, '%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', '%type is used by @count pieces of content on your site. You may not remove %type until you have removed all of the %type content.', array('%type' => $this->entity->label())) . '

    '; + $caption = '

    ' . $this->formatPlural($num_nodes, '%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', '%type is used by @count pieces of content on your site. You may not remove %type until you have removed all of the %type content.', ['%type' => $this->entity->label()]) . '

    '; $form['#title'] = $this->getQuestion(); - $form['description'] = array('#markup' => $caption); + $form['description'] = ['#markup' => $caption]; return $form; } diff --git a/core/modules/node/src/NodeAccessControlHandler.php b/core/modules/node/src/NodeAccessControlHandler.php index 988de9e3..a8a0bc62 100644 --- a/core/modules/node/src/NodeAccessControlHandler.php +++ b/core/modules/node/src/NodeAccessControlHandler.php @@ -62,17 +62,18 @@ public function access(EntityInterface $entity, $operation, AccountInterface $ac return $return_as_object ? $result : $result->isAllowed(); } if (!$account->hasPermission('access content')) { - $result = AccessResult::forbidden()->cachePerPermissions(); + $result = AccessResult::forbidden("The 'access content' permission is required.")->cachePerPermissions(); return $return_as_object ? $result : $result->isAllowed(); } $result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions(); + return $return_as_object ? $result : $result->isAllowed(); } /** * {@inheritdoc} */ - public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = array(), $return_as_object = FALSE) { + public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) { $account = $this->prepareUser($account); if ($account->hasPermission('bypass node access')) { @@ -120,13 +121,13 @@ protected function checkCreateAccess(AccountInterface $account, array $context, protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) { // Only users with the administer nodes permission can edit administrative // fields. - $administrative_fields = array('uid', 'status', 'created', 'promote', 'sticky'); + $administrative_fields = ['uid', 'status', 'created', 'promote', 'sticky']; if ($operation == 'edit' && in_array($field_definition->getName(), $administrative_fields, TRUE)) { return AccessResult::allowedIfHasPermission($account, 'administer nodes'); } // No user can change read only fields. - $read_only_fields = array('revision_timestamp', 'revision_uid'); + $read_only_fields = ['revision_timestamp', 'revision_uid']; if ($operation == 'edit' && in_array($field_definition->getName(), $read_only_fields, TRUE)) { return AccessResult::forbidden(); } @@ -146,12 +147,12 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_ * {@inheritdoc} */ public function acquireGrants(NodeInterface $node) { - $grants = $this->moduleHandler->invokeAll('node_access_records', array($node)); + $grants = $this->moduleHandler->invokeAll('node_access_records', [$node]); // Let modules alter the grants. $this->moduleHandler->alter('node_access_records', $grants, $node); // If no grants are set and the node is published, then use the default grant. if (empty($grants) && $node->isPublished()) { - $grants[] = array('realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0); + $grants[] = ['realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0]; } return $grants; } diff --git a/core/modules/node/src/NodeAccessControlHandlerInterface.php b/core/modules/node/src/NodeAccessControlHandlerInterface.php index 47205f0d..7d407c1f 100644 --- a/core/modules/node/src/NodeAccessControlHandlerInterface.php +++ b/core/modules/node/src/NodeAccessControlHandlerInterface.php @@ -23,7 +23,7 @@ interface NodeAccessControlHandlerInterface { * @param \Drupal\node\NodeInterface $node * The $node to acquire grants for. * - * @return array $grants + * @return array * The access rules for the node. */ public function acquireGrants(NodeInterface $node); @@ -74,7 +74,7 @@ public function countGrants(); * A user object representing the user for whom the operation is to be * performed. * - * @return int. + * @return int * Status of the access check. */ public function checkAllGrants(AccountInterface $account); diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php index 3dd8a959..4c9bbac7 100644 --- a/core/modules/node/src/NodeForm.php +++ b/core/modules/node/src/NodeForm.php @@ -2,9 +2,12 @@ namespace Drupal\node; +use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\user\PrivateTempStoreFactory; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -21,24 +24,30 @@ class NodeForm extends ContentEntityForm { protected $tempStoreFactory; /** - * Whether this node has been previewed or not. + * The Current User object. * - * @deprecated Scheduled for removal in Drupal 8.3.x. Use the form state - * property 'has_been_previewed' instead. + * @var \Drupal\Core\Session\AccountInterface */ - protected $hasBeenPreviewed = FALSE; + protected $currentUser; /** - * Constructs a ContentEntityForm object. + * Constructs a NodeForm object. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory * The factory for the temp store object. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info + * The entity type bundle service. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. + * @param \Drupal\Core\Session\AccountInterface $current_user + * The current user. */ - public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory) { - parent::__construct($entity_manager); + public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL, AccountInterface $current_user) { + parent::__construct($entity_manager, $entity_type_bundle_info, $time); $this->tempStoreFactory = $temp_store_factory; + $this->currentUser = $current_user; } /** @@ -47,29 +56,17 @@ public function __construct(EntityManagerInterface $entity_manager, PrivateTempS public static function create(ContainerInterface $container) { return new static( $container->get('entity.manager'), - $container->get('user.private_tempstore') + $container->get('user.private_tempstore'), + $container->get('entity_type.bundle.info'), + $container->get('datetime.time'), + $container->get('current_user') ); } - /** - * {@inheritdoc} - */ - protected function prepareEntity() { - /** @var \Drupal\node\NodeInterface $node */ - $node = $this->entity; - - if (!$node->isNew()) { - // Remove the revision log message from the original node entity. - $node->revision_log = NULL; - } - } - /** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { - $this->hasBeenPreviewed = $form_state->get('has_been_previewed') ?: FALSE; - // Try to restore from temp store, this must be done before calling // parent::form(). $store = $this->tempStoreFactory->get('node_preview'); @@ -95,80 +92,79 @@ public function form(array $form, FormStateInterface $form_state) { $this->entity->in_preview = NULL; $form_state->set('has_been_previewed', TRUE); - $this->hasBeenPreviewed = TRUE; } /** @var \Drupal\node\NodeInterface $node */ $node = $this->entity; if ($this->operation == 'edit') { - $form['#title'] = $this->t('Edit @type @title', array('@type' => node_get_type_label($node), '@title' => $node->label())); + $form['#title'] = $this->t('Edit @type @title', [ + '@type' => node_get_type_label($node), + '@title' => $node->label() + ]); } - $current_user = $this->currentUser(); - // Changed must be sent to the client, for later overwrite error checking. - $form['changed'] = array( + $form['changed'] = [ '#type' => 'hidden', '#default_value' => $node->getChangedTime(), - ); + ]; - $form['advanced'] = array( - '#type' => 'vertical_tabs', - '#attributes' => array('class' => array('entity-meta')), - '#weight' => 99, - ); $form = parent::form($form, $form_state); - // Add a revision_log field if the "Create new revision" option is checked, - // or if the current user has the ability to check that option. - $form['revision_information'] = array( + $form['advanced']['#attributes']['class'][] = 'entity-meta'; + + $form['meta'] = [ '#type' => 'details', '#group' => 'advanced', - '#title' => t('Revision information'), - // Open by default when "Create new revision" is checked. - '#open' => $node->isNewRevision(), - '#attributes' => array( - 'class' => array('node-form-revision-information'), - ), - '#attached' => array( - 'library' => array('node/drupal.node'), - ), - '#weight' => 20, - '#optional' => TRUE, - ); - - $form['revision'] = array( - '#type' => 'checkbox', - '#title' => t('Create new revision'), - '#default_value' => $node->type->entity->isNewRevision(), - '#access' => $current_user->hasPermission('administer nodes'), - '#group' => 'revision_information', - ); + '#weight' => -10, + '#title' => $this->t('Status'), + '#attributes' => ['class' => ['entity-meta__header']], + '#tree' => TRUE, + '#access' => $this->currentUser->hasPermission('administer nodes'), + ]; + $form['meta']['published'] = [ + '#type' => 'item', + '#markup' => $node->isPublished() ? $this->t('Published') : $this->t('Not published'), + '#access' => !$node->isNew(), + '#wrapper_attributes' => ['class' => ['entity-meta__title']], + ]; + $form['meta']['changed'] = [ + '#type' => 'item', + '#title' => $this->t('Last saved'), + '#markup' => !$node->isNew() ? format_date($node->getChangedTime(), 'short') : $this->t('Not saved yet'), + '#wrapper_attributes' => ['class' => ['entity-meta__last-saved']], + ]; + $form['meta']['author'] = [ + '#type' => 'item', + '#title' => $this->t('Author'), + '#markup' => $node->getOwner()->getUsername(), + '#wrapper_attributes' => ['class' => ['entity-meta__author']], + ]; - $form['revision_log'] += array( - '#states' => array( - 'visible' => array( - ':input[name="revision"]' => array('checked' => TRUE), - ), - ), - '#group' => 'revision_information', - ); + $form['footer'] = [ + '#type' => 'container', + '#weight' => 99, + '#attributes' => [ + 'class' => ['node-form-footer'] + ] + ]; + $form['status']['#group'] = 'footer'; // Node author information for administrators. - $form['author'] = array( + $form['author'] = [ '#type' => 'details', '#title' => t('Authoring information'), '#group' => 'advanced', - '#attributes' => array( - 'class' => array('node-form-author'), - ), - '#attached' => array( - 'library' => array('node/drupal.node'), - ), + '#attributes' => [ + 'class' => ['node-form-author'], + ], + '#attached' => [ + 'library' => ['node/drupal.node'], + ], '#weight' => 90, '#optional' => TRUE, - ); + ]; if (isset($form['uid'])) { $form['uid']['#group'] = 'author'; @@ -179,19 +175,19 @@ public function form(array $form, FormStateInterface $form_state) { } // Node options for administrators. - $form['options'] = array( + $form['options'] = [ '#type' => 'details', '#title' => t('Promotion options'), '#group' => 'advanced', - '#attributes' => array( - 'class' => array('node-form-options'), - ), - '#attached' => array( - 'library' => array('node/drupal.node'), - ), + '#attributes' => [ + 'class' => ['node-form-options'], + ], + '#attached' => [ + 'library' => ['node/drupal.node'], + ], '#weight' => 95, '#optional' => TRUE, - ); + ]; if (isset($form['promote'])) { $form['promote']['#group'] = 'options'; @@ -203,8 +199,6 @@ public function form(array $form, FormStateInterface $form_state) { $form['#attached']['library'][] = 'node/form'; - $form['#entity_builders']['update_status'] = [$this, 'updateStatus']; - return $form; } @@ -221,8 +215,11 @@ public function form(array $form, FormStateInterface $form_state) { * The current state of the form. * * @see \Drupal\node\NodeForm::form() + * + * @deprecated in Drupal 8.4.x, will be removed before Drupal 9.0.0. + * The "Publish" button was removed. */ - function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) { + public function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) { $element = $form_state->getTriggeringElement(); if (isset($element['#published_status'])) { $node->setPublished($element['#published_status']); @@ -239,66 +236,13 @@ protected function actions(array $form, FormStateInterface $form_state) { $element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed'); - // If saving is an option, privileged users get dedicated form submit - // buttons to adjust the publishing status while saving in one go. - // @todo This adjustment makes it close to impossible for contributed - // modules to integrate with "the Save operation" of this form. Modules - // need a way to plug themselves into 1) the ::submit() step, and - // 2) the ::save() step, both decoupled from the pressed form button. - if ($element['submit']['#access'] && \Drupal::currentUser()->hasPermission('administer nodes')) { - // isNew | prev status » default & publish label & unpublish label - // 1 | 1 » publish & Save and publish & Save as unpublished - // 1 | 0 » unpublish & Save and publish & Save as unpublished - // 0 | 1 » publish & Save and keep published & Save and unpublish - // 0 | 0 » unpublish & Save and keep unpublished & Save and publish - - // Add a "Publish" button. - $element['publish'] = $element['submit']; - // If the "Publish" button is clicked, we want to update the status to "published". - $element['publish']['#published_status'] = TRUE; - $element['publish']['#dropbutton'] = 'save'; - if ($node->isNew()) { - $element['publish']['#value'] = t('Save and publish'); - } - else { - $element['publish']['#value'] = $node->isPublished() ? t('Save and keep published') : t('Save and publish'); - } - $element['publish']['#weight'] = 0; - - // Add a "Unpublish" button. - $element['unpublish'] = $element['submit']; - // If the "Unpublish" button is clicked, we want to update the status to "unpublished". - $element['unpublish']['#published_status'] = FALSE; - $element['unpublish']['#dropbutton'] = 'save'; - if ($node->isNew()) { - $element['unpublish']['#value'] = t('Save as unpublished'); - } - else { - $element['unpublish']['#value'] = !$node->isPublished() ? t('Save and keep unpublished') : t('Save and unpublish'); - } - $element['unpublish']['#weight'] = 10; - - // If already published, the 'publish' button is primary. - if ($node->isPublished()) { - unset($element['unpublish']['#button_type']); - } - // Otherwise, the 'unpublish' button is primary and should come first. - else { - unset($element['publish']['#button_type']); - $element['unpublish']['#weight'] = -10; - } - - // Remove the "Save" button. - $element['submit']['#access'] = FALSE; - } - - $element['preview'] = array( + $element['preview'] = [ '#type' => 'submit', '#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')), '#value' => t('Preview'), '#weight' => 20, - '#submit' => array('::submitForm', '::preview'), - ); + '#submit' => ['::submitForm', '::preview'], + ]; $element['delete']['#access'] = $node->access('delete'); $element['delete']['#weight'] = 100; @@ -306,32 +250,6 @@ protected function actions(array $form, FormStateInterface $form_state) { return $element; } - /** - * {@inheritdoc} - * - * Updates the node object by processing the submitted values. - * - * This function can be called by a "Next" button of a wizard to update the - * form state's entity with the current step's values before proceeding to the - * next step. - */ - public function submitForm(array &$form, FormStateInterface $form_state) { - // Build the node object from the submitted values. - parent::submitForm($form, $form_state); - $node = $this->entity; - - // Save as a new revision if requested to do so. - if (!$form_state->isValueEmpty('revision') && $form_state->getValue('revision') != FALSE) { - $node->setNewRevision(); - // If a new revision is created, save the current user as revision author. - $node->setRevisionCreationTime(REQUEST_TIME); - $node->setRevisionUserId(\Drupal::currentUser()->id()); - } - else { - $node->setNewRevision(FALSE); - } - } - /** * Form submission handler for the 'preview' action. * @@ -367,8 +285,8 @@ public function save(array $form, FormStateInterface $form_state) { $insert = $node->isNew(); $node->save(); $node_link = $node->link($this->t('View')); - $context = array('@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link); - $t_args = array('@type' => node_get_type_label($node), '%title' => $node->link($node->label())); + $context = ['@type' => $node->getType(), '%title' => $node->label(), 'link' => $node_link]; + $t_args = ['@type' => node_get_type_label($node), '%title' => $node->link($node->label())]; if ($insert) { $this->logger('content')->notice('@type: added %title.', $context); @@ -385,7 +303,7 @@ public function save(array $form, FormStateInterface $form_state) { if ($node->access('view')) { $form_state->setRedirect( 'entity.node.canonical', - array('node' => $node->id()) + ['node' => $node->id()] ); } else { diff --git a/core/modules/node/src/NodeGrantDatabaseStorage.php b/core/modules/node/src/NodeGrantDatabaseStorage.php index a0a13371..f6ae1f6c 100644 --- a/core/modules/node/src/NodeGrantDatabaseStorage.php +++ b/core/modules/node/src/NodeGrantDatabaseStorage.php @@ -138,7 +138,7 @@ public function checkAll(AccountInterface $account) { $grants = static::buildGrantsQueryCondition(node_access_grants('view', $account)); - if (count($grants) > 0 ) { + if (count($grants) > 0) { $query->condition($grants); } return $query->execute()->fetchField(); @@ -161,7 +161,7 @@ public function alterQuery($query, array $tables, $op, AccountInterface $account if (!($table instanceof SelectInterface) && $table == $base_table) { // Set the subquery. $subquery = $this->database->select('node_access', 'na') - ->fields('na', array('nid')); + ->fields('na', ['nid']); // If any grant exists for the specified user, then user has access to the // node for the specified operation. @@ -202,13 +202,13 @@ public function write(NodeInterface $node, array $grants, $realm = NULL, $delete if ($delete) { $query = $this->database->delete('node_access')->condition('nid', $node->id()); if ($realm) { - $query->condition('realm', array($realm, 'all'), 'IN'); + $query->condition('realm', [$realm, 'all'], 'IN'); } $query->execute(); } // Only perform work when node_access modules are active. if (!empty($grants) && count($this->moduleHandler->getImplementations('node_grants'))) { - $query = $this->database->insert('node_access')->fields(array('nid', 'langcode', 'fallback', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete')); + $query = $this->database->insert('node_access')->fields(['nid', 'langcode', 'fallback', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete']); // If we have defined a granted langcode, use it. But if not, add a grant // for every language this node is translated to. foreach ($grants as $grant) { @@ -216,7 +216,7 @@ public function write(NodeInterface $node, array $grants, $realm = NULL, $delete continue; } if (isset($grant['langcode'])) { - $grant_languages = array($grant['langcode'] => $this->languageManager->getLanguage($grant['langcode'])); + $grant_languages = [$grant['langcode'] => $this->languageManager->getLanguage($grant['langcode'])]; } else { $grant_languages = $node->getTranslationLanguages(TRUE); @@ -253,14 +253,14 @@ public function delete() { */ public function writeDefault() { $this->database->insert('node_access') - ->fields(array( + ->fields([ 'nid' => 0, 'realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, - )) + ]) ->execute(); } diff --git a/core/modules/node/src/NodeGrantDatabaseStorageInterface.php b/core/modules/node/src/NodeGrantDatabaseStorageInterface.php index 659ce101..329d9a10 100644 --- a/core/modules/node/src/NodeGrantDatabaseStorageInterface.php +++ b/core/modules/node/src/NodeGrantDatabaseStorageInterface.php @@ -18,7 +18,7 @@ interface NodeGrantDatabaseStorageInterface { * A user object representing the user for whom the operation is to be * performed. * - * @return int. + * @return int * Status of the access check. */ public function checkAll(AccountInterface $account); @@ -31,11 +31,11 @@ public function checkAll(AccountInterface $account); * @param array $tables * A list of tables that need to be part of the alter. * @param string $op - * The operation to be performed on the node. Possible values are: - * - "view" - * - "update" - * - "delete" - * - "create" + * The operation to be performed on the node. Possible values are: + * - "view" + * - "update" + * - "delete" + * - "create" * @param \Drupal\Core\Session\AccountInterface $account * A user object representing the user for whom the operation is to be * performed. diff --git a/core/modules/node/src/NodeInterface.php b/core/modules/node/src/NodeInterface.php index 980dacd0..87b68927 100644 --- a/core/modules/node/src/NodeInterface.php +++ b/core/modules/node/src/NodeInterface.php @@ -2,6 +2,7 @@ namespace Drupal\node; +use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Entity\RevisionLogInterface; use Drupal\user\EntityOwnerInterface; use Drupal\Core\Entity\EntityChangedInterface; @@ -10,7 +11,37 @@ /** * Provides an interface defining a node entity. */ -interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface { +interface NodeInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface, EntityPublishedInterface { + + /** + * Denotes that the node is not published. + */ + const NOT_PUBLISHED = 0; + + /** + * Denotes that the node is published. + */ + const PUBLISHED = 1; + + /** + * Denotes that the node is not promoted to the front page. + */ + const NOT_PROMOTED = 0; + + /** + * Denotes that the node is promoted to the front page. + */ + const PROMOTED = 1; + + /** + * Denotes that the node is not sticky at the top of the page. + */ + const NOT_STICKY = 0; + + /** + * Denotes that the node is sticky at the top of the page. + */ + const STICKY = 1; /** * Gets the node type. @@ -96,27 +127,6 @@ public function isSticky(); */ public function setSticky($sticky); - /** - * Returns the node published status indicator. - * - * Unpublished nodes are only visible to their authors and to administrators. - * - * @return bool - * TRUE if the node is published. - */ - public function isPublished(); - - /** - * Sets the published status of a node.. - * - * @param bool $published - * TRUE to set this node to published, FALSE to set it to unpublished. - * - * @return \Drupal\node\NodeInterface - * The called node entity. - */ - public function setPublished($published); - /** * Gets the node revision creation timestamp. * diff --git a/core/modules/node/src/NodeListBuilder.php b/core/modules/node/src/NodeListBuilder.php index 921ac9f3..4dbdf27b 100644 --- a/core/modules/node/src/NodeListBuilder.php +++ b/core/modules/node/src/NodeListBuilder.php @@ -68,27 +68,27 @@ public static function createInstance(ContainerInterface $container, EntityTypeI */ public function buildHeader() { // Enable language column and filter if multiple languages are added. - $header = array( + $header = [ 'title' => $this->t('Title'), - 'type' => array( + 'type' => [ 'data' => $this->t('Content type'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ), - 'author' => array( + 'class' => [RESPONSIVE_PRIORITY_MEDIUM], + ], + 'author' => [ 'data' => $this->t('Author'), - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ), + 'class' => [RESPONSIVE_PRIORITY_LOW], + ], 'status' => $this->t('Status'), - 'changed' => array( + 'changed' => [ 'data' => $this->t('Updated'), - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ), - ); + 'class' => [RESPONSIVE_PRIORITY_LOW], + ], + ]; if (\Drupal::languageManager()->isMultilingual()) { - $header['language_name'] = array( + $header['language_name'] = [ 'data' => $this->t('Language'), - 'class' => array(RESPONSIVE_PRIORITY_LOW), - ); + 'class' => [RESPONSIVE_PRIORITY_LOW], + ]; } return $header + parent::buildHeader(); } @@ -98,26 +98,26 @@ public function buildHeader() { */ public function buildRow(EntityInterface $entity) { /** @var \Drupal\node\NodeInterface $entity */ - $mark = array( + $mark = [ '#theme' => 'mark', '#mark_type' => node_mark($entity->id(), $entity->getChangedTime()), - ); + ]; $langcode = $entity->language()->getId(); $uri = $entity->urlInfo(); $options = $uri->getOptions(); - $options += ($langcode != LanguageInterface::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? array('language' => $languages[$langcode]) : array()); + $options += ($langcode != LanguageInterface::LANGCODE_NOT_SPECIFIED && isset($languages[$langcode]) ? ['language' => $languages[$langcode]] : []); $uri->setOptions($options); - $row['title']['data'] = array( + $row['title']['data'] = [ '#type' => 'link', '#title' => $entity->label(), - '#suffix' => ' ' . drupal_render($mark), + '#suffix' => ' ' . \Drupal::service('renderer')->render($mark), '#url' => $uri, - ); + ]; $row['type'] = node_get_type_label($entity); - $row['author']['data'] = array( + $row['author']['data'] = [ '#theme' => 'username', '#account' => $entity->getOwner(), - ); + ]; $row['status'] = $entity->isPublished() ? $this->t('published') : $this->t('not published'); $row['changed'] = $this->dateFormatter->format($entity->getChangedTime(), 'short'); $language_manager = \Drupal::languageManager(); diff --git a/core/modules/node/src/NodePermissions.php b/core/modules/node/src/NodePermissions.php index 94b2d935..1996360a 100644 --- a/core/modules/node/src/NodePermissions.php +++ b/core/modules/node/src/NodePermissions.php @@ -22,7 +22,7 @@ class NodePermissions { * @see \Drupal\user\PermissionHandlerInterface::getPermissions() */ public function nodeTypePermissions() { - $perms = array(); + $perms = []; // Generate node permissions for all node types. foreach (NodeType::loadMultiple() as $type) { $perms += $this->buildPermissions($type); @@ -42,36 +42,37 @@ public function nodeTypePermissions() { */ protected function buildPermissions(NodeType $type) { $type_id = $type->id(); - $type_params = array('%type_name' => $type->label()); + $type_params = ['%type_name' => $type->label()]; - return array( - "create $type_id content" => array( + return [ + "create $type_id content" => [ 'title' => $this->t('%type_name: Create new content', $type_params), - ), - "edit own $type_id content" => array( + ], + "edit own $type_id content" => [ 'title' => $this->t('%type_name: Edit own content', $type_params), - ), - "edit any $type_id content" => array( + ], + "edit any $type_id content" => [ 'title' => $this->t('%type_name: Edit any content', $type_params), - ), - "delete own $type_id content" => array( + ], + "delete own $type_id content" => [ 'title' => $this->t('%type_name: Delete own content', $type_params), - ), - "delete any $type_id content" => array( + ], + "delete any $type_id content" => [ 'title' => $this->t('%type_name: Delete any content', $type_params), - ), - "view $type_id revisions" => array( + ], + "view $type_id revisions" => [ 'title' => $this->t('%type_name: View revisions', $type_params), - ), - "revert $type_id revisions" => array( + 'description' => t('To view a revision, you also need permission to view the content item.'), + ], + "revert $type_id revisions" => [ 'title' => $this->t('%type_name: Revert revisions', $type_params), - 'description' => t('Role requires permission view revisions and edit rights for nodes in question, or administer nodes.'), - ), - "delete $type_id revisions" => array( + 'description' => t('To revert a revision, you also need permission to edit the content item.'), + ], + "delete $type_id revisions" => [ 'title' => $this->t('%type_name: Delete revisions', $type_params), - 'description' => $this->t('Role requires permission to view revisions and delete rights for nodes in question, or administer nodes.'), - ), - ); + 'description' => $this->t('To delete a revision, you also need permission to delete the content item.'), + ], + ]; } } diff --git a/core/modules/node/src/NodeServiceProvider.php b/core/modules/node/src/NodeServiceProvider.php new file mode 100644 index 00000000..8d258172 --- /dev/null +++ b/core/modules/node/src/NodeServiceProvider.php @@ -0,0 +1,42 @@ +getParameter('container.modules'); + if (isset($modules['migrate']) && isset($modules['language'])) { + $container->register('node.node_translation_migrate', NodeTranslationMigrateSubscriber::class) + ->addTag('event_subscriber') + ->addArgument(new Reference('keyvalue')) + ->addArgument(new Reference('state')); + } + + // Register the node.node_translation_exception service in the container if + // the language module is enabled. + if (isset($modules['language'])) { + $container->register('node.node_translation_exception', NodeTranslationExceptionSubscriber::class) + ->addTag('event_subscriber') + ->addArgument(new Reference('keyvalue')) + ->addArgument(new Reference('language_manager')) + ->addArgument(new Reference('url_generator')) + ->addArgument(new Reference('state')); + } + } + +} diff --git a/core/modules/node/src/NodeStorage.php b/core/modules/node/src/NodeStorage.php index 3c720930..af85a067 100644 --- a/core/modules/node/src/NodeStorage.php +++ b/core/modules/node/src/NodeStorage.php @@ -20,7 +20,7 @@ class NodeStorage extends SqlContentEntityStorage implements NodeStorageInterfac public function revisionIds(NodeInterface $node) { return $this->database->query( 'SELECT vid FROM {node_revision} WHERE nid=:nid ORDER BY vid', - array(':nid' => $node->id()) + [':nid' => $node->id()] )->fetchCol(); } @@ -30,7 +30,7 @@ public function revisionIds(NodeInterface $node) { public function userRevisionIds(AccountInterface $account) { return $this->database->query( 'SELECT vid FROM {node_field_revision} WHERE uid = :uid ORDER BY vid', - array(':uid' => $account->id()) + [':uid' => $account->id()] )->fetchCol(); } @@ -38,7 +38,7 @@ public function userRevisionIds(AccountInterface $account) { * {@inheritdoc} */ public function countDefaultLanguageRevisions(NodeInterface $node) { - return $this->database->query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', array(':nid' => $node->id()))->fetchField(); + return $this->database->query('SELECT COUNT(*) FROM {node_field_revision} WHERE nid = :nid AND default_langcode = 1', [':nid' => $node->id()])->fetchField(); } /** @@ -46,7 +46,7 @@ public function countDefaultLanguageRevisions(NodeInterface $node) { */ public function updateType($old_type, $new_type) { return $this->database->update('node') - ->fields(array('type' => $new_type)) + ->fields(['type' => $new_type]) ->condition('type', $old_type) ->execute(); } @@ -56,7 +56,7 @@ public function updateType($old_type, $new_type) { */ public function clearRevisionsLanguage(LanguageInterface $language) { return $this->database->update('node_revision') - ->fields(array('langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)) + ->fields(['langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED]) ->condition('langcode', $language->getId()) ->execute(); } diff --git a/core/modules/node/src/NodeStorageSchema.php b/core/modules/node/src/NodeStorageSchema.php index 43bd465d..ac45bb5d 100644 --- a/core/modules/node/src/NodeStorageSchema.php +++ b/core/modules/node/src/NodeStorageSchema.php @@ -17,11 +17,10 @@ class NodeStorageSchema extends SqlContentEntityStorageSchema { protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { $schema = parent::getEntitySchema($entity_type, $reset); - $schema['node_field_data']['indexes'] += array( - 'node__frontpage' => array('promote', 'status', 'sticky', 'created'), - 'node__status_type' => array('status', 'type', 'nid'), - 'node__title_type' => array('title', array('type', 4)), - ); + $schema['node_field_data']['indexes'] += [ + 'node__frontpage' => ['promote', 'status', 'sticky', 'created'], + 'node__title_type' => ['title', ['type', 4]], + ]; return $schema; } diff --git a/core/modules/node/src/NodeTranslationHandler.php b/core/modules/node/src/NodeTranslationHandler.php index 9c9741e1..ead0d5d5 100644 --- a/core/modules/node/src/NodeTranslationHandler.php +++ b/core/modules/node/src/NodeTranslationHandler.php @@ -17,17 +17,7 @@ class NodeTranslationHandler extends ContentTranslationHandler { public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { parent::entityFormAlter($form, $form_state, $entity); - // Move the translation fieldset to a vertical tab. if (isset($form['content_translation'])) { - $form['content_translation'] += array( - '#group' => 'advanced', - '#attributes' => array( - 'class' => array('node-translation-options'), - ), - ); - - $form['content_translation']['#weight'] = 100; - // We do not need to show these values on node forms: they inherit the // basic node property values. $form['content_translation']['status']['#access'] = FALSE; @@ -49,7 +39,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En } } if (isset($status_translatable)) { - foreach (array('publish', 'unpublish', 'submit') as $button) { + foreach (['publish', 'unpublish', 'submit'] as $button) { if (isset($form['actions'][$button])) { $form['actions'][$button]['#value'] .= ' ' . ($status_translatable ? t('(this translation)') : t('(all translations)')); } @@ -63,7 +53,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En */ protected function entityFormTitle(EntityInterface $entity) { $type_name = node_get_type_label($entity); - return t('Edit @type @title', array('@type' => $type_name, '@title' => $entity->label())); + return t('Edit @type @title', ['@type' => $type_name, '@title' => $entity->label()]); } /** diff --git a/core/modules/node/src/NodeTypeForm.php b/core/modules/node/src/NodeTypeForm.php index d5fb9982..abef502e 100644 --- a/core/modules/node/src/NodeTypeForm.php +++ b/core/modules/node/src/NodeTypeForm.php @@ -54,134 +54,134 @@ public function form(array $form, FormStateInterface $form_state) { // get the default values for workflow settings. // @todo Make it possible to get default values without an entity. // https://www.drupal.org/node/2318187 - $node = $this->entityManager->getStorage('node')->create(array('type' => $type->uuid())); + $node = $this->entityManager->getStorage('node')->create(['type' => $type->uuid()]); } else { - $form['#title'] = $this->t('Edit %label content type', array('%label' => $type->label())); + $form['#title'] = $this->t('Edit %label content type', ['%label' => $type->label()]); $fields = $this->entityManager->getFieldDefinitions('node', $type->id()); // Create a node to get the current values for workflow settings fields. - $node = $this->entityManager->getStorage('node')->create(array('type' => $type->id())); + $node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]); } - $form['name'] = array( + $form['name'] = [ '#title' => t('Name'), '#type' => 'textfield', '#default_value' => $type->label(), '#description' => t('The human-readable name of this content type. This text will be displayed as part of the list on the Add content page. This name must be unique.'), '#required' => TRUE, '#size' => 30, - ); + ]; - $form['type'] = array( + $form['type'] = [ '#type' => 'machine_name', '#default_value' => $type->id(), '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH, '#disabled' => $type->isLocked(), - '#machine_name' => array( + '#machine_name' => [ 'exists' => ['Drupal\node\Entity\NodeType', 'load'], - 'source' => array('name'), - ), - '#description' => t('A unique machine-readable name for this content type. It must only contain lowercase letters, numbers, and underscores. This name will be used for constructing the URL of the %node-add page, in which underscores will be converted into hyphens.', array( + 'source' => ['name'], + ], + '#description' => t('A unique machine-readable name for this content type. It must only contain lowercase letters, numbers, and underscores. This name will be used for constructing the URL of the %node-add page, in which underscores will be converted into hyphens.', [ '%node-add' => t('Add content'), - )), - ); + ]), + ]; - $form['description'] = array( + $form['description'] = [ '#title' => t('Description'), '#type' => 'textarea', '#default_value' => $type->getDescription(), '#description' => t('This text will be displayed on the Add new content page.'), - ); + ]; - $form['additional_settings'] = array( + $form['additional_settings'] = [ '#type' => 'vertical_tabs', - '#attached' => array( - 'library' => array('node/drupal.content_types'), - ), - ); + '#attached' => [ + 'library' => ['node/drupal.content_types'], + ], + ]; - $form['submission'] = array( + $form['submission'] = [ '#type' => 'details', '#title' => t('Submission form settings'), '#group' => 'additional_settings', '#open' => TRUE, - ); - $form['submission']['title_label'] = array( + ]; + $form['submission']['title_label'] = [ '#title' => t('Title field label'), '#type' => 'textfield', '#default_value' => $fields['title']->getLabel(), '#required' => TRUE, - ); - $form['submission']['preview_mode'] = array( + ]; + $form['submission']['preview_mode'] = [ '#type' => 'radios', '#title' => t('Preview before submitting'), '#default_value' => $type->getPreviewMode(), - '#options' => array( + '#options' => [ DRUPAL_DISABLED => t('Disabled'), DRUPAL_OPTIONAL => t('Optional'), DRUPAL_REQUIRED => t('Required'), - ), - ); - $form['submission']['help'] = array( + ], + ]; + $form['submission']['help'] = [ '#type' => 'textarea', '#title' => t('Explanation or submission guidelines'), '#default_value' => $type->getHelp(), '#description' => t('This text will be displayed at the top of the page when creating or editing content of this type.'), - ); - $form['workflow'] = array( + ]; + $form['workflow'] = [ '#type' => 'details', '#title' => t('Publishing options'), '#group' => 'additional_settings', - ); - $workflow_options = array( + ]; + $workflow_options = [ 'status' => $node->status->value, 'promote' => $node->promote->value, 'sticky' => $node->sticky->value, 'revision' => $type->isNewRevision(), - ); + ]; // Prepare workflow options to be used for 'checkboxes' form element. $keys = array_keys(array_filter($workflow_options)); $workflow_options = array_combine($keys, $keys); - $form['workflow']['options'] = array( + $form['workflow']['options'] = [ '#type' => 'checkboxes', '#title' => t('Default options'), '#default_value' => $workflow_options, - '#options' => array( + '#options' => [ 'status' => t('Published'), 'promote' => t('Promoted to front page'), 'sticky' => t('Sticky at top of lists'), 'revision' => t('Create new revision'), - ), + ], '#description' => t('Users with the Administer content permission will be able to override these options.'), - ); + ]; if ($this->moduleHandler->moduleExists('language')) { - $form['language'] = array( + $form['language'] = [ '#type' => 'details', '#title' => t('Language settings'), '#group' => 'additional_settings', - ); + ]; $language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('node', $type->id()); - $form['language']['language_configuration'] = array( + $form['language']['language_configuration'] = [ '#type' => 'language_configuration', - '#entity_information' => array( + '#entity_information' => [ 'entity_type' => 'node', 'bundle' => $type->id(), - ), + ], '#default_value' => $language_configuration, - ); + ]; } - $form['display'] = array( + $form['display'] = [ '#type' => 'details', '#title' => t('Display settings'), '#group' => 'additional_settings', - ); - $form['display']['display_submitted'] = array( + ]; + $form['display']['display_submitted'] = [ '#type' => 'checkbox', '#title' => t('Display author and date information'), '#default_value' => $type->displaySubmitted(), '#description' => t('Author username and publish date will be displayed.'), - ); + ]; return $this->protectBundleIdElement($form); } @@ -205,7 +205,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { $id = trim($form_state->getValue('type')); // '0' is invalid, since elsewhere we check it using empty(). if ($id == '0') { - $form_state->setErrorByName('type', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", array('%invalid' => $id))); + $form_state->setErrorByName('type', $this->t("Invalid machine-readable name. Enter a name other than %invalid.", ['%invalid' => $id])); } } @@ -214,13 +214,13 @@ public function validateForm(array &$form, FormStateInterface $form_state) { */ public function save(array $form, FormStateInterface $form_state) { $type = $this->entity; - $type->setNewRevision($form_state->getValue(array('options', 'revision'))); + $type->setNewRevision($form_state->getValue(['options', 'revision'])); $type->set('type', trim($type->id())); $type->set('name', trim($type->label())); $status = $type->save(); - $t_args = array('%name' => $type->label()); + $t_args = ['%name' => $type->label()]; if ($status == SAVED_UPDATED) { drupal_set_message(t('The content type %name has been updated.', $t_args)); @@ -228,7 +228,7 @@ public function save(array $form, FormStateInterface $form_state) { elseif ($status == SAVED_NEW) { node_add_body_field($type); drupal_set_message(t('The content type %name has been added.', $t_args)); - $context = array_merge($t_args, array('link' => $type->link($this->t('View'), 'collection'))); + $context = array_merge($t_args, ['link' => $type->link($this->t('View'), 'collection')]); $this->logger('node')->notice('Added content type %name.', $context); } @@ -242,8 +242,8 @@ public function save(array $form, FormStateInterface $form_state) { // Update workflow options. // @todo Make it possible to get default values without an entity. // https://www.drupal.org/node/2318187 - $node = $this->entityManager->getStorage('node')->create(array('type' => $type->id())); - foreach (array('status', 'promote', 'sticky') as $field_name) { + $node = $this->entityManager->getStorage('node')->create(['type' => $type->id()]); + foreach (['status', 'promote', 'sticky'] as $field_name) { $value = (bool) $form_state->getValue(['options', $field_name]); if ($node->$field_name->value != $value) { $fields[$field_name]->getConfig($type->id())->setDefaultValue($value)->save(); diff --git a/core/modules/node/src/NodeTypeInterface.php b/core/modules/node/src/NodeTypeInterface.php index c034ffbe..df4831e5 100644 --- a/core/modules/node/src/NodeTypeInterface.php +++ b/core/modules/node/src/NodeTypeInterface.php @@ -3,11 +3,12 @@ namespace Drupal\node; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\RevisionableEntityBundleInterface; /** * Provides an interface defining a node type entity. */ -interface NodeTypeInterface extends ConfigEntityInterface { +interface NodeTypeInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface { /** * Determines whether the node type is locked. @@ -22,13 +23,17 @@ public function isLocked(); * * @return bool * TRUE if a new revision should be created by default. + * + * @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use + * Drupal\Core\Entity\RevisionableEntityBundleInterface::shouldCreateNewRevision() + * instead. */ public function isNewRevision(); /** * Sets whether a new revision should be created by default. * - * @param bool $new_revision_ + * @param bool $new_revision * TRUE if a new revision should be created by default. */ public function setNewRevision($new_revision); diff --git a/core/modules/node/src/NodeTypeListBuilder.php b/core/modules/node/src/NodeTypeListBuilder.php index bdd08745..be6e5f63 100644 --- a/core/modules/node/src/NodeTypeListBuilder.php +++ b/core/modules/node/src/NodeTypeListBuilder.php @@ -18,10 +18,10 @@ class NodeTypeListBuilder extends ConfigEntityListBuilder { */ public function buildHeader() { $header['title'] = t('Name'); - $header['description'] = array( + $header['description'] = [ 'data' => t('Description'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ); + 'class' => [RESPONSIVE_PRIORITY_MEDIUM], + ]; return $header + parent::buildHeader(); } @@ -29,10 +29,10 @@ public function buildHeader() { * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { - $row['title'] = array( + $row['title'] = [ 'data' => $entity->label(), - 'class' => array('menu-label'), - ); + 'class' => ['menu-label'], + ]; $row['description']['data'] = ['#markup' => $entity->getDescription()]; return $row + parent::buildRow($entity); } diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php index c65250ee..f0971fb3 100644 --- a/core/modules/node/src/NodeViewBuilder.php +++ b/core/modules/node/src/NodeViewBuilder.php @@ -28,25 +28,27 @@ public function buildComponents(array &$build, array $entities, array $displays, $display = $displays[$bundle]; if ($display->getComponent('links')) { - $build[$id]['links'] = array( - '#lazy_builder' => [get_called_class() . '::renderLinks', [ - $entity->id(), - $view_mode, - $entity->language()->getId(), - !empty($entity->in_preview), - ]], - ); + $build[$id]['links'] = [ + '#lazy_builder' => [ + get_called_class() . '::renderLinks', [ + $entity->id(), + $view_mode, + $entity->language()->getId(), + !empty($entity->in_preview), + ], + ], + ]; } // Add Language field text element to node render array. if ($display->getComponent('langcode')) { - $build[$id]['langcode'] = array( + $build[$id]['langcode'] = [ '#type' => 'item', '#title' => t('Language'), '#markup' => $entity->language()->getName(), '#prefix' => '
    ', '#suffix' => '
    ' - ); + ]; } } } @@ -81,21 +83,21 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) { * A renderable array representing the node links. */ public static function renderLinks($node_entity_id, $view_mode, $langcode, $is_in_preview) { - $links = array( + $links = [ '#theme' => 'links__node', - '#pre_render' => array('drupal_pre_render_links'), - '#attributes' => array('class' => array('links', 'inline')), - ); + '#pre_render' => ['drupal_pre_render_links'], + '#attributes' => ['class' => ['links', 'inline']], + ]; if (!$is_in_preview) { $entity = Node::load($node_entity_id)->getTranslation($langcode); $links['node'] = static::buildLinks($entity, $view_mode); // Allow other modules to alter the node links. - $hook_context = array( + $hook_context = [ 'view_mode' => $view_mode, 'langcode' => $langcode, - ); + ]; \Drupal::moduleHandler()->alter('node_links', $links, $entity, $hook_context); } return $links; @@ -113,30 +115,30 @@ public static function renderLinks($node_entity_id, $view_mode, $langcode, $is_i * An array that can be processed by drupal_pre_render_links(). */ protected static function buildLinks(NodeInterface $entity, $view_mode) { - $links = array(); + $links = []; // Always display a read more link on teasers because we have no way // to know when a teaser view is different than a full view. if ($view_mode == 'teaser') { $node_title_stripped = strip_tags($entity->label()); - $links['node-readmore'] = array( - 'title' => t('Read more about @title', array( + $links['node-readmore'] = [ + 'title' => t('Read more about @title', [ '@title' => $node_title_stripped, - )), + ]), 'url' => $entity->urlInfo(), 'language' => $entity->language(), - 'attributes' => array( + 'attributes' => [ 'rel' => 'tag', 'title' => $node_title_stripped, - ), - ); + ], + ]; } - return array( + return [ '#theme' => 'links__node__node', '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); + '#attributes' => ['class' => ['links', 'inline']], + ]; } /** diff --git a/core/modules/node/src/NodeViewsData.php b/core/modules/node/src/NodeViewsData.php index 21e1e44b..b5aebf48 100644 --- a/core/modules/node/src/NodeViewsData.php +++ b/core/modules/node/src/NodeViewsData.php @@ -39,15 +39,15 @@ public function getViewsData() { // Use status = 1 instead of status <> 0 in WHERE statement. $data['node_field_data']['status']['filter']['use_equal'] = TRUE; - $data['node_field_data']['status_extra'] = array( + $data['node_field_data']['status_extra'] = [ 'title' => $this->t('Published status or admin user'), 'help' => $this->t('Filters out unpublished content if the current user cannot view it.'), - 'filter' => array( + 'filter' => [ 'field' => 'status', 'id' => 'node_status', 'label' => $this->t('Published status or admin user'), - ), - ); + ], + ]; $data['node_field_data']['promote']['help'] = $this->t('A boolean indicating whether the node is visible on the front page.'); $data['node_field_data']['promote']['filter']['label'] = $this->t('Promoted to front page status'); @@ -58,133 +58,133 @@ public function getViewsData() { $data['node_field_data']['sticky']['filter']['type'] = 'yes-no'; $data['node_field_data']['sticky']['sort']['help'] = $this->t('Whether or not the content is sticky. To list sticky content first, set this to descending.'); - $data['node']['path'] = array( - 'field' => array( + $data['node']['path'] = [ + 'field' => [ 'title' => $this->t('Path'), 'help' => $this->t('The aliased path to this content.'), 'id' => 'node_path', - ), - ); + ], + ]; - $data['node']['node_bulk_form'] = array( + $data['node']['node_bulk_form'] = [ 'title' => $this->t('Node operations bulk form'), 'help' => $this->t('Add a form element that lets you run operations on multiple nodes.'), - 'field' => array( + 'field' => [ 'id' => 'node_bulk_form', - ), - ); + ], + ]; // Bogus fields for aliasing purposes. // @todo Add similar support to any date field // @see https://www.drupal.org/node/2337507 - $data['node_field_data']['created_fulldate'] = array( + $data['node_field_data']['created_fulldate'] = [ 'title' => $this->t('Created date'), 'help' => $this->t('Date in the form of CCYYMMDD.'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_fulldate', - ), - ); + ], + ]; - $data['node_field_data']['created_year_month'] = array( + $data['node_field_data']['created_year_month'] = [ 'title' => $this->t('Created year + month'), 'help' => $this->t('Date in the form of YYYYMM.'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_year_month', - ), - ); + ], + ]; - $data['node_field_data']['created_year'] = array( + $data['node_field_data']['created_year'] = [ 'title' => $this->t('Created year'), 'help' => $this->t('Date in the form of YYYY.'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_year', - ), - ); + ], + ]; - $data['node_field_data']['created_month'] = array( + $data['node_field_data']['created_month'] = [ 'title' => $this->t('Created month'), 'help' => $this->t('Date in the form of MM (01 - 12).'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_month', - ), - ); + ], + ]; - $data['node_field_data']['created_day'] = array( + $data['node_field_data']['created_day'] = [ 'title' => $this->t('Created day'), 'help' => $this->t('Date in the form of DD (01 - 31).'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_day', - ), - ); + ], + ]; - $data['node_field_data']['created_week'] = array( + $data['node_field_data']['created_week'] = [ 'title' => $this->t('Created week'), 'help' => $this->t('Date in the form of WW (01 - 53).'), - 'argument' => array( + 'argument' => [ 'field' => 'created', 'id' => 'date_week', - ), - ); + ], + ]; - $data['node_field_data']['changed_fulldate'] = array( + $data['node_field_data']['changed_fulldate'] = [ 'title' => $this->t('Updated date'), 'help' => $this->t('Date in the form of CCYYMMDD.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_fulldate', - ), - ); + ], + ]; - $data['node_field_data']['changed_year_month'] = array( + $data['node_field_data']['changed_year_month'] = [ 'title' => $this->t('Updated year + month'), 'help' => $this->t('Date in the form of YYYYMM.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_year_month', - ), - ); + ], + ]; - $data['node_field_data']['changed_year'] = array( + $data['node_field_data']['changed_year'] = [ 'title' => $this->t('Updated year'), 'help' => $this->t('Date in the form of YYYY.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_year', - ), - ); + ], + ]; - $data['node_field_data']['changed_month'] = array( + $data['node_field_data']['changed_month'] = [ 'title' => $this->t('Updated month'), 'help' => $this->t('Date in the form of MM (01 - 12).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_month', - ), - ); + ], + ]; - $data['node_field_data']['changed_day'] = array( + $data['node_field_data']['changed_day'] = [ 'title' => $this->t('Updated day'), 'help' => $this->t('Date in the form of DD (01 - 31).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_day', - ), - ); + ], + ]; - $data['node_field_data']['changed_week'] = array( + $data['node_field_data']['changed_week'] = [ 'title' => $this->t('Updated week'), 'help' => $this->t('Date in the form of WW (01 - 53).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_week', - ), - ); + ], + ]; $data['node_field_data']['uid']['help'] = $this->t('The user authoring the content. If you need more fields than the uid add the content: author relationship'); $data['node_field_data']['uid']['filter']['id'] = 'user_name'; @@ -192,13 +192,13 @@ public function getViewsData() { $data['node_field_data']['uid']['relationship']['help'] = $this->t('Relate content to the user who created it.'); $data['node_field_data']['uid']['relationship']['label'] = $this->t('author'); - $data['node']['node_listing_empty'] = array( + $data['node']['node_listing_empty'] = [ 'title' => $this->t('Empty Node Frontpage behavior'), 'help' => $this->t('Provides a link to the node add overview page.'), - 'area' => array( + 'area' => [ 'id' => 'node_listing_empty', - ), - ); + ], + ]; $data['node_field_data']['uid_revision']['title'] = $this->t('User has a revision'); $data['node_field_data']['uid_revision']['help'] = $this->t('All nodes where a certain user has a revision'); @@ -225,19 +225,19 @@ public function getViewsData() { $data['node_field_revision']['nid']['relationship']['title'] = $this->t('Content'); $data['node_field_revision']['nid']['relationship']['label'] = $this->t('Get the actual content from a content revision.'); - $data['node_field_revision']['vid'] = array( - 'argument' => array( + $data['node_field_revision']['vid'] = [ + 'argument' => [ 'id' => 'node_vid', 'numeric' => TRUE, - ), - 'relationship' => array( + ], + 'relationship' => [ 'id' => 'standard', 'base' => 'node_field_data', 'base field' => 'vid', 'title' => $this->t('Content'), 'label' => $this->t('Get the actual content from a content revision.'), - ), - ) + $data['node_field_revision']['vid']; + ], + ] + $data['node_field_revision']['vid']; $data['node_field_revision']['langcode']['help'] = $this->t('The language the original content is in.'); @@ -259,52 +259,52 @@ public function getViewsData() { $data['node_field_revision']['langcode']['help'] = $this->t('The language of the content or translation.'); - $data['node_field_revision']['link_to_revision'] = array( - 'field' => array( + $data['node_field_revision']['link_to_revision'] = [ + 'field' => [ 'title' => $this->t('Link to revision'), 'help' => $this->t('Provide a simple link to the revision.'), 'id' => 'node_revision_link', 'click sortable' => FALSE, - ), - ); + ], + ]; - $data['node_field_revision']['revert_revision'] = array( - 'field' => array( + $data['node_field_revision']['revert_revision'] = [ + 'field' => [ 'title' => $this->t('Link to revert revision'), 'help' => $this->t('Provide a simple link to revert to the revision.'), 'id' => 'node_revision_link_revert', 'click sortable' => FALSE, - ), - ); + ], + ]; - $data['node_field_revision']['delete_revision'] = array( - 'field' => array( + $data['node_field_revision']['delete_revision'] = [ + 'field' => [ 'title' => $this->t('Link to delete revision'), 'help' => $this->t('Provide a simple link to delete the content revision.'), 'id' => 'node_revision_link_delete', 'click sortable' => FALSE, - ), - ); + ], + ]; // Define the base group of this table. Fields that don't have a group defined // will go into this field by default. $data['node_access']['table']['group'] = $this->t('Content access'); // For other base tables, explain how we join. - $data['node_access']['table']['join'] = array( - 'node_field_data' => array( + $data['node_access']['table']['join'] = [ + 'node_field_data' => [ 'left_field' => 'nid', 'field' => 'nid', - ), - ); - $data['node_access']['nid'] = array( + ], + ]; + $data['node_access']['nid'] = [ 'title' => $this->t('Access'), 'help' => $this->t('Filter by access.'), - 'filter' => array( + 'filter' => [ 'id' => 'node_access', 'help' => $this->t('Filter for content by view access. Not necessary if you are using node as your base table.'), - ), - ); + ], + ]; // Add search table, fields, filters, etc., but only if a page using the // node_search plugin is enabled. @@ -324,61 +324,61 @@ public function getViewsData() { // Automatically join to the node table (or actually, node_field_data). // Use a Views table alias to allow other modules to use this table too, // if they use the search index. - $data['node_search_index']['table']['join'] = array( - 'node_field_data' => array( + $data['node_search_index']['table']['join'] = [ + 'node_field_data' => [ 'left_field' => 'nid', 'field' => 'sid', 'table' => 'search_index', 'extra' => "node_search_index.type = 'node_search' AND node_search_index.langcode = node_field_data.langcode", - ) - ); + ] + ]; - $data['node_search_total']['table']['join'] = array( - 'node_search_index' => array( + $data['node_search_total']['table']['join'] = [ + 'node_search_index' => [ 'left_field' => 'word', 'field' => 'word', - ), - ); + ], + ]; - $data['node_search_dataset']['table']['join'] = array( - 'node_field_data' => array( + $data['node_search_dataset']['table']['join'] = [ + 'node_field_data' => [ 'left_field' => 'sid', 'left_table' => 'node_search_index', 'field' => 'sid', 'table' => 'search_dataset', 'extra' => 'node_search_index.type = node_search_dataset.type AND node_search_index.langcode = node_search_dataset.langcode', 'type' => 'INNER', - ), - ); + ], + ]; - $data['node_search_index']['score'] = array( + $data['node_search_index']['score'] = [ 'title' => $this->t('Score'), 'help' => $this->t('The score of the search item. This will not be used if the search filter is not also present.'), - 'field' => array( + 'field' => [ 'id' => 'search_score', 'float' => TRUE, 'no group by' => TRUE, - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'search_score', 'no group by' => TRUE, - ), - ); + ], + ]; - $data['node_search_index']['keys'] = array( + $data['node_search_index']['keys'] = [ 'title' => $this->t('Search Keywords'), 'help' => $this->t('The keywords to search for.'), - 'filter' => array( + 'filter' => [ 'id' => 'search_keywords', 'no group by' => TRUE, 'search_type' => 'node_search', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'search', 'no group by' => TRUE, 'search_type' => 'node_search', - ), - ); + ], + ]; } } diff --git a/core/modules/node/src/Plugin/Action/AssignOwnerNode.php b/core/modules/node/src/Plugin/Action/AssignOwnerNode.php index 7c4412d0..d9a9a435 100644 --- a/core/modules/node/src/Plugin/Action/AssignOwnerNode.php +++ b/core/modules/node/src/Plugin/Action/AssignOwnerNode.php @@ -67,9 +67,9 @@ public function execute($entity = NULL) { * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'owner_uid' => '', - ); + ]; } /** @@ -81,34 +81,34 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta // Use dropdown for fewer than 200 users; textbox for more than that. if (intval($count) < 200) { - $options = array(); + $options = []; $result = $this->connection->query("SELECT uid, name FROM {users_field_data} WHERE uid > 0 AND default_langcode = 1 ORDER BY name"); foreach ($result as $data) { $options[$data->uid] = $data->name; } - $form['owner_uid'] = array( + $form['owner_uid'] = [ '#type' => 'select', '#title' => t('Username'), '#default_value' => $this->configuration['owner_uid'], '#options' => $options, '#description' => $description, - ); + ]; } else { - $form['owner_uid'] = array( + $form['owner_uid'] = [ '#type' => 'entity_autocomplete', '#title' => t('Username'), '#target_type' => 'user', - '#selection_setttings' => array( + '#selection_setttings' => [ 'include_anonymous' => FALSE, - ), + ], '#default_value' => User::load($this->configuration['owner_uid']), // Validation is done in static::validateConfigurationForm(). '#validate_reference' => FALSE, '#size' => '6', '#maxlength' => '60', '#description' => $description, - ); + ]; } return $form; } @@ -117,7 +117,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { - $exists = (bool) $this->connection->queryRange('SELECT 1 FROM {users_field_data} WHERE uid = :uid AND default_langcode = 1', 0, 1, array(':uid' => $form_state->getValue('owner_uid')))->fetchField(); + $exists = (bool) $this->connection->queryRange('SELECT 1 FROM {users_field_data} WHERE uid = :uid AND default_langcode = 1', 0, 1, [':uid' => $form_state->getValue('owner_uid')])->fetchField(); if (!$exists) { $form_state->setErrorByName('owner_uid', t('Enter a valid username.')); } diff --git a/core/modules/node/src/Plugin/Action/DeleteNode.php b/core/modules/node/src/Plugin/Action/DeleteNode.php index 83124f11..5bf5d9ec 100644 --- a/core/modules/node/src/Plugin/Action/DeleteNode.php +++ b/core/modules/node/src/Plugin/Action/DeleteNode.php @@ -85,7 +85,7 @@ public function executeMultiple(array $entities) { * {@inheritdoc} */ public function execute($object = NULL) { - $this->executeMultiple(array($object)); + $this->executeMultiple([$object]); } /** diff --git a/core/modules/node/src/Plugin/Action/DemoteNode.php b/core/modules/node/src/Plugin/Action/DemoteNode.php index 04644a90..efacdb42 100644 --- a/core/modules/node/src/Plugin/Action/DemoteNode.php +++ b/core/modules/node/src/Plugin/Action/DemoteNode.php @@ -2,8 +2,8 @@ namespace Drupal\node\Plugin\Action; -use Drupal\Core\Action\ActionBase; -use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldUpdateActionBase; +use Drupal\node\NodeInterface; /** * Demotes a node. @@ -14,25 +14,13 @@ * type = "node" * ) */ -class DemoteNode extends ActionBase { +class DemoteNode extends FieldUpdateActionBase { /** * {@inheritdoc} */ - public function execute($entity = NULL) { - $entity->setPromoted(FALSE); - $entity->save(); - } - - /** - * {@inheritdoc} - */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { - /** @var \Drupal\node\NodeInterface $object */ - $result = $object->access('update', $account, TRUE) - ->andIf($object->promote->access('edit', $account, TRUE)); - - return $return_as_object ? $result : $result->isAllowed(); + protected function getFieldsToUpdate() { + return ['promote' => NodeInterface::NOT_PROMOTED]; } } diff --git a/core/modules/node/src/Plugin/Action/PromoteNode.php b/core/modules/node/src/Plugin/Action/PromoteNode.php index 097c3414..1d0e6169 100644 --- a/core/modules/node/src/Plugin/Action/PromoteNode.php +++ b/core/modules/node/src/Plugin/Action/PromoteNode.php @@ -2,8 +2,8 @@ namespace Drupal\node\Plugin\Action; -use Drupal\Core\Action\ActionBase; -use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldUpdateActionBase; +use Drupal\node\NodeInterface; /** * Promotes a node. @@ -14,24 +14,13 @@ * type = "node" * ) */ -class PromoteNode extends ActionBase { +class PromoteNode extends FieldUpdateActionBase { /** * {@inheritdoc} */ - public function execute($entity = NULL) { - $entity->setPromoted(TRUE); - $entity->save(); - } - - /** - * {@inheritdoc} - */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { - /** @var \Drupal\node\NodeInterface $object */ - $access = $object->access('update', $account, TRUE) - ->andif($object->promote->access('edit', $account, TRUE)); - return $return_as_object ? $access : $access->isAllowed(); + protected function getFieldsToUpdate() { + return ['promote' => NodeInterface::PROMOTED]; } } diff --git a/core/modules/node/src/Plugin/Action/PublishNode.php b/core/modules/node/src/Plugin/Action/PublishNode.php index 83a43541..2fa8c019 100644 --- a/core/modules/node/src/Plugin/Action/PublishNode.php +++ b/core/modules/node/src/Plugin/Action/PublishNode.php @@ -2,8 +2,8 @@ namespace Drupal\node\Plugin\Action; -use Drupal\Core\Action\ActionBase; -use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldUpdateActionBase; +use Drupal\node\NodeInterface; /** * Publishes a node. @@ -14,25 +14,13 @@ * type = "node" * ) */ -class PublishNode extends ActionBase { +class PublishNode extends FieldUpdateActionBase { /** * {@inheritdoc} */ - public function execute($entity = NULL) { - $entity->status = NODE_PUBLISHED; - $entity->save(); - } - - /** - * {@inheritdoc} - */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { - /** @var \Drupal\node\NodeInterface $object */ - $result = $object->access('update', $account, TRUE) - ->andIf($object->status->access('edit', $account, TRUE)); - - return $return_as_object ? $result : $result->isAllowed(); + protected function getFieldsToUpdate() { + return ['status' => NodeInterface::PUBLISHED]; } } diff --git a/core/modules/node/src/Plugin/Action/StickyNode.php b/core/modules/node/src/Plugin/Action/StickyNode.php index 40685142..679c3c01 100644 --- a/core/modules/node/src/Plugin/Action/StickyNode.php +++ b/core/modules/node/src/Plugin/Action/StickyNode.php @@ -2,8 +2,8 @@ namespace Drupal\node\Plugin\Action; -use Drupal\Core\Action\ActionBase; -use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldUpdateActionBase; +use Drupal\node\NodeInterface; /** * Makes a node sticky. @@ -14,24 +14,13 @@ * type = "node" * ) */ -class StickyNode extends ActionBase { +class StickyNode extends FieldUpdateActionBase { /** * {@inheritdoc} */ - public function execute($entity = NULL) { - $entity->sticky = NODE_STICKY; - $entity->save(); - } - - /** - * {@inheritdoc} - */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { - /** @var \Drupal\node\NodeInterface $object */ - $access = $object->access('update', $account, TRUE) - ->andif($object->sticky->access('edit', $account, TRUE)); - return $return_as_object ? $access : $access->isAllowed(); + protected function getFieldsToUpdate() { + return ['sticky' => NodeInterface::STICKY]; } } diff --git a/core/modules/node/src/Plugin/Action/UnpublishByKeywordNode.php b/core/modules/node/src/Plugin/Action/UnpublishByKeywordNode.php index 6ec835eb..37098533 100644 --- a/core/modules/node/src/Plugin/Action/UnpublishByKeywordNode.php +++ b/core/modules/node/src/Plugin/Action/UnpublishByKeywordNode.php @@ -24,7 +24,7 @@ class UnpublishByKeywordNode extends ConfigurableActionBase { public function execute($node = NULL) { foreach ($this->configuration['keywords'] as $keyword) { $elements = node_view(clone $node); - if (strpos(drupal_render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) { + if (strpos(\Drupal::service('renderer')->render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) { $node->setPublished(FALSE); $node->save(); break; @@ -36,21 +36,21 @@ public function execute($node = NULL) { * {@inheritdoc} */ public function defaultConfiguration() { - return array( - 'keywords' => array(), - ); + return [ + 'keywords' => [], + ]; } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $form['keywords'] = array( + $form['keywords'] = [ '#title' => t('Keywords'), '#type' => 'textarea', '#description' => t('The content will be unpublished if it contains any of the phrases above. Use a case-sensitive, comma-separated list of phrases. Example: funny, bungee jumping, "Company, Inc."'), '#default_value' => Tags::implode($this->configuration['keywords']), - ); + ]; return $form; } diff --git a/core/modules/node/src/Plugin/Action/UnpublishNode.php b/core/modules/node/src/Plugin/Action/UnpublishNode.php index 403a55e6..7c286e2f 100644 --- a/core/modules/node/src/Plugin/Action/UnpublishNode.php +++ b/core/modules/node/src/Plugin/Action/UnpublishNode.php @@ -2,8 +2,8 @@ namespace Drupal\node\Plugin\Action; -use Drupal\Core\Action\ActionBase; -use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldUpdateActionBase; +use Drupal\node\NodeInterface; /** * Unpublishes a node. @@ -14,25 +14,13 @@ * type = "node" * ) */ -class UnpublishNode extends ActionBase { +class UnpublishNode extends FieldUpdateActionBase { /** * {@inheritdoc} */ - public function execute($entity = NULL) { - $entity->status = NODE_NOT_PUBLISHED; - $entity->save(); - } - - /** - * {@inheritdoc} - */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { - /** @var \Drupal\node\NodeInterface $object */ - $access = $object->access('update', $account, TRUE) - ->andIf($object->status->access('edit', $account, TRUE)); - - return $return_as_object ? $access : $access->isAllowed(); + protected function getFieldsToUpdate() { + return ['status' => NodeInterface::NOT_PUBLISHED]; } } diff --git a/core/modules/node/src/Plugin/Action/UnstickyNode.php b/core/modules/node/src/Plugin/Action/UnstickyNode.php index 6c3e9478..c074fe9e 100644 --- a/core/modules/node/src/Plugin/Action/UnstickyNode.php +++ b/core/modules/node/src/Plugin/Action/UnstickyNode.php @@ -2,8 +2,8 @@ namespace Drupal\node\Plugin\Action; -use Drupal\Core\Action\ActionBase; -use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldUpdateActionBase; +use Drupal\node\NodeInterface; /** * Makes a node not sticky. @@ -14,25 +14,13 @@ * type = "node" * ) */ -class UnstickyNode extends ActionBase { +class UnstickyNode extends FieldUpdateActionBase { /** * {@inheritdoc} */ - public function execute($entity = NULL) { - $entity->sticky = NODE_NOT_STICKY; - $entity->save(); - } - - /** - * {@inheritdoc} - */ - public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { - /** @var \Drupal\node\NodeInterface $object */ - $access = $object->access('update', $account, TRUE) - ->andIf($object->sticky->access('edit', $account, TRUE)); - - return $return_as_object ? $access : $access->isAllowed(); + protected function getFieldsToUpdate() { + return ['sticky' => NodeInterface::NOT_STICKY]; } } diff --git a/core/modules/node/src/Plugin/Block/SyndicateBlock.php b/core/modules/node/src/Plugin/Block/SyndicateBlock.php index 07b969b5..bcc98d04 100644 --- a/core/modules/node/src/Plugin/Block/SyndicateBlock.php +++ b/core/modules/node/src/Plugin/Block/SyndicateBlock.php @@ -21,9 +21,9 @@ class SyndicateBlock extends BlockBase { * {@inheritdoc} */ public function defaultConfiguration() { - return array( + return [ 'block_count' => 10, - ); + ]; } /** @@ -37,10 +37,10 @@ protected function blockAccess(AccountInterface $account) { * {@inheritdoc} */ public function build() { - return array( + return [ '#theme' => 'feed_icon', '#url' => 'rss.xml', - ); + ]; } } diff --git a/core/modules/node/src/Plugin/Condition/NodeType.php b/core/modules/node/src/Plugin/Condition/NodeType.php index ace42e62..dcd2dc7d 100644 --- a/core/modules/node/src/Plugin/Condition/NodeType.php +++ b/core/modules/node/src/Plugin/Condition/NodeType.php @@ -64,17 +64,17 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $options = array(); + $options = []; $node_types = $this->entityStorage->loadMultiple(); foreach ($node_types as $type) { $options[$type->id()] = $type->label(); } - $form['bundles'] = array( + $form['bundles'] = [ '#title' => $this->t('Node types'), '#type' => 'checkboxes', '#options' => $options, '#default_value' => $this->configuration['bundles'], - ); + ]; return parent::buildConfigurationForm($form, $form_state); } @@ -94,10 +94,10 @@ public function summary() { $bundles = $this->configuration['bundles']; $last = array_pop($bundles); $bundles = implode(', ', $bundles); - return $this->t('The node bundle is @bundles or @last', array('@bundles' => $bundles, '@last' => $last)); + return $this->t('The node bundle is @bundles or @last', ['@bundles' => $bundles, '@last' => $last]); } $bundle = reset($this->configuration['bundles']); - return $this->t('The node bundle is @bundle', array('@bundle' => $bundle)); + return $this->t('The node bundle is @bundle', ['@bundle' => $bundle]); } /** @@ -115,7 +115,7 @@ public function evaluate() { * {@inheritdoc} */ public function defaultConfiguration() { - return array('bundles' => array()) + parent::defaultConfiguration(); + return ['bundles' => []] + parent::defaultConfiguration(); } } diff --git a/core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php b/core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php index 7943624b..906f15f3 100644 --- a/core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php +++ b/core/modules/node/src/Plugin/EntityReferenceSelection/NodeSelection.php @@ -4,6 +4,7 @@ use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection; use Drupal\Core\Form\FormStateInterface; +use Drupal\node\NodeInterface; /** * Provides specific access control for the node entity type. @@ -38,7 +39,7 @@ protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') // modules in use on the site. As long as one access control module is there, // it is supposed to handle this check. if (!$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'))) { - $query->condition('status', NODE_PUBLISHED); + $query->condition('status', NodeInterface::PUBLISHED); } return $query; } diff --git a/core/modules/node/src/Plugin/Search/NodeSearch.php b/core/modules/node/src/Plugin/Search/NodeSearch.php index d161a0a0..c200f34b 100644 --- a/core/modules/node/src/Plugin/Search/NodeSearch.php +++ b/core/modules/node/src/Plugin/Search/NodeSearch.php @@ -102,12 +102,12 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter * * @var array */ - protected $advanced = array( - 'type' => array('column' => 'n.type'), - 'language' => array('column' => 'i.langcode'), - 'author' => array('column' => 'n.uid'), - 'term' => array('column' => 'ti.tid', 'join' => array('table' => 'taxonomy_index', 'alias' => 'ti', 'condition' => 'n.nid = ti.nid')), - ); + protected $advanced = [ + 'type' => ['column' => 'n.type'], + 'language' => ['column' => 'i.langcode'], + 'author' => ['column' => 'n.uid'], + 'term' => ['column' => 'ti.tid', 'join' => ['table' => 'taxonomy_index', 'alias' => 'ti', 'condition' => 'n.nid = ti.nid']], + ]; /** * A constant for setting and checking the query string. @@ -117,7 +117,7 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter /** * {@inheritdoc} */ - static public function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, @@ -207,7 +207,7 @@ public function execute() { } } - return array(); + return []; } /** @@ -225,7 +225,7 @@ protected function findResults() { // Build matching conditions. $query = $this->database - ->select('search_index', 'i', array('target' => 'replica')) + ->select('search_index', 'i', ['target' => 'replica']) ->extend('Drupal\search\SearchQuery') ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); $query->join('node_field_data', 'n', 'n.nid = i.sid AND n.langcode = i.langcode'); @@ -242,7 +242,7 @@ protected function findResults() { // the keywords string, and some of which are separate conditions. $parameters = $this->getParameters(); if (!empty($parameters['f']) && is_array($parameters['f'])) { - $filters = array(); + $filters = []; // Match any query value that is an expected option and a value // separated by ':' like 'term:27'. $pattern = '/^(' . implode('|', array_keys($this->advanced)) . '):([^ ]*)/i'; @@ -277,7 +277,7 @@ protected function findResults() { $find = $query // Add the language code of the indexed item to the result of the query, // since the node will be rendered using the respective language. - ->fields('i', array('langcode')) + ->fields('i', ['langcode']) // And since SearchQuery makes these into GROUP BY queries, if we add // a field, for PostgreSQL we also need to make it an aggregate or a // GROUP BY. In this case, we want GROUP BY. @@ -289,7 +289,7 @@ protected function findResults() { $status = $query->getStatus(); if ($status & SearchQuery::EXPRESSIONS_IGNORED) { - drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', array('@count' => $this->searchSettings->get('and_or_limit'))), 'warning'); + drupal_set_message($this->t('Your search used too many AND/OR expressions. Only the first @count terms were included in this search.', ['@count' => $this->searchSettings->get('and_or_limit')]), 'warning'); } if ($status & SearchQuery::LOWER_CASE_OR) { @@ -313,7 +313,7 @@ protected function findResults() { * Array of search result item render arrays (empty array if no results). */ protected function prepareResults(StatementInterface $found) { - $results = array(); + $results = []; $node_storage = $this->entityManager->getStorage('node'); $node_render = $this->entityManager->getViewBuilder('node'); @@ -329,7 +329,7 @@ protected function prepareResults(StatementInterface $found) { $type = $this->entityManager->getStorage('node_type')->load($node->bundle()); unset($build['#theme']); - $build['#pre_render'][] = array($this, 'removeSubmittedInfo'); + $build['#pre_render'][] = [$this, 'removeSubmittedInfo']; // Fetch comments for snippet. $rendered = $this->renderer->renderPlain($build); @@ -339,13 +339,13 @@ protected function prepareResults(StatementInterface $found) { $extra = $this->moduleHandler->invokeAll('node_search_result', [$node]); $language = $this->languageManager->getLanguage($item->langcode); - $username = array( + $username = [ '#theme' => 'username', '#account' => $node->getOwner(), - ); + ]; - $result = array( - 'link' => $node->url('canonical', array('absolute' => TRUE, 'language' => $language)), + $result = [ + 'link' => $node->url('canonical', ['absolute' => TRUE, 'language' => $language]), 'type' => $type->label(), 'title' => $node->label(), 'node' => $node, @@ -353,7 +353,7 @@ protected function prepareResults(StatementInterface $found) { 'score' => $item->calculated_score, 'snippet' => search_excerpt($keys, $rendered, $item->langcode), 'langcode' => $node->language()->getId(), - ); + ]; $this->addCacheableDependency($node); @@ -364,10 +364,10 @@ protected function prepareResults(StatementInterface $found) { $this->addCacheableDependency($node->getOwner()); if ($type->displaySubmitted()) { - $result += array( + $result += [ 'user' => $this->renderer->renderPlain($username), 'date' => $node->getChangedTime(), - ); + ]; } $results[] = $result; @@ -411,7 +411,7 @@ protected function addNodeRankings(SelectExtender $query) { if (isset($values['join']) && !isset($tables[$values['join']['alias']])) { $query->addJoin($values['join']['type'], $values['join']['table'], $values['join']['alias'], $values['join']['on']); } - $arguments = isset($values['arguments']) ? $values['arguments'] : array(); + $arguments = isset($values['arguments']) ? $values['arguments'] : []; $query->addScore($values['score'], $arguments, $node_rank); } } @@ -426,15 +426,15 @@ public function updateIndex() { // per cron run. $limit = (int) $this->searchSettings->get('index.cron_limit'); - $query = db_select('node', 'n', array('target' => 'replica')); + $query = db_select('node', 'n', ['target' => 'replica']); $query->addField('n', 'nid'); - $query->leftJoin('search_dataset', 'sd', 'sd.sid = n.nid AND sd.type = :type', array(':type' => $this->getPluginId())); + $query->leftJoin('search_dataset', 'sd', 'sd.sid = n.nid AND sd.type = :type', [':type' => $this->getPluginId()]); $query->addExpression('CASE MAX(sd.reindex) WHEN NULL THEN 0 ELSE 1 END', 'ex'); $query->addExpression('MAX(sd.reindex)', 'ex2'); $query->condition( $query->orConditionGroup() - ->where('sd.sid IS NULL') - ->condition('sd.reindex', 0, '<>') + ->where('sd.sid IS NULL') + ->condition('sd.reindex', 0, '<>') ); $query->orderBy('ex', 'DESC') ->orderBy('ex2') @@ -513,9 +513,9 @@ public function markForReindex() { */ public function indexStatus() { $total = $this->database->query('SELECT COUNT(*) FROM {node}')->fetchField(); - $remaining = $this->database->query("SELECT COUNT(DISTINCT n.nid) FROM {node} n LEFT JOIN {search_dataset} sd ON sd.sid = n.nid AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0", array(':type' => $this->getPluginId()))->fetchField(); + $remaining = $this->database->query("SELECT COUNT(DISTINCT n.nid) FROM {node} n LEFT JOIN {search_dataset} sd ON sd.sid = n.nid AND sd.type = :type WHERE sd.sid IS NULL OR sd.reindex <> 0", [':type' => $this->getPluginId()])->fetchField(); - return array('remaining' => $remaining, 'total' => $total); + return ['remaining' => $remaining, 'total' => $total]; } /** @@ -526,100 +526,100 @@ public function searchFormAlter(array &$form, FormStateInterface $form_state) { $keys = $this->getKeywords(); $used_advanced = !empty($parameters[self::ADVANCED_FORM]); if ($used_advanced) { - $f = isset($parameters['f']) ? (array) $parameters['f'] : array(); + $f = isset($parameters['f']) ? (array) $parameters['f'] : []; $defaults = $this->parseAdvancedDefaults($f, $keys); } else { - $defaults = array('keys' => $keys); + $defaults = ['keys' => $keys]; } $form['basic']['keys']['#default_value'] = $defaults['keys']; // Add advanced search keyword-related boxes. - $form['advanced'] = array( + $form['advanced'] = [ '#type' => 'details', '#title' => t('Advanced search'), - '#attributes' => array('class' => array('search-advanced')), + '#attributes' => ['class' => ['search-advanced']], '#access' => $this->account && $this->account->hasPermission('use advanced search'), '#open' => $used_advanced, - ); - $form['advanced']['keywords-fieldset'] = array( + ]; + $form['advanced']['keywords-fieldset'] = [ '#type' => 'fieldset', '#title' => t('Keywords'), - ); + ]; - $form['advanced']['keywords'] = array( + $form['advanced']['keywords'] = [ '#prefix' => '
    ', '#suffix' => '
    ', - ); + ]; - $form['advanced']['keywords-fieldset']['keywords']['or'] = array( + $form['advanced']['keywords-fieldset']['keywords']['or'] = [ '#type' => 'textfield', '#title' => t('Containing any of the words'), '#size' => 30, '#maxlength' => 255, '#default_value' => isset($defaults['or']) ? $defaults['or'] : '', - ); + ]; - $form['advanced']['keywords-fieldset']['keywords']['phrase'] = array( + $form['advanced']['keywords-fieldset']['keywords']['phrase'] = [ '#type' => 'textfield', '#title' => t('Containing the phrase'), '#size' => 30, '#maxlength' => 255, '#default_value' => isset($defaults['phrase']) ? $defaults['phrase'] : '', - ); + ]; - $form['advanced']['keywords-fieldset']['keywords']['negative'] = array( + $form['advanced']['keywords-fieldset']['keywords']['negative'] = [ '#type' => 'textfield', '#title' => t('Containing none of the words'), '#size' => 30, '#maxlength' => 255, '#default_value' => isset($defaults['negative']) ? $defaults['negative'] : '', - ); + ]; // Add node types. - $types = array_map(array('\Drupal\Component\Utility\Html', 'escape'), node_type_get_names()); - $form['advanced']['types-fieldset'] = array( + $types = array_map(['\Drupal\Component\Utility\Html', 'escape'], node_type_get_names()); + $form['advanced']['types-fieldset'] = [ '#type' => 'fieldset', '#title' => t('Types'), - ); - $form['advanced']['types-fieldset']['type'] = array( + ]; + $form['advanced']['types-fieldset']['type'] = [ '#type' => 'checkboxes', '#title' => t('Only of the type(s)'), '#prefix' => '
    ', '#suffix' => '
    ', '#options' => $types, - '#default_value' => isset($defaults['type']) ? $defaults['type'] : array(), - ); + '#default_value' => isset($defaults['type']) ? $defaults['type'] : [], + ]; - $form['advanced']['submit'] = array( + $form['advanced']['submit'] = [ '#type' => 'submit', '#value' => t('Advanced search'), '#prefix' => '
    ', '#suffix' => '
    ', '#weight' => 100, - ); + ]; // Add languages. - $language_options = array(); + $language_options = []; $language_list = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL); foreach ($language_list as $langcode => $language) { // Make locked languages appear special in the list. - $language_options[$langcode] = $language->isLocked() ? t('- @name -', array('@name' => $language->getName())) : $language->getName(); + $language_options[$langcode] = $language->isLocked() ? t('- @name -', ['@name' => $language->getName()]) : $language->getName(); } if (count($language_options) > 1) { - $form['advanced']['lang-fieldset'] = array( + $form['advanced']['lang-fieldset'] = [ '#type' => 'fieldset', '#title' => t('Languages'), - ); - $form['advanced']['lang-fieldset']['language'] = array( + ]; + $form['advanced']['lang-fieldset']['language'] = [ '#type' => 'checkboxes', '#title' => t('Languages'), '#prefix' => '
    ', '#suffix' => '
    ', '#options' => $language_options, - '#default_value' => isset($defaults['language']) ? $defaults['language'] : array(), - ); + '#default_value' => isset($defaults['language']) ? $defaults['language'] : [], + ]; } } @@ -633,7 +633,7 @@ public function buildSearchUrlQuery(FormStateInterface $form_state) { $advanced = FALSE; // Collect extra filters. - $filters = array(); + $filters = []; if ($form_state->hasValue('type') && is_array($form_state->getValue('type'))) { // Retrieve selected types - Form API sets the value of unselected // checkboxes to 0. @@ -680,7 +680,7 @@ public function buildSearchUrlQuery(FormStateInterface $form_state) { // Put the keywords and advanced parameters into GET parameters. Make sure // to put keywords into the query even if it is empty, because the page // controller uses that to decide it's time to check for search results. - $query = array('keys' => $keys); + $query = ['keys' => $keys]; if ($filters) { $query['f'] = $filters; } @@ -707,13 +707,13 @@ public function buildSearchUrlQuery(FormStateInterface $form_state) { * a modified 'keys' element for the bare search keywords. */ protected function parseAdvancedDefaults($f, $keys) { - $defaults = array(); + $defaults = []; // Split out the advanced search parameters. foreach ($f as $advanced) { list($key, $value) = explode(':', $advanced, 2); if (!isset($defaults[$key])) { - $defaults[$key] = array(); + $defaults[$key] = []; } $defaults[$key][] = $value; } @@ -721,7 +721,7 @@ protected function parseAdvancedDefaults($f, $keys) { // Split out the negative, phrase, and OR parts of keywords. // For phrases, the form only supports one phrase. - $matches = array(); + $matches = []; $keys = ' ' . $keys . ' '; if (preg_match('/ "([^"]+)" /', $keys, $matches)) { $keys = str_replace($matches[0], ' ', $keys); @@ -764,9 +764,9 @@ protected function getRankings() { * {@inheritdoc} */ public function defaultConfiguration() { - $configuration = array( - 'rankings' => array(), - ); + $configuration = [ + 'rankings' => [], + ]; return $configuration; } @@ -775,34 +775,34 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { // Output form for defining rank factor weights. - $form['content_ranking'] = array( + $form['content_ranking'] = [ '#type' => 'details', '#title' => t('Content ranking'), '#open' => TRUE, - ); - $form['content_ranking']['info'] = array( + ]; + $form['content_ranking']['info'] = [ '#markup' => '

    ' . $this->t('Influence is a numeric multiplier used in ordering search results. A higher number means the corresponding factor has more influence on search results; zero means the factor is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') . '

    ' - ); + ]; // Prepare table. $header = [$this->t('Factor'), $this->t('Influence')]; - $form['content_ranking']['rankings'] = array( + $form['content_ranking']['rankings'] = [ '#type' => 'table', '#header' => $header, - ); + ]; // Note: reversed to reflect that higher number = higher ranking. $range = range(0, 10); $options = array_combine($range, $range); foreach ($this->getRankings() as $var => $values) { - $form['content_ranking']['rankings'][$var]['name'] = array( + $form['content_ranking']['rankings'][$var]['name'] = [ '#markup' => $values['title'], - ); - $form['content_ranking']['rankings'][$var]['value'] = array( + ]; + $form['content_ranking']['rankings'][$var]['value'] = [ '#type' => 'select', '#options' => $options, '#attributes' => ['aria-label' => $this->t("Influence of '@title'", ['@title' => $values['title']])], '#default_value' => isset($this->configuration['rankings'][$var]) ? $this->configuration['rankings'][$var] : 0, - ); + ]; } return $form; } diff --git a/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php b/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php index 3fba70ac..536303e9 100644 --- a/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php +++ b/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php @@ -9,6 +9,7 @@ use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\Plugin\MigrationDeriverTrait; use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface; +use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -38,6 +39,20 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface { */ protected $cckPluginManager; + /** + * Already-instantiated field plugins, keyed by ID. + * + * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[] + */ + protected $fieldPluginCache; + + /** + * The field plugin manager. + * + * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface + */ + protected $fieldPluginManager; + /** * Whether or not to include translations. * @@ -52,12 +67,15 @@ class D6NodeDeriver extends DeriverBase implements ContainerDeriverInterface { * The base plugin ID for the plugin ID. * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager * The CCK plugin manager. + * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager + * The field plugin manager. * @param bool $translations * Whether or not to include translations. */ - public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, $translations) { + public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, $translations) { $this->basePluginId = $base_plugin_id; $this->cckPluginManager = $cck_manager; + $this->fieldPluginManager = $field_manager; $this->includeTranslations = $translations; } @@ -69,6 +87,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) { return new static( $base_plugin_id, $container->get('plugin.manager.migrate.cckfield'), + $container->get('plugin.manager.migrate.field'), $container->get('module_handler')->moduleExists('content_translation') ); } @@ -90,8 +109,18 @@ public function getDerivativeDefinitions($base_plugin_definition) { return $this->derivatives; } - // Read all CCK field instance definitions in the source database. - $fields = array(); + $node_types = static::getSourcePlugin('d6_node_type'); + try { + $node_types->checkRequirements(); + } + catch (RequirementsException $e) { + // If the d6_node_type requirements failed, that means we do not have a + // Drupal source database configured - there is nothing to generate. + return $this->derivatives; + } + + // Read all field instance definitions in the source database. + $fields = []; try { $source_plugin = static::getSourcePlugin('d6_field_instance'); $source_plugin->checkRequirements(); @@ -102,12 +131,12 @@ public function getDerivativeDefinitions($base_plugin_definition) { } catch (RequirementsException $e) { // If checkRequirements() failed then the content module did not exist and - // we do not have any CCK fields. Therefore, $fields will be empty and + // we do not have any fields. Therefore, $fields will be empty and // below we'll create a migration just for the node properties. } try { - foreach (static::getSourcePlugin('d6_node_type') as $row) { + foreach ($node_types as $row) { $node_type = $row->getSourceProperty('type'); $values = $base_plugin_definition; @@ -125,20 +154,31 @@ public function getDerivativeDefinitions($base_plugin_definition) { $values['migration_dependencies']['required'][] = 'd6_node:' . $node_type; } + /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values); if (isset($fields[$node_type])) { foreach ($fields[$node_type] as $field_name => $info) { $field_type = $info['type']; try { - $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration); - if (!isset($this->cckPluginCache[$field_type])) { - $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 6], $migration); + $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration); + if (!isset($this->fieldPluginCache[$field_type])) { + $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 6], $migration); } - $this->cckPluginCache[$field_type] - ->processCckFieldValues($migration, $field_name, $info); + $this->fieldPluginCache[$field_type] + ->processFieldValues($migration, $field_name, $info); } catch (PluginNotFoundException $ex) { - $migration->setProcessOfProperty($field_name, $field_name); + try { + $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 6], $migration); + if (!isset($this->cckPluginCache[$field_type])) { + $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 6], $migration); + } + $this->cckPluginCache[$field_type] + ->processCckFieldValues($migration, $field_name, $info); + } + catch (PluginNotFoundException $ex) { + $migration->setProcessOfProperty($field_name, $field_name); + } } } } diff --git a/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php index bd3d8b9f..28c61b83 100644 --- a/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php +++ b/core/modules/node/src/Plugin/migrate/D7NodeDeriver.php @@ -9,6 +9,7 @@ use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\Plugin\MigrationDeriverTrait; use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface; +use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -38,6 +39,27 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface { */ protected $cckPluginManager; + /** + * Already-instantiated field plugins, keyed by ID. + * + * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[] + */ + protected $fieldPluginCache; + + /** + * The field plugin manager. + * + * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface + */ + protected $fieldPluginManager; + + /** + * Whether or not to include translations. + * + * @var bool + */ + protected $includeTranslations; + /** * D7NodeDeriver constructor. * @@ -45,19 +67,28 @@ class D7NodeDeriver extends DeriverBase implements ContainerDeriverInterface { * The base plugin ID for the plugin ID. * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager * The CCK plugin manager. + * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager + * The field plugin manager. + * @param bool $translations + * Whether or not to include translations. */ - public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager) { + public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager, $translations) { $this->basePluginId = $base_plugin_id; $this->cckPluginManager = $cck_manager; + $this->fieldPluginManager = $field_manager; + $this->includeTranslations = $translations; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, $base_plugin_id) { + // Translations don't make sense unless we have content_translation. return new static( $base_plugin_id, - $container->get('plugin.manager.migrate.cckfield') + $container->get('plugin.manager.migrate.cckfield'), + $container->get('plugin.manager.migrate.field'), + $container->get('module_handler')->moduleExists('content_translation') ); } @@ -65,6 +96,21 @@ public static function create(ContainerInterface $container, $base_plugin_id) { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { + if (in_array('translation', $base_plugin_definition['migration_tags']) && !$this->includeTranslations) { + // Refuse to generate anything. + return $this->derivatives; + } + + $node_types = static::getSourcePlugin('d7_node_type'); + try { + $node_types->checkRequirements(); + } + catch (RequirementsException $e) { + // If the d7_node_type requirements failed, that means we do not have a + // Drupal source database configured - there is nothing to generate. + return $this->derivatives; + } + $fields = []; try { $source_plugin = static::getSourcePlugin('d7_field_instance'); @@ -84,7 +130,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { } try { - foreach (static::getSourcePlugin('d7_node_type') as $row) { + foreach ($node_types as $row) { $node_type = $row->getSourceProperty('type'); $values = $base_plugin_definition; @@ -95,20 +141,47 @@ public function getDerivativeDefinitions($base_plugin_definition) { $values['source']['node_type'] = $node_type; $values['destination']['default_bundle'] = $node_type; + // Comment status must be mapped to correct comment type. + // Comment type migration creates a separate comment type for each + // node type except for Forum which uses 'comment_forum'. + $comment_type = 'comment_node_' . $node_type; + if ($node_type == 'forum') { + $comment_type = 'comment_forum'; + } + $nested_key = $comment_type . '/0/status'; + $values['process'][$nested_key] = 'comment'; + + // If this migration is based on the d7_node_revision migration or + // is for translations of nodes, it should explicitly depend on the + // corresponding d7_node variant. + if ($base_plugin_definition['id'] == ['d7_node_revision'] || in_array('translation', $base_plugin_definition['migration_tags'])) { + $values['migration_dependencies']['required'][] = 'd7_node:' . $node_type; + } + $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values); if (isset($fields[$node_type])) { foreach ($fields[$node_type] as $field_name => $info) { $field_type = $info['type']; try { - $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration); - if (!isset($this->cckPluginCache[$field_type])) { - $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration); + $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration); + if (!isset($this->fieldPluginCache[$field_type])) { + $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 7], $migration); } - $this->cckPluginCache[$field_type] - ->processCckFieldValues($migration, $field_name, $info); + $this->fieldPluginCache[$field_type] + ->processFieldValues($migration, $field_name, $info); } catch (PluginNotFoundException $ex) { - $migration->setProcessOfProperty($field_name, $field_name); + try { + $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration); + if (!isset($this->cckPluginCache[$field_type])) { + $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration); + } + $this->cckPluginCache[$field_type] + ->processCckFieldValues($migration, $field_name, $info); + } + catch (PluginNotFoundException $ex) { + $migration->setProcessOfProperty($field_name, $field_name); + } } } } @@ -121,7 +194,6 @@ public function getDerivativeDefinitions($base_plugin_definition) { // MigrationPluginManager gathers up the migration definitions but we do // not actually have a Drupal 7 source database. } - return $this->derivatives; } diff --git a/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php b/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php index 820364c6..c26f3b9f 100644 --- a/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php +++ b/core/modules/node/src/Plugin/migrate/destination/EntityNodeType.php @@ -15,7 +15,7 @@ class EntityNodeType extends EntityConfigBase { /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { $entity_ids = parent::import($row, $old_destination_id_values); if ($row->getDestinationProperty('create_body')) { $node_type = $this->storage->load(reset($entity_ids)); diff --git a/core/modules/node/src/Plugin/migrate/process/d6/NodeUpdate7008.php b/core/modules/node/src/Plugin/migrate/process/d6/NodeUpdate7008.php index cf0b4ade..f6da2eb5 100644 --- a/core/modules/node/src/Plugin/migrate/process/d6/NodeUpdate7008.php +++ b/core/modules/node/src/Plugin/migrate/process/d6/NodeUpdate7008.php @@ -22,7 +22,7 @@ class NodeUpdate7008 extends ProcessPluginBase { */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if ($value === 'administer nodes') { - return array($value, 'access content overview'); + return [$value, 'access content overview']; } return $value; } diff --git a/core/modules/node/src/Plugin/migrate/source/d6/Node.php b/core/modules/node/src/Plugin/migrate/source/d6/Node.php index 2e4d1a60..d20545f2 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/Node.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/Node.php @@ -15,7 +15,9 @@ * Drupal 6 node source from database. * * @MigrateSource( - * id = "d6_node" + * id = "d6_node", + * source_module = "node" + * * ) */ class Node extends DrupalSqlBase { @@ -77,7 +79,7 @@ public function query() { $query->innerJoin('node', 'n', static::JOIN); $this->handleTranslations($query); - $query->fields('n', array( + $query->fields('n', [ 'nid', 'type', 'language', @@ -90,8 +92,8 @@ public function query() { 'sticky', 'tnid', 'translate', - )) - ->fields('nr', array( + ]) + ->fields('nr', [ 'title', 'body', 'teaser', @@ -99,7 +101,7 @@ public function query() { 'timestamp', 'format', 'vid', - )); + ]); $query->addField('n', 'uid', 'node_uid'); $query->addField('nr', 'uid', 'revision_uid'); @@ -129,7 +131,7 @@ protected function initializeIterator() { * {@inheritdoc} */ public function fields() { - $fields = array( + $fields = [ 'nid' => $this->t('Node ID'), 'type' => $this->t('Type'), 'title' => $this->t('Title'), @@ -147,7 +149,7 @@ public function fields() { 'language' => $this->t('Language (fr, en, ...)'), 'tnid' => $this->t('The translation set id for this node'), 'timestamp' => $this->t('The timestamp the latest revision of this node was created.'), - ); + ]; return $fields; } @@ -176,24 +178,24 @@ public function prepareRow(Row $row) { } /** - * Gets CCK field values for a node. + * Gets field values for a node. * * @param \Drupal\migrate\Row $node * The node. * * @return array - * CCK field values, keyed by field name. + * Field values, keyed by field name. */ protected function getFieldValues(Row $node) { $values = []; foreach ($this->getFieldInfo($node->getSourceProperty('type')) as $field => $info) { - $values[$field] = $this->getCckData($info, $node); + $values[$field] = $this->getFieldData($info, $node); } return $values; } /** - * Gets CCK field and instance definitions from the database. + * Gets field and instance definitions from the database. * * @param string $node_type * The node type for which to get field info. @@ -205,14 +207,14 @@ protected function getFieldInfo($node_type) { if (!isset($this->fieldInfo)) { $this->fieldInfo = []; - // Query the database directly for all CCK field info. + // Query the database directly for all field info. $query = $this->select('content_node_field_instance', 'cnfi'); $query->join('content_node_field', 'cnf', 'cnf.field_name = cnfi.field_name'); $query->fields('cnfi'); $query->fields('cnf'); foreach ($query->execute() as $field) { - $this->fieldInfo[ $field['type_name'] ][ $field['field_name'] ] = $field; + $this->fieldInfo[$field['type_name']][$field['field_name']] = $field; } foreach ($this->fieldInfo as $type => $fields) { @@ -230,7 +232,7 @@ protected function getFieldInfo($node_type) { } /** - * Retrieves raw CCK field data for a node. + * Retrieves raw field data for a node. * * @param array $field * A field and instance definition from getFieldInfo(). @@ -240,7 +242,7 @@ protected function getFieldInfo($node_type) { * @return array * The field values, keyed by delta. */ - protected function getCckData(array $field, Row $node) { + protected function getFieldData(array $field, Row $node) { $field_table = 'content_' . $field['field_name']; $node_table = 'content_type_' . $node->getSourceProperty('type'); @@ -276,10 +278,9 @@ protected function getCckData(array $field, Row $node) { return $query // This call to isNotNull() is a kludge which relies on the convention - // that CCK field schemas usually define their most important - // column first. A better way would be to allow cckfield plugins to - // alter the query directly before it's run, but this will do for - // the time being. + // that field schemas usually define their most important column first. + // A better way would be to allow field plugins to alter the query + // directly before it's run, but this will do for the time being. ->isNotNull($field['field_name'] . '_' . $columns[0]) ->condition('nid', $node->getSourceProperty('nid')) ->condition('vid', $node->getSourceProperty('vid')) @@ -291,6 +292,24 @@ protected function getCckData(array $field, Row $node) { } } + /** + * Retrieves raw field data for a node. + * + * @deprecated in Drupal 8.2.x, to be removed in Drupal 9.0.x. Use + * getFieldData() instead. + * + * @param array $field + * A field and instance definition from getFieldInfo(). + * @param \Drupal\migrate\Row $node + * The node. + * + * @return array + * The field values, keyed by delta. + */ + protected function getCckData(array $field, Row $node) { + return $this->getFieldData($field, $node); + } + /** * {@inheritdoc} */ diff --git a/core/modules/node/src/Plugin/migrate/source/d6/NodeRevision.php b/core/modules/node/src/Plugin/migrate/source/d6/NodeRevision.php index 3f9a5808..62924988 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/NodeRevision.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/NodeRevision.php @@ -1,13 +1,15 @@ t('The primary identifier for this version.'), 'log' => $this->t('Revision Log message'), 'timestamp' => $this->t('Revision timestamp'), - ); + ]; } /** diff --git a/core/modules/node/src/Plugin/migrate/source/d6/NodeType.php b/core/modules/node/src/Plugin/migrate/source/d6/NodeType.php index 0653d59c..c5caa12b 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/NodeType.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/NodeType.php @@ -9,7 +9,8 @@ * Drupal 6 Node types source from database. * * @MigrateSource( - * id = "d6_node_type" + * id = "d6_node_type", + * source_module = "node" * ) */ class NodeType extends DrupalSqlBase { @@ -40,7 +41,7 @@ class NodeType extends DrupalSqlBase { */ public function query() { return $this->select('node_type', 't') - ->fields('t', array( + ->fields('t', [ 'type', 'name', 'module', @@ -54,7 +55,7 @@ public function query() { 'modified', 'locked', 'orig_type', - )) + ]) ->orderBy('t.type'); } @@ -62,7 +63,7 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + $fields = [ 'type' => $this->t('Machine name of the node type.'), 'name' => $this->t('Human name of the node type.'), 'module' => $this->t('The module providing the node type.'), @@ -77,7 +78,29 @@ public function fields() { 'locked' => $this->t('Flag.'), 'orig_type' => $this->t('The original type.'), 'teaser_length' => $this->t('Teaser length'), - ); + ]; + if ($this->moduleExists('comment')) { + $fields += $this->getCommentFields(); + } + return $fields; + } + + /** + * Returns the fields containing comment settings for each node type. + * + * @return string[] + * An associative array of field descriptions, keyed by field. + */ + protected function getCommentFields() { + return [ + 'comment' => $this->t('Default comment setting'), + 'comment_default_mode' => $this->t('Default display mode'), + 'comment_default_per_page' => $this->t('Default comments per page'), + 'comment_anonymous' => $this->t('Anonymous commenting'), + 'comment_subject_field' => $this->t('Comment subject field'), + 'comment_preview' => $this->t('Preview comment'), + 'comment_form_location' => $this->t('Location of comment submission form'), + ]; } /** @@ -86,7 +109,7 @@ public function fields() { protected function initializeIterator() { $this->teaserLength = $this->variableGet('teaser_length', 600); $this->nodePreview = $this->variableGet('node_preview', 0); - $this->themeSettings = $this->variableGet('theme_settings', array()); + $this->themeSettings = $this->variableGet('theme_settings', []); return parent::initializeIterator(); } @@ -98,15 +121,26 @@ public function prepareRow(Row $row) { $row->setSourceProperty('node_preview', $this->nodePreview); $type = $row->getSourceProperty('type'); - $source_options = $this->variableGet('node_options_' . $type, array('promote', 'sticky')); - $options = array(); - foreach (array('promote', 'sticky', 'status', 'revision') as $item) { + $source_options = $this->variableGet('node_options_' . $type, ['promote', 'sticky']); + $options = []; + foreach (['promote', 'sticky', 'status', 'revision'] as $item) { $options[$item] = in_array($item, $source_options); } $row->setSourceProperty('options', $options); $submitted = isset($this->themeSettings['toggle_node_info_' . $type]) ? $this->themeSettings['toggle_node_info_' . $type] : FALSE; $row->setSourceProperty('display_submitted', $submitted); + if ($default_node_menu = $this->variableGet('menu_default_node_menu', NULL)) { + $row->setSourceProperty('available_menus', [$default_node_menu]); + $row->setSourceProperty('parent', $default_node_menu . ':'); + } + + if ($this->moduleExists('comment')) { + foreach (array_keys($this->getCommentFields()) as $field) { + $row->setSourceProperty($field, $this->variableGet($field . '_' . $type, NULL)); + } + } + return parent::prepareRow($row); } diff --git a/core/modules/node/src/Plugin/migrate/source/d6/ViewMode.php b/core/modules/node/src/Plugin/migrate/source/d6/ViewMode.php index a4503984..434007a0 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/ViewMode.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/ViewMode.php @@ -7,7 +7,7 @@ * * @MigrateSource( * id = "d6_view_mode", - * source_provider = "content" + * source_module = "content" * ) */ class ViewMode extends ViewModeBase { @@ -16,12 +16,15 @@ class ViewMode extends ViewModeBase { * {@inheritdoc} */ protected function initializeIterator() { - $rows = array(); + $rows = []; $result = $this->prepareQuery()->execute(); while ($field_row = $result->fetchAssoc()) { $field_row['display_settings'] = unserialize($field_row['display_settings']); foreach ($this->getViewModes() as $view_mode) { - if (isset($field_row['display_settings'][$view_mode]) && empty($field_row['display_settings'][$view_mode]['exclude'])) { + // Append to the return value if the row has display settings for this + // view mode and the view mode is neither hidden nor excluded. + // @see \Drupal\field\Plugin\migrate\source\d6\FieldInstancePerViewMode::initializeIterator() + if (isset($field_row['display_settings'][$view_mode]) && $field_row['display_settings'][$view_mode]['format'] != 'hidden' && empty($field_row['display_settings'][$view_mode]['exclude'])) { if (!isset($rows[$view_mode])) { $rows[$view_mode]['entity_type'] = 'node'; $rows[$view_mode]['view_mode'] = $view_mode; @@ -38,9 +41,9 @@ protected function initializeIterator() { */ public function query() { $query = $this->select('content_node_field_instance', 'cnfi') - ->fields('cnfi', array( + ->fields('cnfi', [ 'display_settings', - )); + ]); return $query; } @@ -49,9 +52,9 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'display_settings' => $this->t('Serialize data with display settings.'), - ); + ]; } /** diff --git a/core/modules/node/src/Plugin/migrate/source/d6/ViewModeBase.php b/core/modules/node/src/Plugin/migrate/source/d6/ViewModeBase.php index 54abcb0f..315f069a 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/ViewModeBase.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/ViewModeBase.php @@ -33,7 +33,7 @@ public function count() { * The view mode names. */ public function getViewModes() { - return array( + return [ 0, 1, 2, @@ -42,7 +42,7 @@ public function getViewModes() { 5, 'teaser', 'full', - ); + ]; } } diff --git a/core/modules/node/src/Plugin/migrate/source/d7/Node.php b/core/modules/node/src/Plugin/migrate/source/d7/Node.php index 6286d5fa..1a9037e7 100644 --- a/core/modules/node/src/Plugin/migrate/source/d7/Node.php +++ b/core/modules/node/src/Plugin/migrate/source/d7/Node.php @@ -2,18 +2,54 @@ namespace Drupal\node\Plugin\migrate\source\d7; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\migrate\Row; use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity; +use Drupal\Core\Database\Query\SelectInterface; +use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Extension\ModuleHandler; +use Drupal\Core\State\StateInterface; +use Drupal\migrate\Plugin\MigrationInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Drupal 7 node source from database. * * @MigrateSource( * id = "d7_node", - * source_provider = "node" + * source_module = "node" * ) */ class Node extends FieldableEntity { + /** + * The module handler. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * {@inheritdoc} + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, StateInterface $state, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $state, $entity_manager); + $this->moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('state'), + $container->get('entity.manager'), + $container->get('module_handler') + ); + } /** * The join options between the node and the node_revisions table. @@ -26,7 +62,7 @@ class Node extends FieldableEntity { public function query() { // Select node in its last revision. $query = $this->select('node_revision', 'nr') - ->fields('n', array( + ->fields('n', [ 'nid', 'type', 'language', @@ -38,17 +74,25 @@ public function query() { 'sticky', 'tnid', 'translate', - )) - ->fields('nr', array( + ]) + ->fields('nr', [ 'vid', 'title', 'log', 'timestamp', - )); + ]); $query->addField('n', 'uid', 'node_uid'); $query->addField('nr', 'uid', 'revision_uid'); $query->innerJoin('node', 'n', static::JOIN); + // If the content_translation module is enabled, get the source langcode + // to fill the content_translation_source field. + if ($this->moduleHandler->moduleExists('content_translation')) { + $query->leftJoin('node', 'nt', 'n.tnid = nt.nid'); + $query->addField('nt', 'language', 'source_langcode'); + } + $this->handleTranslations($query); + if (isset($this->configuration['node_type'])) { $query->condition('n.type', $this->configuration['node_type']); } @@ -66,6 +110,11 @@ public function prepareRow(Row $row) { $vid = $row->getSourceProperty('vid'); $row->setSourceProperty($field, $this->getFieldValues('node', $field, $nid, $vid)); } + + // Make sure we always have a translation set. + if ($row->getSourceProperty('tnid') == 0) { + $row->setSourceProperty('tnid', $row->getSourceProperty('nid')); + } return parent::prepareRow($row); } @@ -73,7 +122,7 @@ public function prepareRow(Row $row) { * {@inheritdoc} */ public function fields() { - $fields = array( + $fields = [ 'nid' => $this->t('Node ID'), 'type' => $this->t('Type'), 'title' => $this->t('Title'), @@ -88,7 +137,7 @@ public function fields() { 'language' => $this->t('Language (fr, en, ...)'), 'tnid' => $this->t('The translation set id for this node'), 'timestamp' => $this->t('The timestamp the latest revision of this node was created.'), - ); + ]; return $fields; } @@ -101,4 +150,22 @@ public function getIds() { return $ids; } + /** + * Adapt our query for translations. + * + * @param \Drupal\Core\Database\Query\SelectInterface $query + * The generated query. + */ + protected function handleTranslations(SelectInterface $query) { + // Check whether or not we want translations. + if (empty($this->configuration['translations'])) { + // No translations: Yield untranslated nodes, or default translations. + $query->where('n.tnid = 0 OR n.tnid = n.nid'); + } + else { + // Translations: Yield only non-default translations. + $query->where('n.tnid <> 0 AND n.tnid <> n.nid'); + } + } + } diff --git a/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php b/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php index b88359ab..67071a72 100644 --- a/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php +++ b/core/modules/node/src/Plugin/migrate/source/d7/NodeRevision.php @@ -7,7 +7,7 @@ * * @MigrateSource( * id = "d7_node_revision", - * source_provider = "node" + * source_module = "node" * ) */ class NodeRevision extends Node { @@ -22,11 +22,11 @@ class NodeRevision extends Node { */ public function fields() { // Use all the node fields plus the vid that identifies the version. - return parent::fields() + array( + return parent::fields() + [ 'vid' => t('The primary identifier for this version.'), 'log' => $this->t('Revision Log message'), 'timestamp' => $this->t('Revision timestamp'), - ); + ]; } /** diff --git a/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php b/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php index b8a8519a..44f0b5e0 100644 --- a/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php +++ b/core/modules/node/src/Plugin/migrate/source/d7/NodeType.php @@ -10,7 +10,7 @@ * * @MigrateSource( * id = "d7_node_type", - * source_provider = "node" + * source_module = "node" * ) */ class NodeType extends DrupalSqlBase { @@ -40,7 +40,7 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'type' => $this->t('Machine name of the node type.'), 'name' => $this->t('Human name of the node type.'), 'description' => $this->t('Description of the node type.'), @@ -53,7 +53,29 @@ public function fields() { 'locked' => $this->t('Flag.'), 'orig_type' => $this->t('The original type.'), 'teaser_length' => $this->t('Teaser length'), - ); + ]; + if ($this->moduleExists('comment')) { + $fields += $this->getCommentFields(); + } + return $fields; + } + + /** + * Returns the fields containing comment settings for each node type. + * + * @return string[] + * An associative array of field descriptions, keyed by field. + */ + protected function getCommentFields() { + return [ + 'comment' => $this->t('Default comment setting'), + 'comment_default_mode' => $this->t('Default display mode'), + 'comment_default_per_page' => $this->t('Default comments per page'), + 'comment_anonymous' => $this->t('Anonymous commenting'), + 'comment_subject_field' => $this->t('Comment subject field'), + 'comment_preview' => $this->t('Preview comment'), + 'comment_form_location' => $this->t('Location of comment submission form'), + ]; } /** @@ -73,9 +95,9 @@ public function prepareRow(Row $row) { $row->setSourceProperty('node_preview', $this->nodePreview); $type = $row->getSourceProperty('type'); - $source_options = $this->variableGet('node_options_' . $type, array('promote', 'sticky')); - $options = array(); - foreach (array('promote', 'sticky', 'status', 'revision') as $item) { + $source_options = $this->variableGet('node_options_' . $type, ['promote', 'sticky']); + $options = []; + foreach (['promote', 'sticky', 'status', 'revision'] as $item) { $options[$item] = in_array($item, $source_options); } $row->setSourceProperty('options', $options); @@ -86,7 +108,7 @@ public function prepareRow(Row $row) { if ($this->moduleExists('field')) { // Find body field for this node type. $body = $this->select('field_config_instance', 'fci') - ->fields('fci', array('data')) + ->fields('fci', ['data']) ->condition('entity_type', 'node') ->condition('bundle', $row->getSourceProperty('type')) ->condition('field_name', 'body') @@ -101,6 +123,19 @@ public function prepareRow(Row $row) { $row->setSourceProperty('display_submitted', $this->variableGet('node_submitted_' . $type, TRUE)); + if ($menu_options = $this->variableGet('menu_options_' . $type, NULL)) { + $row->setSourceProperty('available_menus', $menu_options); + } + if ($parent = $this->variableGet('menu_parent_' . $type, NULL)) { + $row->setSourceProperty('parent', $parent . ':'); + } + + if ($this->moduleExists('comment')) { + foreach (array_keys($this->getCommentFields()) as $field) { + $row->setSourceProperty($field, $this->variableGet($field . '_' . $type, NULL)); + } + } + return parent::prepareRow($row); } diff --git a/core/modules/node/src/Plugin/views/area/ListingEmpty.php b/core/modules/node/src/Plugin/views/area/ListingEmpty.php index e52ca1bf..08e1d272 100644 --- a/core/modules/node/src/Plugin/views/area/ListingEmpty.php +++ b/core/modules/node/src/Plugin/views/area/ListingEmpty.php @@ -59,19 +59,19 @@ public static function create(ContainerInterface $container, array $configuratio public function render($empty = FALSE) { $account = \Drupal::currentUser(); if (!$empty || !empty($this->options['empty'])) { - $element = array( + $element = [ '#theme' => 'links', - '#links' => array( - array( + '#links' => [ + [ 'url' => Url::fromRoute('node.add_page'), 'title' => $this->t('Add content'), - ), - ), - '#access' => $this->accessManager->checkNamedRoute('node.add_page', array(), $account), - ); + ], + ], + '#access' => $this->accessManager->checkNamedRoute('node.add_page', [], $account), + ]; return $element; } - return array(); + return []; } } diff --git a/core/modules/node/src/Plugin/views/argument/Nid.php b/core/modules/node/src/Plugin/views/argument/Nid.php index 8f846bc6..3b0f8df9 100644 --- a/core/modules/node/src/Plugin/views/argument/Nid.php +++ b/core/modules/node/src/Plugin/views/argument/Nid.php @@ -52,7 +52,7 @@ public static function create(ContainerInterface $container, array $configuratio * Override the behavior of title(). Get the title of the node. */ public function titleQuery() { - $titles = array(); + $titles = []; $nodes = $this->nodeStorage->loadMultiple($this->value); foreach ($nodes as $node) { diff --git a/core/modules/node/src/Plugin/views/argument/Type.php b/core/modules/node/src/Plugin/views/argument/Type.php index 641b1634..1a78c2fa 100644 --- a/core/modules/node/src/Plugin/views/argument/Type.php +++ b/core/modules/node/src/Plugin/views/argument/Type.php @@ -29,7 +29,7 @@ class Type extends StringArgument { * The plugin_id for the plugin instance. * @param mixed $plugin_definition * The plugin implementation definition. - * @param \Drupal\Core\Entity\EntityStorageInterface $storage + * @param \Drupal\Core\Entity\EntityStorageInterface $node_type_storage * The entity storage class. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $node_type_storage) { @@ -63,11 +63,11 @@ public function summaryName($data) { * Override the behavior of title(). Get the user friendly version of the * node type. */ - function title() { + public function title() { return $this->node_type($this->argument); } - function node_type($type_name) { + public function node_type($type_name) { $type = $this->nodeTypeStorage->load($type_name); $output = $type ? $type->label() : $this->t('Unknown content type'); return $output; diff --git a/core/modules/node/src/Plugin/views/argument/UidRevision.php b/core/modules/node/src/Plugin/views/argument/UidRevision.php index 9a19fe36..0f989a7a 100644 --- a/core/modules/node/src/Plugin/views/argument/UidRevision.php +++ b/core/modules/node/src/Plugin/views/argument/UidRevision.php @@ -15,7 +15,7 @@ class UidRevision extends Uid { public function query($group_by = FALSE) { $this->ensureMyTable(); $placeholder = $this->placeholder(); - $this->query->addWhereExpression(0, "$this->tableAlias.revision_uid = $placeholder OR ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nfr.revision_uid = $placeholder AND nr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $this->argument)); + $this->query->addWhereExpression(0, "$this->tableAlias.uid = $placeholder OR ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid = $placeholder AND nr.nid = $this->tableAlias.nid) > 0)", [$placeholder => $this->argument]); } } diff --git a/core/modules/node/src/Plugin/views/argument/Vid.php b/core/modules/node/src/Plugin/views/argument/Vid.php index 8788b67a..1cad35c7 100644 --- a/core/modules/node/src/Plugin/views/argument/Vid.php +++ b/core/modules/node/src/Plugin/views/argument/Vid.php @@ -66,10 +66,10 @@ public static function create(ContainerInterface $container, array $configuratio * Override the behavior of title(). Get the title of the revision. */ public function titleQuery() { - $titles = array(); + $titles = []; - $results = $this->database->query('SELECT nr.vid, nr.nid, npr.title FROM {node_revision} nr WHERE nr.vid IN ( :vids[] )', array(':vids[]' => $this->value))->fetchAllAssoc('vid', PDO::FETCH_ASSOC); - $nids = array(); + $results = $this->database->query('SELECT nr.vid, nr.nid, npr.title FROM {node_revision} nr WHERE nr.vid IN ( :vids[] )', [':vids[]' => $this->value])->fetchAllAssoc('vid', PDO::FETCH_ASSOC); + $nids = []; foreach ($results as $result) { $nids[] = $result['nid']; } diff --git a/core/modules/node/src/Plugin/views/field/Node.php b/core/modules/node/src/Plugin/views/field/Node.php index d721414f..e5cd9d70 100644 --- a/core/modules/node/src/Plugin/views/field/Node.php +++ b/core/modules/node/src/Plugin/views/field/Node.php @@ -28,7 +28,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o // Don't add the additional fields to groupby if (!empty($this->options['link_to_node'])) { - $this->additional_fields['nid'] = array('table' => 'node_field_data', 'field' => 'nid'); + $this->additional_fields['nid'] = ['table' => 'node_field_data', 'field' => 'nid']; } } @@ -37,7 +37,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o */ protected function defineOptions() { $options = parent::defineOptions(); - $options['link_to_node'] = array('default' => isset($this->definition['link_to_node default']) ? $this->definition['link_to_node default'] : FALSE); + $options['link_to_node'] = ['default' => isset($this->definition['link_to_node default']) ? $this->definition['link_to_node default'] : FALSE]; return $options; } @@ -45,12 +45,12 @@ protected function defineOptions() { * Provide link to node option */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['link_to_node'] = array( + $form['link_to_node'] = [ '#title' => $this->t('Link this field to the original piece of content'), '#description' => $this->t("Enable to override this field's links."), '#type' => 'checkbox', '#default_value' => !empty($this->options['link_to_node']), - ); + ]; parent::buildOptionsForm($form, $form_state); } diff --git a/core/modules/node/src/Plugin/views/field/Path.php b/core/modules/node/src/Plugin/views/field/Path.php index 5fb07cd7..c1c74ab6 100644 --- a/core/modules/node/src/Plugin/views/field/Path.php +++ b/core/modules/node/src/Plugin/views/field/Path.php @@ -31,7 +31,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o */ protected function defineOptions() { $options = parent::defineOptions(); - $options['absolute'] = array('default' => FALSE); + $options['absolute'] = ['default' => FALSE]; return $options; } @@ -41,13 +41,13 @@ protected function defineOptions() { */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['absolute'] = array( + $form['absolute'] = [ '#type' => 'checkbox', '#title' => $this->t('Use absolute link (begins with "http://")'), '#default_value' => $this->options['absolute'], '#description' => $this->t('Enable this option to output an absolute link. Required if you want to use the path as a link destination (as in "output this field as a link" above).'), '#fieldset' => 'alter', - ); + ]; } /** @@ -63,9 +63,9 @@ public function query() { */ public function render(ResultRow $values) { $nid = $this->getValue($values, 'nid'); - return array( + return [ '#markup' => \Drupal::url('entity.node.canonical', ['node' => $nid], ['absolute' => $this->options['absolute']]), - ); + ]; } } diff --git a/core/modules/node/src/Plugin/views/filter/Access.php b/core/modules/node/src/Plugin/views/filter/Access.php index 73844e11..71e8e95e 100644 --- a/core/modules/node/src/Plugin/views/filter/Access.php +++ b/core/modules/node/src/Plugin/views/filter/Access.php @@ -2,6 +2,7 @@ namespace Drupal\node\Plugin\views\filter; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\filter\FilterPluginBase; @@ -14,8 +15,8 @@ */ class Access extends FilterPluginBase { - public function adminSummary() { } - protected function operatorForm(&$form, FormStateInterface $form_state) { } + public function adminSummary() {} + protected function operatorForm(&$form, FormStateInterface $form_state) {} public function canExpose() { return FALSE; } @@ -27,10 +28,10 @@ public function query() { $account = $this->view->getUser(); if (!$account->hasPermission('bypass node access')) { $table = $this->ensureMyTable(); - $grants = db_or(); + $grants = new Condition('OR'); foreach (node_access_grants('view', $account) as $realm => $gids) { foreach ($gids as $gid) { - $grants->condition(db_and() + $grants->condition((new Condition('AND')) ->condition($table . '.gid', $gid) ->condition($table . '.realm', $realm) ); diff --git a/core/modules/node/src/Plugin/views/filter/Status.php b/core/modules/node/src/Plugin/views/filter/Status.php index 194df7a8..bd1fcd30 100644 --- a/core/modules/node/src/Plugin/views/filter/Status.php +++ b/core/modules/node/src/Plugin/views/filter/Status.php @@ -14,11 +14,13 @@ */ class Status extends FilterPluginBase { - public function adminSummary() { } + public function adminSummary() {} - protected function operatorForm(&$form, FormStateInterface $form_state) { } + protected function operatorForm(&$form, FormStateInterface $form_state) {} - public function canExpose() { return FALSE; } + public function canExpose() { + return FALSE; + } public function query() { $table = $this->ensureMyTable(); diff --git a/core/modules/node/src/Plugin/views/filter/UidRevision.php b/core/modules/node/src/Plugin/views/filter/UidRevision.php index ce588b7b..0968480f 100644 --- a/core/modules/node/src/Plugin/views/filter/UidRevision.php +++ b/core/modules/node/src/Plugin/views/filter/UidRevision.php @@ -21,7 +21,7 @@ public function query($group_by = FALSE) { $args = array_values($this->value); $this->query->addWhereExpression($this->options['group'], "$this->tableAlias.uid IN($placeholder) OR - ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid IN ($placeholder) AND nr.nid = $this->tableAlias.nid) > 0)", array($placeholder => $args), + ((SELECT COUNT(DISTINCT vid) FROM {node_revision} nr WHERE nr.revision_uid IN ($placeholder) AND nr.nid = $this->tableAlias.nid) > 0)", [$placeholder => $args], $args); } diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php index 097655a2..96838796 100644 --- a/core/modules/node/src/Plugin/views/row/Rss.php +++ b/core/modules/node/src/Plugin/views/row/Rss.php @@ -27,7 +27,7 @@ class Rss extends RssPluginBase { public $base_field = 'nid'; // Stores the nodes loaded with preRender. - public $nodes = array(); + public $nodes = []; /** * {@inheritdoc} @@ -74,7 +74,7 @@ public function summaryTitle() { } public function preRender($values) { - $nids = array(); + $nids = []; foreach ($values as $row) { $nids[] = $row->{$this->field_alias}; } @@ -103,23 +103,23 @@ public function render($row) { return; } - $node->link = $node->url('canonical', array('absolute' => TRUE)); - $node->rss_namespaces = array(); - $node->rss_elements = array( - array( + $node->link = $node->url('canonical', ['absolute' => TRUE]); + $node->rss_namespaces = []; + $node->rss_elements = [ + [ 'key' => 'pubDate', 'value' => gmdate('r', $node->getCreatedTime()), - ), - array( + ], + [ 'key' => 'dc:creator', 'value' => $node->getOwner()->getDisplayName(), - ), - array( + ], + [ 'key' => 'guid', 'value' => $node->id() . ' at ' . $base_url, - 'attributes' => array('isPermaLink' => 'false'), - ), - ); + 'attributes' => ['isPermaLink' => 'false'], + ], + ]; // The node gets built and modules add to or modify $node->rss_elements // and $node->rss_namespaces. @@ -135,7 +135,7 @@ public function render($row) { elseif (function_exists('rdf_get_namespaces')) { // Merge RDF namespaces in the XML namespaces in case they are used // further in the RSS content. - $xml_rdf_namespaces = array(); + $xml_rdf_namespaces = []; foreach (rdf_get_namespaces() as $prefix => $uri) { $xml_rdf_namespaces['xmlns:' . $prefix] = $uri; } @@ -153,12 +153,12 @@ public function render($row) { // template_preprocess_views_view_row_rss() can still access it. $item->elements = &$node->rss_elements; $item->nid = $node->id(); - $build = array( + $build = [ '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, '#row' => $item, - ); + ]; return $build; } diff --git a/core/modules/node/src/Plugin/views/wizard/Node.php b/core/modules/node/src/Plugin/views/wizard/Node.php index ce267e66..34d4bcf6 100644 --- a/core/modules/node/src/Plugin/views/wizard/Node.php +++ b/core/modules/node/src/Plugin/views/wizard/Node.php @@ -28,16 +28,16 @@ class Node extends WizardPluginBase { /** * Set default values for the filters. */ - protected $filters = array( - 'status' => array( + protected $filters = [ + 'status' => [ 'value' => TRUE, 'table' => 'node_field_data', 'field' => 'status', 'plugin_id' => 'boolean', 'entity_type' => 'node', 'entity_field' => 'status', - ) - ); + ] + ]; /** * Overrides Drupal\views\Plugin\views\wizard\WizardPluginBase::getAvailableSorts(). @@ -48,16 +48,16 @@ class Node extends WizardPluginBase { */ public function getAvailableSorts() { // You can't execute functions in properties, so override the method - return array( + return [ 'node_field_data-title:ASC' => $this->t('Title') - ); + ]; } /** * {@inheritdoc} */ protected function rowStyleOptions() { - $options = array(); + $options = []; $options['teasers'] = $this->t('teasers'); $options['full_posts'] = $this->t('full posts'); $options['titles'] = $this->t('titles'); @@ -110,22 +110,22 @@ protected function defaultDisplayOptions() { protected function defaultDisplayFiltersUser(array $form, FormStateInterface $form_state) { $filters = parent::defaultDisplayFiltersUser($form, $form_state); - $tids = array(); - if ($values = $form_state->getValue(array('show', 'tagged_with'))) { + $tids = []; + if ($values = $form_state->getValue(['show', 'tagged_with'])) { foreach ($values as $value) { $tids[] = $value['target_id']; } } if (!empty($tids)) { $vid = reset($form['displays']['show']['tagged_with']['#selection_settings']['target_bundles']); - $filters['tid'] = array( + $filters['tid'] = [ 'id' => 'tid', 'table' => 'taxonomy_index', 'field' => 'tid', 'value' => $tids, 'vid' => $vid, 'plugin_id' => 'taxonomy_index_tid', - ); + ]; // If the user entered more than one valid term in the autocomplete // field, they probably intended both of them to be applied. if (count($tids) > 1) { @@ -144,8 +144,8 @@ protected function defaultDisplayFiltersUser(array $form, FormStateInterface $fo */ protected function pageDisplayOptions(array $form, FormStateInterface $form_state) { $display_options = parent::pageDisplayOptions($form, $form_state); - $row_plugin = $form_state->getValue(array('page', 'style', 'row_plugin')); - $row_options = $form_state->getValue(array('page', 'style', 'row_options'), array()); + $row_plugin = $form_state->getValue(['page', 'style', 'row_plugin']); + $row_options = $form_state->getValue(['page', 'style', 'row_options'], []); $this->display_options_row($display_options, $row_plugin, $row_options); return $display_options; } @@ -155,8 +155,8 @@ protected function pageDisplayOptions(array $form, FormStateInterface $form_stat */ protected function blockDisplayOptions(array $form, FormStateInterface $form_state) { $display_options = parent::blockDisplayOptions($form, $form_state); - $row_plugin = $form_state->getValue(array('block', 'style', 'row_plugin')); - $row_options = $form_state->getValue(array('block', 'style', 'row_options'), array()); + $row_plugin = $form_state->getValue(['block', 'style', 'row_plugin']); + $row_options = $form_state->getValue(['block', 'style', 'row_options'], []); $this->display_options_row($display_options, $row_plugin, $row_options); return $display_options; } @@ -195,7 +195,7 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { parent::buildFilters($form, $form_state); if (isset($form['displays']['show']['type'])) { - $selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']); + $selected_bundle = static::getSelected($form_state, ['show', 'type'], 'all', $form['displays']['show']['type']); } // Add the "tagged with" filter to the view. @@ -221,9 +221,9 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { // Double check that this is a real bundle before using it (since above // we added a dummy option 'all' to the bundle list on the form). if (isset($selected_bundle) && in_array($selected_bundle, $bundles)) { - $bundles = array($selected_bundle); + $bundles = [$selected_bundle]; } - $tag_fields = array(); + $tag_fields = []; foreach ($bundles as $bundle) { $display = entity_get_form_display($this->entityTypeId, $bundle, 'default'); $taxonomy_fields = array_filter(\Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $bundle), function ($field_definition) { @@ -253,7 +253,7 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { } // Add the autocomplete textfield to the wizard. $target_bundles = $tag_fields[$tag_field_name]->getSetting('handler_settings')['target_bundles']; - $form['displays']['show']['tagged_with'] = array( + $form['displays']['show']['tagged_with'] = [ '#type' => 'entity_autocomplete', '#title' => $this->t('tagged with'), '#target_type' => 'taxonomy_term', @@ -261,7 +261,7 @@ protected function buildFilters(&$form, FormStateInterface $form_state) { '#tags' => TRUE, '#size' => 30, '#maxlength' => 1024, - ); + ]; } } diff --git a/core/modules/node/src/Plugin/views/wizard/NodeRevision.php b/core/modules/node/src/Plugin/views/wizard/NodeRevision.php index 64bc7bed..9c3465d2 100644 --- a/core/modules/node/src/Plugin/views/wizard/NodeRevision.php +++ b/core/modules/node/src/Plugin/views/wizard/NodeRevision.php @@ -27,16 +27,16 @@ class NodeRevision extends WizardPluginBase { /** * Set default values for the filters. */ - protected $filters = array( - 'status' => array( + protected $filters = [ + 'status' => [ 'value' => TRUE, 'table' => 'node_field_revision', 'field' => 'status', 'plugin_id' => 'boolean', 'entity_type' => 'node', 'entity_field' => 'status', - ) - ); + ] + ]; /** * Overrides Drupal\views\Plugin\views\wizard\WizardPluginBase::rowStyleOptions(). diff --git a/core/modules/node/src/Routing/RouteSubscriber.php b/core/modules/node/src/Routing/RouteSubscriber.php index 23bd0f8f..66d83c12 100644 --- a/core/modules/node/src/Routing/RouteSubscriber.php +++ b/core/modules/node/src/Routing/RouteSubscriber.php @@ -19,13 +19,13 @@ protected function alterRoutes(RouteCollection $collection) { // a node listing instead of the path's child links. $route = $collection->get('system.admin_content'); if ($route) { - $route->setDefaults(array( + $route->setDefaults([ '_title' => 'Content', '_entity_list' => 'node', - )); - $route->setRequirements(array( + ]); + $route->setRequirements([ '_permission' => 'access content overview', - )); + ]); } } diff --git a/core/modules/node/src/Tests/AssertButtonsTrait.php b/core/modules/node/src/Tests/AssertButtonsTrait.php index 58d484d9..97016dc2 100644 --- a/core/modules/node/src/Tests/AssertButtonsTrait.php +++ b/core/modules/node/src/Tests/AssertButtonsTrait.php @@ -2,8 +2,13 @@ namespace Drupal\node\Tests; +@trigger_error('\Drupal\Tests\node\Functional\AssertButtonsTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\node\Functional\AssertButtonsTrait', E_USER_DEPRECATED); + /** * Asserts that buttons are present on a page. + * + * @deprecated Scheduled for removal before Drupal 9.0.0. + * Use \Drupal\Tests\node\Functional\AssertButtonsTrait instead. */ trait AssertButtonsTrait { diff --git a/core/modules/node/src/Tests/NodeEditFormTest.php b/core/modules/node/src/Tests/NodeEditFormTest.php deleted file mode 100644 index b154ca0b..00000000 --- a/core/modules/node/src/Tests/NodeEditFormTest.php +++ /dev/null @@ -1,218 +0,0 @@ -webUser = $this->drupalCreateUser(array('edit own page content', 'create page content')); - $this->adminUser = $this->drupalCreateUser(array('bypass node access', 'administer nodes')); - $this->drupalPlaceBlock('local_tasks_block'); - - $this->nodeStorage = $this->container->get('entity.manager')->getStorage('node'); - } - - /** - * Checks node edit functionality. - */ - public function testNodeEdit() { - $this->drupalLogin($this->webUser); - - $title_key = 'title[0][value]'; - $body_key = 'body[0][value]'; - // Create node to edit. - $edit = array(); - $edit[$title_key] = $this->randomMachineName(8); - $edit[$body_key] = $this->randomMachineName(16); - $this->drupalPostForm('node/add/page', $edit, t('Save')); - - // Check that the node exists in the database. - $node = $this->drupalGetNodeByTitle($edit[$title_key]); - $this->assertTrue($node, 'Node found in database.'); - - // Check that "edit" link points to correct page. - $this->clickLink(t('Edit')); - $this->assertUrl($node->url('edit-form', ['absolute' => TRUE])); - - // Check that the title and body fields are displayed with the correct values. - // @todo Ideally assertLink would support HTML, but it doesn't. - $this->assertRaw('Edit(active tab)', 'Edit tab found and marked active.'); - $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.'); - $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.'); - - // Edit the content of the node. - $edit = array(); - $edit[$title_key] = $this->randomMachineName(8); - $edit[$body_key] = $this->randomMachineName(16); - // Stay on the current page, without reloading. - $this->drupalPostForm(NULL, $edit, t('Save')); - - // Check that the title and body fields are displayed with the updated values. - $this->assertText($edit[$title_key], 'Title displayed.'); - $this->assertText($edit[$body_key], 'Body displayed.'); - - // Log in as a second administrator user. - $second_web_user = $this->drupalCreateUser(array('administer nodes', 'edit any page content')); - $this->drupalLogin($second_web_user); - // Edit the same node, creating a new revision. - $this->drupalGet("node/" . $node->id() . "/edit"); - $edit = array(); - $edit['title[0][value]'] = $this->randomMachineName(8); - $edit[$body_key] = $this->randomMachineName(16); - $edit['revision'] = TRUE; - $this->drupalPostForm(NULL, $edit, t('Save and keep published')); - - // Ensure that the node revision has been created. - $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE); - $this->assertNotIdentical($node->getRevisionId(), $revised_node->getRevisionId(), 'A new revision has been created.'); - // Ensure that the node author is preserved when it was not changed in the - // edit form. - $this->assertIdentical($node->getOwnerId(), $revised_node->getOwnerId(), 'The node author has been preserved.'); - // Ensure that the revision authors are different since the revisions were - // made by different users. - $first_node_version = node_revision_load($node->getRevisionId()); - $second_node_version = node_revision_load($revised_node->getRevisionId()); - $this->assertNotIdentical($first_node_version->getRevisionUser()->id(), $second_node_version->getRevisionUser()->id(), 'Each revision has a distinct user.'); - } - - /** - * Tests changing a node's "authored by" field. - */ - public function testNodeEditAuthoredBy() { - $this->drupalLogin($this->adminUser); - - // Create node to edit. - $body_key = 'body[0][value]'; - $edit = array(); - $edit['title[0][value]'] = $this->randomMachineName(8); - $edit[$body_key] = $this->randomMachineName(16); - $this->drupalPostForm('node/add/page', $edit, t('Save and publish')); - - // Check that the node was authored by the currently logged in user. - $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); - $this->assertIdentical($node->getOwnerId(), $this->adminUser->id(), 'Node authored by admin user.'); - - $this->checkVariousAuthoredByValues($node, 'uid[0][target_id]'); - - // Check that normal users cannot change the authored by information. - $this->drupalLogin($this->webUser); - $this->drupalGet('node/' . $node->id() . '/edit'); - $this->assertNoFieldByName('uid[0][target_id]'); - - // Now test with the Autcomplete (Tags) field widget. - /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */ - $form_display = \Drupal::entityManager()->getStorage('entity_form_display')->load('node.page.default'); - $widget = $form_display->getComponent('uid'); - $widget['type'] = 'entity_reference_autocomplete_tags'; - $widget['settings'] = [ - 'match_operator' => 'CONTAINS', - 'size' => 60, - 'placeholder' => '', - ]; - $form_display->setComponent('uid', $widget); - $form_display->save(); - - $this->drupalLogin($this->adminUser); - - // Save the node without making any changes. - $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published')); - $this->nodeStorage->resetCache(array($node->id())); - $node = $this->nodeStorage->load($node->id()); - $this->assertIdentical($this->webUser->id(), $node->getOwner()->id()); - - $this->checkVariousAuthoredByValues($node, 'uid[target_id]'); - - // Hide the 'authored by' field from the form. - $form_display->removeComponent('uid')->save(); - - // Check that saving the node without making any changes keeps the proper - // author ID. - $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published')); - $this->nodeStorage->resetCache(array($node->id())); - $node = $this->nodeStorage->load($node->id()); - $this->assertIdentical($this->webUser->id(), $node->getOwner()->id()); - } - - /** - * Checks that the "authored by" works correctly with various values. - * - * @param \Drupal\node\NodeInterface $node - * A node object. - * @param string $form_element_name - * The name of the form element to populate. - */ - protected function checkVariousAuthoredByValues(NodeInterface $node, $form_element_name) { - // Try to change the 'authored by' field to an invalid user name. - $edit = array( - $form_element_name => 'invalid-name', - ); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); - $this->assertRaw(t('There are no entities matching "%name".', array('%name' => 'invalid-name'))); - - // Change the authored by field to an empty string, which should assign - // authorship to the anonymous user (uid 0). - $edit[$form_element_name] = ''; - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); - $this->nodeStorage->resetCache(array($node->id())); - $node = $this->nodeStorage->load($node->id()); - $uid = $node->getOwnerId(); - // Most SQL database drivers stringify fetches but entities are not - // necessarily stored in a SQL database. At the same time, NULL/FALSE/"" - // won't do. - $this->assertTrue($uid === 0 || $uid === '0', 'Node authored by anonymous user.'); - - // Go back to the edit form and check that the correct value is displayed - // in the author widget. - $this->drupalGet('node/' . $node->id() . '/edit'); - $anonymous_user = User::getAnonymousUser(); - $expected = $anonymous_user->label() . ' (' . $anonymous_user->id() . ')'; - $this->assertFieldByName($form_element_name, $expected, 'Authored by field displays the correct value for the anonymous user.'); - - // Change the authored by field to another user's name (that is not - // logged in). - $edit[$form_element_name] = $this->webUser->getUsername(); - $this->drupalPostForm(NULL, $edit, t('Save and keep published')); - $this->nodeStorage->resetCache(array($node->id())); - $node = $this->nodeStorage->load($node->id()); - $this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.'); - } - -} diff --git a/core/modules/node/src/Tests/NodeFormButtonsTest.php b/core/modules/node/src/Tests/NodeFormButtonsTest.php deleted file mode 100644 index 9f6732bf..00000000 --- a/core/modules/node/src/Tests/NodeFormButtonsTest.php +++ /dev/null @@ -1,135 +0,0 @@ -webUser = $this->drupalCreateUser(array('create article content', 'edit own article content')); - // Create a user that has access to change the state of the node. - $this->adminUser = $this->drupalCreateUser(array('administer nodes', 'bypass node access')); - } - - /** - * Tests that the right buttons are displayed for saving nodes. - */ - function testNodeFormButtons() { - $node_storage = $this->container->get('entity.manager')->getStorage('node'); - // Log in as administrative user. - $this->drupalLogin($this->adminUser); - - // Verify the buttons on a node add form. - $this->drupalGet('node/add/article'); - $this->assertButtons(array(t('Save and publish'), t('Save as unpublished'))); - - // Save the node and assert it's published after clicking - // 'Save and publish'. - $edit = array('title[0][value]' => $this->randomString()); - $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); - - // Get the node. - $node_1 = $node_storage->load(1); - $this->assertTrue($node_1->isPublished(), 'Node is published'); - - // Verify the buttons on a node edit form. - $this->drupalGet('node/' . $node_1->id() . '/edit'); - $this->assertButtons(array(t('Save and keep published'), t('Save and unpublish'))); - - // Save the node and verify it's still published after clicking - // 'Save and keep published'. - $this->drupalPostForm(NULL, $edit, t('Save and keep published')); - $node_storage->resetCache(array(1)); - $node_1 = $node_storage->load(1); - $this->assertTrue($node_1->isPublished(), 'Node is published'); - - // Save the node and verify it's unpublished after clicking - // 'Save and unpublish'. - $this->drupalPostForm('node/' . $node_1->id() . '/edit', $edit, t('Save and unpublish')); - $node_storage->resetCache(array(1)); - $node_1 = $node_storage->load(1); - $this->assertFalse($node_1->isPublished(), 'Node is unpublished'); - - // Verify the buttons on an unpublished node edit screen. - $this->drupalGet('node/' . $node_1->id() . '/edit'); - $this->assertButtons(array(t('Save and keep unpublished'), t('Save and publish'))); - - // Create a node as a normal user. - $this->drupalLogout(); - $this->drupalLogin($this->webUser); - - // Verify the buttons for a normal user. - $this->drupalGet('node/add/article'); - $this->assertButtons(array(t('Save')), FALSE); - - // Create the node. - $edit = array('title[0][value]' => $this->randomString()); - $this->drupalPostForm('node/add/article', $edit, t('Save')); - $node_2 = $node_storage->load(2); - $this->assertTrue($node_2->isPublished(), 'Node is published'); - - // Log in as an administrator and unpublish the node that just - // was created by the normal user. - $this->drupalLogout(); - $this->drupalLogin($this->adminUser); - $this->drupalPostForm('node/' . $node_2->id() . '/edit', array(), t('Save and unpublish')); - $node_storage->resetCache(array(2)); - $node_2 = $node_storage->load(2); - $this->assertFalse($node_2->isPublished(), 'Node is unpublished'); - - // Log in again as the normal user, save the node and verify - // it's still unpublished. - $this->drupalLogout(); - $this->drupalLogin($this->webUser); - $this->drupalPostForm('node/' . $node_2->id() . '/edit', array(), t('Save')); - $node_storage->resetCache(array(2)); - $node_2 = $node_storage->load(2); - $this->assertFalse($node_2->isPublished(), 'Node is still unpublished'); - $this->drupalLogout(); - - // Set article content type default to unpublished. This will change the - // the initial order of buttons and/or status of the node when creating - // a node. - $fields = \Drupal::entityManager()->getFieldDefinitions('node', 'article'); - $fields['status']->getConfig('article') - ->setDefaultValue(FALSE) - ->save(); - - // Verify the buttons on a node add form for an administrator. - $this->drupalLogin($this->adminUser); - $this->drupalGet('node/add/article'); - $this->assertButtons(array(t('Save as unpublished'), t('Save and publish'))); - - // Verify the node is unpublished by default for a normal user. - $this->drupalLogout(); - $this->drupalLogin($this->webUser); - $edit = array('title[0][value]' => $this->randomString()); - $this->drupalPostForm('node/add/article', $edit, t('Save')); - $node_3 = $node_storage->load(3); - $this->assertFalse($node_3->isPublished(), 'Node is unpublished'); - } - -} diff --git a/core/modules/node/src/Tests/NodeLoadMultipleTest.php b/core/modules/node/src/Tests/NodeLoadMultipleTest.php deleted file mode 100644 index 4add3bd1..00000000 --- a/core/modules/node/src/Tests/NodeLoadMultipleTest.php +++ /dev/null @@ -1,62 +0,0 @@ -drupalCreateUser(array('create article content', 'create page content')); - $this->drupalLogin($web_user); - } - - /** - * Creates four nodes and ensures that they are loaded correctly. - */ - function testNodeMultipleLoad() { - $node1 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); - $node2 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); - $node3 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 0)); - $node4 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0)); - - // Confirm that promoted nodes appear in the default node listing. - $this->drupalGet('node'); - $this->assertText($node1->label(), 'Node title appears on the default listing.'); - $this->assertText($node2->label(), 'Node title appears on the default listing.'); - $this->assertNoText($node3->label(), 'Node title does not appear in the default listing.'); - $this->assertNoText($node4->label(), 'Node title does not appear in the default listing.'); - // Load nodes with only a condition. Nodes 3 and 4 will be loaded. - $nodes = $this->container->get('entity_type.manager')->getStorage('node') - ->loadByProperties(array('promote' => 0)); - $this->assertEqual($node3->label(), $nodes[$node3->id()]->label(), 'Node was loaded.'); - $this->assertEqual($node4->label(), $nodes[$node4->id()]->label(), 'Node was loaded.'); - $count = count($nodes); - $this->assertTrue($count == 2, format_string('@count nodes loaded.', array('@count' => $count))); - - // Load nodes by nid. Nodes 1, 2 and 4 will be loaded. - $nodes = Node::loadMultiple(array(1, 2, 4)); - $count = count($nodes); - $this->assertTrue(count($nodes) == 3, format_string('@count nodes loaded', array('@count' => $count))); - $this->assertTrue(isset($nodes[$node1->id()]), 'Node is correctly keyed in the array'); - $this->assertTrue(isset($nodes[$node2->id()]), 'Node is correctly keyed in the array'); - $this->assertTrue(isset($nodes[$node4->id()]), 'Node is correctly keyed in the array'); - foreach ($nodes as $node) { - $this->assertTrue(is_object($node), 'Node is an object'); - } - } - -} diff --git a/core/modules/node/src/Tests/NodeRevisionsTest.php b/core/modules/node/src/Tests/NodeRevisionsTest.php index bfdd213f..efb4011d 100644 --- a/core/modules/node/src/Tests/NodeRevisionsTest.php +++ b/core/modules/node/src/Tests/NodeRevisionsTest.php @@ -47,26 +47,26 @@ protected function setUp() { ConfigurableLanguage::createFromLangcode('de')->save(); ConfigurableLanguage::createFromLangcode('it')->save(); - $field_storage_definition = array( + $field_storage_definition = [ 'field_name' => 'untranslatable_string_field', 'entity_type' => 'node', 'type' => 'string', 'cardinality' => 1, 'translatable' => FALSE, - ); + ]; $field_storage = FieldStorageConfig::create($field_storage_definition); $field_storage->save(); - $field_definition = array( + $field_definition = [ 'field_storage' => $field_storage, 'bundle' => 'page', - ); + ]; $field = FieldConfig::create($field_definition); $field->save(); // Create and log in user. $web_user = $this->drupalCreateUser( - array( + [ 'view page revisions', 'revert page revisions', 'delete page revisions', @@ -75,7 +75,7 @@ protected function setUp() { 'access contextual links', 'translate any entity', 'administer content types', - ) + ] ); $this->drupalLogin($web_user); @@ -86,8 +86,8 @@ protected function setUp() { $settings['revision'] = 1; $settings['isDefaultRevision'] = TRUE; - $nodes = array(); - $logs = array(); + $nodes = []; + $logs = []; // Get original node. $nodes[] = clone $node; @@ -99,10 +99,10 @@ protected function setUp() { // Create revision with a random title and body and update variables. $node->title = $this->randomMachineName(); - $node->body = array( + $node->body = [ 'value' => $this->randomMachineName(32), 'format' => filter_default_format(), - ); + ]; $node->untranslatable_string_field->value = $this->randomString(); $node->setNewRevision(); @@ -117,7 +117,8 @@ protected function setUp() { $node->save(); - $node = Node::load($node->id()); // Make sure we get revision information. + // Make sure we get revision information. + $node = Node::load($node->id()); $nodes[] = clone $node; } @@ -128,7 +129,7 @@ protected function setUp() { /** * Checks node revision related operations. */ - function testRevisions() { + public function testRevisions() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $nodes = $this->nodes; $logs = $this->revisionLogs; @@ -167,11 +168,13 @@ function testRevisions() { // Confirm that revisions revert properly. - $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", array(), t('Revert')); - $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', - array('@type' => 'Basic page', '%title' => $nodes[1]->label(), - '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()))), 'Revision reverted.'); - $node_storage->resetCache(array($node->id())); + $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionid() . "/revert", [], t('Revert')); + $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [ + '@type' => 'Basic page', + '%title' => $nodes[1]->label(), + '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()) + ]), 'Revision reverted.'); + $node_storage->resetCache([$node->id()]); $reverted_node = $node_storage->load($node->id()); $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.'); @@ -190,27 +193,30 @@ function testRevisions() { // Confirm revisions delete properly. - $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", array(), t('Delete')); - $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.', - array('%revision-date' => format_date($nodes[1]->getRevisionCreationTime()), - '@type' => 'Basic page', '%title' => $nodes[1]->label())), 'Revision deleted.'); - $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, 'Revision not found.'); + $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", [], t('Delete')); + $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.', [ + '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()), + '@type' => 'Basic page', + '%title' => $nodes[1]->label(), + ]), 'Revision deleted.'); + $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Revision not found.'); + $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid and vid = :vid', [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Field revision not found.'); // Set the revision timestamp to an older date to make sure that the // confirmation message correctly displays the stored revision date. $old_revision_date = REQUEST_TIME - 86400; db_update('node_revision') ->condition('vid', $nodes[2]->getRevisionId()) - ->fields(array( + ->fields([ 'revision_timestamp' => $old_revision_date, - )) + ]) ->execute(); - $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", array(), t('Revert')); - $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', array( + $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", [], t('Revert')); + $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [ '@type' => 'Basic page', '%title' => $nodes[2]->label(), '%revision-date' => format_date($old_revision_date), - ))); + ])); // Make a new revision and set it to not be default. // This will create a new revision that is not "front facing". @@ -232,7 +238,7 @@ function testRevisions() { // Verify that the non-default revision vid is greater than the default // revision vid. $default_revision = db_select('node', 'n') - ->fields('n', array('vid')) + ->fields('n', ['vid']) ->condition('nid', $node->id()) ->execute() ->fetchCol(); @@ -297,11 +303,11 @@ function testRevisions() { /** * Checks that revisions are correctly saved without log messages. */ - function testNodeRevisionWithoutLogMessage() { + public function testNodeRevisionWithoutLogMessage() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); // Create a node with an initial log message. $revision_log = $this->randomMachineName(10); - $node = $this->drupalCreateNode(array('revision_log' => $revision_log)); + $node = $this->drupalCreateNode(['revision_log' => $revision_log]); // Save over the same revision and explicitly provide an empty log message // (for example, to mimic the case of a node form submitted with no text in @@ -317,12 +323,12 @@ function testNodeRevisionWithoutLogMessage() { $node->save(); $this->drupalGet('node/' . $node->id()); $this->assertText($new_title, 'New node title appears on the page.'); - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $node_revision = $node_storage->load($node->id()); $this->assertEqual($node_revision->revision_log->value, $revision_log, 'After an existing node revision is re-saved without a log message, the original log message is preserved.'); // Create another node with an initial revision log message. - $node = $this->drupalCreateNode(array('revision_log' => $revision_log)); + $node = $this->drupalCreateNode(['revision_log' => $revision_log]); // Save a new node revision without providing a log message, and check that // this revision has an empty log message. @@ -336,7 +342,7 @@ function testNodeRevisionWithoutLogMessage() { $node->save(); $this->drupalGet('node/' . $node->id()); $this->assertText($new_title, 'New node title appears on the page.'); - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $node_revision = $node_storage->load($node->id()); $this->assertTrue(empty($node_revision->revision_log->value), 'After a new node revision is saved with an empty log message, the log message for the node is empty.'); } @@ -353,7 +359,7 @@ function testNodeRevisionWithoutLogMessage() { * The decoded JSON response body. */ protected function renderContextualLinks(array $ids, $current_path) { - $post = array(); + $post = []; for ($i = 0; $i < count($ids); $i++) { $post['ids[' . $i . ']'] = $ids[$i]; } diff --git a/core/modules/node/src/Tests/NodeSyndicateBlockTest.php b/core/modules/node/src/Tests/NodeSyndicateBlockTest.php deleted file mode 100644 index 31b216f5..00000000 --- a/core/modules/node/src/Tests/NodeSyndicateBlockTest.php +++ /dev/null @@ -1,37 +0,0 @@ -drupalCreateUser(array('administer blocks')); - $this->drupalLogin($admin_user); - } - - /** - * Tests that the "Syndicate" block is shown when enabled. - */ - public function testSyndicateBlock() { - // Place the "Syndicate" block and confirm that it is rendered. - $this->drupalPlaceBlock('node_syndicate_block', array('id' => 'test_syndicate_block')); - $this->drupalGet(''); - $this->assertFieldByXPath('//div[@id="block-test-syndicate-block"]/*', NULL, 'Syndicate block found.'); - } - -} diff --git a/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php b/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php deleted file mode 100644 index ec768e68..00000000 --- a/core/modules/node/src/Tests/NodeTemplateSuggestionsTest.php +++ /dev/null @@ -1,38 +0,0 @@ -drupalCreateNode(); - $view_mode = 'full'; - - // Simulate theming of the node. - $build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode); - - $variables['elements'] = $build; - $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', array($variables)); - - $this->assertEqual($suggestions, array('node__full', 'node__page', 'node__page__full', 'node__' . $node->id(), 'node__' . $node->id() . '__full'), 'Found expected node suggestions.'); - - // Change the view mode. - $view_mode = 'node.my_custom_view_mode'; - $build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode); - - $variables['elements'] = $build; - $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', array($variables)); - - $this->assertEqual($suggestions, array('node__node_my_custom_view_mode', 'node__page', 'node__page__node_my_custom_view_mode', 'node__' . $node->id(), 'node__' . $node->id() . '__node_my_custom_view_mode'), 'Found expected node suggestions.'); - } - -} diff --git a/core/modules/node/src/Tests/NodeTestBase.php b/core/modules/node/src/Tests/NodeTestBase.php index d4799d4a..2dcaba5b 100644 --- a/core/modules/node/src/Tests/NodeTestBase.php +++ b/core/modules/node/src/Tests/NodeTestBase.php @@ -8,6 +8,9 @@ /** * Sets up page and article content types. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\node\Functional\NodeTestBase instead. */ abstract class NodeTestBase extends WebTestBase { @@ -16,7 +19,7 @@ abstract class NodeTestBase extends WebTestBase { * * @var array */ - public static $modules = array('node', 'datetime'); + public static $modules = ['node', 'datetime']; /** * The node access control handler. @@ -33,12 +36,12 @@ protected function setUp() { // Create Basic page and Article node types. if ($this->profile != 'standard') { - $this->drupalCreateContentType(array( + $this->drupalCreateContentType([ 'type' => 'page', 'name' => 'Basic page', 'display_submitted' => FALSE, - )); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + ]); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); } $this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('node'); } @@ -56,7 +59,7 @@ protected function setUp() { * @param \Drupal\Core\Session\AccountInterface $account * The user account for which to check access. */ - function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) { + public function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) { foreach ($ops as $op => $result) { $this->assertEqual($result, $this->accessHandler->access($node, $op, $account), $this->nodeAccessAssertMessage($op, $result, $node->language()->getId())); } @@ -75,10 +78,10 @@ function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $acc * (optional) The language code indicating which translation of the node * to check. If NULL, the untranslated (fallback) access is checked. */ - function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) { - $this->assertEqual($result, $this->accessHandler->createAccess($bundle, $account, array( + public function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) { + $this->assertEqual($result, $this->accessHandler->createAccess($bundle, $account, [ 'langcode' => $langcode, - )), $this->nodeAccessAssertMessage('create', $result, $langcode)); + ]), $this->nodeAccessAssertMessage('create', $result, $langcode)); } /** @@ -96,14 +99,14 @@ function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $la * An assert message string which contains information in plain English * about the node access permission test that was performed. */ - function nodeAccessAssertMessage($operation, $result, $langcode = NULL) { + public function nodeAccessAssertMessage($operation, $result, $langcode = NULL) { return format_string( 'Node access returns @result with operation %op, language code %langcode.', - array( + [ '@result' => $result ? 'true' : 'false', '%op' => $operation, '%langcode' => !empty($langcode) ? $langcode : 'empty' - ) + ] ); } diff --git a/core/modules/node/src/Tests/NodeTitleTest.php b/core/modules/node/src/Tests/NodeTitleTest.php deleted file mode 100644 index 59ee0214..00000000 --- a/core/modules/node/src/Tests/NodeTitleTest.php +++ /dev/null @@ -1,103 +0,0 @@ -drupalPlaceBlock('system_breadcrumb_block'); - - $this->adminUser = $this->drupalCreateUser(array('administer nodes', 'create article content', 'create page content', 'post comments')); - $this->drupalLogin($this->adminUser); - $this->addDefaultCommentField('node', 'page'); - } - - /** - * Creates one node and tests if the node title has the correct value. - */ - function testNodeTitle() { - // Create "Basic page" content with title. - // Add the node to the frontpage so we can test if teaser links are - // clickable. - $settings = array( - 'title' => $this->randomMachineName(8), - 'promote' => 1, - ); - $node = $this->drupalCreateNode($settings); - - // Test tag. - $this->drupalGet('node/' . $node->id()); - $xpath = '//title'; - $this->assertEqual(current($this->xpath($xpath)), $node->label() . ' | Drupal', 'Page title is equal to node title.', 'Node'); - - // Test breadcrumb in comment preview. - $this->drupalGet('comment/reply/node/' . $node->id() . '/comment'); - $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; - $this->assertEqual(current($this->xpath($xpath)), $node->label(), 'Node breadcrumb is equal to node title.', 'Node'); - - // Test node title in comment preview. - $this->assertEqual(current($this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]/h2/a/span', array(':node-class' => ' node--type-' . $node->bundle() . ' '))), $node->label(), 'Node preview title is equal to node title.', 'Node'); - - // Test node title is clickable on teaser list (/node). - $this->drupalGet('node'); - $this->clickLink($node->label()); - - // Test edge case where node title is set to 0. - $settings = array( - 'title' => 0, - ); - $node = $this->drupalCreateNode($settings); - // Test that 0 appears as <title>. - $this->drupalGet('node/' . $node->id()); - $this->assertTitle(0 . ' | Drupal', 'Page title is equal to 0.', 'Node'); - // Test that 0 appears in the template <h1>. - $xpath = '//h1'; - $this->assertEqual(current($this->xpath($xpath)), 0, 'Node title is displayed as 0.', 'Node'); - - // Test edge case where node title contains special characters. - $edge_case_title = 'article\'s "title".'; - $settings = array( - 'title' => $edge_case_title, - ); - $node = $this->drupalCreateNode($settings); - // Test that the title appears as <title>. The title will be escaped on the - // the page. - $edge_case_title_escaped = Html::escape($edge_case_title); - $this->drupalGet('node/' . $node->id()); - $this->assertTitle($edge_case_title_escaped . ' | Drupal', 'Page title is equal to article\'s "title".', 'Node'); - - // Test that the title appears as <title> when reloading the node page. - $this->drupalGet('node/' . $node->id()); - $this->assertTitle($edge_case_title_escaped . ' | Drupal', 'Page title is equal to article\'s "title".', 'Node'); - - } - -} diff --git a/core/modules/node/src/Tests/NodeTitleXSSTest.php b/core/modules/node/src/Tests/NodeTitleXSSTest.php deleted file mode 100644 index c4102751..00000000 --- a/core/modules/node/src/Tests/NodeTitleXSSTest.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -namespace Drupal\node\Tests; - -use Drupal\Component\Utility\Html; - -/** - * Create a node with dangerous tags in its title and test that they are - * escaped. - * - * @group node - */ -class NodeTitleXSSTest extends NodeTestBase { - /** - * Tests XSS functionality with a node entity. - */ - function testNodeTitleXSS() { - // Prepare a user to do the stuff. - $web_user = $this->drupalCreateUser(array('create page content', 'edit any page content')); - $this->drupalLogin($web_user); - - $xss = '<script>alert("xss")</script>'; - $title = $xss . $this->randomMachineName(); - $edit = array(); - $edit['title[0][value]'] = $title; - - $this->drupalPostForm('node/add/page', $edit, t('Preview')); - $this->assertNoRaw($xss, 'Harmful tags are escaped when previewing a node.'); - - $settings = array('title' => $title); - $node = $this->drupalCreateNode($settings); - - $this->drupalGet('node/' . $node->id()); - // Titles should be escaped. - $this->assertTitle(Html::escape($title) . ' | Drupal', 'Title is displayed when viewing a node.'); - $this->assertNoRaw($xss, 'Harmful tags are escaped when viewing a node.'); - - $this->drupalGet('node/' . $node->id() . '/edit'); - $this->assertNoRaw($xss, 'Harmful tags are escaped when editing a node.'); - } - -} diff --git a/core/modules/node/src/Tests/NodeTypeTest.php b/core/modules/node/src/Tests/NodeTypeTest.php index 0d2d8dea..70d3ac40 100644 --- a/core/modules/node/src/Tests/NodeTypeTest.php +++ b/core/modules/node/src/Tests/NodeTypeTest.php @@ -5,6 +5,7 @@ use Drupal\field\Entity\FieldConfig; use Drupal\node\Entity\NodeType; use Drupal\Core\Url; +use Drupal\system\Tests\Menu\AssertBreadcrumbTrait; /** * Ensures that node type functions work correctly. @@ -13,19 +14,21 @@ */ class NodeTypeTest extends NodeTestBase { + use AssertBreadcrumbTrait; + /** * Modules to enable. * * @var array */ - public static $modules = ['field_ui']; + public static $modules = ['field_ui', 'block']; /** * Ensures that node type functions (node_type_get_*) work correctly. * * Load available node types and validate the returned data. */ - function testNodeTypeGetFunctions() { + public function testNodeTypeGetFunctions() { $node_types = NodeType::loadMultiple(); $node_names = node_type_get_names(); @@ -42,7 +45,7 @@ function testNodeTypeGetFunctions() { /** * Tests creating a content type programmatically and via a form. */ - function testNodeTypeCreation() { + public function testNodeTypeCreation() { // Create a content type programmatically. $type = $this->drupalCreateContentType(); @@ -50,14 +53,14 @@ function testNodeTypeCreation() { $this->assertTrue($type_exists, 'The new content type has been created in the database.'); // Log in a test user. - $web_user = $this->drupalCreateUser(array('create ' . $type->label() . ' content')); + $web_user = $this->drupalCreateUser(['create ' . $type->label() . ' content']); $this->drupalLogin($web_user); $this->drupalGet('node/add/' . $type->id()); $this->assertResponse(200, 'The new content type can be accessed at node/add.'); // Create a content type via the user interface. - $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types')); + $web_user = $this->drupalCreateUser(['bypass node access', 'administer content types']); $this->drupalLogin($web_user); $this->drupalGet('node/add'); @@ -66,11 +69,11 @@ function testNodeTypeCreation() { $elements = $this->cssSelect('dl.node-type-list dt'); $this->assertEqual(3, count($elements)); - $edit = array( + $edit = [ 'name' => 'foo', 'title_label' => 'title for foo', 'type' => 'foo', - ); + ]; $this->drupalPostForm('admin/structure/types/add', $edit, t('Save and manage fields')); $type_exists = (bool) NodeType::load('foo'); $this->assertTrue($type_exists, 'The new content type has been created in the database.'); @@ -83,8 +86,9 @@ function testNodeTypeCreation() { /** * Tests editing a node type using the UI. */ - function testNodeTypeEditing() { - $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields')); + public function testNodeTypeEditing() { + $this->drupalPlaceBlock('system_breadcrumb_block'); + $web_user = $this->drupalCreateUser(['bypass node access', 'administer content types', 'administer node fields']); $this->drupalLogin($web_user); $field = FieldConfig::loadByName('node', 'page', 'body'); @@ -96,9 +100,9 @@ function testNodeTypeEditing() { $this->assertRaw('Body', 'Body field was found.'); // Rename the title field. - $edit = array( + $edit = [ 'title_label' => 'Foo', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); $this->drupalGet('node/add/page'); @@ -106,10 +110,10 @@ function testNodeTypeEditing() { $this->assertNoRaw('Title', 'Old title label was not displayed.'); // Change the name and the description. - $edit = array( + $edit = [ 'name' => 'Bar', 'description' => 'Lorem ipsum.', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); $this->drupalGet('node/add'); @@ -131,9 +135,15 @@ function testNodeTypeEditing() { $this->assertEqual($node_bundles['page']['label'], 'NewBar', 'Node type bundle cache is updated'); // Remove the body field. - $this->drupalPostForm('admin/structure/types/manage/page/fields/node.page.body/delete', array(), t('Delete')); + $this->drupalPostForm('admin/structure/types/manage/page/fields/node.page.body/delete', [], t('Delete')); // Resave the settings for this type. - $this->drupalPostForm('admin/structure/types/manage/page', array(), t('Save content type')); + $this->drupalPostForm('admin/structure/types/manage/page', [], t('Save content type')); + $front_page_path = Url::fromRoute('<front>')->toString(); + $this->assertBreadcrumb('admin/structure/types/manage/page/fields', [ + $front_page_path => 'Home', + 'admin/structure/types' => 'Content types', + 'admin/structure/types/manage/page' => 'NewBar', + ]); // Check that the body field doesn't exist. $this->drupalGet('node/add/page'); $this->assertNoRaw('Body', 'Body field was not found.'); @@ -142,23 +152,24 @@ function testNodeTypeEditing() { /** * Tests deleting a content type that still has content. */ - function testNodeTypeDeletion() { + public function testNodeTypeDeletion() { + $this->drupalPlaceBlock('page_title_block'); // Create a content type programmatically. $type = $this->drupalCreateContentType(); // Log in a test user. - $web_user = $this->drupalCreateUser(array( + $web_user = $this->drupalCreateUser([ 'bypass node access', 'administer content types', - )); + ]); $this->drupalLogin($web_user); // Add a new node of this type. - $node = $this->drupalCreateNode(array('type' => $type->id())); + $node = $this->drupalCreateNode(['type' => $type->id()]); // Attempt to delete the content type, which should not be allowed. $this->drupalGet('admin/structure/types/manage/' . $type->label() . '/delete'); $this->assertRaw( - t('%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', array('%type' => $type->label())), + t('%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', ['%type' => $type->label()]), 'The content type will not be deleted until all nodes of that type are removed.' ); $this->assertNoText(t('This action cannot be undone.'), 'The node type deletion confirmation form is not available.'); @@ -168,13 +179,13 @@ function testNodeTypeDeletion() { // Attempt to delete the content type, which should now be allowed. $this->drupalGet('admin/structure/types/manage/' . $type->label() . '/delete'); $this->assertRaw( - t('Are you sure you want to delete the content type %type?', array('%type' => $type->label())), + t('Are you sure you want to delete the content type %type?', ['%type' => $type->label()]), 'The content type is available for deletion.' ); $this->assertText(t('This action cannot be undone.'), 'The node type deletion confirmation form is available.'); // Test that a locked node type could not be deleted. - $this->container->get('module_installer')->install(array('node_test_config')); + $this->container->get('module_installer')->install(['node_test_config']); // Lock the default node type. $locked = \Drupal::state()->get('node.type.locked'); $locked['default'] = 'default'; @@ -186,14 +197,14 @@ function testNodeTypeDeletion() { $this->assertNoLink(t('Delete')); $this->drupalGet('admin/structure/types/manage/default/delete'); $this->assertResponse(403); - $this->container->get('module_installer')->uninstall(array('node_test_config')); + $this->container->get('module_installer')->uninstall(['node_test_config']); $this->container = \Drupal::getContainer(); unset($locked['default']); \Drupal::state()->set('node.type.locked', $locked); $this->drupalGet('admin/structure/types/manage/default'); $this->clickLink(t('Delete')); $this->assertResponse(200); - $this->drupalPostForm(NULL, array(), t('Delete')); + $this->drupalPostForm(NULL, [], t('Delete')); $this->assertFalse((bool) NodeType::load('default'), 'Node type with machine default deleted.'); } @@ -202,7 +213,7 @@ function testNodeTypeDeletion() { */ public function testNodeTypeFieldUiPermissions() { // Create an admin user who can only manage node fields. - $admin_user_1 = $this->drupalCreateUser(array('administer content types', 'administer node fields')); + $admin_user_1 = $this->drupalCreateUser(['administer content types', 'administer node fields']); $this->drupalLogin($admin_user_1); // Test that the user only sees the actions available to him. @@ -211,7 +222,7 @@ public function testNodeTypeFieldUiPermissions() { $this->assertNoLinkByHref('admin/structure/types/manage/article/display'); // Create another admin user who can manage node fields display. - $admin_user_2 = $this->drupalCreateUser(array('administer content types', 'administer node display')); + $admin_user_2 = $this->drupalCreateUser(['administer content types', 'administer node display']); $this->drupalLogin($admin_user_2); // Test that the user only sees the actions available to him. diff --git a/core/modules/node/src/Tests/NodeTypeTranslationTest.php b/core/modules/node/src/Tests/NodeTypeTranslationTest.php deleted file mode 100644 index 1c3a768c..00000000 --- a/core/modules/node/src/Tests/NodeTypeTranslationTest.php +++ /dev/null @@ -1,176 +0,0 @@ -<?php - -namespace Drupal\node\Tests; - -use Drupal\Component\Utility\Unicode; -use Drupal\language\Entity\ConfigurableLanguage; -use Drupal\simpletest\WebTestBase; - -/** - * Ensures that node types translation work correctly. - * - * Note that the child site is installed in French; therefore, when making - * assertions on translated text it is important to provide a langcode. This - * ensures the asserts pass regardless of the Drupal version. - * - * @group node - */ -class NodeTypeTranslationTest extends WebTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array( - 'block', - 'config_translation', - 'field_ui', - 'node', - ); - - /** - * The default language code to use in this test. - * - * @var array - */ - protected $defaultLangcode = 'fr'; - - /** - * Languages to enable. - * - * @var array - */ - protected $additionalLangcodes = ['es']; - - /** - * Administrator user for tests. - * - * @var \Drupal\user\UserInterface - */ - protected $adminUser; - - protected function setUp() { - parent::setUp(); - - $admin_permissions = array( - 'administer content types', - 'administer node fields', - 'administer languages', - 'administer site configuration', - 'administer themes', - 'translate configuration', - ); - - // Create and log in user. - $this->adminUser = $this->drupalCreateUser($admin_permissions); - - // Add languages. - foreach ($this->additionalLangcodes as $langcode) { - ConfigurableLanguage::createFromLangcode($langcode)->save(); - } - } - - /** - * {@inheritdoc} - * - * Install Drupal in a language other than English for this test. This is not - * needed to test the node type translation itself but acts as a regression - * test. - * - * @see https://www.drupal.org/node/2584603 - */ - protected function installParameters() { - $parameters = parent::installParameters(); - $parameters['parameters']['langcode'] = $this->defaultLangcode; - return $parameters; - } - - /** - * Tests the node type translation. - */ - public function testNodeTypeTranslation() { - $type = Unicode::strtolower($this->randomMachineName(16)); - $name = $this->randomString(); - $this->drupalLogin($this->adminUser); - $this->drupalCreateContentType(array('type' => $type, 'name' => $name)); - - // Translate the node type name. - $langcode = $this->additionalLangcodes[0]; - $translated_name = $langcode . '-' . $name; - $edit = array( - "translation[config_names][node.type.$type][name]" => $translated_name, - ); - - // Edit the title label to avoid having an exception when we save the translation. - $this->drupalPostForm("admin/structure/types/manage/$type/translate/$langcode/add", $edit, t('Save translation')); - - // Check the name is translated without admin theme for editing. - $this->drupalPostForm('admin/appearance', array('use_admin_theme' => '0'), t('Save configuration')); - $this->drupalGet("$langcode/node/add/$type"); - // This is a Spanish page, so ensure the text asserted is translated in - // Spanish and not French by adding the langcode option. - $this->assertRaw(t('Create @name', array('@name' => $translated_name), array('langcode' => $langcode))); - - // Check the name is translated with admin theme for editing. - $this->drupalPostForm('admin/appearance', array('use_admin_theme' => '1'), t('Save configuration')); - $this->drupalGet("$langcode/node/add/$type"); - // This is a Spanish page, so ensure the text asserted is translated in - // Spanish and not French by adding the langcode option. - $this->assertRaw(t('Create @name', array('@name' => $translated_name), array('langcode' => $langcode))); - } - - /** - * Tests the node type title label translation. - */ - public function testNodeTypeTitleLabelTranslation() { - $type = Unicode::strtolower($this->randomMachineName(16)); - $name = $this->randomString(); - $this->drupalLogin($this->adminUser); - $this->drupalCreateContentType(array('type' => $type, 'name' => $name)); - $langcode = $this->additionalLangcodes[0]; - - // Edit the title label for it to be displayed on the translation form. - $this->drupalPostForm("admin/structure/types/manage/$type", array('title_label' => 'Edited title'), t('Save content type')); - - // Assert that the title label is displayed on the translation form with the right value. - $this->drupalGet("admin/structure/types/manage/$type/translate/$langcode/add"); - $this->assertText('Edited title'); - - // Translate the title label. - $this->drupalPostForm(NULL, array("translation[config_names][core.base_field_override.node.$type.title][label]" => 'Translated title'), t('Save translation')); - - // Assert that the right title label is displayed on the node add form. The - // translations are created in this test; therefore, the assertions do not - // use t(). If t() were used then the correct langcodes would need to be - // provided. - $this->drupalGet("node/add/$type"); - $this->assertText('Edited title'); - $this->drupalGet("$langcode/node/add/$type"); - $this->assertText('Translated title'); - - // Add an e-mail field. - $this->drupalPostForm("admin/structure/types/manage/$type/fields/add-field", array('new_storage_type' => 'email', 'label' => 'Email', 'field_name' => 'email'), 'Save and continue'); - $this->drupalPostForm(NULL, array(), 'Save field settings'); - $this->drupalPostForm(NULL, array(), 'Save settings'); - - $type = Unicode::strtolower($this->randomMachineName(16)); - $name = $this->randomString(); - $this->drupalCreateContentType(array('type' => $type, 'name' => $name)); - - // Set tabs. - $this->drupalPlaceBlock('local_tasks_block', array('primary' => TRUE)); - - // Change default language. - $this->drupalPostForm('admin/config/regional/language', array('site_default_language' => 'es'), 'Save configuration'); - - // Try re-using the email field. - $this->drupalGet("es/admin/structure/types/manage/$type/fields/add-field"); - $this->drupalPostForm(NULL, array('existing_storage_name' => 'field_email', 'existing_storage_label' => 'Email'), 'Save and continue'); - $this->assertResponse(200); - $this->drupalGet("es/admin/structure/types/manage/$type/fields/node.$type.field_email/translate"); - $this->assertResponse(200); - $this->assertText("The configuration objects have different language codes so they cannot be translated"); - } - -} diff --git a/core/modules/node/src/Tests/PagePreviewTest.php b/core/modules/node/src/Tests/PagePreviewTest.php index 086ae827..ed4c6fa1 100644 --- a/core/modules/node/src/Tests/PagePreviewTest.php +++ b/core/modules/node/src/Tests/PagePreviewTest.php @@ -29,7 +29,7 @@ class PagePreviewTest extends NodeTestBase { * * @var array */ - public static $modules = array('node', 'taxonomy', 'comment', 'image', 'file', 'text', 'node_test', 'menu_ui'); + public static $modules = ['node', 'taxonomy', 'comment', 'image', 'file', 'text', 'node_test', 'menu_ui']; /** * The name of the created field. @@ -42,7 +42,7 @@ protected function setUp() { parent::setUp(); $this->addDefaultCommentField('node', 'page'); - $web_user = $this->drupalCreateUser(array('edit own page content', 'create page content', 'administer menu')); + $web_user = $this->drupalCreateUser(['edit own page content', 'create page content', 'administer menu']); $this->drupalLogin($web_user); // Add a vocabulary so we can test different view modes. @@ -89,37 +89,37 @@ protected function setUp() { // Create a field. $this->fieldName = Unicode::strtolower($this->randomMachineName()); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'page', $this->fieldName, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'page', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'entity_reference_autocomplete_tags', - )) + ]) ->save(); // Show on default display and teaser. entity_get_display('node', 'page', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); entity_get_display('node', 'page', 'teaser') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); entity_get_form_display('node', 'page', 'default') - ->setComponent('field_image', array( + ->setComponent('field_image', [ 'type' => 'image_image', 'settings' => [], - )) + ]) ->save(); entity_get_display('node', 'page', 'default') @@ -143,28 +143,28 @@ protected function setUp() { ])->save(); entity_get_form_display('node', 'page', 'default') - ->setComponent('field_test_multi', array( + ->setComponent('field_test_multi', [ 'type' => 'text_textfield', - )) + ]) ->save(); entity_get_display('node', 'page', 'default') - ->setComponent('field_test_multi', array( + ->setComponent('field_test_multi', [ 'type' => 'string', - )) + ]) ->save(); } /** * Checks the node preview functionality. */ - function testPagePreview() { + public function testPagePreview() { $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; $term_key = $this->fieldName . '[target_id]'; // Fill in node creation form and preview node. - $edit = array(); + $edit = []; $edit[$title_key] = '<em>' . $this->randomMachineName(8) . '</em>'; $edit[$body_key] = $this->randomMachineName(16); $edit[$term_key] = $this->term->getName(); @@ -178,7 +178,7 @@ function testPagePreview() { $this->drupalPostForm(NULL, ['field_image[0][alt]' => 'Picture of llamas'], t('Preview')); // Check that the preview is displaying the title, body and term. - $this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.'); + $this->assertTitle(t('@title | Drupal', ['@title' => $edit[$title_key]]), 'Basic page title is preview.'); $this->assertEscaped($edit[$title_key], 'Title displayed and escaped.'); $this->assertText($edit[$body_key], 'Body displayed.'); $this->assertText($edit[$term_key], 'Term displayed.'); @@ -195,7 +195,7 @@ function testPagePreview() { ->removeComponent('body') ->save(); - $view_mode_edit = array('view_mode' => 'teaser'); + $view_mode_edit = ['view_mode' => 'teaser']; $this->drupalPostForm('node/preview/' . $uuid . '/full', $view_mode_edit, t('Switch')); $this->assertRaw('view-mode-teaser', 'View mode teaser class found.'); $this->assertNoText($edit[$body_key], 'Body not displayed.'); @@ -207,20 +207,20 @@ function testPagePreview() { $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.'); $this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.'); $this->assertFieldByName('field_image[0][alt]', 'Picture of llamas'); - $this->drupalPostAjaxForm(NULL, array(), array('field_test_multi_add_more' => t('Add another item')), NULL, array(), array(), 'node-page-form'); + $this->drupalPostAjaxForm(NULL, [], ['field_test_multi_add_more' => t('Add another item')], NULL, [], [], 'node-page-form'); $this->assertFieldByName('field_test_multi[0][value]'); $this->assertFieldByName('field_test_multi[1][value]'); // Return to page preview to check everything is as expected. - $this->drupalPostForm(NULL, array(), t('Preview')); - $this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.'); + $this->drupalPostForm(NULL, [], t('Preview')); + $this->assertTitle(t('@title | Drupal', ['@title' => $edit[$title_key]]), 'Basic page title is preview.'); $this->assertEscaped($edit[$title_key], 'Title displayed and escaped.'); $this->assertText($edit[$body_key], 'Body displayed.'); $this->assertText($edit[$term_key], 'Term displayed.'); $this->assertLink(t('Back to content editing')); // Assert the content is kept when reloading the page. - $this->drupalGet('node/add/page', array('query' => array('uuid' => $uuid))); + $this->drupalGet('node/add/page', ['query' => ['uuid' => $uuid]]); $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.'); $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.'); $this->assertFieldByName($term_key, $edit[$term_key], 'Term field displayed.'); @@ -240,7 +240,7 @@ function testPagePreview() { // Check with two new terms on the edit form, additionally to the existing // one. - $edit = array(); + $edit = []; $newterm1 = $this->randomMachineName(8); $newterm2 = $this->randomMachineName(8); $edit[$term_key] = $this->term->getName() . ', ' . $newterm1 . ', ' . $newterm2; @@ -256,7 +256,7 @@ function testPagePreview() { // Check with one more new term, keeping old terms, removing the existing // one. - $edit = array(); + $edit = []; $newterm3 = $this->randomMachineName(8); $edit[$term_key] = $newterm1 . ', ' . $newterm3 . ', ' . $newterm2; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview')); @@ -270,9 +270,9 @@ function testPagePreview() { // Check that editing an existing node after it has been previewed and not // saved doesn't remember the previous changes. - $edit = array( + $edit = [ $title_key => $this->randomMachineName(8), - ); + ]; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview')); $this->assertText($edit[$title_key], 'New title displayed.'); $this->clickLink(t('Back to content editing')); @@ -289,7 +289,7 @@ function testPagePreview() { $node_type->save(); $this->drupalGet('node/add/page'); $this->assertNoRaw('edit-submit'); - $this->drupalPostForm('node/add/page', array($title_key => 'Preview'), t('Preview')); + $this->drupalPostForm('node/add/page', [$title_key => 'Preview'], t('Preview')); $this->clickLink(t('Back to content editing')); $this->assertRaw('edit-submit'); @@ -348,8 +348,8 @@ function testPagePreview() { $this->assertText('Basic page ' . $title . ' has been created.'); $node = $this->drupalGetNodeByTitle($title); $this->drupalGet('node/' . $node->id() . '/edit'); - $this->drupalPostAjaxForm(NULL, [], array('field_test_multi_add_more' => t('Add another item'))); - $this->drupalPostAjaxForm(NULL, [], array('field_test_multi_add_more' => t('Add another item'))); + $this->drupalPostAjaxForm(NULL, [], ['field_test_multi_add_more' => t('Add another item')]); + $this->drupalPostAjaxForm(NULL, [], ['field_test_multi_add_more' => t('Add another item')]); $edit = [ 'field_test_multi[1][value]' => $example_text_2, 'field_test_multi[2][value]' => $example_text_3, @@ -394,7 +394,7 @@ function testPagePreview() { /** * Checks the node preview functionality, when using revisions. */ - function testPagePreviewWithRevisions() { + public function testPagePreviewWithRevisions() { $title_key = 'title[0][value]'; $body_key = 'body[0][value]'; $term_key = $this->fieldName . '[target_id]'; @@ -404,7 +404,7 @@ function testPagePreviewWithRevisions() { $node_type->save(); // Fill in node creation form and preview node. - $edit = array(); + $edit = []; $edit[$title_key] = $this->randomMachineName(8); $edit[$body_key] = $this->randomMachineName(16); $edit[$term_key] = $this->term->id(); @@ -412,7 +412,7 @@ function testPagePreviewWithRevisions() { $this->drupalPostForm('node/add/page', $edit, t('Preview')); // Check that the preview is displaying the title, body and term. - $this->assertTitle(t('@title | Drupal', array('@title' => $edit[$title_key])), 'Basic page title is preview.'); + $this->assertTitle(t('@title | Drupal', ['@title' => $edit[$title_key]]), 'Basic page title is preview.'); $this->assertText($edit[$title_key], 'Title displayed.'); $this->assertText($edit[$body_key], 'Body displayed.'); $this->assertText($edit[$term_key], 'Term displayed.'); @@ -427,14 +427,14 @@ function testPagePreviewWithRevisions() { $this->assertFieldByName('revision_log[0][value]', $edit['revision_log[0][value]'], 'Revision log field displayed.'); // Save the node after coming back from the preview page so we can create a - // forward revision for it. + // pending revision for it. $this->drupalPostForm(NULL, [], t('Save')); $node = $this->drupalGetNodeByTitle($edit[$title_key]); - // Check that previewing a forward revision of a node works. This can not be + // Check that previewing a pending revision of a node works. This can not be // accomplished through the UI so we have to use API calls. // @todo Change this test to use the UI when we will be able to create - // forward revisions in core. + // pending revisions in core. // @see https://www.drupal.org/node/2725533 $node->setNewRevision(TRUE); $node->isDefaultRevision(FALSE); @@ -450,18 +450,18 @@ function testPagePreviewWithRevisions() { */ public function testSimultaneousPreview() { $title_key = 'title[0][value]'; - $node = $this->drupalCreateNode(array()); + $node = $this->drupalCreateNode([]); - $edit = array($title_key => 'New page title'); + $edit = [$title_key => 'New page title']; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview')); $this->assertText($edit[$title_key]); - $user2 = $this->drupalCreateUser(array('edit any page content')); + $user2 = $this->drupalCreateUser(['edit any page content']); $this->drupalLogin($user2); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertFieldByName($title_key, $node->label(), 'No title leaked from previous user.'); - $edit2 = array($title_key => 'Another page title'); + $edit2 = [$title_key => 'Another page title']; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit2, t('Preview')); $this->assertUrl(\Drupal::url('entity.node.preview', ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'], ['absolute' => TRUE])); $this->assertText($edit2[$title_key]); diff --git a/core/modules/node/src/Tests/SummaryLengthTest.php b/core/modules/node/src/Tests/SummaryLengthTest.php deleted file mode 100644 index 35eb0ddd..00000000 --- a/core/modules/node/src/Tests/SummaryLengthTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace Drupal\node\Tests; - -use Drupal\node\Entity\Node; - -/** - * Tests summary length. - * - * @group node - */ -class SummaryLengthTest extends NodeTestBase { - /** - * Tests the node summary length functionality. - */ - public function testSummaryLength() { - /** @var \Drupal\Core\Render\RendererInterface $renderer */ - $renderer = $this->container->get('renderer'); - - // Create a node to view. - $settings = array( - 'body' => array(array('value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae arcu at leo cursus laoreet. Curabitur dui tortor, adipiscing malesuada tempor in, bibendum ac diam. Cras non tellus a libero pellentesque condimentum. What is a Drupalism? Suspendisse ac lacus libero. Ut non est vel nisl faucibus interdum nec sed leo. Pellentesque sem risus, vulputate eu semper eget, auctor in libero. Ut fermentum est vitae metus convallis scelerisque. Phasellus pellentesque rhoncus tellus, eu dignissim purus posuere id. Quisque eu fringilla ligula. Morbi ullamcorper, lorem et mattis egestas, tortor neque pretium velit, eget eleifend odio turpis eu purus. Donec vitae metus quis leo pretium tincidunt a pulvinar sem. Morbi adipiscing laoreet mauris vel placerat. Nullam elementum, nisl sit amet scelerisque malesuada, dolor nunc hendrerit quam, eu ultrices erat est in orci. Curabitur feugiat egestas nisl sed accumsan.')), - 'promote' => 1, - ); - $node = $this->drupalCreateNode($settings); - $this->assertTrue(Node::load($node->id()), 'Node created.'); - - // Render the node as a teaser. - $content = $this->drupalBuildEntityView($node, 'teaser'); - $this->assertTrue(strlen($content['body'][0]['#markup']) < 600, 'Teaser is less than 600 characters long.'); - $this->setRawContent($renderer->renderRoot($content)); - // The string 'What is a Drupalism?' is between the 200th and 600th - // characters of the node body, so it should be included if the summary is - // 600 characters long. - $expected = 'What is a Drupalism?'; - $this->assertRaw($expected); - - // Change the teaser length for "Basic page" content type. - $display = entity_get_display('node', $node->getType(), 'teaser'); - $display_options = $display->getComponent('body'); - $display_options['settings']['trim_length'] = 200; - $display->setComponent('body', $display_options) - ->save(); - - // Render the node as a teaser again and check that the summary is now only - // 200 characters in length and so does not include 'What is a Drupalism?'. - $content = $this->drupalBuildEntityView($node, 'teaser'); - $this->assertTrue(strlen($content['body'][0]['#markup']) < 200, 'Teaser is less than 200 characters long.'); - $this->setRawContent($renderer->renderRoot($content)); - $this->assertText($node->label()); - $this->assertNoRaw($expected); - } - -} diff --git a/core/modules/node/src/Tests/Views/FilterUidRevisionTest.php b/core/modules/node/src/Tests/Views/FilterUidRevisionTest.php deleted file mode 100644 index 017d5eb3..00000000 --- a/core/modules/node/src/Tests/Views/FilterUidRevisionTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace Drupal\node\Tests\Views; - -use Drupal\views\Views; - -/** - * Tests the node_uid_revision handler. - * - * @group node - */ -class FilterUidRevisionTest extends NodeTestBase { - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_filter_node_uid_revision'); - - /** - * Tests the node_uid_revision filter. - */ - public function testFilter() { - $author = $this->drupalCreateUser(); - $no_author = $this->drupalCreateUser(); - - $expected_result = array(); - // Create one node, with the author as the node author. - $node = $this->drupalCreateNode(array('uid' => $author->id())); - $expected_result[] = array('nid' => $node->id()); - // Create one node of which an additional revision author will be the - // author. - $node = $this->drupalCreateNode(array('revision_uid' => $no_author->id())); - $expected_result[] = array('nid' => $node->id()); - $revision = clone $node; - // Force to add a new revision. - $revision->set('vid', NULL); - $revision->set('revision_uid', $author->id()); - $revision->save(); - - // Create one node on which the author has neither authorship of revisions - // or the main node. - $this->drupalCreateNode(array('uid' => $no_author->id())); - - $view = Views::getView('test_filter_node_uid_revision'); - $view->initHandlers(); - $view->filter['uid_revision']->value = array($author->id()); - - $this->executeView($view); - $this->assertIdenticalResultset($view, $expected_result, array('nid' => 'nid'), 'Make sure that the view only returns nodes which match either the node or the revision author.'); - } - -} diff --git a/core/modules/node/src/Tests/Views/NodeContextualLinksTest.php b/core/modules/node/src/Tests/Views/NodeContextualLinksTest.php index acd7d7b9..dc23d0ce 100644 --- a/core/modules/node/src/Tests/Views/NodeContextualLinksTest.php +++ b/core/modules/node/src/Tests/Views/NodeContextualLinksTest.php @@ -17,27 +17,27 @@ class NodeContextualLinksTest extends NodeTestBase { * * @var array */ - public static $modules = array('contextual'); + public static $modules = ['contextual']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_contextual_links'); + public static $testViews = ['test_contextual_links']; /** * Tests contextual links. */ public function testNodeContextualLinks() { - $this->drupalCreateContentType(array('type' => 'page')); - $this->drupalCreateNode(array('promote' => 1)); + $this->drupalCreateContentType(['type' => 'page']); + $this->drupalCreateNode(['promote' => 1]); $this->drupalGet('node'); - $user = $this->drupalCreateUser(array('administer nodes', 'access contextual links')); + $user = $this->drupalCreateUser(['administer nodes', 'access contextual links']); $this->drupalLogin($user); - $response = $this->renderContextualLinks(array('node:node=1:'), 'node'); + $response = $this->renderContextualLinks(['node:node=1:'], 'node'); $this->assertResponse(200); $json = Json::decode($response); $this->setRawContent($json['node:node=1:']); @@ -63,7 +63,7 @@ public function testNodeContextualLinks() { */ protected function renderContextualLinks($ids, $current_path) { // Build POST values. - $post = array(); + $post = []; for ($i = 0; $i < count($ids); $i++) { $post['ids[' . $i . ']'] = $ids[$i]; } @@ -78,15 +78,15 @@ protected function renderContextualLinks($ids, $current_path) { $post = implode('&', $post); // Perform HTTP request. - return $this->curlExec(array( - CURLOPT_URL => \Drupal::url('contextual.render', [], ['absolute' => TRUE, 'query' => array('destination' => $current_path)]), + return $this->curlExec([ + CURLOPT_URL => \Drupal::url('contextual.render', [], ['absolute' => TRUE, 'query' => ['destination' => $current_path]]), CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $post, - CURLOPT_HTTPHEADER => array( + CURLOPT_HTTPHEADER => [ 'Accept: application/json', 'Content-Type: application/x-www-form-urlencoded', - ), - )); + ], + ]); } /** @@ -108,8 +108,8 @@ public function testPageWithDisabledContextualModule() { $admin_user->pass_raw = 'new_password'; $admin_user->save(); - $this->drupalCreateContentType(array('type' => 'page')); - $this->drupalCreateNode(array('promote' => 1)); + $this->drupalCreateContentType(['type' => 'page']); + $this->drupalCreateNode(['promote' => 1]); $this->drupalLogin($admin_user); $this->drupalGet('node'); diff --git a/core/modules/node/src/Tests/Views/NodeRevisionWizardTest.php b/core/modules/node/src/Tests/Views/NodeRevisionWizardTest.php deleted file mode 100644 index 109cdc4d..00000000 --- a/core/modules/node/src/Tests/Views/NodeRevisionWizardTest.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -namespace Drupal\node\Tests\Views; - -use Drupal\views\Tests\Wizard\WizardTestBase; -use Drupal\views\Views; - -/** - * Tests the wizard with node_revision as base table. - * - * @group node - * @see \Drupal\node\Plugin\views\wizard\NodeRevision - */ -class NodeRevisionWizardTest extends WizardTestBase { - - /** - * Tests creating a node revision view. - */ - public function testViewAdd() { - $this->drupalCreateContentType(array('type' => 'article')); - // Create two nodes with two revision. - $node_storage = \Drupal::entityManager()->getStorage('node'); - /** @var \Drupal\node\NodeInterface $node */ - $node = $node_storage->create(array('title' => $this->randomString(), 'type' => 'article', 'created' => REQUEST_TIME + 40)); - $node->save(); - - $node = $node->createDuplicate(); - $node->setNewRevision(); - $node->created->value = REQUEST_TIME + 20; - $node->save(); - - $node = $node_storage->create(array('title' => $this->randomString(), 'type' => 'article', 'created' => REQUEST_TIME + 30)); - $node->save(); - - $node = $node->createDuplicate(); - $node->setNewRevision(); - $node->created->value = REQUEST_TIME + 10; - $node->save(); - - $view = array(); - $view['label'] = $this->randomMachineName(16); - $view['id'] = strtolower($this->randomMachineName(16)); - $view['description'] = $this->randomMachineName(16); - $view['page[create]'] = FALSE; - $view['show[wizard_key]'] = 'node_revision'; - $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); - - $view_storage_controller = \Drupal::entityManager()->getStorage('view'); - /** @var \Drupal\views\Entity\View $view */ - $view = $view_storage_controller->load($view['id']); - - $this->assertEqual($view->get('base_table'), 'node_field_revision'); - - $executable = Views::executableFactory()->get($view); - $this->executeView($executable); - - $this->assertIdenticalResultset($executable, array(array('vid' => 1), array('vid' => 3), array('vid' => 2), array('vid' => 4)), - array('vid' => 'vid')); - } - -} diff --git a/core/modules/node/src/Tests/Views/NodeTestBase.php b/core/modules/node/src/Tests/Views/NodeTestBase.php index 6701b417..cb765d4c 100644 --- a/core/modules/node/src/Tests/Views/NodeTestBase.php +++ b/core/modules/node/src/Tests/Views/NodeTestBase.php @@ -2,11 +2,16 @@ namespace Drupal\node\Tests\Views; +@trigger_error('\Drupal\node\Tests\Views\NodeTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\node\Functional\Views\NodeTestBase', E_USER_DEPRECATED); + use Drupal\views\Tests\ViewTestBase; use Drupal\views\Tests\ViewTestData; /** * Base class for all node tests. + * + * @deprecated Scheduled for removal before Drupal 9.0.0. + * Use \Drupal\Tests\node\Functional\Views\NodeTestBase instead. */ abstract class NodeTestBase extends ViewTestBase { @@ -15,13 +20,13 @@ abstract class NodeTestBase extends ViewTestBase { * * @var array */ - public static $modules = array('node_test_views'); + public static $modules = ['node_test_views']; protected function setUp($import_test_views = TRUE) { parent::setUp($import_test_views); if ($import_test_views) { - ViewTestData::createTestViews(get_class($this), array('node_test_views')); + ViewTestData::createTestViews(get_class($this), ['node_test_views']); } } diff --git a/core/modules/node/src/Tests/Views/RevisionRelationshipsTest.php b/core/modules/node/src/Tests/Views/RevisionRelationshipsTest.php deleted file mode 100644 index f4b34f16..00000000 --- a/core/modules/node/src/Tests/Views/RevisionRelationshipsTest.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -namespace Drupal\node\Tests\Views; - -use Drupal\views\Views; -use Drupal\views\Tests\ViewTestBase; -use Drupal\views\Tests\ViewTestData; - -/** - * Tests the integration of node_revision table of node module. - * - * @group node - */ -class RevisionRelationshipsTest extends ViewTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('node' , 'node_test_views'); - - protected function setUp() { - parent::setUp(); - - ViewTestData::createTestViews(get_class($this), array('node_test_views')); - } - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_node_revision_nid', 'test_node_revision_vid'); - - /** - * Create a node with revision and rest result count for both views. - */ - public function testNodeRevisionRelationship() { - $node = $this->drupalCreateNode(); - // Create revision of the node. - $node_revision = clone $node; - $node_revision->setNewRevision(); - $node_revision->save(); - $column_map = array( - 'vid' => 'vid', - 'node_field_data_node_field_revision_nid' => 'node_node_revision_nid', - 'nid_1' => 'nid_1', - ); - - // Here should be two rows. - $view_nid = Views::getView('test_node_revision_nid'); - $this->executeView($view_nid, array($node->id())); - $resultset_nid = array( - array( - 'vid' => '1', - 'node_node_revision_nid' => '1', - 'nid_1' => '1', - ), - array( - 'vid' => '2', - 'node_revision_nid' => '1', - 'node_node_revision_nid' => '1', - 'nid_1' => '1', - ), - ); - $this->assertIdenticalResultset($view_nid, $resultset_nid, $column_map); - - // There should be only one row with active revision 2. - $view_vid = Views::getView('test_node_revision_vid'); - $this->executeView($view_vid, array($node->id())); - $resultset_vid = array( - array( - 'vid' => '2', - 'node_node_revision_nid' => '1', - 'nid_1' => '1', - ), - ); - $this->assertIdenticalResultset($view_vid, $resultset_vid, $column_map); - } - -} diff --git a/core/modules/node/src/Tests/Views/StatusExtraTest.php b/core/modules/node/src/Tests/Views/StatusExtraTest.php deleted file mode 100644 index 6d8b7ee8..00000000 --- a/core/modules/node/src/Tests/Views/StatusExtraTest.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace Drupal\node\Tests\Views; - -/** - * Tests the node.status_extra field handler. - * - * @group node - * @see \Drupal\node\Plugin\views\filter\Status - */ -class StatusExtraTest extends NodeTestBase { - - /** - * Views used by this test. - * - * @var array - */ - public static $testViews = array('test_status_extra'); - - /** - * Tests the status extra filter. - */ - public function testStatusExtra() { - $node_author = $this->drupalCreateUser(array('view own unpublished content')); - $node_author_not_unpublished = $this->drupalCreateUser(); - $normal_user = $this->drupalCreateUser(); - $admin_user = $this->drupalCreateUser(array('bypass node access')); - - // Create one published and one unpublished node by the admin. - $node_published = $this->drupalCreateNode(array('uid' => $admin_user->id())); - $node_unpublished = $this->drupalCreateNode(array('uid' => $admin_user->id(), 'status' => NODE_NOT_PUBLISHED)); - - // Create one unpublished node by a certain author user. - $node_unpublished2 = $this->drupalCreateNode(array('uid' => $node_author->id(), 'status' => NODE_NOT_PUBLISHED)); - - // Create one unpublished node by a user who does not have the `view own - // unpublished content` permission. - $node_unpublished3 = $this->drupalCreateNode(array('uid' => $node_author_not_unpublished->id(), 'status' => NODE_NOT_PUBLISHED)); - - // The administrator should simply see all nodes. - $this->drupalLogin($admin_user); - $this->drupalGet('test_status_extra'); - $this->assertText($node_published->label()); - $this->assertText($node_unpublished->label()); - $this->assertText($node_unpublished2->label()); - $this->assertText($node_unpublished3->label()); - - // The node author should see the published node and his own node. - $this->drupalLogin($node_author); - $this->drupalGet('test_status_extra'); - $this->assertText($node_published->label()); - $this->assertNoText($node_unpublished->label()); - $this->assertText($node_unpublished2->label()); - $this->assertNoText($node_unpublished3->label()); - - // The normal user should just see the published node. - $this->drupalLogin($normal_user); - $this->drupalGet('test_status_extra'); - $this->assertText($node_published->label()); - $this->assertNoText($node_unpublished->label()); - $this->assertNoText($node_unpublished2->label()); - $this->assertNoText($node_unpublished3->label()); - - // The author without the permission to see his own unpublished node should - // just see the published node. - $this->drupalLogin($node_author_not_unpublished); - $this->drupalGet('test_status_extra'); - $this->assertText($node_published->label()); - $this->assertNoText($node_unpublished->label()); - $this->assertNoText($node_unpublished2->label()); - $this->assertNoText($node_unpublished3->label()); - } - -} diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.info.yml b/core/modules/node/tests/modules/node_access_test/node_access_test.info.yml index bd0e29b4..ebf41b04 100644 --- a/core/modules/node/tests/modules/node_access_test/node_access_test.info.yml +++ b/core/modules/node/tests/modules/node_access_test/node_access_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/modules/node_access_test/node_access_test.module index 56b53a92..40baeb53 100644 --- a/core/modules/node/tests/modules/node_access_test/node_access_test.module +++ b/core/modules/node/tests/modules/node_access_test/node_access_test.module @@ -50,15 +50,15 @@ use Drupal\node\NodeInterface; * @see node_access_test_node_access_records() */ function node_access_test_node_grants($account, $op) { - $grants = array(); - $grants['node_access_test_author'] = array($account->id()); + $grants = []; + $grants['node_access_test_author'] = [$account->id()]; if ($op == 'view' && $account->hasPermission('node test view', $account)) { - $grants['node_access_test'] = array(8888, 8889); + $grants['node_access_test'] = [8888, 8889]; } $no_access_uid = \Drupal::state()->get('node_access_test.no_access_uid') ?: 0; if ($op == 'view' && $account->id() == $no_access_uid) { - $grants['node_access_all'] = array(0); + $grants['node_access_all'] = [0]; } return $grants; } @@ -77,37 +77,37 @@ function node_access_test_node_grants($account, $op) { * @see node_access_test.permissions.yml */ function node_access_test_node_access_records(NodeInterface $node) { - $grants = array(); + $grants = []; // For NodeAccessBaseTableTestCase, only set records for private nodes. if (!\Drupal::state()->get('node_access_test.private') || $node->private->value) { // Groups 8888 and 8889 for the node_access_test realm both receive a view // grant for all controlled nodes. See node_access_test_node_grants(). - $grants[] = array( + $grants[] = [ 'realm' => 'node_access_test', 'gid' => 8888, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, - ); - $grants[] = array( + ]; + $grants[] = [ 'realm' => 'node_access_test', 'gid' => 8889, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, - ); + ]; // For the author realm, the group ID is equivalent to a user ID, which // means there are many many groups of just 1 user. - $grants[] = array( + $grants[] = [ 'realm' => 'node_access_test_author', 'gid' => $node->getOwnerId(), 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1, 'priority' => 0, - ); + ]; } return $grants; @@ -120,25 +120,25 @@ function node_access_test_node_access_records(NodeInterface $node) { * A node type entity. */ function node_access_test_add_field(NodeTypeInterface $type) { - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'private', 'entity_type' => 'node', 'type' => 'integer', - )); + ]); $field_storage->save(); - $field = FieldConfig::create(array( + $field = FieldConfig::create([ 'field_name' => 'private', 'entity_type' => 'node', 'bundle' => $type->id(), 'label' => 'Private', - )); + ]); $field->save(); // Assign widget settings for the 'default' form mode. entity_get_form_display('node', $type->id(), 'default') - ->setComponent('private', array( + ->setComponent('private', [ 'type' => 'number', - )) + ]) ->save(); } diff --git a/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.info.yml b/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.info.yml index 14a73baa..c3debb8c 100644 --- a/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.info.yml +++ b/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.module b/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.module index 67558e61..d67365a4 100644 --- a/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.module +++ b/core/modules/node/tests/modules/node_access_test_empty/node_access_test_empty.module @@ -11,12 +11,12 @@ use Drupal\node\NodeInterface; * Implements hook_node_grants(). */ function node_access_test_empty_node_grants($account, $op) { - return array(); + return []; } /** * Implements hook_node_access_records(). */ function node_access_test_empty_node_access_records(NodeInterface $node) { - return array(); + return []; } diff --git a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.info.yml b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.info.yml index 0eaa12b9..6b6d6d71 100644 --- a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.info.yml +++ b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - options -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module index ece18d82..565c100e 100644 --- a/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module +++ b/core/modules/node/tests/modules/node_access_test_language/node_access_test_language.module @@ -16,7 +16,7 @@ use Drupal\node\NodeInterface; * This module defines a single grant realm. All users belong to this group. */ function node_access_test_language_node_grants($account, $op) { - $grants['node_access_language_test'] = array(7888); + $grants['node_access_language_test'] = [7888]; return $grants; } @@ -24,13 +24,13 @@ function node_access_test_language_node_grants($account, $op) { * Implements hook_node_access_records(). */ function node_access_test_language_node_access_records(NodeInterface $node) { - $grants = array(); + $grants = []; // Create grants for each translation of the node. foreach ($node->getTranslationLanguages() as $langcode => $language) { // If the translation is not marked as private, grant access. $translation = $node->getTranslation($langcode); - $grants[] = array( + $grants[] = [ 'realm' => 'node_access_language_test', 'gid' => 7888, 'grant_view' => empty($translation->field_private->value) ? 1 : 0, @@ -38,7 +38,7 @@ function node_access_test_language_node_access_records(NodeInterface $node) { 'grant_delete' => 0, 'priority' => 0, 'langcode' => $langcode, - ); + ]; } return $grants; } diff --git a/core/modules/node/tests/modules/node_test/node_test.info.yml b/core/modules/node/tests/modules/node_test/node_test.info.yml index 84e4914f..20ab7040 100644 --- a/core/modules/node/tests/modules/node_test/node_test.info.yml +++ b/core/modules/node/tests/modules/node_test/node_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_test/node_test.module b/core/modules/node/tests/modules/node_test/node_test.module index 866be199..a2f06dec 100644 --- a/core/modules/node/tests/modules/node_test/node_test.module +++ b/core/modules/node/tests/modules/node_test/node_test.module @@ -14,30 +14,29 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\node\NodeInterface; - /** * Implements hook_ENTITY_TYPE_view() for node entities. */ function node_test_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) { if ($view_mode == 'rss') { // Add RSS elements and namespaces when building the RSS feed. - $node->rss_elements[] = array( + $node->rss_elements[] = [ 'key' => 'testElement', - 'value' => t('Value of testElement RSS element for node @nid.', array('@nid' => $node->id())), - ); + 'value' => t('Value of testElement RSS element for node @nid.', ['@nid' => $node->id()]), + ]; // Add content that should be displayed only in the RSS feed. - $build['extra_feed_content'] = array( - '#markup' => '<p>' . t('Extra data that should appear only in the RSS feed for node @nid.', array('@nid' => $node->id())) . '</p>', + $build['extra_feed_content'] = [ + '#markup' => '<p>' . t('Extra data that should appear only in the RSS feed for node @nid.', ['@nid' => $node->id()]) . '</p>', '#weight' => 10, - ); + ]; } if ($view_mode != 'rss') { // Add content that should NOT be displayed in the RSS feed. - $build['extra_non_feed_content'] = array( - '#markup' => '<p>' . t('Extra data that should appear everywhere except the RSS feed for node @nid.', array('@nid' => $node->id())) . '</p>', - ); + $build['extra_non_feed_content'] = [ + '#markup' => '<p>' . t('Extra data that should appear everywhere except the RSS feed for node @nid.', ['@nid' => $node->id()]) . '</p>', + ]; } } @@ -57,11 +56,11 @@ function node_test_node_grants(AccountInterface $account, $op) { // Give everyone full grants so we don't break other node tests. // Our node access tests asserts three realms of access. // See testGrantAlter(). - return array( - 'test_article_realm' => array(1), - 'test_page_realm' => array(1), - 'test_alter_realm' => array(2), - ); + return [ + 'test_article_realm' => [1], + 'test_page_realm' => [1], + 'test_alter_realm' => [2], + ]; } /** @@ -72,28 +71,28 @@ function node_test_node_access_records(NodeInterface $node) { if (!empty($node->disable_node_access)) { return; } - $grants = array(); + $grants = []; if ($node->getType() == 'article') { // Create grant in arbitrary article_realm for article nodes. - $grants[] = array( + $grants[] = [ 'realm' => 'test_article_realm', 'gid' => 1, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, - ); + ]; } elseif ($node->getType() == 'page') { // Create grant in arbitrary page_realm for page nodes. - $grants[] = array( + $grants[] = [ 'realm' => 'test_page_realm', 'gid' => 1, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, - ); + ]; } return $grants; } @@ -118,7 +117,7 @@ function node_test_node_access_records_alter(&$grants, NodeInterface $node) { */ function node_test_node_grants_alter(&$grants, AccountInterface $account, $op) { // Return an empty array of grants to prove that we can alter by reference. - $grants = array(); + $grants = []; } /** @@ -156,7 +155,7 @@ function node_test_node_update(NodeInterface $node) { */ function node_test_entity_view_mode_alter(&$view_mode, EntityInterface $entity, $context) { // Only alter the view mode if we are on the test callback. - $change_view_mode = \Drupal::state()->get( 'node_test_change_view_mode') ?: ''; + $change_view_mode = \Drupal::state()->get('node_test_change_view_mode') ?: ''; if ($change_view_mode) { $view_mode = $change_view_mode; } diff --git a/core/modules/node/tests/modules/node_test_config/node_test_config.info.yml b/core/modules/node/tests/modules/node_test_config/node_test_config.info.yml index 3bdbbd09..33757101 100644 --- a/core/modules/node/tests/modules/node_test_config/node_test_config.info.yml +++ b/core/modules/node/tests/modules/node_test_config/node_test_config.info.yml @@ -5,8 +5,8 @@ description: 'Support module for node configuration tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_test_exception/node_test_exception.info.yml b/core/modules/node/tests/modules/node_test_exception/node_test_exception.info.yml index d54a51ee..fd24ff3a 100644 --- a/core/modules/node/tests/modules/node_test_exception/node_test_exception.info.yml +++ b/core/modules/node/tests/modules/node_test_exception/node_test_exception.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_test_views/node_test_views.info.yml b/core/modules/node/tests/modules/node_test_views/node_test_views.info.yml index 27e15679..a56683ce 100644 --- a/core/modules/node/tests/modules/node_test_views/node_test_views.info.yml +++ b/core/modules/node/tests/modules/node_test_views/node_test_views.info.yml @@ -9,8 +9,8 @@ dependencies: - views - language -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_argument_node_uid_revision.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_argument_node_uid_revision.yml new file mode 100644 index 00000000..00ee678f --- /dev/null +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_argument_node_uid_revision.yml @@ -0,0 +1,106 @@ +langcode: en +status: true +dependencies: + module: + - node + - user +id: test_argument_node_uid_revision +label: test_argument_node_uid_revision +module: views +description: '' +tag: default +base_table: node_field_data +base_field: nid +core: 8.0-dev +display: + default: + display_options: + access: + type: perm + cache: + type: tag + exposed_form: + type: basic + fields: + nid: + id: nid + table: node_field_data + field: nid + plugin_id: field + entity_type: node + entity_field: nid + filter_groups: + groups: + 1: AND + operator: AND + filters: { } + sorts: + nid: + id: nid + table: node_field_data + field: nid + order: ASC + plugin_id: standard + relationship: none + entity_type: node + entity_field: nid + pager: + type: full + query: + type: views_query + style: + type: default + row: + type: fields + display_extenders: { } + arguments: + uid_revision: + id: uid_revision + table: node_field_data + field: uid_revision + relationship: none + group_type: group + admin_label: '' + default_action: empty + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: fixed + default_argument_options: + argument: '' + default_argument_skip_url: false + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + not: false + entity_type: node + plugin_id: node_uid_revision + display_plugin: default + display_title: Master + id: default + position: 0 + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/core/modules/node/tests/node_access_test_auto_bubbling/node_access_test_auto_bubbling.info.yml b/core/modules/node/tests/node_access_test_auto_bubbling/node_access_test_auto_bubbling.info.yml index 9f3b5568..73e48432 100644 --- a/core/modules/node/tests/node_access_test_auto_bubbling/node_access_test_auto_bubbling.info.yml +++ b/core/modules/node/tests/node_access_test_auto_bubbling/node_access_test_auto_bubbling.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/node/tests/node_access_test_auto_bubbling/src/Controller/NodeAccessTestAutoBubblingController.php b/core/modules/node/tests/node_access_test_auto_bubbling/src/Controller/NodeAccessTestAutoBubblingController.php index 19eaf8f7..46f4a5e1 100644 --- a/core/modules/node/tests/node_access_test_auto_bubbling/src/Controller/NodeAccessTestAutoBubblingController.php +++ b/core/modules/node/tests/node_access_test_auto_bubbling/src/Controller/NodeAccessTestAutoBubblingController.php @@ -4,40 +4,13 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Entity\Query\QueryFactory; -use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\node\NodeInterface; /** * Returns a node ID listing. */ class NodeAccessTestAutoBubblingController extends ControllerBase implements ContainerInjectionInterface { - /** - * The entity query factory service. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $entityQuery; - - /** - * Constructs a new NodeAccessTestAutoBubblingController. - * - * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query - * The entity query factory. - */ - public function __construct(QueryFactory $entity_query) { - $this->entityQuery = $entity_query; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.query') - ); - } - /** * Lists the three latest published node IDs. * @@ -45,8 +18,8 @@ public static function create(ContainerInterface $container) { * A render array. */ public function latest() { - $nids = $this->entityQuery->get('node') - ->condition('status', NODE_PUBLISHED) + $nids = $this->entityTypeManager()->getStorage('node')->getQuery() + ->condition('status', NodeInterface::PUBLISHED) ->sort('created', 'DESC') ->range(0, 3) ->execute(); diff --git a/core/modules/node/tests/src/Functional/AssertButtonsTrait.php b/core/modules/node/tests/src/Functional/AssertButtonsTrait.php new file mode 100644 index 00000000..bc2ef907 --- /dev/null +++ b/core/modules/node/tests/src/Functional/AssertButtonsTrait.php @@ -0,0 +1,49 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +/** + * Asserts that buttons are present on a page. + */ +trait AssertButtonsTrait { + + /** + * Assert method to verify the buttons in the dropdown element. + * + * @param array $buttons + * A collection of buttons to assert for on the page. + * @param bool $dropbutton + * Whether to check if the buttons are in a dropbutton widget or not. + */ + public function assertButtons(array $buttons, $dropbutton = TRUE) { + + // Try to find a Save button. + $save_button = $this->xpath('//input[@type="submit"][@value="Save"]'); + + // Verify that the number of buttons passed as parameters is + // available in the dropbutton widget. + if ($dropbutton) { + $i = 0; + $count = count($buttons); + + // Assert there is no save button. + $this->assertTrue(empty($save_button)); + + // Dropbutton elements. + /** @var \Behat\Mink\Element\NodeElement[] $elements */ + $elements = $this->xpath('//div[@class="dropbutton-wrapper"]//input[@type="submit"]'); + $this->assertEqual($count, count($elements)); + foreach ($elements as $element) { + $value = $element->getValue() ?: ''; + $this->assertEqual($buttons[$i], $value); + $i++; + } + } + else { + // Assert there is a save button. + $this->assertTrue(!empty($save_button)); + $this->assertNoRaw('dropbutton-wrapper'); + } + } + +} diff --git a/core/modules/node/src/Tests/Migrate/d6/MigrateNodeRevisionTest.php b/core/modules/node/tests/src/Functional/Migrate/d6/MigrateNodeRevisionTest.php similarity index 92% rename from core/modules/node/src/Tests/Migrate/d6/MigrateNodeRevisionTest.php rename to core/modules/node/tests/src/Functional/Migrate/d6/MigrateNodeRevisionTest.php index a02ef3f1..075e7276 100644 --- a/core/modules/node/src/Tests/Migrate/d6/MigrateNodeRevisionTest.php +++ b/core/modules/node/tests/src/Functional/Migrate/d6/MigrateNodeRevisionTest.php @@ -1,6 +1,7 @@ <?php -namespace Drupal\node\Tests\Migrate\d6; +namespace Drupal\Tests\node\Functional\Migrate\d6; + use Drupal\Tests\node\Kernel\Migrate\d6\MigrateNodeTestBase; /** @@ -13,7 +14,7 @@ class MigrateNodeRevisionTest extends MigrateNodeTestBase { /** * {@inheritdoc} */ - public static $modules = ['language', 'content_translation']; + public static $modules = ['language', 'content_translation', 'menu_ui']; /** * {@inheritdoc} diff --git a/core/modules/node/src/Tests/Migrate/d7/NodeMigrateDeriverTest.php b/core/modules/node/tests/src/Functional/Migrate/d7/NodeMigrateDeriverTest.php similarity index 96% rename from core/modules/node/src/Tests/Migrate/d7/NodeMigrateDeriverTest.php rename to core/modules/node/tests/src/Functional/Migrate/d7/NodeMigrateDeriverTest.php index e57dcbd3..621cdb6d 100644 --- a/core/modules/node/src/Tests/Migrate/d7/NodeMigrateDeriverTest.php +++ b/core/modules/node/tests/src/Functional/Migrate/d7/NodeMigrateDeriverTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests\Migrate\d7; +namespace Drupal\Tests\node\Functional\Migrate\d7; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; diff --git a/core/modules/node/src/Tests/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php similarity index 83% rename from core/modules/node/src/Tests/MultiStepNodeFormBasicOptionsTest.php rename to core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php index c23986ae..fbdb200c 100644 --- a/core/modules/node/src/Tests/MultiStepNodeFormBasicOptionsTest.php +++ b/core/modules/node/tests/src/Functional/MultiStepNodeFormBasicOptionsTest.php @@ -1,6 +1,7 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; + use Drupal\Component\Utility\Unicode; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; @@ -22,19 +23,19 @@ class MultiStepNodeFormBasicOptionsTest extends NodeTestBase { /** * Tests changing the default values of basic options to ensure they persist. */ - function testMultiStepNodeFormBasicOptions() { + public function testMultiStepNodeFormBasicOptions() { // Prepare a user to create the node. - $web_user = $this->drupalCreateUser(array('administer nodes', 'create page content')); + $web_user = $this->drupalCreateUser(['administer nodes', 'create page content']); $this->drupalLogin($web_user); // Create an unlimited cardinality field. $this->fieldName = Unicode::strtolower($this->randomMachineName()); - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'node', 'type' => 'text', 'cardinality' => -1, - ))->save(); + ])->save(); // Attach an instance of the field to the page content type. FieldConfig::create([ @@ -44,17 +45,17 @@ function testMultiStepNodeFormBasicOptions() { 'label' => $this->randomMachineName() . '_label', ])->save(); entity_get_form_display('node', 'page', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'text_textfield', - )) + ]) ->save(); - $edit = array( + $edit = [ 'title[0][value]' => 'a', 'promote[value]' => FALSE, 'sticky[value]' => 1, "{$this->fieldName}[0][value]" => $this->randomString(32), - ); + ]; $this->drupalPostForm('node/add/page', $edit, t('Add another item')); $this->assertNoFieldChecked('edit-promote-value', 'Promote stayed unchecked'); $this->assertFieldChecked('edit-sticky-value', 'Sticky stayed checked'); diff --git a/core/modules/node/src/Tests/NodeAccessAutoBubblingTest.php b/core/modules/node/tests/src/Functional/NodeAccessAutoBubblingTest.php similarity index 91% rename from core/modules/node/src/Tests/NodeAccessAutoBubblingTest.php rename to core/modules/node/tests/src/Functional/NodeAccessAutoBubblingTest.php index 789818b4..20154553 100644 --- a/core/modules/node/src/Tests/NodeAccessAutoBubblingTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessAutoBubblingTest.php @@ -1,8 +1,9 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Url; +use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait; /** * Tests the node access automatic cacheability bubbling logic. @@ -13,6 +14,8 @@ */ class NodeAccessAutoBubblingTest extends NodeTestBase { + use AssertPageCacheContextsAndTagsTrait; + /** * Modules to enable. * diff --git a/core/modules/node/src/Tests/NodeAccessBaseTableTest.php b/core/modules/node/tests/src/Functional/NodeAccessBaseTableTest.php similarity index 84% rename from core/modules/node/src/Tests/NodeAccessBaseTableTest.php rename to core/modules/node/tests/src/Functional/NodeAccessBaseTableTest.php index 74e2340c..d9e4e8b0 100644 --- a/core/modules/node/src/Tests/NodeAccessBaseTableTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessBaseTableTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\node\Entity\NodeType; @@ -16,7 +16,7 @@ class NodeAccessBaseTableTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_access_test', 'views'); + public static $modules = ['node_access_test', 'views']; /** * The installation profile to use with this test. @@ -83,25 +83,25 @@ protected function setUp() { * - Test that user 4 can view all content created above. * - Test that user 4 can view all content on taxonomy listing. */ - function testNodeAccessBasic() { + public function testNodeAccessBasic() { $num_simple_users = 2; - $simple_users = array(); + $simple_users = []; // Nodes keyed by uid and nid: $nodes[$uid][$nid] = $is_private; - $this->nodesByUser = array(); + $this->nodesByUser = []; // Titles keyed by nid. $titles = []; // Array of nids marked private. $private_nodes = []; for ($i = 0; $i < $num_simple_users; $i++) { - $simple_users[$i] = $this->drupalCreateUser(array('access content', 'create article content')); + $simple_users[$i] = $this->drupalCreateUser(['access content', 'create article content']); } foreach ($simple_users as $this->webUser) { $this->drupalLogin($this->webUser); - foreach (array(0 => 'Public', 1 => 'Private') as $is_private => $type) { - $edit = array( - 'title[0][value]' => t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $this->webUser->getUsername())), - ); + foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) { + $edit = [ + 'title[0][value]' => t('@private_public Article created by @user', ['@private_public' => $type, '@user' => $this->webUser->getUsername()]), + ]; if ($is_private) { $edit['private[0][value]'] = TRUE; $edit['body[0][value]'] = 'private node'; @@ -114,7 +114,7 @@ function testNodeAccessBasic() { $this->drupalPostForm('node/add/article', $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); - $this->assertEqual($is_private, (int)$node->private->value, 'The private status of the node was properly set in the node_access_test table.'); + $this->assertEqual($is_private, (int) $node->private->value, 'The private status of the node was properly set in the node_access_test table.'); if ($is_private) { $private_nodes[] = $node->id(); } @@ -122,8 +122,8 @@ function testNodeAccessBasic() { $this->nodesByUser[$this->webUser->id()][$node->id()] = $is_private; } } - $this->publicTid = db_query('SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1', array(':name' => 'public'))->fetchField(); - $this->privateTid = db_query('SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1', array(':name' => 'private'))->fetchField(); + $this->publicTid = db_query('SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1', [':name' => 'public'])->fetchField(); + $this->privateTid = db_query('SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1', [':name' => 'private'])->fetchField(); $this->assertTrue($this->publicTid, 'Public tid was found'); $this->assertTrue($this->privateTid, 'Private tid was found'); foreach ($simple_users as $this->webUser) { @@ -138,12 +138,12 @@ function testNodeAccessBasic() { else { $should_be_visible = TRUE; } - $this->assertResponse($should_be_visible ? 200 : 403, strtr('A %private node by user %uid is %visible for user %current_uid.', array( + $this->assertResponse($should_be_visible ? 200 : 403, strtr('A %private node by user %uid is %visible for user %current_uid.', [ '%private' => $is_private ? 'private' : 'public', '%uid' => $uid, '%visible' => $should_be_visible ? 'visible' : 'not visible', '%current_uid' => $this->webUser->id(), - ))); + ])); } } @@ -153,7 +153,7 @@ function testNodeAccessBasic() { } // Now test that a user with 'node test view' permissions can view content. - $access_user = $this->drupalCreateUser(array('access content', 'create article content', 'node test view', 'search content')); + $access_user = $this->drupalCreateUser(['access content', 'create article content', 'node test view', 'search content']); $this->drupalLogin($access_user); foreach ($this->nodesByUser as $private_status) { @@ -193,12 +193,12 @@ function testNodeAccessBasic() { * user's own private nodes should be listed. */ protected function assertTaxonomyPage($is_admin) { - foreach (array($this->publicTid, $this->privateTid) as $tid_is_private => $tid) { + foreach ([$this->publicTid, $this->privateTid] as $tid_is_private => $tid) { $this->drupalGet("taxonomy/term/$tid"); $this->nidsVisible = []; foreach ($this->xpath("//a[text()='Read more']") as $link) { // See also testTranslationRendering() in NodeTranslationUITest. - $this->assertTrue(preg_match('|node/(\d+)$|', (string) $link['href'], $matches), 'Read more points to a node'); + $this->assertTrue(preg_match('|node/(\d+)$|', $link->getAttribute('href'), $matches), 'Read more points to a node'); $this->nidsVisible[$matches[1]] = TRUE; } foreach ($this->nodesByUser as $uid => $data) { @@ -211,13 +211,13 @@ protected function assertTaxonomyPage($is_admin) { if (!$is_admin && $tid_is_private) { $should_be_visible = $should_be_visible && $uid == $this->webUser->id(); } - $this->assertIdentical(isset($this->nidsVisible[$nid]), $should_be_visible, strtr('A %private node by user %uid is %visible for user %current_uid on the %tid_is_private page.', array( + $this->assertIdentical(isset($this->nidsVisible[$nid]), $should_be_visible, strtr('A %private node by user %uid is %visible for user %current_uid on the %tid_is_private page.', [ '%private' => $is_private ? 'private' : 'public', '%uid' => $uid, '%visible' => isset($this->nidsVisible[$nid]) ? 'visible' : 'not visible', '%current_uid' => $this->webUser->id(), '%tid_is_private' => $tid_is_private ? 'private' : 'public', - ))); + ])); } } } diff --git a/core/modules/node/src/Tests/NodeAccessFieldTest.php b/core/modules/node/tests/src/Functional/NodeAccessFieldTest.php similarity index 84% rename from core/modules/node/src/Tests/NodeAccessFieldTest.php rename to core/modules/node/tests/src/Functional/NodeAccessFieldTest.php index dcfa43d9..8028ec9f 100644 --- a/core/modules/node/src/Tests/NodeAccessFieldTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessFieldTest.php @@ -1,6 +1,7 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; + use Drupal\Component\Utility\Unicode; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; @@ -17,7 +18,7 @@ class NodeAccessFieldTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_access_test', 'field_ui'); + public static $modules = ['node_access_test', 'field_ui']; /** * A user with permission to bypass access content. @@ -46,16 +47,16 @@ protected function setUp() { node_access_rebuild(); // Create some users. - $this->adminUser = $this->drupalCreateUser(array('access content', 'bypass node access')); - $this->contentAdminUser = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields')); + $this->adminUser = $this->drupalCreateUser(['access content', 'bypass node access']); + $this->contentAdminUser = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields']); // Add a custom field to the page content type. $this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name'); - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'node', 'type' => 'text' - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'node', @@ -72,11 +73,11 @@ protected function setUp() { /** * Tests administering fields when node access is restricted. */ - function testNodeAccessAdministerField() { + public function testNodeAccessAdministerField() { // Create a page node. - $fieldData = array(); + $fieldData = []; $value = $fieldData[0]['value'] = $this->randomMachineName(); - $node = $this->drupalCreateNode(array($this->fieldName => $fieldData)); + $node = $this->drupalCreateNode([$this->fieldName => $fieldData]); // Log in as the administrator and confirm that the field value is present. $this->drupalLogin($this->adminUser); @@ -89,7 +90,7 @@ function testNodeAccessAdministerField() { $this->assertText('Access denied', 'Access is denied for the content admin.'); // Modify the field default as the content admin. - $edit = array(); + $edit = []; $default = 'Sometimes words have two meanings'; $edit["default_value_input[{$this->fieldName}][0][value]"] = $default; $this->drupalPostForm( diff --git a/core/modules/node/src/Tests/NodeAccessGrantsCacheContextTest.php b/core/modules/node/tests/src/Functional/NodeAccessGrantsCacheContextTest.php similarity index 89% rename from core/modules/node/src/Tests/NodeAccessGrantsCacheContextTest.php rename to core/modules/node/tests/src/Functional/NodeAccessGrantsCacheContextTest.php index 59321086..fa2116ab 100644 --- a/core/modules/node/src/Tests/NodeAccessGrantsCacheContextTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessGrantsCacheContextTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; /** * Tests the node access grants cache context service. @@ -15,7 +15,7 @@ class NodeAccessGrantsCacheContextTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_access_test'); + public static $modules = ['node_access_test']; /** * User with permission to view content. @@ -43,9 +43,9 @@ protected function setUp() { // Create user with simple node access permission. The 'node test view' // permission is implemented and granted by the node_access_test module. - $this->accessUser = $this->drupalCreateUser(array('access content overview', 'access content', 'node test view')); - $this->noAccessUser = $this->drupalCreateUser(array('access content overview', 'access content')); - $this->noAccessUser2 = $this->drupalCreateUser(array('access content overview', 'access content')); + $this->accessUser = $this->drupalCreateUser(['access content overview', 'access content', 'node test view']); + $this->noAccessUser = $this->drupalCreateUser(['access content overview', 'access content']); + $this->noAccessUser2 = $this->drupalCreateUser(['access content overview', 'access content']); $this->userMapping = [ 1 => $this->rootUser, @@ -84,14 +84,14 @@ public function testCacheContext() { // Grant view to all nodes (because nid = 0) for users in the // 'node_access_all' realm. - $record = array( + $record = [ 'nid' => 0, 'gid' => 0, 'realm' => 'node_access_all', 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, - ); + ]; db_insert('node_access')->fields($record)->execute(); // Put user accessUser (uid 0) in the realm. diff --git a/core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php b/core/modules/node/tests/src/Functional/NodeAccessLanguageAwareCombinationTest.php similarity index 88% rename from core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php rename to core/modules/node/tests/src/Functional/NodeAccessLanguageAwareCombinationTest.php index 1ee5bc27..e388afcb 100644 --- a/core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessLanguageAwareCombinationTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Language\LanguageInterface; use Drupal\field\Entity\FieldConfig; @@ -22,14 +22,14 @@ class NodeAccessLanguageAwareCombinationTest extends NodeTestBase { * * @var array */ - public static $modules = array('language', 'node_access_test_language', 'node_access_test'); + public static $modules = ['language', 'node_access_test_language', 'node_access_test']; /** * A set of nodes to use in testing. * * @var \Drupal\node\NodeInterface[] */ - protected $nodes = array(); + protected $nodes = []; /** * A normal authenticated user. @@ -52,24 +52,24 @@ protected function setUp() { // Create the 'private' field, which allows the node to be marked as private // (restricted access) in a given translation. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'field_private', 'entity_type' => 'node', 'type' => 'boolean', 'cardinality' => 1, - )); + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => 'page', - 'widget' => array( + 'widget' => [ 'type' => 'options_buttons', - ), - 'settings' => array( + ], + 'settings' => [ 'on_label' => 'Private', 'off_label' => 'Not private', - ), + ], ])->save(); // After enabling a node access module, the access table has to be rebuild. @@ -80,7 +80,7 @@ protected function setUp() { ConfigurableLanguage::createFromLangcode('ca')->save(); // Create a normal authenticated user. - $this->webUser = $this->drupalCreateUser(array('access content')); + $this->webUser = $this->drupalCreateUser(['access content']); // Load the user 1 user for later use as an admin user with permission to // see everything. @@ -101,101 +101,101 @@ protected function setUp() { // 4. One public with only the Catalan translation private. // 5. One public with both the Hungarian and Catalan translations private. // 6. One private with both the Hungarian and Catalan translations private. - $this->nodes['public_both_public'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['public_both_public'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 0)), + 'field_private' => [['value' => 0]], 'private' => FALSE, - )); + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); - $this->nodes['private_both_public'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['private_both_public'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 0)), + 'field_private' => [['value' => 0]], 'private' => TRUE, - )); + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); - $this->nodes['public_hu_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['public_hu_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 1)), + 'field_private' => [['value' => 1]], 'private' => FALSE, - )); + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); - $this->nodes['public_ca_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['public_ca_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 0)), + 'field_private' => [['value' => 0]], 'private' => FALSE, - )); + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); - $this->nodes['public_both_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['public_both_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 1)), + 'field_private' => [['value' => 1]], 'private' => FALSE, - )); + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); - $this->nodes['private_both_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['private_both_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 1)), + 'field_private' => [['value' => 1]], 'private' => TRUE, - )); + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); - $this->nodes['public_no_language_private'] = $this->drupalCreateNode(array( - 'field_private' => array(array('value' => 1)), + $this->nodes['public_no_language_private'] = $this->drupalCreateNode([ + 'field_private' => [['value' => 1]], 'private' => FALSE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $this->nodes['public_no_language_public'] = $this->drupalCreateNode(array( - 'field_private' => array(array('value' => 0)), + ]); + $this->nodes['public_no_language_public'] = $this->drupalCreateNode([ + 'field_private' => [['value' => 0]], 'private' => FALSE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $this->nodes['private_no_language_private'] = $this->drupalCreateNode(array( - 'field_private' => array(array('value' => 1)), + ]); + $this->nodes['private_no_language_private'] = $this->drupalCreateNode([ + 'field_private' => [['value' => 1]], 'private' => TRUE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $this->nodes['private_no_language_public'] = $this->drupalCreateNode(array( - 'field_private' => array(array('value' => 1)), + ]); + $this->nodes['private_no_language_public'] = $this->drupalCreateNode([ + 'field_private' => [['value' => 1]], 'private' => TRUE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); } /** * Tests node access and node access queries with multiple node languages. */ - function testNodeAccessLanguageAwareCombination() { + public function testNodeAccessLanguageAwareCombination() { - $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE); - $expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE); + $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE]; + $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE]; // When the node and both translations are public, access should always be // granted. @@ -254,7 +254,7 @@ function testNodeAccessLanguageAwareCombination() { // Query with no language specified. The fallback (hu or und) will be used. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addTag('node_access'); $nids = $select->execute()->fetchAllAssoc('nid'); @@ -269,7 +269,7 @@ function testNodeAccessLanguageAwareCombination() { // Query with Hungarian (hu) specified. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addMetaData('langcode', 'hu') ->addTag('node_access'); @@ -283,7 +283,7 @@ function testNodeAccessLanguageAwareCombination() { // Query with Catalan (ca) specified. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addMetaData('langcode', 'ca') ->addTag('node_access'); @@ -297,7 +297,7 @@ function testNodeAccessLanguageAwareCombination() { // Query with German (de) specified. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addMetaData('langcode', 'de') ->addTag('node_access'); @@ -309,7 +309,7 @@ function testNodeAccessLanguageAwareCombination() { // Query the nodes table as admin user (full access) with the node access // tag and no specific langcode. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->adminUser) ->addTag('node_access'); $nids = $select->execute()->fetchAllAssoc('nid'); @@ -320,7 +320,7 @@ function testNodeAccessLanguageAwareCombination() { // Query the nodes table as admin user (full access) with the node access // tag and langcode de. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->adminUser) ->addMetaData('langcode', 'de') ->addTag('node_access'); diff --git a/core/modules/node/src/Tests/NodeAccessLanguageAwareTest.php b/core/modules/node/tests/src/Functional/NodeAccessLanguageAwareTest.php similarity index 88% rename from core/modules/node/src/Tests/NodeAccessLanguageAwareTest.php rename to core/modules/node/tests/src/Functional/NodeAccessLanguageAwareTest.php index 0609b7ba..48f9dfac 100644 --- a/core/modules/node/src/Tests/NodeAccessLanguageAwareTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessLanguageAwareTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Language\LanguageInterface; use Drupal\field\Entity\FieldConfig; @@ -21,14 +21,14 @@ class NodeAccessLanguageAwareTest extends NodeTestBase { * * @var array */ - public static $modules = array('language', 'node_access_test_language'); + public static $modules = ['language', 'node_access_test_language']; /** * A set of nodes to use in testing. * * @var \Drupal\node\NodeInterface[] */ - protected $nodes = array(); + protected $nodes = []; /** * A user with permission to bypass access content. @@ -49,31 +49,31 @@ protected function setUp() { // Create the 'private' field, which allows the node to be marked as private // (restricted access) in a given translation. - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => 'field_private', 'entity_type' => 'node', 'type' => 'boolean', 'cardinality' => 1, - )); + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => 'page', - 'widget' => array( + 'widget' => [ 'type' => 'options_buttons', - ), - 'settings' => array( + ], + 'settings' => [ 'on_label' => 'Private', 'off_label' => 'Not private', - ), + ], ])->save(); // After enabling a node access module, the access table has to be rebuild. node_access_rebuild(); // Create a normal authenticated user. - $this->webUser = $this->drupalCreateUser(array('access content')); + $this->webUser = $this->drupalCreateUser(['access content']); // Load the user 1 user for later use as an admin user with permission to // see everything. @@ -95,63 +95,63 @@ protected function setUp() { // 2. Two nodes with no language specified. // - One public. // - One private. - $this->nodes['both_public'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['both_public'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 0)), - )); + 'field_private' => [['value' => 0]], + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); - $this->nodes['ca_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['ca_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 0)), - )); + 'field_private' => [['value' => 0]], + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); - $this->nodes['hu_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['hu_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 1)), - )); + 'field_private' => [['value' => 1]], + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); - $this->nodes['both_private'] = $node = $this->drupalCreateNode(array( - 'body' => array(array()), + $this->nodes['both_private'] = $node = $this->drupalCreateNode([ + 'body' => [[]], 'langcode' => 'hu', - 'field_private' => array(array('value' => 1)), - )); + 'field_private' => [['value' => 1]], + ]); $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); - $this->nodes['no_language_public'] = $this->drupalCreateNode(array( - 'field_private' => array(array('value' => 0)), + $this->nodes['no_language_public'] = $this->drupalCreateNode([ + 'field_private' => [['value' => 0]], 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); - $this->nodes['no_language_private'] = $this->drupalCreateNode(array( - 'field_private' => array(array('value' => 1)), + ]); + $this->nodes['no_language_private'] = $this->drupalCreateNode([ + 'field_private' => [['value' => 1]], 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); } /** * Tests node access and node access queries with multiple node languages. */ - function testNodeAccessLanguageAware() { + public function testNodeAccessLanguageAware() { // The node_access_test_language module only grants view access. - $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE); - $expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE); + $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE]; + $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE]; // When both Hungarian and Catalan are marked as public, access to the // Hungarian translation should be granted with the default entity object or @@ -195,7 +195,7 @@ function testNodeAccessLanguageAware() { // Query with no language specified. The fallback (hu) will be used. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addTag('node_access'); $nids = $select->execute()->fetchAllAssoc('nid'); @@ -211,7 +211,7 @@ function testNodeAccessLanguageAware() { // Query with Hungarian (hu) specified. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addMetaData('langcode', 'hu') ->addTag('node_access'); @@ -225,7 +225,7 @@ function testNodeAccessLanguageAware() { // Query with Catalan (ca) specified. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addMetaData('langcode', 'ca') ->addTag('node_access'); @@ -239,7 +239,7 @@ function testNodeAccessLanguageAware() { // Query with German (de) specified. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->webUser) ->addMetaData('langcode', 'de') ->addTag('node_access'); @@ -251,7 +251,7 @@ function testNodeAccessLanguageAware() { // Query the nodes table as admin user (full access) with the node access // tag and no specific langcode. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->adminUser) ->addTag('node_access'); $nids = $select->execute()->fetchAllAssoc('nid'); @@ -262,7 +262,7 @@ function testNodeAccessLanguageAware() { // Query the nodes table as admin user (full access) with the node access // tag and langcode de. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $this->adminUser) ->addMetaData('langcode', 'de') ->addTag('node_access'); diff --git a/core/modules/node/src/Tests/NodeAccessLanguageTest.php b/core/modules/node/tests/src/Functional/NodeAccessLanguageTest.php similarity index 84% rename from core/modules/node/src/Tests/NodeAccessLanguageTest.php rename to core/modules/node/tests/src/Functional/NodeAccessLanguageTest.php index e0393a0a..1af5660f 100644 --- a/core/modules/node/src/Tests/NodeAccessLanguageTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessLanguageTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Language\LanguageInterface; use Drupal\language\Entity\ConfigurableLanguage; @@ -20,7 +20,7 @@ class NodeAccessLanguageTest extends NodeTestBase { * * @var array */ - public static $modules = array('language', 'node_access_test'); + public static $modules = ['language', 'node_access_test']; protected function setUp() { parent::setUp(); @@ -42,15 +42,15 @@ protected function setUp() { /** * Tests node access with multiple node languages and no private nodes. */ - function testNodeAccess() { - $web_user = $this->drupalCreateUser(array('access content')); + public function testNodeAccess() { + $web_user = $this->drupalCreateUser(['access content']); - $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE); - $expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE); + $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE]; + $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE]; // Creating a public node with langcode Hungarian, will be saved as the // fallback in node access table. - $node_public_hu = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => FALSE)); + $node_public_hu = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => FALSE]); $this->assertTrue($node_public_hu->language()->getId() == 'hu', 'Node created as Hungarian.'); // Tests the default access is provided for the public Hungarian node. @@ -61,10 +61,10 @@ function testNodeAccess() { // Creating a public node with no special langcode, like when no language // module enabled. - $node_public_no_language = $this->drupalCreateNode(array( + $node_public_no_language = $this->drupalCreateNode([ 'private' => FALSE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); $this->assertTrue($node_public_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.'); // Tests that access is granted if requested with no language. @@ -73,7 +73,7 @@ function testNodeAccess() { // Reset the node access cache and turn on our test node access code. \Drupal::entityManager()->getAccessControlHandler('node')->resetCache(); \Drupal::state()->set('node_access_test_secret_catalan', 1); - $node_public_ca = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'ca', 'private' => FALSE)); + $node_public_ca = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'ca', 'private' => FALSE]); $this->assertTrue($node_public_ca->language()->getId() == 'ca', 'Node created as Catalan.'); // Tests that access is granted if requested with no language. @@ -112,14 +112,14 @@ function testNodeAccess() { /** * Tests node access with multiple node languages and private nodes. */ - function testNodeAccessPrivate() { - $web_user = $this->drupalCreateUser(array('access content')); - $expected_node_access = array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE); - $expected_node_access_no_access = array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE); + public function testNodeAccessPrivate() { + $web_user = $this->drupalCreateUser(['access content']); + $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE]; + $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE]; // Creating a private node with langcode Hungarian, will be saved as the // fallback in node access table. - $node_private_hu = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => TRUE)); + $node_private_hu = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => TRUE]); $this->assertTrue($node_private_hu->language()->getId() == 'hu', 'Node created as Hungarian.'); // Tests the default access is not provided for the private Hungarian node. @@ -130,10 +130,10 @@ function testNodeAccessPrivate() { // Creating a private node with no special langcode, like when no language // module enabled. - $node_private_no_language = $this->drupalCreateNode(array( + $node_private_no_language = $this->drupalCreateNode([ 'private' => TRUE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); $this->assertTrue($node_private_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.'); // Tests that access is not granted if requested with no language. @@ -148,8 +148,8 @@ function testNodeAccessPrivate() { // Creating a private node with langcode Catalan to test that the // node_access_test_secret_catalan flag works. - $private_ca_user = $this->drupalCreateUser(array('access content', 'node test view')); - $node_private_ca = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'ca', 'private' => TRUE)); + $private_ca_user = $this->drupalCreateUser(['access content', 'node test view']); + $node_private_ca = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'ca', 'private' => TRUE]); $this->assertTrue($node_private_ca->language()->getId() == 'ca', 'Node created as Catalan.'); // Tests that Catalan is still not accessible to either user. @@ -175,9 +175,9 @@ function testNodeAccessPrivate() { /** * Tests db_select() with a 'node_access' tag and langcode metadata. */ - function testNodeAccessQueryTag() { + public function testNodeAccessQueryTag() { // Create a normal authenticated user. - $web_user = $this->drupalCreateUser(array('access content')); + $web_user = $this->drupalCreateUser(['access content']); // Load the user 1 user for later use as an admin user with permission to // see everything. @@ -185,26 +185,26 @@ function testNodeAccessQueryTag() { // Creating a private node with langcode Hungarian, will be saved as // the fallback in node access table. - $node_private = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => TRUE)); + $node_private = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => TRUE]); $this->assertTrue($node_private->language()->getId() == 'hu', 'Node created as Hungarian.'); // Creating a public node with langcode Hungarian, will be saved as // the fallback in node access table. - $node_public = $this->drupalCreateNode(array('body' => array(array()), 'langcode' => 'hu', 'private' => FALSE)); + $node_public = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => FALSE]); $this->assertTrue($node_public->language()->getId() == 'hu', 'Node created as Hungarian.'); // Creating a public node with no special langcode, like when no language // module enabled. - $node_no_language = $this->drupalCreateNode(array( + $node_no_language = $this->drupalCreateNode([ 'private' => FALSE, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); $this->assertTrue($node_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.'); // Query the nodes table as the web user with the node access tag and no // specific langcode. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $web_user) ->addTag('node_access'); $nids = $select->execute()->fetchAllAssoc('nid'); @@ -218,7 +218,7 @@ function testNodeAccessQueryTag() { // Query the nodes table as the web user with the node access tag and // langcode de. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $web_user) ->addMetaData('langcode', 'de') ->addTag('node_access'); @@ -230,7 +230,7 @@ function testNodeAccessQueryTag() { // Query the nodes table as admin user (full access) with the node access // tag and no specific langcode. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $admin_user) ->addTag('node_access'); $nids = $select->execute()->fetchAllAssoc('nid'); @@ -241,7 +241,7 @@ function testNodeAccessQueryTag() { // Query the nodes table as admin user (full access) with the node access // tag and langcode de. $select = db_select('node', 'n') - ->fields('n', array('nid')) + ->fields('n', ['nid']) ->addMetaData('account', $admin_user) ->addMetaData('langcode', 'de') ->addTag('node_access'); diff --git a/core/modules/node/src/Tests/NodeAccessMenuLinkTest.php b/core/modules/node/tests/src/Functional/NodeAccessMenuLinkTest.php similarity index 84% rename from core/modules/node/src/Tests/NodeAccessMenuLinkTest.php rename to core/modules/node/tests/src/Functional/NodeAccessMenuLinkTest.php index c1bc0eb4..6c5bcd4e 100644 --- a/core/modules/node/src/Tests/NodeAccessMenuLinkTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessMenuLinkTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\user\RoleInterface; @@ -16,7 +16,7 @@ class NodeAccessMenuLinkTest extends NodeTestBase { * * @var array */ - public static $modules = array('menu_ui', 'block'); + public static $modules = ['menu_ui', 'block']; /** * A user with permission to manage menu links and create nodes. @@ -30,19 +30,19 @@ protected function setUp() { $this->drupalPlaceBlock('system_menu_block:main'); - $this->contentAdminUser = $this->drupalCreateUser(array( + $this->contentAdminUser = $this->drupalCreateUser([ 'access content', 'administer content types', 'administer menu' - )); + ]); - $this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', array())->save(); + $this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', [])->save(); } /** * SA-CORE-2015-003: Tests menu links to nodes when node access is restricted. */ - function testNodeAccessMenuLink() { + public function testNodeAccessMenuLink() { $menu_link_title = $this->randomString(); @@ -64,7 +64,7 @@ function testNodeAccessMenuLink() { // Ensure anonymous users with "access content" permission see this menu // link. - $this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', array('access content'))->save(); + $this->config('user.role.' . RoleInterface::ANONYMOUS_ID)->set('permissions', ['access content'])->save(); $this->drupalGet(''); $this->assertLink($menu_link_title); } diff --git a/core/modules/node/src/Tests/NodeAccessPagerTest.php b/core/modules/node/tests/src/Functional/NodeAccessPagerTest.php similarity index 77% rename from core/modules/node/src/Tests/NodeAccessPagerTest.php rename to core/modules/node/tests/src/Functional/NodeAccessPagerTest.php index 7db264cd..ad6cc549 100644 --- a/core/modules/node/src/Tests/NodeAccessPagerTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessPagerTest.php @@ -1,18 +1,18 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\comment\CommentInterface; use Drupal\comment\Tests\CommentTestTrait; -use Drupal\simpletest\WebTestBase; use Drupal\comment\Entity\Comment; +use Drupal\Tests\BrowserTestBase; /** * Tests access controlled node views have the right amount of comment pages. * * @group node */ -class NodeAccessPagerTest extends WebTestBase { +class NodeAccessPagerTest extends BrowserTestBase { use CommentTestTrait; @@ -21,15 +21,15 @@ class NodeAccessPagerTest extends WebTestBase { * * @var array */ - public static $modules = array('node_access_test', 'comment', 'forum'); + public static $modules = ['node_access_test', 'comment', 'forum']; protected function setUp() { parent::setUp(); node_access_rebuild(); - $this->drupalCreateContentType(array('type' => 'page', 'name' => t('Basic page'))); + $this->drupalCreateContentType(['type' => 'page', 'name' => t('Basic page')]); $this->addDefaultCommentField('node', 'page'); - $this->webUser = $this->drupalCreateUser(array('access content', 'access comments', 'node test view')); + $this->webUser = $this->drupalCreateUser(['access content', 'access comments', 'node test view']); } /** @@ -41,16 +41,16 @@ public function testCommentPager() { // Create 60 comments. for ($i = 0; $i < 60; $i++) { - $comment = Comment::create(array( + $comment = Comment::create([ 'entity_id' => $node->id(), 'entity_type' => 'node', 'field_name' => 'comment', 'subject' => $this->randomMachineName(), - 'comment_body' => array( - array('value' => $this->randomMachineName()), - ), + 'comment_body' => [ + ['value' => $this->randomMachineName()], + ], 'status' => CommentInterface::PUBLISHED, - )); + ]); $comment->save(); } @@ -80,13 +80,13 @@ public function testForumPager() { // Create 30 nodes. for ($i = 0; $i < 30; $i++) { - $this->drupalCreateNode(array( + $this->drupalCreateNode([ 'nid' => NULL, 'type' => 'forum', - 'taxonomy_forums' => array( - array('target_id' => $tid), - ), - )); + 'taxonomy_forums' => [ + ['target_id' => $tid], + ], + ]); } // View the general discussion forum page. With the default 25 nodes per diff --git a/core/modules/node/src/Tests/NodeAccessRebuildNodeGrantsTest.php b/core/modules/node/tests/src/Functional/NodeAccessRebuildNodeGrantsTest.php similarity index 93% rename from core/modules/node/src/Tests/NodeAccessRebuildNodeGrantsTest.php rename to core/modules/node/tests/src/Functional/NodeAccessRebuildNodeGrantsTest.php index d151aadc..9ea75ccf 100644 --- a/core/modules/node/src/Tests/NodeAccessRebuildNodeGrantsTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessRebuildNodeGrantsTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\node\Entity\NodeType; @@ -32,7 +32,7 @@ class NodeAccessRebuildNodeGrantsTest extends NodeTestBase { protected function setUp() { parent::setUp(); - $this->adminUser = $this->drupalCreateUser(array('administer site configuration', 'access administration pages', 'access site reports')); + $this->adminUser = $this->drupalCreateUser(['administer site configuration', 'access administration pages', 'access site reports']); $this->drupalLogin($this->adminUser); $this->webUser = $this->drupalCreateUser(); @@ -50,10 +50,10 @@ public function testNodeAccessRebuildNodeGrants() { // Create 30 nodes so that _node_access_rebuild_batch_operation() has to run // more than once. for ($i = 0; $i < 30; $i++) { - $nodes[] = $this->drupalCreateNode(array( + $nodes[] = $this->drupalCreateNode([ 'uid' => $this->webUser->id(), 'private' => [['value' => 1]] - )); + ]); } /** @var \Drupal\node\NodeGrantDatabaseStorageInterface $grant_storage */ @@ -71,7 +71,7 @@ public function testNodeAccessRebuildNodeGrants() { // Rebuild permissions. $this->drupalGet('admin/reports/status'); $this->clickLink(t('Rebuild permissions')); - $this->drupalPostForm(NULL, array(), t('Rebuild permissions')); + $this->drupalPostForm(NULL, [], t('Rebuild permissions')); $this->assertText(t('The content access permissions have been rebuilt.')); // Test if the rebuild by user that cannot bypass node access and does not @@ -107,7 +107,7 @@ public function testNodeAccessRebuildNoAccessModules() { // Rebuild permissions. $this->drupalGet('admin/reports/status'); $this->clickLink(t('Rebuild permissions')); - $this->drupalPostForm(NULL, array(), t('Rebuild permissions')); + $this->drupalPostForm(NULL, [], t('Rebuild permissions')); $this->assertText(t('Content permissions have been rebuilt.')); $this->assertNull(\Drupal::state()->get('node.node_access_needs_rebuild'), 'Node access permissions have been rebuilt'); diff --git a/core/modules/node/src/Tests/NodeAccessRecordsTest.php b/core/modules/node/tests/src/Functional/NodeAccessRecordsTest.php similarity index 77% rename from core/modules/node/src/Tests/NodeAccessRecordsTest.php rename to core/modules/node/tests/src/Functional/NodeAccessRecordsTest.php index 41265390..259ed83e 100644 --- a/core/modules/node/src/Tests/NodeAccessRecordsTest.php +++ b/core/modules/node/tests/src/Functional/NodeAccessRecordsTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\node\Entity\Node; @@ -16,68 +16,68 @@ class NodeAccessRecordsTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_test'); + public static $modules = ['node_test']; /** * Creates a node and tests the creation of node access rules. */ - function testNodeAccessRecords() { + public function testNodeAccessRecords() { // Create an article node. - $node1 = $this->drupalCreateNode(array('type' => 'article')); + $node1 = $this->drupalCreateNode(['type' => 'article']); $this->assertTrue(Node::load($node1->id()), 'Article node created.'); // Check to see if grants added by node_test_node_access_records made it in. - $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node1->id()))->fetchAll(); + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node1->id()])->fetchAll(); $this->assertEqual(count($records), 1, 'Returned the correct number of rows.'); $this->assertEqual($records[0]->realm, 'test_article_realm', 'Grant with article_realm acquired for node without alteration.'); $this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.'); // Create an unpromoted "Basic page" node. - $node2 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0)); + $node2 = $this->drupalCreateNode(['type' => 'page', 'promote' => 0]); $this->assertTrue(Node::load($node2->id()), 'Unpromoted basic page node created.'); // Check to see if grants added by node_test_node_access_records made it in. - $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node2->id()))->fetchAll(); + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node2->id()])->fetchAll(); $this->assertEqual(count($records), 1, 'Returned the correct number of rows.'); $this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.'); $this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.'); // Create an unpromoted, unpublished "Basic page" node. - $node3 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0, 'status' => 0)); + $node3 = $this->drupalCreateNode(['type' => 'page', 'promote' => 0, 'status' => 0]); $this->assertTrue(Node::load($node3->id()), 'Unpromoted, unpublished basic page node created.'); // Check to see if grants added by node_test_node_access_records made it in. - $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node3->id()))->fetchAll(); + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node3->id()])->fetchAll(); $this->assertEqual(count($records), 1, 'Returned the correct number of rows.'); $this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.'); $this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.'); // Create a promoted "Basic page" node. - $node4 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1)); + $node4 = $this->drupalCreateNode(['type' => 'page', 'promote' => 1]); $this->assertTrue(Node::load($node4->id()), 'Promoted basic page node created.'); // Check to see if grant added by node_test_node_access_records was altered // by node_test_node_access_records_alter. - $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node4->id()))->fetchAll(); + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node4->id()])->fetchAll(); $this->assertEqual(count($records), 1, 'Returned the correct number of rows.'); $this->assertEqual($records[0]->realm, 'test_alter_realm', 'Altered grant with alter_realm acquired for node.'); $this->assertEqual($records[0]->gid, 2, 'Altered grant with gid = 2 acquired for node.'); // Check to see if we can alter grants with hook_node_grants_alter(). - $operations = array('view', 'update', 'delete'); + $operations = ['view', 'update', 'delete']; // Create a user that is allowed to access content. - $web_user = $this->drupalCreateUser(array('access content')); + $web_user = $this->drupalCreateUser(['access content']); foreach ($operations as $op) { $grants = node_test_node_grants($web_user, $op); $altered_grants = $grants; \Drupal::moduleHandler()->alter('node_grants', $altered_grants, $web_user, $op); - $this->assertNotEqual($grants, $altered_grants, format_string('Altered the %op grant for a user.', array('%op' => $op))); + $this->assertNotEqual($grants, $altered_grants, format_string('Altered the %op grant for a user.', ['%op' => $op])); } // Check that core does not grant access to an unpublished node when an // empty $grants array is returned. - $node6 = $this->drupalCreateNode(array('status' => 0, 'disable_node_access' => TRUE)); - $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node6->id()))->fetchAll(); + $node6 = $this->drupalCreateNode(['status' => 0, 'disable_node_access' => TRUE]); + $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node6->id()])->fetchAll(); $this->assertEqual(count($records), 0, 'Returned no records for unpublished node.'); } diff --git a/core/modules/node/src/Tests/NodeActionsConfigurationTest.php b/core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php similarity index 96% rename from core/modules/node/src/Tests/NodeActionsConfigurationTest.php rename to core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php index 7a732c6c..fbfda8f1 100644 --- a/core/modules/node/src/Tests/NodeActionsConfigurationTest.php +++ b/core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php @@ -1,9 +1,9 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Component\Utility\Crypt; -use Drupal\simpletest\WebTestBase; +use Drupal\Tests\BrowserTestBase; use Drupal\system\Entity\Action; /** @@ -11,7 +11,7 @@ * * @group node */ -class NodeActionsConfigurationTest extends WebTestBase { +class NodeActionsConfigurationTest extends BrowserTestBase { /** * Modules to install. diff --git a/core/modules/node/src/Tests/NodeAdminTest.php b/core/modules/node/tests/src/Functional/NodeAdminTest.php similarity index 80% rename from core/modules/node/src/Tests/NodeAdminTest.php rename to core/modules/node/tests/src/Functional/NodeAdminTest.php index 1717bb19..24a50cf5 100644 --- a/core/modules/node/src/Tests/NodeAdminTest.php +++ b/core/modules/node/tests/src/Functional/NodeAdminTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\user\RoleInterface; @@ -43,7 +43,7 @@ class NodeAdminTest extends NodeTestBase { * * @var array */ - public static $modules = array('views'); + public static $modules = ['views']; protected function setUp() { parent::setUp(); @@ -51,9 +51,9 @@ protected function setUp() { // Remove the "view own unpublished content" permission which is set // by default for authenticated users so we can test this permission // correctly. - user_role_revoke_permissions(RoleInterface::AUTHENTICATED_ID, array('view own unpublished content')); + user_role_revoke_permissions(RoleInterface::AUTHENTICATED_ID, ['view own unpublished content']); - $this->adminUser = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'administer nodes', 'bypass node access')); + $this->adminUser = $this->drupalCreateUser(['access administration pages', 'access content overview', 'administer nodes', 'bypass node access']); $this->baseUser1 = $this->drupalCreateUser(['access content overview']); $this->baseUser2 = $this->drupalCreateUser(['access content overview', 'view own unpublished content']); $this->baseUser3 = $this->drupalCreateUser(['access content overview', 'bypass node access']); @@ -62,43 +62,43 @@ protected function setUp() { /** * Tests that the table sorting works on the content admin pages. */ - function testContentAdminSort() { + public function testContentAdminSort() { $this->drupalLogin($this->adminUser); $changed = REQUEST_TIME; - foreach (array('dd', 'aa', 'DD', 'bb', 'cc', 'CC', 'AA', 'BB') as $prefix) { + foreach (['dd', 'aa', 'DD', 'bb', 'cc', 'CC', 'AA', 'BB'] as $prefix) { $changed += 1000; - $node = $this->drupalCreateNode(array('title' => $prefix . $this->randomMachineName(6))); + $node = $this->drupalCreateNode(['title' => $prefix . $this->randomMachineName(6)]); db_update('node_field_data') - ->fields(array('changed' => $changed)) + ->fields(['changed' => $changed]) ->condition('nid', $node->id()) ->execute(); } // Test that the default sort by node.changed DESC actually fires properly. $nodes_query = db_select('node_field_data', 'n') - ->fields('n', array('title')) + ->fields('n', ['title']) ->orderBy('changed', 'DESC') ->execute() ->fetchCol(); $this->drupalGet('admin/content'); foreach ($nodes_query as $delta => $string) { - $elements = $this->xpath('//table[contains(@class, :class)]/tbody/tr[' . ($delta + 1) . ']/td[2]/a[normalize-space(text())=:label]', array(':class' => 'views-table', ':label' => $string)); + $elements = $this->xpath('//table[contains(@class, :class)]/tbody/tr[' . ($delta + 1) . ']/td[2]/a[normalize-space(text())=:label]', [':class' => 'views-table', ':label' => $string]); $this->assertTrue(!empty($elements), 'The node was found in the correct order.'); } // Compare the rendered HTML node list to a query for the nodes ordered by // title to account for possible database-dependent sort order. $nodes_query = db_select('node_field_data', 'n') - ->fields('n', array('title')) + ->fields('n', ['title']) ->orderBy('title') ->execute() ->fetchCol(); - $this->drupalGet('admin/content', array('query' => array('sort' => 'asc', 'order' => 'title'))); + $this->drupalGet('admin/content', ['query' => ['sort' => 'asc', 'order' => 'title']]); foreach ($nodes_query as $delta => $string) { - $elements = $this->xpath('//table[contains(@class, :class)]/tbody/tr[' . ($delta + 1) . ']/td[2]/a[normalize-space(text())=:label]', array(':class' => 'views-table', ':label' => $string)); + $elements = $this->xpath('//table[contains(@class, :class)]/tbody/tr[' . ($delta + 1) . ']/td[2]/a[normalize-space(text())=:label]', [':class' => 'views-table', ':label' => $string]); $this->assertTrue(!empty($elements), 'The node was found in the correct order.'); } } @@ -110,7 +110,7 @@ function testContentAdminSort() { * * @see TaxonomyNodeFilterTestCase */ - function testContentAdminPages() { + public function testContentAdminPages() { $this->drupalLogin($this->adminUser); // Use an explicit changed time to ensure the expected order in the content @@ -118,10 +118,10 @@ function testContentAdminPages() { // they appear in the following code, and the 'content' View has a table // style configuration with a default sort on the 'changed' field DESC. $time = time(); - $nodes['published_page'] = $this->drupalCreateNode(array('type' => 'page', 'changed' => $time--)); - $nodes['published_article'] = $this->drupalCreateNode(array('type' => 'article', 'changed' => $time--)); - $nodes['unpublished_page_1'] = $this->drupalCreateNode(array('type' => 'page', 'changed' => $time--, 'uid' => $this->baseUser1->id(), 'status' => 0)); - $nodes['unpublished_page_2'] = $this->drupalCreateNode(array('type' => 'page', 'changed' => $time, 'uid' => $this->baseUser2->id(), 'status' => 0)); + $nodes['published_page'] = $this->drupalCreateNode(['type' => 'page', 'changed' => $time--]); + $nodes['published_article'] = $this->drupalCreateNode(['type' => 'article', 'changed' => $time--]); + $nodes['unpublished_page_1'] = $this->drupalCreateNode(['type' => 'page', 'changed' => $time--, 'uid' => $this->baseUser1->id(), 'status' => 0]); + $nodes['unpublished_page_2'] = $this->drupalCreateNode(['type' => 'page', 'changed' => $time, 'uid' => $this->baseUser2->id(), 'status' => 0]); // Verify view, edit, and delete links for any content. $this->drupalGet('admin/content'); @@ -134,19 +134,19 @@ function testContentAdminPages() { $this->assertLinkByHref('node/' . $node->id() . '/edit'); $this->assertLinkByHref('node/' . $node->id() . '/delete'); // Verify that we can see the content type label. - $this->assertEqual(trim((string) $node_type_labels[$delta]), $node->type->entity->label()); + $this->assertEqual(trim($node_type_labels[$delta]->getText()), $node->type->entity->label()); $delta++; } // Verify filtering by publishing status. - $this->drupalGet('admin/content', array('query' => array('status' => TRUE))); + $this->drupalGet('admin/content', ['query' => ['status' => TRUE]]); $this->assertLinkByHref('node/' . $nodes['published_page']->id() . '/edit'); $this->assertLinkByHref('node/' . $nodes['published_article']->id() . '/edit'); $this->assertNoLinkByHref('node/' . $nodes['unpublished_page_1']->id() . '/edit'); // Verify filtering by status and content type. - $this->drupalGet('admin/content', array('query' => array('status' => TRUE, 'type' => 'page'))); + $this->drupalGet('admin/content', ['query' => ['status' => TRUE, 'type' => 'page']]); $this->assertLinkByHref('node/' . $nodes['published_page']->id() . '/edit'); $this->assertNoLinkByHref('node/' . $nodes['published_article']->id() . '/edit'); diff --git a/core/modules/node/src/Tests/NodeBlockFunctionalTest.php b/core/modules/node/tests/src/Functional/NodeBlockFunctionalTest.php similarity index 87% rename from core/modules/node/src/Tests/NodeBlockFunctionalTest.php rename to core/modules/node/tests/src/Functional/NodeBlockFunctionalTest.php index 9579045a..c203c501 100644 --- a/core/modules/node/src/Tests/NodeBlockFunctionalTest.php +++ b/core/modules/node/tests/src/Functional/NodeBlockFunctionalTest.php @@ -1,10 +1,10 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\block\Entity\Block; use Drupal\Core\EventSubscriber\MainContentViewSubscriber; -use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait; +use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait; use Drupal\user\RoleInterface; /** @@ -35,14 +35,14 @@ class NodeBlockFunctionalTest extends NodeTestBase { * * @var array */ - public static $modules = array('block', 'views'); + public static $modules = ['block', 'views']; protected function setUp() { parent::setUp(); // Create users and test node. - $this->adminUser = $this->drupalCreateUser(array('administer content types', 'administer nodes', 'administer blocks', 'access content overview')); - $this->webUser = $this->drupalCreateUser(array('access content', 'create article content')); + $this->adminUser = $this->drupalCreateUser(['administer content types', 'administer nodes', 'administer blocks', 'access content overview']); + $this->webUser = $this->drupalCreateUser(['access content', 'create article content']); } /** @@ -52,34 +52,34 @@ public function testRecentNodeBlock() { $this->drupalLogin($this->adminUser); // Disallow anonymous users to view content. - user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array( + user_role_change_permissions(RoleInterface::ANONYMOUS_ID, [ 'access content' => FALSE, - )); + ]); // Enable the recent content block with two items. - $block = $this->drupalPlaceBlock('views_block:content_recent-block_1', array('id' => 'test_block', 'items_per_page' => 2)); + $block = $this->drupalPlaceBlock('views_block:content_recent-block_1', ['id' => 'test_block', 'items_per_page' => 2]); // Test that block is not visible without nodes. $this->drupalGet(''); $this->assertText(t('No content available.'), 'Block with "No content available." found.'); // Add some test nodes. - $default_settings = array('uid' => $this->webUser->id(), 'type' => 'article'); + $default_settings = ['uid' => $this->webUser->id(), 'type' => 'article']; $node1 = $this->drupalCreateNode($default_settings); $node2 = $this->drupalCreateNode($default_settings); $node3 = $this->drupalCreateNode($default_settings); // Change the changed time for node so that we can test ordering. db_update('node_field_data') - ->fields(array( + ->fields([ 'changed' => $node1->getChangedTime() + 100, - )) + ]) ->condition('nid', $node2->id()) ->execute(); db_update('node_field_data') - ->fields(array( + ->fields([ 'changed' => $node1->getChangedTime() + 200, - )) + ]) ->condition('nid', $node3->id()) ->execute(); @@ -131,7 +131,7 @@ public function testRecentNodeBlock() { $this->assertTrue(isset($visibility['node_type']['bundles']['article']), 'Visibility settings were saved to configuration'); // Create a page node. - $node5 = $this->drupalCreateNode(array('uid' => $this->adminUser->id(), 'type' => 'page')); + $node5 = $this->drupalCreateNode(['uid' => $this->adminUser->id(), 'type' => 'page']); $this->drupalLogout(); $this->drupalLogin($this->webUser); diff --git a/core/modules/node/src/Tests/NodeCacheTagsTest.php b/core/modules/node/tests/src/Functional/NodeCacheTagsTest.php similarity index 91% rename from core/modules/node/src/Tests/NodeCacheTagsTest.php rename to core/modules/node/tests/src/Functional/NodeCacheTagsTest.php index 66932cce..ca5a0a99 100644 --- a/core/modules/node/src/Tests/NodeCacheTagsTest.php +++ b/core/modules/node/tests/src/Functional/NodeCacheTagsTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Entity\EntityInterface; use Drupal\node\Entity\Node; @@ -17,7 +17,7 @@ class NodeCacheTagsTest extends EntityWithUriCacheTagsTestBase { /** * {@inheritdoc} */ - public static $modules = array('node'); + public static $modules = ['node']; /** * {@inheritdoc} @@ -61,7 +61,7 @@ protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) * Each node must have an author. */ protected function getAdditionalCacheTagsForEntity(EntityInterface $node) { - return array('user:' . $node->getOwnerId(), 'user_view'); + return ['user:' . $node->getOwnerId(), 'user_view']; } /** diff --git a/core/modules/node/src/Tests/NodeCreationTest.php b/core/modules/node/tests/src/Functional/NodeCreationTest.php similarity index 83% rename from core/modules/node/src/Tests/NodeCreationTest.php rename to core/modules/node/tests/src/Functional/NodeCreationTest.php index bf3ce864..1ea8fcc3 100644 --- a/core/modules/node/src/Tests/NodeCreationTest.php +++ b/core/modules/node/tests/src/Functional/NodeCreationTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Database\Database; use Drupal\Core\Language\LanguageInterface; @@ -21,19 +21,19 @@ class NodeCreationTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_test_exception', 'dblog', 'test_page_test'); + public static $modules = ['node_test_exception', 'dblog', 'test_page_test']; protected function setUp() { parent::setUp(); - $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content')); + $web_user = $this->drupalCreateUser(['create page content', 'edit own page content']); $this->drupalLogin($web_user); } /** * Creates a "Basic page" node and verifies its consistency in the database. */ - function testNodeCreation() { + public function testNodeCreation() { $node_type_storage = \Drupal::entityManager()->getStorage('node_type'); // Test /node/add page with only one content type. @@ -42,16 +42,16 @@ function testNodeCreation() { $this->assertResponse(200); $this->assertUrl('node/add/page'); // Create a node. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); // Check that the Basic page has been created. - $this->assertText(t('@post @title has been created.', array('@post' => 'Basic page', '@title' => $edit['title[0][value]'])), 'Basic page created.'); + $this->assertText(t('@post @title has been created.', ['@post' => 'Basic page', '@title' => $edit['title[0][value]']]), 'Basic page created.'); // Verify that the creation message contains a link to a node. - $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'node/')); + $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']); $this->assert(isset($view_link), 'The message area contains a link to a node'); // Check that the node exists in the database. @@ -72,20 +72,26 @@ function testNodeCreation() { $this->drupalGet('node/' . $node->id()); $this->assertText($node->getOwner()->getUsername()); $this->assertText(format_date($node->getCreatedTime())); + + // Check if the node revision checkbox is not rendered on node creation form. + $admin_user = $this->drupalCreateUser(['administer nodes', 'create page content']); + $this->drupalLogin($admin_user); + $this->drupalGet('node/add/page'); + $this->assertNoFieldById('edit-revision', NULL, 'The revision checkbox is not present.'); } /** * Verifies that a transaction rolls back the failed creation. */ - function testFailedPageCreation() { + public function testFailedPageCreation() { // Create a node. - $edit = array( + $edit = [ 'uid' => $this->loggedInUser->id(), 'name' => $this->loggedInUser->name, 'type' => 'page', 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'title' => 'testing_transaction_exception', - ); + ]; try { // An exception is generated by node_test_exception_node_insert() if the @@ -120,7 +126,7 @@ function testFailedPageCreation() { /** * Creates an unpublished node and confirms correct redirect behavior. */ - function testUnpublishedNodeCreation() { + public function testUnpublishedNodeCreation() { // Set the front page to the test page. $this->config('system.site')->set('page.front', '/test-page')->save(); @@ -131,7 +137,7 @@ function testUnpublishedNodeCreation() { ->save(); // Create a node. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); @@ -141,10 +147,10 @@ function testUnpublishedNodeCreation() { $this->assertText(t('Test page text')); // Confirm that the node was created. - $this->assertText(t('@post @title has been created.', array('@post' => 'Basic page', '@title' => $edit['title[0][value]']))); + $this->assertText(t('@post @title has been created.', ['@post' => 'Basic page', '@title' => $edit['title[0][value]']])); // Verify that the creation message contains a link to a node. - $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'node/')); + $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']); $this->assert(isset($view_link), 'The message area contains a link to a node'); } @@ -152,7 +158,7 @@ function testUnpublishedNodeCreation() { * Tests the author autocompletion textfield. */ public function testAuthorAutocomplete() { - $admin_user = $this->drupalCreateUser(array('administer nodes', 'create page content')); + $admin_user = $this->drupalCreateUser(['administer nodes', 'create page content']); $this->drupalLogin($admin_user); $this->drupalGet('node/add/page'); @@ -160,7 +166,7 @@ public function testAuthorAutocomplete() { $result = $this->xpath('//input[@id="edit-uid-0-value" and contains(@data-autocomplete-path, "user/autocomplete")]'); $this->assertEqual(count($result), 0, 'No autocompletion without access user profiles.'); - $admin_user = $this->drupalCreateUser(array('administer nodes', 'create page content', 'access user profiles')); + $admin_user = $this->drupalCreateUser(['administer nodes', 'create page content', 'access user profiles']); $this->drupalLogin($admin_user); $this->drupalGet('node/add/page'); @@ -172,20 +178,20 @@ public function testAuthorAutocomplete() { /** * Check node/add when no node types exist. */ - function testNodeAddWithoutContentTypes() { + public function testNodeAddWithoutContentTypes() { $this->drupalGet('node/add'); $this->assertResponse(200); $this->assertNoLinkByHref('/admin/structure/types/add'); // Test /node/add page without content types. - foreach (\Drupal::entityManager()->getStorage('node_type')->loadMultiple() as $entity ) { + foreach (\Drupal::entityManager()->getStorage('node_type')->loadMultiple() as $entity) { $entity->delete(); } $this->drupalGet('node/add'); $this->assertResponse(403); - $admin_content_types = $this->drupalCreateUser(array('administer content types')); + $admin_content_types = $this->drupalCreateUser(['administer content types']); $this->drupalLogin($admin_content_types); $this->drupalGet('node/add'); @@ -203,7 +209,7 @@ function testNodeAddWithoutContentTypes() { protected static function getWatchdogIdsForTestExceptionRollback() { // PostgreSQL doesn't support bytea LIKE queries, so we need to unserialize // first to check for the rollback exception message. - $matches = array(); + $matches = []; $query = db_query("SELECT wid, variables FROM {watchdog}"); foreach ($query as $row) { $variables = (array) unserialize($row->variables); diff --git a/core/modules/node/tests/src/Functional/NodeEditFormTest.php b/core/modules/node/tests/src/Functional/NodeEditFormTest.php new file mode 100644 index 00000000..c15ca70b --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeEditFormTest.php @@ -0,0 +1,283 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +use Drupal\node\NodeInterface; +use Drupal\user\Entity\User; + +/** + * Create a node and test node edit functionality. + * + * @group node + */ +class NodeEditFormTest extends NodeTestBase { + + /** + * A normal logged in user. + * + * @var \Drupal\user\UserInterface + */ + protected $webUser; + + /** + * A user with permission to bypass content access checks. + * + * @var \Drupal\user\UserInterface + */ + protected $adminUser; + + /** + * The node storage. + * + * @var \Drupal\node\NodeStorageInterface + */ + protected $nodeStorage; + + /** + * Modules to enable. + * + * @var string[] + */ + public static $modules = ['block', 'node', 'datetime']; + + protected function setUp() { + parent::setUp(); + + $this->webUser = $this->drupalCreateUser(['edit own page content', 'create page content']); + $this->adminUser = $this->drupalCreateUser(['bypass node access', 'administer nodes']); + $this->drupalPlaceBlock('local_tasks_block'); + + $this->nodeStorage = $this->container->get('entity.manager')->getStorage('node'); + } + + /** + * Checks node edit functionality. + */ + public function testNodeEdit() { + $this->drupalLogin($this->webUser); + + $title_key = 'title[0][value]'; + $body_key = 'body[0][value]'; + // Create node to edit. + $edit = []; + $edit[$title_key] = $this->randomMachineName(8); + $edit[$body_key] = $this->randomMachineName(16); + $this->drupalPostForm('node/add/page', $edit, t('Save')); + + // Check that the node exists in the database. + $node = $this->drupalGetNodeByTitle($edit[$title_key]); + $this->assertTrue($node, 'Node found in database.'); + + // Check that "edit" link points to correct page. + $this->clickLink(t('Edit')); + $this->assertUrl($node->url('edit-form', ['absolute' => TRUE])); + + // Check that the title and body fields are displayed with the correct values. + // @todo Ideally assertLink would support HTML, but it doesn't. + $this->assertRaw('Edit<span class="visually-hidden">(active tab)</span>', 'Edit tab found and marked active.'); + $this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.'); + $this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.'); + + // Edit the content of the node. + $edit = []; + $edit[$title_key] = $this->randomMachineName(8); + $edit[$body_key] = $this->randomMachineName(16); + // Stay on the current page, without reloading. + $this->drupalPostForm(NULL, $edit, t('Save')); + + // Check that the title and body fields are displayed with the updated values. + $this->assertText($edit[$title_key], 'Title displayed.'); + $this->assertText($edit[$body_key], 'Body displayed.'); + + // Log in as a second administrator user. + $second_web_user = $this->drupalCreateUser(['administer nodes', 'edit any page content']); + $this->drupalLogin($second_web_user); + // Edit the same node, creating a new revision. + $this->drupalGet("node/" . $node->id() . "/edit"); + $edit = []; + $edit['title[0][value]'] = $this->randomMachineName(8); + $edit[$body_key] = $this->randomMachineName(16); + $edit['revision'] = TRUE; + $this->drupalPostForm(NULL, $edit, t('Save')); + + // Ensure that the node revision has been created. + $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE); + $this->assertNotIdentical($node->getRevisionId(), $revised_node->getRevisionId(), 'A new revision has been created.'); + // Ensure that the node author is preserved when it was not changed in the + // edit form. + $this->assertIdentical($node->getOwnerId(), $revised_node->getOwnerId(), 'The node author has been preserved.'); + // Ensure that the revision authors are different since the revisions were + // made by different users. + $first_node_version = node_revision_load($node->getRevisionId()); + $second_node_version = node_revision_load($revised_node->getRevisionId()); + $this->assertNotIdentical($first_node_version->getRevisionUser()->id(), $second_node_version->getRevisionUser()->id(), 'Each revision has a distinct user.'); + + // Check if the node revision checkbox is rendered on node edit form. + $this->drupalGet('node/' . $node->id() . '/edit'); + $this->assertFieldById('edit-revision', NULL, 'The revision field is present.'); + + // Check that details form element opens when there are errors on child + // elements. + $this->drupalGet('node/' . $node->id() . '/edit'); + $edit = []; + // This invalid date will trigger an error. + $edit['created[0][value][date]'] = $this->randomMachineName(8); + // Get the current amount of open details elements. + $open_details_elements = count($this->cssSelect('details[open="open"]')); + $this->drupalPostForm(NULL, $edit, t('Save')); + // The node author details must be open. + $this->assertRaw('<details class="node-form-author js-form-wrapper form-wrapper" data-drupal-selector="edit-author" id="edit-author" open="open">'); + // Only one extra details element should now be open. + $open_details_elements++; + $this->assertEqual(count($this->cssSelect('details[open="open"]')), $open_details_elements, 'Exactly one extra open <details> element found.'); + + // Edit the same node, save it and verify it's unpublished after unchecking + // the 'Published' boolean_checkbox and clicking 'Save'. + $this->drupalGet("node/" . $node->id() . "/edit"); + $edit = ['status[value]' => FALSE]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->nodeStorage->resetCache([$node->id()]); + $node = $this->nodeStorage->load($node->id()); + $this->assertFalse($node->isPublished(), 'Node is unpublished'); + } + + /** + * Tests changing a node's "authored by" field. + */ + public function testNodeEditAuthoredBy() { + $this->drupalLogin($this->adminUser); + + // Create node to edit. + $body_key = 'body[0][value]'; + $edit = []; + $edit['title[0][value]'] = $this->randomMachineName(8); + $edit[$body_key] = $this->randomMachineName(16); + $this->drupalPostForm('node/add/page', $edit, t('Save')); + + // Check that the node was authored by the currently logged in user. + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); + $this->assertIdentical($node->getOwnerId(), $this->adminUser->id(), 'Node authored by admin user.'); + + $this->checkVariousAuthoredByValues($node, 'uid[0][target_id]'); + + // Check that normal users cannot change the authored by information. + $this->drupalLogin($this->webUser); + $this->drupalGet('node/' . $node->id() . '/edit'); + $this->assertNoFieldByName('uid[0][target_id]'); + + // Now test with the Autcomplete (Tags) field widget. + /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */ + $form_display = \Drupal::entityManager()->getStorage('entity_form_display')->load('node.page.default'); + $widget = $form_display->getComponent('uid'); + $widget['type'] = 'entity_reference_autocomplete_tags'; + $widget['settings'] = [ + 'match_operator' => 'CONTAINS', + 'size' => 60, + 'placeholder' => '', + ]; + $form_display->setComponent('uid', $widget); + $form_display->save(); + + $this->drupalLogin($this->adminUser); + + // Save the node without making any changes. + $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save')); + $this->nodeStorage->resetCache([$node->id()]); + $node = $this->nodeStorage->load($node->id()); + $this->assertIdentical($this->webUser->id(), $node->getOwner()->id()); + + $this->checkVariousAuthoredByValues($node, 'uid[target_id]'); + + // Hide the 'authored by' field from the form. + $form_display->removeComponent('uid')->save(); + + // Check that saving the node without making any changes keeps the proper + // author ID. + $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save')); + $this->nodeStorage->resetCache([$node->id()]); + $node = $this->nodeStorage->load($node->id()); + $this->assertIdentical($this->webUser->id(), $node->getOwner()->id()); + } + + /** + * Tests the node meta information. + */ + public function testNodeMetaInformation() { + // Check that regular users (i.e. without the 'administer nodes' permission) + // can not see the meta information. + $this->drupalLogin($this->webUser); + $this->drupalGet('node/add/page'); + $this->assertNoText('Not saved yet'); + + // Create node to edit. + $edit['title[0][value]'] = $this->randomMachineName(8); + $edit['body[0][value]'] = $this->randomMachineName(16); + $this->drupalPostForm(NULL, $edit, t('Save')); + + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); + $this->drupalGet("node/" . $node->id() . "/edit"); + $this->assertNoText('Published'); + $this->assertNoText(format_date($node->getChangedTime(), 'short')); + + // Check that users with the 'administer nodes' permission can see the meta + // information. + $this->drupalLogin($this->adminUser); + $this->drupalGet('node/add/page'); + $this->assertText('Not saved yet'); + + // Create node to edit. + $edit['title[0][value]'] = $this->randomMachineName(8); + $edit['body[0][value]'] = $this->randomMachineName(16); + $this->drupalPostForm(NULL, $edit, t('Save')); + + $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); + $this->drupalGet("node/" . $node->id() . "/edit"); + $this->assertText('Published'); + $this->assertText(format_date($node->getChangedTime(), 'short')); + } + + /** + * Checks that the "authored by" works correctly with various values. + * + * @param \Drupal\node\NodeInterface $node + * A node object. + * @param string $form_element_name + * The name of the form element to populate. + */ + protected function checkVariousAuthoredByValues(NodeInterface $node, $form_element_name) { + // Try to change the 'authored by' field to an invalid user name. + $edit = [ + $form_element_name => 'invalid-name', + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + $this->assertRaw(t('There are no entities matching "%name".', ['%name' => 'invalid-name'])); + + // Change the authored by field to an empty string, which should assign + // authorship to the anonymous user (uid 0). + $edit[$form_element_name] = ''; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); + $this->nodeStorage->resetCache([$node->id()]); + $node = $this->nodeStorage->load($node->id()); + $uid = $node->getOwnerId(); + // Most SQL database drivers stringify fetches but entities are not + // necessarily stored in a SQL database. At the same time, NULL/FALSE/"" + // won't do. + $this->assertTrue($uid === 0 || $uid === '0', 'Node authored by anonymous user.'); + + // Go back to the edit form and check that the correct value is displayed + // in the author widget. + $this->drupalGet('node/' . $node->id() . '/edit'); + $anonymous_user = User::getAnonymousUser(); + $expected = $anonymous_user->label() . ' (' . $anonymous_user->id() . ')'; + $this->assertFieldByName($form_element_name, $expected, 'Authored by field displays the correct value for the anonymous user.'); + + // Change the authored by field to another user's name (that is not + // logged in). + $edit[$form_element_name] = $this->webUser->getUsername(); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->nodeStorage->resetCache([$node->id()]); + $node = $this->nodeStorage->load($node->id()); + $this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.'); + } + +} diff --git a/core/modules/node/src/Tests/NodeEntityViewModeAlterTest.php b/core/modules/node/tests/src/Functional/NodeEntityViewModeAlterTest.php similarity index 81% rename from core/modules/node/src/Tests/NodeEntityViewModeAlterTest.php rename to core/modules/node/tests/src/Functional/NodeEntityViewModeAlterTest.php index 25ae6b68..be0f1c06 100644 --- a/core/modules/node/src/Tests/NodeEntityViewModeAlterTest.php +++ b/core/modules/node/tests/src/Functional/NodeEntityViewModeAlterTest.php @@ -1,8 +1,9 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Cache\Cache; +use Drupal\Tests\EntityViewTrait; /** * Tests changing view modes for nodes. @@ -11,20 +12,22 @@ */ class NodeEntityViewModeAlterTest extends NodeTestBase { + use EntityViewTrait; + /** * Enable dummy module that implements hook_ENTITY_TYPE_view() for nodes. */ - public static $modules = array('node_test'); + public static $modules = ['node_test']; /** * Create a "Basic page" node and verify its consistency in the database. */ - function testNodeViewModeChange() { - $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content')); + public function testNodeViewModeChange() { + $web_user = $this->drupalCreateUser(['create page content', 'edit own page content']); $this->drupalLogin($web_user); // Create a node. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = t('Data that should appear only in the body for the node.'); $edit['body[0][summary]'] = t('Extra data that should appear only in the teaser for the node.'); @@ -43,7 +46,7 @@ function testNodeViewModeChange() { $this->assertNoText('Data that should appear only in the body for the node.', 'Body text not present'); // Test that the correct build mode has been set. - $build = $this->drupalBuildEntityView($node); + $build = $this->buildEntityView($node); $this->assertEqual($build['#view_mode'], 'teaser', 'The view mode has correctly been set to teaser.'); } diff --git a/core/modules/node/src/Tests/NodeFieldMultilingualTest.php b/core/modules/node/tests/src/Functional/NodeFieldMultilingualTest.php similarity index 80% rename from core/modules/node/src/Tests/NodeFieldMultilingualTest.php rename to core/modules/node/tests/src/Functional/NodeFieldMultilingualTest.php index 3bd1a51e..771426d0 100644 --- a/core/modules/node/src/Tests/NodeFieldMultilingualTest.php +++ b/core/modules/node/tests/src/Functional/NodeFieldMultilingualTest.php @@ -1,50 +1,50 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\field\Entity\FieldStorageConfig; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; -use Drupal\simpletest\WebTestBase; use Drupal\Core\Language\LanguageInterface; +use Drupal\Tests\BrowserTestBase; /** * Tests multilingual support for fields. * * @group node */ -class NodeFieldMultilingualTest extends WebTestBase { +class NodeFieldMultilingualTest extends BrowserTestBase { /** * Modules to enable. * * @var array */ - public static $modules = array('node', 'language'); + public static $modules = ['node', 'language']; protected function setUp() { parent::setUp(); // Create Basic page node type. - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); // Setup users. - $admin_user = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages', 'create page content', 'edit own page content')); + $admin_user = $this->drupalCreateUser(['administer languages', 'administer content types', 'access administration pages', 'create page content', 'edit own page content']); $this->drupalLogin($admin_user); // Add a new language. ConfigurableLanguage::createFromLangcode('it')->save(); // Enable URL language detection and selection. - $edit = array('language_interface[enabled][language-url]' => '1'); + $edit = ['language_interface[enabled][language-url]' => '1']; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); // Set "Basic page" content type to use multilingual support. - $edit = array( + $edit = [ 'language_configuration[language_alterable]' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); - $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.'); + $this->assertRaw(t('The content type %type has been updated.', ['%type' => 'Basic page']), 'Basic page content type has been updated.'); // Make node body translatable. $field_storage = FieldStorageConfig::loadByName('node', 'body'); @@ -55,7 +55,7 @@ protected function setUp() { /** * Tests whether field languages are correctly set through the node form. */ - function testMultilingualNodeForm() { + public function testMultilingualNodeForm() { // Create "Basic page" content. $langcode = language_get_default_langcode('node', 'page'); $title_key = 'title[0][value]'; @@ -64,7 +64,7 @@ function testMultilingualNodeForm() { $body_value = $this->randomMachineName(16); // Create node to edit. - $edit = array(); + $edit = []; $edit[$title_key] = $title_value; $edit[$body_key] = $body_value; $this->drupalPostForm('node/add/page', $edit, t('Save')); @@ -77,17 +77,17 @@ function testMultilingualNodeForm() { // Change node language. $langcode = 'it'; $this->drupalGet("node/{$node->id()}/edit"); - $edit = array( + $edit = [ $title_key => $this->randomMachineName(8), 'langcode[0][value]' => $langcode, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit[$title_key], TRUE); $this->assertTrue($node, 'Node found in database.'); $this->assertTrue($node->language()->getId() == $langcode && $node->body->value == $body_value, 'Field language correctly changed.'); // Enable content language URL detection. - $this->container->get('language_negotiator')->saveConfiguration(LanguageInterface::TYPE_CONTENT, array(LanguageNegotiationUrl::METHOD_ID => 0)); + $this->container->get('language_negotiator')->saveConfiguration(LanguageInterface::TYPE_CONTENT, [LanguageNegotiationUrl::METHOD_ID => 0]); // Test multilingual field language fallback logic. $this->drupalGet("it/node/{$node->id()}"); @@ -100,7 +100,7 @@ function testMultilingualNodeForm() { /** * Tests multilingual field display settings. */ - function testMultilingualDisplaySettings() { + public function testMultilingualDisplaySettings() { // Create "Basic page" content. $title_key = 'title[0][value]'; $title_value = $this->randomMachineName(8); @@ -108,7 +108,7 @@ function testMultilingualDisplaySettings() { $body_value = $this->randomMachineName(16); // Create node to edit. - $edit = array(); + $edit = []; $edit[$title_key] = $title_value; $edit[$body_key] = $body_value; $this->drupalPostForm('node/add/page', $edit, t('Save')); @@ -119,11 +119,11 @@ function testMultilingualDisplaySettings() { // Check if node body is showed. $this->drupalGet('node/' . $node->id()); - $body = $this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]//div[contains(concat(" ", normalize-space(@class), " "), :content-class)]/descendant::p', array( + $body = $this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]//div[contains(concat(" ", normalize-space(@class), " "), :content-class)]/descendant::p', [ ':node-class' => ' node ', ':content-class' => 'node__content', - )); - $this->assertEqual(current($body), $node->body->value, 'Node body found.'); + ]); + $this->assertEqual($body[0]->getText(), $node->body->value, 'Node body found.'); } } diff --git a/core/modules/node/src/Tests/NodeFormSaveChangedTimeTest.php b/core/modules/node/tests/src/Functional/NodeFormSaveChangedTimeTest.php similarity index 83% rename from core/modules/node/src/Tests/NodeFormSaveChangedTimeTest.php rename to core/modules/node/tests/src/Functional/NodeFormSaveChangedTimeTest.php index 36c1ccce..607e68cf 100644 --- a/core/modules/node/src/Tests/NodeFormSaveChangedTimeTest.php +++ b/core/modules/node/tests/src/Functional/NodeFormSaveChangedTimeTest.php @@ -1,24 +1,24 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; -use Drupal\simpletest\WebTestBase; +use Drupal\Tests\BrowserTestBase; /** * Tests updating the changed time after API and FORM entity save. * * @group node */ -class NodeFormSaveChangedTimeTest extends WebTestBase { +class NodeFormSaveChangedTimeTest extends BrowserTestBase { /** * Modules to enable. * * @var array */ - public static $modules = array( + public static $modules = [ 'node', - ); + ]; /** * An user with permissions to create and edit articles. @@ -34,18 +34,18 @@ protected function setUp() { parent::setUp(); // Create a node type. - $this->drupalCreateContentType(array( + $this->drupalCreateContentType([ 'type' => 'article', 'name' => 'Article', - )); + ]); $this->authorUser = $this->drupalCreateUser(['access content', 'create article content', 'edit any article content'], 'author'); $this->drupalLogin($this->authorUser); // Create one node of the above node type . - $this->drupalCreateNode(array( + $this->drupalCreateNode([ 'type' => 'article', - )); + ]); } /** @@ -65,7 +65,7 @@ public function testChangedTimeAfterSaveWithoutChanges() { sleep(1); // Save the node on the regular node edit form. - $this->drupalPostForm('node/1/edit', array(), t('Save')); + $this->drupalPostForm('node/1/edit', [], t('Save')); $storage->resetCache([1]); $node = $storage->load(1); diff --git a/core/modules/node/src/Tests/NodeHelpTest.php b/core/modules/node/tests/src/Functional/NodeHelpTest.php similarity index 78% rename from core/modules/node/src/Tests/NodeHelpTest.php rename to core/modules/node/tests/src/Functional/NodeHelpTest.php index 29460111..c4b71392 100644 --- a/core/modules/node/src/Tests/NodeHelpTest.php +++ b/core/modules/node/tests/src/Functional/NodeHelpTest.php @@ -1,22 +1,22 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; -use Drupal\simpletest\WebTestBase; +use Drupal\Tests\BrowserTestBase; /** * Tests help functionality for nodes. * * @group node */ -class NodeHelpTest extends WebTestBase { +class NodeHelpTest extends BrowserTestBase { /** * Modules to enable. * * @var array. */ - public static $modules = array('block', 'node', 'help'); + public static $modules = ['block', 'node', 'help']; /** * The name of the test node type to create. @@ -39,11 +39,11 @@ protected function setUp() { parent::setUp(); // Create user. - $admin_user = $this->drupalCreateUser(array( + $admin_user = $this->drupalCreateUser([ 'administer content types', 'administer nodes', 'bypass node access', - )); + ]); $this->drupalLogin($admin_user); $this->drupalPlaceBlock('help_block'); @@ -52,10 +52,10 @@ protected function setUp() { $this->testText = t('Help text to find on node forms.'); // Create content type. - $this->drupalCreateContentType(array( + $this->drupalCreateContentType([ 'type' => $this->testType, 'help' => $this->testText, - )); + ]); } /** @@ -68,7 +68,7 @@ public function testNodeShowHelpText() { $this->assertText($this->testText); // Create node and check the node edit form. - $node = $this->drupalCreateNode(array('type' => $this->testType)); + $node = $this->drupalCreateNode(['type' => $this->testType]); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertResponse(200); $this->assertText($this->testText); diff --git a/core/modules/node/src/Tests/NodeLinksTest.php b/core/modules/node/tests/src/Functional/NodeLinksTest.php similarity index 78% rename from core/modules/node/src/Tests/NodeLinksTest.php rename to core/modules/node/tests/src/Functional/NodeLinksTest.php index 72990c0e..7bd725b4 100644 --- a/core/modules/node/src/Tests/NodeLinksTest.php +++ b/core/modules/node/tests/src/Functional/NodeLinksTest.php @@ -1,6 +1,8 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; + +use Drupal\node\NodeInterface; /** * Tests the output of node links (read more, add new comment, etc). @@ -14,16 +16,16 @@ class NodeLinksTest extends NodeTestBase { * * @var array */ - public static $modules = array('views'); + public static $modules = ['views']; /** * Tests that the links can be hidden in the view display settings. */ public function testHideLinks() { - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'type' => 'article', - 'promote' => NODE_PROMOTED, - )); + 'promote' => NodeInterface::PROMOTED, + ]); // Links are displayed by default. $this->drupalGet('node'); diff --git a/core/modules/node/tests/src/Functional/NodeLoadMultipleTest.php b/core/modules/node/tests/src/Functional/NodeLoadMultipleTest.php new file mode 100644 index 00000000..2da5d1bb --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeLoadMultipleTest.php @@ -0,0 +1,62 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +use Drupal\node\Entity\Node; + +/** + * Tests the loading of multiple nodes. + * + * @group node + */ +class NodeLoadMultipleTest extends NodeTestBase { + + /** + * Enable Views to test the frontpage against Node::loadMultiple() results. + * + * @var array + */ + public static $modules = ['views']; + + protected function setUp() { + parent::setUp(); + $web_user = $this->drupalCreateUser(['create article content', 'create page content']); + $this->drupalLogin($web_user); + } + + /** + * Creates four nodes and ensures that they are loaded correctly. + */ + public function testNodeMultipleLoad() { + $node1 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]); + $node2 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]); + $node3 = $this->drupalCreateNode(['type' => 'article', 'promote' => 0]); + $node4 = $this->drupalCreateNode(['type' => 'page', 'promote' => 0]); + + // Confirm that promoted nodes appear in the default node listing. + $this->drupalGet('node'); + $this->assertText($node1->label(), 'Node title appears on the default listing.'); + $this->assertText($node2->label(), 'Node title appears on the default listing.'); + $this->assertNoText($node3->label(), 'Node title does not appear in the default listing.'); + $this->assertNoText($node4->label(), 'Node title does not appear in the default listing.'); + // Load nodes with only a condition. Nodes 3 and 4 will be loaded. + $nodes = $this->container->get('entity_type.manager')->getStorage('node') + ->loadByProperties(['promote' => 0]); + $this->assertEqual($node3->label(), $nodes[$node3->id()]->label(), 'Node was loaded.'); + $this->assertEqual($node4->label(), $nodes[$node4->id()]->label(), 'Node was loaded.'); + $count = count($nodes); + $this->assertTrue($count == 2, format_string('@count nodes loaded.', ['@count' => $count])); + + // Load nodes by nid. Nodes 1, 2 and 4 will be loaded. + $nodes = Node::loadMultiple([1, 2, 4]); + $count = count($nodes); + $this->assertTrue(count($nodes) == 3, format_string('@count nodes loaded', ['@count' => $count])); + $this->assertTrue(isset($nodes[$node1->id()]), 'Node is correctly keyed in the array'); + $this->assertTrue(isset($nodes[$node2->id()]), 'Node is correctly keyed in the array'); + $this->assertTrue(isset($nodes[$node4->id()]), 'Node is correctly keyed in the array'); + foreach ($nodes as $node) { + $this->assertTrue(is_object($node), 'Node is an object'); + } + } + +} diff --git a/core/modules/node/src/Tests/NodePostSettingsTest.php b/core/modules/node/tests/src/Functional/NodePostSettingsTest.php similarity index 82% rename from core/modules/node/src/Tests/NodePostSettingsTest.php rename to core/modules/node/tests/src/Functional/NodePostSettingsTest.php index bc3dd994..4716b300 100644 --- a/core/modules/node/src/Tests/NodePostSettingsTest.php +++ b/core/modules/node/tests/src/Functional/NodePostSettingsTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; /** * Tests that the post information (submitted by Username on date) text displays @@ -13,45 +13,45 @@ class NodePostSettingsTest extends NodeTestBase { protected function setUp() { parent::setUp(); - $web_user = $this->drupalCreateUser(array('create page content', 'administer content types', 'access user profiles')); + $web_user = $this->drupalCreateUser(['create page content', 'administer content types', 'access user profiles']); $this->drupalLogin($web_user); } /** * Confirms "Basic page" content type and post information is on a new node. */ - function testPagePostInfo() { + public function testPagePostInfo() { // Set "Basic page" content type to display post information. - $edit = array(); + $edit = []; $edit['display_submitted'] = TRUE; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); // Create a node. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); // Check that the post information is displayed. $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); - $elements = $this->xpath('//div[contains(@class, :class)]', array(':class' => 'node__submitted')); + $elements = $this->xpath('//div[contains(@class, :class)]', [':class' => 'node__submitted']); $this->assertEqual(count($elements), 1, 'Post information is displayed.'); $node->delete(); // Set "Basic page" content type to display post information. - $edit = array(); + $edit = []; $edit['display_submitted'] = FALSE; $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); // Create a node. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $this->drupalPostForm('node/add/page', $edit, t('Save')); // Check that the post information is displayed. - $elements = $this->xpath('//div[contains(@class, :class)]', array(':class' => 'node__submitted')); + $elements = $this->xpath('//div[contains(@class, :class)]', [':class' => 'node__submitted']); $this->assertEqual(count($elements), 0, 'Post information is not displayed.'); } diff --git a/core/modules/node/src/Tests/NodeQueryAlterTest.php b/core/modules/node/tests/src/Functional/NodeQueryAlterTest.php similarity index 89% rename from core/modules/node/src/Tests/NodeQueryAlterTest.php rename to core/modules/node/tests/src/Functional/NodeQueryAlterTest.php index 022625bd..362a27fc 100644 --- a/core/modules/node/src/Tests/NodeQueryAlterTest.php +++ b/core/modules/node/tests/src/Functional/NodeQueryAlterTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; /** * Tests that node access queries are properly altered by the node module. @@ -14,7 +14,7 @@ class NodeQueryAlterTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_access_test'); + public static $modules = ['node_access_test']; /** * User with permission to view content. @@ -39,9 +39,9 @@ protected function setUp() { // Create user with simple node access permission. The 'node test view' // permission is implemented and granted by the node_access_test module. - $this->accessUser = $this->drupalCreateUser(array('access content overview', 'access content', 'node test view')); - $this->noAccessUser = $this->drupalCreateUser(array('access content overview', 'access content')); - $this->noAccessUser2 = $this->drupalCreateUser(array('access content overview', 'access content')); + $this->accessUser = $this->drupalCreateUser(['access content overview', 'access content', 'node test view']); + $this->noAccessUser = $this->drupalCreateUser(['access content overview', 'access content']); + $this->noAccessUser2 = $this->drupalCreateUser(['access content overview', 'access content']); } /** @@ -50,7 +50,7 @@ protected function setUp() { * Verifies that a non-standard table alias can be used, and that a user with * node access can view the nodes. */ - function testNodeQueryAlterLowLevelWithAccess() { + public function testNodeQueryAlterLowLevelWithAccess() { // User with access should be able to view 4 nodes. try { $query = db_select('node', 'mytab') @@ -91,7 +91,7 @@ public function testNodeQueryAlterWithRevisions() { * Verifies that a non-standard table alias can be used, and that a user * without node access cannot view the nodes. */ - function testNodeQueryAlterLowLevelNoAccess() { + public function testNodeQueryAlterLowLevelNoAccess() { // User without access should be able to view 0 nodes. try { $query = db_select('node', 'mytab') @@ -114,7 +114,7 @@ function testNodeQueryAlterLowLevelNoAccess() { * Verifies that a non-standard table alias can be used, and that a user with * view-only node access cannot edit the nodes. */ - function testNodeQueryAlterLowLevelEditAccess() { + public function testNodeQueryAlterLowLevelEditAccess() { // User with view-only access should not be able to edit nodes. try { $query = db_select('node', 'mytab') @@ -142,15 +142,15 @@ function testNodeQueryAlterLowLevelEditAccess() { * add a record to {node_access} paired with a corresponding privilege in * hook_node_grants(). */ - function testNodeQueryAlterOverride() { - $record = array( + public function testNodeQueryAlterOverride() { + $record = [ 'nid' => 0, 'gid' => 0, 'realm' => 'node_access_all', 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, - ); + ]; db_insert('node_access')->fields($record)->execute(); // Test that the noAccessUser still doesn't have the 'view' diff --git a/core/modules/node/src/Tests/NodeRSSContentTest.php b/core/modules/node/tests/src/Functional/NodeRSSContentTest.php similarity index 87% rename from core/modules/node/src/Tests/NodeRSSContentTest.php rename to core/modules/node/tests/src/Functional/NodeRSSContentTest.php index d1ce2406..0efa336a 100644 --- a/core/modules/node/src/Tests/NodeRSSContentTest.php +++ b/core/modules/node/tests/src/Functional/NodeRSSContentTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\filter\Entity\FilterFormat; @@ -20,7 +20,7 @@ class NodeRSSContentTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_test', 'views'); + public static $modules = ['node_test', 'views']; protected function setUp() { parent::setUp(); @@ -28,30 +28,30 @@ protected function setUp() { // Use bypass node access permission here, because the test class uses // hook_grants_alter() to deny access to everyone on node_access // queries. - $user = $this->drupalCreateUser(array('bypass node access', 'access content', 'create article content')); + $user = $this->drupalCreateUser(['bypass node access', 'access content', 'create article content']); $this->drupalLogin($user); } /** * Ensures that a new node includes the custom data when added to an RSS feed. */ - function testNodeRSSContent() { + public function testNodeRSSContent() { // Create a node. - $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); + $node = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]); $this->drupalGet('rss.xml'); // Check that content added in 'rss' view mode appear in RSS feed. - $rss_only_content = t('Extra data that should appear only in the RSS feed for node @nid.', array('@nid' => $node->id())); + $rss_only_content = t('Extra data that should appear only in the RSS feed for node @nid.', ['@nid' => $node->id()]); $this->assertText($rss_only_content, 'Node content designated for RSS appear in RSS feed.'); // Check that content added in view modes other than 'rss' doesn't // appear in RSS feed. - $non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node @nid.', array('@nid' => $node->id())); + $non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node @nid.', ['@nid' => $node->id()]); $this->assertNoText($non_rss_content, 'Node content not designed for RSS does not appear in RSS feed.'); // Check that extra RSS elements and namespaces are added to RSS feed. - $test_element = '<testElement>' . t('Value of testElement RSS element for node @nid.', array('@nid' => $node->id())) . '</testElement>'; + $test_element = '<testElement>' . t('Value of testElement RSS element for node @nid.', ['@nid' => $node->id()]) . '</testElement>'; $test_ns = 'xmlns:drupaltest="http://example.com/test-namespace"'; $this->assertRaw($test_element, 'Extra RSS elements appear in RSS feed.'); $this->assertRaw($test_ns, 'Extra namespaces appear in RSS feed.'); diff --git a/core/modules/node/src/Tests/NodeRevisionPermissionsTest.php b/core/modules/node/tests/src/Functional/NodeRevisionPermissionsTest.php similarity index 84% rename from core/modules/node/src/Tests/NodeRevisionPermissionsTest.php rename to core/modules/node/tests/src/Functional/NodeRevisionPermissionsTest.php index e000fb80..ed632a7e 100644 --- a/core/modules/node/src/Tests/NodeRevisionPermissionsTest.php +++ b/core/modules/node/tests/src/Functional/NodeRevisionPermissionsTest.php @@ -1,6 +1,8 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; + +use Drupal\Tests\Traits\Core\GeneratePermutationsTrait; /** * Tests user permissions for node revisions. @@ -9,6 +11,8 @@ */ class NodeRevisionPermissionsTest extends NodeTestBase { + use GeneratePermutationsTrait; + /** * The node revisions. * @@ -21,30 +25,30 @@ class NodeRevisionPermissionsTest extends NodeTestBase { * * @var array */ - protected $accounts = array(); + protected $accounts = []; // Map revision permission names to node revision access ops. - protected $map = array( + protected $map = [ 'view' => 'view all revisions', 'update' => 'revert all revisions', 'delete' => 'delete all revisions', - ); + ]; // Map revision permission names to node type revision access ops. - protected $typeMap = array( + protected $typeMap = [ 'view' => 'view page revisions', 'update' => 'revert page revisions', 'delete' => 'delete page revisions', - ); + ]; protected function setUp() { parent::setUp(); - $types = array('page', 'article'); + $types = ['page', 'article']; foreach ($types as $type) { // Create a node with several revisions. - $nodes[$type] = $this->drupalCreateNode(array('type' => $type)); + $nodes[$type] = $this->drupalCreateNode(['type' => $type]); $this->nodeRevisions[$type][] = $nodes[$type]; for ($i = 0; $i < 3; $i++) { @@ -61,24 +65,24 @@ protected function setUp() { /** * Tests general revision access permissions. */ - function testNodeRevisionAccessAnyType() { + public function testNodeRevisionAccessAnyType() { // Create three users, one with each revision permission. foreach ($this->map as $op => $permission) { // Create the user. $account = $this->drupalCreateUser( - array( + [ 'access content', 'edit any page content', 'delete any page content', $permission, - ) + ] ); $account->op = $op; $this->accounts[] = $account; } // Create an admin account (returns TRUE for all revision permissions). - $admin_account = $this->drupalCreateUser(array('access content', 'administer nodes')); + $admin_account = $this->drupalCreateUser(['access content', 'administer nodes']); $admin_account->is_admin = TRUE; $this->accounts['admin'] = $admin_account; $accounts['admin'] = $admin_account; @@ -90,17 +94,17 @@ function testNodeRevisionAccessAnyType() { $accounts[] = $normal_account; $revision = $this->nodeRevisions['page'][1]; - $parameters = array( + $parameters = [ 'op' => array_keys($this->map), 'account' => $this->accounts, - ); + ]; $permutations = $this->generatePermutations($parameters); $node_revision_access = \Drupal::service('access_check.node.revision'); foreach ($permutations as $case) { // Skip this test if there are no revisions for the node. - if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $revision->id()))->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) { + if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $revision->id()])->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) { if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->map[$case['op']])) { $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} granted."); } @@ -119,26 +123,26 @@ function testNodeRevisionAccessAnyType() { /** * Tests revision access permissions for a specific content type. */ - function testNodeRevisionAccessPerType() { + public function testNodeRevisionAccessPerType() { // Create three users, one with each revision permission. foreach ($this->typeMap as $op => $permission) { // Create the user. $account = $this->drupalCreateUser( - array( + [ 'access content', 'edit any page content', 'delete any page content', $permission, - ) + ] ); $account->op = $op; $accounts[] = $account; } - $parameters = array( + $parameters = [ 'op' => array_keys($this->typeMap), 'account' => $accounts, - ); + ]; // Test that the accounts have access to the corresponding page revision // permissions. @@ -148,7 +152,7 @@ function testNodeRevisionAccessPerType() { $node_revision_access = \Drupal::service('access_check.node.revision'); foreach ($permutations as $case) { // Skip this test if there are no revisions for the node. - if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', array(':nid' => $revision->id()))->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) { + if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $revision->id()])->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) { if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->typeMap[$case['op']], $case['account'])) { $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} granted."); } diff --git a/core/modules/node/src/Tests/NodeRevisionsAllTest.php b/core/modules/node/tests/src/Functional/NodeRevisionsAllTest.php similarity index 81% rename from core/modules/node/src/Tests/NodeRevisionsAllTest.php rename to core/modules/node/tests/src/Functional/NodeRevisionsAllTest.php index 7963aa03..7e718470 100644 --- a/core/modules/node/src/Tests/NodeRevisionsAllTest.php +++ b/core/modules/node/tests/src/Functional/NodeRevisionsAllTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\node\NodeInterface; @@ -11,22 +11,36 @@ * @group node */ class NodeRevisionsAllTest extends NodeTestBase { + + /** + * A list of nodes created to be used as starting point of different tests. + * + * @var Drupal\node\NodeInterface[] + */ protected $nodes; + + /** + * Revision logs of nodes created by the setup method. + * + * @var string[] + */ protected $revisionLogs; - protected $profile = "standard"; + /** + * {@inheritdoc} + */ protected function setUp() { parent::setUp(); // Create and log in user. $web_user = $this->drupalCreateUser( - array( + [ 'view page revisions', 'revert page revisions', 'delete page revisions', 'edit any page content', 'delete any page content' - ) + ] ); $this->drupalLogin($web_user); @@ -36,8 +50,8 @@ protected function setUp() { $settings = get_object_vars($node); $settings['revision'] = 1; - $nodes = array(); - $logs = array(); + $nodes = []; + $logs = []; // Get the original node. $nodes[] = clone $node; @@ -67,10 +81,10 @@ protected function setUp() { protected function createNodeRevision(NodeInterface $node) { // Create revision with a random title and body and update variables. $node->title = $this->randomMachineName(); - $node->body = array( + $node->body = [ 'value' => $this->randomMachineName(32), 'format' => filter_default_format(), - ); + ]; $node->setNewRevision(); $node->save(); @@ -80,7 +94,7 @@ protected function createNodeRevision(NodeInterface $node) { /** * Checks node revision operations. */ - function testRevisions() { + public function testRevisions() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); $nodes = $this->nodes; $logs = $this->revisionLogs; @@ -90,13 +104,13 @@ function testRevisions() { // Create and log in user. $content_admin = $this->drupalCreateUser( - array( + [ 'view all revisions', 'revert all revisions', 'delete all revisions', 'edit any page content', 'delete any page content' - ) + ] ); $this->drupalLogin($content_admin); @@ -115,15 +129,15 @@ function testRevisions() { $this->assertTrue($node->isDefaultRevision(), 'Third node revision is the current one.'); // Confirm that revisions revert properly. - $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/revert", array(), t('Revert')); + $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/revert", [], t('Revert')); $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', - array( + [ '@type' => 'Basic page', '%title' => $nodes[1]->getTitle(), '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()) - )), + ]), 'Revision reverted.'); - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $reverted_node = $node_storage->load($node->id()); $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.'); @@ -131,17 +145,22 @@ function testRevisions() { $node = node_revision_load($node->getRevisionId()); $this->assertFalse($node->isDefaultRevision(), 'Third node revision is not the current one.'); + // Confirm that the node can still be updated. + $this->drupalPostForm("node/" . $reverted_node->id() . "/edit", ['body[0][value]' => 'We are Drupal.'], t('Save')); + $this->assertText(t('Basic page @title has been updated.', ['@title' => $reverted_node->getTitle()]), 'Node was successfully saved after reverting a revision.'); + $this->assertText('We are Drupal.', 'Node was correctly updated after reverting a revision.'); + // Confirm revisions delete properly. - $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", array(), t('Delete')); + $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[1]->getRevisionId() . "/delete", [], t('Delete')); $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.', - array( + [ '%revision-date' => format_date($nodes[1]->getRevisionCreationTime()), '@type' => 'Basic page', '%title' => $nodes[1]->getTitle(), - )), + ]), 'Revision deleted.'); $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', - array(':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()))->fetchField() == 0, + [':nid' => $node->id(), ':vid' => $nodes[1]->getRevisionId()])->fetchField() == 0, 'Revision not found.'); // Set the revision timestamp to an older date to make sure that the @@ -149,16 +168,16 @@ function testRevisions() { $old_revision_date = REQUEST_TIME - 86400; db_update('node_revision') ->condition('vid', $nodes[2]->getRevisionId()) - ->fields(array( + ->fields([ 'revision_timestamp' => $old_revision_date, - )) + ]) ->execute(); - $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", array(), t('Revert')); - $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', array( + $this->drupalPostForm("node/" . $node->id() . "/revisions/" . $nodes[2]->getRevisionId() . "/revert", [], t('Revert')); + $this->assertRaw(t('@type %title has been reverted to the revision from %revision-date.', [ '@type' => 'Basic page', '%title' => $nodes[2]->getTitle(), '%revision-date' => format_date($old_revision_date), - ))); + ])); // Create 50 more revisions in order to trigger paging on the revisions // overview screen. diff --git a/core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php b/core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php similarity index 92% rename from core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php rename to core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php index a6ffb3b9..186b6947 100644 --- a/core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php +++ b/core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\node\Entity\NodeType; @@ -46,7 +46,7 @@ protected function setUp() { /** * Checks that the Revision tab is displayed correctly. */ - function testDisplayRevisionTab() { + public function testDisplayRevisionTab() { $this->drupalPlaceBlock('local_tasks_block'); $this->drupalLogin($this->editor); @@ -66,8 +66,8 @@ function testDisplayRevisionTab() { $this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked"); // Uncheck the create new revision checkbox and save the node. - $edit = array('revision' => FALSE); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published'); + $edit = ['revision' => FALSE]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save'); $this->assertUrl($node->toUrl()); $this->assertNoLink(t('Revisions')); @@ -77,8 +77,8 @@ function testDisplayRevisionTab() { $this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked"); // Submit the form without changing the checkbox. - $edit = array(); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published'); + $edit = []; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save'); $this->assertUrl($node->toUrl()); $this->assertLink(t('Revisions')); diff --git a/core/modules/node/src/Tests/NodeRevisionsUiTest.php b/core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php similarity index 81% rename from core/modules/node/src/Tests/NodeRevisionsUiTest.php rename to core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php index cf609b8a..a437e4ab 100644 --- a/core/modules/node/src/Tests/NodeRevisionsUiTest.php +++ b/core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\Core\Url; use Drupal\node\Entity\Node; @@ -36,7 +36,7 @@ protected function setUp() { /** * Checks that unchecking 'Create new revision' works when editing a node. */ - function testNodeFormSaveWithoutRevision() { + public function testNodeFormSaveWithoutRevision() { $this->drupalLogin($this->editor); $node_storage = $this->container->get('entity.manager')->getStorage('node'); @@ -54,11 +54,11 @@ function testNodeFormSaveWithoutRevision() { $this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked"); // Uncheck the create new revision checkbox and save the node. - $edit = array('revision' => FALSE); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); + $edit = ['revision' => FALSE]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Load the node again and check the revision is the same as before. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $node_revision = $node_storage->load($node->id(), TRUE); $this->assertEqual($node_revision->getRevisionId(), $node->getRevisionId(), "After an existing node is saved with 'Create new revision' unchecked, a new revision is not created."); @@ -67,11 +67,11 @@ function testNodeFormSaveWithoutRevision() { $this->assertFieldChecked('edit-revision', "'Create new revision' checkbox is checked"); // Submit the form without changing the checkbox. - $edit = array(); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); + $edit = []; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Load the node again and check the revision is different from before. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $node_revision = $node_storage->load($node->id()); $this->assertNotEqual($node_revision->getRevisionId(), $node->getRevisionId(), "After an existing node is saved with 'Create new revision' checked, a new revision is created."); } @@ -129,14 +129,29 @@ public function testNodeRevisionsTabWithDefaultRevision() { // Create the node. $node = $this->drupalCreateNode(); + $storage = \Drupal::entityTypeManager()->getStorage($node->getEntityTypeId()); + // Create a new revision based on the default revision. + // Revision 2. + $node = $storage->load($node->id()); $node->setNewRevision(TRUE); $node->save(); + + // Revision 3. + $node = $storage->load($node->id()); $node->setNewRevision(TRUE); $node->save(); + + // Revision 4. + // Trigger translation changes in order to show the revision. + $node = $storage->load($node->id()); + $node->setTitle($this->randomString()); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); + + // Revision 5. + $node = $storage->load($node->id()); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); @@ -147,17 +162,15 @@ public function testNodeRevisionsTabWithDefaultRevision() { // Verify that the default revision can be an older revision than the latest // one. - $this->assertLinkByHref('/node/' . $node_id . '/revisions/5/revert'); + // Assert that the revisions with translations changes are shown: 1 and 4. + $this->assertLinkByHref('/node/' . $node_id . '/revisions/1/revert'); $this->assertLinkByHref('/node/' . $node_id . '/revisions/4/revert'); + + // Assert that the revisions without translations changes are filtered out: + // 2, 3 and 5. + $this->assertNoLinkByHref('/node/' . $node_id . '/revisions/2/revert'); $this->assertNoLinkByHref('/node/' . $node_id . '/revisions/3/revert'); - $current_revision_row = $this->xpath("//table[contains(@class, :table_class)]//tbody//tr[3 and contains(@class, :class) and contains(., :text)]", [ - ':table_class' => 'node-revision-table', - ':class' => 'revision-current', - ':text' => 'Current revision', - ]); - $this->assertEqual(count($current_revision_row), 1, 'The default revision can be a revision other than the latest one.'); - $this->assertLinkByHref('/node/' . $node_id . '/revisions/2/revert'); - $this->assertLinkByHref('/node/' . $node_id . '/revisions/1/revert'); + $this->assertNoLinkByHref('/node/' . $node_id . '/revisions/5/revert'); } } diff --git a/core/modules/node/src/Tests/NodeSaveTest.php b/core/modules/node/tests/src/Functional/NodeSaveTest.php similarity index 89% rename from core/modules/node/src/Tests/NodeSaveTest.php rename to core/modules/node/tests/src/Functional/NodeSaveTest.php index f01724bb..6c508aee 100644 --- a/core/modules/node/src/Tests/NodeSaveTest.php +++ b/core/modules/node/tests/src/Functional/NodeSaveTest.php @@ -1,6 +1,6 @@ <?php -namespace Drupal\node\Tests; +namespace Drupal\Tests\node\Functional; use Drupal\node\Entity\Node; @@ -23,13 +23,13 @@ class NodeSaveTest extends NodeTestBase { * * @var array */ - public static $modules = array('node_test'); + public static $modules = ['node_test']; protected function setUp() { parent::setUp(); // Create a user that is allowed to post; we'll use this to test the submission. - $web_user = $this->drupalCreateUser(array('create article content')); + $web_user = $this->drupalCreateUser(['create article content']); $this->drupalLogin($web_user); $this->webUser = $web_user; } @@ -42,7 +42,7 @@ protected function setUp() { * - save the content * - check if node exists */ - function testImport() { + public function testImport() { // Node ID must be a number that is not in the database. $nids = \Drupal::entityManager()->getStorage('node')->getQuery() ->sort('nid', 'DESC') @@ -51,13 +51,13 @@ function testImport() { $max_nid = reset($nids); $test_nid = $max_nid + mt_rand(1000, 1000000); $title = $this->randomMachineName(8); - $node = array( + $node = [ 'title' => $title, - 'body' => array(array('value' => $this->randomMachineName(32))), + 'body' => [['value' => $this->randomMachineName(32)]], 'uid' => $this->webUser->id(), 'type' => 'article', 'nid' => $test_nid, - ); + ]; /** @var \Drupal\node\NodeInterface $node */ $node = Node::create($node); $node->enforceIsNew(); @@ -76,13 +76,13 @@ function testImport() { /** * Verifies accuracy of the "created" and "changed" timestamp functionality. */ - function testTimestamps() { + public function testTimestamps() { // Use the default timestamps. - $edit = array( + $edit = [ 'uid' => $this->webUser->id(), 'type' => 'article', 'title' => $this->randomMachineName(8), - ); + ]; Node::create($edit)->save(); $node = $this->drupalGetNodeByTitle($edit['title']); @@ -105,13 +105,15 @@ function testTimestamps() { $this->assertEqual($node->getChangedTime(), 979534800, 'Saving a node uses "changed" timestamp set in presave hook.'); // Programmatically set the timestamps on the node. - $edit = array( + $edit = [ 'uid' => $this->webUser->id(), 'type' => 'article', 'title' => $this->randomMachineName(8), - 'created' => 280299600, // Sun, 19 Nov 1978 05:00:00 GMT - 'changed' => 979534800, // Drupal 1.0 release. - ); + // Sun, 19 Nov 1978 05:00:00 GMT. + 'created' => 280299600, + // Drupal 1.0 release. + 'changed' => 979534800, + ]; Node::create($edit)->save(); $node = $this->drupalGetNodeByTitle($edit['title']); @@ -137,7 +139,7 @@ function testTimestamps() { * This test determines changes in hook_ENTITY_TYPE_presave() and verifies * that the static node load cache is cleared upon save. */ - function testDeterminingChanges() { + public function testDeterminingChanges() { // Initial creation. $node = Node::create([ 'uid' => $this->webUser->id(), @@ -172,10 +174,10 @@ function testDeterminingChanges() { * * @see node_test_node_insert() */ - function testNodeSaveOnInsert() { + public function testNodeSaveOnInsert() { // node_test_node_insert() triggers a save on insert if the title equals // 'new'. - $node = $this->drupalCreateNode(array('title' => 'new')); + $node = $this->drupalCreateNode(['title' => 'new']); $this->assertEqual($node->getTitle(), 'Node ' . $node->id(), 'Node saved on node insert.'); } diff --git a/core/modules/node/tests/src/Functional/NodeSyndicateBlockTest.php b/core/modules/node/tests/src/Functional/NodeSyndicateBlockTest.php new file mode 100644 index 00000000..c1daef94 --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeSyndicateBlockTest.php @@ -0,0 +1,37 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +/** + * Tests if the syndicate block is available. + * + * @group node + */ +class NodeSyndicateBlockTest extends NodeTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['block']; + + protected function setUp() { + parent::setUp(); + + // Create a user and log in. + $admin_user = $this->drupalCreateUser(['administer blocks']); + $this->drupalLogin($admin_user); + } + + /** + * Tests that the "Syndicate" block is shown when enabled. + */ + public function testSyndicateBlock() { + // Place the "Syndicate" block and confirm that it is rendered. + $this->drupalPlaceBlock('node_syndicate_block', ['id' => 'test_syndicate_block']); + $this->drupalGet(''); + $this->assertFieldByXPath('//div[@id="block-test-syndicate-block"]/*', NULL, 'Syndicate block found.'); + } + +} diff --git a/core/modules/node/tests/src/Functional/NodeTemplateSuggestionsTest.php b/core/modules/node/tests/src/Functional/NodeTemplateSuggestionsTest.php new file mode 100644 index 00000000..dcadf934 --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeTemplateSuggestionsTest.php @@ -0,0 +1,38 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +/** + * Tests node template suggestions. + * + * @group node + */ +class NodeTemplateSuggestionsTest extends NodeTestBase { + + /** + * Tests if template_preprocess_node() generates the correct suggestions. + */ + public function testNodeThemeHookSuggestions() { + // Create node to be rendered. + $node = $this->drupalCreateNode(); + $view_mode = 'full'; + + // Simulate theming of the node. + $build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode); + + $variables['elements'] = $build; + $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', [$variables]); + + $this->assertEqual($suggestions, ['node__full', 'node__page', 'node__page__full', 'node__' . $node->id(), 'node__' . $node->id() . '__full'], 'Found expected node suggestions.'); + + // Change the view mode. + $view_mode = 'node.my_custom_view_mode'; + $build = \Drupal::entityManager()->getViewBuilder('node')->view($node, $view_mode); + + $variables['elements'] = $build; + $suggestions = \Drupal::moduleHandler()->invokeAll('theme_suggestions_node', [$variables]); + + $this->assertEqual($suggestions, ['node__node_my_custom_view_mode', 'node__page', 'node__page__node_my_custom_view_mode', 'node__' . $node->id(), 'node__' . $node->id() . '__node_my_custom_view_mode'], 'Found expected node suggestions.'); + } + +} diff --git a/core/modules/node/tests/src/Functional/NodeTestBase.php b/core/modules/node/tests/src/Functional/NodeTestBase.php new file mode 100644 index 00000000..2ef0d73c --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeTestBase.php @@ -0,0 +1,110 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +use Drupal\Core\Session\AccountInterface; +use Drupal\node\NodeInterface; +use Drupal\Tests\BrowserTestBase; + +/** + * Sets up page and article content types. + */ +abstract class NodeTestBase extends BrowserTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['node', 'datetime']; + + /** + * The node access control handler. + * + * @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface + */ + protected $accessHandler; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + // Create Basic page and Article node types. + if ($this->profile != 'standard') { + $this->drupalCreateContentType([ + 'type' => 'page', + 'name' => 'Basic page', + 'display_submitted' => FALSE, + ]); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + } + $this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('node'); + } + + /** + * Asserts that node access correctly grants or denies access. + * + * @param array $ops + * An associative array of the expected node access grants for the node + * and account, with each key as the name of an operation (e.g. 'view', + * 'delete') and each value a Boolean indicating whether access to that + * operation should be granted. + * @param \Drupal\node\NodeInterface $node + * The node object to check. + * @param \Drupal\Core\Session\AccountInterface $account + * The user account for which to check access. + */ + public function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) { + foreach ($ops as $op => $result) { + $this->assertEqual($result, $this->accessHandler->access($node, $op, $account), $this->nodeAccessAssertMessage($op, $result, $node->language()->getId())); + } + } + + /** + * Asserts that node create access correctly grants or denies access. + * + * @param string $bundle + * The node bundle to check access to. + * @param bool $result + * Whether access should be granted or not. + * @param \Drupal\Core\Session\AccountInterface $account + * The user account for which to check access. + * @param string|null $langcode + * (optional) The language code indicating which translation of the node + * to check. If NULL, the untranslated (fallback) access is checked. + */ + public function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) { + $this->assertEqual($result, $this->accessHandler->createAccess($bundle, $account, [ + 'langcode' => $langcode, + ]), $this->nodeAccessAssertMessage('create', $result, $langcode)); + } + + /** + * Constructs an assert message to display which node access was tested. + * + * @param string $operation + * The operation to check access for. + * @param bool $result + * Whether access should be granted or not. + * @param string|null $langcode + * (optional) The language code indicating which translation of the node + * to check. If NULL, the untranslated (fallback) access is checked. + * + * @return string + * An assert message string which contains information in plain English + * about the node access permission test that was performed. + */ + public function nodeAccessAssertMessage($operation, $result, $langcode = NULL) { + return format_string( + 'Node access returns @result with operation %op, language code %langcode.', + [ + '@result' => $result ? 'true' : 'false', + '%op' => $operation, + '%langcode' => !empty($langcode) ? $langcode : 'empty' + ] + ); + } + +} diff --git a/core/modules/node/tests/src/Functional/NodeTitleTest.php b/core/modules/node/tests/src/Functional/NodeTitleTest.php new file mode 100644 index 00000000..8c94f795 --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeTitleTest.php @@ -0,0 +1,103 @@ +<?php + +namespace Drupal\Tests\node\Functional; + +use Drupal\comment\Tests\CommentTestTrait; +use Drupal\Component\Utility\Html; + +/** + * Tests node title. + * + * @group node + */ +class NodeTitleTest extends NodeTestBase { + + use CommentTestTrait; + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['comment', 'views', 'block']; + + /** + * A user with permission to bypass access content. + * + * @var \Drupal\user\UserInterface + */ + protected $adminUser; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->drupalPlaceBlock('system_breadcrumb_block'); + + $this->adminUser = $this->drupalCreateUser(['administer nodes', 'create article content', 'create page content', 'post comments']); + $this->drupalLogin($this->adminUser); + $this->addDefaultCommentField('node', 'page'); + } + + /** + * Creates one node and tests if the node title has the correct value. + */ + public function testNodeTitle() { + // Create "Basic page" content with title. + // Add the node to the frontpage so we can test if teaser links are + // clickable. + $settings = [ + 'title' => $this->randomMachineName(8), + 'promote' => 1, + ]; + $node = $this->drupalCreateNode($settings); + + // Test <title> tag. + $this->drupalGet('node/' . $node->id()); + $xpath = '//title'; + $this->assertEqual($this->xpath($xpath)[0]->getText(), $node->label() . ' | Drupal', 'Page title is equal to node title.', 'Node'); + + // Test breadcrumb in comment preview. + $this->drupalGet('comment/reply/node/' . $node->id() . '/comment'); + $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a'; + $this->assertEqual($this->xpath($xpath)[0]->getText(), $node->label(), 'Node breadcrumb is equal to node title.', 'Node'); + + // Test node title in comment preview. + $this->assertEqual($this->xpath('//article[contains(concat(" ", normalize-space(@class), " "), :node-class)]/h2/a/span', [':node-class' => ' node--type-' . $node->bundle() . ' '])[0]->getText(), $node->label(), 'Node preview title is equal to node title.', 'Node'); + + // Test node title is clickable on teaser list (/node). + $this->drupalGet('node'); + $this->clickLink($node->label()); + + // Test edge case where node title is set to 0. + $settings = [ + 'title' => 0, + ]; + $node = $this->drupalCreateNode($settings); + // Test that 0 appears as <title>. + $this->drupalGet('node/' . $node->id()); + $this->assertTitle(0 . ' | Drupal', 'Page title is equal to 0.', 'Node'); + // Test that 0 appears in the template <h1>. + $xpath = '//h1'; + $this->assertEqual(current($this->xpath($xpath)), 0, 'Node title is displayed as 0.', 'Node'); + + // Test edge case where node title contains special characters. + $edge_case_title = 'article\'s "title".'; + $settings = [ + 'title' => $edge_case_title, + ]; + $node = $this->drupalCreateNode($settings); + // Test that the title appears as <title>. The title will be escaped on the + // the page. + $edge_case_title_escaped = Html::escape($edge_case_title); + $this->drupalGet('node/' . $node->id()); + $this->assertRaw('<title>' . $edge_case_title_escaped . ' | Drupal', 'Page title is equal to article\'s "title".', 'Node'); + + // Test that the title appears as when reloading the node page. + $this->drupalGet('node/' . $node->id()); + $this->assertRaw('<title>' . $edge_case_title_escaped . ' | Drupal', 'Page title is equal to article\'s "title".', 'Node'); + + } + +} diff --git a/core/modules/node/tests/src/Functional/NodeTitleXSSTest.php b/core/modules/node/tests/src/Functional/NodeTitleXSSTest.php new file mode 100644 index 00000000..4b750875 --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeTitleXSSTest.php @@ -0,0 +1,43 @@ +drupalCreateUser(['create page content', 'edit any page content']); + $this->drupalLogin($web_user); + + $xss = ''; + $title = $xss . $this->randomMachineName(); + $edit = []; + $edit['title[0][value]'] = $title; + + $this->drupalPostForm('node/add/page', $edit, t('Preview')); + $this->assertNoRaw($xss, 'Harmful tags are escaped when previewing a node.'); + + $settings = ['title' => $title]; + $node = $this->drupalCreateNode($settings); + + $this->drupalGet('node/' . $node->id()); + // Titles should be escaped. + $this->assertRaw('' . Html::escape($title) . ' | Drupal', 'Title is displayed when viewing a node.'); + $this->assertNoRaw($xss, 'Harmful tags are escaped when viewing a node.'); + + $this->drupalGet('node/' . $node->id() . '/edit'); + $this->assertNoRaw($xss, 'Harmful tags are escaped when editing a node.'); + } + +} diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/tests/src/Functional/NodeTranslationUITest.php similarity index 81% rename from core/modules/node/src/Tests/NodeTranslationUITest.php rename to core/modules/node/tests/src/Functional/NodeTranslationUITest.php index 063469d3..a44bea13 100644 --- a/core/modules/node/src/Tests/NodeTranslationUITest.php +++ b/core/modules/node/tests/src/Functional/NodeTranslationUITest.php @@ -1,9 +1,9 @@ drupalPlaceBlock('help_block', array('region' => 'content')); + $this->drupalPlaceBlock('help_block', ['region' => 'content']); // Display the language selector. $this->drupalLogin($this->administrator); - $edit = array('language_configuration[language_alterable]' => TRUE); + $edit = ['language_configuration[language_alterable]' => TRUE]; $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type')); $this->drupalLogin($this->translator); } @@ -75,14 +75,14 @@ public function testPublishedStatusNoFields() { $this->drupalLogin($this->administrator); // Delete all fields. $this->drupalGet('admin/structure/types/manage/article/fields'); - $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.' . $this->fieldName . '/delete', array(), t('Delete')); - $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.field_tags/delete', array(), t('Delete')); - $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.field_image/delete', array(), t('Delete')); + $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.' . $this->fieldName . '/delete', [], t('Delete')); + $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.field_tags/delete', [], t('Delete')); + $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.field_image/delete', [], t('Delete')); // Add a node. $default_langcode = $this->langcodes[0]; - $values[$default_langcode] = array('title' => array(array('value' => $this->randomMachineName()))); - $entity_id = $this->createEntity($values[$default_langcode], $default_langcode); + $values[$default_langcode] = ['title' => [['value' => $this->randomMachineName()]]]; + $this->entityId = $this->createEntity($values[$default_langcode], $default_langcode); $storage = $this->container->get('entity_type.manager') ->getStorage($this->entityTypeId); $storage->resetCache([$this->entityId]); @@ -91,15 +91,17 @@ public function testPublishedStatusNoFields() { // Add a content translation. $langcode = 'fr'; $language = ConfigurableLanguage::load($langcode); - $values[$langcode] = array('title' => array(array('value' => $this->randomMachineName()))); + $values[$langcode] = ['title' => [['value' => $this->randomMachineName()]]]; $entity_type_id = $entity->getEntityTypeId(); $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [ $entity->getEntityTypeId() => $entity->id(), 'source' => $default_langcode, 'target' => $langcode - ], array('language' => $language)); - $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), t('Save and unpublish (this translation)')); + ], ['language' => $language]); + $edit = $this->getEditValues($values, $langcode); + $edit['status[value]'] = FALSE; + $this->drupalPostForm($add_url, $edit, t('Save (this translation)')); $storage->resetCache([$this->entityId]); $entity = $storage->load($this->entityId); @@ -112,40 +114,28 @@ public function testPublishedStatusNoFields() { * {@inheritdoc} */ protected function getTranslatorPermissions() { - return array_merge(parent::getTranslatorPermissions(), array('administer nodes', "edit any $this->bundle content")); + return array_merge(parent::getTranslatorPermissions(), ['administer nodes', "edit any $this->bundle content"]); } /** * {@inheritdoc} */ protected function getEditorPermissions() { - return array('administer nodes', 'create article content'); + return ['administer nodes', 'create article content']; } /** * {@inheritdoc} */ protected function getAdministratorPermissions() { - return array_merge(parent::getAdministratorPermissions(), array('access administration pages', 'administer content types', 'administer node fields', 'access content overview', 'bypass node access', 'administer languages', 'administer themes', 'view the administration theme')); + return array_merge(parent::getAdministratorPermissions(), ['access administration pages', 'administer content types', 'administer node fields', 'access content overview', 'bypass node access', 'administer languages', 'administer themes', 'view the administration theme']); } /** * {@inheritdoc} */ protected function getNewEntityValues($langcode) { - return array('title' => array(array('value' => $this->randomMachineName()))) + parent::getNewEntityValues($langcode); - } - - /** - * {@inheritdoc} - */ - protected function getFormSubmitAction(EntityInterface $entity, $langcode) { - if ($entity->getTranslation($langcode)->isPublished()) { - return t('Save and keep published') . $this->getFormSubmitSuffix($entity, $langcode); - } - else { - return t('Save and keep unpublished') . $this->getFormSubmitSuffix($entity, $langcode); - } + return ['title' => [['value' => $this->randomMachineName()]]] + parent::getNewEntityValues($langcode); } /** @@ -158,18 +148,18 @@ protected function doTestPublishedStatus() { $entity = $storage->load($this->entityId); $languages = $this->container->get('language_manager')->getLanguages(); - $actions = array( - t('Save and keep published'), - t('Save and unpublish'), - ); + $statuses = [ + TRUE, + FALSE, + ]; - foreach ($actions as $index => $action) { + foreach ($statuses as $index => $value) { // (Un)publish the node translations and check that the translation // statuses are (un)published accordingly. foreach ($this->langcodes as $langcode) { - $options = array('language' => $languages[$langcode]); + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); - $this->drupalPostForm($url, array(), $action . $this->getFormSubmitSuffix($entity, $langcode), $options); + $this->drupalPostForm($url, ['status[value]' => $value], t('Save') . $this->getFormSubmitSuffix($entity, $langcode), $options); } $storage->resetCache([$this->entityId]); $entity = $storage->load($this->entityId); @@ -192,25 +182,25 @@ protected function doTestAuthoringInfo() { $storage->resetCache([$this->entityId]); $entity = $storage->load($this->entityId); $languages = $this->container->get('language_manager')->getLanguages(); - $values = array(); + $values = []; // Post different base field information for each translation. foreach ($this->langcodes as $langcode) { $user = $this->drupalCreateUser(); - $values[$langcode] = array( + $values[$langcode] = [ 'uid' => $user->id(), 'created' => REQUEST_TIME - mt_rand(0, 1000), 'sticky' => (bool) mt_rand(0, 1), 'promote' => (bool) mt_rand(0, 1), - ); - $edit = array( + ]; + $edit = [ 'uid[0][target_id]' => $user->getUsername(), 'created[0][value][date]' => format_date($values[$langcode]['created'], 'custom', 'Y-m-d'), 'created[0][value][time]' => format_date($values[$langcode]['created'], 'custom', 'H:i:s'), 'sticky[value]' => $values[$langcode]['sticky'], 'promote[value]' => $values[$langcode]['promote'], - ); - $options = array('language' => $languages[$langcode]); + ]; + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); $this->drupalPostForm($url, $edit, $this->getFormSubmitAction($entity, $langcode), $options); } @@ -232,11 +222,11 @@ protected function doTestAuthoringInfo() { */ public function testTranslationLinkTheme() { $this->drupalLogin($this->administrator); - $article = $this->drupalCreateNode(array('type' => 'article', 'langcode' => $this->langcodes[0])); + $article = $this->drupalCreateNode(['type' => 'article', 'langcode' => $this->langcodes[0]]); // Set up Seven as the admin theme and use it for node editing. - $this->container->get('theme_handler')->install(array('seven')); - $edit = array(); + $this->container->get('theme_handler')->install(['seven']); + $edit = []; $edit['admin_theme'] = 'seven'; $edit['use_admin_theme'] = TRUE; $this->drupalPostForm('admin/appearance', $edit, t('Save configuration')); @@ -259,16 +249,16 @@ public function testTranslationLinkTheme() { public function testDisabledBundle() { // Create a bundle that does not have translation enabled. $disabledBundle = $this->randomMachineName(); - $this->drupalCreateContentType(array('type' => $disabledBundle, 'name' => $disabledBundle)); + $this->drupalCreateContentType(['type' => $disabledBundle, 'name' => $disabledBundle]); // Create a node for each bundle. - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'type' => $this->bundle, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - )); + ]); // Make sure that nothing was inserted into the {content_translation} table. - $rows = db_query('SELECT nid, count(nid) AS count FROM {node_field_data} WHERE type <> :type GROUP BY nid HAVING count(nid) >= 2', array(':type' => $this->bundle))->fetchAll(); + $rows = db_query('SELECT nid, count(nid) AS count FROM {node_field_data} WHERE type <> :type GROUP BY nid HAVING count(nid) >= 2', [':type' => $this->bundle])->fetchAll(); $this->assertEqual(0, count($rows)); // Ensure the translation tab is not accessible. @@ -287,7 +277,7 @@ public function testTranslationRendering() { $node->setPromoted(TRUE); // Create translations. - foreach (array_diff($this->langcodes, array($default_langcode)) as $langcode) { + foreach (array_diff($this->langcodes, [$default_langcode]) as $langcode) { $values[$langcode] = $this->getNewEntityValues($langcode); $translation = $node->addTranslation($langcode, $values[$langcode]); // Publish and promote the translation to frontpage. @@ -297,7 +287,7 @@ public function testTranslationRendering() { $node->save(); // Test that the frontpage view displays the correct translations. - \Drupal::service('module_installer')->install(array('views'), TRUE); + \Drupal::service('module_installer')->install(['views'], TRUE); $this->rebuildContainer(); $this->doTestTranslations('node', $values); @@ -316,7 +306,7 @@ public function testTranslationRendering() { // See also assertTaxonomyPage() in NodeAccessBaseTableTest. $node_href = 'node/' . $node->id(); foreach ($this->langcodes as $langcode) { - $this->drupalGet('node', array('language' => \Drupal::languageManager()->getLanguage($langcode))); + $this->drupalGet('node', ['language' => \Drupal::languageManager()->getLanguage($langcode)]); $num_match_found = 0; if ($langcode == 'en') { // Site default language does not have langcode prefix in the URL. @@ -327,7 +317,7 @@ public function testTranslationRendering() { } $pattern = '|^' . $expected_href . '$|'; foreach ($this->xpath("//a[text()='Read more']") as $link) { - if (preg_match($pattern, (string) $link['href'], $matches) == TRUE) { + if (preg_match($pattern, $link->getAttribute('href'), $matches) == TRUE) { $num_match_found++; } } @@ -338,7 +328,7 @@ public function testTranslationRendering() { // language. $comment_form_href = 'node/' . $node->id() . '#comment-form'; foreach ($this->langcodes as $langcode) { - $this->drupalGet('node', array('language' => \Drupal::languageManager()->getLanguage($langcode))); + $this->drupalGet('node', ['language' => \Drupal::languageManager()->getLanguage($langcode)]); $num_match_found = 0; if ($langcode == 'en') { // Site default language does not have langcode prefix in the URL. @@ -349,7 +339,7 @@ public function testTranslationRendering() { } $pattern = '|^' . $expected_href . '$|'; foreach ($this->xpath("//a[text()='Add new comment']") as $link) { - if (preg_match($pattern, (string) $link['href'], $matches) == TRUE) { + if (preg_match($pattern, $link->getAttribute('href'), $matches) == TRUE) { $num_match_found++; } } @@ -374,8 +364,8 @@ public function testTranslationRendering() { protected function doTestTranslations($path, array $values) { $languages = $this->container->get('language_manager')->getLanguages(); foreach ($this->langcodes as $langcode) { - $this->drupalGet($path, array('language' => $languages[$langcode])); - $this->assertText($values[$langcode]['title'][0]['value'], format_string('The %langcode node translation is correctly displayed.', array('%langcode' => $langcode))); + $this->drupalGet($path, ['language' => $languages[$langcode]]); + $this->assertText($values[$langcode]['title'][0]['value'], format_string('The %langcode node translation is correctly displayed.', ['%langcode' => $langcode])); } } @@ -398,8 +388,8 @@ protected function doTestAlternateHreflangLinks(Url $url) { foreach ($urls as $alternate_langcode => $language_url) { // Retrieve desired link elements from the HTML head. $links = $this->xpath('head/link[@rel = "alternate" and @href = :href and @hreflang = :hreflang]', - array(':href' => $language_url->toString(), ':hreflang' => $alternate_langcode)); - $this->assert(isset($links[0]), format_string('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', array('%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()))); + [':href' => $language_url->toString(), ':hreflang' => $alternate_langcode]); + $this->assert(isset($links[0]), format_string('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', ['%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString()])); } } } @@ -446,15 +436,15 @@ protected function doTestTranslationEdit() { foreach ($this->langcodes as $langcode) { // We only want to test the title for non-english translations. if ($langcode != 'en') { - $options = array('language' => $languages[$langcode]); + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); $this->drupalGet($url); - $title = t('Edit @type @title [%language translation]', array( + $title = t('Edit @type @title [%language translation]', [ '@type' => $type_name, '@title' => $entity->getTranslation($langcode)->label(), '%language' => $languages[$langcode]->getName(), - )); + ]); $this->assertRaw($title); } } diff --git a/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/tests/src/Functional/NodeTypeInitialLanguageTest.php similarity index 84% rename from core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php rename to core/modules/node/tests/src/Functional/NodeTypeInitialLanguageTest.php index 73bfdb34..9c442fd5 100644 --- a/core/modules/node/src/Tests/NodeTypeInitialLanguageTest.php +++ b/core/modules/node/tests/src/Functional/NodeTypeInitialLanguageTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'administer languages')); + $web_user = $this->drupalCreateUser(['bypass node access', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'administer languages']); $this->drupalLogin($web_user); } @@ -31,7 +31,7 @@ protected function setUp() { * The default initial language must be the site's default, and the language * locked option must be on. */ - function testNodeTypeInitialLanguageDefaults() { + public function testNodeTypeInitialLanguageDefaults() { $this->drupalGet('admin/structure/types/manage/article'); $this->assertOptionSelected('edit-language-configuration-langcode', LanguageInterface::LANGCODE_SITE_DEFAULT, 'The default initial language is the site default.'); $this->assertNoFieldChecked('edit-language-configuration-language-alterable', 'Language selector is hidden by default.'); @@ -45,20 +45,20 @@ function testNodeTypeInitialLanguageDefaults() { $this->assertNoField('langcode', 'Language is not selectable on node add/edit page by default.'); // Adds a new language and set it as default. - $edit = array( + $edit = [ 'predefined_langcode' => 'hu', - ); + ]; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); - $edit = array( + $edit = [ 'site_default_language' => 'hu', - ); + ]; $this->drupalPostForm('admin/config/regional/language', $edit, t('Save configuration')); // Tests the initial language after changing the site default language. // First unhide the language selector. - $edit = array( + $edit = [ 'language_configuration[language_alterable]' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type')); $this->drupalGet('node/add/article'); $this->assertField('langcode[0][value]', 'Language is selectable on node add/edit page when language not hidden.'); @@ -75,12 +75,12 @@ function testNodeTypeInitialLanguageDefaults() { $language_display = $this->xpath('//*[@id="langcode"]'); $this->assert(!empty($language_display), 'Language field is visible on manage display tab.'); // Tests if the language field is hidden by default. - $this->assertOptionSelected('edit-fields-langcode-type', 'hidden', 'Language is hidden by default on manage display tab.'); + $this->assertOptionSelected('edit-fields-langcode-region', 'hidden', 'Language is hidden by default on manage display tab.'); // Changes the initial language settings. - $edit = array( + $edit = [ 'language_configuration[langcode]' => 'en', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type')); $this->drupalGet('node/add/article'); $this->assertOptionSelected('edit-langcode-0-value', 'en', 'The initial language is the defined language.'); @@ -89,36 +89,37 @@ function testNodeTypeInitialLanguageDefaults() { /** * Tests language field visibility features. */ - function testLanguageFieldVisibility() { + public function testLanguageFieldVisibility() { // Creates a node to test Language field visibility feature. - $edit = array( + $edit = [ 'title[0][value]' => $this->randomMachineName(8), 'body[0][value]' => $this->randomMachineName(16), - ); + ]; $this->drupalPostForm('node/add/article', $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertTrue($node, 'Node found in database.'); // Loads node page and check if Language field is hidden by default. $this->drupalGet('node/' . $node->id()); - $language_field = $this->xpath('//div[@id=:id]/div', array( + $language_field = $this->xpath('//div[@id=:id]/div', [ ':id' => 'field-language-display', - )); + ]); $this->assertTrue(empty($language_field), 'Language field value is not shown by default on node page.'); // Configures Language field formatter and check if it is saved. - $edit = array( + $edit = [ 'fields[langcode][type]' => 'language', - ); + 'fields[langcode][region]' => 'content', + ]; $this->drupalPostForm('admin/structure/types/manage/article/display', $edit, t('Save')); $this->drupalGet('admin/structure/types/manage/article/display'); $this->assertOptionSelected('edit-fields-langcode-type', 'language', 'Language field has been set to visible.'); // Loads node page and check if Language field is shown. $this->drupalGet('node/' . $node->id()); - $language_field = $this->xpath('//div[@id=:id]/div', array( + $language_field = $this->xpath('//div[@id=:id]/div', [ ':id' => 'field-language-display', - )); + ]); $this->assertFalse(empty($language_field), 'Language field value is shown on node page.'); } diff --git a/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php b/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php new file mode 100644 index 00000000..07e61a03 --- /dev/null +++ b/core/modules/node/tests/src/Functional/NodeTypeTranslationTest.php @@ -0,0 +1,176 @@ +adminUser = $this->drupalCreateUser($admin_permissions); + + // Add languages. + foreach ($this->additionalLangcodes as $langcode) { + ConfigurableLanguage::createFromLangcode($langcode)->save(); + } + } + + /** + * {@inheritdoc} + * + * Install Drupal in a language other than English for this test. This is not + * needed to test the node type translation itself but acts as a regression + * test. + * + * @see https://www.drupal.org/node/2584603 + */ + protected function installParameters() { + $parameters = parent::installParameters(); + $parameters['parameters']['langcode'] = $this->defaultLangcode; + return $parameters; + } + + /** + * Tests the node type translation. + */ + public function testNodeTypeTranslation() { + $type = Unicode::strtolower($this->randomMachineName(16)); + $name = $this->randomString(); + $this->drupalLogin($this->adminUser); + $this->drupalCreateContentType(['type' => $type, 'name' => $name]); + + // Translate the node type name. + $langcode = $this->additionalLangcodes[0]; + $translated_name = $langcode . '-' . $name; + $edit = [ + "translation[config_names][node.type.$type][name]" => $translated_name, + ]; + + // Edit the title label to avoid having an exception when we save the translation. + $this->drupalPostForm("admin/structure/types/manage/$type/translate/$langcode/add", $edit, t('Save translation')); + + // Check the name is translated without admin theme for editing. + $this->drupalPostForm('admin/appearance', ['use_admin_theme' => '0'], t('Save configuration')); + $this->drupalGet("$langcode/node/add/$type"); + // This is a Spanish page, so ensure the text asserted is translated in + // Spanish and not French by adding the langcode option. + $this->assertRaw(t('Create @name', ['@name' => $translated_name], ['langcode' => $langcode])); + + // Check the name is translated with admin theme for editing. + $this->drupalPostForm('admin/appearance', ['use_admin_theme' => '1'], t('Save configuration')); + $this->drupalGet("$langcode/node/add/$type"); + // This is a Spanish page, so ensure the text asserted is translated in + // Spanish and not French by adding the langcode option. + $this->assertRaw(t('Create @name', ['@name' => $translated_name], ['langcode' => $langcode])); + } + + /** + * Tests the node type title label translation. + */ + public function testNodeTypeTitleLabelTranslation() { + $type = Unicode::strtolower($this->randomMachineName(16)); + $name = $this->randomString(); + $this->drupalLogin($this->adminUser); + $this->drupalCreateContentType(['type' => $type, 'name' => $name]); + $langcode = $this->additionalLangcodes[0]; + + // Edit the title label for it to be displayed on the translation form. + $this->drupalPostForm("admin/structure/types/manage/$type", ['title_label' => 'Edited title'], t('Save content type')); + + // Assert that the title label is displayed on the translation form with the right value. + $this->drupalGet("admin/structure/types/manage/$type/translate/$langcode/add"); + $this->assertText('Edited title'); + + // Translate the title label. + $this->drupalPostForm(NULL, ["translation[config_names][core.base_field_override.node.$type.title][label]" => 'Translated title'], t('Save translation')); + + // Assert that the right title label is displayed on the node add form. The + // translations are created in this test; therefore, the assertions do not + // use t(). If t() were used then the correct langcodes would need to be + // provided. + $this->drupalGet("node/add/$type"); + $this->assertText('Edited title'); + $this->drupalGet("$langcode/node/add/$type"); + $this->assertText('Translated title'); + + // Add an e-mail field. + $this->drupalPostForm("admin/structure/types/manage/$type/fields/add-field", ['new_storage_type' => 'email', 'label' => 'Email', 'field_name' => 'email'], 'Save and continue'); + $this->drupalPostForm(NULL, [], 'Save field settings'); + $this->drupalPostForm(NULL, [], 'Save settings'); + + $type = Unicode::strtolower($this->randomMachineName(16)); + $name = $this->randomString(); + $this->drupalCreateContentType(['type' => $type, 'name' => $name]); + + // Set tabs. + $this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]); + + // Change default language. + $this->drupalPostForm('admin/config/regional/language', ['site_default_language' => 'es'], 'Save configuration'); + + // Try re-using the email field. + $this->drupalGet("es/admin/structure/types/manage/$type/fields/add-field"); + $this->drupalPostForm(NULL, ['existing_storage_name' => 'field_email', 'existing_storage_label' => 'Email'], 'Save and continue'); + $this->assertResponse(200); + $this->drupalGet("es/admin/structure/types/manage/$type/fields/node.$type.field_email/translate"); + $this->assertResponse(200); + $this->assertText("The configuration objects have different language codes so they cannot be translated"); + } + +} diff --git a/core/modules/node/src/Tests/NodeViewLanguageTest.php b/core/modules/node/tests/src/Functional/NodeViewLanguageTest.php similarity index 81% rename from core/modules/node/src/Tests/NodeViewLanguageTest.php rename to core/modules/node/tests/src/Functional/NodeViewLanguageTest.php index 71fe4d15..47304275 100644 --- a/core/modules/node/src/Tests/NodeViewLanguageTest.php +++ b/core/modules/node/tests/src/Functional/NodeViewLanguageTest.php @@ -1,6 +1,6 @@ save(); // Create a node in Spanish. - $node = $this->drupalCreateNode(array('langcode' => 'es')); + $node = $this->drupalCreateNode(['langcode' => 'es']); $this->drupalGet($node->urlInfo()); $this->assertText('Spanish', 'The language field is displayed properly.'); diff --git a/core/modules/node/src/Tests/NodeViewTest.php b/core/modules/node/tests/src/Functional/NodeViewTest.php similarity index 79% rename from core/modules/node/src/Tests/NodeViewTest.php rename to core/modules/node/tests/src/Functional/NodeViewTest.php index 3a27ade0..b0eaa47f 100644 --- a/core/modules/node/src/Tests/NodeViewTest.php +++ b/core/modules/node/tests/src/Functional/NodeViewTest.php @@ -1,6 +1,6 @@ drupalGet($node->urlInfo()); $result = $this->xpath('//link[@rel = "canonical"]'); - $this->assertEqual($result[0]['href'], $node->url()); + $this->assertEqual($result[0]->getAttribute('href'), $node->url()); // Link relations are checked for access for anonymous users. $result = $this->xpath('//link[@rel = "version-history"]'); @@ -34,14 +34,14 @@ public function testHtmlHeadLinks() { $this->drupalGet($node->urlInfo()); $result = $this->xpath('//link[@rel = "canonical"]'); - $this->assertEqual($result[0]['href'], $node->url()); + $this->assertEqual($result[0]->getAttribute('href'), $node->url()); // Link relations are present regardless of access for authenticated users. $result = $this->xpath('//link[@rel = "version-history"]'); - $this->assertEqual($result[0]['href'], $node->url('version-history')); + $this->assertEqual($result[0]->getAttribute('href'), $node->url('version-history')); $result = $this->xpath('//link[@rel = "edit-form"]'); - $this->assertEqual($result[0]['href'], $node->url('edit-form')); + $this->assertEqual($result[0]->getAttribute('href'), $node->url('edit-form')); // Give anonymous users access to edit the node. Do this through the UI to // ensure caches are handled properly. @@ -56,13 +56,13 @@ public function testHtmlHeadLinks() { // version-history link. $this->drupalGet($node->urlInfo()); $result = $this->xpath('//link[@rel = "canonical"]'); - $this->assertEqual($result[0]['href'], $node->url()); + $this->assertEqual($result[0]->getAttribute('href'), $node->url()); $result = $this->xpath('//link[@rel = "version-history"]'); $this->assertFalse($result, 'Version history not present for anonymous users without access.'); $result = $this->xpath('//link[@rel = "edit-form"]'); - $this->assertEqual($result[0]['href'], $node->url('edit-form')); + $this->assertEqual($result[0]->getAttribute('href'), $node->url('edit-form')); } /** @@ -79,7 +79,7 @@ public function testLinkHeader() { $this->drupalGet($node->urlInfo()); - $links = explode(',', $this->drupalGetHeader('Link')); + $links = $this->drupalGetHeaders()['Link']; $this->assertEqual($links, $expected); } @@ -89,10 +89,10 @@ public function testLinkHeader() { public function testMultiByteUtf8() { $title = 'ðŸ'; $this->assertTrue(mb_strlen($title, 'utf-8') < strlen($title), 'Title has multi-byte characters.'); - $node = $this->drupalCreateNode(array('title' => $title)); + $node = $this->drupalCreateNode(['title' => $title]); $this->drupalGet($node->urlInfo()); $result = $this->xpath('//span[contains(@class, "field--name-title")]'); - $this->assertEqual((string) $result[0], $title, 'The passed title was returned.'); + $this->assertEqual($result[0]->getText(), $title, 'The passed title was returned.'); } } diff --git a/core/modules/node/src/Tests/PageViewTest.php b/core/modules/node/tests/src/Functional/PageViewTest.php similarity index 82% rename from core/modules/node/src/Tests/PageViewTest.php rename to core/modules/node/tests/src/Functional/PageViewTest.php index 086b3e17..9f7e4140 100644 --- a/core/modules/node/src/Tests/PageViewTest.php +++ b/core/modules/node/tests/src/Functional/PageViewTest.php @@ -1,6 +1,6 @@ drupalCreateNode(); $this->assertTrue(Node::load($node->id()), 'Node created.'); @@ -23,7 +23,7 @@ function testPageView() { $this->assertResponse(403); // Create a user without permission to edit node. - $web_user = $this->drupalCreateUser(array('access content')); + $web_user = $this->drupalCreateUser(['access content']); $this->drupalLogin($web_user); // Attempt to access edit page. @@ -31,7 +31,7 @@ function testPageView() { $this->assertResponse(403); // Create user with permission to edit node. - $web_user = $this->drupalCreateUser(array('bypass node access')); + $web_user = $this->drupalCreateUser(['bypass node access']); $this->drupalLogin($web_user); // Attempt to access edit page. diff --git a/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php b/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php new file mode 100644 index 00000000..223676b3 --- /dev/null +++ b/core/modules/node/tests/src/Functional/Update/NodeUpdateTest.php @@ -0,0 +1,67 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + ]; + } + + /** + * Tests that the node entity type has a 'published' entity key. + * + * @see node_update_8301() + */ + public function testPublishedEntityKey() { + // Check that the 'published' entity key does not exist prior to the update. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node'); + $this->assertFalse($entity_type->getKey('published')); + + // Run updates. + $this->runUpdates(); + + // Check that the entity key exists and it has the correct value. + $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('node'); + $this->assertEqual('status', $entity_type->getKey('published')); + } + + /** + * Tests that the node entity form has the status checkbox. + * + * @see node_post_update_configure_status_field_widget() + */ + public function testStatusCheckbox() { + // Run updates. + $this->runUpdates(); + + $query = \Drupal::entityQuery('entity_form_display') + ->condition('targetEntityType', 'node'); + $ids = $query->execute(); + $form_displays = EntityFormDisplay::loadMultiple($ids); + + /** + * @var string $id + * @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display + */ + foreach ($form_displays as $id => $form_display) { + $component = $form_display->getComponent('status'); + $this->assertEqual('boolean_checkbox', $component['type']); + $this->assertEqual(['display_label' => TRUE], $component['settings']); + } + } + +} diff --git a/core/modules/node/src/Tests/Views/BulkFormAccessTest.php b/core/modules/node/tests/src/Functional/Views/BulkFormAccessTest.php similarity index 82% rename from core/modules/node/src/Tests/Views/BulkFormAccessTest.php rename to core/modules/node/tests/src/Functional/Views/BulkFormAccessTest.php index 6dada72c..194b9b06 100644 --- a/core/modules/node/src/Tests/Views/BulkFormAccessTest.php +++ b/core/modules/node/tests/src/Functional/Views/BulkFormAccessTest.php @@ -1,6 +1,6 @@ drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); $this->accessHandler = \Drupal::entityManager()->getAccessControlHandler('node'); @@ -65,15 +65,15 @@ public function testNodeEditAccess() { // Create an account who will be the author of a private node. $author = $this->drupalCreateUser(); // Create a private node (author may view, edit and delete, others may not). - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'type' => 'article', - 'private' => array(array( - 'value' => TRUE, - )), + 'private' => [ + ['value' => TRUE], + ], 'uid' => $author->id(), - )); + ]); // Create an account that may view the private node, but not edit it. - $account = $this->drupalCreateUser(array('node test view')); + $account = $this->drupalCreateUser(['node test view']); $this->drupalLogin($account); // Ensure the node is published. @@ -83,10 +83,10 @@ public function testNodeEditAccess() { $this->assertEqual(FALSE, $this->accessHandler->access($node, 'update', $account), 'The node may not be edited.'); // Test editing the node using the bulk form. - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_unpublish_action', - ); + ]; $this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items')); $this->assertRaw(SafeMarkup::format('No access to execute %action on the @entity_type_label %entity_label.', [ '%action' => 'Unpublish content', @@ -100,7 +100,7 @@ public function testNodeEditAccess() { // Create an account that may view the private node, but can update the // status. - $account = $this->drupalCreateUser(array('administer nodes', 'node test view')); + $account = $this->drupalCreateUser(['administer nodes', 'node test view']); $this->drupalLogin($account); // Ensure the node is published. @@ -111,10 +111,10 @@ public function testNodeEditAccess() { $this->assertEqual(TRUE, $node->status->access('edit', $account), 'The node status can be edited.'); // Test editing the node using the bulk form. - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_unpublish_action', - ); + ]; $this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items')); // Test that the action message isn't shown. $this->assertNoRaw(SafeMarkup::format('%action was applied to 1 item.', [ @@ -132,25 +132,25 @@ public function testNodeDeleteAccess() { // Create an account who will be the author of a private node. $author = $this->drupalCreateUser(); // Create a private node (author may view, edit and delete, others may not). - $private_node = $this->drupalCreateNode(array( + $private_node = $this->drupalCreateNode([ 'type' => 'article', - 'private' => array(array( - 'value' => TRUE, - )), + 'private' => [ + ['value' => TRUE], + ], 'uid' => $author->id(), - )); + ]); // Create an account that may view the private node, but not delete it. - $account = $this->drupalCreateUser(array('access content', 'administer nodes', 'delete own article content', 'node test view')); + $account = $this->drupalCreateUser(['access content', 'administer nodes', 'delete own article content', 'node test view']); // Create a node that may be deleted too, to ensure the delete confirmation // page is shown later. In node_access_test.module, nodes may only be // deleted by the author. - $own_node = $this->drupalCreateNode(array( + $own_node = $this->drupalCreateNode([ 'type' => 'article', - 'private' => array(array( - 'value' => TRUE, - )), + 'private' => [ + ['value' => TRUE], + ], 'uid' => $account->id(), - )); + ]); $this->drupalLogin($account); // Ensure that the private node can not be deleted. @@ -159,13 +159,13 @@ public function testNodeDeleteAccess() { $this->assertEqual(TRUE, $this->accessHandler->access($own_node, 'delete', $account), 'The own node may be deleted.'); // Try to delete the node using the bulk form. - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'node_bulk_form[1]' => TRUE, 'action' => 'node_delete_action', - ); + ]; $this->drupalPostForm('test-node-bulk-form', $edit, t('Apply to selected items')); - $this->drupalPostForm(NULL, array(), t('Delete')); + $this->drupalPostForm(NULL, [], t('Delete')); // Ensure the private node still exists. $private_node = Node::load($private_node->id()); $this->assertNotNull($private_node, 'The private node has not been deleted.'); diff --git a/core/modules/node/src/Tests/Views/BulkFormTest.php b/core/modules/node/tests/src/Functional/Views/BulkFormTest.php similarity index 84% rename from core/modules/node/src/Tests/Views/BulkFormTest.php rename to core/modules/node/tests/src/Functional/Views/BulkFormTest.php index 677c9d83..319890b6 100644 --- a/core/modules/node/src/Tests/Views/BulkFormTest.php +++ b/core/modules/node/tests/src/Functional/Views/BulkFormTest.php @@ -1,6 +1,6 @@ assertEqual(count($view->result), 10, 'All created translations are selected.'); // Check the operations are accessible to the logged in user. - $this->drupalLogin($this->drupalCreateUser(array('administer nodes', 'access content overview', 'bypass node access'))); + $this->drupalLogin($this->drupalCreateUser(['administer nodes', 'access content overview', 'bypass node access'])); $this->drupalGet('test-node-bulk-form'); $elements = $this->xpath('//select[@id="edit-action"]//option'); $this->assertIdentical(count($elements), 8, 'All node operations are found.'); @@ -101,10 +101,10 @@ public function testBulkForm() { $this->assertTrue($node->isPublished(), 'Node is initially published'); $this->assertTrue($node->getTranslation('en-gb')->isPublished(), 'Node translation is published'); $this->assertTrue($node->getTranslation('it')->isPublished(), 'Node translation is published'); - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_unpublish_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode($node->id()); $this->assertFalse($node->isPublished(), 'Node has been unpublished'); @@ -112,10 +112,10 @@ public function testBulkForm() { $this->assertTrue($node->getTranslation('it')->isPublished(), 'Node translation has not been unpublished'); // Publish action. - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_publish_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode($node->id()); $this->assertTrue($node->isPublished(), 'Node has been published again'); @@ -124,10 +124,10 @@ public function testBulkForm() { $this->assertFalse($node->isSticky(), 'Node is not sticky'); $this->assertFalse($node->getTranslation('en-gb')->isSticky(), 'Node translation is not sticky'); $this->assertFalse($node->getTranslation('it')->isSticky(), 'Node translation is not sticky'); - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_make_sticky_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode($node->id()); $this->assertTrue($node->isSticky(), 'Node has been made sticky'); @@ -135,10 +135,10 @@ public function testBulkForm() { $this->assertFalse($node->getTranslation('it')->isSticky(), 'Node translation has not been made sticky'); // Make unsticky action. - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_make_unsticky_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode($node->id()); $this->assertFalse($node->isSticky(), 'Node is not sticky anymore'); @@ -147,10 +147,10 @@ public function testBulkForm() { $this->assertFalse($node->isPromoted(), 'Node is not promoted to the front page'); $this->assertFalse($node->getTranslation('en-gb')->isPromoted(), 'Node translation is not promoted to the front page'); $this->assertFalse($node->getTranslation('it')->isPromoted(), 'Node translation is not promoted to the front page'); - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_promote_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode($node->id()); $this->assertTrue($node->isPromoted(), 'Node has been promoted to the front page'); @@ -158,33 +158,43 @@ public function testBulkForm() { $this->assertFalse($node->getTranslation('it')->isPromoted(), 'Node translation has not been promoted to the front page'); // Demote from front page. - $edit = array( + $edit = [ 'node_bulk_form[0]' => TRUE, 'action' => 'node_unpromote_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode($node->id()); $this->assertFalse($node->isPromoted(), 'Node has been demoted'); // Select a bunch of translated and untranslated nodes and check that // operations are always applied to individual translations. - $edit = array( + $edit = [ // Original and all translations. - 'node_bulk_form[0]' => TRUE, // Node 1, English, original. - 'node_bulk_form[1]' => TRUE, // Node 1, British English. - 'node_bulk_form[2]' => TRUE, // Node 1, Italian. + // Node 1, English, original. + 'node_bulk_form[0]' => TRUE, + // Node 1, British English. + 'node_bulk_form[1]' => TRUE, + // Node 1, Italian. + 'node_bulk_form[2]' => TRUE, // Original and only one translation. - 'node_bulk_form[3]' => TRUE, // Node 2, English. - 'node_bulk_form[4]' => TRUE, // Node 2, British English, original. - 'node_bulk_form[5]' => FALSE, // Node 2, Italian. + // Node 2, English. + 'node_bulk_form[3]' => TRUE, + // Node 2, British English, original. + 'node_bulk_form[4]' => TRUE, + // Node 2, Italian. + 'node_bulk_form[5]' => FALSE, // Only a single translation. - 'node_bulk_form[6]' => TRUE, // Node 3, English. - 'node_bulk_form[7]' => FALSE, // Node 3, Italian, original. + // Node 3, English. + 'node_bulk_form[6]' => TRUE, + // Node 3, Italian, original. + 'node_bulk_form[7]' => FALSE, // Only a single untranslated node. - 'node_bulk_form[8]' => TRUE, // Node 4, English, untranslated. - 'node_bulk_form[9]' => FALSE, // Node 5, British English, untranslated. + // Node 4, English, untranslated. + 'node_bulk_form[8]' => TRUE, + // Node 5, British English, untranslated. + 'node_bulk_form[9]' => FALSE, 'action' => 'node_unpublish_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $node = $this->loadNode(1); $this->assertFalse($node->getTranslation('en')->isPublished(), '1: English translation has been unpublished'); @@ -209,23 +219,33 @@ public function testBulkForm() { public function testBulkDeletion() { // Select a bunch of translated and untranslated nodes and check that // nodes and individual translations are properly deleted. - $edit = array( + $edit = [ // Original and all translations. - 'node_bulk_form[0]' => TRUE, // Node 1, English, original. - 'node_bulk_form[1]' => TRUE, // Node 1, British English. - 'node_bulk_form[2]' => TRUE, // Node 1, Italian. + // Node 1, English, original. + 'node_bulk_form[0]' => TRUE, + // Node 1, British English. + 'node_bulk_form[1]' => TRUE, + // Node 1, Italian. + 'node_bulk_form[2]' => TRUE, // Original and only one translation. - 'node_bulk_form[3]' => TRUE, // Node 2, English. - 'node_bulk_form[4]' => TRUE, // Node 2, British English, original. - 'node_bulk_form[5]' => FALSE, // Node 2, Italian. + // Node 2, English. + 'node_bulk_form[3]' => TRUE, + // Node 2, British English, original. + 'node_bulk_form[4]' => TRUE, + // Node 2, Italian. + 'node_bulk_form[5]' => FALSE, // Only a single translation. - 'node_bulk_form[6]' => TRUE, // Node 3, English. - 'node_bulk_form[7]' => FALSE, // Node 3, Italian, original. + // Node 3, English. + 'node_bulk_form[6]' => TRUE, + // Node 3, Italian, original. + 'node_bulk_form[7]' => FALSE, // Only a single untranslated node. - 'node_bulk_form[8]' => TRUE, // Node 4, English, untranslated. - 'node_bulk_form[9]' => FALSE, // Node 5, British English, untranslated. + // Node 4, English, untranslated. + 'node_bulk_form[8]' => TRUE, + // Node 5, British English, untranslated. + 'node_bulk_form[9]' => FALSE, 'action' => 'node_delete_action', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Apply to selected items')); $label = $this->loadNode(1)->label(); @@ -239,7 +259,7 @@ public function testBulkDeletion() { $this->assertText($label); $this->assertNoText("$label (Original translation) - The following content translations will be deleted:"); - $this->drupalPostForm(NULL, array(), t('Delete')); + $this->drupalPostForm(NULL, [], t('Delete')); $node = $this->loadNode(1); $this->assertNull($node, '1: Node has been deleted'); diff --git a/core/modules/node/src/Tests/Views/FilterNodeAccessTest.php b/core/modules/node/tests/src/Functional/Views/FilterNodeAccessTest.php similarity index 92% rename from core/modules/node/src/Tests/Views/FilterNodeAccessTest.php rename to core/modules/node/tests/src/Functional/Views/FilterNodeAccessTest.php index dba44195..7eb7097d 100644 --- a/core/modules/node/src/Tests/Views/FilterNodeAccessTest.php +++ b/core/modules/node/tests/src/Functional/Views/FilterNodeAccessTest.php @@ -1,6 +1,6 @@ drupalCreateContentType(['type' => 'article', 'name' => 'Article']); @@ -51,10 +54,12 @@ protected function setUp() { $this->drupalLogin($web_user); foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) { $settings = [ - 'body' => [[ - 'value' => $type . ' node', - 'format' => filter_default_format(), - ]], + 'body' => [ + [ + 'value' => $type . ' node', + 'format' => filter_default_format(), + ], + ], 'title' => t('@private_public Article created by @user', ['@private_public' => $type, '@user' => $web_user->getUsername()]), 'type' => 'article', 'uid' => $web_user->id(), diff --git a/core/modules/node/tests/src/Functional/Views/FilterUidRevisionTest.php b/core/modules/node/tests/src/Functional/Views/FilterUidRevisionTest.php new file mode 100644 index 00000000..2b3f3b30 --- /dev/null +++ b/core/modules/node/tests/src/Functional/Views/FilterUidRevisionTest.php @@ -0,0 +1,54 @@ +drupalCreateUser(); + $no_author = $this->drupalCreateUser(); + + $expected_result = []; + // Create one node, with the author as the node author. + $node = $this->drupalCreateNode(['uid' => $author->id()]); + $expected_result[] = ['nid' => $node->id()]; + // Create one node of which an additional revision author will be the + // author. + $node = $this->drupalCreateNode(['revision_uid' => $no_author->id()]); + $expected_result[] = ['nid' => $node->id()]; + $revision = clone $node; + // Force to add a new revision. + $revision->set('vid', NULL); + $revision->set('revision_uid', $author->id()); + $revision->save(); + + // Create one node on which the author has neither authorship of revisions + // or the main node. + $this->drupalCreateNode(['uid' => $no_author->id()]); + + $view = Views::getView('test_filter_node_uid_revision'); + $view->initHandlers(); + $view->filter['uid_revision']->value = [$author->id()]; + + $this->executeView($view); + $this->assertIdenticalResultset($view, $expected_result, ['nid' => 'nid'], 'Make sure that the view only returns nodes which match either the node or the revision author.'); + } + +} diff --git a/core/modules/node/src/Tests/Views/FrontPageTest.php b/core/modules/node/tests/src/Functional/Views/FrontPageTest.php similarity index 91% rename from core/modules/node/src/Tests/Views/FrontPageTest.php rename to core/modules/node/tests/src/Functional/Views/FrontPageTest.php index b27c416c..37a6b91f 100644 --- a/core/modules/node/src/Tests/Views/FrontPageTest.php +++ b/core/modules/node/tests/src/Functional/Views/FrontPageTest.php @@ -1,13 +1,13 @@ nodeStorage = $this->container->get('entity.manager') ->getStorage('node'); @@ -74,14 +77,14 @@ public function testFrontPage() { $this->executeView($view); $view->preview(); - $this->assertEqual($view->getTitle(), format_string('Welcome to @site_name', array('@site_name' => $site_name)), 'The welcome title is used for the empty view.'); + $this->assertEqual($view->getTitle(), format_string('Welcome to @site_name', ['@site_name' => $site_name]), 'The welcome title is used for the empty view.'); $view->destroy(); // Create some nodes on the frontpage view. Add more than 10 nodes in order // to enable paging. - $expected = array(); + $expected = []; for ($i = 0; $i < 20; $i++) { - $values = array(); + $values = []; $values['type'] = 'article'; $values['title'] = $this->randomMachineName(); $values['promote'] = TRUE; @@ -94,21 +97,21 @@ public function testFrontPage() { $node = $this->nodeStorage->create($values); $node->save(); // Put the sticky on at the front. - array_unshift($expected, array('nid' => $node->id())); + array_unshift($expected, ['nid' => $node->id()]); } else { $values['sticky'] = FALSE; $node = $this->nodeStorage->create($values); $node->save(); - array_push($expected, array('nid' => $node->id())); + array_push($expected, ['nid' => $node->id()]); } } // Create some nodes which aren't on the frontpage, either because they // aren't promoted or because they aren't published. - $not_expected_nids = array(); + $not_expected_nids = []; - $values = array(); + $values = []; $values['type'] = 'article'; $values['title'] = $this->randomMachineName(); $values['status'] = TRUE; @@ -132,7 +135,7 @@ public function testFrontPage() { $node->save(); $not_expected_nids[] = $node->id(); - $column_map = array('nid' => 'nid'); + $column_map = ['nid' => 'nid']; $view->setDisplay('page_1'); $this->executeView($view); @@ -171,7 +174,7 @@ protected function assertNotInResultSet(ViewExecutable $view, array $not_expecte public function testAdminFrontPage() { // When a user with sufficient permissions is logged in, views_ui adds // contextual links to the homepage view. This verifies there are no errors. - \Drupal::service('module_installer')->install(array('views_ui')); + \Drupal::service('module_installer')->install(['views_ui']); // Log in root user with sufficient permissions. $this->drupalLogin($this->rootUser); // Test frontpage view. @@ -265,7 +268,7 @@ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { $render_cache_tags ); $expected_tags = Cache::mergeTags($empty_node_listing_cache_tags, $cache_context_tags); - $expected_tags = Cache::mergeTags($expected_tags, ['rendered', 'config:user.role.anonymous', 'config:system.site']); + $expected_tags = Cache::mergeTags($expected_tags, ['http_response', 'rendered', 'config:user.role.anonymous', 'config:system.site']); $this->assertPageCacheContextsAndTags( Url::fromRoute('view.frontpage.page_1'), $cache_contexts, @@ -331,7 +334,7 @@ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { $this->assertPageCacheContextsAndTags( Url::fromRoute('view.frontpage.page_1'), $cache_contexts, - Cache::mergeTags($first_page_output_cache_tags, ['rendered', 'config:user.role.anonymous']) + Cache::mergeTags($first_page_output_cache_tags, ['http_response', 'rendered', 'config:user.role.anonymous']) ); // Second page. @@ -350,6 +353,7 @@ protected function doTestFrontPageViewCacheTags($do_assert_views_caches) { 'node_view', 'user_view', 'user:0', + 'http_response', 'rendered', // FinishResponseSubscriber adds this cache tag to responses that have the // 'user.permissions' cache context for anonymous users. diff --git a/core/modules/node/src/Tests/Views/NodeFieldFilterTest.php b/core/modules/node/tests/src/Functional/Views/NodeFieldFilterTest.php similarity index 76% rename from core/modules/node/src/Tests/Views/NodeFieldFilterTest.php rename to core/modules/node/tests/src/Functional/Views/NodeFieldFilterTest.php index 6b6d5e24..c2ee2f27 100644 --- a/core/modules/node/src/Tests/Views/NodeFieldFilterTest.php +++ b/core/modules/node/tests/src/Functional/Views/NodeFieldFilterTest.php @@ -1,6 +1,6 @@ profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); } // Add two new languages. @@ -43,15 +46,15 @@ function setUp() { ConfigurableLanguage::createFromLangcode('es')->save(); // Set up node titles. - $this->nodeTitles = array( + $this->nodeTitles = [ 'en' => 'Food in Paris', 'es' => 'Comida en Paris', 'fr' => 'Nouriture en Paris', - ); + ]; // Create node with translations. $node = $this->drupalCreateNode(['title' => $this->nodeTitles['en'], 'langcode' => 'en', 'type' => 'page', 'body' => [['value' => $this->nodeTitles['en']]]]); - foreach (array('es', 'fr') as $langcode) { + foreach (['es', 'fr'] as $langcode) { $translation = $node->addTranslation($langcode, ['title' => $this->nodeTitles[$langcode]]); $translation->body->value = $this->nodeTitles[$langcode]; } @@ -64,19 +67,19 @@ function setUp() { public function testFilters() { // Test the title filter page, which filters for title contains 'Comida'. // Should show just the Spanish translation, once. - $this->assertPageCounts('test-title-filter', array('es' => 1, 'fr' => 0, 'en' => 0), 'Comida title filter'); + $this->assertPageCounts('test-title-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida title filter'); // Test the body filter page, which filters for body contains 'Comida'. // Should show just the Spanish translation, once. - $this->assertPageCounts('test-body-filter', array('es' => 1, 'fr' => 0, 'en' => 0), 'Comida body filter'); + $this->assertPageCounts('test-body-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida body filter'); // Test the title Paris filter page, which filters for title contains // 'Paris'. Should show each translation once. - $this->assertPageCounts('test-title-paris', array('es' => 1, 'fr' => 1, 'en' => 1), 'Paris title filter'); + $this->assertPageCounts('test-title-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris title filter'); // Test the body Paris filter page, which filters for body contains // 'Paris'. Should show each translation once. - $this->assertPageCounts('test-body-paris', array('es' => 1, 'fr' => 1, 'en' => 1), 'Paris body filter'); + $this->assertPageCounts('test-body-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris body filter'); } /** diff --git a/core/modules/node/src/Tests/Views/NodeFieldTokensTest.php b/core/modules/node/tests/src/Functional/Views/NodeFieldTokensTest.php similarity index 94% rename from core/modules/node/src/Tests/Views/NodeFieldTokensTest.php rename to core/modules/node/tests/src/Functional/Views/NodeFieldTokensTest.php index 9c124467..fc547ed3 100644 --- a/core/modules/node/src/Tests/Views/NodeFieldTokensTest.php +++ b/core/modules/node/tests/src/Functional/Views/NodeFieldTokensTest.php @@ -1,6 +1,7 @@ drupalCreateContentType(['name' => '' . $this->randomMachineName() . '']); $types[] = $type; for ($j = 0; $j < 5; $j++) { // Ensure the right order of the nodes. - $node = $this->drupalCreateNode(array('type' => $type->id(), 'created' => REQUEST_TIME - ($i * 5 + $j))); + $node = $this->drupalCreateNode(['type' => $type->id(), 'created' => REQUEST_TIME - ($i * 5 + $j)]); $nodes[$type->id()][$node->id()] = $node; $all_nids[] = $node->id(); } @@ -55,11 +55,11 @@ public function testNodeViewTypeArgument() { * @param array $expected_nids * An array of node IDs. */ - protected function assertNids(array $expected_nids = array()) { + protected function assertNids(array $expected_nids = []) { $result = $this->xpath('//span[@class="field-content"]'); - $nids = array(); + $nids = []; foreach ($result as $element) { - $nids[] = (int) $element; + $nids[] = (int) $element->getText(); } $this->assertEqual($nids, $expected_nids); } diff --git a/core/modules/node/src/Tests/Views/NodeLanguageTest.php b/core/modules/node/tests/src/Functional/Views/NodeLanguageTest.php similarity index 87% rename from core/modules/node/src/Tests/Views/NodeLanguageTest.php rename to core/modules/node/tests/src/Functional/Views/NodeLanguageTest.php index 4561508e..d2d1b479 100644 --- a/core/modules/node/src/Tests/Views/NodeLanguageTest.php +++ b/core/modules/node/tests/src/Functional/Views/NodeLanguageTest.php @@ -1,6 +1,6 @@ profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - ViewTestData::createTestViews(get_class($this), array('node_test_views')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + ViewTestData::createTestViews(get_class($this), ['node_test_views']); } // Add two new languages. @@ -60,30 +60,30 @@ protected function setUp() { // Set up node titles. They should not include the words "French", // "English", or "Spanish", as there is a language field in the view // that prints out those words. - $this->nodeTitles = array( - LanguageInterface::LANGCODE_NOT_SPECIFIED => array( + $this->nodeTitles = [ + LanguageInterface::LANGCODE_NOT_SPECIFIED => [ 'First node und', - ), - 'es' => array( + ], + 'es' => [ 'Primero nodo es', 'Segundo nodo es', 'Tercera nodo es', - ), - 'en' => array( + ], + 'en' => [ 'First node en', 'Second node en', - ), - 'fr' => array( + ], + 'fr' => [ 'Premier nÅ“ud fr', - ) - ); + ] + ]; // Create nodes with translations. foreach ($this->nodeTitles['es'] as $index => $title) { - $node = $this->drupalCreateNode(array('title' => $title, 'langcode' => 'es', 'type' => 'page', 'promote' => 1)); - foreach (array('en', 'fr') as $langcode) { + $node = $this->drupalCreateNode(['title' => $title, 'langcode' => 'es', 'type' => 'page', 'promote' => 1]); + foreach (['en', 'fr'] as $langcode) { if (isset($this->nodeTitles[$langcode][$index])) { - $translation = $node->addTranslation($langcode, array('title' => $this->nodeTitles[$langcode][$index])); + $translation = $node->addTranslation($langcode, ['title' => $this->nodeTitles[$langcode][$index]]); $translation->body->value = $this->randomMachineName(32); } } @@ -91,14 +91,14 @@ protected function setUp() { } // Create non-translatable nodes. foreach ($this->nodeTitles[LanguageInterface::LANGCODE_NOT_SPECIFIED] as $index => $title) { - $node = $this->drupalCreateNode(array('title' => $title, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'type' => 'page', 'promote' => 1)); + $node = $this->drupalCreateNode(['title' => $title, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'type' => 'page', 'promote' => 1]); $node->body->value = $this->randomMachineName(32); $node->save(); } $this->container->get('router.builder')->rebuild(); - $user = $this->drupalCreateUser(array('access content overview', 'access content')); + $user = $this->drupalCreateUser(['access content overview', 'access content']); $this->drupalLogin($user); } @@ -178,7 +178,7 @@ public function testLanguages() { } // When filtered, only the specific languages should show. foreach ($this->nodeTitles as $langcode => $titles) { - $this->drupalGet('admin/content', array('query' => array('langcode' => $langcode))); + $this->drupalGet('admin/content', ['query' => ['langcode' => $langcode]]); foreach ($titles as $title) { $this->assertText($title); } @@ -195,7 +195,7 @@ public function testLanguages() { // filter is set to the site default language instead. This should just // show the English nodes, no matter what the content language is. $config = $this->config('views.view.frontpage'); - $config->set('display.default.display_options.filters.langcode.value', array(PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT => PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT)); + $config->set('display.default.display_options.filters.langcode.value', [PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT => PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT]); $config->save(); foreach ($this->nodeTitles as $langcode => $titles) { if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) { @@ -219,10 +219,10 @@ public function testLanguages() { // // IMPORTANT: Make sure this part of the test is last -- it is changing // language configuration! - $config->set('display.default.display_options.filters.langcode.value', array('***LANGUAGE_language_interface***' => '***LANGUAGE_language_interface***')); + $config->set('display.default.display_options.filters.langcode.value', ['***LANGUAGE_language_interface***' => '***LANGUAGE_language_interface***']); $config->save(); $language_config = $this->config('language.types'); - $language_config->set('negotiation.language_interface.enabled', array('language-selected' => 1)); + $language_config->set('negotiation.language_interface.enabled', ['language-selected' => 1]); $language_config->save(); $language_config = $this->config('language.negotiation'); $language_config->set('selected_langcode', 'es'); diff --git a/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php b/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php new file mode 100644 index 00000000..db70b2c9 --- /dev/null +++ b/core/modules/node/tests/src/Functional/Views/NodeRevisionWizardTest.php @@ -0,0 +1,61 @@ +drupalCreateContentType(['type' => 'article']); + // Create two nodes with two revision. + $node_storage = \Drupal::entityManager()->getStorage('node'); + /** @var \Drupal\node\NodeInterface $node */ + $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'article', 'created' => REQUEST_TIME + 40]); + $node->save(); + + $node = $node->createDuplicate(); + $node->setNewRevision(); + $node->created->value = REQUEST_TIME + 20; + $node->save(); + + $node = $node_storage->create(['title' => $this->randomString(), 'type' => 'article', 'created' => REQUEST_TIME + 30]); + $node->save(); + + $node = $node->createDuplicate(); + $node->setNewRevision(); + $node->created->value = REQUEST_TIME + 10; + $node->save(); + + $view = []; + $view['label'] = $this->randomMachineName(16); + $view['id'] = strtolower($this->randomMachineName(16)); + $view['description'] = $this->randomMachineName(16); + $view['page[create]'] = FALSE; + $view['show[wizard_key]'] = 'node_revision'; + $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); + + $view_storage_controller = \Drupal::entityManager()->getStorage('view'); + /** @var \Drupal\views\Entity\View $view */ + $view = $view_storage_controller->load($view['id']); + + $this->assertEqual($view->get('base_table'), 'node_field_revision'); + + $executable = Views::executableFactory()->get($view); + $this->executeView($executable); + + $this->assertIdenticalResultset($executable, [['vid' => 1], ['vid' => 3], ['vid' => 2], ['vid' => 4]], + ['vid' => 'vid']); + } + +} diff --git a/core/modules/node/tests/src/Functional/Views/NodeTestBase.php b/core/modules/node/tests/src/Functional/Views/NodeTestBase.php new file mode 100644 index 00000000..b98778c5 --- /dev/null +++ b/core/modules/node/tests/src/Functional/Views/NodeTestBase.php @@ -0,0 +1,29 @@ +drupalCreateContentType(array('type' => 'article')); + $this->drupalCreateContentType(['type' => 'article']); // Create two nodes. for ($i = 0; $i < 2; $i++) { $this->nodes[] = $this->drupalCreateNode( - array( + [ 'type' => 'article', - 'body' => array( - array( + 'body' => [ + [ 'value' => $this->randomMachineName(42), 'format' => filter_default_format(), 'summary' => $this->randomMachineName(), - ), - ), - ) + ], + ], + ] ); } } diff --git a/core/modules/node/src/Tests/Views/RevisionLinkTest.php b/core/modules/node/tests/src/Functional/Views/RevisionLinkTest.php similarity index 98% rename from core/modules/node/src/Tests/Views/RevisionLinkTest.php rename to core/modules/node/tests/src/Functional/Views/RevisionLinkTest.php index 0a508dc9..6dc20d64 100644 --- a/core/modules/node/src/Tests/Views/RevisionLinkTest.php +++ b/core/modules/node/tests/src/Functional/Views/RevisionLinkTest.php @@ -1,6 +1,6 @@ drupalCreateContentType(array('type' => 'article')); + $this->drupalCreateContentType(['type' => 'article']); // Create two nodes. for ($i = 0; $i < 2; $i++) { $this->nodes[] = $this->drupalCreateNode( - array( + [ 'type' => 'article', - 'body' => array( - array( + 'body' => [ + [ 'value' => $this->randomMachineName(42), 'format' => filter_default_format(), 'summary' => $this->randomMachineName(), - ), - ), - ) + ], + ], + ] ); } } diff --git a/core/modules/node/tests/src/Functional/Views/StatusExtraTest.php b/core/modules/node/tests/src/Functional/Views/StatusExtraTest.php new file mode 100644 index 00000000..7961088c --- /dev/null +++ b/core/modules/node/tests/src/Functional/Views/StatusExtraTest.php @@ -0,0 +1,76 @@ +drupalCreateUser(['view own unpublished content']); + $node_author_not_unpublished = $this->drupalCreateUser(); + $normal_user = $this->drupalCreateUser(); + $admin_user = $this->drupalCreateUser(['bypass node access']); + + // Create one published and one unpublished node by the admin. + $node_published = $this->drupalCreateNode(['uid' => $admin_user->id()]); + $node_unpublished = $this->drupalCreateNode(['uid' => $admin_user->id(), 'status' => NodeInterface::NOT_PUBLISHED]); + + // Create one unpublished node by a certain author user. + $node_unpublished2 = $this->drupalCreateNode(['uid' => $node_author->id(), 'status' => NodeInterface::NOT_PUBLISHED]); + + // Create one unpublished node by a user who does not have the `view own + // unpublished content` permission. + $node_unpublished3 = $this->drupalCreateNode(['uid' => $node_author_not_unpublished->id(), 'status' => NodeInterface::NOT_PUBLISHED]); + + // The administrator should simply see all nodes. + $this->drupalLogin($admin_user); + $this->drupalGet('test_status_extra'); + $this->assertText($node_published->label()); + $this->assertText($node_unpublished->label()); + $this->assertText($node_unpublished2->label()); + $this->assertText($node_unpublished3->label()); + + // The node author should see the published node and his own node. + $this->drupalLogin($node_author); + $this->drupalGet('test_status_extra'); + $this->assertText($node_published->label()); + $this->assertNoText($node_unpublished->label()); + $this->assertText($node_unpublished2->label()); + $this->assertNoText($node_unpublished3->label()); + + // The normal user should just see the published node. + $this->drupalLogin($normal_user); + $this->drupalGet('test_status_extra'); + $this->assertText($node_published->label()); + $this->assertNoText($node_unpublished->label()); + $this->assertNoText($node_unpublished2->label()); + $this->assertNoText($node_unpublished3->label()); + + // The author without the permission to see his own unpublished node should + // just see the published node. + $this->drupalLogin($node_author_not_unpublished); + $this->drupalGet('test_status_extra'); + $this->assertText($node_published->label()); + $this->assertNoText($node_unpublished->label()); + $this->assertNoText($node_unpublished2->label()); + $this->assertNoText($node_unpublished3->label()); + } + +} diff --git a/core/modules/node/tests/src/FunctionalJavascript/TestSettingSummariesContentType.php b/core/modules/node/tests/src/FunctionalJavascript/TestSettingSummariesContentType.php new file mode 100644 index 00000000..4760ee65 --- /dev/null +++ b/core/modules/node/tests/src/FunctionalJavascript/TestSettingSummariesContentType.php @@ -0,0 +1,49 @@ +drupalCreateUser(['administer content types']); + $this->drupalLogin($admin_user); + $this->drupalCreateContentType(['type' => 'test']); + } + + /** + * Test a vertical tab 'Workflow' summary. + */ + public function testWorkflowSummary() { + $this->drupalGet('admin/structure/types/manage/test'); + $page = $this->getSession()->getPage(); + $page->findField('options[status]')->uncheck(); + $page->findField('options[sticky]')->check(); + $page->findField('options[promote]')->check(); + $page->findField('options[revision]')->check(); + $locator = '[href="#edit-workflow"] .vertical-tabs__menu-item-summary'; + $page->waitFor(10, function () use ($page, $locator) { + $summary = $page->find('css', $locator)->getText(); + return strpos('Not published', $summary) !== FALSE; + }); + $summary = $page->find('css', $locator)->getText(); + $this->assertEquals('Not published, Promoted to front page, Sticky at top of lists, Create new revision', $summary); + } + +} diff --git a/core/modules/node/tests/src/Kernel/Config/NodeImportChangeTest.php b/core/modules/node/tests/src/Kernel/Config/NodeImportChangeTest.php index edb9ae08..e1b17f2c 100644 --- a/core/modules/node/tests/src/Kernel/Config/NodeImportChangeTest.php +++ b/core/modules/node/tests/src/Kernel/Config/NodeImportChangeTest.php @@ -26,7 +26,7 @@ protected function setUp() { parent::setUp(); // Set default storage backend. - $this->installConfig(array('field', 'node_test_config')); + $this->installConfig(['field', 'node_test_config']); } /** diff --git a/core/modules/node/tests/src/Kernel/Config/NodeImportCreateTest.php b/core/modules/node/tests/src/Kernel/Config/NodeImportCreateTest.php index f4fd1e19..cb985173 100644 --- a/core/modules/node/tests/src/Kernel/Config/NodeImportCreateTest.php +++ b/core/modules/node/tests/src/Kernel/Config/NodeImportCreateTest.php @@ -18,7 +18,7 @@ class NodeImportCreateTest extends KernelTestBase { * * @var array */ - public static $modules = array('node', 'field', 'text', 'system', 'user'); + public static $modules = ['node', 'field', 'text', 'system', 'user']; /** * Set the default field storage backend for fields created during tests. @@ -28,7 +28,7 @@ protected function setUp() { $this->installEntitySchema('user'); // Set default storage backend. - $this->installConfig(array('field')); + $this->installConfig(['field']); } /** @@ -42,7 +42,7 @@ public function testImportCreateDefault() { // Enable node_test_config module and check that the content type // shipped in the module's default config is created. - $this->container->get('module_installer')->install(array('node_test_config')); + $this->container->get('module_installer')->install(['node_test_config']); $node_type = NodeType::load($node_type_id); $this->assertTrue($node_type, 'The default content type was created.'); } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeBundleSettingsTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeBundleSettingsTest.php index 1f526b88..9f28c065 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeBundleSettingsTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeBundleSettingsTest.php @@ -13,6 +13,11 @@ */ class MigrateNodeBundleSettingsTest extends MigrateDrupal6TestBase { + /** + * {@inheritdoc} + */ + public static $modules = ['menu_ui']; + /** * {@inheritdoc} */ diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeConfigsTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeConfigsTest.php index 660b3585..8743284d 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeConfigsTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\node\Kernel\Migrate\d6; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingPromoteTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingPromoteTest.php index a434cc72..e7eb008a 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingPromoteTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingPromoteTest.php @@ -10,7 +10,7 @@ */ class MigrateNodeSettingPromoteTest extends MigrateDrupal6TestBase { - public static $modules = ['node', 'text']; + public static $modules = ['node', 'text', 'menu_ui']; /** * {@inheritdoc} diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStatusTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStatusTest.php index 5c4ed679..afd2dc6e 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStatusTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStatusTest.php @@ -10,7 +10,7 @@ */ class MigrateNodeSettingStatusTest extends MigrateDrupal6TestBase { - public static $modules = ['node', 'text']; + public static $modules = ['node', 'text', 'menu_ui']; /** * {@inheritdoc} diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStickyTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStickyTest.php index 1b100b13..58eeca33 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStickyTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeSettingStickyTest.php @@ -10,7 +10,7 @@ */ class MigrateNodeSettingStickyTest extends MigrateDrupal6TestBase { - public static $modules = ['node', 'text']; + public static $modules = ['node', 'text', 'menu_ui']; /** * {@inheritdoc} diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php index 7a0a272a..ce4ce76e 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php @@ -19,7 +19,7 @@ class MigrateNodeTest extends MigrateNodeTestBase { /** * {@inheritdoc} */ - public static $modules = ['language', 'content_translation']; + public static $modules = ['language', 'content_translation', 'menu_ui']; /** * {@inheritdoc} @@ -57,6 +57,8 @@ public function testNode() { $node_revision = \Drupal::entityManager()->getStorage('node')->loadRevision(1); $this->assertIdentical('Test title', $node_revision->getTitle()); $this->assertIdentical('1', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user'); + $this->assertSame('1', $node_revision->id(), 'Node 1 loaded.'); + $this->assertSame('1', $node_revision->getRevisionId(), 'Node 1 revision 1 loaded.'); // This is empty on the first revision. $this->assertIdentical(NULL, $node_revision->revision_log->value); $this->assertIdentical('This is a shared text field', $node->field_test->value); @@ -70,6 +72,11 @@ public function testNode() { $this->assertIdentical('1', $node->field_test_identical2->value, 'Integer value is correct'); $this->assertIdentical('This is a field with exclude unset.', $node->field_test_exclude_unset->value, 'Field with exclude unset is correct.'); + // Test that date fields are migrated. + $this->assertSame('2013-01-02T04:05:00', $node->field_test_date->value, 'Date field is correct'); + $this->assertSame('1391357160', $node->field_test_datestamp->value, 'Datestamp field is correct'); + $this->assertSame('2015-03-04T06:07:00', $node->field_test_datetime->value, 'Datetime field is correct'); + // Test that link fields are migrated. $this->assertIdentical('https://www.drupal.org/project/drupal', $node->field_test_link->uri); $this->assertIdentical('Drupal project page', $node->field_test_link->title); @@ -77,7 +84,20 @@ public function testNode() { // Test the file field meta. $this->assertIdentical('desc', $node->field_test_filefield->description); - $this->assertIdentical('5', $node->field_test_filefield->target_id); + $this->assertIdentical('4', $node->field_test_filefield->target_id); + + // Test that an email field is migrated. + $this->assertSame('PrincessRuwenne@example.com', $node->field_test_email->value); + + // Test that node reference field values were migrated. + $node = Node::load(18); + $this->assertCount(2, $node->field_company); + $this->assertSame('Klingon Empire', $node->field_company[0]->entity->label()); + $this->assertSame('Romulan Empire', $node->field_company[1]->entity->label()); + + // Test that user reference field values were migrated. + $this->assertCount(1, $node->field_commander); + $this->assertSame('joe.roe', $node->field_commander[0]->entity->getUsername()); $node = Node::load(2); $this->assertIdentical('Test title rev 3', $node->getTitle()); @@ -89,6 +109,20 @@ public function testNode() { $this->assertIdentical('Drupal Groups', $node->field_test_link->title); $this->assertIdentical([], $node->field_test_link->options['attributes']); + $node = Node::load(3); + // Test multivalue field. + $value_1 = $node->field_multivalue->value; + $value_2 = $node->field_multivalue[1]->value; + + // SQLite does not support scales for float data types so we need to convert + // the value manually. + if ($this->container->get('database')->driver() == 'sqlite') { + $value_1 = sprintf('%01.2f', $value_1); + $value_2 = sprintf('%01.2f', $value_2); + } + $this->assertSame('33.00', $value_1); + $this->assertSame('44.00', $value_2); + // Test that a link field with an internal link is migrated. $node = Node::load(9); $this->assertSame('internal:/node/10', $node->field_test_link->uri); @@ -156,11 +190,11 @@ public function testNode() { $this->assertIdentical('full_html', $node->body->format); // Now insert a row indicating a failure and set to update later. - $title = $this->rerunMigration(array( + $title = $this->rerunMigration([ 'sourceid1' => 2, 'destid1' => NULL, 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, - )); + ]); $node = Node::load(2); $this->assertIdentical($title, $node->getTitle()); } @@ -178,10 +212,10 @@ protected function rerunMigration($new_row = []) { $title = $this->randomString(); $source_connection = Database::getConnection('default', 'migrate'); $source_connection->update('node_revisions') - ->fields(array( + ->fields([ 'title' => $title, 'format' => 2, - )) + ]) ->condition('vid', 3) ->execute(); $migration = $this->getMigration('d6_node:story'); diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTypeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTypeTest.php index b9845625..9a3e81e1 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTypeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTypeTest.php @@ -13,6 +13,11 @@ */ class MigrateNodeTypeTest extends MigrateDrupal6TestBase { + /** + * {@inheritdoc} + */ + public static $modules = ['menu_ui']; + /** * {@inheritdoc} */ @@ -33,12 +38,18 @@ public function testNodeType() { $this->assertIdentical(TRUE, $node_type_page->displaySubmitted()); $this->assertIdentical(FALSE, $node_type_page->isNewRevision()); $this->assertIdentical(DRUPAL_OPTIONAL, $node_type_page->getPreviewMode()); - $this->assertIdentical($id_map->lookupDestinationID(array('test_page')), array('test_page')); + $this->assertIdentical($id_map->lookupDestinationID(['test_page']), ['test_page']); // Test we have a body field. $field = FieldConfig::loadByName('node', 'test_page', 'body'); $this->assertIdentical('This is the body field label', $field->getLabel(), 'Body field was found.'); + // Test default menus. + $expected_available_menus = ['navigation']; + $this->assertSame($expected_available_menus, $node_type_page->getThirdPartySetting('menu_ui', 'available_menus')); + $expected_parent = 'navigation:'; + $this->assertSame($expected_parent, $node_type_page->getThirdPartySetting('menu_ui', 'parent')); + // Test the test_story content type. $node_type_story = NodeType::load('test_story'); $this->assertIdentical('test_story', $node_type_story->id(), 'Node type test_story loaded'); @@ -46,12 +57,18 @@ public function testNodeType() { $this->assertIdentical(TRUE, $node_type_story->displaySubmitted()); $this->assertIdentical(FALSE, $node_type_story->isNewRevision()); $this->assertIdentical(DRUPAL_OPTIONAL, $node_type_story->getPreviewMode()); - $this->assertIdentical($id_map->lookupDestinationID(array('test_story')), array('test_story')); + $this->assertIdentical($id_map->lookupDestinationID(['test_story']), ['test_story']); // Test we don't have a body field. $field = FieldConfig::loadByName('node', 'test_story', 'body'); $this->assertIdentical(NULL, $field, 'No body field found'); + // Test default menus. + $expected_available_menus = ['navigation']; + $this->assertSame($expected_available_menus, $node_type_story->getThirdPartySetting('menu_ui', 'available_menus')); + $expected_parent = 'navigation:'; + $this->assertSame($expected_parent, $node_type_story->getThirdPartySetting('menu_ui', 'parent')); + // Test the test_event content type. $node_type_event = NodeType::load('test_event'); $this->assertIdentical('test_event', $node_type_event->id(), 'Node type test_event loaded'); @@ -59,11 +76,16 @@ public function testNodeType() { $this->assertIdentical(TRUE, $node_type_event->displaySubmitted()); $this->assertIdentical(TRUE, $node_type_event->isNewRevision()); $this->assertIdentical(DRUPAL_OPTIONAL, $node_type_event->getPreviewMode()); - $this->assertIdentical($id_map->lookupDestinationID(array('test_event')), array('test_event')); + $this->assertIdentical($id_map->lookupDestinationID(['test_event']), ['test_event']); // Test we have a body field. $field = FieldConfig::loadByName('node', 'test_event', 'body'); $this->assertIdentical('Body', $field->getLabel(), 'Body field was found.'); + + $expected_available_menus = ['navigation']; + $this->assertSame($expected_available_menus, $node_type_event->getThirdPartySetting('menu_ui', 'available_menus')); + $expected_parent = 'navigation:'; + $this->assertSame($expected_parent, $node_type_event->getThirdPartySetting('menu_ui', 'parent')); } } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateViewModesTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateViewModesTest.php index 5e8eb0a6..f4755927 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateViewModesTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateViewModesTest.php @@ -29,7 +29,7 @@ public function testViewModes() { $this->assertIdentical(FALSE, is_null($view_mode), 'Preview view mode loaded.'); $this->assertIdentical('Preview', $view_mode->label(), 'View mode has correct label.'); // Test the ID map. - $this->assertIdentical(array('node', 'preview'), $this->getMigration('d6_view_modes')->getIdMap()->lookupDestinationID(array(1))); + $this->assertIdentical(['node', 'preview'], $this->getMigration('d6_view_modes')->getIdMap()->lookupDestinationID([1])); } } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/NodeTranslationRedirectTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/NodeTranslationRedirectTest.php new file mode 100644 index 00000000..7daac883 --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/NodeTranslationRedirectTest.php @@ -0,0 +1,59 @@ +installEntitySchema('node'); + $this->installConfig(['node']); + $this->installSchema('node', ['node_access']); + $this->installSchema('system', ['key_value']); + $this->migrateUsers(FALSE); + $this->migrateFields(); + + $this->executeMigrations([ + 'language', + 'd6_language_types', + 'd6_language_negotiation_settings', + 'd6_node_settings', + 'd6_node', + 'd6_node_translation', + ]); + } + + /** + * Tests that not found node translations are redirected. + */ + public function testNodeTranslationRedirect() { + $kernel = $this->container->get('http_kernel'); + $request = Request::create('/node/11'); + $response = $kernel->handle($request); + $this->assertSame(301, $response->getStatusCode()); + $this->assertSame('/node/10', $response->getTargetUrl()); + } + +} diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeDeriverTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeDeriverTest.php new file mode 100644 index 00000000..2b7169a6 --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeDeriverTest.php @@ -0,0 +1,61 @@ +pluginManager = $this->container->get('plugin.manager.migration'); + $this->moduleHandler = $this->container->get('module_handler'); + } + + /** + * Test node translation migrations with translation disabled. + */ + public function testNoTranslations() { + // Enabling node module for this test. + $this->enableModules(['node']); + // Without content_translation, there should be no translation migrations. + $migrations = $this->pluginManager->createInstances('d7_node_translation'); + $this->assertTrue($this->moduleHandler->moduleExists('node')); + $this->assertEmpty($migrations); + } + + /** + * Test node translation migrations with translation enabled. + */ + public function testTranslations() { + // With content_translation, there should be translation migrations for + // each content type. + $this->enableModules(['language', 'content_translation', 'node', 'filter']); + $migrations = $this->pluginManager->createInstances('d7_node_translation'); + $this->assertArrayHasKey('d7_node_translation:article', $migrations, + "Node translation migrations exist after content_translation installed"); + } + +} diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeSettingsTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeSettingsTest.php index d2924f8a..dcae81b8 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeSettingsTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeSettingsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\node\Kernel\Migrate\d7; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; /** diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php index f7b98bd7..dc053a8b 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTest.php @@ -2,6 +2,8 @@ namespace Drupal\Tests\node\Kernel\Migrate\d7; +use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Tests\file\Kernel\Migrate\d7\FileMigrationSetupTrait; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; @@ -13,17 +15,27 @@ */ class MigrateNodeTest extends MigrateDrupal7TestBase { - public static $modules = array( + use FileMigrationSetupTrait; + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'content_translation', 'comment', 'datetime', + 'file', 'filter', + 'forum', 'image', + 'language', 'link', + 'menu_ui', 'node', 'taxonomy', 'telephone', 'text', - ); + ]; /** * {@inheritdoc} @@ -31,24 +43,31 @@ class MigrateNodeTest extends MigrateDrupal7TestBase { protected function setUp() { parent::setUp(); + $this->fileMigrationSetup(); + $this->installEntitySchema('node'); $this->installEntitySchema('comment'); $this->installEntitySchema('taxonomy_term'); - $this->installEntitySchema('file'); $this->installConfig(static::$modules); + $this->installSchema('comment', ['comment_entity_statistics']); + $this->installSchema('forum', ['forum', 'forum_index']); $this->installSchema('node', ['node_access']); $this->installSchema('system', ['sequences']); $this->executeMigrations([ + 'language', 'd7_user_role', 'd7_user', 'd7_node_type', + 'd7_language_content_settings', 'd7_comment_type', + 'd7_comment_field', + 'd7_comment_field_instance', 'd7_taxonomy_vocabulary', 'd7_field', 'd7_field_instance', 'd7_node', - 'd7_node:article', + 'd7_node_translation', ]); } @@ -79,18 +98,18 @@ protected function setUp() { protected function assertEntity($id, $type, $langcode, $title, $uid, $status, $created, $changed, $promoted, $sticky) { /** @var \Drupal\node\NodeInterface $node */ $node = Node::load($id); - $this->assertTrue($node instanceof NodeInterface); - $this->assertIdentical($type, $node->getType()); - $this->assertIdentical($langcode, $node->langcode->value); - $this->assertIdentical($title, $node->getTitle()); - $this->assertIdentical($uid, $node->getOwnerId()); - $this->assertIdentical($status, $node->isPublished()); - $this->assertIdentical($created, $node->getCreatedTime()); + $this->assertInstanceOf(NodeInterface::class, $node); + $this->assertEquals($type, $node->getType()); + $this->assertEquals($langcode, $node->langcode->value); + $this->assertEquals($title, $node->getTitle()); + $this->assertEquals($uid, $node->getOwnerId()); + $this->assertEquals($status, $node->isPublished()); + $this->assertEquals($created, $node->getCreatedTime()); if (isset($changed)) { - $this->assertIdentical($changed, $node->getChangedTime()); + $this->assertEquals($changed, $node->getChangedTime()); } - $this->assertIdentical($promoted, $node->isPromoted()); - $this->assertIdentical($sticky, $node->isSticky()); + $this->assertEquals($promoted, $node->isPromoted()); + $this->assertEquals($sticky, $node->isSticky()); } /** @@ -109,11 +128,11 @@ protected function assertEntity($id, $type, $langcode, $title, $uid, $status, $c */ protected function assertRevision($id, $title, $uid, $log, $timestamp) { $revision = \Drupal::entityManager()->getStorage('node')->loadRevision($id); - $this->assertTrue($revision instanceof NodeInterface); - $this->assertIdentical($title, $revision->getTitle()); - $this->assertIdentical($uid, $revision->getRevisionUser()->id()); - $this->assertIdentical($log, $revision->revision_log->value); - $this->assertIdentical($timestamp, $revision->getRevisionCreationTime()); + $this->assertInstanceOf(NodeInterface::class, $revision); + $this->assertEquals($title, $revision->getTitle()); + $this->assertEquals($uid, $revision->getRevisionUser()->id()); + $this->assertEquals($log, $revision->revision_log->value); + $this->assertEquals($timestamp, $revision->getRevisionCreationTime()); } /** @@ -125,28 +144,64 @@ public function testNode() { $node = Node::load(1); $this->assertTrue($node->field_boolean->value); - $this->assertIdentical('99-99-99-99', $node->field_phone->value); - // Use assertEqual() here instead, since SQLite interprets floats strictly. - $this->assertEqual('1', $node->field_float->value); - $this->assertIdentical('5', $node->field_integer->value); - $this->assertIdentical('Some more text', $node->field_text_list[0]->value); - $this->assertIdentical('7', $node->field_integer_list[0]->value); - $this->assertIdentical('qwerty', $node->field_text->value); - $this->assertIdentical('2', $node->field_file->target_id); - $this->assertIdentical('file desc', $node->field_file->description); + $this->assertEquals('99-99-99-99', $node->field_phone->value); + $this->assertEquals('1', $node->field_float->value); + $this->assertEquals('5', $node->field_integer->value); + $this->assertEquals('Some more text', $node->field_text_list[0]->value); + $this->assertEquals('7', $node->field_integer_list[0]->value); + $this->assertEquals('qwerty', $node->field_text->value); + $this->assertEquals('2', $node->field_file->target_id); + $this->assertEquals('file desc', $node->field_file->description); $this->assertTrue($node->field_file->display); - $this->assertIdentical('1', $node->field_images->target_id); - $this->assertIdentical('alt text', $node->field_images->alt); - $this->assertIdentical('title text', $node->field_images->title); - $this->assertIdentical('93', $node->field_images->width); - $this->assertIdentical('93', $node->field_images->height); - $this->assertIdentical('http://google.com', $node->field_link->uri); - $this->assertIdentical('Click Here', $node->field_link->title); + $this->assertEquals('1', $node->field_images->target_id); + $this->assertEquals('alt text', $node->field_images->alt); + $this->assertEquals('title text', $node->field_images->title); + $this->assertEquals('93', $node->field_images->width); + $this->assertEquals('93', $node->field_images->height); + $this->assertEquals('http://google.com', $node->field_link->uri); + $this->assertEquals('Click Here', $node->field_link->title); + // Test that an email field is migrated. + $this->assertEquals('default@example.com', $node->field_email->value); + $this->assertEquals('another@example.com', $node->field_email[1]->value); + $this->assertEquals(CommentItemInterface::OPEN, $node->comment_node_test_content_type->status); $node = Node::load(2); - $this->assertIdentical("...is that it's the absolute best show ever. Trust me, I would know.", $node->body->value); - $this->assertIdentical('internal:/', $node->field_link->uri); - $this->assertIdentical('Home', $node->field_link->title); + $this->assertEquals('en', $node->langcode->value); + $this->assertEquals("...is that it's the absolute best show ever. Trust me, I would know.", $node->body->value); + $this->assertEquals('The thing about Deep Space 9', $node->label()); + $this->assertEquals('internal:/', $node->field_link->uri); + $this->assertEquals('Home', $node->field_link->title); + $this->assertEquals(CommentItemInterface::OPEN, $node->comment_node_article->status); + $this->assertTrue($node->hasTranslation('is'), "Node 2 has an Icelandic translation"); + + $translation = $node->getTranslation('is'); + $this->assertEquals('is', $translation->langcode->value); + $this->assertEquals("is - ...is that it's the absolute best show ever. Trust me, I would know.", $translation->body->value); + $this->assertEquals('is - The thing about Deep Space 9', $translation->label()); + $this->assertEquals('internal:/', $translation->field_link->uri); + $this->assertEquals(CommentItemInterface::OPEN, $translation->comment_node_article->status); + $this->assertEquals('Home', $translation->field_link->title); + + // Test that content_translation_source is set. + $manager = $this->container->get('content_translation.manager'); + $this->assertEquals('en', $manager->getTranslationMetadata($node->getTranslation('is'))->getSource()); + + // Node 3 is a translation of node 2, and should not be imported separately. + $this->assertNull(Node::load(3), "Node 3 doesn't exist in D8, it was a translation"); + + // Test that content_translation_source for a source other than English. + $node = Node::load(4); + $this->assertEquals('is', $manager->getTranslationMetadata($node->getTranslation('en'))->getSource()); + $this->assertEquals(CommentItemInterface::CLOSED, $node->comment_node_article->status); + + $translation = $node->getTranslation('en'); + $this->assertEquals(CommentItemInterface::CLOSED, $translation->comment_node_article->status); + + $node = Node::load(6); + $this->assertEquals(CommentItemInterface::CLOSED, $node->comment_forum->status); + + $node = Node::load(7); + $this->assertEquals(CommentItemInterface::OPEN, $node->comment_forum->status); } } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTitleLabelTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTitleLabelTest.php index f0fc493d..06556315 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTitleLabelTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTitleLabelTest.php @@ -12,7 +12,7 @@ */ class MigrateNodeTitleLabelTest extends MigrateDrupal7TestBase { - public static $modules = ['node', 'text']; + public static $modules = ['node', 'text', 'menu_ui']; /** * {@inheritdoc} diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTypeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTypeTest.php index 8b98ec30..b16cd255 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTypeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/MigrateNodeTypeTest.php @@ -20,14 +20,14 @@ class MigrateNodeTypeTest extends MigrateDrupal7TestBase { * * @var array */ - public static $modules = array('node', 'text', 'filter'); + public static $modules = ['node', 'text', 'filter', 'menu_ui']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('node')); + $this->installConfig(['node']); $this->executeMigration('d7_node_type'); } @@ -45,12 +45,13 @@ protected function setUp() { * @param string $help * The expected help text. */ - protected function assertEntity($id, $label, $description, $help, $display_submitted, $new_revision, $body_label = NULL) { + protected function assertEntity($id, $label, $description, $help, $display_submitted, $new_revision, $expected_available_menus, $expected_parent, $body_label = NULL) { /** @var \Drupal\node\NodeTypeInterface $entity */ $entity = NodeType::load($id); $this->assertTrue($entity instanceof NodeTypeInterface); $this->assertIdentical($label, $entity->label()); $this->assertIdentical($description, $entity->getDescription()); + $this->assertIdentical($help, $entity->getHelp()); $this->assertIdentical($display_submitted, $entity->displaySubmitted(), 'Submission info is displayed'); @@ -62,20 +63,32 @@ protected function assertEntity($id, $label, $description, $help, $display_submi $this->assertTrue($body instanceof FieldConfigInterface); $this->assertIdentical($body_label, $body->label()); } + + $this->assertSame($expected_available_menus, $entity->getThirdPartySetting('menu_ui', 'available_menus')); + $this->assertSame($expected_parent, $entity->getThirdPartySetting('menu_ui', 'parent')); } /** * Tests Drupal 7 node type to Drupal 8 migration. */ public function testNodeType() { - $this->assertEntity('article', 'Article', 'Use articles for time-sensitive content like news, press releases or blog posts.', 'Help text for articles', TRUE, FALSE, "Body"); - $this->assertEntity('blog', 'Blog entry', 'Use for multi-user blogs. Every user gets a personal blog.', 'Blog away, good sir!', TRUE, FALSE, 'Body'); + $expected_available_menus = ['main-menu']; + $expected_parent = 'main-menu:0:'; + + $this->assertEntity('article', 'Article', 'Use articles for time-sensitive content like news, press releases or blog posts.', 'Help text for articles', TRUE, FALSE, $expected_available_menus, $expected_parent, "Body"); + $this->assertEntity('blog', 'Blog entry', 'Use for multi-user blogs. Every user gets a personal blog.', 'Blog away, good sir!', TRUE, FALSE, $expected_available_menus, $expected_parent, 'Body'); // book's display_submitted flag is not set, so it will default to TRUE. - $this->assertEntity('book', 'Book page', 'Books have a built-in hierarchical navigation. Use for handbooks or tutorials.', '', TRUE, TRUE, "Body"); - $this->assertEntity('forum', 'Forum topic', 'A forum topic starts a new discussion thread within a forum.', 'No name-calling, no flame wars. Be nice.', TRUE, FALSE, 'Body'); - $this->assertEntity('page', 'Basic page', "Use basic pages for your static content, such as an 'About us' page.", 'Help text for basic pages', FALSE, FALSE, "Body"); + $this->assertEntity('book', 'Book page', 'Books have a built-in hierarchical navigation. Use for handbooks or tutorials.', '', TRUE, TRUE, $expected_available_menus, $expected_parent, "Body"); + $this->assertEntity('forum', 'Forum topic', 'A forum topic starts a new discussion thread within a forum.', 'No name-calling, no flame wars. Be nice.', TRUE, FALSE, $expected_available_menus, $expected_parent, 'Body'); + $this->assertEntity('page', 'Basic page', "Use basic pages for your static content, such as an 'About us' page.", 'Help text for basic pages', FALSE, FALSE, $expected_available_menus, $expected_parent, "Body"); // This node type does not carry a body field. - $this->assertEntity('test_content_type', 'Test content type', 'This is the description of the test content type.', 'Help text for test content type', FALSE, TRUE); + $expected_available_menus = [ + 'main-menu', + 'management', + 'navigation', + 'user-menu', + ]; + $this->assertEntity('test_content_type', 'Test content type', 'This is the description of the test content type.', 'Help text for test content type', FALSE, TRUE, $expected_available_menus, $expected_parent); } } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d7/NodeTranslationRedirectTest.php b/core/modules/node/tests/src/Kernel/Migrate/d7/NodeTranslationRedirectTest.php new file mode 100644 index 00000000..88cc2ade --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Migrate/d7/NodeTranslationRedirectTest.php @@ -0,0 +1,61 @@ +installEntitySchema('node'); + $this->installConfig('node'); + $this->installSchema('node', ['node_access']); + $this->installSchema('system', ['key_value']); + + $this->executeMigrations([ + 'language', + 'd7_language_types', + 'd7_language_negotiation_settings', + 'd7_user_role', + 'd7_user', + 'd7_node_type', + 'd7_node', + 'd7_node_translation', + ]); + } + + /** + * Tests that not found node translations are redirected. + */ + public function testNodeTranslationRedirect() { + $kernel = $this->container->get('http_kernel'); + $request = Request::create('/node/3'); + $response = $kernel->handle($request); + $this->assertSame(301, $response->getStatusCode()); + $this->assertSame('/node/2', $response->getTargetUrl()); + } + +} diff --git a/core/modules/node/tests/src/Kernel/NodeAccessTest.php b/core/modules/node/tests/src/Kernel/NodeAccessTest.php index b8e2251e..539edcb0 100644 --- a/core/modules/node/tests/src/Kernel/NodeAccessTest.php +++ b/core/modules/node/tests/src/Kernel/NodeAccessTest.php @@ -73,11 +73,11 @@ protected function setUp() { $this->drupalCreateUser(); // Create a node type. - $this->drupalCreateContentType(array( + $this->drupalCreateContentType([ 'type' => 'page', 'name' => 'Basic page', 'display_submitted' => FALSE, - )); + ]); } /** diff --git a/core/modules/node/tests/src/Kernel/NodeBodyFieldStorageTest.php b/core/modules/node/tests/src/Kernel/NodeBodyFieldStorageTest.php index 6c1faf37..3dd13496 100644 --- a/core/modules/node/tests/src/Kernel/NodeBodyFieldStorageTest.php +++ b/core/modules/node/tests/src/Kernel/NodeBodyFieldStorageTest.php @@ -28,7 +28,7 @@ protected function setUp() { $this->installSchema('user', 'users_data'); $this->installEntitySchema('user'); $this->installEntitySchema('node'); - $this->installConfig(array('field', 'node')); + $this->installConfig(['field', 'node']); } /** @@ -46,7 +46,7 @@ public function testFieldOverrides() { $field->delete(); $field_storage = FieldStorageConfig::loadByName('node', 'body'); $this->assertTrue(count($field_storage->getBundles()) == 0, 'Node body field storage exists after deleting the only instance of a field.'); - \Drupal::service('module_installer')->uninstall(array('node')); + \Drupal::service('module_installer')->uninstall(['node']); $field_storage = FieldStorageConfig::loadByName('node', 'body'); $this->assertFalse($field_storage, 'Node body field storage does not exist after uninstalling the Node module.'); } diff --git a/core/modules/node/tests/src/Kernel/NodeConditionTest.php b/core/modules/node/tests/src/Kernel/NodeConditionTest.php index 7636d529..a30867cb 100644 --- a/core/modules/node/tests/src/Kernel/NodeConditionTest.php +++ b/core/modules/node/tests/src/Kernel/NodeConditionTest.php @@ -13,7 +13,7 @@ */ class NodeConditionTest extends EntityKernelTestBase { - public static $modules = array('node'); + public static $modules = ['node']; protected function setUp() { parent::setUp(); @@ -30,7 +30,7 @@ protected function setUp() { /** * Tests conditions. */ - function testConditions() { + public function testConditions() { $manager = $this->container->get('plugin.manager.condition', $this->container->get('container.namespaces')); $this->createUser(); @@ -45,20 +45,20 @@ function testConditions() { // Grab the node type condition and configure it to check against node type // of 'article' and set the context to the page type node. $condition = $manager->createInstance('node_type') - ->setConfig('bundles', array('article' => 'article')) + ->setConfig('bundles', ['article' => 'article']) ->setContextValue('node', $page); $this->assertFalse($condition->execute(), 'Page type nodes fail node type checks for articles.'); // Check for the proper summary. $this->assertEqual('The node bundle is article', $condition->summary()); // Set the node type check to page. - $condition->setConfig('bundles', array('page' => 'page')); + $condition->setConfig('bundles', ['page' => 'page']); $this->assertTrue($condition->execute(), 'Page type nodes pass node type checks for pages'); // Check for the proper summary. $this->assertEqual('The node bundle is page', $condition->summary()); // Set the node type check to page or article. - $condition->setConfig('bundles', array('page' => 'page', 'article' => 'article')); + $condition->setConfig('bundles', ['page' => 'page', 'article' => 'article']); $this->assertTrue($condition->execute(), 'Page type nodes pass node type checks for pages or articles'); // Check for the proper summary. $this->assertEqual('The node bundle is page or article', $condition->summary()); @@ -72,11 +72,11 @@ function testConditions() { $this->assertFalse($condition->execute(), 'Test type nodes pass node type checks for pages or articles'); // Check a greater than 2 bundles summary scenario. - $condition->setConfig('bundles', array('page' => 'page', 'article' => 'article', 'test' => 'test')); + $condition->setConfig('bundles', ['page' => 'page', 'article' => 'article', 'test' => 'test']); $this->assertEqual('The node bundle is page, article or test', $condition->summary()); // Test Constructor injection. - $condition = $manager->createInstance('node_type', array('bundles' => array('article' => 'article'), 'context' => array('node' => $article))); + $condition = $manager->createInstance('node_type', ['bundles' => ['article' => 'article'], 'context' => ['node' => $article]]); $this->assertTrue($condition->execute(), 'Constructor injection of context and configuration working as anticipated.'); } diff --git a/core/modules/node/tests/src/Kernel/NodeFieldAccessTest.php b/core/modules/node/tests/src/Kernel/NodeFieldAccessTest.php index f88e45e4..ae66dca0 100644 --- a/core/modules/node/tests/src/Kernel/NodeFieldAccessTest.php +++ b/core/modules/node/tests/src/Kernel/NodeFieldAccessTest.php @@ -19,32 +19,32 @@ class NodeFieldAccessTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('node'); + public static $modules = ['node']; /** * Fields that only users with administer nodes permissions can change. * * @var array */ - protected $administrativeFields = array( + protected $administrativeFields = [ 'status', 'promote', 'sticky', 'created', 'uid', - ); + ]; /** * These fields are automatically managed and can not be changed by any user. * * @var array */ - protected $readOnlyFields = array('changed', 'revision_uid', 'revision_timestamp'); + protected $readOnlyFields = ['changed', 'revision_uid', 'revision_timestamp']; /** * Test permissions on nodes status field. */ - function testAccessToAdministrativeFields() { + public function testAccessToAdministrativeFields() { // Create the page node type with revisions disabled. $page = NodeType::create([ @@ -62,74 +62,74 @@ function testAccessToAdministrativeFields() { // An administrator user. No user exists yet, ensure that the first user // does not have UID 1. - $content_admin_user = $this->createUser(array('uid' => 2), array('administer nodes')); + $content_admin_user = $this->createUser(['uid' => 2], ['administer nodes']); // Two different editor users. - $page_creator_user = $this->createUser(array(), array('create page content', 'edit own page content', 'delete own page content')); - $page_manager_user = $this->createUser(array(), array('create page content', 'edit any page content', 'delete any page content')); + $page_creator_user = $this->createUser([], ['create page content', 'edit own page content', 'delete own page content']); + $page_manager_user = $this->createUser([], ['create page content', 'edit any page content', 'delete any page content']); // An unprivileged user. - $page_unrelated_user = $this->createUser(array(), array('access content')); + $page_unrelated_user = $this->createUser([], ['access content']); // List of all users - $test_users = array( + $test_users = [ $content_admin_user, $page_creator_user, $page_manager_user, $page_unrelated_user, - ); + ]; // Create three "Basic pages". One is owned by our test-user // "page_creator", one by "page_manager", and one by someone else. - $node1 = Node::create(array( + $node1 = Node::create([ 'title' => $this->randomMachineName(8), 'uid' => $page_creator_user->id(), 'type' => 'page', - )); - $node2 = Node::create(array( + ]); + $node2 = Node::create([ 'title' => $this->randomMachineName(8), 'uid' => $page_manager_user->id(), 'type' => 'article', - )); - $node3 = Node::create(array( + ]); + $node3 = Node::create([ 'title' => $this->randomMachineName(8), 'type' => 'page', - )); + ]); foreach ($this->administrativeFields as $field) { // Checks on view operations. foreach ($test_users as $account) { $may_view = $node1->{$field}->access('view', $account); - $this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', array('@name' => $field))); + $this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', ['@name' => $field])); } // Checks on edit operations. $may_update = $node1->{$field}->access('edit', $page_creator_user); - $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', array('@name' => $field))); + $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', ['@name' => $field])); $may_update = $node2->{$field}->access('edit', $page_creator_user); - $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', array('@name' => $field))); + $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit own page content" is not allowed to the field @name.', ['@name' => $field])); $may_update = $node2->{$field}->access('edit', $page_manager_user); - $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', array('@name' => $field))); + $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', ['@name' => $field])); $may_update = $node1->{$field}->access('edit', $page_manager_user); - $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', array('@name' => $field))); + $this->assertFalse($may_update, SafeMarkup::format('Users with permission "edit any page content" is not allowed to the field @name.', ['@name' => $field])); $may_update = $node2->{$field}->access('edit', $page_unrelated_user); - $this->assertFalse($may_update, SafeMarkup::format('Users not having permission "edit any page content" is not allowed to the field @name.', array('@name' => $field))); + $this->assertFalse($may_update, SafeMarkup::format('Users not having permission "edit any page content" is not allowed to the field @name.', ['@name' => $field])); $may_update = $node1->{$field}->access('edit', $content_admin_user) && $node3->status->access('edit', $content_admin_user); - $this->assertTrue($may_update, SafeMarkup::format('Users with permission "administer nodes" may edit @name fields on all nodes.', array('@name' => $field))); + $this->assertTrue($may_update, SafeMarkup::format('Users with permission "administer nodes" may edit @name fields on all nodes.', ['@name' => $field])); } foreach ($this->readOnlyFields as $field) { // Check view operation. foreach ($test_users as $account) { $may_view = $node1->{$field}->access('view', $account); - $this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', array('@name' => $field))); + $this->assertTrue($may_view, SafeMarkup::format('Any user may view the field @name.', ['@name' => $field])); } // Check edit operation. foreach ($test_users as $account) { $may_view = $node1->{$field}->access('edit', $account); - $this->assertFalse($may_view, SafeMarkup::format('No user is not allowed to edit the field @name.', array('@name' => $field))); + $this->assertFalse($may_view, SafeMarkup::format('No user is not allowed to edit the field @name.', ['@name' => $field])); } } diff --git a/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php b/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php index aee02728..7c7bc033 100644 --- a/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php +++ b/core/modules/node/tests/src/Kernel/NodeFieldOverridesTest.php @@ -27,14 +27,14 @@ class NodeFieldOverridesTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('user', 'system', 'field', 'node'); + public static $modules = ['user', 'system', 'field', 'node']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('user')); + $this->installConfig(['user']); $this->user = $this->createUser(); \Drupal::service('current_user')->setAccount($this->user); } diff --git a/core/modules/node/tests/src/Kernel/NodeOwnerTest.php b/core/modules/node/tests/src/Kernel/NodeOwnerTest.php index d21d5ad0..c12f3115 100644 --- a/core/modules/node/tests/src/Kernel/NodeOwnerTest.php +++ b/core/modules/node/tests/src/Kernel/NodeOwnerTest.php @@ -19,16 +19,16 @@ class NodeOwnerTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('node', 'language'); + public static $modules = ['node', 'language']; protected function setUp() { parent::setUp(); // Create the node bundles required for testing. - $type = NodeType::create(array( + $type = NodeType::create([ 'type' => 'page', 'name' => 'page', - )); + ]); $type->save(); // Enable two additional languages. @@ -48,11 +48,11 @@ public function testOwner() { $container->get('current_user')->setAccount($user); // Create a test node. - $english = Node::create(array( + $english = Node::create([ 'type' => 'page', 'title' => $this->randomMachineName(), 'language' => 'en', - )); + ]); $english->save(); $this->assertEqual($user->id(), $english->getOwnerId()); diff --git a/core/modules/node/tests/src/Kernel/NodeTokenReplaceTest.php b/core/modules/node/tests/src/Kernel/NodeTokenReplaceTest.php index c496c83b..dd39b6d2 100644 --- a/core/modules/node/tests/src/Kernel/NodeTokenReplaceTest.php +++ b/core/modules/node/tests/src/Kernel/NodeTokenReplaceTest.php @@ -22,14 +22,14 @@ class NodeTokenReplaceTest extends TokenReplaceKernelTestBase { * * @var array */ - public static $modules = array('node', 'filter'); + public static $modules = ['node', 'filter']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('filter', 'node')); + $this->installConfig(['filter', 'node']); $node_type = NodeType::create(['type' => 'article', 'name' => 'Article']); $node_type->save(); @@ -39,11 +39,11 @@ protected function setUp() { /** * Creates a node, then tests the tokens generated from it. */ - function testNodeTokenReplacement() { - $url_options = array( + public function testNodeTokenReplacement() { + $url_options = [ 'absolute' => TRUE, 'language' => $this->interfaceLanguage, - ); + ]; // Create a user and a node. $account = $this->createUser(); @@ -58,7 +58,7 @@ function testNodeTokenReplacement() { $node->save(); // Generate and test tokens. - $tests = array(); + $tests = []; $tests['[node:nid]'] = $node->id(); $tests['[node:vid]'] = $node->getRevisionId(); $tests['[node:type]'] = 'article'; @@ -72,8 +72,8 @@ function testNodeTokenReplacement() { $tests['[node:author]'] = $account->getUsername(); $tests['[node:author:uid]'] = $node->getOwnerId(); $tests['[node:author:name]'] = $account->getUsername(); - $tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId())); - $tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId())); + $tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), ['langcode' => $this->interfaceLanguage->getId()]); + $tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), ['langcode' => $this->interfaceLanguage->getId()]); $base_bubbleable_metadata = BubbleableMetadata::createFromObject($node); @@ -101,7 +101,7 @@ function testNodeTokenReplacement() { foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); - $output = $this->tokenService->replace($input, array('node' => $node), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata); + $output = $this->tokenService->replace($input, ['node' => $node], ['langcode' => $this->interfaceLanguage->getId()], $bubbleable_metadata); $this->assertEqual($output, $expected, format_string('Node token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } @@ -116,14 +116,14 @@ function testNodeTokenReplacement() { $node->save(); // Generate and test token - use full body as expected value. - $tests = array(); + $tests = []; $tests['[node:summary]'] = $node->body->processed; // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.'); foreach ($tests as $input => $expected) { - $output = $this->tokenService->replace($input, array('node' => $node), array('language' => $this->interfaceLanguage)); + $output = $this->tokenService->replace($input, ['node' => $node], ['language' => $this->interfaceLanguage]); $this->assertEqual($output, $expected, new FormattableMarkup('Node token %token replaced for node without a summary.', ['%token' => $input])); } } diff --git a/core/modules/node/tests/src/Kernel/NodeValidationTest.php b/core/modules/node/tests/src/Kernel/NodeValidationTest.php index 9fd646e6..e111faea 100644 --- a/core/modules/node/tests/src/Kernel/NodeValidationTest.php +++ b/core/modules/node/tests/src/Kernel/NodeValidationTest.php @@ -18,7 +18,7 @@ class NodeValidationTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('node'); + public static $modules = ['node']; /** * Set the default field storage backend for fields created during tests. diff --git a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d6/NodeTypeTest.php b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d6/NodeTypeTest.php index 38af680a..9d59f43f 100644 --- a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d6/NodeTypeTest.php +++ b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d6/NodeTypeTest.php @@ -57,9 +57,139 @@ public function providerSource() { 'orig_type' => 'story', ], ]; + $tests[0]['source_data']['variable'] = [ + [ + 'name' => 'comment_anonymous_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_anonymous_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'comment_default_mode_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_default_mode_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'comment_default_per_page_page', + 'value' => 's:2:"10";', + ], + [ + 'name' => 'comment_default_per_page_story', + 'value' => 's:2:"20";', + ], + [ + 'name' => 'comment_form_location_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_form_location_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'comment_page', + 'value' => 's:1:"0";', + ], + [ + 'name' => 'comment_preview_page', + 'value' => 's:1:"0";', + ], + [ + 'name' => 'comment_preview_story', + 'value' => 's:1:"1";', + ], + [ + 'name' => 'comment_story', + 'value' => 's:1:"1";', + ], + [ + 'name' => 'comment_subject_field_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_subject_field_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'node_options_page', + 'value' => 'a:1:{i:0;s:6:"status";}', + ], + [ + 'name' => 'node_options_story', + 'value' => 'a:1:{i:0;s:6:"status";}', + ], + ]; + $tests[0]['source_data']['system'] = [ + [ + 'type' => 'module', + 'name' => 'comment', + 'status' => '1', + ], + ]; // The expected results. - $tests[0]['expected_data'] = $tests[0]['source_data']['node_type']; + $tests[0]['expected_data'] = [ + [ + 'type' => 'page', + 'name' => 'Page', + 'module' => 'node', + 'description' => 'A page, similar in form to a story, is a simple method for creating and displaying information that rarely changes, such as an "About us" section of a website. By default, a page entry does not allow visitor comments and is not featured on the site\'s initial home page.', + 'help' => '', + 'title_label' => 'Title', + 'has_body' => 1, + 'body_label' => 'Body', + 'min_word_count' => 0, + 'custom' => 1, + 'modified' => 0, + 'locked' => 0, + 'orig_type' => 'page', + 'options' => [ + 'promote' => FALSE, + 'sticky' => FALSE, + 'status' => TRUE, + 'revision' => FALSE, + ], + 'comment' => 0, + 'comment_default_mode' => 0, + 'comment_default_per_page' => '10', + 'comment_anonymous' => 0, + 'comment_subject_field' => 0, + 'comment_preview' => 0, + 'comment_form_location' => 0, + ], + [ + 'type' => 'story', + 'name' => 'Story', + 'module' => 'node', + 'description' => 'A story, similar in form to a page, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a story entry. By default, a story entry is automatically featured on the site\'s initial home page, and provides the ability to post comments.', + 'help' => '', + 'title_label' => 'Title', + 'has_body' => 1, + 'body_label' => 'Body', + 'min_word_count' => 0, + 'custom' => 1, + 'modified' => 0, + 'locked' => 0, + 'orig_type' => 'story', + 'options' => [ + 'promote' => FALSE, + 'sticky' => FALSE, + 'status' => TRUE, + 'revision' => FALSE, + ], + 'comment' => 1, + 'comment_default_mode' => 1, + 'comment_default_per_page' => '20', + 'comment_anonymous' => 1, + 'comment_subject_field' => 1, + 'comment_preview' => 1, + 'comment_form_location' => 1, + ], + ]; return $tests; } diff --git a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTest.php b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTest.php index 6b19b958..da4f57ef 100644 --- a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTest.php +++ b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTest.php @@ -27,7 +27,6 @@ public function providerSource() { // The source data. $tests[0]['source_data']['node'] = [ [ - // Node fields. 'nid' => 1, 'vid' => 1, 'type' => 'page', @@ -44,7 +43,6 @@ public function providerSource() { 'translate' => 0, ], [ - // Node fields. 'nid' => 2, 'vid' => 2, 'type' => 'page', @@ -61,7 +59,6 @@ public function providerSource() { 'translate' => 0, ], [ - // Node fields. 'nid' => 5, 'vid' => 5, 'type' => 'article', @@ -77,11 +74,41 @@ public function providerSource() { 'tnid' => 0, 'translate' => 0, ], - + [ + 'nid' => 6, + 'vid' => 6, + 'type' => 'article', + 'language' => 'en', + 'title' => 'node title 5', + 'uid' => 1, + 'status' => 1, + 'created' => 1279291908, + 'changed' => 1279309993, + 'comment' => 0, + 'promote' => 1, + 'sticky' => 0, + 'tnid' => 6, + 'translate' => 0, + ], + [ + 'nid' => 7, + 'vid' => 7, + 'type' => 'article', + 'language' => 'fr', + 'title' => 'fr - node title 5', + 'uid' => 1, + 'status' => 1, + 'created' => 1279292908, + 'changed' => 1279310993, + 'comment' => 0, + 'promote' => 1, + 'sticky' => 0, + 'tnid' => 6, + 'translate' => 0, + ], ]; $tests[0]['source_data']['node_revision'] = [ [ - // Node fields. 'nid' => 1, 'vid' => 1, 'uid' => 2, @@ -94,7 +121,6 @@ public function providerSource() { 'sticky' => 0, ], [ - // Node fields. 'nid' => 2, 'vid' => 2, 'uid' => 2, @@ -107,7 +133,6 @@ public function providerSource() { 'sticky' => 0, ], [ - // Node fields. 'nid' => 5, 'vid' => 5, 'uid' => 2, @@ -119,6 +144,31 @@ public function providerSource() { 'promote' => 1, 'sticky' => 0, ], + [ + 'nid' => 6, + 'vid' => 6, + 'uid' => 1, + 'title' => 'node title 5', + 'log' => '', + 'timestamp' => 1279309993, + 'status' => 1, + 'comment' => 0, + 'promote' => 1, + 'sticky' => 0, + + ], + [ + 'nid' => 7, + 'vid' => 7, + 'uid' => 1, + 'title' => 'fr - node title 5', + 'log' => '', + 'timestamp' => 1279310993, + 'status' => 1, + 'comment' => 0, + 'promote' => 1, + 'sticky' => 0, + ], ]; $tests[0]['source_data']['field_config_instance'] = [ [ @@ -131,7 +181,7 @@ public function providerSource() { 'deleted' => '0', ], [ - 'id' => '2', + 'id' => '3', 'field_id' => '2', 'field_name' => 'body', 'entity_type' => 'node', @@ -153,12 +203,59 @@ public function providerSource() { 'body_summary' => '', 'body_format' => 'filtered_html', ], + [ + 'entity_type' => 'node', + 'bundle' => 'page', + 'deleted' => '0', + 'entity_id' => '2', + 'revision_id' => '2', + 'language' => 'en', + 'delta' => '0', + 'body_value' => 'body 2', + 'body_summary' => '', + 'body_format' => 'filtered_html', + ], + [ + 'entity_type' => 'node', + 'bundle' => 'page', + 'deleted' => '0', + 'entity_id' => '5', + 'revision_id' => '5', + 'language' => 'en', + 'delta' => '0', + 'body_value' => 'body 5', + 'body_summary' => '', + 'body_format' => 'filtered_html', + ], + [ + 'entity_type' => 'node', + 'bundle' => 'page', + 'deleted' => '0', + 'entity_id' => '6', + 'revision_id' => '6', + 'language' => 'en', + 'delta' => '0', + 'body_value' => 'body 6', + 'body_summary' => '', + 'body_format' => 'filtered_html', + ], + [ + 'entity_type' => 'node', + 'bundle' => 'page', + 'deleted' => '0', + 'entity_id' => '7', + 'revision_id' => '7', + 'language' => 'fr', + 'delta' => '0', + 'body_value' => 'fr - body 6', + 'body_summary' => '', + 'body_format' => 'filtered_html', + ], ]; // The expected results. $tests[0]['expected_data'] = [ [ - // Node fields. 'nid' => 1, 'vid' => 1, 'type' => 'page', @@ -172,7 +269,7 @@ public function providerSource() { 'comment' => 2, 'promote' => 1, 'sticky' => 0, - 'tnid' => 0, + 'tnid' => 1, 'translate' => 0, 'log' => '', 'timestamp' => 1279051598, @@ -185,7 +282,6 @@ public function providerSource() { ], ], [ - // Node fields. 'nid' => 2, 'vid' => 2, 'type' => 'page', @@ -199,13 +295,19 @@ public function providerSource() { 'comment' => 0, 'promote' => 1, 'sticky' => 0, - 'tnid' => 0, + 'tnid' => 2, 'translate' => 0, 'log' => '', 'timestamp' => 1279308993, + 'body' => [ + [ + 'value' => 'body 2', + 'summary' => '', + 'format' => 'filtered_html', + ], + ], ], [ - // Node fields. 'nid' => 5, 'vid' => 5, 'type' => 'article', @@ -219,10 +321,43 @@ public function providerSource() { 'comment' => 0, 'promote' => 1, 'sticky' => 0, - 'tnid' => 0, + 'tnid' => 5, 'translate' => 0, 'log' => '', 'timestamp' => 1279308993, + 'body' => [ + [ + 'value' => 'body 5', + 'summary' => '', + 'format' => 'filtered_html', + ], + ], + ], + [ + 'nid' => 6, + 'vid' => 6, + 'type' => 'article', + 'language' => 'en', + 'title' => 'node title 5', + 'node_uid' => 1, + 'revision_uid' => 1, + 'status' => 1, + 'created' => 1279291908, + 'changed' => 1279309993, + 'comment' => 0, + 'promote' => 1, + 'sticky' => 0, + 'tnid' => 6, + 'translate' => 0, + 'log' => '', + 'timestamp' => 1279309993, + 'body' => [ + [ + 'value' => 'body 6', + 'summary' => '', + 'format' => 'filtered_html', + ], + ], ], ]; diff --git a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTranslationTest.php b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTranslationTest.php new file mode 100644 index 00000000..e46bd35a --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTranslationTest.php @@ -0,0 +1,69 @@ + 7, + 'vid' => 7, + 'type' => 'article', + 'language' => 'fr', + 'title' => 'fr - node title 5', + 'node_uid' => 1, + 'revision_uid' => 1, + 'status' => 1, + 'created' => 1279292908, + 'changed' => 1279310993, + 'comment' => 0, + 'promote' => 1, + 'sticky' => 0, + 'tnid' => 6, + 'translate' => 0, + // Node revision fields. + 'log' => '', + 'timestamp' => 1279310993, + 'body' => [ + [ + 'value' => 'fr - body 6', + 'summary' => '', + 'format' => 'filtered_html', + ], + ], + ], + ]; + + // Do an automatic count. + $tests[0]['expected_count'] = NULL; + + // Set up source plugin configuration. + $tests[0]['configuration'] = [ + 'translations' => TRUE, + ]; + + return $tests; + } + +} diff --git a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTypeTest.php b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTypeTest.php index 1c738d1a..5e876b7d 100644 --- a/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTypeTest.php +++ b/core/modules/node/tests/src/Kernel/Plugin/migrate/source/d7/NodeTypeTest.php @@ -54,6 +54,62 @@ public function providerSource() { ], ]; $tests[0]['source_data']['variable'] = [ + [ + 'name' => 'comment_anonymous_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_anonymous_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'comment_default_mode_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_default_mode_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'comment_default_per_page_page', + 'value' => 's:2:"10";', + ], + [ + 'name' => 'comment_default_per_page_story', + 'value' => 's:2:"20";', + ], + [ + 'name' => 'comment_form_location_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_form_location_story', + 'value' => 'i:1;', + ], + [ + 'name' => 'comment_page', + 'value' => 's:1:"0";', + ], + [ + 'name' => 'comment_preview_page', + 'value' => 's:1:"0";', + ], + [ + 'name' => 'comment_preview_story', + 'value' => 's:1:"1";', + ], + [ + 'name' => 'comment_story', + 'value' => 's:1:"1";', + ], + [ + 'name' => 'comment_subject_field_page', + 'value' => 'i:0;', + ], + [ + 'name' => 'comment_subject_field_story', + 'value' => 'i:1;', + ], [ 'name' => 'node_options_page', 'value' => 'a:1:{i:0;s:6:"status";}', @@ -77,9 +133,78 @@ public function providerSource() { 'data' => 'a:1:{s:5:"label";s:4:"Body";}', ], ]; + $tests[0]['source_data']['system'] = [ + [ + 'type' => 'module', + 'name' => 'comment', + 'status' => '1', + ], + [ + 'type' => 'module', + 'name' => 'field', + 'status' => '1', + ], + ]; // The expected results. - $tests[0]['expected_data'] = $tests[0]['source_data']['node_type']; + $tests[0]['expected_data'] = [ + [ + 'type' => 'page', + 'name' => 'Page', + 'base' => 'node', + 'description' => 'A page, similar in form to a story, is a simple method for creating and displaying information that rarely changes, such as an "About us" section of a website. By default, a page entry does not allow visitor comments and is not featured on the site\'s initial home page.', + 'help' => '', + 'title_label' => 'Title', + 'custom' => 1, + 'modified' => 0, + 'locked' => 0, + 'disabled' => 0, + 'orig_type' => 'page', + 'options' => [ + 'promote' => FALSE, + 'sticky' => FALSE, + 'status' => TRUE, + 'revision' => FALSE, + ], + 'create_body' => TRUE, + 'body_label' => 'Body', + 'comment' => 0, + 'comment_default_mode' => 0, + 'comment_default_per_page' => '10', + 'comment_anonymous' => 0, + 'comment_subject_field' => 0, + 'comment_preview' => 0, + 'comment_form_location' => 0, + ], + [ + 'type' => 'story', + 'name' => 'Story', + 'base' => 'node', + 'description' => 'A story, similar in form to a page, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a story entry. By default, a story entry is automatically featured on the site\'s initial home page, and provides the ability to post comments.', + 'help' => '', + 'title_label' => 'Title', + 'custom' => 1, + 'modified' => 0, + 'locked' => 0, + 'disabled' => 0, + 'orig_type' => 'story', + 'options' => [ + 'promote' => FALSE, + 'sticky' => FALSE, + 'status' => TRUE, + 'revision' => FALSE, + ], + 'create_body' => TRUE, + 'body_label' => 'Body', + 'comment' => 1, + 'comment_default_mode' => 1, + 'comment_default_per_page' => '20', + 'comment_anonymous' => 1, + 'comment_subject_field' => 1, + 'comment_preview' => 1, + 'comment_form_location' => 1, + ], + ]; return $tests; } diff --git a/core/modules/node/tests/src/Kernel/SummaryLengthTest.php b/core/modules/node/tests/src/Kernel/SummaryLengthTest.php new file mode 100644 index 00000000..fa15c0e6 --- /dev/null +++ b/core/modules/node/tests/src/Kernel/SummaryLengthTest.php @@ -0,0 +1,121 @@ +installSchema('system', 'sequences'); + $this->installSchema('node', 'node_access'); + $this->installEntitySchema('user'); + $this->installEntitySchema('node'); + $this->installEntitySchema('date_format'); + $this->installConfig('filter'); + $this->installConfig('node'); + + // Create a node type. + $this->drupalCreateContentType([ + 'type' => 'page', + 'name' => 'Basic page', + 'display_submitted' => FALSE, + ]); + + DateFormat::create([ + 'id' => 'fallback', + 'label' => 'Fallback', + 'pattern' => 'Y-m-d', + ])->save(); + + // Enable multibyte support. + Unicode::setStatus(Unicode::STATUS_MULTIBYTE); + } + + /** + * Tests the node summary length functionality. + */ + public function testSummaryLength() { + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = $this->container->get('renderer'); + + // Create a node to view. + $settings = [ + 'body' => [['value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae arcu at leo cursus laoreet. Curabitur dui tortor, adipiscing malesuada tempor in, bibendum ac diam. Cras non tellus a libero pellentesque condimentum. What is a Drupalism? Suspendisse ac lacus libero. Ut non est vel nisl faucibus interdum nec sed leo. Pellentesque sem risus, vulputate eu semper eget, auctor in libero. Ut fermentum est vitae metus convallis scelerisque. Phasellus pellentesque rhoncus tellus, eu dignissim purus posuere id. Quisque eu fringilla ligula. Morbi ullamcorper, lorem et mattis egestas, tortor neque pretium velit, eget eleifend odio turpis eu purus. Donec vitae metus quis leo pretium tincidunt a pulvinar sem. Morbi adipiscing laoreet mauris vel placerat. Nullam elementum, nisl sit amet scelerisque malesuada, dolor nunc hendrerit quam, eu ultrices erat est in orci. Curabitur feugiat egestas nisl sed accumsan.']], + 'promote' => 1, + ]; + $node = $this->drupalCreateNode($settings); + $this->assertTrue(Node::load($node->id()), 'Node created.'); + + // Render the node as a teaser. + $content = $this->drupalBuildEntityView($node, 'teaser'); + $this->assertTrue(strlen($content['body'][0]['#markup']) < 600, 'Teaser is less than 600 characters long.'); + $this->setRawContent($renderer->renderRoot($content)); + // The string 'What is a Drupalism?' is between the 200th and 600th + // characters of the node body, so it should be included if the summary is + // 600 characters long. + $expected = 'What is a Drupalism?'; + $this->assertRaw($expected); + + // Change the teaser length for "Basic page" content type. + $display = entity_get_display('node', $node->getType(), 'teaser'); + $display_options = $display->getComponent('body'); + $display_options['settings']['trim_length'] = 200; + $display->setComponent('body', $display_options) + ->save(); + + // Render the node as a teaser again and check that the summary is now only + // 200 characters in length and so does not include 'What is a Drupalism?'. + $content = $this->drupalBuildEntityView($node, 'teaser'); + $this->assertTrue(strlen($content['body'][0]['#markup']) < 200, 'Teaser is less than 200 characters long.'); + $this->setRawContent($renderer->renderRoot($content)); + $this->assertText($node->label()); + $this->assertNoRaw($expected); + } + +} diff --git a/core/modules/node/tests/src/Kernel/Views/ArgumentUidRevisionTest.php b/core/modules/node/tests/src/Kernel/Views/ArgumentUidRevisionTest.php new file mode 100644 index 00000000..b216f40f --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Views/ArgumentUidRevisionTest.php @@ -0,0 +1,93 @@ +installEntitySchema('node'); + $this->installSchema('node', ['node_access']); + $this->installEntitySchema('user'); + $this->installConfig(['node', 'field']); + + ViewTestData::createTestViews(get_class($this), ['node_test_views']); + } + + /** + * Tests the node_uid_revision argument. + */ + public function testArgument() { + $expected_result = []; + + $author = $this->createUser(); + $no_author = $this->createUser(); + + // Create one node, with the author as the node author. + $node1 = Node::create([ + 'type' => 'default', + 'title' => $this->randomMachineName(), + ]); + $node1->setOwner($author); + $node1->save(); + $expected_result[] = ['nid' => $node1->id()]; + + // Create one node of which an additional revision author will be the + // author. + $node2 = Node::create([ + 'type' => 'default', + 'title' => $this->randomMachineName(), + ]); + $node2->setRevisionAuthorId($no_author->id()); + $node2->save(); + $expected_result[] = ['nid' => $node2->id()]; + + // Force to add a new revision. + $node2->setNewRevision(TRUE); + $node2->setRevisionAuthorId($author->id()); + $node2->save(); + + // Create one node on which the author has neither authorship of revisions + // or the main node. + $node3 = Node::create([ + 'type' => 'default', + 'title' => $this->randomMachineName(), + ]); + $node3->setOwner($no_author); + $node3->save(); + + $view = Views::getView('test_argument_node_uid_revision'); + $view->initHandlers(); + $view->setArguments(['uid_revision' => $author->id()]); + + $this->executeView($view); + $this->assertIdenticalResultset($view, $expected_result, ['nid' => 'nid']); + } + +} diff --git a/core/modules/node/tests/src/Kernel/Views/RevisionRelationshipsTest.php b/core/modules/node/tests/src/Kernel/Views/RevisionRelationshipsTest.php new file mode 100644 index 00000000..e47bdd03 --- /dev/null +++ b/core/modules/node/tests/src/Kernel/Views/RevisionRelationshipsTest.php @@ -0,0 +1,94 @@ +installSchema('node', 'node_access'); + + $this->installEntitySchema('user'); + $this->installEntitySchema('node'); + + ViewTestData::createTestViews(get_class($this), ['node_test_views']); + } + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = ['test_node_revision_nid', 'test_node_revision_vid']; + + /** + * Create a node with revision and rest result count for both views. + */ + public function testNodeRevisionRelationship() { + $type = NodeType::create(['type' => 'page', 'name' => 'page']); + $type->save(); + $node = Node::create(['type' => 'page', 'title' => 'test', 'uid' => 1]); + $node->save(); + // Create revision of the node. + $node->setNewRevision(TRUE); + $node->save(); + $column_map = [ + 'vid' => 'vid', + 'node_field_data_node_field_revision_nid' => 'node_node_revision_nid', + 'nid_1' => 'nid_1', + ]; + + // Here should be two rows. + $view_nid = Views::getView('test_node_revision_nid'); + $this->executeView($view_nid, [$node->id()]); + $resultset_nid = [ + [ + 'vid' => '1', + 'node_node_revision_nid' => '1', + 'nid_1' => '1', + ], + [ + 'vid' => '2', + 'node_revision_nid' => '1', + 'node_node_revision_nid' => '1', + 'nid_1' => '1', + ], + ]; + $this->assertIdenticalResultset($view_nid, $resultset_nid, $column_map); + + // There should be only one row with active revision 2. + $view_vid = Views::getView('test_node_revision_vid'); + $this->executeView($view_vid, [$node->id()]); + $resultset_vid = [ + [ + 'vid' => '2', + 'node_node_revision_nid' => '1', + 'nid_1' => '1', + ], + ]; + $this->assertIdenticalResultset($view_vid, $resultset_vid, $column_map); + } + +} diff --git a/core/modules/node/tests/src/Traits/ContentTypeCreationTrait.php b/core/modules/node/tests/src/Traits/ContentTypeCreationTrait.php new file mode 100644 index 00000000..e633dad3 --- /dev/null +++ b/core/modules/node/tests/src/Traits/ContentTypeCreationTrait.php @@ -0,0 +1,54 @@ + 'foo'. + * + * @return \Drupal\node\Entity\NodeType + * Created content type. + */ + protected function createContentType(array $values = []) { + // Find a non-existent random type name. + if (!isset($values['type'])) { + do { + $id = strtolower($this->randomMachineName(8)); + } while (NodeType::load($id)); + } + else { + $id = $values['type']; + } + $values += [ + 'type' => $id, + 'name' => $id, + ]; + $type = NodeType::create($values); + $status = $type->save(); + node_add_body_field($type); + + if ($this instanceof TestCase) { + $this->assertSame($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', ['%type' => $type->id()]))->__toString()); + } + else { + $this->assertEqual($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', ['%type' => $type->id()]))->__toString()); + } + + return $type; + } + +} diff --git a/core/modules/node/tests/src/Traits/NodeCreationTrait.php b/core/modules/node/tests/src/Traits/NodeCreationTrait.php new file mode 100644 index 00000000..6e0cf6a2 --- /dev/null +++ b/core/modules/node/tests/src/Traits/NodeCreationTrait.php @@ -0,0 +1,86 @@ +randomMachineName(). + * @param $reset + * (optional) Whether to reset the entity cache. + * + * @return \Drupal\node\NodeInterface + * A node entity matching $title. + */ + public function getNodeByTitle($title, $reset = FALSE) { + if ($reset) { + \Drupal::entityTypeManager()->getStorage('node')->resetCache(); + } + // Cast MarkupInterface objects to string. + $title = (string) $title; + $nodes = \Drupal::entityTypeManager() + ->getStorage('node') + ->loadByProperties(['title' => $title]); + // Load the first node returned from the database. + $returned_node = reset($nodes); + return $returned_node; + } + + /** + * Creates a node based on default settings. + * + * @param array $settings + * (optional) An associative array of settings for the node, as used in + * entity_create(). Override the defaults by specifying the key and value + * in the array, for example: + * @code + * $this->drupalCreateNode(array( + * 'title' => t('Hello, world!'), + * 'type' => 'article', + * )); + * @endcode + * The following defaults are provided: + * - body: Random string using the default filter format: + * @code + * $settings['body'][0] = array( + * 'value' => $this->randomMachineName(32), + * 'format' => filter_default_format(), + * ); + * @endcode + * - title: Random string. + * - type: 'page'. + * - uid: The currently logged in user, or anonymous. + * + * @return \Drupal\node\NodeInterface + * The created node entity. + */ + protected function createNode(array $settings = []) { + // Populate defaults array. + $settings += [ + 'body' => [ + [ + 'value' => $this->randomMachineName(32), + 'format' => filter_default_format(), + ], + ], + 'title' => $this->randomMachineName(8), + 'type' => 'page', + 'uid' => \Drupal::currentUser()->id(), + ]; + $node = Node::create($settings); + $node->save(); + + return $node; + } + +} diff --git a/core/modules/node/tests/src/Unit/Plugin/views/field/NodeBulkFormTest.php b/core/modules/node/tests/src/Unit/Plugin/views/field/NodeBulkFormTest.php index 6b28409e..eb92f8cb 100644 --- a/core/modules/node/tests/src/Unit/Plugin/views/field/NodeBulkFormTest.php +++ b/core/modules/node/tests/src/Unit/Plugin/views/field/NodeBulkFormTest.php @@ -25,7 +25,7 @@ protected function tearDown() { * Tests the constructor assignment of actions. */ public function testConstructor() { - $actions = array(); + $actions = []; for ($i = 1; $i <= 2; $i++) { $action = $this->getMock('\Drupal\system\ActionConfigEntityInterface'); @@ -60,7 +60,7 @@ public function testConstructor() { $views_data->expects($this->any()) ->method('get') ->with('node') - ->will($this->returnValue(array('table' => array('entity type' => 'node')))); + ->will($this->returnValue(['table' => ['entity type' => 'node']])); $container = new ContainerBuilder(); $container->set('views.views_data', $views_data); $container->set('string_translation', $this->getStringTranslationStub()); @@ -82,9 +82,9 @@ public function testConstructor() { ->getMock(); $definition['title'] = ''; - $options = array(); + $options = []; - $node_bulk_form = new NodeBulkForm(array(), 'node_bulk_form', $definition, $entity_manager, $language_manager); + $node_bulk_form = new NodeBulkForm([], 'node_bulk_form', $definition, $entity_manager, $language_manager); $node_bulk_form->init($executable, $display, $options); $this->assertAttributeEquals(array_slice($actions, 0, -1, TRUE), 'actions', $node_bulk_form); diff --git a/core/modules/options/options.api.php b/core/modules/options/options.api.php index 28ac7711..0f52b2be 100644 --- a/core/modules/options/options.api.php +++ b/core/modules/options/options.api.php @@ -81,21 +81,21 @@ function hook_options_list_alter(array &$options, array $context) { */ function callback_allowed_values_function(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL, &$cacheable = TRUE) { if (isset($entity) && ($entity->bundle() == 'not_a_programmer')) { - $values = array( + $values = [ 1 => 'One', 2 => 'Two', - ); + ]; } else { - $values = array( - 'Group 1' => array( + $values = [ + 'Group 1' => [ 0 => 'Zero', 1 => 'One', - ), - 'Group 2' => array( + ], + 'Group 2' => [ 2 => 'Two', - ), - ); + ], + ]; } return $values; diff --git a/core/modules/options/options.info.yml b/core/modules/options/options.info.yml index 343f09dd..8d4318b4 100644 --- a/core/modules/options/options.info.yml +++ b/core/modules/options/options.info.yml @@ -8,8 +8,8 @@ dependencies: - field - text -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/options/options.module b/core/modules/options/options.module index 20416076..7cf36355 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -19,11 +19,11 @@ function options_help($route_name, RouteMatchInterface $route_match) { case 'help.page.options': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Options module allows you to create fields where data values are selected from a fixed list of options. Usually these items are entered through a select list, checkboxes, or radio buttons. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Options module.', array(':field' => \Drupal::url('help.page', array('name' => 'field')), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#', ':options_do' => 'https://www.drupal.org/documentation/modules/options')) . '

    '; + $output .= '

    ' . t('The Options module allows you to create fields where data values are selected from a fixed list of options. Usually these items are entered through a select list, checkboxes, or radio buttons. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Options module.', [':field' => \Drupal::url('help.page', ['name' => 'field']), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#', ':options_do' => 'https://www.drupal.org/documentation/modules/options']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Managing and displaying list fields') . '
    '; - $output .= '
    ' . t('The settings and the display of the list fields can be configured separately. See the Field UI help for more information on how to manage fields and their display.', array(':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#')) . '
    '; + $output .= '
    ' . t('The settings and the display of the list fields can be configured separately. See the Field UI help for more information on how to manage fields and their display.', [':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#']) . '
    '; $output .= '
    ' . t('Defining option keys and labels') . '
    '; $output .= '
    ' . t('When you define the list options you can define a key and a label for each option in the list. The label will be shown to the users while the key gets stored in the database.') . '
    '; $output .= '
    ' . t('Choosing list field type') . '
    '; @@ -70,9 +70,9 @@ function options_field_storage_config_delete(FieldStorageConfigInterface $field_ * @see callback_allowed_values_function() */ function options_allowed_values(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL) { - $allowed_values = &drupal_static(__FUNCTION__, array()); + $allowed_values = &drupal_static(__FUNCTION__, []); - $cache_keys = array($definition->getTargetEntityTypeId(), $definition->getName()); + $cache_keys = [$definition->getTargetEntityTypeId(), $definition->getName()]; if ($entity) { $cache_keys[] = 'entity'; } @@ -112,7 +112,7 @@ function options_field_storage_config_update_forbid(FieldStorageConfigInterface $prior_allowed_values = $prior_field_storage->getSetting('allowed_values'); $lost_keys = array_keys(array_diff_key($prior_allowed_values, $allowed_values)); if (_options_values_in_use($field_storage->getTargetEntityTypeId(), $field_storage->getName(), $lost_keys)) { - throw new FieldStorageDefinitionUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', array('@field_name' => $field_storage->getName()))); + throw new FieldStorageDefinitionUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', ['@field_name' => $field_storage->getName()])); } } } diff --git a/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php b/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php index bc1dba19..ba1ba9c2 100644 --- a/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php +++ b/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsDefaultFormatter.php @@ -29,7 +29,7 @@ class OptionsDefaultFormatter extends FormatterBase { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $elements = array(); + $elements = []; // Only collect allowed options if there are actually items to display. if ($items->count()) { @@ -44,10 +44,10 @@ public function viewElements(FieldItemListInterface $items, $langcode) { // If the stored value is in the current set of allowed values, display // the associated label, otherwise just display the raw value. $output = isset($options[$value]) ? $options[$value] : $value; - $elements[$delta] = array( + $elements[$delta] = [ '#markup' => $output, '#allowed_tags' => FieldFilteredMarkup::allowedTags(), - ); + ]; } } diff --git a/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php b/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php index 2b83b150..64f22e9b 100644 --- a/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php +++ b/core/modules/options/src/Plugin/Field/FieldFormatter/OptionsKeyFormatter.php @@ -28,13 +28,13 @@ class OptionsKeyFormatter extends FormatterBase { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $elements = array(); + $elements = []; foreach ($items as $delta => $item) { - $elements[$delta] = array( + $elements[$delta] = [ '#markup' => $item->value, '#allowed_tags' => FieldFilteredMarkup::allowedTags(), - ); + ]; } return $elements; diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php index 254207d5..416f7dc2 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php @@ -34,16 +34,16 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'float', - ), - ), - 'indexes' => array( - 'value' => array('value'), - ), - ); + ], + ], + 'indexes' => [ + 'value' => ['value'], + ], + ]; } /** @@ -55,7 +55,7 @@ protected function allowedValuesDescription() { $description .= '
    ' . t('The label is optional: if a line contains a single number, it will be used as key and label.'); $description .= '
    ' . t('Lists of labels are also accepted (one label per line), only if the field does not hold any values yet. Numeric keys will be automatically generated from the positions in the list.'); $description .= '

    '; - $description .= '

    ' . t('Allowed HTML tags in labels: @tags', array('@tags' => $this->displayAllowedTags())) . '

    '; + $description .= '

    ' . t('Allowed HTML tags in labels: @tags', ['@tags' => $this->displayAllowedTags()]) . '

    '; return $description; } @@ -90,7 +90,7 @@ protected static function validateAllowedValue($option) { * {@inheritdoc} */ public static function simplifyAllowedValues(array $structured_values) { - $values = array(); + $values = []; foreach ($structured_values as $item) { // Nested elements are embedded in the label. if (is_array($item['label'])) { diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php index 719ae487..b8a42048 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php @@ -34,16 +34,16 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'int', - ), - ), - 'indexes' => array( - 'value' => array('value'), - ), - ); + ], + ], + 'indexes' => [ + 'value' => ['value'], + ], + ]; } /** @@ -55,7 +55,7 @@ protected function allowedValuesDescription() { $description .= '
    ' . t('The label is optional: if a line contains a single number, it will be used as key and label.'); $description .= '
    ' . t('Lists of labels are also accepted (one label per line), only if the field does not hold any values yet. Numeric keys will be automatically generated from the positions in the list.'); $description .= '

    '; - $description .= '

    ' . t('Allowed HTML tags in labels: @tags', array('@tags' => $this->displayAllowedTags())) . '

    '; + $description .= '

    ' . t('Allowed HTML tags in labels: @tags', ['@tags' => $this->displayAllowedTags()]) . '

    '; return $description; } diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php index 4527ca36..3b29b04b 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php @@ -21,10 +21,10 @@ abstract class ListItemBase extends FieldItemBase implements OptionsProviderInte * {@inheritdoc} */ public static function defaultStorageSettings() { - return array( - 'allowed_values' => array(), + return [ + 'allowed_values' => [], 'allowed_values_function' => '', - ) + parent::defaultStorageSettings(); + ] + parent::defaultStorageSettings(); } /** @@ -85,28 +85,28 @@ public function storageSettingsForm(array &$form, FormStateInterface $form_state $allowed_values = $this->getSetting('allowed_values'); $allowed_values_function = $this->getSetting('allowed_values_function'); - $element['allowed_values'] = array( + $element['allowed_values'] = [ '#type' => 'textarea', '#title' => t('Allowed values list'), '#default_value' => $this->allowedValuesString($allowed_values), '#rows' => 10, '#access' => empty($allowed_values_function), - '#element_validate' => array(array(get_class($this), 'validateAllowedValues')), + '#element_validate' => [[get_class($this), 'validateAllowedValues']], '#field_has_data' => $has_data, '#field_name' => $this->getFieldDefinition()->getName(), '#entity_type' => $this->getEntity()->getEntityTypeId(), '#allowed_values' => $allowed_values, - ); + ]; $element['allowed_values']['#description'] = $this->allowedValuesDescription(); - $element['allowed_values_function'] = array( + $element['allowed_values_function'] = [ '#type' => 'item', '#title' => t('Allowed values list'), - '#markup' => t('The value of this field is being determined by the %function function and may not be changed.', array('%function' => $allowed_values_function)), + '#markup' => t('The value of this field is being determined by the %function function and may not be changed.', ['%function' => $allowed_values_function]), '#access' => !empty($allowed_values_function), '#value' => $allowed_values_function, - ); + ]; return $element; } @@ -171,7 +171,7 @@ public static function validateAllowedValues($element, FormStateInterface $form_ * @see \Drupal\options\Plugin\Field\FieldType\ListItemBase::allowedValuesString() */ protected static function extractAllowedValues($string, $has_data) { - $values = array(); + $values = []; $list = explode("\n", $string); $list = array_map('trim', $list); @@ -180,7 +180,7 @@ protected static function extractAllowedValues($string, $has_data) { $generated_keys = $explicit_keys = FALSE; foreach ($list as $position => $text) { // Check for an explicit key. - $matches = array(); + $matches = []; if (preg_match('/(.*)\|(.*)/', $text, $matches)) { // Trim key and value to avoid unwanted spaces issues. $key = trim($matches[1]); @@ -222,7 +222,7 @@ protected static function extractAllowedValues($string, $has_data) { * @return string * The error message if the specified value is invalid, NULL otherwise. */ - protected static function validateAllowedValue($option) { } + protected static function validateAllowedValue($option) {} /** * Generates a string representation of an array of 'allowed values'. @@ -239,7 +239,7 @@ protected static function validateAllowedValue($option) { } * - Each value is in the format "value|label" or "value". */ protected function allowedValuesString($values) { - $lines = array(); + $lines = []; foreach ($values as $key => $value) { $lines[] = "$key|$value"; } @@ -280,7 +280,7 @@ public static function storageSettingsFromConfigData(array $settings) { * @see \Drupal\options\Plugin\Field\FieldType\ListItemBase::structureAllowedValues() */ protected static function simplifyAllowedValues(array $structured_values) { - $values = array(); + $values = []; foreach ($structured_values as $item) { if (is_array($item['label'])) { // Nested elements are embedded in the label. @@ -305,15 +305,15 @@ protected static function simplifyAllowedValues(array $structured_values) { * @see \Drupal\options\Plugin\Field\FieldType\ListItemBase::simplifyAllowedValues() */ protected static function structureAllowedValues(array $values) { - $structured_values = array(); + $structured_values = []; foreach ($values as $value => $label) { if (is_array($label)) { $label = static::structureAllowedValues($label); } - $structured_values[] = array( + $structured_values[] = [ 'value' => static::castAllowedValue($value), 'label' => $label, - ); + ]; } return $structured_values; } diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php index f5440ab3..1f8caeaf 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php @@ -26,7 +26,7 @@ class ListStringItem extends ListItemBase { public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties['value'] = DataDefinition::create('string') ->setLabel(t('Text value')) - ->addConstraint('Length', array('max' => 255)) + ->addConstraint('Length', ['max' => 255]) ->setRequired(TRUE); return $properties; @@ -36,17 +36,17 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'varchar', 'length' => 255, - ), - ), - 'indexes' => array( - 'value' => array('value'), - ), - ); + ], + ], + 'indexes' => [ + 'value' => ['value'], + ], + ]; } /** @@ -57,7 +57,7 @@ protected function allowedValuesDescription() { $description .= '
    ' . t('The key is the stored value. The label will be used in displayed values and edit forms.'); $description .= '
    ' . t('The label is optional: if a line contains a single string, it will be used as key and label.'); $description .= '

    '; - $description .= '

    ' . t('Allowed HTML tags in labels: @tags', array('@tags' => $this->displayAllowedTags())) . '

    '; + $description .= '

    ' . t('Allowed HTML tags in labels: @tags', ['@tags' => $this->displayAllowedTags()]) . '

    '; return $description; } diff --git a/core/modules/options/src/Plugin/migrate/field/d7/ListField.php b/core/modules/options/src/Plugin/migrate/field/d7/ListField.php new file mode 100644 index 00000000..fff29ee1 --- /dev/null +++ b/core/modules/options/src/Plugin/migrate/field/d7/ListField.php @@ -0,0 +1,18 @@ +drupalCreateUser(array('synchronize configuration', 'access content', 'access administration pages', 'administer site configuration', 'administer content types', 'administer nodes', 'bypass node access', 'administer node fields', 'administer node display')); - $this->drupalLogin($admin_user); - } - - /** - * Tests that importing list_float fields works. - */ - public function testImport() { - $field_name = 'field_options_float'; - $type = 'options_install_test'; - - // Test the results on installing options_config_install_test. All the - // necessary configuration for this test is created by installing that - // module. - $field_storage = FieldStorageConfig::loadByName('node', $field_name); - $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = array('0' => 'Zero', '0.5' => 'Point five')); - - $admin_path = 'admin/structure/types/manage/' . $type . '/fields/node.' . $type . '.' . $field_name . '/storage'; - - // Export active config to sync. - $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync')); - - // Set the active to not use dots in the allowed values key names. - $edit = array('settings[allowed_values]' => "0|Zero\n1|One"); - $this->drupalPostForm($admin_path, $edit, t('Save field settings')); - $field_storage = FieldStorageConfig::loadByName('node', $field_name); - $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = array('0' => 'Zero', '1' => 'One')); - - // Import configuration with dots in the allowed values key names. This - // tests \Drupal\Core\Config\Entity\ConfigEntityStorage::importUpdate(). - $this->drupalGet('admin/config/development/configuration'); - $this->drupalPostForm(NULL, array(), t('Import all')); - $field_storage = FieldStorageConfig::loadByName('node', $field_name); - $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = array('0' => 'Zero', '0.5' => 'Point five')); - - // Delete field to test creation. This tests - // \Drupal\Core\Config\Entity\ConfigEntityStorage::importCreate(). - FieldConfig::loadByName('node', $type, $field_name)->delete(); - - $this->drupalGet('admin/config/development/configuration'); - $this->drupalPostForm(NULL, array(), t('Import all')); - $field_storage = FieldStorageConfig::loadByName('node', $field_name); - $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = array('0' => 'Zero', '0.5' => 'Point five')); - } - -} diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml index 19a2ef70..ff5f0ec2 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_form_display.node.options_install_test.default.yml @@ -14,6 +14,7 @@ content: title: type: string_textfield weight: -5 + region: content settings: size: 60 placeholder: '' @@ -21,6 +22,7 @@ content: uid: type: entity_reference_autocomplete weight: 5 + region: content settings: match_operator: CONTAINS size: 60 @@ -29,6 +31,7 @@ content: created: type: datetime_timestamp weight: 10 + region: content settings: { } third_party_settings: { } promote: @@ -36,16 +39,19 @@ content: settings: display_label: true weight: 15 + region: content third_party_settings: { } sticky: type: boolean_checkbox settings: display_label: true weight: 16 + region: content third_party_settings: { } body: type: text_textarea_with_summary weight: 26 + region: content settings: rows: 9 summary_rows: 3 diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml index c107b101..aaea1cb9 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.default.yml @@ -14,10 +14,12 @@ mode: default content: links: weight: 100 + region: content body: label: hidden type: text_default weight: 101 + region: content settings: { } third_party_settings: { } hidden: diff --git a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml index 3b472a7d..6e79af94 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/core.entity_view_display.node.options_install_test.teaser.yml @@ -15,10 +15,12 @@ mode: teaser content: links: weight: 100 + region: content body: label: hidden type: text_summary_or_trimmed weight: 101 + region: content settings: trim_length: 600 third_party_settings: { } diff --git a/core/modules/options/tests/options_config_install_test/options_config_install_test.info.yml b/core/modules/options/tests/options_config_install_test/options_config_install_test.info.yml index b4596562..e9a39ea5 100644 --- a/core/modules/options/tests/options_config_install_test/options_config_install_test.info.yml +++ b/core/modules/options/tests/options_config_install_test/options_config_install_test.info.yml @@ -8,8 +8,8 @@ dependencies: - node - options -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/options/tests/options_test/options_test.info.yml b/core/modules/options/tests/options_test/options_test.info.yml index 6bd20623..a5ee03c9 100644 --- a/core/modules/options/tests/options_test/options_test.info.yml +++ b/core/modules/options/tests/options_test/options_test.info.yml @@ -5,8 +5,8 @@ description: 'Support module for the Options module tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/options/tests/options_test/options_test.module b/core/modules/options/tests/options_test/options_test.module index d20401af..dbb474b4 100644 --- a/core/modules/options/tests/options_test/options_test.module +++ b/core/modules/options/tests/options_test/options_test.module @@ -14,18 +14,18 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; * @see options_allowed_values() */ function options_test_allowed_values_callback(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL) { - $values = array( - 'Group 1' => array( + $values = [ + 'Group 1' => [ 0 => 'Zero', - ), + ], 1 => 'One', - 'Group 2' => array( + 'Group 2' => [ 2 => 'Some & unescaped markup', - ), - 'More markup' => array( + ], + 'More markup' => [ 3 => 'Three', - ), - ); + ], + ]; return $values; } @@ -41,15 +41,15 @@ function options_test_allowed_values_callback(FieldStorageDefinitionInterface $d * @see options_allowed_values() */ function options_test_dynamic_values_callback(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL, &$cacheable = NULL) { - $values = array(); + $values = []; if (isset($entity)) { $cacheable = FALSE; - $values = array( + $values = [ $entity->label(), $entity->url(), $entity->uuid(), $entity->bundle(), - ); + ]; } // We need the values of the entity as keys. return array_combine($values, $values); diff --git a/core/modules/options/tests/options_test_views/options_test_views.info.yml b/core/modules/options/tests/options_test_views/options_test_views.info.yml index 72f37bf3..e45171d9 100644 --- a/core/modules/options/tests/options_test_views/options_test_views.info.yml +++ b/core/modules/options/tests/options_test_views/options_test_views.info.yml @@ -8,8 +8,8 @@ dependencies: - options - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/options/src/Tests/OptionsDynamicValuesApiTest.php b/core/modules/options/tests/src/Functional/OptionsDynamicValuesApiTest.php similarity index 91% rename from core/modules/options/src/Tests/OptionsDynamicValuesApiTest.php rename to core/modules/options/tests/src/Functional/OptionsDynamicValuesApiTest.php index 081696a6..a96fd7a0 100644 --- a/core/modules/options/src/Tests/OptionsDynamicValuesApiTest.php +++ b/core/modules/options/tests/src/Functional/OptionsDynamicValuesApiTest.php @@ -1,6 +1,6 @@ fieldStorage, $this->entity); - $expected_values = array( + $expected_values = [ $this->entity->label(), $this->entity->url(), $this->entity->uuid(), $this->entity->bundle(), - ); + ]; $expected_values = array_combine($expected_values, $expected_values); $this->assertEqual($expected_values, $values); } diff --git a/core/modules/options/src/Tests/OptionsDynamicValuesTestBase.php b/core/modules/options/tests/src/Functional/OptionsDynamicValuesTestBase.php similarity index 97% rename from core/modules/options/src/Tests/OptionsDynamicValuesTestBase.php rename to core/modules/options/tests/src/Functional/OptionsDynamicValuesTestBase.php index 2d3f0fbe..64e90104 100644 --- a/core/modules/options/src/Tests/OptionsDynamicValuesTestBase.php +++ b/core/modules/options/tests/src/Functional/OptionsDynamicValuesTestBase.php @@ -1,6 +1,6 @@ test as $key => $value) { $this->entity->test_options->value = $value; diff --git a/core/modules/options/src/Tests/OptionsFieldUITest.php b/core/modules/options/tests/src/Functional/OptionsFieldUITest.php similarity index 80% rename from core/modules/options/src/Tests/OptionsFieldUITest.php rename to core/modules/options/tests/src/Functional/OptionsFieldUITest.php index d2c11f01..ec5874b2 100644 --- a/core/modules/options/src/Tests/OptionsFieldUITest.php +++ b/core/modules/options/tests/src/Functional/OptionsFieldUITest.php @@ -1,6 +1,6 @@ fieldName = 'field_options_integer'; $this->createOptionsField('list_integer'); // Flat list of textual values. $string = "Zero\nOne"; - $array = array('0' => 'Zero', '1' => 'One'); + $array = ['0' => 'Zero', '1' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.'); // Explicit integer keys. $string = "0|Zero\n2|Two"; - $array = array('0' => 'Zero', '2' => 'Two'); + $array = ['0' => 'Zero', '2' => 'Two']; $this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.'); // Check that values can be added and removed. $string = "0|Zero\n1|One"; - $array = array('0' => 'Zero', '1' => 'One'); + $array = ['0' => 'Zero', '1' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.'); // Non-integer keys. $this->assertAllowedValuesInput("1.1|One", 'keys must be integers', 'Non integer keys are rejected.'); @@ -87,54 +87,54 @@ function testOptionsAllowedValuesInteger() { $this->assertAllowedValuesInput("Zero\n1|One", 'invalid input', 'Mixed lists are rejected.'); // Create a node with actual data for the field. - $settings = array( + $settings = [ 'type' => $this->type, - $this->fieldName => array(array('value' => 1)), - ); + $this->fieldName => [['value' => 1]], + ]; $node = $this->drupalCreateNode($settings); // Check that a flat list of values is rejected once the field has data. - $this->assertAllowedValuesInput( "Zero\nOne", 'invalid input', 'Unkeyed lists are rejected once the field has data.'); + $this->assertAllowedValuesInput("Zero\nOne", 'invalid input', 'Unkeyed lists are rejected once the field has data.'); // Check that values can be added but values in use cannot be removed. $string = "0|Zero\n1|One\n2|Two"; - $array = array('0' => 'Zero', '1' => 'One', '2' => 'Two'); + $array = ['0' => 'Zero', '1' => 'One', '2' => 'Two']; $this->assertAllowedValuesInput($string, $array, 'Values can be added.'); $string = "0|Zero\n1|One"; - $array = array('0' => 'Zero', '1' => 'One'); + $array = ['0' => 'Zero', '1' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); $this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.'); // Delete the node, remove the value. $node->delete(); $string = "0|Zero"; - $array = array('0' => 'Zero'); + $array = ['0' => 'Zero']; $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); // Check that the same key can only be used once. $string = "0|Zero\n0|One"; - $array = array('0' => 'One'); + $array = ['0' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Same value cannot be used multiple times.'); } /** * Options (float) : test 'allowed values' input. */ - function testOptionsAllowedValuesFloat() { + public function testOptionsAllowedValuesFloat() { $this->fieldName = 'field_options_float'; $this->createOptionsField('list_float'); // Flat list of textual values. $string = "Zero\nOne"; - $array = array('0' => 'Zero', '1' => 'One'); + $array = ['0' => 'Zero', '1' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.'); // Explicit numeric keys. $string = "0|Zero\n.5|Point five"; - $array = array('0' => 'Zero', '0.5' => 'Point five'); + $array = ['0' => 'Zero', '0.5' => 'Point five']; $this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.'); // Check that values can be added and removed. $string = "0|Zero\n.5|Point five\n1.0|One"; - $array = array('0' => 'Zero', '0.5' => 'Point five', '1' => 'One'); + $array = ['0' => 'Zero', '0.5' => 'Point five', '1' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.'); // Non-numeric keys. $this->assertAllowedValuesInput("abc|abc\n", 'each key must be a valid integer or decimal', 'Non numeric keys are rejected.'); @@ -142,10 +142,10 @@ function testOptionsAllowedValuesFloat() { $this->assertAllowedValuesInput("Zero\n1|One\n", 'invalid input', 'Mixed lists are rejected.'); // Create a node with actual data for the field. - $settings = array( + $settings = [ 'type' => $this->type, - $this->fieldName => array(array('value' => .5)), - ); + $this->fieldName => [['value' => .5]], + ]; $node = $this->drupalCreateNode($settings); // Check that a flat list of values is rejected once the field has data. @@ -153,105 +153,105 @@ function testOptionsAllowedValuesFloat() { // Check that values can be added but values in use cannot be removed. $string = "0|Zero\n.5|Point five\n2|Two"; - $array = array('0' => 'Zero', '0.5' => 'Point five', '2' => 'Two'); + $array = ['0' => 'Zero', '0.5' => 'Point five', '2' => 'Two']; $this->assertAllowedValuesInput($string, $array, 'Values can be added.'); $string = "0|Zero\n.5|Point five"; - $array = array('0' => 'Zero', '0.5' => 'Point five'); + $array = ['0' => 'Zero', '0.5' => 'Point five']; $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); $this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.'); // Delete the node, remove the value. $node->delete(); $string = "0|Zero"; - $array = array('0' => 'Zero'); + $array = ['0' => 'Zero']; $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); // Check that the same key can only be used once. $string = "0.5|Point five\n0.5|Half"; - $array = array('0.5' => 'Half'); + $array = ['0.5' => 'Half']; $this->assertAllowedValuesInput($string, $array, 'Same value cannot be used multiple times.'); // Check that different forms of the same float value cannot be used. $string = "0|Zero\n.5|Point five\n0.5|Half"; - $array = array('0' => 'Zero', '0.5' => 'Half'); + $array = ['0' => 'Zero', '0.5' => 'Half']; $this->assertAllowedValuesInput($string, $array, 'Different forms of the same value cannot be used.'); } /** * Options (text) : test 'allowed values' input. */ - function testOptionsAllowedValuesText() { + public function testOptionsAllowedValuesText() { $this->fieldName = 'field_options_text'; $this->createOptionsField('list_string'); // Flat list of textual values. $string = "Zero\nOne"; - $array = array('Zero' => 'Zero', 'One' => 'One'); + $array = ['Zero' => 'Zero', 'One' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.'); // Explicit keys. $string = "zero|Zero\none|One"; - $array = array('zero' => 'Zero', 'one' => 'One'); + $array = ['zero' => 'Zero', 'one' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted.'); // Check that values can be added and removed. $string = "zero|Zero\ntwo|Two"; - $array = array('zero' => 'Zero', 'two' => 'Two'); + $array = ['zero' => 'Zero', 'two' => 'Two']; $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.'); // Mixed list of keyed and unkeyed values. $string = "zero|Zero\nOne\n"; - $array = array('zero' => 'Zero', 'One' => 'One'); + $array = ['zero' => 'Zero', 'One' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Mixed lists are accepted.'); // Overly long keys. $this->assertAllowedValuesInput("zero|Zero\n" . $this->randomMachineName(256) . "|One", 'each key must be a string at most 255 characters long', 'Overly long keys are rejected.'); // Create a node with actual data for the field. - $settings = array( + $settings = [ 'type' => $this->type, - $this->fieldName => array(array('value' => 'One')), - ); + $this->fieldName => [['value' => 'One']], + ]; $node = $this->drupalCreateNode($settings); // Check that flat lists of values are still accepted once the field has // data. $string = "Zero\nOne"; - $array = array('Zero' => 'Zero', 'One' => 'One'); + $array = ['Zero' => 'Zero', 'One' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are still accepted once the field has data.'); // Check that values can be added but values in use cannot be removed. $string = "Zero\nOne\nTwo"; - $array = array('Zero' => 'Zero', 'One' => 'One', 'Two' => 'Two'); + $array = ['Zero' => 'Zero', 'One' => 'One', 'Two' => 'Two']; $this->assertAllowedValuesInput($string, $array, 'Values can be added.'); $string = "Zero\nOne"; - $array = array('Zero' => 'Zero', 'One' => 'One'); + $array = ['Zero' => 'Zero', 'One' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); $this->assertAllowedValuesInput("Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.'); // Delete the node, remove the value. $node->delete(); $string = "Zero"; - $array = array('Zero' => 'Zero'); + $array = ['Zero' => 'Zero']; $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.'); // Check that string values with dots can be used. $string = "Zero\nexample.com|Example"; - $array = array('Zero' => 'Zero', 'example.com' => 'Example'); + $array = ['Zero' => 'Zero', 'example.com' => 'Example']; $this->assertAllowedValuesInput($string, $array, 'String value with dot is supported.'); // Check that the same key can only be used once. $string = "zero|Zero\nzero|One"; - $array = array('zero' => 'One'); + $array = ['zero' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Same value cannot be used multiple times.'); } /** * Options (text) : test 'trimmed values' input. */ - function testOptionsTrimmedValuesText() { + public function testOptionsTrimmedValuesText() { $this->fieldName = 'field_options_trimmed_text'; $this->createOptionsField('list_string'); // Explicit keys. $string = "zero |Zero\none | One"; - $array = array('zero' => 'Zero', 'one' => 'One'); + $array = ['zero' => 'Zero', 'one' => 'One']; $this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted and trimmed.'); } @@ -259,15 +259,15 @@ function testOptionsTrimmedValuesText() { * Helper function to create list field of a given type. * * @param string $type - * 'list_integer', 'list_float' or 'list_string' + * One of 'list_integer', 'list_float' or 'list_string'. */ protected function createOptionsField($type) { // Create a field. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'node', 'type' => $type, - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => $this->fieldName, 'entity_type' => 'node', @@ -291,8 +291,8 @@ protected function createOptionsField($type) { * @param $message * Message to display. */ - function assertAllowedValuesInput($input_string, $result, $message) { - $edit = array('settings[allowed_values]' => $input_string); + public function assertAllowedValuesInput($input_string, $result, $message) { + $edit = ['settings[allowed_values]' => $input_string]; $this->drupalPostForm($this->adminPath, $edit, t('Save field settings')); $this->assertNoRaw('&lt;', 'The page does not have double escaped HTML tags.'); @@ -308,34 +308,35 @@ function assertAllowedValuesInput($input_string, $result, $message) { /** * Tests normal and key formatter display on node display. */ - function testNodeDisplay() { + public function testNodeDisplay() { $this->fieldName = strtolower($this->randomMachineName()); $this->createOptionsField('list_integer'); - $node = $this->drupalCreateNode(array('type' => $this->type)); + $node = $this->drupalCreateNode(['type' => $this->type]); $on = $this->randomMachineName(); $off = $this->randomMachineName(); - $edit = array( + $edit = [ 'settings[allowed_values]' => "1|$on 0|$off", - ); + ]; $this->drupalPostForm($this->adminPath, $edit, t('Save field settings')); - $this->assertText(format_string('Updated field @field_name field settings.', array('@field_name' => $this->fieldName)), "The 'On' and 'Off' form fields work for boolean fields."); + $this->assertText(format_string('Updated field @field_name field settings.', ['@field_name' => $this->fieldName]), "The 'On' and 'Off' form fields work for boolean fields."); // Select a default value. - $edit = array( + $edit = [ $this->fieldName => '1', - ); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); + ]; + $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Check the node page and see if the values are correct. - $file_formatters = array('list_default', 'list_key'); + $file_formatters = ['list_default', 'list_key']; foreach ($file_formatters as $formatter) { - $edit = array( + $edit = [ "fields[$this->fieldName][type]" => $formatter, - ); + "fields[$this->fieldName][region]" => 'content', + ]; $this->drupalPostForm('admin/structure/types/manage/' . $this->typeName . '/display', $edit, t('Save')); $this->drupalGet('node/' . $node->id()); diff --git a/core/modules/options/tests/src/Functional/OptionsFloatFieldImportTest.php b/core/modules/options/tests/src/Functional/OptionsFloatFieldImportTest.php new file mode 100644 index 00000000..befd48e4 --- /dev/null +++ b/core/modules/options/tests/src/Functional/OptionsFloatFieldImportTest.php @@ -0,0 +1,72 @@ +drupalCreateUser(['synchronize configuration', 'access content', 'access administration pages', 'administer site configuration', 'administer content types', 'administer nodes', 'bypass node access', 'administer node fields', 'administer node display']); + $this->drupalLogin($admin_user); + } + + /** + * Tests that importing list_float fields works. + */ + public function testImport() { + $field_name = 'field_options_float'; + $type = 'options_install_test'; + + // Test the results on installing options_config_install_test. All the + // necessary configuration for this test is created by installing that + // module. + $field_storage = FieldStorageConfig::loadByName('node', $field_name); + $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = ['0' => 'Zero', '0.5' => 'Point five']); + + $admin_path = 'admin/structure/types/manage/' . $type . '/fields/node.' . $type . '.' . $field_name . '/storage'; + + // Export active config to sync. + $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync')); + + // Set the active to not use dots in the allowed values key names. + $edit = ['settings[allowed_values]' => "0|Zero\n1|One"]; + $this->drupalPostForm($admin_path, $edit, t('Save field settings')); + $field_storage = FieldStorageConfig::loadByName('node', $field_name); + $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = ['0' => 'Zero', '1' => 'One']); + + // Import configuration with dots in the allowed values key names. This + // tests \Drupal\Core\Config\Entity\ConfigEntityStorage::importUpdate(). + $this->drupalGet('admin/config/development/configuration'); + $this->drupalPostForm(NULL, [], t('Import all')); + $field_storage = FieldStorageConfig::loadByName('node', $field_name); + $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = ['0' => 'Zero', '0.5' => 'Point five']); + + // Delete field to test creation. This tests + // \Drupal\Core\Config\Entity\ConfigEntityStorage::importCreate(). + FieldConfig::loadByName('node', $type, $field_name)->delete(); + + $this->drupalGet('admin/config/development/configuration'); + $this->drupalPostForm(NULL, [], t('Import all')); + $field_storage = FieldStorageConfig::loadByName('node', $field_name); + $this->assertIdentical($field_storage->getSetting('allowed_values'), $array = ['0' => 'Zero', '0.5' => 'Point five']); + } + +} diff --git a/core/modules/options/src/Tests/OptionsSelectDynamicValuesTest.php b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php similarity index 81% rename from core/modules/options/src/Tests/OptionsSelectDynamicValuesTest.php rename to core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php index df3365ca..b661c0d5 100644 --- a/core/modules/options/src/Tests/OptionsSelectDynamicValuesTest.php +++ b/core/modules/options/tests/src/Functional/OptionsSelectDynamicValuesTest.php @@ -1,6 +1,6 @@ entity->save(); // Create a web user. - $web_user = $this->drupalCreateUser(array('view test entity', 'administer entity_test content')); + $web_user = $this->drupalCreateUser(['view test entity', 'administer entity_test content']); $this->drupalLogin($web_user); // Display form. diff --git a/core/modules/options/src/Tests/OptionsWidgetsTest.php b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php similarity index 81% rename from core/modules/options/src/Tests/OptionsWidgetsTest.php rename to core/modules/options/tests/src/Functional/OptionsWidgetsTest.php index 23f0f0da..a2157f1f 100644 --- a/core/modules/options/src/Tests/OptionsWidgetsTest.php +++ b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php @@ -1,6 +1,6 @@ $this->card1, @@ -114,9 +114,9 @@ function testRadioButtons() { $this->assertRaw('Some HTML encoded markup with < & >'); // Select first option. - $edit = array('card_1' => 0); + $edit = ['card_1' => 0]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_1', array(0)); + $this->assertFieldValues($entity_init, 'card_1', [0]); // Check that the selected button is checked. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -125,9 +125,9 @@ function testRadioButtons() { $this->assertNoFieldChecked('edit-card-1-2'); // Unselect option. - $edit = array('card_1' => '_none'); + $edit = ['card_1' => '_none']; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_1', array()); + $this->assertFieldValues($entity_init, 'card_1', []); // Check that required radios with one option is auto-selected. $this->card1->setSetting('allowed_values', [99 => 'Only allowed value']); @@ -141,7 +141,7 @@ function testRadioButtons() { /** * Tests the 'options_buttons' widget (multiple select). */ - function testCheckBoxes() { + public function testCheckBoxes() { // Create an instance of the 'multiple values' field. $field = FieldConfig::create([ 'field_storage' => $this->card2, @@ -149,16 +149,16 @@ function testCheckBoxes() { ]); $field->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->card2->getName(), array( + ->setComponent($this->card2->getName(), [ 'type' => 'options_buttons', - )) + ]) ->save(); // Create an entity. - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'user_id' => 1, 'name' => $this->randomMachineName(), - )); + ]); $entity->save(); $entity_init = clone $entity; @@ -170,13 +170,13 @@ function testCheckBoxes() { $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); // Submit form: select first and third options. - $edit = array( + $edit = [ 'card_2[0]' => TRUE, 'card_2[1]' => FALSE, 'card_2[2]' => TRUE, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array(0, 2)); + $this->assertFieldValues($entity_init, 'card_2', [0, 2]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -185,13 +185,13 @@ function testCheckBoxes() { $this->assertFieldChecked('edit-card-2-2'); // Submit form: select only first option. - $edit = array( + $edit = [ 'card_2[0]' => TRUE, 'card_2[1]' => FALSE, 'card_2[2]' => FALSE, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array(0)); + $this->assertFieldValues($entity_init, 'card_2', [0]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -200,23 +200,23 @@ function testCheckBoxes() { $this->assertNoFieldChecked('edit-card-2-2'); // Submit form: select the three options while the field accepts only 2. - $edit = array( + $edit = [ 'card_2[0]' => TRUE, 'card_2[1]' => TRUE, 'card_2[2]' => TRUE, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.'); // Submit form: uncheck all options. - $edit = array( + $edit = [ 'card_2[0]' => FALSE, 'card_2[1]' => FALSE, 'card_2[2]' => FALSE, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); // Check that the value was saved. - $this->assertFieldValues($entity_init, 'card_2', array()); + $this->assertFieldValues($entity_init, 'card_2', []); // Required checkbox with one option is auto-selected. $this->card2->setSetting('allowed_values', [99 => 'Only allowed value']); @@ -230,7 +230,7 @@ function testCheckBoxes() { /** * Tests the 'options_select' widget (single select). */ - function testSelectListSingle() { + public function testSelectListSingle() { // Create an instance of the 'single value' field. $field = FieldConfig::create([ 'field_storage' => $this->card1, @@ -239,23 +239,23 @@ function testSelectListSingle() { ]); $field->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->card1->getName(), array( + ->setComponent($this->card1->getName(), [ 'type' => 'options_select', - )) + ]) ->save(); // Create an entity. - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'user_id' => 1, 'name' => $this->randomMachineName(), - )); + ]); $entity->save(); $entity_init = clone $entity; // Display form. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); // A required field without any value has a "none" option. - $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1', ':label' => t('- Select a value -'))), 'A required select list has a "Select a value" choice.'); + $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', [':id' => 'edit-card-1', ':label' => t('- Select a value -')]), 'A required select list has a "Select a value" choice.'); // With no field data, nothing is selected. $this->assertNoOptionSelected('edit-card-1', '_none'); @@ -265,19 +265,19 @@ function testSelectListSingle() { $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); // Submit form: select invalid 'none' option. - $edit = array('card_1' => '_none'); + $edit = ['card_1' => '_none']; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('@title field is required.', array('@title' => $field->getName())), 'Cannot save a required field when selecting "none" from the select list.'); + $this->assertRaw(t('@title field is required.', ['@title' => $field->getName()]), 'Cannot save a required field when selecting "none" from the select list.'); // Submit form: select first option. - $edit = array('card_1' => 0); + $edit = ['card_1' => 0]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_1', array(0)); + $this->assertFieldValues($entity_init, 'card_1', [0]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); // A required field with a value has no 'none' option. - $this->assertFalse($this->xpath('//select[@id=:id]//option[@value="_none"]', array(':id' => 'edit-card-1')), 'A required select list with an actual value has no "none" choice.'); + $this->assertFalse($this->xpath('//select[@id=:id]//option[@value="_none"]', [':id' => 'edit-card-1']), 'A required select list with an actual value has no "none" choice.'); $this->assertOptionSelected('edit-card-1', 0); $this->assertNoOptionSelected('edit-card-1', 1); $this->assertNoOptionSelected('edit-card-1', 2); @@ -289,11 +289,11 @@ function testSelectListSingle() { // Display form. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); // A non-required field has a 'none' option. - $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1', ':label' => t('- None -'))), 'A non-required select list has a "None" choice.'); + $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', [':id' => 'edit-card-1', ':label' => t('- None -')]), 'A non-required select list has a "None" choice.'); // Submit form: Unselect the option. - $edit = array('card_1' => '_none'); + $edit = ['card_1' => '_none']; $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_1', array()); + $this->assertFieldValues($entity_init, 'card_1', []); // Test optgroups. @@ -311,9 +311,9 @@ function testSelectListSingle() { $this->assertRaw('Group 1', 'Option groups are displayed.'); // Submit form: select first option. - $edit = array('card_1' => 0); + $edit = ['card_1' => 0]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_1', array(0)); + $this->assertFieldValues($entity_init, 'card_1', [0]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -322,15 +322,15 @@ function testSelectListSingle() { $this->assertNoOptionSelected('edit-card-1', 2); // Submit form: Unselect the option. - $edit = array('card_1' => '_none'); + $edit = ['card_1' => '_none']; $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_1', array()); + $this->assertFieldValues($entity_init, 'card_1', []); } /** * Tests the 'options_select' widget (multiple select). */ - function testSelectListMultiple() { + public function testSelectListMultiple() { // Create an instance of the 'multiple values' field. $field = FieldConfig::create([ 'field_storage' => $this->card2, @@ -338,16 +338,16 @@ function testSelectListMultiple() { ]); $field->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->card2->getName(), array( + ->setComponent($this->card2->getName(), [ 'type' => 'options_select', - )) + ]) ->save(); // Create an entity. - $entity = EntityTest::create(array( + $entity = EntityTest::create([ 'user_id' => 1, 'name' => $this->randomMachineName(), - )); + ]); $entity->save(); $entity_init = clone $entity; @@ -360,9 +360,9 @@ function testSelectListMultiple() { $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); // Submit form: select first and third options. - $edit = array('card_2[]' => array(0 => 0, 2 => 2)); + $edit = ['card_2[]' => [0 => 0, 2 => 2]]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array(0, 2)); + $this->assertFieldValues($entity_init, 'card_2', [0, 2]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -371,9 +371,9 @@ function testSelectListMultiple() { $this->assertOptionSelected('edit-card-2', 2); // Submit form: select only first option. - $edit = array('card_2[]' => array(0 => 0)); + $edit = ['card_2[]' => [0 => 0]]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array(0)); + $this->assertFieldValues($entity_init, 'card_2', [0]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -382,33 +382,33 @@ function testSelectListMultiple() { $this->assertNoOptionSelected('edit-card-2', 2); // Submit form: select the three options while the field accepts only 2. - $edit = array('card_2[]' => array(0 => 0, 1 => 1, 2 => 2)); + $edit = ['card_2[]' => [0 => 0, 1 => 1, 2 => 2]]; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.'); // Submit form: uncheck all options. - $edit = array('card_2[]' => array()); + $edit = ['card_2[]' => []]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array()); + $this->assertFieldValues($entity_init, 'card_2', []); // Test the 'None' option. // Check that the 'none' option has no effect if actual options are selected // as well. - $edit = array('card_2[]' => array('_none' => '_none', 0 => 0)); + $edit = ['card_2[]' => ['_none' => '_none', 0 => 0]]; $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array(0)); + $this->assertFieldValues($entity_init, 'card_2', [0]); // Check that selecting the 'none' option empties the field. - $edit = array('card_2[]' => array('_none' => '_none')); + $edit = ['card_2[]' => ['_none' => '_none']]; $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array()); + $this->assertFieldValues($entity_init, 'card_2', []); // A required select list does not have an empty key. $field->setRequired(TRUE); $field->save(); $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); - $this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', array(':id' => 'edit-card-2')), 'A required select list does not have an empty key.'); + $this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', [':id' => 'edit-card-2']), 'A required select list does not have an empty key.'); // We do not have to test that a required select list with one option is // auto-selected because the browser does it for us. @@ -432,9 +432,9 @@ function testSelectListMultiple() { $this->assertRaw('Group 1', 'Option groups are displayed.'); // Submit form: select first option. - $edit = array('card_2[]' => array(0 => 0)); + $edit = ['card_2[]' => [0 => 0]]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array(0)); + $this->assertFieldValues($entity_init, 'card_2', [0]); // Display form: check that the right options are selected. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); @@ -443,15 +443,15 @@ function testSelectListMultiple() { $this->assertNoOptionSelected('edit-card-2', 2); // Submit form: Unselect the option. - $edit = array('card_2[]' => array('_none' => '_none')); + $edit = ['card_2[]' => ['_none' => '_none']]; $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); - $this->assertFieldValues($entity_init, 'card_2', array()); + $this->assertFieldValues($entity_init, 'card_2', []); } /** * Tests the 'options_select' and 'options_button' widget for empty value. */ - function testEmptyValue() { + public function testEmptyValue() { // Create an instance of the 'single value' field. $field = FieldConfig::create([ 'field_storage' => $this->card1, @@ -475,20 +475,20 @@ function testEmptyValue() { // Display form: check that _none options are present and has label. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); - $this->assertTrue($this->xpath('//div[@id=:id]//input[@value=:value]', array(':id' => 'edit-card-1', ':value' => '_none')), 'A test radio button has a "None" choice.'); - $this->assertTrue($this->xpath('//div[@id=:id]//label[@for=:for and text()=:label]', array(':id' => 'edit-card-1', ':for' => 'edit-card-1-none', ':label' => 'N/A')), 'A test radio button has a "N/A" choice.'); + $this->assertTrue($this->xpath('//div[@id=:id]//input[@value=:value]', [':id' => 'edit-card-1', ':value' => '_none']), 'A test radio button has a "None" choice.'); + $this->assertTrue($this->xpath('//div[@id=:id]//label[@for=:for and text()=:label]', [':id' => 'edit-card-1', ':for' => 'edit-card-1-none', ':label' => 'N/A']), 'A test radio button has a "N/A" choice.'); // Change it to the select widget. entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->card1->getName(), array( + ->setComponent($this->card1->getName(), [ 'type' => 'options_select', - )) + ]) ->save(); // Display form: check that _none options are present and has label. $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); // A required field without any value has a "none" option. - $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', array(':id' => 'edit-card-1', ':label' => t('- None -'))), 'A test select has a "None" choice.'); + $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', [':id' => 'edit-card-1', ':label' => t('- None -')]), 'A test select has a "None" choice.'); } } diff --git a/core/modules/options/tests/src/Kernel/OptionsFieldTest.php b/core/modules/options/tests/src/Kernel/OptionsFieldTest.php index 89ac1271..401d6bc1 100644 --- a/core/modules/options/tests/src/Kernel/OptionsFieldTest.php +++ b/core/modules/options/tests/src/Kernel/OptionsFieldTest.php @@ -19,12 +19,12 @@ class OptionsFieldTest extends OptionsFieldUnitTestBase { * * @var array */ - public static $modules = array('options'); + public static $modules = ['options']; /** * Test that allowed values can be updated. */ - function testUpdateAllowedValues() { + public function testUpdateAllowedValues() { // All three options appear. $entity = EntityTest::create(); $form = \Drupal::service('entity.form_builder')->getForm($entity); @@ -81,9 +81,9 @@ function testUpdateAllowedValues() { 'required' => TRUE, ])->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'options_buttons', - )) + ]) ->save(); $entity = EntityTest::create(); $form = \Drupal::service('entity.form_builder')->getForm($entity); diff --git a/core/modules/options/tests/src/Kernel/OptionsFieldUnitTestBase.php b/core/modules/options/tests/src/Kernel/OptionsFieldUnitTestBase.php index 7dd7cbee..9098b818 100644 --- a/core/modules/options/tests/src/Kernel/OptionsFieldUnitTestBase.php +++ b/core/modules/options/tests/src/Kernel/OptionsFieldUnitTestBase.php @@ -16,7 +16,7 @@ abstract class OptionsFieldUnitTestBase extends FieldKernelTestBase { * * @var array */ - public static $modules = array('options'); + public static $modules = ['options']; /** * The field name used in the test. @@ -53,15 +53,15 @@ protected function setUp() { parent::setUp(); $this->container->get('router.builder')->rebuild(); - $this->fieldStorageDefinition = array( + $this->fieldStorageDefinition = [ 'field_name' => $this->fieldName, 'entity_type' => 'entity_test', 'type' => 'list_integer', 'cardinality' => 1, - 'settings' => array( - 'allowed_values' => array(1 => 'One', 2 => 'Two', 3 => 'Three'), - ), - ); + 'settings' => [ + 'allowed_values' => [1 => 'One', 2 => 'Two', 3 => 'Three'], + ], + ]; $this->fieldStorage = FieldStorageConfig::create($this->fieldStorageDefinition); $this->fieldStorage->save(); @@ -72,9 +72,9 @@ protected function setUp() { $this->field->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'options_buttons', - )) + ]) ->save(); } diff --git a/core/modules/options/tests/src/Kernel/OptionsFormattersTest.php b/core/modules/options/tests/src/Kernel/OptionsFormattersTest.php index 632900e9..93607f6f 100644 --- a/core/modules/options/tests/src/Kernel/OptionsFormattersTest.php +++ b/core/modules/options/tests/src/Kernel/OptionsFormattersTest.php @@ -33,7 +33,7 @@ public function testFormatter() { $this->assertEqual($build['#formatter'], 'list_default', 'Ensure to fall back to the default formatter.'); $this->assertEqual($build[0]['#markup'], 'One'); - $build = $items->view(array('type' => 'list_key')); + $build = $items->view(['type' => 'list_key']); $this->assertEqual($build['#formatter'], 'list_key', 'The chosen formatter is used.'); $this->assertEqual((string) $build[0]['#markup'], 1); } diff --git a/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php b/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php index 060c05ec..c5f2902d 100644 --- a/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php +++ b/core/modules/options/tests/src/Kernel/Views/FileViewsDataTest.php @@ -19,7 +19,7 @@ class FileViewsDataTest extends ViewsKernelTestBase { * * @var array */ - public static $modules = array('file', 'views', 'entity_test', 'user', 'field'); + public static $modules = ['file', 'views', 'entity_test', 'user', 'field']; /** * Tests views data generated for file field relationship. @@ -29,16 +29,16 @@ class FileViewsDataTest extends ViewsKernelTestBase { */ public function testRelationshipViewsData() { // Create file field to entity_test. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'entity_type' => 'entity_test', 'field_name' => 'field_base_file', 'type' => 'file', - ))->save(); - FieldConfig::create(array( + ])->save(); + FieldConfig::create([ 'entity_type' => 'entity_test', 'field_name' => 'field_base_file', 'bundle' => 'entity_test', - ))->save(); + ])->save(); // Check the generated views data. $views_data = Views::viewsData()->get('entity_test__field_base_file'); $relationship = $views_data['field_base_file_target_id']['relationship']; @@ -59,16 +59,16 @@ public function testRelationshipViewsData() { $this->assertEqual($relationship['join_extra'][0], ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE]); // Create file field to entity_test_mul. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'entity_type' => 'entity_test_mul', 'field_name' => 'field_data_file', 'type' => 'file', - ))->save(); - FieldConfig::create(array( + ])->save(); + FieldConfig::create([ 'entity_type' => 'entity_test_mul', 'field_name' => 'field_data_file', 'bundle' => 'entity_test_mul', - ))->save(); + ])->save(); // Check the generated views data. $views_data = Views::viewsData()->get('entity_test_mul__field_data_file'); $relationship = $views_data['field_data_file_target_id']['relationship']; diff --git a/core/modules/options/tests/src/Kernel/Views/OptionsListFilterTest.php b/core/modules/options/tests/src/Kernel/Views/OptionsListFilterTest.php index c62b2754..bc377b09 100644 --- a/core/modules/options/tests/src/Kernel/Views/OptionsListFilterTest.php +++ b/core/modules/options/tests/src/Kernel/Views/OptionsListFilterTest.php @@ -35,4 +35,78 @@ public function testViewsTestOptionsListFilter() { $this->assertIdenticalResultset($view, $resultset, $column_map); } + /** + * Tests options list field filter when grouped. + */ + public function testViewsTestOptionsListGroupedFilter() { + $view = Views::getView('test_options_list_filter'); + + $filters = [ + 'field_test_list_string_value' => [ + 'id' => 'field_test_list_string_value', + 'table' => 'field_data_field_test_list_string', + 'field' => 'field_test_list_string_value', + 'relationship' => 'none', + 'group_type' => 'group', + 'admin_label' => '', + 'operator' => 'or', + 'value' => [ + 'man' => 'man', + 'woman' => 'woman', + ], + 'group' => '1', + 'exposed' => TRUE, + 'expose' => [ + 'operator_id' => 'field_test_list_string_value_op', + 'label' => 'list-text', + 'description' => '', + 'identifier' => 'field_test_list_string_value', + ], + 'is_grouped' => TRUE, + 'group_info' => [ + 'label' => 'list-text (field_list_text)', + 'description' => '', + 'identifier' => 'field_test_list_string_value', + 'optional' => TRUE, + 'widget' => 'radios', + 'multiple' => TRUE, + 'remember' => FALSE, + 'default_group' => '1', + 'group_items' => [ + 1 => [ + 'title' => 'First', + 'operator' => 'or', + 'value' => [ + $this->fieldValues[0] => $this->fieldValues[0], + ] + ], + 2 => [ + 'title' => 'Second', + 'operator' => 'or', + 'value' => [ + $this->fieldValues[1] => $this->fieldValues[1], + ] + ], + ], + ], + 'reduce_duplicates' => '', + 'plugin_id' => 'list_field', + ] + ]; + $view->setDisplay(); + $view->displayHandlers->get('default')->overrideOption('filters', $filters); + + $view->storage->save(); + + $this->executeView($view); + + $resultset = [ + ['nid' => $this->nodes[0]->nid->value], + ['nid' => $this->nodes[1]->nid->value], + ]; + + $column_map = ['nid' => 'nid']; + $this->assertIdenticalResultset($view, $resultset, $column_map); + } + } diff --git a/core/modules/outside_in/css/offcanvas.css b/core/modules/outside_in/css/offcanvas.css deleted file mode 100644 index fb671dbb..00000000 --- a/core/modules/outside_in/css/offcanvas.css +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file - * CSS for Offcanvas tray. - * - * @todo Move CSS into core dialog library https://www.drupal.org/node/2784443. - */ -/* Position the dialog-offcanvas tray container outside the right of the viewport. */ -.ui-dialog-offcanvas { - box-sizing: border-box; - height: 100%; - overflow: visible; -} - -/* Wrap the form that's inside the dialog-offcanvas tray. */ -.ui-dialog-offcanvas .ui-dialog-content { - padding: 0 20px; - /* Prevent horizontal scrollbar. */ - overflow-x: hidden; - overflow-y: auto; -} -[dir="rtl"] .ui-dialog-offcanvas .ui-dialog-content { - text-align: right; -} diff --git a/core/modules/outside_in/css/offcanvas.motion.css b/core/modules/outside_in/css/offcanvas.motion.css deleted file mode 100644 index 1c069940..00000000 --- a/core/modules/outside_in/css/offcanvas.motion.css +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file - * Motion effects for off-canvas tray dialog. - * - * Motion effects are in a separate file so that they can be easily turned off - * to improve performance if desired. - * - * @todo Move motion effects file into a core Off-Canvas library and add a - * configuration option for browser rendering performance to disable this - * file: https://www.drupal.org/node/2784443. - */ - -/* Transition the dialog-offcanvas tray container, with 2s delay to match main canvas speed. */ -.ui-dialog-offcanvas .ui-dialog-content { - -webkit-transition: all .7s ease 2s; - -moz-transition: all .7s ease 2s; - transition: all .7s ease 2s; -} - -@media (max-width: 700px) { - .ui-dialog-offcanvas .ui-dialog-content { - -webkit-transition: all .7s ease; - -moz-transition: all .7s ease; - transition: all .7s ease; - } -} - -.dialog-offcanvas__main-canvas { - -webkit-transition: all .7s ease; - -moz-transition: all .7s ease; - transition: all .7s ease; -} diff --git a/core/modules/outside_in/css/outside_in.details.css b/core/modules/outside_in/css/outside_in.details.css deleted file mode 100644 index 8ca1406f..00000000 --- a/core/modules/outside_in/css/outside_in.details.css +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file - * Visual styling for summary and details in the Settings Tray module's off canvas tray. - */ - -.ui-dialog-outside-in details, -.ui-dialog-outside-in summary, -.ui-dialog-outside-in .ui-dialog-content { - background: #474747; - color: #ddd; -} -.ui-dialog-outside-in summary a { - color: #ddd; - padding-top: 0; - padding-bottom: 0; -} -.ui-dialog-outside-in summary a:hover, -.ui-dialog-outside-in summary a:focus { - color: #fff; -} -.ui-dialog-outside-in details, -.ui-dialog-outside-in summary, -.ui-dialog-outside-in .details-wrapper { - border-width: 0; - /* Cancel out the padding of the parent. */ - margin: 0 -20px; - padding: 0 20px; -} -.ui-dialog-outside-in summary { - text-shadow: none; - outline: none; - padding: 10px 20px; - font-size: 14px; - transition: all .5s ease; -} -.ui-dialog-outside-in summary:hover, -.ui-dialog-outside-in summary:focus { - background-color: #222; - outline: none; -} -.ui-dialog-outside-in details[open] { - background-color: #333; - padding-bottom: 10px; -} -.ui-dialog-outside-in details[open] > summary { - background-color: #333; - color: #eee; -} -.ui-dialog-outside-in details[open] > summary:hover { - background-color: #222; - color: #fff; -} diff --git a/core/modules/outside_in/css/outside_in.form.css b/core/modules/outside_in/css/outside_in.form.css deleted file mode 100644 index 5d4c3be8..00000000 --- a/core/modules/outside_in/css/outside_in.form.css +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file - * Visual styling for forms in the Settings Tray module's off canvas tray. - */ - -.ui-dialog-outside-in label { - line-height: normal; - font-size: 12px; - font-weight: normal; - color: #ddd; -} -.ui-dialog-outside-in .description, -.ui-dialog-outside-in .form-item .description, -.ui-dialog-outside-in .details-description { - color: #ddd; - margin-top: 5px; - font-size: 12px; - font-style: normal; -} -.ui-dialog-outside-in .details-wrapper .description { - color: #bbb; -} -.ui-dialog-outside-in .form-item { - margin-bottom: 10px; - margin-top: 10px; -} -/* Set size and position for all inputs. */ -.ui-dialog-outside-in .form-select, -.ui-dialog-outside-in .form-text, -.ui-dialog-outside-in .form-tel, -.ui-dialog-outside-in .form-email, -.ui-dialog-outside-in .form-url, -.ui-dialog-outside-in .form-search, -.ui-dialog-outside-in .form-number, -.ui-dialog-outside-in .form-color, -.ui-dialog-outside-in .form-file, -.ui-dialog-outside-in .form-textarea, -.ui-dialog-outside-in .form-date, -.ui-dialog-outside-in .form-time { - box-sizing: border-box; - max-width: 100%; - padding: 6px; - margin-top: 5px; - margin-right: 0; - margin-bottom: 0; - margin-left: 0; - border-width: 1px; - border-radius: 2px; - outline: 0; - display: block; - font-size: 14px; - line-height: 16px; - cursor: pointer; -} -/* Reduce contrast for fields against dark backround. */ -.ui-dialog-outside-in .form-text, -.ui-dialog-outside-in .form-tel, -.ui-dialog-outside-in .form-email, -.ui-dialog-outside-in .form-url, -.ui-dialog-outside-in .form-search, -.ui-dialog-outside-in .form-number, -.ui-dialog-outside-in .form-color, -.ui-dialog-outside-in .form-file, -.ui-dialog-outside-in .form-textarea, -.ui-dialog-outside-in .form-date, -.ui-dialog-outside-in .form-time { - box-shadow: inset 0 1px 2px rgba(0, 0, 0, .125); - background-color: #eee; - border-color: #333; - color: #595959; -} -.ui-dialog-outside-in .form-text:focus, -.ui-dialog-outside-in .form-tel:focus, -.ui-dialog-outside-in .form-email:focus, -.ui-dialog-outside-in .form-url:focus, -.ui-dialog-outside-in .form-search:focus, -.ui-dialog-outside-in .form-number:focus, -.ui-dialog-outside-in .form-color:focus, -.ui-dialog-outside-in .form-file:focus, -.ui-dialog-outside-in .form-textarea:focus, -.ui-dialog-outside-in .form-date:focus, -.ui-dialog-outside-in .form-time:focus { - border-color: #40b6ff; - box-shadow: inset 0 1px 3px rgba(0, 0, 0, .125), 0 0 8px #40b6ff; - background-color: #fff; -} -.ui-dialog-outside-in input[type="checkbox"], -.ui-dialog-outside-in .checkbox, -.ui-dialog-outside-in input[type="radio"], -.ui-dialog-outside-in .radio { - position: static; - margin: 0; -} -.ui-dialog-outside-in td .checkbox { - display: table-cell; - line-height: normal; - vertical-align: middle; -} -.ui-dialog-outside-in .form-checkbox, -.ui-dialog-outside-in .form-radio { - /* Add contrast for dark background. */ - box-shadow: 0 0 2px 1px #000; -} -.ui-dialog-outside-in input[type="radio"] { - /* Add full circular radius. */ - border-radius: 50%; -} -.ui-dialog-outside-in .form-actions { - text-align: center; -} diff --git a/core/modules/outside_in/css/outside_in.module.css b/core/modules/outside_in/css/outside_in.module.css deleted file mode 100644 index 5ac00ab4..00000000 --- a/core/modules/outside_in/css/outside_in.module.css +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file - * Styling for Settings Tray module. - */ -/* - * Position the edit toolbar tab. - * @todo Move changes into contextual module when Settings Tray is not - * experimental: https://www.drupal.org/node/2784591. - */ -.toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab { - float: left; -} -[dir="rtl"] .toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab { - float: right; -} - -#main-canvas.js-outside-in-edit-mode a, -#main-canvas.js-outside-in-edit-mode input { - pointer-events: none; -} -#main-canvas.js-outside-in-edit-mode .contextual-links a { - pointer-events: inherit; -} - -/* - * Force the tray to be 100% width at the same breakpoint the dialog system uses - * to expand dialog widths. - */ -@media all and (max-width: 48em) { /* 768px */ - .ui-dialog.ui-dialog-offcanvas { - width: 100% !important; - } - /* When tray is at 100% width stop the body from scrolling */ - .js-tray-open { - height: 100%; - overflow-y: hidden; - } -} diff --git a/core/modules/outside_in/css/outside_in.motion.css b/core/modules/outside_in/css/outside_in.motion.css deleted file mode 100644 index 450bffe7..00000000 --- a/core/modules/outside_in/css/outside_in.motion.css +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file - * Motion effects for Settings Tray module. - * - * Motion effects are in a separate file so that they can be easily turned off - * to improve performance if desired. - * - * @todo Move motion effects file into a core Off-Canvas library and add a - * configuration option for browser rendering performance to disable this - * file: https://www.drupal.org/node/2784443. - */ - - -/* Transition the edit icon in the toolbar. */ -#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { - -webkit-transition: all .7s ease; - -moz-transition: all .7s ease; - transition: all .7s ease; -} - -/* Transition the editables on the page, their contextual links and their hover states. */ -.dialog-offcanvas__main-canvas .contextual, -.dialog-offcanvas__main-canvas .js-outside-in-edit-mode .outside-in-editable, -.dialog-offcanvas__main-canvas.js-tray-open .js-outside-in-edit-mode .outside-in-editable { - -webkit-transition: all .7s ease; - -moz-transition: all .7s ease; - transition: all .7s ease; -} - -/* Transition the position of the toolbar. */ -.toolbar-fixed, -.toolbar-tray-open { - -webkit-transition: all .5s ease; - -moz-transition: all .5s ease; - transition: all .5s ease; -} - -/* Transition the administration tray. -#toolbar-administration, -#toolbar-administration * { - -webkit-transition: all .7s ease; - -moz-transition: all .7s ease; - transition: all .7s ease; -}*/ diff --git a/core/modules/outside_in/css/outside_in.table.css b/core/modules/outside_in/css/outside_in.table.css deleted file mode 100644 index dc6bb895..00000000 --- a/core/modules/outside_in/css/outside_in.table.css +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file - * Visual styling for tables in the Settings Tray module's off canvas tray. - */ - -.ui-dialog-outside-in table { - border: 0; - border-collapse: collapse; - min-width: 300px; - margin-top: 0; - /* Cancel out the padding of the parent to make the table full width and flush to the bottom. */ - margin-right: -20px; - margin-left: -20px; - margin-bottom: -10px; -} -.ui-dialog-outside-in tr th { - padding: 2px 4px; - background-color: transparent; - border: 0; - border-collapse: collapse; - font-size: 12px; - color: #bbb; - text-align: left; /* LTR */ -} -[dir="rtl"] .ui-dialog-outside-in tr th { - text-align: right; -} -.ui-dialog-outside-in tr, -.ui-dialog-outside-in tr td { - padding: 2px 4px; - height: 35px; - vertical-align: middle; - text-align: left; /* LTR */ - border: 0px; - border-style: solid; - border-color: #777; - border-bottom-width: 1px; - background: none; - background-color: transparent; - font-size: 12px; -} -[dir="rtl"] .ui-dialog-outside-in tr th, -[dir="rtl"] .ui-dialog-outside-in tr td { - text-align: right; -} -.ui-dialog-outside-in td a { - display: block; - max-width: 120px; - overflow: hidden; -} -.ui-dialog.ui-dialog-outside-in tr td:first-child, -.ui-dialog.ui-dialog-outside-in tr th:first-child { - padding-left: 20px; /* LTR */ - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} -[dir="rtl"] .ui-dialog.ui-dialog-outside-in tr td:first-child, -[dir="rtl"] .ui-dialog.ui-dialog-outside-in tr th:first-child { - padding-right: 20px; -} -.ui-dialog-outside-in tr.odd, -.ui-dialog-outside-in tr.even { - background-image: none; - background-color: transparent; -} -td.checkbox, -th.checkbox { - text-align: center; - width: 20px; -} - diff --git a/core/modules/outside_in/css/outside_in.tabledrag.css b/core/modules/outside_in/css/outside_in.tabledrag.css deleted file mode 100644 index e9d825fd..00000000 --- a/core/modules/outside_in/css/outside_in.tabledrag.css +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file - * Table drag behavior for Settings Tray module. - * - * @see tabledrag.js - */ - - -/* Because base font sizes will vary widely across themes, to maintain consistency outside-in uses only pixels. */ - -.ui-dialog-outside-in body.drag { - cursor: move; -} -.ui-dialog-outside-in tr.region-title { - font-weight: normal; -} -.ui-dialog-outside-in tr.region-message { - color: #fff; -} -.ui-dialog-outside-in tr.region-populated { - display: none; -} -.ui-dialog-outside-in tr.add-new .tabledrag-changed { - display: none; -} -.ui-dialog-outside-in .draggable a.tabledrag-handle { - background-image: none; - margin: 0; - margin-left: 0; /* LTR */ - margin-right: 5px; /* LTR */ - height: auto; - min-width: 20px; - padding: 0; - overflow: hidden; - float: left; /* LTR */ - text-decoration: none; - cursor: move; -} -[dir="rtl"] .ui-dialog-outside-in .draggable a.tabledrag-handle { - float: right; - margin-right: 0; - margin-left: 5px; -} -.ui-dialog-outside-in a.tabledrag-handle .handle { - /* Use lighter drag icon against dark background. */ - background-image: url(../../../misc/icons/bebebe/move.svg); - background-repeat: no-repeat; - background-position: center; - height: auto; - margin: 0; - padding: 0; - width: auto; -} -.ui-dialog-outside-in .draggable a.tabledrag-handle:hover .handle, -.ui-dialog-outside-in .draggable a.tabledrag-handle:focus .handle { - background-image: url(../../../misc/icons/787878/move.svg); - text-decoration: none; -} - -.ui-dialog-outside-in .touchevents .draggable td { - padding: 0 10px; -} -.ui-dialog-outside-in .touchevents .draggable .menu-item__link { - display: inline-block; - padding: 10px 0; -} -.ui-dialog-outside-in .touchevents a.tabledrag-handle { - height: 44px; - width: 40px; -} -.ui-dialog-outside-in .touchevents a.tabledrag-handle .handle { - background-position: 40% 19px; /* LTR */ - height: 21px; -} -[dir="rtl"] .ui-dialog-outside-in .touch a.tabledrag-handle .handle { - background-position: right 40% top 19px; -} -.ui-dialog-outside-in .touchevents .draggable.drag a.tabledrag-handle .handle { - background-position: 50% -32px; -} -.ui-dialog-outside-in .tabledrag-toggle-weight-wrapper { - text-align: right; /* LTR */ -} -[dir="rtl"] .ui-dialog-outside-in .tabledrag-toggle-weight-wrapper { - text-align: left; -} -.ui-dialog-outside-in .indentation { - float: left; /* LTR */ - height: auto; - margin: 0 3px 0 -10px; /* LTR */ - padding: 0 0 0 10px; /* LTR */ - width: auto; -} -[dir="rtl"] .ui-dialog-outside-in .indentation { - float: right; - margin: 0 -10px 0 3px; - padding: 0 10px 0 0; -} -.ui-dialog-outside-in tr.drag { - background-color: #555; -} -.ui-dialog-outside-in tr.drag-previous { - background-color: #000; -} diff --git a/core/modules/outside_in/css/outside_in.theme.css b/core/modules/outside_in/css/outside_in.theme.css deleted file mode 100644 index 91c01abf..00000000 --- a/core/modules/outside_in/css/outside_in.theme.css +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @file - * Visual styling for Settings Tray module. - */ - -/* @todo Move this into toolbar when this module is no longer experimental: - * https://www.drupal.org/node/2784593. - */ - -/* Style the edit mode toolbar and tabs. */ -#toolbar-bar.js-outside-in-edit-mode { - background-color: #fff; -} -.js-outside-in-edit-mode .toolbar-item:not(.toolbar-icon-edit) { - color: #999; -} -.js-outside-in-edit-mode .toolbar-item:not(.toolbar-icon-edit) .is-active { - color: #333; -} - -/* Style both the edit and editing states of the contextual links toggle tab. */ -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item, -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active, -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:focus { - background-color: #50a0e9; - background-image: linear-gradient(to bottom, #007bc6, #0071b8); - color: #ddd; - text-shadow: none; - font-weight: bold; - outline: none; -} -/* Make the hover of the inactive state the same as the active state. */ -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:hover, -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active { - background-image: linear-gradient(to bottom, #0c97ed, #1f86c7); - color: #fff; -} -/* Make the hover of the active state the same as the inactive state. */ -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:hover { - background-color: #2369a6; - background-image: linear-gradient(to bottom, #007bc6, #0071b8); - color: #fff; -} -/* Make the inactive icon grey. */ -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:before { - background-image: url(../../../misc/icons/bebebe/pencil.svg); -} -/* Make the active icon white. */ -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:before { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:hover:before { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} -.toolbar-tab > .toolbar-icon.toolbar-icon-edit.toolbar-item:hover > .toolbar-icon-edit:before { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} -.toolbar-tab > .button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} - -/* Style the editables while in edit mode. */ -.dialog-offcanvas__main-canvas.js-outside-in-edit-mode .outside-in-editable { - outline: 1px dashed rgba(0,0,0,0.5); - box-shadow: 0 0 0 1px rgba(255,255,255,0.7); -} -.dialog-offcanvas__main-canvas.js-outside-in-edit-mode .outside-in-editable:hover, -.dialog-offcanvas__main-canvas.js-outside-in-edit-mode .outside-in-editable.outside-in-active-editable { - background-color: rgba(0,0,0,0.2); -} - -/* Style the dialog-offcanvas container. */ -.ui-dialog-outside-in { - background: #444; - border: 0 solid transparent; - border-radius: 0; - box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.3333); - padding: 0; - color: #ddd; - /* Layer the dialog just under the toolbar. */ - z-index: 501; -} - -/* Style content in the tray. */ -.ui-dialog-outside-in p, -.ui-dialog-outside-in h1, -.ui-dialog-outside-in h2, -.ui-dialog-outside-in h3, -.ui-dialog-outside-in h4, -.ui-dialog-outside-in h5, -.ui-dialog-outside-in h6, -.ui-dialog-outside-in pre, -.ui-dialog-outside-in legend, -.ui-dialog-outside-in cite, -.ui-dialog-outside-in span, -.ui-dialog-outside-in summary, -.ui-dialog-outside-in details, -.ui-dialog-outside-in .form-item { - color: #ddd; - font-family: "Lucida Grande", 'Lucida Sans Unicode','liberation sans', sans-serif; - font-size: 14px; - font-weight: normal; - background-color: transparent; - text-shadow: none; -} -.ui-dialog-outside-in a, -.ui-dialog-outside-in .link { - border-bottom: none; - font-family: "Lucida Grande", 'Lucida Sans Unicode','liberation sans', sans-serif; - font-size: 14px; - font-weight: normal; - color: #85bef4; - text-decoration: none; - transition: color .5s ease; -} -.ui-dialog-outside-in a:focus, -.ui-dialog-outside-in .link:focus, -.ui-dialog-outside-in a:hover, -.ui-dialog-outside-in .link:hover { - outline: none; - color: #46a0f5; -} - -/* Style the tray header. */ -.ui-dialog-outside-in .ui-dialog-titlebar { - padding: 20px; - background: #2d2d2d; - border: 0; - border-bottom: 1px solid #000; - border-radius: 0; - font-weight: normal; - color: #fff; -} -.ui-dialog-outside-in .ui-dialog-titlebar-close { - background-image: url(../../../misc/icons/bebebe/ex.svg); - background-position: center center; - background-repeat: no-repeat; - background-color: transparent; - border: 0; - position: absolute; - right: 20px; - -moz-transition: all .5s ease; - transition: background .5s ease; -} -.ui-dialog-outside-in .ui-dialog-titlebar-close:hover { - background-image: url(../../../misc/icons/ffffff/ex.svg); -} -[dir="rtl"] .ui-dialog-outside-in .ui-dialog-titlebar-close { - left: 20px; - right: auto; -} -.ui-dialog-outside-in .ui-dialog-title { - font-size: 16px; - margin: 0; - /* Push the text away from the icon. */ - padding-left: 30px; /* LTR */ - padding-right: 0px; /* LTR */ - /* Ensure that long titles do not overlap the close button. */ - max-width: 210px; - text-align: left; /* LTR */ -} -[dir="rtl"] .ui-dialog-outside-in .ui-dialog-title { - text-align: right; - padding-left: 0px; - padding-right: 0px; -} -.ui-dialog-outside-in .ui-dialog-title:before { - background: transparent url(../../../misc/icons/ffffff/pencil.svg) no-repeat scroll center center; - background-size: 100% auto; - content: ''; - display: block; - height: 100%; - position: absolute; - left: 20px; /* LTR */ - top: 0; - width: 20px; -} -[dir="rtl"] .ui-dialog-outside-in .ui-dialog-title:before { - left: auto; - right: 20px; -} - -/* Override default styling from jquery UI. */ -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - border: 0; - font-weight: normal; - font-size: 14px; - color: #333; -} -/* Hide the defauld Jquery UI dialog close button. */ -.ui-dialog-outside-in .ui-icon-closethick { - visibility: hidden; -} - -/* Groups below here with todos to move to new component need to load last. */ - -/** - * Visual styling for buttons in the Settings Tray module's off canvas tray. - * @todo Move to its own component: - * https://www.drupal.org/node/1945262. - */ - -.ui-dialog-outside-in button.link { - background: transparent; - border: 0; - cursor: pointer; - margin: 0; - padding: 0; -} -.ui-dialog-outside-in .button { - width: 100%; - height: auto; - margin: 1em auto; - padding: 6px 1em; - background: #7b7b7b; - border-radius: 1em; - font-size: 14px; - color: #fff; - transition: all .5s ease; -} -.ui-dialog-outside-in .button:hover, -.ui-dialog-outside-in .button:focus { - background: #888; -} -.ui-dialog-outside-in .button--primary { - background: #277abd none; - border: none; - color: #fff; - transition: all .5s ease; -} -.ui-dialog-outside-in .button--primary:hover, -.ui-dialog-outside-in .button--primary:focus { - background: #2b8bd8; -} - - -/* - * Visual styling for dropbutton in the Settings Tray module's off canvas tray. - * @todo Move to its own component: - * https://www.drupal.org/node/1945262. - */ - -.ui-dialog-outside-in .dropbutton-widget { - background: #7b7b7b none; - border: 0; - border-radius: 1em; - color: #eee; - transition: background .5s ease; -} -.ui-dialog-outside-in .dropbutton-widget:hover { - box-shadow: 0 2px 2px 1px rgba(0,0,0,0.5); -} -.ui-dialog-outside-in .dropbutton-toggle button { - background: #7b7b7b none; - border-bottom-right-radius: 1em; /* LTR */ - border-top-right-radius: 1em; /* LTR */ - border-style: solid; - border-color: #333; - border-left-width: 1px; /* LTR */ - transition: background .5s ease; -} -[dir="rtl"] .ui-dialog-outside-in .dropbutton-toggle button { - border-radius: 0; - border-bottom-left-radius: 1em; - border-top-left-radius: 1em; - border-width: 0; - border-right-width: 1px; -} -.ui-dialog-outside-in .dropbutton .dropbutton-action:hover, -.ui-dialog-outside-in .dropbutton a:hover { - background: #6b6b6b none; - border-bottom-left-radius: 1em; /* LTR */ - border-top-left-radius: 1em; /* LTR */ -} -[dir="rtl"] .ui-dialog-outside-in .dropbutton .dropbutton-action:hover, -[dir="rtl"] .ui-dialog-outside-in .dropbutton a:hover { - border-radius: 0; - border-bottom-right-radius: 1em; - border-top-right-radius: 1em; -} -.ui-dialog-outside-in .dropbutton a { - padding: 0.1em 0.8em; - color: #eee; - font-size: 90%; - line-height: 1.8; - transition: all .5s ease; -} -.ui-dialog-outside-in .dropbutton:hover a { - color: #fff; -} -/* Make an arrow out of borders with some fancy CSS. */ -.ui-dialog-outside-in span.dropbutton-arrow { - border-bottom-color: transparent; - border-left-color: transparent; - border-right-color: transparent; - border-style: solid; - border-width: 0.3333em 0.3333em 0; - display: block; - height: 0; - line-height: 0; - position: absolute; - right: 40%; - top: 50%; - margin-top: -0.1666em; - width: 0; - overflow: hidden; - color: #fff; -} -.js .ui-dialog-outside-in .dropbutton-toggle .dropbutton-arrow:hover { - background: transparent; -} -.ui-dialog-outside-in td .dropbutton-multiple { - padding-right: 0; -} -[dir="rtl"].ui-dialog-outside-in td .dropbutton-multiple { - padding-left: 0; -} -.ui-dialog-outside-in td .dropbutton-multiple .dropbutton { - border-right: 0; - border-left: 0; -} -.ui-dialog-outside-in td .dropbutton .secondary-action { - border-top-color: #000; -} diff --git a/core/modules/outside_in/css/outside_in.toolbar.css b/core/modules/outside_in/css/outside_in.toolbar.css deleted file mode 100644 index 3f7e0447..00000000 --- a/core/modules/outside_in/css/outside_in.toolbar.css +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * Visual styling for the toolbar when Settings Tray module is enabled. - */ - -/* @todo Move this into toolbar when module is not experimental: - * https://www.drupal.org/node/2784593. - */ - -/* Style the edit mode toolbar and tabs. */ -#toolbar-bar.js-outside-in-edit-mode { - background-color: #fff; -} -#toolbar-bar.js-outside-in-edit-mode .toolbar-item { - color: #999; -} -#toolbar-bar.js-outside-in-edit-mode .toolbar-item .is-active { - color: #333; -} - -/* Style both the edit and editing states of the contextual links toggle tab. */ -.toolbar-icon-edit.toolbar-item { - background-color: #50a0e9; - background-image: -webkit-linear-gradient(top, #007bc6, #0071b8); - background-image: linear-gradient(to bottom, #007bc6, #0071b8); - color: #eee; - text-shadow: 0 1px hsla(0, 0%, 0%, 0.5); - font-weight: 700; - -webkit-font-smoothing: antialiased; -} -.toolbar-icon-edit.toolbar-item.is-active { - background-color: #50a0e9; - background-image: -webkit-linear-gradient(top, #007bc6, #0071b8); - background-image: linear-gradient(to bottom, #007bc6, #0071b8); - color: #eee; - text-shadow: 0 1px hsla(0, 0%, 0%, 0.5); - font-weight: 700; - -webkit-font-smoothing: antialiased; -} -.toolbar-tab:hover > .toolbar-icon-edit, -.toolbar-icon-edit:focus .toolbar-item { - background-color: #2369a6; - background-image: -webkit-linear-gradient(top, #0c97ed, #1f86c7); - background-image: linear-gradient(to bottom, #0c97ed, #1f86c7); - border-color: #1e5c90; - color: #fff; - outline: none; -} -.toolbar-icon.toolbar-icon-edit.toolbar-item:before, -button.toolbar-icon.toolbar-icon-edit.toolbar-item:before { - background-image: url(../../../misc/icons/bebebe/pencil.svg); -} -.toolbar-icon.toolbar-icon-edit.toolbar-item:before:hover, -button.toolbar-icon.toolbar-icon-edit.toolbar-item:before:focus { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} -.toolbar-icon.toolbar-icon-edit.toolbar-item:hover > .toolbar-icon-edit:before { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} -#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { - background-image: url(../../../misc/icons/ffffff/pencil.svg); -} - -#toolbar-bar.js-outside-in-edit-mode button.toolbar-icon.toolbar-icon-edit.toolbar-item.is-active { - background-image: none; - color: #fff; -} -#toolbar-bar.js-outside-in-edit-mode button.toolbar-icon.toolbar-icon-edit.toolbar-item.is-active:hover { - background-image: linear-gradient(to bottom, #0094f0, #0e69be); -} diff --git a/core/modules/outside_in/js/offcanvas.js b/core/modules/outside_in/js/offcanvas.js deleted file mode 100644 index 8cda69d5..00000000 --- a/core/modules/outside_in/js/offcanvas.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file - * Drupal's off-canvas library. - * - * @todo This functionality should extracted into a new core library or a part - * of the current drupal.dialog.ajax library. - * https://www.drupal.org/node/2784443 - */ - -(function ($, Drupal, debounce, displace) { - - 'use strict'; - - // The minimum width to use body displace needs to match the width at which - // the tray will be %100 width. @see outside_in.module.css - var minDisplaceWidth = 768; - - /** - * The edge of the screen that the dialog should appear on. - * - * @type {string} - */ - var edge = document.documentElement.dir === 'rtl' ? 'left' : 'right'; - - var $mainCanvasWrapper = $('[data-offcanvas-main-canvas]'); - - /** - * Resets the size of the dialog. - * - * @param {jQuery.Event} event - * The event triggered. - */ - function resetSize(event) { - var offsets = displace.offsets; - var $element = event.data.$element; - var $widget = $element.dialog('widget'); - - var adjustedOptions = { - // @see http://api.jqueryui.com/position/ - position: { - my: edge + ' top', - at: edge + ' top' + (offsets.top !== 0 ? '+' + offsets.top : ''), - of: window - } - }; - - $widget.css({ - position: 'fixed', - height: ($(window).height() - (offsets.top + offsets.bottom)) + 'px' - }); - - $element - .dialog('option', adjustedOptions) - .trigger('dialogContentResize.offcanvas'); - } - - /** - * Adjusts the dialog on resize. - * - * @param {jQuery.Event} event - * The event triggered. - */ - function handleDialogResize(event) { - var $element = event.data.$element; - var $widget = $element.dialog('widget'); - - var $offsets = $widget.find('> :not(#drupal-offcanvas, .ui-resizable-handle)'); - var offset = 0; - var modalHeight; - - // Let scroll element take all the height available. - $element.css({height: 'auto'}); - modalHeight = $widget.height(); - $offsets.each(function () { offset += $(this).outerHeight(); }); - - // Take internal padding into account. - var scrollOffset = $element.outerHeight() - $element.height(); - $element.height(modalHeight - offset - scrollOffset); - } - - /** - * Adjusts the body padding when the dialog is resized. - * - * @param {jQuery.Event} event - * The event triggered. - */ - function bodyPadding(event) { - if ($('body').outerWidth() < minDisplaceWidth) { - return; - } - var $element = event.data.$element; - var $widget = $element.dialog('widget'); - - var width = $widget.outerWidth(); - var mainCanvasPadding = $mainCanvasWrapper.css('padding-' + edge); - if (width !== mainCanvasPadding) { - $mainCanvasWrapper.css('padding-' + edge, width + 'px'); - $widget.attr('data-offset-' + edge, width); - displace(); - } - } - - $(window).on({ - 'dialog:aftercreate': function (event, dialog, $element, settings) { - if ($element.is('#drupal-offcanvas')) { - var eventData = {settings: settings, $element: $element}; - $('.ui-dialog-offcanvas, .ui-dialog-offcanvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title); - - $element - .on('dialogresize.offcanvas', eventData, debounce(bodyPadding, 100)) - .on('dialogContentResize.offcanvas', eventData, handleDialogResize) - .on('dialogContentResize.offcanvas', eventData, debounce(bodyPadding, 100)) - .trigger('dialogresize.offcanvas'); - - $element.dialog('widget').attr('data-offset-' + edge, ''); - - $(window) - .on('resize.offcanvas scroll.offcanvas', eventData, debounce(resetSize, 100)) - .trigger('resize.offcanvas'); - } - }, - 'dialog:beforecreate': function (event, dialog, $element, settings) { - if ($element.is('#drupal-offcanvas')) { - $('body').addClass('js-tray-open'); - // @see http://api.jqueryui.com/position/ - settings.position = { - my: 'left top', - at: edge + ' top', - of: window - }; - settings.dialogClass += ' ui-dialog-offcanvas'; - // Applies initial height to dialog based on window height. - // See http://api.jqueryui.com/dialog for all dialog options. - settings.height = $(window).height(); - } - }, - 'dialog:beforeclose': function (event, dialog, $element) { - if ($element.is('#drupal-offcanvas')) { - $('body').removeClass('js-tray-open'); - $(document).off('.offcanvas'); - $(window).off('.offcanvas'); - $mainCanvasWrapper.css('padding-' + edge, 0); - } - } - }); - -})(jQuery, Drupal, Drupal.debounce, Drupal.displace); diff --git a/core/modules/outside_in/js/outside_in.js b/core/modules/outside_in/js/outside_in.js deleted file mode 100644 index 0b8bc880..00000000 --- a/core/modules/outside_in/js/outside_in.js +++ /dev/null @@ -1,262 +0,0 @@ -/** - * @file - * Drupal's Settings Tray library. - */ - -(function ($, Drupal) { - - 'use strict'; - - var blockConfigureSelector = '[data-outside-in-edit]'; - var toggleEditSelector = '[data-drupal-outsidein="toggle"]'; - var itemsToToggleSelector = '[data-offcanvas-main-canvas], #toolbar-bar, [data-drupal-outsidein="editable"] a, [data-drupal-outsidein="editable"] button'; - var contextualItemsSelector = '[data-contextual-id] a, [data-contextual-id] button'; - var quickEditItemSelector = '[data-quickedit-entity-id]'; - - /** - * Reacts to contextual links being added. - * - * @param {jQuery.Event} event - * The `drupalContextualLinkAdded` event. - * @param {object} data - * An object containing the data relevant to the event. - * - * @listens event:drupalContextualLinkAdded - */ - $(document).on('drupalContextualLinkAdded', function (event, data) { - // Bind Ajax behaviors to all items showing the class. - // @todo Fix contextual links to work with use-ajax links in - // https://www.drupal.org/node/2764931. - Drupal.attachBehaviors(data.$el[0]); - - // Bind a listener to all 'Quick edit' links for blocks - // Click "Edit" button in toolbar to force Contextual Edit which starts - // Settings Tray edit mode also. - data.$el.find(blockConfigureSelector) - .on('click.outsidein', function () { - if (!isInEditMode()) { - $(toggleEditSelector).trigger('click.outsidein'); - } - // Always disable QuickEdit regardless of whether "EditMode" was just enabled. - disableQuickEdit(); - }); - }); - - $(document).on('keyup.outsidein', function (e) { - if (isInEditMode() && e.keyCode === 27) { - Drupal.announce( - Drupal.t('Exited edit mode.') - ); - toggleEditMode(); - } - }); - - /** - * Gets all items that should be toggled with class during edit mode. - * - * @return {jQuery} - * Items that should be toggled. - */ - function getItemsToToggle() { - return $(itemsToToggleSelector).not(contextualItemsSelector); - } - - /** - * Helper to check the state of the outside-in mode. - * - * @todo don't use a class for this. - * - * @return {boolean} - * State of the outside-in edit mode. - */ - function isInEditMode() { - return $('#toolbar-bar').hasClass('js-outside-in-edit-mode'); - } - - /** - * Helper to toggle Edit mode. - */ - function toggleEditMode() { - setEditModeState(!isInEditMode()); - } - - /** - * Prevent default click events except contextual links. - * - * In edit mode the default action of click events is suppressed. - * - * @param {jQuery.Event} event - * The click event. - */ - function preventClick(event) { - // Do not prevent contextual links. - if ($(event.target).closest('.contextual-links').length) { - return; - } - event.preventDefault(); - } - - /** - * Close any active toolbar tray before entering edit mode. - */ - function closeToolbarTrays() { - $(Drupal.toolbar.models.toolbarModel.get('activeTab')).trigger('click'); - } - - /** - * Disables the QuickEdit module editor if open. - */ - function disableQuickEdit() { - $('.quickedit-toolbar button.action-cancel').trigger('click'); - } - - /** - * Closes/removes offcanvas. - */ - function closeOffCanvas() { - $('.ui-dialog-offcanvas .ui-dialog-titlebar-close').trigger('click'); - } - - /** - * Helper to switch edit mode state. - * - * @param {boolean} editMode - * True enable edit mode, false disable edit mode. - */ - function setEditModeState(editMode) { - editMode = !!editMode; - var $editButton = $(toggleEditSelector); - var $editables; - // Turn on edit mode. - if (editMode) { - $editButton.text(Drupal.t('Editing')); - closeToolbarTrays(); - - $editables = $('[data-drupal-outsidein="editable"]').once('outsidein'); - if ($editables.length) { - // Use event capture to prevent clicks on links. - document.querySelector('[data-offcanvas-main-canvas]').addEventListener('click', preventClick, true); - - // When a click occurs try and find the outside-in edit link - // and click it. - $editables - .not(contextualItemsSelector) - .on('click.outsidein', function (e) { - // Contextual links are allowed to function in Edit mode. - if ($(e.target).closest('.contextual').length || !localStorage.getItem('Drupal.contextualToolbar.isViewing')) { - return; - } - $(e.currentTarget).find(blockConfigureSelector).trigger('click'); - disableQuickEdit(); - }); - $(quickEditItemSelector) - .not(contextualItemsSelector) - .on('click.outsidein', function (e) { - // For all non-contextual links or the contextual QuickEdit link close the off-canvas tray. - if (!$(e.target).parent().hasClass('contextual') || $(e.target).parent().hasClass('quickedit')) { - closeOffCanvas(); - } - // Do not trigger if target is quick edit link to avoid loop. - if ($(e.target).parent().hasClass('contextual') || $(e.target).parent().hasClass('quickedit')) { - return; - } - $(e.currentTarget).find('li.quickedit a').trigger('click'); - }); - } - } - // Disable edit mode. - else { - $editables = $('[data-drupal-outsidein="editable"]').removeOnce('outsidein'); - if ($editables.length) { - document.querySelector('[data-offcanvas-main-canvas]').removeEventListener('click', preventClick, true); - $editables.off('.outsidein'); - $(quickEditItemSelector).off('.outsidein'); - } - - $editButton.text(Drupal.t('Edit')); - closeOffCanvas(); - disableQuickEdit(); - } - getItemsToToggle().toggleClass('js-outside-in-edit-mode', editMode); - $('.edit-mode-inactive').toggleClass('visually-hidden', editMode); - } - - /** - * Attaches contextual's edit toolbar tab behavior. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches contextual toolbar behavior on a contextualToolbar-init event. - */ - Drupal.behaviors.outsideInEdit = { - attach: function () { - var editMode = localStorage.getItem('Drupal.contextualToolbar.isViewing') === 'false'; - if (editMode) { - setEditModeState(true); - } - } - }; - - /** - * Toggle the js-outside-edit-mode class on items that we want to disable while in edit mode. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Toggle the js-outside-edit-mode class. - */ - Drupal.behaviors.toggleEditMode = { - attach: function () { - - $(toggleEditSelector).once('outsidein').on('click.outsidein', toggleEditMode); - - var search = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog'; - var replace = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog_offcanvas'; - // Loop through all Ajax links and change the format to dialog-offcanvas when - // needed. - Drupal.ajax.instances - .filter(function (instance) { - var hasElement = instance && !!instance.element; - var rendererOffcanvas = false; - var wrapperOffcanvas = false; - if (hasElement) { - rendererOffcanvas = $(instance.element).attr('data-dialog-renderer') === 'offcanvas'; - wrapperOffcanvas = instance.options.url.indexOf('drupal_dialog_offcanvas') === -1; - } - return hasElement && rendererOffcanvas && wrapperOffcanvas; - }) - .forEach(function (instance) { - // @todo Move logic for data-dialog-renderer attribute into ajax.js - // https://www.drupal.org/node/2784443 - instance.options.url = instance.options.url.replace(search, replace); - // Check to make sure existing dialogOptions aren't overridden. - if (!('dialogOptions' in instance.options.data)) { - instance.options.data.dialogOptions = {}; - } - instance.options.data.dialogOptions.outsideInActiveEditableId = $(instance.element).parents('.outside-in-editable').attr('id'); - instance.progress = {type: 'fullscreen'}; - }); - } - }; - - // Manage Active editable class on opening and closing of the dialog. - $(window).on({ - 'dialog:beforecreate': function (event, dialog, $element, settings) { - if ($element.is('#drupal-offcanvas')) { - $('body .outside-in-active-editable').removeClass('outside-in-active-editable'); - var $activeElement = $('#' + settings.outsideInActiveEditableId); - if ($activeElement.length) { - $activeElement.addClass('outside-in-active-editable'); - settings.dialogClass += ' ui-dialog-outside-in'; - } - } - }, - 'dialog:beforeclose': function (event, dialog, $element) { - if ($element.is('#drupal-offcanvas')) { - $('body .outside-in-active-editable').removeClass('outside-in-active-editable'); - } - } - }); - -})(jQuery, Drupal); diff --git a/core/modules/outside_in/outside_in.info.yml b/core/modules/outside_in/outside_in.info.yml deleted file mode 100644 index 4542fcd8..00000000 --- a/core/modules/outside_in/outside_in.info.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: 'Settings Tray' -type: module -description: 'Provides the ability to change the most common configuration from the Drupal front-end.' -package: Core (Experimental) -# version: VERSION -# core: 8.x -dependencies: - - block - - toolbar - - contextual - -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' -core: '8.x' -project: 'drupal' -datestamp: 1485975642 diff --git a/core/modules/outside_in/outside_in.install b/core/modules/outside_in/outside_in.install deleted file mode 100644 index e205e46e..00000000 --- a/core/modules/outside_in/outside_in.install +++ /dev/null @@ -1,24 +0,0 @@ -deleteAll(); -} diff --git a/core/modules/outside_in/outside_in.libraries.yml b/core/modules/outside_in/outside_in.libraries.yml deleted file mode 100644 index 5eddea4c..00000000 --- a/core/modules/outside_in/outside_in.libraries.yml +++ /dev/null @@ -1,33 +0,0 @@ -drupal.outside_in: - version: VERSION - js: - js/outside_in.js: {} - css: - component: - css/outside_in.module.css: {} - css/outside_in.motion.css: {} - css/outside_in.form.css: {} - css/outside_in.table.css: {} - css/outside_in.details.css: {} - css/outside_in.tabledrag.css: {} - theme: - # @todo Set the group higher than CSS_AGGREGATE_THEME so that it overrides - # both jQuery UI and Classy's dialog.css, remove in - # https://www.drupal.org/node/1945262. - css/outside_in.theme.css: { group: 200 } - dependencies: - - core/jquery - - core/drupal - - core/jquery.once - - core/drupal.ajax -drupal.off_canvas: - version: VERSION - js: - js/offcanvas.js: {} - dependencies: - - core/jquery - - core/drupal - - core/drupal.ajax - - core/drupal.announce - - core/drupal.dialog - - core/drupal.dialog.ajax diff --git a/core/modules/outside_in/outside_in.links.contextual.yml b/core/modules/outside_in/outside_in.links.contextual.yml deleted file mode 100644 index 99b36eff..00000000 --- a/core/modules/outside_in/outside_in.links.contextual.yml +++ /dev/null @@ -1,4 +0,0 @@ -outside_in.block_configure: - title: 'Quick edit' - route_name: 'entity.block.offcanvas_form' - group: 'block' diff --git a/core/modules/outside_in/outside_in.module b/core/modules/outside_in/outside_in.module deleted file mode 100644 index a7fab7bd..00000000 --- a/core/modules/outside_in/outside_in.module +++ /dev/null @@ -1,156 +0,0 @@ -' . t('About') . ''; - $output .= '

    ' . t('The Settings Tray module provides an \'edit mode\' in which clicking on a block opens a slide-out tray which allows configuration to be altered without leaving the page.For more information, see the online documentation for the Settings Tray module.', [':outside-in-documentation' => 'https://www.drupal.org/documentation/modules/outside_in']) . '

    '; - $output .= '

    ' . t('Uses') . '

    '; - $output .= '
    '; - $output .= '
    ' . t('Editing blocks on the same page in the slide-out tray') . '
    '; - $output .= '
    '; - return ['#markup' => $output]; - } -} - -/** - * Implements hook_contextual_links_view_alter(). - * - * Change Configure Blocks into offcanvas links. - */ -function outside_in_contextual_links_view_alter(&$element, $items) { - if (isset($element['#links']['outside-inblock-configure'])) { - $element['#links']['outside-inblock-configure']['attributes'] = [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'dialog', - 'data-dialog-renderer' => 'offcanvas', - 'data-outside-in-edit' => TRUE, - ]; - - $element['#attached']['library'][] = 'outside_in/drupal.off_canvas'; - } -} - -/** - * Implements hook_block_view_alter(). - */ -function outside_in_block_view_alter(array &$build) { - // Force a new 'data-contextual-id' attribute on blocks when this module is - // enabled so as not to reuse stale data cached client-side. - // @todo Remove when https://www.drupal.org/node/2773591 is fixed. - $build['#contextual_links']['outside_in'] = [ - 'route_parameters' => [], - ]; -} - -/** - * Implements hook_element_info_alter(). - */ -function outside_in_element_info_alter(&$type) { - if (isset($type['page'])) { - $type['page']['#theme_wrappers']['outside_in_page_wrapper'] = ['#weight' => -1000]; - } -} - -/** - * Implements hook_theme(). - */ -function outside_in_theme() { - return [ - 'outside_in_page_wrapper' => [ - 'variables' => ['children' => NULL], - ], - ]; -} - -/** - * Implements hook_entity_type_build(). - */ -function outside_in_entity_type_build(array &$entity_types) { - /* @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */ - $entity_types['block'] - ->setFormClass('offcanvas', BlockEntityOffCanvasForm::class) - ->setLinkTemplate('offcanvas-form', '/admin/structure/block/manage/{block}/offcanvas'); -} - -/** - * Implements hook_preprocess_HOOK() for block templates. - */ -function outside_in_preprocess_block(&$variables) { - // The main system block does not contain the block contextual links. - $variables['#cache']['contexts'][] = 'outside_in_is_applied'; - if ($variables['plugin_id'] !== 'system_main_block' && \Drupal::service('outside_in.manager')->isApplicable()) { - // Add class and attributes to all blocks to allow Javascript to target. - $variables['attributes']['class'][] = 'outside-in-editable'; - $variables['attributes']['data-drupal-outsidein'] = 'editable'; - } -} - -/** - * Implements hook_toolbar_alter(). - * - * Includes outside_library if Edit link is in toolbar. - */ -function outside_in_toolbar_alter(&$items) { - $items['contextual']['#cache']['contexts'][] = 'outside_in_is_applied'; - if (isset($items['contextual']['tab']) && \Drupal::service('outside_in.manager')->isApplicable()) { - $items['contextual']['#weight'] = -1000; - $items['contextual']['#attached']['library'][] = 'outside_in/drupal.outside_in'; - $items['contextual']['tab']['#attributes']['data-drupal-outsidein'] = 'toggle'; - - // Set a class on items to mark whether they should be active in edit mode. - // @todo Create a dynamic method for modules to set their own items. - // https://www.drupal.org/node/2784589 - - $edit_mode_items = ['contextual', 'block_place']; - foreach ($items as $key => $item) { - if (!in_array($key, $edit_mode_items) && (!isset($items[$key]['#wrapper_attributes']['class']) || !in_array('hidden', $items[$key]['#wrapper_attributes']['class']))) { - $items[$key]['#wrapper_attributes']['class'][] = 'edit-mode-inactive'; - } - } - } -} - -/** - * Implements hook_block_alter(). - */ -function outside_in_block_alter(&$definitions) { - if (!empty($definitions['system_branding_block'])) { - $definitions['system_branding_block']['forms']['offcanvas'] = SystemBrandingOffCanvasForm::class; - } - - // Since menu blocks use derivatives, check the definition ID instead of - // relying on the plugin ID. - foreach ($definitions as &$definition) { - if ($definition['id'] === 'system_menu_block') { - $definition['forms']['offcanvas'] = SystemMenuOffCanvasForm::class; - } - } -} - -/** - * Implements hook_css_alter(). - */ -function outside_in_css_alter(&$css, AttachedAssetsInterface $assets) { - // @todo Remove once conditional ordering is introduced in - // https://www.drupal.org/node/1945262. - $path = drupal_get_path('module', 'outside_in') . '/css/outside_in.theme.css'; - if (isset($css[$path])) { - // Use 200 to come after CSS_AGGREGATE_THEME. - $css[$path]['group'] = 200; - } -} diff --git a/core/modules/outside_in/outside_in.routing.yml b/core/modules/outside_in/outside_in.routing.yml deleted file mode 100644 index 79bc38d9..00000000 --- a/core/modules/outside_in/outside_in.routing.yml +++ /dev/null @@ -1,7 +0,0 @@ -entity.block.offcanvas_form: - path: '/admin/structure/block/manage/{block}/offcanvas' - defaults: - _entity_form: 'block.offcanvas' - _title_callback: '\Drupal\outside_in\Block\BlockEntityOffCanvasForm::title' - requirements: - _permission: 'administer blocks' diff --git a/core/modules/outside_in/outside_in.services.yml b/core/modules/outside_in/outside_in.services.yml deleted file mode 100644 index 48f58242..00000000 --- a/core/modules/outside_in/outside_in.services.yml +++ /dev/null @@ -1,16 +0,0 @@ -services: - main_content_renderer.off_canvas: - class: Drupal\outside_in\Render\MainContent\OffCanvasRender - arguments: ['@title_resolver', '@renderer'] - tags: - - { name: render.main_content_renderer, format: drupal_dialog_offcanvas } - - outside_in.manager: - class: Drupal\outside_in\OutsideInManager - arguments: ['@router.admin_context', '@current_route_match', '@current_user'] - - cache_context.outside_in_is_applied: - class: Drupal\outside_in\Cache\Context\OutsideInCacheContext - arguments: ['@outside_in.manager'] - tags: - - { name: cache.context} diff --git a/core/modules/outside_in/src/Ajax/OpenOffCanvasDialogCommand.php b/core/modules/outside_in/src/Ajax/OpenOffCanvasDialogCommand.php deleted file mode 100644 index d78dc353..00000000 --- a/core/modules/outside_in/src/Ajax/OpenOffCanvasDialogCommand.php +++ /dev/null @@ -1,57 +0,0 @@ -dialogOptions['modal'] = FALSE; - $this->dialogOptions['autoResize'] = FALSE; - $this->dialogOptions['resizable'] = 'w'; - $this->dialogOptions['draggable'] = FALSE; - $this->dialogOptions['drupalAutoButtons'] = FALSE; - // @todo drupal.ajax.js does not respect drupalAutoButtons properly, pass an - // empty set of buttons until https://www.drupal.org/node/2793343 is in. - $this->dialogOptions['buttons'] = []; - } - - /** - * {@inheritdoc} - */ - public function render() { - $build = parent::render(); - $build['effect'] = 'fade'; - $build['speed'] = 1000; - return $build; - } - -} diff --git a/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php b/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php deleted file mode 100644 index a77f51fc..00000000 --- a/core/modules/outside_in/src/Block/BlockEntityOffCanvasForm.php +++ /dev/null @@ -1,100 +0,0 @@ - once - // https://www.drupal.org/node/2359901 is fixed. - return $this->t('Configure @block', ['@block' => $block->getPlugin()->getPluginDefinition()['admin_label']]); - } - - /** - * {@inheritdoc} - */ - public function form(array $form, FormStateInterface $form_state) { - $form = parent::form($form, $form_state); - - // Create link to full block form. - $query = []; - if ($destination = $this->getRequest()->query->get('destination')) { - $query['destination'] = $destination; - } - $form['advanced_link'] = [ - '#type' => 'link', - '#title' => $this->t('Advanced options'), - '#url' => $this->entity->toUrl('edit-form', ['query' => $query]), - '#weight' => 1000, - ]; - - // Remove the ID and region elements. - unset($form['id'], $form['region'], $form['settings']['admin_label']); - - return $form; - } - - /** - * {@inheritdoc} - */ - protected function actions(array $form, FormStateInterface $form_state) { - $actions = parent::actions($form, $form_state); - $actions['submit']['#value'] = $this->t('Save @block', ['@block' => $this->entity->getPlugin()->getPluginDefinition()['admin_label']]); - $actions['delete']['#access'] = FALSE; - return $actions; - } - - /** - * {@inheritdoc} - */ - protected function buildVisibilityInterface(array $form, FormStateInterface $form_state) { - // Do not display the visibility. - return []; - } - - /** - * {@inheritdoc} - */ - protected function validateVisibility(array $form, FormStateInterface $form_state) { - // Intentionally empty. - } - - /** - * {@inheritdoc} - */ - protected function submitVisibility(array $form, FormStateInterface $form_state) { - // Intentionally empty. - } - - /** - * {@inheritdoc} - */ - protected function getPluginForm(BlockPluginInterface $block) { - if ($block instanceof PluginWithFormsInterface) { - return $this->pluginFormFactory->createInstance($block, 'offcanvas', 'configure'); - } - return $block; - } - -} diff --git a/core/modules/outside_in/src/Cache/Context/OutsideInCacheContext.php b/core/modules/outside_in/src/Cache/Context/OutsideInCacheContext.php deleted file mode 100644 index 4a24671d..00000000 --- a/core/modules/outside_in/src/Cache/Context/OutsideInCacheContext.php +++ /dev/null @@ -1,54 +0,0 @@ -outsideInManager = $outside_in_manager; - } - - /** - * {@inheritdoc} - */ - public static function getLabel() { - return t('Settings Tray'); - } - - /** - * {@inheritdoc} - */ - public function getContext() { - return $this->outsideInManager->isApplicable() ? '1' : '0'; - } - - /** - * {@inheritdoc} - */ - public function getCacheableMetadata() { - return new CacheableMetadata(); - } - -} diff --git a/core/modules/outside_in/src/OutsideInManager.php b/core/modules/outside_in/src/OutsideInManager.php deleted file mode 100644 index 666a9383..00000000 --- a/core/modules/outside_in/src/OutsideInManager.php +++ /dev/null @@ -1,66 +0,0 @@ -adminContext = $admin_context; - $this->routeMatch = $route_match; - $this->account = $account; - } - - /** - * {@inheritdoc} - */ - public function isApplicable() { - // Remove on Admin routes. - $is_admin_route = $this->adminContext->isAdminRoute(); - - // Remove on Block Demo page. - $is_admin_demo_route = $this->routeMatch->getRouteName() === 'block.admin_demo'; - - // @todo Check if there is actually a different admin theme. - // https://www.drupal.org/node/2784853 - return $this->account->hasPermission('administer blocks') && !$is_admin_route && !$is_admin_demo_route; - } - -} diff --git a/core/modules/outside_in/src/OutsideInManagerInterface.php b/core/modules/outside_in/src/OutsideInManagerInterface.php deleted file mode 100644 index 684adb3f..00000000 --- a/core/modules/outside_in/src/OutsideInManagerInterface.php +++ /dev/null @@ -1,18 +0,0 @@ -renderer = $renderer; - } - - /** - * {@inheritdoc} - */ - public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) { - $response = new AjaxResponse(); - - // First render the main content, because it might provide a title. - $content = $this->renderer->renderRoot($main_content); - - // Attach the library necessary for using the OpenOffCanvasDialogCommand and - // set the attachments for this Ajax response. - $main_content['#attached']['library'][] = 'outside_in/drupal.off_canvas'; - $response->setAttachments($main_content['#attached']); - - // If the main content doesn't provide a title, use the title resolver. - $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject()); - - // Determine the title: use the title provided by the main content if any, - // otherwise get it from the routing information. - $options = $request->request->get('dialogOptions', []); - - $response->addCommand(new OpenOffCanvasDialogCommand($title, $content, $options)); - return $response; - } - -} diff --git a/core/modules/outside_in/src/Tests/Ajax/OffCanvasDialogTest.php b/core/modules/outside_in/src/Tests/Ajax/OffCanvasDialogTest.php deleted file mode 100644 index f3510427..00000000 --- a/core/modules/outside_in/src/Tests/Ajax/OffCanvasDialogTest.php +++ /dev/null @@ -1,59 +0,0 @@ -drupalLogin($this->drupalCreateUser(['administer contact forms'])); - // Ensure the elements render without notices or exceptions. - $this->drupalGet('ajax-test/dialog'); - - // Set up variables for this test. - $dialog_renderable = AjaxTestController::dialogContents(); - $dialog_contents = \Drupal::service('renderer')->renderRoot($dialog_renderable); - - $offcanvas_expected_response = [ - 'command' => 'openDialog', - 'selector' => '#drupal-offcanvas', - 'settings' => NULL, - 'data' => $dialog_contents, - 'dialogOptions' => - [ - 'title' => 'AJAX Dialog & contents', - 'modal' => FALSE, - 'autoResize' => FALSE, - 'resizable' => 'w', - 'draggable' => FALSE, - 'drupalAutoButtons' => FALSE, - 'buttons' => [], - ], - 'effect' => 'fade', - 'speed' => 1000, - ]; - - // Emulate going to the JS version of the page and check the JSON response. - $ajax_result = $this->drupalGetAjax('ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog_offcanvas']]); - $this->assertEqual($offcanvas_expected_response, $ajax_result[3], 'Off-canvas dialog JSON response matches.'); - } - -} diff --git a/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig b/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig deleted file mode 100644 index adedc6bb..00000000 --- a/core/modules/outside_in/templates/outside-in-page-wrapper.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{# -/** - * @file - * Default theme implementation for a page wrapper. - * - * For consistent wrapping to {{ page }} render in all themes. - * - * Available variables: - * - children: Contains the child elements of the page. - * - * @ingroup themeable - */ -#} -{% if children %} -
    - {{ children }} -
    -{% endif %} diff --git a/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.info.yml b/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.info.yml deleted file mode 100644 index 18342206..00000000 --- a/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.info.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: 'Off-canvas tests' -type: module -description: 'Provides off-canvas test links.' -package: Testing -# version: VERSION -# core: 8.x -dependencies: - - block - - outside_in - -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' -core: '8.x' -project: 'drupal' -datestamp: 1485975642 diff --git a/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml b/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml deleted file mode 100644 index 761693b7..00000000 --- a/core/modules/outside_in/tests/modules/offcanvas_test/offcanvas_test.routing.yml +++ /dev/null @@ -1,29 +0,0 @@ -offcanvas_test.links: - path: '/offcanvas-test-links' - defaults: - _controller: '\Drupal\offcanvas_test\Controller\TestController::linksDisplay' - _title: 'Links' - requirements: - _access: 'TRUE' - -offcanvas_test.thing1: - path: '/offcanvas-thing1' - defaults: - _controller: '\Drupal\offcanvas_test\Controller\TestController::thing1' - _title: 'Thing 1' - requirements: - _access: 'TRUE' - -offcanvas_test.thing2: - path: '/offcanvas-thing2' - defaults: - _controller: '\Drupal\offcanvas_test\Controller\TestController::thing2' - requirements: - _access: 'TRUE' - -offcanvas_test.dialog_links: - path: '/offcanvas-dialog-links' - defaults: - _controller: '\Drupal\offcanvas_test\Controller\TestController::otherDialogLinks' - requirements: - _access: 'TRUE' diff --git a/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php b/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php deleted file mode 100644 index 9ee8e176..00000000 --- a/core/modules/outside_in/tests/modules/offcanvas_test/src/Controller/TestController.php +++ /dev/null @@ -1,140 +0,0 @@ - 'markup', - '#markup' => 'Thing 1 says hello', - ]; - } - - /** - * Thing2. - * - * @return string - * Return Hello string. - */ - public function thing2() { - return [ - '#type' => 'markup', - '#markup' => 'Thing 2 says hello', - ]; - } - - /** - * Displays test links that will open in offcanvas tray. - * - * @return array - * Render array with links. - */ - public function linksDisplay() { - return [ - 'offcanvas_link_1' => [ - '#title' => 'Click Me 1!', - '#type' => 'link', - '#url' => Url::fromRoute('offcanvas_test.thing1'), - '#attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'dialog', - 'data-dialog-renderer' => 'offcanvas', - ], - '#attached' => [ - 'library' => [ - 'outside_in/drupal.outside_in', - ], - ], - ], - 'offcanvas_link_2' => [ - '#title' => 'Click Me 2!', - '#type' => 'link', - '#url' => Url::fromRoute('offcanvas_test.thing2'), - '#attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'dialog', - 'data-dialog-renderer' => 'offcanvas', - 'data-dialog-options' => Json::encode([ - 'width' => 555, - ]), - ], - '#attached' => [ - 'library' => [ - 'outside_in/drupal.outside_in', - ], - ], - ], - 'other_dialog_links' => [ - '#title' => 'Display more links!', - '#type' => 'link', - '#url' => Url::fromRoute('offcanvas_test.dialog_links'), - '#attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'dialog', - 'data-dialog-renderer' => 'offcanvas', - ], - '#attached' => [ - 'library' => [ - 'outside_in/drupal.outside_in', - ], - ], - ], - ]; - } - - /** - * Displays dialogs links to be displayed inside the offcanvas tray. - * - * This links are used to test opening a modal and another offcanvas link from - * inside the offcanvas tray. - * - * @todo Update tests to check these links work in the offcanvas tray. - * https://www.drupal.org/node/2790073 - * - * @return array - * Render array with links. - */ - public function otherDialogLinks() { - return [ - '#theme' => 'links', - '#links' => [ - 'modal_link' => [ - 'title' => 'Open modal!', - 'url' => Url::fromRoute('offcanvas_test.thing2'), - 'attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'modal', - ], - ], - 'offcanvas_link' => [ - 'title' => 'Offcanvas link!', - 'url' => Url::fromRoute('offcanvas_test.thing2'), - 'attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'dialog', - 'data-dialog-renderer' => 'offcanvas', - ], - ], - ], - '#attached' => [ - 'library' => [ - 'outside_in/drupal.outside_in', - ], - ], - ]; - } - -} diff --git a/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php b/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php deleted file mode 100644 index efb38e01..00000000 --- a/core/modules/outside_in/tests/modules/offcanvas_test/src/Plugin/Block/TestBlock.php +++ /dev/null @@ -1,49 +0,0 @@ - [ - '#title' => $this->t('Click Me 1!'), - '#type' => 'link', - '#url' => Url::fromRoute('offcanvas_test.thing1'), - '#attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'offcanvas', - ], - ], - 'offcanvas_link_2' => [ - '#title' => $this->t('Click Me 2!'), - '#type' => 'link', - '#url' => Url::fromRoute('offcanvas_test.thing2'), - '#attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'offcanvas', - ], - ], - '#attached' => [ - 'library' => [ - 'outside_in/drupal.off_canvas', - ], - ], - ]; - } - -} diff --git a/core/modules/outside_in/tests/modules/outside_in_test_css/css/css_fix.theme.css b/core/modules/outside_in/tests/modules/outside_in_test_css/css/css_fix.theme.css deleted file mode 100644 index dc9d72ad..00000000 --- a/core/modules/outside_in/tests/modules/outside_in_test_css/css/css_fix.theme.css +++ /dev/null @@ -1,4 +0,0 @@ -#main-canvas.js-outside-in-edit-mode a, -#main-canvas.js-outside-in-edit-mode input { - pointer-events: inherit !important; -} diff --git a/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.info.yml b/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.info.yml deleted file mode 100644 index 29ee6a07..00000000 --- a/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.info.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: 'CSS Test fix' -type: module -description: 'Provides CSS fixes for tests.' -package: Testing -# version: VERSION -# core: 8.x -dependencies: -- outside_in - -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' -core: '8.x' -project: 'drupal' -datestamp: 1485975642 diff --git a/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.module b/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.module deleted file mode 100644 index 2cd32e2b..00000000 --- a/core/modules/outside_in/tests/modules/outside_in_test_css/outside_in_test_css.module +++ /dev/null @@ -1,16 +0,0 @@ -enableTheme($theme); - $this->drupalGet('/offcanvas-test-links'); - - $page = $this->getSession()->getPage(); - $web_assert = $this->assertSession(); - - // Make sure off-canvas tray is on page when first loaded. - $web_assert->elementNotExists('css', '#drupal-offcanvas'); - - // Check opening and closing with two separate links. - // Make sure tray updates to new content. - // Check the first link again to make sure the empty title class is - // removed. - foreach (['1', '2', '1'] as $link_index) { - // Click the first test like that should open the page. - $page->clickLink("Click Me $link_index!"); - $this->waitForOffCanvasToOpen(); - - // Check that the canvas is not on the page. - $web_assert->elementExists('css', '#drupal-offcanvas'); - // Check that response text is on page. - $web_assert->pageTextContains("Thing $link_index says hello"); - $offcanvas_tray = $this->getTray(); - - // Check that tray is visible. - $this->assertEquals(TRUE, $offcanvas_tray->isVisible()); - $header_text = $offcanvas_tray->find('css', '.ui-dialog-title')->getText(); - - $tray_text = $offcanvas_tray->findById('drupal-offcanvas')->getText(); - $this->assertEquals("Thing $link_index says hello", $tray_text); - - if ($link_index == '2') { - // Check no title behavior. - $web_assert->elementExists('css', '.ui-dialog-empty-title'); - $this->assertEquals('', $header_text); - - $style = $page->find('css', '.ui-dialog-offcanvas')->getAttribute('style'); - self::assertTrue(strstr($style, 'width: 555px;') !== FALSE, 'Dialog width respected.'); - } - else { - // Check that header is correct. - $this->assertEquals("Thing $link_index", $header_text); - $web_assert->elementNotExists('css', '.ui-dialog-empty-title'); - } - } - } - } - - /** - * Tests the body displacement behaves differently at a narrow width. - */ - public function testNarrowWidth() { - $themes = ['stark', 'bartik']; - $narrow_width_breakpoint = 768; - $offset = 20; - $height = 800; - $page = $this->getSession()->getPage(); - $web_assert = $this->assertSession(); - - // Test the same functionality on multiple themes. - foreach ($themes as $theme) { - $this->enableTheme($theme); - // Testing at the wider width. - $this->getSession()->resizeWindow($narrow_width_breakpoint + $offset, $height); - $this->drupalGet('/offcanvas-test-links'); - $this->assertFalse($page->find('css', '.dialog-offcanvas__main-canvas')->hasAttribute('style'), 'Body not padded on wide page load.'); - $page->clickLink("Click Me 1!"); - $this->waitForOffCanvasToOpen(); - // Check that the main canvas is padded when page is not narrow width and - // tray is open. - $web_assert->elementAttributeContains('css', '.dialog-offcanvas__main-canvas', 'style', 'padding-right'); - - // Testing at the narrower width. - $this->getSession()->resizeWindow($narrow_width_breakpoint - $offset, $height); - $this->drupalGet('/offcanvas-test-links'); - $this->assertFalse($page->find('css', '.dialog-offcanvas__main-canvas')->hasAttribute('style'), 'Body not padded on narrow page load.'); - $page->clickLink("Click Me 1!"); - $this->waitForOffCanvasToOpen(); - $this->assertFalse($page->find('css', '.dialog-offcanvas__main-canvas')->hasAttribute('style'), 'Body not padded on narrow page with tray open.'); - } - } - -} diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php deleted file mode 100644 index c39f2f8e..00000000 --- a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInBlockFormTest.php +++ /dev/null @@ -1,287 +0,0 @@ -enableTheme('bartik'); - $user = $this->createUser([ - 'administer blocks', - 'access contextual links', - 'access toolbar', - 'administer nodes', - 'access in-place editing', - 'search content', - ]); - $this->drupalLogin($user); - - $this->placeBlock('system_powered_by_block', ['id' => 'powered']); - $this->placeBlock('system_branding_block', ['id' => 'branding']); - $this->placeBlock('search_form_block', ['id' => 'search']); - } - - /** - * Tests opening Offcanvas tray by click blocks and elements in the blocks. - * - * @dataProvider providerTestBlocks - */ - public function testBlocks($block_id, $new_page_text, $element_selector, $label_selector, $button_text, $toolbar_item) { - $web_assert = $this->assertSession(); - $page = $this->getSession()->getPage(); - $block_selector = '#' . $block_id; - $this->drupalGet('user'); - if (isset($toolbar_item)) { - // Check that you can open a toolbar tray and it will be closed after - // entering edit mode. - if ($element = $page->find('css', "#toolbar-administration a.is-active")) { - // If a tray was open from page load close it. - $element->click(); - $this->waitForNoElement("#toolbar-administration a.is-active"); - } - $page->find('css', $toolbar_item)->click(); - $this->waitForElement("{$toolbar_item}.is-active"); - } - $this->toggleEditingMode(); - if (isset($toolbar_item)) { - $this->waitForNoElement("{$toolbar_item}.is-active"); - } - - $this->openBlockForm($block_selector); - - switch ($block_id) { - case 'block-powered': - // Fill out form, save the form. - $page->fillField('settings[label]', $new_page_text); - $page->checkField('settings[label_display]'); - break; - - case 'block-branding': - // Fill out form, save the form. - $page->fillField('settings[site_information][site_name]', $new_page_text); - break; - } - - if (isset($new_page_text)) { - $page->pressButton($button_text); - // Make sure the changes are present. - // @todo Use a wait method that will take into account the form submitting - // and all JavaScript activity. https://www.drupal.org/node/2837676 - // The use \Behat\Mink\WebAssert::pageTextContains to check text. - $this->assertJsCondition('jQuery("' . $block_selector . ' ' . $label_selector . '").html() == "' . $new_page_text . '"'); - } - - $this->openBlockForm($block_selector); - - $this->toggleEditingMode(); - // Canvas should close when editing module is closed. - $this->waitForOffCanvasToClose(); - - // Go into Edit mode again. - $this->toggleEditingMode(); - - $element_selector = "$block_selector {$element_selector}"; - // Open block form by clicking a element inside the block. - // This confirms that default action for links and form elements is - // suppressed. - $this->openBlockForm($element_selector); - - // Exit edit mode using ESC. - $web_assert->elementTextContains('css', '.contextual-toolbar-tab button', 'Editing'); - $web_assert->elementAttributeContains('css', '.dialog-offcanvas__main-canvas', 'class', 'js-outside-in-edit-mode'); - // Simulate press the Escape key. - $this->getSession()->executeScript('jQuery("body").trigger(jQuery.Event("keyup", { keyCode: 27 }));'); - $this->waitForOffCanvasToClose(); - $this->getSession()->wait(100); - $web_assert->elementTextContains('css', '#drupal-live-announce', 'Exited edit mode.'); - $web_assert->elementTextNotContains('css', '.contextual-toolbar-tab button', 'Editing'); - $web_assert->elementAttributeNotContains('css', '.dialog-offcanvas__main-canvas', 'class', 'js-outside-in-edit-mode'); - } - - /** - * Dataprovider for testBlocks(). - */ - public function providerTestBlocks() { - $blocks = [ - 'block-powered' => [ - 'id' => 'block-powered', - 'new_page_text' => 'Can you imagine anyone showing the label on this block?', - 'element_selector' => '.content a', - 'label_selector' => 'h2', - 'button_text' => 'Save Powered by Drupal', - 'toolbar_item' => '#toolbar-item-user', - ], - 'block-branding' => [ - 'id' => 'block-branding', - 'new_page_text' => 'The site that will live a very short life.', - 'element_selector' => 'a[rel="home"]:nth-child(2)', - 'label_selector' => '.site-branding__name a', - 'button_text' => 'Save Site branding', - 'toolbar_item' => '#toolbar-item-administration', - ], - 'block-search' => [ - 'id' => 'block-search', - 'new_page_text' => NULL, - 'element_selector' => '#edit-submit', - 'label_selector' => 'h2', - 'button_text' => 'Save Search form', - 'toolbar_item' => NULL, - ], - ]; - return $blocks; - } - - /** - * Enables Editing mode by pressing "Edit" button in the toolbar. - */ - protected function toggleEditingMode() { - $this->waitForElement('div[data-contextual-id="block:block=powered:langcode=en|outside_in::langcode=en"] .contextual-links a', 10000); - // Waiting for QuickEdit icon animation. - $this->assertSession()->assertWaitOnAjaxRequest(); - - $edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button'); - - $edit_button->press(); - // Waiting for Toolbar animation. - $this->assertSession()->assertWaitOnAjaxRequest(); - } - - /** - * Asserts that Off-Canvas block form is valid. - */ - protected function assertOffCanvasBlockFormIsValid() { - $web_assert = $this->assertSession(); - // Check that common block form elements exist. - $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label"]'); - $web_assert->elementExists('css', 'input[data-drupal-selector="edit-settings-label-display"]'); - // Check that advanced block form elements do not exist. - $web_assert->elementNotExists('css', 'input[data-drupal-selector="edit-visibility-request-path-pages"]'); - $web_assert->elementNotExists('css', 'select[data-drupal-selector="edit-region"]'); - } - - /** - * Open block form by clicking the element found with a css selector. - * - * @param string $block_selector - * A css selector selects the block or an element within it. - */ - protected function openBlockForm($block_selector) { - $this->click($block_selector); - $this->waitForOffCanvasToOpen(); - $this->assertOffCanvasBlockFormIsValid(); - } - - /** - * Tests QuickEdit links behavior. - */ - public function testQuickEditLinks() { - $quick_edit_selector = '#quickedit-entity-toolbar'; - $body_selector = '.field--name-body p'; - $block_selector = '#block-powered'; - $web_assert = $this->assertSession(); - // Create a Content type and two test nodes. - $this->createContentType(['type' => 'page']); - $auth_role = Role::load(Role::AUTHENTICATED_ID); - $this->grantPermissions($auth_role, [ - 'edit any page content', - 'access content', - ]); - $node = $this->createNode( - [ - 'title' => 'Page One', - 'type' => 'page', - 'body' => [ - [ - 'value' => 'Regular NODE body for the test.', - 'format' => 'plain_text', - ], - ], - ] - ); - $page = $this->getSession()->getPage(); - // Load the same page twice. - foreach ([1, 2] as $page_load_times) { - $this->drupalGet('node/' . $node->id()); - // Waiting for Toolbar module. - // @todo Remove the hack after https://www.drupal.org/node/2542050. - $this->waitForElement('.toolbar-fixed'); - // Waiting for Toolbar animation. - $web_assert->assertWaitOnAjaxRequest(); - // The 2nd page load we should already be in edit mode. - if ($page_load_times == 1) { - $this->toggleEditingMode(); - } - // In Edit mode clicking field should open QuickEdit toolbar. - $page->find('css', $body_selector)->click(); - $this->waitForElement($quick_edit_selector); - // Exit Edit mode. - $this->toggleEditingMode(); - // Exiting Edit mode should close QuickEdit toolbar. - $web_assert->elementNotExists('css', $quick_edit_selector); - // When not in Edit mode QuickEdit toolbar should not open. - $page->find('css', $body_selector)->click(); - $web_assert->elementNotExists('css', $quick_edit_selector); - - // Enter Edit mode. - $this->toggleEditingMode(); - $this->openBlockForm($block_selector); - $page->find('css', $body_selector)->click(); - $this->waitForElement($quick_edit_selector); - // Offcanvas should be closed when opening QuickEdit toolbar. - $this->waitForOffCanvasToClose(); - - $this->openBlockForm($block_selector); - // QuickEdit toolbar should be closed when opening Offcanvas. - $web_assert->elementNotExists('css', $quick_edit_selector); - } - - // Check using contextual links to invoke QuickEdit and open the tray. - $this->drupalGet('node/' . $node->id()); - $web_assert->assertWaitOnAjaxRequest(); - $this->toggleEditingMode(); - // Open QuickEdit toolbar before going into Edit mode. - $this->clickContextualLink('.node', "Quick edit"); - $this->waitForElement($quick_edit_selector); - // Open off-canvas and enter Edit mode via contextual link. - $this->clickContextualLink($block_selector, "Quick edit"); - $this->waitForOffCanvasToOpen(); - // QuickEdit toolbar should be closed when opening Offcanvas. - $web_assert->elementNotExists('css', $quick_edit_selector); - // Open QuickEdit toolbar via contextual link while in Edit mode. - $this->clickContextualLink('.node', "Quick edit", FALSE); - $this->waitForOffCanvasToClose(); - $this->waitForElement($quick_edit_selector); - } - -} diff --git a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php b/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php deleted file mode 100644 index 48ba8993..00000000 --- a/core/modules/outside_in/tests/src/FunctionalJavascript/OutsideInJavascriptTestBase.php +++ /dev/null @@ -1,134 +0,0 @@ -assertSession()->assertWaitOnAjaxRequest(); - - return $return; - } - - /** - * Enables a theme. - * - * @param string $theme - * The theme. - */ - public function enableTheme($theme) { - // Enable the theme. - \Drupal::service('theme_installer')->install([$theme]); - $theme_config = \Drupal::configFactory()->getEditable('system.theme'); - $theme_config->set('default', $theme); - $theme_config->save(); - } - - /** - * Waits for Off-canvas tray to open. - */ - protected function waitForOffCanvasToOpen() { - $web_assert = $this->assertSession(); - $web_assert->assertWaitOnAjaxRequest(); - $this->waitForElement('#drupal-offcanvas'); - } - - /** - * Waits for Off-canvas tray to close. - */ - protected function waitForOffCanvasToClose() { - $this->waitForNoElement('#drupal-offcanvas'); - } - - /** - * Waits for an element to appear on the page. - * - * @param string $selector - * CSS selector. - * @param int $timeout - * (optional) Timeout in milliseconds, defaults to 10000. - */ - protected function waitForElement($selector, $timeout = 10000) { - $condition = "(jQuery('$selector').length > 0)"; - $this->assertJsCondition($condition, $timeout); - } - - /** - * Gets the Off-Canvas tray element. - * - * @return \Behat\Mink\Element\NodeElement|null - */ - protected function getTray() { - $tray = $this->getSession()->getPage()->find('css', '.ui-dialog[aria-describedby="drupal-offcanvas"]'); - $this->assertEquals(FALSE, empty($tray), 'The tray was found.'); - return $tray; - } - - /** - * Waits for an element to be removed from the page. - * - * @param string $selector - * CSS selector. - * @param int $timeout - * (optional) Timeout in milliseconds, defaults to 10000. - */ - protected function waitForNoElement($selector, $timeout = 10000) { - $condition = "(jQuery('$selector').length == 0)"; - $this->assertJsCondition($condition, $timeout); - } - - /** - * Clicks a contextual link. - * - * @todo Remove this function when related trait added in - * https://www.drupal.org/node/2821724. - * - * @param string $selector - * The selector for the element that contains the contextual link. - * @param string $link_locator - * The link id, title, or text. - * @param bool $force_visible - * If true then the button will be forced to visible so it can be clicked. - */ - protected function clickContextualLink($selector, $link_locator, $force_visible = TRUE) { - if ($force_visible) { - $this->toggleContextualTriggerVisibility($selector); - } - - $element = $this->getSession()->getPage()->find('css', $selector); - $element->find('css', '.contextual button')->press(); - $element->findLink($link_locator)->click(); - - if ($force_visible) { - $this->toggleContextualTriggerVisibility($selector); - } - } - - /** - * Toggles the visibility of a contextual trigger. - * - * @todo Remove this function when related trait added in - * https://www.drupal.org/node/2821724. - * - * @param string $selector - * The selector for the element that contains the contextual link. - */ - protected function toggleContextualTriggerVisibility($selector) { - // Hovering over the element itself with should be enough, but does not - // work. Manually remove the visually-hidden class. - $this->getSession()->executeScript("jQuery('{$selector} .contextual .trigger').toggleClass('visually-hidden');"); - } - -} diff --git a/core/modules/outside_in/tests/src/Unit/Ajax/OpenOffCanvasDialogCommandTest.php b/core/modules/outside_in/tests/src/Unit/Ajax/OpenOffCanvasDialogCommandTest.php deleted file mode 100644 index cd14d6df..00000000 --- a/core/modules/outside_in/tests/src/Unit/Ajax/OpenOffCanvasDialogCommandTest.php +++ /dev/null @@ -1,41 +0,0 @@ -Text!

    ', ['url' => 'example']); - - $expected = [ - 'command' => 'openDialog', - 'selector' => '#drupal-offcanvas', - 'settings' => NULL, - 'data' => '

    Text!

    ', - 'dialogOptions' => [ - 'url' => 'example', - 'title' => 'Title', - 'modal' => FALSE, - 'autoResize' => FALSE, - 'resizable' => 'w', - 'draggable' => FALSE, - 'drupalAutoButtons' => FALSE, - 'buttons' => [], - ], - 'effect' => 'fade', - 'speed' => 1000, - ]; - $this->assertEquals($expected, $command->render()); - } - -} diff --git a/core/modules/outside_in/tests/src/Unit/OutsideInManagerTest.php b/core/modules/outside_in/tests/src/Unit/OutsideInManagerTest.php deleted file mode 100644 index b08851fc..00000000 --- a/core/modules/outside_in/tests/src/Unit/OutsideInManagerTest.php +++ /dev/null @@ -1,57 +0,0 @@ -prophesize(AdminContext::class); - $admin_context->isAdminRoute()->willReturn($is_admin_route); - - $route_match = $this->prophesize(RouteMatchInterface::class); - $route_match->getRouteName()->willReturn($route_name); - - $account = $this->prophesize(AccountInterface::class); - $account->hasPermission('administer blocks')->willReturn($has_permission); - - $outside_in_manager = new OutsideInManager($admin_context->reveal(), $route_match->reveal(), $account->reveal()); - - $this->assertSame($expected, $outside_in_manager->isApplicable()); - } - - /** - * Data provider for ::testIsApplicable(). - */ - public function providerTestIsApplicable() { - $data = []; - - // Passing combination. - $data[] = [FALSE, 'the_route_name', TRUE, TRUE]; - - // Failing combinations. - $data[] = [TRUE, 'the_route_name', TRUE, FALSE]; - $data[] = [TRUE, 'the_route_name', FALSE, FALSE]; - $data[] = [TRUE, 'block.admin_demo', TRUE, FALSE]; - $data[] = [TRUE, 'block.admin_demo', FALSE, FALSE]; - $data[] = [FALSE, 'the_route_name', FALSE, FALSE]; - $data[] = [FALSE, 'block.admin_demo', TRUE, FALSE]; - $data[] = [FALSE, 'block.admin_demo', FALSE, FALSE]; - - return $data; - } - -} diff --git a/core/modules/page_cache/page_cache.info.yml b/core/modules/page_cache/page_cache.info.yml index 4951bd77..da7e4cb9 100644 --- a/core/modules/page_cache/page_cache.info.yml +++ b/core/modules/page_cache/page_cache.info.yml @@ -5,8 +5,8 @@ package: Core # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/page_cache/page_cache.module b/core/modules/page_cache/page_cache.module index 3b8baf4c..ff728619 100644 --- a/core/modules/page_cache/page_cache.module +++ b/core/modules/page_cache/page_cache.module @@ -15,7 +15,7 @@ function page_cache_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.page_cache': $output = '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Internal Page Cache module caches pages for anonymous users in the database. For more information, see the online documentation for the Internal Page Cache module.', array(':pagecache-documentation' => 'https://www.drupal.org/documentation/modules/internal_page_cache')) . '

    '; + $output .= '

    ' . t('The Internal Page Cache module caches pages for anonymous users in the database. For more information, see the online documentation for the Internal Page Cache module.', [':pagecache-documentation' => 'https://www.drupal.org/documentation/modules/internal_page_cache']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Speeding up your site') . '
    '; @@ -23,7 +23,7 @@ function page_cache_help($route_name, RouteMatchInterface $route_match) { $output .= '
    ' . t('Pages are usually identical for all anonymous users, while they can be personalized for each authenticated user. This is why entire pages can be cached for anonymous users, whereas they will have to be rebuilt for every authenticated user.') . '
    '; $output .= '
    ' . t('To speed up your site for authenticated users, see the Dynamic Page Cache module.', [':dynamic_page_cache-help' => (\Drupal::moduleHandler()->moduleExists('dynamic_page_cache')) ? Url::fromRoute('help.page', ['name' => 'dynamic_page_cache'])->toString() : '#']) . '

    '; $output .= '
    ' . t('Configuring the internal page cache') . '
    '; - $output .= '
    ' . t('On the Performance page, you can configure how long browsers and proxies may cache pages; that setting is also respected by the Internal Page Cache module. There is no other configuration.', array(':cache-settings' => \Drupal::url('system.performance_settings'))) . '
    '; + $output .= '
    ' . t('On the Performance page, you can configure how long browsers and proxies may cache pages; that setting is also respected by the Internal Page Cache module. There is no other configuration.', [':cache-settings' => \Drupal::url('system.performance_settings')]) . '
    '; $output .= '
    '; return $output; diff --git a/core/modules/page_cache/page_cache.services.yml b/core/modules/page_cache/page_cache.services.yml index 6563a019..35b899a1 100644 --- a/core/modules/page_cache/page_cache.services.yml +++ b/core/modules/page_cache/page_cache.services.yml @@ -1,6 +1,13 @@ services: http_middleware.page_cache: class: Drupal\page_cache\StackMiddleware\PageCache - arguments: ['@cache.render', '@page_cache_request_policy', '@page_cache_response_policy'] + arguments: ['@cache.page', '@page_cache_request_policy', '@page_cache_response_policy'] tags: - { name: http_middleware, priority: 200, responder: true } + + cache.page: + class: Drupal\Core\Cache\CacheBackendInterface + tags: + - { name: cache.bin } + factory: cache_factory:get + arguments: [page] diff --git a/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php index a4d9053b..82456b13 100644 --- a/core/modules/page_cache/src/StackMiddleware/PageCache.php +++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php @@ -133,23 +133,6 @@ protected function lookup(Request $request, $type = self::MASTER_REQUEST, $catch $response->setPrivate(); } - // Negotiate whether to use compression. - if (extension_loaded('zlib') && $response->headers->get('Content-Encoding') === 'gzip') { - if (strpos($request->headers->get('Accept-Encoding'), 'gzip') !== FALSE) { - // The response content is already gzip'ed, so make sure - // zlib.output_compression does not compress it once more. - ini_set('zlib.output_compression', '0'); - } - else { - // The client does not support compression. Decompress the content and - // remove the Content-Encoding header. - $content = $response->getContent(); - $content = gzinflate(substr(substr($content, 10), 0, -8)); - $response->setContent($content); - $response->headers->remove('Content-Encoding'); - } - } - // Perform HTTP revalidation. // @todo Use Response::isNotModified() as // per https://www.drupal.org/node/2259489. @@ -160,15 +143,17 @@ protected function lookup(Request $request, $type = self::MASTER_REQUEST, $catch $if_none_match = $request->server->has('HTTP_IF_NONE_MATCH') ? stripslashes($request->server->get('HTTP_IF_NONE_MATCH')) : FALSE; if ($if_modified_since && $if_none_match - && $if_none_match == $response->getEtag() // etag must match - && $if_modified_since == $last_modified->getTimestamp()) { // if-modified-since must match + // etag must match. + && $if_none_match == $response->getEtag() + // if-modified-since must match. + && $if_modified_since == $last_modified->getTimestamp()) { $response->setStatusCode(304); $response->setContent(NULL); // In the case of a 304 response, certain headers must be sent, and the // remaining may not (see RFC 2616, section 10.3.5). foreach (array_keys($response->headers->all()) as $name) { - if (!in_array($name, array('content-location', 'expires', 'cache-control', 'vary'))) { + if (!in_array($name, ['content-location', 'expires', 'cache-control', 'vary'])) { $response->headers->remove($name); } } @@ -181,14 +166,6 @@ protected function lookup(Request $request, $type = self::MASTER_REQUEST, $catch /** * Fetches a response from the backend and stores it in the cache. * - * If page_compression is enabled, a gzipped version of the page is stored in - * the cache to avoid compressing the output on each request. The cache entry - * is unzipped in the relatively rare event that the page is requested by a - * client without gzip support. - * - * Page compression requires the PHP zlib extension - * (http://php.net/manual/ref.zlib.php). - * * @see drupal_page_header() * * @param \Symfony\Component\HttpFoundation\Request $request @@ -206,6 +183,26 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch /** @var \Symfony\Component\HttpFoundation\Response $response */ $response = $this->httpKernel->handle($request, $type, $catch); + // Only set the 'X-Drupal-Cache' header if caching is allowed for this + // response. + if ($this->storeResponse($request, $response)) { + $response->headers->set('X-Drupal-Cache', 'MISS'); + } + + return $response; + } + + /** + * Stores a response in the page cache. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * A request object. + * @param \Symfony\Component\HttpFoundation\Response $response + * A response object that should be stored in the page cache. + * + * @returns bool + */ + protected function storeResponse(Request $request, Response $response) { // Drupal's primary cache invalidation architecture is cache tags: any // response that varies by a configuration value or data in a content // entity should have cache tags, to allow for instant cache invalidation @@ -228,7 +225,7 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch // so by replacing/extending this middleware service or adding another // one. if (!$response instanceof CacheableResponseInterface) { - return $response; + return FALSE; } // Currently it is not possible to cache binary file or streamed responses: @@ -236,12 +233,12 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch // Therefore exclude them, even for subclasses that implement // CacheableResponseInterface. if ($response instanceof BinaryFileResponse || $response instanceof StreamedResponse) { - return $response; + return FALSE; } // Allow policy rules to further restrict which responses to cache. if ($this->responsePolicy->check($response, $request) === ResponsePolicyInterface::DENY) { - return $response; + return FALSE; } $request_time = $request->server->get('REQUEST_TIME'); @@ -263,20 +260,22 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch $expire = $request_time + $cache_ttl_4xx; } } - else { - $date = $response->getExpires()->getTimestamp(); + // The getExpires method could return NULL if Expires header is not set, so + // the returned value needs to be checked before calling getTimestamp. + elseif ($expires = $response->getExpires()) { + $date = $expires->getTimestamp(); $expire = ($date > $request_time) ? $date : Cache::PERMANENT; } + else { + $expire = Cache::PERMANENT; + } if ($expire === Cache::PERMANENT || $expire > $request_time) { $tags = $response->getCacheableMetadata()->getCacheTags(); $this->set($request, $response, $expire, $tags); } - // Mark response as a cache miss. - $response->headers->set('X-Drupal-Cache', 'MISS'); - - return $response; + return TRUE; } /** @@ -340,10 +339,10 @@ protected function set(Request $request, Response $response, $expire, array $tag * The cache ID for this request. */ protected function getCacheId(Request $request) { - $cid_parts = array( - $request->getUri(), + $cid_parts = [ + $request->getSchemeAndHttpHost() . $request->getRequestUri(), $request->getRequestFormat(), - ); + ]; return implode(':', $cid_parts); } diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml b/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml index 1e1a8d79..665298ee 100644 --- a/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml +++ b/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml @@ -5,8 +5,8 @@ description: 'Support module for the Page Cache module tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.install b/core/modules/page_cache/tests/modules/page_cache_form_test.install index 72e3d70b..07f68ce4 100644 --- a/core/modules/page_cache/tests/modules/page_cache_form_test.install +++ b/core/modules/page_cache/tests/modules/page_cache_form_test.install @@ -5,6 +5,9 @@ * Install hooks for page_cache_form_test. */ +/** + * Implements hook_install(). + */ function page_cache_form_test_install() { // Set an explicit module weight, to ensure that the form alter hook is // always called after page_cache_form_alter(). diff --git a/core/modules/page_cache/tests/modules/src/Form/TestForm.php b/core/modules/page_cache/tests/modules/src/Form/TestForm.php index 7b60343b..b712ca0c 100644 --- a/core/modules/page_cache/tests/modules/src/Form/TestForm.php +++ b/core/modules/page_cache/tests/modules/src/Form/TestForm.php @@ -25,6 +25,6 @@ public function buildForm(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function submitForm(array &$form, FormStateInterface $form_state) { } + public function submitForm(array &$form, FormStateInterface $form_state) {} } diff --git a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php similarity index 82% rename from core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php rename to core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php index c8db96e5..5f84a347 100644 --- a/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php +++ b/core/modules/page_cache/tests/src/Functional/PageCacheTagsIntegrationTest.php @@ -1,21 +1,22 @@ drupalCreateUser(); - $node_1 = $this->drupalCreateNode(array( + $node_1 = $this->drupalCreateNode([ 'uid' => $author_1->id(), 'title' => 'Node 1', - 'body' => array( - 0 => array('value' => 'Body 1', 'format' => 'basic_html'), - ), - 'promote' => NODE_PROMOTED, - )); + 'body' => [ + 0 => ['value' => 'Body 1', 'format' => 'basic_html'], + ], + 'promote' => NodeInterface::PROMOTED, + ]); $author_2 = $this->drupalCreateUser(); - $node_2 = $this->drupalCreateNode(array( + $node_2 = $this->drupalCreateNode([ 'uid' => $author_2->id(), 'title' => 'Node 2', - 'body' => array( - 0 => array('value' => 'Body 2', 'format' => 'full_html'), - ), - 'promote' => NODE_PROMOTED, - )); + 'body' => [ + 0 => ['value' => 'Body 2', 'format' => 'full_html'], + ], + 'promote' => NodeInterface::PROMOTED, + ]); // Place a block, but only make it visible on full node page 2. - $block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array( - 'visibility' => array( - 'request_path' => array( + $block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', [ + 'visibility' => [ + 'request_path' => [ 'pages' => '/node/' . $node_2->id(), - ), - ), - )); + ], + ], + ]); $cache_contexts = [ 'languages:' . LanguageInterface::TYPE_INTERFACE, @@ -78,7 +79,8 @@ function testPageCacheTags() { ]; // Full node page 1. - $this->assertPageCacheContextsAndTags($node_1->urlInfo(), $cache_contexts, array( + $this->assertPageCacheContextsAndTags($node_1->urlInfo(), $cache_contexts, [ + 'http_response', 'rendered', 'block_view', 'config:block_list', @@ -112,13 +114,14 @@ function testPageCacheTags() { // FinishResponseSubscriber adds this cache tag to responses that have the // 'user.permissions' cache context for anonymous users. 'config:user.role.anonymous', - )); + ]); // Render the view block adds the languages cache context. $cache_contexts[] = 'languages:' . LanguageInterface::TYPE_CONTENT; // Full node page 2. - $this->assertPageCacheContextsAndTags($node_2->urlInfo(), $cache_contexts, array( + $this->assertPageCacheContextsAndTags($node_2->urlInfo(), $cache_contexts, [ + 'http_response', 'rendered', 'block_view', 'config:block_list', @@ -155,7 +158,7 @@ function testPageCacheTags() { // 'user.permissions' cache context for anonymous users. 'config:user.role.anonymous', 'user:0', - )); + ]); } } diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/tests/src/Functional/PageCacheTest.php similarity index 76% rename from core/modules/page_cache/src/Tests/PageCacheTest.php rename to core/modules/page_cache/tests/src/Functional/PageCacheTest.php index 1ec9282e..bf4951d9 100644 --- a/core/modules/page_cache/src/Tests/PageCacheTest.php +++ b/core/modules/page_cache/tests/src/Functional/PageCacheTest.php @@ -1,13 +1,14 @@ config('system.performance'); $config->set('cache.page.max_age', 300); $config->save(); $path = 'system-test/cache_tags_page'; - $tags = array('system_test_cache_tags_page'); + $tags = ['system_test_cache_tags_page']; $this->drupalGet($path); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); // Verify a cache hit, but also the presence of the correct cache tags. $this->drupalGet($path); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $cid_parts = array(\Drupal::url('system_test.cache_tags_page', array(), array('absolute' => TRUE)), 'html'); + $cid_parts = [\Drupal::url('system_test.cache_tags_page', [], ['absolute' => TRUE]), 'html']; $cid = implode(':', $cid_parts); - $cache_entry = \Drupal::cache('render')->get($cid); + $cache_entry = \Drupal::cache('page')->get($cid); sort($cache_entry->tags); - $expected_tags = array( + $expected_tags = [ 'config:user.role.anonymous', + 'http_response', 'pre_render', 'rendered', 'system_test_cache_tags_page', - ); + ]; $this->assertIdentical($cache_entry->tags, $expected_tags); Cache::invalidateTags($tags); @@ -77,27 +81,31 @@ function testPageCacheTags() { /** * Test that the page cache doesn't depend on cacheability headers. */ - function testPageCacheTagsIndependentFromCacheabilityHeaders() { - $this->setHttpResponseDebugCacheabilityHeaders(FALSE); + public function testPageCacheTagsIndependentFromCacheabilityHeaders() { + // Disable the cacheability headers. + $this->setContainerParameter('http.response.debug_cacheability_headers', FALSE); + $this->rebuildContainer(); + $this->resetAll(); $path = 'system-test/cache_tags_page'; - $tags = array('system_test_cache_tags_page'); + $tags = ['system_test_cache_tags_page']; $this->drupalGet($path); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); // Verify a cache hit, but also the presence of the correct cache tags. $this->drupalGet($path); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $cid_parts = array(\Drupal::url('system_test.cache_tags_page', array(), array('absolute' => TRUE)), 'html'); + $cid_parts = [\Drupal::url('system_test.cache_tags_page', [], ['absolute' => TRUE]), 'html']; $cid = implode(':', $cid_parts); - $cache_entry = \Drupal::cache('render')->get($cid); + $cache_entry = \Drupal::cache('page')->get($cid); sort($cache_entry->tags); - $expected_tags = array( + $expected_tags = [ 'config:user.role.anonymous', + 'http_response', 'pre_render', 'rendered', 'system_test_cache_tags_page', - ); + ]; $this->assertIdentical($cache_entry->tags, $expected_tags); Cache::invalidateTags($tags); @@ -109,7 +117,7 @@ function testPageCacheTagsIndependentFromCacheabilityHeaders() { * Tests support for different cache items with different request formats * specified via a query parameter. */ - function testQueryParameterFormatRequests() { + public function testQueryParameterFormatRequests() { $config = $this->config('system.performance'); $config->set('cache.page.max_age', 300); $config->save(); @@ -154,7 +162,7 @@ function testQueryParameterFormatRequests() { // Clear the page cache. After that request a HAL request, followed by an // ordinary HTML one. - \Drupal::cache('render')->deleteAll(); + \Drupal::cache('page')->deleteAll(); $this->drupalGet($node_url_with_hal_json_format); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); $this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/hal+json'); @@ -173,7 +181,7 @@ function testQueryParameterFormatRequests() { /** * Tests support of requests with If-Modified-Since and If-None-Match headers. */ - function testConditionalRequests() { + public function testConditionalRequests() { $config = $this->config('system.performance'); $config->set('cache.page.max_age', 300); $config->save(); @@ -183,33 +191,42 @@ function testConditionalRequests() { // Verify the page is not printed twice when the cache is cold. $this->assertNoPattern('#drupalHead(''); + $this->drupalGet(''); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); $etag = $this->drupalGetHeader('ETag'); $last_modified = $this->drupalGetHeader('Last-Modified'); - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag)); + $this->drupalGet('', [], ['If-Modified-Since' => $last_modified, 'If-None-Match' => $etag]); $this->assertResponse(304, 'Conditional request returned 304 Not Modified.'); - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC822, strtotime($last_modified)), 'If-None-Match: ' . $etag)); + $this->drupalGet('', [], [ + 'If-Modified-Since' => gmdate(DATE_RFC822, strtotime($last_modified)), + 'If-None-Match' => $etag, + ]); $this->assertResponse(304, 'Conditional request with obsolete If-Modified-Since date returned 304 Not Modified.'); - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC850, strtotime($last_modified)), 'If-None-Match: ' . $etag)); + $this->drupalGet('', [], [ + 'If-Modified-Since' => gmdate(DATE_RFC850, strtotime($last_modified)), + 'If-None-Match' => $etag, + ]); $this->assertResponse(304, 'Conditional request with obsolete If-Modified-Since date returned 304 Not Modified.'); - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified)); + $this->drupalGet('', [], ['If-Modified-Since' => $last_modified, 'If-None-Match' => NULL]); // Verify the page is not printed twice when the cache is warm. $this->assertNoPattern('#assertResponse(200, 'Conditional request without If-None-Match returned 200 OK.'); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DateTimePlus::RFC7231, strtotime($last_modified) + 1), 'If-None-Match: ' . $etag)); + $this->drupalGet('', [], [ + 'If-Modified-Since' => gmdate(DateTimePlus::RFC7231, strtotime($last_modified) + 1), + 'If-None-Match' => $etag, + ]); $this->assertResponse(200, 'Conditional request with new a If-Modified-Since date newer than Last-Modified returned 200 OK.'); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); $user = $this->drupalCreateUser(); $this->drupalLogin($user); - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag)); + $this->drupalGet('', [], ['If-Modified-Since' => $last_modified, 'If-None-Match' => $etag]); $this->assertResponse(200, 'Conditional request returned 200 OK for authenticated user.'); $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Absence of Page was not cached.'); } @@ -217,14 +234,13 @@ function testConditionalRequests() { /** * Tests cache headers. */ - function testPageCache() { + public function testPageCache() { $config = $this->config('system.performance'); $config->set('cache.page.max_age', 300); - $config->set('response.gzip', 1); $config->save(); // Fill the cache. - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar'))); + $this->drupalGet('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'bar']]); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); $this->assertEqual(strtolower($this->drupalGetHeader('Vary')), 'cookie,accept-encoding', 'Vary header was sent.'); // Symfony's Response logic determines a specific order for the subvalues @@ -235,7 +251,7 @@ function testPageCache() { $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); // Check cache. - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar'))); + $this->drupalGet('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'bar']]); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); $this->assertEqual(strtolower($this->drupalGetHeader('Vary')), 'cookie,accept-encoding', 'Vary: Cookie header was sent.'); $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); @@ -243,15 +259,15 @@ function testPageCache() { $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); // Check replacing default headers. - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Expires', 'value' => 'Fri, 19 Nov 2008 05:00:00 GMT'))); + $this->drupalGet('system-test/set-header', ['query' => ['name' => 'Expires', 'value' => 'Fri, 19 Nov 2008 05:00:00 GMT']]); $this->assertEqual($this->drupalGetHeader('Expires'), 'Fri, 19 Nov 2008 05:00:00 GMT', 'Default header was replaced.'); - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Vary', 'value' => 'User-Agent'))); + $this->drupalGet('system-test/set-header', ['query' => ['name' => 'Vary', 'value' => 'User-Agent']]); $this->assertEqual(strtolower($this->drupalGetHeader('Vary')), 'user-agent,accept-encoding', 'Default header was replaced.'); // Check that authenticated users bypass the cache. $user = $this->drupalCreateUser(); $this->drupalLogin($user); - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar'))); + $this->drupalGet('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'bar']]); $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Caching was bypassed.'); $this->assertTrue(strpos(strtolower($this->drupalGetHeader('Vary')), 'cookie') === FALSE, 'Vary: Cookie header was not sent.'); $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'must-revalidate, no-cache, private', 'Cache-Control header was sent.'); @@ -330,7 +346,7 @@ public function testPageCacheAnonymousRolePermissions() { /** * Tests the 4xx-response cache tag is added and invalidated. */ - function testPageCacheAnonymous403404() { + public function testPageCacheAnonymous403404() { $admin_url = Url::fromRoute('system.admin'); $invalid_url = 'foo/does_not_exist'; $tests = [ @@ -347,16 +363,16 @@ function testPageCacheAnonymous403404() { $this->drupalGet($content_url); $this->assertResponse($code); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $entity_values = array( + $entity_values = [ 'name' => $this->randomMachineName(), 'user_id' => 1, - 'field_test_text' => array( - 0 => array( + 'field_test_text' => [ + 0 => [ 'value' => $this->randomString(), 'format' => 'plain_text', - ) - ), - ); + ] + ], + ]; $entity = EntityTest::create($entity_values); $entity->save(); // Saving an entity clears 4xx cache tag. @@ -373,26 +389,26 @@ function testPageCacheAnonymous403404() { $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); // Ensure the 'expire' field on the cache entry uses cache_ttl_4xx. - $cache_item = \Drupal::service('cache.render')->get($this->getUrl() . ':html'); + $cache_item = \Drupal::service('cache.page')->get($this->getUrl() . ':html'); $difference = $cache_item->expire - (int) $cache_item->created; // Given that a second might have passed we cannot be sure that // $difference will exactly equal the default cache_ttl_4xx setting. // Account for any timing difference or rounding errors by ensuring the - // value is within 5 seconds. + // value is within 10 seconds. $this->assertTrue( - $difference > $cache_ttl_4xx - 5 && - $difference < $cache_ttl_4xx + 5, - 'The cache entry expiry time uses the cache_ttl_4xx setting.' + $difference > $cache_ttl_4xx - 10 && + $difference < $cache_ttl_4xx + 10, + "The cache entry expiry time uses the cache_ttl_4xx setting. Expire: {$cache_item->expire} Created: {$cache_item->created}" ); } // Disable 403 and 404 caching. - $settings['settings']['cache_ttl_4xx'] = (object) array( + $settings['settings']['cache_ttl_4xx'] = (object) [ 'value' => 0, 'required' => TRUE, - ); + ]; $this->writeSettings($settings); - \Drupal::service('cache.render')->deleteAll(); + \Drupal::service('cache.page')->deleteAll(); foreach ($tests as $code => $content_url) { // Getting the 404 page twice should still result in a cache miss. @@ -411,10 +427,10 @@ public function testPageCacheWithoutVaryCookie() { $config->set('cache.page.max_age', 300); $config->save(); - $settings['settings']['omit_vary_cookie'] = (object) array( + $settings['settings']['omit_vary_cookie'] = (object) [ 'value' => TRUE, 'required' => TRUE, - ); + ]; $this->writeSettings($settings); // Fill the cache. @@ -514,27 +530,117 @@ public function testCacheableResponseResponses() { * Tests that HEAD requests are treated the same as GET requests. */ public function testHead() { + /** @var \GuzzleHttp\ClientInterface $client */ + $client = $this->getSession()->getDriver()->getClient()->getClient(); + // GET, then HEAD. $url_a = $this->buildUrl('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'bar']]); - $response_body = $this->curlExec([CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $url_a, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_NOBODY => FALSE]); + $response_body = $this->drupalGet($url_a); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); $this->assertEqual('The following header was set: Foo: bar', $response_body); - $response_body = $this->curlExec([CURLOPT_HTTPGET => FALSE, CURLOPT_URL => $url_a, CURLOPT_CUSTOMREQUEST => 'HEAD', CURLOPT_NOBODY => FALSE]); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); - $this->assertEqual('', $response_body); + $response = $client->request('HEAD', $url_a); + $this->assertEqual($response->getHeaderLine('X-Drupal-Cache'), 'HIT', 'Page was cached.'); + $this->assertEqual($response->getHeaderLine('Foo'), 'bar', 'Custom header was sent.'); + $this->assertEqual('', $response->getBody()->getContents()); // HEAD, then GET. $url_b = $this->buildUrl('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'baz']]); - $response_body = $this->curlExec([CURLOPT_HTTPGET => FALSE, CURLOPT_URL => $url_b, CURLOPT_CUSTOMREQUEST => 'HEAD', CURLOPT_NOBODY => FALSE]); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); - $this->assertEqual($this->drupalGetHeader('Foo'), 'baz', 'Custom header was sent.'); - $this->assertEqual('', $response_body); - $response_body = $this->curlExec([CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $url_b, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_NOBODY => FALSE]); + $response = $client->request('HEAD', $url_b); + $this->assertEqual($response->getHeaderLine('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); + $this->assertEqual($response->getHeaderLine('Foo'), 'baz', 'Custom header was sent.'); + $this->assertEqual('', $response->getBody()->getContents()); + $response_body = $this->drupalGet($url_b); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); $this->assertEqual($this->drupalGetHeader('Foo'), 'baz', 'Custom header was sent.'); $this->assertEqual('The following header was set: Foo: baz', $response_body); } + /** + * Test a cacheable response with custom cache control. + */ + public function testCacheableWithCustomCacheControl() { + $config = $this->config('system.performance'); + $config->set('cache.page.max_age', 300); + $config->save(); + + $this->drupalGet('/system-test/custom-cache-control'); + $this->assertResponse(200); + $this->assertHeader('Cache-Control', 'bar, private'); + } + + /** + * Test that URLs are cached in a not normalized form. + */ + public function testNoUrlNormalization() { + + // Use absolute URLs to avoid any processing. + $url = Url::fromRoute('')->setAbsolute()->toString(); + + // In each test, the first array value is raw URL, the second one is the + // possible normalized URL. + $tests = [ + [ + $url . '?z=z&a=a', + $url . '?a=a&z=z', + ], + [ + $url . '?', + $url . '', + ], + [ + $url . '?a=b+c', + $url . '?a=b%20c', + ], + ]; + + foreach ($tests as list($url_raw, $url_normalized)) { + // Initialize cache on raw URL. + $headers = $this->getHeaders($url_raw); + $this->assertEquals('MISS', $headers['X-Drupal-Cache']); + + // Ensure cache was set. + $headers = $this->getHeaders($url_raw); + $this->assertEquals('HIT', $headers['X-Drupal-Cache'], "Cache was set for {$url_raw} URL."); + + // Check if the normalized URL is not cached. + $headers = $this->getHeaders($url_normalized); + $this->assertEquals('MISS', $headers['X-Drupal-Cache'], "Cache is missing for {$url_normalized} URL."); + } + } + + /** + * Retrieves only the headers for an absolute path. + * + * Executes a cURL request without any modifications to the given URL. + * Note that Guzzle always normalizes URLs which prevents testing all + * possible edge cases. + * + * @param string $url + * URL to request. + * + * @return array + * Array of headers. + */ + protected function getHeaders($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_HEADER, TRUE); + curl_setopt($ch, CURLOPT_NOBODY, TRUE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ch, CURLOPT_USERAGENT, drupal_generate_test_ua($this->databasePrefix)); + $output = curl_exec($ch); + curl_close($ch); + + $headers = []; + foreach (explode("\n", $output) as $header) { + if (strpos($header, ':')) { + list($key, $value) = explode(':', $header, 2); + $headers[trim($key)] = trim($value); + } + } + + return $headers; + } + } diff --git a/core/modules/path/migration_templates/d6_url_alias.yml b/core/modules/path/migration_templates/d6_url_alias.yml index 968b1e69..fcf20364 100644 --- a/core/modules/path/migration_templates/d6_url_alias.yml +++ b/core/modules/path/migration_templates/d6_url_alias.yml @@ -30,7 +30,7 @@ process: index: - 1 - - plugin: migration + plugin: migration_lookup migration: d6_node_translation destination: plugin: url_alias diff --git a/core/modules/path/migration_templates/d7_url_alias.yml b/core/modules/path/migration_templates/d7_url_alias.yml index a3ddec1a..dffaf468 100644 --- a/core/modules/path/migration_templates/d7_url_alias.yml +++ b/core/modules/path/migration_templates/d7_url_alias.yml @@ -18,5 +18,17 @@ process: - constants/slash - alias langcode: language + node_translation: + - + plugin: explode + source: source + delimiter: / + - + plugin: extract + index: + - 1 + - + plugin: migration_lookup + migration: d7_node_translation destination: plugin: url_alias diff --git a/core/modules/path/path.api.php b/core/modules/path/path.api.php index 04e1fb31..df20b95e 100644 --- a/core/modules/path/path.api.php +++ b/core/modules/path/path.api.php @@ -21,10 +21,10 @@ */ function hook_path_insert($path) { db_insert('mytable') - ->fields(array( + ->fields([ 'alias' => $path['alias'], 'pid' => $path['pid'], - )) + ]) ->execute(); } @@ -40,7 +40,7 @@ function hook_path_insert($path) { function hook_path_update($path) { if ($path['alias'] != $path['original']['alias']) { db_update('mytable') - ->fields(array('alias' => $path['alias'])) + ->fields(['alias' => $path['alias']]) ->condition('pid', $path['pid']) ->execute(); } diff --git a/core/modules/path/path.es6.js b/core/modules/path/path.es6.js new file mode 100644 index 00000000..97ea9f4d --- /dev/null +++ b/core/modules/path/path.es6.js @@ -0,0 +1,25 @@ +/** + * @file + * Attaches behaviors for the Path module. + */ +(function ($, Drupal) { + /** + * Behaviors for settings summaries on path edit forms. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches summary behavior on path edit forms. + */ + Drupal.behaviors.pathDetailsSummaries = { + attach(context) { + $(context).find('.path-form').drupalSetSummary((context) => { + const path = $('.js-form-item-path-0-alias input').val(); + + return path ? + Drupal.t('Alias: @alias', { '@alias': path }) : + Drupal.t('No alias'); + }); + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/path/path.info.yml b/core/modules/path/path.info.yml index 6c119a9a..c806ad36 100644 --- a/core/modules/path/path.info.yml +++ b/core/modules/path/path.info.yml @@ -6,8 +6,8 @@ package: Core # core: 8.x configure: path.admin_overview -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/path/path.install b/core/modules/path/path.install index 7d454a00..fba049ea 100644 --- a/core/modules/path/path.install +++ b/core/modules/path/path.install @@ -5,11 +5,6 @@ * Update functions for the path module. */ -/** - * @addtogroup updates-8.2.0 - * @{ - */ - /** * Change the path field to computed for node and taxonomy_term. */ @@ -26,7 +21,3 @@ function path_update_8200() { } } } - -/** - * @} End of "addtogroup updates-8.2.0". - */ diff --git a/core/modules/path/path.js b/core/modules/path/path.js index dfa2c052..c50f2d7f 100644 --- a/core/modules/path/path.js +++ b/core/modules/path/path.js @@ -1,29 +1,18 @@ /** - * @file - * Attaches behaviors for the Path module. - */ -(function ($, Drupal) { - - 'use strict'; +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ - /** - * Behaviors for settings summaries on path edit forms. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches summary behavior on path edit forms. - */ +(function ($, Drupal) { Drupal.behaviors.pathDetailsSummaries = { - attach: function (context) { + attach: function attach(context) { $(context).find('.path-form').drupalSetSummary(function (context) { var path = $('.js-form-item-path-0-alias input').val(); - return path ? - Drupal.t('Alias: @alias', {'@alias': path}) : - Drupal.t('No alias'); + return path ? Drupal.t('Alias: @alias', { '@alias': path }) : Drupal.t('No alias'); }); } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/path/path.module b/core/modules/path/path.module index 182c6a9d..38cb57be 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -5,6 +5,7 @@ * Enables users to rename URLs. */ +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; @@ -18,13 +19,13 @@ function path_help($route_name, RouteMatchInterface $route_match) { case 'help.page.path': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Path module allows you to specify an alias, or custom URL, for any existing internal system path. Aliases should not be confused with URL redirects, which allow you to forward a changed or inactive URL to a new URL. In addition to making URLs more readable, aliases also help search engines index content more effectively. Multiple aliases may be used for a single internal system path. To automate the aliasing of paths, you can install the contributed module Pathauto. For more information, see the online documentation for the Path module.', array(':path' => 'https://www.drupal.org/documentation/modules/path', ':pathauto' => 'https://www.drupal.org/project/pathauto')) . '

    '; + $output .= '

    ' . t('The Path module allows you to specify an alias, or custom URL, for any existing internal system path. Aliases should not be confused with URL redirects, which allow you to forward a changed or inactive URL to a new URL. In addition to making URLs more readable, aliases also help search engines index content more effectively. Multiple aliases may be used for a single internal system path. To automate the aliasing of paths, you can install the contributed module Pathauto. For more information, see the online documentation for the Path module.', [':path' => 'https://www.drupal.org/documentation/modules/path', ':pathauto' => 'https://www.drupal.org/project/pathauto']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Creating aliases') . '
    '; - $output .= '
    ' . t('If you create or edit a taxonomy term you can add an alias (for example music/jazz) in the field "URL alias". When creating or editing content you can add an alias (for example about-us/team) under the section "URL path settings" in the field "URL alias". Aliases for any other path can be added through the page URL aliases. To add aliases a user needs the permission Create and edit URL aliases.', array(':aliases' => \Drupal::url('path.admin_overview'), ':permissions' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-path')))) . '
    '; + $output .= '
    ' . t('If you create or edit a taxonomy term you can add an alias (for example music/jazz) in the field "URL alias". When creating or editing content you can add an alias (for example about-us/team) under the section "URL path settings" in the field "URL alias". Aliases for any other path can be added through the page URL aliases. To add aliases a user needs the permission Create and edit URL aliases.', [':aliases' => \Drupal::url('path.admin_overview'), ':permissions' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-path'])]) . '
    '; $output .= '
    ' . t('Managing aliases') . '
    '; - $output .= '
    ' . t('The Path module provides a way to search and view a list of all aliases that are in use on your website. Aliases can be added, edited and deleted through this list.', array(':aliases' => \Drupal::url('path.admin_overview'))) . '
    '; + $output .= '
    ' . t('The Path module provides a way to search and view a list of all aliases that are in use on your website. Aliases can be added, edited and deleted through this list.', [':aliases' => \Drupal::url('path.admin_overview')]) . '
    '; $output .= '
    '; return $output; @@ -41,20 +42,20 @@ function path_help($route_name, RouteMatchInterface $route_match) { */ function path_form_node_form_alter(&$form, FormStateInterface $form_state) { $node = $form_state->getFormObject()->getEntity(); - $form['path_settings'] = array( + $form['path_settings'] = [ '#type' => 'details', '#title' => t('URL path settings'), '#open' => !empty($form['path']['widget'][0]['alias']['#value']), '#group' => 'advanced', '#access' => !empty($form['path']['#access']) && $node->hasField('path') && $node->get('path')->access('edit'), - '#attributes' => array( - 'class' => array('path-form'), - ), - '#attached' => array( - 'library' => array('path/drupal.path'), - ), + '#attributes' => [ + 'class' => ['path-form'], + ], + '#attached' => [ + 'library' => ['path/drupal.path'], + ], '#weight' => 30, - ); + ]; $form['path']['#group'] = 'path_settings'; } @@ -62,17 +63,31 @@ function path_form_node_form_alter(&$form, FormStateInterface $form_state) { * Implements hook_entity_base_field_info(). */ function path_entity_base_field_info(EntityTypeInterface $entity_type) { - if ($entity_type->id() === 'taxonomy_term' || $entity_type->id() === 'node') { + if (in_array($entity_type->id(), ['taxonomy_term', 'node', 'media'], TRUE)) { $fields['path'] = BaseFieldDefinition::create('path') ->setLabel(t('URL alias')) ->setTranslatable(TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'path', 'weight' => 30, - )) + ]) ->setDisplayConfigurable('form', TRUE) ->setComputed(TRUE); return $fields; } } + +/** + * Implements hook_entity_translation_create(). + */ +function path_entity_translation_create(ContentEntityInterface $translation) { + foreach ($translation->getFieldDefinitions() as $field_name => $field_definition) { + if ($field_definition->getType() === 'path' && $translation->get($field_name)->pid) { + // If there are values and a path ID, update the langcode and unset the + // path ID to save this as a new alias. + $translation->get($field_name)->langcode = $translation->language()->getId(); + $translation->get($field_name)->pid = NULL; + } + } +} diff --git a/core/modules/path/src/Controller/PathController.php b/core/modules/path/src/Controller/PathController.php index 26b5d769..51f88dd6 100644 --- a/core/modules/path/src/Controller/PathController.php +++ b/core/modules/path/src/Controller/PathController.php @@ -69,63 +69,63 @@ public function adminOverview(Request $request) { // alias with a language. $multilanguage = ($this->moduleHandler()->moduleExists('language') || $this->aliasStorage->languageAliasExists()); - $header = array(); - $header[] = array('data' => $this->t('Alias'), 'field' => 'alias', 'sort' => 'asc'); - $header[] = array('data' => $this->t('System'), 'field' => 'source'); + $header = []; + $header[] = ['data' => $this->t('Alias'), 'field' => 'alias', 'sort' => 'asc']; + $header[] = ['data' => $this->t('System'), 'field' => 'source']; if ($multilanguage) { - $header[] = array('data' => $this->t('Language'), 'field' => 'langcode'); + $header[] = ['data' => $this->t('Language'), 'field' => 'langcode']; } $header[] = $this->t('Operations'); - $rows = array(); + $rows = []; $destination = $this->getDestinationArray(); foreach ($this->aliasStorage->getAliasesForAdminListing($header, $keys) as $data) { - $row = array(); + $row = []; // @todo Should Path module store leading slashes? See // https://www.drupal.org/node/2430593. - $row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, array( - 'attributes' => array('title' => $data->alias), - ))); - $row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, array( + $row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, [ + 'attributes' => ['title' => $data->alias], + ])); + $row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, [ 'alias' => TRUE, - 'attributes' => array('title' => $data->source), - ))); + 'attributes' => ['title' => $data->source], + ])); if ($multilanguage) { $row['data']['language_name'] = $this->languageManager()->getLanguageName($data->langcode); } - $operations = array(); - $operations['edit'] = array( + $operations = []; + $operations['edit'] = [ 'title' => $this->t('Edit'), 'url' => Url::fromRoute('path.admin_edit', ['pid' => $data->pid], ['query' => $destination]), - ); - $operations['delete'] = array( + ]; + $operations['delete'] = [ 'title' => $this->t('Delete'), 'url' => Url::fromRoute('path.delete', ['pid' => $data->pid], ['query' => $destination]), - ); - $row['data']['operations'] = array( - 'data' => array( + ]; + $row['data']['operations'] = [ + 'data' => [ '#type' => 'operations', '#links' => $operations, - ), - ); + ], + ]; // If the system path maps to a different URL alias, highlight this table // row to let the user know of old aliases. if ($data->alias != $this->aliasManager->getAliasByPath($data->source, $data->langcode)) { - $row['class'] = array('warning'); + $row['class'] = ['warning']; } $rows[] = $row; } - $build['path_table'] = array( + $build['path_table'] = [ '#type' => 'table', '#header' => $header, '#rows' => $rows, - '#empty' => $this->t('No URL aliases available. Add URL alias.', array(':link' => $this->url('path.admin_add'))), - ); - $build['path_pager'] = array('#type' => 'pager'); + '#empty' => $this->t('No URL aliases available. Add URL alias.', [':link' => $this->url('path.admin_add')]), + ]; + $build['path_pager'] = ['#type' => 'pager']; return $build; } diff --git a/core/modules/path/src/Form/AddForm.php b/core/modules/path/src/Form/AddForm.php index 5b7acef8..8f8d4f6b 100644 --- a/core/modules/path/src/Form/AddForm.php +++ b/core/modules/path/src/Form/AddForm.php @@ -20,12 +20,12 @@ public function getFormId() { * {@inheritdoc} */ protected function buildPath($pid) { - return array( + return [ 'source' => '', 'alias' => '', 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'pid' => NULL, - ); + ]; } } diff --git a/core/modules/path/src/Form/DeleteForm.php b/core/modules/path/src/Form/DeleteForm.php index 45cd9a28..ae9257a7 100644 --- a/core/modules/path/src/Form/DeleteForm.php +++ b/core/modules/path/src/Form/DeleteForm.php @@ -16,14 +16,14 @@ class DeleteForm extends ConfirmFormBase { /** * The alias storage service. * - * @var AliasStorageInterface $path + * @var AliasStorageInterface */ protected $aliasStorage; /** * The path alias being deleted. * - * @var array $pathAlias + * @var array */ protected $pathAlias; @@ -57,7 +57,7 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return t('Are you sure you want to delete path alias %title?', array('%title' => $this->pathAlias['alias'])); + return t('Are you sure you want to delete path alias %title?', ['%title' => $this->pathAlias['alias']]); } /** @@ -71,7 +71,7 @@ public function getCancelUrl() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $pid = NULL) { - $this->pathAlias = $this->aliasStorage->load(array('pid' => $pid)); + $this->pathAlias = $this->aliasStorage->load(['pid' => $pid]); $form = parent::buildForm($form, $form_state); @@ -82,7 +82,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - $this->aliasStorage->delete(array('pid' => $this->pathAlias['pid'])); + $this->aliasStorage->delete(['pid' => $this->pathAlias['pid']]); $form_state->setRedirect('path.admin_overview'); } diff --git a/core/modules/path/src/Form/EditForm.php b/core/modules/path/src/Form/EditForm.php index aeb285da..7d4a3693 100644 --- a/core/modules/path/src/Form/EditForm.php +++ b/core/modules/path/src/Form/EditForm.php @@ -21,7 +21,7 @@ public function getFormId() { * {@inheritdoc} */ protected function buildPath($pid) { - return $this->aliasStorage->load(array('pid' => $pid)); + return $this->aliasStorage->load(['pid' => $pid]); } /** @@ -31,27 +31,27 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU $form = parent::buildForm($form, $form_state, $pid); $form['#title'] = $this->path['alias']; - $form['pid'] = array( + $form['pid'] = [ '#type' => 'hidden', '#value' => $this->path['pid'], - ); + ]; - $url = new Url('path.delete', array( + $url = new Url('path.delete', [ 'pid' => $this->path['pid'], - )); + ]); if ($this->getRequest()->query->has('destination')) { $url->setOption('query', $this->getDestinationArray()); } - $form['actions']['delete'] = array( + $form['actions']['delete'] = [ '#type' => 'link', '#title' => $this->t('Delete'), '#url' => $url, - '#attributes' => array( - 'class' => array('button', 'button--danger'), - ), - ); + '#attributes' => [ + 'class' => ['button', 'button--danger'], + ], + ]; return $form; } diff --git a/core/modules/path/src/Form/PathFilterForm.php b/core/modules/path/src/Form/PathFilterForm.php index 6ac15855..f7829061 100644 --- a/core/modules/path/src/Form/PathFilterForm.php +++ b/core/modules/path/src/Form/PathFilterForm.php @@ -21,31 +21,31 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $keys = NULL) { - $form['#attributes'] = array('class' => array('search-form')); - $form['basic'] = array( + $form['#attributes'] = ['class' => ['search-form']]; + $form['basic'] = [ '#type' => 'details', '#title' => $this->t('Filter aliases'), '#open' => TRUE, - '#attributes' => array('class' => array('container-inline')), - ); - $form['basic']['filter'] = array( + '#attributes' => ['class' => ['container-inline']], + ]; + $form['basic']['filter'] = [ '#type' => 'search', '#title' => 'Path alias', '#title_display' => 'invisible', '#default_value' => $keys, '#maxlength' => 128, '#size' => 25, - ); - $form['basic']['submit'] = array( + ]; + $form['basic']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Filter'), - ); + ]; if ($keys) { - $form['basic']['reset'] = array( + $form['basic']['reset'] = [ '#type' => 'submit', '#value' => $this->t('Reset'), - '#submit' => array('::resetForm'), - ); + '#submit' => ['::resetForm'], + ]; } return $form; } @@ -54,9 +54,9 @@ public function buildForm(array $form, FormStateInterface $form_state, $keys = N * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - $form_state->setRedirect('path.admin_overview_filter', array(), array( - 'query' => array('search' => trim($form_state->getValue('filter'))), - )); + $form_state->setRedirect('path.admin_overview_filter', [], [ + 'query' => ['search' => trim($form_state->getValue('filter'))], + ]); } /** diff --git a/core/modules/path/src/Form/PathFormBase.php b/core/modules/path/src/Form/PathFormBase.php index dba3a3fa..884d24fb 100644 --- a/core/modules/path/src/Form/PathFormBase.php +++ b/core/modules/path/src/Form/PathFormBase.php @@ -95,7 +95,7 @@ abstract protected function buildPath($pid); */ public function buildForm(array $form, FormStateInterface $form_state, $pid = NULL) { $this->path = $this->buildPath($pid); - $form['source'] = array( + $form['source'] = [ '#type' => 'textfield', '#title' => $this->t('Existing system path'), '#default_value' => $this->path['source'], @@ -104,8 +104,8 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU '#description' => $this->t('Specify the existing path you wish to alias. For example: /node/28, /forum/1, /taxonomy/term/1.'), '#field_prefix' => $this->requestContext->getCompleteBaseUrl(), '#required' => TRUE, - ); - $form['alias'] = array( + ]; + $form['alias'] = [ '#type' => 'textfield', '#title' => $this->t('Path alias'), '#default_value' => $this->path['alias'], @@ -114,17 +114,17 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "/about" when writing an about page.'), '#field_prefix' => $this->requestContext->getCompleteBaseUrl(), '#required' => TRUE, - ); + ]; // A hidden value unless language.module is enabled. if (\Drupal::moduleHandler()->moduleExists('language')) { $languages = \Drupal::languageManager()->getLanguages(); - $language_options = array(); + $language_options = []; foreach ($languages as $langcode => $language) { $language_options[$langcode] = $language->getName(); } - $form['langcode'] = array( + $form['langcode'] = [ '#type' => 'select', '#title' => $this->t('Language'), '#options' => $language_options, @@ -133,21 +133,21 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU '#default_value' => $this->path['langcode'], '#weight' => -10, '#description' => $this->t('A path alias set for a specific language will always be used when displaying this page in that language, and takes precedence over path aliases set as - None -.'), - ); + ]; } else { - $form['langcode'] = array( + $form['langcode'] = [ '#type' => 'value', '#value' => $this->path['langcode'] - ); + ]; } - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), '#button_type' => 'primary', - ); + ]; return $form; } @@ -193,7 +193,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { if (!$this->pathValidator->isValid(trim($source, '/'))) { - $form_state->setErrorByName('source', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $source))); + $form_state->setErrorByName('source', t("The path '@link_path' is either invalid or you do not have access to it.", ['@link_path' => $source])); } } diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php index ee03361d..a98e7186 100644 --- a/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php +++ b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php @@ -34,4 +34,42 @@ public function delete() { \Drupal::service('path.alias_storage')->delete($conditions); } + /** + * {@inheritdoc} + */ + public function getValue($include_computed = FALSE) { + $this->ensureLoaded(); + return parent::getValue($include_computed); + } + + /** + * {@inheritdoc} + */ + public function isEmpty() { + $this->ensureLoaded(); + return parent::isEmpty(); + } + + /** + * {@inheritdoc} + */ + public function getIterator() { + $this->ensureLoaded(); + return parent::getIterator(); + } + + /** + * Automatically create the first item for computed fields. + * + * This ensures that ::getValue() and ::isEmpty() calls will behave like a + * non-computed field. + * + * @todo: Move this to the base class in https://www.drupal.org/node/2392845. + */ + protected function ensureLoaded() { + if (!isset($this->list[0]) && $this->definition->isComputed()) { + $this->list[0] = $this->createItem(0); + } + } + } diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php index 239588fd..0f0a77bb 100644 --- a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php +++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php @@ -17,11 +17,26 @@ * description = @Translation("An entity field containing a path alias and related data."), * no_ui = TRUE, * default_widget = "path", - * list_class = "\Drupal\path\Plugin\Field\FieldType\PathFieldItemList" + * list_class = "\Drupal\path\Plugin\Field\FieldType\PathFieldItemList", + * constraints = {"PathAlias" = {}}, * ) */ class PathItem extends FieldItemBase { + /** + * Whether the alias has been loaded from the alias storage service yet. + * + * @var bool + */ + protected $isLoaded = FALSE; + + /** + * Whether the alias is currently being set. + * + * @var bool + */ + protected $isLoading = FALSE; + /** * {@inheritdoc} */ @@ -30,14 +45,48 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel ->setLabel(t('Path alias')); $properties['pid'] = DataDefinition::create('integer') ->setLabel(t('Path id')); + $properties['langcode'] = DataDefinition::create('string') + ->setLabel(t('Language Code')); return $properties; } + /** + * {@inheritdoc} + */ + public function __get($name) { + $this->ensureLoaded(); + return parent::__get($name); + } + /** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array(); + return []; + } + + /** + * {@inheritdoc} + */ + public function getValue() { + $this->ensureLoaded(); + return parent::getValue(); + } + + /** + * {@inheritdoc} + */ + public function isEmpty() { + $this->ensureLoaded(); + return parent::isEmpty(); + } + + /** + * {@inheritdoc} + */ + public function getIterator() { + $this->ensureLoaded(); + return parent::getIterator(); } /** @@ -47,6 +96,47 @@ public function preSave() { $this->alias = trim($this->alias); } + /** + * {@inheritdoc} + */ + public function __set($name, $value) { + // Also ensure that existing values are loaded when setting a value, this + // ensures that it is possible to set a new value immediately after loading + // an entity. + $this->ensureLoaded(); + parent::__set($name, $value); + } + + /** + * {@inheritdoc} + */ + public function set($property_name, $value, $notify = TRUE) { + // Also ensure that existing values are loaded when setting a value, this + // ensures that it is possible to set a new value immediately after loading + // an entity. + $this->ensureLoaded(); + return parent::set($property_name, $value, $notify); + } + + /** + * {@inheritdoc} + */ + public function get($property_name) { + $this->ensureLoaded(); + return parent::get($property_name); + } + + /** + * {@inheritdoc} + */ + public function setValue($values, $notify = TRUE) { + // Also ensure that existing values are loaded when setting a value, this + // ensures that it is possible to set a new value immediately after loading + // an entity. + $this->ensureLoaded(); + return parent::setValue($values, $notify); + } + /** * {@inheritdoc} */ @@ -62,7 +152,7 @@ public function postSave($update) { else { // Delete old alias if user erased it. if ($this->pid && !$this->alias) { - \Drupal::service('path.alias_storage')->delete(array('pid' => $this->pid)); + \Drupal::service('path.alias_storage')->delete(['pid' => $this->pid]); } // Only save a non-empty alias. elseif ($this->alias) { @@ -88,4 +178,42 @@ public static function mainPropertyName() { return 'alias'; } + /** + * Ensures the alias properties are loaded if available. + * + * This ensures that the properties will always be loaded and act like + * non-computed fields when calling ::__get() and getValue(). + * + * @todo: Determine if this should be moved to the base class in + * https://www.drupal.org/node/2392845. + */ + protected function ensureLoaded() { + // Make sure to avoid a infinite loop if setValue() has be called from this + // block which calls ensureLoaded(). + if (!$this->isLoaded && !$this->isLoading) { + $entity = $this->getEntity(); + if (!$entity->isNew()) { + // @todo Support loading languge neutral aliases in + // https://www.drupal.org/node/2511968. + $alias = \Drupal::service('path.alias_storage')->load([ + 'source' => '/' . $entity->toUrl()->getInternalPath(), + 'langcode' => $this->getLangcode(), + ]); + if ($alias) { + $this->isLoading = TRUE; + $this->setValue($alias); + $this->isLoading = FALSE; + } + else { + // If there is no existing alias, default the langcode to the current + // language. + // @todo Set the langcode to not specified for untranslatable fields + // in https://www.drupal.org/node/2689459. + $this->langcode = $this->getLangcode(); + } + } + $this->isLoaded = TRUE; + } + } + } diff --git a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php index 366db885..13ab1f10 100644 --- a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php +++ b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php @@ -5,7 +5,6 @@ use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Language\LanguageInterface; use Symfony\Component\Validator\ConstraintViolationInterface; /** @@ -26,47 +25,30 @@ class PathWidget extends WidgetBase { */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $entity = $items->getEntity(); - $path = array(); - if (!$entity->isNew()) { - $conditions = array('source' => '/' . $entity->urlInfo()->getInternalPath()); - if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) { - $conditions['langcode'] = $items->getLangcode(); - } - $path = \Drupal::service('path.alias_storage')->load($conditions); - if ($path === FALSE) { - $path = array(); - } - } - $path += array( - 'pid' => NULL, - 'source' => !$entity->isNew() ? '/' . $entity->urlInfo()->getInternalPath() : NULL, - 'alias' => '', - 'langcode' => $items->getLangcode(), - ); - $element += array( - '#element_validate' => array(array(get_class($this), 'validateFormElement')), - ); - $element['alias'] = array( + $element += [ + '#element_validate' => [[get_class($this), 'validateFormElement']], + ]; + $element['alias'] = [ '#type' => 'textfield', '#title' => $element['#title'], - '#default_value' => $path['alias'], + '#default_value' => $items[$delta]->alias, '#required' => $element['#required'], '#maxlength' => 255, '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "/about" when writing an about page.'), - ); - $element['pid'] = array( + ]; + $element['pid'] = [ '#type' => 'value', - '#value' => $path['pid'], - ); - $element['source'] = array( + '#value' => $items[$delta]->pid, + ]; + $element['source'] = [ '#type' => 'value', - '#value' => $path['source'], - ); - $element['langcode'] = array( + '#value' => !$entity->isNew() ? '/' . $entity->toUrl()->getInternalPath() : NULL, + ]; + $element['langcode'] = [ '#type' => 'value', - '#value' => $path['langcode'], - ); + '#value' => $items[$delta]->langcode, + ]; return $element; } @@ -87,12 +69,12 @@ public static function validateFormElement(array &$element, FormStateInterface $ // Validate that the submitted alias does not exist yet. $is_exists = \Drupal::service('path.alias_storage')->aliasExists($alias, $element['langcode']['#value'], $element['source']['#value']); if ($is_exists) { - $form_state->setError($element, t('The alias is already in use.')); + $form_state->setError($element['alias'], t('The alias is already in use.')); } } if ($alias && $alias[0] !== '/') { - $form_state->setError($element, t('The alias needs to start with a slash.')); + $form_state->setError($element['alias'], t('The alias needs to start with a slash.')); } } diff --git a/core/modules/path/src/Plugin/Validation/Constraint/PathAliasConstraint.php b/core/modules/path/src/Plugin/Validation/Constraint/PathAliasConstraint.php new file mode 100644 index 00000000..4136d265 --- /dev/null +++ b/core/modules/path/src/Plugin/Validation/Constraint/PathAliasConstraint.php @@ -0,0 +1,19 @@ +published
    version of this content.'; + +} diff --git a/core/modules/path/src/Plugin/Validation/Constraint/PathAliasConstraintValidator.php b/core/modules/path/src/Plugin/Validation/Constraint/PathAliasConstraintValidator.php new file mode 100644 index 00000000..e6771f76 --- /dev/null +++ b/core/modules/path/src/Plugin/Validation/Constraint/PathAliasConstraintValidator.php @@ -0,0 +1,57 @@ +entityTypeManager = $entity_type_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity_type.manager') + ); + } + + /** + * {@inheritdoc} + */ + public function validate($value, Constraint $constraint) { + $entity = !empty($value->getParent()) ? $value->getEntity() : NULL; + + if ($entity && !$entity->isNew() && !$entity->isDefaultRevision()) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $original */ + $original = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id()); + if ($value->alias != $original->path->alias) { + $this->context->addViolation($constraint->message); + } + } + } + +} diff --git a/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php b/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php index a71bcc9c..a845fb39 100644 --- a/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php +++ b/core/modules/path/src/Plugin/migrate/destination/UrlAlias.php @@ -19,7 +19,7 @@ class UrlAlias extends DestinationBase implements ContainerFactoryPluginInterfac /** * The alias storage service. * - * @var \Drupal\Core\Path\AliasStorage $aliasStorage + * @var \Drupal\Core\Path\AliasStorage */ protected $aliasStorage; @@ -58,7 +58,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function import(Row $row, array $old_destination_id_values = array()) { + public function import(Row $row, array $old_destination_id_values = []) { $source = $row->getDestinationProperty('source'); $alias = $row->getDestinationProperty('alias'); $langcode = $row->getDestinationProperty('langcode'); @@ -75,7 +75,7 @@ public function import(Row $row, array $old_destination_id_values = array()) { $path = $this->aliasStorage->save($source, $alias, $langcode, $pid); - return array($path['pid']); + return [$path['pid']]; } /** diff --git a/core/modules/path/src/Plugin/migrate/source/UrlAliasBase.php b/core/modules/path/src/Plugin/migrate/source/UrlAliasBase.php index 3529ce28..7714cbd1 100644 --- a/core/modules/path/src/Plugin/migrate/source/UrlAliasBase.php +++ b/core/modules/path/src/Plugin/migrate/source/UrlAliasBase.php @@ -24,10 +24,10 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'pid' => $this->t('The numeric identifier of the path alias.'), 'language' => $this->t('The language code of the URL alias.'), - ); + ]; } /** diff --git a/core/modules/path/src/Plugin/migrate/source/d6/UrlAlias.php b/core/modules/path/src/Plugin/migrate/source/d6/UrlAlias.php index 3e1f624d..c01d3647 100644 --- a/core/modules/path/src/Plugin/migrate/source/d6/UrlAlias.php +++ b/core/modules/path/src/Plugin/migrate/source/d6/UrlAlias.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d6_url_alias", - * source_provider = "path" + * source_module = "path" * ) */ class UrlAlias extends UrlAliasBase { diff --git a/core/modules/path/src/Plugin/migrate/source/d7/UrlAlias.php b/core/modules/path/src/Plugin/migrate/source/d7/UrlAlias.php index eaaea166..58405fdf 100644 --- a/core/modules/path/src/Plugin/migrate/source/d7/UrlAlias.php +++ b/core/modules/path/src/Plugin/migrate/source/d7/UrlAlias.php @@ -9,7 +9,7 @@ * * @MigrateSource( * id = "d7_url_alias", - * source_provider = "path" + * source_module = "path" * ) */ class UrlAlias extends UrlAliasBase { diff --git a/core/modules/path/src/Tests/PathTestBase.php b/core/modules/path/src/Tests/PathTestBase.php index c4a88af7..33cf5aba 100644 --- a/core/modules/path/src/Tests/PathTestBase.php +++ b/core/modules/path/src/Tests/PathTestBase.php @@ -6,6 +6,9 @@ /** * Provides a base class for testing the Path module. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\path\Functional\PathTestBase instead. */ abstract class PathTestBase extends WebTestBase { @@ -14,15 +17,15 @@ abstract class PathTestBase extends WebTestBase { * * @var array */ - public static $modules = array('node', 'path'); + public static $modules = ['node', 'path']; protected function setUp() { parent::setUp(); // Create Basic page and Article node types. if ($this->profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); } } diff --git a/core/modules/path/src/Tests/PathAdminTest.php b/core/modules/path/tests/src/Functional/PathAdminTest.php similarity index 84% rename from core/modules/path/src/Tests/PathAdminTest.php rename to core/modules/path/tests/src/Functional/PathAdminTest.php index 906ce643..a43a1f8d 100644 --- a/core/modules/path/src/Tests/PathAdminTest.php +++ b/core/modules/path/tests/src/Functional/PathAdminTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases')); + $web_user = $this->drupalCreateUser(['create page content', 'edit own page content', 'administer url aliases', 'create url aliases']); $this->drupalLogin($web_user); } @@ -35,63 +35,63 @@ public function testPathFiltering() { // Create aliases. $alias1 = '/' . $this->randomMachineName(8); - $edit = array( + $edit = [ 'source' => '/node/' . $node1->id(), 'alias' => $alias1, - ); + ]; $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); $alias2 = '/' . $this->randomMachineName(8); - $edit = array( + $edit = [ 'source' => '/node/' . $node2->id(), 'alias' => $alias2, - ); + ]; $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); $alias3 = '/' . $this->randomMachineName(4) . '/' . $this->randomMachineName(4); - $edit = array( + $edit = [ 'source' => '/node/' . $node3->id(), 'alias' => $alias3, - ); + ]; $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); // Filter by the first alias. - $edit = array( + $edit = [ 'filter' => $alias1, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Filter')); $this->assertLinkByHref($alias1); $this->assertNoLinkByHref($alias2); $this->assertNoLinkByHref($alias3); // Filter by the second alias. - $edit = array( + $edit = [ 'filter' => $alias2, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Filter')); $this->assertNoLinkByHref($alias1); $this->assertLinkByHref($alias2); $this->assertNoLinkByHref($alias3); // Filter by the third alias which has a slash. - $edit = array( + $edit = [ 'filter' => $alias3, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Filter')); $this->assertNoLinkByHref($alias1); $this->assertNoLinkByHref($alias2); $this->assertLinkByHref($alias3); // Filter by a random string with a different length. - $edit = array( + $edit = [ 'filter' => $this->randomMachineName(10), - ); + ]; $this->drupalPostForm(NULL, $edit, t('Filter')); $this->assertNoLinkByHref($alias1); $this->assertNoLinkByHref($alias2); // Reset the filter. - $edit = array(); + $edit = []; $this->drupalPostForm(NULL, $edit, t('Reset')); $this->assertLinkByHref($alias1); $this->assertLinkByHref($alias2); diff --git a/core/modules/path/src/Tests/PathAliasTest.php b/core/modules/path/tests/src/Functional/PathAliasTest.php similarity index 84% rename from core/modules/path/src/Tests/PathAliasTest.php rename to core/modules/path/tests/src/Functional/PathAliasTest.php index 28c582dd..a12b282d 100644 --- a/core/modules/path/src/Tests/PathAliasTest.php +++ b/core/modules/path/tests/src/Functional/PathAliasTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases')); + $web_user = $this->drupalCreateUser(['create page content', 'edit own page content', 'administer url aliases', 'create url aliases']); $this->drupalLogin($web_user); } /** * Tests the path cache. */ - function testPathCache() { + public function testPathCache() { // Create test node. $node1 = $this->drupalCreateNode(); // Create alias. - $edit = array(); + $edit = []; $edit['source'] = '/node/' . $node1->id(); $edit['alias'] = '/' . $this->randomMachineName(8); $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); @@ -51,7 +51,7 @@ function testPathCache() { // created. \Drupal::cache('data')->deleteAll(); // Make sure the path is not converted to the alias. - $this->drupalGet(trim($edit['source'], '/'), array('alias' => TRUE)); + $this->drupalGet(trim($edit['source'], '/'), ['alias' => TRUE]); $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.'); // Visit the alias for the node and confirm a cache entry is created. @@ -65,12 +65,12 @@ function testPathCache() { /** * Tests alias functionality through the admin interfaces. */ - function testAdminAlias() { + public function testAdminAlias() { // Create test node. $node1 = $this->drupalCreateNode(); // Create alias. - $edit = array(); + $edit = []; $edit['source'] = '/node/' . $node1->id(); $edit['alias'] = '/' . $this->getRandomGenerator()->word(8); $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); @@ -92,7 +92,8 @@ function testAdminAlias() { $pid = $this->getPID($edit['alias']); $previous = $edit['alias']; - $edit['alias'] = '/alias' . // Lower-case letters. + // Lower-case letters. + $edit['alias'] = '/alias' . // "Special" ASCII characters. "- ._~!$'\"()*@[]?&+%#,;=:" . // Characters that look like a percent-escaped string. @@ -129,7 +130,7 @@ function testAdminAlias() { $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); // Confirm no duplicate was created. - $this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])), 'Attempt to move alias was rejected.'); + $this->assertRaw(t('The alias %alias is already in use in this language.', ['%alias' => $edit['alias']]), 'Attempt to move alias was rejected.'); $edit_upper = $edit; $edit_upper['alias'] = Unicode::strtoupper($edit['alias']); @@ -142,8 +143,8 @@ function testAdminAlias() { // Delete alias. $this->drupalGet('admin/config/search/path/edit/' . $pid); $this->clickLink(t('Delete')); - $this->assertRaw(t('Are you sure you want to delete path alias %name?', array('%name' => $edit['alias']))); - $this->drupalPostForm(NULL, array(), t('Confirm')); + $this->assertRaw(t('Are you sure you want to delete path alias %name?', ['%name' => $edit['alias']])); + $this->drupalPostForm(NULL, [], t('Confirm')); // Confirm that the alias no longer works. $this->drupalGet($edit['alias']); @@ -151,7 +152,7 @@ function testAdminAlias() { $this->assertResponse(404); // Create a really long alias. - $edit = array(); + $edit = []; $edit['source'] = '/node/' . $node1->id(); $alias = '/' . $this->randomMachineName(128); $edit['alias'] = $alias; @@ -166,7 +167,7 @@ function testAdminAlias() { $node3 = $this->drupalCreateNode(); // Create absolute path alias. - $edit = array(); + $edit = []; $edit['source'] = '/node/' . $node3->id(); $node3_alias = '/' . $this->randomMachineName(8); $edit['alias'] = $node3_alias; @@ -176,7 +177,7 @@ function testAdminAlias() { $node4 = $this->drupalCreateNode(); // Create alias with trailing slash. - $edit = array(); + $edit = []; $edit['source'] = '/node/' . $node4->id(); $node4_alias = '/' . $this->randomMachineName(8); $edit['alias'] = $node4_alias . '/'; @@ -205,12 +206,12 @@ function testAdminAlias() { $edit['alias'] = $node4_alias; $edit['source'] = '/node/' . $node3->id(); $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save')); - $this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias']))); + $this->assertRaw(t('The alias %alias is already in use in this language.', ['%alias' => $edit['alias']])); // Create an alias without a starting slash. $node5 = $this->drupalCreateNode(); - $edit = array(); + $edit = []; $edit['source'] = 'node/' . $node5->id(); $node5_alias = $this->randomMachineName(8); $edit['alias'] = $node5_alias . '/'; @@ -224,12 +225,12 @@ function testAdminAlias() { /** * Tests alias functionality through the node interfaces. */ - function testNodeAlias() { + public function testNodeAlias() { // Create test node. $node1 = $this->drupalCreateNode(); // Create alias. - $edit = array(); + $edit = []; $edit['path[0][alias]'] = '/' . $this->randomMachineName(8); $this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save')); @@ -246,7 +247,8 @@ function testNodeAlias() { $previous = $edit['path[0][alias]']; // Change alias to one containing "exotic" characters. - $edit['path[0][alias]'] = '/alias' . // Lower-case letters. + // Lower-case letters. + $edit['path[0][alias]'] = '/alias' . // "Special" ASCII characters. "- ._~!$'\"()*@[]?&+%#,;=:" . // Characters that look like a percent-escaped string. @@ -284,7 +286,7 @@ function testNodeAlias() { $this->assertText(t('The alias is already in use.'), 'Attempt to moved alias was rejected.'); // Delete alias. - $this->drupalPostForm('node/' . $node1->id() . '/edit', array('path[0][alias]' => ''), t('Save')); + $this->drupalPostForm('node/' . $node1->id() . '/edit', ['path[0][alias]' => ''], t('Save')); // Confirm that the alias no longer works. $this->drupalGet($edit['path[0][alias]']); @@ -295,7 +297,7 @@ function testNodeAlias() { $node3 = $this->drupalCreateNode(); // Set its path alias to an absolute path. - $edit = array('path[0][alias]' => '/' . $this->randomMachineName(8)); + $edit = ['path[0][alias]' => '/' . $this->randomMachineName(8)]; $this->drupalPostForm('node/' . $node3->id() . '/edit', $edit, t('Save')); // Confirm that the alias was converted to a relative path. @@ -307,7 +309,7 @@ function testNodeAlias() { $node4 = $this->drupalCreateNode(); // Set its path alias to have a trailing slash. - $edit = array('path[0][alias]' => '/' . $this->randomMachineName(8) . '/'); + $edit = ['path[0][alias]' => '/' . $this->randomMachineName(8) . '/']; $this->drupalPostForm('node/' . $node4->id() . '/edit', $edit, t('Save')); // Confirm that the alias was converted to a relative path. @@ -319,7 +321,7 @@ function testNodeAlias() { $node5 = $this->drupalCreateNode(); // Set a path alias. - $edit = array('path[0][alias]' => '/' . $this->randomMachineName(8)); + $edit = ['path[0][alias]' => '/' . $this->randomMachineName(8)]; $this->drupalPostForm('node/' . $node5->id() . '/edit', $edit, t('Save')); // Delete the node and check that the path alias is also deleted. @@ -337,17 +339,17 @@ function testNodeAlias() { * @return int * Integer representing the path ID. */ - function getPID($alias) { - return db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", array(':alias' => $alias))->fetchField(); + public function getPID($alias) { + return db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", [':alias' => $alias])->fetchField(); } /** * Tests that duplicate aliases fail validation. */ - function testDuplicateNodeAlias() { + public function testDuplicateNodeAlias() { // Create one node with a random alias. $node_one = $this->drupalCreateNode(); - $edit = array(); + $edit = []; $edit['path[0][alias]'] = '/' . $this->randomMachineName(); $this->drupalPostForm('node/' . $node_one->id() . '/edit', $edit, t('Save')); @@ -356,6 +358,22 @@ function testDuplicateNodeAlias() { $this->drupalPostForm('node/' . $node_two->id() . '/edit', $edit, t('Save')); $this->assertText(t('The alias is already in use.')); $this->assertFieldByXPath("//input[@name='path[0][alias]' and contains(@class, 'error')]", $edit['path[0][alias]'], 'Textfield exists and has the error class.'); + + // Behavior here differs with the inline_form_errors module enabled. + // Enable the inline_form_errors module and try this again. This module + // improves validation with a link in the error message(s) to the fields + // which have invalid input. + $this->assertTrue($this->container->get('module_installer')->install(['inline_form_errors'], TRUE), 'Installed inline_form_errors.'); + // Attempt to edit the second node again, as before. + $this->drupalPostForm('node/' . $node_two->id() . '/edit', $edit, t('Preview')); + // This error should still be present next to the field. + $this->assertSession()->pageTextContains(t('The alias is already in use.'), 'Field error found with expected text.'); + // The validation error set for the page should include this text. + $this->assertSession()->pageTextContains(t('1 error has been found: URL alias'), 'Form error found with expected text.'); + // The text 'URL alias' should be a link. + $this->assertSession()->linkExists('URL alias'); + // The link should be to the ID of the URL alias field. + $this->assertSession()->linkByHrefExists('#edit-path-0-alias'); } } diff --git a/core/modules/path/tests/src/Functional/PathContentModerationTest.php b/core/modules/path/tests/src/Functional/PathContentModerationTest.php new file mode 100644 index 00000000..87f117b9 --- /dev/null +++ b/core/modules/path/tests/src/Functional/PathContentModerationTest.php @@ -0,0 +1,107 @@ + 'moderated', 'type' => 'moderated']); + $node_type->save(); + + // Set the content type as moderated. + $workflow = Workflow::load('editorial'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated'); + $workflow->save(); + + $this->drupalLogin($this->rootUser); + } + + /** + * Tests node path aliases on a moderated content type. + */ + public function testNodePathAlias() { + // Create some moderated content with a path alias. + $this->drupalGet('node/add/moderated'); + $this->assertSession()->fieldValueEquals('path[0][alias]', ''); + $this->drupalPostForm(NULL, [ + 'title[0][value]' => 'moderated content', + 'path[0][alias]' => '/moderated-content', + 'moderation_state[0][state]' => 'published', + ], t('Save')); + $node = $this->getNodeByTitle('moderated content'); + + // Add a pending revision with the same alias. + $this->drupalGet('node/' . $node->id() . '/edit'); + $this->assertSession()->fieldValueEquals('path[0][alias]', '/moderated-content'); + $this->drupalPostForm(NULL, [ + 'title[0][value]' => 'pending revision', + 'path[0][alias]' => '/moderated-content', + 'moderation_state[0][state]' => 'draft', + ], t('Save')); + $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.'); + + // Create some moderated content with no path alias. + $this->drupalGet('node/add/moderated'); + $this->assertSession()->fieldValueEquals('path[0][alias]', ''); + $this->drupalPostForm(NULL, [ + 'title[0][value]' => 'moderated content 2', + 'path[0][alias]' => '', + 'moderation_state[0][state]' => 'published', + ], t('Save')); + $node = $this->getNodeByTitle('moderated content 2'); + + // Add a pending revision with a new alias. + $this->drupalGet('node/' . $node->id() . '/edit'); + $this->assertSession()->fieldValueEquals('path[0][alias]', ''); + $this->drupalPostForm(NULL, [ + 'title[0][value]' => 'pending revision', + 'path[0][alias]' => '/pending-revision', + 'moderation_state[0][state]' => 'draft', + ], t('Save')); + $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.'); + + // Create some moderated content with no path alias. + $this->drupalGet('node/add/moderated'); + $this->assertSession()->fieldValueEquals('path[0][alias]', ''); + $this->drupalPostForm(NULL, [ + 'title[0][value]' => 'moderated content 3', + 'path[0][alias]' => '', + 'moderation_state[0][state]' => 'published', + ], t('Save')); + $node = $this->getNodeByTitle('moderated content 3'); + + // Add a pending revision with no path alias. + $this->drupalGet('node/' . $node->id() . '/edit'); + $this->assertSession()->fieldValueEquals('path[0][alias]', ''); + $this->drupalPostForm(NULL, [ + 'title[0][value]' => 'pending revision', + 'path[0][alias]' => '', + 'moderation_state[0][state]' => 'draft', + ], t('Save')); + $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.'); + } + +} diff --git a/core/modules/path/src/Tests/PathLanguageTest.php b/core/modules/path/tests/src/Functional/PathLanguageTest.php similarity index 91% rename from core/modules/path/src/Tests/PathLanguageTest.php rename to core/modules/path/tests/src/Functional/PathLanguageTest.php index 4cb2c994..8e41edea 100644 --- a/core/modules/path/src/Tests/PathLanguageTest.php +++ b/core/modules/path/tests/src/Functional/PathLanguageTest.php @@ -1,6 +1,6 @@ webUser = $this->drupalCreateUser($permissions); $this->drupalLogin($this->webUser); // Enable French language. - $edit = array(); + $edit = []; $edit['predefined_langcode'] = 'fr'; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); // Enable URL language detection and selection. - $edit = array('language_interface[enabled][language-url]' => 1); + $edit = ['language_interface[enabled][language-url]' => 1]; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); // Enable translation for page node. - $edit = array( + $edit = [ 'entity_types[node]' => 1, 'settings[node][page][translatable]' => 1, 'settings[node][page][fields][path]' => 1, 'settings[node][page][fields][body]' => 1, 'settings[node][page][settings][language][language_alterable]' => 1, - ); + ]; $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); \Drupal::entityManager()->clearCachedDefinitions(); @@ -71,13 +71,13 @@ protected function setUp() { /** * Test alias functionality through the admin interfaces. */ - function testAliasTranslation() { + public function testAliasTranslation() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); - $english_node = $this->drupalCreateNode(array('type' => 'page', 'langcode' => 'en')); + $english_node = $this->drupalCreateNode(['type' => 'page', 'langcode' => 'en']); $english_alias = $this->randomMachineName(); // Edit the node to set language and path. - $edit = array(); + $edit = []; $edit['path[0][alias]'] = '/' . $english_alias; $this->drupalPostForm('node/' . $english_node->id() . '/edit', $edit, t('Save')); @@ -89,7 +89,7 @@ function testAliasTranslation() { $this->drupalGet('node/' . $english_node->id() . '/translations'); $this->clickLink(t('Add')); - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(); $edit['body[0][value]'] = $this->randomMachineName(); $french_alias = $this->randomMachineName(); @@ -105,7 +105,7 @@ function testAliasTranslation() { $languages = $this->container->get('language_manager')->getLanguages(); // Ensure the node was created. - $node_storage->resetCache(array($english_node->id())); + $node_storage->resetCache([$english_node->id()]); $english_node = $node_storage->load($english_node->id()); $english_node_french_translation = $english_node->getTranslation('fr'); $this->assertTrue($english_node->hasTranslation('fr'), 'Node found in database.'); @@ -118,22 +118,22 @@ function testAliasTranslation() { // many levels, and we need to clear those caches. $this->container->get('language_manager')->reset(); $languages = $this->container->get('language_manager')->getLanguages(); - $url = $english_node_french_translation->url('canonical', array('language' => $languages['fr'])); + $url = $english_node_french_translation->url('canonical', ['language' => $languages['fr']]); $this->assertTrue(strpos($url, $edit['path[0][alias]']), 'URL contains the path alias.'); // Confirm that the alias works even when changing language negotiation // options. Enable User language detection and selection over URL one. - $edit = array( + $edit = [ 'language_interface[enabled][language-user]' => 1, 'language_interface[weight][language-user]' => -9, 'language_interface[enabled][language-url]' => 1, 'language_interface[weight][language-url]' => -8, - ); + ]; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); // Change user language preference. - $edit = array('preferred_langcode' => 'fr'); + $edit = ['preferred_langcode' => 'fr']; $this->drupalPostForm("user/" . $this->webUser->id() . "/edit", $edit, t('Save')); // Check that the English alias works. In this situation French is the @@ -152,7 +152,7 @@ function testAliasTranslation() { $this->assertText($english_node_french_translation->body->value, 'Alias for French translation works.'); // Disable URL language negotiation. - $edit = array('language_interface[enabled][language-url]' => FALSE); + $edit = ['language_interface[enabled][language-url]' => FALSE]; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); // Check that the English alias still works. diff --git a/core/modules/path/src/Tests/PathLanguageUiTest.php b/core/modules/path/tests/src/Functional/PathLanguageUiTest.php similarity index 77% rename from core/modules/path/src/Tests/PathLanguageUiTest.php rename to core/modules/path/tests/src/Functional/PathLanguageUiTest.php index 540cc85d..c2e32762 100644 --- a/core/modules/path/src/Tests/PathLanguageUiTest.php +++ b/core/modules/path/tests/src/Functional/PathLanguageUiTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'access administration pages')); + $web_user = $this->drupalCreateUser(['edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'access administration pages']); $this->drupalLogin($web_user); // Enable French language. - $edit = array(); + $edit = []; $edit['predefined_langcode'] = 'fr'; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); // Enable URL language detection and selection. - $edit = array('language_interface[enabled][language-url]' => 1); + $edit = ['language_interface[enabled][language-url]' => 1]; $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); } /** * Tests that a language-neutral URL alias works. */ - function testLanguageNeutralUrl() { + public function testLanguageNeutralUrl() { $name = $this->randomMachineName(8); - $edit = array(); + $edit = []; $edit['source'] = '/admin/config/search/path'; $edit['alias'] = '/' . $name; $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); @@ -51,9 +51,9 @@ function testLanguageNeutralUrl() { /** * Tests that a default language URL alias works. */ - function testDefaultLanguageUrl() { + public function testDefaultLanguageUrl() { $name = $this->randomMachineName(8); - $edit = array(); + $edit = []; $edit['source'] = '/admin/config/search/path'; $edit['alias'] = '/' . $name; $edit['langcode'] = 'en'; @@ -66,9 +66,9 @@ function testDefaultLanguageUrl() { /** * Tests that a non-default language URL alias works. */ - function testNonDefaultUrl() { + public function testNonDefaultUrl() { $name = $this->randomMachineName(8); - $edit = array(); + $edit = []; $edit['source'] = '/admin/config/search/path'; $edit['alias'] = '/' . $name; $edit['langcode'] = 'fr'; diff --git a/core/modules/path/src/Tests/PathNodeFormTest.php b/core/modules/path/tests/src/Functional/PathNodeFormTest.php similarity index 86% rename from core/modules/path/src/Tests/PathNodeFormTest.php rename to core/modules/path/tests/src/Functional/PathNodeFormTest.php index 79b43a77..ea730fdc 100644 --- a/core/modules/path/src/Tests/PathNodeFormTest.php +++ b/core/modules/path/tests/src/Functional/PathNodeFormTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('create page content', 'create url aliases')); + $web_user = $this->drupalCreateUser(['create page content', 'create url aliases']); $this->drupalLogin($web_user); } diff --git a/core/modules/path/src/Tests/PathTaxonomyTermTest.php b/core/modules/path/tests/src/Functional/PathTaxonomyTermTest.php similarity index 87% rename from core/modules/path/src/Tests/PathTaxonomyTermTest.php rename to core/modules/path/tests/src/Functional/PathTaxonomyTermTest.php index f62fb6c4..80bedab7 100644 --- a/core/modules/path/src/Tests/PathTaxonomyTermTest.php +++ b/core/modules/path/tests/src/Functional/PathTaxonomyTermTest.php @@ -1,6 +1,6 @@ save(); // Create and log in user. - $web_user = $this->drupalCreateUser(array('administer url aliases', 'administer taxonomy', 'access administration pages')); + $web_user = $this->drupalCreateUser(['administer url aliases', 'administer taxonomy', 'access administration pages']); $this->drupalLogin($web_user); } /** * Tests alias functionality through the admin interfaces. */ - function testTermAlias() { + public function testTermAlias() { // Create a term in the default 'Tags' vocabulary with URL alias. $vocabulary = Vocabulary::load('tags'); $description = $this->randomMachineName(); - $edit = array( + $edit = [ 'name[0][value]' => $this->randomMachineName(), 'description[0][value]' => $description, 'path[0][alias]' => '/' . $this->randomMachineName(), - ); + ]; $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add', $edit, t('Save')); - $tid = db_query("SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1", array(':name' => $edit['name[0][value]']))->fetchField(); + $tid = db_query("SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1", [':name' => $edit['name[0][value]']])->fetchField(); // Confirm that the alias works. $this->drupalGet($edit['path[0][alias]']); @@ -59,7 +59,7 @@ function testTermAlias() { $this->assertTrue(!empty($elements), 'Term page contains shortlink URL.'); // Change the term's URL alias. - $edit2 = array(); + $edit2 = []; $edit2['path[0][alias]'] = '/' . $this->randomMachineName(); $this->drupalPostForm('taxonomy/term/' . $tid . '/edit', $edit2, t('Save')); @@ -73,7 +73,7 @@ function testTermAlias() { $this->assertResponse(404, 'Old URL alias returns 404.'); // Remove the term's URL alias. - $edit3 = array(); + $edit3 = []; $edit3['path[0][alias]'] = ''; $this->drupalPostForm('taxonomy/term/' . $tid . '/edit', $edit3, t('Save')); diff --git a/core/modules/path/tests/src/Functional/PathTestBase.php b/core/modules/path/tests/src/Functional/PathTestBase.php new file mode 100644 index 00000000..d4b8826d --- /dev/null +++ b/core/modules/path/tests/src/Functional/PathTestBase.php @@ -0,0 +1,29 @@ +profile != 'standard') { + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + } + } + +} diff --git a/core/modules/path/tests/src/Kernel/Migrate/d6/MigrateUrlAliasTest.php b/core/modules/path/tests/src/Kernel/Migrate/d6/MigrateUrlAliasTest.php index 8df5392f..092d5ac8 100644 --- a/core/modules/path/tests/src/Kernel/Migrate/d6/MigrateUrlAliasTest.php +++ b/core/modules/path/tests/src/Kernel/Migrate/d6/MigrateUrlAliasTest.php @@ -16,7 +16,7 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['language', 'content_translation', 'path']; + public static $modules = ['language', 'content_translation', 'path', 'menu_ui']; /** * {@inheritdoc} @@ -61,46 +61,46 @@ private function assertPath($pid, $conditions, $path) { public function testUrlAlias() { $id_map = $this->getMigration('d6_url_alias')->getIdMap(); // Test that the field exists. - $conditions = array( + $conditions = [ 'source' => '/node/1', 'alias' => '/alias-one', 'langcode' => 'af', - ); + ]; $path = \Drupal::service('path.alias_storage')->load($conditions); $this->assertPath('1', $conditions, $path); - $this->assertIdentical($id_map->lookupDestinationID(array($path['pid'])), array('1'), "Test IdMap"); + $this->assertIdentical($id_map->lookupDestinationID([$path['pid']]), ['1'], "Test IdMap"); - $conditions = array( + $conditions = [ 'source' => '/node/2', 'alias' => '/alias-two', 'langcode' => 'en', - ); + ]; $path = \Drupal::service('path.alias_storage')->load($conditions); $this->assertPath('2', $conditions, $path); // Test that we can re-import using the UrlAlias destination. Database::getConnection('default', 'migrate') ->update('url_alias') - ->fields(array('dst' => 'new-url-alias')) + ->fields(['dst' => 'new-url-alias']) ->condition('src', 'node/2') ->execute(); \Drupal::database() ->update($id_map->mapTableName()) - ->fields(array('source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE)) + ->fields(['source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE]) ->execute(); $migration = $this->getMigration('d6_url_alias'); $this->executeMigration($migration); - $path = \Drupal::service('path.alias_storage')->load(array('pid' => $path['pid'])); + $path = \Drupal::service('path.alias_storage')->load(['pid' => $path['pid']]); $conditions['alias'] = '/new-url-alias'; $this->assertPath('2', $conditions, $path); - $conditions = array( + $conditions = [ 'source' => '/node/3', 'alias' => '/alias-three', 'langcode' => 'und', - ); + ]; $path = \Drupal::service('path.alias_storage')->load($conditions); $this->assertPath('3', $conditions, $path); } diff --git a/core/modules/path/tests/src/Kernel/Migrate/d7/MigrateUrlAliasTest.php b/core/modules/path/tests/src/Kernel/Migrate/d7/MigrateUrlAliasTest.php index 88c102b4..2edf258e 100644 --- a/core/modules/path/tests/src/Kernel/Migrate/d7/MigrateUrlAliasTest.php +++ b/core/modules/path/tests/src/Kernel/Migrate/d7/MigrateUrlAliasTest.php @@ -14,14 +14,34 @@ class MigrateUrlAliasTest extends MigrateDrupal7TestBase { /** * {@inheritdoc} */ - public static $modules = ['path']; + public static $modules = [ + 'content_translation', + 'language', + 'menu_ui', + 'node', + 'path', + 'text', + ]; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->executeMigration('d7_url_alias'); + + $this->installEntitySchema('node'); + $this->installConfig('node'); + $this->installSchema('node', ['node_access']); + + $this->executeMigrations([ + 'language', + 'd7_user_role', + 'd7_user', + 'd7_node_type', + 'd7_node', + 'd7_node_translation', + 'd7_url_alias', + ]); } /** @@ -38,4 +58,33 @@ public function testUrlAlias() { $this->assertIdentical('und', $path['langcode']); } + /** + * Test the URL alias migration with translated nodes. + */ + public function testUrlAliasWithTranslatedNodes() { + $alias_storage = $this->container->get('path.alias_storage'); + + // Alias for the 'The thing about Deep Space 9' node in English. + $path = $alias_storage->load(['alias' => '/deep-space-9']); + $this->assertSame('/node/2', $path['source']); + $this->assertSame('en', $path['langcode']); + + // Alias for the 'The thing about Deep Space 9' Icelandic translation, + // which should now point to node/2 instead of node/3. + $path = $alias_storage->load(['alias' => '/deep-space-9-is']); + $this->assertSame('/node/2', $path['source']); + $this->assertSame('is', $path['langcode']); + + // Alias for the 'The thing about Firefly' node in Icelandic. + $path = $alias_storage->load(['alias' => '/firefly-is']); + $this->assertSame('/node/4', $path['source']); + $this->assertSame('is', $path['langcode']); + + // Alias for the 'The thing about Firefly' English translation, + // which should now point to node/4 instead of node/5. + $path = $alias_storage->load(['alias' => '/firefly']); + $this->assertSame('/node/4', $path['source']); + $this->assertSame('en', $path['langcode']); + } + } diff --git a/core/modules/path/tests/src/Kernel/PathItemTest.php b/core/modules/path/tests/src/Kernel/PathItemTest.php new file mode 100644 index 00000000..88044c3a --- /dev/null +++ b/core/modules/path/tests/src/Kernel/PathItemTest.php @@ -0,0 +1,176 @@ +installEntitySchema('node'); + $this->installEntitySchema('user'); + + $this->installSchema('node', ['node_access']); + + $node_type = NodeType::create(['type' => 'foo']); + $node_type->save(); + + $this->installConfig(['language']); + ConfigurableLanguage::createFromLangcode('de')->save(); + } + + /** + * Test creating, loading, updating and deleting aliases through PathItem. + */ + public function testPathItem() { + + /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */ + $alias_storage = \Drupal::service('path.alias_storage'); + + $node_storage = \Drupal::entityTypeManager()->getStorage('node'); + + $node = Node::create([ + 'title' => 'Testing create()', + 'type' => 'foo', + 'path' => ['alias' => '/foo'], + ]); + $this->assertFalse($node->get('path')->isEmpty()); + $this->assertEquals('/foo', $node->get('path')->alias); + + $node->save(); + $this->assertFalse($node->get('path')->isEmpty()); + $this->assertEquals('/foo', $node->get('path')->alias); + + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertEquals('/foo', $stored_alias); + + $node_storage->resetCache(); + + /** @var \Drupal\node\NodeInterface $loaded_node */ + $loaded_node = $node_storage->load($node->id()); + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/foo', $loaded_node->get('path')->alias); + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $this->assertEquals('/foo', $loaded_node->get('path')[0]->get('alias')->getValue()); + + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $values = $loaded_node->get('path')->getValue(); + $this->assertEquals('/foo', $values[0]['alias']); + + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $this->assertEquals('/foo', $loaded_node->path->alias); + + // Add a translation, verify it is being saved as expected. + $translation = $loaded_node->addTranslation('de', $loaded_node->toArray()); + $translation->get('path')->alias = '/furchtbar'; + $translation->save(); + + // Assert the alias on the English node, the German translation, and the + // stored aliases. + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $this->assertEquals('/foo', $loaded_node->path->alias); + $translation = $loaded_node->getTranslation('de'); + $this->assertEquals('/furchtbar', $translation->path->alias); + + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertEquals('/foo', $stored_alias); + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $translation->language()->getId()); + $this->assertEquals('/furchtbar', $stored_alias); + + $loaded_node->get('path')->alias = '/bar'; + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/bar', $loaded_node->get('path')->alias); + + $loaded_node->save(); + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/bar', $loaded_node->get('path')->alias); + + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/bar', $loaded_node->get('path')->alias); + + $loaded_node->get('path')->alias = '/bar'; + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/bar', $loaded_node->get('path')->alias); + + $loaded_node->save(); + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/bar', $loaded_node->get('path')->alias); + + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertEquals('/bar', $stored_alias); + + $old_alias = $alias_storage->lookupPathSource('/foo', $node->language()->getId()); + $this->assertFalse($old_alias); + + // Reload the node to make sure that it is possible to set a value + // immediately after loading. + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $loaded_node->get('path')->alias = '/foobar'; + $loaded_node->save(); + + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/foobar', $loaded_node->get('path')->alias); + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertEquals('/foobar', $stored_alias); + + $old_alias = $alias_storage->lookupPathSource('/bar', $node->language()->getId()); + $this->assertFalse($old_alias); + + $loaded_node->get('path')->alias = ''; + $this->assertEquals('', $loaded_node->get('path')->alias); + + $loaded_node->save(); + + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertFalse($stored_alias); + + // Check that reading, updating and reading the computed alias again in the + // same request works without clearing any caches in between. + $loaded_node = $node_storage->load($node->id()); + $loaded_node->get('path')->alias = '/foo'; + $loaded_node->save(); + + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/foo', $loaded_node->get('path')->alias); + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertEquals('/foo', $stored_alias); + + $loaded_node->get('path')->alias = '/foobar'; + $loaded_node->save(); + + $this->assertFalse($loaded_node->get('path')->isEmpty()); + $this->assertEquals('/foobar', $loaded_node->get('path')->alias); + $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId()); + $this->assertEquals('/foobar', $stored_alias); + } + +} diff --git a/core/modules/path/tests/src/Kernel/PathNoCanonicalLinkTest.php b/core/modules/path/tests/src/Kernel/PathNoCanonicalLinkTest.php index df64a5c2..602e84f4 100644 --- a/core/modules/path/tests/src/Kernel/PathNoCanonicalLinkTest.php +++ b/core/modules/path/tests/src/Kernel/PathNoCanonicalLinkTest.php @@ -18,7 +18,7 @@ class PathNoCanonicalLinkTest extends KernelTestBase { * * @var array */ - public static $modules = array('path', 'content_translation_test', 'language', 'entity_test', 'user', 'system'); + public static $modules = ['path', 'content_translation_test', 'language', 'entity_test', 'user', 'system']; protected function setUp() { parent::setUp(); diff --git a/core/modules/path/tests/src/Unit/Field/PathFieldDefinitionTest.php b/core/modules/path/tests/src/Unit/Field/PathFieldDefinitionTest.php index 0bb55ae5..7ef7c2f3 100644 --- a/core/modules/path/tests/src/Unit/Field/PathFieldDefinitionTest.php +++ b/core/modules/path/tests/src/Unit/Field/PathFieldDefinitionTest.php @@ -21,7 +21,7 @@ protected function getPluginId() { * {@inheritdoc} */ protected function getModuleAndPath() { - return array('path', dirname(dirname(dirname(dirname(__DIR__))))); + return ['path', dirname(dirname(dirname(dirname(__DIR__))))]; } /** @@ -29,7 +29,7 @@ protected function getModuleAndPath() { * @covers ::getSchema */ public function testGetColumns() { - $this->assertSame(array(), $this->definition->getColumns()); + $this->assertSame([], $this->definition->getColumns()); } } diff --git a/core/modules/quickedit/css/quickedit.theme.css b/core/modules/quickedit/css/quickedit.theme.css index 399db7a8..120573a5 100644 --- a/core/modules/quickedit/css/quickedit.theme.css +++ b/core/modules/quickedit/css/quickedit.theme.css @@ -99,7 +99,7 @@ * Toolbars. */ .quickedit-toolbar-container { - font-family: 'Source Sans Pro','Lucida Grande', sans-serif; + font-family: 'Source Sans Pro', 'Lucida Grande', sans-serif; padding-bottom: 7px; padding-top: 7px; -webkit-transition: all 1s; @@ -174,9 +174,9 @@ padding: 0.1667em 0.2em; } - /** - * Info toolgroup. - */ +/** + * Info toolgroup. + */ .quickedit-toolbar-fullwidth { width: 100%; } diff --git a/core/modules/quickedit/js/editors/formEditor.es6.js b/core/modules/quickedit/js/editors/formEditor.es6.js new file mode 100644 index 00000000..7864f67c --- /dev/null +++ b/core/modules/quickedit/js/editors/formEditor.es6.js @@ -0,0 +1,251 @@ +/** + * @file + * Form-based in-place editor. Works for any field type. + */ + +(function ($, Drupal, _) { + /** + * @constructor + * + * @augments Drupal.quickedit.EditorView + */ + Drupal.quickedit.editors.form = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.form# */{ + + /** + * Tracks form container DOM element that is used while in-place editing. + * + * @type {jQuery} + */ + $formContainer: null, + + /** + * Holds the {@link Drupal.Ajax} object. + * + * @type {Drupal.Ajax} + */ + formSaveAjax: null, + + /** + * @inheritdoc + * + * @param {object} fieldModel + * The field model that holds the state. + * @param {string} state + * The state to change to. + */ + stateChange(fieldModel, state) { + const from = fieldModel.previous('state'); + const to = state; + switch (to) { + case 'inactive': + break; + + case 'candidate': + if (from !== 'inactive') { + this.removeForm(); + } + break; + + case 'highlighted': + break; + + case 'activating': + // If coming from an invalid state, then the form is already loaded. + if (from !== 'invalid') { + this.loadForm(); + } + break; + + case 'active': + break; + + case 'changed': + break; + + case 'saving': + this.save(); + break; + + case 'saved': + break; + + case 'invalid': + this.showValidationErrors(); + break; + } + }, + + /** + * @inheritdoc + * + * @return {object} + * A settings object for the quick edit UI. + */ + getQuickEditUISettings() { + return { padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: true }; + }, + + /** + * Loads the form for this field, displays it on top of the actual field. + */ + loadForm() { + const fieldModel = this.fieldModel; + + // Generate a DOM-compatible ID for the form container DOM element. + const id = `quickedit-form-for-${fieldModel.id.replace(/[\/\[\]]/g, '_')}`; + + // Render form container. + const $formContainer = this.$formContainer = $(Drupal.theme('quickeditFormContainer', { + id, + loadingMsg: Drupal.t('Loading…'), + })); + $formContainer + .find('.quickedit-form') + .addClass('quickedit-editable quickedit-highlighted quickedit-editing') + .attr('role', 'dialog'); + + // Insert form container in DOM. + if (this.$el.css('display') === 'inline') { + $formContainer.prependTo(this.$el.offsetParent()); + // Position the form container to render on top of the field's element. + const pos = this.$el.position(); + $formContainer.css('left', pos.left).css('top', pos.top); + } + else { + $formContainer.insertBefore(this.$el); + } + + // Load form, insert it into the form container and attach event handlers. + const formOptions = { + fieldID: fieldModel.get('fieldID'), + $el: this.$el, + nocssjs: false, + // Reset an existing entry for this entity in the PrivateTempStore (if + // any) when loading the field. Logically speaking, this should happen + // in a separate request because this is an entity-level operation, not + // a field-level operation. But that would require an additional + // request, that might not even be necessary: it is only when a user + // loads a first changed field for an entity that this needs to happen: + // precisely now! + reset: !fieldModel.get('entity').get('inTempStore'), + }; + Drupal.quickedit.util.form.load(formOptions, (form, ajax) => { + Drupal.AjaxCommands.prototype.insert(ajax, { + data: form, + selector: `#${id} .placeholder`, + }); + + $formContainer + .on('formUpdated.quickedit', ':input', (event) => { + const state = fieldModel.get('state'); + // If the form is in an invalid state, it will persist on the page. + // Set the field to activating so that the user can correct the + // invalid value. + if (state === 'invalid') { + fieldModel.set('state', 'activating'); + } + // Otherwise assume that the fieldModel is in a candidate state and + // set it to changed on formUpdate. + else { + fieldModel.set('state', 'changed'); + } + }) + .on('keypress.quickedit', 'input', (event) => { + if (event.keyCode === 13) { + return false; + } + }); + + // The in-place editor has loaded; change state to 'active'. + fieldModel.set('state', 'active'); + }); + }, + + /** + * Removes the form for this field, detaches behaviors and event handlers. + */ + removeForm() { + if (this.$formContainer === null) { + return; + } + + delete this.formSaveAjax; + // Allow form widgets to detach properly. + Drupal.detachBehaviors(this.$formContainer.get(0), null, 'unload'); + this.$formContainer + .off('change.quickedit', ':input') + .off('keypress.quickedit', 'input') + .remove(); + this.$formContainer = null; + }, + + /** + * @inheritdoc + */ + save() { + const $formContainer = this.$formContainer; + const $submit = $formContainer.find('.quickedit-form-submit'); + const editorModel = this.model; + const fieldModel = this.fieldModel; + + function cleanUpAjax() { + Drupal.quickedit.util.form.unajaxifySaving(formSaveAjax); + formSaveAjax = null; + } + + // Create an AJAX object for the form associated with the field. + var formSaveAjax = Drupal.quickedit.util.form.ajaxifySaving({ + nocssjs: false, + other_view_modes: fieldModel.findOtherViewModes(), + }, $submit); + + // Successfully saved. + formSaveAjax.commands.quickeditFieldFormSaved = function (ajax, response, status) { + cleanUpAjax(); + // First, transition the state to 'saved'. + fieldModel.set('state', 'saved'); + // Second, set the 'htmlForOtherViewModes' attribute, so that when this + // field is rerendered, the change can be propagated to other instances + // of this field, which may be displayed in different view modes. + fieldModel.set('htmlForOtherViewModes', response.other_view_modes); + // Finally, set the 'html' attribute on the field model. This will cause + // the field to be rerendered. + _.defer(() => { + fieldModel.set('html', response.data); + }); + }; + + // Unsuccessfully saved; validation errors. + formSaveAjax.commands.quickeditFieldFormValidationErrors = function (ajax, response, status) { + editorModel.set('validationErrors', response.data); + fieldModel.set('state', 'invalid'); + }; + + // The quickeditFieldForm AJAX command is called upon attempting to save + // the form; Form API will mark which form items have errors, if any. This + // command is invoked only if validation errors exist and then it runs + // before editFieldFormValidationErrors(). + formSaveAjax.commands.quickeditFieldForm = function (ajax, response, status) { + Drupal.AjaxCommands.prototype.insert(ajax, { + data: response.data, + selector: `#${$formContainer.attr('id')} form`, + }); + }; + + // Click the form's submit button; the scoped AJAX commands above will + // handle the server's response. + $submit.trigger('click.quickedit'); + }, + + /** + * @inheritdoc + */ + showValidationErrors() { + this.$formContainer + .find('.quickedit-form') + .addClass('quickedit-validation-error') + .find('form') + .prepend(this.model.get('validationErrors')); + }, + }); +}(jQuery, Drupal, _)); diff --git a/core/modules/quickedit/js/editors/formEditor.js b/core/modules/quickedit/js/editors/formEditor.js index 374e5c21..6ff6990e 100644 --- a/core/modules/quickedit/js/editors/formEditor.js +++ b/core/modules/quickedit/js/editors/formEditor.js @@ -1,42 +1,17 @@ /** - * @file - * Form-based in-place editor. Works for any field type. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, _) { - - 'use strict'; - - /** - * @constructor - * - * @augments Drupal.quickedit.EditorView - */ - Drupal.quickedit.editors.form = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.form# */{ - - /** - * Tracks form container DOM element that is used while in-place editing. - * - * @type {jQuery} - */ + Drupal.quickedit.editors.form = Drupal.quickedit.EditorView.extend({ $formContainer: null, - /** - * Holds the {@link Drupal.Ajax} object. - * - * @type {Drupal.Ajax} - */ formSaveAjax: null, - /** - * @inheritdoc - * - * @param {object} fieldModel - * The field model that holds the state. - * @param {string} state - * The state to change to. - */ - stateChange: function (fieldModel, state) { + stateChange: function stateChange(fieldModel, state) { var from = fieldModel.previous('state'); var to = state; switch (to) { @@ -53,7 +28,6 @@ break; case 'activating': - // If coming from an invalid state, then the form is already loaded. if (from !== 'invalid') { this.loadForm(); } @@ -77,59 +51,34 @@ break; } }, - - /** - * @inheritdoc - * - * @return {object} - * A settings object for the quick edit UI. - */ - getQuickEditUISettings: function () { - return {padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: true}; + getQuickEditUISettings: function getQuickEditUISettings() { + return { padding: true, unifiedToolbar: true, fullWidthToolbar: true, popup: true }; }, - - /** - * Loads the form for this field, displays it on top of the actual field. - */ - loadForm: function () { + loadForm: function loadForm() { var fieldModel = this.fieldModel; - // Generate a DOM-compatible ID for the form container DOM element. var id = 'quickedit-form-for-' + fieldModel.id.replace(/[\/\[\]]/g, '_'); - // Render form container. var $formContainer = this.$formContainer = $(Drupal.theme('quickeditFormContainer', { id: id, loadingMsg: Drupal.t('Loading…') })); - $formContainer - .find('.quickedit-form') - .addClass('quickedit-editable quickedit-highlighted quickedit-editing') - .attr('role', 'dialog'); + $formContainer.find('.quickedit-form').addClass('quickedit-editable quickedit-highlighted quickedit-editing').attr('role', 'dialog'); - // Insert form container in DOM. if (this.$el.css('display') === 'inline') { $formContainer.prependTo(this.$el.offsetParent()); - // Position the form container to render on top of the field's element. + var pos = this.$el.position(); $formContainer.css('left', pos.left).css('top', pos.top); - } - else { + } else { $formContainer.insertBefore(this.$el); } - // Load form, insert it into the form container and attach event handlers. var formOptions = { fieldID: fieldModel.get('fieldID'), $el: this.$el, nocssjs: false, - // Reset an existing entry for this entity in the PrivateTempStore (if - // any) when loading the field. Logically speaking, this should happen - // in a separate request because this is an entity-level operation, not - // a field-level operation. But that would require an additional - // request, that might not even be necessary: it is only when a user - // loads a first changed field for an entity that this needs to happen: - // precisely now! + reset: !fieldModel.get('entity').get('inTempStore') }; Drupal.quickedit.util.form.load(formOptions, function (form, ajax) { @@ -138,54 +87,35 @@ selector: '#' + id + ' .placeholder' }); - $formContainer - .on('formUpdated.quickedit', ':input', function (event) { - var state = fieldModel.get('state'); - // If the form is in an invalid state, it will persist on the page. - // Set the field to activating so that the user can correct the - // invalid value. - if (state === 'invalid') { - fieldModel.set('state', 'activating'); - } - // Otherwise assume that the fieldModel is in a candidate state and - // set it to changed on formUpdate. - else { + $formContainer.on('formUpdated.quickedit', ':input', function (event) { + var state = fieldModel.get('state'); + + if (state === 'invalid') { + fieldModel.set('state', 'activating'); + } else { fieldModel.set('state', 'changed'); } - }) - .on('keypress.quickedit', 'input', function (event) { - if (event.keyCode === 13) { - return false; - } - }); + }).on('keypress.quickedit', 'input', function (event) { + if (event.keyCode === 13) { + return false; + } + }); - // The in-place editor has loaded; change state to 'active'. fieldModel.set('state', 'active'); }); }, - - /** - * Removes the form for this field, detaches behaviors and event handlers. - */ - removeForm: function () { + removeForm: function removeForm() { if (this.$formContainer === null) { return; } delete this.formSaveAjax; - // Allow form widgets to detach properly. + Drupal.detachBehaviors(this.$formContainer.get(0), null, 'unload'); - this.$formContainer - .off('change.quickedit', ':input') - .off('keypress.quickedit', 'input') - .remove(); + this.$formContainer.off('change.quickedit', ':input').off('keypress.quickedit', 'input').remove(); this.$formContainer = null; }, - - /** - * @inheritdoc - */ - save: function () { + save: function save() { var $formContainer = this.$formContainer; var $submit = $formContainer.find('.quickedit-form-submit'); var editorModel = this.model; @@ -196,38 +126,28 @@ formSaveAjax = null; } - // Create an AJAX object for the form associated with the field. var formSaveAjax = Drupal.quickedit.util.form.ajaxifySaving({ nocssjs: false, other_view_modes: fieldModel.findOtherViewModes() }, $submit); - // Successfully saved. formSaveAjax.commands.quickeditFieldFormSaved = function (ajax, response, status) { cleanUpAjax(); - // First, transition the state to 'saved'. + fieldModel.set('state', 'saved'); - // Second, set the 'htmlForOtherViewModes' attribute, so that when this - // field is rerendered, the change can be propagated to other instances - // of this field, which may be displayed in different view modes. + fieldModel.set('htmlForOtherViewModes', response.other_view_modes); - // Finally, set the 'html' attribute on the field model. This will cause - // the field to be rerendered. + _.defer(function () { fieldModel.set('html', response.data); }); }; - // Unsuccessfully saved; validation errors. formSaveAjax.commands.quickeditFieldFormValidationErrors = function (ajax, response, status) { editorModel.set('validationErrors', response.data); fieldModel.set('state', 'invalid'); }; - // The quickeditFieldForm AJAX command is called upon attempting to save - // the form; Form API will mark which form items have errors, if any. This - // command is invoked only if validation errors exist and then it runs - // before editFieldFormValidationErrors(). formSaveAjax.commands.quickeditFieldForm = function (ajax, response, status) { Drupal.AjaxCommands.prototype.insert(ajax, { data: response.data, @@ -235,21 +155,10 @@ }); }; - // Click the form's submit button; the scoped AJAX commands above will - // handle the server's response. $submit.trigger('click.quickedit'); }, - - /** - * @inheritdoc - */ - showValidationErrors: function () { - this.$formContainer - .find('.quickedit-form') - .addClass('quickedit-validation-error') - .find('form') - .prepend(this.model.get('validationErrors')); + showValidationErrors: function showValidationErrors() { + this.$formContainer.find('.quickedit-form').addClass('quickedit-validation-error').find('form').prepend(this.model.get('validationErrors')); } }); - -})(jQuery, Drupal, _); +})(jQuery, Drupal, _); \ No newline at end of file diff --git a/core/modules/quickedit/js/editors/plainTextEditor.es6.js b/core/modules/quickedit/js/editors/plainTextEditor.es6.js new file mode 100644 index 00000000..bb4bb3c2 --- /dev/null +++ b/core/modules/quickedit/js/editors/plainTextEditor.es6.js @@ -0,0 +1,140 @@ +/** + * @file + * ContentEditable-based in-place editor for plain text content. + */ + +(function ($, _, Drupal) { + Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.plain_text# */{ + + /** + * Stores the textual DOM element that is being in-place edited. + */ + $textElement: null, + + /** + * @constructs + * + * @augments Drupal.quickedit.EditorView + * + * @param {object} options + * Options for the plain text editor. + */ + initialize(options) { + Drupal.quickedit.EditorView.prototype.initialize.call(this, options); + + const editorModel = this.model; + const fieldModel = this.fieldModel; + + // Store the original value of this field. Necessary for reverting + // changes. + let $textElement; + const $fieldItems = this.$el.find('.quickedit-field'); + if ($fieldItems.length) { + $textElement = this.$textElement = $fieldItems.eq(0); + } + else { + $textElement = this.$textElement = this.$el; + } + editorModel.set('originalValue', $.trim(this.$textElement.text())); + + // Sets the state to 'changed' whenever the value changes. + let previousText = editorModel.get('originalValue'); + $textElement.on('keyup paste', (event) => { + const currentText = $.trim($textElement.text()); + if (previousText !== currentText) { + previousText = currentText; + editorModel.set('currentValue', currentText); + fieldModel.set('state', 'changed'); + } + }); + }, + + /** + * @inheritdoc + * + * @return {jQuery} + * The text element for the plain text editor. + */ + getEditedElement() { + return this.$textElement; + }, + + /** + * @inheritdoc + * + * @param {object} fieldModel + * The field model that holds the state. + * @param {string} state + * The state to change to. + * @param {object} options + * State options, if needed by the state change. + */ + stateChange(fieldModel, state, options) { + const from = fieldModel.previous('state'); + const to = state; + switch (to) { + case 'inactive': + break; + + case 'candidate': + if (from !== 'inactive') { + this.$textElement.removeAttr('contenteditable'); + } + if (from === 'invalid') { + this.removeValidationErrors(); + } + break; + + case 'highlighted': + break; + + case 'activating': + // Defer updating the field model until the current state change has + // propagated, to not trigger a nested state change event. + _.defer(() => { + fieldModel.set('state', 'active'); + }); + break; + + case 'active': + this.$textElement.attr('contenteditable', 'true'); + break; + + case 'changed': + break; + + case 'saving': + if (from === 'invalid') { + this.removeValidationErrors(); + } + this.save(options); + break; + + case 'saved': + break; + + case 'invalid': + this.showValidationErrors(); + break; + } + }, + + /** + * @inheritdoc + * + * @return {object} + * A settings object for the quick edit UI. + */ + getQuickEditUISettings() { + return { padding: true, unifiedToolbar: false, fullWidthToolbar: false, popup: false }; + }, + + /** + * @inheritdoc + */ + revert() { + this.$textElement.html(this.model.get('originalValue')); + }, + + }); +}(jQuery, _, Drupal)); diff --git a/core/modules/quickedit/js/editors/plainTextEditor.js b/core/modules/quickedit/js/editors/plainTextEditor.js index 71f9b74e..e6f5afde 100644 --- a/core/modules/quickedit/js/editors/plainTextEditor.js +++ b/core/modules/quickedit/js/editors/plainTextEditor.js @@ -1,46 +1,29 @@ /** - * @file - * ContentEditable-based in-place editor for plain text content. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, _, Drupal) { - - 'use strict'; - - Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend(/** @lends Drupal.quickedit.editors.plain_text# */{ - - /** - * Stores the textual DOM element that is being in-place edited. - */ + Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend({ $textElement: null, - /** - * @constructs - * - * @augments Drupal.quickedit.EditorView - * - * @param {object} options - * Options for the plain text editor. - */ - initialize: function (options) { + initialize: function initialize(options) { Drupal.quickedit.EditorView.prototype.initialize.call(this, options); var editorModel = this.model; var fieldModel = this.fieldModel; - // Store the original value of this field. Necessary for reverting - // changes. - var $textElement; + var $textElement = void 0; var $fieldItems = this.$el.find('.quickedit-field'); if ($fieldItems.length) { $textElement = this.$textElement = $fieldItems.eq(0); - } - else { + } else { $textElement = this.$textElement = this.$el; } editorModel.set('originalValue', $.trim(this.$textElement.text())); - // Sets the state to 'changed' whenever the value changes. var previousText = editorModel.get('originalValue'); $textElement.on('keyup paste', function (event) { var currentText = $.trim($textElement.text()); @@ -51,28 +34,10 @@ } }); }, - - /** - * @inheritdoc - * - * @return {jQuery} - * The text element for the plain text editor. - */ - getEditedElement: function () { + getEditedElement: function getEditedElement() { return this.$textElement; }, - - /** - * @inheritdoc - * - * @param {object} fieldModel - * The field model that holds the state. - * @param {string} state - * The state to change to. - * @param {object} options - * State options, if needed by the state change. - */ - stateChange: function (fieldModel, state, options) { + stateChange: function stateChange(fieldModel, state, options) { var from = fieldModel.previous('state'); var to = state; switch (to) { @@ -92,8 +57,6 @@ break; case 'activating': - // Defer updating the field model until the current state change has - // propagated, to not trigger a nested state change event. _.defer(function () { fieldModel.set('state', 'active'); }); @@ -121,24 +84,11 @@ break; } }, - - /** - * @inheritdoc - * - * @return {object} - * A settings object for the quick edit UI. - */ - getQuickEditUISettings: function () { - return {padding: true, unifiedToolbar: false, fullWidthToolbar: false, popup: false}; + getQuickEditUISettings: function getQuickEditUISettings() { + return { padding: true, unifiedToolbar: false, fullWidthToolbar: false, popup: false }; }, - - /** - * @inheritdoc - */ - revert: function () { + revert: function revert() { this.$textElement.html(this.model.get('originalValue')); } - }); - -})(jQuery, _, Drupal); +})(jQuery, _, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/models/AppModel.es6.js b/core/modules/quickedit/js/models/AppModel.es6.js new file mode 100644 index 00000000..3648666a --- /dev/null +++ b/core/modules/quickedit/js/models/AppModel.es6.js @@ -0,0 +1,53 @@ +/** + * @file + * A Backbone Model for the state of the in-place editing application. + * + * @see Drupal.quickedit.AppView + */ + +(function (Backbone, Drupal) { + /** + * @constructor + * + * @augments Backbone.Model + */ + Drupal.quickedit.AppModel = Backbone.Model.extend(/** @lends Drupal.quickedit.AppModel# */{ + + /** + * @type {object} + * + * @prop {Drupal.quickedit.FieldModel} highlightedField + * @prop {Drupal.quickedit.FieldModel} activeField + * @prop {Drupal.dialog~dialogDefinition} activeModal + */ + defaults: /** @lends Drupal.quickedit.AppModel# */{ + + /** + * The currently state='highlighted' Drupal.quickedit.FieldModel, if any. + * + * @type {Drupal.quickedit.FieldModel} + * + * @see Drupal.quickedit.FieldModel.states + */ + highlightedField: null, + + /** + * The currently state = 'active' Drupal.quickedit.FieldModel, if any. + * + * @type {Drupal.quickedit.FieldModel} + * + * @see Drupal.quickedit.FieldModel.states + */ + activeField: null, + + /** + * Reference to a {@link Drupal.dialog} instance if a state change + * requires confirmation. + * + * @type {Drupal.dialog~dialogDefinition} + */ + activeModal: null, + }, + + }); +}(Backbone, Drupal)); diff --git a/core/modules/quickedit/js/models/AppModel.js b/core/modules/quickedit/js/models/AppModel.js index 6c473ac9..bfd30ff0 100644 --- a/core/modules/quickedit/js/models/AppModel.js +++ b/core/modules/quickedit/js/models/AppModel.js @@ -1,57 +1,19 @@ /** - * @file - * A Backbone Model for the state of the in-place editing application. - * - * @see Drupal.quickedit.AppView - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (Backbone, Drupal) { - - 'use strict'; - - /** - * @constructor - * - * @augments Backbone.Model - */ - Drupal.quickedit.AppModel = Backbone.Model.extend(/** @lends Drupal.quickedit.AppModel# */{ - - /** - * @type {object} - * - * @prop {Drupal.quickedit.FieldModel} highlightedField - * @prop {Drupal.quickedit.FieldModel} activeField - * @prop {Drupal.dialog~dialogDefinition} activeModal - */ - defaults: /** @lends Drupal.quickedit.AppModel# */{ - - /** - * The currently state='highlighted' Drupal.quickedit.FieldModel, if any. - * - * @type {Drupal.quickedit.FieldModel} - * - * @see Drupal.quickedit.FieldModel.states - */ + Drupal.quickedit.AppModel = Backbone.Model.extend({ + defaults: { highlightedField: null, - /** - * The currently state = 'active' Drupal.quickedit.FieldModel, if any. - * - * @type {Drupal.quickedit.FieldModel} - * - * @see Drupal.quickedit.FieldModel.states - */ activeField: null, - /** - * Reference to a {@link Drupal.dialog} instance if a state change - * requires confirmation. - * - * @type {Drupal.dialog~dialogDefinition} - */ activeModal: null } }); - -}(Backbone, Drupal)); +})(Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/models/BaseModel.es6.js b/core/modules/quickedit/js/models/BaseModel.es6.js new file mode 100644 index 00000000..83d581fd --- /dev/null +++ b/core/modules/quickedit/js/models/BaseModel.es6.js @@ -0,0 +1,56 @@ +/** + * @file + * A Backbone Model subclass that enforces validation when calling set(). + */ + +(function (Drupal, Backbone) { + Drupal.quickedit.BaseModel = Backbone.Model.extend(/** @lends Drupal.quickedit.BaseModel# */{ + + /** + * @constructs + * + * @augments Backbone.Model + * + * @param {object} options + * Options for the base model- + * + * @return {Drupal.quickedit.BaseModel} + * A quickedit base model. + */ + initialize(options) { + this.__initialized = true; + return Backbone.Model.prototype.initialize.call(this, options); + }, + + /** + * Set a value on the model + * + * @param {object|string} key + * The key to set a value for. + * @param {*} val + * The value to set. + * @param {object} [options] + * Options for the model. + * + * @return {*} + * The result of `Backbone.Model.prototype.set` with the specified + * parameters. + */ + set(key, val, options) { + if (this.__initialized) { + // Deal with both the "key", value and {key:value}-style arguments. + if (typeof key === 'object') { + key.validate = true; + } + else { + if (!options) { + options = {}; + } + options.validate = true; + } + } + return Backbone.Model.prototype.set.call(this, key, val, options); + }, + + }); +}(Drupal, Backbone)); diff --git a/core/modules/quickedit/js/models/BaseModel.js b/core/modules/quickedit/js/models/BaseModel.js index 7579b6f0..c37eb921 100644 --- a/core/modules/quickedit/js/models/BaseModel.js +++ b/core/modules/quickedit/js/models/BaseModel.js @@ -1,51 +1,22 @@ /** - * @file - * A Backbone Model subclass that enforces validation when calling set(). - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; (function (Drupal, Backbone) { - - 'use strict'; - - Drupal.quickedit.BaseModel = Backbone.Model.extend(/** @lends Drupal.quickedit.BaseModel# */{ - - /** - * @constructs - * - * @augments Backbone.Model - * - * @param {object} options - * Options for the base model- - * - * @return {Drupal.quickedit.BaseModel} - * A quickedit base model. - */ - initialize: function (options) { + Drupal.quickedit.BaseModel = Backbone.Model.extend({ + initialize: function initialize(options) { this.__initialized = true; return Backbone.Model.prototype.initialize.call(this, options); }, - - /** - * Set a value on the model - * - * @param {object|string} key - * The key to set a value for. - * @param {*} val - * The value to set. - * @param {object} [options] - * Options for the model. - * - * @return {*} - * The result of `Backbone.Model.prototype.set` with the specified - * parameters. - */ - set: function (key, val, options) { + set: function set(key, val, options) { if (this.__initialized) { - // Deal with both the "key", value and {key:value}-style arguments. - if (typeof key === 'object') { + if ((typeof key === 'undefined' ? 'undefined' : _typeof(key)) === 'object') { key.validate = true; - } - else { + } else { if (!options) { options = {}; } @@ -54,7 +25,5 @@ } return Backbone.Model.prototype.set.call(this, key, val, options); } - }); - -}(Drupal, Backbone)); +})(Drupal, Backbone); \ No newline at end of file diff --git a/core/modules/quickedit/js/models/EditorModel.es6.js b/core/modules/quickedit/js/models/EditorModel.es6.js new file mode 100644 index 00000000..0de29853 --- /dev/null +++ b/core/modules/quickedit/js/models/EditorModel.es6.js @@ -0,0 +1,50 @@ +/** + * @file + * A Backbone Model for the state of an in-place editor. + * + * @see Drupal.quickedit.EditorView + */ + +(function (Backbone, Drupal) { + /** + * @constructor + * + * @augments Backbone.Model + */ + Drupal.quickedit.EditorModel = Backbone.Model.extend(/** @lends Drupal.quickedit.EditorModel# */{ + + /** + * @type {object} + * + * @prop {string} originalValue + * @prop {string} currentValue + * @prop {Array} validationErrors + */ + defaults: /** @lends Drupal.quickedit.EditorModel# */{ + + /** + * Not the full HTML representation of this field, but the "actual" + * original value of the field, stored by the used in-place editor, and + * in a representation that can be chosen by the in-place editor. + * + * @type {string} + */ + originalValue: null, + + /** + * Analogous to originalValue, but the current value. + * + * @type {string} + */ + currentValue: null, + + /** + * Stores any validation errors to be rendered. + * + * @type {Array} + */ + validationErrors: null, + }, + + }); +}(Backbone, Drupal)); diff --git a/core/modules/quickedit/js/models/EditorModel.js b/core/modules/quickedit/js/models/EditorModel.js index 4b6177bc..ea044b8b 100644 --- a/core/modules/quickedit/js/models/EditorModel.js +++ b/core/modules/quickedit/js/models/EditorModel.js @@ -1,54 +1,19 @@ /** - * @file - * A Backbone Model for the state of an in-place editor. - * - * @see Drupal.quickedit.EditorView - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (Backbone, Drupal) { - - 'use strict'; - - /** - * @constructor - * - * @augments Backbone.Model - */ - Drupal.quickedit.EditorModel = Backbone.Model.extend(/** @lends Drupal.quickedit.EditorModel# */{ - - /** - * @type {object} - * - * @prop {string} originalValue - * @prop {string} currentValue - * @prop {Array} validationErrors - */ - defaults: /** @lends Drupal.quickedit.EditorModel# */{ - - /** - * Not the full HTML representation of this field, but the "actual" - * original value of the field, stored by the used in-place editor, and - * in a representation that can be chosen by the in-place editor. - * - * @type {string} - */ + Drupal.quickedit.EditorModel = Backbone.Model.extend({ + defaults: { originalValue: null, - /** - * Analogous to originalValue, but the current value. - * - * @type {string} - */ currentValue: null, - /** - * Stores any validation errors to be rendered. - * - * @type {Array} - */ validationErrors: null } }); - -}(Backbone, Drupal)); +})(Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/models/EntityModel.es6.js b/core/modules/quickedit/js/models/EntityModel.es6.js new file mode 100644 index 00000000..7c36e362 --- /dev/null +++ b/core/modules/quickedit/js/models/EntityModel.es6.js @@ -0,0 +1,729 @@ +/** + * @file + * A Backbone Model for the state of an in-place editable entity in the DOM. + */ + +(function (_, $, Backbone, Drupal) { + Drupal.quickedit.EntityModel = Drupal.quickedit.BaseModel.extend(/** @lends Drupal.quickedit.EntityModel# */{ + + /** + * @type {object} + */ + defaults: /** @lends Drupal.quickedit.EntityModel# */{ + + /** + * The DOM element that represents this entity. + * + * It may seem bizarre to have a DOM element in a Backbone Model, but we + * need to be able to map entities in the DOM to EntityModels in memory. + * + * @type {HTMLElement} + */ + el: null, + + /** + * An entity ID, of the form `/` + * + * @example + * "node/1" + * + * @type {string} + */ + entityID: null, + + /** + * An entity instance ID. + * + * The first instance of a specific entity (i.e. with a given entity ID) + * is assigned 0, the second 1, and so on. + * + * @type {number} + */ + entityInstanceID: null, + + /** + * The unique ID of this entity instance on the page, of the form + * `/[entity instance ID]` + * + * @example + * "node/1[0]" + * + * @type {string} + */ + id: null, + + /** + * The label of the entity. + * + * @type {string} + */ + label: null, + + /** + * A FieldCollection for all fields of the entity. + * + * @type {Drupal.quickedit.FieldCollection} + * + * @see Drupal.quickedit.FieldCollection + */ + fields: null, + + // The attributes below are stateful. The ones above will never change + // during the life of a EntityModel instance. + + /** + * Indicates whether this entity is currently being edited in-place. + * + * @type {bool} + */ + isActive: false, + + /** + * Whether one or more fields are already been stored in PrivateTempStore. + * + * @type {bool} + */ + inTempStore: false, + + /** + * Indicates whether a "Save" button is necessary or not. + * + * Whether one or more fields have already been stored in PrivateTempStore + * *or* the field that's currently being edited is in the 'changed' or a + * later state. + * + * @type {bool} + */ + isDirty: false, + + /** + * Whether the request to the server has been made to commit this entity. + * + * Used to prevent multiple such requests. + * + * @type {bool} + */ + isCommitting: false, + + /** + * The current processing state of an entity. + * + * @type {string} + */ + state: 'closed', + + /** + * IDs of fields whose new values have been stored in PrivateTempStore. + * + * We must store this on the EntityModel as well (even though it already + * is on the FieldModel) because when a field is rerendered, its + * FieldModel is destroyed and this allows us to transition it back to + * the proper state. + * + * @type {Array.} + */ + fieldsInTempStore: [], + + /** + * A flag the tells the application that this EntityModel must be reloaded + * in order to restore the original values to its fields in the client. + * + * @type {bool} + */ + reload: false, + }, + + /** + * @constructs + * + * @augments Drupal.quickedit.BaseModel + */ + initialize() { + this.set('fields', new Drupal.quickedit.FieldCollection()); + + // Respond to entity state changes. + this.listenTo(this, 'change:state', this.stateChange); + + // The state of the entity is largely dependent on the state of its + // fields. + this.listenTo(this.get('fields'), 'change:state', this.fieldStateChange); + + // Call Drupal.quickedit.BaseModel's initialize() method. + Drupal.quickedit.BaseModel.prototype.initialize.call(this); + }, + + /** + * Updates FieldModels' states when an EntityModel change occurs. + * + * @param {Drupal.quickedit.EntityModel} entityModel + * The entity model + * @param {string} state + * The state of the associated entity. One of + * {@link Drupal.quickedit.EntityModel.states}. + * @param {object} options + * Options for the entity model. + */ + stateChange(entityModel, state, options) { + const to = state; + switch (to) { + case 'closed': + this.set({ + isActive: false, + inTempStore: false, + isDirty: false, + }); + break; + + case 'launching': + break; + + case 'opening': + // Set the fields to candidate state. + entityModel.get('fields').each((fieldModel) => { + fieldModel.set('state', 'candidate', options); + }); + break; + + case 'opened': + // The entity is now ready for editing! + this.set('isActive', true); + break; + + case 'committing': + // The user indicated they want to save the entity. + var fields = this.get('fields'); + // For fields that are in an active state, transition them to + // candidate. + fields.chain() + .filter(fieldModel => _.intersection([fieldModel.get('state')], ['active']).length) + .each((fieldModel) => { + fieldModel.set('state', 'candidate'); + }); + // For fields that are in a changed state, field values must first be + // stored in PrivateTempStore. + fields.chain() + .filter(fieldModel => _.intersection([fieldModel.get('state')], Drupal.quickedit.app.changedFieldStates).length) + .each((fieldModel) => { + fieldModel.set('state', 'saving'); + }); + break; + + case 'deactivating': + var changedFields = this.get('fields') + .filter(fieldModel => _.intersection([fieldModel.get('state')], ['changed', 'invalid']).length); + // If the entity contains unconfirmed or unsaved changes, return the + // entity to an opened state and ask the user if they would like to + // save the changes or discard the changes. + // 1. One of the fields is in a changed state. The changed field + // might just be a change in the client or it might have been saved + // to tempstore. + // 2. The saved flag is empty and the confirmed flag is empty. If + // the entity has been saved to the server, the fields changed in + // the client are irrelevant. If the changes are confirmed, then + // proceed to set the fields to candidate state. + if ((changedFields.length || this.get('fieldsInTempStore').length) && (!options.saved && !options.confirmed)) { + // Cancel deactivation until the user confirms save or discard. + this.set('state', 'opened', { confirming: true }); + // An action in reaction to state change must be deferred. + _.defer(() => { + Drupal.quickedit.app.confirmEntityDeactivation(entityModel); + }); + } + else { + const invalidFields = this.get('fields') + .filter(fieldModel => _.intersection([fieldModel.get('state')], ['invalid']).length); + // Indicate if this EntityModel needs to be reloaded in order to + // restore the original values of its fields. + entityModel.set('reload', (this.get('fieldsInTempStore').length || invalidFields.length)); + // Set all fields to the 'candidate' state. A changed field may have + // to go through confirmation first. + entityModel.get('fields').each((fieldModel) => { + // If the field is already in the candidate state, trigger a + // change event so that the entityModel can move to the next state + // in deactivation. + if (_.intersection([fieldModel.get('state')], ['candidate', 'highlighted']).length) { + fieldModel.trigger('change:state', fieldModel, fieldModel.get('state'), options); + } + else { + fieldModel.set('state', 'candidate', options); + } + }); + } + break; + + case 'closing': + // Set all fields to the 'inactive' state. + options.reason = 'stop'; + this.get('fields').each((fieldModel) => { + fieldModel.set({ + inTempStore: false, + state: 'inactive', + }, options); + }); + break; + } + }, + + /** + * Updates a Field and Entity model's "inTempStore" when appropriate. + * + * Helper function. + * + * @param {Drupal.quickedit.EntityModel} entityModel + * The model of the entity for which a field's state attribute has + * changed. + * @param {Drupal.quickedit.FieldModel} fieldModel + * The model of the field whose state attribute has changed. + * + * @see Drupal.quickedit.EntityModel#fieldStateChange + */ + _updateInTempStoreAttributes(entityModel, fieldModel) { + const current = fieldModel.get('state'); + const previous = fieldModel.previous('state'); + let fieldsInTempStore = entityModel.get('fieldsInTempStore'); + // If the fieldModel changed to the 'saved' state: remember that this + // field was saved to PrivateTempStore. + if (current === 'saved') { + // Mark the entity as saved in PrivateTempStore, so that we can pass the + // proper "reset PrivateTempStore" boolean value when communicating with + // the server. + entityModel.set('inTempStore', true); + // Mark the field as saved in PrivateTempStore, so that visual + // indicators signifying just that may be rendered. + fieldModel.set('inTempStore', true); + // Remember that this field is in PrivateTempStore, restore when + // rerendered. + fieldsInTempStore.push(fieldModel.get('fieldID')); + fieldsInTempStore = _.uniq(fieldsInTempStore); + entityModel.set('fieldsInTempStore', fieldsInTempStore); + } + // If the fieldModel changed to the 'candidate' state from the + // 'inactive' state, then this is a field for this entity that got + // rerendered. Restore its previous 'inTempStore' attribute value. + else if (current === 'candidate' && previous === 'inactive') { + fieldModel.set('inTempStore', _.intersection([fieldModel.get('fieldID')], fieldsInTempStore).length > 0); + } + }, + + /** + * Reacts to state changes in this entity's fields. + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * The model of the field whose state attribute changed. + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.FieldModel.states}. + */ + fieldStateChange(fieldModel, state) { + const entityModel = this; + const fieldState = state; + // Switch on the entityModel state. + // The EntityModel responds to FieldModel state changes as a function of + // its state. For example, a field switching back to 'candidate' state + // when its entity is in the 'opened' state has no effect on the entity. + // But that same switch back to 'candidate' state of a field when the + // entity is in the 'committing' state might allow the entity to proceed + // with the commit flow. + switch (this.get('state')) { + case 'closed': + case 'launching': + // It should be impossible to reach these: fields can't change state + // while the entity is closed or still launching. + break; + + case 'opening': + // We must change the entity to the 'opened' state, but it must first + // be confirmed that all of its fieldModels have transitioned to the + // 'candidate' state. + // We do this here, because this is called every time a fieldModel + // changes state, hence each time this is called, we get closer to the + // goal of having all fieldModels in the 'candidate' state. + // A state change in reaction to another state change must be + // deferred. + _.defer(() => { + entityModel.set('state', 'opened', { + 'accept-field-states': Drupal.quickedit.app.readyFieldStates, + }); + }); + break; + + case 'opened': + // Set the isDirty attribute when appropriate so that it is known when + // to display the "Save" button in the entity toolbar. + // Note that once a field has been changed, there's no way to discard + // that change, hence it will have to be saved into PrivateTempStore, + // or the in-place editing of this field will have to be stopped + // completely. In other words: once any field enters the 'changed' + // field, then for the remainder of the in-place editing session, the + // entity is by definition dirty. + if (fieldState === 'changed') { + entityModel.set('isDirty', true); + } + else { + this._updateInTempStoreAttributes(entityModel, fieldModel); + } + break; + + case 'committing': + // If the field save returned a validation error, set the state of the + // entity back to 'opened'. + if (fieldState === 'invalid') { + // A state change in reaction to another state change must be + // deferred. + _.defer(() => { + entityModel.set('state', 'opened', { reason: 'invalid' }); + }); + } + else { + this._updateInTempStoreAttributes(entityModel, fieldModel); + } + + // Attempt to save the entity. If the entity's fields are not yet all + // in a ready state, the save will not be processed. + var options = { + 'accept-field-states': Drupal.quickedit.app.readyFieldStates, + }; + if (entityModel.set('isCommitting', true, options)) { + entityModel.save({ + success() { + entityModel.set({ + state: 'deactivating', + isCommitting: false, + }, { saved: true }); + }, + error() { + // Reset the "isCommitting" mutex. + entityModel.set('isCommitting', false); + // Change the state back to "opened", to allow the user to hit + // the "Save" button again. + entityModel.set('state', 'opened', { reason: 'networkerror' }); + // Show a modal to inform the user of the network error. + const message = Drupal.t('Your changes to @entity-title could not be saved, either due to a website problem or a network connection problem.
    Please try again.', { '@entity-title': entityModel.get('label') }); + Drupal.quickedit.util.networkErrorModal(Drupal.t('Network problem!'), message); + }, + }); + } + break; + + case 'deactivating': + // When setting the entity to 'closing', require that all fieldModels + // are in either the 'candidate' or 'highlighted' state. + // A state change in reaction to another state change must be + // deferred. + _.defer(() => { + entityModel.set('state', 'closing', { + 'accept-field-states': Drupal.quickedit.app.readyFieldStates, + }); + }); + break; + + case 'closing': + // When setting the entity to 'closed', require that all fieldModels + // are in the 'inactive' state. + // A state change in reaction to another state change must be + // deferred. + _.defer(() => { + entityModel.set('state', 'closed', { + 'accept-field-states': ['inactive'], + }); + }); + break; + } + }, + + /** + * Fires an AJAX request to the REST save URL for an entity. + * + * @param {object} options + * An object of options that contains: + * @param {function} [options.success] + * A function to invoke if the entity is successfully saved. + */ + save(options) { + const entityModel = this; + + // Create a Drupal.ajax instance to save the entity. + const entitySaverAjax = Drupal.ajax({ + url: Drupal.url(`quickedit/entity/${entityModel.get('entityID')}`), + error() { + // Let the Drupal.quickedit.EntityModel Backbone model's error() + // method handle errors. + options.error.call(entityModel); + }, + }); + // Entity saved successfully. + entitySaverAjax.commands.quickeditEntitySaved = function (ajax, response, status) { + // All fields have been moved from PrivateTempStore to permanent + // storage, update the "inTempStore" attribute on FieldModels, on the + // EntityModel and clear EntityModel's "fieldInTempStore" attribute. + entityModel.get('fields').each((fieldModel) => { + fieldModel.set('inTempStore', false); + }); + entityModel.set('inTempStore', false); + entityModel.set('fieldsInTempStore', []); + + // Invoke the optional success callback. + if (options.success) { + options.success.call(entityModel); + } + }; + // Trigger the AJAX request, which will will return the + // quickeditEntitySaved AJAX command to which we then react. + entitySaverAjax.execute(); + }, + + /** + * Validate the entity model. + * + * @param {object} attrs + * The attributes changes in the save or set call. + * @param {object} options + * An object with the following option: + * @param {string} [options.reason] + * A string that conveys a particular reason to allow for an exceptional + * state change. + * @param {Array} options.accept-field-states + * An array of strings that represent field states that the entities must + * be in to validate. For example, if `accept-field-states` is + * `['candidate', 'highlighted']`, then all the fields of the entity must + * be in either of these two states for the save or set call to + * validate and proceed. + * + * @return {string} + * A string to say something about the state of the entity model. + */ + validate(attrs, options) { + const acceptedFieldStates = options['accept-field-states'] || []; + + // Validate state change. + const currentState = this.get('state'); + const nextState = attrs.state; + if (currentState !== nextState) { + // Ensure it's a valid state. + if (_.indexOf(this.constructor.states, nextState) === -1) { + return `"${nextState}" is an invalid state`; + } + + // Ensure it's a state change that is allowed. + // Check if the acceptStateChange function accepts it. + if (!this._acceptStateChange(currentState, nextState, options)) { + return 'state change not accepted'; + } + // If that function accepts it, then ensure all fields are also in an + // acceptable state. + else if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) { + return 'state change not accepted because fields are not in acceptable state'; + } + } + + // Validate setting isCommitting = true. + const currentIsCommitting = this.get('isCommitting'); + const nextIsCommitting = attrs.isCommitting; + if (currentIsCommitting === false && nextIsCommitting === true) { + if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) { + return 'isCommitting change not accepted because fields are not in acceptable state'; + } + } + else if (currentIsCommitting === true && nextIsCommitting === true) { + return 'isCommitting is a mutex, hence only changes are allowed'; + } + }, + + /** + * Checks if a state change can be accepted. + * + * @param {string} from + * From state. + * @param {string} to + * To state. + * @param {object} context + * Context for the check. + * @param {string} context.reason + * The reason for the state change. + * @param {bool} context.confirming + * Whether context is confirming or not. + * + * @return {bool} + * Whether the state change is accepted or not. + * + * @see Drupal.quickedit.AppView#acceptEditorStateChange + */ + _acceptStateChange(from, to, context) { + let accept = true; + + // In general, enforce the states sequence. Disallow going back from a + // "later" state to an "earlier" state, except in explicitly allowed + // cases. + if (!this.constructor.followsStateSequence(from, to)) { + accept = false; + + // Allow: closing -> closed. + // Necessary to stop editing an entity. + if (from === 'closing' && to === 'closed') { + accept = true; + } + // Allow: committing -> opened. + // Necessary to be able to correct an invalid field, or to hit the + // "Save" button again after a server/network error. + else if (from === 'committing' && to === 'opened' && context.reason && (context.reason === 'invalid' || context.reason === 'networkerror')) { + accept = true; + } + // Allow: deactivating -> opened. + // Necessary to be able to confirm changes with the user. + else if (from === 'deactivating' && to === 'opened' && context.confirming) { + accept = true; + } + // Allow: opened -> deactivating. + // Necessary to be able to stop editing. + else if (from === 'opened' && to === 'deactivating' && context.confirmed) { + accept = true; + } + } + + return accept; + }, + + /** + * Checks if fields have acceptable states. + * + * @param {Array} acceptedFieldStates + * An array of acceptable field states to check for. + * + * @return {bool} + * Whether the fields have an acceptable state. + * + * @see Drupal.quickedit.EntityModel#validate + */ + _fieldsHaveAcceptableStates(acceptedFieldStates) { + let accept = true; + + // If no acceptable field states are provided, assume all field states are + // acceptable. We want to let validation pass as a default and only + // check validity on calls to set that explicitly request it. + if (acceptedFieldStates.length > 0) { + const fieldStates = this.get('fields').pluck('state') || []; + // If not all fields are in one of the accepted field states, then we + // still can't allow this state change. + if (_.difference(fieldStates, acceptedFieldStates).length) { + accept = false; + } + } + + return accept; + }, + + /** + * Destroys the entity model. + * + * @param {object} options + * Options for the entity model. + */ + destroy(options) { + Drupal.quickedit.BaseModel.prototype.destroy.call(this, options); + + this.stopListening(); + + // Destroy all fields of this entity. + this.get('fields').reset(); + }, + + /** + * @inheritdoc + */ + sync() { + // We don't use REST updates to sync. + + }, + + }, /** @lends Drupal.quickedit.EntityModel */{ + + /** + * Sequence of all possible states an entity can be in during quickediting. + * + * @type {Array.} + */ + states: [ + // Initial state, like field's 'inactive' OR the user has just finished + // in-place editing this entity. + // - Trigger: none (initial) or EntityModel (finished). + // - Expected behavior: (when not initial state): tear down + // EntityToolbarView, in-place editors and related views. + 'closed', + // User has activated in-place editing of this entity. + // - Trigger: user. + // - Expected behavior: the EntityToolbarView is gets set up, in-place + // editors (EditorViews) and related views for this entity's fields are + // set up. Upon completion of those, the state is changed to 'opening'. + 'launching', + // Launching has finished. + // - Trigger: application. + // - Guarantees: in-place editors ready for use, all entity and field + // views have been set up, all fields are in the 'inactive' state. + // - Expected behavior: all fields are changed to the 'candidate' state + // and once this is completed, the entity state will be changed to + // 'opened'. + 'opening', + // Opening has finished. + // - Trigger: EntityModel. + // - Guarantees: see 'opening', all fields are in the 'candidate' state. + // - Expected behavior: the user is able to actually use in-place editing. + 'opened', + // User has clicked the 'Save' button (and has thus changed at least one + // field). + // - Trigger: user. + // - Guarantees: see 'opened', plus: either a changed field is in + // PrivateTempStore, or the user has just modified a field without + // activating (switching to) another field. + // - Expected behavior: 1) if any of the fields are not yet in + // PrivateTempStore, save them to PrivateTempStore, 2) if then any of + // the fields has the 'invalid' state, then change the entity state back + // to 'opened', otherwise: save the entity by committing it from + // PrivateTempStore into permanent storage. + 'committing', + // User has clicked the 'Close' button, or has clicked the 'Save' button + // and that was successfully completed. + // - Trigger: user or EntityModel. + // - Guarantees: when having clicked 'Close' hardly any: fields may be in + // a variety of states; when having clicked 'Save': all fields are in + // the 'candidate' state. + // - Expected behavior: transition all fields to the 'candidate' state, + // possibly requiring confirmation in the case of having clicked + // 'Close'. + 'deactivating', + // Deactivation has been completed. + // - Trigger: EntityModel. + // - Guarantees: all fields are in the 'candidate' state. + // - Expected behavior: change all fields to the 'inactive' state. + 'closing', + ], + + /** + * Indicates whether the 'from' state comes before the 'to' state. + * + * @param {string} from + * One of {@link Drupal.quickedit.EntityModel.states}. + * @param {string} to + * One of {@link Drupal.quickedit.EntityModel.states}. + * + * @return {bool} + * Whether the 'from' state comes before the 'to' state. + */ + followsStateSequence(from, to) { + return _.indexOf(this.states, from) < _.indexOf(this.states, to); + }, + + }); + + /** + * @constructor + * + * @augments Backbone.Collection + */ + Drupal.quickedit.EntityCollection = Backbone.Collection.extend(/** @lends Drupal.quickedit.EntityCollection# */{ + + /** + * @type {Drupal.quickedit.EntityModel} + */ + model: Drupal.quickedit.EntityModel, + }); +}(_, jQuery, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/models/EntityModel.js b/core/modules/quickedit/js/models/EntityModel.js index f444fbb9..cf84a515 100644 --- a/core/modules/quickedit/js/models/EntityModel.js +++ b/core/modules/quickedit/js/models/EntityModel.js @@ -1,172 +1,50 @@ /** - * @file - * A Backbone Model for the state of an in-place editable entity in the DOM. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (_, $, Backbone, Drupal) { - - 'use strict'; - - Drupal.quickedit.EntityModel = Drupal.quickedit.BaseModel.extend(/** @lends Drupal.quickedit.EntityModel# */{ - - /** - * @type {object} - */ - defaults: /** @lends Drupal.quickedit.EntityModel# */{ - - /** - * The DOM element that represents this entity. - * - * It may seem bizarre to have a DOM element in a Backbone Model, but we - * need to be able to map entities in the DOM to EntityModels in memory. - * - * @type {HTMLElement} - */ + Drupal.quickedit.EntityModel = Drupal.quickedit.BaseModel.extend({ + defaults: { el: null, - /** - * An entity ID, of the form `/` - * - * @example - * "node/1" - * - * @type {string} - */ entityID: null, - /** - * An entity instance ID. - * - * The first instance of a specific entity (i.e. with a given entity ID) - * is assigned 0, the second 1, and so on. - * - * @type {number} - */ entityInstanceID: null, - /** - * The unique ID of this entity instance on the page, of the form - * `/[entity instance ID]` - * - * @example - * "node/1[0]" - * - * @type {string} - */ id: null, - /** - * The label of the entity. - * - * @type {string} - */ label: null, - /** - * A FieldCollection for all fields of the entity. - * - * @type {Drupal.quickedit.FieldCollection} - * - * @see Drupal.quickedit.FieldCollection - */ fields: null, - // The attributes below are stateful. The ones above will never change - // during the life of a EntityModel instance. - - /** - * Indicates whether this entity is currently being edited in-place. - * - * @type {bool} - */ isActive: false, - /** - * Whether one or more fields are already been stored in PrivateTempStore. - * - * @type {bool} - */ inTempStore: false, - /** - * Indicates whether a "Save" button is necessary or not. - * - * Whether one or more fields have already been stored in PrivateTempStore - * *or* the field that's currently being edited is in the 'changed' or a - * later state. - * - * @type {bool} - */ isDirty: false, - /** - * Whether the request to the server has been made to commit this entity. - * - * Used to prevent multiple such requests. - * - * @type {bool} - */ isCommitting: false, - /** - * The current processing state of an entity. - * - * @type {string} - */ state: 'closed', - /** - * IDs of fields whose new values have been stored in PrivateTempStore. - * - * We must store this on the EntityModel as well (even though it already - * is on the FieldModel) because when a field is rerendered, its - * FieldModel is destroyed and this allows us to transition it back to - * the proper state. - * - * @type {Array.} - */ fieldsInTempStore: [], - /** - * A flag the tells the application that this EntityModel must be reloaded - * in order to restore the original values to its fields in the client. - * - * @type {bool} - */ reload: false }, - /** - * @constructs - * - * @augments Drupal.quickedit.BaseModel - */ - initialize: function () { + initialize: function initialize() { this.set('fields', new Drupal.quickedit.FieldCollection()); - // Respond to entity state changes. this.listenTo(this, 'change:state', this.stateChange); - // The state of the entity is largely dependent on the state of its - // fields. this.listenTo(this.get('fields'), 'change:state', this.fieldStateChange); - // Call Drupal.quickedit.BaseModel's initialize() method. Drupal.quickedit.BaseModel.prototype.initialize.call(this); }, - - /** - * Updates FieldModels' states when an EntityModel change occurs. - * - * @param {Drupal.quickedit.EntityModel} entityModel - * The entity model - * @param {string} state - * The state of the associated entity. One of - * {@link Drupal.quickedit.EntityModel.states}. - * @param {object} options - * Options for the entity model. - */ - stateChange: function (entityModel, state, options) { + stateChange: function stateChange(entityModel, state, options) { var to = state; switch (to) { case 'closed': @@ -181,81 +59,53 @@ break; case 'opening': - // Set the fields to candidate state. entityModel.get('fields').each(function (fieldModel) { fieldModel.set('state', 'candidate', options); }); break; case 'opened': - // The entity is now ready for editing! this.set('isActive', true); break; case 'committing': - // The user indicated they want to save the entity. var fields = this.get('fields'); - // For fields that are in an active state, transition them to - // candidate. - fields.chain() - .filter(function (fieldModel) { - return _.intersection([fieldModel.get('state')], ['active']).length; - }) - .each(function (fieldModel) { - fieldModel.set('state', 'candidate'); - }); - // For fields that are in a changed state, field values must first be - // stored in PrivateTempStore. - fields.chain() - .filter(function (fieldModel) { - return _.intersection([fieldModel.get('state')], Drupal.quickedit.app.changedFieldStates).length; - }) - .each(function (fieldModel) { - fieldModel.set('state', 'saving'); - }); + + fields.chain().filter(function (fieldModel) { + return _.intersection([fieldModel.get('state')], ['active']).length; + }).each(function (fieldModel) { + fieldModel.set('state', 'candidate'); + }); + + fields.chain().filter(function (fieldModel) { + return _.intersection([fieldModel.get('state')], Drupal.quickedit.app.changedFieldStates).length; + }).each(function (fieldModel) { + fieldModel.set('state', 'saving'); + }); break; case 'deactivating': - var changedFields = this.get('fields') - .filter(function (fieldModel) { - return _.intersection([fieldModel.get('state')], ['changed', 'invalid']).length; - }); - // If the entity contains unconfirmed or unsaved changes, return the - // entity to an opened state and ask the user if they would like to - // save the changes or discard the changes. - // 1. One of the fields is in a changed state. The changed field - // might just be a change in the client or it might have been saved - // to tempstore. - // 2. The saved flag is empty and the confirmed flag is empty. If - // the entity has been saved to the server, the fields changed in - // the client are irrelevant. If the changes are confirmed, then - // proceed to set the fields to candidate state. - if ((changedFields.length || this.get('fieldsInTempStore').length) && (!options.saved && !options.confirmed)) { - // Cancel deactivation until the user confirms save or discard. - this.set('state', 'opened', {confirming: true}); - // An action in reaction to state change must be deferred. + var changedFields = this.get('fields').filter(function (fieldModel) { + return _.intersection([fieldModel.get('state')], ['changed', 'invalid']).length; + }); + + if ((changedFields.length || this.get('fieldsInTempStore').length) && !options.saved && !options.confirmed) { + this.set('state', 'opened', { confirming: true }); + _.defer(function () { Drupal.quickedit.app.confirmEntityDeactivation(entityModel); }); - } - else { - var invalidFields = this.get('fields') - .filter(function (fieldModel) { - return _.intersection([fieldModel.get('state')], ['invalid']).length; - }); - // Indicate if this EntityModel needs to be reloaded in order to - // restore the original values of its fields. - entityModel.set('reload', (this.get('fieldsInTempStore').length || invalidFields.length)); - // Set all fields to the 'candidate' state. A changed field may have - // to go through confirmation first. + } else { + var invalidFields = this.get('fields').filter(function (fieldModel) { + return _.intersection([fieldModel.get('state')], ['invalid']).length; + }); + + entityModel.set('reload', this.get('fieldsInTempStore').length || invalidFields.length); + entityModel.get('fields').each(function (fieldModel) { - // If the field is already in the candidate state, trigger a - // change event so that the entityModel can move to the next state - // in deactivation. if (_.intersection([fieldModel.get('state')], ['candidate', 'highlighted']).length) { fieldModel.trigger('change:state', fieldModel, fieldModel.get('state'), options); - } - else { + } else { fieldModel.set('state', 'candidate', options); } }); @@ -263,7 +113,6 @@ break; case 'closing': - // Set all fields to the 'inactive' state. options.reason = 'stop'; this.get('fields').each(function (fieldModel) { fieldModel.set({ @@ -274,83 +123,33 @@ break; } }, - - /** - * Updates a Field and Entity model's "inTempStore" when appropriate. - * - * Helper function. - * - * @param {Drupal.quickedit.EntityModel} entityModel - * The model of the entity for which a field's state attribute has - * changed. - * @param {Drupal.quickedit.FieldModel} fieldModel - * The model of the field whose state attribute has changed. - * - * @see Drupal.quickedit.EntityModel#fieldStateChange - */ - _updateInTempStoreAttributes: function (entityModel, fieldModel) { + _updateInTempStoreAttributes: function _updateInTempStoreAttributes(entityModel, fieldModel) { var current = fieldModel.get('state'); var previous = fieldModel.previous('state'); var fieldsInTempStore = entityModel.get('fieldsInTempStore'); - // If the fieldModel changed to the 'saved' state: remember that this - // field was saved to PrivateTempStore. + if (current === 'saved') { - // Mark the entity as saved in PrivateTempStore, so that we can pass the - // proper "reset PrivateTempStore" boolean value when communicating with - // the server. entityModel.set('inTempStore', true); - // Mark the field as saved in PrivateTempStore, so that visual - // indicators signifying just that may be rendered. + fieldModel.set('inTempStore', true); - // Remember that this field is in PrivateTempStore, restore when - // rerendered. + fieldsInTempStore.push(fieldModel.get('fieldID')); fieldsInTempStore = _.uniq(fieldsInTempStore); entityModel.set('fieldsInTempStore', fieldsInTempStore); - } - // If the fieldModel changed to the 'candidate' state from the - // 'inactive' state, then this is a field for this entity that got - // rerendered. Restore its previous 'inTempStore' attribute value. - else if (current === 'candidate' && previous === 'inactive') { - fieldModel.set('inTempStore', _.intersection([fieldModel.get('fieldID')], fieldsInTempStore).length > 0); - } + } else if (current === 'candidate' && previous === 'inactive') { + fieldModel.set('inTempStore', _.intersection([fieldModel.get('fieldID')], fieldsInTempStore).length > 0); + } }, - - /** - * Reacts to state changes in this entity's fields. - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * The model of the field whose state attribute changed. - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.FieldModel.states}. - */ - fieldStateChange: function (fieldModel, state) { + fieldStateChange: function fieldStateChange(fieldModel, state) { var entityModel = this; var fieldState = state; - // Switch on the entityModel state. - // The EntityModel responds to FieldModel state changes as a function of - // its state. For example, a field switching back to 'candidate' state - // when its entity is in the 'opened' state has no effect on the entity. - // But that same switch back to 'candidate' state of a field when the - // entity is in the 'committing' state might allow the entity to proceed - // with the commit flow. + switch (this.get('state')) { case 'closed': case 'launching': - // It should be impossible to reach these: fields can't change state - // while the entity is closed or still launching. break; case 'opening': - // We must change the entity to the 'opened' state, but it must first - // be confirmed that all of its fieldModels have transitioned to the - // 'candidate' state. - // We do this here, because this is called every time a fieldModel - // changes state, hence each time this is called, we get closer to the - // goal of having all fieldModels in the 'candidate' state. - // A state change in reaction to another state change must be - // deferred. _.defer(function () { entityModel.set('state', 'opened', { 'accept-field-states': Drupal.quickedit.app.readyFieldStates @@ -359,57 +158,39 @@ break; case 'opened': - // Set the isDirty attribute when appropriate so that it is known when - // to display the "Save" button in the entity toolbar. - // Note that once a field has been changed, there's no way to discard - // that change, hence it will have to be saved into PrivateTempStore, - // or the in-place editing of this field will have to be stopped - // completely. In other words: once any field enters the 'changed' - // field, then for the remainder of the in-place editing session, the - // entity is by definition dirty. if (fieldState === 'changed') { entityModel.set('isDirty', true); - } - else { + } else { this._updateInTempStoreAttributes(entityModel, fieldModel); } break; case 'committing': - // If the field save returned a validation error, set the state of the - // entity back to 'opened'. if (fieldState === 'invalid') { - // A state change in reaction to another state change must be - // deferred. _.defer(function () { - entityModel.set('state', 'opened', {reason: 'invalid'}); + entityModel.set('state', 'opened', { reason: 'invalid' }); }); - } - else { + } else { this._updateInTempStoreAttributes(entityModel, fieldModel); } - // Attempt to save the entity. If the entity's fields are not yet all - // in a ready state, the save will not be processed. var options = { 'accept-field-states': Drupal.quickedit.app.readyFieldStates }; if (entityModel.set('isCommitting', true, options)) { entityModel.save({ - success: function () { + success: function success() { entityModel.set({ state: 'deactivating', isCommitting: false - }, {saved: true}); + }, { saved: true }); }, - error: function () { - // Reset the "isCommitting" mutex. + error: function error() { entityModel.set('isCommitting', false); - // Change the state back to "opened", to allow the user to hit - // the "Save" button again. - entityModel.set('state', 'opened', {reason: 'networkerror'}); - // Show a modal to inform the user of the network error. - var message = Drupal.t('Your changes to @entity-title could not be saved, either due to a website problem or a network connection problem.
    Please try again.', {'@entity-title': entityModel.get('label')}); + + entityModel.set('state', 'opened', { reason: 'networkerror' }); + + var message = Drupal.t('Your changes to @entity-title could not be saved, either due to a website problem or a network connection problem.
    Please try again.', { '@entity-title': entityModel.get('label') }); Drupal.quickedit.util.networkErrorModal(Drupal.t('Network problem!'), message); } }); @@ -417,10 +198,6 @@ break; case 'deactivating': - // When setting the entity to 'closing', require that all fieldModels - // are in either the 'candidate' or 'highlighted' state. - // A state change in reaction to another state change must be - // deferred. _.defer(function () { entityModel.set('state', 'closing', { 'accept-field-states': Drupal.quickedit.app.readyFieldStates @@ -429,10 +206,6 @@ break; case 'closing': - // When setting the entity to 'closed', require that all fieldModels - // are in the 'inactive' state. - // A state change in reaction to another state change must be - // deferred. _.defer(function () { entityModel.set('state', 'closed', { 'accept-field-states': ['inactive'] @@ -441,180 +214,82 @@ break; } }, - - /** - * Fires an AJAX request to the REST save URL for an entity. - * - * @param {object} options - * An object of options that contains: - * @param {function} [options.success] - * A function to invoke if the entity is successfully saved. - */ - save: function (options) { + save: function save(options) { var entityModel = this; - // Create a Drupal.ajax instance to save the entity. var entitySaverAjax = Drupal.ajax({ url: Drupal.url('quickedit/entity/' + entityModel.get('entityID')), - error: function () { - // Let the Drupal.quickedit.EntityModel Backbone model's error() - // method handle errors. + error: function error() { options.error.call(entityModel); } }); - // Entity saved successfully. + entitySaverAjax.commands.quickeditEntitySaved = function (ajax, response, status) { - // All fields have been moved from PrivateTempStore to permanent - // storage, update the "inTempStore" attribute on FieldModels, on the - // EntityModel and clear EntityModel's "fieldInTempStore" attribute. entityModel.get('fields').each(function (fieldModel) { fieldModel.set('inTempStore', false); }); entityModel.set('inTempStore', false); entityModel.set('fieldsInTempStore', []); - // Invoke the optional success callback. if (options.success) { options.success.call(entityModel); } }; - // Trigger the AJAX request, which will will return the - // quickeditEntitySaved AJAX command to which we then react. + entitySaverAjax.execute(); }, - - /** - * Validate the entity model. - * - * @param {object} attrs - * The attributes changes in the save or set call. - * @param {object} options - * An object with the following option: - * @param {string} [options.reason] - * A string that conveys a particular reason to allow for an exceptional - * state change. - * @param {Array} options.accept-field-states - * An array of strings that represent field states that the entities must - * be in to validate. For example, if `accept-field-states` is - * `['candidate', 'highlighted']`, then all the fields of the entity must - * be in either of these two states for the save or set call to - * validate and proceed. - * - * @return {string} - * A string to say something about the state of the entity model. - */ - validate: function (attrs, options) { + validate: function validate(attrs, options) { var acceptedFieldStates = options['accept-field-states'] || []; - // Validate state change. var currentState = this.get('state'); var nextState = attrs.state; if (currentState !== nextState) { - // Ensure it's a valid state. if (_.indexOf(this.constructor.states, nextState) === -1) { return '"' + nextState + '" is an invalid state'; } - // Ensure it's a state change that is allowed. - // Check if the acceptStateChange function accepts it. if (!this._acceptStateChange(currentState, nextState, options)) { return 'state change not accepted'; - } - // If that function accepts it, then ensure all fields are also in an - // acceptable state. - else if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) { - return 'state change not accepted because fields are not in acceptable state'; - } + } else if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) { + return 'state change not accepted because fields are not in acceptable state'; + } } - // Validate setting isCommitting = true. var currentIsCommitting = this.get('isCommitting'); var nextIsCommitting = attrs.isCommitting; if (currentIsCommitting === false && nextIsCommitting === true) { if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) { return 'isCommitting change not accepted because fields are not in acceptable state'; } - } - else if (currentIsCommitting === true && nextIsCommitting === true) { + } else if (currentIsCommitting === true && nextIsCommitting === true) { return 'isCommitting is a mutex, hence only changes are allowed'; } }, - - /** - * Checks if a state change can be accepted. - * - * @param {string} from - * From state. - * @param {string} to - * To state. - * @param {object} context - * Context for the check. - * @param {string} context.reason - * The reason for the state change. - * @param {bool} context.confirming - * Whether context is confirming or not. - * - * @return {bool} - * Whether the state change is accepted or not. - * - * @see Drupal.quickedit.AppView#acceptEditorStateChange - */ - _acceptStateChange: function (from, to, context) { + _acceptStateChange: function _acceptStateChange(from, to, context) { var accept = true; - // In general, enforce the states sequence. Disallow going back from a - // "later" state to an "earlier" state, except in explicitly allowed - // cases. if (!this.constructor.followsStateSequence(from, to)) { accept = false; - // Allow: closing -> closed. - // Necessary to stop editing an entity. if (from === 'closing' && to === 'closed') { accept = true; - } - // Allow: committing -> opened. - // Necessary to be able to correct an invalid field, or to hit the - // "Save" button again after a server/network error. - else if (from === 'committing' && to === 'opened' && context.reason && (context.reason === 'invalid' || context.reason === 'networkerror')) { - accept = true; - } - // Allow: deactivating -> opened. - // Necessary to be able to confirm changes with the user. - else if (from === 'deactivating' && to === 'opened' && context.confirming) { - accept = true; - } - // Allow: opened -> deactivating. - // Necessary to be able to stop editing. - else if (from === 'opened' && to === 'deactivating' && context.confirmed) { - accept = true; - } + } else if (from === 'committing' && to === 'opened' && context.reason && (context.reason === 'invalid' || context.reason === 'networkerror')) { + accept = true; + } else if (from === 'deactivating' && to === 'opened' && context.confirming) { + accept = true; + } else if (from === 'opened' && to === 'deactivating' && context.confirmed) { + accept = true; + } } return accept; }, - - /** - * Checks if fields have acceptable states. - * - * @param {Array} acceptedFieldStates - * An array of acceptable field states to check for. - * - * @return {bool} - * Whether the fields have an acceptable state. - * - * @see Drupal.quickedit.EntityModel#validate - */ - _fieldsHaveAcceptableStates: function (acceptedFieldStates) { + _fieldsHaveAcceptableStates: function _fieldsHaveAcceptableStates(acceptedFieldStates) { var accept = true; - // If no acceptable field states are provided, assume all field states are - // acceptable. We want to let validation pass as a default and only - // check validity on calls to set that explicitly request it. if (acceptedFieldStates.length > 0) { var fieldStates = this.get('fields').pluck('state') || []; - // If not all fields are in one of the accepted field states, then we - // still can't allow this state change. + if (_.difference(fieldStates, acceptedFieldStates).length) { accept = false; } @@ -622,120 +297,23 @@ return accept; }, - - /** - * Destroys the entity model. - * - * @param {object} options - * Options for the entity model. - */ - destroy: function (options) { + destroy: function destroy(options) { Drupal.quickedit.BaseModel.prototype.destroy.call(this, options); this.stopListening(); - // Destroy all fields of this entity. this.get('fields').reset(); }, + sync: function sync() {} + }, { + states: ['closed', 'launching', 'opening', 'opened', 'committing', 'deactivating', 'closing'], - /** - * @inheritdoc - */ - sync: function () { - // We don't use REST updates to sync. - return; - } - - }, /** @lends Drupal.quickedit.EntityModel */{ - - /** - * Sequence of all possible states an entity can be in during quickediting. - * - * @type {Array.} - */ - states: [ - // Initial state, like field's 'inactive' OR the user has just finished - // in-place editing this entity. - // - Trigger: none (initial) or EntityModel (finished). - // - Expected behavior: (when not initial state): tear down - // EntityToolbarView, in-place editors and related views. - 'closed', - // User has activated in-place editing of this entity. - // - Trigger: user. - // - Expected behavior: the EntityToolbarView is gets set up, in-place - // editors (EditorViews) and related views for this entity's fields are - // set up. Upon completion of those, the state is changed to 'opening'. - 'launching', - // Launching has finished. - // - Trigger: application. - // - Guarantees: in-place editors ready for use, all entity and field - // views have been set up, all fields are in the 'inactive' state. - // - Expected behavior: all fields are changed to the 'candidate' state - // and once this is completed, the entity state will be changed to - // 'opened'. - 'opening', - // Opening has finished. - // - Trigger: EntityModel. - // - Guarantees: see 'opening', all fields are in the 'candidate' state. - // - Expected behavior: the user is able to actually use in-place editing. - 'opened', - // User has clicked the 'Save' button (and has thus changed at least one - // field). - // - Trigger: user. - // - Guarantees: see 'opened', plus: either a changed field is in - // PrivateTempStore, or the user has just modified a field without - // activating (switching to) another field. - // - Expected behavior: 1) if any of the fields are not yet in - // PrivateTempStore, save them to PrivateTempStore, 2) if then any of - // the fields has the 'invalid' state, then change the entity state back - // to 'opened', otherwise: save the entity by committing it from - // PrivateTempStore into permanent storage. - 'committing', - // User has clicked the 'Close' button, or has clicked the 'Save' button - // and that was successfully completed. - // - Trigger: user or EntityModel. - // - Guarantees: when having clicked 'Close' hardly any: fields may be in - // a variety of states; when having clicked 'Save': all fields are in - // the 'candidate' state. - // - Expected behavior: transition all fields to the 'candidate' state, - // possibly requiring confirmation in the case of having clicked - // 'Close'. - 'deactivating', - // Deactivation has been completed. - // - Trigger: EntityModel. - // - Guarantees: all fields are in the 'candidate' state. - // - Expected behavior: change all fields to the 'inactive' state. - 'closing' - ], - - /** - * Indicates whether the 'from' state comes before the 'to' state. - * - * @param {string} from - * One of {@link Drupal.quickedit.EntityModel.states}. - * @param {string} to - * One of {@link Drupal.quickedit.EntityModel.states}. - * - * @return {bool} - * Whether the 'from' state comes before the 'to' state. - */ - followsStateSequence: function (from, to) { + followsStateSequence: function followsStateSequence(from, to) { return _.indexOf(this.states, from) < _.indexOf(this.states, to); } - }); - /** - * @constructor - * - * @augments Backbone.Collection - */ - Drupal.quickedit.EntityCollection = Backbone.Collection.extend(/** @lends Drupal.quickedit.EntityCollection# */{ - - /** - * @type {Drupal.quickedit.EntityModel} - */ + Drupal.quickedit.EntityCollection = Backbone.Collection.extend({ model: Drupal.quickedit.EntityModel }); - -}(_, jQuery, Backbone, Drupal)); +})(_, jQuery, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/models/FieldModel.es6.js b/core/modules/quickedit/js/models/FieldModel.es6.js new file mode 100644 index 00000000..776c331f --- /dev/null +++ b/core/modules/quickedit/js/models/FieldModel.es6.js @@ -0,0 +1,344 @@ +/** + * @file + * A Backbone Model for the state of an in-place editable field in the DOM. + */ + +(function (_, Backbone, Drupal) { + Drupal.quickedit.FieldModel = Drupal.quickedit.BaseModel.extend(/** @lends Drupal.quickedit.FieldModel# */{ + + /** + * @type {object} + */ + defaults: /** @lends Drupal.quickedit.FieldModel# */{ + + /** + * The DOM element that represents this field. It may seem bizarre to have + * a DOM element in a Backbone Model, but we need to be able to map fields + * in the DOM to FieldModels in memory. + */ + el: null, + + /** + * A field ID, of the form + * `////` + * + * @example + * "node/1/field_tags/und/full" + */ + fieldID: null, + + /** + * The unique ID of this field within its entity instance on the page, of + * the form `////[entity instance ID]`. + * + * @example + * "node/1/field_tags/und/full[0]" + */ + id: null, + + /** + * A {@link Drupal.quickedit.EntityModel}. Its "fields" attribute, which + * is a FieldCollection, is automatically updated to include this + * FieldModel. + */ + entity: null, + + /** + * This field's metadata as returned by the + * QuickEditController::metadata(). + */ + metadata: null, + + /** + * Callback function for validating changes between states. Receives the + * previous state, new state, context, and a callback. + */ + acceptStateChange: null, + + /** + * A logical field ID, of the form + * `///`, i.e. the fieldID without + * the view mode, to be able to identify other instances of the same + * field on the page but rendered in a different view mode. + * + * @example + * "node/1/field_tags/und". + */ + logicalFieldID: null, + + // The attributes below are stateful. The ones above will never change + // during the life of a FieldModel instance. + + /** + * In-place editing state of this field. Defaults to the initial state. + * Possible values: {@link Drupal.quickedit.FieldModel.states}. + */ + state: 'inactive', + + /** + * The field is currently in the 'changed' state or one of the following + * states in which the field is still changed. + */ + isChanged: false, + + /** + * Is tracked by the EntityModel, is mirrored here solely for decorative + * purposes: so that FieldDecorationView.renderChanged() can react to it. + */ + inTempStore: false, + + /** + * The full HTML representation of this field (with the element that has + * the data-quickedit-field-id as the outer element). Used to propagate + * changes from this field to other instances of the same field storage. + */ + html: null, + + /** + * An object containing the full HTML representations (values) of other + * view modes (keys) of this field, for other instances of this field + * displayed in a different view mode. + */ + htmlForOtherViewModes: null, + }, + + /** + * State of an in-place editable field in the DOM. + * + * @constructs + * + * @augments Drupal.quickedit.BaseModel + * + * @param {object} options + * Options for the field model. + */ + initialize(options) { + // Store the original full HTML representation of this field. + this.set('html', options.el.outerHTML); + + // Enlist field automatically in the associated entity's field collection. + this.get('entity').get('fields').add(this); + + // Automatically generate the logical field ID. + this.set('logicalFieldID', this.get('fieldID').split('/').slice(0, 4).join('/')); + + // Call Drupal.quickedit.BaseModel's initialize() method. + Drupal.quickedit.BaseModel.prototype.initialize.call(this, options); + }, + + /** + * Destroys the field model. + * + * @param {object} options + * Options for the field model. + */ + destroy(options) { + if (this.get('state') !== 'inactive') { + throw new Error('FieldModel cannot be destroyed if it is not inactive state.'); + } + Drupal.quickedit.BaseModel.prototype.destroy.call(this, options); + }, + + /** + * @inheritdoc + */ + sync() { + // We don't use REST updates to sync. + + }, + + /** + * Validate function for the field model. + * + * @param {object} attrs + * The attributes changes in the save or set call. + * @param {object} options + * An object with the following option: + * @param {string} [options.reason] + * A string that conveys a particular reason to allow for an exceptional + * state change. + * @param {Array} options.accept-field-states + * An array of strings that represent field states that the entities must + * be in to validate. For example, if `accept-field-states` is + * `['candidate', 'highlighted']`, then all the fields of the entity must + * be in either of these two states for the save or set call to + * validate and proceed. + * + * @return {string} + * A string to say something about the state of the field model. + */ + validate(attrs, options) { + const current = this.get('state'); + const next = attrs.state; + if (current !== next) { + // Ensure it's a valid state. + if (_.indexOf(this.constructor.states, next) === -1) { + return `"${next}" is an invalid state`; + } + // Check if the acceptStateChange callback accepts it. + if (!this.get('acceptStateChange')(current, next, options, this)) { + return 'state change not accepted'; + } + } + }, + + /** + * Extracts the entity ID from this field's ID. + * + * @return {string} + * An entity ID: a string of the format `/`. + */ + getEntityID() { + return this.get('fieldID').split('/').slice(0, 2).join('/'); + }, + + /** + * Extracts the view mode ID from this field's ID. + * + * @return {string} + * A view mode ID. + */ + getViewMode() { + return this.get('fieldID').split('/').pop(); + }, + + /** + * Find other instances of this field with different view modes. + * + * @return {Array} + * An array containing view mode IDs. + */ + findOtherViewModes() { + const currentField = this; + const otherViewModes = []; + Drupal.quickedit.collections.fields + // Find all instances of fields that display the same logical field + // (same entity, same field, just a different instance and maybe a + // different view mode). + .where({ logicalFieldID: currentField.get('logicalFieldID') }) + .forEach((field) => { + // Ignore the current field. + if (field === currentField) { + + } + // Also ignore other fields with the same view mode. + else if (field.get('fieldID') === currentField.get('fieldID')) { + + } + else { + otherViewModes.push(field.getViewMode()); + } + }); + return otherViewModes; + }, + + }, /** @lends Drupal.quickedit.FieldModel */{ + + /** + * Sequence of all possible states a field can be in during quickediting. + * + * @type {Array.} + */ + states: [ + // The field associated with this FieldModel is linked to an EntityModel; + // the user can choose to start in-place editing that entity (and + // consequently this field). No in-place editor (EditorView) is associated + // with this field, because this field is not being in-place edited. + // This is both the initial (not yet in-place editing) and the end state + // (finished in-place editing). + 'inactive', + // The user is in-place editing this entity, and this field is a + // candidate + // for in-place editing. In-place editor should not + // - Trigger: user. + // - Guarantees: entity is ready, in-place editor (EditorView) is + // associated with the field. + // - Expected behavior: visual indicators + // around the field indicate it is available for in-place editing, no + // in-place editor presented yet. + 'candidate', + // User is highlighting this field. + // - Trigger: user. + // - Guarantees: see 'candidate'. + // - Expected behavior: visual indicators to convey highlighting, in-place + // editing toolbar shows field's label. + 'highlighted', + // User has activated the in-place editing of this field; in-place editor + // is activating. + // - Trigger: user. + // - Guarantees: see 'candidate'. + // - Expected behavior: loading indicator, in-place editor is loading + // remote data (e.g. retrieve form from back-end). Upon retrieval of + // remote data, the in-place editor transitions the field's state to + // 'active'. + 'activating', + // In-place editor has finished loading remote data; ready for use. + // - Trigger: in-place editor. + // - Guarantees: see 'candidate'. + // - Expected behavior: in-place editor for the field is ready for use. + 'active', + // User has modified values in the in-place editor. + // - Trigger: user. + // - Guarantees: see 'candidate', plus in-place editor is ready for use. + // - Expected behavior: visual indicator of change. + 'changed', + // User is saving changed field data in in-place editor to + // PrivateTempStore. The save mechanism of the in-place editor is called. + // - Trigger: user. + // - Guarantees: see 'candidate' and 'active'. + // - Expected behavior: saving indicator, in-place editor is saving field + // data into PrivateTempStore. Upon successful saving (without + // validation errors), the in-place editor transitions the field's state + // to 'saved', but to 'invalid' upon failed saving (with validation + // errors). + 'saving', + // In-place editor has successfully saved the changed field. + // - Trigger: in-place editor. + // - Guarantees: see 'candidate' and 'active'. + // - Expected behavior: transition back to 'candidate' state because the + // deed is done. Then: 1) transition to 'inactive' to allow the field + // to be rerendered, 2) destroy the FieldModel (which also destroys + // attached views like the EditorView), 3) replace the existing field + // HTML with the existing HTML and 4) attach behaviors again so that the + // field becomes available again for in-place editing. + 'saved', + // In-place editor has failed to saved the changed field: there were + // validation errors. + // - Trigger: in-place editor. + // - Guarantees: see 'candidate' and 'active'. + // - Expected behavior: remain in 'invalid' state, let the user make more + // changes so that he can save it again, without validation errors. + 'invalid', + ], + + /** + * Indicates whether the 'from' state comes before the 'to' state. + * + * @param {string} from + * One of {@link Drupal.quickedit.FieldModel.states}. + * @param {string} to + * One of {@link Drupal.quickedit.FieldModel.states}. + * + * @return {bool} + * Whether the 'from' state comes before the 'to' state. + */ + followsStateSequence(from, to) { + return _.indexOf(this.states, from) < _.indexOf(this.states, to); + }, + + }); + + /** + * @constructor + * + * @augments Backbone.Collection + */ + Drupal.quickedit.FieldCollection = Backbone.Collection.extend(/** @lends Drupal.quickedit.FieldCollection */{ + + /** + * @type {Drupal.quickedit.FieldModel} + */ + model: Drupal.quickedit.FieldModel, + }); +}(_, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/models/FieldModel.js b/core/modules/quickedit/js/models/FieldModel.js index 8aeff107..f3c6cd58 100644 --- a/core/modules/quickedit/js/models/FieldModel.js +++ b/core/modules/quickedit/js/models/FieldModel.js @@ -1,348 +1,92 @@ /** - * @file - * A Backbone Model for the state of an in-place editable field in the DOM. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (_, Backbone, Drupal) { - - 'use strict'; - - Drupal.quickedit.FieldModel = Drupal.quickedit.BaseModel.extend(/** @lends Drupal.quickedit.FieldModel# */{ - - /** - * @type {object} - */ - defaults: /** @lends Drupal.quickedit.FieldModel# */{ - - /** - * The DOM element that represents this field. It may seem bizarre to have - * a DOM element in a Backbone Model, but we need to be able to map fields - * in the DOM to FieldModels in memory. - */ + Drupal.quickedit.FieldModel = Drupal.quickedit.BaseModel.extend({ + defaults: { el: null, - /** - * A field ID, of the form - * `////` - * - * @example - * "node/1/field_tags/und/full" - */ fieldID: null, - /** - * The unique ID of this field within its entity instance on the page, of - * the form `////[entity instance ID]`. - * - * @example - * "node/1/field_tags/und/full[0]" - */ id: null, - /** - * A {@link Drupal.quickedit.EntityModel}. Its "fields" attribute, which - * is a FieldCollection, is automatically updated to include this - * FieldModel. - */ entity: null, - /** - * This field's metadata as returned by the - * QuickEditController::metadata(). - */ metadata: null, - /** - * Callback function for validating changes between states. Receives the - * previous state, new state, context, and a callback. - */ acceptStateChange: null, - /** - * A logical field ID, of the form - * `///`, i.e. the fieldID without - * the view mode, to be able to identify other instances of the same - * field on the page but rendered in a different view mode. - * - * @example - * "node/1/field_tags/und". - */ logicalFieldID: null, - // The attributes below are stateful. The ones above will never change - // during the life of a FieldModel instance. - - /** - * In-place editing state of this field. Defaults to the initial state. - * Possible values: {@link Drupal.quickedit.FieldModel.states}. - */ state: 'inactive', - /** - * The field is currently in the 'changed' state or one of the following - * states in which the field is still changed. - */ isChanged: false, - /** - * Is tracked by the EntityModel, is mirrored here solely for decorative - * purposes: so that FieldDecorationView.renderChanged() can react to it. - */ inTempStore: false, - /** - * The full HTML representation of this field (with the element that has - * the data-quickedit-field-id as the outer element). Used to propagate - * changes from this field to other instances of the same field storage. - */ html: null, - /** - * An object containing the full HTML representations (values) of other - * view modes (keys) of this field, for other instances of this field - * displayed in a different view mode. - */ htmlForOtherViewModes: null }, - /** - * State of an in-place editable field in the DOM. - * - * @constructs - * - * @augments Drupal.quickedit.BaseModel - * - * @param {object} options - * Options for the field model. - */ - initialize: function (options) { - // Store the original full HTML representation of this field. + initialize: function initialize(options) { this.set('html', options.el.outerHTML); - // Enlist field automatically in the associated entity's field collection. this.get('entity').get('fields').add(this); - // Automatically generate the logical field ID. this.set('logicalFieldID', this.get('fieldID').split('/').slice(0, 4).join('/')); - // Call Drupal.quickedit.BaseModel's initialize() method. Drupal.quickedit.BaseModel.prototype.initialize.call(this, options); }, - - /** - * Destroys the field model. - * - * @param {object} options - * Options for the field model. - */ - destroy: function (options) { + destroy: function destroy(options) { if (this.get('state') !== 'inactive') { throw new Error('FieldModel cannot be destroyed if it is not inactive state.'); } Drupal.quickedit.BaseModel.prototype.destroy.call(this, options); }, - - /** - * @inheritdoc - */ - sync: function () { - // We don't use REST updates to sync. - return; - }, - - /** - * Validate function for the field model. - * - * @param {object} attrs - * The attributes changes in the save or set call. - * @param {object} options - * An object with the following option: - * @param {string} [options.reason] - * A string that conveys a particular reason to allow for an exceptional - * state change. - * @param {Array} options.accept-field-states - * An array of strings that represent field states that the entities must - * be in to validate. For example, if `accept-field-states` is - * `['candidate', 'highlighted']`, then all the fields of the entity must - * be in either of these two states for the save or set call to - * validate and proceed. - * - * @return {string} - * A string to say something about the state of the field model. - */ - validate: function (attrs, options) { + sync: function sync() {}, + validate: function validate(attrs, options) { var current = this.get('state'); var next = attrs.state; if (current !== next) { - // Ensure it's a valid state. if (_.indexOf(this.constructor.states, next) === -1) { return '"' + next + '" is an invalid state'; } - // Check if the acceptStateChange callback accepts it. + if (!this.get('acceptStateChange')(current, next, options, this)) { return 'state change not accepted'; } } }, - - /** - * Extracts the entity ID from this field's ID. - * - * @return {string} - * An entity ID: a string of the format `/`. - */ - getEntityID: function () { + getEntityID: function getEntityID() { return this.get('fieldID').split('/').slice(0, 2).join('/'); }, - - /** - * Extracts the view mode ID from this field's ID. - * - * @return {string} - * A view mode ID. - */ - getViewMode: function () { + getViewMode: function getViewMode() { return this.get('fieldID').split('/').pop(); }, - - /** - * Find other instances of this field with different view modes. - * - * @return {Array} - * An array containing view mode IDs. - */ - findOtherViewModes: function () { + findOtherViewModes: function findOtherViewModes() { var currentField = this; var otherViewModes = []; - Drupal.quickedit.collections.fields - // Find all instances of fields that display the same logical field - // (same entity, same field, just a different instance and maybe a - // different view mode). - .where({logicalFieldID: currentField.get('logicalFieldID')}) - .forEach(function (field) { - // Ignore the current field. - if (field === currentField) { - return; - } - // Also ignore other fields with the same view mode. - else if (field.get('fieldID') === currentField.get('fieldID')) { - return; - } - else { + Drupal.quickedit.collections.fields.where({ logicalFieldID: currentField.get('logicalFieldID') }).forEach(function (field) { + if (field === currentField) {} else if (field.get('fieldID') === currentField.get('fieldID')) {} else { otherViewModes.push(field.getViewMode()); } - }); + }); return otherViewModes; } + }, { + states: ['inactive', 'candidate', 'highlighted', 'activating', 'active', 'changed', 'saving', 'saved', 'invalid'], - }, /** @lends Drupal.quickedit.FieldModel */{ - - /** - * Sequence of all possible states a field can be in during quickediting. - * - * @type {Array.} - */ - states: [ - // The field associated with this FieldModel is linked to an EntityModel; - // the user can choose to start in-place editing that entity (and - // consequently this field). No in-place editor (EditorView) is associated - // with this field, because this field is not being in-place edited. - // This is both the initial (not yet in-place editing) and the end state - // (finished in-place editing). - 'inactive', - // The user is in-place editing this entity, and this field is a - // candidate - // for in-place editing. In-place editor should not - // - Trigger: user. - // - Guarantees: entity is ready, in-place editor (EditorView) is - // associated with the field. - // - Expected behavior: visual indicators - // around the field indicate it is available for in-place editing, no - // in-place editor presented yet. - 'candidate', - // User is highlighting this field. - // - Trigger: user. - // - Guarantees: see 'candidate'. - // - Expected behavior: visual indicators to convey highlighting, in-place - // editing toolbar shows field's label. - 'highlighted', - // User has activated the in-place editing of this field; in-place editor - // is activating. - // - Trigger: user. - // - Guarantees: see 'candidate'. - // - Expected behavior: loading indicator, in-place editor is loading - // remote data (e.g. retrieve form from back-end). Upon retrieval of - // remote data, the in-place editor transitions the field's state to - // 'active'. - 'activating', - // In-place editor has finished loading remote data; ready for use. - // - Trigger: in-place editor. - // - Guarantees: see 'candidate'. - // - Expected behavior: in-place editor for the field is ready for use. - 'active', - // User has modified values in the in-place editor. - // - Trigger: user. - // - Guarantees: see 'candidate', plus in-place editor is ready for use. - // - Expected behavior: visual indicator of change. - 'changed', - // User is saving changed field data in in-place editor to - // PrivateTempStore. The save mechanism of the in-place editor is called. - // - Trigger: user. - // - Guarantees: see 'candidate' and 'active'. - // - Expected behavior: saving indicator, in-place editor is saving field - // data into PrivateTempStore. Upon successful saving (without - // validation errors), the in-place editor transitions the field's state - // to 'saved', but to 'invalid' upon failed saving (with validation - // errors). - 'saving', - // In-place editor has successfully saved the changed field. - // - Trigger: in-place editor. - // - Guarantees: see 'candidate' and 'active'. - // - Expected behavior: transition back to 'candidate' state because the - // deed is done. Then: 1) transition to 'inactive' to allow the field - // to be rerendered, 2) destroy the FieldModel (which also destroys - // attached views like the EditorView), 3) replace the existing field - // HTML with the existing HTML and 4) attach behaviors again so that the - // field becomes available again for in-place editing. - 'saved', - // In-place editor has failed to saved the changed field: there were - // validation errors. - // - Trigger: in-place editor. - // - Guarantees: see 'candidate' and 'active'. - // - Expected behavior: remain in 'invalid' state, let the user make more - // changes so that he can save it again, without validation errors. - 'invalid' - ], - - /** - * Indicates whether the 'from' state comes before the 'to' state. - * - * @param {string} from - * One of {@link Drupal.quickedit.FieldModel.states}. - * @param {string} to - * One of {@link Drupal.quickedit.FieldModel.states}. - * - * @return {bool} - * Whether the 'from' state comes before the 'to' state. - */ - followsStateSequence: function (from, to) { + followsStateSequence: function followsStateSequence(from, to) { return _.indexOf(this.states, from) < _.indexOf(this.states, to); } - }); - /** - * @constructor - * - * @augments Backbone.Collection - */ - Drupal.quickedit.FieldCollection = Backbone.Collection.extend(/** @lends Drupal.quickedit.FieldCollection */{ - - /** - * @type {Drupal.quickedit.FieldModel} - */ + Drupal.quickedit.FieldCollection = Backbone.Collection.extend({ model: Drupal.quickedit.FieldModel }); - -}(_, Backbone, Drupal)); +})(_, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/quickedit.es6.js b/core/modules/quickedit/js/quickedit.es6.js new file mode 100644 index 00000000..84fee16c --- /dev/null +++ b/core/modules/quickedit/js/quickedit.es6.js @@ -0,0 +1,686 @@ +/** + * @file + * Attaches behavior for the Quick Edit module. + * + * Everything happens asynchronously, to allow for: + * - dynamically rendered contextual links + * - asynchronously retrieved (and cached) per-field in-place editing metadata + * - asynchronous setup of in-place editable field and "Quick edit" link. + * + * To achieve this, there are several queues: + * - fieldsMetadataQueue: fields whose metadata still needs to be fetched. + * - fieldsAvailableQueue: queue of fields whose metadata is known, and for + * which it has been confirmed that the user has permission to edit them. + * However, FieldModels will only be created for them once there's a + * contextual link for their entity: when it's possible to initiate editing. + * - contextualLinksQueue: queue of contextual links on entities for which it + * is not yet known whether the user has permission to edit at >=1 of them. + */ + +(function ($, _, Backbone, Drupal, drupalSettings, JSON, storage) { + const options = $.extend(drupalSettings.quickedit, + // Merge strings on top of drupalSettings so that they are not mutable. + { + strings: { + quickEdit: Drupal.t('Quick edit'), + }, + }, + ); + + /** + * Tracks fields without metadata. Contains objects with the following keys: + * - DOM el + * - String fieldID + * - String entityID + */ + let fieldsMetadataQueue = []; + + /** + * Tracks fields ready for use. Contains objects with the following keys: + * - DOM el + * - String fieldID + * - String entityID + */ + let fieldsAvailableQueue = []; + + /** + * Tracks contextual links on entities. Contains objects with the following + * keys: + * - String entityID + * - DOM el + * - DOM region + */ + let contextualLinksQueue = []; + + /** + * Tracks how many instances exist for each unique entity. Contains key-value + * pairs: + * - String entityID + * - Number count + */ + const entityInstancesTracker = {}; + + /** + * + * @type {Drupal~behavior} + */ + Drupal.behaviors.quickedit = { + attach(context) { + // Initialize the Quick Edit app once per page load. + $('body').once('quickedit-init').each(initQuickEdit); + + // Find all in-place editable fields, if any. + const $fields = $(context).find('[data-quickedit-field-id]').once('quickedit'); + if ($fields.length === 0) { + return; + } + + // Process each entity element: identical entities that appear multiple + // times will get a numeric identifier, starting at 0. + $(context).find('[data-quickedit-entity-id]').once('quickedit').each((index, entityElement) => { + processEntity(entityElement); + }); + + // Process each field element: queue to be used or to fetch metadata. + // When a field is being rerendered after editing, it will be processed + // immediately. New fields will be unable to be processed immediately, + // but will instead be queued to have their metadata fetched, which occurs + // below in fetchMissingMetaData(). + $fields.each((index, fieldElement) => { + processField(fieldElement); + }); + + // Entities and fields on the page have been detected, try to set up the + // contextual links for those entities that already have the necessary + // meta- data in the client-side cache. + contextualLinksQueue = _.filter(contextualLinksQueue, contextualLink => !initializeEntityContextualLink(contextualLink)); + + // Fetch metadata for any fields that are queued to retrieve it. + fetchMissingMetadata((fieldElementsWithFreshMetadata) => { + // Metadata has been fetched, reprocess fields whose metadata was + // missing. + _.each(fieldElementsWithFreshMetadata, processField); + + // Metadata has been fetched, try to set up more contextual links now. + contextualLinksQueue = _.filter(contextualLinksQueue, contextualLink => !initializeEntityContextualLink(contextualLink)); + }); + }, + detach(context, settings, trigger) { + if (trigger === 'unload') { + deleteContainedModelsAndQueues($(context)); + } + }, + }; + + /** + * + * @namespace + */ + Drupal.quickedit = { + + /** + * A {@link Drupal.quickedit.AppView} instance. + */ + app: null, + + /** + * @type {object} + * + * @prop {Array.} entities + * @prop {Array.} fields + */ + collections: { + // All in-place editable entities (Drupal.quickedit.EntityModel) on the + // page. + entities: null, + // All in-place editable fields (Drupal.quickedit.FieldModel) on the page. + fields: null, + }, + + /** + * In-place editors will register themselves in this object. + * + * @namespace + */ + editors: {}, + + /** + * Per-field metadata that indicates whether in-place editing is allowed, + * which in-place editor should be used, etc. + * + * @namespace + */ + metadata: { + + /** + * Check if a field exists in storage. + * + * @param {string} fieldID + * The field id to check. + * + * @return {bool} + * Whether it was found or not. + */ + has(fieldID) { + return storage.getItem(this._prefixFieldID(fieldID)) !== null; + }, + + /** + * Add metadata to a field id. + * + * @param {string} fieldID + * The field ID to add data to. + * @param {object} metadata + * Metadata to add. + */ + add(fieldID, metadata) { + storage.setItem(this._prefixFieldID(fieldID), JSON.stringify(metadata)); + }, + + /** + * Get a key from a field id. + * + * @param {string} fieldID + * The field ID to check. + * @param {string} [key] + * The key to check. If empty, will return all metadata. + * + * @return {object|*} + * The value for the key, if defined. Otherwise will return all metadata + * for the specified field id. + * + */ + get(fieldID, key) { + const metadata = JSON.parse(storage.getItem(this._prefixFieldID(fieldID))); + return (typeof key === 'undefined') ? metadata : metadata[key]; + }, + + /** + * Prefix the field id. + * + * @param {string} fieldID + * The field id to prefix. + * + * @return {string} + * A prefixed field id. + */ + _prefixFieldID(fieldID) { + return `Drupal.quickedit.metadata.${fieldID}`; + }, + + /** + * Unprefix the field id. + * + * @param {string} fieldID + * The field id to unprefix. + * + * @return {string} + * An unprefixed field id. + */ + _unprefixFieldID(fieldID) { + // Strip "Drupal.quickedit.metadata.", which is 26 characters long. + return fieldID.substring(26); + }, + + /** + * Intersection calculation. + * + * @param {Array} fieldIDs + * An array of field ids to compare to prefix field id. + * + * @return {Array} + * The intersection found. + */ + intersection(fieldIDs) { + const prefixedFieldIDs = _.map(fieldIDs, this._prefixFieldID); + const intersection = _.intersection(prefixedFieldIDs, _.keys(sessionStorage)); + return _.map(intersection, this._unprefixFieldID); + }, + }, + }; + + // Clear the Quick Edit metadata cache whenever the current user's set of + // permissions changes. + const permissionsHashKey = Drupal.quickedit.metadata._prefixFieldID('permissionsHash'); + const permissionsHashValue = storage.getItem(permissionsHashKey); + const permissionsHash = drupalSettings.user.permissionsHash; + if (permissionsHashValue !== permissionsHash) { + if (typeof permissionsHash === 'string') { + _.chain(storage).keys().each((key) => { + if (key.substring(0, 26) === 'Drupal.quickedit.metadata.') { + storage.removeItem(key); + } + }); + } + storage.setItem(permissionsHashKey, permissionsHash); + } + + /** + * Detect contextual links on entities annotated by quickedit. + * + * Queue contextual links to be processed. + * + * @param {jQuery.Event} event + * The `drupalContextualLinkAdded` event. + * @param {object} data + * An object containing the data relevant to the event. + * + * @listens event:drupalContextualLinkAdded + */ + $(document).on('drupalContextualLinkAdded', (event, data) => { + if (data.$region.is('[data-quickedit-entity-id]')) { + // If the contextual link is cached on the client side, an entity instance + // will not yet have been assigned. So assign one. + if (!data.$region.is('[data-quickedit-entity-instance-id]')) { + data.$region.once('quickedit'); + processEntity(data.$region.get(0)); + } + const contextualLink = { + entityID: data.$region.attr('data-quickedit-entity-id'), + entityInstanceID: data.$region.attr('data-quickedit-entity-instance-id'), + el: data.$el[0], + region: data.$region[0], + }; + // Set up contextual links for this, otherwise queue it to be set up + // later. + if (!initializeEntityContextualLink(contextualLink)) { + contextualLinksQueue.push(contextualLink); + } + } + }); + + /** + * Extracts the entity ID from a field ID. + * + * @param {string} fieldID + * A field ID: a string of the format + * `////`. + * + * @return {string} + * An entity ID: a string of the format `/`. + */ + function extractEntityID(fieldID) { + return fieldID.split('/').slice(0, 2).join('/'); + } + + /** + * Initialize the Quick Edit app. + * + * @param {HTMLElement} bodyElement + * This document's body element. + */ + function initQuickEdit(bodyElement) { + Drupal.quickedit.collections.entities = new Drupal.quickedit.EntityCollection(); + Drupal.quickedit.collections.fields = new Drupal.quickedit.FieldCollection(); + + // Instantiate AppModel (application state) and AppView, which is the + // controller of the whole in-place editing experience. + Drupal.quickedit.app = new Drupal.quickedit.AppView({ + el: bodyElement, + model: new Drupal.quickedit.AppModel(), + entitiesCollection: Drupal.quickedit.collections.entities, + fieldsCollection: Drupal.quickedit.collections.fields, + }); + } + + /** + * Assigns the entity an instance ID. + * + * @param {HTMLElement} entityElement + * A Drupal Entity API entity's DOM element with a data-quickedit-entity-id + * attribute. + */ + function processEntity(entityElement) { + const entityID = entityElement.getAttribute('data-quickedit-entity-id'); + if (!entityInstancesTracker.hasOwnProperty(entityID)) { + entityInstancesTracker[entityID] = 0; + } + else { + entityInstancesTracker[entityID]++; + } + + // Set the calculated entity instance ID for this element. + const entityInstanceID = entityInstancesTracker[entityID]; + entityElement.setAttribute('data-quickedit-entity-instance-id', entityInstanceID); + } + + /** + * Fetch the field's metadata; queue or initialize it (if EntityModel exists). + * + * @param {HTMLElement} fieldElement + * A Drupal Field API field's DOM element with a data-quickedit-field-id + * attribute. + */ + function processField(fieldElement) { + const metadata = Drupal.quickedit.metadata; + const fieldID = fieldElement.getAttribute('data-quickedit-field-id'); + const entityID = extractEntityID(fieldID); + // Figure out the instance ID by looking at the ancestor + // [data-quickedit-entity-id] element's data-quickedit-entity-instance-id + // attribute. + const entityElementSelector = `[data-quickedit-entity-id="${entityID}"]`; + const $entityElement = $(entityElementSelector); + + // If there are no elements returned from `entityElementSelector` + // throw an error. Check the browser console for this message. + if (!$entityElement.length) { + throw `Quick Edit could not associate the rendered entity field markup (with [data-quickedit-field-id="${fieldID}"]) with the corresponding rendered entity markup: no parent DOM node found with [data-quickedit-entity-id="${entityID}"]. This is typically caused by the theme's template for this entity type forgetting to print the attributes.`; + } + let entityElement = $(fieldElement).closest($entityElement); + + // In the case of a full entity view page, the entity title is rendered + // outside of "the entity DOM node": it's rendered as the page title. So in + // this case, we find the lowest common parent element (deepest in the tree) + // and consider that the entity element. + if (entityElement.length === 0) { + const $lowestCommonParent = $entityElement.parents().has(fieldElement).first(); + entityElement = $lowestCommonParent.find($entityElement); + } + const entityInstanceID = entityElement + .get(0) + .getAttribute('data-quickedit-entity-instance-id'); + + // Early-return if metadata for this field is missing. + if (!metadata.has(fieldID)) { + fieldsMetadataQueue.push({ + el: fieldElement, + fieldID, + entityID, + entityInstanceID, + }); + return; + } + // Early-return if the user is not allowed to in-place edit this field. + if (metadata.get(fieldID, 'access') !== true) { + return; + } + + // If an EntityModel for this field already exists (and hence also a "Quick + // edit" contextual link), then initialize it immediately. + if (Drupal.quickedit.collections.entities.findWhere({ entityID, entityInstanceID })) { + initializeField(fieldElement, fieldID, entityID, entityInstanceID); + } + // Otherwise: queue the field. It is now available to be set up when its + // corresponding entity becomes in-place editable. + else { + fieldsAvailableQueue.push({ el: fieldElement, fieldID, entityID, entityInstanceID }); + } + } + + /** + * Initialize a field; create FieldModel. + * + * @param {HTMLElement} fieldElement + * The field's DOM element. + * @param {string} fieldID + * The field's ID. + * @param {string} entityID + * The field's entity's ID. + * @param {string} entityInstanceID + * The field's entity's instance ID. + */ + function initializeField(fieldElement, fieldID, entityID, entityInstanceID) { + const entity = Drupal.quickedit.collections.entities.findWhere({ + entityID, + entityInstanceID, + }); + + $(fieldElement).addClass('quickedit-field'); + + // The FieldModel stores the state of an in-place editable entity field. + const field = new Drupal.quickedit.FieldModel({ + el: fieldElement, + fieldID, + id: `${fieldID}[${entity.get('entityInstanceID')}]`, + entity, + metadata: Drupal.quickedit.metadata.get(fieldID), + acceptStateChange: _.bind(Drupal.quickedit.app.acceptEditorStateChange, Drupal.quickedit.app), + }); + + // Track all fields on the page. + Drupal.quickedit.collections.fields.add(field); + } + + /** + * Fetches metadata for fields whose metadata is missing. + * + * Fields whose metadata is missing are tracked at fieldsMetadataQueue. + * + * @param {function} callback + * A callback function that receives field elements whose metadata will just + * have been fetched. + */ + function fetchMissingMetadata(callback) { + if (fieldsMetadataQueue.length) { + const fieldIDs = _.pluck(fieldsMetadataQueue, 'fieldID'); + const fieldElementsWithoutMetadata = _.pluck(fieldsMetadataQueue, 'el'); + let entityIDs = _.uniq(_.pluck(fieldsMetadataQueue, 'entityID'), true); + // Ensure we only request entityIDs for which we don't have metadata yet. + entityIDs = _.difference(entityIDs, Drupal.quickedit.metadata.intersection(entityIDs)); + fieldsMetadataQueue = []; + + $.ajax({ + url: Drupal.url('quickedit/metadata'), + type: 'POST', + data: { + 'fields[]': fieldIDs, + 'entities[]': entityIDs, + }, + dataType: 'json', + success(results) { + // Store the metadata. + _.each(results, (fieldMetadata, fieldID) => { + Drupal.quickedit.metadata.add(fieldID, fieldMetadata); + }); + + callback(fieldElementsWithoutMetadata); + }, + }); + } + } + + /** + * Loads missing in-place editor's attachments (JavaScript and CSS files). + * + * Missing in-place editors are those whose fields are actively being used on + * the page but don't have. + * + * @param {function} callback + * Callback function to be called when the missing in-place editors (if any) + * have been inserted into the DOM. i.e. they may still be loading. + */ + function loadMissingEditors(callback) { + const loadedEditors = _.keys(Drupal.quickedit.editors); + let missingEditors = []; + Drupal.quickedit.collections.fields.each((fieldModel) => { + const metadata = Drupal.quickedit.metadata.get(fieldModel.get('fieldID')); + if (metadata.access && _.indexOf(loadedEditors, metadata.editor) === -1) { + missingEditors.push(metadata.editor); + // Set a stub, to prevent subsequent calls to loadMissingEditors() from + // loading the same in-place editor again. Loading an in-place editor + // requires talking to a server, to download its JavaScript, then + // executing its JavaScript, and only then its Drupal.quickedit.editors + // entry will be set. + Drupal.quickedit.editors[metadata.editor] = false; + } + }); + missingEditors = _.uniq(missingEditors); + if (missingEditors.length === 0) { + callback(); + return; + } + + // @see https://www.drupal.org/node/2029999. + // Create a Drupal.Ajax instance to load the form. + const loadEditorsAjax = Drupal.ajax({ + url: Drupal.url('quickedit/attachments'), + submit: { 'editors[]': missingEditors }, + }); + // Implement a scoped insert AJAX command: calls the callback after all AJAX + // command functions have been executed (hence the deferred calling). + const realInsert = Drupal.AjaxCommands.prototype.insert; + loadEditorsAjax.commands.insert = function (ajax, response, status) { + _.defer(callback); + realInsert(ajax, response, status); + }; + // Trigger the AJAX request, which will should return AJAX commands to + // insert any missing attachments. + loadEditorsAjax.execute(); + } + + /** + * Attempts to set up a "Quick edit" link and corresponding EntityModel. + * + * @param {object} contextualLink + * An object with the following properties: + * - String entityID: a Quick Edit entity identifier, e.g. "node/1" or + * "block_content/5". + * - String entityInstanceID: a Quick Edit entity instance identifier, + * e.g. 0, 1 or n (depending on whether it's the first, second, or n+1st + * instance of this entity). + * - DOM el: element pointing to the contextual links placeholder for this + * entity. + * - DOM region: element pointing to the contextual region of this entity. + * + * @return {bool} + * Returns true when a contextual the given contextual link metadata can be + * removed from the queue (either because the contextual link has been set + * up or because it is certain that in-place editing is not allowed for any + * of its fields). Returns false otherwise. + */ + function initializeEntityContextualLink(contextualLink) { + const metadata = Drupal.quickedit.metadata; + // Check if the user has permission to edit at least one of them. + function hasFieldWithPermission(fieldIDs) { + for (let i = 0; i < fieldIDs.length; i++) { + const fieldID = fieldIDs[i]; + if (metadata.get(fieldID, 'access') === true) { + return true; + } + } + return false; + } + + // Checks if the metadata for all given field IDs exists. + function allMetadataExists(fieldIDs) { + return fieldIDs.length === metadata.intersection(fieldIDs).length; + } + + // Find all fields for this entity instance and collect their field IDs. + const fields = _.where(fieldsAvailableQueue, { + entityID: contextualLink.entityID, + entityInstanceID: contextualLink.entityInstanceID, + }); + const fieldIDs = _.pluck(fields, 'fieldID'); + + // No fields found yet. + if (fieldIDs.length === 0) { + return false; + } + // The entity for the given contextual link contains at least one field that + // the current user may edit in-place; instantiate EntityModel, + // EntityDecorationView and ContextualLinkView. + else if (hasFieldWithPermission(fieldIDs)) { + const entityModel = new Drupal.quickedit.EntityModel({ + el: contextualLink.region, + entityID: contextualLink.entityID, + entityInstanceID: contextualLink.entityInstanceID, + id: `${contextualLink.entityID}[${contextualLink.entityInstanceID}]`, + label: Drupal.quickedit.metadata.get(contextualLink.entityID, 'label'), + }); + Drupal.quickedit.collections.entities.add(entityModel); + // Create an EntityDecorationView associated with the root DOM node of the + // entity. + const entityDecorationView = new Drupal.quickedit.EntityDecorationView({ + el: contextualLink.region, + model: entityModel, + }); + entityModel.set('entityDecorationView', entityDecorationView); + + // Initialize all queued fields within this entity (creates FieldModels). + _.each(fields, (field) => { + initializeField(field.el, field.fieldID, contextualLink.entityID, contextualLink.entityInstanceID); + }); + fieldsAvailableQueue = _.difference(fieldsAvailableQueue, fields); + + // Initialization should only be called once. Use Underscore's once method + // to get a one-time use version of the function. + const initContextualLink = _.once(() => { + const $links = $(contextualLink.el).find('.contextual-links'); + const contextualLinkView = new Drupal.quickedit.ContextualLinkView($.extend({ + el: $('
  • ').prependTo($links), + model: entityModel, + appModel: Drupal.quickedit.app.model, + }, options)); + entityModel.set('contextualLinkView', contextualLinkView); + }); + + // Set up ContextualLinkView after loading any missing in-place editors. + loadMissingEditors(initContextualLink); + + return true; + } + // There was not at least one field that the current user may edit in-place, + // even though the metadata for all fields within this entity is available. + else if (allMetadataExists(fieldIDs)) { + return true; + } + + return false; + } + + /** + * Delete models and queue items that are contained within a given context. + * + * Deletes any contained EntityModels (plus their associated FieldModels and + * ContextualLinkView) and FieldModels, as well as the corresponding queues. + * + * After EntityModels, FieldModels must also be deleted, because it is + * possible in Drupal for a field DOM element to exist outside of the entity + * DOM element, e.g. when viewing the full node, the title of the node is not + * rendered within the node (the entity) but as the page title. + * + * Note: this will not delete an entity that is actively being in-place + * edited. + * + * @param {jQuery} $context + * The context within which to delete. + */ + function deleteContainedModelsAndQueues($context) { + $context.find('[data-quickedit-entity-id]').addBack('[data-quickedit-entity-id]').each((index, entityElement) => { + // Delete entity model. + const entityModel = Drupal.quickedit.collections.entities.findWhere({ el: entityElement }); + if (entityModel) { + const contextualLinkView = entityModel.get('contextualLinkView'); + contextualLinkView.undelegateEvents(); + contextualLinkView.remove(); + // Remove the EntityDecorationView. + entityModel.get('entityDecorationView').remove(); + // Destroy the EntityModel; this will also destroy its FieldModels. + entityModel.destroy(); + } + + // Filter queue. + function hasOtherRegion(contextualLink) { + return contextualLink.region !== entityElement; + } + + contextualLinksQueue = _.filter(contextualLinksQueue, hasOtherRegion); + }); + + $context.find('[data-quickedit-field-id]').addBack('[data-quickedit-field-id]').each((index, fieldElement) => { + // Delete field models. + Drupal.quickedit.collections.fields.chain() + .filter(fieldModel => fieldModel.get('el') === fieldElement) + .invoke('destroy'); + + // Filter queues. + function hasOtherFieldElement(field) { + return field.el !== fieldElement; + } + + fieldsMetadataQueue = _.filter(fieldsMetadataQueue, hasOtherFieldElement); + fieldsAvailableQueue = _.filter(fieldsAvailableQueue, hasOtherFieldElement); + }); + } +}(jQuery, _, Backbone, Drupal, drupalSettings, window.JSON, window.sessionStorage)); diff --git a/core/modules/quickedit/js/quickedit.js b/core/modules/quickedit/js/quickedit.js index 40bdd3e6..5c2cd95a 100644 --- a/core/modules/quickedit/js/quickedit.js +++ b/core/modules/quickedit/js/quickedit.js @@ -1,244 +1,90 @@ /** - * @file - * Attaches behavior for the Quick Edit module. - * - * Everything happens asynchronously, to allow for: - * - dynamically rendered contextual links - * - asynchronously retrieved (and cached) per-field in-place editing metadata - * - asynchronous setup of in-place editable field and "Quick edit" link. - * - * To achieve this, there are several queues: - * - fieldsMetadataQueue: fields whose metadata still needs to be fetched. - * - fieldsAvailableQueue: queue of fields whose metadata is known, and for - * which it has been confirmed that the user has permission to edit them. - * However, FieldModels will only be created for them once there's a - * contextual link for their entity: when it's possible to initiate editing. - * - contextualLinksQueue: queue of contextual links on entities for which it - * is not yet known whether the user has permission to edit at >=1 of them. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, _, Backbone, Drupal, drupalSettings, JSON, storage) { - - 'use strict'; - - var options = $.extend(drupalSettings.quickedit, - // Merge strings on top of drupalSettings so that they are not mutable. - { - strings: { - quickEdit: Drupal.t('Quick edit') - } + var options = $.extend(drupalSettings.quickedit, { + strings: { + quickEdit: Drupal.t('Quick edit') } - ); - - /** - * Tracks fields without metadata. Contains objects with the following keys: - * - DOM el - * - String fieldID - * - String entityID - */ + }); + var fieldsMetadataQueue = []; - /** - * Tracks fields ready for use. Contains objects with the following keys: - * - DOM el - * - String fieldID - * - String entityID - */ var fieldsAvailableQueue = []; - /** - * Tracks contextual links on entities. Contains objects with the following - * keys: - * - String entityID - * - DOM el - * - DOM region - */ var contextualLinksQueue = []; - /** - * Tracks how many instances exist for each unique entity. Contains key-value - * pairs: - * - String entityID - * - Number count - */ var entityInstancesTracker = {}; - /** - * - * @type {Drupal~behavior} - */ Drupal.behaviors.quickedit = { - attach: function (context) { - // Initialize the Quick Edit app once per page load. + attach: function attach(context) { $('body').once('quickedit-init').each(initQuickEdit); - // Find all in-place editable fields, if any. var $fields = $(context).find('[data-quickedit-field-id]').once('quickedit'); if ($fields.length === 0) { return; } - // Process each entity element: identical entities that appear multiple - // times will get a numeric identifier, starting at 0. $(context).find('[data-quickedit-entity-id]').once('quickedit').each(function (index, entityElement) { processEntity(entityElement); }); - // Process each field element: queue to be used or to fetch metadata. - // When a field is being rerendered after editing, it will be processed - // immediately. New fields will be unable to be processed immediately, - // but will instead be queued to have their metadata fetched, which occurs - // below in fetchMissingMetaData(). $fields.each(function (index, fieldElement) { processField(fieldElement); }); - // Entities and fields on the page have been detected, try to set up the - // contextual links for those entities that already have the necessary - // meta- data in the client-side cache. contextualLinksQueue = _.filter(contextualLinksQueue, function (contextualLink) { return !initializeEntityContextualLink(contextualLink); }); - // Fetch metadata for any fields that are queued to retrieve it. fetchMissingMetadata(function (fieldElementsWithFreshMetadata) { - // Metadata has been fetched, reprocess fields whose metadata was - // missing. _.each(fieldElementsWithFreshMetadata, processField); - // Metadata has been fetched, try to set up more contextual links now. contextualLinksQueue = _.filter(contextualLinksQueue, function (contextualLink) { return !initializeEntityContextualLink(contextualLink); }); }); }, - detach: function (context, settings, trigger) { + detach: function detach(context, settings, trigger) { if (trigger === 'unload') { deleteContainedModelsAndQueues($(context)); } } }; - /** - * - * @namespace - */ Drupal.quickedit = { - - /** - * A {@link Drupal.quickedit.AppView} instance. - */ app: null, - /** - * @type {object} - * - * @prop {Array.} entities - * @prop {Array.} fields - */ collections: { - // All in-place editable entities (Drupal.quickedit.EntityModel) on the - // page. entities: null, - // All in-place editable fields (Drupal.quickedit.FieldModel) on the page. + fields: null }, - /** - * In-place editors will register themselves in this object. - * - * @namespace - */ editors: {}, - /** - * Per-field metadata that indicates whether in-place editing is allowed, - * which in-place editor should be used, etc. - * - * @namespace - */ metadata: { - - /** - * Check if a field exists in storage. - * - * @param {string} fieldID - * The field id to check. - * - * @return {bool} - * Whether it was found or not. - */ - has: function (fieldID) { + has: function has(fieldID) { return storage.getItem(this._prefixFieldID(fieldID)) !== null; }, - - /** - * Add metadata to a field id. - * - * @param {string} fieldID - * The field ID to add data to. - * @param {object} metadata - * Metadata to add. - */ - add: function (fieldID, metadata) { + add: function add(fieldID, metadata) { storage.setItem(this._prefixFieldID(fieldID), JSON.stringify(metadata)); }, - - /** - * Get a key from a field id. - * - * @param {string} fieldID - * The field ID to check. - * @param {string} [key] - * The key to check. If empty, will return all metadata. - * - * @return {object|*} - * The value for the key, if defined. Otherwise will return all metadata - * for the specified field id. - * - */ - get: function (fieldID, key) { + get: function get(fieldID, key) { var metadata = JSON.parse(storage.getItem(this._prefixFieldID(fieldID))); - return (typeof key === 'undefined') ? metadata : metadata[key]; + return typeof key === 'undefined' ? metadata : metadata[key]; }, - - /** - * Prefix the field id. - * - * @param {string} fieldID - * The field id to prefix. - * - * @return {string} - * A prefixed field id. - */ - _prefixFieldID: function (fieldID) { + _prefixFieldID: function _prefixFieldID(fieldID) { return 'Drupal.quickedit.metadata.' + fieldID; }, - - /** - * Unprefix the field id. - * - * @param {string} fieldID - * The field id to unprefix. - * - * @return {string} - * An unprefixed field id. - */ - _unprefixFieldID: function (fieldID) { - // Strip "Drupal.quickedit.metadata.", which is 26 characters long. + _unprefixFieldID: function _unprefixFieldID(fieldID) { return fieldID.substring(26); }, - - /** - * Intersection calculation. - * - * @param {Array} fieldIDs - * An array of field ids to compare to prefix field id. - * - * @return {Array} - * The intersection found. - */ - intersection: function (fieldIDs) { + intersection: function intersection(fieldIDs) { var prefixedFieldIDs = _.map(fieldIDs, this._prefixFieldID); var intersection = _.intersection(prefixedFieldIDs, _.keys(sessionStorage)); return _.map(intersection, this._unprefixFieldID); @@ -246,8 +92,6 @@ } }; - // Clear the Quick Edit metadata cache whenever the current user's set of - // permissions changes. var permissionsHashKey = Drupal.quickedit.metadata._prefixFieldID('permissionsHash'); var permissionsHashValue = storage.getItem(permissionsHashKey); var permissionsHash = drupalSettings.user.permissionsHash; @@ -262,22 +106,8 @@ storage.setItem(permissionsHashKey, permissionsHash); } - /** - * Detect contextual links on entities annotated by quickedit. - * - * Queue contextual links to be processed. - * - * @param {jQuery.Event} event - * The `drupalContextualLinkAdded` event. - * @param {object} data - * An object containing the data relevant to the event. - * - * @listens event:drupalContextualLinkAdded - */ $(document).on('drupalContextualLinkAdded', function (event, data) { if (data.$region.is('[data-quickedit-entity-id]')) { - // If the contextual link is cached on the client side, an entity instance - // will not yet have been assigned. So assign one. if (!data.$region.is('[data-quickedit-entity-instance-id]')) { data.$region.once('quickedit'); processEntity(data.$region.get(0)); @@ -288,40 +118,21 @@ el: data.$el[0], region: data.$region[0] }; - // Set up contextual links for this, otherwise queue it to be set up - // later. + if (!initializeEntityContextualLink(contextualLink)) { contextualLinksQueue.push(contextualLink); } } }); - /** - * Extracts the entity ID from a field ID. - * - * @param {string} fieldID - * A field ID: a string of the format - * `////`. - * - * @return {string} - * An entity ID: a string of the format `/`. - */ function extractEntityID(fieldID) { return fieldID.split('/').slice(0, 2).join('/'); } - /** - * Initialize the Quick Edit app. - * - * @param {HTMLElement} bodyElement - * This document's body element. - */ function initQuickEdit(bodyElement) { Drupal.quickedit.collections.entities = new Drupal.quickedit.EntityCollection(); Drupal.quickedit.collections.fields = new Drupal.quickedit.FieldCollection(); - // Instantiate AppModel (application state) and AppView, which is the - // controller of the whole in-place editing experience. Drupal.quickedit.app = new Drupal.quickedit.AppView({ el: bodyElement, model: new Drupal.quickedit.AppModel(), @@ -330,56 +141,37 @@ }); } - /** - * Assigns the entity an instance ID. - * - * @param {HTMLElement} entityElement - * A Drupal Entity API entity's DOM element with a data-quickedit-entity-id - * attribute. - */ function processEntity(entityElement) { var entityID = entityElement.getAttribute('data-quickedit-entity-id'); if (!entityInstancesTracker.hasOwnProperty(entityID)) { entityInstancesTracker[entityID] = 0; - } - else { + } else { entityInstancesTracker[entityID]++; } - // Set the calculated entity instance ID for this element. var entityInstanceID = entityInstancesTracker[entityID]; entityElement.setAttribute('data-quickedit-entity-instance-id', entityInstanceID); } - /** - * Fetch the field's metadata; queue or initialize it (if EntityModel exists). - * - * @param {HTMLElement} fieldElement - * A Drupal Field API field's DOM element with a data-quickedit-field-id - * attribute. - */ function processField(fieldElement) { var metadata = Drupal.quickedit.metadata; var fieldID = fieldElement.getAttribute('data-quickedit-field-id'); var entityID = extractEntityID(fieldID); - // Figure out the instance ID by looking at the ancestor - // [data-quickedit-entity-id] element's data-quickedit-entity-instance-id - // attribute. + var entityElementSelector = '[data-quickedit-entity-id="' + entityID + '"]'; - var entityElement = $(fieldElement).closest(entityElementSelector); - // In the case of a full entity view page, the entity title is rendered - // outside of "the entity DOM node": it's rendered as the page title. So in - // this case, we find the lowest common parent element (deepest in the tree) - // and consider that the entity element. + var $entityElement = $(entityElementSelector); + + if (!$entityElement.length) { + throw 'Quick Edit could not associate the rendered entity field markup (with [data-quickedit-field-id="' + fieldID + '"]) with the corresponding rendered entity markup: no parent DOM node found with [data-quickedit-entity-id="' + entityID + '"]. This is typically caused by the theme\'s template for this entity type forgetting to print the attributes.'; + } + var entityElement = $(fieldElement).closest($entityElement); + if (entityElement.length === 0) { - var $lowestCommonParent = $(entityElementSelector).parents().has(fieldElement).first(); - entityElement = $lowestCommonParent.find(entityElementSelector); + var $lowestCommonParent = $entityElement.parents().has(fieldElement).first(); + entityElement = $lowestCommonParent.find($entityElement); } - var entityInstanceID = entityElement - .get(0) - .getAttribute('data-quickedit-entity-instance-id'); + var entityInstanceID = entityElement.get(0).getAttribute('data-quickedit-entity-instance-id'); - // Early-return if metadata for this field is missing. if (!metadata.has(fieldID)) { fieldsMetadataQueue.push({ el: fieldElement, @@ -389,35 +181,18 @@ }); return; } - // Early-return if the user is not allowed to in-place edit this field. + if (metadata.get(fieldID, 'access') !== true) { return; } - // If an EntityModel for this field already exists (and hence also a "Quick - // edit" contextual link), then initialize it immediately. - if (Drupal.quickedit.collections.entities.findWhere({entityID: entityID, entityInstanceID: entityInstanceID})) { + if (Drupal.quickedit.collections.entities.findWhere({ entityID: entityID, entityInstanceID: entityInstanceID })) { initializeField(fieldElement, fieldID, entityID, entityInstanceID); - } - // Otherwise: queue the field. It is now available to be set up when its - // corresponding entity becomes in-place editable. - else { - fieldsAvailableQueue.push({el: fieldElement, fieldID: fieldID, entityID: entityID, entityInstanceID: entityInstanceID}); - } + } else { + fieldsAvailableQueue.push({ el: fieldElement, fieldID: fieldID, entityID: entityID, entityInstanceID: entityInstanceID }); + } } - /** - * Initialize a field; create FieldModel. - * - * @param {HTMLElement} fieldElement - * The field's DOM element. - * @param {string} fieldID - * The field's ID. - * @param {string} entityID - * The field's entity's ID. - * @param {string} entityInstanceID - * The field's entity's instance ID. - */ function initializeField(fieldElement, fieldID, entityID, entityInstanceID) { var entity = Drupal.quickedit.collections.entities.findWhere({ entityID: entityID, @@ -426,7 +201,6 @@ $(fieldElement).addClass('quickedit-field'); - // The FieldModel stores the state of an in-place editable entity field. var field = new Drupal.quickedit.FieldModel({ el: fieldElement, fieldID: fieldID, @@ -436,25 +210,15 @@ acceptStateChange: _.bind(Drupal.quickedit.app.acceptEditorStateChange, Drupal.quickedit.app) }); - // Track all fields on the page. Drupal.quickedit.collections.fields.add(field); } - /** - * Fetches metadata for fields whose metadata is missing. - * - * Fields whose metadata is missing are tracked at fieldsMetadataQueue. - * - * @param {function} callback - * A callback function that receives field elements whose metadata will just - * have been fetched. - */ function fetchMissingMetadata(callback) { if (fieldsMetadataQueue.length) { var fieldIDs = _.pluck(fieldsMetadataQueue, 'fieldID'); var fieldElementsWithoutMetadata = _.pluck(fieldsMetadataQueue, 'el'); var entityIDs = _.uniq(_.pluck(fieldsMetadataQueue, 'entityID'), true); - // Ensure we only request entityIDs for which we don't have metadata yet. + entityIDs = _.difference(entityIDs, Drupal.quickedit.metadata.intersection(entityIDs)); fieldsMetadataQueue = []; @@ -466,8 +230,7 @@ 'entities[]': entityIDs }, dataType: 'json', - success: function (results) { - // Store the metadata. + success: function success(results) { _.each(results, function (fieldMetadata, fieldID) { Drupal.quickedit.metadata.add(fieldID, fieldMetadata); }); @@ -478,16 +241,6 @@ } } - /** - * Loads missing in-place editor's attachments (JavaScript and CSS files). - * - * Missing in-place editors are those whose fields are actively being used on - * the page but don't have. - * - * @param {function} callback - * Callback function to be called when the missing in-place editors (if any) - * have been inserted into the DOM. i.e. they may still be loading. - */ function loadMissingEditors(callback) { var loadedEditors = _.keys(Drupal.quickedit.editors); var missingEditors = []; @@ -495,11 +248,7 @@ var metadata = Drupal.quickedit.metadata.get(fieldModel.get('fieldID')); if (metadata.access && _.indexOf(loadedEditors, metadata.editor) === -1) { missingEditors.push(metadata.editor); - // Set a stub, to prevent subsequent calls to loadMissingEditors() from - // loading the same in-place editor again. Loading an in-place editor - // requires talking to a server, to download its JavaScript, then - // executing its JavaScript, and only then its Drupal.quickedit.editors - // entry will be set. + Drupal.quickedit.editors[metadata.editor] = false; } }); @@ -509,47 +258,23 @@ return; } - // @see https://www.drupal.org/node/2029999. - // Create a Drupal.Ajax instance to load the form. var loadEditorsAjax = Drupal.ajax({ url: Drupal.url('quickedit/attachments'), - submit: {'editors[]': missingEditors} + submit: { 'editors[]': missingEditors } }); - // Implement a scoped insert AJAX command: calls the callback after all AJAX - // command functions have been executed (hence the deferred calling). + var realInsert = Drupal.AjaxCommands.prototype.insert; loadEditorsAjax.commands.insert = function (ajax, response, status) { _.defer(callback); realInsert(ajax, response, status); }; - // Trigger the AJAX request, which will should return AJAX commands to - // insert any missing attachments. + loadEditorsAjax.execute(); } - /** - * Attempts to set up a "Quick edit" link and corresponding EntityModel. - * - * @param {object} contextualLink - * An object with the following properties: - * - String entityID: a Quick Edit entity identifier, e.g. "node/1" or - * "block_content/5". - * - String entityInstanceID: a Quick Edit entity instance identifier, - * e.g. 0, 1 or n (depending on whether it's the first, second, or n+1st - * instance of this entity). - * - DOM el: element pointing to the contextual links placeholder for this - * entity. - * - DOM region: element pointing to the contextual region of this entity. - * - * @return {bool} - * Returns true when a contextual the given contextual link metadata can be - * removed from the queue (either because the contextual link has been set - * up or because it is certain that in-place editing is not allowed for any - * of its fields). Returns false otherwise. - */ function initializeEntityContextualLink(contextualLink) { var metadata = Drupal.quickedit.metadata; - // Check if the user has permission to edit at least one of them. + function hasFieldWithPermission(fieldIDs) { for (var i = 0; i < fieldIDs.length; i++) { var fieldID = fieldIDs[i]; @@ -560,106 +285,72 @@ return false; } - // Checks if the metadata for all given field IDs exists. function allMetadataExists(fieldIDs) { return fieldIDs.length === metadata.intersection(fieldIDs).length; } - // Find all fields for this entity instance and collect their field IDs. var fields = _.where(fieldsAvailableQueue, { entityID: contextualLink.entityID, entityInstanceID: contextualLink.entityInstanceID }); var fieldIDs = _.pluck(fields, 'fieldID'); - // No fields found yet. if (fieldIDs.length === 0) { return false; - } - // The entity for the given contextual link contains at least one field that - // the current user may edit in-place; instantiate EntityModel, - // EntityDecorationView and ContextualLinkView. - else if (hasFieldWithPermission(fieldIDs)) { - var entityModel = new Drupal.quickedit.EntityModel({ - el: contextualLink.region, - entityID: contextualLink.entityID, - entityInstanceID: contextualLink.entityInstanceID, - id: contextualLink.entityID + '[' + contextualLink.entityInstanceID + ']', - label: Drupal.quickedit.metadata.get(contextualLink.entityID, 'label') - }); - Drupal.quickedit.collections.entities.add(entityModel); - // Create an EntityDecorationView associated with the root DOM node of the - // entity. - var entityDecorationView = new Drupal.quickedit.EntityDecorationView({ - el: contextualLink.region, - model: entityModel - }); - entityModel.set('entityDecorationView', entityDecorationView); + } else if (hasFieldWithPermission(fieldIDs)) { + var entityModel = new Drupal.quickedit.EntityModel({ + el: contextualLink.region, + entityID: contextualLink.entityID, + entityInstanceID: contextualLink.entityInstanceID, + id: contextualLink.entityID + '[' + contextualLink.entityInstanceID + ']', + label: Drupal.quickedit.metadata.get(contextualLink.entityID, 'label') + }); + Drupal.quickedit.collections.entities.add(entityModel); - // Initialize all queued fields within this entity (creates FieldModels). - _.each(fields, function (field) { - initializeField(field.el, field.fieldID, contextualLink.entityID, contextualLink.entityInstanceID); - }); - fieldsAvailableQueue = _.difference(fieldsAvailableQueue, fields); - - // Initialization should only be called once. Use Underscore's once method - // to get a one-time use version of the function. - var initContextualLink = _.once(function () { - var $links = $(contextualLink.el).find('.contextual-links'); - var contextualLinkView = new Drupal.quickedit.ContextualLinkView($.extend({ - el: $('
  • ').prependTo($links), - model: entityModel, - appModel: Drupal.quickedit.app.model - }, options)); - entityModel.set('contextualLinkView', contextualLinkView); - }); + var entityDecorationView = new Drupal.quickedit.EntityDecorationView({ + el: contextualLink.region, + model: entityModel + }); + entityModel.set('entityDecorationView', entityDecorationView); - // Set up ContextualLinkView after loading any missing in-place editors. - loadMissingEditors(initContextualLink); + _.each(fields, function (field) { + initializeField(field.el, field.fieldID, contextualLink.entityID, contextualLink.entityInstanceID); + }); + fieldsAvailableQueue = _.difference(fieldsAvailableQueue, fields); + + var initContextualLink = _.once(function () { + var $links = $(contextualLink.el).find('.contextual-links'); + var contextualLinkView = new Drupal.quickedit.ContextualLinkView($.extend({ + el: $('
  • ').prependTo($links), + model: entityModel, + appModel: Drupal.quickedit.app.model + }, options)); + entityModel.set('contextualLinkView', contextualLinkView); + }); - return true; - } - // There was not at least one field that the current user may edit in-place, - // even though the metadata for all fields within this entity is available. - else if (allMetadataExists(fieldIDs)) { - return true; - } + loadMissingEditors(initContextualLink); + + return true; + } else if (allMetadataExists(fieldIDs)) { + return true; + } return false; } - /** - * Delete models and queue items that are contained within a given context. - * - * Deletes any contained EntityModels (plus their associated FieldModels and - * ContextualLinkView) and FieldModels, as well as the corresponding queues. - * - * After EntityModels, FieldModels must also be deleted, because it is - * possible in Drupal for a field DOM element to exist outside of the entity - * DOM element, e.g. when viewing the full node, the title of the node is not - * rendered within the node (the entity) but as the page title. - * - * Note: this will not delete an entity that is actively being in-place - * edited. - * - * @param {jQuery} $context - * The context within which to delete. - */ function deleteContainedModelsAndQueues($context) { $context.find('[data-quickedit-entity-id]').addBack('[data-quickedit-entity-id]').each(function (index, entityElement) { - // Delete entity model. - var entityModel = Drupal.quickedit.collections.entities.findWhere({el: entityElement}); + var entityModel = Drupal.quickedit.collections.entities.findWhere({ el: entityElement }); if (entityModel) { var contextualLinkView = entityModel.get('contextualLinkView'); contextualLinkView.undelegateEvents(); contextualLinkView.remove(); - // Remove the EntityDecorationView. + entityModel.get('entityDecorationView').remove(); - // Destroy the EntityModel; this will also destroy its FieldModels. + entityModel.destroy(); } - // Filter queue. function hasOtherRegion(contextualLink) { return contextualLink.region !== entityElement; } @@ -668,12 +359,10 @@ }); $context.find('[data-quickedit-field-id]').addBack('[data-quickedit-field-id]').each(function (index, fieldElement) { - // Delete field models. - Drupal.quickedit.collections.fields.chain() - .filter(function (fieldModel) { return fieldModel.get('el') === fieldElement; }) - .invoke('destroy'); + Drupal.quickedit.collections.fields.chain().filter(function (fieldModel) { + return fieldModel.get('el') === fieldElement; + }).invoke('destroy'); - // Filter queues. function hasOtherFieldElement(field) { return field.el !== fieldElement; } @@ -682,5 +371,4 @@ fieldsAvailableQueue = _.filter(fieldsAvailableQueue, hasOtherFieldElement); }); } - -})(jQuery, _, Backbone, Drupal, drupalSettings, window.JSON, window.sessionStorage); +})(jQuery, _, Backbone, Drupal, drupalSettings, window.JSON, window.sessionStorage); \ No newline at end of file diff --git a/core/modules/quickedit/js/theme.es6.js b/core/modules/quickedit/js/theme.es6.js new file mode 100644 index 00000000..5b43f427 --- /dev/null +++ b/core/modules/quickedit/js/theme.es6.js @@ -0,0 +1,183 @@ +/** + * @file + * Provides theme functions for all of Quick Edit's client-side HTML. + */ + +(function ($, Drupal) { + /** + * Theme function for a "backstage" for the Quick Edit module. + * + * @param {object} settings + * Settings object used to construct the markup. + * @param {string} settings.id + * The id to apply to the backstage. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditBackstage = function (settings) { + let html = ''; + html += `
    `; + return html; + }; + + /** + * Theme function for a toolbar container of the Quick Edit module. + * + * @param {object} settings + * Settings object used to construct the markup. + * @param {string} settings.id + * the id to apply to the backstage. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditEntityToolbar = function (settings) { + let html = ''; + html += `
    `; + html += ''; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    '; + return html; + }; + + /** + * Theme function for a toolbar container of the Quick Edit module. + * + * @param {object} settings + * Settings object used to construct the markup. + * @param {string} settings.entityLabel + * The title of the active entity. + * @param {string} settings.fieldLabel + * The label of the highlighted or active field. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditEntityToolbarLabel = function (settings) { + // @todo Add XSS regression test coverage in https://www.drupal.org/node/2547437 + return `${Drupal.checkPlain(settings.fieldLabel)}${Drupal.checkPlain(settings.entityLabel)}`; + }; + + /** + * Element defining a containing box for the placement of the entity toolbar. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditEntityToolbarFence = function () { + return '
    '; + }; + + /** + * Theme function for a toolbar container of the Quick Edit module. + * + * @param {object} settings + * Settings object used to construct the markup. + * @param {string} settings.id + * The id to apply to the toolbar container. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditFieldToolbar = function (settings) { + return `
    `; + }; + + /** + * Theme function for a toolbar toolgroup of the Quick Edit module. + * + * @param {object} settings + * Settings object used to construct the markup. + * @param {string} [settings.id] + * The id of the toolgroup. + * @param {string} settings.classes + * The class of the toolgroup. + * @param {Array} settings.buttons + * See {@link Drupal.theme.quickeditButtons}. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditToolgroup = function (settings) { + // Classes. + const classes = (settings.classes || []); + classes.unshift('quickedit-toolgroup'); + let html = ''; + html += `
    `; + html += button.label; + html += ''; + } + return html; + }; + + /** + * Theme function for a form container of the Quick Edit module. + * + * @param {object} settings + * Settings object used to construct the markup. + * @param {string} settings.id + * The id to apply to the toolbar container. + * @param {string} settings.loadingMsg + * The message to show while loading. + * + * @return {string} + * The corresponding HTML. + */ + Drupal.theme.quickeditFormContainer = function (settings) { + let html = ''; + html += `
    `; + html += '
    '; + html += '
    '; + html += settings.loadingMsg; + html += '
    '; + html += '
    '; + html += '
    '; + return html; + }; +}(jQuery, Drupal)); diff --git a/core/modules/quickedit/js/theme.js b/core/modules/quickedit/js/theme.js index 93dc3f23..f01e2385 100644 --- a/core/modules/quickedit/js/theme.js +++ b/core/modules/quickedit/js/theme.js @@ -1,40 +1,17 @@ /** - * @file - * Provides theme functions for all of Quick Edit's client-side HTML. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Theme function for a "backstage" for the Quick Edit module. - * - * @param {object} settings - * Settings object used to construct the markup. - * @param {string} settings.id - * The id to apply to the backstage. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditBackstage = function (settings) { var html = ''; html += '
    '; return html; }; - /** - * Theme function for a toolbar container of the Quick Edit module. - * - * @param {object} settings - * Settings object used to construct the markup. - * @param {string} settings.id - * the id to apply to the backstage. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditEntityToolbar = function (settings) { var html = ''; html += '
    '; @@ -48,67 +25,20 @@ return html; }; - /** - * Theme function for a toolbar container of the Quick Edit module. - * - * @param {object} settings - * Settings object used to construct the markup. - * @param {string} settings.entityLabel - * The title of the active entity. - * @param {string} settings.fieldLabel - * The label of the highlighted or active field. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditEntityToolbarLabel = function (settings) { - // @todo Add XSS regression test coverage in https://www.drupal.org/node/2547437 return '' + Drupal.checkPlain(settings.fieldLabel) + '' + Drupal.checkPlain(settings.entityLabel); }; - /** - * Element defining a containing box for the placement of the entity toolbar. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditEntityToolbarFence = function () { return '
    '; }; - /** - * Theme function for a toolbar container of the Quick Edit module. - * - * @param {object} settings - * Settings object used to construct the markup. - * @param {string} settings.id - * The id to apply to the toolbar container. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditFieldToolbar = function (settings) { return '
    '; }; - /** - * Theme function for a toolbar toolgroup of the Quick Edit module. - * - * @param {object} settings - * Settings object used to construct the markup. - * @param {string} [settings.id] - * The id of the toolgroup. - * @param {string} settings.classes - * The class of the toolgroup. - * @param {Array} settings.buttons - * See {@link Drupal.theme.quickeditButtons}. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditToolgroup = function (settings) { - // Classes. - var classes = (settings.classes || []); + var classes = settings.classes || []; classes.unshift('quickedit-toolgroup'); var html = ''; html += '
    '; + html += ''; } return html; }; - /** - * Theme function for a form container of the Quick Edit module. - * - * @param {object} settings - * Settings object used to construct the markup. - * @param {string} settings.id - * The id to apply to the toolbar container. - * @param {string} settings.loadingMsg - * The message to show while loading. - * - * @return {string} - * The corresponding HTML. - */ Drupal.theme.quickeditFormContainer = function (settings) { var html = ''; html += '
    '; @@ -183,5 +84,4 @@ html += '
    '; return html; }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/util.es6.js b/core/modules/quickedit/js/util.es6.js new file mode 100644 index 00000000..7fa952be --- /dev/null +++ b/core/modules/quickedit/js/util.es6.js @@ -0,0 +1,209 @@ +/** + * @file + * Provides utility functions for Quick Edit. + */ + +(function ($, Drupal) { + /** + * @namespace + */ + Drupal.quickedit.util = Drupal.quickedit.util || {}; + + /** + * @namespace + */ + Drupal.quickedit.util.constants = {}; + + /** + * + * @type {string} + */ + Drupal.quickedit.util.constants.transitionEnd = 'transitionEnd.quickedit webkitTransitionEnd.quickedit transitionend.quickedit msTransitionEnd.quickedit oTransitionEnd.quickedit'; + + /** + * Converts a field id into a formatted url path. + * + * @example + * Drupal.quickedit.util.buildUrl( + * 'node/1/body/und/full', + * '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode' + * ); + * + * @param {string} id + * The id of an editable field. + * @param {string} urlFormat + * The Controller route for field processing. + * + * @return {string} + * The formatted URL. + */ + Drupal.quickedit.util.buildUrl = function (id, urlFormat) { + const parts = id.split('/'); + return Drupal.formatString(decodeURIComponent(urlFormat), { + '!entity_type': parts[0], + '!id': parts[1], + '!field_name': parts[2], + '!langcode': parts[3], + '!view_mode': parts[4], + }); + }; + + /** + * Shows a network error modal dialog. + * + * @param {string} title + * The title to use in the modal dialog. + * @param {string} message + * The message to use in the modal dialog. + */ + Drupal.quickedit.util.networkErrorModal = function (title, message) { + const $message = $(`
    ${message}
    `); + var networkErrorModal = Drupal.dialog($message.get(0), { + title, + dialogClass: 'quickedit-network-error', + buttons: [ + { + text: Drupal.t('OK'), + click() { + networkErrorModal.close(); + }, + primary: true, + }, + ], + create() { + $(this).parent().find('.ui-dialog-titlebar-close').remove(); + }, + close(event) { + // Automatically destroy the DOM element that was used for the dialog. + $(event.target).remove(); + }, + }); + networkErrorModal.showModal(); + }; + + /** + * @namespace + */ + Drupal.quickedit.util.form = { + + /** + * Loads a form, calls a callback to insert. + * + * Leverages {@link Drupal.Ajax}' ability to have scoped (per-instance) + * command implementations to be able to call a callback. + * + * @param {object} options + * An object with the following keys: + * @param {string} options.fieldID + * The field ID that uniquely identifies the field for which this form + * will be loaded. + * @param {bool} options.nocssjs + * Boolean indicating whether no CSS and JS should be returned (necessary + * when the form is invisible to the user). + * @param {bool} options.reset + * Boolean indicating whether the data stored for this field's entity in + * PrivateTempStore should be used or reset. + * @param {function} callback + * A callback function that will receive the form to be inserted, as well + * as the ajax object, necessary if the callback wants to perform other + * Ajax commands. + */ + load(options, callback) { + const fieldID = options.fieldID; + + // Create a Drupal.ajax instance to load the form. + const formLoaderAjax = Drupal.ajax({ + url: Drupal.quickedit.util.buildUrl(fieldID, Drupal.url('quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode')), + submit: { + nocssjs: options.nocssjs, + reset: options.reset, + }, + error(xhr, url) { + // Show a modal to inform the user of the network error. + const fieldLabel = Drupal.quickedit.metadata.get(fieldID, 'label'); + const message = Drupal.t('Could not load the form for @field-label, either due to a website problem or a network connection problem.
    Please try again.', { '@field-label': fieldLabel }); + Drupal.quickedit.util.networkErrorModal(Drupal.t('Network problem!'), message); + + // Change the state back to "candidate", to allow the user to start + // in-place editing of the field again. + const fieldModel = Drupal.quickedit.app.model.get('activeField'); + fieldModel.set('state', 'candidate'); + }, + }); + // Implement a scoped quickeditFieldForm AJAX command: calls the callback. + formLoaderAjax.commands.quickeditFieldForm = function (ajax, response, status) { + callback(response.data, ajax); + Drupal.ajax.instances[this.instanceIndex] = null; + }; + // This will ensure our scoped quickeditFieldForm AJAX command gets + // called. + formLoaderAjax.execute(); + }, + + /** + * Creates a {@link Drupal.Ajax} instance that is used to save a form. + * + * @param {object} options + * Submit options to the form. + * @param {bool} options.nocssjs + * Boolean indicating whether no CSS and JS should be returned (necessary + * when the form is invisible to the user). + * @param {Array.} options.other_view_modes + * Array containing view mode IDs (of other instances of this field on the + * page). + * @param {jQuery} $submit + * The submit element. + * + * @return {Drupal.Ajax} + * A {@link Drupal.Ajax} instance. + */ + ajaxifySaving(options, $submit) { + // Re-wire the form to handle submit. + const settings = { + url: $submit.closest('form').attr('action'), + setClick: true, + event: 'click.quickedit', + progress: false, + submit: { + nocssjs: options.nocssjs, + other_view_modes: options.other_view_modes, + }, + + /** + * Reimplement the success handler. + * + * Ensure {@link Drupal.attachBehaviors} does not get called on the + * form. + * + * @param {Drupal.AjaxCommands~commandDefinition} response + * The Drupal AJAX response. + * @param {number} [status] + * The HTTP status code. + */ + success(response, status) { + for (const i in response) { + if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) { + this.commands[response[i].command](this, response[i], status); + } + } + }, + base: $submit.attr('id'), + element: $submit[0], + }; + + return Drupal.ajax(settings); + }, + + /** + * Cleans up the {@link Drupal.Ajax} instance that is used to save the form. + * + * @param {Drupal.Ajax} ajax + * A {@link Drupal.Ajax} instance that was returned by + * {@link Drupal.quickedit.form.ajaxifySaving}. + */ + unajaxifySaving(ajax) { + $(ajax.element).off('click.quickedit'); + }, + + }; +}(jQuery, Drupal)); diff --git a/core/modules/quickedit/js/util.js b/core/modules/quickedit/js/util.js index 4b0a4c43..16b524a9 100644 --- a/core/modules/quickedit/js/util.js +++ b/core/modules/quickedit/js/util.js @@ -1,45 +1,17 @@ /** - * @file - * Provides utility functions for Quick Edit. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * @namespace - */ Drupal.quickedit.util = Drupal.quickedit.util || {}; - /** - * @namespace - */ Drupal.quickedit.util.constants = {}; - /** - * - * @type {string} - */ Drupal.quickedit.util.constants.transitionEnd = 'transitionEnd.quickedit webkitTransitionEnd.quickedit transitionend.quickedit msTransitionEnd.quickedit oTransitionEnd.quickedit'; - /** - * Converts a field id into a formatted url path. - * - * @example - * Drupal.quickedit.util.buildUrl( - * 'node/1/body/und/full', - * '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode' - * ); - * - * @param {string} id - * The id of an editable field. - * @param {string} urlFormat - * The Controller route for field processing. - * - * @return {string} - * The formatted URL. - */ Drupal.quickedit.util.buildUrl = function (id, urlFormat) { var parts = id.split('/'); return Drupal.formatString(decodeURIComponent(urlFormat), { @@ -51,117 +23,57 @@ }); }; - /** - * Shows a network error modal dialog. - * - * @param {string} title - * The title to use in the modal dialog. - * @param {string} message - * The message to use in the modal dialog. - */ Drupal.quickedit.util.networkErrorModal = function (title, message) { var $message = $('
    ' + message + '
    '); var networkErrorModal = Drupal.dialog($message.get(0), { title: title, dialogClass: 'quickedit-network-error', - buttons: [ - { - text: Drupal.t('OK'), - click: function () { - networkErrorModal.close(); - }, - primary: true - } - ], - create: function () { + buttons: [{ + text: Drupal.t('OK'), + click: function click() { + networkErrorModal.close(); + }, + + primary: true + }], + create: function create() { $(this).parent().find('.ui-dialog-titlebar-close').remove(); }, - close: function (event) { - // Automatically destroy the DOM element that was used for the dialog. + close: function close(event) { $(event.target).remove(); } }); networkErrorModal.showModal(); }; - /** - * @namespace - */ Drupal.quickedit.util.form = { - - /** - * Loads a form, calls a callback to insert. - * - * Leverages {@link Drupal.Ajax}' ability to have scoped (per-instance) - * command implementations to be able to call a callback. - * - * @param {object} options - * An object with the following keys: - * @param {string} options.fieldID - * The field ID that uniquely identifies the field for which this form - * will be loaded. - * @param {bool} options.nocssjs - * Boolean indicating whether no CSS and JS should be returned (necessary - * when the form is invisible to the user). - * @param {bool} options.reset - * Boolean indicating whether the data stored for this field's entity in - * PrivateTempStore should be used or reset. - * @param {function} callback - * A callback function that will receive the form to be inserted, as well - * as the ajax object, necessary if the callback wants to perform other - * Ajax commands. - */ - load: function (options, callback) { + load: function load(options, callback) { var fieldID = options.fieldID; - // Create a Drupal.ajax instance to load the form. var formLoaderAjax = Drupal.ajax({ url: Drupal.quickedit.util.buildUrl(fieldID, Drupal.url('quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode')), submit: { nocssjs: options.nocssjs, reset: options.reset }, - error: function (xhr, url) { - // Show a modal to inform the user of the network error. + error: function error(xhr, url) { var fieldLabel = Drupal.quickedit.metadata.get(fieldID, 'label'); - var message = Drupal.t('Could not load the form for @field-label, either due to a website problem or a network connection problem.
    Please try again.', {'@field-label': fieldLabel}); + var message = Drupal.t('Could not load the form for @field-label, either due to a website problem or a network connection problem.
    Please try again.', { '@field-label': fieldLabel }); Drupal.quickedit.util.networkErrorModal(Drupal.t('Network problem!'), message); - // Change the state back to "candidate", to allow the user to start - // in-place editing of the field again. var fieldModel = Drupal.quickedit.app.model.get('activeField'); fieldModel.set('state', 'candidate'); } }); - // Implement a scoped quickeditFieldForm AJAX command: calls the callback. + formLoaderAjax.commands.quickeditFieldForm = function (ajax, response, status) { callback(response.data, ajax); Drupal.ajax.instances[this.instanceIndex] = null; }; - // This will ensure our scoped quickeditFieldForm AJAX command gets - // called. + formLoaderAjax.execute(); }, - - /** - * Creates a {@link Drupal.Ajax} instance that is used to save a form. - * - * @param {object} options - * Submit options to the form. - * @param {bool} options.nocssjs - * Boolean indicating whether no CSS and JS should be returned (necessary - * when the form is invisible to the user). - * @param {Array.} options.other_view_modes - * Array containing view mode IDs (of other instances of this field on the - * page). - * @param {jQuery} $submit - * The submit element. - * - * @return {Drupal.Ajax} - * A {@link Drupal.Ajax} instance. - */ - ajaxifySaving: function (options, $submit) { - // Re-wire the form to handle submit. + ajaxifySaving: function ajaxifySaving(options, $submit) { var settings = { url: $submit.closest('form').attr('action'), setClick: true, @@ -172,42 +84,22 @@ other_view_modes: options.other_view_modes }, - /** - * Reimplement the success handler. - * - * Ensure {@link Drupal.attachBehaviors} does not get called on the - * form. - * - * @param {Drupal.AjaxCommands~commandDefinition} response - * The Drupal AJAX response. - * @param {number} [status] - * The HTTP status code. - */ - success: function (response, status) { + success: function success(response, status) { for (var i in response) { if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) { this.commands[response[i].command](this, response[i], status); } } }, + base: $submit.attr('id'), element: $submit[0] }; return Drupal.ajax(settings); }, - - /** - * Cleans up the {@link Drupal.Ajax} instance that is used to save the form. - * - * @param {Drupal.Ajax} ajax - * A {@link Drupal.Ajax} instance that was returned by - * {@link Drupal.quickedit.form.ajaxifySaving}. - */ - unajaxifySaving: function (ajax) { + unajaxifySaving: function unajaxifySaving(ajax) { $(ajax.element).off('click.quickedit'); } - }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/AppView.es6.js b/core/modules/quickedit/js/views/AppView.es6.js new file mode 100644 index 00000000..1e3093e1 --- /dev/null +++ b/core/modules/quickedit/js/views/AppView.es6.js @@ -0,0 +1,592 @@ +/** + * @file + * A Backbone View that controls the overall "in-place editing application". + * + * @see Drupal.quickedit.AppModel + */ + +(function ($, _, Backbone, Drupal) { + // Indicates whether the page should be reloaded after in-place editing has + // shut down. A page reload is necessary to re-instate the original HTML of + // the edited fields if in-place editing has been canceled and one or more of + // the entity's fields were saved to PrivateTempStore: one of them may have + // been changed to the empty value and hence may have been rerendered as the + // empty string, which makes it impossible for Quick Edit to know where to + // restore the original HTML. + let reload = false; + + Drupal.quickedit.AppView = Backbone.View.extend(/** @lends Drupal.quickedit.AppView# */{ + + /** + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * An object with the following keys: + * @param {Drupal.quickedit.AppModel} options.model + * The application state model. + * @param {Drupal.quickedit.EntityCollection} options.entitiesCollection + * All on-page entities. + * @param {Drupal.quickedit.FieldCollection} options.fieldsCollection + * All on-page fields + */ + initialize(options) { + // AppView's configuration for handling states. + // @see Drupal.quickedit.FieldModel.states + this.activeFieldStates = ['activating', 'active']; + this.singleFieldStates = ['highlighted', 'activating', 'active']; + this.changedFieldStates = ['changed', 'saving', 'saved', 'invalid']; + this.readyFieldStates = ['candidate', 'highlighted']; + + // Track app state. + this.listenTo(options.entitiesCollection, 'change:state', this.appStateChange); + this.listenTo(options.entitiesCollection, 'change:isActive', this.enforceSingleActiveEntity); + + // Track app state. + this.listenTo(options.fieldsCollection, 'change:state', this.editorStateChange); + // Respond to field model HTML representation change events. + this.listenTo(options.fieldsCollection, 'change:html', this.renderUpdatedField); + this.listenTo(options.fieldsCollection, 'change:html', this.propagateUpdatedField); + // Respond to addition. + this.listenTo(options.fieldsCollection, 'add', this.rerenderedFieldToCandidate); + // Respond to destruction. + this.listenTo(options.fieldsCollection, 'destroy', this.teardownEditor); + }, + + /** + * Handles setup/teardown and state changes when the active entity changes. + * + * @param {Drupal.quickedit.EntityModel} entityModel + * An instance of the EntityModel class. + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.EntityModel.states}. + */ + appStateChange(entityModel, state) { + const app = this; + let entityToolbarView; + switch (state) { + case 'launching': + reload = false; + // First, create an entity toolbar view. + entityToolbarView = new Drupal.quickedit.EntityToolbarView({ + model: entityModel, + appModel: this.model, + }); + entityModel.toolbarView = entityToolbarView; + // Second, set up in-place editors. + // They must be notified of state changes, hence this must happen + // while the associated fields are still in the 'inactive' state. + entityModel.get('fields').each((fieldModel) => { + app.setupEditor(fieldModel); + }); + // Third, transition the entity to the 'opening' state, which will + // transition all fields from 'inactive' to 'candidate'. + _.defer(() => { + entityModel.set('state', 'opening'); + }); + break; + + case 'closed': + entityToolbarView = entityModel.toolbarView; + // First, tear down the in-place editors. + entityModel.get('fields').each((fieldModel) => { + app.teardownEditor(fieldModel); + }); + // Second, tear down the entity toolbar view. + if (entityToolbarView) { + entityToolbarView.remove(); + delete entityModel.toolbarView; + } + // A page reload may be necessary to re-instate the original HTML of + // the edited fields. + if (reload) { + reload = false; + location.reload(); + } + break; + } + }, + + /** + * Accepts or reject editor (Editor) state changes. + * + * This is what ensures that the app is in control of what happens. + * + * @param {string} from + * The previous state. + * @param {string} to + * The new state. + * @param {null|object} context + * The context that is trying to trigger the state change. + * @param {Drupal.quickedit.FieldModel} fieldModel + * The fieldModel to which this change applies. + * + * @return {bool} + * Whether the editor change was accepted or rejected. + */ + acceptEditorStateChange(from, to, context, fieldModel) { + let accept = true; + + // If the app is in view mode, then reject all state changes except for + // those to 'inactive'. + if (context && (context.reason === 'stop' || context.reason === 'rerender')) { + if (from === 'candidate' && to === 'inactive') { + accept = true; + } + } + // Handling of edit mode state changes is more granular. + else { + // In general, enforce the states sequence. Disallow going back from a + // "later" state to an "earlier" state, except in explicitly allowed + // cases. + if (!Drupal.quickedit.FieldModel.followsStateSequence(from, to)) { + accept = false; + // Allow: activating/active -> candidate. + // Necessary to stop editing a field. + if (_.indexOf(this.activeFieldStates, from) !== -1 && to === 'candidate') { + accept = true; + } + // Allow: changed/invalid -> candidate. + // Necessary to stop editing a field when it is changed or invalid. + else if ((from === 'changed' || from === 'invalid') && to === 'candidate') { + accept = true; + } + // Allow: highlighted -> candidate. + // Necessary to stop highlighting a field. + else if (from === 'highlighted' && to === 'candidate') { + accept = true; + } + // Allow: saved -> candidate. + // Necessary when successfully saved a field. + else if (from === 'saved' && to === 'candidate') { + accept = true; + } + // Allow: invalid -> saving. + // Necessary to be able to save a corrected, invalid field. + else if (from === 'invalid' && to === 'saving') { + accept = true; + } + // Allow: invalid -> activating. + // Necessary to be able to correct a field that turned out to be + // invalid after the user already had moved on to the next field + // (which we explicitly allow to have a fluent UX). + else if (from === 'invalid' && to === 'activating') { + accept = true; + } + } + + // If it's not against the general principle, then here are more + // disallowed cases to check. + if (accept) { + let activeField; + let activeFieldState; + // Ensure only one field (editor) at a time is active … but allow a + // user to hop from one field to the next, even if we still have to + // start saving the field that is currently active: assume it will be + // valid, to allow for a fluent UX. (If it turns out to be invalid, + // this block of code also handles that.) + if ((this.readyFieldStates.indexOf(from) !== -1 || from === 'invalid') && this.activeFieldStates.indexOf(to) !== -1) { + activeField = this.model.get('activeField'); + if (activeField && activeField !== fieldModel) { + activeFieldState = activeField.get('state'); + // Allow the state change. If the state of the active field is: + // - 'activating' or 'active': change it to 'candidate' + // - 'changed' or 'invalid': change it to 'saving' + // - 'saving' or 'saved': don't do anything. + if (this.activeFieldStates.indexOf(activeFieldState) !== -1) { + activeField.set('state', 'candidate'); + } + else if (activeFieldState === 'changed' || activeFieldState === 'invalid') { + activeField.set('state', 'saving'); + } + + // If the field that's being activated is in fact already in the + // invalid state (which can only happen because above we allowed + // the user to move on to another field to allow for a fluent UX; + // we assumed it would be saved successfully), then we shouldn't + // allow the field to enter the 'activating' state, instead, we + // simply change the active editor. All guarantees and + // assumptions for this field still hold! + if (from === 'invalid') { + this.model.set('activeField', fieldModel); + accept = false; + } + // Do not reject: the field is either in the 'candidate' or + // 'highlighted' state and we allow it to enter the 'activating' + // state! + } + } + // Reject going from activating/active to candidate because of a + // mouseleave. + else if (_.indexOf(this.activeFieldStates, from) !== -1 && to === 'candidate') { + if (context && context.reason === 'mouseleave') { + accept = false; + } + } + // When attempting to stop editing a changed/invalid property, ask for + // confirmation. + else if ((from === 'changed' || from === 'invalid') && to === 'candidate') { + if (context && context.reason === 'mouseleave') { + accept = false; + } + else { + // Check whether the transition has been confirmed? + if (context && context.confirmed) { + accept = true; + } + } + } + } + } + + return accept; + }, + + /** + * Sets up the in-place editor for the given field. + * + * Must happen before the fieldModel's state is changed to 'candidate'. + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * The field for which an in-place editor must be set up. + */ + setupEditor(fieldModel) { + // Get the corresponding entity toolbar. + const entityModel = fieldModel.get('entity'); + const entityToolbarView = entityModel.toolbarView; + // Get the field toolbar DOM root from the entity toolbar. + const fieldToolbarRoot = entityToolbarView.getToolbarRoot(); + // Create in-place editor. + const editorName = fieldModel.get('metadata').editor; + const editorModel = new Drupal.quickedit.EditorModel(); + const editorView = new Drupal.quickedit.editors[editorName]({ + el: $(fieldModel.get('el')), + model: editorModel, + fieldModel, + }); + + // Create in-place editor's toolbar for this field — stored inside the + // entity toolbar, the entity toolbar will position itself appropriately + // above (or below) the edited element. + const toolbarView = new Drupal.quickedit.FieldToolbarView({ + el: fieldToolbarRoot, + model: fieldModel, + $editedElement: $(editorView.getEditedElement()), + editorView, + entityModel, + }); + + // Create decoration for edited element: padding if necessary, sets + // classes on the element to style it according to the current state. + const decorationView = new Drupal.quickedit.FieldDecorationView({ + el: $(editorView.getEditedElement()), + model: fieldModel, + editorView, + }); + + // Track these three views in FieldModel so that we can tear them down + // correctly. + fieldModel.editorView = editorView; + fieldModel.toolbarView = toolbarView; + fieldModel.decorationView = decorationView; + }, + + /** + * Tears down the in-place editor for the given field. + * + * Must happen after the fieldModel's state is changed to 'inactive'. + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * The field for which an in-place editor must be torn down. + */ + teardownEditor(fieldModel) { + // Early-return if this field was not yet decorated. + if (typeof fieldModel.editorView === 'undefined') { + return; + } + + // Unbind event handlers; remove toolbar element; delete toolbar view. + fieldModel.toolbarView.remove(); + delete fieldModel.toolbarView; + + // Unbind event handlers; delete decoration view. Don't remove the element + // because that would remove the field itself. + fieldModel.decorationView.remove(); + delete fieldModel.decorationView; + + // Unbind event handlers; delete editor view. Don't remove the element + // because that would remove the field itself. + fieldModel.editorView.remove(); + delete fieldModel.editorView; + }, + + /** + * Asks the user to confirm whether he wants to stop editing via a modal. + * + * @param {Drupal.quickedit.EntityModel} entityModel + * An instance of the EntityModel class. + * + * @see Drupal.quickedit.AppView#acceptEditorStateChange + */ + confirmEntityDeactivation(entityModel) { + const that = this; + let discardDialog; + + function closeDiscardDialog(action) { + discardDialog.close(action); + // The active modal has been removed. + that.model.set('activeModal', null); + + // If the targetState is saving, the field must be saved, then the + // entity must be saved. + if (action === 'save') { + entityModel.set('state', 'committing', { confirmed: true }); + } + else { + entityModel.set('state', 'deactivating', { confirmed: true }); + // Editing has been canceled and the changes will not be saved. Mark + // the page for reload if the entityModel declares that it requires + // a reload. + if (entityModel.get('reload')) { + reload = true; + entityModel.set('reload', false); + } + } + } + + // Only instantiate if there isn't a modal instance visible yet. + if (!this.model.get('activeModal')) { + const $unsavedChanges = $(`
    ${Drupal.t('You have unsaved changes')}
    `); + discardDialog = Drupal.dialog($unsavedChanges.get(0), { + title: Drupal.t('Discard changes?'), + dialogClass: 'quickedit-discard-modal', + resizable: false, + buttons: [ + { + text: Drupal.t('Save'), + click() { + closeDiscardDialog('save'); + }, + primary: true, + }, + { + text: Drupal.t('Discard changes'), + click() { + closeDiscardDialog('discard'); + }, + }, + ], + // Prevent this modal from being closed without the user making a + // choice as per http://stackoverflow.com/a/5438771. + closeOnEscape: false, + create() { + $(this).parent().find('.ui-dialog-titlebar-close').remove(); + }, + beforeClose: false, + close(event) { + // Automatically destroy the DOM element that was used for the + // dialog. + $(event.target).remove(); + }, + }); + this.model.set('activeModal', discardDialog); + + discardDialog.showModal(); + } + }, + + /** + * Reacts to field state changes; tracks global state. + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * The `fieldModel` holding the state. + * @param {string} state + * The state of the associated field. One of + * {@link Drupal.quickedit.FieldModel.states}. + */ + editorStateChange(fieldModel, state) { + const from = fieldModel.previous('state'); + const to = state; + + // Keep track of the highlighted field in the global state. + if (_.indexOf(this.singleFieldStates, to) !== -1 && this.model.get('highlightedField') !== fieldModel) { + this.model.set('highlightedField', fieldModel); + } + else if (this.model.get('highlightedField') === fieldModel && to === 'candidate') { + this.model.set('highlightedField', null); + } + + // Keep track of the active field in the global state. + if (_.indexOf(this.activeFieldStates, to) !== -1 && this.model.get('activeField') !== fieldModel) { + this.model.set('activeField', fieldModel); + } + else if (this.model.get('activeField') === fieldModel && to === 'candidate') { + // Discarded if it transitions from a changed state to 'candidate'. + if (from === 'changed' || from === 'invalid') { + fieldModel.editorView.revert(); + } + this.model.set('activeField', null); + } + }, + + /** + * Render an updated field (a field whose 'html' attribute changed). + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * The FieldModel whose 'html' attribute changed. + * @param {string} html + * The updated 'html' attribute. + * @param {object} options + * An object with the following keys: + * @param {bool} options.propagation + * Whether this change to the 'html' attribute occurred because of the + * propagation of changes to another instance of this field. + */ + renderUpdatedField(fieldModel, html, options) { + // Get data necessary to rerender property before it is unavailable. + const $fieldWrapper = $(fieldModel.get('el')); + const $context = $fieldWrapper.parent(); + + const renderField = function () { + // Destroy the field model; this will cause all attached views to be + // destroyed too, and removal from all collections in which it exists. + fieldModel.destroy(); + + // Replace the old content with the new content. + $fieldWrapper.replaceWith(html); + + // Attach behaviors again to the modified piece of HTML; this will + // create a new field model and call rerenderedFieldToCandidate() with + // it. + Drupal.attachBehaviors($context.get(0)); + }; + + // When propagating the changes of another instance of this field, this + // field is not being actively edited and hence no state changes are + // necessary. So: only update the state of this field when the rerendering + // of this field happens not because of propagation, but because it is + // being edited itself. + if (!options.propagation) { + // Deferred because renderUpdatedField is reacting to a field model + // change event, and we want to make sure that event fully propagates + // before making another change to the same model. + _.defer(() => { + // First set the state to 'candidate', to allow all attached views to + // clean up all their "active state"-related changes. + fieldModel.set('state', 'candidate'); + + // Similarly, the above .set() call's change event must fully + // propagate before calling it again. + _.defer(() => { + // Set the field's state to 'inactive', to enable the updating of + // its DOM value. + fieldModel.set('state', 'inactive', { reason: 'rerender' }); + + renderField(); + }); + }); + } + else { + renderField(); + } + }, + + /** + * Propagates changes to an updated field to all instances of that field. + * + * @param {Drupal.quickedit.FieldModel} updatedField + * The FieldModel whose 'html' attribute changed. + * @param {string} html + * The updated 'html' attribute. + * @param {object} options + * An object with the following keys: + * @param {bool} options.propagation + * Whether this change to the 'html' attribute occurred because of the + * propagation of changes to another instance of this field. + * + * @see Drupal.quickedit.AppView#renderUpdatedField + */ + propagateUpdatedField(updatedField, html, options) { + // Don't propagate field updates that themselves were caused by + // propagation. + if (options.propagation) { + return; + } + + const htmlForOtherViewModes = updatedField.get('htmlForOtherViewModes'); + Drupal.quickedit.collections.fields + // Find all instances of fields that display the same logical field + // (same entity, same field, just a different instance and maybe a + // different view mode). + .where({ logicalFieldID: updatedField.get('logicalFieldID') }) + .forEach((field) => { + // Ignore the field that was already updated. + if (field === updatedField) { + + } + // If this other instance of the field has the same view mode, we can + // update it easily. + else if (field.getViewMode() === updatedField.getViewMode()) { + field.set('html', updatedField.get('html')); + } + // If this other instance of the field has a different view mode, and + // that is one of the view modes for which a re-rendered version is + // available (and that should be the case unless this field was only + // added to the page after editing of the updated field began), then + // use that view mode's re-rendered version. + else if (field.getViewMode() in htmlForOtherViewModes) { + field.set('html', htmlForOtherViewModes[field.getViewMode()], { propagation: true }); + } + }); + }, + + /** + * If the new in-place editable field is for the entity that's currently + * being edited, then transition it to the 'candidate' state. + * + * This happens when a field was modified, saved and hence rerendered. + * + * @param {Drupal.quickedit.FieldModel} fieldModel + * A field that was just added to the collection of fields. + */ + rerenderedFieldToCandidate(fieldModel) { + const activeEntity = Drupal.quickedit.collections.entities.findWhere({ isActive: true }); + + // Early-return if there is no active entity. + if (!activeEntity) { + return; + } + + // If the field's entity is the active entity, make it a candidate. + if (fieldModel.get('entity') === activeEntity) { + this.setupEditor(fieldModel); + fieldModel.set('state', 'candidate'); + } + }, + + /** + * EntityModel Collection change handler. + * + * Handler is called `change:isActive` and enforces a single active entity. + * + * @param {Drupal.quickedit.EntityModel} changedEntityModel + * The entityModel instance whose active state has changed. + */ + enforceSingleActiveEntity(changedEntityModel) { + // When an entity is deactivated, we don't need to enforce anything. + if (changedEntityModel.get('isActive') === false) { + return; + } + + // This entity was activated; deactivate all other entities. + changedEntityModel.collection.chain() + .filter(entityModel => entityModel.get('isActive') === true && entityModel !== changedEntityModel) + .each((entityModel) => { + entityModel.set('state', 'deactivating'); + }); + }, + + }); +}(jQuery, _, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/views/AppView.js b/core/modules/quickedit/js/views/AppView.js index b09a110b..1903846e 100644 --- a/core/modules/quickedit/js/views/AppView.js +++ b/core/modules/quickedit/js/views/AppView.js @@ -1,91 +1,49 @@ /** - * @file - * A Backbone View that controls the overall "in-place editing application". - * - * @see Drupal.quickedit.AppModel - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, _, Backbone, Drupal) { - - 'use strict'; - - // Indicates whether the page should be reloaded after in-place editing has - // shut down. A page reload is necessary to re-instate the original HTML of - // the edited fields if in-place editing has been canceled and one or more of - // the entity's fields were saved to PrivateTempStore: one of them may have - // been changed to the empty value and hence may have been rerendered as the - // empty string, which makes it impossible for Quick Edit to know where to - // restore the original HTML. var reload = false; - Drupal.quickedit.AppView = Backbone.View.extend(/** @lends Drupal.quickedit.AppView# */{ - - /** - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * An object with the following keys: - * @param {Drupal.quickedit.AppModel} options.model - * The application state model. - * @param {Drupal.quickedit.EntityCollection} options.entitiesCollection - * All on-page entities. - * @param {Drupal.quickedit.FieldCollection} options.fieldsCollection - * All on-page fields - */ - initialize: function (options) { - // AppView's configuration for handling states. - // @see Drupal.quickedit.FieldModel.states + Drupal.quickedit.AppView = Backbone.View.extend({ + initialize: function initialize(options) { this.activeFieldStates = ['activating', 'active']; this.singleFieldStates = ['highlighted', 'activating', 'active']; this.changedFieldStates = ['changed', 'saving', 'saved', 'invalid']; this.readyFieldStates = ['candidate', 'highlighted']; - // Track app state. this.listenTo(options.entitiesCollection, 'change:state', this.appStateChange); this.listenTo(options.entitiesCollection, 'change:isActive', this.enforceSingleActiveEntity); - // Track app state. this.listenTo(options.fieldsCollection, 'change:state', this.editorStateChange); - // Respond to field model HTML representation change events. + this.listenTo(options.fieldsCollection, 'change:html', this.renderUpdatedField); this.listenTo(options.fieldsCollection, 'change:html', this.propagateUpdatedField); - // Respond to addition. + this.listenTo(options.fieldsCollection, 'add', this.rerenderedFieldToCandidate); - // Respond to destruction. + this.listenTo(options.fieldsCollection, 'destroy', this.teardownEditor); }, - - /** - * Handles setup/teardown and state changes when the active entity changes. - * - * @param {Drupal.quickedit.EntityModel} entityModel - * An instance of the EntityModel class. - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.EntityModel.states}. - */ - appStateChange: function (entityModel, state) { + appStateChange: function appStateChange(entityModel, state) { var app = this; - var entityToolbarView; + var entityToolbarView = void 0; switch (state) { case 'launching': reload = false; - // First, create an entity toolbar view. + entityToolbarView = new Drupal.quickedit.EntityToolbarView({ model: entityModel, appModel: this.model }); entityModel.toolbarView = entityToolbarView; - // Second, set up in-place editors. - // They must be notified of state changes, hence this must happen - // while the associated fields are still in the 'inactive' state. + entityModel.get('fields').each(function (fieldModel) { app.setupEditor(fieldModel); }); - // Third, transition the entity to the 'opening' state, which will - // transition all fields from 'inactive' to 'candidate'. + _.defer(function () { entityModel.set('state', 'opening'); }); @@ -93,17 +51,16 @@ case 'closed': entityToolbarView = entityModel.toolbarView; - // First, tear down the in-place editors. + entityModel.get('fields').each(function (fieldModel) { app.teardownEditor(fieldModel); }); - // Second, tear down the entity toolbar view. + if (entityToolbarView) { entityToolbarView.remove(); delete entityModel.toolbarView; } - // A page reload may be necessary to re-instate the original HTML of - // the edited fields. + if (reload) { reload = false; location.reload(); @@ -111,157 +68,76 @@ break; } }, - - /** - * Accepts or reject editor (Editor) state changes. - * - * This is what ensures that the app is in control of what happens. - * - * @param {string} from - * The previous state. - * @param {string} to - * The new state. - * @param {null|object} context - * The context that is trying to trigger the state change. - * @param {Drupal.quickedit.FieldModel} fieldModel - * The fieldModel to which this change applies. - * - * @return {bool} - * Whether the editor change was accepted or rejected. - */ - acceptEditorStateChange: function (from, to, context, fieldModel) { + acceptEditorStateChange: function acceptEditorStateChange(from, to, context, fieldModel) { var accept = true; - // If the app is in view mode, then reject all state changes except for - // those to 'inactive'. if (context && (context.reason === 'stop' || context.reason === 'rerender')) { if (from === 'candidate' && to === 'inactive') { accept = true; } - } - // Handling of edit mode state changes is more granular. - else { - // In general, enforce the states sequence. Disallow going back from a - // "later" state to an "earlier" state, except in explicitly allowed - // cases. - if (!Drupal.quickedit.FieldModel.followsStateSequence(from, to)) { - accept = false; - // Allow: activating/active -> candidate. - // Necessary to stop editing a field. - if (_.indexOf(this.activeFieldStates, from) !== -1 && to === 'candidate') { - accept = true; - } - // Allow: changed/invalid -> candidate. - // Necessary to stop editing a field when it is changed or invalid. - else if ((from === 'changed' || from === 'invalid') && to === 'candidate') { - accept = true; - } - // Allow: highlighted -> candidate. - // Necessary to stop highlighting a field. - else if (from === 'highlighted' && to === 'candidate') { - accept = true; - } - // Allow: saved -> candidate. - // Necessary when successfully saved a field. - else if (from === 'saved' && to === 'candidate') { - accept = true; - } - // Allow: invalid -> saving. - // Necessary to be able to save a corrected, invalid field. - else if (from === 'invalid' && to === 'saving') { - accept = true; - } - // Allow: invalid -> activating. - // Necessary to be able to correct a field that turned out to be - // invalid after the user already had moved on to the next field - // (which we explicitly allow to have a fluent UX). - else if (from === 'invalid' && to === 'activating') { - accept = true; - } - } - - // If it's not against the general principle, then here are more - // disallowed cases to check. - if (accept) { - var activeField; - var activeFieldState; - // Ensure only one field (editor) at a time is active … but allow a - // user to hop from one field to the next, even if we still have to - // start saving the field that is currently active: assume it will be - // valid, to allow for a fluent UX. (If it turns out to be invalid, - // this block of code also handles that.) - if ((this.readyFieldStates.indexOf(from) !== -1 || from === 'invalid') && this.activeFieldStates.indexOf(to) !== -1) { - activeField = this.model.get('activeField'); - if (activeField && activeField !== fieldModel) { - activeFieldState = activeField.get('state'); - // Allow the state change. If the state of the active field is: - // - 'activating' or 'active': change it to 'candidate' - // - 'changed' or 'invalid': change it to 'saving' - // - 'saving' or 'saved': don't do anything. - if (this.activeFieldStates.indexOf(activeFieldState) !== -1) { - activeField.set('state', 'candidate'); - } - else if (activeFieldState === 'changed' || activeFieldState === 'invalid') { - activeField.set('state', 'saving'); - } + } else { + if (!Drupal.quickedit.FieldModel.followsStateSequence(from, to)) { + accept = false; - // If the field that's being activated is in fact already in the - // invalid state (which can only happen because above we allowed - // the user to move on to another field to allow for a fluent UX; - // we assumed it would be saved successfully), then we shouldn't - // allow the field to enter the 'activating' state, instead, we - // simply change the active editor. All guarantees and - // assumptions for this field still hold! - if (from === 'invalid') { - this.model.set('activeField', fieldModel); - accept = false; - } - // Do not reject: the field is either in the 'candidate' or - // 'highlighted' state and we allow it to enter the 'activating' - // state! - } - } - // Reject going from activating/active to candidate because of a - // mouseleave. - else if (_.indexOf(this.activeFieldStates, from) !== -1 && to === 'candidate') { - if (context && context.reason === 'mouseleave') { - accept = false; - } - } - // When attempting to stop editing a changed/invalid property, ask for - // confirmation. - else if ((from === 'changed' || from === 'invalid') && to === 'candidate') { - if (context && context.reason === 'mouseleave') { - accept = false; - } - else { - // Check whether the transition has been confirmed? - if (context && context.confirmed) { + if (_.indexOf(this.activeFieldStates, from) !== -1 && to === 'candidate') { + accept = true; + } else if ((from === 'changed' || from === 'invalid') && to === 'candidate') { accept = true; + } else if (from === 'highlighted' && to === 'candidate') { + accept = true; + } else if (from === 'saved' && to === 'candidate') { + accept = true; + } else if (from === 'invalid' && to === 'saving') { + accept = true; + } else if (from === 'invalid' && to === 'activating') { + accept = true; + } + } + + if (accept) { + var activeField = void 0; + var activeFieldState = void 0; + + if ((this.readyFieldStates.indexOf(from) !== -1 || from === 'invalid') && this.activeFieldStates.indexOf(to) !== -1) { + activeField = this.model.get('activeField'); + if (activeField && activeField !== fieldModel) { + activeFieldState = activeField.get('state'); + + if (this.activeFieldStates.indexOf(activeFieldState) !== -1) { + activeField.set('state', 'candidate'); + } else if (activeFieldState === 'changed' || activeFieldState === 'invalid') { + activeField.set('state', 'saving'); + } + + if (from === 'invalid') { + this.model.set('activeField', fieldModel); + accept = false; + } } - } + } else if (_.indexOf(this.activeFieldStates, from) !== -1 && to === 'candidate') { + if (context && context.reason === 'mouseleave') { + accept = false; + } + } else if ((from === 'changed' || from === 'invalid') && to === 'candidate') { + if (context && context.reason === 'mouseleave') { + accept = false; + } else { + if (context && context.confirmed) { + accept = true; + } + } + } } } - } return accept; }, - - /** - * Sets up the in-place editor for the given field. - * - * Must happen before the fieldModel's state is changed to 'candidate'. - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * The field for which an in-place editor must be set up. - */ - setupEditor: function (fieldModel) { - // Get the corresponding entity toolbar. + setupEditor: function setupEditor(fieldModel) { var entityModel = fieldModel.get('entity'); var entityToolbarView = entityModel.toolbarView; - // Get the field toolbar DOM root from the entity toolbar. + var fieldToolbarRoot = entityToolbarView.getToolbarRoot(); - // Create in-place editor. + var editorName = fieldModel.get('metadata').editor; var editorModel = new Drupal.quickedit.EditorModel(); var editorView = new Drupal.quickedit.editors[editorName]({ @@ -270,9 +146,6 @@ fieldModel: fieldModel }); - // Create in-place editor's toolbar for this field — stored inside the - // entity toolbar, the entity toolbar will position itself appropriately - // above (or below) the edited element. var toolbarView = new Drupal.quickedit.FieldToolbarView({ el: fieldToolbarRoot, model: fieldModel, @@ -281,77 +154,44 @@ entityModel: entityModel }); - // Create decoration for edited element: padding if necessary, sets - // classes on the element to style it according to the current state. var decorationView = new Drupal.quickedit.FieldDecorationView({ el: $(editorView.getEditedElement()), model: fieldModel, editorView: editorView }); - // Track these three views in FieldModel so that we can tear them down - // correctly. fieldModel.editorView = editorView; fieldModel.toolbarView = toolbarView; fieldModel.decorationView = decorationView; }, - - /** - * Tears down the in-place editor for the given field. - * - * Must happen after the fieldModel's state is changed to 'inactive'. - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * The field for which an in-place editor must be torn down. - */ - teardownEditor: function (fieldModel) { - // Early-return if this field was not yet decorated. + teardownEditor: function teardownEditor(fieldModel) { if (typeof fieldModel.editorView === 'undefined') { return; } - // Unbind event handlers; remove toolbar element; delete toolbar view. fieldModel.toolbarView.remove(); delete fieldModel.toolbarView; - // Unbind event handlers; delete decoration view. Don't remove the element - // because that would remove the field itself. fieldModel.decorationView.remove(); delete fieldModel.decorationView; - // Unbind event handlers; delete editor view. Don't remove the element - // because that would remove the field itself. fieldModel.editorView.remove(); delete fieldModel.editorView; }, - - /** - * Asks the user to confirm whether he wants to stop editing via a modal. - * - * @param {Drupal.quickedit.EntityModel} entityModel - * An instance of the EntityModel class. - * - * @see Drupal.quickedit.AppView#acceptEditorStateChange - */ - confirmEntityDeactivation: function (entityModel) { + confirmEntityDeactivation: function confirmEntityDeactivation(entityModel) { var that = this; - var discardDialog; + var discardDialog = void 0; function closeDiscardDialog(action) { discardDialog.close(action); - // The active modal has been removed. + that.model.set('activeModal', null); - // If the targetState is saving, the field must be saved, then the - // entity must be saved. if (action === 'save') { - entityModel.set('state', 'committing', {confirmed: true}); - } - else { - entityModel.set('state', 'deactivating', {confirmed: true}); - // Editing has been canceled and the changes will not be saved. Mark - // the page for reload if the entityModel declares that it requires - // a reload. + entityModel.set('state', 'committing', { confirmed: true }); + } else { + entityModel.set('state', 'deactivating', { confirmed: true }); + if (entityModel.get('reload')) { reload = true; entityModel.set('reload', false); @@ -359,38 +199,33 @@ } } - // Only instantiate if there isn't a modal instance visible yet. if (!this.model.get('activeModal')) { var $unsavedChanges = $('
    ' + Drupal.t('You have unsaved changes') + '
    '); discardDialog = Drupal.dialog($unsavedChanges.get(0), { title: Drupal.t('Discard changes?'), dialogClass: 'quickedit-discard-modal', resizable: false, - buttons: [ - { - text: Drupal.t('Save'), - click: function () { - closeDiscardDialog('save'); - }, - primary: true + buttons: [{ + text: Drupal.t('Save'), + click: function click() { + closeDiscardDialog('save'); }, - { - text: Drupal.t('Discard changes'), - click: function () { - closeDiscardDialog('discard'); - } + + primary: true + }, { + text: Drupal.t('Discard changes'), + click: function click() { + closeDiscardDialog('discard'); } - ], - // Prevent this modal from being closed without the user making a - // choice as per http://stackoverflow.com/a/5438771. + }], + closeOnEscape: false, - create: function () { + create: function create() { $(this).parent().find('.ui-dialog-titlebar-close').remove(); }, + beforeClose: false, - close: function (event) { - // Automatically destroy the DOM element that was used for the - // dialog. + close: function close(event) { $(event.target).remove(); } }); @@ -399,202 +234,87 @@ discardDialog.showModal(); } }, - - /** - * Reacts to field state changes; tracks global state. - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * The `fieldModel` holding the state. - * @param {string} state - * The state of the associated field. One of - * {@link Drupal.quickedit.FieldModel.states}. - */ - editorStateChange: function (fieldModel, state) { + editorStateChange: function editorStateChange(fieldModel, state) { var from = fieldModel.previous('state'); var to = state; - // Keep track of the highlighted field in the global state. if (_.indexOf(this.singleFieldStates, to) !== -1 && this.model.get('highlightedField') !== fieldModel) { this.model.set('highlightedField', fieldModel); - } - else if (this.model.get('highlightedField') === fieldModel && to === 'candidate') { + } else if (this.model.get('highlightedField') === fieldModel && to === 'candidate') { this.model.set('highlightedField', null); } - // Keep track of the active field in the global state. if (_.indexOf(this.activeFieldStates, to) !== -1 && this.model.get('activeField') !== fieldModel) { this.model.set('activeField', fieldModel); - } - else if (this.model.get('activeField') === fieldModel && to === 'candidate') { - // Discarded if it transitions from a changed state to 'candidate'. + } else if (this.model.get('activeField') === fieldModel && to === 'candidate') { if (from === 'changed' || from === 'invalid') { fieldModel.editorView.revert(); } this.model.set('activeField', null); } }, - - /** - * Render an updated field (a field whose 'html' attribute changed). - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * The FieldModel whose 'html' attribute changed. - * @param {string} html - * The updated 'html' attribute. - * @param {object} options - * An object with the following keys: - * @param {bool} options.propagation - * Whether this change to the 'html' attribute occurred because of the - * propagation of changes to another instance of this field. - */ - renderUpdatedField: function (fieldModel, html, options) { - // Get data necessary to rerender property before it is unavailable. + renderUpdatedField: function renderUpdatedField(fieldModel, html, options) { var $fieldWrapper = $(fieldModel.get('el')); var $context = $fieldWrapper.parent(); - var renderField = function () { - // Destroy the field model; this will cause all attached views to be - // destroyed too, and removal from all collections in which it exists. + var renderField = function renderField() { fieldModel.destroy(); - // Replace the old content with the new content. $fieldWrapper.replaceWith(html); - // Attach behaviors again to the modified piece of HTML; this will - // create a new field model and call rerenderedFieldToCandidate() with - // it. Drupal.attachBehaviors($context.get(0)); }; - // When propagating the changes of another instance of this field, this - // field is not being actively edited and hence no state changes are - // necessary. So: only update the state of this field when the rerendering - // of this field happens not because of propagation, but because it is - // being edited itself. if (!options.propagation) { - // Deferred because renderUpdatedField is reacting to a field model - // change event, and we want to make sure that event fully propagates - // before making another change to the same model. _.defer(function () { - // First set the state to 'candidate', to allow all attached views to - // clean up all their "active state"-related changes. fieldModel.set('state', 'candidate'); - // Similarly, the above .set() call's change event must fully - // propagate before calling it again. _.defer(function () { - // Set the field's state to 'inactive', to enable the updating of - // its DOM value. - fieldModel.set('state', 'inactive', {reason: 'rerender'}); + fieldModel.set('state', 'inactive', { reason: 'rerender' }); renderField(); }); }); - } - else { + } else { renderField(); } }, - - /** - * Propagates changes to an updated field to all instances of that field. - * - * @param {Drupal.quickedit.FieldModel} updatedField - * The FieldModel whose 'html' attribute changed. - * @param {string} html - * The updated 'html' attribute. - * @param {object} options - * An object with the following keys: - * @param {bool} options.propagation - * Whether this change to the 'html' attribute occurred because of the - * propagation of changes to another instance of this field. - * - * @see Drupal.quickedit.AppView#renderUpdatedField - */ - propagateUpdatedField: function (updatedField, html, options) { - // Don't propagate field updates that themselves were caused by - // propagation. + propagateUpdatedField: function propagateUpdatedField(updatedField, html, options) { if (options.propagation) { return; } var htmlForOtherViewModes = updatedField.get('htmlForOtherViewModes'); - Drupal.quickedit.collections.fields - // Find all instances of fields that display the same logical field - // (same entity, same field, just a different instance and maybe a - // different view mode). - .where({logicalFieldID: updatedField.get('logicalFieldID')}) - .forEach(function (field) { - // Ignore the field that was already updated. - if (field === updatedField) { - return; - } - // If this other instance of the field has the same view mode, we can - // update it easily. - else if (field.getViewMode() === updatedField.getViewMode()) { + Drupal.quickedit.collections.fields.where({ logicalFieldID: updatedField.get('logicalFieldID') }).forEach(function (field) { + if (field === updatedField) {} else if (field.getViewMode() === updatedField.getViewMode()) { field.set('html', updatedField.get('html')); - } - // If this other instance of the field has a different view mode, and - // that is one of the view modes for which a re-rendered version is - // available (and that should be the case unless this field was only - // added to the page after editing of the updated field began), then - // use that view mode's re-rendered version. - else { - if (field.getViewMode() in htmlForOtherViewModes) { - field.set('html', htmlForOtherViewModes[field.getViewMode()], {propagation: true}); + } else if (field.getViewMode() in htmlForOtherViewModes) { + field.set('html', htmlForOtherViewModes[field.getViewMode()], { propagation: true }); } - } - }); + }); }, + rerenderedFieldToCandidate: function rerenderedFieldToCandidate(fieldModel) { + var activeEntity = Drupal.quickedit.collections.entities.findWhere({ isActive: true }); - /** - * If the new in-place editable field is for the entity that's currently - * being edited, then transition it to the 'candidate' state. - * - * This happens when a field was modified, saved and hence rerendered. - * - * @param {Drupal.quickedit.FieldModel} fieldModel - * A field that was just added to the collection of fields. - */ - rerenderedFieldToCandidate: function (fieldModel) { - var activeEntity = Drupal.quickedit.collections.entities.findWhere({isActive: true}); - - // Early-return if there is no active entity. if (!activeEntity) { return; } - // If the field's entity is the active entity, make it a candidate. if (fieldModel.get('entity') === activeEntity) { this.setupEditor(fieldModel); fieldModel.set('state', 'candidate'); } }, - - /** - * EntityModel Collection change handler. - * - * Handler is called `change:isActive` and enforces a single active entity. - * - * @param {Drupal.quickedit.EntityModel} changedEntityModel - * The entityModel instance whose active state has changed. - */ - enforceSingleActiveEntity: function (changedEntityModel) { - // When an entity is deactivated, we don't need to enforce anything. + enforceSingleActiveEntity: function enforceSingleActiveEntity(changedEntityModel) { if (changedEntityModel.get('isActive') === false) { return; } - // This entity was activated; deactivate all other entities. - changedEntityModel.collection.chain() - .filter(function (entityModel) { - return entityModel.get('isActive') === true && entityModel !== changedEntityModel; - }) - .each(function (entityModel) { - entityModel.set('state', 'deactivating'); - }); + changedEntityModel.collection.chain().filter(function (entityModel) { + return entityModel.get('isActive') === true && entityModel !== changedEntityModel; + }).each(function (entityModel) { + entityModel.set('state', 'deactivating'); + }); } - }); - -}(jQuery, _, Backbone, Drupal)); +})(jQuery, _, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/ContextualLinkView.es6.js b/core/modules/quickedit/js/views/ContextualLinkView.es6.js new file mode 100644 index 00000000..00a15286 --- /dev/null +++ b/core/modules/quickedit/js/views/ContextualLinkView.es6.js @@ -0,0 +1,77 @@ +/** + * @file + * A Backbone View that provides a dynamic contextual link. + */ + +(function ($, Backbone, Drupal) { + Drupal.quickedit.ContextualLinkView = Backbone.View.extend(/** @lends Drupal.quickedit.ContextualLinkView# */{ + + /** + * Define all events to listen to. + * + * @return {object} + * A map of events. + */ + events() { + // Prevents delay and simulated mouse events. + function touchEndToClick(event) { + event.preventDefault(); + event.target.click(); + } + + return { + 'click a': function (event) { + event.preventDefault(); + this.model.set('state', 'launching'); + }, + 'touchEnd a': touchEndToClick, + }; + }, + + /** + * Create a new contextual link view. + * + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * An object with the following keys: + * @param {Drupal.quickedit.EntityModel} options.model + * The associated entity's model. + * @param {Drupal.quickedit.AppModel} options.appModel + * The application state model. + * @param {object} options.strings + * The strings for the "Quick edit" link. + */ + initialize(options) { + // Insert the text of the quick edit toggle. + this.$el.find('a').text(options.strings.quickEdit); + // Initial render. + this.render(); + // Re-render whenever this entity's isActive attribute changes. + this.listenTo(this.model, 'change:isActive', this.render); + }, + + /** + * Render function for the contextual link view. + * + * @param {Drupal.quickedit.EntityModel} entityModel + * The associated `EntityModel`. + * @param {bool} isActive + * Whether the in-place editor is active or not. + * + * @return {Drupal.quickedit.ContextualLinkView} + * The `ContextualLinkView` in question. + */ + render(entityModel, isActive) { + this.$el.find('a').attr('aria-pressed', isActive); + + // Hides the contextual links if an in-place editor is active. + this.$el.closest('.contextual').toggle(!isActive); + + return this; + }, + + }); +}(jQuery, Backbone, Drupal)); diff --git a/core/modules/quickedit/js/views/ContextualLinkView.js b/core/modules/quickedit/js/views/ContextualLinkView.js index bf50f616..e98a95fb 100644 --- a/core/modules/quickedit/js/views/ContextualLinkView.js +++ b/core/modules/quickedit/js/views/ContextualLinkView.js @@ -1,81 +1,39 @@ /** - * @file - * A Backbone View that provides a dynamic contextual link. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Backbone, Drupal) { - - 'use strict'; - - Drupal.quickedit.ContextualLinkView = Backbone.View.extend(/** @lends Drupal.quickedit.ContextualLinkView# */{ - - /** - * Define all events to listen to. - * - * @return {object} - * A map of events. - */ - events: function () { - // Prevents delay and simulated mouse events. + Drupal.quickedit.ContextualLinkView = Backbone.View.extend({ + events: function events() { function touchEndToClick(event) { event.preventDefault(); event.target.click(); } return { - 'click a': function (event) { + 'click a': function clickA(event) { event.preventDefault(); this.model.set('state', 'launching'); }, 'touchEnd a': touchEndToClick }; }, - - /** - * Create a new contextual link view. - * - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * An object with the following keys: - * @param {Drupal.quickedit.EntityModel} options.model - * The associated entity's model. - * @param {Drupal.quickedit.AppModel} options.appModel - * The application state model. - * @param {object} options.strings - * The strings for the "Quick edit" link. - */ - initialize: function (options) { - // Insert the text of the quick edit toggle. + initialize: function initialize(options) { this.$el.find('a').text(options.strings.quickEdit); - // Initial render. + this.render(); - // Re-render whenever this entity's isActive attribute changes. + this.listenTo(this.model, 'change:isActive', this.render); }, - - /** - * Render function for the contextual link view. - * - * @param {Drupal.quickedit.EntityModel} entityModel - * The associated `EntityModel`. - * @param {bool} isActive - * Whether the in-place editor is active or not. - * - * @return {Drupal.quickedit.ContextualLinkView} - * The `ContextualLinkView` in question. - */ - render: function (entityModel, isActive) { + render: function render(entityModel, isActive) { this.$el.find('a').attr('aria-pressed', isActive); - // Hides the contextual links if an in-place editor is active. this.$el.closest('.contextual').toggle(!isActive); return this; } - }); - -})(jQuery, Backbone, Drupal); +})(jQuery, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/quickedit/js/views/EditorView.es6.js b/core/modules/quickedit/js/views/EditorView.es6.js new file mode 100644 index 00000000..7eff43e4 --- /dev/null +++ b/core/modules/quickedit/js/views/EditorView.es6.js @@ -0,0 +1,300 @@ +/** + * @file + * An abstract Backbone View that controls an in-place editor. + */ + +(function ($, Backbone, Drupal) { + Drupal.quickedit.EditorView = Backbone.View.extend(/** @lends Drupal.quickedit.EditorView# */{ + + /** + * A base implementation that outlines the structure for in-place editors. + * + * Specific in-place editor implementations should subclass (extend) this + * View and override whichever method they deem necessary to override. + * + * Typically you would want to override this method to set the + * originalValue attribute in the FieldModel to such a value that your + * in-place editor can revert to the original value when necessary. + * + * @example + *
    If you override this method, you should call this + * method (the parent class' initialize()) first.If you override this method, you should call this - * method (the parent class' initialize()) first.
    - - {% for requirement in requirements %} - - {% if requirement.severity_status in ['warning', 'error'] %} - - - + {{ requirement.title }} + + {{ requirement.value }} + {% if requirement.description %} +
    {{ requirement.description }}
    + {% endif %} + {% endfor %} -
    -
    + * + * Available variables: + * - grouped_requirements: Contains grouped requirements. + * Each group contains: + * - title: The title of the group. + * - type: The severity of the group. + * - items: The requirement instances. + * Each requirement item contains: + * - title: The title of the requirement. + * - value: (optional) The requirement's status. + * - description: (optional) The requirement's description. + * - severity_title: The title of the severity. + * - severity_status: Indicates the severity status. + * - requirements: Ungrouped requirements + * + * @ingroup themeable + */ + #} +{% for group in grouped_requirements %} +

    {{ group.title }}

    + {% for requirement in group.items %} +
    + + {% if requirement.severity_title %} {{ requirement.severity_title }} - {% else %} -
    - {% endif %} - {{ requirement.title }} - - {{ requirement.value }} - {% if requirement.description %} -
    {{ requirement.description }}
    {% endif %} -
    +{% endfor %} diff --git a/core/modules/system/tests/fixtures/update/block.block.secondtestfor2513534.yml b/core/modules/system/tests/fixtures/update/block.block.secondtestfor2513534.yml new file mode 100644 index 00000000..2999cab9 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/block.block.secondtestfor2513534.yml @@ -0,0 +1,18 @@ +uuid: 3c4e92c3-5fb1-408d-993c-6066559230be +langcode: en +status: true +dependencies: + theme: + - bartik +id: pagetitle_2 +theme: bartik +region: '-1' +weight: null +provider: null +plugin: page_title_block +settings: + id: page_title_block + label: 'Page title' + provider: core + label_display: '0' +visibility: { } diff --git a/core/modules/system/tests/fixtures/update/block.block.testfor2513534.yml b/core/modules/system/tests/fixtures/update/block.block.testfor2513534.yml new file mode 100644 index 00000000..b8a55fad --- /dev/null +++ b/core/modules/system/tests/fixtures/update/block.block.testfor2513534.yml @@ -0,0 +1,18 @@ +uuid: 87097da9-29d1-441f-8b00-b93852c760d6 +langcode: en +status: false +dependencies: + theme: + - bartik +id: pagetitle_1 +theme: bartik +region: '-1' +weight: -8 +provider: null +plugin: page_title_block +settings: + id: page_title_block + label: 'Page title' + provider: core + label_display: '0' +visibility: { } diff --git a/core/modules/system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz b/core/modules/system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz index 615b88a7..d7f880d0 100644 Binary files a/core/modules/system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz and b/core/modules/system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz differ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update.php.gz new file mode 100644 index 00000000..a7ecfdce Binary files /dev/null and b/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update.php.gz differ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz new file mode 100644 index 00000000..0252db84 Binary files /dev/null and b/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz differ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul_rev.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul_rev.php.gz new file mode 100644 index 00000000..d7a8ba13 Binary files /dev/null and b/core/modules/system/tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul_rev.php.gz differ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz new file mode 100644 index 00000000..19772649 Binary files /dev/null and b/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz differ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php b/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php index 7f23f902..cb356768 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php @@ -23,16 +23,16 @@ foreach ($block_configs as $block_config) { $connection->insert('config') - ->fields(array( + ->fields([ 'collection', 'name', 'data', - )) - ->values(array( + ]) + ->values([ 'collection' => '', 'name' => 'block.block.' . $block_config['id'], 'data' => serialize($block_config), - )) + ]) ->execute(); } diff --git a/core/modules/system/tests/fixtures/update/drupal-8.broken_routing.php b/core/modules/system/tests/fixtures/update/drupal-8.broken_routing.php index 604321dd..e06cd1c5 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.broken_routing.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.broken_routing.php @@ -7,7 +7,6 @@ use Drupal\Core\Database\Database; - $connection = Database::getConnection(); $config = unserialize($connection->query("SELECT data FROM {config} where name = :name", [':name' => 'core.extension'])->fetchField()); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php b/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php new file mode 100644 index 00000000..0c537f53 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php @@ -0,0 +1,162 @@ +insert('entity_test_revlog') + ->fields([ + 'id', + 'revision_id', + 'type', + 'uuid', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'type' => 'entity_test_revlog', + 'uuid' => 'f0b962b1-391b-441b-a664-2468ad520d96', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + ]) + ->execute(); + +$connection->insert('entity_test_revlog_revision') + ->fields([ + 'id', + 'revision_id', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '1', + 'langcode' => 'en', + 'revision_created' => '1476268517', + 'revision_user' => '1', + 'revision_log_message' => 'first revision', + 'name' => 'entity 1', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + ]) + ->execute(); + +// Data for entity type "entity_test_mul_revlog" +$connection->insert('entity_test_mul_revlog') + ->fields([ + 'id', + 'revision_id', + 'type', + 'uuid', + 'langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'type' => 'entity_test_mul_revlog', + 'uuid' => '6f04027a-1cbd-46e3-a67e-72636b493d4f', + 'langcode' => 'en', + ]) + ->execute(); + +$connection->insert('entity_test_mul_revlog_field_data') + ->fields([ + 'id', + 'revision_id', + 'type', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + 'default_langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'type' => 'entity_test_mul_revlog', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + 'default_langcode' => '1', + ]) + ->execute(); + +$connection->insert('entity_test_mul_revlog_field_revision') + ->fields([ + 'id', + 'revision_id', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + 'default_langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '1', + 'langcode' => 'en', + 'revision_created' => '1476268517', + 'revision_user' => '1', + 'revision_log_message' => 'first revision', + 'name' => 'entity 1', + 'default_langcode' => '1', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + 'default_langcode' => '1', + ]) + ->execute(); + +$connection->insert('entity_test_mul_revlog_revision') + ->fields([ + 'id', + 'revision_id', + 'langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '1', + 'langcode' => 'en', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'langcode' => 'en', + ]) + ->execute(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php new file mode 100644 index 00000000..3a5bc181 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php @@ -0,0 +1,36 @@ +merge('key_value') + ->fields([ + 'value' => 'i:8000;', + 'name' => 'entity_test_schema_converter', + 'collection' => 'system.schema', + ]) + ->condition('collection', 'system.schema') + ->condition('name', 'entity_test_schema_converter') + ->execute(); + +// Update core.extension. +$extensions = $connection->select('config') + ->fields('config', ['data']) + ->condition('collection', '') + ->condition('name', 'core.extension') + ->execute() + ->fetchField(); +$extensions = unserialize($extensions); +$extensions['module']['entity_test_schema_converter'] = 8000; +$connection->update('config') + ->fields([ + 'data' => serialize($extensions), + 'collection' => '', + 'name' => 'core.extension', + ]) + ->condition('collection', '') + ->condition('name', 'core.extension') + ->execute(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.field-schema-data-uninstall-2573667.php b/core/modules/system/tests/fixtures/update/drupal-8.field-schema-data-uninstall-2573667.php index a511cb54..e3531a0c 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.field-schema-data-uninstall-2573667.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.field-schema-data-uninstall-2573667.php @@ -11,64 +11,64 @@ $connection = Database::getConnection(); $connection->insert('key_value') - ->fields(array( + ->fields([ 'collection', 'name', 'value', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.body', 'value' => 'a:2:{s:19:"block_content__body";a:4:{s:11:"description";s:42:"Data storage for block_content field body.";s:6:"fields";a:9:{s:6:"bundle";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:128;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:88:"The field instance bundle to which this row belongs, used when deleting a field instance";}s:7:"deleted";a:5:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:1;s:7:"default";i:0;s:11:"description";s:60:"A boolean indicating whether this data item has been deleted";}s:9:"entity_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:38:"The entity id this data is attached to";}s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:47:"The entity revision id this data is attached to";}s:8:"langcode";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:32;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:37:"The language code for this data item.";}s:5:"delta";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:67:"The sequence number for this data item, used for multi-value fields";}s:10:"body_value";a:3:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:1;}s:12:"body_summary";a:3:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;}s:11:"body_format";a:3:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:255;s:8:"not null";b:0;}}s:11:"primary key";a:4:{i:0;s:9:"entity_id";i:1;s:7:"deleted";i:2;s:5:"delta";i:3;s:8:"langcode";}s:7:"indexes";a:3:{s:6:"bundle";a:1:{i:0;s:6:"bundle";}s:11:"revision_id";a:1:{i:0;s:11:"revision_id";}s:11:"body_format";a:1:{i:0;s:11:"body_format";}}}s:28:"block_content_revision__body";a:4:{s:11:"description";s:54:"Revision archive storage for block_content field body.";s:6:"fields";a:9:{s:6:"bundle";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:128;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:88:"The field instance bundle to which this row belongs, used when deleting a field instance";}s:7:"deleted";a:5:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:1;s:7:"default";i:0;s:11:"description";s:60:"A boolean indicating whether this data item has been deleted";}s:9:"entity_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:38:"The entity id this data is attached to";}s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:47:"The entity revision id this data is attached to";}s:8:"langcode";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:32;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:37:"The language code for this data item.";}s:5:"delta";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:67:"The sequence number for this data item, used for multi-value fields";}s:10:"body_value";a:3:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:1;}s:12:"body_summary";a:3:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;}s:11:"body_format";a:3:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:255;s:8:"not null";b:0;}}s:11:"primary key";a:5:{i:0;s:9:"entity_id";i:1;s:11:"revision_id";i:2;s:7:"deleted";i:3;s:5:"delta";i:4;s:8:"langcode";}s:7:"indexes";a:3:{s:6:"bundle";a:1:{i:0;s:6:"bundle";}s:11:"revision_id";a:1:{i:0;s:11:"revision_id";}s:11:"body_format";a:1:{i:0;s:11:"body_format";}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.changed', 'value' => 'a:2:{s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:7:"changed";a:2:{s:4:"type";s:3:"int";s:8:"not null";b:0;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:7:"changed";a:2:{s:4:"type";s:3:"int";s:8:"not null";b:0;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.default_langcode', 'value' => 'a:2:{s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:16:"default_langcode";a:3:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:1;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:16:"default_langcode";a:3:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:1;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.id', 'value' => 'a:4:{s:13:"block_content";a:1:{s:6:"fields";a:1:{s:2:"id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:2:"id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}s:22:"block_content_revision";a:1:{s:6:"fields";a:1:{s:2:"id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:2:"id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.info', 'value' => 'a:2:{s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:4:"info";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:255;s:6:"binary";b:0;s:8:"not null";b:0;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:4:"info";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:255;s:6:"binary";b:0;s:8:"not null";b:0;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.langcode', 'value' => 'a:4:{s:13:"block_content";a:1:{s:6:"fields";a:1:{s:8:"langcode";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:12;s:8:"is_ascii";b:1;s:8:"not null";b:1;}}}s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:8:"langcode";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:12;s:8:"is_ascii";b:1;s:8:"not null";b:1;}}}s:22:"block_content_revision";a:1:{s:6:"fields";a:1:{s:8:"langcode";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:12;s:8:"is_ascii";b:1;s:8:"not null";b:1;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:8:"langcode";a:4:{s:4:"type";s:7:"varchar";s:6:"length";i:12;s:8:"is_ascii";b:1;s:8:"not null";b:1;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.revision_id', 'value' => 'a:4:{s:13:"block_content";a:1:{s:6:"fields";a:1:{s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:0;}}}s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}s:22:"block_content_revision";a:1:{s:6:"fields";a:1:{s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:4:"size";s:6:"normal";s:8:"not null";b:1;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.revision_log', 'value' => 'a:1:{s:22:"block_content_revision";a:1:{s:6:"fields";a:1:{s:12:"revision_log";a:3:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.revision_translation_affected', 'value' => 'a:2:{s:24:"block_content_field_data";a:1:{s:6:"fields";a:1:{s:29:"revision_translation_affected";a:3:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:0;}}}s:28:"block_content_field_revision";a:1:{s:6:"fields";a:1:{s:29:"revision_translation_affected";a:3:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:0;}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.type', 'value' => 'a:2:{s:13:"block_content";a:2:{s:6:"fields";a:1:{s:4:"type";a:4:{s:11:"description";s:28:"The ID of the target entity.";s:4:"type";s:13:"varchar_ascii";s:6:"length";i:32;s:8:"not null";b:1;}}s:7:"indexes";a:1:{s:36:"block_content_field__type__target_id";a:1:{i:0;s:4:"type";}}}s:24:"block_content_field_data";a:2:{s:6:"fields";a:1:{s:4:"type";a:4:{s:11:"description";s:28:"The ID of the target entity.";s:4:"type";s:13:"varchar_ascii";s:6:"length";i:32;s:8:"not null";b:1;}}s:7:"indexes";a:1:{s:36:"block_content_field__type__target_id";a:1:{i:0;s:4:"type";}}}}', - )) - ->values(array( + ]) + ->values([ 'collection' => 'entity.storage_schema.sql', 'name' => 'block_content.field_schema_data.uuid', 'value' => 'a:1:{s:13:"block_content";a:2:{s:6:"fields";a:1:{s:4:"uuid";a:4:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:128;s:6:"binary";b:0;s:8:"not null";b:1;}}s:11:"unique keys";a:1:{s:32:"block_content_field__uuid__value";a:1:{i:0;s:4:"uuid";}}}}', - )) + ]) ->execute(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz index 1b3e2396..b3f2afb3 100644 Binary files a/core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz and b/core/modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz differ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php b/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php index a47f9e01..6cf44b17 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php @@ -31,11 +31,11 @@ // Update the config entity query "index". $existing_blocks = $connection->select('key_value') - ->fields('key_value', ['value']) - ->condition('collection', 'config.entity.key_store.block') - ->condition('name', 'theme:seven') - ->execute() - ->fetchField(); + ->fields('key_value', ['value']) + ->condition('collection', 'config.entity.key_store.block') + ->condition('name', 'theme:seven') + ->execute() + ->fetchField(); $existing_blocks = unserialize($existing_blocks); $connection->update('key_value') diff --git a/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php b/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php index 1ac03cae..63582dc3 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php @@ -31,11 +31,11 @@ // Update the config entity query "index". $existing_blocks = $connection->select('key_value') - ->fields('key_value', ['value']) - ->condition('collection', 'config.entity.key_store.block') - ->condition('name', 'theme:seven') - ->execute() - ->fetchField(); + ->fields('key_value', ['value']) + ->condition('collection', 'config.entity.key_store.block') + ->condition('name', 'theme:seven') + ->execute() + ->fetchField(); $existing_blocks = unserialize($existing_blocks); $connection->update('key_value') diff --git a/core/modules/system/tests/fixtures/update/drupal-8.update-test-block-disabled-2513534.php b/core/modules/system/tests/fixtures/update/drupal-8.update-test-block-disabled-2513534.php new file mode 100644 index 00000000..fa394473 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.update-test-block-disabled-2513534.php @@ -0,0 +1,50 @@ +insert('config') + ->fields([ + 'collection', + 'name', + 'data', + ]) + ->values([ + 'collection' => '', + 'name' => 'block.block.' . $block_config['id'], + 'data' => serialize($block_config), + ]) + ->execute(); +} + +// Update the config entity query "index". +$existing_blocks = $connection->select('key_value') + ->fields('key_value', ['value']) + ->condition('collection', 'config.entity.key_store.block') + ->condition('name', 'theme:bartik') + ->execute() + ->fetchField(); +$existing_blocks = unserialize($existing_blocks); + +$connection->update('key_value') + ->fields([ + 'value' => serialize(array_merge($existing_blocks, ['block.block.testfor2513534', 'block.block.secondtestfor2513534'])) + ]) + ->condition('collection', 'config.entity.key_store.block') + ->condition('name', 'theme:bartik') + ->execute(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php index 7250741c..93592ece 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php @@ -10,20 +10,20 @@ $connection = Database::getConnection(); // Create the table. -$connection->schema()->createTable('update_test_schema_table', array( - 'fields' => array( - 'a' => array( +$connection->schema()->createTable('update_test_schema_table', [ + 'fields' => [ + 'a' => [ 'type' => 'int', 'not null' => TRUE, 'size' => 'normal', - ), - 'b' => array( + ], + 'b' => [ 'type' => 'blob', 'not null' => FALSE, 'size' => 'normal', - ), - ), -)); + ], + ], +]); // Set the schema version. $connection->merge('key_value') diff --git a/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php b/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php index 2fcda10a..7b04a369 100644 --- a/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php +++ b/core/modules/system/tests/fixtures/update/drupal-8.views-entity-views-data-2455125.php @@ -18,15 +18,15 @@ foreach ($views_configs as $views_config) { $connection->insert('config') - ->fields(array( + ->fields([ 'collection', 'name', 'data', - )) - ->values(array( + ]) + ->values([ 'collection' => '', 'name' => 'views.view.' . $views_config['id'], 'data' => serialize($views_config), - )) + ]) ->execute(); } diff --git a/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php b/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php new file mode 100644 index 00000000..4cc52277 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php @@ -0,0 +1,35 @@ +insert('config') + ->fields([ + 'collection', + 'name', + 'data', + ]) + ->values([ + 'collection' => '', + 'name' => 'views.view.' . $views_config['id'], + 'data' => serialize($views_config), + ]) + ->execute(); +} diff --git a/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml b/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml new file mode 100644 index 00000000..d9eba9a3 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml @@ -0,0 +1,435 @@ +uuid: 25b89168-a8e5-4ae1-8fb5-c8efb91f0938 +langcode: en +status: true +dependencies: + module: + - entity_test_revlog +id: entity_test_mul_revlog_for_2248983 +label: entity_test_mul_revlog +module: views +description: '' +tag: '' +base_table: entity_test_mul_revlog_property_data +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + name: name + info: + name: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + name: + table: entity_test_mul_revlog_property_data + field: name + id: name + entity_type: entity_test_mul_revlog + entity_field: name + plugin_id: field + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + revision_created: + id: revision_created + table: entity_test_mul_revlog_property_data + field: revision_created + relationship: none + group_type: group + admin_label: '' + label: 'Revision create time' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_created + plugin_id: field + revision_id: + id: revision_id + table: entity_test_mul_revlog_property_data + field: revision_id + relationship: none + group_type: group + admin_label: '' + label: 'Revision ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_id + plugin_id: field + revision_log_message: + id: revision_log_message + table: entity_test_mul_revlog_property_data + field: revision_log_message + relationship: none + group_type: group + admin_label: '' + label: 'Revision log message' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: basic_string + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_log_message + plugin_id: field + revision_user: + id: revision_user + table: entity_test_mul_revlog_property_data + field: revision_user + relationship: none + group_type: group + admin_label: '' + label: 'Revision user' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: true + group_column: target_id + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_user + plugin_id: field + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + tags: { } diff --git a/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml b/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml new file mode 100644 index 00000000..412972c4 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml @@ -0,0 +1,436 @@ +uuid: 5a8b00d2-67ce-415b-9e7d-6c013bf7f6b8 +langcode: en +status: true +dependencies: + module: + - entity_test_revlog +id: entity_test_revlog_for_2248983 +label: entity_test_revlog +module: views +description: '' +tag: '' +base_table: entity_test_revlog +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + name: name + info: + name: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + name: + id: name + table: entity_test_revlog + field: name + relationship: none + group_type: group + admin_label: '' + label: Name + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: name + plugin_id: field + revision_created: + id: revision_created + table: entity_test_revlog + field: revision_created + relationship: none + group_type: group + admin_label: '' + label: 'Revision create time' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_created + plugin_id: field + revision_id: + id: revision_id + table: entity_test_revlog + field: revision_id + relationship: none + group_type: group + admin_label: '' + label: 'Revision ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_id + plugin_id: field + revision_log_message: + id: revision_log_message + table: entity_test_revlog + field: revision_log_message + relationship: none + group_type: group + admin_label: '' + label: 'Revision log message' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: basic_string + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_log_message + plugin_id: field + revision_user: + id: revision_user + table: entity_test_revlog + field: revision_user + relationship: none + group_type: group + admin_label: '' + label: 'Revision user' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: true + group_column: target_id + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_user + plugin_id: field + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + tags: { } diff --git a/core/modules/system/tests/modules/accept_header_routing_test/accept_header_routing_test.info.yml b/core/modules/system/tests/modules/accept_header_routing_test/accept_header_routing_test.info.yml index 9c2785b6..5340bdf4 100644 --- a/core/modules/system/tests/modules/accept_header_routing_test/accept_header_routing_test.info.yml +++ b/core/modules/system/tests/modules/accept_header_routing_test/accept_header_routing_test.info.yml @@ -4,8 +4,8 @@ type: module package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/accept_header_routing_test/src/Routing/AcceptHeaderMatcher.php b/core/modules/system/tests/modules/accept_header_routing_test/src/Routing/AcceptHeaderMatcher.php index 0981f46e..1a3c61ea 100644 --- a/core/modules/system/tests/modules/accept_header_routing_test/src/Routing/AcceptHeaderMatcher.php +++ b/core/modules/system/tests/modules/accept_header_routing_test/src/Routing/AcceptHeaderMatcher.php @@ -20,7 +20,7 @@ public function filter(RouteCollection $collection, Request $request) { // Generates a list of Symfony formats matching the acceptable MIME types. // @todo replace by proper content negotiation library. $acceptable_mime_types = $request->getAcceptableContentTypes(); - $acceptable_formats = array_filter(array_map(array($request, 'getFormat'), $acceptable_mime_types)); + $acceptable_formats = array_filter(array_map([$request, 'getFormat'], $acceptable_mime_types)); $primary_format = $request->getRequestFormat(); foreach ($collection as $name => $route) { diff --git a/core/modules/system/tests/modules/action_test/action_test.info.yml b/core/modules/system/tests/modules/action_test/action_test.info.yml index 85faaa14..aaad60f3 100644 --- a/core/modules/system/tests/modules/action_test/action_test.info.yml +++ b/core/modules/system/tests/modules/action_test/action_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.info.yml b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.info.yml index ba4b82a7..966db8af 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.info.yml +++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.info.yml @@ -5,8 +5,8 @@ description: 'Test for AJAX form calls.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module index ecde048b..262572be 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module +++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module @@ -89,7 +89,7 @@ function ajax_forms_test_advanced_commands_css_callback($form, FormStateInterfac $color = 'blue'; $response = new AjaxResponse(); - $response->addCommand(new CssCommand($selector, array('background-color' => $color))); + $response->addCommand(new CssCommand($selector, ['background-color' => $color])); return $response; } @@ -108,7 +108,7 @@ function ajax_forms_test_advanced_commands_data_callback($form, FormStateInterfa */ function ajax_forms_test_advanced_commands_invoke_callback($form, FormStateInterface $form_state) { $response = new AjaxResponse(); - $response->addCommand(new InvokeCommand('#invoke_div', 'addClass', array('error'))); + $response->addCommand(new InvokeCommand('#invoke_div', 'addClass', ['error'])); return $response; } @@ -181,7 +181,7 @@ function ajax_forms_test_advanced_commands_add_css_callback($form, FormStateInte */ function ajax_forms_test_validation_form_callback($form, FormStateInterface $form_state) { drupal_set_message("ajax_forms_test_validation_form_callback invoked"); - drupal_set_message(t("Callback: drivertext=%drivertext, spare_required_field=%spare_required_field", array('%drivertext' => $form_state->getValue('drivertext'), '%spare_required_field' => $form_state->getValue('spare_required_field')))); + drupal_set_message(t("Callback: drivertext=%drivertext, spare_required_field=%spare_required_field", ['%drivertext' => $form_state->getValue('drivertext'), '%spare_required_field' => $form_state->getValue('spare_required_field')])); return ['#markup' => '
    ajax_forms_test_validation_form_callback at ' . date('c') . '
    ']; } @@ -190,7 +190,7 @@ function ajax_forms_test_validation_form_callback($form, FormStateInterface $for */ function ajax_forms_test_validation_number_form_callback($form, FormStateInterface $form_state) { drupal_set_message("ajax_forms_test_validation_number_form_callback invoked"); - drupal_set_message(t("Callback: drivernumber=%drivernumber, spare_required_field=%spare_required_field", array('%drivernumber' => $form_state->getValue('drivernumber'), '%spare_required_field' => $form_state->getValue('spare_required_field')))); + drupal_set_message(t("Callback: drivernumber=%drivernumber, spare_required_field=%spare_required_field", ['%drivernumber' => $form_state->getValue('drivernumber'), '%spare_required_field' => $form_state->getValue('spare_required_field')])); return ['#markup' => '
    ajax_forms_test_validation_number_form_callback at ' . date('c') . '
    ']; } diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml index ccca279b..57801a3e 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml +++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.routing.yml @@ -30,3 +30,19 @@ ajax_forms_test.lazy_load_form: requirements: _access: 'TRUE' +ajax_forms_test.image_button_form: + path: '/ajax_forms_image_button_form' + defaults: + _title: 'AJAX forms image button test' + _form: '\Drupal\ajax_forms_test\Form\AjaxFormsTestImageButtonForm' + requirements: + _access: 'TRUE' + +ajax_forms_test.ajax_element_form: + path: '/ajax_forms_test_ajax_element_form' + defaults: + _title: 'AJAX forms elements test' + _form: '\Drupal\ajax_forms_test\Form\AjaxFormsTestAjaxElementsForm' + requirements: + _access: 'TRUE' + diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php b/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php index 4b3b0396..9b35ef76 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Callbacks.php @@ -15,27 +15,58 @@ class Callbacks { /** * Ajax callback triggered by select. */ - function selectCallback($form, FormStateInterface $form_state) { + public function selectCallback($form, FormStateInterface $form_state) { $response = new AjaxResponse(); $response->addCommand(new HtmlCommand('#ajax_selected_color', $form_state->getValue('select'))); $response->addCommand(new DataCommand('#ajax_selected_color', 'form_state_value_select', $form_state->getValue('select'))); return $response; } + /** + * Ajax callback triggered by date. + */ + public function dateCallback($form, FormStateInterface $form_state) { + $response = new AjaxResponse(); + $response->addCommand(new HtmlCommand('#ajax_date_value', $form_state->getValue('date'))); + $response->addCommand(new DataCommand('#ajax_date_value', 'form_state_value_date', $form_state->getValue('date'))); + return $response; + } + + /** + * Ajax callback triggered by datetime. + */ + public function datetimeCallback($form, FormStateInterface $form_state) { + $datetime = $form_state->getValue('datetime')['date'] . ' ' . $form_state->getValue('datetime')['time']; + + $response = new AjaxResponse(); + $response->addCommand(new HtmlCommand('#ajax_datetime_value', $datetime)); + $response->addCommand(new DataCommand('#ajax_datetime_value', 'form_state_value_datetime', $datetime)); + return $response; + } + /** * Ajax callback triggered by checkbox. */ - function checkboxCallback($form, FormStateInterface $form_state) { + public function checkboxCallback($form, FormStateInterface $form_state) { $response = new AjaxResponse(); $response->addCommand(new HtmlCommand('#ajax_checkbox_value', (int) $form_state->getValue('checkbox'))); $response->addCommand(new DataCommand('#ajax_checkbox_value', 'form_state_value_select', (int) $form_state->getValue('checkbox'))); return $response; } + /** + * Ajax callback to confirm image button was submitted. + */ + public function imageButtonCallback($form, FormStateInterface $form_state) { + $response = new AjaxResponse(); + $response->addCommand(new HtmlCommand('#ajax_image_button_result', "
    Something witty!
    ")); + return $response; + } + /** * Ajax callback triggered by the checkbox in a #group. */ - function checkboxGroupCallback($form, FormStateInterface $form_state) { + public function checkboxGroupCallback($form, FormStateInterface $form_state) { return $form['checkbox_in_group_wrapper']; } diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php new file mode 100644 index 00000000..0290f819 --- /dev/null +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestAjaxElementsForm.php @@ -0,0 +1,57 @@ + 'date', + '#ajax' => [ + 'callback' => [$callback_object, 'dateCallback'], + ], + '#suffix' => '
    No date yet selected
    ', + ]; + + $form['datetime'] = [ + '#type' => 'datetime', + '#ajax' => [ + 'callback' => [$callback_object, 'datetimeCallback'], + 'wrapper' => 'ajax_datetime_value', + ], + ]; + + $form['datetime_result'] = [ + '#type' => 'markup', + '#markup' => '
    No datetime selected.
    ', + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) {} + +} diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestCommandsForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestCommandsForm.php index d04b2170..e3c09af9 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestCommandsForm.php +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestCommandsForm.php @@ -21,178 +21,178 @@ public function getFormId() { * {@inheritdoc}. */ public function buildForm(array $form, FormStateInterface $form_state) { - $form = array(); + $form = []; // Shows the 'after' command with a callback generating commands. - $form['after_command_example'] = array( + $form['after_command_example'] = [ '#value' => $this->t("AJAX 'After': Click to put something after the div"), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_after_callback', - ), + ], '#suffix' => '
    Something can be inserted after this
    ', - ); + ]; // Shows the 'alert' command. - $form['alert_command_example'] = array( + $form['alert_command_example'] = [ '#value' => $this->t("AJAX 'Alert': Click to alert"), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_alert_callback', - ), - ); + ], + ]; // Shows the 'append' command. - $form['append_command_example'] = array( + $form['append_command_example'] = [ '#value' => $this->t("AJAX 'Append': Click to append something"), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_append_callback', - ), + ], '#suffix' => '
    Append inside this div
    ', - ); + ]; // Shows the 'before' command. - $form['before_command_example'] = array( + $form['before_command_example'] = [ '#value' => $this->t("AJAX 'before': Click to put something before the div"), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_before_callback', - ), + ], '#suffix' => '
    Insert something before this.
    ', - ); + ]; // Shows the 'changed' command without asterisk. - $form['changed_command_example'] = array( + $form['changed_command_example'] = [ '#value' => $this->t("AJAX changed: Click to mark div changed."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_changed_callback', - ), + ], '#suffix' => '
    This div can be marked as changed or not.
    ', - ); + ]; // Shows the 'changed' command adding the asterisk. - $form['changed_command_asterisk_example'] = array( + $form['changed_command_asterisk_example'] = [ '#value' => $this->t("AJAX changed: Click to mark div changed with asterisk."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_changed_asterisk_callback', - ), - ); + ], + ]; // Shows the Ajax 'css' command. - $form['css_command_example'] = array( + $form['css_command_example'] = [ '#value' => $this->t("Set the '#box' div to be blue."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_css_callback', - ), + ], '#suffix' => '
    box
    ', - ); + ]; // Shows the Ajax 'data' command. But there is no use of this information, // as this would require a javascript client to use the data. - $form['data_command_example'] = array( + $form['data_command_example'] = [ '#value' => $this->t("AJAX data command: Issue command."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_data_callback', - ), + ], '#suffix' => '
    Data attached to this div.
    ', - ); + ]; // Shows the Ajax 'invoke' command. - $form['invoke_command_example'] = array( + $form['invoke_command_example'] = [ '#value' => $this->t("AJAX invoke command: Invoke addClass() method."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_invoke_callback', - ), + ], '#suffix' => '
    Original contents
    ', - ); + ]; // Shows the Ajax 'html' command. - $form['html_command_example'] = array( + $form['html_command_example'] = [ '#value' => $this->t("AJAX html: Replace the HTML in a selector."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_html_callback', - ), + ], '#suffix' => '
    Original contents
    ', - ); + ]; // Shows the Ajax 'insert' command. - $form['insert_command_example'] = array( + $form['insert_command_example'] = [ '#value' => $this->t("AJAX insert: Let client insert based on #ajax['method']."), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_insert_callback', 'method' => 'prepend', - ), + ], '#suffix' => '
    Original contents
    ', - ); + ]; // Shows the Ajax 'prepend' command. - $form['prepend_command_example'] = array( + $form['prepend_command_example'] = [ '#value' => $this->t("AJAX 'prepend': Click to prepend something"), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_prepend_callback', - ), + ], '#suffix' => '
    Something will be prepended to this div.
    ', - ); + ]; // Shows the Ajax 'remove' command. - $form['remove_command_example'] = array( + $form['remove_command_example'] = [ '#value' => $this->t("AJAX 'remove': Click to remove text"), '#type' => 'submit', - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_remove_callback', - ), + ], '#suffix' => '
    text to be removed
    ', - ); + ]; // Shows the Ajax 'restripe' command. - $form['restripe_command_example'] = array( + $form['restripe_command_example'] = [ '#type' => 'submit', '#value' => $this->t("AJAX 'restripe' command"), - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_restripe_callback', - ), + ], '#suffix' => '
    first row
    second row
    ', - ); + ]; // Demonstrates the Ajax 'settings' command. The 'settings' command has // nothing visual to "show", but it can be tested via SimpleTest and via // Firebug. - $form['settings_command_example'] = array( + $form['settings_command_example'] = [ '#type' => 'submit', '#value' => $this->t("AJAX 'settings' command"), - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_settings_callback', - ), - ); + ], + ]; // Shows the Ajax 'add_css' command. - $form['add_css_command_example'] = array( + $form['add_css_command_example'] = [ '#type' => 'submit', '#value' => $this->t("AJAX 'add_css' command"), - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_advanced_commands_add_css_callback', - ), - ); + ], + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestImageButtonForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestImageButtonForm.php new file mode 100644 index 00000000..20754ffd --- /dev/null +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestImageButtonForm.php @@ -0,0 +1,48 @@ + 'image_button', + '#name' => 'image_button', + '#src' => 'core/misc/icons/787878/cog.svg', + '#attributes' => ['alt' => $this->t('Edit')], + '#op' => 'edit', + '#ajax' => [ + 'callback' => [$object, 'imageButtonCallback'], + ], + '#suffix' => '
    Image button not pressed yet.
    ', + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + // No submit code needed. + } + +} diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php index 19aaaf35..852cf443 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestLazyLoadForm.php @@ -26,20 +26,20 @@ public function buildForm(array $form, FormStateInterface $form_state) { // command to ensure that the 'currentPath' setting is not part // of the Ajax response. $form['#attached']['drupalSettings']['test'] = 'currentPathUpdate'; - $form['add_files'] = array( + $form['add_files'] = [ '#title' => $this->t('Add files'), '#type' => 'checkbox', '#default_value' => FALSE, - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), - '#ajax' => array( + '#ajax' => [ 'wrapper' => 'ajax-forms-test-lazy-load-ajax-wrapper', 'callback' => 'ajax_forms_test_lazy_load_form_ajax', - ), + ], '#prefix' => '
    ', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestSimpleForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestSimpleForm.php index 8ec5b71a..b8e9213e 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestSimpleForm.php +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestSimpleForm.php @@ -24,47 +24,48 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { $object = new Callbacks(); - $form = array(); - $form['select'] = array( + $form = []; + $form['select'] = [ '#title' => $this->t('Color'), '#type' => 'select', - '#options' => array( + '#options' => [ 'red' => 'red', 'green' => 'green', - 'blue' => 'blue'), - '#ajax' => array( - 'callback' => array($object, 'selectCallback'), - ), + 'blue' => 'blue', + ], + '#ajax' => [ + 'callback' => [$object, 'selectCallback'], + ], '#suffix' => '
    No color yet selected
    ', - ); + ]; - $form['checkbox'] = array( + $form['checkbox'] = [ '#type' => 'checkbox', '#title' => $this->t('Test checkbox'), - '#ajax' => array( - 'callback' => array($object, 'checkboxCallback'), - ), + '#ajax' => [ + 'callback' => [$object, 'checkboxCallback'], + ], '#suffix' => '
    No action yet
    ', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('submit'), - ); + ]; // This is for testing invalid callbacks that should return a 500 error in // \Drupal\Core\Form\FormAjaxResponseBuilderInterface::buildResponse(). - $invalid_callbacks = array( + $invalid_callbacks = [ 'null' => NULL, 'empty' => '', 'nonexistent' => 'some_function_that_does_not_exist', - ); + ]; foreach ($invalid_callbacks as $key => $value) { - $form['select_' . $key . '_callback'] = array( + $form['select_' . $key . '_callback'] = [ '#type' => 'select', - '#title' => $this->t('Test %key callbacks', array('%key' => $key)), - '#options' => array('red' => 'red'), - '#ajax' => array('callback' => $value), - ); + '#title' => $this->t('Test %key callbacks', ['%key' => $key]), + '#options' => ['red' => 'red'], + '#ajax' => ['callback' => $value], + ]; } $form['test_group'] = [ diff --git a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestValidationForm.php b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestValidationForm.php index dbf0b7fa..fb301949 100644 --- a/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestValidationForm.php +++ b/core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestValidationForm.php @@ -21,42 +21,42 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['drivertext'] = array( + $form['drivertext'] = [ '#title' => $this->t('AJAX-enabled textfield.'), '#description' => $this->t("When this one AJAX-triggers and the spare required field is empty, you should not get an error."), '#type' => 'textfield', '#default_value' => $form_state->getValue('drivertext', ''), - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_validation_form_callback', 'wrapper' => 'message_area', 'method' => 'replace', - ), + ], '#suffix' => '
    ', - ); + ]; - $form['drivernumber'] = array( + $form['drivernumber'] = [ '#title' => $this->t('AJAX-enabled number field.'), '#description' => $this->t("When this one AJAX-triggers and the spare required field is empty, you should not get an error."), '#type' => 'number', '#default_value' => $form_state->getValue('drivernumber', ''), - '#ajax' => array( + '#ajax' => [ 'callback' => 'ajax_forms_test_validation_number_form_callback', 'wrapper' => 'message_area_number', 'method' => 'replace', - ), + ], '#suffix' => '
    ', - ); + ]; - $form['spare_required_field'] = array( + $form['spare_required_field'] = [ '#title' => $this->t("Spare Required Field"), '#type' => 'textfield', '#required' => TRUE, - ); + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/ajax_test/ajax_test.info.yml b/core/modules/system/tests/modules/ajax_test/ajax_test.info.yml index 09e7e71d..772f9824 100644 --- a/core/modules/system/tests/modules/ajax_test/ajax_test.info.yml +++ b/core/modules/system/tests/modules/ajax_test/ajax_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - contact -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php index 63cc0abf..5ba65e80 100644 --- a/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php +++ b/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php @@ -22,22 +22,22 @@ class AjaxTestController { */ public static function dialogContents() { // This is a regular render array; the keys do not have special meaning. - $content = array( + $content = [ '#title' => 'AJAX Dialog & contents', - 'content' => array( + 'content' => [ '#markup' => 'Example message', - ), - 'cancel' => array( + ], + 'cancel' => [ '#type' => 'link', '#title' => 'Cancel', '#url' => Url::fromRoute(''), - '#attributes' => array( + '#attributes' => [ // This is a special class to which JavaScript assigns dialog closing // behavior. - 'class' => array('dialog-cancel'), - ), - ), - ); + 'class' => ['dialog-cancel'], + ], + ], + ]; return $content; } @@ -111,88 +111,88 @@ public function renderError(Request $request) { public function dialog() { // Add two wrapper elements for testing non-modal dialogs. Modal dialogs use // the global drupal-modal wrapper by default. - $build['dialog_wrappers'] = array('#markup' => '
    '); + $build['dialog_wrappers'] = ['#markup' => '
    ']; // Dialog behavior applied to a button. $build['form'] = \Drupal::formBuilder()->getForm('Drupal\ajax_test\Form\AjaxTestDialogForm'); // Dialog behavior applied to a #type => 'link'. - $build['link'] = array( + $build['link'] = [ '#type' => 'link', '#title' => 'Link 1 (modal)', '#url' => Url::fromRoute('ajax_test.dialog_contents'), - '#attributes' => array( - 'class' => array('use-ajax'), + '#attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'modal', - ), - ); + ], + ]; // Dialog behavior applied to links rendered by links.html.twig. - $build['links'] = array( + $build['links'] = [ '#theme' => 'links', - '#links' => array( - 'link2' => array( + '#links' => [ + 'link2' => [ 'title' => 'Link 2 (modal)', 'url' => Url::fromRoute('ajax_test.dialog_contents'), - 'attributes' => array( - 'class' => array('use-ajax'), + 'attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'modal', - 'data-dialog-options' => json_encode(array( + 'data-dialog-options' => json_encode([ 'width' => 400, - )) - ), - ), - 'link3' => array( + ]) + ], + ], + 'link3' => [ 'title' => 'Link 3 (non-modal)', 'url' => Url::fromRoute('ajax_test.dialog_contents'), - 'attributes' => array( - 'class' => array('use-ajax'), + 'attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'dialog', - 'data-dialog-options' => json_encode(array( + 'data-dialog-options' => json_encode([ 'target' => 'ajax-test-dialog-wrapper-1', 'width' => 800, - )) - ), - ), - 'link4' => array( + ]) + ], + ], + 'link4' => [ 'title' => 'Link 4 (close non-modal if open)', 'url' => Url::fromRoute('ajax_test.dialog_close'), - 'attributes' => array( - 'class' => array('use-ajax'), + 'attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'modal', - ), - ), - 'link5' => array( + ], + ], + 'link5' => [ 'title' => 'Link 5 (form)', 'url' => Url::fromRoute('ajax_test.dialog_form'), - 'attributes' => array( - 'class' => array('use-ajax'), + 'attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'modal', - ), - ), - 'link6' => array( + ], + ], + 'link6' => [ 'title' => 'Link 6 (entity form)', 'url' => Url::fromRoute('contact.form_add'), - 'attributes' => array( - 'class' => array('use-ajax'), + 'attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'modal', - 'data-dialog-options' => json_encode(array( + 'data-dialog-options' => json_encode([ 'width' => 800, 'height' => 500, - )) - ), - ), - 'link7' => array( + ]) + ], + ], + 'link7' => [ 'title' => 'Link 7 (non-modal, no target)', 'url' => Url::fromRoute('ajax_test.dialog_contents'), - 'attributes' => array( - 'class' => array('use-ajax'), + 'attributes' => [ + 'class' => ['use-ajax'], 'data-dialog-type' => 'dialog', - 'data-dialog-options' => json_encode(array( + 'data-dialog-options' => json_encode([ 'width' => 800, - )) - ), - ), + ]) + ], + ], 'link8' => [ 'title' => 'Link 8 (ajax)', 'url' => Url::fromRoute('ajax_test.admin.theme'), @@ -204,8 +204,8 @@ public function dialog() { ]), ], ], - ), - ); + ], + ]; return $build; } diff --git a/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php b/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php index a97ed952..5f11b6b7 100644 --- a/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php +++ b/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestDialogForm.php @@ -28,25 +28,25 @@ public function buildForm(array $form, FormStateInterface $form_state) { // In order to use WebTestBase::drupalPostAjaxForm() to POST from a link, we need // to have a dummy field we can set in WebTestBase::drupalPostForm() else it won't // submit anything. - $form['textfield'] = array( + $form['textfield'] = [ '#type' => 'hidden' - ); - $form['button1'] = array( + ]; + $form['button1'] = [ '#type' => 'submit', '#name' => 'button1', '#value' => 'Button 1 (modal)', - '#ajax' => array( + '#ajax' => [ 'callback' => '::modal', - ), - ); - $form['button2'] = array( + ], + ]; + $form['button2'] = [ '#type' => 'submit', '#name' => 'button2', '#value' => 'Button 2 (non-modal)', - '#ajax' => array( + '#ajax' => [ 'callback' => '::nonModal', - ), - ); + ], + ]; return $form; } diff --git a/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestForm.php b/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestForm.php index 60487699..ea431efa 100644 --- a/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestForm.php +++ b/core/modules/system/tests/modules/ajax_test/src/Form/AjaxTestForm.php @@ -24,23 +24,23 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['#action'] = \Drupal::url('ajax_test.dialog'); - $form['description'] = array( + $form['description'] = [ '#markup' => '

    ' . $this->t("Ajax Form contents description.") . '

    ', - ); + ]; - $form['actions'] = array( + $form['actions'] = [ '#type' => 'actions', - ); - $form['actions']['submit'] = array( + ]; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Do it'), - ); - $form['actions']['preview'] = array( + ]; + $form['actions']['preview'] = [ '#type' => 'submit', '#value' => $this->t('Preview'), // No regular submit-handler. This form only works via JavaScript. - '#submit' => array(), - '#ajax' => array( + '#submit' => [], + '#ajax' => [ // This means the ::preview() method on this class would be invoked in // case of a click event. However, since Drupal core's test runner only // is able to execute PHP, not JS, there is no point in actually @@ -51,8 +51,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { // we cannot meaningfully test it anyway. 'callback' => '::preview', 'event' => 'click', - ), - ); + ], + ]; return $form; } diff --git a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc b/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc index 4a271b08..9116c85f 100644 --- a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc +++ b/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc @@ -100,7 +100,7 @@ function _batch_test_finished_helper($batch_id, $success, $results, $operations) if (!$success) { // A fatal error occurred during the processing. $error_operation = reset($operations); - $messages[] = t('An error occurred while processing @op with arguments:
    @args', array('@op' => $error_operation[0], '@args' => print_r($error_operation[1], TRUE))); + $messages[] = t('An error occurred while processing @op with arguments:
    @args', ['@op' => $error_operation[0], '@args' => print_r($error_operation[1], TRUE)]); } // Use item list template to render the messages. diff --git a/core/modules/system/tests/modules/batch_test/batch_test.info.yml b/core/modules/system/tests/modules/batch_test/batch_test.info.yml index 2a9cc0e0..04e9745b 100644 --- a/core/modules/system/tests/modules/batch_test/batch_test.info.yml +++ b/core/modules/system/tests/modules/batch_test/batch_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module index e7a8de6e..59327de4 100644 --- a/core/modules/system/tests/modules/batch_test/batch_test.module +++ b/core/modules/system/tests/modules/batch_test/batch_test.module @@ -20,11 +20,11 @@ function _batch_test_nested_drupal_form_submit_callback($value) { * Batch 0: Does nothing. */ function _batch_test_batch_0() { - $batch = array( - 'operations' => array(), + $batch = [ + 'operations' => [], 'finished' => '_batch_test_finished_0', 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc', - ); + ]; return $batch; } @@ -38,15 +38,15 @@ function _batch_test_batch_1() { $total = 10; $sleep = (1000000 / $total) * 2; - $operations = array(); + $operations = []; for ($i = 1; $i <= $total; $i++) { - $operations[] = array('_batch_test_callback_1', array($i, $sleep)); + $operations[] = ['_batch_test_callback_1', [$i, $sleep]]; } - $batch = array( + $batch = [ 'operations' => $operations, 'finished' => '_batch_test_finished_1', 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc', - ); + ]; return $batch; } @@ -60,14 +60,14 @@ function _batch_test_batch_2() { $total = 10; $sleep = (1000000 / $total) * 2; - $operations = array( - array('_batch_test_callback_2', array(1, $total, $sleep)), - ); - $batch = array( + $operations = [ + ['_batch_test_callback_2', [1, $total, $sleep]], + ]; + $batch = [ 'operations' => $operations, 'finished' => '_batch_test_finished_2', 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc', - ); + ]; return $batch; } @@ -85,20 +85,20 @@ function _batch_test_batch_3() { $total = 10; $sleep = (1000000 / $total) * 2; - $operations = array(); + $operations = []; for ($i = 1; $i <= round($total / 2); $i++) { - $operations[] = array('_batch_test_callback_1', array($i, $sleep)); + $operations[] = ['_batch_test_callback_1', [$i, $sleep]]; } - $operations[] = array('_batch_test_callback_2', array(1, $total / 2, $sleep)); + $operations[] = ['_batch_test_callback_2', [1, $total / 2, $sleep]]; for ($i = round($total / 2) + 1; $i <= $total; $i++) { - $operations[] = array('_batch_test_callback_1', array($i, $sleep)); + $operations[] = ['_batch_test_callback_1', [$i, $sleep]]; } - $operations[] = array('_batch_test_callback_2', array(6, $total / 2, $sleep)); - $batch = array( + $operations[] = ['_batch_test_callback_2', [6, $total / 2, $sleep]]; + $batch = [ 'operations' => $operations, 'finished' => '_batch_test_finished_3', 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc', - ); + ]; return $batch; } @@ -115,19 +115,19 @@ function _batch_test_batch_4() { $total = 10; $sleep = (1000000 / $total) * 2; - $operations = array(); + $operations = []; for ($i = 1; $i <= round($total / 2); $i++) { - $operations[] = array('_batch_test_callback_1', array($i, $sleep)); + $operations[] = ['_batch_test_callback_1', [$i, $sleep]]; } - $operations[] = array('_batch_test_nested_batch_callback', array()); + $operations[] = ['_batch_test_nested_batch_callback', []]; for ($i = round($total / 2) + 1; $i <= $total; $i++) { - $operations[] = array('_batch_test_callback_1', array($i, $sleep)); + $operations[] = ['_batch_test_callback_1', [$i, $sleep]]; } - $batch = array( + $batch = [ 'operations' => $operations, 'finished' => '_batch_test_finished_4', 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc', - ); + ]; return $batch; } @@ -141,15 +141,15 @@ function _batch_test_batch_5() { $total = 10; $sleep = (1000000 / $total) * 2; - $operations = array(); + $operations = []; for ($i = 1; $i <= $total; $i++) { - $operations[] = array('_batch_test_callback_5', array($i, $sleep)); + $operations[] = ['_batch_test_callback_5', [$i, $sleep]]; } - $batch = array( + $batch = [ 'operations' => $operations, 'finished' => '_batch_test_finished_5', 'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc', - ); + ]; return $batch; } diff --git a/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php b/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php index 811c7fc3..1d34f8a4 100644 --- a/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php +++ b/core/modules/system/tests/modules/batch_test/src/Controller/BatchTestController.php @@ -16,11 +16,11 @@ class BatchTestController { * Render array containing success message. */ public function testRedirect() { - return array( - 'success' => array( + return [ + 'success' => [ '#markup' => 'Redirection successful.', - ) - ); + ] + ]; } /** @@ -47,9 +47,9 @@ public function testLargePercentage() { */ public function testNestedDrupalFormSubmit($value = 1) { // Set the batch and process it. - $batch['operations'] = array( - array('_batch_test_nested_drupal_form_submit_callback', array($value)), - ); + $batch['operations'] = [ + ['_batch_test_nested_drupal_form_submit_callback', [$value]], + ]; batch_set($batch); return batch_process('batch-test/redirect'); } @@ -95,16 +95,16 @@ public function testFinishRedirect() { * @return array * Render array containing markup. */ - function testProgrammatic($value = 1) { + public function testProgrammatic($value = 1) { $form_state = (new FormState())->setValues([ 'value' => $value, ]); \Drupal::formBuilder()->submitForm('Drupal\batch_test\Form\BatchTestChainedForm', $form_state); - return array( - 'success' => array( + return [ + 'success' => [ '#markup' => 'Got out of a programmatic batched form.', - ) - ); + ] + ]; } /** @@ -115,11 +115,11 @@ function testProgrammatic($value = 1) { */ public function testThemeBatch() { batch_test_stack(NULL, TRUE); - $batch = array( - 'operations' => array( - array('_batch_test_theme_callback', array()), - ), - ); + $batch = [ + 'operations' => [ + ['_batch_test_theme_callback', []], + ], + ]; batch_set($batch); return batch_process('batch-test/redirect'); } diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php index aa19ad3f..fe2d02c5 100644 --- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php +++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestChainedForm.php @@ -23,21 +23,21 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { // This value is used to test that $form_state persists through batched // submit handlers. - $form['value'] = array( + $form['value'] = [ '#type' => 'textfield', '#title' => 'Value', '#default_value' => 1, - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); - $form['#submit'] = array( + ]; + $form['#submit'] = [ 'Drupal\batch_test\Form\BatchTestChainedForm::batchTestChainedFormSubmit1', 'Drupal\batch_test\Form\BatchTestChainedForm::batchTestChainedFormSubmit2', 'Drupal\batch_test\Form\BatchTestChainedForm::batchTestChainedFormSubmit3', 'Drupal\batch_test\Form\BatchTestChainedForm::batchTestChainedFormSubmit4', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMockForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMockForm.php index ec8caff0..2d26bcf4 100644 --- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMockForm.php +++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMockForm.php @@ -21,14 +21,14 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['test_value'] = array( + $form['test_value'] = [ '#title' => t('Test value'), '#type' => 'textfield', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php index 260941f5..916831e9 100644 --- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php +++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestMultiStepForm.php @@ -27,13 +27,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form_state->set('step', $step); } - $form['step_display'] = array( + $form['step_display'] = [ '#markup' => 'step ' . $step . '
    ', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; // This is a POST form with multiple steps that does not transition from one // step to the next via POST requests, but via GET requests, because it uses diff --git a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php index 92cf6b11..999649df 100644 --- a/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php +++ b/core/modules/system/tests/modules/batch_test/src/Form/BatchTestSimpleForm.php @@ -21,21 +21,21 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['batch'] = array( + $form['batch'] = [ '#type' => 'select', '#title' => 'Choose batch', - '#options' => array( + '#options' => [ 'batch_0' => 'batch 0', 'batch_1' => 'batch 1', 'batch_2' => 'batch 2', 'batch_3' => 'batch 3', 'batch_4' => 'batch 4', - ), - ); - $form['submit'] = array( + ], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/cache_test/cache_test.info.yml b/core/modules/system/tests/modules/cache_test/cache_test.info.yml index 48ac4c1d..3d5f411d 100644 --- a/core/modules/system/tests/modules/cache_test/cache_test.info.yml +++ b/core/modules/system/tests/modules/cache_test/cache_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/common_test/common_test.info.yml b/core/modules/system/tests/modules/common_test/common_test.info.yml index e0d37ab2..41190f31 100644 --- a/core/modules/system/tests/modules/common_test/common_test.info.yml +++ b/core/modules/system/tests/modules/common_test/common_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/common_test/common_test.module b/core/modules/system/tests/modules/common_test/common_test.module index 0633ac88..040e40a4 100644 --- a/core/modules/system/tests/modules/common_test/common_test.module +++ b/core/modules/system/tests/modules/common_test/common_test.module @@ -5,7 +5,7 @@ * Helper module for the Common tests. */ -use \Drupal\Core\Asset\AttachedAssetsInterface; +use Drupal\Core\Asset\AttachedAssetsInterface; /** * Applies #printed to an element to help test #pre_render. @@ -114,18 +114,18 @@ function common_test_module_implements_alter(&$implementations, $hook) { * Implements hook_theme(). */ function common_test_theme() { - return array( - 'common_test_foo' => array( - 'variables' => array('foo' => 'foo', 'bar' => 'bar'), - ), - 'common_test_render_element' => array( + return [ + 'common_test_foo' => [ + 'variables' => ['foo' => 'foo', 'bar' => 'bar'], + ], + 'common_test_render_element' => [ 'render element' => 'foo', - ), - 'common_test_empty' => array( - 'variables' => array('foo' => 'foo'), + ], + 'common_test_empty' => [ + 'variables' => ['foo' => 'foo'], 'function' => 'theme_common_test_empty', - ), - ); + ], + ]; } /** diff --git a/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php index f77a5813..bb98a59c 100644 --- a/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php +++ b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php @@ -18,40 +18,40 @@ class CommonTestController { * generator. */ public function typeLinkActiveClass() { - return array( - 'no_query' => array( + return [ + 'no_query' => [ '#type' => 'link', '#title' => t('Link with no query string'), '#url' => Url::fromRoute(''), - '#options' => array( + '#options' => [ 'set_active_class' => TRUE, - ), - ), - 'with_query' => array( + ], + ], + 'with_query' => [ '#type' => 'link', '#title' => t('Link with a query string'), '#url' => Url::fromRoute(''), - '#options' => array( - 'query' => array( + '#options' => [ + 'query' => [ 'foo' => 'bar', 'one' => 'two', - ), + ], 'set_active_class' => TRUE, - ), - ), - 'with_query_reversed' => array( + ], + ], + 'with_query_reversed' => [ '#type' => 'link', '#title' => t('Link with the same query string in reverse order'), '#url' => Url::fromRoute(''), - '#options' => array( - 'query' => array( + '#options' => [ + 'query' => [ 'one' => 'two', 'foo' => 'bar', - ), + ], 'set_active_class' => TRUE, - ), - ), - ); + ], + ], + ]; } /** @@ -61,18 +61,18 @@ public function typeLinkActiveClass() { * An empty string. */ public function jsAndCssQuerystring() { - $attached = array( - '#attached' => array( - 'library' => array( + $attached = [ + '#attached' => [ + 'library' => [ 'node/drupal.node', - ), - 'css' => array( - drupal_get_path('module', 'node') . '/css/node.admin.css' => array(), + ], + 'css' => [ + drupal_get_path('module', 'node') . '/css/node.admin.css' => [], // A relative URI may have a query string. - '/' . drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&arg2=value2' => array(), - ), - ), - ); + '/' . drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&arg2=value2' => [], + ], + ], + ]; return \Drupal::service('renderer')->renderRoot($attached); } diff --git a/core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.info.yml b/core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.info.yml index 063f1363..ade20aae 100644 --- a/core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.info.yml +++ b/core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/condition_test/condition_test.info.yml b/core/modules/system/tests/modules/condition_test/condition_test.info.yml index bb3a1adb..879718d2 100644 --- a/core/modules/system/tests/modules/condition_test/condition_test.info.yml +++ b/core/modules/system/tests/modules/condition_test/condition_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/condition_test/src/FormController.php b/core/modules/system/tests/modules/condition_test/src/FormController.php index 38b21cca..da475ae0 100644 --- a/core/modules/system/tests/modules/condition_test/src/FormController.php +++ b/core/modules/system/tests/modules/condition_test/src/FormController.php @@ -39,10 +39,10 @@ public function __construct() { */ public function buildForm(array $form, FormStateInterface $form_state) { $form = $this->condition->buildConfigurationForm($form, $form_state); - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/conneg_test/conneg_test.info.yml b/core/modules/system/tests/modules/conneg_test/conneg_test.info.yml index bc5b2692..ded4024d 100644 --- a/core/modules/system/tests/modules/conneg_test/conneg_test.info.yml +++ b/core/modules/system/tests/modules/conneg_test/conneg_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml b/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml index a7b58e17..2ab2f8c6 100644 --- a/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml +++ b/core/modules/system/tests/modules/cron_queue_test/cron_queue_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/csrf_test/csrf_test.info.yml b/core/modules/system/tests/modules/csrf_test/csrf_test.info.yml index 007d3f23..0e79b83c 100644 --- a/core/modules/system/tests/modules/csrf_test/csrf_test.info.yml +++ b/core/modules/system/tests/modules/csrf_test/csrf_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/database_test/database_test.info.yml b/core/modules/system/tests/modules/database_test/database_test.info.yml index 70a26195..1c097661 100644 --- a/core/modules/system/tests/modules/database_test/database_test.info.yml +++ b/core/modules/system/tests/modules/database_test/database_test.info.yml @@ -5,8 +5,8 @@ description: 'Support module for Database layer tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/database_test/database_test.install b/core/modules/system/tests/modules/database_test/database_test.install index f6b4f68d..b4e3ca56 100644 --- a/core/modules/system/tests/modules/database_test/database_test.install +++ b/core/modules/system/tests/modules/database_test/database_test.install @@ -14,281 +14,282 @@ * like any other, not directly in the test file. */ function database_test_schema() { - $schema['test'] = array( + $schema['test'] = [ 'description' => 'Basic test table for the database unit tests.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ), - 'name' => array( + ], + 'name' => [ 'description' => "A person's name", 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', 'binary' => TRUE, - ), - 'age' => array( + ], + 'age' => [ 'description' => "The person's age", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'job' => array( + ], + 'job' => [ 'description' => "The person's job", 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'Undefined', - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'name' => array('name') - ), - 'indexes' => array( - 'ages' => array('age'), - ), - ); + ], + ], + 'primary key' => ['id'], + 'unique keys' => [ + 'name' => ['name'] + ], + 'indexes' => [ + 'ages' => ['age'], + ], + ]; // This is an alternate version of the same table that is structured the same // but has a non-serial Primary Key. - $schema['test_people'] = array( + $schema['test_people'] = [ 'description' => 'A duplicate version of the test table, used for additional tests.', - 'fields' => array( - 'name' => array( + 'fields' => [ + 'name' => [ 'description' => "A person's name", 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'age' => array( + ], + 'age' => [ 'description' => "The person's age", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'job' => array( + ], + 'job' => [ 'description' => "The person's job", 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - ), - 'primary key' => array('job'), - 'indexes' => array( - 'ages' => array('age'), - ), - ); + ], + ], + 'primary key' => ['job'], + 'indexes' => [ + 'ages' => ['age'], + ], + ]; - $schema['test_people_copy'] = array( + $schema['test_people_copy'] = [ 'description' => 'A duplicate version of the test_people table, used for additional tests.', - 'fields' => array( - 'name' => array( + 'fields' => [ + 'name' => [ 'description' => "A person's name", 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'age' => array( + ], + 'age' => [ 'description' => "The person's age", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'job' => array( + ], + 'job' => [ 'description' => "The person's job", 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - ), - 'primary key' => array('job'), - 'indexes' => array( - 'ages' => array('age'), - ), - ); + ], + ], + 'primary key' => ['job'], + 'indexes' => [ + 'ages' => ['age'], + ], + ]; - $schema['test_one_blob'] = array( + $schema['test_one_blob'] = [ 'description' => 'A simple table including a BLOB field for testing BLOB behavior.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'description' => 'Simple unique ID.', 'type' => 'serial', 'not null' => TRUE, - ), - 'blob1' => array( + ], + 'blob1' => [ 'description' => 'A BLOB field.', 'type' => 'blob', - ), - ), - 'primary key' => array('id'), - ); + ], + ], + 'primary key' => ['id'], + ]; - $schema['test_two_blobs'] = array( + $schema['test_two_blobs'] = [ 'description' => 'A simple test table with two BLOB fields.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'description' => 'Simple unique ID.', 'type' => 'serial', 'not null' => TRUE, - ), - 'blob1' => array( + ], + 'blob1' => [ 'description' => 'A dummy BLOB field.', 'type' => 'blob', - ), - 'blob2' => array( + ], + 'blob2' => [ 'description' => 'A second BLOB field.', 'type' => 'blob' - ), - ), - 'primary key' => array('id'), - ); + ], + ], + 'primary key' => ['id'], + ]; - $schema['test_task'] = array( + $schema['test_task'] = [ 'description' => 'A task list for people in the test table.', - 'fields' => array( - 'tid' => array( + 'fields' => [ + 'tid' => [ 'description' => 'Task ID, primary key.', 'type' => 'serial', 'not null' => TRUE, - ), - 'pid' => array( + ], + 'pid' => [ 'description' => 'The {test_people}.pid, foreign key for the test table.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'task' => array( + ], + 'task' => [ 'description' => 'The task to be completed.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'priority' => array( + ], + 'priority' => [ 'description' => 'The priority of the task.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - ), - 'primary key' => array('tid'), - ); + ], + ], + 'primary key' => ['tid'], + ]; - $schema['test_null'] = array( + $schema['test_null'] = [ 'description' => 'Basic test table for NULL value handling.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ), - 'name' => array( + ], + 'name' => [ 'description' => "A person's name.", 'type' => 'varchar_ascii', 'length' => 255, 'not null' => FALSE, 'default' => '', - ), - 'age' => array( + ], + 'age' => [ 'description' => "The person's age.", 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - 'default' => 0), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'name' => array('name') - ), - 'indexes' => array( - 'ages' => array('age'), - ), - ); + 'default' => 0, + ], + ], + 'primary key' => ['id'], + 'unique keys' => [ + 'name' => ['name'] + ], + 'indexes' => [ + 'ages' => ['age'], + ], + ]; - $schema['test_serialized'] = array( + $schema['test_serialized'] = [ 'description' => 'Basic test table for NULL value handling.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - ), - 'name' => array( + ], + 'name' => [ 'description' => "A person's name.", 'type' => 'varchar_ascii', 'length' => 255, 'not null' => FALSE, 'default' => '', - ), - 'info' => array( + ], + 'info' => [ 'description' => "The person's data in serialized form.", 'type' => 'blob', 'serialize' => TRUE, - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'name' => array('name') - ), - ); + ], + ], + 'primary key' => ['id'], + 'unique keys' => [ + 'name' => ['name'] + ], + ]; - $schema['test_composite_primary'] = array( + $schema['test_composite_primary'] = [ 'description' => 'Basic test table with a composite primary key', - 'fields' => array( - 'name' => array( + 'fields' => [ + 'name' => [ 'description' => "A person's name", 'type' => 'varchar', 'length' => 50, 'not null' => TRUE, 'default' => '', 'binary' => TRUE, - ), - 'age' => array( + ], + 'age' => [ 'description' => "The person's age", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'job' => array( + ], + 'job' => [ 'description' => "The person's job", 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'Undefined', - ), - ), - 'primary key' => array('name', 'age'), - ); + ], + ], + 'primary key' => ['name', 'age'], + ]; - $schema['test_special_columns'] = array( + $schema['test_special_columns'] = [ 'description' => 'A simple test table with special column names.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'description' => 'Simple unique ID.', 'type' => 'int', 'not null' => TRUE, - ), - 'offset' => array( + ], + 'offset' => [ 'description' => 'A column with preserved name.', 'type' => 'text', - ), - ), - 'primary key' => array('id'), - ); + ], + ], + 'primary key' => ['id'], + ]; $schema['TEST_UPPERCASE'] = $schema['test']; diff --git a/core/modules/system/tests/modules/database_test/src/Controller/DatabaseTestController.php b/core/modules/system/tests/modules/database_test/src/Controller/DatabaseTestController.php index 7de24d49..56ea9d14 100644 --- a/core/modules/system/tests/modules/database_test/src/Controller/DatabaseTestController.php +++ b/core/modules/system/tests/modules/database_test/src/Controller/DatabaseTestController.php @@ -19,11 +19,11 @@ class DatabaseTestController { * @return \Symfony\Component\HttpFoundation\JsonResponse */ public function dbQueryTemporary() { - $table_name = db_query_temporary('SELECT age FROM {test}', array()); - return new JsonResponse(array( + $table_name = db_query_temporary('SELECT age FROM {test}', []); + return new JsonResponse([ 'table_name' => $table_name, 'row_count' => db_select($table_name)->countQuery()->execute()->fetchField(), - )); + ]); } /** @@ -37,7 +37,7 @@ public function dbQueryTemporary() { public function pagerQueryEven($limit) { $query = db_select('test', 't'); $query - ->fields('t', array('name')) + ->fields('t', ['name']) ->orderBy('age'); // This should result in 2 pages of results. @@ -47,9 +47,9 @@ public function pagerQueryEven($limit) { $names = $query->execute()->fetchCol(); - return new JsonResponse(array( + return new JsonResponse([ 'names' => $names, - )); + ]); } /** @@ -63,7 +63,7 @@ public function pagerQueryEven($limit) { public function pagerQueryOdd($limit) { $query = db_select('test_task', 't'); $query - ->fields('t', array('task')) + ->fields('t', ['task']) ->orderBy('pid'); // This should result in 4 pages of results. @@ -73,9 +73,9 @@ public function pagerQueryOdd($limit) { $names = $query->execute()->fetchCol(); - return new JsonResponse(array( + return new JsonResponse([ 'names' => $names, - )); + ]); } /** @@ -87,16 +87,16 @@ public function pagerQueryOdd($limit) { * @return \Symfony\Component\HttpFoundation\JsonResponse */ public function testTablesort() { - $header = array( - 'tid' => array('data' => t('Task ID'), 'field' => 'tid', 'sort' => 'desc'), - 'pid' => array('data' => t('Person ID'), 'field' => 'pid'), - 'task' => array('data' => t('Task'), 'field' => 'task'), - 'priority' => array('data' => t('Priority'), 'field' => 'priority', ), - ); + $header = [ + 'tid' => ['data' => t('Task ID'), 'field' => 'tid', 'sort' => 'desc'], + 'pid' => ['data' => t('Person ID'), 'field' => 'pid'], + 'task' => ['data' => t('Task'), 'field' => 'task'], + 'priority' => ['data' => t('Priority'), 'field' => 'priority'], + ]; $query = db_select('test_task', 't'); $query - ->fields('t', array('tid', 'pid', 'task', 'priority')); + ->fields('t', ['tid', 'pid', 'task', 'priority']); $query = $query ->extend('Drupal\Core\Database\Query\TableSortExtender') @@ -105,9 +105,9 @@ public function testTablesort() { // We need all the results at once to check the sort. $tasks = $query->execute()->fetchAll(); - return new JsonResponse(array( + return new JsonResponse([ 'tasks' => $tasks, - )); + ]); } /** @@ -119,16 +119,16 @@ public function testTablesort() { * @return \Symfony\Component\HttpFoundation\JsonResponse */ public function testTablesortFirst() { - $header = array( - 'tid' => array('data' => t('Task ID'), 'field' => 'tid', 'sort' => 'desc'), - 'pid' => array('data' => t('Person ID'), 'field' => 'pid'), - 'task' => array('data' => t('Task'), 'field' => 'task'), - 'priority' => array('data' => t('Priority'), 'field' => 'priority', ), - ); + $header = [ + 'tid' => ['data' => t('Task ID'), 'field' => 'tid', 'sort' => 'desc'], + 'pid' => ['data' => t('Person ID'), 'field' => 'pid'], + 'task' => ['data' => t('Task'), 'field' => 'task'], + 'priority' => ['data' => t('Priority'), 'field' => 'priority'], + ]; $query = db_select('test_task', 't'); $query - ->fields('t', array('tid', 'pid', 'task', 'priority')); + ->fields('t', ['tid', 'pid', 'task', 'priority']); $query = $query ->extend('Drupal\Core\Database\Query\TableSortExtender') @@ -138,9 +138,9 @@ public function testTablesortFirst() { // We need all the results at once to check the sort. $tasks = $query->execute()->fetchAll(); - return new JsonResponse(array( + return new JsonResponse([ 'tasks' => $tasks, - )); + ]); } } diff --git a/core/modules/system/tests/modules/database_test/src/Form/DatabaseTestForm.php b/core/modules/system/tests/modules/database_test/src/Form/DatabaseTestForm.php index 96125548..12eebcca 100644 --- a/core/modules/system/tests/modules/database_test/src/Form/DatabaseTestForm.php +++ b/core/modules/system/tests/modules/database_test/src/Form/DatabaseTestForm.php @@ -22,10 +22,10 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $header = array( - 'username' => array('data' => t('Username'), 'field' => 'u.name'), - 'status' => array('data' => t('Status'), 'field' => 'u.status'), - ); + $header = [ + 'username' => ['data' => t('Username'), 'field' => 'u.name'], + 'status' => ['data' => t('Status'), 'field' => 'u.status'], + ]; $query = db_select('users_field_data', 'u'); $query->condition('u.uid', 0, '<>'); @@ -38,7 +38,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { ->extend('Drupal\Core\Database\Query\PagerSelectExtender') ->extend('Drupal\Core\Database\Query\TableSortExtender'); $query - ->fields('u', array('uid')) + ->fields('u', ['uid']) ->limit(50) ->orderByHeader($header) ->setCountQuery($count_query); @@ -46,22 +46,22 @@ public function buildForm(array $form, FormStateInterface $form_state) { ->execute() ->fetchCol(); - $options = array(); + $options = []; foreach (User::loadMultiple($uids) as $account) { - $options[$account->id()] = array( - 'title' => array('data' => array('#title' => $account->getUsername())), + $options[$account->id()] = [ + 'title' => ['data' => ['#title' => $account->getUsername()]], 'username' => $account->getUsername(), 'status' => $account->isActive() ? t('active') : t('blocked'), - ); + ]; } - $form['accounts'] = array( + $form['accounts'] = [ '#type' => 'tableselect', '#header' => $header, '#options' => $options, '#empty' => t('No people available.'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/deprecation_test/deprecation_test.info.yml b/core/modules/system/tests/modules/deprecation_test/deprecation_test.info.yml new file mode 100644 index 00000000..a72bd24e --- /dev/null +++ b/core/modules/system/tests/modules/deprecation_test/deprecation_test.info.yml @@ -0,0 +1,12 @@ +name: 'Deprecation test' +type: module +description: 'Support module for testing deprecation behaviors.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/deprecation_test/src/Deprecation/FixtureDeprecatedClass.php b/core/modules/system/tests/modules/deprecation_test/src/Deprecation/FixtureDeprecatedClass.php new file mode 100644 index 00000000..65aea782 --- /dev/null +++ b/core/modules/system/tests/modules/deprecation_test/src/Deprecation/FixtureDeprecatedClass.php @@ -0,0 +1,28 @@ + 'markup', + '#markup' => 'Look at me in a modal!', + ]; + } + + /** + * Displays test links that will open in the modal dialog. + * + * @return array + * Render array with links. + */ + public function linksDisplay() { + return [ + 'normal_modal' => [ + '#title' => 'Normal Modal!', + '#type' => 'link', + '#url' => Url::fromRoute('dialog_renderer_test.modal_content'), + '#attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + ], + '#attached' => [ + 'library' => [ + 'core/drupal.ajax', + ], + ], + ], + 'wide_modal' => [ + '#title' => 'Wide Modal!', + '#type' => 'link', + '#url' => Url::fromRoute('dialog_renderer_test.modal_content'), + '#attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + 'data-dialog-renderer' => 'wide', + ], + '#attached' => [ + 'library' => [ + 'core/drupal.ajax', + ], + ], + ], + 'extra_wide_modal' => [ + '#title' => 'Extra Wide Modal!', + '#type' => 'link', + '#url' => Url::fromRoute('dialog_renderer_test.modal_content'), + '#attributes' => [ + 'class' => ['use-ajax'], + 'data-dialog-type' => 'modal', + 'data-dialog-renderer' => 'extra_wide', + ], + '#attached' => [ + 'library' => [ + 'core/drupal.ajax', + ], + ], + ], + ]; + } + +} diff --git a/core/modules/system/tests/modules/dialog_renderer_test/src/Render/MainContent/WideModalRenderer.php b/core/modules/system/tests/modules/dialog_renderer_test/src/Render/MainContent/WideModalRenderer.php new file mode 100644 index 00000000..3ca7715e --- /dev/null +++ b/core/modules/system/tests/modules/dialog_renderer_test/src/Render/MainContent/WideModalRenderer.php @@ -0,0 +1,78 @@ +mode = $mode; + } + + + /** + * {@inheritdoc} + */ + public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) { + $response = new AjaxResponse(); + + // First render the main content, because it might provide a title. + $content = drupal_render_root($main_content); + + // Attach the library necessary for using the OpenModalDialogCommand and set + // the attachments for this Ajax response. + $main_content['#attached']['library'][] = 'core/drupal.dialog.ajax'; + $response->setAttachments($main_content['#attached']); + + // If the main content doesn't provide a title, use the title resolver. + $title = isset($main_content['#title']) ? $main_content['#title'] : $this->titleResolver->getTitle($request, $route_match->getRouteObject()); + + // Determine the title: use the title provided by the main content if any, + // otherwise get it from the routing information. + $options = $request->request->get('dialogOptions', []); + // Override width option. + switch ($this->mode) { + case 'wide': + $options['width'] = 700; + break; + + case 'extra_wide': + $options['width'] = 1000; + break; + } + + + $response->addCommand(new OpenModalDialogCommand($title, $content, $options)); + return $response; + } + +} diff --git a/core/modules/system/tests/modules/display_variant_test/display_variant_test.info.yml b/core/modules/system/tests/modules/display_variant_test/display_variant_test.info.yml index d7424b74..d490c848 100644 --- a/core/modules/system/tests/modules/display_variant_test/display_variant_test.info.yml +++ b/core/modules/system/tests/modules/display_variant_test/display_variant_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/display_variant_test/src/EventSubscriber/TestPageDisplayVariantSubscriber.php b/core/modules/system/tests/modules/display_variant_test/src/EventSubscriber/TestPageDisplayVariantSubscriber.php index 3768bcdf..e24266e0 100644 --- a/core/modules/system/tests/modules/display_variant_test/src/EventSubscriber/TestPageDisplayVariantSubscriber.php +++ b/core/modules/system/tests/modules/display_variant_test/src/EventSubscriber/TestPageDisplayVariantSubscriber.php @@ -31,8 +31,8 @@ public function onSelectPageDisplayVariant(PageDisplayVariantSelectionEvent $eve /** * {@inheritdoc} */ - static function getSubscribedEvents() { - $events[RenderEvents::SELECT_PAGE_DISPLAY_VARIANT][] = array('onSelectPageDisplayVariant'); + public static function getSubscribedEvents() { + $events[RenderEvents::SELECT_PAGE_DISPLAY_VARIANT][] = ['onSelectPageDisplayVariant']; return $events; } diff --git a/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml b/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml index 658dbff4..92b70e67 100644 --- a/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml +++ b/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/early_rendering_controller_test/early_rendering_controller_test.info.yml b/core/modules/system/tests/modules/early_rendering_controller_test/early_rendering_controller_test.info.yml index 30b06c8a..1afcc5f1 100644 --- a/core/modules/system/tests/modules/early_rendering_controller_test/early_rendering_controller_test.info.yml +++ b/core/modules/system/tests/modules/early_rendering_controller_test/early_rendering_controller_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/early_rendering_controller_test/src/EarlyRenderingTestController.php b/core/modules/system/tests/modules/early_rendering_controller_test/src/EarlyRenderingTestController.php index 0b0cdf43..9ba11b77 100644 --- a/core/modules/system/tests/modules/early_rendering_controller_test/src/EarlyRenderingTestController.php +++ b/core/modules/system/tests/modules/early_rendering_controller_test/src/EarlyRenderingTestController.php @@ -62,7 +62,8 @@ public function renderArray() { '#pre_render' => [function () { $elements = $this->earlyRenderContent(); return $elements; - }], + } + ], ]; } diff --git a/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObject.php b/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObject.php index b24f71f6..27756d05 100644 --- a/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObject.php +++ b/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObject.php @@ -2,4 +2,4 @@ namespace Drupal\early_rendering_controller_test; -class TestDomainObject { } +class TestDomainObject {} diff --git a/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObjectViewSubscriber.php b/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObjectViewSubscriber.php index 6dac62f6..e6152ca6 100644 --- a/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObjectViewSubscriber.php +++ b/core/modules/system/tests/modules/early_rendering_controller_test/src/TestDomainObjectViewSubscriber.php @@ -37,7 +37,7 @@ public function onViewTestDomainObject(GetResponseForControllerResultEvent $even /** * {@inheritdoc} */ - static function getSubscribedEvents() { + public static function getSubscribedEvents() { $events[KernelEvents::VIEW][] = ['onViewTestDomainObject']; return $events; diff --git a/core/modules/system/tests/modules/entity_crud_hook_test/entity_crud_hook_test.info.yml b/core/modules/system/tests/modules/entity_crud_hook_test/entity_crud_hook_test.info.yml index 91c4d35c..7a15d29d 100644 --- a/core/modules/system/tests/modules/entity_crud_hook_test/entity_crud_hook_test.info.yml +++ b/core/modules/system/tests/modules/entity_crud_hook_test/entity_crud_hook_test.info.yml @@ -5,8 +5,8 @@ description: 'Support module for CRUD hook tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.info.yml b/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.info.yml index 0c157710..8b4f31d5 100644 --- a/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.info.yml +++ b/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.info.yml @@ -10,8 +10,8 @@ dependencies: - views - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.module b/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.module index 51b506b5..5ae4fcbb 100644 --- a/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.module +++ b/core/modules/system/tests/modules/entity_reference_test/entity_reference_test.module @@ -12,7 +12,7 @@ use Drupal\Core\Field\BaseFieldDefinition; * Implements hook_entity_base_field_info(). */ function entity_reference_test_entity_base_field_info(EntityTypeInterface $entity_type) { - $fields = array(); + $fields = []; if ($entity_type->id() === 'entity_test') { $fields['user_role'] = BaseFieldDefinition::create('entity_reference') @@ -33,10 +33,10 @@ function entity_reference_test_entity_base_field_info_alter(&$fields, EntityType // Allow user_id field to use configurable widget. $fields['user_id'] ->setSetting('handler', 'default') - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 0, - )) + ]) ->setDisplayConfigurable('form', TRUE); } } diff --git a/core/modules/system/tests/modules/entity_reference_test_views/entity_reference_test_views.info.yml b/core/modules/system/tests/modules/entity_reference_test_views/entity_reference_test_views.info.yml index 7aa2dde2..66c28aeb 100644 --- a/core/modules/system/tests/modules/entity_reference_test_views/entity_reference_test_views.info.yml +++ b/core/modules/system/tests/modules/entity_reference_test_views/entity_reference_test_views.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_group_by_empty_relationships.yml b/core/modules/system/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_group_by_empty_relationships.yml new file mode 100644 index 00000000..5c935241 --- /dev/null +++ b/core/modules/system/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_group_by_empty_relationships.yml @@ -0,0 +1,128 @@ +langcode: en +status: true +dependencies: { } +id: test_entity_reference_group_by_empty_relationships +label: '' +module: views +description: '' +tag: '' +base_table: entity_test +base_field: id +core: '8' +display: + default: + display_options: + access: + type: none + cache: + type: tag + exposed_form: + type: basic + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + fields: + name_1: + id: name_1 + table: entity_test + field: name + entity_type: entity_test + entity_field: name + plugin_id: field + relationship: none + group_type: group + group_column: value + group_columns: { } + group_rows: true + exclude: false + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + name_2: + id: name_2 + table: entity_test_mul_property_data + field: name + entity_type: entity_test_mul + entity_field: name + plugin_id: field + relationship: reverse__entity_test_mul__field_data_test_unlimited + group_type: group + group_column: entity_id + group_columns: { } + group_rows: false + exclude: false + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + sorts: + name: + table: entity_test + field: name + id: name + entity_type: entity_test + entity_field: field_test + order: ASC + plugin_id: standard + pager: + type: some + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + name_1: name_1 + name_2: name_2 + info: + name_1: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + name_2: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + relationships: + reverse__entity_test_mul__field_data_test_unlimited: + id: reverse__entity_test_mul__field_data_test_unlimited + table: entity_test + field: reverse__entity_test_mul__field_data_test_unlimited + entity_type: entity_test + plugin_id: entity_reverse + group_type: group + required: false + group_by: true + display_plugin: block + display_title: Master + id: default + position: 0 diff --git a/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.info.yml b/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.info.yml index 74c982d3..0f2d0d13 100644 --- a/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.info.yml +++ b/core/modules/system/tests/modules/entity_schema_test/entity_schema_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml b/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml index 464a007a..d34d9494 100644 --- a/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml +++ b/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml @@ -27,19 +27,3 @@ entity_test.entity_test_bundle.*: description: type: text label: 'Description' - -entity_test.entity_test_bundle.*.third_party.content_moderation: - type: mapping - label: 'Enable moderation states for this entity test type' - mapping: - enabled: - type: boolean - label: 'Moderation states enabled' - allowed_moderation_states: - type: sequence - sequence: - type: string - label: 'Moderation state' - default_moderation_state: - type: string - label: 'Moderation state for new entity test' diff --git a/core/modules/system/tests/modules/entity_test/entity_test.info.yml b/core/modules/system/tests/modules/entity_test/entity_test.info.yml index 7dc05440..06893206 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.info.yml +++ b/core/modules/system/tests/modules/entity_test/entity_test.info.yml @@ -8,8 +8,8 @@ dependencies: - field - text -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install index 5e3bcaa2..c796c9ad 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.install +++ b/core/modules/system/tests/modules/entity_test/entity_test.install @@ -15,12 +15,12 @@ use Drupal\field\Entity\FieldConfig; function entity_test_install() { foreach (entity_test_entity_types() as $entity_type) { // Auto-create fields for testing. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'entity_type' => $entity_type, 'field_name' => 'field_test_text', 'type' => 'text', 'cardinality' => 1, - ))->save(); + ])->save(); FieldConfig::create([ 'entity_type' => $entity_type, 'field_name' => 'field_test_text', @@ -30,7 +30,7 @@ function entity_test_install() { ])->save(); entity_get_form_display($entity_type, $entity_type, 'default') - ->setComponent('field_test_text', array('type' => 'text_textfield')) + ->setComponent('field_test_text', ['type' => 'text_textfield']) ->save(); } } @@ -40,17 +40,17 @@ function entity_test_install() { */ function entity_test_schema() { // Schema for simple entity. - $schema['entity_test_example'] = array( + $schema['entity_test_example'] = [ 'description' => 'Stores entity_test items.', - 'fields' => array( - 'id' => array( + 'fields' => [ + 'id' => [ 'type' => 'serial', 'not null' => TRUE, 'description' => 'Primary Key: Unique entity-test item ID.', - ), - ), - 'primary key' => array('id'), - ); + ], + ], + 'primary key' => ['id'], + ]; return $schema; } diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module index f8f56ebb..bcf55f48 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.module +++ b/core/modules/system/tests/modules/entity_test/entity_test.module @@ -6,6 +6,8 @@ */ use Drupal\Core\Access\AccessResult; +use Drupal\Core\Database\Query\AlterableInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Entity\EntityTypeInterface; @@ -53,7 +55,7 @@ const ENTITY_TEST_TYPES_ROUTING = 3; * List with entity_types. */ function entity_test_entity_types($filter = NULL) { - $types = array(); + $types = []; if ($filter === NULL || $filter === ENTITY_TEST_TYPES_ROUTING) { $types[] = 'entity_test'; } @@ -92,11 +94,8 @@ function entity_test_entity_type_alter(array &$entity_types) { } } - // Allow entity_test_update tests to override the entity type definition. - $entity_types['entity_test_update'] = $state->get('entity_test_update.entity_type', $entity_types['entity_test_update']); - - // Allow entity_test_with_bundle tests to override the entity type definition. - $entity_types['entity_test_with_bundle'] = $state->get('entity_test_with_bundle.entity_type', $entity_types['entity_test_with_bundle']); + // Allow entity_test_rev tests to override the entity type definition. + $entity_types['entity_test_rev'] = $state->get('entity_test_rev.entity_type', $entity_types['entity_test_rev']); // Enable the entity_test_new only when needed. if (!$state->get('entity_test_new')) { @@ -104,17 +103,6 @@ function entity_test_entity_type_alter(array &$entity_types) { } } -/** - * Implements hook_module_implements_alter(). - */ -function entity_test_module_implements_alter(&$implementations, $hook) { - // Move our hook_entity_type_alter() implementation to the beginning of the - // list in order to run before content_moderation_entity_type_alter(). - if ($hook === 'entity_type_alter') { - $implementations = ['entity_test' => $implementations['entity_test']] + $implementations; - } -} - /** * Implements hook_entity_base_field_info(). */ @@ -162,15 +150,6 @@ function entity_test_entity_base_field_info_alter(&$fields, EntityTypeInterface } } -/** - * Implements hook_entity_field_storage_info(). - */ -function entity_test_entity_field_storage_info(EntityTypeInterface $entity_type) { - if ($entity_type->id() == 'entity_test_update') { - return \Drupal::state()->get('entity_test_update.additional_field_storage_definitions', array()); - } -} - /** * Creates a new bundle for entity_test entities. * @@ -184,8 +163,8 @@ function entity_test_entity_field_storage_info(EntityTypeInterface $entity_type) * 'entity_test'. */ function entity_test_create_bundle($bundle, $text = NULL, $entity_type = 'entity_test') { - $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: array($entity_type => array('label' => 'Entity Test Bundle')); - $bundles += array($bundle => array('label' => $text ? $text : $bundle)); + $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: [$entity_type => ['label' => 'Entity Test Bundle']]; + $bundles += [$bundle => ['label' => $text ? $text : $bundle]]; \Drupal::state()->set($entity_type . '.bundles', $bundles); \Drupal::entityManager()->onBundleCreate($bundle, $entity_type); @@ -201,7 +180,7 @@ function entity_test_create_bundle($bundle, $text = NULL, $entity_type = 'entity * 'entity_test'. */ function entity_test_delete_bundle($bundle, $entity_type = 'entity_test') { - $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: array($entity_type => array('label' => 'Entity Test Bundle')); + $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: [$entity_type => ['label' => 'Entity Test Bundle']]; unset($bundles[$bundle]); \Drupal::state()->set($entity_type . '.bundles', $bundles); @@ -212,11 +191,11 @@ function entity_test_delete_bundle($bundle, $entity_type = 'entity_test') { * Implements hook_entity_bundle_info(). */ function entity_test_entity_bundle_info() { - $bundles = array(); + $bundles = []; $entity_types = \Drupal::entityManager()->getDefinitions(); foreach ($entity_types as $entity_type_id => $entity_type) { if ($entity_type->getProvider() == 'entity_test' && $entity_type_id != 'entity_test_with_bundle') { - $bundles[$entity_type_id] = \Drupal::state()->get($entity_type_id . '.bundles') ?: array($entity_type_id => array('label' => 'Entity Test Bundle')); + $bundles[$entity_type_id] = \Drupal::state()->get($entity_type_id . '.bundles') ?: [$entity_type_id => ['label' => 'Entity Test Bundle']]; } } return $bundles; @@ -229,18 +208,18 @@ function entity_test_entity_view_mode_info_alter(&$view_modes) { $entity_info = \Drupal::entityManager()->getDefinitions(); foreach ($entity_info as $entity_type => $info) { if ($entity_info[$entity_type]->getProvider() == 'entity_test' && !isset($view_modes[$entity_type])) { - $view_modes[$entity_type] = array( - 'full' => array( + $view_modes[$entity_type] = [ + 'full' => [ 'label' => t('Full object'), 'status' => TRUE, 'cache' => TRUE, - ), - 'teaser' => array( + ], + 'teaser' => [ 'label' => t('Teaser'), 'status' => TRUE, 'cache' => TRUE, - ), - ); + ], + ]; } } } @@ -252,12 +231,12 @@ function entity_test_entity_form_mode_info_alter(&$form_modes) { $entity_info = \Drupal::entityManager()->getDefinitions(); foreach ($entity_info as $entity_type => $info) { if ($entity_info[$entity_type]->getProvider() == 'entity_test') { - $form_modes[$entity_type] = array( - 'compact' => array( + $form_modes[$entity_type] = [ + 'compact' => [ 'label' => t('Compact version'), 'status' => TRUE, - ), - ); + ], + ]; } } } @@ -266,24 +245,24 @@ function entity_test_entity_form_mode_info_alter(&$form_modes) { * Implements hook_entity_extra_field_info(). */ function entity_test_entity_extra_field_info() { - $extra['entity_test']['bundle_with_extra_fields'] = array( - 'display' => array( + $extra['entity_test']['bundle_with_extra_fields'] = [ + 'display' => [ // Note: those extra fields do not currently display anything, they are // just used in \Drupal\Tests\field_ui\Kernel\EntityDisplayTest to test // the behavior of entity display objects. - 'display_extra_field' => array( + 'display_extra_field' => [ 'label' => t('Display extra field'), 'description' => t('An extra field on the display side.'), 'weight' => 5, 'visible' => TRUE, - ), - 'display_extra_field_hidden' => array( + ], + 'display_extra_field_hidden' => [ 'label' => t('Display extra field (hidden)'), 'description' => t('An extra field on the display side, hidden by default.'), 'visible' => FALSE, - ), - ) - ); + ], + ] + ]; return $extra; } @@ -412,6 +391,25 @@ function entity_test_entity_test_insert($entity) { } } +/** + * Implements hook_entity_insert(). + */ +function entity_test_entity_insert(EntityInterface $entity) { + if ($entity->getEntityTypeId() == 'entity_test_mulrev' && $entity->label() == 'EntityLoadedRevisionTest') { + $entity->setNewRevision(FALSE); + $entity->save(); + } +} + +/** + * Implements hook_entity_update(). + */ +function entity_test_entity_update(EntityInterface $entity) { + if ($entity instanceof ContentEntityInterface) { + \Drupal::state()->set('entity_test.loadedRevisionId', $entity->getLoadedRevisionId()); + } +} + /** * Implements hook_entity_field_access(). * @@ -656,16 +654,16 @@ function entity_test_field_default_value(FieldableEntityInterface $entity, Field // that they are correctly passed. $string = $definition->getName() . '_' . $entity->language()->getId(); // Return a "default value" with multiple items. - return array( - array( + return [ + [ 'shape' => "shape:0:$string", 'color' => "color:0:$string", - ), - array( + ], + [ 'shape' => "shape:1:$string", 'color' => "color:1:$string", - ), - ); + ], + ]; } /** @@ -695,7 +693,7 @@ function entity_test_entity_prepare_view($entity_type, array $entities, array $d // Add a dummy field item attribute on field_test_text if it exists. if ($entity->hasField('field_test_text') && $displays[$entity->bundle()]->getComponent('field_test_text')) { foreach ($entity->get('field_test_text') as $item) { - $item->_attributes += array('data-field-item-attr' => 'foobar'); + $item->_attributes += ['data-field-item-attr' => 'foobar']; } } @@ -704,7 +702,7 @@ function entity_test_entity_prepare_view($entity_type, array $entities, array $d foreach ($fields as $field) { if ($field->getType() === 'daterange') { $item = $entity->get($field->getName()); - $item->_attributes += array('data-field-item-attr' => 'foobar'); + $item->_attributes += ['data-field-item-attr' => 'foobar']; } } } @@ -739,6 +737,16 @@ function entity_test_entity_access(EntityInterface $entity, $operation, AccountI return AccessResult::allowed(); } + // Create specific labels to allow or deny access based on certain test + // conditions. + // @see \Drupal\KernelTests\Core\Entity\EntityAccessControlHandlerTest + if ($entity->label() == 'Accessible') { + return AccessResult::allowed(); + } + if ($entity->label() == 'Inaccessible') { + return AccessResult::forbidden(); + } + // Uncacheable because the access result depends on a State key-value pair and // might therefore change at any time. $condition = \Drupal::state()->get("entity_test_entity_access.{$operation}." . $entity->id(), FALSE); @@ -775,3 +783,17 @@ function entity_test_entity_test_create_access(AccountInterface $account, $conte // No opinion. return AccessResult::neutral(); } + +/** + * Implements hook_query_entity_test_access_alter(). + */ +function entity_test_query_entity_test_access_alter(AlterableInterface $query) { + if (!\Drupal::state()->get('entity_test_query_access')) { + return; + } + + /** @var \Drupal\Core\Database\Query\Select|\Drupal\Core\Database\Query\AlterableInterface $query */ + if (!\Drupal::currentUser()->hasPermission('view all entity_test_query_access entities')) { + $query->condition('entity_test_query_access.name', 'published entity'); + } +} diff --git a/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml b/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml index ca04459a..abfb616f 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml +++ b/core/modules/system/tests/modules/entity_test/entity_test.permissions.yml @@ -12,6 +12,8 @@ administer entity_test_with_bundle content: description: 'administer entity_test_with_bundle content' administer entity_test_bundle content: title: 'administer entity_test_bundle content' +view all entity_test_query_access entities: + title: 'view all entity_test_query_access entities' permission_callbacks: - \Drupal\entity_test\EntityTestPermissions::entityTestBundlePermissions diff --git a/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php b/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php index a753eabd..a6934884 100644 --- a/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php +++ b/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php @@ -4,40 +4,12 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Controller\ControllerBase; -use Drupal\Core\Entity\Query\QueryFactory; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Controller routines for entity_test routes. */ class EntityTestController extends ControllerBase { - /** - * The entity query factory. - * - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $entityQueryFactory; - - /** - * Constructs a new EntityTestController. - * - * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory - * The entity query factory. - */ - public function __construct(QueryFactory $entity_query_factory) { - $this->entityQueryFactory = $entity_query_factory; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.query') - ); - } - /** * Returns an empty page. * @@ -66,11 +38,10 @@ public function listReferencingEntities($entity_reference_field_name, $reference ->getStorage($referenced_entity_type) ->load($referenced_entity_id); if ($referenced_entity === NULL) { - return array(); + return []; } - $query = $this->entityQueryFactory - ->get('entity_test') + $query = $this->entityTypeManager()->getStorage('entity_test')->getQuery() ->condition($entity_reference_field_name . '.target_id', $referenced_entity_id); $entities = $this->entityManager() ->getStorage('entity_test') @@ -91,7 +62,7 @@ public function listReferencingEntities($entity_reference_field_name, $reference */ public function listEntitiesAlphabetically($entity_type_id) { $entity_type_definition = $this->entityManager()->getDefinition($entity_type_id); - $query = $this->entityQueryFactory->get($entity_type_id); + $query = $this->entityTypeManager()->getStorage($entity_type_id)->getQuery(); // Sort by label field, if any. if ($label_field = $entity_type_definition->getKey('label')) { diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php index a603f537..9f8c5b05 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php @@ -48,6 +48,9 @@ * }, * field_ui_base_route = "entity.entity_test.admin_form", * ) + * + * Note that this entity type annotation intentionally omits the "create" link + * template. See https://www.drupal.org/node/2293697. */ class EntityTest extends ContentEntityBase implements EntityOwnerInterface { @@ -72,15 +75,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The name of the test entity.')) ->setTranslatable(TRUE) ->setSetting('max_length', 32) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'string', 'weight' => -5, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -5, - )); + ]); $fields['created'] = BaseFieldDefinition::create('created') ->setLabel(t('Authored on')) @@ -94,17 +97,17 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setSetting('handler', 'default') // Default EntityTest entities to have the root user as the owner, to // simplify testing. - ->setDefaultValue(array(0 => array('target_id' => 1))) + ->setDefaultValue([0 => ['target_id' => 1]]) ->setTranslatable(TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => -1, - 'settings' => array( + 'settings' => [ 'match_operator' => 'CONTAINS', 'size' => '60', 'placeholder' => '', - ), - )); + ], + ]); return $fields; } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php index f7fe8e64..7fe9ce21 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestBaseFieldDisplay.php @@ -53,39 +53,39 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['test_display_configurable'] = BaseFieldDefinition::create('text') ->setLabel(t('Field with configurable display')) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'type' => 'text_default', 'weight' => 10, - )) + ]) ->setDisplayConfigurable('view', TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'text_textfield', 'weight' => 10, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['test_display_non_configurable'] = BaseFieldDefinition::create('text') ->setLabel(t('Field with non-configurable display')) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'type' => 'text_default', 'weight' => 11, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'text_textfield', 'weight' => 11, - )); + ]); $fields['test_display_multiple'] = BaseFieldDefinition::create('text') ->setLabel(t('A field with multiple values')) ->setCardinality(FieldStorageDefinition::CARDINALITY_UNLIMITED) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'type' => 'text_default', 'weight' => 12, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'text_textfield', 'weight' => 12, - )); + ]); return $fields; } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestCompositeConstraint.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestCompositeConstraint.php index a8158b00..3ace1465 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestCompositeConstraint.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestCompositeConstraint.php @@ -1,6 +1,7 @@ setDisplayOptions('form', array( + $fields['name']->setDisplayOptions('form', [ 'type' => 'string', 'weight' => 0, - )); + ]); - $fields['type']->setDisplayOptions('form', array( + $fields['type']->setDisplayOptions('form', [ 'type' => 'entity_reference_autocomplete', 'weight' => 0, - )); + ]); return $fields; } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php new file mode 100644 index 00000000..c873ccc0 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php @@ -0,0 +1,45 @@ +setLabel('Computed Field Test') + ->setComputed(TRUE) + ->setClass(ComputedTestFieldItemList::class); + + return $fields; + } + +} diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php index 448718dc..e12c74a0 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php @@ -33,11 +33,11 @@ class EntityTestConstraintViolation extends EntityTest { public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields = parent::baseFieldDefinitions($entity_type); - $fields['name']->setDisplayOptions('form', array( + $fields['name']->setDisplayOptions('form', [ 'type' => 'string', 'weight' => 0, - )); - $fields['name']->addConstraint('FieldWidgetConstraint', array()); + ]); + $fields['name']->addConstraint('FieldWidgetConstraint', []); return $fields; } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulChanged.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulChanged.php index 5fbc408d..dd3da09d 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulChanged.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulChanged.php @@ -60,6 +60,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The time that the entity was last edited.')) ->setTranslatable(TRUE); + $fields['not_translatable'] = BaseFieldDefinition::create('string') + ->setLabel(t('Non translatable')) + ->setDescription(t('A non-translatable string field')); + return $fields; } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php index 0ee28bf0..f01675f6 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php @@ -27,6 +27,7 @@ * revision_data_table = "entity_test_mulrev_property_revision", * admin_permission = "administer entity_test content", * translatable = TRUE, + * show_revision_ui = TRUE, * entity_keys = { * "id" = "id", * "uuid" = "uuid", diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRevChangedWithRevisionLog.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRevChangedWithRevisionLog.php new file mode 100644 index 00000000..a22954bd --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRevChangedWithRevisionLog.php @@ -0,0 +1,46 @@ +setLabel(t('Revision ID')) - ->setDescription(t('The version id of the test entity.')) - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE); - - $fields['langcode']->setRevisionable(TRUE); $fields['name']->setRevisionable(TRUE); $fields['user_id']->setRevisionable(TRUE); diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php index 342cbb9b..85a5e667 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestStringId.php @@ -1,6 +1,7 @@ get('entity_test_update.additional_base_field_definitions', array()); - return $fields; - } - - /** - * {@inheritdoc} - */ - public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { - $fields = parent::bundleFieldDefinitions($entity_type, $bundle, $base_field_definitions); - $fields += \Drupal::state()->get('entity_test_update.additional_bundle_field_definitions.' . $bundle, array()); - return $fields; - } - -} diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php index c668bd3e..e6cb5428 100644 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php @@ -41,6 +41,7 @@ * "add-form" = "/entity_test_with_bundle/add/{entity_test_bundle}", * "edit-form" = "/entity_test_with_bundle/{entity_test_with_bundle}/edit", * "delete-form" = "/entity_test_with_bundle/{entity_test_with_bundle}/delete", + * "create" = "/entity_test_with_bundle", * }, * ) */ diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php deleted file mode 100644 index 4f4f4f1f..00000000 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php +++ /dev/null @@ -1,48 +0,0 @@ -isDefaultTranslation()) { return AccessResult::allowedIfHasPermission($account, 'view test entity translations'); } return AccessResult::allowedIfHasPermission($account, 'view test entity'); } - elseif (in_array($operation, array('update', 'delete'))) { + elseif (in_array($operation, ['update', 'delete'])) { return AccessResult::allowedIfHasPermission($account, 'administer entity_test content'); } diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestDefinitionSubscriber.php b/core/modules/system/tests/modules/entity_test/src/EntityTestDefinitionSubscriber.php index a31762e4..2b06d80b 100644 --- a/core/modules/system/tests/modules/entity_test/src/EntityTestDefinitionSubscriber.php +++ b/core/modules/system/tests/modules/entity_test/src/EntityTestDefinitionSubscriber.php @@ -38,7 +38,7 @@ class EntityTestDefinitionSubscriber implements EventSubscriberInterface, Entity /** * {@inheritdoc} */ - function __construct(StateInterface $state) { + public function __construct(StateInterface $state) { $this->state = $state; } diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php index 7e4caff4..e4c51143 100644 --- a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php +++ b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php @@ -32,11 +32,11 @@ public function form(array $form, FormStateInterface $form_state) { // @todo: Is there a better way to check if an entity type is revisionable? if ($entity->getEntityType()->hasKey('revision') && !$entity->isNew()) { - $form['revision'] = array( + $form['revision'] = [ '#type' => 'checkbox', '#title' => t('Create new revision'), '#default_value' => $entity->isNewRevision(), - ); + ]; } return $form; @@ -58,10 +58,10 @@ public function save(array $form, FormStateInterface $form_state) { $entity->save(); if ($is_new) { - $message = t('%entity_type @id has been created.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId())); + $message = t('%entity_type @id has been created.', ['@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId()]); } else { - $message = t('%entity_type @id has been updated.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId())); + $message = t('%entity_type @id has been updated.', ['@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId()]); } drupal_set_message($message); @@ -69,7 +69,7 @@ public function save(array $form, FormStateInterface $form_state) { $entity_type = $entity->getEntityTypeId(); $form_state->setRedirect( "entity.$entity_type.edit_form", - array($entity_type => $entity->id()) + [$entity_type => $entity->id()] ); } else { diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestStorageSchema.php b/core/modules/system/tests/modules/entity_test/src/EntityTestStorageSchema.php deleted file mode 100644 index 67a13bdd..00000000 --- a/core/modules/system/tests/modules/entity_test/src/EntityTestStorageSchema.php +++ /dev/null @@ -1,39 +0,0 @@ -id() == 'entity_test_update') { - $schema[$entity_type->getBaseTable()]['indexes'] += \Drupal::state()->get('entity_test_update.additional_entity_indexes', array()); - } - return $schema; - } - - /** - * {@inheritdoc} - */ - protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $storage_definition, $table_name, array $column_mapping) { - $schema = parent::getSharedTableFieldSchema($storage_definition, $table_name, $column_mapping); - - if (\Drupal::state()->get('entity_test_update.additional_field_index.' . $table_name . '.' . $storage_definition->getName())) { - $this->addSharedTableFieldIndex($storage_definition, $schema); - } - - return $schema; - } - -} diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php index 720e3c3b..e90a2270 100644 --- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php +++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php @@ -18,18 +18,18 @@ public function buildComponents(array &$build, array $entities, array $displays, parent::buildComponents($build, $entities, $displays, $view_mode); foreach ($entities as $id => $entity) { - $build[$id]['label'] = array( + $build[$id]['label'] = [ '#weight' => -100, '#plain_text' => $entity->label(), - ); - $build[$id]['separator'] = array( + ]; + $build[$id]['separator'] = [ '#weight' => -150, '#markup' => ' | ', - ); - $build[$id]['view_mode'] = array( + ]; + $build[$id]['view_mode'] = [ '#weight' => -200, '#plain_text' => $view_mode, - ); + ]; } } diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php index 3bb0d24c..27a1186a 100644 --- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php +++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php @@ -16,6 +16,17 @@ class EntityTestViewsData extends EntityViewsData { public function getViewsData() { $views_data = parent::getViewsData(); + if ($this->entityType->id() === 'entity_test_computed_field') { + $views_data['entity_test_computed_field']['computed_string_field'] = [ + 'title' => $this->t('Computed String Field'), + 'field' => [ + 'id' => 'field', + 'default_formatter' => 'string', + 'field_name' => 'computed_string_field', + ], + ]; + } + if ($this->entityType->id() != 'entity_test') { return $views_data; } diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php index 059c3a9f..ed3f1dc4 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Derivative/EntityTestLocalTasks.php @@ -13,16 +13,16 @@ class EntityTestLocalTasks extends DeriverBase { * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - $this->derivatives = array(); + $this->derivatives = []; $types = entity_test_entity_types(ENTITY_TEST_TYPES_ROUTING); foreach ($types as $entity_type) { - $this->derivatives[$entity_type . '.canonical'] = array(); + $this->derivatives[$entity_type . '.canonical'] = []; $this->derivatives[$entity_type . '.canonical']['base_route'] = "entity.$entity_type.canonical"; $this->derivatives[$entity_type . '.canonical']['route_name'] = "entity.$entity_type.canonical"; $this->derivatives[$entity_type . '.canonical']['title'] = 'View'; - $this->derivatives[$entity_type . '.edit'] = array(); + $this->derivatives[$entity_type . '.edit'] = []; $this->derivatives[$entity_type . '.edit']['base_route'] = "entity.$entity_type.canonical"; $this->derivatives[$entity_type . '.edit']['route_name'] = "entity.$entity_type.edit_form"; $this->derivatives[$entity_type . '.edit']['title'] = 'Edit'; diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php new file mode 100644 index 00000000..864d33fe --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php @@ -0,0 +1,37 @@ +get('entity_test_computed_field_item_list_value', []) as $delta => $item) { + $this->list[$delta] = $this->createItem($delta, $item); + } + } + + /** + * {@inheritdoc} + */ + public function get($index) { + $this->computedListProperty(); + return isset($this->list[$index]) ? $this->list[$index] : NULL; + } + + /** + * {@inheritdoc} + */ + public function getIterator() { + $this->computedListProperty(); + return parent::getIterator(); + } + +} diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldFormatter/EntityTestReferenceCustomCacheTagFormatter.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldFormatter/EntityTestReferenceCustomCacheTagFormatter.php new file mode 100644 index 00000000..76fb12fa --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldFormatter/EntityTestReferenceCustomCacheTagFormatter.php @@ -0,0 +1,28 @@ + ['tags' => ['custom_cache_tag']]]; + } + +} diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ChangedTestItem.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ChangedTestItem.php index 1425588f..0e0a46c1 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ChangedTestItem.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ChangedTestItem.php @@ -31,7 +31,14 @@ public function preSave() { // During a test the request time is immutable. To allow tests of the // algorithm of // Drupal\Core\Field\Plugin\Field\FieldType\ChangedItem::preSave() we need - // to set a real time value here. + // to set a real time value here. For the stability of the test, set the + // time of the original language to the current time plus just over one + // second to simulate two different request times. + // @todo mock the time service in https://www.drupal.org/node/2908210. + if ($this->getEntity()->language()->isDefault()) { + // Wait 1.1 seconds because time_sleep_until() is not reliable. + time_sleep_until(time() + 1.1); + } $this->value = time(); } } diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/FieldTestItem.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/FieldTestItem.php index 2310ffdd..b7336c15 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/FieldTestItem.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/FieldTestItem.php @@ -9,7 +9,6 @@ use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; - /** * Defines the 'field_test' entity field type. * @@ -46,14 +45,14 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'varchar', 'length' => 255, - ), - ), - ); + ], + ], + ]; } /** diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php index 0d2ebb9d..4921dcf4 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php @@ -21,9 +21,9 @@ class ShapeItem extends FieldItemBase { * {@inheritdoc} */ public static function defaultStorageSettings() { - return array( + return [ 'foreign_key_name' => 'shape', - ) + parent::defaultStorageSettings(); + ] + parent::defaultStorageSettings(); } /** @@ -43,30 +43,30 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - $foreign_keys = array(); + $foreign_keys = []; // The 'foreign keys' key is not always used in tests. if ($field_definition->getSetting('foreign_key_name')) { - $foreign_keys['foreign keys'] = array( + $foreign_keys['foreign keys'] = [ // This is a dummy foreign key definition, references a table that // doesn't exist, but that's not a problem. - $field_definition->getSetting('foreign_key_name') => array( + $field_definition->getSetting('foreign_key_name') => [ 'table' => $field_definition->getSetting('foreign_key_name'), - 'columns' => array($field_definition->getSetting('foreign_key_name') => 'id'), - ), - ); + 'columns' => [$field_definition->getSetting('foreign_key_name') => 'id'], + ], + ]; } - return array( - 'columns' => array( - 'shape' => array( + return [ + 'columns' => [ + 'shape' => [ 'type' => 'varchar', 'length' => 32, - ), - 'color' => array( + ], + 'color' => [ 'type' => 'varchar', 'length' => 32, - ), - ), - ) + $foreign_keys; + ], + ], + ] + $foreign_keys; } /** diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldWidget/ShapeOnlyColorEditableWidget.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldWidget/ShapeOnlyColorEditableWidget.php index bcff1ec3..ae5dd303 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldWidget/ShapeOnlyColorEditableWidget.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldWidget/ShapeOnlyColorEditableWidget.php @@ -17,7 +17,7 @@ * }, * ) */ -class ShapeOnlyColorEditableWidget extends WidgetBase { +class ShapeOnlyColorEditableWidget extends WidgetBase { /** * {@inheritdoc} diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php index 6602fdcd..3b84ada0 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php @@ -25,6 +25,11 @@ public function validate($value, Constraint $constraint) { $this->context->buildViolation($constraint->message) ->addViolation(); } + if ($value->name->value === 'entity-level-violation-with-path') { + $this->context->buildViolation($constraint->message) + ->atPath('test.form.element') + ->addViolation(); + } } } diff --git a/core/modules/system/tests/modules/entity_test/src/Routing/EntityTestRoutes.php b/core/modules/system/tests/modules/entity_test/src/Routing/EntityTestRoutes.php index d75d3595..5732060d 100644 --- a/core/modules/system/tests/modules/entity_test/src/Routing/EntityTestRoutes.php +++ b/core/modules/system/tests/modules/entity_test/src/Routing/EntityTestRoutes.php @@ -18,13 +18,13 @@ class EntityTestRoutes { public function routes() { $types = entity_test_entity_types(ENTITY_TEST_TYPES_ROUTING); - $routes = array(); + $routes = []; foreach ($types as $entity_type_id) { $routes["entity.$entity_type_id.admin_form"] = new Route( "$entity_type_id/structure/{bundle}", - array('_controller' => '\Drupal\entity_test\Controller\EntityTestController::testAdmin'), - array('_permission' => 'administer entity_test content'), - array('_admin_route' => TRUE) + ['_controller' => '\Drupal\entity_test\Controller\EntityTestController::testAdmin'], + ['_permission' => 'administer entity_test content'], + ['_admin_route' => TRUE] ); } return $routes; diff --git a/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml index 2a931ccf..70e2cec1 100644 --- a/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml +++ b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.info.yml b/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.info.yml index d04680c3..c0bb03e7 100644 --- a/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.info.yml +++ b/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.module b/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.module index d55aab3c..f399ae4b 100644 --- a/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.module +++ b/core/modules/system/tests/modules/entity_test_extra/entity_test_extra.module @@ -11,19 +11,19 @@ use Drupal\Core\Entity\EntityTypeInterface; * Implements hook_entity_base_field_info(). */ function entity_test_extra_entity_base_field_info(EntityTypeInterface $entity_type) { - return \Drupal::state()->get($entity_type->id() . '.additional_base_field_definitions', array()); + return \Drupal::state()->get($entity_type->id() . '.additional_base_field_definitions', []); } /** * Implements hook_entity_field_storage_info(). */ function entity_test_extra_entity_field_storage_info(EntityTypeInterface $entity_type) { - return \Drupal::state()->get($entity_type->id() . '.additional_field_storage_definitions', array()); + return \Drupal::state()->get($entity_type->id() . '.additional_field_storage_definitions', []); } /** * Implements hook_entity_bundle_field_info(). */ function entity_test_extra_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { - return \Drupal::state()->get($entity_type->id() . '.' . $bundle . '.additional_bundle_field_definitions', array()); + return \Drupal::state()->get($entity_type->id() . '.' . $bundle . '.additional_bundle_field_definitions', []); } diff --git a/core/modules/system/tests/modules/entity_test_operation/entity_test_operation.info.yml b/core/modules/system/tests/modules/entity_test_operation/entity_test_operation.info.yml index 020686bf..4ea7729d 100644 --- a/core/modules/system/tests/modules/entity_test_operation/entity_test_operation.info.yml +++ b/core/modules/system/tests/modules/entity_test_operation/entity_test_operation.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_revlog/entity_test_revlog.info.yml b/core/modules/system/tests/modules/entity_test_revlog/entity_test_revlog.info.yml new file mode 100644 index 00000000..981997bd --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_revlog/entity_test_revlog.info.yml @@ -0,0 +1,12 @@ +name: 'Entity test revision log' +type: module +description: 'Provides two entity types with revision logging capabilities.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestMulWithRevisionLog.php b/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestMulWithRevisionLog.php new file mode 100644 index 00000000..5a17b858 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestMulWithRevisionLog.php @@ -0,0 +1,33 @@ +setLabel(t('Name')) + ->setDescription(t('The name of the test entity.')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE) + ->setSetting('max_length', 32) + ->setDisplayOptions('view', [ + 'label' => 'hidden', + 'type' => 'string', + 'weight' => -5, + ]) + ->setDisplayOptions('form', [ + 'type' => 'string_textfield', + 'weight' => -5, + ]); + + return $fields; + } + +} diff --git a/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.info.yml b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.info.yml new file mode 100644 index 00000000..52d5bd94 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.info.yml @@ -0,0 +1,13 @@ +name: 'Entity Schema Converter Test' +type: module +description: 'Provides testing for the entity schema converter.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - entity_test_update +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.post_update.php b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.post_update.php new file mode 100644 index 00000000..ecddf310 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.post_update.php @@ -0,0 +1,41 @@ +convertToRevisionable( + $sandbox, + [ + 'test_single_property', + 'test_multiple_properties', + 'test_single_property_multiple_values', + 'test_multiple_properties_multiple_values', + 'test_entity_base_field_info', + ]); +} + +/** + * @} End of "addtogroup updates-8.4.x". + */ diff --git a/core/modules/system/tests/modules/entity_test_third_party/entity_test_third_party.info.yml b/core/modules/system/tests/modules/entity_test_third_party/entity_test_third_party.info.yml index 30c0234e..efc04737 100644 --- a/core/modules/system/tests/modules/entity_test_third_party/entity_test_third_party.info.yml +++ b/core/modules/system/tests/modules/entity_test_third_party/entity_test_third_party.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_update/config/install/field.field.entity_test_update.entity_test_update.field_test_configurable_field.yml b/core/modules/system/tests/modules/entity_test_update/config/install/field.field.entity_test_update.entity_test_update.field_test_configurable_field.yml new file mode 100644 index 00000000..b1f7cc93 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/config/install/field.field.entity_test_update.entity_test_update.field_test_configurable_field.yml @@ -0,0 +1,21 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.entity_test_update.field_test_configurable_field + module: + - entity_test_update +id: entity_test_update.entity_test_update.field_test_configurable_field +field_name: field_test_configurable_field +entity_type: entity_test_update +bundle: entity_test_update +label: 'Test configurable field' +description: '' +required: false +translatable: true +default_value: + - + value1: { } +default_value_callback: '' +settings: { } +field_type: multi_value_test diff --git a/core/modules/system/tests/modules/entity_test_update/config/install/field.storage.entity_test_update.field_test_configurable_field.yml b/core/modules/system/tests/modules/entity_test_update/config/install/field.storage.entity_test_update.field_test_configurable_field.yml new file mode 100644 index 00000000..1501f89a --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/config/install/field.storage.entity_test_update.field_test_configurable_field.yml @@ -0,0 +1,17 @@ +langcode: en +status: true +dependencies: + module: + - entity_test_update +id: entity_test_update.field_test_configurable_field +field_name: field_test_configurable_field +entity_type: entity_test_update +type: multi_value_test +settings: { } +module: entity_test_update +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/core/modules/system/tests/modules/entity_test_update/config/schema/entity_test_update.schema.yml b/core/modules/system/tests/modules/entity_test_update/config/schema/entity_test_update.schema.yml new file mode 100644 index 00000000..5c604575 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/config/schema/entity_test_update.schema.yml @@ -0,0 +1,9 @@ +field.value.multi_value_test: + type: mapping + label: 'Default value' + mapping: + value1: + type: sequence + sequence: + type: string + label: 'First value' diff --git a/core/modules/system/tests/modules/entity_test_update/entity_test_update.info.yml b/core/modules/system/tests/modules/entity_test_update/entity_test_update.info.yml new file mode 100644 index 00000000..e80a46e1 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/entity_test_update.info.yml @@ -0,0 +1,12 @@ +name: 'Entity Update Test' +type: module +description: 'Provides an entity type for testing definition and schema updates.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/entity_test_update/entity_test_update.install b/core/modules/system/tests/modules/entity_test_update/entity_test_update.install new file mode 100644 index 00000000..14233085 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/entity_test_update.install @@ -0,0 +1,10 @@ +id() == 'entity_test_update') { + $fields = []; + $fields['test_entity_base_field_info'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Field added by hook_entity_base_field_info()')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + return $fields; + } +} + +/** + * Implements hook_entity_field_storage_info(). + */ +function entity_test_update_entity_field_storage_info(EntityTypeInterface $entity_type) { + if ($entity_type->id() == 'entity_test_update') { + return \Drupal::state()->get('entity_test_update.additional_field_storage_definitions', []); + } +} + +/** + * Implements hook_entity_type_alter(). + */ +function entity_test_update_entity_type_alter(array &$entity_types) { + // Allow entity_test_update tests to override the entity type definition. + $entity_types['entity_test_update'] = \Drupal::state()->get('entity_test_update.entity_type', $entity_types['entity_test_update']); +} + +/** + * Implements hook_entity_presave(). + */ +function entity_test_update_entity_presave(EntityInterface $entity) { + // Simulate an error during the save process of a test entity. + if ($entity->getEntityTypeId() === 'entity_test_update' && \Drupal::state()->get('entity_test_update.throw_exception', FALSE)) { + throw new \Exception('Peekaboo!'); + } +} + +/** + * Creates a given number of 'entity_test_update' entities. + * + * The 'drupal-8.0.0-rc1-filled.standard.entity_test_update.php.gz' db dump was + * created with the following characteristics: + * - Drupal 8.0.0-rc1 installed with the Standard profile; + * - The 'entity_test_update' module enabled; + * - 102 test entities created and saved. + * + * The 'drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz' db dump + * was created with the following characteristics: + * - Drupal 8.0.0-rc1 installed with the Standard profile; + * - Manually edited the annotation of the entity_test_update entity type in + * order to make it translatable; + * - The entity_test_update and Language module enabled; + * - Romanian language added; + * - 50 test entities created, translated and saved; + * - The Content Translation module enabled and configured for our test entity + * type. This was enabled after the first 50 entities were created in order + * to have NULL values for its translation metadata fields + * (e.g. content_translation_status); + * - 52 more test entities (with the IDs 51 - 102) crated, translated and saved. + * + * The 'drupal-8.0.0-rc1-filled.standard.entity_test_update_mul_rev.php.gz' db + * dump was created like the multilingual one described above, with one change: + * The annotation of the entity_test_update entity type was also manually edited + * in order to make it revisionable. + * + * @param int $start + * (optional) The entity ID to start from. Defaults to 1. + * @param int $end + * (optional) The entity ID to end with. Defaults to 50. + * @param bool $add_translation + * (optional) Whether to create a translation for each entity. If the number + * of entities is greater than 50, the default translation (en) of the 51st + * entity and the 52nd translation (ro) are disabled through the + * 'content_moderation_status' field. Defaults to FALSE. + * + * @see drupal-8.0.0-rc1-filled.standard.entity_test_update.php.gz + * @see drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz + */ +function _entity_test_update_create_test_entities($start = 1, $end = 50, $add_translation = FALSE) { + for ($i = $start; $i <= $end; $i++) { + $entity = EntityTestUpdate::create([ + 'id' => $i, + 'name' => $i, + 'test_single_property' => $i . ' - test single property', + 'test_multiple_properties' => [ + [ + 'value1' => $i . ' - test multiple properties - value1', + 'value2' => $i . ' - test multiple properties - value2', + ], + ], + 'test_single_property_multiple_values' => [ + ['value' => $i . ' - test single property multiple values 0'], + ['value' => $i . ' - test single property multiple values 1'], + ], + 'test_multiple_properties_multiple_values' => [ + [ + 'value1' => $i . ' - test multiple properties multiple values - value1 0', + 'value2' => $i . ' - test multiple properties multiple values - value2 0', + ], + [ + 'value1' => $i . ' - test multiple properties multiple values - value1 1', + 'value2' => $i . ' - test multiple properties multiple values - value2 1', + ], + ], + 'test_non_rev_field' => $i . ' - test non-revisionable field', + 'test_non_mul_field' => $i . ' - test non-translatable field', + 'test_non_mulrev_field' => $i . ' - test non-translatable and non-revisionable field', + 'field_test_configurable_field' => [ + [ + 'value1' => $i . ' - field test configurable field - value1 0', + 'value2' => $i . ' - field test configurable field - value2 0', + ], + [ + 'value1' => $i . ' - field test configurable field - value1 1', + 'value2' => $i . ' - field test configurable field - value2 1', + ], + ], + 'test_entity_base_field_info' => $i . ' - test entity base field info', + ]); + + if ($add_translation) { + $entity->addTranslation('ro', [ + 'name' => $i . ' - ro', + 'test_single_property' => $i . ' - test single property - ro', + 'test_multiple_properties' => [ + [ + 'value1' => $i . ' - test multiple properties - value1 - ro', + 'value2' => $i . ' - test multiple properties - value2 - ro', + ], + ], + 'test_single_property_multiple_values' => [ + ['value' => $i . ' - test single property multiple values 0 - ro'], + ['value' => $i . ' - test single property multiple values 1 - ro'], + ], + 'test_multiple_properties_multiple_values' => [ + [ + 'value1' => $i . ' - test multiple properties multiple values - value1 0 - ro', + 'value2' => $i . ' - test multiple properties multiple values - value2 0 - ro', + ], + [ + 'value1' => $i . ' - test multiple properties multiple values - value1 1 - ro', + 'value2' => $i . ' - test multiple properties multiple values - value2 1 - ro', + ], + ], + 'test_non_rev_field' => $i . ' - test non-revisionable field - ro', + 'field_test_configurable_field' => [ + [ + 'value1' => $i . ' - field test configurable field - value1 0 - ro', + 'value2' => $i . ' - field test configurable field - value2 0 - ro', + ], + [ + 'value1' => $i . ' - field test configurable field - value1 1 - ro', + 'value2' => $i . ' - field test configurable field - value2 1 - ro', + ], + ], + 'test_entity_base_field_info' => $i . ' - test entity base field info - ro', + ]); + + if ($i == 101) { + $entity->getTranslation('en')->set('content_translation_status', FALSE); + } + if ($i == 102) { + $entity->getTranslation('ro')->set('content_translation_status', FALSE); + } + } + + $entity->save(); + } +} diff --git a/core/modules/system/tests/modules/entity_test_update/src/Entity/EntityTestUpdate.php b/core/modules/system/tests/modules/entity_test_update/src/Entity/EntityTestUpdate.php new file mode 100644 index 00000000..286e8e62 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/src/Entity/EntityTestUpdate.php @@ -0,0 +1,160 @@ +getEntityTypeId(); + } + } + + /** + * {@inheritdoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + // This entity type is used for generating database dumps from Drupal + // 8.0.0-rc1, which didn't have the entity key base fields defined in + // the parent class (ContentEntityBase), so we have to duplicate them here. + + $fields[$entity_type->getKey('id')] = BaseFieldDefinition::create('integer') + ->setLabel(new TranslatableMarkup('ID')) + ->setDescription(new TranslatableMarkup('The ID of the test entity.')) + ->setReadOnly(TRUE) + ->setSetting('unsigned', TRUE); + + $fields[$entity_type->getKey('uuid')] = BaseFieldDefinition::create('uuid') + ->setLabel(new TranslatableMarkup('UUID')) + ->setDescription(new TranslatableMarkup('The UUID of the test entity.')) + ->setReadOnly(TRUE); + + $fields[$entity_type->getKey('bundle')] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Type')) + ->setDescription(new TranslatableMarkup('The bundle of the test entity.')) + ->setRequired(TRUE); + + if ($entity_type->hasKey('revision')) { + $fields[$entity_type->getKey('revision')] = BaseFieldDefinition::create('integer') + ->setLabel(new TranslatableMarkup('Revision ID')) + ->setReadOnly(TRUE) + ->setSetting('unsigned', TRUE); + } + + $fields[$entity_type->getKey('langcode')] = BaseFieldDefinition::create('language') + ->setLabel(new TranslatableMarkup('Language')); + if ($entity_type->isRevisionable()) { + $fields[$entity_type->getKey('langcode')]->setRevisionable(TRUE); + } + if ($entity_type->isTranslatable()) { + $fields[$entity_type->getKey('langcode')]->setTranslatable(TRUE); + } + + $fields['name'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Name')) + ->setDescription(new TranslatableMarkup('The name of the test entity.')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE) + ->setSetting('max_length', 32) + ->setDisplayOptions('view', [ + 'label' => 'hidden', + 'type' => 'string', + 'weight' => -5, + ]) + ->setDisplayOptions('form', [ + 'type' => 'string_textfield', + 'weight' => -5, + ]); + + $fields['test_single_property'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Field with a single property')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_multiple_properties'] = BaseFieldDefinition::create('multi_value_test') + ->setLabel(new TranslatableMarkup('Field with multiple properties')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_single_property_multiple_values'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Field with a single property and multiple values')) + ->setCardinality(2) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_multiple_properties_multiple_values'] = BaseFieldDefinition::create('multi_value_test') + ->setLabel(new TranslatableMarkup('Field with multiple properties and multiple values')) + ->setCardinality(2) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_non_rev_field'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Non Revisionable Field')) + ->setDescription(new TranslatableMarkup('A non-revisionable test field.')) + ->setCardinality(1) + ->setRevisionable(FALSE) + ->setTranslatable(TRUE); + + $fields['test_non_mul_field'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Non Translatable Field')) + ->setDescription(new TranslatableMarkup('A non-translatable test field.')) + ->setCardinality(1) + ->setRevisionable(TRUE) + ->setTranslatable(FALSE); + + $fields['test_non_mulrev_field'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Non Revisionable and Translatable Field')) + ->setDescription(new TranslatableMarkup('A non-revisionable and non-translatable test field.')) + ->setCardinality(1) + ->setRevisionable(FALSE) + ->setTranslatable(FALSE); + + $fields += \Drupal::state()->get('entity_test_update.additional_base_field_definitions', []); + return $fields; + } + + /** + * {@inheritdoc} + */ + public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { + $fields = parent::bundleFieldDefinitions($entity_type, $bundle, $base_field_definitions); + $fields += \Drupal::state()->get('entity_test_update.additional_bundle_field_definitions.' . $bundle, []); + return $fields; + } + +} diff --git a/core/modules/system/tests/modules/entity_test_update/src/EntityTestUpdateStorageSchema.php b/core/modules/system/tests/modules/entity_test_update/src/EntityTestUpdateStorageSchema.php new file mode 100644 index 00000000..2b75e830 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/src/EntityTestUpdateStorageSchema.php @@ -0,0 +1,39 @@ +id() == 'entity_test_update') { + $schema[$entity_type->getBaseTable()]['indexes'] += \Drupal::state()->get('entity_test_update.additional_entity_indexes', []); + } + return $schema; + } + + /** + * {@inheritdoc} + */ + protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $storage_definition, $table_name, array $column_mapping) { + $schema = parent::getSharedTableFieldSchema($storage_definition, $table_name, $column_mapping); + + if (\Drupal::state()->get('entity_test_update.additional_field_index.' . $table_name . '.' . $storage_definition->getName())) { + $this->addSharedTableFieldIndex($storage_definition, $schema); + } + + return $schema; + } + +} diff --git a/core/modules/system/tests/modules/entity_test_update/src/Plugin/Field/FieldType/MultiValueTestItem.php b/core/modules/system/tests/modules/entity_test_update/src/Plugin/Field/FieldType/MultiValueTestItem.php new file mode 100644 index 00000000..cb088180 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/src/Plugin/Field/FieldType/MultiValueTestItem.php @@ -0,0 +1,66 @@ +setLabel(t('First value')); + + $properties['value2'] = DataDefinition::create('string') + ->setLabel(t('Second value')); + + return $properties; + } + + /** + * {@inheritdoc} + */ + public static function schema(FieldStorageDefinitionInterface $field_definition) { + return [ + 'columns' => [ + 'value1' => [ + 'type' => 'varchar', + 'length' => 64, + ], + 'value2' => [ + 'type' => 'varchar', + 'length' => 64, + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function isEmpty() { + $item = $this->getValue(); + return empty($item['value1']) && empty($item['value2']); + } + + /** + * {@inheritdoc} + */ + public static function mainPropertyName() { + return 'value1'; + } + +} diff --git a/core/modules/system/tests/modules/entity_test_update/update/entity_rev_pub_updates_8400.inc b/core/modules/system/tests/modules/entity_test_update/update/entity_rev_pub_updates_8400.inc new file mode 100644 index 00000000..988505d5 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_update/update/entity_rev_pub_updates_8400.inc @@ -0,0 +1,110 @@ + 8400, + ]; + + return $dependencies; +} + +/** + * Add the 'published' and revisionable metadata fields to entity_test_update. + */ +function entity_test_update_update_8400() { + $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + + // Add the published entity key and revisionable metadata fields to the + // entity_test_update entity type. + $entity_type = $definition_update_manager->getEntityType('entity_test_update'); + + $entity_keys = $entity_type->getKeys(); + $entity_keys['published'] = 'status'; + $entity_type->set('entity_keys', $entity_keys); + + $revision_metadata_keys = [ + 'revision_user' => 'revision_user', + 'revision_created' => 'revision_created', + 'revision_log_message' => 'revision_log_message' + ]; + $entity_type->set('revision_metadata_keys', $revision_metadata_keys); + + $definition_update_manager->updateEntityType($entity_type); + + // Add the status field. + $status = BaseFieldDefinition::create('boolean') + ->setLabel(t('Publishing status')) + ->setDescription(t('A boolean indicating the published state.')) + ->setRevisionable(TRUE) + ->setTranslatable(TRUE) + ->setDefaultValue(TRUE); + + $has_content_translation_status_field = \Drupal::moduleHandler()->moduleExists('content_translation') && $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'entity_test_update'); + if ($has_content_translation_status_field) { + $status->setInitialValueFromField('content_translation_status'); + } + else { + $status->setInitialValue(TRUE); + } + $definition_update_manager->installFieldStorageDefinition('status', 'entity_test_update', 'entity_test_update', $status); + + // Add the revision metadata fields. + $revision_created = BaseFieldDefinition::create('created') + ->setLabel(t('Revision create time')) + ->setDescription(t('The time that the current revision was created.')) + ->setRevisionable(TRUE); + $definition_update_manager->installFieldStorageDefinition('revision_created', 'entity_test_update', 'entity_test_update', $revision_created); + + $revision_user = BaseFieldDefinition::create('entity_reference') + ->setLabel(t('Revision user')) + ->setDescription(t('The user ID of the author of the current revision.')) + ->setSetting('target_type', 'user') + ->setRevisionable(TRUE); + $definition_update_manager->installFieldStorageDefinition('revision_user', 'entity_test_update', 'entity_test_update', $revision_user); + + $revision_log_message = BaseFieldDefinition::create('string_long') + ->setLabel(t('Revision log message')) + ->setDescription(t('Briefly describe the changes you have made.')) + ->setRevisionable(TRUE) + ->setDefaultValue('') + ->setDisplayOptions('form', [ + 'type' => 'string_textarea', + 'weight' => 25, + 'settings' => [ + 'rows' => 4, + ], + ]); + $definition_update_manager->installFieldStorageDefinition('revision_log_message', 'entity_test_update', 'entity_test_update', $revision_log_message); + + // Uninstall the 'content_translation_status' field if needed. + $database = \Drupal::database(); + if ($has_content_translation_status_field) { + // First we have to remove the field data. + $database->update($entity_type->getDataTable()) + ->fields(['content_translation_status' => NULL]) + ->execute(); + + // A site may have disabled revisionability for this entity type. + if ($entity_type->isRevisionable()) { + $database->update($entity_type->getRevisionDataTable()) + ->fields(['content_translation_status' => NULL]) + ->execute(); + } + + $content_translation_status = $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'entity_test_update'); + $definition_update_manager->uninstallFieldStorageDefinition($content_translation_status); + } +} diff --git a/core/modules/system/tests/modules/error_service_test/error_service_test.info.yml b/core/modules/system/tests/modules/error_service_test/error_service_test.info.yml index 99588e6c..bd6c750b 100644 --- a/core/modules/system/tests/modules/error_service_test/error_service_test.info.yml +++ b/core/modules/system/tests/modules/error_service_test/error_service_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/error_service_test/src/Logger/TestLog.php b/core/modules/system/tests/modules/error_service_test/src/Logger/TestLog.php index 579d71f8..3f18bb94 100644 --- a/core/modules/system/tests/modules/error_service_test/src/Logger/TestLog.php +++ b/core/modules/system/tests/modules/error_service_test/src/Logger/TestLog.php @@ -16,7 +16,7 @@ class TestLog implements LoggerInterface { /** * {@inheritdoc} */ - public function log($level, $message, array $context = array()) { + public function log($level, $message, array $context = []) { $trigger = [ '%type' => 'Exception', '@message' => 'Deforestation', diff --git a/core/modules/system/tests/modules/error_test/error_test.info.yml b/core/modules/system/tests/modules/error_test/error_test.info.yml index 29d3b35b..939c7e52 100644 --- a/core/modules/system/tests/modules/error_test/error_test.info.yml +++ b/core/modules/system/tests/modules/error_test/error_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php b/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php index 03ae3664..dd526b86 100644 --- a/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php +++ b/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php @@ -56,7 +56,7 @@ public function generateWarnings($collect_errors = FALSE) { * Generate fatals to test the error handler. */ public function generateFatals() { - $function = function(array $test) { + $function = function (array $test) { }; $function("test-string"); diff --git a/core/modules/system/tests/modules/experimental_module_dependency_test/experimental_module_dependency_test.info.yml b/core/modules/system/tests/modules/experimental_module_dependency_test/experimental_module_dependency_test.info.yml index 6dfb5238..86e8bb73 100644 --- a/core/modules/system/tests/modules/experimental_module_dependency_test/experimental_module_dependency_test.info.yml +++ b/core/modules/system/tests/modules/experimental_module_dependency_test/experimental_module_dependency_test.info.yml @@ -7,8 +7,8 @@ dependencies: # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.info.yml b/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.info.yml index c9bf0c65..27e90ea7 100644 --- a/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.info.yml +++ b/core/modules/system/tests/modules/experimental_module_requirements_test/experimental_module_requirements_test.info.yml @@ -5,8 +5,8 @@ package: Core (Experimental) # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml index 2e9b5730..241f9f9a 100644 --- a/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml +++ b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.info.yml @@ -5,8 +5,8 @@ package: Core (Experimental) # version: 8.y.x-unstable # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.module b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.module index ec3ae7f2..1f507208 100644 --- a/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.module +++ b/core/modules/system/tests/modules/experimental_module_test/experimental_module_test.module @@ -5,7 +5,7 @@ * Experimental Test module to test the Core (Experimental) package. */ -use \Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Routing\RouteMatchInterface; /** * Implements hook_help(). diff --git a/core/modules/system/tests/modules/form_test/form_test.info.yml b/core/modules/system/tests/modules/form_test/form_test.info.yml index 29fc533b..0b231fae 100644 --- a/core/modules/system/tests/modules/form_test/form_test.info.yml +++ b/core/modules/system/tests/modules/form_test/form_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module index 7114a29c..e3a5e3f2 100644 --- a/core/modules/system/tests/modules/form_test/form_test.module +++ b/core/modules/system/tests/modules/form_test/form_test.module @@ -41,49 +41,49 @@ function system_form_form_test_alter_form_alter(&$form, FormStateInterface $form * Create a header and options array. Helper function for callbacks. */ function _form_test_tableselect_get_data() { - $header = array( + $header = [ 'one' => t('One'), 'two' => t('Two'), 'three' => t('Three'), 'four' => t('Four'), - ); + ]; - $options['row1'] = array( - 'title' => array('data' => array('#title' => t('row1'))), + $options['row1'] = [ + 'title' => ['data' => ['#title' => t('row1')]], 'one' => 'row1col1', 'two' => t('row1col2'), 'three' => t('row1col3'), 'four' => t('row1col4'), - ); + ]; - $options['row2'] = array( - 'title' => array('data' => array('#title' => t('row2'))), + $options['row2'] = [ + 'title' => ['data' => ['#title' => t('row2')]], 'one' => 'row2col1', 'two' => t('row2col2'), 'three' => t('row2col3'), 'four' => t('row2col4'), - ); + ]; - $options['row3'] = array( - 'title' => array('data' => array('#title' => t('row3'))), + $options['row3'] = [ + 'title' => ['data' => ['#title' => t('row3')]], 'one' => 'row3col1', 'two' => t('row3col2'), 'three' => t('row3col3'), 'four' => t('row3col4'), - ); + ]; - return array($header, $options); + return [$header, $options]; } /** * Implements hook_form_FORM_ID_alter() for the registration form. */ function form_test_form_user_register_form_alter(&$form, FormStateInterface $form_state) { - $form['test_rebuild'] = array( + $form['test_rebuild'] = [ '#type' => 'submit', '#value' => t('Rebuild'), - '#submit' => array('form_test_user_register_form_rebuild'), - ); + '#submit' => ['form_test_user_register_form_rebuild'], + ]; } /** diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml index 2250a0bb..0ee125c9 100644 --- a/core/modules/system/tests/modules/form_test/form_test.routing.yml +++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml @@ -294,6 +294,14 @@ form_test.checkboxes_radios: requirements: _access: 'TRUE' +form_test.radios_checked: + path: '/form-test/radios-checked' + defaults: + _form: '\Drupal\form_test\Form\FormTestRadiosCheckedForm' + _title: 'Radios checked defalt value' + requirements: + _access: 'TRUE' + form_test.email: path: '/form-test/email' defaults: diff --git a/core/modules/system/tests/modules/form_test/src/AutocompleteController.php b/core/modules/system/tests/modules/form_test/src/AutocompleteController.php index acbfa409..cc78a9c0 100644 --- a/core/modules/system/tests/modules/form_test/src/AutocompleteController.php +++ b/core/modules/system/tests/modules/form_test/src/AutocompleteController.php @@ -16,7 +16,7 @@ class AutocompleteController { * A JSON response. */ public function autocomplete1() { - return new JsonResponse(array('key' => 'value')); + return new JsonResponse(['key' => 'value']); } } diff --git a/core/modules/system/tests/modules/form_test/src/Callbacks.php b/core/modules/system/tests/modules/form_test/src/Callbacks.php index 3bf07f30..0310a37e 100644 --- a/core/modules/system/tests/modules/form_test/src/Callbacks.php +++ b/core/modules/system/tests/modules/form_test/src/Callbacks.php @@ -38,7 +38,7 @@ public function validateName(&$element, FormStateInterface $form_state) { if ($triggered) { // Output the element's value from $form_state. - drupal_set_message(t('@label value: @value', array('@label' => $element['#title'], '@value' => $form_state->getValue('name')))); + drupal_set_message(t('@label value: @value', ['@label' => $element['#title'], '@value' => $form_state->getValue('name')])); // Trigger a form validation error to see our changes. $form_state->setErrorByName(''); diff --git a/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php b/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php index 8885836f..eaa0f203 100644 --- a/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php +++ b/core/modules/system/tests/modules/form_test/src/ConfirmFormArrayPathTestForm.php @@ -20,11 +20,11 @@ public function getFormId() { * {@inheritdoc} */ public function getCancelUrl() { - return new Url('form_test.route6', array(), array( - 'query' => array( + return new Url('form_test.route6', [], [ + 'query' => [ 'destination' => 'admin/config', - ), - )); + ], + ]); } /** diff --git a/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php b/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php index d35c59d1..917f9e0e 100644 --- a/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php +++ b/core/modules/system/tests/modules/form_test/src/ConfirmFormTestForm.php @@ -57,7 +57,7 @@ public function getCancelText() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['element'] = array('#markup' => '

    The ConfirmFormTestForm::buildForm() method was used for this form.

    '); + $form['element'] = ['#markup' => '

    The ConfirmFormTestForm::buildForm() method was used for this form.

    ']; return parent::buildForm($form, $form_state); } diff --git a/core/modules/system/tests/modules/form_test/src/Controller/FormTestController.php b/core/modules/system/tests/modules/form_test/src/Controller/FormTestController.php index 5d28bf25..4c9fbe2c 100644 --- a/core/modules/system/tests/modules/form_test/src/Controller/FormTestController.php +++ b/core/modules/system/tests/modules/form_test/src/Controller/FormTestController.php @@ -20,12 +20,12 @@ class FormTestController extends ControllerBase { */ public function twoFormInstances() { $user = $this->currentUser(); - $values = array( + $values = [ 'uid' => $user->id(), 'name' => $user->getUsername(), 'type' => 'page', 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ); + ]; $node1 = $this->entityManager()->getStorage('node')->create($values); $node2 = clone($node1); $return['node_form_1'] = $this->entityFormBuilder()->getForm($node1); diff --git a/core/modules/system/tests/modules/form_test/src/EventSubscriber/FormTestEventSubscriber.php b/core/modules/system/tests/modules/form_test/src/EventSubscriber/FormTestEventSubscriber.php index 15e4545f..3fb97507 100644 --- a/core/modules/system/tests/modules/form_test/src/EventSubscriber/FormTestEventSubscriber.php +++ b/core/modules/system/tests/modules/form_test/src/EventSubscriber/FormTestEventSubscriber.php @@ -39,8 +39,8 @@ public function onKernelResponse(FilterResponseEvent $event) { * {@inheritdoc} */ public static function getSubscribedEvents() { - $events[KernelEvents::REQUEST][] = array('onKernelRequest'); - $events[KernelEvents::RESPONSE][] = array('onKernelResponse'); + $events[KernelEvents::REQUEST][] = ['onKernelRequest']; + $events[KernelEvents::RESPONSE][] = ['onKernelResponse']; return $events; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestButtonClassForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestButtonClassForm.php index 6870781d..4e3de3bb 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestButtonClassForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestButtonClassForm.php @@ -21,16 +21,16 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['button'] = array( + $form['button'] = [ '#type' => 'button', '#value' => 'test', '#button_type' => 'foo', - ); - $form['delete'] = array( + ]; + $form['delete'] = [ '#type' => 'button', '#value' => 'Delete', '#button_type' => 'danger', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php index 66f7d059..62220cc6 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php @@ -20,65 +20,65 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state) { // A required checkbox. - $form['required_checkbox'] = array( + $form['required_checkbox'] = [ '#type' => 'checkbox', '#required' => TRUE, '#title' => 'required_checkbox', - ); + ]; // A disabled checkbox should get its default value back. - $form['disabled_checkbox_on'] = array( + $form['disabled_checkbox_on'] = [ '#type' => 'checkbox', '#disabled' => TRUE, '#return_value' => 'disabled_checkbox_on', '#default_value' => 'disabled_checkbox_on', '#title' => 'disabled_checkbox_on', - ); - $form['disabled_checkbox_off'] = array( + ]; + $form['disabled_checkbox_off'] = [ '#type' => 'checkbox', '#disabled' => TRUE, '#return_value' => 'disabled_checkbox_off', '#default_value' => NULL, '#title' => 'disabled_checkbox_off', - ); + ]; // A checkbox is active when #default_value == #return_value. - $form['checkbox_on'] = array( + $form['checkbox_on'] = [ '#type' => 'checkbox', '#return_value' => 'checkbox_on', '#default_value' => 'checkbox_on', '#title' => 'checkbox_on', - ); + ]; // But inactive in any other case. - $form['checkbox_off'] = array( + $form['checkbox_off'] = [ '#type' => 'checkbox', '#return_value' => 'checkbox_off', '#default_value' => 'checkbox_on', '#title' => 'checkbox_off', - ); + ]; // Checkboxes with a #return_value of '0' are supported. - $form['zero_checkbox_on'] = array( + $form['zero_checkbox_on'] = [ '#type' => 'checkbox', '#return_value' => '0', '#default_value' => '0', '#title' => 'zero_checkbox_on', - ); + ]; // In that case, passing a #default_value != '0' // means that the checkbox is off. - $form['zero_checkbox_off'] = array( + $form['zero_checkbox_off'] = [ '#type' => 'checkbox', '#return_value' => '0', '#default_value' => '1', '#title' => 'zero_checkbox_off', - ); + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxTypeJugglingForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxTypeJugglingForm.php index eb48bfcb..ad0a86e8 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxTypeJugglingForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxTypeJugglingForm.php @@ -21,12 +21,12 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $default_value = NULL, $return_value = NULL) { - $form['checkbox'] = array( + $form['checkbox'] = [ '#title' => t('Checkbox'), '#type' => 'checkbox', '#return_value' => $return_value, '#default_value' => $default_value, - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php index 7c412fec..a1a45a0a 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php @@ -24,53 +24,53 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state, $customize = FALSE) { // Expand #type checkboxes, setting custom element properties for some but not // all options. - $form['checkboxes'] = array( + $form['checkboxes'] = [ '#type' => 'checkboxes', '#title' => 'Checkboxes', - '#options' => array( + '#options' => [ 0 => 'Zero', 'foo' => 'Foo', 1 => 'One', 'bar' => $this->t('Bar - checkboxes'), '>' => "Special Char", - ), - ); + ], + ]; if ($customize) { - $form['checkboxes'] += array( - 'foo' => array( + $form['checkboxes'] += [ + 'foo' => [ '#description' => 'Enable to foo.', - ), - 1 => array( + ], + 1 => [ '#weight' => 10, - ), - ); + ], + ]; } // Expand #type radios, setting custom element properties for some but not // all options. - $form['radios'] = array( + $form['radios'] = [ '#type' => 'radios', '#title' => 'Radios', - '#options' => array( + '#options' => [ 0 => 'Zero', 'foo' => 'Foo', 1 => 'One', 'bar' => 'Bar - radios', '>' => "Special Char", - ), - ); + ], + ]; if ($customize) { - $form['radios'] += array( - 'foo' => array( + $form['radios'] += [ + 'foo' => [ '#description' => 'Enable to foo.', - ), - 1 => array( + ], + 1 => [ '#weight' => 10, - ), - ); + ], + ]; } - $form['submit'] = array('#type' => 'submit', '#value' => 'Submit'); + $form['submit'] = ['#type' => 'submit', '#value' => 'Submit']; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php index 2f2a38f3..59f81e95 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php @@ -23,27 +23,27 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state, $json = TRUE) { $form_state->set('json', $json); - $form['checkbox_off'] = array( + $form['checkbox_off'] = [ '#title' => t('Checkbox off'), '#type' => 'checkboxes', - '#options' => array('foo', 'bar', 'baz'), - ); - $form['checkbox_zero_default'] = array( + '#options' => ['foo', 'bar', 'baz'], + ]; + $form['checkbox_zero_default'] = [ '#title' => t('Zero default'), '#type' => 'checkboxes', - '#options' => array('foo', 'bar', 'baz'), - '#default_value' => array(0), - ); - $form['checkbox_string_zero_default'] = array( + '#options' => ['foo', 'bar', 'baz'], + '#default_value' => [0], + ]; + $form['checkbox_string_zero_default'] = [ '#title' => t('Zero default (string)'), '#type' => 'checkboxes', - '#options' => array('foo', 'bar', 'baz'), - '#default_value' => array('0'), - ); - $form['submit'] = array( + '#options' => ['foo', 'bar', 'baz'], + '#default_value' => ['0'], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Save', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php index c6684db1..adab5bda 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestClickedButtonForm.php @@ -26,10 +26,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $first = // submitted without any information identifying the button responsible for // the submission. In other browsers, the form is submitted as though the // first button were clicked. - $form['text'] = array( + $form['text'] = [ '#title' => 'Text', '#type' => 'textfield', - ); + ]; // Loop through each path argument, adding buttons based on the information // in the argument. For example, if the path is @@ -37,7 +37,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $first = // 'image_button', and a 'button' with #access=FALSE. This enables form.test // to test a variety of combinations. $i = 0; - $args = array($first, $second, $third); + $args = [$first, $second, $third]; foreach ($args as $arg) { $name = 'button' . ++$i; // 's', 'b', or 'i' in the argument define the button type wanted. @@ -54,10 +54,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $first = $type = NULL; } if (isset($type)) { - $form[$name] = array( + $form[$name] = [ '#type' => $type, '#name' => $name, - ); + ]; // Image buttons need a #src; the others need a #value. if ($type == 'image_button') { $form[$name]['#src'] = 'core/misc/druplicon.png'; diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php index a9be1eaa..07638809 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php @@ -22,14 +22,14 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['color'] = array( + $form['color'] = [ '#type' => 'color', '#title' => 'Color', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php index f7527af2..81120ad1 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestDescriptionForm.php @@ -23,26 +23,26 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['form_textfield_test_description_before'] = array( + $form['form_textfield_test_description_before'] = [ '#type' => 'textfield', '#title' => 'Textfield test for description before element', '#description' => 'Textfield test for description before element', '#description_display' => 'before', - ); + ]; - $form['form_textfield_test_description_after'] = array( + $form['form_textfield_test_description_after'] = [ '#type' => 'textfield', '#title' => 'Textfield test for description after element', '#description' => 'Textfield test for description after element', '#description_display' => 'after', - ); + ]; - $form['form_textfield_test_description_invisible'] = array( + $form['form_textfield_test_description_invisible'] = [ '#type' => 'textfield', '#title' => 'Textfield test for visually-hidden description', '#description' => 'Textfield test for visually-hidden description', '#description_display' => 'invisible', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php index 8ebbf83e..56e6d2ee 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php @@ -24,101 +24,101 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state) { // Elements that take a simple default value. - foreach (array('textfield', 'textarea', 'search', 'tel', 'hidden') as $type) { - $form[$type] = array( + foreach (['textfield', 'textarea', 'search', 'tel', 'hidden'] as $type) { + $form[$type] = [ '#type' => $type, '#title' => $type, '#default_value' => $type, '#test_hijack_value' => 'HIJACK', '#disabled' => TRUE, - ); + ]; } // Multiple values option elements. - foreach (array('checkboxes', 'select') as $type) { - $form[$type . '_multiple'] = array( + foreach (['checkboxes', 'select'] as $type) { + $form[$type . '_multiple'] = [ '#type' => $type, '#title' => $type . ' (multiple)', - '#options' => array( + '#options' => [ 'test_1' => 'Test 1', 'test_2' => 'Test 2', - ), + ], '#multiple' => TRUE, - '#default_value' => array('test_2' => 'test_2'), + '#default_value' => ['test_2' => 'test_2'], // The keys of #test_hijack_value need to match the #name of the control. // @see FormsTestCase::testDisabledElements() - '#test_hijack_value' => $type == 'select' ? array('' => 'test_1') : array('test_1' => 'test_1'), + '#test_hijack_value' => $type == 'select' ? ['' => 'test_1'] : ['test_1' => 'test_1'], '#disabled' => TRUE, - ); + ]; } // Single values option elements. - foreach (array('radios', 'select') as $type) { - $form[$type . '_single'] = array( + foreach (['radios', 'select'] as $type) { + $form[$type . '_single'] = [ '#type' => $type, '#title' => $type . ' (single)', - '#options' => array( + '#options' => [ 'test_1' => 'Test 1', 'test_2' => 'Test 2', - ), + ], '#multiple' => FALSE, '#default_value' => 'test_2', '#test_hijack_value' => 'test_1', '#disabled' => TRUE, - ); + ]; } // Checkbox and radio. - foreach (array('checkbox', 'radio') as $type) { - $form[$type . '_unchecked'] = array( + foreach (['checkbox', 'radio'] as $type) { + $form[$type . '_unchecked'] = [ '#type' => $type, '#title' => $type . ' (unchecked)', '#return_value' => 1, '#default_value' => 0, '#test_hijack_value' => 1, '#disabled' => TRUE, - ); - $form[$type . '_checked'] = array( + ]; + $form[$type . '_checked'] = [ '#type' => $type, '#title' => $type . ' (checked)', '#return_value' => 1, '#default_value' => 1, '#test_hijack_value' => NULL, '#disabled' => TRUE, - ); + ]; } // Weight, number, range. - foreach (array('weight', 'number', 'range') as $type) { - $form[$type] = array( + foreach (['weight', 'number', 'range'] as $type) { + $form[$type] = [ '#type' => $type, '#title' => $type, '#default_value' => 10, '#test_hijack_value' => 5, '#disabled' => TRUE, - ); + ]; } // Color. - $form['color'] = array( + $form['color'] = [ '#type' => 'color', '#title' => 'color', '#default_value' => '#0000ff', '#test_hijack_value' => '#ff0000', '#disabled' => TRUE, - ); + ]; // The #disabled state should propagate to children. - $form['disabled_container'] = array( + $form['disabled_container'] = [ '#disabled' => TRUE, - ); - foreach (array('textfield', 'textarea', 'hidden', 'tel', 'url') as $type) { - $form['disabled_container']['disabled_container_' . $type] = array( + ]; + foreach (['textfield', 'textarea', 'hidden', 'tel', 'url'] as $type) { + $form['disabled_container']['disabled_container_' . $type] = [ '#type' => $type, '#title' => $type, '#default_value' => $type, '#test_hijack_value' => 'HIJACK', - ); + ]; } // Date. @@ -128,103 +128,103 @@ public function buildForm(array $form, FormStateInterface $form_state) { // versions by encoding and decoding it again instead of hardcoding it. // See https://github.com/php/php-src/commit/fdb2709dd27c5987c2d2c8aaf0cdbebf9f17f643 $expected = json_decode(json_encode($date), TRUE); - $form['disabled_container']['disabled_container_datetime'] = array( + $form['disabled_container']['disabled_container_datetime'] = [ '#type' => 'datetime', '#title' => 'datetime', '#default_value' => $date, '#expected_value' => $expected, '#test_hijack_value' => new DrupalDateTime('1978-12-02 11:30:00', 'Europe/Berlin'), '#date_timezone' => 'Europe/Berlin', - ); + ]; - $form['disabled_container']['disabled_container_date'] = array( + $form['disabled_container']['disabled_container_date'] = [ '#type' => 'date', '#title' => 'date', '#default_value' => '2001-01-13', '#expected_value' => '2001-01-13', '#test_hijack_value' => '2013-01-01', '#date_timezone' => 'Europe/Berlin', - ); + ]; // Try to hijack the email field with a valid email. - $form['disabled_container']['disabled_container_email'] = array( + $form['disabled_container']['disabled_container_email'] = [ '#type' => 'email', '#title' => 'email', '#default_value' => 'foo@example.com', '#test_hijack_value' => 'bar@example.com', - ); + ]; // Try to hijack the URL field with a valid URL. - $form['disabled_container']['disabled_container_url'] = array( + $form['disabled_container']['disabled_container_url'] = [ '#type' => 'url', '#title' => 'url', '#default_value' => 'http://example.com', '#test_hijack_value' => 'http://example.com/foo', - ); + ]; // Text format. - $form['text_format'] = array( + $form['text_format'] = [ '#type' => 'text_format', '#title' => 'Text format', '#disabled' => TRUE, '#default_value' => 'Text value', '#format' => 'plain_text', - '#expected_value' => array( + '#expected_value' => [ 'value' => 'Text value', 'format' => 'plain_text', - ), - '#test_hijack_value' => array( + ], + '#test_hijack_value' => [ 'value' => 'HIJACK', 'format' => 'filtered_html', - ), - ); + ], + ]; // Password fields. - $form['password'] = array( + $form['password'] = [ '#type' => 'password', '#title' => 'Password', '#disabled' => TRUE, - ); - $form['password_confirm'] = array( + ]; + $form['password_confirm'] = [ '#type' => 'password_confirm', '#title' => 'Password confirm', '#disabled' => TRUE, - ); + ]; // Files. - $form['file'] = array( + $form['file'] = [ '#type' => 'file', '#title' => 'File', '#disabled' => TRUE, - ); - $form['managed_file'] = array( + ]; + $form['managed_file'] = [ '#type' => 'managed_file', '#title' => 'Managed file', '#disabled' => TRUE, - ); + ]; // Buttons. - $form['image_button'] = array( + $form['image_button'] = [ '#type' => 'image_button', '#value' => 'Image button', '#disabled' => TRUE, - ); - $form['button'] = array( + ]; + $form['button'] = [ '#type' => 'button', '#value' => 'Button', '#disabled' => TRUE, - ); - $form['submit_disabled'] = array( + ]; + $form['submit_disabled'] = [ '#type' => 'submit', '#value' => 'Submit', '#disabled' => TRUE, - ); + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php index d669515a..8e82623d 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php @@ -22,21 +22,21 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['email'] = array( + $form['email'] = [ '#type' => 'email', '#title' => 'Email address', '#description' => 'An email address.', - ); - $form['email_required'] = array( + ]; + $form['email_required'] = [ '#type' => 'email', '#title' => 'Address', '#required' => TRUE, '#description' => 'A required email address field.', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestEmptySelectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestEmptySelectForm.php index b6f94545..14dcb0c3 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestEmptySelectForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestEmptySelectForm.php @@ -21,12 +21,12 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['empty_select'] = array( + $form['empty_select'] = [ '#type' => 'select', '#title' => t('Empty Select'), '#multiple' => FALSE, '#options' => NULL, - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanAdvancedForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanAdvancedForm.php index d3cbd520..f910469b 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanAdvancedForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanAdvancedForm.php @@ -22,16 +22,16 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state) { // Build an example form containing a managed file and a submit form element. - $form['image'] = array( + $form['image'] = [ '#type' => 'managed_file', '#title' => t('Image'), '#upload_location' => 'public://', '#default_value' => 0, - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanForm.php index bef56752..d5e0fd96 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestFormStateValuesCleanForm.php @@ -24,13 +24,13 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { // Build an example form containing multiple submit and button elements; not // only on the top-level. - $form = array('#tree' => TRUE); - $form['foo'] = array('#type' => 'submit', '#value' => t('Submit')); - $form['bar'] = array('#type' => 'submit', '#value' => t('Submit')); - $form['beer'] = array('#type' => 'value', '#value' => 1000); - $form['baz']['foo'] = array('#type' => 'button', '#value' => t('Submit')); - $form['baz']['baz'] = array('#type' => 'submit', '#value' => t('Submit')); - $form['baz']['beer'] = array('#type' => 'value', '#value' => 2000); + $form = ['#tree' => TRUE]; + $form['foo'] = ['#type' => 'submit', '#value' => t('Submit')]; + $form['bar'] = ['#type' => 'submit', '#value' => t('Submit')]; + $form['beer'] = ['#type' => 'value', '#value' => 1000]; + $form['baz']['foo'] = ['#type' => 'button', '#value' => t('Submit')]; + $form['baz']['baz'] = ['#type' => 'submit', '#value' => t('Submit')]; + $form['baz']['beer'] = ['#type' => 'value', '#value' => 2000]; // Add an arbitrary element and manually set it to be cleaned. // Using $form_state->addCleanValueKey('wine'); didn't work here. diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupContainerForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupContainerForm.php index a9298efd..b141b7cc 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupContainerForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupContainerForm.php @@ -21,19 +21,19 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['container'] = array( + $form['container'] = [ '#type' => 'container', - ); - $form['meta'] = array( + ]; + $form['meta'] = [ '#type' => 'details', '#title' => 'Group element', '#open' => TRUE, '#group' => 'container', - ); - $form['meta']['element'] = array( + ]; + $form['meta']['element'] = [ '#type' => 'textfield', '#title' => 'Nest in details element', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php index faa83cce..002b07dd 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupDetailsForm.php @@ -21,22 +21,22 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $required = FALSE) { - $form['details'] = array( + $form['details'] = [ '#type' => 'details', '#title' => 'Root element', '#open' => TRUE, '#required' => !empty($required), - ); - $form['meta'] = array( + ]; + $form['meta'] = [ '#type' => 'details', '#title' => 'Group element', '#open' => TRUE, '#group' => 'details', - ); - $form['meta']['element'] = array( + ]; + $form['meta']['element'] = [ '#type' => 'textfield', '#title' => 'Nest in details element', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php index fd7d83b8..37ef246e 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupFieldsetForm.php @@ -21,20 +21,20 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $required = FALSE) { - $form['fieldset'] = array( + $form['fieldset'] = [ '#type' => 'fieldset', '#title' => 'Fieldset', '#required' => !empty($required), - ); - $form['meta'] = array( + ]; + $form['meta'] = [ '#type' => 'container', '#title' => 'Group element', '#group' => 'fieldset', - ); - $form['meta']['element'] = array( + ]; + $form['meta']['element'] = [ '#type' => 'textfield', '#title' => 'Nest in container element', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupVerticalTabsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupVerticalTabsForm.php index 842ae9d0..2d2f98bd 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupVerticalTabsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestGroupVerticalTabsForm.php @@ -21,27 +21,27 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['vertical_tabs'] = array( + $form['vertical_tabs'] = [ '#type' => 'vertical_tabs', - ); - $form['meta'] = array( + ]; + $form['meta'] = [ '#type' => 'details', '#title' => 'First group element', '#group' => 'vertical_tabs', - ); - $form['meta']['element'] = array( + ]; + $form['meta']['element'] = [ '#type' => 'textfield', '#title' => 'First nested element in details element', - ); - $form['meta_2'] = array( + ]; + $form['meta_2'] = [ '#type' => 'details', '#title' => 'Second group element', '#group' => 'vertical_tabs', - ); - $form['meta_2']['element_2'] = array( + ]; + $form['meta_2']['element_2'] = [ '#type' => 'textfield', '#title' => 'Second nested element in details element', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php index 2eeaf7f4..8cdac632 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestInputForgeryForm.php @@ -21,22 +21,41 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { // For testing that a user can't submit a value not matching one of the // allowed options. - $form['checkboxes'] = array( + $form['checkboxes'] = [ '#title' => t('Checkboxes'), '#type' => 'checkboxes', - '#options' => array( + '#options' => [ 'one' => 'One', 'two' => 'Two', - ), - ); - $form['submit'] = array( + ], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; + $form['#post_render'][] = [static::class, 'postRender']; return $form; } + /** + * Alters the rendered form to simulate input forgery. + * + * It's necessary to alter the rendered form here because Mink does not + * support manipulating the DOM tree. + * + * @param string $rendered_form + * The rendered form. + * + * @return string + * The modified rendered form. + * + * @see \Drupal\Tests\system\Functional\Form\FormTest::testInputForgery() + */ + public static function postRender($rendered_form) { + return str_replace('value="two"', 'value="FORGERY"', $rendered_form); + } + /** * {@inheritdoc} */ diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestLabelForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestLabelForm.php index 1adaa18c..74c92ab6 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestLabelForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestLabelForm.php @@ -21,108 +21,108 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['form_checkboxes_test'] = array( + $form['form_checkboxes_test'] = [ '#type' => 'checkboxes', '#title' => t('Checkboxes test'), - '#options' => array( + '#options' => [ 'first-checkbox' => t('First checkbox'), 'second-checkbox' => t('Second checkbox'), 'third-checkbox' => t('Third checkbox'), '0' => t('0'), - ), - ); - $form['form_radios_test'] = array( + ], + ]; + $form['form_radios_test'] = [ '#type' => 'radios', '#title' => t('Radios test'), - '#options' => array( + '#options' => [ 'first-radio' => t('First radio'), 'second-radio' => t('Second radio'), 'third-radio' => t('Third radio'), '0' => t('0'), - ), + ], // Test #field_prefix and #field_suffix placement. '#field_prefix' => '' . t('Radios #field_prefix element') . '', '#field_suffix' => '' . t('Radios #field_suffix element') . '', - ); - $form['form_checkbox_test'] = array( + ]; + $form['form_checkbox_test'] = [ '#type' => 'checkbox', '#title' => t('Checkbox test'), - ); - $form['form_textfield_test_title_and_required'] = array( + ]; + $form['form_textfield_test_title_and_required'] = [ '#type' => 'textfield', '#title' => t('Textfield test for required with title'), '#required' => TRUE, - ); - $form['form_textfield_test_no_title_required'] = array( + ]; + $form['form_textfield_test_no_title_required'] = [ '#type' => 'textfield', // We use an empty title, since not setting #title suppresses the label // and required marker. '#title' => '', '#required' => TRUE, - ); - $form['form_textfield_test_title'] = array( + ]; + $form['form_textfield_test_title'] = [ '#type' => 'textfield', '#title' => t('Textfield test for title only'), // Not required. // Test #prefix and #suffix placement. '#prefix' => '
    ' . t('Textfield #prefix element') . '
    ', '#suffix' => '
    ' . t('Textfield #suffix element') . '
    ', - ); - $form['form_textfield_test_title_after'] = array( + ]; + $form['form_textfield_test_title_after'] = [ '#type' => 'textfield', '#title' => t('Textfield test for title after element'), '#title_display' => 'after', - ); - $form['form_textfield_test_title_invisible'] = array( + ]; + $form['form_textfield_test_title_invisible'] = [ '#type' => 'textfield', '#title' => t('Textfield test for invisible title'), '#title_display' => 'invisible', - ); + ]; // Textfield test for title set not to display. - $form['form_textfield_test_title_no_show'] = array( + $form['form_textfield_test_title_no_show'] = [ '#type' => 'textfield', - ); + ]; // Checkboxes & radios with title as attribute. - $form['form_checkboxes_title_attribute'] = array( + $form['form_checkboxes_title_attribute'] = [ '#type' => 'checkboxes', '#title' => 'Checkboxes test', '#title_display' => 'attribute', - '#options' => array( + '#options' => [ 'first-checkbox' => 'First checkbox', 'second-checkbox' => 'Second checkbox', - ), + ], '#required' => TRUE, - ); - $form['form_radios_title_attribute'] = array( + ]; + $form['form_radios_title_attribute'] = [ '#type' => 'radios', '#title' => 'Radios test', '#title_display' => 'attribute', - '#options' => array( + '#options' => [ 'first-radio' => 'First radio', 'second-radio' => 'Second radio', - ), + ], '#required' => TRUE, - ); - $form['form_checkboxes_title_invisible'] = array( + ]; + $form['form_checkboxes_title_invisible'] = [ '#type' => 'checkboxes', '#title' => 'Checkboxes test invisible', '#title_display' => 'invisible', - '#options' => array( + '#options' => [ 'first-checkbox' => 'First checkbox', 'second-checkbox' => 'Second checkbox', - ), + ], '#required' => TRUE, - ); - $form['form_radios_title_invisible'] = array( + ]; + $form['form_radios_title_invisible'] = [ '#type' => 'radios', '#title' => 'Radios test invisible', '#title_display' => 'invisible', - '#options' => array( + '#options' => [ 'first-radio' => 'First radio', 'second-radio' => 'Second radio', - ), + ], '#required' => TRUE, - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php index 04794504..ba41e19f 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php @@ -23,38 +23,38 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['languages_all'] = array( + $form['languages_all'] = [ '#title' => t('Languages: All'), '#type' => 'language_select', '#languages' => LanguageInterface::STATE_ALL, '#default_value' => 'xx', - ); - $form['languages_configurable'] = array( + ]; + $form['languages_configurable'] = [ '#title' => t('Languages: Configurable'), '#type' => 'language_select', '#languages' => LanguageInterface::STATE_CONFIGURABLE, '#default_value' => 'en', - ); - $form['languages_locked'] = array( + ]; + $form['languages_locked'] = [ '#title' => t('Languages: Locked'), '#type' => 'language_select', '#languages' => LanguageInterface::STATE_LOCKED, - ); - $form['languages_config_and_locked'] = array( + ]; + $form['languages_config_and_locked'] = [ '#title' => t('Languages: Configurable and locked'), '#type' => 'language_select', '#languages' => LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_LOCKED, '#default_value' => 'dummy_value', - ); - $form['language_custom_options'] = array( + ]; + $form['language_custom_options'] = [ '#title' => t('Languages: Custom'), '#type' => 'language_select', '#languages' => LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_LOCKED, - '#options' => array('opt1' => 'First option', 'opt2' => 'Second option', 'opt3' => 'Third option'), + '#options' => ['opt1' => 'First option', 'opt2' => 'Second option', 'opt3' => 'Third option'], '#default_value' => 'opt2', - ); + ]; - $form['submit'] = array('#type' => 'submit', '#value' => 'Submit'); + $form['submit'] = ['#type' => 'submit', '#value' => 'Submit']; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestLimitValidationErrorsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestLimitValidationErrorsForm.php index 2cb22936..deff0b49 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestLimitValidationErrorsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestLimitValidationErrorsForm.php @@ -21,62 +21,62 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['title'] = array( + $form['title'] = [ '#type' => 'textfield', '#title' => 'Title', '#required' => TRUE, - ); + ]; - $form['test'] = array( + $form['test'] = [ '#title' => 'Test', '#type' => 'textfield', - '#element_validate' => array('::elementValidateLimitValidationErrors'), - ); - $form['test_numeric_index'] = array( + '#element_validate' => ['::elementValidateLimitValidationErrors'], + ]; + $form['test_numeric_index'] = [ '#tree' => TRUE, - ); - $form['test_numeric_index'][0] = array( + ]; + $form['test_numeric_index'][0] = [ '#title' => 'Test (numeric index)', '#type' => 'textfield', - '#element_validate' => array('::elementValidateLimitValidationErrors'), - ); + '#element_validate' => ['::elementValidateLimitValidationErrors'], + ]; - $form['test_substring'] = array( + $form['test_substring'] = [ '#tree' => TRUE, - ); - $form['test_substring']['foo'] = array( + ]; + $form['test_substring']['foo'] = [ '#title' => 'Test (substring) foo', '#type' => 'textfield', - '#element_validate' => array('::elementValidateLimitValidationErrors'), - ); - $form['test_substring']['foobar'] = array( + '#element_validate' => ['::elementValidateLimitValidationErrors'], + ]; + $form['test_substring']['foobar'] = [ '#title' => 'Test (substring) foobar', '#type' => 'textfield', - '#element_validate' => array('::elementValidateLimitValidationErrors'), - ); + '#element_validate' => ['::elementValidateLimitValidationErrors'], + ]; - $form['actions']['partial'] = array( + $form['actions']['partial'] = [ '#type' => 'submit', - '#limit_validation_errors' => array(array('test')), - '#submit' => array('::partialSubmitForm'), + '#limit_validation_errors' => [['test']], + '#submit' => ['::partialSubmitForm'], '#value' => t('Partial validate'), - ); - $form['actions']['partial_numeric_index'] = array( + ]; + $form['actions']['partial_numeric_index'] = [ '#type' => 'submit', - '#limit_validation_errors' => array(array('test_numeric_index', 0)), - '#submit' => array('::partialSubmitForm'), + '#limit_validation_errors' => [['test_numeric_index', 0]], + '#submit' => ['::partialSubmitForm'], '#value' => t('Partial validate (numeric index)'), - ); - $form['actions']['substring'] = array( + ]; + $form['actions']['substring'] = [ '#type' => 'submit', - '#limit_validation_errors' => array(array('test_substring', 'foo')), - '#submit' => array('::partialSubmitForm'), + '#limit_validation_errors' => [['test_substring', 'foo']], + '#submit' => ['::partialSubmitForm'], '#value' => t('Partial validate (substring)'), - ); - $form['actions']['full'] = array( + ]; + $form['actions']['full'] = [ '#type' => 'submit', '#value' => t('Full validate'), - ); + ]; return $form; } @@ -85,7 +85,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { */ public function elementValidateLimitValidationErrors($element, FormStateInterface $form_state) { if ($element['#value'] == 'invalid') { - $form_state->setError($element, t('@label element is invalid', array('@label' => $element['#title']))); + $form_state->setError($element, t('@label element is invalid', ['@label' => $element['#title']])); } } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestNumberForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestNumberForm.php index 6b9520bf..ab281462 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestNumberForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestNumberForm.php @@ -21,114 +21,114 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $element = 'number') { - $base = array( + $base = [ '#type' => $element, - ); + ]; - $form['integer_no_number'] = $base + array( + $form['integer_no_number'] = $base + [ '#title' => 'Integer test, #no_error', '#default_value' => '#no_number', - ); - $form['integer_no_step'] = $base + array( + ]; + $form['integer_no_step'] = $base + [ '#title' => 'Integer test without step', '#default_value' => 5, - ); - $form['integer_no_step_step_error'] = $base + array( + ]; + $form['integer_no_step_step_error'] = $base + [ '#title' => 'Integer test without step, #step_error', '#default_value' => 4.5, - ); - $form['integer_step'] = $base + array( + ]; + $form['integer_step'] = $base + [ '#title' => 'Integer test with step', '#default_value' => 5, '#step' => 1, - ); - $form['integer_step_error'] = $base + array( + ]; + $form['integer_step_error'] = $base + [ '#title' => 'Integer test, with step, #step_error', '#default_value' => 5, '#step' => 2, - ); - $form['integer_step_min'] = $base + array( + ]; + $form['integer_step_min'] = $base + [ '#title' => 'Integer test with min value', '#default_value' => 5, '#min' => 0, '#step' => 1, - ); - $form['integer_step_min_error'] = $base + array( + ]; + $form['integer_step_min_error'] = $base + [ '#title' => 'Integer test with min value, #min_error', '#default_value' => 5, '#min' => 6, '#step' => 1, - ); - $form['integer_step_max'] = $base + array( + ]; + $form['integer_step_max'] = $base + [ '#title' => 'Integer test with max value', '#default_value' => 5, '#max' => 6, '#step' => 1, - ); - $form['integer_step_max_error'] = $base + array( + ]; + $form['integer_step_max_error'] = $base + [ '#title' => 'Integer test with max value, #max_error', '#default_value' => 5, '#max' => 4, '#step' => 1, - ); - $form['integer_step_min_border'] = $base + array( + ]; + $form['integer_step_min_border'] = $base + [ '#title' => 'Integer test with min border check', '#default_value' => -1, '#min' => -1, '#step' => 1, - ); - $form['integer_step_max_border'] = $base + array( + ]; + $form['integer_step_max_border'] = $base + [ '#title' => 'Integer test with max border check', '#default_value' => 5, '#max' => 5, '#step' => 1, - ); - $form['integer_step_based_on_min'] = $base + array( + ]; + $form['integer_step_based_on_min'] = $base + [ '#title' => 'Integer test with step based on min check', '#default_value' => 3, '#min' => -1, '#step' => 2, - ); - $form['integer_step_based_on_min_error'] = $base + array( + ]; + $form['integer_step_based_on_min_error'] = $base + [ '#title' => 'Integer test with step based on min check, #step_error', '#default_value' => 4, '#min' => -1, '#step' => 2, - ); - $form['float_small_step'] = $base + array( + ]; + $form['float_small_step'] = $base + [ '#title' => 'Float test with a small step', '#default_value' => 4, '#step' => 0.0000000000001, - ); - $form['float_step_no_error'] = $base + array( + ]; + $form['float_step_no_error'] = $base + [ '#title' => 'Float test', '#default_value' => 1.2, '#step' => 0.3, - ); - $form['float_step_error'] = $base + array( + ]; + $form['float_step_error'] = $base + [ '#title' => 'Float test, #step_error', '#default_value' => 1.3, '#step' => 0.3, - ); - $form['float_step_hard_no_error'] = $base + array( + ]; + $form['float_step_hard_no_error'] = $base + [ '#title' => 'Float test hard', '#default_value' => 0.9411764729088, '#step' => 0.00392156863712, - ); - $form['float_step_hard_error'] = $base + array( + ]; + $form['float_step_hard_error'] = $base + [ '#title' => 'Float test hard, #step_error', '#default_value' => 0.9411764, '#step' => 0.00392156863, - ); - $form['float_step_any_no_error'] = $base + array( + ]; + $form['float_step_any_no_error'] = $base + [ '#title' => 'Arbitrary float', '#default_value' => 0.839562930284, '#step' => 'aNy', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestPatternForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestPatternForm.php index 57801726..9180628b 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestPatternForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestPatternForm.php @@ -21,34 +21,34 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['textfield'] = array( + $form['textfield'] = [ '#type' => 'textfield', '#title' => 'One digit followed by lowercase letters', '#pattern' => '[0-9][a-z]+', - ); - $form['tel'] = array( + ]; + $form['tel'] = [ '#type' => 'tel', '#title' => 'Everything except numbers', '#pattern' => '[^\d]*', - ); - $form['password'] = array( + ]; + $form['password'] = [ '#type' => 'password', '#title' => 'Password', '#pattern' => '[01]+', - ); - $form['url'] = array( + ]; + $form['url'] = [ '#type' => 'url', '#title' => 'Client side validation', '#decription' => 'Just client side validation, using the #pattern attribute.', - '#attributes' => array( + '#attributes' => [ 'pattern' => '.*foo.*', - ), + ], '#pattern' => 'ignored', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestPlaceholderForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestPlaceholderForm.php index 21a50ff9..9dd53219 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestPlaceholderForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestPlaceholderForm.php @@ -21,12 +21,12 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - foreach (array('textfield', 'textarea', 'url', 'password', 'search', 'tel', 'email', 'number') as $type) { - $form[$type] = array( + foreach (['textfield', 'textarea', 'url', 'password', 'search', 'tel', 'email', 'number'] as $type) { + $form[$type] = [ '#type' => $type, '#title' => $type, '#placeholder' => 'placeholder-text', - ); + ]; } return $form; diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php index 1e7a0146..66928f04 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestProgrammaticForm.php @@ -21,61 +21,61 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['textfield'] = array( + $form['textfield'] = [ '#title' => 'Textfield', '#type' => 'textfield', - ); + ]; - $form['checkboxes'] = array( + $form['checkboxes'] = [ '#title' => t('Checkboxes'), '#type' => 'checkboxes', - '#options' => array( + '#options' => [ 1 => 'First checkbox', 2 => 'Second checkbox', - ), + ], // Both checkboxes are selected by default so that we can test the ability // of programmatic form submissions to uncheck them. - '#default_value' => array(1, 2), - ); + '#default_value' => [1, 2], + ]; - $form['field_to_validate'] = array( + $form['field_to_validate'] = [ '#type' => 'radios', '#title' => 'Field to validate (in the case of limited validation)', '#description' => 'If the form is submitted by clicking the "Submit with limited validation" button, then validation can be limited based on the value of this radio button.', - '#options' => array( + '#options' => [ 'all' => 'Validate all fields', 'textfield' => 'Validate the "Textfield" field', 'field_to_validate' => 'Validate the "Field to validate" field', - ), + ], '#default_value' => 'all', - ); + ]; - $form['field_restricted'] = array( + $form['field_restricted'] = [ '#type' => 'textfield', '#title' => 'Textfield (no access)', '#access' => FALSE, - ); + ]; // The main submit button for the form. - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; // A secondary submit button that allows validation to be limited based on // the value of the above radio selector. - $form['submit_limit_validation'] = array( + $form['submit_limit_validation'] = [ '#type' => 'submit', '#value' => 'Submit with limited validation', // Use the same submit handler for this button as for the form itself. // (This must be set explicitly or otherwise the form API will ignore the // #limit_validation_errors property.) - '#submit' => array('::submitForm'), - ); + '#submit' => ['::submitForm'], + ]; $user_input = $form_state->getUserInput(); if (!empty($user_input['field_to_validate']) && $user_input['field_to_validate'] != 'all') { - $form['submit_limit_validation']['#limit_validation_errors'] = array( - array($user_input['field_to_validate']), - ); + $form['submit_limit_validation']['#limit_validation_errors'] = [ + [$user_input['field_to_validate']], + ]; } return $form; diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRadiosCheckedForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRadiosCheckedForm.php new file mode 100644 index 00000000..efb1d4d4 --- /dev/null +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRadiosCheckedForm.php @@ -0,0 +1,151 @@ + 'radios', + '#title' => 'Radios', + '#options' => [ + 0 => 'Zero', + 'foo' => 'Foo', + 1 => 'One', + 'bar' => 'Bar - radios', + '>' => "Special Char", + ], + '#default_value' => 0, + ]; + $form['radios-string'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 0 => 'Zero', + 'foo' => 'Foo', + 1 => 'One', + 'bar' => 'Bar - radios', + '>' => "Special Char", + ], + '#default_value' => 'bar', + ]; + $form['radios-boolean-true'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + 1 => 'True', + 0 => 'False', + ], + '#default_value' => TRUE, + ]; + $form['radios-boolean-false'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + 1 => 'True', + 0 => 'False', + ], + '#default_value' => FALSE, + ]; + $form['radios-boolean-any'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + 1 => 'True', + 0 => 'False', + ], + '#default_value' => 'All', + ]; + $form['radios-string-zero'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + '0' => 'Zero', + 100 => 'One hundred', + ], + '#default_value' => 0, + ]; + $form['radios-int-non-zero'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + 0 => 'Zero', + 10 => 'Ten', + 100 => 'One hundred', + ], + '#default_value' => 10, + ]; + $form['radios-int-non-zero-as-string'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + '0' => 'Zero', + '10' => 'Ten', + '100' => 'One hundred', + ], + '#default_value' => '100', + ]; + $form['radios-empty-string'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + 0 => 'None', + ], + '#default_value' => '', + ]; + $form['radios-empty-array'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + 0 => 'None', + ], + '#default_value' => [], + ]; + $form['radios-key-FALSE'] = [ + '#type' => 'radios', + '#title' => 'Radios', + '#options' => [ + 'All' => '- Any -', + FALSE => 'False', + ], + '#default_value' => '', + ]; + + $form['submit'] = ['#type' => 'submit', '#value' => 'Submit']; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $form_state->setResponse(new JsonResponse($form_state->getValues())); + } + +} diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php index 25cdc3e4..94240e5e 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php @@ -22,7 +22,7 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['with_default_value'] = array( + $form['with_default_value'] = [ '#type' => 'range', '#title' => 'Range with default value', '#min' => 10, @@ -30,34 +30,34 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#step' => 2, '#default_value' => 18, '#description' => 'The default value is 18.', - ); - $form['float'] = array( + ]; + $form['float'] = [ '#type' => 'range', '#title' => 'Float', '#min' => 10, '#max' => 11, '#step' => 'any', '#description' => 'Floating point number between 10 and 11.', - ); - $form['integer'] = array( + ]; + $form['integer'] = [ '#type' => 'range', '#title' => 'Integer', '#min' => 2, '#max' => 8, '#step' => 2, '#description' => 'Even integer between 2 and 8.', - ); - $form['offset'] = array( + ]; + $form['offset'] = [ '#type' => 'range', '#title' => 'Offset', '#min' => 2.9, '#max' => 10.9, '#description' => 'Value between 2.9 and 10.9.', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeInvalidForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeInvalidForm.php index 49bb0b9b..54152058 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeInvalidForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeInvalidForm.php @@ -21,17 +21,17 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['minmax'] = array( + $form['minmax'] = [ '#type' => 'range', '#min' => 10, '#max' => 5, '#title' => 'Invalid range', '#description' => 'Minimum greater than maximum.', - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php index d0d520ec..58934a78 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php @@ -23,58 +23,58 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { // Start the form with two checkboxes, to test different defaults, and a // textfield, to test more than one element type. - $form = array( - 'checkbox_1_default_off' => array( + $form = [ + 'checkbox_1_default_off' => [ '#type' => 'checkbox', '#title' => t('This checkbox defaults to unchecked'), '#default_value' => FALSE, - ), - 'checkbox_1_default_on' => array( + ], + 'checkbox_1_default_on' => [ '#type' => 'checkbox', '#title' => t('This checkbox defaults to checked'), '#default_value' => TRUE, - ), - 'text_1' => array( + ], + 'text_1' => [ '#type' => 'textfield', '#title' => t('This textfield has a non-empty default value.'), '#default_value' => 'DEFAULT 1', - ), - ); + ], + ]; // Provide an 'add more' button that rebuilds the form with an additional two // checkboxes and a textfield. The test is to make sure that the rebuild // triggered by this button preserves the user input values for the initial // elements and initializes the new elements with the correct default values. if (!$form_state->has('add_more')) { - $form['add_more'] = array( + $form['add_more'] = [ '#type' => 'submit', '#value' => 'Add more', - '#submit' => array('::addMoreSubmitForm'), - ); + '#submit' => ['::addMoreSubmitForm'], + ]; } else { - $form += array( - 'checkbox_2_default_off' => array( + $form += [ + 'checkbox_2_default_off' => [ '#type' => 'checkbox', '#title' => t('This checkbox defaults to unchecked'), '#default_value' => FALSE, - ), - 'checkbox_2_default_on' => array( + ], + 'checkbox_2_default_on' => [ '#type' => 'checkbox', '#title' => t('This checkbox defaults to checked'), '#default_value' => TRUE, - ), - 'text_2' => array( + ], + 'text_2' => [ '#type' => 'textfield', '#title' => t('This textfield has a non-empty default value.'), '#default_value' => 'DEFAULT 2', - ), - ); + ], + ]; } // A submit button that finishes the form workflow (does not rebuild). - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } @@ -92,7 +92,7 @@ public function addMoreSubmitForm(array &$form, FormStateInterface $form_state) */ public function submitForm(array &$form, FormStateInterface $form_state) { // Finish the workflow. Do not rebuild. - drupal_set_message(t('Form values: %values', array('%values' => var_export($form_state->getValues(), TRUE)))); + drupal_set_message(t('Form values: %values', ['%values' => var_export($form_state->getValues(), TRUE)])); } } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php index c540fb75..4768acf9 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRedirectForm.php @@ -22,23 +22,23 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['redirection'] = array( + $form['redirection'] = [ '#type' => 'checkbox', '#title' => t('Use redirection'), - ); - $form['destination'] = array( + ]; + $form['destination'] = [ '#type' => 'textfield', '#title' => t('Redirect destination'), - '#states' => array( - 'visible' => array( - ':input[name="redirection"]' => array('checked' => TRUE), - ), - ), - ); - $form['submit'] = array( + '#states' => [ + 'visible' => [ + ':input[name="redirection"]' => ['checked' => TRUE], + ], + ], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php index f11c3caf..b0aa1b00 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php @@ -21,17 +21,17 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - foreach (array('textfield', 'textarea', 'password') as $type) { - $form[$type] = array( + foreach (['textfield', 'textarea', 'password'] as $type) { + $form[$type] = [ '#type' => $type, '#required' => TRUE, '#title' => $type, - ); + ]; } - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestResponseForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestResponseForm.php index 47bc1b99..0ab3a0d2 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestResponseForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestResponseForm.php @@ -22,19 +22,19 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['content'] = array( + $form['content'] = [ '#type' => 'textfield', '#title' => 'Content', - ); - $form['status'] = array( + ]; + $form['status'] = [ '#type' => 'textfield', '#title' => 'Status', '#default_value' => 200, - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php index 76cdc1ac..a922d2a8 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php @@ -22,100 +22,108 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $base = array( + $base = [ '#type' => 'select', - '#options' => array('one' => 'one', 'two' => 'two', 'three' => 'three', 'four' => 'four'), - ); + '#options' => ['one' => 'one', 'two' => 'two', 'three' => 'three', 'four' => 'four'], + ]; - $form['select'] = $base + array( + $form['select'] = $base + [ '#title' => '#default_value one', '#default_value' => 'one', - ); - $form['select_required'] = $base + array( + ]; + $form['select_required'] = $base + [ '#title' => '#default_value one, #required', '#required' => TRUE, '#default_value' => 'one', - ); - $form['select_optional'] = $base + array( + ]; + $form['select_optional'] = $base + [ '#title' => '#default_value one, not #required', '#required' => FALSE, '#default_value' => 'one', - ); - $form['empty_value'] = $base + array( + ]; + $form['empty_value'] = $base + [ '#title' => '#default_value one, #required, #empty_value 0', '#required' => TRUE, '#default_value' => 'one', '#empty_value' => 0, - ); - $form['empty_value_one'] = $base + array( + ]; + $form['empty_value_one'] = $base + [ '#title' => '#default_value = #empty_value, #required', '#required' => TRUE, '#default_value' => 'one', '#empty_value' => 'one', - ); + ]; - $form['no_default'] = $base + array( + $form['no_default'] = $base + [ '#title' => 'No #default_value, #required', '#required' => TRUE, - ); - $form['no_default_optional'] = $base + array( + ]; + $form['no_default_optional'] = $base + [ '#title' => 'No #default_value, not #required', '#required' => FALSE, '#description' => 'Should result in "one" because it is not required and there is no #empty_value requested, so default browser behavior of preselecting first option is in effect.', - ); - $form['no_default_optional_empty_value'] = $base + array( + ]; + $form['no_default_optional_empty_value'] = $base + [ '#title' => 'No #default_value, not #required, #empty_value empty string', '#empty_value' => '', '#required' => FALSE, '#description' => 'Should result in an empty string (due to #empty_value) because it is optional.', - ); + ]; - $form['no_default_empty_option'] = $base + array( + $form['no_default_empty_option'] = $base + [ '#title' => 'No #default_value, #required, #empty_option', '#required' => TRUE, '#empty_option' => '- Choose -', - ); - $form['no_default_empty_option_optional'] = $base + array( + ]; + $form['no_default_empty_option_optional'] = $base + [ '#title' => 'No #default_value, not #required, #empty_option', '#empty_option' => '- Dismiss -', '#description' => 'Should result in an empty string (default of #empty_value) because it is optional.', - ); + ]; - $form['no_default_empty_value'] = $base + array( + $form['no_default_empty_value'] = $base + [ '#title' => 'No #default_value, #required, #empty_value 0', '#required' => TRUE, '#empty_value' => 0, '#description' => 'Should never result in 0.', - ); - $form['no_default_empty_value_one'] = $base + array( + ]; + $form['no_default_empty_value_one'] = $base + [ '#title' => 'No #default_value, #required, #empty_value one', '#required' => TRUE, '#empty_value' => 'one', '#description' => 'A mistakenly assigned #empty_value contained in #options should not be valid.', - ); - $form['no_default_empty_value_optional'] = $base + array( + ]; + $form['no_default_empty_value_optional'] = $base + [ '#title' => 'No #default_value, not #required, #empty_value 0', '#required' => FALSE, '#empty_value' => 0, '#description' => 'Should result in 0 because it is optional.', - ); + ]; - $form['multiple'] = $base + array( + $form['multiple'] = $base + [ '#title' => '#multiple, #default_value two', - '#default_value' => array('two'), + '#default_value' => ['two'], '#multiple' => TRUE, - ); - $form['multiple_no_default'] = $base + array( + ]; + $form['multiple_no_default'] = $base + [ '#title' => '#multiple, no #default_value', '#multiple' => TRUE, - ); - $form['multiple_no_default_required'] = $base + array( + ]; + $form['multiple_no_default_required'] = $base + [ '#title' => '#multiple, #required, no #default_value', '#required' => TRUE, '#multiple' => TRUE, - ); + ]; - $form['submit'] = array('#type' => 'submit', '#value' => 'Submit'); + $form['opt_groups'] = [ + '#type' => 'select', + '#options' => [ + 'optgroup_one' => ['one' => 'one', 'two' => 'two', 'three' => 'three', 'four' => 'four'], + 'optgroup_two' => ['five' => 'five', 'six' => 'six'], + ], + ]; + + $form['submit'] = ['#type' => 'submit', '#value' => 'Submit']; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php index 2640805c..e34af83b 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStatePersistForm.php @@ -21,18 +21,18 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['title'] = array( + $form['title'] = [ '#type' => 'textfield', '#title' => 'title', '#default_value' => 'DEFAULT', '#required' => TRUE, - ); + ]; $form_state->set('value', 'State persisted.'); - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php index 948c592c..91870129 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php @@ -28,7 +28,7 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state) { if ($form_state->isRebuilding()) { - $form_state->setUserInput(array()); + $form_state->setUserInput([]); } // Initialize $storage = $form_state->getStorage(); @@ -50,32 +50,32 @@ public function buildForm(array $form, FormStateInterface $form_state) { $_SESSION['constructions']++; drupal_set_message("Form constructions: " . $_SESSION['constructions']); - $form['title'] = array( + $form['title'] = [ '#type' => 'textfield', '#title' => 'Title', '#default_value' => $storage['thing']['title'], '#required' => TRUE, - ); - $form['value'] = array( + ]; + $form['value'] = [ '#type' => 'textfield', '#title' => 'Value', '#default_value' => $storage['thing']['value'], - '#element_validate' => array('::elementValidateValueCached'), - ); - $form['continue_button'] = array( + '#element_validate' => ['::elementValidateValueCached'], + ]; + $form['continue_button'] = [ '#type' => 'button', '#value' => 'Reset', // Rebuilds the form without keeping the values. - ); - $form['continue_submit'] = array( + ]; + $form['continue_submit'] = [ '#type' => 'submit', '#value' => 'Continue submit', - '#submit' => array('::continueSubmitForm'), - ); - $form['submit'] = array( + '#submit' => ['::continueSubmitForm'], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Save', - ); + ]; // @todo Remove this in https://www.drupal.org/node/2524408, because form // cache immutability is no longer necessary, because we no longer cache @@ -86,7 +86,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { // that issue. if ($this->getRequest()->get('immutable')) { $form_state->addBuildInfo('immutable', TRUE); - if ($this->getRequest()->get('cache') && $this->getRequest()->isMethodSafe()) { + if ($this->getRequest()->get('cache') && $this->getRequest()->isMethodCacheable()) { $form_state->setRequestMethod('FAKE'); $form_state->setCached(); } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php index e7abbfdd..f27e5e06 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php @@ -18,30 +18,30 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['title'] = array( + $form['title'] = [ '#type' => 'textfield', '#title' => 'Title', '#required' => TRUE, - ); + ]; - $form['test_build_id_old'] = array( + $form['test_build_id_old'] = [ '#type' => 'item', '#title' => 'Old build id', '#markup' => 'No old build id', - ); + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => 'Save', - ); + ]; - $form['rebuild'] = array( + $form['rebuild'] = [ '#type' => 'submit', '#value' => 'Rebuild', - '#submit' => array(array($this, 'form_test_storage_page_cache_rebuild')), - ); + '#submit' => [[$this, 'form_test_storage_page_cache_rebuild']], + ]; - $form['#after_build'] = array(array($this, 'form_test_storage_page_cache_old_build_id')); + $form['#after_build'] = [[$this, 'form_test_storage_page_cache_old_build_id']]; return $form; } @@ -49,7 +49,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { /** * Form element #after_build callback: output the old form build-id. */ - function form_test_storage_page_cache_old_build_id($form) { + public function form_test_storage_page_cache_old_build_id($form) { if (isset($form['#build_id_old'])) { $form['test_build_id_old']['#plain_text'] = $form['#build_id_old']; } @@ -59,7 +59,7 @@ function form_test_storage_page_cache_old_build_id($form) { /** * Form submit callback: Rebuild the form and continue. */ - function form_test_storage_page_cache_rebuild($form, FormStateInterface $form_state) { + public function form_test_storage_page_cache_rebuild($form, FormStateInterface $form_state) { $form_state->setRebuild(); } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectColspanForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectColspanForm.php index bae573ec..1c9628bc 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectColspanForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectColspanForm.php @@ -20,20 +20,20 @@ public function buildForm(array $form, FormStateInterface $form_state) { list($header, $options) = _form_test_tableselect_get_data(); // Change the data so that the third column has colspan=2. - $header['three'] = array('data' => 'Three', 'colspan' => 2); + $header['three'] = ['data' => 'Three', 'colspan' => 2]; unset($header['four']); // Set the each row so that column 3 is an array. foreach ($options as $name => $row) { - $options[$name]['three'] = array($row['three'], $row['four']); + $options[$name]['three'] = [$row['three'], $row['four']]; unset($options[$name]['four']); } // Combine cells in row 3. - $options['row3']['one'] = array('data' => $options['row3']['one'], 'colspan' => 2); + $options['row3']['one'] = ['data' => $options['row3']['one'], 'colspan' => 2]; unset($options['row3']['two']); - $options['row3']['three'] = array('data' => $options['row3']['three'][0], 'colspan' => 2); + $options['row3']['three'] = ['data' => $options['row3']['three'][0], 'colspan' => 2]; unset($options['row3']['four']); - return $this->tableselectFormBuilder($form, $form_state, array('#header' => $header, '#options' => $options)); + return $this->tableselectFormBuilder($form, $form_state, ['#header' => $header, '#options' => $options]); } /** diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectEmptyForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectEmptyForm.php index d7954f15..199a7d3e 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectEmptyForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectEmptyForm.php @@ -17,7 +17,7 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - return $this->tableselectFormBuilder($form, $form_state, array('#options' => array())); + return $this->tableselectFormBuilder($form, $form_state, ['#options' => []]); } /** diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php index 4431460d..9a1dc2e6 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php @@ -23,12 +23,12 @@ abstract class FormTestTableSelectFormBase extends FormBase { * @return array * A form with a tableselect element and a submit button. */ - function tableselectFormBuilder($form, FormStateInterface $form_state, $element_properties) { + public function tableselectFormBuilder($form, FormStateInterface $form_state, $element_properties) { list($header, $options) = _form_test_tableselect_get_data(); $form['tableselect'] = $element_properties; - $form['tableselect'] += array( + $form['tableselect'] += [ '#prefix' => '
    ', '#suffix' => '
    ', '#type' => 'tableselect', @@ -36,16 +36,16 @@ function tableselectFormBuilder($form, FormStateInterface $form_state, $element_ '#options' => $options, '#multiple' => FALSE, '#empty' => t('Empty text.'), - '#ajax' => array( + '#ajax' => [ 'callback' => 'form_test_tableselect_ajax_callback', 'wrapper' => 'tableselect-wrapper', - ), - ); + ], + ]; - $form['submit'] = array( + $form['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectJsSelectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectJsSelectForm.php index e5483437..d6d606ae 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectJsSelectForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectJsSelectForm.php @@ -19,19 +19,19 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state, $test_action = NULL) { switch ($test_action) { case 'multiple-true-default': - $options = array('#multiple' => TRUE); + $options = ['#multiple' => TRUE]; break; case 'multiple-false-default': - $options = array('#multiple' => FALSE); + $options = ['#multiple' => FALSE]; break; case 'multiple-true-no-advanced-select': - $options = array('#multiple' => TRUE, '#js_select' => FALSE); + $options = ['#multiple' => TRUE, '#js_select' => FALSE]; break; case 'multiple-false-advanced-select': - $options = array('#multiple' => FALSE, '#js_select' => TRUE); + $options = ['#multiple' => FALSE, '#js_select' => TRUE]; break; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleFalseForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleFalseForm.php index 66fda87b..f21ae3c6 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleFalseForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleFalseForm.php @@ -17,14 +17,14 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - return $this->tableselectFormBuilder($form, $form_state, array('#multiple' => FALSE)); + return $this->tableselectFormBuilder($form, $form_state, ['#multiple' => FALSE]); } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - drupal_set_message(t('Submitted: @value', array('@value' => $form_state->getValue('tableselect')))); + drupal_set_message(t('Submitted: @value', ['@value' => $form_state->getValue('tableselect')])); } } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleTrueForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleTrueForm.php index 5d54b93d..d4a0c1d4 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleTrueForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectMultipleTrueForm.php @@ -17,7 +17,7 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - return $this->tableselectFormBuilder($form, $form_state, array('#multiple' => TRUE)); + return $this->tableselectFormBuilder($form, $form_state, ['#multiple' => TRUE]); } /** @@ -26,7 +26,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { $selected = $form_state->getValue('tableselect'); foreach ($selected as $key => $value) { - drupal_set_message(t('Submitted: @key = @value', array('@key' => $key, '@value' => $value))); + drupal_set_message(t('Submitted: @key = @value', ['@key' => $key, '@value' => $value])); } } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php index 88a66155..fff0e805 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php @@ -22,21 +22,21 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['url'] = array( + $form['url'] = [ '#type' => 'url', '#title' => 'Optional URL', '#description' => 'An optional URL field.', - ); - $form['url_required'] = array( + ]; + $form['url_required'] = [ '#type' => 'url', '#title' => 'Required URL', '#description' => 'A required URL field.', '#required' => TRUE, - ); - $form['submit'] = array( + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Submit', - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php index d17dca4f..41772da2 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateForm.php @@ -33,16 +33,16 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { $object = new Callbacks(); - $form['name'] = array( + $form['name'] = [ '#type' => 'textfield', '#title' => 'Name', '#default_value' => '', - '#element_validate' => array(array($object, 'validateName')), - ); - $form['submit'] = array( + '#element_validate' => [[$object, 'validateName']], + ]; + $form['submit'] = [ '#type' => 'submit', '#value' => 'Save', - ); + ]; return $form; } @@ -57,7 +57,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { // Alter the submitted value in $form_state. $form_state->setValueForElement($form['name'], 'value changed by setValueForElement() in #validate'); // Output the element's value from $form_state. - drupal_set_message(t('@label value: @value', array('@label' => $form['name']['#title'], '@value' => $form_state->getValue('name')))); + drupal_set_message(t('@label value: @value', ['@label' => $form['name']['#title'], '@value' => $form_state->getValue('name')])); // Trigger a form validation error to see our changes. $form_state->setErrorByName(''); diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredForm.php index b5cf6ec8..88e6b353 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredForm.php @@ -21,50 +21,50 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $options = array('foo' => 'foo', 'bar' => 'bar'); - $validate = array('::elementValidateRequired'); + $options = ['foo' => 'foo', 'bar' => 'bar']; + $validate = ['::elementValidateRequired']; - $form['textfield'] = array( + $form['textfield'] = [ '#type' => 'textfield', '#title' => 'Name', '#required' => TRUE, '#required_error' => t('Please enter a name.'), - ); - $form['checkboxes'] = array( + ]; + $form['checkboxes'] = [ '#type' => 'checkboxes', '#title' => 'Checkboxes', '#options' => $options, '#required' => TRUE, '#form_test_required_error' => t('Please choose at least one option.'), '#element_validate' => $validate, - ); - $form['select'] = array( + ]; + $form['select'] = [ '#type' => 'select', '#title' => 'Select', '#options' => $options, '#required' => TRUE, '#form_test_required_error' => t('Please select something.'), '#element_validate' => $validate, - ); - $form['radios'] = array( + ]; + $form['radios'] = [ '#type' => 'radios', '#title' => 'Radios', '#options' => $options, '#required' => TRUE, - ); - $form['radios_optional'] = array( + ]; + $form['radios_optional'] = [ '#type' => 'radios', '#title' => 'Radios (optional)', '#options' => $options, - ); - $form['radios_optional_default_value_false'] = array( + ]; + $form['radios_optional_default_value_false'] = [ '#type' => 'radios', '#title' => 'Radios (optional, with a default value of FALSE)', '#options' => $options, '#default_value' => FALSE, - ); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => 'Submit'); + ]; + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = ['#type' => 'submit', '#value' => 'Submit']; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredNoTitleForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredNoTitleForm.php index 30bd76aa..29b3b5f9 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredNoTitleForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestValidateRequiredNoTitleForm.php @@ -21,12 +21,12 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['textfield'] = array( + $form['textfield'] = [ '#type' => 'textfield', '#required' => TRUE, - ); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => 'Submit'); + ]; + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = ['#type' => 'submit', '#value' => 'Submit']; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php index bab4d192..cb171a66 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php @@ -18,81 +18,81 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['vertical_tabs1'] = array( + $form['vertical_tabs1'] = [ '#type' => 'vertical_tabs', - ); - $form['tab1'] = array( + ]; + $form['tab1'] = [ '#type' => 'fieldset', '#title' => t('Tab 1'), '#collapsible' => TRUE, '#group' => 'vertical_tabs1', - ); - $form['tab1']['field1'] = array( + ]; + $form['tab1']['field1'] = [ '#title' => t('Field 1'), '#type' => 'checkbox', '#default_value' => TRUE, - ); - $form['tab2'] = array( + ]; + $form['tab2'] = [ '#type' => 'fieldset', '#title' => t('Tab 2'), '#collapsible' => TRUE, '#group' => 'vertical_tabs1', - ); - $form['tab2']['field2'] = array( + ]; + $form['tab2']['field2'] = [ '#title' => t('Field 2'), '#type' => 'textfield', '#default_value' => 'field2', - ); + ]; - $form['fieldset1'] = array( + $form['fieldset1'] = [ '#type' => 'fieldset', '#title' => t('Fieldset'), - ); - $form['fieldset1']['field3'] = array( + ]; + $form['fieldset1']['field3'] = [ '#type' => 'checkbox', '#title' => t('Field 3'), '#default_value' => TRUE, - ); + ]; - $form['container'] = array( + $form['container'] = [ '#type' => 'container', - ); - $form['container']['field4'] = array( + ]; + $form['container']['field4'] = [ '#type' => 'checkbox', '#title' => t('Field 4'), '#default_value' => TRUE, - ); - $form['container']['subcontainer'] = array( + ]; + $form['container']['subcontainer'] = [ '#type' => 'container', - ); - $form['container']['subcontainer']['field5'] = array( + ]; + $form['container']['subcontainer']['field5'] = [ '#type' => 'checkbox', '#title' => t('Field 5'), '#default_value' => TRUE, - ); + ]; - $form['vertical_tabs2'] = array( + $form['vertical_tabs2'] = [ '#type' => 'vertical_tabs', - ); - $form['tab3'] = array( + ]; + $form['tab3'] = [ '#type' => 'fieldset', '#title' => t('Tab 3'), '#collapsible' => TRUE, '#group' => 'vertical_tabs2', - ); - $form['tab3']['field6'] = array( + ]; + $form['tab3']['field6'] = [ '#title' => t('Field 6'), '#type' => 'checkbox', '#default_value' => TRUE, - ); + ]; - $form['actions'] = array( + $form['actions'] = [ '#type' => 'actions', - ); - $form['actions']['submit'] = array( + ]; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => t('Submit'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsForm.php index 3457db80..b89636a4 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsForm.php @@ -20,23 +20,23 @@ public function getFormId() { public function buildForm(array $form, FormStateInterface $form_state) { $tab_count = 3; - $form['vertical_tabs'] = array( + $form['vertical_tabs'] = [ '#type' => 'vertical_tabs', '#default_tab' => 'edit-tab' . $tab_count, - ); + ]; for ($i = 1; $i <= $tab_count; $i++) { - $form['tab' . $i] = array( + $form['tab' . $i] = [ '#type' => 'fieldset', - '#title' => t('Tab @num', array('@num' => $i)), + '#title' => t('Tab @num', ['@num' => $i]), '#group' => 'vertical_tabs', '#access' => \Drupal::currentUser()->hasPermission('access vertical_tab_test tabs'), - ); - $form['tab' . $i]['field' . $i] = array( - '#title' => t('Field @num', array('@num' => $i)), + ]; + $form['tab' . $i]['field' . $i] = [ + '#title' => t('Field @num', ['@num' => $i]), '#type' => 'textfield', - ); + ]; } return $form; diff --git a/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php b/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php index 8963462f..163ac227 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/RedirectBlockForm.php @@ -23,8 +23,8 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Submit')); + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = ['#type' => 'submit', '#value' => $this->t('Submit')]; return $form; } @@ -33,7 +33,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - $form_state->setRedirect('form_test.route1', array(), array('query' => array('test1' => 'test2'))); + $form_state->setRedirect('form_test.route1', [], ['query' => ['test1' => 'test2']]); } } diff --git a/core/modules/system/tests/modules/form_test/src/FormTestArgumentsObject.php b/core/modules/system/tests/modules/form_test/src/FormTestArgumentsObject.php index 7bba8e01..7531ca81 100644 --- a/core/modules/system/tests/modules/form_test/src/FormTestArgumentsObject.php +++ b/core/modules/system/tests/modules/form_test/src/FormTestArgumentsObject.php @@ -28,19 +28,19 @@ protected function getEditableConfigNames() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $arg = NULL) { - $form['element'] = array('#markup' => 'The FormTestArgumentsObject::buildForm() method was used for this form.'); + $form['element'] = ['#markup' => 'The FormTestArgumentsObject::buildForm() method was used for this form.']; - $form['bananas'] = array( + $form['bananas'] = [ '#type' => 'textfield', '#default_value' => $arg, '#title' => $this->t('Bananas'), - ); + ]; $form['actions']['#type'] = 'actions'; - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/FormTestAutocompleteForm.php b/core/modules/system/tests/modules/form_test/src/FormTestAutocompleteForm.php index 5b2390ca..019513d0 100644 --- a/core/modules/system/tests/modules/form_test/src/FormTestAutocompleteForm.php +++ b/core/modules/system/tests/modules/form_test/src/FormTestAutocompleteForm.php @@ -21,17 +21,17 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['autocomplete_1'] = array( + $form['autocomplete_1'] = [ '#type' => 'textfield', '#title' => 'Autocomplete 1', '#autocomplete_route_name' => 'form_test.autocomplete_1', - ); - $form['autocomplete_2'] = array( + ]; + $form['autocomplete_2'] = [ '#type' => 'textfield', '#title' => 'Autocomplete 2', '#autocomplete_route_name' => 'form_test.autocomplete_2', - '#autocomplete_route_parameters' => array('param' => 'value'), - ); + '#autocomplete_route_parameters' => ['param' => 'value'], + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php b/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php index 826bf2c2..75732534 100644 --- a/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php +++ b/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php @@ -40,21 +40,21 @@ public static function create(ContainerInterface $container) { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL, $custom_attributes = NULL) { - $form['element'] = array('#markup' => 'The FormTestControllerObject::buildForm() method was used for this form.'); + $form['element'] = ['#markup' => 'The FormTestControllerObject::buildForm() method was used for this form.']; $form['custom_attribute']['#markup'] = $custom_attributes; $form['request_attribute']['#markup'] = $request->attributes->get('request_attribute'); - $form['bananas'] = array( + $form['bananas'] = [ '#type' => 'textfield', '#title' => $this->t('Bananas'), - ); + ]; $form['actions']['#type'] = 'actions'; - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/form_test/src/FormTestObject.php b/core/modules/system/tests/modules/form_test/src/FormTestObject.php index 5fb0dae6..f99fbe73 100644 --- a/core/modules/system/tests/modules/form_test/src/FormTestObject.php +++ b/core/modules/system/tests/modules/form_test/src/FormTestObject.php @@ -28,18 +28,23 @@ protected function getEditableConfigNames() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['element'] = array('#markup' => 'The FormTestObject::buildForm() method was used for this form.'); + $form['element'] = ['#markup' => 'The FormTestObject::buildForm() method was used for this form.']; - $form['bananas'] = array( + $form['bananas'] = [ '#type' => 'textfield', '#title' => $this->t('Bananas'), - ); + ]; + $form['strawberry'] = [ + '#type' => 'hidden', + '#value' => 'red', + '#attributes' => ['id' => 'redstrawberryhiddenfield'], + ]; $form['actions']['#type'] = 'actions'; - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), - ); + ]; $form['#title'] = 'Test dynamic title'; diff --git a/core/modules/system/tests/modules/form_test/src/FormTestServiceObject.php b/core/modules/system/tests/modules/form_test/src/FormTestServiceObject.php index 10ad61b6..effd319b 100644 --- a/core/modules/system/tests/modules/form_test/src/FormTestServiceObject.php +++ b/core/modules/system/tests/modules/form_test/src/FormTestServiceObject.php @@ -28,19 +28,19 @@ protected function getEditableConfigNames() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['element'] = array('#markup' => 'The FormTestServiceObject::buildForm() method was used for this form.'); + $form['element'] = ['#markup' => 'The FormTestServiceObject::buildForm() method was used for this form.']; - $form['bananas'] = array( + $form['bananas'] = [ '#type' => 'textfield', '#default_value' => 'brown', '#title' => $this->t('Bananas'), - ); + ]; $form['actions']['#type'] = 'actions'; - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml b/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml index 15e0c329..df488406 100644 --- a/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml +++ b/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/image_test/image_test.info.yml b/core/modules/system/tests/modules/image_test/image_test.info.yml index 6d01891b..de199bcd 100644 --- a/core/modules/system/tests/modules/image_test/image_test.info.yml +++ b/core/modules/system/tests/modules/image_test/image_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/DerivedToolkit.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/DerivedToolkit.php index 9245662e..55e86497 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/DerivedToolkit.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/DerivedToolkit.php @@ -10,4 +10,4 @@ * title = @Translation("A dummy toolkit, derivative of 'test'.") * ) */ -class DerivedToolkit extends TestToolkit { } +class DerivedToolkit extends TestToolkit {} diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php index eac11b8e..ecd4aaaf 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Bar.php @@ -13,4 +13,4 @@ * description = @Translation("Bar.") * ) */ -class Bar extends OperationBase { } +class Bar extends OperationBase {} diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php index ff05f9b5..3b067d59 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/Foo.php @@ -13,4 +13,4 @@ * description = @Translation("Foo.") * ) */ -class Foo extends OperationBase { } +class Foo extends OperationBase {} diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php index 818a414e..bf38dfdd 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/FooDerived.php @@ -13,4 +13,4 @@ * description = @Translation("Foo derived.") * ) */ -class FooDerived extends OperationBase { } +class FooDerived extends OperationBase {} diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/OperationBase.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/OperationBase.php index 6ac95324..e978f2a0 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/OperationBase.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/Operation/test/OperationBase.php @@ -13,7 +13,7 @@ abstract class OperationBase extends ImageToolkitOperationBase { * {@inheritdoc} */ public function arguments() { - return array(); + return []; } /** diff --git a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php index 9766d099..a0f50804 100644 --- a/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php +++ b/core/modules/system/tests/modules/image_test/src/Plugin/ImageToolkit/TestToolkit.php @@ -92,14 +92,14 @@ public static function create(ContainerInterface $container, array $configuratio */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $this->logCall('settings', func_get_args()); - $form['test_parameter'] = array( + $form['test_parameter'] = [ '#type' => 'number', '#title' => $this->t('Test toolkit parameter'), '#description' => $this->t('A toolkit parameter for testing purposes.'), '#min' => 0, '#max' => 100, '#default_value' => $this->configFactory->getEditable('system.image.test_toolkit')->get('test_parameter', FALSE), - ); + ]; return $form; } @@ -117,7 +117,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { $this->configFactory->getEditable('system.image.test_toolkit') - ->set('test_parameter', $form_state->getValue(array('test', 'test_parameter'))) + ->set('test_parameter', $form_state->getValue(['test', 'test_parameter'])) ->save(); } @@ -161,11 +161,11 @@ public function save($destination) { * @param array $args * Values passed to hook. * - * @see \Drupal\system\Tests\Image\ToolkitTestBase::imageTestReset() - * @see \Drupal\system\Tests\Image\ToolkitTestBase::imageTestGetAllCalls() + * @see \Drupal\Tests\system\Functional\Image\ToolkitTestBase::imageTestReset() + * @see \Drupal\Tests\system\Functional\Image\ToolkitTestBase::imageTestGetAllCalls() */ protected function logCall($op, $args) { - $results = $this->state->get('image_test.results') ?: array(); + $results = $this->state->get('image_test.results') ?: []; $results[$op][] = $args; // A call to apply is also logged under its operation name whereby the // array of arguments are logged as separate arguments, this because at the @@ -236,7 +236,7 @@ public static function isAvailable() { * {@inheritdoc} */ public static function getSupportedExtensions() { - $extensions = array(); + $extensions = []; foreach (static::supportedTypes() as $image_type) { $extensions[] = Unicode::strtolower(image_type_to_extension($image_type, FALSE)); } @@ -251,13 +251,13 @@ public static function getSupportedExtensions() { * IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG, IMAGETYPE_PNG, etc.). */ protected static function supportedTypes() { - return array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF); + return [IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF]; } /** * {@inheritdoc} */ - public function apply($operation, array $arguments = array()) { + public function apply($operation, array $arguments = []) { $this->logCall('apply', func_get_args()); return TRUE; } diff --git a/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml index b57ddef6..8bfbfd2f 100644 --- a/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml +++ b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.es6.js b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.es6.js new file mode 100644 index 00000000..d2e1fea2 --- /dev/null +++ b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.es6.js @@ -0,0 +1,18 @@ +/** + * @file + * Testing behavior for JSWebAssertTest. + */ + +(function ($, Drupal, drupalSettings) { + /** + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Makes changes in the DOM to be able to test the completion of AJAX in assertWaitOnAjaxRequest. + */ + Drupal.behaviors.js_webassert_test_wait_for_ajax_request = { + attach(context) { + $('input[name="test_assert_wait_on_ajax_input"]').val('js_webassert_test'); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.js b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.js index 3fa82d98..3413846d 100644 --- a/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.js +++ b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_ajax_request.js @@ -1,22 +1,14 @@ /** - * @file - * Testing behavior for JSWebAssertTest. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Makes changes in the DOM to be able to test the completion of AJAX in assertWaitOnAjaxRequest. - */ Drupal.behaviors.js_webassert_test_wait_for_ajax_request = { - attach: function (context) { + attach: function attach(context) { $('input[name="test_assert_wait_on_ajax_input"]').val('js_webassert_test'); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.es6.js b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.es6.js new file mode 100644 index 00000000..10d911b9 --- /dev/null +++ b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.es6.js @@ -0,0 +1,18 @@ +/** + * @file + * Testing behavior for JSWebAssertTest. + */ + +(function ($, Drupal, drupalSettings) { + /** + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Makes changes in the DOM to be able to test the completion of AJAX in assertWaitOnAjaxRequest. + */ + Drupal.behaviors.js_webassert_test_wait_for_element = { + attach(context) { + $('#js_webassert_test_element_invisible').show(); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.js b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.js index e11067b2..4ab7ba4e 100644 --- a/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.js +++ b/core/modules/system/tests/modules/js_webassert_test/js/js_webassert_test.wait_for_element.js @@ -1,22 +1,14 @@ /** - * @file - * Testing behavior for JSWebAssertTest. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Makes changes in the DOM to be able to test the completion of AJAX in assertWaitOnAjaxRequest. - */ Drupal.behaviors.js_webassert_test_wait_for_element = { - attach: function (context) { + attach: function attach(context) { $('#js_webassert_test_element_invisible').show(); } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/system/tests/modules/js_webassert_test/js_webassert_test.info.yml b/core/modules/system/tests/modules/js_webassert_test/js_webassert_test.info.yml index d737990f..ff265155 100644 --- a/core/modules/system/tests/modules/js_webassert_test/js_webassert_test.info.yml +++ b/core/modules/system/tests/modules/js_webassert_test/js_webassert_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.info.yml b/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.info.yml index 52cb3977..8cde64f0 100644 --- a/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.info.yml +++ b/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.info.yml @@ -8,8 +8,8 @@ hidden: true dependencies: - entity_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.module b/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.module index ed059960..4316719d 100644 --- a/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.module +++ b/core/modules/system/tests/modules/keyvalue_test/keyvalue_test.module @@ -13,6 +13,7 @@ function keyvalue_test_entity_type_alter(array &$entity_types) { if (isset($entity_types['entity_test_label'])) { $entity_types['entity_test_label']->setStorageClass('Drupal\Core\Entity\KeyValueStore\KeyValueContentEntityStorage'); $entity_keys = $entity_types['entity_test_label']->getKeys(); - $entity_types['entity_test_label']->set('entity_keys', $entity_keys + array('uuid' => 'uuid')); + $entity_types['entity_test_label']->set('entity_keys', $entity_keys + ['uuid' => 'uuid']); + $entity_types['entity_test_label']->set('provider', 'keyvalue_test'); } } diff --git a/core/modules/system/tests/modules/layout_test/config/schema/layout_test.schema.yml b/core/modules/system/tests/modules/layout_test/config/schema/layout_test.schema.yml new file mode 100644 index 00000000..521faafa --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/config/schema/layout_test.schema.yml @@ -0,0 +1,7 @@ +layout_plugin.settings.layout_test_plugin: + type: layout_plugin.settings + label: 'Layout test plugin settings' + mapping: + setting_1: + type: string + label: 'Setting 1' diff --git a/core/modules/system/tests/modules/layout_test/css/layout-test-2col.css b/core/modules/system/tests/modules/layout_test/css/layout-test-2col.css new file mode 100644 index 00000000..ca7e8764 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/css/layout-test-2col.css @@ -0,0 +1,17 @@ +/* stylelint-disable plugin/no-browser-hacks */ +.layout-example-2col .region-left { + float: left; + width: 50%; +} +* html .layout-example-2col .region-left { + width: 49.9%; +} + +.layout-example-2col .region-right { + float: left; + width: 50%; +} +* html .layout-example-2col .region-right { + width: 49.9%; +} +/* stylelint-disable */ diff --git a/core/modules/system/tests/modules/layout_test/layout_test.info.yml b/core/modules/system/tests/modules/layout_test/layout_test.info.yml new file mode 100644 index 00000000..ff0329d2 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/layout_test.info.yml @@ -0,0 +1,12 @@ +name: 'Layout test' +type: module +description: 'Support module for testing layouts.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/layout_test/layout_test.layouts.yml b/core/modules/system/tests/modules/layout_test/layout_test.layouts.yml new file mode 100644 index 00000000..f8fcf5b8 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/layout_test.layouts.yml @@ -0,0 +1,29 @@ +layout_test_1col: + label: 1 column layout + category: Layout test + template: templates/layout-test-1col + regions: + top: + label: Top region + bottom: + label: Bottom region + +layout_test_2col: + label: 2 column layout + category: Layout test + template: templates/layout-test-2col + library: layout_test/layout_test_2col + regions: + left: + label: Left region + right: + label: Right region + +layout_test_1col_no_template: + label: 1 column layout (No template) + category: Layout test + regions: + top: + label: Top region + bottom: + label: Bottom region diff --git a/core/modules/system/tests/modules/layout_test/layout_test.libraries.yml b/core/modules/system/tests/modules/layout_test/layout_test.libraries.yml new file mode 100644 index 00000000..a696c0fc --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/layout_test.libraries.yml @@ -0,0 +1,5 @@ +layout_test_2col: + version: 1.x + css: + theme: + css/layout-test-2col.css: {} diff --git a/core/modules/system/tests/modules/layout_test/layout_test.module b/core/modules/system/tests/modules/layout_test/layout_test.module new file mode 100644 index 00000000..6ebaa254 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/layout_test.module @@ -0,0 +1,13 @@ +addClass('class-added-by-preprocess'); +} diff --git a/core/modules/system/tests/modules/layout_test/src/Plugin/Layout/LayoutTestPlugin.php b/core/modules/system/tests/modules/layout_test/src/Plugin/Layout/LayoutTestPlugin.php new file mode 100644 index 00000000..e678bfa6 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/src/Plugin/Layout/LayoutTestPlugin.php @@ -0,0 +1,61 @@ + 'Default', + ]; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $form['setting_1'] = [ + '#type' => 'textfield', + '#title' => 'Blah', + '#default_value' => $this->configuration['setting_1'], + ]; + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $this->configuration['setting_1'] = $form_state->getValue('setting_1'); + } + +} diff --git a/core/modules/system/tests/modules/layout_test/templates/layout-test-1col.html.twig b/core/modules/system/tests/modules/layout_test/templates/layout-test-1col.html.twig new file mode 100644 index 00000000..2207e3c7 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/templates/layout-test-1col.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Template for an example 1 column layout. + */ +#} + +
    + {{ content.top }} +
    +
    + {{ content.bottom }} +
    + diff --git a/core/modules/system/tests/modules/layout_test/templates/layout-test-2col.html.twig b/core/modules/system/tests/modules/layout_test/templates/layout-test-2col.html.twig new file mode 100644 index 00000000..bb48d132 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/templates/layout-test-2col.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Template for an example 2 column layout. + */ +#} + +
    + {{ content.left }} +
    +
    + {{ content.right }} +
    + diff --git a/core/modules/system/tests/modules/layout_test/templates/layout-test-plugin.html.twig b/core/modules/system/tests/modules/layout_test/templates/layout-test-plugin.html.twig new file mode 100644 index 00000000..c4b4b850 --- /dev/null +++ b/core/modules/system/tests/modules/layout_test/templates/layout-test-plugin.html.twig @@ -0,0 +1,15 @@ +{# +/** + * @file + * Template for layout_test_plugin layout. + */ +#} + +
    + Blah: + {{ settings.setting_1 }} +
    +
    + {{ content.main }} +
    + diff --git a/core/modules/system/tests/modules/link_generation_test/link_generation_test.info.yml b/core/modules/system/tests/modules/link_generation_test/link_generation_test.info.yml index 713a33cd..da38fc81 100644 --- a/core/modules/system/tests/modules/link_generation_test/link_generation_test.info.yml +++ b/core/modules/system/tests/modules/link_generation_test/link_generation_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/menu_test/menu_test.info.yml b/core/modules/system/tests/modules/menu_test/menu_test.info.yml index 39678faf..245797c9 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.info.yml +++ b/core/modules/system/tests/modules/menu_test/menu_test.info.yml @@ -8,8 +8,8 @@ dependencies: - test_page_test - menu_ui -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/menu_test/menu_test.links.contextual.yml b/core/modules/system/tests/modules/menu_test/menu_test.links.contextual.yml index 9a8d8adc..28495924 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.links.contextual.yml +++ b/core/modules/system/tests/modules/menu_test/menu_test.links.contextual.yml @@ -8,6 +8,11 @@ menu_test.contextual_hidden_manage_edit: title: 'Edit menu - contextual' group: menu_test_menu route_name: menu_test.contextual_hidden_manage_edit + options: + attributes: + class: ['use-ajax'] + data-dialog-type: 'modal' + data-is-something: TRUE menu_test.hidden_block_configure: title: 'Configure block' diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/system/tests/modules/menu_test/menu_test.module index f891fce9..79b4dae2 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.module +++ b/core/modules/system/tests/modules/menu_test/menu_test.module @@ -19,35 +19,35 @@ function menu_test_menu_links_discovered_alter(&$links) { $links['menu_test.context']['title'] = \Drupal::config('menu_test.menu_item')->get('title'); // Adds a custom menu link. - $links['menu_test.custom'] = array( + $links['menu_test.custom'] = [ 'title' => 'Custom link', 'route_name' => 'menu_test.custom', 'description' => 'Custom link used to check the integrity of manually added menu links.', 'parent' => 'menu_test', - ); + ]; } /** * Implements hook_menu_local_tasks_alter(). */ function menu_test_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableDependencyInterface &$cacheability) { - if (in_array($route_name, array('menu_test.tasks_default'))) { - $data['tabs'][0]['foo'] = array( + if (in_array($route_name, ['menu_test.tasks_default'])) { + $data['tabs'][0]['foo'] = [ '#theme' => 'menu_local_task', - '#link' => array( + '#link' => [ 'title' => "Task 1 ", - 'url' => Url::fromRoute('menu_test.router_test1', array('bar' => '1')), - ), + 'url' => Url::fromRoute('menu_test.router_test1', ['bar' => '1']), + ], '#weight' => 10, - ); - $data['tabs'][0]['bar'] = array( + ]; + $data['tabs'][0]['bar'] = [ '#theme' => 'menu_local_task', - '#link' => array( + '#link' => [ 'title' => 'Task 2', - 'url' => Url::fromRoute('menu_test.router_test2', array('bar' => '2')), - ), + 'url' => Url::fromRoute('menu_test.router_test2', ['bar' => '2']), + ], '#weight' => 20, - ); + ]; } $cacheability->addCacheTags(['kittens:dwarf-cat']); } diff --git a/core/modules/system/tests/modules/menu_test/src/Controller/MenuTestController.php b/core/modules/system/tests/modules/menu_test/src/Controller/MenuTestController.php index c0832692..fe6566cd 100644 --- a/core/modules/system/tests/modules/menu_test/src/Controller/MenuTestController.php +++ b/core/modules/system/tests/modules/menu_test/src/Controller/MenuTestController.php @@ -83,8 +83,8 @@ public function menuTestCallback() { * @return string * The route title. */ - public function titleCallback(array $_title_arguments = array(), $_title = '') { - $_title_arguments += array('case_number' => '2', 'title' => $_title); + public function titleCallback(array $_title_arguments = [], $_title = '') { + $_title_arguments += ['case_number' => '2', 'title' => $_title]; return t($_title_arguments['title']) . ' - Case ' . $_title_arguments['case_number']; } diff --git a/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/LocalTaskTest.php b/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/LocalTaskTest.php index 10c0810f..90270b64 100644 --- a/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/LocalTaskTest.php +++ b/core/modules/system/tests/modules/menu_test/src/Plugin/Derivative/LocalTaskTest.php @@ -11,11 +11,12 @@ class LocalTaskTest extends DeriverBase { */ public function getDerivativeDefinitions($base_plugin_definition) { $weight = $base_plugin_definition['weight']; - foreach (array('derive1' => 'Derive 1', 'derive2' => 'Derive 2') as $key => $title) { + foreach (['derive1' => 'Derive 1', 'derive2' => 'Derive 2'] as $key => $title) { $this->derivatives[$key] = $base_plugin_definition; $this->derivatives[$key]['title'] = $title; - $this->derivatives[$key]['route_parameters'] = array('placeholder' => $key); - $this->derivatives[$key]['weight'] = $weight++; // ensure weights for testing. + $this->derivatives[$key]['route_parameters'] = ['placeholder' => $key]; + // Ensure weights for testing. + $this->derivatives[$key]['weight'] = $weight++; } return $this->derivatives; } diff --git a/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalAction/TestLocalAction4.php b/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalAction/TestLocalAction4.php index efd75799..1f8300a4 100644 --- a/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalAction/TestLocalAction4.php +++ b/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalAction/TestLocalAction4.php @@ -16,7 +16,7 @@ class TestLocalAction4 extends LocalActionDefault { * {@inheritdoc} */ public function getTitle() { - return $this->t('My @arg action', array('@arg' => 'dynamic-title')); + return $this->t('My @arg action', ['@arg' => 'dynamic-title']); } } diff --git a/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalTask/TestTasksSettingsSub1.php b/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalTask/TestTasksSettingsSub1.php index 72ef717c..7ba75488 100644 --- a/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalTask/TestTasksSettingsSub1.php +++ b/core/modules/system/tests/modules/menu_test/src/Plugin/Menu/LocalTask/TestTasksSettingsSub1.php @@ -12,14 +12,14 @@ class TestTasksSettingsSub1 extends LocalTaskDefault { /** * {@inheritdoc} */ - function getTitle() { - return $this->t('Dynamic title for @class', array('@class' => 'TestTasksSettingsSub1')); + public function getTitle() { + return $this->t('Dynamic title for @class', ['@class' => 'TestTasksSettingsSub1']); } /** * {@inheritdoc} */ - function getCacheTags() { + public function getCacheTags() { return ['kittens:ragdoll']; } diff --git a/core/modules/system/tests/modules/menu_test/src/TestControllers.php b/core/modules/system/tests/modules/menu_test/src/TestControllers.php index 9ed7851b..31fb341a 100644 --- a/core/modules/system/tests/modules/menu_test/src/TestControllers.php +++ b/core/modules/system/tests/modules/menu_test/src/TestControllers.php @@ -59,7 +59,7 @@ public function testDerived() { */ public function testDefaults($placeholder = NULL) { if ($placeholder) { - return ['#markup' => SafeMarkup::format("Sometimes there is a placeholder: '@placeholder'.", array('@placeholder' => $placeholder))]; + return ['#markup' => SafeMarkup::format("Sometimes there is a placeholder: '@placeholder'.", ['@placeholder' => $placeholder])]; } else { return ['#markup' => 'Sometimes there is no placeholder.']; diff --git a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.info.yml b/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.info.yml index 75da492a..ff992e29 100644 --- a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.info.yml +++ b/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php b/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php index b46f3742..6cd97a0c 100644 --- a/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php +++ b/core/modules/system/tests/modules/module_autoload_test/src/SomeClass.php @@ -3,7 +3,7 @@ namespace Drupal\module_autoload_test; class SomeClass { - function testMethod() { + public function testMethod() { return 'Drupal\\module_autoload_test\\SomeClass::testMethod() was invoked.'; } diff --git a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.info.yml b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.info.yml index f069355a..edc9c8b1 100644 --- a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.info.yml +++ b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.info.yml @@ -6,8 +6,8 @@ package: Testing # core: 8.x hidden: true -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install new file mode 100644 index 00000000..4d992d4c --- /dev/null +++ b/core/modules/system/tests/modules/module_handler_test_multiple/module_handler_test_multiple.install @@ -0,0 +1,14 @@ +=8.x) -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/module_test/module_test.file.inc b/core/modules/system/tests/modules/module_test/module_test.file.inc index 0842944c..b40e0f34 100644 --- a/core/modules/system/tests/modules/module_test/module_test.file.inc +++ b/core/modules/system/tests/modules/module_test/module_test.file.inc @@ -9,5 +9,5 @@ * Implements hook_test_hook(). */ function module_test_test_hook() { - return array('module_test' => 'success!'); + return ['module_test' => 'success!']; } diff --git a/core/modules/system/tests/modules/module_test/module_test.info.yml b/core/modules/system/tests/modules/module_test/module_test.info.yml index b0681092..a9ce29cc 100644 --- a/core/modules/system/tests/modules/module_test/module_test.info.yml +++ b/core/modules/system/tests/modules/module_test/module_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/module_test/module_test.install b/core/modules/system/tests/modules/module_test/module_test.install index e90fc577..5f3f6f65 100644 --- a/core/modules/system/tests/modules/module_test/module_test.install +++ b/core/modules/system/tests/modules/module_test/module_test.install @@ -9,18 +9,18 @@ * Implements hook_schema(). */ function module_test_schema() { - $schema['module_test'] = array( + $schema['module_test'] = [ 'description' => 'Dummy table to test the behavior of hook_schema() during module installation.', - 'fields' => array( - 'data' => array( + 'fields' => [ + 'data' => [ 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'An example data column for the module.', - ), - ), - ); + ], + ], + ]; return $schema; } @@ -30,8 +30,8 @@ function module_test_schema() { function module_test_install() { $schema = drupal_get_module_schema('module_test', 'module_test'); db_insert('module_test') - ->fields(array( + ->fields([ 'data' => $schema['fields']['data']['type'], - )) + ]) ->execute(); } diff --git a/core/modules/system/tests/modules/module_test/module_test.module b/core/modules/system/tests/modules/module_test/module_test.module index 9c5cd9ac..dba4889d 100644 --- a/core/modules/system/tests/modules/module_test/module_test.module +++ b/core/modules/system/tests/modules/module_test/module_test.module @@ -60,9 +60,9 @@ function module_test_system_info_alter(&$info, Extension $file, $type) { * Implements hook_hook_info(). */ function module_test_hook_info() { - $hooks['test_hook'] = array( + $hooks['test_hook'] = [ 'group' => 'file', - ); + ]; return $hooks; } diff --git a/core/modules/system/tests/modules/pager_test/pager_test.info.yml b/core/modules/system/tests/modules/pager_test/pager_test.info.yml index 9dc152ab..0f71e7fd 100644 --- a/core/modules/system/tests/modules/pager_test/pager_test.info.yml +++ b/core/modules/system/tests/modules/pager_test/pager_test.info.yml @@ -5,8 +5,8 @@ description: 'Support module for pager tests.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php b/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php index 39144c67..1964f740 100644 --- a/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php +++ b/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php @@ -28,7 +28,7 @@ protected function buildTestTable($element, $limit) { ]; $query = db_select('watchdog', 'd')->extend('Drupal\Core\Database\Query\PagerSelectExtender')->element($element); $result = $query - ->fields('d', array('wid', 'type', 'timestamp')) + ->fields('d', ['wid', 'type', 'timestamp']) ->limit($limit) ->orderBy('d.wid') ->execute(); @@ -58,19 +58,19 @@ public function queryParameters() { // Counter of calls to the current pager. $query_params = pager_get_query_parameters(); $pager_calls = isset($query_params['pager_calls']) ? ($query_params['pager_calls'] ? $query_params['pager_calls'] : 0) : 0; - $build['l_pager_pager_0'] = array('#markup' => $this->t('Pager calls: @pager_calls', array('@pager_calls' => $pager_calls))); + $build['l_pager_pager_0'] = ['#markup' => $this->t('Pager calls: @pager_calls', ['@pager_calls' => $pager_calls])]; // Pager. - $build['pager_pager_0'] = array( + $build['pager_pager_0'] = [ '#type' => 'pager', '#element' => 0, - '#parameters' => array( + '#parameters' => [ 'pager_calls' => ++$pager_calls, - ), + ], '#pre_render' => [ 'Drupal\pager_test\Controller\PagerTestController::showPagerCacheContext', ] - ); + ]; return $build; } @@ -82,34 +82,34 @@ public function multiplePagers() { // Build three tables with same query and different pagers. $build['pager_table_0'] = $this->buildTestTable(0, 20); - $build['pager_pager_0'] = array( + $build['pager_pager_0'] = [ '#type' => 'container', '#attributes' => ['class' => ['test-pager-0']], 'pager' => [ '#type' => 'pager', '#element' => 0, ], - ); + ]; $build['pager_table_1'] = $this->buildTestTable(1, 20); - $build['pager_pager_1'] = array( + $build['pager_pager_1'] = [ '#type' => 'container', '#attributes' => ['class' => ['test-pager-1']], 'pager' => [ '#type' => 'pager', '#element' => 1, ], - ); + ]; $build['pager_table_4'] = $this->buildTestTable(4, 20); - $build['pager_pager_4'] = array( + $build['pager_pager_4'] = [ '#type' => 'container', '#attributes' => ['class' => ['test-pager-4']], 'pager' => [ '#type' => 'pager', '#element' => 4, ], - ); + ]; return $build; } diff --git a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml index 47c3f573..db5d6c7e 100644 --- a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml +++ b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/path_encoded_test/path_encoded_test.info.yml b/core/modules/system/tests/modules/path_encoded_test/path_encoded_test.info.yml new file mode 100644 index 00000000..638ac276 --- /dev/null +++ b/core/modules/system/tests/modules/path_encoded_test/path_encoded_test.info.yml @@ -0,0 +1,12 @@ +name: 'Path encoded character test' +type: module +description: 'Support module for testing path aliases on a route with encoded characters in the path.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/path_encoded_test/path_encoded_test.routing.yml b/core/modules/system/tests/modules/path_encoded_test/path_encoded_test.routing.yml new file mode 100644 index 00000000..9a5b30cc --- /dev/null +++ b/core/modules/system/tests/modules/path_encoded_test/path_encoded_test.routing.yml @@ -0,0 +1,23 @@ +path_encoded_test.colon: + path: '/hi/llamma:party' + defaults: + _title: 'Colon' + _controller: '\Drupal\path_encoded_test\Controller\PathEncodedTestController::simple' + requirements: + _access: 'TRUE' + +path_encoded_test.atsign: + path: '/bloggy/@Dries' + defaults: + _title: 'At sign' + _controller: '\Drupal\path_encoded_test\Controller\PathEncodedTestController::simple' + requirements: + _access: 'TRUE' + +path_encoded_test.parens: + path: '/cat(box)' + defaults: + _title: 'At sign' + _controller: '\Drupal\path_encoded_test\Controller\PathEncodedTestController::simple' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/modules/path_encoded_test/src/Controller/PathEncodedTestController.php b/core/modules/system/tests/modules/path_encoded_test/src/Controller/PathEncodedTestController.php new file mode 100644 index 00000000..027c24f7 --- /dev/null +++ b/core/modules/system/tests/modules/path_encoded_test/src/Controller/PathEncodedTestController.php @@ -0,0 +1,21 @@ +PathEncodedTestController works'); + } + +} diff --git a/core/modules/system/tests/modules/path_test/path_test.info.yml b/core/modules/system/tests/modules/path_test/path_test.info.yml index 16aeca97..26ef838e 100644 --- a/core/modules/system/tests/modules/path_test/path_test.info.yml +++ b/core/modules/system/tests/modules/path_test/path_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/path_test/path_test.module b/core/modules/system/tests/modules/path_test/path_test.module index df039312..32489c02 100644 --- a/core/modules/system/tests/modules/path_test/path_test.module +++ b/core/modules/system/tests/modules/path_test/path_test.module @@ -9,14 +9,14 @@ * Resets the path test results. */ function path_test_reset() { - \Drupal::state()->set('path_test.results', array()); + \Drupal::state()->set('path_test.results', []); } /** * Implements hook_path_update(). */ function path_test_path_update($path) { - $results = \Drupal::state()->get('path_test.results') ?: array(); + $results = \Drupal::state()->get('path_test.results') ?: []; $results['hook_path_update'] = $path; \Drupal::state()->set('path_test.results', $results); } diff --git a/core/modules/system/tests/modules/plugin_test/plugin_test.info.yml b/core/modules/system/tests/modules/plugin_test/plugin_test.info.yml index 1fef64e4..6a3d1b69 100644 --- a/core/modules/system/tests/modules/plugin_test/plugin_test.info.yml +++ b/core/modules/system/tests/modules/plugin_test/plugin_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/Annotation/PluginExample.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/Annotation/PluginExample.php index daca83ba..b80460d6 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/Annotation/PluginExample.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/Annotation/PluginExample.php @@ -29,12 +29,12 @@ class PluginExample extends AnnotationBase { * {@inheritdoc} */ public function get() { - return array( + return [ 'id' => $this->id, 'custom' => $this->custom, 'class' => $this->class, 'provider' => $this->provider, - ); + ]; } } diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/DefaultsTestPluginManager.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/DefaultsTestPluginManager.php index eda8f884..65d7078c 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/DefaultsTestPluginManager.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/DefaultsTestPluginManager.php @@ -28,27 +28,27 @@ public function __construct(ModuleHandlerInterface $module_handler) { $this->moduleHandler = $module_handler; // Specify default values. - $this->defaults = array( - 'metadata' => array( + $this->defaults = [ + 'metadata' => [ 'default' => TRUE, - ), - ); + ], + ]; // Add a plugin with a custom value. - $this->discovery->setDefinition('test_block1', array( + $this->discovery->setDefinition('test_block1', [ 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockTestBlock', - 'metadata' => array( + 'metadata' => [ 'custom' => TRUE, - ), - )); + ], + ]); // Add a plugin that overrides the default value. - $this->discovery->setDefinition('test_block2', array( + $this->discovery->setDefinition('test_block2', [ 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockTestBlock', - 'metadata' => array( + 'metadata' => [ 'custom' => TRUE, 'default' => FALSE, - ), - )); + ], + ]); } } diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php index aebb4730..443ab5d0 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/MockBlockManager.php @@ -34,10 +34,11 @@ public function __construct() { // plugins to the system. // A simple plugin: the user login block. - $this->discovery->setDefinition('user_login', array( + $this->discovery->setDefinition('user_login', [ + 'id' => 'user_login', 'label' => t('User login'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', - )); + ]); // A plugin that requires derivatives: the menu block plugin. We do not want // a generic "Menu" block showing up in the Block administration UI. @@ -45,15 +46,17 @@ public function __construct() { // system and each one's title is user configurable. The // MockMenuBlockDeriver class ensures that only derivatives, and not the // base plugin, are available to the system. - $this->discovery->setDefinition('menu', array( + $this->discovery->setDefinition('menu', [ + 'id' => 'menu', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', 'deriver' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlockDeriver', - )); + ]); // A plugin defining itself as a derivative. - $this->discovery->setDefinition('menu:foo', array( + $this->discovery->setDefinition('menu:foo', [ + 'id' => 'menu', 'label' => t('Base label'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', - )); + ]); // A block plugin that can optionally be derived: the layout block plugin. // A layout is a special kind of block into which other blocks can be @@ -61,46 +64,51 @@ public function __construct() { // administration UI as well as additional user-created custom layouts. The // MockLayoutBlockDeriver class ensures that both the base plugin and the // derivatives are available to the system. - $this->discovery->setDefinition('layout', array( + $this->discovery->setDefinition('layout', [ + 'id' => 'layout', 'label' => t('Layout'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlock', 'deriver' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlockDeriver', - )); + ]); // A block plugin that requires context to function. This block requires a // user object in order to return the user name from the getTitle() method. - $this->discovery->setDefinition('user_name', array( + $this->discovery->setDefinition('user_name', [ + 'id' => 'user_name', 'label' => t('User name'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock', - 'context' => array( + 'context' => [ 'user' => $this->createContextDefinition('entity:user', t('User')), - ), - )); + ], + ]); // An optional context version of the previous block plugin. - $this->discovery->setDefinition('user_name_optional', array( + $this->discovery->setDefinition('user_name_optional', [ + 'id' => 'user_name_optional', 'label' => t('User name optional'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock', - 'context' => array( + 'context' => [ 'user' => $this->createContextDefinition('entity:user', t('User'), FALSE), - ), - )); + ], + ]); // A block plugin that requires a typed data string context to function. - $this->discovery->setDefinition('string_context', array( + $this->discovery->setDefinition('string_context', [ + 'id' => 'string_context', 'label' => t('String typed data'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\TypedDataStringBlock', - )); + ]); // A complex context plugin that requires both a user and node for context. - $this->discovery->setDefinition('complex_context', array( + $this->discovery->setDefinition('complex_context', [ + 'id' => 'complex_context', 'label' => t('Complex context'), 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock', - 'context' => array( + 'context' => [ 'user' => $this->createContextDefinition('entity:user', t('User')), 'node' => $this->createContextDefinition('entity:node', t('Node')), - ), - )); + ], + ]); // In addition to finding all of the plugins available for a type, a plugin // type must also be able to create instances of that plugin. For example, a @@ -119,7 +127,7 @@ public function __construct() { * * @param string $data_type * The required data type. - * @param mixed string|null $label + * @param mixed|string|null $label * The label of this context definition for the UI. * @param bool $required * Whether the context definition is required. diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/TestLazyPluginCollection.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/TestLazyPluginCollection.php index dd426e48..1009faa5 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/TestLazyPluginCollection.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/TestLazyPluginCollection.php @@ -34,14 +34,14 @@ public function __construct(PluginManagerInterface $manager) { * {@inheritdoc} */ protected function initializePlugin($instance_id) { - $this->pluginInstances[$instance_id] = $this->manager->createInstance($instance_id, array()); + $this->pluginInstances[$instance_id] = $this->manager->createInstance($instance_id, []); } /** * {@inheritdoc} */ public function getConfiguration() { - return array(); + return []; } /** diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/TestPluginManager.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/TestPluginManager.php index 60e74d83..ec464a5b 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/TestPluginManager.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/TestPluginManager.php @@ -19,10 +19,10 @@ public function __construct() { $this->discovery = new StaticDiscovery(); // A simple plugin: a mock user login block. - $this->discovery->setDefinition('user_login', array( + $this->discovery->setDefinition('user_login', [ 'label' => 'User login', 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', - )); + ]); // In addition to finding all of the plugins available for a type, a plugin // type must also be able to create instances of that plugin. For example, a diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php index a42a474e..c6924974 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/ExtendingNonInstalledClass.php @@ -11,4 +11,4 @@ * color = "pink", * ) */ -class ExtendingNonInstalledClass extends YummyFruit { } +class ExtendingNonInstalledClass extends YummyFruit {} diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/FruitInterface.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/FruitInterface.php index 62e0c38a..cbd0f88b 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/FruitInterface.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/fruit/FruitInterface.php @@ -5,4 +5,4 @@ /** * Provides an interface for test plugins. */ -interface FruitInterface { } +interface FruitInterface {} diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockLayoutBlockDeriver.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockLayoutBlockDeriver.php index d2fa3a46..93fca538 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockLayoutBlockDeriver.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockLayoutBlockDeriver.php @@ -31,7 +31,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { // key from the returned definitions. unset($base_plugin_definition['deriver']); - $derivatives = array( + $derivatives = [ // Adding a NULL key signifies that the base plugin may also be used in // addition to the derivatives. In this case, we allow the administrator // to add a generic layout block to the page. @@ -40,10 +40,10 @@ public function getDerivativeDefinitions($base_plugin_definition) { // We also allow them to add a customized one. Here, we just mock the // customized one, but in a real implementation, this would be fetched // from some \Drupal::config() object. - 'foo' => array( + 'foo' => [ 'label' => t('Layout Foo'), - ) + $base_plugin_definition, - ); + ] + $base_plugin_definition, + ]; return $derivatives; } diff --git a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockMenuBlockDeriver.php b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockMenuBlockDeriver.php index 413eb133..d5f6d6c2 100644 --- a/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockMenuBlockDeriver.php +++ b/core/modules/system/tests/modules/plugin_test/src/Plugin/plugin_test/mock_block/MockMenuBlockDeriver.php @@ -34,20 +34,20 @@ public function getDerivativeDefinitions($base_plugin_definition) { // Here, we create some mock menu block definitions for menus that might // exist in a typical Drupal site. In a real implementation, we would query // Drupal's configuration to find out which menus actually exist. - $derivatives = array( - 'main_menu' => array( + $derivatives = [ + 'main_menu' => [ 'label' => t('Main menu'), - ) + $base_plugin_definition, - 'navigation' => array( + ] + $base_plugin_definition, + 'navigation' => [ 'label' => t('Navigation'), - ) + $base_plugin_definition, - 'foo' => array( + ] + $base_plugin_definition, + 'foo' => [ // Instead of the derivative label, the specific label will be used. 'label' => t('Derivative label'), // This setting will be merged in. 'setting' => 'default' - ) + $base_plugin_definition, - ); + ] + $base_plugin_definition, + ]; return $derivatives; } diff --git a/core/modules/system/tests/modules/plugin_test_extended/plugin_test_extended.info.yml b/core/modules/system/tests/modules/plugin_test_extended/plugin_test_extended.info.yml index b66964c5..00cbaef8 100644 --- a/core/modules/system/tests/modules/plugin_test_extended/plugin_test_extended.info.yml +++ b/core/modules/system/tests/modules/plugin_test_extended/plugin_test_extended.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.info.yml b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.info.yml new file mode 100644 index 00000000..eb53c7e4 --- /dev/null +++ b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.info.yml @@ -0,0 +1,12 @@ +name: 'Array rendering for non-HTML requests subscriber test' +type: module +description: 'Support module for RenderArrayNonHtmlSubscriberTest.' +package: Testing +# version: VERSION +# core: 8.x + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.routing.yml b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.routing.yml new file mode 100644 index 00000000..e81ae77f --- /dev/null +++ b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.routing.yml @@ -0,0 +1,13 @@ +render_array_non_html_subscriber_test.raw_string: + path: '/render_array_non_html_subscriber_test/raw_string' + defaults: + _controller: '\Drupal\render_array_non_html_subscriber_test\RenderArrayNonHtmlSubscriberTestController::rawString' + requirements: + _access: 'TRUE' + +render_array_non_html_subscriber_test.render_array: + path: '/render_array_non_html_subscriber_test/render_array' + defaults: + _controller: '\Drupal\render_array_non_html_subscriber_test\RenderArrayNonHtmlSubscriberTestController::renderArray' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/modules/render_array_non_html_subscriber_test/src/RenderArrayNonHtmlSubscriberTestController.php b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/src/RenderArrayNonHtmlSubscriberTestController.php new file mode 100644 index 00000000..73a4622b --- /dev/null +++ b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/src/RenderArrayNonHtmlSubscriberTestController.php @@ -0,0 +1,28 @@ +t('Raw controller response.')); + } + + /** + * @return array + */ + public function renderArray() { + return [ + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => $this->t('Controller response successfully rendered.'), + ]; + } + +} diff --git a/core/modules/system/tests/modules/render_attached_test/render_attached_test.info.yml b/core/modules/system/tests/modules/render_attached_test/render_attached_test.info.yml index ec8de774..3f1c2618 100644 --- a/core/modules/system/tests/modules/render_attached_test/render_attached_test.info.yml +++ b/core/modules/system/tests/modules/render_attached_test/render_attached_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - block -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/render_placeholder_message_test/render_placeholder_message_test.info.yml b/core/modules/system/tests/modules/render_placeholder_message_test/render_placeholder_message_test.info.yml index 942517bd..dcef8819 100644 --- a/core/modules/system/tests/modules/render_placeholder_message_test/render_placeholder_message_test.info.yml +++ b/core/modules/system/tests/modules/render_placeholder_message_test/render_placeholder_message_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php b/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php index f02f0b63..4a4d15d8 100644 --- a/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php +++ b/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php @@ -1,6 +1,7 @@ build([ - '', - '', - '', + '', + '', + '', ]); } @@ -25,9 +26,9 @@ public function messagesPlaceholderFirst() { */ public function messagesPlaceholderMiddle() { return $this->build([ - '', - '', - '', + '', + '', + '', ]); } @@ -36,9 +37,9 @@ public function messagesPlaceholderMiddle() { */ public function messagesPlaceholderLast() { return $this->build([ - '', - '', - '', + '', + '', + '', ]); } diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml b/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml index 1502989a..0cd144c9 100644 --- a/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml +++ b/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.install b/core/modules/system/tests/modules/requirements1_test/requirements1_test.install index c8848939..e8121617 100644 --- a/core/modules/system/tests/modules/requirements1_test/requirements1_test.install +++ b/core/modules/system/tests/modules/requirements1_test/requirements1_test.install @@ -9,15 +9,15 @@ * Implements hook_requirements(). */ function requirements1_test_requirements($phase) { - $requirements = array(); + $requirements = []; // Always fails requirements. if ('install' == $phase) { - $requirements['requirements1_test'] = array( + $requirements['requirements1_test'] = [ 'title' => t('Requirements 1 Test'), 'severity' => REQUIREMENT_ERROR, 'description' => t('Requirements 1 Test failed requirements.'), - ); + ]; } return $requirements; diff --git a/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml b/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml index b1908d53..06a8df24 100644 --- a/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml +++ b/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml @@ -8,8 +8,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/router_test_directory/router_test.info.yml b/core/modules/system/tests/modules/router_test_directory/router_test.info.yml index ba79277c..520e1023 100644 --- a/core/modules/system/tests/modules/router_test_directory/router_test.info.yml +++ b/core/modules/system/tests/modules/router_test_directory/router_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml b/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml index ad2d4186..4d5d241b 100644 --- a/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml +++ b/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml @@ -212,3 +212,38 @@ router_test.hierarchy_parent_child2: _controller: '\Drupal\router_test\TestControllers::test' requirements: _access: 'TRUE' + +router_test.two_duplicate1: + path: '/router-test/duplicate-path2' + defaults: + _controller: '\Drupal\router_test\TestControllers::testRouteName' + requirements: + _access: 'TRUE' + +router_test.two_duplicate2: + path: '/router-test/duplicate-path2' + defaults: + _controller: '\Drupal\router_test\TestControllers::testRouteName' + requirements: + _access: 'TRUE' + +router_test.case_sensitive_duplicate1: + path: '/router-test/case-sensitive-duplicate-path3' + defaults: + _controller: '\Drupal\router_test\TestControllers::testRouteName' + requirements: + _access: 'TRUE' + +router_test.case_sensitive_duplicate2: + path: '/router-test/case-sensitive-Duplicate-PATH3' + defaults: + _controller: '\Drupal\router_test\TestControllers::testRouteName' + requirements: + _access: 'TRUE' + +router_test.case_sensitive_duplicate3: + path: '/router-test/case-sensitive-duplicate-path3' + defaults: + _controller: '\Drupal\router_test\TestControllers::testRouteName' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/modules/router_test_directory/src/RouterTestServiceProvider.php b/core/modules/system/tests/modules/router_test_directory/src/RouterTestServiceProvider.php index 7635704f..5430e8d8 100644 --- a/core/modules/system/tests/modules/router_test_directory/src/RouterTestServiceProvider.php +++ b/core/modules/system/tests/modules/router_test_directory/src/RouterTestServiceProvider.php @@ -16,7 +16,7 @@ class RouterTestServiceProvider implements ServiceProviderInterface { public function register(ContainerBuilder $container) { $container->register('router_test.subscriber', 'Drupal\router_test\RouteTestSubscriber')->addTag('event_subscriber'); $container->register('access_check.router_test', 'Drupal\router_test\Access\TestAccessCheck') - ->addTag('access_check', array('applies_to' => '_access_router_test')); + ->addTag('access_check', ['applies_to' => '_access_router_test']); } } diff --git a/core/modules/system/tests/modules/router_test_directory/src/TestContent.php b/core/modules/system/tests/modules/router_test_directory/src/TestContent.php index 9cbe023a..f392a81e 100644 --- a/core/modules/system/tests/modules/router_test_directory/src/TestContent.php +++ b/core/modules/system/tests/modules/router_test_directory/src/TestContent.php @@ -63,7 +63,7 @@ public function testAccount(UserInterface $user) { */ public function subrequestTest(UserInterface $user) { $request = \Drupal::request(); - $request = Request::create('/router_test/test13/' . $user->id(), 'GET', $request->query->all(), $request->cookies->all(), array(), $request->server->all()); + $request = Request::create('/router_test/test13/' . $user->id(), 'GET', $request->query->all(), $request->cookies->all(), [], $request->server->all()); return $this->httpKernel->handle($request, HttpKernelInterface::SUB_REQUEST); } diff --git a/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php b/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php index c3bcac7b..adebf28d 100644 --- a/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php +++ b/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php @@ -6,10 +6,10 @@ use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\user\UserInterface; use Symfony\Cmf\Component\Routing\RouteObjectInterface; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Zend\Diactoros\Response\HtmlResponse; - /** * Controller routines for testing the routing system. */ @@ -110,6 +110,12 @@ public function test25() { ]; } + public function testRouteName(Request $request) { + return [ + '#markup' => $request->attributes->get(RouteObjectInterface::ROUTE_NAME), + ]; + } + /** * Throws an exception. * diff --git a/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml b/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml index 4bef621a..0b885e61 100644 --- a/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml +++ b/core/modules/system/tests/modules/service_provider_test/service_provider_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/service_provider_test/src/TestClass.php b/core/modules/system/tests/modules/service_provider_test/src/TestClass.php index 9a87c972..d521e1fd 100644 --- a/core/modules/system/tests/modules/service_provider_test/src/TestClass.php +++ b/core/modules/system/tests/modules/service_provider_test/src/TestClass.php @@ -57,9 +57,9 @@ public function onKernelResponseTest(FilterResponseEvent $event) { * @return array * An array of event listener definitions. */ - static function getSubscribedEvents() { - $events[KernelEvents::REQUEST][] = array('onKernelRequestTest'); - $events[KernelEvents::RESPONSE][] = array('onKernelResponseTest'); + public static function getSubscribedEvents() { + $events[KernelEvents::REQUEST][] = ['onKernelRequestTest']; + $events[KernelEvents::RESPONSE][] = ['onKernelResponseTest']; return $events; } diff --git a/core/modules/system/tests/modules/session_exists_cache_context_test/session_exists_cache_context_test.info.yml b/core/modules/system/tests/modules/session_exists_cache_context_test/session_exists_cache_context_test.info.yml index 7f6825ef..c09ef53d 100644 --- a/core/modules/system/tests/modules/session_exists_cache_context_test/session_exists_cache_context_test.info.yml +++ b/core/modules/system/tests/modules/session_exists_cache_context_test/session_exists_cache_context_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/session_test/session_test.info.yml b/core/modules/system/tests/modules/session_test/session_test.info.yml index a2b18e6f..814364e4 100644 --- a/core/modules/system/tests/modules/session_test/session_test.info.yml +++ b/core/modules/system/tests/modules/session_test/session_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php b/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php index edde4fd9..76a54629 100644 --- a/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php +++ b/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php @@ -21,7 +21,7 @@ class SessionTestController extends ControllerBase { public function get() { return empty($_SESSION['session_test_value']) ? [] - : ['#markup' => $this->t('The current value of the stored session variable is: %val', array('%val' => $_SESSION['session_test_value']))]; + : ['#markup' => $this->t('The current value of the stored session variable is: %val', ['%val' => $_SESSION['session_test_value']])]; } /** @@ -37,7 +37,7 @@ public function getFromSessionObject(Request $request) { $value = $request->getSession()->get("session_test_key"); return empty($value) ? [] - : ['#markup' => $this->t('The current value of the stored session variable is: %val', array('%val' => $value))]; + : ['#markup' => $this->t('The current value of the stored session variable is: %val', ['%val' => $value])]; } /** @@ -84,7 +84,7 @@ public function getIdFromCookie(Request $request) { public function set($test_value) { $_SESSION['session_test_value'] = $test_value; - return ['#markup' => $this->t('The current value of the stored session variable has been set to %val', array('%val' => $test_value))]; + return ['#markup' => $this->t('The current value of the stored session variable has been set to %val', ['%val' => $test_value])]; } /** @@ -100,7 +100,7 @@ public function set($test_value) { public function noSet($test_value) { \Drupal::service('session_handler.write_safe')->setSessionWritable(FALSE); $this->set($test_value); - return ['#markup' => $this->t('session saving was disabled, and then %val was set', array('%val' => $test_value))]; + return ['#markup' => $this->t('session saving was disabled, and then %val was set', ['%val' => $test_value])]; } /** diff --git a/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php b/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php index ee03668e..47c8c5b1 100644 --- a/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php +++ b/core/modules/system/tests/modules/session_test/src/EventSubscriber/SessionTestSubscriber.php @@ -49,8 +49,8 @@ public function onKernelResponseSessionTest(FilterResponseEvent $event) { * An array of event listener definitions. */ public static function getSubscribedEvents() { - $events[KernelEvents::RESPONSE][] = array('onKernelResponseSessionTest'); - $events[KernelEvents::REQUEST][] = array('onKernelRequestSessionTest'); + $events[KernelEvents::RESPONSE][] = ['onKernelResponseSessionTest']; + $events[KernelEvents::REQUEST][] = ['onKernelRequestSessionTest']; return $events; } diff --git a/core/modules/system/tests/modules/session_test/src/Form/SessionTestForm.php b/core/modules/system/tests/modules/session_test/src/Form/SessionTestForm.php index 70c4f834..bf250ac4 100644 --- a/core/modules/system/tests/modules/session_test/src/Form/SessionTestForm.php +++ b/core/modules/system/tests/modules/session_test/src/Form/SessionTestForm.php @@ -22,17 +22,17 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['input'] = array( + $form['input'] = [ '#type' => 'textfield', '#title' => 'Input', '#required' => TRUE, - ); + ]; - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions']; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => 'Save', - ); + ]; return $form; } @@ -41,7 +41,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - drupal_set_message(SafeMarkup::format('Ok: @input', array('@input' => $form_state->getValue('input')))); + drupal_set_message(SafeMarkup::format('Ok: @input', ['@input' => $form_state->getValue('input')])); } } diff --git a/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.info.yml b/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.info.yml index 4a9a3cbc..6528e8fc 100644 --- a/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.info.yml +++ b/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - _missing_dependency -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info.yml b/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info.yml index 33297535..1623e410 100644 --- a/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info.yml +++ b/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - system_incompatible_core_version_test -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml b/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml index b056e44b..d0898699 100644 --- a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml +++ b/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 5.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.info.yml b/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.info.yml index 322affa8..a5a2b416 100644 --- a/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.info.yml +++ b/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - 'system_incompatible_module_version_test (>2.0)' -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.info.yml b/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.info.yml index 20d7ffff..66b0e928 100644 --- a/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.info.yml +++ b/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: '1.0' # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_incompatible_php_version_test/system_incompatible_php_version_test.info.yml b/core/modules/system/tests/modules/system_incompatible_php_version_test/system_incompatible_php_version_test.info.yml new file mode 100644 index 00000000..97169104 --- /dev/null +++ b/core/modules/system/tests/modules/system_incompatible_php_version_test/system_incompatible_php_version_test.info.yml @@ -0,0 +1,13 @@ +name: 'System incompatible PHP version test' +type: module +description: 'Support module for testing system dependencies.' +package: Testing +# version: VERSION +# core: 8.x +php: 6502 + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.info.yml b/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.info.yml index d8ffc4d1..a79ad3bf 100644 --- a/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.info.yml +++ b/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_module_test/system_module_test.info.yml b/core/modules/system/tests/modules/system_module_test/system_module_test.info.yml index e631628a..114a8cd4 100644 --- a/core/modules/system/tests/modules/system_module_test/system_module_test.info.yml +++ b/core/modules/system/tests/modules/system_module_test/system_module_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_project_namespace_test/system_project_namespace_test.info.yml b/core/modules/system/tests/modules/system_project_namespace_test/system_project_namespace_test.info.yml index 6660a526..07e78b92 100644 --- a/core/modules/system/tests/modules/system_project_namespace_test/system_project_namespace_test.info.yml +++ b/core/modules/system/tests/modules/system_project_namespace_test/system_project_namespace_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - drupal:filter -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php index f2e13862..37eb8758 100644 --- a/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php +++ b/core/modules/system/tests/modules/system_test/src/Controller/SystemTestController.php @@ -206,15 +206,15 @@ public function lockPersist($lock_name) { * Set cache tag on on the returned render array. */ public function system_test_cache_tags_page() { - $build['main'] = array( - '#cache' => array('tags' => array('system_test_cache_tags_page')), - '#pre_render' => array( + $build['main'] = [ + '#cache' => ['tags' => ['system_test_cache_tags_page']], + '#pre_render' => [ '\Drupal\system_test\Controller\SystemTestController::preRenderCacheTags', - ), - 'message' => array( + ], + 'message' => [ '#markup' => 'Cache tags page example', - ), - ); + ], + ]; return $build; } @@ -222,12 +222,12 @@ public function system_test_cache_tags_page() { * Set cache max-age on the returned render array. */ public function system_test_cache_maxage_page() { - $build['main'] = array( - '#cache' => array('max-age' => 90), - 'message' => array( + $build['main'] = [ + '#cache' => ['max-age' => 90], + 'message' => [ '#markup' => 'Cache max-age page example', - ), - ); + ], + ]; return $build; } @@ -245,8 +245,8 @@ public static function preRenderCacheTags($elements) { * @see system_authorized_init() */ public function authorizeInit($page_title) { - $authorize_url = Url::fromUri('base:core/authorize.php', array('absolute' => TRUE))->toString(); - system_authorized_init('system_test_authorize_run', __DIR__ . '/../../system_test.module', array(), $page_title); + $authorize_url = Url::fromUri('base:core/authorize.php', ['absolute' => TRUE])->toString(); + system_authorized_init('system_test_authorize_run', __DIR__ . '/../../system_test.module', [], $page_title); return new RedirectResponse($authorize_url); } @@ -258,7 +258,7 @@ public function setHeader(Request $request) { $response = new CacheableResponse(); $response->headers->set($query['name'], $query['value']); $response->getCacheableMetadata()->addCacheContexts(['url.query_args:name', 'url.query_args:value']); - $response->setContent($this->t('The following header was set: %name: %value', array('%name' => $query['name'], '%value' => $query['value']))); + $response->setContent($this->t('The following header was set: %name: %value', ['%name' => $query['name'], '%value' => $query['value']])); return $response; } @@ -312,6 +312,21 @@ public function configureTitle($foo) { return 'Bar.' . $foo; } + /** + * Simple argument echo. + * + * @param string $text + * Any string for the {text} slug. + * + * @return array + * A render array. + */ + public function simpleEcho($text) { + return [ + '#plain_text' => $text, + ]; + } + /** * Shows permission-dependent content. * @@ -339,7 +354,7 @@ public function permissionDependentContent() { /** * Returns the current date. * - * @return \Symfony\Component\HttpFoundation\Response $response + * @return \Symfony\Component\HttpFoundation\Response * A Response object containing the current date. */ public function getCurrentDate() { @@ -351,7 +366,7 @@ public function getCurrentDate() { /** * Returns a response with a test header set from the request. * - * @return \Symfony\Component\HttpFoundation\Response $response + * @return \Symfony\Component\HttpFoundation\Response * A Response object containing the test header. */ public function getTestHeader(Request $request) { @@ -360,4 +375,11 @@ public function getTestHeader(Request $request) { return $response; } + /** + * Returns a cacheable response with a custom cache control. + */ + public function getCacheableResponseWithCustomCacheControl() { + return new CacheableResponse('Foo', 200, ['Cache-Control' => 'bar']); + } + } diff --git a/core/modules/system/tests/modules/system_test/src/MockFileTransfer.php b/core/modules/system/tests/modules/system_test/src/MockFileTransfer.php index de065af2..b7ea3f21 100644 --- a/core/modules/system/tests/modules/system_test/src/MockFileTransfer.php +++ b/core/modules/system/tests/modules/system_test/src/MockFileTransfer.php @@ -21,11 +21,11 @@ public static function factory() { * Returns a settings form with a text field to input a username. */ public function getSettingsForm() { - $form = array(); - $form['system_test_username'] = array( + $form = []; + $form['system_test_username'] = [ '#type' => 'textfield', '#title' => t('System Test Username'), - ); + ]; return $form; } diff --git a/core/modules/system/tests/modules/system_test/system_test.info.yml b/core/modules/system/tests/modules/system_test/system_test.info.yml index 04ea757b..4e06e536 100644 --- a/core/modules/system/tests/modules/system_test/system_test.info.yml +++ b/core/modules/system/tests/modules/system_test/system_test.info.yml @@ -8,8 +8,8 @@ configure: system_test.configure configure_parameters: foo: bar -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/system_test/system_test.module b/core/modules/system/tests/modules/system_test/system_test.module index 04fa2daa..81739086 100644 --- a/core/modules/system/tests/modules/system_test/system_test.module +++ b/core/modules/system/tests/modules/system_test/system_test.module @@ -27,7 +27,7 @@ function system_test_help($route_name, RouteMatchInterface $route_match) { function system_test_modules_installed($modules) { if (\Drupal::state()->get('system_test.verbose_module_hooks')) { foreach ($modules as $module) { - drupal_set_message(t('hook_modules_installed fired for @module', array('@module' => $module))); + drupal_set_message(t('hook_modules_installed fired for @module', ['@module' => $module])); } } } @@ -38,7 +38,7 @@ function system_test_modules_installed($modules) { function system_test_modules_uninstalled($modules) { if (\Drupal::state()->get('system_test.verbose_module_hooks')) { foreach ($modules as $module) { - drupal_set_message(t('hook_modules_uninstalled fired for @module', array('@module' => $module))); + drupal_set_message(t('hook_modules_uninstalled fired for @module', ['@module' => $module])); } } } @@ -66,12 +66,12 @@ function system_test_system_info_alter(&$info, Extension $file, $type) { if ($file->getName() == 'system_dependencies_test') { $info['hidden'] = FALSE; } - if (in_array($file->getName(), array( + if (in_array($file->getName(), [ 'system_incompatible_module_version_dependencies_test', 'system_incompatible_core_version_dependencies_test', 'system_incompatible_module_version_test', 'system_incompatible_core_version_test', - ))) { + ])) { $info['hidden'] = FALSE; } if ($file->getName() == 'requirements1_test' || $file->getName() == 'requirements2_test') { @@ -99,7 +99,7 @@ function system_test_page_attachments(array &$page) { */ function _system_test_first_shutdown_function($arg1, $arg2) { // Set something to ensure that this function got called. - \Drupal::state()->set('_system_test_first_shutdown_function', array($arg1, $arg2)); + \Drupal::state()->set('_system_test_first_shutdown_function', [$arg1, $arg2]); drupal_register_shutdown_function('_system_test_second_shutdown_function', $arg1, $arg2); } @@ -108,7 +108,7 @@ function _system_test_first_shutdown_function($arg1, $arg2) { */ function _system_test_second_shutdown_function($arg1, $arg2) { // Set something to ensure that this function got called. - \Drupal::state()->set('_system_test_second_shutdown_function', array($arg1, $arg2)); + \Drupal::state()->set('_system_test_second_shutdown_function', [$arg1, $arg2]); // Throw an exception with an HTML tag. Since this is called in a shutdown // function, it will not bubble up to the default exception handler but will @@ -121,13 +121,13 @@ function _system_test_second_shutdown_function($arg1, $arg2) { * Implements hook_filetransfer_info(). */ function system_test_filetransfer_info() { - return array( - 'system_test' => array( + return [ + 'system_test' => [ 'title' => t('System Test FileTransfer'), 'class' => 'Drupal\system_test\MockFileTransfer', 'weight' => -10, - ), - ); + ], + ]; } /** diff --git a/core/modules/system/tests/modules/system_test/system_test.routing.yml b/core/modules/system/tests/modules/system_test/system_test.routing.yml index f35f5462..b7cba071 100644 --- a/core/modules/system/tests/modules/system_test/system_test.routing.yml +++ b/core/modules/system/tests/modules/system_test/system_test.routing.yml @@ -182,3 +182,25 @@ system_test.header: _controller: '\Drupal\system_test\Controller\SystemTestController::getTestHeader' requirements: _access: 'TRUE' + +system_test.echo: + path: '/system-test/echo/{text}' + defaults: + _controller: '\Drupal\system_test\Controller\SystemTestController::simpleEcho' + requirements: + _access: 'TRUE' + +system_test.echo_utf8: + path: '/system-test/È„chÈ/meφΩ/{text}' + defaults: + _controller: '\Drupal\system_test\Controller\SystemTestController::simpleEcho' + requirements: + _access: 'TRUE' + +system_test.custom_cache_control: + path: '/system-test/custom-cache-control' + defaults: + _title: 'Cacheable response with custom cache control' + _controller: '\Drupal\system_test\Controller\SystemTestController::getCacheableResponseWithCustomCacheControl' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php b/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php index 7bb0fb11..e754eaf0 100644 --- a/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php +++ b/core/modules/system/tests/modules/test_page_test/src/Controller/Test.php @@ -1,6 +1,9 @@ 'Content', - ); + ]; } /** @@ -98,4 +101,26 @@ public function renderEncodedMarkup() { return ['#plain_text' => 'Bad html ']; } + /** + * Renders a page with pipe character in link test. + * + * @return array + * A render array as expected by drupal_render() + */ + public function renderPipeInLink() { + return ['#markup' => 'foo|bar|baz']; + } + + /** + * Loads a page that does a redirect. + * + * Drupal uses Symfony's RedirectResponse for generating redirects. That class + * uses a lower-case 'http-equiv="refresh"'. + * + * @see \Symfony\Component\HttpFoundation\RedirectResponse + */ + public function metaRefresh() { + return new RedirectResponse(Url::fromRoute('test_page_test.test_page', [], ['absolute' => TRUE])->toString(), 302); + } + } diff --git a/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php b/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php new file mode 100644 index 00000000..55b1b186 --- /dev/null +++ b/core/modules/system/tests/modules/test_page_test/src/Form/TestForm.php @@ -0,0 +1,107 @@ + 'table', + '#header' => ['Column 1', 'Column 2', 'Column 3'], + 'row_1' => [ + 'col_1' => ['#plain_text' => 'foo'], + 'col_2' => ['#plain_text' => 'bar'], + 'col_3' => ['#plain_text' => 'baz'], + ], + 'row_2' => [ + 'col_1' => ['#plain_text' => 'one'], + 'col_2' => ['#plain_text' => 'two'], + 'col_3' => ['#plain_text' => 'three'], + ], + ]; + + $form['name'] = [ + '#type' => 'textfield', + '#title' => 'Name', + '#default_value' => 'Test name', + ]; + + $form['checkbox_enabled'] = [ + '#type' => 'checkbox', + '#title' => 'Checkbox enabled', + '#default_value' => TRUE, + ]; + + $form['checkbox_disabled'] = [ + '#type' => 'checkbox', + '#title' => 'Checkbox disabled', + '#default_value' => FALSE, + ]; + + $form['description'] = [ + '#type' => 'textfield', + '#title' => 'Description', + '#default_value' => '', + ]; + + $form['options'] = [ + '#type' => 'select', + '#title' => 'Options', + '#options' => [ + 1 => 'one', + 2 => 'two', + 3 => 'three', + ], + '#default_value' => 2, + ]; + + $form['duplicate_button'] = [ + '#type' => 'submit', + '#name' => 'duplicate_button', + '#value' => 'Duplicate button 1', + ]; + + $form['duplicate_button_2'] = [ + '#type' => 'submit', + '#name' => 'duplicate_button', + '#value' => 'Duplicate button 2', + ]; + + $form['test_textarea_with_newline'] = [ + '#type' => 'textarea', + '#title' => 'Textarea with newline', + '#default_value' => "Test text with\nnewline", + ]; + + $form['save'] = [ + '#type' => 'submit', + '#value' => $this->t('Save'), + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'test_page_form'; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + // Empty on purpose, we just want to test the rendered form elements. + } + +} diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.info.yml b/core/modules/system/tests/modules/test_page_test/test_page_test.info.yml index 365964c0..5fbc948f 100644 --- a/core/modules/system/tests/modules/test_page_test/test_page_test.info.yml +++ b/core/modules/system/tests/modules/test_page_test/test_page_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml index cbcf6d83..e64a88d0 100644 --- a/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml +++ b/core/modules/system/tests/modules/test_page_test/test_page_test.routing.yml @@ -66,3 +66,27 @@ test_page_test.encoded: _controller: '\Drupal\test_page_test\Controller\Test::renderEncodedMarkup' requirements: _access: 'TRUE' + +test_page_test.pipe: + path: '/test-pipe-char' + defaults: + _title: 'Page with pipe char in link' + _controller: '\Drupal\test_page_test\Controller\Test::renderPipeInLink' + requirements: + _access: 'TRUE' + +test_page_test.field_xpath: + path: '/test-field-xpath' + defaults: + _title: 'Table and form elements for field xpath assertion testing' + _form: '\Drupal\test_page_test\Form\TestForm' + requirements: + _access: 'TRUE' + +test_page_test.meta_refresh: + path: '/test-meta-refresh' + defaults: + _title: 'Page with a redirect' + _controller: '\Drupal\test_page_test\Controller\Test::metaRefresh' + requirements: + _access: 'TRUE' diff --git a/core/modules/system/tests/modules/theme_page_test/theme_page_test.info.yml b/core/modules/system/tests/modules/theme_page_test/theme_page_test.info.yml index 51644813..bbf94368 100644 --- a/core/modules/system/tests/modules/theme_page_test/theme_page_test.info.yml +++ b/core/modules/system/tests/modules/theme_page_test/theme_page_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/theme_region_test/theme_region_test.info.yml b/core/modules/system/tests/modules/theme_region_test/theme_region_test.info.yml index 28f42e81..c7c237a9 100644 --- a/core/modules/system/tests/modules/theme_region_test/theme_region_test.info.yml +++ b/core/modules/system/tests/modules/theme_region_test/theme_region_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.info.yml b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.info.yml index a885ab06..c2741b47 100644 --- a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.info.yml +++ b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module index 974856ad..50fb86d2 100644 --- a/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module +++ b/core/modules/system/tests/modules/theme_suggestions_test/theme_suggestions_test.module @@ -9,11 +9,11 @@ * Implements hook_theme(). */ function theme_suggestions_test_theme() { - $items['theme_suggestions_test_include'] = array( + $items['theme_suggestions_test_include'] = [ 'file' => 'theme_suggestions_test.inc', - 'variables' => array(), + 'variables' => [], 'function' => 'theme_theme_suggestions_test_include', - ); + ]; return $items; } diff --git a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php index d5f9110a..99fe1923 100644 --- a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php +++ b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php @@ -17,7 +17,8 @@ class ThemeTestSubscriber implements EventSubscriberInterface { /** * The used container. * - * @var \Symfony\Component\DependencyInjection\IntrospectableContainerInterface + * @todo This variable is never initialzed, so we don't know what it is. + * See https://www.drupal.org/node/2721315 */ protected $container; @@ -63,11 +64,11 @@ public function onRequest(GetResponseEvent $event) { // theme_test_request_listener_page_callback() to test that even when the // theme system is initialized this early, it is still capable of // returning output and theming the page as a whole. - $more_link = array( + $more_link = [ '#type' => 'more_link', '#url' => Url::fromRoute('user.page'), - '#attributes' => array('title' => 'Themed output generated in a KernelEvents::REQUEST listener'), - ); + '#attributes' => ['title' => 'Themed output generated in a KernelEvents::REQUEST listener'], + ]; $GLOBALS['theme_test_output'] = $this->renderer->renderPlain($more_link); } } @@ -77,9 +78,9 @@ public function onRequest(GetResponseEvent $event) { */ public function onView(GetResponseEvent $event) { $current_route = $this->currentRouteMatch->getRouteName(); - $entity_autcomplete_route = array( + $entity_autcomplete_route = [ 'system.entity_autocomplete', - ); + ]; if (in_array($current_route, $entity_autcomplete_route)) { if ($this->container->initialized('theme.registry')) { @@ -91,9 +92,9 @@ public function onView(GetResponseEvent $event) { /** * {@inheritdoc} */ - static function getSubscribedEvents() { - $events[KernelEvents::REQUEST][] = array('onRequest'); - $events[KernelEvents::VIEW][] = array('onView', -1000); + public static function getSubscribedEvents() { + $events[KernelEvents::REQUEST][] = ['onRequest']; + $events[KernelEvents::VIEW][] = ['onView', -1000]; return $events; } diff --git a/core/modules/system/tests/modules/theme_test/src/ThemeTestController.php b/core/modules/system/tests/modules/theme_test/src/ThemeTestController.php index 639f1b74..f1ed8f3a 100644 --- a/core/modules/system/tests/modules/theme_test/src/ThemeTestController.php +++ b/core/modules/system/tests/modules/theme_test/src/ThemeTestController.php @@ -17,9 +17,9 @@ class ThemeTestController extends ControllerBase { * Render array containing a theme. */ public function functionTemplateOverridden() { - return array( + return [ '#theme' => 'theme_test_function_template_override', - ); + ]; } /** @@ -29,13 +29,13 @@ public function functionTemplateOverridden() { * A render array containing custom stylesheets. */ public function testInfoStylesheets() { - return array( - '#attached' => array( - 'library' => array( + return [ + '#attached' => [ + 'library' => [ 'theme_test/theme_stylesheets_override_and_remove_test', - ), - ), - ); + ], + ], + ]; } /** @@ -45,7 +45,7 @@ public function testInfoStylesheets() { * A render array containing a theme override. */ public function testTemplate() { - return ['#markup' => \Drupal::theme()->render('theme_test_template_test', array())]; + return ['#markup' => \Drupal::theme()->render('theme_test_template_test', [])]; } /** @@ -55,12 +55,12 @@ public function testTemplate() { * A render array containing an inline template. */ public function testInlineTemplate() { - $element = array(); - $element['test'] = array( + $element = []; + $element['test'] = [ '#type' => 'inline_template', '#template' => 'test-with-context {{ llama }}', - '#context' => array('llama' => 'muuh'), - ); + '#context' => ['llama' => 'muuh'], + ]; return $element; } @@ -71,7 +71,7 @@ public function testInlineTemplate() { * An HTML string containing the themed output. */ public function testSuggestion() { - return ['#markup' => \Drupal::theme()->render(array('theme_test__suggestion', 'theme_test'), array())]; + return ['#markup' => \Drupal::theme()->render(['theme_test__suggestion', 'theme_test'], [])]; } /** @@ -87,44 +87,44 @@ public function testRequestListener() { /** * Menu callback for testing suggestion alter hooks with template files. */ - function suggestionProvided() { - return array('#theme' => 'theme_test_suggestion_provided'); + public function suggestionProvided() { + return ['#theme' => 'theme_test_suggestion_provided']; } /** * Menu callback for testing suggestion alter hooks with template files. */ - function suggestionAlter() { - return array('#theme' => 'theme_test_suggestions'); + public function suggestionAlter() { + return ['#theme' => 'theme_test_suggestions']; } /** * Menu callback for testing hook_theme_suggestions_alter(). */ - function generalSuggestionAlter() { - return array('#theme' => 'theme_test_general_suggestions'); + public function generalSuggestionAlter() { + return ['#theme' => 'theme_test_general_suggestions']; } /** * Menu callback for testing suggestion alter hooks with specific suggestions. */ - function specificSuggestionAlter() { - return array('#theme' => 'theme_test_specific_suggestions__variant'); + public function specificSuggestionAlter() { + return ['#theme' => 'theme_test_specific_suggestions__variant']; } /** * Menu callback for testing suggestion alter hooks with theme functions. */ - function functionSuggestionAlter() { - return array('#theme' => 'theme_test_function_suggestions'); + public function functionSuggestionAlter() { + return ['#theme' => 'theme_test_function_suggestions']; } /** * Menu callback for testing includes with suggestion alter hooks. */ - function suggestionAlterInclude() { - return array('#theme' => 'theme_test_suggestions_include'); + public function suggestionAlterInclude() { + return ['#theme' => 'theme_test_suggestions_include']; } /** diff --git a/core/modules/system/tests/modules/theme_test/theme_test.info.yml b/core/modules/system/tests/modules/theme_test/theme_test.info.yml index eb4dfcaf..5b15f1aa 100644 --- a/core/modules/system/tests/modules/theme_test/theme_test.info.yml +++ b/core/modules/system/tests/modules/theme_test/theme_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/theme_test/theme_test.module b/core/modules/system/tests/modules/theme_test/theme_test.module index 540185ec..6a701abe 100644 --- a/core/modules/system/tests/modules/theme_test/theme_test.module +++ b/core/modules/system/tests/modules/theme_test/theme_test.module @@ -11,55 +11,55 @@ use Drupal\Core\Extension\Extension; * Implements hook_theme(). */ function theme_test_theme($existing, $type, $theme, $path) { - $items['theme_test'] = array( + $items['theme_test'] = [ 'file' => 'theme_test.inc', - 'variables' => array('foo' => ''), + 'variables' => ['foo' => ''], 'function' => 'theme_theme_test', - ); - $items['theme_test_template_test'] = array( + ]; + $items['theme_test_template_test'] = [ 'template' => 'theme_test.template_test', - ); - $items['theme_test_template_test_2'] = array( + ]; + $items['theme_test_template_test_2'] = [ 'template' => 'theme_test.template_test', - ); - $items['theme_test_suggestion_provided'] = array( - 'variables' => array(), - ); - $items['theme_test_specific_suggestions'] = array( - 'variables' => array(), - ); - $items['theme_test_suggestions'] = array( - 'variables' => array(), - ); - $items['theme_test_general_suggestions'] = array( - 'variables' => array(), - ); - $items['theme_test_function_suggestions'] = array( - 'variables' => array(), + ]; + $items['theme_test_suggestion_provided'] = [ + 'variables' => [], + ]; + $items['theme_test_specific_suggestions'] = [ + 'variables' => [], + ]; + $items['theme_test_suggestions'] = [ + 'variables' => [], + ]; + $items['theme_test_general_suggestions'] = [ + 'variables' => [], + ]; + $items['theme_test_function_suggestions'] = [ + 'variables' => [], 'function' => 'theme_theme_test_function_suggestions', - ); - $items['theme_test_suggestions_include'] = array( - 'variables' => array(), + ]; + $items['theme_test_suggestions_include'] = [ + 'variables' => [], 'function' => 'theme_theme_test_suggestions_include', - ); - $items['theme_test_foo'] = array( - 'variables' => array('foo' => NULL), + ]; + $items['theme_test_foo'] = [ + 'variables' => ['foo' => NULL], 'function' => 'theme_theme_test_foo', - ); - $items['theme_test_render_element'] = array( + ]; + $items['theme_test_render_element'] = [ 'render element' => 'elements', - ); - $items['theme_test_render_element_children'] = array( + ]; + $items['theme_test_render_element_children'] = [ 'render element' => 'element', 'function' => 'theme_theme_test_render_element_children', - ); - $items['theme_test_function_template_override'] = array( - 'variables' => array(), + ]; + $items['theme_test_function_template_override'] = [ + 'variables' => [], 'function' => 'theme_theme_test_function_template_override', - ); - $info['test_theme_not_existing_function'] = array( + ]; + $info['test_theme_not_existing_function'] = [ 'function' => 'test_theme_not_existing_function', - ); + ]; $items['theme_test_preprocess_suggestions'] = [ 'variables' => [ 'foo' => '', @@ -83,7 +83,7 @@ function theme_test_preprocess_html(&$variables) { * Implements hook_page_bottom(). */ function theme_test_page_bottom(array &$page_bottom) { - $page_bottom['theme_test_page_bottom'] = array('#markup' => 'theme test page bottom markup'); + $page_bottom['theme_test_page_bottom'] = ['#markup' => 'theme test page bottom markup']; } /** @@ -153,7 +153,7 @@ function template_preprocess_theme_test_render_element(&$variables) { * - element: An associative array containing the properties of the element. */ function theme_theme_test_render_element_children($variables) { - return drupal_render($variables['element']); + return \Drupal::service('renderer')->render($variables['element']); } /** @@ -167,7 +167,7 @@ function theme_theme_test_function_suggestions($variables) { * Implements hook_theme_suggestions_HOOK(). */ function theme_test_theme_suggestions_theme_test_suggestion_provided(array $variables) { - return array('theme_test_suggestion_provided__' . 'foo'); + return ['theme_test_suggestion_provided__' . 'foo']; } /** diff --git a/core/modules/system/tests/modules/token_test/src/Controller/TestController.php b/core/modules/system/tests/modules/token_test/src/Controller/TestController.php index 9f712ed3..019dbf79 100644 --- a/core/modules/system/tests/modules/token_test/src/Controller/TestController.php +++ b/core/modules/system/tests/modules/token_test/src/Controller/TestController.php @@ -2,7 +2,6 @@ namespace Drupal\token_test\Controller; - use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\Utility\Token; diff --git a/core/modules/system/tests/modules/token_test/token_test.info.yml b/core/modules/system/tests/modules/token_test/token_test.info.yml index 5f95b615..802e6b14 100644 --- a/core/modules/system/tests/modules/token_test/token_test.info.yml +++ b/core/modules/system/tests/modules/token_test/token_test.info.yml @@ -7,8 +7,8 @@ dependencies: - user - node -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/trusted_hosts_test/src/Controller/TrustedHostsTestController.php b/core/modules/system/tests/modules/trusted_hosts_test/src/Controller/TrustedHostsTestController.php index 68c8b64e..bb768421 100644 --- a/core/modules/system/tests/modules/trusted_hosts_test/src/Controller/TrustedHostsTestController.php +++ b/core/modules/system/tests/modules/trusted_hosts_test/src/Controller/TrustedHostsTestController.php @@ -1,6 +1,7 @@ new \Twig_Function_Function(array('Drupal\twig_extension_test\TwigExtension\TestExtension', 'testFunction')), - ); + return [ + 'testfunc' => new \Twig_Function_Function(['Drupal\twig_extension_test\TwigExtension\TestExtension', 'testFunction']), + ]; } /** @@ -40,9 +38,9 @@ public function getFunctions() { * The value is a standard PHP callback that defines what the filter does. */ public function getFilters() { - return array( - 'testfilter' => new \Twig_Filter_Function(array('Drupal\twig_extension_test\TwigExtension\TestExtension', 'testFilter')), - ); + return [ + 'testfilter' => new \Twig_Filter_Function(['Drupal\twig_extension_test\TwigExtension\TestExtension', 'testFilter']), + ]; } /** @@ -94,7 +92,7 @@ public static function testFunction($upperCase = FALSE) { * @see \Drupal\system\Tests\Theme\TwigExtensionTest::testTwigExtensionFilter() */ public static function testFilter($string) { - return str_replace(array('animal'), array('plant'), $string); + return str_replace(['animal'], ['plant'], $string); } } diff --git a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php index 44e42d95..c15b16d8 100644 --- a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php +++ b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php @@ -14,7 +14,7 @@ class TwigExtensionTestController { * Menu callback for testing Twig filters in a Twig template. */ public function testFilterRender() { - return array( + return [ '#theme' => 'twig_extension_test_filter', '#message' => 'Every animal is not a mineral.', '#safe_join_items' => [ @@ -22,14 +22,14 @@ public function testFilterRender() { $this->t('will be markup'), ['#markup' => 'will be rendered'] ] - ); + ]; } /** * Menu callback for testing Twig functions in a Twig template. */ public function testFunctionRender() { - return array('#theme' => 'twig_extension_test_function'); + return ['#theme' => 'twig_extension_test_function']; } } diff --git a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.info.yml b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.info.yml index eb3f0c9a..ed70460d 100644 --- a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.info.yml +++ b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module index f55e619a..eb69e344 100644 --- a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module +++ b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module @@ -9,14 +9,14 @@ * Implements hook_theme(). */ function twig_extension_test_theme($existing, $type, $theme, $path) { - return array( - 'twig_extension_test_filter' => array( - 'variables' => array('message' => NULL, 'safe_join_items' => NULL), + return [ + 'twig_extension_test_filter' => [ + 'variables' => ['message' => NULL, 'safe_join_items' => NULL], 'template' => 'twig_extension_test.filter', - ), - 'twig_extension_test_function' => array( + ], + 'twig_extension_test_function' => [ 'render element' => 'element', 'template' => 'twig_extension_test.function', - ), - ); + ], + ]; } diff --git a/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml b/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml index d98b0a85..c0dd1196 100644 --- a/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml +++ b/core/modules/system/tests/modules/twig_loader_test/twig_loader_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml index f627c878..8ae57eab 100644 --- a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml +++ b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_a/twig_namespace_a.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_b/twig_namespace_b.info.yml b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_b/twig_namespace_b.info.yml index f627c878..8ae57eab 100644 --- a/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_b/twig_namespace_b.info.yml +++ b/core/modules/system/tests/modules/twig_theme_test/modules/twig_namespace_b/twig_namespace_b.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php index 7408ce8f..8e1f69e7 100644 --- a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php +++ b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php @@ -14,16 +14,16 @@ class TwigThemeTestController { * Menu callback for testing PHP variables in a Twig template. */ public function phpVariablesRender() { - return ['#markup' => \Drupal::theme()->render('twig_theme_test_php_variables', array())]; + return ['#markup' => \Drupal::theme()->render('twig_theme_test_php_variables', [])]; } /** * Menu callback for testing translation blocks in a Twig template. */ public function transBlockRender() { - return array( + return [ '#theme' => 'twig_theme_test_trans', - ); + ]; } /** @@ -40,9 +40,9 @@ public function placeholderOutsideTransRender() { * Renders for testing url_generator functions in a Twig template. */ public function urlGeneratorRender() { - return array( + return [ '#theme' => 'twig_theme_test_url_generator', - ); + ]; } /** @@ -73,25 +73,25 @@ public function urlToStringRender() { * Renders for testing file_url functions in a Twig template. */ public function fileUrlRender() { - return array( + return [ '#theme' => 'twig_theme_test_file_url', - ); + ]; } /** * Renders for testing attach_library functions in a Twig template. */ public function attachLibraryRender() { - return array( + return [ '#theme' => 'twig_theme_test_attach_library', - ); + ]; } /** * Menu callback for testing the Twig registry loader. */ public function registryLoaderRender() { - return array('#theme' => 'twig_registry_loader_test'); + return ['#theme' => 'twig_registry_loader_test']; } /** diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig index a836aec9..1b20b46e 100644 --- a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.link_generator.html.twig @@ -7,3 +7,4 @@
    link via the linkgenerator: {{ link(title, test_url) }}
    {% set title %}register{% endset %}
    link via the linkgenerator: {{ link(title, test_url) }}
    +
    link via the linkgenerator: {{ link('register', test_url_attribute) }} {{ link('register', test_url_attribute) }}
    diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.es6.js b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.es6.js new file mode 100644 index 00000000..39bf0bb5 --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.es6.js @@ -0,0 +1,6 @@ +/** + * @file + * This file is for testing asset file inclusion, no contents are necessary. + * + * @ignore + */ diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.info.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.info.yml index 7c80b15d..4f1adbce 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.info.yml +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js index 39bf0bb5..9d11a7c1 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js @@ -1,6 +1,6 @@ /** - * @file - * This file is for testing asset file inclusion, no contents are necessary. - * - * @ignore - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ \ No newline at end of file diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module index b3a75e51..a8b40862 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module @@ -9,70 +9,70 @@ * Implements hook_theme(). */ function twig_theme_test_theme($existing, $type, $theme, $path) { - $items['twig_theme_test_filter'] = array( - 'variables' => array('quote' => array(), 'attributes' => array()), + $items['twig_theme_test_filter'] = [ + 'variables' => ['quote' => [], 'attributes' => []], 'template' => 'twig_theme_test.filter', - ); - $items['twig_theme_test_php_variables'] = array( + ]; + $items['twig_theme_test_php_variables'] = [ 'template' => 'twig_theme_test.php_variables', - ); - $items['twig_theme_test_trans'] = array( - 'variables' => array(), + ]; + $items['twig_theme_test_trans'] = [ + 'variables' => [], 'template' => 'twig_theme_test.trans', - ); - $items['twig_theme_test_placeholder_outside_trans'] = array( - 'variables' => array('var' => ''), + ]; + $items['twig_theme_test_placeholder_outside_trans'] = [ + 'variables' => ['var' => ''], 'template' => 'twig_theme_test.placeholder_outside_trans', - ); - $items['twig_namespace_test'] = array( - 'variables' => array(), + ]; + $items['twig_namespace_test'] = [ + 'variables' => [], 'template' => 'twig_namespace_test', - ); - $items['twig_registry_loader_test'] = array( - 'variables' => array(), - ); - $items['twig_registry_loader_test_include'] = array( - 'variables' => array(), - ); - $items['twig_registry_loader_test_extend'] = array( - 'variables' => array(), - ); - $items['twig_raw_test'] = array( - 'variables' => array('script' => ''), - ); - $items['twig_autoescape_test'] = array( - 'variables' => array('script' => ''), - ); - $items['twig_theme_test_url_generator'] = array( - 'variables' => array(), + ]; + $items['twig_registry_loader_test'] = [ + 'variables' => [], + ]; + $items['twig_registry_loader_test_include'] = [ + 'variables' => [], + ]; + $items['twig_registry_loader_test_extend'] = [ + 'variables' => [], + ]; + $items['twig_raw_test'] = [ + 'variables' => ['script' => ''], + ]; + $items['twig_autoescape_test'] = [ + 'variables' => ['script' => ''], + ]; + $items['twig_theme_test_url_generator'] = [ + 'variables' => [], 'template' => 'twig_theme_test.url_generator', - ); - $items['twig_theme_test_link_generator'] = array( + ]; + $items['twig_theme_test_link_generator'] = [ 'variables' => [ 'test_url' => NULL, 'test_url_attribute' => NULL, 'attributes' => [], ], 'template' => 'twig_theme_test.link_generator', - ); - $items['twig_theme_test_url_to_string'] = array( - 'variables' => array('test_url' => NULL), + ]; + $items['twig_theme_test_url_to_string'] = [ + 'variables' => ['test_url' => NULL], 'template' => 'twig_theme_test.url_to_string', - ); - $items['twig_theme_test_file_url'] = array( - 'variables' => array(), + ]; + $items['twig_theme_test_file_url'] = [ + 'variables' => [], 'template' => 'twig_theme_test.file_url', - ); - $items['twig_theme_test_attach_library'] = array( - 'variables' => array(), + ]; + $items['twig_theme_test_attach_library'] = [ + 'variables' => [], 'template' => 'twig_theme_test.attach_library', - ); - $items['twig_theme_test_renderable'] = array( - 'variables' => array( + ]; + $items['twig_theme_test_renderable'] = [ + 'variables' => [ 'renderable' => NULL, - ), + ], 'template' => 'twig_theme_test.renderable', - ); + ]; return $items; } @@ -83,36 +83,36 @@ function _test_theme_twig_php_values() { // Prefix each variable with "twig_" so that Twig doesn't get confused // between a variable and a primitive. Arrays are not tested since they should // be a Drupal render array. - return array( - 'twig_null' => array( + return [ + 'twig_null' => [ 'value' => NULL, 'expected' => '', - ), - 'twig_bool_false' => array( + ], + 'twig_bool_false' => [ 'value' => FALSE, 'expected' => '', - ), - 'twig_bool_true' => array( + ], + 'twig_bool_true' => [ 'value' => TRUE, 'expected' => '1', - ), - 'twig_int' => array( + ], + 'twig_int' => [ 'value' => 1, 'expected' => '1', - ), - 'twig_int_0' => array( + ], + 'twig_int_0' => [ 'value' => 0, 'expected' => '0', - ), - 'twig_float' => array( + ], + 'twig_float' => [ 'value' => 122.34343, 'expected' => '122.34343', - ), - 'twig_string' => array( + ], + 'twig_string' => [ 'value' => 'Hello world!', 'expected' => 'Hello world!', - ), - ); + ], + ]; } /** diff --git a/core/modules/system/tests/modules/update_script_test/src/Controller/UpdateScriptTestController.php b/core/modules/system/tests/modules/update_script_test/src/Controller/UpdateScriptTestController.php index b72ab1b9..e1c21c29 100644 --- a/core/modules/system/tests/modules/update_script_test/src/Controller/UpdateScriptTestController.php +++ b/core/modules/system/tests/modules/update_script_test/src/Controller/UpdateScriptTestController.php @@ -18,12 +18,12 @@ public function databaseUpdatesMenuItem(Request $request) { // @todo Simplify with https://www.drupal.org/node/2548095 $base_url = str_replace('/update.php', '', $request->getBaseUrl()); $url = (new Url('system.db_update'))->setOption('base_url', $base_url); - $build['main'] = array( + $build['main'] = [ '#type' => 'link', '#title' => $this->t('Run database updates'), '#url' => $url, '#access' => $url->access($this->currentUser()), - ); + ]; return $build; } diff --git a/core/modules/system/tests/modules/update_script_test/update_script_test.info.yml b/core/modules/system/tests/modules/update_script_test/update_script_test.info.yml index 156dd8b5..2fd41757 100644 --- a/core/modules/system/tests/modules/update_script_test/update_script_test.info.yml +++ b/core/modules/system/tests/modules/update_script_test/update_script_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_script_test/update_script_test.install b/core/modules/system/tests/modules/update_script_test/update_script_test.install index 0f1718d7..ce387432 100644 --- a/core/modules/system/tests/modules/update_script_test/update_script_test.install +++ b/core/modules/system/tests/modules/update_script_test/update_script_test.install @@ -9,27 +9,27 @@ * Implements hook_requirements(). */ function update_script_test_requirements($phase) { - $requirements = array(); + $requirements = []; if ($phase == 'update') { // Set a requirements warning or error when the test requests it. $requirement_type = \Drupal::config('update_script_test.settings')->get('requirement_type'); switch ($requirement_type) { case REQUIREMENT_WARNING: - $requirements['update_script_test'] = array( + $requirements['update_script_test'] = [ 'title' => 'Update script test', 'value' => 'Warning', 'description' => 'This is a requirements warning provided by the update_script_test module.', 'severity' => REQUIREMENT_WARNING, - ); + ]; break; case REQUIREMENT_ERROR: - $requirements['update_script_test'] = array( + $requirements['update_script_test'] = [ 'title' => 'Update script test', 'value' => 'Error', 'description' => 'This is a requirements error provided by the update_script_test module.', 'severity' => REQUIREMENT_ERROR, - ); + ]; break; } } diff --git a/core/modules/system/tests/modules/update_test_0/update_test_0.info.yml b/core/modules/system/tests/modules/update_test_0/update_test_0.info.yml index 2ffc607a..123bc793 100644 --- a/core/modules/system/tests/modules/update_test_0/update_test_0.info.yml +++ b/core/modules/system/tests/modules/update_test_0/update_test_0.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_1/update_test_1.info.yml b/core/modules/system/tests/modules/update_test_1/update_test_1.info.yml index 3e6ab798..54b8608b 100644 --- a/core/modules/system/tests/modules/update_test_1/update_test_1.info.yml +++ b/core/modules/system/tests/modules/update_test_1/update_test_1.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_1/update_test_1.install b/core/modules/system/tests/modules/update_test_1/update_test_1.install index 7ef5d98a..1d632c71 100644 --- a/core/modules/system/tests/modules/update_test_1/update_test_1.install +++ b/core/modules/system/tests/modules/update_test_1/update_test_1.install @@ -18,21 +18,21 @@ function update_test_1_update_dependencies() { // the correct array structure. Therefore, we use updates from the // update_test_0 module (which will be installed first) that they will not // get in the way of other tests. - $dependencies['update_test_0'][8001] = array( + $dependencies['update_test_0'][8001] = [ // Compare to update_test_2_update_dependencies(), where the same // update_test_0 module update function is forced to depend on an update // function from a different module. This allows us to test that both // dependencies are correctly recorded. 'update_test_1' => 8001, - ); - $dependencies['update_test_0'][8002] = array( + ]; + $dependencies['update_test_0'][8002] = [ // Compare to update_test_2_update_dependencies(), where the same // update_test_0 module update function is forced to depend on a // different update function within the same module. This allows us to // test that only the dependency on the higher-numbered update function // is recorded. 'update_test_1' => 8003, - ); + ]; return $dependencies; } diff --git a/core/modules/system/tests/modules/update_test_2/update_test_2.info.yml b/core/modules/system/tests/modules/update_test_2/update_test_2.info.yml index 3e6ab798..54b8608b 100644 --- a/core/modules/system/tests/modules/update_test_2/update_test_2.info.yml +++ b/core/modules/system/tests/modules/update_test_2/update_test_2.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_2/update_test_2.install b/core/modules/system/tests/modules/update_test_2/update_test_2.install index 42027204..8818545c 100644 --- a/core/modules/system/tests/modules/update_test_2/update_test_2.install +++ b/core/modules/system/tests/modules/update_test_2/update_test_2.install @@ -18,18 +18,18 @@ function update_test_2_update_dependencies() { // 2. update_test_3_update_8001() // 3. update_test_2_update_8002() // 4. update_test_2_update_8003() - $dependencies['update_test_2'][8002] = array( + $dependencies['update_test_2'][8002] = [ 'update_test_3' => 8001, - ); + ]; // These are coordinated with the corresponding dependencies declared in // update_test_1_update_dependencies(). - $dependencies['update_test_0'][8001] = array( + $dependencies['update_test_0'][8001] = [ 'update_test_2' => 8002, - ); - $dependencies['update_test_0'][8002] = array( + ]; + $dependencies['update_test_0'][8002] = [ 'update_test_1' => 8002, - ); + ]; return $dependencies; } diff --git a/core/modules/system/tests/modules/update_test_3/update_test_3.info.yml b/core/modules/system/tests/modules/update_test_3/update_test_3.info.yml index 3e6ab798..54b8608b 100644 --- a/core/modules/system/tests/modules/update_test_3/update_test_3.info.yml +++ b/core/modules/system/tests/modules/update_test_3/update_test_3.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_3/update_test_3.install b/core/modules/system/tests/modules/update_test_3/update_test_3.install index ae2da4b0..6a837b69 100644 --- a/core/modules/system/tests/modules/update_test_3/update_test_3.install +++ b/core/modules/system/tests/modules/update_test_3/update_test_3.install @@ -11,9 +11,9 @@ * @see update_test_2_update_dependencies() */ function update_test_3_update_dependencies() { - $dependencies['update_test_3'][8001] = array( + $dependencies['update_test_3'][8001] = [ 'update_test_2' => 8001, - ); + ]; return $dependencies; } diff --git a/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml b/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml index 154164c6..6c9b853f 100644 --- a/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml +++ b/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_invalid_hook/update_test_invalid_hook.info.yml b/core/modules/system/tests/modules/update_test_invalid_hook/update_test_invalid_hook.info.yml index a9e8ab80..c0a51893 100644 --- a/core/modules/system/tests/modules/update_test_invalid_hook/update_test_invalid_hook.info.yml +++ b/core/modules/system/tests/modules/update_test_invalid_hook/update_test_invalid_hook.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_postupdate/update_test_postupdate.info.yml b/core/modules/system/tests/modules/update_test_postupdate/update_test_postupdate.info.yml index 09a003cf..2a538084 100644 --- a/core/modules/system/tests/modules/update_test_postupdate/update_test_postupdate.info.yml +++ b/core/modules/system/tests/modules/update_test_postupdate/update_test_postupdate.info.yml @@ -4,8 +4,8 @@ type: module package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_schema/update_test_schema.info.yml b/core/modules/system/tests/modules/update_test_schema/update_test_schema.info.yml index 2fdd6a73..cfd54209 100644 --- a/core/modules/system/tests/modules/update_test_schema/update_test_schema.info.yml +++ b/core/modules/system/tests/modules/update_test_schema/update_test_schema.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.info.yml b/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.info.yml index c72aaf55..d5d5cd96 100644 --- a/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.info.yml +++ b/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php b/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php index b59fe4cc..3709907d 100644 --- a/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php +++ b/core/modules/system/tests/modules/url_alter_test/src/PathProcessor.php @@ -16,7 +16,7 @@ class PathProcessor implements InboundPathProcessorInterface { public function processInbound($path, Request $request) { if (preg_match('!^/user/([^/]+)(/.*)?!', $path, $matches)) { if ($account = user_load_by_name($matches[1])) { - $matches += array(2 => ''); + $matches += [2 => '']; $path = '/user/' . $account->id() . $matches[2]; } } diff --git a/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php b/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php index e6b9fc2f..9a89df9b 100644 --- a/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php +++ b/core/modules/system/tests/modules/url_alter_test/src/PathProcessorTest.php @@ -20,7 +20,7 @@ public function processInbound($path, Request $request) { // Rewrite user/username to user/uid. if (preg_match('!^/user/([^/]+)(/.*)?!', $path, $matches)) { if ($account = user_load_by_name($matches[1])) { - $matches += array(2 => ''); + $matches += [2 => '']; $path = '/user/' . $account->id() . $matches[2]; } } @@ -37,11 +37,11 @@ public function processInbound($path, Request $request) { /** * {@inheritdoc} */ - public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) { + public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) { // Rewrite user/uid to user/username. if (preg_match('!^/user/([0-9]+)(/.*)?!', $path, $matches)) { if ($account = User::load($matches[1])) { - $matches += array(2 => ''); + $matches += [2 => '']; $path = '/user/' . $account->getUsername() . $matches[2]; if ($bubbleable_metadata) { $bubbleable_metadata->addCacheTags($account->getCacheTags()); @@ -49,6 +49,11 @@ public function processOutbound($path, &$options = array(), Request $request = N } } + // Verify that $options are alterable. + if ($path == '/user/login') { + $options['query']['foo'] = 'bar'; + } + // Rewrite forum/ to community/. return preg_replace('@^/forum(.*)@', '/community$1', $path); } diff --git a/core/modules/system/tests/modules/url_alter_test/url_alter_test.info.yml b/core/modules/system/tests/modules/url_alter_test/url_alter_test.info.yml index 182cd492..db4fae11 100644 --- a/core/modules/system/tests/modules/url_alter_test/url_alter_test.info.yml +++ b/core/modules/system/tests/modules/url_alter_test/url_alter_test.info.yml @@ -5,8 +5,8 @@ description: 'A support module to test altering the inbound and outbound path.' package: Testing # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/src/Functional/Batch/PageTest.php b/core/modules/system/tests/src/Functional/Batch/PageTest.php new file mode 100644 index 00000000..b1e46a2e --- /dev/null +++ b/core/modules/system/tests/src/Functional/Batch/PageTest.php @@ -0,0 +1,82 @@ +container->get('theme_handler')->install(['seven', 'bartik']); + $this->config('system.theme') + ->set('default', 'bartik') + ->set('admin', 'seven') + ->save(); + + // Log in as an administrator who can see the administrative theme. + $admin_user = $this->drupalCreateUser(['view the administration theme']); + $this->drupalLogin($admin_user); + // Visit an administrative page that runs a test batch, and check that the + // theme that was used during batch execution (which the batch callback + // function saved as a variable) matches the theme used on the + // administrative page. + $this->drupalGet('admin/batch-test/test-theme'); + // The stack should contain the name of the theme used on the progress + // page. + $this->assertEqual(batch_test_stack(), ['seven'], 'A progressive batch correctly uses the theme of the page that started the batch.'); + } + + /** + * Tests that the batch API progress page shows the title correctly. + */ + public function testBatchProgressPageTitle() { + // Visit an administrative page that runs a test batch, and check that the + // title shown during batch execution (which the batch callback function + // saved as a variable) matches the theme used on the administrative page. + // Run initial step only first. + $this->maximumMetaRefreshCount = 0; + $this->drupalGet('batch-test/test-title'); + $this->assertText('Batch Test', 'The test is in the html output.'); + + // Leave the batch process running. + $this->maximumMetaRefreshCount = NULL; + $this->drupalGet('batch-test/test-title'); + + // The stack should contain the title shown on the progress page. + $this->assertEqual(batch_test_stack(), ['Batch Test'], 'The batch title is shown on the batch page.'); + $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); + } + + /** + * Tests that the progress messages are correct. + */ + public function testBatchProgressMessages() { + // Go to the initial step only. + $this->maximumMetaRefreshCount = 0; + $this->drupalGet('batch-test/test-title'); + $this->assertRaw('
    Initializing.
     
    ', 'Initial progress message appears correctly.'); + $this->assertNoRaw('&nbsp;', 'Initial progress message is not double escaped.'); + // Now also go to the next step. + $this->maximumMetaRefreshCount = 1; + $this->drupalGet('batch-test/test-title'); + $this->assertRaw('
    Completed 1 of 1.
    ', 'Progress message for second step appears correctly.'); + } + +} diff --git a/core/modules/system/src/Tests/Batch/ProcessingTest.php b/core/modules/system/tests/src/Functional/Batch/ProcessingTest.php similarity index 86% rename from core/modules/system/src/Tests/Batch/ProcessingTest.php rename to core/modules/system/tests/src/Functional/Batch/ProcessingTest.php index 66c0fc6b..2d7c7ae0 100644 --- a/core/modules/system/src/Tests/Batch/ProcessingTest.php +++ b/core/modules/system/tests/src/Functional/Batch/ProcessingTest.php @@ -1,28 +1,28 @@ drupalGet('batch-test/no-form'); $this->assertBatchMessages($this->_resultMessages('batch_1'), 'Batch for step 2 performed successfully.'); @@ -33,7 +33,7 @@ function testBatchNoForm() { /** * Tests batches that redirect in the batch finished callback. */ - function testBatchRedirectFinishedCallback() { + public function testBatchRedirectFinishedCallback() { // Displaying the page triggers batch 1. $this->drupalGet('batch-test/finish-redirect'); $this->assertBatchMessages($this->_resultMessages('batch_1'), 'Batch for step 2 performed successfully.'); @@ -45,16 +45,16 @@ function testBatchRedirectFinishedCallback() { /** * Tests batches defined in a form submit handler. */ - function testBatchForm() { + public function testBatchForm() { // Batch 0: no operation. - $edit = array('batch' => 'batch_0'); + $edit = ['batch' => 'batch_0']; $this->drupalPostForm('batch-test', $edit, 'Submit'); $this->assertNoEscaped('<', 'No escaped markup is present.'); $this->assertBatchMessages($this->_resultMessages('batch_0'), 'Batch with no operation performed successfully.'); $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); // Batch 1: several simple operations. - $edit = array('batch' => 'batch_1'); + $edit = ['batch' => 'batch_1']; $this->drupalPostForm('batch-test', $edit, 'Submit'); $this->assertNoEscaped('<', 'No escaped markup is present.'); $this->assertBatchMessages($this->_resultMessages('batch_1'), 'Batch with simple operations performed successfully.'); @@ -62,7 +62,7 @@ function testBatchForm() { $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); // Batch 2: one multistep operation. - $edit = array('batch' => 'batch_2'); + $edit = ['batch' => 'batch_2']; $this->drupalPostForm('batch-test', $edit, 'Submit'); $this->assertNoEscaped('<', 'No escaped markup is present.'); $this->assertBatchMessages($this->_resultMessages('batch_2'), 'Batch with multistep operation performed successfully.'); @@ -70,7 +70,7 @@ function testBatchForm() { $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); // Batch 3: simple + multistep combined. - $edit = array('batch' => 'batch_3'); + $edit = ['batch' => 'batch_3']; $this->drupalPostForm('batch-test', $edit, 'Submit'); $this->assertNoEscaped('<', 'No escaped markup is present.'); $this->assertBatchMessages($this->_resultMessages('batch_3'), 'Batch with simple and multistep operations performed successfully.'); @@ -78,7 +78,7 @@ function testBatchForm() { $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); // Batch 4: nested batch. - $edit = array('batch' => 'batch_4'); + $edit = ['batch' => 'batch_4']; $this->drupalPostForm('batch-test', $edit, 'Submit'); $this->assertNoEscaped('<', 'No escaped markup is present.'); $this->assertBatchMessages($this->_resultMessages('batch_4'), 'Nested batch performed successfully.'); @@ -89,34 +89,41 @@ function testBatchForm() { /** * Tests batches defined in a multistep form. */ - function testBatchFormMultistep() { + public function testBatchFormMultistep() { $this->drupalGet('batch-test/multistep'); $this->assertNoEscaped('<', 'No escaped markup is present.'); $this->assertText('step 1', 'Form is displayed in step 1.'); // First step triggers batch 1. - $this->drupalPostForm(NULL, array(), 'Submit'); + $this->drupalPostForm(NULL, [], 'Submit'); $this->assertBatchMessages($this->_resultMessages('batch_1'), 'Batch for step 1 performed successfully.'); $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_1'), 'Execution order was correct.'); $this->assertText('step 2', 'Form is displayed in step 2.'); $this->assertNoEscaped('<', 'No escaped markup is present.'); // Second step triggers batch 2. - $this->drupalPostForm(NULL, array(), 'Submit'); + $this->drupalPostForm(NULL, [], 'Submit'); $this->assertBatchMessages($this->_resultMessages('batch_2'), 'Batch for step 2 performed successfully.'); $this->assertEqual(batch_test_stack(), $this->_resultStack('batch_2'), 'Execution order was correct.'); $this->assertText('Redirection successful.', 'Redirection after batch execution is correct.'); $this->assertNoEscaped('<', 'No escaped markup is present.'); + + // Extra query arguments will trigger logic that will add them to the + // redirect URL. Make sure they are persisted. + $this->drupalGet('batch-test/multistep', ['query' => ['big_tree' => 'small_axe']]); + $this->drupalPostForm(NULL, [], 'Submit'); + $this->assertText('step 2', 'Form is displayed in step 2.'); + $this->assertTrue(strpos($this->getUrl(), 'batch-test/multistep?big_tree=small_axe'), 'Query argument was persisted and another extra argument was added.'); } /** * Tests batches defined in different submit handlers on the same form. */ - function testBatchFormMultipleBatches() { + public function testBatchFormMultipleBatches() { // Batches 1, 2 and 3 are triggered in sequence by different submit // handlers. Each submit handler modify the submitted 'value'. $value = rand(0, 255); - $edit = array('value' => $value); + $edit = ['value' => $value]; $this->drupalPostForm('batch-test/chained', $edit, 'Submit'); // Check that result messages are present and in the correct order. $this->assertBatchMessages($this->_resultMessages('chained'), 'Batches defined in separate submit handlers performed successfully.'); @@ -131,7 +138,7 @@ function testBatchFormMultipleBatches() { * * Same as above, but the form is submitted through drupal_form_execute(). */ - function testBatchFormProgrammatic() { + public function testBatchFormProgrammatic() { // Batches 1, 2 and 3 are triggered in sequence by different submit // handlers. Each submit handler modify the submitted 'value'. $value = rand(0, 255); @@ -147,12 +154,12 @@ function testBatchFormProgrammatic() { /** * Test form submission during a batch operation. */ - function testDrupalFormSubmitInBatch() { + public function testDrupalFormSubmitInBatch() { // Displaying the page triggers a batch that programmatically submits a // form. $value = rand(0, 255); $this->drupalGet('batch-test/nested-programmatic/' . $value); - $this->assertEqual(batch_test_stack(), array('mock form submitted with value = ' . $value), '\Drupal::formBuilder()->submitForm() ran successfully within a batch operation.'); + $this->assertEqual(batch_test_stack(), ['mock form submitted with value = ' . $value], '\Drupal::formBuilder()->submitForm() ran successfully within a batch operation.'); } /** @@ -160,7 +167,7 @@ function testDrupalFormSubmitInBatch() { * * @see https://www.drupal.org/node/600836 */ - function testBatchLargePercentage() { + public function testBatchLargePercentage() { // Displaying the page triggers batch 5. $this->drupalGet('batch-test/large-percentage'); $this->assertBatchMessages($this->_resultMessages('batch_5'), 'Batch for step 2 performed successfully.'); @@ -180,7 +187,7 @@ function testBatchLargePercentage() { * @return * TRUE on pass, FALSE on fail. */ - function assertBatchMessages($texts, $message) { + public function assertBatchMessages($texts, $message) { $pattern = '|' . implode('.*', $texts) . '|s'; return $this->assertPattern($pattern, $message); } @@ -188,8 +195,8 @@ function assertBatchMessages($texts, $message) { /** * Returns expected execution stacks for the test batches. */ - function _resultStack($id, $value = 0) { - $stack = array(); + public function _resultStack($id, $value = 0) { + $stack = []; switch ($id) { case 'batch_1': for ($i = 1; $i <= 10; $i++) { @@ -255,8 +262,8 @@ function _resultStack($id, $value = 0) { /** * Returns expected result messages for the test batches. */ - function _resultMessages($id) { - $messages = array(); + public function _resultMessages($id) { + $messages = []; switch ($id) { case 'batch_0': diff --git a/core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php b/core/modules/system/tests/src/Functional/Bootstrap/DrupalSetMessageTest.php similarity index 84% rename from core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php rename to core/modules/system/tests/src/Functional/Bootstrap/DrupalSetMessageTest.php index 29ca02f3..976e8beb 100644 --- a/core/modules/system/src/Tests/Bootstrap/DrupalSetMessageTest.php +++ b/core/modules/system/tests/src/Functional/Bootstrap/DrupalSetMessageTest.php @@ -1,27 +1,27 @@ drupalGet('system-test/drupal-set-message'); diff --git a/core/modules/system/tests/src/Functional/Cache/AssertPageCacheContextsAndTagsTrait.php b/core/modules/system/tests/src/Functional/Cache/AssertPageCacheContextsAndTagsTrait.php new file mode 100644 index 00000000..e0450d16 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Cache/AssertPageCacheContextsAndTagsTrait.php @@ -0,0 +1,192 @@ +config('system.performance'); + $config->set('cache.page.max_age', 300); + $config->save(); + } + + /** + * Gets a specific header value as array. + * + * @param string $header_name + * The header name. + * + * @return string[] + * The header value, potentially exploded by spaces. + */ + protected function getCacheHeaderValues($header_name) { + $header_value = $this->drupalGetHeader($header_name); + if (empty($header_value)) { + return []; + } + else { + return explode(' ', $header_value); + } + } + + /** + * Asserts whether an expected cache context was present in the last response. + * + * @param string $expected_cache_context + * The expected cache context. + */ + protected function assertCacheContext($expected_cache_context) { + $cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts')); + $this->assertTrue(in_array($expected_cache_context, $cache_contexts), "'" . $expected_cache_context . "' is present in the X-Drupal-Cache-Contexts header."); + } + + /** + * Asserts that a cache context was not present in the last response. + * + * @param string $not_expected_cache_context + * The expected cache context. + */ + protected function assertNoCacheContext($not_expected_cache_context) { + $cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts')); + $this->assertFalse(in_array($not_expected_cache_context, $cache_contexts), "'" . $not_expected_cache_context . "' is not present in the X-Drupal-Cache-Contexts header."); + } + + /** + * Asserts page cache miss, then hit for the given URL; checks cache headers. + * + * @param \Drupal\Core\Url $url + * The URL to test. + * @param string[] $expected_contexts + * The expected cache contexts for the given URL. + * @param string[] $expected_tags + * The expected cache tags for the given URL. + */ + protected function assertPageCacheContextsAndTags(Url $url, array $expected_contexts, array $expected_tags) { + $absolute_url = $url->setAbsolute()->toString(); + sort($expected_contexts); + sort($expected_tags); + + // Assert cache miss + expected cache contexts + tags. + $this->drupalGet($absolute_url); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); + $this->assertCacheTags($expected_tags); + $this->assertCacheContexts($expected_contexts); + + // Assert cache hit + expected cache contexts + tags. + $this->drupalGet($absolute_url); + $this->assertCacheTags($expected_tags); + $this->assertCacheContexts($expected_contexts); + + // Assert page cache item + expected cache tags. + $cid_parts = [$url->setAbsolute()->toString(), 'html']; + $cid = implode(':', $cid_parts); + $cache_entry = \Drupal::cache('page')->get($cid); + sort($cache_entry->tags); + $this->assertEqual($cache_entry->tags, $expected_tags); + $this->debugCacheTags($cache_entry->tags, $expected_tags); + } + + /** + * Provides debug information for cache tags. + * + * @param string[] $actual_tags + * The actual cache tags. + * @param string[] $expected_tags + * The expected cache tags. + */ + protected function debugCacheTags(array $actual_tags, array $expected_tags) { + if ($actual_tags !== $expected_tags) { + debug('Unwanted cache tags in response: ' . implode(',', array_diff($actual_tags, $expected_tags))); + debug('Missing cache tags in response: ' . implode(',', array_diff($expected_tags, $actual_tags))); + } + } + + /** + * Ensures that some cache tags are present in the current response. + * + * @param string[] $expected_tags + * The expected tags. + * @param bool $include_default_tags + * (optional) Whether the default cache tags should be included. + */ + protected function assertCacheTags(array $expected_tags, $include_default_tags = TRUE) { + // The anonymous role cache tag is only added if the user is anonymous. + if ($include_default_tags) { + if (\Drupal::currentUser()->isAnonymous()) { + $expected_tags = Cache::mergeTags($expected_tags, ['config:user.role.anonymous']); + } + $expected_tags[] = 'http_response'; + } + $actual_tags = $this->getCacheHeaderValues('X-Drupal-Cache-Tags'); + $expected_tags = array_unique($expected_tags); + sort($expected_tags); + sort($actual_tags); + $this->assertIdentical($actual_tags, $expected_tags); + $this->debugCacheTags($actual_tags, $expected_tags); + } + + /** + * Ensures that some cache contexts are present in the current response. + * + * @param string[] $expected_contexts + * The expected cache contexts. + * @param string $message + * (optional) A verbose message to output. + * @param bool $include_default_contexts + * (optional) Whether the default contexts should automatically be included. + * + * @return bool + * TRUE if the assertion succeeded, FALSE otherwise. + */ + protected function assertCacheContexts(array $expected_contexts, $message = NULL, $include_default_contexts = TRUE) { + if ($include_default_contexts) { + $default_contexts = ['languages:language_interface', 'theme']; + // Add the user.permission context to the list of default contexts except + // when user is already there. + if (!in_array('user', $expected_contexts)) { + $default_contexts[] = 'user.permissions'; + } + $expected_contexts = Cache::mergeContexts($expected_contexts, $default_contexts); + } + + $actual_contexts = $this->getCacheHeaderValues('X-Drupal-Cache-Contexts'); + sort($expected_contexts); + sort($actual_contexts); + $match = $actual_contexts === $expected_contexts; + if (!$match) { + debug('Unwanted cache contexts in response: ' . implode(',', array_diff($actual_contexts, $expected_contexts))); + debug('Missing cache contexts in response: ' . implode(',', array_diff($expected_contexts, $actual_contexts))); + } + + $this->assertIdentical($actual_contexts, $expected_contexts, $message); + + // For compatibility with both BrowserTestBase and WebTestBase always return + // a boolean. + return $match; + } + + /** + * Asserts the max age header. + * + * @param int $max_age + */ + protected function assertCacheMaxAge($max_age) { + $cache_control_header = $this->drupalGetHeader('Cache-Control'); + if (strpos($cache_control_header, 'max-age:' . $max_age) === FALSE) { + debug('Expected max-age:' . $max_age . '; Response max-age:' . $cache_control_header); + } + $this->assertTrue(strpos($cache_control_header, 'max-age:' . $max_age)); + } + +} diff --git a/core/modules/system/tests/src/Functional/Cache/CacheTestBase.php b/core/modules/system/tests/src/Functional/Cache/CacheTestBase.php new file mode 100644 index 00000000..f1439eae --- /dev/null +++ b/core/modules/system/tests/src/Functional/Cache/CacheTestBase.php @@ -0,0 +1,86 @@ +defaultBin; + } + + $cached = \Drupal::cache($bin)->get($cid); + + return isset($cached->data) && $cached->data == $var; + } + + /** + * Asserts that a cache entry exists. + * + * @param $message + * Message to display. + * @param $var + * The variable the cache should contain. + * @param $cid + * The cache id. + * @param $bin + * The bin the cache item was stored in. + */ + protected function assertCacheExists($message, $var = NULL, $cid = NULL, $bin = NULL) { + if ($bin == NULL) { + $bin = $this->defaultBin; + } + if ($cid == NULL) { + $cid = $this->defaultCid; + } + if ($var == NULL) { + $var = $this->defaultValue; + } + + $this->assertTrue($this->checkCacheExists($cid, $var, $bin), $message); + } + + /** + * Asserts that a cache entry has been removed. + * + * @param $message + * Message to display. + * @param $cid + * The cache id. + * @param $bin + * The bin the cache item was stored in. + */ + public function assertCacheRemoved($message, $cid = NULL, $bin = NULL) { + if ($bin == NULL) { + $bin = $this->defaultBin; + } + if ($cid == NULL) { + $cid = $this->defaultCid; + } + + $cached = \Drupal::cache($bin)->get($cid); + $this->assertFalse($cached, $message); + } + +} diff --git a/core/modules/system/src/Tests/Cache/ClearTest.php b/core/modules/system/tests/src/Functional/Cache/ClearTest.php similarity index 89% rename from core/modules/system/src/Tests/Cache/ClearTest.php rename to core/modules/system/tests/src/Functional/Cache/ClearTest.php index 3a3fe905..bec6d502 100644 --- a/core/modules/system/src/Tests/Cache/ClearTest.php +++ b/core/modules/system/tests/src/Functional/Cache/ClearTest.php @@ -1,6 +1,6 @@ assertTrue($bins, 'Cache::getBins() returned bins to flush.'); @@ -35,7 +35,7 @@ function testFlushAllCaches() { foreach ($bins as $bin => $cache_backend) { $cid = 'test_cid_clear' . $bin; - $this->assertFalse($this->checkCacheExists($cid, $this->defaultValue, $bin), format_string('All cache entries removed from @bin.', array('@bin' => $bin))); + $this->assertFalse($this->checkCacheExists($cid, $this->defaultValue, $bin), format_string('All cache entries removed from @bin.', ['@bin' => $bin])); } } diff --git a/core/modules/system/tests/src/Functional/Cache/PageCacheTagsTestBase.php b/core/modules/system/tests/src/Functional/Cache/PageCacheTagsTestBase.php new file mode 100644 index 00000000..69afeb74 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Cache/PageCacheTagsTestBase.php @@ -0,0 +1,62 @@ +config('system.performance'); + $config->set('cache.page.max_age', 3600); + $config->save(); + } + + /** + * Verify that when loading a given page, it's a page cache hit or miss. + * + * @param \Drupal\Core\Url $url + * The page for this URL will be loaded. + * @param string $hit_or_miss + * 'HIT' if a page cache hit is expected, 'MISS' otherwise. + * + * @param array|false $tags + * When expecting a page cache hit, you may optionally specify an array of + * expected cache tags. While FALSE, the cache tags will not be verified. + */ + protected function verifyPageCache(Url $url, $hit_or_miss, $tags = FALSE) { + $this->drupalGet($url); + $message = SafeMarkup::format('Page cache @hit_or_miss for %path.', ['@hit_or_miss' => $hit_or_miss, '%path' => $url->toString()]); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), $hit_or_miss, $message); + + if ($hit_or_miss === 'HIT' && is_array($tags)) { + $absolute_url = $url->setAbsolute()->toString(); + $cid_parts = [$absolute_url, 'html']; + $cid = implode(':', $cid_parts); + $cache_entry = \Drupal::cache('page')->get($cid); + sort($cache_entry->tags); + $tags = array_unique($tags); + sort($tags); + $this->assertIdentical($cache_entry->tags, $tags); + } + } + +} diff --git a/core/modules/system/src/Tests/Cache/SessionExistsCacheContextTest.php b/core/modules/system/tests/src/Functional/Cache/SessionExistsCacheContextTest.php similarity index 79% rename from core/modules/system/src/Tests/Cache/SessionExistsCacheContextTest.php rename to core/modules/system/tests/src/Functional/Cache/SessionExistsCacheContextTest.php index b3c195d5..78fb983a 100644 --- a/core/modules/system/src/Tests/Cache/SessionExistsCacheContextTest.php +++ b/core/modules/system/tests/src/Functional/Cache/SessionExistsCacheContextTest.php @@ -1,16 +1,16 @@ cookies, function ($item) { return $item['value'] !== 'deleted'; }); - $this->assertEqual($expected_present, isset($non_deleted_cookies[$this->getSessionName()]), 'Session cookie exists.'); + public function assertSessionCookieOnClient($expected_present) { + $this->assertEqual($expected_present, (bool) $this->getSession()->getCookie($this->getSessionName()), 'Session cookie exists.'); } } diff --git a/core/modules/system/tests/src/Functional/Database/DatabaseTestBase.php b/core/modules/system/tests/src/Functional/Database/DatabaseTestBase.php new file mode 100644 index 00000000..a28c1dba --- /dev/null +++ b/core/modules/system/tests/src/Functional/Database/DatabaseTestBase.php @@ -0,0 +1,27 @@ +drupalGet('database_test/pager_query_even/' . $limit, array('query' => array('page' => $page))); - $data = json_decode($this->getRawContent()); + $this->drupalGet('database_test/pager_query_even/' . $limit, ['query' => ['page' => $page]]); + $data = json_decode($this->getSession()->getPage()->getContent()); if ($page == $num_pages) { $correct_number = $count - ($limit * $page); } - $this->assertEqual(count($data->names), $correct_number, format_string('Correct number of records returned by pager: @number', array('@number' => $correct_number))); + $this->assertCount($correct_number, $data->names, format_string('Correct number of records returned by pager: @number', ['@number' => $correct_number])); } } @@ -50,7 +51,7 @@ function testEvenPagerQuery() { * Note that we have to make an HTTP request to a test page handler * because the pager depends on GET parameters. */ - function testOddPagerQuery() { + public function testOddPagerQuery() { // To keep the test from being too brittle, we determine up front // what the page count should be dynamically, and pass the control // information forward to the actual query on the other side of the @@ -67,14 +68,14 @@ function testOddPagerQuery() { } for ($page = 0; $page <= $num_pages; ++$page) { - $this->drupalGet('database_test/pager_query_odd/' . $limit, array('query' => array('page' => $page))); - $data = json_decode($this->getRawContent()); + $this->drupalGet('database_test/pager_query_odd/' . $limit, ['query' => ['page' => $page]]); + $data = json_decode($this->getSession()->getPage()->getContent()); if ($page == $num_pages) { $correct_number = $count - ($limit * $page); } - $this->assertEqual(count($data->names), $correct_number, format_string('Correct number of records returned by pager: @number', array('@number' => $correct_number))); + $this->assertCount($correct_number, $data->names, format_string('Correct number of records returned by pager: @number', ['@number' => $correct_number])); } } @@ -83,11 +84,11 @@ function testOddPagerQuery() { * * This is a regression test for #467984. */ - function testInnerPagerQuery() { + public function testInnerPagerQuery() { $query = db_select('test', 't') ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); $query - ->fields('t', array('age')) + ->fields('t', ['age']) ->orderBy('age') ->limit(5); @@ -97,7 +98,7 @@ function testInnerPagerQuery() { $ages = $outer_query ->execute() ->fetchCol(); - $this->assertEqual($ages, array(25, 26, 27, 28), 'Inner pager query returned the correct ages.'); + $this->assertEqual($ages, [25, 26, 27, 28], 'Inner pager query returned the correct ages.'); } /** @@ -105,37 +106,37 @@ function testInnerPagerQuery() { * * This is a regression test for #467984. */ - function testHavingPagerQuery() { + public function testHavingPagerQuery() { $query = db_select('test', 't') ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); $query - ->fields('t', array('name')) + ->fields('t', ['name']) ->orderBy('name') ->groupBy('name') - ->having('MAX(age) > :count', array(':count' => 26)) + ->having('MAX(age) > :count', [':count' => 26]) ->limit(5); $ages = $query ->execute() ->fetchCol(); - $this->assertEqual($ages, array('George', 'Ringo'), 'Pager query with having expression returned the correct ages.'); + $this->assertEqual($ages, ['George', 'Ringo'], 'Pager query with having expression returned the correct ages.'); } /** * Confirms that every pager gets a valid, non-overlapping element ID. */ - function testElementNumbers() { + public function testElementNumbers() { $request = Request::createFromGlobals(); - $request->query->replace(array( + $request->query->replace([ 'page' => '3, 2, 1, 0', - )); + ]); \Drupal::getContainer()->get('request_stack')->push($request); $name = db_select('test', 't') ->extend('Drupal\Core\Database\Query\PagerSelectExtender') ->element(2) - ->fields('t', array('name')) + ->fields('t', ['name']) ->orderBy('age') ->limit(1) ->execute() @@ -147,7 +148,7 @@ function testElementNumbers() { $name = db_select('test', 't') ->extend('Drupal\Core\Database\Query\PagerSelectExtender') ->element(1) - ->fields('t', array('name')) + ->fields('t', ['name']) ->orderBy('age') ->limit(1) ->execute() @@ -156,7 +157,7 @@ function testElementNumbers() { $name = db_select('test', 't') ->extend('Drupal\Core\Database\Query\PagerSelectExtender') - ->fields('t', array('name')) + ->fields('t', ['name']) ->orderBy('age') ->limit(1) ->execute() diff --git a/core/modules/system/tests/src/Functional/Database/SelectTableSortDefaultTest.php b/core/modules/system/tests/src/Functional/Database/SelectTableSortDefaultTest.php new file mode 100644 index 00000000..2904d31f --- /dev/null +++ b/core/modules/system/tests/src/Functional/Database/SelectTableSortDefaultTest.php @@ -0,0 +1,89 @@ + t('Task ID'), 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'], + ['field' => t('Task ID'), 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'], + ['field' => t('Task'), 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'], + ['field' => t('Task'), 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'], + // more elements here + + ]; + + foreach ($sorts as $sort) { + $this->drupalGet('database_test/tablesort/', ['query' => ['order' => $sort['field'], 'sort' => $sort['sort']]]); + $data = json_decode($this->getSession()->getPage()->getContent()); + + $first = array_shift($data->tasks); + $last = array_pop($data->tasks); + + $this->assertEqual($first->task, $sort['first'], 'Items appear in the correct order.'); + $this->assertEqual($last->task, $sort['last'], 'Items appear in the correct order.'); + } + } + + /** + * Confirms precedence of tablesorts headers. + * + * If a tablesort's orderByHeader is called before another orderBy, then its + * header happens first. + */ + public function testTableSortQueryFirst() { + $sorts = [ + ['field' => t('Task ID'), 'sort' => 'desc', 'first' => 'perform at superbowl', 'last' => 'eat'], + ['field' => t('Task ID'), 'sort' => 'asc', 'first' => 'eat', 'last' => 'perform at superbowl'], + ['field' => t('Task'), 'sort' => 'asc', 'first' => 'code', 'last' => 'sleep'], + ['field' => t('Task'), 'sort' => 'desc', 'first' => 'sleep', 'last' => 'code'], + // more elements here + + ]; + + foreach ($sorts as $sort) { + $this->drupalGet('database_test/tablesort_first/', ['query' => ['order' => $sort['field'], 'sort' => $sort['sort']]]); + $data = json_decode($this->getSession()->getPage()->getContent()); + + $first = array_shift($data->tasks); + $last = array_pop($data->tasks); + + $this->assertEqual($first->task, $sort['first'], format_string('Items appear in the correct order sorting by @field @sort.', ['@field' => $sort['field'], '@sort' => $sort['sort']])); + $this->assertEqual($last->task, $sort['last'], format_string('Items appear in the correct order sorting by @field @sort.', ['@field' => $sort['field'], '@sort' => $sort['sort']])); + } + } + + /** + * Confirms that tableselect is rendered without error. + * + * Specifically that no sort is set in a tableselect, and that header links + * are correct. + */ + public function testTableSortDefaultSort() { + $assert = $this->assertSession(); + + $this->drupalGet('database_test/tablesort_default_sort'); + + // Verify that the table was displayed. Just the header is checked for + // because if there were any fatal errors or exceptions in displaying the + // sorted table, it would not print the table. + $assert->pageTextContains(t('Username')); + + // Verify that the header links are built properly. + $assert->linkByHrefExists('database_test/tablesort_default_sort'); + $assert->responseMatches('/\/'); + } + +} diff --git a/core/modules/system/src/Tests/Database/TemporaryQueryTest.php b/core/modules/system/tests/src/Functional/Database/TemporaryQueryTest.php similarity index 80% rename from core/modules/system/src/Tests/Database/TemporaryQueryTest.php rename to core/modules/system/tests/src/Functional/Database/TemporaryQueryTest.php index 1bfa7546..52265857 100644 --- a/core/modules/system/src/Tests/Database/TemporaryQueryTest.php +++ b/core/modules/system/tests/src/Functional/Database/TemporaryQueryTest.php @@ -1,34 +1,32 @@ countQuery()->execute()->fetchField(); } /** * Confirms that temporary tables work and are limited to one request. */ - function testTemporaryQuery() { + public function testTemporaryQuery() { $this->drupalGet('database_test/db_query_temporary'); - $data = json_decode($this->getRawContent()); + $data = json_decode($this->getSession()->getPage()->getContent()); if ($data) { $this->assertEqual($this->countTableRows('test'), $data->row_count, 'The temporary table contains the correct amount of rows.'); $this->assertFalse(db_table_exists($data->table_name), 'The temporary table is, indeed, temporary.'); @@ -38,8 +36,8 @@ function testTemporaryQuery() { } // Now try to run two db_query_temporary() in the same request. - $table_name_test = db_query_temporary('SELECT name FROM {test}', array()); - $table_name_task = db_query_temporary('SELECT pid FROM {test_task}', array()); + $table_name_test = db_query_temporary('SELECT name FROM {test}', []); + $table_name_task = db_query_temporary('SELECT pid FROM {test_task}', []); $this->assertEqual($this->countTableRows($table_name_test), $this->countTableRows('test'), 'A temporary table was created successfully in this request.'); $this->assertEqual($this->countTableRows($table_name_task), $this->countTableRows('test_task'), 'A second temporary table was created successfully in this request.'); @@ -50,7 +48,7 @@ function testTemporaryQuery() { -- Let's select some rows into a temporary table SELECT name FROM {test} "; - $table_name_test = db_query_temporary($sql, array()); + $table_name_test = db_query_temporary($sql, []); $this->assertEqual($this->countTableRows($table_name_test), $this->countTableRows('test'), 'Leading white space and comments do not interfere with temporary table creation.'); } diff --git a/core/modules/system/src/Tests/Datetime/DrupalDateTimeTest.php b/core/modules/system/tests/src/Functional/Datetime/DrupalDateTimeTest.php similarity index 87% rename from core/modules/system/src/Tests/Datetime/DrupalDateTimeTest.php rename to core/modules/system/tests/src/Functional/Datetime/DrupalDateTimeTest.php index 219bc345..d2114fdf 100644 --- a/core/modules/system/src/Tests/Datetime/DrupalDateTimeTest.php +++ b/core/modules/system/tests/src/Functional/Datetime/DrupalDateTimeTest.php @@ -1,9 +1,9 @@ array( + $options = [ + 'query' => [ 'date' => 'Tue+Sep+17+2013+21%3A35%3A31+GMT%2B0100+(BST)#', - ) - ); + ] + ]; // Query the AJAX Timezone Callback with a long-format date. $response = $this->drupalGet('system/timezone/BST/3600/1', $options); $this->assertEqual($response, '"Europe\/London"', 'Timezone AJAX callback successfully identifies and responds to a long-format date.'); @@ -80,11 +80,11 @@ public function testDateTimezone() { // Create user. $this->config('system.date')->set('timezone.user.configurable', 1)->save(); - $test_user = $this->drupalCreateUser(array()); + $test_user = $this->drupalCreateUser([]); $this->drupalLogin($test_user); // Set up the user with a different timezone than the site. - $edit = array('mail' => $test_user->getEmail(), 'timezone' => 'Asia/Manila'); + $edit = ['mail' => $test_user->getEmail(), 'timezone' => 'Asia/Manila']; $this->drupalPostForm('user/' . $test_user->id() . '/edit', $edit, t('Save')); // Reload the user and reset the timezone in AccountProxy::setAccount(). @@ -101,7 +101,7 @@ public function testDateTimezone() { /** * Tests the ability to override the time zone in the format method. */ - function testTimezoneFormat() { + public function testTimezoneFormat() { // Create a date in UTC $date = DrupalDateTime::createFromTimestamp(87654321, 'UTC'); @@ -109,7 +109,7 @@ function testTimezoneFormat() { $this->assertEqual($date->format('Y/m/d H:i:s e'), '1972/10/11 12:25:21 UTC', 'Date has default UTC time zone and correct date/time.'); // Verify that the format method can override the time zone. - $this->assertEqual($date->format('Y/m/d H:i:s e', array('timezone' => 'America/New_York')), '1972/10/11 08:25:21 America/New_York', 'Date displayed overidden time zone and correct date/time'); + $this->assertEqual($date->format('Y/m/d H:i:s e', ['timezone' => 'America/New_York']), '1972/10/11 08:25:21 America/New_York', 'Date displayed overidden time zone and correct date/time'); // Verify that the date format method still displays the default time zone // for the date object. diff --git a/core/modules/system/tests/src/Functional/DrupalKernel/ContainerRebuildWebTest.php b/core/modules/system/tests/src/Functional/DrupalKernel/ContainerRebuildWebTest.php new file mode 100644 index 00000000..828b92f2 --- /dev/null +++ b/core/modules/system/tests/src/Functional/DrupalKernel/ContainerRebuildWebTest.php @@ -0,0 +1,59 @@ +assertSession(); + + // Ensure the parameter is not set. + $this->drupalGet(''); + $assert->responseHeaderEquals('container_rebuild_indicator', NULL); + + $this->writeSettings(['settings' => ['deployment_identifier' => (object) ['value' => 'new-identifier', 'required' => TRUE]]]); + + $this->drupalGet(''); + + $assert->responseHeaderEquals('container_rebuild_indicator', 'new-identifier'); + } + + /** + * Tests container invalidation. + */ + public function testContainerInvalidation() { + $assert = $this->assertSession(); + + // Ensure that parameter is not set. + $this->drupalGet(''); + $assert->responseHeaderEquals('container_rebuild_test_parameter', NULL); + + // Ensure that after setting the parameter, without a container rebuild the + // parameter is still not set. + $this->writeSettings(['settings' => ['container_rebuild_test_parameter' => (object) ['value' => 'rebuild_me_please', 'required' => TRUE]]]); + + $this->drupalGet(''); + $assert->responseHeaderEquals('container_rebuild_test_parameter', NULL); + + // Ensure that after container invalidation the parameter is set. + \Drupal::service('kernel')->invalidateContainer(); + $this->drupalGet(''); + $assert->responseHeaderEquals('container_rebuild_test_parameter', 'rebuild_me_please'); + } + +} diff --git a/core/modules/system/src/Tests/DrupalKernel/ContentNegotiationTest.php b/core/modules/system/tests/src/Functional/DrupalKernel/ContentNegotiationTest.php similarity index 88% rename from core/modules/system/src/Tests/DrupalKernel/ContentNegotiationTest.php rename to core/modules/system/tests/src/Functional/DrupalKernel/ContentNegotiationTest.php index dcd88ec5..58157369 100644 --- a/core/modules/system/src/Tests/DrupalKernel/ContentNegotiationTest.php +++ b/core/modules/system/tests/src/Functional/DrupalKernel/ContentNegotiationTest.php @@ -1,15 +1,15 @@ 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'IE8 (2009)' => 'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, */*', @@ -34,9 +34,9 @@ function testBogusAcceptHeader() { 'Safari (2010), iOS 4.2.1 (2012)' => 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'Android #1 (2012)' => 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'Android #2 (2012)' => 'text/xml,text/html,application/xhtml+xml,image/png,text/plain,*/*;q=0.8', - ); + ]; foreach ($tests as $case => $header) { - $this->drupalGet('', array(), array('Accept: ' . $header)); + $this->drupalGet('', [], ['Accept: ' . $header]); $this->assertNoText('Unsupported Media Type', '"Unsupported Media Type" not found for ' . $case); $this->assertText(t('Log in'), '"Log in" found for ' . $case); } diff --git a/core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php b/core/modules/system/tests/src/Functional/Entity/ConfigEntityImportTest.php similarity index 96% rename from core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php rename to core/modules/system/tests/src/Functional/Entity/ConfigEntityImportTest.php index 0f731bea..6c5a9d64 100644 --- a/core/modules/system/src/Tests/Entity/ConfigEntityImportTest.php +++ b/core/modules/system/tests/src/Functional/Entity/ConfigEntityImportTest.php @@ -1,12 +1,12 @@ 'apple', 'plugin' => 'action_message_action', - )); + ]); $entity->save(); $this->checkSinglePluginConfigSync($entity, 'configuration', 'message', ''); @@ -69,10 +69,10 @@ protected function doActionUpdate() { protected function doBlockUpdate() { // Create a test block with a known label. $name = 'block.block.apple'; - $block = $this->drupalPlaceBlock('system_powered_by_block', array( + $block = $this->drupalPlaceBlock('system_powered_by_block', [ 'id' => 'apple', 'label' => 'Red Delicious', - )); + ]); $this->checkSinglePluginConfigSync($block, 'settings', 'label', 'Red Delicious'); diff --git a/core/modules/system/src/Tests/Entity/EntityAddUITest.php b/core/modules/system/tests/src/Functional/Entity/EntityAddUITest.php similarity index 97% rename from core/modules/system/src/Tests/Entity/EntityAddUITest.php rename to core/modules/system/tests/src/Functional/Entity/EntityAddUITest.php index f0b286f1..a16614f1 100644 --- a/core/modules/system/src/Tests/Entity/EntityAddUITest.php +++ b/core/modules/system/tests/src/Functional/Entity/EntityAddUITest.php @@ -1,18 +1,18 @@ grantPermission('view test entity'); + $user_role->save(); + + // Create an entity. + $this->entity = $this->createEntity(); + + // If this is an entity with field UI enabled, then add a configurable + // field. We will use this configurable field in later tests to ensure that + // field configuration invalidate render cache entries. + if ($this->entity->getEntityType()->get('field_ui_base_route')) { + // Add field, so we can modify the field storage and field entities to + // verify that changes to those indeed clear cache tags. + FieldStorageConfig::create([ + 'field_name' => 'configurable_field', + 'entity_type' => $this->entity->getEntityTypeId(), + 'type' => 'test_field', + 'settings' => [], + ])->save(); + FieldConfig::create([ + 'entity_type' => $this->entity->getEntityTypeId(), + 'bundle' => $this->entity->bundle(), + 'field_name' => 'configurable_field', + 'label' => 'Configurable field', + 'settings' => [], + ])->save(); + + // Reload the entity now that a new field has been added to it. + $storage = $this->container + ->get('entity.manager') + ->getStorage($this->entity->getEntityTypeId()); + $storage->resetCache(); + $this->entity = $storage->load($this->entity->id()); + } + + // Create a referencing and a non-referencing entity. + list( + $this->referencingEntity, + $this->nonReferencingEntity, + ) = $this->createReferenceTestEntities($this->entity); + } + + /** + * Generates standardized entity cache tags test info. + * + * @param string $entity_type_label + * The label of the entity type whose cache tags to test. + * @param string $group + * The test group. + * + * @return array + * + * @see \Drupal\simpletest\TestBase::getInfo() + */ + protected static function generateStandardizedInfo($entity_type_label, $group) { + return [ + 'name' => "$entity_type_label entity cache tags", + 'description' => "Test the $entity_type_label entity's cache tags.", + 'group' => $group, + ]; + } + + /** + * Creates the entity to be tested. + * + * @return \Drupal\Core\Entity\EntityInterface + * The entity to be tested. + */ + abstract protected function createEntity(); + + /** + * Returns the access cache contexts for the tested entity. + * + * Only list cache contexts that aren't part of the required cache contexts. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to be tested, as created by createEntity(). + * + * @return string[] + * An array of the additional cache contexts. + * + * @see \Drupal\Core\Entity\EntityAccessControlHandlerInterface + */ + protected function getAccessCacheContextsForEntity(EntityInterface $entity) { + return []; + } + + /** + * Returns the additional (non-standard) cache contexts for the tested entity. + * + * Only list cache contexts that aren't part of the required cache contexts. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to be tested, as created by createEntity(). + * + * @return string[] + * An array of the additional cache contexts. + * + * @see \Drupal\system\Tests\Entity\EntityCacheTagsTestBase::createEntity() + */ + protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) { + return []; + } + + /** + * Returns the additional (non-standard) cache tags for the tested entity. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to be tested, as created by createEntity(). + * @return array + * An array of the additional cache tags. + * + * @see \Drupal\system\Tests\Entity\EntityCacheTagsTestBase::createEntity() + */ + protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) { + return []; + } + + /** + * Returns the additional cache tags for the tested entity's listing by type. + * + * @return string[] + * An array of the additional cache contexts. + */ + protected function getAdditionalCacheContextsForEntityListing() { + return []; + } + + /** + * Returns the additional cache tags for the tested entity's listing by type. + * + * Necessary when there are unavoidable default entities of this type, e.g. + * the anonymous and administrator User entities always exist. + * + * @return array + * An array of the additional cache tags. + */ + protected function getAdditionalCacheTagsForEntityListing() { + return []; + } + + /** + * Selects the preferred view mode for the given entity type. + * + * Prefers 'full', picks the first one otherwise, and if none are available, + * chooses 'default'. + */ + protected function selectViewMode($entity_type) { + $view_modes = \Drupal::entityManager() + ->getStorage('entity_view_mode') + ->loadByProperties(['targetEntityType' => $entity_type]); + + if (empty($view_modes)) { + return 'default'; + } + else { + // Prefer the "full" display mode. + if (isset($view_modes[$entity_type . '.full'])) { + return 'full'; + } + else { + $view_modes = array_keys($view_modes); + return substr($view_modes[0], strlen($entity_type) + 1); + } + } + } + + /** + * Creates a referencing and a non-referencing entity for testing purposes. + * + * @param \Drupal\Core\Entity\EntityInterface $referenced_entity + * The entity that the referencing entity should reference. + * + * @return \Drupal\Core\Entity\EntityInterface[] + * An array containing a referencing entity and a non-referencing entity. + */ + protected function createReferenceTestEntities($referenced_entity) { + // All referencing entities should be of the type 'entity_test'. + $entity_type = 'entity_test'; + + // Create a "foo" bundle for the given entity type. + $bundle = 'foo'; + entity_test_create_bundle($bundle, NULL, $entity_type); + + // Add a field of the given type to the given entity type's "foo" bundle. + $field_name = $referenced_entity->getEntityTypeId() . '_reference'; + FieldStorageConfig::create([ + 'field_name' => $field_name, + 'entity_type' => $entity_type, + 'type' => 'entity_reference', + 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + 'settings' => [ + 'target_type' => $referenced_entity->getEntityTypeId(), + ], + ])->save(); + FieldConfig::create([ + 'field_name' => $field_name, + 'entity_type' => $entity_type, + 'bundle' => $bundle, + 'settings' => [ + 'handler' => 'default', + 'handler_settings' => [ + 'target_bundles' => [ + $referenced_entity->bundle() => $referenced_entity->bundle(), + ], + 'sort' => ['field' => '_none'], + 'auto_create' => FALSE, + ], + ], + ])->save(); + if (!$this->entity->getEntityType()->hasHandlerClass('view_builder')) { + entity_get_display($entity_type, $bundle, 'full') + ->setComponent($field_name, [ + 'type' => 'entity_reference_label', + ]) + ->save(); + } + else { + $referenced_entity_view_mode = $this->selectViewMode($this->entity->getEntityTypeId()); + entity_get_display($entity_type, $bundle, 'full') + ->setComponent($field_name, [ + 'type' => 'entity_reference_entity_view', + 'settings' => [ + 'view_mode' => $referenced_entity_view_mode, + ], + ]) + ->save(); + } + + // Create an entity that does reference the entity being tested. + $label_key = \Drupal::entityManager()->getDefinition($entity_type)->getKey('label'); + $referencing_entity = $this->container->get('entity_type.manager') + ->getStorage($entity_type) + ->create([ + $label_key => 'Referencing ' . $entity_type, + 'status' => 1, + 'type' => $bundle, + $field_name => ['target_id' => $referenced_entity->id()], + ]); + $referencing_entity->save(); + + // Create an entity that does not reference the entity being tested. + $non_referencing_entity = $this->container->get('entity_type.manager') + ->getStorage($entity_type) + ->create([ + $label_key => 'Non-referencing ' . $entity_type, + 'status' => 1, + 'type' => $bundle, + ]); + $non_referencing_entity->save(); + + return [ + $referencing_entity, + $non_referencing_entity, + ]; + } + + /** + * Tests cache tags presence and invalidation of the entity when referenced. + * + * Tests the following cache tags: + * - entity type view cache tag: "_view" + * - entity cache tag: ":" + * - entity type list cache tag: "_list" + * - referencing entity type view cache tag: "_view" + * - referencing entity type cache tag: ":" + */ + public function testReferencedEntity() { + $entity_type = $this->entity->getEntityTypeId(); + $referencing_entity_url = $this->referencingEntity->urlInfo('canonical'); + $non_referencing_entity_url = $this->nonReferencingEntity->urlInfo('canonical'); + $listing_url = Url::fromRoute('entity.entity_test.collection_referencing_entities', [ + 'entity_reference_field_name' => $entity_type . '_reference', + 'referenced_entity_type' => $entity_type, + 'referenced_entity_id' => $this->entity->id(), + ]); + $empty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_empty', ['entity_type_id' => $entity_type]); + $nonempty_entity_listing_url = Url::fromRoute('entity.entity_test.collection_labels_alphabetically', ['entity_type_id' => $entity_type]); + + // The default cache contexts for rendered entities. + $default_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions']; + $entity_cache_contexts = $default_cache_contexts; + $page_cache_contexts = Cache::mergeContexts($default_cache_contexts, ['url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT]); + + // Cache tags present on every rendered page. + // 'user.permissions' is a required cache context, and responses that vary + // by this cache context when requested by anonymous users automatically + // also get this cache tag, to ensure correct invalidation. + $page_cache_tags = Cache::mergeTags(['http_response', 'rendered'], ['config:user.role.anonymous']); + // If the block module is used, the Block page display variant is used, + // which adds the block config entity type's list cache tags. + $page_cache_tags = Cache::mergeTags($page_cache_tags, \Drupal::moduleHandler()->moduleExists('block') ? ['config:block_list'] : []); + + $page_cache_tags_referencing_entity = in_array('user.permissions', $this->getAccessCacheContextsForEntity($this->referencingEntity)) ? ['config:user.role.anonymous'] : []; + + $view_cache_tag = []; + if ($this->entity->getEntityType()->hasHandlerClass('view_builder')) { + $view_cache_tag = \Drupal::entityManager()->getViewBuilder($entity_type) + ->getCacheTags(); + } + + $context_metadata = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($entity_cache_contexts); + $cache_context_tags = $context_metadata->getCacheTags(); + + // Generate the cache tags for the (non) referencing entities. + $referencing_entity_cache_tags = Cache::mergeTags($this->referencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags()); + // Includes the main entity's cache tags, since this entity references it. + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $this->entity->getCacheTags()); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $this->getAdditionalCacheTagsForEntity($this->entity)); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $view_cache_tag); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $cache_context_tags); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['rendered']); + + $non_referencing_entity_cache_tags = Cache::mergeTags($this->nonReferencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags()); + $non_referencing_entity_cache_tags = Cache::mergeTags($non_referencing_entity_cache_tags, ['rendered']); + + // Generate the cache tags for all two possible entity listing paths. + // 1. list cache tag only (listing query has no match) + // 2. list cache tag plus entity cache tag (listing query has a match) + $empty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $page_cache_tags); + + $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->entity->getCacheTags()); + $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $this->getAdditionalCacheTagsForEntityListing($this->entity)); + $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags); + + $this->pass("Test referencing entity.", 'Debug'); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + + // Verify a cache hit, but also the presence of the correct cache tags. + $expected_tags = Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags); + $expected_tags = Cache::mergeTags($expected_tags, $page_cache_tags_referencing_entity); + $this->verifyPageCache($referencing_entity_url, 'HIT', $expected_tags); + + // Also verify the existence of an entity render cache entry. + $cache_keys = ['entity_view', 'entity_test', $this->referencingEntity->id(), 'full']; + $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); + $access_cache_contexts = $this->getAccessCacheContextsForEntity($this->entity); + $additional_cache_contexts = $this->getAdditionalCacheContextsForEntity($this->referencingEntity); + $redirected_cid = NULL; + if (count($access_cache_contexts) || count($additional_cache_contexts)) { + $cache_contexts = Cache::mergeContexts($entity_cache_contexts, $additional_cache_contexts); + $cache_contexts = Cache::mergeContexts($cache_contexts, $access_cache_contexts); + $redirected_cid = $this->createCacheId($cache_keys, $cache_contexts); + $context_metadata = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($cache_contexts); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, $context_metadata->getCacheTags()); + } + $this->verifyRenderCache($cid, $referencing_entity_cache_tags, $redirected_cid); + + $this->pass("Test non-referencing entity.", 'Debug'); + $this->verifyPageCache($non_referencing_entity_url, 'MISS'); + // Verify a cache hit, but also the presence of the correct cache tags. + $this->verifyPageCache($non_referencing_entity_url, 'HIT', Cache::mergeTags($non_referencing_entity_cache_tags, $page_cache_tags)); + // Also verify the existence of an entity render cache entry. + $cache_keys = ['entity_view', 'entity_test', $this->nonReferencingEntity->id(), 'full']; + $cid = $this->createCacheId($cache_keys, $entity_cache_contexts); + $this->verifyRenderCache($cid, $non_referencing_entity_cache_tags); + + + $this->pass("Test listing of referencing entities.", 'Debug'); + // Prime the page cache for the listing of referencing entities. + $this->verifyPageCache($listing_url, 'MISS'); + + // Verify a cache hit, but also the presence of the correct cache tags. + $expected_tags = Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags); + $expected_tags = Cache::mergeTags($expected_tags, $page_cache_tags_referencing_entity); + $this->verifyPageCache($listing_url, 'HIT', $expected_tags); + + $this->pass("Test empty listing.", 'Debug'); + // Prime the page cache for the empty listing. + $this->verifyPageCache($empty_entity_listing_url, 'MISS'); + // Verify a cache hit, but also the presence of the correct cache tags. + $this->verifyPageCache($empty_entity_listing_url, 'HIT', $empty_entity_listing_cache_tags); + // Verify the entity type's list cache contexts are present. + $contexts_in_header = $this->drupalGetHeader('X-Drupal-Cache-Contexts'); + $this->assertEqual(Cache::mergeContexts($page_cache_contexts, $this->getAdditionalCacheContextsForEntityListing()), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header)); + + + $this->pass("Test listing containing referenced entity.", 'Debug'); + // Prime the page cache for the listing containing the referenced entity. + $this->verifyPageCache($nonempty_entity_listing_url, 'MISS', $nonempty_entity_listing_cache_tags); + // Verify a cache hit, but also the presence of the correct cache tags. + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT', $nonempty_entity_listing_cache_tags); + // Verify the entity type's list cache contexts are present. + $contexts_in_header = $this->drupalGetHeader('X-Drupal-Cache-Contexts'); + $this->assertEqual(Cache::mergeContexts($page_cache_contexts, $this->getAdditionalCacheContextsForEntityListing()), empty($contexts_in_header) ? [] : explode(' ', $contexts_in_header)); + + + // Verify that after modifying the referenced entity, there is a cache miss + // for every route except the one for the non-referencing entity. + $this->pass("Test modification of referenced entity.", 'Debug'); + $this->entity->save(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($empty_entity_listing_url, 'MISS'); + $this->verifyPageCache($nonempty_entity_listing_url, 'MISS'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + + + // Verify that after modifying the referencing entity, there is a cache miss + // for every route except the ones for the non-referencing entity and the + // empty entity listing. + $this->pass("Test modification of referencing entity.", 'Debug'); + $this->referencingEntity->save(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + + + // Verify that after modifying the non-referencing entity, there is a cache + // miss only for the non-referencing entity route. + $this->pass("Test modification of non-referencing entity.", 'Debug'); + $this->nonReferencingEntity->save(); + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + $this->verifyPageCache($non_referencing_entity_url, 'MISS'); + + // Verify cache hits. + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + + + if ($this->entity->getEntityType()->hasHandlerClass('view_builder')) { + // Verify that after modifying the entity's display, there is a cache miss + // for both the referencing entity, and the listing of referencing + // entities, but not for any other routes. + $referenced_entity_view_mode = $this->selectViewMode($this->entity->getEntityTypeId()); + $this->pass("Test modification of referenced entity's '$referenced_entity_view_mode' display.", 'Debug'); + $entity_display = entity_get_display($entity_type, $this->entity->bundle(), $referenced_entity_view_mode); + $entity_display->save(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + } + + + if ($bundle_entity_type_id = $this->entity->getEntityType()->getBundleEntityType()) { + // Verify that after modifying the corresponding bundle entity, there is a + // cache miss for both the referencing entity, and the listing of + // referencing entities, but not for any other routes. + $this->pass("Test modification of referenced entity's bundle entity.", 'Debug'); + $bundle_entity = $this->container->get('entity_type.manager') + ->getStorage($bundle_entity_type_id) + ->load($this->entity->bundle()); + $bundle_entity->save(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + // Special case: entity types may choose to use their bundle entity type + // cache tags, to avoid having excessively granular invalidation. + $is_special_case = $bundle_entity->getCacheTags() == $this->entity->getCacheTags() && $bundle_entity->getEntityType()->getListCacheTags() == $this->entity->getEntityType()->getListCacheTags(); + if ($is_special_case) { + $this->verifyPageCache($empty_entity_listing_url, 'MISS'); + $this->verifyPageCache($nonempty_entity_listing_url, 'MISS'); + } + else { + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + } + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + if ($is_special_case) { + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + } + } + + + if ($this->entity->getEntityType()->get('field_ui_base_route')) { + // Verify that after modifying a configurable field on the entity, there + // is a cache miss. + $this->pass("Test modification of referenced entity's configurable field.", 'Debug'); + $field_storage_name = $this->entity->getEntityTypeId() . '.configurable_field'; + $field_storage = FieldStorageConfig::load($field_storage_name); + $field_storage->save(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + + + // Verify that after modifying a configurable field on the entity, there + // is a cache miss. + $this->pass("Test modification of referenced entity's configurable field.", 'Debug'); + $field_name = $this->entity->getEntityTypeId() . '.' . $this->entity->bundle() . '.configurable_field'; + $field = FieldConfig::load($field_name); + $field->save(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + } + + + // Verify that after invalidating the entity's cache tag directly, there is + // a cache miss for every route except the ones for the non-referencing + // entity and the empty entity listing. + $this->pass("Test invalidation of referenced entity's cache tag.", 'Debug'); + Cache::invalidateTags($this->entity->getCacheTagsToInvalidate()); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($nonempty_entity_listing_url, 'MISS'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + + // Verify that after invalidating the entity's list cache tag directly, + // there is a cache miss for both the empty entity listing and the non-empty + // entity listing routes, but not for other routes. + $this->pass("Test invalidation of referenced entity's list cache tag.", 'Debug'); + Cache::invalidateTags($this->entity->getEntityType()->getListCacheTags()); + $this->verifyPageCache($empty_entity_listing_url, 'MISS'); + $this->verifyPageCache($nonempty_entity_listing_url, 'MISS'); + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + + + if (!empty($view_cache_tag)) { + // Verify that after invalidating the generic entity type's view cache tag + // directly, there is a cache miss for both the referencing entity, and the + // listing of referencing entities, but not for other routes. + $this->pass("Test invalidation of referenced entity's 'view' cache tag.", 'Debug'); + Cache::invalidateTags($view_cache_tag); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + $this->verifyPageCache($empty_entity_listing_url, 'HIT'); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT'); + + // Verify cache hits. + $this->verifyPageCache($referencing_entity_url, 'HIT'); + $this->verifyPageCache($listing_url, 'HIT'); + } + + // Verify that after deleting the entity, there is a cache miss for every + // route except for the non-referencing entity one. + $this->pass('Test deletion of referenced entity.', 'Debug'); + $this->entity->delete(); + $this->verifyPageCache($referencing_entity_url, 'MISS'); + $this->verifyPageCache($listing_url, 'MISS'); + $this->verifyPageCache($empty_entity_listing_url, 'MISS'); + $this->verifyPageCache($nonempty_entity_listing_url, 'MISS'); + $this->verifyPageCache($non_referencing_entity_url, 'HIT'); + + // Verify cache hits. + $referencing_entity_cache_tags = Cache::mergeTags($this->referencingEntity->getCacheTags(), \Drupal::entityManager()->getViewBuilder('entity_test')->getCacheTags()); + $referencing_entity_cache_tags = Cache::mergeTags($referencing_entity_cache_tags, ['http_response', 'rendered']); + + $nonempty_entity_listing_cache_tags = Cache::mergeTags($this->entity->getEntityType()->getListCacheTags(), $this->getAdditionalCacheTagsForEntityListing()); + $nonempty_entity_listing_cache_tags = Cache::mergeTags($nonempty_entity_listing_cache_tags, $page_cache_tags); + + $this->verifyPageCache($referencing_entity_url, 'HIT', Cache::mergeTags($referencing_entity_cache_tags, $page_cache_tags)); + $this->verifyPageCache($listing_url, 'HIT', $page_cache_tags); + $this->verifyPageCache($empty_entity_listing_url, 'HIT', $empty_entity_listing_cache_tags); + $this->verifyPageCache($nonempty_entity_listing_url, 'HIT', $nonempty_entity_listing_cache_tags); + } + + /** + * Creates a cache ID from a list of cache keys and a set of cache contexts. + * + * @param string[] $keys + * A list of cache keys. + * @param string[] $contexts + * A set of cache contexts. + * + * @return string + * The cache ID string. + */ + protected function createCacheId(array $keys, array $contexts) { + $cid_parts = $keys; + + $contexts = \Drupal::service('cache_contexts_manager')->convertTokensToKeys($contexts); + $cid_parts = array_merge($cid_parts, $contexts->getKeys()); + + return implode(':', $cid_parts); + } + + /** + * Verify that a given render cache entry exists, with the correct cache tags. + * + * @param string $cid + * The render cache item ID. + * @param array $tags + * An array of expected cache tags. + * @param string|null $redirected_cid + * (optional) The redirected render cache item ID. + */ + protected function verifyRenderCache($cid, array $tags, $redirected_cid = NULL) { + // Also verify the existence of an entity render cache entry. + $cache_entry = \Drupal::cache('render')->get($cid); + $this->assertTrue($cache_entry, 'A render cache entry exists.'); + sort($cache_entry->tags); + sort($tags); + $this->assertIdentical($cache_entry->tags, $tags); + $is_redirecting_cache_item = isset($cache_entry->data['#cache_redirect']); + if ($redirected_cid === NULL) { + $this->assertFalse($is_redirecting_cache_item, 'Render cache entry is not a redirect.'); + // If this is a redirecting cache item unlike we expected, log it. + if ($is_redirecting_cache_item) { + debug($cache_entry->data); + } + } + else { + // Verify that $cid contains a cache redirect. + $this->assertTrue($is_redirecting_cache_item, 'Render cache entry is a redirect.'); + // If this is not a redirecting cache item unlike we expected, log it. + if (!$is_redirecting_cache_item) { + debug($cache_entry->data); + } + // Verify that the cache redirect points to the expected CID. + $redirect_cache_metadata = $cache_entry->data['#cache']; + $actual_redirection_cid = $this->createCacheId( + $redirect_cache_metadata['keys'], + $redirect_cache_metadata['contexts'] + ); + $this->assertIdentical($redirected_cid, $actual_redirection_cid); + // Finally, verify that the redirected CID exists and has the same cache + // tags. + $this->verifyRenderCache($redirected_cid, $tags); + } + } + +} diff --git a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php b/core/modules/system/tests/src/Functional/Entity/EntityListBuilderTest.php similarity index 85% rename from core/modules/system/src/Tests/Entity/EntityListBuilderTest.php rename to core/modules/system/tests/src/Functional/Entity/EntityListBuilderTest.php index 2a849b29..94225f4e 100644 --- a/core/modules/system/src/Tests/Entity/EntityListBuilderTest.php +++ b/core/modules/system/tests/src/Functional/Entity/EntityListBuilderTest.php @@ -1,22 +1,22 @@ webUser = $this->drupalCreateUser(array( + $this->webUser = $this->drupalCreateUser([ 'administer entity_test content', - )); + ]); $this->drupalLogin($this->webUser); } @@ -37,7 +37,7 @@ protected function setUp() { public function testPager() { // Create 51 test entities. for ($i = 1; $i < 52; $i++) { - EntityTest::create(array('name' => 'Test entity ' . $i))->save(); + EntityTest::create(['name' => 'Test entity ' . $i])->save(); } // Load the listing page. diff --git a/core/modules/system/src/Tests/Entity/EntityOperationsTest.php b/core/modules/system/tests/src/Functional/Entity/EntityOperationsTest.php similarity index 82% rename from core/modules/system/src/Tests/Entity/EntityOperationsTest.php rename to core/modules/system/tests/src/Functional/Entity/EntityOperationsTest.php index 3e4c69f8..b020f428 100644 --- a/core/modules/system/src/Tests/Entity/EntityOperationsTest.php +++ b/core/modules/system/tests/src/Functional/Entity/EntityOperationsTest.php @@ -1,28 +1,28 @@ drupalLogin($this->drupalCreateUser(array('administer permissions'))); + $this->drupalLogin($this->drupalCreateUser(['administer permissions'])); } /** @@ -36,7 +36,7 @@ public function testEntityOperationAlter() { $roles = user_roles(); foreach ($roles as $role) { $this->assertLinkByHref($role->url() . '/test_operation'); - $this->assertLink(format_string('Test Operation: @label', array('@label' => $role->label()))); + $this->assertLink(format_string('Test Operation: @label', ['@label' => $role->label()])); } } diff --git a/core/modules/system/tests/src/Functional/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php b/core/modules/system/tests/src/Functional/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php new file mode 100644 index 00000000..3772f3a9 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php @@ -0,0 +1,510 @@ +drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + } + + /** + * Checks that a selection plugin returns the expected results. + * + * @param array $selection_options + * An array of options as required by entity reference selection plugins. + * @param array $tests + * An array of tests to run. + * @param string $handler_name + * The name of the entity type selection handler being tested. + */ + protected function assertReferenceable(array $selection_options, $tests, $handler_name) { + $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options); + + foreach ($tests as $test) { + foreach ($test['arguments'] as $arguments) { + $result = call_user_func_array([$handler, 'getReferenceableEntities'], $arguments); + $this->assertEqual($result, $test['result'], format_string('Valid result set returned by @handler.', ['@handler' => $handler_name])); + + $result = call_user_func_array([$handler, 'countReferenceableEntities'], $arguments); + if (!empty($test['result'])) { + $bundle = key($test['result']); + $count = count($test['result'][$bundle]); + } + else { + $count = 0; + } + + $this->assertEqual($result, $count, format_string('Valid count returned by @handler.', ['@handler' => $handler_name])); + } + } + } + + /** + * Test the node-specific overrides of the entity handler. + */ + public function testNodeHandler() { + $selection_options = [ + 'target_type' => 'node', + 'handler' => 'default', + 'target_bundles' => NULL, + ]; + + // Build a set of test data. + // Titles contain HTML-special characters to test escaping. + $node_values = [ + 'published1' => [ + 'type' => 'article', + 'status' => NodeInterface::PUBLISHED, + 'title' => 'Node published1 (<&>)', + 'uid' => 1, + ], + 'published2' => [ + 'type' => 'article', + 'status' => NodeInterface::PUBLISHED, + 'title' => 'Node published2 (<&>)', + 'uid' => 1, + ], + 'unpublished' => [ + 'type' => 'article', + 'status' => NodeInterface::NOT_PUBLISHED, + 'title' => 'Node unpublished (<&>)', + 'uid' => 1, + ], + ]; + + $nodes = []; + $node_labels = []; + foreach ($node_values as $key => $values) { + $node = Node::create($values); + $node->save(); + $nodes[$key] = $node; + $node_labels[$key] = Html::escape($node->label()); + } + + // Test as a non-admin. + $normal_user = $this->drupalCreateUser(['access content']); + \Drupal::currentUser()->setAccount($normal_user); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'article' => [ + $nodes['published1']->id() => $node_labels['published1'], + $nodes['published2']->id() => $node_labels['published2'], + ], + ], + ], + [ + 'arguments' => [ + ['published1', 'CONTAINS'], + ['Published1', 'CONTAINS'], + ], + 'result' => [ + 'article' => [ + $nodes['published1']->id() => $node_labels['published1'], + ], + ], + ], + [ + 'arguments' => [ + ['published2', 'CONTAINS'], + ['Published2', 'CONTAINS'], + ], + 'result' => [ + 'article' => [ + $nodes['published2']->id() => $node_labels['published2'], + ], + ], + ], + [ + 'arguments' => [ + ['invalid node', 'CONTAINS'], + ], + 'result' => [], + ], + [ + 'arguments' => [ + ['Node unpublished', 'CONTAINS'], + ], + 'result' => [], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler'); + + // Test as an admin. + $admin_user = $this->drupalCreateUser(['access content', 'bypass node access']); + \Drupal::currentUser()->setAccount($admin_user); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'article' => [ + $nodes['published1']->id() => $node_labels['published1'], + $nodes['published2']->id() => $node_labels['published2'], + $nodes['unpublished']->id() => $node_labels['unpublished'], + ], + ], + ], + [ + 'arguments' => [ + ['Node unpublished', 'CONTAINS'], + ], + 'result' => [ + 'article' => [ + $nodes['unpublished']->id() => $node_labels['unpublished'], + ], + ], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)'); + } + + /** + * Test the user-specific overrides of the entity handler. + */ + public function testUserHandler() { + $selection_options = [ + 'target_type' => 'user', + 'handler' => 'default', + 'target_bundles' => NULL, + 'include_anonymous' => TRUE, + ]; + + // Build a set of test data. + $user_values = [ + 'anonymous' => User::load(0), + 'admin' => User::load(1), + 'non_admin' => [ + 'name' => 'non_admin <&>', + 'mail' => 'non_admin@example.com', + 'roles' => [], + 'pass' => user_password(), + 'status' => 1, + ], + 'blocked' => [ + 'name' => 'blocked <&>', + 'mail' => 'blocked@example.com', + 'roles' => [], + 'pass' => user_password(), + 'status' => 0, + ], + ]; + + $user_values['anonymous']->name = $this->config('user.settings')->get('anonymous'); + $users = []; + + $user_labels = []; + foreach ($user_values as $key => $values) { + if (is_array($values)) { + $account = User::create($values); + $account->save(); + } + else { + $account = $values; + } + $users[$key] = $account; + $user_labels[$key] = Html::escape($account->getUsername()); + } + + // Test as a non-admin. + \Drupal::currentUser()->setAccount($users['non_admin']); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'user' => [ + $users['admin']->id() => $user_labels['admin'], + $users['non_admin']->id() => $user_labels['non_admin'], + ], + ], + ], + [ + 'arguments' => [ + ['non_admin', 'CONTAINS'], + ['NON_ADMIN', 'CONTAINS'], + ], + 'result' => [ + 'user' => [ + $users['non_admin']->id() => $user_labels['non_admin'], + ], + ], + ], + [ + 'arguments' => [ + ['invalid user', 'CONTAINS'], + ], + 'result' => [], + ], + [ + 'arguments' => [ + ['blocked', 'CONTAINS'], + ], + 'result' => [], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler'); + + \Drupal::currentUser()->setAccount($users['admin']); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'user' => [ + $users['anonymous']->id() => $user_labels['anonymous'], + $users['admin']->id() => $user_labels['admin'], + $users['non_admin']->id() => $user_labels['non_admin'], + $users['blocked']->id() => $user_labels['blocked'], + ], + ], + ], + [ + 'arguments' => [ + ['blocked', 'CONTAINS'], + ], + 'result' => [ + 'user' => [ + $users['blocked']->id() => $user_labels['blocked'], + ], + ], + ], + [ + 'arguments' => [ + ['Anonymous', 'CONTAINS'], + ['anonymous', 'CONTAINS'], + ], + 'result' => [ + 'user' => [ + $users['anonymous']->id() => $user_labels['anonymous'], + ], + ], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)'); + + // Test the 'include_anonymous' option. + $selection_options['include_anonymous'] = FALSE; + $referenceable_tests = [ + [ + 'arguments' => [ + ['Anonymous', 'CONTAINS'], + ['anonymous', 'CONTAINS'], + ], + 'result' => [], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)'); + + // Check that the Anonymous user is not included in the results when no + // label matching is done, for example when using the 'options_select' + // widget. + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL], + ], + 'result' => [ + 'user' => [ + $users['admin']->id() => $user_labels['admin'], + $users['non_admin']->id() => $user_labels['non_admin'], + $users['blocked']->id() => $user_labels['blocked'], + ], + ], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)'); + } + + /** + * Test the comment-specific overrides of the entity handler. + */ + public function testCommentHandler() { + $selection_options = [ + 'target_type' => 'comment', + 'handler' => 'default', + 'target_bundles' => NULL, + ]; + + // Build a set of test data. + $node_values = [ + 'published' => [ + 'type' => 'article', + 'status' => 1, + 'title' => 'Node published', + 'uid' => 1, + ], + 'unpublished' => [ + 'type' => 'article', + 'status' => 0, + 'title' => 'Node unpublished', + 'uid' => 1, + ], + ]; + $nodes = []; + foreach ($node_values as $key => $values) { + $node = Node::create($values); + $node->save(); + $nodes[$key] = $node; + } + + // Create comment field on article. + $this->addDefaultCommentField('node', 'article'); + + $comment_values = [ + 'published_published' => [ + 'entity_id' => $nodes['published']->id(), + 'entity_type' => 'node', + 'field_name' => 'comment', + 'uid' => 1, + 'cid' => NULL, + 'pid' => 0, + 'status' => CommentInterface::PUBLISHED, + 'subject' => 'Comment Published <&>', + 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ], + 'published_unpublished' => [ + 'entity_id' => $nodes['published']->id(), + 'entity_type' => 'node', + 'field_name' => 'comment', + 'uid' => 1, + 'cid' => NULL, + 'pid' => 0, + 'status' => CommentInterface::NOT_PUBLISHED, + 'subject' => 'Comment Unpublished <&>', + 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ], + 'unpublished_published' => [ + 'entity_id' => $nodes['unpublished']->id(), + 'entity_type' => 'node', + 'field_name' => 'comment', + 'uid' => 1, + 'cid' => NULL, + 'pid' => 0, + 'status' => CommentInterface::NOT_PUBLISHED, + 'subject' => 'Comment Published on Unpublished node <&>', + 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ], + ]; + + $comments = []; + $comment_labels = []; + foreach ($comment_values as $key => $values) { + $comment = Comment::create($values); + $comment->save(); + $comments[$key] = $comment; + $comment_labels[$key] = Html::escape($comment->label()); + } + + // Test as a non-admin. + $normal_user = $this->drupalCreateUser(['access content', 'access comments']); + \Drupal::currentUser()->setAccount($normal_user); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'comment' => [ + $comments['published_published']->cid->value => $comment_labels['published_published'], + ], + ], + ], + [ + 'arguments' => [ + ['Published', 'CONTAINS'], + ], + 'result' => [ + 'comment' => [ + $comments['published_published']->cid->value => $comment_labels['published_published'], + ], + ], + ], + [ + 'arguments' => [ + ['invalid comment', 'CONTAINS'], + ], + 'result' => [], + ], + [ + 'arguments' => [ + ['Comment Unpublished', 'CONTAINS'], + ], + 'result' => [], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler'); + + // Test as a comment admin. + $admin_user = $this->drupalCreateUser(['access content', 'access comments', 'administer comments']); + \Drupal::currentUser()->setAccount($admin_user); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'comment' => [ + $comments['published_published']->cid->value => $comment_labels['published_published'], + $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'], + ], + ], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)'); + + // Test as a node and comment admin. + $admin_user = $this->drupalCreateUser(['access content', 'access comments', 'administer comments', 'bypass node access']); + \Drupal::currentUser()->setAccount($admin_user); + $referenceable_tests = [ + [ + 'arguments' => [ + [NULL, 'CONTAINS'], + ], + 'result' => [ + 'comment' => [ + $comments['published_published']->cid->value => $comment_labels['published_published'], + $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'], + $comments['unpublished_published']->cid->value => $comment_labels['unpublished_published'], + ], + ], + ], + ]; + $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Entity/EntityRevisionsTest.php b/core/modules/system/tests/src/Functional/Entity/EntityRevisionsTest.php new file mode 100644 index 00000000..caf5fa2f --- /dev/null +++ b/core/modules/system/tests/src/Functional/Entity/EntityRevisionsTest.php @@ -0,0 +1,162 @@ +webUser = $this->drupalCreateUser([ + 'administer entity_test content', + 'view test entity', + ]); + $this->drupalLogin($this->webUser); + + // Enable an additional language. + ConfigurableLanguage::createFromLangcode('de')->save(); + } + + /** + * Check node revision related operations. + */ + public function testRevisions() { + + // All revisable entity variations have to have the same results. + foreach (entity_test_entity_types(ENTITY_TEST_TYPES_REVISABLE) as $entity_type) { + $this->runRevisionsTests($entity_type); + } + } + + /** + * Executes the revision tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function runRevisionsTests($entity_type) { + + // Create initial entity. + $entity = $this->container->get('entity_type.manager') + ->getStorage($entity_type) + ->create([ + 'name' => 'foo', + 'user_id' => $this->webUser->id(), + ]); + $entity->field_test_text->value = 'bar'; + $entity->save(); + + $names = []; + $texts = []; + $created = []; + $revision_ids = []; + + // Create three revisions. + $revision_count = 3; + for ($i = 0; $i < $revision_count; $i++) { + $legacy_revision_id = $entity->revision_id->value; + $legacy_name = $entity->name->value; + $legacy_text = $entity->field_test_text->value; + + $entity = $this->container->get('entity_type.manager') + ->getStorage($entity_type)->load($entity->id->value); + $entity->setNewRevision(TRUE); + $names[] = $entity->name->value = $this->randomMachineName(32); + $texts[] = $entity->field_test_text->value = $this->randomMachineName(32); + $created[] = $entity->created->value = time() + $i + 1; + $entity->save(); + $revision_ids[] = $entity->revision_id->value; + + // Check that the fields and properties contain new content. + $this->assertTrue($entity->revision_id->value > $legacy_revision_id, format_string('%entity_type: Revision ID changed.', ['%entity_type' => $entity_type])); + $this->assertNotEqual($entity->name->value, $legacy_name, format_string('%entity_type: Name changed.', ['%entity_type' => $entity_type])); + $this->assertNotEqual($entity->field_test_text->value, $legacy_text, format_string('%entity_type: Text changed.', ['%entity_type' => $entity_type])); + } + + $storage = $this->container->get('entity_type.manager')->getStorage($entity_type); + for ($i = 0; $i < $revision_count; $i++) { + // Load specific revision. + $entity_revision = $storage->loadRevision($revision_ids[$i]); + + // Check if properties and fields contain the revision specific content. + $this->assertEqual($entity_revision->revision_id->value, $revision_ids[$i], format_string('%entity_type: Revision ID matches.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity_revision->name->value, $names[$i], format_string('%entity_type: Name matches.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity_revision->field_test_text->value, $texts[$i], format_string('%entity_type: Text matches.', ['%entity_type' => $entity_type])); + + // Check non-revisioned values are loaded. + $this->assertTrue(isset($entity_revision->created->value), format_string('%entity_type: Non-revisioned field is loaded.', ['%entity_type' => $entity_type])); + $this->assertEqual($entity_revision->created->value, $created[2], format_string('%entity_type: Non-revisioned field value is the same between revisions.', ['%entity_type' => $entity_type])); + } + + // Confirm the correct revision text appears in the edit form. + $entity = $this->container->get('entity_type.manager') + ->getStorage($entity_type) + ->load($entity->id->value); + $this->drupalGet($entity_type . '/manage/' . $entity->id->value . '/edit'); + $this->assertFieldById('edit-name-0-value', $entity->name->value, format_string('%entity_type: Name matches in UI.', ['%entity_type' => $entity_type])); + $this->assertFieldById('edit-field-test-text-0-value', $entity->field_test_text->value, format_string('%entity_type: Text matches in UI.', ['%entity_type' => $entity_type])); + } + + /** + * Tests that an entity revision is upcasted in the correct language. + */ + public function testEntityRevisionParamConverter() { + // Create a test entity with multiple revisions and translations for them. + $entity = EntityTestMulRev::create([ + 'name' => 'default revision - en', + 'user_id' => $this->webUser, + 'language' => 'en', + ]); + $entity->addTranslation('de', ['name' => 'default revision - de']); + $entity->save(); + + $pending_revision = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev')->loadUnchanged($entity->id()); + + $pending_revision->setNewRevision(); + $pending_revision->isDefaultRevision(FALSE); + + $pending_revision->name = 'pending revision - en'; + $pending_revision->save(); + + $pending_revision_translation = $pending_revision->getTranslation('de'); + $pending_revision_translation->name = 'pending revision - de'; + $pending_revision_translation->save(); + + // Check that the entity revision is upcasted in the correct language. + $revision_url = 'entity_test_mulrev/' . $entity->id() . '/revision/' . $pending_revision->getRevisionId() . '/view'; + + $this->drupalGet($revision_url); + $this->assertText('pending revision - en'); + $this->assertNoText('pending revision - de'); + + $this->drupalGet('de/' . $revision_url); + $this->assertText('pending revision - de'); + $this->assertNoText('pending revision - en'); + } + +} diff --git a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/tests/src/Functional/Entity/EntityViewControllerTest.php similarity index 86% rename from core/modules/system/src/Tests/Entity/EntityViewControllerTest.php rename to core/modules/system/tests/src/Functional/Entity/EntityViewControllerTest.php index d9f36ff9..36373697 100644 --- a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php +++ b/core/modules/system/tests/src/Functional/Entity/EntityViewControllerTest.php @@ -1,30 +1,30 @@
    ' . $label . '
    '; @@ -86,7 +86,7 @@ function testEntityViewController() { public function testFieldItemAttributes() { // Make sure the test field will be rendered. entity_get_display('entity_test', 'entity_test', 'default') - ->setComponent('field_test_text', array('type' => 'text_default')) + ->setComponent('field_test_text', ['type' => 'text_default']) ->save(); // Create an entity and save test value in field_test_text. @@ -98,24 +98,24 @@ public function testFieldItemAttributes() { // Browse to the entity and verify that the attribute is rendered in the // field item HTML markup. $this->drupalGet('entity_test/' . $entity->id()); - $xpath = $this->xpath('//div[@data-field-item-attr="foobar"]/p[text()=:value]', array(':value' => $test_value)); + $xpath = $this->xpath('//div[@data-field-item-attr="foobar"]/p[text()=:value]', [':value' => $test_value]); $this->assertTrue($xpath, 'The field item attribute has been found in the rendered output of the field.'); // Enable the RDF module to ensure that two modules can add attributes to // the same field item. - \Drupal::service('module_installer')->install(array('rdf')); + \Drupal::service('module_installer')->install(['rdf']); $this->resetAll(); // Set an RDF mapping for the field_test_text field. This RDF mapping will // be turned into RDFa attributes in the field item output. $mapping = rdf_get_mapping('entity_test', 'entity_test'); - $mapping->setFieldMapping('field_test_text', array( - 'properties' => array('schema:text'), - ))->save(); + $mapping->setFieldMapping('field_test_text', [ + 'properties' => ['schema:text'], + ])->save(); // Browse to the entity and verify that the attributes from both modules // are rendered in the field item HTML markup. $this->drupalGet('entity_test/' . $entity->id()); - $xpath = $this->xpath('//div[@data-field-item-attr="foobar" and @property="schema:text"]/p[text()=:value]', array(':value' => $test_value)); + $xpath = $this->xpath('//div[@data-field-item-attr="foobar" and @property="schema:text"]/p[text()=:value]', [':value' => $test_value]); $this->assertTrue($xpath, 'The field item attributes from both modules have been found in the rendered output of the field.'); } @@ -139,10 +139,10 @@ public function testEntityViewControllerViewBuilder() { * The created entity. */ protected function createTestEntity($entity_type) { - $data = array( + $data = [ 'bundle' => $entity_type, 'name' => $this->randomMachineName(), - ); + ]; return $this->container->get('entity.manager')->getStorage($entity_type)->create($data); } diff --git a/core/modules/system/tests/src/Functional/Entity/Update/LangcodeToAsciiUpdateFilledTest.php b/core/modules/system/tests/src/Functional/Entity/Update/LangcodeToAsciiUpdateFilledTest.php new file mode 100644 index 00000000..7e95ed77 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Entity/Update/LangcodeToAsciiUpdateFilledTest.php @@ -0,0 +1,21 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../fixtures/update/drupal-8.filled.standard.php.gz', + ]; + } + +} diff --git a/core/modules/system/src/Tests/Entity/Update/LangcodeToAsciiUpdateTest.php b/core/modules/system/tests/src/Functional/Entity/Update/LangcodeToAsciiUpdateTest.php similarity index 91% rename from core/modules/system/src/Tests/Entity/Update/LangcodeToAsciiUpdateTest.php rename to core/modules/system/tests/src/Functional/Entity/Update/LangcodeToAsciiUpdateTest.php index 270bc494..d1a3cabb 100644 --- a/core/modules/system/src/Tests/Entity/Update/LangcodeToAsciiUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Entity/Update/LangcodeToAsciiUpdateTest.php @@ -1,9 +1,9 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/tests/src/Functional/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php b/core/modules/system/tests/src/Functional/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php new file mode 100644 index 00000000..c843c835 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php @@ -0,0 +1,83 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz', + __DIR__ . '/../../../../../tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php', + __DIR__ . '/../../../../../tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php', + ]; + } + + /** + * Tests that the revision metadata fields are moved correctly. + */ + public function testSystemUpdate8400() { + $this->runUpdates(); + + foreach (['entity_test_revlog', 'entity_test_mul_revlog'] as $entity_type_id) { + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ + $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id); + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ + $entity_type = $storage->getEntityType(); + $revision_metadata_field_names = $entity_type->getRevisionMetadataKeys(); + + $database_schema = \Drupal::database()->schema(); + + // Test that the revision metadata fields are present only in the + // revision table. + foreach ($revision_metadata_field_names as $revision_metadata_field_name) { + if ($entity_type->isTranslatable()) { + $this->assertFalse($database_schema->fieldExists($entity_type->getDataTable(), $revision_metadata_field_name)); + $this->assertFalse($database_schema->fieldExists($entity_type->getRevisionDataTable(), $revision_metadata_field_name)); + } + else { + $this->assertFalse($database_schema->fieldExists($entity_type->getBaseTable(), $revision_metadata_field_name)); + } + $this->assertTrue($database_schema->fieldExists($entity_type->getRevisionTable(), $revision_metadata_field_name)); + } + + // Test that the revision metadata values have been transferred correctly + // and that the moved fields are accessible. + /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_first */ + $entity_rev_first = $storage->loadRevision(1); + $this->assertEqual($entity_rev_first->getRevisionUserId(), '1'); + $this->assertEqual($entity_rev_first->getRevisionLogMessage(), 'first revision'); + $this->assertEqual($entity_rev_first->getRevisionCreationTime(), '1476268517'); + + /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_second */ + $entity_rev_second = $storage->loadRevision(2); + $this->assertEqual($entity_rev_second->getRevisionUserId(), '1'); + $this->assertEqual($entity_rev_second->getRevisionLogMessage(), 'second revision'); + $this->assertEqual($entity_rev_second->getRevisionCreationTime(), '1476268518'); + + + // Test that the views using revision metadata fields are updated + // properly. + $view = View::load($entity_type_id . '_for_2248983'); + $displays = $view->get('display'); + foreach ($displays as $display => $display_data) { + foreach ($display_data['display_options']['fields'] as $property_data) { + if (in_array($property_data['field'], $revision_metadata_field_names)) { + $this->assertEqual($property_data['table'], $entity_type->getRevisionTable()); + } + } + } + } + } + +} diff --git a/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaConverterTest.php b/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaConverterTest.php new file mode 100644 index 00000000..625ee190 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaConverterTest.php @@ -0,0 +1,269 @@ +entityManager = \Drupal::entityManager(); + $this->entityDefinitionUpdateManager = \Drupal::entityDefinitionUpdateManager(); + $this->lastInstalledSchemaRepository = \Drupal::service('entity.last_installed_schema.repository'); + $this->installedStorageSchema = \Drupal::keyValue('entity.storage_schema.sql'); + $this->state = \Drupal::state(); + } + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz', + __DIR__ . '/../../../../fixtures/update/drupal-8.entity-test-schema-converter-enabled.php', + ]; + } + + /** + * Tests the conversion of an entity type to revisionable. + */ + public function testMakeRevisionable() { + // Check that entity type is not revisionable prior to running the update + // process. + $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update'); + $this->assertFalse($entity_test_update->isRevisionable()); + + // Make the entity type revisionable and translatable and run the updates. + $this->updateEntityTypeToRevisionableAndTranslatable(); + + $this->runUpdates(); + + /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_test_update */ + $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update'); + $this->assertTrue($entity_test_update->isRevisionable()); + + $field_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update'); + $this->assertTrue(isset($field_storage_definitions['revision_translation_affected'])); + + /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */ + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + $this->assertEqual(count($storage->loadMultiple()), 102, 'All test entities were found.'); + + // Check that each field value was copied correctly to the revision tables. + for ($i = 1; $i <= 102; $i++) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */ + $revision = $storage->loadRevision($i); + + $this->assertEqual($i, $revision->id()); + $this->assertEqual($i, $revision->getRevisionId()); + + // Check that the correct initial value was provided for the + // 'revision_translation_affected' field. + $this->assertTrue($revision->revision_translation_affected->value); + + $this->assertEqual($i . ' - test single property', $revision->test_single_property->value); + + $this->assertEqual($i . ' - test multiple properties - value1', $revision->test_multiple_properties->value1); + $this->assertEqual($i . ' - test multiple properties - value2', $revision->test_multiple_properties->value2); + + $this->assertEqual($i . ' - test single property multiple values 0', $revision->test_single_property_multiple_values->value); + $this->assertEqual($i . ' - test single property multiple values 1', $revision->test_single_property_multiple_values[1]->value); + + $this->assertEqual($i . ' - test multiple properties multiple values - value1 0', $revision->test_multiple_properties_multiple_values[0]->value1); + $this->assertEqual($i . ' - test multiple properties multiple values - value2 0', $revision->test_multiple_properties_multiple_values[0]->value2); + $this->assertEqual($i . ' - test multiple properties multiple values - value1 1', $revision->test_multiple_properties_multiple_values[1]->value1); + $this->assertEqual($i . ' - test multiple properties multiple values - value2 1', $revision->test_multiple_properties_multiple_values[1]->value2); + + $this->assertEqual($i . ' - field test configurable field - value1 0', $revision->field_test_configurable_field[0]->value1); + $this->assertEqual($i . ' - field test configurable field - value2 0', $revision->field_test_configurable_field[0]->value2); + $this->assertEqual($i . ' - field test configurable field - value1 1', $revision->field_test_configurable_field[1]->value1); + $this->assertEqual($i . ' - field test configurable field - value2 1', $revision->field_test_configurable_field[1]->value2); + + $this->assertEqual($i . ' - test entity base field info', $revision->test_entity_base_field_info->value); + + // Do the same checks for translated field values. + $translation = $revision->getTranslation('ro'); + + $this->assertEqual($i . ' - test single property - ro', $translation->test_single_property->value); + + $this->assertEqual($i . ' - test multiple properties - value1 - ro', $translation->test_multiple_properties->value1); + $this->assertEqual($i . ' - test multiple properties - value2 - ro', $translation->test_multiple_properties->value2); + + $this->assertEqual($i . ' - test single property multiple values 0 - ro', $translation->test_single_property_multiple_values[0]->value); + $this->assertEqual($i . ' - test single property multiple values 1 - ro', $translation->test_single_property_multiple_values[1]->value); + + $this->assertEqual($i . ' - test multiple properties multiple values - value1 0 - ro', $translation->test_multiple_properties_multiple_values[0]->value1); + $this->assertEqual($i . ' - test multiple properties multiple values - value2 0 - ro', $translation->test_multiple_properties_multiple_values[0]->value2); + $this->assertEqual($i . ' - test multiple properties multiple values - value1 1 - ro', $translation->test_multiple_properties_multiple_values[1]->value1); + $this->assertEqual($i . ' - test multiple properties multiple values - value2 1 - ro', $translation->test_multiple_properties_multiple_values[1]->value2); + + $this->assertEqual($i . ' - field test configurable field - value1 0 - ro', $translation->field_test_configurable_field[0]->value1); + $this->assertEqual($i . ' - field test configurable field - value2 0 - ro', $translation->field_test_configurable_field[0]->value2); + $this->assertEqual($i . ' - field test configurable field - value1 1 - ro', $translation->field_test_configurable_field[1]->value1); + $this->assertEqual($i . ' - field test configurable field - value2 1 - ro', $translation->field_test_configurable_field[1]->value2); + + $this->assertEqual($i . ' - test entity base field info - ro', $translation->test_entity_base_field_info->value); + } + + // Check that temporary tables have been removed at the end of the process. + $schema = \Drupal::database()->schema(); + foreach ($storage->getTableMapping()->getTableNames() as $table_name) { + $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name))); + } + + // Check that backup tables have been removed at the end of the process. + $schema = \Drupal::database()->schema(); + foreach ($storage->getTableMapping()->getTableNames() as $table_name) { + $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name, 'old_'))); + } + } + + /** + * Tests that a failed "make revisionable" update preserves the existing data. + */ + public function testMakeRevisionableErrorHandling() { + $original_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update'); + $original_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update'); + + $original_entity_schema_data = $this->installedStorageSchema->get('entity_test_update.entity_schema_data', []); + foreach ($original_storage_definitions as $storage_definition) { + $original_field_schema_data[$storage_definition->getName()] = $this->installedStorageSchema->get('entity_test_update.field_schema_data.' . $storage_definition->getName(), []); + } + + // Check that entity type is not revisionable prior to running the update + // process. + $this->assertFalse($original_entity_type->isRevisionable()); + + // Make the update throw an exception during the entity save process. + \Drupal::state()->set('entity_test_update.throw_exception', TRUE); + + // Since the update process is interrupted by the exception thrown above, + // we can not do the full post update testing offered by UpdatePathTestBase. + $this->checkFailedUpdates = FALSE; + + // Make the entity type revisionable and run the updates. + $this->updateEntityTypeToRevisionableAndTranslatable(); + + $this->runUpdates(); + + // Check that the update failed. + $this->assertRaw('' . t('Failed:') . ''); + + // Check that the last installed entity type definition is kept as + // non-revisionable. + $new_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update'); + $this->assertFalse($new_entity_type->isRevisionable(), 'The entity type is kept unchanged.'); + + // Check that the last installed field storage definitions did not change by + // looking at the 'langcode' field, which is updated automatically. + $new_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update'); + $langcode_key = $original_entity_type->getKey('langcode'); + $this->assertEqual($original_storage_definitions[$langcode_key]->isRevisionable(), $new_storage_definitions[$langcode_key]->isRevisionable(), "The 'langcode' field is kept unchanged."); + + /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */ + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + + // Check that installed storage schema did not change. + $new_entity_schema_data = $this->installedStorageSchema->get('entity_test_update.entity_schema_data', []); + $this->assertEqual($original_entity_schema_data, $new_entity_schema_data); + + foreach ($new_storage_definitions as $storage_definition) { + $new_field_schema_data[$storage_definition->getName()] = $this->installedStorageSchema->get('entity_test_update.field_schema_data.' . $storage_definition->getName(), []); + } + $this->assertEqual($original_field_schema_data, $new_field_schema_data); + + // Check that temporary tables have been removed. + $schema = \Drupal::database()->schema(); + foreach ($storage->getTableMapping()->getTableNames() as $table_name) { + $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name))); + } + + // Check that the original tables still exist and their data is intact. + $this->assertTrue($schema->tableExists('entity_test_update')); + $this->assertTrue($schema->tableExists('entity_test_update_data')); + + $base_table_count = \Drupal::database()->select('entity_test_update') + ->countQuery() + ->execute() + ->fetchField(); + $this->assertEqual($base_table_count, 102); + + $data_table_count = \Drupal::database()->select('entity_test_update_data') + ->countQuery() + ->execute() + ->fetchField(); + // There are two records for each entity, one for English and one for + // Romanian. + $this->assertEqual($data_table_count, 204); + + $base_table_row = \Drupal::database()->select('entity_test_update') + ->fields('entity_test_update') + ->condition('id', 1, '=') + ->condition('langcode', 'en', '=') + ->execute() + ->fetchAllAssoc('id'); + $this->assertEqual('843e9ac7-3351-4cc1-a202-2dbffffae21c', $base_table_row[1]->uuid); + + $data_table_row = \Drupal::database()->select('entity_test_update_data') + ->fields('entity_test_update_data') + ->condition('id', 1, '=') + ->condition('langcode', 'en', '=') + ->execute() + ->fetchAllAssoc('id'); + $this->assertEqual('1 - test single property', $data_table_row[1]->test_single_property); + $this->assertEqual('1 - test multiple properties - value1', $data_table_row[1]->test_multiple_properties__value1); + $this->assertEqual('1 - test multiple properties - value2', $data_table_row[1]->test_multiple_properties__value2); + $this->assertEqual('1 - test entity base field info', $data_table_row[1]->test_entity_base_field_info); + } + +} diff --git a/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaIndexFilledTest.php b/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaIndexFilledTest.php new file mode 100644 index 00000000..d3c6912f --- /dev/null +++ b/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaIndexFilledTest.php @@ -0,0 +1,20 @@ +databaseDumpFiles[0] = __DIR__ . '/../../../../fixtures/update/drupal-8.filled.standard.php.gz'; + } + +} diff --git a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php b/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php similarity index 90% rename from core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php rename to core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php index c92d1db2..39542303 100644 --- a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php +++ b/core/modules/system/tests/src/Functional/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php @@ -1,8 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php b/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php similarity index 96% rename from core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php rename to core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php index ceab801e..89c1d707 100644 --- a/core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php @@ -1,18 +1,18 @@ $this->randomString(), 'user_id' => mt_rand()]); $entity->save(); diff --git a/core/modules/system/src/Tests/File/ConfigTest.php b/core/modules/system/tests/src/Functional/File/ConfigTest.php similarity index 80% rename from core/modules/system/src/Tests/File/ConfigTest.php rename to core/modules/system/tests/src/Functional/File/ConfigTest.php index 2313e26e..f413c38c 100644 --- a/core/modules/system/src/Tests/File/ConfigTest.php +++ b/core/modules/system/tests/src/Functional/File/ConfigTest.php @@ -1,35 +1,35 @@ drupalLogin ($this->drupalCreateUser(array('administer site configuration'))); + $this->drupalLogin($this->drupalCreateUser(['administer site configuration'])); } /** * Tests file configuration page. */ - function testFileConfigurationPage() { + public function testFileConfigurationPage() { $this->drupalGet('admin/config/media/file-system'); // Set the file paths to non-default values. // The respective directories are created automatically // upon form submission. $file_path = $this->publicFilesDirectory; - $fields = array( + $fields = [ 'file_temporary_path' => $file_path . '/file_config_page_test/temporary', 'file_default_scheme' => 'private', - ); + ]; // Check that public and private can be selected as default scheme. $this->assertText('Public local files served by the webserver.'); @@ -43,10 +43,10 @@ function testFileConfigurationPage() { // Remove the private path, rebuild the container and verify that private // can no longer be selected in the UI. - $settings['settings']['file_private_path'] = (object) array( + $settings['settings']['file_private_path'] = (object) [ 'value' => '', 'required' => TRUE, - ); + ]; $this->writeSettings($settings); $this->rebuildContainer(); diff --git a/core/modules/system/src/Tests/File/FileSaveHtaccessLoggingTest.php b/core/modules/system/tests/src/Functional/File/FileSaveHtaccessLoggingTest.php similarity index 83% rename from core/modules/system/src/Tests/File/FileSaveHtaccessLoggingTest.php rename to core/modules/system/tests/src/Functional/File/FileSaveHtaccessLoggingTest.php index 5827e24e..442591d1 100644 --- a/core/modules/system/src/Tests/File/FileSaveHtaccessLoggingTest.php +++ b/core/modules/system/tests/src/Functional/File/FileSaveHtaccessLoggingTest.php @@ -1,23 +1,23 @@ publicFilesDirectory . '/test/private'; diff --git a/core/modules/system/src/Tests/FileTransfer/FileTransferTest.php b/core/modules/system/tests/src/Functional/FileTransfer/FileTransferTest.php similarity index 77% rename from core/modules/system/src/Tests/FileTransfer/FileTransferTest.php rename to core/modules/system/tests/src/Functional/FileTransfer/FileTransferTest.php index e8a67890..04b1f663 100644 --- a/core/modules/system/src/Tests/FileTransfer/FileTransferTest.php +++ b/core/modules/system/tests/src/Functional/FileTransfer/FileTransferTest.php @@ -1,10 +1,10 @@ testConnection = TestFileTransfer::factory(\Drupal::root(), array('hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port)); + $this->testConnection = TestFileTransfer::factory(\Drupal::root(), ['hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port]); } - function _getFakeModuleFiles() { - $files = array( + public function _getFakeModuleFiles() { + $files = [ 'fake.module', 'fake.info.yml', - 'theme' => array( + 'theme' => [ 'fake.html.twig' - ), - 'inc' => array( + ], + 'inc' => [ 'fake.inc' - ) - ); + ] + ]; return $files; } - function _buildFakeModule() { + public function _buildFakeModule() { $location = 'temporary://fake'; if (is_dir($location)) { $ret = 0; - $output = array(); + $output = []; exec('rm -Rf ' . escapeshellarg($location), $output, $ret); if ($ret != 0) { throw new Exception('Error removing fake module directory.'); @@ -53,20 +53,20 @@ function _buildFakeModule() { return $location; } - function _writeDirectory($base, $files = array()) { + public function _writeDirectory($base, $files = []) { mkdir($base); foreach ($files as $key => $file) { if (is_array($file)) { $this->_writeDirectory($base . DIRECTORY_SEPARATOR . $key, $file); } else { - //just write the filename into the file + // just write the filename into the file file_put_contents($base . DIRECTORY_SEPARATOR . $file, $file); } } } - function testJail() { + public function testJail() { $source = $this->_buildFakeModule(); // This convoluted piece of code is here because our testing framework does diff --git a/core/modules/system/tests/src/Functional/FileTransfer/MockTestConnection.php b/core/modules/system/tests/src/Functional/FileTransfer/MockTestConnection.php new file mode 100644 index 00000000..029e72c9 --- /dev/null +++ b/core/modules/system/tests/src/Functional/FileTransfer/MockTestConnection.php @@ -0,0 +1,23 @@ +commandsRun[] = $cmd; + } + + public function flushCommands() { + $out = $this->commandsRun; + $this->commandsRun = []; + return $out; + } + +} diff --git a/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php b/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php new file mode 100644 index 00000000..2f233be5 --- /dev/null +++ b/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php @@ -0,0 +1,65 @@ +connection = new MockTestConnection(); + $this->connection->connectionString = 'test://' . urlencode($this->username) . ':' . urlencode($this->password) . "@$this->host:$this->port/"; + } + + public function copyFileJailed($source, $destination) { + $this->connection->run("copyFile $source $destination"); + } + + protected function removeDirectoryJailed($directory) { + $this->connection->run("rmdir $directory"); + } + + public function createDirectoryJailed($directory) { + $this->connection->run("mkdir $directory"); + } + + public function removeFileJailed($destination) { + if (!ftp_delete($this->connection, $item)) { + throw new FileTransferException('Unable to remove the file @file.', NULL, ['@file' => $item]); + } + } + + public function isDirectory($path) { + return $this->shouldIsDirectoryReturnTrue; + } + + public function isFile($path) { + return FALSE; + } + + public function chmodJailed($path, $mode, $recursive) { + return; + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/AlterTest.php b/core/modules/system/tests/src/Functional/Form/AlterTest.php new file mode 100644 index 00000000..622a3d1e --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/AlterTest.php @@ -0,0 +1,39 @@ +drupalGet('form-test/alter'); + // Ensure that the order is first by module, then for a given module, the + // id-specific one after the generic one. + $expected = [ + 'block_form_form_test_alter_form_alter() executed.', + 'form_test_form_alter() executed.', + 'form_test_form_form_test_alter_form_alter() executed.', + 'system_form_form_test_alter_form_alter() executed.', + ]; + $content = preg_replace('/\s+/', ' ', Xss::filter($this->getSession()->getPage()->getContent(), [])); + $this->assert(strpos($content, implode(' ', $expected)) !== FALSE, 'Form alter hooks executed in the expected order.'); + } + +} diff --git a/core/modules/system/src/Tests/Form/ArbitraryRebuildTest.php b/core/modules/system/tests/src/Functional/Form/ArbitraryRebuildTest.php similarity index 79% rename from core/modules/system/src/Tests/Form/ArbitraryRebuildTest.php rename to core/modules/system/tests/src/Functional/Form/ArbitraryRebuildTest.php index 3702d35e..e35ac6d0 100644 --- a/core/modules/system/src/Tests/Form/ArbitraryRebuildTest.php +++ b/core/modules/system/tests/src/Functional/Form/ArbitraryRebuildTest.php @@ -1,36 +1,36 @@ 'user', 'field_name' => 'test_multiple', 'type' => 'text', 'cardinality' => -1, 'translatable' => FALSE, - ))->save(); + ])->save(); FieldConfig::create([ 'entity_type' => 'user', 'field_name' => 'test_multiple', @@ -38,21 +38,21 @@ protected function setUp() { 'label' => 'Test a multiple valued field', ])->save(); entity_get_form_display('user', 'user', 'register') - ->setComponent('test_multiple', array( + ->setComponent('test_multiple', [ 'type' => 'text_textfield', 'weight' => 0, - )) + ]) ->save(); } /** * Tests a basic rebuild with the user registration form. */ - function testUserRegistrationRebuild() { - $edit = array( + public function testUserRegistrationRebuild() { + $edit = [ 'name' => 'foo', 'mail' => 'bar@example.com', - ); + ]; $this->drupalPostForm('user/register', $edit, 'Rebuild'); $this->assertText('Form rebuilt.'); $this->assertFieldByName('name', 'foo', 'Entered username has been kept.'); @@ -62,11 +62,11 @@ function testUserRegistrationRebuild() { /** * Tests a rebuild caused by a multiple value field. */ - function testUserRegistrationMultipleField() { - $edit = array( + public function testUserRegistrationMultipleField() { + $edit = [ 'name' => 'foo', 'mail' => 'bar@example.com', - ); + ]; $this->drupalPostForm('user/register', $edit, t('Add another item')); $this->assertText('Test a multiple valued field', 'Form has been rebuilt.'); $this->assertFieldByName('name', 'foo', 'Entered username has been kept.'); diff --git a/core/modules/system/tests/src/Functional/Form/CheckboxTest.php b/core/modules/system/tests/src/Functional/Form/CheckboxTest.php new file mode 100644 index 00000000..60fad6a2 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/CheckboxTest.php @@ -0,0 +1,99 @@ +getForm('\Drupal\form_test\Form\FormTestCheckboxTypeJugglingForm', $default_value, $return_value); + $form = \Drupal::service('renderer')->renderRoot($form_array); + if ($default_value === TRUE) { + $checked = TRUE; + } + elseif ($return_value === '0') { + $checked = ($default_value === '0'); + } + elseif ($return_value === '') { + $checked = ($default_value === ''); + } + elseif ($return_value === 1 || $return_value === '1') { + $checked = ($default_value === 1 || $default_value === '1'); + } + elseif ($return_value === 'foobar') { + $checked = ($default_value === 'foobar'); + } + elseif ($return_value === '1foobar') { + $checked = ($default_value === '1foobar'); + } + $checked_in_html = strpos($form, 'checked') !== FALSE; + $message = format_string('#default_value is %default_value #return_value is %return_value.', ['%default_value' => var_export($default_value, TRUE), '%return_value' => var_export($return_value, TRUE)]); + $this->assertIdentical($checked, $checked_in_html, $message); + } + } + + // Ensure that $form_state->getValues() is populated correctly for a + // checkboxes group that includes a 0-indexed array of options. + $this->drupalPostForm('form-test/checkboxes-zero/1', [], 'Save'); + $results = json_decode($this->getSession()->getPage()->getContent()); + $this->assertIdentical($results->checkbox_off, [0, 0, 0], 'All three in checkbox_off are zeroes: off.'); + $this->assertIdentical($results->checkbox_zero_default, ['0', 0, 0], 'The first choice is on in checkbox_zero_default'); + $this->assertIdentical($results->checkbox_string_zero_default, ['0', 0, 0], 'The first choice is on in checkbox_string_zero_default'); + // Due to Mink driver differences, we cannot submit an empty checkbox value + // to drupalPostForm(), even if that empty value is the 'true' value for + // the checkbox. + $this->drupalGet('form-test/checkboxes-zero/1'); + $this->assertSession()->fieldExists('checkbox_off[0]')->check(); + $this->drupalPostForm(NULL, NULL, 'Save'); + $results = json_decode($this->getSession()->getPage()->getContent()); + $this->assertIdentical($results->checkbox_off, ['0', 0, 0], 'The first choice is on in checkbox_off but the rest is not'); + + // Ensure that each checkbox is rendered correctly for a checkboxes group + // that includes a 0-indexed array of options. + $this->drupalPostForm('form-test/checkboxes-zero/0', [], 'Save'); + $checkboxes = $this->xpath('//input[@type="checkbox"]'); + + $this->assertIdentical(count($checkboxes), 9, 'Correct number of checkboxes found.'); + foreach ($checkboxes as $checkbox) { + $checked = $checkbox->isChecked(); + $name = $checkbox->getAttribute('name'); + $this->assertIdentical($checked, $name == 'checkbox_zero_default[0]' || $name == 'checkbox_string_zero_default[0]', format_string('Checkbox %name correctly checked', ['%name' => $name])); + } + // Due to Mink driver differences, we cannot submit an empty checkbox value + // to drupalPostForm(), even if that empty value is the 'true' value for + // the checkbox. + $this->drupalGet('form-test/checkboxes-zero/0'); + $this->assertSession()->fieldExists('checkbox_off[0]')->check(); + $this->drupalPostForm(NULL, NULL, 'Save'); + $checkboxes = $this->xpath('//input[@type="checkbox"]'); + + $this->assertIdentical(count($checkboxes), 9, 'Correct number of checkboxes found.'); + foreach ($checkboxes as $checkbox) { + $checked = $checkbox->isChecked(); + $name = (string) $checkbox->getAttribute('name'); + $this->assertIdentical($checked, $name == 'checkbox_off[0]' || $name == 'checkbox_zero_default[0]' || $name == 'checkbox_string_zero_default[0]', format_string('Checkbox %name correctly checked', ['%name' => $name])); + } + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/ConfirmFormTest.php b/core/modules/system/tests/src/Functional/Form/ConfirmFormTest.php new file mode 100644 index 00000000..c65546a4 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/ConfirmFormTest.php @@ -0,0 +1,86 @@ +drupalGet('form-test/confirm-form'); + $site_name = $this->config('system.site')->get('name'); + $this->assertTitle(t('ConfirmFormTestForm::getQuestion(). | @site-name', ['@site-name' => $site_name]), 'The question was found as the page title.'); + $this->assertText(t('ConfirmFormTestForm::getDescription().'), 'The description was used.'); + $this->assertFieldByXPath('//input[@id="edit-submit"]', t('ConfirmFormTestForm::getConfirmText().'), 'The confirm text was used.'); + + // Test cancelling the form. + $this->clickLink(t('ConfirmFormTestForm::getCancelText().')); + $this->assertUrl('form-test/autocomplete', [], "The form's cancel link was followed."); + + // Test submitting the form. + $this->drupalPostForm('form-test/confirm-form', NULL, t('ConfirmFormTestForm::getConfirmText().')); + $this->assertText('The ConfirmFormTestForm::submitForm() method was used for this form.'); + $this->assertUrl('', [], "The form's redirect was followed."); + + // Test submitting the form with a destination. + $this->drupalPostForm('form-test/confirm-form', NULL, t('ConfirmFormTestForm::getConfirmText().'), ['query' => ['destination' => 'admin/config']]); + $this->assertUrl('admin/config', [], "The form's redirect was not followed, the destination query string was followed."); + + // Test cancelling the form with a complex destination. + $this->drupalGet('form-test/confirm-form-array-path'); + $this->clickLink(t('ConfirmFormArrayPathTestForm::getCancelText().')); + $this->assertUrl('form-test/confirm-form', ['query' => ['destination' => 'admin/config']], "The form's complex cancel link was followed."); + } + + /** + * Tests that the confirm form does not use external destinations. + */ + public function testConfirmFormWithExternalDestination() { + $this->drupalGet('form-test/confirm-form'); + $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); + $this->drupalGet('form-test/confirm-form', ['query' => ['destination' => 'node']]); + $this->assertCancelLinkUrl(Url::fromUri('internal:/node')); + $this->drupalGet('form-test/confirm-form', ['query' => ['destination' => 'http://example.com']]); + $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); + $this->drupalGet('form-test/confirm-form', ['query' => ['destination' => '']]); + $this->assertCancelLinkUrl(Url::fromRoute('')); + // Other invalid destinations, should fall back to the form default. + $this->drupalGet('form-test/confirm-form', ['query' => ['destination' => '/http://example.com']]); + $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); + } + + /** + * Asserts that a cancel link is present pointing to the provided URL. + * + * @param \Drupal\Core\Url $url + * The url to check for. + * @param string $message + * The assert message. + * @param string $group + * The assertion group. + * + * @return bool + * Result of the assertion. + */ + public function assertCancelLinkUrl(Url $url, $message = '', $group = 'Other') { + $links = $this->xpath('//a[@href=:url]', [':url' => $url->toString()]); + $message = ($message ? $message : SafeMarkup::format('Cancel link with URL %url found.', ['%url' => $url->toString()])); + return $this->assertTrue(isset($links[0]), $message, $group); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/ElementTest.php b/core/modules/system/tests/src/Functional/Form/ElementTest.php new file mode 100644 index 00000000..57da8daf --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/ElementTest.php @@ -0,0 +1,226 @@ +drupalGet('form-test/placeholder-text'); + $expected = 'placeholder-text'; + // Test to make sure non-textarea elements have the proper placeholder text. + foreach (['textfield', 'tel', 'url', 'password', 'email', 'number'] as $type) { + $element = $this->xpath('//input[@id=:id and @placeholder=:expected]', [ + ':id' => 'edit-' . $type, + ':expected' => $expected, + ]); + $this->assertTrue(!empty($element), format_string('Placeholder text placed in @type.', ['@type' => $type])); + } + + // Test to make sure textarea has the proper placeholder text. + $element = $this->xpath('//textarea[@id=:id and @placeholder=:expected]', [ + ':id' => 'edit-textarea', + ':expected' => $expected, + ]); + $this->assertTrue(!empty($element), 'Placeholder text placed in textarea.'); + } + + /** + * Tests expansion of #options for #type checkboxes and radios. + */ + public function testOptions() { + $this->drupalGet('form-test/checkboxes-radios'); + + // Verify that all options appear in their defined order. + foreach (['checkbox', 'radio'] as $type) { + $elements = $this->xpath('//input[@type=:type]', [':type' => $type]); + $expected_values = ['0', 'foo', '1', 'bar', '>']; + foreach ($elements as $element) { + $expected = array_shift($expected_values); + $this->assertIdentical((string) $element->getAttribute('value'), $expected); + } + } + + // Verify that the choices are admin filtered as expected. + $this->assertRaw("Special Charalert('checkboxes');"); + $this->assertRaw("Special Charalert('radios');"); + $this->assertRaw('Bar - checkboxes'); + $this->assertRaw('Bar - radios'); + + // Enable customized option sub-elements. + $this->drupalGet('form-test/checkboxes-radios/customize'); + + // Verify that all options appear in their defined order, taking a custom + // #weight into account. + foreach (['checkbox', 'radio'] as $type) { + $elements = $this->xpath('//input[@type=:type]', [':type' => $type]); + $expected_values = ['0', 'foo', 'bar', '>', '1']; + foreach ($elements as $element) { + $expected = array_shift($expected_values); + $this->assertIdentical((string) $element->getAttribute('value'), $expected); + } + } + // Verify that custom #description properties are output. + foreach (['checkboxes', 'radios'] as $type) { + $elements = $this->xpath('//input[@id=:id]/following-sibling::div[@class=:class]', [ + ':id' => 'edit-' . $type . '-foo', + ':class' => 'description', + ]); + $this->assertTrue(count($elements), format_string('Custom %type option description found.', [ + '%type' => $type, + ])); + } + } + + /** + * Tests correct checked attribute for radios element. + */ + public function testRadiosChecked() { + // Verify that there is only one radio option checked. + $this->drupalGet('form-test/radios-checked'); + $elements = $this->xpath('//input[@name="radios" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('0', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-string" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('bar', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-boolean-true" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('1', $elements[0]->getValue()); + // A default value of FALSE indicates that nothing is set. + $elements = $this->xpath('//input[@name="radios-boolean-false" and @checked]'); + $this->assertCount(0, $elements); + $elements = $this->xpath('//input[@name="radios-boolean-any" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('All', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-string-zero" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('0', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-int-non-zero" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('10', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-int-non-zero-as-string" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('100', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-empty-string" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('0', $elements[0]->getValue()); + $elements = $this->xpath('//input[@name="radios-empty-array" and @checked]'); + $this->assertCount(0, $elements); + $elements = $this->xpath('//input[@name="radios-key-FALSE" and @checked]'); + $this->assertCount(1, $elements); + $this->assertSame('0', $elements[0]->getValue()); + } + + /** + * Tests wrapper ids for checkboxes and radios. + */ + public function testWrapperIds() { + $this->drupalGet('form-test/checkboxes-radios'); + + // Verify that wrapper id is different from element id. + foreach (['checkboxes', 'radios'] as $type) { + $element_ids = $this->xpath('//div[@id=:id]', [':id' => 'edit-' . $type]); + $wrapper_ids = $this->xpath('//fieldset[@id=:id]', [':id' => 'edit-' . $type . '--wrapper']); + $this->assertTrue(count($element_ids) == 1, format_string('A single element id found for type %type', ['%type' => $type])); + $this->assertTrue(count($wrapper_ids) == 1, format_string('A single wrapper id found for type %type', ['%type' => $type])); + } + } + + /** + * Tests button classes. + */ + public function testButtonClasses() { + $this->drupalGet('form-test/button-class'); + // Just contains(@class, "button") won't do because then + // "button--foo" would contain "button". Instead, check + // " button ". Make sure it matches in the beginning and the end too + // by adding a space before and after. + $this->assertEqual(2, count($this->xpath('//*[contains(concat(" ", @class, " "), " button ")]'))); + $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " button--foo ")]'))); + $this->assertEqual(1, count($this->xpath('//*[contains(concat(" ", @class, " "), " button--danger ")]'))); + } + + /** + * Tests the #group property. + */ + public function testGroupElements() { + $this->drupalGet('form-test/group-details'); + $elements = $this->xpath('//div[@class="details-wrapper"]//div[@class="details-wrapper"]//label'); + $this->assertTrue(count($elements) == 1); + $this->drupalGet('form-test/group-container'); + $elements = $this->xpath('//div[@id="edit-container"]//div[@class="details-wrapper"]//label'); + $this->assertTrue(count($elements) == 1); + $this->drupalGet('form-test/group-fieldset'); + $elements = $this->xpath('//fieldset[@id="edit-fieldset"]//div[@id="edit-meta"]//label'); + $this->assertTrue(count($elements) == 1); + $this->drupalGet('form-test/group-vertical-tabs'); + $elements = $this->xpath('//div[@data-vertical-tabs-panes]//details[@id="edit-meta"]//label'); + $this->assertTrue(count($elements) == 1); + $elements = $this->xpath('//div[@data-vertical-tabs-panes]//details[@id="edit-meta-2"]//label'); + $this->assertTrue(count($elements) == 1); + } + + /** + * Tests the #required property on details and fieldset elements. + */ + public function testRequiredFieldsetsAndDetails() { + $this->drupalGet('form-test/group-details'); + $this->assertFalse($this->cssSelect('summary.form-required')); + $this->drupalGet('form-test/group-details/1'); + $this->assertTrue($this->cssSelect('summary.form-required')); + $this->drupalGet('form-test/group-fieldset'); + $this->assertFalse($this->cssSelect('span.form-required')); + $this->drupalGet('form-test/group-fieldset/1'); + $this->assertTrue($this->cssSelect('span.form-required')); + } + + /** + * Tests a form with a autocomplete setting.. + */ + public function testFormAutocomplete() { + $this->drupalGet('form-test/autocomplete'); + + $result = $this->xpath('//input[@id="edit-autocomplete-1" and contains(@data-autocomplete-path, "form-test/autocomplete-1")]'); + $this->assertEqual(count($result), 0, 'Ensure that the user does not have access to the autocompletion'); + $result = $this->xpath('//input[@id="edit-autocomplete-2" and contains(@data-autocomplete-path, "form-test/autocomplete-2/value")]'); + $this->assertEqual(count($result), 0, 'Ensure that the user does not have access to the autocompletion'); + + $user = $this->drupalCreateUser(['access autocomplete test']); + $this->drupalLogin($user); + $this->drupalGet('form-test/autocomplete'); + + // Make sure that the autocomplete library is added. + $this->assertRaw('core/misc/autocomplete.js'); + + $result = $this->xpath('//input[@id="edit-autocomplete-1" and contains(@data-autocomplete-path, "form-test/autocomplete-1")]'); + $this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion'); + $result = $this->xpath('//input[@id="edit-autocomplete-2" and contains(@data-autocomplete-path, "form-test/autocomplete-2/value")]'); + $this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion'); + } + + /** + * Tests form element error messages. + */ + public function testFormElementErrors() { + $this->drupalPostForm('form_test/details-form', [], 'Submit'); + $this->assertText('I am an error on the details element.'); + } + +} diff --git a/core/modules/system/src/Tests/Form/ElementsAccessTest.php b/core/modules/system/tests/src/Functional/Form/ElementsAccessTest.php similarity index 85% rename from core/modules/system/src/Tests/Form/ElementsAccessTest.php rename to core/modules/system/tests/src/Functional/Form/ElementsAccessTest.php index 13386d7b..1a92893c 100644 --- a/core/modules/system/src/Tests/Form/ElementsAccessTest.php +++ b/core/modules/system/tests/src/Functional/Form/ElementsAccessTest.php @@ -1,22 +1,22 @@ drupalGet('form_test/form-labels'); // Check that the checkbox/radio processing is not interfering with @@ -85,9 +85,9 @@ function testFormLabels() { // Check title attribute for radios and checkboxes. $elements = $this->xpath('//div[@id="edit-form-checkboxes-title-attribute"]'); - $this->assertEqual($elements[0]['title'], 'Checkboxes test' . ' (' . t('Required') . ')', 'Title attribute found.'); + $this->assertEqual($elements[0]->getAttribute('title'), 'Checkboxes test' . ' (' . t('Required') . ')', 'Title attribute found.'); $elements = $this->xpath('//div[@id="edit-form-radios-title-attribute"]'); - $this->assertEqual($elements[0]['title'], 'Radios test' . ' (' . t('Required') . ')', 'Title attribute found.'); + $this->assertEqual($elements[0]->getAttribute('title'), 'Radios test' . ' (' . t('Required') . ')', 'Title attribute found.'); $elements = $this->xpath('//fieldset[@id="edit-form-checkboxes-title-invisible--wrapper"]/legend/span[contains(@class, "visually-hidden")]'); $this->assertTrue(!empty($elements), "Title/Label not displayed when 'visually-hidden' attribute is set in checkboxes."); @@ -99,7 +99,7 @@ function testFormLabels() { /** * Tests different display options for form element descriptions. */ - function testFormDescriptions() { + public function testFormDescriptions() { $this->drupalGet('form_test/form-descriptions'); // Check #description placement with #description_display='after'. @@ -126,7 +126,7 @@ function testFormDescriptions() { /** * Test forms in theme-less environments. */ - function testFormsInThemeLessEnvironments() { + public function testFormsInThemeLessEnvironments() { $form = $this->getFormWithLimitedProperties(); $render_service = $this->container->get('renderer'); // This should not throw any notices. @@ -137,12 +137,12 @@ function testFormsInThemeLessEnvironments() { * Return a form with element with not all properties defined. */ protected function getFormWithLimitedProperties() { - $form = array(); + $form = []; - $form['fieldset'] = array( + $form['fieldset'] = [ '#type' => 'fieldset', '#title' => 'Fieldset', - ); + ]; return $form; } diff --git a/core/modules/system/tests/src/Functional/Form/ElementsVerticalTabsTest.php b/core/modules/system/tests/src/Functional/Form/ElementsVerticalTabsTest.php new file mode 100644 index 00000000..07f25fef --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/ElementsVerticalTabsTest.php @@ -0,0 +1,95 @@ +adminUser = $this->drupalCreateUser(['access vertical_tab_test tabs']); + $this->webUser = $this->drupalCreateUser(); + $this->drupalLogin($this->adminUser); + } + + /** + * Ensures that vertical-tabs.js is included before collapse.js. + * + * Otherwise, collapse.js adds "SHOW" or "HIDE" labels to the tabs. + */ + public function testJavaScriptOrdering() { + $this->drupalGet('form_test/vertical-tabs'); + $content = $this->getSession()->getPage()->getContent(); + $position1 = strpos($content, 'core/misc/vertical-tabs.js'); + $position2 = strpos($content, 'core/misc/collapse.js'); + $this->assertTrue($position1 !== FALSE && $position2 !== FALSE && $position1 < $position2, 'vertical-tabs.js is included before collapse.js'); + } + + /** + * Ensures that vertical tab markup is not shown if user has no tab access. + */ + public function testWrapperNotShownWhenEmpty() { + // Test admin user can see vertical tabs and wrapper. + $this->drupalGet('form_test/vertical-tabs'); + $wrapper = $this->xpath("//div[@data-vertical-tabs-panes]"); + $this->assertTrue(isset($wrapper[0]), 'Vertical tab panes found.'); + + // Test wrapper markup not present for non-privileged web user. + $this->drupalLogin($this->webUser); + $this->drupalGet('form_test/vertical-tabs'); + $wrapper = $this->xpath("//div[@data-vertical-tabs-panes]"); + $this->assertFalse(isset($wrapper[0]), 'Vertical tab wrappers are not displayed to unprivileged users.'); + } + + /** + * Ensures that default vertical tab is correctly selected. + */ + public function testDefaultTab() { + $this->drupalGet('form_test/vertical-tabs'); + + $value = $this->assertSession() + ->elementExists('css', 'input[name="vertical_tabs__active_tab"]') + ->getValue(); + + $this->assertSame('edit-tab3', $value, t('The default vertical tab is correctly selected.')); + } + + /** + * Ensures that vertical tab form values are cleaned. + */ + public function testDefaultTabCleaned() { + $values = Json::decode($this->drupalPostForm('form_test/form-state-values-clean', [], t('Submit'))); + $this->assertFalse(isset($values['vertical_tabs__active_tab']), SafeMarkup::format('%element was removed.', ['%element' => 'vertical_tabs__active_tab'])); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/EmailTest.php b/core/modules/system/tests/src/Functional/Form/EmailTest.php new file mode 100644 index 00000000..2fe6ebe9 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/EmailTest.php @@ -0,0 +1,49 @@ +drupalPostForm('form-test/email', $edit, 'Submit'); + $this->assertRaw(t('The email address %mail is not valid.', ['%mail' => 'invalid'])); + $this->assertRaw(t('@name field is required.', ['@name' => 'Address'])); + + $edit = []; + $edit['email_required'] = ' foo.bar@example.com '; + $this->drupalPostForm('form-test/email', $edit, 'Submit'); + $values = Json::decode($this->getSession()->getPage()->getContent()); + $this->assertIdentical($values['email'], ''); + $this->assertEqual($values['email_required'], 'foo.bar@example.com'); + + $edit = []; + $edit['email'] = 'foo@example.com'; + $edit['email_required'] = 'example@drupal.org'; + $this->drupalPostForm('form-test/email', $edit, 'Submit'); + $values = Json::decode($this->getSession()->getPage()->getContent()); + $this->assertEqual($values['email'], 'foo@example.com'); + $this->assertEqual($values['email_required'], 'example@drupal.org'); + } + +} diff --git a/core/modules/system/src/Tests/Form/FormObjectTest.php b/core/modules/system/tests/src/Functional/Form/FormObjectTest.php similarity index 89% rename from core/modules/system/src/Tests/Form/FormObjectTest.php rename to core/modules/system/tests/src/Functional/Form/FormObjectTest.php index 38db2119..34ebb2e7 100644 --- a/core/modules/system/src/Tests/Form/FormObjectTest.php +++ b/core/modules/system/tests/src/Functional/Form/FormObjectTest.php @@ -1,6 +1,6 @@ form = new FormTestObject($this->container->get('config.factory')); - $this->values = array( - 'bananas' => array( + $this->values = [ + 'bananas' => [ '#value' => $this->randomString(10), '#config_name' => 'form_test.object', '#config_key' => 'bananas', - ), - ); + ], + ]; } /** @@ -37,14 +37,14 @@ protected function setUp() { * * @see \Drupal\form_test\EventSubscriber\FormTestEventSubscriber::onKernelRequest() */ - function testObjectFormCallback() { + public function testObjectFormCallback() { $config_factory = $this->container->get('config.factory'); $this->drupalGet('form-test/object-builder'); $this->assertText('The FormTestObject::buildForm() method was used for this form.'); $elements = $this->xpath('//form[@id="form-test-form-test-object"]'); $this->assertTrue(!empty($elements), 'The correct form ID was used.'); - $this->drupalPostForm(NULL, array('bananas' => 'green'), t('Save')); + $this->drupalPostForm(NULL, ['bananas' => 'green'], t('Save')); $this->assertText('The FormTestObject::validateForm() method was used for this form.'); $this->assertText('The FormTestObject::submitForm() method was used for this form.'); $value = $config_factory->get('form_test.object')->get('bananas'); @@ -64,7 +64,7 @@ function testObjectFormCallback() { $this->assertText('The FormTestServiceObject::buildForm() method was used for this form.'); $elements = $this->xpath('//form[@id="form-test-form-test-service-object"]'); $this->assertTrue(!empty($elements), 'The correct form ID was used.'); - $this->drupalPostForm(NULL, array('bananas' => 'brown'), t('Save')); + $this->drupalPostForm(NULL, ['bananas' => 'brown'], t('Save')); $this->assertText('The FormTestServiceObject::validateForm() method was used for this form.'); $this->assertText('The FormTestServiceObject::submitForm() method was used for this form.'); $value = $config_factory->get('form_test.object')->get('bananas'); @@ -77,7 +77,7 @@ function testObjectFormCallback() { $this->assertTrue(!empty($elements), 'The correct form ID was used.'); $this->assertText('custom_value', 'Ensure parameters are injected from request attributes.'); $this->assertText('request_value', 'Ensure the request object is injected.'); - $this->drupalPostForm(NULL, array('bananas' => 'black'), t('Save')); + $this->drupalPostForm(NULL, ['bananas' => 'black'], t('Save')); $this->assertText('The FormTestControllerObject::validateForm() method was used for this form.'); $this->assertText('The FormTestControllerObject::submitForm() method was used for this form.'); $value = $config_factory->get('form_test.object')->get('bananas'); diff --git a/core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php b/core/modules/system/tests/src/Functional/Form/FormStoragePageCacheTest.php similarity index 95% rename from core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php rename to core/modules/system/tests/src/Functional/Form/FormStoragePageCacheTest.php index 0ef62e86..474a35b5 100644 --- a/core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php +++ b/core/modules/system/tests/src/Functional/Form/FormStoragePageCacheTest.php @@ -1,20 +1,20 @@ xpath('//input[@name="form_build_id"]'); $this->assertEqual(count($build_id_fields), 1, 'One form build id field on the page'); - return (string) $build_id_fields[0]['value']; + return (string) $build_id_fields[0]->getAttribute('value'); } /** diff --git a/core/modules/system/tests/src/Functional/Form/FormTest.php b/core/modules/system/tests/src/Functional/Form/FormTest.php new file mode 100644 index 00000000..87c76324 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/FormTest.php @@ -0,0 +1,773 @@ + 'filtered_html', + 'name' => 'Filtered HTML', + ]); + $filtered_html_format->save(); + + $filtered_html_permission = $filtered_html_format->getPermissionName(); + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, [$filtered_html_permission]); + } + + /** + * Check several empty values for required forms elements. + * + * Carriage returns, tabs, spaces, and unchecked checkbox elements are not + * valid content for a required field. + * + * If the form field is found in $form_state->getErrors() then the test pass. + */ + public function testRequiredFields() { + // Originates from https://www.drupal.org/node/117748. + // Sets of empty strings and arrays. + $empty_strings = ['""' => "", '"\n"' => "\n", '" "' => " ", '"\t"' => "\t", '" \n\t "' => " \n\t ", '"\n\n\n\n\n"' => "\n\n\n\n\n"]; + $empty_arrays = ['array()' => []]; + $empty_checkbox = [NULL]; + + $elements['textfield']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'textfield']; + $elements['textfield']['empty_values'] = $empty_strings; + + $elements['telephone']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'tel']; + $elements['telephone']['empty_values'] = $empty_strings; + + $elements['url']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'url']; + $elements['url']['empty_values'] = $empty_strings; + + $elements['search']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'search']; + $elements['search']['empty_values'] = $empty_strings; + + $elements['password']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'password']; + $elements['password']['empty_values'] = $empty_strings; + + $elements['password_confirm']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'password_confirm']; + // Provide empty values for both password fields. + foreach ($empty_strings as $key => $value) { + $elements['password_confirm']['empty_values'][$key] = ['pass1' => $value, 'pass2' => $value]; + } + + $elements['textarea']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'textarea']; + $elements['textarea']['empty_values'] = $empty_strings; + + $elements['radios']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'radios', '#options' => ['' => t('None'), $this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName()]]; + $elements['radios']['empty_values'] = $empty_arrays; + + $elements['checkbox']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'checkbox', '#required' => TRUE]; + $elements['checkbox']['empty_values'] = $empty_checkbox; + + $elements['checkboxes']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'checkboxes', '#options' => [$this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName()]]; + $elements['checkboxes']['empty_values'] = $empty_arrays; + + $elements['select']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'select', '#options' => ['' => t('None'), $this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName()]]; + $elements['select']['empty_values'] = $empty_strings; + + $elements['file']['element'] = ['#title' => $this->randomMachineName(), '#type' => 'file']; + $elements['file']['empty_values'] = $empty_strings; + + // Regular expression to find the expected marker on required elements. + $required_marker_preg = '@<.*?class=".*?js-form-required.*form-required.*?">@'; + // Go through all the elements and all the empty values for them. + foreach ($elements as $type => $data) { + foreach ($data['empty_values'] as $key => $empty) { + foreach ([TRUE, FALSE] as $required) { + $form_id = $this->randomMachineName(); + $form = []; + $form_state = new FormState(); + $form['op'] = ['#type' => 'submit', '#value' => t('Submit')]; + $element = $data['element']['#title']; + $form[$element] = $data['element']; + $form[$element]['#required'] = $required; + $user_input[$element] = $empty; + $user_input['form_id'] = $form_id; + $form_state->setUserInput($user_input); + $form_state->setFormObject(new StubForm($form_id, $form)); + $form_state->setMethod('POST'); + // The form token CSRF protection should not interfere with this test, + // so we bypass it by setting the token to FALSE. + $form['#token'] = FALSE; + \Drupal::formBuilder()->prepareForm($form_id, $form, $form_state); + \Drupal::formBuilder()->processForm($form_id, $form, $form_state); + $errors = $form_state->getErrors(); + // Form elements of type 'radios' throw all sorts of PHP notices + // when you try to render them like this, so we ignore those for + // testing the required marker. + // @todo Fix this work-around (https://www.drupal.org/node/588438). + $form_output = ($type == 'radios') ? '' : \Drupal::service('renderer')->renderRoot($form); + if ($required) { + // Make sure we have a form error for this element. + $this->assertTrue(isset($errors[$element]), "Check empty($key) '$type' field '$element'"); + if (!empty($form_output)) { + // Make sure the form element is marked as required. + $this->assertTrue(preg_match($required_marker_preg, $form_output), "Required '$type' field is marked as required"); + } + } + else { + if (!empty($form_output)) { + // Make sure the form element is *not* marked as required. + $this->assertFalse(preg_match($required_marker_preg, $form_output), "Optional '$type' field is not marked as required"); + } + if ($type == 'select') { + // Select elements are going to have validation errors with empty + // input, since those are illegal choices. Just make sure the + // error is not "field is required". + $this->assertTrue((empty($errors[$element]) || strpos('field is required', (string) $errors[$element]) === FALSE), "Optional '$type' field '$element' is not treated as a required element"); + } + else { + // Make sure there is *no* form error for this element. + $this->assertTrue(empty($errors[$element]), "Optional '$type' field '$element' has no errors with empty input"); + } + } + } + } + } + // Clear the expected form error messages so they don't appear as exceptions. + drupal_get_messages(); + } + + /** + * Tests validation for required checkbox, select, and radio elements. + * + * Submits a test form containing several types of form elements. The form + * is submitted twice, first without values for required fields and then + * with values. Each submission is checked for relevant error messages. + * + * @see \Drupal\form_test\Form\FormTestValidateRequiredForm + */ + public function testRequiredCheckboxesRadio() { + $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestValidateRequiredForm'); + + // Attempt to submit the form with no required fields set. + $edit = []; + $this->drupalPostForm('form-test/validate-required', $edit, 'Submit'); + + // The only error messages that should appear are the relevant 'required' + // messages for each field. + $expected = []; + foreach (['textfield', 'checkboxes', 'select', 'radios'] as $key) { + if (isset($form[$key]['#required_error'])) { + $expected[] = $form[$key]['#required_error']; + } + elseif (isset($form[$key]['#form_test_required_error'])) { + $expected[] = $form[$key]['#form_test_required_error']; + } + else { + $expected[] = t('@name field is required.', ['@name' => $form[$key]['#title']]); + } + } + + // Check the page for error messages. + $errors = $this->xpath('//div[contains(@class, "error")]//li'); + foreach ($errors as $error) { + $expected_key = array_search($error->getText(), $expected); + // If the error message is not one of the expected messages, fail. + if ($expected_key === FALSE) { + $this->fail(format_string("Unexpected error message: @error", ['@error' => $error[0]])); + } + // Remove the expected message from the list once it is found. + else { + unset($expected[$expected_key]); + } + } + + // Fail if any expected messages were not found. + foreach ($expected as $not_found) { + $this->fail(format_string("Found error message: @error", ['@error' => $not_found])); + } + + // Verify that input elements are still empty. + $this->assertFieldByName('textfield', ''); + $this->assertNoFieldChecked('edit-checkboxes-foo'); + $this->assertNoFieldChecked('edit-checkboxes-bar'); + $this->assertOptionSelected('edit-select', ''); + $this->assertNoFieldChecked('edit-radios-foo'); + $this->assertNoFieldChecked('edit-radios-bar'); + $this->assertNoFieldChecked('edit-radios-optional-foo'); + $this->assertNoFieldChecked('edit-radios-optional-bar'); + $this->assertNoFieldChecked('edit-radios-optional-default-value-false-foo'); + $this->assertNoFieldChecked('edit-radios-optional-default-value-false-bar'); + + // Submit again with required fields set and verify that there are no + // error messages. + $edit = [ + 'textfield' => $this->randomString(), + 'checkboxes[foo]' => TRUE, + 'select' => 'foo', + 'radios' => 'bar', + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $this->assertNoFieldByXpath('//div[contains(@class, "error")]', FALSE, 'No error message is displayed when all required fields are filled.'); + $this->assertRaw("The form_test_validate_required_form form was submitted successfully.", 'Validation form submitted successfully.'); + } + + /** + * Tests that input is retained for safe elements even with an invalid token. + * + * Submits a test form containing several types of form elements. + */ + public function testInputWithInvalidToken() { + // We need to be logged in to have CSRF tokens. + $account = $this->createUser(); + $this->drupalLogin($account); + // Submit again with required fields set but an invalid form token and + // verify that all the values are retained. + $this->drupalGet(Url::fromRoute('form_test.validate_required')); + $this->assertSession() + ->elementExists('css', 'input[name="form_token"]') + ->setValue('invalid token'); + $edit = [ + 'textfield' => $this->randomString(), + 'checkboxes[bar]' => TRUE, + 'select' => 'bar', + 'radios' => 'foo', + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); + $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); + // Verify that input elements retained the posted values. + $this->assertFieldByName('textfield', $edit['textfield']); + $this->assertNoFieldChecked('edit-checkboxes-foo'); + $this->assertFieldChecked('edit-checkboxes-bar'); + $this->assertOptionSelected('edit-select', 'bar'); + $this->assertFieldChecked('edit-radios-foo'); + + // Check another form that has a textarea input. + $this->drupalGet(Url::fromRoute('form_test.required')); + $this->assertSession() + ->elementExists('css', 'input[name="form_token"]') + ->setValue('invalid token'); + $edit = [ + 'textfield' => $this->randomString(), + 'textarea' => $this->randomString() . "\n", + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); + $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); + $this->assertFieldByName('textfield', $edit['textfield']); + $this->assertFieldByName('textarea', $edit['textarea']); + + // Check another form that has a number input. + $this->drupalGet(Url::fromRoute('form_test.number')); + $this->assertSession() + ->elementExists('css', 'input[name="form_token"]') + ->setValue('invalid token'); + $edit = [ + 'integer_step' => mt_rand(1, 100), + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); + $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); + $this->assertFieldByName('integer_step', $edit['integer_step']); + + // Check a form with a Url field + $this->drupalGet(Url::fromRoute('form_test.url')); + $this->assertSession() + ->elementExists('css', 'input[name="form_token"]') + ->setValue('invalid token'); + $edit = [ + 'url' => $this->randomString(), + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); + $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); + $this->assertFieldByName('url', $edit['url']); + } + + /** + * CSRF tokens for GET forms should not be added by default. + */ + public function testGetFormsCsrfToken() { + // We need to be logged in to have CSRF tokens. + $account = $this->createUser(); + $this->drupalLogin($account); + + $this->drupalGet(Url::fromRoute('form_test.get_form')); + $this->assertNoRaw('form_token'); + } + + /** + * Tests validation for required textfield element without title. + * + * Submits a test form containing a textfield form element without title. + * The form is submitted twice, first without value for the required field + * and then with value. Each submission is checked for relevant error + * messages. + * + * @see \Drupal\form_test\Form\FormTestValidateRequiredNoTitleForm + */ + public function testRequiredTextfieldNoTitle() { + // Attempt to submit the form with no required field set. + $edit = []; + $this->drupalPostForm('form-test/validate-required-no-title', $edit, 'Submit'); + $this->assertNoRaw("The form_test_validate_required_form_no_title form was submitted successfully.", 'Validation form submitted successfully.'); + + // Check the page for the error class on the textfield. + $this->assertFieldByXPath('//input[contains(@class, "error")]', FALSE, 'Error input form element class found.'); + + // Check the page for the aria-invalid attribute on the textfield. + $this->assertFieldByXPath('//input[contains(@aria-invalid, "true")]', FALSE, 'Aria invalid attribute found.'); + + // Submit again with required fields set and verify that there are no + // error messages. + $edit = [ + 'textfield' => $this->randomString(), + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $this->assertNoFieldByXpath('//input[contains(@class, "error")]', FALSE, 'No error input form element class found.'); + $this->assertRaw("The form_test_validate_required_form_no_title form was submitted successfully.", 'Validation form submitted successfully.'); + } + + /** + * Test default value handling for checkboxes. + * + * @see _form_test_checkbox() + */ + public function testCheckboxProcessing() { + // First, try to submit without the required checkbox. + $edit = []; + $this->drupalPostForm('form-test/checkbox', $edit, t('Submit')); + $this->assertRaw(t('@name field is required.', ['@name' => 'required_checkbox']), 'A required checkbox is actually mandatory'); + + // Now try to submit the form correctly. + $this->drupalPostForm(NULL, ['required_checkbox' => 1], t('Submit')); + $values = Json::decode($this->getSession()->getPage()->getContent()); + $expected_values = [ + 'disabled_checkbox_on' => 'disabled_checkbox_on', + 'disabled_checkbox_off' => 0, + 'checkbox_on' => 'checkbox_on', + 'checkbox_off' => 0, + 'zero_checkbox_on' => '0', + 'zero_checkbox_off' => 0, + ]; + foreach ($expected_values as $widget => $expected_value) { + $this->assertSame($values[$widget], $expected_value, format_string('Checkbox %widget returns expected value (expected: %expected, got: %value)', [ + '%widget' => var_export($widget, TRUE), + '%expected' => var_export($expected_value, TRUE), + '%value' => var_export($values[$widget], TRUE), + ])); + } + } + + /** + * Tests validation of #type 'select' elements. + */ + public function testSelect() { + $form = \Drupal::formBuilder()->getForm('Drupal\form_test\Form\FormTestSelectForm'); + $this->drupalGet('form-test/select'); + + // Verify that the options are escaped as expected. + $this->assertEscaped('four'); + $this->assertNoRaw('four'); + + // Posting without any values should throw validation errors. + $this->drupalPostForm(NULL, [], 'Submit'); + $no_errors = [ + 'select', + 'select_required', + 'select_optional', + 'empty_value', + 'empty_value_one', + 'no_default_optional', + 'no_default_empty_option_optional', + 'no_default_empty_value_optional', + 'multiple', + 'multiple_no_default', + ]; + foreach ($no_errors as $key) { + $this->assertNoText(t('@name field is required.', ['@name' => $form[$key]['#title']])); + } + + $expected_errors = [ + 'no_default', + 'no_default_empty_option', + 'no_default_empty_value', + 'no_default_empty_value_one', + 'multiple_no_default_required', + ]; + foreach ($expected_errors as $key) { + $this->assertText(t('@name field is required.', ['@name' => $form[$key]['#title']])); + } + + // Post values for required fields. + $edit = [ + 'no_default' => 'three', + 'no_default_empty_option' => 'three', + 'no_default_empty_value' => 'three', + 'no_default_empty_value_one' => 'three', + 'multiple_no_default_required[]' => 'three', + ]; + $this->drupalPostForm(NULL, $edit, 'Submit'); + $values = Json::decode($this->getRawContent()); + + // Verify expected values. + $expected = [ + 'select' => 'one', + 'empty_value' => 'one', + 'empty_value_one' => 'one', + 'no_default' => 'three', + 'no_default_optional' => 'one', + 'no_default_optional_empty_value' => '', + 'no_default_empty_option' => 'three', + 'no_default_empty_option_optional' => '', + 'no_default_empty_value' => 'three', + 'no_default_empty_value_one' => 'three', + 'no_default_empty_value_optional' => 0, + 'multiple' => ['two' => 'two'], + 'multiple_no_default' => [], + 'multiple_no_default_required' => ['three' => 'three'], + ]; + foreach ($expected as $key => $value) { + $this->assertIdentical($values[$key], $value, format_string('@name: @actual is equal to @expected.', [ + '@name' => $key, + '@actual' => var_export($values[$key], TRUE), + '@expected' => var_export($value, TRUE), + ])); + } + } + + /** + * Tests a select element when #options is not set. + */ + public function testEmptySelect() { + $this->drupalGet('form-test/empty-select'); + $this->assertFieldByXPath("//select[1]", NULL, 'Select element found.'); + $this->assertNoFieldByXPath("//select[1]/option", NULL, 'No option element found.'); + } + + /** + * Tests validation of #type 'number' and 'range' elements. + */ + public function testNumber() { + $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestNumberForm'); + + // Array with all the error messages to be checked. + $error_messages = [ + 'no_number' => '%name must be a number.', + 'too_low' => '%name must be higher than or equal to %min.', + 'too_high' => '%name must be lower than or equal to %max.', + 'step_mismatch' => '%name is not a valid number.', + ]; + + // The expected errors. + $expected = [ + 'integer_no_number' => 'no_number', + 'integer_no_step' => 0, + 'integer_no_step_step_error' => 'step_mismatch', + 'integer_step' => 0, + 'integer_step_error' => 'step_mismatch', + 'integer_step_min' => 0, + 'integer_step_min_error' => 'too_low', + 'integer_step_max' => 0, + 'integer_step_max_error' => 'too_high', + 'integer_step_min_border' => 0, + 'integer_step_max_border' => 0, + 'integer_step_based_on_min' => 0, + 'integer_step_based_on_min_error' => 'step_mismatch', + 'float_small_step' => 0, + 'float_step_no_error' => 0, + 'float_step_error' => 'step_mismatch', + 'float_step_hard_no_error' => 0, + 'float_step_hard_error' => 'step_mismatch', + 'float_step_any_no_error' => 0, + ]; + + // First test the number element type, then range. + foreach (['form-test/number', 'form-test/number/range'] as $path) { + // Post form and show errors. + $this->drupalPostForm($path, [], 'Submit'); + + foreach ($expected as $element => $error) { + // Create placeholder array. + $placeholders = [ + '%name' => $form[$element]['#title'], + '%min' => isset($form[$element]['#min']) ? $form[$element]['#min'] : '0', + '%max' => isset($form[$element]['#max']) ? $form[$element]['#max'] : '0', + ]; + + foreach ($error_messages as $id => $message) { + // Check if the error exists on the page, if the current message ID is + // expected. Otherwise ensure that the error message is not present. + if ($id === $error) { + $this->assertRaw(format_string($message, $placeholders)); + } + else { + $this->assertNoRaw(format_string($message, $placeholders)); + } + } + } + } + } + + /** + * Tests default value handling of #type 'range' elements. + */ + public function testRange() { + $this->drupalPostForm('form-test/range', [], 'Submit'); + $values = json_decode($this->getSession()->getPage()->getContent()); + $this->assertEqual($values->with_default_value, 18); + $this->assertEqual($values->float, 10.5); + $this->assertEqual($values->integer, 6); + $this->assertEqual($values->offset, 6.9); + + $this->drupalPostForm('form-test/range/invalid', [], 'Submit'); + $this->assertFieldByXPath('//input[@type="range" and contains(@class, "error")]', NULL, 'Range element has the error class.'); + } + + /** + * Tests validation of #type 'color' elements. + */ + public function testColorValidation() { + // Keys are inputs, values are expected results. + $values = [ + '' => '#000000', + '#000' => '#000000', + 'AAA' => '#aaaaaa', + '#af0DEE' => '#af0dee', + '#99ccBc' => '#99ccbc', + '#aabbcc' => '#aabbcc', + '123456' => '#123456', + ]; + + // Tests that valid values are properly normalized. + foreach ($values as $input => $expected) { + $edit = [ + 'color' => $input, + ]; + $this->drupalPostForm('form-test/color', $edit, 'Submit'); + $result = json_decode($this->getSession()->getPage()->getContent()); + $this->assertEqual($result->color, $expected); + } + + // Tests invalid values are rejected. + $values = ['#0008', '#1234', '#fffffg', '#abcdef22', '17', '#uaa']; + foreach ($values as $input) { + $edit = [ + 'color' => $input, + ]; + $this->drupalPostForm('form-test/color', $edit, 'Submit'); + $this->assertRaw(t('%name must be a valid color.', ['%name' => 'Color'])); + } + } + + /** + * Test handling of disabled elements. + * + * @see _form_test_disabled_elements() + */ + public function testDisabledElements() { + // Get the raw form in its original state. + $form_state = new FormState(); + $form = (new FormTestDisabledElementsForm())->buildForm([], $form_state); + + // Build a submission that tries to hijack the form by submitting input for + // elements that are disabled. + $edit = []; + foreach (Element::children($form) as $key) { + if (isset($form[$key]['#test_hijack_value'])) { + if (is_array($form[$key]['#test_hijack_value'])) { + foreach ($form[$key]['#test_hijack_value'] as $subkey => $value) { + $edit[$key . '[' . $subkey . ']'] = $value; + } + } + else { + $edit[$key] = $form[$key]['#test_hijack_value']; + } + } + } + + // Submit the form with no input, as the browser does for disabled elements, + // and fetch the $form_state->getValues() that is passed to the submit handler. + $this->drupalPostForm('form-test/disabled-elements', [], t('Submit')); + $returned_values['normal'] = Json::decode($this->getSession()->getPage()->getContent()); + + // Do the same with input, as could happen if JavaScript un-disables an + // element. drupalPostForm() emulates a browser by not submitting input for + // disabled elements, so we need to un-disable those elements first. + $this->drupalGet('form-test/disabled-elements'); + $disabled_elements = []; + foreach ($this->xpath('//*[@disabled]') as $element) { + $disabled_elements[] = (string) $element->getAttribute('name'); + } + + // All the elements should be marked as disabled, including the ones below + // the disabled container. + $actual_count = count($disabled_elements); + $expected_count = 42; + $this->assertEqual($actual_count, $expected_count, SafeMarkup::format('Found @actual elements with disabled property (expected @expected).', [ + '@actual' => count($disabled_elements), + '@expected' => $expected_count, + ])); + + // Mink does not "see" hidden elements, so we need to set the value of the + // hidden element directly. + $this->assertSession() + ->elementExists('css', 'input[name="hidden"]') + ->setValue($edit['hidden']); + unset($edit['hidden']); + $this->drupalPostForm(NULL, $edit, t('Submit')); + $returned_values['hijacked'] = Json::decode($this->getSession()->getPage()->getContent()); + + // Ensure that the returned values match the form's default values in both + // cases. + foreach ($returned_values as $values) { + $this->assertFormValuesDefault($values, $form); + } + } + + /** + * Assert that the values submitted to a form matches the default values of the elements. + */ + public function assertFormValuesDefault($values, $form) { + foreach (Element::children($form) as $key) { + if (isset($form[$key]['#default_value'])) { + if (isset($form[$key]['#expected_value'])) { + $expected_value = $form[$key]['#expected_value']; + } + else { + $expected_value = $form[$key]['#default_value']; + } + + if ($key == 'checkboxes_multiple') { + // Checkboxes values are not filtered out. + $values[$key] = array_filter($values[$key]); + } + $this->assertIdentical($expected_value, $values[$key], format_string('Default value for %type: expected %expected, returned %returned.', ['%type' => $key, '%expected' => var_export($expected_value, TRUE), '%returned' => var_export($values[$key], TRUE)])); + } + + // Recurse children. + $this->assertFormValuesDefault($values, $form[$key]); + } + } + + /** + * Verify markup for disabled form elements. + * + * @see _form_test_disabled_elements() + */ + public function testDisabledMarkup() { + $this->drupalGet('form-test/disabled-elements'); + $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestDisabledElementsForm'); + $type_map = [ + 'textarea' => 'textarea', + 'select' => 'select', + 'weight' => 'select', + 'datetime' => 'datetime', + ]; + + foreach ($form as $name => $item) { + // Skip special #types. + if (!isset($item['#type']) || in_array($item['#type'], ['hidden', 'text_format'])) { + continue; + } + // Setup XPath and CSS class depending on #type. + if (in_array($item['#type'], ['button', 'submit'])) { + $path = "//!type[contains(@class, :div-class) and @value=:value]"; + $class = 'is-disabled'; + } + elseif (in_array($item['#type'], ['image_button'])) { + $path = "//!type[contains(@class, :div-class) and @value=:value]"; + $class = 'is-disabled'; + } + else { + // starts-with() required for checkboxes. + $path = "//div[contains(@class, :div-class)]/descendant::!type[starts-with(@name, :name)]"; + $class = 'form-disabled'; + } + // Replace DOM element name in $path according to #type. + $type = 'input'; + if (isset($type_map[$item['#type']])) { + $type = $type_map[$item['#type']]; + } + if (isset($item['#value']) && is_object($item['#value'])) { + $item['#value'] = (string) $item['#value']; + } + $path = strtr($path, ['!type' => $type]); + // Verify that the element exists. + $element = $this->xpath($path, [ + ':name' => Html::escape($name), + ':div-class' => $class, + ':value' => isset($item['#value']) ? $item['#value'] : '', + ]); + $this->assertTrue(isset($element[0]), format_string('Disabled form element class found for #type %type.', ['%type' => $item['#type']])); + } + + // Verify special element #type text-format. + $element = $this->xpath('//div[contains(@class, :div-class)]/descendant::textarea[@name=:name]', [ + ':name' => 'text_format[value]', + ':div-class' => 'form-disabled', + ]); + $this->assertTrue(isset($element[0]), format_string('Disabled form element class found for #type %type.', ['%type' => 'text_format[value]'])); + $element = $this->xpath('//div[contains(@class, :div-class)]/descendant::select[@name=:name]', [ + ':name' => 'text_format[format]', + ':div-class' => 'form-disabled', + ]); + $this->assertTrue(isset($element[0]), format_string('Disabled form element class found for #type %type.', ['%type' => 'text_format[format]'])); + } + + /** + * Test Form API protections against input forgery. + * + * @see \Drupal\form_test\Form\FormTestInputForgeryForm + */ + public function testInputForgery() { + $this->drupalGet('form-test/input-forgery'); + // The value for checkboxes[two] was changed using post render to simulate + // an input forgery. + // @see \Drupal\form_test\Form\FormTestInputForgeryForm::postRender + $this->drupalPostForm(NULL, ['checkboxes[one]' => TRUE, 'checkboxes[two]' => TRUE], t('Submit')); + $this->assertText('An illegal choice has been detected.', 'Input forgery was detected.'); + } + + /** + * Tests required attribute. + */ + public function testRequiredAttribute() { + $this->drupalGet('form-test/required-attribute'); + $expected = 'required'; + // Test to make sure the elements have the proper required attribute. + foreach (['textfield', 'password'] as $type) { + $element = $this->xpath('//input[@id=:id and @required=:expected]', [ + ':id' => 'edit-' . $type, + ':expected' => $expected, + ]); + $this->assertTrue(!empty($element), format_string('The @type has the proper required attribute.', ['@type' => $type])); + } + + // Test to make sure textarea has the proper required attribute. + $element = $this->xpath('//textarea[@id=:id and @required=:expected]', [ + ':id' => 'edit-textarea', + ':expected' => $expected, + ]); + $this->assertTrue(!empty($element), 'The textarea has the proper required attribute.'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/LanguageSelectElementTest.php b/core/modules/system/tests/src/Functional/Form/LanguageSelectElementTest.php new file mode 100644 index 00000000..1bfa19f4 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/LanguageSelectElementTest.php @@ -0,0 +1,118 @@ + 'aaa', + 'label' => $this->randomMachineName(), + ])->save(); + + ConfigurableLanguage::create([ + 'id' => 'bbb', + 'label' => $this->randomMachineName(), + ])->save(); + + \Drupal::languageManager()->reset(); + + $this->drupalGet('form-test/language_select'); + // Check that the language fields were rendered on the page. + $ids = [ + 'edit-languages-all' => LanguageInterface::STATE_ALL, + 'edit-languages-configurable' => LanguageInterface::STATE_CONFIGURABLE, + 'edit-languages-locked' => LanguageInterface::STATE_LOCKED, + 'edit-languages-config-and-locked' => LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_LOCKED + ]; + foreach ($ids as $id => $flags) { + $this->assertField($id, format_string('The @id field was found on the page.', ['@id' => $id])); + $options = []; + /* @var $language_manager \Drupal\Core\Language\LanguageManagerInterface */ + $language_manager = $this->container->get('language_manager'); + foreach ($language_manager->getLanguages($flags) as $langcode => $language) { + $options[$langcode] = $language->isLocked() ? t('- @name -', ['@name' => $language->getName()]) : $language->getName(); + } + $this->_testLanguageSelectElementOptions($id, $options); + } + + // Test that the #options were not altered by #languages. + $this->assertField('edit-language-custom-options', format_string('The @id field was found on the page.', ['@id' => 'edit-language-custom-options'])); + $this->_testLanguageSelectElementOptions('edit-language-custom-options', ['opt1' => 'First option', 'opt2' => 'Second option', 'opt3' => 'Third option']); + } + + /** + * Tests the case when the language select elements should not be printed. + * + * This happens when the language module is disabled. + */ + public function testHiddenLanguageSelectElement() { + // Disable the language module, so that the language select field will not + // be rendered. + $this->container->get('module_installer')->uninstall(['language']); + $this->drupalGet('form-test/language_select'); + // Check that the language fields were rendered on the page. + $ids = ['edit-languages-all', 'edit-languages-configurable', 'edit-languages-locked', 'edit-languages-config-and-locked']; + foreach ($ids as $id) { + $this->assertNoField($id, format_string('The @id field was not found on the page.', ['@id' => $id])); + } + + // Check that the submitted values were the default values of the language + // field elements. + $edit = []; + $this->drupalPostForm(NULL, $edit, t('Submit')); + $values = Json::decode($this->getRawContent()); + $this->assertEqual($values['languages_all'], 'xx'); + $this->assertEqual($values['languages_configurable'], 'en'); + $this->assertEqual($values['languages_locked'], LanguageInterface::LANGCODE_NOT_SPECIFIED); + $this->assertEqual($values['languages_config_and_locked'], 'dummy_value'); + $this->assertEqual($values['language_custom_options'], 'opt2'); + } + + /** + * Helper function to check the options of a language select form element. + * + * @param string $id + * The id of the language select element to check. + * + * @param array $options + * An array with options to compare with. + */ + protected function _testLanguageSelectElementOptions($id, $options) { + // Check that the options in the language field are exactly the same, + // including the order, as the languages sent as a parameter. + $elements = $this->xpath("//select[@id='" . $id . "']"); + $count = 0; + /** @var \Behat\Mink\Element\NodeElement $option */ + foreach ($elements[0]->findAll('css', 'option') as $option) { + $count++; + $option_title = current($options); + $this->assertEqual($option->getText(), $option_title); + next($options); + } + $this->assertEqual($count, count($options), format_string('The number of languages and the number of options shown by the language element are the same: @languages languages, @number options', ['@languages' => count($options), '@number' => $count])); + } + +} diff --git a/core/modules/system/src/Tests/Form/ModulesListFormWebTest.php b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php similarity index 84% rename from core/modules/system/src/Tests/Form/ModulesListFormWebTest.php rename to core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php index 921a27d7..dc63e64d 100644 --- a/core/modules/system/src/Tests/Form/ModulesListFormWebTest.php +++ b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php @@ -1,20 +1,20 @@ drupalLogin( $this->drupalCreateUser( - array('administer modules', 'administer permissions') + ['administer modules', 'administer permissions'] ) ); $this->drupalGet('admin/modules'); diff --git a/core/modules/system/tests/src/Functional/Form/RedirectTest.php b/core/modules/system/tests/src/Functional/Form/RedirectTest.php new file mode 100644 index 00000000..a4c9e15b --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/RedirectTest.php @@ -0,0 +1,106 @@ + ['foo' => 'bar']]; + $options['absolute'] = TRUE; + + // Test basic redirection. + $edit = [ + 'redirection' => TRUE, + 'destination' => $this->randomMachineName(), + ]; + $this->drupalPostForm($path, $edit, t('Submit')); + $this->assertUrl($edit['destination'], [], 'Basic redirection works.'); + + + // Test without redirection. + $edit = [ + 'redirection' => FALSE, + ]; + $this->drupalPostForm($path, $edit, t('Submit')); + $this->assertUrl($path, [], 'When redirect is set to FALSE, there should be no redirection.'); + + // Test redirection with query parameters. + $edit = [ + 'redirection' => TRUE, + 'destination' => $this->randomMachineName(), + ]; + $this->drupalPostForm($path, $edit, t('Submit'), $options); + $this->assertUrl($edit['destination'], [], 'Redirection with query parameters works.'); + + // Test without redirection but with query parameters. + $edit = [ + 'redirection' => FALSE, + ]; + $this->drupalPostForm($path, $edit, t('Submit'), $options); + $this->assertUrl($path, $options, 'When redirect is set to FALSE, there should be no redirection, and the query parameters should be passed along.'); + + // Test redirection back to the original path. + $edit = [ + 'redirection' => TRUE, + 'destination' => '', + ]; + $this->drupalPostForm($path, $edit, t('Submit')); + $this->assertUrl($path, [], 'When using an empty redirection string, there should be no redirection.'); + + // Test redirection back to the original path with query parameters. + $edit = [ + 'redirection' => TRUE, + 'destination' => '', + ]; + $this->drupalPostForm($path, $edit, t('Submit'), $options); + $this->assertUrl($path, $options, 'When using an empty redirection string, there should be no redirection, and the query parameters should be passed along.'); + } + + /** + * Tests form redirection from 404/403 pages with the Block form. + */ + public function testRedirectFromErrorPages() { + // Make sure the block containing the redirect form is placed. + $this->drupalPlaceBlock('redirect_form_block'); + + // Create a user that does not have permission to administer blocks. + $user = $this->drupalCreateUser(['administer themes']); + $this->drupalLogin($user); + + // Visit page 'foo' (404 page) and submit the form. Verify it ends up + // at the right URL. + $expected = \Drupal::url('form_test.route1', [], ['query' => ['test1' => 'test2'], 'absolute' => TRUE]); + $this->drupalGet('foo'); + $this->assertResponse(404); + $this->drupalPostForm(NULL, [], t('Submit')); + $this->assertResponse(200); + $this->assertUrl($expected, [], 'Redirected to correct URL/query.'); + + // Visit the block admin page (403 page) and submit the form. Verify it + // ends up at the right URL. + $this->drupalGet('admin/structure/block'); + $this->assertResponse(403); + $this->drupalPostForm(NULL, [], t('Submit')); + $this->assertResponse(200); + $this->assertUrl($expected, [], 'Redirected to correct URL/query.'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/ResponseTest.php b/core/modules/system/tests/src/Functional/Form/ResponseTest.php new file mode 100644 index 00000000..de5d8fd6 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/ResponseTest.php @@ -0,0 +1,49 @@ + $this->randomString(), + 'status' => 200, + ]; + $this->drupalPostForm('form-test/response', $edit, 'Submit'); + $content = Json::decode($this->getSession()->getPage()->getContent()); + $this->assertResponse(200); + $this->assertIdentical($edit['content'], $content, 'Response content matches'); + $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Response-Event'), 'Response handled by kernel response subscriber'); + $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Stack-Middleware'), 'Response handled by kernel middleware'); + + $edit = [ + 'content' => $this->randomString(), + 'status' => 418, + ]; + $this->drupalPostForm('form-test/response', $edit, 'Submit'); + $content = Json::decode($this->getSession()->getPage()->getContent()); + $this->assertResponse(418); + $this->assertIdentical($edit['content'], $content, 'Response content matches'); + $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Response-Event'), 'Response handled by kernel response subscriber'); + $this->assertIdentical('invoked', $this->drupalGetHeader('X-Form-Test-Stack-Middleware'), 'Response handled by kernel middleware'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/StateValuesCleanAdvancedTest.php b/core/modules/system/tests/src/Functional/Form/StateValuesCleanAdvancedTest.php new file mode 100644 index 00000000..63d8e70c --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/StateValuesCleanAdvancedTest.php @@ -0,0 +1,56 @@ +drupalGetTestFiles('image'); + $this->image = current($image_files); + + // Check if the physical file is there. + $this->assertTrue(is_file($this->image->uri), "The image file we're going to upload exists."); + + // "Browse" for the desired file. + $edit = ['files[image]' => drupal_realpath($this->image->uri)]; + + // Post the form. + $this->drupalPostForm('form_test/form-state-values-clean-advanced', $edit, t('Submit')); + + // Expecting a 200 HTTP code. + $this->assertResponse(200, 'Received a 200 response for posted test file.'); + $this->assertRaw(t('You WIN!'), 'Found the success message.'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/StateValuesCleanTest.php b/core/modules/system/tests/src/Functional/Form/StateValuesCleanTest.php new file mode 100644 index 00000000..62664872 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/StateValuesCleanTest.php @@ -0,0 +1,59 @@ +drupalPostForm('form_test/form-state-values-clean', [], t('Submit')); + $values = Json::decode($this->getSession()->getPage()->getContent()); + + // Setup the expected result. + $result = [ + 'beer' => 1000, + 'baz' => ['beer' => 2000], + ]; + + // Verify that all internal Form API elements were removed. + $this->assertFalse(isset($values['form_id']), format_string('%element was removed.', ['%element' => 'form_id'])); + $this->assertFalse(isset($values['form_token']), format_string('%element was removed.', ['%element' => 'form_token'])); + $this->assertFalse(isset($values['form_build_id']), format_string('%element was removed.', ['%element' => 'form_build_id'])); + $this->assertFalse(isset($values['op']), format_string('%element was removed.', ['%element' => 'op'])); + + // Verify that all buttons were removed. + $this->assertFalse(isset($values['foo']), format_string('%element was removed.', ['%element' => 'foo'])); + $this->assertFalse(isset($values['bar']), format_string('%element was removed.', ['%element' => 'bar'])); + $this->assertFalse(isset($values['baz']['foo']), format_string('%element was removed.', ['%element' => 'foo'])); + $this->assertFalse(isset($values['baz']['baz']), format_string('%element was removed.', ['%element' => 'baz'])); + + // Verify values manually added for cleaning were removed. + $this->assertFalse(isset($values['wine']), SafeMarkup::format('%element was removed.', ['%element' => 'wine'])); + + // Verify that nested form value still exists. + $this->assertTrue(isset($values['baz']['beer']), 'Nested form value still exists.'); + + // Verify that actual form values equal resulting form values. + $this->assertEqual($values, $result, 'Expected form values equal actual form values.'); + } + +} diff --git a/core/modules/system/src/Tests/Form/StubForm.php b/core/modules/system/tests/src/Functional/Form/StubForm.php similarity index 95% rename from core/modules/system/src/Tests/Form/StubForm.php rename to core/modules/system/tests/src/Functional/Form/StubForm.php index afeb79c3..4cf91c04 100644 --- a/core/modules/system/src/Tests/Form/StubForm.php +++ b/core/modules/system/tests/src/Functional/Form/StubForm.php @@ -1,6 +1,6 @@ drupalGet('form-test/system-config-form'); + $element = $this->xpath('//div[@id = :id]/input[contains(@class, :class)]', [':id' => 'edit-actions', ':class' => 'button--primary']); + $this->assertTrue($element, 'The primary action submit button was found.'); + $this->drupalPostForm(NULL, [], t('Save configuration')); + $this->assertText(t('The configuration options have been saved.')); + } + +} diff --git a/core/modules/system/tests/src/Functional/Form/UrlTest.php b/core/modules/system/tests/src/Functional/Form/UrlTest.php new file mode 100644 index 00000000..82d227bb --- /dev/null +++ b/core/modules/system/tests/src/Functional/Form/UrlTest.php @@ -0,0 +1,52 @@ +drupalPostForm('form-test/url', $edit, 'Submit'); + $this->assertRaw(t('The URL %url is not valid.', ['%url' => 'http://'])); + $this->assertRaw(t('@name field is required.', ['@name' => 'Required URL'])); + + $edit = []; + $edit['url'] = "\n"; + $edit['url_required'] = 'http://example.com/ '; + $this->drupalPostForm('form-test/url', $edit, 'Submit'); + $values = Json::decode($this->getSession()->getPage()->getContent()); + $this->assertIdentical($values['url'], ''); + $this->assertEqual($values['url_required'], 'http://example.com/'); + + $edit = []; + $edit['url'] = 'http://foo.bar.example.com/'; + $edit['url_required'] = 'https://www.drupal.org/node/1174630?page=0&foo=bar#new'; + $this->drupalPostForm('form-test/url', $edit, 'Submit'); + $values = Json::decode($this->getSession()->getPage()->getContent()); + $this->assertEqual($values['url'], $edit['url']); + $this->assertEqual($values['url_required'], $edit['url_required']); + } + +} diff --git a/core/modules/system/src/Tests/Form/ValidationTest.php b/core/modules/system/tests/src/Functional/Form/ValidationTest.php similarity index 77% rename from core/modules/system/src/Tests/Form/ValidationTest.php rename to core/modules/system/tests/src/Functional/Form/ValidationTest.php index 35b340b5..094a0af7 100644 --- a/core/modules/system/src/Tests/Form/ValidationTest.php +++ b/core/modules/system/tests/src/Functional/Form/ValidationTest.php @@ -1,69 +1,71 @@ drupalGet('form-test/validate'); // Verify that #element_validate handlers can alter the form and submitted // form values. - $edit = array( + $edit = [ 'name' => 'element_validate', - ); + ]; $this->drupalPostForm(NULL, $edit, 'Save'); $this->assertFieldByName('name', '#value changed by #element_validate', 'Form element #value was altered.'); $this->assertText('Name value: value changed by setValueForElement() in #element_validate', 'Form element value in $form_state was altered.'); // Verify that #validate handlers can alter the form and submitted // form values. - $edit = array( + $edit = [ 'name' => 'validate', - ); + ]; $this->drupalPostForm(NULL, $edit, 'Save'); $this->assertFieldByName('name', '#value changed by #validate', 'Form element #value was altered.'); $this->assertText('Name value: value changed by setValueForElement() in #validate', 'Form element value in $form_state was altered.'); // Verify that #element_validate handlers can make form elements // inaccessible, but values persist. - $edit = array( + $edit = [ 'name' => 'element_validate_access', - ); + ]; $this->drupalPostForm(NULL, $edit, 'Save'); $this->assertNoFieldByName('name', 'Form element was hidden.'); $this->assertText('Name value: element_validate_access', 'Value for inaccessible form element exists.'); // Verify that value for inaccessible form element persists. - $this->drupalPostForm(NULL, array(), 'Save'); + $this->drupalPostForm(NULL, [], 'Save'); $this->assertNoFieldByName('name', 'Form element was hidden.'); $this->assertText('Name value: element_validate_access', 'Value for inaccessible form element exists.'); // Verify that #validate handlers don't run if the CSRF token is invalid. $this->drupalLogin($this->drupalCreateUser()); $this->drupalGet('form-test/validate'); - $edit = array( - 'name' => 'validate', - 'form_token' => 'invalid token' - ); - $this->drupalPostForm(NULL, $edit, 'Save'); + // $this->assertSession()->fieldExists() does not recognize hidden fields, + // which breaks $this->drupalPostForm() if we try to change the value of a + // hidden field such as form_token. + $this->assertSession() + ->elementExists('css', 'input[name="form_token"]') + ->setValue('invalid_token'); + $this->drupalPostForm(NULL, ['name' => 'validate'], 'Save'); $this->assertNoFieldByName('name', '#value changed by #validate', 'Form element #value was not altered.'); $this->assertNoText('Name value: value changed by setValueForElement() in #validate', 'Form element value in $form_state was not altered.'); $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); @@ -72,7 +74,7 @@ function testValidate() { /** * Tests that a form with a disabled CSRF token can be validated. */ - function testDisabledToken() { + public function testDisabledToken() { $this->drupalPostForm('form-test/validate-no-token', [], 'Save'); $this->assertText('The form_test_validate_no_token form has been submitted successfully.'); } @@ -80,12 +82,12 @@ function testDisabledToken() { /** * Tests partial form validation through #limit_validation_errors. */ - function testValidateLimitErrors() { - $edit = array( + public function testValidateLimitErrors() { + $edit = [ 'test' => 'invalid', 'test_numeric_index[0]' => 'invalid', 'test_substring[foo]' => 'invalid', - ); + ]; $path = 'form-test/limit-validation-errors'; // Render the form, and verify that the buttons with limited server-side @@ -93,18 +95,18 @@ function testValidateLimitErrors() { // client-side validation by the browser). $this->drupalGet($path); $expected = 'formnovalidate'; - foreach (array('partial', 'partial-numeric-index', 'substring') as $type) { - $element = $this->xpath('//input[@id=:id and @formnovalidate=:expected]', array( + foreach (['partial', 'partial-numeric-index', 'substring'] as $type) { + $element = $this->xpath('//input[@id=:id and @formnovalidate=:expected]', [ ':id' => 'edit-' . $type, ':expected' => $expected, - )); - $this->assertTrue(!empty($element), format_string('The @type button has the proper formnovalidate attribute.', array('@type' => $type))); + ]); + $this->assertTrue(!empty($element), format_string('The @type button has the proper formnovalidate attribute.', ['@type' => $type])); } // The button with full server-side validation should not have the // 'formnovalidate' attribute. - $element = $this->xpath('//input[@id=:id and not(@formnovalidate)]', array( + $element = $this->xpath('//input[@id=:id and not(@formnovalidate)]', [ ':id' => 'edit-full', - )); + ]); $this->assertTrue(!empty($element), 'The button with full server-side validation does not have the formnovalidate attribute.'); // Submit the form by pressing the 'Partial validate' button (uses @@ -112,75 +114,75 @@ function testValidateLimitErrors() { // validated, but the #element_validate handler for the 'test' field // is triggered. $this->drupalPostForm($path, $edit, t('Partial validate')); - $this->assertNoText(t('@name field is required.', array('@name' => 'Title'))); + $this->assertNoText(t('@name field is required.', ['@name' => 'Title'])); $this->assertText('Test element is invalid'); // Edge case of #limit_validation_errors containing numeric indexes: same // thing with the 'Partial validate (numeric index)' button and the // 'test_numeric_index' field. $this->drupalPostForm($path, $edit, t('Partial validate (numeric index)')); - $this->assertNoText(t('@name field is required.', array('@name' => 'Title'))); + $this->assertNoText(t('@name field is required.', ['@name' => 'Title'])); $this->assertText('Test (numeric index) element is invalid'); // Ensure something like 'foobar' isn't considered "inside" 'foo'. $this->drupalPostForm($path, $edit, t('Partial validate (substring)')); - $this->assertNoText(t('@name field is required.', array('@name' => 'Title'))); + $this->assertNoText(t('@name field is required.', ['@name' => 'Title'])); $this->assertText('Test (substring) foo element is invalid'); // Ensure not validated values are not available to submit handlers. - $this->drupalPostForm($path, array('title' => '', 'test' => 'valid'), t('Partial validate')); + $this->drupalPostForm($path, ['title' => '', 'test' => 'valid'], t('Partial validate')); $this->assertText('Only validated values appear in the form values.'); // Now test full form validation and ensure that the #element_validate // handler is still triggered. $this->drupalPostForm($path, $edit, t('Full validate')); - $this->assertText(t('@name field is required.', array('@name' => 'Title'))); + $this->assertText(t('@name field is required.', ['@name' => 'Title'])); $this->assertText('Test element is invalid'); } /** * Tests #pattern validation. */ - function testPatternValidation() { - $textfield_error = t('%name field is not in the right format.', array('%name' => 'One digit followed by lowercase letters')); - $tel_error = t('%name field is not in the right format.', array('%name' => 'Everything except numbers')); - $password_error = t('%name field is not in the right format.', array('%name' => 'Password')); + public function testPatternValidation() { + $textfield_error = t('%name field is not in the right format.', ['%name' => 'One digit followed by lowercase letters']); + $tel_error = t('%name field is not in the right format.', ['%name' => 'Everything except numbers']); + $password_error = t('%name field is not in the right format.', ['%name' => 'Password']); // Invalid textfield, valid tel. - $edit = array( + $edit = [ 'textfield' => 'invalid', 'tel' => 'valid', - ); + ]; $this->drupalPostForm('form-test/pattern', $edit, 'Submit'); $this->assertRaw($textfield_error); $this->assertNoRaw($tel_error); $this->assertNoRaw($password_error); // Valid textfield, invalid tel, valid password. - $edit = array( + $edit = [ 'textfield' => '7seven', 'tel' => '818937', 'password' => '0100110', - ); + ]; $this->drupalPostForm('form-test/pattern', $edit, 'Submit'); $this->assertNoRaw($textfield_error); $this->assertRaw($tel_error); $this->assertNoRaw($password_error); // Non required fields are not validated if empty. - $edit = array( + $edit = [ 'textfield' => '', 'tel' => '', - ); + ]; $this->drupalPostForm('form-test/pattern', $edit, 'Submit'); $this->assertNoRaw($textfield_error); $this->assertNoRaw($tel_error); $this->assertNoRaw($password_error); // Invalid password. - $edit = array( + $edit = [ 'password' => $this->randomMachineName(), - ); + ]; $this->drupalPostForm('form-test/pattern', $edit, 'Submit'); $this->assertNoRaw($textfield_error); $this->assertNoRaw($tel_error); @@ -188,13 +190,13 @@ function testPatternValidation() { // The pattern attribute overrides #pattern and is not validated on the // server side. - $edit = array( + $edit = [ 'textfield' => '', 'tel' => '', 'url' => 'http://www.example.com/', - ); + ]; $this->drupalPostForm('form-test/pattern', $edit, 'Submit'); - $this->assertNoRaw(t('%name field is not in the right format.', array('%name' => 'Client side validation'))); + $this->assertNoRaw(t('%name field is not in the right format.', ['%name' => 'Client side validation'])); } /** @@ -202,40 +204,40 @@ function testPatternValidation() { * * @see \Drupal\form_test\Form\FormTestValidateRequiredForm */ - function testCustomRequiredError() { + public function testCustomRequiredError() { $form = \Drupal::formBuilder()->getForm('\Drupal\form_test\Form\FormTestValidateRequiredForm'); // Verify that a custom #required error can be set. - $edit = array(); + $edit = []; $this->drupalPostForm('form-test/validate-required', $edit, 'Submit'); foreach (Element::children($form) as $key) { if (isset($form[$key]['#required_error'])) { - $this->assertNoText(t('@name field is required.', array('@name' => $form[$key]['#title']))); + $this->assertNoText(t('@name field is required.', ['@name' => $form[$key]['#title']])); $this->assertText($form[$key]['#required_error']); } elseif (isset($form[$key]['#form_test_required_error'])) { - $this->assertNoText(t('@name field is required.', array('@name' => $form[$key]['#title']))); + $this->assertNoText(t('@name field is required.', ['@name' => $form[$key]['#title']])); $this->assertText($form[$key]['#form_test_required_error']); } } $this->assertNoText(t('An illegal choice has been detected. Please contact the site administrator.')); // Verify that no custom validation error appears with valid values. - $edit = array( + $edit = [ 'textfield' => $this->randomString(), 'checkboxes[foo]' => TRUE, 'select' => 'foo', - ); + ]; $this->drupalPostForm('form-test/validate-required', $edit, 'Submit'); foreach (Element::children($form) as $key) { if (isset($form[$key]['#required_error'])) { - $this->assertNoText(t('@name field is required.', array('@name' => $form[$key]['#title']))); + $this->assertNoText(t('@name field is required.', ['@name' => $form[$key]['#title']])); $this->assertNoText($form[$key]['#required_error']); } elseif (isset($form[$key]['#form_test_required_error'])) { - $this->assertNoText(t('@name field is required.', array('@name' => $form[$key]['#title']))); + $this->assertNoText(t('@name field is required.', ['@name' => $form[$key]['#title']])); $this->assertNoText($form[$key]['#form_test_required_error']); } } diff --git a/core/modules/system/src/Tests/Lock/LockFunctionalTest.php b/core/modules/system/tests/src/Functional/Lock/LockFunctionalTest.php similarity index 95% rename from core/modules/system/src/Tests/Lock/LockFunctionalTest.php rename to core/modules/system/tests/src/Functional/Lock/LockFunctionalTest.php index 0355a761..0b13f18d 100644 --- a/core/modules/system/src/Tests/Lock/LockFunctionalTest.php +++ b/core/modules/system/tests/src/Functional/Lock/LockFunctionalTest.php @@ -1,22 +1,22 @@ Drupal.org' => "Drupal.org [1]\n\n[1] https://www.drupal.org\n", // @todo Footer URLs should be absolute. @@ -151,7 +151,7 @@ public function testTags() { // A couple of tests for Unicode characters. 'I will be back…' => "I /will/ be back…\n", 'FrançAIS is ÜBER-åwesome' => "FrançAIS is ÜBER-åwesome\n", - ); + ]; foreach ($tests as $html => $text) { $this->assertHtmlToText($html, $text, 'Supported tags'); @@ -168,27 +168,27 @@ public function testDrupalHtmlToTextArgs() { 'Drupal Drupal Drupal', "Drupal *Drupal* Drupal\n", 'Allowed tag found', - array('b') + ['b'] ); $this->assertHtmlToText( 'Drupal

    Drupal

    Drupal', "Drupal Drupal Drupal\n", 'Disallowed

    tag not found', - array('b') + ['b'] ); $this->assertHtmlToText( 'Drupal

    Drupal

    Drupal', "Drupal Drupal Drupal\n", 'Disallowed

    , , and tags not found', - array('a', 'br', 'h1') + ['a', 'br', 'h1'] ); $this->assertHtmlToText( 'Drupal', "Drupal\n", 'Unsupported and tags not found', - array('html', 'body') + ['html', 'body'] ); } @@ -203,7 +203,7 @@ public function testDrupalHtmltoTextCollapsesWhitespace() { $input, $collapsed, 'Whitespace is collapsed', - array('p') + ['p'] ); } @@ -312,17 +312,17 @@ public function testFootnoteReferences() { * and spaces are properly handled. */ public function testDrupalHtmlToTextParagraphs() { - $tests = array(); - $tests[] = array( + $tests = []; + $tests[] = [ 'html' => "

    line 1
    \nline 2
    line 3\n
    line 4

    paragraph

    ", // @todo Trailing line breaks should be trimmed. 'text' => "line 1\nline 2\nline 3\nline 4\n\nparagraph\n\n", - ); - $tests[] = array( + ]; + $tests[] = [ 'html' => "

    line 1
    line 2

    line 4
    line 5

    0

    ", // @todo Trailing line breaks should be trimmed. 'text' => "line 1\nline 2\n\nline 4\nline 5\n\n0\n\n", - ); + ]; foreach ($tests as $test) { $this->assertHtmlToText($test['html'], $test['text'], 'Paragraph breaks'); } diff --git a/core/modules/system/src/Tests/Mail/MailTest.php b/core/modules/system/tests/src/Functional/Mail/MailTest.php similarity index 88% rename from core/modules/system/src/Tests/Mail/MailTest.php rename to core/modules/system/tests/src/Functional/Mail/MailTest.php index 70f5a4b4..74549a32 100644 --- a/core/modules/system/src/Tests/Mail/MailTest.php +++ b/core/modules/system/tests/src/Functional/Mail/MailTest.php @@ -1,9 +1,9 @@ config('system.mail')->set('interface.default', 'test_php_mail_failure')->save(); // Get the default MailInterface class instance. - $mail_backend = \Drupal::service('plugin.manager.mail')->getInstance(array('module' => 'default', 'key' => 'default')); + $mail_backend = \Drupal::service('plugin.manager.mail')->getInstance(['module' => 'default', 'key' => 'default']); // Assert whether the default mail backend is an instance of the expected // class. @@ -38,7 +38,7 @@ public function testPluggableFramework() { $this->config('system.mail')->set('interface.mymodule_testkey', 'test_mail_collector')->save(); // Get the added MailInterface class instance. - $mail_backend = \Drupal::service('plugin.manager.mail')->getInstance(array('module' => 'mymodule', 'key' => 'testkey')); + $mail_backend = \Drupal::service('plugin.manager.mail')->getInstance(['module' => 'mymodule', 'key' => 'testkey']); // Assert whether the added mail backend is an instance of the expected // class. @@ -56,7 +56,7 @@ public function testCancelMessage() { // Use the state system collector mail backend. $this->config('system.mail')->set('interface.default', 'test_mail_collector')->save(); // Reset the state variable that holds sent messages. - \Drupal::state()->set('system.test_mail_collector', array()); + \Drupal::state()->set('system.test_mail_collector', []); // Send a test message that simpletest_mail_alter should cancel. \Drupal::service('plugin.manager.mail')->mail('simpletest', 'cancel_test', 'cancel@example.com', $language_interface->getId()); @@ -77,11 +77,11 @@ public function testFromAndReplyToHeader() { // Use the state system collector mail backend. $this->config('system.mail')->set('interface.default', 'test_mail_collector')->save(); // Reset the state variable that holds sent messages. - \Drupal::state()->set('system.test_mail_collector', array()); + \Drupal::state()->set('system.test_mail_collector', []); // Send an email with a reply-to address specified. $from_email = 'Drupal '; $reply_email = 'someone_else@example.com'; - \Drupal::service('plugin.manager.mail')->mail('simpletest', 'from_test', 'from_test@example.com', $language, array(), $reply_email); + \Drupal::service('plugin.manager.mail')->mail('simpletest', 'from_test', 'from_test@example.com', $language, [], $reply_email); // Test that the reply-to email is just the email and not the site name // and default sender email. $captured_emails = \Drupal::state()->get('system.test_mail_collector'); diff --git a/core/modules/system/tests/src/Functional/Menu/AssertBreadcrumbTrait.php b/core/modules/system/tests/src/Functional/Menu/AssertBreadcrumbTrait.php new file mode 100644 index 00000000..fd0dc7cf --- /dev/null +++ b/core/modules/system/tests/src/Functional/Menu/AssertBreadcrumbTrait.php @@ -0,0 +1,111 @@ +drupalGet($goto); + } + $this->assertBreadcrumbParts($trail); + + // Additionally assert page title, if given. + if (isset($page_title)) { + $this->assertTitle(strtr('@title | Drupal', ['@title' => $page_title])); + } + + // Additionally assert active trail in a menu tree output, if given. + if ($tree) { + $this->assertMenuActiveTrail($tree, $last_active); + } + } + + /** + * Assert that a trail exists in the internal browser. + * + * @param array $trail + * An associative array whose keys are expected breadcrumb link paths and + * whose values are expected breadcrumb link texts (not sanitized). + */ + protected function assertBreadcrumbParts($trail) { + // Compare paths with actual breadcrumb. + $parts = $this->getBreadcrumbParts(); + $pass = TRUE; + // There may be more than one breadcrumb on the page. If $trail is empty + // this test would go into an infinite loop, so we need to check that too. + while ($trail && !empty($parts)) { + foreach ($trail as $path => $title) { + // If the path is empty, generate the path from the route. If + // the path does not start with a leading slash, then run it through + // Url::fromUri('base:')->toString() to get the correct base + // prepended. + if ($path == '') { + $url = Url::fromRoute('')->toString(); + } + elseif ($path[0] != '/') { + $url = Url::fromUri('base:' . $path)->toString(); + } + else { + $url = $path; + } + $part = array_shift($parts); + $pass = ($pass && $part['href'] === $url && $part['text'] === Html::escape($title)); + } + } + // No parts must be left, or an expected "Home" will always pass. + $pass = ($pass && empty($parts)); + + $this->assertTrue($pass, format_string('Breadcrumb %parts found on @path.', [ + '%parts' => implode(' » ', $trail), + '@path' => $this->getUrl(), + ])); + } + + /** + * Returns the breadcrumb contents of the current page in the internal browser. + */ + protected function getBreadcrumbParts() { + $parts = []; + $elements = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a'); + if (!empty($elements)) { + foreach ($elements as $element) { + $parts[] = [ + 'text' => $element->getText(), + 'href' => $element->getAttribute('href'), + 'title' => $element->getAttribute('title'), + ]; + } + } + return $parts; + } + +} diff --git a/core/modules/system/tests/src/Functional/Menu/AssertMenuActiveTrailTrait.php b/core/modules/system/tests/src/Functional/Menu/AssertMenuActiveTrailTrait.php new file mode 100644 index 00000000..c5d60e54 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Menu/AssertMenuActiveTrailTrait.php @@ -0,0 +1,65 @@ + $link_title) { + $part_xpath = (!$i ? '//' : '/following-sibling::ul/descendant::'); + $part_xpath .= 'li[contains(@class, :class)]/a[contains(@href, :href) and contains(text(), :title)]'; + $part_args = [ + ':class' => 'menu-item--active-trail', + ':href' => Url::fromUri('base:' . $link_path)->toString(), + ':title' => $link_title, + ]; + $xpath .= $this->buildXPathQuery($part_xpath, $part_args); + $i++; + } + $elements = $this->xpath($xpath); + $this->assertTrue(!empty($elements), 'Active trail to current page was found in menu tree.'); + + // Append prefix for active link asserted below. + $xpath .= '/following-sibling::ul/descendant::'; + } + else { + $xpath .= '//'; + } + $xpath_last_active = ($last_active ? 'and contains(@class, :class-active)' : ''); + $xpath .= 'li[contains(@class, :class-trail)]/a[contains(@href, :href) ' . $xpath_last_active . 'and contains(text(), :title)]'; + $args = [ + ':class-trail' => 'menu-item--active-trail', + ':class-active' => 'is-active', + ':href' => Url::fromUri('base:' . $active_link_path)->toString(), + ':title' => $active_link_title, + ]; + $elements = $this->xpath($xpath, $args); + $this->assertTrue(!empty($elements), format_string('Active link %title was found in menu tree, including active trail links %tree.', [ + '%title' => $active_link_title, + '%tree' => implode(' » ', $tree), + ])); + } + +} diff --git a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php b/core/modules/system/tests/src/Functional/Menu/BreadcrumbTest.php similarity index 85% rename from core/modules/system/src/Tests/Menu/BreadcrumbTest.php rename to core/modules/system/tests/src/Functional/Menu/BreadcrumbTest.php index f756300e..e9142dc8 100644 --- a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php +++ b/core/modules/system/tests/src/Functional/Menu/BreadcrumbTest.php @@ -1,9 +1,10 @@ drupalPlaceBlock('system_menu_block:tools', array( + $this->drupalPlaceBlock('system_menu_block:tools', [ 'region' => 'content', 'theme' => $this->config('system.theme')->get('admin'), - )); + ]); } /** * Tests breadcrumbs on node and administrative paths. */ - function testBreadCrumbs() { + public function testBreadCrumbs() { // Prepare common base breadcrumb elements. - $home = array('' => 'Home'); - $admin = $home + array('admin' => t('Administration')); - $config = $admin + array('admin/config' => t('Configuration')); + $home = ['' => 'Home']; + $admin = $home + ['admin' => t('Administration')]; + $config = $admin + ['admin/config' => t('Configuration')]; $type = 'article'; // Verify Taxonomy administration breadcrumbs. - $trail = $admin + array( + $trail = $admin + [ 'admin/structure' => t('Structure'), - ); + ]; $this->assertBreadcrumb('admin/structure/taxonomy', $trail); - $trail += array( + $trail += [ 'admin/structure/taxonomy' => t('Taxonomy'), - ); + ]; $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags', $trail); - $trail += array( + $trail += [ 'admin/structure/taxonomy/manage/tags' => t('Tags'), - ); + ]; $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/overview', $trail); $this->assertBreadcrumb('admin/structure/taxonomy/manage/tags/add', $trail); // Verify Menu administration breadcrumbs. - $trail = $admin + array( + $trail = $admin + [ 'admin/structure' => t('Structure'), - ); + ]; $this->assertBreadcrumb('admin/structure/menu', $trail); - $trail += array( + $trail += [ 'admin/structure/menu' => t('Menus'), - ); + ]; $this->assertBreadcrumb('admin/structure/menu/manage/tools', $trail); - $trail += array( + $trail += [ 'admin/structure/menu/manage/tools' => t('Tools'), - ); + ]; $this->assertBreadcrumb("admin/structure/menu/link/node.add_page/edit", $trail); $this->assertBreadcrumb('admin/structure/menu/manage/tools/add', $trail); // Verify Node administration breadcrumbs. - $trail = $admin + array( + $trail = $admin + [ 'admin/structure' => t('Structure'), 'admin/structure/types' => t('Content types'), - ); + ]; $this->assertBreadcrumb('admin/structure/types/add', $trail); $this->assertBreadcrumb("admin/structure/types/manage/$type", $trail); - $trail += array( + $trail += [ "admin/structure/types/manage/$type" => t('Article'), - ); + ]; $this->assertBreadcrumb("admin/structure/types/manage/$type/fields", $trail); $this->assertBreadcrumb("admin/structure/types/manage/$type/display", $trail); - $trail_teaser = $trail + array( + $trail_teaser = $trail + [ "admin/structure/types/manage/$type/display" => t('Manage display'), - ); + ]; $this->assertBreadcrumb("admin/structure/types/manage/$type/display/teaser", $trail_teaser); $this->assertBreadcrumb("admin/structure/types/manage/$type/delete", $trail); - $trail += array( + $trail += [ "admin/structure/types/manage/$type/fields" => t('Manage fields'), - ); + ]; $this->assertBreadcrumb("admin/structure/types/manage/$type/fields/node.$type.body", $trail); // Verify Filter text format administration breadcrumbs. $filter_formats = filter_formats(); $format = reset($filter_formats); $format_id = $format->id(); - $trail = $config + array( + $trail = $config + [ 'admin/config/content' => t('Content authoring'), - ); + ]; $this->assertBreadcrumb('admin/config/content/formats', $trail); - $trail += array( + $trail += [ 'admin/config/content/formats' => t('Text formats and editors'), - ); + ]; $this->assertBreadcrumb('admin/config/content/formats/add', $trail); $this->assertBreadcrumb("admin/config/content/formats/manage/$format_id", $trail); // @todo Remove this part once we have a _title_callback, see // https://www.drupal.org/node/2076085. - $trail += array( + $trail += [ "admin/config/content/formats/manage/$format_id" => $format->label(), - ); + ]; $this->assertBreadcrumb("admin/config/content/formats/manage/$format_id/disable", $trail); // Verify node breadcrumbs (without menu link). @@ -151,13 +154,13 @@ function testBreadCrumbs() { // Also verify that the node does not appear elsewhere (e.g., menu trees). $this->assertNoLink($node1->getTitle()); - $trail += array( + $trail += [ "node/$nid1" => $node1->getTitle(), - ); + ]; $this->assertBreadcrumb("node/$nid1/edit", $trail); // Verify that breadcrumb on node listing page contains "Home" only. - $trail = array(); + $trail = []; $this->assertBreadcrumb('node', $trail); // Verify node breadcrumbs (in menu). @@ -165,7 +168,7 @@ function testBreadCrumbs() { // latter is a preferred menu by default. // @todo Also test all themes? Manually testing led to the suspicion that // breadcrumbs may differ, possibly due to theme overrides. - $menus = array('main', 'tools'); + $menus = ['main', 'tools']; // Alter node type menu settings. $node_type = NodeType::load($type); $node_type->setThirdPartySetting('menu_ui', 'available_menus', $menus); @@ -175,17 +178,17 @@ function testBreadCrumbs() { foreach ($menus as $menu) { // Create a parent node in the current menu. $title = $this->randomMachineName(); - $node2 = $this->drupalCreateNode(array( + $node2 = $this->drupalCreateNode([ 'type' => $type, 'title' => $title, - 'menu' => array( + 'menu' => [ 'enabled' => 1, 'title' => 'Parent ' . $title, 'description' => '', 'menu_name' => $menu, 'parent' => '', - ), - )); + ], + ]); if ($menu == 'tools') { $parent = $node2; @@ -195,52 +198,52 @@ function testBreadCrumbs() { // Create a Tools menu link for 'node', move the last parent node menu // link below it, and verify a full breadcrumb for the last child node. $menu = 'tools'; - $edit = array( + $edit = [ 'title[0][value]' => 'Root', 'link[0][uri]' => '/node', - ); + ]; $this->drupalPostForm("admin/structure/menu/manage/$menu/add", $edit, t('Save')); - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => 'Root')); + $menu_links = entity_load_multiple_by_properties('menu_link_content', ['title' => 'Root']); $link = reset($menu_links); - $edit = array( + $edit = [ 'menu[menu_parent]' => $link->getMenuName() . ':' . $link->getPluginId(), - ); - $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published')); - $expected = array( + ]; + $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save')); + $expected = [ "node" => $link->getTitle(), - ); + ]; $trail = $home + $expected; - $tree = $expected + array( + $tree = $expected + [ 'node/' . $parent->id() => $parent->menu['title'], - ); - $trail += array( + ]; + $trail += [ 'node/' . $parent->id() => $parent->menu['title'], - ); + ]; // Add a taxonomy term/tag to last node, and add a link for that term to the // Tools menu. - $tags = array( - 'Drupal' => array(), - 'Breadcrumbs' => array(), - ); - $edit = array( + $tags = [ + 'Drupal' => [], + 'Breadcrumbs' => [], + ]; + $edit = [ 'field_tags[target_id]' => implode(',', array_keys($tags)), - ); - $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published')); + ]; + $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save')); // Put both terms into a hierarchy Drupal » Breadcrumbs. Required for both // the menu links and the terms itself, since taxonomy_term_page() resets // the breadcrumb based on taxonomy term hierarchy. $parent_tid = 0; foreach ($tags as $name => $null) { - $terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => $name)); + $terms = entity_load_multiple_by_properties('taxonomy_term', ['name' => $name]); $term = reset($terms); $tags[$name]['term'] = $term; if ($parent_tid) { - $edit = array( - 'parent[]' => array($parent_tid), - ); + $edit = [ + 'parent[]' => [$parent_tid], + ]; $this->drupalPostForm("taxonomy/term/{$term->id()}/edit", $edit, t('Save')); } $parent_tid = $term->id(); @@ -248,24 +251,24 @@ function testBreadCrumbs() { $parent_mlid = ''; foreach ($tags as $name => $data) { $term = $data['term']; - $edit = array( + $edit = [ 'title[0][value]' => "$name link", 'link[0][uri]' => "/taxonomy/term/{$term->id()}", 'menu_parent' => "$menu:{$parent_mlid}", 'enabled[value]' => 1, - ); + ]; $this->drupalPostForm("admin/structure/menu/manage/$menu/add", $edit, t('Save')); - $menu_links = entity_load_multiple_by_properties('menu_link_content', array( + $menu_links = entity_load_multiple_by_properties('menu_link_content', [ 'title' => $edit['title[0][value]'], 'link.uri' => 'internal:/taxonomy/term/' . $term->id(), - )); + ]); $tags[$name]['link'] = reset($menu_links); $parent_mlid = $tags[$name]['link']->getPluginId(); } // Verify expected breadcrumbs for menu links. $trail = $home; - $tree = array(); + $tree = []; // Logout the user because we want to check the active class as well, which // is just rendered as anonymous user. $this->drupalLogout(); @@ -275,9 +278,9 @@ function testBreadCrumbs() { $link = $data['link']; $link_path = $link->getUrlObject()->getInternalPath(); - $tree += array( + $tree += [ $link_path => $link->getTitle(), - ); + ]; $this->assertBreadcrumb($link_path, $trail, $term->getName(), $tree); $this->assertEscaped($parent->getTitle(), 'Tagged node found.'); @@ -285,28 +288,28 @@ function testBreadCrumbs() { // untranslated menu links automatically generated from menu router items // ('taxonomy/term/%') should never be translated and appear in any menu // other than the breadcrumb trail. - $elements = $this->xpath('//nav[@id=:menu]/descendant::a[@href=:href]', array( + $elements = $this->xpath('//nav[@id=:menu]/descendant::a[@href=:href]', [ ':menu' => 'block-bartik-tools', ':href' => Url::fromUri('base:' . $link_path)->toString(), - )); + ]); $this->assertTrue(count($elements) == 1, "Link to {$link_path} appears only once."); // Next iteration should expect this tag as parent link. // Note: Term name, not link name, due to taxonomy_term_page(). - $trail += array( + $trail += [ $link_path => $term->getName(), - ); + ]; } // Verify breadcrumbs on user and user/%. // We need to log back in and out below, and cannot simply grant the // 'administer users' permission, since user_page() makes your head explode. - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array( + user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, [ 'access user profiles', - )); + ]); // Verify breadcrumb on front page. - $this->assertBreadcrumb('', array()); + $this->assertBreadcrumb('', []); // Verify breadcrumb on user pages (without menu link) for anonymous user. $trail = $home; @@ -318,39 +321,39 @@ function testBreadCrumbs() { $trail = $home; $this->assertBreadcrumb('user', $trail, $this->adminUser->getUsername()); $this->assertBreadcrumb('user/' . $this->adminUser->id(), $trail, $this->adminUser->getUsername()); - $trail += array( + $trail += [ 'user/' . $this->adminUser->id() => $this->adminUser->getUsername(), - ); + ]; $this->assertBreadcrumb('user/' . $this->adminUser->id() . '/edit', $trail, $this->adminUser->getUsername()); // Create a second user to verify breadcrumb on user pages again. - $this->webUser = $this->drupalCreateUser(array( + $this->webUser = $this->drupalCreateUser([ 'administer users', 'access user profiles', - )); + ]); $this->drupalLogin($this->webUser); // Verify correct breadcrumb and page title on another user's account pages. $trail = $home; $this->assertBreadcrumb('user/' . $this->adminUser->id(), $trail, $this->adminUser->getUsername()); - $trail += array( + $trail += [ 'user/' . $this->adminUser->id() => $this->adminUser->getUsername(), - ); + ]; $this->assertBreadcrumb('user/' . $this->adminUser->id() . '/edit', $trail, $this->adminUser->getUsername()); // Verify correct breadcrumb and page title when viewing own user account. $trail = $home; $this->assertBreadcrumb('user/' . $this->webUser->id(), $trail, $this->webUser->getUsername()); - $trail += array( + $trail += [ 'user/' . $this->webUser->id() => $this->webUser->getUsername(), - ); + ]; $this->assertBreadcrumb('user/' . $this->webUser->id() . '/edit', $trail, $this->webUser->getUsername()); // Create an only slightly privileged user being able to access site reports // but not administration pages. - $this->webUser = $this->drupalCreateUser(array( + $this->webUser = $this->drupalCreateUser([ 'access site reports', - )); + ]); $this->drupalLogin($this->webUser); // Verify that we can access recent log entries, there is a corresponding @@ -358,17 +361,17 @@ function testBreadCrumbs() { // user is not able to access "Administer". $trail = $home; $this->assertBreadcrumb('admin', $trail, t('Access denied')); - $this->assertResponse(403); + $this->assertSession()->statusCodeEquals(403); // Since the 'admin' path is not accessible, we still expect only the Home // link. $this->assertBreadcrumb('admin/reports', $trail, t('Reports')); - $this->assertNoResponse(403); + $this->assertSession()->statusCodeNotEquals(403); // Since the Reports page is accessible, that will show. - $trail += array('admin/reports' => t('Reports')); + $trail += ['admin/reports' => t('Reports')]; $this->assertBreadcrumb('admin/reports/dblog', $trail, t('Recent log messages')); - $this->assertNoResponse(403); + $this->assertSession()->statusCodeNotEquals(403); // Ensure that the breadcrumb is safe against XSS. $this->drupalGet('menu-test/breadcrumb1/breadcrumb2/breadcrumb3'); diff --git a/core/modules/system/src/Tests/Menu/LocalActionTest.php b/core/modules/system/tests/src/Functional/Menu/LocalActionTest.php similarity index 90% rename from core/modules/system/src/Tests/Menu/LocalActionTest.php rename to core/modules/system/tests/src/Functional/Menu/LocalActionTest.php index 40dc744f..f7b9aafa 100644 --- a/core/modules/system/src/Tests/Menu/LocalActionTest.php +++ b/core/modules/system/tests/src/Functional/Menu/LocalActionTest.php @@ -1,17 +1,17 @@ xpath('//a[contains(@class, :class)]', array( + $elements = $this->xpath('//a[contains(@class, :class)]', [ ':class' => 'button-action', - )); + ]); $index = 0; foreach ($actions as $action) { /** @var \Drupal\Core\Url $url */ @@ -80,7 +80,7 @@ protected function assertLocalAction(array $actions) { // This behaviour is a bug in libxml, see // https://bugs.php.net/bug.php?id=49437. $this->assertPattern('@]*class="[^"]*button-action[^"]*"[^>]*>' . preg_quote($title, '@') . 'assertEqual($elements[$index]['href'], $url->toString()); + $this->assertEqual($elements[$index]->getAttribute('href'), $url->toString()); $index++; } } diff --git a/core/modules/system/src/Tests/Menu/LocalTasksTest.php b/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php similarity index 88% rename from core/modules/system/src/Tests/Menu/LocalTasksTest.php rename to core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php index 522e12b2..12a157d5 100644 --- a/core/modules/system/src/Tests/Menu/LocalTasksTest.php +++ b/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php @@ -1,17 +1,17 @@ xpath('//*[contains(@class, :class)]//a', array( + $elements = $this->xpath('//*[contains(@class, :class)]//a', [ ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary', - )); + ]); $this->assertTrue(count($elements), 'Local tasks found.'); foreach ($routes as $index => $route_info) { list($route_name, $route_parameters) = $route_info; $expected = Url::fromRoute($route_name, $route_parameters)->toString(); - $method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail'); - $this->{$method}(format_string('Task @number href @value equals @expected.', array( + $method = ($elements[$index]->getAttribute('href') == $expected ? 'pass' : 'fail'); + $this->{$method}(format_string('Task @number href @value equals @expected.', [ '@number' => $index + 1, - '@value' => (string) $elements[$index]['href'], + '@value' => $elements[$index]->getAttribute('href'), '@expected' => $expected, - ))); + ])); } } @@ -89,9 +89,9 @@ protected function assertLocalTaskAppers($title) { * secondary. Defaults to 0. */ protected function assertNoLocalTasks($level = 0) { - $elements = $this->xpath('//*[contains(@class, :class)]//a', array( + $elements = $this->xpath('//*[contains(@class, :class)]//a', [ ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary', - )); + ]); $this->assertFalse(count($elements), 'Local tasks not found.'); } @@ -129,7 +129,7 @@ public function testPluginLocalTask() { // Ensure the view tab is active. $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]/a'); $this->assertEqual(1, count($result), 'There is just a single active tab.'); - $this->assertEqual('View', (string) $result[0], 'The view tab is active.'); + $this->assertEqual('View(active tab)', $result[0]->getText(), 'The view tab is active.'); // Verify that local tasks in the second level appear. $sub_tasks = [ @@ -144,15 +144,15 @@ public function testPluginLocalTask() { $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]/a'); $this->assertEqual(1, count($result), 'There is just a single active tab.'); - $this->assertEqual('Settings', (string) $result[0], 'The settings tab is active.'); + $this->assertEqual('Settings(active tab)', $result[0]->getText(), 'The settings tab is active.'); $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_settings_sub1')); $this->assertLocalTasks($sub_tasks, 1); $result = $this->xpath('//ul[contains(@class, "tabs")]//a[contains(@class, "active")]'); $this->assertEqual(2, count($result), 'There are tabs active on both levels.'); - $this->assertEqual('Settings', (string) $result[0], 'The settings tab is active.'); - $this->assertEqual('Dynamic title for TestTasksSettingsSub1', (string) $result[1], 'The sub1 tab is active.'); + $this->assertEqual('Settings(active tab)', $result[0]->getText(), 'The settings tab is active.'); + $this->assertEqual('Dynamic title for TestTasksSettingsSub1(active tab)', $result[1]->getText(), 'The sub1 tab is active.'); $this->assertCacheTag('kittens:ragdoll'); $this->assertCacheTag('kittens:dwarf-cat'); @@ -162,8 +162,8 @@ public function testPluginLocalTask() { $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]'); $this->assertEqual(2, count($result), 'There are tabs active on both levels.'); - $this->assertEqual('Settings', (string) $result[0]->a, 'The settings tab is active.'); - $this->assertEqual('Derive 1', (string) $result[1]->a, 'The derive1 tab is active.'); + $this->assertEqual('Settings(active tab)', $result[0]->getText(), 'The settings tab is active.'); + $this->assertEqual('Derive 1(active tab)', $result[1]->getText(), 'The derive1 tab is active.'); // Ensures that the local tasks contains the proper 'provider key' $definitions = $this->container->get('plugin.manager.menu.local_task')->getDefinitions(); @@ -176,7 +176,7 @@ public function testPluginLocalTask() { // Test that we we correctly apply the active class to tabs where one of the // request attributes is upcast to an entity object. - $entity = \Drupal::entityManager()->getStorage('entity_test')->create(array('bundle' => 'test')); + $entity = \Drupal::entityManager()->getStorage('entity_test')->create(['bundle' => 'test']); $entity->save(); $this->drupalGet(Url::fromRoute('menu_test.local_task_test_upcasting_sub1', ['entity_test' => '1'])); @@ -190,7 +190,7 @@ public function testPluginLocalTask() { $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]'); $this->assertEqual(1, count($result), 'There is one active tab.'); - $this->assertEqual('upcasting sub1', (string) $result[0]->a, 'The "upcasting sub1" tab is active.'); + $this->assertEqual('upcasting sub1(active tab)', $result[0]->getText(), 'The "upcasting sub1" tab is active.'); $this->drupalGet(Url::fromRoute('menu_test.local_task_test_upcasting_sub2', ['entity_test' => '1'])); @@ -202,7 +202,7 @@ public function testPluginLocalTask() { $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]'); $this->assertEqual(1, count($result), 'There is one active tab.'); - $this->assertEqual('upcasting sub2', (string) $result[0]->a, 'The "upcasting sub2" tab is active.'); + $this->assertEqual('upcasting sub2(active tab)', $result[0]->getText(), 'The "upcasting sub2" tab is active.'); } /** diff --git a/core/modules/system/src/Tests/Menu/MenuAccessTest.php b/core/modules/system/tests/src/Functional/Menu/MenuAccessTest.php similarity index 92% rename from core/modules/system/src/Tests/Menu/MenuAccessTest.php rename to core/modules/system/tests/src/Functional/Menu/MenuAccessTest.php index fff17e58..10af396a 100644 --- a/core/modules/system/src/Tests/Menu/MenuAccessTest.php +++ b/core/modules/system/tests/src/Functional/Menu/MenuAccessTest.php @@ -1,16 +1,16 @@ drupalGet('foo/asdf/c'); $this->assertResponse(403); - $elements = $this->xpath('//ul[@class=:class]/li/a[@href=:href]', array( + $elements = $this->xpath('//ul[@class=:class]/li/a[@href=:href]', [ ':class' => 'tabs primary', ':href' => Url::fromRoute('menu_test.router_test1', ['bar' => 'asdf'])->toString(), - )); + ]); $this->assertTrue(empty($elements), 'No tab linking to foo/asdf found'); $this->assertNoLinkByHref('foo/asdf/b'); $this->assertNoLinkByHref('foo/asdf/c'); diff --git a/core/modules/system/src/Tests/Menu/MenuLinkSecurityTest.php b/core/modules/system/tests/src/Functional/Menu/MenuLinkSecurityTest.php similarity index 87% rename from core/modules/system/src/Tests/Menu/MenuLinkSecurityTest.php rename to core/modules/system/tests/src/Functional/Menu/MenuLinkSecurityTest.php index 94bb14af..c58bf8e5 100644 --- a/core/modules/system/src/Tests/Menu/MenuLinkSecurityTest.php +++ b/core/modules/system/tests/src/Functional/Menu/MenuLinkSecurityTest.php @@ -1,16 +1,16 @@ drupalGet('test-page'); $this->assertText('A title with @placeholder', 'Raw text found on the page'); - $this->assertNoText(t('A title with @placeholder', array('@placeholder' => 'some other text')), 'Text with placeholder substitutions not found.'); + $this->assertNoText(t('A title with @placeholder', ['@placeholder' => 'some other text']), 'Text with placeholder substitutions not found.'); } /** @@ -110,7 +110,7 @@ protected function doTestDescriptionMenuItems() { * Tests for menu_name parameter for default menu links. */ protected function doTestMenuName() { - $admin_user = $this->drupalCreateUser(array('administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin_user); /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); @@ -179,7 +179,7 @@ protected function doTestMenuOptionalPlaceholders() { * Tests a menu on a router page. */ protected function doTestMenuOnRoute() { - \Drupal::service('module_installer')->install(array('router_test')); + \Drupal::service('module_installer')->install(['router_test']); \Drupal::service('router.builder')->rebuild(); $this->resetAll(); @@ -194,9 +194,13 @@ protected function doTestMenuOnRoute() { * Test path containing "exotic" characters. */ protected function doTestExoticPath() { - $path = "menu-test/ -._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters. - "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string. - "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets. + // "Special" ASCII characters. + $path = + "menu-test/ -._~!$'\"()*@[]?&+%#,;=:" . + // Characters that look like a percent-escaped string. + "%23%25%26%2B%2F%3F" . + // Characters from various non-ASCII alphabets. + "éøïвβ中國書۞"; $this->drupalGet($path); $this->assertRaw('This is the menuTestCallback content.'); $this->assertNoText(t('The website encountered an unexpected error. Please try again later.')); @@ -210,7 +214,7 @@ protected function doTestExoticPath() { public function testMaintenanceModeLoginPaths() { $this->container->get('state')->set('system.maintenance_mode', TRUE); - $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => $this->config('system.site')->get('name'))); + $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', ['@site' => $this->config('system.site')->get('name')]); $this->drupalGet('test-page'); $this->assertText($offline_message); $this->drupalGet('menu_login_callback'); @@ -224,7 +228,7 @@ public function testMaintenanceModeLoginPaths() { * 'user' and 'user/register' gets redirected to the user edit page. */ public function testAuthUserUserLogin() { - $web_user = $this->drupalCreateUser(array()); + $web_user = $this->drupalCreateUser([]); $this->drupalLogin($web_user); $this->drupalGet('user/login'); @@ -282,7 +286,7 @@ protected function doTestThemeCallbackMaintenanceMode() { $this->assertRaw('bartik/css/base/elements.css', "The maintenance theme's CSS appears on the page."); // An administrator, however, should continue to see the requested theme. - $admin_user = $this->drupalCreateUser(array('access site in maintenance mode')); + $admin_user = $this->drupalCreateUser(['access site in maintenance mode']); $this->drupalLogin($admin_user); $this->drupalGet('menu-test/theme-callback/use-admin-theme'); $this->assertText('Active theme: seven. Actual theme: seven.', 'The theme negotiation system is correctly triggered for an administrator when the site is in maintenance mode.'); @@ -302,13 +306,13 @@ protected function doTestThemeCallbackOptionalTheme() { // Now install the theme and request it again. $theme_handler = $this->container->get('theme_handler'); - $theme_handler->install(array('test_theme')); + $theme_handler->install(['test_theme']); $this->drupalGet('menu-test/theme-callback/use-test-theme'); $this->assertText('Active theme: test_theme. Actual theme: test_theme.', 'The theme negotiation system uses an optional theme once it has been installed.'); $this->assertRaw('test_theme/kitten.css', "The optional theme's CSS appears on the page."); - $theme_handler->uninstall(array('test_theme')); + $theme_handler->uninstall(['test_theme']); } /** diff --git a/core/modules/system/src/Tests/Module/ClassLoaderTest.php b/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php similarity index 75% rename from core/modules/system/src/Tests/Module/ClassLoaderTest.php rename to core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php index bc2dfd5f..779a288a 100644 --- a/core/modules/system/src/Tests/Module/ClassLoaderTest.php +++ b/core/modules/system/tests/src/Functional/Module/ClassLoaderTest.php @@ -1,15 +1,15 @@ install(array('module_test', 'module_autoload_test'), FALSE); + \Drupal::service('module_installer')->install(['module_test', 'module_autoload_test'], FALSE); $this->resetAll(); // Check twice to test an unprimed and primed system_list() cache. for ($i = 0; $i < 2; $i++) { @@ -38,9 +38,9 @@ function testClassLoading() { * * @see \Drupal\module_autoload_test\SomeClass */ - function testClassLoadingNotInstalledModules() { + public function testClassLoadingNotInstalledModules() { // Enable the module_test module. - \Drupal::service('module_installer')->install(array('module_test'), FALSE); + \Drupal::service('module_installer')->install(['module_test'], FALSE); $this->resetAll(); // Check twice to test an unprimed and primed system_list() cache. for ($i = 0; $i < 2; $i++) { @@ -55,12 +55,12 @@ function testClassLoadingNotInstalledModules() { * * @see \Drupal\module_autoload_test\SomeClass */ - function testClassLoadingDisabledModules() { + public function testClassLoadingDisabledModules() { // Enable the module_test and module_autoload_test modules. - \Drupal::service('module_installer')->install(array('module_test', 'module_autoload_test'), FALSE); + \Drupal::service('module_installer')->install(['module_test', 'module_autoload_test'], FALSE); $this->resetAll(); // Ensure that module_autoload_test is disabled. - $this->container->get('module_installer')->uninstall(array('module_autoload_test'), FALSE); + $this->container->get('module_installer')->uninstall(['module_autoload_test'], FALSE); $this->resetAll(); // Check twice to test an unprimed and primed system_list() cache. for ($i = 0; $i < 2; $i++) { @@ -76,8 +76,8 @@ function testClassLoadingDisabledModules() { public function testMultipleModules() { $this->drupalLogin($this->rootUser); $edit = [ - "modules[Testing][module_install_class_loader_test1][enable]" => TRUE, - "modules[Testing][module_install_class_loader_test2][enable]" => TRUE, + "modules[module_install_class_loader_test1][enable]" => TRUE, + "modules[module_install_class_loader_test2][enable]" => TRUE, ]; $this->drupalPostForm('admin/modules', $edit, t('Install')); $this->rebuildContainer(); diff --git a/core/modules/system/src/Tests/Module/ExperimentalModuleTest.php b/core/modules/system/tests/src/Functional/Module/ExperimentalModuleTest.php similarity index 87% rename from core/modules/system/src/Tests/Module/ExperimentalModuleTest.php rename to core/modules/system/tests/src/Functional/Module/ExperimentalModuleTest.php index 7b1a376b..177fc5ba 100644 --- a/core/modules/system/src/Tests/Module/ExperimentalModuleTest.php +++ b/core/modules/system/tests/src/Functional/Module/ExperimentalModuleTest.php @@ -1,15 +1,15 @@ drupalPostForm('admin/modules', $edit, t('Install')); $this->assertText('Module Test page has been enabled.'); $this->assertNoText('Experimental modules are provided for testing purposes only.'); @@ -48,7 +48,7 @@ public function testExperimentalConfirmForm() { // There should be a confirmation form with an experimental warning, but no // list of dependencies. $edit = []; - $edit["modules[Core (Experimental)][experimental_module_test][enable]"] = TRUE; + $edit["modules[experimental_module_test][enable]"] = TRUE; $this->drupalPostForm('admin/modules', $edit, 'Install'); // The module should not be enabled and there should be a warning and a @@ -70,7 +70,7 @@ public function testExperimentalConfirmForm() { // Test enabling a module that is not itself experimental, but that depends // on an experimental module. $edit = []; - $edit["modules[Testing][experimental_module_dependency_test][enable]"] = TRUE; + $edit["modules[experimental_module_dependency_test][enable]"] = TRUE; $this->drupalPostForm('admin/modules', $edit, 'Install'); // The module should not be enabled and there should be a warning and a @@ -98,8 +98,8 @@ public function testExperimentalConfirmForm() { // still a warning about experimental modules, but no message about // dependencies, since the user specifically enabled the dependency. $edit = []; - $edit["modules[Core (Experimental)][experimental_module_test][enable]"] = TRUE; - $edit["modules[Testing][experimental_module_dependency_test][enable]"] = TRUE; + $edit["modules[experimental_module_test][enable]"] = TRUE; + $edit["modules[experimental_module_dependency_test][enable]"] = TRUE; $this->drupalPostForm('admin/modules', $edit, 'Install'); // The module should not be enabled and there should be a warning and a @@ -110,7 +110,7 @@ public function testExperimentalConfirmForm() { $this->assertText('The following modules are experimental: Experimental Test'); // Ensure the non-experimental module is not listed as experimental. - $this->assertNoText('The following modules are experimental: Experimental Test, Experimental Dependency Test'); + $this->assertNoText('The following modules are experimental: Experimental Dependency Test, Experimental Test'); $this->assertNoText('The following modules are experimental: Experimental Dependency Test'); // There should be no message about enabling dependencies. @@ -118,13 +118,13 @@ public function testExperimentalConfirmForm() { // Enable the module and confirm that it worked. $this->drupalPostForm(NULL, [], 'Continue'); - $this->assertText('2 modules have been enabled: Experimental Test, Experimental Dependency Test'); + $this->assertText('2 modules have been enabled: Experimental Dependency Test, Experimental Test'); // Try to enable an experimental module that can not be due to // hook_requirements(). \Drupal::state()->set('experimental_module_requirements_test_requirements', TRUE); $edit = []; - $edit["modules[Core (Experimental)][experimental_module_requirements_test][enable]"] = TRUE; + $edit["modules[experimental_module_requirements_test][enable]"] = TRUE; $this->drupalPostForm('admin/modules', $edit, 'Install'); $this->assertUrl('admin/modules', [], 'If the module can not be installed we are not taken to the confirm form.'); $this->assertText('The Experimental Test Requirements module can not be installed.'); diff --git a/core/modules/system/src/Tests/Module/InstallTest.php b/core/modules/system/tests/src/Functional/Module/InstallTest.php similarity index 83% rename from core/modules/system/src/Tests/Module/InstallTest.php rename to core/modules/system/tests/src/Functional/Module/InstallTest.php index babdd76d..ccbca6d3 100644 --- a/core/modules/system/src/Tests/Module/InstallTest.php +++ b/core/modules/system/tests/src/Functional/Module/InstallTest.php @@ -1,23 +1,23 @@ install(array('user'), FALSE); + \Drupal::service('module_installer')->install(['user'], FALSE); $this->assertIdentical($this->config('core.extension')->get('module.user'), 0); } @@ -70,9 +70,9 @@ public function testUninstallPostUpdateFunctions() { */ public function testModuleNameLength() { $module_name = 'invalid_module_name_over_the_maximum_allowed_character_length'; - $message = format_string('Exception thrown when enabling module %name with a name length over the allowed maximum', array('%name' => $module_name)); + $message = format_string('Exception thrown when enabling module %name with a name length over the allowed maximum', ['%name' => $module_name]); try { - $this->container->get('module_installer')->install(array($module_name)); + $this->container->get('module_installer')->install([$module_name]); $this->fail($message); } catch (ExtensionNameLengthException $e) { @@ -80,9 +80,9 @@ public function testModuleNameLength() { } // Since for the UI, the submit callback uses FALSE, test that too. - $message = format_string('Exception thrown when enabling as if via the UI the module %name with a name length over the allowed maximum', array('%name' => $module_name)); + $message = format_string('Exception thrown when enabling as if via the UI the module %name with a name length over the allowed maximum', ['%name' => $module_name]); try { - $this->container->get('module_installer')->install(array($module_name), FALSE); + $this->container->get('module_installer')->install([$module_name], FALSE); $this->fail($message); } catch (ExtensionNameLengthException $e) { diff --git a/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php b/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php new file mode 100644 index 00000000..abdbe039 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Module/ModuleTestBase.php @@ -0,0 +1,196 @@ +adminUser = $this->drupalCreateUser(['access administration pages', 'administer modules']); + $this->drupalLogin($this->adminUser); + } + + /** + * Assert there are tables that begin with the specified base table name. + * + * @param $base_table + * Beginning of table name to look for. + * @param $count + * (optional) Whether or not to assert that there are tables that match the + * specified base table. Defaults to TRUE. + */ + public function assertTableCount($base_table, $count = TRUE) { + $tables = db_find_tables(Database::getConnection()->prefixTables('{' . $base_table . '}') . '%'); + + if ($count) { + return $this->assertTrue($tables, format_string('Tables matching "@base_table" found.', ['@base_table' => $base_table])); + } + return $this->assertFalse($tables, format_string('Tables matching "@base_table" not found.', ['@base_table' => $base_table])); + } + + /** + * Assert that all tables defined in a module's hook_schema() exist. + * + * @param $module + * The name of the module. + */ + public function assertModuleTablesExist($module) { + $tables = array_keys(drupal_get_module_schema($module)); + $tables_exist = TRUE; + foreach ($tables as $table) { + if (!db_table_exists($table)) { + $tables_exist = FALSE; + } + } + return $this->assertTrue($tables_exist, format_string('All database tables defined by the @module module exist.', ['@module' => $module])); + } + + /** + * Assert that none of the tables defined in a module's hook_schema() exist. + * + * @param $module + * The name of the module. + */ + public function assertModuleTablesDoNotExist($module) { + $tables = array_keys(drupal_get_module_schema($module)); + $tables_exist = FALSE; + foreach ($tables as $table) { + if (db_table_exists($table)) { + $tables_exist = TRUE; + } + } + return $this->assertFalse($tables_exist, format_string('None of the database tables defined by the @module module exist.', ['@module' => $module])); + } + + /** + * Asserts that the default configuration of a module has been installed. + * + * @param string $module + * The name of the module. + * + * @return bool|null + * TRUE if configuration has been installed, FALSE otherwise. Returns NULL + * if the module configuration directory does not exist or does not contain + * any configuration files. + */ + public function assertModuleConfig($module) { + $module_config_dir = drupal_get_path('module', $module) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY; + if (!is_dir($module_config_dir)) { + return; + } + $module_file_storage = new FileStorage($module_config_dir); + + // Verify that the module's default config directory is not empty and + // contains default configuration files (instead of something else). + $all_names = $module_file_storage->listAll(); + if (empty($all_names)) { + // Module has an empty config directory. For example it might contain a + // schema directory. + return; + } + $this->assertTrue($all_names); + + // Look up each default configuration object name in the active + // configuration, and if it exists, remove it from the stack. + // Only default config that belongs to $module is guaranteed to exist; any + // other default config depends on whether other modules are enabled. Thus, + // list all default config once more, but filtered by $module. + $names = $module_file_storage->listAll($module . '.'); + foreach ($names as $key => $name) { + if ($this->config($name)->get()) { + unset($names[$key]); + } + } + // Verify that all configuration has been installed (which means that $names + // is empty). + return $this->assertFalse($names, format_string('All default configuration of @module module found.', ['@module' => $module])); + } + + /** + * Asserts that no configuration exists for a given module. + * + * @param string $module + * The name of the module. + * + * @return bool + * TRUE if no configuration was found, FALSE otherwise. + */ + public function assertNoModuleConfig($module) { + $names = \Drupal::configFactory()->listAll($module . '.'); + return $this->assertFalse($names, format_string('No configuration found for @module module.', ['@module' => $module])); + } + + /** + * Assert the list of modules are enabled or disabled. + * + * @param $modules + * Module list to check. + * @param $enabled + * Expected module state. + */ + public function assertModules(array $modules, $enabled) { + $this->rebuildContainer(); + foreach ($modules as $module) { + if ($enabled) { + $message = 'Module "@module" is enabled.'; + } + else { + $message = 'Module "@module" is not enabled.'; + } + $this->assertEqual($this->container->get('module_handler')->moduleExists($module), $enabled, format_string($message, ['@module' => $module])); + } + } + + /** + * Verify a log entry was entered for a module's status change. + * + * @param $type + * The category to which this message belongs. + * @param $message + * The message to store in the log. Keep $message translatable + * by not concatenating dynamic values into it! Variables in the + * message should be added by using placeholder strings alongside + * the variables argument to declare the value of the placeholders. + * See t() for documentation on how $message and $variables interact. + * @param $variables + * Array of variables to replace in the message on display or + * NULL if message is already translated or not possible to + * translate. + * @param $severity + * The severity of the message, as per RFC 3164. + * @param $link + * A link to associate with the message. + */ + public function assertLogMessage($type, $message, $variables = [], $severity = RfcLogLevel::NOTICE, $link = '') { + $count = db_select('watchdog', 'w') + ->condition('type', $type) + ->condition('message', $message) + ->condition('variables', serialize($variables)) + ->condition('severity', $severity) + ->condition('link', $link) + ->countQuery() + ->execute() + ->fetchField(); + $this->assertTrue($count > 0, format_string('watchdog table contains @count rows for @message', ['@count' => $count, '@message' => format_string($message, $variables)])); + } + +} diff --git a/core/modules/system/src/Tests/Module/UninstallTest.php b/core/modules/system/tests/src/Functional/Module/UninstallTest.php similarity index 88% rename from core/modules/system/src/Tests/Module/UninstallTest.php rename to core/modules/system/tests/src/Functional/Module/UninstallTest.php index 20e191df..2b17b8fc 100644 --- a/core/modules/system/src/Tests/Module/UninstallTest.php +++ b/core/modules/system/tests/src/Functional/Module/UninstallTest.php @@ -1,35 +1,35 @@ container->get('module_installer')->uninstall(array('module_test')); + $this->container->get('module_installer')->uninstall(['module_test']); // Are the perms defined by module_test removed? $this->assertFalse(user_roles(FALSE, 'module_test perm'), 'Permissions were all removed.'); @@ -38,8 +38,8 @@ function testUserPermsUninstalled() { /** * Tests the Uninstall page and Uninstall confirmation page. */ - function testUninstallPage() { - $account = $this->drupalCreateUser(array('administer modules')); + public function testUninstallPage() { + $account = $this->drupalCreateUser(['administer modules']); $this->drupalLogin($account); // Create a node type. @@ -67,7 +67,7 @@ function testUninstallPage() { $node->delete(); // Uninstall module_test. - $edit = array(); + $edit = []; $edit['uninstall[module_test]'] = TRUE; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); $this->assertNoText(\Drupal::translation()->translate('Configuration deletions'), 'No configuration deletions listed on the module install confirmation page.'); @@ -78,14 +78,14 @@ function testUninstallPage() { // Uninstall node testing that the configuration that will be deleted is // listed. - $node_dependencies = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('module', array('node')); - $edit = array(); + $node_dependencies = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('module', ['node']); + $edit = []; $edit['uninstall[node]'] = TRUE; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); $this->assertText(\Drupal::translation()->translate('Configuration deletions'), 'Configuration deletions listed on the module install confirmation page.'); $this->assertNoText(\Drupal::translation()->translate('Configuration updates'), 'No configuration updates listed on the module install confirmation page.'); - $entity_types = array(); + $entity_types = []; foreach ($node_dependencies as $entity) { $label = $entity->label() ?: $entity->id(); $this->assertText($label); @@ -103,7 +103,7 @@ function testUninstallPage() { // cleared during the uninstall. \Drupal::cache()->set('uninstall_test', 'test_uninstall_page', Cache::PERMANENT); $cached = \Drupal::cache()->get('uninstall_test'); - $this->assertEqual($cached->data, 'test_uninstall_page', SafeMarkup::format('Cache entry found: @bin', array('@bin' => $cached->data))); + $this->assertEqual($cached->data, 'test_uninstall_page', SafeMarkup::format('Cache entry found: @bin', ['@bin' => $cached->data])); $this->drupalPostForm(NULL, NULL, t('Uninstall')); $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.'); @@ -123,7 +123,7 @@ function testUninstallPage() { $this->assertTitle(t('Uninstall') . ' | Drupal'); // Make sure the correct error is shown when no modules are selected. - $edit = array(); + $edit = []; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); $this->assertText(t('No modules selected.'), 'No module is selected to uninstall'); } @@ -132,12 +132,12 @@ function testUninstallPage() { * Tests that a module which fails to install can still be uninstalled. */ public function testFailedInstallStatus() { - $account = $this->drupalCreateUser(array('administer modules')); + $account = $this->drupalCreateUser(['administer modules']); $this->drupalLogin($account); $message = 'Exception thrown when installing module_installer_config_test with an invalid configuration file.'; try { - $this->container->get('module_installer')->install(array('module_installer_config_test')); + $this->container->get('module_installer')->install(['module_installer_config_test']); $this->fail($message); } catch (EntityMalformedException $e) { diff --git a/core/modules/system/src/Tests/ParamConverter/UpcastingTest.php b/core/modules/system/tests/src/Functional/ParamConverter/UpcastingTest.php similarity index 80% rename from core/modules/system/src/Tests/ParamConverter/UpcastingTest.php rename to core/modules/system/tests/src/Functional/ParamConverter/UpcastingTest.php index b881386c..faafe846 100644 --- a/core/modules/system/src/Tests/ParamConverter/UpcastingTest.php +++ b/core/modules/system/tests/src/Functional/ParamConverter/UpcastingTest.php @@ -1,8 +1,8 @@ drupalCreateNode(array('title' => $this->randomMachineName(8))); - $user = $this->drupalCreateUser(array('access content')); + $node = $this->drupalCreateNode(['title' => $this->randomMachineName(8)]); + $user = $this->drupalCreateUser(['access content']); $foo = 'bar'; // paramconverter_test/test_user_node_foo/{user}/{node}/{foo} @@ -48,8 +48,8 @@ public function testUpcasting() { * Confirms we can upcast to controller arguments of the same type. */ public function testSameTypes() { - $node = $this->drupalCreateNode(array('title' => $this->randomMachineName(8))); - $parent = $this->drupalCreateNode(array('title' => $this->randomMachineName(8))); + $node = $this->drupalCreateNode(['title' => $this->randomMachineName(8)]); + $parent = $this->drupalCreateNode(['title' => $this->randomMachineName(8)]); // paramconverter_test/node/{node}/set/parent/{parent} // options.parameters.parent.type = entity:node $this->drupalGet("paramconverter_test/node/" . $node->id() . "/set/parent/" . $parent->id()); @@ -63,19 +63,19 @@ public function testEntityLanguage() { $language = ConfigurableLanguage::createFromLangcode('de'); $language->save(); \Drupal::configFactory()->getEditable('language.negotiation') - ->set('url.prefixes', array('de' => 'de')) + ->set('url.prefixes', ['de' => 'de']) ->save(); // The container must be recreated after adding a new language. $this->rebuildContainer(); - $node = $this->drupalCreateNode(array('title' => 'English label')); + $node = $this->drupalCreateNode(['title' => 'English label']); $translation = $node->addTranslation('de'); $translation->setTitle('Deutscher Titel')->save(); $this->drupalGet("/paramconverter_test/node/" . $node->id() . "/test_language"); $this->assertRaw("English label"); - $this->drupalGet("paramconverter_test/node/" . $node->id() . "/test_language", array('language' => $language)); + $this->drupalGet("paramconverter_test/node/" . $node->id() . "/test_language", ['language' => $language]); $this->assertRaw("Deutscher Titel"); } diff --git a/core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php b/core/modules/system/tests/src/Functional/Path/UrlAlterFunctionalTest.php similarity index 82% rename from core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php rename to core/modules/system/tests/src/Functional/Path/UrlAlterFunctionalTest.php index 743b74bd..27177416 100644 --- a/core/modules/system/src/Tests/Path/UrlAlterFunctionalTest.php +++ b/core/modules/system/tests/src/Functional/Path/UrlAlterFunctionalTest.php @@ -1,9 +1,10 @@ assertTrue(Database::getConnection()->schema()->tableExists('url_alias'), 'The url_alias table exists after Drupal installation.'); // User names can have quotes and plus signs so we should ensure that URL // altering works with this. - $account = $this->drupalCreateUser(array('administer url aliases'), "a'foo+bar"); + $account = $this->drupalCreateUser(['administer url aliases'], "a'foo+bar"); $this->drupalLogin($account); $uid = $account->id(); @@ -41,14 +42,14 @@ function testUrlAlter() { $this->assertUrlOutboundAlter("/user/$uid", "/user/$name"); // Test that a path always uses its alias. - $path = array('source' => "/user/$uid/test1", 'alias' => '/alias/test1'); + $path = ['source' => "/user/$uid/test1", 'alias' => '/alias/test1']; $this->container->get('path.alias_storage')->save($path['source'], $path['alias']); $this->rebuildContainer(); $this->assertUrlInboundAlter('/alias/test1', "/user/$uid/test1"); $this->assertUrlOutboundAlter("/user/$uid/test1", '/alias/test1'); // Test adding an alias via the UI. - $edit = array('source' => "/user/$uid/edit", 'alias' => '/alias/test2'); + $edit = ['source' => "/user/$uid/edit", 'alias' => '/alias/test2']; $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); $this->assertText(t('The alias has been saved.')); $this->drupalGet('alias/test2'); @@ -74,6 +75,10 @@ function testUrlAlter() { $this->drupalGet("community/" . $term->id()); $this->assertText($term_name, 'The community/{tid} path gets resolved correctly'); $this->assertUrlOutboundAlter("/forum/" . $term->id(), "/community/" . $term->id()); + + // Test outbound query string altering. + $url = Url::fromRoute('user.login'); + $this->assertIdentical(\Drupal::request()->getBaseUrl() . '/user/login?foo=bar', $url->toString()); } /** @@ -90,7 +95,7 @@ function testUrlAlter() { protected function assertUrlOutboundAlter($original, $final) { // Test outbound altering. $result = $this->container->get('path_processor_manager')->processOutbound($original); - return $this->assertIdentical($result, $final, format_string('Altered outbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result))); + return $this->assertIdentical($result, $final, format_string('Altered outbound URL %original, expected %final, and got %result.', ['%original' => $original, '%final' => $final, '%result' => $result])); } /** @@ -107,7 +112,7 @@ protected function assertUrlOutboundAlter($original, $final) { protected function assertUrlInboundAlter($original, $final) { // Test inbound altering. $result = $this->container->get('path.alias_manager')->getPathByAlias($original); - return $this->assertIdentical($result, $final, format_string('Altered inbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result))); + return $this->assertIdentical($result, $final, format_string('Altered inbound URL %original, expected %final, and got %result.', ['%original' => $original, '%final' => $final, '%result' => $result])); } } diff --git a/core/modules/system/src/Tests/Render/AjaxPageStateTest.php b/core/modules/system/tests/src/Functional/Render/AjaxPageStateTest.php similarity index 92% rename from core/modules/system/src/Tests/Render/AjaxPageStateTest.php rename to core/modules/system/tests/src/Functional/Render/AjaxPageStateTest.php index 19e62377..6f5dc7da 100644 --- a/core/modules/system/src/Tests/Render/AjaxPageStateTest.php +++ b/core/modules/system/tests/src/Functional/Render/AjaxPageStateTest.php @@ -1,15 +1,15 @@ drupalGet('node', array()); + $this->drupalGet('node', []); $this->assertRaw( '/core/assets/vendor/html5shiv/html5shiv.min.js', 'The html5shiv library from core should be loaded.' @@ -63,14 +63,14 @@ public function testLibrariesAvailable() { */ public function testHtml5ShivIsNotLoaded() { $this->drupalGet('node', - array( + [ "query" => - array( - 'ajax_page_state' => array( + [ + 'ajax_page_state' => [ 'libraries' => 'core/html5shiv' - ) - ) - ) + ] + ] + ] ); $this->assertNoRaw( '/core/assets/vendor/html5shiv/html5shiv.min.js', diff --git a/core/modules/system/tests/src/Functional/Render/DisplayVariantTest.php b/core/modules/system/tests/src/Functional/Render/DisplayVariantTest.php new file mode 100644 index 00000000..2f5415ba --- /dev/null +++ b/core/modules/system/tests/src/Functional/Render/DisplayVariantTest.php @@ -0,0 +1,34 @@ +drupalGet(''); + $this->assertRaw('A very important, required value.'); + $this->assertRaw('Explicitly passed in context.'); + $this->assertCacheTag('custom_cache_tag'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Render/RenderArrayNonHtmlSubscriberTest.php b/core/modules/system/tests/src/Functional/Render/RenderArrayNonHtmlSubscriberTest.php new file mode 100644 index 00000000..08380dec --- /dev/null +++ b/core/modules/system/tests/src/Functional/Render/RenderArrayNonHtmlSubscriberTest.php @@ -0,0 +1,54 @@ +drupalGet($url); + $this->assertSession()->statusCodeEquals(200); + $this->assertRaw(t('Controller response successfully rendered.')); + + // Test that correct response code is returned for any non-HTML format. + foreach (['json', 'hal+json', 'xml', 'foo'] as $format) { + $url = Url::fromRoute('render_array_non_html_subscriber_test.render_array', [ + '_format' => $format, + ]); + + $this->drupalGet($url); + $this->assertSession()->statusCodeEquals(406); + $this->assertNoRaw(t('Controller response successfully rendered.')); + } + + // Test that event subscriber does not interfere with raw string responses. + $url = Url::fromRoute('render_array_non_html_subscriber_test.raw_string', [ + '_format' => 'foo', + ]); + + $this->drupalGet($url); + $this->assertSession()->statusCodeEquals(200); + $this->assertRaw(t('Raw controller response.')); + } + +} diff --git a/core/modules/system/src/Tests/Routing/MockMatcher.php b/core/modules/system/tests/src/Functional/Routing/MockMatcher.php similarity index 93% rename from core/modules/system/src/Tests/Routing/MockMatcher.php rename to core/modules/system/tests/src/Functional/Routing/MockMatcher.php index 924acd13..eee6b139 100644 --- a/core/modules/system/src/Tests/Routing/MockMatcher.php +++ b/core/modules/system/tests/src/Functional/Routing/MockMatcher.php @@ -1,6 +1,6 @@ drupalGet('router_test/test8'); $this->assertResponse(403, 'Access denied by default if no access specified'); - $user = $this->drupalCreateUser(array('access test7')); + $user = $this->drupalCreateUser(['access test7']); $this->drupalLogin($user); $this->drupalGet('router_test/test7'); $this->assertResponse(200); diff --git a/core/modules/system/src/Tests/ServiceProvider/ServiceProviderWebTest.php b/core/modules/system/tests/src/Functional/ServiceProvider/ServiceProviderWebTest.php similarity index 81% rename from core/modules/system/src/Tests/ServiceProvider/ServiceProviderWebTest.php rename to core/modules/system/tests/src/Functional/ServiceProvider/ServiceProviderWebTest.php index 5d2505ae..73d69100 100644 --- a/core/modules/system/src/Tests/ServiceProvider/ServiceProviderWebTest.php +++ b/core/modules/system/tests/src/Functional/ServiceProvider/ServiceProviderWebTest.php @@ -1,22 +1,22 @@ '; + $this->drupalGet('node'); + $this->assertRaw($string, 'Fingerprinting meta tag generated correctly.', 'System'); + } + +} diff --git a/core/modules/system/src/Tests/System/DateFormatsLockedTest.php b/core/modules/system/tests/src/Functional/System/DateFormatsLockedTest.php similarity index 90% rename from core/modules/system/src/Tests/System/DateFormatsLockedTest.php rename to core/modules/system/tests/src/Functional/System/DateFormatsLockedTest.php index c8a0a67c..faac2b76 100644 --- a/core/modules/system/src/Tests/System/DateFormatsLockedTest.php +++ b/core/modules/system/tests/src/Functional/System/DateFormatsLockedTest.php @@ -1,15 +1,15 @@ drupalCreateUser(array('administer site configuration')); + $admin = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($admin); } @@ -28,49 +28,49 @@ protected function setUp() { public function testDateFormatsMachineNameAllowedValues() { // Try to create a date format with a not allowed character to test the date // format specific machine name replace pattern. - $edit = array( + $edit = [ 'label' => 'Something Not Allowed', 'id' => 'something.bad', 'date_format_pattern' => 'Y-m-d', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertText(t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'), 'It is not possible to create a date format with the machine name that has any character other than lowercase letters, digits or underscore.'); // Try to create a date format with the reserved machine name "custom". - $edit = array( + $edit = [ 'label' => 'Custom', 'id' => 'custom', 'date_format_pattern' => 'Y-m-d', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertText(t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'), 'It is not possible to create a date format with the machine name "custom".'); // Try to create a date format with a machine name, "fallback", that // already exists. - $edit = array( + $edit = [ 'label' => 'Fallback', 'id' => 'fallback', 'date_format_pattern' => 'j/m/Y', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertText(t('The machine-readable name is already in use. It must be unique.'), 'It is not possible to create a date format with the machine name "fallback". It is a built-in format that already exists.'); // Create a date format with a machine name distinct from the previous two. $id = Unicode::strtolower($this->randomMachineName(16)); - $edit = array( + $edit = [ 'label' => $this->randomMachineName(16), 'id' => $id, 'date_format_pattern' => 'd/m/Y', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertText(t('Custom date format added.'), 'It is possible to create a date format with a new machine name.'); // Try to create a date format with same machine name as the previous one. - $edit = array( + $edit = [ 'label' => $this->randomMachineName(16), 'id' => $id, 'date_format_pattern' => 'd-m-Y', - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertText(t('The machine-readable name is already in use. It must be unique.'), 'It is not possible to create a new date format with an existing machine name.'); } diff --git a/core/modules/system/src/Tests/System/DateTimeTest.php b/core/modules/system/tests/src/Functional/System/DateTimeTest.php similarity index 86% rename from core/modules/system/src/Tests/System/DateTimeTest.php rename to core/modules/system/tests/src/Functional/System/DateTimeTest.php index 9ca050f4..bdecab5d 100644 --- a/core/modules/system/src/Tests/System/DateTimeTest.php +++ b/core/modules/system/tests/src/Functional/System/DateTimeTest.php @@ -1,10 +1,10 @@ drupalLogin ($this->drupalCreateUser(array( + $this->drupalLogin($this->drupalCreateUser([ 'administer site configuration', 'administer content types', 'administer nodes', 'administer node fields', 'administer node form display', 'administer node display', - ))); + ])); $this->drupalPlaceBlock('local_actions_block'); } /** * Test time zones and DST handling. */ - function testTimeZoneHandling() { + public function testTimeZoneHandling() { // Setup date/time settings for Honolulu time. $config = $this->config('system.date') ->set('timezone.default', 'Pacific/Honolulu') @@ -52,9 +52,9 @@ function testTimeZoneHandling() { // Create some nodes with different authored-on dates. $date1 = '2007-01-31 21:00:00 -1000'; $date2 = '2007-07-31 21:00:00 -1000'; - $this->drupalCreateContentType(array('type' => 'article')); - $node1 = $this->drupalCreateNode(array('created' => strtotime($date1), 'type' => 'article')); - $node2 = $this->drupalCreateNode(array('created' => strtotime($date2), 'type' => 'article')); + $this->drupalCreateContentType(['type' => 'article']); + $node1 = $this->drupalCreateNode(['created' => strtotime($date1), 'type' => 'article']); + $node2 = $this->drupalCreateNode(['created' => strtotime($date2), 'type' => 'article']); // Confirm date format and time zone. $this->drupalGet('node/' . $node1->id()); @@ -64,7 +64,7 @@ function testTimeZoneHandling() { // Set time zone to Los Angeles time. $config->set('timezone.default', 'America/Los_Angeles')->save(); - \Drupal::entityManager()->getViewBuilder('node')->resetCache(array($node1, $node2)); + \Drupal::entityManager()->getViewBuilder('node')->resetCache([$node1, $node2]); // Confirm date format and time zone. $this->drupalGet('node/' . $node1->id()); @@ -76,7 +76,7 @@ function testTimeZoneHandling() { /** * Test date format configuration. */ - function testDateFormatConfiguration() { + public function testDateFormatConfiguration() { // Confirm 'no custom date formats available' message appears. $this->drupalGet('admin/config/regional/date-time'); @@ -85,11 +85,11 @@ function testDateFormatConfiguration() { $date_format_id = strtolower($this->randomMachineName(8)); $name = ucwords($date_format_id); $date_format = 'd.m.Y - H:i'; - $edit = array( + $edit = [ 'id' => $date_format_id, 'label' => $name, 'date_format_pattern' => $date_format, - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.'); @@ -100,24 +100,24 @@ function testDateFormatConfiguration() { $this->drupalGet('admin/config/regional/date-time'); $this->clickLink(t('Edit')); $this->drupalPostForm(NULL, NULL, t('Save format')); - $this->assertUrl('admin/config/regional/date-time', array('absolute' => TRUE), 'Correct page redirection.'); + $this->assertUrl('admin/config/regional/date-time', ['absolute' => TRUE], 'Correct page redirection.'); $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.'); // Edit custom date format. $this->drupalGet('admin/config/regional/date-time'); $this->clickLink(t('Edit')); - $edit = array( + $edit = [ 'date_format_pattern' => 'Y m', - ); + ]; $this->drupalPostForm($this->getUrl(), $edit, t('Save format')); $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.'); // Delete custom date format. $this->clickLink(t('Delete')); - $this->drupalPostForm('admin/config/regional/date-time/formats/manage/' . $date_format_id . '/delete', array(), t('Delete')); + $this->drupalPostForm('admin/config/regional/date-time/formats/manage/' . $date_format_id . '/delete', [], t('Delete')); $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); - $this->assertRaw(t('The date format %format has been deleted.', array('%format' => $name)), 'Custom date format removed.'); + $this->assertRaw(t('The date format %format has been deleted.', ['%format' => $name]), 'Custom date format removed.'); // Make sure the date does not exist in config. $date_format = DateFormat::load($date_format_id); @@ -127,22 +127,22 @@ function testDateFormatConfiguration() { $date_format_id = strtolower($this->randomMachineName(8)); $name = ucwords($date_format_id); $date_format = 'Y'; - $edit = array( + $edit = [ 'id' => $date_format_id, 'label' => $name, 'date_format_pattern' => $date_format, - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.'); $this->assertText($name, 'Custom date format appears in the date format list.'); $this->assertText(t('Delete'), 'Delete link for custom date format appears.'); - $date_format = DateFormat::create(array( + $date_format = DateFormat::create([ 'id' => 'xss_short', 'label' => 'XSS format', 'pattern' => '\<\s\c\r\i\p\t\>\a\l\e\r\t\(\'\X\S\S\'\)\;\<\/\s\c\r\i\p\t\>', - )); + ]); $date_format->save(); $this->drupalGet(Url::fromRoute('entity.date_format.collection')); @@ -152,11 +152,11 @@ function testDateFormatConfiguration() { $date_format_id = strtolower($this->randomMachineName(8)); $name = ucwords($date_format_id); $date_format = '& \<\e\m\>Y\<\/\e\m\>'; - $edit = array( + $edit = [ 'id' => $date_format_id, 'label' => $name, 'date_format_pattern' => $date_format, - ); + ]; $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format')); $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.'); @@ -167,52 +167,53 @@ function testDateFormatConfiguration() { /** * Test handling case with invalid data in selectors (like February, 31st). */ - function testEnteringDateTimeViaSelectors() { + public function testEnteringDateTimeViaSelectors() { - $this->drupalCreateContentType(array('type' => 'page_with_date', 'name' => 'Page with date')); + $this->drupalCreateContentType(['type' => 'page_with_date', 'name' => 'Page with date']); $this->drupalGet('admin/structure/types/manage/page_with_date'); $this->assertResponse(200, 'Content type created.'); $this->drupalGet('admin/structure/types/manage/page_with_date/fields/add-field'); - $edit = array( + $edit = [ 'new_storage_type' => 'datetime', 'label' => 'dt', 'field_name' => 'dt', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page_with_date/fields/add-field', $edit, t('Save and continue')); $this->assertText(t('These settings apply to the'), 'New datetime field created, now configuring'); $this->drupalGet('admin/structure/types/manage/page_with_date/fields/node.page_with_date.field_dt/storage'); - $edit = array( + $edit = [ 'settings[datetime_type]' => 'datetime', 'cardinality' => 'number', 'cardinality_number' => '1', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/page_with_date/fields/node.page_with_date.field_dt/storage', $edit, t('Save field settings')); $this->drupalGet('admin/structure/types/manage/page_with_date/fields'); $this->assertText('field_dt', 'New field is in place'); $this->drupalGet('admin/structure/types/manage/page_with_date/form-display'); - $edit = array( + $edit = [ 'fields[field_dt][type]' => 'datetime_datelist', - ); + 'fields[field_dt][region]' => 'content', + ]; $this->drupalPostForm('admin/structure/types/manage/page_with_date/form-display', $edit, t('Save')); $this->drupalLogout(); // Now log in as a regular editor. - $this->drupalLogin($this->drupalCreateUser(array('create page_with_date content'))); + $this->drupalLogin($this->drupalCreateUser(['create page_with_date content'])); $this->drupalGet('node/add/page_with_date'); - $edit = array( + $edit = [ 'title[0][value]' => 'sample doc', 'field_dt[0][value][year]' => '2016', 'field_dt[0][value][month]' => '2', 'field_dt[0][value][day]' => '31', 'field_dt[0][value][hour]' => '1', 'field_dt[0][value][minute]' => '30', - ); + ]; $this->drupalPostForm('node/add/page_with_date', $edit, t('Save')); $this->assertText(t('Selected combination of day and month is not valid.'), 'Inorrect date failed validation'); diff --git a/core/modules/system/tests/src/Functional/System/IndexPhpTest.php b/core/modules/system/tests/src/Functional/System/IndexPhpTest.php new file mode 100644 index 00000000..2bf09893 --- /dev/null +++ b/core/modules/system/tests/src/Functional/System/IndexPhpTest.php @@ -0,0 +1,30 @@ +drupalGet($index_php, ['external' => TRUE]); + $this->assertResponse(200, 'Make sure index.php returns a valid page.'); + + $this->drupalGet($index_php . '/user', ['external' => TRUE]); + $this->assertResponse(200, 'Make sure index.php/user returns a valid page.'); + } + +} diff --git a/core/modules/system/src/Tests/System/MainContentFallbackTest.php b/core/modules/system/tests/src/Functional/System/MainContentFallbackTest.php similarity index 82% rename from core/modules/system/src/Tests/System/MainContentFallbackTest.php rename to core/modules/system/tests/src/Functional/System/MainContentFallbackTest.php index 551e4c74..931b84ce 100644 --- a/core/modules/system/src/Tests/System/MainContentFallbackTest.php +++ b/core/modules/system/tests/src/Functional/System/MainContentFallbackTest.php @@ -1,22 +1,22 @@ adminUser = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser([ 'access administration pages', 'administer site configuration', 'administer modules', - )); + ]); $this->drupalLogin($this->adminUser); // Create a web user. - $this->webUser = $this->drupalCreateUser(array('access user profiles')); + $this->webUser = $this->drupalCreateUser(['access user profiles']); } /** * Test availability of main content: Drupal falls back to SimplePageVariant. */ - function testMainContentFallback() { - $edit = array(); + public function testMainContentFallback() { + $edit = []; // Uninstall the block module. $edit['uninstall[block]'] = 'block'; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); @@ -63,8 +63,8 @@ function testMainContentFallback() { // Enable the block module again. $this->drupalLogin($this->adminUser); - $edit = array(); - $edit['modules[Core][block][enable]'] = 'block'; + $edit = []; + $edit['modules[block][enable]'] = 'block'; $this->drupalPostForm('admin/modules', $edit, t('Install')); $this->assertText(t('Module Block has been enabled.'), 'Modules status has been updated.'); $this->rebuildContainer(); diff --git a/core/modules/system/src/Tests/System/RetrieveFileTest.php b/core/modules/system/tests/src/Functional/System/RetrieveFileTest.php similarity index 92% rename from core/modules/system/src/Tests/System/RetrieveFileTest.php rename to core/modules/system/tests/src/Functional/System/RetrieveFileTest.php index 8f6fe4af..ef12a51a 100644 --- a/core/modules/system/src/Tests/System/RetrieveFileTest.php +++ b/core/modules/system/tests/src/Functional/System/RetrieveFileTest.php @@ -1,19 +1,19 @@ randomMachineName()); $filename = 'Файл Ð´Ð»Ñ Ñ‚ÐµÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ' . $this->randomMachineName(); diff --git a/core/modules/system/src/Tests/System/SitesDirectoryHardeningTest.php b/core/modules/system/tests/src/Functional/System/SitesDirectoryHardeningTest.php similarity index 91% rename from core/modules/system/src/Tests/System/SitesDirectoryHardeningTest.php rename to core/modules/system/tests/src/Functional/System/SitesDirectoryHardeningTest.php index f9331ba8..fbe97f4d 100644 --- a/core/modules/system/src/Tests/System/SitesDirectoryHardeningTest.php +++ b/core/modules/system/tests/src/Functional/System/SitesDirectoryHardeningTest.php @@ -1,18 +1,18 @@ settingsFile($site_path); // First, we check based on what the initial install has set. - $this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file.', array('@file' => $site_path))); + $this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file.', ['@file' => $site_path])); // We intentionally don't check for settings.local.php as that file is // not created by Drupal. - $this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file.', array('@file' => $settings_file))); + $this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file.', ['@file' => $settings_file])); $this->makeWritable($site_path); $this->checkSystemRequirements(); - $this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file after manual permissions change.', array('@file' => $site_path))); - $this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file after manual permissions change.', array('@file' => $settings_file))); + $this->assertTrue(drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir'), new FormattableMarkup('Verified permissions for @file after manual permissions change.', ['@file' => $site_path])); + $this->assertTrue(drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE), new FormattableMarkup('Verified permissions for @file after manual permissions change.', ['@file' => $settings_file])); } /** diff --git a/core/modules/system/tests/src/Functional/System/StatusTest.php b/core/modules/system/tests/src/Functional/System/StatusTest.php new file mode 100644 index 00000000..1ec4fb5a --- /dev/null +++ b/core/modules/system/tests/src/Functional/System/StatusTest.php @@ -0,0 +1,104 @@ + (object) [ + 'value' => '', + 'required' => TRUE, + ], + ]; + $this->writeSettings($settings); + + $admin_user = $this->drupalCreateUser([ + 'administer site configuration', + ]); + $this->drupalLogin($admin_user); + } + + /** + * Tests that the status page returns. + */ + public function testStatusPage() { + // Go to Administration. + $this->drupalGet('admin/reports/status'); + $this->assertResponse(200, 'The status page is reachable.'); + + $phpversion = phpversion(); + $this->assertText($phpversion, 'Php version is shown on the page.'); + + // Checks if the suggestion to update to php 5.5.21 or 5.6.5 for disabling + // multiple statements is present when necessary. + if (\Drupal::database()->driver() === 'mysql' && !SystemRequirements::phpVersionWithPdoDisallowMultipleStatements($phpversion)) { + $this->assertText(t('PHP (multiple statement disabling)')); + } + else { + $this->assertNoText(t('PHP (multiple statement disabling)')); + } + + if (function_exists('phpinfo')) { + $this->assertLinkByHref(Url::fromRoute('system.php')->toString()); + } + else { + $this->assertNoLinkByHref(Url::fromRoute('system.php')->toString()); + } + + // If a module is fully installed no pending updates exists. + $this->assertNoText(t('Out of date')); + + // The global $config_directories is not properly formed. + $this->assertRaw(t('Your %file file must define the $config_directories variable as an array containing the names of directories in which configuration files can be found. It must contain a %sync_key key.', ['%file' => $this->siteDirectory . '/settings.php', '%sync_key' => CONFIG_SYNC_DIRECTORY])); + + // Set the schema version of update_test_postupdate to a lower version, so + // update_test_postupdate_update_8001() needs to be executed. + drupal_set_installed_schema_version('update_test_postupdate', 8000); + $this->drupalGet('admin/reports/status'); + $this->assertText(t('Out of date')); + + // Now cleanup the executed post update functions. + drupal_set_installed_schema_version('update_test_postupdate', 8001); + /** @var \Drupal\Core\Update\UpdateRegistry $post_update_registry */ + $post_update_registry = \Drupal::service('update.post_update_registry'); + $post_update_registry->filterOutInvokedUpdatesByModule('update_test_postupdate'); + $this->drupalGet('admin/reports/status'); + $this->assertText(t('Out of date')); + + $this->drupalGet('admin/reports/status/php'); + $this->assertResponse(200, 'The phpinfo page is reachable.'); + + // Check if cron error is displayed in errors section + $cron_last_run = \Drupal::state()->get('system.cron_last'); + \Drupal::state()->set('system.cron_last', 0); + $this->drupalGet('admin/reports/status'); + $css_selector_converter = new CssSelectorConverter(); + $xpath = $css_selector_converter->toXPath('details.system-status-report__entry') . '//div[contains(text(), "Cron has not run recently")]'; + $this->assertNotEmpty($this->xpath($xpath), 'Cron has not run recently error is being displayed.'); + \Drupal::state()->set('system.cron_last', $cron_last_run); + } + +} diff --git a/core/modules/system/src/Tests/System/SystemAuthorizeTest.php b/core/modules/system/tests/src/Functional/System/SystemAuthorizeTest.php similarity index 75% rename from core/modules/system/src/Tests/System/SystemAuthorizeTest.php rename to core/modules/system/tests/src/Functional/System/SystemAuthorizeTest.php index 5e278d72..b3f9b310 100644 --- a/core/modules/system/src/Tests/System/SystemAuthorizeTest.php +++ b/core/modules/system/tests/src/Functional/System/SystemAuthorizeTest.php @@ -1,28 +1,28 @@ drupalLogin ($this->drupalCreateUser(array('administer software updates'))); + $this->drupalLogin($this->drupalCreateUser(['administer software updates'])); } /** @@ -36,17 +36,17 @@ protected function setUp() { * * @see system_authorized_init() */ - function drupalGetAuthorizePHP($page_title = 'system-test-auth') { + public function drupalGetAuthorizePHP($page_title = 'system-test-auth') { $this->drupalGet('system-test/authorize-init/' . $page_title); } /** * Tests the FileTransfer hooks */ - function testFileTransferHooks() { + public function testFileTransferHooks() { $page_title = $this->randomMachineName(16); $this->drupalGetAuthorizePHP($page_title); - $this->assertTitle(strtr('@title | Drupal', array('@title' => $page_title)), 'authorize.php page title is correct.'); + $this->assertTitle(strtr('@title | Drupal', ['@title' => $page_title]), 'authorize.php page title is correct.'); $this->assertNoText('It appears you have reached this page in error.'); $this->assertText('To continue, provide your server connection details'); // Make sure we see the new connection method added by system_test. diff --git a/core/modules/system/src/Tests/System/TokenScanTest.php b/core/modules/system/tests/src/Functional/System/TokenScanTest.php similarity index 89% rename from core/modules/system/src/Tests/System/TokenScanTest.php rename to core/modules/system/tests/src/Functional/System/TokenScanTest.php index 89f2abda..f284aa97 100644 --- a/core/modules/system/src/Tests/System/TokenScanTest.php +++ b/core/modules/system/tests/src/Functional/System/TokenScanTest.php @@ -1,20 +1,20 @@ drupalCreateUser(array( + $admin_user = $this->drupalCreateUser([ 'administer site configuration', - )); + ]); $this->drupalLogin($admin_user); } @@ -39,10 +39,10 @@ public function testStatusPageWithoutConfiguration() { * Tests that the status page shows the trusted patterns from settings.php. */ public function testStatusPageWithConfiguration() { - $settings['settings']['trusted_host_patterns'] = (object) array( - 'value' => array('^' . preg_quote(\Drupal::request()->getHost()) . '$'), + $settings['settings']['trusted_host_patterns'] = (object) [ + 'value' => ['^' . preg_quote(\Drupal::request()->getHost()) . '$'], 'required' => TRUE, - ); + ]; $this->writeSettings($settings); @@ -63,10 +63,10 @@ public function testFakeRequests() { $this->container->get('router.builder')->rebuild(); $host = $this->container->get('request_stack')->getCurrentRequest()->getHost(); - $settings['settings']['trusted_host_patterns'] = (object) array( - 'value' => array('^' . preg_quote($host) . '$'), + $settings['settings']['trusted_host_patterns'] = (object) [ + 'value' => ['^' . preg_quote($host) . '$'], 'required' => TRUE, - ); + ]; $this->writeSettings($settings); diff --git a/core/modules/system/tests/src/Functional/Theme/EngineNyanCatTest.php b/core/modules/system/tests/src/Functional/Theme/EngineNyanCatTest.php new file mode 100644 index 00000000..6dca1b38 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Theme/EngineNyanCatTest.php @@ -0,0 +1,37 @@ +install(['test_theme_nyan_cat_engine']); + } + + /** + * Ensures a theme's template is overridable based on the 'template' filename. + */ + public function testTemplateOverride() { + $this->config('system.theme') + ->set('default', 'test_theme_nyan_cat_engine') + ->save(); + $this->drupalGet('theme-test/template-test'); + $this->assertText('Success: Template overridden with Nyan Cat theme. All of them', 'Template overridden by Nyan Cat file.'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Theme/FastTest.php b/core/modules/system/tests/src/Functional/Theme/FastTest.php new file mode 100644 index 00000000..d8f85f1f --- /dev/null +++ b/core/modules/system/tests/src/Functional/Theme/FastTest.php @@ -0,0 +1,36 @@ +account = $this->drupalCreateUser(['access user profiles']); + } + + /** + * Tests access to user autocompletion and verify the correct results. + */ + public function testUserAutocomplete() { + $this->drupalLogin($this->account); + $this->drupalGet('user/autocomplete', ['query' => ['q' => $this->account->getUsername()]]); + $this->assertRaw($this->account->getUsername()); + $this->assertNoText('registry initialized', 'The registry was not initialized'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Theme/ThemeEarlyInitializationTest.php b/core/modules/system/tests/src/Functional/Theme/ThemeEarlyInitializationTest.php new file mode 100644 index 00000000..040dfabf --- /dev/null +++ b/core/modules/system/tests/src/Functional/Theme/ThemeEarlyInitializationTest.php @@ -0,0 +1,34 @@ +drupalGet('theme-test/request-listener'); + // Verify that themed output generated in the request listener appears. + $this->assertRaw('Themed output generated in a KernelEvents::REQUEST listener'); + // Verify that the default theme's CSS still appears even though the theme + // system was initialized early. + $this->assertRaw('classy/css/components/action-links.css'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php b/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php new file mode 100644 index 00000000..e372bb26 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php @@ -0,0 +1,102 @@ +themeHandler = $this->container->get('theme_handler'); + $this->themeManager = $this->container->get('theme.manager'); + $this->state = $this->container->get('state'); + } + + /** + * Tests stylesheets-remove. + */ + public function testStylesheets() { + $this->themeHandler->install(['test_basetheme', 'test_subtheme']); + $this->config('system.theme') + ->set('default', 'test_subtheme') + ->save(); + + $base = drupal_get_path('theme', 'test_basetheme'); + $sub = drupal_get_path('theme', 'test_subtheme') . '/css'; + + // All removals are expected to be based on a file's path and name and + // should work nevertheless. + $this->drupalGet('theme-test/info/stylesheets'); + + $this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$base/base-add.css"])), "$base/base-add.css found"); + $this->assertIdentical(0, count($this->xpath('//link[contains(@href, :href)]', [':href' => "base-remove.css"])), "base-remove.css not found"); + + $this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$sub/sub-add.css"])), "$sub/sub-add.css found"); + $this->assertIdentical(0, count($this->xpath('//link[contains(@href, :href)]', [':href' => "sub-remove.css"])), "sub-remove.css not found"); + $this->assertIdentical(0, count($this->xpath('//link[contains(@href, :href)]', [':href' => "base-add.sub-remove.css"])), "base-add.sub-remove.css not found"); + + // Verify that CSS files with the same name are loaded from both the base theme and subtheme. + $this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$base/samename.css"])), "$base/samename.css found"); + $this->assertIdentical(1, count($this->xpath('//link[contains(@href, :href)]', [':href' => "$sub/samename.css"])), "$sub/samename.css found"); + + } + + /** + * Tests that changes to the info file are picked up. + */ + public function testChanges() { + $this->themeHandler->install(['test_theme']); + $this->config('system.theme')->set('default', 'test_theme')->save(); + $this->themeManager->resetActiveTheme(); + + $active_theme = $this->themeManager->getActiveTheme(); + // Make sure we are not testing the wrong theme. + $this->assertEqual('test_theme', $active_theme->getName()); + $this->assertEqual(['classy/base', 'classy/messages', 'core/normalize', 'test_theme/global-styling'], $active_theme->getLibraries()); + + // @see theme_test_system_info_alter() + $this->state->set('theme_test.modify_info_files', TRUE); + drupal_flush_all_caches(); + $active_theme = $this->themeManager->getActiveTheme(); + $this->assertEqual(['classy/base', 'classy/messages', 'core/normalize', 'test_theme/global-styling', 'core/backbone'], $active_theme->getLibraries()); + } + +} diff --git a/core/modules/system/src/Tests/Theme/ThemeTokenTest.php b/core/modules/system/tests/src/Functional/Theme/ThemeTokenTest.php similarity index 92% rename from core/modules/system/src/Tests/Theme/ThemeTokenTest.php rename to core/modules/system/tests/src/Functional/Theme/ThemeTokenTest.php index c3b1f8c6..1488c5b3 100644 --- a/core/modules/system/src/Tests/Theme/ThemeTokenTest.php +++ b/core/modules/system/tests/src/Functional/Theme/ThemeTokenTest.php @@ -1,15 +1,15 @@ install(array('test_theme')); + \Drupal::service('theme_handler')->install(['test_theme']); } /** * Tests that the provided Twig extension loads the service appropriately. */ - function testTwigExtensionLoaded() { + public function testTwigExtensionLoaded() { $twigService = \Drupal::service('twig'); $ext = $twigService->getExtension('twig_extension_test.test_extension'); $this->assertEqual(get_class($ext), 'Drupal\twig_extension_test\TwigExtension\TestExtension', 'TestExtension loaded successfully.'); @@ -35,7 +35,7 @@ function testTwigExtensionLoaded() { /** * Tests that the Twig extension's filter produces expected output. */ - function testTwigExtensionFilter() { + public function testTwigExtensionFilter() { $this->config('system.theme') ->set('default', 'test_theme') ->save(); @@ -49,7 +49,7 @@ function testTwigExtensionFilter() { /** * Tests that the Twig extension's function produces expected output. */ - function testTwigExtensionFunction() { + public function testTwigExtensionFunction() { $this->config('system.theme') ->set('default', 'test_theme') ->save(); diff --git a/core/modules/system/tests/src/Functional/Theme/TwigLoaderTest.php b/core/modules/system/tests/src/Functional/Theme/TwigLoaderTest.php new file mode 100644 index 00000000..d2b0b546 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Theme/TwigLoaderTest.php @@ -0,0 +1,34 @@ +loadTemplate('kittens'); + $this->assertEqual($template->render([]), 'kittens', 'Passing "kittens" to the custom Twig loader returns "kittens".'); + + $template = $environment->loadTemplate('meow'); + $this->assertEqual($template->render([]), 'cats', 'Passing something other than "kittens" to the custom Twig loader returns "cats".'); + } + +} diff --git a/core/modules/system/src/Tests/Theme/TwigRegistryLoaderTest.php b/core/modules/system/tests/src/Functional/Theme/TwigRegistryLoaderTest.php similarity index 89% rename from core/modules/system/src/Tests/Theme/TwigRegistryLoaderTest.php rename to core/modules/system/tests/src/Functional/Theme/TwigRegistryLoaderTest.php index 5cbca9f3..24462899 100644 --- a/core/modules/system/src/Tests/Theme/TwigRegistryLoaderTest.php +++ b/core/modules/system/tests/src/Functional/Theme/TwigRegistryLoaderTest.php @@ -1,22 +1,22 @@ install(array('test_theme_twig_registry_loader', 'test_theme_twig_registry_loader_theme', 'test_theme_twig_registry_loader_subtheme')); + \Drupal::service('theme_handler')->install(['test_theme_twig_registry_loader', 'test_theme_twig_registry_loader_theme', 'test_theme_twig_registry_loader_subtheme']); $this->twig = \Drupal::service('twig'); } diff --git a/core/modules/system/src/Tests/Theme/TwigSettingsTest.php b/core/modules/system/tests/src/Functional/Theme/TwigSettingsTest.php similarity index 91% rename from core/modules/system/src/Tests/Theme/TwigSettingsTest.php rename to core/modules/system/tests/src/Functional/Theme/TwigSettingsTest.php index b776639f..0ad88ce3 100644 --- a/core/modules/system/src/Tests/Theme/TwigSettingsTest.php +++ b/core/modules/system/tests/src/Functional/Theme/TwigSettingsTest.php @@ -1,8 +1,8 @@ container->getParameter('twig.config'); $parameters['auto_reload'] = TRUE; @@ -44,7 +44,7 @@ function testTwigAutoReloadOverride() { /** * Ensures Twig engine debug setting can be overridden. */ - function testTwigDebugOverride() { + public function testTwigDebugOverride() { // Enable debug and rebuild the service container. $parameters = $this->container->getParameter('twig.config'); $parameters['debug'] = TRUE; @@ -74,11 +74,11 @@ function testTwigDebugOverride() { /** * Ensures Twig template cache setting can be overridden. */ - function testTwigCacheOverride() { + public function testTwigCacheOverride() { $extension = twig_extension(); $theme_handler = $this->container->get('theme_handler'); - $theme_handler->install(array('test_theme')); - $theme_handler->setDefault('test_theme'); + $theme_handler->install(['test_theme']); + $this->config('system.theme')->set('default', 'test_theme')->save(); // The registry still works on theme globals, so set them here. \Drupal::theme()->setActiveTheme(\Drupal::service('theme.initialization')->getActiveThemeByName('test_theme')); diff --git a/core/modules/system/src/Tests/Update/AutomatedCronUpdateWithAutomatedCronTest.php b/core/modules/system/tests/src/Functional/Update/AutomatedCronUpdateWithAutomatedCronTest.php similarity index 77% rename from core/modules/system/src/Tests/Update/AutomatedCronUpdateWithAutomatedCronTest.php rename to core/modules/system/tests/src/Functional/Update/AutomatedCronUpdateWithAutomatedCronTest.php index a2f480ed..50926c93 100644 --- a/core/modules/system/src/Tests/Update/AutomatedCronUpdateWithAutomatedCronTest.php +++ b/core/modules/system/tests/src/Functional/Update/AutomatedCronUpdateWithAutomatedCronTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/tests/src/Functional/Update/AutomatedCronUpdateWithoutAutomatedCronTest.php b/core/modules/system/tests/src/Functional/Update/AutomatedCronUpdateWithoutAutomatedCronTest.php new file mode 100644 index 00000000..d4ac7118 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/AutomatedCronUpdateWithoutAutomatedCronTest.php @@ -0,0 +1,33 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.without_automated_cron.php', + ]; + } + + /** + * Ensures that automated cron module isn't installed and the config migrated. + */ + public function testUpdate() { + $this->runUpdates(); + $module_data = \Drupal::config('core.extension')->get('module'); + $this->assertFalse(isset($module_data['automated_cron']), 'The automated cron module was not installed.'); + } + +} diff --git a/core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php b/core/modules/system/tests/src/Functional/Update/ConfigOverridesUpdateTest.php similarity index 89% rename from core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/ConfigOverridesUpdateTest.php index 6efa3182..bab7d494 100644 --- a/core/modules/system/src/Tests/Update/ConfigOverridesUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/ConfigOverridesUpdateTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.filled.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/drupal-8.config-override-fix.php', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.config-override-fix.php', ]; } diff --git a/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php b/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php new file mode 100644 index 00000000..55f3a04a --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/DbUpdatesTrait.php @@ -0,0 +1,56 @@ +container->get('state')->set($module . '.db_updates.' . $group, $index); + } + + /** + * Applies any pending DB updates through the Update UI. + */ + protected function applyUpdates() { + $this->drupalGet(Url::fromRoute('system.db_update')); + $this->clickLink($this->t('Continue')); + $this->clickLink($this->t('Apply pending updates')); + $this->checkForMetaRefresh(); + } + + /** + * Conditionally load Update API functions for the specified group. + * + * @param string $module + * The name of the module defining the update functions. + * @param string $group + * A name identifying the group of update functions to enable. + */ + public static function includeUpdates($module, $group) { + if ($index = \Drupal::state()->get($module . '.db_updates.' . $group)) { + module_load_include('inc', $module, 'update/' . $group . '_' . $index); + } + } + +} diff --git a/core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php b/core/modules/system/tests/src/Functional/Update/DependencyHookInvocationTest.php similarity index 80% rename from core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php rename to core/modules/system/tests/src/Functional/Update/DependencyHookInvocationTest.php index a9723c23..8ff7b883 100644 --- a/core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php +++ b/core/modules/system/tests/src/Functional/Update/DependencyHookInvocationTest.php @@ -1,8 +1,8 @@ assertTrue($update_dependencies['update_test_0'][8001]['update_test_1'] == 8001, 'An update function that has a dependency on two separate modules has the first dependency recorded correctly.'); $this->assertTrue($update_dependencies['update_test_0'][8001]['update_test_2'] == 8002, 'An update function that has a dependency on two separate modules has the second dependency recorded correctly.'); diff --git a/core/modules/system/src/Tests/Update/DependencyMissingTest.php b/core/modules/system/tests/src/Functional/Update/DependencyMissingTest.php similarity index 79% rename from core/modules/system/src/Tests/Update/DependencyMissingTest.php rename to core/modules/system/tests/src/Functional/Update/DependencyMissingTest.php index 9764b4c8..6ae4dc40 100644 --- a/core/modules/system/src/Tests/Update/DependencyMissingTest.php +++ b/core/modules/system/tests/src/Functional/Update/DependencyMissingTest.php @@ -1,22 +1,22 @@ 8001, - ); + ]; $update_graph = update_resolve_dependencies($starting_updates); $this->assertTrue($update_graph['update_test_2_update_8001']['allowed'], "The module's first update function is allowed to run, since it does not have any missing dependencies."); $this->assertFalse($update_graph['update_test_2_update_8002']['allowed'], "The module's second update function is not allowed to run, since it has a direct dependency on a missing update."); diff --git a/core/modules/system/src/Tests/Update/DependencyOrderingTest.php b/core/modules/system/tests/src/Functional/Update/DependencyOrderingTest.php similarity index 78% rename from core/modules/system/src/Tests/Update/DependencyOrderingTest.php rename to core/modules/system/tests/src/Functional/Update/DependencyOrderingTest.php index bb3ae371..8cafaadd 100644 --- a/core/modules/system/src/Tests/Update/DependencyOrderingTest.php +++ b/core/modules/system/tests/src/Functional/Update/DependencyOrderingTest.php @@ -1,22 +1,22 @@ 8001, - ); - $expected_updates = array( + ]; + $expected_updates = [ 'update_test_1_update_8001', 'update_test_1_update_8002', 'update_test_1_update_8003', - ); + ]; $actual_updates = array_keys(update_resolve_dependencies($starting_updates)); $this->assertEqual($expected_updates, $actual_updates, 'Updates within a single module run in the correct order.'); } @@ -42,11 +42,11 @@ function testUpdateOrderingSingleModule() { /** * Test that dependencies between modules are resolved correctly. */ - function testUpdateOrderingModuleInterdependency() { - $starting_updates = array( + public function testUpdateOrderingModuleInterdependency() { + $starting_updates = [ 'update_test_2' => 8001, 'update_test_3' => 8001, - ); + ]; $update_order = array_keys(update_resolve_dependencies($starting_updates)); // Make sure that each dependency is satisfied. $first_dependency_satisfied = array_search('update_test_2_update_8001', $update_order) < array_search('update_test_3_update_8001', $update_order); diff --git a/core/modules/system/tests/src/Functional/Update/EntityUpdateAddRevisionTranslationAffectedTest.php b/core/modules/system/tests/src/Functional/Update/EntityUpdateAddRevisionTranslationAffectedTest.php new file mode 100644 index 00000000..f7dcd0c4 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/EntityUpdateAddRevisionTranslationAffectedTest.php @@ -0,0 +1,89 @@ +entityManager = \Drupal::entityManager(); + $this->lastInstalledSchemaRepository = \Drupal::service('entity.last_installed_schema.repository'); + $this->state = \Drupal::state(); + } + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul_rev.php.gz', + ]; + } + + /** + * Tests the addition of the 'revision_translation_affected' base field. + * + * @see system_update_8402() + */ + public function testAddingTheRevisionTranslationAffectedField() { + // Make the entity type revisionable and translatable prior to running the + // updates. + $this->updateEntityTypeToRevisionableAndTranslatable(); + + // Check that the test entity type does not have the + // 'revision_translation_affected' field before running the updates. + $field_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update'); + $this->assertFalse(isset($field_storage_definitions['revision_translation_affected'])); + + $this->runUpdates(); + + // Check that the 'revision_translation_affected' field has been added by + // system_update_8402(). + $field_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update'); + $this->assertTrue(isset($field_storage_definitions['revision_translation_affected'])); + + // Check that the correct initial value was set when the field was + // installed. + $entity = $this->entityManager->getStorage('entity_test_update')->load(1); + $this->assertTrue($entity->revision_translation_affected->value); + } + +} diff --git a/core/modules/system/tests/src/Functional/Update/EntityUpdateToRevisionableAndPublishableTest.php b/core/modules/system/tests/src/Functional/Update/EntityUpdateToRevisionableAndPublishableTest.php new file mode 100644 index 00000000..eb4a01c9 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/EntityUpdateToRevisionableAndPublishableTest.php @@ -0,0 +1,219 @@ +entityTypeManager = \Drupal::entityTypeManager(); + $this->entityDefinitionUpdateManager = \Drupal::entityDefinitionUpdateManager(); + $this->lastInstalledSchemaRepository = \Drupal::service('entity.last_installed_schema.repository'); + $this->installedStorageSchema = \Drupal::keyValue('entity.storage_schema.sql'); + $this->state = \Drupal::state(); + } + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz', + __DIR__ . '/../../../fixtures/update/drupal-8.entity-test-schema-converter-enabled.php', + ]; + } + + /** + * Tests the conversion of an entity type to revisionable and publishable. + * + * @see entity_test_update_update_8400() + */ + public function testConvertToRevisionableAndPublishable() { + // Check that entity type is not revisionable nor publishable prior to + // running the update process. + $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update'); + $this->assertFalse($entity_test_update->isRevisionable()); + $this->assertFalse($entity_test_update->getKey('published')); + + // Make the entity type revisionable, translatable and publishable. + $this->updateEntityTypeDefinition(); + + $this->enableUpdates('entity_test_update', 'entity_rev_pub_updates', 8400); + $this->runUpdates(); + + /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_test_update */ + $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update'); + $this->assertTrue($entity_test_update->isRevisionable()); + $this->assertEqual('status', $entity_test_update->getKey('published')); + + /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */ + $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update'); + $this->assertEqual(count($storage->loadMultiple()), 102, 'All test entities were found.'); + + // The conversion to revisionable is already tested by + // \Drupal\system\Tests\Entity\Update\SqlContentEntityStorageSchemaConverterTest::testMakeRevisionable() + // so we only need to check that some special cases are handled. + // All the checks implemented here are taking into consideration the special + // conditions in which the test database was created. + // @see _entity_test_update_create_test_entities() + + // The test entity with ID 50 was created before Content Translation was + // enabled, which means it didn't have a 'content_translation_status' field. + // content_translation_update_8400() added values for that field which + // should now be reflected in the entity's 'status' field. + /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */ + $revision = $storage->loadRevision(50); + $this->assertEqual(1, $revision->status->value); + + $translation = $revision->getTranslation('ro'); + $this->assertEqual(1, $translation->status->value); + + // The test entity with ID 100 was created with Content Translation enabled + // and it should have the same values as entity 50. + $revision = $storage->loadRevision(100); + $this->assertEqual(1, $revision->status->value); + + $translation = $revision->getTranslation('ro'); + $this->assertEqual(1, $translation->status->value); + + // The test entity 101 had 'content_translation_status' set to 0 for the + // English (source) language. + $revision = $storage->loadRevision(101); + $this->assertEqual(0, $revision->status->value); + + $translation = $revision->getTranslation('ro'); + $this->assertEqual(1, $translation->status->value); + + // The test entity 102 had 'content_translation_status' set to 0 for the + // Romanian language. + $revision = $storage->loadRevision(102); + $this->assertEqual(1, $revision->status->value); + + $translation = $revision->getTranslation('ro'); + $this->assertEqual(0, $translation->status->value); + } + + /** + * Updates the 'entity_test_update' entity type to revisionable, + * translatable, publishable and adds revision metadata keys. + */ + protected function updateEntityTypeDefinition() { + $entity_type = clone $this->entityTypeManager->getDefinition('entity_test_update'); + + $keys = $entity_type->getKeys(); + $keys['revision'] = 'revision_id'; + $keys['published'] = 'status'; + $entity_type->set('entity_keys', $keys); + + $revision_metadata_keys = [ + 'revision_user' => 'revision_user', + 'revision_created' => 'revision_created', + 'revision_log_message' => 'revision_log_message' + ]; + $entity_type->set('revision_metadata_keys', $revision_metadata_keys); + + + $entity_type->set('translatable', TRUE); + $entity_type->set('data_table', 'entity_test_update_data'); + $entity_type->set('revision_table', 'entity_test_update_revision'); + $entity_type->set('revision_data_table', 'entity_test_update_revision_data'); + + $this->state->set('entity_test_update.entity_type', $entity_type); + + // Also add the status and revision metadata base fields to the entity type. + $status = BaseFieldDefinition::create('boolean') + ->setLabel(t('Publishing status')) + ->setDescription(t('A boolean indicating the published state.')) + ->setRevisionable(TRUE) + ->setTranslatable(TRUE) + ->setRequired(TRUE) + ->setDefaultValue(TRUE); + + $revision_created = BaseFieldDefinition::create('created') + ->setLabel(t('Revision create time')) + ->setDescription(t('The time that the current revision was created.')) + ->setRevisionable(TRUE); + + $revision_user = BaseFieldDefinition::create('entity_reference') + ->setLabel(t('Revision user')) + ->setDescription(t('The user ID of the author of the current revision.')) + ->setSetting('target_type', 'user') + ->setRevisionable(TRUE); + + $revision_log_message = BaseFieldDefinition::create('string_long') + ->setLabel(t('Revision log message')) + ->setDescription(t('Briefly describe the changes you have made.')) + ->setRevisionable(TRUE) + ->setDefaultValue('') + ->setDisplayOptions('form', [ + 'type' => 'string_textarea', + 'weight' => 25, + 'settings' => [ + 'rows' => 4, + ], + ]); + + $this->state->set('entity_test_update.additional_base_field_definitions', [ + 'status' => $status, + 'revision_created' => $revision_created, + 'revision_user' => $revision_user, + 'revision_log_message' => $revision_log_message, + ]); + + $this->entityTypeManager->clearCachedDefinitions(); + } + +} diff --git a/core/modules/system/src/Tests/Update/FieldSchemaDataUninstallUpdateTest.php b/core/modules/system/tests/src/Functional/Update/FieldSchemaDataUninstallUpdateTest.php similarity index 77% rename from core/modules/system/src/Tests/Update/FieldSchemaDataUninstallUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/FieldSchemaDataUninstallUpdateTest.php index 6c5d2f24..782e3410 100644 --- a/core/modules/system/src/Tests/Update/FieldSchemaDataUninstallUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/FieldSchemaDataUninstallUpdateTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.block-content-uninstall.php', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.field-schema-data-uninstall-2573667.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.block-content-uninstall.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.field-schema-data-uninstall-2573667.php', ]; } diff --git a/core/modules/system/src/Tests/Update/FilterHtmlUpdateTest.php b/core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php similarity index 89% rename from core/modules/system/src/Tests/Update/FilterHtmlUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php index 892b279b..09e40aa9 100644 --- a/core/modules/system/src/Tests/Update/FilterHtmlUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/FilterHtmlUpdateTest.php @@ -1,8 +1,9 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/tests/src/Functional/Update/InstallProfileSystemInstall8300Test.php b/core/modules/system/tests/src/Functional/Update/InstallProfileSystemInstall8300Test.php new file mode 100644 index 00000000..623f8804 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/InstallProfileSystemInstall8300Test.php @@ -0,0 +1,41 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + } + + /** + * Ensures that the system_update_8300() runs as expected. + */ + public function testUpdate() { + // Ensure the BC layers work and settings.php and configuration is in the + // expected state before updating. + $this->assertEqual('standard', \Drupal::installProfile()); + $this->assertEqual('standard', Settings::get('install_profile'), 'The install profile has not been written to settings.php.'); + $this->assertFalse($this->config('core.extension')->get('profile'), 'The install profile is not present in core.extension configuration.'); + + $this->runUpdates(); + // Confirm that Drupal recognizes this distribution as the current profile. + $this->assertEqual('standard', \Drupal::installProfile()); + $this->assertEqual('standard', Settings::get('install_profile'), 'The install profile has not been written to settings.php.'); + $this->assertEqual('standard', $this->config('core.extension')->get('profile'), 'The install profile has been written to core.extension configuration.'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php b/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php new file mode 100644 index 00000000..44d4832d --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/InvalidUpdateHookTest.php @@ -0,0 +1,52 @@ +updateUrl = $GLOBALS['base_url'] . '/update.php'; + $this->updateUser = $this->drupalCreateUser(['administer software updates']); + } + + public function testInvalidUpdateHook() { + // Confirm that a module with hook_update_8000() cannot be updated. + $this->drupalLogin($this->updateUser); + $this->drupalGet($this->updateUrl); + $this->clickLink(t('Continue')); + $this->assertText(t('Some of the pending updates cannot be applied because their dependencies were not met.')); + } + +} diff --git a/core/modules/system/src/Tests/Update/LocalActionsAndTasksConvertedIntoBlocksUpdateTest.php b/core/modules/system/tests/src/Functional/Update/LocalActionsAndTasksConvertedIntoBlocksUpdateTest.php similarity index 90% rename from core/modules/system/src/Tests/Update/LocalActionsAndTasksConvertedIntoBlocksUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/LocalActionsAndTasksConvertedIntoBlocksUpdateTest.php index ee47a81d..a54bb6d1 100644 --- a/core/modules/system/src/Tests/Update/LocalActionsAndTasksConvertedIntoBlocksUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/LocalActionsAndTasksConvertedIntoBlocksUpdateTest.php @@ -1,7 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.local-actions-tasks-into-blocks-507488.php', ]; } diff --git a/core/modules/system/tests/src/Functional/Update/MenuTreeSerializationTitleFilledTest.php b/core/modules/system/tests/src/Functional/Update/MenuTreeSerializationTitleFilledTest.php new file mode 100644 index 00000000..5bf07d84 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/MenuTreeSerializationTitleFilledTest.php @@ -0,0 +1,20 @@ +databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz'; + } + +} diff --git a/core/modules/system/src/Tests/Update/MenuTreeSerializationTitleTest.php b/core/modules/system/tests/src/Functional/Update/MenuTreeSerializationTitleTest.php similarity index 90% rename from core/modules/system/src/Tests/Update/MenuTreeSerializationTitleTest.php rename to core/modules/system/tests/src/Functional/Update/MenuTreeSerializationTitleTest.php index cc019dc2..0df71482 100644 --- a/core/modules/system/src/Tests/Update/MenuTreeSerializationTitleTest.php +++ b/core/modules/system/tests/src/Functional/Update/MenuTreeSerializationTitleTest.php @@ -1,8 +1,9 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/src/Tests/Update/PageTitleConvertedIntoBlockUpdateTest.php b/core/modules/system/tests/src/Functional/Update/PageTitleConvertedIntoBlockUpdateTest.php similarity index 87% rename from core/modules/system/src/Tests/Update/PageTitleConvertedIntoBlockUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/PageTitleConvertedIntoBlockUpdateTest.php index 6a81566e..2f7306a7 100644 --- a/core/modules/system/src/Tests/Update/PageTitleConvertedIntoBlockUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/PageTitleConvertedIntoBlockUpdateTest.php @@ -1,7 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.page-title-into-block-2476947.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.page-title-into-block-2476947.php', ]; } diff --git a/core/modules/system/src/Tests/Update/RecalculatedDependencyTest.php b/core/modules/system/tests/src/Functional/Update/RecalculatedDependencyTest.php similarity index 92% rename from core/modules/system/src/Tests/Update/RecalculatedDependencyTest.php rename to core/modules/system/tests/src/Functional/Update/RecalculatedDependencyTest.php index 56a010c0..6eb51a2a 100644 --- a/core/modules/system/src/Tests/Update/RecalculatedDependencyTest.php +++ b/core/modules/system/tests/src/Functional/Update/RecalculatedDependencyTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/tests/src/Functional/Update/RemoveResponseGzipFromSystemPerformanceConfigurationTest.php b/core/modules/system/tests/src/Functional/Update/RemoveResponseGzipFromSystemPerformanceConfigurationTest.php new file mode 100644 index 00000000..b2ccfe67 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/RemoveResponseGzipFromSystemPerformanceConfigurationTest.php @@ -0,0 +1,38 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + } + + /** + * Ensures that response.gzip is removed from system.performance + * configuration. + */ + public function testUpdate() { + \Drupal::configFactory()->getEditable('system.performance') + ->set('response.gzip', 1) + ->save(); + + $this->runUpdates(); + + $system_performance = \Drupal::config('system.performance')->get(); + $this->assertFalse(isset($system_performance['response.gzip']), 'Configuration response.gzip has been removed from system.performance.'); + } + +} diff --git a/core/modules/system/tests/src/Functional/Update/RouterIndexOptimizationFilledTest.php b/core/modules/system/tests/src/Functional/Update/RouterIndexOptimizationFilledTest.php new file mode 100644 index 00000000..afb48108 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/RouterIndexOptimizationFilledTest.php @@ -0,0 +1,20 @@ +databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz'; + } + +} diff --git a/core/modules/system/src/Tests/Update/RouterIndexOptimizationTest.php b/core/modules/system/tests/src/Functional/Update/RouterIndexOptimizationTest.php similarity index 78% rename from core/modules/system/src/Tests/Update/RouterIndexOptimizationTest.php rename to core/modules/system/tests/src/Functional/Update/RouterIndexOptimizationTest.php index 0bede3a2..a3bfad25 100644 --- a/core/modules/system/src/Tests/Update/RouterIndexOptimizationTest.php +++ b/core/modules/system/tests/src/Functional/Update/RouterIndexOptimizationTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', ]; } diff --git a/core/modules/system/src/Tests/Update/SevenSecondaryLocalTasksConvertedIntoBlockUpdateTest.php b/core/modules/system/tests/src/Functional/Update/SevenSecondaryLocalTasksConvertedIntoBlockUpdateTest.php similarity index 82% rename from core/modules/system/src/Tests/Update/SevenSecondaryLocalTasksConvertedIntoBlockUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/SevenSecondaryLocalTasksConvertedIntoBlockUpdateTest.php index b61cf20d..341b37be 100644 --- a/core/modules/system/src/Tests/Update/SevenSecondaryLocalTasksConvertedIntoBlockUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/SevenSecondaryLocalTasksConvertedIntoBlockUpdateTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.seven-secondary-local-tasks-block-2569529.php', ]; } diff --git a/core/modules/system/src/Tests/Update/SiteBrandingConvertedIntoBlockUpdateTest.php b/core/modules/system/tests/src/Functional/Update/SiteBrandingConvertedIntoBlockUpdateTest.php similarity index 86% rename from core/modules/system/src/Tests/Update/SiteBrandingConvertedIntoBlockUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/SiteBrandingConvertedIntoBlockUpdateTest.php index c60c2b0d..d904e10e 100644 --- a/core/modules/system/src/Tests/Update/SiteBrandingConvertedIntoBlockUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/SiteBrandingConvertedIntoBlockUpdateTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.site-branding-into-block-2005546.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.site-branding-into-block-2005546.php', ]; } diff --git a/core/modules/system/src/Tests/Update/StableBaseThemeUpdateTest.php b/core/modules/system/tests/src/Functional/Update/StableBaseThemeUpdateTest.php similarity index 78% rename from core/modules/system/src/Tests/Update/StableBaseThemeUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/StableBaseThemeUpdateTest.php index b71d47bf..326bbbb9 100644 --- a/core/modules/system/src/Tests/Update/StableBaseThemeUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/StableBaseThemeUpdateTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.stable-base-theme-2575421.php', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.stable-base-theme-2575421.php', ]; } diff --git a/core/modules/system/tests/src/Functional/Update/UpdateEntityDisplayTest.php b/core/modules/system/tests/src/Functional/Update/UpdateEntityDisplayTest.php new file mode 100644 index 00000000..698d3310 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/UpdateEntityDisplayTest.php @@ -0,0 +1,50 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + } + + /** + * Tests that entity displays are updated with regions for their fields. + */ + public function testUpdate() { + // No region key appears pre-update. + $entity_form_display = EntityFormDisplay::load('node.article.default'); + $options = $entity_form_display->getComponent('body'); + $this->assertFalse(array_key_exists('region', $options)); + + $entity_view_display = EntityViewDisplay::load('node.article.default'); + $options = $entity_view_display->getComponent('body'); + $this->assertFalse(array_key_exists('region', $options)); + + $this->runUpdates(); + + // The region key has been populated with 'content'. + $entity_form_display = EntityFormDisplay::load('node.article.default'); + $options = $entity_form_display->getComponent('body'); + $this->assertIdentical('content', $options['region']); + + $entity_view_display = EntityViewDisplay::load('node.article.default'); + $options = $entity_view_display->getComponent('body'); + $this->assertIdentical('content', $options['region']); + } + +} diff --git a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathRC1TestBaseFilledTest.php similarity index 97% rename from core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php rename to core/modules/system/tests/src/Functional/Update/UpdatePathRC1TestBaseFilledTest.php index eb95fce6..7573fc4a 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdatePathRC1TestBaseFilledTest.php @@ -1,6 +1,6 @@ databaseDumpFiles[0] = __DIR__ . '/../../../tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz'; + $this->databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz'; } /** @@ -29,13 +29,13 @@ public function testUpdatedSite() { $spanish = \Drupal::languageManager()->getLanguage('es'); - $expected_node_data = array( + $expected_node_data = [ [1, 'article', 'en', 'Test Article - New title'], [2, 'book', 'en', 'Book page'], [3, 'forum', 'en', 'Forum topic'], [4, 'page', 'en', 'Test page'], [8, 'test_content_type', 'en', 'Test title'], - ); + ]; foreach ($expected_node_data as $node_data) { $id = $node_data[0]; $type = $node_data[1]; @@ -89,7 +89,7 @@ public function testUpdatedSite() { // Log in as user 1. $account = User::load(1); - $account->pass_raw = 'drupal'; + $account->passRaw = 'drupal'; $this->drupalLogin($account); // Make sure we can see the access-restricted entity reference field @@ -117,7 +117,7 @@ public function testUpdatedSite() { $this->assertText('Test Article - New title'); $this->assertText('Test 1'); $this->assertRaw('0.01'); - $this->drupalPostForm('node/8/edit', [], 'Save and keep published (this translation)'); + $this->drupalPostForm('node/8/edit', [], 'Save (this translation)'); $this->assertResponse(200); $this->drupalGet('node/8/edit', ['language' => $spanish]); $this->assertText('Test title Spanish'); diff --git a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathRC1TestBaseTest.php similarity index 92% rename from core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseTest.php rename to core/modules/system/tests/src/Functional/Update/UpdatePathRC1TestBaseTest.php index a4f99e68..4077a07d 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdatePathRC1TestBaseTest.php @@ -1,8 +1,9 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz', ]; } diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathTestBaseFilledTest.php similarity index 97% rename from core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php rename to core/modules/system/tests/src/Functional/Update/UpdatePathTestBaseFilledTest.php index 6edbfe3a..2ed58fba 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdatePathTestBaseFilledTest.php @@ -1,7 +1,8 @@ databaseDumpFiles[0] = __DIR__ . '/../../../tests/fixtures/update/drupal-8.filled.standard.php.gz'; + $this->databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz'; } /** @@ -29,13 +30,13 @@ public function testUpdatedSite() { $spanish = \Drupal::languageManager()->getLanguage('es'); - $expected_node_data = array( + $expected_node_data = [ [1, 'article', 'en', 'Test Article - New title'], [2, 'book', 'en', 'Book page'], [3, 'forum', 'en', 'Forum topic'], [4, 'page', 'en', 'Test page'], [8, 'test_content_type', 'en', 'Test title'], - ); + ]; foreach ($expected_node_data as $node_data) { $id = $node_data[0]; $type = $node_data[1]; @@ -89,7 +90,7 @@ public function testUpdatedSite() { // Log in as user 1. $account = User::load(1); - $account->pass_raw = 'drupal'; + $account->passRaw = 'drupal'; $this->drupalLogin($account); // Make sure we can see the access-restricted entity reference field @@ -117,7 +118,7 @@ public function testUpdatedSite() { $this->assertText('Test Article - New title'); $this->assertText('Test 1'); $this->assertRaw('0.01'); - $this->drupalPostForm('node/8/edit', [], 'Save and keep published (this translation)'); + $this->drupalPostForm('node/8/edit', [], 'Save (this translation)'); $this->assertResponse(200); $this->drupalGet('node/8/edit', ['language' => $spanish]); $this->assertText('Test title Spanish'); diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathTestJavaScriptTest.php similarity index 79% rename from core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php rename to core/modules/system/tests/src/Functional/Update/UpdatePathTestJavaScriptTest.php index 90f3387a..e30915e7 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathTestJavaScriptTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdatePathTestJavaScriptTest.php @@ -1,6 +1,8 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', ]; } @@ -35,12 +37,12 @@ protected function doSelectionTest() { $scripts = $this->xpath('//script'); $found = FALSE; foreach ($scripts as $script) { - if (!isset($script['src'])) { + if (!$script->getAttribute('src')) { continue; } // Source is a root-relative URL. Transform it to an absolute URL to allow // file_get_contents() to access the file. - $src = preg_replace('#^' . $GLOBALS['base_path'] . '(.*)#i', $GLOBALS['base_url'] . '/' . '${1}', (string) $script['src']); + $src = preg_replace('#^' . $GLOBALS['base_path'] . '(.*)#i', $GLOBALS['base_url'] . '/' . '${1}', $script->getAttribute('src')); $file_content = file_get_contents($src); if (strpos($file_content, 'window.drupalSettings =') !== FALSE) { diff --git a/core/modules/system/tests/src/Functional/Update/UpdatePathWithBrokenRoutingFilledTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathWithBrokenRoutingFilledTest.php new file mode 100644 index 00000000..0e81ad47 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/UpdatePathWithBrokenRoutingFilledTest.php @@ -0,0 +1,20 @@ +databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz'; + } + +} diff --git a/core/modules/system/tests/src/Functional/Update/UpdatePathWithBrokenRoutingTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePathWithBrokenRoutingTest.php new file mode 100644 index 00000000..1c8493d9 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/UpdatePathWithBrokenRoutingTest.php @@ -0,0 +1,44 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.broken_routing.php', + ]; + } + + /** + * Tests running update.php with some form of broken routing. + */ + public function testWithBrokenRouting() { + // Simulate a broken router, and make sure the front page is + // inaccessible. + \Drupal::state()->set('update_script_test_broken_inbound', TRUE); + \Drupal::service('cache_tags.invalidator')->invalidateTags(['route_match', 'rendered']); + $this->drupalGet(''); + $this->assertResponse(500); + + $this->runUpdates(); + + // Remove the simulation of the broken router, and make sure we can get to + // the front page again. + \Drupal::state()->set('update_script_test_broken_inbound', FALSE); + $this->drupalGet(''); + $this->assertResponse(200); + } + +} diff --git a/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateFailingTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateFailingTest.php new file mode 100644 index 00000000..03b5d7b0 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateFailingTest.php @@ -0,0 +1,50 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.update-test-postupdate-failing-enabled.php', + ]; + } + + /** + * Tests hook_post_update_NAME(). + */ + public function testPostUpdate() { + // There are expected to be failed updates. + $this->checkFailedUpdates = FALSE; + + $this->runUpdates(); + + // There should be no post update hooks registered as being run. + $this->assertIdentical([], \Drupal::state()->get('post_update_test_execution', [])); + + $key_value = \Drupal::keyValue('update__post_update'); + $this->assertEqual([], $key_value->get('existing_updates', [])); + } + + /** + * {@inheritdoc} + */ + protected function doSelectionTest() { + // First update, should not be run since this module's update hooks fail. + $this->assertRaw('8001 - This update will fail.'); + $this->assertRaw('8002 - A further update.'); + $this->assertEscaped("First update, should not be run since this module's update hooks fail."); + } + +} diff --git a/core/modules/system/src/Tests/Update/UpdatePostUpdateTest.php b/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php similarity index 90% rename from core/modules/system/src/Tests/Update/UpdatePostUpdateTest.php rename to core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php index c50b1d45..1bba498d 100644 --- a/core/modules/system/src/Tests/Update/UpdatePostUpdateTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdatePostUpdateTest.php @@ -1,8 +1,9 @@ databaseDumpFiles = [ - __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', - __DIR__ . '/../../../tests/fixtures/update/drupal-8.update-test-postupdate-enabled.php', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.update-test-postupdate-enabled.php', ]; } diff --git a/core/modules/system/src/Tests/Update/UpdateSchemaTest.php b/core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php similarity index 91% rename from core/modules/system/src/Tests/Update/UpdateSchemaTest.php rename to core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php index 0e42c9d5..a42cbcb3 100644 --- a/core/modules/system/src/Tests/Update/UpdateSchemaTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdateSchemaTest.php @@ -1,16 +1,16 @@ assertRaw('Schema version 8001.'); // Run the update hooks. $this->clickLink(t('Apply pending updates')); + $this->checkForMetaRefresh(); // Ensure schema has changed. $this->assertEqual(drupal_get_installed_schema_version('update_test_schema', TRUE), 8001); diff --git a/core/modules/system/src/Tests/Update/UpdateScriptTest.php b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php similarity index 81% rename from core/modules/system/src/Tests/Update/UpdateScriptTest.php rename to core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php index b80ef82e..29d4d08e 100644 --- a/core/modules/system/src/Tests/Update/UpdateScriptTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php @@ -1,24 +1,24 @@ updateUrl = Url::fromRoute('system.db_update'); - $this->updateUser = $this->drupalCreateUser(array('administer software updates', 'access site in maintenance mode')); + $this->updateUser = $this->drupalCreateUser(['administer software updates', 'access site in maintenance mode']); \Drupal::service('entity.definition_update_manager')->applyUpdates(); } /** * Tests access to the update script. */ - function testUpdateAccess() { + public function testUpdateAccess() { // Try accessing update.php without the proper permission. $regular_user = $this->drupalCreateUser(); $this->drupalLogin($regular_user); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertResponse(403); // Check that a link to the update page is not accessible to regular users. @@ -62,7 +62,7 @@ function testUpdateAccess() { // Try accessing update.php as an anonymous user. $this->drupalLogout(); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertResponse(403); // Check that a link to the update page is not accessible to anonymous @@ -72,7 +72,7 @@ function testUpdateAccess() { // Access the update page with the proper permission. $this->drupalLogin($this->updateUser); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertResponse(200); // Check that a link to the update page is accessible to users with proper @@ -82,7 +82,7 @@ function testUpdateAccess() { // Access the update page as user 1. $this->drupalLogin($this->rootUser); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertResponse(200); // Check that a link to the update page is accessible to user 1. @@ -93,13 +93,13 @@ function testUpdateAccess() { /** * Tests that requirements warnings and errors are correctly displayed. */ - function testRequirements() { + public function testRequirements() { $update_script_test_config = $this->config('update_script_test.settings'); $this->drupalLogin($this->updateUser); // If there are no requirements warnings or errors, we expect to be able to // go through the update process uninterrupted. - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->assertText(t('No pending updates.'), 'End of update process was reached.'); // Confirm that all caches were cleared. @@ -113,18 +113,19 @@ function testRequirements() { // successfully. $update_script_test_config->set('requirement_type', REQUIREMENT_WARNING)->save(); drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertText('This is a requirements warning provided by the update_script_test module.'); $this->clickLink('try again'); $this->assertNoText('This is a requirements warning provided by the update_script_test module.'); $this->clickLink(t('Continue')); $this->clickLink(t('Apply pending updates')); + $this->checkForMetaRefresh(); $this->assertText(t('The update_script_test_update_8001() update was executed successfully.'), 'End of update process was reached.'); // Confirm that all caches were cleared. $this->assertText(t('hook_cache_flush() invoked for update_script_test.module.'), 'Caches were cleared after resolving a requirements warning and applying updates.'); // Now try again without pending updates to make sure that works too. - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertText('This is a requirements warning provided by the update_script_test module.'); $this->clickLink('try again'); $this->assertNoText('This is a requirements warning provided by the update_script_test module.'); @@ -137,7 +138,7 @@ function testRequirements() { // clicking the link to proceed (since the problem that triggered the error // has not been fixed). $update_script_test_config->set('requirement_type', REQUIREMENT_ERROR)->save(); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->assertText('This is a requirements error provided by the update_script_test module.'); $this->clickLink('try again'); $this->assertText('This is a requirements error provided by the update_script_test module.'); @@ -146,7 +147,7 @@ function testRequirements() { /** * Tests the effect of using the update script on the theme system. */ - function testThemeSystem() { + public function testThemeSystem() { // Since visiting update.php triggers a rebuild of the theme system from an // unusual maintenance mode environment, we check that this rebuild did not // put any incorrect information about the themes into the database. @@ -160,25 +161,25 @@ function testThemeSystem() { /** * Tests update.php when there are no updates to apply. */ - function testNoUpdateFunctionality() { + public function testNoUpdateFunctionality() { // Click through update.php with 'administer software updates' permission. $this->drupalLogin($this->updateUser); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->assertText(t('No pending updates.')); $this->assertNoLink('Administration pages'); - $this->assertNoLinkByHrefInMainRegion('update.php', 0); + $this->assertEmpty($this->xpath('//main//a[contains(@href, :href)]', [':href' => 'update.php'])); $this->clickLink('Front page'); $this->assertResponse(200); // Click through update.php with 'access administration pages' permission. - $admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages')); + $admin_user = $this->drupalCreateUser(['administer software updates', 'access administration pages']); $this->drupalLogin($admin_user); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->assertText(t('No pending updates.')); $this->assertLink('Administration pages'); - $this->assertNoLinkByHrefInMainRegion('update.php', 1); + $this->assertEmpty($this->xpath('//main//a[contains(@href, :href)]', [':href' => 'update.php'])); $this->clickLink('Administration pages'); $this->assertResponse(200); } @@ -186,10 +187,10 @@ function testNoUpdateFunctionality() { /** * Tests update.php after performing a successful update. */ - function testSuccessfulUpdateFunctionality() { + public function testSuccessfulUpdateFunctionality() { $initial_maintenance_mode = $this->container->get('state')->get('system.maintenance_mode'); $this->assertFalse($initial_maintenance_mode, 'Site is not in maintenance mode.'); - $this->updateScriptTest($initial_maintenance_mode); + $this->runUpdates($initial_maintenance_mode); $final_maintenance_mode = $this->container->get('state')->get('system.maintenance_mode'); $this->assertEqual($final_maintenance_mode, $initial_maintenance_mode, 'Maintenance mode should not have changed after database updates.'); @@ -204,15 +205,16 @@ function testSuccessfulUpdateFunctionality() { // Click through update.php with 'access administration pages' and // 'access site reports' permissions. - $admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages', 'access site reports', 'access site in maintenance mode')); + $admin_user = $this->drupalCreateUser(['administer software updates', 'access administration pages', 'access site reports', 'access site in maintenance mode']); $this->drupalLogin($admin_user); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->clickLink(t('Apply pending updates')); + $this->checkForMetaRefresh(); $this->assertText('Updates were attempted.'); $this->assertLink('logged'); $this->assertLink('Administration pages'); - $this->assertNoLinkByHrefInMainRegion('update.php', 1); + $this->assertEmpty($this->xpath('//main//a[contains(@href, :href)]', [':href' => 'update.php'])); $this->clickLink('Administration pages'); $this->assertResponse(200); } @@ -220,13 +222,13 @@ function testSuccessfulUpdateFunctionality() { /** * Tests update.php while in maintenance mode. */ - function testMaintenanceModeUpdateFunctionality() { + public function testMaintenanceModeUpdateFunctionality() { $this->container->get('state') ->set('system.maintenance_mode', TRUE); $initial_maintenance_mode = $this->container->get('state') ->get('system.maintenance_mode'); $this->assertTrue($initial_maintenance_mode, 'Site is in maintenance mode.'); - $this->updateScriptTest($initial_maintenance_mode); + $this->runUpdates($initial_maintenance_mode); $final_maintenance_mode = $this->container->get('state') ->get('system.maintenance_mode'); $this->assertEqual($final_maintenance_mode, $initial_maintenance_mode, 'Maintenance mode should not have changed after database updates.'); @@ -235,13 +237,13 @@ function testMaintenanceModeUpdateFunctionality() { /** * Tests perfoming updates with update.php in a multilingual environment. */ - function testSuccessfulMultilingualUpdateFunctionality() { + public function testSuccessfulMultilingualUpdateFunctionality() { // Add some custom languages. - foreach (array('aa', 'bb') as $language_code) { - ConfigurableLanguage::create(array( + foreach (['aa', 'bb'] as $language_code) { + ConfigurableLanguage::create([ 'id' => $language_code, 'label' => $this->randomMachineName(), - ))->save(); + ])->save(); } $config = \Drupal::service('config.factory')->getEditable('language.negotiation'); @@ -261,24 +263,25 @@ function testSuccessfulMultilingualUpdateFunctionality() { $this->assertEqual($schema_version, 8000, 'update_script_test schema version overridden to 8000.'); // Create admin user. - $admin_user = $this->drupalCreateUser(array('administer software updates', 'access administration pages', 'access site reports', 'access site in maintenance mode', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer software updates', 'access administration pages', 'access site reports', 'access site in maintenance mode', 'administer site configuration']); $this->drupalLogin($admin_user); // Visit status report page and ensure, that link to update.php has no path prefix set. - $this->drupalGet('en/admin/reports/status', array('external' => TRUE)); + $this->drupalGet('en/admin/reports/status', ['external' => TRUE]); $this->assertResponse(200); $this->assertLinkByHref('/update.php'); $this->assertNoLinkByHref('en/update.php'); // Click through update.php with 'access administration pages' and // 'access site reports' permissions. - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->clickLink(t('Apply pending updates')); + $this->checkForMetaRefresh(); $this->assertText('Updates were attempted.'); $this->assertLink('logged'); $this->assertLink('Administration pages'); - $this->assertNoLinkByHrefInMainRegion('update.php', 1); + $this->assertEmpty($this->xpath('//main//a[contains(@href, :href)]', [':href' => 'update.php'])); $this->clickLink('Administration pages'); $this->assertResponse(200); } @@ -286,7 +289,7 @@ function testSuccessfulMultilingualUpdateFunctionality() { /** * Helper function to run updates via the browser. */ - protected function updateScriptTest($maintenance_mode) { + protected function runUpdates($maintenance_mode) { $schema_version = drupal_get_installed_schema_version('update_script_test'); $this->assertEqual($schema_version, 8001, 'update_script_test is initially installed with schema version 8001.'); @@ -303,9 +306,10 @@ protected function updateScriptTest($maintenance_mode) { else { $this->assertNoText('Operating in maintenance mode.'); } - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->clickLink(t('Apply pending updates')); + $this->checkForMetaRefresh(); // Verify that updates were completed successfully. $this->assertText('Updates were attempted.'); @@ -318,7 +322,7 @@ protected function updateScriptTest($maintenance_mode) { // Verify that there are no links to different parts of the workflow. $this->assertNoLink('Administration pages'); - $this->assertNoLinkByHrefInMainRegion('update.php', 0); + $this->assertEmpty($this->xpath('//main//a[contains(@href, :href)]', [':href' => 'update.php'])); $this->assertNoLink('logged'); // Verify the front page can be visited following the upgrade. @@ -330,74 +334,74 @@ protected function updateScriptTest($maintenance_mode) { * Returns the Drupal 7 system table schema. */ public function getSystemSchema() { - return array( + return [ 'description' => "A list of all modules, themes, and theme engines that are or have been installed in Drupal's file system.", - 'fields' => array( - 'filename' => array( + 'fields' => [ + 'filename' => [ 'description' => 'The path of the primary file for this item, relative to the Drupal root; e.g. modules/node/node.module.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'name' => array( + ], + 'name' => [ 'description' => 'The name of the item; e.g. node.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'type' => array( + ], + 'type' => [ 'description' => 'The type of the item, either module, theme, or theme_engine.', 'type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => '', - ), - 'owner' => array( + ], + 'owner' => [ 'description' => "A theme's 'parent' . Can be either a theme or an engine.", 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'status' => array( + ], + 'status' => [ 'description' => 'Boolean indicating whether or not this item is enabled.', 'type' => 'int', 'not null' => TRUE, 'default' => 0, - ), - 'bootstrap' => array( + ], + 'bootstrap' => [ 'description' => "Boolean indicating whether this module is loaded during Drupal's early bootstrapping phase (e.g. even before the page cache is consulted).", 'type' => 'int', 'not null' => TRUE, 'default' => 0, - ), - 'schema_version' => array( + ], + 'schema_version' => [ 'description' => "The module's database schema version number. -1 if the module is not installed (its tables do not exist); \Drupal::CORE_MINIMUM_SCHEMA_VERSION or the largest N of the module's hook_update_N() function that has either been run or existed when the module was first installed.", 'type' => 'int', 'not null' => TRUE, 'default' => -1, 'size' => 'small', - ), - 'weight' => array( + ], + 'weight' => [ 'description' => "The order in which this module's hooks should be invoked relative to other modules. Equal-weighted modules are ordered by name.", 'type' => 'int', 'not null' => TRUE, 'default' => 0, - ), - 'info' => array( + ], + 'info' => [ 'description' => "A serialized array containing information from the module's .info file; keys can include name, description, package, version, core, dependencies, and php.", 'type' => 'blob', 'not null' => FALSE, - ), - ), - 'primary key' => array('filename'), - 'indexes' => array( - 'system_list' => array('status', 'bootstrap', 'type', 'weight', 'name'), - 'type_name' => array('type', 'name'), - ), - ); + ], + ], + 'primary key' => ['filename'], + 'indexes' => [ + 'system_list' => ['status', 'bootstrap', 'type', 'weight', 'name'], + 'type_name' => ['type', 'name'], + ], + ]; } } diff --git a/core/modules/system/src/Tests/Update/UpdatesWith7xTest.php b/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php similarity index 76% rename from core/modules/system/src/Tests/Update/UpdatesWith7xTest.php rename to core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php index 9782d91c..2452264e 100644 --- a/core/modules/system/src/Tests/Update/UpdatesWith7xTest.php +++ b/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php @@ -1,8 +1,8 @@ updateUrl = $GLOBALS['base_url'] . '/update.php'; - $this->updateUser = $this->drupalCreateUser(array('administer software updates')); + $this->updateUser = $this->drupalCreateUser(['administer software updates']); } - function testWith7x() { + public function testWith7x() { // Ensure that the minimum schema version is 8000, despite 7200 update // hooks and a 7XXX hook_update_last_removed(). $this->assertEqual(drupal_get_installed_schema_version('update_test_with_7x'), 8000); @@ -47,7 +47,7 @@ function testWith7x() { // Click through update.php with 'administer software updates' permission. $this->drupalLogin($this->updateUser); - $this->drupalGet($this->updateUrl, array('external' => TRUE)); + $this->drupalGet($this->updateUrl, ['external' => TRUE]); $this->clickLink(t('Continue')); $this->assertText(t('Some of the pending updates cannot be applied because their dependencies were not met.')); } diff --git a/core/modules/system/tests/src/FunctionalJavascript/ModalRendererTest.php b/core/modules/system/tests/src/FunctionalJavascript/ModalRendererTest.php new file mode 100644 index 00000000..7c0aec02 --- /dev/null +++ b/core/modules/system/tests/src/FunctionalJavascript/ModalRendererTest.php @@ -0,0 +1,38 @@ +assertSession(); + $this->drupalGet('/dialog_renderer-test-links'); + $this->clickLink('Normal Modal!'); + // Neither of the wide modals should have been used. + $style = $session_assert->waitForElementVisible('css', '.ui-dialog')->getAttribute('style'); + $this->assertNotContains('700px', $style); + $this->assertNotContains('1000px', $style); + $this->drupalGet('/dialog_renderer-test-links'); + $this->clickLink('Wide Modal!'); + $this->assertNotEmpty($session_assert->waitForElementVisible('css', '.ui-dialog[style*="width: 700px;"]')); + $this->drupalGet('/dialog_renderer-test-links'); + $this->clickLink('Extra Wide Modal!'); + $this->assertNotEmpty($session_assert->waitForElementVisible('css', '.ui-dialog[style*="width: 1000px;"]')); + } + +} diff --git a/core/modules/system/tests/src/FunctionalJavascript/ThemeFormSettingsTest.php b/core/modules/system/tests/src/FunctionalJavascript/ThemeFormSettingsTest.php new file mode 100644 index 00000000..8e4729fe --- /dev/null +++ b/core/modules/system/tests/src/FunctionalJavascript/ThemeFormSettingsTest.php @@ -0,0 +1,78 @@ +drupalCreateUser(['administer themes']); + $this->drupalLogin($admin); + } + + /** + * Tests that submission handler works correctly. + * + * @dataProvider providerTestFormSettingsSubmissionHandler + */ + public function testFormSettingsSubmissionHandler($theme) { + + \Drupal::service('theme_handler')->install([$theme]); + + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + + $this->drupalGet("admin/appearance/settings/$theme"); + + // Add a new managed file. + $file = current($this->getTestFiles('image')); + $image_file_path = \Drupal::service('file_system')->realpath($file->uri); + $page->attachFileToField('files[custom_logo]', $image_file_path); + $assert_session->waitForButton('custom_logo_remove_button'); + + // Assert the new file is uploaded as temporary. This file should not be + // saved as permanent if settings are not submited. + $image_field = $this->xpath('//input[@name="custom_logo[fids]"]')[0]; + $file = File::load($image_field->getValue()); + $this->assertFalse($file->isPermanent()); + + $page->pressButton('Save configuration'); + \Drupal::entityTypeManager()->getStorage('file')->resetCache(); + + // Assert the uploaded file is saved as permanent. + $image_field = $this->xpath('//input[@name="custom_logo[fids]"]')[0]; + $file = File::load($image_field->getValue()); + $this->assertTrue($file->isPermanent()); + } + + /** + * Provides test data for ::testFormSettingsSubmissionHandler(). + */ + public function providerTestFormSettingsSubmissionHandler() { + return [ + 'test theme.theme' => ['test_theme_theme'], + 'test theme-settings.php' => ['test_theme_settings'], + ]; + } + +} diff --git a/core/modules/system/tests/src/Kernel/Action/ActionTest.php b/core/modules/system/tests/src/Kernel/Action/ActionTest.php index 4ca24fb5..6c381d7c 100644 --- a/core/modules/system/tests/src/Kernel/Action/ActionTest.php +++ b/core/modules/system/tests/src/Kernel/Action/ActionTest.php @@ -17,7 +17,7 @@ class ActionTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('system', 'field', 'user', 'action_test'); + public static $modules = ['system', 'field', 'user', 'action_test']; /** * The action manager. @@ -34,7 +34,7 @@ protected function setUp() { $this->actionManager = $this->container->get('plugin.manager.action'); $this->installEntitySchema('user'); - $this->installSchema('system', array('sequences')); + $this->installSchema('system', ['sequences']); } /** @@ -59,7 +59,7 @@ public function testOperations() { // Create a new unsaved user. $name = $this->randomMachineName(); $user_storage = $this->container->get('entity.manager')->getStorage('user'); - $account = $user_storage->create(array('name' => $name, 'bundle' => 'user')); + $account = $user_storage->create(['name' => $name, 'bundle' => 'user']); $loaded_accounts = $user_storage->loadMultiple(); $this->assertEqual(count($loaded_accounts), 0); @@ -76,25 +76,25 @@ public function testOperations() { */ public function testDependencies() { // Create a new action that depends on a user role. - $action = Action::create(array( + $action = Action::create([ 'id' => 'user_add_role_action.' . RoleInterface::ANONYMOUS_ID, 'type' => 'user', 'label' => t('Add the anonymous role to the selected users'), - 'configuration' => array( + 'configuration' => [ 'rid' => RoleInterface::ANONYMOUS_ID, - ), + ], 'plugin' => 'user_add_role_action', - )); + ]); $action->save(); - $expected = array( - 'config' => array( + $expected = [ + 'config' => [ 'user.role.' . RoleInterface::ANONYMOUS_ID, - ), - 'module' => array( + ], + 'module' => [ 'user', - ), - ); + ], + ]; $this->assertIdentical($expected, $action->calculateDependencies()->getDependencies()); } diff --git a/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTest.php b/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTest.php index ca1c5aff..663bff6b 100644 --- a/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTest.php +++ b/core/modules/system/tests/src/Kernel/Block/SystemMenuBlockTest.php @@ -31,7 +31,7 @@ class SystemMenuBlockTest extends KernelTestBase { * * @var array */ - public static $modules = array( + public static $modules = [ 'system', 'block', 'menu_test', @@ -39,7 +39,7 @@ class SystemMenuBlockTest extends KernelTestBase { 'field', 'user', 'link', - ); + ]; /** * The block under test. @@ -65,7 +65,7 @@ class SystemMenuBlockTest extends KernelTestBase { /** * The menu link plugin manager service. * - * @var \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager + * @var \Drupal\Core\Menu\MenuLinkManagerInterface */ protected $menuLinkManager; @@ -97,16 +97,16 @@ protected function setUp() { $this->blockManager = $this->container->get('plugin.manager.block'); $routes = new RouteCollection(); - $requirements = array('_access' => 'TRUE'); - $options = array('_access_checks' => array('access_check.default')); - $routes->add('example1', new Route('/example1', array(), $requirements, $options)); - $routes->add('example2', new Route('/example2', array(), $requirements, $options)); - $routes->add('example3', new Route('/example3', array(), $requirements, $options)); - $routes->add('example4', new Route('/example4', array(), $requirements, $options)); - $routes->add('example5', new Route('/example5', array(), $requirements, $options)); - $routes->add('example6', new Route('/example6', array(), $requirements, $options)); - $routes->add('example7', new Route('/example7', array(), $requirements, $options)); - $routes->add('example8', new Route('/example8', array(), $requirements, $options)); + $requirements = ['_access' => 'TRUE']; + $options = ['_access_checks' => ['access_check.default']]; + $routes->add('example1', new Route('/example1', [], $requirements, $options)); + $routes->add('example2', new Route('/example2', [], $requirements, $options)); + $routes->add('example3', new Route('/example3', [], $requirements, $options)); + $routes->add('example4', new Route('/example4', [], $requirements, $options)); + $routes->add('example5', new Route('/example5', [], $requirements, $options)); + $routes->add('example6', new Route('/example6', [], $requirements, $options)); + $routes->add('example7', new Route('/example7', [], $requirements, $options)); + $routes->add('example8', new Route('/example8', [], $requirements, $options)); $mock_route_provider = new MockRouteProvider($routes); $this->container->set('router.route_provider', $mock_route_provider); @@ -115,11 +115,11 @@ protected function setUp() { $menu_name = 'mock'; $label = $this->randomMachineName(16); - $this->menu = Menu::create(array( + $this->menu = Menu::create([ 'id' => $menu_name, 'label' => $label, 'description' => 'Description text', - )); + ]); $this->menu->save(); // This creates a tree with the following structure: @@ -132,16 +132,16 @@ protected function setUp() { // - 6 // - 8 // With link 6 being the only external link. - $links = array( - 1 => MenuLinkMock::create(array('id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '', 'weight' => 0)), - 2 => MenuLinkMock::create(array('id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => '', 'route_parameters' => array('foo' => 'bar'), 'weight' => 1)), - 3 => MenuLinkMock::create(array('id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'weight' => 2)), - 4 => MenuLinkMock::create(array('id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3', 'weight' => 3)), - 5 => MenuLinkMock::create(array('id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '', 'expanded' => TRUE, 'weight' => 4)), - 6 => MenuLinkMock::create(array('id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '', 'weight' => 5)), - 7 => MenuLinkMock::create(array('id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => 'test.example5', 'weight' => 6)), - 8 => MenuLinkMock::create(array('id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '', 'weight' => 7)), - ); + $links = [ + 1 => MenuLinkMock::create(['id' => 'test.example1', 'route_name' => 'example1', 'title' => 'foo', 'parent' => '', 'weight' => 0]), + 2 => MenuLinkMock::create(['id' => 'test.example2', 'route_name' => 'example2', 'title' => 'bar', 'parent' => '', 'route_parameters' => ['foo' => 'bar'], 'weight' => 1]), + 3 => MenuLinkMock::create(['id' => 'test.example3', 'route_name' => 'example3', 'title' => 'baz', 'parent' => 'test.example2', 'weight' => 2]), + 4 => MenuLinkMock::create(['id' => 'test.example4', 'route_name' => 'example4', 'title' => 'qux', 'parent' => 'test.example3', 'weight' => 3]), + 5 => MenuLinkMock::create(['id' => 'test.example5', 'route_name' => 'example5', 'title' => 'foofoo', 'parent' => '', 'expanded' => TRUE, 'weight' => 4]), + 6 => MenuLinkMock::create(['id' => 'test.example6', 'route_name' => '', 'url' => 'https://www.drupal.org/', 'title' => 'barbar', 'parent' => '', 'weight' => 5]), + 7 => MenuLinkMock::create(['id' => 'test.example7', 'route_name' => 'example7', 'title' => 'bazbaz', 'parent' => 'test.example5', 'weight' => 6]), + 8 => MenuLinkMock::create(['id' => 'test.example8', 'route_name' => 'example8', 'title' => 'quxqux', 'parent' => '', 'weight' => 7]), + ]; foreach ($links as $instance) { $this->menuLinkManager->addDefinition($instance->getPluginId(), $instance->getPluginDefinition()); } @@ -152,25 +152,25 @@ protected function setUp() { */ public function testSystemMenuBlockConfigDependencies() { - $block = Block::create(array( + $block = Block::create([ 'plugin' => 'system_menu_block:' . $this->menu->id(), 'region' => 'footer', 'id' => 'machinename', 'theme' => 'stark', - )); + ]); $dependencies = $block->calculateDependencies()->getDependencies(); - $expected = array( - 'config' => array( + $expected = [ + 'config' => [ 'system.menu.' . $this->menu->id() - ), - 'module' => array( + ], + 'module' => [ 'system' - ), - 'theme' => array( + ], + 'theme' => [ 'stark' - ), - ); + ], + ]; $this->assertIdentical($expected, $dependencies); } @@ -180,13 +180,13 @@ public function testSystemMenuBlockConfigDependencies() { public function testConfigLevelDepth() { // Helper function to generate a configured block instance. $place_block = function ($level, $depth) { - return $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), array( + return $this->blockManager->createInstance('system_menu_block:' . $this->menu->id(), [ 'region' => 'footer', 'id' => 'machinename', 'theme' => 'stark', 'level' => $level, 'depth' => $depth, - )); + ]); }; // All the different block instances we're going to test. @@ -218,9 +218,7 @@ public function testConfigLevelDepth() { 'test.example6' => [], 'test.example8' => [], ]; - $no_active_trail_expectations['level_2_only'] = [ - 'test.example7' => [], - ]; + $no_active_trail_expectations['level_2_only'] = []; $no_active_trail_expectations['level_3_only'] = []; $no_active_trail_expectations['level_1_and_beyond'] = $no_active_trail_expectations['all']; $no_active_trail_expectations['level_2_and_beyond'] = $no_active_trail_expectations['level_2_only']; @@ -266,7 +264,6 @@ public function testConfigLevelDepth() { ]; $active_trail_expectations['level_2_only'] = [ 'test.example3' => [], - 'test.example7' => [], ]; $active_trail_expectations['level_3_only'] = [ 'test.example4' => [], @@ -276,7 +273,6 @@ public function testConfigLevelDepth() { 'test.example3' => [ 'test.example4' => [], ], - 'test.example7' => [], ]; $active_trail_expectations['level_3_and_beyond'] = $active_trail_expectations['level_3_only']; foreach ($blocks as $id => $block) { diff --git a/core/modules/system/tests/src/Kernel/Common/PageRenderTest.php b/core/modules/system/tests/src/Kernel/Common/PageRenderTest.php index 80729448..fa169473 100644 --- a/core/modules/system/tests/src/Kernel/Common/PageRenderTest.php +++ b/core/modules/system/tests/src/Kernel/Common/PageRenderTest.php @@ -14,7 +14,7 @@ class PageRenderTest extends KernelTestBase { /** * Tests hook_page_attachments() exceptions. */ - function testHookPageAttachmentsExceptions() { + public function testHookPageAttachmentsExceptions() { $this->enableModules(['common_test', 'system']); \Drupal::service('router.builder')->rebuild(); @@ -24,7 +24,7 @@ function testHookPageAttachmentsExceptions() { /** * Tests hook_page_attachments_alter() exceptions. */ - function testHookPageAlter() { + public function testHookPageAlter() { $this->enableModules(['common_test', 'system']); \Drupal::service('router.builder')->rebuild(); @@ -39,7 +39,7 @@ function testHookPageAlter() { * @param string $hook * The page render hook to assert expected exceptions for. */ - function assertPageRenderHookExceptions($module, $hook) { + public function assertPageRenderHookExceptions($module, $hook) { $html_renderer = \Drupal::getContainer()->get('main_content_renderer.html'); // Assert a valid hook implementation doesn't trigger an exception. diff --git a/core/modules/system/tests/src/Kernel/Common/SystemListingTest.php b/core/modules/system/tests/src/Kernel/Common/SystemListingTest.php index 7de7ecfb..b0412b43 100644 --- a/core/modules/system/tests/src/Kernel/Common/SystemListingTest.php +++ b/core/modules/system/tests/src/Kernel/Common/SystemListingTest.php @@ -14,17 +14,17 @@ class SystemListingTest extends KernelTestBase { /** * Tests that files in different directories take precedence as expected. */ - function testDirectoryPrecedence() { + public function testDirectoryPrecedence() { // Define the module files we will search for, and the directory precedence // we expect. - $expected_directories = array( + $expected_directories = [ // When both copies of the module are compatible with Drupal core, the // copy in the profile directory takes precedence. - 'drupal_system_listing_compatible_test' => array( + 'drupal_system_listing_compatible_test' => [ 'core/profiles/testing/modules', 'core/modules/system/tests/modules', - ), - ); + ], + ]; // This test relies on two versions of the same module existing in // different places in the filesystem. Without that, the test has no @@ -32,22 +32,22 @@ function testDirectoryPrecedence() { foreach ($expected_directories as $module => $directories) { foreach ($directories as $directory) { $filename = "$directory/$module/$module.info.yml"; - $this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename))); + $this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', ['@filename' => $filename])); } } // Now scan the directories and check that the files take precedence as // expected. $listing = new ExtensionDiscovery(\Drupal::root()); - $listing->setProfileDirectories(array('core/profiles/testing')); + $listing->setProfileDirectories(['core/profiles/testing']); $files = $listing->scan('module'); foreach ($expected_directories as $module => $directories) { $expected_directory = array_shift($directories); $expected_uri = "$expected_directory/$module/$module.info.yml"; - $this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', array( + $this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', [ '@actual' => $files[$module]->getPathname(), '@expected' => $expected_uri, - ))); + ])); } } @@ -56,7 +56,7 @@ function testDirectoryPrecedence() { */ public function testFileScanIgnoreDirectory() { $listing = new ExtensionDiscovery(\Drupal::root(), FALSE); - $listing->setProfileDirectories(array('core/profiles/testing')); + $listing->setProfileDirectories(['core/profiles/testing']); $files = $listing->scan('module'); $this->assertArrayHasKey('drupal_system_listing_compatible_test', $files); @@ -68,7 +68,7 @@ public function testFileScanIgnoreDirectory() { $this->setSetting('file_scan_ignore_directories', ['drupal_system_listing_compatible_test']); $listing = new ExtensionDiscovery(\Drupal::root(), FALSE); - $listing->setProfileDirectories(array('core/profiles/testing')); + $listing->setProfileDirectories(['core/profiles/testing']); $files = $listing->scan('module'); $this->assertArrayNotHasKey('drupal_system_listing_compatible_test', $files); } diff --git a/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php new file mode 100644 index 00000000..01b09dc6 --- /dev/null +++ b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php @@ -0,0 +1,149 @@ +installEntitySchema('date_format'); + $this->installEntitySchema('user'); + $this->installSchema('system', 'sequences'); + $this->accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('date_format'); + } + + /** + * @covers ::checkAccess + * @covers ::checkCreateAccess + * @dataProvider testAccessProvider + */ + public function testAccess($which_user, $which_entity, $view_label_access_result, $view_access_result, $update_access_result, $delete_access_result, $create_access_result) { + // We must always create user 1, so that a "normal" user has a ID >1. + $root_user = $this->drupalCreateUser(); + + if ($which_user === 'user1') { + $user = $root_user; + } + else { + $permissions = ($which_user === 'admin') + ? ['administer site configuration'] + : []; + $user = $this->drupalCreateUser($permissions); + } + + $entity_values = ($which_entity === 'unlocked') + ? ['locked' => FALSE] + : ['locked' => TRUE]; + $entity_values['id'] = $this->randomMachineName(); + $entity = DateFormat::create($entity_values); + $entity->save(); + + static::assertEquals($view_label_access_result, $this->accessControlHandler->access($entity, 'view label', $user, TRUE)); + static::assertEquals($view_access_result, $this->accessControlHandler->access($entity, 'view', $user, TRUE)); + static::assertEquals($update_access_result, $this->accessControlHandler->access($entity, 'update', $user, TRUE)); + static::assertEquals($delete_access_result, $this->accessControlHandler->access($entity, 'delete', $user, TRUE)); + static::assertEquals($create_access_result, $this->accessControlHandler->createAccess(NULL, $user, [], TRUE)); + } + + public function testAccessProvider() { + $c = new ContainerBuilder(); + $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); + $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); + $cache_contexts_manager->reveal(); + $c->set('cache_contexts_manager', $cache_contexts_manager); + \Drupal::setContainer($c); + + return [ + 'permissionless + unlocked' => [ + 'permissionless', + 'unlocked', + AccessResult::allowed(), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required.")->addCacheTags(['rendered']), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required.")->addCacheTags(['rendered']), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + ], + 'permissionless + locked' => [ + 'permissionless', + 'locked', + AccessResult::allowed(), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."), + ], + 'admin + unlocked' => [ + 'admin', + 'unlocked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'admin + locked' => [ + 'admin', + 'locked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'user1 + unlocked' => [ + 'user1', + 'unlocked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'user1 + locked' => [ + 'user1', + 'locked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + ]; + } + +} diff --git a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php index 8a3e98ed..d7c26503 100644 --- a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php +++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php @@ -3,7 +3,7 @@ namespace Drupal\Tests\system\Kernel\Extension; use Drupal\Core\Extension\MissingDependencyException; -use \Drupal\Core\Extension\ModuleUninstallValidatorException; +use Drupal\Core\Extension\ModuleUninstallValidatorException; use Drupal\entity_test\Entity\EntityTest; use Drupal\KernelTests\KernelTestBase; @@ -38,13 +38,13 @@ protected function setUp() { /** * The basic functionality of retrieving enabled modules. */ - function testModuleList() { + public function testModuleList() { $module_list = ['system']; $this->assertModuleList($module_list, 'Initial'); // Try to install a new module. - $this->moduleInstaller()->install(array('ban')); + $this->moduleInstaller()->install(['ban']); $module_list[] = 'ban'; sort($module_list); $this->assertModuleList($module_list, 'After adding a module'); @@ -58,10 +58,10 @@ function testModuleList() { $this->assertModuleList($module_list, 'After changing weights'); // Test the fixed list feature. - $fixed_list = array( + $fixed_list = [ 'system' => 'core/modules/system/system.module', 'menu' => 'core/modules/menu/menu.module', - ); + ]; $this->moduleHandler()->setModuleList($fixed_list); $new_module_list = array_combine(array_keys($fixed_list), array_keys($fixed_list)); $this->assertModuleList($new_module_list, t('When using a fixed list')); @@ -77,7 +77,7 @@ function testModuleList() { protected function assertModuleList(array $expected_values, $condition) { $expected_values = array_values(array_unique($expected_values)); $enabled_modules = array_keys($this->container->get('module_handler')->getModuleList()); - $this->assertEqual($expected_values, $enabled_modules, format_string('@condition: extension handler returns correct results', array('@condition' => $condition))); + $this->assertEqual($expected_values, $enabled_modules, format_string('@condition: extension handler returns correct results', ['@condition' => $condition])); } /** @@ -92,8 +92,8 @@ protected function assertModuleList(array $expected_values, $condition) { * @see module_test_system_info_alter() * @see https://www.drupal.org/files/issues/dep.gv__0.png */ - function testDependencyResolution() { - $this->enableModules(array('module_test')); + public function testDependencyResolution() { + $this->enableModules(['module_test']); $this->assertTrue($this->moduleHandler()->moduleExists('module_test'), 'Test module is enabled.'); // Ensure that modules are not enabled. @@ -108,7 +108,7 @@ function testDependencyResolution() { drupal_static_reset('system_rebuild_module_data'); try { - $result = $this->moduleInstaller()->install(array('color')); + $result = $this->moduleInstaller()->install(['color']); $this->fail(t('ModuleInstaller::install() throws an exception if dependencies are missing.')); } catch (MissingDependencyException $e) { @@ -122,7 +122,7 @@ function testDependencyResolution() { \Drupal::state()->set('module_test.dependency', 'dependency'); drupal_static_reset('system_rebuild_module_data'); - $result = $this->moduleInstaller()->install(array('color')); + $result = $this->moduleInstaller()->install(['color']); $this->assertTrue($result, 'ModuleInstaller::install() returns the correct value.'); // Verify that the fake dependency chain was installed. @@ -132,20 +132,20 @@ function testDependencyResolution() { $this->assertTrue($this->moduleHandler()->moduleExists('color'), 'Module installation with dependencies succeeded.'); // Verify that the modules were enabled in the correct order. - $module_order = \Drupal::state()->get('module_test.install_order') ?: array(); - $this->assertEqual($module_order, array('help', 'config', 'color')); + $module_order = \Drupal::state()->get('module_test.install_order') ?: []; + $this->assertEqual($module_order, ['help', 'config', 'color']); // Uninstall all three modules explicitly, but in the incorrect order, // and make sure that ModuleInstaller::uninstall() uninstalled them in the // correct sequence. - $result = $this->moduleInstaller()->uninstall(array('config', 'help', 'color')); + $result = $this->moduleInstaller()->uninstall(['config', 'help', 'color']); $this->assertTrue($result, 'ModuleInstaller::uninstall() returned TRUE.'); - foreach (array('color', 'config', 'help') as $module) { + foreach (['color', 'config', 'help'] as $module) { $this->assertEqual(drupal_get_installed_schema_version($module), SCHEMA_UNINSTALLED, "$module module was uninstalled."); } - $uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: array(); - $this->assertEqual($uninstalled_modules, array('color', 'config', 'help'), 'Modules were uninstalled in the correct order.'); + $uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: []; + $this->assertEqual($uninstalled_modules, ['color', 'config', 'help'], 'Modules were uninstalled in the correct order.'); // Enable Color module again, which should enable both the Config module and // Help module. But, this time do it with Config module declaring a @@ -154,7 +154,7 @@ function testDependencyResolution() { \Drupal::state()->set('module_test.dependency', 'version dependency'); drupal_static_reset('system_rebuild_module_data'); - $result = $this->moduleInstaller()->install(array('color')); + $result = $this->moduleInstaller()->install(['color']); $this->assertTrue($result, 'ModuleInstaller::install() returns the correct value.'); // Verify that the fake dependency chain was installed. @@ -164,39 +164,39 @@ function testDependencyResolution() { $this->assertTrue($this->moduleHandler()->moduleExists('color'), 'Module installation with version dependencies succeeded.'); // Finally, verify that the modules were enabled in the correct order. - $enable_order = \Drupal::state()->get('module_test.install_order') ?: array(); - $this->assertIdentical($enable_order, array('help', 'config', 'color')); + $enable_order = \Drupal::state()->get('module_test.install_order') ?: []; + $this->assertIdentical($enable_order, ['help', 'config', 'color']); } /** * Tests uninstalling a module that is a "dependency" of a profile. */ - function testUninstallProfileDependency() { - $profile = 'minimal'; - $dependency = 'dblog'; + public function testUninstallProfileDependency() { + $profile = 'testing'; + $dependency = 'page_cache'; $this->setSetting('install_profile', $profile); // Prime the drupal_get_filename() static cache with the location of the // minimal profile as it is not the currently active profile and we don't // yet have any cached way to retrieve its location. // @todo Remove as part of https://www.drupal.org/node/2186491 drupal_get_filename('profile', $profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml'); - $this->enableModules(array('module_test', $profile)); + $this->enableModules(['module_test', $profile]); drupal_static_reset('system_rebuild_module_data'); $data = system_rebuild_module_data(); $this->assertTrue(isset($data[$profile]->requires[$dependency])); - $this->moduleInstaller()->install(array($dependency)); + $this->moduleInstaller()->install([$dependency]); $this->assertTrue($this->moduleHandler()->moduleExists($dependency)); // Uninstall the profile module "dependency". - $result = $this->moduleInstaller()->uninstall(array($dependency)); + $result = $this->moduleInstaller()->uninstall([$dependency]); $this->assertTrue($result, 'ModuleInstaller::uninstall() returns TRUE.'); $this->assertFalse($this->moduleHandler()->moduleExists($dependency)); $this->assertEqual(drupal_get_installed_schema_version($dependency), SCHEMA_UNINSTALLED, "$dependency module was uninstalled."); // Verify that the installation profile itself was not uninstalled. - $uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: array(); + $uninstalled_modules = \Drupal::state()->get('module_test.uninstall_order') ?: []; $this->assertTrue(in_array($dependency, $uninstalled_modules), "$dependency module is in the list of uninstalled modules."); $this->assertFalse(in_array($profile, $uninstalled_modules), 'The installation profile is not in the list of uninstalled modules.'); } @@ -204,8 +204,8 @@ function testUninstallProfileDependency() { /** * Tests uninstalling a module that has content. */ - function testUninstallContentDependency() { - $this->enableModules(array('module_test', 'entity_test', 'text', 'user', 'help')); + public function testUninstallContentDependency() { + $this->enableModules(['module_test', 'entity_test', 'text', 'user', 'help']); $this->assertTrue($this->moduleHandler()->moduleExists('entity_test'), 'Test module is enabled.'); $this->assertTrue($this->moduleHandler()->moduleExists('module_test'), 'Test module is enabled.'); @@ -224,13 +224,13 @@ function testUninstallContentDependency() { drupal_static_reset('system_rebuild_module_data'); // Create an entity so that the modules can not be disabled. - $entity = EntityTest::create(array('name' => $this->randomString())); + $entity = EntityTest::create(['name' => $this->randomString()]); $entity->save(); // Uninstalling entity_test is not possible when there is content. try { $message = 'ModuleInstaller::uninstall() throws ModuleUninstallValidatorException upon uninstalling a module which does not pass validation.'; - $this->moduleInstaller()->uninstall(array('entity_test')); + $this->moduleInstaller()->uninstall(['entity_test']); $this->fail($message); } catch (ModuleUninstallValidatorException $e) { @@ -240,7 +240,7 @@ function testUninstallContentDependency() { // Uninstalling help needs entity_test to be un-installable. try { $message = 'ModuleInstaller::uninstall() throws ModuleUninstallValidatorException upon uninstalling a module which does not pass validation.'; - $this->moduleInstaller()->uninstall(array('help')); + $this->moduleInstaller()->uninstall(['help']); $this->fail($message); } catch (ModuleUninstallValidatorException $e) { @@ -250,7 +250,7 @@ function testUninstallContentDependency() { // Deleting the entity. $entity->delete(); - $result = $this->moduleInstaller()->uninstall(array('help')); + $result = $this->moduleInstaller()->uninstall(['help']); $this->assertTrue($result, 'ModuleInstaller::uninstall() returns TRUE.'); $this->assertEqual(drupal_get_installed_schema_version('entity_test'), SCHEMA_UNINSTALLED, "entity_test module was uninstalled."); } @@ -258,7 +258,7 @@ function testUninstallContentDependency() { /** * Tests whether the correct module metadata is returned. */ - function testModuleMetaData() { + public function testModuleMetaData() { // Generate the list of available modules. $modules = system_rebuild_module_data(); // Check that the mtime field exists for the system module. @@ -289,7 +289,7 @@ public function testModuleStreamWrappers() { /** * Tests whether the correct theme metadata is returned. */ - function testThemeMetaData() { + public function testThemeMetaData() { // Generate the list of available themes. $themes = \Drupal::service('theme_handler')->rebuildThemeData(); // Check that the mtime field exists for the bartik theme. diff --git a/core/modules/system/tests/src/Kernel/Form/FormElementLabelTest.php b/core/modules/system/tests/src/Kernel/Form/FormElementLabelTest.php index f93d461b..2bc895f8 100644 --- a/core/modules/system/tests/src/Kernel/Form/FormElementLabelTest.php +++ b/core/modules/system/tests/src/Kernel/Form/FormElementLabelTest.php @@ -31,6 +31,16 @@ public function testAttributes() { $this->render($render_array); $elements = $this->xpath($css_selector_converter->toXPath('.kitten')); $this->assertCount(1, $elements); + + // Add label attributes to a form element. + $render_array = [ + '#type' => 'textfield', + '#label_attributes' => ['class' => ['meow']], + '#title' => 'Kitten sounds', + ]; + $this->render($render_array); + $elements = $this->xpath($css_selector_converter->toXPath('label.meow')); + $this->assertCount(1, $elements); } } diff --git a/core/modules/system/tests/src/Kernel/Form/FormElementMaxlengthTest.php b/core/modules/system/tests/src/Kernel/Form/FormElementMaxlengthTest.php new file mode 100644 index 00000000..94026b65 --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Form/FormElementMaxlengthTest.php @@ -0,0 +1,80 @@ + 'textfield', + '#maxlength' => 255, + ]; + + $form['description'] = [ + '#type' => 'textarea', + '#maxlength' => 255, + ]; + + $form['submit'] = [ + '#type' => 'submit', + '#value' => 'Submit', + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) {} + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) {} + + /** + * Ensures maxlength attribute can be used in compatible elements. + */ + public function testAttributes() { + + /** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */ + $form_builder = $this->container->get('form_builder'); + $form_state = new FormState(); + $elements = $form_builder->buildForm($this, $form_state); + $this->render($elements); + + $css_selector_converter = new CssSelectorConverter(); + $elements = $this->xpath($css_selector_converter->toXPath('input[name=title][maxlength=255]')); + $this->assertCount(1, $elements, 'Text field has correct maxlength in form.'); + $elements = $this->xpath($css_selector_converter->toXPath('textarea[name=description][maxlength=255]')); + $this->assertCount(1, $elements, 'Textarea field has correct maxlength in form.'); + } + +} diff --git a/core/modules/system/tests/src/Kernel/Form/ProgrammaticTest.php b/core/modules/system/tests/src/Kernel/Form/ProgrammaticTest.php new file mode 100644 index 00000000..03d22afe --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Form/ProgrammaticTest.php @@ -0,0 +1,119 @@ +doSubmitForm([], FALSE); + $this->doSubmitForm(['textfield' => 'test 1'], TRUE); + $this->doSubmitForm([], FALSE); + $this->doSubmitForm(['textfield' => 'test 2'], TRUE); + + // Test that a programmatic form submission can turn on and off checkboxes + // which are, by default, checked. + $this->doSubmitForm(['textfield' => 'dummy value', 'checkboxes' => [1 => 1, 2 => 2]], TRUE); + $this->doSubmitForm(['textfield' => 'dummy value', 'checkboxes' => [1 => 1, 2 => NULL]], TRUE); + $this->doSubmitForm(['textfield' => 'dummy value', 'checkboxes' => [1 => NULL, 2 => 2]], TRUE); + $this->doSubmitForm(['textfield' => 'dummy value', 'checkboxes' => [1 => NULL, 2 => NULL]], TRUE); + + // Test that a programmatic form submission can correctly click a button + // that limits validation errors based on user input. Since we do not + // submit any values for "textfield" here and the textfield is required, we + // only expect form validation to pass when validation is limited to a + // different field. + $this->doSubmitForm(['op' => 'Submit with limited validation', 'field_to_validate' => 'all'], FALSE); + $this->doSubmitForm(['op' => 'Submit with limited validation', 'field_to_validate' => 'textfield'], FALSE); + $this->doSubmitForm(['op' => 'Submit with limited validation', 'field_to_validate' => 'field_to_validate'], TRUE); + + // Restore the current batch status. + $batch = $current_batch; + } + + /** + * Helper function used to programmatically submit the form defined in + * form_test.module with the given values. + * + * @param $values + * An array of field values to be submitted. + * @param $valid_input + * A boolean indicating whether or not the form submission is expected to + * be valid. + */ + protected function doSubmitForm($values, $valid_input) { + // Programmatically submit the given values. + $form_state = (new FormState())->setValues($values); + \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state); + + // Check that the form returns an error when expected, and vice versa. + $errors = $form_state->getErrors(); + $valid_form = empty($errors); + $args = [ + '%values' => print_r($values, TRUE), + '%errors' => $valid_form ? t('None') : implode(' ', $errors), + ]; + $this->assertTrue($valid_input == $valid_form, format_string('Input values: %values
    Validation handler errors: %errors', $args)); + + // We check submitted values only if we have a valid input. + if ($valid_input) { + // Fetching the values that were set in the submission handler. + $stored_values = $form_state->get('programmatic_form_submit'); + foreach ($values as $key => $value) { + $this->assertEqual($stored_values[$key], $value, format_string('Submission handler correctly executed: %stored_key is %stored_value', ['%stored_key' => $key, '%stored_value' => print_r($value, TRUE)])); + } + } + } + + /** + * Test the programmed_bypass_access_check flag. + */ + public function testProgrammaticAccessBypass() { + $form_state = (new FormState())->setValues([ + 'textfield' => 'dummy value', + 'field_restricted' => 'dummy value' + ]); + + // Programmatically submit the form with a value for the restricted field. + // Since programmed_bypass_access_check is set to TRUE by default, the + // field is accessible and can be set. + \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state); + $values = $form_state->get('programmatic_form_submit'); + $this->assertEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is stored correctly.'); + + // Programmatically submit the form with a value for the restricted field + // with programmed_bypass_access_check set to FALSE. Since access + // restrictions apply, the restricted field is inaccessible, and the value + // should not be stored. + $form_state->setProgrammedBypassAccessCheck(FALSE); + \Drupal::formBuilder()->submitForm('\Drupal\form_test\Form\FormTestProgrammaticForm', $form_state); + $values = $form_state->get('programmatic_form_submit'); + $this->assertNotEqual($values['field_restricted'], 'dummy value', 'The value for the restricted field is not stored.'); + + } + +} diff --git a/core/modules/system/tests/src/Kernel/Installer/UninstallKernelTest.php b/core/modules/system/tests/src/Kernel/Installer/UninstallKernelTest.php new file mode 100644 index 00000000..f3591538 --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Installer/UninstallKernelTest.php @@ -0,0 +1,44 @@ +installSchema('user', ['users_data']); + $this->installEntitySchema('media'); + $this->installEntitySchema('file'); + $this->installConfig(['media']); + } + + /** + * Tests uninstalling media and file modules. + */ + public function testUninstallMedia() { + // Media creates a file field that is removed on uninstall, ensure that it + // is fully deleted (as it is empty) and that file then can be uninstalled + // as well. + \Drupal::service('module_installer')->uninstall(['media']); + \Drupal::service('module_installer')->uninstall(['file']); + } + +} diff --git a/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php b/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php new file mode 100644 index 00000000..6d702c7c --- /dev/null +++ b/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php @@ -0,0 +1,149 @@ +installEntitySchema('menu'); + $this->installEntitySchema('user'); + $this->installSchema('system', 'sequences'); + $this->accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('menu'); + } + + /** + * @covers ::checkAccess + * @covers ::checkCreateAccess + * @dataProvider testAccessProvider + */ + public function testAccess($which_user, $which_entity, $view_label_access_result, $view_access_result, $update_access_result, $delete_access_result, $create_access_result) { + // We must always create user 1, so that a "normal" user has a ID >1. + $root_user = $this->drupalCreateUser(); + + if ($which_user === 'user1') { + $user = $root_user; + } + else { + $permissions = ($which_user === 'admin') + ? ['administer menu'] + : []; + $user = $this->drupalCreateUser($permissions); + } + + $entity_values = ($which_entity === 'unlocked') + ? ['locked' => FALSE] + : ['locked' => TRUE]; + $entity_values['id'] = 'llama'; + $entity = Menu::create($entity_values); + $entity->save(); + + static::assertEquals($view_label_access_result, $this->accessControlHandler->access($entity, 'view label', $user, TRUE)); + static::assertEquals($view_access_result, $this->accessControlHandler->access($entity, 'view', $user, TRUE)); + static::assertEquals($update_access_result, $this->accessControlHandler->access($entity, 'update', $user, TRUE)); + static::assertEquals($delete_access_result, $this->accessControlHandler->access($entity, 'delete', $user, TRUE)); + static::assertEquals($create_access_result, $this->accessControlHandler->createAccess(NULL, $user, [], TRUE)); + } + + public function testAccessProvider() { + $c = new ContainerBuilder(); + $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); + $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); + $cache_contexts_manager->reveal(); + $c->set('cache_contexts_manager', $cache_contexts_manager); + \Drupal::setContainer($c); + + return [ + 'permissionless + unlocked' => [ + 'permissionless', + 'unlocked', + AccessResult::allowed(), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required.")->addCacheTags(['config:system.menu.llama']), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required."), + ], + 'permissionless + locked' => [ + 'permissionless', + 'locked', + AccessResult::allowed(), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required."), + AccessResult::forbidden()->addCacheTags(['config:system.menu.llama'])->setReason("The Menu config entity is locked."), + AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer menu' permission is required."), + ], + 'admin + unlocked' => [ + 'admin', + 'unlocked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['config:system.menu.llama']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'admin + locked' => [ + 'admin', + 'locked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::forbidden()->addCacheTags(['config:system.menu.llama'])->setReason("The Menu config entity is locked."), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'user1 + unlocked' => [ + 'user1', + 'unlocked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['config:system.menu.llama']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + 'user1 + locked' => [ + 'user1', + 'locked', + AccessResult::allowed(), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + AccessResult::forbidden()->addCacheTags(['config:system.menu.llama'])->setReason("The Menu config entity is locked."), + AccessResult::allowed()->addCacheContexts(['user.permissions']), + ], + ]; + } + +} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateDateFormatTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateDateFormatTest.php index 54aaac27..b45a3605 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateDateFormatTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateDateFormatTest.php @@ -37,7 +37,7 @@ public function testDateFormats() { // Test that we can re-import using the EntityDateFormat destination. Database::getConnection('default', 'migrate') ->update('variable') - ->fields(array('value' => serialize('\S\H\O\R\T d/m/Y - H:i'))) + ->fields(['value' => serialize('\S\H\O\R\T d/m/Y - H:i')]) ->condition('name', 'date_format_short') ->execute(); diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateMenuTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateMenuTest.php index e6ac30c8..51c93778 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateMenuTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateMenuTest.php @@ -36,14 +36,14 @@ public function testMenu() { // Test that we can re-import using the ConfigEntityBase destination. Database::getConnection('default', 'migrate') ->update('menu_custom') - ->fields(array('title' => 'Home Navigation')) + ->fields(['title' => 'Home Navigation']) ->condition('menu_name', 'navigation') ->execute(); $migration = $this->getMigration('d6_menu'); \Drupal::database() - ->truncate($migration->getIdMap()->mapTableName()) - ->execute(); + ->truncate($migration->getIdMap()->mapTableName()) + ->execute(); $this->executeMigration($migration); $navigation_menu = Menu::load('navigation'); diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php new file mode 100644 index 00000000..33c963de --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemConfigurationTest.php @@ -0,0 +1,159 @@ + [ + 'threshold' => [ + 'requirements_warning' => 172800, + 'requirements_error' => 1209600, + ], + // logging is not handled by the migration. + 'logging' => 1, + ], + 'system.date' => [ + // country is not handled by the migration. + 'country' => [ + 'default' => '', + ], + 'first_day' => 4, + // timezone is not handled by the migration. + 'timezone' => [ + 'default' => 'Europe/Paris', + 'user' => [ + 'configurable' => FALSE, + // warn is not handled by the migration. + 'warn' => FALSE, + // default is not handled by the migration. + 'default' => 0, + ], + ], + ], + 'system.file' => [ + 'allow_insecure_uploads' => TRUE, + // default_scheme is not handled by the migration. + 'default_scheme' => 'public', + 'path' => [ + 'temporary' => 'files/temp', + ], + // temporary_maximum_age is not handled by the migration. + 'temporary_maximum_age' => 21600, + ], + 'system.image.gd' => [ + 'jpeg_quality' => 75, + ], + 'system.image' => [ + 'toolkit' => 'gd', + ], + 'system.logging' => [ + 'error_level' => 'some', + ], + 'system.maintenance' => [ + 'message' => 'Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.', + // langcode is not handled by the migration. + 'langcode' => 'en', + ], + 'system.performance' => [ + 'cache' => [ + 'page' => [ + 'max_age' => 0, + ], + ], + 'css' => [ + 'preprocess' => FALSE, + // gzip is not handled by the migration. + 'gzip' => TRUE, + ], + // fast_404 is not handled by the migration. + 'fast_404' => [ + 'enabled' => TRUE, + 'paths' => '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i', + 'exclude_paths' => '/\/(?:styles|imagecache)\//', + 'html' => '404 Not Found

    Not Found

    The requested URL "@path" was not found on this server.

    ', + ], + 'js' => [ + 'preprocess' => FALSE, + // gzip is not handled by the migration. + 'gzip' => TRUE, + ], + // stale_file_threshold is not handled by the migration. + 'stale_file_threshold' => 2592000, + ], + 'system.rss' => [ + // channel is not handled by the migration. + 'channel' => [ + 'description' => '', + ], + 'items' => [ + 'limit' => 10, + 'view_mode' => 'title', + ], + // langcode is not handled by the migration. + 'langcode' => 'en', + ], + 'system.site' => [ + // uuid is not handled by the migration. + 'uuid' => '', + 'name' => 'site_name', + 'mail' => 'site_mail@example.com', + 'slogan' => 'Migrate rocks', + 'page' => [ + '403' => '/user', + '404' => '/page-not-found', + 'front' => '/node', + ], + 'admin_compact_mode' => FALSE, + 'weight_select_max' => 100, + // langcode and default_langcode are not handled by the migration. + 'langcode' => 'en', + 'default_langcode' => 'en', + ], + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $migrations = [ + 'd6_system_cron', + 'd6_system_date', + 'd6_system_file', + 'system_image_gd', + 'system_image', + 'system_logging', + 'system_maintenance', + 'd6_system_performance', + 'system_rss', + 'system_site', + ]; + $this->executeMigrations($migrations); + } + + /** + * Tests that all expected configuration gets migrated. + */ + public function testConfigurationMigration() { + foreach ($this->expectedConfig as $config_id => $values) { + $actual = \Drupal::config($config_id)->get(); + unset($actual['_core']); + $this->assertSame($actual, $values, $config_id . ' matches expected values.'); + } + } + +} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemCronTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemCronTest.php deleted file mode 100644 index 0df5df1b..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemCronTest.php +++ /dev/null @@ -1,31 +0,0 @@ -executeMigration('d6_system_cron'); - } - - /** - * Tests migration of system (cron) variables to system.cron.yml. - */ - public function testSystemCron() { - $config = $this->config('system.cron'); - $this->assertIdentical(172800, $config->get('threshold.requirements_warning')); - $this->assertIdentical(1209600, $config->get('threshold.requirements_error')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemDateTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemDateTest.php deleted file mode 100644 index c1d0c719..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemDateTest.php +++ /dev/null @@ -1,32 +0,0 @@ -executeMigration('d6_system_date'); - } - - /** - * Tests migration of user variables to system_date.yml. - */ - public function testSystemDate() { - $config = $this->config('system.date'); - $this->assertIdentical(4, $config->get('first_day')); - $this->assertIdentical(FALSE, $config->get('timezone.user.configurable')); - $this->assertIdentical("Europe/Paris", $config->get('timezone.default')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemFileTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemFileTest.php deleted file mode 100644 index d96909bf..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemFileTest.php +++ /dev/null @@ -1,31 +0,0 @@ -executeMigration('d6_system_file'); - } - - /** - * Tests migration of system (file) variables to system.file.yml. - */ - public function testSystemFile() { - $config = \Drupal::configFactory()->getEditable('system.file'); - $this->assertIdentical('files/temp', $config->get('path.temporary')); - $this->assertIdentical(TRUE, $config->get('allow_insecure_uploads')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemImageGdTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemImageGdTest.php deleted file mode 100644 index 4a3b5a24..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemImageGdTest.php +++ /dev/null @@ -1,30 +0,0 @@ -executeMigration('system_image_gd'); - } - - /** - * Tests migration of system (image GD) variables to system.image.gd.yml. - */ - public function testSystemImageGd() { - $config = $this->config('system.image.gd'); - $this->assertIdentical(75, $config->get('jpeg_quality')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemImageTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemImageTest.php deleted file mode 100644 index c714ff85..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemImageTest.php +++ /dev/null @@ -1,30 +0,0 @@ -executeMigration('system_image'); - } - - /** - * Tests migration of system (image) variables to system.image.yml. - */ - public function testSystemImage() { - $config = $this->config('system.image'); - $this->assertIdentical('gd', $config->get('toolkit')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemLoggingTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemLoggingTest.php deleted file mode 100644 index f56a7f5c..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemLoggingTest.php +++ /dev/null @@ -1,34 +0,0 @@ -executeMigration('system_logging'); - } - - /** - * Tests migration of system error_level variables to system.logging.yml. - */ - public function testSystemLogging() { - $config = $this->config('system.logging'); - $this->assertIdentical('some', $config->get('error_level')); - $this->assertConfigSchema(\Drupal::service('config.typed'), 'system.logging', $config->get()); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemMaintenanceTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemMaintenanceTest.php deleted file mode 100644 index 72898027..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemMaintenanceTest.php +++ /dev/null @@ -1,30 +0,0 @@ -executeMigration('system_maintenance'); - } - - /** - * Tests migration of system (maintenance) variables to system.maintenance.yml. - */ - public function testSystemMaintenance() { - $config = $this->config('system.maintenance'); - $this->assertIdentical('Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.', $config->get('message')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemPerformanceTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemPerformanceTest.php deleted file mode 100644 index d341f838..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemPerformanceTest.php +++ /dev/null @@ -1,32 +0,0 @@ -executeMigration('d6_system_performance'); - } - - /** - * Tests migration of system (Performance) variables to system.performance.yml. - */ - public function testSystemPerformance() { - $config = $this->config('system.performance'); - $this->assertIdentical(FALSE, $config->get('css.preprocess')); - $this->assertIdentical(FALSE, $config->get('js.preprocess')); - $this->assertIdentical(0, $config->get('cache.page.max_age')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemRssTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemRssTest.php deleted file mode 100644 index a22864eb..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemRssTest.php +++ /dev/null @@ -1,31 +0,0 @@ -executeMigration('system_rss'); - } - - /** - * Tests migration of system (rss) variables to system.rss.yml. - */ - public function testSystemRss() { - $config = $this->config('system.rss'); - $this->assertIdentical(10, $config->get('items.limit')); - $this->assertIdentical('title', $config->get('items.view_mode')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemSiteTest.php b/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemSiteTest.php deleted file mode 100644 index a634ddb6..00000000 --- a/core/modules/system/tests/src/Kernel/Migrate/d6/MigrateSystemSiteTest.php +++ /dev/null @@ -1,36 +0,0 @@ -executeMigration('system_site'); - } - - /** - * Tests migration of system (site) variables to system.site.yml. - */ - public function testSystemSite() { - $config = $this->config('system.site'); - $this->assertIdentical('site_name', $config->get('name')); - $this->assertIdentical('site_mail@example.com', $config->get('mail')); - $this->assertIdentical('Migrate rocks', $config->get('slogan')); - $this->assertIdentical('/user', $config->get('page.403')); - $this->assertIdentical('/page-not-found', $config->get('page.404')); - $this->assertIdentical('/node', $config->get('page.front')); - $this->assertIdentical(FALSE, $config->get('admin_compact_mode')); - } - -} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateMenuTest.php b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateMenuTest.php index 98708453..455be2ad 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateMenuTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateMenuTest.php @@ -51,14 +51,14 @@ public function testMenu() { // Test that we can re-import using the ConfigEntityBase destination. Database::getConnection('default', 'migrate') ->update('menu_custom') - ->fields(array('title' => 'Home Navigation')) + ->fields(['title' => 'Home Navigation']) ->condition('menu_name', 'navigation') ->execute(); $migration = $this->getMigration('d7_menu'); \Drupal::database() - ->truncate($migration->getIdMap()->mapTableName()) - ->execute(); + ->truncate($migration->getIdMap()->mapTableName()) + ->execute(); $this->executeMigration($migration); $navigation_menu = Menu::load('tools'); diff --git a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php index 59d7b01b..0216e2dd 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php @@ -24,6 +24,7 @@ class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase { 'requirements_warning' => 172800, 'requirements_error' => 1209600, ], + 'logging' => 1, ], 'system.date' => [ 'country' => [ @@ -94,9 +95,6 @@ class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase { ], // stale_file_threshold is not handled by the migration. 'stale_file_threshold' => 2592000, - 'response' => [ - 'gzip' => TRUE, - ], ], 'system.rss' => [ 'channel' => [ diff --git a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateThemeSettingsTest.php b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateThemeSettingsTest.php new file mode 100644 index 00000000..08f70cff --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateThemeSettingsTest.php @@ -0,0 +1,59 @@ +install(['bartik']); + // Install seven theme. + \Drupal::service('theme_handler')->install(['seven']); + $this->executeMigration('d7_theme_settings'); + } + + /** + * Tests migration of theme settings to variables to configuration. + */ + public function testMigrateThemeSettings() { + $config = $this->config('bartik.settings'); + + $this->assertSame('', $config->get('favicon.path')); + $this->assertTrue($config->get('favicon.use_default')); + $this->assertTrue($config->get('features.comment_user_picture')); + $this->assertTrue($config->get('features.comment_user_verification')); + $this->assertTrue($config->get('features.favicon')); + $this->assertTrue($config->get('features.node_user_picture')); + $this->assertFalse($config->get('features.logo')); + $this->assertTrue($config->get('features.name')); + $this->assertTrue($config->get('features.slogan')); + $this->assertSame('public://gnu.png', $config->get('logo.path')); + $this->assertFalse($config->get('logo.use_default')); + + $config = $this->config('seven.settings'); + $this->assertSame('', $config->get('favicon.path')); + $this->assertTrue($config->get('favicon.use_default')); + $this->assertFalse($config->get('features.comment_user_picture')); + $this->assertTrue($config->get('features.comment_user_verification')); + $this->assertTrue($config->get('features.favicon')); + $this->assertTrue($config->get('features.node_user_picture')); + $this->assertFalse($config->get('features.logo')); + $this->assertTrue($config->get('features.name')); + $this->assertTrue($config->get('features.slogan')); + $this->assertSame('', $config->get('logo.path')); + $this->assertTrue($config->get('logo.use_default')); + } + +} diff --git a/core/modules/system/tests/src/Kernel/PhpStorage/PhpStorageFactoryTest.php b/core/modules/system/tests/src/Kernel/PhpStorage/PhpStorageFactoryTest.php index 8adee9d9..4d1c258b 100644 --- a/core/modules/system/tests/src/Kernel/PhpStorage/PhpStorageFactoryTest.php +++ b/core/modules/system/tests/src/Kernel/PhpStorage/PhpStorageFactoryTest.php @@ -57,19 +57,19 @@ public function testGetOverride() { $this->assertTrue($php instanceof MockPhpStorage, 'A MockPhpStorage instance was returned from overridden settings.'); // Test that the name is used for the bin when it is NULL. - $this->setSettings('test', array('bin' => NULL)); + $this->setSettings('test', ['bin' => NULL]); $php = PhpStorageFactory::get('test'); $this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.'); $this->assertSame('test', $php->getConfigurationValue('bin'), 'Name value was used for bin.'); // Test that a default directory is set if it's empty. - $this->setSettings('test', array('directory' => NULL)); + $this->setSettings('test', ['directory' => NULL]); $php = PhpStorageFactory::get('test'); $this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.'); $this->assertSame(PublicStream::basePath() . '/php', $php->getConfigurationValue('directory'), 'Default file directory was used.'); // Test that a default storage class is set if it's empty. - $this->setSettings('test', array('class' => NULL)); + $this->setSettings('test', ['class' => NULL]); $php = PhpStorageFactory::get('test'); $this->assertTrue($php instanceof MTimeProtectedFileStorage, 'An MTimeProtectedFileStorage instance was returned from overridden settings with no class.'); @@ -79,7 +79,7 @@ public function testGetOverride() { $this->assertNotEquals('mock hash salt', $php->getConfigurationValue('secret'), 'The default secret is not used if a secret is set in the overridden settings.'); // Test that a default secret is set if it's empty. - $this->setSettings('test', array('secret' => NULL)); + $this->setSettings('test', ['secret' => NULL]); $php = PhpStorageFactory::get('test'); $this->assertSame('mock hash salt', $php->getConfigurationValue('secret'), 'The default secret is used if one is not set in the overridden settings.'); } @@ -92,13 +92,13 @@ public function testGetOverride() { * @param array $configuration * An array of configuration to set. Will be merged with default values. */ - protected function setSettings($name = 'default', array $configuration = array()) { - $settings['php_storage'][$name] = $configuration + array( + protected function setSettings($name = 'default', array $configuration = []) { + $settings['php_storage'][$name] = $configuration + [ 'class' => 'Drupal\system\PhpStorage\MockPhpStorage', 'directory' => 'tmp://', 'secret' => $this->randomString(), 'bin' => 'test', - ); + ]; $settings['hash_salt'] = 'mock hash salt'; new Settings($settings); } diff --git a/core/modules/system/tests/src/Kernel/Plugin/migrate/source/d7/ThemeSettingsTest.php b/core/modules/system/tests/src/Kernel/Plugin/migrate/source/d7/ThemeSettingsTest.php new file mode 100644 index 00000000..17b54fa1 --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Plugin/migrate/source/d7/ThemeSettingsTest.php @@ -0,0 +1,65 @@ + 1, + 'toggle_name' => 1, + 'toggle_slogan' => 1, + 'toggle_node_user_picture' => 1, + 'toggle_comment_user_picture' => 1, + 'toggle_comment_user_verification' => 1, + 'toggle_favicon' => 1, + 'toggle_main_menu' => 1, + 'toggle_secondary_menu' => 1, + 'default_logo' => 1, + 'logo_path' => ' ', + 'logo_upload' => ' ', + 'default_favicon' => 1, + 'favicon_path' => ' ', + 'favicon_upload' => ' ', + 'scheme' => 'firehouse', + ]; + + $tests[0]['source_data']['variable'] = [ + [ + 'name' => 'theme_bartik_settings', + 'value' => serialize($value), + ], + ]; + + // The expected results are nearly identical to the source data. + $tests[0]['expected_data'] = [ + [ + 'name' => 'theme_bartik_settings', + 'value' => $value, + ], + ]; + + return $tests; + } + +} diff --git a/core/modules/system/tests/src/Kernel/Render/ClassyTest.php b/core/modules/system/tests/src/Kernel/Render/ClassyTest.php index 76cf23ee..8dbb01e5 100644 --- a/core/modules/system/tests/src/Kernel/Render/ClassyTest.php +++ b/core/modules/system/tests/src/Kernel/Render/ClassyTest.php @@ -14,7 +14,7 @@ class ClassyTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array('system', 'twig_theme_test'); + public static $modules = ['system', 'twig_theme_test']; /** * {@inheritdoc} @@ -36,12 +36,12 @@ public function setUp() { /** * Test the classy theme. */ - function testClassyTheme() { + public function testClassyTheme() { drupal_set_message('An error occurred', 'error'); drupal_set_message('But then something nice happened'); - $messages = array( + $messages = [ '#type' => 'status_messages', - ); + ]; $this->render($messages); $this->assertNoText('custom-test-messages-class', 'The custom class attribute value added in the status messages preprocess function is not displayed as page content.'); } diff --git a/core/modules/system/tests/src/Kernel/Scripts/DbCommandBaseTest.php b/core/modules/system/tests/src/Kernel/Scripts/DbCommandBaseTest.php index 1aa2f667..cb7f5eb7 100644 --- a/core/modules/system/tests/src/Kernel/Scripts/DbCommandBaseTest.php +++ b/core/modules/system/tests/src/Kernel/Scripts/DbCommandBaseTest.php @@ -8,6 +8,7 @@ namespace Drupal\Tests\system\Kernel\Scripts; use Drupal\Core\Command\DbCommandBase; +use Drupal\Core\Database\ConnectionNotDefinedException; use Drupal\Core\Database\Database; use Drupal\KernelTests\KernelTestBase; use Symfony\Component\Console\Input\InputInterface; @@ -42,8 +43,6 @@ public function testSpecifyDatabaseKey() { /** * Invalid database names will throw a useful exception. - * - * @expectedException \Drupal\Core\Database\ConnectionNotDefinedException */ public function testSpecifyDatabaseDoesNotExist() { $command = new DbCommandBaseTester(); @@ -51,6 +50,7 @@ public function testSpecifyDatabaseDoesNotExist() { $command_tester->execute([ '--database' => 'dne' ]); + $this->setExpectedException(ConnectionNotDefinedException::class); $command->getDatabaseConnection($command_tester->getInput()); } diff --git a/core/modules/system/tests/src/Kernel/Scripts/DbImportCommandTest.php b/core/modules/system/tests/src/Kernel/Scripts/DbImportCommandTest.php index c90d2266..8a292e50 100644 --- a/core/modules/system/tests/src/Kernel/Scripts/DbImportCommandTest.php +++ b/core/modules/system/tests/src/Kernel/Scripts/DbImportCommandTest.php @@ -51,10 +51,10 @@ class DbImportCommandTest extends KernelTestBase { * @requires extension pdo_sqlite */ public function testDbImportCommand() { - $connection_info = array( + $connection_info = [ 'driver' => 'sqlite', 'database' => ':memory:', - ); + ]; Database::addConnectionInfo($this->databasePrefix, 'default', $connection_info); $command = new DbImportCommand(); diff --git a/core/modules/system/tests/src/Kernel/System/CronQueueTest.php b/core/modules/system/tests/src/Kernel/System/CronQueueTest.php index c51ee5a8..649a2c75 100644 --- a/core/modules/system/tests/src/Kernel/System/CronQueueTest.php +++ b/core/modules/system/tests/src/Kernel/System/CronQueueTest.php @@ -55,7 +55,7 @@ public function testExceptions() { $queue = $this->container->get('queue')->get('cron_queue_test_exception'); // Enqueue an item for processing. - $queue->createItem(array($this->randomMachineName() => $this->randomMachineName())); + $queue->createItem([$this->randomMachineName() => $this->randomMachineName()]); // Run cron; the worker for this queue should throw an exception and handle // it. diff --git a/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php b/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php index 8e6f79e0..ebdac3ce 100644 --- a/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php +++ b/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php @@ -11,7 +11,7 @@ */ class InfoAlterTest extends KernelTestBase { - public static $modules = array('system'); + public static $modules = ['system']; /** * Tests that theme .info.yml data is rebuild after enabling a module. @@ -20,13 +20,13 @@ class InfoAlterTest extends KernelTestBase { * hook_system_info_alter() is enabled. Also tests if core *_list() functions * return freshly altered info. */ - function testSystemInfoAlter() { + public function testSystemInfoAlter() { \Drupal::state()->set('module_required_test.hook_system_info_alter', TRUE); $info = system_rebuild_module_data(); $this->assertFalse(isset($info['node']->info['required']), 'Before the module_required_test is installed the node module is not required.'); // Enable the test module. - \Drupal::service('module_installer')->install(array('module_required_test'), FALSE); + \Drupal::service('module_installer')->install(['module_required_test'], FALSE); $this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_required_test'), 'Test required module is enabled.'); $info = system_rebuild_module_data(); diff --git a/core/modules/system/tests/src/Kernel/Timezone/TimezoneTest.php b/core/modules/system/tests/src/Kernel/Timezone/TimezoneTest.php new file mode 100644 index 00000000..8a5385c2 --- /dev/null +++ b/core/modules/system/tests/src/Kernel/Timezone/TimezoneTest.php @@ -0,0 +1,64 @@ +assertInternalType('array', $result); + $this->assertArrayHasKey('Africa/Dar_es_Salaam', $result); + $this->assertEquals('Africa/Dar es Salaam', $result['Africa/Dar_es_Salaam']); + + // Tests time zone grouping. + $result = system_time_zones(NULL, TRUE); + + // Check a two-level time zone. + $this->assertInternalType('array', $result); + $this->assertArrayHasKey('Africa', $result); + $this->assertArrayHasKey('Africa/Dar_es_Salaam', $result['Africa']); + $this->assertEquals('Dar es Salaam', $result['Africa']['Africa/Dar_es_Salaam']); + + // Check a three level time zone. + $this->assertArrayHasKey('America', $result); + $this->assertArrayHasKey('America/Indiana/Indianapolis', $result['America']); + $this->assertEquals('Indianapolis (Indiana)', $result['America']['America/Indiana/Indianapolis']); + + // Make sure grouping hasn't erroneously created an entry with just the + // first and second levels. + $this->assertArrayNotHasKey('America/Indiana', $result['America']); + + // Make sure grouping hasn't duplicated an entry with just the first and + // third levels. + $this->assertArrayNotHasKey('America/Indianapolis', $result['America']); + + // Make sure that a grouped item isn't duplicated at the top level of the + // results array. + $this->assertArrayNotHasKey('America/Indiana/Indianapolis', $result); + + // Test that the ungrouped and grouped results have the same number of + // items. + $ungrouped_count = count(system_time_zones()); + $grouped_result = system_time_zones(NULL, TRUE); + $grouped_count = 0; + array_walk_recursive($grouped_result, function () use + (&$grouped_count) { + $grouped_count++; + }); + $this->assertEquals($ungrouped_count, $grouped_count); + } + +} diff --git a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php index 040cf1a3..b334e641 100644 --- a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php +++ b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php @@ -29,25 +29,25 @@ protected function setUp() { */ public function testSystemTokenRecognition() { // Generate prefixes and suffixes for the token context. - $tests = array( - array('prefix' => 'this is the ', 'suffix' => ' site'), - array('prefix' => 'this is the', 'suffix' => 'site'), - array('prefix' => '[', 'suffix' => ']'), - array('prefix' => '', 'suffix' => ']]]'), - array('prefix' => '[[[', 'suffix' => ''), - array('prefix' => ':[:', 'suffix' => '--]'), - array('prefix' => '-[-', 'suffix' => ':]:'), - array('prefix' => '[:', 'suffix' => ']'), - array('prefix' => '[site:', 'suffix' => ':name]'), - array('prefix' => '[site:', 'suffix' => ']'), - ); + $tests = [ + ['prefix' => 'this is the ', 'suffix' => ' site'], + ['prefix' => 'this is the', 'suffix' => 'site'], + ['prefix' => '[', 'suffix' => ']'], + ['prefix' => '', 'suffix' => ']]]'], + ['prefix' => '[[[', 'suffix' => ''], + ['prefix' => ':[:', 'suffix' => '--]'], + ['prefix' => '-[-', 'suffix' => ':]:'], + ['prefix' => '[:', 'suffix' => ']'], + ['prefix' => '[site:', 'suffix' => ':name]'], + ['prefix' => '[site:', 'suffix' => ']'], + ]; // Check if the token is recognized in each of the contexts. foreach ($tests as $test) { $input = $test['prefix'] . '[site:name]' . $test['suffix']; $expected = $test['prefix'] . 'Drupal' . $test['suffix']; - $output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId())); - $this->assertTrue($output == $expected, format_string('Token recognized in string %string', array('%string' => $input))); + $output = $this->tokenService->replace($input, [], ['langcode' => $this->interfaceLanguage->getId()]); + $this->assertTrue($output == $expected, format_string('Token recognized in string %string', ['%string' => $input])); } // Test token replacement when the string contains no tokens. @@ -67,12 +67,12 @@ public function testClear() { // Replace with the clear parameter, only the valid token should remain. $target = Html::escape($this->config('system.site')->get('name')); - $result = $this->tokenService->replace($source, array(), array('langcode' => $this->interfaceLanguage->getId(), 'clear' => TRUE)); + $result = $this->tokenService->replace($source, [], ['langcode' => $this->interfaceLanguage->getId(), 'clear' => TRUE]); $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.'); $target .= '[user:name]'; $target .= '[bogus:token]'; - $result = $this->tokenService->replace($source, array(), array('langcode' => $this->interfaceLanguage->getId())); + $result = $this->tokenService->replace($source, [], ['langcode' => $this->interfaceLanguage->getId()]); $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.'); } @@ -80,10 +80,10 @@ public function testClear() { * Tests the generation of all system site information tokens. */ public function testSystemSiteTokenReplacement() { - $url_options = array( + $url_options = [ 'absolute' => TRUE, 'language' => $this->interfaceLanguage, - ); + ]; $slogan = 'Slogan'; $safe_slogan = Xss::filterAdmin($slogan); @@ -98,12 +98,12 @@ public function testSystemSiteTokenReplacement() { // Generate and test tokens. - $tests = array(); + $tests = []; $tests['[site:name]'] = Html::escape($config->get('name')); $tests['[site:slogan]'] = $safe_slogan; $tests['[site:mail]'] = $config->get('mail'); $tests['[site:url]'] = \Drupal::url('', [], $url_options); - $tests['[site:url-brief]'] = preg_replace(array('!^https?://!', '!/$!'), '', \Drupal::url('', [], $url_options)); + $tests['[site:url-brief]'] = preg_replace(['!^https?://!', '!/$!'], '', \Drupal::url('', [], $url_options)); $tests['[site:login-url]'] = \Drupal::url('user.page', [], $url_options); $base_bubbleable_metadata = new BubbleableMetadata(); @@ -122,7 +122,7 @@ public function testSystemSiteTokenReplacement() { foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); - $output = $this->tokenService->replace($input, array(), array('langcode' => $this->interfaceLanguage->getId()), $bubbleable_metadata); + $output = $this->tokenService->replace($input, [], ['langcode' => $this->interfaceLanguage->getId()], $bubbleable_metadata); $this->assertEqual($output, $expected, new FormattableMarkup('System site information token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } @@ -136,21 +136,21 @@ public function testSystemDateTokenReplacement() { $date = REQUEST_TIME - 3600; // Generate and test tokens. - $tests = array(); + $tests = []; $date_formatter = \Drupal::service('date.formatter'); $tests['[date:short]'] = $date_formatter->format($date, 'short', '', NULL, $this->interfaceLanguage->getId()); $tests['[date:medium]'] = $date_formatter->format($date, 'medium', '', NULL, $this->interfaceLanguage->getId()); $tests['[date:long]'] = $date_formatter->format($date, 'long', '', NULL, $this->interfaceLanguage->getId()); $tests['[date:custom:m/j/Y]'] = $date_formatter->format($date, 'custom', 'm/j/Y', NULL, $this->interfaceLanguage->getId()); - $tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, array('langcode' => $this->interfaceLanguage->getId())); + $tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, ['langcode' => $this->interfaceLanguage->getId()]); $tests['[date:raw]'] = Xss::filter($date); // Test to make sure that we generated something for each token. $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = $this->tokenService->replace($input, array('date' => $date), array('langcode' => $this->interfaceLanguage->getId())); - $this->assertEqual($output, $expected, format_string('Date token %token replaced.', array('%token' => $input))); + $output = $this->tokenService->replace($input, ['date' => $date], ['langcode' => $this->interfaceLanguage->getId()]); + $this->assertEqual($output, $expected, format_string('Date token %token replaced.', ['%token' => $input])); } } diff --git a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTestBase.php b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTestBase.php index 0e2a3fc6..2c833906 100644 --- a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTestBase.php +++ b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTestBase.php @@ -28,12 +28,12 @@ abstract class TokenReplaceKernelTestBase extends EntityKernelTestBase { * * @var array */ - public static $modules = array('system'); + public static $modules = ['system']; protected function setUp() { parent::setUp(); // Install default system configuration. - $this->installConfig(array('system')); + $this->installConfig(['system']); \Drupal::service('router.builder')->rebuild(); $this->interfaceLanguage = \Drupal::languageManager()->getCurrentLanguage(); diff --git a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php index eb095a78..2fe4a833 100644 --- a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php +++ b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php @@ -11,6 +11,7 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Link; use Drupal\Core\Access\AccessResultAllowed; +use Drupal\Core\Path\PathMatcherInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Url; use Drupal\Core\Utility\LinkGeneratorInterface; @@ -84,6 +85,13 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { */ protected $currentPath; + /** + * The mocked path matcher service. + * + * @var \Drupal\Core\Path\PathMatcherInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $pathMatcher; + /** * {@inheritdoc} * @@ -94,7 +102,7 @@ protected function setUp() { $this->requestMatcher = $this->getMock('\Symfony\Component\Routing\Matcher\RequestMatcherInterface'); - $config_factory = $this->getConfigFactoryStub(array('system.site' => array('front' => 'test_frontpage'))); + $config_factory = $this->getConfigFactoryStub(['system.site' => ['front' => 'test_frontpage']]); $this->pathProcessor = $this->getMock('\Drupal\Core\PathProcessor\InboundPathProcessorInterface'); $this->context = $this->getMock('\Drupal\Core\Routing\RequestContext'); @@ -106,6 +114,8 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); + $this->pathMatcher = $this->getMock(PathMatcherInterface::class); + $this->builder = new TestPathBasedBreadcrumbBuilder( $this->context, $this->accessManager, @@ -114,7 +124,8 @@ protected function setUp() { $config_factory, $this->titleResolver, $this->currentUser, - $this->currentPath + $this->currentPath, + $this->pathMatcher ); $this->builder->setStringTranslation($this->getStringTranslationStub()); @@ -136,9 +147,9 @@ protected function setUp() { * @covers ::build */ public function testBuildOnFrontpage() { - $this->context->expects($this->once()) - ->method('getPathInfo') - ->will($this->returnValue('/')); + $this->pathMatcher->expects($this->once()) + ->method('isFrontPage') + ->willReturn(TRUE); $breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); $this->assertEquals([], $breadcrumb->getLinks()); @@ -180,13 +191,13 @@ public function testBuildWithTwoPathElements() { $this->requestMatcher->expects($this->exactly(1)) ->method('matchRequest') - ->will($this->returnCallback(function(Request $request) use ($route_1) { + ->will($this->returnCallback(function (Request $request) use ($route_1) { if ($request->getPathInfo() == '/example') { - return array( + return [ RouteObjectInterface::ROUTE_NAME => 'example', RouteObjectInterface::ROUTE_OBJECT => $route_1, - '_raw_variables' => new ParameterBag(array()), - ); + '_raw_variables' => new ParameterBag([]), + ]; } })); @@ -216,20 +227,20 @@ public function testBuildWithThreePathElements() { $this->requestMatcher->expects($this->exactly(2)) ->method('matchRequest') - ->will($this->returnCallback(function(Request $request) use ($route_1, $route_2) { + ->will($this->returnCallback(function (Request $request) use ($route_1, $route_2) { if ($request->getPathInfo() == '/example/bar') { - return array( + return [ RouteObjectInterface::ROUTE_NAME => 'example_bar', RouteObjectInterface::ROUTE_OBJECT => $route_1, - '_raw_variables' => new ParameterBag(array()), - ); + '_raw_variables' => new ParameterBag([]), + ]; } elseif ($request->getPathInfo() == '/example') { - return array( + return [ RouteObjectInterface::ROUTE_NAME => 'example', RouteObjectInterface::ROUTE_OBJECT => $route_2, - '_raw_variables' => new ParameterBag(array()), - ); + '_raw_variables' => new ParameterBag([]), + ]; } })); @@ -286,11 +297,11 @@ public function testBuildWithException($exception_class, $exception_argument) { * @see \Drupal\Tests\system\Unit\Breadcrumbs\PathBasedBreadcrumbBuilderTest::testBuildWithException() */ public function providerTestBuildWithException() { - return array( - array('Drupal\Core\ParamConverter\ParamNotConvertedException', ''), - array('Symfony\Component\Routing\Exception\MethodNotAllowedException', array()), - array('Symfony\Component\Routing\Exception\ResourceNotFoundException', ''), - ); + return [ + ['Drupal\Core\ParamConverter\ParamNotConvertedException', ''], + ['Symfony\Component\Routing\Exception\MethodNotAllowedException', []], + ['Symfony\Component\Routing\Exception\ResourceNotFoundException', ''], + ]; } /** @@ -310,7 +321,7 @@ public function testBuildWithNonProcessedPath() { $this->requestMatcher->expects($this->any()) ->method('matchRequest') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $breadcrumb = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); @@ -346,13 +357,13 @@ public function testBuildWithUserPath() { $this->requestMatcher->expects($this->exactly(1)) ->method('matchRequest') - ->will($this->returnCallback(function(Request $request) use ($route_1) { + ->will($this->returnCallback(function (Request $request) use ($route_1) { if ($request->getPathInfo() == '/user/1') { - return array( + return [ RouteObjectInterface::ROUTE_NAME => 'user_page', RouteObjectInterface::ROUTE_OBJECT => $route_1, - '_raw_variables' => new ParameterBag(array()), - ); + '_raw_variables' => new ParameterBag([]), + ]; } })); diff --git a/core/modules/system/tests/src/Unit/Installer/InstallTranslationFilePatternTest.php b/core/modules/system/tests/src/Unit/Installer/InstallTranslationFilePatternTest.php index fd2b8849..0dd7510e 100644 --- a/core/modules/system/tests/src/Unit/Installer/InstallTranslationFilePatternTest.php +++ b/core/modules/system/tests/src/Unit/Installer/InstallTranslationFilePatternTest.php @@ -45,11 +45,11 @@ public function testFilesPatternValid($langcode, $filename) { * @return array */ public function providerValidTranslationFiles() { - return array( - array('hu', 'drupal-8.0.0-alpha1.hu.po'), - array('ta', 'drupal-8.10.10-beta12.ta.po'), - array('hi', 'drupal-8.0.0.hi.po'), - ); + return [ + ['hu', 'drupal-8.0.0-alpha1.hu.po'], + ['ta', 'drupal-8.10.10-beta12.ta.po'], + ['hi', 'drupal-8.0.0.hi.po'], + ]; } /** @@ -64,13 +64,13 @@ public function testFilesPatternInvalid($langcode, $filename) { * @return array */ public function providerInvalidTranslationFiles() { - return array( - array('hu', 'drupal-alpha1-*-hu.po'), - array('ta', 'drupal-beta12.ta'), - array('hi', 'drupal-hi.po'), - array('de', 'drupal-dummy-de.po'), - array('hu', 'drupal-10.0.1.alpha1-hu.po'), - ); + return [ + ['hu', 'drupal-alpha1-*-hu.po'], + ['ta', 'drupal-beta12.ta'], + ['hi', 'drupal-hi.po'], + ['de', 'drupal-dummy-de.po'], + ['hu', 'drupal-10.0.1.alpha1-hu.po'], + ]; } } diff --git a/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php b/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php index c2014d50..2423668e 100644 --- a/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php +++ b/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php @@ -137,7 +137,7 @@ public function providerTestBuildCacheability() { ] ]; - $get_built_element = function(MenuLinkTreeElement $element) { + $get_built_element = function (MenuLinkTreeElement $element) { $return = [ 'attributes' => new Attribute(), 'title' => $element->link->getTitle(), diff --git a/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php b/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php index 9f0afc62..cfa51fa3 100644 --- a/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php +++ b/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php @@ -25,20 +25,20 @@ class SystemLocalTasksTest extends LocalTaskIntegrationTestBase { protected function setUp() { parent::setUp(); - $this->directoryList = array( + $this->directoryList = [ 'system' => 'core/modules/system', - ); + ]; $this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface'); $theme = new Extension($this->root, 'theme', '/core/themes/bartik', 'bartik.info.yml'); $theme->status = 1; - $theme->info = array('name' => 'bartik'); + $theme->info = ['name' => 'bartik']; $this->themeHandler->expects($this->any()) ->method('listInfo') - ->will($this->returnValue(array( + ->will($this->returnValue([ 'bartik' => $theme, - ))); + ])); $this->themeHandler->expects($this->any()) ->method('hasUi') ->with('bartik') @@ -59,13 +59,16 @@ public function testSystemAdminLocalTasks($route, $expected) { * Provides a list of routes to test. */ public function getSystemAdminRoutes() { - return array( - array('system.admin_content', array(array('system.admin_content'))), - array('system.theme_settings_theme', array( - array('system.themes_page', 'system.theme_settings'), - array('system.theme_settings_global', 'system.theme_settings_theme:bartik'), - )), - ); + return [ + ['system.admin_content', [['system.admin_content']]], + [ + 'system.theme_settings_theme', + [ + ['system.themes_page', 'system.theme_settings'], + ['system.theme_settings_global', 'system.theme_settings_theme:bartik'], + ], + ], + ]; } } diff --git a/core/modules/system/tests/src/Unit/Transliteration/MachineNameControllerTest.php b/core/modules/system/tests/src/Unit/Transliteration/MachineNameControllerTest.php index 90696fda..689c1782 100644 --- a/core/modules/system/tests/src/Unit/Transliteration/MachineNameControllerTest.php +++ b/core/modules/system/tests/src/Unit/Transliteration/MachineNameControllerTest.php @@ -53,21 +53,21 @@ protected function setUp() { * - The expected content of the JSONresponse. */ public function providerTestMachineNameController() { - $valid_data = array( - array(array('text' => 'Bob', 'langcode' => 'en'), '"Bob"'), - array(array('text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE), '"bob"'), - array(array('text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Bob'), '"Alice"'), - array(array('text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Tom'), '"Bob"'), - array(array('text' => 'Äwesome', 'langcode' => 'en', 'lowercase' => TRUE), '"awesome"'), - array(array('text' => 'Äwesome', 'langcode' => 'de', 'lowercase' => TRUE), '"aewesome"'), + $valid_data = [ + [['text' => 'Bob', 'langcode' => 'en'], '"Bob"'], + [['text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE], '"bob"'], + [['text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Bob'], '"Alice"'], + [['text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Tom'], '"Bob"'], + [['text' => 'Äwesome', 'langcode' => 'en', 'lowercase' => TRUE], '"awesome"'], + [['text' => 'Äwesome', 'langcode' => 'de', 'lowercase' => TRUE], '"aewesome"'], // Tests special characters replacement in the input text. - array(array('text' => 'B?!"@\/-ob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.]+'), '"b_ob_e"'), + [['text' => 'B?!"@\/-ob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.]+'], '"b_ob_e"'], // Tests @ character in the replace_pattern regex. - array(array('text' => 'Bob@e\0', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.@]+'), '"bob@e_0"'), + [['text' => 'Bob@e\0', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.@]+'], '"bob@e_0"'], // Tests null byte in the replace_pattern regex. - array(array('text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"), '"bob"'), - array(array('text' => 'Bob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"), '"fail()"'), - ); + [['text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"], '"bob"'], + [['text' => 'Bob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"], '"fail()"'], + ]; $valid_data = array_map(function ($data) { if (isset($data[0]['replace_pattern'])) { diff --git a/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.engine b/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.engine index 04666dc1..21cf116d 100644 --- a/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.engine +++ b/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.engine @@ -21,7 +21,7 @@ function nyan_cat_init(Extension $theme) { * Implements hook_theme(). */ function nyan_cat_theme($existing, $type, $theme, $path) { - $templates = drupal_find_theme_functions($existing, array($theme)); + $templates = drupal_find_theme_functions($existing, [$theme]); $templates += drupal_find_theme_templates($existing, '.nyan-cat.html', $path); return $templates; } diff --git a/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.info.yml b/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.info.yml index a233007c..cdb658c9 100644 --- a/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.info.yml +++ b/core/modules/system/tests/themes/engines/nyan_cat/nyan_cat.info.yml @@ -4,8 +4,8 @@ name: Nyan cat # version: VERSION package: Core -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml b/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml index 40cbaa7d..0e451e06 100644 --- a/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml +++ b/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml @@ -23,8 +23,8 @@ libraries-extend: classy/base: - test_basetheme/global-styling -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_ckeditor_stylesheets_external/test_ckeditor_stylesheets_external.info.yml b/core/modules/system/tests/themes/test_ckeditor_stylesheets_external/test_ckeditor_stylesheets_external.info.yml index 45266490..4ae05469 100644 --- a/core/modules/system/tests/themes/test_ckeditor_stylesheets_external/test_ckeditor_stylesheets_external.info.yml +++ b/core/modules/system/tests/themes/test_ckeditor_stylesheets_external/test_ckeditor_stylesheets_external.info.yml @@ -8,8 +8,8 @@ base theme: false ckeditor_stylesheets: - https://fonts.googleapis.com/css?family=Open+Sans -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_ckeditor_stylesheets_protocol_relative/test_ckeditor_stylesheets_protocol_relative.info.yml b/core/modules/system/tests/themes/test_ckeditor_stylesheets_protocol_relative/test_ckeditor_stylesheets_protocol_relative.info.yml index 26e4d955..3e282931 100644 --- a/core/modules/system/tests/themes/test_ckeditor_stylesheets_protocol_relative/test_ckeditor_stylesheets_protocol_relative.info.yml +++ b/core/modules/system/tests/themes/test_ckeditor_stylesheets_protocol_relative/test_ckeditor_stylesheets_protocol_relative.info.yml @@ -8,8 +8,8 @@ base theme: false ckeditor_stylesheets: - //fonts.googleapis.com/css?family=Open+Sans -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_ckeditor_stylesheets_relative/test_ckeditor_stylesheets_relative.info.yml b/core/modules/system/tests/themes/test_ckeditor_stylesheets_relative/test_ckeditor_stylesheets_relative.info.yml index 5d4de622..879c257d 100644 --- a/core/modules/system/tests/themes/test_ckeditor_stylesheets_relative/test_ckeditor_stylesheets_relative.info.yml +++ b/core/modules/system/tests/themes/test_ckeditor_stylesheets_relative/test_ckeditor_stylesheets_relative.info.yml @@ -8,8 +8,8 @@ base theme: false ckeditor_stylesheets: - css/yokotsoko.css -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_invalid_basetheme/test_invalid_basetheme.info.yml b/core/modules/system/tests/themes/test_invalid_basetheme/test_invalid_basetheme.info.yml index 4b52e3df..a803f035 100644 --- a/core/modules/system/tests/themes/test_invalid_basetheme/test_invalid_basetheme.info.yml +++ b/core/modules/system/tests/themes/test_invalid_basetheme/test_invalid_basetheme.info.yml @@ -5,8 +5,8 @@ description: 'Test theme which has a non-existent base theme.' # core: 8.x base theme: not_real_test_basetheme -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_invalid_basetheme_sub/test_invalid_basetheme_sub.info.yml b/core/modules/system/tests/themes/test_invalid_basetheme_sub/test_invalid_basetheme_sub.info.yml index d2fa9ef1..702ec040 100644 --- a/core/modules/system/tests/themes/test_invalid_basetheme_sub/test_invalid_basetheme_sub.info.yml +++ b/core/modules/system/tests/themes/test_invalid_basetheme_sub/test_invalid_basetheme_sub.info.yml @@ -5,8 +5,8 @@ description: 'Test theme which has a non-existent base theme in the base chain.' # core: 8.x base theme: test_invalid_basetheme -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_invalid_core/test_invalid_core.info.yml b/core/modules/system/tests/themes/test_invalid_core/test_invalid_core.info.yml index 7fd0f6bd..f20be1ba 100644 --- a/core/modules/system/tests/themes/test_invalid_core/test_invalid_core.info.yml +++ b/core/modules/system/tests/themes/test_invalid_core/test_invalid_core.info.yml @@ -4,8 +4,8 @@ description: 'Test theme which has an invalid core version.' # version: VERSION # core: 7.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_invalid_engine/test_invalid_engine.info.yml b/core/modules/system/tests/themes/test_invalid_engine/test_invalid_engine.info.yml index 476f3229..150442ce 100644 --- a/core/modules/system/tests/themes/test_invalid_engine/test_invalid_engine.info.yml +++ b/core/modules/system/tests/themes/test_invalid_engine/test_invalid_engine.info.yml @@ -6,8 +6,8 @@ description: 'Test theme which has a non-existent theme engine.' engine: not_real_engine base theme: false -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_invalid_region/test_invalid_region.info.yml b/core/modules/system/tests/themes/test_invalid_region/test_invalid_region.info.yml index 1efa59f0..29c2aa00 100644 --- a/core/modules/system/tests/themes/test_invalid_region/test_invalid_region.info.yml +++ b/core/modules/system/tests/themes/test_invalid_region/test_invalid_region.info.yml @@ -7,8 +7,8 @@ description: 'Test theme which has a non-existent content region.' regions: - foo: Foo -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_stable/test_stable.info.yml b/core/modules/system/tests/themes/test_stable/test_stable.info.yml index f565d62f..23d17c0d 100644 --- a/core/modules/system/tests/themes/test_stable/test_stable.info.yml +++ b/core/modules/system/tests/themes/test_stable/test_stable.info.yml @@ -4,8 +4,8 @@ description: A theme to test that stable is set as the default. # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml b/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml index 37eb7bac..9b7ea518 100644 --- a/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml +++ b/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml @@ -5,8 +5,8 @@ description: 'Test theme which uses test_subtheme as the base theme.' # core: 8.x base theme: test_subtheme -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml b/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml index 8f7b246e..8b9ec5c6 100644 --- a/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml +++ b/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml @@ -14,8 +14,8 @@ libraries-extend: classy/base: - test_subtheme/global-styling -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_subtheme/test_subtheme.theme b/core/modules/system/tests/themes/test_subtheme/test_subtheme.theme index cd312dbc..78333a9a 100644 --- a/core/modules/system/tests/themes/test_subtheme/test_subtheme.theme +++ b/core/modules/system/tests/themes/test_subtheme/test_subtheme.theme @@ -23,7 +23,7 @@ function test_subtheme_views_post_render(ViewExecutable $view, &$output, CachePl // We append the function name to the title for test to check for. $view->setTitle($view->getTitle() . ":" . __FUNCTION__); if ($view->id() == 'test_page_display') { - $output['#rows'][0]['#title'] = t('%total_rows items found.', array('%total_rows' => $view->total_rows)); + $output['#rows'][0]['#title'] = t('%total_rows items found.', ['%total_rows' => $view->total_rows]); } } diff --git a/core/modules/system/tests/themes/test_theme/js/collapse.es6.js b/core/modules/system/tests/themes/test_theme/js/collapse.es6.js new file mode 100644 index 00000000..4d66841e --- /dev/null +++ b/core/modules/system/tests/themes/test_theme/js/collapse.es6.js @@ -0,0 +1,4 @@ +/** + * @file + * Test JS asset file for test_theme.theme. + */ diff --git a/core/modules/system/tests/themes/test_theme/js/collapse.js b/core/modules/system/tests/themes/test_theme/js/collapse.js index 4d66841e..9d11a7c1 100644 --- a/core/modules/system/tests/themes/test_theme/js/collapse.js +++ b/core/modules/system/tests/themes/test_theme/js/collapse.js @@ -1,4 +1,6 @@ /** - * @file - * Test JS asset file for test_theme.theme. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ \ No newline at end of file diff --git a/core/modules/system/tests/themes/test_theme/src/ThemeClass.php b/core/modules/system/tests/themes/test_theme/src/ThemeClass.php index af5109a0..f0f08038 100644 --- a/core/modules/system/tests/themes/test_theme/src/ThemeClass.php +++ b/core/modules/system/tests/themes/test_theme/src/ThemeClass.php @@ -5,4 +5,4 @@ /** * Represents a random class, used to test if themes can provide classes. */ -class ThemeClass { } +class ThemeClass {} diff --git a/core/modules/system/tests/themes/test_theme/test_theme.info.yml b/core/modules/system/tests/themes/test_theme/test_theme.info.yml index 7ba93235..ee7fc246 100644 --- a/core/modules/system/tests/themes/test_theme/test_theme.info.yml +++ b/core/modules/system/tests/themes/test_theme/test_theme.info.yml @@ -66,8 +66,8 @@ regions: left: Left right: Right -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_having_veery_long_name_which_is_too_long/test_theme_having_veery_long_name_which_is_too_long.info.yml b/core/modules/system/tests/themes/test_theme_having_veery_long_name_which_is_too_long/test_theme_having_veery_long_name_which_is_too_long.info.yml index dda6b1f6..7c7bb8b5 100644 --- a/core/modules/system/tests/themes/test_theme_having_veery_long_name_which_is_too_long/test_theme_having_veery_long_name_which_is_too_long.info.yml +++ b/core/modules/system/tests/themes/test_theme_having_veery_long_name_which_is_too_long/test_theme_having_veery_long_name_which_is_too_long.info.yml @@ -3,8 +3,8 @@ type: theme name: 'Test theme with a too long name' # version: VERSION -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_libraries_empty/test_theme_libraries_empty.info.yml b/core/modules/system/tests/themes/test_theme_libraries_empty/test_theme_libraries_empty.info.yml index b8d9b74a..cf51a1eb 100644 --- a/core/modules/system/tests/themes/test_theme_libraries_empty/test_theme_libraries_empty.info.yml +++ b/core/modules/system/tests/themes/test_theme_libraries_empty/test_theme_libraries_empty.info.yml @@ -7,8 +7,8 @@ base theme: classy libraries: -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_libraries_extend/test_theme_libraries_extend.info.yml b/core/modules/system/tests/themes/test_theme_libraries_extend/test_theme_libraries_extend.info.yml index 1e7d348c..caecd574 100644 --- a/core/modules/system/tests/themes/test_theme_libraries_extend/test_theme_libraries_extend.info.yml +++ b/core/modules/system/tests/themes/test_theme_libraries_extend/test_theme_libraries_extend.info.yml @@ -14,8 +14,8 @@ libraries-extend: - not_a_string: expected: 'an exception' -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml b/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml index c97b5b5d..6d465b23 100644 --- a/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml +++ b/core/modules/system/tests/themes/test_theme_libraries_override_with_drupal_settings/test_theme_libraries_override_with_drupal_settings.info.yml @@ -11,8 +11,8 @@ libraries-override: drupalSettings: ajaxPageState: { } -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml b/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml index f95fd1a1..355ebd32 100644 --- a/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml +++ b/core/modules/system/tests/themes/test_theme_libraries_override_with_invalid_asset/test_theme_libraries_override_with_invalid_asset.info.yml @@ -10,8 +10,8 @@ libraries-override: core/drupal.dialog: css: false -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_nyan_cat_engine/test_theme_nyan_cat_engine.info.yml b/core/modules/system/tests/themes/test_theme_nyan_cat_engine/test_theme_nyan_cat_engine.info.yml index d119d766..efa90d5c 100644 --- a/core/modules/system/tests/themes/test_theme_nyan_cat_engine/test_theme_nyan_cat_engine.info.yml +++ b/core/modules/system/tests/themes/test_theme_nyan_cat_engine/test_theme_nyan_cat_engine.info.yml @@ -6,8 +6,8 @@ description: 'Theme for testing the theme system with the Nyan Cat theme engine' engine: nyan_cat base theme: false -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_settings/config/schema/test_theme_settings.schema.yml b/core/modules/system/tests/themes/test_theme_settings/config/schema/test_theme_settings.schema.yml new file mode 100644 index 00000000..a53e94a0 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_settings/config/schema/test_theme_settings.schema.yml @@ -0,0 +1,12 @@ +# Schema for the configuration files of the Test theme settings. + +test_theme_settings.settings: + type: theme_settings + label: 'Test theme settings' + mapping: + custom_logo: + type: sequence + label: 'Custom logo' + sequence: + type: integer + label: 'fids' diff --git a/core/modules/system/tests/themes/test_theme_settings/test_theme_settings.info.yml b/core/modules/system/tests/themes/test_theme_settings/test_theme_settings.info.yml new file mode 100644 index 00000000..6bf60581 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_settings/test_theme_settings.info.yml @@ -0,0 +1,12 @@ +name: 'Theme test theme-settings.php' +type: theme +description: 'Test theme that extends theme settings options via theme-settings.php file' +# version: VERSION +# core: 8.x +base theme: false + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_settings/theme-settings.php b/core/modules/system/tests/themes/test_theme_settings/theme-settings.php new file mode 100644 index 00000000..7f3c1395 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_settings/theme-settings.php @@ -0,0 +1,39 @@ + 'managed_file', + '#title' => t('Secondary logo.'), + '#default_value' => theme_get_setting('custom_logo'), + '#progress_indicator' => 'bar', + '#progress_message' => t('Please wait...'), + '#upload_location' => 'public://test', + '#upload_validators' => [ + 'file_validate_extensions' => ['gif png jpg jpeg'], + ], + ]; + + $form['#submit'][] = 'test_theme_settings_form_system_theme_settings_submit'; +} + +/** + * Test theme form settings submission handler. + */ +function test_theme_settings_form_system_theme_settings_submit(&$form, FormStateInterface $form_state) { + if ($file_id = $form_state->getValue(['custom_logo', '0'])) { + $file = File::load($file_id); + $file->setPermanent(); + $file->save(); + } +} diff --git a/core/modules/system/tests/themes/test_theme_theme/config/schema/test_theme_theme.schema.yml b/core/modules/system/tests/themes/test_theme_theme/config/schema/test_theme_theme.schema.yml new file mode 100644 index 00000000..fcd044ed --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_theme/config/schema/test_theme_theme.schema.yml @@ -0,0 +1,12 @@ +# Schema for the configuration files of the Test theme theme. + +test_theme_theme.settings: + type: theme_settings + label: 'Test theme settings' + mapping: + custom_logo: + type: sequence + label: 'Custom logo' + sequence: + type: integer + label: 'fids' diff --git a/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.info.yml b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.info.yml new file mode 100644 index 00000000..2230b3ac --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.info.yml @@ -0,0 +1,12 @@ +name: 'Theme test theme.theme file' +type: theme +description: 'Test theme that extends theme settings options via theme.theme file' +# version: VERSION +# core: 8.x +base theme: false + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.theme b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.theme new file mode 100644 index 00000000..937494f1 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.theme @@ -0,0 +1,40 @@ + 'managed_file', + '#title' => t('Secondary logo.'), + '#default_value' => theme_get_setting('custom_logo'), + '#progress_indicator' => 'bar', + '#progress_message' => t('Please wait...'), + '#upload_location' => 'public://test', + '#upload_validators' => [ + 'file_validate_extensions' => ['gif png jpg jpeg'], + ], + ]; + + $form['#submit'][] = 'test_theme_theme_form_system_theme_settings_submit'; +} + +/** + * Test theme form settings submission handler. + */ +function test_theme_theme_form_system_theme_settings_submit(&$form, FormStateInterface $form_state) { + if ($file_id = $form_state->getValue(['custom_logo', '0'])) { + $file = File::load($file_id); + $file->setPermanent(); + $file->save(); + } +} diff --git a/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml b/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml index 6ed80cdb..b9fb43ac 100644 --- a/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml +++ b/core/modules/system/tests/themes/test_theme_twig_registry_loader/test_theme_twig_registry_loader.info.yml @@ -4,8 +4,8 @@ description: 'Support module for Twig registry loader testing.' # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_twig_registry_loader_subtheme/test_theme_twig_registry_loader_subtheme.info.yml b/core/modules/system/tests/themes/test_theme_twig_registry_loader_subtheme/test_theme_twig_registry_loader_subtheme.info.yml index fa3242f9..fcae6887 100644 --- a/core/modules/system/tests/themes/test_theme_twig_registry_loader_subtheme/test_theme_twig_registry_loader_subtheme.info.yml +++ b/core/modules/system/tests/themes/test_theme_twig_registry_loader_subtheme/test_theme_twig_registry_loader_subtheme.info.yml @@ -5,8 +5,8 @@ description: 'Support module for Twig registry loader testing.' # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_theme_twig_registry_loader_theme/test_theme_twig_registry_loader_theme.info.yml b/core/modules/system/tests/themes/test_theme_twig_registry_loader_theme/test_theme_twig_registry_loader_theme.info.yml index d96b8b38..07c89568 100644 --- a/core/modules/system/tests/themes/test_theme_twig_registry_loader_theme/test_theme_twig_registry_loader_theme.info.yml +++ b/core/modules/system/tests/themes/test_theme_twig_registry_loader_theme/test_theme_twig_registry_loader_theme.info.yml @@ -5,8 +5,8 @@ description: 'Support module for Twig registry loader testing.' # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/system/tests/themes/test_wild_west/test_wild_west.info.yml b/core/modules/system/tests/themes/test_wild_west/test_wild_west.info.yml index 1204c5cf..7162ddff 100644 --- a/core/modules/system/tests/themes/test_wild_west/test_wild_west.info.yml +++ b/core/modules/system/tests/themes/test_wild_west/test_wild_west.info.yml @@ -5,8 +5,8 @@ description: A theme that doesn't use Stable as its base. It tests the wild west base theme: false # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/migration_templates/d6_taxonomy_term.yml b/core/modules/taxonomy/migration_templates/d6_taxonomy_term.yml index e5630fc6..e3c3e3d3 100644 --- a/core/modules/taxonomy/migration_templates/d6_taxonomy_term.yml +++ b/core/modules/taxonomy/migration_templates/d6_taxonomy_term.yml @@ -9,7 +9,7 @@ process: # the tid field to allow incremental migrations. tid: tid vid: - plugin: migration + plugin: migration_lookup migration: d6_taxonomy_vocabulary source: vid name: name @@ -22,7 +22,7 @@ process: method: process source: parent - - plugin: migration + plugin: migration_lookup migration: d6_taxonomy_term parent: plugin: default_value diff --git a/core/modules/taxonomy/migration_templates/d6_taxonomy_term_translation.yml b/core/modules/taxonomy/migration_templates/d6_taxonomy_term_translation.yml new file mode 100644 index 00000000..11af8cd4 --- /dev/null +++ b/core/modules/taxonomy/migration_templates/d6_taxonomy_term_translation.yml @@ -0,0 +1,39 @@ +id: d6_taxonomy_term_translation +label: Taxonomy terms +migration_tags: + - Drupal 6 +source: + plugin: d6_taxonomy_term + translations: true +process: + # If you are using this file to build a custom migration consider removing + # the tid field to allow incremental migrations. + tid: tid + langcode: language + vid: + plugin: migration + migration: d6_taxonomy_vocabulary + source: vid + name: name + description: description + weight: weight + # Only attempt to stub real (non-zero) parents. + parent_id: + - + plugin: skip_on_empty + method: process + source: parent + - + plugin: migration + migration: d6_taxonomy_term + parent: + plugin: default_value + default_value: 0 + source: '@parent_id' + changed: timestamp +destination: + plugin: entity:taxonomy_term +migration_dependencies: + required: + - d6_taxonomy_vocabulary + - d6_taxonomy_term diff --git a/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary.yml b/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary.yml index f7f58840..336f502e 100644 --- a/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary.yml +++ b/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary.yml @@ -10,11 +10,17 @@ process: plugin: machine_name source: name - - plugin: dedupe_entity + plugin: make_unique_entity_field entity_type: taxonomy_vocabulary field: vid length: 32 migrated: true + - + # This plugin checks if the vocabulary being migrated is the one used by + # Forum. If so, we use the machine name that Forum expects. Otherwise, we + # leave it unchanged. + plugin: forum_vocabulary + machine_name: forums label: name name: name description: description diff --git a/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary_translation.yml b/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary_translation.yml new file mode 100644 index 00000000..dbb1793f --- /dev/null +++ b/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary_translation.yml @@ -0,0 +1,27 @@ +id: d6_taxonomy_vocabulary_translation +label: Taxonomy vocabularies +migration_tags: + - Drupal 6 +source: + plugin: d6_taxonomy_vocabulary_translation +process: + vid: + - + plugin: machine_name + source: name + - + plugin: substr + length: 32 + langcode: language + property: + plugin: static_map + source: property + map: + name: name + description: description + translation: translation +destination: + plugin: entity:taxonomy_vocabulary +migration_dependencies: + required: + - d6_taxonomy_vocabulary diff --git a/core/modules/taxonomy/migration_templates/d6_term_node.yml b/core/modules/taxonomy/migration_templates/d6_term_node.yml index 63aec856..846334d4 100644 --- a/core/modules/taxonomy/migration_templates/d6_term_node.yml +++ b/core/modules/taxonomy/migration_templates/d6_term_node.yml @@ -8,7 +8,7 @@ source: process: nid: - - plugin: migration + plugin: migration_lookup migration: d6_node source: nid - diff --git a/core/modules/taxonomy/migration_templates/d6_term_node_revision.yml b/core/modules/taxonomy/migration_templates/d6_term_node_revision.yml index cf1c6829..91c8362e 100644 --- a/core/modules/taxonomy/migration_templates/d6_term_node_revision.yml +++ b/core/modules/taxonomy/migration_templates/d6_term_node_revision.yml @@ -8,7 +8,7 @@ source: process: vid: - - plugin: migration + plugin: migration_lookup migration: d6_node source: vid - diff --git a/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_display.yml b/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_display.yml index e8d04c0c..0a624582 100644 --- a/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_display.yml +++ b/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_display.yml @@ -11,15 +11,45 @@ source: label: hidden type: entity_reference_label weight: 20 + field_prefix: field_ process: entity_type: 'constants/entity_type' view_mode: 'constants/view_mode' options: 'constants/options' - bundle: type + bundle: + - + plugin: migration_lookup + migration: d6_node_type + source: type + - + plugin: skip_on_empty + method: row + # This value is only used in the 'field_name' process pipeline below. + raw_field_name: + - + plugin: migration_lookup + migration: d6_taxonomy_vocabulary + source: vid + - + plugin: skip_on_empty + method: row field_name: - plugin: migration - migration: d6_taxonomy_vocabulary - source: vid + # Prepend field_ to avoid conflicts with base fields, and make sure the + # result is no longer than 32 characters. + - + plugin: concat + source: + - constants/field_prefix + - '@raw_field_name' + - + plugin: substr + length: 32 + - + # This plugin checks if the vocabulary being migrated is the one used by + # Forum. If so, we use the machine name that Forum expects. Otherwise, we + # leave it unchanged. + plugin: forum_vocabulary + machine_name: taxonomy_forums destination: plugin: component_entity_display migration_dependencies: diff --git a/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_form_display.yml b/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_form_display.yml index 2608877e..abd31911 100644 --- a/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_form_display.yml +++ b/core/modules/taxonomy/migration_templates/d6_vocabulary_entity_form_display.yml @@ -9,6 +9,7 @@ source: form_mode: default options: weight: 20 + field_prefix: field_ process: entity_type: 'constants/entity_type' form_mode: 'constants/form_mode' @@ -19,11 +20,40 @@ process: 0: options_select 1: entity_reference_autocomplete_tags options/weight: 'constants/options/weight' - bundle: type + bundle: + - + plugin: migration_lookup + migration: d6_node_type + source: type + - + plugin: skip_on_empty + method: row + # This value is only used in the 'field_name' process pipeline below. + raw_field_name: + - + plugin: migration_lookup + migration: d6_taxonomy_vocabulary + source: vid + - + plugin: skip_on_empty + method: row field_name: - plugin: migration - migration: d6_taxonomy_vocabulary - source: vid + # Prepend field_ to avoid conflicts with base fields, and make sure the + # result is no longer than 32 characters. + - + plugin: concat + source: + - constants/field_prefix + - '@raw_field_name' + - + plugin: substr + length: 32 + - + # This plugin checks if the vocabulary being migrated is the one used by + # Forum. If so, we use the machine name that Forum expects. Otherwise, we + # leave it unchanged. + plugin: forum_vocabulary + machine_name: taxonomy_forums destination: plugin: component_entity_form_display migration_dependencies: diff --git a/core/modules/taxonomy/migration_templates/d6_vocabulary_field.yml b/core/modules/taxonomy/migration_templates/d6_vocabulary_field.yml index 0e1a4872..893a95d3 100644 --- a/core/modules/taxonomy/migration_templates/d6_vocabulary_field.yml +++ b/core/modules/taxonomy/migration_templates/d6_vocabulary_field.yml @@ -8,17 +8,36 @@ source: entity_type: node type: entity_reference target_entity_type: taxonomy_term + field_prefix: field_ process: entity_type: 'constants/entity_type' type: 'constants/type' - field_name: + # This value is only used in the 'field_name' process pipeline below. + raw_field_name: - - plugin: migration + plugin: migration_lookup migration: d6_taxonomy_vocabulary source: vid - plugin: skip_on_empty method: row + field_name: + # Prepend field_ to avoid conflicts with base fields, and make sure the + # result is no longer than 32 characters. + - + plugin: concat + source: + - constants/field_prefix + - '@raw_field_name' + - + plugin: substr + length: 32 + - + # This plugin checks if the vocabulary being migrated is the one used by + # Forum. If so, we use the machine name that Forum expects. Otherwise, we + # leave it unchanged. + plugin: forum_vocabulary + machine_name: taxonomy_forums 'settings/target_type': 'constants/target_entity_type' cardinality: cardinality destination: diff --git a/core/modules/taxonomy/migration_templates/d6_vocabulary_field_instance.yml b/core/modules/taxonomy/migration_templates/d6_vocabulary_field_instance.yml index a7bbbbbc..7e283778 100644 --- a/core/modules/taxonomy/migration_templates/d6_vocabulary_field_instance.yml +++ b/core/modules/taxonomy/migration_templates/d6_vocabulary_field_instance.yml @@ -8,17 +8,43 @@ source: entity_type: node auto_create: true selection_handler: 'default:taxonomy_term' + field_prefix: field_ process: entity_type: 'constants/entity_type' - bundle: type - field_name: + bundle: + - + plugin: migration_lookup + migration: d6_node_type + source: type + - + plugin: skip_on_empty + method: row + # This value is only used in the 'field_name' process pipeline below. + raw_field_name: - - plugin: migration + plugin: migration_lookup migration: d6_taxonomy_vocabulary source: vid - plugin: skip_on_empty method: row + field_name: + # Prepend field_ to avoid conflicts with base fields, and make sure the + # result is no longer than 32 characters. + - + plugin: concat + source: + - constants/field_prefix + - '@raw_field_name' + - + plugin: substr + length: 32 + - + # This plugin checks if the vocabulary being migrated is the one used by + # Forum. If so, we use the machine name that Forum expects. Otherwise, we + # leave it unchanged. + plugin: forum_vocabulary + machine_name: taxonomy_forums label: name 'settings/handler': 'constants/selection_handler' 'settings/handler_settings/target_bundles/0': '@field_name' diff --git a/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml b/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml index af851800..46f9f204 100644 --- a/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml +++ b/core/modules/taxonomy/migration_templates/d7_taxonomy_term.yml @@ -10,7 +10,7 @@ process: # the tid field to allow incremental migrations. tid: tid vid: - plugin: migration + plugin: migration_lookup migration: d7_taxonomy_vocabulary source: vid name: name @@ -24,12 +24,13 @@ process: method: process source: parent - - plugin: migration + plugin: migration_lookup migration: d7_taxonomy_term parent: plugin: default_value default_value: 0 source: '@parent_id' + forum_container: is_container changed: timestamp destination: plugin: entity:taxonomy_term diff --git a/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml b/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml index 80c38a79..751f0183 100644 --- a/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml +++ b/core/modules/taxonomy/migration_templates/d7_taxonomy_vocabulary.yml @@ -5,7 +5,20 @@ migration_tags: source: plugin: d7_taxonomy_vocabulary process: - vid: machine_name + vid: + - + plugin: make_unique_entity_field + source: machine_name + entity_type: taxonomy_vocabulary + field: vid + length: 32 + migrated: true + - + # This plugin checks if the vocabulary being migrated is the one used by + # Forum. If so, we use the machine name that Forum expects. Otherwise, we + # leave it unchanged. + plugin: forum_vocabulary + machine_name: forums label: name name: name description: description diff --git a/core/modules/taxonomy/migration_templates/taxonomy_settings.yml b/core/modules/taxonomy/migration_templates/taxonomy_settings.yml index c20372c6..28505db5 100644 --- a/core/modules/taxonomy/migration_templates/taxonomy_settings.yml +++ b/core/modules/taxonomy/migration_templates/taxonomy_settings.yml @@ -8,6 +8,7 @@ source: variables: - taxonomy_override_selector - taxonomy_terms_per_page_admin + source_module: taxonomy process: override_selector: taxonomy_override_selector terms_per_page_admin: taxonomy_terms_per_page_admin diff --git a/core/modules/taxonomy/src/Controller/TaxonomyController.php b/core/modules/taxonomy/src/Controller/TaxonomyController.php index 843cdd7a..27b1ec0c 100644 --- a/core/modules/taxonomy/src/Controller/TaxonomyController.php +++ b/core/modules/taxonomy/src/Controller/TaxonomyController.php @@ -22,7 +22,7 @@ class TaxonomyController extends ControllerBase { * The taxonomy term add form. */ public function addForm(VocabularyInterface $taxonomy_vocabulary) { - $term = $this->entityManager()->getStorage('taxonomy_term')->create(array('vid' => $taxonomy_vocabulary->id())); + $term = $this->entityManager()->getStorage('taxonomy_term')->create(['vid' => $taxonomy_vocabulary->id()]); return $this->entityFormBuilder()->getForm($term); } diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index 2e41e2d0..03491ab9 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -46,6 +46,7 @@ * "canonical" = "/taxonomy/term/{taxonomy_term}", * "delete-form" = "/taxonomy/term/{taxonomy_term}/delete", * "edit-form" = "/taxonomy/term/{taxonomy_term}/edit", + * "create" = "/taxonomy/term", * }, * permission_granularity = "bundle" * ) @@ -61,14 +62,14 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti parent::postDelete($storage, $entities); // See if any of the term's children are about to be become orphans. - $orphans = array(); + $orphans = []; foreach (array_keys($entities) as $tid) { if ($children = $storage->loadChildren($tid)) { foreach ($children as $child) { // If the term has multiple parents, we don't delete it. $parents = $storage->loadParents($child->id()); if (empty($parents)) { - $orphans[] = $child->id(); + $orphans[] = $child; } } } @@ -79,7 +80,7 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti $storage->deleteTermHierarchy(array_keys($entities)); if (!empty($orphans)) { - entity_delete_multiple('taxonomy_term', $orphans); + $storage->delete($orphans); } } @@ -92,7 +93,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { // Only change the parents if a value is set, keep the existing values if // not. if (isset($this->parent->target_id)) { - $storage->deleteTermHierarchy(array($this->id())); + $storage->deleteTermHierarchy([$this->id()]); $storage->updateTermHierarchy($this); } } @@ -116,35 +117,33 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['name'] = BaseFieldDefinition::create('string') ->setLabel(t('Name')) - ->setDescription(t('The term name.')) ->setTranslatable(TRUE) ->setRequired(TRUE) ->setSetting('max_length', 255) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'string', 'weight' => -5, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'string_textfield', 'weight' => -5, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['description'] = BaseFieldDefinition::create('text_long') ->setLabel(t('Description')) - ->setDescription(t('A description of the term.')) ->setTranslatable(TRUE) - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'text_default', 'weight' => 0, - )) + ]) ->setDisplayConfigurable('view', TRUE) - ->setDisplayOptions('form', array( + ->setDisplayOptions('form', [ 'type' => 'text_textfield', 'weight' => 0, - )) + ]) ->setDisplayConfigurable('form', TRUE); $fields['weight'] = BaseFieldDefinition::create('integer') @@ -231,7 +230,21 @@ public function setWeight($weight) { * {@inheritdoc} */ public function getVocabularyId() { - return $this->get('vid')->target_id; + @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.4.0 and will be removed before 9.0.0. Use ' . __CLASS__ . '::bundle() instead to get the vocabulary ID.', E_USER_DEPRECATED); + return $this->bundle(); + } + + /** + * {@inheritdoc} + */ + protected function getFieldsToSkipFromTranslationChangesCheck() { + // @todo the current implementation of the parent field makes it impossible + // for ::hasTranslationChanges() to correctly check the field for changes, + // so it is currently skipped from the comparision and has to be fixed by + // https://www.drupal.org/node/2843060. + $fields = parent::getFieldsToSkipFromTranslationChangesCheck(); + $fields[] = 'parent'; + return $fields; } } diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php index a2d7eef8..b0d1ac13 100644 --- a/core/modules/taxonomy/src/Entity/Vocabulary.php +++ b/core/modules/taxonomy/src/Entity/Vocabulary.php @@ -140,13 +140,13 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti return; } - $vocabularies = array(); + $vocabularies = []; foreach ($entities as $vocabulary) { $vocabularies[$vocabulary->id()] = $vocabulary->id(); } // Load all Taxonomy module fields and delete those which use only this // vocabulary. - $field_storages = entity_load_multiple_by_properties('field_storage_config', array('module' => 'taxonomy')); + $field_storages = entity_load_multiple_by_properties('field_storage_config', ['module' => 'taxonomy']); foreach ($field_storages as $field_storage) { $modified_storage = FALSE; // Term reference fields may reference terms from more than one diff --git a/core/modules/taxonomy/src/Form/OverviewTerms.php b/core/modules/taxonomy/src/Form/OverviewTerms.php index 4c8cee3f..3811ee5f 100644 --- a/core/modules/taxonomy/src/Form/OverviewTerms.php +++ b/core/modules/taxonomy/src/Form/OverviewTerms.php @@ -21,6 +21,13 @@ class OverviewTerms extends FormBase { */ protected $moduleHandler; + /** + * The entity manager. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + /** * The term storage handler. * @@ -38,6 +45,7 @@ class OverviewTerms extends FormBase { */ public function __construct(ModuleHandlerInterface $module_handler, EntityManagerInterface $entity_manager) { $this->moduleHandler = $module_handler; + $this->entityManager = $entity_manager; $this->storageController = $entity_manager->getStorage('taxonomy_term'); } @@ -101,10 +109,10 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular $forward_step = 0; // An array of the terms to be displayed on this page. - $current_page = array(); + $current_page = []; $delta = 0; - $term_deltas = array(); + $term_deltas = []; $tree = $this->storageController->loadTree($taxonomy_vocabulary->id(), 0, NULL, TRUE); $tree_index = 0; do { @@ -199,93 +207,94 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular $destination = $this->getDestinationArray(); $row_position = 0; // Build the actual form. - $form['terms'] = array( + $form['terms'] = [ '#type' => 'table', - '#header' => array($this->t('Name'), $this->t('Weight'), $this->t('Operations')), - '#empty' => $this->t('No terms available.
    Add term.', array(':link' => $this->url('entity.taxonomy_term.add_form', array('taxonomy_vocabulary' => $taxonomy_vocabulary->id())))), - '#attributes' => array( + '#header' => [$this->t('Name'), $this->t('Weight'), $this->t('Operations')], + '#empty' => $this->t('No terms available. Add term.', [':link' => $this->url('entity.taxonomy_term.add_form', ['taxonomy_vocabulary' => $taxonomy_vocabulary->id()])]), + '#attributes' => [ 'id' => 'taxonomy', - ), - ); + ], + ]; foreach ($current_page as $key => $term) { /** @var $term \Drupal\Core\Entity\EntityInterface */ + $term = $this->entityManager->getTranslationFromContext($term); $form['terms'][$key]['#term'] = $term; - $indentation = array(); + $indentation = []; if (isset($term->depth) && $term->depth > 0) { - $indentation = array( + $indentation = [ '#theme' => 'indentation', '#size' => $term->depth, - ); + ]; } - $form['terms'][$key]['term'] = array( - '#prefix' => !empty($indentation) ? drupal_render($indentation) : '', + $form['terms'][$key]['term'] = [ + '#prefix' => !empty($indentation) ? \Drupal::service('renderer')->render($indentation) : '', '#type' => 'link', '#title' => $term->getName(), '#url' => $term->urlInfo(), - ); + ]; if ($taxonomy_vocabulary->getHierarchy() != VocabularyInterface::HIERARCHY_MULTIPLE && count($tree) > 1) { $parent_fields = TRUE; - $form['terms'][$key]['term']['tid'] = array( + $form['terms'][$key]['term']['tid'] = [ '#type' => 'hidden', '#value' => $term->id(), - '#attributes' => array( - 'class' => array('term-id'), - ), - ); - $form['terms'][$key]['term']['parent'] = array( + '#attributes' => [ + 'class' => ['term-id'], + ], + ]; + $form['terms'][$key]['term']['parent'] = [ '#type' => 'hidden', // Yes, default_value on a hidden. It needs to be changeable by the // javascript. '#default_value' => $term->parents[0], - '#attributes' => array( - 'class' => array('term-parent'), - ), - ); - $form['terms'][$key]['term']['depth'] = array( + '#attributes' => [ + 'class' => ['term-parent'], + ], + ]; + $form['terms'][$key]['term']['depth'] = [ '#type' => 'hidden', // Same as above, the depth is modified by javascript, so it's a // default_value. '#default_value' => $term->depth, - '#attributes' => array( - 'class' => array('term-depth'), - ), - ); + '#attributes' => [ + 'class' => ['term-depth'], + ], + ]; } - $form['terms'][$key]['weight'] = array( + $form['terms'][$key]['weight'] = [ '#type' => 'weight', '#delta' => $delta, '#title' => $this->t('Weight for added term'), '#title_display' => 'invisible', '#default_value' => $term->getWeight(), - '#attributes' => array( - 'class' => array('term-weight'), - ), - ); - $operations = array( - 'edit' => array( + '#attributes' => [ + 'class' => ['term-weight'], + ], + ]; + $operations = [ + 'edit' => [ 'title' => $this->t('Edit'), 'query' => $destination, 'url' => $term->urlInfo('edit-form'), - ), - 'delete' => array( + ], + 'delete' => [ 'title' => $this->t('Delete'), 'query' => $destination, 'url' => $term->urlInfo('delete-form'), - ), - ); + ], + ]; if ($this->moduleHandler->moduleExists('content_translation') && content_translation_translate_access($term)->isAllowed()) { - $operations['translate'] = array( + $operations['translate'] = [ 'title' => $this->t('Translate'), 'query' => $destination, 'url' => $term->urlInfo('drupal:content-translation-overview'), - ); + ]; } - $form['terms'][$key]['operations'] = array( + $form['terms'][$key]['operations'] = [ '#type' => 'operations', '#links' => $operations, - ); + ]; - $form['terms'][$key]['#attributes']['class'] = array(); + $form['terms'][$key]['#attributes']['class'] = []; if ($parent_fields) { $form['terms'][$key]['#attributes']['class'][] = 'draggable'; } @@ -314,44 +323,44 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular } if ($parent_fields) { - $form['terms']['#tabledrag'][] = array( + $form['terms']['#tabledrag'][] = [ 'action' => 'match', 'relationship' => 'parent', 'group' => 'term-parent', 'subgroup' => 'term-parent', 'source' => 'term-id', 'hidden' => FALSE, - ); - $form['terms']['#tabledrag'][] = array( + ]; + $form['terms']['#tabledrag'][] = [ 'action' => 'depth', 'relationship' => 'group', 'group' => 'term-depth', 'hidden' => FALSE, - ); + ]; $form['terms']['#attached']['library'][] = 'taxonomy/drupal.taxonomy'; $form['terms']['#attached']['drupalSettings']['taxonomy'] = [ 'backStep' => $back_step, 'forwardStep' => $forward_step, ]; } - $form['terms']['#tabledrag'][] = array( + $form['terms']['#tabledrag'][] = [ 'action' => 'order', 'relationship' => 'sibling', 'group' => 'term-weight', - ); + ]; if ($taxonomy_vocabulary->getHierarchy() != VocabularyInterface::HIERARCHY_MULTIPLE && count($tree) > 1) { - $form['actions'] = array('#type' => 'actions', '#tree' => FALSE); - $form['actions']['submit'] = array( + $form['actions'] = ['#type' => 'actions', '#tree' => FALSE]; + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), '#button_type' => 'primary', - ); - $form['actions']['reset_alphabetical'] = array( + ]; + $form['actions']['reset_alphabetical'] = [ '#type' => 'submit', - '#submit' => array('::submitReset'), + '#submit' => ['::submitReset'], '#value' => $this->t('Reset to alphabetical'), - ); + ]; } $form['pager_pager'] = ['#type' => 'pager']; @@ -378,13 +387,13 @@ public function buildForm(array $form, FormStateInterface $form_state, Vocabular */ public function submitForm(array &$form, FormStateInterface $form_state) { // Sort term order based on weight. - uasort($form_state->getValue('terms'), array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); + uasort($form_state->getValue('terms'), ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']); $vocabulary = $form_state->get(['taxonomy', 'vocabulary']); // Update the current hierarchy type as we go. $hierarchy = VocabularyInterface::HIERARCHY_DISABLED; - $changed_terms = array(); + $changed_terms = []; $tree = $this->storageController->loadTree($vocabulary->id(), 0, NULL, TRUE); if (empty($tree)) { @@ -405,7 +414,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } // Renumber the current page weights and assign any new parents. - $level_weights = array(); + $level_weights = []; foreach ($form_state->getValue('terms') as $tid => $values) { if (isset($form['terms'][$tid]['#term'])) { $term = $form['terms'][$tid]['#term']; diff --git a/core/modules/taxonomy/src/Form/TermDeleteForm.php b/core/modules/taxonomy/src/Form/TermDeleteForm.php index 22ab19b0..0e97ff64 100644 --- a/core/modules/taxonomy/src/Form/TermDeleteForm.php +++ b/core/modules/taxonomy/src/Form/TermDeleteForm.php @@ -38,7 +38,7 @@ public function getDescription() { * {@inheritdoc} */ protected function getDeletionMessage() { - return $this->t('Deleted term %name.', array('%name' => $this->entity->label())); + return $this->t('Deleted term %name.', ['%name' => $this->entity->label()]); } /** @@ -54,7 +54,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $vocabulary = $storage->load($this->entity->bundle()); // @todo Move to storage http://drupal.org/node/1988712 - taxonomy_check_vocabulary_hierarchy($vocabulary, array('tid' => $term->id())); + taxonomy_check_vocabulary_hierarchy($vocabulary, ['tid' => $term->id()]); } } diff --git a/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php b/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php index bada5d6e..7c91b786 100644 --- a/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php +++ b/core/modules/taxonomy/src/Form/VocabularyDeleteForm.php @@ -20,7 +20,7 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to delete the vocabulary %title?', array('%title' => $this->entity->label())); + return $this->t('Are you sure you want to delete the vocabulary %title?', ['%title' => $this->entity->label()]); } /** @@ -34,7 +34,7 @@ public function getDescription() { * {@inheritdoc} */ protected function getDeletionMessage() { - return $this->t('Deleted vocabulary %name.', array('%name' => $this->entity->label())); + return $this->t('Deleted vocabulary %name.', ['%name' => $this->entity->label()]); } } diff --git a/core/modules/taxonomy/src/Form/VocabularyResetForm.php b/core/modules/taxonomy/src/Form/VocabularyResetForm.php index fb33e358..e036ff91 100644 --- a/core/modules/taxonomy/src/Form/VocabularyResetForm.php +++ b/core/modules/taxonomy/src/Form/VocabularyResetForm.php @@ -49,7 +49,7 @@ public function getFormId() { * {@inheritdoc} */ public function getQuestion() { - return $this->t('Are you sure you want to reset the vocabulary %title to alphabetical order?', array('%title' => $this->entity->label())); + return $this->t('Are you sure you want to reset the vocabulary %title to alphabetical order?', ['%title' => $this->entity->label()]); } /** @@ -80,8 +80,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) { parent::submitForm($form, $form_state); $this->termStorage->resetWeights($this->entity->id()); - drupal_set_message($this->t('Reset vocabulary %name to alphabetical order.', array('%name' => $this->entity->label()))); - $this->logger('taxonomy')->notice('Reset vocabulary %name to alphabetical order.', array('%name' => $this->entity->label())); + drupal_set_message($this->t('Reset vocabulary %name to alphabetical order.', ['%name' => $this->entity->label()])); + $this->logger('taxonomy')->notice('Reset vocabulary %name to alphabetical order.', ['%name' => $this->entity->label()]); $form_state->setRedirectUrl($this->getCancelUrl()); } diff --git a/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php b/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php index 7dd4aa2d..a66eaf51 100644 --- a/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php +++ b/core/modules/taxonomy/src/Plugin/EntityReferenceSelection/TermSelection.php @@ -3,7 +3,6 @@ namespace Drupal\taxonomy\Plugin\EntityReferenceSelection; use Drupal\Component\Utility\Html; -use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection; use Drupal\Core\Form\FormStateInterface; use Drupal\taxonomy\Entity\Vocabulary; @@ -24,8 +23,13 @@ class TermSelection extends DefaultSelection { /** * {@inheritdoc} */ - public function entityQueryAlter(SelectInterface $query) { - // @todo: How to set access, as vocabulary is now config? + public function defaultConfiguration() { + return [ + 'sort' => [ + 'field' => 'name', + 'direction' => 'asc', + ] + ] + parent::defaultConfiguration(); } /** @@ -49,15 +53,13 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { if ($match || $limit) { - $this->configuration['handler_settings']['sort'] = ['field' => 'name', 'direction' => 'asc']; return parent::getReferenceableEntities($match, $match_operator, $limit); } - $options = array(); + $options = []; $bundles = $this->entityManager->getBundleInfo('taxonomy_term'); - $handler_settings = $this->configuration['handler_settings']; - $bundle_names = !empty($handler_settings['target_bundles']) ? $handler_settings['target_bundles'] : array_keys($bundles); + $bundle_names = $this->getConfiguration()['target_bundles'] ?: array_keys($bundles); foreach ($bundle_names as $bundle) { if ($vocabulary = Vocabulary::load($bundle)) { diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php index 11e83257..0d0d9170 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldFormatter/EntityReferenceTaxonomyTermRssFormatter.php @@ -25,16 +25,16 @@ class EntityReferenceTaxonomyTermRssFormatter extends EntityReferenceFormatterBa */ public function viewElements(FieldItemListInterface $items, $langcode) { $parent_entity = $items->getEntity(); - $elements = array(); + $elements = []; foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) { - $parent_entity->rss_elements[] = array( + $parent_entity->rss_elements[] = [ 'key' => 'category', 'value' => $entity->label(), - 'attributes' => array( - 'domain' => $entity->id() ? \Drupal::url('entity.taxonomy_term.canonical', ['taxonomy_term' => $entity->id()], array('absolute' => TRUE)) : '', - ), - ); + 'attributes' => [ + 'domain' => $entity->id() ? \Drupal::url('entity.taxonomy_term.canonical', ['taxonomy_term' => $entity->id()], ['absolute' => TRUE]) : '', + ], + ]; } return $elements; diff --git a/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php b/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php index 22280ec6..561a9afe 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php +++ b/core/modules/taxonomy/src/Plugin/migrate/D7TaxonomyTermDeriver.php @@ -7,15 +7,16 @@ use Drupal\Core\Database\DatabaseExceptionWrapper; use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; use Drupal\migrate\Exception\RequirementsException; -use Drupal\migrate\Plugin\Migration; use Drupal\migrate\Plugin\MigrationDeriverTrait; use Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface; +use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Deriver for Drupal 7 taxonomy term migrations based on vocabularies. */ class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInterface { + use MigrationDeriverTrait; /** @@ -39,6 +40,20 @@ class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInter */ protected $cckPluginManager; + /** + * Already-instantiated field plugins, keyed by ID. + * + * @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface[] + */ + protected $fieldPluginCache; + + /** + * The field plugin manager. + * + * @var \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface + */ + protected $fieldPluginManager; + /** * D7TaxonomyTermDeriver constructor. * @@ -46,10 +61,13 @@ class D7TaxonomyTermDeriver extends DeriverBase implements ContainerDeriverInter * The base plugin ID for the plugin ID. * @param \Drupal\migrate_drupal\Plugin\MigrateCckFieldPluginManagerInterface $cck_manager * The CCK plugin manager. + * @param \Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface $field_manager + * The field plugin manager. */ - public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager) { + public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterface $cck_manager, MigrateFieldPluginManagerInterface $field_manager) { $this->basePluginId = $base_plugin_id; $this->cckPluginManager = $cck_manager; + $this->fieldPluginManager = $field_manager; } /** @@ -58,7 +76,8 @@ public function __construct($base_plugin_id, MigrateCckFieldPluginManagerInterfa public static function create(ContainerInterface $container, $base_plugin_id) { return new static( $base_plugin_id, - $container->get('plugin.manager.migrate.cckfield') + $container->get('plugin.manager.migrate.cckfield'), + $container->get('plugin.manager.migrate.field') ); } @@ -84,8 +103,19 @@ public function getDerivativeDefinitions($base_plugin_definition) { // we'll create a migration just for the node properties. } + $vocabulary_source_plugin = static::getSourcePlugin('d7_taxonomy_vocabulary'); + try { + $vocabulary_source_plugin->checkRequirements(); + } + catch (RequirementsException $e) { + // If the d7_taxonomy_vocabulary requirements failed, that means we do not + // have a Drupal source database configured - there is nothing to + // generate. + return $this->derivatives; + } + try { - foreach (static::getSourcePlugin('d7_taxonomy_vocabulary') as $row) { + foreach ($vocabulary_source_plugin as $row) { $bundle = $row->getSourceProperty('machine_name'); $values = $base_plugin_definition; @@ -102,15 +132,25 @@ public function getDerivativeDefinitions($base_plugin_definition) { foreach ($fields[$bundle] as $field_name => $info) { $field_type = $info['type']; try { - $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration); - if (!isset($this->cckPluginCache[$field_type])) { - $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration); + $plugin_id = $this->fieldPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration); + if (!isset($this->fieldPluginCache[$field_type])) { + $this->fieldPluginCache[$field_type] = $this->fieldPluginManager->createInstance($plugin_id, ['core' => 7], $migration); } - $this->cckPluginCache[$field_type] - ->processCckFieldValues($migration, $field_name, $info); + $this->fieldPluginCache[$field_type] + ->processFieldValues($migration, $field_name, $info); } catch (PluginNotFoundException $ex) { - $migration->setProcessOfProperty($field_name, $field_name); + try { + $plugin_id = $this->cckPluginManager->getPluginIdFromFieldType($field_type, ['core' => 7], $migration); + if (!isset($this->cckPluginCache[$field_type])) { + $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($plugin_id, ['core' => 7], $migration); + } + $this->cckPluginCache[$field_type] + ->processCckFieldValues($migration, $field_name, $info); + } + catch (PluginNotFoundException $ex) { + $migration->setProcessOfProperty($field_name, $field_name); + } } } } diff --git a/core/modules/taxonomy/src/Plugin/migrate/cckfield/TaxonomyTermReference.php b/core/modules/taxonomy/src/Plugin/migrate/cckfield/TaxonomyTermReference.php index c3035c43..27cb8d35 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/cckfield/TaxonomyTermReference.php +++ b/core/modules/taxonomy/src/Plugin/migrate/cckfield/TaxonomyTermReference.php @@ -2,6 +2,8 @@ namespace Drupal\taxonomy\Plugin\migrate\cckfield; +@trigger_error('TaxonomyTermReference is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.x. Use \Drupal\taxonomy\Plugin\migrate\field\TaxonomyTermReference instead.', E_USER_DEPRECATED); + use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase; @@ -13,27 +15,25 @@ * }, * core = {6,7} * ) + * + * @deprecated in Drupal 8.4.x, to be removed before Drupal 9.0.x. Use + * \Drupal\taxonomy\Plugin\migrate\field\TaxonomyTermReference instead. + * + * @see https://www.drupal.org/node/2751897 */ class TaxonomyTermReference extends CckFieldPluginBase { - /** - * {@inheritdoc} - */ - public function getFieldFormatterMap() { - return array(); - } - /** * {@inheritdoc} */ public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) { - $process = array( + $process = [ 'plugin' => 'iterator', 'source' => $field_name, - 'process' => array( + 'process' => [ 'target_id' => 'tid', - ), - ); + ], + ]; $migration->setProcessOfProperty($field_name, $process); } diff --git a/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php b/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php new file mode 100644 index 00000000..56ec20ac --- /dev/null +++ b/core/modules/taxonomy/src/Plugin/migrate/field/TaxonomyTermReference.php @@ -0,0 +1,33 @@ + 'iterator', + 'source' => $field_name, + 'process' => [ + 'target_id' => 'tid', + ], + ]; + $migration->setProcessOfProperty($field_name, $process); + } + +} diff --git a/core/modules/taxonomy/src/Plugin/migrate/process/ForumVocabulary.php b/core/modules/taxonomy/src/Plugin/migrate/process/ForumVocabulary.php new file mode 100644 index 00000000..677f2465 --- /dev/null +++ b/core/modules/taxonomy/src/Plugin/migrate/process/ForumVocabulary.php @@ -0,0 +1,46 @@ +getSourceProperty('forum_vocabulary') && !empty($this->configuration['machine_name'])) { + $value = $this->configuration['machine_name']; + } + return $value; + } + +} diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/Term.php b/core/modules/taxonomy/src/Plugin/migrate/source/Term.php index ce468a29..9c7443b4 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/Term.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/Term.php @@ -12,12 +12,14 @@ * * @MigrateSource( * id = "taxonomy_term", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) * * @deprecated in Drupal 8.3.0, intended to be removed in Drupal 9.0.0. * Use \Drupal\taxonomy\Plugin\migrate\source\d6\Term or * \Drupal\taxonomy\Plugin\migrate\source\d7\Term. + * + * @see https://www.drupal.org/node/2879193 */ class Term extends DrupalSqlBase { @@ -64,14 +66,14 @@ public function query() { * {@inheritdoc} */ public function fields() { - $fields = array( + $fields = [ 'tid' => $this->t('The term ID.'), 'vid' => $this->t('Existing term VID'), 'name' => $this->t('The name of the term.'), 'description' => $this->t('The term description.'), 'weight' => $this->t('Weight'), 'parent' => $this->t("The Drupal term IDs of the term's parents."), - ); + ]; if ($this->getModuleSchemaVersion('taxonomy') >= 7000) { $fields['format'] = $this->t('Format of the term description.'); } @@ -84,7 +86,7 @@ public function fields() { public function prepareRow(Row $row) { // Find parents for this row. $parents = $this->select($this->termHierarchyTable, 'th') - ->fields('th', array('parent', 'tid')) + ->fields('th', ['parent', 'tid']) ->condition('tid', $row->getSourceProperty('tid')) ->execute() ->fetchCol(); diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/Term.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/Term.php index b8a603d0..d43ed166 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d6/Term.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/Term.php @@ -12,7 +12,7 @@ * * @MigrateSource( * id = "d6_taxonomy_term", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) */ class Term extends DrupalSqlBase { @@ -45,6 +45,10 @@ public function fields() { 'weight' => $this->t('Weight'), 'parent' => $this->t("The Drupal term IDs of the term's parents."), ]; + if (isset($this->configuration['translations'])) { + $fields['language'] = $this->t('The term language.'); + $fields['trid'] = $this->t('Translation ID.'); + } return $fields; } diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNode.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNode.php index 2635aaa7..4171cceb 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNode.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNode.php @@ -10,7 +10,7 @@ * * @MigrateSource( * id = "d6_term_node", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) */ class TermNode extends DrupalSqlBase { @@ -26,10 +26,10 @@ class TermNode extends DrupalSqlBase { public function query() { $query = $this->select('term_node', 'tn') ->distinct() - ->fields('tn', array('nid', 'vid')) - ->fields('n', array('type')); + ->fields('tn', ['nid', 'vid']) + ->fields('n', ['type']); // Because this is an inner join it enforces the current revision. - $query->innerJoin('term_data', 'td', 'td.tid = tn.tid AND td.vid = :vid', array(':vid' => $this->configuration['vid'])); + $query->innerJoin('term_data', 'td', 'td.tid = tn.tid AND td.vid = :vid', [':vid' => $this->configuration['vid']]); $query->innerJoin('node', 'n', static::JOIN); return $query; } @@ -38,11 +38,11 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'nid' => $this->t('The node revision ID.'), 'vid' => $this->t('The node revision ID.'), 'tid' => $this->t('The term ID.'), - ); + ]; } /** @@ -51,10 +51,10 @@ public function fields() { public function prepareRow(Row $row) { // Select the terms belonging to the revision selected. $query = $this->select('term_node', 'tn') - ->fields('tn', array('tid')) + ->fields('tn', ['tid']) ->condition('n.nid', $row->getSourceProperty('nid')); $query->join('node', 'n', static::JOIN); - $query->innerJoin('term_data', 'td', 'td.tid = tn.tid AND td.vid = :vid', array(':vid' => $this->configuration['vid'])); + $query->innerJoin('term_data', 'td', 'td.tid = tn.tid AND td.vid = :vid', [':vid' => $this->configuration['vid']]); $row->setSourceProperty('tid', $query->execute()->fetchCol()); return parent::prepareRow($row); } diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNodeRevision.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNodeRevision.php index 91c133bc..96d30d48 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNodeRevision.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermNodeRevision.php @@ -6,7 +6,8 @@ * Source returning tids from the term_node table for the non-current revision. * * @MigrateSource( - * id = "d6_term_node_revision" + * id = "d6_term_node_revision", + * source_module = "taxonomy" * ) */ class TermNodeRevision extends TermNode { diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/Vocabulary.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/Vocabulary.php index 25730338..767daf45 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d6/Vocabulary.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/Vocabulary.php @@ -11,7 +11,7 @@ * * @MigrateSource( * id = "d6_taxonomy_vocabulary", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) */ class Vocabulary extends DrupalSqlBase { @@ -21,7 +21,7 @@ class Vocabulary extends DrupalSqlBase { */ public function query() { $query = $this->select('vocabulary', 'v') - ->fields('v', array( + ->fields('v', [ 'vid', 'name', 'description', @@ -33,7 +33,7 @@ public function query() { 'tags', 'module', 'weight', - )); + ]); return $query; } @@ -41,7 +41,7 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'vid' => $this->t('The vocabulary ID.'), 'name' => $this->t('The name of the vocabulary.'), 'description' => $this->t('The description of the vocabulary.'), @@ -54,7 +54,7 @@ public function fields() { 'weight' => $this->t('The weight of the vocabulary in relation to other vocabularies.'), 'parents' => $this->t("The Drupal term IDs of the term's parents."), 'node_types' => $this->t('The names of the node types the vocabulary may be used with.'), - ); + ]; } /** @@ -63,12 +63,20 @@ public function fields() { public function prepareRow(Row $row) { // Find node types for this row. $node_types = $this->select('vocabulary_node_types', 'nt') - ->fields('nt', array('type', 'vid')) + ->fields('nt', ['type', 'vid']) ->condition('vid', $row->getSourceProperty('vid')) ->execute() ->fetchCol(); $row->setSourceProperty('node_types', $node_types); $row->setSourceProperty('cardinality', ($row->getSourceProperty('tags') == 1 || $row->getSourceProperty('multiple') == 1) ? FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED : 1); + + // If the vocabulary being migrated is the one defined in the + // 'forum_nav_vocabulary' variable, set the 'forum_vocabulary' source + // property to true so we know this is the vocabulary used by Forum. + if ($this->variableGet('forum_nav_vocabulary', 0) == $row->getSourceProperty('vid')) { + $row->setSourceProperty('forum_vocabulary', TRUE); + } + return parent::prepareRow($row); } diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyPerType.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyPerType.php index ac7a2fe1..ba736ea8 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyPerType.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyPerType.php @@ -7,7 +7,7 @@ * * @MigrateSource( * id = "d6_taxonomy_vocabulary_per_type", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) */ class VocabularyPerType extends Vocabulary { @@ -18,7 +18,7 @@ class VocabularyPerType extends Vocabulary { public function query() { $query = parent::query(); $query->join('vocabulary_node_types', 'nt', 'v.vid = nt.vid'); - $query->fields('nt', array('type')); + $query->fields('nt', ['type']); return $query; } diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyTranslation.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyTranslation.php new file mode 100644 index 00000000..c8f4ef85 --- /dev/null +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/VocabularyTranslation.php @@ -0,0 +1,57 @@ +select('vocabulary', 'v') + ->fields('v', ['vid', 'name', 'description']) + ->fields('i18n', ['lid', 'type', 'property', 'objectid']) + ->fields('lt', ['lid', 'translation']) + ->condition('i18n.type', 'vocabulary'); + $query->addField('lt', 'language', 'language'); + // The i18n_strings table has two columns containing the object ID, objectid + // and objectindex. The objectid column is a text field. Therefore, for the + // join to work in PostgreSQL, use the objectindex field as this is numeric + // like the vid field. + $query->join('i18n_strings', 'i18n', 'v.vid = i18n.objectindex'); + $query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid'); + + return $query; + } + + /** + * {@inheritdoc} + */ + public function fields() { + return [ + 'vid' => $this->t('The vocabulary ID.'), + 'language' => $this->t('Language for this field.'), + 'property' => $this->t('Name of property being translated.'), + 'translation' => $this->t('Translation of either the title or explanation.'), + ]; + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['vid']['type'] = 'integer'; + return $ids; + } + +} diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php index 518b9f7a..93b0fc4a 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php @@ -12,7 +12,7 @@ * * @MigrateSource( * id = "d7_taxonomy_term", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) */ class Term extends FieldableEntity { @@ -70,6 +70,11 @@ public function prepareRow(Row $row) { ->fetchCol(); $row->setSourceProperty('parent', $parents); + // Determine if this is a forum container. + $forum_container_tids = $this->variableGet('forum_containers', []); + $current_tid = $row->getSourceProperty('tid'); + $row->setSourceProperty('is_container', in_array($current_tid, $forum_container_tids)); + return parent::prepareRow($row); } diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php index e9eb4aa4..18599018 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Vocabulary.php @@ -2,6 +2,7 @@ namespace Drupal\taxonomy\Plugin\migrate\source\d7; +use Drupal\migrate\Row; use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; /** @@ -9,7 +10,7 @@ * * @MigrateSource( * id = "d7_taxonomy_vocabulary", - * source_provider = "taxonomy" + * source_module = "taxonomy" * ) */ class Vocabulary extends DrupalSqlBase { @@ -19,7 +20,7 @@ class Vocabulary extends DrupalSqlBase { */ public function query() { $query = $this->select('taxonomy_vocabulary', 'v') - ->fields('v', array( + ->fields('v', [ 'vid', 'name', 'description', @@ -27,7 +28,7 @@ public function query() { 'module', 'weight', 'machine_name', - )); + ]); return $query; } @@ -35,7 +36,7 @@ public function query() { * {@inheritdoc} */ public function fields() { - return array( + return [ 'vid' => $this->t('The vocabulary ID.'), 'name' => $this->t('The name of the vocabulary.'), 'description' => $this->t('The description of the vocabulary.'), @@ -43,7 +44,21 @@ public function fields() { 'module' => $this->t('Module responsible for the vocabulary.'), 'weight' => $this->t('The weight of the vocabulary in relation to other vocabularies.'), 'machine_name' => $this->t('Unique machine name of the vocabulary.') - ); + ]; + } + + /** + * {@inheritdoc} + */ + public function prepareRow(Row $row) { + // If the vocabulary being migrated is the one defined in the + // 'forum_nav_vocabulary' variable, set the 'forum_vocabulary' source + // property to true so we know this is the vocabulary used by Forum. + if ($this->variableGet('forum_nav_vocabulary', 0) == $row->getSourceProperty('vid')) { + $row->setSourceProperty('forum_vocabulary', TRUE); + } + + return parent::prepareRow($row); } /** diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTid.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTid.php index 8ab40e3e..8d185453 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument/IndexTid.php +++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTid.php @@ -15,7 +15,7 @@ class IndexTid extends ManyToOne { public function titleQuery() { - $titles = array(); + $titles = []; $terms = Term::loadMultiple($this->value); foreach ($terms as $term) { $titles[] = \Drupal::entityManager()->getTranslationFromContext($term)->label(); diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php index 68847168..37abdd56 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php +++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php @@ -2,6 +2,7 @@ namespace Drupal\taxonomy\Plugin\views\argument; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; @@ -44,27 +45,27 @@ public static function create(ContainerInterface $container, array $configuratio protected function defineOptions() { $options = parent::defineOptions(); - $options['depth'] = array('default' => 0); - $options['break_phrase'] = array('default' => FALSE); - $options['use_taxonomy_term_path'] = array('default' => FALSE); + $options['depth'] = ['default' => 0]; + $options['break_phrase'] = ['default' => FALSE]; + $options['use_taxonomy_term_path'] = ['default' => FALSE]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['depth'] = array( + $form['depth'] = [ '#type' => 'weight', '#title' => $this->t('Depth'), '#default_value' => $this->options['depth'], '#description' => $this->t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'), - ); + ]; - $form['break_phrase'] = array( + $form['break_phrase'] = [ '#type' => 'checkbox', '#title' => $this->t('Allow multiple values'), '#description' => $this->t('If selected, users can enter multiple values in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this filter.'), '#default_value' => !empty($this->options['break_phrase']), - ); + ]; parent::buildOptionsForm($form, $form_state); } @@ -74,7 +75,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ protected function defaultActions($which = NULL) { if ($which) { - if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) { + if (in_array($which, ['ignore', 'not found', 'empty', 'default'])) { return parent::defaultActions($which); } return; @@ -92,7 +93,7 @@ public function query($group_by = FALSE) { if (!empty($this->options['break_phrase'])) { $break = static::breakString($this->argument); - if ($break->value === array(-1)) { + if ($break->value === [-1]) { return FALSE; } @@ -106,7 +107,7 @@ public function query($group_by = FALSE) { // Now build the subqueries. $subquery = db_select('taxonomy_index', 'tn'); $subquery->addField('tn', 'nid'); - $where = db_or()->condition('tn.tid', $tids, $operator); + $where = (new Condition('OR'))->condition('tn.tid', $tids, $operator); $last = "tn"; if ($this->options['depth'] > 0) { @@ -130,7 +131,7 @@ public function query($group_by = FALSE) { $this->query->addWhere(0, "$this->tableAlias.$this->realField", $subquery, 'IN'); } - function title() { + public function title() { $term = $this->termStorage->load($this->argument); if (!empty($term)) { return $term->getName(); diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthModifier.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthModifier.php index 0415a7a6..b1822ded 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthModifier.php +++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepthModifier.php @@ -17,9 +17,9 @@ */ class IndexTidDepthModifier extends ArgumentPluginBase { - public function buildOptionsForm(&$form, FormStateInterface $form_state) { } + public function buildOptionsForm(&$form, FormStateInterface $form_state) {} - public function query($group_by = FALSE) { } + public function query($group_by = FALSE) {} public function preQuery() { // We don't know our argument yet, but it's based upon our position: diff --git a/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php b/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php index 38e64c73..25efbf35 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php +++ b/core/modules/taxonomy/src/Plugin/views/argument/Taxonomy.php @@ -45,7 +45,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * Override the behavior of title(). Get the title of the node. */ - function title() { + public function title() { // There might be no valid argument. if ($this->argument) { $term = $this->termStorage->load($this->argument); diff --git a/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php b/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php index 9432c7c7..d2fe8207 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php +++ b/core/modules/taxonomy/src/Plugin/views/argument/VocabularyVid.php @@ -54,7 +54,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * Override the behavior of title(). Get the name of the vocabulary. */ - function title() { + public function title() { $vocabulary = $this->vocabularyStorage->load($this->argument); if ($vocabulary) { return $vocabulary->label(); diff --git a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php index 513ed7e7..ee5a2602 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php +++ b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php @@ -96,11 +96,11 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o protected function defineOptions() { $options = parent::defineOptions(); - $options['term_page'] = array('default' => TRUE); - $options['node'] = array('default' => FALSE); - $options['anyall'] = array('default' => ','); - $options['limit'] = array('default' => FALSE); - $options['vids'] = array('default' => array()); + $options['term_page'] = ['default' => TRUE]; + $options['node'] = ['default' => FALSE]; + $options['anyall'] = ['default' => ',']; + $options['limit'] = ['default' => FALSE]; + $options['vids'] = ['default' => []]; return $options; } @@ -109,67 +109,67 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['term_page'] = array( + $form['term_page'] = [ '#type' => 'checkbox', '#title' => $this->t('Load default filter from term page'), '#default_value' => $this->options['term_page'], - ); - $form['node'] = array( + ]; + $form['node'] = [ '#type' => 'checkbox', - '#title' => $this->t('Load default filter from node page, that\'s good for related taxonomy blocks'), + '#title' => $this->t("Load default filter from node page, that's good for related taxonomy blocks"), '#default_value' => $this->options['node'], - ); + ]; - $form['limit'] = array( + $form['limit'] = [ '#type' => 'checkbox', '#title' => $this->t('Limit terms by vocabulary'), '#default_value' => $this->options['limit'], - '#states' => array( - 'visible' => array( - ':input[name="options[argument_default][taxonomy_tid][node]"]' => array('checked' => TRUE), - ), - ), - ); - - $options = array(); + '#states' => [ + 'visible' => [ + ':input[name="options[argument_default][taxonomy_tid][node]"]' => ['checked' => TRUE], + ], + ], + ]; + + $options = []; $vocabularies = $this->vocabularyStorage->loadMultiple(); foreach ($vocabularies as $voc) { $options[$voc->id()] = $voc->label(); } - $form['vids'] = array( + $form['vids'] = [ '#type' => 'checkboxes', '#title' => $this->t('Vocabularies'), '#options' => $options, '#default_value' => $this->options['vids'], - '#states' => array( - 'visible' => array( - ':input[name="options[argument_default][taxonomy_tid][limit]"]' => array('checked' => TRUE), - ':input[name="options[argument_default][taxonomy_tid][node]"]' => array('checked' => TRUE), - ), - ), - ); - - $form['anyall'] = array( + '#states' => [ + 'visible' => [ + ':input[name="options[argument_default][taxonomy_tid][limit]"]' => ['checked' => TRUE], + ':input[name="options[argument_default][taxonomy_tid][node]"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['anyall'] = [ '#type' => 'radios', '#title' => $this->t('Multiple-value handling'), '#default_value' => $this->options['anyall'], - '#options' => array( + '#options' => [ ',' => $this->t('Filter to items that share all terms'), '+' => $this->t('Filter to items that share any term'), - ), - '#states' => array( - 'visible' => array( - ':input[name="options[argument_default][taxonomy_tid][node]"]' => array('checked' => TRUE), - ), - ), - ); + ], + '#states' => [ + 'visible' => [ + ':input[name="options[argument_default][taxonomy_tid][node]"]' => ['checked' => TRUE], + ], + ], + ]; } /** * {@inheritdoc} */ - public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = array()) { + public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) { // Filter unselected items so we don't unnecessarily store giant arrays. $options['vids'] = array_filter($options['vids']); } @@ -188,18 +188,18 @@ public function getArgument() { if (!empty($this->options['node'])) { // Just check, if a node could be detected. if (($node = $this->routeMatch->getParameter('node')) && $node instanceof NodeInterface) { - $taxonomy = array(); + $taxonomy = []; foreach ($node->getFieldDefinitions() as $field) { if ($field->getType() == 'entity_reference' && $field->getSetting('target_type') == 'taxonomy_term') { $taxonomy_terms = $node->{$field->getName()}->referencedEntities(); /** @var \Drupal\taxonomy\TermInterface $taxonomy_term */ foreach ($taxonomy_terms as $taxonomy_term) { - $taxonomy[$taxonomy_term->id()] = $taxonomy_term->getVocabularyId(); + $taxonomy[$taxonomy_term->id()] = $taxonomy_term->bundle(); } } } if (!empty($this->options['limit'])) { - $tids = array(); + $tids = []; // filter by vocabulary foreach ($taxonomy as $tid => $vocab) { if (!empty($this->options['vids'][$vocab])) { diff --git a/core/modules/taxonomy/src/Plugin/views/argument_validator/TermName.php b/core/modules/taxonomy/src/Plugin/views/argument_validator/TermName.php index eb30ff5f..ac7bad0f 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument_validator/TermName.php +++ b/core/modules/taxonomy/src/Plugin/views/argument_validator/TermName.php @@ -39,7 +39,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition */ protected function defineOptions() { $options = parent::defineOptions(); - $options['transform'] = array('default' => FALSE); + $options['transform'] = ['default' => FALSE]; return $options; } @@ -50,11 +50,11 @@ protected function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); - $form['transform'] = array( + $form['transform'] = [ '#type' => 'checkbox', '#title' => $this->t('Transform dashes in URL to spaces in term name filter values'), '#default_value' => $this->options['transform'], - ); + ]; } /** @@ -64,7 +64,7 @@ public function validateArgument($argument) { if ($this->options['transform']) { $argument = str_replace('-', ' ', $argument); } - $terms = $this->termStorage->loadByProperties(array('name' => $argument)); + $terms = $this->termStorage->loadByProperties(['name' => $argument]); if (!$terms) { // Returned empty array no terms with the name. diff --git a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php index 86a4fce2..367565c3 100644 --- a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php +++ b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php @@ -62,19 +62,19 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o // @todo: Wouldn't it be possible to use $this->base_table and no if here? if ($view->storage->get('base_table') == 'node_field_revision') { - $this->additional_fields['nid'] = array('table' => 'node_field_revision', 'field' => 'nid'); + $this->additional_fields['nid'] = ['table' => 'node_field_revision', 'field' => 'nid']; } else { - $this->additional_fields['nid'] = array('table' => 'node_field_data', 'field' => 'nid'); + $this->additional_fields['nid'] = ['table' => 'node_field_data', 'field' => 'nid']; } } protected function defineOptions() { $options = parent::defineOptions(); - $options['link_to_taxonomy'] = array('default' => TRUE); - $options['limit'] = array('default' => FALSE); - $options['vids'] = array('default' => array()); + $options['link_to_taxonomy'] = ['default' => TRUE]; + $options['limit'] = ['default' => FALSE]; + $options['vids'] = ['default' => []]; return $options; } @@ -83,36 +83,36 @@ protected function defineOptions() { * Provide "link to term" option. */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['link_to_taxonomy'] = array( + $form['link_to_taxonomy'] = [ '#title' => $this->t('Link this field to its term page'), '#type' => 'checkbox', '#default_value' => !empty($this->options['link_to_taxonomy']), - ); + ]; - $form['limit'] = array( + $form['limit'] = [ '#type' => 'checkbox', '#title' => $this->t('Limit terms by vocabulary'), '#default_value' => $this->options['limit'], - ); + ]; - $options = array(); + $options = []; $vocabularies = $this->vocabularyStorage->loadMultiple(); foreach ($vocabularies as $voc) { $options[$voc->id()] = $voc->label(); } - $form['vids'] = array( + $form['vids'] = [ '#type' => 'checkboxes', '#title' => $this->t('Vocabularies'), '#options' => $options, '#default_value' => $this->options['vids'], - '#states' => array( - 'visible' => array( - ':input[name="options[limit]"]' => array('checked' => TRUE), - ), - ), + '#states' => [ + 'visible' => [ + ':input[name="options[limit]"]' => ['checked' => TRUE], + ], + ], - ); + ]; parent::buildOptionsForm($form, $form_state); } @@ -127,7 +127,7 @@ public function query() { public function preRender(&$values) { $vocabularies = $this->vocabularyStorage->loadMultiple(); $this->field_alias = $this->aliases['nid']; - $nids = array(); + $nids = []; foreach ($values as $result) { if (!empty($result->{$this->aliases['nid']})) { $nids[] = $result->{$this->aliases['nid']}; @@ -137,7 +137,7 @@ public function preRender(&$values) { if ($nids) { $vocabs = array_filter($this->options['vids']); if (empty($this->options['limit'])) { - $vocabs = array(); + $vocabs = []; } $result = \Drupal::entityManager()->getStorage('taxonomy_term')->getNodeTerms($nids, $vocabs); @@ -145,8 +145,8 @@ public function preRender(&$values) { foreach ($data as $tid => $term) { $this->items[$node_nid][$tid]['name'] = \Drupal::entityManager()->getTranslationFromContext($term)->label(); $this->items[$node_nid][$tid]['tid'] = $tid; - $this->items[$node_nid][$tid]['vocabulary_vid'] = $term->getVocabularyId(); - $this->items[$node_nid][$tid]['vocabulary'] = $vocabularies[$term->getVocabularyId()]->label(); + $this->items[$node_nid][$tid]['vocabulary_vid'] = $term->bundle(); + $this->items[$node_nid][$tid]['vocabulary'] = $vocabularies[$term->bundle()]->label(); if (!empty($this->options['link_to_taxonomy'])) { $this->items[$node_nid][$tid]['make_link'] = TRUE; @@ -157,7 +157,7 @@ public function preRender(&$values) { } } - function render_item($count, $item) { + public function render_item($count, $item) { return $item['name']; } @@ -169,7 +169,7 @@ protected function documentSelfTokens(&$tokens) { } protected function addSelfTokens(&$tokens, $item) { - foreach (array('tid', 'name', 'vocabulary_vid', 'vocabulary') as $token) { + foreach (['tid', 'name', 'vocabulary_vid', 'vocabulary'] as $token) { $tokens['{{ ' . $this->options['id'] . '__' . $token . ' }}'] = isset($item[$token]) ? $item[$token] : ''; } } diff --git a/core/modules/taxonomy/src/Plugin/views/field/TermName.php b/core/modules/taxonomy/src/Plugin/views/field/TermName.php index 20bc3c6f..0a777e9c 100644 --- a/core/modules/taxonomy/src/Plugin/views/field/TermName.php +++ b/core/modules/taxonomy/src/Plugin/views/field/TermName.php @@ -3,7 +3,7 @@ namespace Drupal\taxonomy\Plugin\views\field; use Drupal\Core\Form\FormStateInterface; -use Drupal\views\Plugin\views\field\Field; +use Drupal\views\Plugin\views\field\EntityField; use Drupal\views\ResultRow; /** @@ -13,7 +13,7 @@ * * @ViewsField("term_name") */ -class TermName extends Field { +class TermName extends EntityField { /** * {@inheritdoc} @@ -37,7 +37,7 @@ public function getItems(ResultRow $values) { */ protected function defineOptions() { $options = parent::defineOptions(); - $options['convert_spaces'] = array('default' => FALSE); + $options['convert_spaces'] = ['default' => FALSE]; return $options; } @@ -45,11 +45,11 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['convert_spaces'] = array( + $form['convert_spaces'] = [ '#title' => $this->t('Convert spaces in term names to hyphens'), '#type' => 'checkbox', '#default_value' => !empty($this->options['convert_spaces']), - ); + ]; parent::buildOptionsForm($form, $form_state); } diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php index d769bb04..efadf831 100644 --- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php +++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php @@ -82,7 +82,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o } } - public function hasExtraOptions() { return TRUE; } + public function hasExtraOptions() { + return TRUE; + } /** * {@inheritdoc} @@ -94,18 +96,18 @@ public function getValueOptions() { protected function defineOptions() { $options = parent::defineOptions(); - $options['type'] = array('default' => 'textfield'); - $options['limit'] = array('default' => TRUE); - $options['vid'] = array('default' => ''); - $options['hierarchy'] = array('default' => FALSE); - $options['error_message'] = array('default' => TRUE); + $options['type'] = ['default' => 'textfield']; + $options['limit'] = ['default' => TRUE]; + $options['vid'] = ['default' => '']; + $options['hierarchy'] = ['default' => FALSE]; + $options['error_message'] = ['default' => TRUE]; return $options; } public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) { $vocabularies = $this->vocabularyStorage->loadMultiple(); - $options = array(); + $options = []; foreach ($vocabularies as $voc) { $options[$voc->id()] = $voc->label(); } @@ -118,56 +120,56 @@ public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) { } if (empty($this->definition['vocabulary'])) { - $form['vid'] = array( + $form['vid'] = [ '#type' => 'radios', '#title' => $this->t('Vocabulary'), '#options' => $options, '#description' => $this->t('Select which vocabulary to show terms for in the regular options.'), '#default_value' => $this->options['vid'], - ); + ]; } } - $form['type'] = array( + $form['type'] = [ '#type' => 'radios', '#title' => $this->t('Selection type'), - '#options' => array('select' => $this->t('Dropdown'), 'textfield' => $this->t('Autocomplete')), + '#options' => ['select' => $this->t('Dropdown'), 'textfield' => $this->t('Autocomplete')], '#default_value' => $this->options['type'], - ); + ]; - $form['hierarchy'] = array( + $form['hierarchy'] = [ '#type' => 'checkbox', '#title' => $this->t('Show hierarchy in dropdown'), '#default_value' => !empty($this->options['hierarchy']), - '#states' => array( - 'visible' => array( - ':input[name="options[type]"]' => array('value' => 'select'), - ), - ), - ); + '#states' => [ + 'visible' => [ + ':input[name="options[type]"]' => ['value' => 'select'], + ], + ], + ]; } protected function valueForm(&$form, FormStateInterface $form_state) { $vocabulary = $this->vocabularyStorage->load($this->options['vid']); if (empty($vocabulary) && $this->options['limit']) { - $form['markup'] = array( + $form['markup'] = [ '#markup' => '
    ' . $this->t('An invalid vocabulary is selected. Please change it in the options.') . '
    ', - ); + ]; return; } if ($this->options['type'] == 'textfield') { - $terms = $this->value ? Term::loadMultiple(($this->value)) : array(); - $form['value'] = array( - '#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->label())) : $this->t('Select terms'), + $terms = $this->value ? Term::loadMultiple(($this->value)) : []; + $form['value'] = [ + '#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', ['@voc' => $vocabulary->label()]) : $this->t('Select terms'), '#type' => 'textfield', '#default_value' => EntityAutocomplete::getEntityLabels($terms), - ); + ]; if ($this->options['limit']) { $form['value']['#type'] = 'entity_autocomplete'; $form['value']['#target_type'] = 'taxonomy_term'; - $form['value']['#selection_settings']['target_bundles'] = array($vocabulary->id()); + $form['value']['#selection_settings']['target_bundles'] = [$vocabulary->id()]; $form['value']['#tags'] = TRUE; $form['value']['#process_default_value'] = FALSE; } @@ -175,18 +177,18 @@ protected function valueForm(&$form, FormStateInterface $form_state) { else { if (!empty($this->options['hierarchy']) && $this->options['limit']) { $tree = $this->termStorage->loadTree($vocabulary->id(), 0, NULL, TRUE); - $options = array(); + $options = []; if ($tree) { foreach ($tree as $term) { $choice = new \stdClass(); - $choice->option = array($term->id() => str_repeat('-', $term->depth) . \Drupal::entityManager()->getTranslationFromContext($term)->label()); + $choice->option = [$term->id() => str_repeat('-', $term->depth) . \Drupal::entityManager()->getTranslationFromContext($term)->label()]; $options[] = $choice; } } } else { - $options = array(); + $options = []; $query = \Drupal::entityQuery('taxonomy_term') // @todo Sorting on vocabulary properties - // https://www.drupal.org/node/1821274. @@ -211,7 +213,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) { $options = $this->reduceValueOptions($options); if (!empty($this->options['expose']['multiple']) && empty($this->options['expose']['required'])) { - $default_value = array(); + $default_value = []; } } @@ -225,7 +227,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } // Due to #1464174 there is a chance that array('') was saved in the admin ui. // Let's choose a safe default value. - elseif ($default_value == array('')) { + elseif ($default_value == ['']) { $default_value = 'All'; } else { @@ -234,14 +236,14 @@ protected function valueForm(&$form, FormStateInterface $form_state) { } } } - $form['value'] = array( + $form['value'] = [ '#type' => 'select', - '#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->label())) : $this->t('Select terms'), + '#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', ['@voc' => $vocabulary->label()]) : $this->t('Select terms'), '#multiple' => TRUE, '#options' => $options, '#size' => min(9, count($options)), '#default_value' => $default_value, - ); + ]; $user_input = $form_state->getUserInput(); if ($exposed && isset($identifier) && !isset($user_input[$identifier])) { @@ -265,13 +267,13 @@ protected function valueValidate($form, FormStateInterface $form_state) { return; } - $tids = array(); - if ($values = $form_state->getValue(array('options', 'value'))) { + $tids = []; + if ($values = $form_state->getValue(['options', 'value'])) { foreach ($values as $value) { $tids[] = $value['target_id']; } } - $form_state->setValue(array('options', 'value'), $tids); + $form_state->setValue(['options', 'value'], $tids); } public function acceptExposedInput($input) { @@ -348,16 +350,16 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) { if ($this->options['type'] != 'select') { unset($form['expose']['reduce']); } - $form['error_message'] = array( + $form['error_message'] = [ '#type' => 'checkbox', '#title' => $this->t('Display error message'), '#default_value' => !empty($this->options['error_message']), - ); + ]; } public function adminSummary() { // set up $this->valueOptions for the parent summary - $this->valueOptions = array(); + $this->valueOptions = []; if ($this->value) { $this->value = array_filter($this->value); diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php index a2b8108f..802786e4 100644 --- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php +++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php @@ -2,6 +2,7 @@ namespace Drupal\taxonomy\Plugin\views\filter; +use Drupal\Core\Database\Query\Condition; use Drupal\Core\Form\FormStateInterface; /** @@ -17,15 +18,15 @@ class TaxonomyIndexTidDepth extends TaxonomyIndexTid { public function operatorOptions($which = 'title') { - return array( + return [ 'or' => $this->t('Is one of'), - ); + ]; } protected function defineOptions() { $options = parent::defineOptions(); - $options['depth'] = array('default' => 0); + $options['depth'] = ['default' => 0]; return $options; } @@ -33,12 +34,12 @@ protected function defineOptions() { public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) { parent::buildExtraOptionsForm($form, $form_state); - $form['depth'] = array( + $form['depth'] = [ '#type' => 'weight', '#title' => $this->t('Depth'), '#default_value' => $this->options['depth'], '#description' => $this->t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'), - ); + ]; } public function query() { @@ -54,7 +55,7 @@ public function query() { $operator = '='; } else { - $operator = 'IN';# " IN (" . implode(', ', array_fill(0, sizeof($this->value), '%d')) . ")"; + $operator = 'IN'; } // The normal use of ensureMyTable() here breaks Views. @@ -72,7 +73,7 @@ public function query() { // Now build the subqueries. $subquery = db_select('taxonomy_index', 'tn'); $subquery->addField('tn', 'nid'); - $where = db_or()->condition('tn.tid', $this->value, $operator); + $where = (new Condition('OR'))->condition('tn.tid', $this->value, $operator); $last = "tn"; if ($this->options['depth'] > 0) { diff --git a/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php b/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php index b1c72e4b..13fd056a 100644 --- a/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php +++ b/core/modules/taxonomy/src/Plugin/views/relationship/NodeTermData.php @@ -74,24 +74,24 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o protected function defineOptions() { $options = parent::defineOptions(); - $options['vids'] = array('default' => array()); + $options['vids'] = ['default' => []]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { $vocabularies = $this->vocabularyStorage->loadMultiple(); - $options = array(); + $options = []; foreach ($vocabularies as $voc) { $options[$voc->id()] = $voc->label(); } - $form['vids'] = array( + $form['vids'] = [ '#type' => 'checkboxes', '#title' => $this->t('Vocabularies'), '#options' => $options, '#default_value' => $this->options['vids'], '#description' => $this->t('Choose which vocabularies you wish to relate. Remember that every term found will create a new record, so this relationship is best used on just one vocabulary that has only one term per node.'), - ); + ]; parent::buildOptionsForm($form, $form_state); } @@ -134,7 +134,7 @@ public function query() { $query->condition('td.vid', array_filter($this->options['vids']), 'IN'); $query->addTag('taxonomy_term_access'); $query->fields('td'); - $query->fields('tn', array('nid')); + $query->fields('tn', ['nid']); $def['table formula'] = $query; } diff --git a/core/modules/taxonomy/src/TermBreadcrumbBuilder.php b/core/modules/taxonomy/src/TermBreadcrumbBuilder.php index 838011d7..73588d1f 100644 --- a/core/modules/taxonomy/src/TermBreadcrumbBuilder.php +++ b/core/modules/taxonomy/src/TermBreadcrumbBuilder.php @@ -68,7 +68,7 @@ public function build(RouteMatchInterface $route_match) { foreach (array_reverse($parents) as $term) { $term = $this->entityManager->getTranslationFromContext($term); $breadcrumb->addCacheableDependency($term); - $breadcrumb->addLink(Link::createFromRoute($term->getName(), 'entity.taxonomy_term.canonical', array('taxonomy_term' => $term->id()))); + $breadcrumb->addLink(Link::createFromRoute($term->getName(), 'entity.taxonomy_term.canonical', ['taxonomy_term' => $term->id()])); } // This breadcrumb builder is based on a route parameter, and hence it diff --git a/core/modules/taxonomy/src/TermForm.php b/core/modules/taxonomy/src/TermForm.php index 1f563513..1eae95a0 100644 --- a/core/modules/taxonomy/src/TermForm.php +++ b/core/modules/taxonomy/src/TermForm.php @@ -23,12 +23,12 @@ public function form(array $form, FormStateInterface $form_state) { $form_state->set(['taxonomy', 'parent'], $parent); $form_state->set(['taxonomy', 'vocabulary'], $vocabulary); - $form['relations'] = array( + $form['relations'] = [ '#type' => 'details', '#title' => $this->t('Relations'), '#open' => $vocabulary->getHierarchy() == VocabularyInterface::HIERARCHY_MULTIPLE, '#weight' => 10, - ); + ]; // \Drupal\taxonomy\TermStorageInterface::loadTree() and // \Drupal\taxonomy\TermStorageInterface::loadParents() may contain large @@ -46,9 +46,9 @@ public function form(array $form, FormStateInterface $form_state) { $exclude[] = $term->id(); $tree = $taxonomy_storage->loadTree($vocabulary->id()); - $options = array('<' . $this->t('root') . '>'); + $options = ['<' . $this->t('root') . '>']; if (empty($parent)) { - $parent = array(0); + $parent = [0]; } foreach ($tree as $item) { @@ -57,35 +57,35 @@ public function form(array $form, FormStateInterface $form_state) { } } - $form['relations']['parent'] = array( + $form['relations']['parent'] = [ '#type' => 'select', '#title' => $this->t('Parent terms'), '#options' => $options, '#default_value' => $parent, '#multiple' => TRUE, - ); + ]; } - $form['relations']['weight'] = array( + $form['relations']['weight'] = [ '#type' => 'textfield', '#title' => $this->t('Weight'), '#size' => 6, '#default_value' => $term->getWeight(), '#description' => $this->t('Terms are displayed in ascending order by weight.'), '#required' => TRUE, - ); + ]; - $form['vid'] = array( + $form['vid'] = [ '#type' => 'value', '#value' => $vocabulary->id(), - ); + ]; - $form['tid'] = array( + $form['tid'] = [ '#type' => 'value', '#value' => $term->id(), - ); + ]; - return parent::form($form, $form_state, $term); + return parent::form($form, $form_state); } /** @@ -127,21 +127,21 @@ public function save(array $form, FormStateInterface $form_state) { $view_link = $term->link($term->getName()); switch ($result) { case SAVED_NEW: - drupal_set_message($this->t('Created new term %term.', array('%term' => $view_link))); - $this->logger('taxonomy')->notice('Created new term %term.', array('%term' => $term->getName(), 'link' => $edit_link)); + drupal_set_message($this->t('Created new term %term.', ['%term' => $view_link])); + $this->logger('taxonomy')->notice('Created new term %term.', ['%term' => $term->getName(), 'link' => $edit_link]); break; case SAVED_UPDATED: - drupal_set_message($this->t('Updated term %term.', array('%term' => $view_link))); - $this->logger('taxonomy')->notice('Updated term %term.', array('%term' => $term->getName(), 'link' => $edit_link)); + drupal_set_message($this->t('Updated term %term.', ['%term' => $view_link])); + $this->logger('taxonomy')->notice('Updated term %term.', ['%term' => $term->getName(), 'link' => $edit_link]); break; } $current_parent_count = count($form_state->getValue('parent')); $previous_parent_count = count($form_state->get(['taxonomy', 'parent'])); // Root doesn't count if it's the only parent. - if ($current_parent_count == 1 && $form_state->hasValue(array('parent', 0))) { + if ($current_parent_count == 1 && $form_state->hasValue(['parent', 0])) { $current_parent_count = 0; - $form_state->setValue('parent', array()); + $form_state->setValue('parent', []); } // If the number of parents has been reduced to one or none, do a check on the diff --git a/core/modules/taxonomy/src/TermInterface.php b/core/modules/taxonomy/src/TermInterface.php index f832620e..3087a56e 100644 --- a/core/modules/taxonomy/src/TermInterface.php +++ b/core/modules/taxonomy/src/TermInterface.php @@ -85,8 +85,11 @@ public function setWeight($weight); /** * Get the taxonomy vocabulary id this term belongs to. * - * @return int + * @return string * The id of the vocabulary. + * + * @deprecated Scheduled for removal before Drupal 9.0.0. Use + * TermInterface::bundle() instead. */ public function getVocabularyId(); diff --git a/core/modules/taxonomy/src/TermStorage.php b/core/modules/taxonomy/src/TermStorage.php index bc44c226..0a00c13d 100644 --- a/core/modules/taxonomy/src/TermStorage.php +++ b/core/modules/taxonomy/src/TermStorage.php @@ -15,49 +15,49 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac * * @var array */ - protected $parents = array(); + protected $parents = []; /** * Array of all loaded term ancestry keyed by ancestor term ID. * * @var array */ - protected $parentsAll = array(); + protected $parentsAll = []; /** * Array of child terms keyed by parent term ID. * * @var array */ - protected $children = array(); + protected $children = []; /** * Array of term parents keyed by vocabulary ID and child term ID. * * @var array */ - protected $treeParents = array(); + protected $treeParents = []; /** * Array of term ancestors keyed by vocabulary ID and parent term ID. * * @var array */ - protected $treeChildren = array(); + protected $treeChildren = []; /** * Array of terms in a tree keyed by vocabulary ID and term ID. * * @var array */ - protected $treeTerms = array(); + protected $treeTerms = []; /** * Array of loaded trees keyed by a cache id matching tree arguments. * * @var array */ - protected $trees = array(); + protected $trees = []; /** * {@inheritdoc} @@ -66,10 +66,10 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac * An array of values to set, keyed by property name. A value for the * vocabulary ID ('vid') is required. */ - public function create(array $values = array()) { + public function create(array $values = []) { // Save new terms with no parents by default. if (empty($values['parent'])) { - $values['parent'] = array(0); + $values['parent'] = [0]; } $entity = parent::create($values); return $entity; @@ -80,13 +80,13 @@ public function create(array $values = array()) { */ public function resetCache(array $ids = NULL) { drupal_static_reset('taxonomy_term_count_nodes'); - $this->parents = array(); - $this->parentsAll = array(); - $this->children = array(); - $this->treeChildren = array(); - $this->treeParents = array(); - $this->treeTerms = array(); - $this->trees = array(); + $this->parents = []; + $this->parentsAll = []; + $this->children = []; + $this->treeChildren = []; + $this->treeParents = []; + $this->treeTerms = []; + $this->trees = []; parent::resetCache($ids); } @@ -104,13 +104,13 @@ public function deleteTermHierarchy($tids) { */ public function updateTermHierarchy(EntityInterface $term) { $query = $this->database->insert('taxonomy_term_hierarchy') - ->fields(array('tid', 'parent')); + ->fields(['tid', 'parent']); foreach ($term->parent as $parent) { - $query->values(array( + $query->values([ 'tid' => $term->id(), 'parent' => (int) $parent->target_id, - )); + ]); } $query->execute(); } @@ -120,7 +120,7 @@ public function updateTermHierarchy(EntityInterface $term) { */ public function loadParents($tid) { if (!isset($this->parents[$tid])) { - $parents = array(); + $parents = []; $query = $this->database->select('taxonomy_term_field_data', 't'); $query->join('taxonomy_term_hierarchy', 'h', 'h.parent = t.tid'); $query->addField('t', 'tid'); @@ -142,7 +142,7 @@ public function loadParents($tid) { */ public function loadAllParents($tid) { if (!isset($this->parentsAll[$tid])) { - $parents = array(); + $parents = []; if ($term = $this->load($tid)) { $parents[$term->id()] = $term; $terms_to_search[] = $term->id(); @@ -169,7 +169,7 @@ public function loadAllParents($tid) { */ public function loadChildren($tid, $vid = NULL) { if (!isset($this->children[$tid])) { - $children = array(); + $children = []; $query = $this->database->select('taxonomy_term_field_data', 't'); $query->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid'); $query->addField('t', 'tid'); @@ -198,15 +198,15 @@ public function loadTree($vid, $parent = 0, $max_depth = NULL, $load_entities = // We cache trees, so it's not CPU-intensive to call on a term and its // children, too. if (!isset($this->treeChildren[$vid])) { - $this->treeChildren[$vid] = array(); - $this->treeParents[$vid] = array(); - $this->treeTerms[$vid] = array(); + $this->treeChildren[$vid] = []; + $this->treeParents[$vid] = []; + $this->treeTerms[$vid] = []; $query = $this->database->select('taxonomy_term_field_data', 't'); $query->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid'); $result = $query ->addTag('taxonomy_term_access') ->fields('t') - ->fields('h', array('parent')) + ->fields('h', ['parent']) ->condition('t.vid', $vid) ->condition('t.default_langcode', 1) ->orderBy('t.weight') @@ -221,17 +221,17 @@ public function loadTree($vid, $parent = 0, $max_depth = NULL, $load_entities = // Load full entities, if necessary. The entity controller statically // caches the results. - $term_entities = array(); + $term_entities = []; if ($load_entities) { $term_entities = $this->loadMultiple(array_keys($this->treeTerms[$vid])); } $max_depth = (!isset($max_depth)) ? count($this->treeChildren[$vid]) : $max_depth; - $tree = array(); + $tree = []; // Keeps track of the parents we have to process, the last entry is used // for the next processing step. - $process_parents = array(); + $process_parents = []; $process_parents[] = $parent; // Loops over the parent terms and adds its children to the tree array. @@ -304,7 +304,7 @@ public function nodeCount($vid) { */ public function resetWeights($vid) { $this->database->update('taxonomy_term_field_data') - ->fields(array('weight' => 0)) + ->fields(['weight' => 0]) ->condition('vid', $vid) ->execute(); } @@ -312,10 +312,10 @@ public function resetWeights($vid) { /** * {@inheritdoc} */ - public function getNodeTerms(array $nids, array $vocabs = array(), $langcode = NULL) { + public function getNodeTerms(array $nids, array $vocabs = [], $langcode = NULL) { $query = db_select('taxonomy_term_field_data', 'td'); $query->innerJoin('taxonomy_index', 'tn', 'td.tid = tn.tid'); - $query->fields('td', array('tid')); + $query->fields('td', ['tid']); $query->addField('tn', 'nid', 'node_nid'); $query->orderby('td.weight'); $query->orderby('td.name'); @@ -328,15 +328,15 @@ public function getNodeTerms(array $nids, array $vocabs = array(), $langcode = N $query->condition('td.langcode', $langcode); } - $results = array(); - $all_tids = array(); + $results = []; + $all_tids = []; foreach ($query->execute() as $term_record) { $results[$term_record->node_nid][] = $term_record->tid; $all_tids[] = $term_record->tid; } $all_terms = $this->loadMultiple($all_tids); - $terms = array(); + $terms = []; foreach ($results as $nid => $tids) { foreach ($tids as $tid) { $terms[$nid][$tid] = $all_terms[$tid]; @@ -361,13 +361,13 @@ public function __sleep() { public function __wakeup() { parent::__wakeup(); // Initialize static caches. - $this->parents = array(); - $this->parentsAll = array(); - $this->children = array(); - $this->treeChildren = array(); - $this->treeParents = array(); - $this->treeTerms = array(); - $this->trees = array(); + $this->parents = []; + $this->parentsAll = []; + $this->children = []; + $this->treeChildren = []; + $this->treeParents = []; + $this->treeTerms = []; + $this->trees = []; } } diff --git a/core/modules/taxonomy/src/TermStorageInterface.php b/core/modules/taxonomy/src/TermStorageInterface.php index 99167114..4ab2d2de 100644 --- a/core/modules/taxonomy/src/TermStorageInterface.php +++ b/core/modules/taxonomy/src/TermStorageInterface.php @@ -52,7 +52,7 @@ public function loadAllParents($tid); * Finds all children of a term ID. * * @param int $tid - * Term ID to retrieve parents for. + * Term ID to retrieve children for. * @param string $vid * An optional vocabulary ID to restrict the child search. * @@ -116,6 +116,6 @@ public function resetWeights($vid); * @return array * An array of nids and the term entities they were tagged with. */ - public function getNodeTerms(array $nids, array $vocabs = array(), $langcode = NULL); + public function getNodeTerms(array $nids, array $vocabs = [], $langcode = NULL); } diff --git a/core/modules/taxonomy/src/TermStorageSchema.php b/core/modules/taxonomy/src/TermStorageSchema.php index 5534821e..5bcb088d 100644 --- a/core/modules/taxonomy/src/TermStorageSchema.php +++ b/core/modules/taxonomy/src/TermStorageSchema.php @@ -17,93 +17,93 @@ class TermStorageSchema extends SqlContentEntityStorageSchema { protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { $schema = parent::getEntitySchema($entity_type, $reset = FALSE); - $schema['taxonomy_term_field_data']['indexes'] += array( - 'taxonomy_term__tree' => array('vid', 'weight', 'name'), - 'taxonomy_term__vid_name' => array('vid', 'name'), - ); + $schema['taxonomy_term_field_data']['indexes'] += [ + 'taxonomy_term__tree' => ['vid', 'weight', 'name'], + 'taxonomy_term__vid_name' => ['vid', 'name'], + ]; - $schema['taxonomy_term_hierarchy'] = array( + $schema['taxonomy_term_hierarchy'] = [ 'description' => 'Stores the hierarchical relationship between terms.', - 'fields' => array( - 'tid' => array( + 'fields' => [ + 'tid' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => 'Primary Key: The {taxonomy_term_data}.tid of the term.', - ), - 'parent' => array( + ], + 'parent' => [ 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'description' => "Primary Key: The {taxonomy_term_data}.tid of the term's parent. 0 indicates no parent.", - ), - ), - 'indexes' => array( - 'parent' => array('parent'), - ), - 'foreign keys' => array( - 'taxonomy_term_data' => array( + ], + ], + 'indexes' => [ + 'parent' => ['parent'], + ], + 'foreign keys' => [ + 'taxonomy_term_data' => [ 'table' => 'taxonomy_term_data', - 'columns' => array('tid' => 'tid'), - ), - ), - 'primary key' => array('tid', 'parent'), - ); + 'columns' => ['tid' => 'tid'], + ], + ], + 'primary key' => ['tid', 'parent'], + ]; - $schema['taxonomy_index'] = array( + $schema['taxonomy_index'] = [ 'description' => 'Maintains denormalized information about node/term relationships.', - 'fields' => array( - 'nid' => array( + 'fields' => [ + 'nid' => [ 'description' => 'The {node}.nid this record tracks.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'tid' => array( + ], + 'tid' => [ 'description' => 'The term ID.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - ), - 'status' => array( + ], + 'status' => [ 'description' => 'Boolean indicating whether the node is published (visible to non-administrators).', 'type' => 'int', 'not null' => TRUE, 'default' => 1, - ), - 'sticky' => array( + ], + 'sticky' => [ 'description' => 'Boolean indicating whether the node is sticky.', 'type' => 'int', 'not null' => FALSE, 'default' => 0, 'size' => 'tiny', - ), - 'created' => array( + ], + 'created' => [ 'description' => 'The Unix timestamp when the node was created.', 'type' => 'int', 'not null' => TRUE, 'default' => 0, - ), - ), - 'primary key' => array('nid', 'tid'), - 'indexes' => array( - 'term_node' => array('tid', 'status', 'sticky', 'created'), - ), - 'foreign keys' => array( - 'tracked_node' => array( + ], + ], + 'primary key' => ['nid', 'tid'], + 'indexes' => [ + 'term_node' => ['tid', 'status', 'sticky', 'created'], + ], + 'foreign keys' => [ + 'tracked_node' => [ 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - 'term' => array( + 'columns' => ['nid' => 'nid'], + ], + 'term' => [ 'table' => 'taxonomy_term_data', - 'columns' => array('tid' => 'tid'), - ), - ), - ); + 'columns' => ['tid' => 'tid'], + ], + ], + ]; return $schema; } diff --git a/core/modules/taxonomy/src/TermTranslationHandler.php b/core/modules/taxonomy/src/TermTranslationHandler.php index 72539b53..688c63e3 100644 --- a/core/modules/taxonomy/src/TermTranslationHandler.php +++ b/core/modules/taxonomy/src/TermTranslationHandler.php @@ -16,7 +16,7 @@ class TermTranslationHandler extends ContentTranslationHandler { */ public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { parent::entityFormAlter($form, $form_state, $entity); - $form['actions']['submit']['#submit'][] = array($this, 'entityFormSave'); + $form['actions']['submit']['#submit'][] = [$this, 'entityFormSave']; } /** @@ -26,7 +26,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En * * @see \Drupal\Core\Entity\EntityForm::build() */ - function entityFormSave(array $form, FormStateInterface $form_state) { + public function entityFormSave(array $form, FormStateInterface $form_state) { if ($this->getSourceLangcode($form_state)) { $entity = $form_state->getFormObject()->getEntity(); // We need a redirect here, otherwise we would get an access denied page, diff --git a/core/modules/taxonomy/src/TermViewBuilder.php b/core/modules/taxonomy/src/TermViewBuilder.php index ca74535a..6748a4b0 100644 --- a/core/modules/taxonomy/src/TermViewBuilder.php +++ b/core/modules/taxonomy/src/TermViewBuilder.php @@ -16,10 +16,10 @@ class TermViewBuilder extends EntityViewBuilder { */ protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { parent::alterBuild($build, $entity, $display, $view_mode); - $build['#contextual_links']['taxonomy_term'] = array( - 'route_parameters' => array('taxonomy_term' => $entity->id()), - 'metadata' => array('changed' => $entity->getChangedTime()), - ); + $build['#contextual_links']['taxonomy_term'] = [ + 'route_parameters' => ['taxonomy_term' => $entity->id()], + 'metadata' => ['changed' => $entity->getChangedTime()], + ]; } } diff --git a/core/modules/taxonomy/src/TermViewsData.php b/core/modules/taxonomy/src/TermViewsData.php index 89b2b55e..5e98bfe9 100644 --- a/core/modules/taxonomy/src/TermViewsData.php +++ b/core/modules/taxonomy/src/TermViewsData.php @@ -19,13 +19,13 @@ public function getViewsData() { $data['taxonomy_term_field_data']['table']['base']['access query tag'] = 'taxonomy_term_access'; $data['taxonomy_term_field_data']['table']['wizard_id'] = 'taxonomy_term'; - $data['taxonomy_term_field_data']['table']['join'] = array( + $data['taxonomy_term_field_data']['table']['join'] = [ // This is provided for the many_to_one argument. - 'taxonomy_index' => array( + 'taxonomy_index' => [ 'field' => 'tid', 'left_field' => 'tid', - ), - ); + ], + ]; $data['taxonomy_term_field_data']['tid']['help'] = $this->t('The tid of a taxonomy term.'); @@ -39,18 +39,18 @@ public function getViewsData() { $data['taxonomy_term_field_data']['tid']['filter']['hierarchy table'] = 'taxonomy_term_hierarchy'; $data['taxonomy_term_field_data']['tid']['filter']['numeric'] = TRUE; - $data['taxonomy_term_field_data']['tid_raw'] = array( + $data['taxonomy_term_field_data']['tid_raw'] = [ 'title' => $this->t('Term ID'), 'help' => $this->t('The tid of a taxonomy term.'), 'real field' => 'tid', - 'filter' => array( + 'filter' => [ 'id' => 'numeric', 'allow empty' => TRUE, - ), - ); + ], + ]; - $data['taxonomy_term_field_data']['tid_representative'] = array( - 'relationship' => array( + $data['taxonomy_term_field_data']['tid_representative'] = [ + 'relationship' => [ 'title' => $this->t('Representative node'), 'label' => $this->t('Representative node'), 'help' => $this->t('Obtains a single representative node for each term, according to a chosen sort criterion.'), @@ -62,12 +62,12 @@ public function getViewsData() { 'base' => 'node_field_data', 'field' => 'nid', 'relationship' => 'node_field_data:term_node_tid' - ), - ); + ], + ]; $data['taxonomy_term_field_data']['vid']['help'] = $this->t('Filter the results of "Taxonomy: Term" to a particular vocabulary.'); unset($data['taxonomy_term_field_data']['vid']['field']); - unset($data['taxonomy_term_field_data']['vid']['argument']); + $data['taxonomy_term_field_data']['vid']['argument']['id'] = 'vocabulary_vid'; unset($data['taxonomy_term_field_data']['vid']['sort']); $data['taxonomy_term_field_data']['name']['field']['id'] = 'term_name'; @@ -79,114 +79,114 @@ public function getViewsData() { $data['taxonomy_term_field_data']['changed']['title'] = $this->t('Updated date'); $data['taxonomy_term_field_data']['changed']['help'] = $this->t('The date the term was last updated.'); - $data['taxonomy_term_field_data']['changed_fulldate'] = array( + $data['taxonomy_term_field_data']['changed_fulldate'] = [ 'title' => $this->t('Updated date'), 'help' => $this->t('Date in the form of CCYYMMDD.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_fulldate', - ), - ); + ], + ]; - $data['taxonomy_term_field_data']['changed_year_month'] = array( + $data['taxonomy_term_field_data']['changed_year_month'] = [ 'title' => $this->t('Updated year + month'), 'help' => $this->t('Date in the form of YYYYMM.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_year_month', - ), - ); + ], + ]; - $data['taxonomy_term_field_data']['changed_year'] = array( + $data['taxonomy_term_field_data']['changed_year'] = [ 'title' => $this->t('Updated year'), 'help' => $this->t('Date in the form of YYYY.'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_year', - ), - ); + ], + ]; - $data['taxonomy_term_field_data']['changed_month'] = array( + $data['taxonomy_term_field_data']['changed_month'] = [ 'title' => $this->t('Updated month'), 'help' => $this->t('Date in the form of MM (01 - 12).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_month', - ), - ); + ], + ]; - $data['taxonomy_term_field_data']['changed_day'] = array( + $data['taxonomy_term_field_data']['changed_day'] = [ 'title' => $this->t('Updated day'), 'help' => $this->t('Date in the form of DD (01 - 31).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_day', - ), - ); + ], + ]; - $data['taxonomy_term_field_data']['changed_week'] = array( + $data['taxonomy_term_field_data']['changed_week'] = [ 'title' => $this->t('Updated week'), 'help' => $this->t('Date in the form of WW (01 - 53).'), - 'argument' => array( + 'argument' => [ 'field' => 'changed', 'id' => 'date_week', - ), - ); + ], + ]; $data['taxonomy_index']['table']['group'] = $this->t('Taxonomy term'); - $data['taxonomy_index']['table']['join'] = array( - 'taxonomy_term_field_data' => array( + $data['taxonomy_index']['table']['join'] = [ + 'taxonomy_term_field_data' => [ // links directly to taxonomy_term_field_data via tid 'left_field' => 'tid', 'field' => 'tid', - ), - 'node_field_data' => array( + ], + 'node_field_data' => [ // links directly to node via nid 'left_field' => 'nid', 'field' => 'nid', - ), - 'taxonomy_term_hierarchy' => array( + ], + 'taxonomy_term_hierarchy' => [ 'left_field' => 'tid', 'field' => 'tid', - ), - ); + ], + ]; - $data['taxonomy_index']['nid'] = array( + $data['taxonomy_index']['nid'] = [ 'title' => $this->t('Content with term'), 'help' => $this->t('Relate all content tagged with a term.'), - 'relationship' => array( + 'relationship' => [ 'id' => 'standard', 'base' => 'node', 'base field' => 'nid', 'label' => $this->t('node'), 'skip base' => 'node', - ), - ); + ], + ]; // @todo This stuff needs to move to a node field since really it's all // about nodes. - $data['taxonomy_index']['tid'] = array( + $data['taxonomy_index']['tid'] = [ 'group' => $this->t('Content'), 'title' => $this->t('Has taxonomy term ID'), 'help' => $this->t('Display content if it has the selected taxonomy terms.'), - 'argument' => array( + 'argument' => [ 'id' => 'taxonomy_index_tid', 'name table' => 'taxonomy_term_field_data', 'name field' => 'name', 'empty field name' => $this->t('Uncategorized'), 'numeric' => TRUE, 'skip base' => 'taxonomy_term_field_data', - ), - 'filter' => array( + ], + 'filter' => [ 'title' => $this->t('Has taxonomy term'), 'id' => 'taxonomy_index_tid', 'hierarchy table' => 'taxonomy_term_hierarchy', 'numeric' => TRUE, 'skip base' => 'taxonomy_term_field_data', 'allow empty' => TRUE, - ), - ); + ], + ]; $data['taxonomy_index']['status'] = [ 'title' => $this->t('Publish status'), @@ -226,37 +226,37 @@ public function getViewsData() { $data['taxonomy_term_hierarchy']['table']['group'] = $this->t('Taxonomy term'); $data['taxonomy_term_hierarchy']['table']['provider'] = 'taxonomy'; - $data['taxonomy_term_hierarchy']['table']['join'] = array( - 'taxonomy_term_hierarchy' => array( + $data['taxonomy_term_hierarchy']['table']['join'] = [ + 'taxonomy_term_hierarchy' => [ // Link to self through left.parent = right.tid (going down in depth). 'left_field' => 'tid', 'field' => 'parent', - ), - 'taxonomy_term_field_data' => array( + ], + 'taxonomy_term_field_data' => [ // Link directly to taxonomy_term_field_data via tid. 'left_field' => 'tid', 'field' => 'tid', - ), - ); + ], + ]; - $data['taxonomy_term_hierarchy']['parent'] = array( + $data['taxonomy_term_hierarchy']['parent'] = [ 'title' => $this->t('Parent term'), 'help' => $this->t('The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents.'), - 'relationship' => array( + 'relationship' => [ 'base' => 'taxonomy_term_field_data', 'field' => 'parent', 'label' => $this->t('Parent'), 'id' => 'standard', - ), - 'filter' => array( + ], + 'filter' => [ 'help' => $this->t('Filter the results of "Taxonomy: Term" by the parent pid.'), 'id' => 'numeric', - ), - 'argument' => array( + ], + 'argument' => [ 'help' => $this->t('The parent term of the term.'), 'id' => 'taxonomy', - ), - ); + ], + ]; return $data; } diff --git a/core/modules/taxonomy/src/Tests/RssTest.php b/core/modules/taxonomy/src/Tests/RssTest.php index effd4dd9..81a397d6 100644 --- a/core/modules/taxonomy/src/Tests/RssTest.php +++ b/core/modules/taxonomy/src/Tests/RssTest.php @@ -18,7 +18,7 @@ class RssTest extends TaxonomyTestBase { * * @var array */ - public static $modules = array('node', 'field_ui', 'views'); + public static $modules = ['node', 'field_ui', 'views']; /** * Vocabulary for testing. @@ -41,23 +41,23 @@ protected function setUp() { $this->vocabulary = $this->createVocabulary(); $this->fieldName = 'taxonomy_' . $this->vocabulary->id(); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $this->fieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'options_select', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } @@ -66,26 +66,27 @@ protected function setUp() { * * Create a node and assert that taxonomy terms appear in rss.xml. */ - function testTaxonomyRss() { + public function testTaxonomyRss() { // Create two taxonomy terms. $term1 = $this->createTerm($this->vocabulary); // RSS display must be added manually. $this->drupalGet("admin/structure/types/manage/article/display"); - $edit = array( + $edit = [ "display_modes_custom[rss]" => '1', - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); // Change the format to 'RSS category'. $this->drupalGet("admin/structure/types/manage/article/display/rss"); - $edit = array( + $edit = [ "fields[taxonomy_" . $this->vocabulary->id() . "][type]" => 'entity_reference_rss_category', - ); + "fields[taxonomy_" . $this->vocabulary->id() . "][region]" => 'content', + ]; $this->drupalPostForm(NULL, $edit, t('Save')); // Post an article. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(); $edit[$this->fieldName . '[]'] = $term1->id(); $this->drupalPostForm('node/add/article', $edit, t('Save')); @@ -94,7 +95,7 @@ function testTaxonomyRss() { $this->drupalGet('rss.xml'); $test_element = sprintf( '%s', - 'domain="' . $term1->url('canonical', array('absolute' => TRUE)) . '"', + 'domain="' . $term1->url('canonical', ['absolute' => TRUE]) . '"', $term1->getName() ); $this->assertRaw($test_element, 'Term is displayed when viewing the rss feed.'); diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTermIndentationTest.php b/core/modules/taxonomy/src/Tests/TaxonomyTermIndentationTest.php index 6043d775..599b6fb2 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTermIndentationTest.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTermIndentationTest.php @@ -14,7 +14,7 @@ class TaxonomyTermIndentationTest extends TaxonomyTestBase { * * @var array */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * Vocabulary for testing. @@ -32,7 +32,7 @@ protected function setUp() { /** * Tests term indentation. */ - function testTermIndentation() { + public function testTermIndentation() { // Create three taxonomy terms. $term1 = $this->createTerm($this->vocabulary); $term2 = $this->createTerm($this->vocabulary); @@ -42,12 +42,12 @@ function testTermIndentation() { $taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term'); // Indent the second term under the first one. - $edit = array( + $edit = [ 'terms[tid:' . $term2->id() . ':0][term][tid]' => 2, 'terms[tid:' . $term2->id() . ':0][term][parent]' => 1, 'terms[tid:' . $term2->id() . ':0][term][depth]' => 1, 'terms[tid:' . $term2->id() . ':0][weight]' => 1, - ); + ]; // Submit the edited form and check for HTML indentation element presence. $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid') . '/overview', $edit, t('Save')); @@ -58,14 +58,14 @@ function testTermIndentation() { $this->assertEqual(key($parents), 1, 'Term 1 is the term 2\'s parent'); // Move the second term back out to the root level. - $edit = array( + $edit = [ 'terms[tid:' . $term2->id() . ':0][term][tid]' => 2, 'terms[tid:' . $term2->id() . ':0][term][parent]' => 0, 'terms[tid:' . $term2->id() . ':0][term][depth]' => 0, 'terms[tid:' . $term2->id() . ':0][weight]' => 1, - ); + ]; - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid' ) . '/overview', $edit, t('Save')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->get('vid') . '/overview', $edit, t('Save')); // All terms back at the root level, no indentation should be present. $this->assertNoPattern('|
     
    |'); diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php b/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php index aa912379..b4f941da 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTestBase.php @@ -2,11 +2,17 @@ namespace Drupal\taxonomy\Tests; +@trigger_error(__NAMESPACE__ . '\TaxonomyTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTestBase', E_USER_DEPRECATED); + use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; use Drupal\simpletest\WebTestBase; +use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait; /** * Provides common helper methods for Taxonomy module tests. + * + * @deprecated Scheduled for removal in Drupal 9.0.0. + * Use \Drupal\Tests\taxonomy\Functional\TaxonomyTestBase instead. */ abstract class TaxonomyTestBase extends WebTestBase { @@ -18,7 +24,7 @@ abstract class TaxonomyTestBase extends WebTestBase { * * @var array */ - public static $modules = array('taxonomy', 'block'); + public static $modules = ['taxonomy', 'block']; /** * {@inheritdoc} @@ -29,7 +35,7 @@ protected function setUp() { // Create Basic page and Article node types. if ($this->profile != 'standard') { - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); } } diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php b/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php index f04be001..8c4a6672 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTestTrait.php @@ -2,6 +2,8 @@ namespace Drupal\taxonomy\Tests; +@trigger_error(__NAMESPACE__ . '\TaxonomyTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait', E_USER_DEPRECATED); + use Drupal\Component\Utility\Unicode; use Drupal\Core\Language\LanguageInterface; use Drupal\taxonomy\Entity\Vocabulary; @@ -9,13 +11,16 @@ /** * Provides common helper methods for Taxonomy module tests. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait */ trait TaxonomyTestTrait { /** * Returns a new vocabulary with random properties. */ - function createVocabulary() { + public function createVocabulary() { // Create a vocabulary. $vocabulary = Vocabulary::create([ 'name' => $this->randomMachineName(), @@ -40,7 +45,7 @@ function createVocabulary() { * @return \Drupal\taxonomy\Entity\Term * The new taxonomy term object. */ - function createTerm(Vocabulary $vocabulary, $values = array()) { + public function createTerm(Vocabulary $vocabulary, $values = []) { $filter_formats = filter_formats(); $format = array_pop($filter_formats); $term = Term::create($values + [ diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php index 5ae62703..9b952ebb 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php @@ -2,6 +2,8 @@ namespace Drupal\taxonomy\Tests; +@trigger_error(__NAMESPACE__ . '\TaxonomyTranslationTestTrait is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\taxonomy\Functional\TaxonomyTranslationTestTrait', E_USER_DEPRECATED); + use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; use Drupal\field\Entity\FieldStorageConfig; @@ -9,6 +11,9 @@ /** * Provides common testing base for translated taxonomy terms. + * + * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. + * Use \Drupal\Tests\taxonomy\Functional\TaxonomyTranslationTestTrait */ trait TaxonomyTranslationTestTrait { @@ -73,32 +78,28 @@ protected function enableTranslation() { /** * Adds term reference field for the article content type. - * - * @param bool $translatable - * (optional) If TRUE, create a translatable term reference field. Defaults - * to FALSE. */ protected function setUpTermReferenceField() { - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $this->termFieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); $field_storage = FieldStorageConfig::loadByName('node', $this->termFieldName); $field_storage->setTranslatable(FALSE); $field_storage->save(); entity_get_form_display('node', 'article', 'default') - ->setComponent($this->termFieldName, array( + ->setComponent($this->termFieldName, [ 'type' => 'entity_reference_autocomplete_tags', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($this->termFieldName, array( + ->setComponent($this->termFieldName, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } diff --git a/core/modules/taxonomy/src/Tests/TermLanguageTest.php b/core/modules/taxonomy/src/Tests/TermLanguageTest.php deleted file mode 100644 index e894ad2f..00000000 --- a/core/modules/taxonomy/src/Tests/TermLanguageTest.php +++ /dev/null @@ -1,110 +0,0 @@ -drupalLogin($this->drupalCreateUser(['administer taxonomy'])); - - // Create a vocabulary to which the terms will be assigned. - $this->vocabulary = $this->createVocabulary(); - - // Add some custom languages. - foreach (array('aa', 'bb', 'cc') as $language_code) { - ConfigurableLanguage::create(array( - 'id' => $language_code, - 'label' => $this->randomMachineName(), - ))->save(); - } - } - - function testTermLanguage() { - // Configure the vocabulary to not hide the language selector. - $edit = array( - 'default_language[language_alterable]' => TRUE, - ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); - - // Add a term. - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); - // Check that we have the language selector. - $this->assertField('edit-langcode-0-value', t('The language selector field was found on the page.')); - // Submit the term. - $edit = array( - 'name[0][value]' => $this->randomMachineName(), - 'langcode[0][value]' => 'aa', - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']); - $term = reset($terms); - $this->assertEqual($term->language()->getId(), $edit['langcode[0][value]'], 'The term contains the correct langcode.'); - - // Check if on the edit page the language is correct. - $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); - $this->assertOptionSelected('edit-langcode-0-value', $edit['langcode[0][value]'], 'The term language was correctly selected.'); - - // Change the language of the term. - $edit['langcode[0][value]'] = 'bb'; - $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save')); - - // Check again that on the edit page the language is correct. - $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); - $this->assertOptionSelected('edit-langcode-0-value', $edit['langcode[0][value]'], 'The term language was correctly selected.'); - } - - function testDefaultTermLanguage() { - // Configure the vocabulary to not hide the language selector, and make the - // default language of the terms fixed. - $edit = array( - 'default_language[langcode]' => 'bb', - 'default_language[language_alterable]' => TRUE, - ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); - $this->assertOptionSelected('edit-langcode-0-value', 'bb', 'The expected langcode was selected.'); - - // Make the default language of the terms to be the current interface. - $edit = array( - 'default_language[langcode]' => 'current_interface', - 'default_language[language_alterable]' => TRUE, - ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); - $this->drupalGet('aa/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); - $this->assertOptionSelected('edit-langcode-0-value', 'aa', "The expected langcode, 'aa', was selected."); - $this->drupalGet('bb/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); - $this->assertOptionSelected('edit-langcode-0-value', 'bb', "The expected langcode, 'bb', was selected."); - - // Change the default language of the site and check if the default terms - // language is still correctly selected. - $this->config('system.site')->set('default_langcode', 'cc')->save(); - $edit = array( - 'default_language[langcode]' => LanguageInterface::LANGCODE_SITE_DEFAULT, - 'default_language[language_alterable]' => TRUE, - ); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); - $this->assertOptionSelected('edit-langcode-0-value', 'cc', "The expected langcode, 'cc', was selected."); - } - -} diff --git a/core/modules/taxonomy/src/Tests/TermTest.php b/core/modules/taxonomy/src/Tests/TermTest.php index 311ed6b7..42f92b1b 100644 --- a/core/modules/taxonomy/src/Tests/TermTest.php +++ b/core/modules/taxonomy/src/Tests/TermTest.php @@ -52,31 +52,31 @@ protected function setUp() { $field_name = 'taxonomy_' . $this->vocabulary->id(); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); $this->field = FieldConfig::loadByName('node', 'article', $field_name); entity_get_form_display('node', 'article', 'default') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => 'options_select', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } /** * Test terms in a single and multiple hierarchy. */ - function testTaxonomyTermHierarchy() { + public function testTaxonomyTermHierarchy() { // Create two taxonomy terms. $term1 = $this->createTerm($this->vocabulary); $term2 = $this->createTerm($this->vocabulary); @@ -89,8 +89,8 @@ function testTaxonomyTermHierarchy() { $this->assertEqual(0, $vocabulary->getHierarchy(), 'Vocabulary is flat.'); // Edit $term2, setting $term1 as parent. - $edit = array(); - $edit['parent[]'] = array($term1->id()); + $edit = []; + $edit['parent[]'] = [$term1->id()]; $this->drupalPostForm('taxonomy/term/' . $term2->id() . '/edit', $edit, t('Save')); // Check the hierarchy. @@ -107,7 +107,7 @@ function testTaxonomyTermHierarchy() { // Create a third term and save this as a parent of term2. $term3 = $this->createTerm($this->vocabulary); - $term2->parent = array($term1->id(), $term3->id()); + $term2->parent = [$term1->id(), $term3->id()]; $term2->save(); $parents = $taxonomy_storage->loadParents($term2->id()); $this->assertTrue(isset($parents[$term1->id()]) && isset($parents[$term3->id()]), 'Both parents found successfully.'); @@ -116,7 +116,7 @@ function testTaxonomyTermHierarchy() { /** * Tests that many terms with parents show on each page */ - function testTaxonomyTermChildTerms() { + public function testTaxonomyTermChildTerms() { // Set limit to 10 terms per page. Set variable to 9 so 10 terms appear. $this->config('taxonomy.settings')->set('terms_per_page_admin', '9')->save(); $term1 = $this->createTerm($this->vocabulary); @@ -127,7 +127,7 @@ function testTaxonomyTermChildTerms() { // Create 40 terms. Terms 1-12 get parent of $term1. All others are // individual terms. for ($x = 1; $x <= 40; $x++) { - $edit = array(); + $edit = []; // Set terms in order so we know which terms will be on which pages. $edit['weight'] = $x; @@ -149,14 +149,14 @@ function testTaxonomyTermChildTerms() { } // Get Page 2. - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array('query' => array('page' => 1))); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', ['query' => ['page' => 1]]); $this->assertText($term1->getName(), 'Parent Term is displayed on Page 2'); for ($x = 1; $x <= 18; $x++) { $this->assertText($terms_array[$x]->getName(), $terms_array[$x]->getName() . ' found on Page 2'); } // Get Page 3. - $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array('query' => array('page' => 2))); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', ['query' => ['page' => 2]]); $this->assertNoText($term1->getName(), 'Parent Term is not displayed on Page 3'); for ($x = 1; $x <= 17; $x++) { $this->assertNoText($terms_array[$x]->getName(), $terms_array[$x]->getName() . ' not found on Page 3'); @@ -171,13 +171,13 @@ function testTaxonomyTermChildTerms() { * * Save & edit a node and assert that taxonomy terms are saved/loaded properly. */ - function testTaxonomyNode() { + public function testTaxonomyNode() { // Create two taxonomy terms. $term1 = $this->createTerm($this->vocabulary); $term2 = $this->createTerm($this->vocabulary); // Post an article. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(); $edit['body[0][value]'] = $this->randomMachineName(); $edit[$this->field->getName() . '[]'] = $term1->id(); @@ -190,7 +190,7 @@ function testTaxonomyNode() { $this->clickLink(t('Edit')); $this->assertText($term1->getName(), 'Term is displayed when editing the node.'); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertText($term1->getName(), 'Term is displayed after saving the node with no changes.'); // Edit the node with a different term. @@ -210,28 +210,28 @@ function testTaxonomyNode() { /** * Test term creation with a free-tagging vocabulary from the node form. */ - function testNodeTermCreationAndDeletion() { + public function testNodeTermCreationAndDeletion() { // Enable tags in the vocabulary. $field = $this->field; entity_get_form_display($field->getTargetEntityTypeId(), $field->getTargetBundle(), 'default') - ->setComponent($field->getName(), array( + ->setComponent($field->getName(), [ 'type' => 'entity_reference_autocomplete_tags', - 'settings' => array( + 'settings' => [ 'placeholder' => 'Start typing here.', - ), - )) + ], + ]) ->save(); // Prefix the terms with a letter to ensure there is no clash in the first // three letters. // @see https://www.drupal.org/node/2397691 - $terms = array( + $terms = [ 'term1' => 'a' . $this->randomMachineName(), 'term2' => 'b' . $this->randomMachineName(), 'term3' => 'c' . $this->randomMachineName() . ', ' . $this->randomMachineName(), 'term4' => 'd' . $this->randomMachineName(), - ); + ]; - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(); $edit['body[0][value]'] = $this->randomMachineName(); // Insert the terms in a comma separated list. Vocabulary 1 is a @@ -255,10 +255,10 @@ function testNodeTermCreationAndDeletion() { // Save, creating the terms. $this->drupalPostForm('node/add/article', $edit, t('Save')); - $this->assertText(t('@type @title has been created.', array('@type' => t('Article'), '@title' => $edit['title[0][value]'])), 'The node was created successfully.'); + $this->assertText(t('@type @title has been created.', ['@type' => t('Article'), '@title' => $edit['title[0][value]']]), 'The node was created successfully.'); // Verify that the creation message contains a link to a node. - $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'node/')); + $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']); $this->assert(isset($view_link), 'The message area contains a link to a node'); foreach ($terms as $term) { @@ -266,7 +266,7 @@ function testNodeTermCreationAndDeletion() { } // Get the created terms. - $term_objects = array(); + $term_objects = []; foreach ($terms as $key => $term) { $term_objects[$key] = taxonomy_term_load_multiple_by_name($term); $term_objects[$key] = reset($term_objects[$key]); @@ -288,30 +288,30 @@ function testNodeTermCreationAndDeletion() { // Delete term 2 from the term delete page. $this->drupalGet('taxonomy/term/' . $term_objects['term2']->id() . '/delete'); - $this->drupalPostForm(NULL, array(), t('Delete')); - $term_names = array($term_objects['term3']->getName(), $term_objects['term4']->getName()); + $this->drupalPostForm(NULL, [], t('Delete')); + $term_names = [$term_objects['term3']->getName(), $term_objects['term4']->getName()]; $this->drupalGet('node/' . $node->id()); foreach ($term_names as $term_name) { - $this->assertText($term_name, format_string('The term %name appears on the node page after two terms, %deleted1 and %deleted2, were deleted.', array('%name' => $term_name, '%deleted1' => $term_objects['term1']->getName(), '%deleted2' => $term_objects['term2']->getName()))); + $this->assertText($term_name, format_string('The term %name appears on the node page after two terms, %deleted1 and %deleted2, were deleted.', ['%name' => $term_name, '%deleted1' => $term_objects['term1']->getName(), '%deleted2' => $term_objects['term2']->getName()])); } - $this->assertNoText($term_objects['term1']->getName(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->getName()))); - $this->assertNoText($term_objects['term2']->getName(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term2']->getName()))); + $this->assertNoText($term_objects['term1']->getName(), format_string('The deleted term %name does not appear on the node page.', ['%name' => $term_objects['term1']->getName()])); + $this->assertNoText($term_objects['term2']->getName(), format_string('The deleted term %name does not appear on the node page.', ['%name' => $term_objects['term2']->getName()])); } /** * Save, edit and delete a term using the user interface. */ - function testTermInterface() { - \Drupal::service('module_installer')->install(array('views')); - $edit = array( + public function testTermInterface() { + \Drupal::service('module_installer')->install(['views']); + $edit = [ 'name[0][value]' => $this->randomMachineName(12), 'description[0][value]' => $this->randomMachineName(100), - ); + ]; // Explicitly set the parents field to 'root', to ensure that // TermForm::save() handles the invalid term ID correctly. - $edit['parent[]'] = array(0); + $edit['parent[]'] = [0]; // Create the term to edit. $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add', $edit, t('Save')); @@ -328,10 +328,10 @@ function testTermInterface() { $this->assertRaw($edit['name[0][value]'], 'The randomly generated term name is present.'); $this->assertText($edit['description[0][value]'], 'The randomly generated term description is present.'); - $edit = array( + $edit = [ 'name[0][value]' => $this->randomMachineName(14), 'description[0][value]' => $this->randomMachineName(102), - ); + ]; // Edit the term. $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save')); @@ -380,7 +380,7 @@ function testTermInterface() { /** * Save, edit and delete a term using the user interface. */ - function testTermReorder() { + public function testTermReorder() { $this->createTerm($this->vocabulary); $this->createTerm($this->vocabulary); $this->createTerm($this->vocabulary); @@ -398,7 +398,7 @@ function testTermReorder() { // "tid:1:0[depth]", and "tid:1:0[weight]". Change the order to term2, // term3, term1 by setting weight property, make term3 a child of term2 by // setting the parent and depth properties, and update all hidden fields. - $edit = array( + $edit = [ 'terms[tid:' . $term2->id() . ':0][term][tid]' => $term2->id(), 'terms[tid:' . $term2->id() . ':0][term][parent]' => 0, 'terms[tid:' . $term2->id() . ':0][term][depth]' => 0, @@ -411,18 +411,18 @@ function testTermReorder() { 'terms[tid:' . $term1->id() . ':0][term][parent]' => 0, 'terms[tid:' . $term1->id() . ':0][term][depth]' => 0, 'terms[tid:' . $term1->id() . ':0][weight]' => 2, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); $taxonomy_storage->resetCache(); $terms = $taxonomy_storage->loadTree($this->vocabulary->id()); $this->assertEqual($terms[0]->tid, $term2->id(), 'Term 2 was moved above term 1.'); - $this->assertEqual($terms[1]->parents, array($term2->id()), 'Term 3 was made a child of term 2.'); + $this->assertEqual($terms[1]->parents, [$term2->id()], 'Term 3 was made a child of term 2.'); $this->assertEqual($terms[2]->tid, $term1->id(), 'Term 1 was moved below term 2.'); - $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array(), t('Reset to alphabetical')); + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', [], t('Reset to alphabetical')); // Submit confirmation form. - $this->drupalPostForm(NULL, array(), t('Reset to alphabetical')); + $this->drupalPostForm(NULL, [], t('Reset to alphabetical')); // Ensure form redirected back to overview. $this->assertUrl('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); @@ -431,22 +431,22 @@ function testTermReorder() { $this->assertEqual($terms[0]->id(), $term1->id(), 'Term 1 was moved to back above term 2.'); $this->assertEqual($terms[1]->id(), $term2->id(), 'Term 2 was moved to back below term 1.'); $this->assertEqual($terms[2]->id(), $term3->id(), 'Term 3 is still below term 2.'); - $this->assertEqual($terms[2]->parents, array($term2->id()), 'Term 3 is still a child of term 2.'); + $this->assertEqual($terms[2]->parents, [$term2->id()], 'Term 3 is still a child of term 2.'); } /** * Test saving a term with multiple parents through the UI. */ - function testTermMultipleParentsInterface() { + public function testTermMultipleParentsInterface() { // Add a new term to the vocabulary so that we can have multiple parents. $parent = $this->createTerm($this->vocabulary); // Add a new term with multiple parents. - $edit = array( + $edit = [ 'name[0][value]' => $this->randomMachineName(12), 'description[0][value]' => $this->randomMachineName(100), - 'parent[]' => array(0, $parent->id()), - ); + 'parent[]' => [0, $parent->id()], + ]; // Save the new term. $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add', $edit, t('Save')); @@ -466,7 +466,7 @@ function testTermMultipleParentsInterface() { /** * Test taxonomy_term_load_multiple_by_name(). */ - function testTaxonomyGetTermByName() { + public function testTaxonomyGetTermByName() { $term = $this->createTerm($this->vocabulary); // Load the term with the exact name. @@ -526,18 +526,18 @@ function testTaxonomyGetTermByName() { /** * Tests that editing and saving a node with no changes works correctly. */ - function testReSavingTags() { + public function testReSavingTags() { // Enable tags in the vocabulary. $field = $this->field; entity_get_form_display($field->getTargetEntityTypeId(), $field->getTargetBundle(), 'default') - ->setComponent($field->getName(), array( + ->setComponent($field->getName(), [ 'type' => 'entity_reference_autocomplete_tags', - )) + ]) ->save(); // Create a term and a node using it. $term = $this->createTerm($this->vocabulary); - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(8); $edit['body[0][value]'] = $this->randomMachineName(16); $edit[$this->field->getName() . '[target_id]'] = $term->getName(); @@ -547,7 +547,7 @@ function testReSavingTags() { // changes. $this->clickLink(t('Edit')); $this->assertRaw($term->getName(), 'Term is displayed when editing the node.'); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertRaw($term->getName(), 'Term is displayed after saving the node with no changes.'); } diff --git a/core/modules/taxonomy/src/Tests/TermTranslationTest.php b/core/modules/taxonomy/src/Tests/TermTranslationTest.php index 91b13b15..ccb16f61 100644 --- a/core/modules/taxonomy/src/Tests/TermTranslationTest.php +++ b/core/modules/taxonomy/src/Tests/TermTranslationTest.php @@ -20,23 +20,23 @@ class TermTranslationTest extends TaxonomyTestBase { * * @var array */ - protected $termTranslationMap = array( + protected $termTranslationMap = [ 'one' => 'translatedOne', 'two' => 'translatedTwo', 'three' => 'translatedThree', - ); + ]; /** * Created terms. * * @var \Drupal\taxonomy\Entity\Term[] */ - protected $terms = array(); + protected $terms = []; /** * {@inheritdoc} */ - public static $modules = array('taxonomy', 'language', 'content_translation'); + public static $modules = ['taxonomy', 'language', 'content_translation']; /** * {@inheritdoc} @@ -55,7 +55,7 @@ protected function setUp() { */ public function testTranslatedBreadcrumbs() { // Ensure non-translated breadcrumb is correct. - $breadcrumb = array(Url::fromRoute('')->toString() => 'Home'); + $breadcrumb = [Url::fromRoute('')->toString() => 'Home']; foreach ($this->terms as $term) { $breadcrumb[$term->url()] = $term->label(); } @@ -69,7 +69,7 @@ public function testTranslatedBreadcrumbs() { $languages = \Drupal::languageManager()->getLanguages(); // Construct the expected translated breadcrumb. - $breadcrumb = array(Url::fromRoute('', [], ['language' => $languages[$this->translateToLangcode]])->toString() => 'Home'); + $breadcrumb = [Url::fromRoute('', [], ['language' => $languages[$this->translateToLangcode]])->toString() => 'Home']; foreach ($this->terms as $term) { $translated = $term->getTranslation($this->translateToLangcode); $url = $translated->url('canonical', ['language' => $languages[$this->translateToLangcode]]); @@ -87,14 +87,14 @@ public function testTranslatedBreadcrumbs() { /** * Test translation of terms are showed in the node. */ - protected function testTermsTranslation() { + public function testTermsTranslation() { // Set the display of the term reference field on the article content type // to "Check boxes/radio buttons". entity_get_form_display('node', 'article', 'default') - ->setComponent($this->termFieldName, array( + ->setComponent($this->termFieldName, [ 'type' => 'options_buttons', - )) + ]) ->save(); $this->drupalLogin($this->drupalCreateUser(['create article content'])); @@ -118,15 +118,15 @@ protected function setUpTerms() { $parent_vid = 0; foreach ($this->termTranslationMap as $name => $translation) { - $term = $this->createTerm($this->vocabulary, array( + $term = $this->createTerm($this->vocabulary, [ 'name' => $name, 'langcode' => $this->baseLangcode, 'parent' => $parent_vid, - )); + ]); - $term->addTranslation($this->translateToLangcode, array( + $term->addTranslation($this->translateToLangcode, [ 'name' => $translation, - )); + ]); $term->save(); // Each term is nested under the last. diff --git a/core/modules/taxonomy/src/Tests/Views/RelationshipRepresentativeNodeTest.php b/core/modules/taxonomy/src/Tests/Views/RelationshipRepresentativeNodeTest.php deleted file mode 100644 index d049f822..00000000 --- a/core/modules/taxonomy/src/Tests/Views/RelationshipRepresentativeNodeTest.php +++ /dev/null @@ -1,41 +0,0 @@ -executeView($view); - $map = array('node_field_data_taxonomy_term_field_data_nid' => 'nid', 'tid' => 'tid'); - $expected_result = array( - array( - 'nid' => $this->nodes[1]->id(), - 'tid' => $this->term2->id(), - ), - array( - 'nid' => $this->nodes[1]->id(), - 'tid' => $this->term1->id(), - ), - ); - $this->assertIdenticalResultset($view, $expected_result, $map); - } - -} diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyParentUITest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyParentUITest.php deleted file mode 100644 index c79a406c..00000000 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyParentUITest.php +++ /dev/null @@ -1,47 +0,0 @@ -drupalGet('admin/structure/views/nojs/handler/test_taxonomy_parent/default/relationship/parent'); - $this->assertNoText('The handler for this item is broken or missing.'); - } - -} diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php deleted file mode 100644 index dc575599..00000000 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTestBase.php +++ /dev/null @@ -1,155 +0,0 @@ -mockStandardInstall(); - - if ($import_test_views) { - ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views')); - } - - $this->term1 = $this->createTerm(); - $this->term2 = $this->createTerm(); - - $node = array(); - $node['type'] = 'article'; - $node['field_views_testing_tags'][]['target_id'] = $this->term1->id(); - $node['field_views_testing_tags'][]['target_id'] = $this->term2->id(); - $this->nodes[] = $this->drupalCreateNode($node); - $this->nodes[] = $this->drupalCreateNode($node); - } - - /** - * Provides a workaround for the inability to use the standard profile. - * - * @see https://www.drupal.org/node/1708692 - */ - protected function mockStandardInstall() { - $this->drupalCreateContentType(array( - 'type' => 'article', - )); - // Create the vocabulary for the tag field. - $this->vocabulary = Vocabulary::create([ - 'name' => 'Views testing tags', - 'vid' => 'views_testing_tags', - ]); - $this->vocabulary->save(); - $field_name = 'field_' . $this->vocabulary->id(); - - $handler_settings = array( - 'target_bundles' => array( - $this->vocabulary->id() => $this->vocabulary->id(), - ), - 'auto_create' => TRUE, - ); - $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - - entity_get_form_display('node', 'article', 'default') - ->setComponent($field_name, array( - 'type' => 'entity_reference_autocomplete_tags', - 'weight' => -4, - )) - ->save(); - - entity_get_display('node', 'article', 'default') - ->setComponent($field_name, array( - 'type' => 'entity_reference_label', - 'weight' => 10, - )) - ->save(); - entity_get_display('node', 'article', 'teaser') - ->setComponent($field_name, array( - 'type' => 'entity_reference_label', - 'weight' => 10, - )) - ->save(); - } - - /** - * Creates and returns a taxonomy term. - * - * @param array $settings - * (optional) An array of values to override the following default - * properties of the term: - * - name: A random string. - * - description: A random string. - * - format: First available text format. - * - vid: Vocabulary ID of self::$vocabulary object. - * - langcode: LANGCODE_NOT_SPECIFIED. - * Defaults to an empty array. - * - * @return \Drupal\taxonomy\Entity\Term - * The created taxonomy term. - */ - protected function createTerm(array $settings = []) { - $filter_formats = filter_formats(); - $format = array_pop($filter_formats); - $settings += [ - 'name' => $this->randomMachineName(), - 'description' => $this->randomMachineName(), - // Use the first available text format. - 'format' => $format->id(), - 'vid' => $this->vocabulary->id(), - 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - ]; - $term = Term::create($settings); - $term->save(); - return $term; - } - -} diff --git a/core/modules/taxonomy/src/Tests/VocabularyTranslationTest.php b/core/modules/taxonomy/src/Tests/VocabularyTranslationTest.php deleted file mode 100644 index 7ad76099..00000000 --- a/core/modules/taxonomy/src/Tests/VocabularyTranslationTest.php +++ /dev/null @@ -1,55 +0,0 @@ -drupalLogin($this->drupalCreateUser([ - 'administer taxonomy', - 'administer content translation', - ])); - } - - /** - * Tests language settings for vocabularies. - */ - function testVocabularyLanguage() { - $this->drupalGet('admin/structure/taxonomy/add'); - - // Check that the field to enable content translation is available. - $this->assertField('edit-default-language-content-translation', 'The content translation checkbox is present on the page.'); - - // Create the vocabulary. - $vid = Unicode::strtolower($this->randomMachineName()); - $edit['name'] = $this->randomMachineName(); - $edit['description'] = $this->randomMachineName(); - $edit['langcode'] = 'en'; - $edit['vid'] = $vid; - $edit['default_language[content_translation]'] = TRUE; - $this->drupalPostForm(NULL, $edit, t('Save')); - - // Check if content translation is enabled on the edit page. - $this->drupalGet('admin/structure/taxonomy/manage/' . $vid); - $this->assertFieldChecked('edit-default-language-content-translation', 'The content translation was correctly selected.'); - } - -} diff --git a/core/modules/taxonomy/src/VocabularyForm.php b/core/modules/taxonomy/src/VocabularyForm.php index 1868ddc3..63f0ccb8 100644 --- a/core/modules/taxonomy/src/VocabularyForm.php +++ b/core/modules/taxonomy/src/VocabularyForm.php @@ -52,59 +52,59 @@ public function form(array $form, FormStateInterface $form_state) { $form['#title'] = $this->t('Edit vocabulary'); } - $form['name'] = array( + $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Name'), '#default_value' => $vocabulary->label(), '#maxlength' => 255, '#required' => TRUE, - ); - $form['vid'] = array( + ]; + $form['vid'] = [ '#type' => 'machine_name', '#default_value' => $vocabulary->id(), '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH, - '#machine_name' => array( - 'exists' => array($this, 'exists'), - 'source' => array('name'), - ), - ); - $form['description'] = array( + '#machine_name' => [ + 'exists' => [$this, 'exists'], + 'source' => ['name'], + ], + ]; + $form['description'] = [ '#type' => 'textfield', '#title' => $this->t('Description'), '#default_value' => $vocabulary->getDescription(), - ); + ]; // $form['langcode'] is not wrapped in an // if ($this->moduleHandler->moduleExists('language')) check because the // language_select form element works also without the language module being // installed. https://www.drupal.org/node/1749954 documents the new element. - $form['langcode'] = array( + $form['langcode'] = [ '#type' => 'language_select', '#title' => $this->t('Vocabulary language'), '#languages' => LanguageInterface::STATE_ALL, '#default_value' => $vocabulary->language()->getId(), - ); + ]; if ($this->moduleHandler->moduleExists('language')) { - $form['default_terms_language'] = array( + $form['default_terms_language'] = [ '#type' => 'details', '#title' => $this->t('Terms language'), '#open' => TRUE, - ); - $form['default_terms_language']['default_language'] = array( + ]; + $form['default_terms_language']['default_language'] = [ '#type' => 'language_configuration', - '#entity_information' => array( + '#entity_information' => [ 'entity_type' => 'taxonomy_term', 'bundle' => $vocabulary->id(), - ), + ], '#default_value' => ContentLanguageSettings::loadByEntityTypeBundle('taxonomy_term', $vocabulary->id()), - ); + ]; } // Set the hierarchy to "multiple parents" by default. This simplifies the // vocabulary form and standardizes the term form. - $form['hierarchy'] = array( + $form['hierarchy'] = [ '#type' => 'value', '#value' => '0', - ); + ]; $form = parent::form($form, $form_state); return $this->protectBundleIdElement($form); @@ -123,14 +123,14 @@ public function save(array $form, FormStateInterface $form_state) { $edit_link = $this->entity->link($this->t('Edit')); switch ($status) { case SAVED_NEW: - drupal_set_message($this->t('Created new vocabulary %name.', array('%name' => $vocabulary->label()))); - $this->logger('taxonomy')->notice('Created new vocabulary %name.', array('%name' => $vocabulary->label(), 'link' => $edit_link)); + drupal_set_message($this->t('Created new vocabulary %name.', ['%name' => $vocabulary->label()])); + $this->logger('taxonomy')->notice('Created new vocabulary %name.', ['%name' => $vocabulary->label(), 'link' => $edit_link]); $form_state->setRedirectUrl($vocabulary->urlInfo('overview-form')); break; case SAVED_UPDATED: - drupal_set_message($this->t('Updated vocabulary %name.', array('%name' => $vocabulary->label()))); - $this->logger('taxonomy')->notice('Updated vocabulary %name.', array('%name' => $vocabulary->label(), 'link' => $edit_link)); + drupal_set_message($this->t('Updated vocabulary %name.', ['%name' => $vocabulary->label()])); + $this->logger('taxonomy')->notice('Updated vocabulary %name.', ['%name' => $vocabulary->label(), 'link' => $edit_link]); $form_state->setRedirectUrl($vocabulary->urlInfo('collection')); break; } diff --git a/core/modules/taxonomy/src/VocabularyListBuilder.php b/core/modules/taxonomy/src/VocabularyListBuilder.php index b5597bb2..8503c288 100644 --- a/core/modules/taxonomy/src/VocabularyListBuilder.php +++ b/core/modules/taxonomy/src/VocabularyListBuilder.php @@ -36,16 +36,16 @@ public function getDefaultOperations(EntityInterface $entity) { $operations['edit']['title'] = t('Edit vocabulary'); } - $operations['list'] = array( + $operations['list'] = [ 'title' => t('List terms'), 'weight' => 0, 'url' => $entity->urlInfo('overview-form'), - ); - $operations['add'] = array( + ]; + $operations['add'] = [ 'title' => t('Add terms'), 'weight' => 10, 'url' => Url::fromRoute('entity.taxonomy_term.add_form', ['taxonomy_vocabulary' => $entity->id()]), - ); + ]; unset($operations['delete']); return $operations; @@ -56,6 +56,7 @@ public function getDefaultOperations(EntityInterface $entity) { */ public function buildHeader() { $header['label'] = t('Vocabulary name'); + $header['description'] = t('Description'); return $header + parent::buildHeader(); } @@ -64,6 +65,7 @@ public function buildHeader() { */ public function buildRow(EntityInterface $entity) { $row['label'] = $entity->label(); + $row['description']['data'] = ['#markup' => $entity->getDescription()]; return $row + parent::buildRow($entity); } @@ -78,7 +80,7 @@ public function render() { unset($this->weightKey); } $build = parent::render(); - $build['table']['#empty'] = t('No vocabularies available. Add vocabulary.', array(':link' => \Drupal::url('entity.taxonomy_vocabulary.add_form'))); + $build['table']['#empty'] = t('No vocabularies available. Add vocabulary.', [':link' => \Drupal::url('entity.taxonomy_vocabulary.add_form')]); return $build; } @@ -87,7 +89,7 @@ public function render() { */ public function buildForm(array $form, FormStateInterface $form_state) { $form = parent::buildForm($form, $form_state); - $form['vocabularies']['#attributes'] = array('id' => 'taxonomy'); + $form['vocabularies']['#attributes'] = ['id' => 'taxonomy']; $form['actions']['submit']['#value'] = t('Save'); return $form; diff --git a/core/modules/taxonomy/src/VocabularyStorage.php b/core/modules/taxonomy/src/VocabularyStorage.php index 4b08b293..bdbf8938 100644 --- a/core/modules/taxonomy/src/VocabularyStorage.php +++ b/core/modules/taxonomy/src/VocabularyStorage.php @@ -21,7 +21,7 @@ public function resetCache(array $ids = NULL) { * {@inheritdoc} */ public function getToplevelTids($vids) { - return db_query('SELECT t.tid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} th ON th.tid = t.tid WHERE t.vid IN ( :vids[] ) AND th.parent = 0', array(':vids[]' => $vids))->fetchCol(); + return db_query('SELECT t.tid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} th ON th.tid = t.tid WHERE t.vid IN ( :vids[] ) AND th.parent = 0', [':vids[]' => $vids])->fetchCol(); } } diff --git a/core/modules/taxonomy/taxonomy.es6.js b/core/modules/taxonomy/taxonomy.es6.js new file mode 100644 index 00000000..ad597290 --- /dev/null +++ b/core/modules/taxonomy/taxonomy.es6.js @@ -0,0 +1,52 @@ +/** + * @file + * Taxonomy behaviors. + */ + +(function ($, Drupal) { + /** + * Move a block in the blocks table from one region to another. + * + * This behavior is dependent on the tableDrag behavior, since it uses the + * objects initialized in that behavior to update the row. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the drag behavior to a applicable table element. + */ + Drupal.behaviors.termDrag = { + attach(context, settings) { + const backStep = settings.taxonomy.backStep; + const forwardStep = settings.taxonomy.forwardStep; + // Get the blocks tableDrag object. + const tableDrag = Drupal.tableDrag.taxonomy; + const $table = $('#taxonomy'); + const rows = $table.find('tr').length; + + // When a row is swapped, keep previous and next page classes set. + tableDrag.row.prototype.onSwap = function (swappedRow) { + $table.find('tr.taxonomy-term-preview').removeClass('taxonomy-term-preview'); + $table.find('tr.taxonomy-term-divider-top').removeClass('taxonomy-term-divider-top'); + $table.find('tr.taxonomy-term-divider-bottom').removeClass('taxonomy-term-divider-bottom'); + + const tableBody = $table[0].tBodies[0]; + if (backStep) { + for (let n = 0; n < backStep; n++) { + $(tableBody.rows[n]).addClass('taxonomy-term-preview'); + } + $(tableBody.rows[backStep - 1]).addClass('taxonomy-term-divider-top'); + $(tableBody.rows[backStep]).addClass('taxonomy-term-divider-bottom'); + } + + if (forwardStep) { + for (let k = rows - forwardStep - 1; k < rows - 1; k++) { + $(tableBody.rows[k]).addClass('taxonomy-term-preview'); + } + $(tableBody.rows[rows - forwardStep - 2]).addClass('taxonomy-term-divider-top'); + $(tableBody.rows[rows - forwardStep - 1]).addClass('taxonomy-term-divider-bottom'); + } + }; + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/taxonomy/taxonomy.info.yml b/core/modules/taxonomy/taxonomy.info.yml index 2370b13c..bc83d8bd 100644 --- a/core/modules/taxonomy/taxonomy.info.yml +++ b/core/modules/taxonomy/taxonomy.info.yml @@ -9,8 +9,8 @@ dependencies: - text configure: entity.taxonomy_vocabulary.collection -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/taxonomy.js b/core/modules/taxonomy/taxonomy.js index 99338d5a..b15e5d14 100644 --- a/core/modules/taxonomy/taxonomy.js +++ b/core/modules/taxonomy/taxonomy.js @@ -1,33 +1,20 @@ /** - * @file - * Taxonomy behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Move a block in the blocks table from one region to another. - * - * This behavior is dependent on the tableDrag behavior, since it uses the - * objects initialized in that behavior to update the row. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the drag behavior to a applicable table element. - */ Drupal.behaviors.termDrag = { - attach: function (context, settings) { + attach: function attach(context, settings) { var backStep = settings.taxonomy.backStep; var forwardStep = settings.taxonomy.forwardStep; - // Get the blocks tableDrag object. + var tableDrag = Drupal.tableDrag.taxonomy; var $table = $('#taxonomy'); var rows = $table.find('tr').length; - // When a row is swapped, keep previous and next page classes set. tableDrag.row.prototype.onSwap = function (swappedRow) { $table.find('tr.taxonomy-term-preview').removeClass('taxonomy-term-preview'); $table.find('tr.taxonomy-term-divider-top').removeClass('taxonomy-term-divider-top'); @@ -52,5 +39,4 @@ }; } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 80884329..e17346ba 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -22,6 +22,8 @@ use Drupal\taxonomy\VocabularyInterface; * * @deprecated in Drupal 8.2.x and will be removed before 9.0.0. Use * \Drupal\taxonomy\VocabularyInterface::HIERARCHY_DISABLED instead. + * + * @see https://www.drupal.org/node/2807795 */ const TAXONOMY_HIERARCHY_DISABLED = 0; @@ -30,6 +32,8 @@ const TAXONOMY_HIERARCHY_DISABLED = 0; * * @deprecated in Drupal 8.2.x and will be removed before 9.0.0. Use * \Drupal\taxonomy\VocabularyInterface::HIERARCHY_SINGLE instead. + * + * @see https://www.drupal.org/node/2807795 */ const TAXONOMY_HIERARCHY_SINGLE = 1; @@ -38,6 +42,8 @@ const TAXONOMY_HIERARCHY_SINGLE = 1; * * @deprecated in Drupal 8.2.x and will be removed before 9.0.0. Use * \Drupal\taxonomy\VocabularyInterface::HIERARCHY_MULTIPLE instead. + * + * @see https://www.drupal.org/node/2807795 */ const TAXONOMY_HIERARCHY_MULTIPLE = 2; @@ -47,23 +53,23 @@ const TAXONOMY_HIERARCHY_MULTIPLE = 2; function taxonomy_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.taxonomy': - $field_ui_url = \Drupal::moduleHandler()->moduleExists('field_ui') ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#'; + $field_ui_url = \Drupal::moduleHandler()->moduleExists('field_ui') ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#'; $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the Administer vocabularies and terms permission can add vocabularies that contain a set of related terms. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.', array(':permissions' => \Drupal::url('user.admin_permissions', array(), array('fragment' => 'module-taxonomy')))) . '

    '; - $output .= '

    ' . t('For more information, see the online documentation for the Taxonomy module.', array(':taxonomy' => 'https://www.drupal.org/documentation/modules/taxonomy/')) . '

    '; + $output .= '

    ' . t('The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the Administer vocabularies and terms permission can add vocabularies that contain a set of related terms. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.', [':permissions' => \Drupal::url('user.admin_permissions', [], ['fragment' => 'module-taxonomy'])]) . '

    '; + $output .= '

    ' . t('For more information, see the online documentation for the Taxonomy module.', [':taxonomy' => 'https://www.drupal.org/documentation/modules/taxonomy/']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Managing vocabularies') . '
    '; - $output .= '
    ' . t('Users who have the Administer vocabularies and terms permission can add and edit vocabularies from the Taxonomy administration page. Vocabularies can be deleted from their Edit vocabulary page. Users with the Taxonomy term: Administer fields permission may add additional fields for terms in that vocabulary using the Field UI module.', array(':taxonomy_admin' => \Drupal::url('entity.taxonomy_vocabulary.collection'), ':field_ui' => $field_ui_url)) . '
    '; + $output .= '
    ' . t('Users who have the Administer vocabularies and terms permission can add and edit vocabularies from the Taxonomy administration page. Vocabularies can be deleted from their Edit vocabulary page. Users with the Taxonomy term: Administer fields permission may add additional fields for terms in that vocabulary using the Field UI module.', [':taxonomy_admin' => \Drupal::url('entity.taxonomy_vocabulary.collection'), ':field_ui' => $field_ui_url]) . '
    '; $output .= '
    ' . t('Managing terms') . '
    '; - $output .= '
    ' . t('Users who have the Administer vocabularies and terms permission or the Edit terms permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the Taxonomy administration page and clicking List terms in the Operations column. Users must have the Administer vocabularies and terms permission or the Delete terms permission for a particular vocabulary to delete terms.', array(':taxonomy_admin' => \Drupal::url('entity.taxonomy_vocabulary.collection'))) . '
    '; + $output .= '
    ' . t('Users who have the Administer vocabularies and terms permission or the Edit terms permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the Taxonomy administration page and clicking List terms in the Operations column. Users must have the Administer vocabularies and terms permission or the Delete terms permission for a particular vocabulary to delete terms.', [':taxonomy_admin' => \Drupal::url('entity.taxonomy_vocabulary.collection')]) . '
    '; $output .= '
    ' . t('Classifying entity content') . '
    '; - $output .= '
    ' . t('A user with the Administer fields permission for a certain entity type may add Taxonomy term reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the Entity Reference help for more information about reference fields. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them.', array(':field_ui' => $field_ui_url, ':field' => \Drupal::url('help.page', array('name' => 'field')), ':entity_reference' => \Drupal::url('help.page', array('name' => 'entity_reference')))) . '
    '; + $output .= '
    ' . t('A user with the Administer fields permission for a certain entity type may add Taxonomy term reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the Entity Reference help for more information about reference fields. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them.', [':field_ui' => $field_ui_url, ':field' => \Drupal::url('help.page', ['name' => 'field']), ':entity_reference' => \Drupal::url('help.page', ['name' => 'entity_reference'])]) . '
    '; $output .= '
    ' . t('Adding new terms during content creation') . '
    '; - $output .= '
    ' . t('Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if either of the two Autocomplete widgets is chosen for the Taxonomy term reference field in the Manage form display page for the field. You will also need to enable the Create referenced entities if they don\'t already exist option, and restrict the field to one vocabulary.') . '
    '; + $output .= '
    ' . t("Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if either of the two Autocomplete widgets is chosen for the Taxonomy term reference field in the Manage form display page for the field. You will also need to enable the Create referenced entities if they don't already exist option, and restrict the field to one vocabulary.") . '
    '; $output .= '
    ' . t('Configuring displays and form displays') . '
    '; - $output .= '
    ' . t('See the Entity Reference help page for the field widgets and formatters that can be configured for any reference field on the Manage display and Manage form display pages. Taxonomy additionally provides an RSS category formatter that displays nothing when the entity item is displayed as HTML, but displays an RSS category instead of a list when the entity item is displayed in an RSS feed.', array(':entity_reference' => \Drupal::url('help.page', array('name' => 'entity_reference')))) . ''; + $output .= '
    ' . t('See the Entity Reference help page for the field widgets and formatters that can be configured for any reference field on the Manage display and Manage form display pages. Taxonomy additionally provides an RSS category formatter that displays nothing when the entity item is displayed as HTML, but displays an RSS category instead of a list when the entity item is displayed in an RSS feed.', [':entity_reference' => \Drupal::url('help.page', ['name' => 'entity_reference'])]) . ''; $output .= ''; $output .= '
    '; $output .= '
    '; @@ -77,11 +83,11 @@ function taxonomy_help($route_name, RouteMatchInterface $route_match) { $vocabulary = $route_match->getParameter('taxonomy_vocabulary'); switch ($vocabulary->getHierarchy()) { case VocabularyInterface::HIERARCHY_DISABLED: - return '

    ' . t('You can reorganize the terms in %capital_name using their drag-and-drop handles, and group terms under a parent term by sliding them under and to the right of the parent.', array('%capital_name' => Unicode::ucfirst($vocabulary->label()), '%name' => $vocabulary->label())) . '

    '; + return '

    ' . t('You can reorganize the terms in %capital_name using their drag-and-drop handles, and group terms under a parent term by sliding them under and to the right of the parent.', ['%capital_name' => Unicode::ucfirst($vocabulary->label()), '%name' => $vocabulary->label()]) . '

    '; case VocabularyInterface::HIERARCHY_SINGLE: - return '

    ' . t('%capital_name contains terms grouped under parent terms. You can reorganize the terms in %capital_name using their drag-and-drop handles.', array('%capital_name' => Unicode::ucfirst($vocabulary->label()), '%name' => $vocabulary->label())) . '

    '; + return '

    ' . t('%capital_name contains terms grouped under parent terms. You can reorganize the terms in %capital_name using their drag-and-drop handles.', ['%capital_name' => Unicode::ucfirst($vocabulary->label()), '%name' => $vocabulary->label()]) . '

    '; case VocabularyInterface::HIERARCHY_MULTIPLE: - return '

    ' . t('%capital_name contains terms with multiple parents. Drag and drop of terms with multiple parents is not supported, but you can re-enable drag-and-drop support by editing each term to include only a single parent.', array('%capital_name' => Unicode::ucfirst($vocabulary->label()))) . '

    '; + return '

    ' . t('%capital_name contains terms with multiple parents. Drag and drop of terms with multiple parents is not supported, but you can re-enable drag-and-drop support by editing each term to include only a single parent.', ['%capital_name' => Unicode::ucfirst($vocabulary->label())]) . '

    '; } } } @@ -90,9 +96,9 @@ function taxonomy_help($route_name, RouteMatchInterface $route_match) { * Entity URI callback. */ function taxonomy_term_uri($term) { - return new Url('entity.taxonomy_term.canonical', array( + return new Url('entity.taxonomy_term.canonical', [ 'taxonomy_term' => $term->id(), - )); + ]); } /** @@ -103,24 +109,24 @@ function taxonomy_page_attachments_alter(array &$page) { if ($route_match->getRouteName() == 'entity.taxonomy_term.canonical' && ($term = $route_match->getParameter('taxonomy_term')) && $term instanceof TermInterface) { foreach ($term->uriRelationships() as $rel) { // Set the URI relationships, like canonical. - $page['#attached']['html_head_link'][] = array( - array( + $page['#attached']['html_head_link'][] = [ + [ 'rel' => $rel, 'href' => $term->url($rel), - ), + ], TRUE, - ); + ]; // Set the term path as the canonical URL to prevent duplicate content. if ($rel == 'canonical') { // Set the non-aliased canonical path as a default shortlink. - $page['#attached']['html_head_link'][] = array( - array( + $page['#attached']['html_head_link'][] = [ + [ 'rel' => 'shortlink', - 'href' => $term->url($rel, array('alias' => TRUE)), - ), + 'href' => $term->url($rel, ['alias' => TRUE]), + ], TRUE, - ); + ]; } } } @@ -130,11 +136,11 @@ function taxonomy_page_attachments_alter(array &$page) { * Implements hook_theme(). */ function taxonomy_theme() { - return array( - 'taxonomy_term' => array( + return [ + 'taxonomy_term' => [ 'render element' => 'elements', - ), - ); + ], + ]; } /** @@ -223,7 +229,7 @@ function taxonomy_term_view_multiple(array $terms, $view_mode = 'full', $langcod * Implements hook_theme_suggestions_HOOK(). */ function taxonomy_theme_suggestions_taxonomy_term(array $variables) { - $suggestions = array(); + $suggestions = []; /** @var \Drupal\taxonomy\TermInterface $term */ $term = $variables['elements']['#taxonomy_term']; @@ -261,7 +267,7 @@ function template_preprocess_taxonomy_term(&$variables) { $variables['page'] = $variables['view_mode'] == 'full' && taxonomy_term_is_page($term); // Helpful $content variable for templates. - $variables['content'] = array(); + $variables['content'] = []; foreach (Element::children($variables['elements']) as $key) { $variables['content'][$key] = $variables['elements'][$key]; } @@ -307,7 +313,7 @@ function taxonomy_vocabulary_get_names() { $names = &drupal_static(__FUNCTION__); if (!isset($names)) { - $names = array(); + $names = []; $config_names = \Drupal::configFactory()->listAll('taxonomy.vocabulary.'); foreach ($config_names as $config_name) { $id = substr($config_name, strlen('taxonomy.vocabulary.')); @@ -333,7 +339,7 @@ function taxonomy_vocabulary_get_names() { * An array of matching term objects. */ function taxonomy_term_load_multiple_by_name($name, $vocabulary = NULL) { - $values = array('name' => trim($name)); + $values = ['name' => trim($name)]; if (isset($vocabulary)) { $vocabularies = taxonomy_vocabulary_get_names(); if (isset($vocabularies[$vocabulary])) { @@ -341,7 +347,7 @@ function taxonomy_term_load_multiple_by_name($name, $vocabulary = NULL) { } else { // Return an empty array when filtering by a non-existing vocabulary. - return array(); + return []; } } return entity_load_multiple_by_properties('taxonomy_term', $values); @@ -436,7 +442,7 @@ function taxonomy_term_load($tid) { * @see \Drupal\Component\Utility\Tags::explode() */ function taxonomy_implode_tags($tags, $vid = NULL) { - $typed_tags = array(); + $typed_tags = []; foreach ($tags as $tag) { // Extract terms belonging to the vocabulary in question. if (!isset($vid) || $tag->bundle() == $vid) { @@ -510,7 +516,7 @@ function taxonomy_build_node_index($node) { // We only maintain the taxonomy index for published nodes. if ($status && $node->isDefaultRevision()) { // Collect a unique list of all the term IDs from all node fields. - $tid_all = array(); + $tid_all = []; $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; foreach ($node->getFieldDefinitions() as $field) { $field_name = $field->getName(); @@ -530,8 +536,8 @@ function taxonomy_build_node_index($node) { if (!empty($tid_all)) { foreach ($tid_all as $tid) { db_merge('taxonomy_index') - ->key(array('nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished())) - ->fields(array('sticky' => $sticky, 'created' => $node->getCreatedTime())) + ->key(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) ->execute(); } } diff --git a/core/modules/taxonomy/taxonomy.tokens.inc b/core/modules/taxonomy/taxonomy.tokens.inc index 20251f22..211a1214 100644 --- a/core/modules/taxonomy/taxonomy.tokens.inc +++ b/core/modules/taxonomy/taxonomy.tokens.inc @@ -12,80 +12,80 @@ use Drupal\taxonomy\Entity\Vocabulary; * Implements hook_token_info(). */ function taxonomy_token_info() { - $types['term'] = array( + $types['term'] = [ 'name' => t("Taxonomy terms"), 'description' => t("Tokens related to taxonomy terms."), 'needs-data' => 'term', - ); - $types['vocabulary'] = array( + ]; + $types['vocabulary'] = [ 'name' => t("Vocabularies"), 'description' => t("Tokens related to taxonomy vocabularies."), 'needs-data' => 'vocabulary', - ); + ]; // Taxonomy term related variables. - $term['tid'] = array( + $term['tid'] = [ 'name' => t("Term ID"), 'description' => t("The unique ID of the taxonomy term."), - ); - $term['name'] = array( + ]; + $term['name'] = [ 'name' => t("Name"), 'description' => t("The name of the taxonomy term."), - ); - $term['description'] = array( + ]; + $term['description'] = [ 'name' => t("Description"), 'description' => t("The optional description of the taxonomy term."), - ); - $term['node-count'] = array( + ]; + $term['node-count'] = [ 'name' => t("Node count"), 'description' => t("The number of nodes tagged with the taxonomy term."), - ); - $term['url'] = array( + ]; + $term['url'] = [ 'name' => t("URL"), 'description' => t("The URL of the taxonomy term."), - ); + ]; // Taxonomy vocabulary related variables. - $vocabulary['vid'] = array( + $vocabulary['vid'] = [ 'name' => t("Vocabulary ID"), 'description' => t("The unique ID of the taxonomy vocabulary."), - ); - $vocabulary['name'] = array( + ]; + $vocabulary['name'] = [ 'name' => t("Name"), 'description' => t("The name of the taxonomy vocabulary."), - ); - $vocabulary['description'] = array( + ]; + $vocabulary['description'] = [ 'name' => t("Description"), 'description' => t("The optional description of the taxonomy vocabulary."), - ); - $vocabulary['node-count'] = array( + ]; + $vocabulary['node-count'] = [ 'name' => t("Node count"), 'description' => t("The number of nodes tagged with terms belonging to the taxonomy vocabulary."), - ); - $vocabulary['term-count'] = array( + ]; + $vocabulary['term-count'] = [ 'name' => t("Term count"), 'description' => t("The number of terms belonging to the taxonomy vocabulary."), - ); + ]; // Chained tokens for taxonomies - $term['vocabulary'] = array( + $term['vocabulary'] = [ 'name' => t("Vocabulary"), 'description' => t("The vocabulary the taxonomy term belongs to."), 'type' => 'vocabulary', - ); - $term['parent'] = array( + ]; + $term['parent'] = [ 'name' => t("Parent term"), 'description' => t("The parent term of the taxonomy term, if one exists."), 'type' => 'term', - ); + ]; - return array( + return [ 'types' => $types, - 'tokens' => array( + 'tokens' => [ 'term' => $term, 'vocabulary' => $vocabulary, - ), - ); + ], + ]; } /** @@ -94,7 +94,7 @@ function taxonomy_token_info() { function taxonomy_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) { $token_service = \Drupal::token(); - $replacements = array(); + $replacements = []; $taxonomy_storage = \Drupal::entityManager()->getStorage('taxonomy_term'); if ($type == 'term' && !empty($data['term'])) { $term = $data['term']; @@ -116,7 +116,7 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable break; case 'url': - $replacements[$original] = $term->url('canonical', array('absolute' => TRUE)); + $replacements[$original] = $term->url('canonical', ['absolute' => TRUE]); break; case 'node-count': @@ -145,12 +145,12 @@ function taxonomy_tokens($type, $tokens, array $data, array $options, Bubbleable if ($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'vocabulary')) { $vocabulary = Vocabulary::load($term->bundle()); - $replacements += $token_service->generate('vocabulary', $vocabulary_tokens, array('vocabulary' => $vocabulary), $options, $bubbleable_metadata); + $replacements += $token_service->generate('vocabulary', $vocabulary_tokens, ['vocabulary' => $vocabulary], $options, $bubbleable_metadata); } if (($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = $taxonomy_storage->loadParents($term->id())) { $parent = array_pop($parents); - $replacements += $token_service->generate('term', $vocabulary_tokens, array('term' => $parent), $options, $bubbleable_metadata); + $replacements += $token_service->generate('term', $vocabulary_tokens, ['term' => $parent], $options, $bubbleable_metadata); } } diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc index 5360d508..1eedbbe7 100644 --- a/core/modules/taxonomy/taxonomy.views.inc +++ b/core/modules/taxonomy/taxonomy.views.inc @@ -11,44 +11,44 @@ use Drupal\field\FieldStorageConfigInterface; * Implements hook_views_data_alter(). */ function taxonomy_views_data_alter(&$data) { - $data['node_field_data']['term_node_tid'] = array( + $data['node_field_data']['term_node_tid'] = [ 'title' => t('Taxonomy terms on node'), 'help' => t('Relate nodes to taxonomy terms, specifying which vocabulary or vocabularies to use. This relationship will cause duplicated records if there are multiple terms.'), - 'relationship' => array( + 'relationship' => [ 'id' => 'node_term_data', 'label' => t('term'), 'base' => 'taxonomy_term_field_data', - ), - 'field' => array( + ], + 'field' => [ 'title' => t('All taxonomy terms'), 'help' => t('Display all taxonomy terms associated with a node from specified vocabularies.'), 'id' => 'taxonomy_index_tid', 'no group by' => TRUE, 'click sortable' => FALSE, - ), - ); + ], + ]; - $data['node_field_data']['term_node_tid_depth'] = array( + $data['node_field_data']['term_node_tid_depth'] = [ 'help' => t('Display content if it has the selected taxonomy terms, or children of the selected terms. Due to additional complexity, this has fewer options than the versions without depth.'), 'real field' => 'nid', - 'argument' => array( + 'argument' => [ 'title' => t('Has taxonomy term ID (with depth)'), 'id' => 'taxonomy_index_tid_depth', 'accept depth modifier' => TRUE, - ), - 'filter' => array( + ], + 'filter' => [ 'title' => t('Has taxonomy terms (with depth)'), 'id' => 'taxonomy_index_tid_depth', - ), - ); + ], + ]; - $data['node_field_data']['term_node_tid_depth_modifier'] = array( + $data['node_field_data']['term_node_tid_depth_modifier'] = [ 'title' => t('Has taxonomy term ID depth modifier'), 'help' => t('Allows the "depth" for Taxonomy: Term ID (with depth) to be modified via an additional contextual filter value.'), - 'argument' => array( + 'argument' => [ 'id' => 'taxonomy_index_tid_depth_modifier', - ), - ); + ], + ]; } /** diff --git a/core/modules/taxonomy/tests/modules/taxonomy_crud/taxonomy_crud.info.yml b/core/modules/taxonomy/tests/modules/taxonomy_crud/taxonomy_crud.info.yml index da26b7fb..84491bdb 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_crud/taxonomy_crud.info.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_crud/taxonomy_crud.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - taxonomy -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/migrations/taxonomy_term_stub_test.yml b/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/migrations/taxonomy_term_stub_test.yml index ad56fff0..4c3cd867 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/migrations/taxonomy_term_stub_test.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/migrations/taxonomy_term_stub_test.yml @@ -19,7 +19,7 @@ process: name: name weight: weight parent: - plugin: migration + plugin: migration_lookup migration: taxonomy_term_stub_test source: parent destination: diff --git a/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/taxonomy_term_stub_test.info.yml b/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/taxonomy_term_stub_test.info.yml index cc4de74c..3e4f9f6c 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/taxonomy_term_stub_test.info.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_term_stub_test/taxonomy_term_stub_test.info.yml @@ -8,8 +8,8 @@ dependencies: - taxonomy - migrate -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test/taxonomy_test.info.yml b/core/modules/taxonomy/tests/modules/taxonomy_test/taxonomy_test.info.yml index 31af8820..0ad2c4c3 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_test/taxonomy_test.info.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_test/taxonomy_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - taxonomy -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.info.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.info.yml index 87762b4c..2fd3752d 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.info.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.info.yml @@ -8,8 +8,8 @@ dependencies: - taxonomy - views -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_vocabulary.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_vocabulary.yml new file mode 100644 index 00000000..a90e618f --- /dev/null +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_argument_taxonomy_vocabulary.yml @@ -0,0 +1,174 @@ +langcode: en +status: true +dependencies: + module: + - taxonomy + - user +id: test_argument_taxonomy_vocabulary +label: test_argument_taxonomy_vocabulary +module: views +description: '' +tag: '' +base_table: taxonomy_term_field_data +base_field: tid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: none + options: + offset: 0 + style: + type: default + row: + type: 'entity:taxonomy_term' + fields: + name: + id: name + table: taxonomy_term_field_data + field: name + entity_type: taxonomy_term + entity_field: name + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + type: string + settings: + link_to_entity: true + plugin_id: term_name + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + convert_spaces: false + filters: { } + sorts: { } + title: '' + header: { } + footer: { } + empty: { } + relationships: { } + arguments: + vid: + id: vid + table: taxonomy_term_field_data + field: vid + relationship: none + group_type: group + admin_label: '' + default_action: ignore + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: fixed + default_argument_options: + argument: '' + default_argument_skip_url: false + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + not: false + entity_type: taxonomy_term + entity_field: vid + plugin_id: vocabulary_vid + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - user.permissions + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: test_argument_taxonomy_vocabulary + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - user.permissions + tags: { } + diff --git a/core/modules/taxonomy/tests/modules/vocabulary_serialization_test/vocabulary_serialization_test.info.yml b/core/modules/taxonomy/tests/modules/vocabulary_serialization_test/vocabulary_serialization_test.info.yml index 567bc371..827a5453 100644 --- a/core/modules/taxonomy/tests/modules/vocabulary_serialization_test/vocabulary_serialization_test.info.yml +++ b/core/modules/taxonomy/tests/modules/vocabulary_serialization_test/vocabulary_serialization_test.info.yml @@ -6,8 +6,8 @@ package: Testing dependencies: - taxonomy -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/taxonomy/src/Tests/EfqTest.php b/core/modules/taxonomy/tests/src/Functional/EfqTest.php similarity index 88% rename from core/modules/taxonomy/src/Tests/EfqTest.php rename to core/modules/taxonomy/tests/src/Functional/EfqTest.php index 572ae8f8..e78d9ec9 100644 --- a/core/modules/taxonomy/src/Tests/EfqTest.php +++ b/core/modules/taxonomy/tests/src/Functional/EfqTest.php @@ -1,6 +1,6 @@ createTerm($this->vocabulary); $terms[$term->id()] = $term; @@ -35,17 +35,17 @@ function testTaxonomyEfq() { sort($result); $this->assertEqual(array_keys($terms), $result, 'Taxonomy terms were retrieved by entity query.'); $tid = reset($result); - $ids = (object) array( + $ids = (object) [ 'entity_type' => 'taxonomy_term', 'entity_id' => $tid, 'bundle' => $this->vocabulary->id(), - ); + ]; $term = _field_create_entity_from_ids($ids); $this->assertEqual($term->id(), $tid, 'Taxonomy term can be created based on the IDs.'); // Create a second vocabulary and five more terms. $vocabulary2 = $this->createVocabulary(); - $terms2 = array(); + $terms2 = []; for ($i = 0; $i < 5; $i++) { $term = $this->createTerm($vocabulary2); $terms2[$term->id()] = $term; @@ -55,13 +55,13 @@ function testTaxonomyEfq() { ->condition('vid', $vocabulary2->id()) ->execute(); sort($result); - $this->assertEqual(array_keys($terms2), $result, format_string('Taxonomy terms from the %name vocabulary were retrieved by entity query.', array('%name' => $vocabulary2->label()))); + $this->assertEqual(array_keys($terms2), $result, format_string('Taxonomy terms from the %name vocabulary were retrieved by entity query.', ['%name' => $vocabulary2->label()])); $tid = reset($result); - $ids = (object) array( + $ids = (object) [ 'entity_type' => 'taxonomy_term', 'entity_id' => $tid, 'bundle' => $vocabulary2->id(), - ); + ]; $term = _field_create_entity_from_ids($ids); $this->assertEqual($term->id(), $tid, 'Taxonomy term can be created based on the IDs.'); } diff --git a/core/modules/taxonomy/src/Tests/LegacyTest.php b/core/modules/taxonomy/tests/src/Functional/LegacyTest.php similarity index 82% rename from core/modules/taxonomy/src/Tests/LegacyTest.php rename to core/modules/taxonomy/tests/src/Functional/LegacyTest.php index b8422263..667ed554 100644 --- a/core/modules/taxonomy/src/Tests/LegacyTest.php +++ b/core/modules/taxonomy/tests/src/Functional/LegacyTest.php @@ -1,10 +1,10 @@ save(); $field_name = 'field_' . $vocabulary->id(); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $vocabulary->id() => $vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => 'entity_reference_autocomplete_tags', - )) + ]) ->save(); $this->drupalLogin($this->drupalCreateUser(['administer taxonomy', 'administer nodes', 'bypass node access'])); @@ -51,16 +51,16 @@ protected function setUp() { /** * Test taxonomy functionality with nodes prior to 1970. */ - function testTaxonomyLegacyNode() { + public function testTaxonomyLegacyNode() { // Posts an article with a taxonomy term and a date prior to 1970. $date = new DrupalDateTime('1969-01-01 00:00:00'); - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(); $edit['created[0][value][date]'] = $date->format('Y-m-d'); $edit['created[0][value][time]'] = $date->format('H:i:s'); $edit['body[0][value]'] = $this->randomMachineName(); $edit['field_tags[target_id]'] = $this->randomMachineName(); - $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); + $this->drupalPostForm('node/add/article', $edit, t('Save')); // Checks that the node has been saved. $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.'); diff --git a/core/modules/taxonomy/src/Tests/LoadMultipleTest.php b/core/modules/taxonomy/tests/src/Functional/LoadMultipleTest.php similarity index 88% rename from core/modules/taxonomy/src/Tests/LoadMultipleTest.php rename to core/modules/taxonomy/tests/src/Functional/LoadMultipleTest.php index 349516c8..186031cc 100644 --- a/core/modules/taxonomy/src/Tests/LoadMultipleTest.php +++ b/core/modules/taxonomy/tests/src/Functional/LoadMultipleTest.php @@ -1,6 +1,6 @@ createVocabulary(); @@ -31,9 +31,9 @@ function testTaxonomyTermMultipleLoad() { $this->createTerm($vocabulary); } // Load the terms from the vocabulary. - $terms = entity_load_multiple_by_properties('taxonomy_term', array('vid' => $vocabulary->id())); + $terms = entity_load_multiple_by_properties('taxonomy_term', ['vid' => $vocabulary->id()]); $count = count($terms); - $this->assertEqual($count, 5, format_string('Correct number of terms were loaded. @count terms.', array('@count' => $count))); + $this->assertEqual($count, 5, format_string('Correct number of terms were loaded. @count terms.', ['@count' => $count])); // Load the same terms again by tid. $terms2 = Term::loadMultiple(array_keys($terms)); @@ -47,13 +47,13 @@ function testTaxonomyTermMultipleLoad() { $this->assertFalse($deleted_term); // Load terms from the vocabulary by vid. - $terms3 = entity_load_multiple_by_properties('taxonomy_term', array('vid' => $vocabulary->id())); + $terms3 = entity_load_multiple_by_properties('taxonomy_term', ['vid' => $vocabulary->id()]); $this->assertEqual(count($terms3), 4, 'Correct number of terms were loaded.'); $this->assertFalse(isset($terms3[$deleted->id()])); // Create a single term and load it by name. $term = $this->createTerm($vocabulary); - $loaded_terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => $term->getName())); + $loaded_terms = entity_load_multiple_by_properties('taxonomy_term', ['name' => $term->getName()]); $this->assertEqual(count($loaded_terms), 1, 'One term was loaded.'); $loaded_term = reset($loaded_terms); $this->assertEqual($term->id(), $loaded_term->id(), 'Term loaded by name successfully.'); diff --git a/core/modules/taxonomy/src/Tests/TaxonomyImageTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyImageTest.php similarity index 75% rename from core/modules/taxonomy/src/Tests/TaxonomyImageTest.php rename to core/modules/taxonomy/tests/src/Functional/TaxonomyImageTest.php index 306e160b..504c0da6 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyImageTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyImageTest.php @@ -1,8 +1,9 @@ vocabulary = $this->createVocabulary(); // Add a field to the vocabulary. $entity_type = 'taxonomy_term'; $name = 'field_test'; - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => $name, 'entity_type' => $entity_type, 'type' => 'image', - 'settings' => array( + 'settings' => [ 'uri_scheme' => 'private', - ), - ))->save(); + ], + ])->save(); FieldConfig::create([ 'field_name' => $name, 'entity_type' => $entity_type, 'bundle' => $this->vocabulary->id(), - 'settings' => array(), + 'settings' => [], ])->save(); entity_get_display($entity_type, $this->vocabulary->id(), 'default') - ->setComponent($name, array( + ->setComponent($name, [ 'type' => 'image', - 'settings' => array(), - )) + 'settings' => [], + ]) ->save(); entity_get_form_display($entity_type, $this->vocabulary->id(), 'default') - ->setComponent($name, array( + ->setComponent($name, [ 'type' => 'image_image', - 'settings' => array(), - )) + 'settings' => [], + ]) ->save(); } public function testTaxonomyImageAccess() { - $user = $this->drupalCreateUser(array('administer site configuration', 'administer taxonomy', 'access user profiles')); + $user = $this->drupalCreateUser(['administer site configuration', 'administer taxonomy', 'access user profiles']); $this->drupalLogin($user); // Create a term and upload the image. @@ -77,12 +83,12 @@ public function testTaxonomyImageAccess() { $edit['files[field_test_0]'] = drupal_realpath($image->uri); $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add', $edit, t('Save')); $this->drupalPostForm(NULL, ['field_test[0][alt]' => $this->randomMachineName()], t('Save')); - $terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => $edit['name[0][value]'])); + $terms = entity_load_multiple_by_properties('taxonomy_term', ['name' => $edit['name[0][value]']]); $term = reset($terms); - $this->assertText(t('Created new term @name.', array('@name' => $term->getName()))); + $this->assertText(t('Created new term @name.', ['@name' => $term->getName()])); // Create a user that should have access to the file and one that doesn't. - $access_user = $this->drupalCreateUser(array('access content')); + $access_user = $this->drupalCreateUser(['access content']); $no_access_user = $this->drupalCreateUser(); $image = File::load($term->field_test->target_id); $this->drupalLogin($access_user); diff --git a/core/modules/taxonomy/src/Tests/TaxonomyQueryAlterTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyQueryAlterTest.php similarity index 96% rename from core/modules/taxonomy/src/Tests/TaxonomyQueryAlterTest.php rename to core/modules/taxonomy/tests/src/Functional/TaxonomyQueryAlterTest.php index 543910b0..85310e9a 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyQueryAlterTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyQueryAlterTest.php @@ -1,15 +1,15 @@ createVocabulary(); - $terms = array(); + $terms = []; for ($i = 0; $i < 5; $i++) { $terms[$i] = $this->createTerm($vocabulary); } diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTermPagerTest.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyTermPagerTest.php similarity index 97% rename from core/modules/taxonomy/src/Tests/TaxonomyTermPagerTest.php rename to core/modules/taxonomy/tests/src/Functional/TaxonomyTermPagerTest.php index f6939883..66782f3e 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTermPagerTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyTermPagerTest.php @@ -1,6 +1,6 @@ drupalPlaceBlock('system_breadcrumb_block'); + + // Create Basic page and Article node types. + if ($this->profile != 'standard') { + $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); + } + } + +} diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php new file mode 100644 index 00000000..db445e96 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyTestTrait.php @@ -0,0 +1,60 @@ + $this->randomMachineName(), + 'description' => $this->randomMachineName(), + 'vid' => Unicode::strtolower($this->randomMachineName()), + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + 'weight' => mt_rand(0, 10), + ]); + $vocabulary->save(); + return $vocabulary; + } + + /** + * Returns a new term with random properties in vocabulary $vid. + * + * @param \Drupal\taxonomy\Entity\Vocabulary $vocabulary + * The vocabulary object. + * @param array $values + * (optional) An array of values to set, keyed by property name. If the + * entity type has bundles, the bundle key has to be specified. + * + * @return \Drupal\taxonomy\Entity\Term + * The new taxonomy term object. + */ + public function createTerm(Vocabulary $vocabulary, $values = []) { + $filter_formats = filter_formats(); + $format = array_pop($filter_formats); + $term = Term::create($values + [ + 'name' => $this->randomMachineName(), + 'description' => [ + 'value' => $this->randomMachineName(), + // Use the first available text format. + 'format' => $format->id(), + ], + 'vid' => $vocabulary->id(), + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ]); + $term->save(); + return $term; + } + +} diff --git a/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php b/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php new file mode 100644 index 00000000..a7fd54b0 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TaxonomyTranslationTestTrait.php @@ -0,0 +1,101 @@ +translateToLangcode)->save(); + $this->rebuildContainer(); + } + + /** + * Enables translations where it needed. + */ + protected function enableTranslation() { + // Enable translation for the current entity type and ensure the change is + // picked up. + \Drupal::service('content_translation.manager')->setEnabled('node', 'article', TRUE); + \Drupal::service('content_translation.manager')->setEnabled('taxonomy_term', $this->vocabulary->id(), TRUE); + drupal_static_reset(); + \Drupal::entityManager()->clearCachedDefinitions(); + \Drupal::service('router.builder')->rebuild(); + \Drupal::service('entity.definition_update_manager')->applyUpdates(); + } + + /** + * Adds term reference field for the article content type. + */ + protected function setUpTermReferenceField() { + $handler_settings = [ + 'target_bundles' => [ + $this->vocabulary->id() => $this->vocabulary->id(), + ], + 'auto_create' => TRUE, + ]; + $this->createEntityReferenceField('node', 'article', $this->termFieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + $field_storage = FieldStorageConfig::loadByName('node', $this->termFieldName); + $field_storage->setTranslatable(FALSE); + $field_storage->save(); + + entity_get_form_display('node', 'article', 'default') + ->setComponent($this->termFieldName, [ + 'type' => 'entity_reference_autocomplete_tags', + ]) + ->save(); + entity_get_display('node', 'article', 'default') + ->setComponent($this->termFieldName, [ + 'type' => 'entity_reference_label', + ]) + ->save(); + } + +} diff --git a/core/modules/taxonomy/src/Tests/TermCacheTagsTest.php b/core/modules/taxonomy/tests/src/Functional/TermCacheTagsTest.php similarity index 89% rename from core/modules/taxonomy/src/Tests/TermCacheTagsTest.php rename to core/modules/taxonomy/tests/src/Functional/TermCacheTagsTest.php index 8d7ddad2..35b7d6bd 100644 --- a/core/modules/taxonomy/src/Tests/TermCacheTagsTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TermCacheTagsTest.php @@ -1,6 +1,6 @@ createVocabulary(); @@ -37,41 +37,41 @@ function testSelectionTestVocabularyRestriction() { // Create an entity reference field. $field_name = 'taxonomy_' . $vocabulary->id(); - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'translatable' => FALSE, - 'settings' => array( + 'settings' => [ 'target_type' => 'taxonomy_term', - ), + ], 'type' => 'entity_reference', 'cardinality' => 1, - )); + ]); $field_storage->save(); - $field = FieldConfig::create(array( + $field = FieldConfig::create([ 'field_storage' => $field_storage, 'entity_type' => 'entity_test', 'bundle' => 'test_bundle', - 'settings' => array( + 'settings' => [ 'handler' => 'default', - 'handler_settings' => array( + 'handler_settings' => [ // Restrict selection of terms to a single vocabulary. - 'target_bundles' => array( + 'target_bundles' => [ $vocabulary->id() => $vocabulary->id(), - ), - ), - ), - )); + ], + ], + ], + ]); $field->save(); $handler = $this->container->get('plugin.manager.entity_reference_selection')->getSelectionHandler($field); $result = $handler->getReferenceableEntities(); - $expected_result = array( - $vocabulary->id() => array( + $expected_result = [ + $vocabulary->id() => [ $term->id() => $term->getName(), - ), - ); + ], + ]; $this->assertIdentical($result, $expected_result, 'Terms selection restricted to a single vocabulary.'); } diff --git a/core/modules/taxonomy/src/Tests/TermIndexTest.php b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php similarity index 81% rename from core/modules/taxonomy/src/Tests/TermIndexTest.php rename to core/modules/taxonomy/tests/src/Functional/TermIndexTest.php index 28e816ce..d4fe8f22 100644 --- a/core/modules/taxonomy/src/Tests/TermIndexTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php @@ -1,6 +1,6 @@ vocabulary = $this->createVocabulary(); $this->fieldName1 = Unicode::strtolower($this->randomMachineName()); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $this->fieldName1, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') - ->setComponent($this->fieldName1, array( + ->setComponent($this->fieldName1, [ 'type' => 'options_select', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($this->fieldName1, array( + ->setComponent($this->fieldName1, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); $this->fieldName2 = Unicode::strtolower($this->randomMachineName()); $this->createEntityReferenceField('node', 'article', $this->fieldName2, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') - ->setComponent($this->fieldName2, array( + ->setComponent($this->fieldName2, [ 'type' => 'options_select', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($this->fieldName2, array( + ->setComponent($this->fieldName2, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } /** * Tests that the taxonomy index is maintained properly. */ - function testTaxonomyIndex() { + public function testTaxonomyIndex() { $node_storage = $this->container->get('entity.manager')->getStorage('node'); // Create terms in the vocabulary. $term_1 = $this->createTerm($this->vocabulary); $term_2 = $this->createTerm($this->vocabulary); // Post an article. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $this->randomMachineName(); $edit['body[0][value]'] = $this->randomMachineName(); $edit["{$this->fieldName1}[]"] = $term_1->id(); @@ -103,10 +103,10 @@ function testTaxonomyIndex() { // Check that the term is indexed, and only once. $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_1->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 1 is indexed once.'); // Update the article to change one term. @@ -114,15 +114,15 @@ function testTaxonomyIndex() { $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Check that both terms are indexed. - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_1->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 1 is indexed.'); - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_2->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 2 is indexed.'); // Update the article to change another term. @@ -130,19 +130,19 @@ function testTaxonomyIndex() { $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Check that only one term is indexed. - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_1->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(0, $index_count, 'Term 1 is not indexed.'); - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_2->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 2 is indexed once.'); // Redo the above tests without interface. - $node_storage->resetCache(array($node->id())); + $node_storage->resetCache([$node->id()]); $node = $node_storage->load($node->id()); $node->title = $this->randomMachineName(); @@ -150,58 +150,58 @@ function testTaxonomyIndex() { $node->save(); // Check that the index was not changed. - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_1->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(0, $index_count, 'Term 1 is not indexed.'); - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_2->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 2 is indexed once.'); // Update the article to change one term. - $node->{$this->fieldName1} = array(array('target_id' => $term_1->id())); + $node->{$this->fieldName1} = [['target_id' => $term_1->id()]]; $node->save(); // Check that both terms are indexed. - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_1->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 1 is indexed.'); - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_2->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 2 is indexed.'); // Update the article to change another term. - $node->{$this->fieldName2} = array(array('target_id' => $term_1->id())); + $node->{$this->fieldName2} = [['target_id' => $term_1->id()]]; $node->save(); // Check that only one term is indexed. - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_1->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(1, $index_count, 'Term 1 is indexed once.'); - $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array( + $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [ ':nid' => $node->id(), ':tid' => $term_2->id(), - ))->fetchField(); + ])->fetchField(); $this->assertEqual(0, $index_count, 'Term 2 is not indexed.'); } /** * Tests that there is a link to the parent term on the child term page. */ - function testTaxonomyTermHierarchyBreadcrumbs() { + public function testTaxonomyTermHierarchyBreadcrumbs() { // Create two taxonomy terms and set term2 as the parent of term1. $term1 = $this->createTerm($this->vocabulary); $term2 = $this->createTerm($this->vocabulary); - $term1->parent = array($term2->id()); + $term1->parent = [$term2->id()]; $term1->save(); // Verify that the page breadcrumbs include a link to the parent term. diff --git a/core/modules/taxonomy/tests/src/Functional/TermLanguageTest.php b/core/modules/taxonomy/tests/src/Functional/TermLanguageTest.php new file mode 100644 index 00000000..f60e77e5 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/TermLanguageTest.php @@ -0,0 +1,143 @@ +drupalLogin($this->drupalCreateUser(['administer taxonomy'])); + + // Create a vocabulary to which the terms will be assigned. + $this->vocabulary = $this->createVocabulary(); + + // Add some custom languages. + foreach (['aa', 'bb', 'cc'] as $language_code) { + ConfigurableLanguage::create([ + 'id' => $language_code, + 'label' => $this->randomMachineName(), + ])->save(); + } + } + + public function testTermLanguage() { + // Configure the vocabulary to not hide the language selector. + $edit = [ + 'default_language[language_alterable]' => TRUE, + ]; + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); + + // Add a term. + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); + // Check that we have the language selector. + $this->assertField('edit-langcode-0-value', t('The language selector field was found on the page.')); + // Submit the term. + $edit = [ + 'name[0][value]' => $this->randomMachineName(), + 'langcode[0][value]' => 'aa', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']); + $term = reset($terms); + $this->assertEqual($term->language()->getId(), $edit['langcode[0][value]'], 'The term contains the correct langcode.'); + + // Check if on the edit page the language is correct. + $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); + $this->assertOptionSelected('edit-langcode-0-value', $edit['langcode[0][value]'], 'The term language was correctly selected.'); + + // Change the language of the term. + $edit['langcode[0][value]'] = 'bb'; + $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save')); + + // Check again that on the edit page the language is correct. + $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); + $this->assertOptionSelected('edit-langcode-0-value', $edit['langcode[0][value]'], 'The term language was correctly selected.'); + } + + public function testDefaultTermLanguage() { + // Configure the vocabulary to not hide the language selector, and make the + // default language of the terms fixed. + $edit = [ + 'default_language[langcode]' => 'bb', + 'default_language[language_alterable]' => TRUE, + ]; + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); + $this->assertOptionSelected('edit-langcode-0-value', 'bb', 'The expected langcode was selected.'); + + // Make the default language of the terms to be the current interface. + $edit = [ + 'default_language[langcode]' => 'current_interface', + 'default_language[language_alterable]' => TRUE, + ]; + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); + $this->drupalGet('aa/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); + $this->assertOptionSelected('edit-langcode-0-value', 'aa', "The expected langcode, 'aa', was selected."); + $this->drupalGet('bb/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); + $this->assertOptionSelected('edit-langcode-0-value', 'bb', "The expected langcode, 'bb', was selected."); + + // Change the default language of the site and check if the default terms + // language is still correctly selected. + $this->config('system.site')->set('default_langcode', 'cc')->save(); + $edit = [ + 'default_language[langcode]' => LanguageInterface::LANGCODE_SITE_DEFAULT, + 'default_language[language_alterable]' => TRUE, + ]; + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); + $this->assertOptionSelected('edit-langcode-0-value', 'cc', "The expected langcode, 'cc', was selected."); + } + + /** + * Tests that translated terms are displayed correctly on the term overview. + */ + public function testTermTranslatedOnOverviewPage() { + // Configure the vocabulary to not hide the language selector. + $edit = [ + 'default_language[language_alterable]' => TRUE, + ]; + $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id(), $edit, t('Save')); + + // Add a term. + $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add'); + // Submit the term. + $edit = [ + 'name[0][value]' => $this->randomMachineName(), + 'langcode[0][value]' => 'aa', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']); + $term = reset($terms); + + // Add a translation for that term. + $translated_title = $this->randomMachineName(); + $term->addTranslation('bb', [ + 'name' => $translated_title, + ]); + $term->save(); + + // Overview page in the other language shows the translated term + $this->drupalGet('bb/admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); + $this->assertPattern('|]*>' . $translated_title . '|', 'The term language is correct'); + } + +} diff --git a/core/modules/taxonomy/src/Tests/TermTranslationFieldViewTest.php b/core/modules/taxonomy/tests/src/Functional/TermTranslationFieldViewTest.php similarity index 81% rename from core/modules/taxonomy/src/Tests/TermTranslationFieldViewTest.php rename to core/modules/taxonomy/tests/src/Functional/TermTranslationFieldViewTest.php index 18cf7208..236ac705 100644 --- a/core/modules/taxonomy/src/Tests/TermTranslationFieldViewTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TermTranslationFieldViewTest.php @@ -1,6 +1,6 @@ $this->randomMachineName(), 'type' => 'article', - 'description' => [[ - 'value' => $this->randomMachineName(), - 'format' => 'basic_html' - ]], - $this->termFieldName => array(array('target_id' => $this->term->id())), + 'description' => [ + [ + 'value' => $this->randomMachineName(), + 'format' => 'basic_html', + ], + ], + $this->termFieldName => [['target_id' => $this->term->id()]], 'langcode' => $this->baseLangcode, ]); $node->save(); @@ -91,14 +93,14 @@ protected function setUpNode() { * Creates a test subject term, with translation. */ protected function setUpTerm() { - $this->term = $this->createTerm($this->vocabulary, array( + $this->term = $this->createTerm($this->vocabulary, [ 'name' => $this->baseTagName, 'langcode' => $this->baseLangcode, - )); + ]); - $this->term->addTranslation($this->translateToLangcode, array( + $this->term->addTranslation($this->translateToLangcode, [ 'name' => $this->translatedTagName, - )); + ]); $this->term->save(); } diff --git a/core/modules/taxonomy/src/Tests/TermTranslationUITest.php b/core/modules/taxonomy/tests/src/Functional/TermTranslationUITest.php similarity index 85% rename from core/modules/taxonomy/src/Tests/TermTranslationUITest.php rename to core/modules/taxonomy/tests/src/Functional/TermTranslationUITest.php index fa9652de..0d24b699 100644 --- a/core/modules/taxonomy/src/Tests/TermTranslationUITest.php +++ b/core/modules/taxonomy/tests/src/Functional/TermTranslationUITest.php @@ -1,8 +1,8 @@ entityTypeId = 'taxonomy_term'; @@ -54,14 +54,14 @@ protected function setupBundle() { * {@inheritdoc} */ protected function getTranslatorPermissions() { - return array_merge(parent::getTranslatorPermissions(), array('administer taxonomy')); + return array_merge(parent::getTranslatorPermissions(), ['administer taxonomy']); } /** * {@inheritdoc} */ protected function getNewEntityValues($langcode) { - return array('name' => $this->randomMachineName()) + parent::getNewEntityValues($langcode); + return ['name' => $this->randomMachineName()] + parent::getNewEntityValues($langcode); } /** @@ -73,7 +73,7 @@ protected function getEditValues($values, $langcode, $new = FALSE) { // To be able to post values for the configurable base fields (name, // description) have to be suffixed with [0][value]. foreach ($edit as $property => $value) { - foreach (array('name', 'description') as $key) { + foreach (['name', 'description'] as $key) { if ($property == $key) { $edit[$key . '[0][value]'] = $value; unset($edit[$property]); @@ -91,7 +91,7 @@ public function testTranslationUI() { // Make sure that no row was inserted for taxonomy vocabularies which do // not have translations enabled. - $rows = db_query('SELECT tid, count(tid) AS count FROM {taxonomy_term_field_data} WHERE vid <> :vid GROUP BY tid', array(':vid' => $this->bundle))->fetchAll(); + $rows = db_query('SELECT tid, count(tid) AS count FROM {taxonomy_term_field_data} WHERE vid <> :vid GROUP BY tid', [':vid' => $this->bundle])->fetchAll(); foreach ($rows as $row) { $this->assertTrue($row->count < 2, 'Term does not have translations.'); } @@ -100,12 +100,12 @@ public function testTranslationUI() { /** * Tests translate link on vocabulary term list. */ - function testTranslateLinkVocabularyAdminPage() { + public function testTranslateLinkVocabularyAdminPage() { $this->drupalLogin($this->drupalCreateUser(array_merge(parent::getTranslatorPermissions(), ['access administration pages', 'administer taxonomy']))); - $values = array( + $values = [ 'name' => $this->randomMachineName(), - ); + ]; $translatable_tid = $this->createEntity($values, $this->langcodes[0], $this->vocabulary->id()); // Create an untranslatable vocabulary. @@ -118,9 +118,9 @@ function testTranslateLinkVocabularyAdminPage() { ]); $untranslatable_vocabulary->save(); - $values = array( + $values = [ 'name' => $this->randomMachineName(), - ); + ]; $untranslatable_tid = $this->createEntity($values, $this->langcodes[0], $untranslatable_vocabulary->id()); // Verify translation links. @@ -148,14 +148,14 @@ protected function doTestTranslationEdit() { foreach ($this->langcodes as $langcode) { // We only want to test the title for non-english translations. if ($langcode != 'en') { - $options = array('language' => $languages[$langcode]); + $options = ['language' => $languages[$langcode]]; $url = $entity->urlInfo('edit-form', $options); $this->drupalGet($url); - $title = t('@title [%language translation]', array( + $title = t('@title [%language translation]', [ '@title' => $entity->getTranslation($langcode)->label(), '%language' => $languages[$langcode]->getName(), - )); + ]); $this->assertRaw($title); } } diff --git a/core/modules/taxonomy/src/Tests/ThemeTest.php b/core/modules/taxonomy/tests/src/Functional/ThemeTest.php similarity index 86% rename from core/modules/taxonomy/src/Tests/ThemeTest.php rename to core/modules/taxonomy/tests/src/Functional/ThemeTest.php index 54ad6e46..43ed72c9 100644 --- a/core/modules/taxonomy/src/Tests/ThemeTest.php +++ b/core/modules/taxonomy/tests/src/Functional/ThemeTest.php @@ -1,6 +1,6 @@ install(array('bartik', 'seven')); + \Drupal::service('theme_handler')->install(['bartik', 'seven']); $this->config('system.theme') ->set('default', 'bartik') ->set('admin', 'seven') @@ -22,14 +22,14 @@ protected function setUp() { // Create and log in as a user who has permission to add and edit taxonomy // terms and view the administrative theme. - $admin_user = $this->drupalCreateUser(array('administer taxonomy', 'view the administration theme')); + $admin_user = $this->drupalCreateUser(['administer taxonomy', 'view the administration theme']); $this->drupalLogin($admin_user); } /** * Test the theme used when adding, viewing and editing taxonomy terms. */ - function testTaxonomyTermThemes() { + public function testTaxonomyTermThemes() { // Adding a term to a vocabulary is considered an administrative action and // should use the administrative theme. $vocabulary = $this->createVocabulary(); diff --git a/core/modules/taxonomy/src/Tests/TokenReplaceTest.php b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php similarity index 77% rename from core/modules/taxonomy/src/Tests/TokenReplaceTest.php rename to core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php index f3c6c5dc..958da3be 100644 --- a/core/modules/taxonomy/src/Tests/TokenReplaceTest.php +++ b/core/modules/taxonomy/tests/src/Functional/TokenReplaceTest.php @@ -1,6 +1,6 @@ vocabulary = $this->createVocabulary(); $this->fieldName = 'taxonomy_' . $this->vocabulary->id(); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $this->fieldName, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'options_select', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($this->fieldName, array( + ->setComponent($this->fieldName, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } /** * Creates some terms and a node, then tests the tokens generated from them. */ - function testTaxonomyTokenReplacement() { + public function testTaxonomyTokenReplacement() { $token_service = \Drupal::token(); $language_interface = \Drupal::languageManager()->getCurrentLanguage(); @@ -65,23 +65,23 @@ function testTaxonomyTokenReplacement() { $term2 = $this->createTerm($this->vocabulary); // Edit $term2, setting $term1 as parent. - $edit = array(); + $edit = []; $edit['name[0][value]'] = 'Blinking Text'; - $edit['parent[]'] = array($term1->id()); + $edit['parent[]'] = [$term1->id()]; $this->drupalPostForm('taxonomy/term/' . $term2->id() . '/edit', $edit, t('Save')); // Create node with term2. - $edit = array(); - $node = $this->drupalCreateNode(array('type' => 'article')); + $edit = []; + $node = $this->drupalCreateNode(['type' => 'article']); $edit[$this->fieldName . '[]'] = $term2->id(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); // Generate and test sanitized tokens for term1. - $tests = array(); + $tests = []; $tests['[term:tid]'] = $term1->id(); $tests['[term:name]'] = $term1->getName(); $tests['[term:description]'] = $term1->description->processed; - $tests['[term:url]'] = $term1->url('canonical', array('absolute' => TRUE)); + $tests['[term:url]'] = $term1->url('canonical', ['absolute' => TRUE]); $tests['[term:node-count]'] = 0; $tests['[term:parent:name]'] = '[term:parent:name]'; $tests['[term:vocabulary:name]'] = $this->vocabulary->label(); @@ -89,7 +89,7 @@ function testTaxonomyTokenReplacement() { $base_bubbleable_metadata = BubbleableMetadata::createFromObject($term1); - $metadata_tests = array(); + $metadata_tests = []; $metadata_tests['[term:tid]'] = $base_bubbleable_metadata; $metadata_tests['[term:name]'] = $base_bubbleable_metadata; $metadata_tests['[term:description]'] = $base_bubbleable_metadata; @@ -102,20 +102,20 @@ function testTaxonomyTokenReplacement() { foreach ($tests as $input => $expected) { $bubbleable_metadata = new BubbleableMetadata(); - $output = $token_service->replace($input, array('term' => $term1), array('langcode' => $language_interface->getId()), $bubbleable_metadata); - $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input))); + $output = $token_service->replace($input, ['term' => $term1], ['langcode' => $language_interface->getId()], $bubbleable_metadata); + $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', ['%token' => $input])); $this->assertEqual($bubbleable_metadata, $metadata_tests[$input]); } // Generate and test sanitized tokens for term2. - $tests = array(); + $tests = []; $tests['[term:tid]'] = $term2->id(); $tests['[term:name]'] = $term2->getName(); $tests['[term:description]'] = $term2->description->processed; - $tests['[term:url]'] = $term2->url('canonical', array('absolute' => TRUE)); + $tests['[term:url]'] = $term2->url('canonical', ['absolute' => TRUE]); $tests['[term:node-count]'] = 1; $tests['[term:parent:name]'] = $term1->getName(); - $tests['[term:parent:url]'] = $term1->url('canonical', array('absolute' => TRUE)); + $tests['[term:parent:url]'] = $term1->url('canonical', ['absolute' => TRUE]); $tests['[term:parent:parent:name]'] = '[term:parent:parent:name]'; $tests['[term:vocabulary:name]'] = $this->vocabulary->label(); @@ -123,12 +123,12 @@ function testTaxonomyTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->getId())); - $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input))); + $output = $token_service->replace($input, ['term' => $term2], ['langcode' => $language_interface->getId()]); + $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', ['%token' => $input])); } // Generate and test sanitized tokens. - $tests = array(); + $tests = []; $tests['[vocabulary:vid]'] = $this->vocabulary->id(); $tests['[vocabulary:name]'] = $this->vocabulary->label(); $tests['[vocabulary:description]'] = $this->vocabulary->getDescription(); @@ -139,8 +139,8 @@ function testTaxonomyTokenReplacement() { $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); foreach ($tests as $input => $expected) { - $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->getId())); - $this->assertEqual($output, $expected, format_string('Sanitized taxonomy vocabulary token %token replaced.', array('%token' => $input))); + $output = $token_service->replace($input, ['vocabulary' => $this->vocabulary], ['langcode' => $language_interface->getId()]); + $this->assertEqual($output, $expected, format_string('Sanitized taxonomy vocabulary token %token replaced.', ['%token' => $input])); } } diff --git a/core/modules/taxonomy/src/Tests/Views/ArgumentValidatorTermTest.php b/core/modules/taxonomy/tests/src/Functional/Views/ArgumentValidatorTermTest.php similarity index 96% rename from core/modules/taxonomy/src/Tests/Views/ArgumentValidatorTermTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/ArgumentValidatorTermTest.php index 1630e0f0..a7ac9b86 100644 --- a/core/modules/taxonomy/src/Tests/Views/ArgumentValidatorTermTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/ArgumentValidatorTermTest.php @@ -1,6 +1,6 @@ assertIdentical($expected, $view->getDependencies()); - $this->executeView($view, array($this->term1->id(), $this->term2->id())); - $expected_result = array( - array( + $this->executeView($view, [$this->term1->id(), $this->term2->id()]); + $expected_result = [ + [ 'nid' => $this->nodes[1]->id(), - ), - array( + ], + [ 'nid' => $this->nodes[0]->id(), - ), - ); - $column_map = array('nid' => 'nid'); + ], + ]; + $column_map = ['nid' => 'nid']; $this->assertIdenticalResultset($view, $expected_result, $column_map); // Change the view to test relation limited by vocabulary. @@ -51,7 +51,7 @@ function testViewsHandlerRelationshipNodeTermData() { // Tests \Drupal\taxonomy\Plugin\views\relationship\NodeTermData::calculateDependencies(). $expected['config'][] = 'taxonomy.vocabulary.views_testing_tags'; $this->assertIdentical($expected, $view->getDependencies()); - $this->executeView($view, array($this->term1->id(), $this->term2->id())); + $this->executeView($view, [$this->term1->id(), $this->term2->id()]); $this->assertIdenticalResultset($view, $expected_result, $column_map); } diff --git a/core/modules/taxonomy/tests/src/Functional/Views/RelationshipRepresentativeNodeTest.php b/core/modules/taxonomy/tests/src/Functional/Views/RelationshipRepresentativeNodeTest.php new file mode 100644 index 00000000..d1de82ef --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/Views/RelationshipRepresentativeNodeTest.php @@ -0,0 +1,41 @@ +executeView($view); + $map = ['node_field_data_taxonomy_term_field_data_nid' => 'nid', 'tid' => 'tid']; + $expected_result = [ + [ + 'nid' => $this->nodes[1]->id(), + 'tid' => $this->term2->id(), + ], + [ + 'nid' => $this->nodes[1]->id(), + 'tid' => $this->term1->id(), + ], + ]; + $this->assertIdenticalResultset($view, $expected_result, $map); + } + +} diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyDefaultArgumentTest.php similarity index 92% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyDefaultArgumentTest.php index c08266f1..82646c03 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyDefaultArgumentTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyDefaultArgumentTest.php @@ -1,6 +1,6 @@ setResponse($response); $view->initHandlers(); - $expected = implode(',', array($this->term1->id(), $this->term2->id())); + $expected = implode(',', [$this->term1->id(), $this->term2->id()]); $this->assertEqual($expected, $view->argument['tid']->getDefaultArgument()); $view->destroy(); } @@ -68,7 +68,7 @@ public function testNodePathWithViewSelection() { $view->setResponse($response); $view->initHandlers(); - $expected = implode(',', array($this->term1->id(), $this->term2->id())); + $expected = implode(',', [$this->term1->id(), $this->term2->id()]); $this->assertEqual($expected, $view->argument['tid']->getDefaultArgument()); } diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldAllTermsTest.php similarity index 81% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldAllTermsTest.php index 4737b989..ad1d67d6 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldAllTermsTest.php @@ -1,6 +1,6 @@ xpath('//a[@href="' . $this->term1->url() . '"]'); $this->assertEqual(count($actual), 2, 'Correct number of taxonomy term1 links'); - $this->assertEqual($actual[0]->__toString(), $this->term1->label()); - $this->assertEqual($actual[1]->__toString(), $this->term1->label()); + $this->assertEqual($actual[0]->getText(), $this->term1->label()); + $this->assertEqual($actual[1]->getText(), $this->term1->label()); $this->assertEscaped($this->term1->label()); $actual = $this->xpath('//a[@href="' . $this->term2->url() . '"]'); $this->assertEqual(count($actual), 2, 'Correct number of taxonomy term2 links'); - $this->assertEqual($actual[0]->__toString(), $this->term2->label()); - $this->assertEqual($actual[1]->__toString(), $this->term2->label()); + $this->assertEqual($actual[0]->getText(), $this->term2->label()); + $this->assertEqual($actual[1]->getText(), $this->term2->label()); } /** @@ -57,7 +57,7 @@ public function testViewsHandlerAllTermsWithTokens() { $this->assertText('The taxonomy term name for the term: ' . $this->term1->getName()); // The machine name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary_vid }} - $this->assertText('The machine name for the vocabulary the term belongs to: ' . $this->term1->getVocabularyId()); + $this->assertText('The machine name for the vocabulary the term belongs to: ' . $this->term1->bundle()); // The name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary }} $vocabulary = Vocabulary::load($this->term1->bundle()); diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldFilterTest.php similarity index 75% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldFilterTest.php index fb0c0df2..1b8bbcaa 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldFilterTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldFilterTest.php @@ -1,11 +1,11 @@ save(); ConfigurableLanguage::createFromLangcode('es')->save(); // Set up term names. - $this->termNames = array( + $this->termNames = [ 'en' => 'Food in Paris', 'es' => 'Comida en Paris', 'fr' => 'Nouriture en Paris', - ); + ]; // Create a vocabulary. $this->vocabulary = Vocabulary::create([ @@ -67,11 +67,11 @@ function setUp() { $this->vocabulary->save(); // Add a translatable field to the vocabulary. - $field = FieldStorageConfig::create(array( + $field = FieldStorageConfig::create([ 'field_name' => 'field_foo', 'entity_type' => 'taxonomy_term', 'type' => 'text', - )); + ]); $field->save(); FieldConfig::create([ 'field_name' => 'field_foo', @@ -81,9 +81,9 @@ function setUp() { ])->save(); // Create term with translations. - $taxonomy = $this->createTermWithProperties(array('name' => $this->termNames['en'], 'langcode' => 'en', 'description' => $this->termNames['en'], 'field_foo' => $this->termNames['en'])); - foreach (array('es', 'fr') as $langcode) { - $translation = $taxonomy->addTranslation($langcode, array('name' => $this->termNames[$langcode])); + $taxonomy = $this->createTermWithProperties(['name' => $this->termNames['en'], 'langcode' => 'en', 'description' => $this->termNames['en'], 'field_foo' => $this->termNames['en']]); + foreach (['es', 'fr'] as $langcode) { + $translation = $taxonomy->addTranslation($langcode, ['name' => $this->termNames[$langcode]]); $translation->description->value = $this->termNames[$langcode]; $translation->field_foo->value = $this->termNames[$langcode]; } @@ -91,7 +91,7 @@ function setUp() { Views::viewsData()->clear(); - ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views')); + ViewTestData::createTestViews(get_class($this), ['taxonomy_test_views']); $this->container->get('router.builder')->rebuild(); } @@ -101,27 +101,27 @@ function setUp() { public function testFilters() { // Test the name filter page, which filters for name contains 'Comida'. // Should show just the Spanish translation, once. - $this->assertPageCounts('test-name-filter', array('es' => 1, 'fr' => 0, 'en' => 0), 'Comida name filter'); + $this->assertPageCounts('test-name-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida name filter'); // Test the description filter page, which filters for description contains // 'Comida'. Should show just the Spanish translation, once. - $this->assertPageCounts('test-desc-filter', array('es' => 1, 'fr' => 0, 'en' => 0), 'Comida description filter'); + $this->assertPageCounts('test-desc-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida description filter'); // Test the field filter page, which filters for field_foo contains // 'Comida'. Should show just the Spanish translation, once. - $this->assertPageCounts('test-field-filter', array('es' => 1, 'fr' => 0, 'en' => 0), 'Comida field filter'); + $this->assertPageCounts('test-field-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida field filter'); // Test the name Paris filter page, which filters for name contains // 'Paris'. Should show each translation once. - $this->assertPageCounts('test-name-paris', array('es' => 1, 'fr' => 1, 'en' => 1), 'Paris name filter'); + $this->assertPageCounts('test-name-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris name filter'); // Test the description Paris page, which filters for description contains // 'Paris'. Should show each translation, once. - $this->assertPageCounts('test-desc-paris', array('es' => 1, 'fr' => 1, 'en' => 1), 'Paris description filter'); + $this->assertPageCounts('test-desc-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris description filter'); // Test the field Paris filter page, which filters for field_foo contains // 'Paris'. Should show each translation once. - $this->assertPageCounts('test-field-paris', array('es' => 1, 'fr' => 1, 'en' => 1), 'Paris field filter'); + $this->assertPageCounts('test-field-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris field filter'); } @@ -163,12 +163,12 @@ protected function createTermWithProperties($properties) { $filter_formats = filter_formats(); $format = array_pop($filter_formats); - $properties += array( + $properties += [ 'name' => $this->randomMachineName(), 'description' => $this->randomMachineName(), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'field_foo' => $this->randomMachineName(), - ); + ]; $term = Term::create([ 'name' => $properties['name'], diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldTidTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldTidTest.php similarity index 83% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyFieldTidTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldTidTest.php index 6480491f..0a44d4cb 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldTidTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyFieldTidTest.php @@ -1,6 +1,6 @@ save(); $this->terms[$term->id()] = $term; - ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views')); + ViewTestData::createTestViews(get_class($this), ['taxonomy_test_views']); } /** diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php similarity index 94% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php index 7dff50a4..4de73705 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php @@ -1,12 +1,12 @@ adminUser = $this->drupalCreateUser(['administer taxonomy', 'administer views']); $this->drupalLogin($this->adminUser); @@ -71,7 +71,7 @@ protected function setUp() { $term->save(); } } - ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views')); + ViewTestData::createTestViews(get_class($this), ['taxonomy_test_views']); Vocabulary::create([ 'vid' => 'empty_vocabulary', @@ -93,10 +93,9 @@ public function testFilterUI() { for ($j = 0; $j <= $i; $j++) { $option = $result[$counter++]; $prefix = $this->terms[$i][$j]->parent->target_id ? '-' : ''; - $attributes = $option->attributes(); - $tid = (string) $attributes->value; + $tid = $option->getAttribute('value'); - $this->assertEqual($prefix . $this->terms[$i][$j]->getName(), (string) $option); + $this->assertEqual($prefix . $this->terms[$i][$j]->getName(), $option->getText()); $this->assertEqual($this->terms[$i][$j]->id(), $tid); } } @@ -108,7 +107,7 @@ public function testFilterUI() { $display['display_options']['filters']['tid']['type'] = 'textfield'; $view->save(); $this->drupalGet('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid'); - $this->assertFieldByXPath('//input[@id="edit-options-value"]'); + $this->assertFieldById('edit-options-value', NULL); // Tests \Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid::calculateDependencies(). $expected = [ diff --git a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyParentUITest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyParentUITest.php new file mode 100644 index 00000000..d8ab8ea1 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyParentUITest.php @@ -0,0 +1,47 @@ +drupalGet('admin/structure/views/nojs/handler/test_taxonomy_parent/default/relationship/parent'); + $this->assertNoText('The handler for this item is broken or missing.'); + } + +} diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyRelationshipTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyRelationshipTest.php similarity index 94% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyRelationshipTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyRelationshipTest.php index bada7fae..03be3e15 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyRelationshipTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyRelationshipTest.php @@ -1,6 +1,6 @@ term1->set('parent', $this->term2->id()); diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermArgumentDepthTest.php similarity index 89% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermArgumentDepthTest.php index 311118df..3505784a 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermArgumentDepthTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermArgumentDepthTest.php @@ -1,6 +1,6 @@ createTerm(['name' => 'First']); diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermFilterDepthTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermFilterDepthTest.php similarity index 96% rename from core/modules/taxonomy/src/Tests/Views/TaxonomyTermFilterDepthTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermFilterDepthTest.php index 10ccad26..4d7a4fdf 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermFilterDepthTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTermFilterDepthTest.php @@ -1,6 +1,6 @@ adminUser = $this->drupalCreateUser(['administer taxonomy', 'bypass node access']); @@ -51,23 +52,23 @@ protected function setUp() { $this->fieldName1 = Unicode::strtolower($this->randomMachineName()); - $handler_settings = array( - 'target_bundles' => array( + $handler_settings = [ + 'target_bundles' => [ $this->vocabulary->id() => $this->vocabulary->id(), - ), + ], 'auto_create' => TRUE, - ); + ]; $this->createEntityReferenceField('node', 'article', $this->fieldName1, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); entity_get_form_display('node', 'article', 'default') - ->setComponent($this->fieldName1, array( + ->setComponent($this->fieldName1, [ 'type' => 'options_select', - )) + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent($this->fieldName1, array( + ->setComponent($this->fieldName1, [ 'type' => 'entity_reference_label', - )) + ]) ->save(); } @@ -79,7 +80,7 @@ public function testTaxonomyTermView() { $term = $this->createTerm(); // Post an article. - $edit = array(); + $edit = []; $edit['title[0][value]'] = $original_title = $this->randomMachineName(); $edit['body[0][value]'] = $this->randomMachineName(); $edit["{$this->fieldName1}[]"] = $term->id(); @@ -90,7 +91,7 @@ public function testTaxonomyTermView() { $this->assertText($term->label()); $this->assertText($node->label()); - \Drupal::service('module_installer')->install(array('language', 'content_translation')); + \Drupal::service('module_installer')->install(['language', 'content_translation']); $language = ConfigurableLanguage::createFromLangcode('ur'); $language->save(); // Enable translation for the article content type and ensure the change is @@ -124,6 +125,12 @@ public function testTaxonomyTermView() { // query anymore. // @see \Drupal\views\Plugin\views\filter\LanguageFilter::query() $node->delete(); + + // We also have to remove the nodes created by the parent ::setUp() method + // if we want to be able to uninstall the Content Translation module. + foreach (Node::loadMultiple() as $node) { + $node->delete(); + } \Drupal::service('module_installer')->uninstall(['content_translation', 'language']); $view = Views::getView('taxonomy_term'); diff --git a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTestBase.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTestBase.php new file mode 100644 index 00000000..a2d8ec14 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyTestBase.php @@ -0,0 +1,155 @@ +mockStandardInstall(); + + if ($import_test_views) { + ViewTestData::createTestViews(get_class($this), ['taxonomy_test_views']); + } + + $this->term1 = $this->createTerm(); + $this->term2 = $this->createTerm(); + + $node = []; + $node['type'] = 'article'; + $node['field_views_testing_tags'][]['target_id'] = $this->term1->id(); + $node['field_views_testing_tags'][]['target_id'] = $this->term2->id(); + $this->nodes[] = $this->drupalCreateNode($node); + $this->nodes[] = $this->drupalCreateNode($node); + } + + /** + * Provides a workaround for the inability to use the standard profile. + * + * @see https://www.drupal.org/node/1708692 + */ + protected function mockStandardInstall() { + $this->drupalCreateContentType([ + 'type' => 'article', + ]); + // Create the vocabulary for the tag field. + $this->vocabulary = Vocabulary::create([ + 'name' => 'Views testing tags', + 'vid' => 'views_testing_tags', + ]); + $this->vocabulary->save(); + $field_name = 'field_' . $this->vocabulary->id(); + + $handler_settings = [ + 'target_bundles' => [ + $this->vocabulary->id() => $this->vocabulary->id(), + ], + 'auto_create' => TRUE, + ]; + $this->createEntityReferenceField('node', 'article', $field_name, 'Tags', 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + + entity_get_form_display('node', 'article', 'default') + ->setComponent($field_name, [ + 'type' => 'entity_reference_autocomplete_tags', + 'weight' => -4, + ]) + ->save(); + + entity_get_display('node', 'article', 'default') + ->setComponent($field_name, [ + 'type' => 'entity_reference_label', + 'weight' => 10, + ]) + ->save(); + entity_get_display('node', 'article', 'teaser') + ->setComponent($field_name, [ + 'type' => 'entity_reference_label', + 'weight' => 10, + ]) + ->save(); + } + + /** + * Creates and returns a taxonomy term. + * + * @param array $settings + * (optional) An array of values to override the following default + * properties of the term: + * - name: A random string. + * - description: A random string. + * - format: First available text format. + * - vid: Vocabulary ID of self::$vocabulary object. + * - langcode: LANGCODE_NOT_SPECIFIED. + * Defaults to an empty array. + * + * @return \Drupal\taxonomy\Entity\Term + * The created taxonomy term. + */ + protected function createTerm(array $settings = []) { + $filter_formats = filter_formats(); + $format = array_pop($filter_formats); + $settings += [ + 'name' => $this->randomMachineName(), + 'description' => $this->randomMachineName(), + // Use the first available text format. + 'format' => $format->id(), + 'vid' => $this->vocabulary->id(), + 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, + ]; + $term = Term::create($settings); + $term->save(); + return $term; + } + +} diff --git a/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyVocabularyArgumentTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyVocabularyArgumentTest.php new file mode 100644 index 00000000..8b1d58cf --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyVocabularyArgumentTest.php @@ -0,0 +1,76 @@ +vocabularies[] = $this->vocabulary; + // Create additional vocabulary. + $vocabulary = Vocabulary::create([ + 'name' => 'Views testing category', + 'vid' => 'views_testing_category', + ]); + $vocabulary->save(); + $this->vocabularies[] = $vocabulary; + + // Create some terms. + $this->terms[0] = $this->createTerm([ + 'name' => 'First', + 'vid' => $this->vocabularies[0]->id(), + ]); + $this->terms[1] = $this->createTerm([ + 'name' => 'Second', + 'vid' => $this->vocabularies[1]->id(), + ]); + } + + /** + * Tests the vocabulary argument handler. + * + * @see Drupal\taxonomy\Plugin\views\argument\VocabularyVid + */ + public function testTermWithVocabularyArgument() { + $this->drupalGet('test_argument_taxonomy_vocabulary/' . $this->vocabularies[0]->id()); + // First term should be present. + $this->assertText($this->terms[0]->label()); + // Second term should not be present. + $this->assertNoText($this->terms[1]->label()); + } + +} diff --git a/core/modules/taxonomy/src/Tests/Views/TermNameFieldTest.php b/core/modules/taxonomy/tests/src/Functional/Views/TermNameFieldTest.php similarity index 92% rename from core/modules/taxonomy/src/Tests/Views/TermNameFieldTest.php rename to core/modules/taxonomy/tests/src/Functional/Views/TermNameFieldTest.php index 2effe722..6fbe0c0b 100644 --- a/core/modules/taxonomy/src/Tests/Views/TermNameFieldTest.php +++ b/core/modules/taxonomy/tests/src/Functional/Views/TermNameFieldTest.php @@ -1,6 +1,6 @@ drupalCreateUser(array('create article content', 'administer taxonomy')); + $admin_user = $this->drupalCreateUser(['create article content', 'administer taxonomy']); $this->drupalLogin($admin_user); $this->vocabulary = $this->createVocabulary(); } @@ -32,7 +32,7 @@ protected function setUp() { /** * Test deleting a taxonomy that contains terms. */ - function testTaxonomyVocabularyDeleteWithTerms() { + public function testTaxonomyVocabularyDeleteWithTerms() { // Delete any existing vocabularies. foreach (Vocabulary::loadMultiple() as $vocabulary) { $vocabulary->delete(); @@ -42,15 +42,15 @@ function testTaxonomyVocabularyDeleteWithTerms() { // Assert that there are no terms left. $this->assertEqual(0, $query->execute(), 'There are no terms remaining.'); - $terms = array(); + $terms = []; for ($i = 0; $i < 5; $i++) { $terms[$i] = $this->createTerm($vocabulary); } // Set up hierarchy. term 2 is a child of 1 and 4 a child of 1 and 2. - $terms[2]->parent = array($terms[1]->id()); + $terms[2]->parent = [$terms[1]->id()]; $terms[2]->save(); - $terms[4]->parent = array($terms[1]->id(), $terms[2]->id()); + $terms[4]->parent = [$terms[1]->id(), $terms[2]->id()]; $terms[4]->save(); // Assert that there are now 5 terms. @@ -65,7 +65,7 @@ function testTaxonomyVocabularyDeleteWithTerms() { /** * Ensure that the vocabulary static reset works correctly. */ - function testTaxonomyVocabularyLoadStaticReset() { + public function testTaxonomyVocabularyLoadStaticReset() { $original_vocabulary = Vocabulary::load($this->vocabulary->id()); $this->assertTrue(is_object($original_vocabulary), 'Vocabulary loaded successfully.'); $this->assertEqual($this->vocabulary->label(), $original_vocabulary->label(), 'Vocabulary loaded successfully.'); @@ -89,7 +89,7 @@ function testTaxonomyVocabularyLoadStaticReset() { /** * Tests for loading multiple vocabularies. */ - function testTaxonomyVocabularyLoadMultiple() { + public function testTaxonomyVocabularyLoadMultiple() { // Delete any existing vocabularies. foreach (Vocabulary::loadMultiple() as $vocabulary) { @@ -119,45 +119,45 @@ function testTaxonomyVocabularyLoadMultiple() { // Fetch the vocabularies with entity_load_multiple(), specifying IDs. // Ensure they are returned in the same order as the original array. - $vocabularies = Vocabulary::loadMultiple(array($vocabulary3->id(), $vocabulary2->id(), $vocabulary1->id())); + $vocabularies = Vocabulary::loadMultiple([$vocabulary3->id(), $vocabulary2->id(), $vocabulary1->id()]); $loaded_order = array_keys($vocabularies); - $expected_order = array($vocabulary3->id(), $vocabulary2->id(), $vocabulary1->id()); + $expected_order = [$vocabulary3->id(), $vocabulary2->id(), $vocabulary1->id()]; $this->assertIdentical($loaded_order, $expected_order); // Test loading vocabularies by their properties. $controller = $this->container->get('entity.manager')->getStorage('taxonomy_vocabulary'); // Fetch vocabulary 1 by name. - $vocabulary = current($controller->loadByProperties(array('name' => $vocabulary1->label()))); + $vocabulary = current($controller->loadByProperties(['name' => $vocabulary1->label()])); $this->assertEqual($vocabulary->id(), $vocabulary1->id(), 'Vocabulary loaded successfully by name.'); // Fetch vocabulary 2 by name and ID. - $vocabulary = current($controller->loadByProperties(array( + $vocabulary = current($controller->loadByProperties([ 'name' => $vocabulary2->label(), 'vid' => $vocabulary2->id(), - ))); + ])); $this->assertEqual($vocabulary->id(), $vocabulary2->id(), 'Vocabulary loaded successfully by name and ID.'); } /** * Test uninstall and reinstall of the taxonomy module. */ - function testUninstallReinstall() { + public function testUninstallReinstall() { // Field storages and fields attached to taxonomy term bundles should be // removed when the module is uninstalled. $field_name = Unicode::strtolower($this->randomMachineName() . '_field_name'); - $storage_definition = array( + $storage_definition = [ 'field_name' => $field_name, 'entity_type' => 'taxonomy_term', 'type' => 'text', 'cardinality' => 4 - ); + ]; FieldStorageConfig::create($storage_definition)->save(); - $field_definition = array( + $field_definition = [ 'field_name' => $field_name, 'entity_type' => 'taxonomy_term', 'bundle' => $this->vocabulary->id(), 'label' => $this->randomMachineName() . '_label', - ); + ]; FieldConfig::create($field_definition)->save(); // Remove the third party setting from the memory copy of the vocabulary. @@ -166,8 +166,8 @@ function testUninstallReinstall() { $this->vocabulary->unsetThirdPartySetting('taxonomy_crud', 'foo'); require_once \Drupal::root() . '/core/includes/install.inc'; - $this->container->get('module_installer')->uninstall(array('taxonomy')); - $this->container->get('module_installer')->install(array('taxonomy')); + $this->container->get('module_installer')->uninstall(['taxonomy']); + $this->container->get('module_installer')->install(['taxonomy']); // Now create a vocabulary with the same name. All fields // connected to this vocabulary name should have been removed when the diff --git a/core/modules/taxonomy/src/Tests/VocabularyLanguageTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php similarity index 93% rename from core/modules/taxonomy/src/Tests/VocabularyLanguageTest.php rename to core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php index 3326e51e..f25df8a1 100644 --- a/core/modules/taxonomy/src/Tests/VocabularyLanguageTest.php +++ b/core/modules/taxonomy/tests/src/Functional/VocabularyLanguageTest.php @@ -1,6 +1,6 @@ drupalLogin($this->drupalCreateUser(['administer taxonomy'])); // Add some custom languages. - ConfigurableLanguage::create(array( + ConfigurableLanguage::create([ 'id' => 'aa', 'label' => $this->randomMachineName(), - ))->save(); + ])->save(); - ConfigurableLanguage::create(array( + ConfigurableLanguage::create([ 'id' => 'bb', 'label' => $this->randomMachineName(), - ))->save(); + ])->save(); } /** * Tests language settings for vocabularies. */ - function testVocabularyLanguage() { + public function testVocabularyLanguage() { $this->drupalGet('admin/structure/taxonomy/add'); // Check that we have the language selector available. @@ -67,15 +67,15 @@ function testVocabularyLanguage() { /** * Tests term language settings for vocabulary terms are saved and updated. */ - function testVocabularyDefaultLanguageForTerms() { + public function testVocabularyDefaultLanguageForTerms() { // Add a new vocabulary and check that the default language settings are for // the terms are saved. - $edit = array( + $edit = [ 'name' => $this->randomMachineName(), 'vid' => Unicode::strtolower($this->randomMachineName()), 'default_language[langcode]' => 'bb', 'default_language[language_alterable]' => TRUE, - ); + ]; $vid = $edit['vid']; $this->drupalPostForm('admin/structure/taxonomy/add', $edit, t('Save')); @@ -93,10 +93,10 @@ function testVocabularyDefaultLanguageForTerms() { $this->assertFieldChecked('edit-default-language-language-alterable', 'Show language selection option is checked.'); // Edit the vocabulary and check that the new settings are updated. - $edit = array( + $edit = [ 'default_language[langcode]' => 'aa', 'default_language[language_alterable]' => FALSE, - ); + ]; $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vid, $edit, t('Save')); // And check again the settings and also the interface. @@ -109,11 +109,11 @@ function testVocabularyDefaultLanguageForTerms() { $this->assertNoFieldChecked('edit-default-language-language-alterable', 'Show language selection option is not checked.'); // Check that language settings are changed after editing vocabulary. - $edit = array( + $edit = [ 'name' => $this->randomMachineName(), 'default_language[langcode]' => 'authors_default', 'default_language[language_alterable]' => FALSE, - ); + ]; $this->drupalPostForm('admin/structure/taxonomy/manage/' . $vid, $edit, t('Save')); // Check that we have the new settings. diff --git a/core/modules/taxonomy/src/Tests/VocabularyPermissionsTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyPermissionsTest.php similarity index 76% rename from core/modules/taxonomy/src/Tests/VocabularyPermissionsTest.php rename to core/modules/taxonomy/tests/src/Functional/VocabularyPermissionsTest.php index 9a5e8c02..3ba8868f 100644 --- a/core/modules/taxonomy/src/Tests/VocabularyPermissionsTest.php +++ b/core/modules/taxonomy/tests/src/Functional/VocabularyPermissionsTest.php @@ -1,6 +1,6 @@ createVocabulary(); // Test as admin user. - $user = $this->drupalCreateUser(array('administer taxonomy')); + $user = $this->drupalCreateUser(['administer taxonomy']); $this->drupalLogin($user); // Visit the main taxonomy administration page. @@ -32,14 +32,14 @@ function testVocabularyPermissionsTaxonomyTerm() { $this->assertField('edit-name-0-value', 'Add taxonomy term form opened successfully.'); // Submit the term. - $edit = array(); + $edit = []; $edit['name[0][value]'] = $this->randomMachineName(); $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('Created new term @name.', array('@name' => $edit['name[0][value]'])), 'Term created successfully.'); + $this->assertText(t('Created new term @name.', ['@name' => $edit['name[0][value]']]), 'Term created successfully.'); // Verify that the creation message contains a link to a term. - $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'term/')); + $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'term/']); $this->assert(isset($view_link), 'The message area contains a link to a term'); $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']); @@ -52,18 +52,18 @@ function testVocabularyPermissionsTaxonomyTerm() { $edit['name[0][value]'] = $this->randomMachineName(); $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('Updated term @name.', array('@name' => $edit['name[0][value]'])), 'Term updated successfully.'); + $this->assertText(t('Updated term @name.', ['@name' => $edit['name[0][value]']]), 'Term updated successfully.'); // Delete the vocabulary. $this->drupalGet('taxonomy/term/' . $term->id() . '/delete'); - $this->assertRaw(t('Are you sure you want to delete the @entity-type %label?', array('@entity-type' => 'taxonomy term', '%label' => $edit['name[0][value]'])), 'Delete taxonomy term form opened successfully.'); + $this->assertRaw(t('Are you sure you want to delete the @entity-type %label?', ['@entity-type' => 'taxonomy term', '%label' => $edit['name[0][value]']]), 'Delete taxonomy term form opened successfully.'); // Confirm deletion. $this->drupalPostForm(NULL, NULL, t('Delete')); - $this->assertRaw(t('Deleted term %name.', array('%name' => $edit['name[0][value]'])), 'Term deleted.'); + $this->assertRaw(t('Deleted term %name.', ['%name' => $edit['name[0][value]']]), 'Term deleted.'); // Test as user with "edit" permissions. - $user = $this->drupalCreateUser(array("edit terms in {$vocabulary->id()}")); + $user = $this->drupalCreateUser(["edit terms in {$vocabulary->id()}"]); $this->drupalLogin($user); // Visit the main taxonomy administration page. @@ -80,10 +80,10 @@ function testVocabularyPermissionsTaxonomyTerm() { $edit['name[0][value]'] = $this->randomMachineName(); $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('Updated term @name.', array('@name' => $edit['name[0][value]'])), 'Term updated successfully.'); + $this->assertText(t('Updated term @name.', ['@name' => $edit['name[0][value]']]), 'Term updated successfully.'); // Verify that the update message contains a link to a term. - $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', array(':href' => 'term/')); + $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'term/']); $this->assert(isset($view_link), 'The message area contains a link to a term'); // Delete the vocabulary. @@ -91,7 +91,7 @@ function testVocabularyPermissionsTaxonomyTerm() { $this->assertResponse(403, 'Delete taxonomy term form open failed.'); // Test as user with "delete" permissions. - $user = $this->drupalCreateUser(array("delete terms in {$vocabulary->id()}")); + $user = $this->drupalCreateUser(["delete terms in {$vocabulary->id()}"]); $this->drupalLogin($user); // Visit the main taxonomy administration page. @@ -107,11 +107,11 @@ function testVocabularyPermissionsTaxonomyTerm() { // Delete the vocabulary. $this->drupalGet('taxonomy/term/' . $term->id() . '/delete'); - $this->assertRaw(t('Are you sure you want to delete the @entity-type %label?', array('@entity-type' => 'taxonomy term', '%label' => $term->getName())), 'Delete taxonomy term form opened successfully.'); + $this->assertRaw(t('Are you sure you want to delete the @entity-type %label?', ['@entity-type' => 'taxonomy term', '%label' => $term->getName()]), 'Delete taxonomy term form opened successfully.'); // Confirm deletion. $this->drupalPostForm(NULL, NULL, t('Delete')); - $this->assertRaw(t('Deleted term %name.', array('%name' => $term->getName())), 'Term deleted.'); + $this->assertRaw(t('Deleted term %name.', ['%name' => $term->getName()]), 'Term deleted.'); // Test as user without proper permissions. $user = $this->drupalCreateUser(); diff --git a/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php new file mode 100644 index 00000000..2d312578 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Functional/VocabularyTranslationTest.php @@ -0,0 +1,55 @@ +drupalLogin($this->drupalCreateUser([ + 'administer taxonomy', + 'administer content translation', + ])); + } + + /** + * Tests language settings for vocabularies. + */ + public function testVocabularyLanguage() { + $this->drupalGet('admin/structure/taxonomy/add'); + + // Check that the field to enable content translation is available. + $this->assertField('edit-default-language-content-translation', 'The content translation checkbox is present on the page.'); + + // Create the vocabulary. + $vid = Unicode::strtolower($this->randomMachineName()); + $edit['name'] = $this->randomMachineName(); + $edit['description'] = $this->randomMachineName(); + $edit['langcode'] = 'en'; + $edit['vid'] = $vid; + $edit['default_language[content_translation]'] = TRUE; + $this->drupalPostForm(NULL, $edit, t('Save')); + + // Check if content translation is enabled on the edit page. + $this->drupalGet('admin/structure/taxonomy/manage/' . $vid); + $this->assertFieldChecked('edit-default-language-content-translation', 'The content translation was correctly selected.'); + } + +} diff --git a/core/modules/taxonomy/src/Tests/VocabularyUiTest.php b/core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php similarity index 80% rename from core/modules/taxonomy/src/Tests/VocabularyUiTest.php rename to core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php index 3066ef07..e39a0d85 100644 --- a/core/modules/taxonomy/src/Tests/VocabularyUiTest.php +++ b/core/modules/taxonomy/tests/src/Functional/VocabularyUiTest.php @@ -1,6 +1,7 @@ drupalGet('admin/structure/taxonomy'); // Create a new vocabulary. $this->clickLink(t('Add vocabulary')); - $edit = array(); + $edit = []; $vid = Unicode::strtolower($this->randomMachineName()); $edit['name'] = $this->randomMachineName(); $edit['description'] = $this->randomMachineName(); $edit['vid'] = $vid; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('Created new vocabulary %name.', array('%name' => $edit['name'])), 'Vocabulary created successfully.'); + $this->assertRaw(t('Created new vocabulary %name.', ['%name' => $edit['name']]), 'Vocabulary created successfully.'); // Edit the vocabulary. $this->drupalGet('admin/structure/taxonomy'); - $this->assertText($edit['name'], 'Vocabulary found in the vocabulary overview listing.'); + $this->assertText($edit['name'], 'Vocabulary name found in the vocabulary overview listing.'); + $this->assertText($edit['description'], 'Vocabulary description found in the vocabulary overview listing.'); $this->assertLinkByHref(Url::fromRoute('entity.taxonomy_term.add_form', ['taxonomy_vocabulary' => $edit['vid']])->toString()); $this->clickLink(t('Edit vocabulary')); - $edit = array(); + $edit = []; $edit['name'] = $this->randomMachineName(); + $edit['description'] = $this->randomMachineName(); $this->drupalPostForm(NULL, $edit, t('Save')); $this->drupalGet('admin/structure/taxonomy'); - $this->assertText($edit['name'], 'Vocabulary found in the vocabulary overview listing.'); + $this->assertText($edit['name'], 'Vocabulary name found in the vocabulary overview listing.'); + $this->assertText($edit['description'], 'Vocabulary description found in the vocabulary overview listing.'); // Try to submit a vocabulary with a duplicate machine name. $edit['vid'] = $vid; @@ -67,28 +71,27 @@ function testVocabularyInterface() { $this->assertText(t('The machine-readable name must contain only lowercase letters, numbers, and underscores.')); // Ensure that vocabulary titles are escaped properly. - $edit = array(); + $edit = []; $edit['name'] = 'Don\'t Panic'; $edit['description'] = $this->randomMachineName(); $edit['vid'] = 'don_t_panic'; $this->drupalPostForm('admin/structure/taxonomy/add', $edit, t('Save')); $site_name = $this->config('system.site')->get('name'); - $this->assertTitle(t('Don\'t Panic | @site-name', array('@site-name' => $site_name)), 'The page title contains the escaped character.'); - $this->assertNoTitle(t('Don't Panic | @site-name', array('@site-name' => $site_name)), 'The page title does not contain an encoded character.'); + $this->assertTitle(t("Don't Panic | @site-name", ['@site-name' => $site_name]), 'The page title contains the escaped character.'); } /** * Changing weights on the vocabulary overview with two or more vocabularies. */ - function testTaxonomyAdminChangingWeights() { + public function testTaxonomyAdminChangingWeights() { // Create some vocabularies. for ($i = 0; $i < 10; $i++) { $this->createVocabulary(); } // Get all vocabularies and change their weights. $vocabularies = Vocabulary::loadMultiple(); - $edit = array(); + $edit = []; foreach ($vocabularies as $key => $vocabulary) { $weight = -$vocabulary->get('weight'); $vocabularies[$key]->set('weight', $weight); @@ -110,7 +113,7 @@ function testTaxonomyAdminChangingWeights() { /** * Test the vocabulary overview with no vocabularies. */ - function testTaxonomyAdminNoVocabularies() { + public function testTaxonomyAdminNoVocabularies() { // Delete all vocabularies. $vocabularies = Vocabulary::loadMultiple(); foreach ($vocabularies as $key => $vocabulary) { @@ -126,13 +129,13 @@ function testTaxonomyAdminNoVocabularies() { /** * Deleting a vocabulary. */ - function testTaxonomyAdminDeletingVocabulary() { + public function testTaxonomyAdminDeletingVocabulary() { // Create a vocabulary. $vid = Unicode::strtolower($this->randomMachineName()); - $edit = array( + $edit = [ 'name' => $this->randomMachineName(), 'vid' => $vid, - ); + ]; $this->drupalPostForm('admin/structure/taxonomy/add', $edit, t('Save')); $this->assertText(t('Created new vocabulary'), 'New vocabulary was created.'); @@ -144,12 +147,12 @@ function testTaxonomyAdminDeletingVocabulary() { // Delete the vocabulary. $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id()); $this->clickLink(t('Delete')); - $this->assertRaw(t('Are you sure you want to delete the vocabulary %name?', array('%name' => $vocabulary->label())), '[confirm deletion] Asks for confirmation.'); + $this->assertRaw(t('Are you sure you want to delete the vocabulary %name?', ['%name' => $vocabulary->label()]), '[confirm deletion] Asks for confirmation.'); $this->assertText(t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'), '[confirm deletion] Inform that all terms will be deleted.'); // Confirm deletion. $this->drupalPostForm(NULL, NULL, t('Delete')); - $this->assertRaw(t('Deleted vocabulary %name.', array('%name' => $vocabulary->label())), 'Vocabulary deleted.'); + $this->assertRaw(t('Deleted vocabulary %name.', ['%name' => $vocabulary->label()]), 'Vocabulary deleted.'); $this->container->get('entity.manager')->getStorage('taxonomy_vocabulary')->resetCache(); $this->assertFalse(Vocabulary::load($vid), 'Vocabulary not found.'); } diff --git a/core/modules/taxonomy/tests/src/Kernel/ForwardRevisionTest.php b/core/modules/taxonomy/tests/src/Kernel/ForwardRevisionTest.php deleted file mode 100644 index abc0846f..00000000 --- a/core/modules/taxonomy/tests/src/Kernel/ForwardRevisionTest.php +++ /dev/null @@ -1,121 +0,0 @@ -installEntitySchema('user'); - $this->installEntitySchema('node'); - $this->installEntitySchema('taxonomy_term'); - $this->installSchema('node', 'node_access'); - } - - /** - * Tests that the taxonomy index work correctly with forward revisions. - */ - public function testTaxonomyIndexWithForwardRevision() { - \Drupal::configFactory()->getEditable('taxonomy.settings')->set('maintain_index_table', TRUE)->save(); - - Vocabulary::create([ - 'name' => 'test', - 'vid' => 'test', - ])->save(); - $term = Term::create([ - 'name' => 'term1', - 'vid' => 'test', - ]); - $term->save(); - $term2 = Term::create([ - 'name' => 'term2', - 'vid' => 'test', - ]); - $term2->save(); - - NodeType::create([ - 'type' => 'page', - ])->save(); - - FieldStorageConfig::create([ - 'entity_type' => 'node', - 'field_name' => 'field_tags', - 'type' => 'entity_reference', - 'settings' => [ - 'target_type' => 'taxonomy_term', - ], - ])->save(); - - FieldConfig::create([ - 'field_name' => 'field_tags', - 'entity_type' => 'node', - 'bundle' => 'page', - ])->save(); - $node = Node::create([ - 'type' => 'page', - 'title' => 'test_title', - 'field_tags' => [$term->id()], - ]); - $node->save(); - - $taxonomy_index = $this->getTaxonomyIndex(); - $this->assertEquals($term->id(), $taxonomy_index[$node->id()]->tid); - - // Normal new revision. - $node->setNewRevision(TRUE); - $node->isDefaultRevision(TRUE); - $node->field_tags->target_id = $term2->id(); - $node->save(); - - $taxonomy_index = $this->getTaxonomyIndex(); - $this->assertEquals($term2->id(), $taxonomy_index[$node->id()]->tid); - - // Check that saving a forward (non-default) revision does not affect the - // taxonomy index. - $node->setNewRevision(TRUE); - $node->isDefaultRevision(FALSE); - $node->field_tags->target_id = $term->id(); - $node->save(); - - $taxonomy_index = $this->getTaxonomyIndex(); - $this->assertEquals($term2->id(), $taxonomy_index[$node->id()]->tid); - - // Check that making the previously created forward-revision the default - // revision updates the taxonomy index correctly. - $node->isDefaultRevision(TRUE); - $node->save(); - - $taxonomy_index = $this->getTaxonomyIndex(); - $this->assertEquals($term->id(), $taxonomy_index[$node->id()]->tid); - } - - protected function getTaxonomyIndex() { - return \Drupal::database()->select('taxonomy_index') - ->fields('taxonomy_index') - ->execute() - ->fetchAllAssoc('nid'); - } - -} diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/MigrateTaxonomyConfigsTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/MigrateTaxonomyConfigsTest.php index bff88305..92ebe592 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/MigrateTaxonomyConfigsTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/MigrateTaxonomyConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\taxonomy\Kernel\Migrate; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** @@ -17,7 +17,7 @@ class MigrateTaxonomyConfigsTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * {@inheritdoc} diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTest.php index b0311f3d..6450e4d9 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTest.php @@ -15,7 +15,7 @@ class MigrateTaxonomyTermTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * {@inheritdoc} @@ -30,44 +30,47 @@ protected function setUp() { * Tests the Drupal 6 taxonomy term to Drupal 8 migration. */ public function testTaxonomyTerms() { - $expected_results = array( - '1' => array( + $expected_results = [ + '1' => [ 'source_vid' => 1, 'vid' => 'vocabulary_1_i_0_', 'weight' => 0, - 'parent' => array(0), - ), - '2' => array( + 'parent' => [0], + 'language' => 'zu', + ], + '2' => [ 'source_vid' => 2, 'vid' => 'vocabulary_2_i_1_', 'weight' => 3, - 'parent' => array(0), - ), - '3' => array( + 'parent' => [0], + 'language' => 'fr', + ], + '3' => [ 'source_vid' => 2, 'vid' => 'vocabulary_2_i_1_', 'weight' => 4, - 'parent' => array(2), - ), - '4' => array( + 'parent' => [2], + 'language' => 'fr', + ], + '4' => [ 'source_vid' => 3, 'vid' => 'vocabulary_3_i_2_', 'weight' => 6, - 'parent' => array(0), - ), - '5' => array( + 'parent' => [0], + ], + '5' => [ 'source_vid' => 3, 'vid' => 'vocabulary_3_i_2_', 'weight' => 7, - 'parent' => array(4), - ), - '6' => array( + 'parent' => [4], + ], + '6' => [ 'source_vid' => 3, 'vid' => 'vocabulary_3_i_2_', 'weight' => 8, - 'parent' => array(4, 5), - ), - ); + 'parent' => [4, 5], + ], + ]; $terms = Term::loadMultiple(array_keys($expected_results)); // Find each term in the tree. @@ -83,19 +86,20 @@ public function testTaxonomyTerms() { foreach ($expected_results as $tid => $values) { /** @var Term $term */ $term = $terms[$tid]; - $this->assertIdentical("term {$tid} of vocabulary {$values['source_vid']}", $term->name->value); - $this->assertIdentical("description of term {$tid} of vocabulary {$values['source_vid']}", $term->description->value); - $this->assertIdentical($values['vid'], $term->vid->target_id); - $this->assertIdentical((string) $values['weight'], $term->weight->value); - if ($values['parent'] === array(0)) { + $language = isset($values['language']) ? $values['language'] . ' - ' : ''; + $this->assertSame("{$language}term {$tid} of vocabulary {$values['source_vid']}", $term->name->value); + $this->assertSame("{$language}description of term {$tid} of vocabulary {$values['source_vid']}", $term->description->value); + $this->assertSame($values['vid'], $term->vid->target_id); + $this->assertSame((string) $values['weight'], $term->weight->value); + if ($values['parent'] === [0]) { $this->assertNull($term->parent->target_id); } else { - $parents = array(); + $parents = []; foreach (\Drupal::entityManager()->getStorage('taxonomy_term')->loadParents($tid) as $parent) { $parents[] = (int) $parent->id(); } - $this->assertIdentical($parents, $values['parent']); + $this->assertSame($parents, $values['parent']); } $this->assertArrayHasKey($tid, $tree_terms, "Term $tid exists in vocabulary tree"); diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTranslationTest.php new file mode 100644 index 00000000..d21ad1e5 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyTermTranslationTest.php @@ -0,0 +1,124 @@ +installEntitySchema('taxonomy_term'); + $this->installConfig(static::$modules); + $this->executeMigrations([ + 'd6_node_type', + 'd6_field', + 'd6_taxonomy_vocabulary', + 'd6_field_instance', + 'd6_taxonomy_term', + 'd6_taxonomy_term_translation', + ]); + } + + /** + * Validate a migrated term contains the expected values. + * + * @param int $id + * Entity ID to load and check. + * @param string $expected_language + * The language code for this term. + * @param string $expected_label + * The label the migrated entity should have. + * @param string $expected_vid + * The parent vocabulary the migrated entity should have. + * @param string $expected_description + * The description the migrated entity should have. + * @param string $expected_format + * The format the migrated entity should have. + * @param int $expected_weight + * The weight the migrated entity should have. + * @param array $expected_parents + * The parent terms the migrated entity should have. + * @param int $expected_field_integer_value + * The value the migrated entity field should have. + * @param int $expected_term_reference_tid + * The term reference ID the migrated entity field should have. + */ + protected function assertEntity($id, $expected_language, $expected_label, $expected_vid, $expected_description = '', $expected_format = NULL, $expected_weight = 0, $expected_parents = [], $expected_field_integer_value = NULL, $expected_term_reference_tid = NULL) { + /** @var \Drupal\taxonomy\TermInterface $entity */ + $entity = Term::load($id); + $this->assertInstanceOf(TermInterface::class, $entity); + $this->assertSame($expected_language, $entity->language()->getId()); + $this->assertSame($expected_label, $entity->label()); + $this->assertSame($expected_vid, $entity->getVocabularyId()); + $this->assertSame($expected_description, $entity->getDescription()); + $this->assertSame($expected_format, $entity->getFormat()); + $this->assertSame($expected_weight, $entity->getWeight()); + $this->assertHierarchy($expected_vid, $id, $expected_parents); + } + + /** + * Assert that a term is present in the tree storage, with the right parents. + * + * @param string $vid + * Vocabulary ID. + * @param int $tid + * ID of the term to check. + * @param array $parent_ids + * The expected parent term IDs. + */ + protected function assertHierarchy($vid, $tid, array $parent_ids) { + if (!isset($this->treeData[$vid])) { + $tree = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid); + $this->treeData[$vid] = []; + foreach ($tree as $item) { + $this->treeData[$vid][$item->tid] = $item; + } + } + + $this->assertArrayHasKey($tid, $this->treeData[$vid], "Term $tid exists in taxonomy tree"); + $term = $this->treeData[$vid][$tid]; + $this->assertEquals($parent_ids, array_filter($term->parents), "Term $tid has correct parents in taxonomy tree"); + } + + /** + * Tests the Drupal 6 i18n taxonomy term to Drupal 8 migration. + */ + public function testTranslatedTaxonomyTerms() { + $this->assertEntity(1, 'zu', 'zu - term 1 of vocabulary 1', 'vocabulary_1_i_0_', 'zu - description of term 1 of vocabulary 1', NULL, '0', []); + $this->assertEntity(2, 'fr', 'fr - term 2 of vocabulary 2', 'vocabulary_2_i_1_', 'fr - description of term 2 of vocabulary 2', NULL, '3', []); + $this->assertEntity(3, 'fr', 'fr - term 3 of vocabulary 2', 'vocabulary_2_i_1_', 'fr - description of term 3 of vocabulary 2', NULL, '4', ['2']); + $this->assertEntity(4, 'en', 'term 4 of vocabulary 3', 'vocabulary_3_i_2_', 'description of term 4 of vocabulary 3', NULL, '6', []); + $this->assertEntity(5, 'en', 'term 5 of vocabulary 3', 'vocabulary_3_i_2_', 'description of term 5 of vocabulary 3', NULL, '7', ['4']); + $this->assertEntity(6, 'en', 'term 6 of vocabulary 3', 'vocabulary_3_i_2_', 'description of term 6 of vocabulary 3', NULL, '8', ['4', '5']); + $this->assertEntity(7, 'fr', 'fr - term 2 of vocabulary 1', 'vocabulary_1_i_0_', 'fr - desc of term 2 vocab 1', NULL, '0', []); + } + +} diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php index c2d4ab61..79e188b9 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php @@ -15,7 +15,7 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * {@inheritdoc} @@ -32,17 +32,17 @@ public function testTaxonomyVocabulary() { for ($i = 0; $i < 3; $i++) { $j = $i + 1; $vocabulary = Vocabulary::load("vocabulary_{$j}_i_{$i}_"); - $this->assertIdentical($this->getMigration('d6_taxonomy_vocabulary')->getIdMap()->lookupDestinationID(array($j)), array($vocabulary->id())); - $this->assertIdentical("vocabulary $j (i=$i)", $vocabulary->label()); - $this->assertIdentical("description of vocabulary $j (i=$i)", $vocabulary->getDescription()); - $this->assertIdentical($i, $vocabulary->getHierarchy()); - $this->assertIdentical(4 + $i, $vocabulary->get('weight')); + $this->assertSame($this->getMigration('d6_taxonomy_vocabulary')->getIdMap()->lookupDestinationID([$j]), [$vocabulary->id()]); + $this->assertSame("vocabulary $j (i=$i)", $vocabulary->label()); + $this->assertSame("description of vocabulary $j (i=$i)", $vocabulary->getDescription()); + $this->assertSame($i, $vocabulary->getHierarchy()); + $this->assertSame(4 + $i, $vocabulary->get('weight')); } $vocabulary = Vocabulary::load('vocabulary_name_much_longer_than'); - $this->assertIdentical('vocabulary name much longer than thirty two characters', $vocabulary->label()); - $this->assertIdentical('description of vocabulary name much longer than thirty two characters', $vocabulary->getDescription()); - $this->assertIdentical(3, $vocabulary->getHierarchy()); - $this->assertIdentical(7, $vocabulary->get('weight')); + $this->assertSame('vocabulary name much longer than thirty two characters', $vocabulary->label()); + $this->assertSame('description of vocabulary name much longer than thirty two characters', $vocabulary->getDescription()); + $this->assertSame(3, $vocabulary->getHierarchy()); + $this->assertSame(7, $vocabulary->get('weight')); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTranslationTest.php new file mode 100644 index 00000000..3993abb9 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTranslationTest.php @@ -0,0 +1,47 @@ +executeMigrations([ + 'd6_taxonomy_vocabulary', + 'd6_taxonomy_vocabulary_translation', + ]); + } + + /** + * Tests the Drupal 6 i18n taxonomy vocabularies to Drupal 8 migration. + */ + public function testTaxonomyVocabularyTranslation() { + $language_manager = \Drupal::service('language_manager'); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_1_i_0_'); + $this->assertSame('fr - vocabulary 1 (i=0)', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_2_i_1_'); + $this->assertSame('fr - vocabulary 2 (i=1)', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_3_i_2_'); + $this->assertSame('fr - vocabulary 3 (i=2)', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_name_much_longer_than'); + $this->assertSame('Nom de vocabulaire beaucoup plus long que trente-deux caractères', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.tags'); + $this->assertSame('fr - Tags', $config->get('name')); + } + +} diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeRevisionTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeRevisionTest.php index facd69ba..614725d9 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeRevisionTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeRevisionTest.php @@ -14,7 +14,7 @@ class MigrateTermNodeRevisionTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['taxonomy']; + public static $modules = ['taxonomy', 'menu_ui']; /** * {@inheritdoc} @@ -32,9 +32,9 @@ protected function setUp() { */ public function testTermRevisionNode() { $node = \Drupal::entityManager()->getStorage('node')->loadRevision(2); - $this->assertIdentical(2, count($node->vocabulary_3_i_2_)); - $this->assertIdentical('4', $node->vocabulary_3_i_2_[0]->target_id); - $this->assertIdentical('5', $node->vocabulary_3_i_2_[1]->target_id); + $this->assertSame(2, count($node->field_vocabulary_3_i_2_)); + $this->assertSame('4', $node->field_vocabulary_3_i_2_[0]->target_id); + $this->assertSame('5', $node->field_vocabulary_3_i_2_[1]->target_id); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php index 26f069c0..8e7d13de 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php @@ -15,7 +15,7 @@ class MigrateTermNodeTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['taxonomy']; + public static $modules = ['taxonomy', 'menu_ui']; /** * {@inheritdoc} @@ -40,12 +40,12 @@ public function testTermNode() { $nodes = Node::loadMultiple([1, 2]); $node = $nodes[1]; - $this->assertIdentical(1, count($node->vocabulary_1_i_0_)); - $this->assertIdentical('1', $node->vocabulary_1_i_0_[0]->target_id); + $this->assertSame(1, count($node->field_vocabulary_1_i_0_)); + $this->assertSame('1', $node->field_vocabulary_1_i_0_[0]->target_id); $node = $nodes[2]; - $this->assertIdentical(2, count($node->vocabulary_2_i_1_)); - $this->assertIdentical('2', $node->vocabulary_2_i_1_[0]->target_id); - $this->assertIdentical('3', $node->vocabulary_2_i_1_[1]->target_id); + $this->assertSame(2, count($node->field_vocabulary_2_i_1_)); + $this->assertSame('2', $node->field_vocabulary_2_i_1_[0]->target_id); + $this->assertSame('3', $node->field_vocabulary_2_i_1_[1]->target_id); } /** diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityDisplayTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityDisplayTest.php index 42f864e4..5b8a6388 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityDisplayTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityDisplayTest.php @@ -15,26 +15,61 @@ class MigrateVocabularyEntityDisplayTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['field', 'taxonomy']; + public static $modules = ['field', 'taxonomy', 'menu_ui']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->migrateTaxonomy(); + + // Execute Dependency Migrations. + $this->migrateContentTypes(); + $this->installEntitySchema('taxonomy_term'); + $this->executeMigrations([ + 'd6_node_type', + 'd6_taxonomy_vocabulary', + 'd6_vocabulary_field', + 'd6_vocabulary_field_instance', + ]); } /** * Tests the Drupal 6 vocabulary-node type association to Drupal 8 migration. */ public function testVocabularyEntityDisplay() { + $this->executeMigration('d6_vocabulary_entity_display'); + // Test that the field exists. - $component = EntityViewDisplay::load('node.page.default')->getComponent('tags'); - $this->assertIdentical('entity_reference_label', $component['type']); - $this->assertIdentical(20, $component['weight']); + $component = EntityViewDisplay::load('node.page.default')->getComponent('field_tags'); + $this->assertSame('entity_reference_label', $component['type']); + $this->assertSame(20, $component['weight']); // Test the Id map. - $this->assertIdentical(array('node', 'article', 'default', 'tags'), $this->getMigration('d6_vocabulary_entity_display')->getIdMap()->lookupDestinationID(array(4, 'article'))); + $this->assertSame(['node', 'article', 'default', 'field_tags'], $this->getMigration('d6_vocabulary_entity_display')->getIdMap()->lookupDestinationID([4, 'article'])); + + // Tests that a vocabulary named like a D8 base field will be migrated and + // prefixed with 'field_' to avoid conflicts. + $field_type = EntityViewDisplay::load('node.sponsor.default')->getComponent('field_type'); + $this->assertTrue(is_array($field_type)); + } + + /** + * Tests that vocabulary displays are ignored appropriately. + * + * Vocabulary displays should be ignored when they belong to node types which + * were not migrated. + */ + public function testSkipNonExistentNodeType() { + // The "story" node type is migrated by d6_node_type but we need to pretend + // that it didn't occur, so record that in the map table. + $this->mockFailure('d6_node_type', ['type' => 'story']); + + // d6_vocabulary_entity_display should skip over the "story" node type + // config because, according to the map table, it didn't occur. + $migration = $this->getMigration('d6_vocabulary_entity_display'); + + $this->executeMigration($migration); + $this->assertNull($migration->getIdMap()->lookupDestinationIds(['type' => 'story'])[0][0]); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityFormDisplayTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityFormDisplayTest.php index a2e26c71..2c96e517 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityFormDisplayTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyEntityFormDisplayTest.php @@ -15,31 +15,66 @@ class MigrateVocabularyEntityFormDisplayTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['taxonomy']; + public static $modules = ['taxonomy', 'menu_ui']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->migrateTaxonomy(); + + // Execute Dependency Migrations. + $this->migrateContentTypes(); + $this->installEntitySchema('taxonomy_term'); + $this->executeMigrations([ + 'd6_taxonomy_vocabulary', + 'd6_vocabulary_field', + 'd6_vocabulary_field_instance', + 'd6_vocabulary_entity_display', + ]); } /** * Tests the Drupal 6 vocabulary-node type association to Drupal 8 migration. */ public function testVocabularyEntityFormDisplay() { + $this->executeMigration('d6_vocabulary_entity_form_display'); + // Test that the field exists. - $component = EntityFormDisplay::load('node.page.default')->getComponent('tags'); - $this->assertIdentical('options_select', $component['type']); - $this->assertIdentical(20, $component['weight']); + $component = EntityFormDisplay::load('node.page.default')->getComponent('field_tags'); + $this->assertSame('options_select', $component['type']); + $this->assertSame(20, $component['weight']); // Test the Id map. - $this->assertIdentical(array('node', 'article', 'default', 'tags'), $this->getMigration('d6_vocabulary_entity_form_display')->getIdMap()->lookupDestinationID(array(4, 'article'))); + $this->assertSame(['node', 'article', 'default', 'field_tags'], $this->getMigration('d6_vocabulary_entity_form_display')->getIdMap()->lookupDestinationID([4, 'article'])); // Test the term widget tags setting. $entity_form_display = EntityFormDisplay::load('node.story.default'); - $this->assertIdentical($entity_form_display->getComponent('vocabulary_1_i_0_')['type'], 'options_select'); - $this->assertIdentical($entity_form_display->getComponent('vocabulary_2_i_1_')['type'], 'entity_reference_autocomplete_tags'); + $this->assertSame($entity_form_display->getComponent('field_vocabulary_1_i_0_')['type'], 'options_select'); + $this->assertSame($entity_form_display->getComponent('field_vocabulary_2_i_1_')['type'], 'entity_reference_autocomplete_tags'); + + // Tests that a vocabulary named like a D8 base field will be migrated and + // prefixed with 'field_' to avoid conflicts. + $field_type = EntityFormDisplay::load('node.sponsor.default')->getComponent('field_type'); + $this->assertTrue(is_array($field_type)); + } + + /** + * Tests that vocabulary displays are ignored appropriately. + * + * Vocabulary displays should be ignored when they belong to node types which + * were not migrated. + */ + public function testSkipNonExistentNodeType() { + // The "story" node type is migrated by d6_node_type but we need to pretend + // that it didn't occur, so record that in the map table. + $this->mockFailure('d6_node_type', ['type' => 'story']); + + // d6_vocabulary_entity_form_display should skip over the "story" node type + // config because, according to the map table, it didn't occur. + $migration = $this->getMigration('d6_vocabulary_entity_form_display'); + + $this->executeMigration($migration); + $this->assertNull($migration->getIdMap()->lookupDestinationIds(['type' => 'story'])[0][0]); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldInstanceTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldInstanceTest.php index 2534c3e3..26cd7f58 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldInstanceTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldInstanceTest.php @@ -15,45 +15,79 @@ class MigrateVocabularyFieldInstanceTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['taxonomy']; + public static $modules = ['taxonomy', 'menu_ui']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->migrateTaxonomy(); + + // Execute Dependency Migrations. + $this->migrateContentTypes(); + $this->installEntitySchema('taxonomy_term'); + $this->executeMigrations([ + 'd6_node_type', + 'd6_taxonomy_vocabulary', + 'd6_vocabulary_field', + ]); } /** * Tests the Drupal 6 vocabulary-node type association to Drupal 8 migration. */ public function testVocabularyFieldInstance() { + $this->executeMigration('d6_vocabulary_field_instance'); + // Test that the field exists. - $field_id = 'node.article.tags'; + $field_id = 'node.article.field_tags'; $field = FieldConfig::load($field_id); - $this->assertIdentical($field_id, $field->id(), 'Field instance exists on article bundle.'); - $this->assertIdentical('Tags', $field->label()); + $this->assertSame($field_id, $field->id(), 'Field instance exists on article bundle.'); + $this->assertSame('Tags', $field->label()); $this->assertTrue($field->isRequired(), 'Field is required'); // Test the page bundle as well. - $field_id = 'node.page.tags'; + $field_id = 'node.page.field_tags'; $field = FieldConfig::load($field_id); - $this->assertIdentical($field_id, $field->id(), 'Field instance exists on page bundle.'); - $this->assertIdentical('Tags', $field->label()); + $this->assertSame($field_id, $field->id(), 'Field instance exists on page bundle.'); + $this->assertSame('Tags', $field->label()); $this->assertTrue($field->isRequired(), 'Field is required'); $settings = $field->getSettings(); - $this->assertIdentical('default:taxonomy_term', $settings['handler'], 'The handler plugin ID is correct.'); - $this->assertIdentical(['tags'], $settings['handler_settings']['target_bundles'], 'The target_bundles handler setting is correct.'); - $this->assertIdentical(TRUE, $settings['handler_settings']['auto_create'], 'The "auto_create" setting is correct.'); + $this->assertSame('default:taxonomy_term', $settings['handler'], 'The handler plugin ID is correct.'); + $this->assertSame(['field_tags'], $settings['handler_settings']['target_bundles'], 'The target_bundles handler setting is correct.'); + $this->assertSame(TRUE, $settings['handler_settings']['auto_create'], 'The "auto_create" setting is correct.'); - $this->assertIdentical(array('node', 'article', 'tags'), $this->getMigration('d6_vocabulary_field_instance')->getIdMap()->lookupDestinationID(array(4, 'article'))); + $this->assertSame(['node', 'article', 'field_tags'], $this->getMigration('d6_vocabulary_field_instance')->getIdMap()->lookupDestinationID([4, 'article'])); - // Test the the field vocabulary_1_i_0_ - $field_id = 'node.story.vocabulary_1_i_0_'; + // Test the the field vocabulary_1_i_0_. + $field_id = 'node.story.field_vocabulary_1_i_0_'; $field = FieldConfig::load($field_id); $this->assertFalse($field->isRequired(), 'Field is not required'); + + // Tests that a vocabulary named like a D8 base field will be migrated and + // prefixed with 'field_' to avoid conflicts. + $field_type = FieldConfig::load('node.sponsor.field_type'); + $this->assertInstanceOf(FieldConfig::class, $field_type); + } + + /** + * Tests that vocabulary field instances are ignored appropriately. + * + * Vocabulary field instances should be ignored when they belong to node + * types which were not migrated. + */ + public function testSkipNonExistentNodeType() { + // The "story" node type is migrated by d6_node_type but we need to pretend + // that it didn't occur, so record that in the map table. + $this->mockFailure('d6_node_type', ['type' => 'story']); + + // d6_vocabulary_field_instance should skip over the "story" node type + // config because, according to the map table, it didn't occur. + $migration = $this->getMigration('d6_vocabulary_field_instance'); + + $this->executeMigration($migration); + $this->assertNull($migration->getIdMap()->lookupDestinationIds(['type' => 'story'])[0][0]); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldTest.php index eb0c4804..d294ec48 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateVocabularyFieldTest.php @@ -15,7 +15,7 @@ class MigrateVocabularyFieldTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = ['taxonomy']; + public static $modules = ['taxonomy', 'menu_ui']; /** * {@inheritdoc} @@ -30,16 +30,21 @@ protected function setUp() { */ public function testVocabularyField() { // Test that the field exists. - $field_storage_id = 'node.tags'; + $field_storage_id = 'node.field_tags'; /** @var \Drupal\field\FieldStorageConfigInterface $field_storage */ $field_storage = FieldStorageConfig::load($field_storage_id); - $this->assertIdentical($field_storage_id, $field_storage->id()); + $this->assertSame($field_storage_id, $field_storage->id()); $settings = $field_storage->getSettings(); - $this->assertIdentical('taxonomy_term', $settings['target_type'], "Target type is correct."); - $this->assertIdentical(1, $field_storage->getCardinality(), "Field cardinality in 1."); + $this->assertSame('taxonomy_term', $settings['target_type'], "Target type is correct."); + $this->assertSame(1, $field_storage->getCardinality(), "Field cardinality in 1."); - $this->assertIdentical(array('node', 'tags'), $this->getMigration('d6_vocabulary_field')->getIdMap()->lookupDestinationID(array(4)), "Test IdMap"); + $this->assertSame(['node', 'field_tags'], $this->getMigration('d6_vocabulary_field')->getIdMap()->lookupDestinationID([4]), "Test IdMap"); + + // Tests that a vocabulary named like a D8 base field will be migrated and + // prefixed with 'field_' to avoid conflicts. + $field_type = FieldStorageConfig::load('node.field_type'); + $this->assertInstanceOf(FieldStorageConfig::class, $field_type); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateNodeTaxonomyTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateNodeTaxonomyTest.php index d57e3341..e8c6fefa 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateNodeTaxonomyTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateNodeTaxonomyTest.php @@ -14,17 +14,18 @@ */ class MigrateNodeTaxonomyTest extends MigrateDrupal7TestBase { - public static $modules = array( + public static $modules = [ 'datetime', 'field', 'filter', 'image', 'link', + 'menu_ui', 'node', 'taxonomy', 'telephone', 'text', - ); + ]; /** * {@inheritdoc} @@ -40,21 +41,21 @@ protected function setUp() { $this->executeMigration('d7_node_type'); - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'type' => 'entity_reference', 'field_name' => 'field_tags', 'entity_type' => 'node', - 'settings' => array( + 'settings' => [ 'target_type' => 'taxonomy_term', - ), + ], 'cardinality' => FieldStorageConfigInterface::CARDINALITY_UNLIMITED, - ))->save(); + ])->save(); - FieldConfig::create(array( + FieldConfig::create([ 'entity_type' => 'node', 'field_name' => 'field_tags', 'bundle' => 'article', - ))->save(); + ])->save(); $this->executeMigrations([ 'd7_taxonomy_vocabulary', diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php index fbcc1297..474969dd 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php @@ -16,8 +16,10 @@ class MigrateTaxonomyTermTest extends MigrateDrupal7TestBase { public static $modules = [ 'comment', 'datetime', + 'forum', 'image', 'link', + 'menu_ui', 'node', 'taxonomy', 'telephone', @@ -70,17 +72,19 @@ protected function setUp() { * The value the migrated entity field should have. * @param int $expected_term_reference_tid * The term reference id the migrated entity field should have. + * @param bool $expected_container_flag + * The term should be a container entity. */ - protected function assertEntity($id, $expected_label, $expected_vid, $expected_description = '', $expected_format = NULL, $expected_weight = 0, $expected_parents = [], $expected_field_integer_value = NULL, $expected_term_reference_tid = NULL) { + protected function assertEntity($id, $expected_label, $expected_vid, $expected_description = '', $expected_format = NULL, $expected_weight = 0, $expected_parents = [], $expected_field_integer_value = NULL, $expected_term_reference_tid = NULL, $expected_container_flag = 0) { /** @var \Drupal\taxonomy\TermInterface $entity */ $entity = Term::load($id); - $this->assertTrue($entity instanceof TermInterface); - $this->assertIdentical($expected_label, $entity->label()); - $this->assertIdentical($expected_vid, $entity->getVocabularyId()); - $this->assertEqual($expected_description, $entity->getDescription()); + $this->assertInstanceOf(TermInterface::class, $entity); + $this->assertEquals($expected_label, $entity->label()); + $this->assertEquals($expected_vid, $entity->bundle()); + $this->assertEquals($expected_description, $entity->getDescription()); $this->assertEquals($expected_format, $entity->getFormat()); - $this->assertEqual($expected_weight, $entity->getWeight()); - $this->assertIdentical($expected_parents, $this->getParentIDs($id)); + $this->assertEquals($expected_weight, $entity->getWeight()); + $this->assertEquals($expected_parents, $this->getParentIDs($id)); $this->assertHierarchy($expected_vid, $id, $expected_parents); if (!is_null($expected_field_integer_value)) { $this->assertTrue($entity->hasField('field_integer')); @@ -90,6 +94,9 @@ protected function assertEntity($id, $expected_label, $expected_vid, $expected_d $this->assertTrue($entity->hasField('field_integer')); $this->assertEquals($expected_term_reference_tid, $entity->field_term_reference->target_id); } + if ($entity->hasField('forum_container')) { + $this->assertEquals($expected_container_flag, $entity->forum_container->value); + } } /** @@ -101,9 +108,17 @@ public function testTaxonomyTerms() { $this->assertEntity(3, 'Term2', 'test_vocabulary', 'The second term.', 'filtered_html'); $this->assertEntity(4, 'Term3', 'test_vocabulary', 'The third term.', 'full_html', 0, [3], 6); $this->assertEntity(5, 'Custom Forum', 'forums', 'Where the cool kids are.', NULL, 3); - $this->assertEntity(6, 'Games', 'forums', '', NULL, 4); + $this->assertEntity(6, 'Games', 'forums', '', NULL, 4, [], NULL, NULL, 1); $this->assertEntity(7, 'Minecraft', 'forums', '', NULL, 1, [6]); $this->assertEntity(8, 'Half Life 3', 'forums', '', NULL, 0, [6]); + + // Verify that we still can create forum containers after the migration. + $term = Term::create(['vid' => 'forums', 'name' => 'Forum Container', 'forum_container' => 1]); + $term->save(); + + // Reset the forums tree data so this new term is included in the tree. + unset($this->treeData['forums']); + $this->assertEntity(19, 'Forum Container', 'forums', '', NULL, 0, [], NULL, NULL, 1); } /** diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php index 3f29fbf7..5663ea6c 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyVocabularyTest.php @@ -16,7 +16,7 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal7TestBase { /** * {@inheritdoc} */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * {@inheritdoc} @@ -55,8 +55,9 @@ protected function assertEntity($id, $expected_label, $expected_description, $ex */ public function testTaxonomyVocabulary() { $this->assertEntity('tags', 'Tags', 'Use tags to group articles on similar topics into categories.', VocabularyInterface::HIERARCHY_DISABLED, 0); - $this->assertEntity('forums', 'Forums', 'Forum navigation vocabulary', VocabularyInterface::HIERARCHY_SINGLE, -10); + $this->assertEntity('forums', 'Sujet de discussion', 'Forum navigation vocabulary', VocabularyInterface::HIERARCHY_SINGLE, -10); $this->assertEntity('test_vocabulary', 'Test Vocabulary', 'This is the vocabulary description', VocabularyInterface::HIERARCHY_SINGLE, 0); + $this->assertEntity('vocabulary_name_much_longer_than', 'vocabulary name clearly different than machine name and much longer than thirty two characters', 'description of vocabulary name much longer than thirty two characters', VocabularyInterface::HIERARCHY_SINGLE, 0); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php b/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php new file mode 100644 index 00000000..e4b2cc05 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php @@ -0,0 +1,120 @@ +installEntitySchema('user'); + $this->installEntitySchema('node'); + $this->installEntitySchema('taxonomy_term'); + $this->installSchema('node', 'node_access'); + } + + /** + * Tests that the taxonomy index work correctly with pending revisions. + */ + public function testTaxonomyIndexWithPendingRevision() { + \Drupal::configFactory()->getEditable('taxonomy.settings')->set('maintain_index_table', TRUE)->save(); + + Vocabulary::create([ + 'name' => 'test', + 'vid' => 'test', + ])->save(); + $term = Term::create([ + 'name' => 'term1', + 'vid' => 'test', + ]); + $term->save(); + $term2 = Term::create([ + 'name' => 'term2', + 'vid' => 'test', + ]); + $term2->save(); + + NodeType::create([ + 'type' => 'page', + ])->save(); + + FieldStorageConfig::create([ + 'entity_type' => 'node', + 'field_name' => 'field_tags', + 'type' => 'entity_reference', + 'settings' => [ + 'target_type' => 'taxonomy_term', + ], + ])->save(); + + FieldConfig::create([ + 'field_name' => 'field_tags', + 'entity_type' => 'node', + 'bundle' => 'page', + ])->save(); + $node = Node::create([ + 'type' => 'page', + 'title' => 'test_title', + 'field_tags' => [$term->id()], + ]); + $node->save(); + + $taxonomy_index = $this->getTaxonomyIndex(); + $this->assertEquals($term->id(), $taxonomy_index[$node->id()]->tid); + + // Normal new revision. + $node->setNewRevision(TRUE); + $node->isDefaultRevision(TRUE); + $node->field_tags->target_id = $term2->id(); + $node->save(); + + $taxonomy_index = $this->getTaxonomyIndex(); + $this->assertEquals($term2->id(), $taxonomy_index[$node->id()]->tid); + + // Check that saving a pending revision does not affect the taxonomy index. + $node->setNewRevision(TRUE); + $node->isDefaultRevision(FALSE); + $node->field_tags->target_id = $term->id(); + $node->save(); + + $taxonomy_index = $this->getTaxonomyIndex(); + $this->assertEquals($term2->id(), $taxonomy_index[$node->id()]->tid); + + // Check that making the previously created pending revision the default + // revision updates the taxonomy index correctly. + $node->isDefaultRevision(TRUE); + $node->save(); + + $taxonomy_index = $this->getTaxonomyIndex(); + $this->assertEquals($term->id(), $taxonomy_index[$node->id()]->tid); + } + + protected function getTaxonomyIndex() { + return \Drupal::database()->select('taxonomy_index') + ->fields('taxonomy_index') + ->execute() + ->fetchAllAssoc('nid'); + } + +} diff --git a/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/TermTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/TermTranslationTest.php new file mode 100644 index 00000000..af69e30e --- /dev/null +++ b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/TermTranslationTest.php @@ -0,0 +1,206 @@ + 1, + 'vid' => 5, + 'name' => 'name value 1', + 'description' => 'description value 1', + 'weight' => 0, + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 2, + 'vid' => 6, + 'name' => 'name value 2', + 'description' => 'description value 2', + 'weight' => 0, + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 3, + 'vid' => 6, + 'name' => 'name value 3', + 'description' => 'description value 3', + 'weight' => 0, + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 4, + 'vid' => 5, + 'name' => 'name value 4', + 'description' => 'description value 4', + 'weight' => 1, + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 5, + 'vid' => 6, + 'name' => 'name value 5', + 'description' => 'description value 5', + 'weight' => 1, + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 6, + 'vid' => 6, + 'name' => 'name value 6', + 'description' => 'description value 6', + 'weight' => 0, + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 10, + 'vid' => 6, + 'name' => 'zu - name value 2', + 'description' => 'zu - description value 2', + 'weight' => 0, + 'language' => 'zu', + 'trid' => 0, + ], + ]; + $tests[0]['source_data']['term_hierarchy'] = [ + [ + 'tid' => 1, + 'parent' => 0, + ], + [ + 'tid' => 2, + 'parent' => 0, + ], + [ + 'tid' => 3, + 'parent' => 0, + ], + [ + 'tid' => 4, + 'parent' => 1, + ], + [ + 'tid' => 5, + 'parent' => 2, + ], + [ + 'tid' => 6, + 'parent' => 3, + ], + [ + 'tid' => 6, + 'parent' => 2, + ], + [ + 'tid' => 10, + 'parent' => 0, + ], + ]; + + // The expected results. + $tests[0]['expected_data'] = [ + [ + 'tid' => 1, + 'vid' => 5, + 'name' => 'name value 1', + 'description' => 'description value 1', + 'weight' => 0, + 'parent' => [0], + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 10, + 'vid' => 6, + 'name' => 'zu - name value 2', + 'description' => 'zu - description value 2', + 'weight' => 0, + 'parent' => [0], + 'language' => 'zu', + 'trid' => 0, + ], + [ + 'tid' => 2, + 'vid' => 6, + 'name' => 'name value 2', + 'description' => 'description value 2', + 'weight' => 0, + 'parent' => [0], + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 3, + 'vid' => 6, + 'name' => 'name value 3', + 'description' => 'description value 3', + 'weight' => 0, + 'parent' => [0], + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 4, + 'vid' => 5, + 'name' => 'name value 4', + 'description' => 'description value 4', + 'weight' => 1, + 'parent' => [1], + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 5, + 'vid' => 6, + 'name' => 'name value 5', + 'description' => 'description value 5', + 'weight' => 1, + 'parent' => [2], + 'language' => NULL, + 'trid' => 0, + ], + [ + 'tid' => 6, + 'vid' => 6, + 'name' => 'name value 6', + 'description' => 'description value 6', + 'weight' => 0, + 'parent' => [3, 2], + 'language' => NULL, + 'trid' => 0, + ], + ]; + + $tests[0]['expected_count'] = NULL; + + return $tests; + } + +} diff --git a/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/VocabularyTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/VocabularyTranslationTest.php new file mode 100644 index 00000000..e54eb6ee --- /dev/null +++ b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/VocabularyTranslationTest.php @@ -0,0 +1,125 @@ + 1, + 'objectid' => 1, + 'type' => 'vocabulary', + 'property' => 'name', + 'objectindex' => 1, + 'format' => 0, + ], + [ + 'lid' => 2, + 'objectid' => 2, + 'type' => 'vocabulary', + 'property' => 'name', + 'objectindex' => 2, + 'format' => 0, + ], + ]; + + $tests[0][0]['locales_target'] = [ + [ + 'lid' => 1, + 'language' => 'fr', + 'translation' => 'fr - vocabulary 1', + 'plid' => 0, + 'plural' => 0, + 'i18n_status' => 0, + ], + [ + 'lid' => 2, + 'language' => 'fr', + 'translation' => 'fr - vocabulary 2', + 'plid' => 0, + 'plural' => 0, + 'i18n_status' => 0, + ], + ]; + + $tests[0][0]['vocabulary'] = [ + [ + 'vid' => 1, + 'name' => 'vocabulary 1', + 'description' => 'description of vocabulary 1', + 'help' => 1, + 'relations' => 1, + 'hierarchy' => 1, + 'multiple' => 0, + 'required' => 0, + 'tags' => 0, + 'module' => 'taxonomy', + 'weight' => 4, + 'language' => '', + ], + [ + 'vid' => 2, + 'name' => 'vocabulary 2', + 'description' => 'description of vocabulary 2', + 'help' => 1, + 'relations' => 1, + 'hierarchy' => 1, + 'multiple' => 0, + 'required' => 0, + 'tags' => 0, + 'module' => 'taxonomy', + 'weight' => 5, + 'language' => '', + ], + ]; + + $tests[0]['expected_results'] = [ + [ + 'vid' => 1, + 'name' => 'vocabulary 1', + 'description' => 'description of vocabulary 1', + 'lid' => '1', + 'type' => 'vocabulary', + 'property' => 'name', + 'objectid' => '1', + 'lt_lid' => '1', + 'translation' => 'fr - vocabulary 1', + 'language' => 'fr', + ], + [ + 'vid' => 2, + 'name' => 'vocabulary 2', + 'description' => 'description of vocabulary 2', + 'lid' => '2', + 'type' => 'vocabulary', + 'property' => 'name', + 'objectid' => '2', + 'lt_lid' => '2', + 'translation' => 'fr - vocabulary 2', + 'language' => 'fr', + ], + ]; + return $tests; + } + +} diff --git a/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d7/TermTest.php b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d7/TermTest.php index be905d9d..dd22672a 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d7/TermTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d7/TermTest.php @@ -31,6 +31,7 @@ public function providerSource() { 'name' => 'name value 1', 'description' => 'description value 1', 'weight' => 0, + 'is_container' => FALSE, ], [ 'tid' => 2, @@ -38,6 +39,7 @@ public function providerSource() { 'name' => 'name value 2', 'description' => 'description value 2', 'weight' => 0, + 'is_container' => TRUE, ], [ 'tid' => 3, @@ -45,6 +47,7 @@ public function providerSource() { 'name' => 'name value 3', 'description' => 'description value 3', 'weight' => 0, + 'is_container' => FALSE, ], [ 'tid' => 4, @@ -52,6 +55,7 @@ public function providerSource() { 'name' => 'name value 4', 'description' => 'description value 4', 'weight' => 1, + 'is_container' => FALSE, ], [ 'tid' => 5, @@ -59,6 +63,7 @@ public function providerSource() { 'name' => 'name value 5', 'description' => 'description value 5', 'weight' => 1, + 'is_container' => FALSE, ], [ 'tid' => 6, @@ -66,6 +71,7 @@ public function providerSource() { 'name' => 'name value 6', 'description' => 'description value 6', 'weight' => 0, + 'is_container' => TRUE, ], [ 'tid' => 7, @@ -73,6 +79,7 @@ public function providerSource() { 'name' => 'name value 7', 'description' => 'description value 7', 'weight' => 0, + 'is_container' => TRUE, ], ]; $tests[0]['source_data']['taxonomy_term_hierarchy'] = [ @@ -149,6 +156,12 @@ public function providerSource() { 'delta' => 0, ], ]; + $tests[0]['source_data']['variable'] = [ + [ + 'name' => 'forum_containers', + 'value' => 'a:3:{i:0;s:1:"5";i:1;s:1:"6";i:2;s:1:"7";}', + ], + ]; // The expected results. $tests[0]['expected_data'] = [ diff --git a/core/modules/taxonomy/tests/src/Kernel/TermKernelTest.php b/core/modules/taxonomy/tests/src/Kernel/TermKernelTest.php index 1e2b2323..3d8bff80 100644 --- a/core/modules/taxonomy/tests/src/Kernel/TermKernelTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/TermKernelTest.php @@ -4,7 +4,7 @@ use Drupal\taxonomy\Entity\Term; use Drupal\KernelTests\KernelTestBase; -use Drupal\taxonomy\Tests\TaxonomyTestTrait; +use Drupal\Tests\taxonomy\Functional\TaxonomyTestTrait; /** * Kernel tests for taxonomy term functions. @@ -18,14 +18,14 @@ class TermKernelTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = array( 'filter', 'taxonomy', 'text', 'user' ); + public static $modules = ['filter', 'taxonomy', 'text', 'user']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->installConfig(array('filter')); + $this->installConfig(['filter']); $this->installEntitySchema('taxonomy_term'); } @@ -38,11 +38,11 @@ public function testTermDelete() { $valid_term = $this->createTerm($vocabulary); // Delete a valid term. $valid_term->delete(); - $terms = entity_load_multiple_by_properties('taxonomy_term', array('vid' => $vocabulary->id())); + $terms = entity_load_multiple_by_properties('taxonomy_term', ['vid' => $vocabulary->id()]); $this->assertTrue(empty($terms), 'Vocabulary is empty after deletion'); // Delete an invalid term. Should not throw any notices. - entity_delete_multiple('taxonomy_term', array(42)); + entity_delete_multiple('taxonomy_term', [42]); } /** @@ -53,18 +53,18 @@ public function testMultipleParentDelete() { $parent_term1 = $this->createTerm($vocabulary); $parent_term2 = $this->createTerm($vocabulary); $child_term = $this->createTerm($vocabulary); - $child_term->parent = array($parent_term1->id(), $parent_term2->id()); + $child_term->parent = [$parent_term1->id(), $parent_term2->id()]; $child_term->save(); $child_term_id = $child_term->id(); $parent_term1->delete(); $term_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term'); - $term_storage->resetCache(array($child_term_id)); + $term_storage->resetCache([$child_term_id]); $child_term = Term::load($child_term_id); $this->assertTrue(!empty($child_term), 'Child term is not deleted if only one of its parents is removed.'); $parent_term2->delete(); - $term_storage->resetCache(array($child_term_id)); + $term_storage->resetCache([$child_term_id]); $child_term = Term::load($child_term_id); $this->assertTrue(empty($child_term), 'Child term is deleted if all of its parents are removed.'); } @@ -75,7 +75,7 @@ public function testMultipleParentDelete() { public function testTaxonomyVocabularyTree() { // Create a new vocabulary with 6 terms. $vocabulary = $this->createVocabulary(); - $term = array(); + $term = []; for ($i = 0; $i < 6; $i++) { $term[$i] = $this->createTerm($vocabulary); } @@ -90,13 +90,13 @@ public function testTaxonomyVocabularyTree() { $term[1]->save(); // $term[2] is a child of 1 and 5. - $term[2]->parent = array($term[1]->id(), $term[5]->id()); + $term[2]->parent = [$term[1]->id(), $term[5]->id()]; $term[2]->save(); // $term[3] is a child of 2. - $term[3]->parent = array($term[2]->id()); + $term[3]->parent = [$term[2]->id()]; $term[3]->save(); // $term[5] is a child of 4. - $term[5]->parent = array($term[4]->id()); + $term[5]->parent = [$term[4]->id()]; $term[5]->save(); /** diff --git a/core/modules/taxonomy/tests/src/Kernel/TermValidationTest.php b/core/modules/taxonomy/tests/src/Kernel/TermValidationTest.php index 3d9cfb77..437a305f 100644 --- a/core/modules/taxonomy/tests/src/Kernel/TermValidationTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/TermValidationTest.php @@ -16,7 +16,7 @@ class TermValidationTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('taxonomy'); + public static $modules = ['taxonomy']; /** * {@inheritdoc} @@ -30,14 +30,14 @@ protected function setUp() { * Tests the term validation constraints. */ public function testValidation() { - $this->entityManager->getStorage('taxonomy_vocabulary')->create(array( + $this->entityManager->getStorage('taxonomy_vocabulary')->create([ 'vid' => 'tags', 'name' => 'Tags', - ))->save(); - $term = $this->entityManager->getStorage('taxonomy_term')->create(array( + ])->save(); + $term = $this->entityManager->getStorage('taxonomy_term')->create([ 'name' => 'test', 'vid' => 'tags', - )); + ]); $violations = $term->validate(); $this->assertEqual(count($violations), 0, 'No violations when validating a default term.'); @@ -46,7 +46,7 @@ public function testValidation() { $this->assertEqual(count($violations), 1, 'Violation found when name is too long.'); $this->assertEqual($violations[0]->getPropertyPath(), 'name.0.value'); $field_label = $term->get('name')->getFieldDefinition()->getLabel(); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => $field_label, '@max' => 255))); + $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', ['%name' => $field_label, '@max' => 255])); $term->set('name', NULL); $violations = $term->validate(); @@ -58,7 +58,7 @@ public function testValidation() { $term->set('parent', 9999); $violations = $term->validate(); $this->assertEqual(count($violations), 1, 'Violation found when term parent is invalid.'); - $this->assertEqual($violations[0]->getMessage(), format_string('The referenced entity (%type: %id) does not exist.', array('%type' => 'taxonomy_term', '%id' => 9999))); + $this->assertEqual($violations[0]->getMessage(), format_string('The referenced entity (%type: %id) does not exist.', ['%type' => 'taxonomy_term', '%id' => 9999])); $term->set('parent', 0); $violations = $term->validate(); diff --git a/core/modules/taxonomy/tests/src/Unit/Menu/TaxonomyLocalTasksTest.php b/core/modules/taxonomy/tests/src/Unit/Menu/TaxonomyLocalTasksTest.php index dcd49671..89423234 100644 --- a/core/modules/taxonomy/tests/src/Unit/Menu/TaxonomyLocalTasksTest.php +++ b/core/modules/taxonomy/tests/src/Unit/Menu/TaxonomyLocalTasksTest.php @@ -12,7 +12,7 @@ class TaxonomyLocalTasksTest extends LocalTaskIntegrationTestBase { protected function setUp() { - $this->directoryList = array('taxonomy' => 'core/modules/taxonomy'); + $this->directoryList = ['taxonomy' => 'core/modules/taxonomy']; parent::setUp(); } @@ -21,11 +21,13 @@ protected function setUp() { * * @dataProvider getTaxonomyPageRoutes */ - public function testTaxonomyPageLocalTasks($route, $subtask = array()) { - $tasks = array( - 0 => array('entity.taxonomy_term.canonical', 'entity.taxonomy_term.edit_form'), - ); - if ($subtask) $tasks[] = $subtask; + public function testTaxonomyPageLocalTasks($route, $subtask = []) { + $tasks = [ + 0 => ['entity.taxonomy_term.canonical', 'entity.taxonomy_term.edit_form'], + ]; + if ($subtask) { + $tasks[] = $subtask; + } $this->assertLocalTasks($route, $tasks); } @@ -33,10 +35,10 @@ public function testTaxonomyPageLocalTasks($route, $subtask = array()) { * Provides a list of routes to test. */ public function getTaxonomyPageRoutes() { - return array( - array('entity.taxonomy_term.canonical'), - array('entity.taxonomy_term.edit_form'), - ); + return [ + ['entity.taxonomy_term.canonical'], + ['entity.taxonomy_term.edit_form'], + ]; } } diff --git a/core/modules/taxonomy/tests/src/Unit/Plugin/migrate/cckfield/TaxonomyTermReferenceCckTest.php b/core/modules/taxonomy/tests/src/Unit/Plugin/migrate/cckfield/TaxonomyTermReferenceCckTest.php new file mode 100644 index 00000000..981969fc --- /dev/null +++ b/core/modules/taxonomy/tests/src/Unit/Plugin/migrate/cckfield/TaxonomyTermReferenceCckTest.php @@ -0,0 +1,63 @@ +plugin = new TaxonomyTermReference([], 'taxonomy', []); + + $migration = $this->prophesize(MigrationInterface::class); + + // The plugin's processCckFieldValues() method will call + // setProcessOfProperty() and return nothing. So, in order to examine the + // process pipeline created by the plugin, we need to ensure that + // getProcess() always returns the last input to setProcessOfProperty(). + $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) + ->will(function ($arguments) use ($migration) { + $migration->getProcess()->willReturn($arguments[1]); + }); + + $this->migration = $migration->reveal(); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessCckFieldValues() { + $this->plugin->processFieldValues($this->migration, 'somefieldname', []); + + $expected = [ + 'plugin' => 'iterator', + 'source' => 'somefieldname', + 'process' => [ + 'target_id' => 'tid', + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()); + } + +} diff --git a/core/modules/taxonomy/tests/src/Unit/Plugin/migrate/field/TaxonomyTermReferenceFieldTest.php b/core/modules/taxonomy/tests/src/Unit/Plugin/migrate/field/TaxonomyTermReferenceFieldTest.php new file mode 100644 index 00000000..974fc158 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Unit/Plugin/migrate/field/TaxonomyTermReferenceFieldTest.php @@ -0,0 +1,62 @@ +plugin = new TaxonomyTermReference([], 'taxonomy', []); + + $migration = $this->prophesize(MigrationInterface::class); + + // The plugin's processFieldValues() method will call + // setProcessOfProperty() and return nothing. So, in order to examine the + // process pipeline created by the plugin, we need to ensure that + // getProcess() always returns the last input to setProcessOfProperty(). + $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) + ->will(function ($arguments) use ($migration) { + $migration->getProcess()->willReturn($arguments[1]); + }); + + $this->migration = $migration->reveal(); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessFieldValues() { + $this->plugin->processFieldValues($this->migration, 'somefieldname', []); + + $expected = [ + 'plugin' => 'iterator', + 'source' => 'somefieldname', + 'process' => [ + 'target_id' => 'tid', + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()); + } + +} diff --git a/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php b/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php index f77b751e..afdf5414 100644 --- a/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php +++ b/core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php @@ -24,20 +24,20 @@ class TelephoneLinkFormatter extends FormatterBase { * {@inheritdoc} */ public static function defaultSettings() { - return array( + return [ 'title' => '', - ) + parent::defaultSettings(); + ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { - $elements['title'] = array( + $elements['title'] = [ '#type' => 'textfield', '#title' => t('Title to replace basic numeric telephone number display'), '#default_value' => $this->getSetting('title'), - ); + ]; return $elements; } @@ -46,11 +46,11 @@ public function settingsForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function settingsSummary() { - $summary = array(); + $summary = []; $settings = $this->getSettings(); if (!empty($settings['title'])) { - $summary[] = t('Link using text: @title', array('@title' => $settings['title'])); + $summary[] = t('Link using text: @title', ['@title' => $settings['title']]); } else { $summary[] = t('Link using provided telephone number.'); @@ -63,23 +63,23 @@ public function settingsSummary() { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $element = array(); + $element = []; $title_setting = $this->getSetting('title'); foreach ($items as $delta => $item) { // Render each element as link. - $element[$delta] = array( + $element[$delta] = [ '#type' => 'link', // Use custom title if available, otherwise use the telephone number // itself as title. '#title' => $title_setting ?: $item->value, // Prepend 'tel:' to the telephone number. '#url' => Url::fromUri('tel:' . rawurlencode(preg_replace('/\s+/', '', $item->value))), - '#options' => array('external' => TRUE), - ); + '#options' => ['external' => TRUE], + ]; if (!empty($item->_attributes)) { - $element[$delta]['#options'] += array('attributes' => array()); + $element[$delta]['#options'] += ['attributes' => []]; $element[$delta]['#options']['attributes'] += $item->_attributes; // Unset field item attributes since they have been included in the // formatter output and should not be rendered in the field template. diff --git a/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php b/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php index 20950e5f..f2aa1ccd 100644 --- a/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php +++ b/core/modules/telephone/src/Plugin/Field/FieldType/TelephoneItem.php @@ -25,14 +25,14 @@ class TelephoneItem extends FieldItemBase { * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'varchar', 'length' => 256, - ), - ), - ); + ], + ], + ]; } /** @@ -62,14 +62,14 @@ public function getConstraints() { $constraints = parent::getConstraints(); $max_length = 256; - $constraints[] = $constraint_manager->create('ComplexData', array( - 'value' => array( - 'Length' => array( + $constraints[] = $constraint_manager->create('ComplexData', [ + 'value' => [ + 'Length' => [ 'max' => $max_length, - 'maxMessage' => t('%name: the telephone number may not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => $max_length)), - ) - ), - )); + 'maxMessage' => t('%name: the telephone number may not be longer than @max characters.', ['%name' => $this->getFieldDefinition()->getLabel(), '@max' => $max_length]), + ] + ], + ]); return $constraints; } diff --git a/core/modules/telephone/src/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php b/core/modules/telephone/src/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php index f585067d..1ea1837d 100644 --- a/core/modules/telephone/src/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php +++ b/core/modules/telephone/src/Plugin/Field/FieldWidget/TelephoneDefaultWidget.php @@ -23,21 +23,21 @@ class TelephoneDefaultWidget extends WidgetBase { * {@inheritdoc} */ public static function defaultSettings() { - return array( + return [ 'placeholder' => '', - ) + parent::defaultSettings(); + ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { - $element['placeholder'] = array( + $element['placeholder'] = [ '#type' => 'textfield', '#title' => t('Placeholder'), '#default_value' => $this->getSetting('placeholder'), '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'), - ); + ]; return $element; } @@ -45,11 +45,11 @@ public function settingsForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function settingsSummary() { - $summary = array(); + $summary = []; $placeholder = $this->getSetting('placeholder'); if (!empty($placeholder)) { - $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder)); + $summary[] = t('Placeholder: @placeholder', ['@placeholder' => $placeholder]); } else { $summary[] = t('No placeholder'); @@ -62,11 +62,11 @@ public function settingsSummary() { * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - $element['value'] = $element + array( + $element['value'] = $element + [ '#type' => 'tel', '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL, '#placeholder' => $this->getSetting('placeholder'), - ); + ]; return $element; } diff --git a/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php b/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php new file mode 100644 index 00000000..3164cecd --- /dev/null +++ b/core/modules/telephone/src/Plugin/migrate/field/d7/PhoneField.php @@ -0,0 +1,16 @@ +' . t('About') . '

    '; - $output .= '

    ' . t('The Telephone module allows you to create fields that contain telephone numbers. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Telephone module.', array(':field' => \Drupal::url('help.page', array('name' => 'field')), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#', ':telephone_documentation' => 'https://www.drupal.org/documentation/modules/telephone')) . '

    '; + $output .= '

    ' . t('The Telephone module allows you to create fields that contain telephone numbers. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Telephone module.', [':field' => \Drupal::url('help.page', ['name' => 'field']), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#', ':telephone_documentation' => 'https://www.drupal.org/documentation/modules/telephone']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Managing and displaying telephone fields') . '
    '; - $output .= '
    ' . t('The settings and the display of the telephone field can be configured separately. See the Field UI help for more information on how to manage fields and their display.', array(':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#')) . '
    '; + $output .= '
    ' . t('The settings and the display of the telephone field can be configured separately. See the Field UI help for more information on how to manage fields and their display.', [':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#']) . '
    '; $output .= '
    ' . t('Displaying telephone numbers as links') . '
    '; $output .= '
    ' . t('Telephone numbers can be displayed as links with the scheme name tel: by choosing the Telephone display format on the Manage display page. Any spaces will be stripped out of the link text. This semantic markup improves the user experience on mobile and assistive technology devices.') . '
    '; $output .= '
    '; diff --git a/core/modules/telephone/src/Tests/TelephoneFieldTest.php b/core/modules/telephone/tests/src/Functional/TelephoneFieldTest.php similarity index 77% rename from core/modules/telephone/src/Tests/TelephoneFieldTest.php rename to core/modules/telephone/tests/src/Functional/TelephoneFieldTest.php index f7452b0b..18bedf07 100644 --- a/core/modules/telephone/src/Tests/TelephoneFieldTest.php +++ b/core/modules/telephone/tests/src/Functional/TelephoneFieldTest.php @@ -1,9 +1,9 @@ drupalCreateContentType(array('type' => 'article')); - $this->webUser = $this->drupalCreateUser(array('create article content', 'edit own article content')); + $this->drupalCreateContentType(['type' => 'article']); + $this->webUser = $this->drupalCreateUser(['create article content', 'edit own article content']); $this->drupalLogin($this->webUser); } @@ -44,14 +44,14 @@ protected function setUp() { /** * Helper function for testTelephoneField(). */ - function testTelephoneField() { + public function testTelephoneField() { // Add the telephone field to the article content type. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => 'field_telephone', 'entity_type' => 'node', 'type' => 'telephone', - ))->save(); + ])->save(); FieldConfig::create([ 'field_name' => 'field_telephone', 'label' => 'Telephone Number', @@ -60,19 +60,19 @@ function testTelephoneField() { ])->save(); entity_get_form_display('node', 'article', 'default') - ->setComponent('field_telephone', array( + ->setComponent('field_telephone', [ 'type' => 'telephone_default', - 'settings' => array( + 'settings' => [ 'placeholder' => '123-456-7890', - ), - )) + ], + ]) ->save(); entity_get_display('node', 'article', 'default') - ->setComponent('field_telephone', array( + ->setComponent('field_telephone', [ 'type' => 'telephone_link', 'weight' => 1, - )) + ]) ->save(); // Display creation form. @@ -81,19 +81,19 @@ function testTelephoneField() { $this->assertRaw('placeholder="123-456-7890"'); // Test basic entry of telephone field. - $edit = array( + $edit = [ 'title[0][value]' => $this->randomMachineName(), 'field_telephone[0][value]' => "123456789", - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertRaw('', 'A telephone link is provided on the article node page.'); // Add number with a space in it. Need to ensure it is stripped on output. - $edit = array( + $edit = [ 'title[0][value]' => $this->randomMachineName(), 'field_telephone[0][value]' => "1234 56789", - ); + ]; $this->drupalPostForm('node/add/article', $edit, t('Save')); $this->assertRaw('', 'Telephone link is output with whitespace removed.'); diff --git a/core/modules/telephone/tests/src/Kernel/TelephoneItemTest.php b/core/modules/telephone/tests/src/Kernel/TelephoneItemTest.php index 7f94ba3b..72269409 100644 --- a/core/modules/telephone/tests/src/Kernel/TelephoneItemTest.php +++ b/core/modules/telephone/tests/src/Kernel/TelephoneItemTest.php @@ -21,17 +21,17 @@ class TelephoneItemTest extends FieldKernelTestBase { * * @var array */ - public static $modules = array('telephone'); + public static $modules = ['telephone']; protected function setUp() { parent::setUp(); // Create a telephone field storage and field for validation. - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => 'field_test', 'entity_type' => 'entity_test', 'type' => 'telephone', - ))->save(); + ])->save(); FieldConfig::create([ 'entity_type' => 'entity_test', 'field_name' => 'field_test', diff --git a/core/modules/text/migration_templates/text_settings.yml b/core/modules/text/migration_templates/text_settings.yml index 45d426da..a38de856 100644 --- a/core/modules/text/migration_templates/text_settings.yml +++ b/core/modules/text/migration_templates/text_settings.yml @@ -7,6 +7,7 @@ source: plugin: variable variables: - teaser_length + source_module: text process: default_summary_length: teaser_length destination: diff --git a/core/modules/text/src/Plugin/Field/FieldFormatter/TextDefaultFormatter.php b/core/modules/text/src/Plugin/Field/FieldFormatter/TextDefaultFormatter.php index 0a781141..e7467169 100644 --- a/core/modules/text/src/Plugin/Field/FieldFormatter/TextDefaultFormatter.php +++ b/core/modules/text/src/Plugin/Field/FieldFormatter/TextDefaultFormatter.php @@ -24,17 +24,17 @@ class TextDefaultFormatter extends FormatterBase { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $elements = array(); + $elements = []; // The ProcessedText element already handles cache context & tag bubbling. // @see \Drupal\filter\Element\ProcessedText::preRenderText() foreach ($items as $delta => $item) { - $elements[$delta] = array( + $elements[$delta] = [ '#type' => 'processed_text', '#text' => $item->value, '#format' => $item->format, '#langcode' => $item->getLangcode(), - ); + ]; } return $elements; diff --git a/core/modules/text/src/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php b/core/modules/text/src/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php index 6d61faf1..5086a31d 100644 --- a/core/modules/text/src/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php +++ b/core/modules/text/src/Plugin/Field/FieldFormatter/TextSummaryOrTrimmedFormatter.php @@ -16,4 +16,4 @@ * } * ) */ -class TextSummaryOrTrimmedFormatter extends TextTrimmedFormatter { } +class TextSummaryOrTrimmedFormatter extends TextTrimmedFormatter {} diff --git a/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php b/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php index 8d69571a..65852382 100644 --- a/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php +++ b/core/modules/text/src/Plugin/Field/FieldFormatter/TextTrimmedFormatter.php @@ -33,24 +33,24 @@ class TextTrimmedFormatter extends FormatterBase { * {@inheritdoc} */ public static function defaultSettings() { - return array( + return [ 'trim_length' => '600', - ) + parent::defaultSettings(); + ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { - $element['trim_length'] = array( + $element['trim_length'] = [ '#title' => t('Trimmed limit'), '#type' => 'number', '#field_suffix' => t('characters'), '#default_value' => $this->getSetting('trim_length'), - '#description' => t('If the summary is not set, the trimmed %label field will end at the last full sentence before this character limit.', array('%label' => $this->fieldDefinition->getLabel())), + '#description' => t('If the summary is not set, the trimmed %label field will end at the last full sentence before this character limit.', ['%label' => $this->fieldDefinition->getLabel()]), '#min' => 1, '#required' => TRUE, - ); + ]; return $element; } @@ -58,8 +58,8 @@ public function settingsForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function settingsSummary() { - $summary = array(); - $summary[] = t('Trimmed limit: @trim_length characters', array('@trim_length' => $this->getSetting('trim_length'))); + $summary = []; + $summary[] = t('Trimmed limit: @trim_length characters', ['@trim_length' => $this->getSetting('trim_length')]); return $summary; } @@ -67,7 +67,7 @@ public function settingsSummary() { * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { - $elements = array(); + $elements = []; $render_as_summary = function (&$element) { // Make sure any default #pre_render callbacks are set on the element, @@ -82,12 +82,12 @@ public function viewElements(FieldItemListInterface $items, $langcode) { // The ProcessedText element already handles cache context & tag bubbling. // @see \Drupal\filter\Element\ProcessedText::preRenderText() foreach ($items as $delta => $item) { - $elements[$delta] = array( + $elements[$delta] = [ '#type' => 'processed_text', '#text' => NULL, '#format' => $item->format, '#langcode' => $item->getLangcode(), - ); + ]; if ($this->getPluginId() == 'text_summary_or_trimmed' && !empty($item->summary)) { $elements[$delta]['#text'] = $item->summary; diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextItem.php index ed896ad5..447a0b18 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextItem.php @@ -23,30 +23,30 @@ class TextItem extends TextItemBase { * {@inheritdoc} */ public static function defaultStorageSettings() { - return array( + return [ 'max_length' => 255, - ) + parent::defaultStorageSettings(); + ] + parent::defaultStorageSettings(); } /** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'varchar', 'length' => $field_definition->getSetting('max_length'), - ), - 'format' => array( + ], + 'format' => [ 'type' => 'varchar', 'length' => 255, - ), - ), - 'indexes' => array( - 'format' => array('format'), - ), - ); + ], + ], + 'indexes' => [ + 'format' => ['format'], + ], + ]; } /** @@ -57,14 +57,14 @@ public function getConstraints() { $constraints = parent::getConstraints(); if ($max_length = $this->getSetting('max_length')) { - $constraints[] = $constraint_manager->create('ComplexData', array( - 'value' => array( - 'Length' => array( + $constraints[] = $constraint_manager->create('ComplexData', [ + 'value' => [ + 'Length' => [ 'max' => $max_length, - 'maxMessage' => t('%name: the text may not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => $max_length)), - ) - ), - )); + 'maxMessage' => t('%name: the text may not be longer than @max characters.', ['%name' => $this->getFieldDefinition()->getLabel(), '@max' => $max_length]), + ] + ], + ]); } return $constraints; @@ -74,9 +74,9 @@ public function getConstraints() { * {@inheritdoc} */ public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) { - $element = array(); + $element = []; - $element['max_length'] = array( + $element['max_length'] = [ '#type' => 'number', '#title' => t('Maximum length'), '#default_value' => $this->getSetting('max_length'), @@ -84,7 +84,7 @@ public function storageSettingsForm(array &$form, FormStateInterface $form_state '#description' => t('The maximum length of the field in characters.'), '#min' => 1, '#disabled' => $has_data, - ); + ]; $element += parent::storageSettingsForm($form, $form_state, $has_data); return $element; diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php index 83cea4ff..6dd43392 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextItemBase.php @@ -39,7 +39,7 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel */ public function applyDefaultValue($notify = TRUE) { // @todo: Add in the filter default format here. - $this->setValue(array('format' => NULL), $notify); + $this->setValue(['format' => NULL], $notify); return $this; } @@ -82,11 +82,11 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin $value = substr($random->sentences(mt_rand(1, $settings['max_length'] / 3), FALSE), 0, $settings['max_length']); } - $values = array( + $values = [ 'value' => $value, 'summary' => $value, 'format' => filter_fallback_format(), - ); + ]; return $values; } diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php index cf1f6163..15e4eb6a 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextLongItem.php @@ -22,21 +22,21 @@ class TextLongItem extends TextItemBase { * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'text', 'size' => 'big', - ), - 'format' => array( + ], + 'format' => [ 'type' => 'varchar_ascii', 'length' => 255, - ), - ), - 'indexes' => array( - 'format' => array('format'), - ), - ); + ], + ], + 'indexes' => [ + 'format' => ['format'], + ], + ]; } } diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php index d42e3a78..6af6d043 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextWithSummaryItem.php @@ -24,9 +24,9 @@ class TextWithSummaryItem extends TextItemBase { * {@inheritdoc} */ public static function defaultFieldSettings() { - return array( + return [ 'display_summary' => 0, - ) + parent::defaultFieldSettings(); + ] + parent::defaultFieldSettings(); } /** @@ -52,25 +52,25 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'value' => array( + return [ + 'columns' => [ + 'value' => [ 'type' => 'text', 'size' => 'big', - ), - 'summary' => array( + ], + 'summary' => [ 'type' => 'text', 'size' => 'big', - ), - 'format' => array( + ], + 'format' => [ 'type' => 'varchar_ascii', 'length' => 255, - ), - ), - 'indexes' => array( - 'format' => array('format'), - ), - ); + ], + ], + 'indexes' => [ + 'format' => ['format'], + ], + ]; } /** @@ -85,15 +85,15 @@ public function isEmpty() { * {@inheritdoc} */ public function fieldSettingsForm(array $form, FormStateInterface $form_state) { - $element = array(); + $element = []; $settings = $this->getSettings(); - $element['display_summary'] = array( + $element['display_summary'] = [ '#type' => 'checkbox', '#title' => t('Summary input'), '#default_value' => $settings['display_summary'], '#description' => t('This allows authors to input an explicit summary, to be displayed instead of the automatically trimmed text when using the "Summary or trimmed" display type.'), - ); + ]; return $element; } diff --git a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php index 25bb6271..69a660e4 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWidget.php @@ -20,6 +20,15 @@ */ class TextareaWidget extends StringTextareaWidget { + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $element = parent::settingsForm($form, $form_state); + $element['rows']['#description'] = $this->t('Text editors (like CKEditor) may override this setting.'); + return $element; + } + /** * {@inheritdoc} */ @@ -37,7 +46,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen * {@inheritdoc} */ public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) { - if ($violation->arrayPropertyPath == array('format') && isset($element['format']['#access']) && !$element['format']['#access']) { + if ($violation->arrayPropertyPath == ['format'] && isset($element['format']['#access']) && !$element['format']['#access']) { // Ignore validation errors for formats if formats may not be changed, // i.e. when existing formats become invalid. See filter_process_format(). return FALSE; diff --git a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php index 0a72e3e5..f41e5b1e 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextareaWithSummaryWidget.php @@ -23,11 +23,11 @@ class TextareaWithSummaryWidget extends TextareaWidget { * {@inheritdoc} */ public static function defaultSettings() { - return array( + return [ 'rows' => '9', 'summary_rows' => '3', 'placeholder' => '', - ) + parent::defaultSettings(); + ] + parent::defaultSettings(); } /** @@ -35,13 +35,14 @@ public static function defaultSettings() { */ public function settingsForm(array $form, FormStateInterface $form_state) { $element = parent::settingsForm($form, $form_state); - $element['summary_rows'] = array( + $element['summary_rows'] = [ '#type' => 'number', '#title' => t('Summary rows'), '#default_value' => $this->getSetting('summary_rows'), + '#description' => $element['rows']['#description'], '#required' => TRUE, '#min' => 1, - ); + ]; return $element; } @@ -51,7 +52,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) { public function settingsSummary() { $summary = parent::settingsSummary(); - $summary[] = t('Number of summary rows: @rows', array('@rows' => $this->getSetting('summary_rows'))); + $summary[] = t('Number of summary rows: @rows', ['@rows' => $this->getSetting('summary_rows')]); return $summary; } @@ -59,24 +60,24 @@ public function settingsSummary() { /** * {@inheritdoc} */ - function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { + public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $element = parent::formElement($items, $delta, $element, $form, $form_state); $display_summary = $items[$delta]->summary || $this->getFieldSetting('display_summary'); - $element['summary'] = array( + $element['summary'] = [ '#type' => $display_summary ? 'textarea' : 'value', '#default_value' => $items[$delta]->summary, '#title' => t('Summary'), '#rows' => $this->getSetting('summary_rows'), '#description' => t('Leave blank to use trimmed value of full text as the summary.'), - '#attached' => array( - 'library' => array('text/drupal.text'), - ), - '#attributes' => array('class' => array('js-text-summary', 'text-summary')), + '#attached' => [ + 'library' => ['text/drupal.text'], + ], + '#attributes' => ['class' => ['js-text-summary', 'text-summary']], '#prefix' => '
    ', '#suffix' => '
    ', '#weight' => -10, - ); + ]; return $element; } diff --git a/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php b/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php index 5a3ed05b..af8493de 100644 --- a/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php +++ b/core/modules/text/src/Plugin/Field/FieldWidget/TextfieldWidget.php @@ -37,7 +37,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen * {@inheritdoc} */ public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) { - if ($violation->arrayPropertyPath == array('format') && isset($element['format']['#access']) && !$element['format']['#access']) { + if ($violation->arrayPropertyPath == ['format'] && isset($element['format']['#access']) && !$element['format']['#access']) { // Ignore validation errors for formats if formats may not be changed, // i.e. when existing formats become invalid. See filter_process_format(). return FALSE; diff --git a/core/modules/text/src/Plugin/migrate/cckfield/TextField.php b/core/modules/text/src/Plugin/migrate/cckfield/TextField.php index 89475ffd..e2511de8 100644 --- a/core/modules/text/src/Plugin/migrate/cckfield/TextField.php +++ b/core/modules/text/src/Plugin/migrate/cckfield/TextField.php @@ -2,6 +2,8 @@ namespace Drupal\text\Plugin\migrate\cckfield; +@trigger_error('TextField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\text\Plugin\migrate\field\d6\TextField or \Drupal\text\Plugin\migrate\field\d7\TextField instead.', E_USER_DEPRECATED); + use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Row; use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase; @@ -16,6 +18,12 @@ * }, * core = {6,7} * ) + * + * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use + * \Drupal\text\Plugin\migrate\field\d6\TextField or + * \Drupal\text\Plugin\migrate\field\d7\TextField instead. + * + * @see https://www.drupal.org/node/2751897 */ class TextField extends CckFieldPluginBase { @@ -43,7 +51,9 @@ public function getFieldFormatterMap() { * {@inheritdoc} */ public function processCckFieldValues(MigrationInterface $migration, $field_name, $field_info) { - if ($field_info['widget_type'] == 'optionwidgets_onoff') { + $widget_type = isset($field_info['widget_type']) ? $field_info['widget_type'] : $field_info['widget']['type']; + + if ($widget_type == 'optionwidgets_onoff') { $process = [ 'value' => [ 'plugin' => 'static_map', @@ -87,11 +97,11 @@ public function processCckFieldValues(MigrationInterface $migration, $field_name ]; } - $process = array( + $process = [ 'plugin' => 'iterator', 'source' => $field_name, 'process' => $process, - ); + ]; $migration->setProcessOfProperty($field_name, $process); } @@ -100,27 +110,29 @@ public function processCckFieldValues(MigrationInterface $migration, $field_name */ public function getFieldType(Row $row) { $widget_type = $row->getSourceProperty('widget_type'); + $settings = $row->getSourceProperty('global_settings'); if ($widget_type == 'text_textfield') { - $settings = $row->getSourceProperty('global_settings'); $field_type = $settings['text_processing'] ? 'text' : 'string'; if (empty($settings['max_length']) || $settings['max_length'] > 255) { $field_type .= '_long'; } return $field_type; } - else { - switch ($widget_type) { - case 'optionwidgets_buttons': - case 'optionwidgets_select': - return 'list_string'; - case 'optionwidgets_onoff': - return 'boolean'; - case 'text_textarea': - return 'text_long'; - default: - return parent::getFieldType($row); - } + + if ($widget_type == 'text_textarea') { + $field_type = $settings['text_processing'] ? 'text_long' : 'string_long'; + return $field_type; + } + + switch ($widget_type) { + case 'optionwidgets_buttons': + case 'optionwidgets_select': + return 'list_string'; + case 'optionwidgets_onoff': + return 'boolean'; + default: + return parent::getFieldType($row); } } diff --git a/core/modules/text/src/Plugin/migrate/field/d6/TextField.php b/core/modules/text/src/Plugin/migrate/field/d6/TextField.php new file mode 100644 index 00000000..62deeee1 --- /dev/null +++ b/core/modules/text/src/Plugin/migrate/field/d6/TextField.php @@ -0,0 +1,131 @@ + 'text_textfield', + ]; + } + + /** + * {@inheritdoc} + */ + public function getFieldFormatterMap() { + return [ + 'default' => 'text_default', + 'trimmed' => 'text_trimmed', + 'plain' => 'basic_string', + ]; + } + + /** + * {@inheritdoc} + */ + public function processFieldValues(MigrationInterface $migration, $field_name, $field_info) { + $widget_type = isset($field_info['widget_type']) ? $field_info['widget_type'] : $field_info['widget']['type']; + + if ($widget_type == 'optionwidgets_onoff') { + $process = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + ], + ]; + + $checked_value = explode("\n", $field_info['global_settings']['allowed_values'])[1]; + if (strpos($checked_value, '|') !== FALSE) { + $checked_value = substr($checked_value, 0, strpos($checked_value, '|')); + } + $process['value']['map'][$checked_value] = 1; + } + else { + // See \Drupal\migrate_drupal\Plugin\migrate\source\d6\User::baseFields(), + // signature_format for an example of the YAML that represents this + // process array. + $process = [ + 'value' => 'value', + 'format' => [ + [ + 'plugin' => 'static_map', + 'bypass' => TRUE, + 'source' => 'format', + 'map' => [0 => NULL], + ], + [ + 'plugin' => 'skip_on_empty', + 'method' => 'process', + ], + [ + 'plugin' => 'migration', + 'migration' => [ + 'd6_filter_format', + 'd7_filter_format', + ], + 'source' => 'format', + ], + ], + ]; + } + + $process = [ + 'plugin' => 'iterator', + 'source' => $field_name, + 'process' => $process, + ]; + $migration->setProcessOfProperty($field_name, $process); + } + + /** + * {@inheritdoc} + */ + public function getFieldType(Row $row) { + $widget_type = $row->getSourceProperty('widget_type'); + $settings = $row->getSourceProperty('global_settings'); + + if ($widget_type == 'text_textfield') { + $field_type = $settings['text_processing'] ? 'text' : 'string'; + if (empty($settings['max_length']) || $settings['max_length'] > 255) { + $field_type .= '_long'; + } + return $field_type; + } + + if ($widget_type == 'text_textarea') { + $field_type = $settings['text_processing'] ? 'text_long' : 'string_long'; + return $field_type; + } + + switch ($widget_type) { + case 'optionwidgets_buttons': + case 'optionwidgets_select': + return 'list_string'; + case 'optionwidgets_onoff': + return 'boolean'; + default: + return parent::getFieldType($row); + } + } + +} diff --git a/core/modules/text/src/Plugin/migrate/field/d7/TextField.php b/core/modules/text/src/Plugin/migrate/field/d7/TextField.php new file mode 100644 index 00000000..ccdedd42 --- /dev/null +++ b/core/modules/text/src/Plugin/migrate/field/d7/TextField.php @@ -0,0 +1,105 @@ +getFieldType($row); + $formatter_type = $row->getSourceProperty('formatter/type'); + + switch ($field_type) { + case 'string': + $formatter_type = str_replace('text_default', 'string', $formatter_type); + break; + case 'string_long': + $formatter_type = str_replace('text_default', 'basic_string', $formatter_type); + break; + } + + return $formatter_type; + } + + /** + * {@inheritdoc} + */ + public function getFieldWidgetType(Row $row) { + $field_type = $this->getFieldType($row); + $widget_type = $row->getSourceProperty('widget/type'); + + switch ($field_type) { + case 'string': + $widget_type = str_replace('text_textfield', 'string_textfield', $widget_type); + break; + case 'string_long': + $widget_type = str_replace('text_textarea', 'string_textarea', $widget_type); + break; + } + + return $widget_type; + } + + /** + * {@inheritdoc} + */ + public function getFieldType(Row $row) { + $type = $row->getSourceProperty('type'); + $plain_text = FALSE; + $filtered_text = FALSE; + + foreach ($row->getSourceProperty('instances') as $instance) { + // Check if this field has plain text instances, filtered text instances, + // or both. + $data = unserialize($instance['data']); + switch ($data['settings']['text_processing']) { + case '0': + $plain_text = TRUE; + break; + case '1': + $filtered_text = TRUE; + break; + } + } + + if (in_array($type, ['text', 'text_long'])) { + // If a text or text_long field has only plain text instances, migrate it + // to a string or string_long field. + if ($plain_text && !$filtered_text) { + $type = str_replace(['text', 'text_long'], ['string', 'string_long'], $type); + } + // If a text or text_long field has both plain text and filtered text + // instances, skip the row. + elseif ($plain_text && $filtered_text) { + $field_name = $row->getSourceProperty('field_name'); + throw new MigrateSkipRowException("Can't migrate source field $field_name configured with both plain text and filtered text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text"); + } + } + elseif ($type == 'text_with_summary' && $plain_text) { + // If a text_with_summary field has plain text instances, skip the row + // since there's no such thing as a string_with_summary field. + $field_name = $row->getSourceProperty('field_name'); + throw new MigrateSkipRowException("Can't migrate source field $field_name of type text_with_summary configured with plain text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text"); + } + + return $type; + } + +} diff --git a/core/modules/text/src/Tests/TextFieldTest.php b/core/modules/text/src/Tests/TextFieldTest.php index 993346a0..d061c00f 100644 --- a/core/modules/text/src/Tests/TextFieldTest.php +++ b/core/modules/text/src/Tests/TextFieldTest.php @@ -26,7 +26,7 @@ class TextFieldTest extends StringFieldTest { protected function setUp() { parent::setUp(); - $this->adminUser = $this->drupalCreateUser(array('administer filters')); + $this->adminUser = $this->drupalCreateUser(['administer filters']); } // Test fields. @@ -34,18 +34,18 @@ protected function setUp() { /** * Test text field validation. */ - function testTextFieldValidation() { + public function testTextFieldValidation() { // Create a field with settings to validate. $max_length = 3; $field_name = Unicode::strtolower($this->randomMachineName()); - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'text', - 'settings' => array( + 'settings' => [ 'max_length' => $max_length, - ) - )); + ] + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, @@ -69,14 +69,14 @@ function testTextFieldValidation() { /** * Test required long text with file upload. */ - function testRequiredLongTextWithFileUpload() { + public function testRequiredLongTextWithFileUpload() { // Create a text field. $text_field_name = 'text_long'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $text_field_name, 'entity_type' => 'entity_test', 'type' => 'text_with_summary', - )); + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, @@ -87,11 +87,11 @@ function testRequiredLongTextWithFileUpload() { // Create a file field. $file_field_name = 'file_field'; - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $file_field_name, 'entity_type' => 'entity_test', 'type' => 'file' - )); + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, @@ -100,12 +100,12 @@ function testRequiredLongTextWithFileUpload() { ])->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($text_field_name, array( + ->setComponent($text_field_name, [ 'type' => 'text_textarea_with_summary', - )) - ->setComponent($file_field_name, array( + ]) + ->setComponent($file_field_name, [ 'type' => 'file_generic', - )) + ]) ->save(); entity_get_display('entity_test', 'entity_test', 'full') ->setComponent($text_field_name) @@ -116,9 +116,9 @@ function testRequiredLongTextWithFileUpload() { $edit['files[file_field_0]'] = drupal_realpath($test_file->uri); $this->drupalPostForm('entity_test/add', $edit, 'Upload'); $this->assertResponse(200); - $edit = array( + $edit = [ 'text_long[0][value]' => 'Long text' - ); + ]; $this->drupalPostForm(NULL, $edit, 'Save'); $this->assertResponse(200); $this->drupalGet('entity_test/1'); @@ -128,7 +128,7 @@ function testRequiredLongTextWithFileUpload() { /** * Test widgets. */ - function testTextfieldWidgets() { + public function testTextfieldWidgets() { $this->_testTextfieldWidgets('text', 'text_textfield'); $this->_testTextfieldWidgets('text_long', 'text_textarea'); } @@ -136,7 +136,7 @@ function testTextfieldWidgets() { /** * Test widgets + 'formatted_text' setting. */ - function testTextfieldWidgetsFormatted() { + public function testTextfieldWidgetsFormatted() { $this->_testTextfieldWidgetsFormatted('text', 'text_textfield'); $this->_testTextfieldWidgetsFormatted('text_long', 'text_textarea'); } @@ -144,17 +144,17 @@ function testTextfieldWidgetsFormatted() { /** * Helper function for testTextfieldWidgetsFormatted(). */ - function _testTextfieldWidgetsFormatted($field_type, $widget_type) { + public function _testTextfieldWidgetsFormatted($field_type, $widget_type) { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); // Create a field. $field_name = Unicode::strtolower($this->randomMachineName()); - $field_storage = FieldStorageConfig::create(array( + $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => $field_type - )); + ]); $field_storage->save(); FieldConfig::create([ 'field_storage' => $field_storage, @@ -162,9 +162,9 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { 'label' => $this->randomMachineName() . '_label', ])->save(); entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( + ->setComponent($field_name, [ 'type' => $widget_type, - )) + ]) ->save(); entity_get_display('entity_test', 'entity_test', 'full') ->setComponent($field_name) @@ -174,7 +174,7 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { $this->drupalLogin($this->adminUser); foreach (filter_formats() as $format) { if (!$format->isFallbackFormat()) { - $this->drupalPostForm('admin/config/content/formats/manage/' . $format->id() . '/disable', array(), t('Disable')); + $this->drupalPostForm('admin/config/content/formats/manage/' . $format->id() . '/disable', [], t('Disable')); } } $this->drupalLogin($this->webUser); @@ -187,13 +187,13 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { // Submit with data that should be filtered. $value = '' . $this->randomMachineName() . ''; - $edit = array( + $edit = [ "{$field_name}[0][value]" => $value, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); preg_match('|entity_test/manage/(\d+)|', $this->url, $match); $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created'); + $this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created'); // Display the entity. $entity = EntityTest::load($id); @@ -206,10 +206,10 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { // Create a new text format that does not escape HTML, and grant the user // access to it. $this->drupalLogin($this->adminUser); - $edit = array( + $edit = [ 'format' => Unicode::strtolower($this->randomMachineName()), 'name' => $this->randomMachineName(), - ); + ]; $this->drupalPostForm('admin/config/content/formats/add', $edit, t('Save configuration')); filter_formats_reset(); $format = FilterFormat::load($edit['format']); @@ -217,7 +217,7 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { $permission = $format->getPermissionName(); $roles = $this->webUser->getRoles(); $rid = $roles[0]; - user_role_grant_permissions($rid, array($permission)); + user_role_grant_permissions($rid, [$permission]); $this->drupalLogin($this->webUser); // Display edition form. @@ -227,14 +227,14 @@ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { $this->assertFieldByName("{$field_name}[0][format]", NULL, 'Format selector is displayed'); // Edit and change the text format to the new one that was created. - $edit = array( + $edit = [ "{$field_name}[0][format]" => $format_id, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('entity_test @id has been updated.', array('@id' => $id)), 'Entity was updated'); + $this->assertText(t('entity_test @id has been updated.', ['@id' => $id]), 'Entity was updated'); // Display the entity. - $this->container->get('entity.manager')->getStorage('entity_test')->resetCache(array($id)); + $this->container->get('entity.manager')->getStorage('entity_test')->resetCache([$id]); $entity = EntityTest::load($id); $display = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'full'); $content = $display->build($entity); diff --git a/core/modules/text/tests/src/Kernel/Migrate/MigrateTextConfigsTest.php b/core/modules/text/tests/src/Kernel/Migrate/MigrateTextConfigsTest.php index 4a9d0d6e..05b37085 100644 --- a/core/modules/text/tests/src/Kernel/Migrate/MigrateTextConfigsTest.php +++ b/core/modules/text/tests/src/Kernel/Migrate/MigrateTextConfigsTest.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\text\Kernel\Migrate; -use Drupal\config\Tests\SchemaCheckTestTrait; +use Drupal\Tests\SchemaCheckTestTrait; use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase; /** diff --git a/core/modules/text/tests/src/Kernel/TextFormatterTest.php b/core/modules/text/tests/src/Kernel/TextFormatterTest.php index 747a06ff..c75ac34b 100644 --- a/core/modules/text/tests/src/Kernel/TextFormatterTest.php +++ b/core/modules/text/tests/src/Kernel/TextFormatterTest.php @@ -33,7 +33,7 @@ class TextFormatterTest extends EntityKernelTestBase { * * @var array */ - public static $modules = array('text'); + public static $modules = ['text']; /** * {@inheritdoc} @@ -41,23 +41,23 @@ class TextFormatterTest extends EntityKernelTestBase { protected function setUp() { parent::setUp(); - FilterFormat::create(array( + FilterFormat::create([ 'format' => 'my_text_format', 'name' => 'My text format', - 'filters' => array( - 'filter_autop' => array( + 'filters' => [ + 'filter_autop' => [ 'module' => 'filter', 'status' => TRUE, - ), - ), - ))->save(); + ], + ], + ])->save(); - FieldStorageConfig::create(array( + FieldStorageConfig::create([ 'field_name' => 'formatted_text', 'entity_type' => $this->entityType, 'type' => 'text', - 'settings' => array(), - ))->save(); + 'settings' => [], + ])->save(); FieldConfig::create([ 'entity_type' => $this->entityType, 'bundle' => $this->bundle, @@ -70,28 +70,28 @@ protected function setUp() { * Tests all text field formatters. */ public function testFormatters() { - $formatters = array( + $formatters = [ 'text_default', 'text_trimmed', 'text_summary_or_trimmed', - ); + ]; // Create the entity to be referenced. $entity = $this->container->get('entity_type.manager') ->getStorage($this->entityType) - ->create(array('name' => $this->randomMachineName())); - $entity->formatted_text = array( + ->create(['name' => $this->randomMachineName()]); + $entity->formatted_text = [ 'value' => 'Hello, world!', 'format' => 'my_text_format', - ); + ]; $entity->save(); foreach ($formatters as $formatter) { // Verify the text field formatter's render array. - $build = $entity->get('formatted_text')->view(array('type' => $formatter)); + $build = $entity->get('formatted_text')->view(['type' => $formatter]); \Drupal::service('renderer')->renderRoot($build[0]); $this->assertEqual($build[0]['#markup'], "

    Hello, world!

    \n"); - $this->assertEqual($build[0]['#cache']['tags'], FilterFormat::load('my_text_format')->getCacheTags(), format_string('The @formatter formatter has the expected cache tags when formatting a formatted text field.', array('@formatter' => $formatter))); + $this->assertEqual($build[0]['#cache']['tags'], FilterFormat::load('my_text_format')->getCacheTags(), format_string('The @formatter formatter has the expected cache tags when formatting a formatted text field.', ['@formatter' => $formatter])); } } diff --git a/core/modules/text/tests/src/Kernel/TextSummaryTest.php b/core/modules/text/tests/src/Kernel/TextSummaryTest.php index abc0b68b..dab6ed5d 100644 --- a/core/modules/text/tests/src/Kernel/TextSummaryTest.php +++ b/core/modules/text/tests/src/Kernel/TextSummaryTest.php @@ -12,12 +12,12 @@ */ class TextSummaryTest extends KernelTestBase { - public static $modules = array('system', 'user', 'filter', 'text'); + public static $modules = ['system', 'user', 'filter', 'text']; protected function setUp() { parent::setUp(); - $this->installConfig(array('text')); + $this->installConfig(['text']); } /** @@ -25,7 +25,7 @@ protected function setUp() { * subsequent sentences are not. This edge case is documented at * https://www.drupal.org/node/180425. */ - function testFirstSentenceQuestion() { + public function testFirstSentenceQuestion() { $text = 'A question? A sentence. Another sentence.'; $expected = 'A question? A sentence.'; $this->assertTextSummary($text, $expected, NULL, 30); @@ -34,11 +34,16 @@ function testFirstSentenceQuestion() { /** * Test summary with long example. */ - function testLongSentence() { - $text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . // 125 - 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . // 108 - 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' . // 103 - 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; // 110 + public function testLongSentence() { + // 125. + $text = + 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . + // 108. + 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . + // 103. + 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' . + // 110. + 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; $expected = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.'; @@ -49,26 +54,26 @@ function testLongSentence() { /** * Test various summary length edge cases. */ - function testLength() { - FilterFormat::create(array( + public function testLength() { + FilterFormat::create([ 'format' => 'autop', - 'filters' => array( - 'filter_autop' => array( + 'filters' => [ + 'filter_autop' => [ 'status' => 1, - ), - ), - ))->save(); - FilterFormat::create(array( + ], + ], + ])->save(); + FilterFormat::create([ 'format' => 'autop_correct', - 'filters' => array( - 'filter_autop' => array( + 'filters' => [ + 'filter_autop' => [ 'status' => 1, - ), - 'filter_htmlcorrector' => array( + ], + 'filter_htmlcorrector' => [ 'status' => 1, - ), - ), - ))->save(); + ], + ], + ])->save(); // This string tests a number of edge cases. $text = "

    \nHi\n

    \n

    \nfolks\n
    \n!\n

    "; @@ -205,12 +210,12 @@ function testLength() { /** * Calls text_summary() and asserts that the expected teaser is returned. */ - function assertTextSummary($text, $expected, $format = NULL, $size = NULL) { + public function assertTextSummary($text, $expected, $format = NULL, $size = NULL) { $summary = text_summary($text, $format, $size); - $this->assertIdentical($summary, $expected, format_string('
    @actual
    is identical to
    @expected
    ', array( + $this->assertIdentical($summary, $expected, format_string('
    @actual
    is identical to
    @expected
    ', [ '@actual' => $summary, '@expected' => $expected, - ))); + ])); } } diff --git a/core/modules/text/tests/src/Kernel/TextWithSummaryItemTest.php b/core/modules/text/tests/src/Kernel/TextWithSummaryItemTest.php index fc02daa7..a48c191b 100644 --- a/core/modules/text/tests/src/Kernel/TextWithSummaryItemTest.php +++ b/core/modules/text/tests/src/Kernel/TextWithSummaryItemTest.php @@ -21,7 +21,7 @@ class TextWithSummaryItemTest extends FieldKernelTestBase { * * @var array */ - public static $modules = array('filter'); + public static $modules = ['filter']; /** * Field storage entity. @@ -44,11 +44,11 @@ protected function setUp() { $this->installEntitySchema('entity_test_rev'); // Create the necessary formats. - $this->installConfig(array('filter')); - FilterFormat::create(array( + $this->installConfig(['filter']); + FilterFormat::create([ 'format' => 'no_filters', - 'filters' => array(), - ))->save(); + 'filters' => [], + ])->save(); } /** @@ -100,14 +100,14 @@ public function testCrudAndUpdate() { */ protected function createField($entity_type) { // Create a field . - $this->fieldStorage = FieldStorageConfig::create(array( + $this->fieldStorage = FieldStorageConfig::create([ 'field_name' => 'summary_field', 'entity_type' => $entity_type, 'type' => 'text_with_summary', - 'settings' => array( + 'settings' => [ 'max_length' => 10, - ) - )); + ] + ]); $this->fieldStorage->save(); $this->field = FieldConfig::create([ 'field_storage' => $this->fieldStorage, diff --git a/core/modules/text/tests/src/Unit/Migrate/TextCckTest.php b/core/modules/text/tests/src/Unit/Migrate/TextCckTest.php new file mode 100644 index 00000000..2d2c6550 --- /dev/null +++ b/core/modules/text/tests/src/Unit/Migrate/TextCckTest.php @@ -0,0 +1,167 @@ +plugin = new TextField([], 'text', []); + + $migration = $this->prophesize(MigrationInterface::class); + + // The plugin's processCckFieldValues() method will call + // setProcessOfProperty() and return nothing. So, in order to examine the + // process pipeline created by the plugin, we need to ensure that + // getProcess() always returns the last input to setProcessOfProperty(). + $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) + ->will(function ($arguments) use ($migration) { + $migration->getProcess()->willReturn($arguments[1]); + }); + + $this->migration = $migration->reveal(); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessFilteredTextFieldValues() { + $field_info = [ + 'widget_type' => 'text_textfield', + ]; + $this->plugin->processCckFieldValues($this->migration, 'body', $field_info); + + $process = $this->migration->getProcess(); + $this->assertSame('iterator', $process['plugin']); + $this->assertSame('body', $process['source']); + $this->assertSame('value', $process['process']['value']); + + // Ensure that filter format IDs will be looked up in the filter format + // migrations. + $lookup = $process['process']['format'][2]; + $this->assertSame('migration', $lookup['plugin']); + $this->assertContains('d6_filter_format', $lookup['migration']); + $this->assertContains('d7_filter_format', $lookup['migration']); + $this->assertSame('format', $lookup['source']); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessBooleanTextImplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo\nbar", + ] + ]; + $this->plugin->processCckFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'bar' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessBooleanTextExplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo|Foo\nbaz|Baz", + ] + ]; + $this->plugin->processCckFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'baz' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * Data provider for testGetFieldType(). + */ + public function getFieldTypeProvider() { + return [ + ['string_long', 'text_textfield', ['text_processing' => FALSE]], + ['string', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 128, + ], + ], + ['string_long', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 4096, + ], + ], + ['text_long', 'text_textfield', ['text_processing' => TRUE]], + ['text', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 128, + ], + ], + ['text_long', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 4096, + ], + ], + ['list_string', 'optionwidgets_buttons'], + ['list_string', 'optionwidgets_select'], + ['boolean', 'optionwidgets_onoff'], + ['text_long', 'text_textarea', ['text_processing' => TRUE]], + ['string_long', 'text_textarea', ['text_processing' => FALSE]], + [NULL, 'undefined'], + ]; + } + + /** + * @covers ::getFieldType + * @dataProvider getFieldTypeProvider + */ + public function testGetFieldType($expected_type, $widget_type, array $settings = []) { + $row = new Row(['widget_type' => $widget_type], ['widget_type' => []]); + $row->setSourceProperty('global_settings', $settings); + $this->assertSame($expected_type, $this->plugin->getFieldType($row)); + } + +} diff --git a/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php b/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php deleted file mode 100644 index 323fbce8..00000000 --- a/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php +++ /dev/null @@ -1,165 +0,0 @@ -plugin = new TextField([], 'text', []); - - $migration = $this->prophesize(MigrationInterface::class); - - // The plugin's processCckFieldValues() method will call - // setProcessOfProperty() and return nothing. So, in order to examine the - // process pipeline created by the plugin, we need to ensure that - // getProcess() always returns the last input to setProcessOfProperty(). - $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) - ->will(function($arguments) use ($migration) { - $migration->getProcess()->willReturn($arguments[1]); - }); - - $this->migration = $migration->reveal(); - } - - /** - * @covers ::processCckFieldValues - */ - public function testProcessFilteredTextFieldValues() { - $field_info = [ - 'widget_type' => 'text_textfield', - ]; - $this->plugin->processCckFieldValues($this->migration, 'body', $field_info); - - $process = $this->migration->getProcess(); - $this->assertSame('iterator', $process['plugin']); - $this->assertSame('body', $process['source']); - $this->assertSame('value', $process['process']['value']); - - // Ensure that filter format IDs will be looked up in the filter format - // migrations. - $lookup = $process['process']['format'][2]; - $this->assertSame('migration', $lookup['plugin']); - $this->assertContains('d6_filter_format', $lookup['migration']); - $this->assertContains('d7_filter_format', $lookup['migration']); - $this->assertSame('format', $lookup['source']); - } - - /** - * @covers ::processCckFieldValues - */ - public function testProcessBooleanTextImplicitValues() { - $info = array( - 'widget_type' => 'optionwidgets_onoff', - 'global_settings' => array( - 'allowed_values' => "foo\nbar", - ) - ); - $this->plugin->processCckFieldValues($this->migration, 'field', $info); - - $expected = [ - 'value' => [ - 'plugin' => 'static_map', - 'source' => 'value', - 'default_value' => 0, - 'map' => [ - 'bar' => 1, - ], - ], - ]; - $this->assertSame($expected, $this->migration->getProcess()['process']); - } - - /** - * @covers ::processCckFieldValues - */ - public function testProcessBooleanTextExplicitValues() { - $info = array( - 'widget_type' => 'optionwidgets_onoff', - 'global_settings' => array( - 'allowed_values' => "foo|Foo\nbaz|Baz", - ) - ); - $this->plugin->processCckFieldValues($this->migration, 'field', $info); - - $expected = [ - 'value' => [ - 'plugin' => 'static_map', - 'source' => 'value', - 'default_value' => 0, - 'map' => [ - 'baz' => 1, - ], - ], - ]; - $this->assertSame($expected, $this->migration->getProcess()['process']); - } - - /** - * Data provider for testGetFieldType(). - */ - public function getFieldTypeProvider() { - return array( - array('string_long', 'text_textfield', array( - 'text_processing' => FALSE, - )), - array('string', 'text_textfield', array( - 'text_processing' => FALSE, - 'max_length' => 128, - )), - array('string_long', 'text_textfield', array( - 'text_processing' => FALSE, - 'max_length' => 4096, - )), - array('text_long', 'text_textfield', array( - 'text_processing' => TRUE, - )), - array('text', 'text_textfield', array( - 'text_processing' => TRUE, - 'max_length' => 128, - )), - array('text_long', 'text_textfield', array( - 'text_processing' => TRUE, - 'max_length' => 4096, - )), - array('list_string', 'optionwidgets_buttons'), - array('list_string', 'optionwidgets_select'), - array('boolean', 'optionwidgets_onoff'), - array('text_long', 'text_textarea'), - array(NULL, 'undefined'), - ); - } - - /** - * @covers ::getFieldType - * @dataProvider getFieldTypeProvider - */ - public function testGetFieldType($expected_type, $widget_type, array $settings = array()) { - $row = new Row(array('widget_type' => $widget_type), array('widget_type' => array())); - $row->setSourceProperty('global_settings', $settings); - $this->assertSame($expected_type, $this->plugin->getFieldType($row)); - } - -} diff --git a/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php b/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php new file mode 100644 index 00000000..a49b9aff --- /dev/null +++ b/core/modules/text/tests/src/Unit/Migrate/d6/TextFieldTest.php @@ -0,0 +1,168 @@ +plugin = new TextField([], 'text', []); + + $migration = $this->prophesize(MigrationInterface::class); + + // The plugin's processFieldValues() method will call + // setProcessOfProperty() and return nothing. So, in order to examine the + // process pipeline created by the plugin, we need to ensure that + // getProcess() always returns the last input to setProcessOfProperty(). + $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) + ->will(function ($arguments) use ($migration) { + $migration->getProcess()->willReturn($arguments[1]); + }); + + $this->migration = $migration->reveal(); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessFilteredTextFieldValues() { + $field_info = [ + 'widget_type' => 'text_textfield', + ]; + $this->plugin->processFieldValues($this->migration, 'body', $field_info); + + $process = $this->migration->getProcess(); + $this->assertSame('iterator', $process['plugin']); + $this->assertSame('body', $process['source']); + $this->assertSame('value', $process['process']['value']); + + // Ensure that filter format IDs will be looked up in the filter format + // migrations. + $lookup = $process['process']['format'][2]; + $this->assertSame('migration', $lookup['plugin']); + $this->assertContains('d6_filter_format', $lookup['migration']); + $this->assertContains('d7_filter_format', $lookup['migration']); + $this->assertSame('format', $lookup['source']); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessBooleanTextImplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo\nbar", + ] + ]; + $this->plugin->processFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'bar' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessBooleanTextExplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo|Foo\nbaz|Baz", + ] + ]; + $this->plugin->processFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'baz' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * Data provider for testGetFieldType(). + */ + public function getFieldTypeProvider() { + return [ + ['string_long', 'text_textfield', ['text_processing' => FALSE]], + ['string', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 128, + ], + ], + ['string_long', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 4096, + ], + ], + ['text_long', 'text_textfield', ['text_processing' => TRUE]], + ['text', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 128, + ], + ], + ['text_long', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 4096, + ], + ], + ['list_string', 'optionwidgets_buttons'], + ['list_string', 'optionwidgets_select'], + ['boolean', 'optionwidgets_onoff'], + ['text_long', 'text_textarea', ['text_processing' => TRUE]], + ['string_long', 'text_textarea', ['text_processing' => FALSE]], + [NULL, 'undefined'], + ]; + } + + /** + * @covers ::getFieldType + * @dataProvider getFieldTypeProvider + */ + public function testGetFieldType($expected_type, $widget_type, array $settings = []) { + $row = new Row(); + $row->setSourceProperty('widget_type', $widget_type); + $row->setSourceProperty('global_settings', $settings); + $this->assertSame($expected_type, $this->plugin->getFieldType($row)); + } + +} diff --git a/core/modules/text/tests/src/Unit/Migrate/d7/TextFieldTest.php b/core/modules/text/tests/src/Unit/Migrate/d7/TextFieldTest.php new file mode 100644 index 00000000..5f7622fa --- /dev/null +++ b/core/modules/text/tests/src/Unit/Migrate/d7/TextFieldTest.php @@ -0,0 +1,12 @@ +plugin = new TextField([], 'text', []); + + $migration = $this->prophesize(MigrationInterface::class); + + // The plugin's processCckFieldValues() method will call + // setProcessOfProperty() and return nothing. So, in order to examine the + // process pipeline created by the plugin, we need to ensure that + // getProcess() always returns the last input to setProcessOfProperty(). + $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) + ->will(function ($arguments) use ($migration) { + $migration->getProcess()->willReturn($arguments[1]); + }); + + $this->migration = $migration->reveal(); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessFilteredTextFieldValues() { + $field_info = [ + 'widget_type' => 'text_textfield', + ]; + $this->plugin->processCckFieldValues($this->migration, 'body', $field_info); + + $process = $this->migration->getProcess(); + $this->assertSame('iterator', $process['plugin']); + $this->assertSame('body', $process['source']); + $this->assertSame('value', $process['process']['value']); + + // Ensure that filter format IDs will be looked up in the filter format + // migrations. + $lookup = $process['process']['format'][2]; + $this->assertSame('migration', $lookup['plugin']); + $this->assertContains('d6_filter_format', $lookup['migration']); + $this->assertContains('d7_filter_format', $lookup['migration']); + $this->assertSame('format', $lookup['source']); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessBooleanTextImplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo\nbar", + ] + ]; + $this->plugin->processCckFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'bar' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * @covers ::processCckFieldValues + */ + public function testProcessBooleanTextExplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo|Foo\nbaz|Baz", + ] + ]; + $this->plugin->processCckFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'baz' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * Data provider for testGetFieldType(). + */ + public function getFieldTypeProvider() { + return [ + ['string_long', 'text_textfield', ['text_processing' => FALSE]], + ['string', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 128, + ], + ], + ['string_long', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 4096, + ], + ], + ['text_long', 'text_textfield', ['text_processing' => TRUE]], + ['text', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 128, + ], + ], + ['text_long', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 4096, + ], + ], + ['list_string', 'optionwidgets_buttons'], + ['list_string', 'optionwidgets_select'], + ['boolean', 'optionwidgets_onoff'], + ['text_long', 'text_textarea', ['text_processing' => TRUE]], + ['string_long', 'text_textarea', ['text_processing' => FALSE]], + [NULL, 'undefined'], + ]; + } + + /** + * @covers ::getFieldType + * @dataProvider getFieldTypeProvider + */ + public function testGetFieldType($expected_type, $widget_type, array $settings = []) { + $row = new Row(['widget_type' => $widget_type], ['widget_type' => []]); + $row->setSourceProperty('global_settings', $settings); + $this->assertSame($expected_type, $this->plugin->getFieldType($row)); + } + +} diff --git a/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php b/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php new file mode 100644 index 00000000..83639892 --- /dev/null +++ b/core/modules/text/tests/src/Unit/Plugin/migrate/field/d6/TextFieldTest.php @@ -0,0 +1,167 @@ +plugin = new TextField([], 'text', []); + + $migration = $this->prophesize(MigrationInterface::class); + + // The plugin's processFieldValues() method will call + // setProcessOfProperty() and return nothing. So, in order to examine the + // process pipeline created by the plugin, we need to ensure that + // getProcess() always returns the last input to setProcessOfProperty(). + $migration->setProcessOfProperty(Argument::type('string'), Argument::type('array')) + ->will(function ($arguments) use ($migration) { + $migration->getProcess()->willReturn($arguments[1]); + }); + + $this->migration = $migration->reveal(); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessFilteredTextFieldValues() { + $field_info = [ + 'widget_type' => 'text_textfield', + ]; + $this->plugin->processFieldValues($this->migration, 'body', $field_info); + + $process = $this->migration->getProcess(); + $this->assertSame('iterator', $process['plugin']); + $this->assertSame('body', $process['source']); + $this->assertSame('value', $process['process']['value']); + + // Ensure that filter format IDs will be looked up in the filter format + // migrations. + $lookup = $process['process']['format'][2]; + $this->assertSame('migration', $lookup['plugin']); + $this->assertContains('d6_filter_format', $lookup['migration']); + $this->assertContains('d7_filter_format', $lookup['migration']); + $this->assertSame('format', $lookup['source']); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessBooleanTextImplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo\nbar", + ] + ]; + $this->plugin->processFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'bar' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * @covers ::processFieldValues + */ + public function testProcessBooleanTextExplicitValues() { + $info = [ + 'widget_type' => 'optionwidgets_onoff', + 'global_settings' => [ + 'allowed_values' => "foo|Foo\nbaz|Baz", + ] + ]; + $this->plugin->processFieldValues($this->migration, 'field', $info); + + $expected = [ + 'value' => [ + 'plugin' => 'static_map', + 'source' => 'value', + 'default_value' => 0, + 'map' => [ + 'baz' => 1, + ], + ], + ]; + $this->assertSame($expected, $this->migration->getProcess()['process']); + } + + /** + * Data provider for testGetFieldType(). + */ + public function getFieldTypeProvider() { + return [ + ['string_long', 'text_textfield', ['text_processing' => FALSE]], + ['string', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 128, + ], + ], + ['string_long', 'text_textfield', [ + 'text_processing' => FALSE, + 'max_length' => 4096, + ], + ], + ['text_long', 'text_textfield', ['text_processing' => TRUE]], + ['text', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 128, + ], + ], + ['text_long', 'text_textfield', [ + 'text_processing' => TRUE, + 'max_length' => 4096, + ], + ], + ['list_string', 'optionwidgets_buttons'], + ['list_string', 'optionwidgets_select'], + ['boolean', 'optionwidgets_onoff'], + ['text_long', 'text_textarea', ['text_processing' => TRUE]], + ['string_long', 'text_textarea', ['text_processing' => FALSE]], + [NULL, 'undefined'], + ]; + } + + /** + * @covers ::getFieldType + * @dataProvider getFieldTypeProvider + */ + public function testGetFieldType($expected_type, $widget_type, array $settings = []) { + $row = new Row(); + $row->setSourceProperty('widget_type', $widget_type); + $row->setSourceProperty('global_settings', $settings); + $this->assertSame($expected_type, $this->plugin->getFieldType($row)); + } + +} diff --git a/core/modules/text/tests/src/Unit/Plugin/migrate/field/d7/TextFieldTest.php b/core/modules/text/tests/src/Unit/Plugin/migrate/field/d7/TextFieldTest.php new file mode 100644 index 00000000..f1b21728 --- /dev/null +++ b/core/modules/text/tests/src/Unit/Plugin/migrate/field/d7/TextFieldTest.php @@ -0,0 +1,11 @@ +').prependTo($full); + } + + // Set up the edit/hide summary link. + const $link = $(` ()`); + const $button = $link.find('button'); + let toggleClick = true; + $link.on('click', (e) => { + if (toggleClick) { + $summary.hide(); + $button.html(Drupal.t('Edit summary')); + $link.appendTo($fullLabel); + } + else { + $summary.show(); + $button.html(Drupal.t('Hide summary')); + $link.appendTo($summaryLabel); + } + e.preventDefault(); + toggleClick = !toggleClick; + }).appendTo($summaryLabel); + + // If no summary is set, hide the summary field. + if ($widget.find('.js-text-summary').val() === '') { + $link.trigger('click'); + } + }); + }, + }; +}(jQuery, Drupal)); diff --git a/core/modules/text/text.info.yml b/core/modules/text/text.info.yml index 6fe1cb87..a5aee897 100644 --- a/core/modules/text/text.info.yml +++ b/core/modules/text/text.info.yml @@ -8,8 +8,8 @@ dependencies: - field - filter -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/text/text.js b/core/modules/text/text.js index ad89bd8a..c760f2dd 100644 --- a/core/modules/text/text.js +++ b/core/modules/text/text.js @@ -1,22 +1,13 @@ /** - * @file - * Text behaviors. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal) { - - 'use strict'; - - /** - * Auto-hide summary textarea if empty and show hide and unhide links. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches auto-hide behavior on `text-summary` events. - */ Drupal.behaviors.textSummary = { - attach: function (context, settings) { + attach: function attach(context, settings) { $(context).find('.js-text-summary').once('text-summary').each(function () { var $widget = $(this).closest('.js-text-format-wrapper'); @@ -25,13 +16,10 @@ var $full = $widget.find('.js-text-full').closest('.js-form-item'); var $fullLabel = $full.find('label').eq(0); - // Create a placeholder label when the field cardinality is greater - // than 1. if ($fullLabel.length === 0) { $fullLabel = $('').prependTo($full); } - // Set up the edit/hide summary link. var $link = $(' ()'); var $button = $link.find('button'); var toggleClick = true; @@ -40,8 +28,7 @@ $summary.hide(); $button.html(Drupal.t('Edit summary')); $link.appendTo($fullLabel); - } - else { + } else { $summary.show(); $button.html(Drupal.t('Hide summary')); $link.appendTo($summaryLabel); @@ -50,12 +37,10 @@ toggleClick = !toggleClick; }).appendTo($summaryLabel); - // If no summary is set, hide the summary field. if ($widget.find('.js-text-summary').val() === '') { $link.trigger('click'); } }); } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/modules/text/text.module b/core/modules/text/text.module index 906b4614..1932e616 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -18,11 +18,11 @@ function text_help($route_name, RouteMatchInterface $route_match) { case 'help.page.text': $output = ''; $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Text module allows you to create short and long text fields with optional summaries. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Text module.', array(':field' => \Drupal::url('help.page', array('name' => 'field')), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#', ':text_documentation' => 'https://www.drupal.org/documentation/modules/text')) . '

    '; + $output .= '

    ' . t('The Text module allows you to create short and long text fields with optional summaries. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Text module.', [':field' => \Drupal::url('help.page', ['name' => 'field']), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#', ':text_documentation' => 'https://www.drupal.org/documentation/modules/text']) . '

    '; $output .= '

    ' . t('Uses') . '

    '; $output .= '
    '; $output .= '
    ' . t('Managing and displaying text fields') . '
    '; - $output .= '
    ' . t('The settings and display of the text field can be configured separately. See the Field UI help for more information on how to manage fields and their display.', array(':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#')) . '
    '; + $output .= '
    ' . t('The settings and display of the text field can be configured separately. See the Field UI help for more information on how to manage fields and their display.', [':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#']) . '
    '; $output .= '
    ' . t('Creating short text fields') . '
    '; $output .= '
    ' . t('If you choose Text (plain) or Text (formatted) as the field type on the Manage fields page, then a field with a single row is displayed. You can change the maximum text length in the Field settings when you set up the field.') . '
    '; $output .= '
    ' . t('Creating long text fields') . '
    '; @@ -32,7 +32,7 @@ function text_help($route_name, RouteMatchInterface $route_match) { $output .= '
    ' . t('Displaying summaries instead of trimmed text') . '
    '; $output .= '
    ' . t('As an alternative to using a trimmed version of the text, you can enter a separate summary by choosing the Text (formatted, long, with summary) field type on the Manage fields page. Even when Summary input is enabled, and summaries are provided, you can display trimmed text nonetheless by choosing the appropriate format on the Manage display page.') . '
    '; $output .= '
    ' . t('Using text formats and editors') . '
    '; - $output .= '
    ' . t('If you choose Text (plain) or Text (plain, long) you restrict the input to Plain text only. If you choose Text (formatted), Text (formatted, long), or Text (formatted, long with summary) you allow users to write formatted text. Which options are available to individual users depends on the settings on the Text formats and editors page.', array(':formats' => \Drupal::url('filter.admin_overview'))) . '
    '; + $output .= '
    ' . t('If you choose Text (plain) or Text (plain, long) you restrict the input to Plain text only. If you choose Text (formatted), Text (formatted, long), or Text (formatted, long with summary) you allow users to write formatted text. Which options are available to individual users depends on the settings on the Text formats and editors page.', [':formats' => \Drupal::url('filter.admin_overview')]) . '
    '; $output .= '
    '; return $output; } @@ -115,13 +115,13 @@ function text_summary($text, $format = NULL, $size = NULL) { $reversed = strrev($summary); // Build an array of arrays of break points grouped by preference. - $break_points = array(); + $break_points = []; // A paragraph near the end of sliced summary is most preferable. - $break_points[] = array('

    ' => 0); + $break_points[] = ['

    ' => 0]; // If no complete paragraph then treat line breaks as paragraphs. - $line_breaks = array('
    ' => 6, '
    ' => 4); + $line_breaks = ['
    ' => 6, '
    ' => 4]; // Newline only indicates a line break if line break converter // filter is present. if (isset($format) && $filters->has('filter_autop') && $filters->get('filter_autop')->status) { @@ -130,7 +130,7 @@ function text_summary($text, $format = NULL, $size = NULL) { $break_points[] = $line_breaks; // If the first paragraph is too long, split at the end of a sentence. - $break_points[] = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1); + $break_points[] = ['. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1]; // Iterate over the groups of break points until a break point is found. foreach ($break_points as $points) { diff --git a/core/modules/toolbar/css/toolbar.icons.theme.css b/core/modules/toolbar/css/toolbar.icons.theme.css index c52f8682..54248a26 100644 --- a/core/modules/toolbar/css/toolbar.icons.theme.css +++ b/core/modules/toolbar/css/toolbar.icons.theme.css @@ -219,7 +219,6 @@ background-color: #f5f5f5; } - /** * Handle. */ @@ -280,8 +279,7 @@ background-image: url(../../../misc/icons/bebebe/push-left.svg); /* LTR */ } .toolbar .toolbar-toggle-orientation [value="vertical"]:hover:before, -.toolbar .toolbar-toggle-orientation [value="vertical"]:focus:before - { +.toolbar .toolbar-toggle-orientation [value="vertical"]:focus:before { background-image: url(../../../misc/icons/787878/push-left.svg); /* LTR */ } [dir="rtl"] .toolbar .toolbar-toggle-orientation [value="vertical"]:before { diff --git a/core/modules/toolbar/css/toolbar.menu.css b/core/modules/toolbar/css/toolbar.menu.css index 099fb084..b4e8b2ef 100644 --- a/core/modules/toolbar/css/toolbar.menu.css +++ b/core/modules/toolbar/css/toolbar.menu.css @@ -13,11 +13,26 @@ position: relative; width: auto; } -.toolbar .toolbar-tray-horizontal .toolbar-menu .toolbar-handle, -.toolbar .toolbar-tray-horizontal .toolbar-menu ul, + +/** + * Hidden vertical toolbar sub-menus by default. + */ .toolbar .toolbar-tray-vertical .toolbar-menu ul { display: none; } + +/** + * Hidden horizontal toolbar handle icon. + */ +.toolbar .toolbar-tray-horizontal .toolbar-menu .toolbar-handle { + display: none; +} +/** + * Hidden toolbar sub-menus by default. + */ +.toolbar-tray-open .toolbar-menu .menu-item--expanded ul { + display: none; +} .toolbar .toolbar-tray-vertical li.open > ul { display: block; /* Show the sub-menus */ } diff --git a/core/modules/toolbar/css/toolbar.module.css b/core/modules/toolbar/css/toolbar.module.css index 69eb7c22..14d0cf0e 100644 --- a/core/modules/toolbar/css/toolbar.module.css +++ b/core/modules/toolbar/css/toolbar.module.css @@ -21,7 +21,9 @@ display: none; } } - +.toolbar-loading #toolbar-administration { + overflow: hidden; +} /** * Very specific overrides for Drupal system CSS. */ @@ -56,18 +58,44 @@ position: relative; z-index: 1250; } +.toolbar-horizontal .toolbar-tray { + position: fixed; + width: 100%; + left: 0; +} /* Position the admin toolbar absolutely when the configured standard breakpoint * is active. The toolbar container, that contains the bar and the trays, is * position absolutely so that it scrolls with the page. Otherwise, on smaller * screens, the components of the admin toolbar are positioned statically. */ -body.toolbar-fixed .toolbar-oriented, -.toolbar-oriented .toolbar-bar, -.toolbar-oriented .toolbar-tray { +.toolbar-oriented .toolbar-bar { left: 0; position: absolute; right: 0; top: 0; } +.toolbar-oriented .toolbar-tray { + left: 0; + position: absolute; + right: 0; +} +/* .toolbar-loading is required by toolbar JavaScript to pre-render markup + * style to avoid extra reflow & flicker. */ +@media (min-width: 61em) { + .toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray { + position: relative; + display: block; + z-index: -999; + visibility: hidden; + width: 1px; + } + .toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray .toolbar-lining { + width: 999em; + } + .toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .home-toolbar-tab + .toolbar-tab .toolbar-tray { + display: block; + } +} + /* Layer the bar just above the trays and above contextual link triggers. */ .toolbar-oriented .toolbar-bar { z-index: 502; @@ -85,13 +113,16 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { width: 240px; width: 15rem; } + /* Present the admin toolbar tabs horizontally as a default on user agents that * do not understand media queries or on user agents where JavaScript is * disabled. */ +.toolbar-loading.toolbar-horizontal .toolbar .toolbar-tray .toolbar-menu > li, .toolbar .toolbar-bar .toolbar-tab, .toolbar .toolbar-tray-horizontal li { float: left; /* LTR */ } +[dir="rtl"] .toolbar-loading.toolbar-horizontal .toolbar .toolbar-tray .toolbar-menu > li, [dir="rtl"] .toolbar .toolbar-bar .toolbar-tab, [dir="rtl"] .toolbar .toolbar-tray-horizontal li { float: right; @@ -111,7 +142,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { /* This min-width media query is meant to provide basic horizontal layout to * the main menu tabs when JavaScript is disabled on user agents that understand * media queries. */ -@media (min-width:16.5em) { +@media (min-width: 16.5em) { .toolbar .toolbar-bar .toolbar-tab, .toolbar .toolbar-tray-horizontal li { float: left; /* LTR */ @@ -171,7 +202,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { right: 0; } /* Layer the links just above the toolbar-tray. */ -.toolbar .toolbar-bar .toolbar-tab > .toolbar-icon{ +.toolbar .toolbar-bar .toolbar-tab > .toolbar-icon { position: relative; z-index: 502; } @@ -179,15 +210,10 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { .toolbar-oriented .toolbar-tray-horizontal .menu-item ul { display: none; } -/* When the configured standard breakpoint is active and the tray is in a - * horizontal position, the tray is fixed to the top of the viewport and does - * not scroll with the page contents. */ -body.toolbar-fixed .toolbar .toolbar-tray-horizontal { - position: fixed; -} /* When the configured standard breakpoint is active and the tray is in a * vertical position, the tray does not scroll with the page. The contents of - * the tray scroll within the confines of the viewport. */ + * the tray scroll within the confines of the viewport. + */ .toolbar .toolbar-tray-vertical.is-active, body.toolbar-fixed .toolbar .toolbar-tray-vertical { height: 100%; @@ -258,3 +284,13 @@ body.toolbar-tray-open.toolbar-vertical.toolbar-fixed { [dir="rtl"] .toolbar-oriented .toolbar-tray-vertical .toolbar-toggle-orientation { float: left; } + +/** + * Toolbar home button toggle. + */ +.toolbar .toolbar-bar .home-toolbar-tab { + display: none; +} +.path-admin .toolbar-bar .home-toolbar-tab { + display: block; +} diff --git a/core/modules/toolbar/css/toolbar.theme.css b/core/modules/toolbar/css/toolbar.theme.css index 981ee00a..3af712bd 100644 --- a/core/modules/toolbar/css/toolbar.theme.css +++ b/core/modules/toolbar/css/toolbar.theme.css @@ -20,7 +20,8 @@ line-height: 1em; text-decoration: none; } -.toolbar .toolbar-item:hover, .toolbar .toolbar-item:focus { +.toolbar .toolbar-item:hover, +.toolbar .toolbar-item:focus { text-decoration: underline; } @@ -57,10 +58,10 @@ .toolbar .toolbar-tray { background-color: #ffffff; } -.toolbar .toolbar-tray-horizontal > .toolbar-lining { +.toolbar-horizontal .toolbar-tray > .toolbar-lining { padding-right: 5em; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal > .toolbar-lining { +[dir="rtl"] .toolbar-horizontal .toolbar-tray > .toolbar-lining { padding-right: 0; padding-left: 5em; } @@ -74,11 +75,11 @@ border-right: 0 none; box-shadow: 1px 0 5px 2px rgba(0, 0, 0, 0.3333); } -.toolbar .toolbar-tray-horizontal { +.toolbar-horizontal .toolbar-tray { border-bottom: 1px solid #aaaaaa; box-shadow: -2px 1px 3px 1px rgba(0, 0, 0, 0.3333); /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal { +[dir="rtl"] .toolbar-horizontal .toolbar-tray { box-shadow: 2px 1px 3px 1px rgba(0, 0, 0, 0.3333); } .toolbar .toolbar-tray-horizontal .toolbar-tray { @@ -93,25 +94,24 @@ .toolbar-tray a:hover, .toolbar-tray a:active, .toolbar-tray a:focus, -.toolbar-tray a.is-active - { +.toolbar-tray a.is-active { color: #000; text-decoration: underline; } .toolbar .toolbar-menu { background-color: #ffffff; } -.toolbar .toolbar-tray-horizontal .menu-item + .menu-item { +.toolbar-horizontal .toolbar-tray .menu-item + .menu-item { border-left: 1px solid #dddddd; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal .menu-item + .menu-item { - border-left: 0 none ; +[dir="rtl"] .toolbar-horizontal .toolbar-tray .menu-item + .menu-item { + border-left: 0 none; border-right: 1px solid #dddddd; } -.toolbar .toolbar-tray-horizontal .menu-item:last-child { +.toolbar-horizontal .toolbar-tray .menu-item:last-child { border-right: 1px solid #dddddd; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal .menu-item:last-child { +[dir="rtl"] .toolbar-horizontal .toolbar-tray .menu-item:last-child { border-left: 1px solid #dddddd; } .toolbar .toolbar-tray-vertical .menu-item + .menu-item { @@ -149,10 +149,10 @@ padding: 0; height: 100%; } -.toolbar .toolbar-tray-horizontal .toolbar-toggle-orientation { +.toolbar-horizontal .toolbar-tray .toolbar-toggle-orientation { border-left: 1px solid #c9c9c9; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal .toolbar-toggle-orientation { +[dir="rtl"] .toolbar-horizontal .toolbar-tray .toolbar-toggle-orientation { border-left: 0 none; border-right: 1px solid #c9c9c9; } diff --git a/core/modules/toolbar/js/escapeAdmin.es6.js b/core/modules/toolbar/js/escapeAdmin.es6.js new file mode 100644 index 00000000..c381f021 --- /dev/null +++ b/core/modules/toolbar/js/escapeAdmin.es6.js @@ -0,0 +1,43 @@ +/** + * @file + * Replaces the home link in toolbar with a back to site link. + */ + +(function ($, Drupal, drupalSettings) { + const pathInfo = drupalSettings.path; + const escapeAdminPath = sessionStorage.getItem('escapeAdminPath'); + const windowLocation = window.location; + + // Saves the last non-administrative page in the browser to be able to link + // back to it when browsing administrative pages. If there is a destination + // parameter there is not need to save the current path because the page is + // loaded within an existing "workflow". + if (!pathInfo.currentPathIsAdmin && !/destination=/.test(windowLocation.search)) { + sessionStorage.setItem('escapeAdminPath', windowLocation); + } + + /** + * Replaces the "Home" link with "Back to site" link. + * + * Back to site link points to the last non-administrative page the user + * visited within the same browser tab. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the replacement functionality to the toolbar-escape-admin element. + */ + Drupal.behaviors.escapeAdmin = { + attach() { + const $toolbarEscape = $('[data-toolbar-escape-admin]').once('escapeAdmin'); + if ($toolbarEscape.length && pathInfo.currentPathIsAdmin) { + if (escapeAdminPath !== null) { + $toolbarEscape.attr('href', escapeAdminPath); + } + else { + $toolbarEscape.text(Drupal.t('Home')); + } + } + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/toolbar/js/escapeAdmin.js b/core/modules/toolbar/js/escapeAdmin.js index 6e8f992f..b462be38 100644 --- a/core/modules/toolbar/js/escapeAdmin.js +++ b/core/modules/toolbar/js/escapeAdmin.js @@ -1,48 +1,29 @@ /** - * @file - * Replaces the home link in toolbar with a back to site link. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - var pathInfo = drupalSettings.path; var escapeAdminPath = sessionStorage.getItem('escapeAdminPath'); var windowLocation = window.location; - // Saves the last non-administrative page in the browser to be able to link - // back to it when browsing administrative pages. If there is a destination - // parameter there is not need to save the current path because the page is - // loaded within an existing "workflow". if (!pathInfo.currentPathIsAdmin && !/destination=/.test(windowLocation.search)) { sessionStorage.setItem('escapeAdminPath', windowLocation); } - /** - * Replaces the "Home" link with "Back to site" link. - * - * Back to site link points to the last non-administrative page the user - * visited within the same browser tab. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the replacement functionality to the toolbar-escape-admin element. - */ Drupal.behaviors.escapeAdmin = { - attach: function () { + attach: function attach() { var $toolbarEscape = $('[data-toolbar-escape-admin]').once('escapeAdmin'); if ($toolbarEscape.length && pathInfo.currentPathIsAdmin) { if (escapeAdminPath !== null) { $toolbarEscape.attr('href', escapeAdminPath); - } - else { + } else { $toolbarEscape.text(Drupal.t('Home')); } - $toolbarEscape.closest('.toolbar-tab').removeClass('hidden'); } } }; - -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/toolbar/js/models/MenuModel.es6.js b/core/modules/toolbar/js/models/MenuModel.es6.js new file mode 100644 index 00000000..a7898b40 --- /dev/null +++ b/core/modules/toolbar/js/models/MenuModel.es6.js @@ -0,0 +1,29 @@ +/** + * @file + * A Backbone Model for collapsible menus. + */ + +(function (Backbone, Drupal) { + /** + * Backbone Model for collapsible menus. + * + * @constructor + * + * @augments Backbone.Model + */ + Drupal.toolbar.MenuModel = Backbone.Model.extend(/** @lends Drupal.toolbar.MenuModel# */{ + + /** + * @type {object} + * + * @prop {object} subtrees + */ + defaults: /** @lends Drupal.toolbar.MenuModel# */{ + + /** + * @type {object} + */ + subtrees: {}, + }, + }); +}(Backbone, Drupal)); diff --git a/core/modules/toolbar/js/models/MenuModel.js b/core/modules/toolbar/js/models/MenuModel.js index 072a4f14..e3217fff 100644 --- a/core/modules/toolbar/js/models/MenuModel.js +++ b/core/modules/toolbar/js/models/MenuModel.js @@ -1,33 +1,14 @@ /** - * @file - * A Backbone Model for collapsible menus. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (Backbone, Drupal) { - - 'use strict'; - - /** - * Backbone Model for collapsible menus. - * - * @constructor - * - * @augments Backbone.Model - */ - Drupal.toolbar.MenuModel = Backbone.Model.extend(/** @lends Drupal.toolbar.MenuModel# */{ - - /** - * @type {object} - * - * @prop {object} subtrees - */ - defaults: /** @lends Drupal.toolbar.MenuModel# */{ - - /** - * @type {object} - */ + Drupal.toolbar.MenuModel = Backbone.Model.extend({ + defaults: { subtrees: {} } }); - -}(Backbone, Drupal)); +})(Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/toolbar/js/models/ToolbarModel.es6.js b/core/modules/toolbar/js/models/ToolbarModel.es6.js new file mode 100644 index 00000000..90c69d0b --- /dev/null +++ b/core/modules/toolbar/js/models/ToolbarModel.es6.js @@ -0,0 +1,153 @@ +/** + * @file + * A Backbone Model for the toolbar. + */ + +(function (Backbone, Drupal) { + /** + * Backbone model for the toolbar. + * + * @constructor + * + * @augments Backbone.Model + */ + Drupal.toolbar.ToolbarModel = Backbone.Model.extend(/** @lends Drupal.toolbar.ToolbarModel# */{ + + /** + * @type {object} + * + * @prop activeTab + * @prop activeTray + * @prop isOriented + * @prop isFixed + * @prop areSubtreesLoaded + * @prop isViewportOverflowConstrained + * @prop orientation + * @prop locked + * @prop isTrayToggleVisible + * @prop height + * @prop offsets + */ + defaults: /** @lends Drupal.toolbar.ToolbarModel# */{ + + /** + * The active toolbar tab. All other tabs should be inactive under + * normal circumstances. It will remain active across page loads. The + * active item is stored as an ID selector e.g. '#toolbar-item--1'. + * + * @type {string} + */ + activeTab: null, + + /** + * Represents whether a tray is open or not. Stored as an ID selector e.g. + * '#toolbar-item--1-tray'. + * + * @type {string} + */ + activeTray: null, + + /** + * Indicates whether the toolbar is displayed in an oriented fashion, + * either horizontal or vertical. + * + * @type {bool} + */ + isOriented: false, + + /** + * Indicates whether the toolbar is positioned absolute (false) or fixed + * (true). + * + * @type {bool} + */ + isFixed: false, + + /** + * Menu subtrees are loaded through an AJAX request only when the Toolbar + * is set to a vertical orientation. + * + * @type {bool} + */ + areSubtreesLoaded: false, + + /** + * If the viewport overflow becomes constrained, isFixed must be true so + * that elements in the trays aren't lost off-screen and impossible to + * get to. + * + * @type {bool} + */ + isViewportOverflowConstrained: false, + + /** + * The orientation of the active tray. + * + * @type {string} + */ + orientation: 'horizontal', + + /** + * A tray is locked if a user toggled it to vertical. Otherwise a tray + * will switch between vertical and horizontal orientation based on the + * configured breakpoints. The locked state will be maintained across page + * loads. + * + * @type {bool} + */ + locked: false, + + /** + * Indicates whether the tray orientation toggle is visible. + * + * @type {bool} + */ + isTrayToggleVisible: true, + + /** + * The height of the toolbar. + * + * @type {number} + */ + height: null, + + /** + * The current viewport offsets determined by {@link Drupal.displace}. The + * offsets suggest how a module might position is components relative to + * the viewport. + * + * @type {object} + * + * @prop {number} top + * @prop {number} right + * @prop {number} bottom + * @prop {number} left + */ + offsets: { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + }, + + /** + * @inheritdoc + * + * @param {object} attributes + * Attributes for the toolbar. + * @param {object} options + * Options for the toolbar. + * + * @return {string|undefined} + * Returns an error message if validation failed. + */ + validate(attributes, options) { + // Prevent the orientation being set to horizontal if it is locked, unless + // override has not been passed as an option. + if (attributes.orientation === 'horizontal' && this.get('locked') && !options.override) { + return Drupal.t('The toolbar cannot be set to a horizontal orientation when it is locked.'); + } + }, + }); +}(Backbone, Drupal)); diff --git a/core/modules/toolbar/js/models/ToolbarModel.js b/core/modules/toolbar/js/models/ToolbarModel.js index 537601d8..30ca577f 100644 --- a/core/modules/toolbar/js/models/ToolbarModel.js +++ b/core/modules/toolbar/js/models/ToolbarModel.js @@ -1,131 +1,33 @@ /** - * @file - * A Backbone Model for the toolbar. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (Backbone, Drupal) { - - 'use strict'; - - /** - * Backbone model for the toolbar. - * - * @constructor - * - * @augments Backbone.Model - */ - Drupal.toolbar.ToolbarModel = Backbone.Model.extend(/** @lends Drupal.toolbar.ToolbarModel# */{ - - /** - * @type {object} - * - * @prop activeTab - * @prop activeTray - * @prop isOriented - * @prop isFixed - * @prop areSubtreesLoaded - * @prop isViewportOverflowConstrained - * @prop orientation - * @prop locked - * @prop isTrayToggleVisible - * @prop height - * @prop offsets - */ - defaults: /** @lends Drupal.toolbar.ToolbarModel# */{ - - /** - * The active toolbar tab. All other tabs should be inactive under - * normal circumstances. It will remain active across page loads. The - * active item is stored as an ID selector e.g. '#toolbar-item--1'. - * - * @type {string} - */ + Drupal.toolbar.ToolbarModel = Backbone.Model.extend({ + defaults: { activeTab: null, - /** - * Represents whether a tray is open or not. Stored as an ID selector e.g. - * '#toolbar-item--1-tray'. - * - * @type {string} - */ activeTray: null, - /** - * Indicates whether the toolbar is displayed in an oriented fashion, - * either horizontal or vertical. - * - * @type {bool} - */ isOriented: false, - /** - * Indicates whether the toolbar is positioned absolute (false) or fixed - * (true). - * - * @type {bool} - */ isFixed: false, - /** - * Menu subtrees are loaded through an AJAX request only when the Toolbar - * is set to a vertical orientation. - * - * @type {bool} - */ areSubtreesLoaded: false, - /** - * If the viewport overflow becomes constrained, isFixed must be true so - * that elements in the trays aren't lost off-screen and impossible to - * get to. - * - * @type {bool} - */ isViewportOverflowConstrained: false, - /** - * The orientation of the active tray. - * - * @type {string} - */ - orientation: 'vertical', + orientation: 'horizontal', - /** - * A tray is locked if a user toggled it to vertical. Otherwise a tray - * will switch between vertical and horizontal orientation based on the - * configured breakpoints. The locked state will be maintained across page - * loads. - * - * @type {bool} - */ locked: false, - /** - * Indicates whether the tray orientation toggle is visible. - * - * @type {bool} - */ - isTrayToggleVisible: false, + isTrayToggleVisible: true, - /** - * The height of the toolbar. - * - * @type {number} - */ height: null, - /** - * The current viewport offsets determined by {@link Drupal.displace}. The - * offsets suggest how a module might position is components relative to - * the viewport. - * - * @type {object} - * - * @prop {number} top - * @prop {number} right - * @prop {number} bottom - * @prop {number} left - */ offsets: { top: 0, right: 0, @@ -134,24 +36,10 @@ } }, - /** - * @inheritdoc - * - * @param {object} attributes - * Attributes for the toolbar. - * @param {object} options - * Options for the toolbar. - * - * @return {string|undefined} - * Returns an error message if validation failed. - */ - validate: function (attributes, options) { - // Prevent the orientation being set to horizontal if it is locked, unless - // override has not been passed as an option. + validate: function validate(attributes, options) { if (attributes.orientation === 'horizontal' && this.get('locked') && !options.override) { return Drupal.t('The toolbar cannot be set to a horizontal orientation when it is locked.'); } } }); - -}(Backbone, Drupal)); +})(Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/toolbar/js/toolbar.es6.js b/core/modules/toolbar/js/toolbar.es6.js new file mode 100644 index 00000000..4fdf090f --- /dev/null +++ b/core/modules/toolbar/js/toolbar.es6.js @@ -0,0 +1,260 @@ +/** + * @file + * Defines the behavior of the Drupal administration toolbar. + */ + +(function ($, Drupal, drupalSettings) { + // Merge run-time settings with the defaults. + const options = $.extend( + { + breakpoints: { + 'toolbar.narrow': '', + 'toolbar.standard': '', + 'toolbar.wide': '', + }, + }, + drupalSettings.toolbar, + // Merge strings on top of drupalSettings so that they are not mutable. + { + strings: { + horizontal: Drupal.t('Horizontal orientation'), + vertical: Drupal.t('Vertical orientation'), + }, + }, + ); + + /** + * Registers tabs with the toolbar. + * + * The Drupal toolbar allows modules to register top-level tabs. These may + * point directly to a resource or toggle the visibility of a tray. + * + * Modules register tabs with hook_toolbar(). + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the toolbar rendering functionality to the toolbar element. + */ + Drupal.behaviors.toolbar = { + attach(context) { + // Verify that the user agent understands media queries. Complex admin + // toolbar layouts require media query support. + if (!window.matchMedia('only screen').matches) { + return; + } + // Process the administrative toolbar. + $(context).find('#toolbar-administration').once('toolbar').each(function () { + // Establish the toolbar models and views. + const model = Drupal.toolbar.models.toolbarModel = new Drupal.toolbar.ToolbarModel({ + locked: JSON.parse(localStorage.getItem('Drupal.toolbar.trayVerticalLocked')), + activeTab: document.getElementById(JSON.parse(localStorage.getItem('Drupal.toolbar.activeTabID'))), + height: $('#toolbar-administration').outerHeight(), + }); + + // Attach a listener to the configured media query breakpoints. + // Executes it before Drupal.toolbar.views to avoid extra rendering. + for (const label in options.breakpoints) { + if (options.breakpoints.hasOwnProperty(label)) { + const mq = options.breakpoints[label]; + const mql = Drupal.toolbar.mql[label] = window.matchMedia(mq); + // Curry the model and the label of the media query breakpoint to + // the mediaQueryChangeHandler function. + mql.addListener(Drupal.toolbar.mediaQueryChangeHandler.bind(null, model, label)); + // Fire the mediaQueryChangeHandler for each configured breakpoint + // so that they process once. + Drupal.toolbar.mediaQueryChangeHandler.call(null, model, label, mql); + } + } + + Drupal.toolbar.views.toolbarVisualView = new Drupal.toolbar.ToolbarVisualView({ + el: this, + model, + strings: options.strings, + }); + Drupal.toolbar.views.toolbarAuralView = new Drupal.toolbar.ToolbarAuralView({ + el: this, + model, + strings: options.strings, + }); + Drupal.toolbar.views.bodyVisualView = new Drupal.toolbar.BodyVisualView({ + el: this, + model, + }); + + // Force layout render to fix mobile view. Only needed on load, not + // for every media query match. + model.trigger('change:isFixed', model, model.get('isFixed')); + model.trigger('change:activeTray', model, model.get('activeTray')); + + // Render collapsible menus. + const menuModel = Drupal.toolbar.models.menuModel = new Drupal.toolbar.MenuModel(); + Drupal.toolbar.views.menuVisualView = new Drupal.toolbar.MenuVisualView({ + el: $(this).find('.toolbar-menu-administration').get(0), + model: menuModel, + strings: options.strings, + }); + + // Handle the resolution of Drupal.toolbar.setSubtrees. + // This is handled with a deferred so that the function may be invoked + // asynchronously. + Drupal.toolbar.setSubtrees.done((subtrees) => { + menuModel.set('subtrees', subtrees); + const theme = drupalSettings.ajaxPageState.theme; + localStorage.setItem(`Drupal.toolbar.subtrees.${theme}`, JSON.stringify(subtrees)); + // Indicate on the toolbarModel that subtrees are now loaded. + model.set('areSubtreesLoaded', true); + }); + + // Trigger an initial attempt to load menu subitems. This first attempt + // is made after the media query handlers have had an opportunity to + // process. The toolbar starts in the vertical orientation by default, + // unless the viewport is wide enough to accommodate a horizontal + // orientation. Thus we give the Toolbar a chance to determine if it + // should be set to horizontal orientation before attempting to load + // menu subtrees. + Drupal.toolbar.views.toolbarVisualView.loadSubtrees(); + + $(document) + // Update the model when the viewport offset changes. + .on('drupalViewportOffsetChange.toolbar', (event, offsets) => { + model.set('offsets', offsets); + }); + + // Broadcast model changes to other modules. + model + .on('change:orientation', (model, orientation) => { + $(document).trigger('drupalToolbarOrientationChange', orientation); + }) + .on('change:activeTab', (model, tab) => { + $(document).trigger('drupalToolbarTabChange', tab); + }) + .on('change:activeTray', (model, tray) => { + $(document).trigger('drupalToolbarTrayChange', tray); + }); + + // If the toolbar's orientation is horizontal and no active tab is + // defined then show the tray of the first toolbar tab by default (but + // not the first 'Home' toolbar tab). + if (Drupal.toolbar.models.toolbarModel.get('orientation') === 'horizontal' && Drupal.toolbar.models.toolbarModel.get('activeTab') === null) { + Drupal.toolbar.models.toolbarModel.set({ + activeTab: $('.toolbar-bar .toolbar-tab:not(.home-toolbar-tab) a').get(0), + }); + } + }); + }, + }; + + /** + * Toolbar methods of Backbone objects. + * + * @namespace + */ + Drupal.toolbar = { + + /** + * A hash of View instances. + * + * @type {object.} + */ + views: {}, + + /** + * A hash of Model instances. + * + * @type {object.} + */ + models: {}, + + /** + * A hash of MediaQueryList objects tracked by the toolbar. + * + * @type {object.} + */ + mql: {}, + + /** + * Accepts a list of subtree menu elements. + * + * A deferred object that is resolved by an inlined JavaScript callback. + * + * @type {jQuery.Deferred} + * + * @see toolbar_subtrees_jsonp(). + */ + setSubtrees: new $.Deferred(), + + /** + * Respond to configured narrow media query changes. + * + * @param {Drupal.toolbar.ToolbarModel} model + * A toolbar model + * @param {string} label + * Media query label. + * @param {object} mql + * A MediaQueryList object. + */ + mediaQueryChangeHandler(model, label, mql) { + switch (label) { + case 'toolbar.narrow': + model.set({ + isOriented: mql.matches, + isTrayToggleVisible: false, + }); + // If the toolbar doesn't have an explicit orientation yet, or if the + // narrow media query doesn't match then set the orientation to + // vertical. + if (!mql.matches || !model.get('orientation')) { + model.set({ orientation: 'vertical' }, { validate: true }); + } + break; + + case 'toolbar.standard': + model.set({ + isFixed: mql.matches, + }); + break; + + case 'toolbar.wide': + model.set({ + orientation: ((mql.matches && !model.get('locked')) ? 'horizontal' : 'vertical'), + }, { validate: true }); + // The tray orientation toggle visibility does not need to be + // validated. + model.set({ + isTrayToggleVisible: mql.matches, + }); + break; + + default: + break; + } + }, + }; + + /** + * A toggle is an interactive element often bound to a click handler. + * + * @return {string} + * A string representing a DOM fragment. + */ + Drupal.theme.toolbarOrientationToggle = function () { + return '
    ' + + '' + + '
    '; + }; + + /** + * Ajax command to set the toolbar subtrees. + * + * @param {Drupal.Ajax} ajax + * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. + * @param {object} response + * JSON response from the Ajax request. + * @param {number} [status] + * XMLHttpRequest status. + */ + Drupal.AjaxCommands.prototype.setToolbarSubtrees = function (ajax, response, status) { + Drupal.toolbar.setSubtrees.resolve(response.subtrees); + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js index 8accad97..4f4ff594 100644 --- a/core/modules/toolbar/js/toolbar.js +++ b/core/modules/toolbar/js/toolbar.js @@ -1,59 +1,48 @@ /** - * @file - * Defines the behavior of the Drupal administration toolbar. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - // Merge run-time settings with the defaults. - var options = $.extend( - { - breakpoints: { - 'toolbar.narrow': '', - 'toolbar.standard': '', - 'toolbar.wide': '' - } - }, - drupalSettings.toolbar, - // Merge strings on top of drupalSettings so that they are not mutable. - { - strings: { - horizontal: Drupal.t('Horizontal orientation'), - vertical: Drupal.t('Vertical orientation') - } + var options = $.extend({ + breakpoints: { + 'toolbar.narrow': '', + 'toolbar.standard': '', + 'toolbar.wide': '' + } + }, drupalSettings.toolbar, { + strings: { + horizontal: Drupal.t('Horizontal orientation'), + vertical: Drupal.t('Vertical orientation') } - ); + }); - /** - * Registers tabs with the toolbar. - * - * The Drupal toolbar allows modules to register top-level tabs. These may - * point directly to a resource or toggle the visibility of a tray. - * - * Modules register tabs with hook_toolbar(). - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the toolbar rendering functionality to the toolbar element. - */ Drupal.behaviors.toolbar = { - attach: function (context) { - // Verify that the user agent understands media queries. Complex admin - // toolbar layouts require media query support. + attach: function attach(context) { if (!window.matchMedia('only screen').matches) { return; } - // Process the administrative toolbar. - $(context).find('#toolbar-administration').once('toolbar').each(function () { - // Establish the toolbar models and views. + $(context).find('#toolbar-administration').once('toolbar').each(function () { var model = Drupal.toolbar.models.toolbarModel = new Drupal.toolbar.ToolbarModel({ - locked: JSON.parse(localStorage.getItem('Drupal.toolbar.trayVerticalLocked')) || false, - activeTab: document.getElementById(JSON.parse(localStorage.getItem('Drupal.toolbar.activeTabID'))) + locked: JSON.parse(localStorage.getItem('Drupal.toolbar.trayVerticalLocked')), + activeTab: document.getElementById(JSON.parse(localStorage.getItem('Drupal.toolbar.activeTabID'))), + height: $('#toolbar-administration').outerHeight() }); + + for (var label in options.breakpoints) { + if (options.breakpoints.hasOwnProperty(label)) { + var mq = options.breakpoints[label]; + var mql = Drupal.toolbar.mql[label] = window.matchMedia(mq); + + mql.addListener(Drupal.toolbar.mediaQueryChangeHandler.bind(null, model, label)); + + Drupal.toolbar.mediaQueryChangeHandler.call(null, model, label, mql); + } + } + Drupal.toolbar.views.toolbarVisualView = new Drupal.toolbar.ToolbarVisualView({ el: this, model: model, @@ -69,7 +58,9 @@ model: model }); - // Render collapsible menus. + model.trigger('change:isFixed', model, model.get('isFixed')); + model.trigger('change:activeTray', model, model.get('activeTray')); + var menuModel = Drupal.toolbar.models.menuModel = new Drupal.toolbar.MenuModel(); Drupal.toolbar.views.menuVisualView = new Drupal.toolbar.MenuVisualView({ el: $(this).find('.toolbar-menu-administration').get(0), @@ -77,61 +68,28 @@ strings: options.strings }); - // Handle the resolution of Drupal.toolbar.setSubtrees. - // This is handled with a deferred so that the function may be invoked - // asynchronously. Drupal.toolbar.setSubtrees.done(function (subtrees) { menuModel.set('subtrees', subtrees); var theme = drupalSettings.ajaxPageState.theme; localStorage.setItem('Drupal.toolbar.subtrees.' + theme, JSON.stringify(subtrees)); - // Indicate on the toolbarModel that subtrees are now loaded. + model.set('areSubtreesLoaded', true); }); - // Attach a listener to the configured media query breakpoints. - for (var label in options.breakpoints) { - if (options.breakpoints.hasOwnProperty(label)) { - var mq = options.breakpoints[label]; - var mql = Drupal.toolbar.mql[label] = window.matchMedia(mq); - // Curry the model and the label of the media query breakpoint to - // the mediaQueryChangeHandler function. - mql.addListener(Drupal.toolbar.mediaQueryChangeHandler.bind(null, model, label)); - // Fire the mediaQueryChangeHandler for each configured breakpoint - // so that they process once. - Drupal.toolbar.mediaQueryChangeHandler.call(null, model, label, mql); - } - } - - // Trigger an initial attempt to load menu subitems. This first attempt - // is made after the media query handlers have had an opportunity to - // process. The toolbar starts in the vertical orientation by default, - // unless the viewport is wide enough to accommodate a horizontal - // orientation. Thus we give the Toolbar a chance to determine if it - // should be set to horizontal orientation before attempting to load - // menu subtrees. Drupal.toolbar.views.toolbarVisualView.loadSubtrees(); - $(document) - // Update the model when the viewport offset changes. - .on('drupalViewportOffsetChange.toolbar', function (event, offsets) { - model.set('offsets', offsets); - }); + $(document).on('drupalViewportOffsetChange.toolbar', function (event, offsets) { + model.set('offsets', offsets); + }); - // Broadcast model changes to other modules. - model - .on('change:orientation', function (model, orientation) { - $(document).trigger('drupalToolbarOrientationChange', orientation); - }) - .on('change:activeTab', function (model, tab) { - $(document).trigger('drupalToolbarTabChange', tab); - }) - .on('change:activeTray', function (model, tray) { - $(document).trigger('drupalToolbarTrayChange', tray); - }); + model.on('change:orientation', function (model, orientation) { + $(document).trigger('drupalToolbarOrientationChange', orientation); + }).on('change:activeTab', function (model, tab) { + $(document).trigger('drupalToolbarTabChange', tab); + }).on('change:activeTray', function (model, tray) { + $(document).trigger('drupalToolbarTrayChange', tray); + }); - // If the toolbar's orientation is horizontal and no active tab is - // defined then show the tray of the first toolbar tab by default (but - // not the first 'Home' toolbar tab). if (Drupal.toolbar.models.toolbarModel.get('orientation') === 'horizontal' && Drupal.toolbar.models.toolbarModel.get('activeTab') === null) { Drupal.toolbar.models.toolbarModel.set({ activeTab: $('.toolbar-bar .toolbar-tab:not(.home-toolbar-tab) a').get(0) @@ -141,67 +99,25 @@ } }; - /** - * Toolbar methods of Backbone objects. - * - * @namespace - */ Drupal.toolbar = { - - /** - * A hash of View instances. - * - * @type {object.} - */ views: {}, - /** - * A hash of Model instances. - * - * @type {object.} - */ models: {}, - /** - * A hash of MediaQueryList objects tracked by the toolbar. - * - * @type {object.} - */ mql: {}, - /** - * Accepts a list of subtree menu elements. - * - * A deferred object that is resolved by an inlined JavaScript callback. - * - * @type {jQuery.Deferred} - * - * @see toolbar_subtrees_jsonp(). - */ setSubtrees: new $.Deferred(), - /** - * Respond to configured narrow media query changes. - * - * @param {Drupal.toolbar.ToolbarModel} model - * A toolbar model - * @param {string} label - * Media query label. - * @param {object} mql - * A MediaQueryList object. - */ - mediaQueryChangeHandler: function (model, label, mql) { + mediaQueryChangeHandler: function mediaQueryChangeHandler(model, label, mql) { switch (label) { case 'toolbar.narrow': model.set({ isOriented: mql.matches, isTrayToggleVisible: false }); - // If the toolbar doesn't have an explicit orientation yet, or if the - // narrow media query doesn't match then set the orientation to - // vertical. + if (!mql.matches || !model.get('orientation')) { - model.set({orientation: 'vertical'}, {validate: true}); + model.set({ orientation: 'vertical' }, { validate: true }); } break; @@ -213,10 +129,9 @@ case 'toolbar.wide': model.set({ - orientation: ((mql.matches) ? 'horizontal' : 'vertical') - }, {validate: true}); - // The tray orientation toggle visibility does not need to be - // validated. + orientation: mql.matches && !model.get('locked') ? 'horizontal' : 'vertical' + }, { validate: true }); + model.set({ isTrayToggleVisible: mql.matches }); @@ -228,30 +143,11 @@ } }; - /** - * A toggle is an interactive element often bound to a click handler. - * - * @return {string} - * A string representing a DOM fragment. - */ Drupal.theme.toolbarOrientationToggle = function () { - return '
    ' + - '' + - '
    '; + return '
    ' + '' + '
    '; }; - /** - * Ajax command to set the toolbar subtrees. - * - * @param {Drupal.Ajax} ajax - * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. - * @param {object} response - * JSON response from the Ajax request. - * @param {number} [status] - * XMLHttpRequest status. - */ Drupal.AjaxCommands.prototype.setToolbarSubtrees = function (ajax, response, status) { Drupal.toolbar.setSubtrees.resolve(response.subtrees); }; - -}(jQuery, Drupal, drupalSettings)); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/toolbar/js/toolbar.menu.es6.js b/core/modules/toolbar/js/toolbar.menu.es6.js new file mode 100644 index 00000000..03fd41f3 --- /dev/null +++ b/core/modules/toolbar/js/toolbar.menu.es6.js @@ -0,0 +1,192 @@ +/** + * @file + * Builds a nested accordion widget. + * + * Invoke on an HTML list element with the jQuery plugin pattern. + * + * @example + * $('.toolbar-menu').drupalToolbarMenu(); + */ + +(function ($, Drupal, drupalSettings) { + /** + * Store the open menu tray. + */ + let activeItem = Drupal.url(drupalSettings.path.currentPath); + + $.fn.drupalToolbarMenu = function () { + const ui = { + handleOpen: Drupal.t('Extend'), + handleClose: Drupal.t('Collapse'), + }; + + /** + * Handle clicks from the disclosure button on an item with sub-items. + * + * @param {Object} event + * A jQuery Event object. + */ + function toggleClickHandler(event) { + const $toggle = $(event.target); + const $item = $toggle.closest('li'); + // Toggle the list item. + toggleList($item); + // Close open sibling menus. + const $openItems = $item.siblings().filter('.open'); + toggleList($openItems, false); + } + + /** + * Handle clicks from a menu item link. + * + * @param {Object} event + * A jQuery Event object. + */ + function linkClickHandler(event) { + // If the toolbar is positioned fixed (and therefore hiding content + // underneath), then users expect clicks in the administration menu tray + // to take them to that destination but for the menu tray to be closed + // after clicking: otherwise the toolbar itself is obstructing the view + // of the destination they chose. + if (!Drupal.toolbar.models.toolbarModel.get('isFixed')) { + Drupal.toolbar.models.toolbarModel.set('activeTab', null); + } + // Stopping propagation to make sure that once a toolbar-box is clicked + // (the whitespace part), the page is not redirected anymore. + event.stopPropagation(); + } + + /** + * Toggle the open/close state of a list is a menu. + * + * @param {jQuery} $item + * The li item to be toggled. + * + * @param {Boolean} switcher + * A flag that forces toggleClass to add or a remove a class, rather than + * simply toggling its presence. + */ + function toggleList($item, switcher) { + const $toggle = $item.children('.toolbar-box').children('.toolbar-handle'); + switcher = (typeof switcher !== 'undefined') ? switcher : !$item.hasClass('open'); + // Toggle the item open state. + $item.toggleClass('open', switcher); + // Twist the toggle. + $toggle.toggleClass('open', switcher); + // Adjust the toggle text. + $toggle + .find('.action') + // Expand Structure, Collapse Structure. + .text((switcher) ? ui.handleClose : ui.handleOpen); + } + + /** + * Add markup to the menu elements. + * + * Items with sub-elements have a list toggle attached to them. Menu item + * links and the corresponding list toggle are wrapped with in a div + * classed with .toolbar-box. The .toolbar-box div provides a positioning + * context for the item list toggle. + * + * @param {jQuery} $menu + * The root of the menu to be initialized. + */ + function initItems($menu) { + const options = { + class: 'toolbar-icon toolbar-handle', + action: ui.handleOpen, + text: '', + }; + // Initialize items and their links. + $menu.find('li > a').wrap('
    '); + // Add a handle to each list item if it has a menu. + $menu.find('li').each((index, element) => { + const $item = $(element); + if ($item.children('ul.toolbar-menu').length) { + const $box = $item.children('.toolbar-box'); + options.text = Drupal.t('@label', { '@label': $box.find('a').text() }); + $item.children('.toolbar-box') + .append(Drupal.theme('toolbarMenuItemToggle', options)); + } + }); + } + + /** + * Adds a level class to each list based on its depth in the menu. + * + * This function is called recursively on each sub level of lists elements + * until the depth of the menu is exhausted. + * + * @param {jQuery} $lists + * A jQuery object of ul elements. + * + * @param {number} level + * The current level number to be assigned to the list elements. + */ + function markListLevels($lists, level) { + level = (!level) ? 1 : level; + const $lis = $lists.children('li').addClass(`level-${level}`); + $lists = $lis.children('ul'); + if ($lists.length) { + markListLevels($lists, level + 1); + } + } + + /** + * On page load, open the active menu item. + * + * Marks the trail of the active link in the menu back to the root of the + * menu with .menu-item--active-trail. + * + * @param {jQuery} $menu + * The root of the menu. + */ + function openActiveItem($menu) { + const pathItem = $menu.find(`a[href="${location.pathname}"]`); + if (pathItem.length && !activeItem) { + activeItem = location.pathname; + } + if (activeItem) { + const $activeItem = $menu.find(`a[href="${activeItem}"]`).addClass('menu-item--active'); + const $activeTrail = $activeItem.parentsUntil('.root', 'li').addClass('menu-item--active-trail'); + toggleList($activeTrail, true); + } + } + + // Return the jQuery object. + return this.each(function (selector) { + const $menu = $(this).once('toolbar-menu'); + if ($menu.length) { + // Bind event handlers. + $menu + .on('click.toolbar', '.toolbar-box', toggleClickHandler) + .on('click.toolbar', '.toolbar-box a', linkClickHandler); + + $menu.addClass('root'); + initItems($menu); + markListLevels($menu); + // Restore previous and active states. + openActiveItem($menu); + } + }); + }; + + /** + * A toggle is an interactive element often bound to a click handler. + * + * @param {object} options + * Options for the button. + * @param {string} options.class + * Class to set on the button. + * @param {string} options.action + * Action for the button. + * @param {string} options.text + * Used as label for the button. + * + * @return {string} + * A string representing a DOM fragment. + */ + Drupal.theme.toolbarMenuItemToggle = function (options) { + return ``; + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/modules/toolbar/js/toolbar.menu.js b/core/modules/toolbar/js/toolbar.menu.js index 0ca25a9b..45cfafbc 100644 --- a/core/modules/toolbar/js/toolbar.menu.js +++ b/core/modules/toolbar/js/toolbar.menu.js @@ -1,134 +1,69 @@ /** - * @file - * Builds a nested accordion widget. - * - * Invoke on an HTML list element with the jQuery plugin pattern. - * - * @example - * $('.toolbar-menu').drupalToolbarMenu(); - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings) { - - 'use strict'; - - /** - * Store the open menu tray. - */ var activeItem = Drupal.url(drupalSettings.path.currentPath); $.fn.drupalToolbarMenu = function () { - var ui = { handleOpen: Drupal.t('Extend'), handleClose: Drupal.t('Collapse') }; - /** - * Handle clicks from the disclosure button on an item with sub-items. - * - * @param {Object} event - * A jQuery Event object. - */ function toggleClickHandler(event) { var $toggle = $(event.target); var $item = $toggle.closest('li'); - // Toggle the list item. + toggleList($item); - // Close open sibling menus. + var $openItems = $item.siblings().filter('.open'); toggleList($openItems, false); } - /** - * Handle clicks from a menu item link. - * - * @param {Object} event - * A jQuery Event object. - */ function linkClickHandler(event) { - // If the toolbar is positioned fixed (and therefore hiding content - // underneath), then users expect clicks in the administration menu tray - // to take them to that destination but for the menu tray to be closed - // after clicking: otherwise the toolbar itself is obstructing the view - // of the destination they chose. if (!Drupal.toolbar.models.toolbarModel.get('isFixed')) { Drupal.toolbar.models.toolbarModel.set('activeTab', null); } - // Stopping propagation to make sure that once a toolbar-box is clicked - // (the whitespace part), the page is not redirected anymore. + event.stopPropagation(); } - /** - * Toggle the open/close state of a list is a menu. - * - * @param {jQuery} $item - * The li item to be toggled. - * - * @param {Boolean} switcher - * A flag that forces toggleClass to add or a remove a class, rather than - * simply toggling its presence. - */ function toggleList($item, switcher) { var $toggle = $item.children('.toolbar-box').children('.toolbar-handle'); - switcher = (typeof switcher !== 'undefined') ? switcher : !$item.hasClass('open'); - // Toggle the item open state. + switcher = typeof switcher !== 'undefined' ? switcher : !$item.hasClass('open'); + $item.toggleClass('open', switcher); - // Twist the toggle. + $toggle.toggleClass('open', switcher); - // Adjust the toggle text. - $toggle - .find('.action') - // Expand Structure, Collapse Structure. - .text((switcher) ? ui.handleClose : ui.handleOpen); + + $toggle.find('.action').text(switcher ? ui.handleClose : ui.handleOpen); } - /** - * Add markup to the menu elements. - * - * Items with sub-elements have a list toggle attached to them. Menu item - * links and the corresponding list toggle are wrapped with in a div - * classed with .toolbar-box. The .toolbar-box div provides a positioning - * context for the item list toggle. - * - * @param {jQuery} $menu - * The root of the menu to be initialized. - */ function initItems($menu) { var options = { class: 'toolbar-icon toolbar-handle', action: ui.handleOpen, text: '' }; - // Initialize items and their links. + $menu.find('li > a').wrap('
    '); - // Add a handle to each list item if it has a menu. + $menu.find('li').each(function (index, element) { var $item = $(element); if ($item.children('ul.toolbar-menu').length) { var $box = $item.children('.toolbar-box'); - options.text = Drupal.t('@label', {'@label': $box.find('a').text()}); - $item.children('.toolbar-box') - .append(Drupal.theme('toolbarMenuItemToggle', options)); + options.text = Drupal.t('@label', { '@label': $box.find('a').text() }); + $item.children('.toolbar-box').append(Drupal.theme('toolbarMenuItemToggle', options)); } }); } - /** - * Adds a level class to each list based on its depth in the menu. - * - * This function is called recursively on each sub level of lists elements - * until the depth of the menu is exhausted. - * - * @param {jQuery} $lists - * A jQuery object of ul elements. - * - * @param {number} level - * The current level number to be assigned to the list elements. - */ function markListLevels($lists, level) { - level = (!level) ? 1 : level; + level = !level ? 1 : level; var $lis = $lists.children('li').addClass('level-' + level); $lists = $lis.children('ul'); if ($lists.length) { @@ -136,15 +71,6 @@ } } - /** - * On page load, open the active menu item. - * - * Marks the trail of the active link in the menu back to the root of the - * menu with .menu-item--active-trail. - * - * @param {jQuery} $menu - * The root of the menu. - */ function openActiveItem($menu) { var pathItem = $menu.find('a[href="' + location.pathname + '"]'); if (pathItem.length && !activeItem) { @@ -157,41 +83,21 @@ } } - // Return the jQuery object. return this.each(function (selector) { var $menu = $(this).once('toolbar-menu'); if ($menu.length) { - // Bind event handlers. - $menu - .on('click.toolbar', '.toolbar-box', toggleClickHandler) - .on('click.toolbar', '.toolbar-box a', linkClickHandler); + $menu.on('click.toolbar', '.toolbar-box', toggleClickHandler).on('click.toolbar', '.toolbar-box a', linkClickHandler); $menu.addClass('root'); initItems($menu); markListLevels($menu); - // Restore previous and active states. + openActiveItem($menu); } }); }; - /** - * A toggle is an interactive element often bound to a click handler. - * - * @param {object} options - * Options for the button. - * @param {string} options.class - * Class to set on the button. - * @param {string} options.action - * Action for the button. - * @param {string} options.text - * Used as label for the button. - * - * @return {string} - * A string representing a DOM fragment. - */ Drupal.theme.toolbarMenuItemToggle = function (options) { - return ''; + return ''; }; - -}(jQuery, Drupal, drupalSettings)); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/toolbar/js/views/BodyVisualView.es6.js b/core/modules/toolbar/js/views/BodyVisualView.es6.js new file mode 100644 index 00000000..0b513c3e --- /dev/null +++ b/core/modules/toolbar/js/views/BodyVisualView.es6.js @@ -0,0 +1,37 @@ +/** + * @file + * A Backbone view for the body element. + */ + +(function ($, Drupal, Backbone) { + Drupal.toolbar.BodyVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.BodyVisualView# */{ + /** + * Adjusts the body element with the toolbar position and dimension changes. + * + * @constructs + * + * @augments Backbone.View + */ + initialize() { + this.listenTo(this.model, 'change:activeTray ', this.render); + this.listenTo(this.model, 'change:isFixed change:isViewportOverflowConstrained', this.isToolbarFixed); + }, + + isToolbarFixed() { + // When the toolbar is fixed, it will not scroll with page scrolling. + const isViewportOverflowConstrained = this.model.get('isViewportOverflowConstrained'); + $('body').toggleClass('toolbar-fixed', (isViewportOverflowConstrained || this.model.get('isFixed'))); + }, + + /** + * @inheritdoc + */ + render() { + $('body') + // Toggle the toolbar-tray-open class on the body element. The class is + // applied when a toolbar tray is active. Padding might be applied to + // the body element to prevent the tray from overlapping content. + .toggleClass('toolbar-tray-open', !!this.model.get('activeTray')); + }, + }); +}(jQuery, Drupal, Backbone)); diff --git a/core/modules/toolbar/js/views/BodyVisualView.js b/core/modules/toolbar/js/views/BodyVisualView.js index 64593c9c..71293844 100644 --- a/core/modules/toolbar/js/views/BodyVisualView.js +++ b/core/modules/toolbar/js/views/BodyVisualView.js @@ -1,53 +1,22 @@ /** - * @file - * A Backbone view for the body element. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, Backbone) { - - 'use strict'; - - Drupal.toolbar.BodyVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.BodyVisualView# */{ - - /** - * Adjusts the body element with the toolbar position and dimension changes. - * - * @constructs - * - * @augments Backbone.View - */ - initialize: function () { - this.listenTo(this.model, 'change:orientation change:offsets change:activeTray change:isOriented change:isFixed change:isViewportOverflowConstrained', this.render); + Drupal.toolbar.BodyVisualView = Backbone.View.extend({ + initialize: function initialize() { + this.listenTo(this.model, 'change:activeTray ', this.render); + this.listenTo(this.model, 'change:isFixed change:isViewportOverflowConstrained', this.isToolbarFixed); }, - - /** - * @inheritdoc - */ - render: function () { - var $body = $('body'); - var orientation = this.model.get('orientation'); - var isOriented = this.model.get('isOriented'); + isToolbarFixed: function isToolbarFixed() { var isViewportOverflowConstrained = this.model.get('isViewportOverflowConstrained'); - - $body - // We are using JavaScript to control media-query handling for two - // reasons: (1) Using JavaScript let's us leverage the breakpoint - // configurations and (2) the CSS is really complex if we try to hide - // some styling from browsers that don't understand CSS media queries. - // If we drive the CSS from classes added through JavaScript, - // then the CSS becomes simpler and more robust. - .toggleClass('toolbar-vertical', (orientation === 'vertical')) - .toggleClass('toolbar-horizontal', (isOriented && orientation === 'horizontal')) - // When the toolbar is fixed, it will not scroll with page scrolling. - .toggleClass('toolbar-fixed', (isViewportOverflowConstrained || this.model.get('isFixed'))) - // Toggle the toolbar-tray-open class on the body element. The class is - // applied when a toolbar tray is active. Padding might be applied to - // the body element to prevent the tray from overlapping content. - .toggleClass('toolbar-tray-open', !!this.model.get('activeTray')) - // Apply padding to the top of the body to offset the placement of the - // toolbar bar element. - .css('padding-top', this.model.get('offsets').top); + $('body').toggleClass('toolbar-fixed', isViewportOverflowConstrained || this.model.get('isFixed')); + }, + render: function render() { + $('body').toggleClass('toolbar-tray-open', !!this.model.get('activeTray')); } }); - -}(jQuery, Drupal, Backbone)); +})(jQuery, Drupal, Backbone); \ No newline at end of file diff --git a/core/modules/toolbar/js/views/MenuVisualView.es6.js b/core/modules/toolbar/js/views/MenuVisualView.es6.js new file mode 100644 index 00000000..e956112a --- /dev/null +++ b/core/modules/toolbar/js/views/MenuVisualView.es6.js @@ -0,0 +1,42 @@ +/** + * @file + * A Backbone view for the collapsible menus. + */ + +(function ($, Backbone, Drupal) { + Drupal.toolbar.MenuVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.MenuVisualView# */{ + + /** + * Backbone View for collapsible menus. + * + * @constructs + * + * @augments Backbone.View + */ + initialize() { + this.listenTo(this.model, 'change:subtrees', this.render); + }, + + /** + * @inheritdoc + */ + render() { + const subtrees = this.model.get('subtrees'); + // Add subtrees. + for (const id in subtrees) { + if (subtrees.hasOwnProperty(id)) { + this.$el + .find(`#toolbar-link-${id}`) + .once('toolbar-subtrees') + .after(subtrees[id]); + } + } + // Render the main menu as a nested, collapsible accordion. + if ('drupalToolbarMenu' in $.fn) { + this.$el + .children('.toolbar-menu') + .drupalToolbarMenu(); + } + }, + }); +}(jQuery, Backbone, Drupal)); diff --git a/core/modules/toolbar/js/views/MenuVisualView.js b/core/modules/toolbar/js/views/MenuVisualView.js index 92dea215..a9cd1a30 100644 --- a/core/modules/toolbar/js/views/MenuVisualView.js +++ b/core/modules/toolbar/js/views/MenuVisualView.js @@ -1,46 +1,27 @@ /** - * @file - * A Backbone view for the collapsible menus. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Backbone, Drupal) { - - 'use strict'; - - Drupal.toolbar.MenuVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.MenuVisualView# */{ - - /** - * Backbone View for collapsible menus. - * - * @constructs - * - * @augments Backbone.View - */ - initialize: function () { + Drupal.toolbar.MenuVisualView = Backbone.View.extend({ + initialize: function initialize() { this.listenTo(this.model, 'change:subtrees', this.render); }, - - /** - * @inheritdoc - */ - render: function () { + render: function render() { var subtrees = this.model.get('subtrees'); - // Add subtrees. + for (var id in subtrees) { if (subtrees.hasOwnProperty(id)) { - this.$el - .find('#toolbar-link-' + id) - .once('toolbar-subtrees') - .after(subtrees[id]); + this.$el.find('#toolbar-link-' + id).once('toolbar-subtrees').after(subtrees[id]); } } - // Render the main menu as a nested, collapsible accordion. + if ('drupalToolbarMenu' in $.fn) { - this.$el - .children('.toolbar-menu') - .drupalToolbarMenu(); + this.$el.children('.toolbar-menu').drupalToolbarMenu(); } } }); - -}(jQuery, Backbone, Drupal)); +})(jQuery, Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/toolbar/js/views/ToolbarAuralView.es6.js b/core/modules/toolbar/js/views/ToolbarAuralView.es6.js new file mode 100644 index 00000000..c27b864f --- /dev/null +++ b/core/modules/toolbar/js/views/ToolbarAuralView.es6.js @@ -0,0 +1,71 @@ +/** + * @file + * A Backbone view for the aural feedback of the toolbar. + */ + +(function (Backbone, Drupal) { + Drupal.toolbar.ToolbarAuralView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarAuralView# */{ + + /** + * Backbone view for the aural feedback of the toolbar. + * + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * Options for the view. + * @param {object} options.strings + * Various strings to use in the view. + */ + initialize(options) { + this.strings = options.strings; + + this.listenTo(this.model, 'change:orientation', this.onOrientationChange); + this.listenTo(this.model, 'change:activeTray', this.onActiveTrayChange); + }, + + /** + * Announces an orientation change. + * + * @param {Drupal.toolbar.ToolbarModel} model + * The toolbar model in question. + * @param {string} orientation + * The new value of the orientation attribute in the model. + */ + onOrientationChange(model, orientation) { + Drupal.announce(Drupal.t('Tray orientation changed to @orientation.', { + '@orientation': orientation, + })); + }, + + /** + * Announces a changed active tray. + * + * @param {Drupal.toolbar.ToolbarModel} model + * The toolbar model in question. + * @param {HTMLElement} tray + * The new value of the tray attribute in the model. + */ + onActiveTrayChange(model, tray) { + const relevantTray = (tray === null) ? model.previous('activeTray') : tray; + // Current activeTray and previous activeTray are empty, no state change + // to announce. + if (!relevantTray) { + return; + } + const action = (tray === null) ? Drupal.t('closed') : Drupal.t('opened'); + const trayNameElement = relevantTray.querySelector('.toolbar-tray-name'); + let text; + if (trayNameElement !== null) { + text = Drupal.t('Tray "@tray" @action.', { + '@tray': trayNameElement.textContent, '@action': action, + }); + } + else { + text = Drupal.t('Tray @action.', { '@action': action }); + } + Drupal.announce(text); + }, + }); +}(Backbone, Drupal)); diff --git a/core/modules/toolbar/js/views/ToolbarAuralView.js b/core/modules/toolbar/js/views/ToolbarAuralView.js index 3cc9adaf..f4cca42b 100644 --- a/core/modules/toolbar/js/views/ToolbarAuralView.js +++ b/core/modules/toolbar/js/views/ToolbarAuralView.js @@ -1,70 +1,40 @@ /** - * @file - * A Backbone view for the aural feedback of the toolbar. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function (Backbone, Drupal) { - - 'use strict'; - - Drupal.toolbar.ToolbarAuralView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarAuralView# */{ - - /** - * Backbone view for the aural feedback of the toolbar. - * - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * Options for the view. - * @param {object} options.strings - * Various strings to use in the view. - */ - initialize: function (options) { + Drupal.toolbar.ToolbarAuralView = Backbone.View.extend({ + initialize: function initialize(options) { this.strings = options.strings; this.listenTo(this.model, 'change:orientation', this.onOrientationChange); this.listenTo(this.model, 'change:activeTray', this.onActiveTrayChange); }, - - /** - * Announces an orientation change. - * - * @param {Drupal.toolbar.ToolbarModel} model - * The toolbar model in question. - * @param {string} orientation - * The new value of the orientation attribute in the model. - */ - onOrientationChange: function (model, orientation) { + onOrientationChange: function onOrientationChange(model, orientation) { Drupal.announce(Drupal.t('Tray orientation changed to @orientation.', { '@orientation': orientation })); }, + onActiveTrayChange: function onActiveTrayChange(model, tray) { + var relevantTray = tray === null ? model.previous('activeTray') : tray; - /** - * Announces a changed active tray. - * - * @param {Drupal.toolbar.ToolbarModel} model - * The toolbar model in question. - * @param {HTMLElement} tray - * The new value of the tray attribute in the model. - */ - onActiveTrayChange: function (model, tray) { - var relevantTray = (tray === null) ? model.previous('activeTray') : tray; - var action = (tray === null) ? Drupal.t('closed') : Drupal.t('opened'); + if (!relevantTray) { + return; + } + var action = tray === null ? Drupal.t('closed') : Drupal.t('opened'); var trayNameElement = relevantTray.querySelector('.toolbar-tray-name'); - var text; + var text = void 0; if (trayNameElement !== null) { text = Drupal.t('Tray "@tray" @action.', { '@tray': trayNameElement.textContent, '@action': action }); - } - else { - text = Drupal.t('Tray @action.', {'@action': action}); + } else { + text = Drupal.t('Tray @action.', { '@action': action }); } Drupal.announce(text); } }); - -}(Backbone, Drupal)); +})(Backbone, Drupal); \ No newline at end of file diff --git a/core/modules/toolbar/js/views/ToolbarVisualView.es6.js b/core/modules/toolbar/js/views/ToolbarVisualView.es6.js new file mode 100644 index 00000000..fd4fa6bf --- /dev/null +++ b/core/modules/toolbar/js/views/ToolbarVisualView.es6.js @@ -0,0 +1,330 @@ +/** + * @file + * A Backbone view for the toolbar element. Listens to mouse & touch. + */ + +(function ($, Drupal, drupalSettings, Backbone) { + Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */{ + + /** + * Event map for the `ToolbarVisualView`. + * + * @return {object} + * A map of events. + */ + events() { + // Prevents delay and simulated mouse events. + const touchEndToClick = function (event) { + event.preventDefault(); + event.target.click(); + }; + + return { + 'click .toolbar-bar .toolbar-tab .trigger': 'onTabClick', + 'click .toolbar-toggle-orientation button': 'onOrientationToggleClick', + 'touchend .toolbar-bar .toolbar-tab .trigger': touchEndToClick, + 'touchend .toolbar-toggle-orientation button': touchEndToClick, + }; + }, + + /** + * Backbone view for the toolbar element. Listens to mouse & touch. + * + * @constructs + * + * @augments Backbone.View + * + * @param {object} options + * Options for the view object. + * @param {object} options.strings + * Various strings to use in the view. + */ + initialize(options) { + this.strings = options.strings; + + this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible', this.render); + this.listenTo(this.model, 'change:mqMatches', this.onMediaQueryChange); + this.listenTo(this.model, 'change:offsets', this.adjustPlacement); + this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented', this.updateToolbarHeight); + + // Add the tray orientation toggles. + this.$el + .find('.toolbar-tray .toolbar-lining') + .append(Drupal.theme('toolbarOrientationToggle')); + + // Trigger an activeTab change so that listening scripts can respond on + // page load. This will call render. + this.model.trigger('change:activeTab'); + }, + + /** + * Update the toolbar element height. + * + * @constructs + * + * @augments Backbone.View + */ + updateToolbarHeight() { + const toolbarTabOuterHeight = $('#toolbar-bar').find('.toolbar-tab').outerHeight() || 0; + const toolbarTrayHorizontalOuterHeight = $('.is-active.toolbar-tray-horizontal').outerHeight() || 0; + this.model.set('height', toolbarTabOuterHeight + toolbarTrayHorizontalOuterHeight); + + $('body').css({ + 'padding-top': this.model.get('height'), + }); + + this.triggerDisplace(); + }, + + // Trigger a recalculation of viewport displacing elements. Use setTimeout + // to ensure this recalculation happens after changes to visual elements + // have processed. + triggerDisplace() { + _.defer(() => { + Drupal.displace(true); + }); + }, + + /** + * @inheritdoc + * + * @return {Drupal.toolbar.ToolbarVisualView} + * The `ToolbarVisualView` instance. + */ + render() { + this.updateTabs(); + this.updateTrayOrientation(); + this.updateBarAttributes(); + + $('body').removeClass('toolbar-loading'); + + // Load the subtrees if the orientation of the toolbar is changed to + // vertical. This condition responds to the case that the toolbar switches + // from horizontal to vertical orientation. The toolbar starts in a + // vertical orientation by default and then switches to horizontal during + // initialization if the media query conditions are met. Simply checking + // that the orientation is vertical here would result in the subtrees + // always being loaded, even when the toolbar initialization ultimately + // results in a horizontal orientation. + // + // @see Drupal.behaviors.toolbar.attach() where admin menu subtrees + // loading is invoked during initialization after media query conditions + // have been processed. + if (this.model.changed.orientation === 'vertical' || this.model.changed.activeTab) { + this.loadSubtrees(); + } + + return this; + }, + + /** + * Responds to a toolbar tab click. + * + * @param {jQuery.Event} event + * The event triggered. + */ + onTabClick(event) { + // If this tab has a tray associated with it, it is considered an + // activatable tab. + if (event.target.hasAttribute('data-toolbar-tray')) { + const activeTab = this.model.get('activeTab'); + const clickedTab = event.target; + + // Set the event target as the active item if it is not already. + this.model.set('activeTab', (!activeTab || clickedTab !== activeTab) ? clickedTab : null); + + event.preventDefault(); + event.stopPropagation(); + } + }, + + /** + * Toggles the orientation of a toolbar tray. + * + * @param {jQuery.Event} event + * The event triggered. + */ + onOrientationToggleClick(event) { + const orientation = this.model.get('orientation'); + // Determine the toggle-to orientation. + const antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical'; + const locked = antiOrientation === 'vertical'; + // Remember the locked state. + if (locked) { + localStorage.setItem('Drupal.toolbar.trayVerticalLocked', 'true'); + } + else { + localStorage.removeItem('Drupal.toolbar.trayVerticalLocked'); + } + // Update the model. + this.model.set({ + locked, + orientation: antiOrientation, + }, { + validate: true, + override: true, + }); + + event.preventDefault(); + event.stopPropagation(); + }, + + /** + * Updates the display of the tabs: toggles a tab and the associated tray. + */ + updateTabs() { + const $tab = $(this.model.get('activeTab')); + // Deactivate the previous tab. + $(this.model.previous('activeTab')) + .removeClass('is-active') + .prop('aria-pressed', false); + // Deactivate the previous tray. + $(this.model.previous('activeTray')) + .removeClass('is-active'); + + // Activate the selected tab. + if ($tab.length > 0) { + $tab + .addClass('is-active') + // Mark the tab as pressed. + .prop('aria-pressed', true); + const name = $tab.attr('data-toolbar-tray'); + // Store the active tab name or remove the setting. + const id = $tab.get(0).id; + if (id) { + localStorage.setItem('Drupal.toolbar.activeTabID', JSON.stringify(id)); + } + // Activate the associated tray. + const $tray = this.$el.find(`[data-toolbar-tray="${name}"].toolbar-tray`); + if ($tray.length) { + $tray.addClass('is-active'); + this.model.set('activeTray', $tray.get(0)); + } + else { + // There is no active tray. + this.model.set('activeTray', null); + } + } + else { + // There is no active tray. + this.model.set('activeTray', null); + localStorage.removeItem('Drupal.toolbar.activeTabID'); + } + }, + + /** + * Update the attributes of the toolbar bar element. + */ + updateBarAttributes() { + const isOriented = this.model.get('isOriented'); + if (isOriented) { + this.$el.find('.toolbar-bar').attr('data-offset-top', ''); + } + else { + this.$el.find('.toolbar-bar').removeAttr('data-offset-top'); + } + // Toggle between a basic vertical view and a more sophisticated + // horizontal and vertical display of the toolbar bar and trays. + this.$el.toggleClass('toolbar-oriented', isOriented); + }, + + /** + * Updates the orientation of the active tray if necessary. + */ + updateTrayOrientation() { + const orientation = this.model.get('orientation'); + + // The antiOrientation is used to render the view of action buttons like + // the tray orientation toggle. + const antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical'; + + // Toggle toolbar's parent classes before other toolbar classes to avoid + // potential flicker and re-rendering. + $('body') + .toggleClass('toolbar-vertical', (orientation === 'vertical')) + .toggleClass('toolbar-horizontal', (orientation === 'horizontal')); + + const removeClass = (antiOrientation === 'horizontal') ? 'toolbar-tray-horizontal' : 'toolbar-tray-vertical'; + const $trays = this.$el.find('.toolbar-tray') + .removeClass(removeClass) + .addClass(`toolbar-tray-${orientation}`); + + // Update the tray orientation toggle button. + const iconClass = `toolbar-icon-toggle-${orientation}`; + const iconAntiClass = `toolbar-icon-toggle-${antiOrientation}`; + const $orientationToggle = this.$el.find('.toolbar-toggle-orientation') + .toggle(this.model.get('isTrayToggleVisible')); + $orientationToggle.find('button') + .val(antiOrientation) + .attr('title', this.strings[antiOrientation]) + .text(this.strings[antiOrientation]) + .removeClass(iconClass) + .addClass(iconAntiClass); + + // Update data offset attributes for the trays. + const dir = document.documentElement.dir; + const edge = (dir === 'rtl') ? 'right' : 'left'; + // Remove data-offset attributes from the trays so they can be refreshed. + $trays.removeAttr('data-offset-left data-offset-right data-offset-top'); + // If an active vertical tray exists, mark it as an offset element. + $trays.filter('.toolbar-tray-vertical.is-active').attr(`data-offset-${edge}`, ''); + // If an active horizontal tray exists, mark it as an offset element. + $trays.filter('.toolbar-tray-horizontal.is-active').attr('data-offset-top', ''); + }, + + /** + * Sets the tops of the trays so that they align with the bottom of the bar. + */ + adjustPlacement() { + const $trays = this.$el.find('.toolbar-tray'); + if (!this.model.get('isOriented')) { + $trays.removeClass('toolbar-tray-horizontal').addClass('toolbar-tray-vertical'); + } + }, + + /** + * Calls the endpoint URI that builds an AJAX command with the rendered + * subtrees. + * + * The rendered admin menu subtrees HTML is cached on the client in + * localStorage until the cache of the admin menu subtrees on the server- + * side is invalidated. The subtreesHash is stored in localStorage as well + * and compared to the subtreesHash in drupalSettings to determine when the + * admin menu subtrees cache has been invalidated. + */ + loadSubtrees() { + const $activeTab = $(this.model.get('activeTab')); + const orientation = this.model.get('orientation'); + // Only load and render the admin menu subtrees if: + // (1) They have not been loaded yet. + // (2) The active tab is the administration menu tab, indicated by the + // presence of the data-drupal-subtrees attribute. + // (3) The orientation of the tray is vertical. + if (!this.model.get('areSubtreesLoaded') && typeof $activeTab.data('drupal-subtrees') !== 'undefined' && orientation === 'vertical') { + const subtreesHash = drupalSettings.toolbar.subtreesHash; + const theme = drupalSettings.ajaxPageState.theme; + const endpoint = Drupal.url(`toolbar/subtrees/${subtreesHash}`); + const cachedSubtreesHash = localStorage.getItem(`Drupal.toolbar.subtreesHash.${theme}`); + const cachedSubtrees = JSON.parse(localStorage.getItem(`Drupal.toolbar.subtrees.${theme}`)); + const isVertical = this.model.get('orientation') === 'vertical'; + // If we have the subtrees in localStorage and the subtree hash has not + // changed, then use the cached data. + if (isVertical && subtreesHash === cachedSubtreesHash && cachedSubtrees) { + Drupal.toolbar.setSubtrees.resolve(cachedSubtrees); + } + // Only make the call to get the subtrees if the orientation of the + // toolbar is vertical. + else if (isVertical) { + // Remove the cached menu information. + localStorage.removeItem(`Drupal.toolbar.subtreesHash.${theme}`); + localStorage.removeItem(`Drupal.toolbar.subtrees.${theme}`); + // The AJAX response's command will trigger the resolve method of the + // Drupal.toolbar.setSubtrees Promise. + Drupal.ajax({ url: endpoint }).execute(); + // Cache the hash for the subtrees locally. + localStorage.setItem(`Drupal.toolbar.subtreesHash.${theme}`, subtreesHash); + } + } + }, + }); +}(jQuery, Drupal, drupalSettings, Backbone)); diff --git a/core/modules/toolbar/js/views/ToolbarVisualView.js b/core/modules/toolbar/js/views/ToolbarVisualView.js index f26c98c4..6b4ce21c 100644 --- a/core/modules/toolbar/js/views/ToolbarVisualView.js +++ b/core/modules/toolbar/js/views/ToolbarVisualView.js @@ -1,23 +1,14 @@ /** - * @file - * A Backbone view for the toolbar element. Listens to mouse & touch. - */ +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ (function ($, Drupal, drupalSettings, Backbone) { - - 'use strict'; - - Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */{ - - /** - * Event map for the `ToolbarVisualView`. - * - * @return {object} - * A map of events. - */ - events: function () { - // Prevents delay and simulated mouse events. - var touchEndToClick = function (event) { + Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({ + events: function events() { + var touchEndToClick = function touchEndToClick(event) { event.preventDefault(); event.target.click(); }; @@ -29,110 +20,70 @@ 'touchend .toolbar-toggle-orientation button': touchEndToClick }; }, - - /** - * Backbone view for the toolbar element. Listens to mouse & touch. - * - * @constructs - * - * @augments Backbone.View - * - * @param {object} options - * Options for the view object. - * @param {object} options.strings - * Various strings to use in the view. - */ - initialize: function (options) { + initialize: function initialize(options) { this.strings = options.strings; this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible', this.render); this.listenTo(this.model, 'change:mqMatches', this.onMediaQueryChange); this.listenTo(this.model, 'change:offsets', this.adjustPlacement); + this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented', this.updateToolbarHeight); - // Add the tray orientation toggles. - this.$el - .find('.toolbar-tray .toolbar-lining') - .append(Drupal.theme('toolbarOrientationToggle')); + this.$el.find('.toolbar-tray .toolbar-lining').append(Drupal.theme('toolbarOrientationToggle')); - // Trigger an activeTab change so that listening scripts can respond on - // page load. This will call render. this.model.trigger('change:activeTab'); }, + updateToolbarHeight: function updateToolbarHeight() { + var toolbarTabOuterHeight = $('#toolbar-bar').find('.toolbar-tab').outerHeight() || 0; + var toolbarTrayHorizontalOuterHeight = $('.is-active.toolbar-tray-horizontal').outerHeight() || 0; + this.model.set('height', toolbarTabOuterHeight + toolbarTrayHorizontalOuterHeight); - /** - * @inheritdoc - * - * @return {Drupal.toolbar.ToolbarVisualView} - * The `ToolbarVisualView` instance. - */ - render: function () { + $('body').css({ + 'padding-top': this.model.get('height') + }); + + this.triggerDisplace(); + }, + triggerDisplace: function triggerDisplace() { + _.defer(function () { + Drupal.displace(true); + }); + }, + render: function render() { this.updateTabs(); this.updateTrayOrientation(); this.updateBarAttributes(); - // Load the subtrees if the orientation of the toolbar is changed to - // vertical. This condition responds to the case that the toolbar switches - // from horizontal to vertical orientation. The toolbar starts in a - // vertical orientation by default and then switches to horizontal during - // initialization if the media query conditions are met. Simply checking - // that the orientation is vertical here would result in the subtrees - // always being loaded, even when the toolbar initialization ultimately - // results in a horizontal orientation. - // - // @see Drupal.behaviors.toolbar.attach() where admin menu subtrees - // loading is invoked during initialization after media query conditions - // have been processed. + + $('body').removeClass('toolbar-loading'); + if (this.model.changed.orientation === 'vertical' || this.model.changed.activeTab) { this.loadSubtrees(); } - // Trigger a recalculation of viewport displacing elements. Use setTimeout - // to ensure this recalculation happens after changes to visual elements - // have processed. - window.setTimeout(function () { - Drupal.displace(true); - }, 0); + return this; }, - - /** - * Responds to a toolbar tab click. - * - * @param {jQuery.Event} event - * The event triggered. - */ - onTabClick: function (event) { - // If this tab has a tray associated with it, it is considered an - // activatable tab. + onTabClick: function onTabClick(event) { if (event.target.hasAttribute('data-toolbar-tray')) { var activeTab = this.model.get('activeTab'); var clickedTab = event.target; - // Set the event target as the active item if it is not already. - this.model.set('activeTab', (!activeTab || clickedTab !== activeTab) ? clickedTab : null); + this.model.set('activeTab', !activeTab || clickedTab !== activeTab ? clickedTab : null); event.preventDefault(); event.stopPropagation(); } }, - - /** - * Toggles the orientation of a toolbar tray. - * - * @param {jQuery.Event} event - * The event triggered. - */ - onOrientationToggleClick: function (event) { + onOrientationToggleClick: function onOrientationToggleClick(event) { var orientation = this.model.get('orientation'); - // Determine the toggle-to orientation. - var antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical'; + + var antiOrientation = orientation === 'vertical' ? 'horizontal' : 'vertical'; var locked = antiOrientation === 'vertical'; - // Remember the locked state. + if (locked) { localStorage.setItem('Drupal.toolbar.trayVerticalLocked', 'true'); - } - else { + } else { localStorage.removeItem('Drupal.toolbar.trayVerticalLocked'); } - // Update the model. + this.model.set({ locked: locked, orientation: antiOrientation @@ -144,136 +95,78 @@ event.preventDefault(); event.stopPropagation(); }, - - /** - * Updates the display of the tabs: toggles a tab and the associated tray. - */ - updateTabs: function () { + updateTabs: function updateTabs() { var $tab = $(this.model.get('activeTab')); - // Deactivate the previous tab. - $(this.model.previous('activeTab')) - .removeClass('is-active') - .prop('aria-pressed', false); - // Deactivate the previous tray. - $(this.model.previous('activeTray')) - .removeClass('is-active'); - - // Activate the selected tab. + + $(this.model.previous('activeTab')).removeClass('is-active').prop('aria-pressed', false); + + $(this.model.previous('activeTray')).removeClass('is-active'); + if ($tab.length > 0) { - $tab - .addClass('is-active') - // Mark the tab as pressed. - .prop('aria-pressed', true); + $tab.addClass('is-active').prop('aria-pressed', true); var name = $tab.attr('data-toolbar-tray'); - // Store the active tab name or remove the setting. + var id = $tab.get(0).id; if (id) { localStorage.setItem('Drupal.toolbar.activeTabID', JSON.stringify(id)); } - // Activate the associated tray. + var $tray = this.$el.find('[data-toolbar-tray="' + name + '"].toolbar-tray'); if ($tray.length) { $tray.addClass('is-active'); this.model.set('activeTray', $tray.get(0)); - } - else { - // There is no active tray. + } else { this.model.set('activeTray', null); } - } - else { - // There is no active tray. + } else { this.model.set('activeTray', null); localStorage.removeItem('Drupal.toolbar.activeTabID'); } }, - - /** - * Update the attributes of the toolbar bar element. - */ - updateBarAttributes: function () { + updateBarAttributes: function updateBarAttributes() { var isOriented = this.model.get('isOriented'); if (isOriented) { this.$el.find('.toolbar-bar').attr('data-offset-top', ''); - } - else { + } else { this.$el.find('.toolbar-bar').removeAttr('data-offset-top'); } - // Toggle between a basic vertical view and a more sophisticated - // horizontal and vertical display of the toolbar bar and trays. + this.$el.toggleClass('toolbar-oriented', isOriented); }, - - /** - * Updates the orientation of the active tray if necessary. - */ - updateTrayOrientation: function () { + updateTrayOrientation: function updateTrayOrientation() { var orientation = this.model.get('orientation'); - // The antiOrientation is used to render the view of action buttons like - // the tray orientation toggle. - var antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical'; - // Update the orientation of the trays. - var $trays = this.$el.find('.toolbar-tray') - .removeClass('toolbar-tray-horizontal toolbar-tray-vertical') - .addClass('toolbar-tray-' + orientation); - - // Update the tray orientation toggle button. + + var antiOrientation = orientation === 'vertical' ? 'horizontal' : 'vertical'; + + $('body').toggleClass('toolbar-vertical', orientation === 'vertical').toggleClass('toolbar-horizontal', orientation === 'horizontal'); + + var removeClass = antiOrientation === 'horizontal' ? 'toolbar-tray-horizontal' : 'toolbar-tray-vertical'; + var $trays = this.$el.find('.toolbar-tray').removeClass(removeClass).addClass('toolbar-tray-' + orientation); + var iconClass = 'toolbar-icon-toggle-' + orientation; var iconAntiClass = 'toolbar-icon-toggle-' + antiOrientation; - var $orientationToggle = this.$el.find('.toolbar-toggle-orientation') - .toggle(this.model.get('isTrayToggleVisible')); - $orientationToggle.find('button') - .val(antiOrientation) - .attr('title', this.strings[antiOrientation]) - .text(this.strings[antiOrientation]) - .removeClass(iconClass) - .addClass(iconAntiClass); - - // Update data offset attributes for the trays. + var $orientationToggle = this.$el.find('.toolbar-toggle-orientation').toggle(this.model.get('isTrayToggleVisible')); + $orientationToggle.find('button').val(antiOrientation).attr('title', this.strings[antiOrientation]).text(this.strings[antiOrientation]).removeClass(iconClass).addClass(iconAntiClass); + var dir = document.documentElement.dir; - var edge = (dir === 'rtl') ? 'right' : 'left'; - // Remove data-offset attributes from the trays so they can be refreshed. + var edge = dir === 'rtl' ? 'right' : 'left'; + $trays.removeAttr('data-offset-left data-offset-right data-offset-top'); - // If an active vertical tray exists, mark it as an offset element. + $trays.filter('.toolbar-tray-vertical.is-active').attr('data-offset-' + edge, ''); - // If an active horizontal tray exists, mark it as an offset element. + $trays.filter('.toolbar-tray-horizontal.is-active').attr('data-offset-top', ''); }, - - /** - * Sets the tops of the trays so that they align with the bottom of the bar. - */ - adjustPlacement: function () { + adjustPlacement: function adjustPlacement() { var $trays = this.$el.find('.toolbar-tray'); if (!this.model.get('isOriented')) { - $trays.css('margin-top', 0); $trays.removeClass('toolbar-tray-horizontal').addClass('toolbar-tray-vertical'); } - else { - // The toolbar container is invisible. Its placement is used to - // determine the container for the trays. - $trays.css('margin-top', this.$el.find('.toolbar-bar').outerHeight()); - } }, - - /** - * Calls the endpoint URI that builds an AJAX command with the rendered - * subtrees. - * - * The rendered admin menu subtrees HTML is cached on the client in - * localStorage until the cache of the admin menu subtrees on the server- - * side is invalidated. The subtreesHash is stored in localStorage as well - * and compared to the subtreesHash in drupalSettings to determine when the - * admin menu subtrees cache has been invalidated. - */ - loadSubtrees: function () { + loadSubtrees: function loadSubtrees() { var $activeTab = $(this.model.get('activeTab')); var orientation = this.model.get('orientation'); - // Only load and render the admin menu subtrees if: - // (1) They have not been loaded yet. - // (2) The active tab is the administration menu tab, indicated by the - // presence of the data-drupal-subtrees attribute. - // (3) The orientation of the tray is vertical. + if (!this.model.get('areSubtreesLoaded') && typeof $activeTab.data('drupal-subtrees') !== 'undefined' && orientation === 'vertical') { var subtreesHash = drupalSettings.toolbar.subtreesHash; var theme = drupalSettings.ajaxPageState.theme; @@ -281,25 +174,18 @@ var cachedSubtreesHash = localStorage.getItem('Drupal.toolbar.subtreesHash.' + theme); var cachedSubtrees = JSON.parse(localStorage.getItem('Drupal.toolbar.subtrees.' + theme)); var isVertical = this.model.get('orientation') === 'vertical'; - // If we have the subtrees in localStorage and the subtree hash has not - // changed, then use the cached data. + if (isVertical && subtreesHash === cachedSubtreesHash && cachedSubtrees) { Drupal.toolbar.setSubtrees.resolve(cachedSubtrees); - } - // Only make the call to get the subtrees if the orientation of the - // toolbar is vertical. - else if (isVertical) { - // Remove the cached menu information. - localStorage.removeItem('Drupal.toolbar.subtreesHash.' + theme); - localStorage.removeItem('Drupal.toolbar.subtrees.' + theme); - // The AJAX response's command will trigger the resolve method of the - // Drupal.toolbar.setSubtrees Promise. - Drupal.ajax({url: endpoint}).execute(); - // Cache the hash for the subtrees locally. - localStorage.setItem('Drupal.toolbar.subtreesHash.' + theme, subtreesHash); - } + } else if (isVertical) { + localStorage.removeItem('Drupal.toolbar.subtreesHash.' + theme); + localStorage.removeItem('Drupal.toolbar.subtrees.' + theme); + + Drupal.ajax({ url: endpoint }).execute(); + + localStorage.setItem('Drupal.toolbar.subtreesHash.' + theme, subtreesHash); + } } } }); - -}(jQuery, Drupal, drupalSettings, Backbone)); +})(jQuery, Drupal, drupalSettings, Backbone); \ No newline at end of file diff --git a/core/modules/toolbar/src/Element/Toolbar.php b/core/modules/toolbar/src/Element/Toolbar.php index 69a53dbd..d92330b3 100644 --- a/core/modules/toolbar/src/Element/Toolbar.php +++ b/core/modules/toolbar/src/Element/Toolbar.php @@ -18,35 +18,35 @@ class Toolbar extends RenderElement { */ public function getInfo() { $class = get_class($this); - return array( - '#pre_render' => array( - array($class, 'preRenderToolbar'), - ), + return [ + '#pre_render' => [ + [$class, 'preRenderToolbar'], + ], '#theme' => 'toolbar', - '#attached' => array( - 'library' => array( + '#attached' => [ + 'library' => [ 'toolbar/toolbar', - ), - ), + ], + ], // Metadata for the toolbar wrapping element. - '#attributes' => array( + '#attributes' => [ // The id cannot be simply "toolbar" or it will clash with the // simpletest tests listing which produces a checkbox with attribute // id="toolbar". 'id' => 'toolbar-administration', 'role' => 'group', 'aria-label' => $this->t('Site administration toolbar'), - ), + ], // Metadata for the administration bar. - '#bar' => array( + '#bar' => [ '#heading' => $this->t('Toolbar items'), - '#attributes' => array( + '#attributes' => [ 'id' => 'toolbar-bar', 'role' => 'navigation', 'aria-label' => $this->t('Toolbar items'), - ), - ), - ); + ], + ], + ]; } /** @@ -68,7 +68,7 @@ public static function preRenderToolbar($element) { // toolbar presentation. $breakpoints = static::breakpointManager()->getBreakpointsByGroup('toolbar'); if (!empty($breakpoints)) { - $media_queries = array(); + $media_queries = []; foreach ($breakpoints as $id => $breakpoint) { $media_queries[$id] = $breakpoint->getMediaQuery(); } @@ -82,7 +82,7 @@ public static function preRenderToolbar($element) { // Allow for altering of hook_toolbar(). $module_handler->alter('toolbar', $items); // Sort the children. - uasort($items, array('\Drupal\Component\Utility\SortArray', 'sortByWeightProperty')); + uasort($items, ['\Drupal\Component\Utility\SortArray', 'sortByWeightProperty']); // Merge in the original toolbar values. $element = array_merge($element, $items); diff --git a/core/modules/toolbar/src/Element/ToolbarItem.php b/core/modules/toolbar/src/Element/ToolbarItem.php index e39295f1..79cbed2d 100644 --- a/core/modules/toolbar/src/Element/ToolbarItem.php +++ b/core/modules/toolbar/src/Element/ToolbarItem.php @@ -19,16 +19,16 @@ class ToolbarItem extends RenderElement { */ public function getInfo() { $class = get_class($this); - return array( - '#pre_render' => array( - array($class, 'preRenderToolbarItem'), - ), - 'tab' => array( + return [ + '#pre_render' => [ + [$class, 'preRenderToolbarItem'], + ], + 'tab' => [ '#type' => 'link', '#title' => NULL, '#url' => Url::fromRoute(''), - ), - ); + ], + ]; } /** @@ -47,33 +47,33 @@ public static function preRenderToolbarItem($element) { $id = $element['#id']; // Provide attributes for a toolbar item. - $attributes = array( + $attributes = [ 'id' => $id, - ); + ]; // If tray content is present, markup the tray and its associated trigger. if (!empty($element['tray'])) { // Provide attributes necessary for trays. - $attributes += array( + $attributes += [ 'data-toolbar-tray' => $id . '-tray', 'aria-owns' => $id . '-tray', 'role' => 'button', 'aria-pressed' => 'false', - ); + ]; // Merge in module-provided attributes. - $element['tab'] += array('#attributes' => array()); + $element['tab'] += ['#attributes' => []]; $element['tab']['#attributes'] += $attributes; $element['tab']['#attributes']['class'][] = 'trigger'; // Provide attributes for the tray theme wrapper. - $attributes = array( + $attributes = [ 'id' => $id . '-tray', 'data-toolbar-tray' => $id . '-tray', - ); + ]; // Merge in module-provided attributes. if (!isset($element['tray']['#wrapper_attributes'])) { - $element['tray']['#wrapper_attributes'] = array(); + $element['tray']['#wrapper_attributes'] = []; } $element['tray']['#wrapper_attributes'] += $attributes; $element['tray']['#wrapper_attributes']['class'][] = 'toolbar-tray'; diff --git a/core/modules/toolbar/src/Menu/ToolbarMenuLinkTree.php b/core/modules/toolbar/src/Menu/ToolbarMenuLinkTree.php index 873ebec7..24ef4e77 100644 --- a/core/modules/toolbar/src/Menu/ToolbarMenuLinkTree.php +++ b/core/modules/toolbar/src/Menu/ToolbarMenuLinkTree.php @@ -15,7 +15,7 @@ class ToolbarMenuLinkTree extends MenuLinkTree { public function build(array $tree, $level = 0) { if ($level == 0) { if (!$tree) { - return array(); + return []; } $build = parent::build($tree, $level); diff --git a/core/modules/toolbar/tests/modules/toolbar_disable_user_toolbar/toolbar_disable_user_toolbar.info.yml b/core/modules/toolbar/tests/modules/toolbar_disable_user_toolbar/toolbar_disable_user_toolbar.info.yml index fa4245bc..333cbce6 100644 --- a/core/modules/toolbar/tests/modules/toolbar_disable_user_toolbar/toolbar_disable_user_toolbar.info.yml +++ b/core/modules/toolbar/tests/modules/toolbar_disable_user_toolbar/toolbar_disable_user_toolbar.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.info.yml b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.info.yml index ac119cac..e37ec308 100644 --- a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.info.yml +++ b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.info.yml @@ -5,8 +5,8 @@ package: Testing # version: VERSION # core: 8.x -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module index 4a82ca7c..323af166 100644 --- a/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module +++ b/core/modules/toolbar/tests/modules/toolbar_test/toolbar_test.module @@ -12,38 +12,38 @@ use Drupal\Core\Url; */ function toolbar_test_toolbar() { - $items['testing'] = array( + $items['testing'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => t('Test tab'), '#url' => Url::fromRoute(''), - '#options' => array( - 'attributes' => array( + '#options' => [ + 'attributes' => [ 'id' => 'toolbar-tab-testing', 'title' => t('Test tab'), - ), - ), - ), - 'tray' => array( + ], + ], + ], + 'tray' => [ '#heading' => t('Test tray'), - '#wrapper_attributes' => array( + '#wrapper_attributes' => [ 'id' => 'toolbar-tray-testing', - ), - 'content' => array( + ], + 'content' => [ '#theme' => 'item_list', - '#items' => array( - \Drupal::l(t('link 1'), new Url('', [], array('attributes' => array('title' => 'Test link 1 title')))), - \Drupal::l(t('link 2'), new Url('', [], array('attributes' => array('title' => 'Test link 2 title')))), - \Drupal::l(t('link 3'), new Url('', [], array('attributes' => array('title' => 'Test link 3 title')))), - ), - '#attributes' => array( - 'class' => array('toolbar-menu'), - ), - ), - ), + '#items' => [ + \Drupal::l(t('link 1'), new Url('', [], ['attributes' => ['title' => 'Test link 1 title']])), + \Drupal::l(t('link 2'), new Url('', [], ['attributes' => ['title' => 'Test link 2 title']])), + \Drupal::l(t('link 3'), new Url('', [], ['attributes' => ['title' => 'Test link 3 title']])), + ], + '#attributes' => [ + 'class' => ['toolbar-menu'], + ], + ], + ], '#weight' => 50, - ); + ]; return $items; } diff --git a/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php similarity index 89% rename from core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php rename to core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php index 56b9d69a..9585c86e 100644 --- a/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php +++ b/core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php @@ -1,11 +1,12 @@ adminUser = $this->drupalCreateUser($perms); @@ -97,13 +98,13 @@ protected function setUp() { * Tests the toolbar_modules_installed() and toolbar_modules_uninstalled() hook * implementations. */ - function testModuleStatusChangeSubtreesHashCacheClear() { + public function testModuleStatusChangeSubtreesHashCacheClear() { // Uninstall a module. - $edit = array(); + $edit = []; $edit['uninstall[taxonomy]'] = TRUE; $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); // Confirm the uninstall form. - $this->drupalPostForm(NULL, array(), t('Uninstall')); + $this->drupalPostForm(NULL, [], t('Uninstall')); $this->rebuildContainer(); // Assert that the subtrees hash has been altered because the subtrees @@ -111,8 +112,8 @@ function testModuleStatusChangeSubtreesHashCacheClear() { $this->assertDifferentHash(); // Enable a module. - $edit = array(); - $edit['modules[Core][taxonomy][enable]'] = TRUE; + $edit = []; + $edit['modules[taxonomy][enable]'] = TRUE; $this->drupalPostForm('admin/modules', $edit, t('Install')); $this->rebuildContainer(); @@ -124,12 +125,12 @@ function testModuleStatusChangeSubtreesHashCacheClear() { /** * Tests toolbar cache tags implementation. */ - function testMenuLinkUpdateSubtreesHashCacheClear() { + public function testMenuLinkUpdateSubtreesHashCacheClear() { // The ID of a (any) admin menu link. $admin_menu_link_id = 'system.admin_config_development'; // Disable the link. - $edit = array(); + $edit = []; $edit['enabled'] = FALSE; $this->drupalPostForm("admin/structure/menu/link/" . $admin_menu_link_id . "/edit", $edit, t('Save')); $this->assertResponse(200); @@ -144,13 +145,13 @@ function testMenuLinkUpdateSubtreesHashCacheClear() { * Exercises the toolbar_user_role_update() and toolbar_user_update() hook * implementations. */ - function testUserRoleUpdateSubtreesHashCacheClear() { + public function testUserRoleUpdateSubtreesHashCacheClear() { // Find the new role ID. $all_rids = $this->adminUser->getRoles(); unset($all_rids[array_search(RoleInterface::AUTHENTICATED_ID, $all_rids)]); $rid = reset($all_rids); - $edit = array(); + $edit = []; $edit[$rid . '[administer taxonomy]'] = FALSE; $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions')); @@ -179,10 +180,10 @@ function testUserRoleUpdateSubtreesHashCacheClear() { $this->hash = $this->getSubtreesHash(); - $rid = $this->drupalCreateRole(array('administer content types',)); + $rid = $this->drupalCreateRole(['administer content types']); // Assign the role to the user. - $this->drupalPostForm('user/' . $this->adminUser->id() . '/edit', array("roles[$rid]" => $rid), t('Save')); + $this->drupalPostForm('user/' . $this->adminUser->id() . '/edit', ["roles[$rid]" => $rid], t('Save')); $this->assertText(t('The changes have been saved.')); // Assert that the subtrees hash has been altered because the subtrees @@ -208,13 +209,13 @@ function testUserRoleUpdateSubtreesHashCacheClear() { * Tests that changes to a user account by another user clears the changed * account's toolbar cached, not the user's who took the action. */ - function testNonCurrentUserAccountUpdates() { + public function testNonCurrentUserAccountUpdates() { $admin_user_id = $this->adminUser->id(); $this->hash = $this->getSubtreesHash(); // adminUser2 will add a role to adminUser. $this->drupalLogin($this->adminUser2); - $rid = $this->drupalCreateRole(array('administer content types',)); + $rid = $this->drupalCreateRole(['administer content types']); // Get the subtree hash for adminUser2 to check later that it has not // changed. Request a new page to refresh the drupalSettings object. @@ -223,7 +224,7 @@ function testNonCurrentUserAccountUpdates() { $admin_user_2_hash = $this->getSubtreesHash(); // Assign the role to the user. - $this->drupalPostForm('user/' . $admin_user_id . '/edit', array("roles[$rid]" => $rid), t('Save')); + $this->drupalPostForm('user/' . $admin_user_id . '/edit', ["roles[$rid]" => $rid], t('Save')); $this->assertText(t('The changes have been saved.')); // Log in adminUser and assert that the subtrees hash has changed. @@ -243,10 +244,10 @@ function testNonCurrentUserAccountUpdates() { /** * Tests that toolbar cache is cleared when string translations are made. */ - function testLocaleTranslationSubtreesHashCacheClear() { + public function testLocaleTranslationSubtreesHashCacheClear() { $admin_user = $this->adminUser; // User to translate and delete string. - $translate_user = $this->drupalCreateUser(array('translate interface', 'access administration pages')); + $translate_user = $this->drupalCreateUser(['translate interface', 'access administration pages']); // Create a new language with the langcode 'xx'. $langcode = 'xx'; @@ -257,14 +258,14 @@ function testLocaleTranslationSubtreesHashCacheClear() { // Add custom language. $this->drupalLogin($admin_user); - $edit = array( + $edit = [ 'predefined_langcode' => 'custom', 'langcode' => $langcode, 'label' => $name, 'direction' => LanguageInterface::DIRECTION_LTR, - ); + ]; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); - t($name, array(), array('langcode' => $langcode)); + t($name, [], ['langcode' => $langcode]); // Reset locale cache. $this->container->get('string_translation')->reset(); $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.'); @@ -285,11 +286,11 @@ function testLocaleTranslationSubtreesHashCacheClear() { // should create a new menu hash if the toolbar subtrees cache is correctly // invalidated. $this->drupalLogin($translate_user); - $search = array( + $search = [ 'string' => 'Search and metadata', 'langcode' => $langcode, 'translation' => 'untranslated', - ); + ]; $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); $this->assertNoText(t('No strings available')); $this->assertText($name, 'Search found the string as untranslated.'); @@ -297,10 +298,10 @@ function testLocaleTranslationSubtreesHashCacheClear() { // Assume this is the only result. // Translate the string to a random string. $textarea = current($this->xpath('//textarea')); - $lid = (string) $textarea[0]['name']; - $edit = array( + $lid = (string) $textarea->getAttribute('name'); + $edit = [ $lid => $translation, - ); + ]; $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); $this->assertText(t('The strings have been saved.'), 'The strings have been saved.'); $this->assertUrl(\Drupal::url('locale.translate_page', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); @@ -324,14 +325,14 @@ function testLocaleTranslationSubtreesHashCacheClear() { /** * Tests that the 'toolbar/subtrees/{hash}' is reachable and correct. */ - function testSubtreesJsonRequest() { + public function testSubtreesJsonRequest() { $admin_user = $this->adminUser; $this->drupalLogin($admin_user); // Request a new page to refresh the drupalSettings object. $subtrees_hash = $this->getSubtreesHash(); - $ajax_result = $this->drupalGetAjax('toolbar/subtrees/' . $subtrees_hash); - $this->assertResponse('200'); + $this->drupalGet('toolbar/subtrees/' . $subtrees_hash, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With: XMLHttpRequest']); + $ajax_result = json_decode($this->getSession()->getPage()->getContent(), TRUE); $this->assertEqual($ajax_result[0]['command'], 'setToolbarSubtrees', 'Subtrees response uses the correct command.'); $this->assertEqual(array_keys($ajax_result[0]['subtrees']), ['system-admin_content', 'system-admin_structure', 'system-themes_page', 'system-modules_list', 'system-admin_config', 'entity-user-collection', 'front'], 'Correct subtrees returned.'); } @@ -339,7 +340,7 @@ function testSubtreesJsonRequest() { /** * Test that subtrees hashes vary by the language of the page. */ - function testLanguageSwitching() { + public function testLanguageSwitching() { // Create a new language with the langcode 'xx'. $langcode = 'xx'; $language = ConfigurableLanguage::createFromLangcode($langcode); @@ -350,7 +351,7 @@ function testLanguageSwitching() { $this->rebuildContainer(); // Get a page with the new language langcode in the URL. - $this->drupalGet('test-page', array('language' => $language)); + $this->drupalGet('test-page', ['language' => $language]); // Assert different hash. $new_subtree_hash = $this->getSubtreesHash(); diff --git a/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php similarity index 95% rename from core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php rename to core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php index 6995d598..26454762 100644 --- a/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php +++ b/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php @@ -1,19 +1,18 @@ adminUser = $this->drupalCreateUser(array('access toolbar')); + $this->adminUser = $this->drupalCreateUser(['access toolbar']); $this->drupalLogin($this->adminUser); } /** * Tests for a tab and tray provided by a module implementing hook_toolbar(). */ - function testHookToolbar() { + public function testHookToolbar() { $this->drupalGet('test-page'); $this->assertResponse(200); diff --git a/core/modules/toolbar/src/Tests/ToolbarMenuTranslationTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarMenuTranslationTest.php similarity index 84% rename from core/modules/toolbar/src/Tests/ToolbarMenuTranslationTest.php rename to core/modules/toolbar/tests/src/Functional/ToolbarMenuTranslationTest.php index 8fa2bed5..995d49ee 100644 --- a/core/modules/toolbar/src/Tests/ToolbarMenuTranslationTest.php +++ b/core/modules/toolbar/tests/src/Functional/ToolbarMenuTranslationTest.php @@ -1,15 +1,15 @@ adminUser = $this->drupalCreateUser(array('access toolbar', 'translate interface', 'administer languages', 'access administration pages')); + $this->adminUser = $this->drupalCreateUser(['access toolbar', 'translate interface', 'administer languages', 'access administration pages']); $this->drupalLogin($this->adminUser); } /** * Tests that toolbar classes don't change when adding a translation. */ - function testToolbarClasses() { + public function testToolbarClasses() { $langcode = 'es'; // Add Spanish. @@ -50,11 +50,11 @@ function testToolbarClasses() { $this->drupalGet($langcode . '/admin/structure'); // Search for the menu item. - $search = array( + $search = [ 'string' => $menu_item, 'langcode' => $langcode, 'translation' => 'untranslated', - ); + ]; $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); // Make sure will be able to translate the menu item. $this->assertNoText('No strings available.', 'Search found the menu item as untranslated.'); @@ -66,18 +66,18 @@ function testToolbarClasses() { // Translate the menu item. $menu_item_translated = $this->randomMachineName(); $textarea = current($this->xpath('//textarea')); - $lid = (string) $textarea[0]['name']; - $edit = array( + $lid = (string) $textarea->getAttribute('name'); + $edit = [ $lid => $menu_item_translated, - ); + ]; $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); // Search for the translated menu item. - $search = array( + $search = [ 'string' => $menu_item, 'langcode' => $langcode, 'translation' => 'translated', - ); + ]; $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); // Make sure the menu item string was translated. $this->assertText($menu_item_translated, 'Search found the menu item as translated: ' . $menu_item_translated . '.'); diff --git a/core/modules/toolbar/toolbar.api.php b/core/modules/toolbar/toolbar.api.php index b2d04091..548b4889 100644 --- a/core/modules/toolbar/toolbar.api.php +++ b/core/modules/toolbar/toolbar.api.php @@ -45,45 +45,45 @@ * @ingroup toolbar_tabs */ function hook_toolbar() { - $items = array(); + $items = []; // Add a search field to the toolbar. The search field employs no toolbar // module theming functions. - $items['global_search'] = array( + $items['global_search'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'search', - '#attributes' => array( + '#attributes' => [ 'placeholder' => t('Search the site'), - 'class' => array('search-global'), - ), - ), + 'class' => ['search-global'], + ], + ], '#weight' => 200, // Custom CSS, JS or a library can be associated with the toolbar item. - '#attached' => array( - 'library' => array( + '#attached' => [ + 'library' => [ 'search/global', - ), - ), - ); + ], + ], + ]; // The 'Home' tab is a simple link, which is wrapped in markup associated // with a visual tab styling. - $items['home'] = array( + $items['home'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => t('Home'), '#url' => Url::fromRoute(''), - '#options' => array( - 'attributes' => array( + '#options' => [ + 'attributes' => [ 'title' => t('Home page'), - 'class' => array('toolbar-icon', 'toolbar-icon-home'), - ), - ), - ), + 'class' => ['toolbar-icon', 'toolbar-icon-home'], + ], + ], + ], '#weight' => -20, - ); + ]; // A tray may be associated with a tab. // @@ -93,27 +93,27 @@ function hook_toolbar() { // The tray should contain a renderable array. An optional #heading property // can be passed. This text is written to a heading tag in the tray as a // landmark for accessibility. - $items['commerce'] = array( + $items['commerce'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => t('Shopping cart'), '#url' => Url::fromRoute('cart'), - '#options' => array( - 'attributes' => array( + '#options' => [ + 'attributes' => [ 'title' => t('Shopping cart'), - ), - ), - ), - 'tray' => array( + ], + ], + ], + 'tray' => [ '#heading' => t('Shopping cart actions'), - 'shopping_cart' => array( + 'shopping_cart' => [ '#theme' => 'item_list', - '#items' => array( /* An item list renderable array */ ), - ), - ), + '#items' => [/* An item list renderable array */], + ], + ], '#weight' => 150, - ); + ]; // The tray can be used to render arbitrary content. // @@ -123,28 +123,28 @@ function hook_toolbar() { // If the default behavior and styling of a toolbar tray is not desired, one // can render content to the toolbar element and apply custom theming and // behaviors. - $items['user_messages'] = array( + $items['user_messages'] = [ // Include the toolbar_tab_wrapper to style the link like a toolbar tab. // Exclude the theme wrapper if custom styling is desired. '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#theme' => 'user_message_toolbar_tab', - '#theme_wrappers' => array(), + '#theme_wrappers' => [], '#title' => t('Messages'), '#url' => Url::fromRoute('user.message'), - '#options' => array( - 'attributes' => array( + '#options' => [ + 'attributes' => [ 'title' => t('Messages'), - ), - ), - ), - 'tray' => array( + ], + ], + ], + 'tray' => [ '#heading' => t('User messages'), - 'messages' => array(/* renderable content */), - ), + 'messages' => [/* renderable content */], + ], '#weight' => 125, - ); + ]; return $items; } diff --git a/core/modules/toolbar/toolbar.info.yml b/core/modules/toolbar/toolbar.info.yml index 41d15534..795d1a1a 100644 --- a/core/modules/toolbar/toolbar.info.yml +++ b/core/modules/toolbar/toolbar.info.yml @@ -7,8 +7,8 @@ package: Core dependencies: - breakpoint -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module index 281f3abb..c7feaee2 100644 --- a/core/modules/toolbar/toolbar.module +++ b/core/modules/toolbar/toolbar.module @@ -20,7 +20,7 @@ function toolbar_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.toolbar': $output = '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Toolbar module provides a toolbar for site administrators, which displays tabs and trays provided by the Toolbar module itself and other modules. For more information, see the online documentation for the Toolbar module.', array(':toolbar_docs' => 'https://www.drupal.org/documentation/modules/toolbar')) . '

    '; + $output .= '

    ' . t('The Toolbar module provides a toolbar for site administrators, which displays tabs and trays provided by the Toolbar module itself and other modules. For more information, see the online documentation for the Toolbar module.', [':toolbar_docs' => 'https://www.drupal.org/documentation/modules/toolbar']) . '

    '; $output .= '

    ' . t('Terminology') . '

    '; $output .= '
    '; $output .= '
    ' . t('Tabs') . '
    '; @@ -36,13 +36,13 @@ function toolbar_help($route_name, RouteMatchInterface $route_match) { * Implements hook_theme(). */ function toolbar_theme($existing, $type, $theme, $path) { - $items['toolbar'] = array( + $items['toolbar'] = [ 'render element' => 'element', - ); - $items['menu__toolbar'] = array( + ]; + $items['menu__toolbar'] = [ 'base hook' => 'menu', - 'variables' => array('items' => array(), 'attributes' => array()), - ); + 'variables' => ['items' => [], 'attributes' => []], + ]; return $items; } @@ -53,14 +53,14 @@ function toolbar_theme($existing, $type, $theme, $path) { * Add admin toolbar to the top of the page automatically. */ function toolbar_page_top(array &$page_top) { - $page_top['toolbar'] = array( + $page_top['toolbar'] = [ '#type' => 'toolbar', '#access' => \Drupal::currentUser()->hasPermission('access toolbar'), '#cache' => [ 'keys' => ['toolbar'], 'contexts' => ['user.permissions'], ], - ); + ]; } /** @@ -83,9 +83,9 @@ function template_preprocess_toolbar(&$variables) { // Prepare the trays and tabs for each toolbar item as well as the remainder // variable that will hold any non-tray, non-tab elements. - $variables['trays'] = array(); - $variables['tabs'] = array(); - $variables['remainder'] = array(); + $variables['trays'] = []; + $variables['tabs'] = []; + $variables['remainder'] = []; foreach (Element::children($element) as $key) { // Early rendering to collect the wrapper attributes from // ToolbarItem elements. @@ -94,14 +94,14 @@ function template_preprocess_toolbar(&$variables) { } // Add the tray. if (isset($element[$key]['tray'])) { - $attributes = array(); + $attributes = []; if (!empty($element[$key]['tray']['#wrapper_attributes'])) { $attributes = $element[$key]['tray']['#wrapper_attributes']; } - $variables['trays'][$key] = array( + $variables['trays'][$key] = [ 'links' => $element[$key]['tray'], 'attributes' => new Attribute($attributes), - ); + ]; if (array_key_exists('#heading', $element[$key]['tray'])) { $variables['trays'][$key]['label'] = $element[$key]['tray']['#heading']; } @@ -109,22 +109,22 @@ function template_preprocess_toolbar(&$variables) { // Add the tab. if (isset($element[$key]['tab'])) { - $attributes = array(); + $attributes = []; // Pass the wrapper attributes along. if (!empty($element[$key]['#wrapper_attributes'])) { $attributes = $element[$key]['#wrapper_attributes']; } - $variables['tabs'][$key] = array( + $variables['tabs'][$key] = [ 'link' => $element[$key]['tab'], 'attributes' => new Attribute($attributes), - ); + ]; } // Add other non-tray, non-tab child elements to the remainder variable for // later rendering. foreach (Element::children($element[$key]) as $child_key) { - if (!in_array($child_key, array('tray', 'tab'))) { + if (!in_array($child_key, ['tray', 'tab'])) { $variables['remainder'][$key][$child_key] = $element[$key][$child_key]; } } @@ -136,28 +136,28 @@ function template_preprocess_toolbar(&$variables) { */ function toolbar_toolbar() { // The 'Home' tab is a simple link, with no corresponding tray. - $items['home'] = array( + $items['home'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => t('Back to site'), '#url' => Url::fromRoute(''), - '#attributes' => array( + '#attributes' => [ 'title' => t('Return to site content'), - 'class' => array('toolbar-icon', 'toolbar-icon-escape-admin'), + 'class' => ['toolbar-icon', 'toolbar-icon-escape-admin'], 'data-toolbar-escape-admin' => TRUE, - ), - ), - '#wrapper_attributes' => array( - 'class' => array('hidden', 'home-toolbar-tab'), - ), - '#attached' => array( - 'library' => array( + ], + ], + '#wrapper_attributes' => [ + 'class' => ['home-toolbar-tab'], + ], + '#attached' => [ + 'library' => [ 'toolbar/toolbar.escapeAdmin', - ), - ), + ], + ], '#weight' => -20, - ); + ]; // To conserve bandwidth, we only include the top-level links in the HTML. // The subtrees are fetched through a JSONP script that is generated at the @@ -171,38 +171,38 @@ function toolbar_toolbar() { // The administration element has a link that is themed to correspond to // a toolbar tray. The tray contains the full administrative menu of the site. - $items['administration'] = array( + $items['administration'] = [ '#type' => 'toolbar_item', - 'tab' => array( + 'tab' => [ '#type' => 'link', '#title' => t('Manage'), '#url' => Url::fromRoute('system.admin'), - '#attributes' => array( + '#attributes' => [ 'title' => t('Admin menu'), - 'class' => array('toolbar-icon', 'toolbar-icon-menu'), + 'class' => ['toolbar-icon', 'toolbar-icon-menu'], // A data attribute that indicates to the client to defer loading of // the admin menu subtrees until this tab is activated. Admin menu // subtrees will not render to the DOM if this attribute is removed. // The value of the attribute is intentionally left blank. Only the // presence of the attribute is necessary. 'data-drupal-subtrees' => '', - ), - ), - 'tray' => array( + ], + ], + 'tray' => [ '#heading' => t('Administration menu'), '#attached' => $subtrees_attached, - 'toolbar_administration' => array( - '#pre_render' => array( + 'toolbar_administration' => [ + '#pre_render' => [ 'toolbar_prerender_toolbar_administration_tray', - ), + ], '#type' => 'container', - '#attributes' => array( - 'class' => array('toolbar-menu-administration'), - ), - ), - ), + '#attributes' => [ + 'class' => ['toolbar-menu-administration'], + ], + ], + ], '#weight' => -15, - ); + ]; $hash_cacheability->applyTo($items['administration']); return $items; @@ -228,11 +228,11 @@ function toolbar_prerender_toolbar_administration_tray(array $element) { $parameters->setMinDepth(2)->setMaxDepth(2)->onlyEnabledLinks(); // @todo Make the menu configurable in https://www.drupal.org/node/1869638. $tree = $menu_tree->load('admin', $parameters); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), - array('callable' => 'toolbar_menu_navigation_links'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'], + ['callable' => 'toolbar_menu_navigation_links'], + ]; $tree = $menu_tree->transform($tree, $manipulators); $element['administration_menu'] = $menu_tree->build($tree); return $element; @@ -262,7 +262,7 @@ function toolbar_menu_navigation_links(array $tree) { $id = substr(Crypt::hashBase64($url->getUri()), 0, 16); } else { - $id = str_replace(array('.', '<', '>'), array('-', '', ''), $url->getRouteName()); + $id = str_replace(['.', '<', '>'], ['-', '', ''], $url->getRouteName()); } // Get the non-localized title to make the icon class. @@ -270,12 +270,24 @@ function toolbar_menu_navigation_links(array $tree) { $element->options['attributes']['id'] = 'toolbar-link-' . $id; $element->options['attributes']['class'][] = 'toolbar-icon'; - $element->options['attributes']['class'][] = 'toolbar-icon-' . strtolower(str_replace(array('.', ' ', '_'), array('-', '-', '-'), $definition['id'])); + $element->options['attributes']['class'][] = 'toolbar-icon-' . strtolower(str_replace(['.', ' ', '_'], ['-', '-', '-'], $definition['id'])); $element->options['attributes']['title'] = $link->getDescription(); } return $tree; } +/** + * Implements hook_preprocess_HOOK() for HTML document templates. + */ +function toolbar_preprocess_html(&$variables) { + if (!\Drupal::currentUser()->hasPermission('access toolbar')) { + return; + } + + $variables['attributes'] = new Attribute($variables['attributes']); + $variables['attributes']->addClass(['toolbar-tray-open', 'toolbar-horizontal', 'toolbar-fixed', 'toolbar-loading']); +} + /** * Returns the rendered subtree of each top-level toolbar link. * @@ -310,13 +322,13 @@ function _toolbar_do_get_rendered_subtrees(array $data) { $parameters->setMinDepth(2)->setMaxDepth(4)->onlyEnabledLinks(); // @todo Make the menu configurable in https://www.drupal.org/node/1869638. $tree = $menu_tree->load('admin', $parameters); - $manipulators = array( - array('callable' => 'menu.default_tree_manipulators:checkAccess'), - array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), - array('callable' => 'toolbar_menu_navigation_links'), - ); + $manipulators = [ + ['callable' => 'menu.default_tree_manipulators:checkAccess'], + ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'], + ['callable' => 'toolbar_menu_navigation_links'], + ]; $tree = $menu_tree->transform($tree, $manipulators); - $subtrees = array(); + $subtrees = []; // Calculated the combined cacheability of all subtrees. $cacheability = new CacheableMetadata(); foreach ($tree as $element) { @@ -333,7 +345,7 @@ function _toolbar_do_get_rendered_subtrees(array $data) { // Many routes have dots as route name, while some special ones like // have <> characters in them. $url = $link->getUrlObject(); - $id = str_replace(array('.', '<', '>'), array('-', '', '' ), $url->isRouted() ? $url->getRouteName() : $url->getUri()); + $id = str_replace(['.', '<', '>'], ['-', '', ''], $url->isRouted() ? $url->getRouteName() : $url->getUri()); $subtrees[$id] = $output; } diff --git a/core/modules/tour/js/tour.es6.js b/core/modules/tour/js/tour.es6.js new file mode 100644 index 00000000..f3b11072 --- /dev/null +++ b/core/modules/tour/js/tour.es6.js @@ -0,0 +1,268 @@ +/** + * @file + * Attaches behaviors for the Tour module's toolbar tab. + */ + +(function ($, Backbone, Drupal, document) { + const queryString = decodeURI(window.location.search); + + /** + * Attaches the tour's toolbar tab behavior. + * + * It uses the query string for: + * - tour: When ?tour=1 is present, the tour will start automatically after + * the page has loaded. + * - tips: Pass ?tips=class in the url to filter the available tips to the + * subset which match the given class. + * + * @example + * http://example.com/foo?tour=1&tips=bar + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attach tour functionality on `tour` events. + */ + Drupal.behaviors.tour = { + attach(context) { + $('body').once('tour').each(() => { + const model = new Drupal.tour.models.StateModel(); + new Drupal.tour.views.ToggleTourView({ + el: $(context).find('#toolbar-tab-tour'), + model, + }); + + model + // Allow other scripts to respond to tour events. + .on('change:isActive', (model, isActive) => { + $(document).trigger((isActive) ? 'drupalTourStarted' : 'drupalTourStopped'); + }) + // Initialization: check whether a tour is available on the current + // page. + .set('tour', $(context).find('ol#tour')); + + // Start the tour immediately if toggled via query string. + if (/tour=?/i.test(queryString)) { + model.set('isActive', true); + } + }); + }, + }; + + /** + * @namespace + */ + Drupal.tour = Drupal.tour || { + + /** + * @namespace Drupal.tour.models + */ + models: {}, + + /** + * @namespace Drupal.tour.views + */ + views: {}, + }; + + /** + * Backbone Model for tours. + * + * @constructor + * + * @augments Backbone.Model + */ + Drupal.tour.models.StateModel = Backbone.Model.extend(/** @lends Drupal.tour.models.StateModel# */{ + + /** + * @type {object} + */ + defaults: /** @lends Drupal.tour.models.StateModel# */{ + + /** + * Indicates whether the Drupal root window has a tour. + * + * @type {Array} + */ + tour: [], + + /** + * Indicates whether the tour is currently running. + * + * @type {bool} + */ + isActive: false, + + /** + * Indicates which tour is the active one (necessary to cleanly stop). + * + * @type {Array} + */ + activeTour: [], + }, + }); + + Drupal.tour.views.ToggleTourView = Backbone.View.extend(/** @lends Drupal.tour.views.ToggleTourView# */{ + + /** + * @type {object} + */ + events: { click: 'onClick' }, + + /** + * Handles edit mode toggle interactions. + * + * @constructs + * + * @augments Backbone.View + */ + initialize() { + this.listenTo(this.model, 'change:tour change:isActive', this.render); + this.listenTo(this.model, 'change:isActive', this.toggleTour); + }, + + /** + * @inheritdoc + * + * @return {Drupal.tour.views.ToggleTourView} + * The `ToggleTourView` view. + */ + render() { + // Render the visibility. + this.$el.toggleClass('hidden', this._getTour().length === 0); + // Render the state. + const isActive = this.model.get('isActive'); + this.$el.find('button') + .toggleClass('is-active', isActive) + .prop('aria-pressed', isActive); + return this; + }, + + /** + * Model change handler; starts or stops the tour. + */ + toggleTour() { + if (this.model.get('isActive')) { + const $tour = this._getTour(); + this._removeIrrelevantTourItems($tour, this._getDocument()); + const that = this; + if ($tour.find('li').length) { + $tour.joyride({ + autoStart: true, + postRideCallback() { + that.model.set('isActive', false); + }, + // HTML segments for tip layout. + template: { + link: '×', + button: '', + }, + }); + this.model.set({ isActive: true, activeTour: $tour }); + } + } + else { + this.model.get('activeTour').joyride('destroy'); + this.model.set({ isActive: false, activeTour: [] }); + } + }, + + /** + * Toolbar tab click event handler; toggles isActive. + * + * @param {jQuery.Event} event + * The click event. + */ + onClick(event) { + this.model.set('isActive', !this.model.get('isActive')); + event.preventDefault(); + event.stopPropagation(); + }, + + /** + * Gets the tour. + * + * @return {jQuery} + * A jQuery element pointing to a `
      ` containing tour items. + */ + _getTour() { + return this.model.get('tour'); + }, + + /** + * Gets the relevant document as a jQuery element. + * + * @return {jQuery} + * A jQuery element pointing to the document within which a tour would be + * started given the current state. + */ + _getDocument() { + return $(document); + }, + + /** + * Removes tour items for elements that don't have matching page elements. + * + * Or that are explicitly filtered out via the 'tips' query string. + * + * @example + *
    This will filter out tips that do not have a matching + * page element or don't have the "bar" class.This will filter out tips that do not have a matching - * page element or don't have the "bar" class.
    +

    {{ row.data.view_name.data }}

    +
    + {{ row.data.machine_name.data }} + + {{ row.data.description.data }} + + {{ row.data.displays.data }} + + {{ row.data.operations.data }} +
    diff --git a/core/modules/views_ui/tests/modules/views_ui_test/views_ui_test.info.yml b/core/modules/views_ui/tests/modules/views_ui_test/views_ui_test.info.yml index 99a86b53..29631a78 100644 --- a/core/modules/views_ui/tests/modules/views_ui_test/views_ui_test.info.yml +++ b/core/modules/views_ui/tests/modules/views_ui_test/views_ui_test.info.yml @@ -7,8 +7,8 @@ package: Testing dependencies: - views_ui -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/modules/views_ui/tests/modules/views_ui_test_field/views_ui_test_field.info.yml b/core/modules/views_ui/tests/modules/views_ui_test_field/views_ui_test_field.info.yml new file mode 100644 index 00000000..cd1c16d1 --- /dev/null +++ b/core/modules/views_ui/tests/modules/views_ui_test_field/views_ui_test_field.info.yml @@ -0,0 +1,14 @@ +name: 'Views test field' +type: module +description: 'Add custom global field for testing purposes.' +package: Testing +# version: VERSION +# core: 8.x +dependencies: + - views_ui + +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' +core: '8.x' +project: 'drupal' +datestamp: 1509562424 diff --git a/core/modules/views_ui/tests/modules/views_ui_test_field/views_ui_test_field.module b/core/modules/views_ui/tests/modules/views_ui_test_field/views_ui_test_field.module new file mode 100644 index 00000000..3d1ac8f6 --- /dev/null +++ b/core/modules/views_ui/tests/modules/views_ui_test_field/views_ui_test_field.module @@ -0,0 +1,18 @@ + t('Views test field 1 - FIELD_1_TITLE'), + 'help' => t('Field 1 for testing purposes - FIELD_1_DESCRIPTION'), + 'field' => [ + 'id' => 'views_test_field_1', + ], + ]; + $data['views']['views_test_field_2'] = [ + 'title' => t('Views test field 2 - FIELD_2_TITLE'), + 'help' => t('Field 2 for testing purposes - FIELD_2_DESCRIPTION'), + 'field' => [ + 'id' => 'views_test_field_2', + ], + ]; + + return $data; +} diff --git a/core/modules/views_ui/tests/src/Functional/AnalyzeTest.php b/core/modules/views_ui/tests/src/Functional/AnalyzeTest.php new file mode 100644 index 00000000..32d1ae98 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/AnalyzeTest.php @@ -0,0 +1,48 @@ +drupalLogin($this->adminUser); + + $this->drupalGet('admin/structure/views/view/test_view/edit'); + $this->assertLink(t('Analyze view')); + + // This redirects the user to the analyze form. + $this->clickLink(t('Analyze view')); + $this->assertSession()->titleEquals('View analysis | Drupal'); + + foreach (['ok', 'warning', 'error'] as $type) { + $xpath = $this->xpath('//div[contains(@class, :class)]', [':class' => $type]); + $this->assertTrue(count($xpath), format_string('Analyse messages with @type found', ['@type' => $type])); + } + + // This redirects the user back to the main views edit page. + $this->drupalPostForm(NULL, [], t('Ok')); + } + +} diff --git a/core/modules/views_ui/src/Tests/AreaEntityUITest.php b/core/modules/views_ui/tests/src/Functional/AreaEntityUITest.php similarity index 93% rename from core/modules/views_ui/src/Tests/AreaEntityUITest.php rename to core/modules/views_ui/tests/src/Functional/AreaEntityUITest.php index ffe895ab..d74575fd 100644 --- a/core/modules/views_ui/src/Tests/AreaEntityUITest.php +++ b/core/modules/views_ui/tests/src/Functional/AreaEntityUITest.php @@ -1,6 +1,6 @@ drupalGet($view->urlInfo('edit-form')); // Add a global NULL argument to the view for testing argument placeholders. - $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/argument", ['name[views.null]' => 1], 'Add and configure contextual filters'); + $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/argument", ['name[views.null]' => TRUE], 'Add and configure contextual filters'); $this->drupalPostForm(NULL, [], 'Apply'); // Configure both the entity_test area header and the block header to // reference the given entities. - $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_block]' => 1], 'Add and configure header'); + $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_block]' => TRUE], 'Add and configure header'); $this->drupalPostForm(NULL, ['options[target]' => $block->id()], 'Apply'); - $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_entity_test]' => 1], 'Add and configure header'); + $this->drupalPostForm("admin/structure/views/nojs/add-handler/$id/page_1/header", ['name[views.entity_entity_test]' => TRUE], 'Add and configure header'); $this->drupalPostForm(NULL, ['options[target]' => $entity_test->id()], 'Apply'); $this->drupalPostForm(NULL, [], 'Save'); diff --git a/core/modules/views_ui/src/Tests/ArgumentValidatorTest.php b/core/modules/views_ui/tests/src/Functional/ArgumentValidatorTest.php similarity index 93% rename from core/modules/views_ui/src/Tests/ArgumentValidatorTest.php rename to core/modules/views_ui/tests/src/Functional/ArgumentValidatorTest.php index b62f876e..5a33970f 100644 --- a/core/modules/views_ui/src/Tests/ArgumentValidatorTest.php +++ b/core/modules/views_ui/tests/src/Functional/ArgumentValidatorTest.php @@ -1,6 +1,6 @@ 'entity---node', 'options[specify_validation]' => $specify_validation, - ); + ]; $this->drupalPostForm('admin/structure/views/nojs/handler/test_argument/default/argument/id', $options, t('Apply')); - $this->drupalPostForm('admin/structure/views/view/test_argument', array(), t('Save')); + $this->drupalPostForm('admin/structure/views/view/test_argument', [], t('Save')); } } diff --git a/core/modules/views_ui/src/Tests/CachedDataUITest.php b/core/modules/views_ui/tests/src/Functional/CachedDataUITest.php similarity index 82% rename from core/modules/views_ui/src/Tests/CachedDataUITest.php rename to core/modules/views_ui/tests/src/Functional/CachedDataUITest.php index 1f69b196..51e489d9 100644 --- a/core/modules/views_ui/src/Tests/CachedDataUITest.php +++ b/core/modules/views_ui/tests/src/Functional/CachedDataUITest.php @@ -1,6 +1,6 @@ drupalGet('admin/structure/views/view/test_view/edit'); // Make sure we have 'changes' to the view. - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/title', array(), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/title', [], t('Apply')); $this->assertText('You have unsaved changes.'); $this->assertEqual($temp_store->getMetadata('test_view')->owner, $views_admin_user_uid, 'View cache has been saved.'); @@ -39,13 +39,13 @@ public function testCacheData() { $this->assertEqual($temp_store->getMetadata('test_view')->owner, $views_admin_user_uid, 'The view is locked.'); // Cancel the view edit and make sure the cache is deleted. - $this->drupalPostForm(NULL, array(), t('Cancel')); + $this->drupalPostForm(NULL, [], t('Cancel')); $this->assertEqual($temp_store->getMetadata('test_view'), NULL, 'User tempstore data has been removed.'); // Test we are redirected to the view listing page. - $this->assertUrl('admin/structure/views', array(), 'Redirected back to the view listing page.'); + $this->assertUrl('admin/structure/views', [], 'Redirected back to the view listing page.'); // Log in with another user and make sure the view is locked and break. - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/title', array(), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/title', [], t('Apply')); $this->drupalLogin($this->adminUser); $this->drupalGet('admin/structure/views/view/test_view/edit'); @@ -56,17 +56,17 @@ public function testCacheData() { $this->assertLinkByHref('admin/structure/views/view/test_view/break-lock'); // Break the lock. $this->clickLink(t('break this lock')); - $this->drupalPostForm(NULL, array(), t('Break lock')); + $this->drupalPostForm(NULL, [], t('Break lock')); // Test that save and cancel buttons are shown. $this->assertFieldById('edit-actions-submit', t('Save')); $this->assertFieldById('edit-actions-cancel', t('Cancel')); // Test we can save the view. - $this->drupalPostForm('admin/structure/views/view/test_view/edit', array(), t('Save')); - $this->assertRaw(t('The view %view has been saved.', array('%view' => 'Test view'))); + $this->drupalPostForm('admin/structure/views/view/test_view/edit', [], t('Save')); + $this->assertRaw(t('The view %view has been saved.', ['%view' => 'Test view'])); // Test that a deleted view has no tempstore data. - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/title', array(), t('Apply')); - $this->drupalPostForm('admin/structure/views/view/test_view/delete', array(), t('Delete')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/default/title', [], t('Apply')); + $this->drupalPostForm('admin/structure/views/view/test_view/delete', [], t('Delete')); // No view tempstore data should be returned for this view after deletion. $this->assertEqual($temp_store->getMetadata('test_view'), NULL, 'View tempstore data has been removed after deletion.'); } diff --git a/core/modules/views_ui/src/Tests/CustomBooleanTest.php b/core/modules/views_ui/tests/src/Functional/CustomBooleanTest.php similarity index 88% rename from core/modules/views_ui/src/Tests/CustomBooleanTest.php rename to core/modules/views_ui/tests/src/Functional/CustomBooleanTest.php index ecde493b..95f6d566 100644 --- a/core/modules/views_ui/src/Tests/CustomBooleanTest.php +++ b/core/modules/views_ui/tests/src/Functional/CustomBooleanTest.php @@ -1,6 +1,6 @@ setDisplay(); - $view->displayHandlers->get('default')->overrideOption('fields', array( - 'age' => array( + $view->displayHandlers->get('default')->overrideOption('fields', [ + 'age' => [ 'id' => 'age', 'table' => 'views_test_data', 'field' => 'age', 'relationship' => 'none', 'plugin_id' => 'boolean', - ), - )); + ], + ]); $view->save(); $this->executeView($view); @@ -64,35 +64,35 @@ public function testCustomOption() { $custom_false = 'Nay'; // Set up some custom value mappings for different types. - $custom_values = array( - 'plain' => array( + $custom_values = [ + 'plain' => [ 'true' => $custom_true, 'false' => $custom_false, 'test' => 'assertTrue', - ), - 'allowed tag' => array( + ], + 'allowed tag' => [ 'true' => '

    ' . $custom_true . '

    ', 'false' => '

    ' . $custom_false . '

    ', 'test' => 'assertTrue', - ), - 'disallowed tag' => array( + ], + 'disallowed tag' => [ 'true' => '', 'false' => '', 'test' => 'assertFalse', - ), - ); + ], + ]; // Run the same tests on each type. foreach ($custom_values as $type => $values) { - $options = array( + $options = [ 'options[type]' => 'custom', 'options[type_custom_true]' => $values['true'], 'options[type_custom_false]' => $values['false'], - ); + ]; $this->drupalPostForm('admin/structure/views/nojs/handler/test_view/default/field/age', $options, 'Apply'); // Save the view. - $this->drupalPostForm('admin/structure/views/view/test_view', array(), 'Save'); + $this->drupalPostForm('admin/structure/views/view/test_view', [], 'Save'); $view = Views::getView('test_view'); $output = $view->preview(); @@ -136,35 +136,35 @@ public function testCustomOptionTemplate() { $custom_false = 'Nay'; // Set up some custom value mappings for different types. - $custom_values = array( - 'plain' => array( + $custom_values = [ + 'plain' => [ 'true' => $custom_true, 'false' => $custom_false, 'test' => 'assertTrue', - ), - 'allowed tag' => array( + ], + 'allowed tag' => [ 'true' => '

    ' . $custom_true . '

    ', 'false' => '

    ' . $custom_false . '

    ', 'test' => 'assertTrue', - ), - 'disallowed tag' => array( + ], + 'disallowed tag' => [ 'true' => '', 'false' => '', 'test' => 'assertFalse', - ), - ); + ], + ]; // Run the same tests on each type. foreach ($custom_values as $type => $values) { - $options = array( + $options = [ 'options[type]' => 'custom', 'options[type_custom_true]' => $values['true'], 'options[type_custom_false]' => $values['false'], - ); + ]; $this->drupalPostForm('admin/structure/views/nojs/handler/test_view/default/field/age', $options, 'Apply'); // Save the view. - $this->drupalPostForm('admin/structure/views/view/test_view', array(), 'Save'); + $this->drupalPostForm('admin/structure/views/view/test_view', [], 'Save'); $view = Views::getView('test_view'); $output = $view->preview(); @@ -173,8 +173,7 @@ public function testCustomOptionTemplate() { $this->{$values['test']}(strpos($output, $values['false']), SafeMarkup::format('Expected custom boolean FALSE value %value in output for %type', ['%value' => $values['false'], '%type' => $type])); // Assert that we are using the correct template. - $this->setRawContent($output); - $this->assertText('llama', 'Loaded the correct views-view-field.html.twig template'); + $this->assertContains('llama', (string) $output); } } diff --git a/core/modules/views_ui/tests/src/Functional/DefaultViewsTest.php b/core/modules/views_ui/tests/src/Functional/DefaultViewsTest.php new file mode 100644 index 00000000..91ee05be --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/DefaultViewsTest.php @@ -0,0 +1,247 @@ +placeBlock('page_title_block'); + } + + /** + * Tests default views. + */ + public function testDefaultViews() { + // Make sure the view starts off as disabled (does not appear on the listing + // page). + $edit_href = 'admin/structure/views/view/glossary'; + $this->drupalGet('admin/structure/views'); + // @todo Disabled default views do now appear on the front page. Test this + // behavior with templates instead. + // $this->assertNoLinkByHref($edit_href); + + // Enable the view, and make sure it is now visible on the main listing + // page. + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Enable'), '/glossary/'); + $this->assertUrl('admin/structure/views'); + $this->assertLinkByHref($edit_href); + + // It should not be possible to revert the view yet. + // @todo Figure out how to handle this with the new configuration system. + // $this->assertNoLink(t('Revert')); + // $revert_href = 'admin/structure/views/view/glossary/revert'; + // $this->assertNoLinkByHref($revert_href); + + // Edit the view and change the title. Make sure that the new title is + // displayed. + $new_title = $this->randomMachineName(16); + $edit = ['title' => $new_title]; + $this->drupalPostForm('admin/structure/views/nojs/display/glossary/page_1/title', $edit, t('Apply')); + $this->drupalPostForm('admin/structure/views/view/glossary/edit/page_1', [], t('Save')); + $this->drupalGet('glossary'); + $this->assertResponse(200); + $this->assertText($new_title); + + // Save another view in the UI. + $this->drupalPostForm('admin/structure/views/nojs/display/archive/page_1/title', [], t('Apply')); + $this->drupalPostForm('admin/structure/views/view/archive/edit/page_1', [], t('Save')); + + // Check there is an enable link. i.e. The view has not been enabled after + // editing. + $this->drupalGet('admin/structure/views'); + $this->assertLinkByHref('admin/structure/views/view/archive/enable'); + // Enable it again so it can be tested for access permissions. + $this->clickViewsOperationLink(t('Enable'), '/archive/'); + + // It should now be possible to revert the view. Do that, and make sure the + // view title we added above no longer is displayed. + // $this->drupalGet('admin/structure/views'); + // $this->assertLink(t('Revert')); + // $this->assertLinkByHref($revert_href); + // $this->drupalPostForm($revert_href, array(), t('Revert')); + // $this->drupalGet('glossary'); + // $this->assertNoText($new_title); + + // Duplicate the view and check that the normal schema of duplicated views is used. + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Duplicate'), '/glossary'); + $edit = [ + 'id' => 'duplicate_of_glossary', + ]; + $this->assertTitle(t('Duplicate of @label | @site-name', ['@label' => 'Glossary', '@site-name' => $this->config('system.site')->get('name')])); + $this->drupalPostForm(NULL, $edit, t('Duplicate')); + $this->assertUrl('admin/structure/views/view/duplicate_of_glossary', [], 'The normal duplicating name schema is applied.'); + + // Duplicate a view and set a custom name. + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Duplicate'), '/glossary'); + $random_name = strtolower($this->randomMachineName()); + $this->drupalPostForm(NULL, ['id' => $random_name], t('Duplicate')); + $this->assertUrl("admin/structure/views/view/$random_name", [], 'The custom view name got saved.'); + + // Now disable the view, and make sure it stops appearing on the main view + // listing page but instead goes back to displaying on the disabled views + // listing page. + // @todo Test this behavior with templates instead. + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Disable'), '/glossary/'); + // $this->assertUrl('admin/structure/views'); + // $this->assertNoLinkByHref($edit_href); + // The easiest way to verify it appears on the disabled views listing page + // is to try to click the "enable" link from there again. + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Enable'), '/glossary/'); + $this->assertUrl('admin/structure/views'); + $this->assertLinkByHref($edit_href); + + // Clear permissions for anonymous users to check access for default views. + Role::load(RoleInterface::ANONYMOUS_ID)->revokePermission('access content')->save(); + + // Test the default views disclose no data by default. + $this->drupalLogout(); + $this->drupalGet('glossary'); + $this->assertResponse(403); + $this->drupalGet('archive'); + $this->assertResponse(403); + + // Test deleting a view. + $this->drupalLogin($this->fullAdminUser); + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Delete'), '/glossary/'); + // Submit the confirmation form. + $this->drupalPostForm(NULL, [], t('Delete')); + // Ensure the view is no longer listed. + $this->assertUrl('admin/structure/views'); + $this->assertNoLinkByHref($edit_href); + // Ensure the view is no longer available. + $this->drupalGet($edit_href); + $this->assertResponse(404); + $this->assertText('Page not found'); + + // Delete all duplicated Glossary views. + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Delete'), 'duplicate_of_glossary'); + // Submit the confirmation form. + $this->drupalPostForm(NULL, [], t('Delete')); + + $this->drupalGet('glossary'); + $this->assertResponse(200); + + $this->drupalGet('admin/structure/views'); + $this->clickViewsOperationLink(t('Delete'), $random_name); + // Submit the confirmation form. + $this->drupalPostForm(NULL, [], t('Delete')); + $this->drupalGet('glossary'); + $this->assertResponse(404); + $this->assertText('Page not found'); + } + + /** + * Tests that enabling views moves them to the correct table. + */ + public function testSplitListing() { + // Build a re-usable xpath query. + $xpath = '//div[@id="views-entity-list"]/div[@class = :status]/table//td/text()[contains(., :title)]'; + + $arguments = [ + ':status' => 'views-list-section enabled', + ':title' => 'test_view_status', + ]; + + $this->drupalGet('admin/structure/views'); + + $elements = $this->xpath($xpath, $arguments); + $this->assertIdentical(count($elements), 0, 'A disabled view is not found in the enabled views table.'); + + $arguments[':status'] = 'views-list-section disabled'; + $elements = $this->xpath($xpath, $arguments); + $this->assertIdentical(count($elements), 1, 'A disabled view is found in the disabled views table.'); + + // Enable the view. + $this->clickViewsOperationLink(t('Enable'), '/test_view_status/'); + + $elements = $this->xpath($xpath, $arguments); + $this->assertIdentical(count($elements), 0, 'After enabling a view, it is not found in the disabled views table.'); + + $arguments[':status'] = 'views-list-section enabled'; + $elements = $this->xpath($xpath, $arguments); + $this->assertIdentical(count($elements), 1, 'After enabling a view, it is found in the enabled views table.'); + + // Attempt to disable the view by path directly, with no token. + $this->drupalGet('admin/structure/views/view/test_view_status/disable'); + $this->assertResponse(403); + } + + /** + * Tests that page displays show the correct path. + */ + public function testPathDestination() { + $this->drupalGet('admin/structure/views'); + + // Check that links to views on default tabs are rendered correctly. + $this->assertLinkByHref('test_page_display_menu'); + $this->assertNoLinkByHref('test_page_display_menu/default'); + $this->assertLinkByHref('test_page_display_menu/local'); + + // Check that a dynamic path is shown as text. + $this->assertRaw('test_route_with_suffix/%/suffix'); + $this->assertNoLinkByHref(Url::fromUri('base:test_route_with_suffix/%/suffix')->toString()); + } + + /** + * Click a link to perform an operation on a view. + * + * In general, we expect lots of links titled "enable" or "disable" on the + * various views listing pages, and they might have tokens in them. So we + * need special code to find the correct one to click. + * + * @param $label + * Text between the anchor tags of the desired link. + * @param $unique_href_part + * A unique string that is expected to occur within the href of the desired + * link. For example, if the link URL is expected to look like + * "admin/structure/views/view/glossary/*", then "/glossary/" could be + * passed as the expected unique string. + * + * @return + * The page content that results from clicking on the link, or FALSE on + * failure. Failure also results in a failed assertion. + */ + public function clickViewsOperationLink($label, $unique_href_part) { + $links = $this->xpath('//a[normalize-space(text())=:label]', [':label' => (string) $label]); + foreach ($links as $link_index => $link) { + $position = strpos($link->getAttribute('href'), $unique_href_part); + if ($position !== FALSE) { + $index = $link_index; + break; + } + } + $this->assertTrue(isset($index), format_string('Link to "@label" containing @part found.', ['@label' => $label, '@part' => $unique_href_part])); + if (isset($index)) { + return $this->clickLink((string) $label, $index); + } + else { + return FALSE; + } + } + +} diff --git a/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php b/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php new file mode 100644 index 00000000..057a785c --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/DisplayAttachmentTest.php @@ -0,0 +1,97 @@ +drupalGet('admin/structure/views/view/test_attachment_ui/edit/attachment_1'); + $this->assertText(t('Not defined'), 'The right text appears if there is no attachment selection yet.'); + + $attachment_display_url = 'admin/structure/views/nojs/display/test_attachment_ui/attachment_1/displays'; + $this->drupalGet($attachment_display_url); + // Display labels should be escaped. + $this->assertEscaped('Page'); + + foreach (['default', 'page-1'] as $display_id) { + $this->assertNoFieldChecked("edit-displays-$display_id", format_string('Make sure the @display_id can be marked as attached', ['@display_id' => $display_id])); + } + + // Save the attachments and test the value on the view. + $this->drupalPostForm($attachment_display_url, ['displays[page_1]' => 1], t('Apply')); + // Options summary should be escaped. + $this->assertEscaped('Page'); + $this->assertNoRaw('Page'); + $result = $this->xpath('//a[@id = :id]', [':id' => 'views-attachment-1-displays']); + $this->assertEqual($result[0]->getAttribute('title'), t('Page')); + $this->drupalPostForm(NULL, [], t('Save')); + + $view = Views::getView('test_attachment_ui'); + $view->initDisplay(); + $this->assertEqual(array_keys(array_filter($view->displayHandlers->get('attachment_1')->getOption('displays'))), ['page_1'], 'The attached displays got saved as expected'); + + $this->drupalPostForm($attachment_display_url, ['displays[default]' => 1, 'displays[page_1]' => 1], t('Apply')); + $result = $this->xpath('//a[@id = :id]', [':id' => 'views-attachment-1-displays']); + $this->assertEqual($result[0]->getAttribute('title'), t('Multiple displays')); + $this->drupalPostForm(NULL, [], t('Save')); + + $view = Views::getView('test_attachment_ui'); + $view->initDisplay(); + $this->assertEqual(array_keys($view->displayHandlers->get('attachment_1')->getOption('displays')), ['default', 'page_1'], 'The attached displays got saved as expected'); + } + + /** + * Tests the attachment working after the attached page was deleted. + */ + public function testRemoveAttachedDisplay() { + // Create a view. + $view = $this->randomView(); + $path_prefix = 'admin/structure/views/view/' . $view['id'] . '/edit'; + $attachment_display_url = 'admin/structure/views/nojs/display/' . $view['id'] . '/attachment_1/displays'; + + // Open the Page display and create the attachment display. + $this->drupalGet($path_prefix . '/page_1'); + $this->drupalPostForm(NULL, [], 'Add Attachment'); + $this->assertText(t('Not defined'), 'The right text appears if there is no attachment selection yet.'); + + // Attach the Attachment to the Page display. + $this->drupalPostForm($attachment_display_url, ['displays[page_1]' => 1], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); + + // Open the Page display and mark it as deleted. + $this->drupalGet($path_prefix . '/page_1'); + $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-delete', 'Delete Page', 'Make sure there is a delete button on the page display.'); + $this->drupalPostForm($path_prefix . '/page_1', [], 'Delete Page'); + + // Open the attachment display and save it. + $this->drupalGet($path_prefix . '/attachment_1'); + $this->drupalPostForm(NULL, [], t('Save')); + + // Check that there is no warning for the removed page display. + $this->assertNoText("Plugin ID 'page_1' was not found."); + + // Check that the attachment is no longer linked to the removed display. + $this->assertText(t('Not defined'), 'The right text appears if there is no attachment selection yet.'); + + } + +} diff --git a/core/modules/views_ui/src/Tests/DisplayCRUDTest.php b/core/modules/views_ui/tests/src/Functional/DisplayCRUDTest.php similarity index 78% rename from core/modules/views_ui/src/Tests/DisplayCRUDTest.php rename to core/modules/views_ui/tests/src/Functional/DisplayCRUDTest.php index 1e060dcb..1e53c711 100644 --- a/core/modules/views_ui/src/Tests/DisplayCRUDTest.php +++ b/core/modules/views_ui/tests/src/Functional/DisplayCRUDTest.php @@ -1,6 +1,6 @@ drupalGet($path_prefix); // Add a new display. - $this->drupalPostForm(NULL, array(), 'Add Page'); + $this->drupalPostForm(NULL, [], 'Add Page'); $this->assertLinkByHref($path_prefix . '/page_1', 0, 'Make sure after adding a display the new display appears in the UI'); $this->assertNoLink('Master*', 'Make sure the master display is not marked as changed.'); $this->assertLink('Page*', 0, 'Make sure the added display is marked as changed.'); - $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/path", array('path' => 'test/path'), t('Apply')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/path", ['path' => 'test/path'], t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); } /** @@ -63,22 +63,22 @@ public function testRemoveDisplay() { $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-delete', 'Delete Page', 'Make sure there is a delete button on the page display.'); // Delete the page, so we can test the undo process. - $this->drupalPostForm($path_prefix . '/page_1', array(), 'Delete Page'); + $this->drupalPostForm($path_prefix . '/page_1', [], 'Delete Page'); $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-undo-delete', 'Undo delete of Page', 'Make sure there a undo button on the page display after deleting.'); - $element = $this->xpath('//a[contains(@href, :href) and contains(@class, :class)]', array(':href' => $path_prefix . '/page_1', ':class' => 'views-display-deleted-link')); + $element = $this->xpath('//a[contains(@href, :href) and contains(@class, :class)]', [':href' => $path_prefix . '/page_1', ':class' => 'views-display-deleted-link']); $this->assertTrue(!empty($element), 'Make sure the display link is marked as to be deleted.'); - $element = $this->xpath('//a[contains(@href, :href) and contains(@class, :class)]', array(':href' => $path_prefix . '/page_1', ':class' => 'views-display-deleted-link')); + $element = $this->xpath('//a[contains(@href, :href) and contains(@class, :class)]', [':href' => $path_prefix . '/page_1', ':class' => 'views-display-deleted-link']); $this->assertTrue(!empty($element), 'Make sure the display link is marked as to be deleted.'); // Undo the deleting of the display. - $this->drupalPostForm($path_prefix . '/page_1', array(), 'Undo delete of Page'); + $this->drupalPostForm($path_prefix . '/page_1', [], 'Undo delete of Page'); $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-undo-delete', 'Undo delete of Page', 'Make sure there is no undo button on the page display after reverting.'); $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-delete', 'Delete Page', 'Make sure there is a delete button on the page display after the reverting.'); // Now delete again and save the view. - $this->drupalPostForm($path_prefix . '/page_1', array(), 'Delete Page'); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm($path_prefix . '/page_1', [], 'Delete Page'); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertNoLinkByHref($path_prefix . '/page_1', 'Make sure there is no display tab for the deleted display.'); @@ -86,9 +86,9 @@ public function testRemoveDisplay() { $view = $this->randomView(); $machine_name = 'new_machine_name'; $path_prefix = 'admin/structure/views/view/' . $view['id'] . '/edit'; - $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/display_id", array('display_id' => $machine_name), 'Apply'); - $this->drupalPostForm(NULL, array(), 'Delete Page'); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_1/display_id", ['display_id' => $machine_name], 'Apply'); + $this->drupalPostForm(NULL, [], 'Delete Page'); + $this->drupalPostForm(NULL, [], t('Save')); $this->assertResponse(200); $this->assertNoLinkByHref($path_prefix . '/new_machine_name', 'Make sure there is no display tab for the deleted display.'); } @@ -111,24 +111,24 @@ public function testDuplicateDisplay() { $path = $view['page[path]']; $this->drupalGet($path_prefix); - $this->drupalPostForm(NULL, array(), 'Duplicate Page'); + $this->drupalPostForm(NULL, [], 'Duplicate Page'); $this->assertLinkByHref($path_prefix . '/page_2', 0, 'Make sure after duplicating the new display appears in the UI'); - $this->assertUrl($path_prefix . '/page_2', array(), 'The user got redirected to the new display.'); + $this->assertUrl($path_prefix . '/page_2', [], 'The user got redirected to the new display.'); // Set the title and override the css classes. $random_title = $this->randomMachineName(); $random_css = $this->randomMachineName(); - $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_2/title", array('title' => $random_title), t('Apply')); - $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_2/css_class", array('override[dropdown]' => 'page_2', 'css_class' => $random_css), t('Apply')); + $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_2/title", ['title' => $random_title], t('Apply')); + $this->drupalPostForm("admin/structure/views/nojs/display/{$view['id']}/page_2/css_class", ['override[dropdown]' => 'page_2', 'css_class' => $random_css], t('Apply')); // Duplicate as a different display type. - $this->drupalPostForm(NULL, array(), 'Duplicate as Block'); + $this->drupalPostForm(NULL, [], 'Duplicate as Block'); $this->assertLinkByHref($path_prefix . '/block_1', 0, 'Make sure after duplicating the new display appears in the UI'); - $this->assertUrl($path_prefix . '/block_1', array(), 'The user got redirected to the new display.'); + $this->assertUrl($path_prefix . '/block_1', [], 'The user got redirected to the new display.'); $this->assertText(t('Block settings')); $this->assertNoText(t('Page settings')); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $view = Views::getView($view['id']); $view->initDisplay(); diff --git a/core/modules/views_ui/src/Tests/DisplayExtenderUITest.php b/core/modules/views_ui/tests/src/Functional/DisplayExtenderUITest.php similarity index 76% rename from core/modules/views_ui/src/Tests/DisplayExtenderUITest.php rename to core/modules/views_ui/tests/src/Functional/DisplayExtenderUITest.php index 7e26dffd..b222f15d 100644 --- a/core/modules/views_ui/src/Tests/DisplayExtenderUITest.php +++ b/core/modules/views_ui/tests/src/Functional/DisplayExtenderUITest.php @@ -1,6 +1,6 @@ config('views.settings')->set('display_extenders', array('display_extender_test'))->save(); + $this->config('views.settings')->set('display_extenders', ['display_extender_test'])->save(); $view = Views::getView('test_view'); $view_edit_url = "admin/structure/views/view/{$view->storage->id()}/edit"; @@ -32,9 +32,9 @@ public function testDisplayExtenderUI() { $this->assertLinkByHref($display_option_url, 0, 'Make sure the option defined by the test display extender appears in the UI.'); $random_text = $this->randomMachineName(); - $this->drupalPostForm($display_option_url, array('test_extender_test_option' => $random_text), t('Apply')); + $this->drupalPostForm($display_option_url, ['test_extender_test_option' => $random_text], t('Apply')); $this->assertLink($random_text); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $view = Views::getView($view->storage->id()); $view->initDisplay(); $display_extender_options = $view->display_handler->getOption('display_extenders'); diff --git a/core/modules/views_ui/src/Tests/DisplayFeedTest.php b/core/modules/views_ui/tests/src/Functional/DisplayFeedTest.php similarity index 77% rename from core/modules/views_ui/src/Tests/DisplayFeedTest.php rename to core/modules/views_ui/tests/src/Functional/DisplayFeedTest.php index 4e7bf8a4..9dba4501 100644 --- a/core/modules/views_ui/src/Tests/DisplayFeedTest.php +++ b/core/modules/views_ui/tests/src/Functional/DisplayFeedTest.php @@ -1,6 +1,6 @@ xpath('//div[@id="edit-displays"]/div'); - $options = array(); + $options = []; foreach ($result as $item) { - foreach ($item->input->attributes() as $attribute => $value) { - if ($attribute == 'value') { - $options[] = (string) $value; - } + $input_node = $item->find('css', 'input'); + if ($input_node->hasAttribute('value')) { + $options[] = $input_node->getAttribute('value'); } } - $this->assertEqual($options, array('default', 'page'), 'Make sure all displays appears as expected.'); + $this->assertEqual($options, ['default', 'page'], 'Make sure all displays appears as expected.'); // Post and save this and check the output. - $this->drupalPostForm('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays', array('displays[page]' => 'page'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays', ['displays[page]' => 'page'], t('Apply')); // Options summary should be escaped. $this->assertEscaped('Page'); $this->assertNoRaw('Page'); @@ -76,7 +75,7 @@ protected function checkFeedViewUi($view_name) { $this->assertFieldByXpath('//*[@id="views-feed-1-displays"]', 'Page'); // Add the default display, so there should now be multiple displays. - $this->drupalPostForm('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays', array('displays[default]' => 'default'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/' . $view_name . '/feed_1/displays', ['displays[default]' => 'default'], t('Apply')); $this->drupalGet('admin/structure/views/view/' . $view_name . '/edit/feed_1'); $this->assertFieldByXpath('//*[@id="views-feed-1-displays"]', 'Multiple displays'); } diff --git a/core/modules/views_ui/src/Tests/DisplayPathTest.php b/core/modules/views_ui/tests/src/Functional/DisplayPathTest.php similarity index 76% rename from core/modules/views_ui/src/Tests/DisplayPathTest.php rename to core/modules/views_ui/tests/src/Functional/DisplayPathTest.php index 8baa5064..7291dc2e 100644 --- a/core/modules/views_ui/src/Tests/DisplayPathTest.php +++ b/core/modules/views_ui/tests/src/Functional/DisplayPathTest.php @@ -1,8 +1,10 @@ drupalPlaceBlock('page_title_block'); + $this->placeBlock('page_title_block'); } /** * {@inheritdoc} */ - public static $modules = array('menu_ui'); + public static $modules = ['menu_ui']; /** * Views used by this test. * * @var array */ - public static $testViews = array('test_view', 'test_page_display_menu'); + public static $testViews = ['test_view', 'test_page_display_menu']; /** * Runs the tests. @@ -46,9 +50,9 @@ protected function doBasicPathUITest() { $this->drupalGet('admin/structure/views/view/test_view'); // Add a new page display and check the appearing text. - $this->drupalPostForm(NULL, array(), 'Add Page'); + $this->drupalPostForm(NULL, [], 'Add Page'); $this->assertText(t('No path is set'), 'The right text appears if no path was set.'); - $this->assertNoLink(t('View @display', array('@display' => 'page')), 'No view page link found on the page.'); + $this->assertNoLink(t('View @display', ['@display' => 'page']), 'No view page link found on the page.'); // Save a path and make sure the summary appears as expected. $random_path = $this->randomMachineName(); @@ -56,7 +60,7 @@ protected function doBasicPathUITest() { // longer use Url::fromUri(), and this path will be able to contain ':'. $random_path = str_replace(':', '', $random_path); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => $random_path), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => $random_path], t('Apply')); $this->assertText('/' . $random_path, 'The custom path appears in the summary.'); $display_link_text = t('View @display', ['@display' => 'Page']); $this->assertLink($display_link_text, 0, 'view page link found on the page.'); @@ -69,13 +73,13 @@ protected function doBasicPathUITest() { */ public function doPathXssFilterTest() { $this->drupalGet('admin/structure/views/view/test_view'); - $this->drupalPostForm(NULL, array(), 'Add Page'); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_2/path', array('path' => 'malformed_path'), t('Apply')); - $this->drupalPostForm(NULL, array(), 'Add Page'); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_3/path', array('path' => ''), t('Apply')); - $this->drupalPostForm(NULL, array(), 'Add Page'); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_4/path', array('path' => ''), t('Apply')); - $this->drupalPostForm('admin/structure/views/view/test_view', array(), t('Save')); + $this->drupalPostForm(NULL, [], 'Add Page'); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_2/path', ['path' => 'malformed_path'], t('Apply')); + $this->drupalPostForm(NULL, [], 'Add Page'); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_3/path', ['path' => ''], t('Apply')); + $this->drupalPostForm(NULL, [], 'Add Page'); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_4/path', ['path' => ''], t('Apply')); + $this->drupalPostForm('admin/structure/views/view/test_view', [], t('Save')); $this->drupalGet('admin/structure/views'); // The anchor text should be escaped. $this->assertEscaped('/malformed_path'); @@ -92,11 +96,11 @@ public function doPathXssFilterTest() { protected function doAdvancedPathsValidationTest() { $url = 'admin/structure/views/nojs/display/test_view/page_1/path'; - $this->drupalPostForm($url, array('path' => '%/magrathea'), t('Apply')); + $this->drupalPostForm($url, ['path' => '%/magrathea'], t('Apply')); $this->assertUrl($url); $this->assertText('"%" may not be used for the first segment of a path.'); - $this->drupalPostForm($url, array('path' => 'user/%1/example'), t('Apply')); + $this->drupalPostForm($url, ['path' => 'user/%1/example'], t('Apply')); $this->assertUrl($url); $this->assertText("Numeric placeholders may not be used. Please use plain placeholders (%)."); } @@ -106,51 +110,51 @@ protected function doAdvancedPathsValidationTest() { */ public function testDeleteWithNoPath() { $this->drupalGet('admin/structure/views/view/test_view'); - $this->drupalPostForm(NULL, array(), t('Add Page')); - $this->drupalPostForm(NULL, array(), t('Delete Page')); - $this->drupalPostForm(NULL, array(), t('Save')); - $this->assertRaw(t('The view %view has been saved.', array('%view' => 'Test view'))); + $this->drupalPostForm(NULL, [], t('Add Page')); + $this->drupalPostForm(NULL, [], t('Delete Page')); + $this->drupalPostForm(NULL, [], t('Save')); + $this->assertRaw(t('The view %view has been saved.', ['%view' => 'Test view'])); } /** * Tests the menu and tab option form. */ public function testMenuOptions() { - $this->container->get('module_installer')->install(array('menu_ui')); + $this->container->get('module_installer')->install(['menu_ui']); $this->drupalGet('admin/structure/views/view/test_view'); // Add a new page display. - $this->drupalPostForm(NULL, array(), 'Add Page'); + $this->drupalPostForm(NULL, [], 'Add Page'); // Add an invalid path (only fragment). - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => '#foo'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => '#foo'], t('Apply')); $this->assertText('Path is empty'); // Add an invalid path with a query. - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => 'foo?bar'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => 'foo?bar'], t('Apply')); $this->assertText('No query allowed.'); // Add an invalid path with just a query. - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => '?bar'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => '?bar'], t('Apply')); $this->assertText('Path is empty'); // Provide a random, valid path string. $random_string = $this->randomMachineName(); // Save a path. - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', array('path' => $random_string), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => $random_string], t('Apply')); $this->drupalGet('admin/structure/views/view/test_view'); - $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', array('menu[type]' => 'default tab', 'menu[title]' => 'Test tab title'), t('Apply')); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', ['menu[type]' => 'default tab', 'menu[title]' => 'Test tab title'], t('Apply')); $this->assertResponse(200); $this->assertUrl('admin/structure/views/nojs/display/test_view/page_1/tab_options'); - $this->drupalPostForm(NULL, array('tab_options[type]' => 'tab', 'tab_options[title]' => $this->randomString()), t('Apply')); + $this->drupalPostForm(NULL, ['tab_options[type]' => 'tab', 'tab_options[title]' => $this->randomString()], t('Apply')); $this->assertResponse(200); $this->assertUrl('admin/structure/views/view/test_view/edit/page_1'); $this->drupalGet('admin/structure/views/view/test_view'); - $this->assertLink(t('Tab: @title', array('@title' => 'Test tab title'))); + $this->assertLink(t('Tab: @title', ['@title' => 'Test tab title'])); // If it's a default tab, it should also have an additional settings link. $this->assertLinkByHref('admin/structure/views/nojs/display/test_view/page_1/tab_options'); @@ -158,9 +162,14 @@ public function testMenuOptions() { $this->drupalGet('admin/structure/views/nojs/display/test_page_display_menu/page_5/menu'); $this->assertResponse(200); $menu_parent = $this->xpath('//select[@id="edit-menu-parent"]'); - $menu_options = (array) $menu_parent[0]->option; + $menu_options = (array) $menu_parent[0]->findAll('css', 'option'); unset($menu_options['@attributes']); + // Convert array to make the next assertion possible. + $menu_options = array_map(function ($element) { + return $element->getText(); + }, $menu_options); + $this->assertEqual([ '', '-- My account', diff --git a/core/modules/views_ui/tests/src/Functional/DisplayTest.php b/core/modules/views_ui/tests/src/Functional/DisplayTest.php new file mode 100644 index 00000000..44724b42 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/DisplayTest.php @@ -0,0 +1,288 @@ +randomView(); + $this->assertNoText('Block'); + $this->assertNoText('Block 2'); + + $this->drupalPostForm(NULL, [], t('Add @display', ['@display' => 'Block'])); + $this->assertText('Block'); + $this->assertNoText('Block 2'); + } + + /** + * Tests reordering of displays. + */ + public function testReorderDisplay() { + $view = [ + 'block[create]' => TRUE + ]; + $view = $this->randomView($view); + + $this->clickLink(t('Reorder displays')); + $this->assertTrue($this->xpath('//tr[@id="display-row-default"]'), 'Make sure the default display appears on the reorder listing'); + $this->assertTrue($this->xpath('//tr[@id="display-row-page_1"]'), 'Make sure the page display appears on the reorder listing'); + $this->assertTrue($this->xpath('//tr[@id="display-row-block_1"]'), 'Make sure the block display appears on the reorder listing'); + + // Ensure the view displays are in the expected order in configuration. + $expected_display_order = ['default', 'block_1', 'page_1']; + $this->assertEqual(array_keys(Views::getView($view['id'])->storage->get('display')), $expected_display_order, 'The correct display names are present.'); + // Put the block display in front of the page display. + $edit = [ + 'displays[page_1][weight]' => 2, + 'displays[block_1][weight]' => 1 + ]; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); + + $view = Views::getView($view['id']); + $displays = $view->storage->get('display'); + $this->assertEqual($displays['default']['position'], 0, 'Make sure the master display comes first.'); + $this->assertEqual($displays['block_1']['position'], 1, 'Make sure the block display comes before the page display.'); + $this->assertEqual($displays['page_1']['position'], 2, 'Make sure the page display comes after the block display.'); + + // Ensure the view displays are in the expected order in configuration. + $this->assertEqual(array_keys($view->storage->get('display')), $expected_display_order, 'The correct display names are present.'); + } + + /** + * Tests disabling of a display. + */ + public function testDisableDisplay() { + $view = $this->randomView(); + $path_prefix = 'admin/structure/views/view/' . $view['id'] . '/edit'; + + $this->drupalGet($path_prefix); + $this->assertFalse($this->xpath('//div[contains(@class, :class)]', [':class' => 'views-display-disabled']), 'Make sure the disabled display css class does not appear after initial adding of a view.'); + + $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', NULL, 'Make sure the disable button is visible.'); + $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', NULL, 'Make sure the enable button is not visible.'); + $this->drupalPostForm(NULL, [], 'Disable Page'); + $this->assertTrue($this->xpath('//div[contains(@class, :class)]', [':class' => 'views-display-disabled']), 'Make sure the disabled display css class appears once the display is marked as such.'); + + $this->assertNoFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-disable', NULL, 'Make sure the disable button is not visible.'); + $this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-enable', NULL, 'Make sure the enable button is visible.'); + $this->drupalPostForm(NULL, [], 'Enable Page'); + $this->assertFalse($this->xpath('//div[contains(@class, :class)]', [':class' => 'views-display-disabled']), 'Make sure the disabled display css class does not appears once the display is enabled again.'); + } + + /** + * Tests views_ui_views_plugins_display_alter is altering plugin definitions. + */ + public function testDisplayPluginsAlter() { + $definitions = Views::pluginManager('display')->getDefinitions(); + + $expected = [ + 'route_name' => 'entity.view.edit_form', + 'route_parameters_names' => ['view' => 'id'], + ]; + + // Test the expected views_ui array exists on each definition. + foreach ($definitions as $definition) { + $this->assertIdentical($definition['contextual links']['entity.view.edit_form'], $expected, 'Expected views_ui array found in plugin definition.'); + } + } + + /** + * Tests display areas. + */ + public function testDisplayAreas() { + // Show the advanced column. + $this->config('views.settings')->set('ui.show.advanced_column', TRUE)->save(); + + // Add a new data display to the view. + $view = Views::getView('test_display'); + $view->storage->addDisplay('display_no_area_test'); + $view->save(); + + $this->drupalGet('admin/structure/views/view/test_display/edit/display_no_area_test_1'); + + $areas = [ + 'header', + 'footer', + 'empty', + ]; + + // Assert that the expected text is found in each area category. + foreach ($areas as $type) { + $element = $this->xpath('//div[contains(@class, :class)]/div', [':class' => $type]); + $this->assertEqual($element[0]->getHtml(), SafeMarkup::format('The selected display type does not use @type plugins', ['@type' => $type])); + } + } + + /** + * Tests the link-display setting. + */ + public function testLinkDisplay() { + // Test setting the link display in the UI form. + $path = 'admin/structure/views/view/test_display/edit/block_1'; + $link_display_path = 'admin/structure/views/nojs/display/test_display/block_1/link_display'; + + // Test the link text displays 'None' and not 'Block 1' + $this->drupalGet($path); + $result = $this->xpath("//a[contains(@href, :path)]", [':path' => $link_display_path]); + $this->assertEqual($result[0]->getHtml(), t('None'), 'Make sure that the link option summary shows "None" by default.'); + + $this->drupalGet($link_display_path); + $this->assertFieldChecked('edit-link-display-0'); + + // Test the default radio option on the link display form. + $this->drupalPostForm($link_display_path, ['link_display' => 'page_1'], t('Apply')); + // The form redirects to the master display. + $this->drupalGet($path); + + $result = $this->xpath("//a[contains(@href, :path)]", [':path' => $link_display_path]); + $this->assertEqual($result[0]->getHtml(), 'Page', 'Make sure that the link option summary shows the right linked display.'); + + $this->drupalPostForm($link_display_path, ['link_display' => 'custom_url', 'link_url' => 'a-custom-url'], t('Apply')); + // The form redirects to the master display. + $this->drupalGet($path); + + $this->assertLink(t('Custom URL'), 0, 'The link option has custom URL as summary.'); + + // Test the default link_url value for new display + $this->drupalPostForm(NULL, [], t('Add Block')); + $this->assertUrl('admin/structure/views/view/test_display/edit/block_2'); + $this->clickLink(t('Custom URL')); + $this->assertFieldByName('link_url', 'a-custom-url'); + } + + /** + * Tests that the view status is correctly reflected on the edit form. + */ + public function testViewStatus() { + $view = $this->randomView(); + $id = $view['id']; + + // The view should initially have the enabled class on it's form wrapper. + $this->drupalGet('admin/structure/views/view/' . $id); + $elements = $this->xpath('//div[contains(@class, :edit) and contains(@class, :status)]', [':edit' => 'views-edit-view', ':status' => 'enabled']); + $this->assertTrue($elements, 'The enabled class was found on the form wrapper'); + + $view = Views::getView($id); + $view->storage->disable()->save(); + + $this->drupalGet('admin/structure/views/view/' . $id); + $elements = $this->xpath('//div[contains(@class, :edit) and contains(@class, :status)]', [':edit' => 'views-edit-view', ':status' => 'disabled']); + $this->assertTrue($elements, 'The disabled class was found on the form wrapper.'); + } + + /** + * Ensures that no XSS is possible for buttons. + */ + public function testDisplayTitleInButtonsXss() { + $xss_markup = '">'; + $view = $this->randomView(); + $view = View::load($view['id']); + \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.master_display', TRUE)->save(); + + foreach ([$xss_markup, '">'] as $input) { + $display =& $view->getDisplay('page_1'); + $display['display_title'] = $input; + $view->save(); + + $this->drupalGet("admin/structure/views/view/{$view->id()}"); + $escaped = views_ui_truncate($input, 25); + $this->assertEscaped($escaped); + $this->assertNoRaw($xss_markup); + + $this->drupalGet("admin/structure/views/view/{$view->id()}/edit/page_1"); + $this->assertEscaped("View $escaped"); + $this->assertNoRaw("View $xss_markup"); + $this->assertEscaped("Duplicate $escaped"); + $this->assertNoRaw("Duplicate $xss_markup"); + $this->assertEscaped("Delete $escaped"); + $this->assertNoRaw("Delete $xss_markup"); + } + } + + /** + * Tests the action links on the edit display UI. + */ + public function testActionLinks() { + // Change the display title of a display so it contains characters that will + // be escaped when rendered. + $display_title = "''"; + $this->drupalGet('admin/structure/views/view/test_display'); + $display_title_path = 'admin/structure/views/nojs/display/test_display/block_1/display_title'; + $this->drupalPostForm($display_title_path, ['display_title' => $display_title], t('Apply')); + + // Ensure that the title is escaped as expected. + $this->assertEscaped($display_title); + $this->assertNoRaw($display_title); + + // Ensure that the dropdown buttons are displayed correctly. + $this->assertFieldByXpath('//input[@type="submit"]', 'Duplicate ' . $display_title); + $this->assertFieldByXpath('//input[@type="submit"]', 'Delete ' . $display_title); + $this->assertFieldByXpath('//input[@type="submit"]', 'Disable ' . $display_title); + $this->assertNoFieldByXpath('//input[@type="submit"]', 'Enable ' . $display_title); + + // Disable the display so we can test the rendering of the "Enable" button. + $this->drupalPostForm(NULL, NULL, 'Disable ' . $display_title); + $this->assertFieldByXpath('//input[@type="submit"]', 'Enable ' . $display_title); + $this->assertNoFieldByXpath('//input[@type="submit"]', 'Disable ' . $display_title); + + // Ensure that the title is escaped as expected. + $this->assertEscaped($display_title); + $this->assertNoRaw($display_title); + } + + /** + * Tests that the override option is hidden when it's not needed. + */ + public function testHideDisplayOverride() { + // Test that the override option appears with two displays. + $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); + $this->assertText('All displays'); + + // Remove a display and test if the override option is hidden. + $this->drupalPostForm('admin/structure/views/view/test_display/edit/block_1', [], t('Delete @display', ['@display' => 'Block'])); + $this->drupalPostForm(NULL, [], t('Save')); + + $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); + $this->assertNoText('All displays'); + + // Test that the override option is shown when display master is on. + \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.master_display', TRUE)->save(); + $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); + $this->assertText('All displays'); + + // Test that the override option is shown if the current display is + // overridden so that the option to revert is available. + $this->drupalPostForm(NULL, ['override[dropdown]' => 'page_1'], t('Apply')); + \Drupal::configFactory()->getEditable('views.settings')->set('ui.show.master_display', FALSE)->save(); + $this->drupalGet('admin/structure/views/nojs/handler/test_display/page_1/field/title'); + $this->assertText('Revert to default'); + } + +} diff --git a/core/modules/views_ui/tests/src/Functional/DuplicateTest.php b/core/modules/views_ui/tests/src/Functional/DuplicateTest.php new file mode 100644 index 00000000..91d88fa6 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/DuplicateTest.php @@ -0,0 +1,43 @@ +placeBlock('page_title_block'); + } + + /** + * Checks if duplicated view exists and has correct label. + */ + public function testDuplicateView() { + + // Create random view. + $random_view = $this->randomView(); + + // Initialize array for duplicated view. + $view = []; + + // Generate random label and id for new view. + $view['label'] = $this->randomMachineName(255); + $view['id'] = strtolower($this->randomMachineName(128)); + + // Duplicate view. + $this->drupalPostForm('admin/structure/views/view/' . $random_view['id'] . '/duplicate', $view, t('Duplicate')); + + // Assert that the page url is correct. + $this->assertUrl('admin/structure/views/view/' . $view['id'], [], 'Make sure the view saving was successful and the browser got redirected to the edit page.'); + + // Assert that the page title is correctly displayed. + $this->assertText($view['label']); + } + +} diff --git a/core/modules/views_ui/tests/src/Functional/ExposedFormUITest.php b/core/modules/views_ui/tests/src/Functional/ExposedFormUITest.php new file mode 100644 index 00000000..0822eb83 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/ExposedFormUITest.php @@ -0,0 +1,320 @@ +drupalCreateContentType(['type' => 'article']); + $this->drupalCreateContentType(['type' => 'page']); + + // Create some random nodes. + for ($i = 0; $i < 5; $i++) { + $this->drupalCreateNode(); + } + + // Error strings used in the grouped filter form validation. + $this->groupFormUiErrors['missing_value'] = t('A value is required if the label for this item is defined.'); + $this->groupFormUiErrors['missing_title'] = t('A label is required if the value for this item is defined.'); + $this->groupFormUiErrors['missing_title_empty_operator'] = t('A label is required for the specified operator.'); + } + + /** + * Tests the admin interface of exposed filter and sort items. + */ + public function testExposedAdminUi() { + $edit = []; + + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + // Be sure that the button is called exposed. + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Expose filter')); + + // The first time the filter UI is displayed, the operator and the + // value forms should be shown. + $this->assertFieldById('edit-options-operator-in', 'in', 'Operator In exists'); + $this->assertFieldById('edit-options-operator-not-in', 'not in', 'Operator Not In exists'); + $this->assertFieldById('edit-options-value-page', '', 'Checkbox for Page exists'); + $this->assertFieldById('edit-options-value-article', '', 'Checkbox for Article exists'); + + // Click the Expose filter button. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', $edit, t('Expose filter')); + // Check the label of the expose button. + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide filter')); + + // After exposing the filter, Operator and Value should be still here. + $this->assertFieldById('edit-options-operator-in', 'in', 'Operator In exists'); + $this->assertFieldById('edit-options-operator-not-in', 'not in', 'Operator Not In exists'); + $this->assertFieldById('edit-options-value-page', '', 'Checkbox for Page exists'); + $this->assertFieldById('edit-options-value-article', '', 'Checkbox for Article exists'); + + // Check the validations of the filter handler. + $edit = []; + $edit['options[expose][identifier]'] = ''; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertText(t('The identifier is required if the filter is exposed.')); + + $edit = []; + $edit['options[expose][identifier]'] = 'value'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertText(t('This identifier is not allowed.')); + + // Now check the sort criteria. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/sort/created'); + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Expose sort')); + $this->assertNoFieldById('edit-options-expose-label', '', 'Make sure no label field is shown'); + + // Un-expose the filter. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + $this->drupalPostForm(NULL, [], t('Hide filter')); + + // After Un-exposing the filter, Operator and Value should be shown again. + $this->assertFieldById('edit-options-operator-in', 'in', 'Operator In exists after hide filter'); + $this->assertFieldById('edit-options-operator-not-in', 'not in', 'Operator Not In exists after hide filter'); + $this->assertFieldById('edit-options-value-page', '', 'Checkbox for Page exists after hide filter'); + $this->assertFieldById('edit-options-value-article', '', 'Checkbox for Article exists after hide filter'); + + // Click the Expose sort button. + $edit = []; + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/sort/created', $edit, t('Expose sort')); + // Check the label of the expose button. + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide sort')); + $this->assertFieldById('edit-options-expose-label', 'Authored on', 'Make sure a label field is shown'); + + // Test adding a new exposed sort criteria. + $view_id = $this->randomView()['id']; + $this->drupalGet("admin/structure/views/nojs/add-handler/$view_id/default/sort"); + $this->drupalPostForm(NULL, ['name[node_field_data.created]' => 1], t('Add and configure @handler', ['@handler' => t('sort criteria')])); + $this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'ASC', 'The default order is set.'); + // Change the order and expose the sort. + $this->drupalPostForm(NULL, ['options[order]' => 'DESC'], t('Apply')); + $this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/sort/created", [], t('Expose sort')); + $this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'DESC'); + $this->assertFieldByName('options[expose][label]', 'Authored on', 'The default label is set.'); + // Change the label and save the view. + $edit = ['options[expose][label]' => $this->randomString()]; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->drupalPostForm(NULL, [], t('Save')); + // Check that the values were saved. + $display = View::load($view_id)->getDisplay('default'); + $this->assertTrue($display['display_options']['sorts']['created']['exposed']); + $this->assertEqual($display['display_options']['sorts']['created']['expose'], ['label' => $edit['options[expose][label]']]); + $this->assertEqual($display['display_options']['sorts']['created']['order'], 'DESC'); + } + + /** + * Tests the admin interface of exposed grouped filters. + */ + public function testGroupedFilterAdminUi() { + $edit = []; + + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + + // Click the Expose filter button. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', $edit, t('Expose filter')); + // Check the label of the grouped filters button. + $this->helperButtonHasLabel('edit-options-group-button-button', t('Grouped filters')); + + // Click the Grouped Filters button. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + $this->drupalPostForm(NULL, [], t('Grouped filters')); + + // After click on 'Grouped Filters', the standard operator and value should + // not be displayed. + $this->assertNoFieldById('edit-options-operator-in', 'in', 'Operator In not exists'); + $this->assertNoFieldById('edit-options-operator-not-in', 'not in', 'Operator Not In not exists'); + $this->assertNoFieldById('edit-options-value-page', '', 'Checkbox for Page not exists'); + $this->assertNoFieldById('edit-options-value-article', '', 'Checkbox for Article not exists'); + + // Check that after click on 'Grouped Filters', a new button is shown to + // add more items to the list. + $this->helperButtonHasLabel('edit-options-group-info-add-group', t('Add another item')); + + // Validate a single entry for a grouped filter. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + $edit = []; + $edit["options[group_info][group_items][1][title]"] = 'Is Article'; + $edit["options[group_info][group_items][1][value][article]"] = 'article'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default'); + $this->assertNoGroupedFilterErrors(); + + // Validate multiple entries for grouped filters. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + $edit = []; + $edit["options[group_info][group_items][1][title]"] = 'Is Article'; + $edit["options[group_info][group_items][1][value][article]"] = 'article'; + $edit["options[group_info][group_items][2][title]"] = 'Is Page'; + $edit["options[group_info][group_items][2][value][page]"] = 'page'; + $edit["options[group_info][group_items][3][title]"] = 'Is Page and Article'; + $edit["options[group_info][group_items][3][value][article]"] = 'article'; + $edit["options[group_info][group_items][3][value][page]"] = 'page'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', [], 'Correct validation of the node type filter.'); + $this->assertNoGroupedFilterErrors(); + + // Validate an "is empty" filter -- title without value is valid. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/body_value'); + $edit = []; + $edit["options[group_info][group_items][1][title]"] = 'No body'; + $edit["options[group_info][group_items][1][operator]"] = 'empty'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', [], 'The "empty" operator validates correctly.'); + $this->assertNoGroupedFilterErrors(); + + // Ensure the string "0" can be used as a value for numeric filters. + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_exposed_admin_ui/default/filter', ['name[node_field_data.nid]' => TRUE], t('Add and configure @handler', ['@handler' => t('filter criteria')])); + $this->drupalPostForm(NULL, [], t('Expose filter')); + $this->drupalPostForm(NULL, [], t('Grouped filters')); + $edit = []; + $edit['options[group_info][group_items][1][title]'] = 'Testing zero'; + $edit['options[group_info][group_items][1][operator]'] = '>'; + $edit['options[group_info][group_items][1][value][value]'] = '0'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', [], 'A string "0" is a valid value.'); + $this->assertNoGroupedFilterErrors(); + + // Ensure "between" filters validate correctly. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/nid'); + $edit['options[group_info][group_items][1][title]'] = 'ID between test'; + $edit['options[group_info][group_items][1][operator]'] = 'between'; + $edit['options[group_info][group_items][1][value][min]'] = '0'; + $edit['options[group_info][group_items][1][value][max]'] = '10'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertUrl('admin/structure/views/view/test_exposed_admin_ui/edit/default', [], 'The "between" filter validates correctly.'); + $this->assertNoGroupedFilterErrors(); + } + + public function testGroupedFilterAdminUiErrors() { + // Select the empty operator without a title specified. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/body_value'); + $edit = []; + $edit["options[group_info][group_items][1][title]"] = ''; + $edit["options[group_info][group_items][1][operator]"] = 'empty'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertText($this->groupFormUiErrors['missing_title_empty_operator']); + + // Specify a title without a value. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', [], t('Expose filter')); + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', [], t('Grouped filters')); + $edit = []; + $edit["options[group_info][group_items][1][title]"] = 'Is Article'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertText($this->groupFormUiErrors['missing_value']); + + // Specify a value without a title. + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type'); + $edit = []; + $edit["options[group_info][group_items][1][title]"] = ''; + $edit["options[group_info][group_items][1][value][article]"] = 'article'; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->assertText($this->groupFormUiErrors['missing_title']); + } + + /** + * Asserts that there are no Grouped Filters errors. + * + * @param string $message + * The assert message. + * @param string $group + * The assertion group. + * + * @return bool + * Result of the assertion. + */ + protected function assertNoGroupedFilterErrors($message = '', $group = 'Other') { + foreach ($this->groupFormUiErrors as $error) { + $err_message = $message; + if (empty($err_message)) { + $err_message = "Verify that '$error' is not in the HTML output."; + } + if (empty($message)) { + return $this->assertNoRaw($error, $err_message, $group); + } + } + return TRUE; + } + + /** + * Tests the configuration of grouped exposed filters. + */ + public function testExposedGroupedFilter() { + // Click the Expose filter button. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', [], t('Expose filter')); + // Select 'Grouped filters' radio button. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/type', [], t('Grouped filters')); + // Add 3 groupings. + $edit = [ + 'options[group_button][radios][radios]' => 1, + 'options[group_info][group_items][1][title]' => '1st', + 'options[group_info][group_items][1][value][all]' => 'all', + 'options[group_info][group_items][2][title]' => '2nd', + 'options[group_info][group_items][2][value][article]' => 'article', + 'options[group_info][group_items][3][title]' => '3rd', + 'options[group_info][group_items][3][value][page]' => 'page', + ]; + // Apply the filter settings. + $this->drupalPostForm(NULL, $edit, t('Apply')); + // Check that the view is saved without errors. + $this->drupalPostForm(NULL, [], t('Save')); + $this->assertResponse(200); + + // Click the Expose filter button. + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_exposed_admin_ui/default/filter', ['name[node_field_data.status]' => 1], t('Add and configure filter criteria')); + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/status', [], t('Expose filter')); + // Select 'Grouped filters' radio button. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/status', [], t('Grouped filters')); + // Add 3 groupings. + $edit = [ + 'options[group_button][radios][radios]' => 1, + 'options[group_info][group_items][1][title]' => 'Any', + 'options[group_info][group_items][1][value]' => 'All', + 'options[group_info][group_items][2][title]' => 'Published', + 'options[group_info][group_items][2][value]' => 1, + 'options[group_info][group_items][3][title]' => 'Unpublished', + 'options[group_info][group_items][3][value]' => 0, + ]; + // Apply the filter settings. + $this->drupalPostForm(NULL, $edit, t('Apply')); + // Check that the view is saved without errors. + $this->drupalPostForm(NULL, [], t('Save')); + $this->assertResponse(200); + + $this->drupalGet('admin/structure/views/nojs/handler/test_exposed_admin_ui/default/filter/status'); + // Assert the same settings defined before still are there. + $this->assertFieldChecked('edit-options-group-info-group-items-1-value-all'); + $this->assertFieldChecked('edit-options-group-info-group-items-2-value-1'); + $this->assertFieldChecked('edit-options-group-info-group-items-3-value-0'); + } + +} diff --git a/core/modules/views_ui/src/Tests/FieldUITest.php b/core/modules/views_ui/tests/src/Functional/FieldUITest.php similarity index 82% rename from core/modules/views_ui/src/Tests/FieldUITest.php rename to core/modules/views_ui/tests/src/Functional/FieldUITest.php index 8c486d8b..dc3081f6 100644 --- a/core/modules/views_ui/src/Tests/FieldUITest.php +++ b/core/modules/views_ui/tests/src/Functional/FieldUITest.php @@ -1,6 +1,6 @@ drupalPostForm($edit_handler_url, array('options[exclude]' => TRUE), t('Apply')); + $this->drupalPostForm($edit_handler_url, ['options[exclude]' => TRUE], t('Apply')); $this->assertText('Views test: Name [' . t('hidden') . ']'); @@ -39,20 +39,20 @@ public function testFieldUI() { $edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/age'; $this->drupalGet($edit_handler_url); $result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/ul/li'); - $this->assertEqual((string) $result[0], '{{ age }} == Age'); + $this->assertEqual($result[0]->getHtml(), '{{ age }} == Age'); $edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/id'; $this->drupalGet($edit_handler_url); $result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/ul/li'); - $this->assertEqual((string) $result[0], '{{ age }} == Age'); - $this->assertEqual((string) $result[1], '{{ id }} == ID'); + $this->assertEqual(trim($result[0]->getHtml()), '{{ age }} == Age'); + $this->assertEqual(trim($result[1]->getHtml()), '{{ id }} == ID'); $edit_handler_url = 'admin/structure/views/nojs/handler/test_view/default/field/name'; $this->drupalGet($edit_handler_url); $result = $this->xpath('//details[@id="edit-options-alter-help"]/div[@class="details-wrapper"]/div[@class="item-list"]/ul/li'); - $this->assertEqual((string) $result[0], '{{ age }} == Age'); - $this->assertEqual((string) $result[1], '{{ id }} == ID'); - $this->assertEqual((string) $result[2], '{{ name }} == Name'); + $this->assertEqual(trim($result[0]->getHtml()), '{{ age }} == Age'); + $this->assertEqual(trim($result[1]->getHtml()), '{{ id }} == ID'); + $this->assertEqual(trim($result[2]->getHtml()), '{{ name }} == Name'); $result = $this->xpath('//details[@id="edit-options-more"]'); $this->assertEqual(empty($result), TRUE, "Container 'more' is empty and should not be displayed."); @@ -62,16 +62,16 @@ public function testFieldUI() { $this->assertNoLinkByHref($edit_groupby_url, 0, 'No aggregation link found.'); // Enable aggregation on the view. - $edit = array( + $edit = [ 'group_by' => TRUE, - ); + ]; $this->drupalPostForm('/admin/structure/views/nojs/display/test_view/default/group_by', $edit, t('Apply')); $this->assertLinkByHref($edit_groupby_url, 0, 'Aggregation link found.'); $edit_handler_url = '/admin/structure/views/ajax/handler-group/test_view/default/field/name'; $this->drupalGet($edit_handler_url); - $data = Json::decode($this->getRawContent()); + $data = Json::decode($this->getSession()->getPage()->getContent()); $this->assertEqual($data[3]['dialogOptions']['title'], 'Configure aggregation settings for field Views test: Name'); } @@ -81,7 +81,7 @@ public function testFieldUI() { public function testFieldLabel() { // Create a view with unformatted style and make sure the fields have no // labels by default. - $view = array(); + $view = []; $view['label'] = $this->randomMachineName(16); $view['id'] = strtolower($this->randomMachineName(16)); $view['description'] = $this->randomMachineName(16); diff --git a/core/modules/views_ui/src/Tests/FilterBooleanWebTest.php b/core/modules/views_ui/tests/src/Functional/FilterBooleanWebTest.php similarity index 76% rename from core/modules/views_ui/src/Tests/FilterBooleanWebTest.php rename to core/modules/views_ui/tests/src/Functional/FilterBooleanWebTest.php index 668cc4c1..e6adfeea 100644 --- a/core/modules/views_ui/src/Tests/FilterBooleanWebTest.php +++ b/core/modules/views_ui/tests/src/Functional/FilterBooleanWebTest.php @@ -1,6 +1,6 @@ drupalPostForm('admin/structure/views/nojs/add-handler/test_view/default/filter', array('name[views_test_data.status]' => TRUE), t('Add and configure @handler', array('@handler' => t('filter criteria')))); + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_view/default/filter', ['name[views_test_data.status]' => TRUE], t('Add and configure @handler', ['@handler' => t('filter criteria')])); // Check the field widget label. 'title' should be used as a fallback. $result = $this->cssSelect('#edit-options-value--wrapper legend span'); - $this->assertEqual((string) $result[0], 'Status'); + $this->assertEqual($result[0]->getHtml(), 'Status'); - $this->drupalPostForm(NULL, array(), t('Expose filter')); - $this->drupalPostForm(NULL, array(), t('Grouped filters')); + $this->drupalPostForm(NULL, [], t('Expose filter')); + $this->drupalPostForm(NULL, [], t('Grouped filters')); - $edit = array(); + $edit = []; $edit['options[group_info][group_items][1][title]'] = 'Published'; $edit['options[group_info][group_items][1][operator]'] = '='; $edit['options[group_info][group_items][1][value]'] = 1; @@ -46,17 +46,17 @@ public function testFilterBooleanUI() { $this->drupalGet('admin/structure/views/nojs/handler/test_view/default/filter/status'); $result = $this->xpath('//input[@name="options[group_info][group_items][1][value]"]'); - $this->assertEqual((int) $result[1]->attributes()->checked, 'checked'); + $this->assertEqual($result[1]->getAttribute('checked'), 'checked'); $result = $this->xpath('//input[@name="options[group_info][group_items][2][value]"]'); - $this->assertEqual((int) $result[2]->attributes()->checked, 'checked'); + $this->assertEqual($result[2]->getAttribute('checked'), 'checked'); $result = $this->xpath('//input[@name="options[group_info][group_items][3][value]"]'); - $this->assertEqual((int) $result[1]->attributes()->checked, 'checked'); + $this->assertEqual($result[1]->getAttribute('checked'), 'checked'); // Test that there is a remove link for each group. $this->assertEqual(count($this->cssSelect('a.views-remove-link')), 3); // Test selecting a default and removing an item. - $edit = array(); + $edit = []; $edit['options[group_info][default_group]'] = 2; $edit['options[group_info][group_items][3][remove]'] = 1; $this->drupalPostForm(NULL, $edit, t('Apply')); diff --git a/core/modules/views_ui/tests/src/Functional/FilterNumericWebTest.php b/core/modules/views_ui/tests/src/Functional/FilterNumericWebTest.php new file mode 100644 index 00000000..8dc568de --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/FilterNumericWebTest.php @@ -0,0 +1,118 @@ +drupalPostForm('admin/structure/views/view/test_view/edit', [], 'Add Page'); + $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => $path], 'Apply'); + $this->drupalPostForm(NULL, [], t('Save')); + + $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_view/default/filter', ['name[views_test_data.age]' => TRUE], t('Add and configure @handler', ['@handler' => t('filter criteria')])); + + $this->drupalPostForm(NULL, [], t('Expose filter')); + $this->drupalPostForm(NULL, [], t('Grouped filters')); + + $edit = []; + $edit['options[group_info][group_items][1][title]'] = 'Old'; + $edit['options[group_info][group_items][1][operator]'] = '>'; + $edit['options[group_info][group_items][1][value][value]'] = 27; + $edit['options[group_info][group_items][2][title]'] = 'Young'; + $edit['options[group_info][group_items][2][operator]'] = '<='; + $edit['options[group_info][group_items][2][value][value]'] = 27; + $edit['options[group_info][group_items][3][title]'] = 'From 26 to 28'; + $edit['options[group_info][group_items][3][operator]'] = 'between'; + $edit['options[group_info][group_items][3][value][min]'] = 26; + $edit['options[group_info][group_items][3][value][max]'] = 28; + + $this->drupalPostForm(NULL, $edit, t('Apply')); + + $this->drupalGet('admin/structure/views/nojs/handler/test_view/default/filter/age'); + foreach ($edit as $name => $value) { + $this->assertFieldByName($name, $value); + } + + $this->drupalPostForm('admin/structure/views/view/test_view', [], t('Save')); + $this->assertConfigSchemaByName('views.view.test_view'); + + // Test that the exposed filter works as expected. + $this->drupalGet('test_view-path'); + $this->assertText('John'); + $this->assertText('Paul'); + $this->assertText('Ringo'); + $this->assertText('George'); + $this->assertText('Meredith'); + $this->drupalPostForm(NULL, ['age' => '2'], 'Apply'); + $this->assertText('John'); + $this->assertText('Paul'); + $this->assertNoText('Ringo'); + $this->assertText('George'); + $this->assertNoText('Meredith'); + + // Change the filter to a single filter to test the schema when the operator + // is not exposed. + $this->drupalPostForm('admin/structure/views/nojs/handler/test_view/default/filter/age', [], t('Single filter')); + $edit = []; + $edit['options[value][value]'] = 25; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->drupalPostForm('admin/structure/views/view/test_view', [], t('Save')); + $this->assertConfigSchemaByName('views.view.test_view'); + + // Test that the filter works as expected. + $this->drupalGet('test_view-path'); + $this->assertText('John'); + $this->assertNoText('Paul'); + $this->assertNoText('Ringo'); + $this->assertNoText('George'); + $this->assertNoText('Meredith'); + $this->drupalPostForm(NULL, ['age' => '26'], t('Apply')); + $this->assertNoText('John'); + $this->assertText('Paul'); + $this->assertNoText('Ringo'); + $this->assertNoText('George'); + $this->assertNoText('Meredith'); + + // Change the filter to a 'between' filter to test if the label and + // description are set for the 'minimum' filter element. + $this->drupalGet('admin/structure/views/nojs/handler/test_view/default/filter/age'); + $edit = []; + $edit['options[expose][label]'] = 'Age between'; + $edit['options[expose][description]'] = 'Description of the exposed filter'; + $edit['options[operator]'] = 'between'; + $edit['options[value][min]'] = 26; + $edit['options[value][max]'] = 28; + $this->drupalPostForm(NULL, $edit, t('Apply')); + $this->drupalPostForm('admin/structure/views/view/test_view', [], t('Save')); + $this->assertConfigSchemaByName('views.view.test_view'); + + $this->drupalPostForm(NULL, [], t('Update preview')); + // Check the max field label. + $this->assertRaw('', 'Max field label found'); + $this->assertRaw('', 'Min field label found'); + // Check that the description is shown in the right place. + $this->assertEqual(trim($this->cssSelect('.form-item-age-min .description')[0]->getText()), 'Description of the exposed filter'); + } + +} diff --git a/core/modules/views_ui/src/Tests/FilterUITest.php b/core/modules/views_ui/tests/src/Functional/FilterUITest.php similarity index 78% rename from core/modules/views_ui/src/Tests/FilterUITest.php rename to core/modules/views_ui/tests/src/Functional/FilterUITest.php index 371800f8..18ada1bc 100644 --- a/core/modules/views_ui/src/Tests/FilterUITest.php +++ b/core/modules/views_ui/tests/src/Functional/FilterUITest.php @@ -1,15 +1,13 @@ drupalCreateContentType(array('type' => 'page')); - $this->enableViewsTestModule(); + protected function setUp($import_test_views = TRUE) { + parent::setUp($import_test_views); + $this->drupalCreateContentType(['type' => 'page']); } /** * Tests that an option for a filter is saved as expected from the UI. */ public function testFilterInOperatorUi() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); $this->drupalLogin($admin_user); $path = 'admin/structure/views/nojs/handler/test_filter_in_operator_ui/default/filter/type'; @@ -48,9 +45,9 @@ public function testFilterInOperatorUi() { $this->assertFieldByName('options[expose][reduce]', FALSE); // Select "Limit list to selected items" option and apply. - $edit = array( + $edit = [ 'options[expose][reduce]' => TRUE, - ); + ]; $this->drupalPostForm($path, $edit, t('Apply')); // Verifies that the option was saved as expected. @@ -62,7 +59,7 @@ public function testFilterInOperatorUi() { * Tests the filters from the UI. */ public function testFiltersUI() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); $this->drupalLogin($admin_user); $this->drupalGet('admin/structure/views/view/test_filter_groups'); @@ -94,28 +91,28 @@ public function testFiltersUI() { * Tests the identifier settings and restrictions. */ public function testFilterIdentifier() { - $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']); $this->drupalLogin($admin_user); $path = 'admin/structure/views/nojs/handler/test_filter_in_operator_ui/default/filter/type'; // Set an empty identifier. - $edit = array( + $edit = [ 'options[expose][identifier]' => '', - ); + ]; $this->drupalPostForm($path, $edit, t('Apply')); $this->assertText('The identifier is required if the filter is exposed.'); // Set the identifier to 'value'. - $edit = array( + $edit = [ 'options[expose][identifier]' => 'value', - ); + ]; $this->drupalPostForm($path, $edit, t('Apply')); $this->assertText('This identifier is not allowed.'); // Set the identifier to a value with a restricted character. - $edit = array( + $edit = [ 'options[expose][identifier]' => 'value value', - ); + ]; $this->drupalPostForm($path, $edit, t('Apply')); $this->assertText('This identifier has illegal characters.'); } diff --git a/core/modules/views_ui/src/Tests/GroupByTest.php b/core/modules/views_ui/tests/src/Functional/GroupByTest.php similarity index 82% rename from core/modules/views_ui/src/Tests/GroupByTest.php rename to core/modules/views_ui/tests/src/Functional/GroupByTest.php index 8d0ae3a9..4a45d85f 100644 --- a/core/modules/views_ui/src/Tests/GroupByTest.php +++ b/core/modules/views_ui/tests/src/Functional/GroupByTest.php @@ -1,6 +1,6 @@ drupalGet('admin/structure/views/view/test_views_groupby_save/edit'); $edit_groupby_url = 'admin/structure/views/nojs/handler-group/test_views_groupby_save/default/field/id'; $this->assertNoLinkByHref($edit_groupby_url, 0, 'No aggregation link found.'); // Enable aggregation on the view. - $edit = array( + $edit = [ 'group_by' => TRUE, - ); + ]; $this->drupalPostForm('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by', $edit, t('Apply')); $this->assertLinkByHref($edit_groupby_url, 0, 'Aggregation link found.'); // Change the groupby type in the UI. - $this->drupalPostForm($edit_groupby_url, array('options[group_type]' => 'count'), t('Apply')); + $this->drupalPostForm($edit_groupby_url, ['options[group_type]' => 'count'], t('Apply')); $this->assertLink('COUNT(Views test: ID)', 0, 'The count setting is displayed in the UI'); - $this->drupalPostForm(NULL, array(), t('Save')); + $this->drupalPostForm(NULL, [], t('Save')); $view = $this->container->get('entity.manager')->getStorage('view')->load('test_views_groupby_save'); $display = $view->getDisplay('default'); diff --git a/core/modules/views_ui/tests/src/Functional/HandlerTest.php b/core/modules/views_ui/tests/src/Functional/HandlerTest.php new file mode 100644 index 00000000..31829941 --- /dev/null +++ b/core/modules/views_ui/tests/src/Functional/HandlerTest.php @@ -0,0 +1,284 @@ +placeBlock('page_title_block'); + ViewTestData::createTestViews(get_class($this), ['node_test_views']); + } + + /** + * Overrides \Drupal\views\Tests\ViewTestBase::schemaDefinition(). + * + * Adds a uid column to test the relationships. + * + * @internal + */ + protected function schemaDefinition() { + $schema = parent::schemaDefinition(); + + $schema['views_test_data']['fields']['uid'] = [ + 'description' => "The {users}.uid of the author of the beatle entry.", + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0 + ]; + + return $schema; + } + + /** + * Overrides \Drupal\views\Tests\ViewTestBase::viewsData(). + * + * Adds: + * - a relationship for the uid column. + * - a dummy field with no help text. + */ + protected function viewsData() { + $data = parent::viewsData(); + $data['views_test_data']['uid'] = [ + 'title' => t('UID'), + 'help' => t('The test data UID'), + 'relationship' => [ + 'id' => 'standard', + 'base' => 'users_field_data', + 'base field' => 'uid' + ] + ]; + + // Create a dummy field with no help text. + $data['views_test_data']['no_help'] = $data['views_test_data']['name']; + $data['views_test_data']['no_help']['field']['title'] = t('No help'); + $data['views_test_data']['no_help']['field']['real field'] = 'name'; + unset($data['views_test_data']['no_help']['help']); + + return $data; + } + + /** + * Tests UI CRUD. + */ + public function testUICRUD() { + $handler_types = ViewExecutable::getHandlerTypes(); + foreach ($handler_types as $type => $type_info) { + // Test adding handlers. + $add_handler_url = "admin/structure/views/nojs/add-handler/test_view_empty/default/$type"; + + // Area handler types need to use a different handler. + if (in_array($type, ['header', 'footer', 'empty'])) { + $this->drupalPostForm($add_handler_url, ['name[views.area]' => TRUE], t('Add and configure @handler', ['@handler' => $type_info['ltitle']])); + $id = 'area'; + $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/$type/$id"; + } + elseif ($type == 'relationship') { + $this->drupalPostForm($add_handler_url, ['name[views_test_data.uid]' => TRUE], t('Add and configure @handler', ['@handler' => $type_info['ltitle']])); + $id = 'uid'; + $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/$type/$id"; + } + else { + $this->drupalPostForm($add_handler_url, ['name[views_test_data.job]' => TRUE], t('Add and configure @handler', ['@handler' => $type_info['ltitle']])); + $id = 'job'; + $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/$type/$id"; + } + + $this->assertUrl($edit_handler_url, [], 'The user got redirected to the handler edit form.'); + $random_label = $this->randomMachineName(); + $this->drupalPostForm(NULL, ['options[admin_label]' => $random_label], t('Apply')); + + $this->assertUrl('admin/structure/views/view/test_view_empty/edit/default', [], 'The user got redirected to the views edit form.'); + + $this->assertLinkByHref($edit_handler_url, 0, 'The handler edit link appears in the UI.'); + $links = $this->xpath('//a[starts-with(normalize-space(text()), :label)]', [':label' => $random_label]); + $this->assertTrue(isset($links[0]), 'The handler edit link has the right label'); + + // Save the view and have a look whether the handler was added as expected. + $this->drupalPostForm(NULL, [], t('Save')); + $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view_empty'); + $display = $view->getDisplay('default'); + $this->assertTrue(isset($display['display_options'][$type_info['plural']][$id]), 'Ensure the field was added to the view itself.'); + + // Remove the item and check that it's removed + $this->drupalPostForm($edit_handler_url, [], t('Remove')); + $this->assertNoLinkByHref($edit_handler_url, 0, 'The handler edit link does not appears in the UI after removing.'); + + $this->drupalPostForm(NULL, [], t('Save')); + $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view_empty'); + $display = $view->getDisplay('default'); + $this->assertFalse(isset($display['display_options'][$type_info['plural']][$id]), 'Ensure the field was removed from the view itself.'); + } + + // Test adding a field of the user table using the uid relationship. + $type_info = $handler_types['relationship']; + $add_handler_url = "admin/structure/views/nojs/add-handler/test_view_empty/default/relationship"; + $this->drupalPostForm($add_handler_url, ['name[views_test_data.uid]' => TRUE], t('Add and configure @handler', ['@handler' => $type_info['ltitle']])); + + $add_handler_url = "admin/structure/views/nojs/add-handler/test_view_empty/default/field"; + $type_info = $handler_types['field']; + $this->drupalPostForm($add_handler_url, ['name[users_field_data.name]' => TRUE], t('Add and configure @handler', ['@handler' => $type_info['ltitle']])); + $id = 'name'; + $edit_handler_url = "admin/structure/views/nojs/handler/test_view_empty/default/field/$id"; + + $this->assertUrl($edit_handler_url, [], 'The user got redirected to the handler edit form.'); + $this->assertFieldByName('options[relationship]', 'uid', 'Ensure the relationship select is filled with the UID relationship.'); + $this->drupalPostForm(NULL, [], t('Apply')); + + $this->drupalPostForm(NULL, [], t('Save')); + $view = $this->container->get('entity.manager')->getStorage('view')->load('test_view_empty'); + $display = $view->getDisplay('default'); + $this->assertTrue(isset($display['display_options'][$type_info['plural']][$id]), 'Ensure the field was added to the view itself.'); + } + + /** + * Tests escaping of field labels in help text. + */ + public function testHandlerHelpEscaping() { + // Setup a field with two instances using a different label. + // Ensure that the label is escaped properly. + + $this->drupalCreateContentType(['type' => 'article']); + $this->drupalCreateContentType(['type' => 'page']); + + FieldStorageConfig::create([ + 'field_name' => 'field_test', + 'entity_type' => 'node', + 'type' => 'string', + ])->save(); + + FieldConfig::create([ + 'field_name' => 'field_test', + 'entity_type' => 'node', + 'bundle' => 'page', + 'label' => 'The giraffe" label' + ])->save(); + + FieldConfig::create([ + 'field_name' => 'field_test', + 'entity_type' => 'node', + 'bundle' => 'article', + 'label' => 'The giraffe" label ' + ])->save(); + + $this->drupalGet('admin/structure/views/nojs/add-handler/content/default/field'); + $this->assertEscaped('The giraffe" label '); + $this->assertEscaped('Appears in: page, article. Also known as: Content: The giraffe" label'); + } + + /** + * Tests broken handlers. + */ + public function testBrokenHandlers() { + $handler_types = ViewExecutable::getHandlerTypes(); + foreach ($handler_types as $type => $type_info) { + $this->drupalGet('admin/structure/views/view/test_view_broken/edit'); + + $href = "admin/structure/views/nojs/handler/test_view_broken/default/$type/id_broken"; + + $result = $this->xpath('//a[contains(@href, :href)]', [':href' => $href]); + $this->assertEqual(count($result), 1, SafeMarkup::format('Handler (%type) edit link found.', ['%type' => $type])); + + $text = 'Broken/missing handler'; + + $this->assertIdentical($result[0]->getText(), $text, 'Ensure the broken handler text was found.'); + + $this->drupalGet($href); + $result = $this->xpath('//h1[@class="page-title"]'); + $this->assertContains($text, $result[0]->getText(), 'Ensure the broken handler text was found.'); + + $original_configuration = [ + 'field' => 'id_broken', + 'id' => 'id_broken', + 'relationship' => 'none', + 'table' => 'views_test_data', + 'plugin_id' => 'numeric', + ]; + + foreach ($original_configuration as $key => $value) { + $this->assertText(SafeMarkup::format('@key: @value', ['@key' => $key, '@value' => $value])); + } + } + } + + /** + * Ensures that neither node type or node ID appears multiple times. + * + * @see \Drupal\views\EntityViewsData + */ + public function testNoDuplicateFields() { + $handler_types = ['field', 'filter', 'sort', 'argument']; + + foreach ($handler_types as $handler_type) { + $add_handler_url = 'admin/structure/views/nojs/add-handler/test_node_view/default/' . $handler_type; + $this->drupalGet($add_handler_url); + + $this->assertNoDuplicateField('ID', 'Content'); + $this->assertNoDuplicateField('ID', 'Content revision'); + $this->assertNoDuplicateField('Content type', 'Content'); + $this->assertNoDuplicateField('UUID', 'Content'); + $this->assertNoDuplicateField('Revision ID', 'Content'); + $this->assertNoDuplicateField('Revision ID', 'Content revision'); + } + } + + /** + * Ensures that no missing help text is shown. + * + * @see \Drupal\views\EntityViewsData + */ + public function testErrorMissingHelp() { + // Test that the error message is not shown for entity fields but an empty + // description field is shown instead. + $this->drupalGet('admin/structure/views/nojs/add-handler/test_node_view/default/field'); + $this->assertNoText('Error: missing help'); + $this->assertRaw('
    Only process misc/drupal.es6.js and misc/drupal.init.es6.js
    11112
    onetwothree
    1-one1-two1-three
    ', 'javascript', 'HTML scheme clearing -- another tag.', - array('table'), - ), - array( + ['table'], + ], + [ '', 'javascript', 'HTML scheme clearing -- one more attribute and tag.', - array('base'), - ), - array( + ['base'], + ], + [ '', 'javascript', 'HTML scheme clearing evasion -- varying case.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'javascript', 'HTML scheme clearing evasion -- UTF-8 decimal encoding.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'javascript', 'HTML scheme clearing evasion -- long UTF-8 encoding.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'javascript', 'HTML scheme clearing evasion -- UTF-8 hex encoding.', - array('img'), - ), - array( + ['img'], + ], + [ "", 'script', 'HTML scheme clearing evasion -- an embedded tab.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'script', 'HTML scheme clearing evasion -- an encoded, embedded tab.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'script', 'HTML scheme clearing evasion -- an encoded, embedded newline.', - array('img'), - ), + ['img'], + ], // With this test would fail, but the entity gets turned into // &#xD;, so it's OK. - array( + [ '', 'script', 'HTML scheme clearing evasion -- an encoded, embedded carriage return.', - array('img'), - ), - array( + ['img'], + ], + [ "", 'cript', 'HTML scheme clearing evasion -- broken into many lines.', - array('img'), - ), - array( + ['img'], + ], + [ "", 'cript', 'HTML scheme clearing evasion -- embedded nulls.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'vbscript', 'HTML scheme clearing evasion -- another scheme.', - array('img'), - ), - array( + ['img'], + ], + [ '', 'nosuchscheme', 'HTML scheme clearing evasion -- unknown scheme.', - array('img'), - ), + ['img'], + ], // Netscape 4.x javascript entities. - array( + [ '
    ', 'alert', 'Netscape 4.x javascript entities.', - array('br'), - ), + ['br'], + ], // DRUPAL-SA-2008-006: Invalid UTF-8, these only work as reflected XSS with // Internet Explorer 6. - array( + [ "

    \" style=\"background-image: url(javascript:alert(0));\"\xe0

    ", 'style', 'HTML filter -- invalid UTF-8.', - array('p'), - ), - ); + ['p'], + ], + ]; // @fixme This dataset currently fails under 5.4 because of // https://www.drupal.org/node/1210798. Restore after its fixed. if (version_compare(PHP_VERSION, '5.4.0', '<')) { - $cases[] = array( + $cases[] = [ '', 'javascript', 'HTML scheme clearing evasion -- spaces and metacharacters before scheme.', - array('img'), - ); + ['img'], + ]; } return $cases; } @@ -468,11 +468,11 @@ public function testInvalidMultiByte($value, $expected, $message) { * - The assertion message. */ public function providerTestInvalidMultiByte() { - return array( - array("Foo\xC0barbaz", '', 'Xss::filter() accepted invalid sequence "Foo\xC0barbaz"'), - array("Fooÿñ", "Fooÿñ", 'Xss::filter() rejects valid sequence Fooÿñ"'), - array("\xc0aaa", '', 'HTML filter -- overlong UTF-8 sequences.'), - ); + return [ + ["Foo\xC0barbaz", '', 'Xss::filter() accepted invalid sequence "Foo\xC0barbaz"'], + ["Fooÿñ", "Fooÿñ", 'Xss::filter() rejects valid sequence Fooÿñ"'], + ["\xc0aaa", '', 'HTML filter -- overlong UTF-8 sequences.'], + ]; } /** @@ -498,38 +498,38 @@ public function testAttribute($value, $expected, $message, $allowed_tags = NULL) * Data provider for testFilterXssAdminNotNormalized(). */ public function providerTestAttributes() { - return array( - array( + return [ + [ 'Example: alt', 'Example: alt', 'Image tag with alt and title attribute', - array('img') - ), - array( + ['img'] + ], + [ 'Drupal', 'Drupal', 'Link tag with rel attribute', - array('a') - ), - array( + ['a'] + ], + [ 'Drupal 8: The best release ever.', 'Drupal 8: The best release ever.', 'Span tag with property attribute', - array('span') - ), - array( + ['span'] + ], + [ '', '', 'Image tag with data attribute', - array('img') - ), - array( + ['img'] + ], + [ '', '', 'Link tag with numeric data attribute', - array('a') - ), - ); + ['a'] + ], + ]; } /** @@ -568,11 +568,11 @@ public function testFilterXssAdminNotNormalized($value, $expected, $message) { * - The assertion message. */ public function providerTestFilterXssAdminNotNormalized() { - return array( + return [ // DRUPAL-SA-2008-044 - array('', 'object', 'Admin HTML filter -- should not allow object tag.'), - array(' 'value', - ); - $tags[] = array($element, "value\n"); + ]; + $tags['sanitized-tag'] = [$element, "value\n"]; // Ensure that #value is not filtered if it is marked as safe. - $element = array( + $element = [ '#tag' => 'p', '#value' => Markup::create(''), - ); - $tags[] = array($element, "

    \n"); + ]; + $tags['value-safe'] = [$element, "

    \n"]; // Ensure that #value is filtered if it is not safe. - $element = array( + $element = [ '#tag' => 'p', '#value' => '', - ); - $tags[] = array($element, "

    value

    \n"); + ]; + $tags['value-not-safe'] = [$element, "

    value

    \n"]; + + // Ensure that nested render arrays render properly. + $element = [ + '#tag' => 'p', + '#value' => NULL, + [ + ['#markup' => 'value1'], + ['#markup' => 'value2'], + ], + ]; + $tags['nested'] = [$element, "

    value1value2

    \n"]; + + // Ensure svg elements. + $element = [ + '#tag' => 'rect', + '#attributes' => [ + 'width' => 25, + 'height' => 25, + 'x' => 5, + 'y' => 10, + ], + ]; + $tags['rect'] = [$element, '' . "\n"]; + + $element = [ + '#tag' => 'circle', + '#attributes' => [ + 'cx' => 100, + 'cy' => 100, + 'r' => 100, + ], + ]; + $tags['circle'] = [$element, '' . "\n"]; + + $element = [ + '#tag' => 'polygon', + '#attributes' => [ + 'points' => '60,20 100,40 100,80 60,100 20,80 20,40', + ], + ]; + $tags['polygon'] = [$element, '' . "\n"]; + + $element = [ + '#tag' => 'ellipse', + '#attributes' => [ + 'cx' => 60, + 'cy' => 60, + 'rx' => 50, + 'ry' => 25, + ], + ]; + $tags['ellipse'] = [$element, '' . "\n"]; + + $element = [ + '#tag' => 'use', + '#attributes' => [ + 'x' => 50, + 'y' => 10, + 'width' => 50, + 'height' => 50, + ], + ]; + $tags['use'] = [$element, '' . "\n"]; + + $element = [ + '#tag' => 'path', + '#attributes' => [ + 'd' => 'M 100 100 L 300 100 L 200 300 z', + 'fill' => 'orange', + 'stroke' => 'black', + 'stroke-width' => 3, + ], + ]; + $tags['path'] = [$element, '' . "\n"]; + + $element = [ + '#tag' => 'stop', + '#attributes' => [ + 'offset' => '5%', + 'stop-color' => '#F60', + ], + ]; + $tags['stop'] = [$element, '' . "\n"]; + + // Nested svg elements. + $element = [ + '#tag' => 'linearGradient', + '#value' => NULL, + [ + '#tag' => 'stop', + '#value' => NULL, + '#attributes' => [ + 'offset' => '5%', + 'stop-color' => '#F60', + ], + ], + [ + '#tag' => 'stop', + '#value' => NULL, + '#attributes' => [ + 'offset' => '95%', + 'stop-color' => '#FF6', + ], + ], + ]; + $tags['linearGradient'] = [$element, '' . "\n" . '' . "\n" . '' . "\n"]; return $tags; } @@ -112,74 +222,74 @@ public function testPreRenderConditionalComments($element, $expected, $set_safe */ public function providerPreRenderConditionalComments() { // No browser specification. - $element = array( + $element = [ '#tag' => 'link', - ); - $tags[] = array($element, $element); + ]; + $tags['no-browser'] = [$element, $element]; // Specify all browsers. - $element['#browsers'] = array( + $element['#browsers'] = [ 'IE' => TRUE, '!IE' => TRUE, - ); - $tags[] = array($element, $element); + ]; + $tags['all-browsers'] = [$element, $element]; // All IE. - $element = array( + $element = [ '#tag' => 'link', - '#browsers' => array( + '#browsers' => [ 'IE' => TRUE, '!IE' => FALSE, - ), - ); + ], + ]; $expected = $element; $expected['#prefix'] = "\n\n"; - $tags[] = array($element, $expected); + $tags['all-ie'] = [$element, $expected]; // Exclude IE. - $element = array( + $element = [ '#tag' => 'link', - '#browsers' => array( + '#browsers' => [ 'IE' => FALSE, - ), - ); + ], + ]; $expected = $element; $expected['#prefix'] = "\n\n"; $expected['#suffix'] = "\n"; - $tags[] = array($element, $expected); + $tags['no-ie'] = [$element, $expected]; // IE gt 8 - $element = array( + $element = [ '#tag' => 'link', - '#browsers' => array( + '#browsers' => [ 'IE' => 'gt IE 8', - ), - ); + ], + ]; $expected = $element; $expected['#prefix'] = "\n\n"; $expected['#suffix'] = "\n"; - $tags[] = array($element, $expected); + $tags['ie9plus'] = [$element, $expected]; // Prefix and suffix filtering if not safe. - $element = array( + $element = [ '#tag' => 'link', - '#browsers' => array( + '#browsers' => [ 'IE' => FALSE, - ), + ], '#prefix' => 'prefix', '#suffix' => 'suffix', - ); + ]; $expected = $element; $expected['#prefix'] = "\n\nprefix"; $expected['#suffix'] = "suffix\n"; - $tags[] = array($element, $expected); + $tags['non-ie-unsafe'] = [$element, $expected]; // Prefix and suffix filtering if marked as safe. This has to come after the // previous test case. $expected['#prefix'] = "\n\nprefix"; $expected['#suffix'] = "suffix\n"; - $tags[] = array($element, $expected, TRUE); + $tags['non-ie-safe'] = [$element, $expected, TRUE]; return $tags; } diff --git a/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php b/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php index 0d5aec69..c3058300 100644 --- a/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php @@ -85,13 +85,13 @@ public function testGetInfoElementPlugin($plugin_class, $expected_info) { $plugin = $this->getMock($plugin_class); $plugin->expects($this->once()) ->method('getInfo') - ->willReturn(array( + ->willReturn([ '#theme' => 'page', - )); + ]); $element_info = $this->getMockBuilder('Drupal\Core\Render\ElementInfoManager') - ->setConstructorArgs(array(new \ArrayObject(), $this->cache, $this->cacheTagsInvalidator, $this->moduleHandler, $this->themeManager)) - ->setMethods(array('getDefinitions', 'createInstance')) + ->setConstructorArgs([new \ArrayObject(), $this->cache, $this->cacheTagsInvalidator, $this->moduleHandler, $this->themeManager]) + ->setMethods(['getDefinitions', 'createInstance']) ->getMock(); $this->themeManager->expects($this->any()) @@ -104,9 +104,9 @@ public function testGetInfoElementPlugin($plugin_class, $expected_info) { ->willReturn($plugin); $element_info->expects($this->once()) ->method('getDefinitions') - ->willReturn(array( - 'page' => array('class' => 'TestElementPlugin'), - )); + ->willReturn([ + 'page' => ['class' => 'TestElementPlugin'], + ]); $this->assertEquals($expected_info, $element_info->getInfo('page')); } @@ -117,26 +117,26 @@ public function testGetInfoElementPlugin($plugin_class, $expected_info) { * @return array */ public function providerTestGetInfoElementPlugin() { - $data = array(); - $data[] = array( + $data = []; + $data[] = [ 'Drupal\Core\Render\Element\ElementInterface', - array( + [ '#type' => 'page', '#theme' => 'page', '#defaults_loaded' => TRUE, - ), - ); + ], + ]; - $data[] = array( + $data[] = [ 'Drupal\Core\Render\Element\FormElementInterface', - array( + [ '#type' => 'page', '#theme' => 'page', '#input' => TRUE, - '#value_callback' => array('TestElementPlugin', 'valueCallback'), + '#value_callback' => ['TestElementPlugin', 'valueCallback'], '#defaults_loaded' => TRUE, - ), - ); + ], + ]; return $data; } @@ -164,12 +164,12 @@ class TestElementInfoManager extends ElementInfoManager { /** * {@inheritdoc} */ - protected $elementInfo = array( - 'test' => array( - 'foo' => array( + protected $elementInfo = [ + 'test' => [ + 'foo' => [ '#bar' => 'baz', - ), - ), - ); + ], + ], + ]; } diff --git a/core/tests/Drupal/Tests/Core/Render/ElementTest.php b/core/tests/Drupal/Tests/Core/Render/ElementTest.php index 604d391d..d168f741 100644 --- a/core/tests/Drupal/Tests/Core/Render/ElementTest.php +++ b/core/tests/Drupal/Tests/Core/Render/ElementTest.php @@ -25,11 +25,11 @@ public function testProperty() { * Tests the properties() method. */ public function testProperties() { - $element = array( + $element = [ '#property1' => 'property1', '#property2' => 'property2', 'property3' => 'property3' - ); + ]; $properties = Element::properties($element); @@ -51,64 +51,62 @@ public function testChild() { * Tests the children() method. */ public function testChildren() { - $element = array( - 'child2' => array('#weight' => 10), - 'child1' => array('#weight' => 0), - 'child3' => array('#weight' => 20), + $element = [ + 'child2' => ['#weight' => 10], + 'child1' => ['#weight' => 0], + 'child3' => ['#weight' => 20], '#property' => 'property', - ); + ]; - $expected = array('child2', 'child1', 'child3'); + $expected = ['child2', 'child1', 'child3']; $element_copy = $element; $this->assertSame($expected, Element::children($element_copy)); // If #sorted is already set, no sorting should happen. $element_copy = $element; $element_copy['#sorted'] = TRUE; - $expected = array('child2', 'child1', 'child3'); + $expected = ['child2', 'child1', 'child3']; $this->assertSame($expected, Element::children($element_copy, TRUE)); // Test with weight sorting, #sorted property should be added. - $expected = array('child1', 'child2', 'child3'); + $expected = ['child1', 'child2', 'child3']; $element_copy = $element; $this->assertSame($expected, Element::children($element_copy, TRUE)); $this->assertArrayHasKey('#sorted', $element_copy); $this->assertTrue($element_copy['#sorted']); // The order should stay the same if no weights present. - $element_no_weight = array( - 'child2' => array(), - 'child1' => array(), - 'child3' => array(), + $element_no_weight = [ + 'child2' => [], + 'child1' => [], + 'child3' => [], '#property' => 'property', - ); + ]; - $expected = array('child2', 'child1', 'child3'); + $expected = ['child2', 'child1', 'child3']; $this->assertSame($expected, Element::children($element_no_weight, TRUE)); // The order of children with same weight should be preserved. - $element_mixed_weight = array( - 'child5' => array('#weight' => 10), - 'child3' => array('#weight' => -10), - 'child1' => array(), - 'child4' => array('#weight' => 10), - 'child2' => array(), - ); - - $expected = array('child3', 'child1', 'child2', 'child5', 'child4'); + $element_mixed_weight = [ + 'child5' => ['#weight' => 10], + 'child3' => ['#weight' => -10], + 'child1' => [], + 'child4' => ['#weight' => 10], + 'child2' => [], + ]; + + $expected = ['child3', 'child1', 'child2', 'child5', 'child4']; $this->assertSame($expected, Element::children($element_mixed_weight, TRUE)); } /** * Tests the children() method with an invalid key. - * - * @expectedException \PHPUnit_Framework_Error - * @expectedExceptionMessage "foo" is an invalid render array key */ public function testInvalidChildren() { - $element = array( + $element = [ 'foo' => 'bar', - ); + ]; + $this->setExpectedException(\PHPUnit_Framework_Error::class, '"foo" is an invalid render array key'); Element::children($element); } @@ -116,10 +114,10 @@ public function testInvalidChildren() { * Tests the children() method with an ignored key/value pair. */ public function testIgnoredChildren() { - $element = array( + $element = [ 'foo' => NULL, - ); - $this->assertSame(array(), Element::children($element)); + ]; + $this->assertSame([], Element::children($element)); } /** @@ -142,17 +140,17 @@ public function testVisibleChildren(array $element, array $expected_keys) { * @return array */ public function providerVisibleChildren() { - return array( - array(array('#property1' => '', '#property2' => array()), array()), - array(array('#property1' => '', 'child1' => array()), array('child1')), - array(array('#property1' => '', 'child1' => array(), 'child2' => array('#access' => TRUE)), array('child1', 'child2')), - array(array('#property1' => '', 'child1' => array(), 'child2' => array('#access' => FALSE)), array('child1')), - 'access_result_object_allowed' => array(array('#property1' => '', 'child1' => array(), 'child2' => array('#access' => AccessResult::allowed())), array('child1', 'child2')), - 'access_result_object_forbidden' => array(array('#property1' => '', 'child1' => array(), 'child2' => array('#access' => AccessResult::forbidden())), array('child1')), - array(array('#property1' => '', 'child1' => array(), 'child2' => array('#type' => 'textfield')), array('child1', 'child2')), - array(array('#property1' => '', 'child1' => array(), 'child2' => array('#type' => 'value')), array('child1')), - array(array('#property1' => '', 'child1' => array(), 'child2' => array('#type' => 'hidden')), array('child1')), - ); + return [ + [['#property1' => '', '#property2' => []], []], + [['#property1' => '', 'child1' => []], ['child1']], + [['#property1' => '', 'child1' => [], 'child2' => ['#access' => TRUE]], ['child1', 'child2']], + [['#property1' => '', 'child1' => [], 'child2' => ['#access' => FALSE]], ['child1']], + 'access_result_object_allowed' => [['#property1' => '', 'child1' => [], 'child2' => ['#access' => AccessResult::allowed()]], ['child1', 'child2']], + 'access_result_object_forbidden' => [['#property1' => '', 'child1' => [], 'child2' => ['#access' => AccessResult::forbidden()]], ['child1']], + [['#property1' => '', 'child1' => [], 'child2' => ['#type' => 'textfield']], ['child1', 'child2']], + [['#property1' => '', 'child1' => [], 'child2' => ['#type' => 'value']], ['child1']], + [['#property1' => '', 'child1' => [], 'child2' => ['#type' => 'hidden']], ['child1']], + ]; } /** @@ -169,12 +167,12 @@ public function testSetAttributes($element, $map, $expected_element) { * Data provider for testSetAttributes(). */ public function providerTestSetAttributes() { - $base = array('#id' => 'id', '#class' => array()); - return array( - array($base, array(), $base), - array($base, array('id', 'class'), $base + array('#attributes' => array('id' => 'id', 'class' => array()))), - array($base + array('#attributes' => array('id' => 'id-not-overwritten')), array('id', 'class'), $base + array('#attributes' => array('id' => 'id-not-overwritten', 'class' => array()))), - ); + $base = ['#id' => 'id', '#class' => []]; + return [ + [$base, [], $base], + [$base, ['id', 'class'], $base + ['#attributes' => ['id' => 'id', 'class' => []]]], + [$base + ['#attributes' => ['id' => 'id-not-overwritten']], ['id', 'class'], $base + ['#attributes' => ['id' => 'id-not-overwritten', 'class' => []]]], + ]; } /** diff --git a/core/tests/Drupal/Tests/Core/Render/Placeholder/ChainedPlaceholderStrategyTest.php b/core/tests/Drupal/Tests/Core/Render/Placeholder/ChainedPlaceholderStrategyTest.php index fc90e5da..776b7944 100644 --- a/core/tests/Drupal/Tests/Core/Render/Placeholder/ChainedPlaceholderStrategyTest.php +++ b/core/tests/Drupal/Tests/Core/Render/Placeholder/ChainedPlaceholderStrategyTest.php @@ -120,9 +120,6 @@ public function providerProcessPlaceholders() { /** * @covers ::processPlaceholders - * - * @expectedException \AssertionError - * @expectedExceptionMessage At least one placeholder strategy must be present; by default the fallback strategy \Drupal\Core\Render\Placeholder\SingleFlushStrategy is always present. */ public function testProcessPlaceholdersNoStrategies() { // Placeholders but no strategies defined. @@ -131,14 +128,12 @@ public function testProcessPlaceholdersNoStrategies() { ]; $chained_placeholder_strategy = new ChainedPlaceholderStrategy(); + $this->setExpectedException(\AssertionError::class, 'At least one placeholder strategy must be present; by default the fallback strategy \Drupal\Core\Render\Placeholder\SingleFlushStrategy is always present.'); $chained_placeholder_strategy->processPlaceholders($placeholders); } /** * @covers ::processPlaceholders - * - * @expectedException \AssertionError - * @expectedExceptionMessage Processed placeholders must be a subset of all placeholders. */ public function testProcessPlaceholdersWithRoguePlaceholderStrategy() { // Placeholders but no strategies defined. @@ -157,6 +152,7 @@ public function testProcessPlaceholdersWithRoguePlaceholderStrategy() { $chained_placeholder_strategy = new ChainedPlaceholderStrategy(); $chained_placeholder_strategy->addPlaceholderStrategy($rogue_strategy); + $this->setExpectedException(\AssertionError::class, 'Processed placeholders must be a subset of all placeholders.'); $chained_placeholder_strategy->processPlaceholders($placeholders); } diff --git a/core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php b/core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php index 3e80a3f2..ce0f1518 100644 --- a/core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php +++ b/core/tests/Drupal/Tests/Core/Render/PlaceholderGeneratorTest.php @@ -30,7 +30,7 @@ class PlaceholderGeneratorTest extends RendererTestBase { public function testCreatePlaceholderGeneratesValidHtmlMarkup(array $element) { $build = $this->placeholderGenerator->createPlaceholder($element); - $original_placeholder_markup = (string)$build['#markup']; + $original_placeholder_markup = (string) $build['#markup']; $processed_placeholder_markup = Html::serialize(Html::load($build['#markup'])); $this->assertEquals($original_placeholder_markup, $processed_placeholder_markup); diff --git a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php index 5a8ae968..573febcc 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php @@ -9,6 +9,7 @@ use Drupal\Core\Cache\MemoryBackend; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; +use Drupal\Core\Lock\NullLockBackend; use Drupal\Core\State\State; use Drupal\Core\Cache\Cache; @@ -45,7 +46,7 @@ public function testBubblingWithoutPreRender() { $element = [ '#type' => 'container', '#cache' => [ - 'keys' => ['simpletest', 'drupal_render', 'children_attached'], + 'keys' => ['simpletest', 'renderer', 'children_attached'], ], '#attached' => ['library' => ['test/parent']], '#title' => 'Parent', @@ -67,7 +68,7 @@ public function testBubblingWithoutPreRender() { // Load the element from cache and verify the presence of the #attached // JavaScript. - $element = ['#cache' => ['keys' => ['simpletest', 'drupal_render', 'children_attached']]]; + $element = ['#cache' => ['keys' => ['simpletest', 'renderer', 'children_attached']]]; $this->assertTrue(strlen($this->renderer->renderRoot($element)) > 0, 'The element was retrieved from cache.'); $this->assertEquals($element['#attached']['library'], $expected_libraries, 'The element, child and subchild #attached libraries are included.'); } @@ -79,13 +80,13 @@ public function testContextBubblingCustomCacheBin() { $bin = $this->randomMachineName(); $this->setUpRequest(); - $this->memoryCache = new MemoryBackend('render'); - $custom_cache = new MemoryBackend($bin); + $this->memoryCache = new MemoryBackend(); + $custom_cache = new MemoryBackend(); $this->cacheFactory->expects($this->atLeastOnce()) ->method('get') ->with($bin) - ->willReturnCallback(function($requested_bin) use ($bin, $custom_cache) { + ->willReturnCallback(function ($requested_bin) use ($bin, $custom_cache) { if ($requested_bin === $bin) { return $custom_cache; } @@ -314,7 +315,7 @@ public function testConditionalCacheContextBubblingSelfHealing() { 'tags' => ['b'], ], 'grandchild' => [ - '#access_callback' => function() use (&$current_user_role) { + '#access_callback' => function () use (&$current_user_role) { // Only role A cannot access this subtree. return $current_user_role !== 'A'; }, @@ -502,7 +503,7 @@ public function testBubblingWithPrerender($test_element) { $this->setupMemoryCache(); // Mock the State service. - $memory_state = new State(new KeyValueMemoryFactory());; + $memory_state = new State(new KeyValueMemoryFactory(), new MemoryBackend('test'), new NullLockBackend()); \Drupal::getContainer()->set('state', $memory_state); $this->controllerResolver->expects($this->any()) ->method('getControllerFromDefinition') @@ -553,26 +554,29 @@ public function providerTestBubblingWithPrerender() { $data = []; // Test element without theme. - $data[] = [[ - 'foo' => [ - '#pre_render' => [__NAMESPACE__ . '\\BubblingTest::bubblingPreRender'], - ]]]; + $data[] = [ + [ + 'foo' => [ + '#pre_render' => [__NAMESPACE__ . '\\BubblingTest::bubblingPreRender'], + ], + ], + ]; // Test element with theme. - $data[] = [[ - '#theme' => 'common_test_render_element', - 'foo' => [ - '#pre_render' => [__NAMESPACE__ . '\\BubblingTest::bubblingPreRender'], - ]]]; + $data[] = [ + [ + '#theme' => 'common_test_render_element', + 'foo' => [ + '#pre_render' => [__NAMESPACE__ . '\\BubblingTest::bubblingPreRender'], + ], + ], + ]; return $data; } /** * Tests that an element's cache keys cannot be changed during its rendering. - * - * @expectedException \LogicException - * @expectedExceptionMessage Cache keys may not be changed after initial setup. Use the contexts property instead to bubble additional metadata. */ public function testOverWriteCacheKeys() { $this->setUpRequest(); @@ -585,6 +589,7 @@ public function testOverWriteCacheKeys() { ], '#pre_render' => [__NAMESPACE__ . '\\BubblingTest::bubblingCacheOverwritePrerender'], ]; + $this->setExpectedException(\LogicException::class, 'Cache keys may not be changed after initial setup. Use the contexts property instead to bubble additional metadata.'); $this->renderer->renderRoot($data); } diff --git a/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php index 530f603f..253a3580 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\Core\Render; +use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\Html; use Drupal\Core\Cache\Cache; use Drupal\Core\Render\Markup; @@ -64,14 +65,14 @@ protected function setUp() { public function providerPlaceholders() { $args = [$this->randomContextValue()]; - $generate_placeholder_markup = function($cache_keys = NULL) use ($args) { + $generate_placeholder_markup = function ($cache_keys = NULL) use ($args) { $token_render_array = [ '#lazy_builder' => ['Drupal\Tests\Core\Render\PlaceholdersTest::callback', $args], ]; if (is_array($cache_keys)) { $token_render_array['#cache']['keys'] = $cache_keys; } - $token = hash('crc32b', serialize($token_render_array)); + $token = Crypt::hashBase64(serialize($token_render_array)); // \Drupal\Core\Render\Markup::create() is necessary as the render // system would mangle this markup. As this is exactly what happens at // runtime this is a valid use-case. @@ -546,12 +547,11 @@ protected function generatePlaceholderElement() { /** * @param false|array $cid_parts - * @param array $expected_data - * FALSE if no render cache item is expected, a render array with the - * expected values if a render cache item is expected. * @param string[] $bubbled_cache_contexts * Additional cache contexts that were bubbled when the placeholder was * rendered. + * @param array $expected_data + * A render array with the expected values. */ protected function assertPlaceholderRenderCache($cid_parts, array $bubbled_cache_contexts, array $expected_data) { if ($cid_parts !== FALSE) { @@ -618,7 +618,7 @@ public function testCacheableParent($test_element, $args, array $expected_placeh $this->setUpRequest('GET'); - $token = hash('crc32b', serialize($expected_placeholder_render_array)); + $token = Crypt::hashBase64(serialize($expected_placeholder_render_array)); $placeholder_callback = $expected_placeholder_render_array['#lazy_builder'][0]; $expected_placeholder_markup = ''; $this->assertSame($expected_placeholder_markup, Html::normalize($expected_placeholder_markup), 'Placeholder unaltered by Html::normalize() which is used by FilterHtmlCorrector.'); @@ -846,28 +846,24 @@ public function testRecursivePlaceholder() { /** * @covers ::render * @covers ::doRender - * - * @expectedException \DomainException - * @expectedExceptionMessage The #lazy_builder property must have an array as a value. */ public function testInvalidLazyBuilder() { $element = []; $element['#lazy_builder'] = '\Drupal\Tests\Core\Render\PlaceholdersTest::callback'; + $this->setExpectedException(\DomainException::class, 'The #lazy_builder property must have an array as a value.'); $this->renderer->renderRoot($element); } /** * @covers ::render * @covers ::doRender - * - * @expectedException \DomainException - * @expectedExceptionMessage The #lazy_builder property must have an array as a value, containing two values: the callback, and the arguments for the callback. */ public function testInvalidLazyBuilderArguments() { $element = []; $element['#lazy_builder'] = ['\Drupal\Tests\Core\Render\PlaceholdersTest::callback', 'arg1', 'arg2']; + $this->setExpectedException(\DomainException::class, 'The #lazy_builder property must have an array as a value, containing two values: the callback, and the arguments for the callback.'); $this->renderer->renderRoot($element); } @@ -879,13 +875,16 @@ public function testInvalidLazyBuilderArguments() { */ public function testScalarLazybuilderCallbackContext() { $element = []; - $element['#lazy_builder'] = ['\Drupal\Tests\Core\Render\PlaceholdersTest::callback', [ - 'string' => 'foo', - 'bool' => TRUE, - 'int' => 1337, - 'float' => 3.14, - 'null' => NULL, - ]]; + $element['#lazy_builder'] = [ + '\Drupal\Tests\Core\Render\PlaceholdersTest::callback', + [ + 'string' => 'foo', + 'bool' => TRUE, + 'int' => 1337, + 'float' => 3.14, + 'null' => NULL, + ], + ]; $result = $this->renderer->renderRoot($element); $this->assertInstanceOf('\Drupal\Core\Render\Markup', $result); @@ -895,31 +894,29 @@ public function testScalarLazybuilderCallbackContext() { /** * @covers ::render * @covers ::doRender - * - * @expectedException \DomainException - * @expectedExceptionMessage A #lazy_builder callback's context may only contain scalar values or NULL. */ public function testNonScalarLazybuilderCallbackContext() { $element = []; - $element['#lazy_builder'] = ['\Drupal\Tests\Core\Render\PlaceholdersTest::callback', [ - 'string' => 'foo', - 'bool' => TRUE, - 'int' => 1337, - 'float' => 3.14, - 'null' => NULL, - // array is not one of the scalar types. - 'array' => ['hi!'], - ]]; + $element['#lazy_builder'] = [ + '\Drupal\Tests\Core\Render\PlaceholdersTest::callback', + [ + 'string' => 'foo', + 'bool' => TRUE, + 'int' => 1337, + 'float' => 3.14, + 'null' => NULL, + // array is not one of the scalar types. + 'array' => ['hi!'], + ], + ]; + $this->setExpectedException(\DomainException::class, "A #lazy_builder callback's context may only contain scalar values or NULL."); $this->renderer->renderRoot($element); } /** * @covers ::render * @covers ::doRender - * - * @expectedException \DomainException - * @expectedExceptionMessage When a #lazy_builder callback is specified, no children can exist; all children must be generated by the #lazy_builder callback. You specified the following children: child_a, child_b. */ public function testChildrenPlusBuilder() { $element = []; @@ -927,15 +924,13 @@ public function testChildrenPlusBuilder() { $element['child_a']['#markup'] = 'Oh hai!'; $element['child_b']['#markup'] = 'kthxbai'; + $this->setExpectedException(\DomainException::class, 'When a #lazy_builder callback is specified, no children can exist; all children must be generated by the #lazy_builder callback. You specified the following children: child_a, child_b.'); $this->renderer->renderRoot($element); } /** * @covers ::render * @covers ::doRender - * - * @expectedException \DomainException - * @expectedExceptionMessage When a #lazy_builder callback is specified, no properties can exist; all properties must be generated by the #lazy_builder callback. You specified the following properties: #llama, #piglet. */ public function testPropertiesPlusBuilder() { $element = []; @@ -943,20 +938,19 @@ public function testPropertiesPlusBuilder() { $element['#llama'] = '#awesome'; $element['#piglet'] = '#cute'; + $this->setExpectedException(\DomainException::class, 'When a #lazy_builder callback is specified, no properties can exist; all properties must be generated by the #lazy_builder callback. You specified the following properties: #llama, #piglet.'); $this->renderer->renderRoot($element); } /** * @covers ::render * @covers ::doRender - * - * @expectedException \LogicException - * @expectedExceptionMessage When #create_placeholder is set, a #lazy_builder callback must be present as well. */ public function testCreatePlaceholderPropertyWithoutLazyBuilder() { $element = []; $element['#create_placeholder'] = TRUE; + $this->setExpectedException(\LogicException::class, 'When #create_placeholder is set, a #lazy_builder callback must be present as well.'); $this->renderer->renderRoot($element); } @@ -1007,7 +1001,7 @@ public function testRenderChildrenPlaceholdersDifferentArguments() { $this->assertSame($element['#attached']['drupalSettings'], $expected_js_settings, '#attached is modified; both the original JavaScript setting and the ones added by each placeholder #lazy_builder callback exist.'); // GET request: validate cached data. - $cached_element = $this->memoryCache->get('simpletest:drupal_render:children_placeholders')->data; + $cached_element = $this->memoryCache->get('simpletest:renderer:children_placeholders')->data; $expected_element = [ '#attached' => [ 'drupalSettings' => [ @@ -1077,7 +1071,7 @@ protected function generatePlaceholdersWithChildrenTestElement(array $args_1, ar $test_element = [ '#type' => 'details', '#cache' => [ - 'keys' => ['simpletest', 'drupal_render', 'children_placeholders'], + 'keys' => ['simpletest', 'renderer', 'children_placeholders'], ], '#title' => 'Parent', '#attached' => [ @@ -1086,7 +1080,7 @@ protected function generatePlaceholdersWithChildrenTestElement(array $args_1, ar ], 'placeholders' => [ 'parent-x-parent' => [ - '#lazy_builder' => [ __NAMESPACE__ . '\\PlaceholdersTest::callback', $args_1], + '#lazy_builder' => [__NAMESPACE__ . '\\PlaceholdersTest::callback', $args_1], ], ], ], diff --git a/core/tests/Drupal/Tests/Core/Render/RendererRecursionTest.php b/core/tests/Drupal/Tests/Core/Render/RendererRecursionTest.php index bffbd221..76f9d48b 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererRecursionTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererRecursionTest.php @@ -31,8 +31,6 @@ protected function setUpRenderRecursionComplexElements() { * @covers ::renderRoot * @covers ::render * @covers ::doRender - * - * @expectedException \LogicException */ public function testRenderRecursionWithNestedRenderRoot() { list($complex_child_markup, $parent_markup, $complex_child_template) = $this->setUpRenderRecursionComplexElements(); @@ -41,6 +39,7 @@ public function testRenderRecursionWithNestedRenderRoot() { $complex_child = $complex_child_template; $callable = function () use ($renderer, $complex_child) { + $this->setExpectedException(\LogicException::class); $renderer->renderRoot($complex_child); }; diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php index 51cfde8b..010ffc2a 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php @@ -74,98 +74,145 @@ public function providerTestRenderBasic() { // Pass an empty string. $data[] = ['', '']; // Previously printed, see ::renderTwice for a more integration-like test. - $data[] = [[ - '#markup' => 'foo', - '#printed' => TRUE, - ], '']; + $data[] = [ + ['#markup' => 'foo', '#printed' => TRUE], + '', + ]; // Printed in pre_render. - $data[] = [[ - '#markup' => 'foo', - '#pre_render' => [[new TestCallables(), 'preRenderPrinted']] - ], '']; + $data[] = [ + [ + '#markup' => 'foo', + '#pre_render' => [[new TestCallables(), 'preRenderPrinted']], + ], + '', + ]; // Basic #markup based renderable array. - $data[] = [[ - '#markup' => 'foo', - ], 'foo']; + $data[] = [ + ['#markup' => 'foo'], + 'foo', + ]; // Basic #plain_text based renderable array. - $data[] = [[ - '#plain_text' => 'foo', - ], 'foo']; + $data[] = [ + ['#plain_text' => 'foo'], + 'foo', + ]; // Mixing #plain_text and #markup based renderable array. - $data[] = [[ - '#plain_text' => 'foo', - '#markup' => 'bar', - ], '<em>foo</em>']; + $data[] = [ + ['#plain_text' => 'foo', '#markup' => 'bar'], + '<em>foo</em>', + ]; // Safe strings in #plain_text are still escaped. - $data[] = [[ - '#plain_text' => Markup::create('foo'), - ], '<em>foo</em>']; + $data[] = [ + ['#plain_text' => Markup::create('foo')], + '<em>foo</em>', + ]; // Renderable child element. - $data[] = [[ - 'child' => ['#markup' => 'bar'], - ], 'bar']; + $data[] = [ + ['child' => ['#markup' => 'bar']], + 'bar', + ]; // XSS filtering test. - $data[] = [[ - 'child' => ['#markup' => "This is test"], - ], "This is alert('XSS') test"]; + $data[] = [ + ['child' => ['#markup' => "This is test"]], + "This is alert('XSS') test", + ]; // XSS filtering test. - $data[] = [[ - 'child' => ['#markup' => "This is test", '#allowed_tags' => ['script']], - ], "This is test"]; + $data[] = [ + [ + 'child' => [ + '#markup' => "This is test", + '#allowed_tags' => ['script'], + ], + ], + "This is test", + ]; // XSS filtering test. - $data[] = [[ - 'child' => ['#markup' => "This is test", '#allowed_tags' => ['em', 'strong']], - ], "This is alert('XSS') test"]; + $data[] = [ + [ + 'child' => [ + '#markup' => "This is test", + '#allowed_tags' => ['em', 'strong'], + ], + ], + "This is alert('XSS') test", + ]; // Html escaping test. - $data[] = [[ - 'child' => ['#plain_text' => "This is test"], - ], "This is <script><em>alert('XSS')</em></script> <strong>test</strong>"]; + $data[] = [ + [ + 'child' => [ + '#plain_text' => "This is test", + ], + ], + "This is <script><em>alert('XSS')</em></script> <strong>test</strong>", + ]; // XSS filtering by default test. - $data[] = [[ - 'child' => ['#markup' => "This is test"], - ], "This is alert('XSS') test"]; + $data[] = [ + [ + 'child' => [ + '#markup' => "This is test", + ], + ], + "This is alert('XSS') test", + ]; // Ensure non-XSS tags are not filtered out. - $data[] = [[ - 'child' => ['#markup' => "This is test"], - ], "This is alert('not a giraffe') test"]; + $data[] = [ + [ + 'child' => [ + '#markup' => "This is test", + ], + ], + "This is alert('not a giraffe') test", + ]; // #children set but empty, and renderable children. - $data[] = [[ - '#children' => '', - 'child' => ['#markup' => 'bar'], - ], 'bar']; + $data[] = [ + ['#children' => '', 'child' => ['#markup' => 'bar']], + 'bar', + ]; // #children set, not empty, and renderable children. #children will be // assumed oto be the rendered child elements, even though the #markup for // 'child' differs. - $data[] = [[ - '#children' => 'foo', - 'child' => ['#markup' => 'bar'], - ], 'foo']; + $data[] = [ + ['#children' => 'foo', 'child' => ['#markup' => 'bar']], + 'foo', + ]; // Ensure that content added to #markup via a #pre_render callback is safe. - $data[] = [[ - '#markup' => 'foo', - '#pre_render' => [function($elements) { - $elements['#markup'] .= ''; - return $elements; - }] - ], 'fooalert("bar");']; + $data[] = [ + [ + '#markup' => 'foo', + '#pre_render' => [function ($elements) { + $elements['#markup'] .= ''; + return $elements; + } + ], + ], + 'fooalert("bar");', + ]; // Test #allowed_tags in combination with #markup and #pre_render. - $data[] = [[ - '#markup' => 'foo', - '#allowed_tags' => array('script'), - '#pre_render' => [function($elements) { - $elements['#markup'] .= ''; - return $elements; - }] - ], 'foo']; + $data[] = [ + [ + '#markup' => 'foo', + '#allowed_tags' => ['script'], + '#pre_render' => [function ($elements) { + $elements['#markup'] .= ''; + return $elements; + } + ], + ], + 'foo', + ]; // Ensure output is escaped when adding content to #check_plain through // a #pre_render callback. - $data[] = [[ - '#plain_text' => 'foo', - '#pre_render' => [function($elements) { - $elements['#plain_text'] .= ''; - return $elements; - }] - ], 'foo<script>alert("bar");</script>']; + $data[] = [ + [ + '#plain_text' => 'foo', + '#pre_render' => [function ($elements) { + $elements['#plain_text'] .= ''; + return $elements; + } + ], + ], + 'foo<script>alert("bar");</script>', + ]; // Part 2: render arrays using #theme and #theme_wrappers. @@ -178,12 +225,12 @@ public function providerTestRenderBasic() { '#theme_wrappers' => ['container'], '#attributes' => ['class' => ['baz']], ]; - $setup_code_type_link = function() { + $setup_code_type_link = function () { $this->setupThemeContainer(); $this->themeManager->expects($this->at(0)) ->method('render') ->with('common_test_foo', $this->anything()) - ->willReturnCallback(function($theme, $vars) { + ->willReturnCallback(function ($theme, $vars) { return $vars['#foo'] . $vars['#bar']; }); }; @@ -203,12 +250,12 @@ public function providerTestRenderBasic() { '#url' => 'https://www.drupal.org', '#title' => 'bar', ]; - $setup_code_type_link = function() { + $setup_code_type_link = function () { $this->setupThemeContainer(); $this->themeManager->expects($this->at(0)) ->method('render') ->with('link', $this->anything()) - ->willReturnCallback(function($theme, $vars) { + ->willReturnCallback(function ($theme, $vars) { $attributes = new Attribute(['href' => $vars['#url']] + (isset($vars['#attributes']) ? $vars['#attributes'] : [])); return '' . $vars['#title'] . ''; }); @@ -240,7 +287,7 @@ public function providerTestRenderBasic() { 'container', ], ]; - $setup_code = function() { + $setup_code = function () { $this->setupThemeContainer($this->any()); }; $data[] = [$build, '
    ' . "\n" . '
    ' . "\n", $setup_code]; @@ -250,7 +297,7 @@ public function providerTestRenderBasic() { '#theme_wrappers' => [['container']], '#attributes' => ['class' => ['foo']], ]; - $setup_code = function() { + $setup_code = function () { $this->setupThemeContainerMultiSuggestion($this->any()); }; $data[] = [$build, '
    ' . "\n", $setup_code]; @@ -264,7 +311,7 @@ public function providerTestRenderBasic() { '#theme' => ['suggestionnotimplemented'], '#markup' => 'foo', ]; - $setup_code = function() { + $setup_code = function () { $this->themeManager->expects($this->once()) ->method('render') ->with(['suggestionnotimplemented'], $this->anything()) @@ -279,7 +326,7 @@ public function providerTestRenderBasic() { '#markup' => 'foo', ], ]; - $setup_code = function() { + $setup_code = function () { $this->themeManager->expects($this->once()) ->method('render') ->with(['suggestionnotimplemented'], $this->anything()) @@ -293,7 +340,7 @@ public function providerTestRenderBasic() { '#markup' => 'foo', ]; $theme_function_output = $this->randomContextValue(); - $setup_code = function() use ($theme_function_output) { + $setup_code = function () use ($theme_function_output) { $this->themeManager->expects($this->once()) ->method('render') ->with(['common_test_empty'], $this->anything()) @@ -322,7 +369,7 @@ public function providerTestRenderBasic() { '#children' => 'baz', 'child' => ['#markup' => 'boo'], ]; - $setup_code = function() { + $setup_code = function () { $this->themeManager->expects($this->once()) ->method('render') ->with('common_test_foo', $this->anything()) @@ -341,7 +388,7 @@ public function providerTestRenderBasic() { '#markup' => 'boo', ], ]; - $setup_code = function() { + $setup_code = function () { $this->themeManager->expects($this->never()) ->method('render'); }; @@ -357,7 +404,7 @@ public function providerTestRenderBasic() { '#markup' => 'boo', ], ]; - $setup_code = function() { + $setup_code = function () { $this->themeManager->expects($this->never()) ->method('render'); }; @@ -408,17 +455,17 @@ public function testRenderSortingWithSetHashSorted() { $first = $this->randomMachineName(); $second = $this->randomMachineName(); // The same array structure again, but with #sorted set to TRUE. - $elements = array( - 'second' => array( + $elements = [ + 'second' => [ '#weight' => 10, '#markup' => $second, - ), - 'first' => array( + ], + 'first' => [ '#weight' => 0, '#markup' => $first, - ), + ], '#sorted' => TRUE, - ); + ]; $output = $this->renderer->renderRoot($elements); // The elements should appear in output in the same order as the array. @@ -447,7 +494,7 @@ public function testRenderWithPresetAccess($access) { */ public function testRenderWithAccessCallbackCallable($access) { $build = [ - '#access_callback' => function() use ($access) { + '#access_callback' => function () use ($access) { return $access; } ]; @@ -466,7 +513,7 @@ public function testRenderWithAccessCallbackCallable($access) { public function testRenderWithAccessPropertyAndCallback($access) { $build = [ '#access' => $access, - '#access_callback' => function() { + '#access_callback' => function () { return TRUE; } ]; @@ -511,7 +558,7 @@ public function testRenderWithAccessControllerResolved($access) { * @covers ::render * @covers ::doRender */ - public function testRenderAccessCacheablityDependencyInheritance() { + public function testRenderAccessCacheabilityDependencyInheritance() { $build = [ '#access' => AccessResult::allowed()->addCacheContexts(['user']), ]; @@ -578,7 +625,7 @@ protected function setupThemeContainer($matcher = NULL) { $this->themeManager->expects($matcher ?: $this->at(1)) ->method('render') ->with('container', $this->anything()) - ->willReturnCallback(function($theme, $vars) { + ->willReturnCallback(function ($theme, $vars) { return '' . $vars['#children'] . "\n"; }); } @@ -587,7 +634,7 @@ protected function setupThemeContainerMultiSuggestion($matcher = NULL) { $this->themeManager->expects($matcher ?: $this->at(1)) ->method('render') ->with(['container'], $this->anything()) - ->willReturnCallback(function($theme, $vars) { + ->willReturnCallback(function ($theme, $vars) { return '' . $vars['#children'] . "\n"; }); } @@ -597,9 +644,9 @@ protected function setupThemeContainerMultiSuggestion($matcher = NULL) { * @covers ::doRender */ public function testRenderWithoutThemeArguments() { - $element = array( + $element = [ '#theme' => 'common_test_foo', - ); + ]; $this->themeManager->expects($this->once()) ->method('render') @@ -615,11 +662,11 @@ public function testRenderWithoutThemeArguments() { * @covers ::doRender */ public function testRenderWithThemeArguments() { - $element = array( + $element = [ '#theme' => 'common_test_foo', '#foo' => $this->randomMachineName(), '#bar' => $this->randomMachineName(), - ); + ]; $this->themeManager->expects($this->once()) ->method('render') diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php index 7c5e8557..258fa22f 100644 --- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php +++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php @@ -147,7 +147,7 @@ protected function setUp() { $current_user_role = &$this->currentUserRole; $this->cacheContextsManager->expects($this->any()) ->method('convertTokensToKeys') - ->willReturnCallback(function($context_tokens) use (&$current_user_role) { + ->willReturnCallback(function ($context_tokens) use (&$current_user_role) { $keys = []; foreach ($context_tokens as $context_id) { switch ($context_id) { @@ -208,7 +208,7 @@ protected function setUpUnusedCache() { * Sets up a memory-based render cache back-end. */ protected function setupMemoryCache() { - $this->memoryCache = $this->memoryCache ?: new MemoryBackend('render'); + $this->memoryCache = $this->memoryCache ?: new MemoryBackend(); $this->cacheFactory->expects($this->atLeastOnce()) ->method('get') diff --git a/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php index dadf612f..96a01b43 100644 --- a/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php +++ b/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php @@ -27,54 +27,54 @@ class RoleAccessCheckTest extends UnitTestCase { protected function getTestRouteCollection() { $route_collection = new RouteCollection(); $route_collection->add('role_test_1', new Route('/role_test_1', - array( + [ '_controller' => '\Drupal\router_test\TestControllers::test1', - ), - array( + ], + [ '_role' => 'role_test_1', - ) + ] )); $route_collection->add('role_test_2', new Route('/role_test_2', - array( + [ '_controller' => '\Drupal\router_test\TestControllers::test1', - ), - array( + ], + [ '_role' => 'role_test_2', - ) + ] )); $route_collection->add('role_test_3', new Route('/role_test_3', - array( + [ '_controller' => '\Drupal\router_test\TestControllers::test1', - ), - array( + ], + [ '_role' => 'role_test_1,role_test_2', - ) + ] )); // Ensure that trimming the values works on "OR" conjunctions. $route_collection->add('role_test_4', new Route('/role_test_4', - array( + [ '_controller' => '\Drupal\router_test\TestControllers::test1', - ), - array( + ], + [ '_role' => 'role_test_1 , role_test_2', - ) + ] )); $route_collection->add('role_test_5', new Route('/role_test_5', - array( + [ '_controller' => '\Drupal\router_test\TestControllers::test1', - ), - array( + ], + [ '_role' => 'role_test_1+role_test_2', - ) + ] )); // Ensure that trimming the values works on "AND" conjunctions. $route_collection->add('role_test_6', new Route('/role_test_6', - array( + [ '_controller' => '\Drupal\router_test\TestControllers::test1', - ), - array( + ], + [ '_role' => 'role_test_1 + role_test_2', - ) + ] )); return $route_collection; @@ -93,35 +93,35 @@ public function roleAccessProvider() { // Setup one user with the first role, one with the second, one with both // and one final without any of these two roles. - $account_1 = new UserSession(array( + $account_1 = new UserSession([ 'uid' => 1, - 'roles' => array($rid_1), - )); + 'roles' => [$rid_1], + ]); - $account_2 = new UserSession(array( + $account_2 = new UserSession([ 'uid' => 2, - 'roles' => array($rid_2), - )); + 'roles' => [$rid_2], + ]); - $account_12 = new UserSession(array( + $account_12 = new UserSession([ 'uid' => 3, - 'roles' => array($rid_1, $rid_2), - )); + 'roles' => [$rid_1, $rid_2], + ]); - $account_none = new UserSession(array( + $account_none = new UserSession([ 'uid' => 1, - 'roles' => array(), - )); + 'roles' => [], + ]); // Setup expected values; specify which paths can be accessed by which user. - return array( - array('role_test_1', array($account_1, $account_12), array($account_2, $account_none)), - array('role_test_2', array($account_2, $account_12), array($account_1, $account_none)), - array('role_test_3', array($account_12), array($account_1, $account_2, $account_none)), - array('role_test_4', array($account_12), array($account_1, $account_2, $account_none)), - array('role_test_5', array($account_1, $account_2, $account_12), array()), - array('role_test_6', array($account_1, $account_2, $account_12), array()), - ); + return [ + ['role_test_1', [$account_1, $account_12], [$account_2, $account_none]], + ['role_test_2', [$account_2, $account_12], [$account_1, $account_none]], + ['role_test_3', [$account_12], [$account_1, $account_2, $account_none]], + ['role_test_4', [$account_12], [$account_1, $account_2, $account_none]], + ['role_test_5', [$account_1, $account_2, $account_12], []], + ['role_test_6', [$account_1, $account_2, $account_12], []], + ]; } /** diff --git a/core/tests/Drupal/Tests/Core/RouteProcessor/RouteProcessorManagerTest.php b/core/tests/Drupal/Tests/Core/RouteProcessor/RouteProcessorManagerTest.php index 5bc2be0f..1de17456 100644 --- a/core/tests/Drupal/Tests/Core/RouteProcessor/RouteProcessorManagerTest.php +++ b/core/tests/Drupal/Tests/Core/RouteProcessor/RouteProcessorManagerTest.php @@ -30,14 +30,14 @@ protected function setUp() { */ public function testRouteProcessorManager() { $route = new Route(''); - $parameters = array('test' => 'test'); + $parameters = ['test' => 'test']; $route_name = 'test_name'; - $processors = array( + $processors = [ 10 => $this->getMockProcessor($route_name, $route, $parameters), 5 => $this->getMockProcessor($route_name, $route, $parameters), 0 => $this->getMockProcessor($route_name, $route, $parameters), - ); + ]; // Add the processors in reverse order. foreach ($processors as $priority => $processor) { diff --git a/core/modules/system/tests/modules/accept_header_routing_test/tests/Unit/AcceptHeaderMatcherTest.php b/core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php similarity index 89% rename from core/modules/system/tests/modules/accept_header_routing_test/tests/Unit/AcceptHeaderMatcherTest.php rename to core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php index 16bb08f4..8d6bf813 100644 --- a/core/modules/system/tests/modules/accept_header_routing_test/tests/Unit/AcceptHeaderMatcherTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/AcceptHeaderMatcherTest.php @@ -1,11 +1,11 @@ headers->set('Accept', 'application/json, text/xml;q=0.9'); $request->setRequestFormat('json'); + $this->setExpectedException(NotAcceptableHttpException::class, 'No route found for the specified formats application/json text/xml'); $this->matcher->filter($routes, $request); - $this->matcher->filter($routes, $request); - $this->fail('No exception was thrown.'); } } diff --git a/core/tests/Drupal/Tests/Core/Routing/AccessAwareRouterTest.php b/core/tests/Drupal/Tests/Core/Routing/AccessAwareRouterTest.php index 0b7bcc67..53405f11 100644 --- a/core/tests/Drupal/Tests/Core/Routing/AccessAwareRouterTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/AccessAwareRouterTest.php @@ -61,7 +61,7 @@ protected function setupRouter() { ->getMock(); $this->chainRouter->expects($this->once()) ->method('matchRequest') - ->will($this->returnValue(array(RouteObjectInterface::ROUTE_OBJECT => $this->route))); + ->will($this->returnValue([RouteObjectInterface::ROUTE_OBJECT => $this->route])); $this->router = new AccessAwareRouter($this->chainRouter, $this->accessManager, $this->currentUser); } @@ -87,8 +87,6 @@ public function testMatchRequestAllowed() { /** * Tests the matchRequest() function for access denied. - * - * @expectedException \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException */ public function testMatchRequestDenied() { $this->setupRouter(); @@ -98,12 +96,8 @@ public function testMatchRequestDenied() { ->method('checkRequest') ->with($request) ->willReturn($access_result); - $parameters = $this->router->matchRequest($request); - $expected = [ - AccessAwareRouterInterface::ACCESS_RESULT => $access_result, - ]; - $this->assertSame($expected, $request->attributes->all()); - $this->assertSame($expected, $parameters); + $this->setExpectedException(AccessDeniedHttpException::class); + $this->router->matchRequest($request); } /** diff --git a/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php b/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php index 1b72b753..8a7554de 100644 --- a/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\Core\Routing; use Drupal\Core\Routing\MethodFilter; +use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Route; @@ -12,7 +13,7 @@ * @coversDefaultClass \Drupal\Core\Routing\MethodFilter * @group Routing */ -class MethodFilterTest extends \PHPUnit_Framework_TestCase { +class MethodFilterTest extends UnitTestCase { /** * @covers ::applies diff --git a/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php b/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php index fd99e990..afe7f4d5 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RedirectDestinationTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\Core\Routing; +use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Routing\RedirectDestination; use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; @@ -48,10 +49,10 @@ protected function setUp() { protected function setupUrlGenerator() { $this->urlGenerator->expects($this->any()) ->method('generateFromRoute') - ->willReturnCallback(function($route, $parameters, $options) { + ->willReturnCallback(function ($route, $parameters, $options) { $query_string = ''; if (!empty($options['query'])) { - $query_string = '?' . $options['query']; + $query_string = '?' . UrlHelper::buildQuery($options['query']); } return '/current-path' . $query_string; diff --git a/core/tests/Drupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php b/core/tests/Drupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php index 39a960b5..4a9e0c6b 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RequestFormatRouteFilterTest.php @@ -5,6 +5,7 @@ use Drupal\Core\Routing\RequestFormatRouteFilter; use Drupal\Tests\UnitTestCase; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -35,10 +36,20 @@ public function testAppliesWithFormat() { /** * @covers ::filter + * @dataProvider filterProvider */ - public function testFilter() { + public function testFilter(RouteCollection $collection, $request_format, array $expected_filtered_collection) { $route_filter = new RequestFormatRouteFilter(); + $request = new Request(); + $request->setRequestFormat($request_format); + $collection = $route_filter->filter($collection, $request); + + $this->assertCount(count($expected_filtered_collection), $collection); + $this->assertSame($expected_filtered_collection, array_keys($collection->all())); + } + + public function filterProvider() { $route_without_format = new Route('/test'); $route_with_format = $route = new Route('/test'); $route_with_format->setRequirement('_format', 'json'); @@ -50,19 +61,20 @@ public function testFilter() { $collection->add('test_1', $route_with_format); $collection->add('test_2', $route_with_multiple_formats); - $request = new Request(); - $request->setRequestFormat('xml'); - $collection = $route_filter->filter($collection, $request); + $sole_route_match_single_format = new RouteCollection(); + $sole_route_match_single_format->add('sole_route_single_format', $route_with_format); - $this->assertCount(2, $collection); - $this->assertEquals(array_keys($collection->all())[0], 'test_2'); - $this->assertEquals(array_keys($collection->all())[1], 'test_0'); + return [ + 'xml requested' => [clone $collection, 'xml', ['test_2', 'test_0']], + 'json requested' => [clone $collection, 'json', ['test_1', 'test_2', 'test_0']], + 'html format requested' => [clone $collection, 'html', ['test_0']], + 'no format requested, defaults to html' => [clone $collection, NULL, ['test_0']], + 'no format requested, single route match with single format, defaults to that format' => [clone $sole_route_match_single_format, NULL, ['sole_route_single_format']], + ]; } /** * @covers ::filter - * @expectedException \Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException - * @expectedExceptionMessage No route found for the specified format xml. */ public function testNoRouteFound() { $collection = new RouteCollection(); @@ -74,6 +86,23 @@ public function testNoRouteFound() { $request = Request::create('test?_format=xml', 'GET'); $request->setRequestFormat('xml'); $route_filter = new RequestFormatRouteFilter(); + $this->setExpectedException(NotAcceptableHttpException::class, 'No route found for the specified format xml.'); + $route_filter->filter($collection, $request); + } + + /** + * @covers ::filter + */ + public function testNoRouteFoundWhenNoRequestFormatAndSingleRouteWithMultipleFormats() { + $this->setExpectedException(NotAcceptableHttpException::class, 'No route found for the specified format html.'); + + $collection = new RouteCollection(); + $route_with_format = $route = new Route('/test'); + $route_with_format->setRequirement('_format', 'json|xml'); + $collection->add('sole_route_multiple_formats', $route_with_format); + + $request = Request::create('test', 'GET'); + $route_filter = new RequestFormatRouteFilter(); $route_filter->filter($collection, $request); } diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php index a1095cd2..d0759341 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php @@ -106,7 +106,7 @@ public function testRebuildLockingUnlocking() { $this->yamlDiscovery->expects($this->any()) ->method('findAll') - ->will($this->returnValue(array())); + ->will($this->returnValue([])); $this->assertTrue($this->routeBuilder->rebuild()); } @@ -149,7 +149,7 @@ public function testRebuildWithStaticModuleRoutes() { $this->yamlDiscovery->expects($this->once()) ->method('findAll') - ->will($this->returnValue(array('test_module' => $routes))); + ->will($this->returnValue(['test_module' => $routes])); $route_collection = $routing_fixtures->sampleRouteCollection(); $route_build_event = new RouteBuildEvent($route_collection); @@ -192,14 +192,14 @@ public function testRebuildWithProviderBasedRoutes() { $this->yamlDiscovery->expects($this->once()) ->method('findAll') - ->will($this->returnValue(array( - 'test_module' => array( - 'route_callbacks' => array( + ->will($this->returnValue([ + 'test_module' => [ + 'route_callbacks' => [ '\Drupal\Tests\Core\Routing\TestRouteSubscriber::routesFromArray', 'test_module.route_service:routesFromCollection', - ), - ), - ))); + ], + ], + ])); $container = new ContainerBuilder(); $container->set('test_module.route_service', new TestRouteSubscriber()); @@ -215,7 +215,7 @@ public function testRebuildWithProviderBasedRoutes() { list($class, $method) = explode('::', $controller, 2); $object = new $class(); } - return array($object, $method); + return [$object, $method]; })); $route_collection_filled = new RouteCollection(); @@ -262,8 +262,8 @@ public function testRebuildIfNeeded() { ->with('router_rebuild'); $this->yamlDiscovery->expects($this->any()) - ->method('findAll') - ->will($this->returnValue(array())); + ->method('findAll') + ->will($this->returnValue([])); $this->routeBuilder->setRebuildNeeded(); @@ -312,9 +312,9 @@ protected function getRouteDefinitions() { */ class TestRouteSubscriber { public function routesFromArray() { - return array( + return [ 'test_route.1' => new Route('/test-route/1'), - ); + ]; } public function routesFromCollection() { $collection = new RouteCollection(); diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php index 271e313e..2ddfdcae 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteCompilerTest.php @@ -38,15 +38,15 @@ public function testGetFit($path, $expected) { * value. */ public function providerTestGetFit() { - return array( - array('test', 1), - array('/testwithleadingslash', 1), - array('testwithtrailingslash/', 1), - array('/testwithslashes/', 1), - array('test/with/multiple/parts', 15), - array('test/with/{some}/slugs', 13), - array('test/very/long/path/that/drupal/7/could/not/have/handled', 2047), - ); + return [ + ['test', 1], + ['/testwithleadingslash', 1], + ['testwithtrailingslash/', 1], + ['/testwithslashes/', 1], + ['test/with/multiple/parts', 15], + ['test/with/{some}/slugs', 13], + ['test/very/long/path/that/drupal/7/could/not/have/handled', 2047], + ]; } /** @@ -67,9 +67,9 @@ public function testCompilation() { public function testCompilationDefaultValue() { // Because "here" has a default value, it should not factor into the outline // or the fitness. - $route = new Route('/test/{something}/more/{here}', array( + $route = new Route('/test/{something}/more/{here}', [ 'here' => 'there', - )); + ]); $route->setOption('compiler_class', 'Drupal\Core\Routing\RouteCompiler'); $compiled = $route->compile(); diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteMatchTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteMatchTest.php index 22055c9f..0a3c65cb 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteMatchTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteMatchTest.php @@ -32,9 +32,9 @@ public function testRouteMatchFromRequest() { $route_match = RouteMatch::createFromRequest($request); $this->assertNull($route_match->getRouteName()); $this->assertNull($route_match->getRouteObject()); - $this->assertSame(array(), $route_match->getParameters()->all()); + $this->assertSame([], $route_match->getParameters()->all()); $this->assertNull($route_match->getParameter('foo')); - $this->assertSame(array(), $route_match->getRawParameters()->all()); + $this->assertSame([], $route_match->getRawParameters()->all()); $this->assertNull($route_match->getRawParameter('foo')); // A routed request without parameter upcasting. @@ -45,17 +45,17 @@ public function testRouteMatchFromRequest() { $route_match = RouteMatch::createFromRequest($request); $this->assertSame('test_route', $route_match->getRouteName()); $this->assertSame($route, $route_match->getRouteObject()); - $this->assertSame(array('foo' => '1'), $route_match->getParameters()->all()); - $this->assertSame(array(), $route_match->getRawParameters()->all()); + $this->assertSame(['foo' => '1'], $route_match->getParameters()->all()); + $this->assertSame([], $route_match->getRawParameters()->all()); // A routed request with parameter upcasting. $foo = new \stdClass(); $foo->value = 1; $request->attributes->set('foo', $foo); - $request->attributes->set('_raw_variables', new ParameterBag(array('foo' => '1'))); + $request->attributes->set('_raw_variables', new ParameterBag(['foo' => '1'])); $route_match = RouteMatch::createFromRequest($request); - $this->assertSame(array('foo' => $foo), $route_match->getParameters()->all()); - $this->assertSame(array('foo' => '1'), $route_match->getRawParameters()->all()); + $this->assertSame(['foo' => $foo], $route_match->getParameters()->all()); + $this->assertSame(['foo' => '1'], $route_match->getRawParameters()->all()); } } diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteMatchTestBase.php b/core/tests/Drupal/Tests/Core/Routing/RouteMatchTestBase.php index 6af83970..2678fd32 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteMatchTestBase.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteMatchTestBase.php @@ -31,46 +31,46 @@ abstract protected function getRouteMatch($name, Route $route, array $parameters * Provide sets of parameters and expected parameters for parameter tests. */ public function routeMatchProvider() { - $base_data = array( - array( + $base_data = [ + [ new Route( '/test-route/{param_without_leading_underscore}/{_param_with_leading_underscore}', - array( + [ 'default_without_leading_underscore' => NULL, '_default_with_leading_underscore' => NULL, - ) + ] ), - array( + [ 'param_without_leading_underscore' => 'value', '_param_with_leading_underscore' => 'value', 'default_without_leading_underscore' => 'value', '_default_with_leading_underscore' => 'value', 'foo' => 'value', - ), + ], // Parameters should be filtered to only those defined by the route. // Specifically: // - Path parameters, regardless of name. // - Defaults that are not path parameters only if they do not start with // an underscore. - array( + [ 'param_without_leading_underscore' => 'value', '_param_with_leading_underscore' => 'value', 'default_without_leading_underscore' => 'value', - ), - ), - ); + ], + ], + ]; - $data = array(); + $data = []; foreach ($base_data as $entry) { $route = $entry[0]; $params = $entry[1]; $expected_params = $entry[2]; - $data[] = array( + $data[] = [ $this->getRouteMatch('test_route', $route, $params, $params), $route, $params, $expected_params, - ); + ]; } return $data; diff --git a/core/tests/Drupal/Tests/Core/Routing/RoutePreloaderTest.php b/core/tests/Drupal/Tests/Core/Routing/RoutePreloaderTest.php index 4db42972..90b4a9dd 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RoutePreloaderTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RoutePreloaderTest.php @@ -61,15 +61,15 @@ public function testOnAlterRoutesWithAdminRoutes() { ->disableOriginalConstructor() ->getMock(); $route_collection = new RouteCollection(); - $route_collection->add('test', new Route('/admin/foo', array('_controller' => 'Drupal\ExampleController'))); - $route_collection->add('test2', new Route('/admin/bar', array('_controller' => 'Drupal\ExampleController'))); + $route_collection->add('test', new Route('/admin/foo', ['_controller' => 'Drupal\ExampleController'])); + $route_collection->add('test2', new Route('/admin/bar', ['_controller' => 'Drupal\ExampleController'])); $event->expects($this->once()) ->method('getRouteCollection') ->will($this->returnValue($route_collection)); $this->state->expects($this->once()) ->method('set') - ->with('routing.non_admin_routes', array()); + ->with('routing.non_admin_routes', []); $this->preloader->onAlterRoutes($event); $this->preloader->onFinishedRoutes(new Event()); } @@ -82,17 +82,17 @@ public function testOnAlterRoutesWithAdminPathNoAdminRoute() { ->disableOriginalConstructor() ->getMock(); $route_collection = new RouteCollection(); - $route_collection->add('test', new Route('/foo/admin/foo', array('_controller' => 'Drupal\ExampleController'))); - $route_collection->add('test2', new Route('/bar/admin/bar', array('_controller' => 'Drupal\ExampleController'))); - $route_collection->add('test3', new Route('/administrator/a', array('_controller' => 'Drupal\ExampleController'))); - $route_collection->add('test4', new Route('/admin', array('_controller' => 'Drupal\ExampleController'))); + $route_collection->add('test', new Route('/foo/admin/foo', ['_controller' => 'Drupal\ExampleController'])); + $route_collection->add('test2', new Route('/bar/admin/bar', ['_controller' => 'Drupal\ExampleController'])); + $route_collection->add('test3', new Route('/administrator/a', ['_controller' => 'Drupal\ExampleController'])); + $route_collection->add('test4', new Route('/admin', ['_controller' => 'Drupal\ExampleController'])); $event->expects($this->once()) ->method('getRouteCollection') ->will($this->returnValue($route_collection)); $this->state->expects($this->once()) ->method('set') - ->with('routing.non_admin_routes', array('test', 'test2', 'test3')); + ->with('routing.non_admin_routes', ['test', 'test2', 'test3']); $this->preloader->onAlterRoutes($event); $this->preloader->onFinishedRoutes(new Event()); } @@ -106,17 +106,17 @@ public function testOnAlterRoutesWithNonAdminRoutes() { ->disableOriginalConstructor() ->getMock(); $route_collection = new RouteCollection(); - $route_collection->add('test', new Route('/admin/foo', array('_controller' => 'Drupal\ExampleController'))); - $route_collection->add('test2', new Route('/bar', array('_controller' => 'Drupal\ExampleController'))); + $route_collection->add('test', new Route('/admin/foo', ['_controller' => 'Drupal\ExampleController'])); + $route_collection->add('test2', new Route('/bar', ['_controller' => 'Drupal\ExampleController'])); // Non content routes, like ajax callbacks should be ignored. - $route_collection->add('test3', new Route('/bar', array('_controller' => 'Drupal\ExampleController'))); + $route_collection->add('test3', new Route('/bar', ['_controller' => 'Drupal\ExampleController'])); $event->expects($this->once()) ->method('getRouteCollection') ->will($this->returnValue($route_collection)); $this->state->expects($this->once()) ->method('set') - ->with('routing.non_admin_routes', array('test2', 'test3')); + ->with('routing.non_admin_routes', ['test2', 'test3']); $this->preloader->onAlterRoutes($event); $this->preloader->onFinishedRoutes(new Event()); } @@ -161,7 +161,7 @@ public function testOnRequestOnHtml() { $this->state->expects($this->once()) ->method('get') ->with('routing.non_admin_routes') - ->will($this->returnValue(array('test2'))); + ->will($this->returnValue(['test2'])); $this->preloader->onRequest($event); } diff --git a/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php b/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php index d1826ed4..38278ab0 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php +++ b/core/tests/Drupal/Tests/Core/Routing/RoutingFixtures.php @@ -47,32 +47,32 @@ public function dropTables(Connection $connection) { * Returns a static version of the routes. */ public function staticSampleRouteCollection() { - $routes = array(); - $routes['route_a'] = array( + $routes = []; + $routes['route_a'] = [ 'path' => '/path/one', - 'methods' => array('GET'), - ); - $routes['route_b'] = array( + 'methods' => ['GET'], + ]; + $routes['route_b'] = [ 'path' => '/path/one', - 'methods' => array('PUT'), - ); - $routes['route_c'] = array( + 'methods' => ['PUT'], + ]; + $routes['route_c'] = [ 'path' => '/path/two', - 'methods' => array('GET'), - 'requirements' => array( + 'methods' => ['GET'], + 'requirements' => [ '_format' => 'json' - ), - ); - $routes['route_d'] = array( + ], + ]; + $routes['route_d'] = [ 'path' => '/path/three', - ); - $routes['route_e'] = array( + ]; + $routes['route_e'] = [ 'path' => '/path/two', - 'methods' => array('GET', 'HEAD'), - 'requirements' => array( + 'methods' => ['GET', 'HEAD'], + 'requirements' => [ '_format' => 'html' - ), - ); + ], + ]; return $routes; } @@ -139,6 +139,74 @@ public function complexRouteCollection() { return $collection; } + /** + * Returns a complex set of routes for testing. + * + * @return \Symfony\Component\Routing\RouteCollection + */ + public function mixedCaseRouteCollection() { + $collection = new RouteCollection(); + + $route = new Route('/path/one'); + $route->setMethods(['GET']); + $collection->add('route_a', $route); + + $route = new Route('/path/{thing}/one'); + $route->setMethods(['PUT']); + $collection->add('route_b', $route); + + // Uses Hebrew letter QOF (U+05E7) + $route = new Route('/somewhere/{item}/over/the/קainbow'); + $route->setMethods(['GET']); + $collection->add('route_c', $route); + + $route = new Route('/another/{thing}/aboUT/{item}'); + $collection->add('route_d', $route); + + // Greek letters lower case phi (U+03C6) and lower case omega (U+03C9) + $route = new Route('/place/meφω'); + $route->setMethods(['GET', 'HEAD']); + $collection->add('route_e', $route); + + return $collection; + } + + /** + * Returns a complex set of routes for testing. + * + * @return \Symfony\Component\Routing\RouteCollection + */ + public function duplicatePathsRouteCollection() { + $collection = new RouteCollection(); + + $route = new Route('/path/one'); + $route->setMethods(['GET']); + $collection->add('route_b', $route); + + // Add the routes not in order by route name. + $route = new Route('/path/one'); + $route->setMethods(['GET']); + $collection->add('route_a', $route); + + $route = new Route('/path/one'); + $route->setMethods(['GET']); + $collection->add('route_c', $route); + + $route = new Route('/path/TWO'); + $route->setMethods(['GET']); + $collection->add('route_d', $route); + + // Greek letters lower case phi (U+03C6) and lower case omega (U+03C9) + $route = new Route('/place/meφω'); + $route->setMethods(['GET', 'HEAD']); + $collection->add('route_f', $route); + + $route = new Route('/PLACE/meφω'); + $collection->add('route_e', $route); + + return $collection; + } + /** * Returns a Content-type restricted set of routes for testing. * @@ -167,74 +235,74 @@ public function contentRouteCollection() { */ public function routingTableDefinition() { - $tables['test_routes'] = array( + $tables['test_routes'] = [ 'description' => 'Maps paths to various callbacks (access, page and title)', - 'fields' => array( - 'name' => array( + 'fields' => [ + 'name' => [ 'description' => 'Primary Key: Machine name of this route', 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'path' => array( + ], + 'path' => [ 'description' => 'The path for this URI', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'pattern_outline' => array( + ], + 'pattern_outline' => [ 'description' => 'The pattern', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'provider' => array( + ], + 'provider' => [ 'description' => 'The provider grouping to which a route belongs.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'access_callback' => array( + ], + 'access_callback' => [ 'description' => 'The callback which determines the access to this router path. Defaults to \Drupal\Core\Session\AccountInterface::hasPermission.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', - ), - 'access_arguments' => array( + ], + 'access_arguments' => [ 'description' => 'A serialized array of arguments for the access callback.', 'type' => 'blob', 'not null' => FALSE, - ), - 'fit' => array( + ], + 'fit' => [ 'description' => 'A numeric representation of how specific the path is.', 'type' => 'int', 'not null' => TRUE, 'default' => 0, - ), - 'number_parts' => array( + ], + 'number_parts' => [ 'description' => 'Number of parts in this router path.', 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small', - ), - 'route' => array( + ], + 'route' => [ 'description' => 'A serialized Route object', 'type' => 'text', - ), - ), - 'indexes' => array( - 'fit' => array('fit'), - 'pattern_outline' => array('pattern_outline'), - 'provider' => array('provider'), - ), - 'primary key' => array('name'), - ); + ], + ], + 'indexes' => [ + 'fit' => ['fit'], + 'pattern_outline' => ['pattern_outline'], + 'provider' => ['provider'], + ], + 'primary key' => ['name'], + ]; return $tables; } diff --git a/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php b/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php index 0cfbad56..ded951b2 100644 --- a/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php @@ -29,7 +29,6 @@ public function testSetTargetUrlWithInternalUrl() { /** * @covers ::setTargetUrl - * @expectedException \InvalidArgumentException */ public function testSetTargetUrlWithUntrustedUrl() { $request_context = new RequestContext(); @@ -40,6 +39,7 @@ public function testSetTargetUrlWithUntrustedUrl() { $redirect_response = new TrustedRedirectResponse('/example'); + $this->setExpectedException(\InvalidArgumentException::class); $redirect_response->setTargetUrl('http://evil-url.com/example'); } diff --git a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php index 06e8c177..6c6d768a 100644 --- a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php @@ -68,6 +68,13 @@ class UrlGeneratorTest extends UnitTestCase { */ protected $context; + /** + * The path processor. + * + * @var \Drupal\Core\PathProcessor\PathProcessorManager + */ + protected $processorManager; + /** * {@inheritdoc} */ @@ -100,8 +107,8 @@ protected function setUp() { // We need to set up return value maps for both the getRouteByName() and the // getRoutesByNames() method calls on the route provider. The parameters // are not passed in and default to an empty array. - $route_name_return_map = $routes_names_return_map = array(); - $return_map_values = array( + $route_name_return_map = $routes_names_return_map = []; + $return_map_values = [ [ 'route_name' => 'test_1', 'return' => $first_route, @@ -122,10 +129,10 @@ protected function setUp() { 'route_name' => '', 'return' => $none_route, ], - ); + ]; foreach ($return_map_values as $values) { - $route_name_return_map[] = array($values['route_name'], $values['return']); - $routes_names_return_map[] = array(array($values['route_name']), $values['return']); + $route_name_return_map[] = [$values['route_name'], $values['return']]; + $routes_names_return_map[] = [[$values['route_name']], $values['return']]; } $this->provider = $provider; $this->provider->expects($this->any()) @@ -142,7 +149,7 @@ protected function setUp() { $alias_manager->expects($this->any()) ->method('getAliasByPath') - ->will($this->returnCallback(array($this, 'aliasManagerCallback'))); + ->will($this->returnCallback([$this, 'aliasManagerCallback'])); $this->aliasManager = $alias_manager; @@ -156,6 +163,7 @@ protected function setUp() { $processor = new PathProcessorAlias($this->aliasManager); $processor_manager = new PathProcessorManager(); $processor_manager->addOutbound($processor, 1000); + $this->processorManager = $processor_manager; $this->routeProcessorManager = $this->getMockBuilder('Drupal\Core\RouteProcessor\RouteProcessorManager') ->disableOriginalConstructor() @@ -215,7 +223,7 @@ public function testAliasGeneration() { * Confirms that generated routes will have aliased paths using interface constants. */ public function testAliasGenerationUsingInterfaceConstants() { - $url = $this->generator->generate('test_1', array(), UrlGenerator::ABSOLUTE_PATH); + $url = $this->generator->generate('test_1', [], UrlGenerator::ABSOLUTE_PATH); $this->assertEquals('/hello/world', $url); // No cacheability to test; UrlGenerator::generate() doesn't support // collecting cacheability metadata. @@ -295,7 +303,7 @@ public function testGetPathFromRouteWithSubdirectory() { * Confirms that generated routes will have aliased paths. */ public function testAliasGenerationWithParameters() { - $url = $this->generator->generate('test_2', array('narf' => '5')); + $url = $this->generator->generate('test_2', ['narf' => '5']); $this->assertEquals('/goodbye/cruel/world', $url); // No cacheability to test; UrlGenerator::generate() doesn't support // collecting cacheability metadata. @@ -304,17 +312,17 @@ public function testAliasGenerationWithParameters() { ->method('processOutbound') ->with($this->anything()); - $options = array('fragment' => 'top'); + $options = ['fragment' => 'top']; // Extra parameters should appear in the query string. $this->assertGenerateFromRoute('test_1', ['zoo' => 5], $options, '/hello/world?zoo=5#top', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); - $options = array('query' => array('page' => '1'), 'fragment' => 'bottom'); + $options = ['query' => ['page' => '1'], 'fragment' => 'bottom']; $this->assertGenerateFromRoute('test_2', ['narf' => 5], $options, '/goodbye/cruel/world?page=1#bottom', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); // Changing the parameters, the route still matches but there is no alias. $this->assertGenerateFromRoute('test_2', ['narf' => 7], $options, '/test/two/7?page=1#bottom', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); - $path = $this->generator->getPathFromRoute('test_2', array('narf' => '5')); + $path = $this->generator->getPathFromRoute('test_2', ['narf' => '5']); $this->assertEquals('test/two/5', $path); // Specify a query parameter with NULL. @@ -363,6 +371,13 @@ public function providerTestAliasGenerationWithOptions() { ['query' => ['page' => '1/2'], 'fragment' => 'bottom'], '/test/two/7?page=1/2#bottom', ]; + // A NULL query string. + $data['query-with-NULL'] = [ + 'test_2', + ['narf' => '7'], + ['query' => NULL, 'fragment' => 'bottom'], + '/test/two/7#bottom', + ]; return $data; } @@ -381,7 +396,7 @@ public function testGetPathFromRouteTrailing() { * Confirms that absolute URLs work with generated routes. */ public function testAbsoluteURLGeneration() { - $url = $this->generator->generate('test_1', array(), TRUE); + $url = $this->generator->generate('test_1', [], TRUE); $this->assertEquals('http://localhost/hello/world', $url); // No cacheability to test; UrlGenerator::generate() doesn't support // collecting cacheability metadata. @@ -390,7 +405,7 @@ public function testAbsoluteURLGeneration() { ->method('processOutbound') ->with($this->anything()); - $options = array('absolute' => TRUE, 'fragment' => 'top'); + $options = ['absolute' => TRUE, 'fragment' => 'top']; // Extra parameters should appear in the query string. $this->assertGenerateFromRoute('test_1', ['zoo' => 5], $options, 'http://localhost/hello/world?zoo=5#top', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)->setCacheContexts(['url.site'])); } @@ -399,7 +414,7 @@ public function testAbsoluteURLGeneration() { * Confirms that absolute URLs work with generated routes using interface constants. */ public function testAbsoluteURLGenerationUsingInterfaceConstants() { - $url = $this->generator->generate('test_1', array(), UrlGenerator::ABSOLUTE_URL); + $url = $this->generator->generate('test_1', [], UrlGenerator::ABSOLUTE_URL); $this->assertEquals('http://localhost/hello/world', $url); // No cacheability to test; UrlGenerator::generate() doesn't support // collecting cacheability metadata. @@ -408,7 +423,7 @@ public function testAbsoluteURLGenerationUsingInterfaceConstants() { ->method('processOutbound') ->with($this->anything()); - $options = array('absolute' => TRUE, 'fragment' => 'top'); + $options = ['absolute' => TRUE, 'fragment' => 'top']; // Extra parameters should appear in the query string. $this->assertGenerateFromRoute('test_1', ['zoo' => 5], $options, 'http://localhost/hello/world?zoo=5#top', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)->setCacheContexts(['url.site'])); } @@ -417,20 +432,20 @@ public function testAbsoluteURLGenerationUsingInterfaceConstants() { * Confirms that explicitly setting the base_url works with generated routes */ public function testBaseURLGeneration() { - $options = array('base_url' => 'http://www.example.com:8888'); + $options = ['base_url' => 'http://www.example.com:8888']; $this->assertGenerateFromRoute('test_1', [], $options, 'http://www.example.com:8888/hello/world', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); - $options = array('base_url' => 'http://www.example.com:8888', 'https' => TRUE); + $options = ['base_url' => 'http://www.example.com:8888', 'https' => TRUE]; $this->assertGenerateFromRoute('test_1', [], $options, 'https://www.example.com:8888/hello/world', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); - $options = array('base_url' => 'https://www.example.com:8888', 'https' => FALSE); + $options = ['base_url' => 'https://www.example.com:8888', 'https' => FALSE]; $this->assertGenerateFromRoute('test_1', [], $options, 'http://www.example.com:8888/hello/world', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); $this->routeProcessorManager->expects($this->exactly(2)) ->method('processOutbound') ->with($this->anything()); - $options = array('base_url' => 'http://www.example.com:8888', 'fragment' => 'top'); + $options = ['base_url' => 'http://www.example.com:8888', 'fragment' => 'top']; // Extra parameters should appear in the query string. $this->assertGenerateFromRoute('test_1', ['zoo' => 5], $options, 'http://www.example.com:8888/hello/world?zoo=5#top', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); } @@ -439,7 +454,7 @@ public function testBaseURLGeneration() { * Test that the 'scheme' route requirement is respected during url generation. */ public function testUrlGenerationWithHttpsRequirement() { - $url = $this->generator->generate('test_4', array(), TRUE); + $url = $this->generator->generate('test_4', [], TRUE); $this->assertEquals('https://localhost/test/four', $url); // No cacheability to test; UrlGenerator::generate() doesn't support // collecting cacheability metadata. @@ -448,7 +463,7 @@ public function testUrlGenerationWithHttpsRequirement() { ->method('processOutbound') ->with($this->anything()); - $options = array('absolute' => TRUE, 'https' => TRUE); + $options = ['absolute' => TRUE, 'https' => TRUE]; $this->assertGenerateFromRoute('test_1', [], $options, 'https://localhost/hello/world', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)->setCacheContexts(['url.site'])); } @@ -489,6 +504,26 @@ public function providerTestNoPath() { ]; } + /** + * @covers \Drupal\Core\Routing\UrlGenerator::generateFromRoute + * + * Note: We use absolute covers to let + * \Drupal\Tests\Core\Render\MetadataBubblingUrlGeneratorTest work. + */ + public function testGenerateWithPathProcessorChangingQueryParameter() { + $path_processor = $this->getMock(OutboundPathProcessorInterface::CLASS); + $path_processor->expects($this->atLeastOnce()) + ->method('processOutbound') + ->willReturnCallback(function ($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) { + $options['query'] = ['zoo' => 5]; + return $path; + }); + $this->processorManager->addOutbound($path_processor); + + $options = []; + $this->assertGenerateFromRoute('test_2', ['narf' => 5], $options, '/goodbye/cruel/world?zoo=5', (new BubbleableMetadata())->setCacheMaxAge(Cache::PERMANENT)); + } + /** * Asserts \Drupal\Core\Routing\UrlGenerator::generateFromRoute()'s output. * diff --git a/core/tests/Drupal/Tests/Core/Session/AccountProxyTest.php b/core/tests/Drupal/Tests/Core/Session/AccountProxyTest.php new file mode 100644 index 00000000..0e575a07 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Session/AccountProxyTest.php @@ -0,0 +1,53 @@ +assertSame(0, $account_proxy->id()); + $account_proxy->setInitialAccountId(1); + $this->assertFalse(\Drupal::hasContainer()); + // If the following call loaded the user entity it would call + // AccountProxy::loadUserEntity() which would fail because the container + // does not exist. + $this->assertSame(1, $account_proxy->id()); + $current_user = $this->prophesize(AccountInterface::class); + $current_user->id()->willReturn(2); + $account_proxy->setAccount($current_user->reveal()); + $this->assertSame(2, $account_proxy->id()); + } + + /** + * @covers ::setInitialAccountId + */ + public function testSetInitialAccountIdException() { + $this->setExpectedException(\LogicException::class); + $account_proxy = new AccountProxy(); + $current_user = $this->prophesize(AccountInterface::class); + $account_proxy->setAccount($current_user->reveal()); + $account_proxy->setInitialAccountId(1); + } + +} + +namespace Drupal\Core\Session; + +if (!function_exists('drupal_get_user_timezone')) { + function drupal_get_user_timezone() { + return date_default_timezone_get(); + } +} diff --git a/core/tests/Drupal/Tests/Core/Session/AnonymousUserSessionTest.php b/core/tests/Drupal/Tests/Core/Session/AnonymousUserSessionTest.php index 0840e000..031de824 100644 --- a/core/tests/Drupal/Tests/Core/Session/AnonymousUserSessionTest.php +++ b/core/tests/Drupal/Tests/Core/Session/AnonymousUserSessionTest.php @@ -20,8 +20,8 @@ class AnonymousUserSessionTest extends UnitTestCase { */ public function testUserGetRoles() { $anonymous_user = new AnonymousUserSession(); - $this->assertEquals(array(RoleInterface::ANONYMOUS_ID), $anonymous_user->getRoles()); - $this->assertEquals(array(), $anonymous_user->getRoles(TRUE)); + $this->assertEquals([RoleInterface::ANONYMOUS_ID], $anonymous_user->getRoles()); + $this->assertEquals([], $anonymous_user->getRoles(TRUE)); } } diff --git a/core/tests/Drupal/Tests/Core/Session/PermissionsHashGeneratorTest.php b/core/tests/Drupal/Tests/Core/Session/PermissionsHashGeneratorTest.php index d5e8c32d..aa980f8c 100644 --- a/core/tests/Drupal/Tests/Core/Session/PermissionsHashGeneratorTest.php +++ b/core/tests/Drupal/Tests/Core/Session/PermissionsHashGeneratorTest.php @@ -75,12 +75,12 @@ class PermissionsHashGeneratorTest extends UnitTestCase { protected function setUp() { parent::setUp(); - new Settings(array('hash_salt' => 'test')); + new Settings(['hash_salt' => 'test']); // The mocked super user account, with the same roles as Account 2. $this->account1 = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('getRoles', 'id')) + ->setMethods(['getRoles', 'id']) ->getMock(); $this->account1->expects($this->any()) ->method('id') @@ -89,10 +89,10 @@ protected function setUp() { ->method('getRoles'); // Account 2: 'administrator' and 'authenticated' roles. - $roles_1 = array('administrator', 'authenticated'); + $roles_1 = ['administrator', 'authenticated']; $this->account2 = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('getRoles', 'id')) + ->setMethods(['getRoles', 'id']) ->getMock(); $this->account2->expects($this->any()) ->method('getRoles') @@ -102,10 +102,10 @@ protected function setUp() { ->willReturn(2); // Account 3: 'authenticated' and 'administrator' roles (different order). - $roles_3 = array('authenticated', 'administrator'); + $roles_3 = ['authenticated', 'administrator']; $this->account3 = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('getRoles', 'id')) + ->setMethods(['getRoles', 'id']) ->getMock(); $this->account3->expects($this->any()) ->method('getRoles') @@ -115,10 +115,10 @@ protected function setUp() { ->willReturn(3); // Updated account 2: now also 'editor' role. - $roles_2_updated = array('editor', 'administrator', 'authenticated'); + $roles_2_updated = ['editor', 'administrator', 'authenticated']; $this->account2Updated = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() - ->setMethods(array('getRoles', 'id')) + ->setMethods(['getRoles', 'id']) ->getMock(); $this->account2Updated->expects($this->any()) ->method('getRoles') @@ -131,7 +131,7 @@ protected function setUp() { $random = Crypt::randomBytesBase64(55); $this->privateKey = $this->getMockBuilder('Drupal\Core\PrivateKey') ->disableOriginalConstructor() - ->setMethods(array('get')) + ->setMethods(['get']) ->getMock(); $this->privateKey->expects($this->any()) ->method('get') @@ -251,9 +251,9 @@ public function testGenerateNoCache() { // @todo remove once user_role_permissions() can be injected. if (!function_exists('user_role_permissions')) { function user_role_permissions(array $roles) { - $role_permissions = array(); + $role_permissions = []; foreach ($roles as $rid) { - $role_permissions[$rid] = array(); + $role_permissions[$rid] = []; } return $role_permissions; } diff --git a/core/tests/Drupal/Tests/Core/Session/UserSessionTest.php b/core/tests/Drupal/Tests/Core/Session/UserSessionTest.php index 52969e03..85fe1bbf 100644 --- a/core/tests/Drupal/Tests/Core/Session/UserSessionTest.php +++ b/core/tests/Drupal/Tests/Core/Session/UserSessionTest.php @@ -18,7 +18,7 @@ class UserSessionTest extends UnitTestCase { * * @var \Drupal\Core\Session\AccountInterface[] */ - protected $users = array(); + protected $users = []; /** * Provides test data for getHasPermission(). @@ -26,10 +26,10 @@ class UserSessionTest extends UnitTestCase { * @return array */ public function providerTestHasPermission() { - $data = array(); - $data[] = array('example permission', array('user_one', 'user_two'), array('user_last')); - $data[] = array('another example permission', array('user_two'), array('user_one', 'user_last')); - $data[] = array('final example permission', array(), array('user_one', 'user_two', 'user_last')); + $data = []; + $data[] = ['example permission', ['user_one', 'user_two'], ['user_last']]; + $data[] = ['another example permission', ['user_two'], ['user_one', 'user_last']]; + $data[] = ['final example permission', [], ['user_one', 'user_two', 'user_last']]; return $data; } @@ -45,9 +45,9 @@ public function providerTestHasPermission() { * @return \Drupal\Core\Session\AccountInterface * The created user session. */ - protected function createUserSession(array $rids = array(), $authenticated = FALSE) { + protected function createUserSession(array $rids = [], $authenticated = FALSE) { array_unshift($rids, $authenticated ? RoleInterface::AUTHENTICATED_ID : RoleInterface::ANONYMOUS_ID); - return new UserSession(array('roles' => $rids)); + return new UserSession(['roles' => $rids]); } /** @@ -56,57 +56,57 @@ protected function createUserSession(array $rids = array(), $authenticated = FAL protected function setUp() { parent::setUp(); - $roles = array(); + $roles = []; $roles['role_one'] = $this->getMockBuilder('Drupal\user\Entity\Role') ->disableOriginalConstructor() - ->setMethods(array('hasPermission')) + ->setMethods(['hasPermission']) ->getMock(); $roles['role_one']->expects($this->any()) ->method('hasPermission') - ->will($this->returnValueMap(array( - array('example permission', TRUE), - array('another example permission', FALSE), - array('last example permission', FALSE), - ))); + ->will($this->returnValueMap([ + ['example permission', TRUE], + ['another example permission', FALSE], + ['last example permission', FALSE], + ])); $roles['role_two'] = $this->getMockBuilder('Drupal\user\Entity\Role') ->disableOriginalConstructor() - ->setMethods(array('hasPermission')) + ->setMethods(['hasPermission']) ->getMock(); $roles['role_two']->expects($this->any()) ->method('hasPermission') - ->will($this->returnValueMap(array( - array('example permission', TRUE), - array('another example permission', TRUE), - array('last example permission', FALSE), - ))); + ->will($this->returnValueMap([ + ['example permission', TRUE], + ['another example permission', TRUE], + ['last example permission', FALSE], + ])); $roles['anonymous'] = $this->getMockBuilder('Drupal\user\Entity\Role') ->disableOriginalConstructor() - ->setMethods(array('hasPermission')) + ->setMethods(['hasPermission']) ->getMock(); $roles['anonymous']->expects($this->any()) ->method('hasPermission') - ->will($this->returnValueMap(array( - array('example permission', FALSE), - array('another example permission', FALSE), - array('last example permission', FALSE), - ))); + ->will($this->returnValueMap([ + ['example permission', FALSE], + ['another example permission', FALSE], + ['last example permission', FALSE], + ])); $role_storage = $this->getMockBuilder('Drupal\user\RoleStorage') ->disableOriginalConstructor() - ->setMethods(array('loadMultiple')) + ->setMethods(['loadMultiple']) ->getMock(); $role_storage->expects($this->any()) ->method('loadMultiple') - ->will($this->returnValueMap(array( - array(array(), array()), - array(NULL, $roles), - array(array('anonymous'), array($roles['anonymous'])), - array(array('anonymous', 'role_one'), array($roles['role_one'])), - array(array('anonymous', 'role_two'), array($roles['role_two'])), - array(array('anonymous', 'role_one', 'role_two'), array($roles['role_one'], $roles['role_two'])), - ))); + ->will($this->returnValueMap([ + [[], []], + [NULL, $roles], + [['anonymous'], [$roles['anonymous']]], + [['anonymous', 'role_one'], [$roles['role_one']]], + [['anonymous', 'role_two'], [$roles['role_two']]], + [['anonymous', 'role_one', 'role_two'], [$roles['role_one'], $roles['role_two']]], + ])); $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); $entity_manager->expects($this->any()) @@ -117,9 +117,9 @@ protected function setUp() { $container->set('entity.manager', $entity_manager); \Drupal::setContainer($container); - $this->users['user_one'] = $this->createUserSession(array('role_one')); - $this->users['user_two'] = $this->createUserSession(array('role_one', 'role_two')); - $this->users['user_three'] = $this->createUserSession(array('role_two'), TRUE); + $this->users['user_one'] = $this->createUserSession(['role_one']); + $this->users['user_two'] = $this->createUserSession(['role_one', 'role_two']); + $this->users['user_three'] = $this->createUserSession(['role_two'], TRUE); $this->users['user_last'] = $this->createUserSession(); } @@ -153,8 +153,8 @@ public function testHasPermission($permission, array $sessions_with_access, arra * @todo Move roles constants to a class/interface */ public function testUserGetRoles() { - $this->assertEquals(array(RoleInterface::AUTHENTICATED_ID, 'role_two'), $this->users['user_three']->getRoles()); - $this->assertEquals(array('role_two'), $this->users['user_three']->getRoles(TRUE)); + $this->assertEquals([RoleInterface::AUTHENTICATED_ID, 'role_two'], $this->users['user_three']->getRoles()); + $this->assertEquals(['role_two'], $this->users['user_three']->getRoles(TRUE)); } } diff --git a/core/tests/Drupal/Tests/Core/Site/SettingsTest.php b/core/tests/Drupal/Tests/Core/Site/SettingsTest.php index 3cf50fc2..4d34b306 100644 --- a/core/tests/Drupal/Tests/Core/Site/SettingsTest.php +++ b/core/tests/Drupal/Tests/Core/Site/SettingsTest.php @@ -16,7 +16,7 @@ class SettingsTest extends UnitTestCase { * * @var array */ - protected $config = array(); + protected $config = []; /** * The class under test. @@ -29,11 +29,11 @@ class SettingsTest extends UnitTestCase { * @covers ::__construct */ protected function setUp(){ - $this->config = array( + $this->config = [ 'one' => '1', 'two' => '2', 'hash_salt' => $this->randomMachineName(), - ); + ]; $this->settings = new Settings($this->config); } @@ -80,12 +80,11 @@ public function testGetHashSalt() { * @covers ::getHashSalt * * @dataProvider providerTestGetHashSaltEmpty - * - * @expectedException \RuntimeException */ public function testGetHashSaltEmpty(array $config) { // Re-create settings with no 'hash_salt' key. $settings = new Settings($config); + $this->setExpectedException(\RuntimeException::class); $settings->getHashSalt(); } @@ -95,21 +94,20 @@ public function testGetHashSaltEmpty(array $config) { * @return array */ public function providerTestGetHashSaltEmpty() { - return array( - array(array()), - array(array('hash_salt' => '')), - array(array('hash_salt' => NULL)), - ); + return [ + [[]], + [['hash_salt' => '']], + [['hash_salt' => NULL]], + ]; } /** * Ensures settings cannot be serialized. * * @covers ::__sleep - * - * @expectedException \LogicException */ public function testSerialize() { + $this->setExpectedException(\LogicException::class); serialize(new Settings([])); } @@ -119,11 +117,28 @@ public function testSerialize() { * @covers ::getApcuPrefix */ public function testGetApcuPrefix() { - $settings = new Settings(array('hash_salt' => 123)); + $settings = new Settings(['hash_salt' => 123]); $this->assertNotEquals($settings::getApcuPrefix('cache_test', '/test/a'), $settings::getApcuPrefix('cache_test', '/test/b')); - $settings = new Settings(array('hash_salt' => 123, 'apcu_ensure_unique_prefix' => FALSE)); + $settings = new Settings(['hash_salt' => 123, 'apcu_ensure_unique_prefix' => FALSE]); $this->assertNotEquals($settings::getApcuPrefix('cache_test', '/test/a'), $settings::getApcuPrefix('cache_test', '/test/b')); } + /** + * Tests that an exception is thrown when settings are not initialized yet. + * + * @covers ::getInstance + */ + public function testGetInstanceReflection() { + $settings = new Settings([]); + + $class = new \ReflectionClass(Settings::class); + $instace_property = $class->getProperty("instance"); + $instace_property->setAccessible(TRUE); + $instace_property->setValue(NULL); + + $this->setExpectedException(\BadMethodCallException::class); + $settings->getInstance(); + } + } diff --git a/core/tests/Drupal/Tests/Core/StackMiddleware/NegotiationMiddlewareTest.php b/core/tests/Drupal/Tests/Core/StackMiddleware/NegotiationMiddlewareTest.php index 0f5142c9..7b3a0d45 100644 --- a/core/tests/Drupal/Tests/Core/StackMiddleware/NegotiationMiddlewareTest.php +++ b/core/tests/Drupal/Tests/Core/StackMiddleware/NegotiationMiddlewareTest.php @@ -142,6 +142,8 @@ public function testSetFormat() { } class StubNegotiationMiddleware extends NegotiationMiddleware { - public function getContentType(Request $request) { return parent::getContentType($request); } + public function getContentType(Request $request) { + return parent::getContentType($request); + } } diff --git a/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php b/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php index 585c4b97..b7a784d4 100644 --- a/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php +++ b/core/tests/Drupal/Tests/Core/StackMiddleware/ReverseProxyMiddlewareTest.php @@ -30,12 +30,12 @@ protected function setUp() { * Tests that subscriber does not act when reverse proxy is not set. */ public function testNoProxy() { - $settings = new Settings(array()); + $settings = new Settings([]); $this->assertEquals(0, $settings->get('reverse_proxy')); $middleware = new ReverseProxyMiddleware($this->mockHttpKernel, $settings); // Mock a request object. - $request = $this->getMock('Symfony\Component\HttpFoundation\Request', array('setTrustedHeaderName', 'setTrustedProxies')); + $request = $this->getMock('Symfony\Component\HttpFoundation\Request', ['setTrustedHeaderName', 'setTrustedProxies']); // setTrustedHeaderName() should never fire. $request->expects($this->never()) ->method('setTrustedHeaderName'); @@ -50,7 +50,7 @@ public function testNoProxy() { */ public function testReverseProxyEnabled($provided_settings) { // Enable reverse proxy and add test values. - $settings = new Settings(array('reverse_proxy' => 1) + $provided_settings); + $settings = new Settings(['reverse_proxy' => 1] + $provided_settings); $this->trustedHeadersAreSet($settings); } @@ -58,18 +58,18 @@ public function testReverseProxyEnabled($provided_settings) { * Data provider for testReverseProxyEnabled. */ public function reverseProxyEnabledProvider() { - return array( - array( - array( + return [ + [ + [ 'reverse_proxy_header' => 'X_FORWARDED_FOR_CUSTOMIZED', 'reverse_proxy_proto_header' => 'X_FORWARDED_PROTO_CUSTOMIZED', 'reverse_proxy_host_header' => 'X_FORWARDED_HOST_CUSTOMIZED', 'reverse_proxy_port_header' => 'X_FORWARDED_PORT_CUSTOMIZED', 'reverse_proxy_forwarded_header' => 'FORWARDED_CUSTOMIZED', - 'reverse_proxy_addresses' => array('127.0.0.2', '127.0.0.3'), - ), - ), - ); + 'reverse_proxy_addresses' => ['127.0.0.2', '127.0.0.3'], + ], + ], + ]; } /** diff --git a/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php b/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php index 3ed2b3de..e48c6103 100644 --- a/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php +++ b/core/tests/Drupal/Tests/Core/StringTranslation/TranslatableMarkupTest.php @@ -82,25 +82,20 @@ public function testToString() { } /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage $string ("foo") must be a string. - * * @covers ::__construct */ public function testIsStringAssertion() { $translation = $this->getStringTranslationStub(); + $this->setExpectedException(\InvalidArgumentException::class, '$string ("foo") must be a string.'); new TranslatableMarkup(new TranslatableMarkup('foo', [], [], $translation)); } /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage $string ("foo") must be a string. - * * @covers ::__construct */ public function testIsStringAssertionWithFormattableMarkup() { - $translation = $this->getStringTranslationStub(); $formattable_string = new FormattableMarkup('@bar', ['@bar' => 'foo']); + $this->setExpectedException(\InvalidArgumentException::class, '$string ("foo") must be a string.'); new TranslatableMarkup($formattable_string); } diff --git a/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php b/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php index 8ab6874e..53a92414 100644 --- a/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php +++ b/core/tests/Drupal/Tests/Core/StringTranslation/TranslationManagerTest.php @@ -36,21 +36,21 @@ protected function setUp() { * @return array */ public function providerTestFormatPlural() { - return array( - [1, 'Singular', '@count plural', array(), array(), 'Singular'], - [2, 'Singular', '@count plural', array(), array(), '2 plural'], + return [ + [1, 'Singular', '@count plural', [], [], 'Singular'], + [2, 'Singular', '@count plural', [], [], '2 plural'], // @todo support locale_get_plural - [2, 'Singular', '@count @arg', array('@arg' => '"); - $this->assertSame('<script>alert('here');</script>', $twig_extension->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE)); + $this->assertSame('<script>alert('here');</script>', $this->systemUnderTest->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE)); } /** * @covers ::safeJoin */ public function testSafeJoin() { - $renderer = $this->prophesize(RendererInterface::class); - $renderer->render(['#markup' => 'will be rendered', '#printed' => FALSE])->willReturn('will be rendered'); - $renderer = $renderer->reveal(); + $this->renderer->expects($this->any()) + ->method('render') + ->with(['#markup' => 'will be rendered', '#printed' => FALSE]) + ->willReturn('will be rendered'); - $twig_extension = new TwigExtension($renderer); $twig_environment = $this->prophesize(TwigEnvironment::class)->reveal(); // Simulate t(). @@ -198,9 +228,9 @@ public function testSafeJoin() { $items = [ 'will be escaped', $markup, - ['#markup' => 'will be rendered'] + ['#markup' => 'will be rendered'], ]; - $result = $twig_extension->safeJoin($twig_environment, $items, '
    '); + $result = $this->systemUnderTest->safeJoin($twig_environment, $items, '
    '); $this->assertEquals('<em>will be escaped</em>
    will be markup
    will be rendered', $result); // Ensure safe_join Twig filter supports Traversable variables. @@ -209,12 +239,12 @@ public function testSafeJoin() { $markup, ['#markup' => 'will be rendered'], ]); - $result = $twig_extension->safeJoin($twig_environment, $items, ', '); + $result = $this->systemUnderTest->safeJoin($twig_environment, $items, ', '); $this->assertEquals('<em>will be escaped</em>, will be markup, will be rendered', $result); // Ensure safe_join Twig filter supports empty variables. $items = NULL; - $result = $twig_extension->safeJoin($twig_environment, $items, '
    '); + $result = $this->systemUnderTest->safeJoin($twig_environment, $items, '
    '); $this->assertEmpty($result); } @@ -222,13 +252,12 @@ public function testSafeJoin() { * @dataProvider providerTestRenderVar */ public function testRenderVar($result, $input) { - $renderer = $this->prophesize(RendererInterface::class); - $renderer->render($result += ['#printed' => FALSE])->willReturn('Rendered output'); - - $renderer = $renderer->reveal(); - $twig_extension = new TwigExtension($renderer); + $this->renderer->expects($this->any()) + ->method('render') + ->with($result += ['#printed' => FALSE]) + ->willReturn('Rendered output'); - $this->assertEquals('Rendered output', $twig_extension->renderVar($input)); + $this->assertEquals('Rendered output', $this->systemUnderTest->renderVar($input)); } public function providerTestRenderVar() { @@ -245,9 +274,10 @@ public function providerTestRenderVar() { /** * @covers ::escapeFilter * @covers ::bubbleArgMetadata + * + * @group legacy */ public function testEscapeWithGeneratedLink() { - $renderer = $this->prophesize(RendererInterface::class); $twig = new \Twig_Environment(NULL, [ 'debug' => TRUE, 'cache' => FALSE, @@ -256,22 +286,23 @@ public function testEscapeWithGeneratedLink() { ] ); - $twig_extension = new TwigExtension($renderer->reveal()); - $twig->addExtension($twig_extension->setUrlGenerator($this->prophesize(UrlGeneratorInterface::class)->reveal())); + $twig->addExtension($this->systemUnderTest); $link = new GeneratedLink(); $link->setGeneratedLink(''); $link->addCacheTags(['foo']); $link->addAttachments(['library' => ['system/base']]); - $result = $twig_extension->escapeFilter($twig, $link, 'html', NULL, TRUE); - $renderer->render([ - "#cache" => [ - "contexts" => [], - "tags" => ["foo"], - "max-age" => -1 - ], - "#attached" => ['library' => ['system/base']], - ])->shouldHaveBeenCalled(); + $this->renderer->expects($this->atLeastOnce()) + ->method('render') + ->with([ + "#cache" => [ + "contexts" => [], + "tags" => ["foo"], + "max-age" => -1, + ], + "#attached" => ['library' => ['system/base']], + ]); + $result = $this->systemUnderTest->escapeFilter($twig, $link, 'html', NULL, TRUE); $this->assertEquals('', $result); } @@ -280,25 +311,61 @@ public function testEscapeWithGeneratedLink() { * @covers ::bubbleArgMetadata */ public function testRenderVarWithGeneratedLink() { - $renderer = $this->prophesize(RendererInterface::class); - $twig_extension = new TwigExtension($renderer->reveal()); $link = new GeneratedLink(); $link->setGeneratedLink(''); $link->addCacheTags(['foo']); $link->addAttachments(['library' => ['system/base']]); - $result = $twig_extension->renderVar($link); - $renderer->render([ - "#cache" => [ - "contexts" => [], - "tags" => ["foo"], - "max-age" => -1 - ], - "#attached" => ['library' => ['system/base']], - ])->shouldHaveBeenCalled(); + $this->renderer->expects($this->atLeastOnce()) + ->method('render') + ->with([ + "#cache" => [ + "contexts" => [], + "tags" => ["foo"], + "max-age" => -1, + ], + "#attached" => ['library' => ['system/base']], + ]); + $result = $this->systemUnderTest->renderVar($link); $this->assertEquals('', $result); } + /** + * Tests creating attributes within a Twig template. + * + * @covers ::createAttribute + */ + public function testCreateAttribute() { + $loader = new StringLoader(); + $twig = new \Twig_Environment($loader); + $twig->addExtension($this->systemUnderTest); + + $iterations = [ + ['class' => ['kittens'], 'data-toggle' => 'modal', 'data-lang' => 'es'], + ['id' => 'puppies', 'data-value' => 'foo', 'data-lang' => 'en'], + [], + ]; + $result = $twig->render("{% for iteration in iterations %}{% endfor %}", ['iterations' => $iterations]); + $expected = '
    '; + $this->assertEquals($expected, $result); + + // Test default creation of empty attribute object and using its method. + $result = $twig->render(""); + $expected = '
    '; + $this->assertEquals($expected, $result); + } + + /** + * @covers ::getLink + */ + public function testLinkWithOverriddenAttributes() { + $url = Url::fromRoute('', [], ['attributes' => ['class' => ['foo']]]); + + $build = $this->systemUnderTest->getLink('test', $url, ['class' => ['bar']]); + + $this->assertEquals(['foo', 'bar'], $build['#url']->getOption('attributes')['class']); + } + } class TwigExtensionTestString { diff --git a/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php b/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php index 7a3dd3ae..cf39a8bb 100644 --- a/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php +++ b/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php @@ -16,6 +16,7 @@ * Tests the twig sandbox policy. * * @group Template + * @group legacy * * @coversDefaultClass \Drupal\Core\Template\TwigSandboxPolicy */ @@ -45,10 +46,10 @@ protected function setUp() { * Tests that dangerous methods cannot be called in entity objects. * * @dataProvider getTwigEntityDangerousMethods - * @expectedException \Twig_Sandbox_SecurityError */ public function testEntityDangerousMethods($template) { $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $this->setExpectedException(\Twig_Sandbox_SecurityError::class); $this->twig->render($template, ['entity' => $entity]); } @@ -84,14 +85,14 @@ public function testEntitySafePrefixes() { ->with('test') ->willReturn(TRUE); $result = $this->twig->render('{{ entity.hasLinkTemplate("test") }}', ['entity' => $entity]); - $this->assertTrue((bool)$result, 'Sandbox policy allows has* functions to be called.'); + $this->assertTrue((bool) $result, 'Sandbox policy allows has* functions to be called.'); $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); $entity->expects($this->atLeastOnce()) ->method('isNew') ->willReturn(TRUE); $result = $this->twig->render('{{ entity.isNew }}', ['entity' => $entity]); - $this->assertTrue((bool)$result, 'Sandbox policy allows is* functions to be called.'); + $this->assertTrue((bool) $result, 'Sandbox policy allows is* functions to be called.'); $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); $entity->expects($this->atLeastOnce()) diff --git a/core/tests/Drupal/Tests/Core/Test/KernelTestBaseTest.php b/core/tests/Drupal/Tests/Core/Test/KernelTestBaseTest.php new file mode 100644 index 00000000..837db3ab --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Test/KernelTestBaseTest.php @@ -0,0 +1,34 @@ +getMockBuilder(KernelTestBase::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $is_isolated = new \ReflectionMethod($kernel_test, 'isTestInIsolation'); + $is_isolated->setAccessible(TRUE); + + // Assert that the return value is a bool, because this unit test might or + // might not be running in process isolation. + $this->assertInternalType('bool', $is_isolated->invoke($kernel_test)); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php index 1243118f..f2cd22ea 100644 --- a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php @@ -66,6 +66,13 @@ class RegistryTest extends UnitTestCase { */ protected $themeManager; + /** + * The list of functions that get_defined_functions() should provide. + * + * @var array + */ + public static $functions = []; + /** * {@inheritdoc} */ @@ -82,6 +89,14 @@ protected function setUp() { $this->setupTheme(); } + /** + * {@inheritdoc} + */ + protected function tearDown() { + parent::tearDown(); + static::$functions = []; + } + /** * Tests getting the theme registry defined by a module. */ @@ -122,7 +137,7 @@ public function testGetRegistryForModule() { $this->moduleHandler->expects($this->exactly(2)) ->method('getImplementations') ->with('theme') - ->will($this->returnValue(array('theme_test'))); + ->will($this->returnValue(['theme_test'])); $this->moduleHandler->expects($this->atLeastOnce()) ->method('getModuleList') ->willReturn([]); @@ -149,7 +164,7 @@ public function testGetRegistryForModule() { $this->assertEquals('module', $info['type']); $this->assertEquals('core/modules/system/tests/modules/theme_test', $info['theme path']); $this->assertEquals('theme_theme_test_function_suggestions', $info['function']); - $this->assertEquals(array(), $info['variables']); + $this->assertEquals([], $info['variables']); // The second call will initialize with the second theme. Ensure that this // returns a different object and the discovery for the second theme's @@ -159,6 +174,317 @@ public function testGetRegistryForModule() { $this->assertTrue(in_array('test_stable_preprocess_theme_test_render_element', $other_registry['theme_test_render_element']['preprocess functions'])); } + /** + * @covers ::postProcessExtension + * @covers ::completeSuggestion + * @covers ::mergePreprocessFunctions + * + * @dataProvider providerTestPostProcessExtension + * + * @param array $defined_functions + * An array of functions to be used in place of get_defined_functions(). + * @param array $hooks + * An array of theme hooks to process. + * @param array $expected + * The expected results. + */ + public function testPostProcessExtension($defined_functions, $hooks, $expected) { + static::$functions['user'] = $defined_functions; + + $theme = $this->prophesize(ActiveTheme::class); + $theme->getBaseThemes()->willReturn([]); + $theme->getName()->willReturn('test'); + $theme->getEngine()->willReturn('twig'); + + $this->moduleHandler->expects($this->atLeastOnce()) + ->method('getModuleList') + ->willReturn([]); + + $class = new \ReflectionClass(TestRegistry::class); + $reflection_method = $class->getMethod('postProcessExtension'); + $reflection_method->setAccessible(TRUE); + $reflection_method->invokeArgs($this->registry, [&$hooks, $theme->reveal()]); + + $this->assertArrayEquals($expected, $hooks); + } + + /** + * Provides test data to ::testPostProcessExtension(). + */ + public function providerTestPostProcessExtension() { + // This is test data for unit testing + // \Drupal\Core\Theme\Registry::postProcessExtension(), not what happens + // before it. Therefore, for all test data: + // - Explicitly defined hooks also come with explicitly defined preprocess + // functions, because those are collected in + // \Drupal\Core\Theme\Registry::processExtension(). + // - Explicitly defined hooks that set a 'base hook' also have + // 'incomplete preprocess functions' set to TRUE, since that is done in + // \Drupal\Core\Theme\Registry::processExtension(). + $data = []; + + // Test the discovery of suggestions via the presence of preprocess + // functions that follow the "__" naming pattern. + $data['base_hook_with_autodiscovered_suggestions'] = [ + 'defined_functions' => [ + 'test_preprocess_test_hook__suggestion', + 'test_preprocess_test_hook__suggestion__another', + ], + 'hooks' => [ + 'test_hook' => [ + 'preprocess functions' => ['explicit_preprocess_test_hook'], + ], + ], + 'expected' => [ + 'test_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + ], + ], + 'test_hook__suggestion' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'test_preprocess_test_hook__suggestion', + ], + 'base hook' => 'test_hook', + ], + 'test_hook__suggestion__another' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'test_preprocess_test_hook__suggestion', + 'test_preprocess_test_hook__suggestion__another', + ], + 'base hook' => 'test_hook', + ], + ], + ]; + + // Test that suggestions following the "__" naming pattern can also be + // explicitly defined in hook_theme(), such as 'field__node__title' defined + // in node_theme(). + $data['base_hook_with_explicit_suggestions'] = [ + 'defined_functions' => [], + 'hooks' => [ + 'test_hook' => [ + 'preprocess functions' => ['explicit_preprocess_test_hook'], + ], + 'test_hook__suggestion__another' => [ + 'base hook' => 'test_hook', + 'preprocess functions' => ['explicit_preprocess_test_hook__suggestion__another'], + 'incomplete preprocess functions' => TRUE, + ], + ], + 'expected' => [ + 'test_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + ], + ], + 'test_hook__suggestion__another' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'explicit_preprocess_test_hook__suggestion__another', + ], + 'base hook' => 'test_hook', + ], + ], + ]; + + // Same as above, but also test that a preprocess function for an + // intermediary suggestion level gets discovered. + $data['base_hook_with_explicit_suggestions_and_intermediary_preprocess_function'] = [ + 'defined_functions' => [ + 'test_preprocess_test_hook__suggestion', + ], + 'hooks' => [ + 'test_hook' => [ + 'preprocess functions' => ['explicit_preprocess_test_hook'], + ], + 'test_hook__suggestion__another' => [ + 'base hook' => 'test_hook', + 'preprocess functions' => ['explicit_preprocess_test_hook__suggestion__another'], + 'incomplete preprocess functions' => TRUE, + ], + ], + 'expected' => [ + 'test_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + ], + ], + 'test_hook__suggestion' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'test_preprocess_test_hook__suggestion', + ], + 'base hook' => 'test_hook', + ], + 'test_hook__suggestion__another' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'test_preprocess_test_hook__suggestion', + 'explicit_preprocess_test_hook__suggestion__another', + ], + 'base hook' => 'test_hook', + ], + ], + ]; + + // Test that hooks not following the "__" naming pattern can explicitly + // specify a base hook, such as is done in + // \Drupal\Core\Layout\LayoutPluginManager::getThemeImplementations(). + $data['child_hook_without_magic_naming'] = [ + 'defined_functions' => [], + 'hooks' => [ + 'test_hook' => [ + 'preprocess functions' => ['explicit_preprocess_test_hook'], + ], + 'child_hook' => [ + 'base hook' => 'test_hook', + 'preprocess functions' => ['explicit_preprocess_child_hook'], + 'incomplete preprocess functions' => TRUE, + ], + ], + 'expected' => [ + 'test_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + ], + ], + 'child_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'explicit_preprocess_child_hook', + ], + 'base hook' => 'test_hook', + ], + ], + ]; + + // Same as above, but also test that such child hooks can also be extended + // with magically named suggestions. + $data['child_hook_with_suggestions'] = [ + 'defined_functions' => [ + 'test_preprocess_child_hook__suggestion', + 'test_preprocess_child_hook__suggestion__another', + ], + 'hooks' => [ + 'test_hook' => [ + 'preprocess functions' => ['explicit_preprocess_test_hook'], + ], + 'child_hook' => [ + 'base hook' => 'test_hook', + 'preprocess functions' => ['explicit_preprocess_child_hook'], + 'incomplete preprocess functions' => TRUE, + ], + ], + 'expected' => [ + 'test_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + ], + ], + 'child_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'explicit_preprocess_child_hook', + ], + 'base hook' => 'test_hook', + ], + 'child_hook__suggestion' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'explicit_preprocess_child_hook', + 'test_preprocess_child_hook__suggestion', + ], + 'base hook' => 'test_hook', + ], + 'child_hook__suggestion__another' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'explicit_preprocess_child_hook', + 'test_preprocess_child_hook__suggestion', + 'test_preprocess_child_hook__suggestion__another', + ], + 'base hook' => 'test_hook', + ], + ], + ]; + + // Test that a suggestion following the "__" naming pattern can specify a + // different base hook than what is implied by that pattern. Ensure that + // preprocess functions from both the naming pattern and from 'base hook' + // are collected. + $data['suggestion_with_alternate_base_hook'] = [ + 'defined_functions' => [ + 'test_preprocess_test_hook__suggestion', + ], + 'hooks' => [ + 'test_hook' => [ + 'preprocess functions' => ['explicit_preprocess_test_hook'], + ], + 'alternate_base_hook' => [ + 'preprocess functions' => ['explicit_preprocess_alternate_base_hook'], + ], + 'test_hook__suggestion__another' => [ + 'base hook' => 'alternate_base_hook', + 'preprocess functions' => ['explicit_preprocess_test_hook__suggestion__another'], + 'incomplete preprocess functions' => TRUE, + ], + ], + 'expected' => [ + 'test_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + ], + ], + 'alternate_base_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_alternate_base_hook', + ], + ], + 'test_hook__suggestion' => [ + 'preprocess functions' => [ + 'explicit_preprocess_test_hook', + 'test_preprocess_test_hook__suggestion', + ], + 'base hook' => 'test_hook', + ], + 'test_hook__suggestion__another' => [ + 'preprocess functions' => [ + 'explicit_preprocess_alternate_base_hook', + 'explicit_preprocess_test_hook', + 'test_preprocess_test_hook__suggestion', + 'explicit_preprocess_test_hook__suggestion__another', + ], + 'base hook' => 'alternate_base_hook', + ], + ], + ]; + + // Test when a base hook is missing. + $data['missing_base_hook'] = [ + 'defined_functions' => [], + 'hooks' => [ + 'child_hook' => [ + 'base hook' => 'test_hook', + 'preprocess functions' => ['explicit_preprocess_child_hook'], + 'incomplete preprocess functions' => TRUE, + ], + ], + 'expected' => [ + 'child_hook' => [ + 'preprocess functions' => [ + 'explicit_preprocess_child_hook', + ], + 'base hook' => 'test_hook', + ], + ], + ]; + + return $data; + } + protected function setupTheme() { $this->registry = new TestRegistry($this->root, $this->cache, $this->lock, $this->moduleHandler, $this->themeHandler, $this->themeInitialization); $this->registry->setThemeManager($this->themeManager); @@ -175,3 +501,14 @@ protected function getPath($module) { } } + +namespace Drupal\Core\Theme; + +use Drupal\Tests\Core\Theme\RegistryTest; + +/** + * Overrides get_defined_functions() with a configurable mock. + */ +function get_defined_functions() { + return RegistryTest::$functions ?: \get_defined_functions(); +} diff --git a/core/tests/Drupal/Tests/Core/Theme/ThemeNegotiatorTest.php b/core/tests/Drupal/Tests/Core/Theme/ThemeNegotiatorTest.php index 958a5454..1e2303d7 100644 --- a/core/tests/Drupal/Tests/Core/Theme/ThemeNegotiatorTest.php +++ b/core/tests/Drupal/Tests/Core/Theme/ThemeNegotiatorTest.php @@ -2,6 +2,8 @@ namespace Drupal\Tests\Core\Theme; +use Drupal\Core\DependencyInjection\ClassResolver; +use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Theme\ThemeNegotiator; use Drupal\Tests\UnitTestCase; @@ -20,6 +22,13 @@ class ThemeNegotiatorTest extends UnitTestCase { */ protected $themeAccessCheck; + /** + * The container builder. + * + * @var \Drupal\Core\DependencyInjection\ContainerBuilder + */ + protected $container; + /** * The request stack. * @@ -34,11 +43,14 @@ class ThemeNegotiatorTest extends UnitTestCase { */ protected $themeNegotiator; + /** + * {@inheritdoc} + */ protected function setUp() { $this->themeAccessCheck = $this->getMockBuilder('\Drupal\Core\Theme\ThemeAccessCheck') ->disableOriginalConstructor() ->getMock(); - $this->themeNegotiator = new ThemeNegotiator($this->themeAccessCheck); + $this->container = new ContainerBuilder(); } /** @@ -55,14 +67,16 @@ public function testDetermineActiveTheme() { ->method('applies') ->will($this->returnValue(TRUE)); - $this->themeNegotiator->addNegotiator($negotiator, 0); + $this->container->set('test_negotiator', $negotiator); + + $negotiators = ['test_negotiator']; $this->themeAccessCheck->expects($this->any()) ->method('checkAccess') ->will($this->returnValue(TRUE)); - $route_match = new RouteMatch('test_route', new Route('/test-route'), array(), array()); - $theme = $this->themeNegotiator->determineActiveTheme($route_match); + $route_match = new RouteMatch('test_route', new Route('/test-route'), [], []); + $theme = $this->createThemeNegotiator($negotiators)->determineActiveTheme($route_match); $this->assertEquals('example_test', $theme); } @@ -73,6 +87,8 @@ public function testDetermineActiveTheme() { * @see \Drupal\Core\Theme\ThemeNegotiator::determineActiveTheme() */ public function testDetermineActiveThemeWithPriority() { + $negotiators = []; + $negotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface'); $negotiator->expects($this->once()) ->method('determineActiveTheme') @@ -81,7 +97,7 @@ public function testDetermineActiveThemeWithPriority() { ->method('applies') ->will($this->returnValue(TRUE)); - $this->themeNegotiator->addNegotiator($negotiator, 10); + $negotiators['test_negotiator_1'] = $negotiator; $negotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface'); $negotiator->expects($this->never()) @@ -89,14 +105,18 @@ public function testDetermineActiveThemeWithPriority() { $negotiator->expects($this->never()) ->method('applies'); - $this->themeNegotiator->addNegotiator($negotiator, 0); + $negotiators['test_negotiator_2'] = $negotiator; + + foreach ($negotiators as $id => $negotiator) { + $this->container->set($id, $negotiator); + } $this->themeAccessCheck->expects($this->any()) ->method('checkAccess') ->will($this->returnValue(TRUE)); - $route_match = new RouteMatch('test_route', new Route('/test-route'), array(), array()); - $theme = $this->themeNegotiator->determineActiveTheme($route_match); + $route_match = new RouteMatch('test_route', new Route('/test-route'), [], []); + $theme = $this->createThemeNegotiator(array_keys($negotiators))->determineActiveTheme($route_match); $this->assertEquals('example_test', $theme); } @@ -107,6 +127,8 @@ public function testDetermineActiveThemeWithPriority() { * @see \Drupal\Core\Theme\ThemeNegotiator::determineActiveTheme() */ public function testDetermineActiveThemeWithAccessCheck() { + $negotiators = []; + $negotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface'); $negotiator->expects($this->once()) ->method('determineActiveTheme') @@ -115,7 +137,7 @@ public function testDetermineActiveThemeWithAccessCheck() { ->method('applies') ->will($this->returnValue(TRUE)); - $this->themeNegotiator->addNegotiator($negotiator, 10); + $negotiators['test_negotiator_1'] = $negotiator; $negotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface'); $negotiator->expects($this->once()) @@ -125,7 +147,11 @@ public function testDetermineActiveThemeWithAccessCheck() { ->method('applies') ->will($this->returnValue(TRUE)); - $this->themeNegotiator->addNegotiator($negotiator, 0); + $negotiators['test_negotiator_2'] = $negotiator; + + foreach ($negotiators as $id => $negotiator) { + $this->container->set($id, $negotiator); + } $this->themeAccessCheck->expects($this->at(0)) ->method('checkAccess') @@ -137,8 +163,8 @@ public function testDetermineActiveThemeWithAccessCheck() { ->with('example_test2') ->will($this->returnValue(TRUE)); - $route_match = new RouteMatch('test_route', new Route('/test-route'), array(), array()); - $theme = $this->themeNegotiator->determineActiveTheme($route_match); + $route_match = new RouteMatch('test_route', new Route('/test-route'), [], []); + $theme = $this->createThemeNegotiator(array_keys($negotiators))->determineActiveTheme($route_match); $this->assertEquals('example_test2', $theme); } @@ -149,6 +175,8 @@ public function testDetermineActiveThemeWithAccessCheck() { * @see \Drupal\Core\Theme\ThemeNegotiatorInterface */ public function testDetermineActiveThemeWithNotApplyingNegotiator() { + $negotiators = []; + $negotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface'); $negotiator->expects($this->never()) ->method('determineActiveTheme'); @@ -156,7 +184,7 @@ public function testDetermineActiveThemeWithNotApplyingNegotiator() { ->method('applies') ->will($this->returnValue(FALSE)); - $this->themeNegotiator->addNegotiator($negotiator, 10); + $negotiators['test_negotiator_1'] = $negotiator; $negotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface'); $negotiator->expects($this->once()) @@ -166,16 +194,35 @@ public function testDetermineActiveThemeWithNotApplyingNegotiator() { ->method('applies') ->will($this->returnValue(TRUE)); - $this->themeNegotiator->addNegotiator($negotiator, 0); + $negotiators['test_negotiator_2'] = $negotiator; + + foreach ($negotiators as $id => $negotiator) { + $this->container->set($id, $negotiator); + } $this->themeAccessCheck->expects($this->any()) ->method('checkAccess') ->will($this->returnValue(TRUE)); - $route_match = new RouteMatch('test_route', new Route('/test-route'), array(), array()); - $theme = $this->themeNegotiator->determineActiveTheme($route_match); + $route_match = new RouteMatch('test_route', new Route('/test-route'), [], []); + $theme = $this->createThemeNegotiator(array_keys($negotiators))->determineActiveTheme($route_match); $this->assertEquals('example_test2', $theme); } + /** + * Creates a new theme negotiator instance. + * + * @param array $negotiators + * An array of negotiator IDs. + * + * @return \Drupal\Core\Theme\ThemeNegotiator + */ + protected function createThemeNegotiator(array $negotiators) { + $resolver = new ClassResolver(); + $resolver->setContainer($this->container); + $theme_negotiator = new ThemeNegotiator($this->themeAccessCheck, $resolver, $negotiators); + return $theme_negotiator; + } + } diff --git a/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php b/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php index 0a3388f1..6ff00ec8 100644 --- a/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php +++ b/core/tests/Drupal/Tests/Core/Transliteration/PhpTransliterationTest.php @@ -40,7 +40,7 @@ public function testPhpTransliterationWithAlter($langcode, $original, $expected, $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $module_handler->expects($this->any()) ->method('alter') - ->will($this->returnCallback(function($hook, &$overrides, $langcode) { + ->will($this->returnCallback(function ($hook, &$overrides, $langcode) { if ($langcode == 'zz') { // The default transliteration of Ä is A, but change it to Z for testing. $overrides[0xC4] = 'Z'; @@ -74,13 +74,13 @@ public function providerTestPhpTransliterationWithAlter() { // Five-byte characters do not work in MySQL, so make a printable version. $five_byte_printable = '𐌰𐌸'; - $cases = array( + $cases = [ // Test the language override hook in the test module, which changes // the transliteration of Ä to Z and provides for the 5-byte characters. - array('zz', $two_byte, 'Z O U A O aouaohello'), - array('zz', $random, $random), - array('zz', $five_byte, 'ATh', $five_byte_printable), - ); + ['zz', $two_byte, 'Z O U A O aouaohello'], + ['zz', $random, $random], + ['zz', $five_byte, 'ATh', $five_byte_printable], + ]; return $cases; } diff --git a/core/tests/Drupal/Tests/Core/TypedData/RecursiveContextualValidatorTest.php b/core/tests/Drupal/Tests/Core/TypedData/RecursiveContextualValidatorTest.php index 5e3558e1..9ba110f1 100644 --- a/core/tests/Drupal/Tests/Core/TypedData/RecursiveContextualValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/TypedData/RecursiveContextualValidatorTest.php @@ -83,7 +83,7 @@ protected function setUp() { $translator = $this->getMock('Drupal\Core\Validation\TranslatorInterface'); $translator->expects($this->any()) ->method('trans') - ->willReturnCallback(function($id) { + ->willReturnCallback(function ($id) { return $id; }); $this->contextFactory = new ExecutionContextFactory($translator); @@ -95,10 +95,9 @@ protected function setUp() { * Ensures that passing an explicit group is not supported. * * @covers ::validate - * - * @expectedException \LogicException */ public function testValidateWithGroups() { + $this->setExpectedException(\LogicException::class); $this->recursiveValidator->validate('test', NULL, 'test group'); } @@ -106,10 +105,9 @@ public function testValidateWithGroups() { * Ensures that passing a non typed data value is not supported. * * @covers ::validate - * - * @expectedException \InvalidArgumentException */ public function testValidateWithoutTypedData() { + $this->setExpectedException(\InvalidArgumentException::class); $this->recursiveValidator->validate('test'); } @@ -228,8 +226,6 @@ protected function setupTypedData(array $tree, $name = '') { /** * @covers ::validateProperty - * - * @expectedException \LogicException */ public function testValidatePropertyWithCustomGroup() { $tree = [ @@ -239,6 +235,7 @@ public function testValidatePropertyWithCustomGroup() { ], ]; $typed_data = $this->setupTypedData($tree, 'test_name'); + $this->setExpectedException(\LogicException::class); $this->recursiveValidator->validateProperty($typed_data, 'key1', 'test group'); } @@ -246,10 +243,9 @@ public function testValidatePropertyWithCustomGroup() { * @covers ::validateProperty * * @dataProvider providerTestValidatePropertyWithInvalidObjects - * - * @expectedException \InvalidArgumentException */ public function testValidatePropertyWithInvalidObjects($object) { + $this->setExpectedException(\InvalidArgumentException::class); $this->recursiveValidator->validateProperty($object, 'key1', NULL); } @@ -289,10 +285,9 @@ public function testValidateProperty() { * @covers ::validatePropertyValue * * @dataProvider providerTestValidatePropertyWithInvalidObjects - * - * @expectedException \InvalidArgumentException */ public function testValidatePropertyValueWithInvalidObjects($object) { + $this->setExpectedException(\InvalidArgumentException::class); $this->recursiveValidator->validatePropertyValue($object, 'key1', [], NULL); } diff --git a/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php b/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php index ef6dd252..680e2fde 100644 --- a/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php +++ b/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php @@ -102,9 +102,9 @@ public function providerFromUri() { * * @covers ::fromUri * @dataProvider providerFromInvalidUri - * @expectedException \InvalidArgumentException */ public function testFromInvalidUri($uri) { + $this->setExpectedException(\InvalidArgumentException::class); $url = Url::fromUri($uri); } @@ -133,8 +133,6 @@ public function providerFromInvalidUri() { * Tests the createFromRequest method. * * @covers ::createFromRequest - * - * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ public function testCreateFromRequest() { $request = Request::create('/test-path'); @@ -144,7 +142,8 @@ public function testCreateFromRequest() { ->with($request) ->will($this->throwException(new ResourceNotFoundException())); - $this->assertNull(Url::createFromRequest($request)); + $this->setExpectedException(ResourceNotFoundException::class); + Url::createFromRequest($request); } /** @@ -179,12 +178,11 @@ public function testToString($uri) { * @depends testFromUri * @dataProvider providerFromUri * - * @expectedException \UnexpectedValueException - * * @covers ::getRouteName */ public function testGetRouteName($uri) { $url = Url::fromUri($uri); + $this->setExpectedException(\UnexpectedValueException::class); $url->getRouteName(); } @@ -194,12 +192,11 @@ public function testGetRouteName($uri) { * @depends testFromUri * @dataProvider providerFromUri * - * @expectedException \UnexpectedValueException - * * @covers ::getRouteParameters */ public function testGetRouteParameters($uri) { $url = Url::fromUri($uri); + $this->setExpectedException(\UnexpectedValueException::class); $url->getRouteParameters(); } @@ -210,12 +207,11 @@ public function testGetRouteParameters($uri) { * @dataProvider providerFromUri * * @covers ::getInternalPath - * - * @expectedException \Exception */ public function testGetInternalPath($uri) { $url = Url::fromUri($uri); - $this->assertNull($url->getInternalPath()); + $this->setExpectedException(\Exception::class); + $url->getInternalPath(); } /** diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php index 5324c264..ff4cb01b 100644 --- a/core/tests/Drupal/Tests/Core/UrlTest.php +++ b/core/tests/Drupal/Tests/Core/UrlTest.php @@ -73,21 +73,21 @@ class UrlTest extends UnitTestCase { protected function setUp() { parent::setUp(); - $map = array(); - $map[] = array('view.frontpage.page_1', array(), array(), FALSE, '/node'); - $map[] = array('node_view', array('node' => '1'), array(), FALSE, '/node/1'); - $map[] = array('node_edit', array('node' => '2'), array(), FALSE, '/node/2/edit'); + $map = []; + $map[] = ['view.frontpage.page_1', [], [], FALSE, '/node']; + $map[] = ['node_view', ['node' => '1'], [], FALSE, '/node/1']; + $map[] = ['node_edit', ['node' => '2'], [], FALSE, '/node/2/edit']; $this->map = $map; - $alias_map = array( + $alias_map = [ // Set up one proper alias that can be resolved to a system path. - array('node-alias-test', NULL, FALSE, 'node'), + ['node-alias-test', NULL, FALSE, 'node'], // Passing in anything else should return the same string. - array('node', NULL, FALSE, 'node'), - array('node/1', NULL, FALSE, 'node/1'), - array('node/2/edit', NULL, FALSE, 'node/2/edit'), - array('non-existent', NULL, FALSE, 'non-existent'), - ); + ['node', NULL, FALSE, 'node'], + ['node/1', NULL, FALSE, 'node/1'], + ['node/2/edit', NULL, FALSE, 'node/2/edit'], + ['non-existent', NULL, FALSE, 'non-existent'], + ]; // $this->map has $collect_bubbleable_metadata = FALSE; also generate the // $collect_bubbleable_metadata = TRUE case for ::generateFromRoute(). @@ -143,7 +143,7 @@ public function testUrlFromRequest() { '_raw_variables' => new ParameterBag(['node' => '2']), ]); - $urls = array(); + $urls = []; foreach ($this->map as $index => $values) { $path = array_pop($values); $url = Url::createFromRequest(Request::create("$path")); @@ -215,10 +215,10 @@ public function testFromUserInput($path) { * Tests the fromUserInput method with invalid paths. * * @covers ::fromUserInput - * @expectedException \InvalidArgumentException * @dataProvider providerFromInvalidInternalUri */ public function testFromInvalidUserInput($path) { + $this->setExpectedException(\InvalidArgumentException::class); $url = Url::fromUserInput($path); } @@ -258,13 +258,13 @@ public function testFromRoutedPathWithValidRoute() { * @covers ::createFromRequest */ public function testCreateFromRequest() { - $attributes = array( - '_raw_variables' => new ParameterBag(array( + $attributes = [ + '_raw_variables' => new ParameterBag([ 'color' => 'chartreuse', - )), + ]), RouteObjectInterface::ROUTE_NAME => 'the_route_name', - ); - $request = new Request(array(), array(), $attributes); + ]; + $request = new Request([], [], $attributes); $this->router->expects($this->once()) ->method('matchRequest') @@ -272,7 +272,7 @@ public function testCreateFromRequest() { ->will($this->returnValue($attributes)); $url = Url::createFromRequest($request); - $expected = new Url('the_route_name', array('color' => 'chartreuse')); + $expected = new Url('the_route_name', ['color' => 'chartreuse']); $this->assertEquals($expected, $url); } @@ -280,8 +280,6 @@ public function testCreateFromRequest() { * Tests that an invalid request will thrown an exception. * * @covers ::createFromRequest - * - * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException */ public function testUrlFromRequestInvalid() { $request = Request::create('/test-path'); @@ -291,7 +289,8 @@ public function testUrlFromRequestInvalid() { ->with($request) ->will($this->throwException(new ResourceNotFoundException())); - $this->assertNull(Url::createFromRequest($request)); + $this->setExpectedException(ResourceNotFoundException::class); + Url::createFromRequest($request); } /** @@ -315,11 +314,10 @@ public function testIsExternal($urls) { * * @depends testUrlFromRequest * - * @expectedException \UnexpectedValueException - * * @covers ::getUri */ public function testGetUriForInternalUrl($urls) { + $this->setExpectedException(\UnexpectedValueException::class); foreach ($urls as $url) { $url->getUri(); } @@ -418,10 +416,10 @@ public function testGetRouteName($urls) { * Tests the getRouteName() with an external URL. * * @covers ::getRouteName - * @expectedException \UnexpectedValueException */ public function testGetRouteNameWithExternalUrl() { $url = Url::fromUri('http://example.com'); + $this->setExpectedException(\UnexpectedValueException::class); $url->getRouteName(); } @@ -445,10 +443,10 @@ public function testGetRouteParameters($urls) { * Tests the getRouteParameters() with an external URL. * * @covers ::getRouteParameters - * @expectedException \UnexpectedValueException */ public function testGetRouteParametersWithExternalUrl() { $url = Url::fromUri('http://example.com'); + $this->setExpectedException(\UnexpectedValueException::class); $url->getRouteParameters(); } @@ -468,6 +466,31 @@ public function testGetOptions($urls) { } } + /** + * Tests the setOptions() method. + * + * @covers ::setOptions + */ + public function testSetOptions() { + $url = Url::fromRoute('test_route', []); + $this->assertEquals([], $url->getOptions()); + $url->setOptions(['foo' => 'bar']); + $this->assertEquals(['foo' => 'bar'], $url->getOptions()); + $url->setOptions([]); + $this->assertEquals([], $url->getOptions()); + } + + /** + * Tests the mergeOptions() method. + * + * @covers ::mergeOptions + */ + public function testMergeOptions() { + $url = Url::fromRoute('test_route', [], ['foo' => 'bar', 'bar' => ['key' => 'value']]); + $url->mergeOptions(['bar' => ['key' => 'value1', 'key2' => 'value2']]); + $this->assertEquals(['foo' => 'bar', 'bar' => ['key' => 'value1', 'key2' => 'value2']], $url->getOptions()); + } + /** * Tests the access() method for routed URLs. * @@ -508,9 +531,9 @@ public function testAccessUnrouted() { * @dataProvider accessProvider */ public function testRenderAccess($access) { - $element = array( + $element = [ '#url' => Url::fromRoute('entity.node.canonical', ['node' => 3]), - ); + ]; $this->container->set('current_user', $this->getMock('Drupal\Core\Session\AccountInterface')); $this->container->set('access_manager', $this->getMockAccessManager($access)); $this->assertEquals($access, TestUrl::renderAccess($element)); @@ -605,7 +628,6 @@ public function testEntityUris($uri, $options, $route_name, $route_parameters, $ * Tests the fromUri() method with an invalid entity: URI. * * @covers ::fromUri - * @expectedException \Symfony\Component\Routing\Exception\InvalidParameterException */ public function testInvalidEntityUriParameter() { // Make the mocked URL generator behave like the actual one. @@ -614,6 +636,7 @@ public function testInvalidEntityUriParameter() { ->with('entity.test_entity.canonical', ['test_entity' => '1/blah']) ->willThrowException(new InvalidParameterException('Parameter "test_entity" for route "/test_entity/{test_entity}" must match "[^/]++" ("1/blah" given) to generate a corresponding URL..')); + $this->setExpectedException(InvalidParameterException::class); Url::fromUri('entity:test_entity/1/blah')->toString(); } @@ -713,6 +736,7 @@ public function providerFromValidInternalUri() { ['/?page=1000'], ['?page=1000'], ['?breed=bengal&page=1000'], + ['?referrer=https://kittenfacts'], // Paths with various token formats but no leading slash. ['/[duckies]'], ['/%bunnies'], @@ -728,10 +752,10 @@ public function providerFromValidInternalUri() { * Tests the fromUri() method with an invalid internal: URI. * * @covers ::fromUri - * @expectedException \InvalidArgumentException * @dataProvider providerFromInvalidInternalUri */ public function testFromInvalidInternalUri($path) { + $this->setExpectedException(\InvalidArgumentException::class); Url::fromUri('internal:' . $path); } @@ -800,10 +824,10 @@ public function providerTestToUriStringForRoute() { } /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage The route URI 'route:' is invalid. + * @covers ::fromUri */ public function testFromRouteUriWithMissingRouteName() { + $this->setExpectedException(\InvalidArgumentException::class, "The route URI 'route:' is invalid."); Url::fromUri('route:'); } @@ -828,10 +852,10 @@ protected function getMockAccessManager($access, $account = NULL) { * Data provider for the access test methods. */ public function accessProvider() { - return array( - array(TRUE), - array(FALSE), - ); + return [ + [TRUE], + [FALSE], + ]; } } diff --git a/core/tests/Drupal/Tests/Core/Utility/ErrorTest.php b/core/tests/Drupal/Tests/Core/Utility/ErrorTest.php index 6c096001..e89f21d1 100644 --- a/core/tests/Drupal/Tests/Core/Utility/ErrorTest.php +++ b/core/tests/Drupal/Tests/Core/Utility/ErrorTest.php @@ -32,29 +32,29 @@ public function testGetLastCaller($backtrace, $expected) { * An array of parameter data. */ public function providerTestGetLastCaller() { - $data = array(); + $data = []; // Test with just one item. This should default to the function being // main(). - $single_item = array($this->createBacktraceItem()); - $data[] = array($single_item, $this->createBacktraceItem('main()')); + $single_item = [$this->createBacktraceItem()]; + $data[] = [$single_item, $this->createBacktraceItem('main()')]; // Add a second item, without a class. $two_items = $single_item; $two_items[] = $this->createBacktraceItem('test_function_two'); - $data[] = array($two_items, $this->createBacktraceItem('test_function_two()')); + $data[] = [$two_items, $this->createBacktraceItem('test_function_two()')]; // Add a second item, with a class. $two_items = $single_item; $two_items[] = $this->createBacktraceItem('test_function_two', 'TestClass'); - $data[] = array($two_items, $this->createBacktraceItem('TestClass->test_function_two()')); + $data[] = [$two_items, $this->createBacktraceItem('TestClass->test_function_two()')]; // Add blacklist functions to backtrace. They should get removed. - foreach (array('debug', '_drupal_error_handler', '_drupal_exception_handler') as $function) { + foreach (['debug', '_drupal_error_handler', '_drupal_exception_handler'] as $function) { $two_items = $single_item; // Push to the start of the backtrace. array_unshift($two_items, $this->createBacktraceItem($function)); - $data[] = array($single_item, $this->createBacktraceItem('main()')); + $data[] = [$single_item, $this->createBacktraceItem('main()')]; } return $data; @@ -80,31 +80,31 @@ public function testFormatBacktrace($backtrace, $expected) { * @return array */ public function providerTestFormatBacktrace() { - $data = array(); + $data = []; // Test with no function, main should be in the backtrace. - $data[] = array(array($this->createBacktraceItem(NULL, NULL)), "main() (Line: 10)\n"); + $data[] = [[$this->createBacktraceItem(NULL, NULL)], "main() (Line: 10)\n"]; - $base = array($this->createBacktraceItem()); - $data[] = array($base, "test_function() (Line: 10)\n"); + $base = [$this->createBacktraceItem()]; + $data[] = [$base, "test_function() (Line: 10)\n"]; // Add a second item. $second_item = $base; $second_item[] = $this->createBacktraceItem('test_function_2'); - $data[] = array($second_item, "test_function() (Line: 10)\ntest_function_2() (Line: 10)\n"); + $data[] = [$second_item, "test_function() (Line: 10)\ntest_function_2() (Line: 10)\n"]; // Add a second item, with a class. $second_item_class = $base; $second_item_class[] = $this->createBacktraceItem('test_function_2', 'TestClass'); - $data[] = array($second_item_class, "test_function() (Line: 10)\nTestClass->test_function_2() (Line: 10)\n"); + $data[] = [$second_item_class, "test_function() (Line: 10)\nTestClass->test_function_2() (Line: 10)\n"]; // Add a second item, with a class. $second_item_args = $base; - $second_item_args[] = $this->createBacktraceItem('test_function_2', NULL, array('string', 10, new \stdClass())); + $second_item_args[] = $this->createBacktraceItem('test_function_2', NULL, ['string', 10, new \stdClass()]); - $data[] = array($second_item_args, "test_function() (Line: 10)\ntest_function_2('string', 10, Object) (Line: 10)\n"); + $data[] = [$second_item_args, "test_function() (Line: 10)\ntest_function_2('string', 10, Object) (Line: 10)\n"]; return $data; } @@ -124,13 +124,13 @@ public function providerTestFormatBacktrace() { * @return array * A backtrace array item. */ - protected function createBacktraceItem($function = 'test_function', $class = NULL, array $args = array(), $line = 10) { - $backtrace = array( + protected function createBacktraceItem($function = 'test_function', $class = NULL, array $args = [], $line = 10) { + $backtrace = [ 'file' => 'test_file', 'line' => $line, 'function' => $function, - 'args' => array(), - ); + 'args' => [], + ]; if (isset($class)) { $backtrace['class'] = $class; diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php index f4dc2dfa..c53b4740 100644 --- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php +++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php @@ -57,12 +57,12 @@ class LinkGeneratorTest extends UnitTestCase { /** * Contains the LinkGenerator default options. */ - protected $defaultOptions = array( - 'query' => array(), + protected $defaultOptions = [ + 'query' => [], 'language' => NULL, 'set_active_class' => FALSE, 'absolute' => FALSE, - ); + ]; /** * {@inheritdoc} @@ -88,14 +88,14 @@ protected function setUp() { * Returns some test data. */ public function providerTestGenerateHrefs() { - return array( + return [ // Test that the url returned by the URL generator is used. - array('test_route_1', array(), FALSE, '/test-route-1'), + ['test_route_1', [], FALSE, '/test-route-1'], // Test that $parameters is passed to the URL generator. - array('test_route_2', array('value' => 'example'), FALSE, '/test-route-2/example'), + ['test_route_2', ['value' => 'example'], FALSE, '/test-route-2/example'], // Test that the 'absolute' option is passed to the URL generator. - array('test_route_3', array(), TRUE, 'http://example.com/test-route-3'), - ); + ['test_route_3', [], TRUE, 'http://example.com/test-route-3'], + ]; } /** @@ -109,17 +109,17 @@ public function providerTestGenerateHrefs() { public function testGenerateHrefs($route_name, array $parameters, $absolute, $expected_url) { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with($route_name, $parameters, array('absolute' => $absolute) + $this->defaultOptions) + ->with($route_name, $parameters, ['absolute' => $absolute] + $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl($expected_url)); $this->moduleHandler->expects($this->once()) ->method('alter'); - $url = new Url($route_name, $parameters, array('absolute' => $absolute)); + $url = new Url($route_name, $parameters, ['absolute' => $absolute]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array('href' => $expected_url), - ), $result); + $this->assertLink([ + 'attributes' => ['href' => $expected_url], + ], $result); } /** @@ -130,23 +130,23 @@ public function testGenerateHrefs($route_name, array $parameters, $absolute, $ex public function testGenerate() { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with('test_route_1', array(), array('fragment' => 'the-fragment') + $this->defaultOptions) + ->with('test_route_1', [], ['fragment' => 'the-fragment'] + $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-1#the-fragment')); $this->moduleHandler->expects($this->once()) ->method('alter') ->with('link', $this->isType('array')); - $url = new Url('test_route_1', array(), array('fragment' => 'the-fragment')); + $url = new Url('test_route_1', [], ['fragment' => 'the-fragment']); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/test-route-1#the-fragment', - ), + ], 'content' => 'Test', - ), $result); + ], $result); } /** @@ -180,7 +180,7 @@ public function testGenerateNoLink() { public function testGenerateExternal() { $this->urlAssembler->expects($this->once()) ->method('assemble') - ->with('https://www.drupal.org', array('set_active_class' => TRUE, 'external' => TRUE) + $this->defaultOptions) + ->with('https://www.drupal.org', ['set_active_class' => TRUE, 'external' => TRUE] + $this->defaultOptions) ->will($this->returnArgument(0)); $this->moduleHandler->expects($this->once()) @@ -189,7 +189,7 @@ public function testGenerateExternal() { $this->urlAssembler->expects($this->once()) ->method('assemble') - ->with('https://www.drupal.org', array('set_active_class' => TRUE, 'external' => TRUE) + $this->defaultOptions) + ->with('https://www.drupal.org', ['set_active_class' => TRUE, 'external' => TRUE] + $this->defaultOptions) ->willReturnArgument(0); $url = Url::fromUri('https://www.drupal.org'); @@ -198,12 +198,12 @@ public function testGenerateExternal() { $url->setOption('set_active_class', TRUE); $result = $this->linkGenerator->generate('Drupal', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => 'https://www.drupal.org', - ), + ], 'content' => 'Drupal', - ), $result); + ], $result); } /** @@ -214,7 +214,7 @@ public function testGenerateExternal() { public function testGenerateUrlWithQuotes() { $this->urlAssembler->expects($this->once()) ->method('assemble') - ->with('base:example', array('query' => array('foo' => '"bar"', 'zoo' => 'baz')) + $this->defaultOptions) + ->with('base:example', ['query' => ['foo' => '"bar"', 'zoo' => 'baz']] + $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/example?foo=%22bar%22&zoo=baz')); $path_validator = $this->getMock('Drupal\Core\Path\PathValidatorInterface'); @@ -229,12 +229,12 @@ public function testGenerateUrlWithQuotes() { $result = $this->linkGenerator->generate('Drupal', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/example?foo=%22bar%22&zoo=baz', - ), + ], 'content' => 'Drupal', - ), $result, 1); + ], $result, 1); } /** @@ -245,21 +245,21 @@ public function testGenerateUrlWithQuotes() { public function testGenerateAttributes() { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with('test_route_1', array(), $this->defaultOptions) + ->with('test_route_1', [], $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-1')); // Test that HTML attributes are added to the anchor. - $url = new Url('test_route_1', array(), array( - 'attributes' => array('title' => 'Tooltip'), - )); + $url = new Url('test_route_1', [], [ + 'attributes' => ['title' => 'Tooltip'], + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/test-route-1', 'title' => 'Tooltip', - ), - ), $result); + ], + ], $result); } /** @@ -270,19 +270,19 @@ public function testGenerateAttributes() { public function testGenerateQuery() { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with('test_route_1', array(), array('query' => array('test' => 'value')) + $this->defaultOptions) + ->with('test_route_1', [], ['query' => ['test' => 'value']] + $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-1?test=value')); - $url = new Url('test_route_1', array(), array( - 'query' => array('test' => 'value'), - )); + $url = new Url('test_route_1', [], [ + 'query' => ['test' => 'value'], + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/test-route-1?test=value', - ), - ), $result); + ], + ], $result); } /** @@ -293,17 +293,17 @@ public function testGenerateQuery() { public function testGenerateParametersAsQuery() { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with('test_route_1', array('test' => 'value'), $this->defaultOptions) + ->with('test_route_1', ['test' => 'value'], $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-1?test=value')); - $url = new Url('test_route_1', array('test' => 'value'), array()); + $url = new Url('test_route_1', ['test' => 'value'], []); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/test-route-1?test=value', - ), - ), $result); + ], + ], $result); } /** @@ -314,18 +314,18 @@ public function testGenerateParametersAsQuery() { public function testGenerateOptions() { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with('test_route_1', array(), array('key' => 'value') + $this->defaultOptions) + ->with('test_route_1', [], ['key' => 'value'] + $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-1?test=value')); - $url = new Url('test_route_1', array(), array( + $url = new Url('test_route_1', [], [ 'key' => 'value', - )); + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/test-route-1?test=value', - ), - ), $result); + ], + ], $result); } /** @@ -336,7 +336,7 @@ public function testGenerateOptions() { public function testGenerateXss() { $this->urlGenerator->expects($this->once()) ->method('generateFromRoute') - ->with('test_route_4', array(), $this->defaultOptions) + ->with('test_route_4', [], $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-4')); // Test that HTML link text is escaped by default. @@ -354,38 +354,38 @@ public function testGenerateXss() { public function testGenerateWithHtml() { $this->urlGenerator->expects($this->at(0)) ->method('generateFromRoute') - ->with('test_route_5', array(), $this->defaultOptions) + ->with('test_route_5', [], $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-5')); $this->urlGenerator->expects($this->at(1)) ->method('generateFromRoute') - ->with('test_route_5', array(), $this->defaultOptions) + ->with('test_route_5', [], $this->defaultOptions) ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test-route-5')); // Test that HTML tags are stripped from the 'title' attribute. - $url = new Url('test_route_5', array(), array( - 'attributes' => array('title' => 'HTML Tooltip'), - )); + $url = new Url('test_route_5', [], [ + 'attributes' => ['title' => 'HTML Tooltip'], + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'href' => '/test-route-5', 'title' => 'HTML Tooltip', - ), - ), $result); + ], + ], $result); // Test that safe HTML is output inside the anchor tag unescaped. The // Markup::create() call is an intentional unit test for the interaction // between MarkupInterface and the LinkGenerator. - $url = new Url('test_route_5', array()); + $url = new Url('test_route_5', []); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate(Markup::create('HTML output'), $url); - $this->assertLink(array( - 'attributes' => array('href' => '/test-route-5'), - 'child' => array( + $this->assertLink([ + 'attributes' => ['href' => '/test-route-5'], + 'child' => [ 'tag' => 'em', - ), - ), $result); + ], + ], $result); $this->assertTrue(strpos($result, 'HTML output') !== FALSE); } @@ -397,7 +397,7 @@ public function testGenerateWithHtml() { public function testGenerateActive() { $this->urlGenerator->expects($this->exactly(5)) ->method('generateFromRoute') - ->willReturnCallback(function($name, $parameters = array(), $options = array(), $collect_bubbleable_metadata = FALSE) { + ->willReturnCallback(function ($name, $parameters = [], $options = [], $collect_bubbleable_metadata = FALSE) { switch ($name) { case 'test_route_1': return (new GeneratedUrl())->setGeneratedUrl('/test-route-1'); @@ -412,70 +412,70 @@ public function testGenerateActive() { $this->urlGenerator->expects($this->exactly(4)) ->method('getPathFromRoute') - ->will($this->returnValueMap(array( - array('test_route_1', array(), 'test-route-1'), - array('test_route_3', array(), 'test-route-3'), - array('test_route_4', array('object' => '1'), 'test-route-4/1'), - ))); + ->will($this->returnValueMap([ + ['test_route_1', [], 'test-route-1'], + ['test_route_3', [], 'test-route-3'], + ['test_route_4', ['object' => '1'], 'test-route-4/1'], + ])); $this->moduleHandler->expects($this->exactly(5)) ->method('alter'); // Render a link. - $url = new Url('test_route_1', array(), array('set_active_class' => TRUE)); + $url = new Url('test_route_1', [], ['set_active_class' => TRUE]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array('data-drupal-link-system-path' => 'test-route-1'), - ), $result); + $this->assertLink([ + 'attributes' => ['data-drupal-link-system-path' => 'test-route-1'], + ], $result); // Render a link with the set_active_class option disabled. - $url = new Url('test_route_1', array(), array('set_active_class' => FALSE)); + $url = new Url('test_route_1', [], ['set_active_class' => FALSE]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); $this->assertNoXPathResults('//a[@data-drupal-link-system-path="test-route-1"]', $result); // Render a link with an associated language. - $url = new Url('test_route_1', array(), array( - 'language' => new Language(array('id' => 'de')), + $url = new Url('test_route_1', [], [ + 'language' => new Language(['id' => 'de']), 'set_active_class' => TRUE, - )); + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'data-drupal-link-system-path' => 'test-route-1', 'hreflang' => 'de', - ), - ), $result); + ], + ], $result); // Render a link with a query parameter. - $url = new Url('test_route_3', array(), array( - 'query' => array('value' => 'example_1'), + $url = new Url('test_route_3', [], [ + 'query' => ['value' => 'example_1'], 'set_active_class' => TRUE, - )); + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'data-drupal-link-system-path' => 'test-route-3', 'data-drupal-link-query' => '{"value":"example_1"}', - ), - ), $result); + ], + ], $result); // Render a link with route parameters and a query parameter. - $url = new Url('test_route_4', array('object' => '1'), array( - 'query' => array('value' => 'example_1'), + $url = new Url('test_route_4', ['object' => '1'], [ + 'query' => ['value' => 'example_1'], 'set_active_class' => TRUE, - )); + ]); $url->setUrlGenerator($this->urlGenerator); $result = $this->linkGenerator->generate('Test', $url); - $this->assertLink(array( - 'attributes' => array( + $this->assertLink([ + 'attributes' => [ 'data-drupal-link-system-path' => 'test-route-4/1', 'data-drupal-link-query' => '{"value":"example_1"}', - ), - ), $result); + ], + ], $result); } /** @@ -537,6 +537,25 @@ public function testGenerateWithAlterHook() { $this->assertEquals($expected_link_markup, (string) $this->linkGenerator->generate('Test', $url)->getGeneratedLink()); } + /** + * Tests whether rendering the same link twice works. + * + * This is a regression test for https://www.drupal.org/node/2842399. + */ + public function testGenerateTwice() { + $this->urlGenerator->expects($this->any()) + ->method('generateFromRoute') + ->will($this->returnValue((new GeneratedUrl())->setGeneratedUrl('/'))); + + $url = Url::fromRoute('', [], ['attributes' => ['class' => ['foo', 'bar']]]); + $url->setUrlGenerator($this->urlGenerator); + + $link = Link::fromTextAndUrl('text', $url); + $link->setLinkGenerator($this->linkGenerator); + $output = $link->toString() . $link->toString(); + $this->assertEquals('texttext', $output); + } + /** * Checks that a link with certain properties exists in a given HTML snippet. * @@ -551,13 +570,13 @@ public function testGenerateWithAlterHook() { */ public static function assertLink(array $properties, MarkupInterface $html, $count = 1) { // Provide default values. - $properties += array('attributes' => array()); + $properties += ['attributes' => []]; // Create an XPath query that selects a link element. $query = '//a'; // Append XPath predicates for the attributes and content text. - $predicates = array(); + $predicates = []; foreach ($properties['attributes'] as $attribute => $value) { $predicates[] = "@$attribute='$value'"; } diff --git a/core/tests/Drupal/Tests/Core/Utility/TokenTest.php b/core/tests/Drupal/Tests/Core/Utility/TokenTest.php index 04a2b8f6..91620e61 100644 --- a/core/tests/Drupal/Tests/Core/Utility/TokenTest.php +++ b/core/tests/Drupal/Tests/Core/Utility/TokenTest.php @@ -104,13 +104,13 @@ protected function setUp() { * @covers ::getInfo */ public function testGetInfo() { - $token_info = array( - 'types' => array( - 'foo' => array( + $token_info = [ + 'types' => [ + 'foo' => [ 'name' => $this->randomMachineName(), - ), - ), - ); + ], + ], + ]; $this->language->expects($this->atLeastOnce()) ->method('getId') diff --git a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php index b2d7700e..a47d2062 100644 --- a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php +++ b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php @@ -56,17 +56,17 @@ protected function setUp() { /** * @covers ::assemble - * @expectedException \InvalidArgumentException */ public function testAssembleWithNeitherExternalNorDomainLocalUri() { + $this->setExpectedException(\InvalidArgumentException::class); $this->unroutedUrlAssembler->assemble('wrong-url'); } /** * @covers ::assemble - * @expectedException \InvalidArgumentException */ public function testAssembleWithLeadingSlash() { + $this->setExpectedException(\InvalidArgumentException::class); $this->unroutedUrlAssembler->assemble('/drupal.org'); } @@ -121,10 +121,10 @@ public function providerTestAssembleWithLocalUri() { ['base:example', ['query' => ['foo' => 'bar']], FALSE, '/example?foo=bar'], ['base:example', ['query' => ['foo' => '"bar"']], FALSE, '/example?foo=%22bar%22'], ['base:example', ['query' => ['foo' => '"bar"', 'zoo' => 'baz']], FALSE, '/example?foo=%22bar%22&zoo=baz'], - ['base:example', ['fragment' => 'example', ], FALSE, '/example#example'], + ['base:example', ['fragment' => 'example'], FALSE, '/example#example'], ['base:example', [], TRUE, '/subdir/example'], ['base:example', ['query' => ['foo' => 'bar']], TRUE, '/subdir/example?foo=bar'], - ['base:example', ['fragment' => 'example', ], TRUE, '/subdir/example#example'], + ['base:example', ['fragment' => 'example'], TRUE, '/subdir/example#example'], ['base:/drupal.org', [], FALSE, '/drupal.org'], ]; } @@ -147,7 +147,7 @@ public function testAssembleWithEnabledProcessing() { $this->setupRequestStack(FALSE); $this->pathProcessor->expects($this->exactly(2)) ->method('processOutbound') - ->willReturnCallback(function($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) { + ->willReturnCallback(function ($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) { if ($bubbleable_metadata) { $bubbleable_metadata->setCacheContexts(['some-cache-context']); } diff --git a/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/PrimitiveTypeConstraintValidatorTest.php b/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/PrimitiveTypeConstraintValidatorTest.php index 12f36eac..6647e5fa 100644 --- a/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/PrimitiveTypeConstraintValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/PrimitiveTypeConstraintValidatorTest.php @@ -13,6 +13,7 @@ use Drupal\Core\Validation\Plugin\Validation\Constraint\PrimitiveTypeConstraintValidator; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Tests\UnitTestCase; +use Symfony\Component\Validator\Context\ExecutionContextInterface; /** * @coversDefaultClass \Drupal\Core\Validation\Plugin\Validation\Constraint\PrimitiveTypeConstraintValidator @@ -26,7 +27,7 @@ class PrimitiveTypeConstraintValidatorTest extends UnitTestCase { * @dataProvider provideTestValidate */ public function testValidate(PrimitiveInterface $typed_data, $value, $valid) { - $context = $this->getMock('\Symfony\Component\Validator\Context\ExecutionContextInterface'); + $context = $this->getMock(ExecutionContextInterface::class); $context->expects($this->any()) ->method('getObject') ->willReturn($typed_data); diff --git a/core/tests/Drupal/Tests/EntityViewTrait.php b/core/tests/Drupal/Tests/EntityViewTrait.php new file mode 100644 index 00000000..d8c9d924 --- /dev/null +++ b/core/tests/Drupal/Tests/EntityViewTrait.php @@ -0,0 +1,71 @@ +getInfo($elements['#type']); + } + + // Make any final changes to the element before it is rendered. This means + // that the $element or the children can be altered or corrected before the + // element is rendered into the final text. + if (isset($elements['#pre_render'])) { + foreach ($elements['#pre_render'] as $callable) { + $elements = call_user_func($callable, $elements); + } + } + + // And recurse. + $children = Element::children($elements, TRUE); + foreach ($children as $key) { + $ensure_fully_built($elements[$key]); + } + }; + + $render_controller = $this->container->get('entity.manager')->getViewBuilder($entity->getEntityTypeId()); + if ($reset) { + $render_controller->resetCache([$entity->id()]); + } + $build = $render_controller->view($entity, $view_mode, $langcode); + $ensure_fully_built($build); + + return $build; + } + +} diff --git a/core/tests/Drupal/Tests/HiddenFieldSelector.php b/core/tests/Drupal/Tests/HiddenFieldSelector.php new file mode 100644 index 00000000..b445c487 --- /dev/null +++ b/core/tests/Drupal/Tests/HiddenFieldSelector.php @@ -0,0 +1,23 @@ +registerNamedXpath('hidden_field', $xpath); + parent::__construct(); + } + +} diff --git a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListener.php b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListener.php new file mode 100644 index 00000000..c3496773 --- /dev/null +++ b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListener.php @@ -0,0 +1,27 @@ +toString(), 0, 22) == 'Drupal\Tests\Component') { + if ($test instanceof BrowserTestBase || $test instanceof KernelTestBase || $test instanceof UnitTestCase) { + $error = new \PHPUnit_Framework_AssertionFailedError('Component tests should not extend a core test base class.'); + $test->getTestResultObject()->addFailure($test, $error, $time); + } + } + } + +} diff --git a/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php b/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php index 7f8396fe..fd15f821 100644 --- a/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php +++ b/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php @@ -2,23 +2,26 @@ namespace Drupal\Tests\Listeners; +use PHPUnit\Framework\BaseTestListener; +use PHPUnit\Framework\TestCase; + /** * Listens for PHPUnit tests and fails those with invalid coverage annotations. * * Enforces various coding standards within test runs. */ -class DrupalStandardsListener extends \PHPUnit_Framework_BaseTestListener { +class DrupalStandardsListener extends BaseTestListener { /** * Signals a coding standards failure to the user. * - * @param \PHPUnit_Framework_TestCase $test + * @param \PHPUnit\Framework\TestCase $test * The test where we should insert our test failure. * @param string $message * The message to add to the failure notice. The test class name and test * name will be appended to this message automatically. */ - protected function fail(\PHPUnit_Framework_TestCase $test, $message) { + protected function fail(TestCase $test, $message) { // Add the report to the test's results. $message .= ': ' . get_class($test) . '::' . $test->getName(); $fail = new \PHPUnit_Framework_AssertionFailedError($message); @@ -44,10 +47,10 @@ protected function classExists($class) { * * This method is called from $this::endTest(). * - * @param \PHPUnit_Framework_TestCase $test + * @param \PHPUnit\Framework\TestCase $test * The test to examine. */ - public function checkValidCoversForTest(\PHPUnit_Framework_TestCase $test) { + public function checkValidCoversForTest(TestCase $test) { // If we're generating a coverage report already, don't do anything here. if ($test->getTestResultObject() && $test->getTestResultObject()->getCollectCodeCoverageInformation()) { return; @@ -139,12 +142,22 @@ public function checkValidCoversForTest(\PHPUnit_Framework_TestCase $test) { /** * {@inheritdoc} + * + * We must mark this method as belonging to the special legacy group because + * it might trigger an E_USER_DEPRECATED error during coverage annotation + * validation. The legacy group allows symfony/phpunit-bridge to keep the + * deprecation notice as a warning instead of an error, which would fail the + * test. + * + * @group legacy + * + * @see http://symfony.com/doc/current/components/phpunit_bridge.html#mark-tests-as-legacy */ public function endTest(\PHPUnit_Framework_Test $test, $time) { // \PHPUnit_Framework_Test does not have any useful methods of its own for // our purpose, so we have to distinguish between the different known // subclasses. - if ($test instanceof \PHPUnit_Framework_TestCase) { + if ($test instanceof TestCase) { $this->checkValidCoversForTest($test); } elseif ($test instanceof \PHPUnit_Framework_TestSuite) { diff --git a/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php new file mode 100644 index 00000000..bfb91d7b --- /dev/null +++ b/core/tests/Drupal/Tests/Listeners/SimpletestUiPrinter.php @@ -0,0 +1,26 @@ + tags. + $url_pattern = '@https?://[^\s]+@'; + $buffer = preg_replace($url_pattern, '$0', $buffer); + // Make the output readable in HTML by breaking up lines properly. + $buffer = nl2br($buffer); + + print $buffer; + } + +} diff --git a/core/tests/Drupal/Tests/RandomGeneratorTrait.php b/core/tests/Drupal/Tests/RandomGeneratorTrait.php index 4fdd89a8..3cac5d29 100644 --- a/core/tests/Drupal/Tests/RandomGeneratorTrait.php +++ b/core/tests/Drupal/Tests/RandomGeneratorTrait.php @@ -36,7 +36,7 @@ trait RandomGeneratorTrait { */ public function randomString($length = 8) { if ($length < 4) { - return $this->getRandomGenerator()->string($length, TRUE, array($this, 'randomStringValidate')); + return $this->getRandomGenerator()->string($length, TRUE, [$this, 'randomStringValidate']); } // To prevent the introduction of random test failures, ensure that the @@ -45,7 +45,7 @@ public function randomString($length = 8) { $replacement_pos = floor($length / 2); // Remove 2 from the length to account for the ampersand and greater than // characters. - $string = $this->getRandomGenerator()->string($length - 2, TRUE, array($this, 'randomStringValidate')); + $string = $this->getRandomGenerator()->string($length - 2, TRUE, [$this, 'randomStringValidate']); return substr_replace($string, '>&', $replacement_pos, 0); } diff --git a/core/tests/Drupal/Tests/SchemaCheckTestTrait.php b/core/tests/Drupal/Tests/SchemaCheckTestTrait.php new file mode 100644 index 00000000..0d4dd4bd --- /dev/null +++ b/core/tests/Drupal/Tests/SchemaCheckTestTrait.php @@ -0,0 +1,59 @@ +checkConfigSchema($typed_config, $config_name, $config_data); + if ($errors === FALSE) { + // @todo Since the use of this trait is under TestBase, it works. + // Can be fixed as part of https://www.drupal.org/node/2260053. + $this->fail(SafeMarkup::format('No schema for @config_name', ['@config_name' => $config_name])); + return; + } + elseif ($errors === TRUE) { + // @todo Since the use of this trait is under TestBase, it works. + // Can be fixed as part of https://www.drupal.org/node/2260053. + $this->pass(SafeMarkup::format('Schema found for @config_name and values comply with schema.', ['@config_name' => $config_name])); + } + else { + foreach ($errors as $key => $error) { + // @todo Since the use of this trait is under TestBase, it works. + // Can be fixed as part of https://www.drupal.org/node/2260053. + $this->fail(SafeMarkup::format('Schema key @key failed with: @error', ['@key' => $key, '@error' => $error])); + } + } + } + + /** + * Asserts configuration, specified by name, has a valid schema. + * + * @param string $config_name + * The configuration name. + */ + public function assertConfigSchemaByName($config_name) { + $config = $this->config($config_name); + $this->assertConfigSchema(\Drupal::service('config.typed'), $config->getName(), $config->get()); + } + +} diff --git a/core/tests/Drupal/Tests/TestRequirementsTrait.php b/core/tests/Drupal/Tests/TestRequirementsTrait.php new file mode 100644 index 00000000..84937ad6 --- /dev/null +++ b/core/tests/Drupal/Tests/TestRequirementsTrait.php @@ -0,0 +1,91 @@ +getAnnotations(); + if (!empty($annotations['class']['requires'])) { + $this->checkModuleRequirements($root, $annotations['class']['requires']); + } + if (!empty($annotations['method']['requires'])) { + $this->checkModuleRequirements($root, $annotations['method']['requires']); + } + } + + /** + * Checks missing module requirements. + * + * Iterates through a list of requires annotations and looks for missing + * modules. The test will be skipped if any of the required modules is + * missing. + * + * @param string $root + * The path to the root of the Drupal installation to scan. + * @param string[] $annotations + * A list of requires annotations from either a method or class annotation. + * + * @throws \PHPUnit_Framework_SkippedTestError + * Thrown when the requirements are not met, and this test should be + * skipped. Callers should not catch this exception. + */ + private function checkModuleRequirements($root, array $annotations) { + // drupal_valid_ua() might not be loaded. + require_once $root . '/core/includes/bootstrap.inc'; + + // Make a list of required modules. + $required_modules = []; + foreach ($annotations as $requirement) { + if (strpos($requirement, 'module ') === 0) { + $required_modules[] = trim(str_replace('module ', '', $requirement)); + } + } + + // If there are required modules, check if they're available. + if (!empty($required_modules)) { + // Scan for modules. + $discovery = new ExtensionDiscovery($root, FALSE); + $discovery->setProfileDirectories([]); + $list = array_keys($discovery->scan('module')); + $not_available = array_diff($required_modules, $list); + if (!empty($not_available)) { + throw new \PHPUnit_Framework_SkippedTestError('Required modules: ' . implode(', ', $not_available)); + } + } + } + +} diff --git a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php index 0ba81434..4c289e4d 100644 --- a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php +++ b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\TestSuites; use org\bovigo\vfs\vfsStream; +use PHPUnit\Framework\TestCase; // The test suite class is not part of the autoloader, we need to include it // manually. @@ -13,7 +14,7 @@ * * @group TestSuite */ -class TestSuiteBaseTest extends \PHPUnit_Framework_TestCase { +class TestSuiteBaseTest extends TestCase { /** * Helper method to set up the file system. @@ -94,6 +95,14 @@ public function testAddTestsBySuiteNamespaceCore($filesystem, $suite_namespace, $this->assertEmpty(array_diff_assoc($expected_tests, $stub->testFiles)); } + /** + * Tests the assumption that local time is in 'Australia/Sydney'. + */ + public function testLocalTimeZone() { + // The 'Australia/Sydney' time zone is set in core/tests/bootstrap.php + $this->assertEquals('Australia/Sydney', date_default_timezone_get()); + } + } /** diff --git a/core/tests/Drupal/Tests/Traits/Core/Config/SchemaConfigListenerTestTrait.php b/core/tests/Drupal/Tests/Traits/Core/Config/SchemaConfigListenerTestTrait.php index 02931e45..5a73cad4 100644 --- a/core/tests/Drupal/Tests/Traits/Core/Config/SchemaConfigListenerTestTrait.php +++ b/core/tests/Drupal/Tests/Traits/Core/Config/SchemaConfigListenerTestTrait.php @@ -2,7 +2,7 @@ namespace Drupal\Tests\Traits\Core\Config; -use \Drupal\Core\Config\Schema\SchemaIncompleteException; +use Drupal\Core\Config\Schema\SchemaIncompleteException; /** * Adds a test for the configuration schema checker use in tests. @@ -10,7 +10,7 @@ trait SchemaConfigListenerTestTrait { /** - * Tests \Drupal\Core\Config\Testing\ConfigSchemaChecker. + * Tests \Drupal\Core\Config\Development\ConfigSchemaChecker. */ public function testConfigSchemaChecker() { // Test a non-existing schema. diff --git a/core/tests/Drupal/Tests/Traits/Core/CronRunTrait.php b/core/tests/Drupal/Tests/Traits/Core/CronRunTrait.php new file mode 100644 index 00000000..17ca9fcd --- /dev/null +++ b/core/tests/Drupal/Tests/Traits/Core/CronRunTrait.php @@ -0,0 +1,17 @@ +drupalGet('cron/' . \Drupal::state()->get('system.cron_key')); + } + +} diff --git a/core/tests/Drupal/Tests/Traits/Core/GeneratePermutationsTrait.php b/core/tests/Drupal/Tests/Traits/Core/GeneratePermutationsTrait.php new file mode 100644 index 00000000..6e222cb6 --- /dev/null +++ b/core/tests/Drupal/Tests/Traits/Core/GeneratePermutationsTrait.php @@ -0,0 +1,59 @@ + [0, 1], + * 'two' => [2, 3], + * ]; + * $permutations = $this->generatePermutations($parameters); + * // Result: + * $permutations == [ + * ['one' => 0, 'two' => 2], + * ['one' => 1, 'two' => 2], + * ['one' => 0, 'two' => 3], + * ['one' => 1, 'two' => 3], + * ] + * @endcode + * + * @param array $parameters + * An associative array of parameters, keyed by parameter name, and whose + * values are arrays of parameter values. + * + * @return array[] + * A list of permutations, which is an array of arrays. Each inner array + * contains the full list of parameters that have been passed, but with a + * single value only. + */ + public static function generatePermutations(array $parameters) { + $all_permutations = [[]]; + foreach ($parameters as $parameter => $values) { + $new_permutations = []; + // Iterate over all values of the parameter. + foreach ($values as $value) { + // Iterate over all existing permutations. + foreach ($all_permutations as $permutation) { + // Add the new parameter value to existing permutations. + $new_permutations[] = $permutation + [$parameter => $value]; + } + } + // Replace the old permutations with the new permutations. + $all_permutations = $new_permutations; + } + return $all_permutations; + } + +} diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php index 0a3b41a7..b157274f 100644 --- a/core/tests/Drupal/Tests/UnitTestCase.php +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -8,14 +8,14 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\StringTranslation\PluralTranslatableMarkup; - +use PHPUnit\Framework\TestCase; /** * Provides a base class and helpers for Drupal unit tests. * * @ingroup testing */ -abstract class UnitTestCase extends \PHPUnit_Framework_TestCase { +abstract class UnitTestCase extends TestCase { /** * The random generator. @@ -104,18 +104,18 @@ protected function assertArrayEquals(array $expected, array $actual, $message = * @return \PHPUnit_Framework_MockObject_MockBuilder * A MockBuilder object for the ConfigFactory with the desired return values. */ - public function getConfigFactoryStub(array $configs = array()) { - $config_get_map = array(); - $config_editable_map = array(); + public function getConfigFactoryStub(array $configs = []) { + $config_get_map = []; + $config_editable_map = []; // Construct the desired configuration object stubs, each with its own // desired return map. foreach ($configs as $config_name => $config_values) { - $map = array(); + $map = []; foreach ($config_values as $key => $value) { - $map[] = array($key, $value); + $map[] = [$key, $value]; } // Also allow to pass in no argument. - $map[] = array('', $config_values); + $map[] = ['', $config_values]; $immutable_config_object = $this->getMockBuilder('Drupal\Core\Config\ImmutableConfig') ->disableOriginalConstructor() @@ -123,7 +123,7 @@ public function getConfigFactoryStub(array $configs = array()) { $immutable_config_object->expects($this->any()) ->method('get') ->will($this->returnValueMap($map)); - $config_get_map[] = array($config_name, $immutable_config_object); + $config_get_map[] = [$config_name, $immutable_config_object]; $mutable_config_object = $this->getMockBuilder('Drupal\Core\Config\Config') ->disableOriginalConstructor() @@ -131,7 +131,7 @@ public function getConfigFactoryStub(array $configs = array()) { $mutable_config_object->expects($this->any()) ->method('get') ->will($this->returnValueMap($map)); - $config_editable_map[] = array($config_name, $mutable_config_object); + $config_editable_map[] = [$config_name, $mutable_config_object]; } // Construct a config factory with the array of configuration object stubs // as its return map. @@ -207,7 +207,7 @@ public function getStringTranslationStub() { $translation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface'); $translation->expects($this->any()) ->method('translate') - ->willReturnCallback(function ($string, array $args = array(), array $options = array()) use ($translation) { + ->willReturnCallback(function ($string, array $args = [], array $options = []) use ($translation) { return new TranslatableMarkup($string, $args, $options, $translation); }); $translation->expects($this->any()) diff --git a/core/tests/Drupal/Tests/WebAssert.php b/core/tests/Drupal/Tests/WebAssert.php index 6156dda8..9171a3f3 100644 --- a/core/tests/Drupal/Tests/WebAssert.php +++ b/core/tests/Drupal/Tests/WebAssert.php @@ -113,10 +113,10 @@ public function buttonNotExists($button, TraversableElement $container = NULL) { */ public function selectExists($select, TraversableElement $container = NULL) { $container = $container ?: $this->session->getPage(); - $node = $container->find('named', array( + $node = $container->find('named', [ 'select', $this->session->getSelectorsHandler()->xpathLiteral($select), - )); + ]); if ($node === NULL) { throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $select); @@ -143,16 +143,16 @@ public function selectExists($select, TraversableElement $container = NULL) { */ public function optionExists($select, $option, TraversableElement $container = NULL) { $container = $container ?: $this->session->getPage(); - $select_field = $container->find('named', array( + $select_field = $container->find('named', [ 'select', $this->session->getSelectorsHandler()->xpathLiteral($select), - )); + ]); if ($select_field === NULL) { throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $select); } - $option_field = $select_field->find('named', array('option', $option)); + $option_field = $select_field->find('named', ['option', $option]); if ($option_field === NULL) { throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $option); @@ -176,16 +176,16 @@ public function optionExists($select, $option, TraversableElement $container = N */ public function optionNotExists($select, $option, TraversableElement $container = NULL) { $container = $container ?: $this->session->getPage(); - $select_field = $container->find('named', array( + $select_field = $container->find('named', [ 'select', $this->session->getSelectorsHandler()->xpathLiteral($select), - )); + ]); if ($select_field === NULL) { throw new ElementNotFoundException($this->session, 'select', 'id|name|label|value', $select); } - $option_field = $select_field->find('named', array('option', $option)); + $option_field = $select_field->find('named', ['option', $option]); $this->assert($option_field === NULL, sprintf('An option "%s" exists in select "%s", but it should not.', $option, $select)); } @@ -231,6 +231,29 @@ public function linkExists($label, $index = 0, $message = '') { $this->assert(!empty($links[$index]), $message); } + /** + * Passes if a link with the exactly specified label is found. + * + * An optional link index may be passed. + * + * @param string $label + * Text between the anchor tags. + * @param int $index + * Link position counting from zero. + * @param string $message + * (optional) A message to display with the assertion. Do not translate + * messages: use strtr() to embed variables in the message text, not + * t(). If left blank, a default message will be displayed. + * + * @throws \Behat\Mink\Exception\ExpectationException + * Thrown when element doesn't exist, or the link label is a different one. + */ + public function linkExistsExact($label, $index = 0, $message = '') { + $message = ($message ? $message : strtr('Link with label %label found.', ['%label' => $label])); + $links = $this->session->getPage()->findAll('named_exact', ['link', $label]); + $this->assert(!empty($links[$index]), $message); + } + /** * Passes if a link with the specified label is not found. * @@ -247,11 +270,32 @@ public function linkExists($label, $index = 0, $message = '') { * Thrown when element doesn't exist, or the link label is a different one. */ public function linkNotExists($label, $message = '') { - $message = ($message ? $message : strtr('Link with label %label found.', ['%label' => $label])); + $message = ($message ? $message : strtr('Link with label %label not found.', ['%label' => $label])); $links = $this->session->getPage()->findAll('named', ['link', $label]); $this->assert(empty($links), $message); } + /** + * Passes if a link with the exactly specified label is not found. + * + * An optional link index may be passed. + * + * @param string $label + * Text between the anchor tags. + * @param string $message + * (optional) A message to display with the assertion. Do not translate + * messages: use strtr() to embed variables in the message text, not + * t(). If left blank, a default message will be displayed. + * + * @throws \Behat\Mink\Exception\ExpectationException + * Thrown when element doesn't exist, or the link label is a different one. + */ + public function linkNotExistsExact($label, $message = '') { + $message = ($message ? $message : strtr('Link with label %label not found.', ['%label' => $label])); + $links = $this->session->getPage()->findAll('named_exact', ['link', $label]); + $this->assert(empty($links), $message); + } + /** * Passes if a link containing a given href (part) is found. * @@ -291,7 +335,7 @@ public function linkByHrefExists($href, $index = 0, $message = '') { */ public function linkByHrefNotExists($href, $message = '') { $xpath = $this->buildXPathQuery('//a[contains(@href, :href)]', [':href' => $href]); - $message = ($message ? $message : strtr('Link containing href %href found.', ['%href' => $href])); + $message = ($message ? $message : strtr('No link containing href %href found.', ['%href' => $href])); $links = $this->session->getPage()->findAll('xpath', $xpath); $this->assert(empty($links), $message); } @@ -316,11 +360,11 @@ public function linkByHrefNotExists($href, $message = '') { * @return string * An XPath query with arguments replaced. */ - public function buildXPathQuery($xpath, array $args = array()) { + public function buildXPathQuery($xpath, array $args = []) { // Replace placeholders. foreach ($args as $placeholder => $value) { if (is_object($value)) { - throw new \InvalidArgumentException('Just pass in scalar values.'); + throw new \InvalidArgumentException('Just pass in scalar values for $args and remove all t() calls from your test.'); } // XPath 1.0 doesn't support a way to escape single or double quotes in a // string literal. We split double quotes out of the string, and encode @@ -422,4 +466,83 @@ public function fieldDisabled($field, TraversableElement $container = NULL) { return $node; } + /** + * Checks that specific hidden field exists. + * + * @param string $field + * One of id|name|value for the hidden field. + * @param \Behat\Mink\Element\TraversableElement $container + * (optional) The document to check against. Defaults to the current page. + * + * @return \Behat\Mink\Element\NodeElement + * The matching element. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + */ + public function hiddenFieldExists($field, TraversableElement $container = NULL) { + $container = $container ?: $this->session->getPage(); + if ($node = $container->find('hidden_field_selector', ['hidden_field', $field])) { + return $node; + } + throw new ElementNotFoundException($this->session->getDriver(), 'form hidden field', 'id|name|value', $field); + } + + /** + * Checks that specific hidden field does not exists. + * + * @param string $field + * One of id|name|value for the hidden field. + * @param \Behat\Mink\Element\TraversableElement $container + * (optional) The document to check against. Defaults to the current page. + * + * @throws \Behat\Mink\Exception\ExpectationException + */ + public function hiddenFieldNotExists($field, TraversableElement $container = NULL) { + $container = $container ?: $this->session->getPage(); + $node = $container->find('hidden_field_selector', ['hidden_field', $field]); + $this->assert($node === NULL, "A hidden field '$field' exists on this page, but it should not."); + } + + /** + * Checks that specific hidden field have provided value. + * + * @param string $field + * One of id|name|value for the hidden field. + * @param string $value + * The hidden field value that needs to be checked. + * @param \Behat\Mink\Element\TraversableElement $container + * (optional) The document to check against. Defaults to the current page. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * @throws \Behat\Mink\Exception\ExpectationException + */ + public function hiddenFieldValueEquals($field, $value, TraversableElement $container = NULL) { + $node = $this->hiddenFieldExists($field, $container); + $actual = $node->getValue(); + $regex = '/^' . preg_quote($value, '/') . '$/ui'; + $message = "The hidden field '$field' value is '$actual', but '$value' expected."; + $this->assert((bool) preg_match($regex, $actual), $message); + } + + /** + * Checks that specific hidden field doesn't have the provided value. + * + * @param string $field + * One of id|name|value for the hidden field. + * @param string $value + * The hidden field value that needs to be checked. + * @param \Behat\Mink\Element\TraversableElement $container + * (optional) The document to check against. Defaults to the current page. + * + * @throws \Behat\Mink\Exception\ElementNotFoundException + * @throws \Behat\Mink\Exception\ExpectationException + */ + public function hiddenFieldValueNotEquals($field, $value, TraversableElement $container = NULL) { + $node = $this->hiddenFieldExists($field, $container); + $actual = $node->getValue(); + $regex = '/^' . preg_quote($value, '/') . '$/ui'; + $message = "The hidden field '$field' value is '$actual', but it should not be."; + $this->assert(!preg_match($regex, $actual), $message); + } + } diff --git a/core/tests/Drupal/Tests/XdebugRequestTrait.php b/core/tests/Drupal/Tests/XdebugRequestTrait.php new file mode 100644 index 00000000..5da86a51 --- /dev/null +++ b/core/tests/Drupal/Tests/XdebugRequestTrait.php @@ -0,0 +1,48 @@ +cookies; + $cookies = []; + if ($cookie_params->has('XDEBUG_SESSION')) { + $cookies['XDEBUG_SESSION'][] = $cookie_params->get('XDEBUG_SESSION'); + } + // For CLI requests, the information is stored in $_SERVER. + $server = $request->server; + if ($server->has('XDEBUG_CONFIG')) { + // $_SERVER['XDEBUG_CONFIG'] has the form "key1=value1 key2=value2 ...". + $pairs = explode(' ', $server->get('XDEBUG_CONFIG')); + foreach ($pairs as $pair) { + list($key, $value) = explode('=', $pair); + // Account for key-value pairs being separated by multiple spaces. + if (trim($key, ' ') == 'idekey') { + $cookies['XDEBUG_SESSION'][] = trim($value, ' '); + } + } + } + return $cookies; + } + +} diff --git a/core/tests/README.md b/core/tests/README.md index 566fa23b..5dd6cc63 100644 --- a/core/tests/README.md +++ b/core/tests/README.md @@ -18,9 +18,9 @@ Note: functional tests have to be invoked with a user in the same group as the web server user. You can either configure Apache (or nginx) to run as your own system user or run tests as a privileged user instead. -To develop locally, a straigtforward - but also less secure - approach is to run -tests as your own system user. To achieve that, change the default Apache user -to run as your system user. Typically, you'd need to modify +To develop locally, a straightforward - but also less secure - approach is to +run tests as your own system user. To achieve that, change the default Apache +user to run as your system user. Typically, you'd need to modify `/etc/apache2/envvars` on Linux or `/etc/apache2/httpd.conf` on Mac. Example for Linux: diff --git a/core/tests/TestSuites/TestSuiteBase.php b/core/tests/TestSuites/TestSuiteBase.php index bd047e83..82a13ba2 100644 --- a/core/tests/TestSuites/TestSuiteBase.php +++ b/core/tests/TestSuites/TestSuiteBase.php @@ -1,6 +1,7 @@ getPathname(), '.info.yml') !== FALSE) { @@ -46,13 +46,13 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL) { if ($root === NULL) { $root = dirname(dirname(__DIR__)); } - $paths = array( + $paths = [ $root . '/core/modules', $root . '/core/profiles', $root . '/modules', $root . '/profiles', $root . '/themes', - ); + ]; $sites_path = $root . '/sites'; // Note this also checks sites/../modules and sites/../profiles. foreach (scandir($sites_path) as $site) { @@ -77,15 +77,28 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL) { * An associative array of extension directories, keyed by their namespace. */ function drupal_phpunit_get_extension_namespaces($dirs) { - $namespaces = array(); + $suite_names = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript']; + $namespaces = []; foreach ($dirs as $extension => $dir) { if (is_dir($dir . '/src')) { // Register the PSR-4 directory for module-provided classes. $namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src'; } - if (is_dir($dir . '/tests/src')) { - // Register the PSR-4 directory for PHPUnit test classes. - $namespaces['Drupal\\Tests\\' . $extension . '\\'][] = $dir . '/tests/src'; + $test_dir = $dir . '/tests/src'; + if (is_dir($test_dir)) { + foreach ($suite_names as $suite_name) { + $suite_dir = $test_dir . '/' . $suite_name; + if (is_dir($suite_dir)) { + // Register the PSR-4 directory for PHPUnit-based suites. + $namespaces['Drupal\\Tests\\' . $extension . '\\' . $suite_name . '\\'][] = $suite_dir; + } + } + // Extensions can have a \Drupal\extension\Traits namespace for + // cross-suite trait code. + $trait_dir = $test_dir . '/Traits'; + if (is_dir($trait_dir)) { + $namespaces['Drupal\\Tests\\' . $extension . '\\Traits\\'][] = $trait_dir; + } } } return $namespaces; @@ -123,7 +136,7 @@ function drupal_phpunit_populate_class_loader() { $extension_roots = drupal_phpunit_contrib_extension_directory_roots(); $dirs = array_map('drupal_phpunit_find_extension_directories', $extension_roots); - $dirs = array_reduce($dirs, 'array_merge', array()); + $dirs = array_reduce($dirs, 'array_merge', []); $GLOBALS['namespaces'] = drupal_phpunit_get_extension_namespaces($dirs); } foreach ($GLOBALS['namespaces'] as $prefix => $paths) { diff --git a/core/tests/fixtures/BrowserMissingDependentModuleMethodTest.php b/core/tests/fixtures/BrowserMissingDependentModuleMethodTest.php new file mode 100644 index 00000000..4a94a536 --- /dev/null +++ b/core/tests/fixtures/BrowserMissingDependentModuleMethodTest.php @@ -0,0 +1,35 @@ +fail('Running test with missing required module.'); + } + + /** + * Public access for checkRequirements() to avoid reflection. + */ + public function publicCheckRequirements() { + return parent::checkRequirements(); + } + +} diff --git a/core/tests/fixtures/BrowserMissingDependentModuleTest.php b/core/tests/fixtures/BrowserMissingDependentModuleTest.php new file mode 100644 index 00000000..9650fc1b --- /dev/null +++ b/core/tests/fixtures/BrowserMissingDependentModuleTest.php @@ -0,0 +1,37 @@ +fail('Running test with missing required module.'); + } + + /** + * Public access for checkRequirements() to avoid reflection. + */ + public function publicCheckRequirements() { + return parent::checkRequirements(); + } + +} diff --git a/core/tests/fixtures/KernelMissingDependentModuleMethodTest.php b/core/tests/fixtures/KernelMissingDependentModuleMethodTest.php new file mode 100644 index 00000000..33dc7938 --- /dev/null +++ b/core/tests/fixtures/KernelMissingDependentModuleMethodTest.php @@ -0,0 +1,33 @@ +fail('Running test with missing required module.'); + } + + /** + * Public access for checkRequirements() to avoid reflection. + */ + public function publicCheckRequirements() { + return parent::checkRequirements(); + } + +} diff --git a/core/tests/fixtures/KernelMissingDependentModuleTest.php b/core/tests/fixtures/KernelMissingDependentModuleTest.php new file mode 100644 index 00000000..3b8f316b --- /dev/null +++ b/core/tests/fixtures/KernelMissingDependentModuleTest.php @@ -0,0 +1,35 @@ +fail('Running test with missing required module.'); + } + + /** + * Public access for checkRequirements() to avoid reflection. + */ + public function publicCheckRequirements() { + return parent::checkRequirements(); + } + +} diff --git a/core/themes/bartik/bartik.info.yml b/core/themes/bartik/bartik.info.yml index e02414b9..0366a527 100644 --- a/core/themes/bartik/bartik.info.yml +++ b/core/themes/bartik/bartik.info.yml @@ -46,8 +46,8 @@ regions: footer_fourth: 'Footer fourth' footer_fifth: 'Footer fifth' -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme index b1b33082..1c408cf3 100644 --- a/core/themes/bartik/bartik.theme +++ b/core/themes/bartik/bartik.theme @@ -45,14 +45,14 @@ function bartik_preprocess_page_title(&$variables) { if (!empty($variables['title_suffix']['add_or_remove_shortcut']) && $variables['title']) { // Add a wrapper div using the title_prefix and title_suffix render // elements. - $variables['title_prefix']['shortcut_wrapper'] = array( + $variables['title_prefix']['shortcut_wrapper'] = [ '#markup' => '
    ', '#weight' => 100, - ); - $variables['title_suffix']['shortcut_wrapper'] = array( + ]; + $variables['title_suffix']['shortcut_wrapper'] = [ '#markup' => '
    ', '#weight' => -99, - ); + ]; // Make sure the shortcut link is the first item in title_suffix. $variables['title_suffix']['add_or_remove_shortcut']['#weight'] = -100; } diff --git a/core/themes/bartik/color/color.inc b/core/themes/bartik/color/color.inc index 4f42620d..55464f24 100644 --- a/core/themes/bartik/color/color.inc +++ b/core/themes/bartik/color/color.inc @@ -5,9 +5,9 @@ * Lists available colors and color schemes for the Bartik theme. */ -$info = array( +$info = [ // Available colors and color labels used in theme. - 'fields' => array( + 'fields' => [ 'top' => t('Header background top'), 'bottom' => t('Header background bottom'), 'bg' => t('Main background'), @@ -17,12 +17,12 @@ $info = array( 'titleslogan' => t('Title and slogan'), 'text' => t('Text color'), 'link' => t('Link color'), - ), + ], // Pre-defined color schemes. - 'schemes' => array( - 'default' => array( + 'schemes' => [ + 'default' => [ 'title' => t('Blue Lagoon (default)'), - 'colors' => array( + 'colors' => [ 'top' => '#055a8e', 'bottom' => '#1d84c3', 'bg' => '#ffffff', @@ -32,11 +32,11 @@ $info = array( 'titleslogan' => '#fffeff', 'text' => '#3b3b3b', 'link' => '#0071B3', - ), - ), - 'firehouse' => array( + ], + ], + 'firehouse' => [ 'title' => t('Firehouse'), - 'colors' => array( + 'colors' => [ 'top' => '#cd2d2d', 'bottom' => '#d64e4e', 'bg' => '#ffffff', @@ -46,11 +46,11 @@ $info = array( 'titleslogan' => '#fffeff', 'text' => '#888888', 'link' => '#d6121f', - ), - ), - 'ice' => array( + ], + ], + 'ice' => [ 'title' => t('Ice'), - 'colors' => array( + 'colors' => [ 'top' => '#d0d0d0', 'bottom' => '#c2c4c5', 'bg' => '#ffffff', @@ -60,11 +60,11 @@ $info = array( 'titleslogan' => '#000000', 'text' => '#4a4a4a', 'link' => '#019dbf', - ), - ), - 'plum' => array( + ], + ], + 'plum' => [ 'title' => t('Plum'), - 'colors' => array( + 'colors' => [ 'top' => '#4c1c58', 'bottom' => '#593662', 'bg' => '#fffdf7', @@ -74,11 +74,11 @@ $info = array( 'titleslogan' => '#ffffff', 'text' => '#301313', 'link' => '#9d408d', - ), - ), - 'slate' => array( + ], + ], + 'slate' => [ 'title' => t('Slate'), - 'colors' => array( + 'colors' => [ 'top' => '#4a4a4a', 'bottom' => '#4e4e4e', 'bg' => '#ffffff', @@ -88,31 +88,31 @@ $info = array( 'titleslogan' => '#ffffff', 'text' => '#3b3b3b', 'link' => '#0073b6', - ), - ), - ), + ], + ], + ], // CSS files (excluding @import) to rewrite with new color scheme. - 'css' => array( + 'css' => [ 'css/colors.css', - ), + ], // Files to copy. - 'copy' => array( + 'copy' => [ 'logo.svg', - ), + ], // Gradient definitions. - 'gradients' => array( - array( + 'gradients' => [ + [ // (x, y, width, height). - 'dimension' => array(0, 0, 0, 0), + 'dimension' => [0, 0, 0, 0], // Direction of gradient ('vertical' or 'horizontal'). 'direction' => 'vertical', // Keys of colors to use for the gradient. - 'colors' => array('top', 'bottom'), - ), - ), + 'colors' => ['top', 'bottom'], + ], + ], // Preview files. 'preview_library' => 'bartik/color.preview', @@ -127,4 +127,4 @@ $info = array( ], ], ], -); +]; diff --git a/core/themes/bartik/color/preview.css b/core/themes/bartik/color/preview.css index ac561d39..48c124e8 100644 --- a/core/themes/bartik/color/preview.css +++ b/core/themes/bartik/color/preview.css @@ -78,7 +78,7 @@ } [dir="rtl"] .color-preview-sidebar, [dir="rtl"] .color-preview-content { - float: right; + float: right; } .color-preview-sidebar { margin-left: 15px; /* LTR */ diff --git a/core/themes/bartik/color/preview.es6.js b/core/themes/bartik/color/preview.es6.js new file mode 100644 index 00000000..90d3b421 --- /dev/null +++ b/core/themes/bartik/color/preview.es6.js @@ -0,0 +1,46 @@ +/** + * @file + * Preview for the Bartik theme. + */ +(function ($, Drupal, drupalSettings) { + Drupal.color = { + logoChanged: false, + callback(context, settings, $form) { + // Change the logo to be the real one. + if (!this.logoChanged) { + $('.color-preview .color-preview-logo img').attr('src', drupalSettings.color.logo); + this.logoChanged = true; + } + // Remove the logo if the setting is toggled off. + if (drupalSettings.color.logo === null) { + $('div').remove('.color-preview-logo'); + } + + const $colorPreview = $form.find('.color-preview'); + const $colorPalette = $form.find('.js-color-palette'); + + // Solid background. + $colorPreview.css('backgroundColor', $colorPalette.find('input[name="palette[bg]"]').val()); + + // Text preview. + $colorPreview.find('.color-preview-main h2, .color-preview .preview-content').css('color', $colorPalette.find('input[name="palette[text]"]').val()); + $colorPreview.find('.color-preview-content a').css('color', $colorPalette.find('input[name="palette[link]"]').val()); + + // Sidebar block. + const $colorPreviewBlock = $colorPreview.find('.color-preview-sidebar .color-preview-block'); + $colorPreviewBlock.css('background-color', $colorPalette.find('input[name="palette[sidebar]"]').val()); + $colorPreviewBlock.css('border-color', $colorPalette.find('input[name="palette[sidebarborders]"]').val()); + + // Footer wrapper background. + $colorPreview.find('.color-preview-footer-wrapper').css('background-color', $colorPalette.find('input[name="palette[footer]"]').val()); + + // CSS3 Gradients. + const gradient_start = $colorPalette.find('input[name="palette[top]"]').val(); + const gradient_end = $colorPalette.find('input[name="palette[bottom]"]').val(); + + $colorPreview.find('.color-preview-header').attr('style', `background-color: ${gradient_start}; background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(${gradient_start}), to(${gradient_end})); background-image: -moz-linear-gradient(-90deg, ${gradient_start}, ${gradient_end});`); + + $colorPreview.find('.color-preview-site-name').css('color', $colorPalette.find('input[name="palette[titleslogan]"]').val()); + }, + }; +}(jQuery, Drupal, drupalSettings)); diff --git a/core/themes/bartik/color/preview.js b/core/themes/bartik/color/preview.js index da8e0ca4..025bbc9a 100644 --- a/core/themes/bartik/color/preview.js +++ b/core/themes/bartik/color/preview.js @@ -1,20 +1,19 @@ /** - * @file - * Preview for the Bartik theme. - */ -(function ($, Drupal, drupalSettings) { - - 'use strict'; +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ +(function ($, Drupal, drupalSettings) { Drupal.color = { logoChanged: false, - callback: function (context, settings, $form) { - // Change the logo to be the real one. + callback: function callback(context, settings, $form) { if (!this.logoChanged) { $('.color-preview .color-preview-logo img').attr('src', drupalSettings.color.logo); this.logoChanged = true; } - // Remove the logo if the setting is toggled off. + if (drupalSettings.color.logo === null) { $('div').remove('.color-preview-logo'); } @@ -22,22 +21,17 @@ var $colorPreview = $form.find('.color-preview'); var $colorPalette = $form.find('.js-color-palette'); - // Solid background. $colorPreview.css('backgroundColor', $colorPalette.find('input[name="palette[bg]"]').val()); - // Text preview. $colorPreview.find('.color-preview-main h2, .color-preview .preview-content').css('color', $colorPalette.find('input[name="palette[text]"]').val()); $colorPreview.find('.color-preview-content a').css('color', $colorPalette.find('input[name="palette[link]"]').val()); - // Sidebar block. var $colorPreviewBlock = $colorPreview.find('.color-preview-sidebar .color-preview-block'); $colorPreviewBlock.css('background-color', $colorPalette.find('input[name="palette[sidebar]"]').val()); $colorPreviewBlock.css('border-color', $colorPalette.find('input[name="palette[sidebarborders]"]').val()); - // Footer wrapper background. $colorPreview.find('.color-preview-footer-wrapper').css('background-color', $colorPalette.find('input[name="palette[footer]"]').val()); - // CSS3 Gradients. var gradient_start = $colorPalette.find('input[name="palette[top]"]').val(); var gradient_end = $colorPalette.find('input[name="palette[bottom]"]').val(); @@ -46,4 +40,4 @@ $colorPreview.find('.color-preview-site-name').css('color', $colorPalette.find('input[name="palette[titleslogan]"]').val()); } }; -})(jQuery, Drupal, drupalSettings); +})(jQuery, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/themes/bartik/css/base/elements.css b/core/themes/bartik/css/base/elements.css index ac475669..645cefa5 100644 --- a/core/themes/bartik/css/base/elements.css +++ b/core/themes/bartik/css/base/elements.css @@ -132,7 +132,8 @@ img { max-width: 100%; height: auto; } -ul, ol { +ul, +ol { margin: 0; padding: 0 0 0.25em 1em; /* LTR */ } diff --git a/core/themes/bartik/css/components/comments.css b/core/themes/bartik/css/components/comments.css index a80e0492..5acf4d52 100644 --- a/core/themes/bartik/css/components/comments.css +++ b/core/themes/bartik/css/components/comments.css @@ -49,7 +49,6 @@ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 0.733em; line-height: 1.2; - } .comment__permalink { font-size: 0.733em; diff --git a/core/themes/bartik/css/components/form.css b/core/themes/bartik/css/components/form.css index 3e469207..672e5911 100644 --- a/core/themes/bartik/css/components/form.css +++ b/core/themes/bartik/css/components/form.css @@ -172,6 +172,14 @@ input.form-submit:focus { .node-form .form-wrapper { margin-bottom: 2em; } +.node-form .node-form-footer, +.node-form .field--name-status { + margin-bottom: 0; +} +.node-form .form-actions { + padding-top: 0; + margin-top: 0; +} /* Contact Form */ .contact-form #edit-name { @@ -316,7 +324,9 @@ input.form-submit:focus { -moz-box-sizing: border-box; } - .js .dropbutton .dropbutton-action > input, .js .dropbutton .dropbutton-action > a, .js .dropbutton .dropbutton-action > button { + .js .dropbutton .dropbutton-action > input, + .js .dropbutton .dropbutton-action > a, + .js .dropbutton .dropbutton-action > button { text-align: center; padding-left: 3em; } diff --git a/core/themes/bartik/css/components/header.css b/core/themes/bartik/css/components/header.css index 40ea0f0a..52ab1c62 100644 --- a/core/themes/bartik/css/components/header.css +++ b/core/themes/bartik/css/components/header.css @@ -21,7 +21,7 @@ } .region-header .site-branding { float: left; /* LTR */ - /* margin-bottom: 1.857em;*/ + /* margin-bottom: 1.857em; */ } [dir="rtl"] .region-header .site-branding { float: right; diff --git a/core/themes/bartik/css/components/menu.css b/core/themes/bartik/css/components/menu.css index efde5d20..f7a3fd00 100644 --- a/core/themes/bartik/css/components/menu.css +++ b/core/themes/bartik/css/components/menu.css @@ -6,7 +6,7 @@ /* This is needed to override ul.menu styles in menu.theme.css */ ul.menu { margin: 0; - padding: 0 0 0.25em 0; + padding: 0 0 0.25em 1em; } /* This is needed to override [dir="rtl"] ul.menu styles in menu.theme.css */ diff --git a/core/themes/bartik/css/maintenance-page.css b/core/themes/bartik/css/maintenance-page.css index 1196a220..eb1a3d0c 100644 --- a/core/themes/bartik/css/maintenance-page.css +++ b/core/themes/bartik/css/maintenance-page.css @@ -49,7 +49,7 @@ body.maintenance-page { .maintenance-page .site-branding-text a:focus { color: #777; } -.maintenance-page .page-title { +.maintenance-page .page-title { line-height: 1em; margin-top: 0; } diff --git a/core/themes/classy/README.txt b/core/themes/classy/README.txt index a5181239..52bf17a6 100644 --- a/core/themes/classy/README.txt +++ b/core/themes/classy/README.txt @@ -8,10 +8,11 @@ To use Classy as your base theme, set the 'base theme' in your theme's .info.yml file to "classy": base theme: classy -See https://www.drupal.org/theme-guide/8/classy for more information on using -the Classy theme. +See https://www.drupal.org/docs/8/theming-drupal-8/using-classy-as-a-base-theme +for more information on using the Classy theme. ABOUT DRUPAL THEMING -------------------- -See https://www.drupal.org/theme-guide/8 for more information on Drupal theming. +See https://www.drupal.org/docs/8/theming for more information on Drupal +theming. diff --git a/core/themes/classy/classy.info.yml b/core/themes/classy/classy.info.yml index b44ca6b5..3cc7fc2e 100644 --- a/core/themes/classy/classy.info.yml +++ b/core/themes/classy/classy.info.yml @@ -1,6 +1,6 @@ name: Classy type: theme -description: 'A base theme with sensible default CSS classes added. Learn how to use Classy as a base theme in the Drupal 8 Theming Guide.' +description: 'A base theme with sensible default CSS classes added. Learn how to use Classy as a base theme in the Drupal 8 Theming Guide.' package: Core # version: VERSION # core: 8.x @@ -8,6 +8,7 @@ hidden: true libraries: - classy/base + - classy/messages - core/normalize libraries-extend: @@ -22,8 +23,8 @@ libraries-extend: core/drupal.progress: - classy/progress -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/themes/classy/classy.libraries.yml b/core/themes/classy/classy.libraries.yml index eb5e0b25..f970f86b 100644 --- a/core/themes/classy/classy.libraries.yml +++ b/core/themes/classy/classy.libraries.yml @@ -56,6 +56,12 @@ forum: component: css/components/forum.css: { weight: -10 } +image-widget: + version: VERSION + css: + component: + css/components/image-widget.css: {} + indented: version: VERSION css: diff --git a/core/themes/classy/css/components/field.css b/core/themes/classy/css/components/field.css index 0ef4c2d8..daa8fb5d 100644 --- a/core/themes/classy/css/components/field.css +++ b/core/themes/classy/css/components/field.css @@ -8,7 +8,7 @@ } .field--label-inline .field__label, .field--label-inline .field__items { - float: left; /*LTR*/ + float: left; /* LTR */ } .field--label-inline .field__label, .field--label-inline > .field__item, diff --git a/core/themes/classy/css/components/file.css b/core/themes/classy/css/components/file.css index 5e16b4f7..8bb31249 100644 --- a/core/themes/classy/css/components/file.css +++ b/core/themes/classy/css/components/file.css @@ -3,7 +3,7 @@ * Default style for file module. */ -/* File icons.*/ +/* File icons. */ .file { padding-left: 20px; /* LTR */ diff --git a/core/themes/classy/css/components/form.css b/core/themes/classy/css/components/form.css index 15b8ec23..97b94fe8 100644 --- a/core/themes/classy/css/components/form.css +++ b/core/themes/classy/css/components/form.css @@ -8,13 +8,13 @@ form .field-multiple-table { } form .field-multiple-table .field-multiple-drag { width: 30px; - padding-right: 0; /*LTR*/ + padding-right: 0; /* LTR */ } [dir="rtl"] form .field-multiple-table .field-multiple-drag { padding-left: 0; } form .field-multiple-table .field-multiple-drag .tabledrag-handle { - padding-right: .5em; /*LTR*/ + padding-right: .5em; /* LTR */ } [dir="rtl"] form .field-multiple-table .field-multiple-drag .tabledrag-handle { padding-right: 0; @@ -64,8 +64,8 @@ label.option { } [dir="rtl"] .form-type-radio .description, [dir="rtl"] .form-type-checkbox .description { - margin-left: 0; - margin-right: 2.4em; + margin-left: 0; + margin-right: 2.4em; } .marker { color: #e00; diff --git a/core/themes/classy/css/components/image-widget.css b/core/themes/classy/css/components/image-widget.css index 3da51ef8..56777c41 100644 --- a/core/themes/classy/css/components/image-widget.css +++ b/core/themes/classy/css/components/image-widget.css @@ -1,7 +1,19 @@ - /** + * @file * Image upload widget. + * + * This CSS file is not used in this theme (Classy). It was intended to be used, + * but due to a bug, Drupal 8 shipped with it not being used. To not break + * backwards compatibility, we continue to not load it in Classy. Every + * subtheme of Classy is encouraged to use it, by attaching the + * classy/image-widget asset library in their image-widget.html.twig file. + * + * @see core/themes/seven/templates/content-edit/image-widget.html.twig. + * + * @todo In Drupal 9, let core/themes/classy/templates/content-edit/image-widget.html.twig + * attach the classy/image-widget asset library. */ + .image-preview { float: left; /* LTR */ padding: 0 10px 10px 0; /* LTR */ diff --git a/core/themes/classy/css/components/progress.css b/core/themes/classy/css/components/progress.css index 1fb80a60..60bc123c 100644 --- a/core/themes/classy/css/components/progress.css +++ b/core/themes/classy/css/components/progress.css @@ -17,27 +17,14 @@ border: 1px #07629a solid; background: #057ec9; background-image: - -webkit-linear-gradient( top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15) ), - -webkit-linear-gradient( left top, - #0094f0 0%, - #0094f0 25%, - #007ecc 25%, - #007ecc 50%, - #0094f0 50%, - #0094f0 75%, - #0094f0 100% ); + -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)), + -webkit-linear-gradient(left top, #0094f0 0%, #0094f0 25%, #007ecc 25%, #007ecc 50%, #0094f0 50%, #0094f0 75%, #0094f0 100%); background-image: - -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)), -webkit-linear-gradient(left top, #0094f0 0%, #0094f0 25%, #007ecc 25%, #007ecc 50%, #0094f0 50%, #0094f0 75%, #0094f0 100%); + -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)), + -webkit-linear-gradient(left top, #0094f0 0%, #0094f0 25%, #007ecc 25%, #007ecc 50%, #0094f0 50%, #0094f0 75%, #0094f0 100%); background-image: - linear-gradient( to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15) ), - linear-gradient( to right bottom, - #0094f0 0%, - #0094f0 25%, - #007ecc 25%, - #007ecc 50%, - #0094f0 50%, - #0094f0 75%, - #0094f0 100% ); + linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)), + linear-gradient(to right bottom, #0094f0 0%, #0094f0 25%, #007ecc 25%, #007ecc 50%, #0094f0 50%, #0094f0 75%, #0094f0 100%); background-size: 40px 40px; margin-top: -1px; margin-left: -1px; /* LTR */ @@ -61,11 +48,14 @@ * Progress bar animations. */ @-webkit-keyframes animate-stripes { - 0% {background-position: 0 0, 0 0;} 100% {background-position: 0 0, -80px 0;} + 0% { background-position: 0 0, 0 0; } + 100% { background-position: 0 0, -80px 0; } } @-ms-keyframes animate-stripes { - 0% {background-position: 0 0, 0 0;} 100% {background-position: 0 0, -80px 0;} + 0% { background-position: 0 0, 0 0; } + 100% { background-position: 0 0, -80px 0; } } @keyframes animate-stripes { - 0% {background-position: 0 0, 0 0;} 100% {background-position: 0 0, -80px 0;} + 0% { background-position: 0 0, 0 0; } + 100% { background-position: 0 0, -80px 0; } } diff --git a/core/themes/classy/templates/content-edit/image-widget.html.twig b/core/themes/classy/templates/content-edit/image-widget.html.twig index 5e8033ff..dac3a227 100644 --- a/core/themes/classy/templates/content-edit/image-widget.html.twig +++ b/core/themes/classy/templates/content-edit/image-widget.html.twig @@ -10,7 +10,6 @@ * @see template_preprocess_image_widget() */ #} -{{ attach_library('classy/image-widget') }} {% if data.preview %}
    diff --git a/core/themes/classy/templates/content/media.html.twig b/core/themes/classy/templates/content/media.html.twig new file mode 100644 index 00000000..f36975cb --- /dev/null +++ b/core/themes/classy/templates/content/media.html.twig @@ -0,0 +1,27 @@ +{# +/** + * @file + * Theme override to display a media item. + * + * Available variables: + * - name: Name of the media. + * - content: Media content. + * + * @see template_preprocess_media() + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'media', + 'media--type-' ~ media.bundle()|clean_class, + not media.isPublished() ? 'media--unpublished', + view_mode ? 'media--view-mode-' ~ view_mode.id()|clean_class, + ] +%} + + {% if content %} + {{ content }} + {% endif %} + diff --git a/core/themes/classy/templates/form/datetime-wrapper.html.twig b/core/themes/classy/templates/form/datetime-wrapper.html.twig index 3f6aa59d..5b52f2da 100644 --- a/core/themes/classy/templates/form/datetime-wrapper.html.twig +++ b/core/themes/classy/templates/form/datetime-wrapper.html.twig @@ -30,5 +30,7 @@
    {% endif %} {% if description %} -
    {{ description }}
    + + {{ description }} + {% endif %} diff --git a/core/themes/classy/templates/misc/status-messages.html.twig b/core/themes/classy/templates/misc/status-messages.html.twig index bc8fd106..282df38e 100644 --- a/core/themes/classy/templates/misc/status-messages.html.twig +++ b/core/themes/classy/templates/misc/status-messages.html.twig @@ -21,7 +21,6 @@ * - class: HTML classes. */ #} -{{ attach_library('classy/messages') }} {% block messages %} {% for type, messages in message_list %} {% diff --git a/core/themes/classy/templates/user/username.html.twig b/core/themes/classy/templates/user/username.html.twig index 5a6c3a55..df694dff 100644 --- a/core/themes/classy/templates/user/username.html.twig +++ b/core/themes/classy/templates/user/username.html.twig @@ -5,10 +5,16 @@ * * Available variables: * - account: The full account information for the user. - * - name: The user's name, sanitized. + * - uid: The user ID, or zero if not a user. As used in anonymous comments. + * - name: The user's name, sanitized, and optionally truncated. + * - name_raw: The user's name, un-truncated. + * - truncated: Whether the user's name was truncated. * - extra: Additional text to append to the user's name, sanitized. + * - profile_access: Whether the current user has permission to access this + users profile page. * - link_path: The path or URL of the user's profile page, home page, * or other desired page to link to for more information about the user. + * - homepage: (optional) The home page of the account, only set for non users. * - link_options: Options to set on the \Drupal\Core\Url object if linking the * user's name to the user's page. * - attributes: HTML attributes for the containing element. diff --git a/core/themes/classy/templates/views/views-view-opml.html.twig b/core/themes/classy/templates/views/views-view-opml.html.twig index a48843ae..4165ccf4 100644 --- a/core/themes/classy/templates/views/views-view-opml.html.twig +++ b/core/themes/classy/templates/views/views-view-opml.html.twig @@ -11,7 +11,7 @@ * @see template_preprocess_views_view_opml() */ #} - + {{ title }} diff --git a/core/themes/classy/templates/views/views-view-rss.html.twig b/core/themes/classy/templates/views/views-view-rss.html.twig index f772d637..0800237e 100644 --- a/core/themes/classy/templates/views/views-view-rss.html.twig +++ b/core/themes/classy/templates/views/views-view-rss.html.twig @@ -15,7 +15,7 @@ * @see template_preprocess_views_view_rss() */ #} - + {{ title }} diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index c8f8f491..177e01a5 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -13,7 +13,7 @@ use Drupal\Core\Extension\Extension; * Implements hook_theme(). */ function twig_theme($existing, $type, $theme, $path) { - $templates = drupal_find_theme_functions($existing, array($theme)); + $templates = drupal_find_theme_functions($existing, [$theme]); $templates += drupal_find_theme_templates($existing, '.html.twig', $path); return $templates; } @@ -128,7 +128,7 @@ function twig_render_template($template_file, array $variables) { * * @param array|object $element * The parent renderable array to exclude the child items. - * @param string[] $args, ... + * @param string[] ... * The string keys of $element to prevent printing. * * @return array diff --git a/core/themes/engines/twig/twig.info.yml b/core/themes/engines/twig/twig.info.yml index 407c3b87..247bdeeb 100644 --- a/core/themes/engines/twig/twig.info.yml +++ b/core/themes/engines/twig/twig.info.yml @@ -4,8 +4,8 @@ name: Twig # version: VERSION package: Core -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/themes/seven/css/base/elements.css b/core/themes/seven/css/base/elements.css index 6644ceae..51f19f03 100644 --- a/core/themes/seven/css/base/elements.css +++ b/core/themes/seven/css/base/elements.css @@ -172,3 +172,7 @@ details summary:focus, details summary:hover { text-decoration: underline; } +img { + max-width: 100%; + height: auto; +} diff --git a/core/themes/seven/css/base/print.css b/core/themes/seven/css/base/print.css index 653e5113..c432ccb5 100644 --- a/core/themes/seven/css/base/print.css +++ b/core/themes/seven/css/base/print.css @@ -42,7 +42,8 @@ color: #000; text-decoration: underline; } - .button, .button--primary { + .button, + .button--primary { background: none !important; } .messages { @@ -70,7 +71,17 @@ background: none; border-radius: 4px; } - input.form-autocomplete, input.form-text, input.form-tel, input.form-email, input.form-url, input.form-search, input.form-number, input.form-color, input.form-file, textarea.form-textarea, select.form-select { + input.form-autocomplete, + input.form-text, + input.form-tel, + input.form-email, + input.form-url, + input.form-search, + input.form-number, + input.form-color, + input.form-file, + textarea.form-textarea, + select.form-select { border-width: 1px; } } diff --git a/core/themes/seven/css/components/dialog.css b/core/themes/seven/css/components/dialog.css index 99aaa539..6d018208 100644 --- a/core/themes/seven/css/components/dialog.css +++ b/core/themes/seven/css/components/dialog.css @@ -60,7 +60,7 @@ } .ui-dialog .ui-widget-content.ui-dialog-buttonpane { background: #f5f5f2; - /*border-top: 1px solid #bfbfbf;*/ + /* border-top: 1px solid #bfbfbf; */ margin: 0; padding: 15px 20px; border-bottom-left-radius: 5px; diff --git a/core/themes/seven/css/components/dropbutton.component.css b/core/themes/seven/css/components/dropbutton.component.css index 229f1bdd..2cf01410 100644 --- a/core/themes/seven/css/components/dropbutton.component.css +++ b/core/themes/seven/css/components/dropbutton.component.css @@ -169,7 +169,7 @@ .dropbutton-single .dropbutton-action a { padding: 4px 1.5em; border: 1px solid #a6a6a6; - border-radius: 20em!important; + border-radius: 20em !important; background-color: #f2f1eb; background-image: -webkit-linear-gradient(top, #f6f6f3, #e7e7df); background-image: linear-gradient(to bottom, #f6f6f3, #e7e7df); @@ -180,7 +180,7 @@ -webkit-transition: all 0.1s; transition: all 0.1s; -webkit-font-smoothing: antialiased; - width: auto!important; + width: auto !important; } .dropbutton-single .dropbutton-action a:hover, .dropbutton-single .dropbutton-action a:focus { @@ -203,6 +203,9 @@ -webkit-transition: none; transition: none; } +.dropbutton-single .dropbutton-action a.use-ajax { + float: left; +} /** * The dropdown trigger. diff --git a/core/themes/seven/css/components/entity-meta.css b/core/themes/seven/css/components/entity-meta.css index 9877ec33..f6999bea 100644 --- a/core/themes/seven/css/components/entity-meta.css +++ b/core/themes/seven/css/components/entity-meta.css @@ -17,6 +17,8 @@ padding: 1em 1.5em; } .entity-meta__title { + font-size: 1.231em; + font-weight: bold; text-shadow: 0 1px 0 #fff; margin: 0.25em 0; } @@ -55,5 +57,5 @@ text-shadow: 0 1px 0 white; } .entity-meta details .summary { - display: none; /* Hide JS summaries. @todo Rethink summaries. */ + display: none; /* Hide JS summaries. @todo Rethink summaries. */ } diff --git a/core/themes/seven/css/components/form.css b/core/themes/seven/css/components/form.css index f3acc2c0..0db30e83 100644 --- a/core/themes/seven/css/components/form.css +++ b/core/themes/seven/css/components/form.css @@ -127,7 +127,6 @@ label[for] { padding: 0.25em 0.666em 0; } - /* Filter */ ul.tips, div.description, @@ -254,8 +253,9 @@ select { } select:focus, select:hover { - background-image: url(../../../../misc/icons/333333/caret-down.svg), - -webkit-linear-gradient(top, #fcfcfa, #e9e9dd); + background-image: + url(../../../../misc/icons/333333/caret-down.svg), + -webkit-linear-gradient(top, #fcfcfa, #e9e9dd); color: #1a1a1a; } select:hover { diff --git a/core/themes/seven/css/components/jquery.ui/theme.css b/core/themes/seven/css/components/jquery.ui/theme.css index 02dc83d1..dd81ec26 100644 --- a/core/themes/seven/css/components/jquery.ui/theme.css +++ b/core/themes/seven/css/components/jquery.ui/theme.css @@ -33,8 +33,6 @@ .ui-state-active, .ui-widget-content .ui-state-active { color: #840; - background: #fe6; - border: solid 1px #ed5; } .ui-state-error, .ui-widget-content .ui-state-error { diff --git a/core/themes/seven/css/components/media.css b/core/themes/seven/css/components/media.css new file mode 100644 index 00000000..34b15994 --- /dev/null +++ b/core/themes/seven/css/components/media.css @@ -0,0 +1,3 @@ +.media-form .field--name-status { + margin-top: 1.5em; +} diff --git a/core/themes/seven/css/components/messages.css b/core/themes/seven/css/components/messages.css index c23a4d11..8b521ccf 100644 --- a/core/themes/seven/css/components/messages.css +++ b/core/themes/seven/css/components/messages.css @@ -10,12 +10,18 @@ .messages pre { margin: 0; } -.messages h1, .messages .heading-a, -.messages h2, .messages .heading-b, -.messages h3, .messages .heading-c, -.messages h4, .messages .heading-d, -.messages h5, .messages .heading-e, -.messages h6, .messages .heading-f { +.messages h1, +.messages .heading-a, +.messages h2, +.messages .heading-b, +.messages h3, +.messages .heading-c, +.messages h4, +.messages .heading-d, +.messages h5, +.messages .heading-e, +.messages h6, +.messages .heading-f { margin-top: 0; } diff --git a/core/themes/seven/css/components/system-status-counter.css b/core/themes/seven/css/components/system-status-counter.css new file mode 100644 index 00000000..8d71965f --- /dev/null +++ b/core/themes/seven/css/components/system-status-counter.css @@ -0,0 +1,87 @@ +/** + * @file + * Styles for the system status counter component. + */ + +.system-status-counter { + box-sizing: border-box; + overflow-y: hidden; + border: 1px solid #e6e4df; + border-radius: 3px; + display: inline-block; + width: 100%; + white-space: nowrap; + background: #FCFCFA; +} +.system-status-counter__status-icon { + display: inline-block; + height: 60px; + width: 60px; + vertical-align: middle; + border-right: 1px solid #e6e4df; /* LTR */ + border-left: 0; /* LTR */ + background-color: #faf9f5; + box-shadow: 0 1px 1px rgba(0, 0, 0, .1) inset; +} +[dir="rtl"] .system-status-counter__status-icon { + border-right: 0; + border-left: 1px solid #e6e4df; + box-shadow: 0 1px 1px rgba(0, 0, 0, .1) inset; +} +.system-status-counter__status-icon:before { + content: ""; + background-size: 25px; + background-position: 50% center; + background-repeat: no-repeat; + width: 100%; + height: 100%; + display: block; +} + +.system-status-counter__status-icon--error:before { + background-image: url(../../../stable/images/core/icons/e32700/error.svg); +} +.system-status-counter__status-icon--warning:before { + background-image: url(../../../stable/images/core/icons/e29700/warning.svg); +} +.system-status-counter__status-icon--checked:before { + background-image: url(../../../stable/images/core/icons/73b355/check.svg); +} + +.system-status-counter__status-title { + display: inline-block; + vertical-align: middle; + text-transform: uppercase; + padding: 0 6px; + font-size: 1rem; + line-height: 1em; + font-weight: bold; +} +.system-status-counter__title-count { + display: block; + margin-bottom: 2px; +} +.system-status-counter__details { + font-size: 12px; + font-weight: normal; + text-transform: none; + display: block; + line-height: 1.5; +} + +@media screen and (min-width: 61em) { + .system-status-counter__status-icon, + .system-status-counter { + height: 65px; + } + .system-status-counter__status-icon { + width: 65px; + } + .system-status-counter__status-title { + font-size: 16px; + padding: 10px 3%; + } + .system-status-counter__status-icon:before { + background-size: 35px; + } +} diff --git a/core/themes/seven/css/components/system-status-report-counters.css b/core/themes/seven/css/components/system-status-report-counters.css new file mode 100644 index 00000000..a8e6db32 --- /dev/null +++ b/core/themes/seven/css/components/system-status-report-counters.css @@ -0,0 +1,26 @@ +/** + * @file + * Styles for the system status report counters. + */ + +.system-status-report-counters__item { + margin: 10px 0; + width: 100%; +} + +@media screen and (min-width: 60em) { + .system-status-report-counters__item { + margin-bottom: 20px; + } + .system-status-report-counters { + flex-wrap: wrap; + display: flex; + justify-content: space-between; + } + .system-status-report-counters__item--half-width { + width: 49%; + } + .system-status-report-counters__item--third-width { + width: 32%; + } +} diff --git a/core/themes/seven/css/components/system-status-report-general-info.css b/core/themes/seven/css/components/system-status-report-general-info.css new file mode 100644 index 00000000..08ee9774 --- /dev/null +++ b/core/themes/seven/css/components/system-status-report-general-info.css @@ -0,0 +1,161 @@ +/** + * @file + * Seven styles for the System Status general info. + */ + +.system-status-general-info { + border: 1px solid #ccc; + border-radius: 3px; +} + +.system-status-general-info__header { + background-color: #f5f5f2; + padding: 10px; + margin: 0; + overflow: hidden; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + font-size: 14px; + text-transform: uppercase; +} + +.system-status-general-info__item { + background: #fcfcfa; + border-top: 1px solid #ccc; + padding: 10px 10px 20px; + box-sizing: border-box; + overflow-x: auto; +} + +.system-status-general-info__item-icon { + display: inline-block; + height: 45px; + width: 45px; + vertical-align: top; +} +.system-status-general-info__item-icon:before { + content: ""; + background-size: 35px; + background-position: 50% center; + background-repeat: no-repeat; + width: 100%; + height: 100%; + display: block; +} +.system-status-general-info__item-icon--d8:before { + background-image: url(../../images/icons/cccccc/d8-logo.svg); +} +.system-status-general-info__item-icon--clock:before { + background-image: url(../../images/icons/cccccc/clock.svg); +} +.system-status-general-info__item-icon--server:before { + background-image: url(../../images/icons/cccccc/server.svg); +} +.system-status-general-info__item-icon--php:before { + background-image: url(../../images/icons/cccccc/php-logo.svg); + background-size: 45px; +} +.system-status-general-info__item-icon--database:before { + background-image: url(../../images/icons/cccccc/database.svg); + background-size: 30px; +} + +.system-status-general-info__item-details { + box-sizing: border-box; + display: inline-block; + width: calc(100% - 60px); + padding-left: 10px; /* LTR */ + position: relative; +} +[dir="rtl"] .system-status-general-info__item-details { + padding-right: 10px; + padding-left: 0; +} + +.system-status-general-info__item-title { + margin-bottom: 0; +} + +.system-status-general-info__sub-item-title { + margin: 0; +} + +.system-status-general-info__sub-item__title { + font-weight: bold; +} +.system-status-general-info__sub-item__value { + display: block; +} + +.system-status-general-info__run-cron { + margin: 1em 0 0; +} + +@media screen and (min-width: 48em) { + .system-status-general-info__items { + display: flex; + flex-wrap: wrap; + overflow-x: hidden; + } + + .system-status-general-info__item { + flex: 1; + flex-basis: 33%; + width: 33%; + } + .system-status-general-info__item:nth-child(2) { + flex: 2; + flex-basis: 66%; + } + .system-status-general-info__item:nth-child(2), + .system-status-general-info__item:nth-child(4), + .system-status-general-info__item:nth-child(5) { + border-left: 1px solid #ccc; /* LTR */ + } + [dir="rtl"] .system-status-general-info__item:nth-child(1), + [dir="rtl"] .system-status-general-info__item:nth-child(3) { + border-left: 1px solid #ccc; + } + [dir="rtl"] .system-status-general-info__item:nth-child(2), + [dir="rtl"] .system-status-general-info__item:nth-child(5) { + border-left: 0; + } + + .system-status-general-info__run-cron { + margin: 15px 0 5px; + } +} + +@media screen and (min-width: 60em) { + .system-status-general-info__item-icon { + width: 55px; + height: 55px; + } + .system-status-general-info__item-icon:before { + background-size: 35px; + } + .system-status-general-info__item-icon--php:before { + background-size: 55px; + } + + .system-status-general-info__run-cron { + position: absolute; + top: 1em; + right: 1em; /* LTR */ + margin-top: 0; + } + [dir="rtl"] .system-status-general-info__run-cron { + left: 1em; + right: auto; + } +} + +@media screen and (max-width: 48em) { + .system-status-general-info__header { + display: none; + } + .system-status-general-info { + border-top: 0; + margin-top: 25px; + } +} diff --git a/core/themes/seven/css/components/system-status-report.css b/core/themes/seven/css/components/system-status-report.css index aeac1d3e..7869fbd7 100644 --- a/core/themes/seven/css/components/system-status-report.css +++ b/core/themes/seven/css/components/system-status-report.css @@ -3,13 +3,151 @@ * Seven styles for the System Status Report. */ +.system-status-report__requirements-group { + padding-top: 20px; +} .system-status-report__entry { + border: 0; border-top: 1px solid #ccc; - border-bottom: inherit; -} -.system-status-report__entry:first-child { - border-top: 1px solid #bebfb9; + margin: 0; + width: 100%; + overflow: auto; } -.system-status-report__entry:last-child { +.system-status-report__entry:last-of-type { border-bottom: 1px solid #bebfb9; } +.system-status-report__entry--error { + background-color: transparent; +} +.system-status-report__entry--warning { + background-color: transparent; +} +/* Account for native and poly-filled details element */ +.system-status-report__status-title { + position: relative; + padding: 1em 1em 1em 3em; /* LTR */ + box-sizing: border-box; + width: 100%; + font-weight: bold; +} +.system-status-report__status-title .details-title { + color: inherit; + text-transform: none; +} +html:not(.details) .system-status-report__status-title { + padding-left: 0; +} +.system-status-report__status-title .details-title { + padding-left: 3em; /* LTR */ +} +[dir="rtl"] .system-status-report__status-title .details-title { + padding-right: 3em; + padding-left: 0; +} +[dir="rtl"].details .system-status-report__status-title { + padding: 1em 3em 1em 1em; +} +.collapse-processed > .system-status-report__status-title:before { + float: right; /* LTR */ +} +.system-status-report__status-title::-webkit-details-marker { + float: right; /* LTR */ +} +[dir="rtl"] .collapse-processed > .system-status-report__status-title:before { + float: left; +} +[dir="rtl"] .system-status-report__status-title::-webkit-details-marker { + float: left; +} + +/* Make poly-filled details and summary elements behave correctly. */ +.system-status-report summary:first-child ~ * { + display: none; +} +.system-status-report details[open] > *, +.system-status-report details > summary:first-child { + display: block; +} + +.system-status-report__status-title .details-title:before, +.details .system-status-report__status-icon:before { + content: ""; + background-repeat: no-repeat; + background-size: contain; + background-position: top center; + height: 16px; + width: 16px; + position: absolute; + left: 10px; /* LTR */ + top: 1em; + display: inline-block; + vertical-align: top; + margin-right: 10px; /* LTR */ +} +[dir="rtl"] .system-status-report__status-title .details-title:before, +[dir="rtl"].details .system-status-report__status-title:before { + left: auto; + right: 10px; + margin-right: 0; +} +.system-status-report__status-icon--error .details-title:before, +.details .system-status-report__status-icon--error:before { + background-image: url(../../../stable/images/core/icons/e32700/error.svg); +} +.system-status-report__status-icon--warning .details-title:before, +.details .system-status-report__status-icon--warning:before { + background-image: url(../../../stable/images/core/icons/e29700/warning.svg); +} + +.system-status-report__entry__value { + box-sizing: border-box; + padding: 0 1em 1em 3em; /* LTR */ +} +[dir="rtl"] .system-status-report__entry__value { + padding-right: 3em; + padding-left: 1em; +} + +@media screen and (max-width: 48em) { + .system-status-report { + word-wrap: break-word; + } +} + +@media screen and (min-width: 48em) { + .system-status-report__entry::after { + display: table; + content: ''; + clear: both; + } + .system-status-report__status-title { + width: 18rem; + float: left; /* LTR */ + cursor: default; + } + .system-status-report__status-title:hover, + .system-status-report__status-title:focus { + text-decoration: none; + } + [dir="rtl"] .system-status-report__status-title { + float: right; + } + .system-status-report__status-title::-webkit-details-marker { + display: none; + } + .collapse-processed > .system-status-report__status-title:before { + position: relative; + top: 3px; + } + .system-status-report__entry__value { + width: calc(100% - 23em); + float: right; + display: block; + padding-left: 0; /* LTR */ + padding-top: 1em; + } + [dir="rtl"] .system-status-report__entry__value { + padding-left: 0; + padding-right: 3em; + } +} diff --git a/core/themes/seven/css/components/tables.css b/core/themes/seven/css/components/tables.css index 913e21a4..5464456e 100644 --- a/core/themes/seven/css/components/tables.css +++ b/core/themes/seven/css/components/tables.css @@ -38,7 +38,6 @@ tbody tr:hover, tbody tr:focus { background: #f7fcff; } - /* See colors.css */ tbody tr.color-warning:hover, tbody tr.color-warning:focus { @@ -48,6 +47,11 @@ tbody tr.color-error:hover, tbody tr.color-error:focus { background: #fcf4f2; } + +table.no-highlight tr.selected td { + background: transparent; +} + td, th { vertical-align: middle; diff --git a/core/themes/seven/css/components/tabs.css b/core/themes/seven/css/components/tabs.css index 28401b42..5aab30b8 100644 --- a/core/themes/seven/css/components/tabs.css +++ b/core/themes/seven/css/components/tabs.css @@ -1,7 +1,7 @@ /** * Tabs. */ -.is-collapse-enabled .tabs, +.is-collapse-enabled .tabs, .is-horizontal .tabs { position: relative; } @@ -107,7 +107,7 @@ li.tabs__tab a { } /* Only add the arrow if there's space */ -@media screen and (min-width:18.75em) { /* 300px */ +@media screen and (min-width: 18.75em) { /* 300px */ .tabs.primary a { background: url(../../../../misc/icons/0074bd/chevron-right.svg) 99% center no-repeat; } @@ -123,7 +123,7 @@ li.tabs__tab a { } /* JS dependent styling */ - .is-collapse-enabled .tabs__trigger { +.is-collapse-enabled .tabs__trigger { box-sizing: content-box; display: block; position: absolute; diff --git a/core/themes/seven/css/components/views-ui.css b/core/themes/seven/css/components/views-ui.css index 68497810..d212dd0b 100644 --- a/core/themes/seven/css/components/views-ui.css +++ b/core/themes/seven/css/components/views-ui.css @@ -74,7 +74,6 @@ details.fieldset-no-legend { margin-right: 1.5em; } - .views-admin-dependent .form-item .form-item, .views-admin-dependent .form-type-checkboxes, .views-admin-dependent .form-type-radios, @@ -169,7 +168,7 @@ details.fieldset-no-legend { */ .views-displays .secondary { - text-align: left; /* LTR */ + text-align: left; /* LTR */ } [dir="rtl"] .views-displays .secondary { text-align: right; @@ -193,14 +192,14 @@ details.fieldset-no-legend { color: #008BCB; } -.views-displays .secondary .action-list li:first-child { +.views-displays .secondary .action-list li:first-child { border-radius: 0 7px 0 0; /* LTR */ } -[dir="rtl"] .views-displays .secondary .action-list li:first-child { +[dir="rtl"] .views-displays .secondary .action-list li:first-child { border-radius: 7px 0 0 0; } -.views-displays .secondary .action-list li:last-child { +.views-displays .secondary .action-list li:last-child { border-radius: 0 0 7px 7px; } diff --git a/core/themes/seven/css/layout/node-add.css b/core/themes/seven/css/layout/node-add.css index 22faf339..f28a1e5f 100644 --- a/core/themes/seven/css/layout/node-add.css +++ b/core/themes/seven/css/layout/node-add.css @@ -1,3 +1,9 @@ +.layout-region-node-footer__content { + border-top: 1px solid #bebfb9; + padding-top: 0.5em; + margin-top: 1.5em; +} + /** * Widescreen * @@ -14,4 +20,7 @@ margin-top: 1em; margin-bottom: 1em; } + .layout-region-node-footer__content { + margin-top: 0.5em; + } } diff --git a/core/themes/seven/css/theme/install-page.css b/core/themes/seven/css/theme/install-page.css index 350e1e64..ad43e4f5 100644 --- a/core/themes/seven/css/theme/install-page.css +++ b/core/themes/seven/css/theme/install-page.css @@ -59,5 +59,4 @@ width: auto; max-width: 100%; } - } diff --git a/core/themes/seven/css/theme/maintenance-page.css b/core/themes/seven/css/theme/maintenance-page.css index 3725ac64..bea8321e 100644 --- a/core/themes/seven/css/theme/maintenance-page.css +++ b/core/themes/seven/css/theme/maintenance-page.css @@ -2,6 +2,7 @@ * @file * Maintenance theming. */ + .maintenance-page { background-color: #e0e0d8; background-image: -webkit-radial-gradient(hsl(203, 2%, 90%), hsl(203, 2%, 95%)); @@ -51,7 +52,6 @@ .task-list { margin-left: 0; /* LTR */ list-style-type: none; - list-style-image: none; padding-left: 0; /* LTR */ padding-bottom: 1em; } @@ -135,15 +135,17 @@ padding: 1em 0; vertical-align: middle; } - html, .install-page, .maintenance-page { + html, + .install-page, + .maintenance-page { margin: 0; width: 100%; height: 100%; } .layout-container { margin: 0 auto; - max-width: 770px; width: 75%; + max-width: 770px; border-radius: 5px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); padding: 20px 0 40px 0; @@ -181,3 +183,21 @@ margin: 0.75em 1.9em; } } + +/** + * Status report customization for install and update page. + */ +.system-status-report__status-title { + float: none; + width: 100%; +} +.system-status-report__entry__value { + float: none; + width: 100%; + padding-left: 3em; /* LTR */ + padding-top: 0; +} +[dir="rtl"] .system-status-report__entry__value { + padding-left: 1em; + padding-right: 3em; +} diff --git a/core/themes/seven/images/icons/cccccc/clock.svg b/core/themes/seven/images/icons/cccccc/clock.svg new file mode 100644 index 00000000..e51d3e01 --- /dev/null +++ b/core/themes/seven/images/icons/cccccc/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/themes/seven/images/icons/cccccc/d8-logo.svg b/core/themes/seven/images/icons/cccccc/d8-logo.svg new file mode 100644 index 00000000..035119bc --- /dev/null +++ b/core/themes/seven/images/icons/cccccc/d8-logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/core/themes/seven/images/icons/cccccc/database.svg b/core/themes/seven/images/icons/cccccc/database.svg new file mode 100644 index 00000000..3351212d --- /dev/null +++ b/core/themes/seven/images/icons/cccccc/database.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/core/themes/seven/images/icons/cccccc/php-logo.svg b/core/themes/seven/images/icons/cccccc/php-logo.svg new file mode 100644 index 00000000..b039d242 --- /dev/null +++ b/core/themes/seven/images/icons/cccccc/php-logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/core/themes/seven/images/icons/cccccc/server.svg b/core/themes/seven/images/icons/cccccc/server.svg new file mode 100644 index 00000000..1576b390 --- /dev/null +++ b/core/themes/seven/images/icons/cccccc/server.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/themes/seven/js/mobile.install.es6.js b/core/themes/seven/js/mobile.install.es6.js new file mode 100644 index 00000000..26271c0f --- /dev/null +++ b/core/themes/seven/js/mobile.install.es6.js @@ -0,0 +1,29 @@ +(function () { + function findActiveStep(steps) { + for (let i = 0; i < steps.length; i++) { + if (steps[i].className === 'is-active') { + return i + 1; + } + } + // The final "Finished" step is never "active". + if (steps[steps.length - 1].className === 'done') { + return steps.length; + } + return 0; + } + + function installStepsSetup() { + const steps = document.querySelectorAll('.task-list li'); + if (steps.length) { + const header = document.querySelector('header[role="banner"]'); + const stepIndicator = document.createElement('div'); + stepIndicator.className = 'step-indicator'; + stepIndicator.innerHTML = `${findActiveStep(steps)}/${steps.length}`; + header.appendChild(stepIndicator); + } + } + + if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', installStepsSetup); + } +}()); diff --git a/core/themes/seven/js/mobile.install.js b/core/themes/seven/js/mobile.install.js index e7a0b5c1..57c2823f 100644 --- a/core/themes/seven/js/mobile.install.js +++ b/core/themes/seven/js/mobile.install.js @@ -1,14 +1,18 @@ -(function () { - - 'use strict'; +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ +(function () { function findActiveStep(steps) { for (var i = 0; i < steps.length; i++) { if (steps[i].className === 'is-active') { return i + 1; } } - // The final "Finished" step is never "active". + if (steps[steps.length - 1].className === 'done') { return steps.length; } @@ -29,5 +33,4 @@ if (document.addEventListener) { document.addEventListener('DOMContentLoaded', installStepsSetup); } - -})(); +})(); \ No newline at end of file diff --git a/core/themes/seven/js/nav-tabs.es6.js b/core/themes/seven/js/nav-tabs.es6.js new file mode 100644 index 00000000..cd447758 --- /dev/null +++ b/core/themes/seven/js/nav-tabs.es6.js @@ -0,0 +1,51 @@ +/** + * @file + * Responsive navigation tabs. + * + * This also supports collapsible navigable is the 'is-collapsible' class is + * added to the main element, and a target element is included. + */ +(function ($, Drupal) { + function init(i, tab) { + const $tab = $(tab); + const $target = $tab.find('[data-drupal-nav-tabs-target]'); + const isCollapsible = $tab.hasClass('is-collapsible'); + + function openMenu(e) { + $target.toggleClass('is-open'); + } + + function handleResize(e) { + $tab.addClass('is-horizontal'); + const $tabs = $tab.find('.tabs'); + const isHorizontal = $tabs.outerHeight() <= $tabs.find('.tabs__tab').outerHeight(); + $tab.toggleClass('is-horizontal', isHorizontal); + if (isCollapsible) { + $tab.toggleClass('is-collapse-enabled', !isHorizontal); + } + if (isHorizontal) { + $target.removeClass('is-open'); + } + } + + $tab.addClass('position-container is-horizontal-enabled'); + + $tab.on('click.tabs', '[data-drupal-nav-tabs-trigger]', openMenu); + $(window).on('resize.tabs', Drupal.debounce(handleResize, 150)).trigger('resize.tabs'); + } + + /** + * Initialise the tabs JS. + */ + Drupal.behaviors.navTabs = { + attach(context, settings) { + const $tabs = $(context).find('[data-drupal-nav-tabs]'); + if ($tabs.length) { + const notSmartPhone = window.matchMedia('(min-width: 300px)'); + if (notSmartPhone.matches) { + $tabs.once('nav-tabs').each(init); + } + } + }, + }; +}(jQuery, Drupal)); diff --git a/core/themes/seven/js/nav-tabs.js b/core/themes/seven/js/nav-tabs.js index ba44ffb9..82d31cdb 100644 --- a/core/themes/seven/js/nav-tabs.js +++ b/core/themes/seven/js/nav-tabs.js @@ -1,14 +1,11 @@ /** - * @file - * Responsive navigation tabs. - * - * This also supports collapsible navigable is the 'is-collapsible' class is - * added to the main element, and a target element is included. - */ -(function ($, Drupal) { - - 'use strict'; +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ +(function ($, Drupal) { function init(i, tab) { var $tab = $(tab); var $target = $tab.find('[data-drupal-nav-tabs-target]'); @@ -37,11 +34,8 @@ $(window).on('resize.tabs', Drupal.debounce(handleResize, 150)).trigger('resize.tabs'); } - /** - * Initialise the tabs JS. - */ Drupal.behaviors.navTabs = { - attach: function (context, settings) { + attach: function attach(context, settings) { var $tabs = $(context).find('[data-drupal-nav-tabs]'); if ($tabs.length) { var notSmartPhone = window.matchMedia('(min-width: 300px)'); @@ -51,5 +45,4 @@ } } }; - -})(jQuery, Drupal); +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/themes/seven/js/responsive-details.es6.js b/core/themes/seven/js/responsive-details.es6.js new file mode 100644 index 00000000..d3cf6ccb --- /dev/null +++ b/core/themes/seven/js/responsive-details.es6.js @@ -0,0 +1,52 @@ +/** + * @file + * Provides responsive behaviors to HTML details elements. + */ + +(function ($, Drupal) { + /** + * Initializes the responsive behaviors for details elements. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the responsive behavior to status report specific details elements. + */ + Drupal.behaviors.responsiveDetails = { + attach(context) { + const $details = $(context).find('details').once('responsive-details'); + + if (!$details.length) { + return; + } + + function detailsToggle(matches) { + if (matches) { + $details.attr('open', true); + $summaries.attr('aria-expanded', true); + $summaries.on('click.details-open', false); + } + else { + // If user explicitly opened one, leave it alone. + const $notPressed = $details + .find('> summary[aria-pressed!=true]') + .attr('aria-expanded', false); + $notPressed + .parent('details') + .attr('open', false); + // After resize, allow user to close previously opened details. + $summaries.off('.details-open'); + } + } + + function handleDetailsMQ(event) { + detailsToggle(event.matches); + } + + var $summaries = $details.find('> summary'); + const mql = window.matchMedia('(min-width:48em)'); + mql.addListener(handleDetailsMQ); + detailsToggle(mql.matches); + }, + }; +}(jQuery, Drupal)); diff --git a/core/themes/seven/js/responsive-details.js b/core/themes/seven/js/responsive-details.js new file mode 100644 index 00000000..62ad4b2b --- /dev/null +++ b/core/themes/seven/js/responsive-details.js @@ -0,0 +1,40 @@ +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ + +(function ($, Drupal) { + Drupal.behaviors.responsiveDetails = { + attach: function attach(context) { + var $details = $(context).find('details').once('responsive-details'); + + if (!$details.length) { + return; + } + + function detailsToggle(matches) { + if (matches) { + $details.attr('open', true); + $summaries.attr('aria-expanded', true); + $summaries.on('click.details-open', false); + } else { + var $notPressed = $details.find('> summary[aria-pressed!=true]').attr('aria-expanded', false); + $notPressed.parent('details').attr('open', false); + + $summaries.off('.details-open'); + } + } + + function handleDetailsMQ(event) { + detailsToggle(event.matches); + } + + var $summaries = $details.find('> summary'); + var mql = window.matchMedia('(min-width:48em)'); + mql.addListener(handleDetailsMQ); + detailsToggle(mql.matches); + } + }; +})(jQuery, Drupal); \ No newline at end of file diff --git a/core/themes/seven/seven.info.yml b/core/themes/seven/seven.info.yml index a8d0eaa7..cdfa6a3a 100644 --- a/core/themes/seven/seven.info.yml +++ b/core/themes/seven/seven.info.yml @@ -22,6 +22,12 @@ package: Core libraries: - seven/global-styling libraries-override: + system/base: + css: + component: + /core/themes/stable/css/system/components/system-status-counter.css: css/components/system-status-counter.css + /core/themes/stable/css/system/components/system-status-report-counters.css: css/components/system-status-report-counters.css + /core/themes/stable/css/system/components/system-status-report-general-info.css: css/components/system-status-report-general-info.css core/drupal.vertical-tabs: css: component: @@ -60,8 +66,8 @@ regions: regions_hidden: - sidebar_first -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/themes/seven/seven.libraries.yml b/core/themes/seven/seven.libraries.yml index e68b75a9..21ac5bca 100644 --- a/core/themes/seven/seven.libraries.yml +++ b/core/themes/seven/seven.libraries.yml @@ -27,7 +27,10 @@ global-styling: css/components/tables.css: {} css/components/search-admin-settings.css: {} css/components/tablesort-indicator.css: {} + css/components/system-status-report-general-info.css: {} css/components/system-status-report.css: {} + css/components/system-status-report-counters.css: {} + css/components/system-status-counter.css: {} css/components/tabs.css: {} css/components/views-ui.css: {} layout: @@ -74,6 +77,18 @@ drupal.nav-tabs: - core/drupal - core/jquery.once - core/drupal.debounce + - core/collapse + +drupal.responsive-detail: + version: VERSION + js: + js/responsive-details.js: {} + dependencies: + - core/matchmedia + - core/matchmedia.addListener + - core/jquery + - core/jquery.once + - core/collapse vertical-tabs: version: VERSION @@ -104,3 +119,11 @@ tour-styling: css: theme: css/components/tour.theme.css: {} + +media-form: + version: VERSION + css: + layout: + css/components/media.css: {} + dependencies: + - media/form diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme index 5ace6b83..2ad947c8 100644 --- a/core/themes/seven/seven.theme +++ b/core/themes/seven/seven.theme @@ -23,7 +23,7 @@ function seven_preprocess_html(&$variables) { } /** - * Implements hook_pre_render_HOOK() for menu-local-tasks templates. + * Implements hook_preprocess_HOOK() for menu-local-tasks templates. * * Use preprocess hook to set #attached to child elements * because they will be processed by Twig and drupal_render will @@ -31,18 +31,18 @@ function seven_preprocess_html(&$variables) { */ function seven_preprocess_menu_local_tasks(&$variables) { if (!empty($variables['primary'])) { - $variables['primary']['#attached'] = array( - 'library' => array( + $variables['primary']['#attached'] = [ + 'library' => [ 'seven/drupal.nav-tabs', - ), - ); + ], + ]; } elseif (!empty($variables['secondary'])) { - $variables['secondary']['#attached'] = array( - 'library' => array( + $variables['secondary']['#attached'] = [ + 'library' => [ 'seven/drupal.nav-tabs', - ), - ); + ], + ]; } } @@ -61,7 +61,7 @@ function seven_preprocess_node_add_list(&$variables) { /** @var \Drupal\node\NodeTypeInterface $type */ foreach ($variables['content'] as $type) { $variables['types'][$type->id()]['label'] = $type->label(); - $variables['types'][$type->id()]['url'] = \Drupal::url('node.add', array('node_type' => $type->id())); + $variables['types'][$type->id()]['url'] = \Drupal::url('node.add', ['node_type' => $type->id()]); } } } @@ -76,8 +76,8 @@ function seven_preprocess_block_content_add_list(&$variables) { if (!empty($variables['content'])) { foreach ($variables['content'] as $type) { $variables['types'][$type->id()]['label'] = $type->label(); - $options = array('query' => \Drupal::request()->query->all()); - $variables['types'][$type->id()]['url'] = \Drupal::url('block_content.add_form', array('block_content_type' => $type->id()), $options); + $options = ['query' => \Drupal::request()->query->all()]; + $variables['types'][$type->id()]['url'] = \Drupal::url('block_content.add_form', ['block_content_type' => $type->id()], $options); } } } @@ -147,42 +147,29 @@ function seven_preprocess_maintenance_page(&$variables) { /** * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm. * - * Changes vertical tabs to container and adds meta information. + * Changes vertical tabs to container. */ function seven_form_node_form_alter(&$form, FormStateInterface $form_state) { - /** @var \Drupal\node\NodeInterface $node */ - $node = $form_state->getFormObject()->getEntity(); - - $form['#theme'] = array('node_edit_form'); + $form['#theme'] = ['node_edit_form']; $form['#attached']['library'][] = 'seven/node-form'; $form['advanced']['#type'] = 'container'; - $is_new = !$node->isNew() ? format_date($node->getChangedTime(), 'short') : t('Not saved yet'); - $form['meta'] = array( - '#attributes' => array('class' => array('entity-meta__header')), - '#type' => 'container', - '#group' => 'advanced', - '#weight' => -100, - 'published' => array( - '#type' => 'html_tag', - '#tag' => 'h3', - '#value' => $node->isPublished() ? t('Published') : t('Not published'), - '#access' => !$node->isNew(), - '#attributes' => array( - 'class' => 'entity-meta__title', - ), - ), - 'changed' => array( - '#type' => 'item', - '#wrapper_attributes' => array('class' => array('entity-meta__last-saved', 'container-inline')), - '#markup' => '

    ' . t('Last saved') . '

    ' . $is_new, - ), - 'author' => array( - '#type' => 'item', - '#wrapper_attributes' => array('class' => array('author', 'container-inline')), - '#markup' => '

    ' . t('Author') . '

    ' . $node->getOwner()->getUsername(), - ), - ); + $form['meta']['#type'] = 'container'; + $form['meta']['#access'] = TRUE; + $form['meta']['changed']['#wrapper_attributes']['class'][] = 'container-inline'; + $form['meta']['author']['#wrapper_attributes']['class'][] = 'container-inline'; + $form['revision_information']['#type'] = 'container'; $form['revision_information']['#group'] = 'meta'; } + +/** + * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\media\MediaForm. + */ +function seven_form_media_form_alter(&$form, FormStateInterface $form_state) { + // @todo Revisit after https://www.drupal.org/node/2892304 is in. It + // introduces a footer region to these forms which will allow for us to + // display a top border over the published checkbox by defining a + // media-edit-form.html.twig template the same way node does. + $form['#attached']['library'][] = 'seven/media-form'; +} diff --git a/core/themes/seven/templates/image-widget.html.twig b/core/themes/seven/templates/image-widget.html.twig new file mode 100644 index 00000000..a7cf3ad4 --- /dev/null +++ b/core/themes/seven/templates/image-widget.html.twig @@ -0,0 +1,12 @@ +{# +/** + * @file + * Theme override for an image field widget. + * + * Included from Classy theme. + * + * @see template_preprocess_image_widget() + */ +#} +{% include '@classy/content-edit/image-widget.html.twig' %} +{{ attach_library('classy/image-widget') }} diff --git a/core/themes/seven/templates/node-edit-form.html.twig b/core/themes/seven/templates/node-edit-form.html.twig new file mode 100644 index 00000000..cf747f92 --- /dev/null +++ b/core/themes/seven/templates/node-edit-form.html.twig @@ -0,0 +1,31 @@ +{# +/** + * @file + * Theme override for a node edit form. + * + * Two column template for the node add/edit form. + * + * This template will be used when a node edit form specifies 'node_edit_form' + * as its #theme callback. Otherwise, by default, node add/edit forms will be + * themed by form.html.twig. + * + * Available variables: + * - form: The node add/edit form. + * + * @see seven_form_node_form_alter() + */ +#} +
    +
    + {{ form|without('advanced', 'footer', 'actions') }} +
    +
    + {{ form.advanced }} +
    + +
    diff --git a/core/themes/seven/templates/status-report-counter.html.twig b/core/themes/seven/templates/status-report-counter.html.twig new file mode 100644 index 00000000..13ab8a84 --- /dev/null +++ b/core/themes/seven/templates/status-report-counter.html.twig @@ -0,0 +1,26 @@ +{# +/** + * @file + * Theme override for status report counter. + * + * Available variables: + * - amount: The number shown on counter. + * - text: The text shown on counter. + * - severity: The severity of the counter. + * + * @ingroup themable + */ +#} +{% + set classes = [ + 'system-status-counter', + 'system-status-counter--' ~ severity, + ] +%} + + + + {{ amount }} {{ text }} + {{ text }} Details + + diff --git a/core/themes/seven/templates/status-report-general-info.html.twig b/core/themes/seven/templates/status-report-general-info.html.twig new file mode 100644 index 00000000..a5d6ce7b --- /dev/null +++ b/core/themes/seven/templates/status-report-general-info.html.twig @@ -0,0 +1,99 @@ +{# +/** + * @file + * Theme override for status report general info. + * + * Available variables: + * - drupal: The status of Drupal installation: + * - value: The current status of Drupal installation. + * - description: The description for current status of Drupal installation. + * - cron: The status of cron: + * - value: The current status of cron. + * - description: The description for current status of cron. + * - cron.run_cron: An array to render a button for running cron. + * - database_system: The status of database system: + * - value: The current status of database sytem. + * - description: The description for current status of cron. + * - database_system_version: The info about current database version: + * - value: The current version of database. + * - description: The description for current version of database. + * - php: The current version of PHP: + * - value: The status of currently installed PHP version. + * - description: The description for current installed PHP version. + * - php_memory_limit: The info about current PHP memory limit: + * - value: The status of currently set PHP memory limit. + * - description: The description for currently set PHP memory limit. + * - webserver: The info about currently installed web server: + * - value: The status of currently installed web server. + * - description: The description for the status of currently installed web + * server. + */ +#} +
    +

    {{ 'General System Information'|t }}

    +
    +
    + +
    +

    {{ 'Drupal Version'|t }}

    + {{ drupal.value }} + {% if drupal.description %} +
    {{ drupal.description }}
    + {% endif %} +
    +
    +
    + +
    +

    {{ 'Last Cron Run'|t }}

    + {{ cron.value }} + {% if cron.run_cron %} +
    {{ cron.run_cron }}
    + {% endif %} + {% if cron.description %} +
    {{ cron.description }}
    + {% endif %} +
    +
    +
    + +
    +

    {{ 'Web Server'|t }}

    + {{ webserver.value }} + {% if webserver.description %} +
    {{ webserver.description }}
    + {% endif %} +
    +
    +
    + +
    +

    {{ 'PHP'|t }}

    +

    {{ 'Version'|t }}

    {{ php.value }} + {% if php.description %} +
    {{ php.description }}
    + {% endif %} + +

    {{ 'Memory limit'|t }}

    {{ php_memory_limit.value }} + {% if php_memory_limit.description %} +
    {{ php_memory_limit.description }}
    + {% endif %} +
    +
    +
    + +
    +

    {{ 'Database'|t }}

    +

    {{ 'Version'|t }}

    {{ database_system_version.value }} + {% if database_system_version.description %} +
    {{ database_system_version.description }}
    + {% endif %} + +

    {{ 'System'|t }}

    {{ database_system.value }} + {% if database_system.description %} +
    {{ database_system.description }}
    + {% endif %} +
    +
    +
    +
    diff --git a/core/themes/seven/templates/status-report-grouped.html.twig b/core/themes/seven/templates/status-report-grouped.html.twig new file mode 100644 index 00000000..c5d6303f --- /dev/null +++ b/core/themes/seven/templates/status-report-grouped.html.twig @@ -0,0 +1,50 @@ +{# +/** + * @file + * Theme override to display status report. + * + * - grouped_requirements: Contains grouped requirements. + * Each group contains: + * - title: The title of the group. + * - type: The severity of the group. + * - items: The requirement instances. + * Each requirement item contains: + * - title: The title of the requirement. + * - value: (optional) The requirement's status. + * - description: (optional) The requirement's description. + * - severity_title: The title of the severity. + * - severity_status: Indicates the severity status. + */ +#} +{{ attach_library('core/drupal.collapse') }} +{{ attach_library('seven/drupal.responsive-detail') }} + +
    + {% for group in grouped_requirements %} +
    +

    {{ group.title }}

    + {% for requirement in group.items %} +
    + {% + set summary_classes = [ + 'system-status-report__status-title', + group.type in ['warning', 'error'] ? 'system-status-report__status-icon system-status-report__status-icon--' ~ group.type + ] + %} + + {% if requirement.severity_title %} + {{ requirement.severity_title }} + {% endif %} + {{ requirement.title }} + +
    + {{ requirement.value }} + {% if requirement.description %} +
    {{ requirement.description }}
    + {% endif %} +
    +
    + {% endfor %} +
    + {% endfor %} +
    diff --git a/core/themes/seven/templates/status-report-page.html.twig b/core/themes/seven/templates/status-report-page.html.twig new file mode 100644 index 00000000..27e0d157 --- /dev/null +++ b/core/themes/seven/templates/status-report-page.html.twig @@ -0,0 +1,28 @@ +{# +/** + * @file + * Theme override for the status report page. + * + * Available variables: + * - counters: The list of counter elements. + * - general_info: A render array to create general info element. + * - requirements: A render array to create requirements table. + * + * @see template_preprocess_status_report() + */ +#} +{% if counters|length == 3 %} + {% set element_width_class = ' system-status-report-counters__item--third-width' %} +{% elseif counters|length == 2 %} + {% set element_width_class = ' system-status-report-counters__item--half-width' %} +{% endif %} +
    + {% for counter in counters %} +
    + {{ counter }} +
    + {% endfor %} +
    + +{{ general_info }} +{{ requirements }} diff --git a/core/themes/stable/README.txt b/core/themes/stable/README.txt index a8687a0d..0539730c 100644 --- a/core/themes/stable/README.txt +++ b/core/themes/stable/README.txt @@ -23,4 +23,4 @@ ABOUT DRUPAL THEMING -------------------- For more information, see Drupal.org's theming guide. -https://www.drupal.org/theme-guide/8 +https://www.drupal.org/docs/8/theming diff --git a/core/themes/stable/css/block/block.admin.css b/core/themes/stable/css/block/block.admin.css index ed120389..08686e78 100644 --- a/core/themes/stable/css/block/block.admin.css +++ b/core/themes/stable/css/block/block.admin.css @@ -24,7 +24,7 @@ a.block-demo-backlink:visited { font-family: "Lucida Grande", Verdana, sans-serif; font-size: small; line-height: 20px; - left: 20px; /*LTR*/ + left: 20px; /* LTR */ padding: 5px 10px; position: fixed; z-index: 499; diff --git a/core/themes/stable/css/ckeditor/ckeditor-iframe.css b/core/themes/stable/css/ckeditor/ckeditor-iframe.css index 8996334d..c34a6835 100644 --- a/core/themes/stable/css/ckeditor/ckeditor-iframe.css +++ b/core/themes/stable/css/ckeditor/ckeditor-iframe.css @@ -16,7 +16,9 @@ body { } } -ol, ul, dl { +ol, +ul, +dl { /* Preserved spaces for list items with text direction other than the list. * (CKEditor issues #6249,#8049) */ padding: 0 40px; diff --git a/core/themes/stable/css/ckeditor/ckeditor.admin.css b/core/themes/stable/css/ckeditor/ckeditor.admin.css index 8b771c74..cfbeae06 100644 --- a/core/themes/stable/css/ckeditor/ckeditor.admin.css +++ b/core/themes/stable/css/ckeditor/ckeditor.admin.css @@ -6,8 +6,6 @@ * "moono". */ - - .ckeditor-toolbar { border: 1px solid #b6b6b6; padding: 0.1667em 0.1667em 0.08em; @@ -119,7 +117,7 @@ margin: 3px 6px; padding: 3px; } -.ckeditor-toolbar-configuration .fieldset-description{ +.ckeditor-toolbar-configuration .fieldset-description { margin-bottom: 1em; } .ckeditor-toolbar-disabled .ckeditor-toolbar-available, diff --git a/core/themes/stable/css/core/dropbutton/dropbutton.css b/core/themes/stable/css/core/dropbutton/dropbutton.css index 5990514f..8b8709da 100644 --- a/core/themes/stable/css/core/dropbutton/dropbutton.css +++ b/core/themes/stable/css/core/dropbutton/dropbutton.css @@ -17,14 +17,14 @@ position: relative; } -@media screen and (max-width:600px) { +@media screen and (max-width: 600px) { .js .dropbutton-wrapper { width: 100%; } } /* Splitbuttons */ -@media screen and (min-width:600px) { +@media screen and (min-width: 600px) { .form-actions .dropbutton-wrapper { float: left; /* LTR */ } diff --git a/core/themes/stable/css/core/print.css b/core/themes/stable/css/core/print.css index 6e69a3ba..586d3329 100644 --- a/core/themes/stable/css/core/print.css +++ b/core/themes/stable/css/core/print.css @@ -17,7 +17,7 @@ th { tr:nth-child(odd) { background-color: #ddd; } -tr:nth-child(even){ +tr:nth-child(even) { background-color: #fff; } td { diff --git a/core/themes/stable/css/core/vertical-tabs.css b/core/themes/stable/css/core/vertical-tabs.css index ec5d3c19..fc83da51 100644 --- a/core/themes/stable/css/core/vertical-tabs.css +++ b/core/themes/stable/css/core/vertical-tabs.css @@ -8,8 +8,8 @@ border: 1px solid #ccc; } [dir="rtl"] .vertical-tabs { - margin-left: 0; - margin-right: 15em; + margin-left: 0; + margin-right: 15em; } .vertical-tabs__menu { float: left; /* LTR */ diff --git a/core/themes/stable/css/file/file.admin.css b/core/themes/stable/css/file/file.admin.css index 6a45644c..38ad4785 100644 --- a/core/themes/stable/css/file/file.admin.css +++ b/core/themes/stable/css/file/file.admin.css @@ -3,7 +3,7 @@ * Admin stylesheet for file module. */ -/* File upload widget.*/ +/* File upload widget. */ .form-managed-file .form-submit { margin: 0 0.5em; } diff --git a/core/themes/stable/css/image/editors/image.css b/core/themes/stable/css/image/editors/image.css new file mode 100644 index 00000000..08bb6792 --- /dev/null +++ b/core/themes/stable/css/image/editors/image.css @@ -0,0 +1,52 @@ +/** + * @file + * Functional styles for the Image module's in-place editor. + */ + +/** + * A minimum width/height is required so that users can drag and drop files + * onto small images. + */ +.quickedit-image-element { + min-width: 200px; + min-height: 200px; +} + +.quickedit-image-dropzone { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.quickedit-image-icon { + display: block; + width: 50px; + height: 50px; + background-repeat: no-repeat; + background-size: cover; +} + +.quickedit-image-field-info { + display: flex; + align-items: center; + justify-content: flex-end; +} + +.quickedit-image-text { + display: block; +} + +/** + * If we do not prevent pointer-events for child elements, our drag+drop events + * will not fire properly. This can lead to unintentional redirects if a file + * is dropped on a child element when a user intended to upload it. + */ +.quickedit-image-dropzone * { + pointer-events: none; +} diff --git a/core/themes/stable/css/image/editors/image.theme.css b/core/themes/stable/css/image/editors/image.theme.css new file mode 100644 index 00000000..f7a1b3a6 --- /dev/null +++ b/core/themes/stable/css/image/editors/image.theme.css @@ -0,0 +1,100 @@ +/** + * @file + * Theme styles for the Image module's in-place editor. + */ + +.quickedit-image-dropzone { + background: rgba(116, 183, 255, 0.8); + transition: background .2s; +} + +.quickedit-image-icon { + margin: 0 0 10px 0; + transition: margin .5s; +} + +.quickedit-image-dropzone.hover { + background: rgba(116, 183, 255, 0.9); +} + +.quickedit-image-dropzone.error { + background: rgba(255, 52, 27, 0.81); +} + +.quickedit-image-dropzone.upload .quickedit-image-icon { + background-image: url('../../../images/image/upload.svg'); +} + +.quickedit-image-dropzone.error .quickedit-image-icon { + background-image: url('../../../images/image/error.svg'); +} + +.quickedit-image-dropzone.loading .quickedit-image-icon { + margin: -10px 0 20px 0; +} + +.quickedit-image-dropzone.loading .quickedit-image-icon::after { + display: block; + content: ""; + margin-left: -10px; + margin-top: -5px; + animation-duration: 2s; + animation-name: quickedit-image-spin; + animation-iteration-count: infinite; + animation-timing-function: linear; + width: 60px; + height: 60px; + border-style: solid; + border-radius: 35px; + border-width: 5px; + border-color: white transparent transparent transparent; +} + +@keyframes quickedit-image-spin { + 0% { transform: rotate(0deg); } + 50% { transform: rotate(180deg); } + 100% { transform: rotate(360deg); } +} + +.quickedit-image-text { + text-align: center; + color: white; + font-family: "Droid sans", "Lucida Grande", sans-serif; + font-size: 16px; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +.quickedit-image-field-info { + background: rgba(0, 0, 0, 0.05); + border-top: 1px solid #c5c5c5; + padding: 5px; +} + +.quickedit-image-field-info div { + margin-right: 10px; /* LTR */ +} + +.quickedit-image-field-info div:last-child { + margin-right: 0; /* LTR */ +} + +[dir="rtl"] .quickedit-image-field-info div { + margin-left: 10px; + margin-right: 0; +} + +[dir="rtl"] .quickedit-image-field-info div:last-child { + margin-left: 0; +} + +.quickedit-image-errors .messages__wrapper { + margin: 0; + padding: 0; +} + +.quickedit-image-errors .messages--error { + box-shadow: none; +} diff --git a/core/themes/stable/css/quickedit/quickedit.theme.css b/core/themes/stable/css/quickedit/quickedit.theme.css index 399db7a8..120573a5 100644 --- a/core/themes/stable/css/quickedit/quickedit.theme.css +++ b/core/themes/stable/css/quickedit/quickedit.theme.css @@ -99,7 +99,7 @@ * Toolbars. */ .quickedit-toolbar-container { - font-family: 'Source Sans Pro','Lucida Grande', sans-serif; + font-family: 'Source Sans Pro', 'Lucida Grande', sans-serif; padding-bottom: 7px; padding-top: 7px; -webkit-transition: all 1s; @@ -174,9 +174,9 @@ padding: 0.1667em 0.2em; } - /** - * Info toolgroup. - */ +/** + * Info toolgroup. + */ .quickedit-toolbar-fullwidth { width: 100%; } diff --git a/core/themes/stable/css/system/components/system-status-counter.css b/core/themes/stable/css/system/components/system-status-counter.css new file mode 100644 index 00000000..8d3ad76d --- /dev/null +++ b/core/themes/stable/css/system/components/system-status-counter.css @@ -0,0 +1,28 @@ +/** + * @file + * Styles for the system status counter component. + */ + +.system-status-counter__status-icon { + display: inline-block; + height: 25px; + width: 25px; + vertical-align: middle; +} +.system-status-counter__status-icon:before { + content: ""; + background-size: 20px; + background-position: center 2px; + background-repeat: no-repeat; + display: block; +} + +.system-status-counter__status-icon--error:before { + background-image: url(../../../images/core/icons/e32700/error.svg); +} +.system-status-counter__status-icon--warning:before { + background-image: url(../../../images/core/icons/e29700/warning.svg); +} +.system-status-counter__status-icon--checked:before { + background-image: url(../../../images/core/icons/73b355/check.svg); +} diff --git a/core/themes/stable/css/system/components/system-status-report-counters.css b/core/themes/stable/css/system/components/system-status-report-counters.css new file mode 100644 index 00000000..1a4e2400 --- /dev/null +++ b/core/themes/stable/css/system/components/system-status-report-counters.css @@ -0,0 +1,27 @@ +/** + * @file + * Styles for the system status report counters. + */ + +.system-status-report-counters__item { + width: 100%; + padding: .5em 0; + text-align: center; + white-space: nowrap; + background-color: rgba(0, 0, 0, 0.063); + margin-bottom: .5em; +} + +@media screen and (min-width: 60em) { + .system-status-report-counters { + flex-wrap: wrap; + display: flex; + justify-content: space-between; + } + .system-status-report-counters__item--half-width { + width: 49%; + } + .system-status-report-counters__item--third-width { + width: 33%; + } +} diff --git a/core/themes/stable/css/system/components/system-status-report-general-info.css b/core/themes/stable/css/system/components/system-status-report-general-info.css new file mode 100644 index 00000000..8334d4d1 --- /dev/null +++ b/core/themes/stable/css/system/components/system-status-report-general-info.css @@ -0,0 +1,14 @@ +/** + * @file + * Default styles for the System Status general info. + */ + +.system-status-general-info__item { + border: 1px solid #ccc; + margin-top: 1em; + padding: 0 1em 1em; +} + +.system-status-general-info__item-title { + border-bottom: 1px solid #ccc; +} diff --git a/core/themes/stable/css/system/system.admin.css b/core/themes/stable/css/system/system.admin.css index c8e20cf7..e8922932 100644 --- a/core/themes/stable/css/system/system.admin.css +++ b/core/themes/stable/css/system/system.admin.css @@ -204,13 +204,14 @@ small .admin-link:after { .system-status-report__status-title { position: relative; vertical-align: top; - width: 25%; + width: 100%; padding: 10px 6px 10px 40px; /* LTR */ box-sizing: border-box; font-weight: normal; + background-color: transparent; } [dir="rtl"] .system-status-report__status-title { - padding: 10px 40px 10px 6px; + padding: 10px 40px 10px 6px; } .system-status-report__status-icon:before { content: ""; @@ -222,7 +223,7 @@ small .admin-link:after { left: 12px; /* LTR */ top: 12px; } -[dir="rtl"] .system-status-report__status-icon:before { +[dir="rtl"] .system-status-report__status-icon:before { left: auto; right: 12px; } @@ -232,6 +233,9 @@ small .admin-link:after { .system-status-report__status-icon--warning:before { background-image: url(../../images/core/icons/e29700/warning.svg); } +.system-status-report__entry__value { + padding: 1em .5em; +} /** * Appearance page. @@ -387,3 +391,11 @@ small .admin-link:after { [dir="rtl"] .system-themes-admin-form { clear: right; } +.cron-description__run-cron { + display: block; +} + +.system-cron-settings__link { + overflow-wrap: break-word; + word-wrap: break-word; +} diff --git a/core/themes/stable/css/toolbar/toolbar.icons.theme.css b/core/themes/stable/css/toolbar/toolbar.icons.theme.css index 54942d51..2a0614ab 100644 --- a/core/themes/stable/css/toolbar/toolbar.icons.theme.css +++ b/core/themes/stable/css/toolbar/toolbar.icons.theme.css @@ -219,7 +219,6 @@ background-color: #f5f5f5; } - /** * Handle. */ @@ -280,8 +279,7 @@ background-image: url(../../images/core/icons/bebebe/push-left.svg); /* LTR */ } .toolbar .toolbar-toggle-orientation [value="vertical"]:hover:before, -.toolbar .toolbar-toggle-orientation [value="vertical"]:focus:before - { +.toolbar .toolbar-toggle-orientation [value="vertical"]:focus:before { background-image: url(../../images/core/icons/787878/push-left.svg); /* LTR */ } [dir="rtl"] .toolbar .toolbar-toggle-orientation [value="vertical"]:before { diff --git a/core/themes/stable/css/toolbar/toolbar.menu.css b/core/themes/stable/css/toolbar/toolbar.menu.css index 099fb084..b4e8b2ef 100644 --- a/core/themes/stable/css/toolbar/toolbar.menu.css +++ b/core/themes/stable/css/toolbar/toolbar.menu.css @@ -13,11 +13,26 @@ position: relative; width: auto; } -.toolbar .toolbar-tray-horizontal .toolbar-menu .toolbar-handle, -.toolbar .toolbar-tray-horizontal .toolbar-menu ul, + +/** + * Hidden vertical toolbar sub-menus by default. + */ .toolbar .toolbar-tray-vertical .toolbar-menu ul { display: none; } + +/** + * Hidden horizontal toolbar handle icon. + */ +.toolbar .toolbar-tray-horizontal .toolbar-menu .toolbar-handle { + display: none; +} +/** + * Hidden toolbar sub-menus by default. + */ +.toolbar-tray-open .toolbar-menu .menu-item--expanded ul { + display: none; +} .toolbar .toolbar-tray-vertical li.open > ul { display: block; /* Show the sub-menus */ } diff --git a/core/themes/stable/css/toolbar/toolbar.module.css b/core/themes/stable/css/toolbar/toolbar.module.css index 69eb7c22..f50d4cb4 100644 --- a/core/themes/stable/css/toolbar/toolbar.module.css +++ b/core/themes/stable/css/toolbar/toolbar.module.css @@ -21,7 +21,9 @@ display: none; } } - +.toolbar-loading #toolbar-administration { + overflow: hidden; +} /** * Very specific overrides for Drupal system CSS. */ @@ -56,18 +58,44 @@ position: relative; z-index: 1250; } +.toolbar-horizontal .toolbar-tray { + position: fixed; + width: 100%; + left: 0; +} /* Position the admin toolbar absolutely when the configured standard breakpoint * is active. The toolbar container, that contains the bar and the trays, is * position absolutely so that it scrolls with the page. Otherwise, on smaller * screens, the components of the admin toolbar are positioned statically. */ -body.toolbar-fixed .toolbar-oriented, -.toolbar-oriented .toolbar-bar, -.toolbar-oriented .toolbar-tray { +.toolbar-oriented .toolbar-bar { left: 0; position: absolute; right: 0; top: 0; } +.toolbar-oriented .toolbar-tray { + left: 0; + position: absolute; + right: 0; +} +/* .toolbar-loading is required by Toolbar JavaScript to pre-render markup + * style to avoid extra reflow & flicker. */ +@media (min-width: 61em) { + .toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray { + position: relative; + display: block; + z-index: -999; + visibility: hidden; + width: 1px; + } + .toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray .toolbar-lining { + width: 999em; + } + .toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .home-toolbar-tab + .toolbar-tab .toolbar-tray { + display: block; + } +} + /* Layer the bar just above the trays and above contextual link triggers. */ .toolbar-oriented .toolbar-bar { z-index: 502; @@ -85,13 +113,16 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { width: 240px; width: 15rem; } + /* Present the admin toolbar tabs horizontally as a default on user agents that * do not understand media queries or on user agents where JavaScript is * disabled. */ +.toolbar-loading.toolbar-horizontal .toolbar .toolbar-tray .toolbar-menu > li, .toolbar .toolbar-bar .toolbar-tab, .toolbar .toolbar-tray-horizontal li { float: left; /* LTR */ } +[dir="rtl"] .toolbar-loading.toolbar-horizontal .toolbar .toolbar-tray .toolbar-menu > li, [dir="rtl"] .toolbar .toolbar-bar .toolbar-tab, [dir="rtl"] .toolbar .toolbar-tray-horizontal li { float: right; @@ -111,7 +142,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { /* This min-width media query is meant to provide basic horizontal layout to * the main menu tabs when JavaScript is disabled on user agents that understand * media queries. */ -@media (min-width:16.5em) { +@media (min-width: 16.5em) { .toolbar .toolbar-bar .toolbar-tab, .toolbar .toolbar-tray-horizontal li { float: left; /* LTR */ @@ -171,7 +202,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { right: 0; } /* Layer the links just above the toolbar-tray. */ -.toolbar .toolbar-bar .toolbar-tab > .toolbar-icon{ +.toolbar .toolbar-bar .toolbar-tab > .toolbar-icon { position: relative; z-index: 502; } @@ -179,15 +210,10 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented { .toolbar-oriented .toolbar-tray-horizontal .menu-item ul { display: none; } -/* When the configured standard breakpoint is active and the tray is in a - * horizontal position, the tray is fixed to the top of the viewport and does - * not scroll with the page contents. */ -body.toolbar-fixed .toolbar .toolbar-tray-horizontal { - position: fixed; -} /* When the configured standard breakpoint is active and the tray is in a * vertical position, the tray does not scroll with the page. The contents of - * the tray scroll within the confines of the viewport. */ + * the tray scroll within the confines of the viewport. + */ .toolbar .toolbar-tray-vertical.is-active, body.toolbar-fixed .toolbar .toolbar-tray-vertical { height: 100%; @@ -258,3 +284,13 @@ body.toolbar-tray-open.toolbar-vertical.toolbar-fixed { [dir="rtl"] .toolbar-oriented .toolbar-tray-vertical .toolbar-toggle-orientation { float: left; } + +/** + * Toolbar home button toggle. + */ +.toolbar .toolbar-bar .home-toolbar-tab { + display: none; +} +.path-admin .toolbar-bar .home-toolbar-tab { + display: block; +} diff --git a/core/themes/stable/css/toolbar/toolbar.theme.css b/core/themes/stable/css/toolbar/toolbar.theme.css index 981ee00a..3af712bd 100644 --- a/core/themes/stable/css/toolbar/toolbar.theme.css +++ b/core/themes/stable/css/toolbar/toolbar.theme.css @@ -20,7 +20,8 @@ line-height: 1em; text-decoration: none; } -.toolbar .toolbar-item:hover, .toolbar .toolbar-item:focus { +.toolbar .toolbar-item:hover, +.toolbar .toolbar-item:focus { text-decoration: underline; } @@ -57,10 +58,10 @@ .toolbar .toolbar-tray { background-color: #ffffff; } -.toolbar .toolbar-tray-horizontal > .toolbar-lining { +.toolbar-horizontal .toolbar-tray > .toolbar-lining { padding-right: 5em; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal > .toolbar-lining { +[dir="rtl"] .toolbar-horizontal .toolbar-tray > .toolbar-lining { padding-right: 0; padding-left: 5em; } @@ -74,11 +75,11 @@ border-right: 0 none; box-shadow: 1px 0 5px 2px rgba(0, 0, 0, 0.3333); } -.toolbar .toolbar-tray-horizontal { +.toolbar-horizontal .toolbar-tray { border-bottom: 1px solid #aaaaaa; box-shadow: -2px 1px 3px 1px rgba(0, 0, 0, 0.3333); /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal { +[dir="rtl"] .toolbar-horizontal .toolbar-tray { box-shadow: 2px 1px 3px 1px rgba(0, 0, 0, 0.3333); } .toolbar .toolbar-tray-horizontal .toolbar-tray { @@ -93,25 +94,24 @@ .toolbar-tray a:hover, .toolbar-tray a:active, .toolbar-tray a:focus, -.toolbar-tray a.is-active - { +.toolbar-tray a.is-active { color: #000; text-decoration: underline; } .toolbar .toolbar-menu { background-color: #ffffff; } -.toolbar .toolbar-tray-horizontal .menu-item + .menu-item { +.toolbar-horizontal .toolbar-tray .menu-item + .menu-item { border-left: 1px solid #dddddd; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal .menu-item + .menu-item { - border-left: 0 none ; +[dir="rtl"] .toolbar-horizontal .toolbar-tray .menu-item + .menu-item { + border-left: 0 none; border-right: 1px solid #dddddd; } -.toolbar .toolbar-tray-horizontal .menu-item:last-child { +.toolbar-horizontal .toolbar-tray .menu-item:last-child { border-right: 1px solid #dddddd; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal .menu-item:last-child { +[dir="rtl"] .toolbar-horizontal .toolbar-tray .menu-item:last-child { border-left: 1px solid #dddddd; } .toolbar .toolbar-tray-vertical .menu-item + .menu-item { @@ -149,10 +149,10 @@ padding: 0; height: 100%; } -.toolbar .toolbar-tray-horizontal .toolbar-toggle-orientation { +.toolbar-horizontal .toolbar-tray .toolbar-toggle-orientation { border-left: 1px solid #c9c9c9; /* LTR */ } -[dir="rtl"] .toolbar .toolbar-tray-horizontal .toolbar-toggle-orientation { +[dir="rtl"] .toolbar-horizontal .toolbar-tray .toolbar-toggle-orientation { border-left: 0 none; border-right: 1px solid #c9c9c9; } diff --git a/core/themes/stable/css/views_ui/views_ui.admin.css b/core/themes/stable/css/views_ui/views_ui.admin.css index e932af13..3d1db05d 100644 --- a/core/themes/stable/css/views_ui/views_ui.admin.css +++ b/core/themes/stable/css/views_ui/views_ui.admin.css @@ -147,7 +147,7 @@ margin-bottom: 2em; } -@media screen and (min-width:45em) { /* 720px */ +@media screen and (min-width: 45em) { /* 720px */ .views-display-columns > * { float: left; /* LTR */ margin-left: 2%; /* LTR */ diff --git a/core/themes/stable/css/views_ui/views_ui.admin.theme.css b/core/themes/stable/css/views_ui/views_ui.admin.theme.css index 3bf3290c..b843586a 100644 --- a/core/themes/stable/css/views_ui/views_ui.admin.theme.css +++ b/core/themes/stable/css/views_ui/views_ui.admin.theme.css @@ -158,7 +158,7 @@ details.box-padding { /* Hide 'remove' checkboxes. */ .views-remove-checkbox { - display: none; + display: none; } /* sizes the labels of checkboxes and radio button to the height of the text */ @@ -170,9 +170,9 @@ details.box-padding { margin-bottom: 6px; margin-top: 6px; } -.views-ui-view-title { +.views-ui-view-name h3 { font-weight: bold; - margin-top: 0; + margin: 0.25em 0; } .view-changed { margin-bottom: 21px; @@ -183,22 +183,33 @@ details.box-padding { margin-bottom: 0; margin-top: 18px; } +.views-ui-view-displays ul { + margin-left: 0; /* LTR */ + padding-left: 0; /* LTR */ + list-style: none; +} +[dir="rtl"] .views-ui-view-displays ul { + margin-right: 0; + padding-right: 0; + margin-left: inherit; + padding-left: inherit; +} /* These header classes are ambiguous and should be scoped to th elements */ .views-ui-name { - width: 18%; + width: 20%; } .views-ui-description { - width: 26%; + width: 30%; } -.views-ui-tag { - width: 8%; +.views-ui-machine-name { + width: 15%; } -.views-ui-path { - width: auto; +.views-ui-displays { + width: 25%; } .views-ui-operations { - width: 24%; + width: 10%; } /** @@ -334,7 +345,7 @@ td.group-title { padding: 0; width: auto; } -.views-displays .tabs li.add ul.action-list li{ +.views-displays .tabs li.add ul.action-list li { margin: 0; } .views-displays .tabs.secondary li { @@ -391,7 +402,7 @@ td.group-title { color: #0074bd; background-color: #f1f1f1; } -.views-displays .tabs .action-list li { +.views-displays .tabs .action-list li { background-color: #f1f1f1; border-color: #cbcbcb; border-style: solid; @@ -401,10 +412,10 @@ td.group-title { .views-displays .tabs .action-list li:first-child { border-width: 1px 1px 0; } -.views-displays .action-list li:last-child { +.views-displays .action-list li:last-child { border-width: 0 1px 1px; } -.views-displays .tabs .action-list li:last-child { +.views-displays .tabs .action-list li:last-child { border-width: 0 1px 1px; } .views-displays .tabs .action-list input.form-submit { @@ -472,7 +483,7 @@ td.group-title { .view-preview-form .form-actions { vertical-align: top; } -@media screen and (min-width:45em) { /* 720px */ +@media screen and (min-width: 45em) { /* 720px */ .view-preview-form .form-type-textfield .description { white-space: nowrap; } @@ -604,7 +615,7 @@ td.group-title { margin: 0; padding: 6px 16px; } -.views-ui-dialog .views-override { +.views-ui-dialog .views-override:not(:empty) { background-color: #f3f4ee; padding: 8px 13px; } diff --git a/core/themes/stable/images/image/error.svg b/core/themes/stable/images/image/error.svg new file mode 100644 index 00000000..1932ea40 --- /dev/null +++ b/core/themes/stable/images/image/error.svg @@ -0,0 +1,4 @@ + + + + diff --git a/core/themes/stable/images/image/upload.svg b/core/themes/stable/images/image/upload.svg new file mode 100644 index 00000000..168bc43e --- /dev/null +++ b/core/themes/stable/images/image/upload.svg @@ -0,0 +1,4 @@ + + + + diff --git a/core/themes/stable/stable.info.yml b/core/themes/stable/stable.info.yml index 9b398276..8ad66148 100644 --- a/core/themes/stable/stable.info.yml +++ b/core/themes/stable/stable.info.yml @@ -98,6 +98,12 @@ libraries-override: css: theme: css/image.admin.css: css/image/image.admin.css + image/quickedit.inPlaceEditor.image: + css: + component: + css/editors/image.css: css/image/editors/image.css + theme: + css/editors/image.theme.css: css/image/editors/image.theme.css language/drupal.language.admin: css: @@ -169,6 +175,9 @@ libraries-override: css/components/reset-appearance.module.css: css/system/components/reset-appearance.module.css css/components/resize.module.css: css/system/components/resize.module.css css/components/sticky-header.module.css: css/system/components/sticky-header.module.css + css/components/system-status-counter.css: css/system/components/system-status-counter.css + css/components/system-status-report-counters.css: css/system/components/system-status-report-counters.css + css/components/system-status-report-general-info.css: css/system/components/system-status-report-general-info.css css/components/tabledrag.module.css: css/system/components/tabledrag.module.css css/components/tablesort.module.css: css/system/components/tablesort.module.css css/components/tree-child.module.css: css/system/components/tree-child.module.css @@ -238,8 +247,8 @@ libraries-override: css/views_ui.admin.theme.css: css/views_ui/views_ui.admin.theme.css css/views_ui.contextual.css: css/views_ui/views_ui.contextual.css -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/themes/stable/templates/admin/status-report-counter.html.twig b/core/themes/stable/templates/admin/status-report-counter.html.twig new file mode 100644 index 00000000..b0f7bd5c --- /dev/null +++ b/core/themes/stable/templates/admin/status-report-counter.html.twig @@ -0,0 +1,15 @@ +{# +/** + * @file + * Theme override for the status report counter. + * + * Available variables: + * - amount: The number shown on counter. + * - text: The text shown on counter. + * - severity: The severity of the counter. + * + * @ingroup themable + */ +#} +{{ amount }} {{ text }} +{{ text }} Details diff --git a/core/themes/stable/templates/admin/status-report-general-info.html.twig b/core/themes/stable/templates/admin/status-report-general-info.html.twig new file mode 100644 index 00000000..c71d8396 --- /dev/null +++ b/core/themes/stable/templates/admin/status-report-general-info.html.twig @@ -0,0 +1,81 @@ +{# +/** + * @file + * Theme override for the status report general info. + * + * Available variables: + * - drupal: The status of Drupal installation: + * - value: The current status of Drupal installation. + * - description: The description for current status of Drupal installation. + * - cron: The status of cron: + * - value: The current status of cron. + * - description: The description for current status of cron. + * - cron.run_cron: An array to render a button for running cron. + * - database_system: The status of database system: + * - value: The current status of database sytem. + * - description: The description for current status of cron. + * - database_system_version: The info about current database version: + * - value: The current version of database. + * - description: The description for current version of database. + * - php: The current version of PHP: + * - value: The status of currently installed PHP version. + * - description: The description for current installed PHP version. + * - php_memory_limit: The info about current PHP memory limit: + * - value: The status of currently set PHP memory limit. + * - description: The description for currently set PHP memory limit. + * - webserver: The info about currently installed web server: + * - value: The status of currently installed web server. + * - description: The description for the status of currently installed web + * server. + */ +#} + +

    {{ 'General System Information'|t }}

    +
    +

    {{ 'Drupal Version'|t }}

    + {{ drupal.value }} + {% if drupal.description %} + {{ drupal.description }} + {% endif %} +
    +
    +

    {{ 'Last Cron Run'|t }}

    + {{ cron.value }} + {% if cron.run_cron %} + {{ cron.run_cron }} + {% endif %} + {% if cron.description %} + {{ cron.description }} + {% endif %} +
    +
    +

    {{ 'Web Server'|t }}

    + {{ webserver.value }} + {% if webserver.description %} + {{ webserver.description }} + {% endif %} +
    +
    +

    {{ 'PHP'|t }}

    +

    {{ 'Version'|t }}

    {{ php.value }} + {% if php.description %} + {{ php.description }} + {% endif %} + +

    {{ 'Memory limit'|t }}

    {{ php_memory_limit.value }} + {% if php_memory_limit.description %} + {{ php_memory_limit.description }} + {% endif %} +
    +
    +

    {{ 'Database'|t }}

    +

    {{ 'Version'|t }}

    {{ database_system_version.value }} + {% if database_system_version.description %} + {{ database_system_version.description }} + {% endif %} + +

    {{ 'System'|t }}

    {{ database_system.value }} + {% if database_system.description %} + {{ database_system.description }} + {% endif %} +
    diff --git a/core/themes/stable/templates/admin/status-report-grouped.html.twig b/core/themes/stable/templates/admin/status-report-grouped.html.twig new file mode 100644 index 00000000..bbeaa47a --- /dev/null +++ b/core/themes/stable/templates/admin/status-report-grouped.html.twig @@ -0,0 +1,49 @@ +{# +/** + * @file + * Theme override of grouped status report requirements. + * + * - grouped_requirements: Contains grouped requirements. + * Each group contains: + * - title: The title of the group. + * - type: The severity of the group. + * - items: The requirement instances. + * Each requirement item contains: + * - title: The title of the requirement. + * - value: (optional) The requirement's status. + * - description: (optional) The requirement's description. + * - severity_title: The title of the severity. + * - severity_status: Indicates the severity status. + */ +#} +{{ attach_library('core/drupal.collapse') }} + +
    + {% for group in grouped_requirements %} +
    +

    {{ group.title }}

    + {% for requirement in group.items %} +
    + {% + set summary_classes = [ + 'system-status-report__status-title', + group.type in ['warning', 'error'] ? 'system-status-report__status-icon system-status-report__status-icon--' ~ group.type + ] + %} + + {% if requirement.severity_title %} + {{ requirement.severity_title }} + {% endif %} + {{ requirement.title }} + +
    + {{ requirement.value }} + {% if requirement.description %} +
    {{ requirement.description }}
    + {% endif %} +
    +
    + {% endfor %} +
    + {% endfor %} +
    diff --git a/core/themes/stable/templates/admin/status-report-page.html.twig b/core/themes/stable/templates/admin/status-report-page.html.twig new file mode 100644 index 00000000..27e0d157 --- /dev/null +++ b/core/themes/stable/templates/admin/status-report-page.html.twig @@ -0,0 +1,28 @@ +{# +/** + * @file + * Theme override for the status report page. + * + * Available variables: + * - counters: The list of counter elements. + * - general_info: A render array to create general info element. + * - requirements: A render array to create requirements table. + * + * @see template_preprocess_status_report() + */ +#} +{% if counters|length == 3 %} + {% set element_width_class = ' system-status-report-counters__item--third-width' %} +{% elseif counters|length == 2 %} + {% set element_width_class = ' system-status-report-counters__item--half-width' %} +{% endif %} +
    + {% for counter in counters %} +
    + {{ counter }} +
    + {% endfor %} +
    + +{{ general_info }} +{{ requirements }} diff --git a/core/themes/stable/templates/admin/views-ui-view-displays-list.html.twig b/core/themes/stable/templates/admin/views-ui-view-displays-list.html.twig new file mode 100644 index 00000000..e6e5b021 --- /dev/null +++ b/core/themes/stable/templates/admin/views-ui-view-displays-list.html.twig @@ -0,0 +1,22 @@ +{# +/** + * @file + * Theme override for views displays on the views listing page. + * + * Available variables: + * - displays: Contains multiple display instances. Each display contains: + * - display: Display name. + * - path: Path to display, if any. + */ +#} +
      + {% for display in displays %} +
    • + {% if display.path %} + {{ display.display }} ({{ display.path }}) + {% else %} + {{ display.display }} + {% endif %} +
    • + {% endfor %} +
    diff --git a/core/themes/stable/templates/admin/views-ui-views-listing-table.html.twig b/core/themes/stable/templates/admin/views-ui-views-listing-table.html.twig new file mode 100644 index 00000000..bc12a0a6 --- /dev/null +++ b/core/themes/stable/templates/admin/views-ui-views-listing-table.html.twig @@ -0,0 +1,47 @@ +{# +/** + * @file + * Theme override for views listing table. + * + * Available variables: + * - headers: Contains table headers. + * - rows: Contains multiple rows. Each row contains: + * - view_name: The human-readable name of the view. + * - machine_name: Machine name of the view. + * - description: The description of the view. + * - displays: List of displays attached to the view. + * - operations: List of available operations. + * + * @see template_preprocess_views_ui_views_listing_table() + */ +#} + +

    + + {% for header in headers %} + {{ header.data }} + {% endfor %} + + + + {% for row in rows %} + + + + + + + + {% endfor %} + +
    +

    {{ row.data.view_name.data }}

    +
    + {{ row.data.machine_name.data }} + + {{ row.data.description.data }} + + {{ row.data.displays.data }} + + {{ row.data.operations.data }} +
    diff --git a/core/themes/stable/templates/content/media.html.twig b/core/themes/stable/templates/content/media.html.twig new file mode 100644 index 00000000..769b7be7 --- /dev/null +++ b/core/themes/stable/templates/content/media.html.twig @@ -0,0 +1,19 @@ +{# +/** + * @file + * Theme override to display a media item. + * + * Available variables: + * - name: Name of the media. + * - content: Media content. + * + * @see template_preprocess_media() + * + * @ingroup themeable + */ +#} + + {% if content %} + {{ content }} + {% endif %} + diff --git a/core/themes/stable/templates/layout/layout--onecol.html.twig b/core/themes/stable/templates/layout/layout--onecol.html.twig new file mode 100644 index 00000000..3a7f9934 --- /dev/null +++ b/core/themes/stable/templates/layout/layout--onecol.html.twig @@ -0,0 +1,25 @@ +{# +/** + * @file + * Default theme implementation to display a one-column layout. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'layout', + 'layout--onecol', + ] +%} +{% if content %} + +
    + {{ content.content }} +
    +
    +{% endif %} diff --git a/core/themes/stable/templates/layout/layout--threecol-25-50-25.html.twig b/core/themes/stable/templates/layout/layout--threecol-25-50-25.html.twig new file mode 100644 index 00000000..e5441d8b --- /dev/null +++ b/core/themes/stable/templates/layout/layout--threecol-25-50-25.html.twig @@ -0,0 +1,54 @@ +{# +/** + * @file + * Default theme implementation for a three column layout. + * + * This template provides a three column 25%-50%-25% display layout, with + * additional areas for the top and the bottom. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'layout', + 'layout--threecol-25-50-25', + ] +%} +{% if content %} + + {% if content.top %} +
    + {{ content.top }} +
    + {% endif %} + + {% if content.first %} +
    + {{ content.first }} +
    + {% endif %} + + {% if content.second %} +
    + {{ content.second }} +
    + {% endif %} + + {% if content.third %} +
    + {{ content.third }} +
    + {% endif %} + + {% if content.bottom %} +
    + {{ content.bottom }} +
    + {% endif %} +
    +{% endif %} diff --git a/core/themes/stable/templates/layout/layout--threecol-33-34-33.html.twig b/core/themes/stable/templates/layout/layout--threecol-33-34-33.html.twig new file mode 100644 index 00000000..6445061c --- /dev/null +++ b/core/themes/stable/templates/layout/layout--threecol-33-34-33.html.twig @@ -0,0 +1,54 @@ +{# +/** + * @file + * Default theme implementation for a three column layout. + * + * This template provides a three column 33%-34%-33% display layout, with + * additional areas for the top and the bottom. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'layout', + 'layout--threecol-33-34-33', + ] +%} +{% if content %} + + {% if content.top %} +
    + {{ content.top }} +
    + {% endif %} + + {% if content.first %} +
    + {{ content.first }} +
    + {% endif %} + + {% if content.second %} +
    + {{ content.second }} +
    + {% endif %} + + {% if content.third %} +
    + {{ content.third }} +
    + {% endif %} + + {% if content.bottom %} +
    + {{ content.bottom }} +
    + {% endif %} +
    +{% endif %} diff --git a/core/themes/stable/templates/layout/layout--twocol-bricks.html.twig b/core/themes/stable/templates/layout/layout--twocol-bricks.html.twig new file mode 100644 index 00000000..dc29e03e --- /dev/null +++ b/core/themes/stable/templates/layout/layout--twocol-bricks.html.twig @@ -0,0 +1,66 @@ +{# +/** + * @file + * Default theme implementation for a two column layout. + * + * This template provides a two column display layout with full width areas at + * the top, bottom and in the middle. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'layout', + 'layout--twocol-bricks', + ] +%} +{% if content %} + + {% if content.top %} +
    + {{ content.top }} +
    + {% endif %} + + {% if content.first_above %} +
    + {{ content.first_above }} +
    + {% endif %} + + {% if content.second_above %} +
    + {{ content.second_above }} +
    + {% endif %} + + {% if content.middle %} +
    + {{ content.middle }} +
    + {% endif %} + + {% if content.first_below %} +
    + {{ content.first_below }} +
    + {% endif %} + + {% if content.second_below %} +
    + {{ content.second_below }} +
    + {% endif %} + + {% if content.bottom %} +
    + {{ content.bottom }} +
    + {% endif %} +
    +{% endif %} diff --git a/core/themes/stable/templates/layout/layout--twocol.html.twig b/core/themes/stable/templates/layout/layout--twocol.html.twig new file mode 100644 index 00000000..262c657f --- /dev/null +++ b/core/themes/stable/templates/layout/layout--twocol.html.twig @@ -0,0 +1,45 @@ +{# +/** + * @file + * Default theme implementation to display a two-column layout. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'layout', + 'layout--twocol', + ] +%} +{% if content %} + + {% if content.top %} +
    + {{ content.top }} +
    + {% endif %} + + {% if content.first %} +
    + {{ content.first }} +
    + {% endif %} + + {% if content.second %} +
    + {{ content.second }} +
    + {% endif %} + + {% if content.bottom %} +
    + {{ content.bottom }} +
    + {% endif %} +
    +{% endif %} diff --git a/core/themes/stable/templates/layout/layout.html.twig b/core/themes/stable/templates/layout/layout.html.twig new file mode 100644 index 00000000..59df5c64 --- /dev/null +++ b/core/themes/stable/templates/layout/layout.html.twig @@ -0,0 +1,23 @@ +{# +/** + * @file + * Template for a generic layout. + */ +#} +{% + set classes = [ + 'layout', + 'layout--' ~ layout.id|clean_class, + ] +%} +{% if content %} + + {% for region in layout.getRegionNames %} + {% if content[region] %} +
    + {{ content[region] }} +
    + {% endif %} + {% endfor %} + +{% endif %} diff --git a/core/themes/stable/templates/user/username.html.twig b/core/themes/stable/templates/user/username.html.twig index 480225f1..7f62f9b4 100644 --- a/core/themes/stable/templates/user/username.html.twig +++ b/core/themes/stable/templates/user/username.html.twig @@ -5,10 +5,16 @@ * * Available variables: * - account: The full account information for the user. - * - name: The user's name, sanitized. + * - uid: The user ID, or zero if not a user. As used in anonymous comments. + * - name: The user's name, sanitized, and optionally truncated. + * - name_raw: The user's name, un-truncated. + * - truncated: Whether the user's name was truncated. * - extra: Additional text to append to the user's name, sanitized. + * - profile_access: Whether the current user has permission to access this + users profile page. * - link_path: The path or URL of the user's profile page, home page, * or other desired page to link to for more information about the user. + * - homepage: (optional) The home page of the account, only set for non users. * - link_options: Options to set on the \Drupal\Core\Url object if linking the * user's name to the user's page. * - attributes: HTML attributes for the containing element. diff --git a/core/themes/stable/templates/views/views-view-opml.html.twig b/core/themes/stable/templates/views/views-view-opml.html.twig index a48843ae..4165ccf4 100644 --- a/core/themes/stable/templates/views/views-view-opml.html.twig +++ b/core/themes/stable/templates/views/views-view-opml.html.twig @@ -11,7 +11,7 @@ * @see template_preprocess_views_view_opml() */ #} - + {{ title }} diff --git a/core/themes/stable/templates/views/views-view-rss.html.twig b/core/themes/stable/templates/views/views-view-rss.html.twig index f772d637..0800237e 100644 --- a/core/themes/stable/templates/views/views-view-rss.html.twig +++ b/core/themes/stable/templates/views/views-view-rss.html.twig @@ -15,7 +15,7 @@ * @see template_preprocess_views_view_rss() */ #} - + {{ title }} diff --git a/core/themes/stark/README.txt b/core/themes/stark/README.txt index 552261ab..62bf058a 100644 --- a/core/themes/stark/README.txt +++ b/core/themes/stark/README.txt @@ -17,7 +17,7 @@ ABOUT DRUPAL THEMING -------------------- To learn how to build your own custom theme and override Drupal's default code, -see the Theming Guide: https://www.drupal.org/theme-guide +see the Theming Guide: https://www.drupal.org/docs/8/theming See the themes/README.txt for more information on where to place your custom themes to ensure easy maintenance and upgrades. diff --git a/core/themes/stark/stark.info.yml b/core/themes/stark/stark.info.yml index 6d38f277..9d8600da 100644 --- a/core/themes/stark/stark.info.yml +++ b/core/themes/stark/stark.info.yml @@ -1,13 +1,13 @@ name: Stark type: theme -description: 'An intentionally plain theme with no styling to demonstrate default Drupal’s HTML and CSS. Learn how to build a custom theme from Stark in the Theming Guide.' +description: 'An intentionally plain theme with no styling to demonstrate default Drupal’s HTML and CSS. Learn how to build a custom theme from Stark in the Theming Guide.' package: Core # version: VERSION # core: 8.x base theme: false -# Information added by Drupal.org packaging script on 2017-02-01 -version: '8.2.6' +# Information added by Drupal.org packaging script on 2017-11-01 +version: '8.4.1' core: '8.x' project: 'drupal' -datestamp: 1485975642 +datestamp: 1509562424 diff --git a/core/yarn.lock b/core/yarn.lock new file mode 100644 index 00000000..d4bab4ac --- /dev/null +++ b/core/yarn.lock @@ -0,0 +1,3093 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +JSONStream@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-0.8.4.tgz#91657dfe6ff857483066132b4618b62e8f4887bd" + dependencies: + jsonparse "0.0.5" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +aproba@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +aria-query@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.3.0.tgz#cb8a9984e2862711c83c80ade5b8f5ca0de2b467" + dependencies: + ast-types-flow "0.0.7" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array.prototype.find@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +ast-types-flow@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +autoprefixer@^6.0.0: + version "6.7.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" + dependencies: + browserslist "^1.7.6" + caniuse-db "^1.0.30000634" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^5.2.16" + postcss-value-parser "^3.2.3" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-core@6.24.1, babel-core@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.24.1" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-add-header-comment@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-add-header-comment/-/babel-plugin-add-header-comment-1.0.3.tgz#511c4901062640d5a480b4ac3edd6944195850ec" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + lodash "^4.2.0" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" + dependencies: + regenerator-transform "0.9.11" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.4.0.tgz#c8e02a3bcc7792f23cded68e0355b9d4c28f0f7a" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^1.4.0" + invariant "^2.2.2" + +babel-register@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" + dependencies: + babel-core "^6.24.1" + babel-runtime "^6.22.0" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-template@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + lodash "^4.2.0" + +babel-traverse@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babylon "^6.15.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.19.0, babel-types@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.11.0, babylon@^6.15.0: + version "6.17.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.0.tgz#37da948878488b9c4e3c4038893fa3314b3fc932" + +balanced-match@^0.4.0, balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +brace-expansion@^1.0.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browserslist@^1.1.1, browserslist@^1.1.3, browserslist@^1.4.0, browserslist@^1.7.6: + version "1.7.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" + dependencies: + caniuse-db "^1.0.30000639" + electron-to-chromium "^1.2.7" + +buffer-shims@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0, camelcase@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: + version "1.0.30000664" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000664.tgz#e16316e5fdabb9c7209b2bf0744ffc8a14201f22" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chokidar@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +circular-json@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +cliui@^3.0.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.0.tgz#eae0a2413f55c0942f818c229fefce845d7f3b1c" + dependencies: + is-regexp "^1.0.0" + is-supported-regexp-flag "^1.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +color-diff@^0.1.3: + version "0.1.7" + resolved "https://registry.yarnpkg.com/color-diff/-/color-diff-0.1.7.tgz#6db78cd9482a8e459d40821eaf4b503283dcb8e2" + +colorguard@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/colorguard/-/colorguard-1.2.0.tgz#f3facaf5caaeba4ef54653d9fb25bb73177c0d84" + dependencies: + chalk "^1.1.1" + color-diff "^0.1.3" + log-symbols "^1.0.2" + object-assign "^4.0.1" + pipetteur "^2.0.0" + plur "^2.0.0" + postcss "^5.0.4" + postcss-reporter "^1.2.1" + text-table "^0.2.0" + yargs "^1.2.6" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + +convert-source-map@^1.1.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + +core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cosmiconfig@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.1.3.tgz#952771eb0dddc1cb3fa2f6fbe51a522e93b3ee0a" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.4.3" + minimist "^1.2.0" + object-assign "^4.1.0" + os-homedir "^1.0.1" + parse-json "^2.2.0" + require-from-string "^1.1.0" + +cross-env@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-4.0.0.tgz#16083862d08275a4628b0b243b121bedaa55dd80" + dependencies: + cross-spawn "^5.1.0" + is-windows "^1.0.0" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +css-color-names@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.3.tgz#de0cef16f4d8aa8222a320d5b6d7e9bbada7b9f6" + +css-rule-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-rule-stream/-/css-rule-stream-1.1.0.tgz#3786e7198983d965a26e31957e09078cbb7705a2" + dependencies: + css-tokenize "^1.0.1" + duplexer2 "0.0.2" + ldjson-stream "^1.2.1" + through2 "^0.6.3" + +css-tokenize@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-tokenize/-/css-tokenize-1.0.1.tgz#4625cb1eda21c143858b7f81d6803c1d26fc14be" + dependencies: + inherits "^2.0.1" + readable-stream "^1.0.33" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +damerau-levenshtein@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debug@^2.1.1, debug@^2.2.0, debug@^2.6.0: + version "2.6.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a" + dependencies: + ms "0.7.3" + +decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +doctrine@1.5.0, doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doiuse@^2.4.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/doiuse/-/doiuse-2.6.0.tgz#1892d10b61a9a356addbf2b614933e81f8bb3834" + dependencies: + browserslist "^1.1.1" + caniuse-db "^1.0.30000187" + css-rule-stream "^1.1.0" + duplexer2 "0.0.2" + jsonfilter "^1.1.2" + ldjson-stream "^1.2.1" + lodash "^4.0.0" + multimatch "^2.0.0" + postcss "^5.0.8" + source-map "^0.4.2" + through2 "^0.6.3" + yargs "^3.5.4" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + dependencies: + readable-stream "~1.1.9" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +electron-to-chromium@^1.2.7: + version "1.3.8" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.8.tgz#b2c8a2c79bb89fbbfd3724d9555e15095b5f5fb6" + +emoji-regex@^6.1.0: + version "6.4.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.4.2.tgz#a30b6fee353d406d96cfb9fa765bdc82897eff6e" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.0" + is-callable "^1.1.3" + is-regex "^1.0.3" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.15" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-airbnb-base@^11.1.0: + version "11.1.3" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.3.tgz#0e8db71514fa36b977fbcf977c01edcf863e0cf0" + +eslint-config-airbnb@14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-14.1.0.tgz#355d290040bbf8e00bf8b4b19f4b70cbe7c2317f" + dependencies: + eslint-config-airbnb-base "^11.1.0" + +eslint-import-resolver-node@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" + dependencies: + debug "^2.2.0" + object-assign "^4.0.1" + resolve "^1.1.6" + +eslint-module-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" + dependencies: + debug "2.2.0" + pkg-dir "^1.0.0" + +eslint-plugin-import@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.2.0" + doctrine "1.5.0" + eslint-import-resolver-node "^0.2.0" + eslint-module-utils "^2.0.0" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + pkg-up "^1.0.0" + +eslint-plugin-jsx-a11y@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-4.0.0.tgz#779bb0fe7b08da564a422624911de10061e048ee" + dependencies: + aria-query "^0.3.0" + ast-types-flow "0.0.7" + damerau-levenshtein "^1.0.0" + emoji-regex "^6.1.0" + jsx-ast-utils "^1.0.0" + object-assign "^4.0.1" + +eslint-plugin-react@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78" + dependencies: + array.prototype.find "^2.0.1" + doctrine "^1.2.2" + has "^1.0.1" + jsx-ast-utils "^1.3.4" + object.assign "^4.0.4" + +eslint@3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.4.0: + version "3.4.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.2.tgz#38dbdedbedc95b8961a1fbf04734a8f6a9c8c592" + dependencies: + acorn "^5.0.1" + acorn-jsx "^3.0.0" + +esprima@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + dependencies: + estraverse "~4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +estraverse@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + +execall@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73" + dependencies: + clone-regexp "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +flatten@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +gather-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gather-stream/-/gather-stream-1.0.0.tgz#b33994af457a8115700d410f317733cbe7a0904b" + +gauge@~2.7.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +get-stdin@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.0.0, globals@^9.14.0: + version "9.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globjoin@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.4.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" + +html-tags@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-1.1.1.tgz#869f43859f12d9bdc3892419e494a628aa1b204e" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +ignore@^3.2.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.7.tgz#4810ca5f1d8eca5595213a34b94f2eb4ed926bbd" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" + +invariant@^2.2.0, invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +irregular-plurals@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-my-json-valid@^2.10.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-regex@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-supported-regexp-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +js-base64@^2.1.9: + version "2.1.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +js-yaml@^3.4.3, js-yaml@^3.5.1: + version "3.8.3" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766" + dependencies: + argparse "^1.0.7" + esprima "^3.1.1" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfilter@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/jsonfilter/-/jsonfilter-1.1.2.tgz#21ef7cedc75193813c75932e96a98be205ba5a11" + dependencies: + JSONStream "^0.8.4" + minimist "^1.1.0" + stream-combiner "^0.2.1" + through2 "^0.6.3" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonparse@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-0.0.5.tgz#330542ad3f0a654665b778f3eb2d9a9fa507ac64" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" + dependencies: + assert-plus "1.0.0" + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" + +kind-of@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.0.tgz#b58abe4d5c044ad33726a8c1525b48cf891bff07" + dependencies: + is-buffer "^1.1.5" + +known-css-properties@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.0.7.tgz#9104343a2adfd8ef3b07bdee7a325e4d44ed9371" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +ldjson-stream@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ldjson-stream/-/ldjson-stream-1.2.1.tgz#91beceda5ac4ed2b17e649fb777e7abfa0189c2b" + dependencies: + split2 "^0.2.1" + through2 "^0.6.1" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + +lodash@^3.0.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" + +mime-types@^2.1.12, mime-types@~2.1.7: + version "2.1.15" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" + dependencies: + mime-db "~1.27.0" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" + +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +nan@^2.3.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +node-pre-gyp@^0.6.29: + version "0.6.34" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" + dependencies: + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "^2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + +normalize-selector@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" + +npmlog@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-keys@^1.0.10, object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object.assign@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.0" + object-keys "^1.0.10" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +once@^1.3.0, once@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onecolor@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.4.tgz#75a46f80da6c7aaa5b4daae17a47198bd9652494" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pipetteur@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pipetteur/-/pipetteur-2.0.3.tgz#1955760959e8d1a11cb2a50ec83eec470633e49f" + dependencies: + onecolor "^3.0.4" + synesthesia "^1.0.1" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +pkg-up@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + dependencies: + find-up "^1.0.0" + +plur@^2.0.0, plur@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + dependencies: + irregular-plurals "^1.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +postcss-less@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-0.14.0.tgz#c631b089c6cce422b9a10f3a958d2bedd3819324" + dependencies: + postcss "^5.0.21" + +postcss-media-query-parser@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" + +postcss-reporter@^1.2.1, postcss-reporter@^1.3.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-1.4.1.tgz#c136f0a5b161915f379dd3765c61075f7e7b9af2" + dependencies: + chalk "^1.0.0" + lodash "^4.1.0" + log-symbols "^1.0.2" + postcss "^5.0.0" + +postcss-reporter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-3.0.0.tgz#09ea0f37a444c5693878606e09b018ebeff7cf8f" + dependencies: + chalk "^1.0.0" + lodash "^4.1.0" + log-symbols "^1.0.2" + postcss "^5.0.0" + +postcss-resolve-nested-selector@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" + +postcss-scss@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-0.4.1.tgz#ad771b81f0f72f5f4845d08aa60f93557653d54c" + dependencies: + postcss "^5.2.13" + +postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.1.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-value-parser@^3.1.1, postcss-value-parser@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" + +postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.8, postcss@^5.2.13, postcss@^5.2.16, postcss@^5.2.4: + version "5.2.17" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b" + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +private@^0.1.6: + version "0.1.7" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +rc@^1.1.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-file-stdin@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/read-file-stdin/-/read-file-stdin-0.2.1.tgz#25eccff3a153b6809afacb23ee15387db9e0ee61" + dependencies: + gather-stream "^1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^1.0.33, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: + version "2.2.9" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" + dependencies: + buffer-shims "~1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~1.0.0" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + +regenerator-transform@0.9.11: + version "0.9.11" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + +resolve@^1.1.6: + version "1.3.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +safe-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shelljs@^0.7.5: + version "0.7.7" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +source-map-support@^0.4.2: + version "0.4.15" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" + dependencies: + source-map "^0.5.6" + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +specificity@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.3.0.tgz#332472d4e5eb5af20821171933998a6bc3b1ce6f" + +split2@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/split2/-/split2-0.2.1.tgz#02ddac9adc03ec0bb78c1282ec079ca6e85ae900" + dependencies: + through2 "~0.6.1" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stream-combiner@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^3.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667" + dependencies: + buffer-shims "~1.0.0" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +style-search@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" + +stylehacks@^2.3.1, stylehacks@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-2.3.2.tgz#64c83e0438a68c9edf449e8c552a7d9ab6009b0b" + dependencies: + browserslist "^1.1.3" + chalk "^1.1.1" + log-symbols "^1.0.2" + minimist "^1.2.0" + plur "^2.1.2" + postcss "^5.0.18" + postcss-reporter "^1.3.3" + postcss-selector-parser "^2.0.0" + read-file-stdin "^0.2.1" + text-table "^0.2.0" + write-file-stdout "0.0.2" + +stylelint-checkstyle-formatter@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stylelint-checkstyle-formatter/-/stylelint-checkstyle-formatter-0.1.0.tgz#8c402853e92a0aae83715670caf63e79f21199a7" + dependencies: + lodash "^3.0.0" + +stylelint-config-standard@^16.0.0: + version "16.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-16.0.0.tgz#bb7387bff1d7dd7186a52b3ebf885b2405d691bf" + +stylelint-no-browser-hacks@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stylelint-no-browser-hacks/-/stylelint-no-browser-hacks-1.0.2.tgz#2a94ac8021ade88706afbc64ef5b940c5fef12f2" + dependencies: + stylehacks "^2.3.1" + stylelint "^7.8.0" + +stylelint@^7.10.1, stylelint@^7.8.0: + version "7.10.1" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-7.10.1.tgz#209a7ce5e781fc2a62489fbb31ec0201ec675db2" + dependencies: + autoprefixer "^6.0.0" + balanced-match "^0.4.0" + chalk "^1.1.1" + colorguard "^1.2.0" + cosmiconfig "^2.1.1" + debug "^2.6.0" + doiuse "^2.4.1" + execall "^1.0.0" + file-entry-cache "^2.0.0" + get-stdin "^5.0.0" + globby "^6.0.0" + globjoin "^0.1.4" + html-tags "^1.1.1" + ignore "^3.2.0" + imurmurhash "^0.1.4" + known-css-properties "^0.0.7" + lodash "^4.17.4" + log-symbols "^1.0.2" + meow "^3.3.0" + micromatch "^2.3.11" + normalize-selector "^0.2.0" + postcss "^5.0.20" + postcss-less "^0.14.0" + postcss-media-query-parser "^0.2.0" + postcss-reporter "^3.0.0" + postcss-resolve-nested-selector "^0.1.1" + postcss-scss "^0.4.0" + postcss-selector-parser "^2.1.1" + postcss-value-parser "^3.1.1" + resolve-from "^2.0.0" + specificity "^0.3.0" + string-width "^2.0.0" + style-search "^0.1.0" + stylehacks "^2.3.2" + sugarss "^0.2.0" + svg-tags "^1.0.0" + table "^4.0.1" + +sugarss@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-0.2.0.tgz#ac34237563327c6ff897b64742bf6aec190ad39e" + dependencies: + postcss "^5.2.4" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +svg-tags@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" + +synesthesia@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/synesthesia/-/synesthesia-1.0.1.tgz#5ef95ea548c0d5c6e6f9bb4b0d0731dff864a777" + dependencies: + css-color-names "0.0.3" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +table@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tar-pack@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through2@^0.6.1, through2@^0.6.3, through2@~0.6.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +"through@>=2.2.7 <3", through@^2.3.6, through@~2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +which@^1.2.9: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +window-size@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-stdout@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/write-file-stdout/-/write-file-stdout-0.0.2.tgz#c252d7c7c5b1b402897630e3453c7bfe690d9ca1" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs@^1.2.6: + version "1.3.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a" + +yargs@^3.5.4: + version "3.32.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + dependencies: + camelcase "^2.0.1" + cliui "^3.0.3" + decamelize "^1.1.1" + os-locale "^1.4.0" + string-width "^1.0.1" + window-size "^0.1.4" + y18n "^3.2.0" diff --git a/example.gitignore b/example.gitignore index c292c2e9..d1e35ac0 100644 --- a/example.gitignore +++ b/example.gitignore @@ -37,7 +37,3 @@ sites/simpletest # Ignore SimpleTest multi-site environment. # simpletest - -# Ignore core phpcs.xml and phpunit.xml. -core/phpcs.xml -core/phpunit.xml diff --git a/themes/bootstrap/bootstrap.info.yml b/themes/bootstrap/bootstrap.info.yml index 1d9e6294..50384096 100644 --- a/themes/bootstrap/bootstrap.info.yml +++ b/themes/bootstrap/bootstrap.info.yml @@ -35,6 +35,8 @@ libraries-extend: - bootstrap/drupal.states core/drupal.tabledrag: - bootstrap/drupal.tabledrag + image_widget_crop/cropper.integration: + - bootstrap/image_widget_crop views/views.ajax: - bootstrap/views.ajax @@ -78,8 +80,8 @@ libraries-override: # core/drupal.dialog: bootstrap/drupal.dialog # core/drupal.dialog.ajax: bootstrap/drupal.dialog.ajax -# Information added by Drupal.org packaging script on 2017-02-21 -version: '8.x-3.2' +# Information added by Drupal.org packaging script on 2017-09-25 +version: '8.x-3.6' core: '8.x' project: 'bootstrap' -datestamp: 1487640792 +datestamp: 1506357855 diff --git a/themes/bootstrap/bootstrap.libraries.yml b/themes/bootstrap/bootstrap.libraries.yml index aed147ff..b98efe03 100644 --- a/themes/bootstrap/bootstrap.libraries.yml +++ b/themes/bootstrap/bootstrap.libraries.yml @@ -87,6 +87,10 @@ drupal.tabledrag: js: js/misc/tabledrag.js: {} +image_widget_crop: + js: + js/modules/image_widget_crop/ImageWidgetCrop.js: {} + views.ajax: js: js/modules/views/ajax_view.js: {} diff --git a/themes/bootstrap/css/3.0.0/overrides-amelia.min.css b/themes/bootstrap/css/3.0.0/overrides-amelia.min.css index 2d666d64..377e95c4 100644 --- a/themes/bootstrap/css/3.0.0/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-cerulean.min.css b/themes/bootstrap/css/3.0.0/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.0.0/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-cosmo.min.css b/themes/bootstrap/css/3.0.0/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.0.0/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-cyborg.min.css b/themes/bootstrap/css/3.0.0/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.0.0/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-flatly.min.css b/themes/bootstrap/css/3.0.0/overrides-flatly.min.css index 43bb187e..aaa43464 100644 --- a/themes/bootstrap/css/3.0.0/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1 #ddd #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1 #ddd #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-journal.min.css b/themes/bootstrap/css/3.0.0/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.0.0/overrides-journal.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-readable.min.css b/themes/bootstrap/css/3.0.0/overrides-readable.min.css index 6b6ddab0..1b193008 100644 --- a/themes/bootstrap/css/3.0.0/overrides-readable.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:15px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:15px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lora,Georgia,"Times New Roman",Times,serif;font-size:17px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:22px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:15px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:15px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lora,Georgia,"Times New Roman",Times,serif;font-size:17px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:22px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-simplex.min.css b/themes/bootstrap/css/3.0.0/overrides-simplex.min.css index cd66c6c0..87a207f5 100644 --- a/themes/bootstrap/css/3.0.0/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-slate.min.css b/themes/bootstrap/css/3.0.0/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.0.0/overrides-slate.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-spacelab.min.css b/themes/bootstrap/css/3.0.0/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.0.0/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides-united.min.css b/themes/bootstrap/css/3.0.0/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.0.0/overrides-united.min.css +++ b/themes/bootstrap/css/3.0.0/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.0/overrides.min.css b/themes/bootstrap/css/3.0.0/overrides.min.css index 9af3842c..11c60678 100644 --- a/themes/bootstrap/css/3.0.0/overrides.min.css +++ b/themes/bootstrap/css/3.0.0/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-amelia.min.css b/themes/bootstrap/css/3.0.1/overrides-amelia.min.css index 504dd97f..14ef124a 100644 --- a/themes/bootstrap/css/3.0.1/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-cerulean.min.css b/themes/bootstrap/css/3.0.1/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.0.1/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-cosmo.min.css b/themes/bootstrap/css/3.0.1/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.0.1/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-cyborg.min.css b/themes/bootstrap/css/3.0.1/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.0.1/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-flatly.min.css b/themes/bootstrap/css/3.0.1/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.0.1/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-journal.min.css b/themes/bootstrap/css/3.0.1/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.0.1/overrides-journal.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-readable.min.css b/themes/bootstrap/css/3.0.1/overrides-readable.min.css index 6b6ddab0..1b193008 100644 --- a/themes/bootstrap/css/3.0.1/overrides-readable.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:15px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:15px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lora,Georgia,"Times New Roman",Times,serif;font-size:17px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:22px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:15px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:15px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lora,Georgia,"Times New Roman",Times,serif;font-size:17px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:22px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-simplex.min.css b/themes/bootstrap/css/3.0.1/overrides-simplex.min.css index cd66c6c0..87a207f5 100644 --- a/themes/bootstrap/css/3.0.1/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-slate.min.css b/themes/bootstrap/css/3.0.1/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.0.1/overrides-slate.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-spacelab.min.css b/themes/bootstrap/css/3.0.1/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.0.1/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides-united.min.css b/themes/bootstrap/css/3.0.1/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.0.1/overrides-united.min.css +++ b/themes/bootstrap/css/3.0.1/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.1/overrides.min.css b/themes/bootstrap/css/3.0.1/overrides.min.css index 224dc7a2..23376fc7 100644 --- a/themes/bootstrap/css/3.0.1/overrides.min.css +++ b/themes/bootstrap/css/3.0.1/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-amelia.min.css b/themes/bootstrap/css/3.0.2/overrides-amelia.min.css index 504dd97f..14ef124a 100644 --- a/themes/bootstrap/css/3.0.2/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-cerulean.min.css b/themes/bootstrap/css/3.0.2/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.0.2/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-cosmo.min.css b/themes/bootstrap/css/3.0.2/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.0.2/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-cyborg.min.css b/themes/bootstrap/css/3.0.2/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.0.2/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-flatly.min.css b/themes/bootstrap/css/3.0.2/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.0.2/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-journal.min.css b/themes/bootstrap/css/3.0.2/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.0.2/overrides-journal.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-readable.min.css b/themes/bootstrap/css/3.0.2/overrides-readable.min.css index 6b6ddab0..1b193008 100644 --- a/themes/bootstrap/css/3.0.2/overrides-readable.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:15px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:15px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lora,Georgia,"Times New Roman",Times,serif;font-size:17px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:22px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:15px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:15px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lora,Georgia,"Times New Roman",Times,serif;font-size:17px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:22px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-simplex.min.css b/themes/bootstrap/css/3.0.2/overrides-simplex.min.css index cd66c6c0..87a207f5 100644 --- a/themes/bootstrap/css/3.0.2/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-slate.min.css b/themes/bootstrap/css/3.0.2/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.0.2/overrides-slate.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-spacelab.min.css b/themes/bootstrap/css/3.0.2/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.0.2/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-united.min.css b/themes/bootstrap/css/3.0.2/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.0.2/overrides-united.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides-yeti.min.css b/themes/bootstrap/css/3.0.2/overrides-yeti.min.css index 224dc7a2..23376fc7 100644 --- a/themes/bootstrap/css/3.0.2/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.0.2/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.2/overrides.min.css b/themes/bootstrap/css/3.0.2/overrides.min.css index 224dc7a2..23376fc7 100644 --- a/themes/bootstrap/css/3.0.2/overrides.min.css +++ b/themes/bootstrap/css/3.0.2/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-amelia.min.css b/themes/bootstrap/css/3.0.3/overrides-amelia.min.css index 504dd97f..14ef124a 100644 --- a/themes/bootstrap/css/3.0.3/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-cerulean.min.css b/themes/bootstrap/css/3.0.3/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.0.3/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-cosmo.min.css b/themes/bootstrap/css/3.0.3/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.0.3/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-cyborg.min.css b/themes/bootstrap/css/3.0.3/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.0.3/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'▼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-flatly.min.css b/themes/bootstrap/css/3.0.3/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.0.3/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-journal.min.css b/themes/bootstrap/css/3.0.3/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.0.3/overrides-journal.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-readable.min.css b/themes/bootstrap/css/3.0.3/overrides-readable.min.css index 865612e7..99acc499 100644 --- a/themes/bootstrap/css/3.0.3/overrides-readable.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#5cb85c}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#5cb85c}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-simplex.min.css b/themes/bootstrap/css/3.0.3/overrides-simplex.min.css index cd66c6c0..87a207f5 100644 --- a/themes/bootstrap/css/3.0.3/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-slate.min.css b/themes/bootstrap/css/3.0.3/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.0.3/overrides-slate.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-spacelab.min.css b/themes/bootstrap/css/3.0.3/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.0.3/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-united.min.css b/themes/bootstrap/css/3.0.3/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.0.3/overrides-united.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides-yeti.min.css b/themes/bootstrap/css/3.0.3/overrides-yeti.min.css index c4c3f04f..86323908 100644 --- a/themes/bootstrap/css/3.0.3/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.0.3/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.0.3/overrides.min.css b/themes/bootstrap/css/3.0.3/overrides.min.css index 82971f93..db53eb60 100644 --- a/themes/bootstrap/css/3.0.3/overrides.min.css +++ b/themes/bootstrap/css/3.0.3/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-amelia.min.css b/themes/bootstrap/css/3.1.0/overrides-amelia.min.css index 504dd97f..14ef124a 100644 --- a/themes/bootstrap/css/3.1.0/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-cerulean.min.css b/themes/bootstrap/css/3.1.0/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.1.0/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-cosmo.min.css b/themes/bootstrap/css/3.1.0/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.1.0/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-cyborg.min.css b/themes/bootstrap/css/3.1.0/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.1.0/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-flatly.min.css b/themes/bootstrap/css/3.1.0/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.1.0/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-journal.min.css b/themes/bootstrap/css/3.1.0/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.1.0/overrides-journal.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-lumen.min.css b/themes/bootstrap/css/3.1.0/overrides-lumen.min.css index 82971f93..db53eb60 100644 --- a/themes/bootstrap/css/3.1.0/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-readable.min.css b/themes/bootstrap/css/3.1.0/overrides-readable.min.css index 865612e7..99acc499 100644 --- a/themes/bootstrap/css/3.1.0/overrides-readable.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#5cb85c}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#5cb85c}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-simplex.min.css b/themes/bootstrap/css/3.1.0/overrides-simplex.min.css index cd66c6c0..87a207f5 100644 --- a/themes/bootstrap/css/3.1.0/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-slate.min.css b/themes/bootstrap/css/3.1.0/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.1.0/overrides-slate.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-spacelab.min.css b/themes/bootstrap/css/3.1.0/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.1.0/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-superhero.min.css b/themes/bootstrap/css/3.1.0/overrides-superhero.min.css index 82971f93..db53eb60 100644 --- a/themes/bootstrap/css/3.1.0/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-united.min.css b/themes/bootstrap/css/3.1.0/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.1.0/overrides-united.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides-yeti.min.css b/themes/bootstrap/css/3.1.0/overrides-yeti.min.css index c4c3f04f..86323908 100644 --- a/themes/bootstrap/css/3.1.0/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.1.0/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.0/overrides.min.css b/themes/bootstrap/css/3.1.0/overrides.min.css index 82971f93..db53eb60 100644 --- a/themes/bootstrap/css/3.1.0/overrides.min.css +++ b/themes/bootstrap/css/3.1.0/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-amelia.min.css b/themes/bootstrap/css/3.1.1/overrides-amelia.min.css index 504dd97f..14ef124a 100644 --- a/themes/bootstrap/css/3.1.1/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-cerulean.min.css b/themes/bootstrap/css/3.1.1/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.1.1/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-cosmo.min.css b/themes/bootstrap/css/3.1.1/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.1.1/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-cyborg.min.css b/themes/bootstrap/css/3.1.1/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.1.1/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-darkly.min.css b/themes/bootstrap/css/3.1.1/overrides-darkly.min.css index 82971f93..db53eb60 100644 --- a/themes/bootstrap/css/3.1.1/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-flatly.min.css b/themes/bootstrap/css/3.1.1/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.1.1/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-journal.min.css b/themes/bootstrap/css/3.1.1/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.1.1/overrides-journal.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-lumen.min.css b/themes/bootstrap/css/3.1.1/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.1.1/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-readable.min.css b/themes/bootstrap/css/3.1.1/overrides-readable.min.css index 91ff3ca8..14dcf59a 100644 --- a/themes/bootstrap/css/3.1.1/overrides-readable.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-simplex.min.css b/themes/bootstrap/css/3.1.1/overrides-simplex.min.css index c94a1dc7..5614d1b4 100644 --- a/themes/bootstrap/css/3.1.1/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-slate.min.css b/themes/bootstrap/css/3.1.1/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.1.1/overrides-slate.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-spacelab.min.css b/themes/bootstrap/css/3.1.1/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.1.1/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-superhero.min.css b/themes/bootstrap/css/3.1.1/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.1.1/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-united.min.css b/themes/bootstrap/css/3.1.1/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.1.1/overrides-united.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides-yeti.min.css b/themes/bootstrap/css/3.1.1/overrides-yeti.min.css index c4c3f04f..86323908 100644 --- a/themes/bootstrap/css/3.1.1/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.1.1/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.1.1/overrides.min.css b/themes/bootstrap/css/3.1.1/overrides.min.css index 82971f93..db53eb60 100644 --- a/themes/bootstrap/css/3.1.1/overrides.min.css +++ b/themes/bootstrap/css/3.1.1/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-amelia.min.css b/themes/bootstrap/css/3.2.0/overrides-amelia.min.css index 504dd97f..14ef124a 100644 --- a/themes/bootstrap/css/3.2.0/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#AD1D28;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#AD1D28;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#DEBB27;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #bf851d}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#13a0aa;border:1px solid #0d747c;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#AD1D28;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#AD1D28}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#ddd;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #15b5c1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#15b5c1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #15b5c1 #15b5c1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #15b5c1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #15b5c1 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#15b5c1 transparent #15b5c1 #15b5c1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #15b5c1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#15b5c1 #15b5c1 #15b5c1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Cabin,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#15b5c1;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-cerulean.min.css b/themes/bootstrap/css/3.2.0/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.2.0/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-cosmo.min.css b/themes/bootstrap/css/3.2.0/overrides-cosmo.min.css index 737b733c..35155816 100644 --- a/themes/bootstrap/css/3.2.0/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#007FFF;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#007FFF;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#007FFF;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#007FFF}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#007FFF;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-cyborg.min.css b/themes/bootstrap/css/3.2.0/overrides-cyborg.min.css index 56f820c1..e6ac24c0 100644 --- a/themes/bootstrap/css/3.2.0/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-darkly.min.css b/themes/bootstrap/css/3.2.0/overrides-darkly.min.css index e58032bd..3bee0dcf 100644 --- a/themes/bootstrap/css/3.2.0/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-flatly.min.css b/themes/bootstrap/css/3.2.0/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.2.0/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-journal.min.css b/themes/bootstrap/css/3.2.0/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.2.0/overrides-journal.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-lumen.min.css b/themes/bootstrap/css/3.2.0/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.2.0/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-paper.min.css b/themes/bootstrap/css/3.2.0/overrides-paper.min.css index 69fd1d32..72d66419 100644 --- a/themes/bootstrap/css/3.2.0/overrides-paper.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-readable.min.css b/themes/bootstrap/css/3.2.0/overrides-readable.min.css index 91ff3ca8..14dcf59a 100644 --- a/themes/bootstrap/css/3.2.0/overrides-readable.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-sandstone.min.css b/themes/bootstrap/css/3.2.0/overrides-sandstone.min.css index 69fd1d32..72d66419 100644 --- a/themes/bootstrap/css/3.2.0/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-simplex.min.css b/themes/bootstrap/css/3.2.0/overrides-simplex.min.css index c94a1dc7..5614d1b4 100644 --- a/themes/bootstrap/css/3.2.0/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-slate.min.css b/themes/bootstrap/css/3.2.0/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.2.0/overrides-slate.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-spacelab.min.css b/themes/bootstrap/css/3.2.0/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.2.0/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-superhero.min.css b/themes/bootstrap/css/3.2.0/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.2.0/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-united.min.css b/themes/bootstrap/css/3.2.0/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.2.0/overrides-united.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides-yeti.min.css b/themes/bootstrap/css/3.2.0/overrides-yeti.min.css index c4c3f04f..86323908 100644 --- a/themes/bootstrap/css/3.2.0/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.2.0/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.2.0/overrides.min.css b/themes/bootstrap/css/3.2.0/overrides.min.css index 69fd1d32..72d66419 100644 --- a/themes/bootstrap/css/3.2.0/overrides.min.css +++ b/themes/bootstrap/css/3.2.0/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-amelia.min.css b/themes/bootstrap/css/3.3.0/overrides-amelia.min.css index 69fd1d32..72d66419 100644 --- a/themes/bootstrap/css/3.3.0/overrides-amelia.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-amelia.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.0/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.0/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.0/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.0/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.0/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.0/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-darkly.min.css b/themes/bootstrap/css/3.3.0/overrides-darkly.min.css index e58032bd..3bee0dcf 100644 --- a/themes/bootstrap/css/3.3.0/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-flatly.min.css b/themes/bootstrap/css/3.3.0/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.0/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-journal.min.css b/themes/bootstrap/css/3.3.0/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.0/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-lumen.min.css b/themes/bootstrap/css/3.3.0/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.0/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-paper.min.css b/themes/bootstrap/css/3.3.0/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.0/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-readable.min.css b/themes/bootstrap/css/3.3.0/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.0/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.0/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.0/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-simplex.min.css b/themes/bootstrap/css/3.3.0/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.0/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-slate.min.css b/themes/bootstrap/css/3.3.0/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.3.0/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.0/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.0/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-superhero.min.css b/themes/bootstrap/css/3.3.0/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.3.0/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-united.min.css b/themes/bootstrap/css/3.3.0/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.3.0/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides-yeti.min.css b/themes/bootstrap/css/3.3.0/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.0/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.0/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.0/overrides.min.css b/themes/bootstrap/css/3.3.0/overrides.min.css index 69fd1d32..72d66419 100644 --- a/themes/bootstrap/css/3.3.0/overrides.min.css +++ b/themes/bootstrap/css/3.3.0/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#428bca;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#428bca;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#428bca;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#428bca}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#428bca;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.1/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.1/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.1/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.1/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.1/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.1/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-darkly.min.css b/themes/bootstrap/css/3.3.1/overrides-darkly.min.css index e58032bd..3bee0dcf 100644 --- a/themes/bootstrap/css/3.3.1/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-flatly.min.css b/themes/bootstrap/css/3.3.1/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.1/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-journal.min.css b/themes/bootstrap/css/3.3.1/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.1/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-lumen.min.css b/themes/bootstrap/css/3.3.1/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.1/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-paper.min.css b/themes/bootstrap/css/3.3.1/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.1/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-readable.min.css b/themes/bootstrap/css/3.3.1/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.1/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.1/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.1/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-simplex.min.css b/themes/bootstrap/css/3.3.1/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.1/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-slate.min.css b/themes/bootstrap/css/3.3.1/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.3.1/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.1/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.1/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-superhero.min.css b/themes/bootstrap/css/3.3.1/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.3.1/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-united.min.css b/themes/bootstrap/css/3.3.1/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.3.1/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides-yeti.min.css b/themes/bootstrap/css/3.3.1/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.1/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.1/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.1/overrides.min.css b/themes/bootstrap/css/3.3.1/overrides.min.css index 1b72f936..7d3c329d 100644 --- a/themes/bootstrap/css/3.3.1/overrides.min.css +++ b/themes/bootstrap/css/3.3.1/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.2/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.2/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.2/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.2/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.2/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.2/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-darkly.min.css b/themes/bootstrap/css/3.3.2/overrides-darkly.min.css index e58032bd..3bee0dcf 100644 --- a/themes/bootstrap/css/3.3.2/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-flatly.min.css b/themes/bootstrap/css/3.3.2/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.2/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-journal.min.css b/themes/bootstrap/css/3.3.2/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.2/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-lumen.min.css b/themes/bootstrap/css/3.3.2/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.2/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-paper.min.css b/themes/bootstrap/css/3.3.2/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.2/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-readable.min.css b/themes/bootstrap/css/3.3.2/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.2/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.2/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.2/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-simplex.min.css b/themes/bootstrap/css/3.3.2/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.2/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-slate.min.css b/themes/bootstrap/css/3.3.2/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.3.2/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.2/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.2/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-superhero.min.css b/themes/bootstrap/css/3.3.2/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.3.2/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-united.min.css b/themes/bootstrap/css/3.3.2/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.3.2/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides-yeti.min.css b/themes/bootstrap/css/3.3.2/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.2/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.2/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.2/overrides.min.css b/themes/bootstrap/css/3.3.2/overrides.min.css index 1b72f936..7d3c329d 100644 --- a/themes/bootstrap/css/3.3.2/overrides.min.css +++ b/themes/bootstrap/css/3.3.2/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.4/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.4/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.4/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.4/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.4/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.4/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-darkly.min.css b/themes/bootstrap/css/3.3.4/overrides-darkly.min.css index e58032bd..3bee0dcf 100644 --- a/themes/bootstrap/css/3.3.4/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#375a7f;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#00bc8c;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-flatly.min.css b/themes/bootstrap/css/3.3.4/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.4/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-journal.min.css b/themes/bootstrap/css/3.3.4/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.4/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-lumen.min.css b/themes/bootstrap/css/3.3.4/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.4/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-paper.min.css b/themes/bootstrap/css/3.3.4/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.4/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-readable.min.css b/themes/bootstrap/css/3.3.4/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.4/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.4/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.4/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-simplex.min.css b/themes/bootstrap/css/3.3.4/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.4/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-slate.min.css b/themes/bootstrap/css/3.3.4/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.3.4/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.4/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.4/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-superhero.min.css b/themes/bootstrap/css/3.3.4/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.3.4/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-united.min.css b/themes/bootstrap/css/3.3.4/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.3.4/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides-yeti.min.css b/themes/bootstrap/css/3.3.4/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.4/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.4/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.4/overrides.min.css b/themes/bootstrap/css/3.3.4/overrides.min.css index 1b72f936..7d3c329d 100644 --- a/themes/bootstrap/css/3.3.4/overrides.min.css +++ b/themes/bootstrap/css/3.3.4/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.5/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.5/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.5/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.5/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.5/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.5/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-darkly.min.css b/themes/bootstrap/css/3.3.5/overrides-darkly.min.css index e21a3864..83a03830 100644 --- a/themes/bootstrap/css/3.3.5/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#303030;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#375a7f;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#303030;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#375a7f;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-flatly.min.css b/themes/bootstrap/css/3.3.5/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.5/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-journal.min.css b/themes/bootstrap/css/3.3.5/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.5/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-lumen.min.css b/themes/bootstrap/css/3.3.5/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.5/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-paper.min.css b/themes/bootstrap/css/3.3.5/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.5/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-readable.min.css b/themes/bootstrap/css/3.3.5/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.5/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.5/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.5/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-simplex.min.css b/themes/bootstrap/css/3.3.5/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.5/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-slate.min.css b/themes/bootstrap/css/3.3.5/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.3.5/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.5/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.5/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-superhero.min.css b/themes/bootstrap/css/3.3.5/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.3.5/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-united.min.css b/themes/bootstrap/css/3.3.5/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.3.5/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides-yeti.min.css b/themes/bootstrap/css/3.3.5/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.5/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.5/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.5/overrides.min.css b/themes/bootstrap/css/3.3.5/overrides.min.css index 1b72f936..7d3c329d 100644 --- a/themes/bootstrap/css/3.3.5/overrides.min.css +++ b/themes/bootstrap/css/3.3.5/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.6/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.6/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.6/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.6/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.6/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.6/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-darkly.min.css b/themes/bootstrap/css/3.3.6/overrides-darkly.min.css index e21a3864..83a03830 100644 --- a/themes/bootstrap/css/3.3.6/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#303030;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#375a7f;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#303030;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#375a7f;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-flatly.min.css b/themes/bootstrap/css/3.3.6/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.6/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-journal.min.css b/themes/bootstrap/css/3.3.6/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.6/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-lumen.min.css b/themes/bootstrap/css/3.3.6/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.6/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-paper.min.css b/themes/bootstrap/css/3.3.6/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.6/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-readable.min.css b/themes/bootstrap/css/3.3.6/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.6/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.6/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.6/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-simplex.min.css b/themes/bootstrap/css/3.3.6/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.6/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-slate.min.css b/themes/bootstrap/css/3.3.6/overrides-slate.min.css index 6f85bcb8..006f62ba 100644 --- a/themes/bootstrap/css/3.3.6/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.6/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.6/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-superhero.min.css b/themes/bootstrap/css/3.3.6/overrides-superhero.min.css index 7b9cb536..1b07badd 100644 --- a/themes/bootstrap/css/3.3.6/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-united.min.css b/themes/bootstrap/css/3.3.6/overrides-united.min.css index 396d1f66..51166a18 100644 --- a/themes/bootstrap/css/3.3.6/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DD4814;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DD4814;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DD4814;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DD4814}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#DD4814;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides-yeti.min.css b/themes/bootstrap/css/3.3.6/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.6/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.6/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.6/overrides.min.css b/themes/bootstrap/css/3.3.6/overrides.min.css index 1b72f936..7d3c329d 100644 --- a/themes/bootstrap/css/3.3.6/overrides.min.css +++ b/themes/bootstrap/css/3.3.6/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-cerulean.min.css b/themes/bootstrap/css/3.3.7/overrides-cerulean.min.css index 731b1752..e300a5ce 100644 --- a/themes/bootstrap/css/3.3.7/overrides-cerulean.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-cerulean.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2FA4E7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2FA4E7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2FA4E7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2FA4E7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2FA4E7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-cosmo.min.css b/themes/bootstrap/css/3.3.7/overrides-cosmo.min.css index 0b483257..0ad64c1b 100644 --- a/themes/bootstrap/css/3.3.7/overrides-cosmo.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-cosmo.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2780E3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2780E3;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#FF7518;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ee3800}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2780E3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2780E3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#e6e6e6 #ddd #e6e6e6 #e6e6e6}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2780E3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-cyborg.min.css b/themes/bootstrap/css/3.3.7/overrides-cyborg.min.css index c4de1553..20d9561c 100644 --- a/themes/bootstrap/css/3.3.7/overrides-cyborg.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-cyborg.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#888;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2A9FD6;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2A9FD6;border-bottom:1px solid #282828;border-top:1px solid #282828}.file>span:first-child{border-left:1px solid #282828}.file>span:last-child{border-right:1px solid #282828}.file>.tabledrag-changed{background:#F80;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d64f00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#222;border:1px solid #282828;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2A9FD6;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#888;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2A9FD6}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#888;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #282828}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#282828;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #282828 #282828}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #282828;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:transparent #282828 transparent transparent}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#282828 transparent #282828 #282828;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:transparent transparent transparent #282828;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#282828 #282828 #282828 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#222;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #444;border:1px solid rgba(255,255,255,.1);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#fff;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2A9FD6;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#888;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-darkly.min.css b/themes/bootstrap/css/3.3.7/overrides-darkly.min.css index e21a3864..83a03830 100644 --- a/themes/bootstrap/css/3.3.7/overrides-darkly.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-darkly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#303030;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#375a7f;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#375a7f;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#375a7f;border-bottom:1px solid #f1f1f1;border-top:1px solid #f1f1f1}.file>span:first-child{border-left:1px solid #f1f1f1}.file>span:last-child{border-right:1px solid #f1f1f1}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#303030;border:1px solid #464545;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#375a7f;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#375a7f}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#605e5e;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #464545}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#464545;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #464545 #464545}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #464545;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#464545}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#464545 transparent #464545 #464545;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#464545;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#464545 #464545 #464545 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#303030;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#375a7f;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-flatly.min.css b/themes/bootstrap/css/3.3.7/overrides-flatly.min.css index 2ac50d32..6f777a39 100644 --- a/themes/bootstrap/css/3.3.7/overrides-flatly.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-flatly.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b4bcc2;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2C3E50;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2C3E50;border-bottom:1px solid #dce4ec;border-top:1px solid #dce4ec}.file>span:first-child{border-left:1px solid #dce4ec}.file>span:last-child{border-right:1px solid #dce4ec}.file>.tabledrag-changed{background:#F39C12;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e08e0b}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ecf0f1;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2C3E50;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b4bcc2;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2C3E50}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b4bcc2;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ecf0f1}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ecf0f1;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ecf0f1 #ecf0f1}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ecf0f1;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ecf0f1}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ecf0f1 transparent #ecf0f1 #ecf0f1;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ecf0f1;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ecf0f1 #ecf0f1 #ecf0f1 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#7b8a8b;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#2C3E50;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b4bcc2;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-journal.min.css b/themes/bootstrap/css/3.3.7/overrides-journal.min.css index f7140d6e..92453b28 100644 --- a/themes/bootstrap/css/3.3.7/overrides-journal.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-journal.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#EB6864;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#EB6864;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#EB6864;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:13px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#EB6864}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:13px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#EB6864;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-lumen.min.css b/themes/bootstrap/css/3.3.7/overrides-lumen.min.css index e289ce8c..ef101ba0 100644 --- a/themes/bootstrap/css/3.3.7/overrides-lumen.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-lumen.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#158CBA;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#158CBA;border-bottom:1px solid #e7e7e7;border-top:1px solid #e7e7e7}.file>span:first-child{border-left:1px solid #e7e7e7}.file>span:last-child{border-right:1px solid #e7e7e7}.file>.tabledrag-changed{background:#FF851B;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #e76b00}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid transparent;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#158CBA;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#158CBA}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #e7e7e7}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#e7e7e7;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #e7e7e7 #e7e7e7}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #e7e7e7;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #e7e7e7 #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#e7e7e7 transparent #e7e7e7 #e7e7e7;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #e7e7e7;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#e7e7e7 #e7e7e7 #e7e7e7 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #e7e7e7;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#999;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:0 0;color:#333}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#158CBA;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-paper.min.css b/themes/bootstrap/css/3.3.7/overrides-paper.min.css index 4beba761..ec44ba20 100644 --- a/themes/bootstrap/css/3.3.7/overrides-paper.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-paper.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#3d8b40}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#771e86}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#cc7a00}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#b9151b}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#bbb;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#2196F3;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#2196F3;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#ffe0b2;border-radius:0;color:#ff9800;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #ffb67f}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 3px 3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#2196F3;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#e51c23}.has-success .select-wrapper:after{color:#4CAF50}.has-warning .select-wrapper:after{color:#ff9800}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:79px}body.navbar-is-fixed-bottom{padding-bottom:79px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#bbb;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#2196F3}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#bbb;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 3px 3px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 3px 3px;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:3px 0 0 3px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee transparent #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 3px 3px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#666;cursor:pointer;display:block;font-weight:400;line-height:1.846;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#141414}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#2196F3;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#bbb;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-readable.min.css b/themes/bootstrap/css/3.3.7/overrides-readable.min.css index 48402ca4..533ac40d 100644 --- a/themes/bootstrap/css/3.3.7/overrides-readable.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-readable.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#b3b3b3;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#4582EC;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#4582EC;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #eea236}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#4582EC;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#3FAD46}.has-warning .select-wrapper:after{color:#f0ad4e}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:80px}body.navbar-is-fixed-bottom{padding-bottom:80px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:14px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#b3b3b3;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#4582EC}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#b3b3b3;font-size:14px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Georgia,"Times New Roman",Times,serif;font-size:16px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#4582EC;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:20px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#b3b3b3;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-sandstone.min.css b/themes/bootstrap/css/3.3.7/overrides-sandstone.min.css index 1feb5725..ca442eb0 100644 --- a/themes/bootstrap/css/3.3.7/overrides-sandstone.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-sandstone.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#DFD7CA;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#325D88;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#325D88;border-bottom:1px solid #DFD7CA;border-top:1px solid #DFD7CA}.file>span:first-child{border-left:1px solid #DFD7CA}.file>span:last-child{border-right:1px solid #DFD7CA}.file>.tabledrag-changed{background:#F47C3C;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #DFD7CA;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#325D88;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#d9534f}.has-success .select-wrapper:after{color:#93C54B}.has-warning .select-wrapper:after{color:#F47C3C}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:75px}body.navbar-is-fixed-bottom{padding-bottom:75px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#DFD7CA;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#325D88}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#DFD7CA;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #DFD7CA}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#DFD7CA;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #DFD7CA #DFD7CA}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #DFD7CA;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#DFD7CA}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#DFD7CA transparent #DFD7CA #DFD7CA;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#DFD7CA;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#DFD7CA #DFD7CA #DFD7CA transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #DFD7CA;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Roboto,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#98978B;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#F8F5F0;color:#98978B}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#DFD7CA;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-simplex.min.css b/themes/bootstrap/css/3.3.7/overrides-simplex.min.css index 04afbbe3..58851e44 100644 --- a/themes/bootstrap/css/3.3.7/overrides-simplex.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-simplex.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:grey;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#D9230F;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#D9230F;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.file>span:first-child{border-left:1px solid #ddd}.file>span:last-child{border-right:1px solid #ddd}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#D9230F;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:grey;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#D9230F}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:grey;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#ddd}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#444;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#D9230F;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:17px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:grey;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-slate.min.css b/themes/bootstrap/css/3.3.7/overrides-slate.min.css index 10557507..ec0b1edb 100644 --- a/themes/bootstrap/css/3.3.7/overrides-slate.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-slate.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #000;border-top:1px solid #000}.file>span:first-child{border-left:1px solid #000}.file>span:last-child{border-right:1px solid #000}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#7A8288;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#7A8288;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#7A8288;border-bottom:1px solid #000;border-top:1px solid #000}.file>span:first-child{border-left:1px solid #000}.file>span:last-child{border-right:1px solid #000}.file>.tabledrag-changed{background:#f89406;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #d05a05}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#2e3338;border:1px solid rgba(0,0,0,.6);border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#7A8288;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#fff}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#7A8288;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#7A8288}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#7A8288;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #1c1e22}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#1c1e22;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #1c1e22 #1c1e22}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #1c1e22;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#1c1e22}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#1c1e22 transparent #1c1e22 #1c1e22;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#1c1e22;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#1c1e22 #1c1e22 #1c1e22 transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#3A3F44;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #272B30;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#C8C8C8;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#272B30;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#7A8288;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-spacelab.min.css b/themes/bootstrap/css/3.3.7/overrides-spacelab.min.css index 1587e423..0b33b863 100644 --- a/themes/bootstrap/css/3.3.7/overrides-spacelab.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-spacelab.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#446E9B;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#446E9B;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#446E9B;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#446E9B}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#446E9B;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-superhero.min.css b/themes/bootstrap/css/3.3.7/overrides-superhero.min.css index 2899eace..bb500023 100644 --- a/themes/bootstrap/css/3.3.7/overrides-superhero.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-superhero.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#d2d2d2}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#4E5D6C;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#DF691A;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#DF691A;border-bottom:1px solid transparent;border-top:1px solid transparent}.file>span:first-child{border-left:1px solid transparent}.file>span:last-child{border-right:1px solid transparent}.file>.tabledrag-changed{background:#f0ad4e;border-radius:0;color:#EBEBEB;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child,.filter-wrapper{border:1px solid transparent}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#4E5D6C;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#DF691A;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after,.has-success .select-wrapper:after,.has-warning .select-wrapper:after{color:#EBEBEB}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:55px}body.navbar-is-fixed-bottom{padding-bottom:55px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#4E5D6C;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#DF691A}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#4E5D6C;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid transparent}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:transparent;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid transparent;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#4E5D6C transparent #4E5D6C #4E5D6C}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:transparent;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#4E5D6C #4E5D6C #4E5D6C transparent;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#4E5D6C;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Lato,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#EBEBEB;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#485563;color:#EBEBEB}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#DF691A;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#4E5D6C;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-united.min.css b/themes/bootstrap/css/3.3.7/overrides-united.min.css index 9a748d32..bc4c0eb6 100644 --- a/themes/bootstrap/css/3.3.7/overrides-united.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-united.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#E95420;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#E95420;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#E95420;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#E95420}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#E95420;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#356635}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#2d6987}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#a47e3c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#953b39}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#AEA79F;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#E95420;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#E95420;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#c09853;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f8e5be}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#E95420;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#b94a48}.has-success .select-wrapper:after{color:#468847}.has-warning .select-wrapper:after{color:#c09853}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#AEA79F;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#E95420}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#AEA79F;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:Ubuntu,Tahoma,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus,.ui-autocomplete .ui-menu-item.ui-state-hover{background:#E95420;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#AEA79F;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides-yeti.min.css b/themes/bootstrap/css/3.3.7/overrides-yeti.min.css index 6da0f338..df22c6c4 100644 --- a/themes/bootstrap/css/3.3.7/overrides-yeti.min.css +++ b/themes/bootstrap/css/3.3.7/overrides-yeti.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover,.alert-info a,.alert-info a:focus,.alert-info a:hover,.alert-success a,.alert-success a:focus,.alert-success a:hover,.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#e6e6e6}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#999;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#008cba;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#008cba;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#E99002;border-radius:0;color:#fff;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #b67102}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#008cba;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#F04124}.has-success .select-wrapper:after{color:#43ac6a}.has-warning .select-wrapper:after{color:#E99002}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:60px}body.navbar-is-fixed-bottom{padding-bottom:60px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#999;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#008cba}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#999;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{border-radius:0}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#555;cursor:pointer;display:block;font-weight:400;line-height:1.4;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#eee;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#008cba;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:19px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#999;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/css/3.3.7/overrides.min.css b/themes/bootstrap/css/3.3.7/overrides.min.css index 1b72f936..7d3c329d 100644 --- a/themes/bootstrap/css/3.3.7/overrides.min.css +++ b/themes/bootstrap/css/3.3.7/overrides.min.css @@ -1 +1 @@ -.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file +.glyphicon-spin,a .glyphicon-spin{display:inline-block}.alert a,.field--label,.file{font-weight:700}.file,.file-link{width:100%}.tabs-left>.nav-tabs>li:focus,.tabs-left>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li:focus,.tabs-right>.nav-tabs>li>a:focus{outline:0}.panel-title:focus,.panel-title:hover,a .glyphicon-spin{text-decoration:none}.image-widget.row,.region-help .block,.tabledrag-changed-warning{overflow:hidden}.alert-sm{padding:5px 10px}.alert-success a,.alert-success a:focus,.alert-success a:hover{color:#2b542c}.alert-info a,.alert-info a:focus,.alert-info a:hover{color:#245269}.alert-warning a,.alert-warning a:focus,.alert-warning a:hover{color:#66512c}.alert-danger a,.alert-danger a:focus,.alert-danger a:hover{color:#843534}@-webkit-keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes glyphicon-spin{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes glyphicon-spin{0%{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}.glyphicon-spin{-webkit-animation:glyphicon-spin 1s infinite linear;-o-animation:glyphicon-spin 1s infinite linear;animation:glyphicon-spin 1s infinite linear}html.js .btn .ajax-throbber{margin-left:.5em;margin-right:-.25em}html.js .form-item .input-group-addon .glyphicon{color:#777;opacity:.5;-webkit-transition:150ms color,150ms opacity;-o-transition:150ms color,150ms opacity;transition:150ms color,150ms opacity}html.js .form-item .input-group-addon .glyphicon.glyphicon-spin{color:#337ab7;opacity:1}html.js .form-item .input-group-addon .input-group-addon{background-color:#fff}html.js .ajax-new-content:empty{display:none!important}.field--label-inline .field--items,.field--label-inline .field--label{float:left}.field--label-inline .field--items,.field--label-inline .field--label,.field--label-inline>.field--item{padding-right:.5em}[dir=rtl] .field--label-inline .field--items,[dir=rtl] .field--label-inline .field--label{padding-left:.5em;padding-right:0}.field--label-inline .field--label::after{content:':'}.file{display:table;font-size:75%;margin:5px 0}.file-icon,.file-link,.file-size,.file>.tabledrag-changed{display:table-cell;vertical-align:middle}.file>span{background:#fff;color:#337ab7;border-bottom:1px solid #ccc;border-top:1px solid #ccc}.file>span:first-child{border-left:1px solid #ccc}.file>span:last-child{border-right:1px solid #ccc}.file>.tabledrag-changed{background:#fcf8e3;border-radius:0;color:#8a6d3b;padding:0 1em;top:0}.file>.tabledrag-changed,.file>.tabledrag-changed:last-child{border:1px solid #f7e1b5}.file-icon{font-size:150%;padding:.25em .5em;text-align:center}.file-link a,.file-link a:active,.file-link a:focus,.file-link a:hover{color:inherit}.file-size{padding:0 1em;text-align:right;white-space:pre}.filter-wrapper{background-color:#fff;border:1px solid #ddd;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);margin-bottom:0;padding:10px;height:51px}.filter-help{float:right;line-height:1;margin:.5em 0 0}.nav.nav-tabs.filter-formats{margin-bottom:15px}table .checkbox.form-no-label,table .radio.form-no-label{margin-bottom:0;margin-top:0}.select-wrapper{display:inline-block;position:relative;width:100%}.form-inline .select-wrapper{width:auto}.input-group .select-wrapper{display:table-cell}.input-group .select-wrapper:first-child .form-control:first-child{border-bottom-left-radius:4px;border-top-left-radius:4px}.input-group .select-wrapper:last-child .form-control:first-child{border-bottom-right-radius:4px;border-top-right-radius:4px}.select-wrapper select{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1;padding-right:2em}.select-wrapper select::-ms-expand{opacity:0}.select-wrapper:after{color:#337ab7;content:'â–¼';font-style:normal;font-weight:400;line-height:1;margin-top:-.5em;padding-right:.5em;pointer-events:none;position:absolute;right:0;top:50%;z-index:10}.has-glyphicons .select-wrapper:after{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e114';display:inline-block;font-family:'Glyphicons Halflings'}.has-error .select-wrapper:after{color:#a94442}.has-success .select-wrapper:after{color:#3c763d}.has-warning .select-wrapper:after{color:#8a6d3b}.form-required:after{background-image:url(../images/required.svg);-webkit-background-size:10px 7px;background-size:10px 7px;content:"";display:inline-block;line-height:1;height:7px;width:10px}.form-actions .btn,.form-actions .btn-group{margin-right:10px}.form-actions .btn-group .btn{margin-right:0}a.icon-before .glyphicon{margin-right:.25em}a.icon-after .glyphicon{margin-left:.25em}.btn.icon-before .glyphicon{margin-left:-.25em;margin-right:.25em}.btn.icon-after .glyphicon{margin-left:.25em;margin-right:-.25em}body{position:relative}body.navbar-is-static-top{margin-top:0}body.navbar-is-fixed-top{margin-top:65px}body.navbar-is-fixed-bottom{padding-bottom:65px}@media screen and (max-width:767px){body.toolbar-vertical.navbar-is-fixed-bottom .toolbar-bar,body.toolbar-vertical.navbar-is-fixed-top .toolbar-bar{position:fixed}body.toolbar-vertical.navbar-is-fixed-bottom header,body.toolbar-vertical.navbar-is-fixed-top header{z-index:500}body.toolbar-vertical.navbar-is-fixed-top header{top:39px}}@media screen and (min-width:768px){body{margin-top:15px}.navbar.container{max-width:720px}}@media screen and (min-width:992px){.navbar.container{max-width:940px}}@media screen and (min-width:1200px){.navbar.container{max-width:1140px}}.navbar .logo{margin-right:-15px;padding-left:15px;padding-right:15px}@media screen and (min-width:768px){.navbar .logo{margin-right:0;padding-left:0}}.node-preview-container{margin-top:-15px}.node-preview-form-select{padding:15px}.panel-title{display:block;margin:-10px -15px;padding:10px 15px}.panel-title,.panel-title:focus,.panel-title:hover,.panel-title:hover:focus{color:inherit}.progress-wrapper{margin-bottom:15px}.progress-wrapper:last-child .progress{margin-bottom:5px}.progress-wrapper .message{font-weight:700;margin-bottom:5px}.progress-wrapper .percentage,.progress-wrapper .progress-label{font-size:12px}.progress-wrapper .progress-bar{min-width:2em}.tabledrag-toggle-weight{float:right;margin:1px 2px 1px 10px}.tabledrag-changed-warning{margin:0}.tabledrag-handle{color:#777;cursor:move;float:left;font-size:125%;line-height:1;margin:-10px 0 0 -10px;padding:10px}.tabledrag-handle:focus,.tabledrag-handle:hover{color:#337ab7}.indentation{float:left;height:1.7em;margin:-.4em .2em -.4em -.4em;padding:.42em 0 .42em .6em;width:20px}[dir=rtl] .indentation{float:right;margin:-.4em -.4em -.4em .2em;padding:.42em .6em .42em 0}.local-actions{margin:10px 0 10px -5px}.tabs--secondary{margin:10px 0 5px}.tabbable{margin-bottom:20px}.tabs-below>.nav-tabs,.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{border-bottom:0}.tabs-below>.nav-tabs .summary,.tabs-left>.nav-tabs .summary,.tabs-right>.nav-tabs .summary{color:#777;font-size:12px}.tab-pane>.panel-heading{display:none}.tab-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:focus,.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:focus,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd}.tabs-left>.nav-tabs,.tabs-right>.nav-tabs{padding-bottom:20px;width:220px}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{margin-right:0;margin-bottom:3px}.form-group:last-child,.panel:last-child,.popover ol:last-child,.popover ul:last-child,p:last-child{margin-bottom:0}.tabs-left>.tab-content,.tabs-right>.tab-content{border-radius:0 4px 4px;border:1px solid #ddd;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);overflow:hidden;padding:10px 15px}.tabs-left>.nav-tabs{float:left;margin-right:-1px}.tabs-left>.nav-tabs>li>a{border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:focus,.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs>.active>a,.tabs-left>.nav-tabs>.active>a:focus,.tabs-left>.nav-tabs>.active>a:hover{border-color:#ddd transparent #ddd #ddd;-webkit-box-shadow:-1px 1px 1px rgba(0,0,0,.05);box-shadow:-1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs{float:right;margin-left:-1px}.tabs-right>.nav-tabs>li>a{border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:focus,.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd;-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.05);box-shadow:1px 1px 1px rgba(0,0,0,.05)}.tabs-right>.nav-tabs>.active>a,.tabs-right>.nav-tabs>.active>a:focus,.tabs-right>.nav-tabs>.active>a:hover{border-color:#ddd #ddd #ddd transparent}body.toolbar-fixed .toolbar-oriented .toolbar-bar{z-index:1031}body.toolbar-fixed .navbar-fixed-top{top:39px}body.toolbar-fixed.toolbar-horizontal.toolbar-tray-open .navbar-fixed-top{top:79px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open .navbar-fixed-top{left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed{margin-left:240px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray{padding-bottom:40px}body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray,body.toolbar-fixed.toolbar-vertical.toolbar-tray-open.toolbar-fixed .toolbar-tray>.toolbar-lining:before{width:240px}.ui-autocomplete{background:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);color:inherit;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;list-style:none;min-width:160px;padding:5px 0;text-align:left;z-index:1000}.ui-autocomplete .ui-menu-item{border:0;border-radius:0;clear:both;color:#333;cursor:pointer;display:block;font-weight:400;line-height:1.42857143;margin:0;outline:0;padding:3px 20px;text-decoration:none;white-space:nowrap}.ui-autocomplete .ui-menu-item.ui-state-hover{background:#f5f5f5;color:#262626}.ui-autocomplete .ui-menu-item.ui-state-active,.ui-autocomplete .ui-menu-item.ui-state-focus{background:#337ab7;color:#fff}ol,ul{padding-left:1.5em}.page-header{margin-top:0}.footer{margin-top:45px;padding-top:35px;padding-bottom:36px;border-top:1px solid #E5E5E5}.region-help>.glyphicon{font-size:18px;float:left;margin:-.05em .5em 0 0}.control-group .help-inline,.help-block{color:#777;font-size:12px;margin:5px 0 10px;padding:0}.control-group .help-inline:first-child,.help-block:first-child{margin-top:0} \ No newline at end of file diff --git a/themes/bootstrap/docs/plugins/Setting.md b/themes/bootstrap/docs/plugins/Setting.md index 04de642b..d0200c6f 100644 --- a/themes/bootstrap/docs/plugins/Setting.md +++ b/themes/bootstrap/docs/plugins/Setting.md @@ -21,7 +21,8 @@ Create a file at `./THEMENAME/src/Plugin/Setting/THEMENAME/Accessibility/SkipLin with the following contents: ```php -namespace Drupal\THEMENAME\Plugin\Setting\THEMENAME\Accessibility\SkipLink; + .panel-heading > .panel-title'; + } + +})(window.jQuery, window.Drupal); diff --git a/themes/bootstrap/js/popover.js b/themes/bootstrap/js/popover.js index 7f606f8a..198cd3eb 100644 --- a/themes/bootstrap/js/popover.js +++ b/themes/bootstrap/js/popover.js @@ -15,6 +15,7 @@ var Drupal = Drupal || {}; return { DEFAULTS: { animation: !!settings.popover_animation, + enabled: settings.popover_enabled, html: !!settings.popover_html, placement: settings.popover_placement, selector: settings.popover_selector, @@ -35,6 +36,10 @@ var Drupal = Drupal || {}; */ Drupal.behaviors.bootstrapPopovers = { attach: function (context) { + // Immediately return if popovers are not available. + if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { + return; + } // Popover autoclose. if ($.fn.popover.Constructor.DEFAULTS.triggerAutoclose) { @@ -102,6 +107,11 @@ var Drupal = Drupal || {}; } }, detach: function (context) { + // Immediately return if popovers are not available. + if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { + return; + } + // Destroy all popovers. $(context).find('[data-toggle="popover"]') .off('click.drupal.bootstrap.popover') diff --git a/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php b/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php index 86ae7701..7ff3ac7c 100644 --- a/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php +++ b/themes/bootstrap/src/Plugin/Alter/ThemeRegistry.php @@ -87,12 +87,23 @@ public function alter(&$cache, &$context1 = NULL, &$context2 = NULL) { $hook = str_replace('-', '_', str_replace('.html.twig', '', $file->filename)); $path = dirname($file->uri); $incomplete = !isset($cache[$hook]) || strrpos($hook, '__'); + + // Create a new theme hook. This primarily happens when theme hook + // suggestion templates are created. To prevent the new hook from + // inheriting parent hook's "template", it must be manually set here. + // @see https://www.drupal.org/node/2871551 if (!isset($cache[$hook])) { - $cache[$hook] = []; + $cache[$hook] = [ + 'template' => str_replace('.html.twig', '', $file->filename), + ]; } + + // Always ensure that "path", "type" and "theme path" are properly set. $cache[$hook]['path'] = $path; $cache[$hook]['type'] = $current_theme ? 'theme' : 'base_theme'; $cache[$hook]['theme path'] = $theme_path; + + // Flag incomplete. if ($incomplete) { $cache[$hook]['incomplete preprocess functions'] = TRUE; } diff --git a/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php b/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php index ce29ba64..b4a4c63d 100644 --- a/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php +++ b/themes/bootstrap/src/Plugin/Alter/ThemeSuggestions.php @@ -143,15 +143,18 @@ protected function alterUser() { ***************************************************************************/ /** - * Add a suggestion to the list of suggestions. + * Adds suggestions based on an array of hooks. * - * @param string $hook - * The theme hook suggestion to add. + * @param string|string[] $hook + * A single theme hook suggestion or an array of theme hook suggestions. */ protected function addSuggestion($hook) { - $suggestions = $this->buildSuggestions($hook); - foreach ($suggestions as $suggestion) { - $this->suggestions[] = $suggestion; + $hooks = (array) $hook; + foreach ($hooks as $hook) { + $suggestions = $this->buildSuggestions($hook); + foreach ($suggestions as $suggestion) { + $this->suggestions[] = $suggestion; + } } } @@ -180,6 +183,8 @@ protected function addSuggestionsForEntity($entity_type = 'entity', $prefix = '' // Extract the entity. if ($entity = $this->getEntityObject($entity_type)) { $entity_type_id = $entity->getEntityTypeId(); + $suggestions = []; + // Only add the entity type identifier if there's a prefix. if (!empty($prefix)) { $prefix .= '__'; @@ -196,6 +201,11 @@ protected function addSuggestionsForEntity($entity_type = 'entity', $prefix = '' $suggestions[] = $prefix . $entity_type_id . '__' . $entity->bundle() . '__' . $view_mode; } } + + // Add suggestions. + if ($suggestions) { + $this->addSuggestion($suggestions); + } } } diff --git a/themes/bootstrap/src/Plugin/Preprocess/BootstrapCarousel.php b/themes/bootstrap/src/Plugin/Preprocess/BootstrapCarousel.php index 49459710..2674f9cf 100644 --- a/themes/bootstrap/src/Plugin/Preprocess/BootstrapCarousel.php +++ b/themes/bootstrap/src/Plugin/Preprocess/BootstrapCarousel.php @@ -75,8 +75,10 @@ protected function preprocessVariables(Variables $variables) { '#theme' => 'item_list__bootstrap_carousel_indicators', '#list_type' => 'ol', '#items' => array_keys($variables->slides), - '#target' => "#$id", - '#start_index' => $variables->start_index, + '#context' => [ + 'target' => "#$id", + 'start_index' => $variables->start_index, + ], ]; } diff --git a/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php b/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php index 28e16629..73c601d6 100644 --- a/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php +++ b/themes/bootstrap/src/Plugin/Preprocess/BootstrapDropdown.php @@ -35,8 +35,10 @@ protected function preprocessVariables(Variables $variables) { // Convert the items into a proper item list. $variables->items = [ '#theme' => 'item_list__dropdown', - '#alignment' => $variables->alignment, '#items' => $variables->items, + '#context' => [ + 'alignment' => $variables->alignment, + ], ]; // Ensure all attributes are proper objects. diff --git a/themes/bootstrap/src/Plugin/Preprocess/Input.php b/themes/bootstrap/src/Plugin/Preprocess/Input.php index 5d56e40b..e30c1c24 100644 --- a/themes/bootstrap/src/Plugin/Preprocess/Input.php +++ b/themes/bootstrap/src/Plugin/Preprocess/Input.php @@ -23,8 +23,6 @@ class Input extends PreprocessBase implements PreprocessInterface { * {@inheritdoc} */ public function preprocessElement(Element $element, Variables $variables) { - $element->map(['id', 'name', 'value', 'type']); - // Autocomplete. if ($route = $element->getProperty('autocomplete_route_name')) { $variables['autocomplete'] = TRUE; diff --git a/themes/bootstrap/src/Plugin/Preprocess/ItemListBootstrapCarouselIndicators.php b/themes/bootstrap/src/Plugin/Preprocess/ItemListBootstrapCarouselIndicators.php new file mode 100644 index 00000000..227c993f --- /dev/null +++ b/themes/bootstrap/src/Plugin/Preprocess/ItemListBootstrapCarouselIndicators.php @@ -0,0 +1,26 @@ +target = $variables->getContext('target'); + $variables->start_index = $variables->getContext('start_index'); + } + +} diff --git a/themes/bootstrap/src/Plugin/Preprocess/ItemListDropdown.php b/themes/bootstrap/src/Plugin/Preprocess/ItemListDropdown.php new file mode 100644 index 00000000..2b1979f6 --- /dev/null +++ b/themes/bootstrap/src/Plugin/Preprocess/ItemListDropdown.php @@ -0,0 +1,25 @@ +alignment = $variables->getContext('alignment'); + } + +} diff --git a/themes/bootstrap/src/Plugin/Prerender/Captcha.php b/themes/bootstrap/src/Plugin/Prerender/Captcha.php new file mode 100644 index 00000000..35634363 --- /dev/null +++ b/themes/bootstrap/src/Plugin/Prerender/Captcha.php @@ -0,0 +1,29 @@ +setProperty('smart_description', FALSE, TRUE); + } + +} diff --git a/themes/bootstrap/src/Utility/Element.php b/themes/bootstrap/src/Utility/Element.php index 84df3f77..49309a02 100644 --- a/themes/bootstrap/src/Utility/Element.php +++ b/themes/bootstrap/src/Utility/Element.php @@ -671,11 +671,18 @@ public function setIcon(array $icon = NULL) { * The name of the property to set. * @param mixed $value * The value of the property to set. + * @param bool $recurse + * Flag indicating wither to set the same property on child elements. * * @return $this */ - public function setProperty($name, $value) { + public function setProperty($name, $value, $recurse = FALSE) { $this->array["#$name"] = $value instanceof Element ? $value->getArray() : $value; + if ($recurse) { + foreach ($this->children() as $child) { + $child->setProperty($name, $value, $recurse); + } + } return $this; } @@ -745,9 +752,23 @@ public function smartDescription(&$target_element = NULL, $input_only = TRUE, $l // Return if element or target shouldn't have "simple" tooltip descriptions. $html = FALSE; - if (($input_only && !$target->hasProperty('input')) - // Ignore if the actual element has no #description set. - || !$this->hasProperty('description') + + // If the description is a render array, it must first be pre-rendered so + // it can be later passed to Unicode::isSimple() if needed. + $description = $this->hasProperty('description') ? $this->getProperty('description') : FALSE; + if (static::isRenderArray($description)) { + $description = static::createStandalone($description)->renderPlain(); + } + + if ( + // Ignore if element has no #description. + !$description + + // Ignore if description is not a simple string or MarkupInterface. + || (!is_string($description) && !($description instanceof MarkupInterface)) + + // Ignore if element is not an input. + || ($input_only && !$target->hasProperty('input')) // Ignore if the target element already has a "data-toggle" attribute set. || $target->hasAttribute('data-toggle') @@ -761,7 +782,7 @@ public function smartDescription(&$target_element = NULL, $input_only = TRUE, $l || !$target->getProperty('smart_description', TRUE) // Ignore if the description is not "simple". - || !Unicode::isSimple($this->getProperty('description'), $length, $allowed_tags, $html) + || !Unicode::isSimple($description, $length, $allowed_tags, $html) ) { // Set the both the actual element and the target element // #smart_description property to FALSE. @@ -786,7 +807,7 @@ public function smartDescription(&$target_element = NULL, $input_only = TRUE, $l $attributes = $target->getAttributes($type); // Set the tooltip attributes. - $attributes['title'] = $allowed_tags !== FALSE ? Xss::filter((string) $this->getProperty('description'), $allowed_tags) : $this->getProperty('description'); + $attributes['title'] = $allowed_tags !== FALSE ? Xss::filter((string) $description, $allowed_tags) : $description; $attributes['data-toggle'] = 'tooltip'; if ($html || $allowed_tags === FALSE) { $attributes['data-html'] = 'true'; diff --git a/themes/bootstrap/starterkits/less/images/required.svg b/themes/bootstrap/starterkits/less/images/required.svg index f7882d6d..e69de29b 100644 --- a/themes/bootstrap/starterkits/less/images/required.svg +++ b/themes/bootstrap/starterkits/less/images/required.svg @@ -1 +0,0 @@ - diff --git a/themes/bootstrap/starterkits/less/less/component/navbar.less b/themes/bootstrap/starterkits/less/less/component/navbar.less index 6b0cd43e..252700f4 100644 --- a/themes/bootstrap/starterkits/less/less/component/navbar.less +++ b/themes/bootstrap/starterkits/less/less/component/navbar.less @@ -1,10 +1,11 @@ /** * Navbar styling. */ -@mobile: ~"screen and (max-width: @{screen-xs-max})"; -@tablet: ~"screen and (min-width: @{screen-sm-min})"; -@normal: ~"screen and (min-width: @{screen-md-min})"; -@wide: ~"screen and (min-width: @{screen-lg-min})"; +@mobile: ~"screen and (max-width: @{screen-xs-max})"; +@tablet: ~"screen and (min-width: @{screen-sm-min})"; +@normal: ~"screen and (min-width: @{screen-md-min})"; +@wide: ~"screen and (min-width: @{screen-lg-min})"; +@grid-breakpoint: ~"screen and (min-width: @{grid-float-breakpoint})"; body { // Fix horizontal scrolling on iOS devices. @@ -54,3 +55,14 @@ body { max-width: ((@container-lg - @grid-gutter-width)); } } + +// Branding. +.navbar .logo { + margin-right: -(@grid-gutter-width / 2); + padding-left: (@grid-gutter-width / 2); + padding-right: (@grid-gutter-width / 2); + @media @grid-breakpoint { + margin-right: 0; + padding-left: 0; + } +} diff --git a/themes/bootstrap/starterkits/sass/README.md b/themes/bootstrap/starterkits/sass/README.md old mode 100755 new mode 100644 index c483e9ab..eefe74ce --- a/themes/bootstrap/starterkits/sass/README.md +++ b/themes/bootstrap/starterkits/sass/README.md @@ -33,11 +33,11 @@ or when you upgrade your version of the [Bootstrap Framework]. [Bootstrap Framework] in the future. ## Overrides {#overrides} -The `./THEMENAME/sass/_default-variables.scss` file is generally where you will +The `./THEMENAME/scss/_default-variables.scss` file is generally where you will spend the majority of your time providing any default variables that should be used by the [Bootstrap Framework] instead of its own. -The `./THEMENAME/sass/overrides.scss` file contains various Drupal overrides to +The `./THEMENAME/scss/overrides.scss` file contains various Drupal overrides to properly integrate with the [Bootstrap Framework]. It may contain a few enhancements, feel free to edit this file as you see fit. diff --git a/themes/bootstrap/starterkits/sass/THEMENAME.libraries.yml b/themes/bootstrap/starterkits/sass/THEMENAME.libraries.yml old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/THEMENAME.starterkit.yml b/themes/bootstrap/starterkits/sass/THEMENAME.starterkit.yml old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/THEMENAME.theme b/themes/bootstrap/starterkits/sass/THEMENAME.theme old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/config/install/THEMENAME.settings.yml b/themes/bootstrap/starterkits/sass/config/install/THEMENAME.settings.yml old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/config/schema/THEMENAME.schema.yml b/themes/bootstrap/starterkits/sass/config/schema/THEMENAME.schema.yml old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/favicon.ico b/themes/bootstrap/starterkits/sass/favicon.ico old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/logo.svg b/themes/bootstrap/starterkits/sass/logo.svg old mode 100755 new mode 100644 diff --git a/themes/bootstrap/starterkits/sass/scss/component/_navbar.scss b/themes/bootstrap/starterkits/sass/scss/component/_navbar.scss index f34f4162..31301426 100644 --- a/themes/bootstrap/starterkits/sass/scss/component/_navbar.scss +++ b/themes/bootstrap/starterkits/sass/scss/component/_navbar.scss @@ -1,10 +1,11 @@ /** * Navbar styling. */ -$mobile: "screen and (max-width: #{$screen-xs-max})"; -$tablet: "screen and (min-width: #{$screen-sm-min})"; -$normal: "screen and (min-width: #{$screen-md-min})"; -$wide: "screen and (min-width: #{$screen-lg-min})"; +$mobile: "screen and (max-width: #{$screen-xs-max})"; +$tablet: "screen and (min-width: #{$screen-sm-min})"; +$normal: "screen and (min-width: #{$screen-md-min})"; +$wide: "screen and (min-width: #{$screen-lg-min})"; +$grid-breakpoint: "screen and (min-width: #{$grid-float-breakpoint})"; body { // Fix horizontal scrolling on iOS devices. @@ -54,3 +55,15 @@ body { max-width: (($container-lg - $grid-gutter-width)); } } + +// Branding. +.navbar .logo { + margin-right: -($grid-gutter-width / 2); + padding-left: ($grid-gutter-width / 2); + padding-right: ($grid-gutter-width / 2); + @media #{$grid-breakpoint} { + margin-right: 0; + padding-left: 0; + } +} + diff --git a/themes/bootstrap/starterkits/sass/templates/README.md b/themes/bootstrap/starterkits/sass/templates/README.md old mode 100755 new mode 100644 diff --git a/themes/bootstrap/templates/field/field--node--field-image--article.html.twig b/themes/bootstrap/templates/field/field--node--field-image--article.html.twig deleted file mode 100644 index 693fffff..00000000 --- a/themes/bootstrap/templates/field/field--node--field-image--article.html.twig +++ /dev/null @@ -1,82 +0,0 @@ -{# -/** - * @file - * Theme override for a field. - * - * To override output, copy the "field.html.twig" from the templates directory - * to your theme's directory and customize it, just like customizing other - * Drupal templates such as page.html.twig or node.html.twig. - * - * Instead of overriding the theming for all fields, you can also just override - * theming for a subset of fields using - * @link themeable Theme hook suggestions. @endlink For example, - * here are some theme hook suggestions that can be used for a field_foo field - * on an article node type: - * - field--node--field-foo--article.html.twig - * - field--node--field-foo.html.twig - * - field--node--article.html.twig - * - field--field-foo.html.twig - * - field--text-with-summary.html.twig - * - field.html.twig - * - * Available variables: - * - attributes: HTML attributes for the containing element. - * - label_hidden: Whether to show the field label or not. - * - title_attributes: HTML attributes for the title. - * - label: The label for the field. - * - multiple: TRUE if a field can contain multiple items. - * - items: List of all the field items. Each item contains: - * - attributes: List of HTML attributes for each item. - * - content: The field item's content. - * - entity_type: The entity type to which the field belongs. - * - field_name: The name of the field. - * - field_type: The type of the field. - * - label_display: The display settings for the label. - * - * @ingroup templates - * - * @see template_preprocess_field() - */ -#} -{% - set classes = [ - 'field', - 'field--name-' ~ field_name|clean_class, - 'field--type-' ~ field_type|clean_class, - 'field--label-' ~ label_display, - 'col-sm-4', - ] -%} -{% - set title_classes = [ - 'field--label', - label_display == 'visually_hidden' ? 'sr-only', - ] -%} - -{% if label_hidden %} - {% if multiple %} - - {% for item in items %} - {{ item.content }} - {% endfor %} - - {% else %} - {% for item in items %} - {{ item.content }} - {% endfor %} - {% endif %} -{% else %} - - {{ label }} - {% if multiple %} -
    - {% endif %} - {% for item in items %} - {{ item.content }}
    - {% endfor %} - {% if multiple %} - - {% endif %} - -{% endif %} diff --git a/themes/bootstrap/templates/input/input--button.html.twig b/themes/bootstrap/templates/input/input--button.html.twig index 4272b24a..7166b1a5 100644 --- a/themes/bootstrap/templates/input/input--button.html.twig +++ b/themes/bootstrap/templates/input/input--button.html.twig @@ -31,7 +31,7 @@ ] %} {% block input %} - {% if icon_only %} + {% if icon and icon_only %} {{ label }} {{ icon }} diff --git a/themes/bootstrap/templates/system/page.html.twig b/themes/bootstrap/templates/system/page.html.twig index f3e9ed2a..70f8c1d9 100644 --- a/themes/bootstrap/templates/system/page.html.twig +++ b/themes/bootstrap/templates/system/page.html.twig @@ -20,9 +20,6 @@ * - front_page: The URL of the front page. Use this instead of base_path when * linking to the front page. This includes the language domain or prefix. * - * Navigation: - * - breadcrumb: The breadcrumb trail for the current page. - * * Page content (in order of occurrence in the default page.html.twig): * - title_prefix: Additional output populated by modules, intended to be * displayed in front of the main title tag that appears in the template. @@ -32,8 +29,6 @@ * - messages: Status and error messages. Should be displayed prominently. * - tabs: Tabs linking to any sub-pages beneath the current page (e.g., the * view and edit tabs when displaying a node). - * - action_links: Actions local to the page, such as "Add menu" on the menu - * administration interface. * - node: Fully loaded node, if there is an automatically-loaded node * associated with the page and the node ID is the second argument in the * page's path (e.g. node/12345 and node/12345/revisions, but not @@ -68,7 +63,7 @@ ] %} - {% if not navbar_attributes.hasClass('container') %} + {% if not navbar_attributes.hasClass(container) %}
    {% endif %} {% endif %} - {% if not navbar_attributes.hasClass('container') %} + {% if not navbar_attributes.hasClass(container) %}
    {% endif %} @@ -138,20 +133,6 @@ {% endblock %} {% endif %} - {# Breadcrumbs #} - {% if breadcrumb %} - {% block breadcrumb %} - {{ breadcrumb }} - {% endblock %} - {% endif %} - - {# Action Links #} - {% if action_links %} - {% block action_links %} - - {% endblock %} - {% endif %} - {# Help #} {% if page.help %} {% block help %} diff --git a/vendor/asm89/stack-cors/.gitignore b/vendor/asm89/stack-cors/.gitignore deleted file mode 100644 index 8844fdc4..00000000 --- a/vendor/asm89/stack-cors/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -phpunit.xml -composer.lock -composer.phar -/vendor/ diff --git a/vendor/asm89/stack-cors/.travis.yml b/vendor/asm89/stack-cors/.travis.yml deleted file mode 100644 index 7eb55a91..00000000 --- a/vendor/asm89/stack-cors/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: php - -php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - hhvm - -before_script: composer install --dev - -script: phpunit diff --git a/vendor/asm89/stack-cors/LICENSE b/vendor/asm89/stack-cors/LICENSE new file mode 100644 index 00000000..d9f2067d --- /dev/null +++ b/vendor/asm89/stack-cors/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2017 Alexander + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/asm89/stack-cors/README.md b/vendor/asm89/stack-cors/README.md index dea18a8e..904ac936 100644 --- a/vendor/asm89/stack-cors/README.md +++ b/vendor/asm89/stack-cors/README.md @@ -2,12 +2,11 @@ Library and middleware enabling cross-origin resource sharing for your http-{foundation,kernel} using application. It attempts to implement the -[W3C Candidate Recommendation] for cross-origin resource sharing. +[W3C Recommendation] for cross-origin resource sharing. -[W3C Candidate Recommendation]: http://www.w3.org/TR/cors/ +[W3C Recommendation]: http://www.w3.org/TR/cors/ Master [![Build Status](https://secure.travis-ci.org/asm89/stack-cors.png?branch=master)](http://travis-ci.org/asm89/stack-cors) -Develop [![Build Status](https://secure.travis-ci.org/asm89/stack-cors.png?branch=develop)](http://travis-ci.org/asm89/stack-cors) ## Installation @@ -15,45 +14,49 @@ Require `asm89/stack-cors` using composer. ## Usage -Stack middleware: +This package can be used as a library or as [stack middleware]. + +[stack middleware]: http://stackphp.com/ + +### Example: using the library ```php array('x-allowed-header', 'x-other-allowed-header'), - // you can use array('*') to allow any methods 'allowedMethods' => array('DELETE', 'GET', 'POST', 'PUT'), - // you can use array('*') to allow requests from any origin 'allowedOrigins' => array('localhost'), 'exposedHeaders' => false, 'maxAge' => false, 'supportsCredentials' => false, )); + +$cors->addActualRequestHeaders(Response $response, $origin); +$cors->handlePreflightRequest(Request $request); +$cors->isActualRequestAllowed(Request $request); +$cors->isCorsRequest(Request $request); +$cors->isPreflightRequest(Request $request); ``` -Or use the library: +## Example: using the stack middleware ```php array('x-allowed-header', 'x-other-allowed-header'), + // you can use array('*') to allow any methods 'allowedMethods' => array('DELETE', 'GET', 'POST', 'PUT'), + // you can use array('*') to allow requests from any origin 'allowedOrigins' => array('localhost'), 'exposedHeaders' => false, 'maxAge' => false, 'supportsCredentials' => false, )); - -$cors->addActualRequestHeaders(Response $response, $origin); -$cors->handlePreflightRequest(Request $request); -$cors->isActualRequestAllowed(Request $request); -$cors->isCorsRequest(Request $request); -$cors->isPreflightRequest(Request $request); ``` diff --git a/vendor/asm89/stack-cors/composer.json b/vendor/asm89/stack-cors/composer.json index 02296c61..18e96c6e 100644 --- a/vendor/asm89/stack-cors/composer.json +++ b/vendor/asm89/stack-cors/composer.json @@ -12,11 +12,32 @@ } ], "require": { - "php": ">=5.3.2", - "symfony/http-foundation": "~2.1|~3.0", - "symfony/http-kernel": "~2.1|~3.0" + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0", + "symfony/http-kernel": "~2.7|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" }, "autoload": { - "psr-0": { "Asm89\\Stack": "src/" } + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" + } + }, + "autoload-dev": { + "psr-4": { + "Asm89\\Stack\\": "test/Asm89/Stack/" + } + }, + "scripts": { + "test": "phpunit", + "check-style": "phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src", + "fix-style": "phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src" + }, + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } } } diff --git a/vendor/asm89/stack-cors/phpunit.xml.dist b/vendor/asm89/stack-cors/phpunit.xml.dist deleted file mode 100644 index 1959e537..00000000 --- a/vendor/asm89/stack-cors/phpunit.xml.dist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - ./test/Asm89/ - - - - - - ./src/ - - - - diff --git a/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php b/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php old mode 100755 new mode 100644 index a5e81ce2..99f29736 --- a/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php +++ b/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Asm89\Stack; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -31,12 +40,11 @@ public function __construct(HttpKernelInterface $app, array $options = array()) { $this->app = $app; $this->cors = new CorsService(array_merge($this->defaultOptions, $options)); - } public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { - if ( ! $this->cors->isCorsRequest($request)) { + if (!$this->cors->isCorsRequest($request)) { return $this->app->handle($request, $type, $catch); } @@ -44,7 +52,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ return $this->cors->handlePreflightRequest($request); } - if ( ! $this->cors->isActualRequestAllowed($request)) { + if (!$this->cors->isActualRequestAllowed($request)) { return new Response('Not allowed.', 403); } diff --git a/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php b/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php old mode 100755 new mode 100644 index 339256b3..09dc44b7 --- a/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php +++ b/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Asm89\Stack; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -17,7 +26,6 @@ public function __construct(array $options = array()) private function normalizeOptions(array $options = array()) { - $options += array( 'allowedOrigins' => array(), 'supportsCredentials' => false, @@ -29,18 +37,18 @@ private function normalizeOptions(array $options = array()) // normalize array('*') to true if (in_array('*', $options['allowedOrigins'])) { - $options['allowedOrigins'] = true; + $options['allowedOrigins'] = true; } if (in_array('*', $options['allowedHeaders'])) { - $options['allowedHeaders'] = true; + $options['allowedHeaders'] = true; } else { - $options['allowedHeaders'] = array_map('strtolower', $options['allowedHeaders']); + $options['allowedHeaders'] = array_map('strtolower', $options['allowedHeaders']); } if (in_array('*', $options['allowedMethods'])) { - $options['allowedMethods'] = true; + $options['allowedMethods'] = true; } else { - $options['allowedMethods'] = array_map('strtoupper', $options['allowedMethods']); + $options['allowedMethods'] = array_map('strtoupper', $options['allowedMethods']); } return $options; @@ -53,25 +61,25 @@ public function isActualRequestAllowed(Request $request) public function isCorsRequest(Request $request) { - return $request->headers->has('Origin'); + return $request->headers->has('Origin') && !$this->isSameHost($request); } public function isPreflightRequest(Request $request) { return $this->isCorsRequest($request) - &&$request->getMethod() === 'OPTIONS' + && $request->getMethod() === 'OPTIONS' && $request->headers->has('Access-Control-Request-Method'); } public function addActualRequestHeaders(Response $response, Request $request) { - if ( ! $this->checkOrigin($request)) { + if (!$this->checkOrigin($request)) { return $response; } $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin')); - if ( ! $response->headers->has('Vary')) { + if (!$response->headers->has('Vary')) { $response->headers->set('Vary', 'Origin'); } else { $response->headers->set('Vary', $response->headers->get('Vary') . ', Origin'); @@ -126,11 +134,11 @@ private function buildPreflightCheckResponse(Request $request) private function checkPreflightRequestConditions(Request $request) { - if ( ! $this->checkOrigin($request)) { + if (!$this->checkOrigin($request)) { return $this->createBadRequestResponse(403, 'Origin not allowed'); } - if ( ! $this->checkMethod($request)) { + if (!$this->checkMethod($request)) { return $this->createBadRequestResponse(405, 'Method not allowed'); } @@ -138,10 +146,10 @@ private function checkPreflightRequestConditions(Request $request) // if allowedHeaders has been set to true ('*' allow all flag) just skip this check if ($this->options['allowedHeaders'] !== true && $request->headers->has('Access-Control-Request-Headers')) { $headers = strtolower($request->headers->get('Access-Control-Request-Headers')); - $requestHeaders = explode(',', $headers); + $requestHeaders = array_filter(explode(',', $headers)); foreach ($requestHeaders as $header) { - if ( ! in_array(trim($header), $this->options['allowedHeaders'])) { + if (!in_array(trim($header), $this->options['allowedHeaders'])) { return $this->createBadRequestResponse(403, 'Header not allowed'); } } @@ -155,7 +163,13 @@ private function createBadRequestResponse($code, $reason = '') return new Response($reason, $code); } - private function checkOrigin(Request $request) { + private function isSameHost(Request $request) + { + return $request->headers->get('Origin') === $request->getSchemeAndHttpHost(); + } + + private function checkOrigin(Request $request) + { if ($this->options['allowedOrigins'] === true) { // allow all '*' flag return true; @@ -165,7 +179,8 @@ private function checkOrigin(Request $request) { return in_array($origin, $this->options['allowedOrigins']); } - private function checkMethod(Request $request) { + private function checkMethod(Request $request) + { if ($this->options['allowedMethods'] === true) { // allow all '*' flag return true; @@ -174,5 +189,4 @@ private function checkMethod(Request $request) { $requestMethod = strtoupper($request->headers->get('Access-Control-Request-Method')); return in_array($requestMethod, $this->options['allowedMethods']); } - } diff --git a/vendor/asm89/stack-cors/test/Asm89/Stack/CorsTest.php b/vendor/asm89/stack-cors/test/Asm89/Stack/CorsTest.php deleted file mode 100755 index 1493c46c..00000000 --- a/vendor/asm89/stack-cors/test/Asm89/Stack/CorsTest.php +++ /dev/null @@ -1,395 +0,0 @@ -createStackedApp(); - $unmodifiedResponse = new Response(); - - $response = $app->handle(new Request()); - - $this->assertEquals($unmodifiedResponse->headers, $response->headers); - } - - /** - * @test - */ - public function it_returns_403_on_valid_actual_request_with_origin_not_allowed() - { - $app = $this->createStackedApp(array('allowedOrigins' => array('notlocalhost'))); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertEquals(403, $response->getStatusCode()); - } - - /** - * @test - */ - public function it_returns_allow_origin_header_on_valid_actual_request() - { - $app = $this->createStackedApp(); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Origin')); - $this->assertEquals('localhost', $response->headers->get('Access-Control-Allow-Origin')); - } - - /** - * @test - */ - public function it_returns_allow_origin_header_on_allow_all_origin_request() - { - $app = $this->createStackedApp(array('allowedOrigins' => array('*'))); - $request = new Request(); - $request->headers->set('Origin', 'http://localhost'); - - $response = $app->handle($request); - - $this->assertEquals(200, $response->getStatusCode()); - $this->assertTrue($response->headers->has('Access-Control-Allow-Origin')); - $this->assertEquals('http://localhost', $response->headers->get('Access-Control-Allow-Origin')); - } - - /** - * @test - */ - public function it_returns_allow_headers_header_on_allow_all_headers_request() - { - $app = $this->createStackedApp(array('allowedHeaders' => array('*'))); - $request = $this->createValidPreflightRequest(); - $request->headers->set('Access-Control-Request-Headers', 'Foo, BAR'); - - $response = $app->handle($request); - - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('FOO, BAR', $response->headers->get('Access-Control-Allow-Headers')); - } - - /** - * @test - */ - public function it_does_not_return_allow_origin_header_on_valid_actual_request_with_origin_not_allowed() - { - $app = $this->createStackedApp(array('allowedOrigins' => array('notlocalhost'))); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertFalse($response->headers->has('Access-Control-Allow-Origin')); - } - - /** - * @test - */ - public function it_sets_allow_credentials_header_when_flag_is_set_on_valid_actual_request() - { - $app = $this->createStackedApp(array('supportsCredentials' => true)); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Credentials')); - $this->assertEquals('true', $response->headers->get('Access-Control-Allow-Credentials')); - } - - /** - * @test - */ - public function it_does_not_set_allow_credentials_header_when_flag_is_not_set_on_valid_actual_request() - { - $app = $this->createStackedApp(); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertFalse($response->headers->has('Access-Control-Allow-Credentials')); - } - - /** - * @test - */ - public function it_sets_exposed_headers_when_configured_on_actual_request() - { - $app = $this->createStackedApp(array('exposedHeaders' => array('x-exposed-header', 'x-another-exposed-header'))); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Expose-Headers')); - $this->assertEquals('x-exposed-header, x-another-exposed-header', $response->headers->get('Access-Control-Expose-Headers')); - } - - /** - * @test - * @see http://www.w3.org/TR/cors/index.html#resource-implementation - */ - public function it_adds_a_vary_header() - { - $app = $this->createStackedApp(); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Vary')); - $this->assertEquals('Origin', $response->headers->get('Vary')); - } - - /** - * @test - * @see http://www.w3.org/TR/cors/index.html#resource-implementation - */ - public function it_appends_an_existing_vary_header() - { - $app = $this->createStackedApp(array(), array('Vary' => 'Content-Type')); - $request = $this->createValidActualRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Vary')); - $this->assertEquals('Content-Type, Origin', $response->headers->get('Vary')); - } - - /** - * @test - */ - public function it_returns_access_control_headers_on_cors_request() - { - $app = $this->createStackedApp(); - $request = new Request(); - $request->headers->set('Origin', 'localhost'); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Origin')); - $this->assertEquals('localhost', $response->headers->get('Access-Control-Allow-Origin')); - } - - /** - * @test - */ - public function it_returns_access_control_headers_on_valid_preflight_request() - { - $app = $this->createStackedApp(); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Origin')); - $this->assertEquals('localhost', $response->headers->get('Access-Control-Allow-Origin')); - } - - /** - * @test - */ - public function it_returns_403_on_valid_preflight_request_with_origin_not_allowed() - { - $app = $this->createStackedApp(array('allowedOrigins' => array('notlocalhost'))); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertEquals(403, $response->getStatusCode()); - } - - /** - * @test - */ - public function it_does_not_modify_request_with_origin_not_allowed() - { - $passedOptions = array( - 'allowedOrigins' => array('notlocalhost'), - ); - - $service = new CorsService($passedOptions); - $request = $this->createValidActualRequest(); - $response = new Response(); - $service->addActualRequestHeaders($response, $request); - - $this->assertEquals($response, new Response()); - } - - /** - * @test - */ - public function it_returns_405_on_valid_preflight_request_with_method_not_allowed() - { - $app = $this->createStackedApp(array('allowedMethods' => array('put'))); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertEquals(405, $response->getStatusCode()); - } - - /** - * @test - */ - public function it_allow_methods_on_valid_preflight_request() - { - $app = $this->createStackedApp(array('allowedMethods' => array('get', 'put'))); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Methods')); - // it will uppercase the methods - $this->assertEquals('GET, PUT', $response->headers->get('Access-Control-Allow-Methods')); - } - - /** - * @test - */ - public function it_returns_valid_preflight_request_with_allow_methods_all() - { - $app = $this->createStackedApp(array('allowedMethods' => array('*'))); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Methods')); - // it will return the Access-Control-Request-Method pass in the request - $this->assertEquals('GET', $response->headers->get('Access-Control-Allow-Methods')); - } - - /** - * @test - */ - public function it_returns_403_on_valid_preflight_request_with_one_of_the_requested_headers_not_allowed() - { - $app = $this->createStackedApp(); - $request = $this->createValidPreflightRequest(); - $request->headers->set('Access-Control-Request-Headers', 'x-not-allowed-header'); - - $response = $app->handle($request); - - $this->assertEquals(403, $response->getStatusCode()); - } - - /** - * @test - */ - public function it_returns_ok_on_valid_preflight_request_with_requested_headers_allowed() - { - $app = $this->createStackedApp(); - $requestHeaders = 'X-Allowed-Header, x-other-allowed-header'; - $request = $this->createValidPreflightRequest(); - $request->headers->set('Access-Control-Request-Headers', $requestHeaders); - - $response = $app->handle($request); - - $this->assertEquals(200, $response->getStatusCode()); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Headers')); - // the response will have the "allowedHeaders" value passed to Cors rather than the request one - $this->assertEquals('x-allowed-header, x-other-allowed-header', $response->headers->get('Access-Control-Allow-Headers')); - } - - /** - * @test - */ - public function it_sets_allow_credentials_header_when_flag_is_set_on_valid_preflight_request() - { - $app = $this->createStackedApp(array('supportsCredentials' => true)); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Allow-Credentials')); - $this->assertEquals('true', $response->headers->get('Access-Control-Allow-Credentials')); - } - - /** - * @test - */ - public function it_does_not_set_allow_credentials_header_when_flag_is_not_set_on_valid_preflight_request() - { - $app = $this->createStackedApp(); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertFalse($response->headers->has('Access-Control-Allow-Credentials')); - } - - /** - * @test - */ - public function it_sets_max_age_when_set() - { - $app = $this->createStackedApp(array('maxAge' => 42)); - $request = $this->createValidPreflightRequest(); - - $response = $app->handle($request); - - $this->assertTrue($response->headers->has('Access-Control-Max-Age')); - $this->assertEquals(42, $response->headers->get('Access-Control-Max-Age')); - } - - private function createValidActualRequest() - { - $request = new Request(); - $request->headers->set('Origin', 'localhost'); - - return $request; - } - - private function createValidPreflightRequest() - { - $request = new Request(); - $request->headers->set('Origin', 'localhost'); - $request->headers->set('Access-Control-Request-Method', 'get'); - $request->setMethod('OPTIONS'); - - return $request; - } - - private function createStackedApp(array $options = array(), array $responseHeaders = array()) - { - $passedOptions = array_merge(array( - 'allowedHeaders' => array('x-allowed-header', 'x-other-allowed-header'), - 'allowedMethods' => array('delete', 'get', 'post', 'put'), - 'allowedOrigins' => array('localhost'), - 'exposedHeaders' => false, - 'maxAge' => false, - 'supportsCredentials' => false, - ), - $options - ); - - return new Cors(new MockApp($responseHeaders), $passedOptions); - } -} - -class MockApp implements HttpKernelInterface -{ - private $responseHeaders; - - public function __construct(array $responseHeaders) - { - $this->responseHeaders = $responseHeaders; - } - - public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) - { - $response = new Response(); - - $response->headers->add($this->responseHeaders); - - return $response; - } -} diff --git a/vendor/asm89/stack-cors/test/bootstrap.php b/vendor/asm89/stack-cors/test/bootstrap.php deleted file mode 100644 index deb617fb..00000000 --- a/vendor/asm89/stack-cors/test/bootstrap.php +++ /dev/null @@ -1,10 +0,0 @@ -add('Asm89\Stack', __DIR__); - $loader->add('Asm89\Stack', __DIR__ . '/../src'); -} else { - throw new RuntimeException('Install dependencies to run test suite.'); -} - diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 4626994f..2c72175e 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -374,9 +374,13 @@ private function findFileWithExtension($class, $ext) $first = $class[0]; if (isset($this->prefixLengthsPsr4[$first])) { - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { - if (0 === strpos($class, $prefix)) { - foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + foreach ($this->prefixDirsPsr4[$search] as $dir) { + $length = $this->prefixLengthsPsr4[$first][$search]; if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { return $file; } diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE index 1a281248..f27399a0 100644 --- a/vendor/composer/LICENSE +++ b/vendor/composer/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) 2016 Nils Adermann, Jordi Boggiano +Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 6bd4f40c..6d69f7f0 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,7 +6,6 @@ $baseDir = dirname($vendorDir); return array( - 'CallbackFilterIterator' => $vendorDir . '/symfony/polyfill-php54/Resources/stubs/CallbackFilterIterator.php', 'Drupal' => $baseDir . '/core/lib/Drupal.php', 'Drupal\\Component\\Utility\\Timer' => $baseDir . '/core/lib/Drupal/Component/Utility/Timer.php', 'Drupal\\Component\\Utility\\Unicode' => $baseDir . '/core/lib/Drupal/Component/Utility/Unicode.php', @@ -14,8 +13,6 @@ 'Drupal\\Core\\DrupalKernel' => $baseDir . '/core/lib/Drupal/Core/DrupalKernel.php', 'Drupal\\Core\\DrupalKernelInterface' => $baseDir . '/core/lib/Drupal/Core/DrupalKernelInterface.php', 'Drupal\\Core\\Site\\Settings' => $baseDir . '/core/lib/Drupal/Core/Site/Settings.php', - 'RecursiveCallbackFilterIterator' => $vendorDir . '/symfony/polyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.php', - 'SessionHandlerInterface' => $vendorDir . '/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php', 'Symfony\\Component\\HttpFoundation\\FileBag' => $vendorDir . '/symfony/http-foundation/FileBag.php', 'Symfony\\Component\\HttpFoundation\\HeaderBag' => $vendorDir . '/symfony/http-foundation/HeaderBag.php', 'Symfony\\Component\\HttpFoundation\\ParameterBag' => $vendorDir . '/symfony/http-foundation/ParameterBag.php', diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 947fa010..bcf8ded6 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -7,10 +7,6 @@ return array( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', - 'e40631d46120a9c38ea139981f8dab26' => $vendorDir . '/ircmaxell/password-compat/lib/password.php', - 'edc6464955a37aa4d5fbf39d40fb6ee7' => $vendorDir . '/symfony/polyfill-php55/bootstrap.php', - '3e2471375464aac821502deb0ac64275' => $vendorDir . '/symfony/polyfill-php54/bootstrap.php', - '32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index 8fec74fd..d234d49a 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -8,15 +8,10 @@ return array( 'Twig_' => array($vendorDir . '/twig/twig/lib'), 'Stack' => array($vendorDir . '/stack/builder/src'), - 'Psr\\Log\\' => array($vendorDir . '/psr/log'), 'Egulias\\' => array($vendorDir . '/egulias/email-validator/src'), 'EasyRdf_' => array($vendorDir . '/easyrdf/easyrdf/lib'), 'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'), 'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'), 'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib'), - 'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib'), 'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib'), - 'Doctrine\\Common\\' => array($vendorDir . '/doctrine/common/lib'), - 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src'), - 'Asm89\\Stack' => array($vendorDir . '/asm89/stack-cors/src'), ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 132440ba..83bd5c7b 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,13 +7,10 @@ return array( 'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib/src'), - 'Zend\\Hydrator\\' => array($vendorDir . '/zendframework/zend-hydrator/src'), 'Zend\\Feed\\' => array($vendorDir . '/zendframework/zend-feed/src'), 'Zend\\Escaper\\' => array($vendorDir . '/zendframework/zend-escaper/src'), 'Zend\\Diactoros\\' => array($vendorDir . '/zendframework/zend-diactoros/src'), 'Wikimedia\\Composer\\' => array($vendorDir . '/wikimedia/composer-merge-plugin/src'), - 'Symfony\\Polyfill\\Php55\\' => array($vendorDir . '/symfony/polyfill-php55'), - 'Symfony\\Polyfill\\Php54\\' => array($vendorDir . '/symfony/polyfill-php54'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Iconv\\' => array($vendorDir . '/symfony/polyfill-iconv'), 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), @@ -31,6 +28,7 @@ 'Symfony\\Component\\ClassLoader\\' => array($vendorDir . '/symfony/class-loader'), 'Symfony\\Cmf\\Component\\Routing\\' => array($vendorDir . '/symfony-cmf/routing'), 'Symfony\\Bridge\\PsrHttpMessage\\' => array($vendorDir . '/symfony/psr-http-message-bridge'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'Masterminds\\' => array($vendorDir . '/masterminds/html5/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), @@ -40,5 +38,9 @@ 'Drupal\\Core\\Composer\\' => array($baseDir . '/core/lib/Drupal/Core/Composer'), 'Drupal\\Core\\' => array($baseDir . '/core/lib/Drupal/Core'), 'Drupal\\Component\\' => array($baseDir . '/core/lib/Drupal/Component'), + 'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'), + 'Doctrine\\Common\\' => array($vendorDir . '/doctrine/common/lib/Doctrine/Common'), 'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'), + 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), + 'Asm89\\Stack\\' => array($vendorDir . '/asm89/stack-cors/src/Asm89/Stack'), ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index d39f78d1..6187fc56 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -8,10 +8,6 @@ class ComposerStaticInitDrupal8 { public static $files = array ( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', - 'e40631d46120a9c38ea139981f8dab26' => __DIR__ . '/..' . '/ircmaxell/password-compat/lib/password.php', - 'edc6464955a37aa4d5fbf39d40fb6ee7' => __DIR__ . '/..' . '/symfony/polyfill-php55/bootstrap.php', - '3e2471375464aac821502deb0ac64275' => __DIR__ . '/..' . '/symfony/polyfill-php54/bootstrap.php', - '32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', @@ -23,7 +19,6 @@ class ComposerStaticInitDrupal8 'Z' => array ( 'Zend\\Stdlib\\' => 12, - 'Zend\\Hydrator\\' => 14, 'Zend\\Feed\\' => 10, 'Zend\\Escaper\\' => 13, 'Zend\\Diactoros\\' => 15, @@ -34,8 +29,6 @@ class ComposerStaticInitDrupal8 ), 'S' => array ( - 'Symfony\\Polyfill\\Php55\\' => 23, - 'Symfony\\Polyfill\\Php54\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Iconv\\' => 23, 'Symfony\\Component\\Yaml\\' => 23, @@ -56,6 +49,7 @@ class ComposerStaticInitDrupal8 ), 'P' => array ( + 'Psr\\Log\\' => 8, 'Psr\\Http\\Message\\' => 17, ), 'M' => @@ -74,10 +68,17 @@ class ComposerStaticInitDrupal8 'Drupal\\Core\\Composer\\' => 21, 'Drupal\\Core\\' => 12, 'Drupal\\Component\\' => 17, + 'Doctrine\\Common\\Cache\\' => 22, + 'Doctrine\\Common\\' => 16, ), 'C' => array ( 'Composer\\Semver\\' => 16, + 'Composer\\Installers\\' => 20, + ), + 'A' => + array ( + 'Asm89\\Stack\\' => 12, ), ); @@ -86,10 +87,6 @@ class ComposerStaticInitDrupal8 array ( 0 => __DIR__ . '/..' . '/zendframework/zend-stdlib/src', ), - 'Zend\\Hydrator\\' => - array ( - 0 => __DIR__ . '/..' . '/zendframework/zend-hydrator/src', - ), 'Zend\\Feed\\' => array ( 0 => __DIR__ . '/..' . '/zendframework/zend-feed/src', @@ -106,14 +103,6 @@ class ComposerStaticInitDrupal8 array ( 0 => __DIR__ . '/..' . '/wikimedia/composer-merge-plugin/src', ), - 'Symfony\\Polyfill\\Php55\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php55', - ), - 'Symfony\\Polyfill\\Php54\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php54', - ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', @@ -182,6 +171,10 @@ class ComposerStaticInitDrupal8 array ( 0 => __DIR__ . '/..' . '/symfony/psr-http-message-bridge', ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), 'Psr\\Http\\Message\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-message/src', @@ -218,10 +211,26 @@ class ComposerStaticInitDrupal8 array ( 0 => __DIR__ . '/../..' . '/core/lib/Drupal/Component', ), + 'Doctrine\\Common\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache', + ), + 'Doctrine\\Common\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/common/lib/Doctrine/Common', + ), 'Composer\\Semver\\' => array ( 0 => __DIR__ . '/..' . '/composer/semver/src', ), + 'Composer\\Installers\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', + ), + 'Asm89\\Stack\\' => + array ( + 0 => __DIR__ . '/..' . '/asm89/stack-cors/src/Asm89/Stack', + ), ); public static $prefixesPsr0 = array ( @@ -239,13 +248,6 @@ class ComposerStaticInitDrupal8 0 => __DIR__ . '/..' . '/stack/builder/src', ), ), - 'P' => - array ( - 'Psr\\Log\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/log', - ), - ), 'E' => array ( 'Egulias\\' => @@ -271,37 +273,14 @@ class ComposerStaticInitDrupal8 array ( 0 => __DIR__ . '/..' . '/doctrine/collections/lib', ), - 'Doctrine\\Common\\Cache\\' => - array ( - 0 => __DIR__ . '/..' . '/doctrine/cache/lib', - ), 'Doctrine\\Common\\Annotations\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/annotations/lib', ), - 'Doctrine\\Common\\' => - array ( - 0 => __DIR__ . '/..' . '/doctrine/common/lib', - ), - ), - 'C' => - array ( - 'Composer\\Installers\\' => - array ( - 0 => __DIR__ . '/..' . '/composer/installers/src', - ), - ), - 'A' => - array ( - 'Asm89\\Stack' => - array ( - 0 => __DIR__ . '/..' . '/asm89/stack-cors/src', - ), ), ); public static $classMap = array ( - 'CallbackFilterIterator' => __DIR__ . '/..' . '/symfony/polyfill-php54/Resources/stubs/CallbackFilterIterator.php', 'Drupal' => __DIR__ . '/../..' . '/core/lib/Drupal.php', 'Drupal\\Component\\Utility\\Timer' => __DIR__ . '/../..' . '/core/lib/Drupal/Component/Utility/Timer.php', 'Drupal\\Component\\Utility\\Unicode' => __DIR__ . '/../..' . '/core/lib/Drupal/Component/Utility/Unicode.php', @@ -309,8 +288,6 @@ class ComposerStaticInitDrupal8 'Drupal\\Core\\DrupalKernel' => __DIR__ . '/../..' . '/core/lib/Drupal/Core/DrupalKernel.php', 'Drupal\\Core\\DrupalKernelInterface' => __DIR__ . '/../..' . '/core/lib/Drupal/Core/DrupalKernelInterface.php', 'Drupal\\Core\\Site\\Settings' => __DIR__ . '/../..' . '/core/lib/Drupal/Core/Site/Settings.php', - 'RecursiveCallbackFilterIterator' => __DIR__ . '/..' . '/symfony/polyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.php', - 'SessionHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php', 'Symfony\\Component\\HttpFoundation\\FileBag' => __DIR__ . '/..' . '/symfony/http-foundation/FileBag.php', 'Symfony\\Component\\HttpFoundation\\HeaderBag' => __DIR__ . '/..' . '/symfony/http-foundation/HeaderBag.php', 'Symfony\\Component\\HttpFoundation\\ParameterBag' => __DIR__ . '/..' . '/symfony/http-foundation/ParameterBag.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 4c629e50..481b3789 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,19 +1,22 @@ [ { "name": "composer/installers", - "version": "v1.0.21", - "version_normalized": "1.0.21.0", + "version": "v1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45" + "reference": "9ce17fb70e9a38dd8acff0636a29f5cf4d575c1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45", - "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45", + "url": "https://api.github.com/repos/composer/installers/zipball/9ce17fb70e9a38dd8acff0636a29f5cf4d575c1b", + "reference": "9ce17fb70e9a38dd8acff0636a29f5cf4d575c1b", "shasum": "" }, + "require": { + "composer-plugin-api": "^1.0" + }, "replace": { "roundcube/plugin-installer": "*", "shama/baton": "*" @@ -22,18 +25,18 @@ "composer/composer": "1.0.*@dev", "phpunit/phpunit": "4.1.*" }, - "time": "2015-02-18T17:17:01+00:00", - "type": "composer-installer", + "time": "2017-08-09T07:53:48+00:00", + "type": "composer-plugin", "extra": { - "class": "Composer\\Installers\\Installer", + "class": "Composer\\Installers\\Plugin", "branch-alias": { "dev-master": "1.0-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Composer\\Installers\\": "src/" + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" } }, "notification-url": "https://packagist.org/downloads/", @@ -48,67 +51,86 @@ } ], "description": "A multi-framework Composer library installer", - "homepage": "http://composer.github.com/installers/", + "homepage": "https://composer.github.io/installers/", "keywords": [ "Craft", "Dolibarr", + "Eliasis", "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", "MODX Evo", + "Mautic", + "Maya", "OXID", + "Plentymarkets", + "Porto", + "RadPHP", "SMF", "Thelia", "WolfCMS", "agl", "aimeos", "annotatecms", + "attogram", "bitrix", "cakephp", "chef", + "cockpit", "codeigniter", "concrete5", "croogo", "dokuwiki", "drupal", + "eZ Platform", "elgg", + "expressionengine", "fuelphp", "grav", "installer", + "itop", "joomla", "kohana", "laravel", + "lavalite", "lithium", "magento", "mako", "mediawiki", "modulework", "moodle", + "osclass", "phpbb", "piwik", "ppi", "puppet", + "reindex", "roundcube", "shopware", "silverstripe", + "sydes", "symfony", "typo3", "wordpress", + "yawik", "zend", "zikula" ] }, { "name": "wikimedia/composer-merge-plugin", - "version": "v1.3.1", - "version_normalized": "1.3.1.0", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", "source": { "type": "git", "url": "https://github.com/wikimedia/composer-merge-plugin.git", - "reference": "0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4" + "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4", - "reference": "0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/81c6ac72a24a67383419c7eb9aa2b3437f2ab100", + "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100", "shasum": "" }, "require": { @@ -116,12 +138,12 @@ "php": ">=5.3.2" }, "require-dev": { - "composer/composer": "1.0.*@dev", + "composer/composer": "~1.0.0", "jakub-onderka/php-parallel-lint": "~0.8", "phpunit/phpunit": "~4.8|~5.0", "squizlabs/php_codesniffer": "~2.1.0" }, - "time": "2016-03-08T17:11:37+00:00", + "time": "2017-04-25T02:31:25+00:00", "type": "composer-plugin", "extra": { "branch-alias": { @@ -147,168 +169,6 @@ ], "description": "Composer plugin to merge multiple composer.json files" }, - { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", - "version_normalized": "1.0.4.0", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "time": "2014-11-20T16:49:30+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ] - }, - { - "name": "symfony/polyfill-php55", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php55.git", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67", - "reference": "03e3f0350bca2220e3623a0e340eef194405fc67", - "shasum": "" - }, - "require": { - "ircmaxell/password-compat": "~1.0", - "php": ">=5.3.3" - }, - "time": "2016-11-14T01:06:16+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php55\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ] - }, - { - "name": "symfony/polyfill-php54", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", - "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2016-11-14T01:06:16+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php54\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ] - }, { "name": "symfony/polyfill-mbstring", "version": "v1.3.0", @@ -372,33 +232,31 @@ }, { "name": "symfony/http-foundation", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f" + "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/464cdde6757a40701d758112cc7ff2c6adf6e82f", - "reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9de6add7f731e5af7f5b2e9c0da365e43383ebef", + "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/expression-language": "~2.8|~3.0" }, - "time": "2017-01-08T20:43:03+00:00", + "time": "2017-05-01T14:55:58+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -429,38 +287,38 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34" + "reference": "b8a401f733b43251e1d088c589368b2a94155e40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34", - "reference": "74877977f90fb9c3e46378d5764217c55f32df34", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b8a401f733b43251e1d088c589368b2a94155e40", + "reference": "b8a401f733b43251e1d088c589368b2a94155e40", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" }, "suggest": { "symfony/dependency-injection": "", "symfony/http-kernel": "" }, - "time": "2017-01-02T20:30:24+00:00", + "time": "2017-05-01T14:58:48+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -491,25 +349,33 @@ }, { "name": "psr/log", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.0.2", + "version_normalized": "1.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "1.0.0" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/1.0.0", - "reference": "1.0.0", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, - "time": "2012-12-21T11:40:51+00:00", + "require": { + "php": ">=5.3.0" + }, + "time": "2016-10-10T12:19:37+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "installation-source": "dist", "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -523,6 +389,7 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", @@ -531,35 +398,35 @@ }, { "name": "symfony/debug", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "567681e2c4e5431704e884e4be25a95fd900770f" + "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/567681e2c4e5431704e884e4be25a95fd900770f", - "reference": "567681e2c4e5431704e884e4be25a95fd900770f", + "url": "https://api.github.com/repos/symfony/debug/zipball/fd6eeee656a5a7b384d56f1072243fe1c0e81686", + "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "psr/log": "~1.0" }, "conflict": { "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0" + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" }, - "time": "2017-01-02T20:30:24+00:00", + "time": "2017-04-19T20:17:50+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -590,45 +457,45 @@ }, { "name": "symfony/http-kernel", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c" + "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1097eb4ce0a7bdcd030f110c123682fed89a137c", - "reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/46e8b209abab55c072c47d72d5cd1d62c0585e05", + "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "psr/log": "~1.0", - "symfony/debug": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0", - "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6" + "symfony/debug": "~2.8|~3.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { - "symfony/browser-kit": "~2.3|~3.0.0", - "symfony/class-loader": "~2.1|~3.0.0", - "symfony/config": "~2.8", - "symfony/console": "~2.3|~3.0.0", - "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.8|~3.0.0", - "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/finder": "~2.0,>=2.0.5|~3.0.0", - "symfony/process": "~2.0,>=2.0.5|~3.0.0", - "symfony/routing": "~2.8|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0", - "symfony/templating": "~2.2|~3.0.0", - "symfony/translation": "~2.0,>=2.0.5|~3.0.0", - "symfony/var-dumper": "~2.6|~3.0.0" + "symfony/browser-kit": "~2.8|~3.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/css-selector": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/dom-crawler": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0", + "symfony/routing": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", + "symfony/templating": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/var-dumper": "~3.2" }, "suggest": { "symfony/browser-kit": "", @@ -639,11 +506,11 @@ "symfony/finder": "", "symfony/var-dumper": "" }, - "time": "2017-01-12T20:27:24+00:00", + "time": "2017-05-01T17:46:48+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -674,30 +541,39 @@ }, { "name": "asm89/stack-cors", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/asm89/stack-cors.git", - "reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc" + "reference": "65ccbd455370f043c2e3b93482a3813603d68731" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/asm89/stack-cors/zipball/3ae8ef219bb4c9a6caf857421719aa07fa7776cc", - "reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc", + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/65ccbd455370f043c2e3b93482a3813603d68731", + "reference": "65ccbd455370f043c2e3b93482a3813603d68731", "shasum": "" }, "require": { - "php": ">=5.3.2", - "symfony/http-foundation": "~2.1|~3.0", - "symfony/http-kernel": "~2.1|~3.0" + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0", + "symfony/http-kernel": "~2.7|~3.0" }, - "time": "2016-08-01T12:05:04+00:00", + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" + }, + "time": "2017-04-11T20:03:41+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, "installation-source": "dist", "autoload": { - "psr-0": { - "Asm89\\Stack": "src/" + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" } }, "notification-url": "https://packagist.org/downloads/", @@ -719,31 +595,31 @@ }, { "name": "composer/semver", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.4.2", + "version_normalized": "1.4.2.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba" + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba", - "reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "~2.3" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, - "time": "2015-09-21T09:42:36+00:00", + "time": "2016-08-30T16:08:34+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "0.1-dev" + "dev-master": "1.x-dev" } }, "installation-source": "dist", @@ -757,10 +633,6 @@ "MIT" ], "authors": [ - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com" - }, { "name": "Nils Adermann", "email": "naderman@naderman.de", @@ -770,6 +642,11 @@ "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], "description": "Semver library that offers utilities, version constraint parsing and validation.", @@ -838,17 +715,17 @@ }, { "name": "doctrine/inflector", - "version": "v1.0.1", - "version_normalized": "1.0.1.0", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", "shasum": "" }, "require": { @@ -857,11 +734,11 @@ "require-dev": { "phpunit/phpunit": "4.*" }, - "time": "2014-12-20T21:24:13+00:00", + "time": "2015-11-06T14:35:42+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "installation-source": "dist", @@ -975,41 +852,41 @@ }, { "name": "doctrine/cache", - "version": "v1.4.2", - "version_normalized": "1.4.2.0", + "version": "v1.6.1", + "version_normalized": "1.6.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca" + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "conflict": { "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "phpunit/phpunit": ">=3.7", + "phpunit/phpunit": "~4.8|~5.0", "predis/predis": "~1.0", "satooshi/php-coveralls": "~0.6" }, - "time": "2015-08-31T12:36:41+00:00", + "time": "2016-10-29T11:16:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.5.x-dev" + "dev-master": "1.6.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Doctrine\\Common\\Cache\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } }, "notification-url": "https://packagist.org/downloads/", @@ -1117,17 +994,17 @@ }, { "name": "doctrine/common", - "version": "v2.5.1", - "version_normalized": "2.5.1.0", + "version": "v2.6.2", + "version_normalized": "2.6.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9" + "reference": "7bce00698899aa2c06fe7365c76e4d78ddb15fa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9", + "url": "https://api.github.com/repos/doctrine/common/zipball/7bce00698899aa2c06fe7365c76e4d78ddb15fa3", + "reference": "7bce00698899aa2c06fe7365c76e4d78ddb15fa3", "shasum": "" }, "require": { @@ -1136,22 +1013,22 @@ "doctrine/collections": "1.*", "doctrine/inflector": "1.*", "doctrine/lexer": "1.*", - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "require-dev": { - "phpunit/phpunit": "~3.7" + "phpunit/phpunit": "~4.8|~5.0" }, - "time": "2015-08-31T13:00:22+00:00", + "time": "2016-11-30T16:50:46+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } }, "installation-source": "dist", "autoload": { - "psr-0": { - "Doctrine\\Common\\": "lib/" + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", @@ -1256,28 +1133,27 @@ }, { "name": "egulias/email-validator", - "version": "1.2.9", - "version_normalized": "1.2.9.0", + "version": "1.2.14", + "version_normalized": "1.2.14.0", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "af864423f50ea59f96c87bb1eae147a70bcf67a1" + "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/af864423f50ea59f96c87bb1eae147a70bcf67a1", - "reference": "af864423f50ea59f96c87bb1eae147a70bcf67a1", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/5642614492f0ca2064c01d60cc33284cc2f731a9", + "reference": "5642614492f0ca2064c01d60cc33284cc2f731a9", "shasum": "" }, "require": { - "doctrine/lexer": "~1.0,>=1.0.1", + "doctrine/lexer": "^1.0.1", "php": ">= 5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.4", - "satooshi/php-coveralls": "dev-master" + "phpunit/phpunit": "^4.8.24" }, - "time": "2015-06-22T21:07:51+00:00", + "time": "2017-02-03T22:48:59+00:00", "type": "library", "extra": { "branch-alias": { @@ -1311,23 +1187,23 @@ }, { "name": "psr/http-message", - "version": "1.0", - "version_normalized": "1.0.0.0", + "version": "1.0.1", + "version_normalized": "1.0.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2015-05-04T20:22:00+00:00", + "time": "2016-08-06T14:39:51+00:00", "type": "library", "extra": { "branch-alias": { @@ -1351,6 +1227,7 @@ } ], "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", "keywords": [ "http", "http-message", @@ -1362,17 +1239,17 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.3.1", - "version_normalized": "1.3.1.0", + "version": "1.4.2", + "version_normalized": "1.4.2.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b" + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", - "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "shasum": "" }, "require": { @@ -1385,7 +1262,7 @@ "require-dev": { "phpunit/phpunit": "~4.0" }, - "time": "2016-06-24T23:00:38+00:00", + "time": "2017-03-20T17:10:46+00:00", "type": "library", "extra": { "branch-alias": { @@ -1410,42 +1287,49 @@ "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } ], - "description": "PSR-7 message implementation", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ "http", "message", + "request", + "response", "stream", - "uri" + "uri", + "url" ] }, { "name": "guzzlehttp/promises", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "version": "v1.3.1", + "version_normalized": "1.3.1.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", - "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", "shasum": "" }, "require": { "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0" }, - "time": "2016-05-18T16:56:05+00:00", + "time": "2016-12-20T10:07:11+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } }, "installation-source": "dist", @@ -1475,30 +1359,33 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.2.1", - "version_normalized": "6.2.1.0", + "version": "6.3.0", + "version_normalized": "6.3.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "3f808fba627f2c5b69e2501217bf31af349c1427" + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427", - "reference": "3f808fba627f2c5b69e2501217bf31af349c1427", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", "shasum": "" }, "require": { "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.3.1", + "guzzlehttp/psr7": "^1.4", "php": ">=5.5" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.0", + "phpunit/phpunit": "^4.0 || ^5.0", "psr/log": "^1.0" }, - "time": "2016-07-15T17:22:37+00:00", + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "time": "2017-06-22T18:50:49+00:00", "type": "library", "extra": { "branch-alias": { @@ -1539,17 +1426,17 @@ }, { "name": "masterminds/html5", - "version": "2.2.1", - "version_normalized": "2.2.1.0", + "version": "2.3.0", + "version_normalized": "2.3.0.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "170aa5cb35b29fccafbf5ea63487c013f396fdc9" + "reference": "2c37c6c520b995b761674de3be8455a381679067" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/170aa5cb35b29fccafbf5ea63487c013f396fdc9", - "reference": "170aa5cb35b29fccafbf5ea63487c013f396fdc9", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/2c37c6c520b995b761674de3be8455a381679067", + "reference": "2c37c6c520b995b761674de3be8455a381679067", "shasum": "" }, "require": { @@ -1561,11 +1448,11 @@ "sami/sami": "~2.0", "satooshi/php-coveralls": "1.0.*" }, - "time": "2016-05-10T14:11:45+00:00", + "time": "2017-09-04T12:26:28+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, "installation-source": "dist", @@ -1606,17 +1493,17 @@ }, { "name": "paragonie/random_compat", - "version": "1.1.1", - "version_normalized": "1.1.1.0", + "version": "v2.0.10", + "version_normalized": "2.0.10.0", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32" + "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a208865a5aeffc2dbbef2a5b3409887272d93f32", - "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d", + "reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d", "shasum": "" }, "require": { @@ -1628,7 +1515,7 @@ "suggest": { "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." }, - "time": "2015-12-01T02:52:15+00:00", + "time": "2017-03-13T16:27:32+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1707,33 +1594,33 @@ }, { "name": "symfony/routing", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f" + "reference": "5029745d6d463585e8b487dbc83d6333f408853a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f", - "reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f", + "url": "https://api.github.com/repos/symfony/routing/zipball/5029745d6d463585e8b487dbc83d6333f408853a", + "reference": "5029745d6d463585e8b487dbc83d6333f408853a", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/common": "~2.2", "psr/log": "~1.0", - "symfony/config": "~2.7|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", @@ -1743,11 +1630,11 @@ "symfony/http-foundation": "For using a Symfony Request object", "symfony/yaml": "For using the YAML loader" }, - "time": "2017-01-02T20:30:24+00:00", + "time": "2017-04-12T14:13:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -1784,17 +1671,17 @@ }, { "name": "symfony-cmf/routing", - "version": "1.4.0", - "version_normalized": "1.4.0.0", + "version": "1.4.1", + "version_normalized": "1.4.1.0", "source": { "type": "git", - "url": "https://github.com/symfony-cmf/Routing.git", - "reference": "b93704ca098334f56e9b317932f21a4362e620db" + "url": "https://github.com/symfony-cmf/routing.git", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/b93704ca098334f56e9b317932f21a4362e620db", - "reference": "b93704ca098334f56e9b317932f21a4362e620db", + "url": "https://api.github.com/repos/symfony-cmf/routing/zipball/fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", "shasum": "" }, "require": { @@ -1813,7 +1700,7 @@ "suggest": { "symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version (~2.1)" }, - "time": "2016-03-31T09:11:39+00:00", + "time": "2017-05-09T08:10:41+00:00", "type": "library", "extra": { "branch-alias": { @@ -1843,88 +1730,36 @@ "routing" ] }, - { - "name": "symfony/polyfill-apcu", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-apcu.git", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa", - "reference": "5d4474f447403c3348e37b70acc2b95475b7befa", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2016-11-14T01:06:16+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "apcu", - "compatibility", - "polyfill", - "portable", - "shim" - ] - }, { "name": "symfony/class-loader", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68" + "reference": "fc4c04bfd17130a9dccfded9578353f311967da7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/7c46951128f7169cbece2c303fba4a9eb35cbe68", - "reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/fc4c04bfd17130a9dccfded9578353f311967da7", + "reference": "fc4c04bfd17130a9dccfded9578353f311967da7", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-apcu": "~1.1" + "php": ">=5.5.9" }, "require-dev": { - "symfony/finder": "~2.0,>=2.0.5|~3.0.0" + "symfony/finder": "~2.8|~3.0", + "symfony/polyfill-apcu": "~1.1" }, - "time": "2017-01-10T14:03:07+00:00", + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" + }, + "time": "2017-04-12T14:13:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -1955,39 +1790,41 @@ }, { "name": "symfony/console", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912" + "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912", - "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912", + "url": "https://api.github.com/repos/symfony/console/zipball/a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38", + "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/debug": "~2.7,>=2.7.2|~3.0.0", + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0" + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/filesystem": "", "symfony/process": "" }, - "time": "2017-01-08T20:43:03+00:00", + "time": "2017-04-26T01:39:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2018,29 +1855,29 @@ }, { "name": "symfony/dependency-injection", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "b75356611675364607d697f314850d9d870a84aa" + "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b75356611675364607d697f314850d9d870a84aa", - "reference": "b75356611675364607d697f314850d9d870a84aa", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59", + "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "conflict": { - "symfony/expression-language": "<2.6" + "symfony/yaml": "<3.2" }, "require-dev": { - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/yaml": "~3.2" }, "suggest": { "symfony/config": "", @@ -2048,11 +1885,11 @@ "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", "symfony/yaml": "" }, - "time": "2017-01-10T14:27:01+00:00", + "time": "2017-04-26T01:39:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2144,27 +1981,27 @@ }, { "name": "symfony/process", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231" + "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ebb3c2abe0940a703f08e0cbe373f62d97d40231", - "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231", + "url": "https://api.github.com/repos/symfony/process/zipball/999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0", + "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, - "time": "2017-01-02T20:30:24+00:00", + "time": "2017-04-12T14:13:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2195,17 +2032,17 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v0.2", - "version_normalized": "0.2.0.0", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "dc7e308e1dc2898a46776e2221a643cb08315453" + "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/dc7e308e1dc2898a46776e2221a643cb08315453", - "reference": "dc7e308e1dc2898a46776e2221a643cb08315453", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/66085f246d3893cbdbcec5f5ad15ac60546cf0de", + "reference": "66085f246d3893cbdbcec5f5ad15ac60546cf0de", "shasum": "" }, "require": { @@ -2217,10 +2054,16 @@ "symfony/phpunit-bridge": "~2.7|~3.0" }, "suggest": { + "psr/http-message-implementation": "To use the HttpFoundation factory", "zendframework/zend-diactoros": "To use the Zend Diactoros factory" }, - "time": "2015-05-29T17:57:12+00:00", + "time": "2016-09-14T18:37:20+00:00", "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -2251,42 +2094,53 @@ }, { "name": "symfony/serializer", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a" + "reference": "6eeae1ba82005b761a53b7b8cf960bbf40c95986" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/3a5337e3daaabb9ada73d60f3271adb6bfa56a1a", - "reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a", + "url": "https://api.github.com/repos/symfony/serializer/zipball/6eeae1ba82005b761a53b7b8cf960bbf40c95986", + "reference": "6eeae1ba82005b761a53b7b8cf960bbf40c95986", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/polyfill-php55": "~1.0" + "php": ">=5.5.9" + }, + "conflict": { + "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", + "symfony/property-info": "<3.1", + "symfony/yaml": "<3.1" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "symfony/config": "~2.2|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "phpdocumentor/reflection-docblock": "~3.0", + "symfony/cache": "~3.1", + "symfony/config": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/property-access": "~2.8|~3.0", + "symfony/property-info": "~3.1", + "symfony/yaml": "~3.1" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "To use the DataUriNormalizer.", "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", "symfony/yaml": "For using the default YAML mapping loader." }, - "time": "2017-01-02T20:30:24+00:00", + "time": "2017-05-01T14:55:58+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2317,42 +2171,42 @@ }, { "name": "symfony/translation", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b4ac4a393f6970cc157fba17be537380de396a86" + "reference": "f4a04d2df710f81515df576b2de06bdeee518b83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b4ac4a393f6970cc157fba17be537380de396a86", - "reference": "b4ac4a393f6970cc157fba17be537380de396a86", + "url": "https://api.github.com/repos/symfony/translation/zipball/f4a04d2df710f81515df576b2de06bdeee518b83", + "reference": "f4a04d2df710f81515df576b2de06bdeee518b83", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.8", - "symfony/intl": "~2.4|~3.0.0", - "symfony/yaml": "~2.2|~3.0.0" + "symfony/config": "~2.8|~3.0", + "symfony/intl": "^2.8.18|^3.2.5", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "psr/log": "To use logging capability in translator", "symfony/config": "", "symfony/yaml": "" }, - "time": "2017-01-02T20:30:24+00:00", + "time": "2017-04-12T14:13:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2383,51 +2237,55 @@ }, { "name": "symfony/validator", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811" + "reference": "98bf011bf1f3b69bece3b79e19633e9c51545b2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/3b1a3188efea75ec7c0419a2568b6e5f82031811", - "reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811", + "url": "https://api.github.com/repos/symfony/validator/zipball/98bf011bf1f3b69bece3b79e19633e9c51545b2b", + "reference": "98bf011bf1f3b69bece3b79e19633e9c51545b2b", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation": "~2.4|~3.0.0" + "symfony/translation": "~2.8|~3.0" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "egulias/email-validator": "~1.2,>=1.2.1", - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/intl": "~2.7.4|~2.8|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" + "egulias/email-validator": "^1.2.8|~2.0", + "symfony/cache": "~3.1", + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/intl": "^2.8.18|^3.2.5", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", "doctrine/cache": "For using the default cached annotation reader and metadata cache.", "egulias/email-validator": "Strict (RFC compliant) email validation", + "psr/cache-implementation": "For using the metadata cache.", "symfony/config": "", - "symfony/expression-language": "For using the 2.4 Expression validator", + "symfony/expression-language": "For using the Expression validator", "symfony/http-foundation": "", "symfony/intl": "", - "symfony/property-access": "For using the 2.4 Validator API", + "symfony/property-access": "For using the Expression validator", "symfony/yaml": "" }, - "time": "2017-01-12T19:24:25+00:00", + "time": "2017-04-12T14:13:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2458,27 +2316,33 @@ }, { "name": "symfony/yaml", - "version": "v2.8.16", - "version_normalized": "2.8.16.0", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2" + "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", - "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2", + "url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6", + "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, - "time": "2017-01-03T13:49:52+00:00", + "time": "2017-05-01T14:55:58+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } }, "installation-source": "dist", @@ -2509,31 +2373,32 @@ }, { "name": "twig/twig", - "version": "v1.24.0", - "version_normalized": "1.24.0.0", + "version": "v1.32.0", + "version_normalized": "1.32.0.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" + "reference": "9935b662e24d6e634da88901ab534cc12e8c728f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", - "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9935b662e24d6e634da88901ab534cc12e8c728f", + "reference": "9935b662e24d6e634da88901ab534cc12e8c728f", "shasum": "" }, "require": { "php": ">=5.2.7" }, "require-dev": { + "psr/container": "^1.0", "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" + "symfony/phpunit-bridge": "~3.2" }, - "time": "2016-01-25T21:22:18+00:00", + "time": "2017-02-27T00:07:03+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.24-dev" + "dev-master": "1.32-dev" } }, "installation-source": "dist", @@ -2572,36 +2437,38 @@ }, { "name": "zendframework/zend-diactoros", - "version": "1.1.3", - "version_normalized": "1.1.3.0", + "version": "1.4.1", + "version_normalized": "1.4.1.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181" + "reference": "424a840dc3bedcdeea510b42e056c77c2d6c4bef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/e2f5c12916c74da384058d0dfbc7fbc0b03d1181", - "reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/424a840dc3bedcdeea510b42e056c77c2d6c4bef", + "reference": "424a840dc3bedcdeea510b42e056c77c2d6c4bef", "shasum": "" }, "require": { - "php": ">=5.4", + "php": "^5.4 || ^7.0", "psr/http-message": "~1.0" }, "provide": { - "psr/http-message-implementation": "~1.0.0" + "psr/http-message-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "~4.6", - "squizlabs/php_codesniffer": "^2.3.1" + "ext-dom": "*", + "ext-libxml": "*", + "phpunit/phpunit": "^4.6 || ^5.5", + "zendframework/zend-coding-standard": "~1.0.0" }, - "time": "2015-08-10T20:04:20+00:00", + "time": "2017-08-17T21:21:00+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" + "dev-master": "1.4-dev", + "dev-develop": "1.5-dev" } }, "installation-source": "dist", @@ -2624,46 +2491,33 @@ }, { "name": "zendframework/zend-stdlib", - "version": "2.7.3", - "version_normalized": "2.7.3.0", + "version": "3.0.1", + "version_normalized": "3.0.1.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "8ac0c77ff567fcf49b58689ee3bfa7595be102bc" + "reference": "8bafa58574204bdff03c275d1d618aaa601588ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/8ac0c77ff567fcf49b58689ee3bfa7595be102bc", - "reference": "8ac0c77ff567fcf49b58689ee3bfa7595be102bc", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/8bafa58574204bdff03c275d1d618aaa601588ae", + "reference": "8bafa58574204bdff03c275d1d618aaa601588ae", "shasum": "" }, "require": { - "php": ">=5.5", - "zendframework/zend-hydrator": "~1.0" + "php": "^5.5 || ^7.0" }, "require-dev": { "athletic/athletic": "~0.1", "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-config": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-servicemanager": "~2.5" - }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-filter": "To support naming strategy hydrator usage", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" + "phpunit/phpunit": "~4.0" }, - "time": "2015-09-25T04:06:33+00:00", + "time": "2016-04-12T21:19:36+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "3.0-dev", + "dev-develop": "3.1-dev" } }, "installation-source": "dist", @@ -2682,87 +2536,29 @@ "zf2" ] }, - { - "name": "zendframework/zend-hydrator", - "version": "1.0.0", - "version_normalized": "1.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-hydrator.git", - "reference": "f3ed8b833355140350bbed98d8a7b8b66875903f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/f3ed8b833355140350bbed98d8a7b8b66875903f", - "reference": "f3ed8b833355140350bbed98d8a7b8b66875903f", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "zendframework/zend-stdlib": "^2.5.1" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.0@dev", - "zendframework/zend-eventmanager": "^2.5.1", - "zendframework/zend-filter": "^2.5.1", - "zendframework/zend-inputfilter": "^2.5.1", - "zendframework/zend-serializer": "^2.5.1", - "zendframework/zend-servicemanager": "^2.5.1" - }, - "suggest": { - "zendframework/zend-eventmanager": "^2.5.1, to support aggregate hydrator usage", - "zendframework/zend-filter": "^2.5.1, to support naming strategy hydrator usage", - "zendframework/zend-serializer": "^2.5.1, to use the SerializableStrategy", - "zendframework/zend-servicemanager": "^2.5.1, to support hydrator plugin manager usage" - }, - "time": "2015-09-17T14:06:43+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Zend\\Hydrator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-hydrator", - "keywords": [ - "hydrator", - "zf2" - ] - }, { "name": "zendframework/zend-escaper", - "version": "2.5.1", - "version_normalized": "2.5.1.0", + "version": "2.5.2", + "version_normalized": "2.5.2.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73" + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73", - "reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": ">=5.5" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", "phpunit/phpunit": "~4.0" }, - "time": "2015-06-03T14:05:37+00:00", + "time": "2016-06-30T19:48:38+00:00", "type": "library", "extra": { "branch-alias": { @@ -2788,46 +2584,48 @@ }, { "name": "zendframework/zend-feed", - "version": "2.5.2", - "version_normalized": "2.5.2.0", + "version": "2.7.0", + "version_normalized": "2.7.0.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-feed.git", - "reference": "0661345b82b51428619e05d3aadd3de65b57fa54" + "reference": "12b328d382aa5200f1de53d4147033b885776b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-feed/zipball/0661345b82b51428619e05d3aadd3de65b57fa54", - "reference": "0661345b82b51428619e05d3aadd3de65b57fa54", + "url": "https://api.github.com/repos/zendframework/zend-feed/zipball/12b328d382aa5200f1de53d4147033b885776b67", + "reference": "12b328d382aa5200f1de53d4147033b885776b67", "shasum": "" }, "require": { - "php": ">=5.5", - "zendframework/zend-escaper": "~2.5", - "zendframework/zend-stdlib": "~2.5" + "php": "^5.5 || ^7.0", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", "phpunit/phpunit": "~4.0", - "zendframework/zend-cache": "~2.5", - "zendframework/zend-db": "~2.5", - "zendframework/zend-http": "~2.5", - "zendframework/zend-servicemanager": "~2.5", - "zendframework/zend-validator": "~2.5" + "psr/http-message": "^1.0", + "zendframework/zend-cache": "^2.5", + "zendframework/zend-db": "^2.5", + "zendframework/zend-http": "^2.5", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-validator": "^2.5" }, "suggest": { - "zendframework/zend-cache": "Zend\\Cache component", - "zendframework/zend-db": "Zend\\Db component", + "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator", + "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests", + "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub", "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations", - "zendframework/zend-validator": "Zend\\Validator component" + "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations", + "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent" }, - "time": "2015-08-04T21:39:18+00:00", + "time": "2016-02-11T18:54:29+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" } }, "installation-source": "dist", diff --git a/vendor/composer/installers/.travis.yml b/vendor/composer/installers/.travis.yml index 81ca8e10..931191dd 100644 --- a/vendor/composer/installers/.travis.yml +++ b/vendor/composer/installers/.travis.yml @@ -1,14 +1,32 @@ language: php +sudo: false + +dist: trusty + +git: + depth: 5 + php: - - 5.3 - 5.4 - 5.5 - 5.6 + - 7.0 + - 7.1 - hhvm + - nightly + +matrix: + include: + - dist: precise + php: 5.3 + fast_finish: true + allow_failures: + - php: nightly before_script: - - curl -s http://getcomposer.org/installer | php -- --quiet - - php composer.phar install --dev + - composer self-update + - composer install -script: phpunit +script: + - composer test diff --git a/vendor/composer/installers/CHANGELOG.md b/vendor/composer/installers/CHANGELOG.md new file mode 100644 index 00000000..357a7ded --- /dev/null +++ b/vendor/composer/installers/CHANGELOG.md @@ -0,0 +1,69 @@ +# Change Log + +## [Unreleased] + +## v1.4.0 - 2017-08-09 +### Added +* Installer for eZ Platform. +* Installer for UserFrosting. +* Installer for Osclass. +* Installer for Lan Management System. + +### Changed +* Added vendor name to package path for Lavalite. + +## v1.3.0 - 2017-04-24 +### Added +* Kanboard plugins installer. +* Porto-SAP installer. +* Add `core` to concrete5 installer. +* Support Moodle "search" plugin type. +* SyDES installer. +* iTop installer. +* Lavalite installer. +* Module type for Eliasis. +* Vgmcp installer. +* OntoWiki installer. +* The requirements for contributing (CONTRIBUTING.md). + +## v1.2.0 - 2016-08-13 +### Added +* Installer for Attogram. +* Installer for Cockpit. +* Installer for Plentymarkets. +* Installer for ReIndex. +* Installer for Vanilla. +* Installer for YAWIK. +* Added missing environments for new Shopware (5.2) Plugin System. + +## v1.1.0 - 2016-07-05 +### Added +* Installer for ReIndex. +* Installer for RadPHP. +* Installer for Decibel. +* Installer for Phifty. +* Installer for ExpressionEngine. + +### Changed +* New paths for new Bitrix CMS. Old paths is deprecated. + +### Deprecated +* Old paths in Bitrix CMS Installer is deprecated. + +## v1.0.25 - 2016-04-13 +### Removed +* Revert TYPO3 installer deletion. + +## v1.0.24 - 2016-04-05 +### Added +* Installer for ImageCMS. +* Installer for Mautic. +* New types in the Kirby installer: `kirby-plugin` and `kirby-field`. +* New types in the Drupal installer: `custom-theme` and `custom-module`. + +### Changed +* Switch to PSR-4. +* Update Bitrix Installer: configuration for setting custom path to directory with kernel. + +### Removed +* Remove TYPO3 Extension installers. diff --git a/vendor/composer/installers/CONTRIBUTING.md b/vendor/composer/installers/CONTRIBUTING.md new file mode 100644 index 00000000..1b1998e0 --- /dev/null +++ b/vendor/composer/installers/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing + +If you would like to help, please take a look at the list of +[issues](https://github.com/composer/installers/issues). + +## Pull requests + +* [Fork and clone](https://help.github.com/articles/fork-a-repo). +* Run the command `php composer.phar install` to install the dependencies. + This will also install the dev dependencies. See [Composer](https://getcomposer.org/doc/03-cli.md#install). +* Use the command `phpunit` to run the tests. See [PHPUnit](http://phpunit.de). +* Create a branch, commit, push and send us a + [pull request](https://help.github.com/articles/using-pull-requests). + +To ensure a consistent code base, you should make sure the code follows the +coding standards [PSR-1](http://www.php-fig.org/psr/psr-1/) and +[PSR-2](http://www.php-fig.org/psr/psr-2/). + +### Create a new Installer + +* Create class extends `Composer\Installers\BaseInstaller` with your Installer. +* Create unit tests as a separate class or as part of a `Composer\Installers\Test\InstallerTest`. +* Add information about your Installer in `README.md` in section "Current Supported Package Types". +* Run the tests. diff --git a/vendor/composer/installers/README.md b/vendor/composer/installers/README.md index b3317719..b77dbe38 100644 --- a/vendor/composer/installers/README.md +++ b/vendor/composer/installers/README.md @@ -6,11 +6,11 @@ This is for PHP package authors to require in their `composer.json`. It will install their package to the correct location based on the specified package type. -The goal of `installers` is to be a simple package type to install path map. +The goal of Installers is to be a simple package type to install path map. Users can also customize the install path per package and package authors can modify the package name upon installing. -`installers` isn't intended on replacing all custom installers. If your +Installers isn't intended on replacing all custom installers. If your package requires special installation handling then by all means, create a custom installer to handle it. @@ -25,7 +25,7 @@ is not needed to install packages with these frameworks: * Yii * Yii2 -**Current Supported Package Types**: +## Current Supported Package Types > Stable types are marked as **bold**, this means that installation paths > for those type will not be changed. Any adjustment for those types would @@ -35,56 +35,83 @@ is not needed to install packages with these frameworks: | --------- | ----- | Aimeos | `aimeos-extension` | Asgard | `asgard-module`
    `asgard-theme` +| Attogram | `attogram-module` | AGL | `agl-module` +| Bonefish | `bonefish-package` | AnnotateCms | `annotatecms-module`
    `annotatecms-component`
    `annotatecms-service` -| Bitrix | `bitrix-module`
    `bitrix-component`
    `bitrix-theme` +| Bitrix | `bitrix-module` (deprecated)
    `bitrix-component` (deprecated)
    `bitrix-theme` (deprecated)

    `bitrix-d7-module`
    `bitrix-d7-component`
    `bitrix-d7-template` | CakePHP 2+ | **`cakephp-plugin`** | Chef | `chef-cookbook`
    `chef-role` | CCFramework | `ccframework-ship`
    `ccframework-theme` +| Cockpit | `cockpit-module` | CodeIgniter | `codeigniter-library`
    `codeigniter-third-party`
    `codeigniter-module` -| concrete5 | `concrete5-block`
    `concrete5-package`
    `concrete5-theme`
    `concrete5-update` +| concrete5 | `concrete5-core`
    `concrete5-package`
    `concrete5-theme`
    `concrete5-block`
    `concrete5-update` | Craft | `craft-plugin` | Croogo | `croogo-plugin`
    `croogo-theme` +| Decibel | `decibel-app` | DokuWiki | `dokuwiki-plugin`
    `dokuwiki-template` | Dolibarr | `dolibarr-module` -| Drupal | `drupal-module`
    `drupal-theme`

    `drupal-library`
    `drupal-profile`
    `drupal-drush` +| Drupal | `drupal-core`
    `drupal-module`
    `drupal-theme`

    `drupal-library`
    `drupal-profile`
    `drupal-drush` | Elgg | `elgg-plugin` +| Eliasis | `eliasis-module` +| ExpressionEngine 3 | `ee3-addon`
    `ee3-theme` +| eZ Platform | `ezplatform-assets`
    `ezplatform-meta-assets` | FuelPHP v1.x | `fuel-module`
    `fuel-package`
    `fuel-theme` | FuelPHP v2.x | `fuelphp-component` | Grav | `grav-plugin`
    `grav-theme` | Hurad | `hurad-plugin`
    `hurad-theme` +| ImageCMS | `imagecms-template`
    `imagecms-module`
    `imagecms-library` +| iTop | `itop-extension` | Joomla | `joomla-component`
    `joomla-module`
    `joomla-template`
    `joomla-plugin`
    `joomla-library` -| Kirby | **`kirby-plugin`** +| Kanboard | `kanboard-plugin` +| Kirby | **`kirby-plugin`**
    `kirby-field`
    `kirby-tag` +| KodiCMS | `kodicms-plugin`
    `kodicms-media` | Kohana | **`kohana-module`** +| Lan Management System | `lms-plugin`
    `lms-template`
    `lms-document-template`
    `lms-userpanel-module` | Laravel | `laravel-library` +| Lavalite | `lavalite-theme`
    `lavalite-package` | Lithium | **`lithium-library`
    `lithium-source`** | Magento | `magento-library`
    `magento-skin`
    `magento-theme` | Mako | `mako-package` +| Mautic | `mautic-plugin`
    `mautic-theme` +| Maya | `maya-module` | MODX Evo | `modxevo-snippet`
    `modxevo-plugin`
    `modxevo-module`
    `modxevo-template`
    `modxevo-lib` | MediaWiki | `mediawiki-extension` | October | **`october-module`
    `october-plugin`
    `october-theme`** +| OntoWiki | `ontowiki-extension`
    `ontowiki-theme`
    `ontowiki-translation` | OXID | `oxid-module`
    `oxid-theme`
    `oxid-out` +| Osclass | `osclass-plugin`
    `osclass-theme`
    `osclass-language` | MODULEWork | `modulework-module` | Moodle | `moodle-*` (Please [check source](https://raw.githubusercontent.com/composer/installers/master/src/Composer/Installers/MoodleInstaller.php) for all supported types) | Piwik | `piwik-plugin` | phpBB | `phpbb-extension`
    `phpbb-style`
    `phpbb-language` | Pimcore | `pimcore-plugin` +| Plentymarkets | `plentymarkets-plugin` | PPI | **`ppi-module`** | Puppet | `puppet-module` +| Porto | `porto-container` +| RadPHP | `radphp-bundle` | REDAXO | `redaxo-addon` +| ReIndex | **`reindex-plugin`**
    **`reindex-theme`** | Roundcube | `roundcube-plugin` -| shopware | `shopware-backend-plugin`
    `shopware-core-plugin`
    `shopware-frontend-plugin`
    `shopware-theme` +| shopware | `shopware-backend-plugin`
    `shopware-core-plugin`
    `shopware-frontend-plugin`
    `shopware-theme`
    `shopware-plugin`
    `shopware-frontend-theme` | SilverStripe | `silverstripe-module`
    `silverstripe-theme` | SMF | `smf-module`
    `smf-theme` +| SyDES | `sydes-module`
    `sydes-theme` | symfony1 | **`symfony1-plugin`** | Tusk | `tusk-task`
    `tusk-command`
    `tusk-asset` | TYPO3 Flow | `typo3-flow-package`
    `typo3-flow-framework`
    `typo3-flow-plugin`
    `typo3-flow-site`
    `typo3-flow-boilerplate`
    `typo3-flow-build` -| TYPO3 CMS | `typo3-cms-extension` +| TYPO3 CMS | `typo3-cms-extension` (Deprecated in this package, use the [TYPO3 CMS Installers](https://packagist.org/packages/typo3/cms-composer-installers) instead) +| UserFrosting | `userfrosting-sprinkle` +| Vanilla | `vanilla-plugin`
    `vanilla-theme` +| Vgmcp | `vgmcp-bundle`
    `vgmcp-theme` | Wolf CMS | `wolfcms-plugin` | WordPress | `wordpress-plugin`
    `wordpress-theme`

    `wordpress-muplugin` +| YAWIK | `yawik-module` | Zend | `zend-library`
    `zend-extra`
    `zend-module` | Zikula | `zikula-module`
    `zikula-theme` | Prestashop | `prestashop-module`
    `prestashop-theme` +| Phifty | `phifty-bundle`
    `phifty-framework`
    `phifty-library` ## Example `composer.json` File @@ -135,7 +162,20 @@ A package type can have a custom installation path with a `type:` prefix. } ``` -This would use your custom path for each of the listed packages. The available +You can also have the same vendor packages with a custom installation path by +using the `vendor:` prefix. + +``` json +{ + "extra": { + "installer-paths": { + "your/custom/path/{$name}/": ["vendor:my_organization"] + } + } +} +``` + +These would use your custom path for each of the listed packages. The available variables to use in your paths are: `{$name}`, `{$vendor}`, `{$type}`. ## Custom Install Names @@ -163,29 +203,16 @@ will allow this: Please note the name entered into `installer-name` will be the final and will not be inflected. -## Contribute! - -* [Fork and clone](https://help.github.com/articles/fork-a-repo). -* Run the command `php composer.phar install --dev` to install the dev - dependencies. See [Composer](https://github.com/composer/composer#installation--usage). -* Use the command `phpunit` to run the tests. See [PHPUnit](http://phpunit.de). -* Create a branch, commit, push and send us a - [pull request](https://help.github.com/articles/using-pull-requests). +## Should we allow dynamic package types or paths? No. -To ensure a consistent code base, you should make sure the code follows the -[Coding Standards](http://symfony.com/doc/2.0/contributing/code/standards.html) -which we borrowed from Symfony. - -If you would like to help, please take a look at the list of -[issues](https://github.com/composer/installers/issues). - -### Should we allow dynamic package types or paths? No. What are they? The ability for a package author to determine where a package will be installed either through setting the path directly in their `composer.json` or through a dynamic package type: `"type": "framework-install-here"`. It has been proposed many times. Even implemented once early on and then -removed. `installers` won't do this because it would allow a single package +removed. Installers won't do this because it would allow a single package author to wipe out entire folders without the user's consent. That user would then come here to yell at us. + +Anyone still wanting this capability should consider requiring https://github.com/oomphinc/composer-installers-extender. diff --git a/vendor/composer/installers/_config.yml b/vendor/composer/installers/_config.yml new file mode 100644 index 00000000..c4192631 --- /dev/null +++ b/vendor/composer/installers/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/vendor/composer/installers/composer.json b/vendor/composer/installers/composer.json index 6ee931ee..0a7477d1 100644 --- a/vendor/composer/installers/composer.json +++ b/vendor/composer/installers/composer.json @@ -1,6 +1,6 @@ { "name": "composer/installers", - "type": "composer-installer", + "type": "composer-plugin", "license": "MIT", "description": "A multi-framework Composer library installer", "keywords": [ @@ -8,9 +8,11 @@ "Aimeos", "AGL", "AnnotateCms", + "Attogram", "Bitrix", "CakePHP", "Chef", + "Cockpit", "CodeIgniter", "concrete5", "Craft", @@ -19,37 +21,54 @@ "Dolibarr", "Drupal", "Elgg", + "Eliasis", + "ExpressionEngine", + "eZ Platform", "FuelPHP", "Grav", "Hurad", + "ImageCMS", + "iTop", "Joomla", + "Kanboard", "Kohana", + "Lan Management System", "Laravel", + "Lavalite", "Lithium", "Magento", "Mako", + "Mautic", + "Maya", "MODX Evo", "MediaWiki", "OXID", + "osclass", "MODULEWork", "Moodle", "Piwik", "phpBB", + "Plentymarkets", "PPI", "Puppet", + "Porto", + "RadPHP", + "ReIndex", "Roundcube", "shopware", "SilverStripe", "SMF", + "SyDES", "symfony", "Thelia", "TYPO3", "WolfCMS", "WordPress", + "YAWIK", "Zend", "Zikula" ], - "homepage": "http://composer.github.com/installers/", + "homepage": "https://composer.github.io/installers/", "authors": [ { "name": "Kyle Robinson Young", @@ -58,10 +77,10 @@ } ], "autoload": { - "psr-0": { "Composer\\Installers\\": "src/" } + "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" } }, "extra": { - "class": "Composer\\Installers\\Installer", + "class": "Composer\\Installers\\Plugin", "branch-alias": { "dev-master": "1.0-dev" } @@ -70,8 +89,14 @@ "shama/baton": "*", "roundcube/plugin-installer": "*" }, + "require": { + "composer-plugin-api": "^1.0" + }, "require-dev": { "composer/composer": "1.0.*@dev", "phpunit/phpunit": "4.1.*" + }, + "scripts": { + "test": "phpunit" } } diff --git a/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php index 995ee2b4..22dad1b9 100644 --- a/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php @@ -31,14 +31,18 @@ public function inflectPackageVars($vars) protected function inflectPluginVars($vars) { - $vars['name'] = ucfirst(preg_replace('/-module/', '', $vars['name'])); + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } protected function inflectThemeVars($vars) { - $vars['name'] = ucfirst(preg_replace('/-theme$/', '', $vars['name'])); + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } diff --git a/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php new file mode 100644 index 00000000..d62fd8fd --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php index cc27d3e2..7082bf2c 100644 --- a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php @@ -1,6 +1,7 @@ composer = $composer; $this->package = $package; + $this->io = $io; } /** @@ -51,7 +55,7 @@ public function getInstallPath(PackageInterface $package, $frameworkType = '') if ($this->composer->getPackage()) { $extra = $this->composer->getPackage()->getExtra(); if (!empty($extra['installer-paths'])) { - $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type); + $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); if ($customPath !== false) { return $this->templatePath($customPath, $availableVars); } @@ -116,12 +120,13 @@ protected function templatePath($path, array $vars = array()) * @param array $paths * @param string $name * @param string $type + * @param string $vendor = NULL * @return string */ - protected function mapCustomInstallPaths(array $paths, $name, $type) + protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL) { foreach ($paths as $path => $names) { - if (in_array($name, $names) || in_array('type:' . $type, $names)) { + if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) { return $path; } } diff --git a/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php index 48a8367a..e80cd1e1 100644 --- a/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php @@ -1,11 +1,126 @@ .`. + * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`. + * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`. + * + * You can set custom path to directory with Bitrix kernel in `composer.json`: + * + * ```json + * { + * "extra": { + * "bitrix-dir": "s1/bitrix" + * } + * } + * ``` + * + * @author Nik Samokhvalov + * @author Denis Kulichkin + */ class BitrixInstaller extends BaseInstaller { protected $locations = array( - 'module' => 'local/modules/{$name}/', - 'component' => 'local/components/{$name}/', - 'theme' => 'local/templates/{$name}/' + 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/', + 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/', + 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/', ); + + /** + * @var array Storage for informations about duplicates at all the time of installation packages. + */ + private static $checkedDuplicates = array(); + + /** + * {@inheritdoc} + */ + public function inflectPackageVars($vars) + { + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + + if (isset($extra['bitrix-dir'])) { + $vars['bitrix_dir'] = $extra['bitrix-dir']; + } + } + + if (!isset($vars['bitrix_dir'])) { + $vars['bitrix_dir'] = 'bitrix'; + } + + return parent::inflectPackageVars($vars); + } + + /** + * {@inheritdoc} + */ + protected function templatePath($path, array $vars = array()) + { + $templatePath = parent::templatePath($path, $vars); + $this->checkDuplicates($templatePath, $vars); + + return $templatePath; + } + + /** + * Duplicates search packages. + * + * @param string $path + * @param array $vars + */ + protected function checkDuplicates($path, array $vars = array()) + { + $packageType = substr($vars['type'], strlen('bitrix') + 1); + $localDir = explode('/', $vars['bitrix_dir']); + array_pop($localDir); + $localDir[] = 'local'; + $localDir = implode('/', $localDir); + + $oldPath = str_replace( + array('{$bitrix_dir}', '{$name}'), + array($localDir, $vars['name']), + $this->locations[$packageType] + ); + + if (in_array($oldPath, static::$checkedDuplicates)) { + return; + } + + if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) { + + $this->io->writeError(' Duplication of packages:'); + $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ''); + + while (true) { + switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) { + case 'y': + $fs = new Filesystem(); + $fs->removeDirectory($oldPath); + break 2; + + case 'n': + break 2; + + case '?': + default: + $this->io->writeError(array( + ' y - delete package ' . $oldPath . ' and to continue with the installation', + ' n - don\'t delete and to continue with the installation', + )); + $this->io->writeError(' ? - print help'); + break; + } + } + } + + static::$checkedDuplicates[] = $oldPath; + } } diff --git a/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php new file mode 100644 index 00000000..da3aad2a --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php @@ -0,0 +1,9 @@ + 'Packages/{$vendor}/{$name}/' + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php index cbeb60b8..96e987a2 100644 --- a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -3,8 +3,6 @@ use Composer\DependencyResolver\Pool; use Composer\Package\PackageInterface; -use Composer\Package\LinkConstraint\MultiConstraint; -use Composer\Package\LinkConstraint\VersionConstraint; class CakePHPInstaller extends BaseInstaller { @@ -52,24 +50,31 @@ public function getLocations() */ protected function matchesCakeVersion($matcher, $version) { + if (class_exists('Composer\Semver\Constraint\MultiConstraint')) { + $multiClass = 'Composer\Semver\Constraint\MultiConstraint'; + $constraintClass = 'Composer\Semver\Constraint\Constraint'; + } else { + $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint'; + $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint'; + } + $repositoryManager = $this->composer->getRepositoryManager(); if ($repositoryManager) { $repos = $repositoryManager->getLocalRepository(); if (!$repos) { return false; } - $cake3 = new MultiConstraint(array( - new VersionConstraint($matcher, $version), - new VersionConstraint('!=', '9999999-dev'), + $cake3 = new $multiClass(array( + new $constraintClass($matcher, $version), + new $constraintClass('!=', '9999999-dev'), )); $pool = new Pool('dev'); $pool->addRepository($repos); $packages = $pool->whatProvides('cakephp/cakephp'); foreach ($packages as $package) { - $installed = new VersionConstraint('=', $package->getVersion()); + $installed = new $constraintClass('=', $package->getVersion()); if ($cake3->matches($installed)) { return true; - break; } } } diff --git a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php new file mode 100644 index 00000000..c7816dfc --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php @@ -0,0 +1,34 @@ + 'cockpit/modules/addons/{$name}/', + ); + + /** + * Format module name. + * + * Strip `module-` prefix from package name. + * + * @param array @vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'cockpit-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name'])); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php index 4d398a44..5c01bafd 100644 --- a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php @@ -4,9 +4,10 @@ class Concrete5Installer extends BaseInstaller { protected $locations = array( - 'block' => 'blocks/{$name}/', + 'core' => 'concrete/', + 'block' => 'application/blocks/{$name}/', 'package' => 'packages/{$name}/', - 'theme' => 'themes/{$name}/', + 'theme' => 'application/themes/{$name}/', 'update' => 'updates/{$name}/', ); } diff --git a/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php index dc3be8d1..d37a77ae 100644 --- a/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php @@ -1,9 +1,35 @@ 'craft/plugins/{$name}/', ); + + /** + * Strip `craft-` prefix and/or `-plugin` suffix from package names + * + * @param array $vars + * + * @return array + */ + final public function inflectPackageVars($vars) + { + return $this->inflectPluginVars($vars); + } + + private function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']); + $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']); + + return $vars; + } } diff --git a/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php new file mode 100644 index 00000000..f4837a6c --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php @@ -0,0 +1,10 @@ + 'app/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php index 17941314..a41ee2e1 100644 --- a/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php @@ -10,5 +10,7 @@ class DrupalInstaller extends BaseInstaller 'library' => 'libraries/{$name}/', 'profile' => 'profiles/{$name}/', 'drush' => 'drush/{$name}/', + 'custom-theme' => 'themes/custom/{$name}/', + 'custom-module' => 'modules/custom/{$name}', ); } diff --git a/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php new file mode 100644 index 00000000..2be4e3cb --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/' + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php new file mode 100644 index 00000000..d5321a8c --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php @@ -0,0 +1,29 @@ + 'system/expressionengine/third_party/{$name}/', + 'theme' => 'themes/third_party/{$name}/', + ); + + private $ee3Locations = array( + 'addon' => 'system/user/addons/{$name}/', + 'theme' => 'themes/user/{$name}/', + ); + + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + + $version = "{$frameworkType}Locations"; + $this->locations = $this->$version; + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php new file mode 100644 index 00000000..f30ebcc7 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php @@ -0,0 +1,10 @@ + 'web/assets/ezplatform/', + 'assets' => 'web/assets/ezplatform/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php new file mode 100644 index 00000000..5e2142ea --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php @@ -0,0 +1,11 @@ + 'templates/{$name}/', + 'module' => 'application/modules/{$name}/', + 'library' => 'application/libraries/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/Installer.php b/vendor/composer/installers/src/Composer/Installers/Installer.php index 63ba64ce..8356b8c9 100644 --- a/vendor/composer/installers/src/Composer/Installers/Installer.php +++ b/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -1,6 +1,7 @@ 'AimeosInstaller', 'asgard' => 'AsgardInstaller', + 'attogram' => 'AttogramInstaller', 'agl' => 'AglInstaller', 'annotatecms' => 'AnnotateCmsInstaller', 'bitrix' => 'BitrixInstaller', + 'bonefish' => 'BonefishInstaller', 'cakephp' => 'CakePHPInstaller', 'chef' => 'ChefInstaller', 'ccframework' => 'ClanCatsFrameworkInstaller', + 'cockpit' => 'CockpitInstaller', 'codeigniter' => 'CodeIgniterInstaller', 'concrete5' => 'Concrete5Installer', 'craft' => 'CraftInstaller', 'croogo' => 'CroogoInstaller', 'dokuwiki' => 'DokuWikiInstaller', 'dolibarr' => 'DolibarrInstaller', + 'decibel' => 'DecibelInstaller', 'drupal' => 'DrupalInstaller', 'elgg' => 'ElggInstaller', + 'eliasis' => 'EliasisInstaller', + 'ee3' => 'ExpressionEngineInstaller', + 'ee2' => 'ExpressionEngineInstaller', + 'ezplatform' => 'EzPlatformInstaller', 'fuel' => 'FuelInstaller', 'fuelphp' => 'FuelphpInstaller', 'grav' => 'GravInstaller', 'hurad' => 'HuradInstaller', + 'imagecms' => 'ImageCMSInstaller', + 'itop' => 'ItopInstaller', 'joomla' => 'JoomlaInstaller', + 'kanboard' => 'KanboardInstaller', 'kirby' => 'KirbyInstaller', + 'kodicms' => 'KodiCMSInstaller', 'kohana' => 'KohanaInstaller', + 'lms' => 'LanManagementSystemInstaller', 'laravel' => 'LaravelInstaller', + 'lavalite' => 'LavaLiteInstaller', 'lithium' => 'LithiumInstaller', 'magento' => 'MagentoInstaller', 'mako' => 'MakoInstaller', + 'maya' => 'MayaInstaller', + 'mautic' => 'MauticInstaller', 'mediawiki' => 'MediaWikiInstaller', - 'microweber' => 'MicroweberInstaller', + 'microweber' => 'MicroweberInstaller', 'modulework' => 'MODULEWorkInstaller', 'modxevo' => 'MODXEvoInstaller', 'moodle' => 'MoodleInstaller', 'october' => 'OctoberInstaller', + 'ontowiki' => 'OntoWikiInstaller', 'oxid' => 'OxidInstaller', + 'osclass' => 'OsclassInstaller', 'phpbb' => 'PhpBBInstaller', 'pimcore' => 'PimcoreInstaller', 'piwik' => 'PiwikInstaller', + 'plentymarkets'=> 'PlentymarketsInstaller', 'ppi' => 'PPIInstaller', 'puppet' => 'PuppetInstaller', + 'radphp' => 'RadPHPInstaller', + 'phifty' => 'PhiftyInstaller', + 'porto' => 'PortoInstaller', 'redaxo' => 'RedaxoInstaller', + 'reindex' => 'ReIndexInstaller', 'roundcube' => 'RoundcubeInstaller', 'shopware' => 'ShopwareInstaller', 'silverstripe' => 'SilverStripeInstaller', 'smf' => 'SMFInstaller', + 'sydes' => 'SyDESInstaller', 'symfony1' => 'Symfony1Installer', 'thelia' => 'TheliaInstaller', 'tusk' => 'TuskInstaller', 'typo3-cms' => 'TYPO3CmsInstaller', 'typo3-flow' => 'TYPO3FlowInstaller', + 'userfrosting' => 'UserFrostingInstaller', + 'vanilla' => 'VanillaInstaller', 'whmcs' => 'WHMCSInstaller', 'wolfcms' => 'WolfCMSInstaller', 'wordpress' => 'WordPressInstaller', + 'yawik' => 'YawikInstaller', 'zend' => 'ZendInstaller', 'zikula' => 'ZikulaInstaller', - 'prestashop' => 'PrestashopInstaller', + 'prestashop' => 'PrestashopInstaller' ); /** @@ -85,7 +113,7 @@ public function getInstallPath(PackageInterface $package) } $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; - $installer = new $class($package, $this->composer); + $installer = new $class($package, $this->composer, $this->getIO()); return $installer->getInstallPath($package, $frameworkType); } @@ -153,11 +181,21 @@ protected function getLocationPattern($frameworkType) if (!empty($this->supportedTypes[$frameworkType])) { $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; /** @var BaseInstaller $framework */ - $framework = new $frameworkClass(null, $this->composer); + $framework = new $frameworkClass(null, $this->composer, $this->getIO()); $locations = array_keys($framework->getLocations()); $pattern = $locations ? '(' . implode('|', $locations) . ')' : false; } return $pattern ? : '(\w+)'; } + + /** + * Get I/O object + * + * @return IOInterface + */ + private function getIO() + { + return $this->io; + } } diff --git a/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php new file mode 100644 index 00000000..c6c1b337 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php @@ -0,0 +1,9 @@ + 'extensions/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php new file mode 100644 index 00000000..9cb7b8cd --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php @@ -0,0 +1,18 @@ + 'plugins/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php index ae7ba8a4..36b2f84a 100644 --- a/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php @@ -5,5 +5,7 @@ class KirbyInstaller extends BaseInstaller { protected $locations = array( 'plugin' => 'site/plugins/{$name}/', + 'field' => 'site/fields/{$name}/', + 'tag' => 'site/tags/{$name}/' ); } diff --git a/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php new file mode 100644 index 00000000..7143e232 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php @@ -0,0 +1,10 @@ + 'cms/plugins/{$name}/', + 'media' => 'cms/media/vendor/{$name}/' + ); +} \ No newline at end of file diff --git a/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php new file mode 100644 index 00000000..903143a5 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php @@ -0,0 +1,27 @@ + 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + 'document-template' => 'documents/templates/{$name}/', + 'userpanel-module' => 'userpanel/modules/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + +} diff --git a/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php new file mode 100644 index 00000000..412c0b5c --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php @@ -0,0 +1,10 @@ + 'packages/{$vendor}/{$name}/', + 'theme' => 'public/themes/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php new file mode 100644 index 00000000..3e1ce2b2 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php @@ -0,0 +1,25 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name of mautic-plugins to CamelCase + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'mautic-plugin') { + $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, ucfirst($vars['name'])); + } + + return $vars; + } + +} diff --git a/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php new file mode 100644 index 00000000..30a91676 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php @@ -0,0 +1,33 @@ + 'modules/{$name}/', + ); + + /** + * Format package name. + * + * For package type maya-module, cut off a trailing '-module' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'maya-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php index 04be73c2..a89c82f7 100644 --- a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -6,6 +6,7 @@ class MoodleInstaller extends BaseInstaller protected $locations = array( 'mod' => 'mod/{$name}/', 'admin_report' => 'admin/report/{$name}/', + 'atto' => 'lib/editor/atto/plugins/{$name}/', 'tool' => 'admin/tool/{$name}/', 'assignment' => 'mod/assignment/type/{$name}/', 'assignsubmission' => 'mod/assign/submission/{$name}/', @@ -13,6 +14,9 @@ class MoodleInstaller extends BaseInstaller 'auth' => 'auth/{$name}/', 'availability' => 'availability/condition/{$name}/', 'block' => 'blocks/{$name}/', + 'booktool' => 'mod/book/tool/{$name}/', + 'cachestore' => 'cache/stores/{$name}/', + 'cachelock' => 'cache/locks/{$name}/', 'calendartype' => 'calendar/type/{$name}/', 'format' => 'course/format/{$name}/', 'coursereport' => 'course/report/{$name}/', @@ -26,7 +30,11 @@ class MoodleInstaller extends BaseInstaller 'gradereport' => 'grade/report/{$name}/', 'gradingform' => 'grade/grading/form/{$name}/', 'local' => 'local/{$name}/', + 'logstore' => 'admin/tool/log/store/{$name}/', + 'ltisource' => 'mod/lti/source/{$name}/', + 'ltiservice' => 'mod/lti/service/{$name}/', 'message' => 'message/output/{$name}/', + 'mnetservice' => 'mnet/service/{$name}/', 'plagiarism' => 'plagiarism/{$name}/', 'portfolio' => 'portfolio/{$name}/', 'qbehaviour' => 'question/behaviour/{$name}/', @@ -37,7 +45,9 @@ class MoodleInstaller extends BaseInstaller 'report' => 'report/{$name}/', 'repository' => 'repository/{$name}/', 'scormreport' => 'mod/scorm/report/{$name}/', + 'search' => 'search/engine/{$name}/', 'theme' => 'theme/{$name}/', + 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/', 'profilefield' => 'user/profile/field/{$name}/', 'webservice' => 'webservice/{$name}/', 'workshopallocation' => 'mod/workshop/allocation/{$name}/', diff --git a/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php new file mode 100644 index 00000000..5dd3438d --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php @@ -0,0 +1,24 @@ + 'extensions/{$name}/', + 'theme' => 'extensions/themes/{$name}/', + 'translation' => 'extensions/translations/{$name}/', + ); + + /** + * Format package name to lower case and remove ".ontowiki" suffix + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']); + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = preg_replace('/-translation$/', '', $vars['name']); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php new file mode 100644 index 00000000..3ca7954c --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php @@ -0,0 +1,14 @@ + 'oc-content/plugins/{$name}/', + 'theme' => 'oc-content/themes/{$name}/', + 'language' => 'oc-content/languages/{$name}/', + ); + +} diff --git a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php index 22fb56aa..49940ff6 100644 --- a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php @@ -1,11 +1,59 @@ .+)\/.+/'; + protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'application/views/{$name}/', 'out' => 'out/{$name}/', ); + + /** + * getInstallPath + * + * @param PackageInterface $package + * @param string $frameworkType + * @return void + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $installPath = parent::getInstallPath($package, $frameworkType); + $type = $this->package->getType(); + if ($type === 'oxid-module') { + $this->prepareVendorDirectory($installPath); + } + return $installPath; + } + + /** + * prepareVendorDirectory + * + * Makes sure there is a vendormetadata.php file inside + * the vendor folder if there is a vendor folder. + * + * @param string $installPath + * @return void + */ + protected function prepareVendorDirectory($installPath) + { + $matches = ''; + $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); + if (!$hasVendorDirectory) { + return; + } + + $vendorDirectory = $matches['vendor']; + $vendorPath = getcwd() . '/modules/' . $vendorDirectory; + if (!file_exists($vendorPath)) { + mkdir($vendorPath, 0755, true); + } + + $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; + touch($vendorMetaDataPath); + } } diff --git a/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php new file mode 100644 index 00000000..4e59a8a7 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php @@ -0,0 +1,11 @@ + 'bundles/{$name}/', + 'library' => 'libraries/{$name}/', + 'framework' => 'frameworks/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php new file mode 100644 index 00000000..903e55f6 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php @@ -0,0 +1,29 @@ + '{$name}/' + ); + + /** + * Remove hyphen, "plugin" and format to camelcase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = explode("-", $vars['name']); + foreach ($vars['name'] as $key => $name) { + $vars['name'][$key] = ucfirst($vars['name'][$key]); + if (strcasecmp($name, "Plugin") == 0) { + unset($vars['name'][$key]); + } + } + $vars['name'] = implode("",$vars['name']); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/Plugin.php b/vendor/composer/installers/src/Composer/Installers/Plugin.php new file mode 100644 index 00000000..5eb04af1 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/Plugin.php @@ -0,0 +1,17 @@ +getInstallationManager()->addInstaller($installer); + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php new file mode 100644 index 00000000..dbf85e63 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php @@ -0,0 +1,9 @@ + 'app/Containers/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php new file mode 100644 index 00000000..0f78b5ca --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php @@ -0,0 +1,24 @@ + 'src/{$name}/' + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php new file mode 100644 index 00000000..252c7339 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php @@ -0,0 +1,10 @@ + 'themes/{$name}/', + 'plugin' => 'plugins/{$name}/' + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php index 673f1fc1..d0193cba 100644 --- a/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php @@ -11,7 +11,9 @@ class ShopwareInstaller extends BaseInstaller 'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/', 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/', 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/', - 'theme' => 'templates/{$name}/' + 'theme' => 'templates/{$name}/', + 'plugin' => 'custom/plugins/{$name}/', + 'frontend-theme' => 'themes/Frontend/{$name}/', ); /** diff --git a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php new file mode 100644 index 00000000..83ef9d09 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php @@ -0,0 +1,49 @@ + 'app/modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format module name. + * + * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. + * + * @param array @vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'sydes-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'sydes-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']); + $vars['name'] = strtolower($vars['name']); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php index 8220b40d..b1663e84 100644 --- a/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +++ b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php @@ -4,6 +4,8 @@ /** * Extension installer for TYPO3 CMS * + * @deprecated since 1.0.25, use https://packagist.org/packages/typo3/cms-composer-installers instead + * * @author Sascha Egerer */ class TYPO3CmsInstaller extends BaseInstaller diff --git a/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php new file mode 100644 index 00000000..fcb414ab --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php @@ -0,0 +1,9 @@ + 'app/sprinkles/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php new file mode 100644 index 00000000..24ca6451 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php @@ -0,0 +1,10 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php new file mode 100644 index 00000000..7d90c5e6 --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php @@ -0,0 +1,49 @@ + 'src/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type vgmcp-bundle, cut off a trailing '-bundle' if present. + * + * For package type vgmcp-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'vgmcp-bundle') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'vgmcp-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php new file mode 100644 index 00000000..27f429ff --- /dev/null +++ b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php @@ -0,0 +1,32 @@ + 'module/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} \ No newline at end of file diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php index 71480eca..f6e83410 100644 --- a/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php +++ b/vendor/composer/installers/tests/Composer/Installers/Test/AsgardInstallerTest.php @@ -8,7 +8,7 @@ class AsgardInstallerTest extends \PHPUnit_Framework_TestCase { /** - * @var OctoberInstaller + * @var AsgardInstaller */ private $installer; @@ -26,14 +26,20 @@ public function setUp() public function testInflectPackageVars($type, $name, $expected) { $this->assertEquals( - $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)), - array('name' => $expected, 'type' => $type) + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) ); } public function packageNameInflectionProvider() { return array( + // Should keep module name StudlyCase + array( + 'asgard-module', + 'user-profile', + 'UserProfile' + ), array( 'asgard-module', 'asgard-module', @@ -44,11 +50,17 @@ public function packageNameInflectionProvider() 'blog', 'Blog' ), + // tests that exactly one '-module' is cut off + array( + 'asgard-module', + 'some-module-module', + 'SomeModule', + ), // tests that exactly one '-theme' is cut off array( 'asgard-theme', 'some-theme-theme', - 'Some-theme', + 'SomeTheme', ), // tests that names without '-theme' suffix stay valid array( @@ -56,6 +68,12 @@ public function packageNameInflectionProvider() 'someothertheme', 'Someothertheme', ), + // Should keep theme name StudlyCase + array( + 'asgard-theme', + 'adminlte-advanced', + 'AdminlteAdvanced' + ), ); } } diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/BitrixInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/BitrixInstallerTest.php new file mode 100644 index 00000000..e909bb42 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/BitrixInstallerTest.php @@ -0,0 +1,76 @@ +composer = new Composer(); + } + + /** + * @param string $vars + * @param string $expectedVars + * + * @covers ::inflectPackageVars + * + * @dataProvider provideExpectedInflectionResults + */ + final public function testInflectPackageVars($vars, $expectedVars) + { + + $this->installer = new BitrixInstaller( + new Package($vars['name'], '4.2', '4.2'), + $this->composer + ); + $actual = $this->installer->inflectPackageVars($vars); + $this->assertEquals($actual, $expectedVars); + } + + /** + * Provides various parameters for packages and the expected result after inflection + * + * @return array + */ + final public function provideExpectedInflectionResults() + { + return array( + //check bitrix-dir is correct + array( + array('name' => 'Nyan/Cat'), + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'bitrix') + ), + array( + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'bitrix'), + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'bitrix') + ), + array( + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'local'), + array('name' => 'Nyan/Cat', 'bitrix_dir' => 'local') + ), + ); + } +} \ No newline at end of file diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php index 976bd9be..523e8476 100644 --- a/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php +++ b/vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php @@ -100,7 +100,7 @@ public function testGetLocations() { $this->setCakephpVersion($rm, '~8.8'); $result = $installer->getLocations(); - $this->assertEquals('vendor/{$vendor}/{$name}/', $result['plugin']); + $this->assertContains('vendor/{$vendor}/{$name}/', $result['plugin']); } protected function setCakephpVersion($rm, $version) { diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php new file mode 100644 index 00000000..31ccecdb --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/CraftInstallerTest.php @@ -0,0 +1,83 @@ +installer = new CraftInstaller(); + } + + /** + * @param string $packageName + * @param string $expectedName + * + * @covers ::inflectPackageVars + * + * @dataProvider provideExpectedInflectionResults + */ + final public function testInflectPackageVars($packageName, $expectedName) + { + $installer = $this->installer; + + $vars = array('name' => $packageName); + $expected = array('name' => $expectedName); + + $actual = $installer->inflectPackageVars($vars); + + $this->assertEquals($actual, $expected); + } + + /** + * Provides various names for packages and the expected result after inflection + * + * @return array + */ + final public function provideExpectedInflectionResults() + { + return array( + // lowercase + array('foo', 'foo'), + array('craftfoo', 'craftfoo'), + array('fooplugin', 'fooplugin'), + array('craftfooplugin', 'craftfooplugin'), + // lowercase - dash + array('craft-foo', 'foo'), + array('foo-plugin', 'foo'), + array('craft-foo-plugin', 'foo'), + // lowercase - underscore + array('craft_foo', 'craft_foo'), + array('foo_plugin', 'foo_plugin'), + array('craft_foo_plugin', 'craft_foo_plugin'), + // CamelCase + array('Foo', 'Foo'), + array('CraftFoo', 'CraftFoo'), + array('FooPlugin', 'FooPlugin'), + array('CraftFooPlugin', 'CraftFooPlugin'), + // CamelCase - Dash + array('Craft-Foo', 'Foo'), + array('Foo-Plugin', 'Foo'), + array('Craft-Foo-Plugin', 'Foo'), + // CamelCase - underscore + array('Craft_Foo', 'Craft_Foo'), + array('Foo_Plugin', 'Foo_Plugin'), + array('Craft_Foo_Plugin', 'Craft_Foo_Plugin'), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php index a516daf0..cec3e455 100644 --- a/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php +++ b/vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php @@ -89,15 +89,18 @@ public function dataForTestSupport() array('annotatecms-module', true), array('annotatecms-component', true), array('annotatecms-service', true), + array('attogram-module', true), array('bitrix-module', true), array('bitrix-component', true), array('bitrix-theme', true), + array('bonefish-package', true), array('cakephp', false), array('cakephp-', false), array('cakephp-app', false), array('cakephp-plugin', true), array('chef-cookbook', true), array('chef-role', true), + array('cockpit-module', true), array('codeigniter-app', false), array('codeigniter-library', true), array('codeigniter-third-party', true), @@ -105,25 +108,45 @@ public function dataForTestSupport() array('concrete5-block', true), array('concrete5-package', true), array('concrete5-theme', true), + array('concrete5-core', true), array('concrete5-update', true), array('craft-plugin', true), array('croogo-plugin', true), array('croogo-theme', true), + array('decibel-app', true), array('dokuwiki-plugin', true), array('dokuwiki-template', true), array('drupal-module', true), array('dolibarr-module', true), + array('ee3-theme', true), + array('ee3-addon', true), + array('ee2-theme', true), + array('ee2-addon', true), array('elgg-plugin', true), + array('eliasis-module', true), + array('ezplatform-assets', true), + array('ezplatform-meta-assets', true), array('fuel-module', true), array('fuel-package', true), array('fuel-theme', true), array('fuelphp-component', true), array('hurad-plugin', true), array('hurad-theme', true), + array('imagecms-template', true), + array('imagecms-module', true), + array('imagecms-library', true), + array('itop-extension', true), array('joomla-library', true), + array('kanboard-plugin', true), array('kirby-plugin', true), array('kohana-module', true), + array('lms-plugin', true), + array('lms-template', true), + array('lms-document-template', true), + array('lms-userpanel-module', true), array('laravel-library', true), + array('lavalite-theme', true), + array('lavalite-package', true), array('lithium-library', true), array('magento-library', true), array('mako-package', true), @@ -142,21 +165,30 @@ public function dataForTestSupport() array('piwik-plugin', true), array('phpbb-extension', true), array('pimcore-plugin', true), + array('plentymarkets-plugin', true), array('ppi-module', true), array('prestashop-module', true), array('prestashop-theme', true), array('puppet-module', true), + array('porto-container', true), + array('radphp-bundle', true), array('redaxo-addon', true), array('redaxo-bestyle-plugin', true), + array('reindex-theme', true), + array('reindex-plugin', true), array('roundcube-plugin', true), array('shopware-backend-plugin', true), array('shopware-core-plugin', true), array('shopware-frontend-plugin', true), array('shopware-theme', true), + array('shopware-plugin', true), + array('shopware-frontend-theme', true), array('silverstripe-module', true), array('silverstripe-theme', true), array('smf-module', true), array('smf-theme', true), + array('sydes-module', true), + array('sydes-theme', true), array('symfony1-plugin', true), array('thelia-module', true), array('thelia-frontoffice-template', true), @@ -166,13 +198,25 @@ public function dataForTestSupport() array('tusk-asset', true), array('typo3-flow-plugin', true), array('typo3-cms-extension', true), + array('userfrosting-sprinkle', true), + array('vanilla-plugin', true), + array('vanilla-theme', true), array('whmcs-gateway', true), array('wolfcms-plugin', true), array('wordpress-plugin', true), array('wordpress-core', false), + array('yawik-module', true), array('zend-library', true), array('zikula-module', true), array('zikula-theme', true), + array('kodicms-plugin', true), + array('kodicms-media', true), + array('phifty-bundle', true), + array('phifty-library', true), + array('phifty-framework', true), + array('osclass-plugin', true), + array('osclass-theme', true), + array('osclass-language', true), ); } @@ -202,21 +246,29 @@ public function dataForTestInstallPath() array('annotatecms-module', 'addons/modules/my_module/', 'vysinsky/my_module'), array('annotatecms-component', 'addons/components/my_component/', 'vysinsky/my_component'), array('annotatecms-service', 'addons/services/my_service/', 'vysinsky/my_service'), - array('bitrix-module', 'local/modules/my_module/', 'author/my_module'), - array('bitrix-component', 'local/components/my_component/', 'author/my_component'), - array('bitrix-theme', 'local/templates/my_theme/', 'author/my_theme'), + array('attogram-module', 'modules/my_module/', 'author/my_module'), + array('bitrix-module', 'bitrix/modules/my_module/', 'author/my_module'), + array('bitrix-component', 'bitrix/components/my_component/', 'author/my_component'), + array('bitrix-theme', 'bitrix/templates/my_theme/', 'author/my_theme'), + array('bitrix-d7-module', 'bitrix/modules/author.my_module/', 'author/my_module'), + array('bitrix-d7-component', 'bitrix/components/author/my_component/', 'author/my_component'), + array('bitrix-d7-template', 'bitrix/templates/author_my_template/', 'author/my_template'), + array('bonefish-package', 'Packages/bonefish/package/', 'bonefish/package'), array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'), array('chef-cookbook', 'Chef/mre/my_cookbook/', 'mre/my_cookbook'), array('chef-role', 'Chef/roles/my_role/', 'mre/my_role'), + array('cockpit-module', 'cockpit/modules/addons/My_module/', 'piotr-cz/cockpit-my_module'), array('codeigniter-library', 'application/libraries/my_package/', 'shama/my_package'), array('codeigniter-module', 'application/modules/my_package/', 'shama/my_package'), - array('concrete5-block', 'blocks/concrete5_block/', 'remo/concrete5_block'), + array('concrete5-block', 'application/blocks/concrete5_block/', 'remo/concrete5_block'), array('concrete5-package', 'packages/concrete5_package/', 'remo/concrete5_package'), - array('concrete5-theme', 'themes/concrete5_theme/', 'remo/concrete5_theme'), + array('concrete5-theme', 'application/themes/concrete5_theme/', 'remo/concrete5_theme'), + array('concrete5-core', 'concrete/', 'concrete5/core'), array('concrete5-update', 'updates/concrete5/', 'concrete5/concrete5'), array('craft-plugin', 'craft/plugins/my_plugin/', 'mdcpepper/my_plugin'), array('croogo-plugin', 'Plugin/Sitemaps/', 'fahad19/sitemaps'), array('croogo-theme', 'View/Themed/Readable/', 'rchavik/readable'), + array('decibel-app', 'app/someapp/', 'author/someapp'), array('dokuwiki-plugin', 'lib/plugins/someplugin/', 'author/someplugin'), array('dokuwiki-template', 'lib/tpl/sometemplate/', 'author/sometemplate'), array('dolibarr-module', 'htdocs/custom/my_module/', 'shama/my_module'), @@ -225,16 +277,38 @@ public function dataForTestInstallPath() array('drupal-profile', 'profiles/my_module/', 'shama/my_module'), array('drupal-drush', 'drush/my_module/', 'shama/my_module'), array('elgg-plugin', 'mod/sample_plugin/', 'test/sample_plugin'), + array('eliasis-module', 'modules/my_module/', 'shama/my_module'), + array('ee3-addon', 'system/user/addons/ee_theme/', 'author/ee_theme'), + array('ee3-theme', 'themes/user/ee_package/', 'author/ee_package'), + array('ee2-addon', 'system/expressionengine/third_party/ee_theme/', 'author/ee_theme'), + array('ee2-theme', 'themes/third_party/ee_package/', 'author/ee_package'), + array('ezplatform-assets', 'web/assets/ezplatform/ezplatform_comp/', 'author/ezplatform_comp'), + array('ezplatform-meta-assets', 'web/assets/ezplatform/', 'author/ezplatform_comp'), array('fuel-module', 'fuel/app/modules/module/', 'fuel/module'), array('fuel-package', 'fuel/packages/orm/', 'fuel/orm'), array('fuel-theme', 'fuel/app/themes/theme/', 'fuel/theme'), array('fuelphp-component', 'components/demo/', 'fuelphp/demo'), array('hurad-plugin', 'plugins/Akismet/', 'atkrad/akismet'), array('hurad-theme', 'plugins/Hurad2013/', 'atkrad/Hurad2013'), + array('imagecms-template', 'templates/my_template/', 'shama/my_template'), + array('imagecms-module', 'application/modules/my_module/', 'shama/my_module'), + array('imagecms-library', 'application/libraries/my_library/', 'shama/my_library'), + array('itop-extension', 'extensions/my_extension/', 'shama/my_extension'), array('joomla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'), + array('kanboard-plugin', 'plugins/my_plugin/', 'shama/my_plugin'), array('kirby-plugin', 'site/plugins/my_plugin/', 'shama/my_plugin'), array('kohana-module', 'modules/my_package/', 'shama/my_package'), + array('lms-plugin', 'plugins/MyPackage/', 'shama/MyPackage'), + array('lms-plugin', 'plugins/MyPackage/', 'shama/my_package'), + array('lms-template', 'templates/MyPackage/', 'shama/MyPackage'), + array('lms-template', 'templates/MyPackage/', 'shama/my_package'), + array('lms-document-template', 'documents/templates/MyPackage/', 'shama/MyPackage'), + array('lms-document-template', 'documents/templates/MyPackage/', 'shama/my_package'), + array('lms-userpanel-module', 'userpanel/modules/MyPackage/', 'shama/MyPackage'), + array('lms-userpanel-module', 'userpanel/modules/MyPackage/', 'shama/my_package'), array('laravel-library', 'libraries/my_package/', 'shama/my_package'), + array('lavalite-theme', 'public/themes/my_theme/', 'shama/my_theme'), + array('lavalite-package', 'packages/my_group/my_package/', 'my_group/my_package'), array('lithium-library', 'libraries/li3_test/', 'user/li3_test'), array('magento-library', 'lib/foo/', 'test/foo'), array('modxevo-snippet', 'assets/snippets/my_snippet/', 'shama/my_snippet'), @@ -262,16 +336,23 @@ public function dataForTestInstallPath() array('phpbb-style', 'styles/foo/', 'test/foo'), array('phpbb-language', 'language/foo/', 'test/foo'), array('pimcore-plugin', 'plugins/MyPlugin/', 'ubikz/my_plugin'), + array('plentymarkets-plugin', 'HelloWorld/', 'plugin-hello-world'), array('ppi-module', 'modules/foo/', 'test/foo'), array('puppet-module', 'modules/puppet-name/', 'puppet/puppet-name'), + array('porto-container', 'app/Containers/container-name/', 'test/container-name'), + array('radphp-bundle', 'src/Migration/', 'atkrad/migration'), array('redaxo-addon', 'redaxo/include/addons/my_plugin/', 'shama/my_plugin'), array('redaxo-bestyle-plugin', 'redaxo/include/addons/be_style/plugins/my_plugin/', 'shama/my_plugin'), + array('reindex-theme', 'themes/my_module/', 'author/my_module'), + array('reindex-plugin', 'plugins/my_module/', 'author/my_module'), array('roundcube-plugin', 'plugins/base/', 'test/base'), array('roundcube-plugin', 'plugins/replace_dash/', 'test/replace-dash'), array('shopware-backend-plugin', 'engine/Shopware/Plugins/Local/Backend/ShamaMyBackendPlugin/', 'shama/my-backend-plugin'), array('shopware-core-plugin', 'engine/Shopware/Plugins/Local/Core/ShamaMyCorePlugin/', 'shama/my-core-plugin'), array('shopware-frontend-plugin', 'engine/Shopware/Plugins/Local/Frontend/ShamaMyFrontendPlugin/', 'shama/my-frontend-plugin'), array('shopware-theme', 'templates/my_theme/', 'shama/my-theme'), + array('shopware-frontend-theme', 'themes/Frontend/ShamaMyFrontendTheme/', 'shama/my-frontend-theme'), + array('shopware-plugin', 'custom/plugins/ShamaMyPlugin/', 'shama/my-plugin'), array('silverstripe-module', 'my_module/', 'shama/my_module'), array('silverstripe-module', 'sapphire/', 'silverstripe/framework', '2.4.0'), array('silverstripe-module', 'framework/', 'silverstripe/framework', '3.0.0'), @@ -290,6 +371,9 @@ public function dataForTestInstallPath() array('typo3-flow-package', 'Packages/Application/my_package/', 'shama/my_package'), array('typo3-flow-build', 'Build/my_package/', 'shama/my_package'), array('typo3-cms-extension', 'typo3conf/ext/my_extension/', 'shama/my_extension'), + array('userfrosting-sprinkle', 'app/sprinkles/my_sprinkle/', 'shama/my_sprinkle'), + array('vanilla-plugin', 'plugins/my_plugin/', 'shama/my_plugin'), + array('vanilla-theme', 'themes/my_theme/', 'shama/my_theme'), array('whmcs-gateway', 'modules/gateways/gateway_name/', 'vendor/gateway_name'), array('wolfcms-plugin', 'wolf/plugins/my_plugin/', 'shama/my_plugin'), array('wordpress-plugin', 'wp-content/plugins/my_plugin/', 'shama/my_plugin'), @@ -297,6 +381,15 @@ public function dataForTestInstallPath() array('zend-extra', 'extras/library/zend_test/', 'shama/zend_test'), array('zikula-module', 'modules/my-test_module/', 'my/test_module'), array('zikula-theme', 'themes/my-test_theme/', 'my/test_theme'), + array('kodicms-media', 'cms/media/vendor/my_media/', 'shama/my_media'), + array('kodicms-plugin', 'cms/plugins/my_plugin/', 'shama/my_plugin'), + array('phifty-bundle', 'bundles/core/', 'shama/core'), + array('phifty-library', 'libraries/my-lib/', 'shama/my-lib'), + array('phifty-framework', 'frameworks/my-framework/', 'shama/my-framework'), + array('yawik-module', 'module/MyModule/', 'shama/my_module'), + array('osclass-plugin', 'oc-content/plugins/sample_plugin/', 'test/sample_plugin'), + array('osclass-theme', 'oc-content/themes/sample_theme/', 'test/sample_theme'), + array('osclass-language', 'oc-content/languages/sample_lang/', 'test/sample_lang'), ); } @@ -374,6 +467,27 @@ public function testCustomTypePath() $this->assertEquals('my/custom/path/my_plugin/', $result); } + /** + * testVendorPath + */ + public function testVendorPath() + { + $installer = new Installer($this->io, $this->composer); + $package = new Package('penyaskito/my_module', '1.0.0', '1.0.0'); + $package->setType('drupal-module'); + $consumerPackage = new RootPackage('drupal/drupal', '1.0.0', '1.0.0'); + $this->composer->setPackage($consumerPackage); + $consumerPackage->setExtra(array( + 'installer-paths' => array( + 'modules/custom/{$name}/' => array( + 'vendor:penyaskito' + ), + ), + )); + $result = $installer->getInstallPath($package); + $this->assertEquals('modules/custom/my_module/', $result); + } + /** * testNoVendorName */ diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/MayaInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/MayaInstallerTest.php new file mode 100644 index 00000000..f800c611 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/MayaInstallerTest.php @@ -0,0 +1,61 @@ +installer = new MayaInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // Should keep module name StudlyCase + array( + 'maya-module', + 'user-profile', + 'UserProfile' + ), + array( + 'maya-module', + 'maya-module', + 'Maya' + ), + array( + 'maya-module', + 'blog', + 'Blog' + ), + // tests that exactly one '-module' is cut off + array( + 'maya-module', + 'some-module-module', + 'SomeModule', + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/OntoWikiInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/OntoWikiInstallerTest.php new file mode 100644 index 00000000..24c498c8 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/OntoWikiInstallerTest.php @@ -0,0 +1,85 @@ +installer = new OntoWikiInstaller(); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)), + array('name' => $expected, 'type'=>$type) + ); + } + + public function packageNameInflectionProvider() + { + return array( + array( + 'ontowiki-extension', + 'CSVImport.ontowiki', + 'csvimport', + ), + array( + 'ontowiki-extension', + 'csvimport', + 'csvimport', + ), + array( + 'ontowiki-extension', + 'some_ontowiki_extension', + 'some_ontowiki_extension', + ), + array( + 'ontowiki-extension', + 'some_ontowiki_extension.ontowiki', + 'some_ontowiki_extension', + ), + array( + 'ontowiki-translation', + 'de-translation.ontowiki', + 'de', + ), + array( + 'ontowiki-translation', + 'en-US-translation.ontowiki', + 'en-us', + ), + array( + 'ontowiki-translation', + 'en-US-translation', + 'en-us', + ), + array( + 'ontowiki-theme', + 'blue-theme.ontowiki', + 'blue', + ), + array( + 'ontowiki-theme', + 'blue-theme', + 'blue', + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/SyDESInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/SyDESInstallerTest.php new file mode 100644 index 00000000..1521fbf3 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/SyDESInstallerTest.php @@ -0,0 +1,81 @@ +installer = new SyDESInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // modules + array( + 'sydes-module', + 'name', + 'Name' + ), + array( + 'sydes-module', + 'sample-name', + 'SampleName' + ), + array( + 'sydes-module', + 'sydes-name', + 'Name' + ), + array( + 'sydes-module', + 'sample-name-module', + 'SampleName', + ), + array( + 'sydes-module', + 'sydes-sample-name-module', + 'SampleName' + ), + // themes + array( + 'sydes-theme', + 'some-theme-theme', + 'some-theme', + ), + array( + 'sydes-theme', + 'sydes-sometheme', + 'sometheme', + ), + array( + 'sydes-theme', + 'Sample-Name', + 'sample-name' + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/VgmcpInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/VgmcpInstallerTest.php new file mode 100644 index 00000000..8b33ab81 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/VgmcpInstallerTest.php @@ -0,0 +1,79 @@ +installer = new VgmcpInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $name, $expected) + { + $this->assertEquals( + array('name' => $expected, 'type' => $type), + $this->installer->inflectPackageVars(array('name' => $name, 'type' => $type)) + ); + } + + public function packageNameInflectionProvider() + { + return array( + // Should keep bundle name StudlyCase + array( + 'vgmcp-bundle', + 'user-profile', + 'UserProfile' + ), + array( + 'vgmcp-bundle', + 'vgmcp-bundle', + 'Vgmcp' + ), + array( + 'vgmcp-bundle', + 'blog', + 'Blog' + ), + // tests that exactly one '-bundle' is cut off + array( + 'vgmcp-bundle', + 'some-bundle-bundle', + 'SomeBundle', + ), + // tests that exactly one '-theme' is cut off + array( + 'vgmcp-theme', + 'some-theme-theme', + 'SomeTheme', + ), + // tests that names without '-theme' suffix stay valid + array( + 'vgmcp-theme', + 'someothertheme', + 'Someothertheme', + ), + // Should keep theme name StudlyCase + array( + 'vgmcp-theme', + 'adminlte-advanced', + 'AdminlteAdvanced' + ), + ); + } +} diff --git a/vendor/composer/installers/tests/Composer/Installers/Test/YawikInstallerTest.php b/vendor/composer/installers/tests/Composer/Installers/Test/YawikInstallerTest.php new file mode 100644 index 00000000..d8d35ff2 --- /dev/null +++ b/vendor/composer/installers/tests/Composer/Installers/Test/YawikInstallerTest.php @@ -0,0 +1,64 @@ +package = new Package('YawikCompanyRegistration', '1.0', '1.0'); + $this->io = $this->getMock('Composer\IO\PackageInterface'); + $this->composer = new Composer(); + } + + /** + * testInflectPackageVars + * + * @dataProvider packageNameProvider + * @return void + */ + public function testInflectPackageVars($input) + { + $installer = new YawikInstaller($this->package, $this->composer); + $result = $installer->inflectPackageVars(array('name' => $input)); + $this->assertEquals($result, array('name' => 'YawikCompanyRegistration')); + } + + public function packageNameProvider() + { + return array( + array('yawik-company-registration'), + array('yawik_company_registration'), + array('YawikCompanyRegistration') + ); + } +} diff --git a/vendor/composer/semver/CHANGELOG.md b/vendor/composer/semver/CHANGELOG.md index 8352cb72..febedc97 100644 --- a/vendor/composer/semver/CHANGELOG.md +++ b/vendor/composer/semver/CHANGELOG.md @@ -3,6 +3,36 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +### [1.4.2] 2016-08-30 + + * Fixed: collapsing of complex constraints lead to buggy constraints + +### [1.4.1] 2016-06-02 + + * Changed: branch-like requirements no longer strip build metadata - [composer/semver#38](https://github.com/composer/semver/pull/38). + +### [1.4.0] 2016-03-30 + + * Added: getters on MultiConstraint - [composer/semver#35](https://github.com/composer/semver/pull/35). + +### [1.3.0] 2016-02-25 + + * Fixed: stability parsing - [composer/composer#1234](https://github.com/composer/composer/issues/4889). + * Changed: collapse contiguous constraints when possible. + +### [1.2.0] 2015-11-10 + + * Changed: allow multiple numerical identifiers in 'pre-release' version part. + * Changed: add more 'v' prefix support. + +### [1.1.0] 2015-11-03 + + * Changed: dropped redundant `test` namespace. + * Changed: minor adjustment in datetime parsing normalization. + * Changed: `ConstraintInterface` relaxed, setPrettyString is not required anymore. + * Changed: `AbstractConstraint` marked deprecated, will be removed in 2.0. + * Changed: `Constraint` is now extensible. + ### [1.0.0] 2015-09-21 * Break: `VersionConstraint` renamed to `Constraint`. @@ -13,7 +43,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). * Changed: `VersionParser::parseConstraints` allows (but ignores) prefixing numeric versions with a 'v' now. * Changed: Fixed namespace(s) of test files. * Changed: `Comparator::compare` no longer throws `InvalidArgumentException`. - * Changed: `VersionConstraint` now throws `InvalidArgumentException`. + * Changed: `Constraint` now throws `InvalidArgumentException`. ### [0.1.0] 2015-07-23 @@ -26,3 +56,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Namespace: `Composer\Test\Package\Version` -> `Composer\Test\Semver` - Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint` * Changed: code style using php-cs-fixer. + +[1.4.1]: https://github.com/composer/semver/compare/1.4.0...1.4.1 +[1.4.0]: https://github.com/composer/semver/compare/1.3.0...1.4.0 +[1.3.0]: https://github.com/composer/semver/compare/1.2.0...1.3.0 +[1.2.0]: https://github.com/composer/semver/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/composer/semver/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/composer/semver/compare/0.1.0...1.0.0 +[0.1.0]: https://github.com/composer/semver/compare/5e0b9a4da...0.1.0 diff --git a/vendor/composer/semver/README.md b/vendor/composer/semver/README.md index c8b69798..143daa0d 100644 --- a/vendor/composer/semver/README.md +++ b/vendor/composer/semver/README.md @@ -56,10 +56,10 @@ Comparator::greaterThan('1.25.0', '1.24.0'); // 1.25.0 > 1.24.0 ### Semver -The `Composer\Semver\Semver` class providers the following methods: +The `Composer\Semver\Semver` class provides the following methods: * satisfies($version, $constraints) -* satisfiedBy($constraint, array $versions) +* satisfiedBy(array $versions, $constraint) * sort($versions) * rsort($versions) diff --git a/vendor/composer/semver/composer.json b/vendor/composer/semver/composer.json index b996186f..b0400cd7 100644 --- a/vendor/composer/semver/composer.json +++ b/vendor/composer/semver/composer.json @@ -22,7 +22,8 @@ }, { "name": "Rob Bast", - "email": "rob.bast@gmail.com" + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], "support": { @@ -30,11 +31,11 @@ "issues": "https://github.com/composer/semver/issues" }, "require": { - "php": ">=5.3.2" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "~2.3" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, "autoload": { "psr-4": { @@ -43,12 +44,12 @@ }, "autoload-dev": { "psr-4": { - "Composer\\Semver\\Test\\": "tests" + "Composer\\Semver\\": "tests" } }, "extra": { "branch-alias": { - "dev-master": "0.1-dev" + "dev-master": "1.x-dev" } }, "scripts": { diff --git a/vendor/composer/semver/src/Constraint/AbstractConstraint.php b/vendor/composer/semver/src/Constraint/AbstractConstraint.php index ccd834f6..be83f750 100644 --- a/vendor/composer/semver/src/Constraint/AbstractConstraint.php +++ b/vendor/composer/semver/src/Constraint/AbstractConstraint.php @@ -11,6 +11,8 @@ namespace Composer\Semver\Constraint; +trigger_error('The ' . __CLASS__ . ' abstract class is deprecated, there is no replacement for it, it will be removed in the next major version.', E_USER_DEPRECATED); + /** * Base constraint class. */ @@ -26,17 +28,13 @@ abstract class AbstractConstraint implements ConstraintInterface */ public function matches(ConstraintInterface $provider) { - if ($provider instanceof MultiConstraint) { - // turn matching around to find a match - return $provider->matches($this); - } - if ($provider instanceof $this) { // see note at bottom of this class declaration return $this->matchSpecific($provider); } - return true; + // turn matching around to find a match + return $provider->matches($this); } /** diff --git a/vendor/composer/semver/src/Constraint/Constraint.php b/vendor/composer/semver/src/Constraint/Constraint.php index 8bc68db7..7a21eb47 100644 --- a/vendor/composer/semver/src/Constraint/Constraint.php +++ b/vendor/composer/semver/src/Constraint/Constraint.php @@ -14,7 +14,7 @@ /** * Defines a constraint. */ -class Constraint extends AbstractConstraint +class Constraint implements ConstraintInterface { /* operator integer values */ const OP_EQ = 0; @@ -55,10 +55,48 @@ class Constraint extends AbstractConstraint ); /** @var string */ - private $operator; + protected $operator; /** @var string */ - private $version; + protected $version; + + /** @var string */ + protected $prettyString; + + /** + * @param ConstraintInterface $provider + * + * @return bool + */ + public function matches(ConstraintInterface $provider) + { + if ($provider instanceof $this) { + return $this->matchSpecific($provider); + } + + // turn matching around to find a match + return $provider->matches($this); + } + + /** + * @param string $prettyString + */ + public function setPrettyString($prettyString) + { + $this->prettyString = $prettyString; + } + + /** + * @return string + */ + public function getPrettyString() + { + if ($this->prettyString) { + return $this->prettyString; + } + + return $this->__toString(); + } /** * Get all supported comparison operators. diff --git a/vendor/composer/semver/src/Constraint/ConstraintInterface.php b/vendor/composer/semver/src/Constraint/ConstraintInterface.php index 78c099ce..7cb13b6a 100644 --- a/vendor/composer/semver/src/Constraint/ConstraintInterface.php +++ b/vendor/composer/semver/src/Constraint/ConstraintInterface.php @@ -20,11 +20,6 @@ interface ConstraintInterface */ public function matches(ConstraintInterface $provider); - /** - * @param string $prettyString - */ - public function setPrettyString($prettyString); - /** * @return string */ diff --git a/vendor/composer/semver/src/Constraint/MultiConstraint.php b/vendor/composer/semver/src/Constraint/MultiConstraint.php index 0d769b7c..0c547afd 100644 --- a/vendor/composer/semver/src/Constraint/MultiConstraint.php +++ b/vendor/composer/semver/src/Constraint/MultiConstraint.php @@ -35,6 +35,30 @@ public function __construct(array $constraints, $conjunctive = true) $this->conjunctive = $conjunctive; } + /** + * @return ConstraintInterface[] + */ + public function getConstraints() + { + return $this->constraints; + } + + /** + * @return bool + */ + public function isConjunctive() + { + return $this->conjunctive; + } + + /** + * @return bool + */ + public function isDisjunctive() + { + return !$this->conjunctive; + } + /** * @param ConstraintInterface $provider * diff --git a/vendor/composer/semver/src/VersionParser.php b/vendor/composer/semver/src/VersionParser.php index 269aee94..359c18c4 100644 --- a/vendor/composer/semver/src/VersionParser.php +++ b/vendor/composer/semver/src/VersionParser.php @@ -23,13 +23,23 @@ */ class VersionParser { - /** @var string */ - private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)(?:[.-]?(\d+))?)?([.-]?dev)?'; + /** + * Regex to match pre-release data (sort of). + * + * Due to backwards compatibility: + * - Instead of enforcing hyphen, an underscore, dot or nothing at all are also accepted. + * - Only stabilities as recognized by Composer are allowed to precede a numerical identifier. + * - Numerical-only pre-release identifiers are not supported, see tests. + * + * |--------------| + * [major].[minor].[patch] -[pre-release] +[build-metadata] + * + * @var string + */ + private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*+)?)?([.-]?dev)?'; /** @var array */ - private static $stabilities = array( - 'stable', 'RC', 'beta', 'alpha', 'dev', - ); + private static $stabilities = array('stable', 'RC', 'beta', 'alpha', 'dev'); /** * Returns the stability of a version. @@ -46,7 +56,7 @@ public static function parseStability($version) return 'dev'; } - preg_match('{' . self::$modifierRegex . '$}i', strtolower($version), $match); + preg_match('{' . self::$modifierRegex . '(?:\+.*)?$}i', strtolower($version), $match); if (!empty($match[3])) { return 'dev'; } @@ -96,12 +106,7 @@ public function normalize($version, $fullVersion = null) } // strip off aliasing - if (preg_match('{^([^,\s]+) +as +([^,\s]+)$}', $version, $match)) { - $version = $match[1]; - } - - // strip off build metadata - if (preg_match('{^([^,\s+]+)\+[^\s]+$}', $version, $match)) { + if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $version, $match)) { $version = $match[1]; } @@ -110,12 +115,18 @@ public function normalize($version, $fullVersion = null) return '9999999-dev'; } + // if requirement is branch-like, use full name if ('dev-' === strtolower(substr($version, 0, 4))) { return 'dev-' . substr($version, 4); } + // strip off build metadata + if (preg_match('{^([^,\s+]++)\+[^\s]++$}', $version, $match)) { + $version = $match[1]; + } + // match classical versioning - if (preg_match('{^v?(\d{1,5})(\.\d+)?(\.\d+)?(\.\d+)?' . self::$modifierRegex . '$}i', $version, $matches)) { + if (preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) { $version = $matches[1] . (!empty($matches[2]) ? $matches[2] : '.0') . (!empty($matches[3]) ? $matches[3] : '.0') @@ -123,7 +134,7 @@ public function normalize($version, $fullVersion = null) $index = 5; // match date(time) based versioning } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) { - $version = preg_replace('{\D}', '-', $matches[1]); + $version = preg_replace('{\D}', '.', $matches[1]); $index = 2; } @@ -133,7 +144,7 @@ public function normalize($version, $fullVersion = null) if ('stable' === $matches[$index]) { return $version; } - $version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? $matches[$index + 1] : ''); + $version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? ltrim($matches[$index + 1], '.-') : ''); } if (!empty($matches[$index + 2])) { @@ -170,7 +181,7 @@ public function normalize($version, $fullVersion = null) */ public function parseNumericAliasPrefix($branch) { - if (preg_match('{^(?P(\d+\\.)*\d+)(?:\.x)?-dev$}i', $branch, $matches)) { + if (preg_match('{^(?P(\d++\\.)*\d++)(?:\.x)?-dev$}i', $branch, $matches)) { return $matches['version'] . '.'; } @@ -192,7 +203,7 @@ public function normalizeBranch($name) return $this->normalize($name); } - if (preg_match('{^v?(\d+)(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?(\.(?:\d+|[xX*]))?$}i', $name, $matches)) { + if (preg_match('{^v?(\d++)(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?$}i', $name, $matches)) { $version = ''; for ($i = 1; $i < 5; ++$i) { $version .= isset($matches[$i]) ? str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x'; @@ -205,7 +216,7 @@ public function normalizeBranch($name) } /** - * Parses as constraint string into LinkConstraint objects. + * Parses a constraint string into MultiConstraint and/or Constraint objects. * * @param string $constraints * @@ -249,6 +260,23 @@ public function parseConstraints($constraints) if (1 === count($orGroups)) { $constraint = $orGroups[0]; + } elseif (2 === count($orGroups) + // parse the two OR groups and if they are contiguous we collapse + // them into one constraint + && $orGroups[0] instanceof MultiConstraint + && $orGroups[1] instanceof MultiConstraint + && 2 === count($orGroups[0]->getConstraints()) + && 2 === count($orGroups[1]->getConstraints()) + && ($a = (string) $orGroups[0]) + && substr($a, 0, 3) === '[>=' && (false !== ($posA = strpos($a, '<', 4))) + && ($b = (string) $orGroups[1]) + && substr($b, 0, 3) === '[>=' && (false !== ($posB = strpos($b, '<', 4))) + && substr($a, $posA + 2, -1) === substr($b, 4, $posB - 5) + ) { + $constraint = new MultiConstraint(array( + new Constraint('>=', substr($a, 4, $posA - 5)), + new Constraint('<', substr($b, $posB + 2, -1)), + )); } else { $constraint = new MultiConstraint($orGroups, false); } @@ -274,11 +302,11 @@ private function parseConstraint($constraint) } } - if (preg_match('{^[xX*](\.[xX*])*$}i', $constraint)) { + if (preg_match('{^v?[xX*](\.[xX*])*$}i', $constraint)) { return array(new EmptyConstraint()); } - $versionRegex = 'v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+))?' . self::$modifierRegex . '(?:\+[^\s]+)?'; + $versionRegex = 'v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.(\d++))?' . self::$modifierRegex . '(?:\+[^\s]+)?'; // Tilde Range // @@ -372,7 +400,7 @@ private function parseConstraint($constraint) // // Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple. // A partial version range is treated as an X-Range, so the special character is in fact optional. - if (preg_match('{^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.[xX*])+$}', $constraint, $matches)) { + if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) { if (isset($matches[3]) && '' !== $matches[3]) { $position = 3; } elseif (isset($matches[2]) && '' !== $matches[2]) { diff --git a/vendor/doctrine/cache/.travis.yml b/vendor/doctrine/cache/.travis.yml index 2952a481..a16fd9d9 100644 --- a/vendor/doctrine/cache/.travis.yml +++ b/vendor/doctrine/cache/.travis.yml @@ -1,11 +1,17 @@ language: php +sudo: false + +cache: + directories: + - vendor + - $HOME/.composer/cache + php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - hhvm + - 5.5 + - 5.6 + - 7.0 + - hhvm services: - riak @@ -14,13 +20,14 @@ services: - redis-server before_install: - - sh -c "if [ $TRAVIS_PHP_VERSION != 'hhvm' ]; then pecl install riak-beta; fi" - - sh -c "if [[ $TRAVIS_PHP_VERSION != 'hhvm' && `php-config --vernum` -ge 50500 ]] ; then pecl config-set preferred_state beta; printf "yes\n" | pecl install apcu ; else echo 'extension="apc.so"' >> ./tests/travis/php.ini ;fi" - - composer self-update - - sh -c "if [ $TRAVIS_PHP_VERSION != 'hhvm' ]; then phpenv config-add ./tests/travis/php.ini; fi" + - if [[ $TRAVIS_PHP_VERSION != 'hhvm' ]] ; then pecl channel-update pecl.php.net; fi; + - if [[ $TRAVIS_PHP_VERSION != 'hhvm' && $TRAVIS_PHP_VERSION != '7.0' ]]; then pecl install riak-beta; fi; + - if [[ $TRAVIS_PHP_VERSION =~ 5.[56] ]] ; then echo yes | pecl install apcu-4.0.10; fi; + - if [[ $TRAVIS_PHP_VERSION = 7.* ]] ; then pecl config-set preferred_state beta; echo yes | pecl install apcu; fi; + - if [[ $TRAVIS_PHP_VERSION != 'hhvm' ]]; then phpenv config-add ./tests/travis/php.ini; fi; install: - - composer --prefer-source --dev install + - travis_retry composer install script: - ./vendor/bin/phpunit -c ./tests/travis/phpunit.travis.xml -v @@ -29,5 +36,7 @@ after_script: - php vendor/bin/coveralls -v matrix: - allow_failures: - - php: hhvm + fast_finish: true + allow_failures: + - php: hhvm + - php: 7.0 diff --git a/vendor/doctrine/cache/LICENSE b/vendor/doctrine/cache/LICENSE index 4a91f0bf..8c38cc1b 100644 --- a/vendor/doctrine/cache/LICENSE +++ b/vendor/doctrine/cache/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2006-2012 Doctrine Project +Copyright (c) 2006-2015 Doctrine Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/vendor/doctrine/cache/composer.json b/vendor/doctrine/cache/composer.json index f3caa7a8..7ef1727a 100644 --- a/vendor/doctrine/cache/composer.json +++ b/vendor/doctrine/cache/composer.json @@ -13,10 +13,10 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "require-dev": { - "phpunit/phpunit": ">=3.7", + "phpunit/phpunit": "~4.8|~5.0", "satooshi/php-coveralls": "~0.6", "predis/predis": "~1.0" }, @@ -24,11 +24,14 @@ "doctrine/common": ">2.2,<2.4" }, "autoload": { - "psr-0": { "Doctrine\\Common\\Cache\\": "lib/" } + "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } + }, + "autoload-dev": { + "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" } }, "extra": { "branch-alias": { - "dev-master": "1.5.x-dev" + "dev-master": "1.6.x-dev" } } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php index abd5e71c..0dfbd6a1 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php @@ -22,13 +22,14 @@ /** * APC cache provider. * - * @link www.doctrine-project.org - * @since 2.0 - * @author Benjamin Eberlei - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie + * @link www.doctrine-project.org + * @deprecated since version 1.6, use ApcuCache instead + * @since 2.0 + * @author Benjamin Eberlei + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author David Abdemoulaie */ class ApcCache extends CacheProvider { @@ -53,7 +54,7 @@ protected function doContains($id) */ protected function doSave($id, $data, $lifeTime = 0) { - return (bool) apc_store($id, $data, (int) $lifeTime); + return apc_store($id, $data, $lifeTime); } /** @@ -61,7 +62,8 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - return apc_delete($id); + // apc_delete returns false if the id does not exist + return apc_delete($id) || ! apc_exists($id); } /** @@ -77,7 +79,17 @@ protected function doFlush() */ protected function doFetchMultiple(array $keys) { - return apc_fetch($keys); + return apc_fetch($keys) ?: []; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $result = apc_store($keysAndValues, null, $lifetime); + + return empty($result); } /** diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php new file mode 100644 index 00000000..2a91752b --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php @@ -0,0 +1,106 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * APCu cache provider. + * + * @link www.doctrine-project.org + * @since 1.6 + * @author Kévin Dunglas + */ +class ApcuCache extends CacheProvider +{ + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return apcu_fetch($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return apcu_exists($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return apcu_store($id, $data, $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + // apcu_delete returns false if the id does not exist + return apcu_delete($id) || ! apcu_exists($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return apcu_clear_cache(); + } + + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + return apcu_fetch($keys) ?: []; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $result = apcu_store($keysAndValues, null, $lifetime); + + return empty($result); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $info = apcu_cache_info(true); + $sma = apcu_sma_info(); + + return array( + Cache::STATS_HITS => $info['num_hits'], + Cache::STATS_MISSES => $info['num_misses'], + Cache::STATS_UPTIME => $info['start_time'], + Cache::STATS_MEMORY_USAGE => $info['mem_size'], + Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], + ); + } +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php index 31a07290..6610cc21 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php @@ -33,16 +33,47 @@ class ArrayCache extends CacheProvider { /** - * @var array $data + * @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool */ - private $data = array(); + private $data = []; + + /** + * @var int + */ + private $hitsCount = 0; + + /** + * @var int + */ + private $missesCount = 0; + + /** + * @var int + */ + private $upTime; + + /** + * {@inheritdoc} + */ + public function __construct() + { + $this->upTime = time(); + } /** * {@inheritdoc} */ protected function doFetch($id) { - return $this->doContains($id) ? $this->data[$id] : false; + if (! $this->doContains($id)) { + $this->missesCount += 1; + + return false; + } + + $this->hitsCount += 1; + + return $this->data[$id][0]; } /** @@ -50,8 +81,19 @@ protected function doFetch($id) */ protected function doContains($id) { - // isset() is required for performance optimizations, to avoid unnecessary function calls to array_key_exists. - return isset($this->data[$id]) || array_key_exists($id, $this->data); + if (! isset($this->data[$id])) { + return false; + } + + $expiration = $this->data[$id][1]; + + if ($expiration && $expiration < time()) { + $this->doDelete($id); + + return false; + } + + return true; } /** @@ -59,7 +101,7 @@ protected function doContains($id) */ protected function doSave($id, $data, $lifeTime = 0) { - $this->data[$id] = $data; + $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false]; return true; } @@ -79,7 +121,7 @@ protected function doDelete($id) */ protected function doFlush() { - $this->data = array(); + $this->data = []; return true; } @@ -89,6 +131,12 @@ protected function doFlush() */ protected function doGetStats() { - return null; + return [ + Cache::STATS_HITS => $this->hitsCount, + Cache::STATS_MISSES => $this->missesCount, + Cache::STATS_UPTIME => $this->upTime, + Cache::STATS_MEMORY_USAGE => null, + Cache::STATS_MEMORY_AVAILABLE => null, + ]; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php index 205a1232..89fe3230 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php @@ -59,19 +59,22 @@ public function fetch($id); * * @param string $id The cache id of the entry to check for. * - * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise. + * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. */ public function contains($id); /** * Puts data into the cache. * + * If a cache entry with the given id already exists, its data will be replaced. + * * @param string $id The cache id. * @param mixed $data The cache entry/data. - * @param int $lifeTime The cache lifetime. - * If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime). + * @param int $lifeTime The lifetime in number of seconds for this cache entry. + * If zero (the default), the entry never expires (although it may be deleted from the cache + * to make place for other entries). * - * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise. + * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise. */ public function save($id, $data, $lifeTime = 0); @@ -80,7 +83,8 @@ public function save($id, $data, $lifeTime = 0); * * @param string $id The cache id. * - * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. + * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise. + * Deleting a non-existing entry is considered successful. */ public function delete($id); diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php index a172a4ce..9f579237 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php @@ -29,7 +29,7 @@ * @author Roman Borschel * @author Fabio B. Silva */ -abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache +abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache { const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]'; @@ -83,6 +83,10 @@ public function fetch($id) */ public function fetchMultiple(array $keys) { + if (empty($keys)) { + return array(); + } + // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys $namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys)); $items = $this->doFetchMultiple($namespacedKeys); @@ -91,7 +95,7 @@ public function fetchMultiple(array $keys) // no internal array function supports this sort of mapping: needs to be iterative // this filters and combines keys in one pass foreach ($namespacedKeys as $requestedKey => $namespacedKey) { - if (isset($items[$namespacedKey])) { + if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) { $foundItems[$requestedKey] = $items[$namespacedKey]; } } @@ -99,6 +103,19 @@ public function fetchMultiple(array $keys) return $foundItems; } + /** + * {@inheritdoc} + */ + public function saveMultiple(array $keysAndValues, $lifetime = 0) + { + $namespacedKeysAndValues = array(); + foreach ($keysAndValues as $key => $value) { + $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value; + } + + return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime); + } + /** * {@inheritdoc} */ @@ -147,9 +164,13 @@ public function deleteAll() $namespaceCacheKey = $this->getNamespaceCacheKey(); $namespaceVersion = $this->getNamespaceVersion() + 1; - $this->namespaceVersion = $namespaceVersion; + if ($this->doSave($namespaceCacheKey, $namespaceVersion)) { + $this->namespaceVersion = $namespaceVersion; + + return true; + } - return $this->doSave($namespaceCacheKey, $namespaceVersion); + return false; } /** @@ -188,15 +209,7 @@ private function getNamespaceVersion() } $namespaceCacheKey = $this->getNamespaceCacheKey(); - $namespaceVersion = $this->doFetch($namespaceCacheKey); - - if (false === $namespaceVersion) { - $namespaceVersion = 1; - - $this->doSave($namespaceCacheKey, $namespaceVersion); - } - - $this->namespaceVersion = $namespaceVersion; + $this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1; return $this->namespaceVersion; } @@ -211,8 +224,8 @@ protected function doFetchMultiple(array $keys) { $returnValues = array(); - foreach ($keys as $index => $key) { - if (false !== ($item = $this->doFetch($key))) { + foreach ($keys as $key) { + if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) { $returnValues[$key] = $item; } } @@ -225,7 +238,7 @@ protected function doFetchMultiple(array $keys) * * @param string $id The id of the cache entry to fetch. * - * @return mixed|boolean The cached data or FALSE, if no cache entry exists for the given id. + * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id. */ abstract protected function doFetch($id); @@ -234,10 +247,32 @@ abstract protected function doFetch($id); * * @param string $id The cache id of the entry to check for. * - * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise. + * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. */ abstract protected function doContains($id); + /** + * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it. + * + * @param array $keysAndValues Array of keys and values to save in cache + * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these + * cache entries (0 => infinite lifeTime). + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't. + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $success = true; + + foreach ($keysAndValues as $key => $value) { + if (!$this->doSave($key, $value, $lifetime)) { + $success = false; + } + } + + return $success; + } + /** * Puts data into the cache. * @@ -246,7 +281,7 @@ abstract protected function doContains($id); * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this * cache entry (0 => infinite lifeTime). * - * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise. + * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise. */ abstract protected function doSave($id, $data, $lifeTime = 0); @@ -255,14 +290,14 @@ abstract protected function doSave($id, $data, $lifeTime = 0); * * @param string $id The cache id. * - * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise. + * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise. */ abstract protected function doDelete($id); /** * Flushes all cache entries. * - * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise. + * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise. */ abstract protected function doFlush(); diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php index d7b4358d..3a91eaf3 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php @@ -34,7 +34,7 @@ interface ClearableCache /** * Deletes all cache entries in the current cache namespace. * - * @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise. + * @return bool TRUE if the cache entries were successfully deleted, FALSE otherwise. */ public function deleteAll(); } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php index 9ad3ce2c..b2e0427e 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php @@ -24,6 +24,7 @@ * * @since 2.3 * @author Fabio B. Silva + * @author Tobias Schultze */ abstract class FileCache extends CacheProvider { @@ -42,22 +43,24 @@ abstract class FileCache extends CacheProvider private $extension; /** - * @var string[] regular expressions for replacing disallowed characters in file name + * @var int */ - private $disallowedCharacterPatterns = array( - '/\-/', // replaced to disambiguate original `-` and `-` derived from replacements - '/[^a-zA-Z0-9\-_\[\]]/' // also excludes non-ascii chars (not supported, depending on FS) - ); + private $umask; /** - * @var string[] replacements for disallowed file characters + * @var int */ - private $replacementCharacters = array('__', '-'); + private $directoryStringLength; /** * @var int */ - private $umask; + private $extensionStringLength; + + /** + * @var bool + */ + private $isRunningOnWindows; /** * Constructor. @@ -95,6 +98,10 @@ public function __construct($directory, $extension = '', $umask = 0002) // YES, this needs to be *after* createPathIfNeeded() $this->directory = realpath($directory); $this->extension = (string) $extension; + + $this->directoryStringLength = strlen($this->directory); + $this->extensionStringLength = strlen($this->extension); + $this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD'); } /** @@ -110,7 +117,7 @@ public function getDirectory() /** * Gets the cache file extension. * - * @return string|null + * @return string */ public function getExtension() { @@ -124,11 +131,29 @@ public function getExtension() */ protected function getFilename($id) { + $hash = hash('sha256', $id); + + // This ensures that the filename is unique and that there are no invalid chars in it. + if ( + '' === $id + || ((strlen($id) * 2 + $this->extensionStringLength) > 255) + || ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258) + ) { + // Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited + // to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API. + // And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259. + // So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents + // collisions between the hash and bin2hex. + $filename = '_' . $hash; + } else { + $filename = bin2hex($id); + } + return $this->directory . DIRECTORY_SEPARATOR - . implode(str_split(hash('sha256', $id), 2), DIRECTORY_SEPARATOR) + . substr($hash, 0, 2) . DIRECTORY_SEPARATOR - . preg_replace($this->disallowedCharacterPatterns, $this->replacementCharacters, $id) + . $filename . $this->extension; } @@ -137,7 +162,9 @@ protected function getFilename($id) */ protected function doDelete($id) { - return @unlink($this->getFilename($id)); + $filename = $this->getFilename($id); + + return @unlink($filename) || ! file_exists($filename); } /** @@ -146,7 +173,16 @@ protected function doDelete($id) protected function doFlush() { foreach ($this->getIterator() as $name => $file) { - @unlink($name); + if ($file->isDir()) { + // Remove the intermediate directories which have been created to balance the tree. It only takes effect + // if the directory is empty. If several caches share the same directory but with different file extensions, + // the other ones are not removed. + @rmdir($name); + } elseif ($this->isFilenameEndingWithExtension($name)) { + // If an extension is set, only remove files which end with the given extension. + // If no extension is set, we have no other choice than removing everything. + @unlink($name); + } } return true; @@ -158,8 +194,10 @@ protected function doFlush() protected function doGetStats() { $usage = 0; - foreach ($this->getIterator() as $file) { - $usage += $file->getSize(); + foreach ($this->getIterator() as $name => $file) { + if (! $file->isDir() && $this->isFilenameEndingWithExtension($name)) { + $usage += $file->getSize(); + } } $free = disk_free_space($this->directory); @@ -229,9 +267,20 @@ protected function writeFile($filename, $content) */ private function getIterator() { - return new \RegexIterator( - new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory)), - '/^.+' . preg_quote($this->extension, '/') . '$/i' + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST ); } + + /** + * @param string $name The filename + * + * @return bool + */ + private function isFilenameEndingWithExtension($name) + { + return '' === $this->extension + || strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength); + } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php index 29d5e074..d988294f 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php @@ -53,7 +53,7 @@ protected function doFetch($id) $resource = fopen($filename, "r"); if (false !== ($line = fgets($resource))) { - $lifetime = (integer) $line; + $lifetime = (int) $line; } if ($lifetime !== 0 && $lifetime < time()) { @@ -86,7 +86,7 @@ protected function doContains($id) $resource = fopen($filename, "r"); if (false !== ($line = fgets($resource))) { - $lifetime = (integer) $line; + $lifetime = (int) $line; } fclose($resource); diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php index e4e606b1..4311d4f5 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php @@ -31,7 +31,7 @@ interface FlushableCache /** * Flushes all cache entries, globally. * - * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise. + * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise. */ public function flushAll(); } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php index c5098fd9..8afaeeac 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php @@ -97,7 +97,8 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - return $this->memcache->delete($id); + // Memcache::delete() returns false if entry does not exist + return $this->memcache->delete($id) || ! $this->doContains($id); } /** diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php index 040c26c0..dc4016b5 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php @@ -74,7 +74,19 @@ protected function doFetch($id) */ protected function doFetchMultiple(array $keys) { - return $this->memcached->getMulti($keys); + return $this->memcached->getMulti($keys) ?: []; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + if ($lifetime > 30 * 24 * 3600) { + $lifetime = time() + $lifetime; + } + + return $this->memcached->setMulti($keysAndValues, $lifetime); } /** @@ -82,7 +94,8 @@ protected function doFetchMultiple(array $keys) */ protected function doContains($id) { - return (false !== $this->memcached->get($id)); + return false !== $this->memcached->get($id) + || $this->memcached->getResultCode() !== Memcached::RES_NOTFOUND; } /** @@ -101,7 +114,8 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - return $this->memcached->delete($id); + return $this->memcached->delete($id) + || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND; } /** diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php index 0c7ac0a0..75fe0ca1 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php @@ -21,6 +21,7 @@ use MongoBinData; use MongoCollection; +use MongoCursorException; use MongoDate; /** @@ -41,7 +42,7 @@ class MongoDBCache extends CacheProvider * cache entry should expire. * * With MongoDB 2.2+, entries can be automatically deleted by MongoDB by - * indexing this field wit the "expireAfterSeconds" option equal to zero. + * indexing this field with the "expireAfterSeconds" option equal to zero. * This will direct MongoDB to regularly query for and delete any entries * whose date is older than the current time. Entries without a date value * in this field will be ignored. @@ -119,14 +120,18 @@ protected function doContains($id) */ protected function doSave($id, $data, $lifeTime = 0) { - $result = $this->collection->update( - array('_id' => $id), - array('$set' => array( - self::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null), - self::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY), - )), - array('upsert' => true, 'multiple' => false) - ); + try { + $result = $this->collection->update( + array('_id' => $id), + array('$set' => array( + self::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null), + self::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY), + )), + array('upsert' => true, 'multiple' => false) + ); + } catch (MongoCursorException $e) { + return false; + } return isset($result['ok']) ? $result['ok'] == 1 : true; } @@ -138,7 +143,7 @@ protected function doDelete($id) { $result = $this->collection->remove(array('_id' => $id)); - return isset($result['n']) ? $result['n'] == 1 : true; + return isset($result['ok']) ? $result['ok'] == 1 : true; } /** @@ -170,8 +175,8 @@ protected function doGetStats() return array( Cache::STATS_HITS => null, Cache::STATS_MISSES => null, - Cache::STATS_UPTIME => (isset($serverStatus['uptime']) ? (integer) $serverStatus['uptime'] : null), - Cache::STATS_MEMORY_USAGE => (isset($collStats['size']) ? (integer) $collStats['size'] : null), + Cache::STATS_UPTIME => (isset($serverStatus['uptime']) ? (int) $serverStatus['uptime'] : null), + Cache::STATS_MEMORY_USAGE => (isset($collStats['size']) ? (int) $collStats['size'] : null), Cache::STATS_MEMORY_AVAILABLE => null, ); } @@ -180,7 +185,8 @@ protected function doGetStats() * Check if the document is expired. * * @param array $document - * @return boolean + * + * @return bool */ private function isExpired(array $document) { diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php new file mode 100644 index 00000000..bf87ea9f --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php @@ -0,0 +1,41 @@ +. + */ + +namespace Doctrine\Common\Cache; + +/** + * Interface for cache drivers that allows to put many items at once. + * + * @link www.doctrine-project.org + * @since 1.6 + * @author Daniel Gorgan + */ +interface MultiPutCache +{ + /** + * Returns a boolean value indicating if the operation succeeded. + * + * @param array $keysAndValues Array of keys and values to save in cache + * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these + * cache entries (0 => infinite lifeTime). + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't. + */ + function saveMultiple(array $keysAndValues, $lifetime = 0); +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php index 823477e6..bcd27497 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php @@ -2,7 +2,7 @@ namespace Doctrine\Common\Cache; -use Predis\Client; +use Predis\ClientInterface; /** * Predis cache provider. @@ -12,16 +12,16 @@ class PredisCache extends CacheProvider { /** - * @var Client + * @var ClientInterface */ private $client; /** - * @param Client $client + * @param ClientInterface $client * * @return void */ - public function __construct(Client $client) + public function __construct(ClientInterface $client) { $this->client = $client; } @@ -46,14 +46,43 @@ protected function doFetchMultiple(array $keys) { $fetchedItems = call_user_func_array(array($this->client, 'mget'), $keys); - return array_filter(array_combine($keys, array_map('unserialize', $fetchedItems))); + return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems))); } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + if ($lifetime) { + $success = true; + + // Keys have lifetime, use SETEX for each of them + foreach ($keysAndValues as $key => $value) { + $response = $this->client->setex($key, $lifetime, serialize($value)); + + if ((string) $response != 'OK') { + $success = false; + } + } + + return $success; + } + + // No lifetime, use MSET + $response = $this->client->mset(array_map(function ($value) { + return serialize($value); + }, $keysAndValues)); + + return (string) $response == 'OK'; + } + /** * {@inheritdoc} */ protected function doContains($id) { - return $this->client->exists($id); + return (bool) $this->client->exists($id); } /** @@ -76,7 +105,7 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - return $this->client->del($id) > 0; + return $this->client->del($id) >= 0; } /** diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php index 50d7c917..22add667 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php @@ -71,7 +71,40 @@ protected function doFetch($id) */ protected function doFetchMultiple(array $keys) { - return array_filter(array_combine($keys, $this->redis->mget($keys))); + $fetchedItems = array_combine($keys, $this->redis->mget($keys)); + + // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data. + $foundItems = array(); + + foreach ($fetchedItems as $key => $value) { + if (false !== $value || $this->redis->exists($key)) { + $foundItems[$key] = $value; + } + } + + return $foundItems; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + if ($lifetime) { + $success = true; + + // Keys have lifetime, use SETEX for each of them + foreach ($keysAndValues as $key => $value) { + if (!$this->redis->setex($key, $lifetime, $value)) { + $success = false; + } + } + + return $success; + } + + // No lifetime, use MSET + return (bool) $this->redis->mset($keysAndValues); } /** @@ -99,7 +132,7 @@ protected function doSave($id, $data, $lifeTime = 0) */ protected function doDelete($id) { - return $this->redis->delete($id) > 0; + return $this->redis->delete($id) >= 0; } /** @@ -137,6 +170,11 @@ protected function getSerializerValue() if (defined('HHVM_VERSION')) { return Redis::SERIALIZER_PHP; } - return defined('Redis::SERIALIZER_IGBINARY') ? Redis::SERIALIZER_IGBINARY : Redis::SERIALIZER_PHP; + + if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) { + return Redis::SERIALIZER_IGBINARY; + } + + return Redis::SERIALIZER_PHP; } } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php index 8bb6b4bf..0baa3f25 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php @@ -202,7 +202,7 @@ protected function doGetStats() * * @param \Riak\Object $object * - * @return boolean + * @return bool */ private function isExpired(Object $object) { diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php index b12978c4..0bf6e4d4 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php @@ -98,7 +98,7 @@ protected function doFetch($id) */ protected function doContains($id) { - return (boolean) $this->findById($id, false); + return null !== $this->findById($id, false); } /** @@ -157,7 +157,7 @@ protected function doGetStats() * Find a single row by ID. * * @param mixed $id - * @param boolean $includeData + * @param bool $includeData * * @return array|null */ @@ -208,7 +208,8 @@ private function getFields() * Check if the item is expired. * * @param array $item - * @return boolean + * + * @return bool */ private function isExpired(array $item) { diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php index d742fa08..a6399ecc 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php @@ -21,5 +21,5 @@ class Version { - const VERSION = '1.4.0-DEV'; + const VERSION = '1.6.1-DEV'; } diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php index ae327729..8a250b29 100644 --- a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php @@ -53,7 +53,7 @@ protected function doContains($id) */ protected function doSave($id, $data, $lifeTime = 0) { - return (bool) wincache_ucache_set($id, $data, (int) $lifeTime); + return wincache_ucache_set($id, $data, $lifeTime); } /** @@ -72,6 +72,24 @@ protected function doFlush() return wincache_ucache_clear(); } + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + return wincache_ucache_get($keys); + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $result = wincache_ucache_set($keysAndValues, null, $lifetime); + + return empty($result); + } + /** * {@inheritdoc} */ diff --git a/vendor/doctrine/cache/phpunit.xml.dist b/vendor/doctrine/cache/phpunit.xml.dist index 34d7f4c8..40cc24de 100644 --- a/vendor/doctrine/cache/phpunit.xml.dist +++ b/vendor/doctrine/cache/phpunit.xml.dist @@ -1,16 +1,16 @@ - + + + + ./tests/Doctrine/ diff --git a/vendor/doctrine/common/.gitignore b/vendor/doctrine/common/.gitignore deleted file mode 100644 index b15c686b..00000000 --- a/vendor/doctrine/common/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -build/ -logs/ -reports/ -dist/ -tests/Doctrine/Tests/Common/Proxy/generated/ -vendor/ -.idea -composer.lock -doctrine-common-*.tar -doctrine-common-*.tar.gz diff --git a/vendor/doctrine/common/.gitmodules b/vendor/doctrine/common/.gitmodules deleted file mode 100644 index 51f08435..00000000 --- a/vendor/doctrine/common/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/vendor/doctrine-build-common"] - path = lib/vendor/doctrine-build-common - url = git://github.com/doctrine/doctrine-build-common.git diff --git a/vendor/doctrine/common/.travis.yml b/vendor/doctrine/common/.travis.yml deleted file mode 100644 index 9c20a84b..00000000 --- a/vendor/doctrine/common/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: php - -sudo: false - -cache: - directory: - - $HOME/.composer/cache - -php: - - 5.3.3 - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - hhvm - -before_script: - - composer --prefer-source install - -script: - - ./vendor/bin/phpunit - -matrix: - allow_failures: - - php: 7.0 diff --git a/vendor/doctrine/common/LICENSE b/vendor/doctrine/common/LICENSE index 4a91f0bf..8c38cc1b 100644 --- a/vendor/doctrine/common/LICENSE +++ b/vendor/doctrine/common/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2006-2012 Doctrine Project +Copyright (c) 2006-2015 Doctrine Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/vendor/doctrine/common/build.properties b/vendor/doctrine/common/build.properties deleted file mode 100644 index ef51d207..00000000 --- a/vendor/doctrine/common/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Version class and file -project.version_class = Doctrine\\Common\\Version -project.version_file = lib/Doctrine/Common/Version.php diff --git a/vendor/doctrine/common/build.xml b/vendor/doctrine/common/build.xml deleted file mode 100644 index 429b7688..00000000 --- a/vendor/doctrine/common/build.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/doctrine/common/composer.json b/vendor/doctrine/common/composer.json index be42e7fe..a12495ab 100644 --- a/vendor/doctrine/common/composer.json +++ b/vendor/doctrine/common/composer.json @@ -13,26 +13,24 @@ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} ], "require": { - "php": ">=5.3.2", + "php": "~5.5|~7.0", "doctrine/inflector": "1.*", "doctrine/cache": "1.*", "doctrine/collections": "1.*", "doctrine/lexer": "1.*", "doctrine/annotations": "1.*" }, - "minimum-stability": "dev", "require-dev": { - "phpunit/phpunit": "~3.7" + "phpunit/phpunit": "~4.8|~5.0" }, "autoload": { - "psr-0": { "Doctrine\\Common\\": "lib/" } + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } }, "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } - }, - "archive": { - "exclude": ["!vendor", "tests", "*phpunit.xml", ".travis.yml", "build.xml", "build.properties", "composer.phar"] } } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php b/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php index d65b9a63..78eeb35d 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php @@ -153,7 +153,7 @@ public function getFileExtension() */ public function register() { - spl_autoload_register(array($this, 'loadClass')); + spl_autoload_register([$this, 'loadClass']); } /** @@ -163,7 +163,7 @@ public function register() */ public function unregister() { - spl_autoload_unregister(array($this, 'loadClass')); + spl_autoload_unregister([$this, 'loadClass']); } /** @@ -275,6 +275,6 @@ private static function typeExists($type, $autoload = false) { return class_exists($type, $autoload) || interface_exists($type, $autoload) - || (function_exists('trait_exists') && trait_exists($type, $autoload)); + || trait_exists($type, $autoload); } } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php b/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php index 69eb17ec..0ee04a15 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php @@ -38,7 +38,7 @@ class EventManager * * @var array */ - private $_listeners = array(); + private $_listeners = []; /** * Dispatches an event to all registered listeners. diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php index 33770f90..6da54223 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php @@ -141,7 +141,7 @@ public function getConnectionNames() */ public function getConnections() { - $connections = array(); + $connections = []; foreach ($this->connections as $name => $id) { $connections[$name] = $this->getService($id); } @@ -195,8 +195,13 @@ public function getManagerForClass($class) } $proxyClass = new \ReflectionClass($class); + if ($proxyClass->implementsInterface($this->proxyInterfaceName)) { - $class = $proxyClass->getParentClass()->getName(); + if (! $parentClass = $proxyClass->getParentClass()) { + return null; + } + + $class = $parentClass->getName(); } foreach ($this->managers as $id) { @@ -221,7 +226,7 @@ public function getManagerNames() */ public function getManagers() { - $dms = array(); + $dms = []; foreach ($this->managers as $name => $id) { $dms[$name] = $this->getService($id); } @@ -253,5 +258,7 @@ public function resetManager($name = null) // force the creation of a new document manager // if the current one is closed $this->resetService($this->managers[$name]); + + return $this->getManager($name); } } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php index 404fea91..cba424b0 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -53,7 +53,7 @@ abstract class AbstractClassMetadataFactory implements ClassMetadataFactory /** * @var ClassMetadata[] */ - private $loadedMetadata = array(); + private $loadedMetadata = []; /** * @var bool @@ -110,7 +110,7 @@ public function getAllMetadata() } $driver = $this->getDriver(); - $metadata = array(); + $metadata = []; foreach ($driver->getAllClassNames() as $className) { $metadata[] = $this->getMetadataFor($className); } @@ -208,7 +208,7 @@ public function getMetadataFor($className) try { if ($this->cacheDriver) { - if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) !== false) { + if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) instanceof ClassMetadata) { $this->loadedMetadata[$realClassName] = $cached; $this->wakeupReflection($cached, $this->getReflectionService()); @@ -277,7 +277,7 @@ public function setMetadataFor($className, $class) protected function getParentClasses($name) { // Collect parent classes, ignoring transient (not-mapped) classes. - $parentClasses = array(); + $parentClasses = []; foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) { if ( ! $this->getDriver()->isTransient($parentClass)) { $parentClasses[] = $parentClass; @@ -306,7 +306,7 @@ protected function loadMetadata($name) $this->initialize(); } - $loaded = array(); + $loaded = []; $parentClasses = $this->getParentClasses($name); $parentClasses[] = $name; @@ -314,7 +314,7 @@ protected function loadMetadata($name) // Move down the hierarchy of parent classes, starting from the topmost class $parent = null; $rootEntityFound = false; - $visited = array(); + $visited = []; $reflService = $this->getReflectionService(); foreach ($parentClasses as $className) { if (isset($this->loadedMetadata[$className])) { diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php index 8bb574d9..deb82c0c 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php @@ -45,14 +45,14 @@ abstract class AnnotationDriver implements MappingDriver * * @var array */ - protected $paths = array(); + protected $paths = []; /** * The paths excluded from path where to look for mapping files. * * @var array */ - protected $excludePaths = array(); + protected $excludePaths = []; /** * The file extension of mapping documents. @@ -73,7 +73,7 @@ abstract class AnnotationDriver implements MappingDriver * * @var array */ - protected $entityAnnotationClasses = array(); + protected $entityAnnotationClasses = []; /** * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading @@ -200,8 +200,8 @@ public function getAllClassNames() throw MappingException::pathRequired(); } - $classes = array(); - $includedFiles = array(); + $classes = []; + $includedFiles = []; foreach ($this->paths as $path) { if ( ! is_dir($path)) { diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php index 58a740b5..6ed7f6d0 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php @@ -37,7 +37,7 @@ class DefaultFileLocator implements FileLocator * * @var array */ - protected $paths = array(); + protected $paths = []; /** * The file extension of mapping documents. @@ -125,7 +125,7 @@ public function findMappingFile($className) */ public function getAllClassNames($globalBasename) { - $classes = array(); + $classes = []; if ($this->paths) { foreach ($this->paths as $path) { diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php index ccc64faf..dc799d5c 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php @@ -145,11 +145,14 @@ public function getAllClassNames() $this->initialize(); } - $classNames = (array)$this->locator->getAllClassNames($this->globalBasename); - if ($this->classCache) { - $classNames = array_merge(array_keys($this->classCache), $classNames); + if (! $this->classCache) { + return (array) $this->locator->getAllClassNames($this->globalBasename); } - return $classNames; + + return array_merge( + array_keys($this->classCache), + (array) $this->locator->getAllClassNames($this->globalBasename) + ); } /** @@ -175,7 +178,7 @@ abstract protected function loadMappingFile($file); */ protected function initialize() { - $this->classCache = array(); + $this->classCache = []; if (null !== $this->globalBasename) { foreach ($this->locator->getPaths() as $path) { $file = $path.'/'.$this->globalBasename.$this->locator->getFileExtension(); diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php index 26a9f3e2..50d9785b 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php @@ -39,12 +39,12 @@ class MappingDriverChain implements MappingDriver * * @var MappingDriver|null */ - private $defaultDriver = null; + private $defaultDriver; /** * @var array */ - private $drivers = array(); + private $drivers = []; /** * Gets the default driver. @@ -117,8 +117,8 @@ public function loadMetadataForClass($className, ClassMetadata $metadata) */ public function getAllClassNames() { - $classNames = array(); - $driverClasses = array(); + $classNames = []; + $driverClasses = []; /* @var $driver MappingDriver */ foreach ($this->drivers AS $namespace => $driver) { diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php index 6df54b0f..efffa6aa 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php @@ -44,8 +44,7 @@ class PHPDriver extends FileDriver */ public function __construct($locator, $fileExtension = null) { - $fileExtension = ".php"; - parent::__construct($locator, $fileExtension); + parent::__construct($locator, '.php'); } /** @@ -54,6 +53,7 @@ public function __construct($locator, $fileExtension = null) public function loadMetadataForClass($className, ClassMetadata $metadata) { $this->metadata = $metadata; + $this->loadMappingFile($this->locator->findMappingFile($className)); } @@ -65,6 +65,6 @@ protected function loadMappingFile($file) $metadata = $this->metadata; include $file; - return array($metadata->getName() => $metadata); + return [$metadata->getName() => $metadata]; } } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php index df8f4770..8e37e5a7 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php @@ -40,7 +40,7 @@ class StaticPHPDriver implements MappingDriver * * @var array */ - private $paths = array(); + private $paths = []; /** * Map of all class names. @@ -93,8 +93,8 @@ public function getAllClassNames() throw MappingException::pathRequired(); } - $classes = array(); - $includedFiles = array(); + $classes = []; + $includedFiles = []; foreach ($this->paths as $path) { if (!is_dir($path)) { diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php index f3342656..4588cfec 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php @@ -37,14 +37,14 @@ class SymfonyFileLocator implements FileLocator * * @var array */ - protected $paths = array(); + protected $paths = []; /** * A map of mapping directory path to namespace prefix used to expand class shortnames. * * @var array */ - protected $prefixes = array(); + protected $prefixes = []; /** * File extension that is searched for. @@ -153,7 +153,9 @@ public function fileExists($className) } $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', $this->nsSeparator).$this->fileExtension; - return is_file($filename); + if (is_file($filename)) { + return true; + } } return false; @@ -164,7 +166,7 @@ public function fileExists($className) */ public function getAllClassNames($globalBasename = null) { - $classes = array(); + $classes = []; if ($this->paths) { foreach ((array) $this->paths as $path) { @@ -194,7 +196,7 @@ public function getAllClassNames($globalBasename = null) '\\' ); - $classes[] = $this->prefixes[$path] . $nsSuffix . '\\' .str_replace($this->nsSeparator, '\\', $fileName); + $classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' .str_replace($this->nsSeparator, '\\', $fileName); } else { $classes[] = str_replace($this->nsSeparator, '\\', $fileName); } @@ -230,8 +232,6 @@ public function findMappingFile($className) if (is_file($filename)) { return $filename; } - - throw MappingException::mappingFileNotFound($className, $filename); } throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->fileExtension); diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php index e5bcb06e..7d017664 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php @@ -31,7 +31,7 @@ class StaticReflectionService implements ReflectionService */ public function getParentClasses($class) { - return array(); + return []; } /** diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php index a35b71a2..990642e7 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php @@ -198,7 +198,7 @@ private function add($field, $args) throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'"); } if (!($this->$field instanceof Collection)) { - $this->$field = new ArrayCollection($this->$field ?: array()); + $this->$field = new ArrayCollection($this->$field ?: []); } $this->$field->add($args[0]); $this->completeOwningSide($field, $targetClass, $args[0]); diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php b/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php index bc546902..7eb216bf 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php @@ -87,7 +87,7 @@ abstract class AbstractProxyFactory /** * @var \Doctrine\Common\Proxy\ProxyDefinition[] */ - private $definitions = array(); + private $definitions = []; /** * @param \Doctrine\Common\Proxy\ProxyGenerator $proxyGenerator diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php b/vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php index c9d0e2cf..925dcd1b 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php @@ -58,10 +58,10 @@ class ProxyGenerator * * @var string[]|callable[] */ - protected $placeholders = array( - 'baseProxyInterface' => 'Doctrine\Common\Proxy\Proxy', + protected $placeholders = [ + 'baseProxyInterface' => Proxy::class, 'additionalProperties' => '', - ); + ]; /** * Template used as a blueprint to generate proxies. @@ -106,7 +106,7 @@ class extends \ implements \); + public static $lazyPropertiesDefaults = []; @@ -129,7 +129,7 @@ class extends \ implements \__initializer__ && $this->__initializer__->__invoke($this, \'__load\', array()); + $this->__initializer__ && $this->__initializer__->__invoke($this, \'__load\', []); } /** @@ -263,12 +263,12 @@ public function generateProxyClass(ClassMetadata $class, $fileName = false) preg_match_all('(<([a-zA-Z]+)>)', $this->proxyClassTemplate, $placeholderMatches); $placeholderMatches = array_combine($placeholderMatches[0], $placeholderMatches[1]); - $placeholders = array(); + $placeholders = []; foreach ($placeholderMatches as $placeholder => $name) { $placeholders[$placeholder] = isset($this->placeholders[$name]) ? $this->placeholders[$name] - : array($this, 'generate' . $name); + : [$this, 'generate' . $name]; } foreach ($placeholders as & $placeholder) { @@ -302,7 +302,7 @@ public function generateProxyClass(ClassMetadata $class, $fileName = false) $tmpFileName = $fileName . '.' . uniqid('', true); file_put_contents($tmpFileName, $proxyCode); - chmod($tmpFileName, 0664); + @chmod($tmpFileName, 0664); rename($tmpFileName, $fileName); } @@ -358,7 +358,7 @@ private function generateClassName(ClassMetadata $class) private function generateLazyPropertiesDefaults(ClassMetadata $class) { $lazyPublicProperties = $this->getLazyLoadedPublicProperties($class); - $values = array(); + $values = []; foreach ($lazyPublicProperties as $key => $value) { $values[] = var_export($key, true) . ' => ' . var_export($value, true); @@ -385,7 +385,7 @@ public function __construct($initializer = null, $cloner = null) { EOT; - $toUnset = array(); + $toUnset = []; foreach ($this->getLazyLoadedPublicProperties($class) as $lazyPublicProperty => $unused) { $toUnset[] = '$this->' . $lazyPublicProperty; @@ -443,7 +443,7 @@ public function {$returnReference}__get(\$name) if ( ! empty($lazyPublicProperties)) { $magicGet .= <<<'EOT' if (array_key_exists($name, $this->__getLazyProperties())) { - $this->__initializer__ && $this->__initializer__->__invoke($this, '__get', array($name)); + $this->__initializer__ && $this->__initializer__->__invoke($this, '__get', [$name]); return $this->$name; } @@ -454,7 +454,7 @@ public function {$returnReference}__get(\$name) if ($hasParentGet) { $magicGet .= <<<'EOT' - $this->__initializer__ && $this->__initializer__->__invoke($this, '__get', array($name)); + $this->__initializer__ && $this->__initializer__->__invoke($this, '__get', [$name]); return parent::__get($name); @@ -502,7 +502,7 @@ public function __set(\$name, \$value) if ( ! empty($lazyPublicProperties)) { $magicSet .= <<<'EOT' if (array_key_exists($name, $this->__getLazyProperties())) { - $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', array($name, $value)); + $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]); $this->$name = $value; @@ -515,7 +515,7 @@ public function __set(\$name, \$value) if ($hasParentSet) { $magicSet .= <<<'EOT' - $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', array($name, $value)); + $this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]); return parent::__set($name, $value); EOT; @@ -559,7 +559,7 @@ public function __isset(\$name) if ( ! empty($lazyPublicProperties)) { $magicIsset .= <<<'EOT' if (array_key_exists($name, $this->__getLazyProperties())) { - $this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', array($name)); + $this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', [$name]); return isset($this->$name); } @@ -570,7 +570,7 @@ public function __isset(\$name) if ($hasParentIsset) { $magicIsset .= <<<'EOT' - $this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', array($name)); + $this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', [$name]); return parent::__isset($name); @@ -605,7 +605,7 @@ public function __sleep() if ($hasParentSleep) { return $sleepImpl . <<<'EOT' - $properties = array_merge(array('__isInitialized__'), parent::__sleep()); + $properties = array_merge(['__isInitialized__'], parent::__sleep()); if ($this->__isInitialized__) { $properties = array_diff($properties, array_keys($this->__getLazyProperties())); @@ -616,7 +616,7 @@ public function __sleep() EOT; } - $allProperties = array('__isInitialized__'); + $allProperties = ['__isInitialized__']; /* @var $prop \ReflectionProperty */ foreach ($class->getReflectionClass()->getProperties() as $prop) { @@ -645,10 +645,10 @@ public function __sleep() return $sleepImpl . <<__isInitialized__) { - return array($allProperties); + return [$allProperties]; } - return array($protectedProperties); + return [$protectedProperties]; } EOT; } @@ -662,7 +662,7 @@ public function __sleep() */ private function generateWakeupImpl(ClassMetadata $class) { - $unsetPublicProperties = array(); + $unsetPublicProperties = []; $hasWakeup = $class->getReflectionClass()->hasMethod('__wakeup'); foreach (array_keys($this->getLazyLoadedPublicProperties($class)) as $lazyPublicProperty) { @@ -727,7 +727,7 @@ private function generateCloneImpl(ClassMetadata $class) */ public function __clone() { - \$this->__cloner__ && \$this->__cloner__->__invoke(\$this, '__clone', array()); + \$this->__cloner__ && \$this->__cloner__->__invoke(\$this, '__clone', []); $callParentClone } EOT; } @@ -742,16 +742,16 @@ public function __clone() private function generateMethods(ClassMetadata $class) { $methods = ''; - $methodNames = array(); + $methodNames = []; $reflectionMethods = $class->getReflectionClass()->getMethods(\ReflectionMethod::IS_PUBLIC); - $skippedMethods = array( + $skippedMethods = [ '__sleep' => true, '__clone' => true, '__wakeup' => true, '__get' => true, '__set' => true, '__isset' => true, - ); + ]; foreach ($reflectionMethods as $method) { $name = $method->getName(); @@ -778,12 +778,13 @@ private function generateMethods(ClassMetadata $class) } $methods .= $name . '(' . $this->buildParametersString($class, $method, $method->getParameters()) . ')'; + $methods .= $this->getMethodReturnType($method); $methods .= "\n" . ' {' . "\n"; if ($this->isShortIdentifierGetter($method, $class)) { $identifier = lcfirst(substr($name, 3)); $fieldType = $class->getTypeOfField($identifier); - $cast = in_array($fieldType, array('integer', 'smallint')) ? '(int) ' : ''; + $cast = in_array($fieldType, ['integer', 'smallint']) ? '(int) ' : ''; $methods .= ' if ($this->__isInitialized__ === false) {' . "\n"; $methods .= ' return ' . $cast . ' parent::' . $method->getName() . "();\n"; @@ -795,7 +796,7 @@ private function generateMethods(ClassMetadata $class) $methods .= "\n \$this->__initializer__ " . "&& \$this->__initializer__->__invoke(\$this, " . var_export($name, true) - . ", array(" . $invokeParamsString . "));" + . ", [" . $invokeParamsString . "]);" . "\n\n return parent::" . $name . '(' . $callParamsString . ');' . "\n" . ' }' . "\n"; } @@ -872,7 +873,7 @@ private function isShortIdentifierGetter($method, ClassMetadata $class) private function getLazyLoadedPublicProperties(ClassMetadata $class) { $defaultProperties = $class->getReflectionClass()->getDefaultProperties(); - $properties = array(); + $properties = []; foreach ($class->getReflectionClass()->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $name = $property->getName(); @@ -894,7 +895,7 @@ private function getLazyLoadedPublicProperties(ClassMetadata $class) */ private function buildParametersString(ClassMetadata $class, \ReflectionMethod $method, array $parameters) { - $parameterDefinitions = array(); + $parameterDefinitions = []; /* @var $param \ReflectionParameter */ foreach ($parameters as $param) { @@ -908,10 +909,8 @@ private function buildParametersString(ClassMetadata $class, \ReflectionMethod $ $parameterDefinition .= '&'; } - if (method_exists($param, 'isVariadic')) { - if ($param->isVariadic()) { - $parameterDefinition .= '...'; - } + if (method_exists($param, 'isVariadic') && $param->isVariadic()) { + $parameterDefinition .= '...'; } $parameters[] = '$' . $param->getName(); @@ -942,10 +941,14 @@ private function getParameterType(ClassMetadata $class, \ReflectionMethod $metho return 'array'; } - if (method_exists($parameter, 'isCallable') && $parameter->isCallable()) { + if ($parameter->isCallable()) { return 'callable'; } + if (method_exists($parameter, 'hasType') && $parameter->hasType() && $parameter->getType()->isBuiltin()) { + return (string) $parameter->getType(); + } + try { $parameterClass = $parameter->getClass(); @@ -990,10 +993,8 @@ private function getParameterNamesForParentCall(array $parameters) function (\ReflectionParameter $parameter) { $name = ''; - if (method_exists($parameter, 'isVariadic')) { - if ($parameter->isVariadic()) { - $name .= '...'; - } + if (method_exists($parameter, 'isVariadic') && $parameter->isVariadic()) { + $name .= '...'; } $name .= '$' . $parameter->getName(); @@ -1003,4 +1004,34 @@ function (\ReflectionParameter $parameter) { $parameters ); } + + /** + * @Param \ReflectionMethod $method + * + * @return string + */ + private function getMethodReturnType(\ReflectionMethod $method) + { + if (! (method_exists($method, 'hasReturnType') && $method->hasReturnType())) { + return ''; + } + + $returnType = $method->getReturnType(); + + if ($returnType->isBuiltin()) { + return ': ' . $returnType; + } + + $nameLower = strtolower((string) $returnType); + + if ('self' === $nameLower) { + return ': \\' . $method->getDeclaringClass()->getName(); + } + + if ('parent' === $nameLower) { + return ': \\' . $method->getDeclaringClass()->getParentClass()->getName(); + } + + return ': \\' . (string) $returnType; + } } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionClass.php b/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionClass.php index b65979ad..2d0f5b00 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionClass.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionClass.php @@ -402,7 +402,7 @@ public function newInstance($args) /** * {@inheritDoc} */ - public function newInstanceArgs(array $args = array()) + public function newInstanceArgs(array $args = []) { throw new ReflectionException('Method not implemented'); } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php b/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php index 922404d9..c48e9ba7 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php @@ -69,18 +69,18 @@ class StaticReflectionParser implements ReflectionProviderInterface * * @var array */ - protected $useStatements = array(); + protected $useStatements = []; /** * The docComment of the class. * * @var string */ - protected $docComment = array( + protected $docComment = [ 'class' => '', - 'property' => array(), - 'method' => array() - ); + 'property' => [], + 'method' => [] + ]; /** * The name of the class this class extends, if any. diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionProperty.php b/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionProperty.php index 79b40d4a..7f6522bb 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionProperty.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionProperty.php @@ -91,7 +91,7 @@ public function getUseStatements() /** * {@inheritDoc} */ - public static function export ($class, $name, $return = false) + public static function export($class, $name, $return = false) { throw new ReflectionException('Method not implemented'); } @@ -155,7 +155,7 @@ public function isStatic() /** * {@inheritDoc} */ - public function setAccessible ($accessible) + public function setAccessible($accessible) { throw new ReflectionException('Method not implemented'); } @@ -163,7 +163,7 @@ public function setAccessible ($accessible) /** * {@inheritDoc} */ - public function setValue ($object, $value = null) + public function setValue($object, $value = null) { throw new ReflectionException('Method not implemented'); } diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php b/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php index 0959ce5d..7f675328 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php @@ -19,6 +19,7 @@ namespace Doctrine\Common\Util; +use Doctrine\Common\Collections\Collection; use Doctrine\Common\Persistence\Proxy; /** @@ -95,13 +96,13 @@ public static function export($var, $maxDepth) $return = null; $isObj = is_object($var); - if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) { + if ($var instanceof Collection) { $var = $var->toArray(); } if ($maxDepth) { if (is_array($var)) { - $return = array(); + $return = []; foreach ($var as $k => $v) { $return[$k] = self::export($v, $maxDepth - 1); diff --git a/vendor/doctrine/common/lib/Doctrine/Common/Version.php b/vendor/doctrine/common/lib/Doctrine/Common/Version.php index 80c1fbf7..872f169a 100644 --- a/vendor/doctrine/common/lib/Doctrine/Common/Version.php +++ b/vendor/doctrine/common/lib/Doctrine/Common/Version.php @@ -34,7 +34,7 @@ class Version /** * Current Doctrine Version. */ - const VERSION = '2.6.0-DEV'; + const VERSION = '2.6.2-DEV'; /** * Compares a Doctrine version with the current one. diff --git a/vendor/doctrine/common/phpunit.xml.dist b/vendor/doctrine/common/phpunit.xml.dist deleted file mode 100644 index f6fcf849..00000000 --- a/vendor/doctrine/common/phpunit.xml.dist +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - ./tests/Doctrine/ - - - - - - ./lib/Doctrine/ - - - diff --git a/vendor/doctrine/inflector/.travis.yml b/vendor/doctrine/inflector/.travis.yml index 6b1d8ffd..9ec68f76 100644 --- a/vendor/doctrine/inflector/.travis.yml +++ b/vendor/doctrine/inflector/.travis.yml @@ -1,11 +1,21 @@ language: php +sudo: false + +cache: + directory: + - $HOME/.composer/cache + php: - 5.3 - 5.4 - 5.5 - 5.6 + - 7.0 - hhvm install: - - composer --prefer-source install + - composer install -n + +script: + - phpunit diff --git a/vendor/doctrine/inflector/LICENSE b/vendor/doctrine/inflector/LICENSE index 5e781fce..8c38cc1b 100644 --- a/vendor/doctrine/inflector/LICENSE +++ b/vendor/doctrine/inflector/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2006-2013 Doctrine Project +Copyright (c) 2006-2015 Doctrine Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/vendor/doctrine/inflector/composer.json b/vendor/doctrine/inflector/composer.json index a29c68cf..7e5b2efb 100644 --- a/vendor/doctrine/inflector/composer.json +++ b/vendor/doctrine/inflector/composer.json @@ -23,7 +23,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } } } diff --git a/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php index b007b217..a53828ab 100644 --- a/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php +++ b/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php @@ -56,11 +56,12 @@ class Inflector '/(p)erson$/i' => '\1eople', '/(m)an$/i' => '\1en', '/(c)hild$/i' => '\1hildren', - '/(buffal|tomat)o$/i' => '\1\2oes', + '/(f)oot$/i' => '\1eet', + '/(buffal|her|potat|tomat|volcan)o$/i' => '\1\2oes', '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i', '/us$/i' => 'uses', '/(alias)$/i' => '\1es', - '/(ax|cris|test)is$/i' => '\1es', + '/(analys|ax|cris|test|thes)is$/i' => '\1es', '/s$/' => 's', '/^$/' => '', '/$/' => 's', @@ -70,27 +71,42 @@ class Inflector ), 'irregular' => array( 'atlas' => 'atlases', + 'axe' => 'axes', 'beef' => 'beefs', 'brother' => 'brothers', 'cafe' => 'cafes', + 'chateau' => 'chateaux', 'child' => 'children', 'cookie' => 'cookies', 'corpus' => 'corpuses', 'cow' => 'cows', - 'criteria' => 'criterion', + 'criterion' => 'criteria', + 'curriculum' => 'curricula', + 'demo' => 'demos', + 'domino' => 'dominoes', + 'echo' => 'echoes', + 'foot' => 'feet', + 'fungus' => 'fungi', 'ganglion' => 'ganglions', 'genie' => 'genies', 'genus' => 'genera', 'graffito' => 'graffiti', + 'hippopotamus' => 'hippopotami', 'hoof' => 'hoofs', 'human' => 'humans', + 'iris' => 'irises', + 'leaf' => 'leaves', 'loaf' => 'loaves', 'man' => 'men', + 'medium' => 'media', + 'memorandum' => 'memoranda', 'money' => 'monies', 'mongoose' => 'mongooses', + 'motto' => 'mottoes', 'move' => 'moves', 'mythos' => 'mythoi', 'niche' => 'niches', + 'nucleus' => 'nuclei', 'numen' => 'numina', 'occiput' => 'occiputs', 'octopus' => 'octopuses', @@ -98,11 +114,19 @@ class Inflector 'ox' => 'oxen', 'penis' => 'penises', 'person' => 'people', + 'plateau' => 'plateaux', + 'runner-up' => 'runners-up', 'sex' => 'sexes', 'soliloquy' => 'soliloquies', + 'son-in-law' => 'sons-in-law', + 'syllabus' => 'syllabi', 'testis' => 'testes', + 'thief' => 'thieves', + 'tooth' => 'teeth', + 'tornado' => 'tornadoes', 'trilby' => 'trilbys', 'turf' => 'turfs', + 'volcano' => 'volcanoes', ) ); @@ -120,9 +144,10 @@ class Inflector '/(vert|ind)ices$/i' => '\1ex', '/^(ox)en/i' => '\1', '/(alias)(es)*$/i' => '\1', + '/(buffal|her|potat|tomat|volcan)oes$/i' => '\1o', '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', '/([ftw]ax)es/i' => '\1', - '/(cris|ax|test)es$/i' => '\1is', + '/(analys|ax|cris|test|thes)es$/i' => '\1is', '/(shoe|slave)s$/i' => '\1', '/(o)es$/i' => '\1', '/ouses$/' => 'ouse', @@ -143,6 +168,7 @@ class Inflector '/(p)eople$/i' => '\1\2erson', '/(m)en$/i' => '\1an', '/(c)hildren$/i' => '\1\2hild', + '/(f)eet$/i' => '\1oot', '/(n)ews$/i' => '\1\2ews', '/eaus$/' => 'eau', '/^(.*us)$/' => '\\1', @@ -159,10 +185,15 @@ class Inflector '.*ss', ), 'irregular' => array( - 'criterion' => 'criteria', - 'curves' => 'curve', - 'foes' => 'foe', - 'waves' => 'wave', + 'criteria' => 'criterion', + 'curves' => 'curve', + 'emphases' => 'emphasis', + 'foes' => 'foe', + 'hoaxes' => 'hoax', + 'media' => 'medium', + 'neuroses' => 'neurosis', + 'waves' => 'wave', + 'oases' => 'oasis', ) ); @@ -236,6 +267,42 @@ public static function camelize($word) return lcfirst(self::classify($word)); } + /** + * Uppercases words with configurable delimeters between words. + * + * Takes a string and capitalizes all of the words, like PHP's built-in + * ucwords function. This extends that behavior, however, by allowing the + * word delimeters to be configured, rather than only separating on + * whitespace. + * + * Here is an example: + * + * + * + * + * @param string $string The string to operate on. + * @param string $delimiters A list of word separators. + * + * @return string The string with all delimeter-separated words capitalized. + */ + public static function ucwords($string, $delimiters = " \n\t\r\0\x0B-") + { + return preg_replace_callback( + '/[^' . preg_quote($delimiters, '/') . ']+/', + function($matches) { + return ucfirst($matches[0]); + }, + $string + ); + } + /** * Clears Inflectors inflected value caches, and resets the inflection * rules to the initial values. diff --git a/vendor/egulias/email-validator/.travis.yml b/vendor/egulias/email-validator/.travis.yml index f25de0fb..86d52b23 100644 --- a/vendor/egulias/email-validator/.travis.yml +++ b/vendor/egulias/email-validator/.travis.yml @@ -12,15 +12,17 @@ php: env: global: - - deps=no + - deps=high matrix: fast_finish: true include: - php: 5.3 env: deps=low - - php: 5.6 - env: deps=high + - php: 5.4 + env: deps=no + - php: 5.5 + env: deps=no install: - if [ "$deps" = "no" ]; then composer install; fi @@ -31,6 +33,3 @@ script: - mkdir -p build/logs - phpunit --coverage-clover build/logs/clover.xml -after_script: - - php vendor/bin/coveralls - diff --git a/vendor/egulias/email-validator/README.md b/vendor/egulias/email-validator/README.md index 262693bf..0d0c5cc0 100644 --- a/vendor/egulias/email-validator/README.md +++ b/vendor/egulias/email-validator/README.md @@ -9,7 +9,7 @@ With the help of Run the command below to install via Composer ```shell -composer require egulias/email-validator +composer require egulias/email-validator "~1.2" ``` ##Usage## diff --git a/vendor/egulias/email-validator/composer.json b/vendor/egulias/email-validator/composer.json index 1ccb77a1..6fdc4d0b 100644 --- a/vendor/egulias/email-validator/composer.json +++ b/vendor/egulias/email-validator/composer.json @@ -15,11 +15,10 @@ }, "require": { "php": ">= 5.3.3", - "doctrine/lexer": "~1.0,>=1.0.1" + "doctrine/lexer": "^1.0.1" }, "require-dev" : { - "satooshi/php-coveralls": "dev-master", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^4.8.24" }, "autoload": { "psr-0": { diff --git a/vendor/egulias/email-validator/composer.lock b/vendor/egulias/email-validator/composer.lock index 49f7df86..cbd6ba2e 100644 --- a/vendor/egulias/email-validator/composer.lock +++ b/vendor/egulias/email-validator/composer.lock @@ -1,10 +1,11 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "9426f5a00cf0f71d83c287a7c0ff392b", + "hash": "aeeae19ffaaf639f5ad6edac2f979b28", + "content-hash": "61ce0ff395bacaa79d3f6e1216e23e4b", "packages": [ { "name": "doctrine/lexer", @@ -63,124 +64,93 @@ ], "packages-dev": [ { - "name": "doctrine/instantiator", - "version": "1.0.5", + "name": "dflydev/markdown", + "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "url": "https://github.com/dflydev/dflydev-markdown.git", + "reference": "76501a808522dbe40a5a71d272bd08d54cbae03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/dflydev/dflydev-markdown/zipball/76501a808522dbe40a5a71d272bd08d54cbae03d", + "reference": "76501a808522dbe40a5a71d272bd08d54cbae03d", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "php": ">=5.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "psr-0": { + "dflydev\\markdown": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "New BSD License" ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Michel Fortin", + "homepage": "http://michelf.com" + }, + { + "name": "John Gruber", + "homepage": "http://daringfireball.net" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "description": "PHP Markdown & Extra", + "homepage": "http://github.com/dflydev/dflydev-markdown", "keywords": [ - "constructor", - "instantiate" + "markdown" ], - "time": "2015-06-14 21:17:01" + "abandoned": "michelf/php-markdown", + "time": "2012-01-02 23:11:32" }, { - "name": "guzzle/guzzle", - "version": "v3.9.3", + "name": "doctrine/instantiator", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/guzzle/guzzle3.git", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "26404e0c90565b614ee76b988b9bc8790d77f590" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/26404e0c90565b614ee76b988b9bc8790d77f590", + "reference": "26404e0c90565b614ee76b988b9bc8790d77f590", "shasum": "" }, "require": { - "ext-curl": "*", - "php": ">=5.3.3", - "symfony/event-dispatcher": "~2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-error-response": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" + "php": "~5.3" }, "require-dev": { - "doctrine/cache": "~1.3", - "monolog/monolog": "~1.0", - "phpunit/phpunit": "3.7.*", - "psr/log": "~1.0", - "symfony/class-loader": "~2.1", - "zendframework/zend-cache": "2.*,<2.3", - "zendframework/zend-log": "2.*,<2.3" - }, - "suggest": { - "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.9-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { - "Guzzle": "src/", - "Guzzle\\Tests": "tests/" + "Doctrine\\Instantiator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -189,51 +159,39 @@ ], "authors": [ { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" } ], - "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", - "homepage": "http://guzzlephp.org/", + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" + "constructor", + "instantiate" ], - "time": "2015-03-18 18:23:50" + "time": "2014-08-25 15:09:25" }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + "reference": "66ae84e9d7c8ea85c979cb65977bd8e608baf0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/66ae84e9d7c8ea85c979cb65977bd8e608baf0c5", + "reference": "66ae84e9d7c8ea85c979cb65977bd8e608baf0c5", "shasum": "" }, "require": { + "dflydev/markdown": "1.0.*", "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" + "phpunit/phpunit": "3.7.*@stable" }, "type": "library", "extra": { @@ -258,26 +216,25 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2015-02-03 12:10:50" + "time": "2013-08-07 11:04:22" }, { "name": "phpspec/prophecy", - "version": "v1.4.1", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373" + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", - "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" + "doctrine/instantiator": "~1.0,>=1.0.2", + "phpdocumentor/reflection-docblock": "~2.0" }, "require-dev": { "phpspec/phpspec": "~2.0" @@ -285,7 +242,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -309,7 +266,7 @@ } ], "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", + "homepage": "http://phpspec.org", "keywords": [ "Double", "Dummy", @@ -318,20 +275,20 @@ "spy", "stub" ], - "time": "2015-04-27 22:15:08" + "time": "2014-11-17 16:23:49" }, { "name": "phpunit/php-code-coverage", - "version": "2.1.6", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "631e365cf26bb2c078683e8d9bcf8bc631ac4d44" + "reference": "ba315f46873fd6e86fdb98685a1a900e7379c886" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/631e365cf26bb2c078683e8d9bcf8bc631ac4d44", - "reference": "631e365cf26bb2c078683e8d9bcf8bc631ac4d44", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ba315f46873fd6e86fdb98685a1a900e7379c886", + "reference": "ba315f46873fd6e86fdb98685a1a900e7379c886", "shasum": "" }, "require": { @@ -380,7 +337,7 @@ "testing", "xunit" ], - "time": "2015-06-19 07:11:55" + "time": "2015-05-30 12:58:40" }, { "name": "phpunit/php-file-iterator", @@ -431,16 +388,16 @@ }, { "name": "phpunit/php-text-template", - "version": "1.2.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", "shasum": "" }, "require": { @@ -449,17 +406,20 @@ "type": "library", "autoload": { "classmap": [ - "src/" + "Text/" ] }, "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", + "email": "sb@sebastian-bergmann.de", "role": "lead" } ], @@ -468,7 +428,7 @@ "keywords": [ "template" ], - "time": "2015-06-21 13:50:34" + "time": "2014-01-30 17:20:04" }, { "name": "phpunit/php-timer", @@ -513,16 +473,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.3", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9" + "reference": "f8d5d08c56de5cfd592b3340424a81733259a876" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9", - "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876", + "reference": "f8d5d08c56de5cfd592b3340424a81733259a876", "shasum": "" }, "require": { @@ -535,7 +495,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -558,20 +518,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-06-19 03:43:16" + "time": "2014-08-31 06:12:13" }, { "name": "phpunit/phpunit", - "version": "4.7.5", + "version": "4.8.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f6701ef3faea759acd1910a7751d8d102a7fd5bc" + "reference": "a1066c562c52900a142a0e2bbf0582994671385e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f6701ef3faea759acd1910a7751d8d102a7fd5bc", - "reference": "f6701ef3faea759acd1910a7751d8d102a7fd5bc", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e", + "reference": "a1066c562c52900a142a0e2bbf0582994671385e", "shasum": "" }, "require": { @@ -581,7 +541,7 @@ "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", - "phpspec/prophecy": "~1.3,>=1.3.1", + "phpspec/prophecy": "^1.3.1", "phpunit/php-code-coverage": "~2.1", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", @@ -589,7 +549,7 @@ "phpunit/phpunit-mock-objects": "~2.3", "sebastian/comparator": "~1.1", "sebastian/diff": "~1.2", - "sebastian/environment": "~1.2", + "sebastian/environment": "~1.3", "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", @@ -604,7 +564,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.7.x-dev" + "dev-master": "4.8.x-dev" } }, "autoload": { @@ -630,29 +590,29 @@ "testing", "xunit" ], - "time": "2015-06-21 07:23:36" + "time": "2016-03-14 06:16:08" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.4", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "92408bb1968a81b3217a6fdf6c1a198da83caa35" + "reference": "c63d2367247365f688544f0d500af90a11a44c65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/92408bb1968a81b3217a6fdf6c1a198da83caa35", - "reference": "92408bb1968a81b3217a6fdf6c1a198da83caa35", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", + "reference": "c63d2367247365f688544f0d500af90a11a44c65", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", + "doctrine/instantiator": "~1.0,>=1.0.1", "php": ">=5.3.3", "phpunit/php-text-template": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "~4.3" }, "suggest": { "ext-soap": "*" @@ -685,142 +645,29 @@ "mock", "xunit" ], - "time": "2015-06-11 15:55:48" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "satooshi/php-coveralls", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/satooshi/php-coveralls.git", - "reference": "2fbf803803d179ab1082807308a67bbd5a760c70" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/2fbf803803d179ab1082807308a67bbd5a760c70", - "reference": "2fbf803803d179ab1082807308a67bbd5a760c70", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-simplexml": "*", - "guzzle/guzzle": ">=2.7", - "php": ">=5.3", - "psr/log": "1.0.0", - "symfony/config": ">=2.0", - "symfony/console": ">=2.0", - "symfony/stopwatch": ">=2.2", - "symfony/yaml": ">=2.0" - }, - "require-dev": { - "apigen/apigen": "2.8.*@stable", - "pdepend/pdepend": "dev-master as 2.0.0", - "phpmd/phpmd": "dev-master", - "phpunit/php-invoker": ">=1.1.0,<1.2.0", - "phpunit/phpunit": "3.7.*@stable", - "sebastian/finder-facade": "dev-master", - "sebastian/phpcpd": "1.4.*@stable", - "squizlabs/php_codesniffer": "1.4.*@stable", - "theseer/fdomdocument": "dev-master" - }, - "suggest": { - "symfony/http-kernel": "Allows Symfony integration" - }, - "bin": [ - "composer/bin/coveralls" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.7-dev" - } - }, - "autoload": { - "psr-0": { - "Satooshi\\Component": "src/", - "Satooshi\\Bundle": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kitamura Satoshi", - "email": "with.no.parachute@gmail.com", - "homepage": "https://www.facebook.com/satooshi.jp" - } - ], - "description": "PHP client library for Coveralls API", - "homepage": "https://github.com/satooshi/php-coveralls", - "keywords": [ - "ci", - "coverage", - "github", - "test" - ], - "time": "2014-11-11 15:35:34" + "time": "2014-10-03 05:12:11" }, { "name": "sebastian/comparator", - "version": "1.1.1", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + "reference": "c484a80f97573ab934e37826dba0135a3301b26a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a", + "reference": "c484a80f97573ab934e37826dba0135a3301b26a", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/diff": "~1.1", + "sebastian/exporter": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "~4.1" }, "type": "library", "extra": { @@ -862,20 +709,20 @@ "compare", "equality" ], - "time": "2015-01-29 16:28:08" + "time": "2014-11-16 21:32:38" }, { "name": "sebastian/diff", - "version": "1.3.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", "shasum": "" }, "require": { @@ -887,7 +734,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -914,20 +761,20 @@ "keywords": [ "diff" ], - "time": "2015-02-22 15:13:53" + "time": "2014-08-15 10:29:00" }, { "name": "sebastian/environment", - "version": "1.2.2", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" + "reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", - "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4fe0a44cddd8cc19583a024bdc7374eb2fef0b87", + "reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87", "shasum": "" }, "require": { @@ -964,7 +811,7 @@ "environment", "hhvm" ], - "time": "2015-01-01 10:01:08" + "time": "2015-07-26 06:42:57" }, { "name": "sebastian/exporter", @@ -1138,16 +985,16 @@ }, { "name": "sebastian/version", - "version": "1.0.6", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + "reference": "16b021aed448b654ae05846e394e057e9a6f04cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/16b021aed448b654ae05846e394e057e9a6f04cb", + "reference": "16b021aed448b654ae05846e394e057e9a6f04cb", "shasum": "" }, "type": "library", @@ -1169,202 +1016,35 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" + "time": "2013-01-05 14:27:32" }, { - "name": "symfony/config", - "version": "v2.7.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/58ded81f1f582a87c528ef3dae9a859f78b5f374", - "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "symfony/filesystem": "~2.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com", - "time": "2015-06-11 14:06:56" - }, - { - "name": "symfony/console", - "version": "v2.7.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "564398bc1f33faf92fc2ec86859983d30eb81806" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/564398bc1f33faf92fc2ec86859983d30eb81806", - "reference": "564398bc1f33faf92fc2ec86859983d30eb81806", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.1" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com", - "time": "2015-06-10 15:30:22" - }, - { - "name": "symfony/event-dispatcher", - "version": "v2.7.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/be3c5ff8d503c46768aeb78ce6333051aa6f26d9", - "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5", - "symfony/dependency-injection": "~2.6", - "symfony/expression-language": "~2.6", - "symfony/phpunit-bridge": "~2.7", - "symfony/stopwatch": "~2.3" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "time": "2015-06-08 09:37:21" - }, - { - "name": "symfony/filesystem", - "version": "v2.7.1", + "name": "symfony/yaml", + "version": "v2.1.0", + "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3" + "url": "https://github.com/symfony/yaml.git", + "reference": "f18e004fc975707bb4695df1dbbe9b0d8c8b7715" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a0d43eb3e17d4f4c6990289805a488a0482a07f3", - "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3", + "url": "https://api.github.com/repos/symfony/yaml/zipball/f18e004fc975707bb4695df1dbbe9b0d8c8b7715", + "reference": "f18e004fc975707bb4695df1dbbe9b0d8c8b7715", "shasum": "" }, "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.1-dev" } }, "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "psr-0": { + "Symfony\\Component\\Yaml": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1372,125 +1052,25 @@ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, { "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2015-06-08 09:37:21" - }, - { - "name": "symfony/stopwatch", - "version": "v2.7.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/Stopwatch.git", - "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", - "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "homepage": "http://symfony.com/contributors" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "https://symfony.com", - "time": "2015-06-04 20:11:48" - }, - { - "name": "symfony/yaml", - "version": "v2.7.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/9808e75c609a14f6db02f70fccf4ca4aab53c160", - "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2015-06-10 15:30:22" + "homepage": "http://symfony.com", + "time": "2012-08-22 13:48:41" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "satooshi/php-coveralls": 20 - }, + "stability-flags": [], "prefer-stable": false, - "prefer-lowest": false, + "prefer-lowest": true, "platform": { "php": ">= 5.3.3" }, diff --git a/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php b/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php index d8522fff..882c9681 100644 --- a/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php +++ b/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailLexer.php @@ -67,8 +67,6 @@ class EmailLexer extends AbstractLexer "\n" => self::S_LF, "\r\n" => self::CRLF, 'IPv6' => self::S_IPV6TAG, - '<' => self::S_LOWERTHAN, - '>' => self::S_GREATERTHAN, '{' => self::S_OPENQBRACKET, '}' => self::S_CLOSEQBRACKET, '' => self::S_EMPTY, diff --git a/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php b/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php index d047decf..69ff5fc1 100644 --- a/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php +++ b/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidator.php @@ -7,49 +7,52 @@ * * @author Eduardo Gulias Davis */ -class EmailValidator +class EmailValidator implements EmailValidatorInterface { + /** + * Critical validation errors used to indicate that + * an email address is invalid: + */ const ERR_CONSECUTIVEATS = 128; const ERR_EXPECTING_DTEXT = 129; const ERR_NOLOCALPART = 130; const ERR_NODOMAIN = 131; const ERR_CONSECUTIVEDOTS = 132; const ERR_ATEXT_AFTER_CFWS = 133; - const ERR_ATEXT_AFTER_QS = 134; - const ERR_ATEXT_AFTER_DOMLIT = 135; const ERR_EXPECTING_QPAIR = 136; const ERR_EXPECTING_ATEXT = 137; - const ERR_EXPECTING_QTEXT = 138; const ERR_EXPECTING_CTEXT = 139; - const ERR_BACKSLASHEND = 140; const ERR_DOT_START = 141; const ERR_DOT_END = 142; - const ERR_DOMAINHYPHENSTART = 143; const ERR_DOMAINHYPHENEND = 144; const ERR_UNCLOSEDQUOTEDSTR = 145; const ERR_UNCLOSEDCOMMENT = 146; - const ERR_UNCLOSEDDOMLIT = 147; const ERR_FWS_CRLF_X2 = 148; const ERR_FWS_CRLF_END = 149; const ERR_CR_NO_LF = 150; const ERR_DEPREC_REACHED = 151; + const ERR_UNOPENEDCOMMENT = 152; + const ERR_ATEXT_AFTER_QS = 134; // not in use + const ERR_ATEXT_AFTER_DOMLIT = 135; // not in use + const ERR_EXPECTING_QTEXT = 138; // not in use + const ERR_BACKSLASHEND = 140; // not in use + const ERR_DOMAINHYPHENSTART = 143; // not in use + const ERR_UNCLOSEDDOMLIT = 147; // not in use + + /** + * Informational validation warnings regarding unusual or + * deprecated features found in an email address: + */ + // Address is valid for SMTP (RFC-5321), but has unusual elements. const RFC5321_TLD = 9; - const RFC5321_TLDNUMERIC = 10; const RFC5321_QUOTEDSTRING = 11; const RFC5321_ADDRESSLITERAL = 12; const RFC5321_IPV6DEPRECATED = 13; - const CFWS_COMMENT = 17; - const CFWS_FWS = 18; - const DEPREC_LOCALPART = 33; - const DEPREC_FWS = 34; - const DEPREC_QTEXT = 35; - const DEPREC_QP = 36; - const DEPREC_COMMENT = 37; - const DEPREC_CTEXT = 38; - const DEPREC_CFWS_NEAR_AT = 49; + const RFC5321_TLDNUMERIC = 10; // not in use + // Address is only valid according to the broad + // definition of RFC-5322. It is otherwise invalid. const RFC5322_LOCAL_TOOLONG = 64; const RFC5322_LABEL_TOOLONG = 63; - const RFC5322_DOMAIN = 65; const RFC5322_TOOLONG = 66; const RFC5322_DOMAIN_TOOLONG = 255; const RFC5322_DOMAINLITERAL = 70; @@ -60,12 +63,48 @@ class EmailValidator const RFC5322_IPV6_MAXGRPS = 75; const RFC5322_IPV6_COLONSTRT = 76; const RFC5322_IPV6_COLONEND = 77; + const RFC5322_DOMAIN = 65; // not in use + // Address contains deprecated elements, but may + // still be valid in restricted contexts. + const DEPREC_QP = 36; + const DEPREC_COMMENT = 37; + const DEPREC_CFWS_NEAR_AT = 49; + const DEPREC_LOCALPART = 33; // not in use + const DEPREC_FWS = 34; // not in use + const DEPREC_QTEXT = 35; // not in use + const DEPREC_CTEXT = 38; // not in use + // Address is valid within the message, + // but cannot be used unmodified in the envelope. + const CFWS_COMMENT = 17; + const CFWS_FWS = 18; + // Hostname DNS checks were unsuccessful. const DNSWARN_NO_MX_RECORD = 5; const DNSWARN_NO_RECORD = 6; + /** + * @var EmailParser + */ protected $parser; + + /** + * Contains any informational warnings regarding unusual/deprecated + * features that were encountered during validation. + * + * @var array + */ protected $warnings = array(); + + /** + * If a critical validation problem is encountered, this will be + * set to the value of one of this class's ERR_* constants. + * + * @var int + */ protected $error; + + /** + * @var int + */ protected $threshold = 255; public function __construct() @@ -73,6 +112,9 @@ public function __construct() $this->parser = new EmailParser(new EmailLexer()); } + /** + * {@inheritdoc} + */ public function isValid($email, $checkDNS = false, $strict = false) { try { @@ -84,22 +126,18 @@ public function isValid($email, $checkDNS = false, $strict = false) return false; } - $dns = true; - if ($checkDNS) { - $dns = $this->checkDNS(); - } + $dnsProblemExists = ($checkDNS ? !$this->checkDNS() : false); if ($this->hasWarnings() && ((int) max($this->warnings) > $this->threshold)) { $this->error = self::ERR_DEPREC_REACHED; - return false; } - return !$strict || (!$this->hasWarnings() && $dns); + return ($strict ? (!$this->hasWarnings() && !$dnsProblemExists) : true); } /** - * @return boolean + * {@inheritdoc} */ public function hasWarnings() { @@ -107,7 +145,7 @@ public function hasWarnings() } /** - * @return array + * {@inheritdoc} */ public function getWarnings() { @@ -115,7 +153,7 @@ public function getWarnings() } /** - * @return string + * {@inheritdoc} */ public function getError() { @@ -123,9 +161,7 @@ public function getError() } /** - * @param int $threshold - * - * @return EmailValidator + * {@inheritdoc} */ public function setThreshold($threshold) { @@ -135,26 +171,30 @@ public function setThreshold($threshold) } /** - * @return int + * {@inheritdoc} */ public function getThreshold() { return $this->threshold; } + /** + * @return bool Whether or not an MX record exists for the + * email address's host name. + */ protected function checkDNS() { - $checked = true; + $host = $this->parser->getParsedDomainPart(); + $host = rtrim($host, '.') . '.'; - $result = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX'); + $mxRecordExists = checkdnsrr($host, 'MX'); - if (!$result) { + if (!$mxRecordExists) { $this->warnings[] = self::DNSWARN_NO_RECORD; - $checked = false; $this->addTLDWarnings(); } - return $checked; + return $mxRecordExists; } protected function addTLDWarnings() diff --git a/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidatorInterface.php b/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidatorInterface.php new file mode 100644 index 00000000..7ac54f93 --- /dev/null +++ b/vendor/egulias/email-validator/src/Egulias/EmailValidator/EmailValidatorInterface.php @@ -0,0 +1,62 @@ + + */ +interface EmailValidatorInterface +{ + /** + * Validates an email address against the following standards: + * + * RFC-5321: Simple Mail Transfer Protocol + * RFC-5322: Internet Message Format + * RFC-6530: Overview and Framework for Internationalized Email + * RFC-6531: SMTP Extension for Internationalized Email + * RFC-6532: Internationalized Email Headers + * RFC-1123 section 2.1: Requirements for Internet Hosts -- Application and Support + * RFC-4291 section 2.2: IP Version 6 Addressing Architecture + * + * @param string $email The email address to validate. + * @param bool $checkDNS Whether or not the email address's hostname should + * be confirmed with a DNS lookup. This only comes + * into play if strict mode is also enabled. + * @param bool $strict If this is true, and any informational warnings + * were raised during validation, the email address + * will be considered invalid. Additionally, if + * $checkDNS is true and the DNS lookup failed, + * the email address will be considered invalid. + * @return bool + */ + public function isValid($email, $checkDNS = false, $strict = false); + + /** + * @return bool + */ + public function hasWarnings(); + + /** + * @return array + */ + public function getWarnings(); + + /** + * @return string + */ + public function getError(); + + /** + * @param int $threshold The acceptable number of deprecation warnings. + * + * @return EmailValidator + */ + public function setThreshold($threshold); + + /** + * @return int + */ + public function getThreshold(); +} diff --git a/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php b/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php index c4d0cf60..66a51fb4 100644 --- a/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php +++ b/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/DomainPart.php @@ -4,7 +4,6 @@ namespace Egulias\EmailValidator\Parser; use Egulias\EmailValidator\EmailLexer; -use Egulias\EmailValidator\Parser\Parser; use Egulias\EmailValidator\EmailValidator; class DomainPart extends Parser @@ -103,23 +102,34 @@ public function checkIPV6Tag($addressLiteral, $maxGroups = 8) protected function doParseDomainPart() { $domain = ''; + $openedParenthesis = 0; + $openBrackets = false; do { - $prev = $this->lexer->getPrevious(); - if ($this->lexer->token['type'] === EmailLexer::S_SLASH) { - throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED'); - } + $this->checkNotAllowedChars($this->lexer->token); if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { $this->parseComments(); + $openedParenthesis += $this->getOpenedParenthesis(); $this->lexer->moveNext(); + $tmpPrev = $this->lexer->getPrevious(); + if ($tmpPrev['type'] === EmailLexer::S_CLOSEPARENTHESIS) { + $openedParenthesis--; + } + } + if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) { + if ($openedParenthesis === 0) { + throw new \InvalidArgumentException('ERR_UNOPENEDCOMMENT'); + } else { + $openedParenthesis--; + } } $this->checkConsecutiveDots(); $this->checkDomainPartExceptions($prev); - if ($this->hasBrackets()) { + if ($openBrackets = $this->hasBrackets($openBrackets)) { $this->parseDomainLiteral(); } @@ -136,6 +146,14 @@ protected function doParseDomainPart() return $domain; } + private function checkNotAllowedChars($token) + { + $notAllowed = array(EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true); + if (isset($notAllowed[$token['type']])) { + throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED'); + } + } + protected function parseDomainLiteral() { if ($this->lexer->isNextToken(EmailLexer::S_COLON)) { @@ -180,7 +198,7 @@ protected function doParseDomainLiteral() } if ($this->lexer->isNextToken(EmailLexer::S_CR)) { - throw new \InvalidArgumentException("ERR_CR_NO_LF"); + throw new \InvalidArgumentException('ERR_CR_NO_LF'); } if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) { $this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT; @@ -276,8 +294,12 @@ protected function checkDomainPartExceptions($prev) } } - protected function hasBrackets() + protected function hasBrackets($openBrackets) { + if ($this->lexer->token['type'] === EmailLexer::S_CLOSEBRACKET && !$openBrackets) { + throw new \InvalidArgumentException('ERR_EXPECTING_OPENBRACKET'); + } + if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) { return false; } diff --git a/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php b/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php index 2f771640..449748f4 100644 --- a/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php +++ b/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/LocalPart.php @@ -4,7 +4,6 @@ use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailValidator; -use \InvalidArgumentException; class LocalPart extends Parser { @@ -12,9 +11,9 @@ public function parse($localPart) { $parseDQuote = true; $closingQuote = false; + $openedParenthesis = 0; while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) { - if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) { throw new \InvalidArgumentException('ERR_DOT_START'); } @@ -26,12 +25,19 @@ public function parse($localPart) if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) { $this->parseComments(); + $openedParenthesis += $this->getOpenedParenthesis(); + } + if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) { + if ($openedParenthesis === 0) { + throw new \InvalidArgumentException('ERR_UNOPENEDCOMMENT'); + } else { + $openedParenthesis--; + } } $this->checkConsecutiveDots(); - if ( - $this->lexer->token['type'] === EmailLexer::S_DOT && + if ($this->lexer->token['type'] === EmailLexer::S_DOT && $this->lexer->isNextToken(EmailLexer::S_AT) ) { throw new \InvalidArgumentException('ERR_DOT_END'); @@ -82,7 +88,7 @@ protected function parseDoubleQuote() $this->lexer->moveNext(); if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) { - throw new InvalidArgumentException("ERR_EXPECTED_ATEXT"); + throw new \InvalidArgumentException('ERR_EXPECTED_ATEXT'); } } @@ -90,12 +96,12 @@ protected function parseDoubleQuote() if ($prev['type'] === EmailLexer::S_BACKSLASH) { if (!$this->checkDQUOTE(false)) { - throw new \InvalidArgumentException("ERR_UNCLOSED_DQUOTE"); + throw new \InvalidArgumentException('ERR_UNCLOSED_DQUOTE'); } } if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) { - throw new \InvalidArgumentException("ERR_EXPECED_AT"); + throw new \InvalidArgumentException('ERR_EXPECED_AT'); } return $parseAgain; diff --git a/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php b/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php index b66279e2..8a72cd10 100644 --- a/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php +++ b/vendor/egulias/email-validator/src/Egulias/EmailValidator/Parser/Parser.php @@ -9,6 +9,7 @@ abstract class Parser { protected $warnings = array(); protected $lexer; + protected $openedParenthesis = 0; public function __construct(EmailLexer $lexer) { @@ -20,7 +21,13 @@ public function getWarnings() return $this->warnings; } - abstract function parse($str); + abstract public function parse($str); + + /** @return int */ + public function getOpenedParenthesis() + { + return $this->openedParenthesis; + } /** * validateQuotedPair @@ -35,15 +42,15 @@ protected function validateQuotedPair() $this->warnings[] = EmailValidator::DEPREC_QP; } - /** - * @return string the the comment - * @throws \InvalidArgumentException - */ protected function parseComments() { + $this->openedParenthesis = 1; $this->isUnclosedComment(); $this->warnings[] = EmailValidator::CFWS_COMMENT; while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) { + if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) { + $this->openedParenthesis++; + } $this->warnEscaping(); $this->lexer->moveNext(); } @@ -75,11 +82,11 @@ protected function parseFWS() $this->checkCRLFInFWS(); if ($this->lexer->token['type'] === EmailLexer::S_CR) { - throw new \InvalidArgumentException("ERR_CR_NO_LF"); + throw new \InvalidArgumentException('ERR_CR_NO_LF'); } if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) { - throw new \InvalidArgumentException("ERR_ATEXT_AFTER_CFWS"); + throw new \InvalidArgumentException('ERR_ATEXT_AFTER_CFWS'); } if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) { @@ -160,7 +167,7 @@ protected function checkDQUOTE($hasClosingQuote) return $hasClosingQuote; } $previous = $this->lexer->getPrevious(); - if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) { + if ($previous['type'] === EmailLexer::GENERIC && $this->lexer->isNextToken(EmailLexer::GENERIC)) { throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT'); } @@ -181,10 +188,10 @@ protected function checkCRLFInFWS() return; } if ($this->lexer->isNextToken(EmailLexer::CRLF)) { - throw new \InvalidArgumentException("ERR_FWS_CRLF_X2"); + throw new \InvalidArgumentException('ERR_FWS_CRLF_X2'); } if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) { - throw new \InvalidArgumentException("ERR_FWS_CRLF_END"); + throw new \InvalidArgumentException('ERR_FWS_CRLF_END'); } } } diff --git a/vendor/guzzlehttp/guzzle/.travis.yml b/vendor/guzzlehttp/guzzle/.travis.yml deleted file mode 100644 index a4cd64cc..00000000 --- a/vendor/guzzlehttp/guzzle/.travis.yml +++ /dev/null @@ -1,41 +0,0 @@ -language: php - -sudo: false - -php: - - 5.5 - - 5.6 - - 7.0 - - hhvm - -before_script: - - curl --version - - composer self-update - - composer install --no-interaction --prefer-source --dev - - ~/.nvm/nvm.sh install v0.6.14 - - ~/.nvm/nvm.sh run v0.6.14 - - '[ "$TRAVIS_PHP_VERSION" != "7.0" ] || echo "xdebug.overload_var_dump = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini' - -script: make test - -matrix: - allow_failures: - - php: hhvm - fast_finish: true - -before_deploy: - - rvm 1.9.3 do gem install mime-types -v 2.6.2 - - make package - -deploy: - provider: releases - api_key: - secure: UpypqlYgsU68QT/x40YzhHXvzWjFwCNo9d+G8KAdm7U9+blFfcWhV1aMdzugvPMl6woXgvJj7qHq5tAL4v6oswCORhpSBfLgOQVFaica5LiHsvWlAedOhxGmnJqMTwuepjBCxXhs3+I8Kof1n4oUL9gKytXjOVCX/f7XU1HiinU= - file: - - build/artifacts/guzzle.phar - - build/artifacts/guzzle.zip - on: - repo: guzzle/guzzle - tags: true - all_branches: true - php: 5.5 diff --git a/vendor/guzzlehttp/guzzle/CHANGELOG.md b/vendor/guzzlehttp/guzzle/CHANGELOG.md index affddab4..b265cbcd 100644 --- a/vendor/guzzlehttp/guzzle/CHANGELOG.md +++ b/vendor/guzzlehttp/guzzle/CHANGELOG.md @@ -1,5 +1,37 @@ # CHANGELOG +## 6.3.0 - 2017-06-22 + +* Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659) +* Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621) +* Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580) +* Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609) +* Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641) +* Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611) +* Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811) +* Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642) +* Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569) +* Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711) +* Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745) +* Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721) +* Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318) +* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684) +* Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827) + + ++ Minor code cleanups, documentation fixes and clarifications. + +## 6.2.3 - 2017-02-28 + +* Fix deprecations with guzzle/psr7 version 1.4 + +## 6.2.2 - 2016-10-08 + +* Allow to pass nullable Response to delay callable +* Only add scheme when host is present +* Fix drain case where content-length is the literal string zero +* Obfuscate in-URL credentials in exceptions + ## 6.2.1 - 2016-07-18 * Address HTTP_PROXY security vulnerability, CVE-2016-5385: @@ -746,7 +778,7 @@ interfaces. * Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference to help with refcount based garbage collection of resources created by sending a request * Deprecating ZF1 cache and log adapters. These will be removed in the next major version. -* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it'sdeprecated). Use the +* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it's deprecated). Use the HistoryPlugin for a history. * Added a `responseBody` alias for the `response_body` location * Refactored internals to no longer rely on Response::getRequest() diff --git a/vendor/guzzlehttp/guzzle/README.md b/vendor/guzzlehttp/guzzle/README.md index 772b18d0..2f614d6f 100644 --- a/vendor/guzzlehttp/guzzle/README.md +++ b/vendor/guzzlehttp/guzzle/README.md @@ -19,15 +19,13 @@ trivial to integrate with web services. ```php $client = new \GuzzleHttp\Client(); -$res = $client->request('GET', 'https://api.github.com/user', [ - 'auth' => ['user', 'pass'] -]); +$res = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); echo $res->getStatusCode(); // 200 echo $res->getHeaderLine('content-type'); // 'application/json; charset=utf8' echo $res->getBody(); -// {"type":"User"...' +// '{"id": 1420053, "name": "guzzle", ...}' // Send an asynchronous request. $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org'); @@ -40,7 +38,7 @@ $promise->wait(); ## Help and docs - [Documentation](http://guzzlephp.org/) -- [stackoverflow](http://stackoverflow.com/questions/tagged/guzzle) +- [Stack Overflow](http://stackoverflow.com/questions/tagged/guzzle) - [Gitter](https://gitter.im/guzzle/guzzle) @@ -75,14 +73,15 @@ composer.phar update ## Version Guidance -| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | -|---------|-------------|---------------------|--------------|---------------------|---------------------|-------| -| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | -| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | N/A | N/A | No | -| 5.x | Maintained | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | -| 6.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | +| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version | +|---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------| +| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >= 5.3.3 | +| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >= 5.4 | +| 5.x | Maintained | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >= 5.4 | +| 6.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >= 5.5 | [guzzle-3-repo]: https://github.com/guzzle/guzzle3 +[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3 [guzzle-6-repo]: https://github.com/guzzle/guzzle [guzzle-3-docs]: http://guzzle3.readthedocs.org/en/latest/ diff --git a/vendor/guzzlehttp/guzzle/UPGRADING.md b/vendor/guzzlehttp/guzzle/UPGRADING.md index 9e31ddcc..91d1dcc9 100644 --- a/vendor/guzzlehttp/guzzle/UPGRADING.md +++ b/vendor/guzzlehttp/guzzle/UPGRADING.md @@ -132,7 +132,7 @@ $handler = GuzzleHttp\HandlerStack::create(); $handler->push(Middleware::mapRequest(function (RequestInterface $request) { // Notice that we have to return a request object return $request->withHeader('X-Foo', 'Bar'); -}); +})); // Inject the handler into the client $client = new GuzzleHttp\Client(['handler' => $handler]); ``` @@ -600,7 +600,7 @@ these if needed): The following plugins are not part of the core Guzzle package, but are provided in separate repositories: -- `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be muchs simpler +- `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be much simpler to build custom retry policies using simple functions rather than various chained classes. See: https://github.com/guzzle/retry-subscriber - `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to @@ -664,8 +664,8 @@ that contain additional metadata accessible via `getMetadata()`. The entire concept of the StreamRequestFactory has been removed. The way this was used in Guzzle 3 broke the actual interface of sending streaming requests -(instead of getting back a Response, you got a StreamInterface). Streeaming -PHP requests are now implemented throught the `GuzzleHttp\Adapter\StreamAdapter`. +(instead of getting back a Response, you got a StreamInterface). Streaming +PHP requests are now implemented through the `GuzzleHttp\Adapter\StreamAdapter`. 3.6 to 3.7 ---------- diff --git a/vendor/guzzlehttp/guzzle/composer.json b/vendor/guzzlehttp/guzzle/composer.json index 218c2473..65687a58 100644 --- a/vendor/guzzlehttp/guzzle/composer.json +++ b/vendor/guzzlehttp/guzzle/composer.json @@ -14,12 +14,12 @@ ], "require": { "php": ">=5.5", - "guzzlehttp/psr7": "^1.3.1", + "guzzlehttp/psr7": "^1.4", "guzzlehttp/promises": "^1.0" }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.0", + "phpunit/phpunit": "^4.0 || ^5.0", "psr/log": "^1.0" }, "autoload": { @@ -33,6 +33,9 @@ "GuzzleHttp\\Tests\\": "tests/" } }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, "extra": { "branch-alias": { "dev-master": "6.2-dev" diff --git a/vendor/guzzlehttp/guzzle/src/Client.php b/vendor/guzzlehttp/guzzle/src/Client.php index 6089c186..de4df8a5 100644 --- a/vendor/guzzlehttp/guzzle/src/Client.php +++ b/vendor/guzzlehttp/guzzle/src/Client.php @@ -9,18 +9,18 @@ use Psr\Http\Message\ResponseInterface; /** - * @method ResponseInterface get($uri, array $options = []) - * @method ResponseInterface head($uri, array $options = []) - * @method ResponseInterface put($uri, array $options = []) - * @method ResponseInterface post($uri, array $options = []) - * @method ResponseInterface patch($uri, array $options = []) - * @method ResponseInterface delete($uri, array $options = []) - * @method Promise\PromiseInterface getAsync($uri, array $options = []) - * @method Promise\PromiseInterface headAsync($uri, array $options = []) - * @method Promise\PromiseInterface putAsync($uri, array $options = []) - * @method Promise\PromiseInterface postAsync($uri, array $options = []) - * @method Promise\PromiseInterface patchAsync($uri, array $options = []) - * @method Promise\PromiseInterface deleteAsync($uri, array $options = []) + * @method ResponseInterface get(string|UriInterface $uri, array $options = []) + * @method ResponseInterface head(string|UriInterface $uri, array $options = []) + * @method ResponseInterface put(string|UriInterface $uri, array $options = []) + * @method ResponseInterface post(string|UriInterface $uri, array $options = []) + * @method ResponseInterface patch(string|UriInterface $uri, array $options = []) + * @method ResponseInterface delete(string|UriInterface $uri, array $options = []) + * @method Promise\PromiseInterface getAsync(string|UriInterface $uri, array $options = []) + * @method Promise\PromiseInterface headAsync(string|UriInterface $uri, array $options = []) + * @method Promise\PromiseInterface putAsync(string|UriInterface $uri, array $options = []) + * @method Promise\PromiseInterface postAsync(string|UriInterface $uri, array $options = []) + * @method Promise\PromiseInterface patchAsync(string|UriInterface $uri, array $options = []) + * @method Promise\PromiseInterface deleteAsync(string|UriInterface $uri, array $options = []) */ class Client implements ClientInterface { @@ -63,6 +63,8 @@ public function __construct(array $config = []) { if (!isset($config['handler'])) { $config['handler'] = HandlerStack::create(); + } elseif (!is_callable($config['handler'])) { + throw new \InvalidArgumentException('handler must be a callable'); } // Convert the base_uri to a UriInterface @@ -142,10 +144,10 @@ private function buildUri($uri, array $config) $uri = Psr7\uri_for($uri === null ? '' : $uri); if (isset($config['base_uri'])) { - $uri = Psr7\Uri::resolve(Psr7\uri_for($config['base_uri']), $uri); + $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); } - return $uri->getScheme() === '' ? $uri->withScheme('http') : $uri; + return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; } /** @@ -350,6 +352,10 @@ private function applyOptions(RequestInterface $request, array &$options) $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST; $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; break; + case 'ntlm': + $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM; + $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; + break; } } @@ -402,7 +408,7 @@ private function invalidBody() throw new \InvalidArgumentException('Passing in the "body" request ' . 'option as an array to send a POST request has been deprecated. ' . 'Please use the "form_params" request option to send a ' - . 'application/x-www-form-urlencoded request, or a the "multipart" ' + . 'application/x-www-form-urlencoded request, or the "multipart" ' . 'request option to send a multipart/form-data request.'); } } diff --git a/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php index 7fffd30e..1c17b5a4 100644 --- a/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ b/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -86,6 +86,25 @@ public static function shouldPersist( return false; } + /** + * Finds and returns the cookie based on the name + * + * @param string $name cookie name to search for + * @return SetCookie|null cookie that was found or null if not found + */ + public function getCookieByName($name) + { + // don't allow a null name + if($name === null) { + return null; + } + foreach($this->cookies as $cookie) { + if($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) { + return $cookie; + } + } + } + public function toArray() { return array_map(function (SetCookie $cookie) { @@ -216,11 +235,41 @@ public function extractCookies( if (!$sc->getDomain()) { $sc->setDomain($request->getUri()->getHost()); } + if (0 !== strpos($sc->getPath(), '/')) { + $sc->setPath($this->getCookiePathFromRequest($request)); + } $this->setCookie($sc); } } } + /** + * Computes cookie path following RFC 6265 section 5.1.4 + * + * @link https://tools.ietf.org/html/rfc6265#section-5.1.4 + * + * @param RequestInterface $request + * @return string + */ + private function getCookiePathFromRequest(RequestInterface $request) + { + $uriPath = $request->getUri()->getPath(); + if ('' === $uriPath) { + return '/'; + } + if (0 !== strpos($uriPath, '/')) { + return '/'; + } + if ('/' === $uriPath) { + return '/'; + } + if (0 === $lastSlashPos = strrpos($uriPath, '/')) { + return '/'; + } + + return substr($uriPath, 0, $lastSlashPos); + } + public function withCookieHeader(RequestInterface $request) { $values = []; diff --git a/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php index fd78431e..427d896f 100644 --- a/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php +++ b/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php @@ -1,7 +1,27 @@ getStatusCode() / 100); if ($level === 4) { $label = 'Client error'; - $className = __NAMESPACE__ . '\\ClientException'; + $className = ClientException::class; } elseif ($level === 5) { $label = 'Server error'; - $className = __NAMESPACE__ . '\\ServerException'; + $className = ServerException::class; } else { $label = 'Unsuccessful request'; $className = __CLASS__; } - // Server Error: `GET /` resulted in a `404 Not Found` response: + $uri = $request->getUri(); + $uri = static::obfuscateUri($uri); + + // Client Error: `GET /` resulted in a `404 Not Found` response: // ... (truncated) $message = sprintf( - '%s: `%s` resulted in a `%s` response', + '%s: `%s %s` resulted in a `%s %s` response', $label, - $request->getMethod() . ' ' . $request->getUri(), - $response->getStatusCode() . ' ' . $response->getReasonPhrase() + $request->getMethod(), + $uri, + $response->getStatusCode(), + $response->getReasonPhrase() ); $summary = static::getResponseBodySummary($response); @@ -125,6 +131,11 @@ public static function getResponseBodySummary(ResponseInterface $response) } $size = $body->getSize(); + + if ($size === 0) { + return null; + } + $summary = $body->read(120); $body->rewind(); @@ -141,6 +152,24 @@ public static function getResponseBodySummary(ResponseInterface $response) return $summary; } + /** + * Obfuscates URI if there is an username and a password present + * + * @param UriInterface $uri + * + * @return UriInterface + */ + private static function obfuscateUri($uri) + { + $userInfo = $uri->getUserInfo(); + + if (false !== ($pos = strpos($userInfo, ':'))) { + return $uri->withUserInfo(substr($userInfo, 0, $pos), '***'); + } + + return $uri; + } + /** * Get the request that caused the exception * diff --git a/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php b/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php index 9f757454..49808e5c 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php @@ -16,7 +16,7 @@ class CurlFactory implements CurlFactoryInterface { /** @var array */ - private $handles; + private $handles = []; /** @var int Total number of idle handles to keep in cache */ private $maxHandles; @@ -163,7 +163,7 @@ private static function createRejection(EasyHandle $easy, array $ctx) // If an exception was encountered during the onHeaders event, then // return a rejected promise that wraps that exception. if ($easy->onHeadersException) { - return new RejectedPromise( + return \GuzzleHttp\Promise\rejection_for( new RequestException( 'An error was encountered during the on_headers event', $easy->request, @@ -186,7 +186,7 @@ private static function createRejection(EasyHandle $easy, array $ctx) ? new ConnectException($message, $easy->request, null, $ctx) : new RequestException($message, $easy->request, $easy->response, null, $ctx); - return new RejectedPromise($error); + return \GuzzleHttp\Promise\rejection_for($error); } private function getDefaultConf(EasyHandle $easy) @@ -326,12 +326,20 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf) $conf[CURLOPT_SSL_VERIFYHOST] = 2; $conf[CURLOPT_SSL_VERIFYPEER] = true; if (is_string($options['verify'])) { - $conf[CURLOPT_CAINFO] = $options['verify']; + // Throw an error if the file/folder/link path is not valid or doesn't exist. if (!file_exists($options['verify'])) { throw new \InvalidArgumentException( "SSL CA bundle not found: {$options['verify']}" ); } + // If it's a directory or a link to a directory use CURLOPT_CAPATH. + // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. + if (is_dir($options['verify']) || + (is_link($options['verify']) && is_dir(readlink($options['verify'])))) { + $conf[CURLOPT_CAPATH] = $options['verify']; + } else { + $conf[CURLOPT_CAINFO] = $options['verify']; + } } } } @@ -370,15 +378,30 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf) $conf[CURLOPT_FILE] = fopen('php://temp', 'w+'); $easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]); } - + $timeoutRequiresNoSignal = false; if (isset($options['timeout'])) { + $timeoutRequiresNoSignal |= $options['timeout'] < 1; $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; } + // CURL default value is CURL_IPRESOLVE_WHATEVER + if (isset($options['force_ip_resolve'])) { + if ('v4' === $options['force_ip_resolve']) { + $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; + } else if ('v6' === $options['force_ip_resolve']) { + $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6; + } + } + if (isset($options['connect_timeout'])) { + $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1; $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; } + if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + $conf[CURLOPT_NOSIGNAL] = true; + } + if (isset($options['proxy'])) { if (!is_array($options['proxy'])) { $conf[CURLOPT_PROXY] = $options['proxy']; diff --git a/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php b/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php index 7bbe7354..d892061c 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php @@ -1,6 +1,7 @@ lastOptions = $options; $response = array_shift($this->queue); + if (isset($options['on_headers'])) { + if (!is_callable($options['on_headers'])) { + throw new \InvalidArgumentException('on_headers must be callable'); + } + try { + $options['on_headers']($response); + } catch (\Exception $e) { + $msg = 'An error was encountered during the on_headers event'; + $response = new RequestException($msg, $request, $response, $e); + } + } + if (is_callable($response)) { $response = call_user_func($response, $request, $options); } $response = $response instanceof \Exception - ? new RejectedPromise($response) + ? \GuzzleHttp\Promise\rejection_for($response) : \GuzzleHttp\Promise\promise_for($response); return $response->then( @@ -107,7 +120,7 @@ function ($reason) use ($request, $options) { if ($this->onRejected) { call_user_func($this->onRejected, $reason); } - return new RejectedPromise($reason); + return \GuzzleHttp\Promise\rejection_for($reason); } ); } @@ -145,7 +158,7 @@ public function getLastRequest() /** * Get the last received request options. * - * @return RequestInterface + * @return array */ public function getLastOptions() { diff --git a/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php b/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php index 30b602e2..b12bfd94 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php @@ -67,7 +67,7 @@ public function __invoke(RequestInterface $request, array $options) $e = RequestException::wrapException($request, $e); $this->invokeStats($options, $request, $startTime, null, $e); - return new RejectedPromise($e); + return \GuzzleHttp\Promise\rejection_for($e); } } @@ -119,7 +119,7 @@ private function createResponse( } catch (\Exception $e) { $msg = 'An error was encountered during the on_headers event'; $ex = new RequestException($msg, $request, $response, $e); - return new RejectedPromise($ex); + return \GuzzleHttp\Promise\rejection_for($ex); } } @@ -210,7 +210,7 @@ private function drain( Psr7\copy_to_stream( $source, $sink, - strlen($contentLength) > 0 ? (int) $contentLength : -1 + (strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 ); $sink->seek(0); @@ -301,6 +301,18 @@ private function createStream(RequestInterface $request, array $options) ); } + // Microsoft NTLM authentication only supported with curl handler + if (isset($options['auth']) + && is_array($options['auth']) + && isset($options['auth'][2]) + && 'ntlm' == $options['auth'][2] + ) { + + throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler'); + } + + $uri = $this->resolveHost($request, $options); + $context = $this->createResource( function () use ($context, $params) { return stream_context_create($context, $params); @@ -308,14 +320,45 @@ function () use ($context, $params) { ); return $this->createResource( - function () use ($request, &$http_response_header, $context) { - $resource = fopen((string) $request->getUri()->withFragment(''), 'r', null, $context); + function () use ($uri, &$http_response_header, $context, $options) { + $resource = fopen((string) $uri, 'r', null, $context); $this->lastHeaders = $http_response_header; + + if (isset($options['read_timeout'])) { + $readTimeout = $options['read_timeout']; + $sec = (int) $readTimeout; + $usec = ($readTimeout - $sec) * 100000; + stream_set_timeout($resource, $sec, $usec); + } + return $resource; } ); } + private function resolveHost(RequestInterface $request, array $options) + { + $uri = $request->getUri(); + + if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) { + if ('v4' === $options['force_ip_resolve']) { + $records = dns_get_record($uri->getHost(), DNS_A); + if (!isset($records[0]['ip'])) { + throw new ConnectException(sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request); + } + $uri = $uri->withHost($records[0]['ip']); + } elseif ('v6' === $options['force_ip_resolve']) { + $records = dns_get_record($uri->getHost(), DNS_AAAA); + if (!isset($records[0]['ipv6'])) { + throw new ConnectException(sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request); + } + $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']'); + } + } + + return $uri; + } + private function getDefaultContext(RequestInterface $request) { $headers = ''; diff --git a/vendor/guzzlehttp/guzzle/src/Middleware.php b/vendor/guzzlehttp/guzzle/src/Middleware.php index 449ab4bf..9d79bd26 100644 --- a/vendor/guzzlehttp/guzzle/src/Middleware.php +++ b/vendor/guzzlehttp/guzzle/src/Middleware.php @@ -102,7 +102,7 @@ function ($reason) use ($request, &$container, $options) { 'error' => $reason, 'options' => $options ]; - return new RejectedPromise($reason); + return \GuzzleHttp\Promise\rejection_for($reason); } ); }; diff --git a/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php index e6d176b6..2eb95f9b 100644 --- a/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +++ b/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php @@ -14,9 +14,6 @@ class PrepareBodyMiddleware /** @var callable */ private $nextHandler; - /** @var array */ - private static $skipMethods = ['GET' => true, 'HEAD' => true]; - /** * @param callable $nextHandler Next handler to invoke. */ @@ -36,9 +33,7 @@ public function __invoke(RequestInterface $request, array $options) $fn = $this->nextHandler; // Don't do anything if the request has no body. - if (isset(self::$skipMethods[$request->getMethod()]) - || $request->getBody()->getSize() === 0 - ) { + if ($request->getBody()->getSize() === 0) { return $fn($request, $options); } @@ -54,8 +49,7 @@ public function __invoke(RequestInterface $request, array $options) } // Add a default content-length or transfer-encoding header. - if (!isset(self::$skipMethods[$request->getMethod()]) - && !$request->hasHeader('Content-Length') + if (!$request->hasHeader('Content-Length') && !$request->hasHeader('Transfer-Encoding') ) { $size = $request->getBody()->getSize(); diff --git a/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php b/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php index dbe8b87e..131b7717 100644 --- a/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php +++ b/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php @@ -19,6 +19,8 @@ class RedirectMiddleware { const HISTORY_HEADER = 'X-Guzzle-Redirect-History'; + const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History'; + public static $defaultSettings = [ 'max' => 5, 'protocols' => ['http', 'https'], @@ -108,23 +110,27 @@ public function checkRedirect( if (!empty($options['allow_redirects']['track_redirects'])) { return $this->withTracking( $promise, - (string) $nextRequest->getUri() + (string) $nextRequest->getUri(), + $response->getStatusCode() ); } return $promise; } - private function withTracking(PromiseInterface $promise, $uri) + private function withTracking(PromiseInterface $promise, $uri, $statusCode) { return $promise->then( - function (ResponseInterface $response) use ($uri) { + function (ResponseInterface $response) use ($uri, $statusCode) { // Note that we are pushing to the front of the list as this // would be an earlier response than what is currently present // in the history header. - $header = $response->getHeader(self::HISTORY_HEADER); - array_unshift($header, $uri); - return $response->withHeader(self::HISTORY_HEADER, $header); + $historyHeader = $response->getHeader(self::HISTORY_HEADER); + $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER); + array_unshift($historyHeader, $uri); + array_unshift($statusHeader, $statusCode); + return $response->withHeader(self::HISTORY_HEADER, $historyHeader) + ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader); } ); } @@ -208,9 +214,9 @@ private function redirectUri( ResponseInterface $response, array $protocols ) { - $location = Psr7\Uri::resolve( + $location = Psr7\UriResolver::resolve( $request->getUri(), - $response->getHeaderLine('Location') + new Psr7\Uri($response->getHeaderLine('Location')) ); // Ensure that the redirect URI is allowed based on the protocols. diff --git a/vendor/guzzlehttp/guzzle/src/RequestOptions.php b/vendor/guzzlehttp/guzzle/src/RequestOptions.php index 3af2f368..c6aacfb1 100644 --- a/vendor/guzzlehttp/guzzle/src/RequestOptions.php +++ b/vendor/guzzlehttp/guzzle/src/RequestOptions.php @@ -43,8 +43,8 @@ final class RequestOptions const AUTH = 'auth'; /** - * body: (string|null|callable|iterator|object) Body to send in the - * request. + * body: (resource|string|null|int|float|StreamInterface|callable|\Iterator) + * Body to send in the request. */ const BODY = 'body'; @@ -237,8 +237,19 @@ final class RequestOptions */ const TIMEOUT = 'timeout'; + /** + * read_timeout: (float, default=default_socket_timeout ini setting) Float describing + * the body read timeout, for stream requests. + */ + const READ_TIMEOUT = 'read_timeout'; + /** * version: (float) Specifies the HTTP protocol version to attempt to use. */ const VERSION = 'version'; + + /** + * force_ip_resolve: (bool) Force client to use only ipv4 or ipv6 protocol + */ + const FORCE_IP_RESOLVE = 'force_ip_resolve'; } diff --git a/vendor/guzzlehttp/guzzle/src/RetryMiddleware.php b/vendor/guzzlehttp/guzzle/src/RetryMiddleware.php index 4b95a147..f27090fd 100644 --- a/vendor/guzzlehttp/guzzle/src/RetryMiddleware.php +++ b/vendor/guzzlehttp/guzzle/src/RetryMiddleware.php @@ -5,6 +5,7 @@ use GuzzleHttp\Promise\RejectedPromise; use GuzzleHttp\Psr7; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; /** * Middleware that retries requests based on the boolean result of @@ -25,8 +26,8 @@ class RetryMiddleware * retried. * @param callable $nextHandler Next handler to invoke. * @param callable $delay Function that accepts the number of retries - * and returns the number of milliseconds to - * delay. + * and [response] and returns the number of + * milliseconds to delay. */ public function __construct( callable $decider, @@ -82,7 +83,7 @@ private function onFulfilled(RequestInterface $req, array $options) )) { return $value; } - return $this->doRetry($req, $options); + return $this->doRetry($req, $options, $value); }; } @@ -96,15 +97,15 @@ private function onRejected(RequestInterface $req, array $options) null, $reason )) { - return new RejectedPromise($reason); + return \GuzzleHttp\Promise\rejection_for($reason); } return $this->doRetry($req, $options); }; } - private function doRetry(RequestInterface $request, array $options) + private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) { - $options['delay'] = call_user_func($this->delay, ++$options['retries']); + $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); return $this($request, $options); } diff --git a/vendor/guzzlehttp/guzzle/src/functions.php b/vendor/guzzlehttp/guzzle/src/functions.php index 85cf9c64..59e212ed 100644 --- a/vendor/guzzlehttp/guzzle/src/functions.php +++ b/vendor/guzzlehttp/guzzle/src/functions.php @@ -167,6 +167,8 @@ function default_ca_bundle() '/etc/ssl/certs/ca-certificates.crt', // FreeBSD (provided by the ca_root_nss package) '/usr/local/share/certs/ca-root-nss.crt', + // SLES 12 (provided by the ca-certificates package) + '/var/lib/ca-certificates/ca-bundle.pem', // OS X provided by homebrew (using the default path) '/usr/local/etc/openssl/cert.pem', // Google app engine diff --git a/vendor/guzzlehttp/promises/.gitignore b/vendor/guzzlehttp/promises/.gitignore deleted file mode 100644 index 83ec41e2..00000000 --- a/vendor/guzzlehttp/promises/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -phpunit.xml -composer.phar -composer.lock -composer-test.lock -vendor/ -build/artifacts/ -artifacts/ -docs/_build -docs/*.pyc -.idea -.DS_STORE diff --git a/vendor/guzzlehttp/promises/.travis.yml b/vendor/guzzlehttp/promises/.travis.yml deleted file mode 100644 index 4f4d2b86..00000000 --- a/vendor/guzzlehttp/promises/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: php - -php: - - 5.5 - - 5.6 - - 7.0 - - hhvm - -sudo: false - -install: - - travis_retry composer install --no-interaction --prefer-source - -script: make test - -matrix: - allow_failures: - - php: hhvm - fast_finish: true diff --git a/vendor/guzzlehttp/promises/CHANGELOG.md b/vendor/guzzlehttp/promises/CHANGELOG.md index 99603e5d..551929f6 100644 --- a/vendor/guzzlehttp/promises/CHANGELOG.md +++ b/vendor/guzzlehttp/promises/CHANGELOG.md @@ -1,31 +1,65 @@ # CHANGELOG + +## 1.3.1 - 2016-12-20 + +### Fixed + +- `wait()` foreign promise compatibility + + +## 1.3.0 - 2016-11-18 + +### Added + +- Adds support for custom task queues. + +### Fixed + +- Fixed coroutine promise memory leak. + + ## 1.2.0 - 2016-05-18 -* Update to now catch `\Throwable` on PHP 7+ +### Changed + +- Update to now catch `\Throwable` on PHP 7+ + ## 1.1.0 - 2016-03-07 -* Update EachPromise to prevent recurring on a iterator when advancing, as this +### Changed + +- Update EachPromise to prevent recurring on a iterator when advancing, as this could trigger fatal generator errors. -* Update Promise to allow recursive waiting without unwrapping exceptions. +- Update Promise to allow recursive waiting without unwrapping exceptions. + ## 1.0.3 - 2015-10-15 -* Update EachPromise to immediately resolve when the underlying promise iterator +### Changed + +- Update EachPromise to immediately resolve when the underlying promise iterator is empty. Previously, such a promise would throw an exception when its `wait` function was called. + ## 1.0.2 - 2015-05-15 -* Conditionally require functions.php. +### Changed + +- Conditionally require functions.php. + ## 1.0.1 - 2015-06-24 -* Updating EachPromise to call next on the underlying promise iterator as late +### Changed + +- Updating EachPromise to call next on the underlying promise iterator as late as possible to ensure that generators that generate new requests based on callbacks are not iterated until after callbacks are invoked. + ## 1.0.0 - 2015-05-12 -* Initial release +- Initial release diff --git a/vendor/guzzlehttp/promises/LICENSE b/vendor/guzzlehttp/promises/LICENSE index 581d95f9..67f91a14 100644 --- a/vendor/guzzlehttp/promises/LICENSE +++ b/vendor/guzzlehttp/promises/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling +Copyright (c) 2015-2016 Michael Dowling, https://github.com/mtdowling Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/guzzlehttp/promises/README.md b/vendor/guzzlehttp/promises/README.md index 0dea8401..7b607e28 100644 --- a/vendor/guzzlehttp/promises/README.md +++ b/vendor/guzzlehttp/promises/README.md @@ -96,7 +96,7 @@ $promise->resolve('reader.'); ## Promise forwarding Promises can be chained one after the other. Each then in the chain is a new -promise. The return value of of a promise is what's forwarded to the next +promise. The return value of a promise is what's forwarded to the next promise in the chain. Returning a promise in a `then` callback will cause the subsequent promises in the chain to only be fulfilled when the returned promise has been fulfilled. The next promise in the chain will be invoked with the @@ -315,8 +315,11 @@ A promise has the following methods: - `then(callable $onFulfilled, callable $onRejected) : PromiseInterface` - Creates a new promise that is fulfilled or rejected when the promise is - resolved. + Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler. + +- `otherwise(callable $onRejected) : PromiseInterface` + + Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled. - `wait($unwrap = true) : mixed` diff --git a/vendor/guzzlehttp/promises/composer.json b/vendor/guzzlehttp/promises/composer.json index f13844b6..ec41a61e 100644 --- a/vendor/guzzlehttp/promises/composer.json +++ b/vendor/guzzlehttp/promises/composer.json @@ -1,6 +1,5 @@ { "name": "guzzlehttp/promises", - "type": "library", "description": "Guzzle promises library", "keywords": ["promise"], "license": "MIT", @@ -15,7 +14,7 @@ "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0" }, "autoload": { "psr-4": { @@ -23,9 +22,13 @@ }, "files": ["src/functions_include.php"] }, + "scripts": { + "test": "vendor/bin/phpunit", + "test-ci": "vendor/bin/phpunit --coverage-text" + }, "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } } } diff --git a/vendor/guzzlehttp/promises/phpunit.xml.dist b/vendor/guzzlehttp/promises/phpunit.xml.dist deleted file mode 100644 index 500cd53a..00000000 --- a/vendor/guzzlehttp/promises/phpunit.xml.dist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - tests - - - - - src - - src/ - - - - diff --git a/vendor/guzzlehttp/promises/src/Coroutine.php b/vendor/guzzlehttp/promises/src/Coroutine.php new file mode 100644 index 00000000..6aa09587 --- /dev/null +++ b/vendor/guzzlehttp/promises/src/Coroutine.php @@ -0,0 +1,151 @@ +then(function ($v) { echo $v; }); + * + * @param callable $generatorFn Generator function to wrap into a promise. + * + * @return Promise + * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration + */ +final class Coroutine implements PromiseInterface +{ + /** + * @var PromiseInterface|null + */ + private $currentPromise; + + /** + * @var Generator + */ + private $generator; + + /** + * @var Promise + */ + private $result; + + public function __construct(callable $generatorFn) + { + $this->generator = $generatorFn(); + $this->result = new Promise(function () { + while (isset($this->currentPromise)) { + $this->currentPromise->wait(); + } + }); + $this->nextCoroutine($this->generator->current()); + } + + public function then( + callable $onFulfilled = null, + callable $onRejected = null + ) { + return $this->result->then($onFulfilled, $onRejected); + } + + public function otherwise(callable $onRejected) + { + return $this->result->otherwise($onRejected); + } + + public function wait($unwrap = true) + { + return $this->result->wait($unwrap); + } + + public function getState() + { + return $this->result->getState(); + } + + public function resolve($value) + { + $this->result->resolve($value); + } + + public function reject($reason) + { + $this->result->reject($reason); + } + + public function cancel() + { + $this->currentPromise->cancel(); + $this->result->cancel(); + } + + private function nextCoroutine($yielded) + { + $this->currentPromise = promise_for($yielded) + ->then([$this, '_handleSuccess'], [$this, '_handleFailure']); + } + + /** + * @internal + */ + public function _handleSuccess($value) + { + unset($this->currentPromise); + try { + $next = $this->generator->send($value); + if ($this->generator->valid()) { + $this->nextCoroutine($next); + } else { + $this->result->resolve($value); + } + } catch (Exception $exception) { + $this->result->reject($exception); + } catch (Throwable $throwable) { + $this->result->reject($throwable); + } + } + + /** + * @internal + */ + public function _handleFailure($reason) + { + unset($this->currentPromise); + try { + $nextYield = $this->generator->throw(exception_for($reason)); + // The throw was caught, so keep iterating on the coroutine + $this->nextCoroutine($nextYield); + } catch (Exception $exception) { + $this->result->reject($exception); + } catch (Throwable $throwable) { + $this->result->reject($throwable); + } + } +} diff --git a/vendor/guzzlehttp/promises/src/Promise.php b/vendor/guzzlehttp/promises/src/Promise.php index 04f3ea04..844ada07 100644 --- a/vendor/guzzlehttp/promises/src/Promise.php +++ b/vendor/guzzlehttp/promises/src/Promise.php @@ -263,10 +263,17 @@ private function invokeWaitList() $this->waitList = null; foreach ($waitList as $result) { - $result->waitIfPending(); - while ($result->result instanceof Promise) { - $result = $result->result; + while (true) { $result->waitIfPending(); + + if ($result->result instanceof Promise) { + $result = $result->result; + } else { + if ($result->result instanceof PromiseInterface) { + $result->result->wait(false); + } + break; + } } } } diff --git a/vendor/guzzlehttp/promises/src/TaskQueue.php b/vendor/guzzlehttp/promises/src/TaskQueue.php index 39fe5bbb..6e8a2a08 100644 --- a/vendor/guzzlehttp/promises/src/TaskQueue.php +++ b/vendor/guzzlehttp/promises/src/TaskQueue.php @@ -10,7 +10,7 @@ * * GuzzleHttp\Promise\queue()->run(); */ -class TaskQueue +class TaskQueue implements TaskQueueInterface { private $enableShutdown = true; private $queue = []; @@ -30,30 +30,16 @@ public function __construct($withShutdown = true) } } - /** - * Returns true if the queue is empty. - * - * @return bool - */ public function isEmpty() { return !$this->queue; } - /** - * Adds a task to the queue that will be executed the next time run is - * called. - * - * @param callable $task - */ public function add(callable $task) { $this->queue[] = $task; } - /** - * Execute all of the pending task in the queue. - */ public function run() { /** @var callable $task */ diff --git a/vendor/guzzlehttp/promises/src/TaskQueueInterface.php b/vendor/guzzlehttp/promises/src/TaskQueueInterface.php new file mode 100644 index 00000000..ac8306e1 --- /dev/null +++ b/vendor/guzzlehttp/promises/src/TaskQueueInterface.php @@ -0,0 +1,25 @@ + * - * @return TaskQueue + * @param TaskQueueInterface $assign Optionally specify a new queue instance. + * + * @return TaskQueueInterface */ -function queue() +function queue(TaskQueueInterface $assign = null) { static $queue; - if (!$queue) { + if ($assign) { + $queue = $assign; + } elseif (!$queue) { $queue = new TaskQueue(); } @@ -210,7 +214,7 @@ function unwrap($promises) * * @param mixed $promises Promises or values. * - * @return Promise + * @return PromiseInterface */ function all($promises) { @@ -243,7 +247,7 @@ function ($reason, $idx, Promise $aggregate) { * @param int $count Total number of promises. * @param mixed $promises Promises or values. * - * @return Promise + * @return PromiseInterface */ function some($count, $promises) { @@ -299,7 +303,7 @@ function any($promises) * * @param mixed $promises Promises or values. * - * @return Promise + * @return PromiseInterface * @see GuzzleHttp\Promise\inspect for the inspection state array format. */ function settle($promises) @@ -337,7 +341,7 @@ function ($reason, $idx) use (&$results) { * @param callable $onFulfilled * @param callable $onRejected * - * @return Promise + * @return PromiseInterface */ function each( $iterable, @@ -363,7 +367,7 @@ function each( * @param callable $onFulfilled * @param callable $onRejected * - * @return mixed + * @return PromiseInterface */ function each_limit( $iterable, @@ -387,7 +391,7 @@ function each_limit( * @param int|callable $concurrency * @param callable $onFulfilled * - * @return mixed + * @return PromiseInterface */ function each_limit_all( $iterable, @@ -441,60 +445,13 @@ function is_settled(PromiseInterface $promise) } /** - * Creates a promise that is resolved using a generator that yields values or - * promises (somewhat similar to C#'s async keyword). - * - * When called, the coroutine function will start an instance of the generator - * and returns a promise that is fulfilled with its final yielded value. - * - * Control is returned back to the generator when the yielded promise settles. - * This can lead to less verbose code when doing lots of sequential async calls - * with minimal processing in between. - * - * use GuzzleHttp\Promise; + * @see Coroutine * - * function createPromise($value) { - * return new Promise\FulfilledPromise($value); - * } + * @param callable $generatorFn * - * $promise = Promise\coroutine(function () { - * $value = (yield createPromise('a')); - * try { - * $value = (yield createPromise($value . 'b')); - * } catch (\Exception $e) { - * // The promise was rejected. - * } - * yield $value . 'c'; - * }); - * - * // Outputs "abc" - * $promise->then(function ($v) { echo $v; }); - * - * @param callable $generatorFn Generator function to wrap into a promise. - * - * @return Promise - * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration + * @return PromiseInterface */ function coroutine(callable $generatorFn) { - $generator = $generatorFn(); - return __next_coroutine($generator->current(), $generator)->then(); -} - -/** @internal */ -function __next_coroutine($yielded, \Generator $generator) -{ - return promise_for($yielded)->then( - function ($value) use ($generator) { - $nextYield = $generator->send($value); - return $generator->valid() - ? __next_coroutine($nextYield, $generator) - : $value; - }, - function ($reason) use ($generator) { - $nextYield = $generator->throw(exception_for($reason)); - // The throw was caught, so keep iterating on the coroutine - return __next_coroutine($nextYield, $generator); - } - ); + return new Coroutine($generatorFn); } diff --git a/vendor/guzzlehttp/psr7/.gitignore b/vendor/guzzlehttp/psr7/.gitignore deleted file mode 100644 index 83ec41e2..00000000 --- a/vendor/guzzlehttp/psr7/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -phpunit.xml -composer.phar -composer.lock -composer-test.lock -vendor/ -build/artifacts/ -artifacts/ -docs/_build -docs/*.pyc -.idea -.DS_STORE diff --git a/vendor/guzzlehttp/psr7/.travis.yml b/vendor/guzzlehttp/psr7/.travis.yml deleted file mode 100644 index b88f8da2..00000000 --- a/vendor/guzzlehttp/psr7/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: php - -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - hhvm - -sudo: false - -install: - - travis_retry composer install --no-interaction --prefer-source - -script: make test - -matrix: - allow_failures: - - php: hhvm - fast_finish: true diff --git a/vendor/guzzlehttp/psr7/CHANGELOG.md b/vendor/guzzlehttp/psr7/CHANGELOG.md index 0771a9ac..5c252b3a 100644 --- a/vendor/guzzlehttp/psr7/CHANGELOG.md +++ b/vendor/guzzlehttp/psr7/CHANGELOG.md @@ -1,5 +1,45 @@ # CHANGELOG +## 1.4.2 - 2017-03-20 + +* Reverted BC break to `Uri::resolve` and `Uri::removeDotSegments` by removing + calls to `trigger_error` when deprecated methods are invoked. + +## 1.4.1 - 2017-02-27 + +* Reverted BC break by reintroducing behavior to automagically fix a URI with a + relative path and an authority by adding a leading slash to the path. It's only + deprecated now. +* Added triggering of silenced deprecation warnings. + +## 1.4.0 - 2017-02-21 + +* Fix `Stream::read` when length parameter <= 0. +* `copy_to_stream` reads bytes in chunks instead of `maxLen` into memory. +* Fix `ServerRequest::getUriFromGlobals` when `Host` header contains port. +* Ensure `ServerRequest::getUriFromGlobals` returns a URI in absolute form. +* Allow `parse_response` to parse a response without delimiting space and reason. +* Ensure each URI modification results in a valid URI according to PSR-7 discussions. + Invalid modifications will throw an exception instead of returning a wrong URI or + doing some magic. + - `(new Uri)->withPath('foo')->withHost('example.com')` will throw an exception + because the path of a URI with an authority must start with a slash "/" or be empty + - `(new Uri())->withScheme('http')` will return `'http://localhost'` +* Fix compatibility of URIs with `file` scheme and empty host. +* Added common URI utility methods based on RFC 3986 (see documentation in the readme): + - `Uri::isDefaultPort` + - `Uri::isAbsolute` + - `Uri::isNetworkPathReference` + - `Uri::isAbsolutePathReference` + - `Uri::isRelativePathReference` + - `Uri::isSameDocumentReference` + - `Uri::composeComponents` + - `UriNormalizer::normalize` + - `UriNormalizer::isEquivalent` + - `UriResolver::relativize` +* Deprecated `Uri::resolve` in favor of `UriResolver::resolve` +* Deprecated `Uri::removeDotSegments` in favor of `UriResolver::removeDotSegments` + ## 1.3.1 - 2016-06-25 * Fix `Uri::__toString` for network path references, e.g. `//example.org`. diff --git a/vendor/guzzlehttp/psr7/Makefile b/vendor/guzzlehttp/psr7/Makefile deleted file mode 100644 index 8b00b43e..00000000 --- a/vendor/guzzlehttp/psr7/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -all: clean test - -test: - vendor/bin/phpunit $(TEST) - -coverage: - vendor/bin/phpunit --coverage-html=artifacts/coverage $(TEST) - -view-coverage: - open artifacts/coverage/index.html - -check-tag: - $(if $(TAG),,$(error TAG is not defined. Pass via "make tag TAG=4.2.1")) - -tag: check-tag - @echo Tagging $(TAG) - chag update $(TAG) - git commit -a -m '$(TAG) release' - chag tag - @echo "Release has been created. Push using 'make release'" - @echo "Changes made in the release commit" - git diff HEAD~1 HEAD - -release: check-tag - git push origin master - git push origin $(TAG) - -clean: - rm -rf artifacts/* diff --git a/vendor/guzzlehttp/psr7/README.md b/vendor/guzzlehttp/psr7/README.md index 2642164f..16499358 100644 --- a/vendor/guzzlehttp/psr7/README.md +++ b/vendor/guzzlehttp/psr7/README.md @@ -519,51 +519,221 @@ Determines the mimetype of a file by looking at its extension. Maps a file extensions to a mimetype. -# Static URI methods +# Additional URI Methods -The `GuzzleHttp\Psr7\Uri` class has several static methods to manipulate URIs. +Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class, +this library also provides additional functionality when working with URIs as static methods. +## URI Types -## `GuzzleHttp\Psr7\Uri::removeDotSegments` +An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference. +An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI, +the base URI. Relative references can be divided into several forms according to +[RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2): -`public static function removeDotSegments(string $path): string` +- network-path references, e.g. `//example.com/path` +- absolute-path references, e.g. `/path` +- relative-path references, e.g. `subpath` -Removes dot segments from a path and returns the new path. +The following methods can be used to identify the type of the URI. -See http://tools.ietf.org/html/rfc3986#section-5.2.4 +### `GuzzleHttp\Psr7\Uri::isAbsolute` +`public static function isAbsolute(UriInterface $uri): bool` -## `GuzzleHttp\Psr7\Uri::resolve` +Whether the URI is absolute, i.e. it has a scheme. -`public static function resolve(UriInterface $base, $rel): UriInterface` +### `GuzzleHttp\Psr7\Uri::isNetworkPathReference` -Resolve a base URI with a relative URI and return a new URI. +`public static function isNetworkPathReference(UriInterface $uri): bool` -See http://tools.ietf.org/html/rfc3986#section-5 +Whether the URI is a network-path reference. A relative reference that begins with two slash characters is +termed an network-path reference. +### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference` -## `GuzzleHttp\Psr7\Uri::withQueryValue` +`public static function isAbsolutePathReference(UriInterface $uri): bool` -`public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface` +Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is +termed an absolute-path reference. -Create a new URI with a specific query string value. +### `GuzzleHttp\Psr7\Uri::isRelativePathReference` -Any existing query string values that exactly match the provided key are -removed and replaced with the given key value pair. +`public static function isRelativePathReference(UriInterface $uri): bool` +Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is +termed a relative-path reference. -## `GuzzleHttp\Psr7\Uri::withoutQueryValue` +### `GuzzleHttp\Psr7\Uri::isSameDocumentReference` -`public static function withoutQueryValue(UriInterface $uri, $key): UriInterface` +`public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool` + +Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its +fragment component, identical to the base URI. When no base URI is given, only an empty URI reference +(apart from its fragment) is considered a same-document reference. + +## URI Components + +Additional methods to work with URI components. + +### `GuzzleHttp\Psr7\Uri::isDefaultPort` + +`public static function isDefaultPort(UriInterface $uri): bool` + +Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null +or the standard port. This method can be used independently of the implementation. -Create a new URI with a specific query string value removed. +### `GuzzleHttp\Psr7\Uri::composeComponents` -Any existing query string values that exactly match the provided key are -removed. +`public static function composeComponents($scheme, $authority, $path, $query, $fragment): string` +Composes a URI reference string from its various components according to +[RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called +manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`. -## `GuzzleHttp\Psr7\Uri::fromParts` +### `GuzzleHttp\Psr7\Uri::fromParts` `public static function fromParts(array $parts): UriInterface` -Create a `GuzzleHttp\Psr7\Uri` object from a hash of `parse_url` parts. +Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components. + + +### `GuzzleHttp\Psr7\Uri::withQueryValue` + +`public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface` + +Creates a new URI with a specific query string value. Any existing query string values that exactly match the +provided key are removed and replaced with the given key value pair. A value of null will set the query string +key without a value, e.g. "key" instead of "key=value". + + +### `GuzzleHttp\Psr7\Uri::withoutQueryValue` + +`public static function withoutQueryValue(UriInterface $uri, $key): UriInterface` + +Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the +provided key are removed. + +## Reference Resolution + +`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according +to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers +do when resolving a link in a website based on the current request URI. + +### `GuzzleHttp\Psr7\UriResolver::resolve` + +`public static function resolve(UriInterface $base, UriInterface $rel): UriInterface` + +Converts the relative URI into a new URI that is resolved against the base URI. + +### `GuzzleHttp\Psr7\UriResolver::removeDotSegments` + +`public static function removeDotSegments(string $path): string` + +Removes dot segments from a path and returns the new path according to +[RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4). + +### `GuzzleHttp\Psr7\UriResolver::relativize` + +`public static function relativize(UriInterface $base, UriInterface $target): UriInterface` + +Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve(): + +```php +(string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target)) +``` + +One use-case is to use the current request URI as base URI and then generate relative links in your documents +to reduce the document size or offer self-contained downloadable document archives. + +```php +$base = new Uri('http://example.com/a/b/'); +echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. +echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. +echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. +echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'. +``` + +## Normalization and Comparison + +`GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to +[RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6). + +### `GuzzleHttp\Psr7\UriNormalizer::normalize` + +`public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface` + +Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface. +This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask +of normalizations to apply. The following normalizations are available: + +- `UriNormalizer::PRESERVING_NORMALIZATIONS` + + Default normalizations which only include the ones that preserve semantics. + +- `UriNormalizer::CAPITALIZE_PERCENT_ENCODING` + + All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized. + + Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b` + +- `UriNormalizer::DECODE_UNRESERVED_CHARACTERS` + + Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of + ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should + not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved + characters by URI normalizers. + + Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/` + +- `UriNormalizer::CONVERT_EMPTY_PATH` + + Converts the empty path to "/" for http and https URIs. + + Example: `http://example.org` → `http://example.org/` + +- `UriNormalizer::REMOVE_DEFAULT_HOST` + + Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host + "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to + RFC 3986. + + Example: `file://localhost/myfile` → `file:///myfile` + +- `UriNormalizer::REMOVE_DEFAULT_PORT` + + Removes the default port of the given URI scheme from the URI. + + Example: `http://example.org:80/` → `http://example.org/` + +- `UriNormalizer::REMOVE_DOT_SEGMENTS` + + Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would + change the semantics of the URI reference. + + Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html` + +- `UriNormalizer::REMOVE_DUPLICATE_SLASHES` + + Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes + and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization + may change the semantics. Encoded slashes (%2F) are not removed. + + Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html` + +- `UriNormalizer::SORT_QUERY_PARAMETERS` + + Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be + significant (this is not defined by the standard). So this normalization is not safe and may change the semantics + of the URI. + + Example: `?lang=en&article=fred` → `?article=fred&lang=en` + +### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent` + +`public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool` + +Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given +`$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent. +This of course assumes they will be resolved against the same base URI. If this is not the case, determination of +equivalence or difference of relative references does not mean anything. diff --git a/vendor/guzzlehttp/psr7/composer.json b/vendor/guzzlehttp/psr7/composer.json index fdfb97bd..b1c5a90b 100644 --- a/vendor/guzzlehttp/psr7/composer.json +++ b/vendor/guzzlehttp/psr7/composer.json @@ -1,14 +1,18 @@ { "name": "guzzlehttp/psr7", "type": "library", - "description": "PSR-7 message implementation", - "keywords": ["message", "stream", "http", "uri"], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": ["request", "response", "message", "stream", "http", "uri", "url"], "license": "MIT", "authors": [ { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" } ], "require": { diff --git a/vendor/guzzlehttp/psr7/phpunit.xml.dist b/vendor/guzzlehttp/psr7/phpunit.xml.dist deleted file mode 100644 index 500cd53a..00000000 --- a/vendor/guzzlehttp/psr7/phpunit.xml.dist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - tests - - - - - src - - src/ - - - - diff --git a/vendor/guzzlehttp/psr7/src/LimitStream.php b/vendor/guzzlehttp/psr7/src/LimitStream.php index 7f2298bc..3c13d4f4 100644 --- a/vendor/guzzlehttp/psr7/src/LimitStream.php +++ b/vendor/guzzlehttp/psr7/src/LimitStream.php @@ -21,7 +21,7 @@ class LimitStream implements StreamInterface * @param StreamInterface $stream Stream to wrap * @param int $limit Total number of bytes to allow to be read * from the stream. Pass -1 for no limit. - * @param int|null $offset Position to seek to before reading (only + * @param int $offset Position to seek to before reading (only * works on seekable streams). */ public function __construct( diff --git a/vendor/guzzlehttp/psr7/src/MultipartStream.php b/vendor/guzzlehttp/psr7/src/MultipartStream.php index 2988fcba..c0fd584f 100644 --- a/vendor/guzzlehttp/psr7/src/MultipartStream.php +++ b/vendor/guzzlehttp/psr7/src/MultipartStream.php @@ -27,7 +27,7 @@ class MultipartStream implements StreamInterface */ public function __construct(array $elements = [], $boundary = null) { - $this->boundary = $boundary ?: uniqid(); + $this->boundary = $boundary ?: sha1(uniqid('', true)); $this->stream = $this->createStream($elements); } @@ -108,7 +108,7 @@ private function addElement(AppendStream $stream, array $element) /** * @return array */ - private function createElement($name, $stream, $filename, array $headers) + private function createElement($name, StreamInterface $stream, $filename, array $headers) { // Set a default content-disposition header if one was no provided $disposition = $this->getHeader($headers, 'content-disposition'); diff --git a/vendor/guzzlehttp/psr7/src/Request.php b/vendor/guzzlehttp/psr7/src/Request.php index 4a3db6ec..08285484 100644 --- a/vendor/guzzlehttp/psr7/src/Request.php +++ b/vendor/guzzlehttp/psr7/src/Request.php @@ -19,7 +19,7 @@ class Request implements RequestInterface /** @var null|string */ private $requestTarget; - /** @var null|UriInterface */ + /** @var UriInterface */ private $uri; /** diff --git a/vendor/guzzlehttp/psr7/src/Response.php b/vendor/guzzlehttp/psr7/src/Response.php index 841ff020..2830c6c9 100644 --- a/vendor/guzzlehttp/psr7/src/Response.php +++ b/vendor/guzzlehttp/psr7/src/Response.php @@ -2,6 +2,7 @@ namespace GuzzleHttp\Psr7; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; /** * PSR-7 response implementation. @@ -100,7 +101,7 @@ public function __construct( $this->setHeaders($headers); if ($reason == '' && isset(self::$phrases[$this->statusCode])) { - $this->reasonPhrase = self::$phrases[$status]; + $this->reasonPhrase = self::$phrases[$this->statusCode]; } else { $this->reasonPhrase = (string) $reason; } diff --git a/vendor/guzzlehttp/psr7/src/ServerRequest.php b/vendor/guzzlehttp/psr7/src/ServerRequest.php index a6a47bec..575aab84 100644 --- a/vendor/guzzlehttp/psr7/src/ServerRequest.php +++ b/vendor/guzzlehttp/psr7/src/ServerRequest.php @@ -188,25 +188,37 @@ public static function fromGlobals() public static function getUriFromGlobals() { $uri = new Uri(''); - if (isset($_SERVER['HTTPS'])) { - $uri = $uri->withScheme($_SERVER['HTTPS'] == 'on' ? 'https' : 'http'); - } + $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http'); + $hasPort = false; if (isset($_SERVER['HTTP_HOST'])) { - $uri = $uri->withHost($_SERVER['HTTP_HOST']); + $hostHeaderParts = explode(':', $_SERVER['HTTP_HOST']); + $uri = $uri->withHost($hostHeaderParts[0]); + if (isset($hostHeaderParts[1])) { + $hasPort = true; + $uri = $uri->withPort($hostHeaderParts[1]); + } } elseif (isset($_SERVER['SERVER_NAME'])) { $uri = $uri->withHost($_SERVER['SERVER_NAME']); + } elseif (isset($_SERVER['SERVER_ADDR'])) { + $uri = $uri->withHost($_SERVER['SERVER_ADDR']); } - if (isset($_SERVER['SERVER_PORT'])) { + if (!$hasPort && isset($_SERVER['SERVER_PORT'])) { $uri = $uri->withPort($_SERVER['SERVER_PORT']); } + $hasQuery = false; if (isset($_SERVER['REQUEST_URI'])) { - $uri = $uri->withPath(current(explode('?', $_SERVER['REQUEST_URI']))); + $requestUriParts = explode('?', $_SERVER['REQUEST_URI']); + $uri = $uri->withPath($requestUriParts[0]); + if (isset($requestUriParts[1])) { + $hasQuery = true; + $uri = $uri->withQuery($requestUriParts[1]); + } } - if (isset($_SERVER['QUERY_STRING'])) { + if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) { $uri = $uri->withQuery($_SERVER['QUERY_STRING']); } diff --git a/vendor/guzzlehttp/psr7/src/Stream.php b/vendor/guzzlehttp/psr7/src/Stream.php index 214af151..e3366287 100644 --- a/vendor/guzzlehttp/psr7/src/Stream.php +++ b/vendor/guzzlehttp/psr7/src/Stream.php @@ -207,8 +207,20 @@ public function read($length) if (!$this->readable) { throw new \RuntimeException('Cannot read from non-readable stream'); } + if ($length < 0) { + throw new \RuntimeException('Length parameter cannot be negative'); + } + + if (0 === $length) { + return ''; + } + + $string = fread($this->stream, $length); + if (false === $string) { + throw new \RuntimeException('Unable to read from stream'); + } - return fread($this->stream, $length); + return $string; } public function write($string) diff --git a/vendor/guzzlehttp/psr7/src/Uri.php b/vendor/guzzlehttp/psr7/src/Uri.php index 44a1e9d4..f46c1db9 100644 --- a/vendor/guzzlehttp/psr7/src/Uri.php +++ b/vendor/guzzlehttp/psr7/src/Uri.php @@ -12,9 +12,26 @@ */ class Uri implements UriInterface { - private static $schemes = [ + /** + * Absolute http and https URIs require a host per RFC 7230 Section 2.7 + * but in generic URIs the host can be empty. So for http(s) URIs + * we apply this default host when no host is given yet to form a + * valid URI. + */ + const HTTP_DEFAULT_HOST = 'localhost'; + + private static $defaultPorts = [ 'http' => 80, 'https' => 443, + 'ftp' => 21, + 'gopher' => 70, + 'nntp' => 119, + 'news' => 119, + 'telnet' => 23, + 'tn3270' => 23, + 'imap' => 143, + 'pop' => 110, + 'ldap' => 389, ]; private static $charUnreserved = 'a-zA-Z0-9_\-\.~'; @@ -47,6 +64,7 @@ class Uri implements UriInterface */ public function __construct($uri = '') { + // weak type check to also accept null until we can add scalar type hints if ($uri != '') { $parts = parse_url($uri); if ($parts === false) { @@ -58,7 +76,7 @@ public function __construct($uri = '') public function __toString() { - return self::createUriString( + return self::composeComponents( $this->scheme, $this->getAuthority(), $this->path, @@ -68,56 +86,198 @@ public function __toString() } /** - * Removes dot segments from a path and returns the new path. + * Composes a URI reference string from its various components. + * + * Usually this method does not need to be called manually but instead is used indirectly via + * `Psr\Http\Message\UriInterface::__toString`. + * + * PSR-7 UriInterface treats an empty component the same as a missing component as + * getQuery(), getFragment() etc. always return a string. This explains the slight + * difference to RFC 3986 Section 5.3. * + * Another adjustment is that the authority separator is added even when the authority is missing/empty + * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with + * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But + * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to + * that format). + * + * @param string $scheme + * @param string $authority * @param string $path + * @param string $query + * @param string $fragment * * @return string - * @link http://tools.ietf.org/html/rfc3986#section-5.2.4 + * + * @link https://tools.ietf.org/html/rfc3986#section-5.3 */ - public static function removeDotSegments($path) + public static function composeComponents($scheme, $authority, $path, $query, $fragment) { - static $noopPaths = ['' => true, '/' => true, '*' => true]; - static $ignoreSegments = ['.' => true, '..' => true]; + $uri = ''; - if (isset($noopPaths[$path])) { - return $path; + // weak type checks to also accept null until we can add scalar type hints + if ($scheme != '') { + $uri .= $scheme . ':'; } - $results = []; - $segments = explode('/', $path); - foreach ($segments as $segment) { - if ($segment === '..') { - array_pop($results); - } elseif (!isset($ignoreSegments[$segment])) { - $results[] = $segment; - } + if ($authority != ''|| $scheme === 'file') { + $uri .= '//' . $authority; } - $newPath = implode('/', $results); - // Add the leading slash if necessary - if (substr($path, 0, 1) === '/' && - substr($newPath, 0, 1) !== '/' - ) { - $newPath = '/' . $newPath; + $uri .= $path; + + if ($query != '') { + $uri .= '?' . $query; } - // Add the trailing slash if necessary - if ($newPath !== '/' && isset($ignoreSegments[end($segments)])) { - $newPath .= '/'; + if ($fragment != '') { + $uri .= '#' . $fragment; } - return $newPath; + return $uri; + } + + /** + * Whether the URI has the default port of the current scheme. + * + * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used + * independently of the implementation. + * + * @param UriInterface $uri + * + * @return bool + */ + public static function isDefaultPort(UriInterface $uri) + { + return $uri->getPort() === null + || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]); } /** - * Resolve a base URI with a relative URI and return a new URI. + * Whether the URI is absolute, i.e. it has a scheme. + * + * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true + * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative + * to another URI, the base URI. Relative references can be divided into several forms: + * - network-path references, e.g. '//example.com/path' + * - absolute-path references, e.g. '/path' + * - relative-path references, e.g. 'subpath' + * + * @param UriInterface $uri + * + * @return bool + * @see Uri::isNetworkPathReference + * @see Uri::isAbsolutePathReference + * @see Uri::isRelativePathReference + * @link https://tools.ietf.org/html/rfc3986#section-4 + */ + public static function isAbsolute(UriInterface $uri) + { + return $uri->getScheme() !== ''; + } + + /** + * Whether the URI is a network-path reference. + * + * A relative reference that begins with two slash characters is termed an network-path reference. + * + * @param UriInterface $uri + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public static function isNetworkPathReference(UriInterface $uri) + { + return $uri->getScheme() === '' && $uri->getAuthority() !== ''; + } + + /** + * Whether the URI is a absolute-path reference. + * + * A relative reference that begins with a single slash character is termed an absolute-path reference. + * + * @param UriInterface $uri + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public static function isAbsolutePathReference(UriInterface $uri) + { + return $uri->getScheme() === '' + && $uri->getAuthority() === '' + && isset($uri->getPath()[0]) + && $uri->getPath()[0] === '/'; + } + + /** + * Whether the URI is a relative-path reference. + * + * A relative reference that does not begin with a slash character is termed a relative-path reference. + * + * @param UriInterface $uri + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public static function isRelativePathReference(UriInterface $uri) + { + return $uri->getScheme() === '' + && $uri->getAuthority() === '' + && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/'); + } + + /** + * Whether the URI is a same-document reference. + * + * A same-document reference refers to a URI that is, aside from its fragment + * component, identical to the base URI. When no base URI is given, only an empty + * URI reference (apart from its fragment) is considered a same-document reference. + * + * @param UriInterface $uri The URI to check + * @param UriInterface|null $base An optional base URI to compare against + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.4 + */ + public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null) + { + if ($base !== null) { + $uri = UriResolver::resolve($base, $uri); + + return ($uri->getScheme() === $base->getScheme()) + && ($uri->getAuthority() === $base->getAuthority()) + && ($uri->getPath() === $base->getPath()) + && ($uri->getQuery() === $base->getQuery()); + } + + return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === ''; + } + + /** + * Removes dot segments from a path and returns the new path. + * + * @param string $path + * + * @return string + * + * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead. + * @see UriResolver::removeDotSegments + */ + public static function removeDotSegments($path) + { + return UriResolver::removeDotSegments($path); + } + + /** + * Converts the relative URI into a new URI that is resolved against the base URI. * * @param UriInterface $base Base URI * @param string|UriInterface $rel Relative URI * * @return UriInterface - * @link http://tools.ietf.org/html/rfc3986#section-5.2 + * + * @deprecated since version 1.4. Use UriResolver::resolve instead. + * @see UriResolver::resolve */ public static function resolve(UriInterface $base, $rel) { @@ -125,55 +285,11 @@ public static function resolve(UriInterface $base, $rel) $rel = new self($rel); } - if ((string) $rel === '') { - // we can simply return the same base URI instance for this same-document reference - return $base; - } - - if ($rel->getScheme() != '') { - return $rel->withPath(self::removeDotSegments($rel->getPath())); - } - - if ($rel->getAuthority() != '') { - $targetAuthority = $rel->getAuthority(); - $targetPath = self::removeDotSegments($rel->getPath()); - $targetQuery = $rel->getQuery(); - } else { - $targetAuthority = $base->getAuthority(); - if ($rel->getPath() === '') { - $targetPath = $base->getPath(); - $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery(); - } else { - if ($rel->getPath()[0] === '/') { - $targetPath = $rel->getPath(); - } else { - if ($targetAuthority != '' && $base->getPath() === '') { - $targetPath = '/' . $rel->getPath(); - } else { - $lastSlashPos = strrpos($base->getPath(), '/'); - if ($lastSlashPos === false) { - $targetPath = $rel->getPath(); - } else { - $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath(); - } - } - } - $targetPath = self::removeDotSegments($targetPath); - $targetQuery = $rel->getQuery(); - } - } - - return new self(self::createUriString( - $base->getScheme(), - $targetAuthority, - $targetPath, - $targetQuery, - $rel->getFragment() - )); + return UriResolver::resolve($base, $rel); } /** - * Create a new URI with a specific query string value removed. + * Creates a new URI with a specific query string value removed. * * Any existing query string values that exactly match the provided key are * removed. @@ -186,7 +302,7 @@ public static function resolve(UriInterface $base, $rel) public static function withoutQueryValue(UriInterface $uri, $key) { $current = $uri->getQuery(); - if ($current == '') { + if ($current === '') { return $uri; } @@ -199,7 +315,7 @@ public static function withoutQueryValue(UriInterface $uri, $key) } /** - * Create a new URI with a specific query string value. + * Creates a new URI with a specific query string value. * * Any existing query string values that exactly match the provided key are * removed and replaced with the given key value pair. @@ -217,7 +333,7 @@ public static function withQueryValue(UriInterface $uri, $key, $value) { $current = $uri->getQuery(); - if ($current == '') { + if ($current === '') { $result = []; } else { $decodedKey = rawurldecode($key); @@ -241,16 +357,21 @@ public static function withQueryValue(UriInterface $uri, $key, $value) } /** - * Create a URI from a hash of parse_url parts. + * Creates a URI from a hash of `parse_url` components. * * @param array $parts * - * @return self + * @return UriInterface + * @link http://php.net/manual/en/function.parse-url.php + * + * @throws \InvalidArgumentException If the components do not form a valid URI. */ public static function fromParts(array $parts) { $uri = new self(); $uri->applyParts($parts); + $uri->validateState(); + return $uri; } @@ -261,12 +382,8 @@ public function getScheme() public function getAuthority() { - if ($this->host == '') { - return ''; - } - $authority = $this->host; - if ($this->userInfo != '') { + if ($this->userInfo !== '') { $authority = $this->userInfo . '@' . $authority; } @@ -317,7 +434,9 @@ public function withScheme($scheme) $new = clone $this; $new->scheme = $scheme; - $new->port = $new->filterPort($new->port); + $new->removeDefaultPort(); + $new->validateState(); + return $new; } @@ -334,6 +453,8 @@ public function withUserInfo($user, $password = null) $new = clone $this; $new->userInfo = $info; + $new->validateState(); + return $new; } @@ -347,6 +468,8 @@ public function withHost($host) $new = clone $this; $new->host = $host; + $new->validateState(); + return $new; } @@ -360,6 +483,9 @@ public function withPort($port) $new = clone $this; $new->port = $port; + $new->removeDefaultPort(); + $new->validateState(); + return $new; } @@ -373,6 +499,8 @@ public function withPath($path) $new = clone $this; $new->path = $path; + $new->validateState(); + return $new; } @@ -386,6 +514,7 @@ public function withQuery($query) $new = clone $this; $new->query = $query; + return $new; } @@ -399,6 +528,7 @@ public function withFragment($fragment) $new = clone $this; $new->fragment = $fragment; + return $new; } @@ -431,69 +561,8 @@ private function applyParts(array $parts) if (isset($parts['pass'])) { $this->userInfo .= ':' . $parts['pass']; } - } - - /** - * Create a URI string from its various parts - * - * @param string $scheme - * @param string $authority - * @param string $path - * @param string $query - * @param string $fragment - * @return string - */ - private static function createUriString($scheme, $authority, $path, $query, $fragment) - { - $uri = ''; - - if ($scheme != '') { - $uri .= $scheme . ':'; - } - - if ($authority != '') { - $uri .= '//' . $authority; - } - - if ($path != '') { - if ($path[0] !== '/') { - if ($authority != '') { - // If the path is rootless and an authority is present, the path MUST be prefixed by "/" - $path = '/' . $path; - } - } elseif (isset($path[1]) && $path[1] === '/') { - if ($authority == '') { - // If the path is starting with more than one "/" and no authority is present, the - // starting slashes MUST be reduced to one. - $path = '/' . ltrim($path, '/'); - } - } - - $uri .= $path; - } - - if ($query != '') { - $uri .= '?' . $query; - } - - if ($fragment != '') { - $uri .= '#' . $fragment; - } - - return $uri; - } - /** - * Is a given port non-standard for the current scheme? - * - * @param string $scheme - * @param int $port - * - * @return bool - */ - private static function isNonStandardPort($scheme, $port) - { - return !isset(self::$schemes[$scheme]) || $port !== self::$schemes[$scheme]; + $this->removeDefaultPort(); } /** @@ -548,7 +617,14 @@ private function filterPort($port) ); } - return self::isNonStandardPort($this->scheme, $port) ? $port : null; + return $port; + } + + private function removeDefaultPort() + { + if ($this->port !== null && self::isDefaultPort($this)) { + $this->port = null; + } } /** @@ -599,4 +675,28 @@ private function rawurlencodeMatchZero(array $match) { return rawurlencode($match[0]); } + + private function validateState() + { + if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) { + $this->host = self::HTTP_DEFAULT_HOST; + } + + if ($this->getAuthority() === '') { + if (0 === strpos($this->path, '//')) { + throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"'); + } + if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) { + throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon'); + } + } elseif (isset($this->path[0]) && $this->path[0] !== '/') { + @trigger_error( + 'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' . + 'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.', + E_USER_DEPRECATED + ); + $this->path = '/'. $this->path; + //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty'); + } + } } diff --git a/vendor/guzzlehttp/psr7/src/UriNormalizer.php b/vendor/guzzlehttp/psr7/src/UriNormalizer.php new file mode 100644 index 00000000..384c29e5 --- /dev/null +++ b/vendor/guzzlehttp/psr7/src/UriNormalizer.php @@ -0,0 +1,216 @@ +getPath() === '' && + ($uri->getScheme() === 'http' || $uri->getScheme() === 'https') + ) { + $uri = $uri->withPath('/'); + } + + if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') { + $uri = $uri->withHost(''); + } + + if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) { + $uri = $uri->withPort(null); + } + + if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) { + $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath())); + } + + if ($flags & self::REMOVE_DUPLICATE_SLASHES) { + $uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath())); + } + + if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') { + $queryKeyValues = explode('&', $uri->getQuery()); + sort($queryKeyValues); + $uri = $uri->withQuery(implode('&', $queryKeyValues)); + } + + return $uri; + } + + /** + * Whether two URIs can be considered equivalent. + * + * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also + * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be + * resolved against the same base URI. If this is not the case, determination of equivalence or difference of + * relative references does not mean anything. + * + * @param UriInterface $uri1 An URI to compare + * @param UriInterface $uri2 An URI to compare + * @param int $normalizations A bitmask of normalizations to apply, see constants + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-6.1 + */ + public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS) + { + return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations); + } + + private static function capitalizePercentEncoding(UriInterface $uri) + { + $regex = '/(?:%[A-Fa-f0-9]{2})++/'; + + $callback = function (array $match) { + return strtoupper($match[0]); + }; + + return + $uri->withPath( + preg_replace_callback($regex, $callback, $uri->getPath()) + )->withQuery( + preg_replace_callback($regex, $callback, $uri->getQuery()) + ); + } + + private static function decodeUnreservedCharacters(UriInterface $uri) + { + $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i'; + + $callback = function (array $match) { + return rawurldecode($match[0]); + }; + + return + $uri->withPath( + preg_replace_callback($regex, $callback, $uri->getPath()) + )->withQuery( + preg_replace_callback($regex, $callback, $uri->getQuery()) + ); + } + + private function __construct() + { + // cannot be instantiated + } +} diff --git a/vendor/guzzlehttp/psr7/src/UriResolver.php b/vendor/guzzlehttp/psr7/src/UriResolver.php new file mode 100644 index 00000000..c1cb8a27 --- /dev/null +++ b/vendor/guzzlehttp/psr7/src/UriResolver.php @@ -0,0 +1,219 @@ +getScheme() != '') { + return $rel->withPath(self::removeDotSegments($rel->getPath())); + } + + if ($rel->getAuthority() != '') { + $targetAuthority = $rel->getAuthority(); + $targetPath = self::removeDotSegments($rel->getPath()); + $targetQuery = $rel->getQuery(); + } else { + $targetAuthority = $base->getAuthority(); + if ($rel->getPath() === '') { + $targetPath = $base->getPath(); + $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery(); + } else { + if ($rel->getPath()[0] === '/') { + $targetPath = $rel->getPath(); + } else { + if ($targetAuthority != '' && $base->getPath() === '') { + $targetPath = '/' . $rel->getPath(); + } else { + $lastSlashPos = strrpos($base->getPath(), '/'); + if ($lastSlashPos === false) { + $targetPath = $rel->getPath(); + } else { + $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath(); + } + } + } + $targetPath = self::removeDotSegments($targetPath); + $targetQuery = $rel->getQuery(); + } + } + + return new Uri(Uri::composeComponents( + $base->getScheme(), + $targetAuthority, + $targetPath, + $targetQuery, + $rel->getFragment() + )); + } + + /** + * Returns the target URI as a relative reference from the base URI. + * + * This method is the counterpart to resolve(): + * + * (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target)) + * + * One use-case is to use the current request URI as base URI and then generate relative links in your documents + * to reduce the document size or offer self-contained downloadable document archives. + * + * $base = new Uri('http://example.com/a/b/'); + * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. + * echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. + * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. + * echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'. + * + * This method also accepts a target that is already relative and will try to relativize it further. Only a + * relative-path reference will be returned as-is. + * + * echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well + * + * @param UriInterface $base Base URI + * @param UriInterface $target Target URI + * + * @return UriInterface The relative URI reference + */ + public static function relativize(UriInterface $base, UriInterface $target) + { + if ($target->getScheme() !== '' && + ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '') + ) { + return $target; + } + + if (Uri::isRelativePathReference($target)) { + // As the target is already highly relative we return it as-is. It would be possible to resolve + // the target with `$target = self::resolve($base, $target);` and then try make it more relative + // by removing a duplicate query. But let's not do that automatically. + return $target; + } + + if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) { + return $target->withScheme(''); + } + + // We must remove the path before removing the authority because if the path starts with two slashes, the URI + // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also + // invalid. + $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost(''); + + if ($base->getPath() !== $target->getPath()) { + return $emptyPathUri->withPath(self::getRelativePath($base, $target)); + } + + if ($base->getQuery() === $target->getQuery()) { + // Only the target fragment is left. And it must be returned even if base and target fragment are the same. + return $emptyPathUri->withQuery(''); + } + + // If the base URI has a query but the target has none, we cannot return an empty path reference as it would + // inherit the base query component when resolving. + if ($target->getQuery() === '') { + $segments = explode('/', $target->getPath()); + $lastSegment = end($segments); + + return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment); + } + + return $emptyPathUri; + } + + private static function getRelativePath(UriInterface $base, UriInterface $target) + { + $sourceSegments = explode('/', $base->getPath()); + $targetSegments = explode('/', $target->getPath()); + array_pop($sourceSegments); + $targetLastSegment = array_pop($targetSegments); + foreach ($sourceSegments as $i => $segment) { + if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) { + unset($sourceSegments[$i], $targetSegments[$i]); + } else { + break; + } + } + $targetSegments[] = $targetLastSegment; + $relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments); + + // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./". + // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used + // as the first segment of a relative-path reference, as it would be mistaken for a scheme name. + if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) { + $relativePath = "./$relativePath"; + } elseif ('/' === $relativePath[0]) { + if ($base->getAuthority() != '' && $base->getPath() === '') { + // In this case an extra slash is added by resolve() automatically. So we must not add one here. + $relativePath = ".$relativePath"; + } else { + $relativePath = "./$relativePath"; + } + } + + return $relativePath; + } + + private function __construct() + { + // cannot be instantiated + } +} diff --git a/vendor/guzzlehttp/psr7/src/functions.php b/vendor/guzzlehttp/psr7/src/functions.php index 96bf9261..e40348d6 100644 --- a/vendor/guzzlehttp/psr7/src/functions.php +++ b/vendor/guzzlehttp/psr7/src/functions.php @@ -371,25 +371,24 @@ function copy_to_stream( StreamInterface $dest, $maxLen = -1 ) { + $bufferSize = 8192; + if ($maxLen === -1) { while (!$source->eof()) { - if (!$dest->write($source->read(1048576))) { + if (!$dest->write($source->read($bufferSize))) { break; } } - return; - } - - $bytes = 0; - while (!$source->eof()) { - $buf = $source->read($maxLen - $bytes); - if (!($len = strlen($buf))) { - break; - } - $bytes += $len; - $dest->write($buf); - if ($bytes == $maxLen) { - break; + } else { + $remaining = $maxLen; + while ($remaining > 0 && !$source->eof()) { + $buf = $source->read(min($bufferSize, $remaining)); + $len = strlen($buf); + if (!$len) { + break; + } + $remaining -= $len; + $dest->write($buf); } } } @@ -492,7 +491,10 @@ function parse_request($message) function parse_response($message) { $data = _parse_message($message); - if (!preg_match('/^HTTP\/.* [0-9]{3} .*/', $data['start-line'])) { + // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space + // between status-code and reason-phrase is required. But browsers accept + // responses without space and reason as well. + if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { throw new \InvalidArgumentException('Invalid response string'); } $parts = explode(' ', $data['start-line'], 3); diff --git a/vendor/ircmaxell/password-compat/LICENSE.md b/vendor/ircmaxell/password-compat/LICENSE.md deleted file mode 100644 index 1efc565f..00000000 --- a/vendor/ircmaxell/password-compat/LICENSE.md +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2012 Anthony Ferrara - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/ircmaxell/password-compat/composer.json b/vendor/ircmaxell/password-compat/composer.json deleted file mode 100644 index 822fd1ff..00000000 --- a/vendor/ircmaxell/password-compat/composer.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "ircmaxell/password-compat", - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "keywords": ["password", "hashing"], - "homepage": "https://github.com/ircmaxell/password_compat", - "license": "MIT", - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "autoload": { - "files": ["lib/password.php"] - } -} diff --git a/vendor/ircmaxell/password-compat/lib/password.php b/vendor/ircmaxell/password-compat/lib/password.php deleted file mode 100644 index cc6896c1..00000000 --- a/vendor/ircmaxell/password-compat/lib/password.php +++ /dev/null @@ -1,314 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @copyright 2012 The Authors - */ - -namespace { - - if (!defined('PASSWORD_BCRYPT')) { - /** - * PHPUnit Process isolation caches constants, but not function declarations. - * So we need to check if the constants are defined separately from - * the functions to enable supporting process isolation in userland - * code. - */ - define('PASSWORD_BCRYPT', 1); - define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); - define('PASSWORD_BCRYPT_DEFAULT_COST', 10); - } - - if (!function_exists('password_hash')) { - - /** - * Hash the password using the specified algorithm - * - * @param string $password The password to hash - * @param int $algo The algorithm to use (Defined by PASSWORD_* constants) - * @param array $options The options for the algorithm to use - * - * @return string|false The hashed password, or false on error. - */ - function password_hash($password, $algo, array $options = array()) { - if (!function_exists('crypt')) { - trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING); - return null; - } - if (is_null($password) || is_int($password)) { - $password = (string) $password; - } - if (!is_string($password)) { - trigger_error("password_hash(): Password must be a string", E_USER_WARNING); - return null; - } - if (!is_int($algo)) { - trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING); - return null; - } - $resultLength = 0; - switch ($algo) { - case PASSWORD_BCRYPT: - $cost = PASSWORD_BCRYPT_DEFAULT_COST; - if (isset($options['cost'])) { - $cost = $options['cost']; - if ($cost < 4 || $cost > 31) { - trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING); - return null; - } - } - // The length of salt to generate - $raw_salt_len = 16; - // The length required in the final serialization - $required_salt_len = 22; - $hash_format = sprintf("$2y$%02d$", $cost); - // The expected length of the final crypt() output - $resultLength = 60; - break; - default: - trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING); - return null; - } - $salt_requires_encoding = false; - if (isset($options['salt'])) { - switch (gettype($options['salt'])) { - case 'NULL': - case 'boolean': - case 'integer': - case 'double': - case 'string': - $salt = (string) $options['salt']; - break; - case 'object': - if (method_exists($options['salt'], '__tostring')) { - $salt = (string) $options['salt']; - break; - } - case 'array': - case 'resource': - default: - trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING); - return null; - } - if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) { - trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING); - return null; - } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) { - $salt_requires_encoding = true; - } - } else { - $buffer = ''; - $buffer_valid = false; - if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { - $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM); - if ($buffer) { - $buffer_valid = true; - } - } - if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { - $buffer = openssl_random_pseudo_bytes($raw_salt_len); - if ($buffer) { - $buffer_valid = true; - } - } - if (!$buffer_valid && @is_readable('/dev/urandom')) { - $f = fopen('/dev/urandom', 'r'); - $read = PasswordCompat\binary\_strlen($buffer); - while ($read < $raw_salt_len) { - $buffer .= fread($f, $raw_salt_len - $read); - $read = PasswordCompat\binary\_strlen($buffer); - } - fclose($f); - if ($read >= $raw_salt_len) { - $buffer_valid = true; - } - } - if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) { - $bl = PasswordCompat\binary\_strlen($buffer); - for ($i = 0; $i < $raw_salt_len; $i++) { - if ($i < $bl) { - $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); - } else { - $buffer .= chr(mt_rand(0, 255)); - } - } - } - $salt = $buffer; - $salt_requires_encoding = true; - } - if ($salt_requires_encoding) { - // encode string with the Base64 variant used by crypt - $base64_digits = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - $bcrypt64_digits = - './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - $base64_string = base64_encode($salt); - $salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits); - } - $salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len); - - $hash = $hash_format . $salt; - - $ret = crypt($password, $hash); - - if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) { - return false; - } - - return $ret; - } - - /** - * Get information about the password hash. Returns an array of the information - * that was used to generate the password hash. - * - * array( - * 'algo' => 1, - * 'algoName' => 'bcrypt', - * 'options' => array( - * 'cost' => PASSWORD_BCRYPT_DEFAULT_COST, - * ), - * ) - * - * @param string $hash The password hash to extract info from - * - * @return array The array of information about the hash. - */ - function password_get_info($hash) { - $return = array( - 'algo' => 0, - 'algoName' => 'unknown', - 'options' => array(), - ); - if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) { - $return['algo'] = PASSWORD_BCRYPT; - $return['algoName'] = 'bcrypt'; - list($cost) = sscanf($hash, "$2y$%d$"); - $return['options']['cost'] = $cost; - } - return $return; - } - - /** - * Determine if the password hash needs to be rehashed according to the options provided - * - * If the answer is true, after validating the password using password_verify, rehash it. - * - * @param string $hash The hash to test - * @param int $algo The algorithm used for new password hashes - * @param array $options The options array passed to password_hash - * - * @return boolean True if the password needs to be rehashed. - */ - function password_needs_rehash($hash, $algo, array $options = array()) { - $info = password_get_info($hash); - if ($info['algo'] != $algo) { - return true; - } - switch ($algo) { - case PASSWORD_BCRYPT: - $cost = isset($options['cost']) ? $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST; - if ($cost != $info['options']['cost']) { - return true; - } - break; - } - return false; - } - - /** - * Verify a password against a hash using a timing attack resistant approach - * - * @param string $password The password to verify - * @param string $hash The hash to verify against - * - * @return boolean If the password matches the hash - */ - function password_verify($password, $hash) { - if (!function_exists('crypt')) { - trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); - return false; - } - $ret = crypt($password, $hash); - if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) { - return false; - } - - $status = 0; - for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) { - $status |= (ord($ret[$i]) ^ ord($hash[$i])); - } - - return $status === 0; - } - } - -} - -namespace PasswordCompat\binary { - - if (!function_exists('PasswordCompat\\binary\\_strlen')) { - - /** - * Count the number of bytes in a string - * - * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension. - * In this case, strlen() will count the number of *characters* based on the internal encoding. A - * sequence of bytes might be regarded as a single multibyte character. - * - * @param string $binary_string The input string - * - * @internal - * @return int The number of bytes - */ - function _strlen($binary_string) { - if (function_exists('mb_strlen')) { - return mb_strlen($binary_string, '8bit'); - } - return strlen($binary_string); - } - - /** - * Get a substring based on byte limits - * - * @see _strlen() - * - * @param string $binary_string The input string - * @param int $start - * @param int $length - * - * @internal - * @return string The substring - */ - function _substr($binary_string, $start, $length) { - if (function_exists('mb_substr')) { - return mb_substr($binary_string, $start, $length, '8bit'); - } - return substr($binary_string, $start, $length); - } - - /** - * Check if current PHP version is compatible with the library - * - * @return boolean the check result - */ - function check() { - static $pass = NULL; - - if (is_null($pass)) { - if (function_exists('crypt')) { - $hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG'; - $test = crypt("password", $hash); - $pass = $test == $hash; - } else { - $pass = false; - } - } - return $pass; - } - - } -} \ No newline at end of file diff --git a/vendor/ircmaxell/password-compat/version-test.php b/vendor/ircmaxell/password-compat/version-test.php deleted file mode 100644 index 96f60ca8..00000000 --- a/vendor/ircmaxell/password-compat/version-test.php +++ /dev/null @@ -1,6 +0,0 @@ -errors = array(); - $events = new DOMTreeBuilder(false, array_merge($this->getOptions(), $options)); + $options = array_merge($this->getOptions(), $options); + $events = new DOMTreeBuilder(false, $options); $scanner = new Scanner($input); - $parser = new Tokenizer($scanner, $events); + $parser = new Tokenizer($scanner, $events, !empty($options['xmlNamespaces']) ? Tokenizer::CONFORMANT_XML: Tokenizer::CONFORMANT_HTML); $parser->parse(); $this->errors = $events->getErrors(); @@ -184,9 +185,10 @@ public function parse(\Masterminds\HTML5\Parser\InputStream $input, array $optio */ public function parseFragment(\Masterminds\HTML5\Parser\InputStream $input, array $options = array()) { - $events = new DOMTreeBuilder(true, array_merge($this->getOptions(), $options)); + $options = array_merge($this->getOptions(), $options); + $events = new DOMTreeBuilder(true, $options); $scanner = new Scanner($input); - $parser = new Tokenizer($scanner, $events); + $parser = new Tokenizer($scanner, $events, !empty($options['xmlNamespaces']) ? Tokenizer::CONFORMANT_XML: Tokenizer::CONFORMANT_HTML); $parser->parse(); $this->errors = $events->getErrors(); diff --git a/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php b/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php index ccad2294..b26860da 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php @@ -274,7 +274,8 @@ public function startTag($name, $attributes = array(), $selfClosing = false) // SPECIAL TAG HANDLING: // Spec says do this, and "don't ask." - if ($name == 'image') { + // find the spec where this is defined... looks problematic + if ($name == 'image' && !($this->insertMode === static::IM_IN_SVG || $this->insertMode === static::IM_IN_MATHML)) { $name = 'img'; } @@ -681,4 +682,4 @@ protected function isParent($tagname) { return $this->current->tagName == $tagname; } -} \ No newline at end of file +} diff --git a/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php b/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php index 301addf1..c42bc3d8 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php @@ -43,6 +43,10 @@ class Tokenizer protected $textMode = 0; // TEXTMODE_NORMAL; protected $untilTag = null; + const CONFORMANT_XML = 'xml'; + const CONFORMANT_HTML = 'html'; + protected $mode = self::CONFORMANT_HTML; + const WHITE = "\t\n\f "; /** @@ -57,11 +61,13 @@ class Tokenizer * @param \Masterminds\HTML5\Parser\EventHandler $eventHandler * An event handler, initialized and ready to receive * events. + * @param string $mode */ - public function __construct($scanner, $eventHandler) + public function __construct($scanner, $eventHandler, $mode = self::CONFORMANT_HTML) { $this->scanner = $scanner; $this->events = $eventHandler; + $this->mode = $mode; } /** @@ -77,11 +83,8 @@ public function __construct($scanner, $eventHandler) */ public function parse() { - $p = 0; do { - $p = $this->scanner->position(); $this->consumeData(); - // FIXME: Add infinite loop protection. } while ($this->carryOn); } @@ -139,7 +142,8 @@ protected function consumeData() */ protected function characterData() { - if ($this->scanner->current() === false) { + $tok = $this->scanner->current(); + if ($tok === false) { return false; } switch ($this->textMode) { @@ -148,7 +152,6 @@ protected function characterData() case Elements::TEXT_RCDATA: return $this->rcdata(); default: - $tok = $this->scanner->current(); if (strspn($tok, "<&")) { return false; } @@ -335,7 +338,8 @@ protected function endTag() return $this->bogusComment('scanner->charsUntil("\n\f \t>")); + $name = $this->scanner->charsUntil("\n\f \t>"); + $name = $this->mode === self::CONFORMANT_XML ? $name: strtolower($name); // Trash whitespace. $this->scanner->whitespace(); @@ -362,7 +366,8 @@ protected function tagName() } // We know this is at least one char. - $name = strtolower($this->scanner->charsWhile(":_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); + $name = $this->scanner->charsWhile(":_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + $name = $this->mode === self::CONFORMANT_XML ? $name : strtolower($name); $attributes = array(); $selfClose = false; @@ -400,24 +405,26 @@ protected function isTagEnd(&$selfClose) if ($tok == '/') { $this->scanner->next(); $this->scanner->whitespace(); - if ($this->scanner->current() == '>') { + $tok = $this->scanner->current(); + + if ($tok == '>') { $selfClose = true; return true; } - if ($this->scanner->current() === false) { + if ($tok === false) { $this->parseError("Unexpected EOF inside of tag."); return true; } // Basically, we skip the / token and go on. // See 8.2.4.43. - $this->parseError("Unexpected '%s' inside of a tag.", $this->scanner->current()); + $this->parseError("Unexpected '%s' inside of a tag.", $tok); return false; } - if ($this->scanner->current() == '>') { + if ($tok == '>') { return true; } - if ($this->scanner->current() === false) { + if ($tok === false) { $this->parseError("Unexpected EOF inside of tag."); return true; } @@ -533,15 +540,21 @@ protected function quotedAttributeValue($quote) { $stoplist = "\f" . $quote; $val = ''; - $tok = $this->scanner->current(); - while (strspn($tok, $stoplist) == 0 && $tok !== false) { - if ($tok == '&') { - $val .= $this->decodeCharacterReference(true); - $tok = $this->scanner->current(); + + while (true) { + $tokens = $this->scanner->charsUntil($stoplist.'&'); + if ($tokens !== false) { + $val .= $tokens; } else { - $val .= $tok; - $tok = $this->scanner->next(); + break; } + + $tok = $this->scanner->current(); + if ($tok == '&') { + $val .= $this->decodeCharacterReference(true, $tok); + continue; + } + break; } $this->scanner->next(); return $val; @@ -583,18 +596,18 @@ protected function unquotedAttributeValue() */ protected function bogusComment($leading = '') { - - // TODO: This can be done more efficiently when the - // scanner exposes a readUntil() method. $comment = $leading; + $tokens = $this->scanner->charsUntil('>'); + if ($tokens !== false) { + $comment .= $tokens; + } $tok = $this->scanner->current(); - do { + if ($tok !== false) { $comment .= $tok; - $tok = $this->scanner->next(); - } while ($tok !== false && $tok != '>'); + } $this->flushBuffer(); - $this->events->comment($comment . $tok); + $this->events->comment($comment); $this->scanner->next(); return true; @@ -638,15 +651,17 @@ protected function comment() */ protected function isCommentEnd() { + $tok = $this->scanner->current(); + // EOF - if ($this->scanner->current() === false) { + if ($tok === false) { // Hit the end. $this->parseError("Unexpected EOF in a comment."); return true; } // If it doesn't start with -, not the end. - if ($this->scanner->current() != '-') { + if ($tok != '-') { return false; } @@ -729,7 +744,6 @@ protected function doctype() $pub = strtoupper($this->scanner->getAsciiAlpha()); $white = strlen($this->scanner->whitespace()); - $tok = $this->scanner->current(); // Get ID, and flag it as pub or system. if (($pub == 'PUBLIC' || $pub == 'SYSTEM') && $white > 0) { @@ -930,10 +944,11 @@ protected function sequenceMatches($sequence, $caseSensitive = true) $len = strlen($sequence); $buffer = ''; for ($i = 0; $i < $len; ++ $i) { - $buffer .= $this->scanner->current(); + $tok = $this->scanner->current(); + $buffer .= $tok; // EOF. Rewind and let the caller handle it. - if ($this->scanner->current() === false) { + if ($tok === false) { $this->scanner->unconsume($i); return false; } @@ -1059,18 +1074,22 @@ protected function decodeCharacterReference($inAttribute = false) } $entity = CharacterReference::lookupDecimal($numeric); } - } // String entity. - else { + } elseif ($tok === '=' && $inAttribute) { + return '&'; + } else { // String entity. + // Attempt to consume a string up to a ';'. // [a-zA-Z0-9]+; - $cname = $this->scanner->getAsciiAlpha(); + $cname = $this->scanner->getAsciiAlphaNum(); $entity = CharacterReference::lookupName($cname); // When no entity is found provide the name of the unmatched string // and continue on as the & is not part of an entity. The & will // be converted to & elsewhere. if ($entity == null) { - $this->parseError("No match in entity table for '%s'", $cname); + if (!$inAttribute || strlen($cname) === 0) { + $this->parseError("No match in entity table for '%s'", $cname); + } $this->scanner->unconsume($this->scanner->position() - $start); return '&'; } diff --git a/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php b/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php index 2af3c664..62362082 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php @@ -76,7 +76,6 @@ public function evaluate($new, $current) case 'option': return $this->closeIfCurrentMatches($new, $current, array( 'option', - 'optgroup' )); case 'tr': return $this->closeIfCurrentMatches($new, $current, array( diff --git a/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php b/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php index c45045f7..a22683c3 100644 --- a/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php +++ b/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php @@ -221,7 +221,11 @@ public function element($ele) $this->openTag($ele); if (Elements::isA($name, Elements::TEXT_RAW)) { foreach ($ele->childNodes as $child) { - $this->wr($child->data); + if ($child instanceof \DOMCharacterData) { + $this->wr($child->data); + } elseif ($child instanceof \DOMElement) { + $this->element($child); + } } } else { // Handle children. diff --git a/vendor/paragonie/random_compat/.gitignore b/vendor/paragonie/random_compat/.gitignore deleted file mode 100644 index de26af57..00000000 --- a/vendor/paragonie/random_compat/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -composer.lock -/vendor/ -/tests/phpunit.phar -/tests/phpunit.phar.asc \ No newline at end of file diff --git a/vendor/paragonie/random_compat/.scrutinizer.yml b/vendor/paragonie/random_compat/.scrutinizer.yml deleted file mode 100644 index a2f32ead..00000000 --- a/vendor/paragonie/random_compat/.scrutinizer.yml +++ /dev/null @@ -1,4 +0,0 @@ -checks: - php: - code_rating: true - duplication: false \ No newline at end of file diff --git a/vendor/paragonie/random_compat/.travis.yml b/vendor/paragonie/random_compat/.travis.yml deleted file mode 100644 index 43ec1272..00000000 --- a/vendor/paragonie/random_compat/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: php -php: - -- "7.0" -- "5.6" -- "5.5" -- "5.4" -- "5.3" -- "hhvm" - - -sudo: false - -matrix: - fast_finish: true - allow_failures: - - php: "hhvm" - -install: - -- composer install -- composer self-update -- composer update -- chmod +x ./phpunit.sh - -script: ./phpunit.sh travis diff --git a/vendor/paragonie/random_compat/ERRATA.md b/vendor/paragonie/random_compat/ERRATA.md deleted file mode 100644 index 9c0ef9fd..00000000 --- a/vendor/paragonie/random_compat/ERRATA.md +++ /dev/null @@ -1,40 +0,0 @@ -## Errata (Design Decisions) - -### Reasoning Behind the Order of Preferred Random Data Sources - -The order is: - - 1. `libsodium if available` - 2. `fread() /dev/urandom if available` - 3. `mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)` - 4. `COM('CAPICOM.Utilities.1')->GetRandom()` - 5. `openssl_random_pseudo_bytes()` - -If libsodium is available, we get random data from it. This is the preferred -method on all OSes, but libsodium is not very widely installed, so other -fallbacks are available. - -Next, we read `/dev/urandom` (if it exists). This is the preferred file to read -for random data for cryptographic purposes for BSD and Linux. - -Despite [strongly urging people not to use mcrypt in their projects](https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong), -because libmcrypt is abandonware and the API puts too much responsibility on the -implementor, we prioritize `mcrypt_create_iv()` with `MCRYPT_DEV_URANDOM` above -the remaining implementations. - -The reason is simple: `mcrypt_create_iv()` is part of PHP's `ext/mcrypt` code, -and is not part `libmcrypt`. It actually does the right thing: - - * On Unix-based operating systems, it reads from `/dev/urandom`, which is the - sane and correct thing to do. - * On Windows, it reads from `CryptGenRandom`, which is an exclusively Windows - way to get random bytes. - -If we're on Windows and don't have access to `mcrypt`, we use `CAPICOM.Utilities.1`. - -Finally, we use `openssl_random_pseudo_bytes()` **as a last resort**, due to -[PHP bug #70014](https://bugs.php.net/bug.php?id=70014). Internally, this -function calls `RAND_pseudo_bytes()`, which has been [deprecated](https://github.com/paragonie/random_compat/issues/5) -by the OpenSSL team. Furthermore, [it might silently return weak random data](https://github.com/paragonie/random_compat/issues/6#issuecomment-119564973) -if it is called before OpenSSL's **userspace** CSPRNG is seeded. Also, -[you want the OS CSPRNG, not a userspace CSPRNG](http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/). diff --git a/vendor/paragonie/random_compat/README.md b/vendor/paragonie/random_compat/README.md deleted file mode 100644 index ed5b1d85..00000000 --- a/vendor/paragonie/random_compat/README.md +++ /dev/null @@ -1,149 +0,0 @@ -# random_compat - -[![Build Status](https://travis-ci.org/paragonie/random_compat.svg?branch=master)](https://travis-ci.org/paragonie/random_compat) -[![Scrutinizer](https://scrutinizer-ci.com/g/paragonie/random_compat/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/paragonie/random_compat) - -PHP 5.x polyfill for `random_bytes()` and `random_int()` created and maintained -by [Paragon Initiative Enterprises](https://paragonie.com). - -Although this library *should* function in earlier versions of PHP, we will only -consider issues relevant to [supported PHP versions](https://secure.php.net/supported-versions.php). -**If you are using an unsupported version of PHP, please upgrade as soon as possible.** - -## Important - -Although this library has been examined by some security experts in the PHP -community, there will always be a chance that we overlooked something. Please -ask your favorite trusted hackers to hammer it for implementation errors and -bugs before even thinking about deploying it in production. - -**Do not use the master branch, use a [stable release](https://github.com/paragonie/random_compat/releases/latest).** - -For the background of this library, please refer to our blog post on -[Generating Random Integers and Strings in PHP](https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php). - -### Usability Notice - -If PHP cannot safely generate random data, this library will throw an `Exception`. -It will never fall back to insecure random data. If this keeps happening, upgrade -to a newer version of PHP immediately. - -## Usage - -This library exposes the [CSPRNG functions added in PHP 7](https://secure.php.net/manual/en/ref.csprng.php) -for use in PHP 5 projects. Their behavior should be identical. - -### Generate a string of random bytes - -```php -try { - $string = random_bytes(32); -} catch (TypeError $e) { - // Well, it's an integer, so this IS unexpected. - die("An unexpected error has occurred"); -} catch (Error $e) { - // This is also unexpected because 32 is a reasonable integer. - die("An unexpected error has occurred"); -} catch (Exception $e) { - // If you get this message, the CSPRNG failed hard. - die("Could not generate a random string. Is our OS secure?"); -} - -var_dump(bin2hex($string)); -// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f" -``` - -### Generate a random integer between two given integers (inclusive) - -```php -try { - $int = random_int(0,255); - -} catch (TypeError $e) { - // Well, it's an integer, so this IS unexpected. - die("An unexpected error has occurred"); -} catch (Error $e) { - // This is also unexpected because 0 and 255 are both reasonable integers. - die("An unexpected error has occurred"); -} catch (Exception $e) { - // If you get this message, the CSPRNG failed hard. - die("Could not generate a random string. Is our OS secure?"); -} - -var_dump($int); -// int(47) -``` - -### Exception handling - -When handling exceptions and errors you must account for differences between -PHP 5 and PHP7. - -The differences: - -* Catching `Error` works, so long as it is caught before `Exception`. -* Catching `Exception` has different behavior, without previously catching `Error`. -* There is *no* portable way to catch all errors/exceptions. - -#### Our recommendation - -**Always** catch `Error` before `Exception`. - -#### Example - -```php -try { - return random_int(1, $userInput); -} catch (TypeError $e) { - // This is okay, so long as `Error` is caught before `Exception`. - throw new Exception('Please enter a number!'); -} catch (Error $e) { - // This is required, if you do not need to do anything just rethrow. - throw $e; -} catch (Exception $e) { - // This is optional and maybe omitted if you do not want to handle errors - // during generation. - throw new InternalServerErrorException( - 'Oops, our server is bust and cannot generate any random data.', - 500, - $e - ); -} -``` - -## Contributors - -This project would not be anywhere near as excellent as it is today if it -weren't for the contributions of the following individuals: - -* [@AndrewCarterUK (Andrew Carter)](https://github.com/AndrewCarterUK) -* [@asgrim (James Titcumb)](https://github.com/asgrim) -* [@CodesInChaos (Christian Winnerlein)](https://github.com/CodesInChaos) -* [@chriscct7 (Chris Christoff)](https://github.com/chriscct7) -* [@cs278 (Chris Smith)](https://github.com/cs278) -* [@cweagans (Cameron Eagans)](https://github.com/cweagans) -* [@dd32 (Dion Hulse)](https://github.com/dd32) -* [@geggleto (Glenn Eggleton)](https://github.com/geggleto) -* [@ircmaxell (Anthony Ferrara)](https://github.com/ircmaxell) -* [@jedisct1 (Frank Denis)](https://github.com/jedisct1) -* [@juliangut (Julián Gutiérrez)](https://github.com/juliangut) -* [@kelunik (Niklas Keller)](https://github.com/kelunik) -* [@lt (Leigh)](https://github.com/lt) -* [@MasonM (Mason Malone)](https://github.com/MasonM) -* [@mmeyer2k (Michael M)](https://github.com/mmeyer2k) -* [@narfbg (Andrey Andreev)](https://github.com/narfbg) -* [@nicolas-grekas (Nicolas Grekas)](https://github.com/nicolas-grekas) -* [@oittaa](https://github.com/oittaa) -* [@redragonx (Stephen Chavez)](https://github.com/redragonx) -* [@rchouinard (Ryan Chouinard)](https://github.com/rchouinard) -* [@SammyK (Sammy Kaye Powers)](https://github.com/SammyK) -* [@scottchiefbaker (Scott Baker)](https://github.com/scottchiefbaker) -* [@skyosev (Stoyan Kyosev)](https://github.com/skyosev) -* [@stof (Christophe Coevoet)](https://github.com/stof) -* [@teohhanhui (Teoh Han Hui)](https://github.com/teohhanhui) -* [@tom-- (Tom Worster)](https://github.com/tom--) -* [@tsyr2ko](https://github.com/tsyr2ko) -* [@trowski (Aaron Piotrowski)](https://github.com/trowski) -* [@twistor (Chris Lepannen)](https://github.com/twistor) -* [@voku (Lars Moelleken)](https://github.com/voku) -* [@xabbuh (Christian Flothmann)](https://github.com/xabbuh) diff --git a/vendor/paragonie/random_compat/SECURITY.md b/vendor/paragonie/random_compat/SECURITY.md deleted file mode 100644 index 8f731b38..00000000 --- a/vendor/paragonie/random_compat/SECURITY.md +++ /dev/null @@ -1,108 +0,0 @@ -# An Invitation to Security Researchers - -Every company says they take security "very seriously." Rather than bore anyone -with banal boilerplate, here are some quick answers followed by detailed -elaboration. If you have any questions about our policies, please email them to -`scott@paragonie.com`. - -## Quick Answers - -* There is no compulsion to disclose vulnerabilities privately, but we - appreciate a head's up. -* `security@paragonie.com` will get your reports to the right person. Our GPG - fingerprint, should you decide to encrypt your report, is - `7F52 D5C6 1D12 55C7 3136 2E82 6B97 A1C2 8264 04DA`. - -* **YES**, we will reward security researchers who disclose vulnerabilities in - our software. -* In most cases, **No Proof-of-Concept Required.** - -## How to Report a Security Bug to Paragon Initiative Enterprises - -### There is no compulsion to disclose privately. - -We believe vulnerability disclosure style is a personal choice and enjoy working -with a diverse community. We understand and appreciate the importance of Full -Disclosure in the history and practice of security research. - -We would *like* to know about high-severity bugs before they become public -knowledge, so we can fix them in a timely manner, but **we do not believe in -threatening researchers or trying to enforce vulnerability embargoes**. - -Ultimately, if you discover a security-affecting vulnerability, what you do with -it is your choice. We would like to work with people, and to celebrate and -reward their skill, experience, and dedication. We appreciate being informed of -our mistakes so we can learn from them and build a better product. Our goal is -to empower the community. - -### Where to Send Security Vulnerabilities - -Our security email address is `security@paragonie.com`. Also feel free to open a -new issue on Github if you want to disclose publicly. - -``` ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG - -mQENBFUgwRUBCADcIpqNwyYc5UmY/tpx1sF/rQ3knR1YNXYZThzFV+Gmqhp1fDH5 -qBs9foh1xwI6O7knWmQngnf/nBumI3x6xj7PuOdEZUh2FwCG/VWnglW8rKmoHzHA -ivjiu9SLnPIPAgHSHeh2XD7q3Ndm3nenbjAiRFNl2iXcwA2cTQp9Mmfw9vVcw0G0 -z1o0G3s8cC8ZS6flFySIervvfSRWj7A1acI5eE3+AH/qXJRdEJ+9J8OB65p1JMfk -6+fWgOB1XZxMpz70S0rW6IX38WDSRhEK2fXyZJAJjyt+YGuzjZySNSoQR/V6vNYn -syrNPCJ2i5CgZQxAkyBBcr7koV9RIhPRzct/ABEBAAG0IVNlY3VyaXR5IDxzZWN1 -cml0eUBwYXJhZ29uaWUuY29tPokBOQQTAQIAIwUCVSDBFQIbAwcLCQgHAwIBBhUI -AgkKCwQWAgMBAh4BAheAAAoJEGuXocKCZATat2YIAIoejNFEQ2c1iaOEtSuB7Pn/ -WLbsDsHNLDKOV+UnfaCjv/vL7D+5NMChFCi2frde/NQb2TsjqmIH+V+XbnJtlrXD -Vj7yvMVal+Jqjwj7v4eOEWcKVcFZk+9cfUgh7t92T2BMX58RpgZF0IQZ6Z1R3FfC -9Ub4X6ykW+te1q0/4CoRycniwmlQi6iGSr99LQ5pfJq2Qlmz/luTZ0UX0h575T7d -cp2T1sX/zFRk/fHeANWSksipdDBjAXR7NMnYZgw2HghEdFk/xRDY7K1NRWNZBf05 -WrMHmh6AIVJiWZvI175URxEe268hh+wThBhXQHMhFNJM1qPIuzb4WogxM3UUD7m5 -AQ0EVSDBFQEIALNkpzSuJsHAHh79sc0AYWztdUe2MzyofQbbOnOCpWZebYsC3EXU -335fIg59k0m6f+O7GmEZzzIv5v0i99GS1R8CJm6FvhGqtH8ZqmOGbc71WdJSiNVE -0kpQoJlVzRbig6ZyyjzrggbM1eh5OXOk5pw4+23FFEdw7JWU0HJS2o71r1hwp05Z -vy21kcUEobz/WWQQyGS0Neo7PJn+9KS6wOxXul/UE0jct/5f7KLMdWMJ1VgniQmm -hjvkHLPSICteqCI04RfcmMseW9gueHQXeUu1SNIvsWa2MhxjeBej3pDnrZWszKwy -gF45GO9/v4tkIXNMy5J1AtOyRgQ3IUMqp8EAEQEAAYkBHwQYAQIACQUCVSDBFQIb -DAAKCRBrl6HCgmQE2jnIB/4/xFz8InpM7eybnBOAir3uGcYfs3DOmaKn7qWVtGzv -rKpQPYnVtlU2i6Z5UO4c4jDLT/8Xm1UDz3Lxvqt4xCaDwJvBZexU5BMK8l5DvOzH -6o6P2L1UDu6BvmPXpVZz7/qUhOnyf8VQg/dAtYF4/ax19giNUpI5j5o5mX5w80Rx -qSXV9NdSL4fdjeG1g/xXv2luhoV53T1bsycI3wjk/x5tV+M2KVhZBvvuOm/zhJje -oLWp0saaESkGXIXqurj6gZoujJvSvzl0n9F9VwqMEizDUfrXgtD1siQGhP0sVC6q -ha+F/SAEJ0jEquM4TfKWWU2S5V5vgPPpIQSYRnhQW4b1 -=xJPW ------END PGP PUBLIC KEY BLOCK----- -``` - -### We Will Reward Security Researchers - -**This process has not been formalized; nor have dollar amounts been -discussed.** - -However, if you report a valid security-affecting bug, we will compensate you -for the time spent finding the vulnerability and reward you for being a good -neighbor. - -#### What does a "valid" bug mean? - -There are two sides to this: - -1. Some have spammed projects with invalid bug reports hoping to collect - bounties for pressing a button and running an automated analysis tool. This - is not cool. -2. There is a potential for the developers of a project to declare all security - bug reports as invalid to save money. - -Our team members have an established history of reporting vulnerabilities to -large open source projects. **We aren't in the business of ripping people off.** -When in doubt, our policy is to err on the side of generosity. - -### No Proof-of-Concept Required - -We might ask for one if we feel we do not understand some of the details -pertaining to a specific vulnerability. We certainly appreciate them if you -include them in your report, but we believe **the burden lies with the developer -to prove their software *is* secure** rather than with the researcher to prove -that it isn't. - -In our experience, most bugs are simpler to fix than they are to exploit. - diff --git a/vendor/paragonie/random_compat/build-phar.sh b/vendor/paragonie/random_compat/build-phar.sh new file mode 100755 index 00000000..b4a5ba31 --- /dev/null +++ b/vendor/paragonie/random_compat/build-phar.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) + +php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/vendor/paragonie/random_compat/composer.json b/vendor/paragonie/random_compat/composer.json index d363f4c8..1c5978c6 100644 --- a/vendor/paragonie/random_compat/composer.json +++ b/vendor/paragonie/random_compat/composer.json @@ -1,35 +1,37 @@ { - "name": "paragonie/random_compat", - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "random", - "pseudorandom" - ], - "license": "MIT", - "type": "library", - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "support": { - "issues": "https://github.com/paragonie/random_compat/issues", - "email": "info@paragonie.com", - "source": "https://github.com/paragonie/random_compat" - }, - "require": { - "php": ">=5.2.0" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "autoload": { - "files": ["lib/random.php"] + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "autoload": { + "files": [ + "lib/random.php" + ] + } } diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey new file mode 100644 index 00000000..eb50ebfc --- /dev/null +++ b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm +pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p ++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc +-----END PUBLIC KEY----- diff --git a/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc new file mode 100644 index 00000000..6a1d7f30 --- /dev/null +++ b/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (MingW32) + +iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip +QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg +1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW +NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA +NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV +JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= +=B6+8 +-----END PGP SIGNATURE----- diff --git a/vendor/paragonie/random_compat/lib/byte_safe_strings.php b/vendor/paragonie/random_compat/lib/byte_safe_strings.php index a3cc90b1..3de86b22 100644 --- a/vendor/paragonie/random_compat/lib/byte_safe_strings.php +++ b/vendor/paragonie/random_compat/lib/byte_safe_strings.php @@ -5,7 +5,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2015 Paragon Initiative Enterprises + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,7 @@ * SOFTWARE. */ -if (!function_exists('RandomCompat_strlen')) { +if (!is_callable('RandomCompat_strlen')) { if ( defined('MB_OVERLOAD_STRING') && ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING @@ -50,8 +50,10 @@ function RandomCompat_strlen($binary_string) 'RandomCompat_strlen() expects a string' ); } - return mb_strlen($binary_string, '8bit'); + + return (int) mb_strlen($binary_string, '8bit'); } + } else { /** * strlen() implementation that isn't brittle to mbstring.func_overload @@ -71,14 +73,16 @@ function RandomCompat_strlen($binary_string) 'RandomCompat_strlen() expects a string' ); } - return strlen($binary_string); + return (int) strlen($binary_string); } } } -if (!function_exists('RandomCompat_substr')) { +if (!is_callable('RandomCompat_substr')) { + if ( - defined('MB_OVERLOAD_STRING') && + defined('MB_OVERLOAD_STRING') + && ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING ) { /** @@ -102,25 +106,38 @@ function RandomCompat_substr($binary_string, $start, $length = null) 'RandomCompat_substr(): First argument should be a string' ); } + if (!is_int($start)) { throw new TypeError( 'RandomCompat_substr(): Second argument should be an integer' ); } + if ($length === null) { /** * mb_substr($str, 0, NULL, '8bit') returns an empty string on * PHP 5.3, so we have to find the length ourselves. */ - $length = RandomCompat_strlen($length) - $start; + $length = RandomCompat_strlen($binary_string) - $start; } elseif (!is_int($length)) { throw new TypeError( 'RandomCompat_substr(): Third argument should be an integer, or omitted' ); } - return mb_substr($binary_string, $start, $length, '8bit'); + + // Consistency with PHP's behavior + if ($start === RandomCompat_strlen($binary_string) && $length === 0) { + return ''; + } + if ($start > RandomCompat_strlen($binary_string)) { + return ''; + } + + return (string) mb_substr($binary_string, $start, $length, '8bit'); } + } else { + /** * substr() implementation that isn't brittle to mbstring.func_overload * @@ -141,20 +158,24 @@ function RandomCompat_substr($binary_string, $start, $length = null) 'RandomCompat_substr(): First argument should be a string' ); } + if (!is_int($start)) { throw new TypeError( 'RandomCompat_substr(): Second argument should be an integer' ); } + if ($length !== null) { if (!is_int($length)) { throw new TypeError( 'RandomCompat_substr(): Third argument should be an integer, or omitted' ); } - return substr($binary_string, $start, $length); + + return (string) substr($binary_string, $start, $length); } - return substr($binary_string, $start); + + return (string) substr($binary_string, $start); } } } diff --git a/vendor/paragonie/random_compat/lib/cast_to_int.php b/vendor/paragonie/random_compat/lib/cast_to_int.php index 474ce640..be7388df 100644 --- a/vendor/paragonie/random_compat/lib/cast_to_int.php +++ b/vendor/paragonie/random_compat/lib/cast_to_int.php @@ -5,7 +5,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2015 Paragon Initiative Enterprises + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,7 @@ * SOFTWARE. */ -if (!function_exists('RandomCompat_intval')) { +if (!is_callable('RandomCompat_intval')) { /** * Cast to an integer if we can, safely. @@ -37,28 +37,38 @@ * lose precision, so the <= and => operators might accidentally let a float * through. * - * @param numeric $number The number we want to convert to an int - * @param boolean $fail_open Set to true to not throw an exception + * @param int|float $number The number we want to convert to an int + * @param boolean $fail_open Set to true to not throw an exception * - * @return int (or float if $fail_open) + * @return float|int + * + * @throws TypeError */ function RandomCompat_intval($number, $fail_open = false) { - if (is_numeric($number)) { + if (is_int($number) || is_float($number)) { + $number += 0; + } elseif (is_numeric($number)) { $number += 0; } + if ( - is_float($number) && - $number > ~PHP_INT_MAX && + is_float($number) + && + $number > ~PHP_INT_MAX + && $number < PHP_INT_MAX ) { $number = (int) $number; } - if (is_int($number) || $fail_open) { - return $number; + + if (is_int($number)) { + return (int) $number; + } elseif (!$fail_open) { + throw new TypeError( + 'Expected an integer.' + ); } - throw new TypeError( - 'Expected an integer.' - ); + return $number; } } diff --git a/vendor/paragonie/random_compat/lib/error_polyfill.php b/vendor/paragonie/random_compat/lib/error_polyfill.php index 57cfefdc..6a91990c 100644 --- a/vendor/paragonie/random_compat/lib/error_polyfill.php +++ b/vendor/paragonie/random_compat/lib/error_polyfill.php @@ -4,8 +4,8 @@ * for using the new PHP 7 random_* API in PHP 5 projects * * The MIT License (MIT) - * - * Copyright (c) 2015 Paragon Initiative Enterprises + * + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,8 +35,15 @@ class Error extends Exception } if (!class_exists('TypeError', false)) { - class TypeError extends Error - { - + if (is_subclass_of('Error', 'Exception')) { + class TypeError extends Error + { + + } + } else { + class TypeError extends Exception + { + + } } } diff --git a/vendor/paragonie/random_compat/lib/random.php b/vendor/paragonie/random_compat/lib/random.php index d1f7555a..df74c8a4 100644 --- a/vendor/paragonie/random_compat/lib/random.php +++ b/vendor/paragonie/random_compat/lib/random.php @@ -1,22 +1,25 @@ = 70000) { + return; +} + +if (!defined('RANDOM_COMPAT_READ_BUFFER')) { + define('RANDOM_COMPAT_READ_BUFFER', 8); +} + +$RandomCompatDIR = dirname(__FILE__); + +require_once $RandomCompatDIR . '/byte_safe_strings.php'; +require_once $RandomCompatDIR . '/cast_to_int.php'; +require_once $RandomCompatDIR . '/error_polyfill.php'; + +if (!is_callable('random_bytes')) { + /** + * PHP 5.2.0 - 5.6.x way to implement random_bytes() + * + * We use conditional statements here to define the function in accordance + * to the operating environment. It's a micro-optimization. + * + * In order of preference: + * 1. Use libsodium if available. + * 2. fread() /dev/urandom if available (never on Windows) + * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM) + * 4. COM('CAPICOM.Utilities.1')->GetRandom() + * + * See RATIONALE.md for our reasoning behind this particular order + */ + if (extension_loaded('libsodium')) { + // See random_bytes_libsodium.php + if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { + require_once $RandomCompatDIR . '/random_bytes_libsodium.php'; + } elseif (method_exists('Sodium', 'randombytes_buf')) { + require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php'; + } } - $RandomCompatDIR = dirname(__FILE__); - require_once $RandomCompatDIR.'/byte_safe_strings.php'; - require_once $RandomCompatDIR.'/cast_to_int.php'; - require_once $RandomCompatDIR.'/error_polyfill.php'; - if (!function_exists('random_bytes')) { - /** - * PHP 5.2.0 - 5.6.x way to implement random_bytes() - * - * We use conditional statements here to define the function in accordance - * to the operating environment. It's a micro-optimization. - * - * In order of preference: - * 1. Use libsodium if available. - * 2. fread() /dev/urandom if available (never on Windows) - * 3. mcrypt_create_iv($bytes, MCRYPT_CREATE_IV) - * 4. COM('CAPICOM.Utilities.1')->GetRandom() - * 5. openssl_random_pseudo_bytes() (absolute last resort) - * - * See ERRATA.md for our reasoning behind this particular order - */ - if (extension_loaded('libsodium')) { - // See random_bytes_libsodium.php - require_once $RandomCompatDIR.'/random_bytes_libsodium.php'; + + /** + * Reading directly from /dev/urandom: + */ + if (DIRECTORY_SEPARATOR === '/') { + // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast + // way to exclude Windows. + $RandomCompatUrandom = true; + $RandomCompat_basedir = ini_get('open_basedir'); + + if (!empty($RandomCompat_basedir)) { + $RandomCompat_open_basedir = explode( + PATH_SEPARATOR, + strtolower($RandomCompat_basedir) + ); + $RandomCompatUrandom = (array() !== array_intersect( + array('/dev', '/dev/', '/dev/urandom'), + $RandomCompat_open_basedir + )); + $RandomCompat_open_basedir = null; } + if ( - !function_exists('random_bytes') && - DIRECTORY_SEPARATOR === '/' && + !is_callable('random_bytes') + && + $RandomCompatUrandom + && @is_readable('/dev/urandom') ) { - // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast - // way to exclude Windows. - // - // Error suppression on is_readable() in case of an open_basedir or - // safe_mode failure. All we care about is whether or not we can - // read it at this point. If the PHP environment is going to panic - // over trying to see if the file can be read in the first place, - // that is not helpful to us here. - + // Error suppression on is_readable() in case of an open_basedir + // or safe_mode failure. All we care about is whether or not we + // can read it at this point. If the PHP environment is going to + // panic over trying to see if the file can be read in the first + // place, that is not helpful to us here. + // See random_bytes_dev_urandom.php - require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php'; - } - if ( - !function_exists('random_bytes') && - PHP_VERSION_ID >= 50307 && - extension_loaded('mcrypt') - ) { - // See random_bytes_mcrypt.php - require_once $RandomCompatDIR.'/random_bytes_mcrypt.php'; + require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php'; } - if ( - !function_exists('random_bytes') && - extension_loaded('com_dotnet') && - class_exists('COM') - ) { + // Unset variables after use + $RandomCompat_basedir = null; + } else { + $RandomCompatUrandom = false; + } + + /** + * mcrypt_create_iv() + * + * We only want to use mcypt_create_iv() if: + * + * - random_bytes() hasn't already been defined + * - the mcrypt extensions is loaded + * - One of these two conditions is true: + * - We're on Windows (DIRECTORY_SEPARATOR !== '/') + * - We're not on Windows and /dev/urandom is readabale + * (i.e. we're not in a chroot jail) + * - Special case: + * - If we're not on Windows, but the PHP version is between + * 5.6.10 and 5.6.12, we don't want to use mcrypt. It will + * hang indefinitely. This is bad. + * - If we're on Windows, we want to use PHP >= 5.3.7 or else + * we get insufficient entropy errors. + */ + if ( + !is_callable('random_bytes') + && + // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be. + (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307) + && + // Prevent this code from hanging indefinitely on non-Windows; + // see https://bugs.php.net/bug.php?id=69833 + ( + DIRECTORY_SEPARATOR !== '/' || + (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613) + ) + && + extension_loaded('mcrypt') + ) { + // See random_bytes_mcrypt.php + require_once $RandomCompatDIR . '/random_bytes_mcrypt.php'; + } + $RandomCompatUrandom = null; + + /** + * This is a Windows-specific fallback, for when the mcrypt extension + * isn't loaded. + */ + if ( + !is_callable('random_bytes') + && + extension_loaded('com_dotnet') + && + class_exists('COM') + ) { + $RandomCompat_disabled_classes = preg_split( + '#\s*,\s*#', + strtolower(ini_get('disable_classes')) + ); + + if (!in_array('com', $RandomCompat_disabled_classes)) { try { $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); if (method_exists($RandomCompatCOMtest, 'GetRandom')) { // See random_bytes_com_dotnet.php - require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php'; + require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php'; } } catch (com_exception $e) { // Don't try to use it. } - $RandomCompatCOMtest = null; - } - if ( - !function_exists('random_bytes') && - extension_loaded('openssl') && - ( - // Unix-like with PHP >= 5.3.0 or - ( - DIRECTORY_SEPARATOR === '/' && - PHP_VERSION_ID >= 50300 - ) || - // Windows with PHP >= 5.4.1 - PHP_VERSION_ID >= 50401 - ) - ) { - // See random_bytes_openssl.php - require_once $RandomCompatDIR.'/random_bytes_openssl.php'; - } - if (!function_exists('random_bytes')) { - /** - * We don't have any more options, so let's throw an exception right now - * and hope the developer won't let it fail silently. - */ - function random_bytes() - { - throw new Exception( - 'There is no suitable CSPRNG installed on your system' - ); - } } + $RandomCompat_disabled_classes = null; + $RandomCompatCOMtest = null; } - if (!function_exists('random_int')) { - require_once $RandomCompatDIR.'/random_int.php'; + + /** + * throw new Exception + */ + if (!is_callable('random_bytes')) { + /** + * We don't have any more options, so let's throw an exception right now + * and hope the developer won't let it fail silently. + * + * @param mixed $length + * @return void + * @throws Exception + */ + function random_bytes($length) + { + unset($length); // Suppress "variable not used" warnings. + throw new Exception( + 'There is no suitable CSPRNG installed on your system' + ); + } } - $RandomCompatDIR = null; } + +if (!is_callable('random_int')) { + require_once $RandomCompatDIR . '/random_int.php'; +} + +$RandomCompatDIR = null; diff --git a/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php b/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php index 0a781f4e..fc1926e5 100644 --- a/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php +++ b/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php @@ -5,7 +5,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2015 Paragon Initiative Enterprises + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,52 +26,63 @@ * SOFTWARE. */ -/** - * Windows with PHP < 5.3.0 will not have the function - * openssl_random_pseudo_bytes() available, so let's use - * CAPICOM to work around this deficiency. - * - * @param int $bytes - * - * @throws Exception - * - * @return string - */ -function random_bytes($bytes) -{ - try { - $bytes = RandomCompat_intval($bytes); - } catch (TypeError $ex) { - throw new TypeError( - 'random_bytes(): $bytes must be an integer' - ); - } - if ($bytes < 1) { - throw new Error( - 'Length must be greater than 0' - ); - } - $buf = ''; - $util = new COM('CAPICOM.Utilities.1'); - $execCount = 0; +if (!is_callable('random_bytes')) { /** - * Let's not let it loop forever. If we run N times and fail to - * get N bytes of random data, then CAPICOM has failed us. + * Windows with PHP < 5.3.0 will not have the function + * openssl_random_pseudo_bytes() available, so let's use + * CAPICOM to work around this deficiency. + * + * @param int $bytes + * + * @throws Exception + * + * @return string */ - do { - $buf .= base64_decode($util->GetRandom($bytes, 0)); - if (RandomCompat_strlen($buf) >= $bytes) { - /** - * Return our random entropy buffer here: - */ - return RandomCompat_substr($buf, 0, $bytes); + function random_bytes($bytes) + { + try { + $bytes = RandomCompat_intval($bytes); + } catch (TypeError $ex) { + throw new TypeError( + 'random_bytes(): $bytes must be an integer' + ); } - ++$execCount; - } while ($execCount < $bytes); - /** - * If we reach here, PHP has failed us. - */ - throw new Exception( - 'Could not gather sufficient random data' - ); -} + + if ($bytes < 1) { + throw new Error( + 'Length must be greater than 0' + ); + } + + $buf = ''; + if (!class_exists('COM')) { + throw new Error( + 'COM does not exist' + ); + } + $util = new COM('CAPICOM.Utilities.1'); + $execCount = 0; + + /** + * Let's not let it loop forever. If we run N times and fail to + * get N bytes of random data, then CAPICOM has failed us. + */ + do { + $buf .= base64_decode($util->GetRandom($bytes, 0)); + if (RandomCompat_strlen($buf) >= $bytes) { + /** + * Return our random entropy buffer here: + */ + return RandomCompat_substr($buf, 0, $bytes); + } + ++$execCount; + } while ($execCount < $bytes); + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); + } +} \ No newline at end of file diff --git a/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php b/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php index 5d07104b..df5b9152 100644 --- a/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php +++ b/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php @@ -4,8 +4,8 @@ * for using the new PHP 7 random_* API in PHP 5 projects * * The MIT License (MIT) - * - * Copyright (c) 2015 Paragon Initiative Enterprises + * + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,113 +30,138 @@ define('RANDOM_COMPAT_READ_BUFFER', 8); } -/** - * Unless open_basedir is enabled, use /dev/urandom for - * random numbers in accordance with best practices - * - * Why we use /dev/urandom and not /dev/random - * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers - * - * @param int $bytes - * - * @throws Exception - * - * @return string - */ -function random_bytes($bytes) -{ - static $fp = null; +if (!is_callable('random_bytes')) { /** - * This block should only be run once + * Unless open_basedir is enabled, use /dev/urandom for + * random numbers in accordance with best practices + * + * Why we use /dev/urandom and not /dev/random + * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers + * + * @param int $bytes + * + * @throws Exception + * + * @return string */ - if (empty($fp)) { + function random_bytes($bytes) + { + static $fp = null; /** - * We use /dev/urandom if it is a char device. - * We never fall back to /dev/random + * This block should only be run once */ - $fp = fopen('/dev/urandom', 'rb'); - if (!empty($fp)) { - $st = fstat($fp); - if (($st['mode'] & 0170000) !== 020000) { - fclose($fp); - $fp = false; - } - } - if (!empty($fp)) { + if (empty($fp)) { /** - * stream_set_read_buffer() does not exist in HHVM - * - * If we don't set the stream's read buffer to 0, PHP will - * internally buffer 8192 bytes, which can waste entropy - * - * stream_set_read_buffer returns 0 on success + * We use /dev/urandom if it is a char device. + * We never fall back to /dev/random */ - if (function_exists('stream_set_read_buffer')) { - stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER); + $fp = fopen('/dev/urandom', 'rb'); + if (!empty($fp)) { + $st = fstat($fp); + if (($st['mode'] & 0170000) !== 020000) { + fclose($fp); + $fp = false; + } } - if (function_exists('stream_set_chunk_size')) { - stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER); + + if (!empty($fp)) { + /** + * stream_set_read_buffer() does not exist in HHVM + * + * If we don't set the stream's read buffer to 0, PHP will + * internally buffer 8192 bytes, which can waste entropy + * + * stream_set_read_buffer returns 0 on success + */ + if (is_callable('stream_set_read_buffer')) { + stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER); + } + if (is_callable('stream_set_chunk_size')) { + stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER); + } } } - } - try { - $bytes = RandomCompat_intval($bytes); - } catch (TypeError $ex) { - throw new TypeError( - 'random_bytes(): $bytes must be an integer' - ); - } - if ($bytes < 1) { - throw new Error( - 'Length must be greater than 0' - ); - } - /** - * This if() block only runs if we managed to open a file handle - * - * It does not belong in an else {} block, because the above - * if (empty($fp)) line is logic that should only be run once per - * page load. - */ - if (!empty($fp)) { - $remaining = $bytes; - $buf = ''; + + try { + $bytes = RandomCompat_intval($bytes); + } catch (TypeError $ex) { + throw new TypeError( + 'random_bytes(): $bytes must be an integer' + ); + } + + if ($bytes < 1) { + throw new Error( + 'Length must be greater than 0' + ); + } + /** - * We use fread() in a loop to protect against partial reads + * This if() block only runs if we managed to open a file handle + * + * It does not belong in an else {} block, because the above + * if (empty($fp)) line is logic that should only be run once per + * page load. */ - do { - $read = fread($fp, $remaining); - if ($read === false) { - /** - * We cannot safely read from the file. Exit the - * do-while loop and trigger the exception condition - */ - $buf = false; - break; - } + if (!empty($fp)) { /** - * Decrease the number of bytes returned from remaining + * @var int */ - $remaining -= RandomCompat_strlen($read); - $buf .= $read; - } while ($remaining > 0); - - /** - * Is our result valid? - */ - if ($buf !== false) { - if (RandomCompat_strlen($buf) === $bytes) { + $remaining = $bytes; + + /** + * @var string|bool + */ + $buf = ''; + + /** + * We use fread() in a loop to protect against partial reads + */ + do { /** - * Return our random entropy buffer here: + * @var string|bool */ - return $buf; + $read = fread($fp, $remaining); + if (!is_string($read)) { + if ($read === false) { + /** + * We cannot safely read from the file. Exit the + * do-while loop and trigger the exception condition + * + * @var string|bool + */ + $buf = false; + break; + } + } + /** + * Decrease the number of bytes returned from remaining + */ + $remaining -= RandomCompat_strlen($read); + /** + * @var string|bool + */ + $buf = $buf . $read; + } while ($remaining > 0); + + /** + * Is our result valid? + */ + if (is_string($buf)) { + if (RandomCompat_strlen($buf) === $bytes) { + /** + * Return our random entropy buffer here: + */ + return $buf; + } } } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Error reading from source device' + ); } - /** - * If we reach here, PHP has failed us. - */ - throw new Exception( - 'Error reading from source device' - ); } diff --git a/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php b/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php index 938cac92..4af1a242 100644 --- a/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php +++ b/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php @@ -4,8 +4,8 @@ * for using the new PHP 7 random_* API in PHP 5 projects * * The MIT License (MIT) - * - * Copyright (c) 2015 Paragon Initiative Enterprises + * + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,59 +26,63 @@ * SOFTWARE. */ -/** - * If the libsodium PHP extension is loaded, we'll use it above any other - * solution. - * - * libsodium-php project: - * @ref https://github.com/jedisct1/libsodium-php - * - * @param int $bytes - * - * @throws Exception - * - * @return string - */ -function random_bytes($bytes) -{ - try { - $bytes = RandomCompat_intval($bytes); - } catch (TypeError $ex) { - throw new TypeError( - 'random_bytes(): $bytes must be an integer' - ); - } - if ($bytes < 1) { - throw new Error( - 'Length must be greater than 0' - ); - } +if (!is_callable('random_bytes')) { /** - * \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be - * generated in one invocation. + * If the libsodium PHP extension is loaded, we'll use it above any other + * solution. + * + * libsodium-php project: + * @ref https://github.com/jedisct1/libsodium-php + * + * @param int $bytes + * + * @throws Exception + * + * @return string */ - if ($bytes > 2147483647) { - $buf = ''; - for ($i = 0; $i < $bytes; $i += 1073741824) { - $n = ($bytes - $i) > 1073741824 - ? 1073741824 - : $bytes - $i; - $buf .= \Sodium\randombytes_buf($n); + function random_bytes($bytes) + { + try { + $bytes = RandomCompat_intval($bytes); + } catch (TypeError $ex) { + throw new TypeError( + 'random_bytes(): $bytes must be an integer' + ); } - } else { - $buf = \Sodium\randombytes_buf($bytes); - } - if ($buf !== false) { - if (RandomCompat_strlen($buf) === $bytes) { - return $buf; + if ($bytes < 1) { + throw new Error( + 'Length must be greater than 0' + ); } - } - /** - * If we reach here, PHP has failed us. - */ - throw new Exception( - 'Could not gather sufficient random data' - ); + /** + * \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be + * generated in one invocation. + */ + if ($bytes > 2147483647) { + $buf = ''; + for ($i = 0; $i < $bytes; $i += 1073741824) { + $n = ($bytes - $i) > 1073741824 + ? 1073741824 + : $bytes - $i; + $buf .= \Sodium\randombytes_buf($n); + } + } else { + $buf = \Sodium\randombytes_buf($bytes); + } + + if ($buf !== false) { + if (RandomCompat_strlen($buf) === $bytes) { + return $buf; + } + } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); + } } diff --git a/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php b/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php new file mode 100644 index 00000000..02160b91 --- /dev/null +++ b/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php @@ -0,0 +1,92 @@ + 2147483647) { + for ($i = 0; $i < $bytes; $i += 1073741824) { + $n = ($bytes - $i) > 1073741824 + ? 1073741824 + : $bytes - $i; + $buf .= Sodium::randombytes_buf($n); + } + } else { + $buf .= Sodium::randombytes_buf($bytes); + } + + if (is_string($buf)) { + if (RandomCompat_strlen($buf) === $bytes) { + return $buf; + } + } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); + } +} diff --git a/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php b/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php index 5a1b688f..aac9c013 100644 --- a/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php +++ b/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php @@ -4,8 +4,8 @@ * for using the new PHP 7 random_* API in PHP 5 projects * * The MIT License (MIT) - * - * Copyright (c) 2015 Paragon Initiative Enterprises + * + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,47 +26,52 @@ * SOFTWARE. */ +if (!is_callable('random_bytes')) { + /** + * Powered by ext/mcrypt (and thankfully NOT libmcrypt) + * + * @ref https://bugs.php.net/bug.php?id=55169 + * @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386 + * + * @param int $bytes + * + * @throws Exception + * + * @return string + */ + function random_bytes($bytes) + { + try { + $bytes = RandomCompat_intval($bytes); + } catch (TypeError $ex) { + throw new TypeError( + 'random_bytes(): $bytes must be an integer' + ); + } -/** - * Powered by ext/mcrypt (and thankfully NOT libmcrypt) - * - * @ref https://bugs.php.net/bug.php?id=55169 - * @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386 - * - * @param int $bytes - * - * @throws Exception - * - * @return string - */ -function random_bytes($bytes) -{ - try { - $bytes = RandomCompat_intval($bytes); - } catch (TypeError $ex) { - throw new TypeError( - 'random_bytes(): $bytes must be an integer' - ); - } - if ($bytes < 1) { - throw new Error( - 'Length must be greater than 0' - ); - } + if ($bytes < 1) { + throw new Error( + 'Length must be greater than 0' + ); + } - $buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); - if ($buf !== false) { - if (RandomCompat_strlen($buf) === $bytes) { + $buf = @mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); + if ( + $buf !== false + && + RandomCompat_strlen($buf) === $bytes + ) { /** * Return our random entropy buffer here: */ return $buf; } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); } - /** - * If we reach here, PHP has failed us. - */ - throw new Exception( - 'Could not gather sufficient random data' - ); } diff --git a/vendor/paragonie/random_compat/lib/random_bytes_openssl.php b/vendor/paragonie/random_compat/lib/random_bytes_openssl.php deleted file mode 100644 index 3e12d3da..00000000 --- a/vendor/paragonie/random_compat/lib/random_bytes_openssl.php +++ /dev/null @@ -1,76 +0,0 @@ - operators might accidentally let a float - * through. - */ - - try { - $min = RandomCompat_intval($min); - } catch (TypeError $ex) { - throw new TypeError( - 'random_int(): $min must be an integer' - ); - } - try { - $max = RandomCompat_intval($max); - } catch (TypeError $ex) { - throw new TypeError( - 'random_int(): $max must be an integer' - ); - } - - /** - * Now that we've verified our weak typing system has given us an integer, - * let's validate the logic then we can move forward with generating random - * integers along a given range. - */ - if ($min > $max) { - throw new Error( - 'Minimum value must be less than or equal to the maximum value' - ); - } - if ($max === $min) { - return $min; - } - - /** - * Initialize variables to 0 - * - * We want to store: - * $bytes => the number of random bytes we need - * $mask => an integer bitmask (for use with the &) operator - * so we can minimize the number of discards - */ - $attempts = $bits = $bytes = $mask = $valueShift = 0; +if (!is_callable('random_int')) { /** - * At this point, $range is a positive number greater than 0. It might - * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to - * a float and we will lose some precision. + * Random_* Compatibility Library + * for using the new PHP 7 random_* API in PHP 5 projects + * + * The MIT License (MIT) + * + * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ - $range = $max - $min; /** - * Test for integer overflow: + * Fetch a random integer between $min and $max inclusive + * + * @param int $min + * @param int $max + * + * @throws Exception + * + * @return int */ - if (!is_int($range)) { + function random_int($min, $max) + { /** - * Still safely calculate wider ranges. - * Provided by @CodesInChaos, @oittaa - * - * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435 - * - * We use ~0 as a mask in this case because it generates all 1s - * - * @ref https://eval.in/400356 (32-bit) - * @ref http://3v4l.org/XX9r5 (64-bit) + * Type and input logic checks + * + * If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX) + * (non-inclusive), it will sanely cast it to an int. If you it's equal to + * ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats + * lose precision, so the <= and => operators might accidentally let a float + * through. */ - $bytes = PHP_INT_SIZE; - $mask = ~0; - } else { - /** - * $bits is effectively ceil(log($range, 2)) without dealing with - * type juggling - */ - while ($range > 0) { - if ($bits % 8 === 0) { - ++$bytes; - } - ++$bits; - $range >>= 1; - $mask = $mask << 1 | 1; + + try { + $min = RandomCompat_intval($min); + } catch (TypeError $ex) { + throw new TypeError( + 'random_int(): $min must be an integer' + ); } - $valueShift = $min; - } - /** - * Now that we have our parameters set up, let's begin generating - * random integers until one falls between $min and $max - */ - do { - /** - * The rejection probability is at most 0.5, so this corresponds - * to a failure probability of 2^-128 for a working RNG - */ - if ($attempts > 128) { - throw new Exception( - 'random_int: RNG is broken - too many rejections' + try { + $max = RandomCompat_intval($max); + } catch (TypeError $ex) { + throw new TypeError( + 'random_int(): $max must be an integer' ); } /** - * Let's grab the necessary number of random bytes + * Now that we've verified our weak typing system has given us an integer, + * let's validate the logic then we can move forward with generating random + * integers along a given range. */ - $randomByteString = random_bytes($bytes); - if ($randomByteString === false) { - throw new Exception( - 'Random number generator failure' + if ($min > $max) { + throw new Error( + 'Minimum value must be less than or equal to the maximum value' ); } + if ($max === $min) { + return $min; + } + /** - * Let's turn $randomByteString into an integer - * - * This uses bitwise operators (<< and |) to build an integer - * out of the values extracted from ord() - * - * Example: [9F] | [6D] | [32] | [0C] => - * 159 + 27904 + 3276800 + 201326592 => - * 204631455 + * Initialize variables to 0 + * + * We want to store: + * $bytes => the number of random bytes we need + * $mask => an integer bitmask (for use with the &) operator + * so we can minimize the number of discards */ - $val = 0; - for ($i = 0; $i < $bytes; ++$i) { - $val |= ord($randomByteString[$i]) << ($i * 8); - } + $attempts = $bits = $bytes = $mask = $valueShift = 0; /** - * Apply mask + * At this point, $range is a positive number greater than 0. It might + * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to + * a float and we will lose some precision. */ - $val &= $mask; - $val += $valueShift; + $range = $max - $min; - ++$attempts; /** - * If $val overflows to a floating point number, - * ... or is larger than $max, - * ... or smaller than $min, - * then try again. + * Test for integer overflow: */ - } while (!is_int($val) || $val > $max || $val < $min); - return (int) $val; + if (!is_int($range)) { + + /** + * Still safely calculate wider ranges. + * Provided by @CodesInChaos, @oittaa + * + * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435 + * + * We use ~0 as a mask in this case because it generates all 1s + * + * @ref https://eval.in/400356 (32-bit) + * @ref http://3v4l.org/XX9r5 (64-bit) + */ + $bytes = PHP_INT_SIZE; + $mask = ~0; + + } else { + + /** + * $bits is effectively ceil(log($range, 2)) without dealing with + * type juggling + */ + while ($range > 0) { + if ($bits % 8 === 0) { + ++$bytes; + } + ++$bits; + $range >>= 1; + $mask = $mask << 1 | 1; + } + $valueShift = $min; + } + + $val = 0; + /** + * Now that we have our parameters set up, let's begin generating + * random integers until one falls between $min and $max + */ + do { + /** + * The rejection probability is at most 0.5, so this corresponds + * to a failure probability of 2^-128 for a working RNG + */ + if ($attempts > 128) { + throw new Exception( + 'random_int: RNG is broken - too many rejections' + ); + } + + /** + * Let's grab the necessary number of random bytes + */ + $randomByteString = random_bytes($bytes); + + /** + * Let's turn $randomByteString into an integer + * + * This uses bitwise operators (<< and |) to build an integer + * out of the values extracted from ord() + * + * Example: [9F] | [6D] | [32] | [0C] => + * 159 + 27904 + 3276800 + 201326592 => + * 204631455 + */ + $val &= 0; + for ($i = 0; $i < $bytes; ++$i) { + $val |= ord($randomByteString[$i]) << ($i * 8); + } + + /** + * Apply mask + */ + $val &= $mask; + $val += $valueShift; + + ++$attempts; + /** + * If $val overflows to a floating point number, + * ... or is larger than $max, + * ... or smaller than $min, + * then try again. + */ + } while (!is_int($val) || $val > $max || $val < $min); + + return (int)$val; + } } diff --git a/vendor/paragonie/random_compat/other/build_phar.php b/vendor/paragonie/random_compat/other/build_phar.php new file mode 100644 index 00000000..70ef4b2e --- /dev/null +++ b/vendor/paragonie/random_compat/other/build_phar.php @@ -0,0 +1,57 @@ +buildFromDirectory(dirname(__DIR__).'/lib'); +rename( + dirname(__DIR__).'/lib/index.php', + dirname(__DIR__).'/lib/random.php' +); + +/** + * If we pass an (optional) path to a private key as a second argument, we will + * sign the Phar with OpenSSL. + * + * If you leave this out, it will produce an unsigned .phar! + */ +if ($argc > 1) { + if (!@is_readable($argv[1])) { + echo 'Could not read the private key file:', $argv[1], "\n"; + exit(255); + } + $pkeyFile = file_get_contents($argv[1]); + + $private = openssl_get_privatekey($pkeyFile); + if ($private !== false) { + $pkey = ''; + openssl_pkey_export($private, $pkey); + $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + + /** + * Save the corresponding public key to the file + */ + if (!@is_readable($dist.'/random_compat.phar.pubkey')) { + $details = openssl_pkey_get_details($private); + file_put_contents( + $dist.'/random_compat.phar.pubkey', + $details['key'] + ); + } + } else { + echo 'An error occurred reading the private key from OpenSSL.', "\n"; + exit(255); + } +} diff --git a/vendor/paragonie/random_compat/phpunit.sh b/vendor/paragonie/random_compat/phpunit.sh deleted file mode 100755 index c4c6a9f6..00000000 --- a/vendor/paragonie/random_compat/phpunit.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -if [ "$1" == 'full' ]; then - fulltest=1 -elif [ "$1" == 'each' ]; then - testeach=1 -else - fulltest=0 -fi - -PHP_VERSION=$(php -r "echo PHP_VERSION_ID;") - -echo -echo -e "\033[33mBegin Unit Testing\033[0m" -# Run the testing suite -echo "Basic test suite:" -php vendor/bin/phpunit tests/unit -if [ $? -ne 0 ]; then - # Test failure - exit 1 -fi -echo "With open_basedir enabled:" -php -d open_basedir=`pwd` vendor/bin/phpunit tests/unit -if [ $? -ne 0 ]; then - # Test failure - exit 1 -fi -echo "With open_basedir enabled, allowing /dev:" -php -d open_basedir=`pwd`:/dev vendor/bin/phpunit tests/unit -if [ $? -ne 0 ]; then - # Test failure - exit 1 -fi -echo "With mbstring.func_overload enabled:" -php -d mbstring.func_overload=7 vendor/bin/phpunit tests/unit -if [ $? -ne 0 ]; then - # Test failure - exit 1 -fi - -if [[ "$testeach" == "1" ]]; then - echo " CAPICOM:" - php vendor/bin/phpunit --bootstrap tests/specific/capicom.php tests/unit - echo " /dev/urandom:" - php vendor/bin/phpunit --bootstrap tests/specific/dev_urandom.php tests/unit - echo " libsodium:" - php vendor/bin/phpunit --bootstrap tests/specific/libsodium.php tests/unit - echo " mcrypt:" - php vendor/bin/phpunit --bootstrap tests/specific/mcrypt.php tests/unit - echo " openssl:" - php vendor/bin/phpunit --bootstrap tests/specific/openssl.php tests/unit -fi - -# Should we perform full statistical analyses? -if [[ "$fulltest" == "1" ]]; then - php vendor/bin/phpunit tests/full - if [ $? -ne 0 ]; then - # Test failure - exit 1 - fi -fi - diff --git a/vendor/paragonie/random_compat/phpunit.xml.dist b/vendor/paragonie/random_compat/phpunit.xml.dist deleted file mode 100644 index b4697d35..00000000 --- a/vendor/paragonie/random_compat/phpunit.xml.dist +++ /dev/null @@ -1,29 +0,0 @@ - - - - - tests/unit - - - - - ./tests/unit - - - - - ./lib - - - \ No newline at end of file diff --git a/vendor/paragonie/random_compat/psalm-autoload.php b/vendor/paragonie/random_compat/psalm-autoload.php new file mode 100644 index 00000000..d71d1b81 --- /dev/null +++ b/vendor/paragonie/random_compat/psalm-autoload.php @@ -0,0 +1,9 @@ + + + + + + + + + + + diff --git a/vendor/psr/http-message/CHANGELOG.md b/vendor/psr/http-message/CHANGELOG.md new file mode 100644 index 00000000..74b1ef92 --- /dev/null +++ b/vendor/psr/http-message/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 1.0.1 - 2016-08-06 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Updated all `@return self` annotation references in interfaces to use + `@return static`, which more closelly follows the semantics of the + specification. +- Updated the `MessageInterface::getHeaders()` return annotation to use the + value `string[][]`, indicating the format is a nested array of strings. +- Updated the `@link` annotation for `RequestInterface::withRequestTarget()` + to point to the correct section of RFC 7230. +- Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation + to add the parameter name (`$uploadedFiles`). +- Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()` + method to correctly reference the method parameter (it was referencing an + incorrect parameter name previously). + +## 1.0.0 - 2016-05-18 + +Initial stable release; reflects accepted PSR-7 specification. diff --git a/vendor/psr/http-message/composer.json b/vendor/psr/http-message/composer.json index 4774b612..b0d2937a 100644 --- a/vendor/psr/http-message/composer.json +++ b/vendor/psr/http-message/composer.json @@ -2,6 +2,7 @@ "name": "psr/http-message", "description": "Common interface for HTTP messages", "keywords": ["psr", "psr-7", "http", "http-message", "request", "response"], + "homepage": "https://github.com/php-fig/http-message", "license": "MIT", "authors": [ { diff --git a/vendor/psr/http-message/src/MessageInterface.php b/vendor/psr/http-message/src/MessageInterface.php index 8f67a050..dd46e5ec 100644 --- a/vendor/psr/http-message/src/MessageInterface.php +++ b/vendor/psr/http-message/src/MessageInterface.php @@ -36,7 +36,7 @@ public function getProtocolVersion(); * new protocol version. * * @param string $version HTTP protocol version - * @return self + * @return static */ public function withProtocolVersion($version); @@ -61,7 +61,7 @@ public function withProtocolVersion($version); * While header names are not case-sensitive, getHeaders() will preserve the * exact case in which headers were originally specified. * - * @return array Returns an associative array of the message's headers. Each + * @return string[][] Returns an associative array of the message's headers. Each * key MUST be a header name, and each value MUST be an array of strings * for that header. */ @@ -126,7 +126,7 @@ public function getHeaderLine($name); * * @param string $name Case-insensitive header field name. * @param string|string[] $value Header value(s). - * @return self + * @return static * @throws \InvalidArgumentException for invalid header names or values. */ public function withHeader($name, $value); @@ -144,7 +144,7 @@ public function withHeader($name, $value); * * @param string $name Case-insensitive header field name to add. * @param string|string[] $value Header value(s). - * @return self + * @return static * @throws \InvalidArgumentException for invalid header names or values. */ public function withAddedHeader($name, $value); @@ -159,7 +159,7 @@ public function withAddedHeader($name, $value); * the named header. * * @param string $name Case-insensitive header field name to remove. - * @return self + * @return static */ public function withoutHeader($name); @@ -180,7 +180,7 @@ public function getBody(); * new body stream. * * @param StreamInterface $body Body. - * @return self + * @return static * @throws \InvalidArgumentException When the body is not valid. */ public function withBody(StreamInterface $body); diff --git a/vendor/psr/http-message/src/RequestInterface.php b/vendor/psr/http-message/src/RequestInterface.php index 75c802e2..a96d4fd6 100644 --- a/vendor/psr/http-message/src/RequestInterface.php +++ b/vendor/psr/http-message/src/RequestInterface.php @@ -53,10 +53,10 @@ public function getRequestTarget(); * immutability of the message, and MUST return an instance that has the * changed request target. * - * @link http://tools.ietf.org/html/rfc7230#section-2.7 (for the various + * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various * request-target forms allowed in request messages) * @param mixed $requestTarget - * @return self + * @return static */ public function withRequestTarget($requestTarget); @@ -79,7 +79,7 @@ public function getMethod(); * changed request method. * * @param string $method Case-sensitive method. - * @return self + * @return static * @throws \InvalidArgumentException for invalid HTTP methods. */ public function withMethod($method); @@ -107,7 +107,7 @@ public function getUri(); * setting `$preserveHost` to `true`. When `$preserveHost` is set to * `true`, this method interacts with the Host header in the following ways: * - * - If the the Host header is missing or empty, and the new URI contains + * - If the Host header is missing or empty, and the new URI contains * a host component, this method MUST update the Host header in the returned * request. * - If the Host header is missing or empty, and the new URI does not contain a @@ -123,7 +123,7 @@ public function getUri(); * @link http://tools.ietf.org/html/rfc3986#section-4.3 * @param UriInterface $uri New request URI to use. * @param bool $preserveHost Preserve the original state of the Host header. - * @return self + * @return static */ public function withUri(UriInterface $uri, $preserveHost = false); } diff --git a/vendor/psr/http-message/src/ResponseInterface.php b/vendor/psr/http-message/src/ResponseInterface.php index 6724809e..c306514e 100644 --- a/vendor/psr/http-message/src/ResponseInterface.php +++ b/vendor/psr/http-message/src/ResponseInterface.php @@ -46,7 +46,7 @@ public function getStatusCode(); * @param string $reasonPhrase The reason phrase to use with the * provided status code; if none is provided, implementations MAY * use the defaults as suggested in the HTTP specification. - * @return self + * @return static * @throws \InvalidArgumentException For invalid status code arguments. */ public function withStatus($code, $reasonPhrase = ''); diff --git a/vendor/psr/http-message/src/ServerRequestInterface.php b/vendor/psr/http-message/src/ServerRequestInterface.php index 916e0658..02512340 100644 --- a/vendor/psr/http-message/src/ServerRequestInterface.php +++ b/vendor/psr/http-message/src/ServerRequestInterface.php @@ -80,7 +80,7 @@ public function getCookieParams(); * updated cookie values. * * @param array $cookies Array of key/value pairs representing cookies. - * @return self + * @return static */ public function withCookieParams(array $cookies); @@ -118,7 +118,7 @@ public function getQueryParams(); * * @param array $query Array of query string arguments, typically from * $_GET. - * @return self + * @return static */ public function withQueryParams(array $query); @@ -143,8 +143,8 @@ public function getUploadedFiles(); * immutability of the message, and MUST return an instance that has the * updated body parameters. * - * @param array An array tree of UploadedFileInterface instances. - * @return self + * @param array $uploadedFiles An array tree of UploadedFileInterface instances. + * @return static * @throws \InvalidArgumentException if an invalid structure is provided. */ public function withUploadedFiles(array $uploadedFiles); @@ -190,7 +190,7 @@ public function getParsedBody(); * * @param null|array|object $data The deserialized body data. This will * typically be in an array or object. - * @return self + * @return static * @throws \InvalidArgumentException if an unsupported argument type is * provided. */ @@ -239,7 +239,7 @@ public function getAttribute($name, $default = null); * @see getAttributes() * @param string $name The attribute name. * @param mixed $value The value of the attribute. - * @return self + * @return static */ public function withAttribute($name, $value); @@ -255,7 +255,7 @@ public function withAttribute($name, $value); * * @see getAttributes() * @param string $name The attribute name. - * @return self + * @return static */ public function withoutAttribute($name); } diff --git a/vendor/psr/http-message/src/UploadedFileInterface.php b/vendor/psr/http-message/src/UploadedFileInterface.php index 5ad288d2..f8a6901e 100644 --- a/vendor/psr/http-message/src/UploadedFileInterface.php +++ b/vendor/psr/http-message/src/UploadedFileInterface.php @@ -58,7 +58,7 @@ public function getStream(); * @see http://php.net/is_uploaded_file * @see http://php.net/move_uploaded_file * @param string $targetPath Path to which to move the uploaded file. - * @throws \InvalidArgumentException if the $path specified is invalid. + * @throws \InvalidArgumentException if the $targetPath specified is invalid. * @throws \RuntimeException on any error during the move operation, or on * the second or subsequent call to the method. */ diff --git a/vendor/psr/http-message/src/UriInterface.php b/vendor/psr/http-message/src/UriInterface.php index 1ff5bf01..9d7ab9ea 100644 --- a/vendor/psr/http-message/src/UriInterface.php +++ b/vendor/psr/http-message/src/UriInterface.php @@ -185,7 +185,7 @@ public function getFragment(); * An empty scheme is equivalent to removing the scheme. * * @param string $scheme The scheme to use with the new instance. - * @return self A new instance with the specified scheme. + * @return static A new instance with the specified scheme. * @throws \InvalidArgumentException for invalid or unsupported schemes. */ public function withScheme($scheme); @@ -202,7 +202,7 @@ public function withScheme($scheme); * * @param string $user The user name to use for authority. * @param null|string $password The password associated with $user. - * @return self A new instance with the specified user information. + * @return static A new instance with the specified user information. */ public function withUserInfo($user, $password = null); @@ -215,7 +215,7 @@ public function withUserInfo($user, $password = null); * An empty host value is equivalent to removing the host. * * @param string $host The hostname to use with the new instance. - * @return self A new instance with the specified host. + * @return static A new instance with the specified host. * @throws \InvalidArgumentException for invalid hostnames. */ public function withHost($host); @@ -234,7 +234,7 @@ public function withHost($host); * * @param null|int $port The port to use with the new instance; a null value * removes the port information. - * @return self A new instance with the specified port. + * @return static A new instance with the specified port. * @throws \InvalidArgumentException for invalid ports. */ public function withPort($port); @@ -258,7 +258,7 @@ public function withPort($port); * Implementations ensure the correct encoding as outlined in getPath(). * * @param string $path The path to use with the new instance. - * @return self A new instance with the specified path. + * @return static A new instance with the specified path. * @throws \InvalidArgumentException for invalid paths. */ public function withPath($path); @@ -275,7 +275,7 @@ public function withPath($path); * An empty query string value is equivalent to removing the query string. * * @param string $query The query string to use with the new instance. - * @return self A new instance with the specified query string. + * @return static A new instance with the specified query string. * @throws \InvalidArgumentException for invalid query strings. */ public function withQuery($query); @@ -292,7 +292,7 @@ public function withQuery($query); * An empty fragment value is equivalent to removing the fragment. * * @param string $fragment The fragment to use with the new instance. - * @return self A new instance with the specified fragment. + * @return static A new instance with the specified fragment. */ public function withFragment($fragment); diff --git a/vendor/psr/log/Psr/Log/AbstractLogger.php b/vendor/psr/log/Psr/Log/AbstractLogger.php index 00f90345..90e721af 100644 --- a/vendor/psr/log/Psr/Log/AbstractLogger.php +++ b/vendor/psr/log/Psr/Log/AbstractLogger.php @@ -15,8 +15,9 @@ abstract class AbstractLogger implements LoggerInterface * System is unusable. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function emergency($message, array $context = array()) { @@ -30,8 +31,9 @@ public function emergency($message, array $context = array()) * trigger the SMS alerts and wake you up. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function alert($message, array $context = array()) { @@ -44,8 +46,9 @@ public function alert($message, array $context = array()) * Example: Application component unavailable, unexpected exception. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function critical($message, array $context = array()) { @@ -57,8 +60,9 @@ public function critical($message, array $context = array()) * be logged and monitored. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function error($message, array $context = array()) { @@ -72,8 +76,9 @@ public function error($message, array $context = array()) * that are not necessarily wrong. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function warning($message, array $context = array()) { @@ -84,8 +89,9 @@ public function warning($message, array $context = array()) * Normal but significant events. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function notice($message, array $context = array()) { @@ -98,8 +104,9 @@ public function notice($message, array $context = array()) * Example: User logs in, SQL logs. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function info($message, array $context = array()) { @@ -110,8 +117,9 @@ public function info($message, array $context = array()) * Detailed debug information. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function debug($message, array $context = array()) { diff --git a/vendor/psr/log/Psr/Log/LogLevel.php b/vendor/psr/log/Psr/Log/LogLevel.php index e32c151c..9cebcace 100644 --- a/vendor/psr/log/Psr/Log/LogLevel.php +++ b/vendor/psr/log/Psr/Log/LogLevel.php @@ -3,16 +3,16 @@ namespace Psr\Log; /** - * Describes log levels + * Describes log levels. */ class LogLevel { const EMERGENCY = 'emergency'; - const ALERT = 'alert'; - const CRITICAL = 'critical'; - const ERROR = 'error'; - const WARNING = 'warning'; - const NOTICE = 'notice'; - const INFO = 'info'; - const DEBUG = 'debug'; + const ALERT = 'alert'; + const CRITICAL = 'critical'; + const ERROR = 'error'; + const WARNING = 'warning'; + const NOTICE = 'notice'; + const INFO = 'info'; + const DEBUG = 'debug'; } diff --git a/vendor/psr/log/Psr/Log/LoggerAwareInterface.php b/vendor/psr/log/Psr/Log/LoggerAwareInterface.php index 2eebc4eb..4d64f478 100644 --- a/vendor/psr/log/Psr/Log/LoggerAwareInterface.php +++ b/vendor/psr/log/Psr/Log/LoggerAwareInterface.php @@ -3,15 +3,16 @@ namespace Psr\Log; /** - * Describes a logger-aware instance + * Describes a logger-aware instance. */ interface LoggerAwareInterface { /** - * Sets a logger instance on the object + * Sets a logger instance on the object. * * @param LoggerInterface $logger - * @return null + * + * @return void */ public function setLogger(LoggerInterface $logger); } diff --git a/vendor/psr/log/Psr/Log/LoggerAwareTrait.php b/vendor/psr/log/Psr/Log/LoggerAwareTrait.php index f087a3da..639f79bd 100644 --- a/vendor/psr/log/Psr/Log/LoggerAwareTrait.php +++ b/vendor/psr/log/Psr/Log/LoggerAwareTrait.php @@ -7,12 +7,16 @@ */ trait LoggerAwareTrait { - /** @var LoggerInterface */ + /** + * The logger instance. + * + * @var LoggerInterface + */ protected $logger; /** * Sets a logger. - * + * * @param LoggerInterface $logger */ public function setLogger(LoggerInterface $logger) diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php index 476bb962..5ea72438 100644 --- a/vendor/psr/log/Psr/Log/LoggerInterface.php +++ b/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -3,14 +3,14 @@ namespace Psr\Log; /** - * Describes a logger instance + * Describes a logger instance. * * The message MUST be a string or object implementing __toString(). * * The message MAY contain placeholders in the form: {foo} where foo * will be replaced by the context data in key "foo". * - * The context array can contain arbitrary data, the only assumption that + * The context array can contain arbitrary data. The only assumption that * can be made by implementors is that if an Exception instance is given * to produce a stack trace, it MUST be in a key named "exception". * @@ -23,8 +23,9 @@ interface LoggerInterface * System is unusable. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function emergency($message, array $context = array()); @@ -35,8 +36,9 @@ public function emergency($message, array $context = array()); * trigger the SMS alerts and wake you up. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function alert($message, array $context = array()); @@ -46,8 +48,9 @@ public function alert($message, array $context = array()); * Example: Application component unavailable, unexpected exception. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function critical($message, array $context = array()); @@ -56,8 +59,9 @@ public function critical($message, array $context = array()); * be logged and monitored. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function error($message, array $context = array()); @@ -68,8 +72,9 @@ public function error($message, array $context = array()); * that are not necessarily wrong. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function warning($message, array $context = array()); @@ -77,8 +82,9 @@ public function warning($message, array $context = array()); * Normal but significant events. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function notice($message, array $context = array()); @@ -88,8 +94,9 @@ public function notice($message, array $context = array()); * Example: User logs in, SQL logs. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function info($message, array $context = array()); @@ -97,18 +104,20 @@ public function info($message, array $context = array()); * Detailed debug information. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function debug($message, array $context = array()); /** * Logs with an arbitrary level. * - * @param mixed $level + * @param mixed $level * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function log($level, $message, array $context = array()); } diff --git a/vendor/psr/log/Psr/Log/LoggerTrait.php b/vendor/psr/log/Psr/Log/LoggerTrait.php index 59124960..867225df 100644 --- a/vendor/psr/log/Psr/Log/LoggerTrait.php +++ b/vendor/psr/log/Psr/Log/LoggerTrait.php @@ -6,8 +6,8 @@ * This is a simple Logger trait that classes unable to extend AbstractLogger * (because they extend another class, etc) can include. * - * It simply delegates all log-level-specific methods to the `log` method to - * reduce boilerplate code that a simple Logger that does the same thing with + * It simply delegates all log-level-specific methods to the `log` method to + * reduce boilerplate code that a simple Logger that does the same thing with * messages regardless of the error level has to implement. */ trait LoggerTrait @@ -16,8 +16,9 @@ trait LoggerTrait * System is unusable. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function emergency($message, array $context = array()) { @@ -31,8 +32,9 @@ public function emergency($message, array $context = array()) * trigger the SMS alerts and wake you up. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function alert($message, array $context = array()) { @@ -45,8 +47,9 @@ public function alert($message, array $context = array()) * Example: Application component unavailable, unexpected exception. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function critical($message, array $context = array()) { @@ -58,8 +61,9 @@ public function critical($message, array $context = array()) * be logged and monitored. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function error($message, array $context = array()) { @@ -73,8 +77,9 @@ public function error($message, array $context = array()) * that are not necessarily wrong. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function warning($message, array $context = array()) { @@ -85,8 +90,9 @@ public function warning($message, array $context = array()) * Normal but significant events. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function notice($message, array $context = array()) { @@ -99,8 +105,9 @@ public function notice($message, array $context = array()) * Example: User logs in, SQL logs. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function info($message, array $context = array()) { @@ -111,8 +118,9 @@ public function info($message, array $context = array()) * Detailed debug information. * * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function debug($message, array $context = array()) { @@ -122,10 +130,11 @@ public function debug($message, array $context = array()) /** * Logs with an arbitrary level. * - * @param mixed $level + * @param mixed $level * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ abstract public function log($level, $message, array $context = array()); } diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php index 553a3c59..d8cd682c 100644 --- a/vendor/psr/log/Psr/Log/NullLogger.php +++ b/vendor/psr/log/Psr/Log/NullLogger.php @@ -3,7 +3,7 @@ namespace Psr\Log; /** - * This Logger can be used to avoid conditional log calls + * This Logger can be used to avoid conditional log calls. * * Logging should always be optional, and if no logger is provided to your * library creating a NullLogger instance to have something to throw logs at @@ -15,10 +15,11 @@ class NullLogger extends AbstractLogger /** * Logs with an arbitrary level. * - * @param mixed $level + * @param mixed $level * @param string $message - * @param array $context - * @return null + * @param array $context + * + * @return void */ public function log($level, $message, array $context = array()) { diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php index a9328151..a0391a52 100644 --- a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php +++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php @@ -2,28 +2,32 @@ namespace Psr\Log\Test; +use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; /** - * Provides a base test class for ensuring compliance with the LoggerInterface + * Provides a base test class for ensuring compliance with the LoggerInterface. * - * Implementors can extend the class and implement abstract methods to run this as part of their test suite + * Implementors can extend the class and implement abstract methods to run this + * as part of their test suite. */ abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase { /** * @return LoggerInterface */ - abstract function getLogger(); + abstract public function getLogger(); /** - * This must return the log messages in order with a simple formatting: " " + * This must return the log messages in order. * - * Example ->error('Foo') would yield "error Foo" + * The simple formatting of the messages is: " ". + * + * Example ->error('Foo') would yield "error Foo". * * @return string[] */ - abstract function getLogs(); + abstract public function getLogs(); public function testImplements() { @@ -61,7 +65,7 @@ public function provideLevelsAndMessages() } /** - * @expectedException Psr\Log\InvalidArgumentException + * @expectedException \Psr\Log\InvalidArgumentException */ public function testThrowsOnInvalidLevel() { @@ -80,12 +84,19 @@ public function testContextReplacement() public function testObjectCastToString() { - $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } $dummy->expects($this->once()) ->method('__toString') ->will($this->returnValue('DUMMY')); $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); } public function testContextCanContainAnything() @@ -102,15 +113,28 @@ public function testContextCanContainAnything() ); $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); } public function testContextExceptionKeyCanBeExceptionOrOtherValues() { - $this->getLogger()->warning('Random message', array('exception' => 'oops')); - $this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); } } class DummyTest { -} \ No newline at end of file + public function __toString() + { + } +} diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json index 6bdcc219..87934d70 100644 --- a/vendor/psr/log/composer.json +++ b/vendor/psr/log/composer.json @@ -2,6 +2,7 @@ "name": "psr/log", "description": "Common interface for logging libraries", "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", "license": "MIT", "authors": [ { @@ -9,9 +10,17 @@ "homepage": "http://www.php-fig.org/" } ], + "require": { + "php": ">=5.3.0" + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" } } } diff --git a/vendor/symfony-cmf/routing/Candidates/Candidates.php b/vendor/symfony-cmf/routing/Candidates/Candidates.php index 21bef551..b0a3ab4c 100644 --- a/vendor/symfony-cmf/routing/Candidates/Candidates.php +++ b/vendor/symfony-cmf/routing/Candidates/Candidates.php @@ -108,7 +108,7 @@ protected function determineLocale($url) } $matches = array(); - if (preg_match('#('.implode('|', $this->locales).')(/|$)#', $url, $matches)) { + if (preg_match('#^/('.implode('|', $this->locales).')(/|$)#', $url, $matches)) { return $matches[1]; } diff --git a/vendor/symfony-cmf/routing/README.md b/vendor/symfony-cmf/routing/README.md index 2a18ed16..dbafdd20 100644 --- a/vendor/symfony-cmf/routing/README.md +++ b/vendor/symfony-cmf/routing/README.md @@ -1,6 +1,6 @@ # Symfony CMF Routing Component -[![Build Status](https://secure.travis-ci.org/symfony-cmf/Routing.png?branch=master)](http://travis-ci.org/symfony-cmf/Routing) +[![Build Status](https://travis-ci.org/symfony-cmf/routing.svg?branch=master)](https://travis-ci.org/symfony-cmf/routing) [![Latest Stable Version](https://poser.pugx.org/symfony-cmf/routing/version.png)](https://packagist.org/packages/symfony-cmf/routing) [![Total Downloads](https://poser.pugx.org/symfony-cmf/routing/d/total.png)](https://packagist.org/packages/symfony-cmf/routing) diff --git a/vendor/symfony/class-loader/ApcClassLoader.php b/vendor/symfony/class-loader/ApcClassLoader.php index 46ee4a85..5500e362 100644 --- a/vendor/symfony/class-loader/ApcClassLoader.php +++ b/vendor/symfony/class-loader/ApcClassLoader.php @@ -16,8 +16,8 @@ * * It expects an object implementing a findFile method to find the file. This * allows using it as a wrapper around the other loaders of the component (the - * ClassLoader and the UniversalClassLoader for instance) but also around any - * other autoloaders following this convention (the Composer one for instance). + * ClassLoader for instance) but also around any other autoloaders following + * this convention (the Composer one for instance). * * // with a Symfony autoloader * use Symfony\Component\ClassLoader\ClassLoader; diff --git a/vendor/symfony/class-loader/ApcUniversalClassLoader.php b/vendor/symfony/class-loader/ApcUniversalClassLoader.php deleted file mode 100644 index 0ab45678..00000000 --- a/vendor/symfony/class-loader/ApcUniversalClassLoader.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\ClassLoader; - -@trigger_error('The '.__NAMESPACE__.'\ApcUniversalClassLoader class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\ClassLoader\ApcClassLoader class instead.', E_USER_DEPRECATED); - -/** - * ApcUniversalClassLoader implements a "universal" autoloader cached in APC for PHP 5.3. - * - * It is able to load classes that use either: - * - * * The technical interoperability standards for PHP 5.3 namespaces and - * class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md); - * - * * The PEAR naming convention for classes (http://pear.php.net/). - * - * Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be - * looked for in a list of locations to ease the vendoring of a sub-set of - * classes for large projects. - * - * Example usage: - * - * require 'vendor/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; - * require 'vendor/symfony/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php'; - * - * use Symfony\Component\ClassLoader\ApcUniversalClassLoader; - * - * $loader = new ApcUniversalClassLoader('apc.prefix.'); - * - * // register classes with namespaces - * $loader->registerNamespaces(array( - * 'Symfony\Component' => __DIR__.'/component', - * 'Symfony' => __DIR__.'/framework', - * 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'), - * )); - * - * // register a library using the PEAR naming convention - * $loader->registerPrefixes(array( - * 'Swift_' => __DIR__.'/Swift', - * )); - * - * // activate the autoloader - * $loader->register(); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * @author Fabien Potencier - * @author Kris Wallsmith - * - * @deprecated since version 2.4, to be removed in 3.0. - * Use the {@link ClassLoader} class instead. - */ -class ApcUniversalClassLoader extends UniversalClassLoader -{ - private $prefix; - - /** - * Constructor. - * - * @param string $prefix A prefix to create a namespace in APC - * - * @throws \RuntimeException - */ - public function __construct($prefix) - { - if (!function_exists('apcu_fetch')) { - throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.'); - } - - $this->prefix = $prefix; - } - - /** - * Finds a file by class name while caching lookups to APC. - * - * @param string $class A class name to resolve to file - * - * @return string|null The path, if found - */ - public function findFile($class) - { - $file = apcu_fetch($this->prefix.$class, $success); - - if (!$success) { - apcu_store($this->prefix.$class, $file = parent::findFile($class) ?: null); - } - - return $file; - } -} diff --git a/vendor/symfony/class-loader/CHANGELOG.md b/vendor/symfony/class-loader/CHANGELOG.md index 64660a87..64ef8d9c 100644 --- a/vendor/symfony/class-loader/CHANGELOG.md +++ b/vendor/symfony/class-loader/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +3.0.0 +----- + + * The DebugClassLoader class has been removed + * The DebugUniversalClassLoader class has been removed + * The UniversalClassLoader class has been removed + * The ApcUniversalClassLoader class has been removed + 2.4.0 ----- diff --git a/vendor/symfony/class-loader/ClassCollectionLoader.php b/vendor/symfony/class-loader/ClassCollectionLoader.php index 6f88286d..e45c3f8c 100644 --- a/vendor/symfony/class-loader/ClassCollectionLoader.php +++ b/vendor/symfony/class-loader/ClassCollectionLoader.php @@ -44,10 +44,7 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive = self::$loaded[$name] = true; if ($adaptive) { - $declared = array_merge(get_declared_classes(), get_declared_interfaces()); - if (function_exists('get_declared_traits')) { - $declared = array_merge($declared, get_declared_traits()); - } + $declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits()); // don't include already declared classes $classes = array_diff($classes, $declared); @@ -98,10 +95,39 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive = return; } if (!$adaptive) { - $declared = array_merge(get_declared_classes(), get_declared_interfaces()); - if (function_exists('get_declared_traits')) { - $declared = array_merge($declared, get_declared_traits()); - } + $declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits()); + } + + $files = self::inline($classes, $cache, $declared); + + if ($autoReload) { + // save the resources + self::writeCacheFile($metadata, serialize(array(array_values($files), $classes))); + } + } + + /** + * Generates a file where classes and their parents are inlined. + * + * @param array $classes An array of classes to load + * @param string $cache The file where classes are inlined + * @param array $excluded An array of classes that won't be inlined + * + * @return array The source map of inlined classes, with classes as keys and files as values + * + * @throws \RuntimeException When class can't be loaded + */ + public static function inline($classes, $cache, array $excluded) + { + $declared = array(); + foreach (self::getOrderedClasses($excluded) as $class) { + $declared[$class->getName()] = true; + } + + // cache the core classes + $cacheDir = dirname($cache); + if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) { + throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir)); } $spacesRegex = '(?:\s*+(?:(?:\#|//)[^\n]*+\n|/\*(?:(?getName(), $declared)) { + if (isset($declared[$class->getName()])) { continue; } + $declared[$class->getName()] = true; - $files[] = $file = $class->getFileName(); + $files[$class->getName()] = $file = $class->getFileName(); $c = file_get_contents($file); if (preg_match($dontInlineRegex, $c)) { @@ -158,10 +185,7 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive = } self::writeCacheFile($cache, '= 50400) { - define('SYMFONY_TRAIT', T_TRAIT); - } else { - define('SYMFONY_TRAIT', 0); - } -} - /** * ClassMapGenerator. * @@ -122,7 +114,7 @@ private static function findClasses($path) break; case T_CLASS: case T_INTERFACE: - case SYMFONY_TRAIT: + case T_TRAIT: // Skip usage of ::class constant $isClassConstant = false; for ($j = $i - 1; $j > 0; --$j) { diff --git a/vendor/symfony/class-loader/DebugClassLoader.php b/vendor/symfony/class-loader/DebugClassLoader.php deleted file mode 100644 index 783cf676..00000000 --- a/vendor/symfony/class-loader/DebugClassLoader.php +++ /dev/null @@ -1,120 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\ClassLoader; - -@trigger_error('The '.__NAMESPACE__.'\DebugClassLoader class is deprecated since version 2.4 and will be removed in 3.0. Use the Symfony\Component\Debug\DebugClassLoader class instead.', E_USER_DEPRECATED); - -/** - * Autoloader checking if the class is really defined in the file found. - * - * The DebugClassLoader will wrap all registered autoloaders providing a - * findFile method and will throw an exception if a file is found but does - * not declare the class. - * - * @author Fabien Potencier - * @author Christophe Coevoet - * - * @deprecated since version 2.4, to be removed in 3.0. - * Use {@link \Symfony\Component\Debug\DebugClassLoader} instead. - */ -class DebugClassLoader -{ - private $classFinder; - - /** - * Constructor. - * - * @param object $classFinder - */ - public function __construct($classFinder) - { - $this->classFinder = $classFinder; - } - - /** - * Gets the wrapped class loader. - * - * @return object a class loader instance - */ - public function getClassLoader() - { - return $this->classFinder; - } - - /** - * Replaces all autoloaders implementing a findFile method by a DebugClassLoader wrapper. - */ - public static function enable() - { - if (!is_array($functions = spl_autoload_functions())) { - return; - } - - foreach ($functions as $function) { - spl_autoload_unregister($function); - } - - foreach ($functions as $function) { - if (is_array($function) && !$function[0] instanceof self && method_exists($function[0], 'findFile')) { - $function = array(new static($function[0]), 'loadClass'); - } - - spl_autoload_register($function); - } - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - } - - /** - * Finds a file by class name. - * - * @param string $class A class name to resolve to file - * - * @return string|null - */ - public function findFile($class) - { - return $this->classFinder->findFile($class) ?: null; - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * - * @return bool|null True, if loaded - * - * @throws \RuntimeException - */ - public function loadClass($class) - { - if ($file = $this->classFinder->findFile($class)) { - require $file; - - if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { - if (false !== strpos($class, '/')) { - throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class)); - } - - throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); - } - - return true; - } - } -} diff --git a/vendor/symfony/class-loader/DebugUniversalClassLoader.php b/vendor/symfony/class-loader/DebugUniversalClassLoader.php deleted file mode 100644 index 807bcd15..00000000 --- a/vendor/symfony/class-loader/DebugUniversalClassLoader.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\ClassLoader; - -@trigger_error('The '.__NAMESPACE__.'\DebugUniversalClassLoader class is deprecated since version 2.4 and will be removed in 3.0. Use the Symfony\Component\Debug\DebugClassLoader class instead.', E_USER_DEPRECATED); - -/** - * Checks that the class is actually declared in the included file. - * - * @author Fabien Potencier - * - * @deprecated since version 2.4, to be removed in 3.0. - * Use the {@link \Symfony\Component\Debug\DebugClassLoader} class instead. - */ -class DebugUniversalClassLoader extends UniversalClassLoader -{ - /** - * Replaces all regular UniversalClassLoader instances by a DebugUniversalClassLoader ones. - */ - public static function enable() - { - if (!is_array($functions = spl_autoload_functions())) { - return; - } - - foreach ($functions as $function) { - spl_autoload_unregister($function); - } - - foreach ($functions as $function) { - if (is_array($function) && $function[0] instanceof UniversalClassLoader) { - $loader = new static(); - $loader->registerNamespaceFallbacks($function[0]->getNamespaceFallbacks()); - $loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks()); - $loader->registerNamespaces($function[0]->getNamespaces()); - $loader->registerPrefixes($function[0]->getPrefixes()); - $loader->useIncludePath($function[0]->getUseIncludePath()); - - $function[0] = $loader; - } - - spl_autoload_register($function); - } - } - - /** - * {@inheritdoc} - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - require $file; - - if (!class_exists($class, false) && !interface_exists($class, false) && (!function_exists('trait_exists') || !trait_exists($class, false))) { - throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file)); - } - } - } -} diff --git a/vendor/symfony/class-loader/Psr4ClassLoader.php b/vendor/symfony/class-loader/Psr4ClassLoader.php index a00cf7b8..84647b75 100644 --- a/vendor/symfony/class-loader/Psr4ClassLoader.php +++ b/vendor/symfony/class-loader/Psr4ClassLoader.php @@ -45,8 +45,7 @@ public function findFile($class) { $class = ltrim($class, '\\'); - foreach ($this->prefixes as $current) { - list($currentPrefix, $currentBaseDir) = $current; + foreach ($this->prefixes as list($currentPrefix, $currentBaseDir)) { if (0 === strpos($class, $currentPrefix)) { $classWithoutPrefix = substr($class, strlen($currentPrefix)); $file = $currentBaseDir.str_replace('\\', DIRECTORY_SEPARATOR, $classWithoutPrefix).'.php'; diff --git a/vendor/symfony/class-loader/UniversalClassLoader.php b/vendor/symfony/class-loader/UniversalClassLoader.php deleted file mode 100644 index 961c7518..00000000 --- a/vendor/symfony/class-loader/UniversalClassLoader.php +++ /dev/null @@ -1,307 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\ClassLoader; - -@trigger_error('The '.__NAMESPACE__.'\UniversalClassLoader class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\ClassLoader\ClassLoader class instead.', E_USER_DEPRECATED); - -/** - * UniversalClassLoader implements a "universal" autoloader for PHP 5.3. - * - * It is able to load classes that use either: - * - * * The technical interoperability standards for PHP 5.3 namespaces and - * class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md); - * - * * The PEAR naming convention for classes (http://pear.php.net/). - * - * Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be - * looked for in a list of locations to ease the vendoring of a sub-set of - * classes for large projects. - * - * Example usage: - * - * $loader = new UniversalClassLoader(); - * - * // register classes with namespaces - * $loader->registerNamespaces(array( - * 'Symfony\Component' => __DIR__.'/component', - * 'Symfony' => __DIR__.'/framework', - * 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'), - * )); - * - * // register a library using the PEAR naming convention - * $loader->registerPrefixes(array( - * 'Swift_' => __DIR__.'/Swift', - * )); - * - * - * // to enable searching the include path (e.g. for PEAR packages) - * $loader->useIncludePath(true); - * - * // activate the autoloader - * $loader->register(); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * @author Fabien Potencier - * - * @deprecated since version 2.4, to be removed in 3.0. - * Use the {@link ClassLoader} class instead. - */ -class UniversalClassLoader -{ - private $namespaces = array(); - private $prefixes = array(); - private $namespaceFallbacks = array(); - private $prefixFallbacks = array(); - private $useIncludePath = false; - - /** - * Turns on searching the include for class files. Allows easy loading - * of installed PEAR packages. - * - * @param bool $useIncludePath - */ - public function useIncludePath($useIncludePath) - { - $this->useIncludePath = (bool) $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Gets the configured namespaces. - * - * @return array A hash with namespaces as keys and directories as values - */ - public function getNamespaces() - { - return $this->namespaces; - } - - /** - * Gets the configured class prefixes. - * - * @return array A hash with class prefixes as keys and directories as values - */ - public function getPrefixes() - { - return $this->prefixes; - } - - /** - * Gets the directory(ies) to use as a fallback for namespaces. - * - * @return array An array of directories - */ - public function getNamespaceFallbacks() - { - return $this->namespaceFallbacks; - } - - /** - * Gets the directory(ies) to use as a fallback for class prefixes. - * - * @return array An array of directories - */ - public function getPrefixFallbacks() - { - return $this->prefixFallbacks; - } - - /** - * Registers the directory to use as a fallback for namespaces. - * - * @param array $dirs An array of directories - */ - public function registerNamespaceFallbacks(array $dirs) - { - $this->namespaceFallbacks = $dirs; - } - - /** - * Registers a directory to use as a fallback for namespaces. - * - * @param string $dir A directory - */ - public function registerNamespaceFallback($dir) - { - $this->namespaceFallbacks[] = $dir; - } - - /** - * Registers directories to use as a fallback for class prefixes. - * - * @param array $dirs An array of directories - */ - public function registerPrefixFallbacks(array $dirs) - { - $this->prefixFallbacks = $dirs; - } - - /** - * Registers a directory to use as a fallback for class prefixes. - * - * @param string $dir A directory - */ - public function registerPrefixFallback($dir) - { - $this->prefixFallbacks[] = $dir; - } - - /** - * Registers an array of namespaces. - * - * @param array $namespaces An array of namespaces (namespaces as keys and locations as values) - */ - public function registerNamespaces(array $namespaces) - { - foreach ($namespaces as $namespace => $locations) { - $this->namespaces[$namespace] = (array) $locations; - } - } - - /** - * Registers a namespace. - * - * @param string $namespace The namespace - * @param array|string $paths The location(s) of the namespace - */ - public function registerNamespace($namespace, $paths) - { - $this->namespaces[$namespace] = (array) $paths; - } - - /** - * Registers an array of classes using the PEAR naming convention. - * - * @param array $classes An array of classes (prefixes as keys and locations as values) - */ - public function registerPrefixes(array $classes) - { - foreach ($classes as $prefix => $locations) { - $this->prefixes[$prefix] = (array) $locations; - } - } - - /** - * Registers a set of classes using the PEAR naming convention. - * - * @param string $prefix The classes prefix - * @param array|string $paths The location(s) of the classes - */ - public function registerPrefix($prefix, $paths) - { - $this->prefixes[$prefix] = (array) $paths; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * - * @return bool|null True, if loaded - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - require $file; - - return true; - } - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|null The path, if found - */ - public function findFile($class) - { - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $namespace = substr($class, 0, $pos); - $className = substr($class, $pos + 1); - $normalizedClass = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; - foreach ($this->namespaces as $ns => $dirs) { - if (0 !== strpos($namespace, $ns)) { - continue; - } - - foreach ($dirs as $dir) { - $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; - if (is_file($file)) { - return $file; - } - } - } - - foreach ($this->namespaceFallbacks as $dir) { - $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; - if (is_file($file)) { - return $file; - } - } - } else { - // PEAR-like class name - $normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; - foreach ($this->prefixes as $prefix => $dirs) { - if (0 !== strpos($class, $prefix)) { - continue; - } - - foreach ($dirs as $dir) { - $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; - if (is_file($file)) { - return $file; - } - } - } - - foreach ($this->prefixFallbacks as $dir) { - $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; - if (is_file($file)) { - return $file; - } - } - } - - if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) { - return $file; - } - } -} diff --git a/vendor/symfony/class-loader/WinCacheClassLoader.php b/vendor/symfony/class-loader/WinCacheClassLoader.php index 3e077450..b95a1d79 100644 --- a/vendor/symfony/class-loader/WinCacheClassLoader.php +++ b/vendor/symfony/class-loader/WinCacheClassLoader.php @@ -16,12 +16,10 @@ * * It expects an object implementing a findFile method to find the file. This * allow using it as a wrapper around the other loaders of the component (the - * ClassLoader and the UniversalClassLoader for instance) but also around any - * other autoloaders following this convention (the Composer one for instance). + * ClassLoader for instance) but also around any other autoloaders following + * this convention (the Composer one for instance). * * // with a Symfony autoloader - * use Symfony\Component\ClassLoader\ClassLoader; - * * $loader = new ClassLoader(); * $loader->addPrefix('Symfony\Component', __DIR__.'/component'); * $loader->addPrefix('Symfony', __DIR__.'/framework'); diff --git a/vendor/symfony/class-loader/XcacheClassLoader.php b/vendor/symfony/class-loader/XcacheClassLoader.php index aa4dc9d0..bf309a69 100644 --- a/vendor/symfony/class-loader/XcacheClassLoader.php +++ b/vendor/symfony/class-loader/XcacheClassLoader.php @@ -16,12 +16,10 @@ * * It expects an object implementing a findFile method to find the file. This * allows using it as a wrapper around the other loaders of the component (the - * ClassLoader and the UniversalClassLoader for instance) but also around any - * other autoloaders following this convention (the Composer one for instance). + * ClassLoader for instance) but also around any other autoloaders following + * this convention (the Composer one for instance). * * // with a Symfony autoloader - * use Symfony\Component\ClassLoader\ClassLoader; - * * $loader = new ClassLoader(); * $loader->addPrefix('Symfony\Component', __DIR__.'/component'); * $loader->addPrefix('Symfony', __DIR__.'/framework'); diff --git a/vendor/symfony/class-loader/composer.json b/vendor/symfony/class-loader/composer.json index 7acbeafd..634c647c 100644 --- a/vendor/symfony/class-loader/composer.json +++ b/vendor/symfony/class-loader/composer.json @@ -17,11 +17,14 @@ ], "minimum-stability": "dev", "require": { - "php": ">=5.3.9", - "symfony/polyfill-apcu": "~1.1" + "php": ">=5.5.9" }, "require-dev": { - "symfony/finder": "~2.0,>=2.0.5|~3.0.0" + "symfony/finder": "~2.8|~3.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" }, "autoload": { "psr-4": { "Symfony\\Component\\ClassLoader\\": "" }, @@ -31,7 +34,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/class-loader/phpunit.xml.dist b/vendor/symfony/class-loader/phpunit.xml.dist index 4856db5b..5158b22f 100644 --- a/vendor/symfony/class-loader/phpunit.xml.dist +++ b/vendor/symfony/class-loader/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/console/Application.php b/vendor/symfony/console/Application.php index bd340d30..6f87532a 100644 --- a/vendor/symfony/console/Application.php +++ b/vendor/symfony/console/Application.php @@ -11,20 +11,19 @@ namespace Symfony\Component\Console; -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; use Symfony\Component\Console\Exception\ExceptionInterface; +use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\DebugFormatterHelper; use Symfony\Component\Console\Helper\ProcessHelper; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\StreamableInputInterface; use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputAwareInterface; -use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\ConsoleOutputInterface; @@ -33,9 +32,6 @@ use Symfony\Component\Console\Command\ListCommand; use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\FormatterHelper; -use Symfony\Component\Console\Helper\DialogHelper; -use Symfony\Component\Console\Helper\ProgressHelper; -use Symfony\Component\Console\Helper\TableHelper; use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\Console\Event\ConsoleTerminateEvent; @@ -71,12 +67,11 @@ class Application private $definition; private $helperSet; private $dispatcher; - private $terminalDimensions; + private $terminal; private $defaultCommand; + private $singleCommand; /** - * Constructor. - * * @param string $name The name of the application * @param string $version The version of the application */ @@ -84,6 +79,7 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') { $this->name = $name; $this->version = $version; + $this->terminal = new Terminal(); $this->defaultCommand = 'list'; $this->helperSet = $this->getDefaultHelperSet(); $this->definition = $this->getDefaultInputDefinition(); @@ -105,9 +101,14 @@ public function setDispatcher(EventDispatcherInterface $dispatcher) * @param OutputInterface $output An Output instance * * @return int 0 if everything went fine, or an error code + * + * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}. */ public function run(InputInterface $input = null, OutputInterface $output = null) { + putenv('LINES='.$this->terminal->getHeight()); + putenv('COLUMNS='.$this->terminal->getWidth()); + if (null === $input) { $input = new ArgvInput(); } @@ -119,10 +120,17 @@ public function run(InputInterface $input = null, OutputInterface $output = null $this->configureIO($input, $output); try { + $e = null; $exitCode = $this->doRun($input, $output); - } catch (\Exception $e) { + } catch (\Exception $x) { + $e = $x; + } catch (\Throwable $x) { + $e = new FatalThrowableError($x); + } + + if (null !== $e) { if (!$this->catchExceptions) { - throw $e; + throw $x; } if ($output instanceof ConsoleOutputInterface) { @@ -163,17 +171,17 @@ public function run(InputInterface $input = null, OutputInterface $output = null */ public function doRun(InputInterface $input, OutputInterface $output) { - if (true === $input->hasParameterOption(array('--version', '-V'))) { + if (true === $input->hasParameterOption(array('--version', '-V'), true)) { $output->writeln($this->getLongVersion()); return 0; } $name = $this->getCommandName($input); - if (true === $input->hasParameterOption(array('--help', '-h'))) { + if (true === $input->hasParameterOption(array('--help', '-h'), true)) { if (!$name) { $name = 'help'; - $input = new ArrayInput(array('command' => 'help')); + $input = new ArrayInput(array('command_name' => $this->defaultCommand)); } else { $this->wantHelps = true; } @@ -184,6 +192,7 @@ public function doRun(InputInterface $input, OutputInterface $output) $input = new ArrayInput(array('command' => $this->defaultCommand)); } + $this->runningCommand = null; // the command name MUST be the first element of the input $command = $this->find($name); @@ -231,6 +240,13 @@ public function setDefinition(InputDefinition $definition) */ public function getDefinition() { + if ($this->singleCommand) { + $inputDefinition = $this->definition; + $inputDefinition->setArguments(); + + return $inputDefinition; + } + return $this->definition; } @@ -244,6 +260,16 @@ public function getHelp() return $this->getLongVersion(); } + /** + * Gets whether to catch exceptions or not during commands execution. + * + * @return bool Whether to catch exceptions or not during commands execution + */ + public function areExceptionsCaught() + { + return $this->catchExceptions; + } + /** * Sets whether to catch exceptions or not during commands execution. * @@ -254,6 +280,16 @@ public function setCatchExceptions($boolean) $this->catchExceptions = (bool) $boolean; } + /** + * Gets whether to automatically exit after a command execution or not. + * + * @return bool Whether to automatically exit after a command execution or not + */ + public function isAutoExitEnabled() + { + return $this->autoExit; + } + /** * Sets whether to automatically exit after a command execution or not. * @@ -313,13 +349,13 @@ public function getLongVersion() { if ('UNKNOWN' !== $this->getName()) { if ('UNKNOWN' !== $this->getVersion()) { - return sprintf('%s version %s', $this->getName(), $this->getVersion()); + return sprintf('%s %s', $this->getName(), $this->getVersion()); } - return sprintf('%s', $this->getName()); + return $this->getName(); } - return 'Console Tool'; + return 'Console Tool'; } /** @@ -585,79 +621,35 @@ public static function getAbbreviations($names) return $abbrevs; } - /** - * Returns a text representation of the Application. - * - * @param string $namespace An optional namespace name - * @param bool $raw Whether to return raw command list - * - * @return string A string representing the Application - * - * @deprecated since version 2.3, to be removed in 3.0. - */ - public function asText($namespace = null, $raw = false) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED); - - $descriptor = new TextDescriptor(); - $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw); - $descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true)); - - return $output->fetch(); - } - - /** - * Returns an XML representation of the Application. - * - * @param string $namespace An optional namespace name - * @param bool $asDom Whether to return a DOM or an XML string - * - * @return string|\DOMDocument An XML string representing the Application - * - * @deprecated since version 2.3, to be removed in 3.0. - */ - public function asXml($namespace = null, $asDom = false) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED); - - $descriptor = new XmlDescriptor(); - - if ($asDom) { - return $descriptor->getApplicationDocument($this, $namespace); - } - - $output = new BufferedOutput(); - $descriptor->describe($output, $this, array('namespace' => $namespace)); - - return $output->fetch(); - } - /** * Renders a caught exception. * * @param \Exception $e An exception instance * @param OutputInterface $output An OutputInterface instance */ - public function renderException($e, $output) + public function renderException(\Exception $e, OutputInterface $output) { $output->writeln('', OutputInterface::VERBOSITY_QUIET); do { - $title = sprintf(' [%s] ', get_class($e)); + $title = sprintf( + ' [%s%s] ', + get_class($e), + $output->isVerbose() && 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : '' + ); $len = $this->stringWidth($title); - $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX; + $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : PHP_INT_MAX; // HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327 if (defined('HHVM_VERSION') && $width > 1 << 31) { $width = 1 << 31; } - $formatter = $output->getFormatter(); $lines = array(); foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { foreach ($this->splitStringByWidth($line, $width - 4) as $line) { // pre-format lines to get the right string length - $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4; + $lineLength = $this->stringWidth($line) + 4; $lines[] = array($line, $lineLength); $len = max($lineLength, $len); @@ -665,15 +657,15 @@ public function renderException($e, $output) } $messages = array(); - $messages[] = $emptyLine = $formatter->format(sprintf('%s', str_repeat(' ', $len))); - $messages[] = $formatter->format(sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title))))); + $messages[] = $emptyLine = sprintf('%s', str_repeat(' ', $len)); + $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))); foreach ($lines as $line) { - $messages[] = $formatter->format(sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1]))); + $messages[] = sprintf(' %s %s', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1])); } $messages[] = $emptyLine; $messages[] = ''; - $output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET); + $output->writeln($messages, OutputInterface::VERBOSITY_QUIET); if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { $output->writeln('Exception trace:', OutputInterface::VERBOSITY_QUIET); @@ -711,60 +703,42 @@ public function renderException($e, $output) * Tries to figure out the terminal width in which this application runs. * * @return int|null + * + * @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead. */ protected function getTerminalWidth() { - $dimensions = $this->getTerminalDimensions(); + @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); - return $dimensions[0]; + return $this->terminal->getWidth(); } /** * Tries to figure out the terminal height in which this application runs. * * @return int|null + * + * @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead. */ protected function getTerminalHeight() { - $dimensions = $this->getTerminalDimensions(); + @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); - return $dimensions[1]; + return $this->terminal->getHeight(); } /** * Tries to figure out the terminal dimensions based on the current environment. * * @return array Array containing width and height + * + * @deprecated since version 3.2, to be removed in 4.0. Create a Terminal instance instead. */ public function getTerminalDimensions() { - if ($this->terminalDimensions) { - return $this->terminalDimensions; - } - - if ('\\' === DIRECTORY_SEPARATOR) { - // extract [w, H] from "wxh (WxH)" - if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) { - return array((int) $matches[1], (int) $matches[2]); - } - // extract [w, h] from "wxh" - if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) { - return array((int) $matches[1], (int) $matches[2]); - } - } + @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Create a Terminal instance instead.', __METHOD__), E_USER_DEPRECATED); - if ($sttyString = $this->getSttyColumns()) { - // extract [w, h] from "rows h; columns w;" - if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { - return array((int) $matches[2], (int) $matches[1]); - } - // extract [w, h] from "; h rows; w columns" - if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { - return array((int) $matches[2], (int) $matches[1]); - } - } - - return array(null, null); + return array($this->terminal->getWidth(), $this->terminal->getHeight()); } /** @@ -776,10 +750,15 @@ public function getTerminalDimensions() * @param int $height The height * * @return $this + * + * @deprecated since version 3.2, to be removed in 4.0. Set the COLUMNS and LINES env vars instead. */ public function setTerminalDimensions($width, $height) { - $this->terminalDimensions = array($width, $height); + @trigger_error(sprintf('%s is deprecated as of 3.2 and will be removed in 4.0. Set the COLUMNS and LINES env vars instead.', __METHOD__), E_USER_DEPRECATED); + + putenv('COLUMNS='.$width); + putenv('LINES='.$height); return $this; } @@ -792,30 +771,41 @@ public function setTerminalDimensions($width, $height) */ protected function configureIO(InputInterface $input, OutputInterface $output) { - if (true === $input->hasParameterOption(array('--ansi'))) { + if (true === $input->hasParameterOption(array('--ansi'), true)) { $output->setDecorated(true); - } elseif (true === $input->hasParameterOption(array('--no-ansi'))) { + } elseif (true === $input->hasParameterOption(array('--no-ansi'), true)) { $output->setDecorated(false); } - if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) { + if (true === $input->hasParameterOption(array('--no-interaction', '-n'), true)) { $input->setInteractive(false); - } elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) { - $inputStream = $this->getHelperSet()->get('question')->getInputStream(); + } elseif (function_exists('posix_isatty')) { + $inputStream = null; + + if ($input instanceof StreamableInputInterface) { + $inputStream = $input->getStream(); + } + + // This check ensures that calling QuestionHelper::setInputStream() works + // To be removed in 4.0 (in the same time as QuestionHelper::setInputStream) + if (!$inputStream && $this->getHelperSet()->has('question')) { + $inputStream = $this->getHelperSet()->get('question')->getInputStream(false); + } + if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) { $input->setInteractive(false); } } - if (true === $input->hasParameterOption(array('--quiet', '-q'))) { + if (true === $input->hasParameterOption(array('--quiet', '-q'), true)) { $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); $input->setInteractive(false); } else { - if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) { + if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || $input->getParameterOption('--verbose', false, true) === 3) { $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) { + } elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || $input->getParameterOption('--verbose', false, true) === 2) { $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); - } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) { + } elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) { $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); } } @@ -842,13 +832,7 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI } if (null === $this->dispatcher) { - try { - return $command->run($input, $output); - } catch (\Exception $e) { - throw $e; - } catch (\Throwable $e) { - throw new FatalThrowableError($e); - } + return $command->run($input, $output); } // bind before the console.command event, so the listeners have access to input options/arguments @@ -860,37 +844,37 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI } $event = new ConsoleCommandEvent($command, $input, $output); - $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); + $e = null; + + try { + $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); - if ($event->commandShouldRun()) { - try { - $e = null; + if ($event->commandShouldRun()) { $exitCode = $command->run($input, $output); - } catch (\Exception $x) { - $e = $x; - } catch (\Throwable $x) { - $e = new FatalThrowableError($x); + } else { + $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; } - if (null !== $e) { - $event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode()); - $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); - - if ($e !== $event->getException()) { - $x = $e = $event->getException(); - } - - $event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode()); - $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + if (null !== $e) { + $x = $e instanceof \Exception ? $e : new FatalThrowableError($e); + $event = new ConsoleExceptionEvent($command, $input, $output, $x, $x->getCode()); + $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); - throw $x; + if ($x !== $event->getException()) { + $e = $event->getException(); } - } else { - $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; + $exitCode = $e->getCode(); } $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); + if (null !== $e) { + throw $e; + } + return $event->getExitCode(); } @@ -903,7 +887,7 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI */ protected function getCommandName(InputInterface $input) { - return $input->getFirstArgument(); + return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument(); } /** @@ -945,63 +929,12 @@ protected function getDefaultHelperSet() { return new HelperSet(array( new FormatterHelper(), - new DialogHelper(false), - new ProgressHelper(false), - new TableHelper(false), new DebugFormatterHelper(), new ProcessHelper(), new QuestionHelper(), )); } - /** - * Runs and parses stty -a if it's available, suppressing any error output. - * - * @return string - */ - private function getSttyColumns() - { - if (!function_exists('proc_open')) { - return; - } - - $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')); - $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true)); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - return $info; - } - } - - /** - * Runs and parses mode CON if it's available, suppressing any error output. - * - * @return string|null x or null if it could not be parsed - */ - private function getConsoleMode() - { - if (!function_exists('proc_open')) { - return; - } - - $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')); - $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true)); - if (is_resource($process)) { - $info = stream_get_contents($pipes[1]); - fclose($pipes[1]); - fclose($pipes[2]); - proc_close($process); - - if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { - return $matches[2].'x'.$matches[1]; - } - } - } - /** * Returns abbreviated suggestions in string format. * @@ -1086,11 +1019,23 @@ private function findAlternatives($name, $collection) /** * Sets the default Command name. * - * @param string $commandName The Command name + * @param string $commandName The Command name + * @param bool $isSingleCommand Set to true if there is only one command in this application + * + * @return self */ - public function setDefaultCommand($commandName) + public function setDefaultCommand($commandName, $isSingleCommand = false) { $this->defaultCommand = $commandName; + + if ($isSingleCommand) { + // Ensure the command exist + $this->find($commandName); + + $this->singleCommand = true; + } + + return $this; } private function stringWidth($string) diff --git a/vendor/symfony/console/CHANGELOG.md b/vendor/symfony/console/CHANGELOG.md index 8021068e..a97a4a7a 100644 --- a/vendor/symfony/console/CHANGELOG.md +++ b/vendor/symfony/console/CHANGELOG.md @@ -1,6 +1,20 @@ CHANGELOG ========= +3.2.0 +------ + +* added `setInputs()` method to CommandTester for ease testing of commands expecting inputs +* added `setStream()` and `getStream()` methods to Input (implement StreamableInputInterface) +* added StreamableInputInterface +* added LockableTrait + +3.1.0 +----- + + * added truncate method to FormatterHelper + * added setColumnWidth(s) method to Table + 2.8.3 ----- diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php index 39a1f6e8..23596775 100644 --- a/vendor/symfony/console/Command/Command.php +++ b/vendor/symfony/console/Command/Command.php @@ -11,14 +11,11 @@ namespace Symfony\Component\Console\Command; -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; use Symfony\Component\Console\Exception\ExceptionInterface; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Application; use Symfony\Component\Console\Helper\HelperSet; @@ -37,6 +34,7 @@ class Command private $processTitle; private $aliases = array(); private $definition; + private $hidden = false; private $help; private $description; private $ignoreValidationErrors = false; @@ -205,6 +203,8 @@ protected function initialize(InputInterface $input, OutputInterface $output) * * @return int The command exit code * + * @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}. + * * @see setCode() * @see execute() */ @@ -281,13 +281,9 @@ public function run(InputInterface $input, OutputInterface $output) * * @see execute() */ - public function setCode($code) + public function setCode(callable $code) { - if (!is_callable($code)) { - throw new InvalidArgumentException('Invalid callable provided to Command::setCode.'); - } - - if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) { + if ($code instanceof \Closure) { $r = new \ReflectionFunction($code); if (null === $r->getClosureThis()) { if (PHP_VERSION_ID < 70000) { @@ -365,7 +361,7 @@ public function getDefinition() } /** - * Gets the InputDefinition to be used to create XML and Text representations of this Command. + * Gets the InputDefinition to be used to create representations of this Command. * * Can be overridden to provide the original command representation when it would otherwise * be changed by merging with the application InputDefinition. @@ -466,6 +462,26 @@ public function getName() return $this->name; } + /** + * @param bool $hidden Whether or not the command should be hidden from the list of commands + * + * @return Command The current instance + */ + public function setHidden($hidden) + { + $this->hidden = (bool) $hidden; + + return $this; + } + + /** + * @return bool Whether the command should be publicly shown or not. + */ + public function isHidden() + { + return $this->hidden; + } + /** * Sets the description for the command. * @@ -635,49 +651,6 @@ public function getHelper($name) return $this->helperSet->get($name); } - /** - * Returns a text representation of the command. - * - * @return string A string representing the command - * - * @deprecated since version 2.3, to be removed in 3.0. - */ - public function asText() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED); - - $descriptor = new TextDescriptor(); - $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); - $descriptor->describe($output, $this, array('raw_output' => true)); - - return $output->fetch(); - } - - /** - * Returns an XML representation of the command. - * - * @param bool $asDom Whether to return a DOM or an XML string - * - * @return string|\DOMDocument An XML string representing the command - * - * @deprecated since version 2.3, to be removed in 3.0. - */ - public function asXml($asDom = false) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED); - - $descriptor = new XmlDescriptor(); - - if ($asDom) { - return $descriptor->getCommandDocument($this); - } - - $output = new BufferedOutput(); - $descriptor->describe($output, $this); - - return $output->fetch(); - } - /** * Validates a command name. * diff --git a/vendor/symfony/console/Command/HelpCommand.php b/vendor/symfony/console/Command/HelpCommand.php index c0e7b388..b8fd911a 100644 --- a/vendor/symfony/console/Command/HelpCommand.php +++ b/vendor/symfony/console/Command/HelpCommand.php @@ -37,7 +37,6 @@ protected function configure() ->setName('help') ->setDefinition(array( new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), - new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), )) @@ -76,12 +75,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->command = $this->getApplication()->find($input->getArgument('command_name')); } - if ($input->getOption('xml')) { - @trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED); - - $input->setOption('format', 'xml'); - } - $helper = new DescriptorHelper(); $helper->describe($output, $this->command, array( 'format' => $input->getOption('format'), diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php index 5e1b926a..179ddea5 100644 --- a/vendor/symfony/console/Command/ListCommand.php +++ b/vendor/symfony/console/Command/ListCommand.php @@ -68,12 +68,6 @@ public function getNativeDefinition() */ protected function execute(InputInterface $input, OutputInterface $output) { - if ($input->getOption('xml')) { - @trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED); - - $input->setOption('format', 'xml'); - } - $helper = new DescriptorHelper(); $helper->describe($output, $this->getApplication(), array( 'format' => $input->getOption('format'), @@ -89,7 +83,6 @@ private function createDefinition() { return new InputDefinition(array( new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), - new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), )); diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php new file mode 100644 index 00000000..95597705 --- /dev/null +++ b/vendor/symfony/console/Command/LockableTrait.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Command; + +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Filesystem\LockHandler; + +/** + * Basic lock feature for commands. + * + * @author Geoffrey Brier + */ +trait LockableTrait +{ + private $lockHandler; + + /** + * Locks a command. + * + * @return bool + */ + private function lock($name = null, $blocking = false) + { + if (!class_exists(LockHandler::class)) { + throw new RuntimeException('To enable the locking feature you must install the symfony/filesystem component.'); + } + + if (null !== $this->lockHandler) { + throw new LogicException('A lock is already in place.'); + } + + $this->lockHandler = new LockHandler($name ?: $this->getName()); + + if (!$this->lockHandler->lock($blocking)) { + $this->lockHandler = null; + + return false; + } + + return true; + } + + /** + * Releases the command lock if there is one. + */ + private function release() + { + if ($this->lockHandler) { + $this->lockHandler->release(); + $this->lockHandler = null; + } + } +} diff --git a/vendor/symfony/console/ConsoleEvents.php b/vendor/symfony/console/ConsoleEvents.php index 1ed41b7d..b3571e9a 100644 --- a/vendor/symfony/console/ConsoleEvents.php +++ b/vendor/symfony/console/ConsoleEvents.php @@ -23,10 +23,7 @@ final class ConsoleEvents * executed by the console. It also allows you to modify the command, input and output * before they are handled to the command. * - * The event listener method receives a Symfony\Component\Console\Event\ConsoleCommandEvent - * instance. - * - * @Event + * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent") * * @var string */ @@ -36,10 +33,7 @@ final class ConsoleEvents * The TERMINATE event allows you to attach listeners after a command is * executed by the console. * - * The event listener method receives a Symfony\Component\Console\Event\ConsoleTerminateEvent - * instance. - * - * @Event + * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent") * * @var string */ @@ -49,11 +43,9 @@ final class ConsoleEvents * The EXCEPTION event occurs when an uncaught exception appears. * * This event allows you to deal with the exception or - * to modify the thrown exception. The event listener method receives - * a Symfony\Component\Console\Event\ConsoleExceptionEvent - * instance. + * to modify the thrown exception. * - * @Event + * @Event("Symfony\Component\Console\Event\ConsoleExceptionEvent") * * @var string */ diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php index 89961b9c..4c4a267f 100644 --- a/vendor/symfony/console/Descriptor/ApplicationDescription.php +++ b/vendor/symfony/console/Descriptor/ApplicationDescription.php @@ -112,7 +112,7 @@ private function inspectApplication() /** @var Command $command */ foreach ($commands as $name => $command) { - if (!$command->getName()) { + if (!$command->getName() || $command->isHidden()) { continue; } diff --git a/vendor/symfony/console/Descriptor/Descriptor.php b/vendor/symfony/console/Descriptor/Descriptor.php index 43a7a0a1..50dd86ce 100644 --- a/vendor/symfony/console/Descriptor/Descriptor.php +++ b/vendor/symfony/console/Descriptor/Descriptor.php @@ -29,7 +29,7 @@ abstract class Descriptor implements DescriptorInterface /** * @var OutputInterface */ - private $output; + protected $output; /** * {@inheritdoc} diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php index b49b64d5..81710046 100644 --- a/vendor/symfony/console/Descriptor/TextDescriptor.php +++ b/vendor/symfony/console/Descriptor/TextDescriptor.php @@ -200,6 +200,8 @@ protected function describeApplication(Application $application, array $options } // add commands by namespace + $commands = $description->getCommands(); + foreach ($description->getNamespaces() as $namespace) { if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { $this->writeText("\n"); @@ -207,9 +209,13 @@ protected function describeApplication(Application $application, array $options } foreach ($namespace['commands'] as $name) { - $this->writeText("\n"); - $spacingWidth = $width - Helper::strlen($name); - $this->writeText(sprintf(' %s%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options); + if (isset($commands[$name])) { + $this->writeText("\n"); + $spacingWidth = $width - Helper::strlen($name); + $command = $commands[$name]; + $commandAliases = $this->getCommandAliasesText($command); + $this->writeText(sprintf(' %s%s%s', $name, str_repeat(' ', $spacingWidth), $commandAliases.$command->getDescription()), $options); + } } } @@ -228,6 +234,25 @@ private function writeText($content, array $options = array()) ); } + /** + * Formats command aliases to show them in the command description. + * + * @param Command $command + * + * @return string + */ + private function getCommandAliasesText($command) + { + $text = ''; + $aliases = $command->getAliases(); + + if ($aliases) { + $text = '['.implode('|', $aliases).'] '; + } + + return $text; + } + /** * Formats input option/argument default value. * @@ -247,10 +272,6 @@ private function formatDefaultValue($default) } } - if (PHP_VERSION_ID < 50400) { - return str_replace(array('\/', '\\\\'), array('/', '\\'), json_encode($default)); - } - return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); } @@ -283,7 +304,7 @@ private function calculateTotalWidthForOptions($options) $totalWidth = 0; foreach ($options as $option) { // "-" + shortcut + ", --" + name - $nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName()); + $nameLength = 1 + max(Helper::strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName()); if ($option->acceptValue()) { $valueLength = 1 + Helper::strlen($option->getName()); // = + value diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php index dee69675..d32f0915 100644 --- a/vendor/symfony/console/Formatter/OutputFormatter.php +++ b/vendor/symfony/console/Formatter/OutputFormatter.php @@ -81,9 +81,7 @@ public function __construct($decorated = false, array $styles = array()) } /** - * Sets the decorated flag. - * - * @param bool $decorated Whether to decorate the messages or not + * {@inheritdoc} */ public function setDecorated($decorated) { @@ -91,9 +89,7 @@ public function setDecorated($decorated) } /** - * Gets the decorated flag. - * - * @return bool true if the output will decorate messages, false otherwise + * {@inheritdoc} */ public function isDecorated() { @@ -101,10 +97,7 @@ public function isDecorated() } /** - * Sets a new style. - * - * @param string $name The style name - * @param OutputFormatterStyleInterface $style The style instance + * {@inheritdoc} */ public function setStyle($name, OutputFormatterStyleInterface $style) { @@ -112,11 +105,7 @@ public function setStyle($name, OutputFormatterStyleInterface $style) } /** - * Checks if output formatter has style with specified name. - * - * @param string $name - * - * @return bool + * {@inheritdoc} */ public function hasStyle($name) { @@ -124,13 +113,7 @@ public function hasStyle($name) } /** - * Gets style options from style with specified name. - * - * @param string $name - * - * @return OutputFormatterStyleInterface - * - * @throws InvalidArgumentException When style isn't defined + * {@inheritdoc} */ public function getStyle($name) { @@ -142,18 +125,14 @@ public function getStyle($name) } /** - * Formats a message according to the given styles. - * - * @param string $message The message to style - * - * @return string The styled message + * {@inheritdoc} */ public function format($message) { $message = (string) $message; $offset = 0; $output = ''; - $tagRegex = '[a-z][a-z0-9_=;-]*+'; + $tagRegex = '[a-z][a-z0-9,_=;-]*+'; preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE); foreach ($matches[0] as $i => $match) { $pos = $match[1]; @@ -216,7 +195,7 @@ private function createStyleFromString($string) return $this->styles[$string]; } - if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) { + if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, PREG_SET_ORDER)) { return false; } @@ -228,12 +207,20 @@ private function createStyleFromString($string) $style->setForeground($match[1]); } elseif ('bg' == $match[0]) { $style->setBackground($match[1]); - } else { - try { - $style->setOption($match[1]); - } catch (\InvalidArgumentException $e) { - return false; + } elseif ('options' === $match[0]) { + preg_match_all('([^,;]+)', $match[1], $options); + $options = array_shift($options); + foreach ($options as $option) { + try { + $style->setOption($option); + } catch (\InvalidArgumentException $e) { + @trigger_error(sprintf('Unknown style options are deprecated since version 3.2 and will be removed in 4.0. Exception "%s".', $e->getMessage()), E_USER_DEPRECATED); + + return false; + } } + } else { + return false; } } diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php index 5a52ba09..281e240c 100644 --- a/vendor/symfony/console/Formatter/OutputFormatterInterface.php +++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php @@ -55,6 +55,8 @@ public function hasStyle($name); * @param string $name * * @return OutputFormatterStyleInterface + * + * @throws \InvalidArgumentException When style isn't defined */ public function getStyle($name); diff --git a/vendor/symfony/console/Helper/DialogHelper.php b/vendor/symfony/console/Helper/DialogHelper.php deleted file mode 100644 index 9ce9f661..00000000 --- a/vendor/symfony/console/Helper/DialogHelper.php +++ /dev/null @@ -1,502 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; - -/** - * The Dialog class provides helpers to interact with the user. - * - * @author Fabien Potencier - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link \Symfony\Component\Console\Helper\QuestionHelper} instead. - */ -class DialogHelper extends InputAwareHelper -{ - private $inputStream; - private static $shell; - private static $stty; - - public function __construct($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED); - } - } - - /** - * Asks the user to select a value. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param array $choices List of choices to pick from - * @param bool|string $default The default answer if the user enters nothing - * @param bool|int $attempts Max number of times to ask before giving up (false by default, which means infinite) - * @param string $errorMessage Message which will be shown if invalid value from choice list would be picked - * @param bool $multiselect Select more than one value separated by comma - * - * @return int|string|array The selected value or values (the key of the choices array) - * - * @throws InvalidArgumentException - */ - public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false) - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $width = max(array_map('strlen', array_keys($choices))); - - $messages = (array) $question; - foreach ($choices as $key => $value) { - $messages[] = sprintf(" [%-{$width}s] %s", $key, $value); - } - - $output->writeln($messages); - - $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) { - // Collapse all spaces. - $selectedChoices = str_replace(' ', '', $picked); - - if ($multiselect) { - // Check for a separated comma values - if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) { - throw new InvalidArgumentException(sprintf($errorMessage, $picked)); - } - $selectedChoices = explode(',', $selectedChoices); - } else { - $selectedChoices = array($picked); - } - - $multiselectChoices = array(); - - foreach ($selectedChoices as $value) { - if (empty($choices[$value])) { - throw new InvalidArgumentException(sprintf($errorMessage, $value)); - } - $multiselectChoices[] = $value; - } - - if ($multiselect) { - return $multiselectChoices; - } - - return $picked; - }, $attempts, $default); - - return $result; - } - - /** - * Asks a question to the user. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param string $default The default answer if none is given by the user - * @param array $autocomplete List of values to autocomplete - * - * @return string The user answer - * - * @throws RuntimeException If there is no data to read in the input stream - */ - public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null) - { - if ($this->input && !$this->input->isInteractive()) { - return $default; - } - - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $output->write($question); - - $inputStream = $this->inputStream ?: STDIN; - - if (null === $autocomplete || !$this->hasSttyAvailable()) { - $ret = fgets($inputStream, 4096); - if (false === $ret) { - throw new RuntimeException('Aborted'); - } - $ret = trim($ret); - } else { - $ret = ''; - - $i = 0; - $ofs = -1; - $matches = $autocomplete; - $numMatches = count($matches); - - $sttyMode = shell_exec('stty -g'); - - // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) - shell_exec('stty -icanon -echo'); - - // Add highlighted text style - $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); - - // Read a keypress - while (!feof($inputStream)) { - $c = fread($inputStream, 1); - - // Backspace Character - if ("\177" === $c) { - if (0 === $numMatches && 0 !== $i) { - --$i; - // Move cursor backwards - $output->write("\033[1D"); - } - - if ($i === 0) { - $ofs = -1; - $matches = $autocomplete; - $numMatches = count($matches); - } else { - $numMatches = 0; - } - - // Pop the last character off the end of our string - $ret = substr($ret, 0, $i); - } elseif ("\033" === $c) { - // Did we read an escape sequence? - $c .= fread($inputStream, 2); - - // A = Up Arrow. B = Down Arrow - if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { - if ('A' === $c[2] && -1 === $ofs) { - $ofs = 0; - } - - if (0 === $numMatches) { - continue; - } - - $ofs += ('A' === $c[2]) ? -1 : 1; - $ofs = ($numMatches + $ofs) % $numMatches; - } - } elseif (ord($c) < 32) { - if ("\t" === $c || "\n" === $c) { - if ($numMatches > 0 && -1 !== $ofs) { - $ret = $matches[$ofs]; - // Echo out remaining chars for current match - $output->write(substr($ret, $i)); - $i = strlen($ret); - } - - if ("\n" === $c) { - $output->write($c); - break; - } - - $numMatches = 0; - } - - continue; - } else { - $output->write($c); - $ret .= $c; - ++$i; - - $numMatches = 0; - $ofs = 0; - - foreach ($autocomplete as $value) { - // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) - if (0 === strpos($value, $ret) && $i !== strlen($value)) { - $matches[$numMatches++] = $value; - } - } - } - - // Erase characters from cursor to end of line - $output->write("\033[K"); - - if ($numMatches > 0 && -1 !== $ofs) { - // Save cursor position - $output->write("\0337"); - // Write highlighted text - $output->write(''.substr($matches[$ofs], $i).''); - // Restore cursor position - $output->write("\0338"); - } - } - - // Reset stty so it behaves normally again - shell_exec(sprintf('stty %s', $sttyMode)); - } - - return strlen($ret) > 0 ? $ret : $default; - } - - /** - * Asks a confirmation to the user. - * - * The question will be asked until the user answers by nothing, yes, or no. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param bool $default The default answer if the user enters nothing - * - * @return bool true if the user has confirmed, false otherwise - */ - public function askConfirmation(OutputInterface $output, $question, $default = true) - { - $answer = 'z'; - while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) { - $answer = $this->ask($output, $question); - } - - if (false === $default) { - return $answer && 'y' == strtolower($answer[0]); - } - - return !$answer || 'y' == strtolower($answer[0]); - } - - /** - * Asks a question to the user, the response is hidden. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question - * @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not - * - * @return string The answer - * - * @throws RuntimeException In case the fallback is deactivated and the response can not be hidden - */ - public function askHiddenResponse(OutputInterface $output, $question, $fallback = true) - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - if ('\\' === DIRECTORY_SEPARATOR) { - $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; - - // handle code running from a phar - if ('phar:' === substr(__FILE__, 0, 5)) { - $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; - copy($exe, $tmpExe); - $exe = $tmpExe; - } - - $output->write($question); - $value = rtrim(shell_exec($exe)); - $output->writeln(''); - - if (isset($tmpExe)) { - unlink($tmpExe); - } - - return $value; - } - - if ($this->hasSttyAvailable()) { - $output->write($question); - - $sttyMode = shell_exec('stty -g'); - - shell_exec('stty -echo'); - $value = fgets($this->inputStream ?: STDIN, 4096); - shell_exec(sprintf('stty %s', $sttyMode)); - - if (false === $value) { - throw new RuntimeException('Aborted'); - } - - $value = trim($value); - $output->writeln(''); - - return $value; - } - - if (false !== $shell = $this->getShell()) { - $output->write($question); - $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword'; - $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); - $value = rtrim(shell_exec($command)); - $output->writeln(''); - - return $value; - } - - if ($fallback) { - return $this->ask($output, $question); - } - - throw new RuntimeException('Unable to hide the response'); - } - - /** - * Asks for a value and validates the response. - * - * The validator receives the data to validate. It must return the - * validated data when the data is valid and throw an exception - * otherwise. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param callable $validator A PHP callback - * @param int|false $attempts Max number of times to ask before giving up (false by default, which means infinite) - * @param string $default The default answer if none is given by the user - * @param array $autocomplete List of values to autocomplete - * - * @return mixed - * - * @throws \Exception When any of the validators return an error - */ - public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null) - { - $that = $this; - - $interviewer = function () use ($output, $question, $default, $autocomplete, $that) { - return $that->ask($output, $question, $default, $autocomplete); - }; - - return $this->validateAttempts($interviewer, $output, $validator, $attempts); - } - - /** - * Asks for a value, hide and validates the response. - * - * The validator receives the data to validate. It must return the - * validated data when the data is valid and throw an exception - * otherwise. - * - * @param OutputInterface $output An Output instance - * @param string|array $question The question to ask - * @param callable $validator A PHP callback - * @param int|false $attempts Max number of times to ask before giving up (false by default, which means infinite) - * @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not - * - * @return string The response - * - * @throws \Exception When any of the validators return an error - * @throws RuntimeException In case the fallback is deactivated and the response can not be hidden - */ - public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true) - { - $that = $this; - - $interviewer = function () use ($output, $question, $fallback, $that) { - return $that->askHiddenResponse($output, $question, $fallback); - }; - - return $this->validateAttempts($interviewer, $output, $validator, $attempts); - } - - /** - * Sets the input stream to read from when interacting with the user. - * - * This is mainly useful for testing purpose. - * - * @param resource $stream The input stream - */ - public function setInputStream($stream) - { - $this->inputStream = $stream; - } - - /** - * Returns the helper's input stream. - * - * @return resource|null The input stream or null if the default STDIN is used - */ - public function getInputStream() - { - return $this->inputStream; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'dialog'; - } - - /** - * Return a valid Unix shell. - * - * @return string|bool The valid shell name, false in case no valid shell is found - */ - private function getShell() - { - if (null !== self::$shell) { - return self::$shell; - } - - self::$shell = false; - - if (file_exists('/usr/bin/env')) { - // handle other OSs with bash/zsh/ksh/csh if available to hide the answer - $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; - foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) { - if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { - self::$shell = $sh; - break; - } - } - } - - return self::$shell; - } - - private function hasSttyAvailable() - { - if (null !== self::$stty) { - return self::$stty; - } - - exec('stty 2>&1', $output, $exitcode); - - return self::$stty = $exitcode === 0; - } - - /** - * Validate an attempt. - * - * @param callable $interviewer A callable that will ask for a question and return the result - * @param OutputInterface $output An Output instance - * @param callable $validator A PHP callback - * @param int|false $attempts Max number of times to ask before giving up; false will ask infinitely - * - * @return string The validated response - * - * @throws \Exception In case the max number of attempts has been reached and no valid response has been given - */ - private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts) - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $e = null; - while (false === $attempts || $attempts--) { - if (null !== $e) { - $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($e->getMessage(), 'error')); - } - - try { - return call_user_func($validator, $interviewer()); - } catch (\Exception $e) { - } - } - - throw $e; - } -} diff --git a/vendor/symfony/console/Helper/FormatterHelper.php b/vendor/symfony/console/Helper/FormatterHelper.php index ac736f98..6a48a77f 100644 --- a/vendor/symfony/console/Helper/FormatterHelper.php +++ b/vendor/symfony/console/Helper/FormatterHelper.php @@ -72,6 +72,30 @@ public function formatBlock($messages, $style, $large = false) return implode("\n", $messages); } + /** + * Truncates a message to the given length. + * + * @param string $message + * @param int $length + * @param string $suffix + * + * @return string + */ + public function truncate($message, $length, $suffix = '...') + { + $computedLength = $length - $this->strlen($suffix); + + if ($computedLength > $this->strlen($message)) { + return $message; + } + + if (false === $encoding = mb_detect_encoding($message, null, true)) { + return substr($message, 0, $length).$suffix; + } + + return mb_substr($message, 0, $length, $encoding).$suffix; + } + /** * {@inheritdoc} */ diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php index 9c538d1a..4fb17652 100644 --- a/vendor/symfony/console/Helper/Helper.php +++ b/vendor/symfony/console/Helper/Helper.php @@ -105,6 +105,11 @@ public static function formatMemory($memory) } public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string) + { + return self::strlen(self::removeDecoration($formatter, $string)); + } + + public static function removeDecoration(OutputFormatterInterface $formatter, $string) { $isDecorated = $formatter->isDecorated(); $formatter->setDecorated(false); @@ -114,6 +119,6 @@ public static function strlenWithoutDecoration(OutputFormatterInterface $formatt $string = preg_replace("/\033\[[^m]*m/", '', $string); $formatter->setDecorated($isDecorated); - return self::strlen($string); + return $string; } } diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php index 896326ee..6f12b39d 100644 --- a/vendor/symfony/console/Helper/HelperSet.php +++ b/vendor/symfony/console/Helper/HelperSet.php @@ -82,14 +82,6 @@ public function get($name) throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name)); } - if ('dialog' === $name && $this->helpers[$name] instanceof DialogHelper) { - @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED); - } elseif ('progress' === $name && $this->helpers[$name] instanceof ProgressHelper) { - @trigger_error('"Symfony\Component\Console\Helper\ProgressHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\ProgressBar" instead.', E_USER_DEPRECATED); - } elseif ('table' === $name && $this->helpers[$name] instanceof TableHelper) { - @trigger_error('"Symfony\Component\Console\Helper\TableHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\Table" instead.', E_USER_DEPRECATED); - } - return $this->helpers[$name]; } diff --git a/vendor/symfony/console/Helper/ProcessHelper.php b/vendor/symfony/console/Helper/ProcessHelper.php index a811eb48..2c46a2c3 100644 --- a/vendor/symfony/console/Helper/ProcessHelper.php +++ b/vendor/symfony/console/Helper/ProcessHelper.php @@ -36,7 +36,7 @@ class ProcessHelper extends Helper * * @return Process The process that ran */ - public function run(OutputInterface $output, $cmd, $error = null, $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) + public function run(OutputInterface $output, $cmd, $error = null, callable $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) { if ($output instanceof ConsoleOutputInterface) { $output = $output->getErrorOutput(); @@ -92,7 +92,7 @@ public function run(OutputInterface $output, $cmd, $error = null, $callback = nu * * @see run() */ - public function mustRun(OutputInterface $output, $cmd, $error = null, $callback = null) + public function mustRun(OutputInterface $output, $cmd, $error = null, callable $callback = null) { $process = $this->run($output, $cmd, $error, $callback); @@ -112,7 +112,7 @@ public function mustRun(OutputInterface $output, $cmd, $error = null, $callback * * @return callable */ - public function wrapCallback(OutputInterface $output, Process $process, $callback = null) + public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null) { if ($output instanceof ConsoleOutputInterface) { $output = $output->getErrorOutput(); @@ -120,10 +120,8 @@ public function wrapCallback(OutputInterface $output, Process $process, $callbac $formatter = $this->getHelperSet()->get('debug_formatter'); - $that = $this; - - return function ($type, $buffer) use ($output, $process, $callback, $formatter, $that) { - $output->write($formatter->progress(spl_object_hash($process), $that->escapeString($buffer), Process::ERR === $type)); + return function ($type, $buffer) use ($output, $process, $callback, $formatter) { + $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type)); if (null !== $callback) { call_user_func($callback, $type, $buffer); @@ -131,12 +129,7 @@ public function wrapCallback(OutputInterface $output, Process $process, $callbac }; } - /** - * This method is public for PHP 5.3 compatibility, it should be private. - * - * @internal - */ - public function escapeString($str) + private function escapeString($str) { return str_replace('<', '\\<', $str); } diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php index 89ca85d2..5ac86406 100644 --- a/vendor/symfony/console/Helper/ProgressBar.php +++ b/vendor/symfony/console/Helper/ProgressBar.php @@ -14,6 +14,7 @@ use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Terminal; /** * The ProgressBar provides helpers to display progress output. @@ -44,14 +45,13 @@ class ProgressBar private $formatLineCount; private $messages = array(); private $overwrite = true; + private $terminal; private $firstRun = true; private static $formatters; private static $formats; /** - * Constructor. - * * @param OutputInterface $output An OutputInterface instance * @param int $max Maximum steps (0 if unknown) */ @@ -63,6 +63,7 @@ public function __construct(OutputInterface $output, $max = 0) $this->output = $output; $this->setMaxSteps($max); + $this->terminal = new Terminal(); if (!$this->output->isDecorated()) { // disable overwrite when output does not support ANSI codes. @@ -83,7 +84,7 @@ public function __construct(OutputInterface $output, $max = 0) * @param string $name The placeholder name (including the delimiter char like %) * @param callable $callable A PHP callable */ - public static function setPlaceholderFormatterDefinition($name, $callable) + public static function setPlaceholderFormatterDefinition($name, callable $callable) { if (!self::$formatters) { self::$formatters = self::initPlaceholderFormatters(); @@ -181,20 +182,6 @@ public function getMaxSteps() return $this->max; } - /** - * Gets the progress bar step. - * - * @deprecated since version 2.6, to be removed in 3.0. Use {@link getProgress()} instead. - * - * @return int The progress bar step - */ - public function getStep() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED); - - return $this->getProgress(); - } - /** * Gets the current step position. * @@ -208,11 +195,9 @@ public function getProgress() /** * Gets the progress bar step width. * - * @internal This method is public for PHP 5.3 compatibility, it should not be used. - * * @return int The progress bar step width */ - public function getStepWidth() + private function getStepWidth() { return $this->stepWidth; } @@ -234,7 +219,7 @@ public function getProgressPercent() */ public function setBarWidth($size) { - $this->barWidth = (int) $size; + $this->barWidth = max(1, (int) $size); } /** @@ -354,30 +339,12 @@ public function start($max = null) * Advances the progress output X steps. * * @param int $step Number of steps to advance - * - * @throws LogicException */ public function advance($step = 1) { $this->setProgress($this->step + $step); } - /** - * Sets the current progress. - * - * @deprecated since version 2.6, to be removed in 3.0. Use {@link setProgress()} instead. - * - * @param int $step The current progress - * - * @throws LogicException - */ - public function setCurrent($step) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED); - - $this->setProgress($step); - } - /** * Sets whether to overwrite the progressbar, false for new line. * @@ -392,18 +359,15 @@ public function setOverwrite($overwrite) * Sets the current progress. * * @param int $step The current progress - * - * @throws LogicException */ public function setProgress($step) { $step = (int) $step; - if ($step < $this->step) { - throw new LogicException('You can\'t regress the progress bar.'); - } if ($this->max && $step > $this->max) { $this->max = $step; + } elseif ($step < 0) { + $step = 0; } $prevPeriod = (int) ($this->step / $this->redrawFreq); @@ -445,25 +409,7 @@ public function display() $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); } - // these 3 variables can be removed in favor of using $this in the closure when support for PHP 5.3 will be dropped. - $self = $this; - $output = $this->output; - $messages = $this->messages; - $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) { - if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) { - $text = call_user_func($formatter, $self, $output); - } elseif (isset($messages[$matches[1]])) { - $text = $messages[$matches[1]]; - } else { - return $matches[0]; - } - - if (isset($matches[2])) { - $text = sprintf('%'.$matches[2], $text); - } - - return $text; - }, $this->format)); + $this->overwrite($this->buildLine()); } /** @@ -633,4 +579,44 @@ private static function initFormats() 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%', ); } + + /** + * @return string + */ + private function buildLine() + { + $regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i"; + $callback = function ($matches) { + if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) { + $text = call_user_func($formatter, $this, $this->output); + } elseif (isset($this->messages[$matches[1]])) { + $text = $this->messages[$matches[1]]; + } else { + return $matches[0]; + } + + if (isset($matches[2])) { + $text = sprintf('%'.$matches[2], $text); + } + + return $text; + }; + $line = preg_replace_callback($regex, $callback, $this->format); + + // gets string length for each sub line with multiline format + $linesLength = array_map(function ($subLine) { + return Helper::strlenWithoutDecoration($this->output->getFormatter(), rtrim($subLine, "\r")); + }, explode("\n", $line)); + + $linesWidth = max($linesLength); + + $terminalWidth = $this->terminal->getWidth(); + if ($linesWidth <= $terminalWidth) { + return $line; + } + + $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth); + + return preg_replace_callback($regex, $callback, $this->format); + } } diff --git a/vendor/symfony/console/Helper/ProgressHelper.php b/vendor/symfony/console/Helper/ProgressHelper.php deleted file mode 100644 index eaac2df1..00000000 --- a/vendor/symfony/console/Helper/ProgressHelper.php +++ /dev/null @@ -1,469 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\Console\Output\ConsoleOutputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Exception\LogicException; - -/** - * The Progress class provides helpers to display progress output. - * - * @author Chris Jones - * @author Fabien Potencier - * - * @deprecated since version 2.5, to be removed in 3.0 - * Use {@link ProgressBar} instead. - */ -class ProgressHelper extends Helper -{ - const FORMAT_QUIET = ' %percent%%'; - const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%'; - const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%'; - const FORMAT_QUIET_NOMAX = ' %current%'; - const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]'; - const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%'; - - // options - private $barWidth = 28; - private $barChar = '='; - private $emptyBarChar = '-'; - private $progressChar = '>'; - private $format = null; - private $redrawFreq = 1; - - private $lastMessagesLength; - private $barCharOriginal; - - /** - * @var OutputInterface - */ - private $output; - - /** - * Current step. - * - * @var int - */ - private $current; - - /** - * Maximum number of steps. - * - * @var int - */ - private $max; - - /** - * Start time of the progress bar. - * - * @var int - */ - private $startTime; - - /** - * List of formatting variables. - * - * @var array - */ - private $defaultFormatVars = array( - 'current', - 'max', - 'bar', - 'percent', - 'elapsed', - ); - - /** - * Available formatting variables. - * - * @var array - */ - private $formatVars; - - /** - * Stored format part widths (used for padding). - * - * @var array - */ - private $widths = array( - 'current' => 4, - 'max' => 4, - 'percent' => 3, - 'elapsed' => 6, - ); - - /** - * Various time formats. - * - * @var array - */ - private $timeFormats = array( - array(0, '???'), - array(2, '1 sec'), - array(59, 'secs', 1), - array(60, '1 min'), - array(3600, 'mins', 60), - array(5400, '1 hr'), - array(86400, 'hrs', 3600), - array(129600, '1 day'), - array(604800, 'days', 86400), - ); - - public function __construct($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\ProgressBar class instead.', E_USER_DEPRECATED); - } - } - - /** - * Sets the progress bar width. - * - * @param int $size The progress bar size - */ - public function setBarWidth($size) - { - $this->barWidth = (int) $size; - } - - /** - * Sets the bar character. - * - * @param string $char A character - */ - public function setBarCharacter($char) - { - $this->barChar = $char; - } - - /** - * Sets the empty bar character. - * - * @param string $char A character - */ - public function setEmptyBarCharacter($char) - { - $this->emptyBarChar = $char; - } - - /** - * Sets the progress bar character. - * - * @param string $char A character - */ - public function setProgressCharacter($char) - { - $this->progressChar = $char; - } - - /** - * Sets the progress bar format. - * - * @param string $format The format - */ - public function setFormat($format) - { - $this->format = $format; - } - - /** - * Sets the redraw frequency. - * - * @param int $freq The frequency in steps - */ - public function setRedrawFrequency($freq) - { - $this->redrawFreq = (int) $freq; - } - - /** - * Starts the progress output. - * - * @param OutputInterface $output An Output instance - * @param int|null $max Maximum steps - */ - public function start(OutputInterface $output, $max = null) - { - if ($output instanceof ConsoleOutputInterface) { - $output = $output->getErrorOutput(); - } - - $this->startTime = time(); - $this->current = 0; - $this->max = (int) $max; - - // Disabling output when it does not support ANSI codes as it would result in a broken display anyway. - $this->output = $output->isDecorated() ? $output : new NullOutput(); - $this->lastMessagesLength = 0; - $this->barCharOriginal = ''; - - if (null === $this->format) { - switch ($output->getVerbosity()) { - case OutputInterface::VERBOSITY_QUIET: - $this->format = self::FORMAT_QUIET_NOMAX; - if ($this->max > 0) { - $this->format = self::FORMAT_QUIET; - } - break; - case OutputInterface::VERBOSITY_VERBOSE: - case OutputInterface::VERBOSITY_VERY_VERBOSE: - case OutputInterface::VERBOSITY_DEBUG: - $this->format = self::FORMAT_VERBOSE_NOMAX; - if ($this->max > 0) { - $this->format = self::FORMAT_VERBOSE; - } - break; - default: - $this->format = self::FORMAT_NORMAL_NOMAX; - if ($this->max > 0) { - $this->format = self::FORMAT_NORMAL; - } - break; - } - } - - $this->initialize(); - } - - /** - * Advances the progress output X steps. - * - * @param int $step Number of steps to advance - * @param bool $redraw Whether to redraw or not - * - * @throws LogicException - */ - public function advance($step = 1, $redraw = false) - { - $this->setCurrent($this->current + $step, $redraw); - } - - /** - * Sets the current progress. - * - * @param int $current The current progress - * @param bool $redraw Whether to redraw or not - * - * @throws LogicException - */ - public function setCurrent($current, $redraw = false) - { - if (null === $this->startTime) { - throw new LogicException('You must start the progress bar before calling setCurrent().'); - } - - $current = (int) $current; - - if ($current < $this->current) { - throw new LogicException('You can\'t regress the progress bar'); - } - - if (0 === $this->current) { - $redraw = true; - } - - $prevPeriod = (int) ($this->current / $this->redrawFreq); - - $this->current = $current; - - $currPeriod = (int) ($this->current / $this->redrawFreq); - if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) { - $this->display(); - } - } - - /** - * Outputs the current progress string. - * - * @param bool $finish Forces the end result - * - * @throws LogicException - */ - public function display($finish = false) - { - if (null === $this->startTime) { - throw new LogicException('You must start the progress bar before calling display().'); - } - - $message = $this->format; - foreach ($this->generate($finish) as $name => $value) { - $message = str_replace("%{$name}%", $value, $message); - } - $this->overwrite($this->output, $message); - } - - /** - * Removes the progress bar from the current line. - * - * This is useful if you wish to write some output - * while a progress bar is running. - * Call display() to show the progress bar again. - */ - public function clear() - { - $this->overwrite($this->output, ''); - } - - /** - * Finishes the progress output. - */ - public function finish() - { - if (null === $this->startTime) { - throw new LogicException('You must start the progress bar before calling finish().'); - } - - if (null !== $this->startTime) { - if (!$this->max) { - $this->barChar = $this->barCharOriginal; - $this->display(true); - } - $this->startTime = null; - $this->output->writeln(''); - $this->output = null; - } - } - - /** - * Initializes the progress helper. - */ - private function initialize() - { - $this->formatVars = array(); - foreach ($this->defaultFormatVars as $var) { - if (false !== strpos($this->format, "%{$var}%")) { - $this->formatVars[$var] = true; - } - } - - if ($this->max > 0) { - $this->widths['max'] = $this->strlen($this->max); - $this->widths['current'] = $this->widths['max']; - } else { - $this->barCharOriginal = $this->barChar; - $this->barChar = $this->emptyBarChar; - } - } - - /** - * Generates the array map of format variables to values. - * - * @param bool $finish Forces the end result - * - * @return array Array of format vars and values - */ - private function generate($finish = false) - { - $vars = array(); - $percent = 0; - if ($this->max > 0) { - $percent = (float) $this->current / $this->max; - } - - if (isset($this->formatVars['bar'])) { - if ($this->max > 0) { - $completeBars = floor($percent * $this->barWidth); - } else { - if (!$finish) { - $completeBars = floor($this->current % $this->barWidth); - } else { - $completeBars = $this->barWidth; - } - } - - $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar); - $bar = str_repeat($this->barChar, $completeBars); - if ($completeBars < $this->barWidth) { - $bar .= $this->progressChar; - $bar .= str_repeat($this->emptyBarChar, $emptyBars); - } - - $vars['bar'] = $bar; - } - - if (isset($this->formatVars['elapsed'])) { - $elapsed = time() - $this->startTime; - $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT); - } - - if (isset($this->formatVars['current'])) { - $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT); - } - - if (isset($this->formatVars['max'])) { - $vars['max'] = $this->max; - } - - if (isset($this->formatVars['percent'])) { - $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT); - } - - return $vars; - } - - /** - * Converts seconds into human-readable format. - * - * @param int $secs Number of seconds - * - * @return string Time in readable format - */ - private function humaneTime($secs) - { - $text = ''; - foreach ($this->timeFormats as $format) { - if ($secs < $format[0]) { - if (count($format) == 2) { - $text = $format[1]; - break; - } else { - $text = ceil($secs / $format[2]).' '.$format[1]; - break; - } - } - } - - return $text; - } - - /** - * Overwrites a previous message to the output. - * - * @param OutputInterface $output An Output instance - * @param string $message The message - */ - private function overwrite(OutputInterface $output, $message) - { - $length = $this->strlen($message); - - // append whitespace to match the last line's length - if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) { - $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT); - } - - // carriage return - $output->write("\x0D"); - $output->write($message); - - $this->lastMessagesLength = $this->strlen($message); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'progress'; - } -} diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php index 2e43bc3f..d441accd 100644 --- a/vendor/symfony/console/Helper/ProgressIndicator.php +++ b/vendor/symfony/console/Helper/ProgressIndicator.php @@ -75,42 +75,6 @@ public function setMessage($message) $this->display(); } - /** - * Gets the current indicator message. - * - * @return string|null - * - * @internal for PHP 5.3 compatibility - */ - public function getMessage() - { - return $this->message; - } - - /** - * Gets the progress bar start time. - * - * @return int The progress bar start time - * - * @internal for PHP 5.3 compatibility - */ - public function getStartTime() - { - return $this->startTime; - } - - /** - * Gets the current animated indicator character. - * - * @return string - * - * @internal for PHP 5.3 compatibility - */ - public function getCurrentValue() - { - return $this->indicatorValues[$this->indicatorCurrent % count($this->indicatorValues)]; - } - /** * Starts the indicator output. * @@ -277,13 +241,13 @@ private static function initPlaceholderFormatters() { return array( 'indicator' => function (ProgressIndicator $indicator) { - return $indicator->getCurrentValue(); + return $indicator->indicatorValues[$indicator->indicatorCurrent % count($indicator->indicatorValues)]; }, 'message' => function (ProgressIndicator $indicator) { - return $indicator->getMessage(); + return $indicator->message; }, 'elapsed' => function (ProgressIndicator $indicator) { - return Helper::formatTime(time() - $indicator->getStartTime()); + return Helper::formatTime(time() - $indicator->startTime); }, 'memory' => function () { return Helper::formatMemory(memory_get_usage(true)); diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php index 4b4e1a63..fe58bb9f 100644 --- a/vendor/symfony/console/Helper/QuestionHelper.php +++ b/vendor/symfony/console/Helper/QuestionHelper.php @@ -14,6 +14,7 @@ use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\StreamableInputInterface; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Formatter\OutputFormatterStyle; @@ -38,7 +39,7 @@ class QuestionHelper extends Helper * @param OutputInterface $output An OutputInterface instance * @param Question $question The question to ask * - * @return string The user answer + * @return mixed The user answer * * @throws RuntimeException If there is no data to read in the input stream */ @@ -52,14 +53,16 @@ public function ask(InputInterface $input, OutputInterface $output, Question $qu return $question->getDefault(); } + if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) { + $this->inputStream = $stream; + } + if (!$question->getValidator()) { return $this->doAsk($output, $question); } - $that = $this; - - $interviewer = function () use ($output, $question, $that) { - return $that->doAsk($output, $question); + $interviewer = function () use ($output, $question) { + return $this->doAsk($output, $question); }; return $this->validateAttempts($interviewer, $output, $question); @@ -70,12 +73,17 @@ public function ask(InputInterface $input, OutputInterface $output, Question $qu * * This is mainly useful for testing purpose. * + * @deprecated since version 3.2, to be removed in 4.0. Use + * StreamableInputInterface::setStream() instead. + * * @param resource $stream The input stream * * @throws InvalidArgumentException In case the stream is not a resource */ public function setInputStream($stream) { + @trigger_error(sprintf('The %s() method is deprecated since version 3.2 and will be removed in 4.0. Use %s::setStream() instead.', __METHOD__, StreamableInputInterface::class), E_USER_DEPRECATED); + if (!is_resource($stream)) { throw new InvalidArgumentException('Input stream must be a valid resource.'); } @@ -86,10 +94,17 @@ public function setInputStream($stream) /** * Returns the helper's input stream. * + * @deprecated since version 3.2, to be removed in 4.0. Use + * StreamableInputInterface::getStream() instead. + * * @return resource */ public function getInputStream() { + if (0 === func_num_args() || func_get_arg(0)) { + @trigger_error(sprintf('The %s() method is deprecated since version 3.2 and will be removed in 4.0. Use %s::getStream() instead.', __METHOD__, StreamableInputInterface::class), E_USER_DEPRECATED); + } + return $this->inputStream; } @@ -104,8 +119,6 @@ public function getName() /** * Asks the question to the user. * - * This method is public for PHP 5.3 compatibility, it should be private. - * * @param OutputInterface $output * @param Question $question * @@ -114,7 +127,7 @@ public function getName() * @throws \Exception * @throws \RuntimeException */ - public function doAsk(OutputInterface $output, Question $question) + private function doAsk(OutputInterface $output, Question $question) { $this->writePrompt($output, $question); @@ -384,11 +397,11 @@ private function getHiddenResponse(OutputInterface $output, $inputStream) * @param OutputInterface $output An Output instance * @param Question $question A Question instance * - * @return string The validated response + * @return mixed The validated response * * @throws \Exception In case the max number of attempts has been reached and no valid response has been given */ - private function validateAttempts($interviewer, OutputInterface $output, Question $question) + private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question) { $error = null; $attempts = $question->getMaxAttempts(); diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php index d622294e..66962c94 100644 --- a/vendor/symfony/console/Helper/Table.php +++ b/vendor/symfony/console/Helper/Table.php @@ -43,7 +43,7 @@ class Table * * @var array */ - private $columnWidths = array(); + private $effectiveColumnWidths = array(); /** * Number of columns cache. @@ -67,6 +67,13 @@ class Table */ private $columnStyles = array(); + /** + * User set column widths. + * + * @var array + */ + private $columnWidths = array(); + private static $styles; public function __construct(OutputInterface $output) @@ -174,6 +181,38 @@ public function getColumnStyle($columnIndex) return $this->getStyle(); } + /** + * Sets the minimum width of a column. + * + * @param int $columnIndex Column index + * @param int $width Minimum column width in characters + * + * @return $this + */ + public function setColumnWidth($columnIndex, $width) + { + $this->columnWidths[intval($columnIndex)] = intval($width); + + return $this; + } + + /** + * Sets the minimum width of all columns. + * + * @param array $widths + * + * @return $this + */ + public function setColumnWidths(array $widths) + { + $this->columnWidths = array(); + foreach ($widths as $index => $width) { + $this->setColumnWidth($index, $width); + } + + return $this; + } + public function setHeaders(array $headers) { $headers = array_values($headers); @@ -284,7 +323,7 @@ private function renderRowSeparator() $markup = $this->style->getCrossingChar(); for ($column = 0; $column < $count; ++$column) { - $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar(); + $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]).$this->style->getCrossingChar(); } $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup)); @@ -330,11 +369,11 @@ private function renderRow(array $row, $cellFormat) private function renderCell(array $row, $column, $cellFormat) { $cell = isset($row[$column]) ? $row[$column] : ''; - $width = $this->columnWidths[$column]; + $width = $this->effectiveColumnWidths[$column]; if ($cell instanceof TableCell && $cell->getColspan() > 1) { // add the width of the following columns(numbers of colspan). foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { - $width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn]; + $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn]; } } @@ -387,7 +426,7 @@ private function buildTableRows($rows) if (!strstr($cell, "\n")) { continue; } - $lines = explode("\n", $cell); + $lines = explode("\n", str_replace("\n", "\n", $cell)); foreach ($lines as $lineKey => $line) { if ($cell instanceof TableCell) { $line = new TableCell($line, array('colspan' => $cell->getColspan())); @@ -428,7 +467,7 @@ private function fillNextRows($rows, $line) $nbLines = $cell->getRowspan() - 1; $lines = array($cell); if (strstr($cell, "\n")) { - $lines = explode("\n", $cell); + $lines = explode("\n", str_replace("\n", "\n", $cell)); $nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; $rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan())); @@ -440,6 +479,9 @@ private function fillNextRows($rows, $line) foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : ''; $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan())); + if ($nbLines === $unmergedRowKey - $line) { + break; + } } } } @@ -560,9 +602,10 @@ private function calculateColumnsWidth($rows) foreach ($row as $i => $cell) { if ($cell instanceof TableCell) { - $textLength = strlen($cell); + $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell); + $textLength = Helper::strlen($textContent); if ($textLength > 0) { - $contentColumns = str_split($cell, ceil($textLength / $cell->getColspan())); + $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan())); foreach ($contentColumns as $position => $content) { $row[$i + $position] = $content; } @@ -573,7 +616,7 @@ private function calculateColumnsWidth($rows) $lengths[] = $this->getCellWidth($row, $column); } - $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2; + $this->effectiveColumnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2; } } @@ -597,14 +640,16 @@ private function getColumnSeparatorWidth() */ private function getCellWidth(array $row, $column) { + $cellWidth = 0; + if (isset($row[$column])) { $cell = $row[$column]; $cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell); - - return $cellWidth; } - return 0; + $columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0; + + return max($cellWidth, $columnWidth); } /** @@ -612,7 +657,7 @@ private function getCellWidth(array $row, $column) */ private function cleanup() { - $this->columnWidths = array(); + $this->effectiveColumnWidths = array(); $this->numberOfColumns = null; } diff --git a/vendor/symfony/console/Helper/TableCell.php b/vendor/symfony/console/Helper/TableCell.php index 69442d42..a3064fc0 100644 --- a/vendor/symfony/console/Helper/TableCell.php +++ b/vendor/symfony/console/Helper/TableCell.php @@ -37,6 +37,10 @@ class TableCell */ public function __construct($value = '', array $options = array()) { + if (is_numeric($value) && !is_string($value)) { + $value = (string) $value; + } + $this->value = $value; // check option names diff --git a/vendor/symfony/console/Helper/TableHelper.php b/vendor/symfony/console/Helper/TableHelper.php deleted file mode 100644 index 1f50d2c1..00000000 --- a/vendor/symfony/console/Helper/TableHelper.php +++ /dev/null @@ -1,269 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console\Helper; - -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\Console\Exception\InvalidArgumentException; - -/** - * Provides helpers to display table output. - * - * @author Саша Стаменковић - * @author Fabien Potencier - * - * @deprecated since version 2.5, to be removed in 3.0 - * Use {@link Table} instead. - */ -class TableHelper extends Helper -{ - const LAYOUT_DEFAULT = 0; - const LAYOUT_BORDERLESS = 1; - const LAYOUT_COMPACT = 2; - - /** - * @var Table - */ - private $table; - - public function __construct($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\Table class instead.', E_USER_DEPRECATED); - } - - $this->table = new Table(new NullOutput()); - } - - /** - * Sets table layout type. - * - * @param int $layout self::LAYOUT_* - * - * @return $this - * - * @throws InvalidArgumentException when the table layout is not known - */ - public function setLayout($layout) - { - switch ($layout) { - case self::LAYOUT_BORDERLESS: - $this->table->setStyle('borderless'); - break; - - case self::LAYOUT_COMPACT: - $this->table->setStyle('compact'); - break; - - case self::LAYOUT_DEFAULT: - $this->table->setStyle('default'); - break; - - default: - throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout)); - } - - return $this; - } - - public function setHeaders(array $headers) - { - $this->table->setHeaders($headers); - - return $this; - } - - public function setRows(array $rows) - { - $this->table->setRows($rows); - - return $this; - } - - public function addRows(array $rows) - { - $this->table->addRows($rows); - - return $this; - } - - public function addRow(array $row) - { - $this->table->addRow($row); - - return $this; - } - - public function setRow($column, array $row) - { - $this->table->setRow($column, $row); - - return $this; - } - - /** - * Sets padding character, used for cell padding. - * - * @param string $paddingChar - * - * @return $this - */ - public function setPaddingChar($paddingChar) - { - $this->table->getStyle()->setPaddingChar($paddingChar); - - return $this; - } - - /** - * Sets horizontal border character. - * - * @param string $horizontalBorderChar - * - * @return $this - */ - public function setHorizontalBorderChar($horizontalBorderChar) - { - $this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar); - - return $this; - } - - /** - * Sets vertical border character. - * - * @param string $verticalBorderChar - * - * @return $this - */ - public function setVerticalBorderChar($verticalBorderChar) - { - $this->table->getStyle()->setVerticalBorderChar($verticalBorderChar); - - return $this; - } - - /** - * Sets crossing character. - * - * @param string $crossingChar - * - * @return $this - */ - public function setCrossingChar($crossingChar) - { - $this->table->getStyle()->setCrossingChar($crossingChar); - - return $this; - } - - /** - * Sets header cell format. - * - * @param string $cellHeaderFormat - * - * @return $this - */ - public function setCellHeaderFormat($cellHeaderFormat) - { - $this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat); - - return $this; - } - - /** - * Sets row cell format. - * - * @param string $cellRowFormat - * - * @return $this - */ - public function setCellRowFormat($cellRowFormat) - { - $this->table->getStyle()->setCellHeaderFormat($cellRowFormat); - - return $this; - } - - /** - * Sets row cell content format. - * - * @param string $cellRowContentFormat - * - * @return $this - */ - public function setCellRowContentFormat($cellRowContentFormat) - { - $this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat); - - return $this; - } - - /** - * Sets table border format. - * - * @param string $borderFormat - * - * @return $this - */ - public function setBorderFormat($borderFormat) - { - $this->table->getStyle()->setBorderFormat($borderFormat); - - return $this; - } - - /** - * Sets cell padding type. - * - * @param int $padType STR_PAD_* - * - * @return $this - */ - public function setPadType($padType) - { - $this->table->getStyle()->setPadType($padType); - - return $this; - } - - /** - * Renders table to output. - * - * Example: - * +---------------+-----------------------+------------------+ - * | ISBN | Title | Author | - * +---------------+-----------------------+------------------+ - * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | - * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | - * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | - * +---------------+-----------------------+------------------+ - * - * @param OutputInterface $output - */ - public function render(OutputInterface $output) - { - $p = new \ReflectionProperty($this->table, 'output'); - $p->setAccessible(true); - $p->setValue($this->table, $output); - - $this->table->render(); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'table'; - } -} diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php index f6e40cfc..f626c33e 100644 --- a/vendor/symfony/console/Input/ArgvInput.php +++ b/vendor/symfony/console/Input/ArgvInput.php @@ -277,11 +277,14 @@ public function getFirstArgument() /** * {@inheritdoc} */ - public function hasParameterOption($values) + public function hasParameterOption($values, $onlyParams = false) { $values = (array) $values; foreach ($this->tokens as $token) { + if ($onlyParams && $token === '--') { + return false; + } foreach ($values as $value) { if ($token === $value || 0 === strpos($token, $value.'=')) { return true; @@ -295,13 +298,16 @@ public function hasParameterOption($values) /** * {@inheritdoc} */ - public function getParameterOption($values, $default = false) + public function getParameterOption($values, $default = false, $onlyParams = false) { $values = (array) $values; $tokens = $this->tokens; while (0 < count($tokens)) { $token = array_shift($tokens); + if ($onlyParams && $token === '--') { + return false; + } foreach ($values as $value) { if ($token === $value || 0 === strpos($token, $value.'=')) { @@ -324,14 +330,13 @@ public function getParameterOption($values, $default = false) */ public function __toString() { - $self = $this; - $tokens = array_map(function ($token) use ($self) { + $tokens = array_map(function ($token) { if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { - return $match[1].$self->escapeToken($match[2]); + return $match[1].$this->escapeToken($match[2]); } if ($token && $token[0] !== '-') { - return $self->escapeToken($token); + return $this->escapeToken($token); } return $token; diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php index af4c204b..a44b6b28 100644 --- a/vendor/symfony/console/Input/ArrayInput.php +++ b/vendor/symfony/console/Input/ArrayInput.php @@ -57,7 +57,7 @@ public function getFirstArgument() /** * {@inheritdoc} */ - public function hasParameterOption($values) + public function hasParameterOption($values, $onlyParams = false) { $values = (array) $values; @@ -66,6 +66,10 @@ public function hasParameterOption($values) $v = $k; } + if ($onlyParams && $v === '--') { + return false; + } + if (in_array($v, $values)) { return true; } @@ -77,11 +81,15 @@ public function hasParameterOption($values) /** * {@inheritdoc} */ - public function getParameterOption($values, $default = false) + public function getParameterOption($values, $default = false, $onlyParams = false) { $values = (array) $values; foreach ($this->parameters as $k => $v) { + if ($onlyParams && ($k === '--' || (is_int($k) && $v === '--'))) { + return false; + } + if (is_int($k)) { if (in_array($v, $values)) { return true; @@ -119,6 +127,9 @@ public function __toString() protected function parse() { foreach ($this->parameters as $key => $value) { + if ($key === '--') { + return; + } if (0 === strpos($key, '--')) { $this->addLongOption(substr($key, 2), $value); } elseif ('-' === $key[0]) { diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php index 817292ed..474a0203 100644 --- a/vendor/symfony/console/Input/Input.php +++ b/vendor/symfony/console/Input/Input.php @@ -25,12 +25,13 @@ * * @author Fabien Potencier */ -abstract class Input implements InputInterface +abstract class Input implements InputInterface, StreamableInputInterface { /** * @var InputDefinition */ protected $definition; + protected $stream; protected $options = array(); protected $arguments = array(); protected $interactive = true; @@ -191,4 +192,20 @@ public function escapeToken($token) { return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token); } + + /** + * {@inheritdoc} + */ + public function setStream($stream) + { + $this->stream = $stream; + } + + /** + * {@inheritdoc} + */ + public function getStream() + { + return $this->stream; + } } diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php index 52f324d7..85b778b2 100644 --- a/vendor/symfony/console/Input/InputDefinition.php +++ b/vendor/symfony/console/Input/InputDefinition.php @@ -11,9 +11,6 @@ namespace Symfony\Component\Console\Input; -use Symfony\Component\Console\Descriptor\TextDescriptor; -use Symfony\Component\Console\Descriptor\XmlDescriptor; -use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Exception\LogicException; @@ -414,47 +411,4 @@ public function getSynopsis($short = false) return implode(' ', $elements); } - - /** - * Returns a textual representation of the InputDefinition. - * - * @return string A string representing the InputDefinition - * - * @deprecated since version 2.3, to be removed in 3.0. - */ - public function asText() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED); - - $descriptor = new TextDescriptor(); - $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true); - $descriptor->describe($output, $this, array('raw_output' => true)); - - return $output->fetch(); - } - - /** - * Returns an XML representation of the InputDefinition. - * - * @param bool $asDom Whether to return a DOM or an XML string - * - * @return string|\DOMDocument An XML string representing the InputDefinition - * - * @deprecated since version 2.3, to be removed in 3.0. - */ - public function asXml($asDom = false) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED); - - $descriptor = new XmlDescriptor(); - - if ($asDom) { - return $descriptor->getInputDefinitionDocument($this); - } - - $output = new BufferedOutput(); - $descriptor->describe($output, $this); - - return $output->fetch(); - } } diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php index 45012609..bc664664 100644 --- a/vendor/symfony/console/Input/InputInterface.php +++ b/vendor/symfony/console/Input/InputInterface.php @@ -34,11 +34,12 @@ public function getFirstArgument(); * This method is to be used to introspect the input parameters * before they have been validated. It must be used carefully. * - * @param string|array $values The values to look for in the raw parameters (can be an array) + * @param string|array $values The values to look for in the raw parameters (can be an array) + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal * * @return bool true if the value is contained in the raw parameters */ - public function hasParameterOption($values); + public function hasParameterOption($values, $onlyParams = false); /** * Returns the value of a raw option (not parsed). @@ -46,12 +47,13 @@ public function hasParameterOption($values); * This method is to be used to introspect the input parameters * before they have been validated. It must be used carefully. * - * @param string|array $values The value(s) to look for in the raw parameters (can be an array) - * @param mixed $default The default value to return if no result is found + * @param string|array $values The value(s) to look for in the raw parameters (can be an array) + * @param mixed $default The default value to return if no result is found + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal * * @return mixed The option value */ - public function getParameterOption($values, $default = false); + public function getParameterOption($values, $default = false, $onlyParams = false); /** * Binds the current Input instance with the given arguments and options. diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php new file mode 100644 index 00000000..d7e462f2 --- /dev/null +++ b/vendor/symfony/console/Input/StreamableInputInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +/** + * StreamableInputInterface is the interface implemented by all input classes + * that have an input stream. + * + * @author Robin Chalas + */ +interface StreamableInputInterface extends InputInterface +{ + /** + * Sets the input stream to read from when interacting with the user. + * + * This is mainly useful for testing purpose. + * + * @param resource $stream The input stream + */ + public function setStream($stream); + + /** + * Returns the input stream. + * + * @return resource|null + */ + public function getStream(); +} diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php index a40ddba3..9ce02174 100644 --- a/vendor/symfony/console/Input/StringInput.php +++ b/vendor/symfony/console/Input/StringInput.php @@ -30,24 +30,13 @@ class StringInput extends ArgvInput /** * Constructor. * - * @param string $input An array of parameters from the CLI (in the argv format) - * @param InputDefinition $definition A InputDefinition instance - * - * @deprecated The second argument is deprecated as it does not work (will be removed in 3.0), use 'bind' method instead + * @param string $input An array of parameters from the CLI (in the argv format) */ - public function __construct($input, InputDefinition $definition = null) + public function __construct($input) { - if ($definition) { - @trigger_error('The $definition argument of the '.__METHOD__.' method is deprecated and will be removed in 3.0. Set this parameter with the bind() method instead.', E_USER_DEPRECATED); - } - - parent::__construct(array(), null); + parent::__construct(array()); $this->setTokens($this->tokenize($input)); - - if (null !== $definition) { - $this->bind($definition); - } } /** diff --git a/vendor/symfony/console/Logger/ConsoleLogger.php b/vendor/symfony/console/Logger/ConsoleLogger.php index 987e96a6..208575ce 100644 --- a/vendor/symfony/console/Logger/ConsoleLogger.php +++ b/vendor/symfony/console/Logger/ConsoleLogger.php @@ -59,6 +59,7 @@ class ConsoleLogger extends AbstractLogger LogLevel::INFO => self::INFO, LogLevel::DEBUG => self::INFO, ); + private $errored = false; /** * @param OutputInterface $output @@ -81,18 +82,31 @@ public function log($level, $message, array $context = array()) throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level)); } + $output = $this->output; + // Write to the error output if necessary and available - if ($this->formatLevelMap[$level] === self::ERROR && $this->output instanceof ConsoleOutputInterface) { - $output = $this->output->getErrorOutput(); - } else { - $output = $this->output; + if ($this->formatLevelMap[$level] === self::ERROR) { + if ($this->output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->errored = true; } + // the if condition check isn't necessary -- it's the same one that $output will do internally anyway. + // We only do it for efficiency here as the message formatting is relatively expensive. if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) { - $output->writeln(sprintf('<%1$s>[%2$s] %3$s', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context))); + $output->writeln(sprintf('<%1$s>[%2$s] %3$s', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]); } } + /** + * Returns true when any messages have been logged at error levels. + */ + public function hasErrored() + { + return $this->errored; + } + /** * Interpolates context values into the message placeholders. * diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php index 5682fc24..205b02f5 100644 --- a/vendor/symfony/console/Output/BufferedOutput.php +++ b/vendor/symfony/console/Output/BufferedOutput.php @@ -42,7 +42,7 @@ protected function doWrite($message, $newline) $this->buffer .= $message; if ($newline) { - $this->buffer .= "\n"; + $this->buffer .= PHP_EOL; } } } diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php index f666c793..007f3f01 100644 --- a/vendor/symfony/console/Output/ConsoleOutput.php +++ b/vendor/symfony/console/Output/ConsoleOutput.php @@ -14,15 +14,16 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface; /** - * ConsoleOutput is the default class for all CLI output. It uses STDOUT. + * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR. * - * This class is a convenient wrapper around `StreamOutput`. + * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR. * * $output = new ConsoleOutput(); * * This is equivalent to: * * $output = new StreamOutput(fopen('php://stdout', 'w')); + * $stdErr = new StreamOutput(fopen('php://stderr', 'w')); * * @author Fabien Potencier */ @@ -139,9 +140,11 @@ function_exists('php_uname') ? php_uname('s') : '', */ private function openOutputStream() { - $outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output'; + if (!$this->hasStdoutSupport()) { + return fopen('php://output', 'w'); + } - return @fopen($outputStream, 'w') ?: fopen('php://output', 'w'); + return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w'); } /** @@ -149,8 +152,6 @@ private function openOutputStream() */ private function openErrorStream() { - $errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output'; - - return fopen($errorStream, 'w'); + return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w'); } } diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php index 9a8290bd..a291ca7d 100644 --- a/vendor/symfony/console/Output/OutputInterface.php +++ b/vendor/symfony/console/Output/OutputInterface.php @@ -61,6 +61,34 @@ public function setVerbosity($level); */ public function getVerbosity(); + /** + * Returns whether verbosity is quiet (-q). + * + * @return bool true if verbosity is set to VERBOSITY_QUIET, false otherwise + */ + public function isQuiet(); + + /** + * Returns whether verbosity is verbose (-v). + * + * @return bool true if verbosity is set to VERBOSITY_VERBOSE, false otherwise + */ + public function isVerbose(); + + /** + * Returns whether verbosity is very verbose (-vv). + * + * @return bool true if verbosity is set to VERBOSITY_VERY_VERBOSE, false otherwise + */ + public function isVeryVerbose(); + + /** + * Returns whether verbosity is debug (-vvv). + * + * @return bool true if verbosity is set to VERBOSITY_DEBUG, false otherwise + */ + public function isDebug(); + /** * Sets the decorated flag. * diff --git a/vendor/symfony/console/Question/Question.php b/vendor/symfony/console/Question/Question.php index a618e7aa..6425cc54 100644 --- a/vendor/symfony/console/Question/Question.php +++ b/vendor/symfony/console/Question/Question.php @@ -164,7 +164,7 @@ public function setAutocompleterValues($values) * * @return $this */ - public function setValidator($validator) + public function setValidator(callable $validator = null) { $this->validator = $validator; @@ -224,7 +224,7 @@ public function getMaxAttempts() * * @return $this */ - public function setNormalizer($normalizer) + public function setNormalizer(callable $normalizer) { $this->normalizer = $normalizer; diff --git a/vendor/symfony/console/Shell.php b/vendor/symfony/console/Shell.php deleted file mode 100644 index dacdf223..00000000 --- a/vendor/symfony/console/Shell.php +++ /dev/null @@ -1,233 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Console; - -use Symfony\Component\Console\Exception\RuntimeException; -use Symfony\Component\Console\Input\StringInput; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\Process\ProcessBuilder; -use Symfony\Component\Process\PhpExecutableFinder; - -/** - * A Shell wraps an Application to add shell capabilities to it. - * - * Support for history and completion only works with a PHP compiled - * with readline support (either --with-readline or --with-libedit) - * - * @deprecated since version 2.8, to be removed in 3.0. - * - * @author Fabien Potencier - * @author Martin Hasoň - */ -class Shell -{ - private $application; - private $history; - private $output; - private $hasReadline; - private $processIsolation = false; - - /** - * Constructor. - * - * If there is no readline support for the current PHP executable - * a \RuntimeException exception is thrown. - * - * @param Application $application An application instance - */ - public function __construct(Application $application) - { - @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - - $this->hasReadline = function_exists('readline'); - $this->application = $application; - $this->history = getenv('HOME').'/.history_'.$application->getName(); - $this->output = new ConsoleOutput(); - } - - /** - * Runs the shell. - */ - public function run() - { - $this->application->setAutoExit(false); - $this->application->setCatchExceptions(true); - - if ($this->hasReadline) { - readline_read_history($this->history); - readline_completion_function(array($this, 'autocompleter')); - } - - $this->output->writeln($this->getHeader()); - $php = null; - if ($this->processIsolation) { - $finder = new PhpExecutableFinder(); - $php = $finder->find(); - $this->output->writeln(<<<'EOF' -Running with process isolation, you should consider this: - * each command is executed as separate process, - * commands don't support interactivity, all params must be passed explicitly, - * commands output is not colorized. - -EOF - ); - } - - while (true) { - $command = $this->readline(); - - if (false === $command) { - $this->output->writeln("\n"); - - break; - } - - if ($this->hasReadline) { - readline_add_history($command); - readline_write_history($this->history); - } - - if ($this->processIsolation) { - $pb = new ProcessBuilder(); - - $process = $pb - ->add($php) - ->add($_SERVER['argv'][0]) - ->add($command) - ->inheritEnvironmentVariables(true) - ->getProcess() - ; - - $output = $this->output; - $process->run(function ($type, $data) use ($output) { - $output->writeln($data); - }); - - $ret = $process->getExitCode(); - } else { - $ret = $this->application->run(new StringInput($command), $this->output); - } - - if (0 !== $ret) { - $this->output->writeln(sprintf('The command terminated with an error status (%s)', $ret)); - } - } - } - - /** - * Returns the shell header. - * - * @return string The header string - */ - protected function getHeader() - { - return <<{$this->application->getName()} shell ({$this->application->getVersion()}). - -At the prompt, type help for some help, -or list to get a list of available commands. - -To exit the shell, type ^D. - -EOF; - } - - /** - * Renders a prompt. - * - * @return string The prompt - */ - protected function getPrompt() - { - // using the formatter here is required when using readline - return $this->output->getFormatter()->format($this->application->getName().' > '); - } - - protected function getOutput() - { - return $this->output; - } - - protected function getApplication() - { - return $this->application; - } - - /** - * Tries to return autocompletion for the current entered text. - * - * @param string $text The last segment of the entered text - * - * @return bool|array A list of guessed strings or true - */ - private function autocompleter($text) - { - $info = readline_info(); - $text = substr($info['line_buffer'], 0, $info['end']); - - if ($info['point'] !== $info['end']) { - return true; - } - - // task name? - if (false === strpos($text, ' ') || !$text) { - return array_keys($this->application->all()); - } - - // options and arguments? - try { - $command = $this->application->find(substr($text, 0, strpos($text, ' '))); - } catch (\Exception $e) { - return true; - } - - $list = array('--help'); - foreach ($command->getDefinition()->getOptions() as $option) { - $list[] = '--'.$option->getName(); - } - - return $list; - } - - /** - * Reads a single line from standard input. - * - * @return string The single line from standard input - */ - private function readline() - { - if ($this->hasReadline) { - $line = readline($this->getPrompt()); - } else { - $this->output->write($this->getPrompt()); - $line = fgets(STDIN, 1024); - $line = (false === $line || '' === $line) ? false : rtrim($line); - } - - return $line; - } - - public function getProcessIsolation() - { - return $this->processIsolation; - } - - public function setProcessIsolation($processIsolation) - { - $this->processIsolation = (bool) $processIsolation; - - if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) { - throw new RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.'); - } - } -} diff --git a/vendor/symfony/console/Style/OutputStyle.php b/vendor/symfony/console/Style/OutputStyle.php index 8371bb53..de7be1e0 100644 --- a/vendor/symfony/console/Style/OutputStyle.php +++ b/vendor/symfony/console/Style/OutputStyle.php @@ -113,4 +113,36 @@ public function getFormatter() { return $this->output->getFormatter(); } + + /** + * {@inheritdoc} + */ + public function isQuiet() + { + return $this->output->isQuiet(); + } + + /** + * {@inheritdoc} + */ + public function isVerbose() + { + return $this->output->isVerbose(); + } + + /** + * {@inheritdoc} + */ + public function isVeryVerbose() + { + return $this->output->isVeryVerbose(); + } + + /** + * {@inheritdoc} + */ + public function isDebug() + { + return $this->output->isDebug(); + } } diff --git a/vendor/symfony/console/Style/SymfonyStyle.php b/vendor/symfony/console/Style/SymfonyStyle.php index 9ae6513c..3c9617fb 100644 --- a/vendor/symfony/console/Style/SymfonyStyle.php +++ b/vendor/symfony/console/Style/SymfonyStyle.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Console\Style; -use Symfony\Component\Console\Application; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\Helper; @@ -24,6 +23,7 @@ use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Terminal; /** * Output decorator helpers for the Symfony Style Guide. @@ -49,7 +49,8 @@ public function __construct(InputInterface $input, OutputInterface $output) $this->input = $input; $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter()); // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. - $this->lineLength = min($this->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); + $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; + $this->lineLength = min($width - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); parent::__construct($output); } @@ -348,14 +349,6 @@ private function getProgressBar() return $this->progressBar; } - private function getTerminalWidth() - { - $application = new Application(); - $dimensions = $application->getTerminalDimensions(); - - return $dimensions[0] ?: self::MAX_LINE_LENGTH; - } - private function autoPrependBlock() { $chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2); diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php new file mode 100644 index 00000000..927dfc4d --- /dev/null +++ b/vendor/symfony/console/Terminal.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console; + +class Terminal +{ + private static $width; + private static $height; + + /** + * Gets the terminal width. + * + * @return int + */ + public function getWidth() + { + $width = getenv('COLUMNS'); + if (false !== $width) { + return (int) trim($width); + } + + if (null === self::$width) { + self::initDimensions(); + } + + return self::$width ?: 80; + } + + /** + * Gets the terminal height. + * + * @return int + */ + public function getHeight() + { + $height = getenv('LINES'); + if (false !== $height) { + return (int) trim($height); + } + + if (null === self::$height) { + self::initDimensions(); + } + + return self::$height ?: 50; + } + + private static function initDimensions() + { + if ('\\' === DIRECTORY_SEPARATOR) { + if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) { + // extract [w, H] from "wxh (WxH)" + // or [w, h] from "wxh" + self::$width = (int) $matches[1]; + self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2]; + } elseif (null !== $dimensions = self::getConsoleMode()) { + // extract [w, h] from "wxh" + self::$width = (int) $dimensions[0]; + self::$height = (int) $dimensions[1]; + } + } elseif ($sttyString = self::getSttyColumns()) { + if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { + // extract [w, h] from "rows h; columns w;" + self::$width = (int) $matches[2]; + self::$height = (int) $matches[1]; + } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { + // extract [w, h] from "; h rows; w columns" + self::$width = (int) $matches[2]; + self::$height = (int) $matches[1]; + } + } + } + + /** + * Runs and parses mode CON if it's available, suppressing any error output. + * + * @return int[]|null An array composed of the width and the height or null if it could not be parsed + */ + private static function getConsoleMode() + { + if (!function_exists('proc_open')) { + return; + } + + $descriptorspec = array( + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w'), + ); + $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true)); + if (is_resource($process)) { + $info = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { + return array((int) $matches[2], (int) $matches[1]); + } + } + } + + /** + * Runs and parses stty -a if it's available, suppressing any error output. + * + * @return string|null + */ + private static function getSttyColumns() + { + if (!function_exists('proc_open')) { + return; + } + + $descriptorspec = array( + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w'), + ); + + $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true)); + if (is_resource($process)) { + $info = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + return $info; + } + } +} diff --git a/vendor/symfony/console/Tester/ApplicationTester.php b/vendor/symfony/console/Tester/ApplicationTester.php index 90efbab2..c0f8c720 100644 --- a/vendor/symfony/console/Tester/ApplicationTester.php +++ b/vendor/symfony/console/Tester/ApplicationTester.php @@ -14,6 +14,7 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\StreamOutput; @@ -31,14 +32,13 @@ class ApplicationTester { private $application; private $input; - private $output; private $statusCode; - /** - * Constructor. - * - * @param Application $application An Application instance to test + * @var OutputInterface */ + private $output; + private $captureStreamsIndependently = false; + public function __construct(Application $application) { $this->application = $application; @@ -49,9 +49,10 @@ public function __construct(Application $application) * * Available options: * - * * interactive: Sets the input interactive flag - * * decorated: Sets the output decorated flag - * * verbosity: Sets the output verbosity flag + * * interactive: Sets the input interactive flag + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available * * @param array $input An array of arguments and options * @param array $options An array of options @@ -65,12 +66,35 @@ public function run(array $input, $options = array()) $this->input->setInteractive($options['interactive']); } - $this->output = new StreamOutput(fopen('php://memory', 'w', false)); - if (isset($options['decorated'])) { - $this->output->setDecorated($options['decorated']); - } - if (isset($options['verbosity'])) { - $this->output->setVerbosity($options['verbosity']); + $this->captureStreamsIndependently = array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately']; + if (!$this->captureStreamsIndependently) { + $this->output = new StreamOutput(fopen('php://memory', 'w', false)); + if (isset($options['decorated'])) { + $this->output->setDecorated($options['decorated']); + } + if (isset($options['verbosity'])) { + $this->output->setVerbosity($options['verbosity']); + } + } else { + $this->output = new ConsoleOutput( + isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL, + isset($options['decorated']) ? $options['decorated'] : null + ); + + $errorOutput = new StreamOutput(fopen('php://memory', 'w', false)); + $errorOutput->setFormatter($this->output->getFormatter()); + $errorOutput->setVerbosity($this->output->getVerbosity()); + $errorOutput->setDecorated($this->output->isDecorated()); + + $reflectedOutput = new \ReflectionObject($this->output); + $strErrProperty = $reflectedOutput->getProperty('stderr'); + $strErrProperty->setAccessible(true); + $strErrProperty->setValue($this->output, $errorOutput); + + $reflectedParent = $reflectedOutput->getParentClass(); + $streamProperty = $reflectedParent->getProperty('stream'); + $streamProperty->setAccessible(true); + $streamProperty->setValue($this->output, fopen('php://memory', 'w', false)); } return $this->statusCode = $this->application->run($this->input, $this->output); @@ -96,6 +120,30 @@ public function getDisplay($normalize = false) return $display; } + /** + * Gets the output written to STDERR by the application. + * + * @param bool $normalize Whether to normalize end of lines to \n or not + * + * @return string + */ + public function getErrorOutput($normalize = false) + { + if (!$this->captureStreamsIndependently) { + throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.'); + } + + rewind($this->output->getErrorOutput()->getStream()); + + $display = stream_get_contents($this->output->getErrorOutput()->getStream()); + + if ($normalize) { + $display = str_replace(PHP_EOL, "\n", $display); + } + + return $display; + } + /** * Gets the input instance used by the last execution of the application. * diff --git a/vendor/symfony/console/Tester/CommandTester.php b/vendor/symfony/console/Tester/CommandTester.php index f95298bc..0bb1603c 100644 --- a/vendor/symfony/console/Tester/CommandTester.php +++ b/vendor/symfony/console/Tester/CommandTester.php @@ -21,12 +21,14 @@ * Eases the testing of console commands. * * @author Fabien Potencier + * @author Robin Chalas */ class CommandTester { private $command; private $input; private $output; + private $inputs = array(); private $statusCode; /** @@ -65,14 +67,16 @@ public function execute(array $input, array $options = array()) } $this->input = new ArrayInput($input); + if ($this->inputs) { + $this->input->setStream(self::createStream($this->inputs)); + } + if (isset($options['interactive'])) { $this->input->setInteractive($options['interactive']); } $this->output = new StreamOutput(fopen('php://memory', 'w', false)); - if (isset($options['decorated'])) { - $this->output->setDecorated($options['decorated']); - } + $this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false); if (isset($options['verbosity'])) { $this->output->setVerbosity($options['verbosity']); } @@ -129,4 +133,29 @@ public function getStatusCode() { return $this->statusCode; } + + /** + * Sets the user inputs. + * + * @param array An array of strings representing each input + * passed to the command input stream. + * + * @return CommandTester + */ + public function setInputs(array $inputs) + { + $this->inputs = $inputs; + + return $this; + } + + private static function createStream(array $inputs) + { + $stream = fopen('php://memory', 'r+', false); + + fwrite($stream, implode(PHP_EOL, $inputs)); + rewind($stream); + + return $stream; + } } diff --git a/vendor/symfony/console/composer.json b/vendor/symfony/console/composer.json index f0af3f21..fab17b8a 100644 --- a/vendor/symfony/console/composer.json +++ b/vendor/symfony/console/composer.json @@ -16,17 +16,19 @@ } ], "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0", - "symfony/debug": "~2.7,>=2.7.2|~3.0.0" + "symfony/debug": "~2.8|~3.0" }, "require-dev": { - "symfony/event-dispatcher": "~2.1|~3.0.0", - "symfony/process": "~2.1|~3.0.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0", "psr/log": "~1.0" }, "suggest": { "symfony/event-dispatcher": "", + "symfony/filesystem": "", "symfony/process": "", "psr/log": "For using the console logger" }, @@ -39,7 +41,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/console/phpunit.xml.dist b/vendor/symfony/console/phpunit.xml.dist index 8c09554f..32569d63 100644 --- a/vendor/symfony/console/phpunit.xml.dist +++ b/vendor/symfony/console/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/debug/CHANGELOG.md b/vendor/symfony/debug/CHANGELOG.md index ab07458a..70f7802a 100644 --- a/vendor/symfony/debug/CHANGELOG.md +++ b/vendor/symfony/debug/CHANGELOG.md @@ -1,6 +1,18 @@ CHANGELOG ========= +3.2.0 +----- + +* `FlattenException::getTrace()` now returns additional type descriptions + `integer` and `float`. + + +3.0.0 +----- + +* removed classes, methods and interfaces deprecated in 2.x + 2.8.0 ----- diff --git a/vendor/symfony/debug/Debug.php b/vendor/symfony/debug/Debug.php index 9404992d..e3665ae5 100644 --- a/vendor/symfony/debug/Debug.php +++ b/vendor/symfony/debug/Debug.php @@ -31,7 +31,7 @@ class Debug * @param int $errorReportingLevel The level of error reporting you want * @param bool $displayErrors Whether to display errors (for development) or just log them (for production) */ - public static function enable($errorReportingLevel = null, $displayErrors = true) + public static function enable($errorReportingLevel = E_ALL, $displayErrors = true) { if (static::$enabled) { return; @@ -42,7 +42,7 @@ public static function enable($errorReportingLevel = null, $displayErrors = true if (null !== $errorReportingLevel) { error_reporting($errorReportingLevel); } else { - error_reporting(-1); + error_reporting(E_ALL); } if ('cli' !== PHP_SAPI) { diff --git a/vendor/symfony/debug/DebugClassLoader.php b/vendor/symfony/debug/DebugClassLoader.php index 12d379aa..f79e9fbe 100644 --- a/vendor/symfony/debug/DebugClassLoader.php +++ b/vendor/symfony/debug/DebugClassLoader.php @@ -26,7 +26,6 @@ class DebugClassLoader { private $classLoader; private $isFinder; - private $wasFinder; private static $caseCheck; private static $deprecated = array(); private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null'); @@ -35,20 +34,12 @@ class DebugClassLoader /** * Constructor. * - * @param callable|object $classLoader Passing an object is @deprecated since version 2.5 and support for it will be removed in 3.0 + * @param callable $classLoader A class loader */ - public function __construct($classLoader) + public function __construct(callable $classLoader) { - $this->wasFinder = is_object($classLoader) && method_exists($classLoader, 'findFile'); - - if ($this->wasFinder) { - @trigger_error('The '.__METHOD__.' method will no longer support receiving an object into its $classLoader argument in 3.0.', E_USER_DEPRECATED); - $this->classLoader = array($classLoader, 'loadClass'); - $this->isFinder = true; - } else { - $this->classLoader = $classLoader; - $this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile'); - } + $this->classLoader = $classLoader; + $this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile'); if (!isset(self::$caseCheck)) { $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), DIRECTORY_SEPARATOR); @@ -77,11 +68,11 @@ public function __construct($classLoader) /** * Gets the wrapped class loader. * - * @return callable|object A class loader. Since version 2.5, returning an object is @deprecated and support for it will be removed in 3.0 + * @return callable The wrapped class loader */ public function getClassLoader() { - return $this->wasFinder ? $this->classLoader[0] : $this->classLoader; + return $this->classLoader; } /** @@ -132,24 +123,6 @@ public static function disable() } } - /** - * Finds a file by class name. - * - * @param string $class A class name to resolve to file - * - * @return string|null - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function findFile($class) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - if ($this->wasFinder) { - return $this->classLoader[0]->findFile($class); - } - } - /** * Loads the given class or interface. * @@ -172,21 +145,13 @@ public function loadClass($class) call_user_func($this->classLoader, $class); $file = false; } - } catch (\Exception $e) { + } finally { ErrorHandler::unstackErrors(); - - throw $e; - } catch (\Throwable $e) { - ErrorHandler::unstackErrors(); - - throw $e; } - ErrorHandler::unstackErrors(); - - $exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false)); + $exists = class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false); - if ('\\' === $class[0]) { + if ($class && '\\' === $class[0]) { $class = substr($class, 1); } diff --git a/vendor/symfony/debug/ErrorHandler.php b/vendor/symfony/debug/ErrorHandler.php index d541b83a..c91e3599 100644 --- a/vendor/symfony/debug/ErrorHandler.php +++ b/vendor/symfony/debug/ErrorHandler.php @@ -17,6 +17,7 @@ use Symfony\Component\Debug\Exception\FatalErrorException; use Symfony\Component\Debug\Exception\FatalThrowableError; use Symfony\Component\Debug\Exception\OutOfMemoryException; +use Symfony\Component\Debug\Exception\SilencedErrorContext; use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler; use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler; use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler; @@ -29,7 +30,7 @@ * - thrownErrors: errors thrown as \ErrorException * - loggedErrors: logged errors, when not @-silenced * - scopedErrors: errors thrown or logged with their local context - * - tracedErrors: errors logged with their stack trace, only once for repeated errors + * - tracedErrors: errors logged with their stack trace * - screamedErrors: never @-silenced errors * * Each error level can be logged by a dedicated PSR-3 logger object. @@ -43,14 +44,10 @@ * can see them and weight them as more important to fix than others of the same level. * * @author Nicolas Grekas + * @author Grégoire Pineau */ class ErrorHandler { - /** - * @deprecated since version 2.6, to be removed in 3.0. - */ - const TYPE_DEPRECATION = -100; - private $levels = array( E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'User Deprecated', @@ -92,8 +89,8 @@ class ErrorHandler private $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE private $loggedErrors = 0; + private $traceReflector; - private $loggedTraces = array(); private $isRecursive = 0; private $isRoot = false; private $exceptionHandler; @@ -103,37 +100,24 @@ class ErrorHandler private static $stackedErrors = array(); private static $stackedErrorLevels = array(); private static $toStringException = null; - - /** - * Same init value as thrownErrors. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - private $displayErrors = 0x1FFF; + private static $exitCode = 0; /** * Registers the error handler. * - * @param self|null|int $handler The handler to register, or @deprecated (since version 2.6, to be removed in 3.0) bit field of thrown levels - * @param bool $replace Whether to replace or not any existing handler + * @param self|null $handler The handler to register + * @param bool $replace Whether to replace or not any existing handler * * @return self The registered error handler */ - public static function register($handler = null, $replace = true) + public static function register(self $handler = null, $replace = true) { if (null === self::$reservedMemory) { self::$reservedMemory = str_repeat('x', 10240); register_shutdown_function(__CLASS__.'::handleFatalError'); } - $levels = -1; - - if ($handlerIsNew = !$handler instanceof self) { - // @deprecated polymorphism, to be removed in 3.0 - if (null !== $handler) { - $levels = $replace ? $handler : 0; - $replace = true; - } + if ($handlerIsNew = null === $handler) { $handler = new static(); } @@ -154,7 +138,7 @@ public static function register($handler = null, $replace = true) restore_error_handler(); } - $handler->throwAt($levels & $handler->thrownErrors, true); + $handler->throwAt(E_ALL & $handler->thrownErrors, true); return $handler; } @@ -165,6 +149,8 @@ public function __construct(BufferingLogger $bootstrappingLogger = null) $this->bootstrappingLogger = $bootstrappingLogger; $this->setDefaultLogger($bootstrappingLogger); } + $this->traceReflector = new \ReflectionProperty('Exception', 'trace'); + $this->traceReflector->setAccessible(true); } /** @@ -174,7 +160,7 @@ public function __construct(BufferingLogger $bootstrappingLogger = null) * @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants * @param bool $replace Whether to replace or not any existing logger */ - public function setDefaultLogger(LoggerInterface $logger, $levels = null, $replace = false) + public function setDefaultLogger(LoggerInterface $logger, $levels = E_ALL, $replace = false) { $loggers = array(); @@ -186,7 +172,7 @@ public function setDefaultLogger(LoggerInterface $logger, $levels = null, $repla } } else { if (null === $levels) { - $levels = E_ALL | E_STRICT; + $levels = E_ALL; } foreach ($this->loggers as $type => $log) { if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) { @@ -240,7 +226,7 @@ public function setLoggers(array $loggers) if ($flush) { foreach ($this->bootstrappingLogger->cleanLogs() as $log) { - $type = $log[2]['type']; + $type = $log[2]['exception'] instanceof \ErrorException ? $log[2]['exception']->getSeverity() : E_ERROR; if (!isset($flush[$type])) { $this->bootstrappingLogger->log($log[0], $log[1], $log[2]); } elseif ($this->loggers[$type][0]) { @@ -258,14 +244,9 @@ public function setLoggers(array $loggers) * @param callable $handler A handler that will be called on Exception * * @return callable|null The previous exception handler - * - * @throws \InvalidArgumentException */ - public function setExceptionHandler($handler) + public function setExceptionHandler(callable $handler = null) { - if (null !== $handler && !is_callable($handler)) { - throw new \LogicException('The exception handler must be a valid PHP callable.'); - } $prev = $this->exceptionHandler; $this->exceptionHandler = $handler; @@ -289,9 +270,6 @@ public function throwAt($levels, $replace = false) } $this->reRegister($prev | $this->loggedErrors); - // $this->displayErrors is @deprecated since version 2.6 - $this->displayErrors = $this->thrownErrors; - return $prev; } @@ -375,12 +353,10 @@ private function reRegister($prev) /** * Handles errors by filtering then logging them according to the configured bit fields. * - * @param int $type One of the E_* constants + * @param int $type One of the E_* constants * @param string $message * @param string $file * @param int $line - * @param array $context - * @param array $backtrace * * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself * @@ -388,8 +364,10 @@ private function reRegister($prev) * * @internal */ - public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) + public function handleError($type, $message, $file, $line) { + // Level is the current error reporting level to manage silent error. + // Strong errors are not authorized to be silenced. $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; @@ -398,8 +376,17 @@ public function handleError($type, $message, $file, $line, array $context, array if (!$type || (!$log && !$throw)) { return $type && $log; } + $scope = $this->scopedErrors & $type; - if (isset($context['GLOBALS']) && ($this->scopedErrors & $type)) { + if (4 < $numArgs = func_num_args()) { + $context = $scope ? (func_get_arg(4) ?: array()) : array(); + $backtrace = 5 < $numArgs ? func_get_arg(5) : null; // defined on HHVM + } else { + $context = array(); + $backtrace = null; + } + + if (isset($context['GLOBALS']) && $scope) { $e = $context; // Whatever the signature of the method, unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 $context = $e; @@ -414,28 +401,44 @@ public function handleError($type, $message, $file, $line, array $context, array return true; } - if ($throw) { - if (null !== self::$toStringException) { - $throw = self::$toStringException; - self::$toStringException = null; - } elseif (($this->scopedErrors & $type) && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) { - // Checking for class existence is a work around for https://bugs.php.net/42098 - $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context); + $logMessage = $this->levels[$type].': '.$message; + + if (null !== self::$toStringException) { + $errorAsException = self::$toStringException; + self::$toStringException = null; + } elseif (!$throw && !($type & $level)) { + $errorAsException = new SilencedErrorContext($type, $file, $line); + } else { + if ($scope) { + $errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context); } else { - $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line); + $errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line); } - if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { - // Exceptions thrown from error handlers are sometimes not caught by the exception - // handler and shutdown handlers are bypassed before 5.4.8/5.3.18. - // We temporarily re-enable display_errors to prevent any blank page related to this bug. + // Clean the trace by removing function arguments and the first frames added by the error handler itself. + if ($throw || $this->tracedErrors & $type) { + $backtrace = $backtrace ?: $errorAsException->getTrace(); + $lightTrace = $backtrace; - $throw->errorHandlerCanary = new ErrorHandlerCanary(); + for ($i = 0; isset($backtrace[$i]); ++$i) { + if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) { + $lightTrace = array_slice($lightTrace, 1 + $i); + break; + } + } + if (!($throw || $this->scopedErrors & $type)) { + for ($i = 0; isset($lightTrace[$i]); ++$i) { + unset($lightTrace[$i]['args']); + } + } + $this->traceReflector->setValue($errorAsException, $lightTrace); + } else { + $this->traceReflector->setValue($errorAsException, array()); } + } + if ($throw) { if (E_USER_ERROR & $type) { - $backtrace = $backtrace ?: $throw->getTrace(); - for ($i = 1; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) && '__toString' === $backtrace[$i]['function'] @@ -454,7 +457,7 @@ public function handleError($type, $message, $file, $line, array $context, array if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { if (1 === $i) { // On HHVM - $throw = $e; + $errorAsException = $e; break; } self::$toStringException = $e; @@ -465,7 +468,7 @@ public function handleError($type, $message, $file, $line, array $context, array if (1 < $i) { // On PHP (not on HHVM), display the original error message instead of the default one. - $this->handleException($throw); + $this->handleException($errorAsException); // Stop the process by giving back the error to the native handler. return false; @@ -474,56 +477,25 @@ public function handleError($type, $message, $file, $line, array $context, array } } - throw $throw; - } - - // For duplicated errors, log the trace only once - $e = md5("{$type}/{$line}/{$file}\x00{$message}", true); - $trace = true; - - if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { - $trace = false; - } else { - $this->loggedTraces[$e] = 1; - } - - $e = compact('type', 'file', 'line', 'level'); - - if ($type & $level) { - if ($this->scopedErrors & $type) { - $e['scope_vars'] = $context; - if ($trace) { - $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); - } - } elseif ($trace) { - if (null === $backtrace) { - $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - } else { - foreach ($backtrace as &$frame) { - unset($frame['args'], $frame); - } - $e['stack'] = $backtrace; - } - } + throw $errorAsException; } if ($this->isRecursive) { $log = 0; } elseif (self::$stackedErrorLevels) { - self::$stackedErrors[] = array($this->loggers[$type][0], ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); + self::$stackedErrors[] = array( + $this->loggers[$type][0], + ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, + $logMessage, + array('exception' => $errorAsException), + ); } else { try { $this->isRecursive = true; - $this->loggers[$type][0]->log(($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); - $this->isRecursive = false; - } catch (\Exception $e) { - $this->isRecursive = false; - - throw $e; - } catch (\Throwable $e) { + $level = ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG; + $this->loggers[$type][0]->log($level, $logMessage, array('exception' => $errorAsException)); + } finally { $this->isRecursive = false; - - throw $e; } } @@ -540,26 +512,22 @@ public function handleError($type, $message, $file, $line, array $context, array */ public function handleException($exception, array $error = null) { + if (null === $error) { + self::$exitCode = 255; + } if (!$exception instanceof \Exception) { $exception = new FatalThrowableError($exception); } $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR; if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) { - $e = array( - 'type' => $type, - 'file' => $exception->getFile(), - 'line' => $exception->getLine(), - 'level' => error_reporting(), - 'stack' => $exception->getTrace(), - ); if ($exception instanceof FatalErrorException) { if ($exception instanceof FatalThrowableError) { $error = array( 'type' => $type, 'message' => $message = $exception->getMessage(), - 'file' => $e['file'], - 'line' => $e['line'], + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), ); } else { $message = 'Fatal '.$exception->getMessage(); @@ -575,7 +543,7 @@ public function handleException($exception, array $error = null) } if ($this->loggedErrors & $type) { try { - $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e); + $this->loggers[$type][0]->log($this->loggers[$type][1], $message, array('exception' => $exception)); } catch (\Exception $handlerException) { } catch (\Throwable $handlerException) { } @@ -625,7 +593,7 @@ public static function handleFatalError(array $error = null) return; } - if (null === $error) { + if ($exit = null === $error) { $error = error_get_last(); } @@ -649,15 +617,21 @@ public static function handleFatalError(array $error = null) } else { $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace); } - } elseif (!isset($exception)) { - return; } try { - $handler->handleException($exception, $error); + if (isset($exception)) { + self::$exitCode = 255; + $handler->handleException($exception, $error); + } } catch (FatalErrorException $e) { // Ignore this re-throw } + + if ($exit && self::$exitCode) { + $exitCode = self::$exitCode; + register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); }); + } } /** @@ -684,10 +658,10 @@ public static function unstackErrors() $level = array_pop(self::$stackedErrorLevels); if (null !== $level) { - $e = error_reporting($level); - if ($e !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) { + $errorReportingLevel = error_reporting($level); + if ($errorReportingLevel !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) { // If the user changed the error level, do not overwrite it - error_reporting($e); + error_reporting($errorReportingLevel); } } @@ -695,8 +669,8 @@ public static function unstackErrors() $errors = self::$stackedErrors; self::$stackedErrors = array(); - foreach ($errors as $e) { - $e[0]->log($e[1], $e[2], $e[3]); + foreach ($errors as $error) { + $error[0]->log($error[1], $error[2], $error[3]); } } } @@ -716,118 +690,4 @@ protected function getFatalErrorHandlers() new ClassNotFoundFatalErrorHandler(), ); } - - /** - * Sets the level at which the conversion to Exception is done. - * - * @param int|null $level The level (null to use the error_reporting() value and 0 to disable) - * - * @deprecated since version 2.6, to be removed in 3.0. Use throwAt() instead. - */ - public function setLevel($level) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED); - - $level = null === $level ? error_reporting() : $level; - $this->throwAt($level, true); - } - - /** - * Sets the display_errors flag value. - * - * @param int $displayErrors The display_errors flag value - * - * @deprecated since version 2.6, to be removed in 3.0. Use throwAt() instead. - */ - public function setDisplayErrors($displayErrors) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED); - - if ($displayErrors) { - $this->throwAt($this->displayErrors, true); - } else { - $displayErrors = $this->displayErrors; - $this->throwAt(0, true); - $this->displayErrors = $displayErrors; - } - } - - /** - * Sets a logger for the given channel. - * - * @param LoggerInterface $logger A logger interface - * @param string $channel The channel associated with the logger (deprecation, emergency or scream) - * - * @deprecated since version 2.6, to be removed in 3.0. Use setLoggers() or setDefaultLogger() instead. - */ - public static function setLogger(LoggerInterface $logger, $channel = 'deprecation') - { - @trigger_error('The '.__METHOD__.' static method is deprecated since version 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED); - - $handler = set_error_handler('var_dump'); - $handler = is_array($handler) ? $handler[0] : null; - restore_error_handler(); - if (!$handler instanceof self) { - return; - } - if ('deprecation' === $channel) { - $handler->setDefaultLogger($logger, E_DEPRECATED | E_USER_DEPRECATED, true); - $handler->screamAt(E_DEPRECATED | E_USER_DEPRECATED); - } elseif ('scream' === $channel) { - $handler->setDefaultLogger($logger, E_ALL | E_STRICT, false); - $handler->screamAt(E_ALL | E_STRICT); - } elseif ('emergency' === $channel) { - $handler->setDefaultLogger($logger, E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR, true); - $handler->screamAt(E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR); - } - } - - /** - * @deprecated since version 2.6, to be removed in 3.0. Use handleError() instead. - */ - public function handle($level, $message, $file = 'unknown', $line = 0, $context = array()) - { - $this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array()); - - return $this->handleError($level, $message, $file, $line, (array) $context); - } - - /** - * Handles PHP fatal errors. - * - * @deprecated since version 2.6, to be removed in 3.0. Use handleFatalError() instead. - */ - public function handleFatal() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED); - - static::handleFatalError(); - } -} - -/** - * Private class used to work around https://bugs.php.net/54275. - * - * @author Nicolas Grekas - * - * @internal - */ -class ErrorHandlerCanary -{ - private static $displayErrors = null; - - public function __construct() - { - if (null === self::$displayErrors) { - self::$displayErrors = ini_set('display_errors', 1); - } - } - - public function __destruct() - { - if (null !== self::$displayErrors) { - ini_set('display_errors', self::$displayErrors); - self::$displayErrors = null; - } - } } diff --git a/vendor/symfony/debug/Exception/DummyException.php b/vendor/symfony/debug/Exception/DummyException.php deleted file mode 100644 index c836f876..00000000 --- a/vendor/symfony/debug/Exception/DummyException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Debug\Exception; - -@trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -/** - * @author Fabien Potencier - * - * @deprecated since version 2.5, to be removed in 3.0. - */ -class DummyException extends \ErrorException -{ -} diff --git a/vendor/symfony/debug/Exception/FatalErrorException.php b/vendor/symfony/debug/Exception/FatalErrorException.php index db2fb43b..f24a54e7 100644 --- a/vendor/symfony/debug/Exception/FatalErrorException.php +++ b/vendor/symfony/debug/Exception/FatalErrorException.php @@ -9,31 +9,14 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\HttpKernel\Exception; - -/** - * Fatal Error Exception. - * - * @author Fabien Potencier - * @author Konstanton Myakshin - * @author Nicolas Grekas - * - * @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead. - */ -class FatalErrorException extends \ErrorException -{ -} - namespace Symfony\Component\Debug\Exception; -use Symfony\Component\HttpKernel\Exception\FatalErrorException as LegacyFatalErrorException; - /** * Fatal Error Exception. * * @author Konstanton Myakshin */ -class FatalErrorException extends LegacyFatalErrorException +class FatalErrorException extends \ErrorException { public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null) { diff --git a/vendor/symfony/debug/Exception/FlattenException.php b/vendor/symfony/debug/Exception/FlattenException.php index b3a98ac0..286a71ec 100644 --- a/vendor/symfony/debug/Exception/FlattenException.php +++ b/vendor/symfony/debug/Exception/FlattenException.php @@ -9,49 +9,8 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\HttpKernel\Exception; - -use Symfony\Component\Debug\Exception\FlattenException as DebugFlattenException; - -/** - * FlattenException wraps a PHP Exception to be able to serialize it. - * - * Basically, this class removes all objects from the trace. - * - * @author Fabien Potencier - * - * @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead. - */ -class FlattenException -{ - private $handler; - - public static function __callStatic($method, $args) - { - if (!method_exists('Symfony\Component\Debug\Exception\FlattenException', $method)) { - throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_called_class(), $method)); - } - - return call_user_func_array(array('Symfony\Component\Debug\Exception\FlattenException', $method), $args); - } - - public function __call($method, $args) - { - if (!isset($this->handler)) { - $this->handler = new DebugFlattenException(); - } - - if (!method_exists($this->handler, $method)) { - throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method)); - } - - return call_user_func_array(array($this->handler, $method), $args); - } -} - namespace Symfony\Component\Debug\Exception; -use Symfony\Component\HttpKernel\Exception\FlattenException as LegacyFlattenException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; /** @@ -61,7 +20,7 @@ public function __call($method, $args) * * @author Fabien Potencier */ -class FlattenException extends LegacyFlattenException +class FlattenException { private $message; private $code; @@ -278,6 +237,10 @@ private function flattenArgs($args, $level = 0, &$count = 0) $result[$key] = array('null', null); } elseif (is_bool($value)) { $result[$key] = array('boolean', $value); + } elseif (is_int($value)) { + $result[$key] = array('integer', $value); + } elseif (is_float($value)) { + $result[$key] = array('float', $value); } elseif (is_resource($value)) { $result[$key] = array('resource', get_resource_type($value)); } else { diff --git a/vendor/symfony/debug/Exception/SilencedErrorContext.php b/vendor/symfony/debug/Exception/SilencedErrorContext.php new file mode 100644 index 00000000..0c3a0e1d --- /dev/null +++ b/vendor/symfony/debug/Exception/SilencedErrorContext.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Exception; + +/** + * Data Object that represents a Silenced Error. + * + * @author Grégoire Pineau + */ +class SilencedErrorContext implements \JsonSerializable +{ + private $severity; + private $file; + private $line; + + public function __construct($severity, $file, $line) + { + $this->severity = $severity; + $this->file = $file; + $this->line = $line; + } + + public function getSeverity() + { + return $this->severity; + } + + public function getFile() + { + return $this->file; + } + + public function getLine() + { + return $this->line; + } + + public function JsonSerialize() + { + return array( + 'severity' => $this->severity, + 'file' => $this->file, + 'line' => $this->line, + ); + } +} diff --git a/vendor/symfony/debug/ExceptionHandler.php b/vendor/symfony/debug/ExceptionHandler.php index 3cdc0921..f2ae4b10 100644 --- a/vendor/symfony/debug/ExceptionHandler.php +++ b/vendor/symfony/debug/ExceptionHandler.php @@ -11,9 +11,9 @@ namespace Symfony\Component\Debug; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Debug\Exception\FlattenException; use Symfony\Component\Debug\Exception\OutOfMemoryException; +use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; /** * ExceptionHandler converts an exception to a Response object. @@ -38,14 +38,6 @@ class ExceptionHandler public function __construct($debug = true, $charset = null, $fileLinkFormat = null) { - if (false !== strpos($charset, '%')) { - @trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since version 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED); - - // Swap $charset and $fileLinkFormat for BC reasons - $pivot = $fileLinkFormat; - $fileLinkFormat = $charset; - $charset = $pivot; - } $this->debug = $debug; $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8'; $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); @@ -80,11 +72,8 @@ public static function register($debug = true, $charset = null, $fileLinkFormat * * @return callable|null The previous exception handler if any */ - public function setHandler($handler) + public function setHandler(callable $handler = null) { - if (null !== $handler && !is_callable($handler)) { - throw new \LogicException('The exception handler must be a valid PHP callable.'); - } $old = $this->handler; $this->handler = $handler; @@ -94,14 +83,14 @@ public function setHandler($handler) /** * Sets the format for links to source files. * - * @param string $format The format for links to source files + * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files * * @return string The previous file link format */ - public function setFileLinkFormat($format) + public function setFileLinkFormat($fileLinkFormat) { $old = $this->fileLinkFormat; - $this->fileLinkFormat = $format; + $this->fileLinkFormat = $fileLinkFormat; return $old; } @@ -117,20 +106,36 @@ public function setFileLinkFormat($format) public function handle(\Exception $exception) { if (null === $this->handler || $exception instanceof OutOfMemoryException) { - $this->failSafeHandle($exception); + $this->sendPhpResponse($exception); return; } $caughtLength = $this->caughtLength = 0; - ob_start(array($this, 'catchOutput')); - $this->failSafeHandle($exception); + ob_start(function ($buffer) { + $this->caughtBuffer = $buffer; + + return ''; + }); + + $this->sendPhpResponse($exception); while (null === $this->caughtBuffer && ob_end_flush()) { // Empty loop, everything is in the condition } if (isset($this->caughtBuffer[0])) { - ob_start(array($this, 'cleanOutput')); + ob_start(function ($buffer) { + if ($this->caughtLength) { + // use substr_replace() instead of substr() for mbstring overloading resistance + $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength); + if (isset($cleanBuffer[0])) { + $buffer = $cleanBuffer; + } + } + + return $buffer; + }); + echo $this->caughtBuffer; $caughtLength = ob_get_length(); } @@ -147,33 +152,6 @@ public function handle(\Exception $exception) } } - /** - * Sends a response for the given Exception. - * - * If you have the Symfony HttpFoundation component installed, - * this method will use it to create and send the response. If not, - * it will fallback to plain PHP functions. - * - * @param \Exception $exception An \Exception instance - */ - private function failSafeHandle(\Exception $exception) - { - if (class_exists('Symfony\Component\HttpFoundation\Response', false) - && __CLASS__ !== get_class($this) - && ($reflector = new \ReflectionMethod($this, 'createResponse')) - && __CLASS__ !== $reflector->class - ) { - $response = $this->createResponse($exception); - $response->sendHeaders(); - $response->sendContent(); - @trigger_error(sprintf("The %s::createResponse method is deprecated since 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED); - - return; - } - - $this->sendPhpResponse($exception); - } - /** * Sends the error associated with the given Exception as a plain PHP response. * @@ -199,26 +177,6 @@ public function sendPhpResponse($exception) echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception)); } - /** - * Creates the error Response associated with the given Exception. - * - * @param \Exception|FlattenException $exception An \Exception or FlattenException instance - * - * @return Response A Response instance - * - * @deprecated since 2.8, to be removed in 3.0. - */ - public function createResponse($exception) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - - if (!$exception instanceof FlattenException) { - $exception = FlattenException::create($exception); - } - - return Response::create($this->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset($this->charset); - } - /** * Gets the full HTML content associated with the given exception. * @@ -333,10 +291,6 @@ public function getStylesheet(FlattenException $exception) .sf-reset .exception_message { margin-left: 3em; display: block; } .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; } .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px; - -webkit-border-bottom-right-radius: 16px; - -webkit-border-bottom-left-radius: 16px; - -moz-border-radius-bottomright: 16px; - -moz-border-radius-bottomleft: 16px; border-bottom-right-radius: 16px; border-bottom-left-radius: 16px; border-bottom:1px solid #ccc; @@ -345,10 +299,6 @@ public function getStylesheet(FlattenException $exception) word-wrap: break-word; } .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px; - -webkit-border-top-left-radius: 16px; - -webkit-border-top-right-radius: 16px; - -moz-border-radius-topleft: 16px; - -moz-border-radius-topright: 16px; border-top-left-radius: 16px; border-top-right-radius: 16px; border-top:1px solid #ccc; @@ -361,8 +311,6 @@ public function getStylesheet(FlattenException $exception) .sf-reset a:hover { background:none; color:#313131; text-decoration:underline; } .sf-reset ol { padding: 10px 0; } .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px; - -webkit-border-radius: 10px; - -moz-border-radius: 10px; border-radius: 10px; border: 1px solid #ccc; } @@ -387,7 +335,7 @@ private function decorate($content, $css) $css - + $content @@ -403,16 +351,14 @@ private function formatClass($class) private function formatPath($path, $line) { - $path = $this->escapeHtml($path); - $file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path; - - if ($linkFormat = $this->fileLinkFormat) { - $link = strtr($this->escapeHtml($linkFormat), array('%f' => $path, '%l' => (int) $line)); + $file = $this->escapeHtml(preg_match('#[^/\\\\]*+$#', $path, $file) ? $file[0] : $path); + $fmt = $this->fileLinkFormat; - return sprintf(' in %s line %d', $link, $file, $line); + if ($fmt && $link = is_string($fmt) ? strtr($fmt, array('%f' => $path, '%l' => $line)) : $fmt->format($path, $line)) { + return sprintf(' in %s line %d', $this->escapeHtml($link), $file, $line); } - return sprintf(' in %s line %d', $path, $file, $line); + return sprintf(' in %s line %d', $this->escapeHtml($path), $file, $line); } /** @@ -430,8 +376,6 @@ private function formatArgs(array $args) $formattedValue = sprintf('object(%s)', $this->formatClass($item[1])); } elseif ('array' === $item[0]) { $formattedValue = sprintf('array(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]); - } elseif ('string' === $item[0]) { - $formattedValue = sprintf("'%s'", $this->escapeHtml($item[1])); } elseif ('null' === $item[0]) { $formattedValue = 'null'; } elseif ('boolean' === $item[0]) { @@ -439,7 +383,7 @@ private function formatArgs(array $args) } elseif ('resource' === $item[0]) { $formattedValue = 'resource'; } else { - $formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true)); + $formattedValue = str_replace("\n", '', $this->escapeHtml(var_export($item[1], true))); } $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue); @@ -448,49 +392,11 @@ private function formatArgs(array $args) return implode(', ', $result); } - /** - * Returns an UTF-8 and HTML encoded string. - * - * @deprecated since version 2.7, to be removed in 3.0. - */ - protected static function utf8Htmlize($str) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); - - return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8'); - } - /** * HTML-encodes a string. */ private function escapeHtml($str) { - return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset); - } - - /** - * @internal - */ - public function catchOutput($buffer) - { - $this->caughtBuffer = $buffer; - - return ''; - } - - /** - * @internal - */ - public function cleanOutput($buffer) - { - if ($this->caughtLength) { - // use substr_replace() instead of substr() for mbstring overloading resistance - $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength); - if (isset($cleanBuffer[0])) { - $buffer = $cleanBuffer; - } - } - - return $buffer; + return htmlspecialchars($str, ENT_COMPAT | ENT_SUBSTITUTE, $this->charset); } } diff --git a/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php index abfe90d7..32ba9a09 100644 --- a/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php +++ b/vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php @@ -16,7 +16,6 @@ use Symfony\Component\Debug\DebugClassLoader; use Composer\Autoload\ClassLoader as ComposerClassLoader; use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader; -use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader; /** * ErrorHandler for classes that do not exist. @@ -101,17 +100,12 @@ private function getClassCandidates($class) if ($function[0] instanceof DebugClassLoader) { $function = $function[0]->getClassLoader(); - // @deprecated since version 2.5. Returning an object from DebugClassLoader::getClassLoader() is deprecated. - if (is_object($function)) { - $function = array($function); - } - if (!is_array($function)) { continue; } } - if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) { + if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader) { foreach ($function[0]->getPrefixes() as $prefix => $paths) { foreach ($paths as $path) { $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix)); @@ -179,7 +173,7 @@ private function convertFileToClass($path, $file, $prefix) ); if ($prefix) { - $candidates = array_filter($candidates, function ($candidate) use ($prefix) {return 0 === strpos($candidate, $prefix);}); + $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); }); } // We cannot use the autoloader here as most of them use require; but if the class @@ -207,6 +201,6 @@ private function convertFileToClass($path, $file, $prefix) */ private function classExists($class) { - return class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false)); + return class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false); } } diff --git a/vendor/symfony/debug/composer.json b/vendor/symfony/debug/composer.json index e739f756..5c40bea3 100644 --- a/vendor/symfony/debug/composer.json +++ b/vendor/symfony/debug/composer.json @@ -16,15 +16,15 @@ } ], "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "psr/log": "~1.0" }, "conflict": { "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0" + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Debug\\": "" }, @@ -35,7 +35,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/debug/phpunit.xml.dist b/vendor/symfony/debug/phpunit.xml.dist index e99c4ddf..12e58612 100644 --- a/vendor/symfony/debug/phpunit.xml.dist +++ b/vendor/symfony/debug/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/dependency-injection/CHANGELOG.md b/vendor/symfony/dependency-injection/CHANGELOG.md index 27cb2d58..43f44573 100644 --- a/vendor/symfony/dependency-injection/CHANGELOG.md +++ b/vendor/symfony/dependency-injection/CHANGELOG.md @@ -1,6 +1,20 @@ CHANGELOG ========= +3.2.0 +----- + + * allowed to prioritize compiler passes by introducing a third argument to `PassConfig::addPass()`, to `Compiler::addPass` and to `ContainerBuilder::addCompilerPass()` + * added support for PHP constants in YAML configuration files + * deprecated the ability to set or unset a private service with the `Container::set()` method + * deprecated the ability to check for the existence of a private service with the `Container::has()` method + * deprecated the ability to request a private service with the `Container::get()` method + +3.0.0 +----- + + * removed all deprecated codes from 2.x versions + 2.8.0 ----- diff --git a/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php index 681f8afd..717fc378 100644 --- a/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php +++ b/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php @@ -69,9 +69,6 @@ public function process(ContainerBuilder $container) $this->currentDefinition = $definition; $this->processArguments($definition->getArguments()); - if ($definition->getFactoryService(false)) { - $this->processArguments(array(new Reference($definition->getFactoryService(false)))); - } if (is_array($definition->getFactory())) { $this->processArguments($definition->getFactory()); } @@ -116,9 +113,6 @@ private function processArguments(array $arguments) if (is_array($argument->getFactory())) { $this->processArguments($argument->getFactory()); } - if ($argument->getFactoryService(false)) { - $this->processArguments(array(new Reference($argument->getFactoryService(false)))); - } } } } diff --git a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php index cd5b61b2..ae1f24d3 100644 --- a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php +++ b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Config\AutowireServiceResource; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\RuntimeException; @@ -27,7 +28,8 @@ class AutowirePass implements CompilerPassInterface private $reflectionClasses = array(); private $definedTypes = array(); private $types; - private $notGuessableTypes = array(); + private $ambiguousServiceTypes = array(); + private $autowired = array(); /** * {@inheritdoc} @@ -44,22 +46,38 @@ public function process(ContainerBuilder $container) $this->completeDefinition($id, $definition); } } - } catch (\Exception $e) { - } catch (\Throwable $e) { + } finally { + spl_autoload_unregister($throwingAutoloader); + + // Free memory and remove circular reference to container + $this->reflectionClasses = array(); + $this->definedTypes = array(); + $this->types = null; + $this->ambiguousServiceTypes = array(); + $this->autowired = array(); } + } - spl_autoload_unregister($throwingAutoloader); + /** + * Creates a resource to help know if this service has changed. + * + * @param \ReflectionClass $reflectionClass + * + * @return AutowireServiceResource + */ + public static function createResourceForClass(\ReflectionClass $reflectionClass) + { + $metadata = array(); - // Free memory and remove circular reference to container - $this->container = null; - $this->reflectionClasses = array(); - $this->definedTypes = array(); - $this->types = null; - $this->notGuessableTypes = array(); + if ($constructor = $reflectionClass->getConstructor()) { + $metadata['__construct'] = self::getResourceMetadataForMethod($constructor); + } - if (isset($e)) { - throw $e; + foreach (self::getSetters($reflectionClass) as $reflectionMethod) { + $metadata[$reflectionMethod->name] = self::getResourceMetadataForMethod($reflectionMethod); } + + return new AutowireServiceResource($reflectionClass->name, $reflectionClass->getFileName(), $metadata); } /** @@ -72,24 +90,38 @@ public function process(ContainerBuilder $container) */ private function completeDefinition($id, Definition $definition) { + if ($definition->getFactory()) { + throw new RuntimeException(sprintf('Service "%s" can use either autowiring or a factory, not both.', $id)); + } + if (!$reflectionClass = $this->getReflectionClass($id, $definition)) { return; } - $this->container->addClassResource($reflectionClass); + if ($this->container->isTrackingResources()) { + $this->container->addResource(static::createResourceForClass($reflectionClass)); + } if (!$constructor = $reflectionClass->getConstructor()) { return; } + $parameters = $constructor->getParameters(); + if (method_exists('ReflectionMethod', 'isVariadic') && $constructor->isVariadic()) { + array_pop($parameters); + } $arguments = $definition->getArguments(); - foreach ($constructor->getParameters() as $index => $parameter) { + foreach ($parameters as $index => $parameter) { if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) { continue; } try { if (!$typeHint = $parameter->getClass()) { + if (isset($arguments[$index])) { + continue; + } + // no default value? Then fail if (!$parameter->isOptional()) { throw new RuntimeException(sprintf('Unable to autowire argument index %d ($%s) for the service "%s". If this is an object, give it a type-hint. Otherwise, specify this argument\'s value explicitly.', $index, $parameter->name, $id)); @@ -101,23 +133,29 @@ private function completeDefinition($id, Definition $definition) continue; } + if (isset($this->autowired[$typeHint->name])) { + $arguments[$index] = $this->autowired[$typeHint->name] ? new Reference($this->autowired[$typeHint->name]) : null; + continue; + } + if (null === $this->types) { $this->populateAvailableTypes(); } - if (isset($this->types[$typeHint->name]) && !isset($this->notGuessableTypes[$typeHint->name])) { + if (isset($this->types[$typeHint->name])) { $value = new Reference($this->types[$typeHint->name]); } else { try { $value = $this->createAutowiredDefinition($typeHint, $id); } catch (RuntimeException $e) { - if ($parameter->allowsNull()) { - $value = null; - } elseif ($parameter->isDefaultValueAvailable()) { + if ($parameter->isDefaultValueAvailable()) { $value = $parameter->getDefaultValue(); + } elseif ($parameter->allowsNull()) { + $value = null; } else { throw $e; } + $this->autowired[$typeHint->name] = false; } } } catch (\ReflectionException $e) { @@ -133,6 +171,16 @@ private function completeDefinition($id, Definition $definition) $arguments[$index] = $value; } + if ($parameters && !isset($arguments[++$index])) { + while (0 <= --$index) { + $parameter = $parameters[$index]; + if (!$parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== $arguments[$index]) { + break; + } + unset($arguments[$index]); + } + } + // it's possible index 1 was set, then index 0, then 2, etc // make sure that we re-order so they're injected as expected ksort($arguments); @@ -167,6 +215,7 @@ private function populateAvailableType($id, Definition $definition) foreach ($definition->getAutowiringTypes() as $type) { $this->definedTypes[$type] = true; $this->types[$type] = $id; + unset($this->ambiguousServiceTypes[$type]); } if (!$reflectionClass = $this->getReflectionClass($id, $definition)) { @@ -194,22 +243,26 @@ private function set($type, $id) return; } - if (!isset($this->types[$type])) { - $this->types[$type] = $id; + // is this already a type/class that is known to match multiple services? + if (isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type][] = $id; return; } - if ($this->types[$type] === $id) { + // check to make sure the type doesn't match multiple services + if (!isset($this->types[$type]) || $this->types[$type] === $id) { + $this->types[$type] = $id; + return; } - if (!isset($this->notGuessableTypes[$type])) { - $this->notGuessableTypes[$type] = true; - $this->types[$type] = (array) $this->types[$type]; + // keep an array of all services matching this type + if (!isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type] = array($this->types[$type]); + unset($this->types[$type]); } - - $this->types[$type][] = $id; + $this->ambiguousServiceTypes[$type][] = $id; } /** @@ -224,9 +277,9 @@ private function set($type, $id) */ private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) { - if (isset($this->notGuessableTypes[$typeHint->name])) { + if (isset($this->ambiguousServiceTypes[$typeHint->name])) { $classOrInterface = $typeHint->isInterface() ? 'interface' : 'class'; - $matchingServices = implode(', ', $this->types[$typeHint->name]); + $matchingServices = implode(', ', $this->ambiguousServiceTypes[$typeHint->name]); throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices)); } @@ -236,13 +289,11 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface)); } - $argumentId = sprintf('autowired.%s', $typeHint->name); + $this->autowired[$typeHint->name] = $argumentId = sprintf('autowired.%s', $typeHint->name); $argumentDefinition = $this->container->register($argumentId, $typeHint->name); $argumentDefinition->setPublic(false); - $this->populateAvailableType($argumentId, $argumentDefinition); - try { $this->completeDefinition($argumentId, $argumentDefinition); } catch (RuntimeException $e) { @@ -275,12 +326,67 @@ private function getReflectionClass($id, Definition $definition) $class = $this->container->getParameterBag()->resolveValue($class); + if ($deprecated = $definition->isDeprecated()) { + $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) { + return (E_USER_DEPRECATED === $level || !$prevErrorHandler) ? false : $prevErrorHandler($level, $message, $file, $line); + }); + } + + $e = null; + try { $reflector = new \ReflectionClass($class); - } catch (\ReflectionException $e) { + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if ($deprecated) { + restore_error_handler(); + } + + if (null !== $e) { + if (!$e instanceof \ReflectionException) { + throw $e; + } $reflector = false; } return $this->reflectionClasses[$id] = $reflector; } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return \ReflectionMethod[] + */ + private static function getSetters(\ReflectionClass $reflectionClass) + { + foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) { + if (!$reflectionMethod->isStatic() && 1 === $reflectionMethod->getNumberOfParameters() && 0 === strpos($reflectionMethod->name, 'set')) { + yield $reflectionMethod; + } + } + } + + private static function getResourceMetadataForMethod(\ReflectionMethod $method) + { + $methodArgumentsMetadata = array(); + foreach ($method->getParameters() as $parameter) { + try { + $class = $parameter->getClass(); + } catch (\ReflectionException $e) { + // type-hint is against a non-existent class + $class = false; + } + + $isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic(); + $methodArgumentsMetadata[] = array( + 'class' => $class, + 'isOptional' => $parameter->isOptional(), + 'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null, + ); + } + + return $methodArgumentsMetadata; + } } diff --git a/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php index 156bcc0c..f39a89af 100644 --- a/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php +++ b/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php @@ -60,7 +60,6 @@ private function checkOutEdges(array $edges) $id = $node->getId(); if (empty($this->checkedNodes[$id])) { - // don't check circular dependencies for lazy services if (!$node->getValue() || !$node->getValue()->isLazy()) { $searchKey = array_search($id, $this->currentPath); diff --git a/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php b/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php index e54ee60a..0d21ef28 100644 --- a/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php +++ b/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php @@ -11,7 +11,6 @@ namespace Symfony\Component\DependencyInjection\Compiler; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\RuntimeException; @@ -24,8 +23,6 @@ * * - non synthetic, non abstract services always have a class set * - synthetic services are always public - * - synthetic services are always of non-prototype scope - * - shared services are always of non-prototype scope * * @author Johannes M. Schmitt */ @@ -46,23 +43,9 @@ public function process(ContainerBuilder $container) throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id)); } - // synthetic service has non-prototype scope - if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) { - throw new RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id)); - } - - // shared service has non-prototype scope - if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) { - throw new RuntimeException(sprintf('A shared service ("%s") cannot be of scope "prototype".', $id)); - } - - if ($definition->getFactory() && ($definition->getFactoryClass(false) || $definition->getFactoryService(false) || $definition->getFactoryMethod(false))) { - throw new RuntimeException(sprintf('A service ("%s") can use either the old or the new factory syntax, not both.', $id)); - } - // non-synthetic, non-abstract service has class if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) { - if ($definition->getFactory() || $definition->getFactoryClass(false) || $definition->getFactoryService(false)) { + if ($definition->getFactory()) { throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); } diff --git a/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php b/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php index ac4072a8..80b81d69 100644 --- a/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php +++ b/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php @@ -12,20 +12,15 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\RuntimeException; -use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException; -use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException; /** * Checks the validity of references. * * The following checks are performed by this pass: * - target definitions are not abstract - * - target definitions are of equal or wider scope - * - target definitions are in the same scope hierarchy * * @author Johannes M. Schmitt */ @@ -33,9 +28,6 @@ class CheckReferenceValidityPass implements CompilerPassInterface { private $container; private $currentId; - private $currentScope; - private $currentScopeAncestors; - private $currentScopeChildren; /** * Processes the ContainerBuilder to validate References. @@ -46,33 +38,12 @@ public function process(ContainerBuilder $container) { $this->container = $container; - $children = $this->container->getScopeChildren(false); - $ancestors = array(); - - $scopes = $this->container->getScopes(false); - foreach ($scopes as $name => $parent) { - $ancestors[$name] = array($parent); - - while (isset($scopes[$parent])) { - $ancestors[$name][] = $parent = $scopes[$parent]; - } - } - foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isSynthetic() || $definition->isAbstract()) { continue; } $this->currentId = $id; - $this->currentScope = $scope = $definition->getScope(false); - - if (ContainerInterface::SCOPE_CONTAINER === $scope) { - $this->currentScopeChildren = array_keys($scopes); - $this->currentScopeAncestors = array(); - } elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) { - $this->currentScopeChildren = isset($children[$scope]) ? $children[$scope] : array(); - $this->currentScopeAncestors = isset($ancestors[$scope]) ? $ancestors[$scope] : array(); - } $this->validateReferences($definition->getArguments()); $this->validateReferences($definition->getMethodCalls()); @@ -103,50 +74,10 @@ private function validateReferences(array $arguments) $argument )); } - - $this->validateScope($argument, $targetDefinition); } } } - /** - * Validates the scope of a single Reference. - * - * @param Reference $reference - * @param Definition $definition - * - * @throws ScopeWideningInjectionException when the definition references a service of a narrower scope - * @throws ScopeCrossingInjectionException when the definition references a service of another scope hierarchy - */ - private function validateScope(Reference $reference, Definition $definition = null) - { - if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) { - return; - } - - if (!$reference->isStrict(false)) { - return; - } - - if (null === $definition) { - return; - } - - if ($this->currentScope === $scope = $definition->getScope(false)) { - return; - } - - $id = (string) $reference; - - if (in_array($scope, $this->currentScopeChildren, true)) { - throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope); - } - - if (!in_array($scope, $this->currentScopeAncestors, true)) { - throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope); - } - } - /** * Returns the Definition given an id. * diff --git a/vendor/symfony/dependency-injection/Compiler/Compiler.php b/vendor/symfony/dependency-injection/Compiler/Compiler.php index 1f6304ee..cd49e7b8 100644 --- a/vendor/symfony/dependency-injection/Compiler/Compiler.php +++ b/vendor/symfony/dependency-injection/Compiler/Compiler.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; /** * This class is used to remove circular dependencies between individual passes. @@ -65,12 +66,26 @@ public function getLoggingFormatter() /** * Adds a pass to the PassConfig. * - * @param CompilerPassInterface $pass A compiler pass - * @param string $type The type of the pass + * @param CompilerPassInterface $pass A compiler pass + * @param string $type The type of the pass + * @param int $priority Used to sort the passes */ - public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION) + public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, $priority = 0*/) { - $this->passConfig->addPass($pass, $type); + if (func_num_args() >= 3) { + $priority = func_get_arg(2); + } else { + if (__CLASS__ !== get_class($this)) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s() will have a third `$priority = 0` argument in version 4.0. Not defining it is deprecated since 3.2.', __METHOD__), E_USER_DEPRECATED); + } + } + + $priority = 0; + } + + $this->passConfig->addPass($pass, $type, $priority); } /** @@ -100,8 +115,29 @@ public function getLog() */ public function compile(ContainerBuilder $container) { - foreach ($this->passConfig->getPasses() as $pass) { - $pass->process($container); + try { + foreach ($this->passConfig->getPasses() as $pass) { + $pass->process($container); + } + } catch (\Exception $e) { + $usedEnvs = array(); + $prev = $e; + + do { + $msg = $prev->getMessage(); + + if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) { + $r = new \ReflectionProperty($prev, 'message'); + $r->setAccessible(true); + $r->setValue($prev, $resolvedMsg); + } + } while ($prev = $prev->getPrevious()); + + if ($usedEnvs) { + $e = new EnvParameterException($usedEnvs, $e); + } + + throw $e; } } } diff --git a/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php b/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php index 2c4c79d6..8edb717b 100644 --- a/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php +++ b/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php @@ -35,8 +35,7 @@ public function process(ContainerBuilder $container) $definitions->insert(array($id, $definition), array($decorated[2], --$order)); } - foreach ($definitions as $arr) { - list($id, $definition) = $arr; + foreach ($definitions as list($id, $definition)) { list($inner, $renamedId) = $definition->getDecoratedService(); $definition->setDecoratedService(null); diff --git a/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php b/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php new file mode 100644 index 00000000..e4e64db4 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Guilhem N. + */ +class FactoryReturnTypePass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + // works only since php 7.0 and hhvm 3.11 + if (!method_exists(\ReflectionMethod::class, 'getReturnType')) { + return; + } + + foreach ($container->getDefinitions() as $id => $definition) { + $this->updateDefinition($container, $id, $definition); + } + } + + private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $previous = array()) + { + // circular reference + if (isset($previous[$id])) { + return; + } + + $factory = $definition->getFactory(); + if (null === $factory || null !== $definition->getClass()) { + return; + } + + $class = null; + if (is_string($factory)) { + try { + $m = new \ReflectionFunction($factory); + } catch (\ReflectionException $e) { + return; + } + } else { + if ($factory[0] instanceof Reference) { + $previous[$id] = true; + $factoryDefinition = $container->findDefinition((string) $factory[0]); + $this->updateDefinition($container, strtolower($factory[0]), $factoryDefinition, $previous); + $class = $factoryDefinition->getClass(); + } else { + $class = $factory[0]; + } + + try { + $m = new \ReflectionMethod($class, $factory[1]); + } catch (\ReflectionException $e) { + return; + } + } + + $returnType = $m->getReturnType(); + if (null !== $returnType && !$returnType->isBuiltin()) { + $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString(); + if (null !== $class) { + $declaringClass = $m->getDeclaringClass()->getName(); + if ('self' === strtolower($returnType)) { + $returnType = $declaringClass; + } elseif ('parent' === strtolower($returnType)) { + $returnType = get_parent_class($declaringClass) ?: null; + } + } + + $definition->setClass($returnType); + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php b/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php index 1beaaf0c..a4e2e041 100644 --- a/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php +++ b/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php @@ -11,7 +11,6 @@ namespace Symfony\Component\DependencyInjection\Compiler; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -73,10 +72,10 @@ private function inlineArguments(ContainerBuilder $container, array $arguments, continue; } - if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) { + if ($this->isInlineableDefinition($id, $definition = $container->getDefinition($id))) { $this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId)); - if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false)) { + if ($definition->isShared()) { $arguments[$k] = $definition; } else { $arguments[$k] = clone $definition; @@ -101,15 +100,14 @@ private function inlineArguments(ContainerBuilder $container, array $arguments, /** * Checks if the definition is inlineable. * - * @param ContainerBuilder $container - * @param string $id - * @param Definition $definition + * @param string $id + * @param Definition $definition * * @return bool If the definition is inlineable */ - private function isInlineableDefinition(ContainerBuilder $container, $id, Definition $definition) + private function isInlineableDefinition($id, Definition $definition) { - if (!$definition->isShared() || ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) { + if (!$definition->isShared()) { return true; } @@ -138,10 +136,6 @@ private function isInlineableDefinition(ContainerBuilder $container, $id, Defini return false; } - if (count($ids) > 1 && $definition->getFactoryService(false)) { - return false; - } - - return $container->getDefinition(reset($ids))->getScope(false) === $definition->getScope(false); + return true; } } diff --git a/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php b/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php index f9e60241..9434ac70 100644 --- a/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php +++ b/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; /** @@ -47,6 +48,9 @@ public function process(ContainerBuilder $container) $tmpContainer = new ContainerBuilder($container->getParameterBag()); $tmpContainer->setResourceTracking($container->isTrackingResources()); $tmpContainer->addObjectResource($extension); + if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) { + $tmpContainer->addObjectResource($configuration); + } foreach ($exprLangProviders as $provider) { $tmpContainer->addExpressionLanguageProvider($provider); diff --git a/vendor/symfony/dependency-injection/Compiler/PassConfig.php b/vendor/symfony/dependency-injection/Compiler/PassConfig.php index cc6e0e71..fefd5af3 100644 --- a/vendor/symfony/dependency-injection/Compiler/PassConfig.php +++ b/vendor/symfony/dependency-injection/Compiler/PassConfig.php @@ -39,11 +39,12 @@ public function __construct() { $this->mergePass = new MergeExtensionConfigurationPass(); - $this->optimizationPasses = array( + $this->optimizationPasses = array(array( new ExtensionCompilerPass(), new ResolveDefinitionTemplatesPass(), new DecoratorServicePass(), new ResolveParameterPlaceHoldersPass(), + new FactoryReturnTypePass(), new CheckDefinitionValidityPass(), new ResolveReferencesToAliasesPass(), new ResolveInvalidReferencesPass(), @@ -51,9 +52,9 @@ public function __construct() new AnalyzeServiceReferencesPass(true), new CheckCircularReferencesPass(), new CheckReferenceValidityPass(), - ); + )); - $this->removingPasses = array( + $this->removingPasses = array(array( new RemovePrivateAliasesPass(), new ReplaceAliasByActualDefinitionPass(), new RemoveAbstractDefinitionsPass(), @@ -64,98 +65,117 @@ public function __construct() new RemoveUnusedDefinitionsPass(), )), new CheckExceptionOnInvalidReferenceBehaviorPass(), - ); + )); } /** * Returns all passes in order to be processed. * - * @return array An array of all passes to process + * @return CompilerPassInterface[] */ public function getPasses() { return array_merge( array($this->mergePass), - $this->beforeOptimizationPasses, - $this->optimizationPasses, - $this->beforeRemovingPasses, - $this->removingPasses, - $this->afterRemovingPasses + $this->getBeforeOptimizationPasses(), + $this->getOptimizationPasses(), + $this->getBeforeRemovingPasses(), + $this->getRemovingPasses(), + $this->getAfterRemovingPasses() ); } /** * Adds a pass. * - * @param CompilerPassInterface $pass A Compiler pass - * @param string $type The pass type + * @param CompilerPassInterface $pass A Compiler pass + * @param string $type The pass type + * @param int $priority Used to sort the passes * * @throws InvalidArgumentException when a pass type doesn't exist */ - public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION) + public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION/*, $priority = 0*/) { + if (func_num_args() >= 3) { + $priority = func_get_arg(2); + } else { + if (__CLASS__ !== get_class($this)) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s() will have a third `$priority = 0` argument in version 4.0. Not defining it is deprecated since 3.2.', __METHOD__), E_USER_DEPRECATED); + } + } + + $priority = 0; + } + $property = $type.'Passes'; if (!isset($this->$property)) { throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type)); } - $this->{$property}[] = $pass; + $passes = &$this->$property; + + if (!isset($passes[$priority])) { + $passes[$priority] = array(); + } + $passes[$priority][] = $pass; } /** * Gets all passes for the AfterRemoving pass. * - * @return array An array of passes + * @return CompilerPassInterface[] */ public function getAfterRemovingPasses() { - return $this->afterRemovingPasses; + return $this->sortPasses($this->afterRemovingPasses); } /** * Gets all passes for the BeforeOptimization pass. * - * @return array An array of passes + * @return CompilerPassInterface[] */ public function getBeforeOptimizationPasses() { - return $this->beforeOptimizationPasses; + return $this->sortPasses($this->beforeOptimizationPasses); } /** * Gets all passes for the BeforeRemoving pass. * - * @return array An array of passes + * @return CompilerPassInterface[] */ public function getBeforeRemovingPasses() { - return $this->beforeRemovingPasses; + return $this->sortPasses($this->beforeRemovingPasses); } /** * Gets all passes for the Optimization pass. * - * @return array An array of passes + * @return CompilerPassInterface[] */ public function getOptimizationPasses() { - return $this->optimizationPasses; + return $this->sortPasses($this->optimizationPasses); } /** * Gets all passes for the Removing pass. * - * @return array An array of passes + * @return CompilerPassInterface[] */ public function getRemovingPasses() { - return $this->removingPasses; + return $this->sortPasses($this->removingPasses); } /** * Gets the Merge pass. * - * @return CompilerPassInterface The merge pass + * @return CompilerPassInterface */ public function getMergePass() { @@ -175,50 +195,69 @@ public function setMergePass(CompilerPassInterface $pass) /** * Sets the AfterRemoving passes. * - * @param array $passes An array of passes + * @param CompilerPassInterface[] $passes */ public function setAfterRemovingPasses(array $passes) { - $this->afterRemovingPasses = $passes; + $this->afterRemovingPasses = array($passes); } /** * Sets the BeforeOptimization passes. * - * @param array $passes An array of passes + * @param CompilerPassInterface[] $passes */ public function setBeforeOptimizationPasses(array $passes) { - $this->beforeOptimizationPasses = $passes; + $this->beforeOptimizationPasses = array($passes); } /** * Sets the BeforeRemoving passes. * - * @param array $passes An array of passes + * @param CompilerPassInterface[] $passes */ public function setBeforeRemovingPasses(array $passes) { - $this->beforeRemovingPasses = $passes; + $this->beforeRemovingPasses = array($passes); } /** * Sets the Optimization passes. * - * @param array $passes An array of passes + * @param CompilerPassInterface[] $passes */ public function setOptimizationPasses(array $passes) { - $this->optimizationPasses = $passes; + $this->optimizationPasses = array($passes); } /** * Sets the Removing passes. * - * @param array $passes An array of passes + * @param CompilerPassInterface[] $passes */ public function setRemovingPasses(array $passes) { - $this->removingPasses = $passes; + $this->removingPasses = array($passes); + } + + /** + * Sort passes by priority. + * + * @param array $passes CompilerPassInterface instances with their priority as key + * + * @return CompilerPassInterface[] + */ + private function sortPasses(array $passes) + { + if (0 === count($passes)) { + return array(); + } + + krsort($passes); + + // Flatten the array + return call_user_func_array('array_merge', $passes); } } diff --git a/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php b/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php new file mode 100644 index 00000000..64c041e9 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Trait that allows a generic method to find and sort service by priority option in the tag. + * + * @author Iltar van der Berg + */ +trait PriorityTaggedServiceTrait +{ + /** + * Finds all services with the given tag name and order them by their priority. + * + * The order of additions must be respected for services having the same priority, + * and knowing that the \SplPriorityQueue class does not respect the FIFO method, + * we should not use this class. + * + * @see https://bugs.php.net/bug.php?id=53710 + * @see https://bugs.php.net/bug.php?id=60926 + * + * @param string $tagName + * @param ContainerBuilder $container + * + * @return Reference[] + */ + private function findAndSortTaggedServices($tagName, ContainerBuilder $container) + { + $services = array(); + + foreach ($container->findTaggedServiceIds($tagName) as $serviceId => $attributes) { + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; + $services[$priority][] = new Reference($serviceId); + } + + if ($services) { + krsort($services); + $services = call_user_func_array('array_merge', $services); + } + + return $services; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php b/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php index 9e18a9eb..8252f73f 100644 --- a/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php +++ b/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php @@ -72,6 +72,7 @@ public function process(ContainerBuilder $container) $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias '.reset($referencingAliases))); } elseif (0 === count($referencingAliases) && false === $isReferenced) { $container->removeDefinition($id); + $container->resolveEnvPlaceholders(serialize($definition)); $compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused')); $hasChanged = true; } diff --git a/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php b/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php index 5c58656a..85c1cf54 100644 --- a/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php +++ b/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -51,7 +51,7 @@ public function process(ContainerBuilder $container) if (isset($replacements[$targetId])) { $container->setAlias($definitionId, $replacements[$targetId]); } - // No neeed to process the same target twice + // No need to process the same target twice if (isset($seenAliasTargets[$targetId])) { continue; } @@ -77,7 +77,6 @@ public function process(ContainerBuilder $container) $definition->setArguments($this->updateArgumentReferences($replacements, $definitionId, $definition->getArguments())); $definition->setMethodCalls($this->updateArgumentReferences($replacements, $definitionId, $definition->getMethodCalls())); $definition->setProperties($this->updateArgumentReferences($replacements, $definitionId, $definition->getProperties())); - $definition->setFactoryService($this->updateFactoryReferenceId($replacements, $definition->getFactoryService(false)), false); $definition->setFactory($this->updateFactoryReference($replacements, $definition->getFactory())); } } @@ -116,23 +115,6 @@ private function updateArgumentReferences(array $replacements, $definitionId, ar return $arguments; } - /** - * Returns the updated reference for the factory service. - * - * @param array $replacements Table of aliases to replace - * @param string|null $referenceId Factory service reference identifier - * - * @return string|null - */ - private function updateFactoryReferenceId(array $replacements, $referenceId) - { - if (null === $referenceId) { - return; - } - - return isset($replacements[$referenceId]) ? $replacements[$referenceId] : $referenceId; - } - private function updateFactoryReference(array $replacements, $factory) { if (is_array($factory) && $factory[0] instanceof Reference && isset($replacements[$referenceId = (string) $factory[0]])) { diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php index 4f8cd2b7..a755fd61 100644 --- a/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php +++ b/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php @@ -14,6 +14,7 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ExceptionInterface; use Symfony\Component\DependencyInjection\Exception\RuntimeException; /** @@ -96,11 +97,24 @@ private function resolveArguments(ContainerBuilder $container, array $arguments, */ private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition) { - if (!$container->hasDefinition($parent = $definition->getParent())) { - throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId)); + try { + return $this->doResolveDefinition($container, $definition); + } catch (ExceptionInterface $e) { + $r = new \ReflectionProperty($e, 'message'); + $r->setAccessible(true); + $r->setValue($e, sprintf('Service "%s": %s', $this->currentId, $e->getMessage())); + + throw $e; + } + } + + private function doResolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition) + { + if (!$container->has($parent = $definition->getParent())) { + throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent)); } - $parentDef = $container->getDefinition($parent); + $parentDef = $container->findDefinition($parent); if ($parentDef instanceof DefinitionDecorator) { $id = $this->currentId; $this->currentId = $parent; @@ -113,21 +127,12 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora $def = new Definition(); // merge in parent definition - // purposely ignored attributes: scope, abstract, tags + // purposely ignored attributes: abstract, tags $def->setClass($parentDef->getClass()); $def->setArguments($parentDef->getArguments()); $def->setMethodCalls($parentDef->getMethodCalls()); $def->setProperties($parentDef->getProperties()); $def->setAutowiringTypes($parentDef->getAutowiringTypes()); - if ($parentDef->getFactoryClass(false)) { - $def->setFactoryClass($parentDef->getFactoryClass(false)); - } - if ($parentDef->getFactoryMethod(false)) { - $def->setFactoryMethod($parentDef->getFactoryMethod(false)); - } - if ($parentDef->getFactoryService(false)) { - $def->setFactoryService($parentDef->getFactoryService(false)); - } if ($parentDef->isDeprecated()) { $def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%')); } @@ -143,15 +148,6 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora if (isset($changes['class'])) { $def->setClass($definition->getClass()); } - if (isset($changes['factory_class'])) { - $def->setFactoryClass($definition->getFactoryClass(false)); - } - if (isset($changes['factory_method'])) { - $def->setFactoryMethod($definition->getFactoryMethod(false)); - } - if (isset($changes['factory_service'])) { - $def->setFactoryService($definition->getFactoryService(false)); - } if (isset($changes['factory'])) { $def->setFactory($definition->getFactory()); } @@ -214,7 +210,6 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora // these attributes are always taken from the child $def->setAbstract($definition->isAbstract()); - $def->setScope($definition->getScope(false), false); $def->setShared($definition->isShared()); $def->setTags($definition->getTags()); diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php index 85dbceb9..5b58fb1e 100644 --- a/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php +++ b/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php @@ -71,16 +71,19 @@ public function process(ContainerBuilder $container) * * @param array $arguments An array of Reference objects * @param bool $inMethodCall + * @param bool $inCollection * * @return array * * @throws RuntimeException When the config is invalid */ - private function processArguments(array $arguments, $inMethodCall = false) + private function processArguments(array $arguments, $inMethodCall = false, $inCollection = false) { + $isNumeric = array_keys($arguments) === range(0, count($arguments) - 1); + foreach ($arguments as $k => $argument) { if (is_array($argument)) { - $arguments[$k] = $this->processArguments($argument, $inMethodCall); + $arguments[$k] = $this->processArguments($argument, $inMethodCall, true); } elseif ($argument instanceof Reference) { $id = (string) $argument; @@ -91,6 +94,10 @@ private function processArguments(array $arguments, $inMethodCall = false) if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { $arguments[$k] = null; } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + if ($inCollection) { + unset($arguments[$k]); + continue; + } if ($inMethodCall) { throw new RuntimeException('Method shouldn\'t be called.'); } @@ -100,6 +107,11 @@ private function processArguments(array $arguments, $inMethodCall = false) } } + // Ensure numerically indexed arguments have sequential numeric keys. + if ($isNumeric) { + $arguments = array_values($arguments); + } + return $arguments; } } diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php index a35f84cb..0c5963cc 100644 --- a/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php +++ b/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php @@ -37,9 +37,6 @@ public function process(ContainerBuilder $container) $definition->setClass($parameterBag->resolveValue($definition->getClass())); $definition->setFile($parameterBag->resolveValue($definition->getFile())); $definition->setArguments($parameterBag->resolveValue($definition->getArguments())); - if ($definition->getFactoryClass(false)) { - $definition->setFactoryClass($parameterBag->resolveValue($definition->getFactoryClass(false))); - } $factory = $definition->getFactory(); diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php index c200cb4d..8514739a 100644 --- a/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php +++ b/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php @@ -43,7 +43,6 @@ public function process(ContainerBuilder $container) $definition->setMethodCalls($this->processArguments($definition->getMethodCalls())); $definition->setProperties($this->processArguments($definition->getProperties())); $definition->setFactory($this->processFactory($definition->getFactory())); - $definition->setFactoryService($this->processFactoryService($definition->getFactoryService(false)), false); } foreach ($container->getAliases() as $id => $alias) { @@ -70,7 +69,7 @@ private function processArguments(array $arguments) $defId = $this->getDefinitionId($id = (string) $argument); if ($defId !== $id) { - $arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict(false)); + $arguments[$k] = new Reference($defId, $argument->getInvalidBehavior()); } } } @@ -78,15 +77,6 @@ private function processArguments(array $arguments) return $arguments; } - private function processFactoryService($factoryService) - { - if (null === $factoryService) { - return; - } - - return $this->getDefinitionId($factoryService); - } - private function processFactory($factory) { if (null === $factory || !is_array($factory) || !$factory[0] instanceof Reference) { @@ -96,7 +86,7 @@ private function processFactory($factory) $defId = $this->getDefinitionId($id = (string) $factory[0]); if ($defId !== $id) { - $factory[0] = new Reference($defId, $factory[0]->getInvalidBehavior(), $factory[0]->isStrict(false)); + $factory[0] = new Reference($defId, $factory[0]->getInvalidBehavior()); } return $factory; diff --git a/vendor/symfony/dependency-injection/Config/AutowireServiceResource.php b/vendor/symfony/dependency-injection/Config/AutowireServiceResource.php new file mode 100644 index 00000000..36449d8d --- /dev/null +++ b/vendor/symfony/dependency-injection/Config/AutowireServiceResource.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Config; + +use Symfony\Component\Config\Resource\SelfCheckingResourceInterface; +use Symfony\Component\DependencyInjection\Compiler\AutowirePass; + +class AutowireServiceResource implements SelfCheckingResourceInterface, \Serializable +{ + private $class; + private $filePath; + private $autowiringMetadata = array(); + + public function __construct($class, $path, array $autowiringMetadata) + { + $this->class = $class; + $this->filePath = $path; + $this->autowiringMetadata = $autowiringMetadata; + } + + public function isFresh($timestamp) + { + if (!file_exists($this->filePath)) { + return false; + } + + // has the file *not* been modified? Definitely fresh + if (@filemtime($this->filePath) <= $timestamp) { + return true; + } + + try { + $reflectionClass = new \ReflectionClass($this->class); + } catch (\ReflectionException $e) { + // the class does not exist anymore! + return false; + } + + return (array) $this === (array) AutowirePass::createResourceForClass($reflectionClass); + } + + public function __toString() + { + return 'service.autowire.'.$this->class; + } + + public function serialize() + { + return serialize(array($this->class, $this->filePath, $this->autowiringMetadata)); + } + + public function unserialize($serialized) + { + list($this->class, $this->filePath, $this->autowiringMetadata) = unserialize($serialized); + } + + /** + * @deprecated Implemented for compatibility with Symfony 2.8 + */ + public function getResource() + { + return $this->filePath; + } +} diff --git a/vendor/symfony/dependency-injection/Container.php b/vendor/symfony/dependency-injection/Container.php index ea804c70..da84d18a 100644 --- a/vendor/symfony/dependency-injection/Container.php +++ b/vendor/symfony/dependency-injection/Container.php @@ -11,14 +11,12 @@ namespace Symfony\Component\DependencyInjection; -use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; +use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; -use Symfony\Component\DependencyInjection\Exception\LogicException; -use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; /** @@ -59,7 +57,7 @@ * @author Fabien Potencier * @author Johannes M. Schmitt */ -class Container implements IntrospectableContainerInterface, ResettableContainerInterface +class Container implements ResettableContainerInterface { /** * @var ParameterBagInterface @@ -68,21 +66,19 @@ class Container implements IntrospectableContainerInterface, ResettableContainer protected $services = array(); protected $methodMap = array(); + protected $privates = array(); protected $aliases = array(); - protected $scopes = array(); - protected $scopeChildren = array(); - protected $scopedServices = array(); - protected $scopeStacks = array(); protected $loading = array(); private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_'); + private $envCache = array(); /** * @param ParameterBagInterface $parameterBag A ParameterBagInterface instance */ public function __construct(ParameterBagInterface $parameterBag = null) { - $this->parameterBag = $parameterBag ?: new ParameterBag(); + $this->parameterBag = $parameterBag ?: new EnvPlaceholderParameterBag(); } /** @@ -163,39 +159,15 @@ public function setParameter($name, $value) * Setting a service to null resets the service: has() returns false and get() * behaves in the same way as if the service was never created. * - * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0. - * * @param string $id The service identifier * @param object $service The service instance - * @param string $scope The scope of the service - * - * @throws RuntimeException When trying to set a service in an inactive scope - * @throws InvalidArgumentException When trying to set a service in the prototype scope */ - public function set($id, $service, $scope = self::SCOPE_CONTAINER) + public function set($id, $service) { - if (!in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) { - @trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED); - } - - if (self::SCOPE_PROTOTYPE === $scope) { - throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id)); - } - $id = strtolower($id); if ('service_container' === $id) { - // BC: 'service_container' is no longer a self-reference but always - // $this, so ignore this call. - // @todo Throw InvalidArgumentException in next major release. - return; - } - if (self::SCOPE_CONTAINER !== $scope) { - if (!isset($this->scopedServices[$scope])) { - throw new RuntimeException(sprintf('You cannot set service "%s" of inactive scope.', $id)); - } - - $this->scopedServices[$scope][$id] = $service; + throw new InvalidArgumentException('You cannot set service "service_container".'); } if (isset($this->aliases[$id])) { @@ -204,16 +176,17 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER) $this->services[$id] = $service; - if (method_exists($this, $method = 'synchronize'.strtr($id, $this->underscoreMap).'Service')) { - $this->$method(); + if (null === $service) { + unset($this->services[$id]); } - if (null === $service) { - if (self::SCOPE_CONTAINER !== $scope) { - unset($this->scopedServices[$scope][$id]); + if (isset($this->privates[$id])) { + if (null === $service) { + @trigger_error(sprintf('Unsetting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); + unset($this->privates[$id]); + } else { + @trigger_error(sprintf('Setting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0. A new public service will be created instead.', $id), E_USER_DEPRECATED); } - - unset($this->services[$id]); } } @@ -230,15 +203,32 @@ public function has($id) if ('service_container' === $id || isset($this->aliases[$id]) || isset($this->services[$id]) - || array_key_exists($id, $this->services) ) { return true; } + + if (isset($this->privates[$id])) { + @trigger_error(sprintf('Checking for the existence of the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); + } + + if (isset($this->methodMap[$id])) { + return true; + } + if (--$i && $id !== $lcId = strtolower($id)) { $id = $lcId; - } else { - return method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service'); + continue; + } + + // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, + // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) + if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service')) { + @trigger_error('Generating a dumped container without populating the method map is deprecated since 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED); + + return true; } + + return false; } } @@ -273,7 +263,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE $id = $this->aliases[$id]; } // Re-use shared service instance if it exists. - if (isset($this->services[$id]) || array_key_exists($id, $this->services)) { + if (isset($this->services[$id])) { return $this->services[$id]; } @@ -286,7 +276,10 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE } elseif (--$i && $id !== $lcId = strtolower($id)) { $id = $lcId; continue; - } elseif (method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) { + } elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) { + // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, + // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) + @trigger_error('Generating a dumped container without populating the method map is deprecated since 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED); // $method is set to the right value, proceed } else { if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { @@ -307,29 +300,22 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE return; } + if (isset($this->privates[$id])) { + @trigger_error(sprintf('Requesting the "%s" private service is deprecated since Symfony 3.2 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED); + } $this->loading[$id] = true; try { $service = $this->$method(); } catch (\Exception $e) { - unset($this->loading[$id]); unset($this->services[$id]); - if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { - return; - } - throw $e; - } catch (\Throwable $e) { + } finally { unset($this->loading[$id]); - unset($this->services[$id]); - - throw $e; } - unset($this->loading[$id]); - return $service; } } @@ -346,16 +332,14 @@ public function initialized($id) $id = strtolower($id); if ('service_container' === $id) { - // BC: 'service_container' was a synthetic service previously. - // @todo Change to false in next major release. - return true; + return false; } if (isset($this->aliases[$id])) { $id = $this->aliases[$id]; } - return isset($this->services[$id]) || array_key_exists($id, $this->services); + return isset($this->services[$id]); } /** @@ -363,10 +347,6 @@ public function initialized($id) */ public function reset() { - if (!empty($this->scopedServices)) { - throw new LogicException('Resetting the container is not allowed when a scope is active.'); - } - $this->services = array(); } @@ -378,215 +358,72 @@ public function reset() public function getServiceIds() { $ids = array(); - foreach (get_class_methods($this) as $method) { - if (preg_match('/^get(.+)Service$/', $method, $match)) { - $ids[] = self::underscore($match[1]); + + if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class) { + // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, + // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) + @trigger_error('Generating a dumped container without populating the method map is deprecated since 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED); + + foreach (get_class_methods($this) as $method) { + if (preg_match('/^get(.+)Service$/', $method, $match)) { + $ids[] = self::underscore($match[1]); + } } } $ids[] = 'service_container'; - return array_unique(array_merge($ids, array_keys($this->services))); + return array_unique(array_merge($ids, array_keys($this->methodMap), array_keys($this->services))); } /** - * This is called when you enter a scope. - * - * @param string $name + * Camelizes a string. * - * @throws RuntimeException When the parent scope is inactive - * @throws InvalidArgumentException When the scope does not exist + * @param string $id A string to camelize * - * @deprecated since version 2.8, to be removed in 3.0. + * @return string The camelized string */ - public function enterScope($name) + public static function camelize($id) { - if ('request' !== $name) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - if (!isset($this->scopes[$name])) { - throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name)); - } - - if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) { - throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name])); - } - - // check if a scope of this name is already active, if so we need to - // remove all services of this scope, and those of any of its child - // scopes from the global services map - if (isset($this->scopedServices[$name])) { - $services = array($this->services, $name => $this->scopedServices[$name]); - unset($this->scopedServices[$name]); - - foreach ($this->scopeChildren[$name] as $child) { - if (isset($this->scopedServices[$child])) { - $services[$child] = $this->scopedServices[$child]; - unset($this->scopedServices[$child]); - } - } - - // update global map - $this->services = call_user_func_array('array_diff_key', $services); - array_shift($services); - - // add stack entry for this scope so we can restore the removed services later - if (!isset($this->scopeStacks[$name])) { - $this->scopeStacks[$name] = new \SplStack(); - } - $this->scopeStacks[$name]->push($services); - } - - $this->scopedServices[$name] = array(); + return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => '')); } /** - * This is called to leave the current scope, and move back to the parent - * scope. - * - * @param string $name The name of the scope to leave + * A string to underscore. * - * @throws InvalidArgumentException if the scope is not active + * @param string $id The string to underscore * - * @deprecated since version 2.8, to be removed in 3.0. + * @return string The underscored string */ - public function leaveScope($name) + public static function underscore($id) { - if ('request' !== $name) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - if (!isset($this->scopedServices[$name])) { - throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name)); - } - - // remove all services of this scope, or any of its child scopes from - // the global service map - $services = array($this->services, $this->scopedServices[$name]); - unset($this->scopedServices[$name]); - - foreach ($this->scopeChildren[$name] as $child) { - if (isset($this->scopedServices[$child])) { - $services[] = $this->scopedServices[$child]; - unset($this->scopedServices[$child]); - } - } - - // update global map - $this->services = call_user_func_array('array_diff_key', $services); - - // check if we need to restore services of a previous scope of this type - if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) { - $services = $this->scopeStacks[$name]->pop(); - $this->scopedServices += $services; - - if ($this->scopeStacks[$name]->isEmpty()) { - unset($this->scopeStacks[$name]); - } - - foreach ($services as $array) { - foreach ($array as $id => $service) { - $this->set($id, $service, $name); - } - } - } + return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), str_replace('_', '.', $id))); } /** - * Adds a scope to the container. + * Fetches a variable from the environment. * - * @param ScopeInterface $scope + * @param string The name of the environment variable * - * @throws InvalidArgumentException + * @return scalar The value to use for the provided environment variable name * - * @deprecated since version 2.8, to be removed in 3.0. + * @throws EnvNotFoundException When the environment variable is not found and has no default value */ - public function addScope(ScopeInterface $scope) + protected function getEnv($name) { - $name = $scope->getName(); - $parentScope = $scope->getParentName(); - - if ('request' !== $name) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) { - throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name)); - } - if (isset($this->scopes[$name])) { - throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name)); + if (isset($this->envCache[$name]) || array_key_exists($name, $this->envCache)) { + return $this->envCache[$name]; } - if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) { - throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope)); + if (isset($_ENV[$name])) { + return $this->envCache[$name] = $_ENV[$name]; } - - $this->scopes[$name] = $parentScope; - $this->scopeChildren[$name] = array(); - - // normalize the child relations - while ($parentScope !== self::SCOPE_CONTAINER) { - $this->scopeChildren[$parentScope][] = $name; - $parentScope = $this->scopes[$parentScope]; + if (false !== $env = getenv($name)) { + return $this->envCache[$name] = $env; } - } - - /** - * Returns whether this container has a certain scope. - * - * @param string $name The name of the scope - * - * @return bool - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function hasScope($name) - { - if ('request' !== $name) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); + if (!$this->hasParameter("env($name)")) { + throw new EnvNotFoundException($name); } - return isset($this->scopes[$name]); - } - - /** - * Returns whether this scope is currently active. - * - * This does not actually check if the passed scope actually exists. - * - * @param string $name - * - * @return bool - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function isScopeActive($name) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - - return isset($this->scopedServices[$name]); - } - - /** - * Camelizes a string. - * - * @param string $id A string to camelize - * - * @return string The camelized string - */ - public static function camelize($id) - { - return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => '')); - } - - /** - * A string to underscore. - * - * @param string $id The string to underscore - * - * @return string The underscored string - */ - public static function underscore($id) - { - return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), str_replace('_', '.', $id))); + return $this->envCache[$name] = $this->getParameter("env($name)"); } private function __clone() diff --git a/vendor/symfony/dependency-injection/ContainerAware.php b/vendor/symfony/dependency-injection/ContainerAware.php deleted file mode 100644 index f3f2a506..00000000 --- a/vendor/symfony/dependency-injection/ContainerAware.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection; - -/** - * A simple implementation of ContainerAwareInterface. - * - * @author Fabien Potencier - * - * @deprecated since version 2.8, to be removed in 3.0. Use the ContainerAwareTrait instead. - */ -abstract class ContainerAware implements ContainerAwareInterface -{ - /** - * @var ContainerInterface - */ - protected $container; - - /** - * {@inheritdoc} - */ - public function setContainer(ContainerInterface $container = null) - { - $this->container = $container; - } -} diff --git a/vendor/symfony/dependency-injection/ContainerBuilder.php b/vendor/symfony/dependency-injection/ContainerBuilder.php index ede06d6c..b2a1d77a 100644 --- a/vendor/symfony/dependency-injection/ContainerBuilder.php +++ b/vendor/symfony/dependency-injection/ContainerBuilder.php @@ -15,17 +15,18 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; -use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\LogicException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Resource\ResourceInterface; use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; @@ -51,11 +52,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface */ private $definitions = array(); - /** - * @var Definition[] - */ - private $obsoleteDefinitions = array(); - /** * @var Alias[] */ @@ -73,7 +69,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface */ private $compiler; - private $trackResources = true; + private $trackResources; /** * @var InstantiatorInterface|null @@ -90,11 +86,28 @@ class ContainerBuilder extends Container implements TaggedContainerInterface */ private $expressionLanguageProviders = array(); + public function __construct(ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + + $this->trackResources = interface_exists('Symfony\Component\Config\Resource\ResourceInterface'); + } + /** * @var string[] with tag names used by findTaggedServiceIds */ private $usedTags = array(); + /** + * @var string[][] a map of env var names to their placeholders + */ + private $envPlaceholders = array(); + + /** + * @var int[] a map of env vars to their resolution counter + */ + private $envCounters = array(); + /** * Sets the track resources flag. * @@ -297,14 +310,28 @@ public function loadFromExtension($extension, array $values = array()) /** * Adds a compiler pass. * - * @param CompilerPassInterface $pass A compiler pass - * @param string $type The type of compiler pass + * @param CompilerPassInterface $pass A compiler pass + * @param string $type The type of compiler pass + * @param int $priority Used to sort the passes * * @return $this */ - public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION) + public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, $priority = 0*/) { - $this->getCompiler()->addPass($pass, $type); + if (func_num_args() >= 3) { + $priority = func_get_arg(2); + } else { + if (__CLASS__ !== get_class($this)) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s() will have a third `$priority = 0` argument in version 4.0. Not defining it is deprecated since 3.2.', __METHOD__), E_USER_DEPRECATED); + } + } + + $priority = 0; + } + + $this->getCompiler()->addPass($pass, $type, $priority); $this->addObjectResource($pass); @@ -335,70 +362,26 @@ public function getCompiler() return $this->compiler; } - /** - * Returns all Scopes. - * - * @return array An array of scopes - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function getScopes($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->scopes; - } - - /** - * Returns all Scope children. - * - * @return array An array of scope children - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function getScopeChildren($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->scopeChildren; - } - /** * Sets a service. * - * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0. - * * @param string $id The service identifier * @param object $service The service instance - * @param string $scope The scope * * @throws BadMethodCallException When this ContainerBuilder is frozen */ - public function set($id, $service, $scope = self::SCOPE_CONTAINER) + public function set($id, $service) { $id = strtolower($id); - $set = isset($this->definitions[$id]); - if ($this->isFrozen() && ($set || isset($this->obsoleteDefinitions[$id])) && !$this->{$set ? 'definitions' : 'obsoleteDefinitions'}[$id]->isSynthetic()) { + if ($this->isFrozen() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) { // setting a synthetic service on a frozen container is alright - throw new BadMethodCallException(sprintf('Setting service "%s" on a frozen container is not allowed.', $id)); - } - - if ($set) { - $this->obsoleteDefinitions[$id] = $this->definitions[$id]; + throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a frozen container is not allowed.', $id)); } unset($this->definitions[$id], $this->aliasDefinitions[$id]); - parent::set($id, $service, $scope); - - if (isset($this->obsoleteDefinitions[$id]) && $this->obsoleteDefinitions[$id]->isSynchronized(false)) { - $this->synchronize($id); - } + parent::set($id, $service); } /** @@ -448,7 +431,7 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV return $service; } - if (!array_key_exists($id, $this->definitions) && isset($this->aliasDefinitions[$id])) { + if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) { return $this->get((string) $this->aliasDefinitions[$id], $invalidBehavior); } @@ -466,22 +449,10 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV try { $service = $this->createService($definition, $id); - } catch (\Exception $e) { - unset($this->loading[$id]); - - if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { - return; - } - - throw $e; - } catch (\Throwable $e) { + } finally { unset($this->loading[$id]); - - throw $e; } - unset($this->loading[$id]); - return $service; } @@ -530,6 +501,18 @@ public function merge(ContainerBuilder $container) $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name)); } + + if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) { + $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag()); + } + + foreach ($container->envCounters as $env => $count) { + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = $count; + } else { + $this->envCounters[$env] += $count; + } + } } /** @@ -589,17 +572,21 @@ public function compile() $compiler->compile($this); - if ($this->trackResources) { - foreach ($this->definitions as $definition) { - if ($definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) { - $this->addClassResource(new \ReflectionClass($class)); - } + foreach ($this->definitions as $id => $definition) { + if (!$definition->isPublic()) { + $this->privates[$id] = true; + } + if ($this->trackResources && $definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) { + $this->addClassResource(new \ReflectionClass($class)); } } $this->extensionConfigs = array(); + $bag = $this->getParameterBag(); parent::compile(); + + $this->envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : array(); } /** @@ -796,7 +783,7 @@ public function setDefinition($id, Definition $definition) */ public function hasDefinition($id) { - return array_key_exists(strtolower($id), $this->definitions); + return isset($this->definitions[strtolower($id)]); } /** @@ -812,7 +799,7 @@ public function getDefinition($id) { $id = strtolower($id); - if (!array_key_exists($id, $this->definitions)) { + if (!isset($this->definitions[$id])) { throw new ServiceNotFoundException($id); } @@ -850,14 +837,11 @@ public function findDefinition($id) * * @return object The service described by the service definition * - * @throws RuntimeException When the scope is inactive * @throws RuntimeException When the factory definition is incomplete * @throws RuntimeException When the service is a synthetic service * @throws InvalidArgumentException When configure callable is not callable - * - * @internal this method is public because of PHP 5.3 limitations, do not use it explicitly in your code */ - public function createService(Definition $definition, $id, $tryProxy = true) + private function createService(Definition $definition, $id, $tryProxy = true) { if ($definition instanceof DefinitionDecorator) { throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id)); @@ -872,15 +856,13 @@ public function createService(Definition $definition, $id, $tryProxy = true) } if ($tryProxy && $definition->isLazy()) { - $container = $this; - $proxy = $this ->getProxyInstantiator() ->instantiateProxy( - $container, + $this, $definition, - $id, function () use ($definition, $id, $container) { - return $container->createService($definition, $id, false); + $id, function () use ($definition, $id) { + return $this->createService($definition, $id, false); } ); $this->shareService($definition, $proxy, $id); @@ -912,16 +894,6 @@ public function createService(Definition $definition, $id, $tryProxy = true) @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name), E_USER_DEPRECATED); } } - } elseif (null !== $definition->getFactoryMethod(false)) { - if (null !== $definition->getFactoryClass(false)) { - $factory = $parameterBag->resolveValue($definition->getFactoryClass(false)); - } elseif (null !== $definition->getFactoryService(false)) { - $factory = $this->get($parameterBag->resolveValue($definition->getFactoryService(false))); - } else { - throw new RuntimeException(sprintf('Cannot create service "%s" from factory method without a factory service or factory class.', $id)); - } - - $service = call_user_func_array(array($factory, $definition->getFactoryMethod(false)), $arguments); } else { $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass())); @@ -1061,6 +1033,69 @@ public function getExpressionLanguageProviders() return $this->expressionLanguageProviders; } + /** + * Resolves env parameter placeholders in a string or an array. + * + * @param mixed $value The value to resolve + * @param string|null $format A sprintf() format to use as replacement for env placeholders or null to use the default parameter format + * @param array &$usedEnvs Env vars found while resolving are added to this array + * + * @return string The string with env parameters resolved + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (null === $format) { + $format = '%%env(%s)%%'; + } + + if (is_array($value)) { + $result = array(); + foreach ($value as $k => $v) { + $result[$this->resolveEnvPlaceholders($k, $format, $usedEnvs)] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); + } + + return $result; + } + + if (!is_string($value)) { + return $value; + } + + $bag = $this->getParameterBag(); + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + + foreach ($envPlaceholders as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (false !== stripos($value, $placeholder)) { + $value = str_ireplace($placeholder, sprintf($format, $env), $value); + $usedEnvs[$env] = $env; + $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; + } + } + } + + return $value; + } + + /** + * Get statistics about env usage. + * + * @return int[] The number of time each env vars has been resolved + */ + public function getEnvCounters() + { + $bag = $this->getParameterBag(); + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + + foreach ($envPlaceholders as $env => $placeholders) { + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = 0; + } + } + + return $this->envCounters; + } + /** * Returns the Service Conditionals. * @@ -1097,38 +1132,6 @@ private function getProxyInstantiator() return $this->proxyInstantiator; } - /** - * Synchronizes a service change. - * - * This method updates all services that depend on the given - * service by calling all methods referencing it. - * - * @param string $id A service id - * - * @deprecated since version 2.7, will be removed in 3.0. - */ - private function synchronize($id) - { - if ('request' !== $id) { - @trigger_error('The '.__METHOD__.' method is deprecated in version 2.7 and will be removed in version 3.0.', E_USER_DEPRECATED); - } - - foreach ($this->definitions as $definitionId => $definition) { - // only check initialized services - if (!$this->initialized($definitionId)) { - continue; - } - - foreach ($definition->getMethodCalls() as $call) { - foreach ($call[1] as $argument) { - if ($argument instanceof Reference && $id == (string) $argument) { - $this->callMethod($this->get($definitionId), $call); - } - } - } - } - } - private function callMethod($service, $call) { $services = self::getServiceConditionals($call[1]); @@ -1148,21 +1151,11 @@ private function callMethod($service, $call) * @param Definition $definition * @param mixed $service * @param string|null $id - * - * @throws InactiveScopeException */ private function shareService(Definition $definition, $service, $id) { - if (null !== $id && $definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) { - if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) { - throw new InactiveScopeException($id, $scope); - } - - $this->services[$lowerId = strtolower($id)] = $service; - - if (self::SCOPE_CONTAINER !== $scope) { - $this->scopedServices[$scope][$lowerId] = $service; - } + if (null !== $id && $definition->isShared()) { + $this->services[strtolower($id)] = $service; } } diff --git a/vendor/symfony/dependency-injection/ContainerInterface.php b/vendor/symfony/dependency-injection/ContainerInterface.php index d9076eb1..7e2fbb1c 100644 --- a/vendor/symfony/dependency-injection/ContainerInterface.php +++ b/vendor/symfony/dependency-injection/ContainerInterface.php @@ -26,19 +26,14 @@ interface ContainerInterface const EXCEPTION_ON_INVALID_REFERENCE = 1; const NULL_ON_INVALID_REFERENCE = 2; const IGNORE_ON_INVALID_REFERENCE = 3; - const SCOPE_CONTAINER = 'container'; - const SCOPE_PROTOTYPE = 'prototype'; /** * Sets a service. * - * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0. - * * @param string $id The service identifier * @param object $service The service instance - * @param string $scope The scope of the service */ - public function set($id, $service, $scope = self::SCOPE_CONTAINER); + public function set($id, $service); /** * Gets a service. @@ -64,6 +59,15 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE */ public function has($id); + /** + * Check for whether or not a service has been initialized. + * + * @param string $id + * + * @return bool true if the service has been initialized, false otherwise + */ + public function initialized($id); + /** * Gets a parameter. * @@ -91,55 +95,4 @@ public function hasParameter($name); * @param mixed $value The parameter value */ public function setParameter($name, $value); - - /** - * Enters the given scope. - * - * @param string $name - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function enterScope($name); - - /** - * Leaves the current scope, and re-enters the parent scope. - * - * @param string $name - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function leaveScope($name); - - /** - * Adds a scope to the container. - * - * @param ScopeInterface $scope - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function addScope(ScopeInterface $scope); - - /** - * Whether this container has the given scope. - * - * @param string $name - * - * @return bool - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function hasScope($name); - - /** - * Determines whether the given scope is currently active. - * - * It does however not check if the scope actually exists. - * - * @param string $name - * - * @return bool - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function isScopeActive($name); } diff --git a/vendor/symfony/dependency-injection/Definition.php b/vendor/symfony/dependency-injection/Definition.php index a002df28..53f6c5b2 100644 --- a/vendor/symfony/dependency-injection/Definition.php +++ b/vendor/symfony/dependency-injection/Definition.php @@ -24,13 +24,9 @@ class Definition private $class; private $file; private $factory; - private $factoryClass; - private $factoryMethod; - private $factoryService; private $shared = true; private $deprecated = false; private $deprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.'; - private $scope = ContainerInterface::SCOPE_CONTAINER; private $properties = array(); private $calls = array(); private $configurator; @@ -38,7 +34,6 @@ class Definition private $public = true; private $synthetic = false; private $abstract = false; - private $synchronized = false; private $lazy = false; private $decoratedService; private $autowired = false; @@ -84,59 +79,6 @@ public function getFactory() return $this->factory; } - /** - * Sets the name of the class that acts as a factory using the factory method, - * which will be invoked statically. - * - * @param string $factoryClass The factory class name - * - * @return $this - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function setFactoryClass($factoryClass) - { - @trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryClass), E_USER_DEPRECATED); - - $this->factoryClass = $factoryClass; - - return $this; - } - - /** - * Gets the factory class. - * - * @return string|null The factory class name - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function getFactoryClass($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->factoryClass; - } - - /** - * Sets the factory method able to create an instance of this class. - * - * @param string $factoryMethod The factory method name - * - * @return $this - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function setFactoryMethod($factoryMethod) - { - @trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryMethod), E_USER_DEPRECATED); - - $this->factoryMethod = $factoryMethod; - - return $this; - } - /** * Sets the service that this service is decorating. * @@ -151,7 +93,7 @@ public function setFactoryMethod($factoryMethod) public function setDecoratedService($id, $renamedId = null, $priority = 0) { if ($renamedId && $id == $renamedId) { - throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); + throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); } if (null === $id) { @@ -164,7 +106,7 @@ public function setDecoratedService($id, $renamedId = null, $priority = 0) } /** - * Gets the service that decorates this service. + * Gets the service that this service is decorating. * * @return null|array An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated */ @@ -173,58 +115,6 @@ public function getDecoratedService() return $this->decoratedService; } - /** - * Gets the factory method. - * - * @return string|null The factory method name - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function getFactoryMethod($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->factoryMethod; - } - - /** - * Sets the name of the service that acts as a factory using the factory method. - * - * @param string $factoryService The factory service id - * - * @return $this - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function setFactoryService($factoryService, $triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryService), E_USER_DEPRECATED); - } - - $this->factoryService = $factoryService; - - return $this; - } - - /** - * Gets the factory service id. - * - * @return string|null The factory service id - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function getFactoryService($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->factoryService; - } - /** * Sets the service class. * @@ -308,6 +198,10 @@ public function addArgument($argument) */ public function replaceArgument($index, $argument) { + if (0 === count($this->arguments)) { + throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.'); + } + if ($index < 0 || $index > count($this->arguments) - 1) { throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1)); } @@ -375,7 +269,7 @@ public function setMethodCalls(array $calls = array()) public function addMethodCall($method, array $arguments = array()) { if (empty($method)) { - throw new InvalidArgumentException(sprintf('Method name cannot be empty.')); + throw new InvalidArgumentException('Method name cannot be empty.'); } $this->calls[] = array($method, $arguments); @@ -566,46 +460,6 @@ public function isShared() return $this->shared; } - /** - * Sets the scope of the service. - * - * @param string $scope Whether the service must be shared or not - * - * @return $this - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function setScope($scope, $triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - if (ContainerInterface::SCOPE_PROTOTYPE === $scope) { - $this->setShared(false); - } - - $this->scope = $scope; - - return $this; - } - - /** - * Returns the scope of the service. - * - * @return string - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function getScope($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->scope; - } - /** * Sets the visibility of this service. * @@ -630,42 +484,6 @@ public function isPublic() return $this->public; } - /** - * Sets the synchronized flag of this service. - * - * @param bool $boolean - * - * @return $this - * - * @deprecated since version 2.7, will be removed in 3.0. - */ - public function setSynchronized($boolean, $triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - $this->synchronized = (bool) $boolean; - - return $this; - } - - /** - * Whether this service is synchronized. - * - * @return bool - * - * @deprecated since version 2.7, will be removed in 3.0. - */ - public function isSynchronized($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->synchronized; - } - /** * Sets the lazy flag of this service. * @@ -798,13 +616,17 @@ public function getDeprecationMessage($id) /** * Sets a configurator to call after the service is fully initialized. * - * @param callable $callable A PHP callable + * @param string|array $configurator A PHP callable * * @return $this */ - public function setConfigurator($callable) + public function setConfigurator($configurator) { - $this->configurator = $callable; + if (is_string($configurator) && strpos($configurator, '::') !== false) { + $configurator = explode('::', $configurator, 2); + } + + $this->configurator = $configurator; return $this; } diff --git a/vendor/symfony/dependency-injection/DefinitionDecorator.php b/vendor/symfony/dependency-injection/DefinitionDecorator.php index 4d0f694a..1243695d 100644 --- a/vendor/symfony/dependency-injection/DefinitionDecorator.php +++ b/vendor/symfony/dependency-injection/DefinitionDecorator.php @@ -74,36 +74,6 @@ public function setFactory($callable) return parent::setFactory($callable); } - /** - * {@inheritdoc} - */ - public function setFactoryClass($class) - { - $this->changes['factory_class'] = true; - - return parent::setFactoryClass($class); - } - - /** - * {@inheritdoc} - */ - public function setFactoryMethod($method) - { - $this->changes['factory_method'] = true; - - return parent::setFactoryMethod($method); - } - - /** - * {@inheritdoc} - */ - public function setFactoryService($service, $triggerDeprecationError = true) - { - $this->changes['factory_service'] = true; - - return parent::setFactoryService($service, $triggerDeprecationError); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php b/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php index 4172b3d7..9e6b1904 100644 --- a/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php @@ -15,10 +15,8 @@ use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Parameter; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; -use Symfony\Component\DependencyInjection\Scope; /** * GraphvizDumper dumps a service container as a graphviz file. @@ -83,7 +81,7 @@ public function dump(array $options = array()) } } - return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot(); + return $this->container->resolveEnvPlaceholders($this->startDot().$this->addNodes().$this->addEdges().$this->endDot(), '__ENV_%s__'); } /** @@ -177,19 +175,17 @@ private function findNodes() } catch (ParameterNotFoundException $e) { } - $nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false) ? 'filled' : 'dotted'))); + $nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() ? 'filled' : 'dotted'))); $container->setDefinition($id, new Definition('stdClass')); } foreach ($container->getServiceIds() as $id) { - $service = $container->get($id); - if (array_key_exists($id, $container->getAliases())) { continue; } if (!$container->hasDefinition($id)) { - $class = ('service_container' === $id) ? get_class($this->container) : get_class($service); + $class = get_class('service_container' === $id ? $this->container : $container->get($id)); $nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => $this->options['node.instance']); } } @@ -205,9 +201,6 @@ private function cloneContainer() $container->setDefinitions($this->container->getDefinitions()); $container->setAliases($this->container->getAliases()); $container->setResources($this->container->getResources()); - foreach ($this->container->getScopes(false) as $scope => $parentScope) { - $container->addScope(new Scope($scope, $parentScope)); - } foreach ($this->container->getExtensions() as $extension) { $container->registerExtension($extension); } diff --git a/vendor/symfony/dependency-injection/Dumper/PhpDumper.php b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php index 2ef29aa3..89888433 100644 --- a/vendor/symfony/dependency-injection/Dumper/PhpDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php @@ -18,6 +18,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; @@ -25,7 +26,6 @@ use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; use Symfony\Component\DependencyInjection\ExpressionLanguage; use Symfony\Component\ExpressionLanguage\Expression; -use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; use Symfony\Component\HttpKernel\Kernel; /** @@ -59,11 +59,8 @@ class PhpDumper extends Dumper private $targetDirRegex; private $targetDirMaxMatches; private $docStar; - - /** - * @var ExpressionFunctionProviderInterface[] - */ - private $expressionLanguageProviders = array(); + private $serviceIdToMethodNameMap; + private $usedMethodNames; /** * @var \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface @@ -102,6 +99,8 @@ public function setProxyDumper(ProxyDumper $proxyDumper) * @param array $options An array of options * * @return string A PHP class representing of the service container + * + * @throws EnvParameterException When an env var exists but has not been dumped */ public function dump(array $options = array()) { @@ -112,6 +111,9 @@ public function dump(array $options = array()) 'namespace' => '', 'debug' => true, ), $options); + + $this->initializeMethodNamesMap($options['base_class']); + $this->docStar = $options['debug'] ? '*' : ''; if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) { @@ -157,6 +159,16 @@ public function dump(array $options = array()) ; $this->targetDirRegex = null; + $unusedEnvs = array(); + foreach ($this->container->getEnvCounters() as $env => $use) { + if (!$use) { + $unusedEnvs[] = $env; + } + } + if ($unusedEnvs) { + throw new EnvParameterException($unusedEnvs); + } + return $code; } @@ -332,7 +344,7 @@ private function addServiceInlinedDefinitions($id, $definition) throw new ServiceCircularReferenceException($id, array($id)); } - $code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = '); + $code .= $this->addNewInstance($sDefinition, '$'.$name, ' = ', $id); if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) { $code .= $this->addServiceProperties(null, $sDefinition, $name); @@ -385,7 +397,7 @@ private function addServiceInstance($id, Definition $definition) $class = $this->dumpValue($class); - if (0 === strpos($class, "'") && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); } @@ -393,10 +405,8 @@ private function addServiceInstance($id, Definition $definition) $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition); $instantiation = ''; - if (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) { + if (!$isProxyCandidate && $definition->isShared()) { $instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance'); - } elseif (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) { - $instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance'); } elseif (!$simple) { $instantiation = '$instance'; } @@ -408,7 +418,7 @@ private function addServiceInstance($id, Definition $definition) $instantiation .= ' = '; } - $code = $this->addNewInstance($id, $definition, $return, $instantiation); + $code = $this->addNewInstance($definition, $return, $instantiation, $id); if (!$simple) { $code .= "\n"; @@ -542,10 +552,14 @@ private function addServiceConfigurator($id, Definition $definition, $variableNa $class = $this->dumpValue($callable[0]); // If the class is a string we can optimize call_user_func away - if (strpos($class, "'") === 0) { + if (0 === strpos($class, "'") && false === strpos($class, '$')) { return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); } + if (0 === strpos($class, 'new ')) { + return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + return sprintf(" call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } @@ -571,6 +585,7 @@ private function addService($id, Definition $definition) if ($definition->isSynthetic()) { $return[] = '@throws RuntimeException always since this service is expected to be injected dynamically'; } elseif ($class = $definition->getClass()) { + $class = $this->container->resolveEnvPlaceholders($class); $return[] = sprintf('@return %s A %s instance', 0 === strpos($class, '%') ? 'object' : '\\'.ltrim($class, '\\'), ltrim($class, '\\')); } elseif ($definition->getFactory()) { $factory = $definition->getFactory(); @@ -583,18 +598,6 @@ private function addService($id, Definition $definition) $return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]); } } - } elseif ($definition->getFactoryClass(false)) { - $return[] = sprintf('@return object An instance returned by %s::%s()', $definition->getFactoryClass(false), $definition->getFactoryMethod(false)); - } elseif ($definition->getFactoryService(false)) { - $return[] = sprintf('@return object An instance returned by %s::%s()', $definition->getFactoryService(false), $definition->getFactoryMethod(false)); - } - - $scope = $definition->getScope(false); - if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) { - if ($return && 0 === strpos($return[count($return) - 1], '@return')) { - $return[] = ''; - } - $return[] = sprintf("@throws InactiveScopeException when the '%s' service is requested while the '%s' scope is not active", $id, $scope); } if ($definition->isDeprecated()) { @@ -606,9 +609,10 @@ private function addService($id, Definition $definition) } $return = str_replace("\n * \n", "\n *\n", implode("\n * ", $return)); + $return = $this->container->resolveEnvPlaceholders($return); $doc = ''; - if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope) { + if ($definition->isShared()) { $doc .= <<<'EOF' * @@ -628,7 +632,7 @@ private function addService($id, Definition $definition) } if ($definition->isAutowired()) { - $doc = <<getProxyDumper()->isProxyCandidate($definition); $visibility = $isProxyCandidate ? 'public' : 'protected'; + $methodName = $this->generateMethodName($id); $code = <<docStar} @@ -653,28 +658,18 @@ private function addService($id, Definition $definition) *$lazyInitializationDoc * $return */ - {$visibility} function get{$this->camelize($id)}Service($lazyInitialization) + {$visibility} function {$methodName}($lazyInitialization) { EOF; - $code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id) : ''; - - if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) { - $code .= <<scopedServices['$scope'])) { - throw new InactiveScopeException('$id', '$scope'); - } - - -EOF; - } + $code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $methodName) : ''; if ($definition->isSynthetic()) { $code .= sprintf(" throw new RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n }\n", $id); } else { if ($definition->isDeprecated()) { - $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", var_export($definition->getDeprecationMessage($id), true)); + $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); } $code .= @@ -703,7 +698,7 @@ private function addService($id, Definition $definition) */ private function addServices() { - $publicServices = $privateServices = $synchronizers = ''; + $publicServices = $privateServices = ''; $definitions = $this->container->getDefinitions(); ksort($definitions); foreach ($definitions as $id => $definition) { @@ -712,73 +707,12 @@ private function addServices() } else { $privateServices .= $this->addService($id, $definition); } - - $synchronizers .= $this->addServiceSynchronizer($id, $definition); } - return $publicServices.$synchronizers.$privateServices; + return $publicServices.$privateServices; } - /** - * Adds synchronizer methods. - * - * @param string $id A service identifier - * @param Definition $definition A Definition instance - * - * @return string|null - * - * @deprecated since version 2.7, will be removed in 3.0. - */ - private function addServiceSynchronizer($id, Definition $definition) - { - if (!$definition->isSynchronized(false)) { - return; - } - - if ('request' !== $id) { - @trigger_error('Synchronized services were deprecated in version 2.7 and won\'t work anymore in 3.0.', E_USER_DEPRECATED); - } - - $code = ''; - foreach ($this->container->getDefinitions() as $definitionId => $definition) { - foreach ($definition->getMethodCalls() as $call) { - foreach ($call[1] as $argument) { - if ($argument instanceof Reference && $id == (string) $argument) { - $arguments = array(); - foreach ($call[1] as $value) { - $arguments[] = $this->dumpValue($value); - } - - $call = $this->wrapServiceConditionals($call[1], sprintf("\$this->get('%s')->%s(%s);", $definitionId, $call[0], implode(', ', $arguments))); - - $code .= <<initialized('$definitionId')) { - $call - } - -EOF; - } - } - } - } - - if (!$code) { - return; - } - - return <<docStar} - * Updates the '$id' service. - */ - protected function synchronize{$this->camelize($id)}Service() - { -$code } - -EOF; - } - - private function addNewInstance($id, Definition $definition, $return, $instantiation) + private function addNewInstance(Definition $definition, $return, $instantiation, $id) { $class = $this->dumpValue($definition->getClass()); @@ -801,31 +735,22 @@ private function addNewInstance($id, Definition $definition, $return, $instantia $class = $this->dumpValue($callable[0]); // If the class is a string we can optimize call_user_func away - if (strpos($class, "'") === 0) { + if (0 === strpos($class, "'") && false === strpos($class, '$')) { + if ("''" === $class) { + throw new RuntimeException(sprintf('Cannot dump definition: The "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id)); + } + return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : ''); } - return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); - } - - return sprintf(" $return{$instantiation}\\%s(%s);\n", $callable, $arguments ? implode(', ', $arguments) : ''); - } elseif (null !== $definition->getFactoryMethod(false)) { - if (null !== $definition->getFactoryClass(false)) { - $class = $this->dumpValue($definition->getFactoryClass(false)); - - // If the class is a string we can optimize call_user_func away - if (strpos($class, "'") === 0) { - return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $definition->getFactoryMethod(false), $arguments ? implode(', ', $arguments) : ''); + if (0 === strpos($class, 'new ')) { + return sprintf(" $return{$instantiation}(%s)->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); } - return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass(false)), $definition->getFactoryMethod(false), $arguments ? ', '.implode(', ', $arguments) : ''); - } - - if (null !== $definition->getFactoryService(false)) { - return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService(false)), $definition->getFactoryMethod(false), implode(', ', $arguments)); + return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); } - throw new RuntimeException(sprintf('Factory method requires a factory service or factory class in service definition for %s', $id)); + return sprintf(" $return{$instantiation}%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); } if (false !== strpos($class, '$')) { @@ -854,7 +779,6 @@ private function startClass($class, $baseClass, $namespace) $namespaceLine use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\LogicException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; @@ -895,13 +819,8 @@ public function __construct() EOF; - if (count($scopes = $this->container->getScopes(false)) > 0) { - $code .= "\n"; - $code .= ' $this->scopes = '.$this->dumpValue($scopes).";\n"; - $code .= ' $this->scopeChildren = '.$this->dumpValue($this->container->getScopeChildren(false)).";\n"; - } - $code .= $this->addMethodMap(); + $code .= $this->addPrivateServices(); $code .= $this->addAliases(); $code .= <<<'EOF' @@ -934,23 +853,9 @@ public function __construct() $code .= "\n \$this->parameters = \$this->getDefaultParameters();\n"; } - $code .= <<<'EOF' - - $this->services = - $this->scopedServices = - $this->scopeStacks = array(); -EOF; - - $code .= "\n"; - if (count($scopes = $this->container->getScopes(false)) > 0) { - $code .= ' $this->scopes = '.$this->dumpValue($scopes).";\n"; - $code .= ' $this->scopeChildren = '.$this->dumpValue($this->container->getScopeChildren(false)).";\n"; - } else { - $code .= " \$this->scopes = array();\n"; - $code .= " \$this->scopeChildren = array();\n"; - } - + $code .= "\n \$this->services = array();\n"; $code .= $this->addMethodMap(); + $code .= $this->addPrivateServices(); $code .= $this->addAliases(); $code .= <<<'EOF' @@ -1015,12 +920,42 @@ private function addMethodMap() $code = " \$this->methodMap = array(\n"; ksort($definitions); foreach ($definitions as $id => $definition) { - $code .= ' '.var_export($id, true).' => '.var_export('get'.$this->camelize($id).'Service', true).",\n"; + $code .= ' '.$this->export($id).' => '.$this->export($this->generateMethodName($id)).",\n"; } return $code." );\n"; } + /** + * Adds the privates property definition. + * + * @return string + */ + private function addPrivateServices() + { + if (!$definitions = $this->container->getDefinitions()) { + return ''; + } + + $code = ''; + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isPublic()) { + $code .= ' '.$this->export($id)." => true,\n"; + } + } + + if (empty($code)) { + return ''; + } + + $out = " \$this->privates = array(\n"; + $out .= $code; + $out .= " );\n"; + + return $out; + } + /** * Adds the aliases property definition. * @@ -1029,11 +964,7 @@ private function addMethodMap() private function addAliases() { if (!$aliases = $this->container->getAliases()) { - if ($this->container->isFrozen()) { - return "\n \$this->aliases = array();\n"; - } else { - return ''; - } + return $this->container->isFrozen() ? "\n \$this->aliases = array();\n" : ''; } $code = " \$this->aliases = array(\n"; @@ -1043,7 +974,7 @@ private function addAliases() while (isset($aliases[$id])) { $id = (string) $aliases[$id]; } - $code .= ' '.var_export($alias, true).' => '.var_export($id, true).",\n"; + $code .= ' '.$this->export($alias).' => '.$this->export($id).",\n"; } return $code." );\n"; @@ -1060,7 +991,23 @@ private function addDefaultParametersMethod() return ''; } - $parameters = $this->exportParameters($this->container->getParameterBag()->all()); + $php = array(); + $dynamicPhp = array(); + + foreach ($this->container->getParameterBag()->all() as $key => $value) { + if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) { + throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: %s.', $resolvedKey)); + } + $export = $this->exportParameters(array($value)); + $export = explode('0 => ', substr(rtrim($export, " )\n"), 7, -1), 2); + + if (preg_match("/\\\$this->(?:getEnv\('\w++'\)|targetDirs\[\d++\])/", $export[1])) { + $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]); + } else { + $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); + } + } + $parameters = sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', 8)); $code = ''; if ($this->container->isFrozen()) { @@ -1073,9 +1020,12 @@ public function getParameter($name) { $name = strtolower($name); - if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters))) { + if (!(isset($this->parameters[$name]) || array_key_exists($name, $this->parameters) || isset($this->loadedDynamicParameters[$name]))) { throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } return $this->parameters[$name]; } @@ -1087,7 +1037,7 @@ public function hasParameter($name) { $name = strtolower($name); - return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters); + return isset($this->parameters[$name]) || array_key_exists($name, $this->parameters) || isset($this->loadedDynamicParameters[$name]); } /** @@ -1104,7 +1054,11 @@ public function setParameter($name, $value) public function getParameterBag() { if (null === $this->parameterBag) { - $this->parameterBag = new FrozenParameterBag($this->parameters); + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); } return $this->parameterBag; @@ -1114,6 +1068,46 @@ public function getParameterBag() if ('' === $this->docStar) { $code = str_replace('/**', '/*', $code); } + + if ($dynamicPhp) { + $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, count($dynamicPhp), false)), '', 8); + $getDynamicParameter = <<<'EOF' + switch ($name) { +%s + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; +EOF; + $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp)); + } else { + $loadedDynamicParameters = 'array()'; + $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; + } + + $code .= <<docStar} + * Computes a dynamic parameter. + * + * @param string The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter(\$name) + { +{$getDynamicParameter} + } + +EOF; + } elseif ($dynamicPhp) { + throw new RuntimeException('You cannot dump a not-frozen container with dynamic parameters.'); } $code .= <<export($value); } - $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), var_export($key, true), $value); + $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value); } return sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', $indent - 4)); @@ -1355,9 +1349,12 @@ private function dumpValue($value, $interpolate = true) if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate); } - if (count($value->getMethodCalls()) > 0) { + if ($value->getMethodCalls()) { throw new RuntimeException('Cannot dump definitions which have method calls.'); } + if ($value->getProperties()) { + throw new RuntimeException('Cannot dump definitions which have properties.'); + } if (null !== $value->getConfigurator()) { throw new RuntimeException('Cannot dump definitions which have a configurator.'); } @@ -1371,7 +1368,7 @@ private function dumpValue($value, $interpolate = true) $factory = $value->getFactory(); if (is_string($factory)) { - return sprintf('\\%s(%s)', $factory, implode(', ', $arguments)); + return sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory)), implode(', ', $arguments)); } if (is_array($factory)) { @@ -1395,18 +1392,6 @@ private function dumpValue($value, $interpolate = true) throw new RuntimeException('Cannot dump definition because of invalid factory'); } - if (null !== $value->getFactoryMethod(false)) { - if (null !== $value->getFactoryClass(false)) { - return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass(false)), $value->getFactoryMethod(false), count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); - } elseif (null !== $value->getFactoryService(false)) { - $service = $this->dumpValue($value->getFactoryService(false)); - - return sprintf('%s->%s(%s)', 0 === strpos($service, '$') ? sprintf('$this->get(%s)', $service) : $this->getServiceCall($value->getFactoryService(false)), $value->getFactoryMethod(false), implode(', ', $arguments)); - } else { - throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.'); - } - } - $class = $value->getClass(); if (null === $class) { throw new RuntimeException('Cannot dump definitions which have no class nor factory.'); @@ -1431,9 +1416,8 @@ private function dumpValue($value, $interpolate = true) // the preg_replace_callback converts them to strings return $this->dumpParameter(strtolower($match[1])); } else { - $that = $this; - $replaceParameters = function ($match) use ($that) { - return "'.".$that->dumpParameter(strtolower($match[2])).".'"; + $replaceParameters = function ($match) { + return "'.".$this->dumpParameter(strtolower($match[2])).".'"; }; $code = str_replace('%%', '%', preg_replace_callback('/(?export($value))); @@ -1442,9 +1426,9 @@ private function dumpValue($value, $interpolate = true) } } elseif (is_object($value) || is_resource($value)) { throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); - } else { - return $this->export($value); } + + return $this->export($value); } /** @@ -1459,7 +1443,7 @@ private function dumpValue($value, $interpolate = true) private function dumpLiteralClass($class) { if (false !== strpos($class, '$')) { - throw new RuntimeException('Cannot dump definitions which have a variable class name.'); + return sprintf('${($_ = %s) && false ?: "_"}', $class); } if (0 !== strpos($class, "'") || !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s)', $class ?: 'n/a')); @@ -1475,7 +1459,7 @@ private function dumpLiteralClass($class) * * @return string */ - public function dumpParameter($name) + private function dumpParameter($name) { if ($this->container->isFrozen() && $this->container->hasParameter($name)) { return $this->dumpValue($this->container->getParameter($name), false); @@ -1484,19 +1468,6 @@ public function dumpParameter($name) return sprintf("\$this->getParameter('%s')", strtolower($name)); } - /** - * @deprecated since version 2.6.2, to be removed in 3.0. - * Use \Symfony\Component\DependencyInjection\ContainerBuilder::addExpressionLanguageProvider instead. - * - * @param ExpressionFunctionProviderInterface $provider - */ - public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6.2 and will be removed in 3.0. Use the Symfony\Component\DependencyInjection\ContainerBuilder::addExpressionLanguageProvider method instead.', E_USER_DEPRECATED); - - $this->expressionLanguageProviders[] = $provider; - } - /** * Gets a service call. * @@ -1511,14 +1482,38 @@ private function getServiceCall($id, Reference $reference = null) return '$this'; } + if ($this->container->hasDefinition($id) && !$this->container->getDefinition($id)->isPublic()) { + // The following is PHP 5.5 syntax for what could be written as "(\$this->services['$id'] ?? \$this->{$this->generateMethodName($id)}())" on PHP>=7.0 + + return "\${(\$_ = isset(\$this->services['$id']) ? \$this->services['$id'] : \$this->{$this->generateMethodName($id)}()) && false ?: '_'}"; + } if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) { return sprintf('$this->get(\'%s\', ContainerInterface::NULL_ON_INVALID_REFERENCE)', $id); - } else { - if ($this->container->hasAlias($id)) { - $id = (string) $this->container->getAlias($id); - } + } - return sprintf('$this->get(\'%s\')', $id); + if ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + return sprintf('$this->get(\'%s\')', $id); + } + + /** + * Initializes the method names map to avoid conflicts with the Container methods. + * + * @param string $class the container base class + */ + private function initializeMethodNamesMap($class) + { + $this->serviceIdToMethodNameMap = array(); + $this->usedMethodNames = array(); + + try { + $reflectionClass = new \ReflectionClass($class); + foreach ($reflectionClass->getMethods() as $method) { + $this->usedMethodNames[strtolower($method->getName())] = true; + } + } catch (\ReflectionException $e) { } } @@ -1531,15 +1526,26 @@ private function getServiceCall($id, Reference $reference = null) * * @throws InvalidArgumentException */ - private function camelize($id) + private function generateMethodName($id) { + if (isset($this->serviceIdToMethodNameMap[$id])) { + return $this->serviceIdToMethodNameMap[$id]; + } + $name = Container::camelize($id); + $name = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '', $name); + $methodName = 'get'.$name.'Service'; + $suffix = 1; - if (!preg_match('/^[a-zA-Z0-9_\x7f-\xff]+$/', $name)) { - throw new InvalidArgumentException(sprintf('Service id "%s" cannot be converted to a valid PHP method name.', $id)); + while (isset($this->usedMethodNames[strtolower($methodName)])) { + ++$suffix; + $methodName = 'get'.$name.$suffix.'Service'; } - return $name; + $this->serviceIdToMethodNameMap[$id] = $methodName; + $this->usedMethodNames[strtolower($methodName)] = true; + + return $methodName; } /** @@ -1586,7 +1592,7 @@ private function getExpressionLanguage() if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); } - $providers = array_merge($this->container->getExpressionLanguageProviders(), $this->expressionLanguageProviders); + $providers = $this->container->getExpressionLanguageProviders(); $this->expressionLanguage = new ExpressionLanguage(null, $providers); if ($this->container->isTrackingResources()) { @@ -1613,9 +1619,9 @@ private function exportTargetDirs() private function export($value) { if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { - $prefix = $matches[0][1] ? var_export(substr($value, 0, $matches[0][1]), true).'.' : ''; + $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1])).'.' : ''; $suffix = $matches[0][1] + strlen($matches[0][0]); - $suffix = isset($value[$suffix]) ? '.'.var_export(substr($value, $suffix), true) : ''; + $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix)) : ''; $dirname = '__DIR__'; if (0 < $offset = 1 + $this->targetDirMaxMatches - count($matches)) { @@ -1629,6 +1635,23 @@ private function export($value) return $dirname; } - return var_export($value, true); + return $this->doExport($value); + } + + private function doExport($value) + { + $export = var_export($value, true); + + if ("'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('%s').'")) { + $export = $resolvedExport; + if ("'" === $export[1]) { + $export = substr($export, 3); + } + if (".''" === substr($export, -3)) { + $export = substr($export, 0, -3); + } + } + + return $export; } } diff --git a/vendor/symfony/dependency-injection/Dumper/XmlDumper.php b/vendor/symfony/dependency-injection/Dumper/XmlDumper.php index d7698235..c3a98720 100644 --- a/vendor/symfony/dependency-injection/Dumper/XmlDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/XmlDumper.php @@ -55,7 +55,7 @@ public function dump(array $options = array()) $xml = $this->document->saveXML(); $this->document = null; - return $xml; + return $this->container->resolveEnvPlaceholders($xml); } /** @@ -117,30 +117,15 @@ private function addService($definition, $id, \DOMElement $parent) $service->setAttribute('class', $class); } - if ($definition->getFactoryMethod(false)) { - $service->setAttribute('factory-method', $definition->getFactoryMethod(false)); - } - if ($definition->getFactoryClass(false)) { - $service->setAttribute('factory-class', $definition->getFactoryClass(false)); - } - if ($definition->getFactoryService(false)) { - $service->setAttribute('factory-service', $definition->getFactoryService(false)); - } if (!$definition->isShared()) { $service->setAttribute('shared', 'false'); } - if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) { - $service->setAttribute('scope', $scope); - } if (!$definition->isPublic()) { $service->setAttribute('public', 'false'); } if ($definition->isSynthetic()) { $service->setAttribute('synthetic', 'true'); } - if ($definition->isSynchronized(false)) { - $service->setAttribute('synchronized', 'true'); - } if ($definition->isLazy()) { $service->setAttribute('lazy', 'true'); } @@ -307,9 +292,6 @@ private function convertParameters(array $parameters, $type, \DOMElement $parent } elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) { $element->setAttribute('on-invalid', 'ignore'); } - if (!$value->isStrict(false)) { - $element->setAttribute('strict', 'false'); - } } elseif ($value instanceof Definition) { $element->setAttribute('type', 'service'); $this->addService($value, null, $element); diff --git a/vendor/symfony/dependency-injection/Dumper/YamlDumper.php b/vendor/symfony/dependency-injection/Dumper/YamlDumper.php index 431b40f9..070ae1d1 100644 --- a/vendor/symfony/dependency-injection/Dumper/YamlDumper.php +++ b/vendor/symfony/dependency-injection/Dumper/YamlDumper.php @@ -46,7 +46,7 @@ public function dump(array $options = array()) $this->dumper = new YmlDumper(); } - return $this->addParameters()."\n".$this->addServices(); + return $this->container->resolveEnvPlaceholders($this->addParameters()."\n".$this->addServices()); } /** @@ -93,11 +93,7 @@ private function addService($id, $definition) } if ($definition->isSynthetic()) { - $code .= sprintf(" synthetic: true\n"); - } - - if ($definition->isSynchronized(false)) { - $code .= sprintf(" synchronized: true\n"); + $code .= " synthetic: true\n"; } if ($definition->isDeprecated()) { @@ -116,20 +112,8 @@ private function addService($id, $definition) $code .= sprintf(" autowiring_types:\n%s", $autowiringTypesCode); } - if ($definition->getFactoryClass(false)) { - $code .= sprintf(" factory_class: %s\n", $this->dumper->dump($definition->getFactoryClass(false))); - } - if ($definition->isLazy()) { - $code .= sprintf(" lazy: true\n"); - } - - if ($definition->getFactoryMethod(false)) { - $code .= sprintf(" factory_method: %s\n", $this->dumper->dump($definition->getFactoryMethod(false))); - } - - if ($definition->getFactoryService(false)) { - $code .= sprintf(" factory_service: %s\n", $this->dumper->dump($definition->getFactoryService(false))); + $code .= " lazy: true\n"; } if ($definition->getArguments()) { @@ -148,10 +132,6 @@ private function addService($id, $definition) $code .= " shared: false\n"; } - if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) { - $code .= sprintf(" scope: %s\n", $this->dumper->dump($scope)); - } - if (null !== $decorated = $definition->getDecoratedService()) { list($decorated, $renamedId, $priority) = $decorated; $code .= sprintf(" decorates: %s\n", $decorated); diff --git a/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php b/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php new file mode 100644 index 00000000..577095e8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when an environment variable is not found. + * + * @author Nicolas Grekas + */ +class EnvNotFoundException extends InvalidArgumentException +{ + public function __construct($name) + { + parent::__construct(sprintf('Environment variable not found: "%s".', $name)); + } +} diff --git a/vendor/symfony/dependency-injection/Exception/EnvParameterException.php b/vendor/symfony/dependency-injection/Exception/EnvParameterException.php new file mode 100644 index 00000000..44dbab45 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/EnvParameterException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception wraps exceptions whose messages contain a reference to an env parameter. + * + * @author Nicolas Grekas + */ +class EnvParameterException extends InvalidArgumentException +{ + public function __construct(array $usedEnvs, \Exception $previous = null) + { + parent::__construct(sprintf('Incompatible use of dynamic environment variables "%s" found in parameters.', implode('", "', $usedEnvs)), 0, $previous); + } +} diff --git a/vendor/symfony/dependency-injection/Exception/InactiveScopeException.php b/vendor/symfony/dependency-injection/Exception/InactiveScopeException.php deleted file mode 100644 index 6b3dd3eb..00000000 --- a/vendor/symfony/dependency-injection/Exception/InactiveScopeException.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Exception; - -/** - * This exception is thrown when you try to create a service of an inactive scope. - * - * @author Johannes M. Schmitt - */ -class InactiveScopeException extends RuntimeException -{ - private $serviceId; - private $scope; - - public function __construct($serviceId, $scope, \Exception $previous = null) - { - parent::__construct(sprintf('You cannot create a service ("%s") of an inactive scope ("%s").', $serviceId, $scope), 0, $previous); - - $this->serviceId = $serviceId; - $this->scope = $scope; - } - - public function getServiceId() - { - return $this->serviceId; - } - - public function getScope() - { - return $this->scope; - } -} diff --git a/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php b/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php index ab7b86d5..40c01b05 100644 --- a/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php +++ b/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php @@ -22,20 +22,23 @@ class ParameterNotFoundException extends InvalidArgumentException private $sourceId; private $sourceKey; private $alternatives; + private $nonNestedAlternative; /** - * @param string $key The requested parameter key - * @param string $sourceId The service id that references the non-existent parameter - * @param string $sourceKey The parameter key that references the non-existent parameter - * @param \Exception $previous The previous exception - * @param string[] $alternatives Some parameter name alternatives + * @param string $key The requested parameter key + * @param string $sourceId The service id that references the non-existent parameter + * @param string $sourceKey The parameter key that references the non-existent parameter + * @param \Exception $previous The previous exception + * @param string[] $alternatives Some parameter name alternatives + * @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters */ - public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array()) + public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array(), $nonNestedAlternative = null) { $this->key = $key; $this->sourceId = $sourceId; $this->sourceKey = $sourceKey; $this->alternatives = $alternatives; + $this->nonNestedAlternative = $nonNestedAlternative; parent::__construct('', 0, $previous); @@ -59,6 +62,8 @@ public function updateRepr() $this->message .= ' Did you mean one of these: "'; } $this->message .= implode('", "', $this->alternatives).'"?'; + } elseif (null !== $this->nonNestedAlternative) { + $this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?'; } } diff --git a/vendor/symfony/dependency-injection/Exception/ScopeCrossingInjectionException.php b/vendor/symfony/dependency-injection/Exception/ScopeCrossingInjectionException.php deleted file mode 100644 index 661fbab3..00000000 --- a/vendor/symfony/dependency-injection/Exception/ScopeCrossingInjectionException.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Exception; - -/** - * This exception is thrown when the a scope crossing injection is detected. - * - * @author Johannes M. Schmitt - */ -class ScopeCrossingInjectionException extends RuntimeException -{ - private $sourceServiceId; - private $sourceScope; - private $destServiceId; - private $destScope; - - public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope, \Exception $previous = null) - { - parent::__construct(sprintf( - 'Scope Crossing Injection detected: The definition "%s" references the service "%s" which belongs to another scope hierarchy. ' - .'This service might not be available consistently. Generally, it is safer to either move the definition "%s" to scope "%s", or ' - .'declare "%s" as a child scope of "%s". If you can be sure that the other scope is always active, you can set the reference to strict=false to get rid of this error.', - $sourceServiceId, - $destServiceId, - $sourceServiceId, - $destScope, - $sourceScope, - $destScope - ), 0, $previous); - - $this->sourceServiceId = $sourceServiceId; - $this->sourceScope = $sourceScope; - $this->destServiceId = $destServiceId; - $this->destScope = $destScope; - } - - public function getSourceServiceId() - { - return $this->sourceServiceId; - } - - public function getSourceScope() - { - return $this->sourceScope; - } - - public function getDestServiceId() - { - return $this->destServiceId; - } - - public function getDestScope() - { - return $this->destScope; - } -} diff --git a/vendor/symfony/dependency-injection/Exception/ScopeWideningInjectionException.php b/vendor/symfony/dependency-injection/Exception/ScopeWideningInjectionException.php deleted file mode 100644 index 86a66841..00000000 --- a/vendor/symfony/dependency-injection/Exception/ScopeWideningInjectionException.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Exception; - -/** - * Thrown when a scope widening injection is detected. - * - * @author Johannes M. Schmitt - */ -class ScopeWideningInjectionException extends RuntimeException -{ - private $sourceServiceId; - private $sourceScope; - private $destServiceId; - private $destScope; - - public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope, \Exception $previous = null) - { - parent::__construct(sprintf( - 'Scope Widening Injection detected: The definition "%s" references the service "%s" which belongs to a narrower scope. ' - .'Generally, it is safer to either move "%s" to scope "%s" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "%s" each time it is needed. ' - .'In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.', - $sourceServiceId, - $destServiceId, - $sourceServiceId, - $destScope, - $destServiceId - ), 0, $previous); - - $this->sourceServiceId = $sourceServiceId; - $this->sourceScope = $sourceScope; - $this->destServiceId = $destServiceId; - $this->destScope = $destScope; - } - - public function getSourceServiceId() - { - return $this->sourceServiceId; - } - - public function getSourceScope() - { - return $this->sourceScope; - } - - public function getDestServiceId() - { - return $this->destServiceId; - } - - public function getDestScope() - { - return $this->destScope; - } -} diff --git a/vendor/symfony/dependency-injection/IntrospectableContainerInterface.php b/vendor/symfony/dependency-injection/IntrospectableContainerInterface.php deleted file mode 100644 index 4aa00599..00000000 --- a/vendor/symfony/dependency-injection/IntrospectableContainerInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection; - -/** - * IntrospectableContainerInterface defines additional introspection functionality - * for containers, allowing logic to be implemented based on a Container's state. - * - * @author Evan Villemez - * - * @deprecated since version 2.8, to be merged with ContainerInterface in 3.0. - */ -interface IntrospectableContainerInterface extends ContainerInterface -{ - /** - * Check for whether or not a service has been initialized. - * - * @param string $id - * - * @return bool true if the service has been initialized, false otherwise - */ - public function initialized($id); -} diff --git a/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php b/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php index 878d965b..ce88eba9 100644 --- a/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php +++ b/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php @@ -34,10 +34,11 @@ public function isProxyCandidate(Definition $definition); * * @param Definition $definition * @param string $id service identifier + * @param string $methodName the method name to get the service, will be added to the interface in 4.0 * * @return string */ - public function getProxyFactoryCode(Definition $definition, $id); + public function getProxyFactoryCode(Definition $definition, $id/**, $methodName = null */); /** * Generates the code for the lazy proxy. diff --git a/vendor/symfony/dependency-injection/Loader/IniFileLoader.php b/vendor/symfony/dependency-injection/Loader/IniFileLoader.php index 16ddf87f..9fea56be 100644 --- a/vendor/symfony/dependency-injection/Loader/IniFileLoader.php +++ b/vendor/symfony/dependency-injection/Loader/IniFileLoader.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Loader; use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Util\XmlUtils; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; /** @@ -30,14 +31,18 @@ public function load($resource, $type = null) $this->container->addResource(new FileResource($path)); + // first pass to catch parsing errors $result = parse_ini_file($path, true); if (false === $result || array() === $result) { throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource)); } + // real raw parsing + $result = parse_ini_file($path, true, INI_SCANNER_RAW); + if (isset($result['parameters']) && is_array($result['parameters'])) { foreach ($result['parameters'] as $key => $value) { - $this->container->setParameter($key, $value); + $this->container->setParameter($key, $this->phpize($value)); } } } @@ -49,4 +54,33 @@ public function supports($resource, $type = null) { return is_string($resource) && 'ini' === pathinfo($resource, PATHINFO_EXTENSION); } + + /** + * Note that the following features are not supported: + * * strings with escaped quotes are not supported "foo\"bar"; + * * string concatenation ("foo" "bar"). + */ + private function phpize($value) + { + // trim on the right as comments removal keep whitespaces + $value = rtrim($value); + $lowercaseValue = strtolower($value); + + switch (true) { + case defined($value): + return constant($value); + case 'yes' === $lowercaseValue || 'on' === $lowercaseValue: + return true; + case 'no' === $lowercaseValue || 'off' === $lowercaseValue || 'none' === $lowercaseValue: + return false; + case isset($value[1]) && ( + ("'" === $value[0] && "'" === $value[strlen($value) - 1]) || + ('"' === $value[0] && '"' === $value[strlen($value) - 1]) + ): + // quoted string + return substr($value, 1, -1); + default: + return XmlUtils::phpize($value); + } + } } diff --git a/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php b/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php index dc7ca933..d0009c33 100644 --- a/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php +++ b/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php @@ -133,6 +133,8 @@ private function parseDefinitions(\DOMDocument $xml, $file) private function parseDefinition(\DOMElement $service, $file) { if ($alias = $service->getAttribute('alias')) { + $this->validateAlias($service, $file); + $public = true; if ($publicAttr = $service->getAttribute('public')) { $public = XmlUtils::phpize($publicAttr); @@ -148,12 +150,9 @@ private function parseDefinition(\DOMElement $service, $file) $definition = new Definition(); } - foreach (array('class', 'shared', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'lazy', 'abstract') as $key) { + foreach (array('class', 'shared', 'public', 'synthetic', 'lazy', 'abstract') as $key) { if ($value = $service->getAttribute($key)) { - if (in_array($key, array('factory-class', 'factory-method', 'factory-service'))) { - @trigger_error(sprintf('The "%s" attribute of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use the "factory" element instead.', $key, (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED); - } - $method = 'set'.str_replace('-', '', $key); + $method = 'set'.$key; $definition->$method(XmlUtils::phpize($value)); } } @@ -162,26 +161,6 @@ private function parseDefinition(\DOMElement $service, $file) $definition->setAutowired(XmlUtils::phpize($value)); } - if ($value = $service->getAttribute('scope')) { - $triggerDeprecation = 'request' !== (string) $service->getAttribute('id'); - - if ($triggerDeprecation) { - @trigger_error(sprintf('The "scope" attribute of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED); - } - - $definition->setScope(XmlUtils::phpize($value), false); - } - - if ($value = $service->getAttribute('synchronized')) { - $triggerDeprecation = 'request' !== (string) $service->getAttribute('id'); - - if ($triggerDeprecation) { - @trigger_error(sprintf('The "synchronized" attribute of service "%s" in file "%s" is deprecated since version 2.7 and will be removed in 3.0.', (string) $service->getAttribute('id'), $file), E_USER_DEPRECATED); - } - - $definition->setSynchronized(XmlUtils::phpize($value), $triggerDeprecation); - } - if ($files = $this->getChildren($service, 'file')) { $definition->setFile($files[0]->nodeValue); } @@ -203,7 +182,7 @@ private function parseDefinition(\DOMElement $service, $file) if (isset($factoryService[0])) { $class = $this->parseDefinition($factoryService[0], $file); } elseif ($childService = $factory->getAttribute('service')) { - $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false); + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); } else { $class = $factory->getAttribute('class'); } @@ -222,7 +201,7 @@ private function parseDefinition(\DOMElement $service, $file) if (isset($configuratorService[0])) { $class = $this->parseDefinition($configuratorService[0], $file); } elseif ($childService = $configurator->getAttribute('service')) { - $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false); + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); } else { $class = $configurator->getAttribute('class'); } @@ -245,7 +224,7 @@ private function parseDefinition(\DOMElement $service, $file) if (false !== strpos($name, '-') && false === strpos($name, '_') && !array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) { $parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue); } - // keep not normalized key for BC too + // keep not normalized key $parameters[$name] = XmlUtils::phpize($node->nodeValue); } @@ -335,9 +314,7 @@ private function processAnonymousServices(\DOMDocument $xml, $file) // resolve definitions krsort($definitions); - foreach ($definitions as $id => $def) { - list($domElement, $file, $wild) = $def; - + foreach ($definitions as $id => list($domElement, $file, $wild)) { if (null !== $definition = $this->parseDefinition($domElement, $file)) { $this->container->setDefinition($id, $definition); } @@ -397,13 +374,7 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true) $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; } - if ($strict = $arg->getAttribute('strict')) { - $strict = XmlUtils::phpize($strict); - } else { - $strict = true; - } - - $arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior, $strict); + $arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior); break; case 'expression': $arguments[$key] = new Expression($arg->nodeValue); @@ -519,6 +490,27 @@ public function validateSchema(\DOMDocument $dom) return $valid; } + /** + * Validates an alias. + * + * @param \DOMElement $alias + * @param string $file + */ + private function validateAlias(\DOMElement $alias, $file) + { + foreach ($alias->attributes as $name => $node) { + if (!in_array($name, array('alias', 'id', 'public'))) { + @trigger_error(sprintf('Using the attribute "%s" is deprecated for the service "%s" which is defined as an alias in "%s". Allowed attributes for service aliases are "alias", "id" and "public". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $name, $alias->getAttribute('id'), $file), E_USER_DEPRECATED); + } + } + + foreach ($alias->childNodes as $child) { + if ($child instanceof \DOMElement && $child->namespaceURI === self::NS) { + @trigger_error(sprintf('Using the element "%s" is deprecated for the service "%s" which is defined as an alias in "%s". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported elements.', $child->localName, $alias->getAttribute('id'), $file), E_USER_DEPRECATED); + } + } + } + /** * Validates an extension. * diff --git a/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php b/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php index dbfc0524..cd9bcbba 100644 --- a/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php +++ b/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php @@ -21,6 +21,7 @@ use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser as YamlParser; +use Symfony\Component\Yaml\Yaml; use Symfony\Component\ExpressionLanguage\Expression; /** @@ -32,6 +33,30 @@ */ class YamlFileLoader extends FileLoader { + private static $keywords = array( + 'alias' => 'alias', + 'parent' => 'parent', + 'class' => 'class', + 'shared' => 'shared', + 'synthetic' => 'synthetic', + 'lazy' => 'lazy', + 'public' => 'public', + 'abstract' => 'abstract', + 'deprecated' => 'deprecated', + 'factory' => 'factory', + 'file' => 'file', + 'arguments' => 'arguments', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'decorates' => 'decorates', + 'decoration_inner_name' => 'decoration_inner_name', + 'decoration_priority' => 'decoration_priority', + 'autowire' => 'autowire', + 'autowiring_types' => 'autowiring_types', + ); + private $yamlParser; /** @@ -85,7 +110,7 @@ public function supports($resource, $type = null) * @param array $content * @param string $file */ - private function parseImports($content, $file) + private function parseImports(array $content, $file) { if (!isset($content['imports'])) { return; @@ -112,7 +137,7 @@ private function parseImports($content, $file) * @param array $content * @param string $file */ - private function parseDefinitions($content, $file) + private function parseDefinitions(array $content, $file) { if (!isset($content['services'])) { return; @@ -130,9 +155,9 @@ private function parseDefinitions($content, $file) /** * Parses a definition. * - * @param string $id - * @param array $service - * @param string $file + * @param string $id + * @param array|string $service + * @param string $file * * @throws InvalidArgumentException When tags are invalid */ @@ -148,10 +173,18 @@ private function parseDefinition($id, $service, $file) throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file)); } + static::checkDefinition($id, $service, $file); + if (isset($service['alias'])) { $public = !array_key_exists('public', $service) || (bool) $service['public']; $this->container->setAlias($id, new Alias($service['alias'], $public)); + foreach ($service as $key => $value) { + if (!in_array($key, array('alias', 'public'))) { + @trigger_error(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED); + } + } + return; } @@ -169,22 +202,10 @@ private function parseDefinition($id, $service, $file) $definition->setShared($service['shared']); } - if (isset($service['scope'])) { - if ('request' !== $id) { - @trigger_error(sprintf('The "scope" key of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED); - } - $definition->setScope($service['scope'], false); - } - if (isset($service['synthetic'])) { $definition->setSynthetic($service['synthetic']); } - if (isset($service['synchronized'])) { - @trigger_error(sprintf('The "synchronized" key of service "%s" in file "%s" is deprecated since version 2.7 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED); - $definition->setSynchronized($service['synchronized'], 'request' !== $id); - } - if (isset($service['lazy'])) { $definition->setLazy($service['lazy']); } @@ -202,31 +223,7 @@ private function parseDefinition($id, $service, $file) } if (isset($service['factory'])) { - if (is_string($service['factory'])) { - if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) { - $parts = explode(':', $service['factory']); - $definition->setFactory(array($this->resolveServices('@'.$parts[0]), $parts[1])); - } else { - $definition->setFactory($service['factory']); - } - } else { - $definition->setFactory(array($this->resolveServices($service['factory'][0]), $service['factory'][1])); - } - } - - if (isset($service['factory_class'])) { - @trigger_error(sprintf('The "factory_class" key of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $id, $file), E_USER_DEPRECATED); - $definition->setFactoryClass($service['factory_class']); - } - - if (isset($service['factory_method'])) { - @trigger_error(sprintf('The "factory_method" key of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $id, $file), E_USER_DEPRECATED); - $definition->setFactoryMethod($service['factory_method']); - } - - if (isset($service['factory_service'])) { - @trigger_error(sprintf('The "factory_service" key of service "%s" in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use "factory" instead.', $id, $file), E_USER_DEPRECATED); - $definition->setFactoryService($service['factory_service']); + $definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file)); } if (isset($service['file'])) { @@ -242,11 +239,7 @@ private function parseDefinition($id, $service, $file) } if (isset($service['configurator'])) { - if (is_string($service['configurator'])) { - $definition->setConfigurator($service['configurator']); - } else { - $definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1])); - } + $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file)); } if (isset($service['calls'])) { @@ -333,6 +326,45 @@ private function parseDefinition($id, $service, $file) $this->container->setDefinition($id, $definition); } + /** + * Parses a callable. + * + * @param string|array $callable A callable + * @param string $parameter A parameter (e.g. 'factory' or 'configurator') + * @param string $id A service identifier + * @param string $file A parsed file + * + * @throws InvalidArgumentException When errors are occuried + * + * @return string|array A parsed callable + */ + private function parseCallable($callable, $parameter, $id, $file) + { + if (is_string($callable)) { + if ('' !== $callable && '@' === $callable[0]) { + throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $parameter, $id, $callable, substr($callable, 1))); + } + + if (false !== strpos($callable, ':') && false === strpos($callable, '::')) { + $parts = explode(':', $callable); + + return array($this->resolveServices('@'.$parts[0]), $parts[1]); + } + + return $callable; + } + + if (is_array($callable)) { + if (isset($callable[0]) && isset($callable[1])) { + return array($this->resolveServices($callable[0]), $callable[1]); + } + + throw new InvalidArgumentException(sprintf('Parameter "%s" must contain an array with two elements for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file)); + } + + throw new InvalidArgumentException(sprintf('Parameter "%s" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file)); + } + /** * Loads a YAML file. * @@ -353,7 +385,7 @@ protected function loadFile($file) } if (!file_exists($file)) { - throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file)); + throw new InvalidArgumentException(sprintf('The file "%s" does not exist.', $file)); } if (null === $this->yamlParser) { @@ -361,7 +393,7 @@ protected function loadFile($file) } try { - $configuration = $this->yamlParser->parse(file_get_contents($file)); + $configuration = $this->yamlParser->parse(file_get_contents($file), Yaml::PARSE_CONSTANT); } catch (ParseException $e) { throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e); } @@ -436,13 +468,10 @@ private function resolveServices($value) if ('=' === substr($value, -1)) { $value = substr($value, 0, -1); - $strict = false; - } else { - $strict = true; } if (null !== $invalidBehavior) { - $value = new Reference($value, $invalidBehavior, $strict); + $value = new Reference($value, $invalidBehavior); } } @@ -454,7 +483,7 @@ private function resolveServices($value) * * @param array $content */ - private function loadFromExtensions($content) + private function loadFromExtensions(array $content) { foreach ($content as $namespace => $values) { if (in_array($namespace, array('imports', 'parameters', 'services'))) { @@ -468,4 +497,24 @@ private function loadFromExtensions($content) $this->container->loadFromExtension($namespace, $values); } } + + /** + * Checks the keywords used to define a service. + * + * @param string $id The service name + * @param array $definition The service definition to check + * @param string $file The loaded YAML file + */ + private static function checkDefinition($id, array $definition, $file) + { + foreach ($definition as $key => $value) { + if (!isset(static::$keywords[$key])) { + @trigger_error(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s". The YamlFileLoader object will raise an exception instead in Symfony 4.0 when detecting an unsupported service configuration key.', $key, $id, $file, implode('", "', static::$keywords)), E_USER_DEPRECATED); + // @deprecated Uncomment the following statement in Symfony 4.0 + // and also update the corresponding unit test to make it expect + // an InvalidArgumentException exception. + //throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', static::$keywords))); + } + } + } } diff --git a/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd b/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd index 530ca1c1..68387c9c 100644 --- a/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd +++ b/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd @@ -104,15 +104,10 @@ - - - - - @@ -145,8 +140,8 @@ - - + + @@ -158,8 +153,8 @@ - - + + @@ -170,10 +165,9 @@ - - - - + + + diff --git a/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php b/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php new file mode 100644 index 00000000..d20e5353 --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas + */ +class EnvPlaceholderParameterBag extends ParameterBag +{ + private $envPlaceholders = array(); + + /** + * {@inheritdoc} + */ + public function get($name) + { + if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) { + $env = substr($name, 4, -1); + + if (isset($this->envPlaceholders[$env])) { + foreach ($this->envPlaceholders[$env] as $placeholder) { + return $placeholder; // return first result + } + } + if (preg_match('/\W/', $env)) { + throw new InvalidArgumentException(sprintf('Invalid %s name: only "word" characters are allowed.', $name)); + } + + if ($this->has($name)) { + $defaultValue = parent::get($name); + + if (null !== $defaultValue && !is_scalar($defaultValue)) { + throw new RuntimeException(sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', gettype($defaultValue), $name)); + } + } + + $uniqueName = md5($name.uniqid(mt_rand(), true)); + $placeholder = sprintf('env_%s_%s', $env, $uniqueName); + $this->envPlaceholders[$env][$placeholder] = $placeholder; + + return $placeholder; + } + + return parent::get($name); + } + + /** + * Returns the map of env vars used in the resolved parameter values to their placeholders. + * + * @return string[][] A map of env var names to their placeholders + */ + public function getEnvPlaceholders() + { + return $this->envPlaceholders; + } + + /** + * Merges the env placeholders of another EnvPlaceholderParameterBag. + */ + public function mergeEnvPlaceholders(self $bag) + { + if ($newPlaceholders = $bag->getEnvPlaceholders()) { + $this->envPlaceholders += $newPlaceholders; + + foreach ($newPlaceholders as $env => $placeholders) { + $this->envPlaceholders[$env] += $placeholders; + } + } + } + + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + parent::resolve(); + + foreach ($this->envPlaceholders as $env => $placeholders) { + if (!isset($this->parameters[$name = strtolower("env($env)")])) { + continue; + } + if (is_numeric($default = $this->parameters[$name])) { + $this->parameters[$name] = (string) $default; + } elseif (null !== $default && !is_scalar($default)) { + throw new RuntimeException(sprintf('The default value of env parameter "%s" must be scalar or null, %s given.', $env, gettype($default))); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php b/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php index 0611b1f6..83ba7e70 100644 --- a/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php +++ b/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php @@ -81,7 +81,23 @@ public function get($name) } } - throw new ParameterNotFoundException($name, null, null, null, $alternatives); + $nonNestedAlternative = null; + if (!count($alternatives) && false !== strpos($name, '.')) { + $namePartsLength = array_map('strlen', explode('.', $name)); + $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength))); + while (count($namePartsLength)) { + if ($this->has($key)) { + if (is_array($this->get($key))) { + $nonNestedAlternative = $key; + } + break; + } + + $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength))); + } + } + + throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative); } return $this->parameters[$name]; @@ -189,40 +205,40 @@ public function resolveString($value, array $resolving = array()) // as the preg_replace_callback throw an exception when trying // a non-string in a parameter value if (preg_match('/^%([^%\s]+)%$/', $value, $match)) { - $key = strtolower($match[1]); + $key = $match[1]; + $lcKey = strtolower($key); - if (isset($resolving[$key])) { + if (isset($resolving[$lcKey])) { throw new ParameterCircularReferenceException(array_keys($resolving)); } - $resolving[$key] = true; + $resolving[$lcKey] = true; return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving); } - $self = $this; - - return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($self, $resolving, $value) { + return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) { // skip %% if (!isset($match[1])) { return '%%'; } - $key = strtolower($match[1]); - if (isset($resolving[$key])) { + $key = $match[1]; + $lcKey = strtolower($key); + if (isset($resolving[$lcKey])) { throw new ParameterCircularReferenceException(array_keys($resolving)); } - $resolved = $self->get($key); + $resolved = $this->get($key); if (!is_string($resolved) && !is_numeric($resolved)) { throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".', $key, gettype($resolved), $value)); } $resolved = (string) $resolved; - $resolving[$key] = true; + $resolving[$lcKey] = true; - return $self->isResolved() ? $resolved : $self->resolveString($resolved, $resolving); + return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving); }, $value); } diff --git a/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php b/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php index 3291b373..7386df06 100644 --- a/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php +++ b/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php @@ -55,6 +55,13 @@ public function all(); */ public function get($name); + /** + * Removes a parameter. + * + * @param string $name The parameter name + */ + public function remove($name); + /** * Sets a service container parameter. * diff --git a/vendor/symfony/dependency-injection/Reference.php b/vendor/symfony/dependency-injection/Reference.php index cb244502..3c8b314f 100644 --- a/vendor/symfony/dependency-injection/Reference.php +++ b/vendor/symfony/dependency-injection/Reference.php @@ -20,22 +20,17 @@ class Reference { private $id; private $invalidBehavior; - private $strict; /** - * Note: The $strict parameter is deprecated since version 2.8 and will be removed in 3.0. - * * @param string $id The service identifier * @param int $invalidBehavior The behavior when the service does not exist - * @param bool $strict Sets how this reference is validated * * @see Container */ - public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $strict = true) + public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) { $this->id = strtolower($id); $this->invalidBehavior = $invalidBehavior; - $this->strict = $strict; } /** @@ -55,20 +50,4 @@ public function getInvalidBehavior() { return $this->invalidBehavior; } - - /** - * Returns true when this Reference is strict. - * - * @return bool - * - * @deprecated since version 2.8, to be removed in 3.0. - */ - public function isStrict($triggerDeprecationError = true) - { - if ($triggerDeprecationError) { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - } - - return $this->strict; - } } diff --git a/vendor/symfony/dependency-injection/Scope.php b/vendor/symfony/dependency-injection/Scope.php deleted file mode 100644 index b0b8ed6c..00000000 --- a/vendor/symfony/dependency-injection/Scope.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection; - -/** - * Scope class. - * - * @author Johannes M. Schmitt - * - * @deprecated since version 2.8, to be removed in 3.0. - */ -class Scope implements ScopeInterface -{ - private $name; - private $parentName; - - public function __construct($name, $parentName = ContainerInterface::SCOPE_CONTAINER) - { - $this->name = $name; - $this->parentName = $parentName; - } - - public function getName() - { - return $this->name; - } - - public function getParentName() - { - return $this->parentName; - } -} diff --git a/vendor/symfony/dependency-injection/ScopeInterface.php b/vendor/symfony/dependency-injection/ScopeInterface.php deleted file mode 100644 index 11b10973..00000000 --- a/vendor/symfony/dependency-injection/ScopeInterface.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection; - -/** - * Scope Interface. - * - * @author Johannes M. Schmitt - * - * @deprecated since version 2.8, to be removed in 3.0. - */ -interface ScopeInterface -{ - public function getName(); - - public function getParentName(); -} diff --git a/vendor/symfony/dependency-injection/SimpleXMLElement.php b/vendor/symfony/dependency-injection/SimpleXMLElement.php deleted file mode 100644 index 87c67c4d..00000000 --- a/vendor/symfony/dependency-injection/SimpleXMLElement.php +++ /dev/null @@ -1,116 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection; - -@trigger_error('The '.__NAMESPACE__.'\SimpleXMLElement class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -use Symfony\Component\Config\Util\XmlUtils; -use Symfony\Component\ExpressionLanguage\Expression; - -/** - * SimpleXMLElement class. - * - * @author Fabien Potencier - * - * @deprecated since version 2.5, to be removed in 3.0. - */ -class SimpleXMLElement extends \SimpleXMLElement -{ - /** - * Converts an attribute as a PHP type. - * - * @param string $name - * - * @return mixed - */ - public function getAttributeAsPhp($name) - { - return self::phpize($this[$name]); - } - - /** - * Returns arguments as valid PHP types. - * - * @param string $name - * @param bool $lowercase - * - * @return mixed - */ - public function getArgumentsAsPhp($name, $lowercase = true) - { - $arguments = array(); - foreach ($this->$name as $arg) { - if (isset($arg['name'])) { - $arg['key'] = (string) $arg['name']; - } - $key = isset($arg['key']) ? (string) $arg['key'] : (!$arguments ? 0 : max(array_keys($arguments)) + 1); - - // parameter keys are case insensitive - if ('parameter' == $name && $lowercase) { - $key = strtolower($key); - } - - // this is used by DefinitionDecorator to overwrite a specific - // argument of the parent definition - if (isset($arg['index'])) { - $key = 'index_'.$arg['index']; - } - - switch ($arg['type']) { - case 'service': - $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; - if (isset($arg['on-invalid']) && 'ignore' == $arg['on-invalid']) { - $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; - } elseif (isset($arg['on-invalid']) && 'null' == $arg['on-invalid']) { - $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; - } - - if (isset($arg['strict'])) { - $strict = self::phpize($arg['strict']); - } else { - $strict = true; - } - - $arguments[$key] = new Reference((string) $arg['id'], $invalidBehavior, $strict); - break; - case 'expression': - $arguments[$key] = new Expression((string) $arg); - break; - case 'collection': - $arguments[$key] = $arg->getArgumentsAsPhp($name, false); - break; - case 'string': - $arguments[$key] = (string) $arg; - break; - case 'constant': - $arguments[$key] = constant((string) $arg); - break; - default: - $arguments[$key] = self::phpize($arg); - } - } - - return $arguments; - } - - /** - * Converts an xml value to a PHP type. - * - * @param mixed $value - * - * @return mixed - */ - public static function phpize($value) - { - return XmlUtils::phpize($value); - } -} diff --git a/vendor/symfony/dependency-injection/composer.json b/vendor/symfony/dependency-injection/composer.json index 2506690c..0f3ae8de 100644 --- a/vendor/symfony/dependency-injection/composer.json +++ b/vendor/symfony/dependency-injection/composer.json @@ -16,15 +16,12 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "require-dev": { - "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7", - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0" - }, - "conflict": { - "symfony/expression-language": "<2.6" + "symfony/yaml": "~3.2", + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0" }, "suggest": { "symfony/yaml": "", @@ -32,6 +29,9 @@ "symfony/expression-language": "For using expressions in service container configuration", "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them" }, + "conflict": { + "symfony/yaml": "<3.2" + }, "autoload": { "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" }, "exclude-from-classmap": [ @@ -41,7 +41,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/dependency-injection/phpunit.xml.dist b/vendor/symfony/dependency-injection/phpunit.xml.dist index 86252d04..781f767d 100644 --- a/vendor/symfony/dependency-injection/phpunit.xml.dist +++ b/vendor/symfony/dependency-injection/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/event-dispatcher/CHANGELOG.md b/vendor/symfony/event-dispatcher/CHANGELOG.md index bb42ee19..8feda35d 100644 --- a/vendor/symfony/event-dispatcher/CHANGELOG.md +++ b/vendor/symfony/event-dispatcher/CHANGELOG.md @@ -1,6 +1,15 @@ CHANGELOG ========= +3.0.0 +----- + + * The method `getListenerPriority($eventName, $listener)` has been added to the + `EventDispatcherInterface`. + * The methods `Event::setDispatcher()`, `Event::getDispatcher()`, `Event::setName()` + and `Event::getName()` have been removed. + The event dispatcher and the event name are passed to the listener call. + 2.5.0 ----- diff --git a/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php b/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php index 6a02e9f9..5982b85f 100644 --- a/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php +++ b/vendor/symfony/event-dispatcher/ContainerAwareEventDispatcher.php @@ -80,8 +80,7 @@ public function removeListener($eventName, $listener) $this->lazyLoad($eventName); if (isset($this->listenerIds[$eventName])) { - foreach ($this->listenerIds[$eventName] as $i => $args) { - list($serviceId, $method, $priority) = $args; + foreach ($this->listenerIds[$eventName] as $i => list($serviceId, $method, $priority)) { $key = $serviceId.'.'.$method; if (isset($this->listeners[$eventName][$key]) && $listener === array($this->listeners[$eventName][$key], $method)) { unset($this->listeners[$eventName][$key]); @@ -178,8 +177,7 @@ public function getContainer() protected function lazyLoad($eventName) { if (isset($this->listenerIds[$eventName])) { - foreach ($this->listenerIds[$eventName] as $args) { - list($serviceId, $method, $priority) = $args; + foreach ($this->listenerIds[$eventName] as list($serviceId, $method, $priority)) { $listener = $this->container->get($serviceId); $key = $serviceId.'.'.$method; diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php index 9b460f55..988cf112 100644 --- a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php +++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -104,8 +104,14 @@ public function getListeners($eventName = null) */ public function getListenerPriority($eventName, $listener) { - if (!method_exists($this->dispatcher, 'getListenerPriority')) { - return 0; + // we might have wrapped listeners for the event (if called while dispatching) + // in that case get the priority by wrapper + if (isset($this->wrappedListeners[$eventName])) { + foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) { + if ($wrappedListener->getWrappedListener() === $listener) { + return $this->dispatcher->getListenerPriority($eventName, $wrappedListener); + } + } } return $this->dispatcher->getListenerPriority($eventName, $listener); @@ -157,8 +163,7 @@ public function getCalledListeners() $called = array(); foreach ($this->called as $eventName => $listeners) { foreach ($listeners as $listener) { - $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName); - $called[$eventName.'.'.$info['pretty']] = $info; + $called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName); } } @@ -196,8 +201,10 @@ public function getNotCalledListeners() } if (!$called) { - $info = $this->getListenerInfo($listener, $eventName); - $notCalled[$eventName.'.'.$info['pretty']] = $info; + if (!$listener instanceof WrappedListener) { + $listener = new WrappedListener($listener, null, $this->stopwatch, $this); + } + $notCalled[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName); } } } @@ -243,12 +250,11 @@ protected function postDispatch($eventName, Event $event) private function preProcess($eventName) { foreach ($this->dispatcher->getListeners($eventName) as $listener) { - $info = $this->getListenerInfo($listener, $eventName); - $name = isset($info['class']) ? $info['class'] : $info['type']; - $wrappedListener = new WrappedListener($listener, $name, $this->stopwatch, $this); + $priority = $this->getListenerPriority($eventName, $listener); + $wrappedListener = new WrappedListener($listener, null, $this->stopwatch, $this); $this->wrappedListeners[$eventName][] = $wrappedListener; $this->dispatcher->removeListener($eventName, $listener); - $this->dispatcher->addListener($eventName, $wrappedListener, $info['priority']); + $this->dispatcher->addListener($eventName, $wrappedListener, $priority); } } @@ -265,10 +271,13 @@ private function postProcess($eventName) $this->dispatcher->removeListener($eventName, $listener); $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority); - $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName); + if (null !== $this->logger) { + $context = array('event' => $eventName, 'listener' => $listener->getPretty()); + } + if ($listener->wasCalled()) { if (null !== $this->logger) { - $this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, $info['pretty'])); + $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context); } if (!isset($this->called[$eventName])) { @@ -279,12 +288,12 @@ private function postProcess($eventName) } if (null !== $this->logger && $skipped) { - $this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', $info['pretty'], $eventName)); + $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context); } if ($listener->stoppedPropagation()) { if (null !== $this->logger) { - $this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', $info['pretty'], $eventName)); + $this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context); } $skipped = true; @@ -292,67 +301,6 @@ private function postProcess($eventName) } } - /** - * Returns information about the listener. - * - * @param object $listener The listener - * @param string $eventName The event name - * - * @return array Information about the listener - */ - private function getListenerInfo($listener, $eventName) - { - $info = array( - 'event' => $eventName, - 'priority' => $this->getListenerPriority($eventName, $listener), - ); - if ($listener instanceof \Closure) { - $info += array( - 'type' => 'Closure', - 'pretty' => 'closure', - ); - } elseif (is_string($listener)) { - try { - $r = new \ReflectionFunction($listener); - $file = $r->getFileName(); - $line = $r->getStartLine(); - } catch (\ReflectionException $e) { - $file = null; - $line = null; - } - $info += array( - 'type' => 'Function', - 'function' => $listener, - 'file' => $file, - 'line' => $line, - 'pretty' => $listener, - ); - } elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) { - if (!is_array($listener)) { - $listener = array($listener, '__invoke'); - } - $class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0]; - try { - $r = new \ReflectionMethod($class, $listener[1]); - $file = $r->getFileName(); - $line = $r->getStartLine(); - } catch (\ReflectionException $e) { - $file = null; - $line = null; - } - $info += array( - 'type' => 'Method', - 'class' => $class, - 'method' => $listener[1], - 'file' => $file, - 'line' => $line, - 'pretty' => $class.'::'.$listener[1], - ); - } - - return $info; - } - private function sortListenersByPriority($a, $b) { if (is_int($a['priority']) && !is_int($b['priority'])) { diff --git a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php index e16627d6..45208a19 100644 --- a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php +++ b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php @@ -14,6 +14,8 @@ use Symfony\Component\Stopwatch\Stopwatch; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Cloner\VarCloner; /** * @author Fabien Potencier @@ -26,6 +28,10 @@ class WrappedListener private $stoppedPropagation; private $stopwatch; private $dispatcher; + private $pretty; + private $data; + + private static $cloner; public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) { @@ -35,6 +41,26 @@ public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatc $this->dispatcher = $dispatcher; $this->called = false; $this->stoppedPropagation = false; + + if (is_array($listener)) { + $this->name = is_object($listener[0]) ? get_class($listener[0]) : $listener[0]; + $this->pretty = $this->name.'::'.$listener[1]; + } elseif ($listener instanceof \Closure) { + $this->pretty = $this->name = 'closure'; + } elseif (is_string($listener)) { + $this->pretty = $this->name = $listener; + } else { + $this->name = get_class($listener); + $this->pretty = $this->name.'::__invoke'; + } + + if (null !== $name) { + $this->name = $name; + } + + if (null === self::$cloner) { + self::$cloner = class_exists(ClassStub::class) ? new VarCloner() : false; + } } public function getWrappedListener() @@ -52,6 +78,25 @@ public function stoppedPropagation() return $this->stoppedPropagation; } + public function getPretty() + { + return $this->pretty; + } + + public function getInfo($eventName) + { + if (null === $this->data) { + $this->data = false !== self::$cloner ? self::$cloner->cloneVar(array(new ClassStub($this->pretty.'()', $this->listener)))->seek(0) : $this->pretty; + } + + return array( + 'event' => $eventName, + 'priority' => null !== $this->dispatcher ? $this->dispatcher->getListenerPriority($eventName, $this->listener) : null, + 'pretty' => $this->pretty, + 'data' => $this->data, + ); + } + public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) { $this->called = true; diff --git a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php index 326bfd18..4636ba3a 100644 --- a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php +++ b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php @@ -13,6 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; /** * Compiler pass to register tagged services for an event dispatcher. @@ -59,18 +60,18 @@ public function process(ContainerBuilder $container) foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) { $def = $container->getDefinition($id); if (!$def->isPublic()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id)); + throw new InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id)); } if ($def->isAbstract()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id)); + throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id)); } foreach ($events as $event) { $priority = isset($event['priority']) ? $event['priority'] : 0; if (!isset($event['event'])) { - throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); + throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); } if (!isset($event['method'])) { @@ -88,11 +89,11 @@ public function process(ContainerBuilder $container) foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) { $def = $container->getDefinition($id); if (!$def->isPublic()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id)); + throw new InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id)); } if ($def->isAbstract()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event subscribers are lazy-loaded.', $id)); + throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as event subscribers are lazy-loaded.', $id)); } // We must assume that the class value has been correctly filled, even if the service is created by a factory @@ -101,10 +102,10 @@ public function process(ContainerBuilder $container) if (!is_subclass_of($class, $interface)) { if (!class_exists($class, false)) { - throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } - throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); } $definition->addMethodCall('addSubscriberService', array($id, $class)); diff --git a/vendor/symfony/event-dispatcher/Event.php b/vendor/symfony/event-dispatcher/Event.php index 3ce85496..9c56b2f5 100644 --- a/vendor/symfony/event-dispatcher/Event.php +++ b/vendor/symfony/event-dispatcher/Event.php @@ -32,16 +32,6 @@ class Event */ private $propagationStopped = false; - /** - * @var EventDispatcherInterface Dispatcher that dispatched this event - */ - private $dispatcher; - - /** - * @var string This event's name - */ - private $name; - /** * Returns whether further event listeners should be triggered. * @@ -65,56 +55,4 @@ public function stopPropagation() { $this->propagationStopped = true; } - - /** - * Stores the EventDispatcher that dispatches this Event. - * - * @param EventDispatcherInterface $dispatcher - * - * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call. - */ - public function setDispatcher(EventDispatcherInterface $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - /** - * Returns the EventDispatcher that dispatches this Event. - * - * @return EventDispatcherInterface - * - * @deprecated since version 2.4, to be removed in 3.0. The event dispatcher is passed to the listener call. - */ - public function getDispatcher() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event dispatcher instance can be received in the listener call instead.', E_USER_DEPRECATED); - - return $this->dispatcher; - } - - /** - * Gets the event's name. - * - * @return string - * - * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call. - */ - public function getName() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0. The event name can be received in the listener call instead.', E_USER_DEPRECATED); - - return $this->name; - } - - /** - * Sets the event's name property. - * - * @param string $name The event name - * - * @deprecated since version 2.4, to be removed in 3.0. The event name is passed to the listener call. - */ - public function setName($name) - { - $this->name = $name; - } } diff --git a/vendor/symfony/event-dispatcher/EventDispatcher.php b/vendor/symfony/event-dispatcher/EventDispatcher.php index bce44a14..01bfc006 100644 --- a/vendor/symfony/event-dispatcher/EventDispatcher.php +++ b/vendor/symfony/event-dispatcher/EventDispatcher.php @@ -39,9 +39,6 @@ public function dispatch($eventName, Event $event = null) $event = new Event(); } - $event->setDispatcher($this); - $event->setName($eventName); - if ($listeners = $this->getListeners($eventName)) { $this->doDispatch($listeners, $eventName, $event); } @@ -76,14 +73,7 @@ public function getListeners($eventName = null) } /** - * Gets the listener priority for a specific event. - * - * Returns null if the event or the listener does not exist. - * - * @param string $eventName The name of the event - * @param callable $listener The listener - * - * @return int|null The event listener priority + * {@inheritdoc} */ public function getListenerPriority($eventName, $listener) { @@ -103,7 +93,7 @@ public function getListenerPriority($eventName, $listener) */ public function hasListeners($eventName = null) { - return (bool) count($this->getListeners($eventName)); + return (bool) $this->getListeners($eventName); } /** diff --git a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php index abe8d289..08ebf340 100644 --- a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php +++ b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php @@ -77,6 +77,18 @@ public function removeSubscriber(EventSubscriberInterface $subscriber); */ public function getListeners($eventName = null); + /** + * Gets the listener priority for a specific event. + * + * Returns null if the event or the listener does not exist. + * + * @param string $eventName The name of the event + * @param callable $listener The listener + * + * @return int|null The event listener priority + */ + public function getListenerPriority($eventName, $listener); + /** * Checks whether an event has any registered listeners. * diff --git a/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php index 5e165326..5943039c 100644 --- a/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php +++ b/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php @@ -11,11 +11,12 @@ namespace Symfony\Component\EventDispatcher\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase +abstract class AbstractEventDispatcherTest extends TestCase { /* Some pseudo events */ const preFoo = 'pre.foo'; @@ -136,16 +137,6 @@ public function testDispatch() $this->assertSame($event, $return); } - /** - * @group legacy - */ - public function testLegacyDispatch() - { - $event = new Event(); - $this->dispatcher->dispatch(self::preFoo, $event); - $this->assertEquals('pre.foo', $event->getName()); - } - public function testDispatchForClosure() { $invoked = 0; @@ -263,19 +254,6 @@ public function testRemoveSubscriberWithMultipleListeners() $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); } - /** - * @group legacy - */ - public function testLegacyEventReceivesTheDispatcherInstance() - { - $dispatcher = null; - $this->dispatcher->addListener('test', function ($event) use (&$dispatcher) { - $dispatcher = $event->getDispatcher(); - }); - $this->dispatcher->dispatch('test'); - $this->assertSame($this->dispatcher, $dispatcher); - } - public function testEventReceivesTheDispatcherInstanceAsArgument() { $listener = new TestWithDispatcher(); diff --git a/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php index b1f84d48..2a0da9ca 100644 --- a/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php +++ b/vendor/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\EventDispatcher\Tests; use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\Scope; use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -104,72 +103,6 @@ public function testPreventDuplicateListenerService() $dispatcher->dispatch('onEvent', $event); } - /** - * @expectedException \InvalidArgumentException - * @group legacy - */ - public function testTriggerAListenerServiceOutOfScope() - { - $service = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); - - $scope = new Scope('scope'); - $container = new Container(); - $container->addScope($scope); - $container->enterScope('scope'); - - $container->set('service.listener', $service, 'scope'); - - $dispatcher = new ContainerAwareEventDispatcher($container); - $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); - - $container->leaveScope('scope'); - $dispatcher->dispatch('onEvent'); - } - - /** - * @group legacy - */ - public function testReEnteringAScope() - { - $event = new Event(); - - $service1 = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); - - $service1 - ->expects($this->exactly(2)) - ->method('onEvent') - ->with($event) - ; - - $scope = new Scope('scope'); - $container = new Container(); - $container->addScope($scope); - $container->enterScope('scope'); - - $container->set('service.listener', $service1, 'scope'); - - $dispatcher = new ContainerAwareEventDispatcher($container); - $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); - $dispatcher->dispatch('onEvent', $event); - - $service2 = $this->getMockBuilder('Symfony\Component\EventDispatcher\Tests\Service')->getMock(); - - $service2 - ->expects($this->once()) - ->method('onEvent') - ->with($event) - ; - - $container->enterScope('scope'); - $container->set('service.listener', $service2, 'scope'); - - $dispatcher->dispatch('onEvent', $event); - - $container->leaveScope('scope'); - - $dispatcher->dispatch('onEvent'); - } - public function testHasListenersOnLazyLoad() { $event = new Event(); @@ -182,9 +115,6 @@ public function testHasListenersOnLazyLoad() $dispatcher = new ContainerAwareEventDispatcher($container); $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent')); - $event->setDispatcher($dispatcher); - $event->setName('onEvent'); - $service ->expects($this->once()) ->method('onEvent') diff --git a/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php index 46eece72..9c129312 100644 --- a/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php +++ b/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -11,14 +11,16 @@ namespace Symfony\Component\EventDispatcher\Tests\Debug; +use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\Debug\WrappedListener; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\Stopwatch\Stopwatch; -class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase +class TraceableEventDispatcherTest extends TestCase { public function testAddRemoveListener() { @@ -73,14 +75,18 @@ public function testGetListenerPriority() $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0])); } - public function testGetListenerPriorityReturnsZeroWhenWrappedMethodDoesNotExist() + public function testGetListenerPriorityWhileDispatching() { - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); - $traceableEventDispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); - $traceableEventDispatcher->addListener('foo', function () {}, 123); - $listeners = $traceableEventDispatcher->getListeners('foo'); + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $priorityWhileDispatching = null; - $this->assertSame(0, $traceableEventDispatcher->getListenerPriority('foo', $listeners[0])); + $listener = function () use ($tdispatcher, &$priorityWhileDispatching, &$listener) { + $priorityWhileDispatching = $tdispatcher->getListenerPriority('bar', $listener); + }; + + $tdispatcher->addListener('bar', $listener, 5); + $tdispatcher->dispatch('bar'); + $this->assertSame(5, $priorityWhileDispatching); } public function testAddRemoveSubscriber() @@ -99,21 +105,43 @@ public function testAddRemoveSubscriber() $this->assertCount(0, $dispatcher->getListeners('foo')); } - public function testGetCalledListeners() + /** + * @dataProvider isWrappedDataProvider + * + * @param bool $isWrapped + */ + public function testGetCalledListeners($isWrapped) { $dispatcher = new EventDispatcher(); - $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); - $tdispatcher->addListener('foo', $listener = function () {}); + $stopWatch = new Stopwatch(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, $stopWatch); + + $listener = function () {}; + + $tdispatcher->addListener('foo', $listener, 5); + $listeners = $tdispatcher->getNotCalledListeners(); + $this->assertArrayHasKey('data', $listeners['foo.closure']); + unset($listeners['foo.closure']['data']); $this->assertEquals(array(), $tdispatcher->getCalledListeners()); - $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure', 'priority' => 0)), $tdispatcher->getNotCalledListeners()); + $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners); $tdispatcher->dispatch('foo'); - $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure', 'priority' => null)), $tdispatcher->getCalledListeners()); + $listeners = $tdispatcher->getCalledListeners(); + unset($listeners['foo.closure']['data']); + $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners); $this->assertEquals(array(), $tdispatcher->getNotCalledListeners()); } + public function isWrappedDataProvider() + { + return array( + array(false), + array(true), + ); + } + public function testGetCalledListenersNested() { $tdispatcher = null; @@ -137,8 +165,8 @@ public function testLogger() $tdispatcher->addListener('foo', $listener1 = function () {}); $tdispatcher->addListener('foo', $listener2 = function () {}); - $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); - $logger->expects($this->at(1))->method('debug')->with('Notified event "foo" to listener "closure".'); + $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure')); + $logger->expects($this->at(1))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure')); $tdispatcher->dispatch('foo'); } @@ -152,9 +180,9 @@ public function testLoggerWithStoppedEvent() $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); }); $tdispatcher->addListener('foo', $listener2 = function () {}); - $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); - $logger->expects($this->at(1))->method('debug')->with('Listener "closure" stopped propagation of the event "foo".'); - $logger->expects($this->at(2))->method('debug')->with('Listener "closure" was not called for event "foo".'); + $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', array('event' => 'foo', 'listener' => 'closure')); + $logger->expects($this->at(1))->method('debug')->with('Listener "{listener}" stopped propagation of the event "{event}".', array('event' => 'foo', 'listener' => 'closure')); + $logger->expects($this->at(2))->method('debug')->with('Listener "{listener}" was not called for event "{event}".', array('event' => 'foo', 'listener' => 'closure')); $tdispatcher->dispatch('foo'); } @@ -177,14 +205,20 @@ public function testDispatchNested() { $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); $loop = 1; + $dispatchedEvents = 0; $dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) { ++$loop; if (2 == $loop) { $dispatcher->dispatch('foo'); } }); + $dispatcher->addListener('foo', function () use (&$dispatchedEvents) { + ++$dispatchedEvents; + }); $dispatcher->dispatch('foo'); + + $this->assertSame(2, $dispatchedEvents); } public function testDispatchReusedEventNested() diff --git a/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php index cb04f74b..53d7282b 100644 --- a/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php +++ b/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -11,10 +11,11 @@ namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection; +use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; -class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase +class RegisterListenersPassTest extends TestCase { /** * Tests that event subscribers not implementing EventSubscriberInterface diff --git a/vendor/symfony/event-dispatcher/Tests/EventTest.php b/vendor/symfony/event-dispatcher/Tests/EventTest.php index 9a822670..5be2ea09 100644 --- a/vendor/symfony/event-dispatcher/Tests/EventTest.php +++ b/vendor/symfony/event-dispatcher/Tests/EventTest.php @@ -11,24 +11,19 @@ namespace Symfony\Component\EventDispatcher\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\Event; -use Symfony\Component\EventDispatcher\EventDispatcher; /** * Test class for Event. */ -class EventTest extends \PHPUnit_Framework_TestCase +class EventTest extends TestCase { /** * @var \Symfony\Component\EventDispatcher\Event */ protected $event; - /** - * @var \Symfony\Component\EventDispatcher\EventDispatcher - */ - protected $dispatcher; - /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -36,7 +31,6 @@ class EventTest extends \PHPUnit_Framework_TestCase protected function setUp() { $this->event = new Event(); - $this->dispatcher = new EventDispatcher(); } /** @@ -46,7 +40,6 @@ protected function setUp() protected function tearDown() { $this->event = null; - $this->dispatcher = null; } public function testIsPropagationStopped() @@ -59,38 +52,4 @@ public function testStopPropagationAndIsPropagationStopped() $this->event->stopPropagation(); $this->assertTrue($this->event->isPropagationStopped()); } - - /** - * @group legacy - */ - public function testLegacySetDispatcher() - { - $this->event->setDispatcher($this->dispatcher); - $this->assertSame($this->dispatcher, $this->event->getDispatcher()); - } - - /** - * @group legacy - */ - public function testLegacyGetDispatcher() - { - $this->assertNull($this->event->getDispatcher()); - } - - /** - * @group legacy - */ - public function testLegacyGetName() - { - $this->assertNull($this->event->getName()); - } - - /** - * @group legacy - */ - public function testLegacySetName() - { - $this->event->setName('foo'); - $this->assertEquals('foo', $this->event->getName()); - } } diff --git a/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php b/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php index aebd82da..c84d3ac2 100644 --- a/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php +++ b/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php @@ -11,12 +11,13 @@ namespace Symfony\Component\EventDispatcher\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\GenericEvent; /** * Test class for Event. */ -class GenericEventTest extends \PHPUnit_Framework_TestCase +class GenericEventTest extends TestCase { /** * @var GenericEvent @@ -95,7 +96,7 @@ public function testOffsetGet() $this->assertEquals('Event', $this->event['name']); // test getting invalid arg - $this->setExpectedException('InvalidArgumentException'); + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); $this->assertFalse($this->event['nameNotExist']); } diff --git a/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php index 0f886803..04f2861e 100644 --- a/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php +++ b/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php @@ -11,13 +11,14 @@ namespace Symfony\Component\EventDispatcher\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\ImmutableEventDispatcher; /** * @author Bernhard Schussek */ -class ImmutableEventDispatcherTest extends \PHPUnit_Framework_TestCase +class ImmutableEventDispatcherTest extends TestCase { /** * @var \PHPUnit_Framework_MockObject_MockObject diff --git a/vendor/symfony/event-dispatcher/composer.json b/vendor/symfony/event-dispatcher/composer.json index 282b770c..49031330 100644 --- a/vendor/symfony/event-dispatcher/composer.json +++ b/vendor/symfony/event-dispatcher/composer.json @@ -16,13 +16,13 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "require-dev": { - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", "psr/log": "~1.0" }, "suggest": { @@ -38,7 +38,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/event-dispatcher/phpunit.xml.dist b/vendor/symfony/event-dispatcher/phpunit.xml.dist index ae0586e0..b3ad1bdf 100644 --- a/vendor/symfony/event-dispatcher/phpunit.xml.dist +++ b/vendor/symfony/event-dispatcher/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/http-foundation/BinaryFileResponse.php b/vendor/symfony/http-foundation/BinaryFileResponse.php index 825c78fe..03146219 100644 --- a/vendor/symfony/http-foundation/BinaryFileResponse.php +++ b/vendor/symfony/http-foundation/BinaryFileResponse.php @@ -164,7 +164,7 @@ public function setContentDisposition($disposition, $filename = '', $filenameFal if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) { $encoding = mb_detect_encoding($filename, null, true); - for ($i = 0; $i < mb_strlen($filename, $encoding); ++$i) { + for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) { $char = mb_substr($filename, $i, 1, $encoding); if ('%' === $char || ord($char) < 32 || ord($char) > 126) { diff --git a/vendor/symfony/http-foundation/CHANGELOG.md b/vendor/symfony/http-foundation/CHANGELOG.md index 9f48e825..6baa1f40 100644 --- a/vendor/symfony/http-foundation/CHANGELOG.md +++ b/vendor/symfony/http-foundation/CHANGELOG.md @@ -1,6 +1,16 @@ CHANGELOG ========= +3.1.0 +----- + + * Added support for creating `JsonResponse` with a string of JSON data + +3.0.0 +----- + + * The precedence of parameters returned from `Request::get()` changed from "GET, PATH, BODY" to "PATH, GET, BODY" + 2.8.0 ----- diff --git a/vendor/symfony/http-foundation/Cookie.php b/vendor/symfony/http-foundation/Cookie.php index 91783a6a..be13dab8 100644 --- a/vendor/symfony/http-foundation/Cookie.php +++ b/vendor/symfony/http-foundation/Cookie.php @@ -25,21 +25,28 @@ class Cookie protected $path; protected $secure; protected $httpOnly; + private $raw; + private $sameSite; + + const SAMESITE_LAX = 'lax'; + const SAMESITE_STRICT = 'strict'; /** * Constructor. * - * @param string $name The name of the cookie - * @param string $value The value of the cookie - * @param int|string|\DateTime|\DateTimeInterface $expire The time the cookie expires - * @param string $path The path on the server in which the cookie will be available on - * @param string $domain The domain that the cookie is available to - * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client - * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol + * @param string $name The name of the cookie + * @param string $value The value of the cookie + * @param int|string|\DateTimeInterface $expire The time the cookie expires + * @param string $path The path on the server in which the cookie will be available on + * @param string $domain The domain that the cookie is available to + * @param bool $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client + * @param bool $httpOnly Whether the cookie will be made accessible only through the HTTP protocol + * @param bool $raw Whether the cookie value should be sent with no url encoding + * @param string|null $sameSite Whether the cookie will be available for cross-site requests * * @throws \InvalidArgumentException */ - public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true) + public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null) { // from PHP source code if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { @@ -51,7 +58,7 @@ public function __construct($name, $value = null, $expire = 0, $path = '/', $dom } // convert expiration time to a Unix timestamp - if ($expire instanceof \DateTime || $expire instanceof \DateTimeInterface) { + if ($expire instanceof \DateTimeInterface) { $expire = $expire->format('U'); } elseif (!is_numeric($expire)) { $expire = strtotime($expire); @@ -68,6 +75,13 @@ public function __construct($name, $value = null, $expire = 0, $path = '/', $dom $this->path = empty($path) ? '/' : $path; $this->secure = (bool) $secure; $this->httpOnly = (bool) $httpOnly; + $this->raw = (bool) $raw; + + if (!in_array($sameSite, array(self::SAMESITE_LAX, self::SAMESITE_STRICT, null), true)) { + throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.'); + } + + $this->sameSite = $sameSite; } /** @@ -77,20 +91,20 @@ public function __construct($name, $value = null, $expire = 0, $path = '/', $dom */ public function __toString() { - $str = urlencode($this->getName()).'='; + $str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'='; if ('' === (string) $this->getValue()) { $str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001); } else { - $str .= urlencode($this->getValue()); + $str .= $this->isRaw() ? $this->getValue() : urlencode($this->getValue()); if (0 !== $this->getExpiresTime()) { $str .= '; expires='.gmdate('D, d-M-Y H:i:s T', $this->getExpiresTime()); } } - if ($this->path) { - $str .= '; path='.$this->path; + if ($this->getPath()) { + $str .= '; path='.$this->getPath(); } if ($this->getDomain()) { @@ -105,6 +119,10 @@ public function __toString() $str .= '; httponly'; } + if (null !== $this->getSameSite()) { + $str .= '; samesite='.$this->getSameSite(); + } + return $str; } @@ -121,7 +139,7 @@ public function getName() /** * Gets the value of the cookie. * - * @return string + * @return string|null */ public function getValue() { @@ -131,7 +149,7 @@ public function getValue() /** * Gets the domain that the cookie is available to. * - * @return string + * @return string|null */ public function getDomain() { @@ -187,4 +205,24 @@ public function isCleared() { return $this->expire < time(); } + + /** + * Checks if the cookie value should be sent with no url encoding. + * + * @return bool + */ + public function isRaw() + { + return $this->raw; + } + + /** + * Gets the SameSite attribute. + * + * @return string|null + */ + public function getSameSite() + { + return $this->sameSite; + } } diff --git a/vendor/symfony/http-foundation/FileBag.php b/vendor/symfony/http-foundation/FileBag.php index 197eab42..e17a9057 100644 --- a/vendor/symfony/http-foundation/FileBag.php +++ b/vendor/symfony/http-foundation/FileBag.php @@ -69,7 +69,7 @@ public function add(array $files = array()) * * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information * - * @return array A (multi-dimensional) array of UploadedFile instances + * @return UploadedFile|UploadedFile[] A (multi-dimensional) array of UploadedFile instances */ protected function convertFileInformation($file) { diff --git a/vendor/symfony/http-foundation/JsonResponse.php b/vendor/symfony/http-foundation/JsonResponse.php index 2412b5e2..cf1a11ea 100644 --- a/vendor/symfony/http-foundation/JsonResponse.php +++ b/vendor/symfony/http-foundation/JsonResponse.php @@ -29,16 +29,17 @@ class JsonResponse extends Response // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML. // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT - protected $encodingOptions = 15; + const DEFAULT_ENCODING_OPTIONS = 15; + + protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS; /** - * Constructor. - * * @param mixed $data The response data * @param int $status The response status code * @param array $headers An array of response headers + * @param bool $json If the data is already a JSON string */ - public function __construct($data = null, $status = 200, $headers = array()) + public function __construct($data = null, $status = 200, $headers = array(), $json = false) { parent::__construct('', $status, $headers); @@ -46,7 +47,7 @@ public function __construct($data = null, $status = 200, $headers = array()) $data = new \ArrayObject(); } - $this->setData($data); + $json ? $this->setJson($data) : $this->setData($data); } /** @@ -68,6 +69,14 @@ public static function create($data = null, $status = 200, $headers = array()) return new static($data, $status, $headers); } + /** + * Make easier the creation of JsonResponse from raw json. + */ + public static function fromJsonString($data = null, $status = 200, $headers = array()) + { + return new static($data, $status, $headers, true); + } + /** * Sets the JSONP callback. * @@ -80,8 +89,8 @@ public static function create($data = null, $status = 200, $headers = array()) public function setCallback($callback = null) { if (null !== $callback) { - // partially token from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ - // partially token from https://github.com/willdurand/JsonpCallbackValidator + // partially taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/ + // partially taken from https://github.com/willdurand/JsonpCallbackValidator // JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details. // (c) William Durand $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u'; @@ -103,6 +112,22 @@ public function setCallback($callback = null) return $this->update(); } + /** + * Sets a raw string containing a JSON document to be sent. + * + * @param string $json + * + * @return $this + * + * @throws \InvalidArgumentException + */ + public function setJson($json) + { + $this->data = $json; + + return $this->update(); + } + /** * Sets the data to be sent as JSON. * @@ -121,39 +146,12 @@ public function setData($data = array()) $data = json_encode($data, $this->encodingOptions); } else { try { - if (PHP_VERSION_ID < 50400) { - // PHP 5.3 triggers annoying warnings for some - // types that can't be serialized as JSON (INF, resources, etc.) - // but doesn't provide the JsonSerializable interface. - set_error_handler(function () { return false; }); - $data = @json_encode($data, $this->encodingOptions); - } else { - // PHP 5.4 and up wrap exceptions thrown by JsonSerializable - // objects in a new exception that needs to be removed. - // Fortunately, PHP 5.5 and up do not trigger any warning anymore. - if (PHP_VERSION_ID < 50500) { - // Clear json_last_error() - json_encode(null); - $errorHandler = set_error_handler('var_dump'); - restore_error_handler(); - set_error_handler(function () use ($errorHandler) { - if (JSON_ERROR_NONE === json_last_error()) { - return $errorHandler && false !== call_user_func_array($errorHandler, func_get_args()); - } - }); - } - - $data = json_encode($data, $this->encodingOptions); - } - - if (PHP_VERSION_ID < 50500) { - restore_error_handler(); - } + // PHP 5.4 and up wrap exceptions thrown by JsonSerializable + // objects in a new exception that needs to be removed. + // Fortunately, PHP 5.5 and up do not trigger any warning anymore. + $data = json_encode($data, $this->encodingOptions); } catch (\Exception $e) { - if (PHP_VERSION_ID < 50500) { - restore_error_handler(); - } - if (PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { + if ('Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) { throw $e->getPrevious() ?: $e; } throw $e; @@ -164,9 +162,7 @@ public function setData($data = array()) throw new \InvalidArgumentException(json_last_error_msg()); } - $this->data = $data; - - return $this->update(); + return $this->setJson($data); } /** diff --git a/vendor/symfony/http-foundation/ParameterBag.php b/vendor/symfony/http-foundation/ParameterBag.php index ef13494e..c0b36479 100644 --- a/vendor/symfony/http-foundation/ParameterBag.php +++ b/vendor/symfony/http-foundation/ParameterBag.php @@ -78,67 +78,14 @@ public function add(array $parameters = array()) /** * Returns a parameter by name. * - * Note: Finding deep items is deprecated since version 2.8, to be removed in 3.0. - * * @param string $key The key * @param mixed $default The default value if the parameter key does not exist - * @param bool $deep If true, a path like foo[bar] will find deeper items * * @return mixed - * - * @throws \InvalidArgumentException */ - public function get($key, $default = null, $deep = false) + public function get($key, $default = null) { - if ($deep) { - @trigger_error('Using paths to find deeper items in '.__METHOD__.' is deprecated since version 2.8 and will be removed in 3.0. Filter the returned value in your own code instead.', E_USER_DEPRECATED); - } - - if (!$deep || false === $pos = strpos($key, '[')) { - return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default; - } - - $root = substr($key, 0, $pos); - if (!array_key_exists($root, $this->parameters)) { - return $default; - } - - $value = $this->parameters[$root]; - $currentKey = null; - for ($i = $pos, $c = strlen($key); $i < $c; ++$i) { - $char = $key[$i]; - - if ('[' === $char) { - if (null !== $currentKey) { - throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i)); - } - - $currentKey = ''; - } elseif (']' === $char) { - if (null === $currentKey) { - throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i)); - } - - if (!is_array($value) || !array_key_exists($currentKey, $value)) { - return $default; - } - - $value = $value[$currentKey]; - $currentKey = null; - } else { - if (null === $currentKey) { - throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i)); - } - - $currentKey .= $char; - } - } - - if (null !== $currentKey) { - throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".')); - } - - return $value; + return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default; } /** @@ -179,13 +126,12 @@ public function remove($key) * * @param string $key The parameter key * @param string $default The default value if the parameter key does not exist - * @param bool $deep If true, a path like foo[bar] will find deeper items * * @return string The filtered value */ - public function getAlpha($key, $default = '', $deep = false) + public function getAlpha($key, $default = '') { - return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep)); + return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default)); } /** @@ -193,13 +139,12 @@ public function getAlpha($key, $default = '', $deep = false) * * @param string $key The parameter key * @param string $default The default value if the parameter key does not exist - * @param bool $deep If true, a path like foo[bar] will find deeper items * * @return string The filtered value */ - public function getAlnum($key, $default = '', $deep = false) + public function getAlnum($key, $default = '') { - return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep)); + return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default)); } /** @@ -207,14 +152,13 @@ public function getAlnum($key, $default = '', $deep = false) * * @param string $key The parameter key * @param string $default The default value if the parameter key does not exist - * @param bool $deep If true, a path like foo[bar] will find deeper items * * @return string The filtered value */ - public function getDigits($key, $default = '', $deep = false) + public function getDigits($key, $default = '') { // we need to remove - and + because they're allowed in the filter - return str_replace(array('-', '+'), '', $this->filter($key, $default, FILTER_SANITIZE_NUMBER_INT, array(), $deep)); + return str_replace(array('-', '+'), '', $this->filter($key, $default, FILTER_SANITIZE_NUMBER_INT)); } /** @@ -222,13 +166,12 @@ public function getDigits($key, $default = '', $deep = false) * * @param string $key The parameter key * @param int $default The default value if the parameter key does not exist - * @param bool $deep If true, a path like foo[bar] will find deeper items * * @return int The filtered value */ - public function getInt($key, $default = 0, $deep = false) + public function getInt($key, $default = 0) { - return (int) $this->get($key, $default, $deep); + return (int) $this->get($key, $default); } /** @@ -236,13 +179,12 @@ public function getInt($key, $default = 0, $deep = false) * * @param string $key The parameter key * @param mixed $default The default value if the parameter key does not exist - * @param bool $deep If true, a path like foo[bar] will find deeper items * * @return bool The filtered value */ - public function getBoolean($key, $default = false, $deep = false) + public function getBoolean($key, $default = false) { - return $this->filter($key, $default, FILTER_VALIDATE_BOOLEAN, array(), $deep); + return $this->filter($key, $default, FILTER_VALIDATE_BOOLEAN); } /** @@ -252,30 +194,14 @@ public function getBoolean($key, $default = false, $deep = false) * @param mixed $default Default = null * @param int $filter FILTER_* constant * @param mixed $options Filter options - * @param bool $deep Default = false * * @see http://php.net/manual/en/function.filter-var.php * * @return mixed */ - public function filter($key, $default = null, $filter = FILTER_DEFAULT, $options = array(), $deep = false) + public function filter($key, $default = null, $filter = FILTER_DEFAULT, $options = array()) { - static $filters = null; - - if (null === $filters) { - foreach (filter_list() as $tmp) { - $filters[filter_id($tmp)] = 1; - } - } - if (is_bool($filter) || !isset($filters[$filter]) || is_array($deep)) { - @trigger_error('Passing the $deep boolean as 3rd argument to the '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Remove it altogether as the $deep argument will be removed in 3.0.', E_USER_DEPRECATED); - $tmp = $deep; - $deep = $filter; - $filter = $options; - $options = $tmp; - } - - $value = $this->get($key, $default, $deep); + $value = $this->get($key, $default); // Always turn $options into an array - this allows filter_var option shortcuts. if (!is_array($options) && $options) { diff --git a/vendor/symfony/http-foundation/RedirectResponse.php b/vendor/symfony/http-foundation/RedirectResponse.php index 5a775ad1..7435999a 100644 --- a/vendor/symfony/http-foundation/RedirectResponse.php +++ b/vendor/symfony/http-foundation/RedirectResponse.php @@ -41,6 +41,10 @@ public function __construct($url, $status = 302, $headers = array()) if (!$this->isRedirect()) { throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status)); } + + if (301 == $status && !array_key_exists('cache-control', $headers)) { + $this->headers->remove('cache-control'); + } } /** diff --git a/vendor/symfony/http-foundation/Request.php b/vendor/symfony/http-foundation/Request.php index 46cc6bea..2768b21a 100644 --- a/vendor/symfony/http-foundation/Request.php +++ b/vendor/symfony/http-foundation/Request.php @@ -206,6 +206,15 @@ class Request protected static $requestFactory; + private $isForwardedValid = true; + + private static $forwardedParams = array( + self::HEADER_CLIENT_IP => 'for', + self::HEADER_CLIENT_HOST => 'host', + self::HEADER_CLIENT_PROTO => 'proto', + self::HEADER_CLIENT_PORT => 'host', + ); + /** * Constructor. * @@ -312,7 +321,7 @@ public static function create($uri, $method = 'GET', $parameters = array(), $coo 'SERVER_NAME' => 'localhost', 'SERVER_PORT' => 80, 'HTTP_HOST' => 'localhost', - 'HTTP_USER_AGENT' => 'Symfony/2.X', + 'HTTP_USER_AGENT' => 'Symfony/3.X', 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5', 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', @@ -596,6 +605,7 @@ public static function getTrustedHosts() * * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getHost()) * * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getPort()) * * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure()) + * * Request::HEADER_FORWARDED: defaults to Forwarded (see RFC 7239) * * Setting an empty value allows to disable the trusted header for the given key. * @@ -701,43 +711,30 @@ public static function getHttpMethodParameterOverride() } /** - * Gets a "parameter" value. - * - * This method is mainly useful for libraries that want to provide some flexibility. - * - * Order of precedence: GET, PATH, POST + * Gets a "parameter" value from any bag. * - * Avoid using this method in controllers: + * This method is mainly useful for libraries that want to provide some flexibility. If you don't need the + * flexibility in controllers, it is better to explicitly get request parameters from the appropriate + * public property instead (attributes, query, request). * - * * slow - * * prefer to get from a "named" source - * - * It is better to explicitly get request parameters from the appropriate - * public property instead (query, attributes, request). - * - * Note: Finding deep items is deprecated since version 2.8, to be removed in 3.0. + * Order of precedence: PATH (routing placeholders or custom attributes), GET, BODY * * @param string $key the key * @param mixed $default the default value if the parameter key does not exist - * @param bool $deep is parameter deep in multidimensional array * * @return mixed */ - public function get($key, $default = null, $deep = false) + public function get($key, $default = null) { - if ($deep) { - @trigger_error('Using paths to find deeper items in '.__METHOD__.' is deprecated since version 2.8 and will be removed in 3.0. Filter the returned value in your own code instead.', E_USER_DEPRECATED); - } - - if ($this !== $result = $this->query->get($key, $this, $deep)) { + if ($this !== $result = $this->attributes->get($key, $this)) { return $result; } - if ($this !== $result = $this->attributes->get($key, $this, $deep)) { + if ($this !== $result = $this->query->get($key, $this)) { return $result; } - if ($this !== $result = $this->request->get($key, $this, $deep)) { + if ($this !== $result = $this->request->get($key, $this)) { return $result; } @@ -805,41 +802,13 @@ public function setSession(SessionInterface $session) */ public function getClientIps() { - $clientIps = array(); $ip = $this->server->get('REMOTE_ADDR'); if (!$this->isFromTrustedProxy()) { return array($ip); } - $hasTrustedForwardedHeader = self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED]); - $hasTrustedClientIpHeader = self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP]); - - if ($hasTrustedForwardedHeader) { - $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); - preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches); - $forwardedClientIps = $matches[3]; - - $forwardedClientIps = $this->normalizeAndFilterClientIps($forwardedClientIps, $ip); - $clientIps = $forwardedClientIps; - } - - if ($hasTrustedClientIpHeader) { - $xForwardedForClientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); - - $xForwardedForClientIps = $this->normalizeAndFilterClientIps($xForwardedForClientIps, $ip); - $clientIps = $xForwardedForClientIps; - } - - if ($hasTrustedForwardedHeader && $hasTrustedClientIpHeader && $forwardedClientIps !== $xForwardedForClientIps) { - throw new ConflictingHeadersException('The request has both a trusted Forwarded header and a trusted Client IP header, conflicting with each other with regards to the originating IP addresses of the request. This is the result of a misconfiguration. You should either configure your proxy only to send one of these headers, or configure Symfony to distrust one of them.'); - } - - if (!$hasTrustedForwardedHeader && !$hasTrustedClientIpHeader) { - return $this->normalizeAndFilterClientIps(array(), $ip); - } - - return $clientIps; + return $this->getTrustedValues(self::HEADER_CLIENT_IP, $ip) ?: array($ip); } /** @@ -855,7 +824,7 @@ public function getClientIps() * ("Client-Ip" for instance), configure it via "setTrustedHeaderName()" with * the "client-ip" key. * - * @return string The client IP address + * @return string|null The client IP address * * @see getClientIps() * @see http://en.wikipedia.org/wiki/X-Forwarded-For @@ -961,35 +930,29 @@ public function getScheme() * If your reverse proxy uses a different header name than "X-Forwarded-Port", * configure it via "setTrustedHeaderName()" with the "client-port" key. * - * @return string + * @return int|string can be a string if fetched from the server bag */ public function getPort() { - if ($this->isFromTrustedProxy()) { - if (self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) { - return $port; - } - - if (self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && 'https' === $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO], 'http')) { - return 443; - } + if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_PORT)) { + $host = $host[0]; + } elseif ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_HOST)) { + $host = $host[0]; + } elseif (!$host = $this->headers->get('HOST')) { + return $this->server->get('SERVER_PORT'); } - if ($host = $this->headers->get('HOST')) { - if ($host[0] === '[') { - $pos = strpos($host, ':', strrpos($host, ']')); - } else { - $pos = strrpos($host, ':'); - } - - if (false !== $pos) { - return (int) substr($host, $pos + 1); - } + if ($host[0] === '[') { + $pos = strpos($host, ':', strrpos($host, ']')); + } else { + $pos = strrpos($host, ':'); + } - return 'https' === $this->getScheme() ? 443 : 80; + if (false !== $pos) { + return (int) substr($host, $pos + 1); } - return $this->server->get('SERVER_PORT'); + return 'https' === $this->getScheme() ? 443 : 80; } /** @@ -1189,8 +1152,8 @@ public function getQueryString() */ public function isSecure() { - if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) { - return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1')); + if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_CLIENT_PROTO)) { + return in_array(strtolower($proto[0]), array('https', 'on', 'ssl', '1'), true); } $https = $this->server->get('HTTPS'); @@ -1215,10 +1178,8 @@ public function isSecure() */ public function getHost() { - if ($this->isFromTrustedProxy() && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { - $elements = explode(',', $host); - - $host = $elements[count($elements) - 1]; + if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_HOST)) { + $host = $host[0]; } elseif (!$host = $this->headers->get('HOST')) { if (!$host = $this->server->get('SERVER_NAME')) { $host = $this->server->get('SERVER_ADDR', ''); @@ -1328,6 +1289,22 @@ public function getMimeType($format) return isset(static::$formats[$format]) ? static::$formats[$format][0] : null; } + /** + * Gets the mime types associated with the format. + * + * @param string $format The format + * + * @return array The associated mime types + */ + public static function getMimeTypes($format) + { + if (null === static::$formats) { + static::initializeFormats(); + } + + return isset(static::$formats[$format]) ? static::$formats[$format] : array(); + } + /** * Gets the format associated with the mime type. * @@ -1377,7 +1354,7 @@ public function setFormat($format, $mimeTypes) * Here is the process to determine the format: * * * format defined by the user (with setRequestFormat()) - * * _format request parameter + * * _format request attribute * * $default * * @param string $default The default format @@ -1387,10 +1364,10 @@ public function setFormat($format, $mimeTypes) public function getRequestFormat($default = 'html') { if (null === $this->format) { - $this->format = $this->get('_format', $default); + $this->format = $this->attributes->get('_format'); } - return $this->format; + return null === $this->format ? $default : $this->format; } /** @@ -1470,7 +1447,7 @@ public function isMethod($method) } /** - * Checks whether the method is safe or not. + * Checks whether or not the method is safe. * * @see https://tools.ietf.org/html/rfc7231#section-4.2.1 * @@ -1480,7 +1457,25 @@ public function isMethod($method) */ public function isMethodSafe(/* $andCacheable = true */) { - return in_array($this->getMethod(), 0 < func_num_args() && !func_get_arg(0) ? array('GET', 'HEAD', 'OPTIONS', 'TRACE') : array('GET', 'HEAD')); + if (!func_num_args() || func_get_arg(0)) { + // This deprecation should be turned into a BadMethodCallException in 4.0 (without adding the argument in the signature) + // then setting $andCacheable to false should be deprecated in 4.1 + @trigger_error('Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since version 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.', E_USER_DEPRECATED); + + return in_array($this->getMethod(), array('GET', 'HEAD')); + } + + return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE')); + } + + /** + * Checks whether or not the method is idempotent. + * + * @return bool + */ + public function isMethodIdempotent() + { + return in_array($this->getMethod(), array('HEAD', 'GET', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'PURGE')); } /** @@ -1779,6 +1774,9 @@ protected function prepareBaseUrl() // Does the baseUrl have anything in common with the request_uri? $requestUri = $this->getRequestUri(); + if ($requestUri !== '' && $requestUri[0] !== '/') { + $requestUri = '/'.$requestUri; + } if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) { // full $baseUrl matches @@ -1851,9 +1849,12 @@ protected function preparePathInfo() } // Remove the query string from REQUEST_URI - if ($pos = strpos($requestUri, '?')) { + if (false !== $pos = strpos($requestUri, '?')) { $requestUri = substr($requestUri, 0, $pos); } + if ($requestUri !== '' && $requestUri[0] !== '/') { + $requestUri = '/'.$requestUri; + } $pathInfo = substr($requestUri, strlen($baseUrl)); if (null !== $baseUrl && (false === $pathInfo || '' === $pathInfo)) { @@ -1942,13 +1943,61 @@ private static function createRequestFromFactory(array $query = array(), array $ return new static($query, $request, $attributes, $cookies, $files, $server, $content); } - private function isFromTrustedProxy() + /** + * Indicates whether this request originated from a trusted proxy. + * + * This can be useful to determine whether or not to trust the + * contents of a proxy-specific header. + * + * @return bool true if the request came from a trusted proxy, false otherwise + */ + public function isFromTrustedProxy() { return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR'), self::$trustedProxies); } + private function getTrustedValues($type, $ip = null) + { + $clientValues = array(); + $forwardedValues = array(); + + if (self::$trustedHeaders[$type] && $this->headers->has(self::$trustedHeaders[$type])) { + foreach (explode(',', $this->headers->get(self::$trustedHeaders[$type])) as $v) { + $clientValues[] = (self::HEADER_CLIENT_PORT === $type ? '0.0.0.0:' : '').trim($v); + } + } + + if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { + $forwardedValues = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); + $forwardedValues = preg_match_all(sprintf('{(?:%s)=(?:"?\[?)([a-zA-Z0-9\.:_\-/]*+)}', self::$forwardedParams[$type]), $forwardedValues, $matches) ? $matches[1] : array(); + } + + if (null !== $ip) { + $clientValues = $this->normalizeAndFilterClientIps($clientValues, $ip); + $forwardedValues = $this->normalizeAndFilterClientIps($forwardedValues, $ip); + } + + if ($forwardedValues === $clientValues || !$clientValues) { + return $forwardedValues; + } + + if (!$forwardedValues) { + return $clientValues; + } + + if (!$this->isForwardedValid) { + return null !== $ip ? array('0.0.0.0', $ip) : array(); + } + $this->isForwardedValid = false; + + throw new ConflictingHeadersException(sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::$trustedHeaders[self::HEADER_FORWARDED], self::$trustedHeaders[$type])); + } + private function normalizeAndFilterClientIps(array $clientIps, $ip) { + if (!$clientIps) { + return array(); + } $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from $firstTrustedIp = null; diff --git a/vendor/symfony/http-foundation/Response.php b/vendor/symfony/http-foundation/Response.php index 9d112d15..acc4bb6e 100644 --- a/vendor/symfony/http-foundation/Response.php +++ b/vendor/symfony/http-foundation/Response.php @@ -179,13 +179,37 @@ class Response 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates (Experimental)', // RFC2295 + 506 => 'Variant Also Negotiates', // RFC2295 507 => 'Insufficient Storage', // RFC4918 508 => 'Loop Detected', // RFC5842 510 => 'Not Extended', // RFC2774 511 => 'Network Authentication Required', // RFC6585 ); + private static $deprecatedMethods = array( + 'setDate', 'getDate', + 'setExpires', 'getExpires', + 'setLastModified', 'getLastModified', + 'setProtocolVersion', 'getProtocolVersion', + 'setStatusCode', 'getStatusCode', + 'setCharset', 'getCharset', + 'setPrivate', 'setPublic', + 'getAge', 'getMaxAge', 'setMaxAge', 'setSharedMaxAge', + 'getTtl', 'setTtl', 'setClientTtl', + 'getEtag', 'setEtag', + 'hasVary', 'getVary', 'setVary', + 'isInvalid', 'isSuccessful', 'isRedirection', + 'isClientError', 'isOk', 'isForbidden', + 'isNotFound', 'isRedirect', 'isEmpty', + ); + private static $deprecationsTriggered = array( + __CLASS__ => true, + BinaryFileResponse::class => true, + JsonResponse::class => true, + RedirectResponse::class => true, + StreamedResponse::class => true, + ); + /** * Constructor. * @@ -201,6 +225,28 @@ public function __construct($content = '', $status = 200, $headers = array()) $this->setContent($content); $this->setStatusCode($status); $this->setProtocolVersion('1.0'); + + /* RFC2616 - 14.18 says all Responses need to have a Date */ + if (!$this->headers->has('Date')) { + $this->setDate(\DateTime::createFromFormat('U', time())); + } + + // Deprecations + $class = get_class($this); + if ($this instanceof \PHPUnit_Framework_MockObject_MockObject || $this instanceof \Prophecy\Doubler\DoubleInterface) { + $class = get_parent_class($class); + } + if (isset(self::$deprecationsTriggered[$class])) { + return; + } + + self::$deprecationsTriggered[$class] = true; + foreach (self::$deprecatedMethods as $method) { + $r = new \ReflectionMethod($class, $method); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Extending %s::%s() in %s is deprecated since version 3.2 and won\'t be supported anymore in 4.0 as it will be final.', __CLASS__, $method, $class), E_USER_DEPRECATED); + } + } } /** @@ -307,7 +353,7 @@ public function prepare(Request $request) } // Check if we need to send extra expire info headers - if ('1.0' == $this->getProtocolVersion() && 'no-cache' == $this->headers->get('Cache-Control')) { + if ('1.0' == $this->getProtocolVersion() && false !== strpos($this->headers->get('Cache-Control'), 'no-cache')) { $this->headers->set('pragma', 'no-cache'); $this->headers->set('expires', -1); } @@ -329,6 +375,7 @@ public function sendHeaders() return $this; } + /* RFC2616 - 14.18 says all Responses need to have a Date */ if (!$this->headers->has('Date')) { $this->setDate(\DateTime::createFromFormat('U', time())); } @@ -345,7 +392,11 @@ public function sendHeaders() // cookies foreach ($this->headers->getCookies() as $cookie) { - setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + if ($cookie->isRaw()) { + setrawcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + } else { + setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly()); + } } return $this; @@ -612,6 +663,11 @@ public function mustRevalidate() */ public function getDate() { + /* + RFC2616 - 14.18 says all Responses need to have a Date. + Make sure we provide one even if it the header + has been removed in the meantime. + */ if (!$this->headers->has('Date')) { $this->setDate(\DateTime::createFromFormat('U', time())); } @@ -1153,6 +1209,7 @@ public static function closeOutputBuffers($targetLevel, $flush) { $status = ob_get_status(true); $level = count($status); + // PHP_OUTPUT_HANDLER_* are not defined on HHVM 3.3 $flags = defined('PHP_OUTPUT_HANDLER_REMOVABLE') ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1; while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) { diff --git a/vendor/symfony/http-foundation/ResponseHeaderBag.php b/vendor/symfony/http-foundation/ResponseHeaderBag.php index 3223691e..2b630d8a 100644 --- a/vendor/symfony/http-foundation/ResponseHeaderBag.php +++ b/vendor/symfony/http-foundation/ResponseHeaderBag.php @@ -281,7 +281,7 @@ public function makeDisposition($disposition, $filename, $filenameFallback = '') protected function computeCacheControlValue() { if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) { - return 'no-cache'; + return 'no-cache, private'; } if (!$this->cacheControl) { diff --git a/vendor/symfony/http-foundation/Session/Flash/FlashBag.php b/vendor/symfony/http-foundation/Session/Flash/FlashBag.php index 1516de7f..85b4f00b 100644 --- a/vendor/symfony/http-foundation/Session/Flash/FlashBag.php +++ b/vendor/symfony/http-foundation/Session/Flash/FlashBag.php @@ -14,11 +14,9 @@ /** * FlashBag flash message container. * - * \IteratorAggregate implementation is deprecated and will be removed in 3.0. - * * @author Drak */ -class FlashBag implements FlashBagInterface, \IteratorAggregate +class FlashBag implements FlashBagInterface { private $name = 'flashes'; @@ -165,18 +163,4 @@ public function clear() { return $this->all(); } - - /** - * Returns an iterator for flashes. - * - * @deprecated since version 2.4, to be removed in 3.0. - * - * @return \ArrayIterator An \ArrayIterator instance - */ - public function getIterator() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); - - return new \ArrayIterator($this->all()); - } } diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php deleted file mode 100644 index 111541d9..00000000 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/LegacyPdoSessionHandler.php +++ /dev/null @@ -1,271 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; - -@trigger_error('The '.__NAMESPACE__.'\LegacyPdoSessionHandler class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler class instead.', E_USER_DEPRECATED); - -/** - * Session handler using a PDO connection to read and write data. - * - * Session data is a binary string that can contain non-printable characters like the null byte. - * For this reason this handler base64 encodes the data to be able to save it in a character column. - * - * This version of the PdoSessionHandler does NOT implement locking. So concurrent requests to the - * same session can result in data loss due to race conditions. - * - * @author Fabien Potencier - * @author Michael Williams - * @author Tobias Schultze - * - * @deprecated since version 2.6, to be removed in 3.0. Use - * {@link PdoSessionHandler} instead. - */ -class LegacyPdoSessionHandler implements \SessionHandlerInterface -{ - /** - * @var \PDO PDO instance - */ - private $pdo; - - /** - * @var string Table name - */ - private $table; - - /** - * @var string Column for session id - */ - private $idCol; - - /** - * @var string Column for session data - */ - private $dataCol; - - /** - * @var string Column for timestamp - */ - private $timeCol; - - /** - * Constructor. - * - * List of available options: - * * db_table: The name of the table [required] - * * db_id_col: The column where to store the session id [default: sess_id] - * * db_data_col: The column where to store the session data [default: sess_data] - * * db_time_col: The column where to store the timestamp [default: sess_time] - * - * @param \PDO $pdo A \PDO instance - * @param array $dbOptions An associative array of DB options - * - * @throws \InvalidArgumentException When "db_table" option is not provided - */ - public function __construct(\PDO $pdo, array $dbOptions = array()) - { - if (!array_key_exists('db_table', $dbOptions)) { - throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.'); - } - if (\PDO::ERRMODE_EXCEPTION !== $pdo->getAttribute(\PDO::ATTR_ERRMODE)) { - throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__)); - } - - $this->pdo = $pdo; - $dbOptions = array_merge(array( - 'db_id_col' => 'sess_id', - 'db_data_col' => 'sess_data', - 'db_time_col' => 'sess_time', - ), $dbOptions); - - $this->table = $dbOptions['db_table']; - $this->idCol = $dbOptions['db_id_col']; - $this->dataCol = $dbOptions['db_data_col']; - $this->timeCol = $dbOptions['db_time_col']; - } - - /** - * {@inheritdoc} - */ - public function open($savePath, $sessionName) - { - return true; - } - - /** - * {@inheritdoc} - */ - public function close() - { - return true; - } - - /** - * {@inheritdoc} - */ - public function destroy($sessionId) - { - // delete the record associated with this id - $sql = "DELETE FROM $this->table WHERE $this->idCol = :id"; - - try { - $stmt = $this->pdo->prepare($sql); - $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); - $stmt->execute(); - } catch (\PDOException $e) { - throw new \RuntimeException(sprintf('PDOException was thrown when trying to delete a session: %s', $e->getMessage()), 0, $e); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function gc($maxlifetime) - { - // delete the session records that have expired - $sql = "DELETE FROM $this->table WHERE $this->timeCol < :time"; - - try { - $stmt = $this->pdo->prepare($sql); - $stmt->bindValue(':time', time() - $maxlifetime, \PDO::PARAM_INT); - $stmt->execute(); - } catch (\PDOException $e) { - throw new \RuntimeException(sprintf('PDOException was thrown when trying to delete expired sessions: %s', $e->getMessage()), 0, $e); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function read($sessionId) - { - $sql = "SELECT $this->dataCol FROM $this->table WHERE $this->idCol = :id"; - - try { - $stmt = $this->pdo->prepare($sql); - $stmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); - $stmt->execute(); - - // We use fetchAll instead of fetchColumn to make sure the DB cursor gets closed - $sessionRows = $stmt->fetchAll(\PDO::FETCH_NUM); - - if ($sessionRows) { - return base64_decode($sessionRows[0][0]); - } - - return ''; - } catch (\PDOException $e) { - throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e); - } - } - - /** - * {@inheritdoc} - */ - public function write($sessionId, $data) - { - $encoded = base64_encode($data); - - try { - // We use a single MERGE SQL query when supported by the database. - $mergeSql = $this->getMergeSql(); - - if (null !== $mergeSql) { - $mergeStmt = $this->pdo->prepare($mergeSql); - $mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); - $mergeStmt->bindParam(':data', $encoded, \PDO::PARAM_STR); - $mergeStmt->bindValue(':time', time(), \PDO::PARAM_INT); - $mergeStmt->execute(); - - return true; - } - - $updateStmt = $this->pdo->prepare( - "UPDATE $this->table SET $this->dataCol = :data, $this->timeCol = :time WHERE $this->idCol = :id" - ); - $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); - $updateStmt->bindParam(':data', $encoded, \PDO::PARAM_STR); - $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT); - $updateStmt->execute(); - - // When MERGE is not supported, like in Postgres, we have to use this approach that can result in - // duplicate key errors when the same session is written simultaneously. We can just catch such an - // error and re-execute the update. This is similar to a serializable transaction with retry logic - // on serialization failures but without the overhead and without possible false positives due to - // longer gap locking. - if (!$updateStmt->rowCount()) { - try { - $insertStmt = $this->pdo->prepare( - "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)" - ); - $insertStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); - $insertStmt->bindParam(':data', $encoded, \PDO::PARAM_STR); - $insertStmt->bindValue(':time', time(), \PDO::PARAM_INT); - $insertStmt->execute(); - } catch (\PDOException $e) { - // Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys - if (0 === strpos($e->getCode(), '23')) { - $updateStmt->execute(); - } else { - throw $e; - } - } - } - } catch (\PDOException $e) { - throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e); - } - - return true; - } - - /** - * Returns a merge/upsert (i.e. insert or update) SQL query when supported by the database. - * - * @return string|null The SQL string or null when not supported - */ - private function getMergeSql() - { - $driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); - - switch ($driver) { - case 'mysql': - return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ". - "ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->timeCol = VALUES($this->timeCol)"; - case 'oci': - // DUAL is Oracle specific dummy table - return "MERGE INTO $this->table USING DUAL ON ($this->idCol = :id) ". - "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ". - "WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time"; - case 'sqlsrv' === $driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>='): - // MERGE is only available since SQL Server 2008 and must be terminated by semicolon - // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx - return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = :id) ". - "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ". - "WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time;"; - case 'sqlite': - return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)"; - } - } - - /** - * Return a PDO instance. - * - * @return \PDO - */ - protected function getConnection() - { - return $this->pdo; - } -} diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php index 95d5cdbf..4ae410f9 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php @@ -11,14 +11,11 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; -// Adds SessionHandler functionality if available. -// @see http://php.net/sessionhandler -if (PHP_VERSION_ID >= 50400) { - class NativeSessionHandler extends \SessionHandler - { - } -} else { - class NativeSessionHandler - { - } +/** + * Adds SessionHandler functionality if available. + * + * @see http://php.net/sessionhandler + */ +class NativeSessionHandler extends \SessionHandler +{ } diff --git a/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php index c26cc133..348fd230 100644 --- a/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php @@ -58,9 +58,9 @@ class MockArraySessionStorage implements SessionStorageInterface protected $metadataBag; /** - * @var array + * @var array|SessionBagInterface[] */ - protected $bags; + protected $bags = array(); /** * Constructor. diff --git a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php index 274b0df6..fd46b1d1 100644 --- a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @@ -13,7 +13,6 @@ use Symfony\Component\HttpFoundation\Session\SessionBagInterface; use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; -use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; @@ -81,6 +80,7 @@ class NativeSessionStorage implements SessionStorageInterface * name, "PHPSESSID" * referer_check, "" * serialize_handler, "php" + * use_strict_mode, "0" * use_cookies, "1" * use_only_cookies, "1" * use_trans_sid, "0" @@ -127,15 +127,10 @@ public function start() return true; } - if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE === session_status()) { + if (\PHP_SESSION_ACTIVE === session_status()) { throw new \RuntimeException('Failed to start the session: already started by PHP.'); } - if (PHP_VERSION_ID < 50400 && !$this->closed && isset($_SESSION) && session_id()) { - // not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3 - throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).'); - } - if (ini_get('session.use_cookies') && headers_sent($file, $line)) { throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); } @@ -146,10 +141,6 @@ public function start() } $this->loadSession(); - if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { - // This condition matches only PHP 5.3 with internal save handlers - $this->saveHandler->setActive(true); - } return true; } @@ -192,12 +183,7 @@ public function setName($name) public function regenerate($destroy = false, $lifetime = null) { // Cannot regenerate the session ID for non-active sessions. - if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE !== session_status()) { - return false; - } - - // Check if session ID exists in PHP 5.3 - if (PHP_VERSION_ID < 50400 && '' === session_id()) { + if (\PHP_SESSION_ACTIVE !== session_status()) { return false; } @@ -225,11 +211,6 @@ public function save() { session_write_close(); - if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { - // This condition matches only PHP 5.3 with internal save handlers - $this->saveHandler->setActive(false); - } - $this->closed = true; $this->started = false; } @@ -331,7 +312,7 @@ public function setOptions(array $options) 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', 'hash_function', 'name', 'referer_check', - 'serialize_handler', 'use_cookies', + 'serialize_handler', 'use_strict_mode', 'use_cookies', 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', @@ -379,24 +360,12 @@ public function setSaveHandler($saveHandler = null) if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); } elseif (!$saveHandler instanceof AbstractProxy) { - $saveHandler = PHP_VERSION_ID >= 50400 ? - new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy(); + $saveHandler = new SessionHandlerProxy(new \SessionHandler()); } $this->saveHandler = $saveHandler; if ($this->saveHandler instanceof \SessionHandlerInterface) { - if (PHP_VERSION_ID >= 50400) { - session_set_save_handler($this->saveHandler, false); - } else { - session_set_save_handler( - array($this->saveHandler, 'open'), - array($this->saveHandler, 'close'), - array($this->saveHandler, 'read'), - array($this->saveHandler, 'write'), - array($this->saveHandler, 'destroy'), - array($this->saveHandler, 'gc') - ); - } + session_set_save_handler($this->saveHandler, false); } } diff --git a/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php index ced706f7..6f02a7fd 100644 --- a/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php @@ -43,10 +43,6 @@ public function start() } $this->loadSession(); - if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { - // This condition matches only PHP 5.3 + internal save handlers - $this->saveHandler->setActive(true); - } return true; } diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php index 463677b5..a7478656 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php +++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php @@ -25,11 +25,6 @@ abstract class AbstractProxy */ protected $wrapper = false; - /** - * @var bool - */ - protected $active = false; - /** * @var string */ @@ -72,32 +67,7 @@ public function isWrapper() */ public function isActive() { - if (PHP_VERSION_ID >= 50400) { - return $this->active = \PHP_SESSION_ACTIVE === session_status(); - } - - return $this->active; - } - - /** - * Sets the active flag. - * - * Has no effect under PHP 5.4+ as status is detected - * automatically in isActive() - * - * @internal - * - * @param bool $flag - * - * @throws \LogicException - */ - public function setActive($flag) - { - if (PHP_VERSION_ID >= 50400) { - throw new \LogicException('This method is disabled in PHP 5.4.0+'); - } - - $this->active = (bool) $flag; + return \PHP_SESSION_ACTIVE === session_status(); } /** diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php index 81643c74..c5e97d41 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php +++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php @@ -42,13 +42,7 @@ public function __construct(\SessionHandlerInterface $handler) */ public function open($savePath, $sessionName) { - $return = (bool) $this->handler->open($savePath, $sessionName); - - if (true === $return) { - $this->active = true; - } - - return $return; + return (bool) $this->handler->open($savePath, $sessionName); } /** @@ -56,8 +50,6 @@ public function open($savePath, $sessionName) */ public function close() { - $this->active = false; - return (bool) $this->handler->close(); } diff --git a/vendor/symfony/http-foundation/StreamedResponse.php b/vendor/symfony/http-foundation/StreamedResponse.php index 8be62443..92853130 100644 --- a/vendor/symfony/http-foundation/StreamedResponse.php +++ b/vendor/symfony/http-foundation/StreamedResponse.php @@ -37,7 +37,7 @@ class StreamedResponse extends Response * @param int $status The response status code * @param array $headers An array of response headers */ - public function __construct($callback = null, $status = 200, $headers = array()) + public function __construct(callable $callback = null, $status = 200, $headers = array()) { parent::__construct(null, $status, $headers); @@ -66,14 +66,9 @@ public static function create($callback = null, $status = 200, $headers = array( * Sets the PHP callback associated with this Response. * * @param callable $callback A valid PHP callback - * - * @throws \LogicException */ - public function setCallback($callback) + public function setCallback(callable $callback) { - if (!is_callable($callback)) { - throw new \LogicException('The Response callback must be a valid PHP callable.'); - } $this->callback = $callback; } diff --git a/vendor/symfony/http-foundation/composer.json b/vendor/symfony/http-foundation/composer.json index fe9b9edc..33364d87 100644 --- a/vendor/symfony/http-foundation/composer.json +++ b/vendor/symfony/http-foundation/composer.json @@ -16,13 +16,11 @@ } ], "require": { - "php": ">=5.3.9", - "symfony/polyfill-php54": "~1.0", - "symfony/polyfill-php55": "~1.0", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { - "symfony/expression-language": "~2.4|~3.0.0" + "symfony/expression-language": "~2.8|~3.0" }, "autoload": { "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" }, @@ -33,7 +31,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/http-foundation/phpunit.xml.dist b/vendor/symfony/http-foundation/phpunit.xml.dist index 9ffdb43a..c1d61f8b 100644 --- a/vendor/symfony/http-foundation/phpunit.xml.dist +++ b/vendor/symfony/http-foundation/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/http-kernel/Bundle/Bundle.php b/vendor/symfony/http-kernel/Bundle/Bundle.php index bd8f51ec..3b4e156c 100644 --- a/vendor/symfony/http-kernel/Bundle/Bundle.php +++ b/vendor/symfony/http-kernel/Bundle/Bundle.php @@ -11,7 +11,7 @@ namespace Symfony\Component\HttpKernel\Bundle; -use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\Console\Application; @@ -26,13 +26,12 @@ */ abstract class Bundle implements BundleInterface { - /** - * @var ContainerInterface - */ - protected $container; + use ContainerAwareTrait; + protected $name; protected $extension; protected $path; + private $namespace; /** * Boots the Bundle. @@ -62,16 +61,6 @@ public function build(ContainerBuilder $container) { } - /** - * Sets the container. - * - * @param ContainerInterface|null $container A ContainerInterface instance or null - */ - public function setContainer(ContainerInterface $container = null) - { - $this->container = $container; - } - /** * Returns the bundle's container extension. * @@ -118,9 +107,11 @@ public function getContainerExtension() */ public function getNamespace() { - $class = get_class($this); + if (null === $this->namespace) { + $this->parseClassName(); + } - return substr($class, 0, strrpos($class, '\\')); + return $this->namespace; } /** @@ -141,7 +132,7 @@ public function getPath() /** * Returns the bundle parent name. * - * @return string The Bundle parent name it overrides or null if no parent + * @return string|null The Bundle parent name it overrides or null if no parent */ public function getParent() { @@ -154,14 +145,11 @@ public function getParent() */ final public function getName() { - if (null !== $this->name) { - return $this->name; + if (null === $this->name) { + $this->parseClassName(); } - $name = get_class($this); - $pos = strrpos($name, '\\'); - - return $this->name = false === $pos ? $name : substr($name, $pos + 1); + return $this->name; } /** @@ -230,4 +218,13 @@ protected function createContainerExtension() return new $class(); } } + + private function parseClassName() + { + $pos = strrpos(static::class, '\\'); + $this->namespace = false === $pos ? '' : substr(static::class, 0, $pos); + if (null === $this->name) { + $this->name = false === $pos ? static::class : substr(static::class, $pos + 1); + } + } } diff --git a/vendor/symfony/http-kernel/CHANGELOG.md b/vendor/symfony/http-kernel/CHANGELOG.md index bab3aba4..0c95ff56 100644 --- a/vendor/symfony/http-kernel/CHANGELOG.md +++ b/vendor/symfony/http-kernel/CHANGELOG.md @@ -1,6 +1,49 @@ CHANGELOG ========= +3.2.0 +----- + + * deprecated `DataCollector::varToString()`, use `cloneVar()` instead + * changed surrogate capability name in `AbstractSurrogate::addSurrogateCapability` to 'symfony' + +3.1.0 +----- + * deprecated passing objects as URI attributes to the ESI and SSI renderers + * deprecated `ControllerResolver::getArguments()` + * added `Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface` + * added `Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface` as argument to `HttpKernel` + * added `Symfony\Component\HttpKernel\Controller\ArgumentResolver` + * added `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::getMethod()` + * added `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector::getRedirect()` + * added the `kernel.controller_arguments` event, triggered after controller arguments have been resolved + +3.0.0 +----- + + * removed `Symfony\Component\HttpKernel\Kernel::init()` + * removed `Symfony\Component\HttpKernel\Kernel::isClassInActiveBundle()` and `Symfony\Component\HttpKernel\KernelInterface::isClassInActiveBundle()` + * removed `Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher::setProfiler()` + * removed `Symfony\Component\HttpKernel\EventListener\FragmentListener::getLocalIpAddresses()` + * removed `Symfony\Component\HttpKernel\EventListener\LocaleListener::setRequest()` + * removed `Symfony\Component\HttpKernel\EventListener\RouterListener::setRequest()` + * removed `Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest()` + * removed `Symfony\Component\HttpKernel\Fragment\FragmentHandler::setRequest()` + * removed `Symfony\Component\HttpKernel\HttpCache\Esi::hasSurrogateEsiCapability()` + * removed `Symfony\Component\HttpKernel\HttpCache\Esi::addSurrogateEsiCapability()` + * removed `Symfony\Component\HttpKernel\HttpCache\Esi::needsEsiParsing()` + * removed `Symfony\Component\HttpKernel\HttpCache\HttpCache::getEsi()` + * removed `Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel` + * removed `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass` + * removed `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` + * removed `Symfony\Component\HttpKernel\EventListener\EsiListener` + * removed `Symfony\Component\HttpKernel\HttpCache\EsiResponseCacheStrategy` + * removed `Symfony\Component\HttpKernel\HttpCache\EsiResponseCacheStrategyInterface` + * removed `Symfony\Component\HttpKernel\Log\LoggerInterface` + * removed `Symfony\Component\HttpKernel\Log\NullLogger` + * removed `Symfony\Component\HttpKernel\Profiler::import()` + * removed `Symfony\Component\HttpKernel\Profiler::export()` + 2.8.0 ----- @@ -34,7 +77,7 @@ CHANGELOG * [BC BREAK] renamed `Symfony\Component\HttpKernel\EventListener\DeprecationLoggerListener` to `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` and changed its constructor * deprecated `Symfony\Component\HttpKernel\Debug\ErrorHandler`, `Symfony\Component\HttpKernel\Debug\ExceptionHandler`, `Symfony\Component\HttpKernel\Exception\FatalErrorException` and `Symfony\Component\HttpKernel\Exception\FlattenException` - * deprecated `Symfony\Component\HttpKernel\Kernel::init()`` + * deprecated `Symfony\Component\HttpKernel\Kernel::init()` * added the possibility to specify an id an extra attributes to hinclude tags * added the collect of data if a controller is a Closure in the Request collector * pass exceptions from the ExceptionListener to the logger using the logging context to allow for more diff --git a/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php b/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php new file mode 100644 index 00000000..30261b3f --- /dev/null +++ b/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\CacheClearer; + +use Psr\Cache\CacheItemPoolInterface; + +/** + * @author Nicolas Grekas + */ +class Psr6CacheClearer implements CacheClearerInterface +{ + private $pools = array(); + + public function addPool(CacheItemPoolInterface $pool) + { + $this->pools[] = $pool; + } + + /** + * {@inheritdoc} + */ + public function clear($cacheDir) + { + foreach ($this->pools as $pool) { + $pool->clear(); + } + } +} diff --git a/vendor/symfony/http-kernel/Client.php b/vendor/symfony/http-kernel/Client.php index 80b1bd6c..b1814ad1 100644 --- a/vendor/symfony/http-kernel/Client.php +++ b/vendor/symfony/http-kernel/Client.php @@ -25,6 +25,9 @@ * Client simulates a browser and makes requests to a Kernel object. * * @author Fabien Potencier + * + * @method Request|null getRequest() A Request instance + * @method Response|null getResponse() A Response instance */ class Client extends BaseClient { @@ -47,26 +50,6 @@ public function __construct(HttpKernelInterface $kernel, array $server = array() parent::__construct($server, $history, $cookieJar); } - /** - * {@inheritdoc} - * - * @return Request|null A Request instance - */ - public function getRequest() - { - return parent::getRequest(); - } - - /** - * {@inheritdoc} - * - * @return Response|null A Response instance - */ - public function getResponse() - { - return parent::getResponse(); - } - /** * Makes a request. * diff --git a/vendor/symfony/http-kernel/Config/EnvParametersResource.php b/vendor/symfony/http-kernel/Config/EnvParametersResource.php index b4178a50..bad199be 100644 --- a/vendor/symfony/http-kernel/Config/EnvParametersResource.php +++ b/vendor/symfony/http-kernel/Config/EnvParametersResource.php @@ -50,7 +50,7 @@ public function __toString() } /** - * {@inheritdoc} + * @return array An array with two keys: 'prefix' for the prefix used and 'variables' containing all the variables watched by this resource */ public function getResource() { diff --git a/vendor/symfony/http-kernel/Controller/ArgumentResolver.php b/vendor/symfony/http-kernel/Controller/ArgumentResolver.php new file mode 100644 index 00000000..e63daaba --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentResolver.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestValueResolver; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver\VariadicValueResolver; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface; + +/** + * Responsible for resolving the arguments passed to an action. + * + * @author Iltar van der Berg + */ +final class ArgumentResolver implements ArgumentResolverInterface +{ + private $argumentMetadataFactory; + + /** + * @var ArgumentValueResolverInterface[] + */ + private $argumentValueResolvers; + + public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, array $argumentValueResolvers = array()) + { + $this->argumentMetadataFactory = $argumentMetadataFactory ?: new ArgumentMetadataFactory(); + $this->argumentValueResolvers = $argumentValueResolvers ?: self::getDefaultArgumentValueResolvers(); + } + + /** + * {@inheritdoc} + */ + public function getArguments(Request $request, $controller) + { + $arguments = array(); + + foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller) as $metadata) { + foreach ($this->argumentValueResolvers as $resolver) { + if (!$resolver->supports($request, $metadata)) { + continue; + } + + $resolved = $resolver->resolve($request, $metadata); + + if (!$resolved instanceof \Generator) { + throw new \InvalidArgumentException(sprintf('%s::resolve() must yield at least one value.', get_class($resolver))); + } + + foreach ($resolved as $append) { + $arguments[] = $append; + } + + // continue to the next controller argument + continue 2; + } + + $representative = $controller; + + if (is_array($representative)) { + $representative = sprintf('%s::%s()', get_class($representative[0]), $representative[1]); + } elseif (is_object($representative)) { + $representative = get_class($representative); + } + + throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.', $representative, $metadata->getName())); + } + + return $arguments; + } + + public static function getDefaultArgumentValueResolvers() + { + return array( + new RequestAttributeValueResolver(), + new RequestValueResolver(), + new DefaultValueResolver(), + new VariadicValueResolver(), + ); + } +} diff --git a/vendor/symfony/http-kernel/Controller/ArgumentResolver/DefaultValueResolver.php b/vendor/symfony/http-kernel/Controller/ArgumentResolver/DefaultValueResolver.php new file mode 100644 index 00000000..e58fd3ab --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentResolver/DefaultValueResolver.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * Yields the default value defined in the action signature when no value has been given. + * + * @author Iltar van der Berg + */ +final class DefaultValueResolver implements ArgumentValueResolverInterface +{ + /** + * {@inheritdoc} + */ + public function supports(Request $request, ArgumentMetadata $argument) + { + return $argument->hasDefaultValue() || (null !== $argument->getType() && $argument->isNullable() && !$argument->isVariadic()); + } + + /** + * {@inheritdoc} + */ + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield $argument->hasDefaultValue() ? $argument->getDefaultValue() : null; + } +} diff --git a/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestAttributeValueResolver.php b/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestAttributeValueResolver.php new file mode 100644 index 00000000..05be372d --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestAttributeValueResolver.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * Yields a non-variadic argument's value from the request attributes. + * + * @author Iltar van der Berg + */ +final class RequestAttributeValueResolver implements ArgumentValueResolverInterface +{ + /** + * {@inheritdoc} + */ + public function supports(Request $request, ArgumentMetadata $argument) + { + return !$argument->isVariadic() && $request->attributes->has($argument->getName()); + } + + /** + * {@inheritdoc} + */ + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield $request->attributes->get($argument->getName()); + } +} diff --git a/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestValueResolver.php b/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestValueResolver.php new file mode 100644 index 00000000..2a5060a6 --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestValueResolver.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * Yields the same instance as the request object passed along. + * + * @author Iltar van der Berg + */ +final class RequestValueResolver implements ArgumentValueResolverInterface +{ + /** + * {@inheritdoc} + */ + public function supports(Request $request, ArgumentMetadata $argument) + { + return Request::class === $argument->getType() || is_subclass_of($argument->getType(), Request::class); + } + + /** + * {@inheritdoc} + */ + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield $request; + } +} diff --git a/vendor/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php b/vendor/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php new file mode 100644 index 00000000..56ae5f19 --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * Yields a variadic argument's values from the request attributes. + * + * @author Iltar van der Berg + */ +final class VariadicValueResolver implements ArgumentValueResolverInterface +{ + /** + * {@inheritdoc} + */ + public function supports(Request $request, ArgumentMetadata $argument) + { + return $argument->isVariadic() && $request->attributes->has($argument->getName()); + } + + /** + * {@inheritdoc} + */ + public function resolve(Request $request, ArgumentMetadata $argument) + { + $values = $request->attributes->get($argument->getName()); + + if (!is_array($values)) { + throw new \InvalidArgumentException(sprintf('The action argument "...$%1$s" is required to be an array, the request attribute "%1$s" contains a type of "%2$s" instead.', $argument->getName(), gettype($values))); + } + + foreach ($values as $value) { + yield $value; + } + } +} diff --git a/vendor/symfony/http-kernel/Controller/ArgumentResolverInterface.php b/vendor/symfony/http-kernel/Controller/ArgumentResolverInterface.php new file mode 100644 index 00000000..5c512309 --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentResolverInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\HttpFoundation\Request; + +/** + * An ArgumentResolverInterface instance knows how to determine the + * arguments for a specific action. + * + * @author Fabien Potencier + */ +interface ArgumentResolverInterface +{ + /** + * Returns the arguments to pass to the controller. + * + * @param Request $request + * @param callable $controller + * + * @return array An array of arguments to pass to the controller + * + * @throws \RuntimeException When no value could be provided for a required argument + */ + public function getArguments(Request $request, $controller); +} diff --git a/vendor/symfony/http-kernel/Controller/ArgumentValueResolverInterface.php b/vendor/symfony/http-kernel/Controller/ArgumentValueResolverInterface.php new file mode 100644 index 00000000..fd7b09ec --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/ArgumentValueResolverInterface.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +/** + * Responsible for resolving the value of an argument based on its metadata. + * + * @author Iltar van der Berg + */ +interface ArgumentValueResolverInterface +{ + /** + * Whether this resolver can resolve the value for the given ArgumentMetadata. + * + * @param Request $request + * @param ArgumentMetadata $argument + * + * @return bool + */ + public function supports(Request $request, ArgumentMetadata $argument); + + /** + * Returns the possible value(s). + * + * @param Request $request + * @param ArgumentMetadata $argument + * + * @return \Generator + */ + public function resolve(Request $request, ArgumentMetadata $argument); +} diff --git a/vendor/symfony/http-kernel/Controller/ControllerResolver.php b/vendor/symfony/http-kernel/Controller/ControllerResolver.php index a1cff535..f51a5a8e 100644 --- a/vendor/symfony/http-kernel/Controller/ControllerResolver.php +++ b/vendor/symfony/http-kernel/Controller/ControllerResolver.php @@ -23,7 +23,7 @@ * * @author Fabien Potencier */ -class ControllerResolver implements ControllerResolverInterface +class ControllerResolver implements ArgumentResolverInterface, ControllerResolverInterface { private $logger; @@ -95,7 +95,7 @@ public function getController(Request $request) $callable = $this->createController($controller); if (!is_callable($callable)) { - throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', $controller, $request->getPathInfo())); + throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s', $request->getPathInfo(), $this->getControllerError($callable))); } return $callable; @@ -103,9 +103,13 @@ public function getController(Request $request) /** * {@inheritdoc} + * + * @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface and inject it in the HttpKernel instead. */ public function getArguments(Request $request, $controller) { + @trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED); + if (is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); } elseif (is_object($controller) && !$controller instanceof \Closure) { @@ -124,9 +128,13 @@ public function getArguments(Request $request, $controller) * @param \ReflectionParameter[] $parameters * * @return array The arguments to use when calling the action + * + * @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface and inject it in the HttpKernel instead. */ protected function doGetArguments(Request $request, $controller, array $parameters) { + @trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), E_USER_DEPRECATED); + $attributes = $request->attributes->all(); $arguments = array(); foreach ($parameters as $param) { @@ -193,4 +201,65 @@ protected function instantiateController($class) { return new $class(); } + + private function getControllerError($callable) + { + if (is_string($callable)) { + if (false !== strpos($callable, '::')) { + $callable = explode('::', $callable); + } + + if (class_exists($callable) && !method_exists($callable, '__invoke')) { + return sprintf('Class "%s" does not have a method "__invoke".', $callable); + } + + if (!function_exists($callable)) { + return sprintf('Function "%s" does not exist.', $callable); + } + } + + if (!is_array($callable)) { + return sprintf('Invalid type for controller given, expected string or array, got "%s".', gettype($callable)); + } + + if (2 !== count($callable)) { + return sprintf('Invalid format for controller, expected array(controller, method) or controller::method.'); + } + + list($controller, $method) = $callable; + + if (is_string($controller) && !class_exists($controller)) { + return sprintf('Class "%s" does not exist.', $controller); + } + + $className = is_object($controller) ? get_class($controller) : $controller; + + if (method_exists($controller, $method)) { + return sprintf('Method "%s" on class "%s" should be public and non-abstract.', $method, $className); + } + + $collection = get_class_methods($controller); + + $alternatives = array(); + + foreach ($collection as $item) { + $lev = levenshtein($method, $item); + + if ($lev <= strlen($method) / 3 || false !== strpos($item, $method)) { + $alternatives[] = $item; + } + } + + asort($alternatives); + + $message = sprintf('Expected method "%s" on class "%s"', $method, $className); + + if (count($alternatives) > 0) { + $message .= sprintf(', did you mean "%s"?', implode('", "', $alternatives)); + } else { + $message .= sprintf('. Available methods: "%s".', implode('", "', $collection)); + } + + return $message; + } } diff --git a/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php b/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php index f7b19ed1..0dd7cce9 100644 --- a/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php +++ b/vendor/symfony/http-kernel/Controller/ControllerResolverInterface.php @@ -52,6 +52,8 @@ public function getController(Request $request); * @return array An array of arguments to pass to the controller * * @throws \RuntimeException When value for argument given is not provided + * + * @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. Please use the {@see ArgumentResolverInterface} instead. */ public function getArguments(Request $request, $controller); } diff --git a/vendor/symfony/http-kernel/Controller/TraceableArgumentResolver.php b/vendor/symfony/http-kernel/Controller/TraceableArgumentResolver.php new file mode 100644 index 00000000..6fb0fa66 --- /dev/null +++ b/vendor/symfony/http-kernel/Controller/TraceableArgumentResolver.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Controller; + +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Fabien Potencier + */ +class TraceableArgumentResolver implements ArgumentResolverInterface +{ + private $resolver; + private $stopwatch; + + public function __construct(ArgumentResolverInterface $resolver, Stopwatch $stopwatch) + { + $this->resolver = $resolver; + $this->stopwatch = $stopwatch; + } + + /** + * {@inheritdoc} + */ + public function getArguments(Request $request, $controller) + { + $e = $this->stopwatch->start('controller.get_arguments'); + + $ret = $this->resolver->getArguments($request, $controller); + + $e->stop(); + + return $ret; + } +} diff --git a/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php b/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php index f8de31cf..ce291b1e 100644 --- a/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php +++ b/vendor/symfony/http-kernel/Controller/TraceableControllerResolver.php @@ -19,21 +19,33 @@ * * @author Fabien Potencier */ -class TraceableControllerResolver implements ControllerResolverInterface +class TraceableControllerResolver implements ControllerResolverInterface, ArgumentResolverInterface { private $resolver; private $stopwatch; + private $argumentResolver; /** * Constructor. * - * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance - * @param Stopwatch $stopwatch A Stopwatch instance + * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance + * @param Stopwatch $stopwatch A Stopwatch instance + * @param ArgumentResolverInterface $argumentResolver Only required for BC */ - public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch) + public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch, ArgumentResolverInterface $argumentResolver = null) { $this->resolver = $resolver; $this->stopwatch = $stopwatch; + $this->argumentResolver = $argumentResolver; + + // BC + if (null === $this->argumentResolver) { + $this->argumentResolver = $resolver; + } + + if (!$this->argumentResolver instanceof TraceableArgumentResolver) { + $this->argumentResolver = new TraceableArgumentResolver($this->argumentResolver, $this->stopwatch); + } } /** @@ -52,14 +64,14 @@ public function getController(Request $request) /** * {@inheritdoc} + * + * @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. */ public function getArguments(Request $request, $controller) { - $e = $this->stopwatch->start('controller.get_arguments'); + @trigger_error(sprintf('The %s method is deprecated as of 3.1 and will be removed in 4.0. Please use the %s instead.', __METHOD__, TraceableArgumentResolver::class), E_USER_DEPRECATED); - $ret = $this->resolver->getArguments($request, $controller); - - $e->stop(); + $ret = $this->argumentResolver->getArguments($request, $controller); return $ret; } diff --git a/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php new file mode 100644 index 00000000..32316a8d --- /dev/null +++ b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\ControllerMetadata; + +/** + * Responsible for storing metadata of an argument. + * + * @author Iltar van der Berg + */ +class ArgumentMetadata +{ + private $name; + private $type; + private $isVariadic; + private $hasDefaultValue; + private $defaultValue; + private $isNullable; + + /** + * @param string $name + * @param string $type + * @param bool $isVariadic + * @param bool $hasDefaultValue + * @param mixed $defaultValue + * @param bool $isNullable + */ + public function __construct($name, $type, $isVariadic, $hasDefaultValue, $defaultValue, $isNullable = false) + { + $this->name = $name; + $this->type = $type; + $this->isVariadic = $isVariadic; + $this->hasDefaultValue = $hasDefaultValue; + $this->defaultValue = $defaultValue; + $this->isNullable = $isNullable || null === $type || ($hasDefaultValue && null === $defaultValue); + } + + /** + * Returns the name as given in PHP, $foo would yield "foo". + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Returns the type of the argument. + * + * The type is the PHP class in 5.5+ and additionally the basic type in PHP 7.0+. + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Returns whether the argument is defined as "...$variadic". + * + * @return bool + */ + public function isVariadic() + { + return $this->isVariadic; + } + + /** + * Returns whether the argument has a default value. + * + * Implies whether an argument is optional. + * + * @return bool + */ + public function hasDefaultValue() + { + return $this->hasDefaultValue; + } + + /** + * Returns whether the argument accepts null values. + * + * @return bool + */ + public function isNullable() + { + return $this->isNullable; + } + + /** + * Returns the default value of the argument. + * + * @throws \LogicException if no default value is present; {@see self::hasDefaultValue()} + * + * @return mixed + */ + public function getDefaultValue() + { + if (!$this->hasDefaultValue) { + throw new \LogicException(sprintf('Argument $%s does not have a default value. Use %s::hasDefaultValue() to avoid this exception.', $this->name, __CLASS__)); + } + + return $this->defaultValue; + } +} diff --git a/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php new file mode 100644 index 00000000..d1e7af20 --- /dev/null +++ b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\ControllerMetadata; + +/** + * Builds {@see ArgumentMetadata} objects based on the given Controller. + * + * @author Iltar van der Berg + */ +final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface +{ + /** + * If the ...$arg functionality is available. + * + * Requires at least PHP 5.6.0 or HHVM 3.9.1 + * + * @var bool + */ + private $supportsVariadic; + + /** + * If the reflection supports the getType() method to resolve types. + * + * Requires at least PHP 7.0.0 or HHVM 3.11.0 + * + * @var bool + */ + private $supportsParameterType; + + public function __construct() + { + $this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic'); + $this->supportsParameterType = method_exists('ReflectionParameter', 'getType'); + } + + /** + * {@inheritdoc} + */ + public function createArgumentMetadata($controller) + { + $arguments = array(); + + if (is_array($controller)) { + $reflection = new \ReflectionMethod($controller[0], $controller[1]); + } elseif (is_object($controller) && !$controller instanceof \Closure) { + $reflection = (new \ReflectionObject($controller))->getMethod('__invoke'); + } else { + $reflection = new \ReflectionFunction($controller); + } + + foreach ($reflection->getParameters() as $param) { + $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $param->allowsNull()); + } + + return $arguments; + } + + /** + * Returns whether an argument is variadic. + * + * @param \ReflectionParameter $parameter + * + * @return bool + */ + private function isVariadic(\ReflectionParameter $parameter) + { + return $this->supportsVariadic && $parameter->isVariadic(); + } + + /** + * Determines whether an argument has a default value. + * + * @param \ReflectionParameter $parameter + * + * @return bool + */ + private function hasDefaultValue(\ReflectionParameter $parameter) + { + return $parameter->isDefaultValueAvailable(); + } + + /** + * Returns a default value if available. + * + * @param \ReflectionParameter $parameter + * + * @return mixed|null + */ + private function getDefaultValue(\ReflectionParameter $parameter) + { + return $this->hasDefaultValue($parameter) ? $parameter->getDefaultValue() : null; + } + + /** + * Returns an associated type to the given parameter if available. + * + * @param \ReflectionParameter $parameter + * + * @return null|string + */ + private function getType(\ReflectionParameter $parameter) + { + if ($this->supportsParameterType) { + if (!$type = $parameter->getType()) { + return; + } + $typeName = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); + if ('array' === $typeName && !$type->isBuiltin()) { + // Special case for HHVM with variadics + return; + } + + return $typeName; + } + + if (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $parameter, $info)) { + return $info[1]; + } + } +} diff --git a/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactoryInterface.php b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactoryInterface.php new file mode 100644 index 00000000..6ea179d7 --- /dev/null +++ b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactoryInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\ControllerMetadata; + +/** + * Builds method argument data. + * + * @author Iltar van der Berg + */ +interface ArgumentMetadataFactoryInterface +{ + /** + * @param mixed $controller The controller to resolve the arguments for + * + * @return ArgumentMetadata[] + */ + public function createArgumentMetadata($controller); +} diff --git a/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php b/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php index 395fee39..13db7c43 100644 --- a/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php +++ b/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php @@ -29,7 +29,6 @@ class ConfigDataCollector extends DataCollector private $kernel; private $name; private $version; - private $cacheVersionInfo = true; /** * Constructor. @@ -127,11 +126,6 @@ public function getSymfonyState() return $this->data['symfony_state']; } - public function setCacheVersionInfo($cacheVersionInfo) - { - $this->cacheVersionInfo = $cacheVersionInfo; - } - /** * Gets the PHP version. * diff --git a/vendor/symfony/http-kernel/DataCollector/DataCollector.php b/vendor/symfony/http-kernel/DataCollector/DataCollector.php index 5dca6529..3808852d 100644 --- a/vendor/symfony/http-kernel/DataCollector/DataCollector.php +++ b/vendor/symfony/http-kernel/DataCollector/DataCollector.php @@ -12,6 +12,13 @@ namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; +use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Caster\LinkStub; +use Symfony\Component\VarDumper\Caster\StubCaster; +use Symfony\Component\VarDumper\Cloner\ClonerInterface; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\Stub; +use Symfony\Component\VarDumper\Cloner\VarCloner; /** * DataCollector. @@ -30,6 +37,13 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable */ private $valueExporter; + /** + * @var ClonerInterface + */ + private $cloner; + + private static $stubsCache = array(); + public function serialize() { return serialize($this->data); @@ -40,19 +54,92 @@ public function unserialize($data) $this->data = unserialize($data); } + /** + * Converts the variable into a serializable Data instance. + * + * This array can be displayed in the template using + * the VarDumper component. + * + * @param mixed $var + * + * @return Data + */ + protected function cloneVar($var) + { + if (null === $this->cloner) { + if (class_exists(ClassStub::class)) { + $this->cloner = new VarCloner(); + $this->cloner->setMaxItems(250); + $this->cloner->addCasters(array( + Stub::class => function (Stub $v, array $a, Stub $s, $isNested) { + return $isNested ? $a : StubCaster::castStub($v, $a, $s, true); + }, + )); + } else { + @trigger_error(sprintf('Using the %s() method without the VarDumper component is deprecated since version 3.2 and won\'t be supported in 4.0. Install symfony/var-dumper version 3.2 or above.', __METHOD__), E_USER_DEPRECATED); + $this->cloner = false; + } + } + if (false === $this->cloner) { + if (null === $this->valueExporter) { + $this->valueExporter = new ValueExporter(); + } + + return $this->valueExporter->exportValue($var); + } + + return $this->cloner->cloneVar($this->decorateVar($var)); + } + /** * Converts a PHP variable to a string. * * @param mixed $var A PHP variable * * @return string The string representation of the variable + * + * @deprecated Deprecated since version 3.2, to be removed in 4.0. Use cloneVar() instead. */ protected function varToString($var) { + @trigger_error(sprintf('The %s() method is deprecated since version 3.2 and will be removed in 4.0. Use cloneVar() instead.', __METHOD__), E_USER_DEPRECATED); + if (null === $this->valueExporter) { $this->valueExporter = new ValueExporter(); } return $this->valueExporter->exportValue($var); } + + private function decorateVar($var) + { + if (is_array($var)) { + if (isset($var[0], $var[1]) && is_callable($var)) { + return ClassStub::wrapCallable($var); + } + foreach ($var as $k => $v) { + if ($v !== $d = $this->decorateVar($v)) { + $var[$k] = $d; + } + } + + return $var; + } + if (is_string($var)) { + if (isset(self::$stubsCache[$var])) { + return self::$stubsCache[$var]; + } + if (false !== strpos($var, '\\')) { + $c = (false !== $i = strpos($var, '::')) ? substr($var, 0, $i) : $var; + if (class_exists($c, false) || interface_exists($c, false) || trait_exists($c, false)) { + return self::$stubsCache[$var] = new ClassStub($var); + } + } + if (false !== strpos($var, DIRECTORY_SEPARATOR) && false === strpos($var, '://') && false === strpos($var, "\0") && @is_file($var)) { + return self::$stubsCache[$var] = new LinkStub($var); + } + } + + return $var; + } } diff --git a/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php b/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php index 3f5e6acf..b638ba79 100644 --- a/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php +++ b/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php @@ -70,12 +70,7 @@ public function dump(Data $data) $this->isCollected = false; } - $trace = DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS; - if (PHP_VERSION_ID >= 50400) { - $trace = debug_backtrace($trace, 7); - } else { - $trace = debug_backtrace($trace); - } + $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS, 7); $file = $trace[0]['file']; $line = $trace[0]['line']; @@ -157,6 +152,7 @@ public function collect(Request $request, Response $response, \Exception $except ) { if ($response->headers->has('Content-Type') && false !== strpos($response->headers->get('Content-Type'), 'html')) { $this->dumper = new HtmlDumper('php://output', $this->charset); + $this->dumper->setDisplayOptions(array('fileLinkFormat' => $this->fileLinkFormat)); } else { $this->dumper = new CliDumper('php://output', $this->charset); } @@ -206,18 +202,14 @@ public function getDumps($format, $maxDepthLimit = -1, $maxItemsPerDepth = -1) if ('html' === $format) { $dumper = new HtmlDumper($data, $this->charset); + $dumper->setDisplayOptions(array('fileLinkFormat' => $this->fileLinkFormat)); } else { throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format)); } $dumps = array(); foreach ($this->data as $dump) { - if (method_exists($dump['data'], 'withMaxDepth')) { - $dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth)); - } else { - // getLimitedClone is @deprecated, to be removed in 3.0 - $dumper->dump($dump['data']->getLimitedClone($maxDepthLimit, $maxItemsPerDepth)); - } + $dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth)); $dump['data'] = stream_get_contents($data, -1, 0); ftruncate($data, 0); rewind($data); @@ -247,6 +239,7 @@ public function __destruct() if ('cli' !== PHP_SAPI && stripos($h[$i], 'html')) { $this->dumper = new HtmlDumper('php://output', $this->charset); + $this->dumper->setDisplayOptions(array('fileLinkFormat' => $this->fileLinkFormat)); } else { $this->dumper = new CliDumper('php://output', $this->charset); } @@ -263,18 +256,17 @@ public function __destruct() private function doDump($data, $name, $file, $line) { - if (PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) { - $contextDumper = function ($name, $file, $line, $fileLinkFormat) { + if ($this->dumper instanceof CliDumper) { + $contextDumper = function ($name, $file, $line, $fmt) { if ($this instanceof HtmlDumper) { if ($file) { $s = $this->style('meta', '%s'); + $f = strip_tags($this->style('', $file)); $name = strip_tags($this->style('', $name)); - $file = strip_tags($this->style('', $file)); - if ($fileLinkFormat) { - $link = strtr(strip_tags($this->style('', $fileLinkFormat)), array('%f' => $file, '%l' => (int) $line)); - $name = sprintf(''.$s.'', $link, $file, $name); + if ($fmt && $link = is_string($fmt) ? strtr($fmt, array('%f' => $file, '%l' => $line)) : $fmt->format($file, $line)) { + $name = sprintf(''.$s.'', strip_tags($this->style('', $link)), $f, $name); } else { - $name = sprintf(''.$s.'', $file, $name); + $name = sprintf(''.$s.'', $f, $name); } } else { $name = $this->style('meta', $name); @@ -298,7 +290,7 @@ private function htmlEncode($s) { $html = ''; - $dumper = new HtmlDumper(function ($line) use (&$html) {$html .= $line;}, $this->charset); + $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset); $dumper->setDumpHeader(''); $dumper->setDumpBoundaries('', ''); diff --git a/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php b/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php index 0e4df12b..358a411a 100644 --- a/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php +++ b/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpKernel\DataCollector; +use Symfony\Component\Debug\Exception\SilencedErrorContext; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; @@ -22,24 +23,6 @@ */ class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface { - private $errorNames = array( - E_DEPRECATED => 'E_DEPRECATED', - E_USER_DEPRECATED => 'E_USER_DEPRECATED', - E_NOTICE => 'E_NOTICE', - E_USER_NOTICE => 'E_USER_NOTICE', - E_STRICT => 'E_STRICT', - E_WARNING => 'E_WARNING', - E_USER_WARNING => 'E_USER_WARNING', - E_COMPILE_WARNING => 'E_COMPILE_WARNING', - E_CORE_WARNING => 'E_CORE_WARNING', - E_USER_ERROR => 'E_USER_ERROR', - E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', - E_COMPILE_ERROR => 'E_COMPILE_ERROR', - E_PARSE => 'E_PARSE', - E_ERROR => 'E_ERROR', - E_CORE_ERROR => 'E_CORE_ERROR', - ); - private $logger; public function __construct($logger = null) @@ -93,6 +76,11 @@ public function countDeprecations() return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0; } + public function countWarnings() + { + return isset($this->data['warning_count']) ? $this->data['warning_count'] : 0; + } + public function countScreams() { return isset($this->data['scream_count']) ? $this->data['scream_count'] : 0; @@ -108,74 +96,53 @@ public function getName() private function sanitizeLogs($logs) { - $errorContextById = array(); $sanitizedLogs = array(); foreach ($logs as $log) { - $context = $this->sanitizeContext($log['context']); - - if (isset($context['type'], $context['file'], $context['line'], $context['level'])) { - $errorId = md5("{$context['type']}/{$context['line']}/{$context['file']}\x00{$log['message']}", true); - $silenced = !($context['type'] & $context['level']); - if (isset($this->errorNames[$context['type']])) { - $context = array_merge(array('name' => $this->errorNames[$context['type']]), $context); - } + if (!$this->isSilencedOrDeprecationErrorLog($log)) { + $log['context'] = $log['context'] ? $this->cloneVar($log['context']) : $log['context']; + $sanitizedLogs[] = $log; - if (isset($errorContextById[$errorId])) { - if (isset($errorContextById[$errorId]['errorCount'])) { - ++$errorContextById[$errorId]['errorCount']; - } else { - $errorContextById[$errorId]['errorCount'] = 2; - } + continue; + } - if (!$silenced && isset($errorContextById[$errorId]['scream'])) { - unset($errorContextById[$errorId]['scream']); - $errorContextById[$errorId]['level'] = $context['level']; - } + $exception = $log['context']['exception']; + $errorId = md5("{$exception->getSeverity()}/{$exception->getLine()}/{$exception->getFile()}".($exception instanceof \Exception ? "\0".$exception->getMessage() : ''), true); - continue; - } + if (isset($sanitizedLogs[$errorId])) { + ++$sanitizedLogs[$errorId]['errorCount']; + } else { + $log['context'] = $log['context'] ? $this->cloneVar($log['context']) : $log['context']; - $errorContextById[$errorId] = &$context; - if ($silenced) { - $context['scream'] = true; - } + $log += array( + 'errorCount' => 1, + 'scream' => $exception instanceof SilencedErrorContext, + ); - $log['context'] = &$context; - unset($context); - } else { - $log['context'] = $context; + $sanitizedLogs[$errorId] = $log; } - - $sanitizedLogs[] = $log; } - return $sanitizedLogs; + return array_values($sanitizedLogs); } - private function sanitizeContext($context) + private function isSilencedOrDeprecationErrorLog(array $log) { - if (is_array($context)) { - foreach ($context as $key => $value) { - $context[$key] = $this->sanitizeContext($value); - } - - return $context; + if (!isset($log['context']['exception'])) { + return false; } - if (is_resource($context)) { - return sprintf('Resource(%s)', get_resource_type($context)); - } + $exception = $log['context']['exception']; - if (is_object($context)) { - if ($context instanceof \Exception) { - return sprintf('Exception(%s): %s', get_class($context), $context->getMessage()); - } + if ($exception instanceof SilencedErrorContext) { + return true; + } - return sprintf('Object(%s)', get_class($context)); + if ($exception instanceof \ErrorException && in_array($exception->getSeverity(), array(E_DEPRECATED, E_USER_DEPRECATED), true)) { + return true; } - return $context; + return false; } private function computeErrorsCount() @@ -183,6 +150,7 @@ private function computeErrorsCount() $count = array( 'error_count' => $this->logger->countErrors(), 'deprecation_count' => 0, + 'warning_count' => 0, 'scream_count' => 0, 'priorities' => array(), ); @@ -196,12 +164,15 @@ private function computeErrorsCount() 'name' => $log['priorityName'], ); } + if ('WARNING' === $log['priorityName']) { + ++$count['warning_count']; + } - if (isset($log['context']['type'], $log['context']['level'])) { - if (E_DEPRECATED === $log['context']['type'] || E_USER_DEPRECATED === $log['context']['type']) { - ++$count['deprecation_count']; - } elseif (!($log['context']['type'] & $log['context']['level'])) { + if ($this->isSilencedOrDeprecationErrorLog($log)) { + if ($log['context']['exception'] instanceof SilencedErrorContext) { ++$count['scream_count']; + } else { + ++$count['deprecation_count']; } } } diff --git a/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php b/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php index 7929cfc6..e29cc9da 100644 --- a/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php +++ b/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php @@ -14,6 +14,7 @@ use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -25,6 +26,7 @@ */ class RequestDataCollector extends DataCollector implements EventSubscriberInterface { + /** @var \SplObjectStorage */ protected $controllers; public function __construct() @@ -44,17 +46,13 @@ public function collect(Request $request, Response $response, \Exception $except // attributes are serialized and as they can be anything, they need to be converted to strings. $attributes = array(); + $route = ''; foreach ($request->attributes->all() as $key => $value) { - if ('_route' === $key && is_object($value)) { - $attributes[$key] = $this->varToString($value->getPath()); - } elseif ('_route_params' === $key) { - // we need to keep route params as an array (see getRouteParams()) - foreach ($value as $k => $v) { - $value[$k] = $this->varToString($v); - } - $attributes[$key] = $value; + if ('_route' === $key) { + $route = is_object($value) ? $value->getPath() : $value; + $attributes[$key] = $route; } else { - $attributes[$key] = $this->varToString($value); + $attributes[$key] = $value; } } @@ -68,6 +66,7 @@ public function collect(Request $request, Response $response, \Exception $except $sessionMetadata = array(); $sessionAttributes = array(); + $session = null; $flashes = array(); if ($request->hasSession()) { $session = $request->getSession(); @@ -83,6 +82,7 @@ public function collect(Request $request, Response $response, \Exception $except $statusCode = $response->getStatusCode(); $this->data = array( + 'method' => $request->getMethod(), 'format' => $request->getRequestFormat(), 'content' => $content, 'content_type' => $response->headers->get('Content-Type', 'text/html'), @@ -94,6 +94,7 @@ public function collect(Request $request, Response $response, \Exception $except 'request_server' => $request->server->all(), 'request_cookies' => $request->cookies->all(), 'request_attributes' => $attributes, + 'route' => $route, 'response_headers' => $responseHeaders, 'session_metadata' => $sessionMetadata, 'session_attributes' => $sessionAttributes, @@ -123,53 +124,36 @@ public function collect(Request $request, Response $response, \Exception $except $value = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value); } if ('request_server' !== $key && 'request_cookies' !== $key) { - $this->data[$key] = $value; + $this->data[$key] = array_map(array($this, 'cloneVar'), $value); } } if (isset($this->controllers[$request])) { - $controller = $this->controllers[$request]; - if (is_array($controller)) { - try { - $r = new \ReflectionMethod($controller[0], $controller[1]); - $this->data['controller'] = array( - 'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], - 'method' => $controller[1], - 'file' => $r->getFileName(), - 'line' => $r->getStartLine(), - ); - } catch (\ReflectionException $e) { - if (is_callable($controller)) { - // using __call or __callStatic - $this->data['controller'] = array( - 'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], - 'method' => $controller[1], - 'file' => 'n/a', - 'line' => 'n/a', - ); - } - } - } elseif ($controller instanceof \Closure) { - $r = new \ReflectionFunction($controller); - $this->data['controller'] = array( - 'class' => $r->getName(), - 'method' => null, - 'file' => $r->getFileName(), - 'line' => $r->getStartLine(), - ); - } elseif (is_object($controller)) { - $r = new \ReflectionClass($controller); - $this->data['controller'] = array( - 'class' => $r->getName(), - 'method' => null, - 'file' => $r->getFileName(), - 'line' => $r->getStartLine(), - ); - } else { - $this->data['controller'] = (string) $controller ?: 'n/a'; - } + $this->data['controller'] = $this->parseController($this->controllers[$request]); unset($this->controllers[$request]); } + + if (null !== $session && $session->isStarted()) { + if ($request->attributes->has('_redirected')) { + $this->data['redirect'] = $session->remove('sf_redirect'); + } + + if ($response->isRedirect()) { + $session->set('sf_redirect', array( + 'token' => $response->headers->get('x-debug-token'), + 'route' => $request->attributes->get('_route', 'n/a'), + 'method' => $request->getMethod(), + 'controller' => $this->parseController($request->attributes->get('_controller')), + 'status_code' => $statusCode, + 'status_text' => Response::$statusTexts[(int) $statusCode], + )); + } + } + } + + public function getMethod() + { + return $this->data['method']; } public function getPathInfo() @@ -192,14 +176,14 @@ public function getRequestHeaders() return new ParameterBag($this->data['request_headers']); } - public function getRequestServer() + public function getRequestServer($raw = false) { - return new ParameterBag($this->data['request_server']); + return new ParameterBag($raw ? $this->data['request_server'] : array_map(array($this, 'cloneVar'), $this->data['request_server'])); } - public function getRequestCookies() + public function getRequestCookies($raw = false) { - return new ParameterBag($this->data['request_cookies']); + return new ParameterBag($raw ? $this->data['request_cookies'] : array_map(array($this, 'cloneVar'), $this->data['request_cookies'])); } public function getRequestAttributes() @@ -266,7 +250,12 @@ public function getLocale() */ public function getRoute() { - return isset($this->data['request_attributes']['_route']) ? $this->data['request_attributes']['_route'] : ''; + return $this->data['route']; + } + + public function getIdentifier() + { + return $this->data['route'] ?: (is_array($this->data['controller']) ? $this->data['controller']['class'].'::'.$this->data['controller']['method'].'()' : $this->data['controller']); } /** @@ -278,27 +267,68 @@ public function getRoute() */ public function getRouteParams() { - return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : array(); + if (!isset($this->data['request_attributes']['_route_params'])) { + return array(); + } + + $data = $this->data['request_attributes']['_route_params']; + $rawData = $data->getRawData(); + if (!isset($rawData[1])) { + return array(); + } + + $params = array(); + foreach ($rawData[1] as $k => $v) { + $params[$k] = $data->seek($k); + } + + return $params; } /** - * Gets the controller. + * Gets the parsed controller. * - * @return string The controller as a string + * @return array|string The controller as a string or array of data + * with keys 'class', 'method', 'file' and 'line' */ public function getController() { return $this->data['controller']; } + /** + * Gets the previous request attributes. + * + * @return array|bool A legacy array of data from the previous redirection response + * or false otherwise + */ + public function getRedirect() + { + return isset($this->data['redirect']) ? $this->data['redirect'] : false; + } + public function onKernelController(FilterControllerEvent $event) { $this->controllers[$event->getRequest()] = $event->getController(); } + public function onKernelResponse(FilterResponseEvent $event) + { + if (!$event->isMasterRequest() || !$event->getRequest()->hasSession() || !$event->getRequest()->getSession()->isStarted()) { + return; + } + + if ($event->getRequest()->getSession()->has('sf_redirect')) { + $event->getRequest()->attributes->set('_redirected', true); + } + } + public static function getSubscribedEvents() { - return array(KernelEvents::CONTROLLER => 'onKernelController'); + return array( + KernelEvents::CONTROLLER => 'onKernelController', + KernelEvents::RESPONSE => 'onKernelResponse', + ); } /** @@ -308,4 +338,65 @@ public function getName() { return 'request'; } + + /** + * Parse a controller. + * + * @param mixed $controller The controller to parse + * + * @return array|string An array of controller data or a simple string + */ + protected function parseController($controller) + { + if (is_string($controller) && false !== strpos($controller, '::')) { + $controller = explode('::', $controller); + } + + if (is_array($controller)) { + try { + $r = new \ReflectionMethod($controller[0], $controller[1]); + + return array( + 'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], + 'method' => $controller[1], + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ); + } catch (\ReflectionException $e) { + if (is_callable($controller)) { + // using __call or __callStatic + return array( + 'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0], + 'method' => $controller[1], + 'file' => 'n/a', + 'line' => 'n/a', + ); + } + } + } + + if ($controller instanceof \Closure) { + $r = new \ReflectionFunction($controller); + + return array( + 'class' => $r->getName(), + 'method' => null, + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ); + } + + if (is_object($controller)) { + $r = new \ReflectionClass($controller); + + return array( + 'class' => $r->getName(), + 'method' => null, + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ); + } + + return is_string($controller) ? $controller : 'n/a'; + } } diff --git a/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php b/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php index 09fe4e33..f1e48311 100644 --- a/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php +++ b/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php @@ -11,8 +11,12 @@ namespace Symfony\Component\HttpKernel\DataCollector\Util; +@trigger_error('The '.__NAMESPACE__.'\ValueExporter class is deprecated since version 3.2 and will be removed in 4.0. Use the VarDumper component instead.', E_USER_DEPRECATED); + /** * @author Bernhard Schussek + * + * @deprecated since version 3.2, to be removed in 4.0. Use the VarDumper component instead. */ class ValueExporter { @@ -32,8 +36,8 @@ public function exportValue($value, $depth = 1, $deep = false) } if (is_object($value)) { - if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) { - return sprintf('Object(%s) - %s', get_class($value), $value->format(\DateTime::ISO8601)); + if ($value instanceof \DateTimeInterface) { + return sprintf('Object(%s) - %s', get_class($value), $value->format(\DateTime::ATOM)); } return sprintf('Object(%s)', get_class($value)); @@ -58,7 +62,13 @@ public function exportValue($value, $depth = 1, $deep = false) return sprintf("[\n%s%s\n%s]", $indent, implode(sprintf(", \n%s", $indent), $a), str_repeat(' ', $depth - 1)); } - return sprintf('[%s]', implode(', ', $a)); + $s = sprintf('[%s]', implode(', ', $a)); + + if (80 > strlen($s)) { + return $s; + } + + return sprintf("[\n%s%s\n]", $indent, implode(sprintf(",\n%s", $indent), $a)); } if (is_resource($value)) { diff --git a/vendor/symfony/http-kernel/Debug/ErrorHandler.php b/vendor/symfony/http-kernel/Debug/ErrorHandler.php deleted file mode 100644 index af714a30..00000000 --- a/vendor/symfony/http-kernel/Debug/ErrorHandler.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Debug; - -@trigger_error('The '.__NAMESPACE__.'\ErrorHandler class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\ErrorHandler class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Debug\ErrorHandler as DebugErrorHandler; - -/** - * ErrorHandler. - * - * @author Fabien Potencier - * - * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. - */ -class ErrorHandler extends DebugErrorHandler -{ -} diff --git a/vendor/symfony/http-kernel/Debug/ExceptionHandler.php b/vendor/symfony/http-kernel/Debug/ExceptionHandler.php deleted file mode 100644 index 50755d97..00000000 --- a/vendor/symfony/http-kernel/Debug/ExceptionHandler.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Debug; - -@trigger_error('The '.__NAMESPACE__.'\ExceptionHandler class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\ExceptionHandler class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Debug\ExceptionHandler as DebugExceptionHandler; - -/** - * ExceptionHandler converts an exception to a Response object. - * - * @author Fabien Potencier - * - * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. - */ -class ExceptionHandler extends DebugExceptionHandler -{ -} diff --git a/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php b/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php new file mode 100644 index 00000000..03e3cf89 --- /dev/null +++ b/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Debug; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; + +/** + * Formats debug file links. + * + * @author Jérémy Romey + */ +class FileLinkFormatter implements \Serializable +{ + private $fileLinkFormat; + private $requestStack; + private $baseDir; + private $urlFormat; + + public function __construct($fileLinkFormat = null, RequestStack $requestStack = null, $baseDir = null, $urlFormat = null) + { + $fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + if ($fileLinkFormat && !is_array($fileLinkFormat)) { + $i = strpos($f = $fileLinkFormat, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: strlen($f); + $fileLinkFormat = array(substr($f, 0, $i)) + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE); + } + + $this->fileLinkFormat = $fileLinkFormat; + $this->requestStack = $requestStack; + $this->baseDir = $baseDir; + $this->urlFormat = $urlFormat; + } + + public function format($file, $line) + { + if ($fmt = $this->getFileLinkFormat()) { + for ($i = 1; isset($fmt[$i]); ++$i) { + if (0 === strpos($file, $k = $fmt[$i++])) { + $file = substr_replace($file, $fmt[$i], 0, strlen($k)); + break; + } + } + + return strtr($fmt[0], array('%f' => $file, '%l' => $line)); + } + + return false; + } + + public function serialize() + { + return serialize($this->getFileLinkFormat()); + } + + public function unserialize($serialized) + { + $this->fileLinkFormat = unserialize($serialized); + } + + private function getFileLinkFormat() + { + if ($this->fileLinkFormat) { + return $this->fileLinkFormat; + } + if ($this->requestStack && $this->baseDir && $this->urlFormat) { + $request = $this->requestStack->getMasterRequest(); + if ($request instanceof Request) { + return array( + $request->getSchemeAndHttpHost().$request->getBaseUrl().$this->urlFormat, + $this->baseDir.DIRECTORY_SEPARATOR, '', + ); + } + } + } +} diff --git a/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php b/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php index eb1d8a8e..fbc49dff 100644 --- a/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php +++ b/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php @@ -12,7 +12,6 @@ namespace Symfony\Component\HttpKernel\Debug; use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher as BaseTraceableEventDispatcher; -use Symfony\Component\HttpKernel\Profiler\Profiler; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\Event; @@ -25,22 +24,6 @@ */ class TraceableEventDispatcher extends BaseTraceableEventDispatcher { - /** - * Sets the profiler. - * - * The traceable event dispatcher does not use the profiler anymore. - * The job is now done directly by the Profiler listener and the - * data collectors themselves. - * - * @param Profiler|null $profiler A Profiler instance - * - * @deprecated since version 2.4, to be removed in 3.0. - */ - public function setProfiler(Profiler $profiler = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); - } - /** * {@inheritdoc} */ @@ -78,7 +61,7 @@ protected function preDispatch($eventName, Event $event) protected function postDispatch($eventName, Event $event) { switch ($eventName) { - case KernelEvents::CONTROLLER: + case KernelEvents::CONTROLLER_ARGUMENTS: $this->stopwatch->start('controller', 'section'); break; case KernelEvents::RESPONSE: diff --git a/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php b/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php index 09af6bd2..e9d01203 100644 --- a/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php +++ b/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php @@ -11,6 +11,8 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; +use Composer\Autoload\ClassLoader; +use Symfony\Component\Debug\DebugClassLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\HttpKernel\Kernel; @@ -35,12 +37,113 @@ public function __construct(Kernel $kernel) public function process(ContainerBuilder $container) { $classes = array(); + $annotatedClasses = array(); foreach ($container->getExtensions() as $extension) { if ($extension instanceof Extension) { $classes = array_merge($classes, $extension->getClassesToCompile()); + $annotatedClasses = array_merge($annotatedClasses, $extension->getAnnotatedClassesToCompile()); } } - $this->kernel->setClassCache(array_unique($container->getParameterBag()->resolveValue($classes))); + $classes = $container->getParameterBag()->resolveValue($classes); + $annotatedClasses = $container->getParameterBag()->resolveValue($annotatedClasses); + $existingClasses = $this->getClassesInComposerClassMaps(); + + $this->kernel->setClassCache($this->expandClasses($classes, $existingClasses)); + $this->kernel->setAnnotatedClassCache($this->expandClasses($annotatedClasses, $existingClasses)); + } + + /** + * Expands the given class patterns using a list of existing classes. + * + * @param array $patterns The class patterns to expand + * @param array $classes The existing classes to match against the patterns + * + * @return array A list of classes derivated from the patterns + */ + private function expandClasses(array $patterns, array $classes) + { + $expanded = array(); + + // Explicit classes declared in the patterns are returned directly + foreach ($patterns as $key => $pattern) { + if (substr($pattern, -1) !== '\\' && false === strpos($pattern, '*')) { + unset($patterns[$key]); + $expanded[] = ltrim($pattern, '\\'); + } + } + + // Match patterns with the classes list + $regexps = $this->patternsToRegexps($patterns); + + foreach ($classes as $class) { + $class = ltrim($class, '\\'); + + if ($this->matchAnyRegexps($class, $regexps)) { + $expanded[] = $class; + } + } + + return array_unique($expanded); + } + + private function getClassesInComposerClassMaps() + { + $classes = array(); + + foreach (spl_autoload_functions() as $function) { + if (!is_array($function)) { + continue; + } + + if ($function[0] instanceof DebugClassLoader) { + $function = $function[0]->getClassLoader(); + } + + if (is_array($function) && $function[0] instanceof ClassLoader) { + $classes += array_filter($function[0]->getClassMap()); + } + } + + return array_keys($classes); + } + + private function patternsToRegexps($patterns) + { + $regexps = array(); + + foreach ($patterns as $pattern) { + // Escape user input + $regex = preg_quote(ltrim($pattern, '\\')); + + // Wildcards * and ** + $regex = strtr($regex, array('\\*\\*' => '.*?', '\\*' => '[^\\\\]*?')); + + // If this class does not end by a slash, anchor the end + if (substr($regex, -1) !== '\\') { + $regex .= '$'; + } + + $regexps[] = '{^\\\\'.$regex.'}'; + } + + return $regexps; + } + + private function matchAnyRegexps($class, $regexps) + { + $blacklisted = false !== strpos($class, 'Test'); + + foreach ($regexps as $regex) { + if ($blacklisted && false === strpos($regex, 'Test')) { + continue; + } + + if (preg_match($regex, '\\'.$class)) { + return true; + } + } + + return false; } } diff --git a/vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php b/vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php deleted file mode 100644 index 4b3e218b..00000000 --- a/vendor/symfony/http-kernel/DependencyInjection/ContainerAwareHttpKernel.php +++ /dev/null @@ -1,87 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\DependencyInjection; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\HttpKernel\HttpKernel; -use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Scope; - -/** - * Adds a managed request scope. - * - * @author Fabien Potencier - * @author Johannes M. Schmitt - * - * @deprecated since version 2.7, to be removed in 3.0. - */ -class ContainerAwareHttpKernel extends HttpKernel -{ - protected $container; - - /** - * Constructor. - * - * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance - * @param ContainerInterface $container A ContainerInterface instance - * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance - * @param RequestStack $requestStack A stack for master/sub requests - * @param bool $triggerDeprecation Whether or not to trigger the deprecation warning for the ContainerAwareHttpKernel - */ - public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, $triggerDeprecation = true) - { - parent::__construct($dispatcher, $controllerResolver, $requestStack); - - if ($triggerDeprecation) { - @trigger_error('The '.__CLASS__.' class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpKernel class instead.', E_USER_DEPRECATED); - } - - $this->container = $container; - - // the request scope might have been created before (see FrameworkBundle) - if (!$container->hasScope('request')) { - $container->addScope(new Scope('request')); - } - } - - /** - * {@inheritdoc} - */ - public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) - { - $this->container->enterScope('request'); - $this->container->set('request', $request, 'request'); - - try { - $response = parent::handle($request, $type, $catch); - } catch (\Exception $e) { - $this->container->set('request', null, 'request'); - $this->container->leaveScope('request'); - - throw $e; - } catch (\Throwable $e) { - $this->container->set('request', null, 'request'); - $this->container->leaveScope('request'); - - throw $e; - } - - $this->container->set('request', null, 'request'); - $this->container->leaveScope('request'); - - return $response; - } -} diff --git a/vendor/symfony/http-kernel/DependencyInjection/Extension.php b/vendor/symfony/http-kernel/DependencyInjection/Extension.php index 2ca0f132..a71bed04 100644 --- a/vendor/symfony/http-kernel/DependencyInjection/Extension.php +++ b/vendor/symfony/http-kernel/DependencyInjection/Extension.php @@ -21,6 +21,7 @@ abstract class Extension extends BaseExtension { private $classes = array(); + private $annotatedClasses = array(); /** * Gets the classes to cache. @@ -32,13 +33,33 @@ public function getClassesToCompile() return $this->classes; } + /** + * Gets the annotated classes to cache. + * + * @return array An array of classes + */ + public function getAnnotatedClassesToCompile() + { + return $this->annotatedClasses; + } + /** * Adds classes to the class cache. * - * @param array $classes An array of classes + * @param array $classes An array of class patterns */ public function addClassesToCompile(array $classes) { $this->classes = array_merge($this->classes, $classes); } + + /** + * Adds annotated classes to the class cache. + * + * @param array $annotatedClasses An array of class patterns + */ + public function addAnnotatedClassesToCompile(array $annotatedClasses) + { + $this->annotatedClasses = array_merge($this->annotatedClasses, $annotatedClasses); + } } diff --git a/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php b/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php index 0c4cecef..95cc3882 100644 --- a/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php +++ b/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php @@ -12,8 +12,8 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; /** * Adds services tagged kernel.fragment_renderer as HTTP content rendering strategies. @@ -45,11 +45,11 @@ public function process(ContainerBuilder $container) foreach ($container->findTaggedServiceIds($this->rendererTag) as $id => $tags) { $def = $container->getDefinition($id); if (!$def->isPublic()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must be public as fragment renderer are lazy-loaded.', $id)); + throw new InvalidArgumentException(sprintf('The service "%s" must be public as fragment renderer are lazy-loaded.', $id)); } if ($def->isAbstract()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as fragment renderer are lazy-loaded.', $id)); + throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as fragment renderer are lazy-loaded.', $id)); } $class = $container->getParameterBag()->resolveValue($def->getClass()); @@ -57,21 +57,14 @@ public function process(ContainerBuilder $container) if (!is_subclass_of($class, $interface)) { if (!class_exists($class, false)) { - throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } - throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); } foreach ($tags as $tag) { - if (!isset($tag['alias'])) { - @trigger_error(sprintf('Service "%s" will have to define the "alias" attribute on the "%s" tag as of Symfony 3.0.', $id, $this->rendererTag), E_USER_DEPRECATED); - - // register the handler as a non-lazy-loaded one - $definition->addMethodCall('addRenderer', array(new Reference($id))); - } else { - $definition->addMethodCall('addRendererService', array($tag['alias'], $id)); - } + $definition->addMethodCall('addRendererService', array($tag['alias'], $id)); } } } diff --git a/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php b/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php index 1d1e979d..3559e39e 100644 --- a/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php +++ b/vendor/symfony/http-kernel/DependencyInjection/LazyLoadingFragmentHandler.php @@ -28,26 +28,14 @@ class LazyLoadingFragmentHandler extends FragmentHandler /** * Constructor. * - * RequestStack will become required in 3.0. - * * @param ContainerInterface $container A container * @param RequestStack $requestStack The Request stack that controls the lifecycle of requests * @param bool $debug Whether the debug mode is enabled or not */ - public function __construct(ContainerInterface $container, $requestStack = null, $debug = false) + public function __construct(ContainerInterface $container, RequestStack $requestStack, $debug = false) { $this->container = $container; - if ((null !== $requestStack && !$requestStack instanceof RequestStack) || $debug instanceof RequestStack) { - $tmp = $debug; - $debug = $requestStack; - $requestStack = func_num_args() < 3 ? null : $tmp; - - @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } elseif (!$requestStack instanceof RequestStack) { - @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } - parent::__construct($requestStack, array(), $debug); } diff --git a/vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php b/vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php deleted file mode 100644 index f1c22473..00000000 --- a/vendor/symfony/http-kernel/DependencyInjection/RegisterListenersPass.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\DependencyInjection; - -@trigger_error('The '.__NAMESPACE__.'\RegisterListenersPass is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass class instead.', E_USER_DEPRECATED); - -use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass as BaseRegisterListenersPass; - -/** - * Compiler pass to register tagged services for an event dispatcher. - * - * @deprecated since version 2.5, to be removed in 3.0. Use the Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass class instead. - */ -class RegisterListenersPass extends BaseRegisterListenersPass -{ -} diff --git a/vendor/symfony/http-kernel/Event/FilterControllerArgumentsEvent.php b/vendor/symfony/http-kernel/Event/FilterControllerArgumentsEvent.php new file mode 100644 index 00000000..1dc784ed --- /dev/null +++ b/vendor/symfony/http-kernel/Event/FilterControllerArgumentsEvent.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\Event; + +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Allows filtering of controller arguments. + * + * You can call getController() to retrieve the controller and getArguments + * to retrieve the current arguments. With setArguments() you can replace + * arguments that are used to call the controller. + * + * Arguments set in the event must be compatible with the signature of the + * controller. + * + * @author Christophe Coevoet + */ +class FilterControllerArgumentsEvent extends FilterControllerEvent +{ + private $arguments; + + public function __construct(HttpKernelInterface $kernel, callable $controller, array $arguments, Request $request, $requestType) + { + parent::__construct($kernel, $controller, $request, $requestType); + + $this->arguments = $arguments; + } + + /** + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * @param array $arguments + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + } +} diff --git a/vendor/symfony/http-kernel/Event/FilterControllerEvent.php b/vendor/symfony/http-kernel/Event/FilterControllerEvent.php index 77a5c1a2..e0d46aa4 100644 --- a/vendor/symfony/http-kernel/Event/FilterControllerEvent.php +++ b/vendor/symfony/http-kernel/Event/FilterControllerEvent.php @@ -32,7 +32,7 @@ class FilterControllerEvent extends KernelEvent */ private $controller; - public function __construct(HttpKernelInterface $kernel, $controller, Request $request, $requestType) + public function __construct(HttpKernelInterface $kernel, callable $controller, Request $request, $requestType) { parent::__construct($kernel, $request, $requestType); @@ -53,50 +53,9 @@ public function getController() * Sets a new controller. * * @param callable $controller - * - * @throws \LogicException */ - public function setController($controller) + public function setController(callable $controller) { - // controller must be a callable - if (!is_callable($controller)) { - throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller))); - } - $this->controller = $controller; } - - private function varToString($var) - { - if (is_object($var)) { - return sprintf('Object(%s)', get_class($var)); - } - - if (is_array($var)) { - $a = array(); - foreach ($var as $k => $v) { - $a[] = sprintf('%s => %s', $k, $this->varToString($v)); - } - - return sprintf('Array(%s)', implode(', ', $a)); - } - - if (is_resource($var)) { - return sprintf('Resource(%s)', get_resource_type($var)); - } - - if (null === $var) { - return 'null'; - } - - if (false === $var) { - return 'false'; - } - - if (true === $var) { - return 'true'; - } - - return (string) $var; - } } diff --git a/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php b/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php index 14a5d435..280844c1 100644 --- a/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php +++ b/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php @@ -52,6 +52,6 @@ public function onKernelRequest(GetResponseEvent $event) */ public static function getSubscribedEvents() { - return array(KernelEvents::REQUEST => 'onKernelRequest'); + return array(KernelEvents::REQUEST => array('onKernelRequest', 1)); } } diff --git a/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php b/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php index 2f523a54..29e1725a 100644 --- a/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php +++ b/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php @@ -35,6 +35,7 @@ class DebugHandlersListener implements EventSubscriberInterface private $throwAt; private $scream; private $fileLinkFormat; + private $scope; private $firstCall = true; /** @@ -43,16 +44,18 @@ class DebugHandlersListener implements EventSubscriberInterface * @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants * @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value * @param bool $scream Enables/disables screaming mode, where even silenced errors are logged - * @param string $fileLinkFormat The format for links to source files + * @param string|array $fileLinkFormat The format for links to source files + * @param bool $scope Enables/disables scoping mode */ - public function __construct($exceptionHandler, LoggerInterface $logger = null, $levels = null, $throwAt = -1, $scream = true, $fileLinkFormat = null) + public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, $throwAt = E_ALL, $scream = true, $fileLinkFormat = null, $scope = true) { $this->exceptionHandler = $exceptionHandler; $this->logger = $logger; - $this->levels = $levels; - $this->throwAt = is_numeric($throwAt) ? (int) $throwAt : (null === $throwAt ? null : ($throwAt ? -1 : null)); + $this->levels = null === $levels ? E_ALL : $levels; + $this->throwAt = is_numeric($throwAt) ? (int) $throwAt : (null === $throwAt ? null : ($throwAt ? E_ALL : null)); $this->scream = (bool) $scream; - $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + $this->fileLinkFormat = $fileLinkFormat; + $this->scope = (bool) $scope; } /** @@ -74,15 +77,20 @@ public function configure(Event $event = null) if ($this->logger) { $handler->setDefaultLogger($this->logger, $this->levels); if (is_array($this->levels)) { - $scream = 0; + $levels = 0; foreach ($this->levels as $type => $log) { - $scream |= $type; + $levels |= $type; } } else { - $scream = null === $this->levels ? E_ALL | E_STRICT : $this->levels; + $levels = $this->levels; } if ($this->scream) { - $handler->screamAt($scream); + $handler->screamAt($levels); + } + if ($this->scope) { + $handler->scopeAt($this->levels); + } else { + $handler->scopeAt(0, true); } $this->logger = $this->levels = null; } @@ -129,7 +137,7 @@ public static function getSubscribedEvents() { $events = array(KernelEvents::REQUEST => array('configure', 2048)); - if (defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) { + if ('cli' === PHP_SAPI && defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) { $events[ConsoleEvents::COMMAND] = array('configure', 2048); } diff --git a/vendor/symfony/http-kernel/EventListener/DumpListener.php b/vendor/symfony/http-kernel/EventListener/DumpListener.php index 06b8a030..88acef31 100644 --- a/vendor/symfony/http-kernel/EventListener/DumpListener.php +++ b/vendor/symfony/http-kernel/EventListener/DumpListener.php @@ -49,6 +49,10 @@ public function configure() public static function getSubscribedEvents() { + if (!class_exists(ConsoleEvents::class)) { + return array(); + } + // Register early to have a working dump() as early as possible return array(ConsoleEvents::COMMAND => array('configure', 1024)); } diff --git a/vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php b/vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php deleted file mode 100644 index 80c3fe59..00000000 --- a/vendor/symfony/http-kernel/EventListener/ErrorsLoggerListener.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\EventListener; - -@trigger_error('The '.__NAMESPACE__.'\ErrorsLoggerListener class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\EventListener\DebugHandlersListener class instead.', E_USER_DEPRECATED); - -use Psr\Log\LoggerInterface; -use Symfony\Component\Debug\ErrorHandler; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpKernel\KernelEvents; - -/** - * Injects the logger into the ErrorHandler, so that it can log various errors. - * - * @author Colin Frei - * @author Konstantin Myakshin - * - * @deprecated since version 2.6, to be removed in 3.0. Use the DebugHandlersListener class instead. - */ -class ErrorsLoggerListener implements EventSubscriberInterface -{ - private $channel; - private $logger; - - public function __construct($channel, LoggerInterface $logger = null) - { - $this->channel = $channel; - $this->logger = $logger; - } - - public function injectLogger() - { - if (null !== $this->logger) { - ErrorHandler::setLogger($this->logger, $this->channel); - $this->logger = null; - } - } - - public static function getSubscribedEvents() - { - return array(KernelEvents::REQUEST => array('injectLogger', 2048)); - } -} diff --git a/vendor/symfony/http-kernel/EventListener/EsiListener.php b/vendor/symfony/http-kernel/EventListener/EsiListener.php deleted file mode 100644 index bceb6726..00000000 --- a/vendor/symfony/http-kernel/EventListener/EsiListener.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\EventListener; - -@trigger_error('The '.__NAMESPACE__.'\EsiListener class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\EventListener\SurrogateListener class instead.', E_USER_DEPRECATED); - -/** - * EsiListener adds a Surrogate-Control HTTP header when the Response needs to be parsed for ESI. - * - * @author Fabien Potencier - * - * @deprecated since version 2.6, to be removed in 3.0. Use SurrogateListener instead - */ -class EsiListener extends SurrogateListener -{ -} diff --git a/vendor/symfony/http-kernel/EventListener/ExceptionListener.php b/vendor/symfony/http-kernel/EventListener/ExceptionListener.php index 1c50ef4a..cf3a2f0a 100644 --- a/vendor/symfony/http-kernel/EventListener/ExceptionListener.php +++ b/vendor/symfony/http-kernel/EventListener/ExceptionListener.php @@ -107,10 +107,6 @@ protected function duplicateRequest(\Exception $exception, Request $request) '_controller' => $this->controller, 'exception' => FlattenException::create($exception), 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, - // keep for BC -- as $format can be an argument of the controller callable - // see src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php - // @deprecated since version 2.4, to be removed in 3.0 - 'format' => $request->getRequestFormat(), ); $request = $request->duplicate(null, null, $attributes); $request->setMethod('GET'); diff --git a/vendor/symfony/http-kernel/EventListener/FragmentListener.php b/vendor/symfony/http-kernel/EventListener/FragmentListener.php index ad634928..37bf15c3 100644 --- a/vendor/symfony/http-kernel/EventListener/FragmentListener.php +++ b/vendor/symfony/http-kernel/EventListener/FragmentListener.php @@ -94,18 +94,6 @@ protected function validateRequest(Request $request) throw new AccessDeniedHttpException(); } - /** - * @deprecated since version 2.3.19, to be removed in 3.0. - * - * @return string[] - */ - protected function getLocalIpAddresses() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3.19 and will be removed in 3.0.', E_USER_DEPRECATED); - - return array('127.0.0.1', 'fe80::1', '::1'); - } - public static function getSubscribedEvents() { return array( diff --git a/vendor/symfony/http-kernel/EventListener/LocaleListener.php b/vendor/symfony/http-kernel/EventListener/LocaleListener.php index 0ff3a863..99fc7867 100644 --- a/vendor/symfony/http-kernel/EventListener/LocaleListener.php +++ b/vendor/symfony/http-kernel/EventListener/LocaleListener.php @@ -22,11 +22,6 @@ /** * Initializes the locale based on the current request. * - * This listener works in 2 modes: - * - * * 2.3 compatibility mode where you must call setRequest whenever the Request changes. - * * 2.4+ mode where you must pass a RequestStack instance in the constructor. - * * @author Fabien Potencier */ class LocaleListener implements EventSubscriberInterface @@ -38,62 +33,17 @@ class LocaleListener implements EventSubscriberInterface /** * Constructor. * - * RequestStack will become required in 3.0. - * * @param RequestStack $requestStack A RequestStack instance * @param string $defaultLocale The default locale * @param RequestContextAwareInterface|null $router The router - * - * @throws \InvalidArgumentException */ - public function __construct($requestStack = null, $defaultLocale = 'en', $router = null) + public function __construct(RequestStack $requestStack, $defaultLocale = 'en', RequestContextAwareInterface $router = null) { - if ((null !== $requestStack && !$requestStack instanceof RequestStack) || $defaultLocale instanceof RequestContextAwareInterface || $router instanceof RequestStack) { - $tmp = $router; - $router = func_num_args() < 2 ? null : $defaultLocale; - $defaultLocale = $requestStack; - $requestStack = func_num_args() < 3 ? null : $tmp; - - @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as first argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } elseif (!$requestStack instanceof RequestStack) { - @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } - - if (null !== $requestStack && !$requestStack instanceof RequestStack) { - throw new \InvalidArgumentException('RequestStack instance expected.'); - } - if (null !== $router && !$router instanceof RequestContextAwareInterface) { - throw new \InvalidArgumentException('Router must implement RequestContextAwareInterface.'); - } - $this->defaultLocale = $defaultLocale; $this->requestStack = $requestStack; $this->router = $router; } - /** - * Sets the current Request. - * - * This method was used to synchronize the Request, but as the HttpKernel - * is doing that automatically now, you should never call it directly. - * It is kept public for BC with the 2.3 version. - * - * @param Request|null $request A Request instance - * - * @deprecated since version 2.4, to be removed in 3.0. - */ - public function setRequest(Request $request = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); - - if (null === $request) { - return; - } - - $this->setLocale($request); - $this->setRouterContext($request); - } - public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); @@ -105,10 +55,6 @@ public function onKernelRequest(GetResponseEvent $event) public function onKernelFinishRequest(FinishRequestEvent $event) { - if (null === $this->requestStack) { - return; // removed when requestStack is required - } - if (null !== $parentRequest = $this->requestStack->getParentRequest()) { $this->setRouterContext($parentRequest); } diff --git a/vendor/symfony/http-kernel/EventListener/ProfilerListener.php b/vendor/symfony/http-kernel/EventListener/ProfilerListener.php index f73f3252..c3772b68 100644 --- a/vendor/symfony/http-kernel/EventListener/ProfilerListener.php +++ b/vendor/symfony/http-kernel/EventListener/ProfilerListener.php @@ -11,7 +11,6 @@ namespace Symfony\Component\HttpKernel\EventListener; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\PostResponseEvent; @@ -33,7 +32,6 @@ class ProfilerListener implements EventSubscriberInterface protected $onlyException; protected $onlyMasterRequests; protected $exception; - protected $requests = array(); protected $profiles; protected $requestStack; protected $parents; @@ -47,27 +45,8 @@ class ProfilerListener implements EventSubscriberInterface * @param bool $onlyException true if the profiler only collects data when an exception occurs, false otherwise * @param bool $onlyMasterRequests true if the profiler only collects data when the request is a master request, false otherwise */ - public function __construct(Profiler $profiler, $requestStack = null, $matcher = null, $onlyException = false, $onlyMasterRequests = false) + public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false) { - if ($requestStack instanceof RequestMatcherInterface || (null !== $matcher && !$matcher instanceof RequestMatcherInterface) || $onlyMasterRequests instanceof RequestStack) { - $tmp = $onlyMasterRequests; - $onlyMasterRequests = $onlyException; - $onlyException = $matcher; - $matcher = $requestStack; - $requestStack = func_num_args() < 5 ? null : $tmp; - - @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::onKernelRequest method will be removed in 3.0.', E_USER_DEPRECATED); - } elseif (!$requestStack instanceof RequestStack) { - @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::onKernelRequest method will be removed in 3.0.', E_USER_DEPRECATED); - } - - if (null !== $requestStack && !$requestStack instanceof RequestStack) { - throw new \InvalidArgumentException('RequestStack instance expected.'); - } - if (null !== $matcher && !$matcher instanceof RequestMatcherInterface) { - throw new \InvalidArgumentException('Matcher must implement RequestMatcherInterface.'); - } - $this->profiler = $profiler; $this->matcher = $matcher; $this->onlyException = (bool) $onlyException; @@ -91,16 +70,6 @@ public function onKernelException(GetResponseForExceptionEvent $event) $this->exception = $event->getException(); } - /** - * @deprecated since version 2.4, to be removed in 3.0. - */ - public function onKernelRequest(GetResponseEvent $event) - { - if (null === $this->requestStack) { - $this->requests[] = $event->getRequest(); - } - } - /** * Handles the onKernelResponse event. * @@ -131,14 +100,7 @@ public function onKernelResponse(FilterResponseEvent $event) $this->profiles[$request] = $profile; - if (null !== $this->requestStack) { - $this->parents[$request] = $this->requestStack->getParentRequest(); - } elseif (!$master) { - // to be removed when requestStack is required - array_pop($this->requests); - - $this->parents[$request] = end($this->requests); - } + $this->parents[$request] = $this->requestStack->getParentRequest(); } public function onKernelTerminate(PostResponseEvent $event) @@ -160,15 +122,11 @@ public function onKernelTerminate(PostResponseEvent $event) $this->profiles = new \SplObjectStorage(); $this->parents = new \SplObjectStorage(); - $this->requests = array(); } public static function getSubscribedEvents() { return array( - // kernel.request must be registered as early as possible to not break - // when an exception is thrown in any other kernel.request listener - KernelEvents::REQUEST => array('onKernelRequest', 1024), KernelEvents::RESPONSE => array('onKernelResponse', -100), KernelEvents::EXCEPTION => 'onKernelException', KernelEvents::TERMINATE => array('onKernelTerminate', -1024), diff --git a/vendor/symfony/http-kernel/EventListener/RouterListener.php b/vendor/symfony/http-kernel/EventListener/RouterListener.php index 761e5913..3c46be86 100644 --- a/vendor/symfony/http-kernel/EventListener/RouterListener.php +++ b/vendor/symfony/http-kernel/EventListener/RouterListener.php @@ -30,11 +30,6 @@ /** * Initializes the context from the request and sets request attributes based on a matching route. * - * This listener works in 2 modes: - * - * * 2.3 compatibility mode where you must call setRequest whenever the Request changes. - * * 2.4+ mode where you must pass a RequestStack instance in the constructor. - * * @author Fabien Potencier */ class RouterListener implements EventSubscriberInterface @@ -42,14 +37,11 @@ class RouterListener implements EventSubscriberInterface private $matcher; private $context; private $logger; - private $request; private $requestStack; /** * Constructor. * - * RequestStack will become required in 3.0. - * * @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher * @param RequestStack $requestStack A RequestStack instance * @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface) @@ -57,29 +49,8 @@ class RouterListener implements EventSubscriberInterface * * @throws \InvalidArgumentException */ - public function __construct($matcher, $requestStack = null, $context = null, $logger = null) + public function __construct($matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null) { - if ($requestStack instanceof RequestContext || $context instanceof LoggerInterface || $logger instanceof RequestStack) { - $tmp = $requestStack; - $requestStack = $logger; - $logger = $context; - $context = $tmp; - - @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } elseif (!$requestStack instanceof RequestStack) { - @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } - - if (null !== $requestStack && !$requestStack instanceof RequestStack) { - throw new \InvalidArgumentException('RequestStack instance expected.'); - } - if (null !== $context && !$context instanceof RequestContext) { - throw new \InvalidArgumentException('RequestContext instance expected.'); - } - if (null !== $logger && !$logger instanceof LoggerInterface) { - throw new \InvalidArgumentException('Logger must implement LoggerInterface.'); - } - if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) { throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.'); } @@ -94,39 +65,21 @@ public function __construct($matcher, $requestStack = null, $context = null, $lo $this->logger = $logger; } - /** - * Sets the current Request. - * - * This method was used to synchronize the Request, but as the HttpKernel - * is doing that automatically now, you should never call it directly. - * It is kept public for BC with the 2.3 version. - * - * @param Request|null $request A Request instance - * - * @deprecated since version 2.4, to be removed in 3.0. - */ - public function setRequest(Request $request = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be made private in 3.0.', E_USER_DEPRECATED); - - $this->setCurrentRequest($request); - } - private function setCurrentRequest(Request $request = null) { - if (null !== $request && $this->request !== $request) { + if (null !== $request) { $this->context->fromRequest($request); } - - $this->request = $request; } + /** + * After a sub-request is done, we need to reset the routing context to the parent request so that the URL generator + * operates on the correct context again. + * + * @param FinishRequestEvent $event + */ public function onKernelFinishRequest(FinishRequestEvent $event) { - if (null === $this->requestStack) { - return; // removed when requestStack is required - } - $this->setCurrentRequest($this->requestStack->getParentRequest()); } @@ -134,13 +87,7 @@ public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); - // initialize the context that is also used by the generator (assuming matcher and generator share the same context instance) - // we call setCurrentRequest even if most of the time, it has already been done to keep compatibility - // with frameworks which do not use the Symfony service container - // when we have a RequestStack, no need to do it - if (null !== $this->requestStack) { - $this->setCurrentRequest($request); - } + $this->setCurrentRequest($request); if ($request->attributes->has('_controller')) { // routing is already done @@ -157,9 +104,11 @@ public function onKernelRequest(GetResponseEvent $event) } if (null !== $this->logger) { - $this->logger->info(sprintf('Matched route "%s".', isset($parameters['_route']) ? $parameters['_route'] : 'n/a'), array( + $this->logger->info('Matched route "{route}".', array( + 'route' => isset($parameters['_route']) ? $parameters['_route'] : 'n/a', 'route_parameters' => $parameters, 'request_uri' => $request->getUri(), + 'method' => $request->getMethod(), )); } diff --git a/vendor/symfony/http-kernel/EventListener/SessionListener.php b/vendor/symfony/http-kernel/EventListener/SessionListener.php index ecf065f0..2d6adfa0 100644 --- a/vendor/symfony/http-kernel/EventListener/SessionListener.php +++ b/vendor/symfony/http-kernel/EventListener/SessionListener.php @@ -11,6 +11,7 @@ namespace Symfony\Component\HttpKernel\EventListener; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; diff --git a/vendor/symfony/http-kernel/EventListener/TestSessionListener.php b/vendor/symfony/http-kernel/EventListener/TestSessionListener.php index 8fc8e575..19a61f16 100644 --- a/vendor/symfony/http-kernel/EventListener/TestSessionListener.php +++ b/vendor/symfony/http-kernel/EventListener/TestSessionListener.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpKernel\EventListener; use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; diff --git a/vendor/symfony/http-kernel/Exception/FatalErrorException.php b/vendor/symfony/http-kernel/Exception/FatalErrorException.php deleted file mode 100644 index 0d2b4f92..00000000 --- a/vendor/symfony/http-kernel/Exception/FatalErrorException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Exception; - -@trigger_error('The '.__NAMESPACE__.'\FatalErrorException class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\Exception\FatalErrorException class instead.', E_USER_DEPRECATED); - -/* - * Fatal Error Exception. - * - * @author Konstanton Myakshin - * - * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. - */ -class_exists('Symfony\Component\Debug\Exception\FatalErrorException'); diff --git a/vendor/symfony/http-kernel/Exception/FlattenException.php b/vendor/symfony/http-kernel/Exception/FlattenException.php deleted file mode 100644 index 599aa959..00000000 --- a/vendor/symfony/http-kernel/Exception/FlattenException.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Exception; - -@trigger_error('The '.__NAMESPACE__.'\FlattenException class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Debug\Exception\FlattenException class instead.', E_USER_DEPRECATED); - -/* - * FlattenException wraps a PHP Exception to be able to serialize it. - * - * Basically, this class removes all objects from the trace. - * - * @author Fabien Potencier - * - * @deprecated since version 2.3, to be removed in 3.0. Use the same class from the Debug component instead. - */ -class_exists('Symfony\Component\Debug\Exception\FlattenException'); diff --git a/vendor/symfony/http-kernel/Exception/HttpException.php b/vendor/symfony/http-kernel/Exception/HttpException.php index 4e1b5263..e8e37605 100644 --- a/vendor/symfony/http-kernel/Exception/HttpException.php +++ b/vendor/symfony/http-kernel/Exception/HttpException.php @@ -38,4 +38,14 @@ public function getHeaders() { return $this->headers; } + + /** + * Set response headers. + * + * @param array $headers Response headers + */ + public function setHeaders(array $headers) + { + $this->headers = $headers; + } } diff --git a/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php b/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php index 1968001a..0d4d26b6 100644 --- a/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php +++ b/vendor/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php @@ -64,6 +64,10 @@ public function __construct(SurrogateInterface $surrogate = null, FragmentRender public function render($uri, Request $request, array $options = array()) { if (!$this->surrogate || !$this->surrogate->hasSurrogateCapability($request)) { + if ($uri instanceof ControllerReference && $this->containsNonScalars($uri->attributes)) { + @trigger_error('Passing non-scalar values as part of URI attributes to the ESI and SSI rendering strategies is deprecated since version 3.1, and will be removed in 4.0. Use a different rendering strategy or pass scalar values.', E_USER_DEPRECATED); + } + return $this->inlineStrategy->render($uri, $request, $options); } @@ -92,4 +96,17 @@ private function generateSignedFragmentUri($uri, Request $request) return substr($fragmentUri, strlen($request->getSchemeAndHttpHost())); } + + private function containsNonScalars(array $values) + { + foreach ($values as $value) { + if (is_array($value) && $this->containsNonScalars($value)) { + return true; + } elseif (!is_scalar($value) && null !== $value) { + return true; + } + } + + return false; + } } diff --git a/vendor/symfony/http-kernel/Fragment/FragmentHandler.php b/vendor/symfony/http-kernel/Fragment/FragmentHandler.php index dff3773d..0d0a0424 100644 --- a/vendor/symfony/http-kernel/Fragment/FragmentHandler.php +++ b/vendor/symfony/http-kernel/Fragment/FragmentHandler.php @@ -11,7 +11,6 @@ namespace Symfony\Component\HttpKernel\Fragment; -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\RequestStack; @@ -23,11 +22,6 @@ * This class handles the rendering of resource fragments that are included into * a main resource. The handling of the rendering is managed by specialized renderers. * - * This listener works in 2 modes: - * - * * 2.3 compatibility mode where you must call setRequest whenever the Request changes. - * * 2.4+ mode where you must pass a RequestStack instance in the constructor. - * * @author Fabien Potencier * * @see FragmentRendererInterface @@ -36,38 +30,17 @@ class FragmentHandler { private $debug; private $renderers = array(); - private $request; private $requestStack; /** * Constructor. * - * RequestStack will become required in 3.0. - * * @param RequestStack $requestStack The Request stack that controls the lifecycle of requests * @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances * @param bool $debug Whether the debug mode is enabled or not */ - public function __construct($requestStack = null, $renderers = array(), $debug = false) + public function __construct(RequestStack $requestStack, array $renderers = array(), $debug = false) { - if (is_array($requestStack)) { - $tmp = $debug; - $debug = func_num_args() < 2 ? false : $renderers; - $renderers = $requestStack; - $requestStack = func_num_args() < 3 ? null : $tmp; - - @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as first argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } elseif (!$requestStack instanceof RequestStack) { - @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED); - } - - if (null !== $requestStack && !$requestStack instanceof RequestStack) { - throw new \InvalidArgumentException('RequestStack instance expected.'); - } - if (!is_array($renderers)) { - throw new \InvalidArgumentException('Renderers must be an array.'); - } - $this->requestStack = $requestStack; foreach ($renderers as $renderer) { $this->addRenderer($renderer); @@ -85,24 +58,6 @@ public function addRenderer(FragmentRendererInterface $renderer) $this->renderers[$renderer->getName()] = $renderer; } - /** - * Sets the current Request. - * - * This method was used to synchronize the Request, but as the HttpKernel - * is doing that automatically now, you should never call it directly. - * It is kept public for BC with the 2.3 version. - * - * @param Request|null $request A Request instance - * - * @deprecated since version 2.4, to be removed in 3.0. - */ - public function setRequest(Request $request = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED); - - $this->request = $request; - } - /** * Renders a URI and returns the Response content. * @@ -129,7 +84,7 @@ public function render($uri, $renderer = 'inline', array $options = array()) throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer)); } - if (!$request = $this->getRequest()) { + if (!$request = $this->requestStack->getCurrentRequest()) { throw new \LogicException('Rendering a fragment can only be done when handling a Request.'); } @@ -151,7 +106,7 @@ public function render($uri, $renderer = 'inline', array $options = array()) protected function deliver(Response $response) { if (!$response->isSuccessful()) { - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->getRequest()->getUri(), $response->getStatusCode())); + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->requestStack->getCurrentRequest()->getUri(), $response->getStatusCode())); } if (!$response instanceof StreamedResponse) { @@ -160,9 +115,4 @@ protected function deliver(Response $response) $response->sendContent(); } - - private function getRequest() - { - return $this->requestStack ? $this->requestStack->getCurrentRequest() : $this->request; - } } diff --git a/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php b/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php index 27051cfb..c163a090 100644 --- a/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php +++ b/vendor/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php @@ -107,11 +107,7 @@ public function render($uri, Request $request, array $options = array()) } $renderedAttributes = ''; if (count($attributes) > 0) { - if (PHP_VERSION_ID >= 50400) { - $flags = ENT_QUOTES | ENT_SUBSTITUTE; - } else { - $flags = ENT_QUOTES; - } + $flags = ENT_QUOTES | ENT_SUBSTITUTE; foreach ($attributes as $attribute => $value) { $renderedAttributes .= sprintf( ' %s="%s"', diff --git a/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php b/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php new file mode 100644 index 00000000..af94bea9 --- /dev/null +++ b/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\HttpCache; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * Abstract class implementing Surrogate capabilities to Request and Response instances. + * + * @author Fabien Potencier + * @author Robin Chalas + */ +abstract class AbstractSurrogate implements SurrogateInterface +{ + protected $contentTypes; + protected $phpEscapeMap = array( + array('', '', '', ''), + ); + + /** + * Constructor. + * + * @param array $contentTypes An array of content-type that should be parsed for Surrogate information + * (default: text/html, text/xml, application/xhtml+xml, and application/xml) + */ + public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml')) + { + $this->contentTypes = $contentTypes; + } + + /** + * Returns a new cache strategy instance. + * + * @return ResponseCacheStrategyInterface A ResponseCacheStrategyInterface instance + */ + public function createCacheStrategy() + { + return new ResponseCacheStrategy(); + } + + /** + * {@inheritdoc} + */ + public function hasSurrogateCapability(Request $request) + { + if (null === $value = $request->headers->get('Surrogate-Capability')) { + return false; + } + + return false !== strpos($value, sprintf('%s/1.0', strtoupper($this->getName()))); + } + + /** + * {@inheritdoc} + */ + public function addSurrogateCapability(Request $request) + { + $current = $request->headers->get('Surrogate-Capability'); + $new = sprintf('symfony="%s/1.0"', strtoupper($this->getName())); + + $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); + } + + /** + * {@inheritdoc} + */ + public function needsParsing(Response $response) + { + if (!$control = $response->headers->get('Surrogate-Control')) { + return false; + } + + $pattern = sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName())); + + return (bool) preg_match($pattern, $control); + } + + /** + * {@inheritdoc} + */ + public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) + { + $subRequest = Request::create($uri, Request::METHOD_GET, array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); + + try { + $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); + + if (!$response->isSuccessful()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); + } + + return $response->getContent(); + } catch (\Exception $e) { + if ($alt) { + return $this->handle($cache, $alt, '', $ignoreErrors); + } + + if (!$ignoreErrors) { + throw $e; + } + } + } + + /** + * Remove the Surrogate from the Surrogate-Control header. + * + * @param Response $response + */ + protected function removeFromControl(Response $response) + { + if (!$response->headers->has('Surrogate-Control')) { + return; + } + + $value = $response->headers->get('Surrogate-Control'); + $upperName = strtoupper($this->getName()); + + if (sprintf('content="%s/1.0"', $upperName) == $value) { + $response->headers->remove('Surrogate-Control'); + } elseif (preg_match(sprintf('#,\s*content="%s/1.0"#', $upperName), $value)) { + $response->headers->set('Surrogate-Control', preg_replace(sprintf('#,\s*content="%s/1.0"#', $upperName), '', $value)); + } elseif (preg_match(sprintf('#content="%s/1.0",\s*#', $upperName), $value)) { + $response->headers->set('Surrogate-Control', preg_replace(sprintf('#content="%s/1.0",\s*#', $upperName), '', $value)); + } + } +} diff --git a/vendor/symfony/http-kernel/HttpCache/Esi.php b/vendor/symfony/http-kernel/HttpCache/Esi.php index 45779395..d09907ea 100644 --- a/vendor/symfony/http-kernel/HttpCache/Esi.php +++ b/vendor/symfony/http-kernel/HttpCache/Esi.php @@ -13,7 +13,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Esi implements the ESI capabilities to Request and Response instances. @@ -26,105 +25,15 @@ * * @author Fabien Potencier */ -class Esi implements SurrogateInterface +class Esi extends AbstractSurrogate { - private $contentTypes; - private $phpEscapeMap = array( - array('', '', '', ''), - ); - - /** - * Constructor. - * - * @param array $contentTypes An array of content-type that should be parsed for ESI information - * (default: text/html, text/xml, application/xhtml+xml, and application/xml) - */ - public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml')) - { - $this->contentTypes = $contentTypes; - } - public function getName() { return 'esi'; } /** - * Returns a new cache strategy instance. - * - * @return ResponseCacheStrategyInterface A ResponseCacheStrategyInterface instance - */ - public function createCacheStrategy() - { - return new ResponseCacheStrategy(); - } - - /** - * Checks that at least one surrogate has ESI/1.0 capability. - * - * @param Request $request A Request instance - * - * @return bool true if one surrogate has ESI/1.0 capability, false otherwise - */ - public function hasSurrogateCapability(Request $request) - { - if (null === $value = $request->headers->get('Surrogate-Capability')) { - return false; - } - - return false !== strpos($value, 'ESI/1.0'); - } - - /** - * Checks that at least one surrogate has ESI/1.0 capability. - * - * @param Request $request A Request instance - * - * @return bool true if one surrogate has ESI/1.0 capability, false otherwise - * - * @deprecated since version 2.6, to be removed in 3.0. Use hasSurrogateCapability() instead - */ - public function hasSurrogateEsiCapability(Request $request) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the hasSurrogateCapability() method instead.', E_USER_DEPRECATED); - - return $this->hasSurrogateCapability($request); - } - - /** - * Adds ESI/1.0 capability to the given Request. - * - * @param Request $request A Request instance - */ - public function addSurrogateCapability(Request $request) - { - $current = $request->headers->get('Surrogate-Capability'); - $new = 'symfony2="ESI/1.0"'; - - $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); - } - - /** - * Adds ESI/1.0 capability to the given Request. - * - * @param Request $request A Request instance - * - * @deprecated since version 2.6, to be removed in 3.0. Use addSurrogateCapability() instead - */ - public function addSurrogateEsiCapability(Request $request) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the addSurrogateCapability() method instead.', E_USER_DEPRECATED); - - $this->addSurrogateCapability($request); - } - - /** - * Adds HTTP headers to specify that the Response needs to be parsed for ESI. - * - * This method only adds an ESI HTTP header if the Response has some ESI tags. - * - * @param Response $response A Response instance + * {@inheritdoc} */ public function addSurrogateControl(Response $response) { @@ -134,46 +43,7 @@ public function addSurrogateControl(Response $response) } /** - * Checks that the Response needs to be parsed for ESI tags. - * - * @param Response $response A Response instance - * - * @return bool true if the Response needs to be parsed, false otherwise - */ - public function needsParsing(Response $response) - { - if (!$control = $response->headers->get('Surrogate-Control')) { - return false; - } - - return (bool) preg_match('#content="[^"]*ESI/1.0[^"]*"#', $control); - } - - /** - * Checks that the Response needs to be parsed for ESI tags. - * - * @param Response $response A Response instance - * - * @return bool true if the Response needs to be parsed, false otherwise - * - * @deprecated since version 2.6, to be removed in 3.0. Use needsParsing() instead - */ - public function needsEsiParsing(Response $response) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the needsParsing() method instead.', E_USER_DEPRECATED); - - return $this->needsParsing($response); - } - - /** - * Renders an ESI tag. - * - * @param string $uri A URI - * @param string $alt An alternate URI - * @param bool $ignoreErrors Whether to ignore errors or not - * @param string $comment A comment to add as an esi:include tag - * - * @return string + * {@inheritdoc} */ public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = '') { @@ -191,12 +61,7 @@ public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comme } /** - * Replaces a Response ESI tags with the included resource content. - * - * @param Request $request A Request instance - * @param Response $response A Response instance - * - * @return Response + * {@inheritdoc} */ public function process(Request $request, Response $response) { @@ -245,51 +110,6 @@ public function process(Request $request, Response $response) $response->headers->set('X-Body-Eval', 'ESI'); // remove ESI/1.0 from the Surrogate-Control header - if ($response->headers->has('Surrogate-Control')) { - $value = $response->headers->get('Surrogate-Control'); - if ('content="ESI/1.0"' == $value) { - $response->headers->remove('Surrogate-Control'); - } elseif (preg_match('#,\s*content="ESI/1.0"#', $value)) { - $response->headers->set('Surrogate-Control', preg_replace('#,\s*content="ESI/1.0"#', '', $value)); - } elseif (preg_match('#content="ESI/1.0",\s*#', $value)) { - $response->headers->set('Surrogate-Control', preg_replace('#content="ESI/1.0",\s*#', '', $value)); - } - } - } - - /** - * Handles an ESI from the cache. - * - * @param HttpCache $cache An HttpCache instance - * @param string $uri The main URI - * @param string $alt An alternative URI - * @param bool $ignoreErrors Whether to ignore errors or not - * - * @return string - * - * @throws \RuntimeException - * @throws \Exception - */ - public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) - { - $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); - - try { - $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); - - if (!$response->isSuccessful()) { - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); - } - - return $response->getContent(); - } catch (\Exception $e) { - if ($alt) { - return $this->handle($cache, $alt, '', $ignoreErrors); - } - - if (!$ignoreErrors) { - throw $e; - } - } + $this->removeFromControl($response); } } diff --git a/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php b/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php deleted file mode 100644 index 636f60e9..00000000 --- a/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategy.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * This code is partially based on the Rack-Cache library by Ryan Tomayko, - * which is released under the MIT license. - * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\HttpCache; - -@trigger_error('The '.__NAMESPACE__.'\EsiResponseCacheStrategy class is deprecated since version 2.6 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpCache\ResponseCacheStrategy class instead.', E_USER_DEPRECATED); - -/** - * EsiResponseCacheStrategy knows how to compute the Response cache HTTP header - * based on the different ESI response cache headers. - * - * This implementation changes the master response TTL to the smallest TTL received - * or force validation if one of the ESI has validation cache strategy. - * - * @author Fabien Potencier - * - * @deprecated since version 2.6, to be removed in 3.0. Use ResponseCacheStrategy instead - */ -class EsiResponseCacheStrategy extends ResponseCacheStrategy implements EsiResponseCacheStrategyInterface -{ -} diff --git a/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php b/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php deleted file mode 100644 index 5388e99c..00000000 --- a/vendor/symfony/http-kernel/HttpCache/EsiResponseCacheStrategyInterface.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * This code is partially based on the Rack-Cache library by Ryan Tomayko, - * which is released under the MIT license. - * (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801) - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\HttpCache; - -/** - * ResponseCacheStrategyInterface implementations know how to compute the - * Response cache HTTP header based on the different response cache headers. - * - * @author Fabien Potencier - * - * @deprecated since version 2.6, to be removed in 3.0. Use ResponseCacheStrategyInterface instead. - */ -interface EsiResponseCacheStrategyInterface extends ResponseCacheStrategyInterface -{ -} diff --git a/vendor/symfony/http-kernel/HttpCache/HttpCache.php b/vendor/symfony/http-kernel/HttpCache/HttpCache.php index 941d4c6f..297e98a2 100644 --- a/vendor/symfony/http-kernel/HttpCache/HttpCache.php +++ b/vendor/symfony/http-kernel/HttpCache/HttpCache.php @@ -159,29 +159,9 @@ public function getKernel() */ public function getSurrogate() { - if (!$this->surrogate instanceof Esi) { - throw new \LogicException('This instance of HttpCache was not set up to use ESI as surrogate handler. You must overwrite and use createSurrogate'); - } - return $this->surrogate; } - /** - * Gets the Esi instance. - * - * @return Esi An Esi instance - * - * @throws \LogicException - * - * @deprecated since version 2.6, to be removed in 3.0. Use getSurrogate() instead - */ - public function getEsi() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getSurrogate() method instead.', E_USER_DEPRECATED); - - return $this->getSurrogate(); - } - /** * {@inheritdoc} */ @@ -484,7 +464,7 @@ protected function forward(Request $request, $catch = false, Response $entry = n // make sure HttpCache is a trusted proxy if (!in_array('127.0.0.1', $trustedProxies = Request::getTrustedProxies())) { $trustedProxies[] = '127.0.0.1'; - Request::setTrustedProxies($trustedProxies); + Request::setTrustedProxies($trustedProxies, method_exists('Request', 'getTrustedHeaderSet') ? Request::getTrustedHeaderSet() : -1); } // always a "master" request (as the real master request can be in cache) diff --git a/vendor/symfony/http-kernel/HttpCache/Ssi.php b/vendor/symfony/http-kernel/HttpCache/Ssi.php index 5f7ee10a..3178c335 100644 --- a/vendor/symfony/http-kernel/HttpCache/Ssi.php +++ b/vendor/symfony/http-kernel/HttpCache/Ssi.php @@ -13,32 +13,14 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpKernelInterface; /** * Ssi implements the SSI capabilities to Request and Response instances. * * @author Sebastian Krebs */ -class Ssi implements SurrogateInterface +class Ssi extends AbstractSurrogate { - private $contentTypes; - private $phpEscapeMap = array( - array('', '', '', ''), - ); - - /** - * Constructor. - * - * @param array $contentTypes An array of content-type that should be parsed for SSI information - * (default: text/html, text/xml, application/xhtml+xml, and application/xml) - */ - public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml')) - { - $this->contentTypes = $contentTypes; - } - /** * {@inheritdoc} */ @@ -47,37 +29,6 @@ public function getName() return 'ssi'; } - /** - * {@inheritdoc} - */ - public function createCacheStrategy() - { - return new ResponseCacheStrategy(); - } - - /** - * {@inheritdoc} - */ - public function hasSurrogateCapability(Request $request) - { - if (null === $value = $request->headers->get('Surrogate-Capability')) { - return false; - } - - return false !== strpos($value, 'SSI/1.0'); - } - - /** - * {@inheritdoc} - */ - public function addSurrogateCapability(Request $request) - { - $current = $request->headers->get('Surrogate-Capability'); - $new = 'symfony2="SSI/1.0"'; - - $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); - } - /** * {@inheritdoc} */ @@ -88,18 +39,6 @@ public function addSurrogateControl(Response $response) } } - /** - * {@inheritdoc} - */ - public function needsParsing(Response $response) - { - if (!$control = $response->headers->get('Surrogate-Control')) { - return false; - } - - return (bool) preg_match('#content="[^"]*SSI/1.0[^"]*"#', $control); - } - /** * {@inheritdoc} */ @@ -154,41 +93,6 @@ public function process(Request $request, Response $response) $response->headers->set('X-Body-Eval', 'SSI'); // remove SSI/1.0 from the Surrogate-Control header - if ($response->headers->has('Surrogate-Control')) { - $value = $response->headers->get('Surrogate-Control'); - if ('content="SSI/1.0"' == $value) { - $response->headers->remove('Surrogate-Control'); - } elseif (preg_match('#,\s*content="SSI/1.0"#', $value)) { - $response->headers->set('Surrogate-Control', preg_replace('#,\s*content="SSI/1.0"#', '', $value)); - } elseif (preg_match('#content="SSI/1.0",\s*#', $value)) { - $response->headers->set('Surrogate-Control', preg_replace('#content="SSI/1.0",\s*#', '', $value)); - } - } - } - - /** - * {@inheritdoc} - */ - public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) - { - $subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all()); - - try { - $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); - - if (!$response->isSuccessful()) { - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); - } - - return $response->getContent(); - } catch (\Exception $e) { - if ($alt) { - return $this->handle($cache, $alt, '', $ignoreErrors); - } - - if (!$ignoreErrors) { - throw $e; - } - } + $this->removeFromControl($response); } } diff --git a/vendor/symfony/http-kernel/HttpCache/Store.php b/vendor/symfony/http-kernel/HttpCache/Store.php index b57d4a77..c4d961e6 100644 --- a/vendor/symfony/http-kernel/HttpCache/Store.php +++ b/vendor/symfony/http-kernel/HttpCache/Store.php @@ -317,14 +317,33 @@ private function getMetadata($key) /** * Purges data for the given URL. * + * This method purges both the HTTP and the HTTPS version of the cache entry. + * * @param string $url A URL * - * @return bool true if the URL exists and has been purged, false otherwise + * @return bool true if the URL exists with either HTTP or HTTPS scheme and has been purged, false otherwise */ public function purge($url) { - $key = $this->getCacheKey(Request::create($url)); + $http = preg_replace('#^https:#', 'http:', $url); + $https = preg_replace('#^http:#', 'https:', $url); + + $purgedHttp = $this->doPurge($http); + $purgedHttps = $this->doPurge($https); + return $purgedHttp || $purgedHttps; + } + + /** + * Purges data for the given URL. + * + * @param string $url A URL + * + * @return bool true if the URL exists and has been purged, false otherwise + */ + private function doPurge($url) + { + $key = $this->getCacheKey(Request::create($url)); if (isset($this->locks[$key])) { flock($this->locks[$key], LOCK_UN); fclose($this->locks[$key]); diff --git a/vendor/symfony/http-kernel/HttpKernel.php b/vendor/symfony/http-kernel/HttpKernel.php index 4e628a14..c63a6af8 100644 --- a/vendor/symfony/http-kernel/HttpKernel.php +++ b/vendor/symfony/http-kernel/HttpKernel.php @@ -11,7 +11,10 @@ namespace Symfony\Component\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver; +use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; +use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; @@ -38,19 +41,20 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface protected $dispatcher; protected $resolver; protected $requestStack; + private $argumentResolver; - /** - * Constructor. - * - * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance - * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance - * @param RequestStack $requestStack A stack for master/sub requests - */ - public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null) + public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverInterface $argumentResolver = null) { $this->dispatcher = $dispatcher; $this->resolver = $resolver; $this->requestStack = $requestStack ?: new RequestStack(); + $this->argumentResolver = $argumentResolver; + + if (null === $this->argumentResolver) { + @trigger_error(sprintf('As of 3.1 an %s is used to resolve arguments. In 4.0 the $argumentResolver becomes the %s if no other is provided instead of using the $resolver argument.', ArgumentResolverInterface::class, ArgumentResolver::class), E_USER_DEPRECATED); + // fallback in case of deprecations + $this->argumentResolver = $resolver; + } } /** @@ -138,7 +142,12 @@ private function handleRaw(Request $request, $type = self::MASTER_REQUEST) $controller = $event->getController(); // controller arguments - $arguments = $this->resolver->getArguments($request, $controller); + $arguments = $this->argumentResolver->getArguments($request, $controller); + + $event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type); + $this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event); + $controller = $event->getController(); + $arguments = $event->getArguments(); // call controller $response = call_user_func_array($controller, $arguments); diff --git a/vendor/symfony/http-kernel/Kernel.php b/vendor/symfony/http-kernel/Kernel.php index acc77dc8..7ef34d65 100644 --- a/vendor/symfony/http-kernel/Kernel.php +++ b/vendor/symfony/http-kernel/Kernel.php @@ -16,7 +16,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\IniFileLoader; @@ -59,15 +58,15 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.16'; - const VERSION_ID = 20816; - const MAJOR_VERSION = 2; - const MINOR_VERSION = 8; - const RELEASE_VERSION = 16; + const VERSION = '3.2.8'; + const VERSION_ID = 30208; + const MAJOR_VERSION = 3; + const MINOR_VERSION = 2; + const RELEASE_VERSION = 8; const EXTRA_VERSION = ''; - const END_OF_MAINTENANCE = '11/2018'; - const END_OF_LIFE = '11/2019'; + const END_OF_MAINTENANCE = '07/2017'; + const END_OF_LIFE = '01/2018'; /** * Constructor. @@ -85,22 +84,6 @@ public function __construct($environment, $debug) if ($this->debug) { $this->startTime = microtime(true); } - - $defClass = new \ReflectionMethod($this, 'init'); - $defClass = $defClass->getDeclaringClass()->name; - - if (__CLASS__ !== $defClass) { - @trigger_error(sprintf('Calling the %s::init() method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', $defClass), E_USER_DEPRECATED); - $this->init(); - } - } - - /** - * @deprecated since version 2.3, to be removed in 3.0. Move your logic in the constructor instead. - */ - public function init() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0. Move your logic to the constructor method instead.', E_USER_DEPRECATED); } public function __clone() @@ -203,24 +186,6 @@ public function getBundles() return $this->bundles; } - /** - * {@inheritdoc} - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function isClassInActiveBundle($class) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in version 3.0.', E_USER_DEPRECATED); - - foreach ($this->getBundles() as $bundle) { - if (0 === strpos($class, $bundle->getNamespace())) { - return true; - } - } - - return false; - } - /** * {@inheritdoc} */ @@ -303,6 +268,9 @@ public function getName() { if (null === $this->name) { $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir)); + if (ctype_digit($this->name[0])) { + $this->name = '_'.$this->name; + } } return $this->name; @@ -363,13 +331,21 @@ public function loadClassCache($name = 'classes', $extension = '.php') } /** - * Used internally. + * @internal */ public function setClassCache(array $classes) { file_put_contents($this->getCacheDir().'/classes.map', sprintf('getCacheDir().'/annotations.map', sprintf('getKernelParameters())); + $container = new ContainerBuilder(); + $container->getParameterBag()->add($this->getKernelParameters()); if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) { $container->setProxyInstantiator(new RuntimeInstantiator()); diff --git a/vendor/symfony/http-kernel/KernelEvents.php b/vendor/symfony/http-kernel/KernelEvents.php index abbbfcc0..3e961737 100644 --- a/vendor/symfony/http-kernel/KernelEvents.php +++ b/vendor/symfony/http-kernel/KernelEvents.php @@ -23,11 +23,9 @@ final class KernelEvents * dispatching. * * This event allows you to create a response for a request before any - * other code in the framework is executed. The event listener method - * receives a Symfony\Component\HttpKernel\Event\GetResponseEvent - * instance. + * other code in the framework is executed. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\GetResponseEvent") * * @var string */ @@ -37,11 +35,9 @@ final class KernelEvents * The EXCEPTION event occurs when an uncaught exception appears. * * This event allows you to create a response for a thrown exception or - * to modify the thrown exception. The event listener method receives - * a Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent - * instance. + * to modify the thrown exception. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent") * * @var string */ @@ -52,11 +48,9 @@ final class KernelEvents * is not a Response instance. * * This event allows you to create a response for the return value of the - * controller. The event listener method receives a - * Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent - * instance. + * controller. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent") * * @var string */ @@ -67,24 +61,34 @@ final class KernelEvents * handling a request. * * This event allows you to change the controller that will handle the - * request. The event listener method receives a - * Symfony\Component\HttpKernel\Event\FilterControllerEvent instance. + * request. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\FilterControllerEvent") * * @var string */ const CONTROLLER = 'kernel.controller'; + /** + * The CONTROLLER_ARGUMENTS event occurs once controller arguments have been resolved. + * + * This event allows you to change the arguments that will be passed to + * the controller. + * + * @Event("Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent") + * + * @var string + */ + const CONTROLLER_ARGUMENTS = 'kernel.controller_arguments'; + /** * The RESPONSE event occurs once a response was created for * replying to a request. * * This event allows you to modify or replace the response that will be - * replied. The event listener method receives a - * Symfony\Component\HttpKernel\Event\FilterResponseEvent instance. + * replied. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\FilterResponseEvent") * * @var string */ @@ -94,10 +98,8 @@ final class KernelEvents * The TERMINATE event occurs once a response was sent. * * This event allows you to run expensive post-response jobs. - * The event listener method receives a - * Symfony\Component\HttpKernel\Event\PostResponseEvent instance. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\PostResponseEvent") * * @var string */ @@ -108,10 +110,8 @@ final class KernelEvents * * This event allows you to reset the global and environmental state of * the application, when it was changed during the request. - * The event listener method receives a - * Symfony\Component\HttpKernel\Event\FinishRequestEvent instance. * - * @Event + * @Event("Symfony\Component\HttpKernel\Event\FinishRequestEvent") * * @var string */ diff --git a/vendor/symfony/http-kernel/KernelInterface.php b/vendor/symfony/http-kernel/KernelInterface.php index 37ac3af5..d7308ae5 100644 --- a/vendor/symfony/http-kernel/KernelInterface.php +++ b/vendor/symfony/http-kernel/KernelInterface.php @@ -57,17 +57,6 @@ public function shutdown(); */ public function getBundles(); - /** - * Checks if a given class name belongs to an active bundle. - * - * @param string $class A class name - * - * @return bool true if the class belongs to an active bundle, false otherwise - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function isClassInActiveBundle($class); - /** * Returns a bundle and optionally its descendants by its name. * diff --git a/vendor/symfony/http-kernel/Log/LoggerInterface.php b/vendor/symfony/http-kernel/Log/LoggerInterface.php deleted file mode 100644 index cad38e55..00000000 --- a/vendor/symfony/http-kernel/Log/LoggerInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Log; - -use Psr\Log\LoggerInterface as PsrLogger; - -/** - * LoggerInterface. - * - * @author Fabien Potencier - * - * @deprecated since version 2.2, to be removed in 3.0. Type-hint \Psr\Log\LoggerInterface instead. - */ -interface LoggerInterface extends PsrLogger -{ - /** - * @deprecated since version 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible. - */ - public function emerg($message, array $context = array()); - - /** - * @deprecated since version 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible. - */ - public function crit($message, array $context = array()); - - /** - * @deprecated since version 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible. - */ - public function err($message, array $context = array()); - - /** - * @deprecated since version 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible. - */ - public function warn($message, array $context = array()); -} diff --git a/vendor/symfony/http-kernel/Log/NullLogger.php b/vendor/symfony/http-kernel/Log/NullLogger.php deleted file mode 100644 index 36a857d3..00000000 --- a/vendor/symfony/http-kernel/Log/NullLogger.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Log; - -@trigger_error('The '.__NAMESPACE__.'\NullLogger class is deprecated since version 2.2 and will be removed in 3.0. Use the Psr\Log\NullLogger class instead from the psr/log Composer package.', E_USER_DEPRECATED); - -use Psr\Log\NullLogger as PsrNullLogger; - -/** - * NullLogger. - * - * @author Fabien Potencier - */ -class NullLogger extends PsrNullLogger implements LoggerInterface -{ - public function emerg($message, array $context = array()) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new emergency() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); - } - - public function crit($message, array $context = array()) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new critical() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); - } - - public function err($message, array $context = array()) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new error() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); - } - - public function warn($message, array $context = array()) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. You should use the new warning() method instead, which is PSR-3 compatible.', E_USER_DEPRECATED); - } -} diff --git a/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php deleted file mode 100644 index 3eb69194..00000000 --- a/vendor/symfony/http-kernel/Profiler/BaseMemcacheProfilerStorage.php +++ /dev/null @@ -1,315 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\BaseMemcacheProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * Base Memcache storage for profiling information in a Memcache. - * - * @author Andrej Hudec - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface -{ - const TOKEN_PREFIX = 'sf_profiler_'; - - protected $dsn; - protected $lifetime; - - /** - * Constructor. - * - * @param string $dsn A data source name - * @param string $username - * @param string $password - * @param int $lifetime The lifetime to use for the purge - */ - public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) - { - $this->dsn = $dsn; - $this->lifetime = (int) $lifetime; - } - - /** - * {@inheritdoc} - */ - public function find($ip, $url, $limit, $method, $start = null, $end = null) - { - $indexName = $this->getIndexName(); - - $indexContent = $this->getValue($indexName); - if (!$indexContent) { - return array(); - } - - $profileList = explode("\n", $indexContent); - $result = array(); - - foreach ($profileList as $item) { - if ($limit === 0) { - break; - } - - if ($item == '') { - continue; - } - - $values = explode("\t", $item, 7); - list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; - $statusCode = isset($values[6]) ? $values[6] : null; - - $itemTime = (int) $itemTime; - - if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { - continue; - } - - if (!empty($start) && $itemTime < $start) { - continue; - } - - if (!empty($end) && $itemTime > $end) { - continue; - } - - $result[$itemToken] = array( - 'token' => $itemToken, - 'ip' => $itemIp, - 'method' => $itemMethod, - 'url' => $itemUrl, - 'time' => $itemTime, - 'parent' => $itemParent, - 'status_code' => $statusCode, - ); - --$limit; - } - - usort($result, function ($a, $b) { - if ($a['time'] === $b['time']) { - return 0; - } - - return $a['time'] > $b['time'] ? -1 : 1; - }); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function purge() - { - // delete only items from index - $indexName = $this->getIndexName(); - - $indexContent = $this->getValue($indexName); - - if (!$indexContent) { - return false; - } - - $profileList = explode("\n", $indexContent); - - foreach ($profileList as $item) { - if ($item == '') { - continue; - } - - if (false !== $pos = strpos($item, "\t")) { - $this->delete($this->getItemName(substr($item, 0, $pos))); - } - } - - return $this->delete($indexName); - } - - /** - * {@inheritdoc} - */ - public function read($token) - { - if (empty($token)) { - return false; - } - - $profile = $this->getValue($this->getItemName($token)); - - if (false !== $profile) { - $profile = $this->createProfileFromData($token, $profile); - } - - return $profile; - } - - /** - * {@inheritdoc} - */ - public function write(Profile $profile) - { - $data = array( - 'token' => $profile->getToken(), - 'parent' => $profile->getParentToken(), - 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), - 'data' => $profile->getCollectors(), - 'ip' => $profile->getIp(), - 'method' => $profile->getMethod(), - 'url' => $profile->getUrl(), - 'time' => $profile->getTime(), - ); - - $profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken())); - - if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime)) { - if (!$profileIndexed) { - // Add to index - $indexName = $this->getIndexName(); - - $indexRow = implode("\t", array( - $profile->getToken(), - $profile->getIp(), - $profile->getMethod(), - $profile->getUrl(), - $profile->getTime(), - $profile->getParentToken(), - $profile->getStatusCode(), - ))."\n"; - - return $this->appendValue($indexName, $indexRow, $this->lifetime); - } - - return true; - } - - return false; - } - - /** - * Retrieve item from the memcache server. - * - * @param string $key - * - * @return mixed - */ - abstract protected function getValue($key); - - /** - * Store an item on the memcache server under the specified key. - * - * @param string $key - * @param mixed $value - * @param int $expiration - * - * @return bool - */ - abstract protected function setValue($key, $value, $expiration = 0); - - /** - * Delete item from the memcache server. - * - * @param string $key - * - * @return bool - */ - abstract protected function delete($key); - - /** - * Append data to an existing item on the memcache server. - * - * @param string $key - * @param string $value - * @param int $expiration - * - * @return bool - */ - abstract protected function appendValue($key, $value, $expiration = 0); - - private function createProfileFromData($token, $data, $parent = null) - { - $profile = new Profile($token); - $profile->setIp($data['ip']); - $profile->setMethod($data['method']); - $profile->setUrl($data['url']); - $profile->setTime($data['time']); - $profile->setCollectors($data['data']); - - if (!$parent && $data['parent']) { - $parent = $this->read($data['parent']); - } - - if ($parent) { - $profile->setParent($parent); - } - - foreach ($data['children'] as $token) { - if (!$token) { - continue; - } - - if (!$childProfileData = $this->getValue($this->getItemName($token))) { - continue; - } - - $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); - } - - return $profile; - } - - /** - * Get item name. - * - * @param string $token - * - * @return string - */ - private function getItemName($token) - { - $name = self::TOKEN_PREFIX.$token; - - if ($this->isItemNameValid($name)) { - return $name; - } - - return false; - } - - /** - * Get name of index. - * - * @return string - */ - private function getIndexName() - { - $name = self::TOKEN_PREFIX.'index'; - - if ($this->isItemNameValid($name)) { - return $name; - } - - return false; - } - - private function isItemNameValid($name) - { - $length = strlen($name); - - if ($length > 250) { - throw new \RuntimeException(sprintf('The memcache item key "%s" is too long (%s bytes). Allowed maximum size is 250 bytes.', $name, $length)); - } - - return true; - } -} diff --git a/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php index 29da4abf..bd8761f5 100644 --- a/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php +++ b/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php @@ -49,7 +49,7 @@ public function __construct($dsn) /** * {@inheritdoc} */ - public function find($ip, $url, $limit, $method, $start = null, $end = null) + public function find($ip, $url, $limit, $method, $start = null, $end = null, $statusCode = null) { $file = $this->getIndexFilename(); @@ -63,12 +63,10 @@ public function find($ip, $url, $limit, $method, $start = null, $end = null) $result = array(); while (count($result) < $limit && $line = $this->readLineFromFile($file)) { $values = str_getcsv($line); - list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = $values; - $csvStatusCode = isset($values[6]) ? $values[6] : null; - + list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent, $csvStatusCode) = $values; $csvTime = (int) $csvTime; - if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) { + if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method) || $statusCode && false === strpos($csvStatusCode, $statusCode)) { continue; } @@ -154,6 +152,7 @@ public function write(Profile $profile) 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime(), + 'status_code' => $profile->getStatusCode(), ); if (false === file_put_contents($file, serialize($data))) { @@ -261,6 +260,7 @@ protected function createProfileFromData($token, $data, $parent = null) $profile->setMethod($data['method']); $profile->setUrl($data['url']); $profile->setTime($data['time']); + $profile->setStatusCode($data['status_code']); $profile->setCollectors($data['data']); if (!$parent && $data['parent']) { diff --git a/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php deleted file mode 100644 index 997c0dd4..00000000 --- a/vendor/symfony/http-kernel/Profiler/MemcacheProfilerStorage.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\MemcacheProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * Memcache Profiler Storage. - * - * @author Andrej Hudec - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -class MemcacheProfilerStorage extends BaseMemcacheProfilerStorage -{ - /** - * @var \Memcache - */ - private $memcache; - - /** - * Internal convenience method that returns the instance of the Memcache. - * - * @return \Memcache - * - * @throws \RuntimeException - */ - protected function getMemcache() - { - if (null === $this->memcache) { - if (!preg_match('#^memcache://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcache with an invalid dsn "%s". The expected format is "memcache://[host]:port".', $this->dsn)); - } - - $host = $matches[1] ?: $matches[2]; - $port = $matches[3]; - - $memcache = new \Memcache(); - $memcache->addserver($host, $port); - - $this->memcache = $memcache; - } - - return $this->memcache; - } - - /** - * Set instance of the Memcache. - * - * @param \Memcache $memcache - */ - public function setMemcache($memcache) - { - $this->memcache = $memcache; - } - - /** - * {@inheritdoc} - */ - protected function getValue($key) - { - return $this->getMemcache()->get($key); - } - - /** - * {@inheritdoc} - */ - protected function setValue($key, $value, $expiration = 0) - { - return $this->getMemcache()->set($key, $value, false, time() + $expiration); - } - - /** - * {@inheritdoc} - */ - protected function delete($key) - { - return $this->getMemcache()->delete($key); - } - - /** - * {@inheritdoc} - */ - protected function appendValue($key, $value, $expiration = 0) - { - $memcache = $this->getMemcache(); - - if (method_exists($memcache, 'append')) { - // Memcache v3.0 - if (!$result = $memcache->append($key, $value, false, $expiration)) { - return $memcache->set($key, $value, false, $expiration); - } - - return $result; - } - - // simulate append in Memcache <3.0 - $content = $memcache->get($key); - - return $memcache->set($key, $content.$value, false, $expiration); - } -} diff --git a/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php deleted file mode 100644 index edf6ff19..00000000 --- a/vendor/symfony/http-kernel/Profiler/MemcachedProfilerStorage.php +++ /dev/null @@ -1,108 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\MemcachedProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * Memcached Profiler Storage. - * - * @author Andrej Hudec - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -class MemcachedProfilerStorage extends BaseMemcacheProfilerStorage -{ - /** - * @var \Memcached - */ - private $memcached; - - /** - * Internal convenience method that returns the instance of the Memcached. - * - * @return \Memcached - * - * @throws \RuntimeException - */ - protected function getMemcached() - { - if (null === $this->memcached) { - if (!preg_match('#^memcached://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcached with an invalid dsn "%s". The expected format is "memcached://[host]:port".', $this->dsn)); - } - - $host = $matches[1] ?: $matches[2]; - $port = $matches[3]; - - $memcached = new \Memcached(); - - // disable compression to allow appending - $memcached->setOption(\Memcached::OPT_COMPRESSION, false); - - $memcached->addServer($host, $port); - - $this->memcached = $memcached; - } - - return $this->memcached; - } - - /** - * Set instance of the Memcached. - * - * @param \Memcached $memcached - */ - public function setMemcached($memcached) - { - $this->memcached = $memcached; - } - - /** - * {@inheritdoc} - */ - protected function getValue($key) - { - return $this->getMemcached()->get($key); - } - - /** - * {@inheritdoc} - */ - protected function setValue($key, $value, $expiration = 0) - { - return $this->getMemcached()->set($key, $value, time() + $expiration); - } - - /** - * {@inheritdoc} - */ - protected function delete($key) - { - return $this->getMemcached()->delete($key); - } - - /** - * {@inheritdoc} - */ - protected function appendValue($key, $value, $expiration = 0) - { - $memcached = $this->getMemcached(); - - if (!$result = $memcached->append($key, $value)) { - return $memcached->set($key, $value, $expiration); - } - - return $result; - } -} diff --git a/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php deleted file mode 100644 index fddc87e1..00000000 --- a/vendor/symfony/http-kernel/Profiler/MongoDbProfilerStorage.php +++ /dev/null @@ -1,265 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\MongoDbProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -class MongoDbProfilerStorage implements ProfilerStorageInterface -{ - protected $dsn; - protected $lifetime; - private $mongo; - - /** - * Constructor. - * - * @param string $dsn A data source name - * @param string $username Not used - * @param string $password Not used - * @param int $lifetime The lifetime to use for the purge - */ - public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) - { - $this->dsn = $dsn; - $this->lifetime = (int) $lifetime; - } - - /** - * {@inheritdoc} - */ - public function find($ip, $url, $limit, $method, $start = null, $end = null) - { - $cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time', 'status_code'))->sort(array('time' => -1))->limit($limit); - - $tokens = array(); - foreach ($cursor as $profile) { - $tokens[] = $this->getData($profile); - } - - return $tokens; - } - - /** - * {@inheritdoc} - */ - public function purge() - { - $this->getMongo()->remove(array()); - } - - /** - * {@inheritdoc} - */ - public function read($token) - { - $profile = $this->getMongo()->findOne(array('_id' => $token, 'data' => array('$exists' => true))); - - if (null !== $profile) { - $profile = $this->createProfileFromData($this->getData($profile)); - } - - return $profile; - } - - /** - * {@inheritdoc} - */ - public function write(Profile $profile) - { - $this->cleanup(); - - $record = array( - '_id' => $profile->getToken(), - 'parent' => $profile->getParentToken(), - 'data' => base64_encode(serialize($profile->getCollectors())), - 'ip' => $profile->getIp(), - 'method' => $profile->getMethod(), - 'url' => $profile->getUrl(), - 'time' => $profile->getTime(), - 'status_code' => $profile->getStatusCode(), - ); - - $result = $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true)); - - return (bool) (isset($result['ok']) ? $result['ok'] : $result); - } - - /** - * Internal convenience method that returns the instance of the MongoDB Collection. - * - * @return \MongoCollection - * - * @throws \RuntimeException - */ - protected function getMongo() - { - if (null !== $this->mongo) { - return $this->mongo; - } - - if (!$parsedDsn = $this->parseDsn($this->dsn)) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn)); - } - - list($server, $database, $collection) = $parsedDsn; - $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? '\Mongo' : '\MongoClient'; - $mongo = new $mongoClass($server); - - return $this->mongo = $mongo->selectCollection($database, $collection); - } - - /** - * @param array $data - * - * @return Profile - */ - protected function createProfileFromData(array $data) - { - $profile = $this->getProfile($data); - - if ($data['parent']) { - $parent = $this->getMongo()->findOne(array('_id' => $data['parent'], 'data' => array('$exists' => true))); - if ($parent) { - $profile->setParent($this->getProfile($this->getData($parent))); - } - } - - $profile->setChildren($this->readChildren($data['token'])); - - return $profile; - } - - /** - * @param string $token - * - * @return Profile[] An array of Profile instances - */ - protected function readChildren($token) - { - $profiles = array(); - - $cursor = $this->getMongo()->find(array('parent' => $token, 'data' => array('$exists' => true))); - foreach ($cursor as $d) { - $profiles[] = $this->getProfile($this->getData($d)); - } - - return $profiles; - } - - protected function cleanup() - { - $this->getMongo()->remove(array('time' => array('$lt' => time() - $this->lifetime))); - } - - /** - * @param string $ip - * @param string $url - * @param string $method - * @param int $start - * @param int $end - * - * @return array - */ - private function buildQuery($ip, $url, $method, $start, $end) - { - $query = array(); - - if (!empty($ip)) { - $query['ip'] = $ip; - } - - if (!empty($url)) { - $query['url'] = $url; - } - - if (!empty($method)) { - $query['method'] = $method; - } - - if (!empty($start) || !empty($end)) { - $query['time'] = array(); - } - - if (!empty($start)) { - $query['time']['$gte'] = $start; - } - - if (!empty($end)) { - $query['time']['$lte'] = $end; - } - - return $query; - } - - /** - * @param array $data - * - * @return array - */ - private function getData(array $data) - { - return array( - 'token' => $data['_id'], - 'parent' => isset($data['parent']) ? $data['parent'] : null, - 'ip' => isset($data['ip']) ? $data['ip'] : null, - 'method' => isset($data['method']) ? $data['method'] : null, - 'url' => isset($data['url']) ? $data['url'] : null, - 'time' => isset($data['time']) ? $data['time'] : null, - 'data' => isset($data['data']) ? $data['data'] : null, - 'status_code' => isset($data['status_code']) ? $data['status_code'] : null, - ); - } - - /** - * @param array $data - * - * @return Profile - */ - private function getProfile(array $data) - { - $profile = new Profile($data['token']); - $profile->setIp($data['ip']); - $profile->setMethod($data['method']); - $profile->setUrl($data['url']); - $profile->setTime($data['time']); - $profile->setCollectors(unserialize(base64_decode($data['data']))); - - return $profile; - } - - /** - * @param string $dsn - * - * @return null|array Array($server, $database, $collection) - */ - private function parseDsn($dsn) - { - if (!preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $dsn, $matches)) { - return; - } - - $server = $matches[1]; - $database = $matches[2]; - $collection = $matches[3]; - preg_match('#^mongodb://(([^:]+):?(.*)(?=@))?@?([^/]*)(.*)$#', $server, $matchesServer); - - if ('' == $matchesServer[5] && '' != $matches[2]) { - $server .= '/'.$matches[2]; - } - - return array($server, $database, $collection); - } -} diff --git a/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php deleted file mode 100644 index 45d9cfff..00000000 --- a/vendor/symfony/http-kernel/Profiler/MysqlProfilerStorage.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\MysqlProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * A ProfilerStorage for Mysql. - * - * @author Jan Schumann - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -class MysqlProfilerStorage extends PdoProfilerStorage -{ - /** - * {@inheritdoc} - */ - protected function initDb() - { - if (null === $this->db) { - if (0 !== strpos($this->dsn, 'mysql')) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Mysql with an invalid dsn "%s". The expected format is "mysql:dbname=database_name;host=host_name".', $this->dsn)); - } - - if (!class_exists('PDO') || !in_array('mysql', \PDO::getAvailableDrivers(), true)) { - throw new \RuntimeException('You need to enable PDO_Mysql extension for the profiler to run properly.'); - } - - $db = new \PDO($this->dsn, $this->username, $this->password); - $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, status_code SMALLINT UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))'); - - $this->db = $db; - } - - return $this->db; - } - - /** - * {@inheritdoc} - */ - protected function buildCriteria($ip, $url, $start, $end, $limit, $method) - { - $criteria = array(); - $args = array(); - - if ($ip = preg_replace('/[^\d\.]/', '', $ip)) { - $criteria[] = 'ip LIKE :ip'; - $args[':ip'] = '%'.$ip.'%'; - } - - if ($url) { - $criteria[] = 'url LIKE :url'; - $args[':url'] = '%'.addcslashes($url, '%_\\').'%'; - } - - if ($method) { - $criteria[] = 'method = :method'; - $args[':method'] = $method; - } - - if (!empty($start)) { - $criteria[] = 'time >= :start'; - $args[':start'] = $start; - } - - if (!empty($end)) { - $criteria[] = 'time <= :end'; - $args[':end'] = $end; - } - - return array($criteria, $args); - } -} diff --git a/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php deleted file mode 100644 index 27da1591..00000000 --- a/vendor/symfony/http-kernel/Profiler/PdoProfilerStorage.php +++ /dev/null @@ -1,267 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\PdoProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * Base PDO storage for profiling information in a PDO database. - * - * @author Fabien Potencier - * @author Jan Schumann - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -abstract class PdoProfilerStorage implements ProfilerStorageInterface -{ - protected $dsn; - protected $username; - protected $password; - protected $lifetime; - protected $db; - - /** - * Constructor. - * - * @param string $dsn A data source name - * @param string $username The username for the database - * @param string $password The password for the database - * @param int $lifetime The lifetime to use for the purge - */ - public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) - { - $this->dsn = $dsn; - $this->username = $username; - $this->password = $password; - $this->lifetime = (int) $lifetime; - } - - /** - * {@inheritdoc} - */ - public function find($ip, $url, $limit, $method, $start = null, $end = null) - { - if (null === $start) { - $start = 0; - } - - if (null === $end) { - $end = time(); - } - - list($criteria, $args) = $this->buildCriteria($ip, $url, $start, $end, $limit, $method); - - $criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : ''; - - $db = $this->initDb(); - $tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent, status_code FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((int) $limit), $args); - $this->close($db); - - return $tokens; - } - - /** - * {@inheritdoc} - */ - public function read($token) - { - $db = $this->initDb(); - $args = array(':token' => $token); - $data = $this->fetch($db, 'SELECT data, parent, ip, method, url, time FROM sf_profiler_data WHERE token = :token LIMIT 1', $args); - $this->close($db); - if (isset($data[0]['data'])) { - return $this->createProfileFromData($token, $data[0]); - } - } - - /** - * {@inheritdoc} - */ - public function write(Profile $profile) - { - $db = $this->initDb(); - $args = array( - ':token' => $profile->getToken(), - ':parent' => $profile->getParentToken(), - ':data' => base64_encode(serialize($profile->getCollectors())), - ':ip' => $profile->getIp(), - ':method' => $profile->getMethod(), - ':url' => $profile->getUrl(), - ':time' => $profile->getTime(), - ':created_at' => time(), - ':status_code' => $profile->getStatusCode(), - ); - - try { - if ($this->has($profile->getToken())) { - $this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at, status_code = :status_code WHERE token = :token', $args); - } else { - $this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at, status_code) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at, :status_code)', $args); - } - $this->cleanup(); - $status = true; - } catch (\Exception $e) { - $status = false; - } - - $this->close($db); - - return $status; - } - - /** - * {@inheritdoc} - */ - public function purge() - { - $db = $this->initDb(); - $this->exec($db, 'DELETE FROM sf_profiler_data'); - $this->close($db); - } - - /** - * Build SQL criteria to fetch records by ip and url. - * - * @param string $ip The IP - * @param string $url The URL - * @param string $start The start period to search from - * @param string $end The end period to search to - * @param string $limit The maximum number of tokens to return - * @param string $method The request method - * - * @return array An array with (criteria, args) - */ - abstract protected function buildCriteria($ip, $url, $start, $end, $limit, $method); - - /** - * Initializes the database. - * - * @throws \RuntimeException When the requested database driver is not installed - */ - abstract protected function initDb(); - - protected function cleanup() - { - $db = $this->initDb(); - $this->exec($db, 'DELETE FROM sf_profiler_data WHERE created_at < :time', array(':time' => time() - $this->lifetime)); - $this->close($db); - } - - protected function exec($db, $query, array $args = array()) - { - $stmt = $this->prepareStatement($db, $query); - - foreach ($args as $arg => $val) { - $stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR); - } - $success = $stmt->execute(); - if (!$success) { - throw new \RuntimeException(sprintf('Error executing query "%s"', $query)); - } - } - - protected function prepareStatement($db, $query) - { - try { - $stmt = $db->prepare($query); - } catch (\Exception $e) { - $stmt = false; - } - - if (false === $stmt) { - throw new \RuntimeException('The database cannot successfully prepare the statement'); - } - - return $stmt; - } - - protected function fetch($db, $query, array $args = array()) - { - $stmt = $this->prepareStatement($db, $query); - - foreach ($args as $arg => $val) { - $stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR); - } - $stmt->execute(); - - return $stmt->fetchAll(\PDO::FETCH_ASSOC); - } - - protected function close($db) - { - } - - protected function createProfileFromData($token, $data, $parent = null) - { - $profile = new Profile($token); - $profile->setIp($data['ip']); - $profile->setMethod($data['method']); - $profile->setUrl($data['url']); - $profile->setTime($data['time']); - $profile->setCollectors(unserialize(base64_decode($data['data']))); - - if (!$parent && !empty($data['parent'])) { - $parent = $this->read($data['parent']); - } - - if ($parent) { - $profile->setParent($parent); - } - - $profile->setChildren($this->readChildren($token, $profile)); - - return $profile; - } - - /** - * Reads the child profiles for the given token. - * - * @param string $token The parent token - * @param string $parent The parent instance - * - * @return Profile[] An array of Profile instance - */ - protected function readChildren($token, $parent) - { - $db = $this->initDb(); - $data = $this->fetch($db, 'SELECT token, data, ip, method, url, time FROM sf_profiler_data WHERE parent = :token', array(':token' => $token)); - $this->close($db); - - if (!$data) { - return array(); - } - - $profiles = array(); - foreach ($data as $d) { - $profiles[] = $this->createProfileFromData($d['token'], $d, $parent); - } - - return $profiles; - } - - /** - * Returns whether data for the given token already exists in storage. - * - * @param string $token The profile token - * - * @return string - */ - protected function has($token) - { - $db = $this->initDb(); - $tokenExists = $this->fetch($db, 'SELECT 1 FROM sf_profiler_data WHERE token = :token LIMIT 1', array(':token' => $token)); - $this->close($db); - - return !empty($tokenExists); - } -} diff --git a/vendor/symfony/http-kernel/Profiler/Profile.php b/vendor/symfony/http-kernel/Profiler/Profile.php index d6be0c7d..fab8b41d 100644 --- a/vendor/symfony/http-kernel/Profiler/Profile.php +++ b/vendor/symfony/http-kernel/Profiler/Profile.php @@ -156,7 +156,7 @@ public function setUrl($url) /** * Returns the time. * - * @return string The time + * @return int The time */ public function getTime() { @@ -167,6 +167,9 @@ public function getTime() return $this->time; } + /** + * @param int The time + */ public function setTime($time) { $this->time = $time; @@ -287,6 +290,6 @@ public function hasCollector($name) public function __sleep() { - return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time'); + return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time', 'statusCode'); } } diff --git a/vendor/symfony/http-kernel/Profiler/Profiler.php b/vendor/symfony/http-kernel/Profiler/Profiler.php index 88b4c0c9..f31e2437 100644 --- a/vendor/symfony/http-kernel/Profiler/Profiler.php +++ b/vendor/symfony/http-kernel/Profiler/Profiler.php @@ -132,63 +132,24 @@ public function purge() $this->storage->purge(); } - /** - * Exports the current profiler data. - * - * @param Profile $profile A Profile instance - * - * @return string The exported data - * - * @deprecated since Symfony 2.8, to be removed in 3.0. - */ - public function export(Profile $profile) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - - return base64_encode(serialize($profile)); - } - - /** - * Imports data into the profiler storage. - * - * @param string $data A data string as exported by the export() method - * - * @return Profile|false A Profile instance - * - * @deprecated since Symfony 2.8, to be removed in 3.0. - */ - public function import($data) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED); - - $profile = unserialize(base64_decode($data)); - - if ($this->storage->read($profile->getToken())) { - return false; - } - - $this->saveProfile($profile); - - return $profile; - } - /** * Finds profiler tokens for the given criteria. * - * @param string $ip The IP - * @param string $url The URL - * @param string $limit The maximum number of tokens to return - * @param string $method The request method - * @param string $start The start date to search from - * @param string $end The end date to search to + * @param string $ip The IP + * @param string $url The URL + * @param string $limit The maximum number of tokens to return + * @param string $method The request method + * @param string $start The start date to search from + * @param string $end The end date to search to + * @param string $statusCode The request status code * * @return array An array of tokens * * @see http://php.net/manual/en/datetime.formats.php for the supported date/time formats */ - public function find($ip, $url, $limit, $method, $start, $end) + public function find($ip, $url, $limit, $method, $start, $end, $statusCode = null) { - return $this->storage->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end)); + return $this->storage->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end), $statusCode); } /** diff --git a/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php deleted file mode 100644 index 2568e3b5..00000000 --- a/vendor/symfony/http-kernel/Profiler/RedisProfilerStorage.php +++ /dev/null @@ -1,399 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\RedisProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * RedisProfilerStorage stores profiling information in Redis. - * - * @author Andrej Hudec - * @author Stephane PY - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -class RedisProfilerStorage implements ProfilerStorageInterface -{ - const TOKEN_PREFIX = 'sf_profiler_'; - - const REDIS_OPT_SERIALIZER = 1; - const REDIS_OPT_PREFIX = 2; - const REDIS_SERIALIZER_NONE = 0; - const REDIS_SERIALIZER_PHP = 1; - - protected $dsn; - protected $lifetime; - - /** - * @var \Redis - */ - private $redis; - - /** - * Constructor. - * - * @param string $dsn A data source name - * @param string $username Not used - * @param string $password Not used - * @param int $lifetime The lifetime to use for the purge - */ - public function __construct($dsn, $username = '', $password = '', $lifetime = 86400) - { - $this->dsn = $dsn; - $this->lifetime = (int) $lifetime; - } - - /** - * {@inheritdoc} - */ - public function find($ip, $url, $limit, $method, $start = null, $end = null) - { - $indexName = $this->getIndexName(); - - if (!$indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE)) { - return array(); - } - - $profileList = array_reverse(explode("\n", $indexContent)); - $result = array(); - - foreach ($profileList as $item) { - if ($limit === 0) { - break; - } - - if ($item == '') { - continue; - } - - $values = explode("\t", $item, 7); - list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; - $statusCode = isset($values[6]) ? $values[6] : null; - - $itemTime = (int) $itemTime; - - if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) { - continue; - } - - if (!empty($start) && $itemTime < $start) { - continue; - } - - if (!empty($end) && $itemTime > $end) { - continue; - } - - $result[] = array( - 'token' => $itemToken, - 'ip' => $itemIp, - 'method' => $itemMethod, - 'url' => $itemUrl, - 'time' => $itemTime, - 'parent' => $itemParent, - 'status_code' => $statusCode, - ); - --$limit; - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function purge() - { - // delete only items from index - $indexName = $this->getIndexName(); - - $indexContent = $this->getValue($indexName, self::REDIS_SERIALIZER_NONE); - - if (!$indexContent) { - return false; - } - - $profileList = explode("\n", $indexContent); - - $result = array(); - - foreach ($profileList as $item) { - if ($item == '') { - continue; - } - - if (false !== $pos = strpos($item, "\t")) { - $result[] = $this->getItemName(substr($item, 0, $pos)); - } - } - - $result[] = $indexName; - - return $this->delete($result); - } - - /** - * {@inheritdoc} - */ - public function read($token) - { - if (empty($token)) { - return false; - } - - $profile = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP); - - if (false !== $profile) { - $profile = $this->createProfileFromData($token, $profile); - } - - return $profile; - } - - /** - * {@inheritdoc} - */ - public function write(Profile $profile) - { - $data = array( - 'token' => $profile->getToken(), - 'parent' => $profile->getParentToken(), - 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), - 'data' => $profile->getCollectors(), - 'ip' => $profile->getIp(), - 'method' => $profile->getMethod(), - 'url' => $profile->getUrl(), - 'time' => $profile->getTime(), - ); - - $profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken())); - - if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime, self::REDIS_SERIALIZER_PHP)) { - if (!$profileIndexed) { - // Add to index - $indexName = $this->getIndexName(); - - $indexRow = implode("\t", array( - $profile->getToken(), - $profile->getIp(), - $profile->getMethod(), - $profile->getUrl(), - $profile->getTime(), - $profile->getParentToken(), - $profile->getStatusCode(), - ))."\n"; - - return $this->appendValue($indexName, $indexRow, $this->lifetime); - } - - return true; - } - - return false; - } - - /** - * Internal convenience method that returns the instance of Redis. - * - * @return \Redis - * - * @throws \RuntimeException - */ - protected function getRedis() - { - if (null === $this->redis) { - $data = parse_url($this->dsn); - - if (false === $data || !isset($data['scheme']) || $data['scheme'] !== 'redis' || !isset($data['host']) || !isset($data['port'])) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Redis with an invalid dsn "%s". The minimal expected format is "redis://[host]:port".', $this->dsn)); - } - - if (!extension_loaded('redis')) { - throw new \RuntimeException('RedisProfilerStorage requires that the redis extension is loaded.'); - } - - $redis = new \Redis(); - $redis->connect($data['host'], $data['port']); - - if (isset($data['path'])) { - $redis->select(substr($data['path'], 1)); - } - - if (isset($data['pass'])) { - $redis->auth($data['pass']); - } - - $redis->setOption(self::REDIS_OPT_PREFIX, self::TOKEN_PREFIX); - - $this->redis = $redis; - } - - return $this->redis; - } - - /** - * Set instance of the Redis. - * - * @param \Redis $redis - */ - public function setRedis($redis) - { - $this->redis = $redis; - } - - private function createProfileFromData($token, $data, $parent = null) - { - $profile = new Profile($token); - $profile->setIp($data['ip']); - $profile->setMethod($data['method']); - $profile->setUrl($data['url']); - $profile->setTime($data['time']); - $profile->setCollectors($data['data']); - - if (!$parent && $data['parent']) { - $parent = $this->read($data['parent']); - } - - if ($parent) { - $profile->setParent($parent); - } - - foreach ($data['children'] as $token) { - if (!$token) { - continue; - } - - if (!$childProfileData = $this->getValue($this->getItemName($token), self::REDIS_SERIALIZER_PHP)) { - continue; - } - - $profile->addChild($this->createProfileFromData($token, $childProfileData, $profile)); - } - - return $profile; - } - - /** - * Gets the item name. - * - * @param string $token - * - * @return string - */ - private function getItemName($token) - { - $name = $token; - - if ($this->isItemNameValid($name)) { - return $name; - } - - return false; - } - - /** - * Gets the name of the index. - * - * @return string - */ - private function getIndexName() - { - $name = 'index'; - - if ($this->isItemNameValid($name)) { - return $name; - } - - return false; - } - - private function isItemNameValid($name) - { - $length = strlen($name); - - if ($length > 2147483648) { - throw new \RuntimeException(sprintf('The Redis item key "%s" is too long (%s bytes). Allowed maximum size is 2^31 bytes.', $name, $length)); - } - - return true; - } - - /** - * Retrieves an item from the Redis server. - * - * @param string $key - * @param int $serializer - * - * @return mixed - */ - private function getValue($key, $serializer = self::REDIS_SERIALIZER_NONE) - { - $redis = $this->getRedis(); - $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer); - - return $redis->get($key); - } - - /** - * Stores an item on the Redis server under the specified key. - * - * @param string $key - * @param mixed $value - * @param int $expiration - * @param int $serializer - * - * @return bool - */ - private function setValue($key, $value, $expiration = 0, $serializer = self::REDIS_SERIALIZER_NONE) - { - $redis = $this->getRedis(); - $redis->setOption(self::REDIS_OPT_SERIALIZER, $serializer); - - return $redis->setex($key, $expiration, $value); - } - - /** - * Appends data to an existing item on the Redis server. - * - * @param string $key - * @param string $value - * @param int $expiration - * - * @return bool - */ - private function appendValue($key, $value, $expiration = 0) - { - $redis = $this->getRedis(); - $redis->setOption(self::REDIS_OPT_SERIALIZER, self::REDIS_SERIALIZER_NONE); - - if ($redis->exists($key)) { - $redis->append($key, $value); - - return $redis->setTimeout($key, $expiration); - } - - return $redis->setex($key, $expiration, $value); - } - - /** - * Removes the specified keys. - * - * @param array $keys - * - * @return bool - */ - private function delete(array $keys) - { - return (bool) $this->getRedis()->delete($keys); - } -} diff --git a/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php b/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php deleted file mode 100644 index 7f3d9baa..00000000 --- a/vendor/symfony/http-kernel/Profiler/SqliteProfilerStorage.php +++ /dev/null @@ -1,144 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\HttpKernel\Profiler; - -@trigger_error('The '.__NAMESPACE__.'\SqliteProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED); - -/** - * SqliteProfilerStorage stores profiling information in a SQLite database. - * - * @author Fabien Potencier - * - * @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0. - * Use {@link FileProfilerStorage} instead. - */ -class SqliteProfilerStorage extends PdoProfilerStorage -{ - /** - * @throws \RuntimeException When neither of SQLite3 or PDO_SQLite extension is enabled - */ - protected function initDb() - { - if (null === $this->db || $this->db instanceof \SQLite3) { - if (0 !== strpos($this->dsn, 'sqlite')) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Sqlite with an invalid dsn "%s". The expected format is "sqlite:/path/to/the/db/file".', $this->dsn)); - } - if (class_exists('SQLite3')) { - $db = new \SQLite3(substr($this->dsn, 7, strlen($this->dsn)), \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE); - if (method_exists($db, 'busyTimeout')) { - // busyTimeout only exists for PHP >= 5.3.3 - $db->busyTimeout(1000); - } - } elseif (class_exists('PDO') && in_array('sqlite', \PDO::getAvailableDrivers(), true)) { - $db = new \PDO($this->dsn); - } else { - throw new \RuntimeException('You need to enable either the SQLite3 or PDO_SQLite extension for the profiler to run properly.'); - } - - $db->exec('PRAGMA temp_store=MEMORY; PRAGMA journal_mode=MEMORY;'); - $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token STRING, data STRING, ip STRING, method STRING, url STRING, time INTEGER, parent STRING, created_at INTEGER, status_code INTEGER)'); - $db->exec('CREATE INDEX IF NOT EXISTS data_created_at ON sf_profiler_data (created_at)'); - $db->exec('CREATE INDEX IF NOT EXISTS data_ip ON sf_profiler_data (ip)'); - $db->exec('CREATE INDEX IF NOT EXISTS data_method ON sf_profiler_data (method)'); - $db->exec('CREATE INDEX IF NOT EXISTS data_url ON sf_profiler_data (url)'); - $db->exec('CREATE INDEX IF NOT EXISTS data_parent ON sf_profiler_data (parent)'); - $db->exec('CREATE UNIQUE INDEX IF NOT EXISTS data_token ON sf_profiler_data (token)'); - - $this->db = $db; - } - - return $this->db; - } - - protected function exec($db, $query, array $args = array()) - { - if ($db instanceof \SQLite3) { - $stmt = $this->prepareStatement($db, $query); - foreach ($args as $arg => $val) { - $stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT); - } - - $res = $stmt->execute(); - if (false === $res) { - throw new \RuntimeException(sprintf('Error executing SQLite query "%s"', $query)); - } - $res->finalize(); - } else { - parent::exec($db, $query, $args); - } - } - - protected function fetch($db, $query, array $args = array()) - { - $return = array(); - - if ($db instanceof \SQLite3) { - $stmt = $this->prepareStatement($db, $query); - foreach ($args as $arg => $val) { - $stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT); - } - $res = $stmt->execute(); - while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { - $return[] = $row; - } - $res->finalize(); - $stmt->close(); - } else { - $return = parent::fetch($db, $query, $args); - } - - return $return; - } - - /** - * {@inheritdoc} - */ - protected function buildCriteria($ip, $url, $start, $end, $limit, $method) - { - $criteria = array(); - $args = array(); - - if ($ip = preg_replace('/[^\d\.]/', '', $ip)) { - $criteria[] = 'ip LIKE :ip'; - $args[':ip'] = '%'.$ip.'%'; - } - - if ($url) { - $criteria[] = 'url LIKE :url ESCAPE "\"'; - $args[':url'] = '%'.addcslashes($url, '%_\\').'%'; - } - - if ($method) { - $criteria[] = 'method = :method'; - $args[':method'] = $method; - } - - if (!empty($start)) { - $criteria[] = 'time >= :start'; - $args[':start'] = $start; - } - - if (!empty($end)) { - $criteria[] = 'time <= :end'; - $args[':end'] = $end; - } - - return array($criteria, $args); - } - - protected function close($db) - { - if ($db instanceof \SQLite3) { - $db->close(); - } - } -} diff --git a/vendor/symfony/http-kernel/composer.json b/vendor/symfony/http-kernel/composer.json index 13a89b71..b4e6f23e 100644 --- a/vendor/symfony/http-kernel/composer.json +++ b/vendor/symfony/http-kernel/composer.json @@ -16,31 +16,31 @@ } ], "require": { - "php": ">=5.3.9", - "symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0", - "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6", - "symfony/debug": "~2.6,>=2.6.2", + "php": ">=5.5.9", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2", + "symfony/debug": "~2.8|~3.0", "psr/log": "~1.0" }, "require-dev": { - "symfony/browser-kit": "~2.3|~3.0.0", - "symfony/class-loader": "~2.1|~3.0.0", - "symfony/config": "~2.8", - "symfony/console": "~2.3|~3.0.0", - "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.8|~3.0.0", - "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/finder": "~2.0,>=2.0.5|~3.0.0", - "symfony/process": "~2.0,>=2.0.5|~3.0.0", - "symfony/routing": "~2.8|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0", - "symfony/templating": "~2.2|~3.0.0", - "symfony/translation": "~2.0,>=2.0.5|~3.0.0", - "symfony/var-dumper": "~2.6|~3.0.0" + "symfony/browser-kit": "~2.8|~3.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/console": "~2.8|~3.0", + "symfony/css-selector": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/dom-crawler": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0", + "symfony/routing": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", + "symfony/templating": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/var-dumper": "~3.2" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "suggest": { "symfony/browser-kit": "", @@ -60,7 +60,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/http-kernel/phpunit.xml.dist b/vendor/symfony/http-kernel/phpunit.xml.dist index b29969b3..e0de769d 100644 --- a/vendor/symfony/http-kernel/phpunit.xml.dist +++ b/vendor/symfony/http-kernel/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/polyfill-apcu/LICENSE b/vendor/symfony/polyfill-apcu/LICENSE deleted file mode 100644 index 0564c5a9..00000000 --- a/vendor/symfony/polyfill-apcu/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2016 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/symfony/polyfill-apcu/README.md b/vendor/symfony/polyfill-apcu/README.md deleted file mode 100644 index e614bcab..00000000 --- a/vendor/symfony/polyfill-apcu/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Symfony Polyfill / APCu -======================== - -This component provides `apcu_*` functions and the `APCUIterator` class to users of the legacy APC extension. - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-apcu/bootstrap.php b/vendor/symfony/polyfill-apcu/bootstrap.php deleted file mode 100644 index a5682af5..00000000 --- a/vendor/symfony/polyfill-apcu/bootstrap.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (!extension_loaded('apc')) { - return; -} - -if (!function_exists('apcu_add')) { - function apcu_add($key, $var = null, $ttl = 0) { return apc_add($key, $var, $ttl); } - function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } - function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } - function apcu_clear_cache() { return apc_clear_cache('user'); } - function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } - function apcu_delete($key) { return apc_delete($key); } - function apcu_exists($keys) { return apc_exists($keys); } - function apcu_fetch($key, &$success = false) { return apc_fetch($key, $success); } - function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } - function apcu_sma_info($limited = false) { return apc_sma_info($limited); } - function apcu_store($key, $var = null, $ttl = 0) { return apc_store($key, $var, $ttl); } -} - -if (!class_exists('APCUIterator', false) && class_exists('APCIterator', false)) { - class APCUIterator extends APCIterator - { - public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) - { - parent::__construct('user', $search, $format, $chunk_size, $list); - } - } -} diff --git a/vendor/symfony/polyfill-apcu/composer.json b/vendor/symfony/polyfill-apcu/composer.json deleted file mode 100644 index cb8df8bd..00000000 --- a/vendor/symfony/polyfill-apcu/composer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "symfony/polyfill-apcu", - "type": "library", - "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable", "apcu"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=5.3.3" - }, - "autoload": { - "files": [ "bootstrap.php" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - } -} diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.big5.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.big5.ser deleted file mode 100644 index 379bc53f..00000000 --- a/vendor/symfony/polyfill-iconv/Resources/charset/from.big5.ser +++ /dev/null @@ -1 +0,0 @@ -a:13710:{s:2:"¡@";s:3:" ";s:2:"¡A";s:3:",";s:2:"¡B";s:3:"ã€";s:2:"¡C";s:3:"。";s:2:"¡D";s:3:".";s:2:"¡E";s:3:"•";s:2:"¡F";s:3:"ï¼›";s:2:"¡G";s:3:":";s:2:"¡H";s:3:"?";s:2:"¡I";s:3:"ï¼";s:2:"¡J";s:3:"︰";s:2:"¡K";s:3:"…";s:2:"¡L";s:3:"‥";s:2:"¡M";s:3:"ï¹";s:2:"¡N";s:3:"、";s:2:"¡O";s:3:"ï¹’";s:2:"¡P";s:2:"·";s:2:"¡Q";s:3:"ï¹”";s:2:"¡R";s:3:"﹕";s:2:"¡S";s:3:"ï¹–";s:2:"¡T";s:3:"ï¹—";s:2:"¡U";s:3:"|";s:2:"¡V";s:3:"–";s:2:"¡W";s:3:"︱";s:2:"¡X";s:3:"—";s:2:"¡Y";s:3:"︳";s:2:"¡Z";s:3:"�";s:2:"¡[";s:3:"︴";s:2:"¡\";s:3:"ï¹";s:2:"¡]";s:3:"(";s:2:"¡^";s:3:")";s:2:"¡_";s:3:"︵";s:2:"¡`";s:3:"︶";s:2:"¡a";s:3:"ï½›";s:2:"¡b";s:3:"ï½";s:2:"¡c";s:3:"︷";s:2:"¡d";s:3:"︸";s:2:"¡e";s:3:"〔";s:2:"¡f";s:3:"〕";s:2:"¡g";s:3:"︹";s:2:"¡h";s:3:"︺";s:2:"¡i";s:3:"ã€";s:2:"¡j";s:3:"】";s:2:"¡k";s:3:"︻";s:2:"¡l";s:3:"︼";s:2:"¡m";s:3:"《";s:2:"¡n";s:3:"》";s:2:"¡o";s:3:"︽";s:2:"¡p";s:3:"︾";s:2:"¡q";s:3:"〈";s:2:"¡r";s:3:"〉";s:2:"¡s";s:3:"︿";s:2:"¡t";s:3:"ï¹€";s:2:"¡u";s:3:"「";s:2:"¡v";s:3:"ã€";s:2:"¡w";s:3:"ï¹";s:2:"¡x";s:3:"﹂";s:2:"¡y";s:3:"『";s:2:"¡z";s:3:"ã€";s:2:"¡{";s:3:"﹃";s:2:"¡|";s:3:"﹄";s:2:"¡}";s:3:"ï¹™";s:2:"¡~";s:3:"﹚";s:2:"¡¡";s:3:"ï¹›";s:2:"¡¢";s:3:"﹜";s:2:"¡£";s:3:"ï¹";s:2:"¡¤";s:3:"﹞";s:2:"¡¥";s:3:"‘";s:2:"¡¦";s:3:"’";s:2:"¡§";s:3:"“";s:2:"¡¨";s:3:"â€";s:2:"¡©";s:3:"ã€";s:2:"¡ª";s:3:"〞";s:2:"¡«";s:3:"‵";s:2:"¡¬";s:3:"′";s:2:"¡­";s:3:"#";s:2:"¡®";s:3:"&";s:2:"¡¯";s:3:"*";s:2:"¡°";s:3:"※";s:2:"¡±";s:2:"§";s:2:"¡²";s:3:"〃";s:2:"¡³";s:3:"â—‹";s:2:"¡´";s:3:"â—";s:2:"¡µ";s:3:"â–³";s:2:"¡¶";s:3:"â–²";s:2:"¡·";s:3:"â—Ž";s:2:"¡¸";s:3:"☆";s:2:"¡¹";s:3:"★";s:2:"¡º";s:3:"â—‡";s:2:"¡»";s:3:"â—†";s:2:"¡¼";s:3:"â–¡";s:2:"¡½";s:3:"â– ";s:2:"¡¾";s:3:"â–½";s:2:"¡¿";s:3:"â–¼";s:2:"¡À";s:3:"㊣";s:2:"¡Á";s:3:"â„…";s:2:"¡Â";s:3:"‾";s:2:"¡Ã";s:3:"�";s:2:"¡Ä";s:3:"_";s:2:"¡Å";s:3:"�";s:2:"¡Æ";s:3:"﹉";s:2:"¡Ç";s:3:"﹊";s:2:"¡È";s:3:"ï¹";s:2:"¡É";s:3:"﹎";s:2:"¡Ê";s:3:"﹋";s:2:"¡Ë";s:3:"﹌";s:2:"¡Ì";s:3:"﹟";s:2:"¡Í";s:3:"ï¹ ";s:2:"¡Î";s:3:"﹡";s:2:"¡Ï";s:3:"+";s:2:"¡Ð";s:3:"ï¼";s:2:"¡Ñ";s:2:"×";s:2:"¡Ò";s:2:"÷";s:2:"¡Ó";s:2:"±";s:2:"¡Ô";s:3:"√";s:2:"¡Õ";s:3:"<";s:2:"¡Ö";s:3:">";s:2:"¡×";s:3:"ï¼";s:2:"¡Ø";s:3:"≦";s:2:"¡Ù";s:3:"≧";s:2:"¡Ú";s:3:"≠";s:2:"¡Û";s:3:"∞";s:2:"¡Ü";s:3:"≒";s:2:"¡Ý";s:3:"≡";s:2:"¡Þ";s:3:"ï¹¢";s:2:"¡ß";s:3:"ï¹£";s:2:"¡à";s:3:"﹤";s:2:"¡á";s:3:"ï¹¥";s:2:"¡â";s:3:"﹦";s:2:"¡ã";s:3:"∼";s:2:"¡ä";s:3:"∩";s:2:"¡å";s:3:"∪";s:2:"¡æ";s:3:"⊥";s:2:"¡ç";s:3:"∠";s:2:"¡è";s:3:"∟";s:2:"¡é";s:3:"⊿";s:2:"¡ê";s:3:"ã’";s:2:"¡ë";s:3:"ã‘";s:2:"¡ì";s:3:"∫";s:2:"¡í";s:3:"∮";s:2:"¡î";s:3:"∵";s:2:"¡ï";s:3:"∴";s:2:"¡ð";s:3:"♀";s:2:"¡ñ";s:3:"♂";s:2:"¡ò";s:3:"â™";s:2:"¡ó";s:3:"☉";s:2:"¡ô";s:3:"↑";s:2:"¡õ";s:3:"↓";s:2:"¡ö";s:3:"â†";s:2:"¡÷";s:3:"→";s:2:"¡ø";s:3:"↖";s:2:"¡ù";s:3:"↗";s:2:"¡ú";s:3:"↙";s:2:"¡û";s:3:"↘";s:2:"¡ü";s:3:"∥";s:2:"¡ý";s:3:"∣";s:2:"¡þ";s:3:"�";s:2:"¢@";s:3:"�";s:2:"¢A";s:3:"ï¼";s:2:"¢B";s:3:"ï¼¼";s:2:"¢C";s:3:"$";s:2:"¢D";s:2:"Â¥";s:2:"¢E";s:3:"〒";s:2:"¢F";s:2:"¢";s:2:"¢G";s:2:"£";s:2:"¢H";s:3:"ï¼…";s:2:"¢I";s:3:"ï¼ ";s:2:"¢J";s:3:"℃";s:2:"¢K";s:3:"℉";s:2:"¢L";s:3:"﹩";s:2:"¢M";s:3:"﹪";s:2:"¢N";s:3:"﹫";s:2:"¢O";s:3:"ã•";s:2:"¢P";s:3:"㎜";s:2:"¢Q";s:3:"ãŽ";s:2:"¢R";s:3:"㎞";s:2:"¢S";s:3:"ãŽ";s:2:"¢T";s:3:"㎡";s:2:"¢U";s:3:"㎎";s:2:"¢V";s:3:"ãŽ";s:2:"¢W";s:3:"ã„";s:2:"¢X";s:2:"°";s:2:"¢Y";s:3:"å…™";s:2:"¢Z";s:3:"å…›";s:2:"¢[";s:3:"å…ž";s:2:"¢\";s:3:"å…";s:2:"¢]";s:3:"å…¡";s:2:"¢^";s:3:"å…£";s:2:"¢_";s:3:"å—§";s:2:"¢`";s:3:"ç“©";s:2:"¢a";s:3:"糎";s:2:"¢b";s:3:"â–";s:2:"¢c";s:3:"â–‚";s:2:"¢d";s:3:"â–ƒ";s:2:"¢e";s:3:"â–„";s:2:"¢f";s:3:"â–…";s:2:"¢g";s:3:"â–†";s:2:"¢h";s:3:"â–‡";s:2:"¢i";s:3:"â–ˆ";s:2:"¢j";s:3:"â–";s:2:"¢k";s:3:"â–Ž";s:2:"¢l";s:3:"â–";s:2:"¢m";s:3:"â–Œ";s:2:"¢n";s:3:"â–‹";s:2:"¢o";s:3:"â–Š";s:2:"¢p";s:3:"â–‰";s:2:"¢q";s:3:"┼";s:2:"¢r";s:3:"â”´";s:2:"¢s";s:3:"┬";s:2:"¢t";s:3:"┤";s:2:"¢u";s:3:"├";s:2:"¢v";s:3:"â–”";s:2:"¢w";s:3:"─";s:2:"¢x";s:3:"│";s:2:"¢y";s:3:"â–•";s:2:"¢z";s:3:"┌";s:2:"¢{";s:3:"â”";s:2:"¢|";s:3:"â””";s:2:"¢}";s:3:"┘";s:2:"¢~";s:3:"â•­";s:2:"¢¡";s:3:"â•®";s:2:"¢¢";s:3:"â•°";s:2:"¢£";s:3:"╯";s:2:"¢¤";s:3:"â•";s:2:"¢¥";s:3:"╞";s:2:"¢¦";s:3:"╪";s:2:"¢§";s:3:"â•¡";s:2:"¢¨";s:3:"â—¢";s:2:"¢©";s:3:"â—£";s:2:"¢ª";s:3:"â—¥";s:2:"¢«";s:3:"â—¤";s:2:"¢¬";s:3:"╱";s:2:"¢­";s:3:"╲";s:2:"¢®";s:3:"╳";s:2:"¢¯";s:3:"ï¼";s:2:"¢°";s:3:"1";s:2:"¢±";s:3:"ï¼’";s:2:"¢²";s:3:"3";s:2:"¢³";s:3:"ï¼”";s:2:"¢´";s:3:"5";s:2:"¢µ";s:3:"ï¼–";s:2:"¢¶";s:3:"ï¼—";s:2:"¢·";s:3:"8";s:2:"¢¸";s:3:"ï¼™";s:2:"¢¹";s:3:"â… ";s:2:"¢º";s:3:"â…¡";s:2:"¢»";s:3:"â…¢";s:2:"¢¼";s:3:"â…£";s:2:"¢½";s:3:"â…¤";s:2:"¢¾";s:3:"â…¥";s:2:"¢¿";s:3:"â…¦";s:2:"¢À";s:3:"â…§";s:2:"¢Á";s:3:"â…¨";s:2:"¢Â";s:3:"â…©";s:2:"¢Ã";s:3:"〡";s:2:"¢Ä";s:3:"〢";s:2:"¢Å";s:3:"〣";s:2:"¢Æ";s:3:"〤";s:2:"¢Ç";s:3:"〥";s:2:"¢È";s:3:"〦";s:2:"¢É";s:3:"〧";s:2:"¢Ê";s:3:"〨";s:2:"¢Ë";s:3:"〩";s:2:"¢Ì";s:3:"�";s:2:"¢Í";s:3:"å„";s:2:"¢Î";s:3:"�";s:2:"¢Ï";s:3:"A";s:2:"¢Ð";s:3:"ï¼¢";s:2:"¢Ñ";s:3:"ï¼£";s:2:"¢Ò";s:3:"D";s:2:"¢Ó";s:3:"ï¼¥";s:2:"¢Ô";s:3:"F";s:2:"¢Õ";s:3:"ï¼§";s:2:"¢Ö";s:3:"H";s:2:"¢×";s:3:"I";s:2:"¢Ø";s:3:"J";s:2:"¢Ù";s:3:"K";s:2:"¢Ú";s:3:"L";s:2:"¢Û";s:3:"ï¼­";s:2:"¢Ü";s:3:"ï¼®";s:2:"¢Ý";s:3:"O";s:2:"¢Þ";s:3:"ï¼°";s:2:"¢ß";s:3:"ï¼±";s:2:"¢à";s:3:"ï¼²";s:2:"¢á";s:3:"ï¼³";s:2:"¢â";s:3:"ï¼´";s:2:"¢ã";s:3:"ï¼µ";s:2:"¢ä";s:3:"ï¼¶";s:2:"¢å";s:3:"ï¼·";s:2:"¢æ";s:3:"X";s:2:"¢ç";s:3:"ï¼¹";s:2:"¢è";s:3:"Z";s:2:"¢é";s:3:"ï½";s:2:"¢ê";s:3:"b";s:2:"¢ë";s:3:"c";s:2:"¢ì";s:3:"d";s:2:"¢í";s:3:"ï½…";s:2:"¢î";s:3:"f";s:2:"¢ï";s:3:"g";s:2:"¢ð";s:3:"h";s:2:"¢ñ";s:3:"i";s:2:"¢ò";s:3:"j";s:2:"¢ó";s:3:"k";s:2:"¢ô";s:3:"l";s:2:"¢õ";s:3:"ï½";s:2:"¢ö";s:3:"n";s:2:"¢÷";s:3:"ï½";s:2:"¢ø";s:3:"ï½";s:2:"¢ù";s:3:"q";s:2:"¢ú";s:3:"ï½’";s:2:"¢û";s:3:"s";s:2:"¢ü";s:3:"ï½”";s:2:"¢ý";s:3:"u";s:2:"¢þ";s:3:"ï½–";s:2:"£@";s:3:"ï½—";s:2:"£A";s:3:"x";s:2:"£B";s:3:"ï½™";s:2:"£C";s:3:"z";s:2:"£D";s:2:"Α";s:2:"£E";s:2:"Î’";s:2:"£F";s:2:"Γ";s:2:"£G";s:2:"Δ";s:2:"£H";s:2:"Ε";s:2:"£I";s:2:"Ζ";s:2:"£J";s:2:"Η";s:2:"£K";s:2:"Θ";s:2:"£L";s:2:"Ι";s:2:"£M";s:2:"Κ";s:2:"£N";s:2:"Λ";s:2:"£O";s:2:"Μ";s:2:"£P";s:2:"Î";s:2:"£Q";s:2:"Ξ";s:2:"£R";s:2:"Ο";s:2:"£S";s:2:"Π";s:2:"£T";s:2:"Ρ";s:2:"£U";s:2:"Σ";s:2:"£V";s:2:"Τ";s:2:"£W";s:2:"Î¥";s:2:"£X";s:2:"Φ";s:2:"£Y";s:2:"Χ";s:2:"£Z";s:2:"Ψ";s:2:"£[";s:2:"Ω";s:2:"£\";s:2:"α";s:2:"£]";s:2:"β";s:2:"£^";s:2:"γ";s:2:"£_";s:2:"δ";s:2:"£`";s:2:"ε";s:2:"£a";s:2:"ζ";s:2:"£b";s:2:"η";s:2:"£c";s:2:"θ";s:2:"£d";s:2:"ι";s:2:"£e";s:2:"κ";s:2:"£f";s:2:"λ";s:2:"£g";s:2:"μ";s:2:"£h";s:2:"ν";s:2:"£i";s:2:"ξ";s:2:"£j";s:2:"ο";s:2:"£k";s:2:"Ï€";s:2:"£l";s:2:"Ï";s:2:"£m";s:2:"σ";s:2:"£n";s:2:"Ï„";s:2:"£o";s:2:"Ï…";s:2:"£p";s:2:"φ";s:2:"£q";s:2:"χ";s:2:"£r";s:2:"ψ";s:2:"£s";s:2:"ω";s:2:"£t";s:3:"ã„…";s:2:"£u";s:3:"ㄆ";s:2:"£v";s:3:"ㄇ";s:2:"£w";s:3:"ㄈ";s:2:"£x";s:3:"ㄉ";s:2:"£y";s:3:"ㄊ";s:2:"£z";s:3:"ã„‹";s:2:"£{";s:3:"ㄌ";s:2:"£|";s:3:"ã„";s:2:"£}";s:3:"ㄎ";s:2:"£~";s:3:"ã„";s:2:"£¡";s:3:"ã„";s:2:"£¢";s:3:"ã„‘";s:2:"££";s:3:"ã„’";s:2:"£¤";s:3:"ã„“";s:2:"£¥";s:3:"ã„”";s:2:"£¦";s:3:"ã„•";s:2:"£§";s:3:"ã„–";s:2:"£¨";s:3:"ã„—";s:2:"£©";s:3:"ㄘ";s:2:"£ª";s:3:"ã„™";s:2:"£«";s:3:"ㄚ";s:2:"£¬";s:3:"ã„›";s:2:"£­";s:3:"ㄜ";s:2:"£®";s:3:"ã„";s:2:"£¯";s:3:"ㄞ";s:2:"£°";s:3:"ㄟ";s:2:"£±";s:3:"ã„ ";s:2:"£²";s:3:"ã„¡";s:2:"£³";s:3:"ã„¢";s:2:"£´";s:3:"ã„£";s:2:"£µ";s:3:"ㄤ";s:2:"£¶";s:3:"ã„¥";s:2:"£·";s:3:"ㄦ";s:2:"£¸";s:3:"ã„§";s:2:"£¹";s:3:"ㄨ";s:2:"£º";s:3:"ã„©";s:2:"£»";s:2:"Ë™";s:2:"£¼";s:2:"ˉ";s:2:"£½";s:2:"ËŠ";s:2:"£¾";s:2:"ˇ";s:2:"£¿";s:2:"Ë‹";s:2:"¤@";s:3:"一";s:2:"¤A";s:3:"ä¹™";s:2:"¤B";s:3:"ä¸";s:2:"¤C";s:3:"七";s:2:"¤D";s:3:"乃";s:2:"¤E";s:3:"ä¹";s:2:"¤F";s:3:"了";s:2:"¤G";s:3:"二";s:2:"¤H";s:3:"人";s:2:"¤I";s:3:"å„¿";s:2:"¤J";s:3:"å…¥";s:2:"¤K";s:3:"å…«";s:2:"¤L";s:3:"几";s:2:"¤M";s:3:"刀";s:2:"¤N";s:3:"åˆ";s:2:"¤O";s:3:"力";s:2:"¤P";s:3:"匕";s:2:"¤Q";s:3:"å";s:2:"¤R";s:3:"åœ";s:2:"¤S";s:3:"åˆ";s:2:"¤T";s:3:"三";s:2:"¤U";s:3:"下";s:2:"¤V";s:3:"丈";s:2:"¤W";s:3:"上";s:2:"¤X";s:3:"丫";s:2:"¤Y";s:3:"丸";s:2:"¤Z";s:3:"凡";s:2:"¤[";s:3:"ä¹…";s:2:"¤\";s:3:"么";s:2:"¤]";s:3:"也";s:2:"¤^";s:3:"乞";s:2:"¤_";s:3:"于";s:2:"¤`";s:3:"亡";s:2:"¤a";s:3:"å…€";s:2:"¤b";s:3:"刃";s:2:"¤c";s:3:"勺";s:2:"¤d";s:3:"åƒ";s:2:"¤e";s:3:"å‰";s:2:"¤f";s:3:"å£";s:2:"¤g";s:3:"土";s:2:"¤h";s:3:"士";s:2:"¤i";s:3:"夕";s:2:"¤j";s:3:"大";s:2:"¤k";s:3:"女";s:2:"¤l";s:3:"å­";s:2:"¤m";s:3:"å­‘";s:2:"¤n";s:3:"å­“";s:2:"¤o";s:3:"寸";s:2:"¤p";s:3:"å°";s:2:"¤q";s:3:"å°¢";s:2:"¤r";s:3:"å°¸";s:2:"¤s";s:3:"å±±";s:2:"¤t";s:3:"å·";s:2:"¤u";s:3:"å·¥";s:2:"¤v";s:3:"å·±";s:2:"¤w";s:3:"å·²";s:2:"¤x";s:3:"å·³";s:2:"¤y";s:3:"å·¾";s:2:"¤z";s:3:"å¹²";s:2:"¤{";s:3:"廾";s:2:"¤|";s:3:"弋";s:2:"¤}";s:3:"弓";s:2:"¤~";s:3:"æ‰";s:2:"¤¡";s:3:"丑";s:2:"¤¢";s:3:"ä¸";s:2:"¤£";s:3:"ä¸";s:2:"¤¤";s:3:"中";s:2:"¤¥";s:3:"丰";s:2:"¤¦";s:3:"丹";s:2:"¤§";s:3:"之";s:2:"¤¨";s:3:"å°¹";s:2:"¤©";s:3:"予";s:2:"¤ª";s:3:"云";s:2:"¤«";s:3:"井";s:2:"¤¬";s:3:"互";s:2:"¤­";s:3:"五";s:2:"¤®";s:3:"亢";s:2:"¤¯";s:3:"ä»";s:2:"¤°";s:3:"什";s:2:"¤±";s:3:"仃";s:2:"¤²";s:3:"仆";s:2:"¤³";s:3:"仇";s:2:"¤´";s:3:"ä»";s:2:"¤µ";s:3:"今";s:2:"¤¶";s:3:"介";s:2:"¤·";s:3:"仄";s:2:"¤¸";s:3:"å…ƒ";s:2:"¤¹";s:3:"å…";s:2:"¤º";s:3:"å…§";s:2:"¤»";s:3:"å…­";s:2:"¤¼";s:3:"å…®";s:2:"¤½";s:3:"å…¬";s:2:"¤¾";s:3:"冗";s:2:"¤¿";s:3:"凶";s:2:"¤À";s:3:"分";s:2:"¤Á";s:3:"切";s:2:"¤Â";s:3:"刈";s:2:"¤Ã";s:3:"å‹»";s:2:"¤Ä";s:3:"勾";s:2:"¤Å";s:3:"å‹¿";s:2:"¤Æ";s:3:"化";s:2:"¤Ç";s:3:"匹";s:2:"¤È";s:3:"åˆ";s:2:"¤É";s:3:"å‡";s:2:"¤Ê";s:3:"å…";s:2:"¤Ë";s:3:"åž";s:2:"¤Ì";s:3:"厄";s:2:"¤Í";s:3:"å‹";s:2:"¤Î";s:3:"åŠ";s:2:"¤Ï";s:3:"å";s:2:"¤Ð";s:3:"壬";s:2:"¤Ñ";s:3:"天";s:2:"¤Ò";s:3:"夫";s:2:"¤Ó";s:3:"太";s:2:"¤Ô";s:3:"夭";s:2:"¤Õ";s:3:"å­”";s:2:"¤Ö";s:3:"å°‘";s:2:"¤×";s:3:"å°¤";s:2:"¤Ø";s:3:"å°º";s:2:"¤Ù";s:3:"屯";s:2:"¤Ú";s:3:"å·´";s:2:"¤Û";s:3:"å¹»";s:2:"¤Ü";s:3:"廿";s:2:"¤Ý";s:3:"å¼”";s:2:"¤Þ";s:3:"引";s:2:"¤ß";s:3:"心";s:2:"¤à";s:3:"戈";s:2:"¤á";s:3:"戶";s:2:"¤â";s:3:"手";s:2:"¤ã";s:3:"扎";s:2:"¤ä";s:3:"支";s:2:"¤å";s:3:"æ–‡";s:2:"¤æ";s:3:"æ–—";s:2:"¤ç";s:3:"æ–¤";s:2:"¤è";s:3:"æ–¹";s:2:"¤é";s:3:"æ—¥";s:2:"¤ê";s:3:"æ›°";s:2:"¤ë";s:3:"月";s:2:"¤ì";s:3:"木";s:2:"¤í";s:3:"欠";s:2:"¤î";s:3:"æ­¢";s:2:"¤ï";s:3:"æ­¹";s:2:"¤ð";s:3:"毋";s:2:"¤ñ";s:3:"比";s:2:"¤ò";s:3:"毛";s:2:"¤ó";s:3:"æ°";s:2:"¤ô";s:3:"æ°´";s:2:"¤õ";s:3:"ç«";s:2:"¤ö";s:3:"爪";s:2:"¤÷";s:3:"父";s:2:"¤ø";s:3:"爻";s:2:"¤ù";s:3:"片";s:2:"¤ú";s:3:"牙";s:2:"¤û";s:3:"牛";s:2:"¤ü";s:3:"犬";s:2:"¤ý";s:3:"王";s:2:"¤þ";s:3:"丙";s:2:"¥@";s:3:"世";s:2:"¥A";s:3:"丕";s:2:"¥B";s:3:"且";s:2:"¥C";s:3:"丘";s:2:"¥D";s:3:"主";s:2:"¥E";s:3:"ä¹";s:2:"¥F";s:3:"ä¹";s:2:"¥G";s:3:"乎";s:2:"¥H";s:3:"以";s:2:"¥I";s:3:"付";s:2:"¥J";s:3:"ä»”";s:2:"¥K";s:3:"仕";s:2:"¥L";s:3:"ä»–";s:2:"¥M";s:3:"ä»—";s:2:"¥N";s:3:"代";s:2:"¥O";s:3:"令";s:2:"¥P";s:3:"ä»™";s:2:"¥Q";s:3:"仞";s:2:"¥R";s:3:"å……";s:2:"¥S";s:3:"å…„";s:2:"¥T";s:3:"冉";s:2:"¥U";s:3:"冊";s:2:"¥V";s:3:"冬";s:2:"¥W";s:3:"凹";s:2:"¥X";s:3:"出";s:2:"¥Y";s:3:"凸";s:2:"¥Z";s:3:"刊";s:2:"¥[";s:3:"加";s:2:"¥\";s:3:"功";s:2:"¥]";s:3:"包";s:2:"¥^";s:3:"匆";s:2:"¥_";s:3:"北";s:2:"¥`";s:3:"åŒ";s:2:"¥a";s:3:"仟";s:2:"¥b";s:3:"åŠ";s:2:"¥c";s:3:"å‰";s:2:"¥d";s:3:"å¡";s:2:"¥e";s:3:"å ";s:2:"¥f";s:3:"å¯";s:2:"¥g";s:3:"å®";s:2:"¥h";s:3:"去";s:2:"¥i";s:3:"å¯";s:2:"¥j";s:3:"å¤";s:2:"¥k";s:3:"å³";s:2:"¥l";s:3:"å¬";s:2:"¥m";s:3:"å®";s:2:"¥n";s:3:"å©";s:2:"¥o";s:3:"å¨";s:2:"¥p";s:3:"å¼";s:2:"¥q";s:3:"å¸";s:2:"¥r";s:3:"åµ";s:2:"¥s";s:3:"å«";s:2:"¥t";s:3:"å¦";s:2:"¥u";s:3:"åª";s:2:"¥v";s:3:"å²";s:2:"¥w";s:3:"å±";s:2:"¥x";s:3:"å°";s:2:"¥y";s:3:"å¥";s:2:"¥z";s:3:"å­";s:2:"¥{";s:3:"å»";s:2:"¥|";s:3:"å››";s:2:"¥}";s:3:"囚";s:2:"¥~";s:3:"外";s:2:"¥¡";s:3:"央";s:2:"¥¢";s:3:"失";s:2:"¥£";s:3:"奴";s:2:"¥¤";s:3:"奶";s:2:"¥¥";s:3:"å­•";s:2:"¥¦";s:3:"它";s:2:"¥§";s:3:"å°¼";s:2:"¥¨";s:3:"å·¨";s:2:"¥©";s:3:"å·§";s:2:"¥ª";s:3:"å·¦";s:2:"¥«";s:3:"市";s:2:"¥¬";s:3:"布";s:2:"¥­";s:3:"å¹³";s:2:"¥®";s:3:"å¹¼";s:2:"¥¯";s:3:"å¼";s:2:"¥°";s:3:"弘";s:2:"¥±";s:3:"å¼—";s:2:"¥²";s:3:"å¿…";s:2:"¥³";s:3:"戊";s:2:"¥´";s:3:"打";s:2:"¥µ";s:3:"扔";s:2:"¥¶";s:3:"扒";s:2:"¥·";s:3:"扑";s:2:"¥¸";s:3:"æ–¥";s:2:"¥¹";s:3:"æ—¦";s:2:"¥º";s:3:"朮";s:2:"¥»";s:3:"本";s:2:"¥¼";s:3:"未";s:2:"¥½";s:3:"末";s:2:"¥¾";s:3:"札";s:2:"¥¿";s:3:"æ­£";s:2:"¥À";s:3:"æ¯";s:2:"¥Á";s:3:"æ°‘";s:2:"¥Â";s:3:"æ°";s:2:"¥Ã";s:3:"æ°¸";s:2:"¥Ä";s:3:"æ±";s:2:"¥Å";s:3:"æ±€";s:2:"¥Æ";s:3:"æ°¾";s:2:"¥Ç";s:3:"犯";s:2:"¥È";s:3:"玄";s:2:"¥É";s:3:"玉";s:2:"¥Ê";s:3:"瓜";s:2:"¥Ë";s:3:"瓦";s:2:"¥Ì";s:3:"甘";s:2:"¥Í";s:3:"生";s:2:"¥Î";s:3:"用";s:2:"¥Ï";s:3:"甩";s:2:"¥Ð";s:3:"ç”°";s:2:"¥Ñ";s:3:"ç”±";s:2:"¥Ò";s:3:"甲";s:2:"¥Ó";s:3:"申";s:2:"¥Ô";s:3:"ç–‹";s:2:"¥Õ";s:3:"白";s:2:"¥Ö";s:3:"çš®";s:2:"¥×";s:3:"çš¿";s:2:"¥Ø";s:3:"ç›®";s:2:"¥Ù";s:3:"矛";s:2:"¥Ú";s:3:"矢";s:2:"¥Û";s:3:"石";s:2:"¥Ü";s:3:"示";s:2:"¥Ý";s:3:"禾";s:2:"¥Þ";s:3:"ç©´";s:2:"¥ß";s:3:"ç«‹";s:2:"¥à";s:3:"丞";s:2:"¥á";s:3:"丟";s:2:"¥â";s:3:"ä¹’";s:2:"¥ã";s:3:"乓";s:2:"¥ä";s:3:"乩";s:2:"¥å";s:3:"亙";s:2:"¥æ";s:3:"交";s:2:"¥ç";s:3:"亦";s:2:"¥è";s:3:"亥";s:2:"¥é";s:3:"仿";s:2:"¥ê";s:3:"伉";s:2:"¥ë";s:3:"ä¼™";s:2:"¥ì";s:3:"伊";s:2:"¥í";s:3:"伕";s:2:"¥î";s:3:"ä¼";s:2:"¥ï";s:3:"ä¼";s:2:"¥ð";s:3:"休";s:2:"¥ñ";s:3:"ä¼";s:2:"¥ò";s:3:"仲";s:2:"¥ó";s:3:"ä»¶";s:2:"¥ô";s:3:"ä»»";s:2:"¥õ";s:3:"ä»°";s:2:"¥ö";s:3:"仳";s:2:"¥÷";s:3:"份";s:2:"¥ø";s:3:"ä¼";s:2:"¥ù";s:3:"伋";s:2:"¥ú";s:3:"å…‰";s:2:"¥û";s:3:"å…‡";s:2:"¥ü";s:3:"å…†";s:2:"¥ý";s:3:"å…ˆ";s:2:"¥þ";s:3:"å…¨";s:2:"¦@";s:3:"å…±";s:2:"¦A";s:3:"å†";s:2:"¦B";s:3:"冰";s:2:"¦C";s:3:"列";s:2:"¦D";s:3:"刑";s:2:"¦E";s:3:"划";s:2:"¦F";s:3:"刎";s:2:"¦G";s:3:"刖";s:2:"¦H";s:3:"劣";s:2:"¦I";s:3:"匈";s:2:"¦J";s:3:"匡";s:2:"¦K";s:3:"匠";s:2:"¦L";s:3:"å°";s:2:"¦M";s:3:"å±";s:2:"¦N";s:3:"å‰";s:2:"¦O";s:3:"å";s:2:"¦P";s:3:"åŒ";s:2:"¦Q";s:3:"åŠ";s:2:"¦R";s:3:"å";s:2:"¦S";s:3:"å";s:2:"¦T";s:3:"å‹";s:2:"¦U";s:3:"å„";s:2:"¦V";s:3:"å‘";s:2:"¦W";s:3:"å";s:2:"¦X";s:3:"åˆ";s:2:"¦Y";s:3:"åƒ";s:2:"¦Z";s:3:"åŽ";s:2:"¦[";s:3:"å†";s:2:"¦\";s:3:"å’";s:2:"¦]";s:3:"å› ";s:2:"¦^";s:3:"回";s:2:"¦_";s:3:"å›";s:2:"¦`";s:3:"圳";s:2:"¦a";s:3:"地";s:2:"¦b";s:3:"在";s:2:"¦c";s:3:"圭";s:2:"¦d";s:3:"圬";s:2:"¦e";s:3:"圯";s:2:"¦f";s:3:"圩";s:2:"¦g";s:3:"夙";s:2:"¦h";s:3:"多";s:2:"¦i";s:3:"夷";s:2:"¦j";s:3:"夸";s:2:"¦k";s:3:"妄";s:2:"¦l";s:3:"奸";s:2:"¦m";s:3:"妃";s:2:"¦n";s:3:"好";s:2:"¦o";s:3:"她";s:2:"¦p";s:3:"如";s:2:"¦q";s:3:"å¦";s:2:"¦r";s:3:"å­—";s:2:"¦s";s:3:"å­˜";s:2:"¦t";s:3:"宇";s:2:"¦u";s:3:"守";s:2:"¦v";s:3:"å®…";s:2:"¦w";s:3:"安";s:2:"¦x";s:3:"寺";s:2:"¦y";s:3:"å°–";s:2:"¦z";s:3:"å±¹";s:2:"¦{";s:3:"å·ž";s:2:"¦|";s:3:"帆";s:2:"¦}";s:3:"å¹¶";s:2:"¦~";s:3:"å¹´";s:2:"¦¡";s:3:"å¼";s:2:"¦¢";s:3:"å¼›";s:2:"¦£";s:3:"å¿™";s:2:"¦¤";s:3:"å¿–";s:2:"¦¥";s:3:"戎";s:2:"¦¦";s:3:"戌";s:2:"¦§";s:3:"æˆ";s:2:"¦¨";s:3:"æˆ";s:2:"¦©";s:3:"扣";s:2:"¦ª";s:3:"扛";s:2:"¦«";s:3:"托";s:2:"¦¬";s:3:"æ”¶";s:2:"¦­";s:3:"æ—©";s:2:"¦®";s:3:"æ—¨";s:2:"¦¯";s:3:"æ—¬";s:2:"¦°";s:3:"æ—­";s:2:"¦±";s:3:"曲";s:2:"¦²";s:3:"曳";s:2:"¦³";s:3:"有";s:2:"¦´";s:3:"朽";s:2:"¦µ";s:3:"朴";s:2:"¦¶";s:3:"朱";s:2:"¦·";s:3:"朵";s:2:"¦¸";s:3:"次";s:2:"¦¹";s:3:"æ­¤";s:2:"¦º";s:3:"æ­»";s:2:"¦»";s:3:"æ°–";s:2:"¦¼";s:3:"æ±";s:2:"¦½";s:3:"æ±—";s:2:"¦¾";s:3:"æ±™";s:2:"¦¿";s:3:"江";s:2:"¦À";s:3:"æ± ";s:2:"¦Á";s:3:"æ±";s:2:"¦Â";s:3:"汕";s:2:"¦Ã";s:3:"污";s:2:"¦Ä";s:3:"æ±›";s:2:"¦Å";s:3:"æ±";s:2:"¦Æ";s:3:"汎";s:2:"¦Ç";s:3:"ç°";s:2:"¦È";s:3:"牟";s:2:"¦É";s:3:"ç‰";s:2:"¦Ê";s:3:"百";s:2:"¦Ë";s:3:"竹";s:2:"¦Ì";s:3:"ç±³";s:2:"¦Í";s:3:"糸";s:2:"¦Î";s:3:"ç¼¶";s:2:"¦Ï";s:3:"羊";s:2:"¦Ð";s:3:"ç¾½";s:2:"¦Ñ";s:3:"è€";s:2:"¦Ò";s:3:"考";s:2:"¦Ó";s:3:"而";s:2:"¦Ô";s:3:"耒";s:2:"¦Õ";s:3:"耳";s:2:"¦Ö";s:3:"è¿";s:2:"¦×";s:3:"肉";s:2:"¦Ø";s:3:"è‚‹";s:2:"¦Ù";s:3:"肌";s:2:"¦Ú";s:3:"臣";s:2:"¦Û";s:3:"自";s:2:"¦Ü";s:3:"至";s:2:"¦Ý";s:3:"臼";s:2:"¦Þ";s:3:"舌";s:2:"¦ß";s:3:"舛";s:2:"¦à";s:3:"舟";s:2:"¦á";s:3:"艮";s:2:"¦â";s:3:"色";s:2:"¦ã";s:3:"艾";s:2:"¦ä";s:3:"虫";s:2:"¦å";s:3:"è¡€";s:2:"¦æ";s:3:"行";s:2:"¦ç";s:3:"è¡£";s:2:"¦è";s:3:"西";s:2:"¦é";s:3:"阡";s:2:"¦ê";s:3:"串";s:2:"¦ë";s:3:"亨";s:2:"¦ì";s:3:"ä½";s:2:"¦í";s:3:"ä½";s:2:"¦î";s:3:"佇";s:2:"¦ï";s:3:"ä½—";s:2:"¦ð";s:3:"佞";s:2:"¦ñ";s:3:"ä¼´";s:2:"¦ò";s:3:"ä½›";s:2:"¦ó";s:3:"何";s:2:"¦ô";s:3:"ä¼°";s:2:"¦õ";s:3:"ä½";s:2:"¦ö";s:3:"佑";s:2:"¦÷";s:3:"ä¼½";s:2:"¦ø";s:3:"伺";s:2:"¦ù";s:3:"伸";s:2:"¦ú";s:3:"佃";s:2:"¦û";s:3:"ä½”";s:2:"¦ü";s:3:"ä¼¼";s:2:"¦ý";s:3:"但";s:2:"¦þ";s:3:"ä½£";s:2:"§@";s:3:"作";s:2:"§A";s:3:"ä½ ";s:2:"§B";s:3:"伯";s:2:"§C";s:3:"低";s:2:"§D";s:3:"ä¼¶";s:2:"§E";s:3:"ä½™";s:2:"§F";s:3:"ä½";s:2:"§G";s:3:"佈";s:2:"§H";s:3:"佚";s:2:"§I";s:3:"å…Œ";s:2:"§J";s:3:"å…‹";s:2:"§K";s:3:"å…";s:2:"§L";s:3:"å…µ";s:2:"§M";s:3:"冶";s:2:"§N";s:3:"冷";s:2:"§O";s:3:"別";s:2:"§P";s:3:"判";s:2:"§Q";s:3:"利";s:2:"§R";s:3:"刪";s:2:"§S";s:3:"刨";s:2:"§T";s:3:"劫";s:2:"§U";s:3:"助";s:2:"§V";s:3:"努";s:2:"§W";s:3:"劬";s:2:"§X";s:3:"匣";s:2:"§Y";s:3:"å³";s:2:"§Z";s:3:"åµ";s:2:"§[";s:3:"å";s:2:"§\";s:3:"å­";s:2:"§]";s:3:"åž";s:2:"§^";s:3:"å¾";s:2:"§_";s:3:"å¦";s:2:"§`";s:3:"呎";s:2:"§a";s:3:"å§";s:2:"§b";s:3:"呆";s:2:"§c";s:3:"呃";s:2:"§d";s:3:"å³";s:2:"§e";s:3:"呈";s:2:"§f";s:3:"å‘‚";s:2:"§g";s:3:"å›";s:2:"§h";s:3:"å©";s:2:"§i";s:3:"告";s:2:"§j";s:3:"å¹";s:2:"§k";s:3:"å»";s:2:"§l";s:3:"å¸";s:2:"§m";s:3:"å®";s:2:"§n";s:3:"åµ";s:2:"§o";s:3:"å¶";s:2:"§p";s:3:"å ";s:2:"§q";s:3:"å¼";s:2:"§r";s:3:"å‘€";s:2:"§s";s:3:"å±";s:2:"§t";s:3:"å«";s:2:"§u";s:3:"åŸ";s:2:"§v";s:3:"å¬";s:2:"§w";s:3:"囪";s:2:"§x";s:3:"å›°";s:2:"§y";s:3:"囤";s:2:"§z";s:3:"囫";s:2:"§{";s:3:"åŠ";s:2:"§|";s:3:"å‘";s:2:"§}";s:3:"å€";s:2:"§~";s:3:"å";s:2:"§¡";s:3:"å‡";s:2:"§¢";s:3:"åŽ";s:2:"§£";s:3:"圾";s:2:"§¤";s:3:"å";s:2:"§¥";s:3:"å";s:2:"§¦";s:3:"圻";s:2:"§§";s:3:"壯";s:2:"§¨";s:3:"夾";s:2:"§©";s:3:"å¦";s:2:"§ª";s:3:"妒";s:2:"§«";s:3:"妨";s:2:"§¬";s:3:"妞";s:2:"§­";s:3:"妣";s:2:"§®";s:3:"妙";s:2:"§¯";s:3:"妖";s:2:"§°";s:3:"å¦";s:2:"§±";s:3:"妤";s:2:"§²";s:3:"妓";s:2:"§³";s:3:"妊";s:2:"§´";s:3:"妥";s:2:"§µ";s:3:"å­";s:2:"§¶";s:3:"å­œ";s:2:"§·";s:3:"å­š";s:2:"§¸";s:3:"å­›";s:2:"§¹";s:3:"完";s:2:"§º";s:3:"宋";s:2:"§»";s:3:"å®";s:2:"§¼";s:3:"å°¬";s:2:"§½";s:3:"å±€";s:2:"§¾";s:3:"å±";s:2:"§¿";s:3:"å°¿";s:2:"§À";s:3:"å°¾";s:2:"§Á";s:3:"å²";s:2:"§Â";s:3:"岑";s:2:"§Ã";s:3:"å²”";s:2:"§Ä";s:3:"岌";s:2:"§Å";s:3:"å·«";s:2:"§Æ";s:3:"希";s:2:"§Ç";s:3:"åº";s:2:"§È";s:3:"庇";s:2:"§É";s:3:"床";s:2:"§Ê";s:3:"å»·";s:2:"§Ë";s:3:"弄";s:2:"§Ì";s:3:"弟";s:2:"§Í";s:3:"彤";s:2:"§Î";s:3:"å½¢";s:2:"§Ï";s:3:"å½·";s:2:"§Ð";s:3:"å½¹";s:2:"§Ñ";s:3:"忘";s:2:"§Ò";s:3:"忌";s:2:"§Ó";s:3:"å¿—";s:2:"§Ô";s:3:"å¿";s:2:"§Õ";s:3:"忱";s:2:"§Ö";s:3:"å¿«";s:2:"§×";s:3:"忸";s:2:"§Ø";s:3:"忪";s:2:"§Ù";s:3:"戒";s:2:"§Ú";s:3:"我";s:2:"§Û";s:3:"抄";s:2:"§Ü";s:3:"抗";s:2:"§Ý";s:3:"抖";s:2:"§Þ";s:3:"技";s:2:"§ß";s:3:"扶";s:2:"§à";s:3:"抉";s:2:"§á";s:3:"扭";s:2:"§â";s:3:"把";s:2:"§ã";s:3:"扼";s:2:"§ä";s:3:"找";s:2:"§å";s:3:"批";s:2:"§æ";s:3:"扳";s:2:"§ç";s:3:"抒";s:2:"§è";s:3:"扯";s:2:"§é";s:3:"折";s:2:"§ê";s:3:"扮";s:2:"§ë";s:3:"投";s:2:"§ì";s:3:"抓";s:2:"§í";s:3:"抑";s:2:"§î";s:3:"抆";s:2:"§ï";s:3:"改";s:2:"§ð";s:3:"æ”»";s:2:"§ñ";s:3:"攸";s:2:"§ò";s:3:"æ—±";s:2:"§ó";s:3:"æ›´";s:2:"§ô";s:3:"æŸ";s:2:"§õ";s:3:"æŽ";s:2:"§ö";s:3:"æ";s:2:"§÷";s:3:"æ";s:2:"§ø";s:3:"æ‘";s:2:"§ù";s:3:"æœ";s:2:"§ú";s:3:"æ–";s:2:"§û";s:3:"æž";s:2:"§ü";s:3:"æ‰";s:2:"§ý";s:3:"æ†";s:2:"§þ";s:3:"æ ";s:2:"¨@";s:3:"æ“";s:2:"¨A";s:3:"æ—";s:2:"¨B";s:3:"æ­¥";s:2:"¨C";s:3:"æ¯";s:2:"¨D";s:3:"求";s:2:"¨E";s:3:"汞";s:2:"¨F";s:3:"æ²™";s:2:"¨G";s:3:"æ²";s:2:"¨H";s:3:"沈";s:2:"¨I";s:3:"沉";s:2:"¨J";s:3:"æ²…";s:2:"¨K";s:3:"æ²›";s:2:"¨L";s:3:"汪";s:2:"¨M";s:3:"決";s:2:"¨N";s:3:"æ²";s:2:"¨O";s:3:"æ±°";s:2:"¨P";s:3:"沌";s:2:"¨Q";s:3:"汨";s:2:"¨R";s:3:"æ²–";s:2:"¨S";s:3:"æ²’";s:2:"¨T";s:3:"æ±½";s:2:"¨U";s:3:"沃";s:2:"¨V";s:3:"æ±²";s:2:"¨W";s:3:"æ±¾";s:2:"¨X";s:3:"æ±´";s:2:"¨Y";s:3:"沆";s:2:"¨Z";s:3:"æ±¶";s:2:"¨[";s:3:"æ²";s:2:"¨\";s:3:"æ²”";s:2:"¨]";s:3:"沘";s:2:"¨^";s:3:"沂";s:2:"¨_";s:3:"ç¶";s:2:"¨`";s:3:"ç¼";s:2:"¨a";s:3:"ç½";s:2:"¨b";s:3:"ç¸";s:2:"¨c";s:3:"牢";s:2:"¨d";s:3:"牡";s:2:"¨e";s:3:"牠";s:2:"¨f";s:3:"ç‹„";s:2:"¨g";s:3:"ç‹‚";s:2:"¨h";s:3:"玖";s:2:"¨i";s:3:"甬";s:2:"¨j";s:3:"甫";s:2:"¨k";s:3:"ç”·";s:2:"¨l";s:3:"甸";s:2:"¨m";s:3:"çš‚";s:2:"¨n";s:3:"盯";s:2:"¨o";s:3:"矣";s:2:"¨p";s:3:"ç§";s:2:"¨q";s:3:"ç§€";s:2:"¨r";s:3:"禿";s:2:"¨s";s:3:"ç©¶";s:2:"¨t";s:3:"ç³»";s:2:"¨u";s:3:"罕";s:2:"¨v";s:3:"è‚–";s:2:"¨w";s:3:"è‚“";s:2:"¨x";s:3:"è‚";s:2:"¨y";s:3:"肘";s:2:"¨z";s:3:"è‚›";s:2:"¨{";s:3:"肚";s:2:"¨|";s:3:"育";s:2:"¨}";s:3:"良";s:2:"¨~";s:3:"芒";s:2:"¨¡";s:3:"芋";s:2:"¨¢";s:3:"èŠ";s:2:"¨£";s:3:"見";s:2:"¨¤";s:3:"è§’";s:2:"¨¥";s:3:"言";s:2:"¨¦";s:3:"è°·";s:2:"¨§";s:3:"豆";s:2:"¨¨";s:3:"豕";s:2:"¨©";s:3:"è²";s:2:"¨ª";s:3:"赤";s:2:"¨«";s:3:"èµ°";s:2:"¨¬";s:3:"è¶³";s:2:"¨­";s:3:"身";s:2:"¨®";s:3:"車";s:2:"¨¯";s:3:"è¾›";s:2:"¨°";s:3:"è¾°";s:2:"¨±";s:3:"è¿‚";s:2:"¨²";s:3:"迆";s:2:"¨³";s:3:"è¿…";s:2:"¨´";s:3:"è¿„";s:2:"¨µ";s:3:"å·¡";s:2:"¨¶";s:3:"é‚‘";s:2:"¨·";s:3:"é‚¢";s:2:"¨¸";s:3:"邪";s:2:"¨¹";s:3:"邦";s:2:"¨º";s:3:"é‚£";s:2:"¨»";s:3:"é…‰";s:2:"¨¼";s:3:"釆";s:2:"¨½";s:3:"里";s:2:"¨¾";s:3:"防";s:2:"¨¿";s:3:"阮";s:2:"¨À";s:3:"阱";s:2:"¨Á";s:3:"阪";s:2:"¨Â";s:3:"阬";s:2:"¨Ã";s:3:"並";s:2:"¨Ä";s:3:"ä¹–";s:2:"¨Å";s:3:"ä¹³";s:2:"¨Æ";s:3:"事";s:2:"¨Ç";s:3:"些";s:2:"¨È";s:3:"亞";s:2:"¨É";s:3:"享";s:2:"¨Ê";s:3:"京";s:2:"¨Ë";s:3:"佯";s:2:"¨Ì";s:3:"ä¾";s:2:"¨Í";s:3:"ä¾";s:2:"¨Î";s:3:"ä½³";s:2:"¨Ï";s:3:"使";s:2:"¨Ð";s:3:"佬";s:2:"¨Ñ";s:3:"ä¾›";s:2:"¨Ò";s:3:"例";s:2:"¨Ó";s:3:"來";s:2:"¨Ô";s:3:"侃";s:2:"¨Õ";s:3:"ä½°";s:2:"¨Ö";s:3:"ä½µ";s:2:"¨×";s:3:"侈";s:2:"¨Ø";s:3:"佩";s:2:"¨Ù";s:3:"ä½»";s:2:"¨Ú";s:3:"ä¾–";s:2:"¨Û";s:3:"ä½¾";s:2:"¨Ü";s:3:"ä¾";s:2:"¨Ý";s:3:"侑";s:2:"¨Þ";s:3:"佺";s:2:"¨ß";s:3:"å…”";s:2:"¨à";s:3:"å…’";s:2:"¨á";s:3:"å…•";s:2:"¨â";s:3:"å…©";s:2:"¨ã";s:3:"å…·";s:2:"¨ä";s:3:"å…¶";s:2:"¨å";s:3:"å…¸";s:2:"¨æ";s:3:"冽";s:2:"¨ç";s:3:"函";s:2:"¨è";s:3:"刻";s:2:"¨é";s:3:"券";s:2:"¨ê";s:3:"刷";s:2:"¨ë";s:3:"刺";s:2:"¨ì";s:3:"到";s:2:"¨í";s:3:"刮";s:2:"¨î";s:3:"制";s:2:"¨ï";s:3:"å‰";s:2:"¨ð";s:3:"劾";s:2:"¨ñ";s:3:"劻";s:2:"¨ò";s:3:"å’";s:2:"¨ó";s:3:"å”";s:2:"¨ô";s:3:"å“";s:2:"¨õ";s:3:"å‘";s:2:"¨ö";s:3:"å¦";s:2:"¨÷";s:3:"å·";s:2:"¨ø";s:3:"å¸";s:2:"¨ù";s:3:"å¹";s:2:"¨ú";s:3:"å–";s:2:"¨û";s:3:"å”";s:2:"¨ü";s:3:"å—";s:2:"¨ý";s:3:"味";s:2:"¨þ";s:3:"呵";s:2:"©@";s:3:"å’–";s:2:"©A";s:3:"呸";s:2:"©B";s:3:"å’•";s:2:"©C";s:3:"å’€";s:2:"©D";s:3:"å‘»";s:2:"©E";s:3:"å‘·";s:2:"©F";s:3:"å’„";s:2:"©G";s:3:"å’’";s:2:"©H";s:3:"å’†";s:2:"©I";s:3:"呼";s:2:"©J";s:3:"å’";s:2:"©K";s:3:"呱";s:2:"©L";s:3:"å‘¶";s:2:"©M";s:3:"å’Œ";s:2:"©N";s:3:"å’š";s:2:"©O";s:3:"å‘¢";s:2:"©P";s:3:"周";s:2:"©Q";s:3:"å’‹";s:2:"©R";s:3:"命";s:2:"©S";s:3:"å’Ž";s:2:"©T";s:3:"固";s:2:"©U";s:3:"垃";s:2:"©V";s:3:"å·";s:2:"©W";s:3:"åª";s:2:"©X";s:3:"å©";s:2:"©Y";s:3:"å¡";s:2:"©Z";s:3:"å¦";s:2:"©[";s:3:"å¤";s:2:"©\";s:3:"å¼";s:2:"©]";s:3:"夜";s:2:"©^";s:3:"奉";s:2:"©_";s:3:"奇";s:2:"©`";s:3:"奈";s:2:"©a";s:3:"奄";s:2:"©b";s:3:"奔";s:2:"©c";s:3:"妾";s:2:"©d";s:3:"妻";s:2:"©e";s:3:"å§”";s:2:"©f";s:3:"妹";s:2:"©g";s:3:"妮";s:2:"©h";s:3:"å§‘";s:2:"©i";s:3:"姆";s:2:"©j";s:3:"å§";s:2:"©k";s:3:"å§";s:2:"©l";s:3:"å§‹";s:2:"©m";s:3:"å§“";s:2:"©n";s:3:"å§Š";s:2:"©o";s:3:"妯";s:2:"©p";s:3:"妳";s:2:"©q";s:3:"å§’";s:2:"©r";s:3:"å§…";s:2:"©s";s:3:"å­Ÿ";s:2:"©t";s:3:"å­¤";s:2:"©u";s:3:"å­£";s:2:"©v";s:3:"å®—";s:2:"©w";s:3:"定";s:2:"©x";s:3:"官";s:2:"©y";s:3:"宜";s:2:"©z";s:3:"å®™";s:2:"©{";s:3:"å®›";s:2:"©|";s:3:"å°š";s:2:"©}";s:3:"屈";s:2:"©~";s:3:"å±…";s:2:"©¡";s:3:"屆";s:2:"©¢";s:3:"å²·";s:2:"©£";s:3:"岡";s:2:"©¤";s:3:"岸";s:2:"©¥";s:3:"岩";s:2:"©¦";s:3:"岫";s:2:"©§";s:3:"å²±";s:2:"©¨";s:3:"å²³";s:2:"©©";s:3:"帘";s:2:"©ª";s:3:"帚";s:2:"©«";s:3:"帖";s:2:"©¬";s:3:"帕";s:2:"©­";s:3:"帛";s:2:"©®";s:3:"帑";s:2:"©¯";s:3:"幸";s:2:"©°";s:3:"庚";s:2:"©±";s:3:"店";s:2:"©²";s:3:"府";s:2:"©³";s:3:"底";s:2:"©´";s:3:"庖";s:2:"©µ";s:3:"å»¶";s:2:"©¶";s:3:"弦";s:2:"©·";s:3:"å¼§";s:2:"©¸";s:3:"弩";s:2:"©¹";s:3:"å¾€";s:2:"©º";s:3:"å¾";s:2:"©»";s:3:"彿";s:2:"©¼";s:3:"å½¼";s:2:"©½";s:3:"å¿";s:2:"©¾";s:3:"å¿ ";s:2:"©¿";s:3:"忽";s:2:"©À";s:3:"念";s:2:"©Á";s:3:"å¿¿";s:2:"©Â";s:3:"æ€";s:2:"©Ã";s:3:"怔";s:2:"©Ä";s:3:"怯";s:2:"©Å";s:3:"怵";s:2:"©Æ";s:3:"怖";s:2:"©Ç";s:3:"怪";s:2:"©È";s:3:"怕";s:2:"©É";s:3:"怡";s:2:"©Ê";s:3:"性";s:2:"©Ë";s:3:"怩";s:2:"©Ì";s:3:"怫";s:2:"©Í";s:3:"怛";s:2:"©Î";s:3:"或";s:2:"©Ï";s:3:"戕";s:2:"©Ð";s:3:"房";s:2:"©Ñ";s:3:"戾";s:2:"©Ò";s:3:"所";s:2:"©Ó";s:3:"承";s:2:"©Ô";s:3:"拉";s:2:"©Õ";s:3:"拌";s:2:"©Ö";s:3:"æ‹„";s:2:"©×";s:3:"抿";s:2:"©Ø";s:3:"æ‹‚";s:2:"©Ù";s:3:"抹";s:2:"©Ú";s:3:"æ‹’";s:2:"©Û";s:3:"æ‹›";s:2:"©Ü";s:3:"披";s:2:"©Ý";s:3:"æ‹“";s:2:"©Þ";s:3:"æ‹”";s:2:"©ß";s:3:"æ‹‹";s:2:"©à";s:3:"拈";s:2:"©á";s:3:"抨";s:2:"©â";s:3:"抽";s:2:"©ã";s:3:"押";s:2:"©ä";s:3:"æ‹";s:2:"©å";s:3:"æ‹™";s:2:"©æ";s:3:"拇";s:2:"©ç";s:3:"æ‹";s:2:"©è";s:3:"抵";s:2:"©é";s:3:"拚";s:2:"©ê";s:3:"抱";s:2:"©ë";s:3:"拘";s:2:"©ì";s:3:"æ‹–";s:2:"©í";s:3:"æ‹—";s:2:"©î";s:3:"拆";s:2:"©ï";s:3:"抬";s:2:"©ð";s:3:"拎";s:2:"©ñ";s:3:"放";s:2:"©ò";s:3:"æ–§";s:2:"©ó";s:3:"æ–¼";s:2:"©ô";s:3:"æ—º";s:2:"©õ";s:3:"昔";s:2:"©ö";s:3:"易";s:2:"©÷";s:3:"昌";s:2:"©ø";s:3:"昆";s:2:"©ù";s:3:"昂";s:2:"©ú";s:3:"明";s:2:"©û";s:3:"昀";s:2:"©ü";s:3:"æ˜";s:2:"©ý";s:3:"昕";s:2:"©þ";s:3:"昊";s:2:"ª@";s:3:"昇";s:2:"ªA";s:3:"æœ";s:2:"ªB";s:3:"朋";s:2:"ªC";s:3:"æ­";s:2:"ªD";s:3:"æž‹";s:2:"ªE";s:3:"æž•";s:2:"ªF";s:3:"æ±";s:2:"ªG";s:3:"æžœ";s:2:"ªH";s:3:"æ³";s:2:"ªI";s:3:"æ·";s:2:"ªJ";s:3:"枇";s:2:"ªK";s:3:"æž";s:2:"ªL";s:3:"æž—";s:2:"ªM";s:3:"æ¯";s:2:"ªN";s:3:"æ°";s:2:"ªO";s:3:"æ¿";s:2:"ªP";s:3:"枉";s:2:"ªQ";s:3:"æ¾";s:2:"ªR";s:3:"æž";s:2:"ªS";s:3:"æµ";s:2:"ªT";s:3:"æžš";s:2:"ªU";s:3:"æž“";s:2:"ªV";s:3:"æ¼";s:2:"ªW";s:3:"æª";s:2:"ªX";s:3:"æ²";s:2:"ªY";s:3:"欣";s:2:"ªZ";s:3:"æ­¦";s:2:"ª[";s:3:"æ­§";s:2:"ª\";s:3:"æ­¿";s:2:"ª]";s:3:"æ°“";s:2:"ª^";s:3:"æ°›";s:2:"ª_";s:3:"æ³£";s:2:"ª`";s:3:"注";s:2:"ªa";s:3:"æ³³";s:2:"ªb";s:3:"æ²±";s:2:"ªc";s:3:"泌";s:2:"ªd";s:3:"æ³¥";s:2:"ªe";s:3:"æ²³";s:2:"ªf";s:3:"æ²½";s:2:"ªg";s:3:"æ²¾";s:2:"ªh";s:3:"æ²¼";s:2:"ªi";s:3:"æ³¢";s:2:"ªj";s:3:"沫";s:2:"ªk";s:3:"法";s:2:"ªl";s:3:"泓";s:2:"ªm";s:3:"沸";s:2:"ªn";s:3:"泄";s:2:"ªo";s:3:"æ²¹";s:2:"ªp";s:3:"æ³";s:2:"ªq";s:3:"æ²®";s:2:"ªr";s:3:"æ³—";s:2:"ªs";s:3:"æ³…";s:2:"ªt";s:3:"æ³±";s:2:"ªu";s:3:"沿";s:2:"ªv";s:3:"æ²»";s:2:"ªw";s:3:"泡";s:2:"ªx";s:3:"æ³›";s:2:"ªy";s:3:"泊";s:2:"ªz";s:3:"沬";s:2:"ª{";s:3:"泯";s:2:"ª|";s:3:"泜";s:2:"ª}";s:3:"æ³–";s:2:"ª~";s:3:"æ³ ";s:2:"ª¡";s:3:"ç‚•";s:2:"ª¢";s:3:"炎";s:2:"ª£";s:3:"ç‚’";s:2:"ª¤";s:3:"炊";s:2:"ª¥";s:3:"ç‚™";s:2:"ª¦";s:3:"爬";s:2:"ª§";s:3:"爭";s:2:"ª¨";s:3:"爸";s:2:"ª©";s:3:"版";s:2:"ªª";s:3:"牧";s:2:"ª«";s:3:"物";s:2:"ª¬";s:3:"ç‹€";s:2:"ª­";s:3:"狎";s:2:"ª®";s:3:"ç‹™";s:2:"ª¯";s:3:"ç‹—";s:2:"ª°";s:3:"ç‹";s:2:"ª±";s:3:"玩";s:2:"ª²";s:3:"玨";s:2:"ª³";s:3:"玟";s:2:"ª´";s:3:"玫";s:2:"ªµ";s:3:"玥";s:2:"ª¶";s:3:"甽";s:2:"ª·";s:3:"ç–";s:2:"ª¸";s:3:"ç–™";s:2:"ª¹";s:3:"ç–š";s:2:"ªº";s:3:"çš„";s:2:"ª»";s:3:"盂";s:2:"ª¼";s:3:"盲";s:2:"ª½";s:3:"ç›´";s:2:"ª¾";s:3:"知";s:2:"ª¿";s:3:"矽";s:2:"ªÀ";s:3:"社";s:2:"ªÁ";s:3:"祀";s:2:"ªÂ";s:3:"ç¥";s:2:"ªÃ";s:3:"秉";s:2:"ªÄ";s:3:"秈";s:2:"ªÅ";s:3:"空";s:2:"ªÆ";s:3:"穹";s:2:"ªÇ";s:3:"竺";s:2:"ªÈ";s:3:"ç³¾";s:2:"ªÉ";s:3:"ç½”";s:2:"ªÊ";s:3:"羌";s:2:"ªË";s:3:"羋";s:2:"ªÌ";s:3:"者";s:2:"ªÍ";s:3:"肺";s:2:"ªÎ";s:3:"è‚¥";s:2:"ªÏ";s:3:"è‚¢";s:2:"ªÐ";s:3:"肱";s:2:"ªÑ";s:3:"è‚¡";s:2:"ªÒ";s:3:"è‚«";s:2:"ªÓ";s:3:"è‚©";s:2:"ªÔ";s:3:"è‚´";s:2:"ªÕ";s:3:"肪";s:2:"ªÖ";s:3:"肯";s:2:"ª×";s:3:"臥";s:2:"ªØ";s:3:"臾";s:2:"ªÙ";s:3:"èˆ";s:2:"ªÚ";s:3:"芳";s:2:"ªÛ";s:3:"èŠ";s:2:"ªÜ";s:3:"芙";s:2:"ªÝ";s:3:"芭";s:2:"ªÞ";s:3:"芽";s:2:"ªß";s:3:"芟";s:2:"ªà";s:3:"芹";s:2:"ªá";s:3:"花";s:2:"ªâ";s:3:"芬";s:2:"ªã";s:3:"芥";s:2:"ªä";s:3:"芯";s:2:"ªå";s:3:"芸";s:2:"ªæ";s:3:"芣";s:2:"ªç";s:3:"芰";s:2:"ªè";s:3:"芾";s:2:"ªé";s:3:"芷";s:2:"ªê";s:3:"虎";s:2:"ªë";s:3:"è™±";s:2:"ªì";s:3:"åˆ";s:2:"ªí";s:3:"表";s:2:"ªî";s:3:"軋";s:2:"ªï";s:3:"迎";s:2:"ªð";s:3:"è¿”";s:2:"ªñ";s:3:"è¿‘";s:2:"ªò";s:3:"邵";s:2:"ªó";s:3:"邸";s:2:"ªô";s:3:"邱";s:2:"ªõ";s:3:"é‚¶";s:2:"ªö";s:3:"采";s:2:"ª÷";s:3:"金";s:2:"ªø";s:3:"é•·";s:2:"ªù";s:3:"é–€";s:2:"ªú";s:3:"阜";s:2:"ªû";s:3:"陀";s:2:"ªü";s:3:"阿";s:2:"ªý";s:3:"阻";s:2:"ªþ";s:3:"附";s:2:"«@";s:3:"陂";s:2:"«A";s:3:"éš¹";s:2:"«B";s:3:"雨";s:2:"«C";s:3:"é’";s:2:"«D";s:3:"éž";s:2:"«E";s:3:"亟";s:2:"«F";s:3:"亭";s:2:"«G";s:3:"亮";s:2:"«H";s:3:"ä¿¡";s:2:"«I";s:3:"ä¾µ";s:2:"«J";s:3:"侯";s:2:"«K";s:3:"便";s:2:"«L";s:3:"ä¿ ";s:2:"«M";s:3:"ä¿‘";s:2:"«N";s:3:"ä¿";s:2:"«O";s:3:"ä¿";s:2:"«P";s:3:"促";s:2:"«Q";s:3:"ä¾¶";s:2:"«R";s:3:"俘";s:2:"«S";s:3:"俟";s:2:"«T";s:3:"俊";s:2:"«U";s:3:"ä¿—";s:2:"«V";s:3:"ä¾®";s:2:"«W";s:3:"ä¿";s:2:"«X";s:3:"ä¿„";s:2:"«Y";s:3:"ä¿‚";s:2:"«Z";s:3:"俚";s:2:"«[";s:3:"俎";s:2:"«\";s:3:"俞";s:2:"«]";s:3:"ä¾·";s:2:"«^";s:3:"å…—";s:2:"«_";s:3:"冒";s:2:"«`";s:3:"冑";s:2:"«a";s:3:"冠";s:2:"«b";s:3:"剎";s:2:"«c";s:3:"剃";s:2:"«d";s:3:"削";s:2:"«e";s:3:"å‰";s:2:"«f";s:3:"剌";s:2:"«g";s:3:"剋";s:2:"«h";s:3:"則";s:2:"«i";s:3:"勇";s:2:"«j";s:3:"勉";s:2:"«k";s:3:"勃";s:2:"«l";s:3:"å‹";s:2:"«m";s:3:"åŒ";s:2:"«n";s:3:"å—";s:2:"«o";s:3:"å»";s:2:"«p";s:3:"厚";s:2:"«q";s:3:"å›";s:2:"«r";s:3:"å’¬";s:2:"«s";s:3:"å“€";s:2:"«t";s:3:"å’¨";s:2:"«u";s:3:"哎";s:2:"«v";s:3:"哉";s:2:"«w";s:3:"å’¸";s:2:"«x";s:3:"å’¦";s:2:"«y";s:3:"å’³";s:2:"«z";s:3:"哇";s:2:"«{";s:3:"å“‚";s:2:"«|";s:3:"å’½";s:2:"«}";s:3:"å’ª";s:2:"«~";s:3:"å“";s:2:"«¡";s:3:"å“„";s:2:"«¢";s:3:"哈";s:2:"«£";s:3:"å’¯";s:2:"«¤";s:3:"å’«";s:2:"«¥";s:3:"å’±";s:2:"«¦";s:3:"å’»";s:2:"«§";s:3:"å’©";s:2:"«¨";s:3:"å’§";s:2:"«©";s:3:"å’¿";s:2:"«ª";s:3:"囿";s:2:"««";s:3:"åž‚";s:2:"«¬";s:3:"åž‹";s:2:"«­";s:3:"åž ";s:2:"«®";s:3:"垣";s:2:"«¯";s:3:"垢";s:2:"«°";s:3:"城";s:2:"«±";s:3:"åž®";s:2:"«²";s:3:"åž“";s:2:"«³";s:3:"奕";s:2:"«´";s:3:"契";s:2:"«µ";s:3:"å¥";s:2:"«¶";s:3:"奎";s:2:"«·";s:3:"å¥";s:2:"«¸";s:3:"å§œ";s:2:"«¹";s:3:"姘";s:2:"«º";s:3:"å§¿";s:2:"«»";s:3:"å§£";s:2:"«¼";s:3:"姨";s:2:"«½";s:3:"娃";s:2:"«¾";s:3:"å§¥";s:2:"«¿";s:3:"姪";s:2:"«À";s:3:"å§š";s:2:"«Á";s:3:"姦";s:2:"«Â";s:3:"å¨";s:2:"«Ã";s:3:"å§»";s:2:"«Ä";s:3:"å­©";s:2:"«Å";s:3:"宣";s:2:"«Æ";s:3:"宦";s:2:"«Ç";s:3:"室";s:2:"«È";s:3:"客";s:2:"«É";s:3:"宥";s:2:"«Ê";s:3:"å°";s:2:"«Ë";s:3:"屎";s:2:"«Ì";s:3:"å±";s:2:"«Í";s:3:"å±";s:2:"«Î";s:3:"屋";s:2:"«Ï";s:3:"å³™";s:2:"«Ð";s:3:"å³’";s:2:"«Ñ";s:3:"å··";s:2:"«Ò";s:3:"å¸";s:2:"«Ó";s:3:"帥";s:2:"«Ô";s:3:"帟";s:2:"«Õ";s:3:"å¹½";s:2:"«Ö";s:3:"庠";s:2:"«×";s:3:"度";s:2:"«Ø";s:3:"建";s:2:"«Ù";s:3:"弈";s:2:"«Ú";s:3:"å¼­";s:2:"«Û";s:3:"å½¥";s:2:"«Ü";s:3:"很";s:2:"«Ý";s:3:"å¾…";s:2:"«Þ";s:3:"徊";s:2:"«ß";s:3:"律";s:2:"«à";s:3:"徇";s:2:"«á";s:3:"後";s:2:"«â";s:3:"徉";s:2:"«ã";s:3:"怒";s:2:"«ä";s:3:"æ€";s:2:"«å";s:3:"怠";s:2:"«æ";s:3:"急";s:2:"«ç";s:3:"怎";s:2:"«è";s:3:"怨";s:2:"«é";s:3:"æ";s:2:"«ê";s:3:"æ°";s:2:"«ë";s:3:"æ¨";s:2:"«ì";s:3:"æ¢";s:2:"«í";s:3:"æ†";s:2:"«î";s:3:"æƒ";s:2:"«ï";s:3:"æ¬";s:2:"«ð";s:3:"æ«";s:2:"«ñ";s:3:"æª";s:2:"«ò";s:3:"æ¤";s:2:"«ó";s:3:"æ‰";s:2:"«ô";s:3:"拜";s:2:"«õ";s:3:"挖";s:2:"«ö";s:3:"按";s:2:"«÷";s:3:"拼";s:2:"«ø";s:3:"æ‹­";s:2:"«ù";s:3:"æŒ";s:2:"«ú";s:3:"æ‹®";s:2:"«û";s:3:"拽";s:2:"«ü";s:3:"指";s:2:"«ý";s:3:"拱";s:2:"«þ";s:3:"æ‹·";s:2:"¬@";s:3:"拯";s:2:"¬A";s:3:"括";s:2:"¬B";s:3:"拾";s:2:"¬C";s:3:"æ‹´";s:2:"¬D";s:3:"挑";s:2:"¬E";s:3:"挂";s:2:"¬F";s:3:"政";s:2:"¬G";s:3:"æ•…";s:2:"¬H";s:3:"æ–«";s:2:"¬I";s:3:"æ–½";s:2:"¬J";s:3:"æ—¢";s:2:"¬K";s:3:"春";s:2:"¬L";s:3:"昭";s:2:"¬M";s:3:"映";s:2:"¬N";s:3:"昧";s:2:"¬O";s:3:"是";s:2:"¬P";s:3:"星";s:2:"¬Q";s:3:"昨";s:2:"¬R";s:3:"昱";s:2:"¬S";s:3:"昤";s:2:"¬T";s:3:"æ›·";s:2:"¬U";s:3:"柿";s:2:"¬V";s:3:"染";s:2:"¬W";s:3:"柱";s:2:"¬X";s:3:"柔";s:2:"¬Y";s:3:"æŸ";s:2:"¬Z";s:3:"柬";s:2:"¬[";s:3:"æž¶";s:2:"¬\";s:3:"枯";s:2:"¬]";s:3:"柵";s:2:"¬^";s:3:"柩";s:2:"¬_";s:3:"柯";s:2:"¬`";s:3:"柄";s:2:"¬a";s:3:"柑";s:2:"¬b";s:3:"æž´";s:2:"¬c";s:3:"柚";s:2:"¬d";s:3:"查";s:2:"¬e";s:3:"枸";s:2:"¬f";s:3:"æŸ";s:2:"¬g";s:3:"柞";s:2:"¬h";s:3:"柳";s:2:"¬i";s:3:"æž°";s:2:"¬j";s:3:"柙";s:2:"¬k";s:3:"柢";s:2:"¬l";s:3:"æŸ";s:2:"¬m";s:3:"柒";s:2:"¬n";s:3:"æ­ª";s:2:"¬o";s:3:"殃";s:2:"¬p";s:3:"殆";s:2:"¬q";s:3:"段";s:2:"¬r";s:3:"毒";s:2:"¬s";s:3:"毗";s:2:"¬t";s:3:"æ°Ÿ";s:2:"¬u";s:3:"泉";s:2:"¬v";s:3:"æ´‹";s:2:"¬w";s:3:"æ´²";s:2:"¬x";s:3:"æ´ª";s:2:"¬y";s:3:"æµ";s:2:"¬z";s:3:"æ´¥";s:2:"¬{";s:3:"æ´Œ";s:2:"¬|";s:3:"æ´±";s:2:"¬}";s:3:"æ´ž";s:2:"¬~";s:3:"æ´—";s:2:"¬¡";s:3:"æ´»";s:2:"¬¢";s:3:"æ´½";s:2:"¬£";s:3:"æ´¾";s:2:"¬¤";s:3:"æ´¶";s:2:"¬¥";s:3:"æ´›";s:2:"¬¦";s:3:"æ³µ";s:2:"¬§";s:3:"æ´¹";s:2:"¬¨";s:3:"æ´§";s:2:"¬©";s:3:"æ´¸";s:2:"¬ª";s:3:"æ´©";s:2:"¬«";s:3:"æ´®";s:2:"¬¬";s:3:"æ´µ";s:2:"¬­";s:3:"æ´Ž";s:2:"¬®";s:3:"æ´«";s:2:"¬¯";s:3:"ç‚«";s:2:"¬°";s:3:"為";s:2:"¬±";s:3:"炳";s:2:"¬²";s:3:"炬";s:2:"¬³";s:3:"炯";s:2:"¬´";s:3:"ç‚­";s:2:"¬µ";s:3:"炸";s:2:"¬¶";s:3:"ç‚®";s:2:"¬·";s:3:"炤";s:2:"¬¸";s:3:"爰";s:2:"¬¹";s:3:"牲";s:2:"¬º";s:3:"牯";s:2:"¬»";s:3:"牴";s:2:"¬¼";s:3:"ç‹©";s:2:"¬½";s:3:"ç‹ ";s:2:"¬¾";s:3:"ç‹¡";s:2:"¬¿";s:3:"玷";s:2:"¬À";s:3:"çŠ";s:2:"¬Á";s:3:"玻";s:2:"¬Â";s:3:"玲";s:2:"¬Ã";s:3:"ç";s:2:"¬Ä";s:3:"ç€";s:2:"¬Å";s:3:"玳";s:2:"¬Æ";s:3:"甚";s:2:"¬Ç";s:3:"ç”­";s:2:"¬È";s:3:"ç•";s:2:"¬É";s:3:"界";s:2:"¬Ê";s:3:"畎";s:2:"¬Ë";s:3:"ç•‹";s:2:"¬Ì";s:3:"ç–«";s:2:"¬Í";s:3:"ç–¤";s:2:"¬Î";s:3:"ç–¥";s:2:"¬Ï";s:3:"ç–¢";s:2:"¬Ð";s:3:"ç–£";s:2:"¬Ñ";s:3:"癸";s:2:"¬Ò";s:3:"皆";s:2:"¬Ó";s:3:"皇";s:2:"¬Ô";s:3:"皈";s:2:"¬Õ";s:3:"盈";s:2:"¬Ö";s:3:"盆";s:2:"¬×";s:3:"盃";s:2:"¬Ø";s:3:"ç›…";s:2:"¬Ù";s:3:"çœ";s:2:"¬Ú";s:3:"盹";s:2:"¬Û";s:3:"相";s:2:"¬Ü";s:3:"眉";s:2:"¬Ý";s:3:"看";s:2:"¬Þ";s:3:"盾";s:2:"¬ß";s:3:"盼";s:2:"¬à";s:3:"眇";s:2:"¬á";s:3:"矜";s:2:"¬â";s:3:"ç ‚";s:2:"¬ã";s:3:"ç ”";s:2:"¬ä";s:3:"ç Œ";s:2:"¬å";s:3:"ç ";s:2:"¬æ";s:3:"祆";s:2:"¬ç";s:3:"祉";s:2:"¬è";s:3:"祈";s:2:"¬é";s:3:"祇";s:2:"¬ê";s:3:"禹";s:2:"¬ë";s:3:"禺";s:2:"¬ì";s:3:"ç§‘";s:2:"¬í";s:3:"ç§’";s:2:"¬î";s:3:"ç§‹";s:2:"¬ï";s:3:"ç©¿";s:2:"¬ð";s:3:"çª";s:2:"¬ñ";s:3:"ç«¿";s:2:"¬ò";s:3:"竽";s:2:"¬ó";s:3:"ç±½";s:2:"¬ô";s:3:"ç´‚";s:2:"¬õ";s:3:"ç´…";s:2:"¬ö";s:3:"ç´€";s:2:"¬÷";s:3:"ç´‰";s:2:"¬ø";s:3:"ç´‡";s:2:"¬ù";s:3:"ç´„";s:2:"¬ú";s:3:"ç´†";s:2:"¬û";s:3:"缸";s:2:"¬ü";s:3:"美";s:2:"¬ý";s:3:"羿";s:2:"¬þ";s:3:"耄";s:2:"­@";s:3:"è€";s:2:"­A";s:3:"è€";s:2:"­B";s:3:"耑";s:2:"­C";s:3:"耶";s:2:"­D";s:3:"胖";s:2:"­E";s:3:"胥";s:2:"­F";s:3:"胚";s:2:"­G";s:3:"胃";s:2:"­H";s:3:"胄";s:2:"­I";s:3:"背";s:2:"­J";s:3:"胡";s:2:"­K";s:3:"胛";s:2:"­L";s:3:"胎";s:2:"­M";s:3:"胞";s:2:"­N";s:3:"胤";s:2:"­O";s:3:"èƒ";s:2:"­P";s:3:"致";s:2:"­Q";s:3:"舢";s:2:"­R";s:3:"è‹§";s:2:"­S";s:3:"范";s:2:"­T";s:3:"茅";s:2:"­U";s:3:"è‹£";s:2:"­V";s:3:"è‹›";s:2:"­W";s:3:"苦";s:2:"­X";s:3:"茄";s:2:"­Y";s:3:"è‹¥";s:2:"­Z";s:3:"茂";s:2:"­[";s:3:"茉";s:2:"­\";s:3:"è‹’";s:2:"­]";s:3:"è‹—";s:2:"­^";s:3:"英";s:2:"­_";s:3:"èŒ";s:2:"­`";s:3:"苜";s:2:"­a";s:3:"è‹”";s:2:"­b";s:3:"è‹‘";s:2:"­c";s:3:"苞";s:2:"­d";s:3:"è‹“";s:2:"­e";s:3:"苟";s:2:"­f";s:3:"苯";s:2:"­g";s:3:"茆";s:2:"­h";s:3:"è™";s:2:"­i";s:3:"虹";s:2:"­j";s:3:"è™»";s:2:"­k";s:3:"虺";s:2:"­l";s:3:"è¡";s:2:"­m";s:3:"è¡«";s:2:"­n";s:3:"è¦";s:2:"­o";s:3:"è§”";s:2:"­p";s:3:"計";s:2:"­q";s:3:"訂";s:2:"­r";s:3:"訃";s:2:"­s";s:3:"貞";s:2:"­t";s:3:"è² ";s:2:"­u";s:3:"èµ´";s:2:"­v";s:3:"èµ³";s:2:"­w";s:3:"è¶´";s:2:"­x";s:3:"è»";s:2:"­y";s:3:"軌";s:2:"­z";s:3:"è¿°";s:2:"­{";s:3:"迦";s:2:"­|";s:3:"è¿¢";s:2:"­}";s:3:"迪";s:2:"­~";s:3:"è¿¥";s:2:"­¡";s:3:"è¿­";s:2:"­¢";s:3:"è¿«";s:2:"­£";s:3:"迤";s:2:"­¤";s:3:"迨";s:2:"­¥";s:3:"郊";s:2:"­¦";s:3:"郎";s:2:"­§";s:3:"éƒ";s:2:"­¨";s:3:"郃";s:2:"­©";s:3:"é…‹";s:2:"­ª";s:3:"é…Š";s:2:"­«";s:3:"é‡";s:2:"­¬";s:3:"é–‚";s:2:"­­";s:3:"é™";s:2:"­®";s:3:"陋";s:2:"­¯";s:3:"陌";s:2:"­°";s:3:"é™";s:2:"­±";s:3:"é¢";s:2:"­²";s:3:"é©";s:2:"­³";s:3:"韋";s:2:"­´";s:3:"韭";s:2:"­µ";s:3:"音";s:2:"­¶";s:3:"é ";s:2:"­·";s:3:"風";s:2:"­¸";s:3:"飛";s:2:"­¹";s:3:"食";s:2:"­º";s:3:"首";s:2:"­»";s:3:"香";s:2:"­¼";s:3:"乘";s:2:"­½";s:3:"亳";s:2:"­¾";s:3:"倌";s:2:"­¿";s:3:"å€";s:2:"­À";s:3:"倣";s:2:"­Á";s:3:"俯";s:2:"­Â";s:3:"倦";s:2:"­Ã";s:3:"倥";s:2:"­Ä";s:3:"俸";s:2:"­Å";s:3:"倩";s:2:"­Æ";s:3:"倖";s:2:"­Ç";s:3:"倆";s:2:"­È";s:3:"值";s:2:"­É";s:3:"借";s:2:"­Ê";s:3:"倚";s:2:"­Ë";s:3:"倒";s:2:"­Ì";s:3:"們";s:2:"­Í";s:3:"俺";s:2:"­Î";s:3:"倀";s:2:"­Ï";s:3:"倔";s:2:"­Ð";s:3:"倨";s:2:"­Ñ";s:3:"俱";s:2:"­Ò";s:3:"倡";s:2:"­Ó";s:3:"個";s:2:"­Ô";s:3:"候";s:2:"­Õ";s:3:"倘";s:2:"­Ö";s:3:"俳";s:2:"­×";s:3:"ä¿®";s:2:"­Ø";s:3:"倭";s:2:"­Ù";s:3:"倪";s:2:"­Ú";s:3:"俾";s:2:"­Û";s:3:"倫";s:2:"­Ü";s:3:"倉";s:2:"­Ý";s:3:"å…¼";s:2:"­Þ";s:3:"冤";s:2:"­ß";s:3:"冥";s:2:"­à";s:3:"冢";s:2:"­á";s:3:"å‡";s:2:"­â";s:3:"凌";s:2:"­ã";s:3:"准";s:2:"­ä";s:3:"凋";s:2:"­å";s:3:"剖";s:2:"­æ";s:3:"剜";s:2:"­ç";s:3:"剔";s:2:"­è";s:3:"剛";s:2:"­é";s:3:"å‰";s:2:"­ê";s:3:"匪";s:2:"­ë";s:3:"å¿";s:2:"­ì";s:3:"原";s:2:"­í";s:3:"åŽ";s:2:"­î";s:3:"åŸ";s:2:"­ï";s:3:"哨";s:2:"­ð";s:3:"å”";s:2:"­ñ";s:3:"å”";s:2:"­ò";s:3:"å”·";s:2:"­ó";s:3:"哼";s:2:"­ô";s:3:"å“¥";s:2:"­õ";s:3:"哲";s:2:"­ö";s:3:"唆";s:2:"­÷";s:3:"哺";s:2:"­ø";s:3:"å””";s:2:"­ù";s:3:"å“©";s:2:"­ú";s:3:"å“­";s:2:"­û";s:3:"å“¡";s:2:"­ü";s:3:"唉";s:2:"­ý";s:3:"å“®";s:2:"­þ";s:3:"哪";s:2:"®@";s:3:"哦";s:2:"®A";s:3:"å”§";s:2:"®B";s:3:"唇";s:2:"®C";s:3:"哽";s:2:"®D";s:3:"å”";s:2:"®E";s:3:"圃";s:2:"®F";s:3:"圄";s:2:"®G";s:3:"埂";s:2:"®H";s:3:"埔";s:2:"®I";s:3:"埋";s:2:"®J";s:3:"埃";s:2:"®K";s:3:"å ‰";s:2:"®L";s:3:"å¤";s:2:"®M";s:3:"套";s:2:"®N";s:3:"奘";s:2:"®O";s:3:"奚";s:2:"®P";s:3:"娑";s:2:"®Q";s:3:"娘";s:2:"®R";s:3:"娜";s:2:"®S";s:3:"娟";s:2:"®T";s:3:"娛";s:2:"®U";s:3:"娓";s:2:"®V";s:3:"姬";s:2:"®W";s:3:"娠";s:2:"®X";s:3:"娣";s:2:"®Y";s:3:"娩";s:2:"®Z";s:3:"娥";s:2:"®[";s:3:"娌";s:2:"®\";s:3:"娉";s:2:"®]";s:3:"å­«";s:2:"®^";s:3:"屘";s:2:"®_";s:3:"å®°";s:2:"®`";s:3:"害";s:2:"®a";s:3:"å®¶";s:2:"®b";s:3:"å®´";s:2:"®c";s:3:"å®®";s:2:"®d";s:3:"宵";s:2:"®e";s:3:"容";s:2:"®f";s:3:"宸";s:2:"®g";s:3:"å°„";s:2:"®h";s:3:"屑";s:2:"®i";s:3:"展";s:2:"®j";s:3:"å±";s:2:"®k";s:3:"å³­";s:2:"®l";s:3:"å³½";s:2:"®m";s:3:"å³»";s:2:"®n";s:3:"峪";s:2:"®o";s:3:"峨";s:2:"®p";s:3:"å³°";s:2:"®q";s:3:"å³¶";s:2:"®r";s:3:"å´";s:2:"®s";s:3:"å³´";s:2:"®t";s:3:"å·®";s:2:"®u";s:3:"席";s:2:"®v";s:3:"師";s:2:"®w";s:3:"庫";s:2:"®x";s:3:"庭";s:2:"®y";s:3:"座";s:2:"®z";s:3:"å¼±";s:2:"®{";s:3:"å¾’";s:2:"®|";s:3:"徑";s:2:"®}";s:3:"å¾";s:2:"®~";s:3:"æ™";s:2:"®¡";s:3:"æ£";s:2:"®¢";s:3:"æ¥";s:2:"®£";s:3:"æ";s:2:"®¤";s:3:"æ•";s:2:"®¥";s:3:"æ­";s:2:"®¦";s:3:"æ©";s:2:"®§";s:3:"æ¯";s:2:"®¨";s:3:"æ‚„";s:2:"®©";s:3:"悟";s:2:"®ª";s:3:"悚";s:2:"®«";s:3:"æ‚";s:2:"®¬";s:3:"æ‚”";s:2:"®­";s:3:"悌";s:2:"®®";s:3:"æ‚…";s:2:"®¯";s:3:"æ‚–";s:2:"®°";s:3:"扇";s:2:"®±";s:3:"拳";s:2:"®²";s:3:"挈";s:2:"®³";s:3:"æ‹¿";s:2:"®´";s:3:"æŽ";s:2:"®µ";s:3:"挾";s:2:"®¶";s:3:"振";s:2:"®·";s:3:"æ•";s:2:"®¸";s:3:"æ‚";s:2:"®¹";s:3:"æ†";s:2:"®º";s:3:"æ";s:2:"®»";s:3:"æ‰";s:2:"®¼";s:3:"挺";s:2:"®½";s:3:"æ";s:2:"®¾";s:3:"挽";s:2:"®¿";s:3:"挪";s:2:"®À";s:3:"挫";s:2:"®Á";s:3:"挨";s:2:"®Â";s:3:"æ";s:2:"®Ã";s:3:"æŒ";s:2:"®Ä";s:3:"效";s:2:"®Å";s:3:"敉";s:2:"®Æ";s:3:"æ–™";s:2:"®Ç";s:3:"æ—";s:2:"®È";s:3:"æ—…";s:2:"®É";s:3:"時";s:2:"®Ê";s:3:"晉";s:2:"®Ë";s:3:"æ™";s:2:"®Ì";s:3:"晃";s:2:"®Í";s:3:"æ™’";s:2:"®Î";s:3:"晌";s:2:"®Ï";s:3:"æ™…";s:2:"®Ð";s:3:"æ™";s:2:"®Ñ";s:3:"書";s:2:"®Ò";s:3:"朔";s:2:"®Ó";s:3:"朕";s:2:"®Ô";s:3:"朗";s:2:"®Õ";s:3:"æ ¡";s:2:"®Ö";s:3:"æ ¸";s:2:"®×";s:3:"案";s:2:"®Ø";s:3:"框";s:2:"®Ù";s:3:"æ¡“";s:2:"®Ú";s:3:"æ ¹";s:2:"®Û";s:3:"æ¡‚";s:2:"®Ü";s:3:"æ¡”";s:2:"®Ý";s:3:"æ ©";s:2:"®Þ";s:3:"梳";s:2:"®ß";s:3:"æ —";s:2:"®à";s:3:"桌";s:2:"®á";s:3:"æ¡‘";s:2:"®â";s:3:"æ ½";s:2:"®ã";s:3:"柴";s:2:"®ä";s:3:"æ¡";s:2:"®å";s:3:"æ¡€";s:2:"®æ";s:3:"æ ¼";s:2:"®ç";s:3:"桃";s:2:"®è";s:3:"æ ª";s:2:"®é";s:3:"æ¡…";s:2:"®ê";s:3:"æ “";s:2:"®ë";s:3:"æ ˜";s:2:"®ì";s:3:"æ¡";s:2:"®í";s:3:"殊";s:2:"®î";s:3:"殉";s:2:"®ï";s:3:"æ®·";s:2:"®ð";s:3:"æ°£";s:2:"®ñ";s:3:"æ°§";s:2:"®ò";s:3:"æ°¨";s:2:"®ó";s:3:"æ°¦";s:2:"®ô";s:3:"æ°¤";s:2:"®õ";s:3:"æ³°";s:2:"®ö";s:3:"浪";s:2:"®÷";s:3:"æ¶•";s:2:"®ø";s:3:"消";s:2:"®ù";s:3:"涇";s:2:"®ú";s:3:"浦";s:2:"®û";s:3:"浸";s:2:"®ü";s:3:"æµ·";s:2:"®ý";s:3:"æµ™";s:2:"®þ";s:3:"æ¶“";s:2:"¯@";s:3:"浬";s:2:"¯A";s:3:"涉";s:2:"¯B";s:3:"æµ®";s:2:"¯C";s:3:"浚";s:2:"¯D";s:3:"æµ´";s:2:"¯E";s:3:"浩";s:2:"¯F";s:3:"æ¶Œ";s:2:"¯G";s:3:"æ¶Š";s:2:"¯H";s:3:"æµ¹";s:2:"¯I";s:3:"æ¶…";s:2:"¯J";s:3:"æµ¥";s:2:"¯K";s:3:"æ¶”";s:2:"¯L";s:3:"烊";s:2:"¯M";s:3:"烘";s:2:"¯N";s:3:"烤";s:2:"¯O";s:3:"烙";s:2:"¯P";s:3:"烈";s:2:"¯Q";s:3:"çƒ";s:2:"¯R";s:3:"爹";s:2:"¯S";s:3:"特";s:2:"¯T";s:3:"狼";s:2:"¯U";s:3:"狹";s:2:"¯V";s:3:"狽";s:2:"¯W";s:3:"狸";s:2:"¯X";s:3:"ç‹·";s:2:"¯Y";s:3:"玆";s:2:"¯Z";s:3:"ç­";s:2:"¯[";s:3:"ç‰";s:2:"¯\";s:3:"ç®";s:2:"¯]";s:3:"ç ";s:2:"¯^";s:3:"çª";s:2:"¯_";s:3:"çž";s:2:"¯`";s:3:"ç•”";s:2:"¯a";s:3:"ç•";s:2:"¯b";s:3:"畜";s:2:"¯c";s:3:"畚";s:2:"¯d";s:3:"ç•™";s:2:"¯e";s:3:"ç–¾";s:2:"¯f";s:3:"ç—…";s:2:"¯g";s:3:"ç—‡";s:2:"¯h";s:3:"ç–²";s:2:"¯i";s:3:"ç–³";s:2:"¯j";s:3:"ç–½";s:2:"¯k";s:3:"ç–¼";s:2:"¯l";s:3:"ç–¹";s:2:"¯m";s:3:"ç—‚";s:2:"¯n";s:3:"ç–¸";s:2:"¯o";s:3:"çš‹";s:2:"¯p";s:3:"çš°";s:2:"¯q";s:3:"益";s:2:"¯r";s:3:"ç›";s:2:"¯s";s:3:"盎";s:2:"¯t";s:3:"眩";s:2:"¯u";s:3:"真";s:2:"¯v";s:3:"眠";s:2:"¯w";s:3:"眨";s:2:"¯x";s:3:"矩";s:2:"¯y";s:3:"ç °";s:2:"¯z";s:3:"ç §";s:2:"¯{";s:3:"ç ¸";s:2:"¯|";s:3:"ç ";s:2:"¯}";s:3:"ç ´";s:2:"¯~";s:3:"ç ·";s:2:"¯¡";s:3:"ç ¥";s:2:"¯¢";s:3:"ç ­";s:2:"¯£";s:3:"ç  ";s:2:"¯¤";s:3:"ç Ÿ";s:2:"¯¥";s:3:"ç ²";s:2:"¯¦";s:3:"祕";s:2:"¯§";s:3:"ç¥";s:2:"¯¨";s:3:"祠";s:2:"¯©";s:3:"祟";s:2:"¯ª";s:3:"祖";s:2:"¯«";s:3:"神";s:2:"¯¬";s:3:"ç¥";s:2:"¯­";s:3:"祗";s:2:"¯®";s:3:"祚";s:2:"¯¯";s:3:"秤";s:2:"¯°";s:3:"ç§£";s:2:"¯±";s:3:"ç§§";s:2:"¯²";s:3:"ç§Ÿ";s:2:"¯³";s:3:"秦";s:2:"¯´";s:3:"ç§©";s:2:"¯µ";s:3:"秘";s:2:"¯¶";s:3:"窄";s:2:"¯·";s:3:"窈";s:2:"¯¸";s:3:"ç«™";s:2:"¯¹";s:3:"笆";s:2:"¯º";s:3:"笑";s:2:"¯»";s:3:"粉";s:2:"¯¼";s:3:"ç´¡";s:2:"¯½";s:3:"ç´—";s:2:"¯¾";s:3:"ç´‹";s:2:"¯¿";s:3:"ç´Š";s:2:"¯À";s:3:"ç´ ";s:2:"¯Á";s:3:"ç´¢";s:2:"¯Â";s:3:"ç´”";s:2:"¯Ã";s:3:"ç´";s:2:"¯Ä";s:3:"ç´•";s:2:"¯Å";s:3:"ç´š";s:2:"¯Æ";s:3:"ç´œ";s:2:"¯Ç";s:3:"ç´";s:2:"¯È";s:3:"ç´™";s:2:"¯É";s:3:"ç´›";s:2:"¯Ê";s:3:"缺";s:2:"¯Ë";s:3:"罟";s:2:"¯Ì";s:3:"ç¾”";s:2:"¯Í";s:3:"ç¿…";s:2:"¯Î";s:3:"ç¿";s:2:"¯Ï";s:3:"耆";s:2:"¯Ð";s:3:"耘";s:2:"¯Ñ";s:3:"耕";s:2:"¯Ò";s:3:"耙";s:2:"¯Ó";s:3:"耗";s:2:"¯Ô";s:3:"耽";s:2:"¯Õ";s:3:"耿";s:2:"¯Ö";s:3:"胱";s:2:"¯×";s:3:"è„‚";s:2:"¯Ø";s:3:"胰";s:2:"¯Ù";s:3:"è„…";s:2:"¯Ú";s:3:"胭";s:2:"¯Û";s:3:"胴";s:2:"¯Ü";s:3:"脆";s:2:"¯Ý";s:3:"胸";s:2:"¯Þ";s:3:"胳";s:2:"¯ß";s:3:"脈";s:2:"¯à";s:3:"能";s:2:"¯á";s:3:"脊";s:2:"¯â";s:3:"胼";s:2:"¯ã";s:3:"胯";s:2:"¯ä";s:3:"臭";s:2:"¯å";s:3:"臬";s:2:"¯æ";s:3:"舀";s:2:"¯ç";s:3:"èˆ";s:2:"¯è";s:3:"航";s:2:"¯é";s:3:"舫";s:2:"¯ê";s:3:"舨";s:2:"¯ë";s:3:"般";s:2:"¯ì";s:3:"芻";s:2:"¯í";s:3:"茫";s:2:"¯î";s:3:"è’";s:2:"¯ï";s:3:"è”";s:2:"¯ð";s:3:"èŠ";s:2:"¯ñ";s:3:"茸";s:2:"¯ò";s:3:"è";s:2:"¯ó";s:3:"è‰";s:2:"¯ô";s:3:"茵";s:2:"¯õ";s:3:"茴";s:2:"¯ö";s:3:"è";s:2:"¯÷";s:3:"茲";s:2:"¯ø";s:3:"茹";s:2:"¯ù";s:3:"茶";s:2:"¯ú";s:3:"茗";s:2:"¯û";s:3:"è€";s:2:"¯ü";s:3:"茱";s:2:"¯ý";s:3:"茨";s:2:"¯þ";s:3:"èƒ";s:2:"°@";s:3:"è™”";s:2:"°A";s:3:"蚊";s:2:"°B";s:3:"蚪";s:2:"°C";s:3:"èš“";s:2:"°D";s:3:"蚤";s:2:"°E";s:3:"èš©";s:2:"°F";s:3:"蚌";s:2:"°G";s:3:"蚣";s:2:"°H";s:3:"èšœ";s:2:"°I";s:3:"è¡°";s:2:"°J";s:3:"è¡·";s:2:"°K";s:3:"è¢";s:2:"°L";s:3:"袂";s:2:"°M";s:3:"衽";s:2:"°N";s:3:"衹";s:2:"°O";s:3:"記";s:2:"°P";s:3:"è¨";s:2:"°Q";s:3:"討";s:2:"°R";s:3:"訌";s:2:"°S";s:3:"訕";s:2:"°T";s:3:"訊";s:2:"°U";s:3:"託";s:2:"°V";s:3:"訓";s:2:"°W";s:3:"訖";s:2:"°X";s:3:"è¨";s:2:"°Y";s:3:"訑";s:2:"°Z";s:3:"豈";s:2:"°[";s:3:"豺";s:2:"°\";s:3:"è±¹";s:2:"°]";s:3:"財";s:2:"°^";s:3:"è²¢";s:2:"°_";s:3:"èµ·";s:2:"°`";s:3:"躬";s:2:"°a";s:3:"è»’";s:2:"°b";s:3:"è»”";s:2:"°c";s:3:"è»";s:2:"°d";s:3:"è¾±";s:2:"°e";s:3:"é€";s:2:"°f";s:3:"逆";s:2:"°g";s:3:"è¿·";s:2:"°h";s:3:"退";s:2:"°i";s:3:"迺";s:2:"°j";s:3:"è¿´";s:2:"°k";s:3:"逃";s:2:"°l";s:3:"追";s:2:"°m";s:3:"逅";s:2:"°n";s:3:"迸";s:2:"°o";s:3:"é‚•";s:2:"°p";s:3:"郡";s:2:"°q";s:3:"éƒ";s:2:"°r";s:3:"郢";s:2:"°s";s:3:"é…’";s:2:"°t";s:3:"é…";s:2:"°u";s:3:"é…Œ";s:2:"°v";s:3:"釘";s:2:"°w";s:3:"é‡";s:2:"°x";s:3:"釗";s:2:"°y";s:3:"釜";s:2:"°z";s:3:"釙";s:2:"°{";s:3:"é–ƒ";s:2:"°|";s:3:"院";s:2:"°}";s:3:"陣";s:2:"°~";s:3:"陡";s:2:"°¡";s:3:"é™›";s:2:"°¢";s:3:"é™";s:2:"°£";s:3:"除";s:2:"°¤";s:3:"陘";s:2:"°¥";s:3:"陞";s:2:"°¦";s:3:"éš»";s:2:"°§";s:3:"飢";s:2:"°¨";s:3:"馬";s:2:"°©";s:3:"骨";s:2:"°ª";s:3:"高";s:2:"°«";s:3:"鬥";s:2:"°¬";s:3:"鬲";s:2:"°­";s:3:"鬼";s:2:"°®";s:3:"ä¹¾";s:2:"°¯";s:3:"åº";s:2:"°°";s:3:"å½";s:2:"°±";s:3:"åœ";s:2:"°²";s:3:"å‡";s:2:"°³";s:3:"åƒ";s:2:"°´";s:3:"åŒ";s:2:"°µ";s:3:"åš";s:2:"°¶";s:3:"å‰";s:2:"°·";s:3:"å¥";s:2:"°¸";s:3:"å¶";s:2:"°¹";s:3:"åŽ";s:2:"°º";s:3:"å•";s:2:"°»";s:3:"åµ";s:2:"°¼";s:3:"å´";s:2:"°½";s:3:"å·";s:2:"°¾";s:3:"å";s:2:"°¿";s:3:"å€";s:2:"°À";s:3:"å¯";s:2:"°Á";s:3:"å­";s:2:"°Â";s:3:"å…œ";s:2:"°Ã";s:3:"冕";s:2:"°Ä";s:3:"凰";s:2:"°Å";s:3:"剪";s:2:"°Æ";s:3:"副";s:2:"°Ç";s:3:"å‹’";s:2:"°È";s:3:"å‹™";s:2:"°É";s:3:"勘";s:2:"°Ê";s:3:"å‹•";s:2:"°Ë";s:3:"åŒ";s:2:"°Ì";s:3:"åŒ";s:2:"°Í";s:3:"匙";s:2:"°Î";s:3:"匿";s:2:"°Ï";s:3:"å€";s:2:"°Ð";s:3:"匾";s:2:"°Ñ";s:3:"åƒ";s:2:"°Ò";s:3:"曼";s:2:"°Ó";s:3:"商";s:2:"°Ô";s:3:"啪";s:2:"°Õ";s:3:"啦";s:2:"°Ö";s:3:"å•„";s:2:"°×";s:3:"啞";s:2:"°Ø";s:3:"å•¡";s:2:"°Ù";s:3:"啃";s:2:"°Ú";s:3:"啊";s:2:"°Û";s:3:"å”±";s:2:"°Ü";s:3:"å•–";s:2:"°Ý";s:3:"å•";s:2:"°Þ";s:3:"å••";s:2:"°ß";s:3:"唯";s:2:"°à";s:3:"啤";s:2:"°á";s:3:"唸";s:2:"°â";s:3:"å”®";s:2:"°ã";s:3:"啜";s:2:"°ä";s:3:"唬";s:2:"°å";s:3:"å•£";s:2:"°æ";s:3:"唳";s:2:"°ç";s:3:"å•";s:2:"°è";s:3:"å•—";s:2:"°é";s:3:"圈";s:2:"°ê";s:3:"國";s:2:"°ë";s:3:"圉";s:2:"°ì";s:3:"域";s:2:"°í";s:3:"å …";s:2:"°î";s:3:"å Š";s:2:"°ï";s:3:"å †";s:2:"°ð";s:3:"埠";s:2:"°ñ";s:3:"埤";s:2:"°ò";s:3:"基";s:2:"°ó";s:3:"å ‚";s:2:"°ô";s:3:"å µ";s:2:"°õ";s:3:"執";s:2:"°ö";s:3:"培";s:2:"°÷";s:3:"夠";s:2:"°ø";s:3:"奢";s:2:"°ù";s:3:"娶";s:2:"°ú";s:3:"å©";s:2:"°û";s:3:"婉";s:2:"°ü";s:3:"婦";s:2:"°ý";s:3:"婪";s:2:"°þ";s:3:"å©€";s:2:"±@";s:3:"娼";s:2:"±A";s:3:"å©¢";s:2:"±B";s:3:"婚";s:2:"±C";s:3:"婆";s:2:"±D";s:3:"婊";s:2:"±E";s:3:"å­°";s:2:"±F";s:3:"寇";s:2:"±G";s:3:"寅";s:2:"±H";s:3:"寄";s:2:"±I";s:3:"寂";s:2:"±J";s:3:"宿";s:2:"±K";s:3:"密";s:2:"±L";s:3:"å°‰";s:2:"±M";s:3:"å°ˆ";s:2:"±N";s:3:"å°‡";s:2:"±O";s:3:"å± ";s:2:"±P";s:3:"屜";s:2:"±Q";s:3:"å±";s:2:"±R";s:3:"å´‡";s:2:"±S";s:3:"å´†";s:2:"±T";s:3:"å´Ž";s:2:"±U";s:3:"å´›";s:2:"±V";s:3:"å´–";s:2:"±W";s:3:"å´¢";s:2:"±X";s:3:"å´‘";s:2:"±Y";s:3:"å´©";s:2:"±Z";s:3:"å´”";s:2:"±[";s:3:"å´™";s:2:"±\";s:3:"å´¤";s:2:"±]";s:3:"å´§";s:2:"±^";s:3:"å´—";s:2:"±_";s:3:"å·¢";s:2:"±`";s:3:"常";s:2:"±a";s:3:"帶";s:2:"±b";s:3:"帳";s:2:"±c";s:3:"帷";s:2:"±d";s:3:"康";s:2:"±e";s:3:"庸";s:2:"±f";s:3:"庶";s:2:"±g";s:3:"庵";s:2:"±h";s:3:"庾";s:2:"±i";s:3:"å¼µ";s:2:"±j";s:3:"å¼·";s:2:"±k";s:3:"å½—";s:2:"±l";s:3:"彬";s:2:"±m";s:3:"彩";s:2:"±n";s:3:"彫";s:2:"±o";s:3:"å¾—";s:2:"±p";s:3:"å¾™";s:2:"±q";s:3:"從";s:2:"±r";s:3:"徘";s:2:"±s";s:3:"御";s:2:"±t";s:3:"å¾ ";s:2:"±u";s:3:"徜";s:2:"±v";s:3:"æ¿";s:2:"±w";s:3:"æ‚£";s:2:"±x";s:3:"悉";s:2:"±y";s:3:"æ‚ ";s:2:"±z";s:3:"您";s:2:"±{";s:3:"惋";s:2:"±|";s:3:"æ‚´";s:2:"±}";s:3:"惦";s:2:"±~";s:3:"悽";s:2:"±¡";s:3:"情";s:2:"±¢";s:3:"æ‚»";s:2:"±£";s:3:"悵";s:2:"±¤";s:3:"惜";s:2:"±¥";s:3:"悼";s:2:"±¦";s:3:"惘";s:2:"±§";s:3:"惕";s:2:"±¨";s:3:"惆";s:2:"±©";s:3:"惟";s:2:"±ª";s:3:"悸";s:2:"±«";s:3:"惚";s:2:"±¬";s:3:"惇";s:2:"±­";s:3:"戚";s:2:"±®";s:3:"戛";s:2:"±¯";s:3:"扈";s:2:"±°";s:3:"掠";s:2:"±±";s:3:"控";s:2:"±²";s:3:"æ²";s:2:"±³";s:3:"掖";s:2:"±´";s:3:"探";s:2:"±µ";s:3:"接";s:2:"±¶";s:3:"æ·";s:2:"±·";s:3:"æ§";s:2:"±¸";s:3:"掘";s:2:"±¹";s:3:"措";s:2:"±º";s:3:"æ±";s:2:"±»";s:3:"掩";s:2:"±¼";s:3:"掉";s:2:"±½";s:3:"掃";s:2:"±¾";s:3:"掛";s:2:"±¿";s:3:"æ«";s:2:"±À";s:3:"推";s:2:"±Á";s:3:"掄";s:2:"±Â";s:3:"授";s:2:"±Ã";s:3:"掙";s:2:"±Ä";s:3:"採";s:2:"±Å";s:3:"掬";s:2:"±Æ";s:3:"排";s:2:"±Ç";s:3:"æŽ";s:2:"±È";s:3:"掀";s:2:"±É";s:3:"æ»";s:2:"±Ê";s:3:"æ©";s:2:"±Ë";s:3:"æ¨";s:2:"±Ì";s:3:"æº";s:2:"±Í";s:3:"æ•";s:2:"±Î";s:3:"æ•–";s:2:"±Ï";s:3:"æ•‘";s:2:"±Ð";s:3:"æ•™";s:2:"±Ñ";s:3:"æ•—";s:2:"±Ò";s:3:"啟";s:2:"±Ó";s:3:"æ•";s:2:"±Ô";s:3:"敘";s:2:"±Õ";s:3:"æ••";s:2:"±Ö";s:3:"æ•”";s:2:"±×";s:3:"æ–œ";s:2:"±Ø";s:3:"æ–›";s:2:"±Ù";s:3:"æ–¬";s:2:"±Ú";s:3:"æ—";s:2:"±Û";s:3:"æ—‹";s:2:"±Ü";s:3:"æ—Œ";s:2:"±Ý";s:3:"æ—Ž";s:2:"±Þ";s:3:"æ™";s:2:"±ß";s:3:"晚";s:2:"±à";s:3:"晤";s:2:"±á";s:3:"晨";s:2:"±â";s:3:"晦";s:2:"±ã";s:3:"晞";s:2:"±ä";s:3:"曹";s:2:"±å";s:3:"å‹—";s:2:"±æ";s:3:"望";s:2:"±ç";s:3:"æ¢";s:2:"±è";s:3:"梯";s:2:"±é";s:3:"梢";s:2:"±ê";s:3:"梓";s:2:"±ë";s:3:"梵";s:2:"±ì";s:3:"æ¡¿";s:2:"±í";s:3:"æ¡¶";s:2:"±î";s:3:"梱";s:2:"±ï";s:3:"梧";s:2:"±ð";s:3:"梗";s:2:"±ñ";s:3:"械";s:2:"±ò";s:3:"梃";s:2:"±ó";s:3:"棄";s:2:"±ô";s:3:"梭";s:2:"±õ";s:3:"梆";s:2:"±ö";s:3:"梅";s:2:"±÷";s:3:"梔";s:2:"±ø";s:3:"æ¢";s:2:"±ù";s:3:"梨";s:2:"±ú";s:3:"梟";s:2:"±û";s:3:"梡";s:2:"±ü";s:3:"梂";s:2:"±ý";s:3:"欲";s:2:"±þ";s:3:"殺";s:2:"²@";s:3:"毫";s:2:"²A";s:3:"毬";s:2:"²B";s:3:"æ°«";s:2:"²C";s:3:"æ¶Ž";s:2:"²D";s:3:"æ¶¼";s:2:"²E";s:3:"æ·³";s:2:"²F";s:3:"æ·™";s:2:"²G";s:3:"æ¶²";s:2:"²H";s:3:"æ·¡";s:2:"²I";s:3:"æ·Œ";s:2:"²J";s:3:"æ·¤";s:2:"²K";s:3:"æ·»";s:2:"²L";s:3:"æ·º";s:2:"²M";s:3:"清";s:2:"²N";s:3:"æ·‡";s:2:"²O";s:3:"æ·‹";s:2:"²P";s:3:"涯";s:2:"²Q";s:3:"æ·‘";s:2:"²R";s:3:"æ¶®";s:2:"²S";s:3:"æ·ž";s:2:"²T";s:3:"æ·¹";s:2:"²U";s:3:"涸";s:2:"²V";s:3:"æ··";s:2:"²W";s:3:"æ·µ";s:2:"²X";s:3:"æ·…";s:2:"²Y";s:3:"æ·’";s:2:"²Z";s:3:"渚";s:2:"²[";s:3:"æ¶µ";s:2:"²\";s:3:"æ·š";s:2:"²]";s:3:"æ·«";s:2:"²^";s:3:"æ·˜";s:2:"²_";s:3:"æ·ª";s:2:"²`";s:3:"æ·±";s:2:"²a";s:3:"æ·®";s:2:"²b";s:3:"æ·¨";s:2:"²c";s:3:"æ·†";s:2:"²d";s:3:"æ·„";s:2:"²e";s:3:"涪";s:2:"²f";s:3:"æ·¬";s:2:"²g";s:3:"æ¶¿";s:2:"²h";s:3:"æ·¦";s:2:"²i";s:3:"烹";s:2:"²j";s:3:"焉";s:2:"²k";s:3:"焊";s:2:"²l";s:3:"烽";s:2:"²m";s:3:"烯";s:2:"²n";s:3:"爽";s:2:"²o";s:3:"牽";s:2:"²p";s:3:"çŠ";s:2:"²q";s:3:"猜";s:2:"²r";s:3:"猛";s:2:"²s";s:3:"猖";s:2:"²t";s:3:"猓";s:2:"²u";s:3:"猙";s:2:"²v";s:3:"率";s:2:"²w";s:3:"ç…";s:2:"²x";s:3:"çŠ";s:2:"²y";s:3:"çƒ";s:2:"²z";s:3:"ç†";s:2:"²{";s:3:"ç¾";s:2:"²|";s:3:"ç";s:2:"²}";s:3:"ç“ ";s:2:"²~";s:3:"ç“¶";s:2:"²¡";s:3:"ç“·";s:2:"²¢";s:3:"甜";s:2:"²£";s:3:"產";s:2:"²¤";s:3:"ç•¥";s:2:"²¥";s:3:"畦";s:2:"²¦";s:3:"ç•¢";s:2:"²§";s:3:"ç•°";s:2:"²¨";s:3:"ç–";s:2:"²©";s:3:"ç—”";s:2:"²ª";s:3:"ç—•";s:2:"²«";s:3:"ç–µ";s:2:"²¬";s:3:"ç—Š";s:2:"²­";s:3:"ç—";s:2:"²®";s:3:"皎";s:2:"²¯";s:3:"ç›”";s:2:"²°";s:3:"ç›’";s:2:"²±";s:3:"ç››";s:2:"²²";s:3:"眷";s:2:"²³";s:3:"眾";s:2:"²´";s:3:"眼";s:2:"²µ";s:3:"眶";s:2:"²¶";s:3:"眸";s:2:"²·";s:3:"眺";s:2:"²¸";s:3:"ç¡«";s:2:"²¹";s:3:"硃";s:2:"²º";s:3:"硎";s:2:"²»";s:3:"祥";s:2:"²¼";s:3:"票";s:2:"²½";s:3:"祭";s:2:"²¾";s:3:"ç§»";s:2:"²¿";s:3:"窒";s:2:"²À";s:3:"窕";s:2:"²Á";s:3:"笠";s:2:"²Â";s:3:"笨";s:2:"²Ã";s:3:"笛";s:2:"²Ä";s:3:"第";s:2:"²Å";s:3:"符";s:2:"²Æ";s:3:"笙";s:2:"²Ç";s:3:"笞";s:2:"²È";s:3:"笮";s:2:"²É";s:3:"ç²’";s:2:"²Ê";s:3:"ç²—";s:2:"²Ë";s:3:"粕";s:2:"²Ì";s:3:"絆";s:2:"²Í";s:3:"絃";s:2:"²Î";s:3:"çµ±";s:2:"²Ï";s:3:"ç´®";s:2:"²Ð";s:3:"ç´¹";s:2:"²Ñ";s:3:"ç´¼";s:2:"²Ò";s:3:"çµ€";s:2:"²Ó";s:3:"ç´°";s:2:"²Ô";s:3:"ç´³";s:2:"²Õ";s:3:"組";s:2:"²Ö";s:3:"ç´¯";s:2:"²×";s:3:"終";s:2:"²Ø";s:3:"ç´²";s:2:"²Ù";s:3:"ç´±";s:2:"²Ú";s:3:"ç¼½";s:2:"²Û";s:3:"羞";s:2:"²Ü";s:3:"羚";s:2:"²Ý";s:3:"翌";s:2:"²Þ";s:3:"翎";s:2:"²ß";s:3:"ç¿’";s:2:"²à";s:3:"耜";s:2:"²á";s:3:"èŠ";s:2:"²â";s:3:"è†";s:2:"²ã";s:3:"脯";s:2:"²ä";s:3:"è„–";s:2:"²å";s:3:"è„£";s:2:"²æ";s:3:"è„«";s:2:"²ç";s:3:"è„©";s:2:"²è";s:3:"è„°";s:2:"²é";s:3:"脤";s:2:"²ê";s:3:"舂";s:2:"²ë";s:3:"舵";s:2:"²ì";s:3:"舷";s:2:"²í";s:3:"舶";s:2:"²î";s:3:"船";s:2:"²ï";s:3:"莎";s:2:"²ð";s:3:"莞";s:2:"²ñ";s:3:"莘";s:2:"²ò";s:3:"è¸";s:2:"²ó";s:3:"莢";s:2:"²ô";s:3:"莖";s:2:"²õ";s:3:"莽";s:2:"²ö";s:3:"莫";s:2:"²÷";s:3:"莒";s:2:"²ø";s:3:"莊";s:2:"²ù";s:3:"莓";s:2:"²ú";s:3:"莉";s:2:"²û";s:3:"莠";s:2:"²ü";s:3:"è·";s:2:"²ý";s:3:"è»";s:2:"²þ";s:3:"è¼";s:2:"³@";s:3:"莆";s:2:"³A";s:3:"莧";s:2:"³B";s:3:"處";s:2:"³C";s:3:"彪";s:2:"³D";s:3:"蛇";s:2:"³E";s:3:"蛀";s:2:"³F";s:3:"èš¶";s:2:"³G";s:3:"蛄";s:2:"³H";s:3:"èšµ";s:2:"³I";s:3:"蛆";s:2:"³J";s:3:"蛋";s:2:"³K";s:3:"èš±";s:2:"³L";s:3:"蚯";s:2:"³M";s:3:"蛉";s:2:"³N";s:3:"è¡“";s:2:"³O";s:3:"袞";s:2:"³P";s:3:"袈";s:2:"³Q";s:3:"被";s:2:"³R";s:3:"袒";s:2:"³S";s:3:"袖";s:2:"³T";s:3:"è¢";s:2:"³U";s:3:"袋";s:2:"³V";s:3:"覓";s:2:"³W";s:3:"è¦";s:2:"³X";s:3:"訪";s:2:"³Y";s:3:"è¨";s:2:"³Z";s:3:"訣";s:2:"³[";s:3:"訥";s:2:"³\";s:3:"許";s:2:"³]";s:3:"設";s:2:"³^";s:3:"訟";s:2:"³_";s:3:"訛";s:2:"³`";s:3:"訢";s:2:"³a";s:3:"豉";s:2:"³b";s:3:"豚";s:2:"³c";s:3:"販";s:2:"³d";s:3:"責";s:2:"³e";s:3:"貫";s:2:"³f";s:3:"貨";s:2:"³g";s:3:"貪";s:2:"³h";s:3:"è²§";s:2:"³i";s:3:"èµ§";s:2:"³j";s:3:"赦";s:2:"³k";s:3:"è¶¾";s:2:"³l";s:3:"趺";s:2:"³m";s:3:"è»›";s:2:"³n";s:3:"軟";s:2:"³o";s:3:"這";s:2:"³p";s:3:"é€";s:2:"³q";s:3:"通";s:2:"³r";s:3:"逗";s:2:"³s";s:3:"連";s:2:"³t";s:3:"速";s:2:"³u";s:3:"é€";s:2:"³v";s:3:"é€";s:2:"³w";s:3:"逕";s:2:"³x";s:3:"逞";s:2:"³y";s:3:"造";s:2:"³z";s:3:"é€";s:2:"³{";s:3:"逢";s:2:"³|";s:3:"逖";s:2:"³}";s:3:"逛";s:2:"³~";s:3:"途";s:2:"³¡";s:3:"部";s:2:"³¢";s:3:"郭";s:2:"³£";s:3:"都";s:2:"³¤";s:3:"é…—";s:2:"³¥";s:3:"野";s:2:"³¦";s:3:"釵";s:2:"³§";s:3:"釦";s:2:"³¨";s:3:"釣";s:2:"³©";s:3:"釧";s:2:"³ª";s:3:"釭";s:2:"³«";s:3:"釩";s:2:"³¬";s:3:"é–‰";s:2:"³­";s:3:"陪";s:2:"³®";s:3:"陵";s:2:"³¯";s:3:"陳";s:2:"³°";s:3:"陸";s:2:"³±";s:3:"é™°";s:2:"³²";s:3:"é™´";s:2:"³³";s:3:"é™¶";s:2:"³´";s:3:"é™·";s:2:"³µ";s:3:"陬";s:2:"³¶";s:3:"雀";s:2:"³·";s:3:"雪";s:2:"³¸";s:3:"雩";s:2:"³¹";s:3:"ç« ";s:2:"³º";s:3:"竟";s:2:"³»";s:3:"é ‚";s:2:"³¼";s:3:"é ƒ";s:2:"³½";s:3:"é­š";s:2:"³¾";s:3:"é³¥";s:2:"³¿";s:3:"é¹µ";s:2:"³À";s:3:"鹿";s:2:"³Á";s:3:"麥";s:2:"³Â";s:3:"麻";s:2:"³Ã";s:3:"å‚¢";s:2:"³Ä";s:3:"å‚";s:2:"³Å";s:3:"å‚…";s:2:"³Æ";s:3:"å‚™";s:2:"³Ç";s:3:"å‚‘";s:2:"³È";s:3:"å‚€";s:2:"³É";s:3:"å‚–";s:2:"³Ê";s:3:"傘";s:2:"³Ë";s:3:"傚";s:2:"³Ì";s:3:"最";s:2:"³Í";s:3:"凱";s:2:"³Î";s:3:"割";s:2:"³Ï";s:3:"剴";s:2:"³Ð";s:3:"創";s:2:"³Ñ";s:3:"剩";s:2:"³Ò";s:3:"勞";s:2:"³Ó";s:3:"å‹";s:2:"³Ô";s:3:"å‹›";s:2:"³Õ";s:3:"åš";s:2:"³Ö";s:3:"厥";s:2:"³×";s:3:"å•»";s:2:"³Ø";s:3:"å–€";s:2:"³Ù";s:3:"å–§";s:2:"³Ú";s:3:"啼";s:2:"³Û";s:3:"å–Š";s:2:"³Ü";s:3:"å–";s:2:"³Ý";s:3:"å–˜";s:2:"³Þ";s:3:"å–‚";s:2:"³ß";s:3:"å–œ";s:2:"³à";s:3:"å–ª";s:2:"³á";s:3:"å–”";s:2:"³â";s:3:"å–‡";s:2:"³ã";s:3:"å–‹";s:2:"³ä";s:3:"å–ƒ";s:2:"³å";s:3:"å–³";s:2:"³æ";s:3:"å–®";s:2:"³ç";s:3:"å–Ÿ";s:2:"³è";s:3:"唾";s:2:"³é";s:3:"å–²";s:2:"³ê";s:3:"å–š";s:2:"³ë";s:3:"å–»";s:2:"³ì";s:3:"å–¬";s:2:"³í";s:3:"å–±";s:2:"³î";s:3:"啾";s:2:"³ï";s:3:"å–‰";s:2:"³ð";s:3:"å–«";s:2:"³ñ";s:3:"å–™";s:2:"³ò";s:3:"åœ";s:2:"³ó";s:3:"å ¯";s:2:"³ô";s:3:"å ª";s:2:"³õ";s:3:"å ´";s:2:"³ö";s:3:"å ¤";s:2:"³÷";s:3:"å °";s:2:"³ø";s:3:"å ±";s:2:"³ù";s:3:"å ¡";s:2:"³ú";s:3:"å ";s:2:"³û";s:3:"å  ";s:2:"³ü";s:3:"壹";s:2:"³ý";s:3:"壺";s:2:"³þ";s:3:"奠";s:2:"´@";s:3:"å©·";s:2:"´A";s:3:"媚";s:2:"´B";s:3:"å©¿";s:2:"´C";s:3:"媒";s:2:"´D";s:3:"媛";s:2:"´E";s:3:"媧";s:2:"´F";s:3:"å­³";s:2:"´G";s:3:"å­±";s:2:"´H";s:3:"寒";s:2:"´I";s:3:"富";s:2:"´J";s:3:"寓";s:2:"´K";s:3:"å¯";s:2:"´L";s:3:"å°Š";s:2:"´M";s:3:"å°‹";s:2:"´N";s:3:"å°±";s:2:"´O";s:3:"嵌";s:2:"´P";s:3:"åµ";s:2:"´Q";s:3:"å´´";s:2:"´R";s:3:"嵇";s:2:"´S";s:3:"å·½";s:2:"´T";s:3:"å¹…";s:2:"´U";s:3:"帽";s:2:"´V";s:3:"å¹€";s:2:"´W";s:3:"幃";s:2:"´X";s:3:"å¹¾";s:2:"´Y";s:3:"廊";s:2:"´Z";s:3:"å»";s:2:"´[";s:3:"廂";s:2:"´\";s:3:"廄";s:2:"´]";s:3:"å¼¼";s:2:"´^";s:3:"å½­";s:2:"´_";s:3:"復";s:2:"´`";s:3:"循";s:2:"´a";s:3:"徨";s:2:"´b";s:3:"惑";s:2:"´c";s:3:"惡";s:2:"´d";s:3:"悲";s:2:"´e";s:3:"æ‚¶";s:2:"´f";s:3:"惠";s:2:"´g";s:3:"愜";s:2:"´h";s:3:"æ„£";s:2:"´i";s:3:"惺";s:2:"´j";s:3:"æ„•";s:2:"´k";s:3:"惰";s:2:"´l";s:3:"惻";s:2:"´m";s:3:"惴";s:2:"´n";s:3:"æ…¨";s:2:"´o";s:3:"惱";s:2:"´p";s:3:"愎";s:2:"´q";s:3:"惶";s:2:"´r";s:3:"愉";s:2:"´s";s:3:"æ„€";s:2:"´t";s:3:"æ„’";s:2:"´u";s:3:"戟";s:2:"´v";s:3:"扉";s:2:"´w";s:3:"掣";s:2:"´x";s:3:"掌";s:2:"´y";s:3:"æ";s:2:"´z";s:3:"æ€";s:2:"´{";s:3:"æ©";s:2:"´|";s:3:"æ‰";s:2:"´}";s:3:"æ†";s:2:"´~";s:3:"æ";s:2:"´¡";s:3:"æ’";s:2:"´¢";s:3:"æ£";s:2:"´£";s:3:"æ";s:2:"´¤";s:3:"æ¡";s:2:"´¥";s:3:"æ–";s:2:"´¦";s:3:"æ­";s:2:"´§";s:3:"æ®";s:2:"´¨";s:3:"æ¶";s:2:"´©";s:3:"æ´";s:2:"´ª";s:3:"æª";s:2:"´«";s:3:"æ›";s:2:"´¬";s:3:"æ‘’";s:2:"´­";s:3:"æš";s:2:"´®";s:3:"æ¹";s:2:"´¯";s:3:"敞";s:2:"´°";s:3:"敦";s:2:"´±";s:3:"æ•¢";s:2:"´²";s:3:"æ•£";s:2:"´³";s:3:"æ–‘";s:2:"´´";s:3:"æ–";s:2:"´µ";s:3:"æ–¯";s:2:"´¶";s:3:"æ™®";s:2:"´·";s:3:"æ™°";s:2:"´¸";s:3:"æ™´";s:2:"´¹";s:3:"æ™¶";s:2:"´º";s:3:"景";s:2:"´»";s:3:"æš‘";s:2:"´¼";s:3:"智";s:2:"´½";s:3:"晾";s:2:"´¾";s:3:"æ™·";s:2:"´¿";s:3:"曾";s:2:"´À";s:3:"替";s:2:"´Á";s:3:"期";s:2:"´Â";s:3:"æœ";s:2:"´Ã";s:3:"棺";s:2:"´Ä";s:3:"棕";s:2:"´Å";s:3:"棠";s:2:"´Æ";s:3:"棘";s:2:"´Ç";s:3:"棗";s:2:"´È";s:3:"椅";s:2:"´É";s:3:"棟";s:2:"´Ê";s:3:"棵";s:2:"´Ë";s:3:"森";s:2:"´Ì";s:3:"棧";s:2:"´Í";s:3:"棹";s:2:"´Î";s:3:"棒";s:2:"´Ï";s:3:"棲";s:2:"´Ð";s:3:"棣";s:2:"´Ñ";s:3:"棋";s:2:"´Ò";s:3:"æ£";s:2:"´Ó";s:3:"æ¤";s:2:"´Ô";s:3:"椒";s:2:"´Õ";s:3:"椎";s:2:"´Ö";s:3:"棉";s:2:"´×";s:3:"棚";s:2:"´Ø";s:3:"楮";s:2:"´Ù";s:3:"棻";s:2:"´Ú";s:3:"款";s:2:"´Û";s:3:"欺";s:2:"´Ü";s:3:"欽";s:2:"´Ý";s:3:"殘";s:2:"´Þ";s:3:"æ®–";s:2:"´ß";s:3:"殼";s:2:"´à";s:3:"毯";s:2:"´á";s:3:"æ°®";s:2:"´â";s:3:"æ°¯";s:2:"´ã";s:3:"æ°¬";s:2:"´ä";s:3:"港";s:2:"´å";s:3:"游";s:2:"´æ";s:3:"æ¹”";s:2:"´ç";s:3:"渡";s:2:"´è";s:3:"渲";s:2:"´é";s:3:"æ¹§";s:2:"´ê";s:3:"湊";s:2:"´ë";s:3:"渠";s:2:"´ì";s:3:"渥";s:2:"´í";s:3:"渣";s:2:"´î";s:3:"減";s:2:"´ï";s:3:"æ¹›";s:2:"´ð";s:3:"湘";s:2:"´ñ";s:3:"渤";s:2:"´ò";s:3:"æ¹–";s:2:"´ó";s:3:"æ¹®";s:2:"´ô";s:3:"渭";s:2:"´õ";s:3:"渦";s:2:"´ö";s:3:"湯";s:2:"´÷";s:3:"渴";s:2:"´ø";s:3:"æ¹";s:2:"´ù";s:3:"渺";s:2:"´ú";s:3:"測";s:2:"´û";s:3:"湃";s:2:"´ü";s:3:"æ¸";s:2:"´ý";s:3:"渾";s:2:"´þ";s:3:"滋";s:2:"µ@";s:3:"溉";s:2:"µA";s:3:"渙";s:2:"µB";s:3:"湎";s:2:"µC";s:3:"æ¹£";s:2:"µD";s:3:"湄";s:2:"µE";s:3:"æ¹²";s:2:"µF";s:3:"湩";s:2:"µG";s:3:"湟";s:2:"µH";s:3:"ç„™";s:2:"µI";s:3:"焚";s:2:"µJ";s:3:"焦";s:2:"µK";s:3:"ç„°";s:2:"µL";s:3:"ç„¡";s:2:"µM";s:3:"ç„¶";s:2:"µN";s:3:"ç…®";s:2:"µO";s:3:"焜";s:2:"µP";s:3:"牌";s:2:"µQ";s:3:"犄";s:2:"µR";s:3:"犀";s:2:"µS";s:3:"猶";s:2:"µT";s:3:"猥";s:2:"µU";s:3:"猴";s:2:"µV";s:3:"猩";s:2:"µW";s:3:"çº";s:2:"µX";s:3:"çª";s:2:"µY";s:3:"ç³";s:2:"µZ";s:3:"ç¢";s:2:"µ[";s:3:"ç¥";s:2:"µ\";s:3:"çµ";s:2:"µ]";s:3:"ç¶";s:2:"µ^";s:3:"ç´";s:2:"µ_";s:3:"ç¯";s:2:"µ`";s:3:"ç›";s:2:"µa";s:3:"ç¦";s:2:"µb";s:3:"ç¨";s:2:"µc";s:3:"甥";s:2:"µd";s:3:"甦";s:2:"µe";s:3:"ç•«";s:2:"µf";s:3:"番";s:2:"µg";s:3:"ç—¢";s:2:"µh";s:3:"ç—›";s:2:"µi";s:3:"ç—£";s:2:"µj";s:3:"ç—™";s:2:"µk";s:3:"ç—˜";s:2:"µl";s:3:"ç—ž";s:2:"µm";s:3:"ç— ";s:2:"µn";s:3:"ç™»";s:2:"µo";s:3:"發";s:2:"µp";s:3:"çš–";s:2:"µq";s:3:"çš“";s:2:"µr";s:3:"çš´";s:2:"µs";s:3:"盜";s:2:"µt";s:3:"ç";s:2:"µu";s:3:"短";s:2:"µv";s:3:"ç¡";s:2:"µw";s:3:"硬";s:2:"µx";s:3:"硯";s:2:"µy";s:3:"ç¨";s:2:"µz";s:3:"稈";s:2:"µ{";s:3:"程";s:2:"µ|";s:3:"稅";s:2:"µ}";s:3:"稀";s:2:"µ~";s:3:"窘";s:2:"µ¡";s:3:"窗";s:2:"µ¢";s:3:"窖";s:2:"µ£";s:3:"ç«¥";s:2:"µ¤";s:3:"ç«£";s:2:"µ¥";s:3:"ç­‰";s:2:"µ¦";s:3:"ç­–";s:2:"µ§";s:3:"ç­†";s:2:"µ¨";s:3:"ç­";s:2:"µ©";s:3:"ç­’";s:2:"µª";s:3:"ç­”";s:2:"µ«";s:3:"ç­";s:2:"µ¬";s:3:"ç­‹";s:2:"µ­";s:3:"ç­";s:2:"µ®";s:3:"ç­‘";s:2:"µ¯";s:3:"粟";s:2:"µ°";s:3:"ç²¥";s:2:"µ±";s:3:"絞";s:2:"µ²";s:3:"çµ";s:2:"µ³";s:3:"絨";s:2:"µ´";s:3:"絕";s:2:"µµ";s:3:"ç´«";s:2:"µ¶";s:3:"çµ®";s:2:"µ·";s:3:"çµ²";s:2:"µ¸";s:3:"絡";s:2:"µ¹";s:3:"給";s:2:"µº";s:3:"çµ¢";s:2:"µ»";s:3:"çµ°";s:2:"µ¼";s:3:"çµ³";s:2:"µ½";s:3:"å–„";s:2:"µ¾";s:3:"ç¿”";s:2:"µ¿";s:3:"ç¿•";s:2:"µÀ";s:3:"耋";s:2:"µÁ";s:3:"è’";s:2:"µÂ";s:3:"è‚…";s:2:"µÃ";s:3:"è…•";s:2:"µÄ";s:3:"è…”";s:2:"µÅ";s:3:"è…‹";s:2:"µÆ";s:3:"è…‘";s:2:"µÇ";s:3:"è…Ž";s:2:"µÈ";s:3:"脹";s:2:"µÉ";s:3:"è…†";s:2:"µÊ";s:3:"脾";s:2:"µË";s:3:"è…Œ";s:2:"µÌ";s:3:"è…“";s:2:"µÍ";s:3:"è…´";s:2:"µÎ";s:3:"舒";s:2:"µÏ";s:3:"舜";s:2:"µÐ";s:3:"è©";s:2:"µÑ";s:3:"èƒ";s:2:"µÒ";s:3:"è¸";s:2:"µÓ";s:3:"è";s:2:"µÔ";s:3:"è ";s:2:"µÕ";s:3:"è…";s:2:"µÖ";s:3:"è‹";s:2:"µ×";s:3:"è";s:2:"µØ";s:3:"è¯";s:2:"µÙ";s:3:"è±";s:2:"µÚ";s:3:"è´";s:2:"µÛ";s:3:"è‘—";s:2:"µÜ";s:3:"èŠ";s:2:"µÝ";s:3:"è°";s:2:"µÞ";s:3:"èŒ";s:2:"µß";s:3:"èŒ";s:2:"µà";s:3:"è½";s:2:"µá";s:3:"è²";s:2:"µâ";s:3:"èŠ";s:2:"µã";s:3:"è¸";s:2:"µä";s:3:"èŽ";s:2:"µå";s:3:"è„";s:2:"µæ";s:3:"èœ";s:2:"µç";s:3:"è‡";s:2:"µè";s:3:"è”";s:2:"µé";s:3:"èŸ";s:2:"µê";s:3:"è™›";s:2:"µë";s:3:"蛟";s:2:"µì";s:3:"è›™";s:2:"µí";s:3:"è›­";s:2:"µî";s:3:"è›”";s:2:"µï";s:3:"è››";s:2:"µð";s:3:"蛤";s:2:"µñ";s:3:"è›";s:2:"µò";s:3:"蛞";s:2:"µó";s:3:"è¡—";s:2:"µô";s:3:"è£";s:2:"µõ";s:3:"裂";s:2:"µö";s:3:"袱";s:2:"µ÷";s:3:"覃";s:2:"µø";s:3:"視";s:2:"µù";s:3:"註";s:2:"µú";s:3:"è© ";s:2:"µû";s:3:"è©•";s:2:"µü";s:3:"詞";s:2:"µý";s:3:"証";s:2:"µþ";s:3:"è©";s:2:"¶@";s:3:"è©”";s:2:"¶A";s:3:"è©›";s:2:"¶B";s:3:"è©";s:2:"¶C";s:3:"詆";s:2:"¶D";s:3:"訴";s:2:"¶E";s:3:"診";s:2:"¶F";s:3:"訶";s:2:"¶G";s:3:"è©–";s:2:"¶H";s:3:"象";s:2:"¶I";s:3:"貂";s:2:"¶J";s:3:"貯";s:2:"¶K";s:3:"è²¼";s:2:"¶L";s:3:"è²³";s:2:"¶M";s:3:"è²½";s:2:"¶N";s:3:"è³";s:2:"¶O";s:3:"è²»";s:2:"¶P";s:3:"è³€";s:2:"¶Q";s:3:"è²´";s:2:"¶R";s:3:"è²·";s:2:"¶S";s:3:"è²¶";s:2:"¶T";s:3:"貿";s:2:"¶U";s:3:"貸";s:2:"¶V";s:3:"è¶Š";s:2:"¶W";s:3:"è¶…";s:2:"¶X";s:3:"è¶";s:2:"¶Y";s:3:"è·Ž";s:2:"¶Z";s:3:"è·";s:2:"¶[";s:3:"è·‹";s:2:"¶\";s:3:"è·š";s:2:"¶]";s:3:"è·‘";s:2:"¶^";s:3:"è·Œ";s:2:"¶_";s:3:"è·›";s:2:"¶`";s:3:"è·†";s:2:"¶a";s:3:"è»»";s:2:"¶b";s:3:"軸";s:2:"¶c";s:3:"軼";s:2:"¶d";s:3:"辜";s:2:"¶e";s:3:"逮";s:2:"¶f";s:3:"逵";s:2:"¶g";s:3:"週";s:2:"¶h";s:3:"逸";s:2:"¶i";s:3:"進";s:2:"¶j";s:3:"逶";s:2:"¶k";s:3:"é„‚";s:2:"¶l";s:3:"郵";s:2:"¶m";s:3:"鄉";s:2:"¶n";s:3:"郾";s:2:"¶o";s:3:"é…£";s:2:"¶p";s:3:"é…¥";s:2:"¶q";s:3:"é‡";s:2:"¶r";s:3:"鈔";s:2:"¶s";s:3:"鈕";s:2:"¶t";s:3:"鈣";s:2:"¶u";s:3:"鈉";s:2:"¶v";s:3:"鈞";s:2:"¶w";s:3:"éˆ";s:2:"¶x";s:3:"éˆ";s:2:"¶y";s:3:"鈇";s:2:"¶z";s:3:"鈑";s:2:"¶{";s:3:"é–”";s:2:"¶|";s:3:"é–";s:2:"¶}";s:3:"é–‹";s:2:"¶~";s:3:"é–‘";s:2:"¶¡";s:3:"é–“";s:2:"¶¢";s:3:"é–’";s:2:"¶£";s:3:"é–Ž";s:2:"¶¤";s:3:"隊";s:2:"¶¥";s:3:"階";s:2:"¶¦";s:3:"éš‹";s:2:"¶§";s:3:"陽";s:2:"¶¨";s:3:"éš…";s:2:"¶©";s:3:"隆";s:2:"¶ª";s:3:"éš";s:2:"¶«";s:3:"陲";s:2:"¶¬";s:3:"éš„";s:2:"¶­";s:3:"é›";s:2:"¶®";s:3:"é›…";s:2:"¶¯";s:3:"雄";s:2:"¶°";s:3:"集";s:2:"¶±";s:3:"雇";s:2:"¶²";s:3:"雯";s:2:"¶³";s:3:"雲";s:2:"¶´";s:3:"韌";s:2:"¶µ";s:3:"é …";s:2:"¶¶";s:3:"é †";s:2:"¶·";s:3:"é ˆ";s:2:"¶¸";s:3:"飧";s:2:"¶¹";s:3:"飪";s:2:"¶º";s:3:"飯";s:2:"¶»";s:3:"飩";s:2:"¶¼";s:3:"飲";s:2:"¶½";s:3:"飭";s:2:"¶¾";s:3:"馮";s:2:"¶¿";s:3:"馭";s:2:"¶À";s:3:"黃";s:2:"¶Á";s:3:"é»";s:2:"¶Â";s:3:"黑";s:2:"¶Ã";s:3:"亂";s:2:"¶Ä";s:3:"å‚­";s:2:"¶Å";s:3:"債";s:2:"¶Æ";s:3:"傲";s:2:"¶Ç";s:3:"傳";s:2:"¶È";s:3:"僅";s:2:"¶É";s:3:"傾";s:2:"¶Ê";s:3:"催";s:2:"¶Ë";s:3:"å‚·";s:2:"¶Ì";s:3:"å‚»";s:2:"¶Í";s:3:"傯";s:2:"¶Î";s:3:"僇";s:2:"¶Ï";s:3:"剿";s:2:"¶Ð";s:3:"剷";s:2:"¶Ñ";s:3:"剽";s:2:"¶Ò";s:3:"募";s:2:"¶Ó";s:3:"勦";s:2:"¶Ô";s:3:"勤";s:2:"¶Õ";s:3:"å‹¢";s:2:"¶Ö";s:3:"å‹£";s:2:"¶×";s:3:"匯";s:2:"¶Ø";s:3:"å—Ÿ";s:2:"¶Ù";s:3:"å—¨";s:2:"¶Ú";s:3:"å—“";s:2:"¶Û";s:3:"å—¦";s:2:"¶Ü";s:3:"å—Ž";s:2:"¶Ý";s:3:"å—œ";s:2:"¶Þ";s:3:"å—‡";s:2:"¶ß";s:3:"å—‘";s:2:"¶à";s:3:"å—£";s:2:"¶á";s:3:"å—¤";s:2:"¶â";s:3:"å—¯";s:2:"¶ã";s:3:"å—š";s:2:"¶ä";s:3:"å—¡";s:2:"¶å";s:3:"å—…";s:2:"¶æ";s:3:"å—†";s:2:"¶ç";s:3:"å—¥";s:2:"¶è";s:3:"å—‰";s:2:"¶é";s:3:"園";s:2:"¶ê";s:3:"圓";s:2:"¶ë";s:3:"塞";s:2:"¶ì";s:3:"å¡‘";s:2:"¶í";s:3:"塘";s:2:"¶î";s:3:"å¡—";s:2:"¶ï";s:3:"塚";s:2:"¶ð";s:3:"å¡”";s:2:"¶ñ";s:3:"å¡«";s:2:"¶ò";s:3:"塌";s:2:"¶ó";s:3:"å¡­";s:2:"¶ô";s:3:"塊";s:2:"¶õ";s:3:"å¡¢";s:2:"¶ö";s:3:"å¡’";s:2:"¶÷";s:3:"å¡‹";s:2:"¶ø";s:3:"奧";s:2:"¶ù";s:3:"å«";s:2:"¶ú";s:3:"嫉";s:2:"¶û";s:3:"嫌";s:2:"¶ü";s:3:"媾";s:2:"¶ý";s:3:"媽";s:2:"¶þ";s:3:"媼";s:2:"·@";s:3:"媳";s:2:"·A";s:3:"å«‚";s:2:"·B";s:3:"媲";s:2:"·C";s:3:"嵩";s:2:"·D";s:3:"嵯";s:2:"·E";s:3:"幌";s:2:"·F";s:3:"å¹¹";s:2:"·G";s:3:"廉";s:2:"·H";s:3:"廈";s:2:"·I";s:3:"å¼’";s:2:"·J";s:3:"å½™";s:2:"·K";s:3:"徬";s:2:"·L";s:3:"å¾®";s:2:"·M";s:3:"愚";s:2:"·N";s:3:"æ„";s:2:"·O";s:3:"æ…ˆ";s:2:"·P";s:3:"感";s:2:"·Q";s:3:"想";s:2:"·R";s:3:"æ„›";s:2:"·S";s:3:"惹";s:2:"·T";s:3:"æ„";s:2:"·U";s:3:"愈";s:2:"·V";s:3:"æ…Ž";s:2:"·W";s:3:"æ…Œ";s:2:"·X";s:3:"æ…„";s:2:"·Y";s:3:"æ…";s:2:"·Z";s:3:"愾";s:2:"·[";s:3:"æ„´";s:2:"·\";s:3:"æ„§";s:2:"·]";s:3:"æ„";s:2:"·^";s:3:"愆";s:2:"·_";s:3:"æ„·";s:2:"·`";s:3:"戡";s:2:"·a";s:3:"戢";s:2:"·b";s:3:"æ“";s:2:"·c";s:3:"æ¾";s:2:"·d";s:3:"æž";s:2:"·e";s:3:"æª";s:2:"·f";s:3:"æ­";s:2:"·g";s:3:"æ½";s:2:"·h";s:3:"æ¬";s:2:"·i";s:3:"æ";s:2:"·j";s:3:"æœ";s:2:"·k";s:3:"æ”";s:2:"·l";s:3:"æ";s:2:"·m";s:3:"æ¶";s:2:"·n";s:3:"æ–";s:2:"·o";s:3:"æ—";s:2:"·p";s:3:"æ†";s:2:"·q";s:3:"敬";s:2:"·r";s:3:"æ–Ÿ";s:2:"·s";s:3:"æ–°";s:2:"·t";s:3:"æš—";s:2:"·u";s:3:"暉";s:2:"·v";s:3:"暇";s:2:"·w";s:3:"暈";s:2:"·x";s:3:"æš–";s:2:"·y";s:3:"æš„";s:2:"·z";s:3:"暘";s:2:"·{";s:3:"æš";s:2:"·|";s:3:"會";s:2:"·}";s:3:"榔";s:2:"·~";s:3:"業";s:2:"·¡";s:3:"楚";s:2:"·¢";s:3:"楷";s:2:"·£";s:3:"楠";s:2:"·¤";s:3:"楔";s:2:"·¥";s:3:"極";s:2:"·¦";s:3:"椰";s:2:"·§";s:3:"概";s:2:"·¨";s:3:"楊";s:2:"·©";s:3:"楨";s:2:"·ª";s:3:"楫";s:2:"·«";s:3:"楞";s:2:"·¬";s:3:"楓";s:2:"·­";s:3:"楹";s:2:"·®";s:3:"榆";s:2:"·¯";s:3:"æ¥";s:2:"·°";s:3:"楣";s:2:"·±";s:3:"楛";s:2:"·²";s:3:"æ­‡";s:2:"·³";s:3:"æ­²";s:2:"·´";s:3:"毀";s:2:"·µ";s:3:"殿";s:2:"·¶";s:3:"毓";s:2:"··";s:3:"毽";s:2:"·¸";s:3:"溢";s:2:"·¹";s:3:"溯";s:2:"·º";s:3:"滓";s:2:"·»";s:3:"溶";s:2:"·¼";s:3:"滂";s:2:"·½";s:3:"æº";s:2:"·¾";s:3:"æº";s:2:"·¿";s:3:"滇";s:2:"·À";s:3:"æ»…";s:2:"·Á";s:3:"溥";s:2:"·Â";s:3:"溘";s:2:"·Ã";s:3:"溼";s:2:"·Ä";s:3:"溺";s:2:"·Å";s:3:"溫";s:2:"·Æ";s:3:"滑";s:2:"·Ç";s:3:"準";s:2:"·È";s:3:"溜";s:2:"·É";s:3:"滄";s:2:"·Ê";s:3:"æ»”";s:2:"·Ë";s:3:"溪";s:2:"·Ì";s:3:"溧";s:2:"·Í";s:3:"溴";s:2:"·Î";s:3:"ç…Ž";s:2:"·Ï";s:3:"ç…™";s:2:"·Ð";s:3:"ç…©";s:2:"·Ñ";s:3:"ç…¤";s:2:"·Ò";s:3:"ç…‰";s:2:"·Ó";s:3:"ç…§";s:2:"·Ô";s:3:"ç…œ";s:2:"·Õ";s:3:"ç…¬";s:2:"·Ö";s:3:"ç…¦";s:2:"·×";s:3:"ç…Œ";s:2:"·Ø";s:3:"ç…¥";s:2:"·Ù";s:3:"ç…ž";s:2:"·Ú";s:3:"ç…†";s:2:"·Û";s:3:"ç…¨";s:2:"·Ü";s:3:"ç…–";s:2:"·Ý";s:3:"爺";s:2:"·Þ";s:3:"牒";s:2:"·ß";s:3:"猷";s:2:"·à";s:3:"ç…";s:2:"·á";s:3:"猿";s:2:"·â";s:3:"猾";s:2:"·ã";s:3:"瑯";s:2:"·ä";s:3:"瑚";s:2:"·å";s:3:"ç‘•";s:2:"·æ";s:3:"瑟";s:2:"·ç";s:3:"瑞";s:2:"·è";s:3:"ç‘";s:2:"·é";s:3:"ç¿";s:2:"·ê";s:3:"ç‘™";s:2:"·ë";s:3:"ç‘›";s:2:"·ì";s:3:"瑜";s:2:"·í";s:3:"ç•¶";s:2:"·î";s:3:"畸";s:2:"·ï";s:3:"瘀";s:2:"·ð";s:3:"ç—°";s:2:"·ñ";s:3:"ç˜";s:2:"·ò";s:3:"ç—²";s:2:"·ó";s:3:"ç—±";s:2:"·ô";s:3:"ç—º";s:2:"·õ";s:3:"ç—¿";s:2:"·ö";s:3:"ç—´";s:2:"·÷";s:3:"ç—³";s:2:"·ø";s:3:"盞";s:2:"·ù";s:3:"盟";s:2:"·ú";s:3:"ç›";s:2:"·û";s:3:"ç«";s:2:"·ü";s:3:"ç¦";s:2:"·ý";s:3:"çž";s:2:"·þ";s:3:"ç£";s:2:"¸@";s:3:"ç¹";s:2:"¸A";s:3:"çª";s:2:"¸B";s:3:"ç¬";s:2:"¸C";s:3:"çœ";s:2:"¸D";s:3:"ç¥";s:2:"¸E";s:3:"ç¨";s:2:"¸F";s:3:"ç¢";s:2:"¸G";s:3:"矮";s:2:"¸H";s:3:"碎";s:2:"¸I";s:3:"碰";s:2:"¸J";s:3:"碗";s:2:"¸K";s:3:"碘";s:2:"¸L";s:3:"碌";s:2:"¸M";s:3:"碉";s:2:"¸N";s:3:"硼";s:2:"¸O";s:3:"碑";s:2:"¸P";s:3:"碓";s:2:"¸Q";s:3:"ç¡¿";s:2:"¸R";s:3:"祺";s:2:"¸S";s:3:"祿";s:2:"¸T";s:3:"ç¦";s:2:"¸U";s:3:"è¬";s:2:"¸V";s:3:"禽";s:2:"¸W";s:3:"稜";s:2:"¸X";s:3:"稚";s:2:"¸Y";s:3:"稠";s:2:"¸Z";s:3:"稔";s:2:"¸[";s:3:"稟";s:2:"¸\";s:3:"稞";s:2:"¸]";s:3:"窟";s:2:"¸^";s:3:"窠";s:2:"¸_";s:3:"ç­·";s:2:"¸`";s:3:"節";s:2:"¸a";s:3:"ç­ ";s:2:"¸b";s:3:"ç­®";s:2:"¸c";s:3:"ç­§";s:2:"¸d";s:3:"ç²±";s:2:"¸e";s:3:"ç²³";s:2:"¸f";s:3:"ç²µ";s:2:"¸g";s:3:"ç¶“";s:2:"¸h";s:3:"çµ¹";s:2:"¸i";s:3:"ç¶‘";s:2:"¸j";s:3:"ç¶";s:2:"¸k";s:3:"ç¶";s:2:"¸l";s:3:"çµ›";s:2:"¸m";s:3:"ç½®";s:2:"¸n";s:3:"罩";s:2:"¸o";s:3:"罪";s:2:"¸p";s:3:"ç½²";s:2:"¸q";s:3:"義";s:2:"¸r";s:3:"羨";s:2:"¸s";s:3:"群";s:2:"¸t";s:3:"è–";s:2:"¸u";s:3:"è˜";s:2:"¸v";s:3:"肆";s:2:"¸w";s:3:"è‚„";s:2:"¸x";s:3:"è…±";s:2:"¸y";s:3:"è…°";s:2:"¸z";s:3:"è…¸";s:2:"¸{";s:3:"è…¥";s:2:"¸|";s:3:"è…®";s:2:"¸}";s:3:"è…³";s:2:"¸~";s:3:"è…«";s:2:"¸¡";s:3:"è…¹";s:2:"¸¢";s:3:"è…º";s:2:"¸£";s:3:"è…¦";s:2:"¸¤";s:3:"舅";s:2:"¸¥";s:3:"艇";s:2:"¸¦";s:3:"è’‚";s:2:"¸§";s:3:"è‘·";s:2:"¸¨";s:3:"è½";s:2:"¸©";s:3:"è±";s:2:"¸ª";s:3:"葵";s:2:"¸«";s:3:"葦";s:2:"¸¬";s:3:"è‘«";s:2:"¸­";s:3:"葉";s:2:"¸®";s:3:"葬";s:2:"¸¯";s:3:"è‘›";s:2:"¸°";s:3:"è¼";s:2:"¸±";s:3:"èµ";s:2:"¸²";s:3:"è‘¡";s:2:"¸³";s:3:"è‘£";s:2:"¸´";s:3:"è‘©";s:2:"¸µ";s:3:"è‘­";s:2:"¸¶";s:3:"葆";s:2:"¸·";s:3:"虞";s:2:"¸¸";s:3:"虜";s:2:"¸¹";s:3:"號";s:2:"¸º";s:3:"蛹";s:2:"¸»";s:3:"蜓";s:2:"¸¼";s:3:"蜈";s:2:"¸½";s:3:"蜇";s:2:"¸¾";s:3:"蜀";s:2:"¸¿";s:3:"蛾";s:2:"¸À";s:3:"è›»";s:2:"¸Á";s:3:"蜂";s:2:"¸Â";s:3:"蜃";s:2:"¸Ã";s:3:"蜆";s:2:"¸Ä";s:3:"蜊";s:2:"¸Å";s:3:"è¡™";s:2:"¸Æ";s:3:"裟";s:2:"¸Ç";s:3:"裔";s:2:"¸È";s:3:"裙";s:2:"¸É";s:3:"補";s:2:"¸Ê";s:3:"裘";s:2:"¸Ë";s:3:"è£";s:2:"¸Ì";s:3:"裡";s:2:"¸Í";s:3:"裊";s:2:"¸Î";s:3:"裕";s:2:"¸Ï";s:3:"裒";s:2:"¸Ð";s:3:"覜";s:2:"¸Ñ";s:3:"è§£";s:2:"¸Ò";s:3:"è©«";s:2:"¸Ó";s:3:"該";s:2:"¸Ô";s:3:"詳";s:2:"¸Õ";s:3:"試";s:2:"¸Ö";s:3:"è©©";s:2:"¸×";s:3:"è©°";s:2:"¸Ø";s:3:"誇";s:2:"¸Ù";s:3:"詼";s:2:"¸Ú";s:3:"è©£";s:2:"¸Û";s:3:"誠";s:2:"¸Ü";s:3:"話";s:2:"¸Ý";s:3:"誅";s:2:"¸Þ";s:3:"è©­";s:2:"¸ß";s:3:"è©¢";s:2:"¸à";s:3:"è©®";s:2:"¸á";s:3:"詬";s:2:"¸â";s:3:"詹";s:2:"¸ã";s:3:"è©»";s:2:"¸ä";s:3:"訾";s:2:"¸å";s:3:"詨";s:2:"¸æ";s:3:"è±¢";s:2:"¸ç";s:3:"貊";s:2:"¸è";s:3:"貉";s:2:"¸é";s:3:"賊";s:2:"¸ê";s:3:"資";s:2:"¸ë";s:3:"賈";s:2:"¸ì";s:3:"賄";s:2:"¸í";s:3:"è²²";s:2:"¸î";s:3:"賃";s:2:"¸ï";s:3:"賂";s:2:"¸ð";s:3:"è³…";s:2:"¸ñ";s:3:"è·¡";s:2:"¸ò";s:3:"è·Ÿ";s:2:"¸ó";s:3:"è·¨";s:2:"¸ô";s:3:"è·¯";s:2:"¸õ";s:3:"è·³";s:2:"¸ö";s:3:"è·º";s:2:"¸÷";s:3:"è·ª";s:2:"¸ø";s:3:"è·¤";s:2:"¸ù";s:3:"è·¦";s:2:"¸ú";s:3:"躲";s:2:"¸û";s:3:"較";s:2:"¸ü";s:3:"載";s:2:"¸ý";s:3:"軾";s:2:"¸þ";s:3:"輊";s:2:"¹@";s:3:"辟";s:2:"¹A";s:3:"è¾²";s:2:"¹B";s:3:"é‹";s:2:"¹C";s:3:"éŠ";s:2:"¹D";s:3:"é“";s:2:"¹E";s:3:"é‚";s:2:"¹F";s:3:"é”";s:2:"¹G";s:3:"逼";s:2:"¹H";s:3:"é•";s:2:"¹I";s:3:"é";s:2:"¹J";s:3:"é‡";s:2:"¹K";s:3:"é";s:2:"¹L";s:3:"éŽ";s:2:"¹M";s:3:"é";s:2:"¹N";s:3:"é‘";s:2:"¹O";s:3:"逾";s:2:"¹P";s:3:"é";s:2:"¹Q";s:3:"é„’";s:2:"¹R";s:3:"é„—";s:2:"¹S";s:3:"é…¬";s:2:"¹T";s:3:"é…ª";s:2:"¹U";s:3:"é…©";s:2:"¹V";s:3:"釉";s:2:"¹W";s:3:"鈷";s:2:"¹X";s:3:"鉗";s:2:"¹Y";s:3:"鈸";s:2:"¹Z";s:3:"鈽";s:2:"¹[";s:3:"鉀";s:2:"¹\";s:3:"鈾";s:2:"¹]";s:3:"鉛";s:2:"¹^";s:3:"鉋";s:2:"¹_";s:3:"鉤";s:2:"¹`";s:3:"鉑";s:2:"¹a";s:3:"鈴";s:2:"¹b";s:3:"鉉";s:2:"¹c";s:3:"é‰";s:2:"¹d";s:3:"鉅";s:2:"¹e";s:3:"鈹";s:2:"¹f";s:3:"鈿";s:2:"¹g";s:3:"鉚";s:2:"¹h";s:3:"é–˜";s:2:"¹i";s:3:"隘";s:2:"¹j";s:3:"éš”";s:2:"¹k";s:3:"éš•";s:2:"¹l";s:3:"é›";s:2:"¹m";s:3:"雋";s:2:"¹n";s:3:"雉";s:2:"¹o";s:3:"雊";s:2:"¹p";s:3:"é›·";s:2:"¹q";s:3:"é›»";s:2:"¹r";s:3:"雹";s:2:"¹s";s:3:"é›¶";s:2:"¹t";s:3:"é–";s:2:"¹u";s:3:"é´";s:2:"¹v";s:3:"é¶";s:2:"¹w";s:3:"é ";s:2:"¹x";s:3:"é ‘";s:2:"¹y";s:3:"é “";s:2:"¹z";s:3:"é Š";s:2:"¹{";s:3:"é ’";s:2:"¹|";s:3:"é Œ";s:2:"¹}";s:3:"飼";s:2:"¹~";s:3:"飴";s:2:"¹¡";s:3:"飽";s:2:"¹¢";s:3:"飾";s:2:"¹£";s:3:"馳";s:2:"¹¤";s:3:"馱";s:2:"¹¥";s:3:"馴";s:2:"¹¦";s:3:"é«¡";s:2:"¹§";s:3:"鳩";s:2:"¹¨";s:3:"麂";s:2:"¹©";s:3:"鼎";s:2:"¹ª";s:3:"鼓";s:2:"¹«";s:3:"é¼ ";s:2:"¹¬";s:3:"僧";s:2:"¹­";s:3:"僮";s:2:"¹®";s:3:"僥";s:2:"¹¯";s:3:"僖";s:2:"¹°";s:3:"僭";s:2:"¹±";s:3:"僚";s:2:"¹²";s:3:"僕";s:2:"¹³";s:3:"åƒ";s:2:"¹´";s:3:"僑";s:2:"¹µ";s:3:"僱";s:2:"¹¶";s:3:"僎";s:2:"¹·";s:3:"僩";s:2:"¹¸";s:3:"å…¢";s:2:"¹¹";s:3:"凳";s:2:"¹º";s:3:"劃";s:2:"¹»";s:3:"劂";s:2:"¹¼";s:3:"匱";s:2:"¹½";s:3:"厭";s:2:"¹¾";s:3:"å—¾";s:2:"¹¿";s:3:"嘀";s:2:"¹À";s:3:"嘛";s:2:"¹Á";s:3:"嘗";s:2:"¹Â";s:3:"å—½";s:2:"¹Ã";s:3:"嘔";s:2:"¹Ä";s:3:"嘆";s:2:"¹Å";s:3:"嘉";s:2:"¹Æ";s:3:"å˜";s:2:"¹Ç";s:3:"嘎";s:2:"¹È";s:3:"å—·";s:2:"¹É";s:3:"嘖";s:2:"¹Ê";s:3:"嘟";s:2:"¹Ë";s:3:"嘈";s:2:"¹Ì";s:3:"å˜";s:2:"¹Í";s:3:"å—¶";s:2:"¹Î";s:3:"團";s:2:"¹Ï";s:3:"圖";s:2:"¹Ð";s:3:"塵";s:2:"¹Ñ";s:3:"塾";s:2:"¹Ò";s:3:"境";s:2:"¹Ó";s:3:"墓";s:2:"¹Ô";s:3:"墊";s:2:"¹Õ";s:3:"塹";s:2:"¹Ö";s:3:"墅";s:2:"¹×";s:3:"塽";s:2:"¹Ø";s:3:"壽";s:2:"¹Ù";s:3:"夥";s:2:"¹Ú";s:3:"夢";s:2:"¹Û";s:3:"夤";s:2:"¹Ü";s:3:"奪";s:2:"¹Ý";s:3:"奩";s:2:"¹Þ";s:3:"å«¡";s:2:"¹ß";s:3:"嫦";s:2:"¹à";s:3:"å«©";s:2:"¹á";s:3:"å«—";s:2:"¹â";s:3:"å«–";s:2:"¹ã";s:3:"嫘";s:2:"¹ä";s:3:"å«£";s:2:"¹å";s:3:"å­µ";s:2:"¹æ";s:3:"寞";s:2:"¹ç";s:3:"寧";s:2:"¹è";s:3:"寡";s:2:"¹é";s:3:"寥";s:2:"¹ê";s:3:"實";s:2:"¹ë";s:3:"寨";s:2:"¹ì";s:3:"寢";s:2:"¹í";s:3:"寤";s:2:"¹î";s:3:"察";s:2:"¹ï";s:3:"å°";s:2:"¹ð";s:3:"å±¢";s:2:"¹ñ";s:3:"å¶„";s:2:"¹ò";s:3:"嶇";s:2:"¹ó";s:3:"å¹›";s:2:"¹ô";s:3:"å¹£";s:2:"¹õ";s:3:"幕";s:2:"¹ö";s:3:"å¹—";s:2:"¹÷";s:3:"å¹”";s:2:"¹ø";s:3:"廓";s:2:"¹ù";s:3:"å»–";s:2:"¹ú";s:3:"弊";s:2:"¹û";s:3:"彆";s:2:"¹ü";s:3:"å½°";s:2:"¹ý";s:3:"å¾¹";s:2:"¹þ";s:3:"æ…‡";s:2:"º@";s:3:"æ„¿";s:2:"ºA";s:3:"æ…‹";s:2:"ºB";s:3:"æ…·";s:2:"ºC";s:3:"æ…¢";s:2:"ºD";s:3:"æ…£";s:2:"ºE";s:3:"æ…Ÿ";s:2:"ºF";s:3:"æ…š";s:2:"ºG";s:3:"æ…˜";s:2:"ºH";s:3:"æ…µ";s:2:"ºI";s:3:"截";s:2:"ºJ";s:3:"æ’‡";s:2:"ºK";s:3:"摘";s:2:"ºL";s:3:"æ‘”";s:2:"ºM";s:3:"æ’¤";s:2:"ºN";s:3:"摸";s:2:"ºO";s:3:"摟";s:2:"ºP";s:3:"摺";s:2:"ºQ";s:3:"æ‘‘";s:2:"ºR";s:3:"æ‘§";s:2:"ºS";s:3:"æ´";s:2:"ºT";s:3:"æ‘­";s:2:"ºU";s:3:"æ‘»";s:2:"ºV";s:3:"敲";s:2:"ºW";s:3:"æ–¡";s:2:"ºX";s:3:"æ——";s:2:"ºY";s:3:"æ—–";s:2:"ºZ";s:3:"暢";s:2:"º[";s:3:"暨";s:2:"º\";s:3:"æš";s:2:"º]";s:3:"榜";s:2:"º^";s:3:"榨";s:2:"º_";s:3:"榕";s:2:"º`";s:3:"æ§";s:2:"ºa";s:3:"榮";s:2:"ºb";s:3:"æ§“";s:2:"ºc";s:3:"æ§‹";s:2:"ºd";s:3:"榛";s:2:"ºe";s:3:"榷";s:2:"ºf";s:3:"榻";s:2:"ºg";s:3:"榫";s:2:"ºh";s:3:"榴";s:2:"ºi";s:3:"æ§";s:2:"ºj";s:3:"æ§";s:2:"ºk";s:3:"榭";s:2:"ºl";s:3:"æ§Œ";s:2:"ºm";s:3:"榦";s:2:"ºn";s:3:"槃";s:2:"ºo";s:3:"榣";s:2:"ºp";s:3:"æ­‰";s:2:"ºq";s:3:"æ­Œ";s:2:"ºr";s:3:"æ°³";s:2:"ºs";s:3:"æ¼³";s:2:"ºt";s:3:"æ¼”";s:2:"ºu";s:3:"滾";s:2:"ºv";s:3:"漓";s:2:"ºw";s:3:"æ»´";s:2:"ºx";s:3:"漩";s:2:"ºy";s:3:"æ¼¾";s:2:"ºz";s:3:"æ¼ ";s:2:"º{";s:3:"漬";s:2:"º|";s:3:"æ¼";s:2:"º}";s:3:"漂";s:2:"º~";s:3:"æ¼¢";s:2:"º¡";s:3:"滿";s:2:"º¢";s:3:"滯";s:2:"º£";s:3:"漆";s:2:"º¤";s:3:"æ¼±";s:2:"º¥";s:3:"漸";s:2:"º¦";s:3:"æ¼²";s:2:"º§";s:3:"æ¼£";s:2:"º¨";s:3:"漕";s:2:"º©";s:3:"漫";s:2:"ºª";s:3:"漯";s:2:"º«";s:3:"澈";s:2:"º¬";s:3:"漪";s:2:"º­";s:3:"滬";s:2:"º®";s:3:"æ¼";s:2:"º¯";s:3:"滲";s:2:"º°";s:3:"滌";s:2:"º±";s:3:"æ»·";s:2:"º²";s:3:"熔";s:2:"º³";s:3:"熙";s:2:"º´";s:3:"ç…½";s:2:"ºµ";s:3:"熊";s:2:"º¶";s:3:"熄";s:2:"º·";s:3:"熒";s:2:"º¸";s:3:"爾";s:2:"º¹";s:3:"犒";s:2:"ºº";s:3:"犖";s:2:"º»";s:3:"ç„";s:2:"º¼";s:3:"ç";s:2:"º½";s:3:"瑤";s:2:"º¾";s:3:"ç‘£";s:2:"º¿";s:3:"瑪";s:2:"ºÀ";s:3:"ç‘°";s:2:"ºÁ";s:3:"ç‘­";s:2:"ºÂ";s:3:"甄";s:2:"ºÃ";s:3:"ç–‘";s:2:"ºÄ";s:3:"瘧";s:2:"ºÅ";s:3:"ç˜";s:2:"ºÆ";s:3:"瘋";s:2:"ºÇ";s:3:"瘉";s:2:"ºÈ";s:3:"瘓";s:2:"ºÉ";s:3:"盡";s:2:"ºÊ";s:3:"監";s:2:"ºË";s:3:"çž„";s:2:"ºÌ";s:3:"ç½";s:2:"ºÍ";s:3:"ç¿";s:2:"ºÎ";s:3:"ç¡";s:2:"ºÏ";s:3:"ç£";s:2:"ºÐ";s:3:"碟";s:2:"ºÑ";s:3:"碧";s:2:"ºÒ";s:3:"碳";s:2:"ºÓ";s:3:"碩";s:2:"ºÔ";s:3:"碣";s:2:"ºÕ";s:3:"禎";s:2:"ºÖ";s:3:"ç¦";s:2:"º×";s:3:"ç¦";s:2:"ºØ";s:3:"種";s:2:"ºÙ";s:3:"稱";s:2:"ºÚ";s:3:"窪";s:2:"ºÛ";s:3:"窩";s:2:"ºÜ";s:3:"ç«­";s:2:"ºÝ";s:3:"端";s:2:"ºÞ";s:3:"管";s:2:"ºß";s:3:"箕";s:2:"ºà";s:3:"箋";s:2:"ºá";s:3:"ç­µ";s:2:"ºâ";s:3:"ç®—";s:2:"ºã";s:3:"ç®";s:2:"ºä";s:3:"ç®”";s:2:"ºå";s:3:"ç®";s:2:"ºæ";s:3:"箸";s:2:"ºç";s:3:"箇";s:2:"ºè";s:3:"箄";s:2:"ºé";s:3:"ç²¹";s:2:"ºê";s:3:"ç²½";s:2:"ºë";s:3:"ç²¾";s:2:"ºì";s:3:"ç¶»";s:2:"ºí";s:3:"ç¶°";s:2:"ºî";s:3:"ç¶œ";s:2:"ºï";s:3:"ç¶½";s:2:"ºð";s:3:"ç¶¾";s:2:"ºñ";s:3:"ç¶ ";s:2:"ºò";s:3:"ç·Š";s:2:"ºó";s:3:"ç¶´";s:2:"ºô";s:3:"ç¶²";s:2:"ºõ";s:3:"ç¶±";s:2:"ºö";s:3:"綺";s:2:"º÷";s:3:"ç¶¢";s:2:"ºø";s:3:"ç¶¿";s:2:"ºù";s:3:"ç¶µ";s:2:"ºú";s:3:"綸";s:2:"ºû";s:3:"ç¶­";s:2:"ºü";s:3:"ç·’";s:2:"ºý";s:3:"ç·‡";s:2:"ºþ";s:3:"綬";s:2:"»@";s:3:"ç½°";s:2:"»A";s:3:"ç¿ ";s:2:"»B";s:3:"ç¿¡";s:2:"»C";s:3:"翟";s:2:"»D";s:3:"èž";s:2:"»E";s:3:"èš";s:2:"»F";s:3:"肇";s:2:"»G";s:3:"è…";s:2:"»H";s:3:"膀";s:2:"»I";s:3:"è†";s:2:"»J";s:3:"膈";s:2:"»K";s:3:"膊";s:2:"»L";s:3:"è…¿";s:2:"»M";s:3:"膂";s:2:"»N";s:3:"臧";s:2:"»O";s:3:"臺";s:2:"»P";s:3:"與";s:2:"»Q";s:3:"舔";s:2:"»R";s:3:"舞";s:2:"»S";s:3:"艋";s:2:"»T";s:3:"蓉";s:2:"»U";s:3:"è’¿";s:2:"»V";s:3:"蓆";s:2:"»W";s:3:"è“„";s:2:"»X";s:3:"è’™";s:2:"»Y";s:3:"è’ž";s:2:"»Z";s:3:"è’²";s:2:"»[";s:3:"è’œ";s:2:"»\";s:3:"è“‹";s:2:"»]";s:3:"è’¸";s:2:"»^";s:3:"è“€";s:2:"»_";s:3:"è““";s:2:"»`";s:3:"è’";s:2:"»a";s:3:"è’¼";s:2:"»b";s:3:"è“‘";s:2:"»c";s:3:"蓊";s:2:"»d";s:3:"蜿";s:2:"»e";s:3:"蜜";s:2:"»f";s:3:"蜻";s:2:"»g";s:3:"蜢";s:2:"»h";s:3:"蜥";s:2:"»i";s:3:"蜴";s:2:"»j";s:3:"蜘";s:2:"»k";s:3:"è•";s:2:"»l";s:3:"蜷";s:2:"»m";s:3:"蜩";s:2:"»n";s:3:"裳";s:2:"»o";s:3:"褂";s:2:"»p";s:3:"裴";s:2:"»q";s:3:"裹";s:2:"»r";s:3:"裸";s:2:"»s";s:3:"製";s:2:"»t";s:3:"裨";s:2:"»u";s:3:"褚";s:2:"»v";s:3:"裯";s:2:"»w";s:3:"誦";s:2:"»x";s:3:"誌";s:2:"»y";s:3:"語";s:2:"»z";s:3:"誣";s:2:"»{";s:3:"èª";s:2:"»|";s:3:"誡";s:2:"»}";s:3:"誓";s:2:"»~";s:3:"誤";s:2:"»¡";s:3:"說";s:2:"»¢";s:3:"誥";s:2:"»£";s:3:"誨";s:2:"»¤";s:3:"誘";s:2:"»¥";s:3:"誑";s:2:"»¦";s:3:"誚";s:2:"»§";s:3:"誧";s:2:"»¨";s:3:"豪";s:2:"»©";s:3:"è²";s:2:"»ª";s:3:"貌";s:2:"»«";s:3:"賓";s:2:"»¬";s:3:"賑";s:2:"»­";s:3:"è³’";s:2:"»®";s:3:"赫";s:2:"»¯";s:3:"è¶™";s:2:"»°";s:3:"è¶•";s:2:"»±";s:3:"è·¼";s:2:"»²";s:3:"è¼”";s:2:"»³";s:3:"è¼’";s:2:"»´";s:3:"輕";s:2:"»µ";s:3:"輓";s:2:"»¶";s:3:"è¾£";s:2:"»·";s:3:"é ";s:2:"»¸";s:3:"é˜";s:2:"»¹";s:3:"éœ";s:2:"»º";s:3:"é£";s:2:"»»";s:3:"é™";s:2:"»¼";s:3:"éž";s:2:"»½";s:3:"é¢";s:2:"»¾";s:3:"é";s:2:"»¿";s:3:"é›";s:2:"»À";s:3:"é„™";s:2:"»Á";s:3:"鄘";s:2:"»Â";s:3:"鄞";s:2:"»Ã";s:3:"é…µ";s:2:"»Ä";s:3:"é…¸";s:2:"»Å";s:3:"é…·";s:2:"»Æ";s:3:"é…´";s:2:"»Ç";s:3:"鉸";s:2:"»È";s:3:"銀";s:2:"»É";s:3:"銅";s:2:"»Ê";s:3:"銘";s:2:"»Ë";s:3:"銖";s:2:"»Ì";s:3:"鉻";s:2:"»Í";s:3:"銓";s:2:"»Î";s:3:"銜";s:2:"»Ï";s:3:"銨";s:2:"»Ð";s:3:"鉼";s:2:"»Ñ";s:3:"銑";s:2:"»Ò";s:3:"é–¡";s:2:"»Ó";s:3:"é–¨";s:2:"»Ô";s:3:"é–©";s:2:"»Õ";s:3:"é–£";s:2:"»Ö";s:3:"é–¥";s:2:"»×";s:3:"é–¤";s:2:"»Ø";s:3:"éš™";s:2:"»Ù";s:3:"éšœ";s:2:"»Ú";s:3:"éš›";s:2:"»Û";s:3:"雌";s:2:"»Ü";s:3:"é›’";s:2:"»Ý";s:3:"需";s:2:"»Þ";s:3:"é¼";s:2:"»ß";s:3:"éž…";s:2:"»à";s:3:"韶";s:2:"»á";s:3:"é —";s:2:"»â";s:3:"é ˜";s:2:"»ã";s:3:"颯";s:2:"»ä";s:3:"颱";s:2:"»å";s:3:"餃";s:2:"»æ";s:3:"餅";s:2:"»ç";s:3:"餌";s:2:"»è";s:3:"餉";s:2:"»é";s:3:"é§";s:2:"»ê";s:3:"骯";s:2:"»ë";s:3:"骰";s:2:"»ì";s:3:"髦";s:2:"»í";s:3:"é­";s:2:"»î";s:3:"é­‚";s:2:"»ï";s:3:"é³´";s:2:"»ð";s:3:"é³¶";s:2:"»ñ";s:3:"é³³";s:2:"»ò";s:3:"麼";s:2:"»ó";s:3:"é¼»";s:2:"»ô";s:3:"齊";s:2:"»õ";s:3:"å„„";s:2:"»ö";s:3:"å„€";s:2:"»÷";s:3:"僻";s:2:"»ø";s:3:"僵";s:2:"»ù";s:3:"價";s:2:"»ú";s:3:"å„‚";s:2:"»û";s:3:"儈";s:2:"»ü";s:3:"儉";s:2:"»ý";s:3:"å„…";s:2:"»þ";s:3:"凜";s:2:"¼@";s:3:"劇";s:2:"¼A";s:3:"劈";s:2:"¼B";s:3:"劉";s:2:"¼C";s:3:"åŠ";s:2:"¼D";s:3:"劊";s:2:"¼E";s:3:"å‹°";s:2:"¼F";s:3:"厲";s:2:"¼G";s:3:"嘮";s:2:"¼H";s:3:"嘻";s:2:"¼I";s:3:"嘹";s:2:"¼J";s:3:"嘲";s:2:"¼K";s:3:"嘿";s:2:"¼L";s:3:"嘴";s:2:"¼M";s:3:"嘩";s:2:"¼N";s:3:"噓";s:2:"¼O";s:3:"噎";s:2:"¼P";s:3:"å™—";s:2:"¼Q";s:3:"å™´";s:2:"¼R";s:3:"嘶";s:2:"¼S";s:3:"嘯";s:2:"¼T";s:3:"嘰";s:2:"¼U";s:3:"墀";s:2:"¼V";s:3:"墟";s:2:"¼W";s:3:"增";s:2:"¼X";s:3:"墳";s:2:"¼Y";s:3:"墜";s:2:"¼Z";s:3:"墮";s:2:"¼[";s:3:"墩";s:2:"¼\";s:3:"墦";s:2:"¼]";s:3:"奭";s:2:"¼^";s:3:"嬉";s:2:"¼_";s:3:"å«»";s:2:"¼`";s:3:"嬋";s:2:"¼a";s:3:"嫵";s:2:"¼b";s:3:"嬌";s:2:"¼c";s:3:"嬈";s:2:"¼d";s:3:"寮";s:2:"¼e";s:3:"寬";s:2:"¼f";s:3:"審";s:2:"¼g";s:3:"寫";s:2:"¼h";s:3:"層";s:2:"¼i";s:3:"å±¥";s:2:"¼j";s:3:"å¶";s:2:"¼k";s:3:"å¶”";s:2:"¼l";s:3:"å¹¢";s:2:"¼m";s:3:"幟";s:2:"¼n";s:3:"幡";s:2:"¼o";s:3:"廢";s:2:"¼p";s:3:"廚";s:2:"¼q";s:3:"廟";s:2:"¼r";s:3:"å»";s:2:"¼s";s:3:"廣";s:2:"¼t";s:3:"å» ";s:2:"¼u";s:3:"彈";s:2:"¼v";s:3:"å½±";s:2:"¼w";s:3:"å¾·";s:2:"¼x";s:3:"å¾µ";s:2:"¼y";s:3:"æ…¶";s:2:"¼z";s:3:"æ…§";s:2:"¼{";s:3:"æ…®";s:2:"¼|";s:3:"æ…";s:2:"¼}";s:3:"æ…•";s:2:"¼~";s:3:"憂";s:2:"¼¡";s:3:"æ…¼";s:2:"¼¢";s:3:"æ…°";s:2:"¼£";s:3:"æ…«";s:2:"¼¤";s:3:"æ…¾";s:2:"¼¥";s:3:"憧";s:2:"¼¦";s:3:"æ†";s:2:"¼§";s:3:"憫";s:2:"¼¨";s:3:"憎";s:2:"¼©";s:3:"憬";s:2:"¼ª";s:3:"憚";s:2:"¼«";s:3:"憤";s:2:"¼¬";s:3:"憔";s:2:"¼­";s:3:"憮";s:2:"¼®";s:3:"戮";s:2:"¼¯";s:3:"æ‘©";s:2:"¼°";s:3:"摯";s:2:"¼±";s:3:"摹";s:2:"¼²";s:3:"æ’ž";s:2:"¼³";s:3:"æ’²";s:2:"¼´";s:3:"æ’ˆ";s:2:"¼µ";s:3:"æ’";s:2:"¼¶";s:3:"æ’°";s:2:"¼·";s:3:"æ’¥";s:2:"¼¸";s:3:"æ’“";s:2:"¼¹";s:3:"æ’•";s:2:"¼º";s:3:"æ’©";s:2:"¼»";s:3:"æ’’";s:2:"¼¼";s:3:"æ’®";s:2:"¼½";s:3:"æ’­";s:2:"¼¾";s:3:"æ’«";s:2:"¼¿";s:3:"æ’š";s:2:"¼À";s:3:"æ’¬";s:2:"¼Á";s:3:"æ’™";s:2:"¼Â";s:3:"æ’¢";s:2:"¼Ã";s:3:"æ’³";s:2:"¼Ä";s:3:"敵";s:2:"¼Å";s:3:"æ•·";s:2:"¼Æ";s:3:"數";s:2:"¼Ç";s:3:"æš®";s:2:"¼È";s:3:"æš«";s:2:"¼É";s:3:"æš´";s:2:"¼Ê";s:3:"æš±";s:2:"¼Ë";s:3:"樣";s:2:"¼Ì";s:3:"樟";s:2:"¼Í";s:3:"槨";s:2:"¼Î";s:3:"æ¨";s:2:"¼Ï";s:3:"樞";s:2:"¼Ð";s:3:"標";s:2:"¼Ñ";s:3:"æ§½";s:2:"¼Ò";s:3:"模";s:2:"¼Ó";s:3:"樓";s:2:"¼Ô";s:3:"樊";s:2:"¼Õ";s:3:"æ§³";s:2:"¼Ö";s:3:"樂";s:2:"¼×";s:3:"樅";s:2:"¼Ø";s:3:"æ§­";s:2:"¼Ù";s:3:"樑";s:2:"¼Ú";s:3:"æ­";s:2:"¼Û";s:3:"æ­Ž";s:2:"¼Ü";s:3:"殤";s:2:"¼Ý";s:3:"毅";s:2:"¼Þ";s:3:"毆";s:2:"¼ß";s:3:"漿";s:2:"¼à";s:3:"æ½¼";s:2:"¼á";s:3:"澄";s:2:"¼â";s:3:"潑";s:2:"¼ã";s:3:"潦";s:2:"¼ä";s:3:"æ½”";s:2:"¼å";s:3:"澆";s:2:"¼æ";s:3:"æ½­";s:2:"¼ç";s:3:"æ½›";s:2:"¼è";s:3:"潸";s:2:"¼é";s:3:"æ½®";s:2:"¼ê";s:3:"澎";s:2:"¼ë";s:3:"潺";s:2:"¼ì";s:3:"æ½°";s:2:"¼í";s:3:"潤";s:2:"¼î";s:3:"æ¾—";s:2:"¼ï";s:3:"潘";s:2:"¼ð";s:3:"滕";s:2:"¼ñ";s:3:"潯";s:2:"¼ò";s:3:"æ½ ";s:2:"¼ó";s:3:"潟";s:2:"¼ô";s:3:"熟";s:2:"¼õ";s:3:"熬";s:2:"¼ö";s:3:"熱";s:2:"¼÷";s:3:"熨";s:2:"¼ø";s:3:"牖";s:2:"¼ù";s:3:"犛";s:2:"¼ú";s:3:"çŽ";s:2:"¼û";s:3:"ç—";s:2:"¼ü";s:3:"ç‘©";s:2:"¼ý";s:3:"ç’‹";s:2:"¼þ";s:3:"ç’ƒ";s:2:"½@";s:3:"瑾";s:2:"½A";s:3:"ç’€";s:2:"½B";s:3:"ç•¿";s:2:"½C";s:3:"瘠";s:2:"½D";s:3:"瘩";s:2:"½E";s:3:"瘟";s:2:"½F";s:3:"瘤";s:2:"½G";s:3:"瘦";s:2:"½H";s:3:"瘡";s:2:"½I";s:3:"瘢";s:2:"½J";s:3:"çšš";s:2:"½K";s:3:"皺";s:2:"½L";s:3:"盤";s:2:"½M";s:3:"瞎";s:2:"½N";s:3:"瞇";s:2:"½O";s:3:"瞌";s:2:"½P";s:3:"çž‘";s:2:"½Q";s:3:"çž‹";s:2:"½R";s:3:"磋";s:2:"½S";s:3:"磅";s:2:"½T";s:3:"確";s:2:"½U";s:3:"磊";s:2:"½V";s:3:"碾";s:2:"½W";s:3:"磕";s:2:"½X";s:3:"碼";s:2:"½Y";s:3:"ç£";s:2:"½Z";s:3:"稿";s:2:"½[";s:3:"稼";s:2:"½\";s:3:"ç©€";s:2:"½]";s:3:"稽";s:2:"½^";s:3:"稷";s:2:"½_";s:3:"稻";s:2:"½`";s:3:"窯";s:2:"½a";s:3:"窮";s:2:"½b";s:3:"ç®­";s:2:"½c";s:3:"ç®±";s:2:"½d";s:3:"範";s:2:"½e";s:3:"ç®´";s:2:"½f";s:3:"篆";s:2:"½g";s:3:"篇";s:2:"½h";s:3:"ç¯";s:2:"½i";s:3:"ç® ";s:2:"½j";s:3:"篌";s:2:"½k";s:3:"糊";s:2:"½l";s:3:"ç· ";s:2:"½m";s:3:"ç·´";s:2:"½n";s:3:"ç·¯";s:2:"½o";s:3:"ç·»";s:2:"½p";s:3:"ç·˜";s:2:"½q";s:3:"ç·¬";s:2:"½r";s:3:"ç·";s:2:"½s";s:3:"ç·¨";s:2:"½t";s:3:"ç·£";s:2:"½u";s:3:"ç·š";s:2:"½v";s:3:"ç·ž";s:2:"½w";s:3:"ç·©";s:2:"½x";s:3:"ç¶ž";s:2:"½y";s:3:"ç·™";s:2:"½z";s:3:"ç·²";s:2:"½{";s:3:"ç·¹";s:2:"½|";s:3:"ç½µ";s:2:"½}";s:3:"ç½·";s:2:"½~";s:3:"羯";s:2:"½¡";s:3:"ç¿©";s:2:"½¢";s:3:"耦";s:2:"½£";s:3:"膛";s:2:"½¤";s:3:"膜";s:2:"½¥";s:3:"è†";s:2:"½¦";s:3:"膠";s:2:"½§";s:3:"膚";s:2:"½¨";s:3:"膘";s:2:"½©";s:3:"è”—";s:2:"½ª";s:3:"蔽";s:2:"½«";s:3:"蔚";s:2:"½¬";s:3:"è“®";s:2:"½­";s:3:"蔬";s:2:"½®";s:3:"è”­";s:2:"½¯";s:3:"蔓";s:2:"½°";s:3:"蔑";s:2:"½±";s:3:"蔣";s:2:"½²";s:3:"蔡";s:2:"½³";s:3:"è””";s:2:"½´";s:3:"蓬";s:2:"½µ";s:3:"蔥";s:2:"½¶";s:3:"è“¿";s:2:"½·";s:3:"蔆";s:2:"½¸";s:3:"èž‚";s:2:"½¹";s:3:"è´";s:2:"½º";s:3:"è¶";s:2:"½»";s:3:"è ";s:2:"½¼";s:3:"è¦";s:2:"½½";s:3:"è¸";s:2:"½¾";s:3:"è¨";s:2:"½¿";s:3:"è™";s:2:"½À";s:3:"è—";s:2:"½Á";s:3:"èŒ";s:2:"½Â";s:3:"è“";s:2:"½Ã";s:3:"è¡›";s:2:"½Ä";s:3:"è¡";s:2:"½Å";s:3:"è¤";s:2:"½Æ";s:3:"複";s:2:"½Ç";s:3:"褒";s:2:"½È";s:3:"褓";s:2:"½É";s:3:"褕";s:2:"½Ê";s:3:"褊";s:2:"½Ë";s:3:"誼";s:2:"½Ì";s:3:"è«’";s:2:"½Í";s:3:"談";s:2:"½Î";s:3:"è«„";s:2:"½Ï";s:3:"誕";s:2:"½Ð";s:3:"è«‹";s:2:"½Ñ";s:3:"諸";s:2:"½Ò";s:3:"課";s:2:"½Ó";s:3:"諉";s:2:"½Ô";s:3:"è«‚";s:2:"½Õ";s:3:"調";s:2:"½Ö";s:3:"誰";s:2:"½×";s:3:"è«–";s:2:"½Ø";s:3:"è«";s:2:"½Ù";s:3:"誶";s:2:"½Ú";s:3:"誹";s:2:"½Û";s:3:"è«›";s:2:"½Ü";s:3:"豌";s:2:"½Ý";s:3:"豎";s:2:"½Þ";s:3:"豬";s:2:"½ß";s:3:"è³ ";s:2:"½à";s:3:"賞";s:2:"½á";s:3:"賦";s:2:"½â";s:3:"賤";s:2:"½ã";s:3:"賬";s:2:"½ä";s:3:"è³­";s:2:"½å";s:3:"è³¢";s:2:"½æ";s:3:"è³£";s:2:"½ç";s:3:"賜";s:2:"½è";s:3:"質";s:2:"½é";s:3:"賡";s:2:"½ê";s:3:"èµ­";s:2:"½ë";s:3:"è¶Ÿ";s:2:"½ì";s:3:"è¶£";s:2:"½í";s:3:"踫";s:2:"½î";s:3:"è¸";s:2:"½ï";s:3:"è¸";s:2:"½ð";s:3:"踢";s:2:"½ñ";s:3:"è¸";s:2:"½ò";s:3:"踩";s:2:"½ó";s:3:"踟";s:2:"½ô";s:3:"踡";s:2:"½õ";s:3:"踞";s:2:"½ö";s:3:"躺";s:2:"½÷";s:3:"è¼";s:2:"½ø";s:3:"è¼›";s:2:"½ù";s:3:"輟";s:2:"½ú";s:3:"輩";s:2:"½û";s:3:"輦";s:2:"½ü";s:3:"輪";s:2:"½ý";s:3:"輜";s:2:"½þ";s:3:"輞";s:2:"¾@";s:3:"è¼¥";s:2:"¾A";s:3:"é©";s:2:"¾B";s:3:"é®";s:2:"¾C";s:3:"é¨";s:2:"¾D";s:3:"é­";s:2:"¾E";s:3:"é·";s:2:"¾F";s:3:"é„°";s:2:"¾G";s:3:"é„­";s:2:"¾H";s:3:"é„§";s:2:"¾I";s:3:"鄱";s:2:"¾J";s:3:"醇";s:2:"¾K";s:3:"醉";s:2:"¾L";s:3:"醋";s:2:"¾M";s:3:"醃";s:2:"¾N";s:3:"é‹…";s:2:"¾O";s:3:"銻";s:2:"¾P";s:3:"銷";s:2:"¾Q";s:3:"鋪";s:2:"¾R";s:3:"銬";s:2:"¾S";s:3:"鋤";s:2:"¾T";s:3:"é‹";s:2:"¾U";s:3:"銳";s:2:"¾V";s:3:"銼";s:2:"¾W";s:3:"é‹’";s:2:"¾X";s:3:"鋇";s:2:"¾Y";s:3:"é‹°";s:2:"¾Z";s:3:"銲";s:2:"¾[";s:3:"é–­";s:2:"¾\";s:3:"é–±";s:2:"¾]";s:3:"霄";s:2:"¾^";s:3:"霆";s:2:"¾_";s:3:"震";s:2:"¾`";s:3:"霉";s:2:"¾a";s:3:"é ";s:2:"¾b";s:3:"éž";s:2:"¾c";s:3:"éž‹";s:2:"¾d";s:3:"éž";s:2:"¾e";s:3:"é ¡";s:2:"¾f";s:3:"é «";s:2:"¾g";s:3:"é œ";s:2:"¾h";s:3:"颳";s:2:"¾i";s:3:"養";s:2:"¾j";s:3:"餓";s:2:"¾k";s:3:"餒";s:2:"¾l";s:3:"餘";s:2:"¾m";s:3:"é§";s:2:"¾n";s:3:"é§";s:2:"¾o";s:3:"é§Ÿ";s:2:"¾p";s:3:"é§›";s:2:"¾q";s:3:"é§‘";s:2:"¾r";s:3:"é§•";s:2:"¾s";s:3:"é§’";s:2:"¾t";s:3:"é§™";s:2:"¾u";s:3:"骷";s:2:"¾v";s:3:"é«®";s:2:"¾w";s:3:"髯";s:2:"¾x";s:3:"鬧";s:2:"¾y";s:3:"é­…";s:2:"¾z";s:3:"é­„";s:2:"¾{";s:3:"é­·";s:2:"¾|";s:3:"é­¯";s:2:"¾}";s:3:"é´†";s:2:"¾~";s:3:"é´‰";s:2:"¾¡";s:3:"é´ƒ";s:2:"¾¢";s:3:"麩";s:2:"¾£";s:3:"麾";s:2:"¾¤";s:3:"黎";s:2:"¾¥";s:3:"墨";s:2:"¾¦";s:3:"é½’";s:2:"¾§";s:3:"å„’";s:2:"¾¨";s:3:"儘";s:2:"¾©";s:3:"å„”";s:2:"¾ª";s:3:"å„";s:2:"¾«";s:3:"å„•";s:2:"¾¬";s:3:"冀";s:2:"¾­";s:3:"冪";s:2:"¾®";s:3:"å‡";s:2:"¾¯";s:3:"劑";s:2:"¾°";s:3:"劓";s:2:"¾±";s:3:"勳";s:2:"¾²";s:3:"å™™";s:2:"¾³";s:3:"噫";s:2:"¾´";s:3:"噹";s:2:"¾µ";s:3:"噩";s:2:"¾¶";s:3:"噤";s:2:"¾·";s:3:"噸";s:2:"¾¸";s:3:"噪";s:2:"¾¹";s:3:"器";s:2:"¾º";s:3:"噥";s:2:"¾»";s:3:"å™±";s:2:"¾¼";s:3:"噯";s:2:"¾½";s:3:"噬";s:2:"¾¾";s:3:"噢";s:2:"¾¿";s:3:"å™¶";s:2:"¾À";s:3:"å£";s:2:"¾Á";s:3:"墾";s:2:"¾Â";s:3:"壇";s:2:"¾Ã";s:3:"壅";s:2:"¾Ä";s:3:"奮";s:2:"¾Å";s:3:"å¬";s:2:"¾Æ";s:3:"嬴";s:2:"¾Ç";s:3:"å­¸";s:2:"¾È";s:3:"寰";s:2:"¾É";s:3:"å°Ž";s:2:"¾Ê";s:3:"彊";s:2:"¾Ë";s:3:"憲";s:2:"¾Ì";s:3:"憑";s:2:"¾Í";s:3:"憩";s:2:"¾Î";s:3:"憊";s:2:"¾Ï";s:3:"æ‡";s:2:"¾Ð";s:3:"憶";s:2:"¾Ñ";s:3:"憾";s:2:"¾Ò";s:3:"懊";s:2:"¾Ó";s:3:"懈";s:2:"¾Ô";s:3:"戰";s:2:"¾Õ";s:3:"æ“…";s:2:"¾Ö";s:3:"æ“";s:2:"¾×";s:3:"æ“‹";s:2:"¾Ø";s:3:"æ’»";s:2:"¾Ù";s:3:"æ’¼";s:2:"¾Ú";s:3:"據";s:2:"¾Û";s:3:"æ“„";s:2:"¾Ü";s:3:"擇";s:2:"¾Ý";s:3:"æ“‚";s:2:"¾Þ";s:3:"æ“";s:2:"¾ß";s:3:"æ’¿";s:2:"¾à";s:3:"æ“’";s:2:"¾á";s:3:"æ“”";s:2:"¾â";s:3:"æ’¾";s:2:"¾ã";s:3:"æ•´";s:2:"¾ä";s:3:"曆";s:2:"¾å";s:3:"曉";s:2:"¾æ";s:3:"æš¹";s:2:"¾ç";s:3:"曄";s:2:"¾è";s:3:"曇";s:2:"¾é";s:3:"暸";s:2:"¾ê";s:3:"樽";s:2:"¾ë";s:3:"樸";s:2:"¾ì";s:3:"樺";s:2:"¾í";s:3:"æ©™";s:2:"¾î";s:3:"æ©«";s:2:"¾ï";s:3:"橘";s:2:"¾ð";s:3:"樹";s:2:"¾ñ";s:3:"æ©„";s:2:"¾ò";s:3:"æ©¢";s:2:"¾ó";s:3:"æ©¡";s:2:"¾ô";s:3:"æ©‹";s:2:"¾õ";s:3:"橇";s:2:"¾ö";s:3:"樵";s:2:"¾÷";s:3:"機";s:2:"¾ø";s:3:"橈";s:2:"¾ù";s:3:"æ­™";s:2:"¾ú";s:3:"æ­·";s:2:"¾û";s:3:"æ°…";s:2:"¾ü";s:3:"æ¿‚";s:2:"¾ý";s:3:"æ¾±";s:2:"¾þ";s:3:"澡";s:2:"¿@";s:3:"濃";s:2:"¿A";s:3:"澤";s:2:"¿B";s:3:"æ¿";s:2:"¿C";s:3:"æ¾§";s:2:"¿D";s:3:"æ¾³";s:2:"¿E";s:3:"æ¿€";s:2:"¿F";s:3:"æ¾¹";s:2:"¿G";s:3:"æ¾¶";s:2:"¿H";s:3:"澦";s:2:"¿I";s:3:"æ¾ ";s:2:"¿J";s:3:"æ¾´";s:2:"¿K";s:3:"熾";s:2:"¿L";s:3:"燉";s:2:"¿M";s:3:"ç‡";s:2:"¿N";s:3:"燒";s:2:"¿O";s:3:"燈";s:2:"¿P";s:3:"燕";s:2:"¿Q";s:3:"熹";s:2:"¿R";s:3:"燎";s:2:"¿S";s:3:"燙";s:2:"¿T";s:3:"燜";s:2:"¿U";s:3:"燃";s:2:"¿V";s:3:"燄";s:2:"¿W";s:3:"ç¨";s:2:"¿X";s:3:"ç’œ";s:2:"¿Y";s:3:"ç’£";s:2:"¿Z";s:3:"ç’˜";s:2:"¿[";s:3:"ç’Ÿ";s:2:"¿\";s:3:"ç’ž";s:2:"¿]";s:3:"ç“¢";s:2:"¿^";s:3:"甌";s:2:"¿_";s:3:"ç”";s:2:"¿`";s:3:"瘴";s:2:"¿a";s:3:"瘸";s:2:"¿b";s:3:"瘺";s:2:"¿c";s:3:"ç›§";s:2:"¿d";s:3:"盥";s:2:"¿e";s:3:"çž ";s:2:"¿f";s:3:"çžž";s:2:"¿g";s:3:"瞟";s:2:"¿h";s:3:"瞥";s:2:"¿i";s:3:"磨";s:2:"¿j";s:3:"磚";s:2:"¿k";s:3:"磬";s:2:"¿l";s:3:"磧";s:2:"¿m";s:3:"禦";s:2:"¿n";s:3:"ç©";s:2:"¿o";s:3:"穎";s:2:"¿p";s:3:"穆";s:2:"¿q";s:3:"穌";s:2:"¿r";s:3:"ç©‹";s:2:"¿s";s:3:"窺";s:2:"¿t";s:3:"篙";s:2:"¿u";s:3:"ç°‘";s:2:"¿v";s:3:"築";s:2:"¿w";s:3:"篤";s:2:"¿x";s:3:"篛";s:2:"¿y";s:3:"篡";s:2:"¿z";s:3:"篩";s:2:"¿{";s:3:"篦";s:2:"¿|";s:3:"糕";s:2:"¿}";s:3:"ç³–";s:2:"¿~";s:3:"縊";s:2:"¿¡";s:3:"縑";s:2:"¿¢";s:3:"縈";s:2:"¿£";s:3:"縛";s:2:"¿¤";s:3:"縣";s:2:"¿¥";s:3:"縞";s:2:"¿¦";s:3:"ç¸";s:2:"¿§";s:3:"縉";s:2:"¿¨";s:3:"ç¸";s:2:"¿©";s:3:"ç½¹";s:2:"¿ª";s:3:"ç¾²";s:2:"¿«";s:3:"ç¿°";s:2:"¿¬";s:3:"翱";s:2:"¿­";s:3:"ç¿®";s:2:"¿®";s:3:"耨";s:2:"¿¯";s:3:"膳";s:2:"¿°";s:3:"膩";s:2:"¿±";s:3:"膨";s:2:"¿²";s:3:"臻";s:2:"¿³";s:3:"興";s:2:"¿´";s:3:"艘";s:2:"¿µ";s:3:"艙";s:2:"¿¶";s:3:"蕊";s:2:"¿·";s:3:"è•™";s:2:"¿¸";s:3:"蕈";s:2:"¿¹";s:3:"蕨";s:2:"¿º";s:3:"è•©";s:2:"¿»";s:3:"蕃";s:2:"¿¼";s:3:"蕉";s:2:"¿½";s:3:"è•­";s:2:"¿¾";s:3:"蕪";s:2:"¿¿";s:3:"蕞";s:2:"¿À";s:3:"螃";s:2:"¿Á";s:3:"螟";s:2:"¿Â";s:3:"èžž";s:2:"¿Ã";s:3:"螢";s:2:"¿Ä";s:3:"èž";s:2:"¿Å";s:3:"è¡¡";s:2:"¿Æ";s:3:"褪";s:2:"¿Ç";s:3:"褲";s:2:"¿È";s:3:"褥";s:2:"¿É";s:3:"褫";s:2:"¿Ê";s:3:"褡";s:2:"¿Ë";s:3:"親";s:2:"¿Ì";s:3:"覦";s:2:"¿Í";s:3:"諦";s:2:"¿Î";s:3:"諺";s:2:"¿Ï";s:3:"è««";s:2:"¿Ð";s:3:"諱";s:2:"¿Ñ";s:3:"謀";s:2:"¿Ò";s:3:"諜";s:2:"¿Ó";s:3:"è«§";s:2:"¿Ô";s:3:"è«®";s:2:"¿Õ";s:3:"諾";s:2:"¿Ö";s:3:"è¬";s:2:"¿×";s:3:"謂";s:2:"¿Ø";s:3:"è«·";s:2:"¿Ù";s:3:"è«­";s:2:"¿Ú";s:3:"諳";s:2:"¿Û";s:3:"è«¶";s:2:"¿Ü";s:3:"諼";s:2:"¿Ý";s:3:"豫";s:2:"¿Þ";s:3:"è±­";s:2:"¿ß";s:3:"貓";s:2:"¿à";s:3:"è³´";s:2:"¿á";s:3:"蹄";s:2:"¿â";s:3:"踱";s:2:"¿ã";s:3:"踴";s:2:"¿ä";s:3:"蹂";s:2:"¿å";s:3:"踹";s:2:"¿æ";s:3:"踵";s:2:"¿ç";s:3:"è¼»";s:2:"¿è";s:3:"輯";s:2:"¿é";s:3:"輸";s:2:"¿ê";s:3:"è¼³";s:2:"¿ë";s:3:"辨";s:2:"¿ì";s:3:"辦";s:2:"¿í";s:3:"éµ";s:2:"¿î";s:3:"é´";s:2:"¿ï";s:3:"é¸";s:2:"¿ð";s:3:"é²";s:2:"¿ñ";s:3:"é¼";s:2:"¿ò";s:3:"éº";s:2:"¿ó";s:3:"é„´";s:2:"¿ô";s:3:"醒";s:2:"¿õ";s:3:"錠";s:2:"¿ö";s:3:"錶";s:2:"¿÷";s:3:"鋸";s:2:"¿ø";s:3:"錳";s:2:"¿ù";s:3:"錯";s:2:"¿ú";s:3:"錢";s:2:"¿û";s:3:"鋼";s:2:"¿ü";s:3:"錫";s:2:"¿ý";s:3:"錄";s:2:"¿þ";s:3:"錚";s:2:"À@";s:3:"éŒ";s:2:"ÀA";s:3:"錦";s:2:"ÀB";s:3:"錡";s:2:"ÀC";s:3:"錕";s:2:"ÀD";s:3:"錮";s:2:"ÀE";s:3:"錙";s:2:"ÀF";s:3:"é–»";s:2:"ÀG";s:3:"éš§";s:2:"ÀH";s:3:"隨";s:2:"ÀI";s:3:"險";s:2:"ÀJ";s:3:"雕";s:2:"ÀK";s:3:"霎";s:2:"ÀL";s:3:"霑";s:2:"ÀM";s:3:"霖";s:2:"ÀN";s:3:"éœ";s:2:"ÀO";s:3:"霓";s:2:"ÀP";s:3:"éœ";s:2:"ÀQ";s:3:"é›";s:2:"ÀR";s:3:"éœ";s:2:"ÀS";s:3:"é¦";s:2:"ÀT";s:3:"鞘";s:2:"ÀU";s:3:"é °";s:2:"ÀV";s:3:"é ¸";s:2:"ÀW";s:3:"é »";s:2:"ÀX";s:3:"é ·";s:2:"ÀY";s:3:"é ­";s:2:"ÀZ";s:3:"é ¹";s:2:"À[";s:3:"é ¤";s:2:"À\";s:3:"é¤";s:2:"À]";s:3:"館";s:2:"À^";s:3:"餞";s:2:"À_";s:3:"餛";s:2:"À`";s:3:"餡";s:2:"Àa";s:3:"餚";s:2:"Àb";s:3:"é§­";s:2:"Àc";s:3:"é§¢";s:2:"Àd";s:3:"é§±";s:2:"Àe";s:3:"骸";s:2:"Àf";s:3:"骼";s:2:"Àg";s:3:"é«»";s:2:"Àh";s:3:"é«­";s:2:"Ài";s:3:"鬨";s:2:"Àj";s:3:"鮑";s:2:"Àk";s:3:"é´•";s:2:"Àl";s:3:"é´£";s:2:"Àm";s:3:"é´¦";s:2:"Àn";s:3:"é´¨";s:2:"Ào";s:3:"é´’";s:2:"Àp";s:3:"é´›";s:2:"Àq";s:3:"默";s:2:"Àr";s:3:"é»”";s:2:"Às";s:3:"é¾";s:2:"Àt";s:3:"龜";s:2:"Àu";s:3:"優";s:2:"Àv";s:3:"償";s:2:"Àw";s:3:"å„¡";s:2:"Àx";s:3:"儲";s:2:"Ày";s:3:"勵";s:2:"Àz";s:3:"嚎";s:2:"À{";s:3:"嚀";s:2:"À|";s:3:"åš";s:2:"À}";s:3:"åš…";s:2:"À~";s:3:"嚇";s:2:"À¡";s:3:"åš";s:2:"À¢";s:3:"壕";s:2:"À£";s:3:"壓";s:2:"À¤";s:3:"壑";s:2:"À¥";s:3:"壎";s:2:"À¦";s:3:"嬰";s:2:"À§";s:3:"嬪";s:2:"À¨";s:3:"嬤";s:2:"À©";s:3:"å­º";s:2:"Àª";s:3:"å°·";s:2:"À«";s:3:"屨";s:2:"À¬";s:3:"å¶¼";s:2:"À­";s:3:"嶺";s:2:"À®";s:3:"å¶½";s:2:"À¯";s:3:"嶸";s:2:"À°";s:3:"幫";s:2:"À±";s:3:"彌";s:2:"À²";s:3:"å¾½";s:2:"À³";s:3:"應";s:2:"À´";s:3:"懂";s:2:"Àµ";s:3:"懇";s:2:"À¶";s:3:"懦";s:2:"À·";s:3:"懋";s:2:"À¸";s:3:"戲";s:2:"À¹";s:3:"戴";s:2:"Àº";s:3:"擎";s:2:"À»";s:3:"擊";s:2:"À¼";s:3:"擘";s:2:"À½";s:3:"æ“ ";s:2:"À¾";s:3:"æ“°";s:2:"À¿";s:3:"擦";s:2:"ÀÀ";s:3:"擬";s:2:"ÀÁ";s:3:"擱";s:2:"ÀÂ";s:3:"æ“¢";s:2:"ÀÃ";s:3:"æ“­";s:2:"ÀÄ";s:3:"æ–‚";s:2:"ÀÅ";s:3:"æ–ƒ";s:2:"ÀÆ";s:3:"æ›™";s:2:"ÀÇ";s:3:"æ›–";s:2:"ÀÈ";s:3:"檀";s:2:"ÀÉ";s:3:"檔";s:2:"ÀÊ";s:3:"檄";s:2:"ÀË";s:3:"檢";s:2:"ÀÌ";s:3:"檜";s:2:"ÀÍ";s:3:"æ«›";s:2:"ÀÎ";s:3:"檣";s:2:"ÀÏ";s:3:"橾";s:2:"ÀÐ";s:3:"檗";s:2:"ÀÑ";s:3:"æª";s:2:"ÀÒ";s:3:"檠";s:2:"ÀÓ";s:3:"æ­œ";s:2:"ÀÔ";s:3:"æ®®";s:2:"ÀÕ";s:3:"毚";s:2:"ÀÖ";s:3:"æ°ˆ";s:2:"À×";s:3:"濘";s:2:"ÀØ";s:3:"濱";s:2:"ÀÙ";s:3:"濟";s:2:"ÀÚ";s:3:"æ¿ ";s:2:"ÀÛ";s:3:"æ¿›";s:2:"ÀÜ";s:3:"濤";s:2:"ÀÝ";s:3:"æ¿«";s:2:"ÀÞ";s:3:"濯";s:2:"Àß";s:3:"æ¾€";s:2:"Àà";s:3:"濬";s:2:"Àá";s:3:"æ¿¡";s:2:"Àâ";s:3:"æ¿©";s:2:"Àã";s:3:"æ¿•";s:2:"Àä";s:3:"æ¿®";s:2:"Àå";s:3:"æ¿°";s:2:"Àæ";s:3:"燧";s:2:"Àç";s:3:"營";s:2:"Àè";s:3:"燮";s:2:"Àé";s:3:"燦";s:2:"Àê";s:3:"燥";s:2:"Àë";s:3:"燭";s:2:"Àì";s:3:"燬";s:2:"Àí";s:3:"燴";s:2:"Àî";s:3:"燠";s:2:"Àï";s:3:"爵";s:2:"Àð";s:3:"牆";s:2:"Àñ";s:3:"ç°";s:2:"Àò";s:3:"ç²";s:2:"Àó";s:3:"ç’©";s:2:"Àô";s:3:"ç’°";s:2:"Àõ";s:3:"ç’¦";s:2:"Àö";s:3:"ç’¨";s:2:"À÷";s:3:"癆";s:2:"Àø";s:3:"療";s:2:"Àù";s:3:"癌";s:2:"Àú";s:3:"盪";s:2:"Àû";s:3:"çž³";s:2:"Àü";s:3:"瞪";s:2:"Àý";s:3:"çž°";s:2:"Àþ";s:3:"瞬";s:2:"Á@";s:3:"çž§";s:2:"ÁA";s:3:"çž­";s:2:"ÁB";s:3:"矯";s:2:"ÁC";s:3:"磷";s:2:"ÁD";s:3:"磺";s:2:"ÁE";s:3:"磴";s:2:"ÁF";s:3:"磯";s:2:"ÁG";s:3:"ç¤";s:2:"ÁH";s:3:"禧";s:2:"ÁI";s:3:"禪";s:2:"ÁJ";s:3:"ç©—";s:2:"ÁK";s:3:"窿";s:2:"ÁL";s:3:"ç°‡";s:2:"ÁM";s:3:"ç°";s:2:"ÁN";s:3:"篾";s:2:"ÁO";s:3:"篷";s:2:"ÁP";s:3:"ç°Œ";s:2:"ÁQ";s:3:"篠";s:2:"ÁR";s:3:"ç³ ";s:2:"ÁS";s:3:"糜";s:2:"ÁT";s:3:"糞";s:2:"ÁU";s:3:"ç³¢";s:2:"ÁV";s:3:"糟";s:2:"ÁW";s:3:"ç³™";s:2:"ÁX";s:3:"ç³";s:2:"ÁY";s:3:"縮";s:2:"ÁZ";s:3:"績";s:2:"Á[";s:3:"繆";s:2:"Á\";s:3:"縷";s:2:"Á]";s:3:"縲";s:2:"Á^";s:3:"繃";s:2:"Á_";s:3:"縫";s:2:"Á`";s:3:"總";s:2:"Áa";s:3:"縱";s:2:"Áb";s:3:"ç¹…";s:2:"Ác";s:3:"ç¹";s:2:"Ád";s:3:"縴";s:2:"Áe";s:3:"縹";s:2:"Áf";s:3:"繈";s:2:"Ág";s:3:"縵";s:2:"Áh";s:3:"縿";s:2:"Ái";s:3:"縯";s:2:"Áj";s:3:"罄";s:2:"Ák";s:3:"翳";s:2:"Ál";s:3:"翼";s:2:"Ám";s:3:"è±";s:2:"Án";s:3:"è²";s:2:"Áo";s:3:"è°";s:2:"Áp";s:3:"è¯";s:2:"Áq";s:3:"è³";s:2:"Ár";s:3:"臆";s:2:"Ás";s:3:"臃";s:2:"Át";s:3:"膺";s:2:"Áu";s:3:"臂";s:2:"Áv";s:3:"臀";s:2:"Áw";s:3:"膿";s:2:"Áx";s:3:"膽";s:2:"Áy";s:3:"臉";s:2:"Áz";s:3:"膾";s:2:"Á{";s:3:"臨";s:2:"Á|";s:3:"舉";s:2:"Á}";s:3:"艱";s:2:"Á~";s:3:"è–ª";s:2:"Á¡";s:3:"è–„";s:2:"Á¢";s:3:"蕾";s:2:"Á£";s:3:"è–œ";s:2:"Á¤";s:3:"è–‘";s:2:"Á¥";s:3:"è–”";s:2:"Á¦";s:3:"è–¯";s:2:"Á§";s:3:"è–›";s:2:"Á¨";s:3:"è–‡";s:2:"Á©";s:3:"è–¨";s:2:"Áª";s:3:"è–Š";s:2:"Á«";s:3:"è™§";s:2:"Á¬";s:3:"蟀";s:2:"Á­";s:3:"蟑";s:2:"Á®";s:3:"èž³";s:2:"Á¯";s:3:"蟒";s:2:"Á°";s:3:"蟆";s:2:"Á±";s:3:"èž«";s:2:"Á²";s:3:"èž»";s:2:"Á³";s:3:"螺";s:2:"Á´";s:3:"蟈";s:2:"Áµ";s:3:"蟋";s:2:"Á¶";s:3:"褻";s:2:"Á·";s:3:"褶";s:2:"Á¸";s:3:"襄";s:2:"Á¹";s:3:"褸";s:2:"Áº";s:3:"褽";s:2:"Á»";s:3:"覬";s:2:"Á¼";s:3:"謎";s:2:"Á½";s:3:"謗";s:2:"Á¾";s:3:"謙";s:2:"Á¿";s:3:"講";s:2:"ÁÀ";s:3:"謊";s:2:"ÁÁ";s:3:"謠";s:2:"ÁÂ";s:3:"è¬";s:2:"ÁÃ";s:3:"謄";s:2:"ÁÄ";s:3:"è¬";s:2:"ÁÅ";s:3:"è±";s:2:"ÁÆ";s:3:"è°¿";s:2:"ÁÇ";s:3:"è±³";s:2:"ÁÈ";s:3:"賺";s:2:"ÁÉ";s:3:"è³½";s:2:"ÁÊ";s:3:"è³¼";s:2:"ÁË";s:3:"賸";s:2:"ÁÌ";s:3:"è³»";s:2:"ÁÍ";s:3:"趨";s:2:"ÁÎ";s:3:"蹉";s:2:"ÁÏ";s:3:"蹋";s:2:"ÁÐ";s:3:"蹈";s:2:"ÁÑ";s:3:"蹊";s:2:"ÁÒ";s:3:"轄";s:2:"ÁÓ";s:3:"è¼¾";s:2:"ÁÔ";s:3:"轂";s:2:"ÁÕ";s:3:"è½…";s:2:"ÁÖ";s:3:"輿";s:2:"Á×";s:3:"é¿";s:2:"ÁØ";s:3:"é½";s:2:"ÁÙ";s:3:"é‚„";s:2:"ÁÚ";s:3:"é‚";s:2:"ÁÛ";s:3:"é‚‚";s:2:"ÁÜ";s:3:"é‚€";s:2:"ÁÝ";s:3:"鄹";s:2:"ÁÞ";s:3:"醣";s:2:"Áß";s:3:"醞";s:2:"Áà";s:3:"醜";s:2:"Áá";s:3:"é";s:2:"Áâ";s:3:"鎂";s:2:"Áã";s:3:"錨";s:2:"Áä";s:3:"éµ";s:2:"Áå";s:3:"éŠ";s:2:"Áæ";s:3:"é¥";s:2:"Áç";s:3:"é‹";s:2:"Áè";s:3:"錘";s:2:"Áé";s:3:"é¾";s:2:"Áê";s:3:"é¬";s:2:"Áë";s:3:"é›";s:2:"Áì";s:3:"é°";s:2:"Áí";s:3:"éš";s:2:"Áî";s:3:"é”";s:2:"Áï";s:3:"é—Š";s:2:"Áð";s:3:"é—‹";s:2:"Áñ";s:3:"é—Œ";s:2:"Áò";s:3:"é—ˆ";s:2:"Áó";s:3:"é—†";s:2:"Áô";s:3:"éš±";s:2:"Áõ";s:3:"隸";s:2:"Áö";s:3:"é›–";s:2:"Á÷";s:3:"霜";s:2:"Áø";s:3:"霞";s:2:"Áù";s:3:"éž ";s:2:"Áú";s:3:"韓";s:2:"Áû";s:3:"顆";s:2:"Áü";s:3:"颶";s:2:"Áý";s:3:"餵";s:2:"Áþ";s:3:"é¨";s:2:"Â@";s:3:"é§¿";s:2:"ÂA";s:3:"é®®";s:2:"ÂB";s:3:"鮫";s:2:"ÂC";s:3:"鮪";s:2:"ÂD";s:3:"é®­";s:2:"ÂE";s:3:"é´»";s:2:"ÂF";s:3:"é´¿";s:2:"ÂG";s:3:"麋";s:2:"ÂH";s:3:"é»";s:2:"ÂI";s:3:"點";s:2:"ÂJ";s:3:"黜";s:2:"ÂK";s:3:"é»";s:2:"ÂL";s:3:"é»›";s:2:"ÂM";s:3:"é¼¾";s:2:"ÂN";s:3:"齋";s:2:"ÂO";s:3:"å¢";s:2:"ÂP";s:3:"åš•";s:2:"ÂQ";s:3:"åš®";s:2:"ÂR";s:3:"壙";s:2:"ÂS";s:3:"壘";s:2:"ÂT";s:3:"嬸";s:2:"ÂU";s:3:"å½";s:2:"ÂV";s:3:"懣";s:2:"ÂW";s:3:"戳";s:2:"ÂX";s:3:"æ“´";s:2:"ÂY";s:3:"擲";s:2:"ÂZ";s:3:"擾";s:2:"Â[";s:3:"攆";s:2:"Â\";s:3:"擺";s:2:"Â]";s:3:"æ“»";s:2:"Â^";s:3:"æ“·";s:2:"Â_";s:3:"æ–·";s:2:"Â`";s:3:"曜";s:2:"Âa";s:3:"朦";s:2:"Âb";s:3:"檳";s:2:"Âc";s:3:"檬";s:2:"Âd";s:3:"櫃";s:2:"Âe";s:3:"檻";s:2:"Âf";s:3:"檸";s:2:"Âg";s:3:"æ«‚";s:2:"Âh";s:3:"檮";s:2:"Âi";s:3:"檯";s:2:"Âj";s:3:"æ­Ÿ";s:2:"Âk";s:3:"æ­¸";s:2:"Âl";s:3:"殯";s:2:"Âm";s:3:"瀉";s:2:"Ân";s:3:"瀋";s:2:"Âo";s:3:"濾";s:2:"Âp";s:3:"瀆";s:2:"Âq";s:3:"濺";s:2:"Âr";s:3:"瀑";s:2:"Âs";s:3:"ç€";s:2:"Ât";s:3:"燻";s:2:"Âu";s:3:"燼";s:2:"Âv";s:3:"燾";s:2:"Âw";s:3:"燸";s:2:"Âx";s:3:"ç·";s:2:"Ây";s:3:"çµ";s:2:"Âz";s:3:"ç’§";s:2:"Â{";s:3:"ç’¿";s:2:"Â|";s:3:"甕";s:2:"Â}";s:3:"ç™–";s:2:"Â~";s:3:"癘";s:2:"¡";s:3:"ç™’";s:2:"¢";s:3:"çž½";s:2:"£";s:3:"çž¿";s:2:"¤";s:3:"çž»";s:2:"Â¥";s:3:"çž¼";s:2:"¦";s:3:"礎";s:2:"§";s:3:"禮";s:2:"¨";s:3:"ç©¡";s:2:"©";s:3:"ç©¢";s:2:"ª";s:3:"ç© ";s:2:"«";s:3:"ç«„";s:2:"¬";s:3:"ç«…";s:2:"­";s:3:"ç°«";s:2:"®";s:3:"ç°§";s:2:"¯";s:3:"ç°ª";s:2:"°";s:3:"ç°ž";s:2:"±";s:3:"ç°£";s:2:"²";s:3:"ç°¡";s:2:"³";s:3:"ç³§";s:2:"´";s:3:"ç¹”";s:2:"µ";s:3:"繕";s:2:"¶";s:3:"繞";s:2:"·";s:3:"繚";s:2:"¸";s:3:"繡";s:2:"¹";s:3:"ç¹’";s:2:"º";s:3:"ç¹™";s:2:"»";s:3:"罈";s:2:"¼";s:3:"翹";s:2:"½";s:3:"ç¿»";s:2:"¾";s:3:"è·";s:2:"¿";s:3:"è¶";s:2:"ÂÀ";s:3:"è‡";s:2:"ÂÁ";s:3:"è‡";s:2:"ÂÂ";s:3:"舊";s:2:"ÂÃ";s:3:"è—";s:2:"ÂÄ";s:3:"è–©";s:2:"ÂÅ";s:3:"è—";s:2:"ÂÆ";s:3:"è—";s:2:"ÂÇ";s:3:"è—‰";s:2:"ÂÈ";s:3:"è–°";s:2:"ÂÉ";s:3:"è–º";s:2:"ÂÊ";s:3:"è–¹";s:2:"ÂË";s:3:"è–¦";s:2:"ÂÌ";s:3:"蟯";s:2:"ÂÍ";s:3:"蟬";s:2:"ÂÎ";s:3:"蟲";s:2:"ÂÏ";s:3:"蟠";s:2:"ÂÐ";s:3:"覆";s:2:"ÂÑ";s:3:"覲";s:2:"ÂÒ";s:3:"è§´";s:2:"ÂÓ";s:3:"謨";s:2:"ÂÔ";s:3:"謹";s:2:"ÂÕ";s:3:"謬";s:2:"ÂÖ";s:3:"謫";s:2:"Â×";s:3:"è±";s:2:"ÂØ";s:3:"è´…";s:2:"ÂÙ";s:3:"è¹™";s:2:"ÂÚ";s:3:"è¹£";s:2:"ÂÛ";s:3:"蹦";s:2:"ÂÜ";s:3:"蹤";s:2:"ÂÝ";s:3:"蹟";s:2:"ÂÞ";s:3:"蹕";s:2:"Âß";s:3:"軀";s:2:"Âà";s:3:"轉";s:2:"Âá";s:3:"è½";s:2:"Ââ";s:3:"邇";s:2:"Âã";s:3:"邃";s:2:"Âä";s:3:"邈";s:2:"Âå";s:3:"醫";s:2:"Âæ";s:3:"醬";s:2:"Âç";s:3:"é‡";s:2:"Âè";s:3:"鎔";s:2:"Âé";s:3:"鎊";s:2:"Âê";s:3:"鎖";s:2:"Âë";s:3:"鎢";s:2:"Âì";s:3:"鎳";s:2:"Âí";s:3:"鎮";s:2:"Âî";s:3:"鎬";s:2:"Âï";s:3:"鎰";s:2:"Âð";s:3:"鎘";s:2:"Âñ";s:3:"鎚";s:2:"Âò";s:3:"鎗";s:2:"Âó";s:3:"é—”";s:2:"Âô";s:3:"é—–";s:2:"Âõ";s:3:"é—";s:2:"Âö";s:3:"é—•";s:2:"Â÷";s:3:"離";s:2:"Âø";s:3:"雜";s:2:"Âù";s:3:"é›™";s:2:"Âú";s:3:"é››";s:2:"Âû";s:3:"雞";s:2:"Âü";s:3:"霤";s:2:"Âý";s:3:"鞣";s:2:"Âþ";s:3:"鞦";s:2:"Ã@";s:3:"éž­";s:2:"ÃA";s:3:"韹";s:2:"ÃB";s:3:"é¡";s:2:"ÃC";s:3:"é¡";s:2:"ÃD";s:3:"題";s:2:"ÃE";s:3:"顎";s:2:"ÃF";s:3:"é¡“";s:2:"ÃG";s:3:"颺";s:2:"ÃH";s:3:"餾";s:2:"ÃI";s:3:"餿";s:2:"ÃJ";s:3:"餽";s:2:"ÃK";s:3:"餮";s:2:"ÃL";s:3:"馥";s:2:"ÃM";s:3:"騎";s:2:"ÃN";s:3:"é«";s:2:"ÃO";s:3:"鬃";s:2:"ÃP";s:3:"鬆";s:2:"ÃQ";s:3:"é­";s:2:"ÃR";s:3:"é­Ž";s:2:"ÃS";s:3:"é­";s:2:"ÃT";s:3:"鯊";s:2:"ÃU";s:3:"鯉";s:2:"ÃV";s:3:"鯽";s:2:"ÃW";s:3:"鯈";s:2:"ÃX";s:3:"鯀";s:2:"ÃY";s:3:"鵑";s:2:"ÃZ";s:3:"éµ";s:2:"Ã[";s:3:"éµ ";s:2:"Ã\";s:3:"é» ";s:2:"Ã]";s:3:"鼕";s:2:"Ã^";s:3:"鼬";s:2:"Ã_";s:3:"儳";s:2:"Ã`";s:3:"嚥";s:2:"Ãa";s:3:"壞";s:2:"Ãb";s:3:"壟";s:2:"Ãc";s:3:"壢";s:2:"Ãd";s:3:"寵";s:2:"Ãe";s:3:"é¾";s:2:"Ãf";s:3:"廬";s:2:"Ãg";s:3:"懲";s:2:"Ãh";s:3:"懷";s:2:"Ãi";s:3:"懶";s:2:"Ãj";s:3:"懵";s:2:"Ãk";s:3:"攀";s:2:"Ãl";s:3:"æ”";s:2:"Ãm";s:3:"æ› ";s:2:"Ãn";s:3:"æ›";s:2:"Ão";s:3:"æ«¥";s:2:"Ãp";s:3:"æ«";s:2:"Ãq";s:3:"櫚";s:2:"Ãr";s:3:"æ«“";s:2:"Ãs";s:3:"瀛";s:2:"Ãt";s:3:"瀟";s:2:"Ãu";s:3:"瀨";s:2:"Ãv";s:3:"瀚";s:2:"Ãw";s:3:"ç€";s:2:"Ãx";s:3:"瀕";s:2:"Ãy";s:3:"瀘";s:2:"Ãz";s:3:"爆";s:2:"Ã{";s:3:"çˆ";s:2:"Ã|";s:3:"牘";s:2:"Ã}";s:3:"犢";s:2:"Ã~";s:3:"ç¸";s:2:"á";s:3:"çº";s:2:"â";s:3:"ç’½";s:2:"ã";s:3:"瓊";s:2:"ä";s:3:"ç“£";s:2:"Ã¥";s:3:"ç–‡";s:2:"æ";s:3:"ç–†";s:2:"ç";s:3:"癟";s:2:"è";s:3:"癡";s:2:"é";s:3:"矇";s:2:"ê";s:3:"礙";s:2:"ë";s:3:"禱";s:2:"ì";s:3:"ç©«";s:2:"í";s:3:"ç©©";s:2:"î";s:3:"ç°¾";s:2:"ï";s:3:"ç°¿";s:2:"ð";s:3:"ç°¸";s:2:"ñ";s:3:"ç°½";s:2:"ò";s:3:"ç°·";s:2:"ó";s:3:"ç±€";s:2:"ô";s:3:"繫";s:2:"õ";s:3:"ç¹­";s:2:"ö";s:3:"ç¹¹";s:2:"÷";s:3:"繩";s:2:"ø";s:3:"繪";s:2:"ù";s:3:"ç¾…";s:2:"ú";s:3:"ç¹³";s:2:"û";s:3:"ç¾¶";s:2:"ü";s:3:"ç¾¹";s:2:"ý";s:3:"羸";s:2:"þ";s:3:"臘";s:2:"ÿ";s:3:"è—©";s:2:"ÃÀ";s:3:"è—";s:2:"ÃÁ";s:3:"è—ª";s:2:"ÃÂ";s:3:"è—•";s:2:"ÃÃ";s:3:"è—¤";s:2:"ÃÄ";s:3:"è—¥";s:2:"ÃÅ";s:3:"è—·";s:2:"ÃÆ";s:3:"蟻";s:2:"ÃÇ";s:3:"è …";s:2:"ÃÈ";s:3:"è ";s:2:"ÃÉ";s:3:"蟹";s:2:"ÃÊ";s:3:"蟾";s:2:"ÃË";s:3:"襠";s:2:"ÃÌ";s:3:"襟";s:2:"ÃÍ";s:3:"襖";s:2:"ÃÎ";s:3:"襞";s:2:"ÃÏ";s:3:"è­";s:2:"ÃÐ";s:3:"è­œ";s:2:"ÃÑ";s:3:"è­˜";s:2:"ÃÒ";s:3:"è­‰";s:2:"ÃÓ";s:3:"è­š";s:2:"ÃÔ";s:3:"è­Ž";s:2:"ÃÕ";s:3:"è­";s:2:"ÃÖ";s:3:"è­†";s:2:"Ã×";s:3:"è­™";s:2:"ÃØ";s:3:"è´ˆ";s:2:"ÃÙ";s:3:"è´Š";s:2:"ÃÚ";s:3:"è¹¼";s:2:"ÃÛ";s:3:"è¹²";s:2:"ÃÜ";s:3:"躇";s:2:"ÃÝ";s:3:"è¹¶";s:2:"ÃÞ";s:3:"蹬";s:2:"Ãß";s:3:"蹺";s:2:"Ãà";s:3:"è¹´";s:2:"Ãá";s:3:"è½”";s:2:"Ãâ";s:3:"轎";s:2:"Ãã";s:3:"è¾­";s:2:"Ãä";s:3:"邊";s:2:"Ãå";s:3:"é‚‹";s:2:"Ãæ";s:3:"醱";s:2:"Ãç";s:3:"醮";s:2:"Ãè";s:3:"é¡";s:2:"Ãé";s:3:"é‘";s:2:"Ãê";s:3:"éŸ";s:2:"Ãë";s:3:"éƒ";s:2:"Ãì";s:3:"éˆ";s:2:"Ãí";s:3:"éœ";s:2:"Ãî";s:3:"é";s:2:"Ãï";s:3:"é–";s:2:"Ãð";s:3:"é¢";s:2:"Ãñ";s:3:"é";s:2:"Ãò";s:3:"é˜";s:2:"Ãó";s:3:"é¤";s:2:"Ãô";s:3:"é—";s:2:"Ãõ";s:3:"é¨";s:2:"Ãö";s:3:"é—œ";s:2:"Ã÷";s:3:"éš´";s:2:"Ãø";s:3:"難";s:2:"Ãù";s:3:"霪";s:2:"Ãú";s:3:"霧";s:2:"Ãû";s:3:"é¡";s:2:"Ãü";s:3:"韜";s:2:"Ãý";s:3:"韻";s:2:"Ãþ";s:3:"類";s:2:"Ä@";s:3:"願";s:2:"ÄA";s:3:"é¡›";s:2:"ÄB";s:3:"颼";s:2:"ÄC";s:3:"饅";s:2:"ÄD";s:3:"饉";s:2:"ÄE";s:3:"騖";s:2:"ÄF";s:3:"騙";s:2:"ÄG";s:3:"é¬";s:2:"ÄH";s:3:"鯨";s:2:"ÄI";s:3:"鯧";s:2:"ÄJ";s:3:"鯖";s:2:"ÄK";s:3:"鯛";s:2:"ÄL";s:3:"鶉";s:2:"ÄM";s:3:"鵡";s:2:"ÄN";s:3:"éµ²";s:2:"ÄO";s:3:"鵪";s:2:"ÄP";s:3:"鵬";s:2:"ÄQ";s:3:"麒";s:2:"ÄR";s:3:"麗";s:2:"ÄS";s:3:"麓";s:2:"ÄT";s:3:"麴";s:2:"ÄU";s:3:"勸";s:2:"ÄV";s:3:"嚨";s:2:"ÄW";s:3:"åš·";s:2:"ÄX";s:3:"åš¶";s:2:"ÄY";s:3:"åš´";s:2:"ÄZ";s:3:"åš¼";s:2:"Ä[";s:3:"壤";s:2:"Ä\";s:3:"å­€";s:2:"Ä]";s:3:"å­ƒ";s:2:"Ä^";s:3:"å­½";s:2:"Ä_";s:3:"寶";s:2:"Ä`";s:3:"å·‰";s:2:"Äa";s:3:"懸";s:2:"Äb";s:3:"懺";s:2:"Äc";s:3:"攘";s:2:"Äd";s:3:"æ””";s:2:"Äe";s:3:"æ”™";s:2:"Äf";s:3:"曦";s:2:"Äg";s:3:"朧";s:2:"Äh";s:3:"櫬";s:2:"Äi";s:3:"瀾";s:2:"Äj";s:3:"瀰";s:2:"Äk";s:3:"瀲";s:2:"Äl";s:3:"çˆ";s:2:"Äm";s:3:"ç»";s:2:"Än";s:3:"ç“";s:2:"Äo";s:3:"癢";s:2:"Äp";s:3:"癥";s:2:"Äq";s:3:"礦";s:2:"Är";s:3:"礪";s:2:"Äs";s:3:"礬";s:2:"Ät";s:3:"礫";s:2:"Äu";s:3:"竇";s:2:"Äv";s:3:"ç«¶";s:2:"Äw";s:3:"籌";s:2:"Äx";s:3:"籃";s:2:"Äy";s:3:"ç±";s:2:"Äz";s:3:"糯";s:2:"Ä{";s:3:"ç³°";s:2:"Ä|";s:3:"è¾®";s:2:"Ä}";s:3:"ç¹½";s:2:"Ä~";s:3:"ç¹¼";s:2:"Ä¡";s:3:"纂";s:2:"Ä¢";s:3:"罌";s:2:"Ä£";s:3:"耀";s:2:"Ĥ";s:3:"臚";s:2:"Ä¥";s:3:"艦";s:2:"Ħ";s:3:"è—»";s:2:"ħ";s:3:"è—¹";s:2:"Ĩ";s:3:"蘑";s:2:"Ä©";s:3:"è—º";s:2:"Ī";s:3:"蘆";s:2:"Ä«";s:3:"蘋";s:2:"Ĭ";s:3:"蘇";s:2:"Ä­";s:3:"蘊";s:2:"Ä®";s:3:"è ”";s:2:"į";s:3:"è •";s:2:"İ";s:3:"襤";s:2:"ı";s:3:"覺";s:2:"IJ";s:3:"觸";s:2:"ij";s:3:"è­°";s:2:"Ä´";s:3:"è­¬";s:2:"ĵ";s:3:"è­¦";s:2:"Ķ";s:3:"è­¯";s:2:"Ä·";s:3:"è­Ÿ";s:2:"ĸ";s:3:"è­«";s:2:"Ĺ";s:3:"è´";s:2:"ĺ";s:3:"è´";s:2:"Ä»";s:3:"躉";s:2:"ļ";s:3:"èº";s:2:"Ľ";s:3:"躅";s:2:"ľ";s:3:"躂";s:2:"Ä¿";s:3:"醴";s:2:"ÄÀ";s:3:"釋";s:2:"ÄÁ";s:3:"é˜";s:2:"ÄÂ";s:3:"éƒ";s:2:"ÄÃ";s:3:"é½";s:2:"ÄÄ";s:3:"é—¡";s:2:"ÄÅ";s:3:"霰";s:2:"ÄÆ";s:3:"飄";s:2:"ÄÇ";s:3:"饒";s:2:"ÄÈ";s:3:"饑";s:2:"ÄÉ";s:3:"馨";s:2:"ÄÊ";s:3:"騫";s:2:"ÄË";s:3:"騰";s:2:"ÄÌ";s:3:"騷";s:2:"ÄÍ";s:3:"騵";s:2:"ÄÎ";s:3:"é°“";s:2:"ÄÏ";s:3:"é°";s:2:"ÄÐ";s:3:"é¹¹";s:2:"ÄÑ";s:3:"麵";s:2:"ÄÒ";s:3:"黨";s:2:"ÄÓ";s:3:"鼯";s:2:"ÄÔ";s:3:"齟";s:2:"ÄÕ";s:3:"é½£";s:2:"ÄÖ";s:3:"齡";s:2:"Ä×";s:3:"å„·";s:2:"ÄØ";s:3:"儸";s:2:"ÄÙ";s:3:"å›";s:2:"ÄÚ";s:3:"囀";s:2:"ÄÛ";s:3:"囂";s:2:"ÄÜ";s:3:"夔";s:2:"ÄÝ";s:3:"屬";s:2:"ÄÞ";s:3:"å·";s:2:"Äß";s:3:"懼";s:2:"Äà";s:3:"懾";s:2:"Äá";s:3:"æ”";s:2:"Äâ";s:3:"攜";s:2:"Äã";s:3:"æ–•";s:2:"Ää";s:3:"曩";s:2:"Äå";s:3:"æ«»";s:2:"Äæ";s:3:"欄";s:2:"Äç";s:3:"櫺";s:2:"Äè";s:3:"殲";s:2:"Äé";s:3:"çŒ";s:2:"Äê";s:3:"爛";s:2:"Äë";s:3:"犧";s:2:"Äì";s:3:"ç“–";s:2:"Äí";s:3:"ç“”";s:2:"Äî";s:3:"癩";s:2:"Äï";s:3:"矓";s:2:"Äð";s:3:"ç±";s:2:"Äñ";s:3:"çº";s:2:"Äò";s:3:"續";s:2:"Äó";s:3:"ç¾¼";s:2:"Äô";s:3:"蘗";s:2:"Äõ";s:3:"蘭";s:2:"Äö";s:3:"蘚";s:2:"Ä÷";s:3:"è £";s:2:"Äø";s:3:"è ¢";s:2:"Äù";s:3:"è ¡";s:2:"Äú";s:3:"è Ÿ";s:2:"Äû";s:3:"襪";s:2:"Äü";s:3:"襬";s:2:"Äý";s:3:"覽";s:2:"Äþ";s:3:"è­´";s:2:"Å@";s:3:"è­·";s:2:"ÅA";s:3:"è­½";s:2:"ÅB";s:3:"è´“";s:2:"ÅC";s:3:"躊";s:2:"ÅD";s:3:"èº";s:2:"ÅE";s:3:"躋";s:2:"ÅF";s:3:"轟";s:2:"ÅG";s:3:"辯";s:2:"ÅH";s:3:"醺";s:2:"ÅI";s:3:"é®";s:2:"ÅJ";s:3:"é³";s:2:"ÅK";s:3:"éµ";s:2:"ÅL";s:3:"éº";s:2:"ÅM";s:3:"é¸";s:2:"ÅN";s:3:"é²";s:2:"ÅO";s:3:"é«";s:2:"ÅP";s:3:"é—¢";s:2:"ÅQ";s:3:"霸";s:2:"ÅR";s:3:"霹";s:2:"ÅS";s:3:"露";s:2:"ÅT";s:3:"響";s:2:"ÅU";s:3:"é¡§";s:2:"ÅV";s:3:"é¡¥";s:2:"ÅW";s:3:"饗";s:2:"ÅX";s:3:"é©…";s:2:"ÅY";s:3:"驃";s:2:"ÅZ";s:3:"é©€";s:2:"Å[";s:3:"騾";s:2:"Å\";s:3:"é«";s:2:"Å]";s:3:"é­”";s:2:"Å^";s:3:"é­‘";s:2:"Å_";s:3:"é°­";s:2:"Å`";s:3:"é°¥";s:2:"Åa";s:3:"鶯";s:2:"Åb";s:3:"é¶´";s:2:"Åc";s:3:"é·‚";s:2:"Åd";s:3:"鶸";s:2:"Åe";s:3:"éº";s:2:"Åf";s:3:"黯";s:2:"Åg";s:3:"é¼™";s:2:"Åh";s:3:"齜";s:2:"Åi";s:3:"齦";s:2:"Åj";s:3:"é½§";s:2:"Åk";s:3:"儼";s:2:"Ål";s:3:"å„»";s:2:"Åm";s:3:"囈";s:2:"Ån";s:3:"囊";s:2:"Åo";s:3:"囉";s:2:"Åp";s:3:"å­¿";s:2:"Åq";s:3:"å·”";s:2:"År";s:3:"å·’";s:2:"Ås";s:3:"彎";s:2:"Åt";s:3:"懿";s:2:"Åu";s:3:"攤";s:2:"Åv";s:3:"權";s:2:"Åw";s:3:"æ­¡";s:2:"Åx";s:3:"ç‘";s:2:"Åy";s:3:"ç˜";s:2:"Åz";s:3:"玀";s:2:"Å{";s:3:"瓤";s:2:"Å|";s:3:"ç–Š";s:2:"Å}";s:3:"ç™®";s:2:"Å~";s:3:"癬";s:2:"Å¡";s:3:"禳";s:2:"Å¢";s:3:"ç± ";s:2:"Å£";s:3:"籟";s:2:"Ť";s:3:"è¾";s:2:"Å¥";s:3:"è½";s:2:"Ŧ";s:3:"臟";s:2:"ŧ";s:3:"襲";s:2:"Ũ";s:3:"襯";s:2:"Å©";s:3:"è§¼";s:2:"Ū";s:3:"讀";s:2:"Å«";s:3:"è´–";s:2:"Ŭ";s:3:"è´—";s:2:"Å­";s:3:"躑";s:2:"Å®";s:3:"躓";s:2:"ů";s:3:"轡";s:2:"Ű";s:3:"é…ˆ";s:2:"ű";s:3:"é‘„";s:2:"Ų";s:3:"é‘‘";s:2:"ų";s:3:"é‘’";s:2:"Å´";s:3:"霽";s:2:"ŵ";s:3:"霾";s:2:"Ŷ";s:3:"韃";s:2:"Å·";s:3:"éŸ";s:2:"Ÿ";s:3:"é¡«";s:2:"Ź";s:3:"饕";s:2:"ź";s:3:"é©•";s:2:"Å»";s:3:"é©";s:2:"ż";s:3:"é«’";s:2:"Ž";s:3:"鬚";s:2:"ž";s:3:"鱉";s:2:"Å¿";s:3:"é°±";s:2:"ÅÀ";s:3:"é°¾";s:2:"ÅÁ";s:3:"é°»";s:2:"ÅÂ";s:3:"é·“";s:2:"ÅÃ";s:3:"é·—";s:2:"ÅÄ";s:3:"é¼´";s:2:"ÅÅ";s:3:"齬";s:2:"ÅÆ";s:3:"齪";s:2:"ÅÇ";s:3:"é¾”";s:2:"ÅÈ";s:3:"囌";s:2:"ÅÉ";s:3:"å·–";s:2:"ÅÊ";s:3:"戀";s:2:"ÅË";s:3:"攣";s:2:"ÅÌ";s:3:"攫";s:2:"ÅÍ";s:3:"攪";s:2:"ÅÎ";s:3:"曬";s:2:"ÅÏ";s:3:"æ¬";s:2:"ÅÐ";s:3:"瓚";s:2:"ÅÑ";s:3:"竊";s:2:"ÅÒ";s:3:"籤";s:2:"ÅÓ";s:3:"ç±£";s:2:"ÅÔ";s:3:"ç±¥";s:2:"ÅÕ";s:3:"纓";s:2:"ÅÖ";s:3:"纖";s:2:"Å×";s:3:"纔";s:2:"ÅØ";s:3:"臢";s:2:"ÅÙ";s:3:"蘸";s:2:"ÅÚ";s:3:"蘿";s:2:"ÅÛ";s:3:"è ±";s:2:"ÅÜ";s:3:"變";s:2:"ÅÝ";s:3:"é‚";s:2:"ÅÞ";s:3:"é‚";s:2:"Åß";s:3:"é‘£";s:2:"Åà";s:3:"é‘ ";s:2:"Åá";s:3:"鑤";s:2:"Åâ";s:3:"é¨";s:2:"Åã";s:3:"顯";s:2:"Åä";s:3:"饜";s:2:"Åå";s:3:"驚";s:2:"Åæ";s:3:"é©›";s:2:"Åç";s:3:"é©—";s:2:"Åè";s:3:"é«“";s:2:"Åé";s:3:"é«”";s:2:"Åê";s:3:"é«‘";s:2:"Åë";s:3:"é±”";s:2:"Åì";s:3:"é±—";s:2:"Åí";s:3:"é±–";s:2:"Åî";s:3:"é·¥";s:2:"Åï";s:3:"麟";s:2:"Åð";s:3:"é»´";s:2:"Åñ";s:3:"囑";s:2:"Åò";s:3:"壩";s:2:"Åó";s:3:"攬";s:2:"Åô";s:3:"çž";s:2:"Åõ";s:3:"ç™±";s:2:"Åö";s:3:"癲";s:2:"Å÷";s:3:"矗";s:2:"Åø";s:3:"ç½";s:2:"Åù";s:3:"羈";s:2:"Åú";s:3:"è ¶";s:2:"Åû";s:3:"è ¹";s:2:"Åü";s:3:"è¡¢";s:2:"Åý";s:3:"讓";s:2:"Åþ";s:3:"è®’";s:2:"Æ@";s:3:"è®–";s:2:"ÆA";s:3:"艷";s:2:"ÆB";s:3:"è´›";s:2:"ÆC";s:3:"釀";s:2:"ÆD";s:3:"鑪";s:2:"ÆE";s:3:"é‚";s:2:"ÆF";s:3:"éˆ";s:2:"ÆG";s:3:"é„";s:2:"ÆH";s:3:"韆";s:2:"ÆI";s:3:"é¡°";s:2:"ÆJ";s:3:"驟";s:2:"ÆK";s:3:"鬢";s:2:"ÆL";s:3:"é­˜";s:2:"ÆM";s:3:"鱟";s:2:"ÆN";s:3:"é·¹";s:2:"ÆO";s:3:"é·º";s:2:"ÆP";s:3:"é¹¼";s:2:"ÆQ";s:3:"é¹½";s:2:"ÆR";s:3:"鼇";s:2:"ÆS";s:3:"é½·";s:2:"ÆT";s:3:"é½²";s:2:"ÆU";s:3:"廳";s:2:"ÆV";s:3:"欖";s:2:"ÆW";s:3:"ç£";s:2:"ÆX";s:3:"籬";s:2:"ÆY";s:3:"ç±®";s:2:"ÆZ";s:3:"è »";s:2:"Æ[";s:3:"è§€";s:2:"Æ\";s:3:"躡";s:2:"Æ]";s:3:"é‡";s:2:"Æ^";s:3:"鑲";s:2:"Æ_";s:3:"é‘°";s:2:"Æ`";s:3:"顱";s:2:"Æa";s:3:"饞";s:2:"Æb";s:3:"é«–";s:2:"Æc";s:3:"鬣";s:2:"Æd";s:3:"黌";s:2:"Æe";s:3:"ç¤";s:2:"Æf";s:3:"矚";s:2:"Æg";s:3:"讚";s:2:"Æh";s:3:"é‘·";s:2:"Æi";s:3:"韉";s:2:"Æj";s:3:"é©¢";s:2:"Æk";s:3:"é©¥";s:2:"Æl";s:3:"纜";s:2:"Æm";s:3:"讜";s:2:"Æn";s:3:"躪";s:2:"Æo";s:3:"釅";s:2:"Æp";s:3:"鑽";s:2:"Æq";s:3:"鑾";s:2:"Ær";s:3:"鑼";s:2:"Æs";s:3:"é±·";s:2:"Æt";s:3:"鱸";s:2:"Æu";s:3:"é»·";s:2:"Æv";s:3:"è±”";s:2:"Æw";s:3:"é‘¿";s:2:"Æx";s:3:"鸚";s:2:"Æy";s:3:"爨";s:2:"Æz";s:3:"驪";s:2:"Æ{";s:3:"鬱";s:2:"Æ|";s:3:"鸛";s:2:"Æ}";s:3:"鸞";s:2:"Æ~";s:3:"ç±²";s:2:"Æ¡";s:3:"ヾ";s:2:"Æ¢";s:3:"ã‚";s:2:"Æ£";s:3:"ゞ";s:2:"Ƥ";s:3:"々";s:2:"Æ¥";s:3:"ã";s:2:"Ʀ";s:3:"ã‚";s:2:"Ƨ";s:3:"ãƒ";s:2:"ƨ";s:3:"ã„";s:2:"Æ©";s:3:"ã…";s:2:"ƪ";s:3:"ã†";s:2:"Æ«";s:3:"ã‡";s:2:"Ƭ";s:3:"ãˆ";s:2:"Æ­";s:3:"ã‰";s:2:"Æ®";s:3:"ãŠ";s:2:"Ư";s:3:"ã‹";s:2:"ư";s:3:"ãŒ";s:2:"Ʊ";s:3:"ã";s:2:"Ʋ";s:3:"ãŽ";s:2:"Ƴ";s:3:"ã";s:2:"Æ´";s:3:"ã";s:2:"Ƶ";s:3:"ã‘";s:2:"ƶ";s:3:"ã’";s:2:"Æ·";s:3:"ã“";s:2:"Ƹ";s:3:"ã”";s:2:"ƹ";s:3:"ã•";s:2:"ƺ";s:3:"ã–";s:2:"Æ»";s:3:"ã—";s:2:"Ƽ";s:3:"ã˜";s:2:"ƽ";s:3:"ã™";s:2:"ƾ";s:3:"ãš";s:2:"Æ¿";s:3:"ã›";s:2:"ÆÀ";s:3:"ãœ";s:2:"ÆÁ";s:3:"ã";s:2:"ÆÂ";s:3:"ãž";s:2:"ÆÃ";s:3:"ãŸ";s:2:"ÆÄ";s:3:"ã ";s:2:"ÆÅ";s:3:"ã¡";s:2:"ÆÆ";s:3:"ã¢";s:2:"ÆÇ";s:3:"ã£";s:2:"ÆÈ";s:3:"ã¤";s:2:"ÆÉ";s:3:"ã¥";s:2:"ÆÊ";s:3:"ã¦";s:2:"ÆË";s:3:"ã§";s:2:"ÆÌ";s:3:"ã¨";s:2:"ÆÍ";s:3:"ã©";s:2:"ÆÎ";s:3:"ãª";s:2:"ÆÏ";s:3:"ã«";s:2:"ÆÐ";s:3:"ã¬";s:2:"ÆÑ";s:3:"ã­";s:2:"ÆÒ";s:3:"ã®";s:2:"ÆÓ";s:3:"ã¯";s:2:"ÆÔ";s:3:"ã°";s:2:"ÆÕ";s:3:"ã±";s:2:"ÆÖ";s:3:"ã²";s:2:"Æ×";s:3:"ã³";s:2:"ÆØ";s:3:"ã´";s:2:"ÆÙ";s:3:"ãµ";s:2:"ÆÚ";s:3:"ã¶";s:2:"ÆÛ";s:3:"ã·";s:2:"ÆÜ";s:3:"ã¸";s:2:"ÆÝ";s:3:"ã¹";s:2:"ÆÞ";s:3:"ãº";s:2:"Æß";s:3:"ã»";s:2:"Æà";s:3:"ã¼";s:2:"Æá";s:3:"ã½";s:2:"Æâ";s:3:"ã¾";s:2:"Æã";s:3:"ã¿";s:2:"Æä";s:3:"ã‚€";s:2:"Æå";s:3:"ã‚";s:2:"Ææ";s:3:"ã‚‚";s:2:"Æç";s:3:"ゃ";s:2:"Æè";s:3:"ã‚„";s:2:"Æé";s:3:"ã‚…";s:2:"Æê";s:3:"ゆ";s:2:"Æë";s:3:"ょ";s:2:"Æì";s:3:"よ";s:2:"Æí";s:3:"ら";s:2:"Æî";s:3:"り";s:2:"Æï";s:3:"ã‚‹";s:2:"Æð";s:3:"れ";s:2:"Æñ";s:3:"ã‚";s:2:"Æò";s:3:"ゎ";s:2:"Æó";s:3:"ã‚";s:2:"Æô";s:3:"ã‚";s:2:"Æõ";s:3:"ã‚‘";s:2:"Æö";s:3:"ã‚’";s:2:"Æ÷";s:3:"ã‚“";s:2:"Æø";s:3:"ã‚¡";s:2:"Æù";s:3:"ã‚¢";s:2:"Æú";s:3:"ã‚£";s:2:"Æû";s:3:"イ";s:2:"Æü";s:3:"ã‚¥";s:2:"Æý";s:3:"ウ";s:2:"Æþ";s:3:"ã‚§";s:2:"Ç@";s:3:"エ";s:2:"ÇA";s:3:"ã‚©";s:2:"ÇB";s:3:"オ";s:2:"ÇC";s:3:"ã‚«";s:2:"ÇD";s:3:"ガ";s:2:"ÇE";s:3:"ã‚­";s:2:"ÇF";s:3:"ã‚®";s:2:"ÇG";s:3:"ク";s:2:"ÇH";s:3:"ã‚°";s:2:"ÇI";s:3:"ケ";s:2:"ÇJ";s:3:"ゲ";s:2:"ÇK";s:3:"コ";s:2:"ÇL";s:3:"ã‚´";s:2:"ÇM";s:3:"サ";s:2:"ÇN";s:3:"ã‚¶";s:2:"ÇO";s:3:"ã‚·";s:2:"ÇP";s:3:"ジ";s:2:"ÇQ";s:3:"ス";s:2:"ÇR";s:3:"ズ";s:2:"ÇS";s:3:"ã‚»";s:2:"ÇT";s:3:"ゼ";s:2:"ÇU";s:3:"ソ";s:2:"ÇV";s:3:"ゾ";s:2:"ÇW";s:3:"ã‚¿";s:2:"ÇX";s:3:"ダ";s:2:"ÇY";s:3:"ãƒ";s:2:"ÇZ";s:3:"ヂ";s:2:"Ç[";s:3:"ッ";s:2:"Ç\";s:3:"ツ";s:2:"Ç]";s:3:"ヅ";s:2:"Ç^";s:3:"テ";s:2:"Ç_";s:3:"デ";s:2:"Ç`";s:3:"ト";s:2:"Ça";s:3:"ド";s:2:"Çb";s:3:"ナ";s:2:"Çc";s:3:"ニ";s:2:"Çd";s:3:"ヌ";s:2:"Çe";s:3:"ãƒ";s:2:"Çf";s:3:"ノ";s:2:"Çg";s:3:"ãƒ";s:2:"Çh";s:3:"ãƒ";s:2:"Çi";s:3:"パ";s:2:"Çj";s:3:"ヒ";s:2:"Çk";s:3:"ビ";s:2:"Çl";s:3:"ピ";s:2:"Çm";s:3:"フ";s:2:"Çn";s:3:"ブ";s:2:"Ço";s:3:"プ";s:2:"Çp";s:3:"ヘ";s:2:"Çq";s:3:"ベ";s:2:"Çr";s:3:"ペ";s:2:"Çs";s:3:"ホ";s:2:"Çt";s:3:"ボ";s:2:"Çu";s:3:"ãƒ";s:2:"Çv";s:3:"マ";s:2:"Çw";s:3:"ミ";s:2:"Çx";s:3:"ム";s:2:"Çy";s:3:"メ";s:2:"Çz";s:3:"モ";s:2:"Ç{";s:3:"ャ";s:2:"Ç|";s:3:"ヤ";s:2:"Ç}";s:3:"ュ";s:2:"Ç~";s:3:"ユ";s:2:"Ç¡";s:3:"ョ";s:2:"Ç¢";s:3:"ヨ";s:2:"Ç£";s:3:"ラ";s:2:"Ǥ";s:3:"リ";s:2:"Ç¥";s:3:"ル";s:2:"Ǧ";s:3:"レ";s:2:"ǧ";s:3:"ロ";s:2:"Ǩ";s:3:"ヮ";s:2:"Ç©";s:3:"ワ";s:2:"Ǫ";s:3:"ヰ";s:2:"Ç«";s:3:"ヱ";s:2:"Ǭ";s:3:"ヲ";s:2:"Ç­";s:3:"ン";s:2:"Ç®";s:3:"ヴ";s:2:"ǯ";s:3:"ヵ";s:2:"ǰ";s:3:"ヶ";s:2:"DZ";s:2:"Д";s:2:"Dz";s:2:"Е";s:2:"dz";s:2:"Ð";s:2:"Ç´";s:2:"Ж";s:2:"ǵ";s:2:"З";s:2:"Ƕ";s:2:"И";s:2:"Ç·";s:2:"Й";s:2:"Ǹ";s:2:"К";s:2:"ǹ";s:2:"Л";s:2:"Ǻ";s:2:"М";s:2:"Ç»";s:2:"У";s:2:"Ǽ";s:2:"Ф";s:2:"ǽ";s:2:"Ð¥";s:2:"Ǿ";s:2:"Ц";s:2:"Ç¿";s:2:"Ч";s:2:"ÇÀ";s:2:"Ш";s:2:"ÇÁ";s:2:"Щ";s:2:"ÇÂ";s:2:"Ъ";s:2:"ÇÃ";s:2:"Ы";s:2:"ÇÄ";s:2:"Ь";s:2:"ÇÅ";s:2:"Э";s:2:"ÇÆ";s:2:"Ю";s:2:"ÇÇ";s:2:"Я";s:2:"ÇÈ";s:2:"а";s:2:"ÇÉ";s:2:"б";s:2:"ÇÊ";s:2:"в";s:2:"ÇË";s:2:"г";s:2:"ÇÌ";s:2:"д";s:2:"ÇÍ";s:2:"е";s:2:"ÇÎ";s:2:"Ñ‘";s:2:"ÇÏ";s:2:"ж";s:2:"ÇÐ";s:2:"з";s:2:"ÇÑ";s:2:"и";s:2:"ÇÒ";s:2:"й";s:2:"ÇÓ";s:2:"к";s:2:"ÇÔ";s:2:"л";s:2:"ÇÕ";s:2:"м";s:2:"ÇÖ";s:2:"н";s:2:"Ç×";s:2:"о";s:2:"ÇØ";s:2:"п";s:2:"ÇÙ";s:2:"Ñ€";s:2:"ÇÚ";s:2:"Ñ";s:2:"ÇÛ";s:2:"Ñ‚";s:2:"ÇÜ";s:2:"у";s:2:"ÇÝ";s:2:"Ñ„";s:2:"ÇÞ";s:2:"Ñ…";s:2:"Çß";s:2:"ц";s:2:"Çà";s:2:"ч";s:2:"Çá";s:2:"ш";s:2:"Çâ";s:2:"щ";s:2:"Çã";s:2:"ÑŠ";s:2:"Çä";s:2:"Ñ‹";s:2:"Çå";s:2:"ÑŒ";s:2:"Çæ";s:2:"Ñ";s:2:"Çç";s:2:"ÑŽ";s:2:"Çè";s:2:"Ñ";s:2:"Çé";s:3:"â‘ ";s:2:"Çê";s:3:"â‘¡";s:2:"Çë";s:3:"â‘¢";s:2:"Çì";s:3:"â‘£";s:2:"Çí";s:3:"⑤";s:2:"Çî";s:3:"â‘¥";s:2:"Çï";s:3:"⑦";s:2:"Çð";s:3:"â‘§";s:2:"Çñ";s:3:"⑨";s:2:"Çò";s:3:"â‘©";s:2:"Çó";s:3:"â‘´";s:2:"Çô";s:3:"⑵";s:2:"Çõ";s:3:"â‘¶";s:2:"Çö";s:3:"â‘·";s:2:"Ç÷";s:3:"⑸";s:2:"Çø";s:3:"⑹";s:2:"Çù";s:3:"⑺";s:2:"Çú";s:3:"â‘»";s:2:"Çû";s:3:"⑼";s:2:"Çü";s:3:"⑽";s:2:"É@";s:3:"乂";s:2:"ÉA";s:3:"乜";s:2:"ÉB";s:3:"凵";s:2:"ÉC";s:3:"匚";s:2:"ÉD";s:3:"厂";s:2:"ÉE";s:3:"万";s:2:"ÉF";s:3:"丌";s:2:"ÉG";s:3:"乇";s:2:"ÉH";s:3:"äº";s:2:"ÉI";s:3:"å›—";s:2:"ÉJ";s:3:"兀";s:2:"ÉK";s:3:"å±®";s:2:"ÉL";s:3:"å½³";s:2:"ÉM";s:3:"ä¸";s:2:"ÉN";s:3:"冇";s:2:"ÉO";s:3:"与";s:2:"ÉP";s:3:"丮";s:2:"ÉQ";s:3:"亓";s:2:"ÉR";s:3:"仂";s:2:"ÉS";s:3:"仉";s:2:"ÉT";s:3:"仈";s:2:"ÉU";s:3:"冘";s:2:"ÉV";s:3:"勼";s:2:"ÉW";s:3:"å¬";s:2:"ÉX";s:3:"厹";s:2:"ÉY";s:3:"圠";s:2:"ÉZ";s:3:"夃";s:2:"É[";s:3:"夬";s:2:"É\";s:3:"å°";s:2:"É]";s:3:"å·¿";s:2:"É^";s:3:"æ—¡";s:2:"É_";s:3:"殳";s:2:"É`";s:3:"毌";s:2:"Éa";s:3:"æ°”";s:2:"Éb";s:3:"爿";s:2:"Éc";s:3:"丱";s:2:"Éd";s:3:"丼";s:2:"Ée";s:3:"仨";s:2:"Éf";s:3:"仜";s:2:"Ég";s:3:"仩";s:2:"Éh";s:3:"仡";s:2:"Éi";s:3:"ä»";s:2:"Éj";s:3:"仚";s:2:"Ék";s:3:"刌";s:2:"Él";s:3:"匜";s:2:"Ém";s:3:"åŒ";s:2:"Én";s:3:"圢";s:2:"Éo";s:3:"圣";s:2:"Ép";s:3:"夗";s:2:"Éq";s:3:"夯";s:2:"Ér";s:3:"å®";s:2:"És";s:3:"宄";s:2:"Ét";s:3:"å°’";s:2:"Éu";s:3:"å°»";s:2:"Év";s:3:"å±´";s:2:"Éw";s:3:"å±³";s:2:"Éx";s:3:"帄";s:2:"Éy";s:3:"庀";s:2:"Éz";s:3:"庂";s:2:"É{";s:3:"忉";s:2:"É|";s:3:"戉";s:2:"É}";s:3:"æ‰";s:2:"É~";s:3:"æ°•";s:2:"É¡";s:3:"æ°¶";s:2:"É¢";s:3:"汃";s:2:"É£";s:3:"æ°¿";s:2:"ɤ";s:3:"æ°»";s:2:"É¥";s:3:"犮";s:2:"ɦ";s:3:"犰";s:2:"ɧ";s:3:"玊";s:2:"ɨ";s:3:"禸";s:2:"É©";s:3:"肊";s:2:"ɪ";s:3:"阞";s:2:"É«";s:3:"伎";s:2:"ɬ";s:3:"优";s:2:"É­";s:3:"伬";s:2:"É®";s:3:"仵";s:2:"ɯ";s:3:"ä¼”";s:2:"ɰ";s:3:"ä»±";s:2:"ɱ";s:3:"ä¼€";s:2:"ɲ";s:3:"ä»·";s:2:"ɳ";s:3:"伈";s:2:"É´";s:3:"ä¼";s:2:"ɵ";s:3:"伂";s:2:"ɶ";s:3:"ä¼…";s:2:"É·";s:3:"ä¼¢";s:2:"ɸ";s:3:"伓";s:2:"ɹ";s:3:"伄";s:2:"ɺ";s:3:"ä»´";s:2:"É»";s:3:"ä¼’";s:2:"ɼ";s:3:"冱";s:2:"ɽ";s:3:"刓";s:2:"ɾ";s:3:"刉";s:2:"É¿";s:3:"åˆ";s:2:"ÉÀ";s:3:"劦";s:2:"ÉÁ";s:3:"匢";s:2:"ÉÂ";s:3:"匟";s:2:"ÉÃ";s:3:"å";s:2:"ÉÄ";s:3:"厊";s:2:"ÉÅ";s:3:"å‡";s:2:"ÉÆ";s:3:"囡";s:2:"ÉÇ";s:3:"囟";s:2:"ÉÈ";s:3:"圮";s:2:"ÉÉ";s:3:"圪";s:2:"ÉÊ";s:3:"圴";s:2:"ÉË";s:3:"夼";s:2:"ÉÌ";s:3:"妀";s:2:"ÉÍ";s:3:"奼";s:2:"ÉÎ";s:3:"妅";s:2:"ÉÏ";s:3:"奻";s:2:"ÉÐ";s:3:"奾";s:2:"ÉÑ";s:3:"奷";s:2:"ÉÒ";s:3:"奿";s:2:"ÉÓ";s:3:"å­–";s:2:"ÉÔ";s:3:"å°•";s:2:"ÉÕ";s:3:"å°¥";s:2:"ÉÖ";s:3:"å±¼";s:2:"É×";s:3:"屺";s:2:"ÉØ";s:3:"å±»";s:2:"ÉÙ";s:3:"å±¾";s:2:"ÉÚ";s:3:"å·Ÿ";s:2:"ÉÛ";s:3:"å¹µ";s:2:"ÉÜ";s:3:"庄";s:2:"ÉÝ";s:3:"异";s:2:"ÉÞ";s:3:"弚";s:2:"Éß";s:3:"å½´";s:2:"Éà";s:3:"å¿•";s:2:"Éá";s:3:"å¿”";s:2:"Éâ";s:3:"å¿";s:2:"Éã";s:3:"扜";s:2:"Éä";s:3:"扞";s:2:"Éå";s:3:"扤";s:2:"Éæ";s:3:"扡";s:2:"Éç";s:3:"扦";s:2:"Éè";s:3:"扢";s:2:"Éé";s:3:"扙";s:2:"Éê";s:3:"扠";s:2:"Éë";s:3:"扚";s:2:"Éì";s:3:"扥";s:2:"Éí";s:3:"æ—¯";s:2:"Éî";s:3:"æ—®";s:2:"Éï";s:3:"朾";s:2:"Éð";s:3:"朹";s:2:"Éñ";s:3:"朸";s:2:"Éò";s:3:"朻";s:2:"Éó";s:3:"机";s:2:"Éô";s:3:"朿";s:2:"Éõ";s:3:"朼";s:2:"Éö";s:3:"朳";s:2:"É÷";s:3:"æ°˜";s:2:"Éø";s:3:"汆";s:2:"Éù";s:3:"æ±’";s:2:"Éú";s:3:"汜";s:2:"Éû";s:3:"æ±";s:2:"Éü";s:3:"汊";s:2:"Éý";s:3:"æ±”";s:2:"Éþ";s:3:"汋";s:2:"Ê@";s:3:"汌";s:2:"ÊA";s:3:"ç±";s:2:"ÊB";s:3:"牞";s:2:"ÊC";s:3:"犴";s:2:"ÊD";s:3:"犵";s:2:"ÊE";s:3:"玎";s:2:"ÊF";s:3:"甪";s:2:"ÊG";s:3:"癿";s:2:"ÊH";s:3:"穵";s:2:"ÊI";s:3:"网";s:2:"ÊJ";s:3:"艸";s:2:"ÊK";s:3:"艼";s:2:"ÊL";s:3:"芀";s:2:"ÊM";s:3:"艽";s:2:"ÊN";s:3:"艿";s:2:"ÊO";s:3:"è™";s:2:"ÊP";s:3:"襾";s:2:"ÊQ";s:3:"é‚™";s:2:"ÊR";s:3:"é‚—";s:2:"ÊS";s:3:"邘";s:2:"ÊT";s:3:"é‚›";s:2:"ÊU";s:3:"é‚”";s:2:"ÊV";s:3:"阢";s:2:"ÊW";s:3:"阤";s:2:"ÊX";s:3:"阠";s:2:"ÊY";s:3:"阣";s:2:"ÊZ";s:3:"ä½–";s:2:"Ê[";s:3:"ä¼»";s:2:"Ê\";s:3:"ä½¢";s:2:"Ê]";s:3:"佉";s:2:"Ê^";s:3:"体";s:2:"Ê_";s:3:"佤";s:2:"Ê`";s:3:"ä¼¾";s:2:"Êa";s:3:"ä½§";s:2:"Êb";s:3:"ä½’";s:2:"Êc";s:3:"佟";s:2:"Êd";s:3:"ä½";s:2:"Êe";s:3:"佘";s:2:"Êf";s:3:"ä¼­";s:2:"Êg";s:3:"ä¼³";s:2:"Êh";s:3:"伿";s:2:"Êi";s:3:"佡";s:2:"Êj";s:3:"å†";s:2:"Êk";s:3:"冹";s:2:"Êl";s:3:"刜";s:2:"Êm";s:3:"刞";s:2:"Ên";s:3:"刡";s:2:"Êo";s:3:"劭";s:2:"Êp";s:3:"劮";s:2:"Êq";s:3:"匉";s:2:"Êr";s:3:"å£";s:2:"Ês";s:3:"å²";s:2:"Êt";s:3:"厎";s:2:"Êu";s:3:"åŽ";s:2:"Êv";s:3:"å°";s:2:"Êw";s:3:"å·";s:2:"Êx";s:3:"åª";s:2:"Êy";s:3:"å‘”";s:2:"Êz";s:3:"å‘…";s:2:"Ê{";s:3:"å™";s:2:"Ê|";s:3:"åœ";s:2:"Ê}";s:3:"å¥";s:2:"Ê~";s:3:"å˜";s:2:"Ê¡";s:3:"å½";s:2:"Ê¢";s:3:"å‘";s:2:"Ê£";s:3:"å‘";s:2:"ʤ";s:3:"å¨";s:2:"Ê¥";s:3:"å¤";s:2:"ʦ";s:3:"呇";s:2:"ʧ";s:3:"å›®";s:2:"ʨ";s:3:"å›§";s:2:"Ê©";s:3:"囥";s:2:"ʪ";s:3:"å";s:2:"Ê«";s:3:"å…";s:2:"ʬ";s:3:"åŒ";s:2:"Ê­";s:3:"å‰";s:2:"Ê®";s:3:"å‹";s:2:"ʯ";s:3:"å’";s:2:"ʰ";s:3:"夆";s:2:"ʱ";s:3:"奀";s:2:"ʲ";s:3:"妦";s:2:"ʳ";s:3:"妘";s:2:"Ê´";s:3:"妠";s:2:"ʵ";s:3:"妗";s:2:"ʶ";s:3:"妎";s:2:"Ê·";s:3:"妢";s:2:"ʸ";s:3:"å¦";s:2:"ʹ";s:3:"å¦";s:2:"ʺ";s:3:"妧";s:2:"Ê»";s:3:"妡";s:2:"ʼ";s:3:"宎";s:2:"ʽ";s:3:"å®’";s:2:"ʾ";s:3:"å°¨";s:2:"Ê¿";s:3:"å°ª";s:2:"ÊÀ";s:3:"å²";s:2:"ÊÁ";s:3:"å²";s:2:"ÊÂ";s:3:"岈";s:2:"ÊÃ";s:3:"岋";s:2:"ÊÄ";s:3:"岉";s:2:"ÊÅ";s:3:"å²’";s:2:"ÊÆ";s:3:"岊";s:2:"ÊÇ";s:3:"岆";s:2:"ÊÈ";s:3:"岓";s:2:"ÊÉ";s:3:"岕";s:2:"ÊÊ";s:3:"å· ";s:2:"ÊË";s:3:"帊";s:2:"ÊÌ";s:3:"帎";s:2:"ÊÍ";s:3:"庋";s:2:"ÊÎ";s:3:"庉";s:2:"ÊÏ";s:3:"庌";s:2:"ÊÐ";s:3:"庈";s:2:"ÊÑ";s:3:"åº";s:2:"ÊÒ";s:3:"å¼…";s:2:"ÊÓ";s:3:"å¼";s:2:"ÊÔ";s:3:"彸";s:2:"ÊÕ";s:3:"å½¶";s:2:"ÊÖ";s:3:"å¿’";s:2:"Ê×";s:3:"å¿‘";s:2:"ÊØ";s:3:"å¿";s:2:"ÊÙ";s:3:"å¿­";s:2:"ÊÚ";s:3:"忨";s:2:"ÊÛ";s:3:"å¿®";s:2:"ÊÜ";s:3:"忳";s:2:"ÊÝ";s:3:"å¿¡";s:2:"ÊÞ";s:3:"忤";s:2:"Êß";s:3:"å¿£";s:2:"Êà";s:3:"忺";s:2:"Êá";s:3:"忯";s:2:"Êâ";s:3:"å¿·";s:2:"Êã";s:3:"å¿»";s:2:"Êä";s:3:"怀";s:2:"Êå";s:3:"å¿´";s:2:"Êæ";s:3:"戺";s:2:"Êç";s:3:"抃";s:2:"Êè";s:3:"抌";s:2:"Êé";s:3:"抎";s:2:"Êê";s:3:"æŠ";s:2:"Êë";s:3:"抔";s:2:"Êì";s:3:"抇";s:2:"Êí";s:3:"扱";s:2:"Êî";s:3:"扻";s:2:"Êï";s:3:"扺";s:2:"Êð";s:3:"扰";s:2:"Êñ";s:3:"æŠ";s:2:"Êò";s:3:"抈";s:2:"Êó";s:3:"扷";s:2:"Êô";s:3:"扽";s:2:"Êõ";s:3:"扲";s:2:"Êö";s:3:"扴";s:2:"Ê÷";s:3:"æ”·";s:2:"Êø";s:3:"æ—°";s:2:"Êù";s:3:"æ—´";s:2:"Êú";s:3:"æ—³";s:2:"Êû";s:3:"æ—²";s:2:"Êü";s:3:"æ—µ";s:2:"Êý";s:3:"æ…";s:2:"Êþ";s:3:"æ‡";s:2:"Ë@";s:3:"æ™";s:2:"ËA";s:3:"æ•";s:2:"ËB";s:3:"æŒ";s:2:"ËC";s:3:"æˆ";s:2:"ËD";s:3:"æ";s:2:"ËE";s:3:"æ";s:2:"ËF";s:3:"æš";s:2:"ËG";s:3:"æ‹";s:2:"ËH";s:3:"æ¯";s:2:"ËI";s:3:"æ°™";s:2:"ËJ";s:3:"æ°š";s:2:"ËK";s:3:"汸";s:2:"ËL";s:3:"æ±§";s:2:"ËM";s:3:"汫";s:2:"ËN";s:3:"沄";s:2:"ËO";s:3:"沋";s:2:"ËP";s:3:"æ²";s:2:"ËQ";s:3:"æ±±";s:2:"ËR";s:3:"汯";s:2:"ËS";s:3:"汩";s:2:"ËT";s:3:"沚";s:2:"ËU";s:3:"æ±­";s:2:"ËV";s:3:"沇";s:2:"ËW";s:3:"沕";s:2:"ËX";s:3:"沜";s:2:"ËY";s:3:"汦";s:2:"ËZ";s:3:"æ±³";s:2:"Ë[";s:3:"æ±¥";s:2:"Ë\";s:3:"æ±»";s:2:"Ë]";s:3:"沎";s:2:"Ë^";s:3:"ç´";s:2:"Ë_";s:3:"çº";s:2:"Ë`";s:3:"牣";s:2:"Ëa";s:3:"犿";s:2:"Ëb";s:3:"犽";s:2:"Ëc";s:3:"狃";s:2:"Ëd";s:3:"狆";s:2:"Ëe";s:3:"ç‹";s:2:"Ëf";s:3:"犺";s:2:"Ëg";s:3:"ç‹…";s:2:"Ëh";s:3:"玕";s:2:"Ëi";s:3:"玗";s:2:"Ëj";s:3:"玓";s:2:"Ëk";s:3:"玔";s:2:"Ël";s:3:"玒";s:2:"Ëm";s:3:"町";s:2:"Ën";s:3:"甹";s:2:"Ëo";s:3:"ç–”";s:2:"Ëp";s:3:"ç–•";s:2:"Ëq";s:3:"çš";s:2:"Ër";s:3:"礽";s:2:"Ës";s:3:"耴";s:2:"Ët";s:3:"è‚•";s:2:"Ëu";s:3:"è‚™";s:2:"Ëv";s:3:"è‚";s:2:"Ëw";s:3:"è‚’";s:2:"Ëx";s:3:"肜";s:2:"Ëy";s:3:"èŠ";s:2:"Ëz";s:3:"èŠ";s:2:"Ë{";s:3:"芅";s:2:"Ë|";s:3:"芎";s:2:"Ë}";s:3:"芑";s:2:"Ë~";s:3:"芓";s:2:"Ë¡";s:3:"芊";s:2:"Ë¢";s:3:"芃";s:2:"Ë£";s:3:"芄";s:2:"ˤ";s:3:"豸";s:2:"Ë¥";s:3:"迉";s:2:"˦";s:3:"辿";s:2:"˧";s:3:"邟";s:2:"˨";s:3:"é‚¡";s:2:"Ë©";s:3:"é‚¥";s:2:"˪";s:3:"邞";s:2:"Ë«";s:3:"é‚§";s:2:"ˬ";s:3:"é‚ ";s:2:"Ë­";s:3:"阰";s:2:"Ë®";s:3:"阨";s:2:"˯";s:3:"阯";s:2:"˰";s:3:"阭";s:2:"˱";s:3:"丳";s:2:"˲";s:3:"侘";s:2:"˳";s:3:"ä½¼";s:2:"Ë´";s:3:"ä¾…";s:2:"˵";s:3:"ä½½";s:2:"˶";s:3:"ä¾€";s:2:"Ë·";s:3:"侇";s:2:"˸";s:3:"ä½¶";s:2:"˹";s:3:"ä½´";s:2:"˺";s:3:"侉";s:2:"Ë»";s:3:"侄";s:2:"˼";s:3:"ä½·";s:2:"˽";s:3:"佌";s:2:"˾";s:3:"ä¾—";s:2:"Ë¿";s:3:"佪";s:2:"ËÀ";s:3:"侚";s:2:"ËÁ";s:3:"ä½¹";s:2:"ËÂ";s:3:"ä¾";s:2:"ËÃ";s:3:"佸";s:2:"ËÄ";s:3:"ä¾";s:2:"ËÅ";s:3:"侜";s:2:"ËÆ";s:3:"ä¾”";s:2:"ËÇ";s:3:"侞";s:2:"ËÈ";s:3:"ä¾’";s:2:"ËÉ";s:3:"侂";s:2:"ËÊ";s:3:"侕";s:2:"ËË";s:3:"佫";s:2:"ËÌ";s:3:"ä½®";s:2:"ËÍ";s:3:"冞";s:2:"ËÎ";s:3:"冼";s:2:"ËÏ";s:3:"冾";s:2:"ËÐ";s:3:"刵";s:2:"ËÑ";s:3:"刲";s:2:"ËÒ";s:3:"刳";s:2:"ËÓ";s:3:"剆";s:2:"ËÔ";s:3:"刱";s:2:"ËÕ";s:3:"劼";s:2:"ËÖ";s:3:"匊";s:2:"Ë×";s:3:"匋";s:2:"ËØ";s:3:"匼";s:2:"ËÙ";s:3:"厒";s:2:"ËÚ";s:3:"厔";s:2:"ËÛ";s:3:"å’‡";s:2:"ËÜ";s:3:"å‘¿";s:2:"ËÝ";s:3:"å’";s:2:"ËÞ";s:3:"å’‘";s:2:"Ëß";s:3:"å’‚";s:2:"Ëà";s:3:"å’ˆ";s:2:"Ëá";s:3:"å‘«";s:2:"Ëâ";s:3:"呺";s:2:"Ëã";s:3:"呾";s:2:"Ëä";s:3:"å‘¥";s:2:"Ëå";s:3:"呬";s:2:"Ëæ";s:3:"å‘´";s:2:"Ëç";s:3:"呦";s:2:"Ëè";s:3:"å’";s:2:"Ëé";s:3:"呯";s:2:"Ëê";s:3:"å‘¡";s:2:"Ëë";s:3:"å‘ ";s:2:"Ëì";s:3:"å’˜";s:2:"Ëí";s:3:"å‘£";s:2:"Ëî";s:3:"å‘§";s:2:"Ëï";s:3:"呤";s:2:"Ëð";s:3:"å›·";s:2:"Ëñ";s:3:"囹";s:2:"Ëò";s:3:"å¯";s:2:"Ëó";s:3:"å²";s:2:"Ëô";s:3:"å­";s:2:"Ëõ";s:3:"å«";s:2:"Ëö";s:3:"å±";s:2:"Ë÷";s:3:"å°";s:2:"Ëø";s:3:"å¶";s:2:"Ëù";s:3:"垀";s:2:"Ëú";s:3:"åµ";s:2:"Ëû";s:3:"å»";s:2:"Ëü";s:3:"å³";s:2:"Ëý";s:3:"å´";s:2:"Ëþ";s:3:"å¢";s:2:"Ì@";s:3:"å¨";s:2:"ÌA";s:3:"å½";s:2:"ÌB";s:3:"夌";s:2:"ÌC";s:3:"奅";s:2:"ÌD";s:3:"妵";s:2:"ÌE";s:3:"妺";s:2:"ÌF";s:3:"å§";s:2:"ÌG";s:3:"å§Ž";s:2:"ÌH";s:3:"妲";s:2:"ÌI";s:3:"å§Œ";s:2:"ÌJ";s:3:"å§";s:2:"ÌK";s:3:"妶";s:2:"ÌL";s:3:"妼";s:2:"ÌM";s:3:"姃";s:2:"ÌN";s:3:"å§–";s:2:"ÌO";s:3:"妱";s:2:"ÌP";s:3:"妽";s:2:"ÌQ";s:3:"å§€";s:2:"ÌR";s:3:"姈";s:2:"ÌS";s:3:"妴";s:2:"ÌT";s:3:"姇";s:2:"ÌU";s:3:"å­¢";s:2:"ÌV";s:3:"å­¥";s:2:"ÌW";s:3:"宓";s:2:"ÌX";s:3:"宕";s:2:"ÌY";s:3:"屄";s:2:"ÌZ";s:3:"屇";s:2:"Ì[";s:3:"å²®";s:2:"Ì\";s:3:"岤";s:2:"Ì]";s:3:"å² ";s:2:"Ì^";s:3:"å²µ";s:2:"Ì_";s:3:"岯";s:2:"Ì`";s:3:"岨";s:2:"Ìa";s:3:"岬";s:2:"Ìb";s:3:"岟";s:2:"Ìc";s:3:"å²£";s:2:"Ìd";s:3:"å²­";s:2:"Ìe";s:3:"å²¢";s:2:"Ìf";s:3:"岪";s:2:"Ìg";s:3:"å²§";s:2:"Ìh";s:3:"å²";s:2:"Ìi";s:3:"å²¥";s:2:"Ìj";s:3:"å²¶";s:2:"Ìk";s:3:"å²°";s:2:"Ìl";s:3:"岦";s:2:"Ìm";s:3:"帗";s:2:"Ìn";s:3:"帔";s:2:"Ìo";s:3:"帙";s:2:"Ìp";s:3:"弨";s:2:"Ìq";s:3:"å¼¢";s:2:"Ìr";s:3:"å¼£";s:2:"Ìs";s:3:"弤";s:2:"Ìt";s:3:"å½”";s:2:"Ìu";s:3:"徂";s:2:"Ìv";s:3:"å½¾";s:2:"Ìw";s:3:"å½½";s:2:"Ìx";s:3:"忞";s:2:"Ìy";s:3:"å¿¥";s:2:"Ìz";s:3:"怭";s:2:"Ì{";s:3:"怦";s:2:"Ì|";s:3:"怙";s:2:"Ì}";s:3:"怲";s:2:"Ì~";s:3:"怋";s:2:"Ì¡";s:3:"怴";s:2:"Ì¢";s:3:"怊";s:2:"Ì£";s:3:"怗";s:2:"̤";s:3:"怳";s:2:"Ì¥";s:3:"怚";s:2:"̦";s:3:"怞";s:2:"̧";s:3:"怬";s:2:"̨";s:3:"怢";s:2:"Ì©";s:3:"æ€";s:2:"̪";s:3:"æ€";s:2:"Ì«";s:3:"怮";s:2:"̬";s:3:"怓";s:2:"Ì­";s:3:"怑";s:2:"Ì®";s:3:"怌";s:2:"̯";s:3:"怉";s:2:"̰";s:3:"怜";s:2:"̱";s:3:"戔";s:2:"̲";s:3:"戽";s:2:"̳";s:3:"抭";s:2:"Ì´";s:3:"抴";s:2:"̵";s:3:"æ‹‘";s:2:"̶";s:3:"抾";s:2:"Ì·";s:3:"抪";s:2:"̸";s:3:"抶";s:2:"̹";s:3:"拊";s:2:"̺";s:3:"抮";s:2:"Ì»";s:3:"抳";s:2:"̼";s:3:"抯";s:2:"̽";s:3:"抻";s:2:"̾";s:3:"抩";s:2:"Ì¿";s:3:"抰";s:2:"ÌÀ";s:3:"抸";s:2:"ÌÁ";s:3:"攽";s:2:"ÌÂ";s:3:"æ–¨";s:2:"ÌÃ";s:3:"æ–»";s:2:"ÌÄ";s:3:"昉";s:2:"ÌÅ";s:3:"æ—¼";s:2:"ÌÆ";s:3:"昄";s:2:"ÌÇ";s:3:"昒";s:2:"ÌÈ";s:3:"昈";s:2:"ÌÉ";s:3:"æ—»";s:2:"ÌÊ";s:3:"昃";s:2:"ÌË";s:3:"昋";s:2:"ÌÌ";s:3:"æ˜";s:2:"ÌÍ";s:3:"昅";s:2:"ÌÎ";s:3:"æ—½";s:2:"ÌÏ";s:3:"昑";s:2:"ÌÐ";s:3:"æ˜";s:2:"ÌÑ";s:3:"æ›¶";s:2:"ÌÒ";s:3:"朊";s:2:"ÌÓ";s:3:"æž…";s:2:"ÌÔ";s:3:"æ¬";s:2:"ÌÕ";s:3:"枎";s:2:"ÌÖ";s:3:"æž’";s:2:"Ì×";s:3:"æ¶";s:2:"ÌØ";s:3:"æ»";s:2:"ÌÙ";s:3:"枘";s:2:"ÌÚ";s:3:"枆";s:2:"ÌÛ";s:3:"æž„";s:2:"ÌÜ";s:3:"æ´";s:2:"ÌÝ";s:3:"æž";s:2:"ÌÞ";s:3:"枌";s:2:"Ìß";s:3:"æº";s:2:"Ìà";s:3:"枟";s:2:"Ìá";s:3:"æž‘";s:2:"Ìâ";s:3:"æž™";s:2:"Ìã";s:3:"枃";s:2:"Ìä";s:3:"æ½";s:2:"Ìå";s:3:"æž";s:2:"Ìæ";s:3:"æ¸";s:2:"Ìç";s:3:"æ¹";s:2:"Ìè";s:3:"æž”";s:2:"Ìé";s:3:"欥";s:2:"Ìê";s:3:"殀";s:2:"Ìë";s:3:"æ­¾";s:2:"Ìì";s:3:"毞";s:2:"Ìí";s:3:"æ°";s:2:"Ìî";s:3:"沓";s:2:"Ìï";s:3:"泬";s:2:"Ìð";s:3:"泫";s:2:"Ìñ";s:3:"æ³®";s:2:"Ìò";s:3:"æ³™";s:2:"Ìó";s:3:"æ²¶";s:2:"Ìô";s:3:"æ³”";s:2:"Ìõ";s:3:"æ²­";s:2:"Ìö";s:3:"æ³§";s:2:"Ì÷";s:3:"æ²·";s:2:"Ìø";s:3:"æ³";s:2:"Ìù";s:3:"泂";s:2:"Ìú";s:3:"沺";s:2:"Ìû";s:3:"泃";s:2:"Ìü";s:3:"泆";s:2:"Ìý";s:3:"æ³­";s:2:"Ìþ";s:3:"æ³²";s:2:"Í@";s:3:"æ³’";s:2:"ÍA";s:3:"æ³";s:2:"ÍB";s:3:"æ²´";s:2:"ÍC";s:3:"沊";s:2:"ÍD";s:3:"æ²";s:2:"ÍE";s:3:"æ²€";s:2:"ÍF";s:3:"泞";s:2:"ÍG";s:3:"æ³€";s:2:"ÍH";s:3:"æ´°";s:2:"ÍI";s:3:"æ³";s:2:"ÍJ";s:3:"泇";s:2:"ÍK";s:3:"æ²°";s:2:"ÍL";s:3:"æ³¹";s:2:"ÍM";s:3:"æ³";s:2:"ÍN";s:3:"泩";s:2:"ÍO";s:3:"泑";s:2:"ÍP";s:3:"ç‚”";s:2:"ÍQ";s:3:"炘";s:2:"ÍR";s:3:"ç‚…";s:2:"ÍS";s:3:"ç‚“";s:2:"ÍT";s:3:"炆";s:2:"ÍU";s:3:"ç‚„";s:2:"ÍV";s:3:"ç‚‘";s:2:"ÍW";s:3:"ç‚–";s:2:"ÍX";s:3:"ç‚‚";s:2:"ÍY";s:3:"炚";s:2:"ÍZ";s:3:"炃";s:2:"Í[";s:3:"牪";s:2:"Í\";s:3:"ç‹–";s:2:"Í]";s:3:"ç‹‹";s:2:"Í^";s:3:"狘";s:2:"Í_";s:3:"狉";s:2:"Í`";s:3:"狜";s:2:"Ía";s:3:"ç‹’";s:2:"Íb";s:3:"ç‹”";s:2:"Íc";s:3:"狚";s:2:"Íd";s:3:"狌";s:2:"Íe";s:3:"ç‹‘";s:2:"Íf";s:3:"玤";s:2:"Íg";s:3:"玡";s:2:"Íh";s:3:"玭";s:2:"Íi";s:3:"玦";s:2:"Íj";s:3:"玢";s:2:"Ík";s:3:"玠";s:2:"Íl";s:3:"玬";s:2:"Ím";s:3:"çŽ";s:2:"Ín";s:3:"ç“";s:2:"Ío";s:3:"瓨";s:2:"Íp";s:3:"甿";s:2:"Íq";s:3:"ç•€";s:2:"Ír";s:3:"甾";s:2:"Ís";s:3:"ç–Œ";s:2:"Ít";s:3:"ç–˜";s:2:"Íu";s:3:"皯";s:2:"Ív";s:3:"盳";s:2:"Íw";s:3:"ç›±";s:2:"Íx";s:3:"ç›°";s:2:"Íy";s:3:"盵";s:2:"Íz";s:3:"矸";s:2:"Í{";s:3:"矼";s:2:"Í|";s:3:"矹";s:2:"Í}";s:3:"矻";s:2:"Í~";s:3:"矺";s:2:"Í¡";s:3:"矷";s:2:"Í¢";s:3:"祂";s:2:"Í£";s:3:"礿";s:2:"ͤ";s:3:"ç§…";s:2:"Í¥";s:3:"穸";s:2:"ͦ";s:3:"ç©»";s:2:"ͧ";s:3:"ç«»";s:2:"ͨ";s:3:"ç±µ";s:2:"Í©";s:3:"ç³½";s:2:"ͪ";s:3:"耵";s:2:"Í«";s:3:"è‚";s:2:"ͬ";s:3:"è‚®";s:2:"Í­";s:3:"è‚£";s:2:"Í®";s:3:"肸";s:2:"ͯ";s:3:"肵";s:2:"Ͱ";s:3:"è‚­";s:2:"ͱ";s:3:"舠";s:2:"Ͳ";s:3:"芠";s:2:"ͳ";s:3:"è‹€";s:2:"Í´";s:3:"芫";s:2:"͵";s:3:"芚";s:2:"Ͷ";s:3:"芘";s:2:"Í·";s:3:"芛";s:2:"͸";s:3:"芵";s:2:"͹";s:3:"芧";s:2:"ͺ";s:3:"芮";s:2:"Í»";s:3:"芼";s:2:"ͼ";s:3:"芞";s:2:"ͽ";s:3:"芺";s:2:";";s:3:"芴";s:2:"Í¿";s:3:"芨";s:2:"ÍÀ";s:3:"芡";s:2:"ÍÁ";s:3:"芩";s:2:"ÍÂ";s:3:"è‹‚";s:2:"ÍÃ";s:3:"芤";s:2:"ÍÄ";s:3:"苃";s:2:"ÍÅ";s:3:"芶";s:2:"ÍÆ";s:3:"芢";s:2:"ÍÇ";s:3:"è™°";s:2:"ÍÈ";s:3:"虯";s:2:"ÍÉ";s:3:"è™­";s:2:"ÍÊ";s:3:"è™®";s:2:"ÍË";s:3:"è±–";s:2:"ÍÌ";s:3:"è¿’";s:2:"ÍÍ";s:3:"è¿‹";s:2:"ÍÎ";s:3:"è¿“";s:2:"ÍÏ";s:3:"è¿";s:2:"ÍÐ";s:3:"è¿–";s:2:"ÍÑ";s:3:"è¿•";s:2:"ÍÒ";s:3:"è¿—";s:2:"ÍÓ";s:3:"邲";s:2:"ÍÔ";s:3:"é‚´";s:2:"ÍÕ";s:3:"邯";s:2:"ÍÖ";s:3:"邳";s:2:"Í×";s:3:"é‚°";s:2:"ÍØ";s:3:"阹";s:2:"ÍÙ";s:3:"阽";s:2:"ÍÚ";s:3:"阼";s:2:"ÍÛ";s:3:"阺";s:2:"ÍÜ";s:3:"陃";s:2:"ÍÝ";s:3:"ä¿";s:2:"ÍÞ";s:3:"ä¿…";s:2:"Íß";s:3:"ä¿“";s:2:"Íà";s:3:"ä¾²";s:2:"Íá";s:3:"俉";s:2:"Íâ";s:3:"ä¿‹";s:2:"Íã";s:3:"ä¿";s:2:"Íä";s:3:"ä¿”";s:2:"Íå";s:3:"俜";s:2:"Íæ";s:3:"ä¿™";s:2:"Íç";s:3:"ä¾»";s:2:"Íè";s:3:"ä¾³";s:2:"Íé";s:3:"ä¿›";s:2:"Íê";s:3:"俇";s:2:"Íë";s:3:"ä¿–";s:2:"Íì";s:3:"侺";s:2:"Íí";s:3:"ä¿€";s:2:"Íî";s:3:"ä¾¹";s:2:"Íï";s:3:"俬";s:2:"Íð";s:3:"剄";s:2:"Íñ";s:3:"剉";s:2:"Íò";s:3:"å‹€";s:2:"Íó";s:3:"å‹‚";s:2:"Íô";s:3:"匽";s:2:"Íõ";s:3:"å¼";s:2:"Íö";s:3:"厗";s:2:"Í÷";s:3:"厖";s:2:"Íø";s:3:"厙";s:2:"Íù";s:3:"厘";s:2:"Íú";s:3:"å’º";s:2:"Íû";s:3:"å’¡";s:2:"Íü";s:3:"å’­";s:2:"Íý";s:3:"å’¥";s:2:"Íþ";s:3:"å“";s:2:"Î@";s:3:"哃";s:2:"ÎA";s:3:"èŒ";s:2:"ÎB";s:3:"å’·";s:2:"ÎC";s:3:"å’®";s:2:"ÎD";s:3:"å“–";s:2:"ÎE";s:3:"å’¶";s:2:"ÎF";s:3:"å“…";s:2:"ÎG";s:3:"哆";s:2:"ÎH";s:3:"å’ ";s:2:"ÎI";s:3:"å‘°";s:2:"ÎJ";s:3:"å’¼";s:2:"ÎK";s:3:"å’¢";s:2:"ÎL";s:3:"å’¾";s:2:"ÎM";s:3:"呲";s:2:"ÎN";s:3:"哞";s:2:"ÎO";s:3:"å’°";s:2:"ÎP";s:3:"åžµ";s:2:"ÎQ";s:3:"åžž";s:2:"ÎR";s:3:"垟";s:2:"ÎS";s:3:"垤";s:2:"ÎT";s:3:"垌";s:2:"ÎU";s:3:"åž—";s:2:"ÎV";s:3:"åž";s:2:"ÎW";s:3:"åž›";s:2:"ÎX";s:3:"åž”";s:2:"ÎY";s:3:"垘";s:2:"ÎZ";s:3:"åž";s:2:"Î[";s:3:"åž™";s:2:"Î\";s:3:"垥";s:2:"Î]";s:3:"åžš";s:2:"Î^";s:3:"åž•";s:2:"Î_";s:3:"壴";s:2:"Î`";s:3:"å¤";s:2:"Îa";s:3:"奓";s:2:"Îb";s:3:"å§¡";s:2:"Îc";s:3:"å§ž";s:2:"Îd";s:3:"å§®";s:2:"Îe";s:3:"娀";s:2:"Îf";s:3:"å§±";s:2:"Îg";s:3:"å§";s:2:"Îh";s:3:"姺";s:2:"Îi";s:3:"å§½";s:2:"Îj";s:3:"å§¼";s:2:"Îk";s:3:"å§¶";s:2:"Îl";s:3:"姤";s:2:"Îm";s:3:"å§²";s:2:"În";s:3:"å§·";s:2:"Îo";s:3:"å§›";s:2:"Îp";s:3:"å§©";s:2:"Îq";s:3:"å§³";s:2:"Îr";s:3:"å§µ";s:2:"Îs";s:3:"å§ ";s:2:"Ît";s:3:"å§¾";s:2:"Îu";s:3:"å§´";s:2:"Îv";s:3:"å§­";s:2:"Îw";s:3:"宨";s:2:"Îx";s:3:"屌";s:2:"Îy";s:3:"å³";s:2:"Îz";s:3:"峘";s:2:"Î{";s:3:"峌";s:2:"Î|";s:3:"å³—";s:2:"Î}";s:3:"峋";s:2:"Î~";s:3:"å³›";s:2:"Ρ";s:3:"峞";s:2:"΢";s:3:"峚";s:2:"Σ";s:3:"峉";s:2:"Τ";s:3:"峇";s:2:"Î¥";s:3:"峊";s:2:"Φ";s:3:"å³–";s:2:"Χ";s:3:"峓";s:2:"Ψ";s:3:"å³”";s:2:"Ω";s:3:"å³";s:2:"Ϊ";s:3:"峈";s:2:"Ϋ";s:3:"峆";s:2:"ά";s:3:"峎";s:2:"έ";s:3:"峟";s:2:"ή";s:3:"峸";s:2:"ί";s:3:"å·¹";s:2:"ΰ";s:3:"帡";s:2:"α";s:3:"帢";s:2:"β";s:3:"帣";s:2:"γ";s:3:"帠";s:2:"δ";s:3:"帤";s:2:"ε";s:3:"庰";s:2:"ζ";s:3:"庤";s:2:"η";s:3:"庢";s:2:"θ";s:3:"庛";s:2:"ι";s:3:"庣";s:2:"κ";s:3:"庥";s:2:"λ";s:3:"弇";s:2:"μ";s:3:"å¼®";s:2:"ν";s:3:"å½–";s:2:"ξ";s:3:"徆";s:2:"ο";s:3:"怷";s:2:"ÎÀ";s:3:"怹";s:2:"ÎÁ";s:3:"æ”";s:2:"ÎÂ";s:3:"æ²";s:2:"ÎÃ";s:3:"æž";s:2:"ÎÄ";s:3:"æ…";s:2:"ÎÅ";s:3:"æ“";s:2:"ÎÆ";s:3:"æ‡";s:2:"ÎÇ";s:3:"æ‰";s:2:"ÎÈ";s:3:"æ›";s:2:"ÎÉ";s:3:"æŒ";s:2:"ÎÊ";s:3:"æ€";s:2:"ÎË";s:3:"æ‚";s:2:"ÎÌ";s:3:"æŸ";s:2:"ÎÍ";s:3:"怤";s:2:"ÎÎ";s:3:"æ„";s:2:"ÎÏ";s:3:"æ˜";s:2:"ÎÐ";s:3:"æ¦";s:2:"ÎÑ";s:3:"æ®";s:2:"ÎÒ";s:3:"扂";s:2:"ÎÓ";s:3:"扃";s:2:"ÎÔ";s:3:"æ‹";s:2:"ÎÕ";s:3:"æŒ";s:2:"ÎÖ";s:3:"挋";s:2:"Î×";s:3:"拵";s:2:"ÎØ";s:3:"挎";s:2:"ÎÙ";s:3:"挃";s:2:"ÎÚ";s:3:"æ‹«";s:2:"ÎÛ";s:3:"拹";s:2:"ÎÜ";s:3:"æŒ";s:2:"ÎÝ";s:3:"挌";s:2:"ÎÞ";s:3:"拸";s:2:"Îß";s:3:"æ‹¶";s:2:"Îà";s:3:"挀";s:2:"Îá";s:3:"挓";s:2:"Îâ";s:3:"挔";s:2:"Îã";s:3:"拺";s:2:"Îä";s:3:"挕";s:2:"Îå";s:3:"æ‹»";s:2:"Îæ";s:3:"æ‹°";s:2:"Îç";s:3:"æ•";s:2:"Îè";s:3:"敃";s:2:"Îé";s:3:"æ–ª";s:2:"Îê";s:3:"æ–¿";s:2:"Îë";s:3:"昶";s:2:"Îì";s:3:"昡";s:2:"Îí";s:3:"昲";s:2:"Îî";s:3:"昵";s:2:"Îï";s:3:"昜";s:2:"Îð";s:3:"昦";s:2:"Îñ";s:3:"昢";s:2:"Îò";s:3:"昳";s:2:"Îó";s:3:"昫";s:2:"Îô";s:3:"昺";s:2:"Îõ";s:3:"æ˜";s:2:"Îö";s:3:"昴";s:2:"Î÷";s:3:"昹";s:2:"Îø";s:3:"昮";s:2:"Îù";s:3:"æœ";s:2:"Îú";s:3:"æœ";s:2:"Îû";s:3:"æŸ";s:2:"Îü";s:3:"柲";s:2:"Îý";s:3:"柈";s:2:"Îþ";s:3:"枺";s:2:"Ï@";s:3:"柜";s:2:"ÏA";s:3:"æž»";s:2:"ÏB";s:3:"柸";s:2:"ÏC";s:3:"柘";s:2:"ÏD";s:3:"柀";s:2:"ÏE";s:3:"æž·";s:2:"ÏF";s:3:"柅";s:2:"ÏG";s:3:"柫";s:2:"ÏH";s:3:"柤";s:2:"ÏI";s:3:"柟";s:2:"ÏJ";s:3:"æžµ";s:2:"ÏK";s:3:"æŸ";s:2:"ÏL";s:3:"æž³";s:2:"ÏM";s:3:"柷";s:2:"ÏN";s:3:"柶";s:2:"ÏO";s:3:"柮";s:2:"ÏP";s:3:"柣";s:2:"ÏQ";s:3:"柂";s:2:"ÏR";s:3:"æž¹";s:2:"ÏS";s:3:"柎";s:2:"ÏT";s:3:"柧";s:2:"ÏU";s:3:"柰";s:2:"ÏV";s:3:"æž²";s:2:"ÏW";s:3:"柼";s:2:"ÏX";s:3:"柆";s:2:"ÏY";s:3:"柭";s:2:"ÏZ";s:3:"柌";s:2:"Ï[";s:3:"æž®";s:2:"Ï\";s:3:"柦";s:2:"Ï]";s:3:"柛";s:2:"Ï^";s:3:"柺";s:2:"Ï_";s:3:"柉";s:2:"Ï`";s:3:"柊";s:2:"Ïa";s:3:"柃";s:2:"Ïb";s:3:"柪";s:2:"Ïc";s:3:"柋";s:2:"Ïd";s:3:"欨";s:2:"Ïe";s:3:"殂";s:2:"Ïf";s:3:"殄";s:2:"Ïg";s:3:"æ®¶";s:2:"Ïh";s:3:"毖";s:2:"Ïi";s:3:"毘";s:2:"Ïj";s:3:"毠";s:2:"Ïk";s:3:"æ° ";s:2:"Ïl";s:3:"æ°¡";s:2:"Ïm";s:3:"æ´¨";s:2:"Ïn";s:3:"æ´´";s:2:"Ïo";s:3:"æ´­";s:2:"Ïp";s:3:"æ´Ÿ";s:2:"Ïq";s:3:"æ´¼";s:2:"Ïr";s:3:"æ´¿";s:2:"Ïs";s:3:"æ´’";s:2:"Ït";s:3:"æ´Š";s:2:"Ïu";s:3:"泚";s:2:"Ïv";s:3:"æ´³";s:2:"Ïw";s:3:"æ´„";s:2:"Ïx";s:3:"æ´™";s:2:"Ïy";s:3:"æ´º";s:2:"Ïz";s:3:"æ´š";s:2:"Ï{";s:3:"æ´‘";s:2:"Ï|";s:3:"æ´€";s:2:"Ï}";s:3:"æ´";s:2:"Ï~";s:3:"浂";s:2:"Ï¡";s:3:"æ´";s:2:"Ï¢";s:3:"æ´˜";s:2:"Ï£";s:3:"æ´·";s:2:"Ϥ";s:3:"æ´ƒ";s:2:"Ï¥";s:3:"æ´";s:2:"Ϧ";s:3:"æµ€";s:2:"ϧ";s:3:"æ´‡";s:2:"Ϩ";s:3:"æ´ ";s:2:"Ï©";s:3:"æ´¬";s:2:"Ϫ";s:3:"æ´ˆ";s:2:"Ï«";s:3:"æ´¢";s:2:"Ϭ";s:3:"æ´‰";s:2:"Ï­";s:3:"æ´";s:2:"Ï®";s:3:"ç‚·";s:2:"ϯ";s:3:"炟";s:2:"ϰ";s:3:"炾";s:2:"ϱ";s:3:"炱";s:2:"ϲ";s:3:"ç‚°";s:2:"ϳ";s:3:"ç‚¡";s:2:"Ï´";s:3:"ç‚´";s:2:"ϵ";s:3:"炵";s:2:"϶";s:3:"ç‚©";s:2:"Ï·";s:3:"ç‰";s:2:"ϸ";s:3:"牉";s:2:"Ϲ";s:3:"牊";s:2:"Ϻ";s:3:"牬";s:2:"Ï»";s:3:"牰";s:2:"ϼ";s:3:"牳";s:2:"Ͻ";s:3:"牮";s:2:"Ͼ";s:3:"狊";s:2:"Ï¿";s:3:"狤";s:2:"ÏÀ";s:3:"狨";s:2:"ÏÁ";s:3:"ç‹«";s:2:"ÏÂ";s:3:"狟";s:2:"ÏÃ";s:3:"狪";s:2:"ÏÄ";s:3:"狦";s:2:"ÏÅ";s:3:"ç‹£";s:2:"ÏÆ";s:3:"玅";s:2:"ÏÇ";s:3:"çŒ";s:2:"ÏÈ";s:3:"ç‚";s:2:"ÏÉ";s:3:"çˆ";s:2:"ÏÊ";s:3:"ç…";s:2:"ÏË";s:3:"玹";s:2:"ÏÌ";s:3:"玶";s:2:"ÏÍ";s:3:"玵";s:2:"ÏÎ";s:3:"玴";s:2:"ÏÏ";s:3:"ç«";s:2:"ÏÐ";s:3:"玿";s:2:"ÏÑ";s:3:"ç‡";s:2:"ÏÒ";s:3:"玾";s:2:"ÏÓ";s:3:"çƒ";s:2:"ÏÔ";s:3:"ç†";s:2:"ÏÕ";s:3:"玸";s:2:"ÏÖ";s:3:"ç‹";s:2:"Ï×";s:3:"瓬";s:2:"ÏØ";s:3:"ç“®";s:2:"ÏÙ";s:3:"ç”®";s:2:"ÏÚ";s:3:"畇";s:2:"ÏÛ";s:3:"畈";s:2:"ÏÜ";s:3:"ç–§";s:2:"ÏÝ";s:3:"ç–ª";s:2:"ÏÞ";s:3:"癹";s:2:"Ïß";s:3:"盄";s:2:"Ïà";s:3:"眈";s:2:"Ïá";s:3:"眃";s:2:"Ïâ";s:3:"眄";s:2:"Ïã";s:3:"眅";s:2:"Ïä";s:3:"眊";s:2:"Ïå";s:3:"ç›·";s:2:"Ïæ";s:3:"ç›»";s:2:"Ïç";s:3:"盺";s:2:"Ïè";s:3:"矧";s:2:"Ïé";s:3:"矨";s:2:"Ïê";s:3:"ç †";s:2:"Ïë";s:3:"ç ‘";s:2:"Ïì";s:3:"ç ’";s:2:"Ïí";s:3:"ç …";s:2:"Ïî";s:3:"ç ";s:2:"Ïï";s:3:"ç ";s:2:"Ïð";s:3:"ç Ž";s:2:"Ïñ";s:3:"ç ‰";s:2:"Ïò";s:3:"ç ƒ";s:2:"Ïó";s:3:"ç “";s:2:"Ïô";s:3:"祊";s:2:"Ïõ";s:3:"祌";s:2:"Ïö";s:3:"祋";s:2:"Ï÷";s:3:"祅";s:2:"Ïø";s:3:"祄";s:2:"Ïù";s:3:"ç§•";s:2:"Ïú";s:3:"ç§";s:2:"Ïû";s:3:"ç§";s:2:"Ïü";s:3:"ç§–";s:2:"Ïý";s:3:"ç§Ž";s:2:"Ïþ";s:3:"窀";s:2:"Ð@";s:3:"穾";s:2:"ÐA";s:3:"ç«‘";s:2:"ÐB";s:3:"笀";s:2:"ÐC";s:3:"ç¬";s:2:"ÐD";s:3:"籺";s:2:"ÐE";s:3:"籸";s:2:"ÐF";s:3:"ç±¹";s:2:"ÐG";s:3:"籿";s:2:"ÐH";s:3:"ç²€";s:2:"ÐI";s:3:"ç²";s:2:"ÐJ";s:3:"ç´ƒ";s:2:"ÐK";s:3:"ç´ˆ";s:2:"ÐL";s:3:"ç´";s:2:"ÐM";s:3:"罘";s:2:"ÐN";s:3:"羑";s:2:"ÐO";s:3:"ç¾";s:2:"ÐP";s:3:"ç¾¾";s:2:"ÐQ";s:3:"耇";s:2:"ÐR";s:3:"耎";s:2:"ÐS";s:3:"è€";s:2:"ÐT";s:3:"耔";s:2:"ÐU";s:3:"耷";s:2:"ÐV";s:3:"胘";s:2:"ÐW";s:3:"胇";s:2:"ÐX";s:3:"胠";s:2:"ÐY";s:3:"胑";s:2:"ÐZ";s:3:"胈";s:2:"Ð[";s:3:"胂";s:2:"Ð\";s:3:"èƒ";s:2:"Ð]";s:3:"胅";s:2:"Ð^";s:3:"胣";s:2:"Ð_";s:3:"胙";s:2:"Ð`";s:3:"胜";s:2:"Ða";s:3:"胊";s:2:"Ðb";s:3:"胕";s:2:"Ðc";s:3:"胉";s:2:"Ðd";s:3:"èƒ";s:2:"Ðe";s:3:"胗";s:2:"Ðf";s:3:"胦";s:2:"Ðg";s:3:"èƒ";s:2:"Ðh";s:3:"臿";s:2:"Ði";s:3:"舡";s:2:"Ðj";s:3:"芔";s:2:"Ðk";s:3:"è‹™";s:2:"Ðl";s:3:"苾";s:2:"Ðm";s:3:"苹";s:2:"Ðn";s:3:"茇";s:2:"Ðo";s:3:"苨";s:2:"Ðp";s:3:"茀";s:2:"Ðq";s:3:"è‹•";s:2:"Ðr";s:3:"茺";s:2:"Ðs";s:3:"è‹«";s:2:"Ðt";s:3:"è‹–";s:2:"Ðu";s:3:"è‹´";s:2:"Ðv";s:3:"苬";s:2:"Ðw";s:3:"è‹¡";s:2:"Ðx";s:3:"苲";s:2:"Ðy";s:3:"苵";s:2:"Ðz";s:3:"茌";s:2:"Ð{";s:3:"è‹»";s:2:"Ð|";s:3:"è‹¶";s:2:"Ð}";s:3:"è‹°";s:2:"Ð~";s:3:"苪";s:2:"С";s:3:"苤";s:2:"Т";s:3:"è‹ ";s:2:"У";s:3:"苺";s:2:"Ф";s:3:"苳";s:2:"Ð¥";s:3:"è‹­";s:2:"Ц";s:3:"è™·";s:2:"Ч";s:3:"è™´";s:2:"Ш";s:3:"虼";s:2:"Щ";s:3:"虳";s:2:"Ъ";s:3:"è¡";s:2:"Ы";s:3:"衎";s:2:"Ь";s:3:"è¡§";s:2:"Э";s:3:"衪";s:2:"Ю";s:3:"è¡©";s:2:"Я";s:3:"è§“";s:2:"а";s:3:"訄";s:2:"б";s:3:"訇";s:2:"в";s:3:"èµ²";s:2:"г";s:3:"è¿£";s:2:"д";s:3:"è¿¡";s:2:"е";s:3:"è¿®";s:2:"ж";s:3:"è¿ ";s:2:"з";s:3:"郱";s:2:"и";s:3:"邽";s:2:"й";s:3:"é‚¿";s:2:"к";s:3:"郕";s:2:"л";s:3:"郅";s:2:"м";s:3:"邾";s:2:"н";s:3:"郇";s:2:"о";s:3:"郋";s:2:"п";s:3:"郈";s:2:"ÐÀ";s:3:"釔";s:2:"ÐÁ";s:3:"釓";s:2:"ÐÂ";s:3:"é™”";s:2:"ÐÃ";s:3:"é™";s:2:"ÐÄ";s:3:"陑";s:2:"ÐÅ";s:3:"陓";s:2:"ÐÆ";s:3:"陊";s:2:"ÐÇ";s:3:"陎";s:2:"ÐÈ";s:3:"倞";s:2:"ÐÉ";s:3:"倅";s:2:"ÐÊ";s:3:"倇";s:2:"ÐË";s:3:"倓";s:2:"ÐÌ";s:3:"倢";s:2:"ÐÍ";s:3:"倰";s:2:"ÐÎ";s:3:"倛";s:2:"ÐÏ";s:3:"俵";s:2:"ÐÐ";s:3:"ä¿´";s:2:"ÐÑ";s:3:"倳";s:2:"ÐÒ";s:3:"倷";s:2:"ÐÓ";s:3:"倬";s:2:"ÐÔ";s:3:"ä¿¶";s:2:"ÐÕ";s:3:"ä¿·";s:2:"ÐÖ";s:3:"倗";s:2:"Ð×";s:3:"倜";s:2:"ÐØ";s:3:"倠";s:2:"ÐÙ";s:3:"倧";s:2:"ÐÚ";s:3:"倵";s:2:"ÐÛ";s:3:"倯";s:2:"ÐÜ";s:3:"倱";s:2:"ÐÝ";s:3:"倎";s:2:"ÐÞ";s:3:"å…š";s:2:"Ðß";s:3:"冔";s:2:"Ðà";s:3:"冓";s:2:"Ðá";s:3:"凊";s:2:"Ðâ";s:3:"凄";s:2:"Ðã";s:3:"凅";s:2:"Ðä";s:3:"凈";s:2:"Ðå";s:3:"凎";s:2:"Ðæ";s:3:"剡";s:2:"Ðç";s:3:"剚";s:2:"Ðè";s:3:"剒";s:2:"Ðé";s:3:"剞";s:2:"Ðê";s:3:"剟";s:2:"Ðë";s:3:"剕";s:2:"Ðì";s:3:"剢";s:2:"Ðí";s:3:"å‹";s:2:"Ðî";s:3:"匎";s:2:"Ðï";s:3:"厞";s:2:"Ðð";s:3:"唦";s:2:"Ðñ";s:3:"å“¢";s:2:"Ðò";s:3:"å”—";s:2:"Ðó";s:3:"å”’";s:2:"Ðô";s:3:"å“§";s:2:"Ðõ";s:3:"哳";s:2:"Ðö";s:3:"哤";s:2:"Ð÷";s:3:"唚";s:2:"Ðø";s:3:"å“¿";s:2:"Ðù";s:3:"唄";s:2:"Ðú";s:3:"唈";s:2:"Ðû";s:3:"å“«";s:2:"Ðü";s:3:"唑";s:2:"Ðý";s:3:"å”…";s:2:"Ðþ";s:3:"哱";s:2:"Ñ@";s:3:"唊";s:2:"ÑA";s:3:"å“»";s:2:"ÑB";s:3:"å“·";s:2:"ÑC";s:3:"哸";s:2:"ÑD";s:3:"å“ ";s:2:"ÑE";s:3:"唎";s:2:"ÑF";s:3:"唃";s:2:"ÑG";s:3:"唋";s:2:"ÑH";s:3:"åœ";s:2:"ÑI";s:3:"圂";s:2:"ÑJ";s:3:"埌";s:2:"ÑK";s:3:"å ²";s:2:"ÑL";s:3:"埕";s:2:"ÑM";s:3:"埒";s:2:"ÑN";s:3:"垺";s:2:"ÑO";s:3:"埆";s:2:"ÑP";s:3:"åž½";s:2:"ÑQ";s:3:"åž¼";s:2:"ÑR";s:3:"垸";s:2:"ÑS";s:3:"åž¶";s:2:"ÑT";s:3:"åž¿";s:2:"ÑU";s:3:"埇";s:2:"ÑV";s:3:"åŸ";s:2:"ÑW";s:3:"åž¹";s:2:"ÑX";s:3:"åŸ";s:2:"ÑY";s:3:"夎";s:2:"ÑZ";s:3:"奊";s:2:"Ñ[";s:3:"娙";s:2:"Ñ\";s:3:"娖";s:2:"Ñ]";s:3:"娭";s:2:"Ñ^";s:3:"娮";s:2:"Ñ_";s:3:"娕";s:2:"Ñ`";s:3:"å¨";s:2:"Ña";s:3:"娗";s:2:"Ñb";s:3:"娊";s:2:"Ñc";s:3:"娞";s:2:"Ñd";s:3:"娳";s:2:"Ñe";s:3:"å­¬";s:2:"Ñf";s:3:"å®§";s:2:"Ñg";s:3:"å®­";s:2:"Ñh";s:3:"宬";s:2:"Ñi";s:3:"å°ƒ";s:2:"Ñj";s:3:"å±–";s:2:"Ñk";s:3:"å±”";s:2:"Ñl";s:3:"峬";s:2:"Ñm";s:3:"峿";s:2:"Ñn";s:3:"å³®";s:2:"Ño";s:3:"å³±";s:2:"Ñp";s:3:"å³·";s:2:"Ñq";s:3:"å´€";s:2:"Ñr";s:3:"å³¹";s:2:"Ñs";s:3:"帩";s:2:"Ñt";s:3:"帨";s:2:"Ñu";s:3:"庨";s:2:"Ñv";s:3:"庮";s:2:"Ñw";s:3:"庪";s:2:"Ñx";s:3:"庬";s:2:"Ñy";s:3:"å¼³";s:2:"Ñz";s:3:"å¼°";s:2:"Ñ{";s:3:"å½§";s:2:"Ñ|";s:3:"æ";s:2:"Ñ}";s:3:"æš";s:2:"Ñ~";s:3:"æ§";s:2:"Ñ¡";s:3:"æ";s:2:"Ñ¢";s:3:"æ‚¢";s:2:"Ñ£";s:3:"悈";s:2:"Ѥ";s:3:"æ‚€";s:2:"Ñ¥";s:3:"æ‚’";s:2:"Ѧ";s:3:"æ‚";s:2:"ѧ";s:3:"æ‚";s:2:"Ѩ";s:3:"悃";s:2:"Ñ©";s:3:"æ‚•";s:2:"Ѫ";s:3:"æ‚›";s:2:"Ñ«";s:3:"æ‚—";s:2:"Ѭ";s:3:"悇";s:2:"Ñ­";s:3:"悜";s:2:"Ñ®";s:3:"悎";s:2:"ѯ";s:3:"戙";s:2:"Ѱ";s:3:"扆";s:2:"ѱ";s:3:"拲";s:2:"Ѳ";s:3:"æŒ";s:2:"ѳ";s:3:"æ–";s:2:"Ñ´";s:3:"挬";s:2:"ѵ";s:3:"æ„";s:2:"Ѷ";s:3:"æ…";s:2:"Ñ·";s:3:"挶";s:2:"Ѹ";s:3:"æƒ";s:2:"ѹ";s:3:"æ¤";s:2:"Ѻ";s:3:"挹";s:2:"Ñ»";s:3:"æ‹";s:2:"Ѽ";s:3:"æŠ";s:2:"ѽ";s:3:"挼";s:2:"Ѿ";s:3:"挩";s:2:"Ñ¿";s:3:"æ";s:2:"ÑÀ";s:3:"挴";s:2:"ÑÁ";s:3:"æ˜";s:2:"ÑÂ";s:3:"æ”";s:2:"ÑÃ";s:3:"æ™";s:2:"ÑÄ";s:3:"挭";s:2:"ÑÅ";s:3:"æ‡";s:2:"ÑÆ";s:3:"挳";s:2:"ÑÇ";s:3:"æš";s:2:"ÑÈ";s:3:"æ‘";s:2:"ÑÉ";s:3:"挸";s:2:"ÑÊ";s:3:"æ—";s:2:"ÑË";s:3:"æ€";s:2:"ÑÌ";s:3:"æˆ";s:2:"ÑÍ";s:3:"敊";s:2:"ÑÎ";s:3:"敆";s:2:"ÑÏ";s:3:"æ—†";s:2:"ÑÐ";s:3:"æ—ƒ";s:2:"ÑÑ";s:3:"æ—„";s:2:"ÑÒ";s:3:"æ—‚";s:2:"ÑÓ";s:3:"晊";s:2:"ÑÔ";s:3:"晟";s:2:"ÑÕ";s:3:"晇";s:2:"ÑÖ";s:3:"晑";s:2:"Ñ×";s:3:"朒";s:2:"ÑØ";s:3:"朓";s:2:"ÑÙ";s:3:"æ Ÿ";s:2:"ÑÚ";s:3:"æ š";s:2:"ÑÛ";s:3:"桉";s:2:"ÑÜ";s:3:"æ ²";s:2:"ÑÝ";s:3:"æ ³";s:2:"ÑÞ";s:3:"æ »";s:2:"Ñß";s:3:"æ¡‹";s:2:"Ñà";s:3:"æ¡";s:2:"Ñá";s:3:"æ –";s:2:"Ñâ";s:3:"æ ±";s:2:"Ñã";s:3:"æ œ";s:2:"Ñä";s:3:"æ µ";s:2:"Ñå";s:3:"æ «";s:2:"Ñæ";s:3:"æ ­";s:2:"Ñç";s:3:"æ ¯";s:2:"Ñè";s:3:"桎";s:2:"Ñé";s:3:"æ¡„";s:2:"Ñê";s:3:"æ ´";s:2:"Ñë";s:3:"æ ";s:2:"Ñì";s:3:"æ ’";s:2:"Ñí";s:3:"æ ”";s:2:"Ñî";s:3:"æ ¦";s:2:"Ñï";s:3:"æ ¨";s:2:"Ñð";s:3:"æ ®";s:2:"Ññ";s:3:"æ¡";s:2:"Ñò";s:3:"æ º";s:2:"Ñó";s:3:"æ ¥";s:2:"Ñô";s:3:"æ  ";s:2:"Ñõ";s:3:"欬";s:2:"Ñö";s:3:"欯";s:2:"Ñ÷";s:3:"欭";s:2:"Ñø";s:3:"欱";s:2:"Ñù";s:3:"欴";s:2:"Ñú";s:3:"æ­­";s:2:"Ñû";s:3:"è‚‚";s:2:"Ñü";s:3:"殈";s:2:"Ñý";s:3:"毦";s:2:"Ñþ";s:3:"毤";s:2:"Ò@";s:3:"毨";s:2:"ÒA";s:3:"毣";s:2:"ÒB";s:3:"毢";s:2:"ÒC";s:3:"毧";s:2:"ÒD";s:3:"æ°¥";s:2:"ÒE";s:3:"浺";s:2:"ÒF";s:3:"æµ£";s:2:"ÒG";s:3:"浤";s:2:"ÒH";s:3:"æµ¶";s:2:"ÒI";s:3:"æ´";s:2:"ÒJ";s:3:"浡";s:2:"ÒK";s:3:"æ¶’";s:2:"ÒL";s:3:"浘";s:2:"ÒM";s:3:"æµ¢";s:2:"ÒN";s:3:"æµ­";s:2:"ÒO";s:3:"浯";s:2:"ÒP";s:3:"æ¶‘";s:2:"ÒQ";s:3:"æ¶";s:2:"ÒR";s:3:"æ·¯";s:2:"ÒS";s:3:"浿";s:2:"ÒT";s:3:"涆";s:2:"ÒU";s:3:"浞";s:2:"ÒV";s:3:"æµ§";s:2:"ÒW";s:3:"æµ ";s:2:"ÒX";s:3:"æ¶—";s:2:"ÒY";s:3:"æµ°";s:2:"ÒZ";s:3:"æµ¼";s:2:"Ò[";s:3:"浟";s:2:"Ò\";s:3:"æ¶‚";s:2:"Ò]";s:3:"涘";s:2:"Ò^";s:3:"æ´¯";s:2:"Ò_";s:3:"浨";s:2:"Ò`";s:3:"æ¶‹";s:2:"Òa";s:3:"æµ¾";s:2:"Òb";s:3:"æ¶€";s:2:"Òc";s:3:"æ¶„";s:2:"Òd";s:3:"æ´–";s:2:"Òe";s:3:"涃";s:2:"Òf";s:3:"æµ»";s:2:"Òg";s:3:"æµ½";s:2:"Òh";s:3:"æµµ";s:2:"Òi";s:3:"æ¶";s:2:"Òj";s:3:"烜";s:2:"Òk";s:3:"烓";s:2:"Òl";s:3:"烑";s:2:"Òm";s:3:"çƒ";s:2:"Òn";s:3:"烋";s:2:"Òo";s:3:"ç¼¹";s:2:"Òp";s:3:"烢";s:2:"Òq";s:3:"烗";s:2:"Òr";s:3:"烒";s:2:"Òs";s:3:"烞";s:2:"Òt";s:3:"烠";s:2:"Òu";s:3:"烔";s:2:"Òv";s:3:"çƒ";s:2:"Òw";s:3:"烅";s:2:"Òx";s:3:"烆";s:2:"Òy";s:3:"烇";s:2:"Òz";s:3:"烚";s:2:"Ò{";s:3:"烎";s:2:"Ò|";s:3:"烡";s:2:"Ò}";s:3:"牂";s:2:"Ò~";s:3:"牸";s:2:"Ò¡";s:3:"牷";s:2:"Ò¢";s:3:"牶";s:2:"Ò£";s:3:"猀";s:2:"Ò¤";s:3:"狺";s:2:"Ò¥";s:3:"ç‹´";s:2:"Ò¦";s:3:"狾";s:2:"Ò§";s:3:"ç‹¶";s:2:"Ò¨";s:3:"狳";s:2:"Ò©";s:3:"ç‹»";s:2:"Òª";s:3:"çŒ";s:2:"Ò«";s:3:"ç“";s:2:"Ò¬";s:3:"ç™";s:2:"Ò­";s:3:"ç¥";s:2:"Ò®";s:3:"ç–";s:2:"Ò¯";s:3:"玼";s:2:"Ò°";s:3:"ç§";s:2:"Ò±";s:3:"ç£";s:2:"Ò²";s:3:"ç©";s:2:"Ò³";s:3:"çœ";s:2:"Ò´";s:3:"ç’";s:2:"Òµ";s:3:"ç›";s:2:"Ò¶";s:3:"ç”";s:2:"Ò·";s:3:"ç";s:2:"Ò¸";s:3:"çš";s:2:"Ò¹";s:3:"ç—";s:2:"Òº";s:3:"ç˜";s:2:"Ò»";s:3:"ç¨";s:2:"Ò¼";s:3:"瓞";s:2:"Ò½";s:3:"瓟";s:2:"Ò¾";s:3:"ç“´";s:2:"Ò¿";s:3:"瓵";s:2:"ÒÀ";s:3:"甡";s:2:"ÒÁ";s:3:"ç•›";s:2:"ÒÂ";s:3:"畟";s:2:"ÒÃ";s:3:"ç–°";s:2:"ÒÄ";s:3:"ç—";s:2:"ÒÅ";s:3:"ç–»";s:2:"ÒÆ";s:3:"ç—„";s:2:"ÒÇ";s:3:"ç—€";s:2:"ÒÈ";s:3:"ç–¿";s:2:"ÒÉ";s:3:"ç–¶";s:2:"ÒÊ";s:3:"ç–º";s:2:"ÒË";s:3:"皊";s:2:"ÒÌ";s:3:"盉";s:2:"ÒÍ";s:3:"çœ";s:2:"ÒÎ";s:3:"眛";s:2:"ÒÏ";s:3:"çœ";s:2:"ÒÐ";s:3:"眓";s:2:"ÒÑ";s:3:"眒";s:2:"ÒÒ";s:3:"眣";s:2:"ÒÓ";s:3:"眑";s:2:"ÒÔ";s:3:"眕";s:2:"ÒÕ";s:3:"眙";s:2:"ÒÖ";s:3:"眚";s:2:"Ò×";s:3:"眢";s:2:"ÒØ";s:3:"眧";s:2:"ÒÙ";s:3:"ç £";s:2:"ÒÚ";s:3:"ç ¬";s:2:"ÒÛ";s:3:"ç ¢";s:2:"ÒÜ";s:3:"ç µ";s:2:"ÒÝ";s:3:"ç ¯";s:2:"ÒÞ";s:3:"ç ¨";s:2:"Òß";s:3:"ç ®";s:2:"Òà";s:3:"ç «";s:2:"Òá";s:3:"ç ¡";s:2:"Òâ";s:3:"ç ©";s:2:"Òã";s:3:"ç ³";s:2:"Òä";s:3:"ç ª";s:2:"Òå";s:3:"ç ±";s:2:"Òæ";s:3:"祔";s:2:"Òç";s:3:"祛";s:2:"Òè";s:3:"ç¥";s:2:"Òé";s:3:"祜";s:2:"Òê";s:3:"祓";s:2:"Òë";s:3:"祒";s:2:"Òì";s:3:"祑";s:2:"Òí";s:3:"ç§«";s:2:"Òî";s:3:"秬";s:2:"Òï";s:3:"ç§ ";s:2:"Òð";s:3:"ç§®";s:2:"Òñ";s:3:"ç§­";s:2:"Òò";s:3:"秪";s:2:"Òó";s:3:"ç§œ";s:2:"Òô";s:3:"ç§ž";s:2:"Òõ";s:3:"ç§";s:2:"Òö";s:3:"窆";s:2:"Ò÷";s:3:"窉";s:2:"Òø";s:3:"窅";s:2:"Òù";s:3:"窋";s:2:"Òú";s:3:"窌";s:2:"Òû";s:3:"窊";s:2:"Òü";s:3:"窇";s:2:"Òý";s:3:"竘";s:2:"Òþ";s:3:"ç¬";s:2:"Ó@";s:3:"笄";s:2:"ÓA";s:3:"笓";s:2:"ÓB";s:3:"笅";s:2:"ÓC";s:3:"ç¬";s:2:"ÓD";s:3:"笈";s:2:"ÓE";s:3:"笊";s:2:"ÓF";s:3:"笎";s:2:"ÓG";s:3:"笉";s:2:"ÓH";s:3:"笒";s:2:"ÓI";s:3:"粄";s:2:"ÓJ";s:3:"粑";s:2:"ÓK";s:3:"粊";s:2:"ÓL";s:3:"粌";s:2:"ÓM";s:3:"粈";s:2:"ÓN";s:3:"ç²";s:2:"ÓO";s:3:"ç²…";s:2:"ÓP";s:3:"ç´ž";s:2:"ÓQ";s:3:"ç´";s:2:"ÓR";s:3:"ç´‘";s:2:"ÓS";s:3:"ç´Ž";s:2:"ÓT";s:3:"ç´˜";s:2:"ÓU";s:3:"ç´–";s:2:"ÓV";s:3:"ç´“";s:2:"ÓW";s:3:"ç´Ÿ";s:2:"ÓX";s:3:"ç´’";s:2:"ÓY";s:3:"ç´";s:2:"ÓZ";s:3:"ç´Œ";s:2:"Ó[";s:3:"罜";s:2:"Ó\";s:3:"罡";s:2:"Ó]";s:3:"罞";s:2:"Ó^";s:3:"ç½ ";s:2:"Ó_";s:3:"ç½";s:2:"Ó`";s:3:"ç½›";s:2:"Óa";s:3:"ç¾–";s:2:"Ób";s:3:"ç¾’";s:2:"Óc";s:3:"翃";s:2:"Ód";s:3:"ç¿‚";s:2:"Óe";s:3:"ç¿€";s:2:"Óf";s:3:"耖";s:2:"Óg";s:3:"耾";s:2:"Óh";s:3:"耹";s:2:"Ói";s:3:"胺";s:2:"Ój";s:3:"胲";s:2:"Ók";s:3:"胹";s:2:"Ól";s:3:"胵";s:2:"Óm";s:3:"è„";s:2:"Ón";s:3:"胻";s:2:"Óo";s:3:"è„€";s:2:"Óp";s:3:"èˆ";s:2:"Óq";s:3:"舯";s:2:"Ór";s:3:"舥";s:2:"Ós";s:3:"茳";s:2:"Ót";s:3:"茭";s:2:"Óu";s:3:"è„";s:2:"Óv";s:3:"茙";s:2:"Ów";s:3:"è‘";s:2:"Óx";s:3:"茥";s:2:"Óy";s:3:"è–";s:2:"Óz";s:3:"茿";s:2:"Ó{";s:3:"è";s:2:"Ó|";s:3:"茦";s:2:"Ó}";s:3:"茜";s:2:"Ó~";s:3:"茢";s:2:"Ó¡";s:3:"è‚";s:2:"Ó¢";s:3:"èŽ";s:2:"Ó£";s:3:"茛";s:2:"Ó¤";s:3:"茪";s:2:"Ó¥";s:3:"茈";s:2:"Ó¦";s:3:"茼";s:2:"Ó§";s:3:"è";s:2:"Ó¨";s:3:"茖";s:2:"Ó©";s:3:"茤";s:2:"Óª";s:3:"茠";s:2:"Ó«";s:3:"茷";s:2:"Ó¬";s:3:"茯";s:2:"Ó­";s:3:"茩";s:2:"Ó®";s:3:"è‡";s:2:"Ó¯";s:3:"è…";s:2:"Ó°";s:3:"èŒ";s:2:"Ó±";s:3:"è“";s:2:"Ó²";s:3:"茞";s:2:"Ó³";s:3:"茬";s:2:"Ó´";s:3:"è‹";s:2:"Óµ";s:3:"茧";s:2:"Ó¶";s:3:"èˆ";s:2:"Ó·";s:3:"虓";s:2:"Ó¸";s:3:"è™’";s:2:"Ó¹";s:3:"蚢";s:2:"Óº";s:3:"蚨";s:2:"Ó»";s:3:"èš–";s:2:"Ó¼";s:3:"èš";s:2:"Ó½";s:3:"èš‘";s:2:"Ó¾";s:3:"èšž";s:2:"Ó¿";s:3:"蚇";s:2:"ÓÀ";s:3:"èš—";s:2:"ÓÁ";s:3:"蚆";s:2:"ÓÂ";s:3:"èš‹";s:2:"ÓÃ";s:3:"èšš";s:2:"ÓÄ";s:3:"èš…";s:2:"ÓÅ";s:3:"蚥";s:2:"ÓÆ";s:3:"èš™";s:2:"ÓÇ";s:3:"èš¡";s:2:"ÓÈ";s:3:"èš§";s:2:"ÓÉ";s:3:"èš•";s:2:"ÓÊ";s:3:"蚘";s:2:"ÓË";s:3:"蚎";s:2:"ÓÌ";s:3:"èš";s:2:"ÓÍ";s:3:"èš";s:2:"ÓÎ";s:3:"èš”";s:2:"ÓÏ";s:3:"衃";s:2:"ÓÐ";s:3:"è¡„";s:2:"ÓÑ";s:3:"è¡­";s:2:"ÓÒ";s:3:"衵";s:2:"ÓÓ";s:3:"è¡¶";s:2:"ÓÔ";s:3:"衲";s:2:"ÓÕ";s:3:"袀";s:2:"ÓÖ";s:3:"衱";s:2:"Ó×";s:3:"è¡¿";s:2:"ÓØ";s:3:"衯";s:2:"ÓÙ";s:3:"袃";s:2:"ÓÚ";s:3:"衾";s:2:"ÓÛ";s:3:"è¡´";s:2:"ÓÜ";s:3:"衼";s:2:"ÓÝ";s:3:"訒";s:2:"ÓÞ";s:3:"豇";s:2:"Óß";s:3:"è±—";s:2:"Óà";s:3:"è±»";s:2:"Óá";s:3:"貤";s:2:"Óâ";s:3:"è²£";s:2:"Óã";s:3:"èµ¶";s:2:"Óä";s:3:"赸";s:2:"Óå";s:3:"è¶µ";s:2:"Óæ";s:3:"è¶·";s:2:"Óç";s:3:"è¶¶";s:2:"Óè";s:3:"軑";s:2:"Óé";s:3:"軓";s:2:"Óê";s:3:"迾";s:2:"Óë";s:3:"迵";s:2:"Óì";s:3:"适";s:2:"Óí";s:3:"è¿¿";s:2:"Óî";s:3:"è¿»";s:2:"Óï";s:3:"逄";s:2:"Óð";s:3:"迼";s:2:"Óñ";s:3:"è¿¶";s:2:"Óò";s:3:"郖";s:2:"Óó";s:3:"郠";s:2:"Óô";s:3:"郙";s:2:"Óõ";s:3:"郚";s:2:"Óö";s:3:"郣";s:2:"Ó÷";s:3:"郟";s:2:"Óø";s:3:"郥";s:2:"Óù";s:3:"郘";s:2:"Óú";s:3:"郛";s:2:"Óû";s:3:"郗";s:2:"Óü";s:3:"郜";s:2:"Óý";s:3:"郤";s:2:"Óþ";s:3:"é…";s:2:"Ô@";s:3:"é…Ž";s:2:"ÔA";s:3:"é…";s:2:"ÔB";s:3:"釕";s:2:"ÔC";s:3:"釢";s:2:"ÔD";s:3:"釚";s:2:"ÔE";s:3:"陜";s:2:"ÔF";s:3:"陟";s:2:"ÔG";s:3:"éš¼";s:2:"ÔH";s:3:"飣";s:2:"ÔI";s:3:"髟";s:2:"ÔJ";s:3:"鬯";s:2:"ÔK";s:3:"乿";s:2:"ÔL";s:3:"å°";s:2:"ÔM";s:3:"åª";s:2:"ÔN";s:3:"å¡";s:2:"ÔO";s:3:"åž";s:2:"ÔP";s:3:"å ";s:2:"ÔQ";s:3:"å“";s:2:"ÔR";s:3:"å‹";s:2:"ÔS";s:3:"å";s:2:"ÔT";s:3:"å²";s:2:"ÔU";s:3:"åˆ";s:2:"ÔV";s:3:"å";s:2:"ÔW";s:3:"å";s:2:"ÔX";s:3:"å›";s:2:"ÔY";s:3:"åŠ";s:2:"ÔZ";s:3:"å¢";s:2:"Ô[";s:3:"倕";s:2:"Ô\";s:3:"å…";s:2:"Ô]";s:3:"åŸ";s:2:"Ô^";s:3:"å©";s:2:"Ô_";s:3:"å«";s:2:"Ô`";s:3:"å£";s:2:"Ôa";s:3:"å¤";s:2:"Ôb";s:3:"å†";s:2:"Ôc";s:3:"å€";s:2:"Ôd";s:3:"å®";s:2:"Ôe";s:3:"å³";s:2:"Ôf";s:3:"å—";s:2:"Ôg";s:3:"å‘";s:2:"Ôh";s:3:"å‡";s:2:"Ôi";s:3:"剫";s:2:"Ôj";s:3:"剭";s:2:"Ôk";s:3:"剬";s:2:"Ôl";s:3:"剮";s:2:"Ôm";s:3:"å‹–";s:2:"Ôn";s:3:"å‹“";s:2:"Ôo";s:3:"匭";s:2:"Ôp";s:3:"厜";s:2:"Ôq";s:3:"啵";s:2:"Ôr";s:3:"å•¶";s:2:"Ôs";s:3:"唼";s:2:"Ôt";s:3:"å•";s:2:"Ôu";s:3:"å•";s:2:"Ôv";s:3:"å”´";s:2:"Ôw";s:3:"唪";s:2:"Ôx";s:3:"å•‘";s:2:"Ôy";s:3:"å•¢";s:2:"Ôz";s:3:"å”¶";s:2:"Ô{";s:3:"唵";s:2:"Ô|";s:3:"å”°";s:2:"Ô}";s:3:"å•’";s:2:"Ô~";s:3:"å•…";s:2:"Ô¡";s:3:"唌";s:2:"Ô¢";s:3:"唲";s:2:"Ô£";s:3:"å•¥";s:2:"Ô¤";s:3:"啎";s:2:"Ô¥";s:3:"唹";s:2:"Ô¦";s:3:"啈";s:2:"Ô§";s:3:"å”­";s:2:"Ô¨";s:3:"å”»";s:2:"Ô©";s:3:"å•€";s:2:"Ôª";s:3:"å•‹";s:2:"Ô«";s:3:"圊";s:2:"Ô¬";s:3:"圇";s:2:"Ô­";s:3:"埻";s:2:"Ô®";s:3:"å ”";s:2:"Ô¯";s:3:"埢";s:2:"Ô°";s:3:"埶";s:2:"Ô±";s:3:"埜";s:2:"Ô²";s:3:"埴";s:2:"Ô³";s:3:"å €";s:2:"Ô´";s:3:"埭";s:2:"Ôµ";s:3:"埽";s:2:"Ô¶";s:3:"å ˆ";s:2:"Ô·";s:3:"埸";s:2:"Ô¸";s:3:"å ‹";s:2:"Ô¹";s:3:"埳";s:2:"Ôº";s:3:"åŸ";s:2:"Ô»";s:3:"å ‡";s:2:"Ô¼";s:3:"埮";s:2:"Ô½";s:3:"埣";s:2:"Ô¾";s:3:"埲";s:2:"Ô¿";s:3:"埥";s:2:"ÔÀ";s:3:"埬";s:2:"ÔÁ";s:3:"埡";s:2:"ÔÂ";s:3:"å Ž";s:2:"ÔÃ";s:3:"埼";s:2:"ÔÄ";s:3:"å ";s:2:"ÔÅ";s:3:"埧";s:2:"ÔÆ";s:3:"å ";s:2:"ÔÇ";s:3:"å Œ";s:2:"ÔÈ";s:3:"埱";s:2:"ÔÉ";s:3:"埩";s:2:"ÔÊ";s:3:"埰";s:2:"ÔË";s:3:"å ";s:2:"ÔÌ";s:3:"å „";s:2:"ÔÍ";s:3:"奜";s:2:"ÔÎ";s:3:"å© ";s:2:"ÔÏ";s:3:"婘";s:2:"ÔÐ";s:3:"å©•";s:2:"ÔÑ";s:3:"å©§";s:2:"ÔÒ";s:3:"婞";s:2:"ÔÓ";s:3:"娸";s:2:"ÔÔ";s:3:"娵";s:2:"ÔÕ";s:3:"å©­";s:2:"ÔÖ";s:3:"å©";s:2:"Ô×";s:3:"婟";s:2:"ÔØ";s:3:"å©¥";s:2:"ÔÙ";s:3:"婬";s:2:"ÔÚ";s:3:"å©“";s:2:"ÔÛ";s:3:"婤";s:2:"ÔÜ";s:3:"å©—";s:2:"ÔÝ";s:3:"婃";s:2:"ÔÞ";s:3:"å©";s:2:"Ôß";s:3:"å©’";s:2:"Ôà";s:3:"å©„";s:2:"Ôá";s:3:"å©›";s:2:"Ôâ";s:3:"婈";s:2:"Ôã";s:3:"媎";s:2:"Ôä";s:3:"娾";s:2:"Ôå";s:3:"å©";s:2:"Ôæ";s:3:"娹";s:2:"Ôç";s:3:"婌";s:2:"Ôè";s:3:"å©°";s:2:"Ôé";s:3:"å©©";s:2:"Ôê";s:3:"婇";s:2:"Ôë";s:3:"å©‘";s:2:"Ôì";s:3:"å©–";s:2:"Ôí";s:3:"å©‚";s:2:"Ôî";s:3:"婜";s:2:"Ôï";s:3:"å­²";s:2:"Ôð";s:3:"å­®";s:2:"Ôñ";s:3:"å¯";s:2:"Ôò";s:3:"寀";s:2:"Ôó";s:3:"å±™";s:2:"Ôô";s:3:"å´ž";s:2:"Ôõ";s:3:"å´‹";s:2:"Ôö";s:3:"å´";s:2:"Ô÷";s:3:"å´š";s:2:"Ôø";s:3:"å´ ";s:2:"Ôù";s:3:"å´Œ";s:2:"Ôú";s:3:"å´¨";s:2:"Ôû";s:3:"å´";s:2:"Ôü";s:3:"å´¦";s:2:"Ôý";s:3:"å´¥";s:2:"Ôþ";s:3:"å´";s:2:"Õ@";s:3:"å´°";s:2:"ÕA";s:3:"å´’";s:2:"ÕB";s:3:"å´£";s:2:"ÕC";s:3:"å´Ÿ";s:2:"ÕD";s:3:"å´®";s:2:"ÕE";s:3:"帾";s:2:"ÕF";s:3:"帴";s:2:"ÕG";s:3:"庱";s:2:"ÕH";s:3:"庴";s:2:"ÕI";s:3:"庹";s:2:"ÕJ";s:3:"庲";s:2:"ÕK";s:3:"庳";s:2:"ÕL";s:3:"å¼¶";s:2:"ÕM";s:3:"弸";s:2:"ÕN";s:3:"å¾›";s:2:"ÕO";s:3:"å¾–";s:2:"ÕP";s:3:"徟";s:2:"ÕQ";s:3:"悊";s:2:"ÕR";s:3:"æ‚";s:2:"ÕS";s:3:"悆";s:2:"ÕT";s:3:"悾";s:2:"ÕU";s:3:"æ‚°";s:2:"ÕV";s:3:"悺";s:2:"ÕW";s:3:"惓";s:2:"ÕX";s:3:"惔";s:2:"ÕY";s:3:"æƒ";s:2:"ÕZ";s:3:"惤";s:2:"Õ[";s:3:"惙";s:2:"Õ\";s:3:"æƒ";s:2:"Õ]";s:3:"惈";s:2:"Õ^";s:3:"悱";s:2:"Õ_";s:3:"惛";s:2:"Õ`";s:3:"æ‚·";s:2:"Õa";s:3:"惊";s:2:"Õb";s:3:"æ‚¿";s:2:"Õc";s:3:"惃";s:2:"Õd";s:3:"æƒ";s:2:"Õe";s:3:"惀";s:2:"Õf";s:3:"挲";s:2:"Õg";s:3:"æ¥";s:2:"Õh";s:3:"掊";s:2:"Õi";s:3:"掂";s:2:"Õj";s:3:"æ½";s:2:"Õk";s:3:"掽";s:2:"Õl";s:3:"掞";s:2:"Õm";s:3:"掭";s:2:"Õn";s:3:"æŽ";s:2:"Õo";s:3:"掗";s:2:"Õp";s:3:"掫";s:2:"Õq";s:3:"掎";s:2:"Õr";s:3:"æ¯";s:2:"Õs";s:3:"掇";s:2:"Õt";s:3:"æŽ";s:2:"Õu";s:3:"æ®";s:2:"Õv";s:3:"掯";s:2:"Õw";s:3:"æµ";s:2:"Õx";s:3:"掜";s:2:"Õy";s:3:"æ­";s:2:"Õz";s:3:"掮";s:2:"Õ{";s:3:"æ¼";s:2:"Õ|";s:3:"掤";s:2:"Õ}";s:3:"挻";s:2:"Õ~";s:3:"掟";s:2:"Õ¡";s:3:"æ¸";s:2:"Õ¢";s:3:"掅";s:2:"Õ£";s:3:"æŽ";s:2:"Õ¤";s:3:"掑";s:2:"Õ¥";s:3:"æŽ";s:2:"Õ¦";s:3:"æ°";s:2:"Õ§";s:3:"æ•“";s:2:"Õ¨";s:3:"æ—";s:2:"Õ©";s:3:"晥";s:2:"Õª";s:3:"晡";s:2:"Õ«";s:3:"æ™›";s:2:"Õ¬";s:3:"æ™™";s:2:"Õ­";s:3:"晜";s:2:"Õ®";s:3:"晢";s:2:"Õ¯";s:3:"朘";s:2:"Õ°";s:3:"桹";s:2:"Õ±";s:3:"梇";s:2:"Õ²";s:3:"æ¢";s:2:"Õ³";s:3:"梜";s:2:"Õ´";s:3:"æ¡­";s:2:"Õµ";s:3:"æ¡®";s:2:"Õ¶";s:3:"梮";s:2:"Õ·";s:3:"梫";s:2:"Õ¸";s:3:"楖";s:2:"Õ¹";s:3:"桯";s:2:"Õº";s:3:"梣";s:2:"Õ»";s:3:"梬";s:2:"Õ¼";s:3:"梩";s:2:"Õ½";s:3:"桵";s:2:"Õ¾";s:3:"æ¡´";s:2:"Õ¿";s:3:"梲";s:2:"ÕÀ";s:3:"æ¢";s:2:"ÕÁ";s:3:"æ¡·";s:2:"ÕÂ";s:3:"梒";s:2:"ÕÃ";s:3:"桼";s:2:"ÕÄ";s:3:"æ¡«";s:2:"ÕÅ";s:3:"桲";s:2:"ÕÆ";s:3:"梪";s:2:"ÕÇ";s:3:"梀";s:2:"ÕÈ";s:3:"桱";s:2:"ÕÉ";s:3:"桾";s:2:"ÕÊ";s:3:"梛";s:2:"ÕË";s:3:"梖";s:2:"ÕÌ";s:3:"梋";s:2:"ÕÍ";s:3:"梠";s:2:"ÕÎ";s:3:"梉";s:2:"ÕÏ";s:3:"梤";s:2:"ÕÐ";s:3:"桸";s:2:"ÕÑ";s:3:"æ¡»";s:2:"ÕÒ";s:3:"梑";s:2:"ÕÓ";s:3:"梌";s:2:"ÕÔ";s:3:"梊";s:2:"ÕÕ";s:3:"桽";s:2:"ÕÖ";s:3:"欶";s:2:"Õ×";s:3:"欳";s:2:"ÕØ";s:3:"欷";s:2:"ÕÙ";s:3:"欸";s:2:"ÕÚ";s:3:"殑";s:2:"ÕÛ";s:3:"æ®";s:2:"ÕÜ";s:3:"æ®";s:2:"ÕÝ";s:3:"殎";s:2:"ÕÞ";s:3:"殌";s:2:"Õß";s:3:"æ°ª";s:2:"Õà";s:3:"æ·€";s:2:"Õá";s:3:"æ¶«";s:2:"Õâ";s:3:"æ¶´";s:2:"Õã";s:3:"æ¶³";s:2:"Õä";s:3:"æ¹´";s:2:"Õå";s:3:"涬";s:2:"Õæ";s:3:"æ·©";s:2:"Õç";s:3:"æ·¢";s:2:"Õè";s:3:"æ¶·";s:2:"Õé";s:3:"æ·¶";s:2:"Õê";s:3:"æ·”";s:2:"Õë";s:3:"渀";s:2:"Õì";s:3:"æ·ˆ";s:2:"Õí";s:3:"æ· ";s:2:"Õî";s:3:"æ·Ÿ";s:2:"Õï";s:3:"æ·–";s:2:"Õð";s:3:"æ¶¾";s:2:"Õñ";s:3:"æ·¥";s:2:"Õò";s:3:"æ·œ";s:2:"Õó";s:3:"æ·";s:2:"Õô";s:3:"æ·›";s:2:"Õõ";s:3:"æ·´";s:2:"Õö";s:3:"æ·Š";s:2:"Õ÷";s:3:"æ¶½";s:2:"Õø";s:3:"æ·­";s:2:"Õù";s:3:"æ·°";s:2:"Õú";s:3:"涺";s:2:"Õû";s:3:"æ·•";s:2:"Õü";s:3:"æ·‚";s:2:"Õý";s:3:"æ·";s:2:"Õþ";s:3:"æ·‰";s:2:"Ö@";s:3:"æ·";s:2:"ÖA";s:3:"æ·²";s:2:"ÖB";s:3:"æ·“";s:2:"ÖC";s:3:"æ·½";s:2:"ÖD";s:3:"æ·—";s:2:"ÖE";s:3:"æ·";s:2:"ÖF";s:3:"æ·£";s:2:"ÖG";s:3:"æ¶»";s:2:"ÖH";s:3:"烺";s:2:"ÖI";s:3:"ç„";s:2:"ÖJ";s:3:"烷";s:2:"ÖK";s:3:"ç„—";s:2:"ÖL";s:3:"烴";s:2:"ÖM";s:3:"焌";s:2:"ÖN";s:3:"烰";s:2:"ÖO";s:3:"ç„„";s:2:"ÖP";s:3:"烳";s:2:"ÖQ";s:3:"ç„";s:2:"ÖR";s:3:"烼";s:2:"ÖS";s:3:"烿";s:2:"ÖT";s:3:"焆";s:2:"ÖU";s:3:"ç„“";s:2:"ÖV";s:3:"ç„€";s:2:"ÖW";s:3:"烸";s:2:"ÖX";s:3:"烶";s:2:"ÖY";s:3:"ç„‹";s:2:"ÖZ";s:3:"ç„‚";s:2:"Ö[";s:3:"焎";s:2:"Ö\";s:3:"牾";s:2:"Ö]";s:3:"牻";s:2:"Ö^";s:3:"牼";s:2:"Ö_";s:3:"牿";s:2:"Ö`";s:3:"çŒ";s:2:"Öa";s:3:"猗";s:2:"Öb";s:3:"猇";s:2:"Öc";s:3:"猑";s:2:"Öd";s:3:"猘";s:2:"Öe";s:3:"猊";s:2:"Öf";s:3:"猈";s:2:"Ög";s:3:"ç‹¿";s:2:"Öh";s:3:"çŒ";s:2:"Öi";s:3:"猞";s:2:"Öj";s:3:"玈";s:2:"Ök";s:3:"ç¶";s:2:"Öl";s:3:"ç¸";s:2:"Öm";s:3:"çµ";s:2:"Ön";s:3:"ç„";s:2:"Öo";s:3:"ç";s:2:"Öp";s:3:"ç½";s:2:"Öq";s:3:"ç‡";s:2:"Ör";s:3:"ç€";s:2:"Ös";s:3:"çº";s:2:"Öt";s:3:"ç¼";s:2:"Öu";s:3:"ç¿";s:2:"Öv";s:3:"çŒ";s:2:"Öw";s:3:"ç‹";s:2:"Öx";s:3:"ç´";s:2:"Öy";s:3:"çˆ";s:2:"Öz";s:3:"畤";s:2:"Ö{";s:3:"ç•£";s:2:"Ö|";s:3:"ç—Ž";s:2:"Ö}";s:3:"ç—’";s:2:"Ö~";s:3:"ç—";s:2:"Ö¡";s:3:"ç—‹";s:2:"Ö¢";s:3:"ç—Œ";s:2:"Ö£";s:3:"ç—‘";s:2:"Ö¤";s:3:"ç—";s:2:"Ö¥";s:3:"çš";s:2:"Ö¦";s:3:"皉";s:2:"Ö§";s:3:"盓";s:2:"Ö¨";s:3:"眹";s:2:"Ö©";s:3:"眯";s:2:"Öª";s:3:"眭";s:2:"Ö«";s:3:"眱";s:2:"Ö¬";s:3:"眲";s:2:"Ö­";s:3:"眴";s:2:"Ö®";s:3:"眳";s:2:"Ö¯";s:3:"眽";s:2:"Ö°";s:3:"眥";s:2:"Ö±";s:3:"眻";s:2:"Ö²";s:3:"眵";s:2:"Ö³";s:3:"硈";s:2:"Ö´";s:3:"ç¡’";s:2:"Öµ";s:3:"硉";s:2:"Ö¶";s:3:"ç¡";s:2:"Ö·";s:3:"硊";s:2:"Ö¸";s:3:"硌";s:2:"Ö¹";s:3:"ç ¦";s:2:"Öº";s:3:"ç¡…";s:2:"Ö»";s:3:"ç¡";s:2:"Ö¼";s:3:"祤";s:2:"Ö½";s:3:"祧";s:2:"Ö¾";s:3:"祩";s:2:"Ö¿";s:3:"祪";s:2:"ÖÀ";s:3:"祣";s:2:"ÖÁ";s:3:"祫";s:2:"ÖÂ";s:3:"祡";s:2:"ÖÃ";s:3:"离";s:2:"ÖÄ";s:3:"秺";s:2:"ÖÅ";s:3:"秸";s:2:"ÖÆ";s:3:"ç§¶";s:2:"ÖÇ";s:3:"ç§·";s:2:"ÖÈ";s:3:"çª";s:2:"ÖÉ";s:3:"窔";s:2:"ÖÊ";s:3:"çª";s:2:"ÖË";s:3:"笵";s:2:"ÖÌ";s:3:"ç­‡";s:2:"ÖÍ";s:3:"笴";s:2:"ÖÎ";s:3:"笥";s:2:"ÖÏ";s:3:"笰";s:2:"ÖÐ";s:3:"笢";s:2:"ÖÑ";s:3:"笤";s:2:"ÖÒ";s:3:"笳";s:2:"ÖÓ";s:3:"笘";s:2:"ÖÔ";s:3:"笪";s:2:"ÖÕ";s:3:"ç¬";s:2:"ÖÖ";s:3:"笱";s:2:"Ö×";s:3:"笫";s:2:"ÖØ";s:3:"笭";s:2:"ÖÙ";s:3:"笯";s:2:"ÖÚ";s:3:"笲";s:2:"ÖÛ";s:3:"笸";s:2:"ÖÜ";s:3:"笚";s:2:"ÖÝ";s:3:"笣";s:2:"ÖÞ";s:3:"ç²”";s:2:"Öß";s:3:"粘";s:2:"Öà";s:3:"ç²–";s:2:"Öá";s:3:"ç²£";s:2:"Öâ";s:3:"ç´µ";s:2:"Öã";s:3:"ç´½";s:2:"Öä";s:3:"ç´¸";s:2:"Öå";s:3:"ç´¶";s:2:"Öæ";s:3:"ç´º";s:2:"Öç";s:3:"çµ…";s:2:"Öè";s:3:"ç´¬";s:2:"Öé";s:3:"ç´©";s:2:"Öê";s:3:"çµ";s:2:"Öë";s:3:"絇";s:2:"Öì";s:3:"ç´¾";s:2:"Öí";s:3:"ç´¿";s:2:"Öî";s:3:"絊";s:2:"Öï";s:3:"ç´»";s:2:"Öð";s:3:"ç´¨";s:2:"Öñ";s:3:"ç½£";s:2:"Öò";s:3:"羕";s:2:"Öó";s:3:"羜";s:2:"Öô";s:3:"ç¾";s:2:"Öõ";s:3:"ç¾›";s:2:"Öö";s:3:"翊";s:2:"Ö÷";s:3:"ç¿‹";s:2:"Öø";s:3:"ç¿";s:2:"Öù";s:3:"ç¿";s:2:"Öú";s:3:"ç¿‘";s:2:"Öû";s:3:"翇";s:2:"Öü";s:3:"ç¿";s:2:"Öý";s:3:"翉";s:2:"Öþ";s:3:"耟";s:2:"×@";s:3:"耞";s:2:"×A";s:3:"耛";s:2:"×B";s:3:"è‡";s:2:"×C";s:3:"èƒ";s:2:"×D";s:3:"èˆ";s:2:"×E";s:3:"脘";s:2:"×F";s:3:"è„¥";s:2:"×G";s:3:"è„™";s:2:"×H";s:3:"è„›";s:2:"×I";s:3:"è„­";s:2:"×J";s:3:"脟";s:2:"×K";s:3:"脬";s:2:"×L";s:3:"脞";s:2:"×M";s:3:"è„¡";s:2:"×N";s:3:"è„•";s:2:"×O";s:3:"è„§";s:2:"×P";s:3:"è„";s:2:"×Q";s:3:"è„¢";s:2:"×R";s:3:"舑";s:2:"×S";s:3:"舸";s:2:"×T";s:3:"舳";s:2:"×U";s:3:"舺";s:2:"×V";s:3:"舴";s:2:"×W";s:3:"舲";s:2:"×X";s:3:"艴";s:2:"×Y";s:3:"èŽ";s:2:"×Z";s:3:"莣";s:2:"×[";s:3:"莨";s:2:"×\";s:3:"èŽ";s:2:"×]";s:3:"èº";s:2:"×^";s:3:"è³";s:2:"×_";s:3:"莤";s:2:"×`";s:3:"è´";s:2:"×a";s:3:"èŽ";s:2:"×b";s:3:"èŽ";s:2:"×c";s:3:"莕";s:2:"×d";s:3:"莙";s:2:"×e";s:3:"èµ";s:2:"×f";s:3:"莔";s:2:"×g";s:3:"莩";s:2:"×h";s:3:"è½";s:2:"×i";s:3:"莃";s:2:"×j";s:3:"莌";s:2:"×k";s:3:"èŽ";s:2:"×l";s:3:"莛";s:2:"×m";s:3:"莪";s:2:"×n";s:3:"莋";s:2:"×o";s:3:"è¾";s:2:"×p";s:3:"莥";s:2:"×q";s:3:"莯";s:2:"×r";s:3:"莈";s:2:"×s";s:3:"莗";s:2:"×t";s:3:"莰";s:2:"×u";s:3:"è¿";s:2:"×v";s:3:"莦";s:2:"×w";s:3:"莇";s:2:"×x";s:3:"莮";s:2:"×y";s:3:"è¶";s:2:"×z";s:3:"莚";s:2:"×{";s:3:"è™™";s:2:"×|";s:3:"è™–";s:2:"×}";s:3:"èš¿";s:2:"×~";s:3:"èš·";s:2:"ס";s:3:"蛂";s:2:"×¢";s:3:"è›";s:2:"×£";s:3:"è›…";s:2:"פ";s:3:"蚺";s:2:"×¥";s:3:"èš°";s:2:"צ";s:3:"蛈";s:2:"×§";s:3:"èš¹";s:2:"ר";s:3:"èš³";s:2:"ש";s:3:"蚸";s:2:"ת";s:3:"蛌";s:2:"׫";s:3:"èš´";s:2:"׬";s:3:"èš»";s:2:"×­";s:3:"èš¼";s:2:"×®";s:3:"蛃";s:2:"ׯ";s:3:"èš½";s:2:"×°";s:3:"èš¾";s:2:"×±";s:3:"è¡’";s:2:"ײ";s:3:"袉";s:2:"׳";s:3:"袕";s:2:"×´";s:3:"袨";s:2:"×µ";s:3:"袢";s:2:"×¶";s:3:"袪";s:2:"×·";s:3:"袚";s:2:"׸";s:3:"袑";s:2:"×¹";s:3:"袡";s:2:"׺";s:3:"袟";s:2:"×»";s:3:"袘";s:2:"×¼";s:3:"袧";s:2:"×½";s:3:"袙";s:2:"×¾";s:3:"袛";s:2:"׿";s:3:"袗";s:2:"×À";s:3:"袤";s:2:"×Á";s:3:"袬";s:2:"×Â";s:3:"袌";s:2:"×Ã";s:3:"袓";s:2:"×Ä";s:3:"袎";s:2:"×Å";s:3:"覂";s:2:"ׯ";s:3:"è§–";s:2:"×Ç";s:3:"è§™";s:2:"×È";s:3:"è§•";s:2:"×É";s:3:"訰";s:2:"×Ê";s:3:"訧";s:2:"×Ë";s:3:"訬";s:2:"×Ì";s:3:"訞";s:2:"×Í";s:3:"è°¹";s:2:"×Î";s:3:"è°»";s:2:"×Ï";s:3:"豜";s:2:"×Ð";s:3:"è±";s:2:"×Ñ";s:3:"è±½";s:2:"×Ò";s:3:"è²¥";s:2:"×Ó";s:3:"èµ½";s:2:"×Ô";s:3:"èµ»";s:2:"×Õ";s:3:"èµ¹";s:2:"×Ö";s:3:"è¶¼";s:2:"××";s:3:"è·‚";s:2:"ר";s:3:"è¶¹";s:2:"×Ù";s:3:"è¶¿";s:2:"×Ú";s:3:"è·";s:2:"×Û";s:3:"軘";s:2:"×Ü";s:3:"軞";s:2:"×Ý";s:3:"è»";s:2:"×Þ";s:3:"軜";s:2:"×ß";s:3:"è»—";s:2:"×à";s:3:"è» ";s:2:"×á";s:3:"軡";s:2:"×â";s:3:"逤";s:2:"×ã";s:3:"逋";s:2:"×ä";s:3:"逑";s:2:"×å";s:3:"逜";s:2:"׿";s:3:"逌";s:2:"×ç";s:3:"逡";s:2:"×è";s:3:"郯";s:2:"×é";s:3:"郪";s:2:"×ê";s:3:"郰";s:2:"×ë";s:3:"郴";s:2:"×ì";s:3:"郲";s:2:"×í";s:3:"郳";s:2:"×î";s:3:"郔";s:2:"×ï";s:3:"郫";s:2:"×ð";s:3:"郬";s:2:"×ñ";s:3:"郩";s:2:"×ò";s:3:"é…–";s:2:"×ó";s:3:"é…˜";s:2:"×ô";s:3:"é…š";s:2:"×õ";s:3:"é…“";s:2:"×ö";s:3:"é…•";s:2:"×÷";s:3:"釬";s:2:"×ø";s:3:"釴";s:2:"×ù";s:3:"釱";s:2:"×ú";s:3:"釳";s:2:"×û";s:3:"釸";s:2:"×ü";s:3:"釤";s:2:"×ý";s:3:"釹";s:2:"×þ";s:3:"釪";s:2:"Ø@";s:3:"釫";s:2:"ØA";s:3:"釷";s:2:"ØB";s:3:"釨";s:2:"ØC";s:3:"釮";s:2:"ØD";s:3:"镺";s:2:"ØE";s:3:"é–†";s:2:"ØF";s:3:"é–ˆ";s:2:"ØG";s:3:"陼";s:2:"ØH";s:3:"é™­";s:2:"ØI";s:3:"陫";s:2:"ØJ";s:3:"é™±";s:2:"ØK";s:3:"陯";s:2:"ØL";s:3:"éš¿";s:2:"ØM";s:3:"éª";s:2:"ØN";s:3:"é „";s:2:"ØO";s:3:"飥";s:2:"ØP";s:3:"馗";s:2:"ØQ";s:3:"å‚›";s:2:"ØR";s:3:"å‚•";s:2:"ØS";s:3:"å‚”";s:2:"ØT";s:3:"傞";s:2:"ØU";s:3:"å‚‹";s:2:"ØV";s:3:"å‚£";s:2:"ØW";s:3:"傃";s:2:"ØX";s:3:"傌";s:2:"ØY";s:3:"傎";s:2:"ØZ";s:3:"å‚";s:2:"Ø[";s:3:"å¨";s:2:"Ø\";s:3:"傜";s:2:"Ø]";s:3:"å‚’";s:2:"Ø^";s:3:"å‚‚";s:2:"Ø_";s:3:"傇";s:2:"Ø`";s:3:"å…Ÿ";s:2:"Øa";s:3:"凔";s:2:"Øb";s:3:"匒";s:2:"Øc";s:3:"匑";s:2:"Ød";s:3:"厤";s:2:"Øe";s:3:"厧";s:2:"Øf";s:3:"å–‘";s:2:"Øg";s:3:"å–¨";s:2:"Øh";s:3:"å–¥";s:2:"Øi";s:3:"å–­";s:2:"Øj";s:3:"å•·";s:2:"Øk";s:3:"å™…";s:2:"Øl";s:3:"å–¢";s:2:"Øm";s:3:"å–“";s:2:"Øn";s:3:"å–ˆ";s:2:"Øo";s:3:"å–";s:2:"Øp";s:3:"å–µ";s:2:"Øq";s:3:"å–";s:2:"Ør";s:3:"å–£";s:2:"Øs";s:3:"å–’";s:2:"Øt";s:3:"å–¤";s:2:"Øu";s:3:"啽";s:2:"Øv";s:3:"å–Œ";s:2:"Øw";s:3:"å–¦";s:2:"Øx";s:3:"å•¿";s:2:"Øy";s:3:"å–•";s:2:"Øz";s:3:"å–¡";s:2:"Ø{";s:3:"å–Ž";s:2:"Ø|";s:3:"圌";s:2:"Ø}";s:3:"å ©";s:2:"Ø~";s:3:"å ·";s:2:"Ø¡";s:3:"å ™";s:2:"Ø¢";s:3:"å ž";s:2:"Ø£";s:3:"å §";s:2:"ؤ";s:3:"å £";s:2:"Ø¥";s:3:"å ¨";s:2:"ئ";s:3:"埵";s:2:"ا";s:3:"塈";s:2:"ب";s:3:"å ¥";s:2:"Ø©";s:3:"å œ";s:2:"ت";s:3:"å ›";s:2:"Ø«";s:3:"å ³";s:2:"ج";s:3:"å ¿";s:2:"Ø­";s:3:"å ¶";s:2:"Ø®";s:3:"å ®";s:2:"د";s:3:"å ¹";s:2:"ذ";s:3:"å ¸";s:2:"ر";s:3:"å ­";s:2:"ز";s:3:"å ¬";s:2:"س";s:3:"å »";s:2:"Ø´";s:3:"奡";s:2:"ص";s:3:"媯";s:2:"ض";s:3:"媔";s:2:"Ø·";s:3:"媟";s:2:"ظ";s:3:"婺";s:2:"ع";s:3:"媢";s:2:"غ";s:3:"媞";s:2:"Ø»";s:3:"婸";s:2:"ؼ";s:3:"媦";s:2:"ؽ";s:3:"婼";s:2:"ؾ";s:3:"媥";s:2:"Ø¿";s:3:"媬";s:2:"ØÀ";s:3:"媕";s:2:"ØÁ";s:3:"媮";s:2:"ØÂ";s:3:"娷";s:2:"ØÃ";s:3:"媄";s:2:"ØÄ";s:3:"媊";s:2:"ØÅ";s:3:"媗";s:2:"ØÆ";s:3:"媃";s:2:"ØÇ";s:3:"媋";s:2:"ØÈ";s:3:"媩";s:2:"ØÉ";s:3:"å©»";s:2:"ØÊ";s:3:"婽";s:2:"ØË";s:3:"媌";s:2:"ØÌ";s:3:"媜";s:2:"ØÍ";s:3:"åª";s:2:"ØÎ";s:3:"媓";s:2:"ØÏ";s:3:"åª";s:2:"ØÐ";s:3:"寪";s:2:"ØÑ";s:3:"å¯";s:2:"ØÒ";s:3:"寋";s:2:"ØÓ";s:3:"寔";s:2:"ØÔ";s:3:"寑";s:2:"ØÕ";s:3:"寊";s:2:"ØÖ";s:3:"寎";s:2:"Ø×";s:3:"å°Œ";s:2:"ØØ";s:3:"å°°";s:2:"ØÙ";s:3:"å´·";s:2:"ØÚ";s:3:"嵃";s:2:"ØÛ";s:3:"嵫";s:2:"ØÜ";s:3:"åµ";s:2:"ØÝ";s:3:"嵋";s:2:"ØÞ";s:3:"å´¿";s:2:"Øß";s:3:"å´µ";s:2:"Øà";s:3:"嵑";s:2:"Øá";s:3:"嵎";s:2:"Øâ";s:3:"嵕";s:2:"Øã";s:3:"å´³";s:2:"Øä";s:3:"å´º";s:2:"Øå";s:3:"åµ’";s:2:"Øæ";s:3:"å´½";s:2:"Øç";s:3:"å´±";s:2:"Øè";s:3:"åµ™";s:2:"Øé";s:3:"嵂";s:2:"Øê";s:3:"å´¹";s:2:"Øë";s:3:"嵉";s:2:"Øì";s:3:"å´¸";s:2:"Øí";s:3:"å´¼";s:2:"Øî";s:3:"å´²";s:2:"Øï";s:3:"å´¶";s:2:"Øð";s:3:"åµ€";s:2:"Øñ";s:3:"åµ…";s:2:"Øò";s:3:"幄";s:2:"Øó";s:3:"å¹";s:2:"Øô";s:3:"彘";s:2:"Øõ";s:3:"徦";s:2:"Øö";s:3:"å¾¥";s:2:"Ø÷";s:3:"徫";s:2:"Øø";s:3:"惉";s:2:"Øù";s:3:"悹";s:2:"Øú";s:3:"惌";s:2:"Øû";s:3:"惢";s:2:"Øü";s:3:"惎";s:2:"Øý";s:3:"惄";s:2:"Øþ";s:3:"æ„”";s:2:"Ù@";s:3:"惲";s:2:"ÙA";s:3:"愊";s:2:"ÙB";s:3:"æ„–";s:2:"ÙC";s:3:"æ„…";s:2:"ÙD";s:3:"惵";s:2:"ÙE";s:3:"æ„“";s:2:"ÙF";s:3:"惸";s:2:"ÙG";s:3:"惼";s:2:"ÙH";s:3:"惾";s:2:"ÙI";s:3:"æƒ";s:2:"ÙJ";s:3:"愃";s:2:"ÙK";s:3:"愘";s:2:"ÙL";s:3:"æ„";s:2:"ÙM";s:3:"æ„";s:2:"ÙN";s:3:"惿";s:2:"ÙO";s:3:"æ„„";s:2:"ÙP";s:3:"æ„‹";s:2:"ÙQ";s:3:"扊";s:2:"ÙR";s:3:"掔";s:2:"ÙS";s:3:"掱";s:2:"ÙT";s:3:"掰";s:2:"ÙU";s:3:"æŽ";s:2:"ÙV";s:3:"æ¥";s:2:"ÙW";s:3:"æ¨";s:2:"ÙX";s:3:"æ¯";s:2:"ÙY";s:3:"æƒ";s:2:"ÙZ";s:3:"æ’";s:2:"Ù[";s:3:"æ³";s:2:"Ù\";s:3:"æŠ";s:2:"Ù]";s:3:"æ ";s:2:"Ù^";s:3:"æ¶";s:2:"Ù_";s:3:"æ•";s:2:"Ù`";s:3:"æ²";s:2:"Ùa";s:3:"æµ";s:2:"Ùb";s:3:"æ‘¡";s:2:"Ùc";s:3:"æŸ";s:2:"Ùd";s:3:"掾";s:2:"Ùe";s:3:"æ";s:2:"Ùf";s:3:"æœ";s:2:"Ùg";s:3:"æ„";s:2:"Ùh";s:3:"æ˜";s:2:"Ùi";s:3:"æ“";s:2:"Ùj";s:3:"æ‚";s:2:"Ùk";s:3:"æ‡";s:2:"Ùl";s:3:"æŒ";s:2:"Ùm";s:3:"æ‹";s:2:"Ùn";s:3:"æˆ";s:2:"Ùo";s:3:"æ°";s:2:"Ùp";s:3:"æ—";s:2:"Ùq";s:3:"æ™";s:2:"Ùr";s:3:"攲";s:2:"Ùs";s:3:"æ•§";s:2:"Ùt";s:3:"敪";s:2:"Ùu";s:3:"敤";s:2:"Ùv";s:3:"敜";s:2:"Ùw";s:3:"敨";s:2:"Ùx";s:3:"æ•¥";s:2:"Ùy";s:3:"æ–Œ";s:2:"Ùz";s:3:"æ–";s:2:"Ù{";s:3:"æ–ž";s:2:"Ù|";s:3:"æ–®";s:2:"Ù}";s:3:"æ—";s:2:"Ù~";s:3:"æ—’";s:2:"Ù¡";s:3:"晼";s:2:"Ù¢";s:3:"晬";s:2:"Ù£";s:3:"æ™»";s:2:"Ù¤";s:3:"暀";s:2:"Ù¥";s:3:"æ™±";s:2:"Ù¦";s:3:"晹";s:2:"Ù§";s:3:"晪";s:2:"Ù¨";s:3:"晲";s:2:"Ù©";s:3:"æœ";s:2:"Ùª";s:3:"椌";s:2:"Ù«";s:3:"棓";s:2:"Ù¬";s:3:"椄";s:2:"Ù­";s:3:"棜";s:2:"Ù®";s:3:"椪";s:2:"Ù¯";s:3:"棬";s:2:"Ù°";s:3:"棪";s:2:"Ù±";s:3:"棱";s:2:"Ù²";s:3:"æ¤";s:2:"Ù³";s:3:"棖";s:2:"Ù´";s:3:"棷";s:2:"Ùµ";s:3:"棫";s:2:"Ù¶";s:3:"棤";s:2:"Ù·";s:3:"棶";s:2:"Ù¸";s:3:"椓";s:2:"Ù¹";s:3:"æ¤";s:2:"Ùº";s:3:"棳";s:2:"Ù»";s:3:"棡";s:2:"Ù¼";s:3:"椇";s:2:"Ù½";s:3:"棌";s:2:"Ù¾";s:3:"椈";s:2:"Ù¿";s:3:"楰";s:2:"ÙÀ";s:3:"梴";s:2:"ÙÁ";s:3:"椑";s:2:"ÙÂ";s:3:"棯";s:2:"ÙÃ";s:3:"棆";s:2:"ÙÄ";s:3:"椔";s:2:"ÙÅ";s:3:"棸";s:2:"ÙÆ";s:3:"æ£";s:2:"ÙÇ";s:3:"棽";s:2:"ÙÈ";s:3:"棼";s:2:"ÙÉ";s:3:"棨";s:2:"ÙÊ";s:3:"椋";s:2:"ÙË";s:3:"椊";s:2:"ÙÌ";s:3:"椗";s:2:"ÙÍ";s:3:"棎";s:2:"ÙÎ";s:3:"棈";s:2:"ÙÏ";s:3:"æ£";s:2:"ÙÐ";s:3:"棞";s:2:"ÙÑ";s:3:"棦";s:2:"ÙÒ";s:3:"棴";s:2:"ÙÓ";s:3:"棑";s:2:"ÙÔ";s:3:"椆";s:2:"ÙÕ";s:3:"棔";s:2:"ÙÖ";s:3:"棩";s:2:"Ù×";s:3:"椕";s:2:"ÙØ";s:3:"椥";s:2:"ÙÙ";s:3:"棇";s:2:"ÙÚ";s:3:"欹";s:2:"ÙÛ";s:3:"欻";s:2:"ÙÜ";s:3:"欿";s:2:"ÙÝ";s:3:"欼";s:2:"ÙÞ";s:3:"æ®”";s:2:"Ùß";s:3:"æ®—";s:2:"Ùà";s:3:"æ®™";s:2:"Ùá";s:3:"殕";s:2:"Ùâ";s:3:"殽";s:2:"Ùã";s:3:"毰";s:2:"Ùä";s:3:"毲";s:2:"Ùå";s:3:"毳";s:2:"Ùæ";s:3:"æ°°";s:2:"Ùç";s:3:"æ·¼";s:2:"Ùè";s:3:"湆";s:2:"Ùé";s:3:"湇";s:2:"Ùê";s:3:"渟";s:2:"Ùë";s:3:"湉";s:2:"Ùì";s:3:"溈";s:2:"Ùí";s:3:"渼";s:2:"Ùî";s:3:"渽";s:2:"Ùï";s:3:"æ¹…";s:2:"Ùð";s:3:"æ¹¢";s:2:"Ùñ";s:3:"渫";s:2:"Ùò";s:3:"渿";s:2:"Ùó";s:3:"æ¹";s:2:"Ùô";s:3:"æ¹";s:2:"Ùõ";s:3:"æ¹³";s:2:"Ùö";s:3:"渜";s:2:"Ù÷";s:3:"渳";s:2:"Ùø";s:3:"湋";s:2:"Ùù";s:3:"æ¹€";s:2:"Ùú";s:3:"湑";s:2:"Ùû";s:3:"渻";s:2:"Ùü";s:3:"渃";s:2:"Ùý";s:3:"渮";s:2:"Ùþ";s:3:"湞";s:2:"Ú@";s:3:"湨";s:2:"ÚA";s:3:"湜";s:2:"ÚB";s:3:"湡";s:2:"ÚC";s:3:"渱";s:2:"ÚD";s:3:"渨";s:2:"ÚE";s:3:"æ¹ ";s:2:"ÚF";s:3:"æ¹±";s:2:"ÚG";s:3:"湫";s:2:"ÚH";s:3:"渹";s:2:"ÚI";s:3:"渢";s:2:"ÚJ";s:3:"渰";s:2:"ÚK";s:3:"湓";s:2:"ÚL";s:3:"æ¹¥";s:2:"ÚM";s:3:"渧";s:2:"ÚN";s:3:"湸";s:2:"ÚO";s:3:"湤";s:2:"ÚP";s:3:"æ¹·";s:2:"ÚQ";s:3:"湕";s:2:"ÚR";s:3:"æ¹¹";s:2:"ÚS";s:3:"æ¹’";s:2:"ÚT";s:3:"湦";s:2:"ÚU";s:3:"渵";s:2:"ÚV";s:3:"渶";s:2:"ÚW";s:3:"湚";s:2:"ÚX";s:3:"ç„ ";s:2:"ÚY";s:3:"焞";s:2:"ÚZ";s:3:"焯";s:2:"Ú[";s:3:"烻";s:2:"Ú\";s:3:"ç„®";s:2:"Ú]";s:3:"焱";s:2:"Ú^";s:3:"ç„£";s:2:"Ú_";s:3:"ç„¥";s:2:"Ú`";s:3:"ç„¢";s:2:"Úa";s:3:"焲";s:2:"Úb";s:3:"焟";s:2:"Úc";s:3:"焨";s:2:"Úd";s:3:"焺";s:2:"Úe";s:3:"ç„›";s:2:"Úf";s:3:"牋";s:2:"Úg";s:3:"牚";s:2:"Úh";s:3:"犈";s:2:"Úi";s:3:"犉";s:2:"Új";s:3:"犆";s:2:"Úk";s:3:"犅";s:2:"Úl";s:3:"犋";s:2:"Úm";s:3:"猒";s:2:"Ún";s:3:"猋";s:2:"Úo";s:3:"猰";s:2:"Úp";s:3:"猢";s:2:"Úq";s:3:"猱";s:2:"Úr";s:3:"猳";s:2:"Ús";s:3:"猧";s:2:"Út";s:3:"猲";s:2:"Úu";s:3:"猭";s:2:"Úv";s:3:"猦";s:2:"Úw";s:3:"猣";s:2:"Úx";s:3:"猵";s:2:"Úy";s:3:"猌";s:2:"Úz";s:3:"ç®";s:2:"Ú{";s:3:"ç¬";s:2:"Ú|";s:3:"ç°";s:2:"Ú}";s:3:"ç«";s:2:"Ú~";s:3:"ç–";s:2:"Ú¡";s:3:"çš";s:2:"Ú¢";s:3:"ç¡";s:2:"Ú£";s:3:"ç­";s:2:"Ú¤";s:3:"ç±";s:2:"Ú¥";s:3:"ç¤";s:2:"Ú¦";s:3:"ç£";s:2:"Ú§";s:3:"ç";s:2:"Ú¨";s:3:"ç©";s:2:"Ú©";s:3:"ç ";s:2:"Úª";s:3:"ç²";s:2:"Ú«";s:3:"ç“»";s:2:"Ú¬";s:3:"甯";s:2:"Ú­";s:3:"畯";s:2:"Ú®";s:3:"畬";s:2:"Ú¯";s:3:"ç—§";s:2:"Ú°";s:3:"ç—š";s:2:"Ú±";s:3:"ç—¡";s:2:"Ú²";s:3:"ç—¦";s:2:"Ú³";s:3:"ç—";s:2:"Ú´";s:3:"ç—Ÿ";s:2:"Úµ";s:3:"ç—¤";s:2:"Ú¶";s:3:"ç——";s:2:"Ú·";s:3:"çš•";s:2:"Ú¸";s:3:"çš’";s:2:"Ú¹";s:3:"盚";s:2:"Úº";s:3:"ç†";s:2:"Ú»";s:3:"ç‡";s:2:"Ú¼";s:3:"ç„";s:2:"Ú½";s:3:"ç";s:2:"Ú¾";s:3:"ç…";s:2:"Ú¿";s:3:"çŠ";s:2:"ÚÀ";s:3:"çŽ";s:2:"ÚÁ";s:3:"ç‹";s:2:"ÚÂ";s:3:"çŒ";s:2:"ÚÃ";s:3:"矞";s:2:"ÚÄ";s:3:"矬";s:2:"ÚÅ";s:3:"ç¡ ";s:2:"ÚÆ";s:3:"硤";s:2:"ÚÇ";s:3:"ç¡¥";s:2:"ÚÈ";s:3:"硜";s:2:"ÚÉ";s:3:"ç¡­";s:2:"ÚÊ";s:3:"硱";s:2:"ÚË";s:3:"硪";s:2:"ÚÌ";s:3:"ç¡®";s:2:"ÚÍ";s:3:"ç¡°";s:2:"ÚÎ";s:3:"ç¡©";s:2:"ÚÏ";s:3:"硨";s:2:"ÚÐ";s:3:"硞";s:2:"ÚÑ";s:3:"ç¡¢";s:2:"ÚÒ";s:3:"祴";s:2:"ÚÓ";s:3:"祳";s:2:"ÚÔ";s:3:"祲";s:2:"ÚÕ";s:3:"祰";s:2:"ÚÖ";s:3:"稂";s:2:"Ú×";s:3:"稊";s:2:"ÚØ";s:3:"稃";s:2:"ÚÙ";s:3:"稌";s:2:"ÚÚ";s:3:"稄";s:2:"ÚÛ";s:3:"窙";s:2:"ÚÜ";s:3:"竦";s:2:"ÚÝ";s:3:"竤";s:2:"ÚÞ";s:3:"ç­Š";s:2:"Úß";s:3:"笻";s:2:"Úà";s:3:"ç­„";s:2:"Úá";s:3:"ç­ˆ";s:2:"Úâ";s:3:"ç­Œ";s:2:"Úã";s:3:"ç­Ž";s:2:"Úä";s:3:"ç­€";s:2:"Úå";s:3:"ç­˜";s:2:"Úæ";s:3:"ç­…";s:2:"Úç";s:3:"ç²¢";s:2:"Úè";s:3:"粞";s:2:"Úé";s:3:"粨";s:2:"Úê";s:3:"粡";s:2:"Úë";s:3:"絘";s:2:"Úì";s:3:"絯";s:2:"Úí";s:3:"çµ£";s:2:"Úî";s:3:"絓";s:2:"Úï";s:3:"çµ–";s:2:"Úð";s:3:"çµ§";s:2:"Úñ";s:3:"絪";s:2:"Úò";s:3:"çµ";s:2:"Úó";s:3:"çµ­";s:2:"Úô";s:3:"絜";s:2:"Úõ";s:3:"絫";s:2:"Úö";s:3:"çµ’";s:2:"Ú÷";s:3:"çµ”";s:2:"Úø";s:3:"絩";s:2:"Úù";s:3:"絑";s:2:"Úú";s:3:"絟";s:2:"Úû";s:3:"絎";s:2:"Úü";s:3:"ç¼¾";s:2:"Úý";s:3:"缿";s:2:"Úþ";s:3:"ç½¥";s:2:"Û@";s:3:"罦";s:2:"ÛA";s:3:"ç¾¢";s:2:"ÛB";s:3:"ç¾ ";s:2:"ÛC";s:3:"羡";s:2:"ÛD";s:3:"ç¿—";s:2:"ÛE";s:3:"è‘";s:2:"ÛF";s:3:"è";s:2:"ÛG";s:3:"è";s:2:"ÛH";s:3:"胾";s:2:"ÛI";s:3:"胔";s:2:"ÛJ";s:3:"è…ƒ";s:2:"ÛK";s:3:"è…Š";s:2:"ÛL";s:3:"è…’";s:2:"ÛM";s:3:"è…";s:2:"ÛN";s:3:"è…‡";s:2:"ÛO";s:3:"脽";s:2:"ÛP";s:3:"è…";s:2:"ÛQ";s:3:"脺";s:2:"ÛR";s:3:"臦";s:2:"ÛS";s:3:"臮";s:2:"ÛT";s:3:"臷";s:2:"ÛU";s:3:"臸";s:2:"ÛV";s:3:"臹";s:2:"ÛW";s:3:"舄";s:2:"ÛX";s:3:"舼";s:2:"ÛY";s:3:"舽";s:2:"ÛZ";s:3:"舿";s:2:"Û[";s:3:"艵";s:2:"Û\";s:3:"茻";s:2:"Û]";s:3:"è";s:2:"Û^";s:3:"è¹";s:2:"Û_";s:3:"è£";s:2:"Û`";s:3:"è€";s:2:"Ûa";s:3:"è¨";s:2:"Ûb";s:3:"è’";s:2:"Ûc";s:3:"è§";s:2:"Ûd";s:3:"è¤";s:2:"Ûe";s:3:"è¼";s:2:"Ûf";s:3:"è¶";s:2:"Ûg";s:3:"è";s:2:"Ûh";s:3:"è†";s:2:"Ûi";s:3:"èˆ";s:2:"Ûj";s:3:"è«";s:2:"Ûk";s:3:"è£";s:2:"Ûl";s:3:"莿";s:2:"Ûm";s:3:"è";s:2:"Ûn";s:3:"è";s:2:"Ûo";s:3:"è¥";s:2:"Ûp";s:3:"è˜";s:2:"Ûq";s:3:"è¿";s:2:"Ûr";s:3:"è¡";s:2:"Ûs";s:3:"è‹";s:2:"Ût";s:3:"èŽ";s:2:"Ûu";s:3:"è–";s:2:"Ûv";s:3:"èµ";s:2:"Ûw";s:3:"è‰";s:2:"Ûx";s:3:"è‰";s:2:"Ûy";s:3:"è";s:2:"Ûz";s:3:"èž";s:2:"Û{";s:3:"è‘";s:2:"Û|";s:3:"è†";s:2:"Û}";s:3:"è‚";s:2:"Û~";s:3:"è³";s:2:"Û¡";s:3:"è•";s:2:"Û¢";s:3:"èº";s:2:"Û£";s:3:"è‡";s:2:"Û¤";s:3:"è‘";s:2:"Û¥";s:3:"èª";s:2:"Û¦";s:3:"è“";s:2:"Û§";s:3:"èƒ";s:2:"Û¨";s:3:"è¬";s:2:"Û©";s:3:"è®";s:2:"Ûª";s:3:"è„";s:2:"Û«";s:3:"è»";s:2:"Û¬";s:3:"è—";s:2:"Û­";s:3:"è¢";s:2:"Û®";s:3:"è›";s:2:"Û¯";s:3:"è›";s:2:"Û°";s:3:"è¾";s:2:"Û±";s:3:"蛘";s:2:"Û²";s:3:"蛢";s:2:"Û³";s:3:"蛦";s:2:"Û´";s:3:"蛓";s:2:"Ûµ";s:3:"蛣";s:2:"Û¶";s:3:"蛚";s:2:"Û·";s:3:"蛪";s:2:"Û¸";s:3:"è›";s:2:"Û¹";s:3:"蛫";s:2:"Ûº";s:3:"蛜";s:2:"Û»";s:3:"蛬";s:2:"Û¼";s:3:"蛩";s:2:"Û½";s:3:"è›—";s:2:"Û¾";s:3:"蛨";s:2:"Û¿";s:3:"蛑";s:2:"ÛÀ";s:3:"衈";s:2:"ÛÁ";s:3:"è¡–";s:2:"ÛÂ";s:3:"è¡•";s:2:"ÛÃ";s:3:"袺";s:2:"ÛÄ";s:3:"裗";s:2:"ÛÅ";s:3:"袹";s:2:"ÛÆ";s:3:"袸";s:2:"ÛÇ";s:3:"裀";s:2:"ÛÈ";s:3:"袾";s:2:"ÛÉ";s:3:"袶";s:2:"ÛÊ";s:3:"袼";s:2:"ÛË";s:3:"袷";s:2:"ÛÌ";s:3:"袽";s:2:"ÛÍ";s:3:"袲";s:2:"ÛÎ";s:3:"è¤";s:2:"ÛÏ";s:3:"裉";s:2:"ÛÐ";s:3:"覕";s:2:"ÛÑ";s:3:"覘";s:2:"ÛÒ";s:3:"覗";s:2:"ÛÓ";s:3:"è§";s:2:"ÛÔ";s:3:"è§š";s:2:"ÛÕ";s:3:"è§›";s:2:"ÛÖ";s:3:"詎";s:2:"Û×";s:3:"è©";s:2:"ÛØ";s:3:"訹";s:2:"ÛÙ";s:3:"è©™";s:2:"ÛÚ";s:3:"è©€";s:2:"ÛÛ";s:3:"è©—";s:2:"ÛÜ";s:3:"詘";s:2:"ÛÝ";s:3:"è©„";s:2:"ÛÞ";s:3:"è©…";s:2:"Ûß";s:3:"è©’";s:2:"Ûà";s:3:"詈";s:2:"Ûá";s:3:"è©‘";s:2:"Ûâ";s:3:"詊";s:2:"Ûã";s:3:"詌";s:2:"Ûä";s:3:"è©";s:2:"Ûå";s:3:"豟";s:2:"Ûæ";s:3:"è²";s:2:"Ûç";s:3:"è²€";s:2:"Ûè";s:3:"貺";s:2:"Ûé";s:3:"è²¾";s:2:"Ûê";s:3:"è²°";s:2:"Ûë";s:3:"è²¹";s:2:"Ûì";s:3:"è²µ";s:2:"Ûí";s:3:"è¶„";s:2:"Ûî";s:3:"è¶€";s:2:"Ûï";s:3:"趉";s:2:"Ûð";s:3:"è·˜";s:2:"Ûñ";s:3:"è·“";s:2:"Ûò";s:3:"è·";s:2:"Ûó";s:3:"è·‡";s:2:"Ûô";s:3:"è·–";s:2:"Ûõ";s:3:"è·œ";s:2:"Ûö";s:3:"è·";s:2:"Û÷";s:3:"è·•";s:2:"Ûø";s:3:"è·™";s:2:"Ûù";s:3:"è·ˆ";s:2:"Ûú";s:3:"è·—";s:2:"Ûû";s:3:"è·…";s:2:"Ûü";s:3:"軯";s:2:"Ûý";s:3:"è»·";s:2:"Ûþ";s:3:"軺";s:2:"Ü@";s:3:"軹";s:2:"ÜA";s:3:"軦";s:2:"ÜB";s:3:"è»®";s:2:"ÜC";s:3:"軥";s:2:"ÜD";s:3:"軵";s:2:"ÜE";s:3:"è»§";s:2:"ÜF";s:3:"軨";s:2:"ÜG";s:3:"è»¶";s:2:"ÜH";s:3:"軫";s:2:"ÜI";s:3:"è»±";s:2:"ÜJ";s:3:"軬";s:2:"ÜK";s:3:"è»´";s:2:"ÜL";s:3:"軩";s:2:"ÜM";s:3:"逭";s:2:"ÜN";s:3:"逴";s:2:"ÜO";s:3:"逯";s:2:"ÜP";s:3:"鄆";s:2:"ÜQ";s:3:"鄬";s:2:"ÜR";s:3:"é„„";s:2:"ÜS";s:3:"郿";s:2:"ÜT";s:3:"郼";s:2:"ÜU";s:3:"鄈";s:2:"ÜV";s:3:"郹";s:2:"ÜW";s:3:"郻";s:2:"ÜX";s:3:"é„";s:2:"ÜY";s:3:"é„€";s:2:"ÜZ";s:3:"鄇";s:2:"Ü[";s:3:"é„…";s:2:"Ü\";s:3:"鄃";s:2:"Ü]";s:3:"é…¡";s:2:"Ü^";s:3:"é…¤";s:2:"Ü_";s:3:"é…Ÿ";s:2:"Ü`";s:3:"é…¢";s:2:"Üa";s:3:"é… ";s:2:"Üb";s:3:"éˆ";s:2:"Üc";s:3:"鈊";s:2:"Üd";s:3:"鈥";s:2:"Üe";s:3:"鈃";s:2:"Üf";s:3:"鈚";s:2:"Üg";s:3:"鈦";s:2:"Üh";s:3:"éˆ";s:2:"Üi";s:3:"鈌";s:2:"Üj";s:3:"鈀";s:2:"Ük";s:3:"鈒";s:2:"Ül";s:3:"釿";s:2:"Üm";s:3:"釽";s:2:"Ün";s:3:"鈆";s:2:"Üo";s:3:"鈄";s:2:"Üp";s:3:"鈧";s:2:"Üq";s:3:"鈂";s:2:"Ür";s:3:"鈜";s:2:"Üs";s:3:"鈤";s:2:"Üt";s:3:"鈙";s:2:"Üu";s:3:"鈗";s:2:"Üv";s:3:"鈅";s:2:"Üw";s:3:"鈖";s:2:"Üx";s:3:"é•»";s:2:"Üy";s:3:"é–";s:2:"Üz";s:3:"é–Œ";s:2:"Ü{";s:3:"é–";s:2:"Ü|";s:3:"隇";s:2:"Ü}";s:3:"陾";s:2:"Ü~";s:3:"隈";s:2:"Ü¡";s:3:"隉";s:2:"Ü¢";s:3:"隃";s:2:"Ü£";s:3:"隀";s:2:"ܤ";s:3:"雂";s:2:"Ü¥";s:3:"雈";s:2:"ܦ";s:3:"雃";s:2:"ܧ";s:3:"é›±";s:2:"ܨ";s:3:"é›°";s:2:"Ü©";s:3:"é¬";s:2:"ܪ";s:3:"é°";s:2:"Ü«";s:3:"é®";s:2:"ܬ";s:3:"é ‡";s:2:"Ü­";s:3:"颩";s:2:"Ü®";s:3:"飫";s:2:"ܯ";s:3:"鳦";s:2:"ܰ";s:3:"黹";s:2:"ܱ";s:3:"亃";s:2:"ܲ";s:3:"亄";s:2:"ܳ";s:3:"亶";s:2:"Ü´";s:3:"傽";s:2:"ܵ";s:3:"å‚¿";s:2:"ܶ";s:3:"僆";s:2:"Ü·";s:3:"å‚®";s:2:"ܸ";s:3:"僄";s:2:"ܹ";s:3:"僊";s:2:"ܺ";s:3:"å‚´";s:2:"Ü»";s:3:"僈";s:2:"ܼ";s:3:"僂";s:2:"ܽ";s:3:"å‚°";s:2:"ܾ";s:3:"åƒ";s:2:"Ü¿";s:3:"傺";s:2:"ÜÀ";s:3:"傱";s:2:"ÜÁ";s:3:"僋";s:2:"ÜÂ";s:3:"僉";s:2:"ÜÃ";s:3:"å‚¶";s:2:"ÜÄ";s:3:"傸";s:2:"ÜÅ";s:3:"凗";s:2:"ÜÆ";s:3:"剺";s:2:"ÜÇ";s:3:"剸";s:2:"ÜÈ";s:3:"剻";s:2:"ÜÉ";s:3:"剼";s:2:"ÜÊ";s:3:"å—ƒ";s:2:"ÜË";s:3:"å—›";s:2:"ÜÌ";s:3:"å—Œ";s:2:"ÜÍ";s:3:"å—";s:2:"ÜÎ";s:3:"å—‹";s:2:"ÜÏ";s:3:"å—Š";s:2:"ÜÐ";s:3:"å—";s:2:"ÜÑ";s:3:"å—€";s:2:"ÜÒ";s:3:"å—”";s:2:"ÜÓ";s:3:"å—„";s:2:"ÜÔ";s:3:"å—©";s:2:"ÜÕ";s:3:"å–¿";s:2:"ÜÖ";s:3:"å—’";s:2:"Ü×";s:3:"å–";s:2:"ÜØ";s:3:"å—";s:2:"ÜÙ";s:3:"å—•";s:2:"ÜÚ";s:3:"å—¢";s:2:"ÜÛ";s:3:"å—–";s:2:"ÜÜ";s:3:"å—ˆ";s:2:"ÜÝ";s:3:"å—²";s:2:"ÜÞ";s:3:"å—";s:2:"Üß";s:3:"å—™";s:2:"Üà";s:3:"å—‚";s:2:"Üá";s:3:"圔";s:2:"Üâ";s:3:"å¡“";s:2:"Üã";s:3:"塨";s:2:"Üä";s:3:"塤";s:2:"Üå";s:3:"å¡";s:2:"Üæ";s:3:"å¡";s:2:"Üç";s:3:"塉";s:2:"Üè";s:3:"塯";s:2:"Üé";s:3:"å¡•";s:2:"Üê";s:3:"塎";s:2:"Üë";s:3:"å¡";s:2:"Üì";s:3:"å¡™";s:2:"Üí";s:3:"å¡¥";s:2:"Üî";s:3:"å¡›";s:2:"Üï";s:3:"å ½";s:2:"Üð";s:3:"å¡£";s:2:"Üñ";s:3:"塱";s:2:"Üò";s:3:"壼";s:2:"Üó";s:3:"嫇";s:2:"Üô";s:3:"å«„";s:2:"Üõ";s:3:"å«‹";s:2:"Üö";s:3:"媺";s:2:"Ü÷";s:3:"媸";s:2:"Üø";s:3:"媱";s:2:"Üù";s:3:"媵";s:2:"Üú";s:3:"媰";s:2:"Üû";s:3:"媿";s:2:"Üü";s:3:"嫈";s:2:"Üý";s:3:"媻";s:2:"Üþ";s:3:"嫆";s:2:"Ý@";s:3:"媷";s:2:"ÝA";s:3:"å«€";s:2:"ÝB";s:3:"嫊";s:2:"ÝC";s:3:"媴";s:2:"ÝD";s:3:"媶";s:2:"ÝE";s:3:"å«";s:2:"ÝF";s:3:"媹";s:2:"ÝG";s:3:"åª";s:2:"ÝH";s:3:"寖";s:2:"ÝI";s:3:"寘";s:2:"ÝJ";s:3:"寙";s:2:"ÝK";s:3:"å°Ÿ";s:2:"ÝL";s:3:"å°³";s:2:"ÝM";s:3:"åµ±";s:2:"ÝN";s:3:"åµ£";s:2:"ÝO";s:3:"嵊";s:2:"ÝP";s:3:"åµ¥";s:2:"ÝQ";s:3:"åµ²";s:2:"ÝR";s:3:"嵬";s:2:"ÝS";s:3:"嵞";s:2:"ÝT";s:3:"嵨";s:2:"ÝU";s:3:"åµ§";s:2:"ÝV";s:3:"åµ¢";s:2:"ÝW";s:3:"å·°";s:2:"ÝX";s:3:"å¹";s:2:"ÝY";s:3:"幎";s:2:"ÝZ";s:3:"幊";s:2:"Ý[";s:3:"å¹";s:2:"Ý\";s:3:"幋";s:2:"Ý]";s:3:"å»…";s:2:"Ý^";s:3:"廌";s:2:"Ý_";s:3:"廆";s:2:"Ý`";s:3:"廋";s:2:"Ýa";s:3:"廇";s:2:"Ýb";s:3:"å½€";s:2:"Ýc";s:3:"徯";s:2:"Ýd";s:3:"å¾­";s:2:"Ýe";s:3:"惷";s:2:"Ýf";s:3:"æ…‰";s:2:"Ýg";s:3:"æ…Š";s:2:"Ýh";s:3:"æ„«";s:2:"Ýi";s:3:"æ……";s:2:"Ýj";s:3:"æ„¶";s:2:"Ýk";s:3:"愲";s:2:"Ýl";s:3:"æ„®";s:2:"Ým";s:3:"æ…†";s:2:"Ýn";s:3:"愯";s:2:"Ýo";s:3:"æ…";s:2:"Ýp";s:3:"æ„©";s:2:"Ýq";s:3:"æ…€";s:2:"Ýr";s:3:"戠";s:2:"Ýs";s:3:"é…¨";s:2:"Ýt";s:3:"戣";s:2:"Ýu";s:3:"戥";s:2:"Ýv";s:3:"戤";s:2:"Ýw";s:3:"æ…";s:2:"Ýx";s:3:"æ±";s:2:"Ýy";s:3:"æ«";s:2:"Ýz";s:3:"æ";s:2:"Ý{";s:3:"æ’";s:2:"Ý|";s:3:"æ‰";s:2:"Ý}";s:3:"æ ";s:2:"Ý~";s:3:"æ¤";s:2:"Ý¡";s:3:"æ³";s:2:"Ý¢";s:3:"摃";s:2:"Ý£";s:3:"æŸ";s:2:"ݤ";s:3:"æ•";s:2:"Ý¥";s:3:"æ˜";s:2:"ݦ";s:3:"æ¹";s:2:"ݧ";s:3:"æ·";s:2:"ݨ";s:3:"æ¢";s:2:"Ý©";s:3:"æ£";s:2:"ݪ";s:3:"æŒ";s:2:"Ý«";s:3:"æ¦";s:2:"ݬ";s:3:"æ°";s:2:"Ý­";s:3:"æ¨";s:2:"Ý®";s:3:"æ‘";s:2:"ݯ";s:3:"æµ";s:2:"ݰ";s:3:"æ¯";s:2:"ݱ";s:3:"æŠ";s:2:"ݲ";s:3:"æš";s:2:"ݳ";s:3:"æ‘€";s:2:"Ý´";s:3:"æ¥";s:2:"ݵ";s:3:"æ§";s:2:"ݶ";s:3:"æ‹";s:2:"Ý·";s:3:"æ§";s:2:"ݸ";s:3:"æ›";s:2:"ݹ";s:3:"æ®";s:2:"ݺ";s:3:"æ¡";s:2:"Ý»";s:3:"æŽ";s:2:"ݼ";s:3:"敯";s:2:"ݽ";s:3:"æ–’";s:2:"ݾ";s:3:"æ—“";s:2:"Ý¿";s:3:"暆";s:2:"ÝÀ";s:3:"暌";s:2:"ÝÁ";s:3:"æš•";s:2:"ÝÂ";s:3:"æš";s:2:"ÝÃ";s:3:"æš‹";s:2:"ÝÄ";s:3:"暊";s:2:"ÝÅ";s:3:"æš™";s:2:"ÝÆ";s:3:"æš”";s:2:"ÝÇ";s:3:"晸";s:2:"ÝÈ";s:3:"朠";s:2:"ÝÉ";s:3:"楦";s:2:"ÝÊ";s:3:"楟";s:2:"ÝË";s:3:"椸";s:2:"ÝÌ";s:3:"楎";s:2:"ÝÍ";s:3:"楢";s:2:"ÝÎ";s:3:"楱";s:2:"ÝÏ";s:3:"椿";s:2:"ÝÐ";s:3:"楅";s:2:"ÝÑ";s:3:"楪";s:2:"ÝÒ";s:3:"椹";s:2:"ÝÓ";s:3:"楂";s:2:"ÝÔ";s:3:"楗";s:2:"ÝÕ";s:3:"楙";s:2:"ÝÖ";s:3:"楺";s:2:"Ý×";s:3:"楈";s:2:"ÝØ";s:3:"楉";s:2:"ÝÙ";s:3:"椵";s:2:"ÝÚ";s:3:"楬";s:2:"ÝÛ";s:3:"椳";s:2:"ÝÜ";s:3:"椽";s:2:"ÝÝ";s:3:"楥";s:2:"ÝÞ";s:3:"棰";s:2:"Ýß";s:3:"楸";s:2:"Ýà";s:3:"椴";s:2:"Ýá";s:3:"楩";s:2:"Ýâ";s:3:"楀";s:2:"Ýã";s:3:"楯";s:2:"Ýä";s:3:"楄";s:2:"Ýå";s:3:"楶";s:2:"Ýæ";s:3:"楘";s:2:"Ýç";s:3:"æ¥";s:2:"Ýè";s:3:"楴";s:2:"Ýé";s:3:"楌";s:2:"Ýê";s:3:"椻";s:2:"Ýë";s:3:"楋";s:2:"Ýì";s:3:"椷";s:2:"Ýí";s:3:"楜";s:2:"Ýî";s:3:"æ¥";s:2:"Ýï";s:3:"楑";s:2:"Ýð";s:3:"椲";s:2:"Ýñ";s:3:"楒";s:2:"Ýò";s:3:"椯";s:2:"Ýó";s:3:"楻";s:2:"Ýô";s:3:"椼";s:2:"Ýõ";s:3:"æ­†";s:2:"Ýö";s:3:"æ­…";s:2:"Ý÷";s:3:"æ­ƒ";s:2:"Ýø";s:3:"æ­‚";s:2:"Ýù";s:3:"æ­ˆ";s:2:"Ýú";s:3:"æ­";s:2:"Ýû";s:3:"æ®›";s:2:"Ýü";s:3:"ï¨";s:2:"Ýý";s:3:"毻";s:2:"Ýþ";s:3:"毼";s:2:"Þ@";s:3:"毹";s:2:"ÞA";s:3:"毷";s:2:"ÞB";s:3:"毸";s:2:"ÞC";s:3:"溛";s:2:"ÞD";s:3:"æ»–";s:2:"ÞE";s:3:"滈";s:2:"ÞF";s:3:"æº";s:2:"ÞG";s:3:"滀";s:2:"ÞH";s:3:"溟";s:2:"ÞI";s:3:"溓";s:2:"ÞJ";s:3:"溔";s:2:"ÞK";s:3:"溠";s:2:"ÞL";s:3:"溱";s:2:"ÞM";s:3:"溹";s:2:"ÞN";s:3:"滆";s:2:"ÞO";s:3:"æ»’";s:2:"ÞP";s:3:"溽";s:2:"ÞQ";s:3:"æ»";s:2:"ÞR";s:3:"溞";s:2:"ÞS";s:3:"滉";s:2:"ÞT";s:3:"溷";s:2:"ÞU";s:3:"溰";s:2:"ÞV";s:3:"æ»";s:2:"ÞW";s:3:"溦";s:2:"ÞX";s:3:"æ»";s:2:"ÞY";s:3:"溲";s:2:"ÞZ";s:3:"溾";s:2:"Þ[";s:3:"滃";s:2:"Þ\";s:3:"滜";s:2:"Þ]";s:3:"滘";s:2:"Þ^";s:3:"溙";s:2:"Þ_";s:3:"溒";s:2:"Þ`";s:3:"溎";s:2:"Þa";s:3:"æº";s:2:"Þb";s:3:"溤";s:2:"Þc";s:3:"溡";s:2:"Þd";s:3:"溿";s:2:"Þe";s:3:"溳";s:2:"Þf";s:3:"æ»";s:2:"Þg";s:3:"滊";s:2:"Þh";s:3:"溗";s:2:"Þi";s:3:"溮";s:2:"Þj";s:3:"溣";s:2:"Þk";s:3:"ç…‡";s:2:"Þl";s:3:"ç…”";s:2:"Þm";s:3:"ç…’";s:2:"Þn";s:3:"ç…£";s:2:"Þo";s:3:"ç… ";s:2:"Þp";s:3:"ç…";s:2:"Þq";s:3:"ç…";s:2:"Þr";s:3:"ç…¢";s:2:"Þs";s:3:"ç…²";s:2:"Þt";s:3:"ç…¸";s:2:"Þu";s:3:"ç…ª";s:2:"Þv";s:3:"ç…¡";s:2:"Þw";s:3:"ç…‚";s:2:"Þx";s:3:"ç…˜";s:2:"Þy";s:3:"ç…ƒ";s:2:"Þz";s:3:"ç…‹";s:2:"Þ{";s:3:"ç…°";s:2:"Þ|";s:3:"ç…Ÿ";s:2:"Þ}";s:3:"ç…";s:2:"Þ~";s:3:"ç…“";s:2:"Þ¡";s:3:"ç…„";s:2:"Þ¢";s:3:"ç…";s:2:"Þ£";s:3:"ç…š";s:2:"Þ¤";s:3:"ç‰";s:2:"Þ¥";s:3:"çŠ";s:2:"Þ¦";s:3:"犌";s:2:"Þ§";s:3:"犑";s:2:"Þ¨";s:3:"çŠ";s:2:"Þ©";s:3:"犎";s:2:"Þª";s:3:"猼";s:2:"Þ«";s:3:"ç‚";s:2:"Þ¬";s:3:"猻";s:2:"Þ­";s:3:"猺";s:2:"Þ®";s:3:"ç€";s:2:"Þ¯";s:3:"çŠ";s:2:"Þ°";s:3:"ç‰";s:2:"Þ±";s:3:"ç‘„";s:2:"Þ²";s:3:"瑊";s:2:"Þ³";s:3:"ç‘‹";s:2:"Þ´";s:3:"ç‘’";s:2:"Þµ";s:3:"ç‘‘";s:2:"Þ¶";s:3:"ç‘—";s:2:"Þ·";s:3:"ç‘€";s:2:"Þ¸";s:3:"ç‘";s:2:"Þ¹";s:3:"ç‘";s:2:"Þº";s:3:"瑎";s:2:"Þ»";s:3:"ç‘‚";s:2:"Þ¼";s:3:"瑆";s:2:"Þ½";s:3:"ç‘";s:2:"Þ¾";s:3:"ç‘”";s:2:"Þ¿";s:3:"ç“¡";s:2:"ÞÀ";s:3:"ç“¿";s:2:"ÞÁ";s:3:"瓾";s:2:"ÞÂ";s:3:"瓽";s:2:"ÞÃ";s:3:"ç”";s:2:"ÞÄ";s:3:"畹";s:2:"ÞÅ";s:3:"ç•·";s:2:"ÞÆ";s:3:"榃";s:2:"ÞÇ";s:3:"ç—¯";s:2:"ÞÈ";s:3:"ç˜";s:2:"ÞÉ";s:3:"瘃";s:2:"ÞÊ";s:3:"ç—·";s:2:"ÞË";s:3:"ç—¾";s:2:"ÞÌ";s:3:"ç—¼";s:2:"ÞÍ";s:3:"ç—¹";s:2:"ÞÎ";s:3:"ç—¸";s:2:"ÞÏ";s:3:"ç˜";s:2:"ÞÐ";s:3:"ç—»";s:2:"ÞÑ";s:3:"ç—¶";s:2:"ÞÒ";s:3:"ç—­";s:2:"ÞÓ";s:3:"ç—µ";s:2:"ÞÔ";s:3:"ç—½";s:2:"ÞÕ";s:3:"çš™";s:2:"ÞÖ";s:3:"çšµ";s:2:"Þ×";s:3:"ç›";s:2:"ÞØ";s:3:"ç•";s:2:"ÞÙ";s:3:"çŸ";s:2:"ÞÚ";s:3:"ç ";s:2:"ÞÛ";s:3:"ç’";s:2:"ÞÜ";s:3:"ç–";s:2:"ÞÝ";s:3:"çš";s:2:"ÞÞ";s:3:"ç©";s:2:"Þß";s:3:"ç§";s:2:"Þà";s:3:"ç”";s:2:"Þá";s:3:"ç™";s:2:"Þâ";s:3:"ç­";s:2:"Þã";s:3:"矠";s:2:"Þä";s:3:"碇";s:2:"Þå";s:3:"碚";s:2:"Þæ";s:3:"碔";s:2:"Þç";s:3:"ç¢";s:2:"Þè";s:3:"碄";s:2:"Þé";s:3:"碕";s:2:"Þê";s:3:"碅";s:2:"Þë";s:3:"碆";s:2:"Þì";s:3:"碡";s:2:"Þí";s:3:"碃";s:2:"Þî";s:3:"硹";s:2:"Þï";s:3:"碙";s:2:"Þð";s:3:"碀";s:2:"Þñ";s:3:"碖";s:2:"Þò";s:3:"ç¡»";s:2:"Þó";s:3:"祼";s:2:"Þô";s:3:"禂";s:2:"Þõ";s:3:"祽";s:2:"Þö";s:3:"祹";s:2:"Þ÷";s:3:"稑";s:2:"Þø";s:3:"稘";s:2:"Þù";s:3:"稙";s:2:"Þú";s:3:"稒";s:2:"Þû";s:3:"稗";s:2:"Þü";s:3:"稕";s:2:"Þý";s:3:"稢";s:2:"Þþ";s:3:"稓";s:2:"ß@";s:3:"稛";s:2:"ßA";s:3:"ç¨";s:2:"ßB";s:3:"窣";s:2:"ßC";s:3:"窢";s:2:"ßD";s:3:"窞";s:2:"ßE";s:3:"ç««";s:2:"ßF";s:3:"ç­¦";s:2:"ßG";s:3:"ç­¤";s:2:"ßH";s:3:"ç­­";s:2:"ßI";s:3:"ç­´";s:2:"ßJ";s:3:"ç­©";s:2:"ßK";s:3:"ç­²";s:2:"ßL";s:3:"ç­¥";s:2:"ßM";s:3:"ç­³";s:2:"ßN";s:3:"ç­±";s:2:"ßO";s:3:"ç­°";s:2:"ßP";s:3:"ç­¡";s:2:"ßQ";s:3:"ç­¸";s:2:"ßR";s:3:"ç­¶";s:2:"ßS";s:3:"ç­£";s:2:"ßT";s:3:"ç²²";s:2:"ßU";s:3:"ç²´";s:2:"ßV";s:3:"粯";s:2:"ßW";s:3:"綈";s:2:"ßX";s:3:"綆";s:2:"ßY";s:3:"ç¶€";s:2:"ßZ";s:3:"ç¶";s:2:"ß[";s:3:"絿";s:2:"ß\";s:3:"ç¶…";s:2:"ß]";s:3:"絺";s:2:"ß^";s:3:"ç¶Ž";s:2:"ß_";s:3:"çµ»";s:2:"ß`";s:3:"綃";s:2:"ßa";s:3:"çµ¼";s:2:"ßb";s:3:"ç¶Œ";s:2:"ßc";s:3:"ç¶”";s:2:"ßd";s:3:"ç¶„";s:2:"ße";s:3:"çµ½";s:2:"ßf";s:3:"ç¶’";s:2:"ßg";s:3:"ç½­";s:2:"ßh";s:3:"罫";s:2:"ßi";s:3:"ç½§";s:2:"ßj";s:3:"罨";s:2:"ßk";s:3:"罬";s:2:"ßl";s:3:"羦";s:2:"ßm";s:3:"ç¾¥";s:2:"ßn";s:3:"ç¾§";s:2:"ßo";s:3:"ç¿›";s:2:"ßp";s:3:"翜";s:2:"ßq";s:3:"耡";s:2:"ßr";s:3:"è…¤";s:2:"ßs";s:3:"è… ";s:2:"ßt";s:3:"è…·";s:2:"ßu";s:3:"è…œ";s:2:"ßv";s:3:"è…©";s:2:"ßw";s:3:"è…›";s:2:"ßx";s:3:"è…¢";s:2:"ßy";s:3:"è…²";s:2:"ßz";s:3:"朡";s:2:"ß{";s:3:"è…ž";s:2:"ß|";s:3:"è…¶";s:2:"ß}";s:3:"è…§";s:2:"ß~";s:3:"è…¯";s:2:"ß¡";s:3:"è…„";s:2:"ߢ";s:3:"è…¡";s:2:"ߣ";s:3:"èˆ";s:2:"ߤ";s:3:"艉";s:2:"ߥ";s:3:"艄";s:2:"ߦ";s:3:"艀";s:2:"ß§";s:3:"艂";s:2:"ߨ";s:3:"艅";s:2:"ß©";s:3:"蓱";s:2:"ߪ";s:3:"è¿";s:2:"ß«";s:3:"è‘–";s:2:"߬";s:3:"è‘¶";s:2:"ß­";s:3:"葹";s:2:"ß®";s:3:"è’";s:2:"߯";s:3:"è’";s:2:"ß°";s:3:"è‘¥";s:2:"ß±";s:3:"è‘‘";s:2:"ß²";s:3:"è‘€";s:2:"ß³";s:3:"è’†";s:2:"ß´";s:3:"è‘§";s:2:"ßµ";s:3:"è°";s:2:"ß¶";s:3:"è‘";s:2:"ß·";s:3:"葽";s:2:"߸";s:3:"葚";s:2:"ß¹";s:3:"è‘™";s:2:"ߺ";s:3:"è‘´";s:2:"ß»";s:3:"葳";s:2:"ß¼";s:3:"è‘";s:2:"ß½";s:3:"蔇";s:2:"ß¾";s:3:"葞";s:2:"ß¿";s:3:"è·";s:2:"ßÀ";s:3:"èº";s:2:"ßÁ";s:3:"è´";s:2:"ßÂ";s:3:"葺";s:2:"ßÃ";s:3:"葃";s:2:"ßÄ";s:3:"葸";s:2:"ßÅ";s:3:"è²";s:2:"߯";s:3:"è‘…";s:2:"ßÇ";s:3:"è©";s:2:"ßÈ";s:3:"è™";s:2:"ßÉ";s:3:"è‘‹";s:2:"ßÊ";s:3:"è¯";s:2:"ßË";s:3:"è‘‚";s:2:"ßÌ";s:3:"è­";s:2:"ßÍ";s:3:"葟";s:2:"ßÎ";s:3:"è‘°";s:2:"ßÏ";s:3:"è¹";s:2:"ßÐ";s:3:"葎";s:2:"ßÑ";s:3:"葌";s:2:"ßÒ";s:3:"è‘’";s:2:"ßÓ";s:3:"葯";s:2:"ßÔ";s:3:"è“…";s:2:"ßÕ";s:3:"è’Ž";s:2:"ßÖ";s:3:"è»";s:2:"ß×";s:3:"葇";s:2:"ߨ";s:3:"è¶";s:2:"ßÙ";s:3:"è³";s:2:"ßÚ";s:3:"葨";s:2:"ßÛ";s:3:"葾";s:2:"ßÜ";s:3:"è‘„";s:2:"ßÝ";s:3:"è«";s:2:"ßÞ";s:3:"è‘ ";s:2:"ßß";s:3:"è‘”";s:2:"ßà";s:3:"è‘®";s:2:"ßá";s:3:"è‘";s:2:"ßâ";s:3:"蜋";s:2:"ßã";s:3:"蜄";s:2:"ßä";s:3:"è›·";s:2:"ßå";s:3:"蜌";s:2:"ßæ";s:3:"蛺";s:2:"ßç";s:3:"è›–";s:2:"ßè";s:3:"蛵";s:2:"ßé";s:3:"è";s:2:"ßê";s:3:"蛸";s:2:"ßë";s:3:"蜎";s:2:"ßì";s:3:"蜉";s:2:"ßí";s:3:"èœ";s:2:"ßî";s:3:"è›¶";s:2:"ßï";s:3:"èœ";s:2:"ßð";s:3:"蜅";s:2:"ßñ";s:3:"裖";s:2:"ßò";s:3:"裋";s:2:"ßó";s:3:"è£";s:2:"ßô";s:3:"裎";s:2:"ßõ";s:3:"裞";s:2:"ßö";s:3:"裛";s:2:"ß÷";s:3:"裚";s:2:"ßø";s:3:"裌";s:2:"ßù";s:3:"è£";s:2:"ßú";s:3:"覅";s:2:"ßû";s:3:"覛";s:2:"ßü";s:3:"è§Ÿ";s:2:"ßý";s:3:"è§¥";s:2:"ßþ";s:3:"觤";s:2:"à@";s:3:"è§¡";s:2:"àA";s:3:"è§ ";s:2:"àB";s:3:"è§¢";s:2:"àC";s:3:"è§œ";s:2:"àD";s:3:"触";s:2:"àE";s:3:"è©¶";s:2:"àF";s:3:"誆";s:2:"àG";s:3:"è©¿";s:2:"àH";s:3:"è©¡";s:2:"àI";s:3:"訿";s:2:"àJ";s:3:"è©·";s:2:"àK";s:3:"誂";s:2:"àL";s:3:"誄";s:2:"àM";s:3:"詵";s:2:"àN";s:3:"誃";s:2:"àO";s:3:"èª";s:2:"àP";s:3:"è©´";s:2:"àQ";s:3:"詺";s:2:"àR";s:3:"è°¼";s:2:"àS";s:3:"豋";s:2:"àT";s:3:"豊";s:2:"àU";s:3:"è±¥";s:2:"àV";s:3:"豤";s:2:"àW";s:3:"豦";s:2:"àX";s:3:"貆";s:2:"àY";s:3:"貄";s:2:"àZ";s:3:"è²…";s:2:"à[";s:3:"賌";s:2:"à\";s:3:"赨";s:2:"à]";s:3:"赩";s:2:"à^";s:3:"è¶‘";s:2:"à_";s:3:"è¶Œ";s:2:"à`";s:3:"è¶Ž";s:2:"àa";s:3:"è¶";s:2:"àb";s:3:"è¶";s:2:"àc";s:3:"è¶“";s:2:"àd";s:3:"è¶”";s:2:"àe";s:3:"è¶";s:2:"àf";s:3:"è¶’";s:2:"àg";s:3:"è·°";s:2:"àh";s:3:"è· ";s:2:"ài";s:3:"è·¬";s:2:"àj";s:3:"è·±";s:2:"àk";s:3:"è·®";s:2:"àl";s:3:"è·";s:2:"àm";s:3:"è·©";s:2:"àn";s:3:"è·£";s:2:"ào";s:3:"è·¢";s:2:"àp";s:3:"è·§";s:2:"àq";s:3:"è·²";s:2:"àr";s:3:"è·«";s:2:"às";s:3:"è·´";s:2:"àt";s:3:"輆";s:2:"àu";s:3:"軿";s:2:"àv";s:3:"è¼";s:2:"àw";s:3:"è¼€";s:2:"àx";s:3:"è¼…";s:2:"ày";s:3:"輇";s:2:"àz";s:3:"輈";s:2:"à{";s:3:"輂";s:2:"à|";s:3:"輋";s:2:"à}";s:3:"é’";s:2:"à~";s:3:"逿";s:2:"à¡";s:3:"é„";s:2:"à¢";s:3:"é‰";s:2:"à£";s:3:"逽";s:2:"à¤";s:3:"é„";s:2:"à¥";s:3:"é„";s:2:"à¦";s:3:"é„";s:2:"à§";s:3:"é„‘";s:2:"à¨";s:3:"é„–";s:2:"à©";s:3:"é„”";s:2:"àª";s:3:"é„‹";s:2:"à«";s:3:"鄎";s:2:"à¬";s:3:"é…®";s:2:"à­";s:3:"é…¯";s:2:"à®";s:3:"鉈";s:2:"à¯";s:3:"鉒";s:2:"à°";s:3:"鈰";s:2:"à±";s:3:"鈺";s:2:"à²";s:3:"鉦";s:2:"à³";s:3:"鈳";s:2:"à´";s:3:"鉥";s:2:"àµ";s:3:"鉞";s:2:"à¶";s:3:"銃";s:2:"à·";s:3:"鈮";s:2:"à¸";s:3:"鉊";s:2:"à¹";s:3:"鉆";s:2:"àº";s:3:"鉭";s:2:"à»";s:3:"鉬";s:2:"à¼";s:3:"é‰";s:2:"à½";s:3:"鉠";s:2:"à¾";s:3:"鉧";s:2:"à¿";s:3:"鉯";s:2:"àÀ";s:3:"鈶";s:2:"àÁ";s:3:"鉡";s:2:"àÂ";s:3:"鉰";s:2:"àÃ";s:3:"鈱";s:2:"àÄ";s:3:"鉔";s:2:"àÅ";s:3:"鉣";s:2:"àÆ";s:3:"é‰";s:2:"àÇ";s:3:"鉲";s:2:"àÈ";s:3:"鉎";s:2:"àÉ";s:3:"鉓";s:2:"àÊ";s:3:"鉌";s:2:"àË";s:3:"鉖";s:2:"àÌ";s:3:"鈲";s:2:"àÍ";s:3:"é–Ÿ";s:2:"àÎ";s:3:"é–œ";s:2:"àÏ";s:3:"é–ž";s:2:"àÐ";s:3:"é–›";s:2:"àÑ";s:3:"éš’";s:2:"àÒ";s:3:"éš“";s:2:"àÓ";s:3:"éš‘";s:2:"àÔ";s:3:"éš—";s:2:"àÕ";s:3:"雎";s:2:"àÖ";s:3:"雺";s:2:"à×";s:3:"雽";s:2:"àØ";s:3:"雸";s:2:"àÙ";s:3:"雵";s:2:"àÚ";s:3:"é³";s:2:"àÛ";s:3:"é·";s:2:"àÜ";s:3:"é¸";s:2:"àÝ";s:3:"é²";s:2:"àÞ";s:3:"é ";s:2:"àß";s:3:"é ";s:2:"àà";s:3:"é Ž";s:2:"àá";s:3:"颬";s:2:"àâ";s:3:"飶";s:2:"àã";s:3:"飹";s:2:"àä";s:3:"馯";s:2:"àå";s:3:"馲";s:2:"àæ";s:3:"馰";s:2:"àç";s:3:"馵";s:2:"àè";s:3:"骭";s:2:"àé";s:3:"骫";s:2:"àê";s:3:"é­›";s:2:"àë";s:3:"鳪";s:2:"àì";s:3:"é³­";s:2:"àí";s:3:"é³§";s:2:"àî";s:3:"麀";s:2:"àï";s:3:"黽";s:2:"àð";s:3:"僦";s:2:"àñ";s:3:"僔";s:2:"àò";s:3:"僗";s:2:"àó";s:3:"僨";s:2:"àô";s:3:"僳";s:2:"àõ";s:3:"僛";s:2:"àö";s:3:"僪";s:2:"à÷";s:3:"åƒ";s:2:"àø";s:3:"僤";s:2:"àù";s:3:"僓";s:2:"àú";s:3:"僬";s:2:"àû";s:3:"僰";s:2:"àü";s:3:"僯";s:2:"àý";s:3:"僣";s:2:"àþ";s:3:"僠";s:2:"á@";s:3:"凘";s:2:"áA";s:3:"劀";s:2:"áB";s:3:"åŠ";s:2:"áC";s:3:"å‹©";s:2:"áD";s:3:"å‹«";s:2:"áE";s:3:"匰";s:2:"áF";s:3:"厬";s:2:"áG";s:3:"嘧";s:2:"áH";s:3:"嘕";s:2:"áI";s:3:"嘌";s:2:"áJ";s:3:"嘒";s:2:"áK";s:3:"å—¼";s:2:"áL";s:3:"å˜";s:2:"áM";s:3:"嘜";s:2:"áN";s:3:"å˜";s:2:"áO";s:3:"嘓";s:2:"áP";s:3:"嘂";s:2:"áQ";s:3:"å—º";s:2:"áR";s:3:"å˜";s:2:"áS";s:3:"嘄";s:2:"áT";s:3:"å—¿";s:2:"áU";s:3:"å—¹";s:2:"áV";s:3:"墉";s:2:"áW";s:3:"塼";s:2:"áX";s:3:"å¢";s:2:"áY";s:3:"墘";s:2:"áZ";s:3:"墆";s:2:"á[";s:3:"å¢";s:2:"á\";s:3:"å¡¿";s:2:"á]";s:3:"å¡´";s:2:"á^";s:3:"墋";s:2:"á_";s:3:"塺";s:2:"á`";s:3:"墇";s:2:"áa";s:3:"墑";s:2:"áb";s:3:"墎";s:2:"ác";s:3:"å¡¶";s:2:"ád";s:3:"墂";s:2:"áe";s:3:"墈";s:2:"áf";s:3:"å¡»";s:2:"ág";s:3:"墔";s:2:"áh";s:3:"å¢";s:2:"ái";s:3:"壾";s:2:"áj";s:3:"奫";s:2:"ák";s:3:"嫜";s:2:"ál";s:3:"å«®";s:2:"ám";s:3:"å«¥";s:2:"án";s:3:"å«•";s:2:"áo";s:3:"嫪";s:2:"áp";s:3:"嫚";s:2:"áq";s:3:"å«­";s:2:"ár";s:3:"å««";s:2:"ás";s:3:"嫳";s:2:"át";s:3:"å«¢";s:2:"áu";s:3:"å« ";s:2:"áv";s:3:"å«›";s:2:"áw";s:3:"嫬";s:2:"áx";s:3:"嫞";s:2:"áy";s:3:"å«";s:2:"áz";s:3:"å«™";s:2:"á{";s:3:"嫨";s:2:"á|";s:3:"嫟";s:2:"á}";s:3:"å­·";s:2:"á~";s:3:"寠";s:2:"á¡";s:3:"寣";s:2:"á¢";s:3:"å±£";s:2:"á£";s:3:"å¶‚";s:2:"á¤";s:3:"å¶€";s:2:"á¥";s:3:"åµ½";s:2:"á¦";s:3:"嶆";s:2:"á§";s:3:"嵺";s:2:"á¨";s:3:"å¶";s:2:"á©";s:3:"åµ·";s:2:"áª";s:3:"å¶Š";s:2:"á«";s:3:"嶉";s:2:"á¬";s:3:"嶈";s:2:"á­";s:3:"åµ¾";s:2:"á®";s:3:"åµ¼";s:2:"á¯";s:3:"å¶";s:2:"á°";s:3:"åµ¹";s:2:"á±";s:3:"嵿";s:2:"á²";s:3:"幘";s:2:"á³";s:3:"å¹™";s:2:"á´";s:3:"幓";s:2:"áµ";s:3:"廘";s:2:"á¶";s:3:"廑";s:2:"á·";s:3:"å»—";s:2:"á¸";s:3:"廎";s:2:"á¹";s:3:"廜";s:2:"áº";s:3:"廕";s:2:"á»";s:3:"å»™";s:2:"á¼";s:3:"å»’";s:2:"á½";s:3:"å»”";s:2:"á¾";s:3:"彄";s:2:"á¿";s:3:"彃";s:2:"áÀ";s:3:"彯";s:2:"áÁ";s:3:"å¾¶";s:2:"áÂ";s:3:"愬";s:2:"áÃ";s:3:"愨";s:2:"áÄ";s:3:"æ…";s:2:"áÅ";s:3:"æ…ž";s:2:"áÆ";s:3:"æ…±";s:2:"áÇ";s:3:"æ…³";s:2:"áÈ";s:3:"æ…’";s:2:"áÉ";s:3:"æ…“";s:2:"áÊ";s:3:"æ…²";s:2:"áË";s:3:"æ…¬";s:2:"áÌ";s:3:"憀";s:2:"áÍ";s:3:"æ…´";s:2:"áÎ";s:3:"æ…”";s:2:"áÏ";s:3:"æ…º";s:2:"áÐ";s:3:"æ…›";s:2:"áÑ";s:3:"æ…¥";s:2:"áÒ";s:3:"æ„»";s:2:"áÓ";s:3:"æ…ª";s:2:"áÔ";s:3:"æ…¡";s:2:"áÕ";s:3:"æ…–";s:2:"áÖ";s:3:"戩";s:2:"á×";s:3:"戧";s:2:"áØ";s:3:"戫";s:2:"áÙ";s:3:"æ«";s:2:"áÚ";s:3:"æ‘";s:2:"áÛ";s:3:"æ‘›";s:2:"áÜ";s:3:"æ‘";s:2:"áÝ";s:3:"æ‘´";s:2:"áÞ";s:3:"æ‘¶";s:2:"áß";s:3:"摲";s:2:"áà";s:3:"摳";s:2:"áá";s:3:"摽";s:2:"áâ";s:3:"摵";s:2:"áã";s:3:"摦";s:2:"áä";s:3:"æ’¦";s:2:"áå";s:3:"摎";s:2:"áæ";s:3:"æ’‚";s:2:"áç";s:3:"摞";s:2:"áè";s:3:"摜";s:2:"áé";s:3:"æ‘‹";s:2:"áê";s:3:"æ‘“";s:2:"áë";s:3:"æ‘ ";s:2:"áì";s:3:"æ‘";s:2:"áí";s:3:"æ‘¿";s:2:"áî";s:3:"æ¿";s:2:"áï";s:3:"摬";s:2:"áð";s:3:"æ‘«";s:2:"áñ";s:3:"æ‘™";s:2:"áò";s:3:"æ‘¥";s:2:"áó";s:3:"æ‘·";s:2:"áô";s:3:"敳";s:2:"áõ";s:3:"æ– ";s:2:"áö";s:3:"æš¡";s:2:"á÷";s:3:"æš ";s:2:"áø";s:3:"暟";s:2:"áù";s:3:"朅";s:2:"áú";s:3:"朄";s:2:"áû";s:3:"朢";s:2:"áü";s:3:"榱";s:2:"áý";s:3:"榶";s:2:"áþ";s:3:"槉";s:2:"â@";s:3:"榠";s:2:"âA";s:3:"æ§Ž";s:2:"âB";s:3:"榖";s:2:"âC";s:3:"榰";s:2:"âD";s:3:"榬";s:2:"âE";s:3:"榼";s:2:"âF";s:3:"榑";s:2:"âG";s:3:"榙";s:2:"âH";s:3:"榎";s:2:"âI";s:3:"榧";s:2:"âJ";s:3:"æ¦";s:2:"âK";s:3:"榩";s:2:"âL";s:3:"榾";s:2:"âM";s:3:"榯";s:2:"âN";s:3:"榿";s:2:"âO";s:3:"æ§„";s:2:"âP";s:3:"榽";s:2:"âQ";s:3:"榤";s:2:"âR";s:3:"æ§”";s:2:"âS";s:3:"榹";s:2:"âT";s:3:"æ§Š";s:2:"âU";s:3:"榚";s:2:"âV";s:3:"æ§";s:2:"âW";s:3:"榳";s:2:"âX";s:3:"榓";s:2:"âY";s:3:"榪";s:2:"âZ";s:3:"榡";s:2:"â[";s:3:"榞";s:2:"â\";s:3:"æ§™";s:2:"â]";s:3:"榗";s:2:"â^";s:3:"æ¦";s:2:"â_";s:3:"æ§‚";s:2:"â`";s:3:"榵";s:2:"âa";s:3:"榥";s:2:"âb";s:3:"槆";s:2:"âc";s:3:"æ­Š";s:2:"âd";s:3:"æ­";s:2:"âe";s:3:"æ­‹";s:2:"âf";s:3:"殞";s:2:"âg";s:3:"殟";s:2:"âh";s:3:"æ® ";s:2:"âi";s:3:"毃";s:2:"âj";s:3:"毄";s:2:"âk";s:3:"毾";s:2:"âl";s:3:"滎";s:2:"âm";s:3:"滵";s:2:"ân";s:3:"æ»±";s:2:"âo";s:3:"漃";s:2:"âp";s:3:"æ¼¥";s:2:"âq";s:3:"滸";s:2:"âr";s:3:"æ¼·";s:2:"âs";s:3:"æ»»";s:2:"ât";s:3:"æ¼®";s:2:"âu";s:3:"漉";s:2:"âv";s:3:"潎";s:2:"âw";s:3:"æ¼™";s:2:"âx";s:3:"漚";s:2:"ây";s:3:"æ¼§";s:2:"âz";s:3:"漘";s:2:"â{";s:3:"æ¼»";s:2:"â|";s:3:"æ¼’";s:2:"â}";s:3:"æ»­";s:2:"â~";s:3:"漊";s:2:"â¡";s:3:"æ¼¶";s:2:"â¢";s:3:"æ½³";s:2:"â£";s:3:"滹";s:2:"â¤";s:3:"æ»®";s:2:"â¥";s:3:"æ¼­";s:2:"â¦";s:3:"æ½€";s:2:"â§";s:3:"æ¼°";s:2:"â¨";s:3:"æ¼¼";s:2:"â©";s:3:"æ¼µ";s:2:"âª";s:3:"滫";s:2:"â«";s:3:"漇";s:2:"â¬";s:3:"漎";s:2:"â­";s:3:"潃";s:2:"â®";s:3:"æ¼…";s:2:"â¯";s:3:"滽";s:2:"â°";s:3:"æ»¶";s:2:"â±";s:3:"æ¼¹";s:2:"â²";s:3:"漜";s:2:"â³";s:3:"滼";s:2:"â´";s:3:"漺";s:2:"âµ";s:3:"漟";s:2:"â¶";s:3:"æ¼";s:2:"â·";s:3:"漞";s:2:"â¸";s:3:"漈";s:2:"â¹";s:3:"漡";s:2:"âº";s:3:"熇";s:2:"â»";s:3:"ç†";s:2:"â¼";s:3:"熉";s:2:"â½";s:3:"熀";s:2:"â¾";s:3:"熅";s:2:"â¿";s:3:"熂";s:2:"âÀ";s:3:"ç†";s:2:"âÁ";s:3:"ç…»";s:2:"âÂ";s:3:"熆";s:2:"âÃ";s:3:"ç†";s:2:"âÄ";s:3:"熗";s:2:"âÅ";s:3:"牄";s:2:"âÆ";s:3:"牓";s:2:"âÇ";s:3:"犗";s:2:"âÈ";s:3:"犕";s:2:"âÉ";s:3:"犓";s:2:"âÊ";s:3:"çƒ";s:2:"âË";s:3:"ç";s:2:"âÌ";s:3:"ç‘";s:2:"âÍ";s:3:"çŒ";s:2:"âÎ";s:3:"ç‘¢";s:2:"âÏ";s:3:"瑳";s:2:"âÐ";s:3:"瑱";s:2:"âÑ";s:3:"瑵";s:2:"âÒ";s:3:"瑲";s:2:"âÓ";s:3:"ç‘§";s:2:"âÔ";s:3:"ç‘®";s:2:"âÕ";s:3:"甀";s:2:"âÖ";s:3:"甂";s:2:"â×";s:3:"甃";s:2:"âØ";s:3:"畽";s:2:"âÙ";s:3:"ç–";s:2:"âÚ";s:3:"瘖";s:2:"âÛ";s:3:"瘈";s:2:"âÜ";s:3:"瘌";s:2:"âÝ";s:3:"瘕";s:2:"âÞ";s:3:"瘑";s:2:"âß";s:3:"瘊";s:2:"âà";s:3:"瘔";s:2:"âá";s:3:"皸";s:2:"ââ";s:3:"çž";s:2:"âã";s:3:"ç¼";s:2:"âä";s:3:"çž…";s:2:"âå";s:3:"çž‚";s:2:"âæ";s:3:"ç®";s:2:"âç";s:3:"瞀";s:2:"âè";s:3:"ç¯";s:2:"âé";s:3:"ç¾";s:2:"âê";s:3:"瞃";s:2:"âë";s:3:"碲";s:2:"âì";s:3:"碪";s:2:"âí";s:3:"碴";s:2:"âî";s:3:"碭";s:2:"âï";s:3:"碨";s:2:"âð";s:3:"硾";s:2:"âñ";s:3:"碫";s:2:"âò";s:3:"碞";s:2:"âó";s:3:"碥";s:2:"âô";s:3:"碠";s:2:"âõ";s:3:"碬";s:2:"âö";s:3:"碢";s:2:"â÷";s:3:"碤";s:2:"âø";s:3:"禘";s:2:"âù";s:3:"禊";s:2:"âú";s:3:"禋";s:2:"âû";s:3:"禖";s:2:"âü";s:3:"禕";s:2:"âý";s:3:"禔";s:2:"âþ";s:3:"禓";s:2:"ã@";s:3:"禗";s:2:"ãA";s:3:"禈";s:2:"ãB";s:3:"禒";s:2:"ãC";s:3:"ç¦";s:2:"ãD";s:3:"稫";s:2:"ãE";s:3:"穊";s:2:"ãF";s:3:"稰";s:2:"ãG";s:3:"稯";s:2:"ãH";s:3:"稨";s:2:"ãI";s:3:"稦";s:2:"ãJ";s:3:"窨";s:2:"ãK";s:3:"窫";s:2:"ãL";s:3:"窬";s:2:"ãM";s:3:"ç«®";s:2:"ãN";s:3:"箈";s:2:"ãO";s:3:"箜";s:2:"ãP";s:3:"箊";s:2:"ãQ";s:3:"箑";s:2:"ãR";s:3:"ç®";s:2:"ãS";s:3:"ç®–";s:2:"ãT";s:3:"ç®";s:2:"ãU";s:3:"箌";s:2:"ãV";s:3:"ç®›";s:2:"ãW";s:3:"箎";s:2:"ãX";s:3:"ç®…";s:2:"ãY";s:3:"箘";s:2:"ãZ";s:3:"劄";s:2:"ã[";s:3:"ç®™";s:2:"ã\";s:3:"箤";s:2:"ã]";s:3:"箂";s:2:"ã^";s:3:"ç²»";s:2:"ã_";s:3:"粿";s:2:"ã`";s:3:"ç²¼";s:2:"ãa";s:3:"粺";s:2:"ãb";s:3:"ç¶§";s:2:"ãc";s:3:"ç¶·";s:2:"ãd";s:3:"ç·‚";s:2:"ãe";s:3:"ç¶£";s:2:"ãf";s:3:"綪";s:2:"ãg";s:3:"ç·";s:2:"ãh";s:3:"ç·€";s:2:"ãi";s:3:"ç·…";s:2:"ãj";s:3:"ç¶";s:2:"ãk";s:3:"ç·Ž";s:2:"ãl";s:3:"ç·„";s:2:"ãm";s:3:"ç·†";s:2:"ãn";s:3:"ç·‹";s:2:"ão";s:3:"ç·Œ";s:2:"ãp";s:3:"綯";s:2:"ãq";s:3:"ç¶¹";s:2:"ãr";s:3:"ç¶–";s:2:"ãs";s:3:"ç¶¼";s:2:"ãt";s:3:"ç¶Ÿ";s:2:"ãu";s:3:"綦";s:2:"ãv";s:3:"ç¶®";s:2:"ãw";s:3:"ç¶©";s:2:"ãx";s:3:"ç¶¡";s:2:"ãy";s:3:"ç·‰";s:2:"ãz";s:3:"ç½³";s:2:"ã{";s:3:"ç¿¢";s:2:"ã|";s:3:"ç¿£";s:2:"ã}";s:3:"ç¿¥";s:2:"ã~";s:3:"翞";s:2:"ã¡";s:3:"耤";s:2:"ã¢";s:3:"è";s:2:"ã£";s:3:"èœ";s:2:"ã¤";s:3:"膉";s:2:"ã¥";s:3:"膆";s:2:"ã¦";s:3:"膃";s:2:"ã§";s:3:"膇";s:2:"ã¨";s:3:"è†";s:2:"ã©";s:3:"膌";s:2:"ãª";s:3:"膋";s:2:"ã«";s:3:"舕";s:2:"ã¬";s:3:"è’—";s:2:"ã­";s:3:"è’¤";s:2:"ã®";s:3:"è’¡";s:2:"ã¯";s:3:"è’Ÿ";s:2:"ã°";s:3:"è’º";s:2:"ã±";s:3:"蓎";s:2:"ã²";s:3:"è“‚";s:2:"ã³";s:3:"è’¬";s:2:"ã´";s:3:"è’®";s:2:"ãµ";s:3:"è’«";s:2:"ã¶";s:3:"è’¹";s:2:"ã·";s:3:"è’´";s:2:"ã¸";s:3:"è“";s:2:"ã¹";s:3:"è“";s:2:"ãº";s:3:"è’ª";s:2:"ã»";s:3:"è’š";s:2:"ã¼";s:3:"è’±";s:2:"ã½";s:3:"è“";s:2:"ã¾";s:3:"è’";s:2:"ã¿";s:3:"è’§";s:2:"ãÀ";s:3:"è’»";s:2:"ãÁ";s:3:"è’¢";s:2:"ãÂ";s:3:"è’”";s:2:"ãÃ";s:3:"蓇";s:2:"ãÄ";s:3:"蓌";s:2:"ãÅ";s:3:"è’›";s:2:"ãÆ";s:3:"è’©";s:2:"ãÇ";s:3:"è’¯";s:2:"ãÈ";s:3:"è’¨";s:2:"ãÉ";s:3:"è“–";s:2:"ãÊ";s:3:"è’˜";s:2:"ãË";s:3:"è’¶";s:2:"ãÌ";s:3:"è“";s:2:"ãÍ";s:3:"è’ ";s:2:"ãÎ";s:3:"è“—";s:2:"ãÏ";s:3:"è“”";s:2:"ãÐ";s:3:"è“’";s:2:"ãÑ";s:3:"è“›";s:2:"ãÒ";s:3:"è’°";s:2:"ãÓ";s:3:"è’‘";s:2:"ãÔ";s:3:"虡";s:2:"ãÕ";s:3:"蜳";s:2:"ãÖ";s:3:"蜣";s:2:"ã×";s:3:"蜨";s:2:"ãØ";s:3:"è«";s:2:"ãÙ";s:3:"è€";s:2:"ãÚ";s:3:"蜮";s:2:"ãÛ";s:3:"蜞";s:2:"ãÜ";s:3:"蜡";s:2:"ãÝ";s:3:"蜙";s:2:"ãÞ";s:3:"蜛";s:2:"ãß";s:3:"èƒ";s:2:"ãà";s:3:"蜬";s:2:"ãá";s:3:"è";s:2:"ãâ";s:3:"蜾";s:2:"ãã";s:3:"è†";s:2:"ãä";s:3:"蜠";s:2:"ãå";s:3:"蜲";s:2:"ãæ";s:3:"蜪";s:2:"ãç";s:3:"蜭";s:2:"ãè";s:3:"蜼";s:2:"ãé";s:3:"蜒";s:2:"ãê";s:3:"蜺";s:2:"ãë";s:3:"蜱";s:2:"ãì";s:3:"蜵";s:2:"ãí";s:3:"è‚";s:2:"ãî";s:3:"蜦";s:2:"ãï";s:3:"蜧";s:2:"ãð";s:3:"蜸";s:2:"ãñ";s:3:"蜤";s:2:"ãò";s:3:"蜚";s:2:"ãó";s:3:"蜰";s:2:"ãô";s:3:"蜑";s:2:"ãõ";s:3:"裷";s:2:"ãö";s:3:"裧";s:2:"ã÷";s:3:"裱";s:2:"ãø";s:3:"裲";s:2:"ãù";s:3:"裺";s:2:"ãú";s:3:"裾";s:2:"ãû";s:3:"裮";s:2:"ãü";s:3:"裼";s:2:"ãý";s:3:"裶";s:2:"ãþ";s:3:"裻";s:2:"ä@";s:3:"裰";s:2:"äA";s:3:"裬";s:2:"äB";s:3:"裫";s:2:"äC";s:3:"è¦";s:2:"äD";s:3:"覡";s:2:"äE";s:3:"覟";s:2:"äF";s:3:"覞";s:2:"äG";s:3:"è§©";s:2:"äH";s:3:"è§«";s:2:"äI";s:3:"觨";s:2:"äJ";s:3:"誫";s:2:"äK";s:3:"誙";s:2:"äL";s:3:"誋";s:2:"äM";s:3:"誒";s:2:"äN";s:3:"èª";s:2:"äO";s:3:"誖";s:2:"äP";s:3:"è°½";s:2:"äQ";s:3:"豨";s:2:"äR";s:3:"豩";s:2:"äS";s:3:"賕";s:2:"äT";s:3:"è³";s:2:"äU";s:3:"è³—";s:2:"äV";s:3:"è¶–";s:2:"äW";s:3:"踉";s:2:"äX";s:3:"踂";s:2:"äY";s:3:"è·¿";s:2:"äZ";s:3:"è¸";s:2:"ä[";s:3:"è·½";s:2:"ä\";s:3:"踊";s:2:"ä]";s:3:"踃";s:2:"ä^";s:3:"踇";s:2:"ä_";s:3:"踆";s:2:"ä`";s:3:"踅";s:2:"äa";s:3:"è·¾";s:2:"äb";s:3:"踀";s:2:"äc";s:3:"踄";s:2:"äd";s:3:"è¼";s:2:"äe";s:3:"輑";s:2:"äf";s:3:"輎";s:2:"äg";s:3:"è¼";s:2:"äh";s:3:"é„£";s:2:"äi";s:3:"鄜";s:2:"äj";s:3:"é„ ";s:2:"äk";s:3:"é„¢";s:2:"äl";s:3:"鄟";s:2:"äm";s:3:"é„";s:2:"än";s:3:"鄚";s:2:"äo";s:3:"鄤";s:2:"äp";s:3:"é„¡";s:2:"äq";s:3:"é„›";s:2:"är";s:3:"é…º";s:2:"äs";s:3:"é…²";s:2:"ät";s:3:"é…¹";s:2:"äu";s:3:"é…³";s:2:"äv";s:3:"銥";s:2:"äw";s:3:"銤";s:2:"äx";s:3:"鉶";s:2:"äy";s:3:"銛";s:2:"äz";s:3:"鉺";s:2:"ä{";s:3:"銠";s:2:"ä|";s:3:"銔";s:2:"ä}";s:3:"銪";s:2:"ä~";s:3:"éŠ";s:2:"ä¡";s:3:"銦";s:2:"ä¢";s:3:"銚";s:2:"ä£";s:3:"銫";s:2:"ä¤";s:3:"鉹";s:2:"ä¥";s:3:"銗";s:2:"ä¦";s:3:"鉿";s:2:"ä§";s:3:"銣";s:2:"ä¨";s:3:"é‹®";s:2:"ä©";s:3:"銎";s:2:"äª";s:3:"銂";s:2:"ä«";s:3:"銕";s:2:"ä¬";s:3:"銢";s:2:"ä­";s:3:"鉽";s:2:"ä®";s:3:"銈";s:2:"ä¯";s:3:"銡";s:2:"ä°";s:3:"銊";s:2:"ä±";s:3:"銆";s:2:"ä²";s:3:"銌";s:2:"ä³";s:3:"銙";s:2:"ä´";s:3:"銧";s:2:"äµ";s:3:"鉾";s:2:"ä¶";s:3:"銇";s:2:"ä·";s:3:"銩";s:2:"ä¸";s:3:"éŠ";s:2:"ä¹";s:3:"銋";s:2:"äº";s:3:"鈭";s:2:"ä»";s:3:"éšž";s:2:"ä¼";s:3:"éš¡";s:2:"ä½";s:3:"雿";s:2:"ä¾";s:3:"é˜";s:2:"ä¿";s:3:"é½";s:2:"äÀ";s:3:"éº";s:2:"äÁ";s:3:"é¾";s:2:"äÂ";s:3:"鞃";s:2:"äÃ";s:3:"鞀";s:2:"äÄ";s:3:"éž‚";s:2:"äÅ";s:3:"é»";s:2:"äÆ";s:3:"éž„";s:2:"äÇ";s:3:"éž";s:2:"äÈ";s:3:"é¿";s:2:"äÉ";s:3:"韎";s:2:"äÊ";s:3:"éŸ";s:2:"äË";s:3:"é –";s:2:"äÌ";s:3:"颭";s:2:"äÍ";s:3:"颮";s:2:"äÎ";s:3:"餂";s:2:"äÏ";s:3:"餀";s:2:"äÐ";s:3:"餇";s:2:"äÑ";s:3:"é¦";s:2:"äÒ";s:3:"馜";s:2:"äÓ";s:3:"駃";s:2:"äÔ";s:3:"馹";s:2:"äÕ";s:3:"馻";s:2:"äÖ";s:3:"馺";s:2:"ä×";s:3:"é§‚";s:2:"äØ";s:3:"馽";s:2:"äÙ";s:3:"駇";s:2:"äÚ";s:3:"骱";s:2:"äÛ";s:3:"é«£";s:2:"äÜ";s:3:"é«§";s:2:"äÝ";s:3:"鬾";s:2:"äÞ";s:3:"鬿";s:2:"äß";s:3:"é­ ";s:2:"äà";s:3:"é­¡";s:2:"äá";s:3:"é­Ÿ";s:2:"äâ";s:3:"é³±";s:2:"äã";s:3:"é³²";s:2:"ää";s:3:"é³µ";s:2:"äå";s:3:"麧";s:2:"äæ";s:3:"僿";s:2:"äç";s:3:"儃";s:2:"äè";s:3:"å„°";s:2:"äé";s:3:"僸";s:2:"äê";s:3:"儆";s:2:"äë";s:3:"儇";s:2:"äì";s:3:"僶";s:2:"äí";s:3:"僾";s:2:"äî";s:3:"å„‹";s:2:"äï";s:3:"儌";s:2:"äð";s:3:"僽";s:2:"äñ";s:3:"儊";s:2:"äò";s:3:"劋";s:2:"äó";s:3:"劌";s:2:"äô";s:3:"勱";s:2:"äõ";s:3:"勯";s:2:"äö";s:3:"噈";s:2:"ä÷";s:3:"噂";s:2:"äø";s:3:"噌";s:2:"äù";s:3:"嘵";s:2:"äú";s:3:"å™";s:2:"äû";s:3:"噊";s:2:"äü";s:3:"噉";s:2:"äý";s:3:"噆";s:2:"äþ";s:3:"噘";s:2:"å@";s:3:"噚";s:2:"åA";s:3:"噀";s:2:"åB";s:3:"嘳";s:2:"åC";s:3:"嘽";s:2:"åD";s:3:"嘬";s:2:"åE";s:3:"嘾";s:2:"åF";s:3:"嘸";s:2:"åG";s:3:"嘪";s:2:"åH";s:3:"嘺";s:2:"åI";s:3:"圚";s:2:"åJ";s:3:"墫";s:2:"åK";s:3:"å¢";s:2:"åL";s:3:"墱";s:2:"åM";s:3:"墠";s:2:"åN";s:3:"墣";s:2:"åO";s:3:"墯";s:2:"åP";s:3:"墬";s:2:"åQ";s:3:"墥";s:2:"åR";s:3:"墡";s:2:"åS";s:3:"壿";s:2:"åT";s:3:"å«¿";s:2:"åU";s:3:"å«´";s:2:"åV";s:3:"嫽";s:2:"åW";s:3:"å«·";s:2:"åX";s:3:"å«¶";s:2:"åY";s:3:"嬃";s:2:"åZ";s:3:"嫸";s:2:"å[";s:3:"嬂";s:2:"å\";s:3:"嫹";s:2:"å]";s:3:"å¬";s:2:"å^";s:3:"嬇";s:2:"å_";s:3:"嬅";s:2:"å`";s:3:"å¬";s:2:"åa";s:3:"å±§";s:2:"åb";s:3:"å¶™";s:2:"åc";s:3:"å¶—";s:2:"åd";s:3:"å¶Ÿ";s:2:"åe";s:3:"å¶’";s:2:"åf";s:3:"å¶¢";s:2:"åg";s:3:"å¶“";s:2:"åh";s:3:"å¶•";s:2:"åi";s:3:"å¶ ";s:2:"åj";s:3:"å¶œ";s:2:"åk";s:3:"å¶¡";s:2:"ål";s:3:"å¶š";s:2:"åm";s:3:"å¶ž";s:2:"ån";s:3:"幩";s:2:"åo";s:3:"å¹";s:2:"åp";s:3:"å¹ ";s:2:"åq";s:3:"幜";s:2:"år";s:3:"ç·³";s:2:"ås";s:3:"å»›";s:2:"åt";s:3:"廞";s:2:"åu";s:3:"廡";s:2:"åv";s:3:"彉";s:2:"åw";s:3:"å¾²";s:2:"åx";s:3:"憋";s:2:"åy";s:3:"憃";s:2:"åz";s:3:"æ…¹";s:2:"å{";s:3:"憱";s:2:"å|";s:3:"憰";s:2:"å}";s:3:"憢";s:2:"å~";s:3:"憉";s:2:"å¡";s:3:"憛";s:2:"å¢";s:3:"憓";s:2:"å£";s:3:"憯";s:2:"å¤";s:3:"憭";s:2:"å¥";s:3:"憟";s:2:"å¦";s:3:"憒";s:2:"å§";s:3:"憪";s:2:"å¨";s:3:"憡";s:2:"å©";s:3:"æ†";s:2:"åª";s:3:"æ…¦";s:2:"å«";s:3:"憳";s:2:"å¬";s:3:"戭";s:2:"å­";s:3:"æ‘®";s:2:"å®";s:3:"æ‘°";s:2:"å¯";s:3:"æ’–";s:2:"å°";s:3:"æ’ ";s:2:"å±";s:3:"æ’…";s:2:"å²";s:3:"æ’—";s:2:"å³";s:3:"æ’œ";s:2:"å´";s:3:"æ’";s:2:"åµ";s:3:"æ’‹";s:2:"å¶";s:3:"æ’Š";s:2:"å·";s:3:"æ’Œ";s:2:"å¸";s:3:"æ’£";s:2:"å¹";s:3:"æ’Ÿ";s:2:"åº";s:3:"摨";s:2:"å»";s:3:"æ’±";s:2:"å¼";s:3:"æ’˜";s:2:"å½";s:3:"æ•¶";s:2:"å¾";s:3:"敺";s:2:"å¿";s:3:"敹";s:2:"åÀ";s:3:"æ•»";s:2:"åÁ";s:3:"æ–²";s:2:"åÂ";s:3:"æ–³";s:2:"åÃ";s:3:"æšµ";s:2:"åÄ";s:3:"æš°";s:2:"åÅ";s:3:"æš©";s:2:"åÆ";s:3:"æš²";s:2:"åÇ";s:3:"æš·";s:2:"åÈ";s:3:"暪";s:2:"åÉ";s:3:"暯";s:2:"åÊ";s:3:"樀";s:2:"åË";s:3:"樆";s:2:"åÌ";s:3:"樗";s:2:"åÍ";s:3:"æ§¥";s:2:"åÎ";s:3:"槸";s:2:"åÏ";s:3:"樕";s:2:"åÐ";s:3:"æ§±";s:2:"åÑ";s:3:"槤";s:2:"åÒ";s:3:"樠";s:2:"åÓ";s:3:"æ§¿";s:2:"åÔ";s:3:"槬";s:2:"åÕ";s:3:"æ§¢";s:2:"åÖ";s:3:"樛";s:2:"å×";s:3:"æ¨";s:2:"åØ";s:3:"æ§¾";s:2:"åÙ";s:3:"樧";s:2:"åÚ";s:3:"æ§²";s:2:"åÛ";s:3:"æ§®";s:2:"åÜ";s:3:"樔";s:2:"åÝ";s:3:"æ§·";s:2:"åÞ";s:3:"æ§§";s:2:"åß";s:3:"æ©€";s:2:"åà";s:3:"樈";s:2:"åá";s:3:"槦";s:2:"åâ";s:3:"æ§»";s:2:"åã";s:3:"æ¨";s:2:"åä";s:3:"æ§¼";s:2:"åå";s:3:"æ§«";s:2:"åæ";s:3:"樉";s:2:"åç";s:3:"樄";s:2:"åè";s:3:"樘";s:2:"åé";s:3:"樥";s:2:"åê";s:3:"æ¨";s:2:"åë";s:3:"æ§¶";s:2:"åì";s:3:"樦";s:2:"åí";s:3:"樇";s:2:"åî";s:3:"æ§´";s:2:"åï";s:3:"樖";s:2:"åð";s:3:"æ­‘";s:2:"åñ";s:3:"殥";s:2:"åò";s:3:"殣";s:2:"åó";s:3:"殢";s:2:"åô";s:3:"殦";s:2:"åõ";s:3:"æ°";s:2:"åö";s:3:"æ°€";s:2:"å÷";s:3:"毿";s:2:"åø";s:3:"æ°‚";s:2:"åù";s:3:"æ½";s:2:"åú";s:3:"漦";s:2:"åû";s:3:"æ½¾";s:2:"åü";s:3:"澇";s:2:"åý";s:3:"濆";s:2:"åþ";s:3:"æ¾’";s:2:"æ@";s:3:"æ¾";s:2:"æA";s:3:"澉";s:2:"æB";s:3:"澌";s:2:"æC";s:3:"æ½¢";s:2:"æD";s:3:"æ½";s:2:"æE";s:3:"æ¾…";s:2:"æF";s:3:"潚";s:2:"æG";s:3:"æ¾–";s:2:"æH";s:3:"æ½¶";s:2:"æI";s:3:"潬";s:2:"æJ";s:3:"澂";s:2:"æK";s:3:"潕";s:2:"æL";s:3:"æ½²";s:2:"æM";s:3:"æ½’";s:2:"æN";s:3:"æ½";s:2:"æO";s:3:"æ½—";s:2:"æP";s:3:"æ¾”";s:2:"æQ";s:3:"澓";s:2:"æR";s:3:"æ½";s:2:"æS";s:3:"æ¼€";s:2:"æT";s:3:"潡";s:2:"æU";s:3:"潫";s:2:"æV";s:3:"æ½½";s:2:"æW";s:3:"æ½§";s:2:"æX";s:3:"æ¾";s:2:"æY";s:3:"潓";s:2:"æZ";s:3:"澋";s:2:"æ[";s:3:"潩";s:2:"æ\";s:3:"潿";s:2:"æ]";s:3:"澕";s:2:"æ^";s:3:"æ½£";s:2:"æ_";s:3:"æ½·";s:2:"æ`";s:3:"潪";s:2:"æa";s:3:"æ½»";s:2:"æb";s:3:"熲";s:2:"æc";s:3:"熯";s:2:"æd";s:3:"熛";s:2:"æe";s:3:"熰";s:2:"æf";s:3:"熠";s:2:"æg";s:3:"熚";s:2:"æh";s:3:"熩";s:2:"æi";s:3:"熵";s:2:"æj";s:3:"ç†";s:2:"æk";s:3:"熥";s:2:"æl";s:3:"熞";s:2:"æm";s:3:"熤";s:2:"æn";s:3:"熡";s:2:"æo";s:3:"熪";s:2:"æp";s:3:"熜";s:2:"æq";s:3:"熧";s:2:"ær";s:3:"熳";s:2:"æs";s:3:"犘";s:2:"æt";s:3:"犚";s:2:"æu";s:3:"ç˜";s:2:"æv";s:3:"ç’";s:2:"æw";s:3:"çž";s:2:"æx";s:3:"çŸ";s:2:"æy";s:3:"ç ";s:2:"æz";s:3:"ç";s:2:"æ{";s:3:"ç›";s:2:"æ|";s:3:"ç¡";s:2:"æ}";s:3:"çš";s:2:"æ~";s:3:"ç™";s:2:"æ¡";s:3:"ç¢";s:2:"æ¢";s:3:"ç’‡";s:2:"æ£";s:3:"ç’‰";s:2:"æ¤";s:3:"ç’Š";s:2:"æ¥";s:3:"ç’†";s:2:"æ¦";s:3:"ç’";s:2:"æ§";s:3:"瑽";s:2:"æ¨";s:3:"ç’…";s:2:"æ©";s:3:"ç’ˆ";s:2:"æª";s:3:"瑼";s:2:"æ«";s:3:"瑹";s:2:"æ¬";s:3:"甈";s:2:"æ­";s:3:"甇";s:2:"æ®";s:3:"畾";s:2:"æ¯";s:3:"瘥";s:2:"æ°";s:3:"瘞";s:2:"æ±";s:3:"瘙";s:2:"æ²";s:3:"ç˜";s:2:"æ³";s:3:"瘜";s:2:"æ´";s:3:"瘣";s:2:"æµ";s:3:"瘚";s:2:"æ¶";s:3:"瘨";s:2:"æ·";s:3:"瘛";s:2:"æ¸";s:3:"çšœ";s:2:"æ¹";s:3:"çš";s:2:"æº";s:3:"çšž";s:2:"æ»";s:3:"çš›";s:2:"æ¼";s:3:"çž";s:2:"æ½";s:3:"çž";s:2:"æ¾";s:3:"瞉";s:2:"æ¿";s:3:"瞈";s:2:"æÀ";s:3:"ç£";s:2:"æÁ";s:3:"碻";s:2:"æÂ";s:3:"ç£";s:2:"æÃ";s:3:"磌";s:2:"æÄ";s:3:"磑";s:2:"æÅ";s:3:"磎";s:2:"æÆ";s:3:"磔";s:2:"æÇ";s:3:"磈";s:2:"æÈ";s:3:"磃";s:2:"æÉ";s:3:"磄";s:2:"æÊ";s:3:"磉";s:2:"æË";s:3:"禚";s:2:"æÌ";s:3:"禡";s:2:"æÍ";s:3:"禠";s:2:"æÎ";s:3:"禜";s:2:"æÏ";s:3:"禢";s:2:"æÐ";s:3:"禛";s:2:"æÑ";s:3:"æ­¶";s:2:"æÒ";s:3:"稹";s:2:"æÓ";s:3:"窲";s:2:"æÔ";s:3:"窴";s:2:"æÕ";s:3:"窳";s:2:"æÖ";s:3:"ç®·";s:2:"æ×";s:3:"篋";s:2:"æØ";s:3:"箾";s:2:"æÙ";s:3:"箬";s:2:"æÚ";s:3:"篎";s:2:"æÛ";s:3:"箯";s:2:"æÜ";s:3:"箹";s:2:"æÝ";s:3:"篊";s:2:"æÞ";s:3:"箵";s:2:"æß";s:3:"ç³…";s:2:"æà";s:3:"糈";s:2:"æá";s:3:"糌";s:2:"æâ";s:3:"糋";s:2:"æã";s:3:"ç··";s:2:"æä";s:3:"ç·›";s:2:"æå";s:3:"ç·ª";s:2:"ææ";s:3:"ç·§";s:2:"æç";s:3:"ç·—";s:2:"æè";s:3:"ç·¡";s:2:"æé";s:3:"縃";s:2:"æê";s:3:"ç·º";s:2:"æë";s:3:"ç·¦";s:2:"æì";s:3:"ç·¶";s:2:"æí";s:3:"ç·±";s:2:"æî";s:3:"ç·°";s:2:"æï";s:3:"ç·®";s:2:"æð";s:3:"ç·Ÿ";s:2:"æñ";s:3:"ç½¶";s:2:"æò";s:3:"羬";s:2:"æó";s:3:"ç¾°";s:2:"æô";s:3:"ç¾­";s:2:"æõ";s:3:"ç¿­";s:2:"æö";s:3:"ç¿«";s:2:"æ÷";s:3:"翪";s:2:"æø";s:3:"翬";s:2:"æù";s:3:"翦";s:2:"æú";s:3:"翨";s:2:"æû";s:3:"è¤";s:2:"æü";s:3:"è§";s:2:"æý";s:3:"膣";s:2:"æþ";s:3:"膟";s:2:"ç@";s:3:"膞";s:2:"çA";s:3:"膕";s:2:"çB";s:3:"膢";s:2:"çC";s:3:"膙";s:2:"çD";s:3:"膗";s:2:"çE";s:3:"舖";s:2:"çF";s:3:"è‰";s:2:"çG";s:3:"艓";s:2:"çH";s:3:"艒";s:2:"çI";s:3:"è‰";s:2:"çJ";s:3:"艎";s:2:"çK";s:3:"艑";s:2:"çL";s:3:"蔤";s:2:"çM";s:3:"è”»";s:2:"çN";s:3:"è”";s:2:"çO";s:3:"蔀";s:2:"çP";s:3:"蔩";s:2:"çQ";s:3:"蔎";s:2:"çR";s:3:"蔉";s:2:"çS";s:3:"è”";s:2:"çT";s:3:"蔟";s:2:"çU";s:3:"蔊";s:2:"çV";s:3:"è”§";s:2:"çW";s:3:"蔜";s:2:"çX";s:3:"è“»";s:2:"çY";s:3:"蔫";s:2:"çZ";s:3:"蓺";s:2:"ç[";s:3:"蔈";s:2:"ç\";s:3:"蔌";s:2:"ç]";s:3:"è“´";s:2:"ç^";s:3:"蔪";s:2:"ç_";s:3:"蓲";s:2:"ç`";s:3:"蔕";s:2:"ça";s:3:"è“·";s:2:"çb";s:3:"è“«";s:2:"çc";s:3:"蓳";s:2:"çd";s:3:"蓼";s:2:"çe";s:3:"è”’";s:2:"çf";s:3:"蓪";s:2:"çg";s:3:"è“©";s:2:"çh";s:3:"è”–";s:2:"çi";s:3:"蓾";s:2:"çj";s:3:"蔨";s:2:"çk";s:3:"è”";s:2:"çl";s:3:"è”®";s:2:"çm";s:3:"蔂";s:2:"çn";s:3:"蓽";s:2:"ço";s:3:"蔞";s:2:"çp";s:3:"è“¶";s:2:"çq";s:3:"è”±";s:2:"çr";s:3:"蔦";s:2:"çs";s:3:"è“§";s:2:"çt";s:3:"蓨";s:2:"çu";s:3:"è“°";s:2:"çv";s:3:"蓯";s:2:"çw";s:3:"蓹";s:2:"çx";s:3:"蔘";s:2:"çy";s:3:"è” ";s:2:"çz";s:3:"è”°";s:2:"ç{";s:3:"蔋";s:2:"ç|";s:3:"è”™";s:2:"ç}";s:3:"蔯";s:2:"ç~";s:3:"虢";s:2:"ç¡";s:3:"è–";s:2:"ç¢";s:3:"è£";s:2:"ç£";s:3:"è¤";s:2:"ç¤";s:3:"è·";s:2:"ç¥";s:3:"蟡";s:2:"ç¦";s:3:"è³";s:2:"ç§";s:3:"è˜";s:2:"ç¨";s:3:"è”";s:2:"ç©";s:3:"è›";s:2:"çª";s:3:"è’";s:2:"ç«";s:3:"è¡";s:2:"ç¬";s:3:"èš";s:2:"ç­";s:3:"è‘";s:2:"ç®";s:3:"èž";s:2:"ç¯";s:3:"è­";s:2:"ç°";s:3:"èª";s:2:"ç±";s:3:"è";s:2:"ç²";s:3:"èŽ";s:2:"ç³";s:3:"èŸ";s:2:"ç´";s:3:"è";s:2:"çµ";s:3:"è¯";s:2:"ç¶";s:3:"è¬";s:2:"ç·";s:3:"èº";s:2:"ç¸";s:3:"è®";s:2:"ç¹";s:3:"èœ";s:2:"çº";s:3:"è¥";s:2:"ç»";s:3:"è";s:2:"ç¼";s:3:"è»";s:2:"ç½";s:3:"èµ";s:2:"ç¾";s:3:"è¢";s:2:"ç¿";s:3:"è§";s:2:"çÀ";s:3:"è©";s:2:"çÁ";s:3:"衚";s:2:"çÂ";s:3:"褅";s:2:"çÃ";s:3:"褌";s:2:"çÄ";s:3:"褔";s:2:"çÅ";s:3:"褋";s:2:"çÆ";s:3:"褗";s:2:"çÇ";s:3:"褘";s:2:"çÈ";s:3:"褙";s:2:"çÉ";s:3:"褆";s:2:"çÊ";s:3:"褖";s:2:"çË";s:3:"褑";s:2:"çÌ";s:3:"褎";s:2:"çÍ";s:3:"褉";s:2:"çÎ";s:3:"覢";s:2:"çÏ";s:3:"覤";s:2:"çÐ";s:3:"覣";s:2:"çÑ";s:3:"è§­";s:2:"çÒ";s:3:"è§°";s:2:"çÓ";s:3:"觬";s:2:"çÔ";s:3:"è«";s:2:"çÕ";s:3:"諆";s:2:"çÖ";s:3:"誸";s:2:"ç×";s:3:"è«“";s:2:"çØ";s:3:"è«‘";s:2:"çÙ";s:3:"è«”";s:2:"çÚ";s:3:"è«•";s:2:"çÛ";s:3:"誻";s:2:"çÜ";s:3:"è«—";s:2:"çÝ";s:3:"誾";s:2:"çÞ";s:3:"è«€";s:2:"çß";s:3:"è«…";s:2:"çà";s:3:"諘";s:2:"çá";s:3:"諃";s:2:"çâ";s:3:"誺";s:2:"çã";s:3:"誽";s:2:"çä";s:3:"è«™";s:2:"çå";s:3:"è°¾";s:2:"çæ";s:3:"è±";s:2:"çç";s:3:"è²";s:2:"çè";s:3:"è³¥";s:2:"çé";s:3:"賟";s:2:"çê";s:3:"è³™";s:2:"çë";s:3:"賨";s:2:"çì";s:3:"賚";s:2:"çí";s:3:"è³";s:2:"çî";s:3:"è³§";s:2:"çï";s:3:"è¶ ";s:2:"çð";s:3:"è¶œ";s:2:"çñ";s:3:"è¶¡";s:2:"çò";s:3:"è¶›";s:2:"çó";s:3:"踠";s:2:"çô";s:3:"踣";s:2:"çõ";s:3:"踥";s:2:"çö";s:3:"踤";s:2:"ç÷";s:3:"踮";s:2:"çø";s:3:"踕";s:2:"çù";s:3:"踛";s:2:"çú";s:3:"踖";s:2:"çû";s:3:"踑";s:2:"çü";s:3:"踙";s:2:"çý";s:3:"踦";s:2:"çþ";s:3:"踧";s:2:"è@";s:3:"踔";s:2:"èA";s:3:"踒";s:2:"èB";s:3:"踘";s:2:"èC";s:3:"踓";s:2:"èD";s:3:"踜";s:2:"èE";s:3:"踗";s:2:"èF";s:3:"踚";s:2:"èG";s:3:"輬";s:2:"èH";s:3:"輤";s:2:"èI";s:3:"輘";s:2:"èJ";s:3:"輚";s:2:"èK";s:3:"è¼ ";s:2:"èL";s:3:"è¼£";s:2:"èM";s:3:"è¼–";s:2:"èN";s:3:"è¼—";s:2:"èO";s:3:"é³";s:2:"èP";s:3:"é°";s:2:"èQ";s:3:"é¯";s:2:"èR";s:3:"é§";s:2:"èS";s:3:"é«";s:2:"èT";s:3:"鄯";s:2:"èU";s:3:"é„«";s:2:"èV";s:3:"é„©";s:2:"èW";s:3:"鄪";s:2:"èX";s:3:"鄲";s:2:"èY";s:3:"鄦";s:2:"èZ";s:3:"é„®";s:2:"è[";s:3:"醅";s:2:"è\";s:3:"醆";s:2:"è]";s:3:"醊";s:2:"è^";s:3:"é†";s:2:"è_";s:3:"醂";s:2:"è`";s:3:"醄";s:2:"èa";s:3:"醀";s:2:"èb";s:3:"é‹";s:2:"èc";s:3:"鋃";s:2:"èd";s:3:"é‹„";s:2:"èe";s:3:"é‹€";s:2:"èf";s:3:"é‹™";s:2:"èg";s:3:"銶";s:2:"èh";s:3:"é‹";s:2:"èi";s:3:"鋱";s:2:"èj";s:3:"鋟";s:2:"èk";s:3:"鋘";s:2:"èl";s:3:"é‹©";s:2:"èm";s:3:"é‹—";s:2:"èn";s:3:"é‹";s:2:"èo";s:3:"鋌";s:2:"èp";s:3:"鋯";s:2:"èq";s:3:"é‹‚";s:2:"èr";s:3:"鋨";s:2:"ès";s:3:"鋊";s:2:"èt";s:3:"鋈";s:2:"èu";s:3:"鋎";s:2:"èv";s:3:"鋦";s:2:"èw";s:3:"é‹";s:2:"èx";s:3:"é‹•";s:2:"èy";s:3:"鋉";s:2:"èz";s:3:"é‹ ";s:2:"è{";s:3:"鋞";s:2:"è|";s:3:"é‹§";s:2:"è}";s:3:"é‹‘";s:2:"è~";s:3:"é‹“";s:2:"è¡";s:3:"銵";s:2:"è¢";s:3:"é‹¡";s:2:"è£";s:3:"鋆";s:2:"è¤";s:3:"銴";s:2:"è¥";s:3:"镼";s:2:"è¦";s:3:"é–¬";s:2:"è§";s:3:"é–«";s:2:"è¨";s:3:"é–®";s:2:"è©";s:3:"é–°";s:2:"èª";s:3:"隤";s:2:"è«";s:3:"隢";s:2:"è¬";s:3:"雓";s:2:"è­";s:3:"霅";s:2:"è®";s:3:"霈";s:2:"è¯";s:3:"霂";s:2:"è°";s:3:"éš";s:2:"è±";s:3:"鞊";s:2:"è²";s:3:"鞎";s:2:"è³";s:3:"鞈";s:2:"è´";s:3:"éŸ";s:2:"èµ";s:3:"éŸ";s:2:"è¶";s:3:"é ž";s:2:"è·";s:3:"é ";s:2:"è¸";s:3:"é ¦";s:2:"è¹";s:3:"é ©";s:2:"èº";s:3:"é ¨";s:2:"è»";s:3:"é  ";s:2:"è¼";s:3:"é ›";s:2:"è½";s:3:"é §";s:2:"è¾";s:3:"颲";s:2:"è¿";s:3:"餈";s:2:"èÀ";s:3:"飺";s:2:"èÁ";s:3:"餑";s:2:"èÂ";s:3:"餔";s:2:"èÃ";s:3:"餖";s:2:"èÄ";s:3:"餗";s:2:"èÅ";s:3:"餕";s:2:"èÆ";s:3:"é§œ";s:2:"èÇ";s:3:"é§";s:2:"èÈ";s:3:"é§";s:2:"èÉ";s:3:"é§“";s:2:"èÊ";s:3:"é§”";s:2:"èË";s:3:"é§Ž";s:2:"èÌ";s:3:"駉";s:2:"èÍ";s:3:"é§–";s:2:"èÎ";s:3:"駘";s:2:"èÏ";s:3:"é§‹";s:2:"èÐ";s:3:"é§—";s:2:"èÑ";s:3:"é§Œ";s:2:"èÒ";s:3:"骳";s:2:"èÓ";s:3:"髬";s:2:"èÔ";s:3:"é««";s:2:"èÕ";s:3:"髳";s:2:"èÖ";s:3:"髲";s:2:"è×";s:3:"髱";s:2:"èØ";s:3:"é­†";s:2:"èÙ";s:3:"é­ƒ";s:2:"èÚ";s:3:"é­§";s:2:"èÛ";s:3:"é­´";s:2:"èÜ";s:3:"é­±";s:2:"èÝ";s:3:"é­¦";s:2:"èÞ";s:3:"é­¶";s:2:"èß";s:3:"é­µ";s:2:"èà";s:3:"é­°";s:2:"èá";s:3:"é­¨";s:2:"èâ";s:3:"é­¤";s:2:"èã";s:3:"é­¬";s:2:"èä";s:3:"é³¼";s:2:"èå";s:3:"鳺";s:2:"èæ";s:3:"é³½";s:2:"èç";s:3:"鳿";s:2:"èè";s:3:"é³·";s:2:"èé";s:3:"é´‡";s:2:"èê";s:3:"é´€";s:2:"èë";s:3:"é³¹";s:2:"èì";s:3:"é³»";s:2:"èí";s:3:"é´ˆ";s:2:"èî";s:3:"é´…";s:2:"èï";s:3:"é´„";s:2:"èð";s:3:"麃";s:2:"èñ";s:3:"黓";s:2:"èò";s:3:"é¼";s:2:"èó";s:3:"é¼";s:2:"èô";s:3:"儜";s:2:"èõ";s:3:"å„“";s:2:"èö";s:3:"å„—";s:2:"è÷";s:3:"儚";s:2:"èø";s:3:"å„‘";s:2:"èù";s:3:"凞";s:2:"èú";s:3:"匴";s:2:"èû";s:3:"å¡";s:2:"èü";s:3:"å™°";s:2:"èý";s:3:"å™ ";s:2:"èþ";s:3:"å™®";s:2:"é@";s:3:"噳";s:2:"éA";s:3:"噦";s:2:"éB";s:3:"噣";s:2:"éC";s:3:"å™­";s:2:"éD";s:3:"噲";s:2:"éE";s:3:"噞";s:2:"éF";s:3:"å™·";s:2:"éG";s:3:"圜";s:2:"éH";s:3:"圛";s:2:"éI";s:3:"壈";s:2:"éJ";s:3:"墽";s:2:"éK";s:3:"壉";s:2:"éL";s:3:"墿";s:2:"éM";s:3:"墺";s:2:"éN";s:3:"壂";s:2:"éO";s:3:"墼";s:2:"éP";s:3:"壆";s:2:"éQ";s:3:"嬗";s:2:"éR";s:3:"嬙";s:2:"éS";s:3:"嬛";s:2:"éT";s:3:"嬡";s:2:"éU";s:3:"嬔";s:2:"éV";s:3:"嬓";s:2:"éW";s:3:"å¬";s:2:"éX";s:3:"嬖";s:2:"éY";s:3:"嬨";s:2:"éZ";s:3:"嬚";s:2:"é[";s:3:"嬠";s:2:"é\";s:3:"嬞";s:2:"é]";s:3:"寯";s:2:"é^";s:3:"嶬";s:2:"é_";s:3:"å¶±";s:2:"é`";s:3:"å¶©";s:2:"éa";s:3:"å¶§";s:2:"éb";s:3:"å¶µ";s:2:"éc";s:3:"å¶°";s:2:"éd";s:3:"å¶®";s:2:"ée";s:3:"嶪";s:2:"éf";s:3:"嶨";s:2:"ég";s:3:"å¶²";s:2:"éh";s:3:"å¶­";s:2:"éi";s:3:"嶯";s:2:"éj";s:3:"å¶´";s:2:"ék";s:3:"å¹§";s:2:"él";s:3:"幨";s:2:"ém";s:3:"幦";s:2:"én";s:3:"幯";s:2:"éo";s:3:"廩";s:2:"ép";s:3:"å»§";s:2:"éq";s:3:"廦";s:2:"ér";s:3:"廨";s:2:"és";s:3:"廥";s:2:"ét";s:3:"彋";s:2:"éu";s:3:"å¾¼";s:2:"év";s:3:"æ†";s:2:"éw";s:3:"憨";s:2:"éx";s:3:"憖";s:2:"éy";s:3:"懅";s:2:"éz";s:3:"憴";s:2:"é{";s:3:"懆";s:2:"é|";s:3:"æ‡";s:2:"é}";s:3:"懌";s:2:"é~";s:3:"憺";s:2:"é¡";s:3:"憿";s:2:"é¢";s:3:"憸";s:2:"é£";s:3:"憌";s:2:"é¤";s:3:"æ“—";s:2:"é¥";s:3:"æ“–";s:2:"é¦";s:3:"æ“";s:2:"é§";s:3:"æ“";s:2:"é¨";s:3:"擉";s:2:"é©";s:3:"æ’½";s:2:"éª";s:3:"æ’‰";s:2:"é«";s:3:"擃";s:2:"é¬";s:3:"æ“›";s:2:"é­";s:3:"擳";s:2:"é®";s:3:"æ“™";s:2:"é¯";s:3:"攳";s:2:"é°";s:3:"æ•¿";s:2:"é±";s:3:"敼";s:2:"é²";s:3:"æ–¢";s:2:"é³";s:3:"曈";s:2:"é´";s:3:"æš¾";s:2:"éµ";s:3:"曀";s:2:"é¶";s:3:"曊";s:2:"é·";s:3:"曋";s:2:"é¸";s:3:"æ›";s:2:"é¹";s:3:"æš½";s:2:"éº";s:3:"æš»";s:2:"é»";s:3:"暺";s:2:"é¼";s:3:"曌";s:2:"é½";s:3:"朣";s:2:"é¾";s:3:"樴";s:2:"é¿";s:3:"橦";s:2:"éÀ";s:3:"橉";s:2:"éÁ";s:3:"æ©§";s:2:"éÂ";s:3:"樲";s:2:"éÃ";s:3:"橨";s:2:"éÄ";s:3:"樾";s:2:"éÅ";s:3:"æ©";s:2:"éÆ";s:3:"æ©­";s:2:"éÇ";s:3:"æ©¶";s:2:"éÈ";s:3:"æ©›";s:2:"éÉ";s:3:"æ©‘";s:2:"éÊ";s:3:"樨";s:2:"éË";s:3:"橚";s:2:"éÌ";s:3:"樻";s:2:"éÍ";s:3:"樿";s:2:"éÎ";s:3:"æ©";s:2:"éÏ";s:3:"橪";s:2:"éÐ";s:3:"橤";s:2:"éÑ";s:3:"æ©";s:2:"éÒ";s:3:"æ©";s:2:"éÓ";s:3:"æ©”";s:2:"éÔ";s:3:"橯";s:2:"éÕ";s:3:"æ©©";s:2:"éÖ";s:3:"æ© ";s:2:"é×";s:3:"樼";s:2:"éØ";s:3:"橞";s:2:"éÙ";s:3:"æ©–";s:2:"éÚ";s:3:"æ©•";s:2:"éÛ";s:3:"æ©";s:2:"éÜ";s:3:"橎";s:2:"éÝ";s:3:"橆";s:2:"éÞ";s:3:"æ­•";s:2:"éß";s:3:"æ­”";s:2:"éà";s:3:"æ­–";s:2:"éá";s:3:"æ®§";s:2:"éâ";s:3:"殪";s:2:"éã";s:3:"殫";s:2:"éä";s:3:"毈";s:2:"éå";s:3:"毇";s:2:"éæ";s:3:"æ°„";s:2:"éç";s:3:"æ°ƒ";s:2:"éè";s:3:"æ°†";s:2:"éé";s:3:"æ¾­";s:2:"éê";s:3:"æ¿‹";s:2:"éë";s:3:"æ¾£";s:2:"éì";s:3:"濇";s:2:"éí";s:3:"æ¾¼";s:2:"éî";s:3:"濎";s:2:"éï";s:3:"濈";s:2:"éð";s:3:"潞";s:2:"éñ";s:3:"æ¿„";s:2:"éò";s:3:"æ¾½";s:2:"éó";s:3:"澞";s:2:"éô";s:3:"濊";s:2:"éõ";s:3:"澨";s:2:"éö";s:3:"瀄";s:2:"é÷";s:3:"æ¾¥";s:2:"éø";s:3:"æ¾®";s:2:"éù";s:3:"澺";s:2:"éú";s:3:"澬";s:2:"éû";s:3:"澪";s:2:"éü";s:3:"æ¿";s:2:"éý";s:3:"澿";s:2:"éþ";s:3:"澸";s:2:"ê@";s:3:"æ¾¢";s:2:"êA";s:3:"濉";s:2:"êB";s:3:"澫";s:2:"êC";s:3:"æ¿";s:2:"êD";s:3:"澯";s:2:"êE";s:3:"æ¾²";s:2:"êF";s:3:"æ¾°";s:2:"êG";s:3:"燅";s:2:"êH";s:3:"燂";s:2:"êI";s:3:"熿";s:2:"êJ";s:3:"熸";s:2:"êK";s:3:"燖";s:2:"êL";s:3:"燀";s:2:"êM";s:3:"ç‡";s:2:"êN";s:3:"燋";s:2:"êO";s:3:"燔";s:2:"êP";s:3:"燊";s:2:"êQ";s:3:"燇";s:2:"êR";s:3:"ç‡";s:2:"êS";s:3:"熽";s:2:"êT";s:3:"燘";s:2:"êU";s:3:"熼";s:2:"êV";s:3:"燆";s:2:"êW";s:3:"燚";s:2:"êX";s:3:"燛";s:2:"êY";s:3:"çŠ";s:2:"êZ";s:3:"犞";s:2:"ê[";s:3:"ç©";s:2:"ê\";s:3:"ç¦";s:2:"ê]";s:3:"ç§";s:2:"ê^";s:3:"ç¬";s:2:"ê_";s:3:"ç¥";s:2:"ê`";s:3:"ç«";s:2:"êa";s:3:"çª";s:2:"êb";s:3:"ç‘¿";s:2:"êc";s:3:"ç’š";s:2:"êd";s:3:"ç’ ";s:2:"êe";s:3:"ç’”";s:2:"êf";s:3:"ç’’";s:2:"êg";s:3:"ç’•";s:2:"êh";s:3:"ç’¡";s:2:"êi";s:3:"甋";s:2:"êj";s:3:"ç–€";s:2:"êk";s:3:"瘯";s:2:"êl";s:3:"瘭";s:2:"êm";s:3:"瘱";s:2:"ên";s:3:"瘽";s:2:"êo";s:3:"瘳";s:2:"êp";s:3:"瘼";s:2:"êq";s:3:"瘵";s:2:"êr";s:3:"瘲";s:2:"ês";s:3:"瘰";s:2:"êt";s:3:"çš»";s:2:"êu";s:3:"盦";s:2:"êv";s:3:"çžš";s:2:"êw";s:3:"çž";s:2:"êx";s:3:"çž¡";s:2:"êy";s:3:"çžœ";s:2:"êz";s:3:"çž›";s:2:"ê{";s:3:"瞢";s:2:"ê|";s:3:"瞣";s:2:"ê}";s:3:"çž•";s:2:"ê~";s:3:"çž™";s:2:"ê¡";s:3:"çž—";s:2:"ê¢";s:3:"ç£";s:2:"ê£";s:3:"磩";s:2:"ê¤";s:3:"磥";s:2:"ê¥";s:3:"磪";s:2:"ê¦";s:3:"磞";s:2:"ê§";s:3:"磣";s:2:"ê¨";s:3:"磛";s:2:"ê©";s:3:"磡";s:2:"êª";s:3:"磢";s:2:"ê«";s:3:"磭";s:2:"ê¬";s:3:"磟";s:2:"ê­";s:3:"磠";s:2:"ê®";s:3:"禤";s:2:"ê¯";s:3:"ç©„";s:2:"ê°";s:3:"穈";s:2:"ê±";s:3:"穇";s:2:"ê²";s:3:"窶";s:2:"ê³";s:3:"窸";s:2:"ê´";s:3:"窵";s:2:"êµ";s:3:"窱";s:2:"ê¶";s:3:"窷";s:2:"ê·";s:3:"篞";s:2:"ê¸";s:3:"篣";s:2:"ê¹";s:3:"篧";s:2:"êº";s:3:"ç¯";s:2:"ê»";s:3:"篕";s:2:"ê¼";s:3:"篥";s:2:"ê½";s:3:"篚";s:2:"ê¾";s:3:"篨";s:2:"ê¿";s:3:"篹";s:2:"êÀ";s:3:"篔";s:2:"êÁ";s:3:"篪";s:2:"êÂ";s:3:"篢";s:2:"êÃ";s:3:"篜";s:2:"êÄ";s:3:"篫";s:2:"êÅ";s:3:"篘";s:2:"êÆ";s:3:"篟";s:2:"êÇ";s:3:"ç³’";s:2:"êÈ";s:3:"ç³”";s:2:"êÉ";s:3:"ç³—";s:2:"êÊ";s:3:"ç³";s:2:"êË";s:3:"糑";s:2:"êÌ";s:3:"縒";s:2:"êÍ";s:3:"縡";s:2:"êÎ";s:3:"縗";s:2:"êÏ";s:3:"縌";s:2:"êÐ";s:3:"縟";s:2:"êÑ";s:3:"縠";s:2:"êÒ";s:3:"縓";s:2:"êÓ";s:3:"縎";s:2:"êÔ";s:3:"縜";s:2:"êÕ";s:3:"縕";s:2:"êÖ";s:3:"縚";s:2:"ê×";s:3:"縢";s:2:"êØ";s:3:"縋";s:2:"êÙ";s:3:"ç¸";s:2:"êÚ";s:3:"縖";s:2:"êÛ";s:3:"ç¸";s:2:"êÜ";s:3:"縔";s:2:"êÝ";s:3:"縥";s:2:"êÞ";s:3:"縤";s:2:"êß";s:3:"罃";s:2:"êà";s:3:"ç½»";s:2:"êá";s:3:"ç½¼";s:2:"êâ";s:3:"罺";s:2:"êã";s:3:"ç¾±";s:2:"êä";s:3:"翯";s:2:"êå";s:3:"耪";s:2:"êæ";s:3:"耩";s:2:"êç";s:3:"è¬";s:2:"êè";s:3:"膱";s:2:"êé";s:3:"膦";s:2:"êê";s:3:"膮";s:2:"êë";s:3:"膹";s:2:"êì";s:3:"膵";s:2:"êí";s:3:"膫";s:2:"êî";s:3:"膰";s:2:"êï";s:3:"膬";s:2:"êð";s:3:"膴";s:2:"êñ";s:3:"膲";s:2:"êò";s:3:"膷";s:2:"êó";s:3:"膧";s:2:"êô";s:3:"臲";s:2:"êõ";s:3:"艕";s:2:"êö";s:3:"艖";s:2:"ê÷";s:3:"艗";s:2:"êø";s:3:"è•–";s:2:"êù";s:3:"è•…";s:2:"êú";s:3:"è•«";s:2:"êû";s:3:"è•";s:2:"êü";s:3:"è•“";s:2:"êý";s:3:"è•¡";s:2:"êþ";s:3:"蕘";s:2:"ë@";s:3:"è•€";s:2:"ëA";s:3:"蕆";s:2:"ëB";s:3:"蕤";s:2:"ëC";s:3:"è•";s:2:"ëD";s:3:"è•¢";s:2:"ëE";s:3:"è•„";s:2:"ëF";s:3:"è•‘";s:2:"ëG";s:3:"蕇";s:2:"ëH";s:3:"è•£";s:2:"ëI";s:3:"蔾";s:2:"ëJ";s:3:"è•›";s:2:"ëK";s:3:"蕱";s:2:"ëL";s:3:"蕎";s:2:"ëM";s:3:"è•®";s:2:"ëN";s:3:"蕵";s:2:"ëO";s:3:"è••";s:2:"ëP";s:3:"è•§";s:2:"ëQ";s:3:"è• ";s:2:"ëR";s:3:"è–Œ";s:2:"ëS";s:3:"蕦";s:2:"ëT";s:3:"è•";s:2:"ëU";s:3:"è•”";s:2:"ëV";s:3:"è•¥";s:2:"ëW";s:3:"蕬";s:2:"ëX";s:3:"虣";s:2:"ëY";s:3:"虥";s:2:"ëZ";s:3:"虤";s:2:"ë[";s:3:"èž›";s:2:"ë\";s:3:"èž";s:2:"ë]";s:3:"èž—";s:2:"ë^";s:3:"èž“";s:2:"ë_";s:3:"èž’";s:2:"ë`";s:3:"螈";s:2:"ëa";s:3:"èž";s:2:"ëb";s:3:"èž–";s:2:"ëc";s:3:"螘";s:2:"ëd";s:3:"è¹";s:2:"ëe";s:3:"螇";s:2:"ëf";s:3:"螣";s:2:"ëg";s:3:"èž…";s:2:"ëh";s:3:"èž";s:2:"ëi";s:3:"èž‘";s:2:"ëj";s:3:"èž";s:2:"ëk";s:3:"èž„";s:2:"ël";s:3:"èž”";s:2:"ëm";s:3:"èžœ";s:2:"ën";s:3:"èžš";s:2:"ëo";s:3:"螉";s:2:"ëp";s:3:"褞";s:2:"ëq";s:3:"褦";s:2:"ër";s:3:"褰";s:2:"ës";s:3:"褭";s:2:"ët";s:3:"褮";s:2:"ëu";s:3:"褧";s:2:"ëv";s:3:"褱";s:2:"ëw";s:3:"褢";s:2:"ëx";s:3:"褩";s:2:"ëy";s:3:"褣";s:2:"ëz";s:3:"褯";s:2:"ë{";s:3:"褬";s:2:"ë|";s:3:"褟";s:2:"ë}";s:3:"è§±";s:2:"ë~";s:3:"è« ";s:2:"ë¡";s:3:"è«¢";s:2:"ë¢";s:3:"諲";s:2:"ë£";s:3:"è«´";s:2:"ë¤";s:3:"諵";s:2:"ë¥";s:3:"è«";s:2:"ë¦";s:3:"謔";s:2:"ë§";s:3:"諤";s:2:"ë¨";s:3:"諟";s:2:"ë©";s:3:"è«°";s:2:"ëª";s:3:"諈";s:2:"ë«";s:3:"諞";s:2:"ë¬";s:3:"è«¡";s:2:"ë­";s:3:"諨";s:2:"ë®";s:3:"è«¿";s:2:"ë¯";s:3:"諯";s:2:"ë°";s:3:"è«»";s:2:"ë±";s:3:"貑";s:2:"ë²";s:3:"è²’";s:2:"ë³";s:3:"è²";s:2:"ë´";s:3:"è³µ";s:2:"ëµ";s:3:"è³®";s:2:"ë¶";s:3:"è³±";s:2:"ë·";s:3:"è³°";s:2:"ë¸";s:3:"è³³";s:2:"ë¹";s:3:"赬";s:2:"ëº";s:3:"èµ®";s:2:"ë»";s:3:"è¶¥";s:2:"ë¼";s:3:"è¶§";s:2:"ë½";s:3:"踳";s:2:"ë¾";s:3:"踾";s:2:"ë¿";s:3:"踸";s:2:"ëÀ";s:3:"è¹€";s:2:"ëÁ";s:3:"è¹…";s:2:"ëÂ";s:3:"踶";s:2:"ëÃ";s:3:"踼";s:2:"ëÄ";s:3:"踽";s:2:"ëÅ";s:3:"è¹";s:2:"ëÆ";s:3:"踰";s:2:"ëÇ";s:3:"踿";s:2:"ëÈ";s:3:"躽";s:2:"ëÉ";s:3:"è¼¶";s:2:"ëÊ";s:3:"è¼®";s:2:"ëË";s:3:"è¼µ";s:2:"ëÌ";s:3:"è¼²";s:2:"ëÍ";s:3:"è¼¹";s:2:"ëÎ";s:3:"è¼·";s:2:"ëÏ";s:3:"è¼´";s:2:"ëÐ";s:3:"é¶";s:2:"ëÑ";s:3:"é¹";s:2:"ëÒ";s:3:"é»";s:2:"ëÓ";s:3:"邆";s:2:"ëÔ";s:3:"郺";s:2:"ëÕ";s:3:"鄳";s:2:"ëÖ";s:3:"鄵";s:2:"ë×";s:3:"é„¶";s:2:"ëØ";s:3:"醓";s:2:"ëÙ";s:3:"é†";s:2:"ëÚ";s:3:"醑";s:2:"ëÛ";s:3:"é†";s:2:"ëÜ";s:3:"é†";s:2:"ëÝ";s:3:"錧";s:2:"ëÞ";s:3:"錞";s:2:"ëß";s:3:"錈";s:2:"ëà";s:3:"錟";s:2:"ëá";s:3:"錆";s:2:"ëâ";s:3:"éŒ";s:2:"ëã";s:3:"éº";s:2:"ëä";s:3:"錸";s:2:"ëå";s:3:"錼";s:2:"ëæ";s:3:"錛";s:2:"ëç";s:3:"錣";s:2:"ëè";s:3:"錒";s:2:"ëé";s:3:"éŒ";s:2:"ëê";s:3:"é†";s:2:"ëë";s:3:"錭";s:2:"ëì";s:3:"錎";s:2:"ëí";s:3:"éŒ";s:2:"ëî";s:3:"é‹‹";s:2:"ëï";s:3:"éŒ";s:2:"ëð";s:3:"鋺";s:2:"ëñ";s:3:"錥";s:2:"ëò";s:3:"錓";s:2:"ëó";s:3:"鋹";s:2:"ëô";s:3:"é‹·";s:2:"ëõ";s:3:"錴";s:2:"ëö";s:3:"錂";s:2:"ë÷";s:3:"錤";s:2:"ëø";s:3:"é‹¿";s:2:"ëù";s:3:"錩";s:2:"ëú";s:3:"錹";s:2:"ëû";s:3:"錵";s:2:"ëü";s:3:"錪";s:2:"ëý";s:3:"錔";s:2:"ëþ";s:3:"錌";s:2:"ì@";s:3:"錋";s:2:"ìA";s:3:"鋾";s:2:"ìB";s:3:"錉";s:2:"ìC";s:3:"錀";s:2:"ìD";s:3:"é‹»";s:2:"ìE";s:3:"錖";s:2:"ìF";s:3:"é–¼";s:2:"ìG";s:3:"é—";s:2:"ìH";s:3:"é–¾";s:2:"ìI";s:3:"é–¹";s:2:"ìJ";s:3:"é–º";s:2:"ìK";s:3:"é–¶";s:2:"ìL";s:3:"é–¿";s:2:"ìM";s:3:"é–µ";s:2:"ìN";s:3:"é–½";s:2:"ìO";s:3:"éš©";s:2:"ìP";s:3:"é›”";s:2:"ìQ";s:3:"霋";s:2:"ìR";s:3:"霒";s:2:"ìS";s:3:"éœ";s:2:"ìT";s:3:"éž™";s:2:"ìU";s:3:"éž—";s:2:"ìV";s:3:"éž”";s:2:"ìW";s:3:"韰";s:2:"ìX";s:3:"韸";s:2:"ìY";s:3:"é µ";s:2:"ìZ";s:3:"é ¯";s:2:"ì[";s:3:"é ²";s:2:"ì\";s:3:"餤";s:2:"ì]";s:3:"餟";s:2:"ì^";s:3:"餧";s:2:"ì_";s:3:"餩";s:2:"ì`";s:3:"馞";s:2:"ìa";s:3:"é§®";s:2:"ìb";s:3:"駬";s:2:"ìc";s:3:"é§¥";s:2:"ìd";s:3:"駤";s:2:"ìe";s:3:"é§°";s:2:"ìf";s:3:"é§£";s:2:"ìg";s:3:"駪";s:2:"ìh";s:3:"é§©";s:2:"ìi";s:3:"é§§";s:2:"ìj";s:3:"骹";s:2:"ìk";s:3:"骿";s:2:"ìl";s:3:"骴";s:2:"ìm";s:3:"骻";s:2:"ìn";s:3:"é«¶";s:2:"ìo";s:3:"髺";s:2:"ìp";s:3:"髹";s:2:"ìq";s:3:"é«·";s:2:"ìr";s:3:"鬳";s:2:"ìs";s:3:"鮀";s:2:"ìt";s:3:"é®…";s:2:"ìu";s:3:"鮇";s:2:"ìv";s:3:"é­¼";s:2:"ìw";s:3:"é­¾";s:2:"ìx";s:3:"é­»";s:2:"ìy";s:3:"鮂";s:2:"ìz";s:3:"鮓";s:2:"ì{";s:3:"é®’";s:2:"ì|";s:3:"é®";s:2:"ì}";s:3:"é­º";s:2:"ì~";s:3:"鮕";s:2:"ì¡";s:3:"é­½";s:2:"ì¢";s:3:"鮈";s:2:"ì£";s:3:"é´¥";s:2:"ì¤";s:3:"é´—";s:2:"ì¥";s:3:"é´ ";s:2:"ì¦";s:3:"é´ž";s:2:"ì§";s:3:"é´”";s:2:"ì¨";s:3:"é´©";s:2:"ì©";s:3:"é´";s:2:"ìª";s:3:"é´˜";s:2:"ì«";s:3:"é´¢";s:2:"ì¬";s:3:"é´";s:2:"ì­";s:3:"é´™";s:2:"ì®";s:3:"é´Ÿ";s:2:"ì¯";s:3:"麈";s:2:"ì°";s:3:"麆";s:2:"ì±";s:3:"麇";s:2:"ì²";s:3:"麮";s:2:"ì³";s:3:"麭";s:2:"ì´";s:3:"黕";s:2:"ìµ";s:3:"é»–";s:2:"ì¶";s:3:"黺";s:2:"ì·";s:3:"é¼’";s:2:"ì¸";s:3:"é¼½";s:2:"ì¹";s:3:"儦";s:2:"ìº";s:3:"å„¥";s:2:"ì»";s:3:"å„¢";s:2:"ì¼";s:3:"儤";s:2:"ì½";s:3:"å„ ";s:2:"ì¾";s:3:"å„©";s:2:"ì¿";s:3:"å‹´";s:2:"ìÀ";s:3:"åš“";s:2:"ìÁ";s:3:"嚌";s:2:"ìÂ";s:3:"åš";s:2:"ìÃ";s:3:"嚆";s:2:"ìÄ";s:3:"åš„";s:2:"ìÅ";s:3:"嚃";s:2:"ìÆ";s:3:"噾";s:2:"ìÇ";s:3:"åš‚";s:2:"ìÈ";s:3:"噿";s:2:"ìÉ";s:3:"åš";s:2:"ìÊ";s:3:"壖";s:2:"ìË";s:3:"壔";s:2:"ìÌ";s:3:"å£";s:2:"ìÍ";s:3:"壒";s:2:"ìÎ";s:3:"嬭";s:2:"ìÏ";s:3:"嬥";s:2:"ìÐ";s:3:"嬲";s:2:"ìÑ";s:3:"嬣";s:2:"ìÒ";s:3:"嬬";s:2:"ìÓ";s:3:"嬧";s:2:"ìÔ";s:3:"嬦";s:2:"ìÕ";s:3:"嬯";s:2:"ìÖ";s:3:"嬮";s:2:"ì×";s:3:"å­»";s:2:"ìØ";s:3:"寱";s:2:"ìÙ";s:3:"寲";s:2:"ìÚ";s:3:"å¶·";s:2:"ìÛ";s:3:"幬";s:2:"ìÜ";s:3:"幪";s:2:"ìÝ";s:3:"å¾¾";s:2:"ìÞ";s:3:"å¾»";s:2:"ìß";s:3:"懃";s:2:"ìà";s:3:"憵";s:2:"ìá";s:3:"憼";s:2:"ìâ";s:3:"懧";s:2:"ìã";s:3:"懠";s:2:"ìä";s:3:"懥";s:2:"ìå";s:3:"懤";s:2:"ìæ";s:3:"懨";s:2:"ìç";s:3:"懞";s:2:"ìè";s:3:"擯";s:2:"ìé";s:3:"æ“©";s:2:"ìê";s:3:"æ“£";s:2:"ìë";s:3:"æ“«";s:2:"ìì";s:3:"擤";s:2:"ìí";s:3:"擨";s:2:"ìî";s:3:"æ–";s:2:"ìï";s:3:"æ–€";s:2:"ìð";s:3:"æ–¶";s:2:"ìñ";s:3:"æ—š";s:2:"ìò";s:3:"æ›’";s:2:"ìó";s:3:"æª";s:2:"ìô";s:3:"檖";s:2:"ìõ";s:3:"æª";s:2:"ìö";s:3:"檥";s:2:"ì÷";s:3:"檉";s:2:"ìø";s:3:"檟";s:2:"ìù";s:3:"檛";s:2:"ìú";s:3:"檡";s:2:"ìû";s:3:"檞";s:2:"ìü";s:3:"檇";s:2:"ìý";s:3:"檓";s:2:"ìþ";s:3:"檎";s:2:"í@";s:3:"檕";s:2:"íA";s:3:"檃";s:2:"íB";s:3:"檨";s:2:"íC";s:3:"檤";s:2:"íD";s:3:"檑";s:2:"íE";s:3:"æ©¿";s:2:"íF";s:3:"檦";s:2:"íG";s:3:"檚";s:2:"íH";s:3:"檅";s:2:"íI";s:3:"檌";s:2:"íJ";s:3:"檒";s:2:"íK";s:3:"æ­›";s:2:"íL";s:3:"æ®­";s:2:"íM";s:3:"æ°‰";s:2:"íN";s:3:"濌";s:2:"íO";s:3:"澩";s:2:"íP";s:3:"æ¿´";s:2:"íQ";s:3:"æ¿”";s:2:"íR";s:3:"æ¿£";s:2:"íS";s:3:"濜";s:2:"íT";s:3:"æ¿­";s:2:"íU";s:3:"æ¿§";s:2:"íV";s:3:"濦";s:2:"íW";s:3:"濞";s:2:"íX";s:3:"濲";s:2:"íY";s:3:"æ¿";s:2:"íZ";s:3:"æ¿¢";s:2:"í[";s:3:"濨";s:2:"í\";s:3:"燡";s:2:"í]";s:3:"燱";s:2:"í^";s:3:"燨";s:2:"í_";s:3:"燲";s:2:"í`";s:3:"燤";s:2:"ía";s:3:"燰";s:2:"íb";s:3:"燢";s:2:"íc";s:3:"ç³";s:2:"íd";s:3:"ç®";s:2:"íe";s:3:"ç¯";s:2:"íf";s:3:"ç’—";s:2:"íg";s:3:"ç’²";s:2:"íh";s:3:"ç’«";s:2:"íi";s:3:"ç’";s:2:"íj";s:3:"ç’ª";s:2:"ík";s:3:"ç’­";s:2:"íl";s:3:"ç’±";s:2:"ím";s:3:"ç’¥";s:2:"ín";s:3:"ç’¯";s:2:"ío";s:3:"ç”";s:2:"íp";s:3:"甑";s:2:"íq";s:3:"ç”’";s:2:"ír";s:3:"ç”";s:2:"ís";s:3:"ç–„";s:2:"ít";s:3:"癃";s:2:"íu";s:3:"癈";s:2:"ív";s:3:"癉";s:2:"íw";s:3:"癇";s:2:"íx";s:3:"皤";s:2:"íy";s:3:"盩";s:2:"íz";s:3:"çžµ";s:2:"í{";s:3:"çž«";s:2:"í|";s:3:"çž²";s:2:"í}";s:3:"çž·";s:2:"í~";s:3:"çž¶";s:2:"í¡";s:3:"çž´";s:2:"í¢";s:3:"çž±";s:2:"í£";s:3:"瞨";s:2:"í¤";s:3:"矰";s:2:"í¥";s:3:"磳";s:2:"í¦";s:3:"磽";s:2:"í§";s:3:"礂";s:2:"í¨";s:3:"磻";s:2:"í©";s:3:"磼";s:2:"íª";s:3:"磲";s:2:"í«";s:3:"礅";s:2:"í¬";s:3:"磹";s:2:"í­";s:3:"磾";s:2:"í®";s:3:"礄";s:2:"í¯";s:3:"禫";s:2:"í°";s:3:"禨";s:2:"í±";s:3:"穜";s:2:"í²";s:3:"ç©›";s:2:"í³";s:3:"ç©–";s:2:"í´";s:3:"穘";s:2:"íµ";s:3:"ç©”";s:2:"í¶";s:3:"穚";s:2:"í·";s:3:"窾";s:2:"í¸";s:3:"ç«€";s:2:"í¹";s:3:"ç«";s:2:"íº";s:3:"ç°…";s:2:"í»";s:3:"ç°";s:2:"í¼";s:3:"篲";s:2:"í½";s:3:"ç°€";s:2:"í¾";s:3:"篿";s:2:"í¿";s:3:"篻";s:2:"íÀ";s:3:"ç°Ž";s:2:"íÁ";s:3:"篴";s:2:"íÂ";s:3:"ç°‹";s:2:"íÃ";s:3:"篳";s:2:"íÄ";s:3:"ç°‚";s:2:"íÅ";s:3:"ç°‰";s:2:"íÆ";s:3:"ç°ƒ";s:2:"íÇ";s:3:"ç°";s:2:"íÈ";s:3:"篸";s:2:"íÉ";s:3:"篽";s:2:"íÊ";s:3:"ç°†";s:2:"íË";s:3:"篰";s:2:"íÌ";s:3:"篱";s:2:"íÍ";s:3:"ç°";s:2:"íÎ";s:3:"ç°Š";s:2:"íÏ";s:3:"糨";s:2:"íÐ";s:3:"縭";s:2:"íÑ";s:3:"縼";s:2:"íÒ";s:3:"繂";s:2:"íÓ";s:3:"縳";s:2:"íÔ";s:3:"顈";s:2:"íÕ";s:3:"縸";s:2:"íÖ";s:3:"縪";s:2:"í×";s:3:"繉";s:2:"íØ";s:3:"ç¹€";s:2:"íÙ";s:3:"繇";s:2:"íÚ";s:3:"縩";s:2:"íÛ";s:3:"繌";s:2:"íÜ";s:3:"縰";s:2:"íÝ";s:3:"縻";s:2:"íÞ";s:3:"縶";s:2:"íß";s:3:"繄";s:2:"íà";s:3:"縺";s:2:"íá";s:3:"ç½…";s:2:"íâ";s:3:"罿";s:2:"íã";s:3:"ç½¾";s:2:"íä";s:3:"ç½½";s:2:"íå";s:3:"ç¿´";s:2:"íæ";s:3:"翲";s:2:"íç";s:3:"耬";s:2:"íè";s:3:"膻";s:2:"íé";s:3:"臄";s:2:"íê";s:3:"臌";s:2:"íë";s:3:"臊";s:2:"íì";s:3:"臅";s:2:"íí";s:3:"臇";s:2:"íî";s:3:"膼";s:2:"íï";s:3:"臩";s:2:"íð";s:3:"艛";s:2:"íñ";s:3:"艚";s:2:"íò";s:3:"艜";s:2:"íó";s:3:"è–ƒ";s:2:"íô";s:3:"è–€";s:2:"íõ";s:3:"è–";s:2:"íö";s:3:"è–§";s:2:"í÷";s:3:"è–•";s:2:"íø";s:3:"è– ";s:2:"íù";s:3:"è–‹";s:2:"íú";s:3:"è–£";s:2:"íû";s:3:"è•»";s:2:"íü";s:3:"è–¤";s:2:"íý";s:3:"è–š";s:2:"íþ";s:3:"è–ž";s:2:"î@";s:3:"è•·";s:2:"îA";s:3:"蕼";s:2:"îB";s:3:"è–‰";s:2:"îC";s:3:"è–¡";s:2:"îD";s:3:"蕺";s:2:"îE";s:3:"蕸";s:2:"îF";s:3:"è•—";s:2:"îG";s:3:"è–Ž";s:2:"îH";s:3:"è––";s:2:"îI";s:3:"è–†";s:2:"îJ";s:3:"è–";s:2:"îK";s:3:"è–™";s:2:"îL";s:3:"è–";s:2:"îM";s:3:"è–";s:2:"îN";s:3:"è–¢";s:2:"îO";s:3:"è–‚";s:2:"îP";s:3:"è–ˆ";s:2:"îQ";s:3:"è–…";s:2:"îR";s:3:"蕹";s:2:"îS";s:3:"è•¶";s:2:"îT";s:3:"è–˜";s:2:"îU";s:3:"è–";s:2:"îV";s:3:"è–Ÿ";s:2:"îW";s:3:"虨";s:2:"îX";s:3:"èž¾";s:2:"îY";s:3:"螪";s:2:"îZ";s:3:"èž­";s:2:"î[";s:3:"蟅";s:2:"î\";s:3:"èž°";s:2:"î]";s:3:"螬";s:2:"î^";s:3:"èž¹";s:2:"î_";s:3:"èžµ";s:2:"î`";s:3:"èž¼";s:2:"îa";s:3:"èž®";s:2:"îb";s:3:"蟉";s:2:"îc";s:3:"蟃";s:2:"îd";s:3:"蟂";s:2:"îe";s:3:"蟌";s:2:"îf";s:3:"èž·";s:2:"îg";s:3:"螯";s:2:"îh";s:3:"蟄";s:2:"îi";s:3:"蟊";s:2:"îj";s:3:"èž´";s:2:"îk";s:3:"èž¶";s:2:"îl";s:3:"èž¿";s:2:"îm";s:3:"螸";s:2:"în";s:3:"èž½";s:2:"îo";s:3:"蟞";s:2:"îp";s:3:"èž²";s:2:"îq";s:3:"褵";s:2:"îr";s:3:"褳";s:2:"îs";s:3:"褼";s:2:"ît";s:3:"褾";s:2:"îu";s:3:"è¥";s:2:"îv";s:3:"襒";s:2:"îw";s:3:"褷";s:2:"îx";s:3:"襂";s:2:"îy";s:3:"覭";s:2:"îz";s:3:"覯";s:2:"î{";s:3:"覮";s:2:"î|";s:3:"è§²";s:2:"î}";s:3:"è§³";s:2:"î~";s:3:"謞";s:2:"î¡";s:3:"謘";s:2:"î¢";s:3:"謖";s:2:"î£";s:3:"謑";s:2:"î¤";s:3:"謅";s:2:"î¥";s:3:"謋";s:2:"î¦";s:3:"謢";s:2:"î§";s:3:"è¬";s:2:"î¨";s:3:"謒";s:2:"î©";s:3:"謕";s:2:"îª";s:3:"謇";s:2:"î«";s:3:"è¬";s:2:"î¬";s:3:"謈";s:2:"î­";s:3:"謆";s:2:"î®";s:3:"謜";s:2:"î¯";s:3:"謓";s:2:"î°";s:3:"謚";s:2:"î±";s:3:"è±";s:2:"î²";s:3:"è±°";s:2:"î³";s:3:"è±²";s:2:"î´";s:3:"è±±";s:2:"îµ";s:3:"豯";s:2:"î¶";s:3:"貕";s:2:"î·";s:3:"è²”";s:2:"î¸";s:3:"è³¹";s:2:"î¹";s:3:"赯";s:2:"îº";s:3:"蹎";s:2:"î»";s:3:"è¹";s:2:"î¼";s:3:"蹓";s:2:"î½";s:3:"è¹";s:2:"î¾";s:3:"蹌";s:2:"î¿";s:3:"蹇";s:2:"îÀ";s:3:"轃";s:2:"îÁ";s:3:"è½€";s:2:"îÂ";s:3:"é‚…";s:2:"îÃ";s:3:"é¾";s:2:"îÄ";s:3:"鄸";s:2:"îÅ";s:3:"醚";s:2:"îÆ";s:3:"醢";s:2:"îÇ";s:3:"醛";s:2:"îÈ";s:3:"醙";s:2:"îÉ";s:3:"醟";s:2:"îÊ";s:3:"醡";s:2:"îË";s:3:"é†";s:2:"îÌ";s:3:"醠";s:2:"îÍ";s:3:"鎡";s:2:"îÎ";s:3:"鎃";s:2:"îÏ";s:3:"鎯";s:2:"îÐ";s:3:"é¤";s:2:"îÑ";s:3:"é–";s:2:"îÒ";s:3:"é‡";s:2:"îÓ";s:3:"é¼";s:2:"îÔ";s:3:"é˜";s:2:"îÕ";s:3:"éœ";s:2:"îÖ";s:3:"é¶";s:2:"î×";s:3:"é‰";s:2:"îØ";s:3:"é";s:2:"îÙ";s:3:"é‘";s:2:"îÚ";s:3:"é ";s:2:"îÛ";s:3:"é­";s:2:"îÜ";s:3:"éŽ";s:2:"îÝ";s:3:"éŒ";s:2:"îÞ";s:3:"éª";s:2:"îß";s:3:"é¹";s:2:"îà";s:3:"é—";s:2:"îá";s:3:"é•";s:2:"îâ";s:3:"é’";s:2:"îã";s:3:"é";s:2:"îä";s:3:"é±";s:2:"îå";s:3:"é·";s:2:"îæ";s:3:"é»";s:2:"îç";s:3:"é¡";s:2:"îè";s:3:"éž";s:2:"îé";s:3:"é£";s:2:"îê";s:3:"é§";s:2:"îë";s:3:"鎀";s:2:"îì";s:3:"éŽ";s:2:"îí";s:3:"é™";s:2:"îî";s:3:"é—‡";s:2:"îï";s:3:"é—€";s:2:"îð";s:3:"é—‰";s:2:"îñ";s:3:"é—ƒ";s:2:"îò";s:3:"é—…";s:2:"îó";s:3:"é–·";s:2:"îô";s:3:"éš®";s:2:"îõ";s:3:"éš°";s:2:"îö";s:3:"隬";s:2:"î÷";s:3:"霠";s:2:"îø";s:3:"霟";s:2:"îù";s:3:"霘";s:2:"îú";s:3:"éœ";s:2:"îû";s:3:"霙";s:2:"îü";s:3:"éžš";s:2:"îý";s:3:"éž¡";s:2:"îþ";s:3:"éžœ";s:2:"ï@";s:3:"éžž";s:2:"ïA";s:3:"éž";s:2:"ïB";s:3:"韕";s:2:"ïC";s:3:"韔";s:2:"ïD";s:3:"韱";s:2:"ïE";s:3:"é¡";s:2:"ïF";s:3:"é¡„";s:2:"ïG";s:3:"顊";s:2:"ïH";s:3:"顉";s:2:"ïI";s:3:"é¡…";s:2:"ïJ";s:3:"顃";s:2:"ïK";s:3:"餥";s:2:"ïL";s:3:"餫";s:2:"ïM";s:3:"餬";s:2:"ïN";s:3:"餪";s:2:"ïO";s:3:"餳";s:2:"ïP";s:3:"餲";s:2:"ïQ";s:3:"餯";s:2:"ïR";s:3:"餭";s:2:"ïS";s:3:"餱";s:2:"ïT";s:3:"餰";s:2:"ïU";s:3:"馘";s:2:"ïV";s:3:"馣";s:2:"ïW";s:3:"馡";s:2:"ïX";s:3:"騂";s:2:"ïY";s:3:"駺";s:2:"ïZ";s:3:"é§´";s:2:"ï[";s:3:"é§·";s:2:"ï\";s:3:"é§¹";s:2:"ï]";s:3:"駸";s:2:"ï^";s:3:"é§¶";s:2:"ï_";s:3:"é§»";s:2:"ï`";s:3:"é§½";s:2:"ïa";s:3:"é§¾";s:2:"ïb";s:3:"é§¼";s:2:"ïc";s:3:"騃";s:2:"ïd";s:3:"骾";s:2:"ïe";s:3:"髾";s:2:"ïf";s:3:"髽";s:2:"ïg";s:3:"é¬";s:2:"ïh";s:3:"髼";s:2:"ïi";s:3:"é­ˆ";s:2:"ïj";s:3:"鮚";s:2:"ïk";s:3:"鮨";s:2:"ïl";s:3:"鮞";s:2:"ïm";s:3:"é®›";s:2:"ïn";s:3:"鮦";s:2:"ïo";s:3:"鮡";s:2:"ïp";s:3:"鮥";s:2:"ïq";s:3:"鮤";s:2:"ïr";s:3:"鮆";s:2:"ïs";s:3:"鮢";s:2:"ït";s:3:"é® ";s:2:"ïu";s:3:"鮯";s:2:"ïv";s:3:"é´³";s:2:"ïw";s:3:"éµ";s:2:"ïx";s:3:"éµ§";s:2:"ïy";s:3:"é´¶";s:2:"ïz";s:3:"é´®";s:2:"ï{";s:3:"é´¯";s:2:"ï|";s:3:"é´±";s:2:"ï}";s:3:"é´¸";s:2:"ï~";s:3:"é´°";s:2:"ï¡";s:3:"éµ…";s:2:"ï¢";s:3:"鵂";s:2:"ï£";s:3:"鵃";s:2:"ï¤";s:3:"é´¾";s:2:"ï¥";s:3:"é´·";s:2:"ï¦";s:3:"éµ€";s:2:"ï§";s:3:"é´½";s:2:"ï¨";s:3:"翵";s:2:"ï©";s:3:"é´­";s:2:"ïª";s:3:"麊";s:2:"ï«";s:3:"麉";s:2:"ï¬";s:3:"éº";s:2:"ï­";s:3:"麰";s:2:"ï®";s:3:"黈";s:2:"ï¯";s:3:"黚";s:2:"ï°";s:3:"é»»";s:2:"ï±";s:3:"黿";s:2:"ï²";s:3:"鼤";s:2:"ï³";s:3:"é¼£";s:2:"ï´";s:3:"é¼¢";s:2:"ïµ";s:3:"é½”";s:2:"ï¶";s:3:"é¾ ";s:2:"ï·";s:3:"儱";s:2:"ï¸";s:3:"å„­";s:2:"ï¹";s:3:"å„®";s:2:"ïº";s:3:"嚘";s:2:"ï»";s:3:"åšœ";s:2:"ï¼";s:3:"åš—";s:2:"ï½";s:3:"åšš";s:2:"ï¾";s:3:"åš";s:2:"ï¿";s:3:"åš™";s:2:"ïÀ";s:3:"奰";s:2:"ïÁ";s:3:"嬼";s:2:"ïÂ";s:3:"屩";s:2:"ïÃ";s:3:"屪";s:2:"ïÄ";s:3:"å·€";s:2:"ïÅ";s:3:"å¹­";s:2:"ïÆ";s:3:"å¹®";s:2:"ïÇ";s:3:"懘";s:2:"ïÈ";s:3:"懟";s:2:"ïÉ";s:3:"懭";s:2:"ïÊ";s:3:"懮";s:2:"ïË";s:3:"懱";s:2:"ïÌ";s:3:"懪";s:2:"ïÍ";s:3:"懰";s:2:"ïÎ";s:3:"懫";s:2:"ïÏ";s:3:"懖";s:2:"ïÐ";s:3:"懩";s:2:"ïÑ";s:3:"æ“¿";s:2:"ïÒ";s:3:"攄";s:2:"ïÓ";s:3:"擽";s:2:"ïÔ";s:3:"擸";s:2:"ïÕ";s:3:"æ”";s:2:"ïÖ";s:3:"攃";s:2:"ï×";s:3:"擼";s:2:"ïØ";s:3:"æ–”";s:2:"ïÙ";s:3:"æ—›";s:2:"ïÚ";s:3:"曚";s:2:"ïÛ";s:3:"æ››";s:2:"ïÜ";s:3:"曘";s:2:"ïÝ";s:3:"æ«…";s:2:"ïÞ";s:3:"檹";s:2:"ïß";s:3:"檽";s:2:"ïà";s:3:"æ«¡";s:2:"ïá";s:3:"櫆";s:2:"ïâ";s:3:"檺";s:2:"ïã";s:3:"檶";s:2:"ïä";s:3:"檷";s:2:"ïå";s:3:"櫇";s:2:"ïæ";s:3:"檴";s:2:"ïç";s:3:"檭";s:2:"ïè";s:3:"æ­ž";s:2:"ïé";s:3:"毉";s:2:"ïê";s:3:"æ°‹";s:2:"ïë";s:3:"瀇";s:2:"ïì";s:3:"瀌";s:2:"ïí";s:3:"ç€";s:2:"ïî";s:3:"ç€";s:2:"ïï";s:3:"瀅";s:2:"ïð";s:3:"瀔";s:2:"ïñ";s:3:"瀎";s:2:"ïò";s:3:"æ¿¿";s:2:"ïó";s:3:"瀀";s:2:"ïô";s:3:"æ¿»";s:2:"ïõ";s:3:"瀦";s:2:"ïö";s:3:"濼";s:2:"ï÷";s:3:"æ¿·";s:2:"ïø";s:3:"瀊";s:2:"ïù";s:3:"çˆ";s:2:"ïú";s:3:"燿";s:2:"ïû";s:3:"燹";s:2:"ïü";s:3:"爃";s:2:"ïý";s:3:"燽";s:2:"ïþ";s:3:"ç¶";s:2:"ð@";s:3:"ç’¸";s:2:"ðA";s:3:"ç“€";s:2:"ðB";s:3:"ç’µ";s:2:"ðC";s:3:"ç“";s:2:"ðD";s:3:"ç’¾";s:2:"ðE";s:3:"ç’¶";s:2:"ðF";s:3:"ç’»";s:2:"ðG";s:3:"ç“‚";s:2:"ðH";s:3:"ç””";s:2:"ðI";s:3:"甓";s:2:"ðJ";s:3:"癜";s:2:"ðK";s:3:"癤";s:2:"ðL";s:3:"ç™™";s:2:"ðM";s:3:"ç™";s:2:"ðN";s:3:"癓";s:2:"ðO";s:3:"ç™—";s:2:"ðP";s:3:"癚";s:2:"ðQ";s:3:"皦";s:2:"ðR";s:3:"çš½";s:2:"ðS";s:3:"盬";s:2:"ðT";s:3:"矂";s:2:"ðU";s:3:"瞺";s:2:"ðV";s:3:"磿";s:2:"ðW";s:3:"礌";s:2:"ðX";s:3:"礓";s:2:"ðY";s:3:"礔";s:2:"ðZ";s:3:"礉";s:2:"ð[";s:3:"ç¤";s:2:"ð\";s:3:"礒";s:2:"ð]";s:3:"礑";s:2:"ð^";s:3:"禭";s:2:"ð_";s:3:"禬";s:2:"ð`";s:3:"穟";s:2:"ða";s:3:"ç°œ";s:2:"ðb";s:3:"ç°©";s:2:"ðc";s:3:"ç°™";s:2:"ðd";s:3:"ç° ";s:2:"ðe";s:3:"ç°Ÿ";s:2:"ðf";s:3:"ç°­";s:2:"ðg";s:3:"ç°";s:2:"ðh";s:3:"ç°¦";s:2:"ði";s:3:"ç°¨";s:2:"ðj";s:3:"ç°¢";s:2:"ðk";s:3:"ç°¥";s:2:"ðl";s:3:"ç°°";s:2:"ðm";s:3:"繜";s:2:"ðn";s:3:"ç¹";s:2:"ðo";s:3:"ç¹–";s:2:"ðp";s:3:"ç¹£";s:2:"ðq";s:3:"繘";s:2:"ðr";s:3:"ç¹¢";s:2:"ðs";s:3:"繟";s:2:"ðt";s:3:"繑";s:2:"ðu";s:3:"ç¹ ";s:2:"ðv";s:3:"ç¹—";s:2:"ðw";s:3:"繓";s:2:"ðx";s:3:"ç¾µ";s:2:"ðy";s:3:"ç¾³";s:2:"ðz";s:3:"ç¿·";s:2:"ð{";s:3:"翸";s:2:"ð|";s:3:"èµ";s:2:"ð}";s:3:"臑";s:2:"ð~";s:3:"臒";s:2:"ð¡";s:3:"è‡";s:2:"ð¢";s:3:"艟";s:2:"ð£";s:3:"艞";s:2:"ð¤";s:3:"è–´";s:2:"ð¥";s:3:"è—†";s:2:"ð¦";s:3:"è—€";s:2:"ð§";s:3:"è—ƒ";s:2:"ð¨";s:3:"è—‚";s:2:"ð©";s:3:"è–³";s:2:"ðª";s:3:"è–µ";s:2:"ð«";s:3:"è–½";s:2:"ð¬";s:3:"è—‡";s:2:"ð­";s:3:"è—„";s:2:"ð®";s:3:"è–¿";s:2:"ð¯";s:3:"è—‹";s:2:"ð°";s:3:"è—Ž";s:2:"ð±";s:3:"è—ˆ";s:2:"ð²";s:3:"è—…";s:2:"ð³";s:3:"è–±";s:2:"ð´";s:3:"è–¶";s:2:"ðµ";s:3:"è—’";s:2:"ð¶";s:3:"蘤";s:2:"ð·";s:3:"è–¸";s:2:"ð¸";s:3:"è–·";s:2:"ð¹";s:3:"è–¾";s:2:"ðº";s:3:"虩";s:2:"ð»";s:3:"蟧";s:2:"ð¼";s:3:"蟦";s:2:"ð½";s:3:"蟢";s:2:"ð¾";s:3:"蟛";s:2:"ð¿";s:3:"蟫";s:2:"ðÀ";s:3:"蟪";s:2:"ðÁ";s:3:"蟥";s:2:"ðÂ";s:3:"蟟";s:2:"ðÃ";s:3:"蟳";s:2:"ðÄ";s:3:"蟤";s:2:"ðÅ";s:3:"蟔";s:2:"ðÆ";s:3:"蟜";s:2:"ðÇ";s:3:"蟓";s:2:"ðÈ";s:3:"蟭";s:2:"ðÉ";s:3:"蟘";s:2:"ðÊ";s:3:"蟣";s:2:"ðË";s:3:"螤";s:2:"ðÌ";s:3:"蟗";s:2:"ðÍ";s:3:"蟙";s:2:"ðÎ";s:3:"è ";s:2:"ðÏ";s:3:"蟴";s:2:"ðÐ";s:3:"蟨";s:2:"ðÑ";s:3:"èŸ";s:2:"ðÒ";s:3:"襓";s:2:"ðÓ";s:3:"襋";s:2:"ðÔ";s:3:"è¥";s:2:"ðÕ";s:3:"襌";s:2:"ðÖ";s:3:"襆";s:2:"ð×";s:3:"è¥";s:2:"ðØ";s:3:"襑";s:2:"ðÙ";s:3:"襉";s:2:"ðÚ";s:3:"謪";s:2:"ðÛ";s:3:"謧";s:2:"ðÜ";s:3:"謣";s:2:"ðÝ";s:3:"謳";s:2:"ðÞ";s:3:"謰";s:2:"ðß";s:3:"謵";s:2:"ðà";s:3:"è­‡";s:2:"ðá";s:3:"謯";s:2:"ðâ";s:3:"謼";s:2:"ðã";s:3:"謾";s:2:"ðä";s:3:"謱";s:2:"ðå";s:3:"謥";s:2:"ðæ";s:3:"謷";s:2:"ðç";s:3:"謦";s:2:"ðè";s:3:"謶";s:2:"ðé";s:3:"謮";s:2:"ðê";s:3:"謤";s:2:"ðë";s:3:"謻";s:2:"ðì";s:3:"謽";s:2:"ðí";s:3:"謺";s:2:"ðî";s:3:"豂";s:2:"ðï";s:3:"è±µ";s:2:"ðð";s:3:"è²™";s:2:"ðñ";s:3:"貘";s:2:"ðò";s:3:"è²—";s:2:"ðó";s:3:"è³¾";s:2:"ðô";s:3:"è´„";s:2:"ðõ";s:3:"è´‚";s:2:"ðö";s:3:"è´€";s:2:"ð÷";s:3:"蹜";s:2:"ðø";s:3:"è¹¢";s:2:"ðù";s:3:"è¹ ";s:2:"ðú";s:3:"è¹—";s:2:"ðû";s:3:"è¹–";s:2:"ðü";s:3:"蹞";s:2:"ðý";s:3:"è¹¥";s:2:"ðþ";s:3:"è¹§";s:2:"ñ@";s:3:"è¹›";s:2:"ñA";s:3:"蹚";s:2:"ñB";s:3:"蹡";s:2:"ñC";s:3:"è¹";s:2:"ñD";s:3:"蹩";s:2:"ñE";s:3:"è¹”";s:2:"ñF";s:3:"轆";s:2:"ñG";s:3:"轇";s:2:"ñH";s:3:"轈";s:2:"ñI";s:3:"轋";s:2:"ñJ";s:3:"鄨";s:2:"ñK";s:3:"鄺";s:2:"ñL";s:3:"é„»";s:2:"ñM";s:3:"鄾";s:2:"ñN";s:3:"醨";s:2:"ñO";s:3:"醥";s:2:"ñP";s:3:"醧";s:2:"ñQ";s:3:"醯";s:2:"ñR";s:3:"醪";s:2:"ñS";s:3:"鎵";s:2:"ñT";s:3:"鎌";s:2:"ñU";s:3:"鎒";s:2:"ñV";s:3:"鎷";s:2:"ñW";s:3:"鎛";s:2:"ñX";s:3:"éŽ";s:2:"ñY";s:3:"鎉";s:2:"ñZ";s:3:"鎧";s:2:"ñ[";s:3:"鎎";s:2:"ñ\";s:3:"鎪";s:2:"ñ]";s:3:"鎞";s:2:"ñ^";s:3:"鎦";s:2:"ñ_";s:3:"鎕";s:2:"ñ`";s:3:"鎈";s:2:"ña";s:3:"鎙";s:2:"ñb";s:3:"鎟";s:2:"ñc";s:3:"éŽ";s:2:"ñd";s:3:"鎱";s:2:"ñe";s:3:"鎑";s:2:"ñf";s:3:"鎲";s:2:"ñg";s:3:"鎤";s:2:"ñh";s:3:"鎨";s:2:"ñi";s:3:"鎴";s:2:"ñj";s:3:"鎣";s:2:"ñk";s:3:"鎥";s:2:"ñl";s:3:"é—’";s:2:"ñm";s:3:"é—“";s:2:"ñn";s:3:"é—‘";s:2:"ño";s:3:"éš³";s:2:"ñp";s:3:"é›—";s:2:"ñq";s:3:"雚";s:2:"ñr";s:3:"å·‚";s:2:"ñs";s:3:"雟";s:2:"ñt";s:3:"雘";s:2:"ñu";s:3:"é›";s:2:"ñv";s:3:"霣";s:2:"ñw";s:3:"霢";s:2:"ñx";s:3:"霥";s:2:"ñy";s:3:"鞬";s:2:"ñz";s:3:"éž®";s:2:"ñ{";s:3:"鞨";s:2:"ñ|";s:3:"éž«";s:2:"ñ}";s:3:"鞤";s:2:"ñ~";s:3:"鞪";s:2:"ñ¡";s:3:"鞢";s:2:"ñ¢";s:3:"鞥";s:2:"ñ£";s:3:"韗";s:2:"ñ¤";s:3:"韙";s:2:"ñ¥";s:3:"韖";s:2:"ñ¦";s:3:"韘";s:2:"ñ§";s:3:"韺";s:2:"ñ¨";s:3:"é¡";s:2:"ñ©";s:3:"é¡‘";s:2:"ñª";s:3:"é¡’";s:2:"ñ«";s:3:"颸";s:2:"ñ¬";s:3:"é¥";s:2:"ñ­";s:3:"餼";s:2:"ñ®";s:3:"餺";s:2:"ñ¯";s:3:"é¨";s:2:"ñ°";s:3:"騋";s:2:"ñ±";s:3:"騉";s:2:"ñ²";s:3:"é¨";s:2:"ñ³";s:3:"騄";s:2:"ñ´";s:3:"騑";s:2:"ñµ";s:3:"騊";s:2:"ñ¶";s:3:"騅";s:2:"ñ·";s:3:"騇";s:2:"ñ¸";s:3:"騆";s:2:"ñ¹";s:3:"é«€";s:2:"ñº";s:3:"髜";s:2:"ñ»";s:3:"鬈";s:2:"ñ¼";s:3:"鬄";s:2:"ñ½";s:3:"鬅";s:2:"ñ¾";s:3:"鬩";s:2:"ñ¿";s:3:"鬵";s:2:"ñÀ";s:3:"é­Š";s:2:"ñÁ";s:3:"é­Œ";s:2:"ñÂ";s:3:"é­‹";s:2:"ñÃ";s:3:"鯇";s:2:"ñÄ";s:3:"鯆";s:2:"ñÅ";s:3:"鯃";s:2:"ñÆ";s:3:"鮿";s:2:"ñÇ";s:3:"é¯";s:2:"ñÈ";s:3:"鮵";s:2:"ñÉ";s:3:"鮸";s:2:"ñÊ";s:3:"鯓";s:2:"ñË";s:3:"é®¶";s:2:"ñÌ";s:3:"鯄";s:2:"ñÍ";s:3:"鮹";s:2:"ñÎ";s:3:"鮽";s:2:"ñÏ";s:3:"鵜";s:2:"ñÐ";s:3:"鵓";s:2:"ñÑ";s:3:"éµ";s:2:"ñÒ";s:3:"鵊";s:2:"ñÓ";s:3:"éµ›";s:2:"ñÔ";s:3:"鵋";s:2:"ñÕ";s:3:"éµ™";s:2:"ñÖ";s:3:"éµ–";s:2:"ñ×";s:3:"鵌";s:2:"ñØ";s:3:"éµ—";s:2:"ñÙ";s:3:"éµ’";s:2:"ñÚ";s:3:"éµ”";s:2:"ñÛ";s:3:"鵟";s:2:"ñÜ";s:3:"鵘";s:2:"ñÝ";s:3:"鵚";s:2:"ñÞ";s:3:"麎";s:2:"ñß";s:3:"麌";s:2:"ñà";s:3:"黟";s:2:"ñá";s:3:"é¼";s:2:"ñâ";s:3:"é¼€";s:2:"ñã";s:3:"é¼–";s:2:"ñä";s:3:"é¼¥";s:2:"ñå";s:3:"鼫";s:2:"ñæ";s:3:"鼪";s:2:"ñç";s:3:"鼩";s:2:"ñè";s:3:"鼨";s:2:"ñé";s:3:"齌";s:2:"ñê";s:3:"齕";s:2:"ñë";s:3:"å„´";s:2:"ñì";s:3:"儵";s:2:"ñí";s:3:"劖";s:2:"ñî";s:3:"å‹·";s:2:"ñï";s:3:"厴";s:2:"ñð";s:3:"åš«";s:2:"ññ";s:3:"åš­";s:2:"ñò";s:3:"嚦";s:2:"ñó";s:3:"åš§";s:2:"ñô";s:3:"嚪";s:2:"ñõ";s:3:"嚬";s:2:"ñö";s:3:"壚";s:2:"ñ÷";s:3:"å£";s:2:"ñø";s:3:"壛";s:2:"ñù";s:3:"夒";s:2:"ñú";s:3:"嬽";s:2:"ñû";s:3:"嬾";s:2:"ñü";s:3:"嬿";s:2:"ñý";s:3:"å·ƒ";s:2:"ñþ";s:3:"å¹°";s:2:"ò@";s:3:"徿";s:2:"òA";s:3:"懻";s:2:"òB";s:3:"攇";s:2:"òC";s:3:"æ”";s:2:"òD";s:3:"æ”";s:2:"òE";s:3:"攉";s:2:"òF";s:3:"攌";s:2:"òG";s:3:"攎";s:2:"òH";s:3:"æ–„";s:2:"òI";s:3:"æ—ž";s:2:"òJ";s:3:"æ—";s:2:"òK";s:3:"曞";s:2:"òL";s:3:"æ«§";s:2:"òM";s:3:"æ« ";s:2:"òN";s:3:"櫌";s:2:"òO";s:3:"æ«‘";s:2:"òP";s:3:"æ«™";s:2:"òQ";s:3:"æ«‹";s:2:"òR";s:3:"櫟";s:2:"òS";s:3:"櫜";s:2:"òT";s:3:"æ«";s:2:"òU";s:3:"æ««";s:2:"òV";s:3:"æ«";s:2:"òW";s:3:"æ«";s:2:"òX";s:3:"櫞";s:2:"òY";s:3:"æ­ ";s:2:"òZ";s:3:"æ®°";s:2:"ò[";s:3:"æ°Œ";s:2:"ò\";s:3:"瀙";s:2:"ò]";s:3:"瀧";s:2:"ò^";s:3:"瀠";s:2:"ò_";s:3:"瀖";s:2:"ò`";s:3:"瀫";s:2:"òa";s:3:"瀡";s:2:"òb";s:3:"瀢";s:2:"òc";s:3:"瀣";s:2:"òd";s:3:"瀩";s:2:"òe";s:3:"瀗";s:2:"òf";s:3:"瀤";s:2:"òg";s:3:"瀜";s:2:"òh";s:3:"瀪";s:2:"òi";s:3:"爌";s:2:"òj";s:3:"爊";s:2:"òk";s:3:"爇";s:2:"òl";s:3:"爂";s:2:"òm";s:3:"爅";s:2:"òn";s:3:"犥";s:2:"òo";s:3:"犦";s:2:"òp";s:3:"犤";s:2:"òq";s:3:"犣";s:2:"òr";s:3:"犡";s:2:"òs";s:3:"ç“‹";s:2:"òt";s:3:"ç“…";s:2:"òu";s:3:"ç’·";s:2:"òv";s:3:"瓃";s:2:"òw";s:3:"ç”–";s:2:"òx";s:3:"ç™ ";s:2:"òy";s:3:"矉";s:2:"òz";s:3:"矊";s:2:"ò{";s:3:"矄";s:2:"ò|";s:3:"矱";s:2:"ò}";s:3:"ç¤";s:2:"ò~";s:3:"礛";s:2:"ò¡";s:3:"礡";s:2:"ò¢";s:3:"礜";s:2:"ò£";s:3:"礗";s:2:"ò¤";s:3:"礞";s:2:"ò¥";s:3:"禰";s:2:"ò¦";s:3:"ç©§";s:2:"ò§";s:3:"穨";s:2:"ò¨";s:3:"ç°³";s:2:"ò©";s:3:"ç°¼";s:2:"òª";s:3:"ç°¹";s:2:"ò«";s:3:"ç°¬";s:2:"ò¬";s:3:"ç°»";s:2:"ò­";s:3:"糬";s:2:"ò®";s:3:"糪";s:2:"ò¯";s:3:"ç¹¶";s:2:"ò°";s:3:"ç¹µ";s:2:"ò±";s:3:"繸";s:2:"ò²";s:3:"ç¹°";s:2:"ò³";s:3:"ç¹·";s:2:"ò´";s:3:"繯";s:2:"òµ";s:3:"繺";s:2:"ò¶";s:3:"ç¹²";s:2:"ò·";s:3:"ç¹´";s:2:"ò¸";s:3:"繨";s:2:"ò¹";s:3:"罋";s:2:"òº";s:3:"罊";s:2:"ò»";s:3:"羃";s:2:"ò¼";s:3:"羆";s:2:"ò½";s:3:"ç¾·";s:2:"ò¾";s:3:"翽";s:2:"ò¿";s:3:"翾";s:2:"òÀ";s:3:"è¸";s:2:"òÁ";s:3:"臗";s:2:"òÂ";s:3:"臕";s:2:"òÃ";s:3:"艤";s:2:"òÄ";s:3:"艡";s:2:"òÅ";s:3:"艣";s:2:"òÆ";s:3:"è—«";s:2:"òÇ";s:3:"è—±";s:2:"òÈ";s:3:"è—­";s:2:"òÉ";s:3:"è—™";s:2:"òÊ";s:3:"è—¡";s:2:"òË";s:3:"è—¨";s:2:"òÌ";s:3:"è—š";s:2:"òÍ";s:3:"è——";s:2:"òÎ";s:3:"è—¬";s:2:"òÏ";s:3:"è—²";s:2:"òÐ";s:3:"è—¸";s:2:"òÑ";s:3:"è—˜";s:2:"òÒ";s:3:"è—Ÿ";s:2:"òÓ";s:3:"è—£";s:2:"òÔ";s:3:"è—œ";s:2:"òÕ";s:3:"è—‘";s:2:"òÖ";s:3:"è—°";s:2:"ò×";s:3:"è—¦";s:2:"òØ";s:3:"è—¯";s:2:"òÙ";s:3:"è—ž";s:2:"òÚ";s:3:"è—¢";s:2:"òÛ";s:3:"è €";s:2:"òÜ";s:3:"蟺";s:2:"òÝ";s:3:"è ƒ";s:2:"òÞ";s:3:"蟶";s:2:"òß";s:3:"蟷";s:2:"òà";s:3:"è ‰";s:2:"òá";s:3:"è Œ";s:2:"òâ";s:3:"è ‹";s:2:"òã";s:3:"è †";s:2:"òä";s:3:"蟼";s:2:"òå";s:3:"è ˆ";s:2:"òæ";s:3:"蟿";s:2:"òç";s:3:"è Š";s:2:"òè";s:3:"è ‚";s:2:"òé";s:3:"襢";s:2:"òê";s:3:"襚";s:2:"òë";s:3:"襛";s:2:"òì";s:3:"襗";s:2:"òí";s:3:"襡";s:2:"òî";s:3:"襜";s:2:"òï";s:3:"襘";s:2:"òð";s:3:"è¥";s:2:"òñ";s:3:"襙";s:2:"òò";s:3:"覈";s:2:"òó";s:3:"覷";s:2:"òô";s:3:"覶";s:2:"òõ";s:3:"è§¶";s:2:"òö";s:3:"è­";s:2:"ò÷";s:3:"è­ˆ";s:2:"òø";s:3:"è­Š";s:2:"òù";s:3:"è­€";s:2:"òú";s:3:"è­“";s:2:"òû";s:3:"è­–";s:2:"òü";s:3:"è­”";s:2:"òý";s:3:"è­‹";s:2:"òþ";s:3:"è­•";s:2:"ó@";s:3:"è­‘";s:2:"óA";s:3:"è­‚";s:2:"óB";s:3:"è­’";s:2:"óC";s:3:"è­—";s:2:"óD";s:3:"豃";s:2:"óE";s:3:"è±·";s:2:"óF";s:3:"è±¶";s:2:"óG";s:3:"貚";s:2:"óH";s:3:"è´†";s:2:"óI";s:3:"è´‡";s:2:"óJ";s:3:"è´‰";s:2:"óK";s:3:"趬";s:2:"óL";s:3:"趪";s:2:"óM";s:3:"è¶­";s:2:"óN";s:3:"è¶«";s:2:"óO";s:3:"è¹­";s:2:"óP";s:3:"蹸";s:2:"óQ";s:3:"è¹³";s:2:"óR";s:3:"蹪";s:2:"óS";s:3:"蹯";s:2:"óT";s:3:"è¹»";s:2:"óU";s:3:"軂";s:2:"óV";s:3:"è½’";s:2:"óW";s:3:"轑";s:2:"óX";s:3:"è½";s:2:"óY";s:3:"è½";s:2:"óZ";s:3:"轓";s:2:"ó[";s:3:"è¾´";s:2:"ó\";s:3:"é…€";s:2:"ó]";s:3:"é„¿";s:2:"ó^";s:3:"醰";s:2:"ó_";s:3:"醭";s:2:"ó`";s:3:"éž";s:2:"óa";s:3:"é‡";s:2:"ób";s:3:"é";s:2:"óc";s:3:"é‚";s:2:"ód";s:3:"éš";s:2:"óe";s:3:"é";s:2:"óf";s:3:"é¹";s:2:"óg";s:3:"é¬";s:2:"óh";s:3:"éŒ";s:2:"ói";s:3:"é™";s:2:"ój";s:3:"鎩";s:2:"ók";s:3:"é¦";s:2:"ól";s:3:"éŠ";s:2:"óm";s:3:"é”";s:2:"ón";s:3:"é®";s:2:"óo";s:3:"é£";s:2:"óp";s:3:"é•";s:2:"óq";s:3:"é„";s:2:"ór";s:3:"éŽ";s:2:"ós";s:3:"é€";s:2:"ót";s:3:"é’";s:2:"óu";s:3:"é§";s:2:"óv";s:3:"镽";s:2:"ów";s:3:"é—š";s:2:"óx";s:3:"é—›";s:2:"óy";s:3:"雡";s:2:"óz";s:3:"霩";s:2:"ó{";s:3:"霫";s:2:"ó|";s:3:"霬";s:2:"ó}";s:3:"霨";s:2:"ó~";s:3:"霦";s:2:"ó¡";s:3:"éž³";s:2:"ó¢";s:3:"éž·";s:2:"ó£";s:3:"éž¶";s:2:"ó¤";s:3:"éŸ";s:2:"ó¥";s:3:"韞";s:2:"ó¦";s:3:"韟";s:2:"ó§";s:3:"顜";s:2:"ó¨";s:3:"é¡™";s:2:"ó©";s:3:"é¡";s:2:"óª";s:3:"é¡—";s:2:"ó«";s:3:"颿";s:2:"ó¬";s:3:"颽";s:2:"ó­";s:3:"颻";s:2:"ó®";s:3:"颾";s:2:"ó¯";s:3:"饈";s:2:"ó°";s:3:"饇";s:2:"ó±";s:3:"饃";s:2:"ó²";s:3:"馦";s:2:"ó³";s:3:"馧";s:2:"ó´";s:3:"騚";s:2:"óµ";s:3:"騕";s:2:"ó¶";s:3:"騥";s:2:"ó·";s:3:"é¨";s:2:"ó¸";s:3:"騤";s:2:"ó¹";s:3:"騛";s:2:"óº";s:3:"騢";s:2:"ó»";s:3:"騠";s:2:"ó¼";s:3:"騧";s:2:"ó½";s:3:"騣";s:2:"ó¾";s:3:"騞";s:2:"ó¿";s:3:"騜";s:2:"óÀ";s:3:"騔";s:2:"óÁ";s:3:"é«‚";s:2:"óÂ";s:3:"鬋";s:2:"óÃ";s:3:"鬊";s:2:"óÄ";s:3:"鬎";s:2:"óÅ";s:3:"鬌";s:2:"óÆ";s:3:"鬷";s:2:"óÇ";s:3:"鯪";s:2:"óÈ";s:3:"鯫";s:2:"óÉ";s:3:"鯠";s:2:"óÊ";s:3:"鯞";s:2:"óË";s:3:"鯤";s:2:"óÌ";s:3:"鯦";s:2:"óÍ";s:3:"鯢";s:2:"óÎ";s:3:"鯰";s:2:"óÏ";s:3:"鯔";s:2:"óÐ";s:3:"鯗";s:2:"óÑ";s:3:"鯬";s:2:"óÒ";s:3:"鯜";s:2:"óÓ";s:3:"鯙";s:2:"óÔ";s:3:"鯥";s:2:"óÕ";s:3:"鯕";s:2:"óÖ";s:3:"鯡";s:2:"ó×";s:3:"鯚";s:2:"óØ";s:3:"éµ·";s:2:"óÙ";s:3:"é¶";s:2:"óÚ";s:3:"é¶Š";s:2:"óÛ";s:3:"é¶„";s:2:"óÜ";s:3:"鶈";s:2:"óÝ";s:3:"éµ±";s:2:"óÞ";s:3:"é¶€";s:2:"óß";s:3:"鵸";s:2:"óà";s:3:"鶆";s:2:"óá";s:3:"é¶‹";s:2:"óâ";s:3:"é¶Œ";s:2:"óã";s:3:"éµ½";s:2:"óä";s:3:"鵫";s:2:"óå";s:3:"éµ´";s:2:"óæ";s:3:"éµµ";s:2:"óç";s:3:"éµ°";s:2:"óè";s:3:"鵩";s:2:"óé";s:3:"é¶…";s:2:"óê";s:3:"éµ³";s:2:"óë";s:3:"éµ»";s:2:"óì";s:3:"é¶‚";s:2:"óí";s:3:"鵯";s:2:"óî";s:3:"éµ¹";s:2:"óï";s:3:"鵿";s:2:"óð";s:3:"鶇";s:2:"óñ";s:3:"鵨";s:2:"óò";s:3:"麔";s:2:"óó";s:3:"麑";s:2:"óô";s:3:"黀";s:2:"óõ";s:3:"黼";s:2:"óö";s:3:"é¼­";s:2:"ó÷";s:3:"é½€";s:2:"óø";s:3:"é½";s:2:"óù";s:3:"é½";s:2:"óú";s:3:"é½–";s:2:"óû";s:3:"é½—";s:2:"óü";s:3:"齘";s:2:"óý";s:3:"匷";s:2:"óþ";s:3:"åš²";s:2:"ô@";s:3:"åšµ";s:2:"ôA";s:3:"åš³";s:2:"ôB";s:3:"壣";s:2:"ôC";s:3:"å­…";s:2:"ôD";s:3:"å·†";s:2:"ôE";s:3:"å·‡";s:2:"ôF";s:3:"å»®";s:2:"ôG";s:3:"廯";s:2:"ôH";s:3:"å¿€";s:2:"ôI";s:3:"å¿";s:2:"ôJ";s:3:"懹";s:2:"ôK";s:3:"æ”—";s:2:"ôL";s:3:"æ”–";s:2:"ôM";s:3:"攕";s:2:"ôN";s:3:"攓";s:2:"ôO";s:3:"æ—Ÿ";s:2:"ôP";s:3:"曨";s:2:"ôQ";s:3:"曣";s:2:"ôR";s:3:"曤";s:2:"ôS";s:3:"櫳";s:2:"ôT";s:3:"æ«°";s:2:"ôU";s:3:"櫪";s:2:"ôV";s:3:"櫨";s:2:"ôW";s:3:"櫹";s:2:"ôX";s:3:"櫱";s:2:"ôY";s:3:"æ«®";s:2:"ôZ";s:3:"櫯";s:2:"ô[";s:3:"瀼";s:2:"ô\";s:3:"瀵";s:2:"ô]";s:3:"瀯";s:2:"ô^";s:3:"瀷";s:2:"ô_";s:3:"瀴";s:2:"ô`";s:3:"瀱";s:2:"ôa";s:3:"ç‚";s:2:"ôb";s:3:"瀸";s:2:"ôc";s:3:"瀿";s:2:"ôd";s:3:"瀺";s:2:"ôe";s:3:"瀹";s:2:"ôf";s:3:"ç€";s:2:"ôg";s:3:"瀻";s:2:"ôh";s:3:"瀳";s:2:"ôi";s:3:"ç";s:2:"ôj";s:3:"爓";s:2:"ôk";s:3:"爔";s:2:"ôl";s:3:"犨";s:2:"ôm";s:3:"ç½";s:2:"ôn";s:3:"ç¼";s:2:"ôo";s:3:"ç’º";s:2:"ôp";s:3:"çš«";s:2:"ôq";s:3:"皪";s:2:"ôr";s:3:"çš¾";s:2:"ôs";s:3:"ç›­";s:2:"ôt";s:3:"矌";s:2:"ôu";s:3:"矎";s:2:"ôv";s:3:"çŸ";s:2:"ôw";s:3:"çŸ";s:2:"ôx";s:3:"矲";s:2:"ôy";s:3:"礥";s:2:"ôz";s:3:"礣";s:2:"ô{";s:3:"礧";s:2:"ô|";s:3:"礨";s:2:"ô}";s:3:"礤";s:2:"ô~";s:3:"礩";s:2:"ô¡";s:3:"禲";s:2:"ô¢";s:3:"ç©®";s:2:"ô£";s:3:"穬";s:2:"ô¤";s:3:"ç©­";s:2:"ô¥";s:3:"ç«·";s:2:"ô¦";s:3:"籉";s:2:"ô§";s:3:"籈";s:2:"ô¨";s:3:"籊";s:2:"ô©";s:3:"籇";s:2:"ôª";s:3:"ç±…";s:2:"ô«";s:3:"ç³®";s:2:"ô¬";s:3:"ç¹»";s:2:"ô­";s:3:"ç¹¾";s:2:"ô®";s:3:"çº";s:2:"ô¯";s:3:"纀";s:2:"ô°";s:3:"羺";s:2:"ô±";s:3:"ç¿¿";s:2:"ô²";s:3:"è¹";s:2:"ô³";s:3:"臛";s:2:"ô´";s:3:"臙";s:2:"ôµ";s:3:"舋";s:2:"ô¶";s:3:"艨";s:2:"ô·";s:3:"艩";s:2:"ô¸";s:3:"蘢";s:2:"ô¹";s:3:"è—¿";s:2:"ôº";s:3:"è˜";s:2:"ô»";s:3:"è—¾";s:2:"ô¼";s:3:"蘛";s:2:"ô½";s:3:"蘀";s:2:"ô¾";s:3:"è—¶";s:2:"ô¿";s:3:"蘄";s:2:"ôÀ";s:3:"蘉";s:2:"ôÁ";s:3:"蘅";s:2:"ôÂ";s:3:"蘌";s:2:"ôÃ";s:3:"è—½";s:2:"ôÄ";s:3:"è ™";s:2:"ôÅ";s:3:"è ";s:2:"ôÆ";s:3:"è ‘";s:2:"ôÇ";s:3:"è —";s:2:"ôÈ";s:3:"è “";s:2:"ôÉ";s:3:"è –";s:2:"ôÊ";s:3:"襣";s:2:"ôË";s:3:"襦";s:2:"ôÌ";s:3:"覹";s:2:"ôÍ";s:3:"è§·";s:2:"ôÎ";s:3:"è­ ";s:2:"ôÏ";s:3:"è­ª";s:2:"ôÐ";s:3:"è­";s:2:"ôÑ";s:3:"è­¨";s:2:"ôÒ";s:3:"è­£";s:2:"ôÓ";s:3:"è­¥";s:2:"ôÔ";s:3:"è­§";s:2:"ôÕ";s:3:"è­­";s:2:"ôÖ";s:3:"è¶®";s:2:"ô×";s:3:"躆";s:2:"ôØ";s:3:"躈";s:2:"ôÙ";s:3:"躄";s:2:"ôÚ";s:3:"è½™";s:2:"ôÛ";s:3:"è½–";s:2:"ôÜ";s:3:"è½—";s:2:"ôÝ";s:3:"轕";s:2:"ôÞ";s:3:"轘";s:2:"ôß";s:3:"轚";s:2:"ôà";s:3:"é‚";s:2:"ôá";s:3:"é…ƒ";s:2:"ôâ";s:3:"é…";s:2:"ôã";s:3:"醷";s:2:"ôä";s:3:"醵";s:2:"ôå";s:3:"醲";s:2:"ôæ";s:3:"醳";s:2:"ôç";s:3:"é‹";s:2:"ôè";s:3:"é“";s:2:"ôé";s:3:"é»";s:2:"ôê";s:3:"é ";s:2:"ôë";s:3:"é";s:2:"ôì";s:3:"é”";s:2:"ôí";s:3:"é¾";s:2:"ôî";s:3:"é•";s:2:"ôï";s:3:"é";s:2:"ôð";s:3:"é¨";s:2:"ôñ";s:3:"é™";s:2:"ôò";s:3:"é";s:2:"ôó";s:3:"éµ";s:2:"ôô";s:3:"é€";s:2:"ôõ";s:3:"é·";s:2:"ôö";s:3:"é‡";s:2:"ô÷";s:3:"éŽ";s:2:"ôø";s:3:"é–";s:2:"ôù";s:3:"é’";s:2:"ôú";s:3:"éº";s:2:"ôû";s:3:"é‰";s:2:"ôü";s:3:"é¸";s:2:"ôý";s:3:"éŠ";s:2:"ôþ";s:3:"é¿";s:2:"õ@";s:3:"é¼";s:2:"õA";s:3:"éŒ";s:2:"õB";s:3:"é¶";s:2:"õC";s:3:"é‘";s:2:"õD";s:3:"é†";s:2:"õE";s:3:"é—ž";s:2:"õF";s:3:"é— ";s:2:"õG";s:3:"é—Ÿ";s:2:"õH";s:3:"霮";s:2:"õI";s:3:"霯";s:2:"õJ";s:3:"éž¹";s:2:"õK";s:3:"éž»";s:2:"õL";s:3:"韽";s:2:"õM";s:3:"韾";s:2:"õN";s:3:"é¡ ";s:2:"õO";s:3:"é¡¢";s:2:"õP";s:3:"é¡£";s:2:"õQ";s:3:"顟";s:2:"õR";s:3:"é£";s:2:"õS";s:3:"飂";s:2:"õT";s:3:"é¥";s:2:"õU";s:3:"饎";s:2:"õV";s:3:"饙";s:2:"õW";s:3:"饌";s:2:"õX";s:3:"饋";s:2:"õY";s:3:"饓";s:2:"õZ";s:3:"騲";s:2:"õ[";s:3:"騴";s:2:"õ\";s:3:"騱";s:2:"õ]";s:3:"騬";s:2:"õ^";s:3:"騪";s:2:"õ_";s:3:"騶";s:2:"õ`";s:3:"騩";s:2:"õa";s:3:"騮";s:2:"õb";s:3:"騸";s:2:"õc";s:3:"騭";s:2:"õd";s:3:"髇";s:2:"õe";s:3:"髊";s:2:"õf";s:3:"髆";s:2:"õg";s:3:"é¬";s:2:"õh";s:3:"鬒";s:2:"õi";s:3:"鬑";s:2:"õj";s:3:"é°‹";s:2:"õk";s:3:"é°ˆ";s:2:"õl";s:3:"鯷";s:2:"õm";s:3:"é°…";s:2:"õn";s:3:"é°’";s:2:"õo";s:3:"鯸";s:2:"õp";s:3:"é±€";s:2:"õq";s:3:"é°‡";s:2:"õr";s:3:"é°Ž";s:2:"õs";s:3:"é°†";s:2:"õt";s:3:"é°—";s:2:"õu";s:3:"é°”";s:2:"õv";s:3:"é°‰";s:2:"õw";s:3:"é¶Ÿ";s:2:"õx";s:3:"é¶™";s:2:"õy";s:3:"鶤";s:2:"õz";s:3:"é¶";s:2:"õ{";s:3:"é¶’";s:2:"õ|";s:3:"鶘";s:2:"õ}";s:3:"é¶";s:2:"õ~";s:3:"é¶›";s:2:"õ¡";s:3:"é¶ ";s:2:"õ¢";s:3:"é¶”";s:2:"õ£";s:3:"é¶œ";s:2:"õ¤";s:3:"鶪";s:2:"õ¥";s:3:"é¶—";s:2:"õ¦";s:3:"é¶¡";s:2:"õ§";s:3:"é¶š";s:2:"õ¨";s:3:"é¶¢";s:2:"õ©";s:3:"鶨";s:2:"õª";s:3:"é¶ž";s:2:"õ«";s:3:"é¶£";s:2:"õ¬";s:3:"é¶¿";s:2:"õ­";s:3:"é¶©";s:2:"õ®";s:3:"é¶–";s:2:"õ¯";s:3:"鶦";s:2:"õ°";s:3:"é¶§";s:2:"õ±";s:3:"麙";s:2:"õ²";s:3:"麛";s:2:"õ³";s:3:"麚";s:2:"õ´";s:3:"黥";s:2:"õµ";s:3:"黤";s:2:"õ¶";s:3:"é»§";s:2:"õ·";s:3:"黦";s:2:"õ¸";s:3:"é¼°";s:2:"õ¹";s:3:"é¼®";s:2:"õº";s:3:"é½›";s:2:"õ»";s:3:"é½ ";s:2:"õ¼";s:3:"齞";s:2:"õ½";s:3:"é½";s:2:"õ¾";s:3:"é½™";s:2:"õ¿";s:3:"龑";s:2:"õÀ";s:3:"儺";s:2:"õÁ";s:3:"儹";s:2:"õÂ";s:3:"劘";s:2:"õÃ";s:3:"劗";s:2:"õÄ";s:3:"囃";s:2:"õÅ";s:3:"åš½";s:2:"õÆ";s:3:"åš¾";s:2:"õÇ";s:3:"å­ˆ";s:2:"õÈ";s:3:"å­‡";s:2:"õÉ";s:3:"å·‹";s:2:"õÊ";s:3:"å·";s:2:"õË";s:3:"å»±";s:2:"õÌ";s:3:"懽";s:2:"õÍ";s:3:"æ”›";s:2:"õÎ";s:3:"欂";s:2:"õÏ";s:3:"櫼";s:2:"õÐ";s:3:"欃";s:2:"õÑ";s:3:"櫸";s:2:"õÒ";s:3:"欀";s:2:"õÓ";s:3:"çƒ";s:2:"õÔ";s:3:"ç„";s:2:"õÕ";s:3:"çŠ";s:2:"õÖ";s:3:"çˆ";s:2:"õ×";s:3:"ç‰";s:2:"õØ";s:3:"ç…";s:2:"õÙ";s:3:"ç†";s:2:"õÚ";s:3:"çˆ";s:2:"õÛ";s:3:"爚";s:2:"õÜ";s:3:"爙";s:2:"õÝ";s:3:"ç¾";s:2:"õÞ";s:3:"ç”—";s:2:"õß";s:3:"癪";s:2:"õà";s:3:"çŸ";s:2:"õá";s:3:"礭";s:2:"õâ";s:3:"礱";s:2:"õã";s:3:"礯";s:2:"õä";s:3:"ç±”";s:2:"õå";s:3:"籓";s:2:"õæ";s:3:"ç³²";s:2:"õç";s:3:"纊";s:2:"õè";s:3:"纇";s:2:"õé";s:3:"纈";s:2:"õê";s:3:"纋";s:2:"õë";s:3:"纆";s:2:"õì";s:3:"çº";s:2:"õí";s:3:"ç½";s:2:"õî";s:3:"ç¾»";s:2:"õï";s:3:"耰";s:2:"õð";s:3:"è‡";s:2:"õñ";s:3:"蘘";s:2:"õò";s:3:"蘪";s:2:"õó";s:3:"蘦";s:2:"õô";s:3:"蘟";s:2:"õõ";s:3:"蘣";s:2:"õö";s:3:"蘜";s:2:"õ÷";s:3:"蘙";s:2:"õø";s:3:"蘧";s:2:"õù";s:3:"蘮";s:2:"õú";s:3:"蘡";s:2:"õû";s:3:"蘠";s:2:"õü";s:3:"蘩";s:2:"õý";s:3:"蘞";s:2:"õþ";s:3:"蘥";s:2:"ö@";s:3:"è ©";s:2:"öA";s:3:"è ";s:2:"öB";s:3:"è ›";s:2:"öC";s:3:"è  ";s:2:"öD";s:3:"è ¤";s:2:"öE";s:3:"è œ";s:2:"öF";s:3:"è «";s:2:"öG";s:3:"衊";s:2:"öH";s:3:"襭";s:2:"öI";s:3:"襩";s:2:"öJ";s:3:"襮";s:2:"öK";s:3:"襫";s:2:"öL";s:3:"觺";s:2:"öM";s:3:"è­¹";s:2:"öN";s:3:"è­¸";s:2:"öO";s:3:"è­…";s:2:"öP";s:3:"è­º";s:2:"öQ";s:3:"è­»";s:2:"öR";s:3:"è´";s:2:"öS";s:3:"è´”";s:2:"öT";s:3:"趯";s:2:"öU";s:3:"躎";s:2:"öV";s:3:"躌";s:2:"öW";s:3:"轞";s:2:"öX";s:3:"è½›";s:2:"öY";s:3:"è½";s:2:"öZ";s:3:"é…†";s:2:"ö[";s:3:"é…„";s:2:"ö\";s:3:"é……";s:2:"ö]";s:3:"醹";s:2:"ö^";s:3:"é¿";s:2:"ö_";s:3:"é»";s:2:"ö`";s:3:"é¶";s:2:"öa";s:3:"é©";s:2:"öb";s:3:"é½";s:2:"öc";s:3:"é¼";s:2:"öd";s:3:"é°";s:2:"öe";s:3:"é¹";s:2:"öf";s:3:"éª";s:2:"ög";s:3:"é·";s:2:"öh";s:3:"é¬";s:2:"öi";s:3:"é‘€";s:2:"öj";s:3:"é±";s:2:"ök";s:3:"é—¥";s:2:"öl";s:3:"é—¤";s:2:"öm";s:3:"é—£";s:2:"ön";s:3:"霵";s:2:"öo";s:3:"霺";s:2:"öp";s:3:"éž¿";s:2:"öq";s:3:"韡";s:2:"ör";s:3:"顤";s:2:"ös";s:3:"飉";s:2:"öt";s:3:"飆";s:2:"öu";s:3:"飀";s:2:"öv";s:3:"饘";s:2:"öw";s:3:"饖";s:2:"öx";s:3:"騹";s:2:"öy";s:3:"騽";s:2:"öz";s:3:"驆";s:2:"ö{";s:3:"é©„";s:2:"ö|";s:3:"é©‚";s:2:"ö}";s:3:"é©";s:2:"ö~";s:3:"騺";s:2:"ö¡";s:3:"騿";s:2:"ö¢";s:3:"é«";s:2:"ö£";s:3:"鬕";s:2:"ö¤";s:3:"鬗";s:2:"ö¥";s:3:"鬘";s:2:"ö¦";s:3:"鬖";s:2:"ö§";s:3:"鬺";s:2:"ö¨";s:3:"é­’";s:2:"ö©";s:3:"é°«";s:2:"öª";s:3:"é°";s:2:"ö«";s:3:"é°œ";s:2:"ö¬";s:3:"é°¬";s:2:"ö­";s:3:"é°£";s:2:"ö®";s:3:"é°¨";s:2:"ö¯";s:3:"é°©";s:2:"ö°";s:3:"é°¤";s:2:"ö±";s:3:"é°¡";s:2:"ö²";s:3:"é¶·";s:2:"ö³";s:3:"é¶¶";s:2:"ö´";s:3:"é¶¼";s:2:"öµ";s:3:"é·";s:2:"ö¶";s:3:"é·‡";s:2:"ö·";s:3:"é·Š";s:2:"ö¸";s:3:"é·";s:2:"ö¹";s:3:"é¶¾";s:2:"öº";s:3:"é·…";s:2:"ö»";s:3:"é·ƒ";s:2:"ö¼";s:3:"é¶»";s:2:"ö½";s:3:"é¶µ";s:2:"ö¾";s:3:"é·Ž";s:2:"ö¿";s:3:"é¶¹";s:2:"öÀ";s:3:"鶺";s:2:"öÁ";s:3:"鶬";s:2:"öÂ";s:3:"é·ˆ";s:2:"öÃ";s:3:"é¶±";s:2:"öÄ";s:3:"é¶­";s:2:"öÅ";s:3:"é·Œ";s:2:"öÆ";s:3:"é¶³";s:2:"öÇ";s:3:"é·";s:2:"öÈ";s:3:"é¶²";s:2:"öÉ";s:3:"鹺";s:2:"öÊ";s:3:"麜";s:2:"öË";s:3:"黫";s:2:"öÌ";s:3:"é»®";s:2:"öÍ";s:3:"é»­";s:2:"öÎ";s:3:"é¼›";s:2:"öÏ";s:3:"鼘";s:2:"öÐ";s:3:"鼚";s:2:"öÑ";s:3:"é¼±";s:2:"öÒ";s:3:"齎";s:2:"öÓ";s:3:"é½¥";s:2:"öÔ";s:3:"齤";s:2:"öÕ";s:3:"é¾’";s:2:"öÖ";s:3:"亹";s:2:"ö×";s:3:"囆";s:2:"öØ";s:3:"å›…";s:2:"öÙ";s:3:"囋";s:2:"öÚ";s:3:"奱";s:2:"öÛ";s:3:"å­‹";s:2:"öÜ";s:3:"å­Œ";s:2:"öÝ";s:3:"å·•";s:2:"öÞ";s:3:"å·‘";s:2:"öß";s:3:"廲";s:2:"öà";s:3:"攡";s:2:"öá";s:3:"æ” ";s:2:"öâ";s:3:"攦";s:2:"öã";s:3:"攢";s:2:"öä";s:3:"欋";s:2:"öå";s:3:"欈";s:2:"öæ";s:3:"欉";s:2:"öç";s:3:"æ°";s:2:"öè";s:3:"ç•";s:2:"öé";s:3:"ç–";s:2:"öê";s:3:"ç—";s:2:"öë";s:3:"ç’";s:2:"öì";s:3:"爞";s:2:"öí";s:3:"爟";s:2:"öî";s:3:"犩";s:2:"öï";s:3:"ç¿";s:2:"öð";s:3:"瓘";s:2:"öñ";s:3:"ç“•";s:2:"öò";s:3:"ç“™";s:2:"öó";s:3:"ç“—";s:2:"öô";s:3:"ç™­";s:2:"öõ";s:3:"çš­";s:2:"öö";s:3:"礵";s:2:"ö÷";s:3:"禴";s:2:"öø";s:3:"ç©°";s:2:"öù";s:3:"穱";s:2:"öú";s:3:"ç±—";s:2:"öû";s:3:"籜";s:2:"öü";s:3:"ç±™";s:2:"öý";s:3:"ç±›";s:2:"öþ";s:3:"籚";s:2:"÷@";s:3:"ç³´";s:2:"÷A";s:3:"ç³±";s:2:"÷B";s:3:"纑";s:2:"÷C";s:3:"ç½";s:2:"÷D";s:3:"羇";s:2:"÷E";s:3:"臞";s:2:"÷F";s:3:"艫";s:2:"÷G";s:3:"蘴";s:2:"÷H";s:3:"蘵";s:2:"÷I";s:3:"蘳";s:2:"÷J";s:3:"蘬";s:2:"÷K";s:3:"蘲";s:2:"÷L";s:3:"蘶";s:2:"÷M";s:3:"è ¬";s:2:"÷N";s:3:"è ¨";s:2:"÷O";s:3:"è ¦";s:2:"÷P";s:3:"è ª";s:2:"÷Q";s:3:"è ¥";s:2:"÷R";s:3:"襱";s:2:"÷S";s:3:"覿";s:2:"÷T";s:3:"覾";s:2:"÷U";s:3:"è§»";s:2:"÷V";s:3:"è­¾";s:2:"÷W";s:3:"讄";s:2:"÷X";s:3:"讂";s:2:"÷Y";s:3:"讆";s:2:"÷Z";s:3:"è®…";s:2:"÷[";s:3:"è­¿";s:2:"÷\";s:3:"è´•";s:2:"÷]";s:3:"躕";s:2:"÷^";s:3:"躔";s:2:"÷_";s:3:"躚";s:2:"÷`";s:3:"躒";s:2:"÷a";s:3:"èº";s:2:"÷b";s:3:"躖";s:2:"÷c";s:3:"躗";s:2:"÷d";s:3:"è½ ";s:2:"÷e";s:3:"è½¢";s:2:"÷f";s:3:"é…‡";s:2:"÷g";s:3:"鑌";s:2:"÷h";s:3:"é‘";s:2:"÷i";s:3:"鑊";s:2:"÷j";s:3:"é‘‹";s:2:"÷k";s:3:"é‘";s:2:"÷l";s:3:"鑇";s:2:"÷m";s:3:"é‘…";s:2:"÷n";s:3:"鑈";s:2:"÷o";s:3:"鑉";s:2:"÷p";s:3:"鑆";s:2:"÷q";s:3:"霿";s:2:"÷r";s:3:"韣";s:2:"÷s";s:3:"顪";s:2:"÷t";s:3:"é¡©";s:2:"÷u";s:3:"飋";s:2:"÷v";s:3:"饔";s:2:"÷w";s:3:"饛";s:2:"÷x";s:3:"驎";s:2:"÷y";s:3:"é©“";s:2:"÷z";s:3:"é©”";s:2:"÷{";s:3:"驌";s:2:"÷|";s:3:"é©";s:2:"÷}";s:3:"驈";s:2:"÷~";s:3:"驊";s:2:"÷¡";s:3:"驉";s:2:"÷¢";s:3:"é©’";s:2:"÷£";s:3:"é©";s:2:"÷¤";s:3:"é«";s:2:"÷¥";s:3:"鬙";s:2:"÷¦";s:3:"鬫";s:2:"÷§";s:3:"鬻";s:2:"÷¨";s:3:"é­–";s:2:"÷©";s:3:"é­•";s:2:"÷ª";s:3:"鱆";s:2:"÷«";s:3:"鱈";s:2:"÷¬";s:3:"é°¿";s:2:"÷­";s:3:"鱄";s:2:"÷®";s:3:"é°¹";s:2:"÷¯";s:3:"é°³";s:2:"÷°";s:3:"é±";s:2:"÷±";s:3:"é°¼";s:2:"÷²";s:3:"é°·";s:2:"÷³";s:3:"é°´";s:2:"÷´";s:3:"é°²";s:2:"÷µ";s:3:"é°½";s:2:"÷¶";s:3:"é°¶";s:2:"÷·";s:3:"é·›";s:2:"÷¸";s:3:"é·’";s:2:"÷¹";s:3:"é·ž";s:2:"÷º";s:3:"é·š";s:2:"÷»";s:3:"é·‹";s:2:"÷¼";s:3:"é·";s:2:"÷½";s:3:"é·œ";s:2:"÷¾";s:3:"é·‘";s:2:"÷¿";s:3:"é·Ÿ";s:2:"÷À";s:3:"é·©";s:2:"÷Á";s:3:"é·™";s:2:"÷Â";s:3:"é·˜";s:2:"÷Ã";s:3:"é·–";s:2:"÷Ä";s:3:"é·µ";s:2:"÷Å";s:3:"é·•";s:2:"÷Æ";s:3:"é·";s:2:"÷Ç";s:3:"麶";s:2:"÷È";s:3:"é»°";s:2:"÷É";s:3:"é¼µ";s:2:"÷Ê";s:3:"é¼³";s:2:"÷Ë";s:3:"é¼²";s:2:"÷Ì";s:3:"齂";s:2:"÷Í";s:3:"齫";s:2:"÷Î";s:3:"龕";s:2:"÷Ï";s:3:"é¾¢";s:2:"÷Ð";s:3:"儽";s:2:"÷Ñ";s:3:"劙";s:2:"÷Ò";s:3:"壨";s:2:"÷Ó";s:3:"壧";s:2:"÷Ô";s:3:"奲";s:2:"÷Õ";s:3:"å­";s:2:"÷Ö";s:3:"å·˜";s:2:"÷×";s:3:"è ¯";s:2:"÷Ø";s:3:"å½";s:2:"÷Ù";s:3:"æˆ";s:2:"÷Ú";s:3:"戃";s:2:"÷Û";s:3:"戄";s:2:"÷Ü";s:3:"攩";s:2:"÷Ý";s:3:"攥";s:2:"÷Þ";s:3:"æ––";s:2:"÷ß";s:3:"曫";s:2:"÷à";s:3:"欑";s:2:"÷á";s:3:"欒";s:2:"÷â";s:3:"æ¬";s:2:"÷ã";s:3:"毊";s:2:"÷ä";s:3:"ç›";s:2:"÷å";s:3:"çš";s:2:"÷æ";s:3:"爢";s:2:"÷ç";s:3:"玂";s:2:"÷è";s:3:"çŽ";s:2:"÷é";s:3:"玃";s:2:"÷ê";s:3:"ç™°";s:2:"÷ë";s:3:"矔";s:2:"÷ì";s:3:"ç±§";s:2:"÷í";s:3:"籦";s:2:"÷î";s:3:"纕";s:2:"÷ï";s:3:"艬";s:2:"÷ð";s:3:"蘺";s:2:"÷ñ";s:3:"虀";s:2:"÷ò";s:3:"蘹";s:2:"÷ó";s:3:"蘼";s:2:"÷ô";s:3:"蘱";s:2:"÷õ";s:3:"蘻";s:2:"÷ö";s:3:"蘾";s:2:"÷÷";s:3:"è °";s:2:"÷ø";s:3:"è ²";s:2:"÷ù";s:3:"è ®";s:2:"÷ú";s:3:"è ³";s:2:"÷û";s:3:"襶";s:2:"÷ü";s:3:"襴";s:2:"÷ý";s:3:"襳";s:2:"÷þ";s:3:"è§¾";s:2:"ø@";s:3:"讌";s:2:"øA";s:3:"讎";s:2:"øB";s:3:"讋";s:2:"øC";s:3:"讈";s:2:"øD";s:3:"è±…";s:2:"øE";s:3:"è´™";s:2:"øF";s:3:"躘";s:2:"øG";s:3:"轤";s:2:"øH";s:3:"è½£";s:2:"øI";s:3:"醼";s:2:"øJ";s:3:"é‘¢";s:2:"øK";s:3:"é‘•";s:2:"øL";s:3:"é‘";s:2:"øM";s:3:"é‘—";s:2:"øN";s:3:"鑞";s:2:"øO";s:3:"韄";s:2:"øP";s:3:"韅";s:2:"øQ";s:3:"é €";s:2:"øR";s:3:"é©–";s:2:"øS";s:3:"é©™";s:2:"øT";s:3:"鬞";s:2:"øU";s:3:"鬟";s:2:"øV";s:3:"鬠";s:2:"øW";s:3:"é±’";s:2:"øX";s:3:"鱘";s:2:"øY";s:3:"é±";s:2:"øZ";s:3:"鱊";s:2:"ø[";s:3:"é±";s:2:"ø\";s:3:"鱋";s:2:"ø]";s:3:"鱕";s:2:"ø^";s:3:"é±™";s:2:"ø_";s:3:"鱌";s:2:"ø`";s:3:"鱎";s:2:"øa";s:3:"é·»";s:2:"øb";s:3:"é··";s:2:"øc";s:3:"é·¯";s:2:"ød";s:3:"é·£";s:2:"øe";s:3:"é·«";s:2:"øf";s:3:"é·¸";s:2:"øg";s:3:"é·¤";s:2:"øh";s:3:"é·¶";s:2:"øi";s:3:"é·¡";s:2:"øj";s:3:"é·®";s:2:"øk";s:3:"é·¦";s:2:"øl";s:3:"é·²";s:2:"øm";s:3:"é·°";s:2:"øn";s:3:"é·¢";s:2:"øo";s:3:"é·¬";s:2:"øp";s:3:"é·´";s:2:"øq";s:3:"é·³";s:2:"ør";s:3:"é·¨";s:2:"øs";s:3:"é·­";s:2:"øt";s:3:"黂";s:2:"øu";s:3:"é»";s:2:"øv";s:3:"黲";s:2:"øw";s:3:"黳";s:2:"øx";s:3:"鼆";s:2:"øy";s:3:"鼜";s:2:"øz";s:3:"鼸";s:2:"ø{";s:3:"é¼·";s:2:"ø|";s:3:"é¼¶";s:2:"ø}";s:3:"齃";s:2:"ø~";s:3:"é½";s:2:"ø¡";s:3:"é½±";s:2:"ø¢";s:3:"é½°";s:2:"ø£";s:3:"é½®";s:2:"ø¤";s:3:"齯";s:2:"ø¥";s:3:"囓";s:2:"ø¦";s:3:"å›";s:2:"ø§";s:3:"å­Ž";s:2:"ø¨";s:3:"å±­";s:2:"ø©";s:3:"æ”­";s:2:"øª";s:3:"æ›­";s:2:"ø«";s:3:"æ›®";s:2:"ø¬";s:3:"欓";s:2:"ø­";s:3:"çŸ";s:2:"ø®";s:3:"ç¡";s:2:"ø¯";s:3:"ç";s:2:"ø°";s:3:"ç ";s:2:"ø±";s:3:"爣";s:2:"ø²";s:3:"ç“›";s:2:"ø³";s:3:"ç“¥";s:2:"ø´";s:3:"矕";s:2:"øµ";s:3:"礸";s:2:"ø¶";s:3:"禷";s:2:"ø·";s:3:"禶";s:2:"ø¸";s:3:"籪";s:2:"ø¹";s:3:"纗";s:2:"øº";s:3:"羉";s:2:"ø»";s:3:"艭";s:2:"ø¼";s:3:"虃";s:2:"ø½";s:3:"è ¸";s:2:"ø¾";s:3:"è ·";s:2:"ø¿";s:3:"è µ";s:2:"øÀ";s:3:"è¡‹";s:2:"øÁ";s:3:"è®”";s:2:"øÂ";s:3:"讕";s:2:"øÃ";s:3:"躞";s:2:"øÄ";s:3:"躟";s:2:"øÅ";s:3:"躠";s:2:"øÆ";s:3:"èº";s:2:"øÇ";s:3:"醾";s:2:"øÈ";s:3:"醽";s:2:"øÉ";s:3:"釂";s:2:"øÊ";s:3:"é‘«";s:2:"øË";s:3:"鑨";s:2:"øÌ";s:3:"é‘©";s:2:"øÍ";s:3:"雥";s:2:"øÎ";s:3:"é†";s:2:"øÏ";s:3:"éƒ";s:2:"øÐ";s:3:"é‡";s:2:"øÑ";s:3:"韇";s:2:"øÒ";s:3:"韥";s:2:"øÓ";s:3:"驞";s:2:"øÔ";s:3:"é«•";s:2:"øÕ";s:3:"é­™";s:2:"øÖ";s:3:"é±£";s:2:"ø×";s:3:"é±§";s:2:"øØ";s:3:"鱦";s:2:"øÙ";s:3:"é±¢";s:2:"øÚ";s:3:"鱞";s:2:"øÛ";s:3:"é± ";s:2:"øÜ";s:3:"鸂";s:2:"øÝ";s:3:"é·¾";s:2:"øÞ";s:3:"鸇";s:2:"øß";s:3:"鸃";s:2:"øà";s:3:"鸆";s:2:"øá";s:3:"鸅";s:2:"øâ";s:3:"鸀";s:2:"øã";s:3:"é¸";s:2:"øä";s:3:"鸉";s:2:"øå";s:3:"é·¿";s:2:"øæ";s:3:"é·½";s:2:"øç";s:3:"鸄";s:2:"øè";s:3:"麠";s:2:"øé";s:3:"鼞";s:2:"øê";s:3:"齆";s:2:"øë";s:3:"é½´";s:2:"øì";s:3:"é½µ";s:2:"øí";s:3:"é½¶";s:2:"øî";s:3:"å›”";s:2:"øï";s:3:"æ”®";s:2:"øð";s:3:"æ–¸";s:2:"øñ";s:3:"欘";s:2:"øò";s:3:"欙";s:2:"øó";s:3:"欗";s:2:"øô";s:3:"欚";s:2:"øõ";s:3:"ç¢";s:2:"øö";s:3:"爦";s:2:"ø÷";s:3:"犪";s:2:"øø";s:3:"矘";s:2:"øù";s:3:"矙";s:2:"øú";s:3:"礹";s:2:"øû";s:3:"籩";s:2:"øü";s:3:"籫";s:2:"øý";s:3:"ç³¶";s:2:"øþ";s:3:"纚";s:2:"ù@";s:3:"纘";s:2:"ùA";s:3:"纛";s:2:"ùB";s:3:"纙";s:2:"ùC";s:3:"臠";s:2:"ùD";s:3:"臡";s:2:"ùE";s:3:"虆";s:2:"ùF";s:3:"虇";s:2:"ùG";s:3:"虈";s:2:"ùH";s:3:"襹";s:2:"ùI";s:3:"襺";s:2:"ùJ";s:3:"襼";s:2:"ùK";s:3:"襻";s:2:"ùL";s:3:"è§¿";s:2:"ùM";s:3:"讘";s:2:"ùN";s:3:"è®™";s:2:"ùO";s:3:"躥";s:2:"ùP";s:3:"躤";s:2:"ùQ";s:3:"躣";s:2:"ùR";s:3:"é‘®";s:2:"ùS";s:3:"é‘­";s:2:"ùT";s:3:"鑯";s:2:"ùU";s:3:"鑱";s:2:"ùV";s:3:"鑳";s:2:"ùW";s:3:"é‰";s:2:"ùX";s:3:"顲";s:2:"ùY";s:3:"饟";s:2:"ùZ";s:3:"鱨";s:2:"ù[";s:3:"é±®";s:2:"ù\";s:3:"é±­";s:2:"ù]";s:3:"鸋";s:2:"ù^";s:3:"é¸";s:2:"ù_";s:3:"é¸";s:2:"ù`";s:3:"é¸";s:2:"ùa";s:3:"鸒";s:2:"ùb";s:3:"鸑";s:2:"ùc";s:3:"麡";s:2:"ùd";s:3:"黵";s:2:"ùe";s:3:"鼉";s:2:"ùf";s:3:"齇";s:2:"ùg";s:3:"齸";s:2:"ùh";s:3:"é½»";s:2:"ùi";s:3:"齺";s:2:"ùj";s:3:"é½¹";s:2:"ùk";s:3:"圞";s:2:"ùl";s:3:"ç¦";s:2:"ùm";s:3:"籯";s:2:"ùn";s:3:"è ¼";s:2:"ùo";s:3:"è¶²";s:2:"ùp";s:3:"躦";s:2:"ùq";s:3:"釃";s:2:"ùr";s:3:"é‘´";s:2:"ùs";s:3:"鑸";s:2:"ùt";s:3:"é‘¶";s:2:"ùu";s:3:"鑵";s:2:"ùv";s:3:"é© ";s:2:"ùw";s:3:"é±´";s:2:"ùx";s:3:"é±³";s:2:"ùy";s:3:"é±±";s:2:"ùz";s:3:"é±µ";s:2:"ù{";s:3:"鸔";s:2:"ù|";s:3:"鸓";s:2:"ù}";s:3:"é»¶";s:2:"ù~";s:3:"鼊";s:2:"ù¡";s:3:"龤";s:2:"ù¢";s:3:"ç¨";s:2:"ù£";s:3:"ç¥";s:2:"ù¤";s:3:"ç³·";s:2:"ù¥";s:3:"虪";s:2:"ù¦";s:3:"è ¾";s:2:"ù§";s:3:"è ½";s:2:"ù¨";s:3:"è ¿";s:2:"ù©";s:3:"讞";s:2:"ùª";s:3:"貜";s:2:"ù«";s:3:"躩";s:2:"ù¬";s:3:"軉";s:2:"ù­";s:3:"é‹";s:2:"ù®";s:3:"顳";s:2:"ù¯";s:3:"é¡´";s:2:"ù°";s:3:"飌";s:2:"ù±";s:3:"饡";s:2:"ù²";s:3:"馫";s:2:"ù³";s:3:"驤";s:2:"ù´";s:3:"驦";s:2:"ùµ";s:3:"é©§";s:2:"ù¶";s:3:"鬤";s:2:"ù·";s:3:"鸕";s:2:"ù¸";s:3:"鸗";s:2:"ù¹";s:3:"齈";s:2:"ùº";s:3:"戇";s:2:"ù»";s:3:"欞";s:2:"ù¼";s:3:"爧";s:2:"ù½";s:3:"虌";s:2:"ù¾";s:3:"躨";s:2:"ù¿";s:3:"é’‚";s:2:"ùÀ";s:3:"é’€";s:2:"ùÁ";s:3:"é’";s:2:"ùÂ";s:3:"é©©";s:2:"ùÃ";s:3:"驨";s:2:"ùÄ";s:3:"鬮";s:2:"ùÅ";s:3:"鸙";s:2:"ùÆ";s:3:"爩";s:2:"ùÇ";s:3:"虋";s:2:"ùÈ";s:3:"讟";s:2:"ùÉ";s:3:"é’ƒ";s:2:"ùÊ";s:3:"é±¹";s:2:"ùË";s:3:"麷";s:2:"ùÌ";s:3:"癵";s:2:"ùÍ";s:3:"é©«";s:2:"ùÎ";s:3:"鱺";s:2:"ùÏ";s:3:"é¸";s:2:"ùÐ";s:3:"ç©";s:2:"ùÑ";s:3:"çª";s:2:"ùÒ";s:3:"麤";s:2:"ùÓ";s:3:"é½¾";s:2:"ùÔ";s:3:"齉";s:2:"ùÕ";s:3:"龘";} \ No newline at end of file diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp037.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp037.ser deleted file mode 100644 index a629eb49..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp037.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1006.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1006.ser deleted file mode 100644 index d3a6c4c8..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1006.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1026.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1026.ser deleted file mode 100644 index 8ec9bea3..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp1026.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp424.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp424.ser deleted file mode 100644 index 5e1168e5..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp424.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp437.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp437.ser deleted file mode 100644 index aa20fd82..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp437.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp500.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp500.ser deleted file mode 100644 index 9bdfdfbc..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp500.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp737.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp737.ser deleted file mode 100644 index d586ac9a..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp737.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp775.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp775.ser deleted file mode 100644 index c993ef5b..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp775.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp850.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp850.ser deleted file mode 100644 index 8035a913..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp850.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp852.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp852.ser deleted file mode 100644 index 83d6b3c8..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp852.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp855.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp855.ser deleted file mode 100644 index 2b99b4c5..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp855.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp856.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp856.ser deleted file mode 100644 index bcc21feb..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp856.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp857.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp857.ser deleted file mode 100644 index a7074a46..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp857.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp860.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp860.ser deleted file mode 100644 index 848d9fe4..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp860.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp861.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp861.ser deleted file mode 100644 index e0469a6f..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp861.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp862.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp862.ser deleted file mode 100644 index eabcebf8..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp862.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp863.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp863.ser deleted file mode 100644 index a64d70a0..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp863.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp864.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp864.ser deleted file mode 100644 index 1d9c3713..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp864.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp865.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp865.ser deleted file mode 100644 index 816ddf37..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp865.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp866.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp866.ser deleted file mode 100644 index 8e0f7dcb..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp866.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp869.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp869.ser deleted file mode 100644 index 32de1f2a..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp869.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp874.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp874.ser deleted file mode 100644 index 030ce156..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp874.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp875.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp875.ser deleted file mode 100644 index e42792a2..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp875.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp932.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp932.ser deleted file mode 100644 index 5861d4c9..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp932.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp936.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp936.ser deleted file mode 100644 index 8fc183b5..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp936.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp949.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp949.ser deleted file mode 100644 index 4447cdb8..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp949.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp950.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.cp950.ser deleted file mode 100644 index b2f11df1..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.cp950.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-1.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-1.ser deleted file mode 100644 index 5fecd4ca..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-1.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-10.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-10.ser deleted file mode 100644 index 3f0cce13..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-10.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-11.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-11.ser deleted file mode 100644 index 2757b1ce..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-11.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-13.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-13.ser deleted file mode 100644 index 55a7a3e1..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-13.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-14.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-14.ser deleted file mode 100644 index 7b963ae8..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-14.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-15.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-15.ser deleted file mode 100644 index 2ce20a16..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-15.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-16.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-16.ser deleted file mode 100644 index 8da24829..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-16.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-2.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-2.ser deleted file mode 100644 index 7dbeb25b..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-2.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-3.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-3.ser deleted file mode 100644 index 626fffe6..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-3.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-4.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-4.ser deleted file mode 100644 index f7501691..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-4.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-5.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-5.ser deleted file mode 100644 index d89cc063..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-5.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-6.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-6.ser deleted file mode 100644 index 2dcfeb89..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-6.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-7.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-7.ser deleted file mode 100644 index a1375583..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-7.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-8.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-8.ser deleted file mode 100644 index 4179e15b..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-8.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-9.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-9.ser deleted file mode 100644 index be4c816e..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.iso-8859-9.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-r.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-r.ser deleted file mode 100644 index c46860b9..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-r.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-u.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-u.ser deleted file mode 100644 index 6e5af630..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.koi8-u.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.us-ascii.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.us-ascii.ser deleted file mode 100644 index 3a2f7e49..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.us-ascii.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1250.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1250.ser deleted file mode 100644 index 9e799cb5..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1250.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1251.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1251.ser deleted file mode 100644 index 6592885c..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1251.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1252.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1252.ser deleted file mode 100644 index cccc26c9..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1252.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1253.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1253.ser deleted file mode 100644 index 13c5a0b6..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1253.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1254.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1254.ser deleted file mode 100644 index 96d69722..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1254.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1255.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1255.ser deleted file mode 100644 index c366bfdb..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1255.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1256.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1256.ser deleted file mode 100644 index cc98d2c6..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1256.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1257.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1257.ser deleted file mode 100644 index 2a522061..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1257.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1258.ser b/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1258.ser deleted file mode 100644 index 114dd846..00000000 Binary files a/vendor/symfony/polyfill-iconv/Resources/charset/from.windows-1258.ser and /dev/null differ diff --git a/vendor/symfony/polyfill-iconv/Resources/charset/translit.ser b/vendor/symfony/polyfill-iconv/Resources/charset/translit.ser deleted file mode 100644 index 5e5652dc..00000000 --- a/vendor/symfony/polyfill-iconv/Resources/charset/translit.ser +++ /dev/null @@ -1 +0,0 @@ -a:3960:{s:2:"µ";s:2:"μ";s:2:"¼";s:7:" 1â„4 ";s:2:"½";s:7:" 1â„2 ";s:2:"¾";s:7:" 3â„4 ";s:2:"IJ";s:2:"IJ";s:2:"ij";s:2:"ij";s:2:"Ä¿";s:3:"L·";s:2:"Å€";s:3:"l·";s:2:"ʼn";s:3:"ʼn";s:2:"Å¿";s:1:"s";s:2:"Ç„";s:3:"DŽ";s:2:"Ç…";s:3:"Dž";s:2:"dž";s:3:"dž";s:2:"LJ";s:2:"LJ";s:2:"Lj";s:2:"Lj";s:2:"lj";s:2:"lj";s:2:"ÇŠ";s:2:"NJ";s:2:"Ç‹";s:2:"Nj";s:2:"ÇŒ";s:2:"nj";s:2:"DZ";s:2:"DZ";s:2:"Dz";s:2:"Dz";s:2:"dz";s:2:"dz";s:2:"Ï";s:2:"β";s:2:"Ï‘";s:2:"θ";s:2:"Ï’";s:2:"Î¥";s:2:"Ï•";s:2:"φ";s:2:"Ï–";s:2:"Ï€";s:2:"ϰ";s:2:"κ";s:2:"ϱ";s:2:"Ï";s:2:"ϲ";s:2:"Ï‚";s:2:"Ï´";s:2:"Θ";s:2:"ϵ";s:2:"ε";s:2:"Ϲ";s:2:"Σ";s:2:"Ö‡";s:4:"Õ¥Ö‚";s:2:"Ùµ";s:4:"اٴ";s:2:"Ù¶";s:4:"وٴ";s:2:"Ù·";s:4:"Û‡Ù´";s:2:"Ù¸";s:4:"يٴ";s:3:"ำ";s:6:"à¹à¸²";s:3:"ຳ";s:6:"à»àº²";s:3:"ໜ";s:6:"ຫນ";s:3:"à»";s:6:"ຫມ";s:3:"ཷ";s:6:"ྲà¾";s:3:"ཹ";s:6:"ླà¾";s:3:"ẚ";s:3:"aʾ";s:3:"․";s:1:".";s:3:"‥";s:2:"..";s:3:"…";s:3:"...";s:3:"″";s:6:"′′";s:3:"‴";s:9:"′′′";s:3:"‶";s:6:"‵‵";s:3:"‷";s:9:"‵‵‵";s:3:"‼";s:2:"!!";s:3:"â‡";s:2:"??";s:3:"âˆ";s:2:"?!";s:3:"â‰";s:2:"!?";s:3:"â—";s:12:"′′′′";s:3:"₨";s:2:"Rs";s:3:"â„€";s:3:"a/c";s:3:"â„";s:3:"a/s";s:3:"â„‚";s:1:"C";s:3:"℃";s:3:"°C";s:3:"â„…";s:3:"c/o";s:3:"℆";s:3:"c/u";s:3:"ℇ";s:2:"Æ";s:3:"℉";s:3:"°F";s:3:"ℊ";s:1:"g";s:3:"â„‹";s:1:"H";s:3:"ℌ";s:1:"H";s:3:"â„";s:1:"H";s:3:"ℎ";s:1:"h";s:3:"â„";s:2:"ħ";s:3:"â„";s:1:"I";s:3:"â„‘";s:1:"I";s:3:"â„’";s:1:"L";s:3:"â„“";s:1:"l";s:3:"â„•";s:1:"N";s:3:"â„–";s:2:"No";s:3:"â„™";s:1:"P";s:3:"ℚ";s:1:"Q";s:3:"â„›";s:1:"R";s:3:"ℜ";s:1:"R";s:3:"â„";s:1:"R";s:3:"â„¡";s:3:"TEL";s:3:"ℤ";s:1:"Z";s:3:"ℨ";s:1:"Z";s:3:"ℬ";s:1:"B";s:3:"â„­";s:1:"C";s:3:"ℯ";s:1:"e";s:3:"â„°";s:1:"E";s:3:"ℱ";s:1:"F";s:3:"ℳ";s:1:"M";s:3:"â„´";s:1:"o";s:3:"ℵ";s:2:"×";s:3:"â„¶";s:2:"ב";s:3:"â„·";s:2:"×’";s:3:"ℸ";s:2:"ד";s:3:"ℹ";s:1:"i";s:3:"â„»";s:3:"FAX";s:3:"ℼ";s:2:"Ï€";s:3:"ℽ";s:2:"γ";s:3:"ℾ";s:2:"Γ";s:3:"â„¿";s:2:"Π";s:3:"â…€";s:3:"∑";s:3:"â……";s:1:"D";s:3:"â…†";s:1:"d";s:3:"â…‡";s:1:"e";s:3:"â…ˆ";s:1:"i";s:3:"â…‰";s:1:"j";s:3:"â…";s:7:" 1â„7 ";s:3:"â…‘";s:7:" 1â„9 ";s:3:"â…’";s:8:" 1â„10 ";s:3:"â…“";s:7:" 1â„3 ";s:3:"â…”";s:7:" 2â„3 ";s:3:"â…•";s:7:" 1â„5 ";s:3:"â…–";s:7:" 2â„5 ";s:3:"â…—";s:7:" 3â„5 ";s:3:"â…˜";s:7:" 4â„5 ";s:3:"â…™";s:7:" 1â„6 ";s:3:"â…š";s:7:" 5â„6 ";s:3:"â…›";s:7:" 1â„8 ";s:3:"â…œ";s:7:" 3â„8 ";s:3:"â…";s:7:" 5â„8 ";s:3:"â…ž";s:7:" 7â„8 ";s:3:"â…Ÿ";s:6:" 1â„ ";s:3:"â… ";s:1:"I";s:3:"â…¡";s:2:"II";s:3:"â…¢";s:3:"III";s:3:"â…£";s:2:"IV";s:3:"â…¤";s:1:"V";s:3:"â…¥";s:2:"VI";s:3:"â…¦";s:3:"VII";s:3:"â…§";s:4:"VIII";s:3:"â…¨";s:2:"IX";s:3:"â…©";s:1:"X";s:3:"â…ª";s:2:"XI";s:3:"â…«";s:3:"XII";s:3:"â…¬";s:1:"L";s:3:"â…­";s:1:"C";s:3:"â…®";s:1:"D";s:3:"â…¯";s:1:"M";s:3:"â…°";s:1:"i";s:3:"â…±";s:2:"ii";s:3:"â…²";s:3:"iii";s:3:"â…³";s:2:"iv";s:3:"â…´";s:1:"v";s:3:"â…µ";s:2:"vi";s:3:"â…¶";s:3:"vii";s:3:"â…·";s:4:"viii";s:3:"â…¸";s:2:"ix";s:3:"â…¹";s:1:"x";s:3:"â…º";s:2:"xi";s:3:"â…»";s:3:"xii";s:3:"â…¼";s:1:"l";s:3:"â…½";s:1:"c";s:3:"â…¾";s:1:"d";s:3:"â…¿";s:1:"m";s:3:"↉";s:7:" 0â„3 ";s:3:"∬";s:6:"∫∫";s:3:"∭";s:9:"∫∫∫";s:3:"∯";s:6:"∮∮";s:3:"∰";s:9:"∮∮∮";s:3:"â‘ ";s:3:"(1)";s:3:"â‘¡";s:3:"(2)";s:3:"â‘¢";s:3:"(3)";s:3:"â‘£";s:3:"(4)";s:3:"⑤";s:3:"(5)";s:3:"â‘¥";s:3:"(6)";s:3:"⑦";s:3:"(7)";s:3:"â‘§";s:3:"(8)";s:3:"⑨";s:3:"(9)";s:3:"â‘©";s:4:"(10)";s:3:"⑪";s:4:"(11)";s:3:"â‘«";s:4:"(12)";s:3:"⑬";s:4:"(13)";s:3:"â‘­";s:4:"(14)";s:3:"â‘®";s:4:"(15)";s:3:"⑯";s:4:"(16)";s:3:"â‘°";s:4:"(17)";s:3:"⑱";s:4:"(18)";s:3:"⑲";s:4:"(19)";s:3:"⑳";s:4:"(20)";s:3:"â‘´";s:3:"(1)";s:3:"⑵";s:3:"(2)";s:3:"â‘¶";s:3:"(3)";s:3:"â‘·";s:3:"(4)";s:3:"⑸";s:3:"(5)";s:3:"⑹";s:3:"(6)";s:3:"⑺";s:3:"(7)";s:3:"â‘»";s:3:"(8)";s:3:"⑼";s:3:"(9)";s:3:"⑽";s:4:"(10)";s:3:"⑾";s:4:"(11)";s:3:"â‘¿";s:4:"(12)";s:3:"â’€";s:4:"(13)";s:3:"â’";s:4:"(14)";s:3:"â’‚";s:4:"(15)";s:3:"â’ƒ";s:4:"(16)";s:3:"â’„";s:4:"(17)";s:3:"â’…";s:4:"(18)";s:3:"â’†";s:4:"(19)";s:3:"â’‡";s:4:"(20)";s:3:"â’ˆ";s:2:"1.";s:3:"â’‰";s:2:"2.";s:3:"â’Š";s:2:"3.";s:3:"â’‹";s:2:"4.";s:3:"â’Œ";s:2:"5.";s:3:"â’";s:2:"6.";s:3:"â’Ž";s:2:"7.";s:3:"â’";s:2:"8.";s:3:"â’";s:2:"9.";s:3:"â’‘";s:3:"10.";s:3:"â’’";s:3:"11.";s:3:"â’“";s:3:"12.";s:3:"â’”";s:3:"13.";s:3:"â’•";s:3:"14.";s:3:"â’–";s:3:"15.";s:3:"â’—";s:3:"16.";s:3:"â’˜";s:3:"17.";s:3:"â’™";s:3:"18.";s:3:"â’š";s:3:"19.";s:3:"â’›";s:3:"20.";s:3:"â’œ";s:3:"(a)";s:3:"â’";s:3:"(b)";s:3:"â’ž";s:3:"(c)";s:3:"â’Ÿ";s:3:"(d)";s:3:"â’ ";s:3:"(e)";s:3:"â’¡";s:3:"(f)";s:3:"â’¢";s:3:"(g)";s:3:"â’£";s:3:"(h)";s:3:"â’¤";s:3:"(i)";s:3:"â’¥";s:3:"(j)";s:3:"â’¦";s:3:"(k)";s:3:"â’§";s:3:"(l)";s:3:"â’¨";s:3:"(m)";s:3:"â’©";s:3:"(n)";s:3:"â’ª";s:3:"(o)";s:3:"â’«";s:3:"(p)";s:3:"â’¬";s:3:"(q)";s:3:"â’­";s:3:"(r)";s:3:"â’®";s:3:"(s)";s:3:"â’¯";s:3:"(t)";s:3:"â’°";s:3:"(u)";s:3:"â’±";s:3:"(v)";s:3:"â’²";s:3:"(w)";s:3:"â’³";s:3:"(x)";s:3:"â’´";s:3:"(y)";s:3:"â’µ";s:3:"(z)";s:3:"â’¶";s:3:"(A)";s:3:"â’·";s:3:"(B)";s:3:"â’¸";s:3:"(C)";s:3:"â’¹";s:3:"(D)";s:3:"â’º";s:3:"(E)";s:3:"â’»";s:3:"(F)";s:3:"â’¼";s:3:"(G)";s:3:"â’½";s:3:"(H)";s:3:"â’¾";s:3:"(I)";s:3:"â’¿";s:3:"(J)";s:3:"â“€";s:3:"(K)";s:3:"â“";s:3:"(L)";s:3:"â“‚";s:3:"(M)";s:3:"Ⓝ";s:3:"(N)";s:3:"â“„";s:3:"(O)";s:3:"â“…";s:3:"(P)";s:3:"Ⓠ";s:3:"(Q)";s:3:"Ⓡ";s:3:"(R)";s:3:"Ⓢ";s:3:"(S)";s:3:"Ⓣ";s:3:"(T)";s:3:"Ⓤ";s:3:"(U)";s:3:"â“‹";s:3:"(V)";s:3:"Ⓦ";s:3:"(W)";s:3:"â“";s:3:"(X)";s:3:"Ⓨ";s:3:"(Y)";s:3:"â“";s:3:"(Z)";s:3:"â“";s:3:"(a)";s:3:"â“‘";s:3:"(b)";s:3:"â“’";s:3:"(c)";s:3:"â““";s:3:"(d)";s:3:"â“”";s:3:"(e)";s:3:"â“•";s:3:"(f)";s:3:"â“–";s:3:"(g)";s:3:"â“—";s:3:"(h)";s:3:"ⓘ";s:3:"(i)";s:3:"â“™";s:3:"(j)";s:3:"ⓚ";s:3:"(k)";s:3:"â“›";s:3:"(l)";s:3:"ⓜ";s:3:"(m)";s:3:"â“";s:3:"(n)";s:3:"ⓞ";s:3:"(o)";s:3:"ⓟ";s:3:"(p)";s:3:"â“ ";s:3:"(q)";s:3:"â“¡";s:3:"(r)";s:3:"â“¢";s:3:"(s)";s:3:"â“£";s:3:"(t)";s:3:"ⓤ";s:3:"(u)";s:3:"â“¥";s:3:"(v)";s:3:"ⓦ";s:3:"(w)";s:3:"â“§";s:3:"(x)";s:3:"ⓨ";s:3:"(y)";s:3:"â“©";s:3:"(z)";s:3:"⓪";s:3:"(0)";s:3:"⨌";s:12:"∫∫∫∫";s:3:"â©´";s:3:"::=";s:3:"⩵";s:2:"==";s:3:"â©¶";s:3:"===";s:3:"⺟";s:3:"æ¯";s:3:"⻳";s:3:"龟";s:3:"â¼€";s:3:"一";s:3:"â¼";s:3:"丨";s:3:"⼂";s:3:"丶";s:3:"⼃";s:3:"丿";s:3:"⼄";s:3:"ä¹™";s:3:"â¼…";s:3:"亅";s:3:"⼆";s:3:"二";s:3:"⼇";s:3:"亠";s:3:"⼈";s:3:"人";s:3:"⼉";s:3:"å„¿";s:3:"⼊";s:3:"å…¥";s:3:"⼋";s:3:"å…«";s:3:"⼌";s:3:"冂";s:3:"â¼";s:3:"冖";s:3:"⼎";s:3:"冫";s:3:"â¼";s:3:"几";s:3:"â¼";s:3:"凵";s:3:"⼑";s:3:"刀";s:3:"â¼’";s:3:"力";s:3:"⼓";s:3:"勹";s:3:"â¼”";s:3:"匕";s:3:"⼕";s:3:"匚";s:3:"â¼–";s:3:"匸";s:3:"â¼—";s:3:"å";s:3:"⼘";s:3:"åœ";s:3:"â¼™";s:3:"å©";s:3:"⼚";s:3:"厂";s:3:"â¼›";s:3:"厶";s:3:"⼜";s:3:"åˆ";s:3:"â¼";s:3:"å£";s:3:"⼞";s:3:"å›—";s:3:"⼟";s:3:"土";s:3:"â¼ ";s:3:"士";s:3:"⼡";s:3:"夂";s:3:"â¼¢";s:3:"夊";s:3:"â¼£";s:3:"夕";s:3:"⼤";s:3:"大";s:3:"â¼¥";s:3:"女";s:3:"⼦";s:3:"å­";s:3:"â¼§";s:3:"宀";s:3:"⼨";s:3:"寸";s:3:"⼩";s:3:"å°";s:3:"⼪";s:3:"å°¢";s:3:"⼫";s:3:"å°¸";s:3:"⼬";s:3:"å±®";s:3:"â¼­";s:3:"å±±";s:3:"â¼®";s:3:"å·›";s:3:"⼯";s:3:"å·¥";s:3:"â¼°";s:3:"å·±";s:3:"â¼±";s:3:"å·¾";s:3:"â¼²";s:3:"å¹²";s:3:"â¼³";s:3:"幺";s:3:"â¼´";s:3:"广";s:3:"â¼µ";s:3:"å»´";s:3:"â¼¶";s:3:"廾";s:3:"â¼·";s:3:"弋";s:3:"⼸";s:3:"弓";s:3:"â¼¹";s:3:"å½";s:3:"⼺";s:3:"彡";s:3:"â¼»";s:3:"å½³";s:3:"â¼¼";s:3:"心";s:3:"â¼½";s:3:"戈";s:3:"â¼¾";s:3:"戶";s:3:"⼿";s:3:"手";s:3:"â½€";s:3:"支";s:3:"â½";s:3:"æ”´";s:3:"⽂";s:3:"æ–‡";s:3:"⽃";s:3:"æ–—";s:3:"⽄";s:3:"æ–¤";s:3:"â½…";s:3:"æ–¹";s:3:"⽆";s:3:"æ— ";s:3:"⽇";s:3:"æ—¥";s:3:"⽈";s:3:"æ›°";s:3:"⽉";s:3:"月";s:3:"⽊";s:3:"木";s:3:"⽋";s:3:"欠";s:3:"⽌";s:3:"æ­¢";s:3:"â½";s:3:"æ­¹";s:3:"⽎";s:3:"殳";s:3:"â½";s:3:"毋";s:3:"â½";s:3:"比";s:3:"⽑";s:3:"毛";s:3:"â½’";s:3:"æ°";s:3:"⽓";s:3:"æ°”";s:3:"â½”";s:3:"æ°´";s:3:"⽕";s:3:"ç«";s:3:"â½–";s:3:"爪";s:3:"â½—";s:3:"父";s:3:"⽘";s:3:"爻";s:3:"â½™";s:3:"爿";s:3:"⽚";s:3:"片";s:3:"â½›";s:3:"牙";s:3:"⽜";s:3:"牛";s:3:"â½";s:3:"犬";s:3:"⽞";s:3:"玄";s:3:"⽟";s:3:"玉";s:3:"â½ ";s:3:"瓜";s:3:"⽡";s:3:"瓦";s:3:"â½¢";s:3:"甘";s:3:"â½£";s:3:"生";s:3:"⽤";s:3:"用";s:3:"â½¥";s:3:"ç”°";s:3:"⽦";s:3:"ç–‹";s:3:"â½§";s:3:"ç–’";s:3:"⽨";s:3:"ç™¶";s:3:"⽩";s:3:"白";s:3:"⽪";s:3:"çš®";s:3:"⽫";s:3:"çš¿";s:3:"⽬";s:3:"ç›®";s:3:"â½­";s:3:"矛";s:3:"â½®";s:3:"矢";s:3:"⽯";s:3:"石";s:3:"â½°";s:3:"示";s:3:"â½±";s:3:"禸";s:3:"â½²";s:3:"禾";s:3:"â½³";s:3:"ç©´";s:3:"â½´";s:3:"ç«‹";s:3:"â½µ";s:3:"竹";s:3:"â½¶";s:3:"ç±³";s:3:"â½·";s:3:"糸";s:3:"⽸";s:3:"ç¼¶";s:3:"â½¹";s:3:"网";s:3:"⽺";s:3:"羊";s:3:"â½»";s:3:"ç¾½";s:3:"â½¼";s:3:"è€";s:3:"â½½";s:3:"而";s:3:"â½¾";s:3:"耒";s:3:"⽿";s:3:"耳";s:3:"â¾€";s:3:"è¿";s:3:"â¾";s:3:"肉";s:3:"⾂";s:3:"臣";s:3:"⾃";s:3:"自";s:3:"⾄";s:3:"至";s:3:"â¾…";s:3:"臼";s:3:"⾆";s:3:"舌";s:3:"⾇";s:3:"舛";s:3:"⾈";s:3:"舟";s:3:"⾉";s:3:"艮";s:3:"⾊";s:3:"色";s:3:"⾋";s:3:"艸";s:3:"⾌";s:3:"è™";s:3:"â¾";s:3:"虫";s:3:"⾎";s:3:"è¡€";s:3:"â¾";s:3:"行";s:3:"â¾";s:3:"è¡£";s:3:"⾑";s:3:"襾";s:3:"â¾’";s:3:"見";s:3:"⾓";s:3:"è§’";s:3:"â¾”";s:3:"言";s:3:"⾕";s:3:"è°·";s:3:"â¾–";s:3:"豆";s:3:"â¾—";s:3:"豕";s:3:"⾘";s:3:"豸";s:3:"â¾™";s:3:"è²";s:3:"⾚";s:3:"赤";s:3:"â¾›";s:3:"èµ°";s:3:"⾜";s:3:"è¶³";s:3:"â¾";s:3:"身";s:3:"⾞";s:3:"車";s:3:"⾟";s:3:"è¾›";s:3:"â¾ ";s:3:"è¾°";s:3:"⾡";s:3:"è¾µ";s:3:"â¾¢";s:3:"é‚‘";s:3:"â¾£";s:3:"é…‰";s:3:"⾤";s:3:"釆";s:3:"â¾¥";s:3:"里";s:3:"⾦";s:3:"金";s:3:"â¾§";s:3:"é•·";s:3:"⾨";s:3:"é–€";s:3:"⾩";s:3:"阜";s:3:"⾪";s:3:"éš¶";s:3:"⾫";s:3:"éš¹";s:3:"⾬";s:3:"雨";s:3:"â¾­";s:3:"é‘";s:3:"â¾®";s:3:"éž";s:3:"⾯";s:3:"é¢";s:3:"â¾°";s:3:"é©";s:3:"â¾±";s:3:"韋";s:3:"â¾²";s:3:"韭";s:3:"â¾³";s:3:"音";s:3:"â¾´";s:3:"é ";s:3:"â¾µ";s:3:"風";s:3:"â¾¶";s:3:"飛";s:3:"â¾·";s:3:"食";s:3:"⾸";s:3:"首";s:3:"â¾¹";s:3:"香";s:3:"⾺";s:3:"馬";s:3:"â¾»";s:3:"骨";s:3:"â¾¼";s:3:"高";s:3:"â¾½";s:3:"髟";s:3:"â¾¾";s:3:"鬥";s:3:"⾿";s:3:"鬯";s:3:"â¿€";s:3:"鬲";s:3:"â¿";s:3:"鬼";s:3:"â¿‚";s:3:"é­š";s:3:"⿃";s:3:"é³¥";s:3:"â¿„";s:3:"é¹µ";s:3:"â¿…";s:3:"鹿";s:3:"⿆";s:3:"麥";s:3:"⿇";s:3:"麻";s:3:"⿈";s:3:"黃";s:3:"⿉";s:3:"é»";s:3:"⿊";s:3:"黑";s:3:"â¿‹";s:3:"黹";s:3:"⿌";s:3:"黽";s:3:"â¿";s:3:"鼎";s:3:"⿎";s:3:"鼓";s:3:"â¿";s:3:"é¼ ";s:3:"â¿";s:3:"é¼»";s:3:"â¿‘";s:3:"齊";s:3:"â¿’";s:3:"é½’";s:3:"â¿“";s:3:"é¾";s:3:"â¿”";s:3:"龜";s:3:"â¿•";s:3:"é¾ ";s:3:" ";s:1:" ";s:3:"〶";s:3:"〒";s:3:"〸";s:3:"å";s:3:"〹";s:3:"å„";s:3:"〺";s:3:"å…";s:3:"ㄱ";s:3:"á„€";s:3:"ㄲ";s:3:"á„";s:3:"ㄳ";s:3:"ᆪ";s:3:"ã„´";s:3:"á„‚";s:3:"ㄵ";s:3:"ᆬ";s:3:"ã„¶";s:3:"ᆭ";s:3:"ã„·";s:3:"ᄃ";s:3:"ㄸ";s:3:"á„„";s:3:"ㄹ";s:3:"á„…";s:3:"ㄺ";s:3:"ᆰ";s:3:"ã„»";s:3:"ᆱ";s:3:"ㄼ";s:3:"ᆲ";s:3:"ㄽ";s:3:"ᆳ";s:3:"ㄾ";s:3:"ᆴ";s:3:"ã„¿";s:3:"ᆵ";s:3:"ã…€";s:3:"ᄚ";s:3:"ã…";s:3:"ᄆ";s:3:"ã…‚";s:3:"ᄇ";s:3:"ã…ƒ";s:3:"ᄈ";s:3:"ã…„";s:3:"á„¡";s:3:"ã……";s:3:"ᄉ";s:3:"ã…†";s:3:"ᄊ";s:3:"ã…‡";s:3:"á„‹";s:3:"ã…ˆ";s:3:"ᄌ";s:3:"ã…‰";s:3:"á„";s:3:"ã…Š";s:3:"ᄎ";s:3:"ã…‹";s:3:"á„";s:3:"ã…Œ";s:3:"á„";s:3:"ã…";s:3:"á„‘";s:3:"ã…Ž";s:3:"á„’";s:3:"ã…";s:3:"á…¡";s:3:"ã…";s:3:"á…¢";s:3:"ã…‘";s:3:"á…£";s:3:"ã…’";s:3:"á…¤";s:3:"ã…“";s:3:"á…¥";s:3:"ã…”";s:3:"á…¦";s:3:"ã…•";s:3:"á…§";s:3:"ã…–";s:3:"á…¨";s:3:"ã…—";s:3:"á…©";s:3:"ã…˜";s:3:"á…ª";s:3:"ã…™";s:3:"á…«";s:3:"ã…š";s:3:"á…¬";s:3:"ã…›";s:3:"á…­";s:3:"ã…œ";s:3:"á…®";s:3:"ã…";s:3:"á…¯";s:3:"ã…ž";s:3:"á…°";s:3:"ã…Ÿ";s:3:"á…±";s:3:"ã… ";s:3:"á…²";s:3:"ã…¡";s:3:"á…³";s:3:"ã…¢";s:3:"á…´";s:3:"ã…£";s:3:"á…µ";s:3:"ã…¤";s:3:"á… ";s:3:"ã…¥";s:3:"á„”";s:3:"ã…¦";s:3:"á„•";s:3:"ã…§";s:3:"ᇇ";s:3:"ã…¨";s:3:"ᇈ";s:3:"ã…©";s:3:"ᇌ";s:3:"ã…ª";s:3:"ᇎ";s:3:"ã…«";s:3:"ᇓ";s:3:"ã…¬";s:3:"ᇗ";s:3:"ã…­";s:3:"ᇙ";s:3:"ã…®";s:3:"ᄜ";s:3:"ã…¯";s:3:"á‡";s:3:"ã…°";s:3:"ᇟ";s:3:"ã…±";s:3:"á„";s:3:"ã…²";s:3:"ᄞ";s:3:"ã…³";s:3:"á„ ";s:3:"ã…´";s:3:"á„¢";s:3:"ã…µ";s:3:"á„£";s:3:"ã…¶";s:3:"á„§";s:3:"ã…·";s:3:"á„©";s:3:"ã…¸";s:3:"á„«";s:3:"ã…¹";s:3:"ᄬ";s:3:"ã…º";s:3:"á„­";s:3:"ã…»";s:3:"á„®";s:3:"ã…¼";s:3:"ᄯ";s:3:"ã…½";s:3:"ᄲ";s:3:"ã…¾";s:3:"á„¶";s:3:"ã…¿";s:3:"á…€";s:3:"ㆀ";s:3:"á…‡";s:3:"ã†";s:3:"á…Œ";s:3:"ㆂ";s:3:"ᇱ";s:3:"ㆃ";s:3:"ᇲ";s:3:"ㆄ";s:3:"á…—";s:3:"ㆅ";s:3:"á…˜";s:3:"ㆆ";s:3:"á…™";s:3:"ㆇ";s:3:"ᆄ";s:3:"ㆈ";s:3:"ᆅ";s:3:"ㆉ";s:3:"ᆈ";s:3:"ㆊ";s:3:"ᆑ";s:3:"ㆋ";s:3:"ᆒ";s:3:"ㆌ";s:3:"ᆔ";s:3:"ã†";s:3:"ᆞ";s:3:"ㆎ";s:3:"ᆡ";s:3:"㈀";s:5:"(á„€)";s:3:"ãˆ";s:5:"(á„‚)";s:3:"㈂";s:5:"(ᄃ)";s:3:"㈃";s:5:"(á„…)";s:3:"㈄";s:5:"(ᄆ)";s:3:"㈅";s:5:"(ᄇ)";s:3:"㈆";s:5:"(ᄉ)";s:3:"㈇";s:5:"(á„‹)";s:3:"㈈";s:5:"(ᄌ)";s:3:"㈉";s:5:"(ᄎ)";s:3:"㈊";s:5:"(á„)";s:3:"㈋";s:5:"(á„)";s:3:"㈌";s:5:"(á„‘)";s:3:"ãˆ";s:5:"(á„’)";s:3:"㈎";s:8:"(가)";s:3:"ãˆ";s:8:"(á„‚á…¡)";s:3:"ãˆ";s:8:"(다)";s:3:"㈑";s:8:"(á„…á…¡)";s:3:"㈒";s:8:"(마)";s:3:"㈓";s:8:"(바)";s:3:"㈔";s:8:"(사)";s:3:"㈕";s:8:"(á„‹á…¡)";s:3:"㈖";s:8:"(자)";s:3:"㈗";s:8:"(차)";s:3:"㈘";s:8:"(á„á…¡)";s:3:"㈙";s:8:"(á„á…¡)";s:3:"㈚";s:8:"(á„‘á…¡)";s:3:"㈛";s:8:"(á„’á…¡)";s:3:"㈜";s:8:"(주)";s:3:"ãˆ";s:17:"(오전)";s:3:"㈞";s:14:"(á„‹á…©á„’á…®)";s:3:"㈠";s:5:"(一)";s:3:"㈡";s:5:"(二)";s:3:"㈢";s:5:"(三)";s:3:"㈣";s:5:"(å››)";s:3:"㈤";s:5:"(五)";s:3:"㈥";s:5:"(å…­)";s:3:"㈦";s:5:"(七)";s:3:"㈧";s:5:"(å…«)";s:3:"㈨";s:5:"(ä¹)";s:3:"㈩";s:5:"(å)";s:3:"㈪";s:5:"(月)";s:3:"㈫";s:5:"(ç«)";s:3:"㈬";s:5:"(æ°´)";s:3:"㈭";s:5:"(木)";s:3:"㈮";s:5:"(金)";s:3:"㈯";s:5:"(土)";s:3:"㈰";s:5:"(æ—¥)";s:3:"㈱";s:5:"(æ ª)";s:3:"㈲";s:5:"(有)";s:3:"㈳";s:5:"(社)";s:3:"㈴";s:5:"(å)";s:3:"㈵";s:5:"(特)";s:3:"㈶";s:5:"(財)";s:3:"㈷";s:5:"(ç¥)";s:3:"㈸";s:5:"(労)";s:3:"㈹";s:5:"(代)";s:3:"㈺";s:5:"(呼)";s:3:"㈻";s:5:"(å­¦)";s:3:"㈼";s:5:"(監)";s:3:"㈽";s:5:"(ä¼)";s:3:"㈾";s:5:"(資)";s:3:"㈿";s:5:"(å”)";s:3:"㉀";s:5:"(祭)";s:3:"ã‰";s:5:"(休)";s:3:"㉂";s:5:"(自)";s:3:"㉃";s:5:"(至)";s:3:"㉄";s:5:"(å•)";s:3:"㉅";s:5:"(å¹¼)";s:3:"㉆";s:5:"(æ–‡)";s:3:"㉇";s:5:"(ç®)";s:3:"ã‰";s:3:"PTE";s:3:"㉑";s:4:"(21)";s:3:"㉒";s:4:"(22)";s:3:"㉓";s:4:"(23)";s:3:"㉔";s:4:"(24)";s:3:"㉕";s:4:"(25)";s:3:"㉖";s:4:"(26)";s:3:"㉗";s:4:"(27)";s:3:"㉘";s:4:"(28)";s:3:"㉙";s:4:"(29)";s:3:"㉚";s:4:"(30)";s:3:"㉛";s:4:"(31)";s:3:"㉜";s:4:"(32)";s:3:"ã‰";s:4:"(33)";s:3:"㉞";s:4:"(34)";s:3:"㉟";s:4:"(35)";s:3:"㉠";s:5:"(á„€)";s:3:"㉡";s:5:"(á„‚)";s:3:"㉢";s:5:"(ᄃ)";s:3:"㉣";s:5:"(á„…)";s:3:"㉤";s:5:"(ᄆ)";s:3:"㉥";s:5:"(ᄇ)";s:3:"㉦";s:5:"(ᄉ)";s:3:"㉧";s:5:"(á„‹)";s:3:"㉨";s:5:"(ᄌ)";s:3:"㉩";s:5:"(ᄎ)";s:3:"㉪";s:5:"(á„)";s:3:"㉫";s:5:"(á„)";s:3:"㉬";s:5:"(á„‘)";s:3:"㉭";s:5:"(á„’)";s:3:"㉮";s:8:"(가)";s:3:"㉯";s:8:"(á„‚á…¡)";s:3:"㉰";s:8:"(다)";s:3:"㉱";s:8:"(á„…á…¡)";s:3:"㉲";s:8:"(마)";s:3:"㉳";s:8:"(바)";s:3:"㉴";s:8:"(사)";s:3:"㉵";s:8:"(á„‹á…¡)";s:3:"㉶";s:8:"(자)";s:3:"㉷";s:8:"(차)";s:3:"㉸";s:8:"(á„á…¡)";s:3:"㉹";s:8:"(á„á…¡)";s:3:"㉺";s:8:"(á„‘á…¡)";s:3:"㉻";s:8:"(á„’á…¡)";s:3:"㉼";s:17:"(참고)";s:3:"㉽";s:14:"(주의)";s:3:"㉾";s:8:"(á„‹á…®)";s:3:"㊀";s:5:"(一)";s:3:"ãŠ";s:5:"(二)";s:3:"㊂";s:5:"(三)";s:3:"㊃";s:5:"(å››)";s:3:"㊄";s:5:"(五)";s:3:"㊅";s:5:"(å…­)";s:3:"㊆";s:5:"(七)";s:3:"㊇";s:5:"(å…«)";s:3:"㊈";s:5:"(ä¹)";s:3:"㊉";s:5:"(å)";s:3:"㊊";s:5:"(月)";s:3:"㊋";s:5:"(ç«)";s:3:"㊌";s:5:"(æ°´)";s:3:"ãŠ";s:5:"(木)";s:3:"㊎";s:5:"(金)";s:3:"ãŠ";s:5:"(土)";s:3:"ãŠ";s:5:"(æ—¥)";s:3:"㊑";s:5:"(æ ª)";s:3:"㊒";s:5:"(有)";s:3:"㊓";s:5:"(社)";s:3:"㊔";s:5:"(å)";s:3:"㊕";s:5:"(特)";s:3:"㊖";s:5:"(財)";s:3:"㊗";s:5:"(ç¥)";s:3:"㊘";s:5:"(労)";s:3:"㊙";s:5:"(秘)";s:3:"㊚";s:5:"(ç”·)";s:3:"㊛";s:5:"(女)";s:3:"㊜";s:5:"(é©)";s:3:"ãŠ";s:5:"(優)";s:3:"㊞";s:5:"(å°)";s:3:"㊟";s:5:"(注)";s:3:"㊠";s:5:"(é …)";s:3:"㊡";s:5:"(休)";s:3:"㊢";s:5:"(写)";s:3:"㊣";s:5:"(æ­£)";s:3:"㊤";s:5:"(上)";s:3:"㊥";s:5:"(中)";s:3:"㊦";s:5:"(下)";s:3:"㊧";s:5:"(å·¦)";s:3:"㊨";s:5:"(å³)";s:3:"㊩";s:5:"(医)";s:3:"㊪";s:5:"(å®—)";s:3:"㊫";s:5:"(å­¦)";s:3:"㊬";s:5:"(監)";s:3:"㊭";s:5:"(ä¼)";s:3:"㊮";s:5:"(資)";s:3:"㊯";s:5:"(å”)";s:3:"㊰";s:5:"(夜)";s:3:"㊱";s:4:"(36)";s:3:"㊲";s:4:"(37)";s:3:"㊳";s:4:"(38)";s:3:"㊴";s:4:"(39)";s:3:"㊵";s:4:"(40)";s:3:"㊶";s:4:"(41)";s:3:"㊷";s:4:"(42)";s:3:"㊸";s:4:"(43)";s:3:"㊹";s:4:"(44)";s:3:"㊺";s:4:"(45)";s:3:"㊻";s:4:"(46)";s:3:"㊼";s:4:"(47)";s:3:"㊽";s:4:"(48)";s:3:"㊾";s:4:"(49)";s:3:"㊿";s:4:"(50)";s:3:"ã‹€";s:4:"1月";s:3:"ã‹";s:4:"2月";s:3:"ã‹‚";s:4:"3月";s:3:"㋃";s:4:"4月";s:3:"ã‹„";s:4:"5月";s:3:"ã‹…";s:4:"6月";s:3:"㋆";s:4:"7月";s:3:"㋇";s:4:"8月";s:3:"㋈";s:4:"9月";s:3:"㋉";s:5:"10月";s:3:"㋊";s:5:"11月";s:3:"ã‹‹";s:5:"12月";s:3:"㋌";s:2:"Hg";s:3:"ã‹";s:3:"erg";s:3:"㋎";s:2:"eV";s:3:"ã‹";s:3:"LTD";s:3:"ã‹";s:5:"(ã‚¢)";s:3:"ã‹‘";s:5:"(イ)";s:3:"ã‹’";s:5:"(ウ)";s:3:"ã‹“";s:5:"(エ)";s:3:"ã‹”";s:5:"(オ)";s:3:"ã‹•";s:5:"(ã‚«)";s:3:"ã‹–";s:5:"(ã‚­)";s:3:"ã‹—";s:5:"(ク)";s:3:"㋘";s:5:"(ケ)";s:3:"ã‹™";s:5:"(コ)";s:3:"㋚";s:5:"(サ)";s:3:"ã‹›";s:5:"(ã‚·)";s:3:"㋜";s:5:"(ス)";s:3:"ã‹";s:5:"(ã‚»)";s:3:"㋞";s:5:"(ソ)";s:3:"㋟";s:5:"(ã‚¿)";s:3:"ã‹ ";s:5:"(ãƒ)";s:3:"ã‹¡";s:5:"(ツ)";s:3:"ã‹¢";s:5:"(テ)";s:3:"ã‹£";s:5:"(ト)";s:3:"㋤";s:5:"(ナ)";s:3:"ã‹¥";s:5:"(ニ)";s:3:"㋦";s:5:"(ヌ)";s:3:"ã‹§";s:5:"(ãƒ)";s:3:"㋨";s:5:"(ノ)";s:3:"ã‹©";s:5:"(ãƒ)";s:3:"㋪";s:5:"(ヒ)";s:3:"ã‹«";s:5:"(フ)";s:3:"㋬";s:5:"(ヘ)";s:3:"ã‹­";s:5:"(ホ)";s:3:"ã‹®";s:5:"(マ)";s:3:"㋯";s:5:"(ミ)";s:3:"ã‹°";s:5:"(ム)";s:3:"㋱";s:5:"(メ)";s:3:"㋲";s:5:"(モ)";s:3:"㋳";s:5:"(ヤ)";s:3:"ã‹´";s:5:"(ユ)";s:3:"㋵";s:5:"(ヨ)";s:3:"ã‹¶";s:5:"(ラ)";s:3:"ã‹·";s:5:"(リ)";s:3:"㋸";s:5:"(ル)";s:3:"㋹";s:5:"(レ)";s:3:"㋺";s:5:"(ロ)";s:3:"ã‹»";s:5:"(ワ)";s:3:"㋼";s:5:"(ヰ)";s:3:"㋽";s:5:"(ヱ)";s:3:"㋾";s:5:"(ヲ)";s:3:"㌀";s:12:"アパート";s:3:"ãŒ";s:12:"アルファ";s:3:"㌂";s:12:"アンペア";s:3:"㌃";s:9:"アール";s:3:"㌄";s:12:"イニング";s:3:"㌅";s:9:"インãƒ";s:3:"㌆";s:9:"ウォン";s:3:"㌇";s:15:"エスクード";s:3:"㌈";s:12:"エーカー";s:3:"㌉";s:9:"オンス";s:3:"㌊";s:9:"オーム";s:3:"㌋";s:9:"カイリ";s:3:"㌌";s:12:"カラット";s:3:"ãŒ";s:12:"カロリー";s:3:"㌎";s:9:"ガロン";s:3:"ãŒ";s:9:"ガンマ";s:3:"ãŒ";s:6:"ギガ";s:3:"㌑";s:9:"ギニー";s:3:"㌒";s:12:"キュリー";s:3:"㌓";s:12:"ギルダー";s:3:"㌔";s:6:"キロ";s:3:"㌕";s:15:"キログラム";s:3:"㌖";s:18:"キロメートル";s:3:"㌗";s:15:"キロワット";s:3:"㌘";s:9:"グラム";s:3:"㌙";s:15:"グラムトン";s:3:"㌚";s:15:"クルゼイロ";s:3:"㌛";s:12:"クローãƒ";s:3:"㌜";s:9:"ケース";s:3:"ãŒ";s:9:"コルナ";s:3:"㌞";s:9:"コーãƒ";s:3:"㌟";s:12:"サイクル";s:3:"㌠";s:15:"サンãƒãƒ¼ãƒ ";s:3:"㌡";s:12:"シリング";s:3:"㌢";s:9:"センãƒ";s:3:"㌣";s:9:"セント";s:3:"㌤";s:9:"ダース";s:3:"㌥";s:6:"デシ";s:3:"㌦";s:6:"ドル";s:3:"㌧";s:6:"トン";s:3:"㌨";s:6:"ナノ";s:3:"㌩";s:9:"ノット";s:3:"㌪";s:9:"ãƒã‚¤ãƒ„";s:3:"㌫";s:15:"パーセント";s:3:"㌬";s:9:"パーツ";s:3:"㌭";s:12:"ãƒãƒ¼ãƒ¬ãƒ«";s:3:"㌮";s:15:"ピアストル";s:3:"㌯";s:9:"ピクル";s:3:"㌰";s:6:"ピコ";s:3:"㌱";s:6:"ビル";s:3:"㌲";s:15:"ファラッド";s:3:"㌳";s:12:"フィート";s:3:"㌴";s:15:"ブッシェル";s:3:"㌵";s:9:"フラン";s:3:"㌶";s:15:"ヘクタール";s:3:"㌷";s:6:"ペソ";s:3:"㌸";s:9:"ペニヒ";s:3:"㌹";s:9:"ヘルツ";s:3:"㌺";s:9:"ペンス";s:3:"㌻";s:9:"ページ";s:3:"㌼";s:9:"ベータ";s:3:"㌽";s:12:"ãƒã‚¤ãƒ³ãƒˆ";s:3:"㌾";s:9:"ボルト";s:3:"㌿";s:6:"ホン";s:3:"ã€";s:9:"ãƒãƒ³ãƒ‰";s:3:"ã";s:9:"ホール";s:3:"ã‚";s:9:"ホーン";s:3:"ãƒ";s:12:"マイクロ";s:3:"ã„";s:9:"マイル";s:3:"ã…";s:9:"マッãƒ";s:3:"ã†";s:9:"マルク";s:3:"ã‡";s:15:"マンション";s:3:"ãˆ";s:12:"ミクロン";s:3:"ã‰";s:6:"ミリ";s:3:"ãŠ";s:15:"ミリãƒãƒ¼ãƒ«";s:3:"ã‹";s:6:"メガ";s:3:"ãŒ";s:12:"メガトン";s:3:"ã";s:12:"メートル";s:3:"ãŽ";s:9:"ヤード";s:3:"ã";s:9:"ヤール";s:3:"ã";s:9:"ユアン";s:3:"ã‘";s:12:"リットル";s:3:"ã’";s:6:"リラ";s:3:"ã“";s:9:"ルピー";s:3:"ã”";s:12:"ルーブル";s:3:"ã•";s:6:"レム";s:3:"ã–";s:15:"レントゲン";s:3:"ã—";s:9:"ワット";s:3:"ã˜";s:4:"0点";s:3:"ã™";s:4:"1点";s:3:"ãš";s:4:"2点";s:3:"ã›";s:4:"3点";s:3:"ãœ";s:4:"4点";s:3:"ã";s:4:"5点";s:3:"ãž";s:4:"6点";s:3:"ãŸ";s:4:"7点";s:3:"ã ";s:4:"8点";s:3:"ã¡";s:4:"9点";s:3:"ã¢";s:5:"10点";s:3:"ã£";s:5:"11点";s:3:"ã¤";s:5:"12点";s:3:"ã¥";s:5:"13点";s:3:"ã¦";s:5:"14点";s:3:"ã§";s:5:"15点";s:3:"ã¨";s:5:"16点";s:3:"ã©";s:5:"17点";s:3:"ãª";s:5:"18点";s:3:"ã«";s:5:"19点";s:3:"ã¬";s:5:"20点";s:3:"ã­";s:5:"21点";s:3:"ã®";s:5:"22点";s:3:"ã¯";s:5:"23点";s:3:"ã°";s:5:"24点";s:3:"ã±";s:3:"hPa";s:3:"ã²";s:2:"da";s:3:"ã³";s:2:"AU";s:3:"ã´";s:3:"bar";s:3:"ãµ";s:2:"oV";s:3:"ã¶";s:2:"pc";s:3:"ã·";s:2:"dm";s:3:"ã¸";s:4:"dm²";s:3:"ã¹";s:4:"dm³";s:3:"ãº";s:2:"IU";s:3:"ã»";s:6:"å¹³æˆ";s:3:"ã¼";s:6:"昭和";s:3:"ã½";s:6:"大正";s:3:"ã¾";s:6:"明治";s:3:"ã¿";s:12:"æ ªå¼ä¼šç¤¾";s:3:"㎀";s:2:"pA";s:3:"ãŽ";s:2:"nA";s:3:"㎂";s:3:"μA";s:3:"㎃";s:2:"mA";s:3:"㎄";s:2:"kA";s:3:"㎅";s:2:"KB";s:3:"㎆";s:2:"MB";s:3:"㎇";s:2:"GB";s:3:"㎈";s:3:"cal";s:3:"㎉";s:4:"kcal";s:3:"㎊";s:2:"pF";s:3:"㎋";s:2:"nF";s:3:"㎌";s:3:"μF";s:3:"ãŽ";s:3:"μg";s:3:"㎎";s:2:"mg";s:3:"ãŽ";s:2:"kg";s:3:"ãŽ";s:2:"Hz";s:3:"㎑";s:3:"kHz";s:3:"㎒";s:3:"MHz";s:3:"㎓";s:3:"GHz";s:3:"㎔";s:3:"THz";s:3:"㎕";s:5:"μℓ";s:3:"㎖";s:4:"mâ„“";s:3:"㎗";s:4:"dâ„“";s:3:"㎘";s:4:"kâ„“";s:3:"㎙";s:2:"fm";s:3:"㎚";s:2:"nm";s:3:"㎛";s:3:"μm";s:3:"㎜";s:2:"mm";s:3:"ãŽ";s:2:"cm";s:3:"㎞";s:2:"km";s:3:"㎟";s:4:"mm²";s:3:"㎠";s:4:"cm²";s:3:"㎡";s:3:"m²";s:3:"㎢";s:4:"km²";s:3:"㎣";s:4:"mm³";s:3:"㎤";s:4:"cm³";s:3:"㎥";s:3:"m³";s:3:"㎦";s:4:"km³";s:3:"㎧";s:5:"m∕s";s:3:"㎨";s:7:"m∕s²";s:3:"㎩";s:2:"Pa";s:3:"㎪";s:3:"kPa";s:3:"㎫";s:3:"MPa";s:3:"㎬";s:3:"GPa";s:3:"㎭";s:3:"rad";s:3:"㎮";s:7:"rad∕s";s:3:"㎯";s:9:"rad∕s²";s:3:"㎰";s:2:"ps";s:3:"㎱";s:2:"ns";s:3:"㎲";s:3:"μs";s:3:"㎳";s:2:"ms";s:3:"㎴";s:2:"pV";s:3:"㎵";s:2:"nV";s:3:"㎶";s:3:"μV";s:3:"㎷";s:2:"mV";s:3:"㎸";s:2:"kV";s:3:"㎹";s:2:"MV";s:3:"㎺";s:2:"pW";s:3:"㎻";s:2:"nW";s:3:"㎼";s:3:"μW";s:3:"㎽";s:2:"mW";s:3:"㎾";s:2:"kW";s:3:"㎿";s:2:"MW";s:3:"ã€";s:3:"kΩ";s:3:"ã";s:3:"MΩ";s:3:"ã‚";s:4:"a.m.";s:3:"ãƒ";s:2:"Bq";s:3:"ã„";s:2:"cc";s:3:"ã…";s:2:"cd";s:3:"ã†";s:6:"C∕kg";s:3:"ã‡";s:3:"Co.";s:3:"ãˆ";s:2:"dB";s:3:"ã‰";s:2:"Gy";s:3:"ãŠ";s:2:"ha";s:3:"ã‹";s:2:"HP";s:3:"ãŒ";s:2:"in";s:3:"ã";s:2:"KK";s:3:"ãŽ";s:2:"KM";s:3:"ã";s:2:"kt";s:3:"ã";s:2:"lm";s:3:"ã‘";s:2:"ln";s:3:"ã’";s:3:"log";s:3:"ã“";s:2:"lx";s:3:"ã”";s:2:"mb";s:3:"ã•";s:3:"mil";s:3:"ã–";s:3:"mol";s:3:"ã—";s:2:"PH";s:3:"ã˜";s:4:"p.m.";s:3:"ã™";s:3:"PPM";s:3:"ãš";s:2:"PR";s:3:"ã›";s:2:"sr";s:3:"ãœ";s:2:"Sv";s:3:"ã";s:2:"Wb";s:3:"ãž";s:5:"V∕m";s:3:"ãŸ";s:5:"A∕m";s:3:"ã ";s:4:"1æ—¥";s:3:"ã¡";s:4:"2æ—¥";s:3:"ã¢";s:4:"3æ—¥";s:3:"ã£";s:4:"4æ—¥";s:3:"ã¤";s:4:"5æ—¥";s:3:"ã¥";s:4:"6æ—¥";s:3:"ã¦";s:4:"7æ—¥";s:3:"ã§";s:4:"8æ—¥";s:3:"ã¨";s:4:"9æ—¥";s:3:"ã©";s:5:"10æ—¥";s:3:"ãª";s:5:"11æ—¥";s:3:"ã«";s:5:"12æ—¥";s:3:"ã¬";s:5:"13æ—¥";s:3:"ã­";s:5:"14æ—¥";s:3:"ã®";s:5:"15æ—¥";s:3:"ã¯";s:5:"16æ—¥";s:3:"ã°";s:5:"17æ—¥";s:3:"ã±";s:5:"18æ—¥";s:3:"ã²";s:5:"19æ—¥";s:3:"ã³";s:5:"20æ—¥";s:3:"ã´";s:5:"21æ—¥";s:3:"ãµ";s:5:"22æ—¥";s:3:"ã¶";s:5:"23æ—¥";s:3:"ã·";s:5:"24æ—¥";s:3:"ã¸";s:5:"25æ—¥";s:3:"ã¹";s:5:"26æ—¥";s:3:"ãº";s:5:"27æ—¥";s:3:"ã»";s:5:"28æ—¥";s:3:"ã¼";s:5:"29æ—¥";s:3:"ã½";s:5:"30æ—¥";s:3:"ã¾";s:5:"31æ—¥";s:3:"ã¿";s:3:"gal";s:3:"豈";s:3:"豈";s:3:"ï¤";s:3:"æ›´";s:3:"車";s:3:"車";s:3:"賈";s:3:"賈";s:3:"滑";s:3:"滑";s:3:"串";s:3:"串";s:3:"句";s:3:"å¥";s:3:"龜";s:3:"龜";s:3:"龜";s:3:"龜";s:3:"契";s:3:"契";s:3:"金";s:3:"金";s:3:"喇";s:3:"å–‡";s:3:"奈";s:3:"奈";s:3:"ï¤";s:3:"懶";s:3:"癩";s:3:"癩";s:3:"ï¤";s:3:"ç¾…";s:3:"ï¤";s:3:"蘿";s:3:"螺";s:3:"螺";s:3:"裸";s:3:"裸";s:3:"邏";s:3:"é‚";s:3:"樂";s:3:"樂";s:3:"洛";s:3:"æ´›";s:3:"烙";s:3:"烙";s:3:"珞";s:3:"çž";s:3:"落";s:3:"è½";s:3:"酪";s:3:"é…ª";s:3:"駱";s:3:"é§±";s:3:"亂";s:3:"亂";s:3:"卵";s:3:"åµ";s:3:"ï¤";s:3:"欄";s:3:"爛";s:3:"爛";s:3:"蘭";s:3:"蘭";s:3:"鸞";s:3:"鸞";s:3:"嵐";s:3:"åµ";s:3:"濫";s:3:"æ¿«";s:3:"藍";s:3:"è—";s:3:"襤";s:3:"襤";s:3:"拉";s:3:"拉";s:3:"臘";s:3:"臘";s:3:"蠟";s:3:"è Ÿ";s:3:"廊";s:3:"廊";s:3:"朗";s:3:"朗";s:3:"浪";s:3:"浪";s:3:"狼";s:3:"狼";s:3:"郎";s:3:"郎";s:3:"來";s:3:"來";s:3:"冷";s:3:"冷";s:3:"勞";s:3:"勞";s:3:"擄";s:3:"æ“„";s:3:"櫓";s:3:"æ«“";s:3:"爐";s:3:"çˆ";s:3:"盧";s:3:"ç›§";s:3:"老";s:3:"è€";s:3:"蘆";s:3:"蘆";s:3:"虜";s:3:"虜";s:3:"路";s:3:"è·¯";s:3:"露";s:3:"露";s:3:"魯";s:3:"é­¯";s:3:"鷺";s:3:"é·º";s:3:"碌";s:3:"碌";s:3:"祿";s:3:"祿";s:3:"綠";s:3:"ç¶ ";s:3:"菉";s:3:"è‰";s:3:"錄";s:3:"錄";s:3:"鹿";s:3:"鹿";s:3:"ï¥";s:3:"è«–";s:3:"壟";s:3:"壟";s:3:"弄";s:3:"弄";s:3:"籠";s:3:"ç± ";s:3:"聾";s:3:"è¾";s:3:"牢";s:3:"牢";s:3:"磊";s:3:"磊";s:3:"賂";s:3:"賂";s:3:"雷";s:3:"é›·";s:3:"壘";s:3:"壘";s:3:"屢";s:3:"å±¢";s:3:"樓";s:3:"樓";s:3:"ï¥";s:3:"æ·š";s:3:"漏";s:3:"æ¼";s:3:"ï¥";s:3:"ç´¯";s:3:"ï¥";s:3:"縷";s:3:"陋";s:3:"陋";s:3:"勒";s:3:"å‹’";s:3:"肋";s:3:"è‚‹";s:3:"凜";s:3:"凜";s:3:"凌";s:3:"凌";s:3:"稜";s:3:"稜";s:3:"綾";s:3:"ç¶¾";s:3:"菱";s:3:"è±";s:3:"陵";s:3:"陵";s:3:"讀";s:3:"讀";s:3:"拏";s:3:"æ‹";s:3:"樂";s:3:"樂";s:3:"ï¥";s:3:"諾";s:3:"丹";s:3:"丹";s:3:"寧";s:3:"寧";s:3:"怒";s:3:"怒";s:3:"率";s:3:"率";s:3:"異";s:3:"ç•°";s:3:"北";s:3:"北";s:3:"磻";s:3:"磻";s:3:"便";s:3:"便";s:3:"復";s:3:"復";s:3:"不";s:3:"ä¸";s:3:"泌";s:3:"泌";s:3:"數";s:3:"數";s:3:"索";s:3:"ç´¢";s:3:"參";s:3:"åƒ";s:3:"塞";s:3:"塞";s:3:"省";s:3:"çœ";s:3:"葉";s:3:"葉";s:3:"說";s:3:"說";s:3:"殺";s:3:"殺";s:3:"辰";s:3:"è¾°";s:3:"沈";s:3:"沈";s:3:"拾";s:3:"拾";s:3:"若";s:3:"è‹¥";s:3:"掠";s:3:"掠";s:3:"略";s:3:"ç•¥";s:3:"亮";s:3:"亮";s:3:"兩";s:3:"å…©";s:3:"凉";s:3:"凉";s:3:"梁";s:3:"æ¢";s:3:"糧";s:3:"ç³§";s:3:"良";s:3:"良";s:3:"諒";s:3:"è«’";s:3:"量";s:3:"é‡";s:3:"勵";s:3:"勵";s:3:"呂";s:3:"å‘‚";s:3:"ï¦";s:3:"女";s:3:"廬";s:3:"廬";s:3:"旅";s:3:"æ—…";s:3:"濾";s:3:"濾";s:3:"礪";s:3:"礪";s:3:"閭";s:3:"é–­";s:3:"驪";s:3:"驪";s:3:"麗";s:3:"麗";s:3:"黎";s:3:"黎";s:3:"力";s:3:"力";s:3:"曆";s:3:"曆";s:3:"歷";s:3:"æ­·";s:3:"ï¦";s:3:"è½¢";s:3:"年";s:3:"å¹´";s:3:"ï¦";s:3:"æ†";s:3:"ï¦";s:3:"戀";s:3:"撚";s:3:"æ’š";s:3:"漣";s:3:"æ¼£";s:3:"煉";s:3:"ç…‰";s:3:"璉";s:3:"ç’‰";s:3:"秊";s:3:"ç§Š";s:3:"練";s:3:"ç·´";s:3:"聯";s:3:"è¯";s:3:"輦";s:3:"輦";s:3:"蓮";s:3:"è“®";s:3:"連";s:3:"連";s:3:"鍊";s:3:"éŠ";s:3:"列";s:3:"列";s:3:"ï¦";s:3:"劣";s:3:"咽";s:3:"å’½";s:3:"烈";s:3:"烈";s:3:"裂";s:3:"裂";s:3:"說";s:3:"說";s:3:"廉";s:3:"廉";s:3:"念";s:3:"念";s:3:"捻";s:3:"æ»";s:3:"殮";s:3:"æ®®";s:3:"簾";s:3:"ç°¾";s:3:"獵";s:3:"çµ";s:3:"令";s:3:"令";s:3:"囹";s:3:"囹";s:3:"寧";s:3:"寧";s:3:"嶺";s:3:"嶺";s:3:"怜";s:3:"怜";s:3:"玲";s:3:"玲";s:3:"瑩";s:3:"ç‘©";s:3:"羚";s:3:"羚";s:3:"聆";s:3:"è†";s:3:"鈴";s:3:"鈴";s:3:"零";s:3:"é›¶";s:3:"靈";s:3:"éˆ";s:3:"領";s:3:"é ˜";s:3:"例";s:3:"例";s:3:"禮";s:3:"禮";s:3:"醴";s:3:"醴";s:3:"隸";s:3:"隸";s:3:"惡";s:3:"惡";s:3:"了";s:3:"了";s:3:"僚";s:3:"僚";s:3:"寮";s:3:"寮";s:3:"尿";s:3:"å°¿";s:3:"料";s:3:"æ–™";s:3:"樂";s:3:"樂";s:3:"ï§€";s:3:"燎";s:3:"ï§";s:3:"療";s:3:"ï§‚";s:3:"蓼";s:3:"遼";s:3:"é¼";s:3:"ï§„";s:3:"é¾";s:3:"ï§…";s:3:"暈";s:3:"阮";s:3:"阮";s:3:"劉";s:3:"劉";s:3:"杻";s:3:"æ»";s:3:"柳";s:3:"柳";s:3:"ï§Š";s:3:"æµ";s:3:"ï§‹";s:3:"溜";s:3:"ï§Œ";s:3:"ç‰";s:3:"ï§";s:3:"ç•™";s:3:"ï§Ž";s:3:"ç¡«";s:3:"ï§";s:3:"ç´";s:3:"ï§";s:3:"類";s:3:"ï§‘";s:3:"å…­";s:3:"ï§’";s:3:"戮";s:3:"ï§“";s:3:"陸";s:3:"ï§”";s:3:"倫";s:3:"ï§•";s:3:"å´™";s:3:"ï§–";s:3:"æ·ª";s:3:"ï§—";s:3:"輪";s:3:"律";s:3:"律";s:3:"ï§™";s:3:"æ…„";s:3:"ï§š";s:3:"æ —";s:3:"ï§›";s:3:"率";s:3:"ï§œ";s:3:"隆";s:3:"ï§";s:3:"利";s:3:"ï§ž";s:3:"å";s:3:"ï§Ÿ";s:3:"å±¥";s:3:"ï§ ";s:3:"易";s:3:"ï§¡";s:3:"æŽ";s:3:"ï§¢";s:3:"梨";s:3:"ï§£";s:3:"æ³¥";s:3:"理";s:3:"ç†";s:3:"ï§¥";s:3:"ç—¢";s:3:"罹";s:3:"ç½¹";s:3:"ï§§";s:3:"è£";s:3:"裡";s:3:"裡";s:3:"ï§©";s:3:"里";s:3:"離";s:3:"離";s:3:"ï§«";s:3:"匿";s:3:"溺";s:3:"溺";s:3:"ï§­";s:3:"å";s:3:"ï§®";s:3:"ç‡";s:3:"璘";s:3:"ç’˜";s:3:"ï§°";s:3:"è—º";s:3:"ï§±";s:3:"隣";s:3:"ï§²";s:3:"é±—";s:3:"ï§³";s:3:"麟";s:3:"ï§´";s:3:"æž—";s:3:"ï§µ";s:3:"æ·‹";s:3:"ï§¶";s:3:"臨";s:3:"ï§·";s:3:"ç«‹";s:3:"笠";s:3:"笠";s:3:"ï§¹";s:3:"ç²’";s:3:"狀";s:3:"ç‹€";s:3:"ï§»";s:3:"ç‚™";s:3:"ï§¼";s:3:"è­˜";s:3:"ï§½";s:3:"什";s:3:"ï§¾";s:3:"茶";s:3:"ï§¿";s:3:"刺";s:3:"切";s:3:"切";s:3:"ï¨";s:3:"度";s:3:"拓";s:3:"æ‹“";s:3:"糖";s:3:"ç³–";s:3:"宅";s:3:"å®…";s:3:"洞";s:3:"æ´ž";s:3:"暴";s:3:"æš´";s:3:"輻";s:3:"è¼»";s:3:"行";s:3:"行";s:3:"降";s:3:"é™";s:3:"見";s:3:"見";s:3:"廓";s:3:"廓";s:3:"兀";s:3:"å…€";s:3:"ï¨";s:3:"å—€";s:3:"﨎";s:1:"";s:3:"ï¨";s:1:"";s:3:"ï¨";s:3:"塚";s:3:"﨑";s:1:"";s:3:"晴";s:3:"æ™´";s:3:"﨓";s:1:"";s:3:"﨔";s:1:"";s:3:"凞";s:3:"凞";s:3:"猪";s:3:"猪";s:3:"益";s:3:"益";s:3:"礼";s:3:"礼";s:3:"神";s:3:"神";s:3:"祥";s:3:"祥";s:3:"福";s:3:"ç¦";s:3:"靖";s:3:"é–";s:3:"ï¨";s:3:"ç²¾";s:3:"羽";s:3:"ç¾½";s:3:"﨟";s:1:"";s:3:"蘒";s:3:"蘒";s:3:"﨡";s:1:"";s:3:"諸";s:3:"諸";s:3:"﨣";s:1:"";s:3:"﨤";s:1:"";s:3:"逸";s:3:"逸";s:3:"都";s:3:"都";s:3:"﨧";s:1:"";s:3:"﨨";s:1:"";s:3:"﨩";s:1:"";s:3:"飯";s:3:"飯";s:3:"飼";s:3:"飼";s:3:"館";s:3:"館";s:3:"鶴";s:3:"é¶´";s:3:"郞";s:3:"郞";s:3:"隷";s:3:"éš·";s:3:"侮";s:3:"ä¾®";s:3:"僧";s:3:"僧";s:3:"免";s:3:"å…";s:3:"勉";s:3:"勉";s:3:"勤";s:3:"勤";s:3:"卑";s:3:"å‘";s:3:"喝";s:3:"å–";s:3:"嘆";s:3:"嘆";s:3:"器";s:3:"器";s:3:"塀";s:3:"å¡€";s:3:"墨";s:3:"墨";s:3:"層";s:3:"層";s:3:"屮";s:3:"å±®";s:3:"悔";s:3:"æ‚”";s:3:"慨";s:3:"æ…¨";s:3:"憎";s:3:"憎";s:3:"ï©€";s:3:"懲";s:3:"ï©";s:3:"æ•";s:3:"ï©‚";s:3:"æ—¢";s:3:"暑";s:3:"æš‘";s:3:"ï©„";s:3:"梅";s:3:"ï©…";s:3:"æµ·";s:3:"渚";s:3:"渚";s:3:"漢";s:3:"æ¼¢";s:3:"煮";s:3:"ç…®";s:3:"爫";s:3:"爫";s:3:"琢";s:3:"ç¢";s:3:"ï©‹";s:3:"碑";s:3:"社";s:3:"社";s:3:"ï©";s:3:"祉";s:3:"祈";s:3:"祈";s:3:"ï©";s:3:"ç¥";s:3:"ï©";s:3:"祖";s:3:"ï©‘";s:3:"ç¥";s:3:"ï©’";s:3:"ç¦";s:3:"ï©“";s:3:"禎";s:3:"ï©”";s:3:"ç©€";s:3:"ï©•";s:3:"çª";s:3:"ï©–";s:3:"節";s:3:"ï©—";s:3:"ç·´";s:3:"縉";s:3:"縉";s:3:"ï©™";s:3:"ç¹";s:3:"署";s:3:"ç½²";s:3:"ï©›";s:3:"者";s:3:"臭";s:3:"臭";s:3:"ï©";s:3:"艹";s:3:"艹";s:3:"艹";s:3:"著";s:3:"è‘—";s:3:"ï© ";s:3:"è¤";s:3:"ï©¡";s:3:"視";s:3:"ï©¢";s:3:"è¬";s:3:"ï©£";s:3:"謹";s:3:"賓";s:3:"賓";s:3:"ï©¥";s:3:"è´ˆ";s:3:"辶";s:3:"è¾¶";s:3:"ï©§";s:3:"逸";s:3:"難";s:3:"難";s:3:"ï©©";s:3:"響";s:3:"頻";s:3:"é »";s:3:"ï©«";s:3:"æµ";s:3:"𤋮";s:4:"𤋮";s:3:"ï©­";s:3:"舘";s:3:"ï©°";s:3:"並";s:3:"况";s:3:"况";s:3:"全";s:3:"å…¨";s:3:"侀";s:3:"ä¾€";s:3:"ï©´";s:3:"å……";s:3:"冀";s:3:"冀";s:3:"ï©¶";s:3:"勇";s:3:"ï©·";s:3:"勺";s:3:"喝";s:3:"å–";s:3:"啕";s:3:"å••";s:3:"喙";s:3:"å–™";s:3:"ï©»";s:3:"å—¢";s:3:"塚";s:3:"塚";s:3:"墳";s:3:"墳";s:3:"奄";s:3:"奄";s:3:"ï©¿";s:3:"奔";s:3:"婢";s:3:"å©¢";s:3:"ïª";s:3:"嬨";s:3:"廒";s:3:"å»’";s:3:"廙";s:3:"å»™";s:3:"彩";s:3:"彩";s:3:"徭";s:3:"å¾­";s:3:"惘";s:3:"惘";s:3:"慎";s:3:"æ…Ž";s:3:"愈";s:3:"愈";s:3:"憎";s:3:"憎";s:3:"慠";s:3:"æ… ";s:3:"懲";s:3:"懲";s:3:"戴";s:3:"戴";s:3:"ïª";s:3:"æ„";s:3:"搜";s:3:"æœ";s:3:"ïª";s:3:"æ‘’";s:3:"ïª";s:3:"æ•–";s:3:"晴";s:3:"æ™´";s:3:"朗";s:3:"朗";s:3:"望";s:3:"望";s:3:"杖";s:3:"æ–";s:3:"歹";s:3:"æ­¹";s:3:"殺";s:3:"殺";s:3:"流";s:3:"æµ";s:3:"滛";s:3:"æ»›";s:3:"滋";s:3:"滋";s:3:"漢";s:3:"æ¼¢";s:3:"瀞";s:3:"瀞";s:3:"煮";s:3:"ç…®";s:3:"ïª";s:3:"çž§";s:3:"爵";s:3:"爵";s:3:"犯";s:3:"犯";s:3:"猪";s:3:"猪";s:3:"瑱";s:3:"瑱";s:3:"甆";s:3:"甆";s:3:"画";s:3:"ç”»";s:3:"瘝";s:3:"ç˜";s:3:"瘟";s:3:"瘟";s:3:"益";s:3:"益";s:3:"盛";s:3:"ç››";s:3:"直";s:3:"ç›´";s:3:"睊";s:3:"çŠ";s:3:"着";s:3:"ç€";s:3:"磌";s:3:"磌";s:3:"窱";s:3:"窱";s:3:"節";s:3:"節";s:3:"类";s:3:"ç±»";s:3:"絛";s:3:"çµ›";s:3:"練";s:3:"ç·´";s:3:"缾";s:3:"ç¼¾";s:3:"者";s:3:"者";s:3:"荒";s:3:"è’";s:3:"華";s:3:"è¯";s:3:"蝹";s:3:"è¹";s:3:"襁";s:3:"è¥";s:3:"覆";s:3:"覆";s:3:"視";s:3:"視";s:3:"調";s:3:"調";s:3:"諸";s:3:"諸";s:3:"請";s:3:"è«‹";s:3:"謁";s:3:"è¬";s:3:"諾";s:3:"諾";s:3:"諭";s:3:"è«­";s:3:"謹";s:3:"謹";s:3:"ï«€";s:3:"變";s:3:"ï«";s:3:"è´ˆ";s:3:"ï«‚";s:3:"輸";s:3:"遲";s:3:"é²";s:3:"ï«„";s:3:"醙";s:3:"ï«…";s:3:"鉶";s:3:"陼";s:3:"陼";s:3:"難";s:3:"難";s:3:"靖";s:3:"é–";s:3:"韛";s:3:"韛";s:3:"響";s:3:"響";s:3:"ï«‹";s:3:"é ‹";s:3:"頻";s:3:"é »";s:3:"ï«";s:3:"鬒";s:3:"龜";s:3:"龜";s:3:"ï«";s:4:"𢡊";s:3:"ï«";s:4:"𢡄";s:3:"ï«‘";s:4:"ð£•";s:3:"ï«’";s:3:"ã®";s:3:"ï«“";s:3:"䀘";s:3:"ï«”";s:3:"䀹";s:3:"ï«•";s:4:"𥉉";s:3:"ï«–";s:4:"ð¥³";s:3:"ï«—";s:4:"𧻓";s:3:"齃";s:3:"齃";s:3:"ï«™";s:3:"龎";s:3:"ff";s:2:"ff";s:3:"ï¬";s:2:"fi";s:3:"fl";s:2:"fl";s:3:"ffi";s:3:"ffi";s:3:"ffl";s:3:"ffl";s:3:"ſt";s:3:"Å¿t";s:3:"st";s:2:"st";s:3:"ﬓ";s:4:"Õ´Õ¶";s:3:"ﬔ";s:4:"Õ´Õ¥";s:3:"ﬕ";s:4:"Õ´Õ«";s:3:"ﬖ";s:4:"Õ¾Õ¶";s:3:"ﬗ";s:4:"Õ´Õ­";s:3:"ﬠ";s:2:"×¢";s:3:"ﬡ";s:2:"×";s:3:"ﬢ";s:2:"ד";s:3:"ﬣ";s:2:"×”";s:3:"ﬤ";s:2:"×›";s:3:"ﬥ";s:2:"ל";s:3:"ﬦ";s:2:"×";s:3:"ﬧ";s:2:"ר";s:3:"ﬨ";s:2:"ת";s:3:"﬩";s:1:"+";s:3:"ï­";s:4:"×ל";s:3:"﹉";s:3:"‾";s:3:"﹊";s:3:"‾";s:3:"﹋";s:3:"‾";s:3:"﹌";s:3:"‾";s:3:"ï¹";s:1:"_";s:3:"﹎";s:1:"_";s:3:"ï¹";s:1:"_";s:3:"ï¹";s:1:",";s:3:"﹑";s:3:"ã€";s:3:"ï¹’";s:1:".";s:3:"ï¹”";s:1:";";s:3:"﹕";s:1:":";s:3:"ï¹–";s:1:"?";s:3:"ï¹—";s:1:"!";s:3:"﹘";s:3:"—";s:3:"ï¹™";s:1:"(";s:3:"﹚";s:1:")";s:3:"ï¹›";s:1:"{";s:3:"﹜";s:1:"}";s:3:"ï¹";s:3:"〔";s:3:"﹞";s:3:"〕";s:3:"﹟";s:1:"#";s:3:"ï¹ ";s:1:"&";s:3:"﹡";s:1:"*";s:3:"ï¹¢";s:1:"+";s:3:"ï¹£";s:1:"-";s:3:"﹤";s:1:"<";s:3:"ï¹¥";s:1:">";s:3:"﹦";s:1:"=";s:3:"﹨";s:1:"\";s:3:"﹩";s:1:"$";s:3:"﹪";s:1:"%";s:3:"﹫";s:1:"@";s:3:"ï¼";s:1:"!";s:3:""";s:1:""";s:3:"#";s:1:"#";s:3:"$";s:1:"$";s:3:"ï¼…";s:1:"%";s:3:"&";s:1:"&";s:3:"'";s:1:"'";s:3:"(";s:1:"(";s:3:")";s:1:")";s:3:"*";s:1:"*";s:3:"+";s:1:"+";s:3:",";s:1:",";s:3:"ï¼";s:1:"-";s:3:".";s:1:".";s:3:"ï¼";s:1:"/";s:3:"ï¼";s:1:"0";s:3:"1";s:1:"1";s:3:"ï¼’";s:1:"2";s:3:"3";s:1:"3";s:3:"ï¼”";s:1:"4";s:3:"5";s:1:"5";s:3:"ï¼–";s:1:"6";s:3:"ï¼—";s:1:"7";s:3:"8";s:1:"8";s:3:"ï¼™";s:1:"9";s:3:":";s:1:":";s:3:"ï¼›";s:1:";";s:3:"<";s:1:"<";s:3:"ï¼";s:1:"=";s:3:">";s:1:">";s:3:"?";s:1:"?";s:3:"ï¼ ";s:1:"@";s:3:"A";s:1:"A";s:3:"ï¼¢";s:1:"B";s:3:"ï¼£";s:1:"C";s:3:"D";s:1:"D";s:3:"ï¼¥";s:1:"E";s:3:"F";s:1:"F";s:3:"ï¼§";s:1:"G";s:3:"H";s:1:"H";s:3:"I";s:1:"I";s:3:"J";s:1:"J";s:3:"K";s:1:"K";s:3:"L";s:1:"L";s:3:"ï¼­";s:1:"M";s:3:"ï¼®";s:1:"N";s:3:"O";s:1:"O";s:3:"ï¼°";s:1:"P";s:3:"ï¼±";s:1:"Q";s:3:"ï¼²";s:1:"R";s:3:"ï¼³";s:1:"S";s:3:"ï¼´";s:1:"T";s:3:"ï¼µ";s:1:"U";s:3:"ï¼¶";s:1:"V";s:3:"ï¼·";s:1:"W";s:3:"X";s:1:"X";s:3:"ï¼¹";s:1:"Y";s:3:"Z";s:1:"Z";s:3:"ï¼»";s:1:"[";s:3:"ï¼¼";s:1:"\";s:3:"ï¼½";s:1:"]";s:3:"ï¼¾";s:1:"^";s:3:"_";s:1:"_";s:3:"ï½€";s:1:"`";s:3:"ï½";s:1:"a";s:3:"b";s:1:"b";s:3:"c";s:1:"c";s:3:"d";s:1:"d";s:3:"ï½…";s:1:"e";s:3:"f";s:1:"f";s:3:"g";s:1:"g";s:3:"h";s:1:"h";s:3:"i";s:1:"i";s:3:"j";s:1:"j";s:3:"k";s:1:"k";s:3:"l";s:1:"l";s:3:"ï½";s:1:"m";s:3:"n";s:1:"n";s:3:"ï½";s:1:"o";s:3:"ï½";s:1:"p";s:3:"q";s:1:"q";s:3:"ï½’";s:1:"r";s:3:"s";s:1:"s";s:3:"ï½”";s:1:"t";s:3:"u";s:1:"u";s:3:"ï½–";s:1:"v";s:3:"ï½—";s:1:"w";s:3:"x";s:1:"x";s:3:"ï½™";s:1:"y";s:3:"z";s:1:"z";s:3:"ï½›";s:1:"{";s:3:"|";s:1:"|";s:3:"ï½";s:1:"}";s:3:"~";s:1:"~";s:3:"⦅";s:3:"⦅";s:3:"ï½ ";s:3:"⦆";s:3:"。";s:3:"。";s:3:"ï½¢";s:3:"「";s:3:"ï½£";s:3:"ã€";s:3:"、";s:3:"ã€";s:3:"ï½¥";s:3:"・";s:3:"ヲ";s:3:"ヲ";s:3:"ï½§";s:3:"ã‚¡";s:3:"ィ";s:3:"ã‚£";s:3:"ゥ";s:3:"ã‚¥";s:3:"ェ";s:3:"ã‚§";s:3:"ォ";s:3:"ã‚©";s:3:"ャ";s:3:"ャ";s:3:"ï½­";s:3:"ュ";s:3:"ï½®";s:3:"ョ";s:3:"ッ";s:3:"ッ";s:3:"ï½°";s:3:"ー";s:3:"ï½±";s:3:"ã‚¢";s:3:"ï½²";s:3:"イ";s:3:"ï½³";s:3:"ウ";s:3:"ï½´";s:3:"エ";s:3:"ï½µ";s:3:"オ";s:3:"ï½¶";s:3:"ã‚«";s:3:"ï½·";s:3:"ã‚­";s:3:"ク";s:3:"ク";s:3:"ï½¹";s:3:"ケ";s:3:"コ";s:3:"コ";s:3:"ï½»";s:3:"サ";s:3:"ï½¼";s:3:"ã‚·";s:3:"ï½½";s:3:"ス";s:3:"ï½¾";s:3:"ã‚»";s:3:"ソ";s:3:"ソ";s:3:"ï¾€";s:3:"ã‚¿";s:3:"ï¾";s:3:"ãƒ";s:3:"ツ";s:3:"ツ";s:3:"テ";s:3:"テ";s:3:"ト";s:3:"ト";s:3:"ï¾…";s:3:"ナ";s:3:"ニ";s:3:"ニ";s:3:"ヌ";s:3:"ヌ";s:3:"ネ";s:3:"ãƒ";s:3:"ノ";s:3:"ノ";s:3:"ハ";s:3:"ãƒ";s:3:"ヒ";s:3:"ヒ";s:3:"フ";s:3:"フ";s:3:"ï¾";s:3:"ヘ";s:3:"ホ";s:3:"ホ";s:3:"ï¾";s:3:"マ";s:3:"ï¾";s:3:"ミ";s:3:"ム";s:3:"ム";s:3:"ï¾’";s:3:"メ";s:3:"モ";s:3:"モ";s:3:"ï¾”";s:3:"ヤ";s:3:"ユ";s:3:"ユ";s:3:"ï¾–";s:3:"ヨ";s:3:"ï¾—";s:3:"ラ";s:3:"リ";s:3:"リ";s:3:"ï¾™";s:3:"ル";s:3:"レ";s:3:"レ";s:3:"ï¾›";s:3:"ロ";s:3:"ワ";s:3:"ワ";s:3:"ï¾";s:3:"ン";s:3:"゙";s:3:"ã‚™";s:3:"゚";s:3:"゚";s:3:"ï¾ ";s:3:"ã…¤";s:3:"ᄀ";s:3:"ㄱ";s:3:"ï¾¢";s:3:"ㄲ";s:3:"ï¾£";s:3:"ㄳ";s:3:"ᄂ";s:3:"ã„´";s:3:"ï¾¥";s:3:"ㄵ";s:3:"ᆭ";s:3:"ã„¶";s:3:"ï¾§";s:3:"ã„·";s:3:"ᄄ";s:3:"ㄸ";s:3:"ᄅ";s:3:"ㄹ";s:3:"ᆰ";s:3:"ㄺ";s:3:"ᆱ";s:3:"ã„»";s:3:"ᆲ";s:3:"ㄼ";s:3:"ï¾­";s:3:"ㄽ";s:3:"ï¾®";s:3:"ㄾ";s:3:"ᆵ";s:3:"ã„¿";s:3:"ï¾°";s:3:"ã…€";s:3:"ï¾±";s:3:"ã…";s:3:"ï¾²";s:3:"ã…‚";s:3:"ï¾³";s:3:"ã…ƒ";s:3:"ï¾´";s:3:"ã…„";s:3:"ï¾µ";s:3:"ã……";s:3:"ï¾¶";s:3:"ã…†";s:3:"ï¾·";s:3:"ã…‡";s:3:"ᄌ";s:3:"ã…ˆ";s:3:"ï¾¹";s:3:"ã…‰";s:3:"ᄎ";s:3:"ã…Š";s:3:"ï¾»";s:3:"ã…‹";s:3:"ï¾¼";s:3:"ã…Œ";s:3:"ï¾½";s:3:"ã…";s:3:"ï¾¾";s:3:"ã…Ž";s:3:"ï¿‚";s:3:"ã…";s:3:"ᅢ";s:3:"ã…";s:3:"ï¿„";s:3:"ã…‘";s:3:"ï¿…";s:3:"ã…’";s:3:"ᅥ";s:3:"ã…“";s:3:"ᅦ";s:3:"ã…”";s:3:"ᅧ";s:3:"ã…•";s:3:"ï¿‹";s:3:"ã…–";s:3:"ᅩ";s:3:"ã…—";s:3:"ï¿";s:3:"ã…˜";s:3:"ᅫ";s:3:"ã…™";s:3:"ï¿";s:3:"ã…š";s:3:"ï¿’";s:3:"ã…›";s:3:"ï¿“";s:3:"ã…œ";s:3:"ï¿”";s:3:"ã…";s:3:"ï¿•";s:3:"ã…ž";s:3:"ï¿–";s:3:"ã…Ÿ";s:3:"ï¿—";s:3:"ã… ";s:3:"ᅳ";s:3:"ã…¡";s:3:"ï¿›";s:3:"ã…¢";s:3:"ᅵ";s:3:"ã…£";s:3:"ï¿ ";s:2:"¢";s:3:"ï¿¡";s:2:"£";s:3:"ï¿¢";s:2:"¬";s:3:"ï¿£";s:2:"¯";s:3:"¦";s:2:"¦";s:3:"ï¿¥";s:2:"Â¥";s:3:"₩";s:3:"â‚©";s:3:"│";s:3:"│";s:3:"ï¿©";s:3:"â†";s:3:"↑";s:3:"↑";s:3:"ï¿«";s:3:"→";s:3:"↓";s:3:"↓";s:3:"ï¿­";s:3:"â– ";s:3:"ï¿®";s:3:"â—‹";s:4:"ð€";s:1:"A";s:4:"ð";s:1:"B";s:4:"ð‚";s:1:"C";s:4:"ðƒ";s:1:"D";s:4:"ð„";s:1:"E";s:4:"ð…";s:1:"F";s:4:"ð†";s:1:"G";s:4:"ð‡";s:1:"H";s:4:"ðˆ";s:1:"I";s:4:"ð‰";s:1:"J";s:4:"ðŠ";s:1:"K";s:4:"ð‹";s:1:"L";s:4:"ðŒ";s:1:"M";s:4:"ð";s:1:"N";s:4:"ðŽ";s:1:"O";s:4:"ð";s:1:"P";s:4:"ð";s:1:"Q";s:4:"ð‘";s:1:"R";s:4:"ð’";s:1:"S";s:4:"ð“";s:1:"T";s:4:"ð”";s:1:"U";s:4:"ð•";s:1:"V";s:4:"ð–";s:1:"W";s:4:"ð—";s:1:"X";s:4:"ð˜";s:1:"Y";s:4:"ð™";s:1:"Z";s:4:"ðš";s:1:"a";s:4:"ð›";s:1:"b";s:4:"ðœ";s:1:"c";s:4:"ð";s:1:"d";s:4:"ðž";s:1:"e";s:4:"ðŸ";s:1:"f";s:4:"ð ";s:1:"g";s:4:"ð¡";s:1:"h";s:4:"ð¢";s:1:"i";s:4:"ð£";s:1:"j";s:4:"ð¤";s:1:"k";s:4:"ð¥";s:1:"l";s:4:"ð¦";s:1:"m";s:4:"ð§";s:1:"n";s:4:"ð¨";s:1:"o";s:4:"ð©";s:1:"p";s:4:"ðª";s:1:"q";s:4:"ð«";s:1:"r";s:4:"ð¬";s:1:"s";s:4:"ð­";s:1:"t";s:4:"ð®";s:1:"u";s:4:"ð¯";s:1:"v";s:4:"ð°";s:1:"w";s:4:"ð±";s:1:"x";s:4:"ð²";s:1:"y";s:4:"ð³";s:1:"z";s:4:"ð´";s:1:"A";s:4:"ðµ";s:1:"B";s:4:"ð¶";s:1:"C";s:4:"ð·";s:1:"D";s:4:"ð¸";s:1:"E";s:4:"ð¹";s:1:"F";s:4:"ðº";s:1:"G";s:4:"ð»";s:1:"H";s:4:"ð¼";s:1:"I";s:4:"ð½";s:1:"J";s:4:"ð¾";s:1:"K";s:4:"ð¿";s:1:"L";s:4:"ð‘€";s:1:"M";s:4:"ð‘";s:1:"N";s:4:"ð‘‚";s:1:"O";s:4:"ð‘ƒ";s:1:"P";s:4:"ð‘„";s:1:"Q";s:4:"ð‘…";s:1:"R";s:4:"ð‘†";s:1:"S";s:4:"ð‘‡";s:1:"T";s:4:"ð‘ˆ";s:1:"U";s:4:"ð‘‰";s:1:"V";s:4:"ð‘Š";s:1:"W";s:4:"ð‘‹";s:1:"X";s:4:"ð‘Œ";s:1:"Y";s:4:"ð‘";s:1:"Z";s:4:"ð‘Ž";s:1:"a";s:4:"ð‘";s:1:"b";s:4:"ð‘";s:1:"c";s:4:"ð‘‘";s:1:"d";s:4:"ð‘’";s:1:"e";s:4:"ð‘“";s:1:"f";s:4:"ð‘”";s:1:"g";s:4:"ð‘–";s:1:"i";s:4:"ð‘—";s:1:"j";s:4:"ð‘˜";s:1:"k";s:4:"ð‘™";s:1:"l";s:4:"ð‘š";s:1:"m";s:4:"ð‘›";s:1:"n";s:4:"ð‘œ";s:1:"o";s:4:"ð‘";s:1:"p";s:4:"ð‘ž";s:1:"q";s:4:"ð‘Ÿ";s:1:"r";s:4:"ð‘ ";s:1:"s";s:4:"ð‘¡";s:1:"t";s:4:"ð‘¢";s:1:"u";s:4:"ð‘£";s:1:"v";s:4:"ð‘¤";s:1:"w";s:4:"ð‘¥";s:1:"x";s:4:"ð‘¦";s:1:"y";s:4:"ð‘§";s:1:"z";s:4:"ð‘¨";s:1:"A";s:4:"ð‘©";s:1:"B";s:4:"ð‘ª";s:1:"C";s:4:"ð‘«";s:1:"D";s:4:"ð‘¬";s:1:"E";s:4:"ð‘­";s:1:"F";s:4:"ð‘®";s:1:"G";s:4:"ð‘¯";s:1:"H";s:4:"ð‘°";s:1:"I";s:4:"ð‘±";s:1:"J";s:4:"ð‘²";s:1:"K";s:4:"ð‘³";s:1:"L";s:4:"ð‘´";s:1:"M";s:4:"ð‘µ";s:1:"N";s:4:"ð‘¶";s:1:"O";s:4:"ð‘·";s:1:"P";s:4:"ð‘¸";s:1:"Q";s:4:"ð‘¹";s:1:"R";s:4:"ð‘º";s:1:"S";s:4:"ð‘»";s:1:"T";s:4:"ð‘¼";s:1:"U";s:4:"ð‘½";s:1:"V";s:4:"ð‘¾";s:1:"W";s:4:"ð‘¿";s:1:"X";s:4:"ð’€";s:1:"Y";s:4:"ð’";s:1:"Z";s:4:"ð’‚";s:1:"a";s:4:"ð’ƒ";s:1:"b";s:4:"ð’„";s:1:"c";s:4:"ð’…";s:1:"d";s:4:"ð’†";s:1:"e";s:4:"ð’‡";s:1:"f";s:4:"ð’ˆ";s:1:"g";s:4:"ð’‰";s:1:"h";s:4:"ð’Š";s:1:"i";s:4:"ð’‹";s:1:"j";s:4:"ð’Œ";s:1:"k";s:4:"ð’";s:1:"l";s:4:"ð’Ž";s:1:"m";s:4:"ð’";s:1:"n";s:4:"ð’";s:1:"o";s:4:"ð’‘";s:1:"p";s:4:"ð’’";s:1:"q";s:4:"ð’“";s:1:"r";s:4:"ð’”";s:1:"s";s:4:"ð’•";s:1:"t";s:4:"ð’–";s:1:"u";s:4:"ð’—";s:1:"v";s:4:"ð’˜";s:1:"w";s:4:"ð’™";s:1:"x";s:4:"ð’š";s:1:"y";s:4:"ð’›";s:1:"z";s:4:"ð’œ";s:1:"A";s:4:"ð’ž";s:1:"C";s:4:"ð’Ÿ";s:1:"D";s:4:"ð’¢";s:1:"G";s:4:"ð’¥";s:1:"J";s:4:"ð’¦";s:1:"K";s:4:"ð’©";s:1:"N";s:4:"ð’ª";s:1:"O";s:4:"ð’«";s:1:"P";s:4:"ð’¬";s:1:"Q";s:4:"ð’®";s:1:"S";s:4:"ð’¯";s:1:"T";s:4:"ð’°";s:1:"U";s:4:"ð’±";s:1:"V";s:4:"ð’²";s:1:"W";s:4:"ð’³";s:1:"X";s:4:"ð’´";s:1:"Y";s:4:"ð’µ";s:1:"Z";s:4:"ð’¶";s:1:"a";s:4:"ð’·";s:1:"b";s:4:"ð’¸";s:1:"c";s:4:"ð’¹";s:1:"d";s:4:"ð’»";s:1:"f";s:4:"ð’½";s:1:"h";s:4:"ð’¾";s:1:"i";s:4:"ð’¿";s:1:"j";s:4:"ð“€";s:1:"k";s:4:"ð“";s:1:"l";s:4:"ð“‚";s:1:"m";s:4:"ð“ƒ";s:1:"n";s:4:"ð“…";s:1:"p";s:4:"ð“†";s:1:"q";s:4:"ð“‡";s:1:"r";s:4:"ð“ˆ";s:1:"s";s:4:"ð“‰";s:1:"t";s:4:"ð“Š";s:1:"u";s:4:"ð“‹";s:1:"v";s:4:"ð“Œ";s:1:"w";s:4:"ð“";s:1:"x";s:4:"ð“Ž";s:1:"y";s:4:"ð“";s:1:"z";s:4:"ð“";s:1:"A";s:4:"ð“‘";s:1:"B";s:4:"ð“’";s:1:"C";s:4:"ð““";s:1:"D";s:4:"ð“”";s:1:"E";s:4:"ð“•";s:1:"F";s:4:"ð“–";s:1:"G";s:4:"ð“—";s:1:"H";s:4:"ð“˜";s:1:"I";s:4:"ð“™";s:1:"J";s:4:"ð“š";s:1:"K";s:4:"ð“›";s:1:"L";s:4:"ð“œ";s:1:"M";s:4:"ð“";s:1:"N";s:4:"ð“ž";s:1:"O";s:4:"ð“Ÿ";s:1:"P";s:4:"ð“ ";s:1:"Q";s:4:"ð“¡";s:1:"R";s:4:"ð“¢";s:1:"S";s:4:"ð“£";s:1:"T";s:4:"ð“¤";s:1:"U";s:4:"ð“¥";s:1:"V";s:4:"ð“¦";s:1:"W";s:4:"ð“§";s:1:"X";s:4:"ð“¨";s:1:"Y";s:4:"ð“©";s:1:"Z";s:4:"ð“ª";s:1:"a";s:4:"ð“«";s:1:"b";s:4:"ð“¬";s:1:"c";s:4:"ð“­";s:1:"d";s:4:"ð“®";s:1:"e";s:4:"ð“¯";s:1:"f";s:4:"ð“°";s:1:"g";s:4:"ð“±";s:1:"h";s:4:"ð“²";s:1:"i";s:4:"ð“³";s:1:"j";s:4:"ð“´";s:1:"k";s:4:"ð“µ";s:1:"l";s:4:"ð“¶";s:1:"m";s:4:"ð“·";s:1:"n";s:4:"ð“¸";s:1:"o";s:4:"ð“¹";s:1:"p";s:4:"ð“º";s:1:"q";s:4:"ð“»";s:1:"r";s:4:"ð“¼";s:1:"s";s:4:"ð“½";s:1:"t";s:4:"ð“¾";s:1:"u";s:4:"ð“¿";s:1:"v";s:4:"ð”€";s:1:"w";s:4:"ð”";s:1:"x";s:4:"ð”‚";s:1:"y";s:4:"ð”ƒ";s:1:"z";s:4:"ð”„";s:1:"A";s:4:"ð”…";s:1:"B";s:4:"ð”‡";s:1:"D";s:4:"ð”ˆ";s:1:"E";s:4:"ð”‰";s:1:"F";s:4:"ð”Š";s:1:"G";s:4:"ð”";s:1:"J";s:4:"ð”Ž";s:1:"K";s:4:"ð”";s:1:"L";s:4:"ð”";s:1:"M";s:4:"ð”‘";s:1:"N";s:4:"ð”’";s:1:"O";s:4:"ð”“";s:1:"P";s:4:"ð””";s:1:"Q";s:4:"ð”–";s:1:"S";s:4:"ð”—";s:1:"T";s:4:"ð”˜";s:1:"U";s:4:"ð”™";s:1:"V";s:4:"ð”š";s:1:"W";s:4:"ð”›";s:1:"X";s:4:"ð”œ";s:1:"Y";s:4:"ð”ž";s:1:"a";s:4:"ð”Ÿ";s:1:"b";s:4:"ð” ";s:1:"c";s:4:"ð”¡";s:1:"d";s:4:"ð”¢";s:1:"e";s:4:"ð”£";s:1:"f";s:4:"ð”¤";s:1:"g";s:4:"ð”¥";s:1:"h";s:4:"ð”¦";s:1:"i";s:4:"ð”§";s:1:"j";s:4:"ð”¨";s:1:"k";s:4:"ð”©";s:1:"l";s:4:"ð”ª";s:1:"m";s:4:"ð”«";s:1:"n";s:4:"ð”¬";s:1:"o";s:4:"ð”­";s:1:"p";s:4:"ð”®";s:1:"q";s:4:"ð”¯";s:1:"r";s:4:"ð”°";s:1:"s";s:4:"ð”±";s:1:"t";s:4:"ð”²";s:1:"u";s:4:"ð”³";s:1:"v";s:4:"ð”´";s:1:"w";s:4:"ð”µ";s:1:"x";s:4:"ð”¶";s:1:"y";s:4:"ð”·";s:1:"z";s:4:"ð”¸";s:1:"A";s:4:"ð”¹";s:1:"B";s:4:"ð”»";s:1:"D";s:4:"ð”¼";s:1:"E";s:4:"ð”½";s:1:"F";s:4:"ð”¾";s:1:"G";s:4:"ð•€";s:1:"I";s:4:"ð•";s:1:"J";s:4:"ð•‚";s:1:"K";s:4:"ð•ƒ";s:1:"L";s:4:"ð•„";s:1:"M";s:4:"ð•†";s:1:"O";s:4:"ð•Š";s:1:"S";s:4:"ð•‹";s:1:"T";s:4:"ð•Œ";s:1:"U";s:4:"ð•";s:1:"V";s:4:"ð•Ž";s:1:"W";s:4:"ð•";s:1:"X";s:4:"ð•";s:1:"Y";s:4:"ð•’";s:1:"a";s:4:"ð•“";s:1:"b";s:4:"ð•”";s:1:"c";s:4:"ð••";s:1:"d";s:4:"ð•–";s:1:"e";s:4:"ð•—";s:1:"f";s:4:"ð•˜";s:1:"g";s:4:"ð•™";s:1:"h";s:4:"ð•š";s:1:"i";s:4:"ð•›";s:1:"j";s:4:"ð•œ";s:1:"k";s:4:"ð•";s:1:"l";s:4:"ð•ž";s:1:"m";s:4:"ð•Ÿ";s:1:"n";s:4:"ð• ";s:1:"o";s:4:"ð•¡";s:1:"p";s:4:"ð•¢";s:1:"q";s:4:"ð•£";s:1:"r";s:4:"ð•¤";s:1:"s";s:4:"ð•¥";s:1:"t";s:4:"ð•¦";s:1:"u";s:4:"ð•§";s:1:"v";s:4:"ð•¨";s:1:"w";s:4:"ð•©";s:1:"x";s:4:"ð•ª";s:1:"y";s:4:"ð•«";s:1:"z";s:4:"ð•¬";s:1:"A";s:4:"ð•­";s:1:"B";s:4:"ð•®";s:1:"C";s:4:"ð•¯";s:1:"D";s:4:"ð•°";s:1:"E";s:4:"ð•±";s:1:"F";s:4:"ð•²";s:1:"G";s:4:"ð•³";s:1:"H";s:4:"ð•´";s:1:"I";s:4:"ð•µ";s:1:"J";s:4:"ð•¶";s:1:"K";s:4:"ð•·";s:1:"L";s:4:"ð•¸";s:1:"M";s:4:"ð•¹";s:1:"N";s:4:"ð•º";s:1:"O";s:4:"ð•»";s:1:"P";s:4:"ð•¼";s:1:"Q";s:4:"ð•½";s:1:"R";s:4:"ð•¾";s:1:"S";s:4:"ð•¿";s:1:"T";s:4:"ð–€";s:1:"U";s:4:"ð–";s:1:"V";s:4:"ð–‚";s:1:"W";s:4:"ð–ƒ";s:1:"X";s:4:"ð–„";s:1:"Y";s:4:"ð–…";s:1:"Z";s:4:"ð–†";s:1:"a";s:4:"ð–‡";s:1:"b";s:4:"ð–ˆ";s:1:"c";s:4:"ð–‰";s:1:"d";s:4:"ð–Š";s:1:"e";s:4:"ð–‹";s:1:"f";s:4:"ð–Œ";s:1:"g";s:4:"ð–";s:1:"h";s:4:"ð–Ž";s:1:"i";s:4:"ð–";s:1:"j";s:4:"ð–";s:1:"k";s:4:"ð–‘";s:1:"l";s:4:"ð–’";s:1:"m";s:4:"ð–“";s:1:"n";s:4:"ð–”";s:1:"o";s:4:"ð–•";s:1:"p";s:4:"ð––";s:1:"q";s:4:"ð–—";s:1:"r";s:4:"ð–˜";s:1:"s";s:4:"ð–™";s:1:"t";s:4:"ð–š";s:1:"u";s:4:"ð–›";s:1:"v";s:4:"ð–œ";s:1:"w";s:4:"ð–";s:1:"x";s:4:"ð–ž";s:1:"y";s:4:"ð–Ÿ";s:1:"z";s:4:"ð– ";s:1:"A";s:4:"ð–¡";s:1:"B";s:4:"ð–¢";s:1:"C";s:4:"ð–£";s:1:"D";s:4:"ð–¤";s:1:"E";s:4:"ð–¥";s:1:"F";s:4:"ð–¦";s:1:"G";s:4:"ð–§";s:1:"H";s:4:"ð–¨";s:1:"I";s:4:"ð–©";s:1:"J";s:4:"ð–ª";s:1:"K";s:4:"ð–«";s:1:"L";s:4:"ð–¬";s:1:"M";s:4:"ð–­";s:1:"N";s:4:"ð–®";s:1:"O";s:4:"ð–¯";s:1:"P";s:4:"ð–°";s:1:"Q";s:4:"ð–±";s:1:"R";s:4:"ð–²";s:1:"S";s:4:"ð–³";s:1:"T";s:4:"ð–´";s:1:"U";s:4:"ð–µ";s:1:"V";s:4:"ð–¶";s:1:"W";s:4:"ð–·";s:1:"X";s:4:"ð–¸";s:1:"Y";s:4:"ð–¹";s:1:"Z";s:4:"ð–º";s:1:"a";s:4:"ð–»";s:1:"b";s:4:"ð–¼";s:1:"c";s:4:"ð–½";s:1:"d";s:4:"ð–¾";s:1:"e";s:4:"ð–¿";s:1:"f";s:4:"ð—€";s:1:"g";s:4:"ð—";s:1:"h";s:4:"ð—‚";s:1:"i";s:4:"ð—ƒ";s:1:"j";s:4:"ð—„";s:1:"k";s:4:"ð—…";s:1:"l";s:4:"ð—†";s:1:"m";s:4:"ð—‡";s:1:"n";s:4:"ð—ˆ";s:1:"o";s:4:"ð—‰";s:1:"p";s:4:"ð—Š";s:1:"q";s:4:"ð—‹";s:1:"r";s:4:"ð—Œ";s:1:"s";s:4:"ð—";s:1:"t";s:4:"ð—Ž";s:1:"u";s:4:"ð—";s:1:"v";s:4:"ð—";s:1:"w";s:4:"ð—‘";s:1:"x";s:4:"ð—’";s:1:"y";s:4:"ð—“";s:1:"z";s:4:"ð—”";s:1:"A";s:4:"ð—•";s:1:"B";s:4:"ð—–";s:1:"C";s:4:"ð——";s:1:"D";s:4:"ð—˜";s:1:"E";s:4:"ð—™";s:1:"F";s:4:"ð—š";s:1:"G";s:4:"ð—›";s:1:"H";s:4:"ð—œ";s:1:"I";s:4:"ð—";s:1:"J";s:4:"ð—ž";s:1:"K";s:4:"ð—Ÿ";s:1:"L";s:4:"ð— ";s:1:"M";s:4:"ð—¡";s:1:"N";s:4:"ð—¢";s:1:"O";s:4:"ð—£";s:1:"P";s:4:"ð—¤";s:1:"Q";s:4:"ð—¥";s:1:"R";s:4:"ð—¦";s:1:"S";s:4:"ð—§";s:1:"T";s:4:"ð—¨";s:1:"U";s:4:"ð—©";s:1:"V";s:4:"ð—ª";s:1:"W";s:4:"ð—«";s:1:"X";s:4:"ð—¬";s:1:"Y";s:4:"ð—­";s:1:"Z";s:4:"ð—®";s:1:"a";s:4:"ð—¯";s:1:"b";s:4:"ð—°";s:1:"c";s:4:"ð—±";s:1:"d";s:4:"ð—²";s:1:"e";s:4:"ð—³";s:1:"f";s:4:"ð—´";s:1:"g";s:4:"ð—µ";s:1:"h";s:4:"ð—¶";s:1:"i";s:4:"ð—·";s:1:"j";s:4:"ð—¸";s:1:"k";s:4:"ð—¹";s:1:"l";s:4:"ð—º";s:1:"m";s:4:"ð—»";s:1:"n";s:4:"ð—¼";s:1:"o";s:4:"ð—½";s:1:"p";s:4:"ð—¾";s:1:"q";s:4:"ð—¿";s:1:"r";s:4:"ð˜€";s:1:"s";s:4:"ð˜";s:1:"t";s:4:"ð˜‚";s:1:"u";s:4:"ð˜ƒ";s:1:"v";s:4:"ð˜„";s:1:"w";s:4:"ð˜…";s:1:"x";s:4:"ð˜†";s:1:"y";s:4:"ð˜‡";s:1:"z";s:4:"ð˜ˆ";s:1:"A";s:4:"ð˜‰";s:1:"B";s:4:"ð˜Š";s:1:"C";s:4:"ð˜‹";s:1:"D";s:4:"ð˜Œ";s:1:"E";s:4:"ð˜";s:1:"F";s:4:"ð˜Ž";s:1:"G";s:4:"ð˜";s:1:"H";s:4:"ð˜";s:1:"I";s:4:"ð˜‘";s:1:"J";s:4:"ð˜’";s:1:"K";s:4:"ð˜“";s:1:"L";s:4:"ð˜”";s:1:"M";s:4:"ð˜•";s:1:"N";s:4:"ð˜–";s:1:"O";s:4:"ð˜—";s:1:"P";s:4:"ð˜˜";s:1:"Q";s:4:"ð˜™";s:1:"R";s:4:"ð˜š";s:1:"S";s:4:"ð˜›";s:1:"T";s:4:"ð˜œ";s:1:"U";s:4:"ð˜";s:1:"V";s:4:"ð˜ž";s:1:"W";s:4:"ð˜Ÿ";s:1:"X";s:4:"ð˜ ";s:1:"Y";s:4:"ð˜¡";s:1:"Z";s:4:"ð˜¢";s:1:"a";s:4:"ð˜£";s:1:"b";s:4:"ð˜¤";s:1:"c";s:4:"ð˜¥";s:1:"d";s:4:"ð˜¦";s:1:"e";s:4:"ð˜§";s:1:"f";s:4:"ð˜¨";s:1:"g";s:4:"ð˜©";s:1:"h";s:4:"ð˜ª";s:1:"i";s:4:"ð˜«";s:1:"j";s:4:"ð˜¬";s:1:"k";s:4:"ð˜­";s:1:"l";s:4:"ð˜®";s:1:"m";s:4:"ð˜¯";s:1:"n";s:4:"ð˜°";s:1:"o";s:4:"ð˜±";s:1:"p";s:4:"ð˜²";s:1:"q";s:4:"ð˜³";s:1:"r";s:4:"ð˜´";s:1:"s";s:4:"ð˜µ";s:1:"t";s:4:"ð˜¶";s:1:"u";s:4:"ð˜·";s:1:"v";s:4:"ð˜¸";s:1:"w";s:4:"ð˜¹";s:1:"x";s:4:"ð˜º";s:1:"y";s:4:"ð˜»";s:1:"z";s:4:"ð˜¼";s:1:"A";s:4:"ð˜½";s:1:"B";s:4:"ð˜¾";s:1:"C";s:4:"ð˜¿";s:1:"D";s:4:"ð™€";s:1:"E";s:4:"ð™";s:1:"F";s:4:"ð™‚";s:1:"G";s:4:"ð™ƒ";s:1:"H";s:4:"ð™„";s:1:"I";s:4:"ð™…";s:1:"J";s:4:"ð™†";s:1:"K";s:4:"ð™‡";s:1:"L";s:4:"ð™ˆ";s:1:"M";s:4:"ð™‰";s:1:"N";s:4:"ð™Š";s:1:"O";s:4:"ð™‹";s:1:"P";s:4:"ð™Œ";s:1:"Q";s:4:"ð™";s:1:"R";s:4:"ð™Ž";s:1:"S";s:4:"ð™";s:1:"T";s:4:"ð™";s:1:"U";s:4:"ð™‘";s:1:"V";s:4:"ð™’";s:1:"W";s:4:"ð™“";s:1:"X";s:4:"ð™”";s:1:"Y";s:4:"ð™•";s:1:"Z";s:4:"ð™–";s:1:"a";s:4:"ð™—";s:1:"b";s:4:"ð™˜";s:1:"c";s:4:"ð™™";s:1:"d";s:4:"ð™š";s:1:"e";s:4:"ð™›";s:1:"f";s:4:"ð™œ";s:1:"g";s:4:"ð™";s:1:"h";s:4:"ð™ž";s:1:"i";s:4:"ð™Ÿ";s:1:"j";s:4:"ð™ ";s:1:"k";s:4:"ð™¡";s:1:"l";s:4:"ð™¢";s:1:"m";s:4:"ð™£";s:1:"n";s:4:"ð™¤";s:1:"o";s:4:"ð™¥";s:1:"p";s:4:"ð™¦";s:1:"q";s:4:"ð™§";s:1:"r";s:4:"ð™¨";s:1:"s";s:4:"ð™©";s:1:"t";s:4:"ð™ª";s:1:"u";s:4:"ð™«";s:1:"v";s:4:"ð™¬";s:1:"w";s:4:"ð™­";s:1:"x";s:4:"ð™®";s:1:"y";s:4:"ð™¯";s:1:"z";s:4:"ð™°";s:1:"A";s:4:"ð™±";s:1:"B";s:4:"ð™²";s:1:"C";s:4:"ð™³";s:1:"D";s:4:"ð™´";s:1:"E";s:4:"ð™µ";s:1:"F";s:4:"ð™¶";s:1:"G";s:4:"ð™·";s:1:"H";s:4:"ð™¸";s:1:"I";s:4:"ð™¹";s:1:"J";s:4:"ð™º";s:1:"K";s:4:"ð™»";s:1:"L";s:4:"ð™¼";s:1:"M";s:4:"ð™½";s:1:"N";s:4:"ð™¾";s:1:"O";s:4:"ð™¿";s:1:"P";s:4:"ðš€";s:1:"Q";s:4:"ðš";s:1:"R";s:4:"ðš‚";s:1:"S";s:4:"ðšƒ";s:1:"T";s:4:"ðš„";s:1:"U";s:4:"ðš…";s:1:"V";s:4:"ðš†";s:1:"W";s:4:"ðš‡";s:1:"X";s:4:"ðšˆ";s:1:"Y";s:4:"ðš‰";s:1:"Z";s:4:"ðšŠ";s:1:"a";s:4:"ðš‹";s:1:"b";s:4:"ðšŒ";s:1:"c";s:4:"ðš";s:1:"d";s:4:"ðšŽ";s:1:"e";s:4:"ðš";s:1:"f";s:4:"ðš";s:1:"g";s:4:"ðš‘";s:1:"h";s:4:"ðš’";s:1:"i";s:4:"ðš“";s:1:"j";s:4:"ðš”";s:1:"k";s:4:"ðš•";s:1:"l";s:4:"ðš–";s:1:"m";s:4:"ðš—";s:1:"n";s:4:"ðš˜";s:1:"o";s:4:"ðš™";s:1:"p";s:4:"ðšš";s:1:"q";s:4:"ðš›";s:1:"r";s:4:"ðšœ";s:1:"s";s:4:"ðš";s:1:"t";s:4:"ðšž";s:1:"u";s:4:"ðšŸ";s:1:"v";s:4:"ðš ";s:1:"w";s:4:"ðš¡";s:1:"x";s:4:"ðš¢";s:1:"y";s:4:"ðš£";s:1:"z";s:4:"ðš¤";s:2:"ı";s:4:"ðš¥";s:2:"È·";s:4:"ðš¨";s:2:"Α";s:4:"ðš©";s:2:"Î’";s:4:"ðšª";s:2:"Γ";s:4:"ðš«";s:2:"Δ";s:4:"ðš¬";s:2:"Ε";s:4:"ðš­";s:2:"Ζ";s:4:"ðš®";s:2:"Η";s:4:"ðš¯";s:2:"Θ";s:4:"ðš°";s:2:"Ι";s:4:"ðš±";s:2:"Κ";s:4:"ðš²";s:2:"Λ";s:4:"ðš³";s:2:"Μ";s:4:"ðš´";s:2:"Î";s:4:"ðšµ";s:2:"Ξ";s:4:"ðš¶";s:2:"Ο";s:4:"ðš·";s:2:"Π";s:4:"ðš¸";s:2:"Ρ";s:4:"ðš¹";s:2:"Ï´";s:4:"ðšº";s:2:"Σ";s:4:"ðš»";s:2:"Τ";s:4:"ðš¼";s:2:"Î¥";s:4:"ðš½";s:2:"Φ";s:4:"ðš¾";s:2:"Χ";s:4:"ðš¿";s:2:"Ψ";s:4:"ð›€";s:2:"Ω";s:4:"ð›";s:3:"∇";s:4:"ð›‚";s:2:"α";s:4:"ð›ƒ";s:2:"β";s:4:"ð›„";s:2:"γ";s:4:"ð›…";s:2:"δ";s:4:"ð›†";s:2:"ε";s:4:"ð›‡";s:2:"ζ";s:4:"ð›ˆ";s:2:"η";s:4:"ð›‰";s:2:"θ";s:4:"ð›Š";s:2:"ι";s:4:"ð›‹";s:2:"κ";s:4:"ð›Œ";s:2:"λ";s:4:"ð›";s:2:"μ";s:4:"ð›Ž";s:2:"ν";s:4:"ð›";s:2:"ξ";s:4:"ð›";s:2:"ο";s:4:"ð›‘";s:2:"Ï€";s:4:"ð›’";s:2:"Ï";s:4:"ð›“";s:2:"Ï‚";s:4:"ð›”";s:2:"σ";s:4:"ð›•";s:2:"Ï„";s:4:"ð›–";s:2:"Ï…";s:4:"ð›—";s:2:"φ";s:4:"ð›˜";s:2:"χ";s:4:"ð›™";s:2:"ψ";s:4:"ð›š";s:2:"ω";s:4:"ð››";s:3:"∂";s:4:"ð›œ";s:2:"ϵ";s:4:"ð›";s:2:"Ï‘";s:4:"ð›ž";s:2:"ϰ";s:4:"ð›Ÿ";s:2:"Ï•";s:4:"ð› ";s:2:"ϱ";s:4:"ð›¡";s:2:"Ï–";s:4:"ð›¢";s:2:"Α";s:4:"ð›£";s:2:"Î’";s:4:"ð›¤";s:2:"Γ";s:4:"ð›¥";s:2:"Δ";s:4:"ð›¦";s:2:"Ε";s:4:"ð›§";s:2:"Ζ";s:4:"ð›¨";s:2:"Η";s:4:"ð›©";s:2:"Θ";s:4:"ð›ª";s:2:"Ι";s:4:"ð›«";s:2:"Κ";s:4:"ð›¬";s:2:"Λ";s:4:"ð›­";s:2:"Μ";s:4:"ð›®";s:2:"Î";s:4:"ð›¯";s:2:"Ξ";s:4:"ð›°";s:2:"Ο";s:4:"ð›±";s:2:"Π";s:4:"ð›²";s:2:"Ρ";s:4:"ð›³";s:2:"Ï´";s:4:"ð›´";s:2:"Σ";s:4:"ð›µ";s:2:"Τ";s:4:"ð›¶";s:2:"Î¥";s:4:"ð›·";s:2:"Φ";s:4:"ð›¸";s:2:"Χ";s:4:"ð›¹";s:2:"Ψ";s:4:"ð›º";s:2:"Ω";s:4:"ð›»";s:3:"∇";s:4:"ð›¼";s:2:"α";s:4:"ð›½";s:2:"β";s:4:"ð›¾";s:2:"γ";s:4:"ð›¿";s:2:"δ";s:4:"ðœ€";s:2:"ε";s:4:"ðœ";s:2:"ζ";s:4:"ðœ‚";s:2:"η";s:4:"ðœƒ";s:2:"θ";s:4:"ðœ„";s:2:"ι";s:4:"ðœ…";s:2:"κ";s:4:"ðœ†";s:2:"λ";s:4:"ðœ‡";s:2:"μ";s:4:"ðœˆ";s:2:"ν";s:4:"ðœ‰";s:2:"ξ";s:4:"ðœŠ";s:2:"ο";s:4:"ðœ‹";s:2:"Ï€";s:4:"ðœŒ";s:2:"Ï";s:4:"ðœ";s:2:"Ï‚";s:4:"ðœŽ";s:2:"σ";s:4:"ðœ";s:2:"Ï„";s:4:"ðœ";s:2:"Ï…";s:4:"ðœ‘";s:2:"φ";s:4:"ðœ’";s:2:"χ";s:4:"ðœ“";s:2:"ψ";s:4:"ðœ”";s:2:"ω";s:4:"ðœ•";s:3:"∂";s:4:"ðœ–";s:2:"ϵ";s:4:"ðœ—";s:2:"Ï‘";s:4:"ðœ˜";s:2:"ϰ";s:4:"ðœ™";s:2:"Ï•";s:4:"ðœš";s:2:"ϱ";s:4:"ðœ›";s:2:"Ï–";s:4:"ðœœ";s:2:"Α";s:4:"ðœ";s:2:"Î’";s:4:"ðœž";s:2:"Γ";s:4:"ðœŸ";s:2:"Δ";s:4:"ðœ ";s:2:"Ε";s:4:"ðœ¡";s:2:"Ζ";s:4:"ðœ¢";s:2:"Η";s:4:"ðœ£";s:2:"Θ";s:4:"ðœ¤";s:2:"Ι";s:4:"ðœ¥";s:2:"Κ";s:4:"ðœ¦";s:2:"Λ";s:4:"ðœ§";s:2:"Μ";s:4:"ðœ¨";s:2:"Î";s:4:"ðœ©";s:2:"Ξ";s:4:"ðœª";s:2:"Ο";s:4:"ðœ«";s:2:"Π";s:4:"ðœ¬";s:2:"Ρ";s:4:"ðœ­";s:2:"Ï´";s:4:"ðœ®";s:2:"Σ";s:4:"ðœ¯";s:2:"Τ";s:4:"ðœ°";s:2:"Î¥";s:4:"ðœ±";s:2:"Φ";s:4:"ðœ²";s:2:"Χ";s:4:"ðœ³";s:2:"Ψ";s:4:"ðœ´";s:2:"Ω";s:4:"ðœµ";s:3:"∇";s:4:"ðœ¶";s:2:"α";s:4:"ðœ·";s:2:"β";s:4:"ðœ¸";s:2:"γ";s:4:"ðœ¹";s:2:"δ";s:4:"ðœº";s:2:"ε";s:4:"ðœ»";s:2:"ζ";s:4:"ðœ¼";s:2:"η";s:4:"ðœ½";s:2:"θ";s:4:"ðœ¾";s:2:"ι";s:4:"ðœ¿";s:2:"κ";s:4:"ð€";s:2:"λ";s:4:"ð";s:2:"μ";s:4:"ð‚";s:2:"ν";s:4:"ðƒ";s:2:"ξ";s:4:"ð„";s:2:"ο";s:4:"ð…";s:2:"Ï€";s:4:"ð†";s:2:"Ï";s:4:"ð‡";s:2:"Ï‚";s:4:"ðˆ";s:2:"σ";s:4:"ð‰";s:2:"Ï„";s:4:"ðŠ";s:2:"Ï…";s:4:"ð‹";s:2:"φ";s:4:"ðŒ";s:2:"χ";s:4:"ð";s:2:"ψ";s:4:"ðŽ";s:2:"ω";s:4:"ð";s:3:"∂";s:4:"ð";s:2:"ϵ";s:4:"ð‘";s:2:"Ï‘";s:4:"ð’";s:2:"ϰ";s:4:"ð“";s:2:"Ï•";s:4:"ð”";s:2:"ϱ";s:4:"ð•";s:2:"Ï–";s:4:"ð–";s:2:"Α";s:4:"ð—";s:2:"Î’";s:4:"ð˜";s:2:"Γ";s:4:"ð™";s:2:"Δ";s:4:"ðš";s:2:"Ε";s:4:"ð›";s:2:"Ζ";s:4:"ðœ";s:2:"Η";s:4:"ð";s:2:"Θ";s:4:"ðž";s:2:"Ι";s:4:"ðŸ";s:2:"Κ";s:4:"ð ";s:2:"Λ";s:4:"ð¡";s:2:"Μ";s:4:"ð¢";s:2:"Î";s:4:"ð£";s:2:"Ξ";s:4:"ð¤";s:2:"Ο";s:4:"ð¥";s:2:"Π";s:4:"ð¦";s:2:"Ρ";s:4:"ð§";s:2:"Ï´";s:4:"ð¨";s:2:"Σ";s:4:"ð©";s:2:"Τ";s:4:"ðª";s:2:"Î¥";s:4:"ð«";s:2:"Φ";s:4:"ð¬";s:2:"Χ";s:4:"ð­";s:2:"Ψ";s:4:"ð®";s:2:"Ω";s:4:"ð¯";s:3:"∇";s:4:"ð°";s:2:"α";s:4:"ð±";s:2:"β";s:4:"ð²";s:2:"γ";s:4:"ð³";s:2:"δ";s:4:"ð´";s:2:"ε";s:4:"ðµ";s:2:"ζ";s:4:"ð¶";s:2:"η";s:4:"ð·";s:2:"θ";s:4:"ð¸";s:2:"ι";s:4:"ð¹";s:2:"κ";s:4:"ðº";s:2:"λ";s:4:"ð»";s:2:"μ";s:4:"ð¼";s:2:"ν";s:4:"ð½";s:2:"ξ";s:4:"ð¾";s:2:"ο";s:4:"ð¿";s:2:"Ï€";s:4:"ðž€";s:2:"Ï";s:4:"ðž";s:2:"Ï‚";s:4:"ðž‚";s:2:"σ";s:4:"ðžƒ";s:2:"Ï„";s:4:"ðž„";s:2:"Ï…";s:4:"ðž…";s:2:"φ";s:4:"ðž†";s:2:"χ";s:4:"ðž‡";s:2:"ψ";s:4:"ðžˆ";s:2:"ω";s:4:"ðž‰";s:3:"∂";s:4:"ðžŠ";s:2:"ϵ";s:4:"ðž‹";s:2:"Ï‘";s:4:"ðžŒ";s:2:"ϰ";s:4:"ðž";s:2:"Ï•";s:4:"ðžŽ";s:2:"ϱ";s:4:"ðž";s:2:"Ï–";s:4:"ðž";s:2:"Α";s:4:"ðž‘";s:2:"Î’";s:4:"ðž’";s:2:"Γ";s:4:"ðž“";s:2:"Δ";s:4:"ðž”";s:2:"Ε";s:4:"ðž•";s:2:"Ζ";s:4:"ðž–";s:2:"Η";s:4:"ðž—";s:2:"Θ";s:4:"ðž˜";s:2:"Ι";s:4:"ðž™";s:2:"Κ";s:4:"ðžš";s:2:"Λ";s:4:"ðž›";s:2:"Μ";s:4:"ðžœ";s:2:"Î";s:4:"ðž";s:2:"Ξ";s:4:"ðžž";s:2:"Ο";s:4:"ðžŸ";s:2:"Π";s:4:"ðž ";s:2:"Ρ";s:4:"ðž¡";s:2:"Ï´";s:4:"ðž¢";s:2:"Σ";s:4:"ðž£";s:2:"Τ";s:4:"ðž¤";s:2:"Î¥";s:4:"ðž¥";s:2:"Φ";s:4:"ðž¦";s:2:"Χ";s:4:"ðž§";s:2:"Ψ";s:4:"ðž¨";s:2:"Ω";s:4:"ðž©";s:3:"∇";s:4:"ðžª";s:2:"α";s:4:"ðž«";s:2:"β";s:4:"ðž¬";s:2:"γ";s:4:"ðž­";s:2:"δ";s:4:"ðž®";s:2:"ε";s:4:"ðž¯";s:2:"ζ";s:4:"ðž°";s:2:"η";s:4:"ðž±";s:2:"θ";s:4:"ðž²";s:2:"ι";s:4:"ðž³";s:2:"κ";s:4:"ðž´";s:2:"λ";s:4:"ðžµ";s:2:"μ";s:4:"ðž¶";s:2:"ν";s:4:"ðž·";s:2:"ξ";s:4:"ðž¸";s:2:"ο";s:4:"ðž¹";s:2:"Ï€";s:4:"ðžº";s:2:"Ï";s:4:"ðž»";s:2:"Ï‚";s:4:"ðž¼";s:2:"σ";s:4:"ðž½";s:2:"Ï„";s:4:"ðž¾";s:2:"Ï…";s:4:"ðž¿";s:2:"φ";s:4:"ðŸ€";s:2:"χ";s:4:"ðŸ";s:2:"ψ";s:4:"ðŸ‚";s:2:"ω";s:4:"ðŸƒ";s:3:"∂";s:4:"ðŸ„";s:2:"ϵ";s:4:"ðŸ…";s:2:"Ï‘";s:4:"ðŸ†";s:2:"ϰ";s:4:"ðŸ‡";s:2:"Ï•";s:4:"ðŸˆ";s:2:"ϱ";s:4:"ðŸ‰";s:2:"Ï–";s:4:"ðŸŠ";s:2:"Ïœ";s:4:"ðŸ‹";s:2:"Ï";s:4:"ðŸŽ";s:1:"0";s:4:"ðŸ";s:1:"1";s:4:"ðŸ";s:1:"2";s:4:"ðŸ‘";s:1:"3";s:4:"ðŸ’";s:1:"4";s:4:"ðŸ“";s:1:"5";s:4:"ðŸ”";s:1:"6";s:4:"ðŸ•";s:1:"7";s:4:"ðŸ–";s:1:"8";s:4:"ðŸ—";s:1:"9";s:4:"ðŸ˜";s:1:"0";s:4:"ðŸ™";s:1:"1";s:4:"ðŸš";s:1:"2";s:4:"ðŸ›";s:1:"3";s:4:"ðŸœ";s:1:"4";s:4:"ðŸ";s:1:"5";s:4:"ðŸž";s:1:"6";s:4:"ðŸŸ";s:1:"7";s:4:"ðŸ ";s:1:"8";s:4:"ðŸ¡";s:1:"9";s:4:"ðŸ¢";s:1:"0";s:4:"ðŸ£";s:1:"1";s:4:"ðŸ¤";s:1:"2";s:4:"ðŸ¥";s:1:"3";s:4:"ðŸ¦";s:1:"4";s:4:"ðŸ§";s:1:"5";s:4:"ðŸ¨";s:1:"6";s:4:"ðŸ©";s:1:"7";s:4:"ðŸª";s:1:"8";s:4:"ðŸ«";s:1:"9";s:4:"ðŸ¬";s:1:"0";s:4:"ðŸ­";s:1:"1";s:4:"ðŸ®";s:1:"2";s:4:"ðŸ¯";s:1:"3";s:4:"ðŸ°";s:1:"4";s:4:"ðŸ±";s:1:"5";s:4:"ðŸ²";s:1:"6";s:4:"ðŸ³";s:1:"7";s:4:"ðŸ´";s:1:"8";s:4:"ðŸµ";s:1:"9";s:4:"ðŸ¶";s:1:"0";s:4:"ðŸ·";s:1:"1";s:4:"ðŸ¸";s:1:"2";s:4:"ðŸ¹";s:1:"3";s:4:"ðŸº";s:1:"4";s:4:"ðŸ»";s:1:"5";s:4:"ðŸ¼";s:1:"6";s:4:"ðŸ½";s:1:"7";s:4:"ðŸ¾";s:1:"8";s:4:"ðŸ¿";s:1:"9";s:4:"𞸀";s:2:"ا";s:4:"ðž¸";s:2:"ب";s:4:"𞸂";s:2:"ج";s:4:"𞸃";s:2:"د";s:4:"𞸅";s:2:"Ùˆ";s:4:"𞸆";s:2:"ز";s:4:"𞸇";s:2:"Ø­";s:4:"𞸈";s:2:"Ø·";s:4:"𞸉";s:2:"ÙŠ";s:4:"𞸊";s:2:"Ùƒ";s:4:"𞸋";s:2:"Ù„";s:4:"𞸌";s:2:"Ù…";s:4:"ðž¸";s:2:"Ù†";s:4:"𞸎";s:2:"س";s:4:"ðž¸";s:2:"ع";s:4:"ðž¸";s:2:"Ù";s:4:"𞸑";s:2:"ص";s:4:"𞸒";s:2:"Ù‚";s:4:"𞸓";s:2:"ر";s:4:"𞸔";s:2:"Ø´";s:4:"𞸕";s:2:"ت";s:4:"𞸖";s:2:"Ø«";s:4:"𞸗";s:2:"Ø®";s:4:"𞸘";s:2:"ذ";s:4:"𞸙";s:2:"ض";s:4:"𞸚";s:2:"ظ";s:4:"𞸛";s:2:"غ";s:4:"𞸜";s:2:"Ù®";s:4:"ðž¸";s:2:"Úº";s:4:"𞸞";s:2:"Ú¡";s:4:"𞸟";s:2:"Ù¯";s:4:"𞸡";s:2:"ب";s:4:"𞸢";s:2:"ج";s:4:"𞸤";s:2:"Ù‡";s:4:"𞸧";s:2:"Ø­";s:4:"𞸩";s:2:"ÙŠ";s:4:"𞸪";s:2:"Ùƒ";s:4:"𞸫";s:2:"Ù„";s:4:"𞸬";s:2:"Ù…";s:4:"𞸭";s:2:"Ù†";s:4:"𞸮";s:2:"س";s:4:"𞸯";s:2:"ع";s:4:"𞸰";s:2:"Ù";s:4:"𞸱";s:2:"ص";s:4:"𞸲";s:2:"Ù‚";s:4:"𞸴";s:2:"Ø´";s:4:"𞸵";s:2:"ت";s:4:"𞸶";s:2:"Ø«";s:4:"𞸷";s:2:"Ø®";s:4:"𞸹";s:2:"ض";s:4:"𞸻";s:2:"غ";s:4:"𞹂";s:2:"ج";s:4:"𞹇";s:2:"Ø­";s:4:"𞹉";s:2:"ÙŠ";s:4:"𞹋";s:2:"Ù„";s:4:"ðž¹";s:2:"Ù†";s:4:"𞹎";s:2:"س";s:4:"ðž¹";s:2:"ع";s:4:"𞹑";s:2:"ص";s:4:"ðž¹’";s:2:"Ù‚";s:4:"ðž¹”";s:2:"Ø´";s:4:"ðž¹—";s:2:"Ø®";s:4:"ðž¹™";s:2:"ض";s:4:"ðž¹›";s:2:"غ";s:4:"ðž¹";s:2:"Úº";s:4:"𞹟";s:2:"Ù¯";s:4:"𞹡";s:2:"ب";s:4:"ðž¹¢";s:2:"ج";s:4:"𞹤";s:2:"Ù‡";s:4:"ðž¹§";s:2:"Ø­";s:4:"𞹨";s:2:"Ø·";s:4:"𞹩";s:2:"ÙŠ";s:4:"𞹪";s:2:"Ùƒ";s:4:"𞹬";s:2:"Ù…";s:4:"ðž¹­";s:2:"Ù†";s:4:"ðž¹®";s:2:"س";s:4:"𞹯";s:2:"ع";s:4:"ðž¹°";s:2:"Ù";s:4:"ðž¹±";s:2:"ص";s:4:"ðž¹²";s:2:"Ù‚";s:4:"ðž¹´";s:2:"Ø´";s:4:"ðž¹µ";s:2:"ت";s:4:"ðž¹¶";s:2:"Ø«";s:4:"ðž¹·";s:2:"Ø®";s:4:"ðž¹¹";s:2:"ض";s:4:"𞹺";s:2:"ظ";s:4:"ðž¹»";s:2:"غ";s:4:"ðž¹¼";s:2:"Ù®";s:4:"ðž¹¾";s:2:"Ú¡";s:4:"𞺀";s:2:"ا";s:4:"ðžº";s:2:"ب";s:4:"𞺂";s:2:"ج";s:4:"𞺃";s:2:"د";s:4:"𞺄";s:2:"Ù‡";s:4:"𞺅";s:2:"Ùˆ";s:4:"𞺆";s:2:"ز";s:4:"𞺇";s:2:"Ø­";s:4:"𞺈";s:2:"Ø·";s:4:"𞺉";s:2:"ÙŠ";s:4:"𞺋";s:2:"Ù„";s:4:"𞺌";s:2:"Ù…";s:4:"ðžº";s:2:"Ù†";s:4:"𞺎";s:2:"س";s:4:"ðžº";s:2:"ع";s:4:"ðžº";s:2:"Ù";s:4:"𞺑";s:2:"ص";s:4:"𞺒";s:2:"Ù‚";s:4:"𞺓";s:2:"ر";s:4:"𞺔";s:2:"Ø´";s:4:"𞺕";s:2:"ت";s:4:"𞺖";s:2:"Ø«";s:4:"𞺗";s:2:"Ø®";s:4:"𞺘";s:2:"ذ";s:4:"𞺙";s:2:"ض";s:4:"𞺚";s:2:"ظ";s:4:"𞺛";s:2:"غ";s:4:"𞺡";s:2:"ب";s:4:"𞺢";s:2:"ج";s:4:"𞺣";s:2:"د";s:4:"𞺥";s:2:"Ùˆ";s:4:"𞺦";s:2:"ز";s:4:"𞺧";s:2:"Ø­";s:4:"𞺨";s:2:"Ø·";s:4:"𞺩";s:2:"ÙŠ";s:4:"𞺫";s:2:"Ù„";s:4:"𞺬";s:2:"Ù…";s:4:"𞺭";s:2:"Ù†";s:4:"𞺮";s:2:"س";s:4:"𞺯";s:2:"ع";s:4:"𞺰";s:2:"Ù";s:4:"𞺱";s:2:"ص";s:4:"𞺲";s:2:"Ù‚";s:4:"𞺳";s:2:"ر";s:4:"𞺴";s:2:"Ø´";s:4:"𞺵";s:2:"ت";s:4:"𞺶";s:2:"Ø«";s:4:"𞺷";s:2:"Ø®";s:4:"𞺸";s:2:"ذ";s:4:"𞺹";s:2:"ض";s:4:"𞺺";s:2:"ظ";s:4:"𞺻";s:2:"غ";s:4:"🄀";s:2:"0.";s:4:"ðŸ„";s:2:"0,";s:4:"🄂";s:2:"1,";s:4:"🄃";s:2:"2,";s:4:"🄄";s:2:"3,";s:4:"🄅";s:2:"4,";s:4:"🄆";s:2:"5,";s:4:"🄇";s:2:"6,";s:4:"🄈";s:2:"7,";s:4:"🄉";s:2:"8,";s:4:"🄊";s:2:"9,";s:4:"ðŸ„";s:3:"(A)";s:4:"🄑";s:3:"(B)";s:4:"🄒";s:3:"(C)";s:4:"🄓";s:3:"(D)";s:4:"🄔";s:3:"(E)";s:4:"🄕";s:3:"(F)";s:4:"🄖";s:3:"(G)";s:4:"🄗";s:3:"(H)";s:4:"🄘";s:3:"(I)";s:4:"🄙";s:3:"(J)";s:4:"🄚";s:3:"(K)";s:4:"🄛";s:3:"(L)";s:4:"🄜";s:3:"(M)";s:4:"ðŸ„";s:3:"(N)";s:4:"🄞";s:3:"(O)";s:4:"🄟";s:3:"(P)";s:4:"🄠";s:3:"(Q)";s:4:"🄡";s:3:"(R)";s:4:"🄢";s:3:"(S)";s:4:"🄣";s:3:"(T)";s:4:"🄤";s:3:"(U)";s:4:"🄥";s:3:"(V)";s:4:"🄦";s:3:"(W)";s:4:"🄧";s:3:"(X)";s:4:"🄨";s:3:"(Y)";s:4:"🄩";s:3:"(Z)";s:4:"🄪";s:7:"〔S〕";s:4:"🄫";s:3:"(C)";s:4:"🄬";s:3:"(R)";s:4:"🄭";s:4:"(CD)";s:4:"🄮";s:4:"(WZ)";s:4:"🄰";s:1:"A";s:4:"🄱";s:1:"B";s:4:"🄲";s:1:"C";s:4:"🄳";s:1:"D";s:4:"🄴";s:1:"E";s:4:"🄵";s:1:"F";s:4:"🄶";s:1:"G";s:4:"🄷";s:1:"H";s:4:"🄸";s:1:"I";s:4:"🄹";s:1:"J";s:4:"🄺";s:1:"K";s:4:"🄻";s:1:"L";s:4:"🄼";s:1:"M";s:4:"🄽";s:1:"N";s:4:"🄾";s:1:"O";s:4:"🄿";s:1:"P";s:4:"🅀";s:1:"Q";s:4:"ðŸ…";s:1:"R";s:4:"🅂";s:1:"S";s:4:"🅃";s:1:"T";s:4:"🅄";s:1:"U";s:4:"🅅";s:1:"V";s:4:"🅆";s:1:"W";s:4:"🅇";s:1:"X";s:4:"🅈";s:1:"Y";s:4:"🅉";s:1:"Z";s:4:"🅊";s:2:"HV";s:4:"🅋";s:2:"MV";s:4:"🅌";s:2:"SD";s:4:"ðŸ…";s:2:"SS";s:4:"🅎";s:3:"PPV";s:4:"ðŸ…";s:2:"WC";s:4:"ðŸ†";s:2:"DJ";s:4:"🈀";s:6:"ã»ã‹";s:4:"ðŸˆ";s:6:"ココ";s:4:"🈂";s:3:"サ";s:4:"ðŸˆ";s:3:"手";s:4:"🈑";s:3:"å­—";s:4:"🈒";s:3:"åŒ";s:4:"🈓";s:3:"デ";s:4:"🈔";s:3:"二";s:4:"🈕";s:3:"多";s:4:"🈖";s:3:"è§£";s:4:"🈗";s:3:"天";s:4:"🈘";s:3:"交";s:4:"🈙";s:3:"映";s:4:"🈚";s:3:"ç„¡";s:4:"🈛";s:3:"æ–™";s:4:"🈜";s:3:"å‰";s:4:"ðŸˆ";s:3:"後";s:4:"🈞";s:3:"å†";s:4:"🈟";s:3:"æ–°";s:4:"🈠";s:3:"åˆ";s:4:"🈡";s:3:"終";s:4:"🈢";s:3:"生";s:4:"🈣";s:3:"販";s:4:"🈤";s:3:"声";s:4:"🈥";s:3:"å¹";s:4:"🈦";s:3:"æ¼”";s:4:"🈧";s:3:"投";s:4:"🈨";s:3:"æ•";s:4:"🈩";s:3:"一";s:4:"🈪";s:3:"三";s:4:"🈫";s:3:"éŠ";s:4:"🈬";s:3:"å·¦";s:4:"🈭";s:3:"中";s:4:"🈮";s:3:"å³";s:4:"🈯";s:3:"指";s:4:"🈰";s:3:"èµ°";s:4:"🈱";s:3:"打";s:4:"🈲";s:3:"ç¦";s:4:"🈳";s:3:"空";s:4:"🈴";s:3:"åˆ";s:4:"🈵";s:3:"満";s:4:"🈶";s:3:"有";s:4:"🈷";s:3:"月";s:4:"🈸";s:3:"申";s:4:"🈹";s:3:"割";s:4:"🈺";s:3:"å–¶";s:4:"🉀";s:9:"〔本〕";s:4:"ðŸ‰";s:9:"〔三〕";s:4:"🉂";s:9:"〔二〕";s:4:"🉃";s:9:"〔安〕";s:4:"🉄";s:9:"〔点〕";s:4:"🉅";s:9:"〔打〕";s:4:"🉆";s:9:"〔盗〕";s:4:"🉇";s:9:"〔å‹ã€•";s:4:"🉈";s:9:"〔敗〕";s:4:"ðŸ‰";s:5:"(å¾—)";s:4:"🉑";s:5:"(å¯)";s:4:"丽";s:3:"丽";s:4:"ð¯ ";s:3:"丸";s:4:"乁";s:3:"ä¹";s:4:"𠄢";s:4:"ð „¢";s:4:"你";s:3:"ä½ ";s:4:"侮";s:3:"ä¾®";s:4:"侻";s:3:"ä¾»";s:4:"倂";s:3:"倂";s:4:"偺";s:3:"åº";s:4:"備";s:3:"å‚™";s:4:"僧";s:3:"僧";s:4:"像";s:3:"åƒ";s:4:"㒞";s:3:"ã’ž";s:4:"ð¯ ";s:4:"𠘺";s:4:"免";s:3:"å…";s:4:"ð¯ ";s:3:"å…”";s:4:"ð¯ ";s:3:"å…¤";s:4:"具";s:3:"å…·";s:4:"𠔜";s:4:"𠔜";s:4:"㒹";s:3:"ã’¹";s:4:"內";s:3:"å…§";s:4:"再";s:3:"å†";s:4:"𠕋";s:4:"ð •‹";s:4:"冗";s:3:"冗";s:4:"冤";s:3:"冤";s:4:"仌";s:3:"仌";s:4:"冬";s:3:"冬";s:4:"况";s:3:"况";s:4:"𩇟";s:4:"𩇟";s:4:"ð¯ ";s:3:"凵";s:4:"刃";s:3:"刃";s:4:"㓟";s:3:"㓟";s:4:"刻";s:3:"刻";s:4:"剆";s:3:"剆";s:4:"割";s:3:"割";s:4:"剷";s:3:"剷";s:4:"㔕";s:3:"㔕";s:4:"勇";s:3:"勇";s:4:"勉";s:3:"勉";s:4:"勤";s:3:"勤";s:4:"勺";s:3:"勺";s:4:"包";s:3:"包";s:4:"匆";s:3:"匆";s:4:"北";s:3:"北";s:4:"卉";s:3:"å‰";s:4:"卑";s:3:"å‘";s:4:"博";s:3:"åš";s:4:"即";s:3:"å³";s:4:"卽";s:3:"å½";s:4:"卿";s:3:"å¿";s:4:"卿";s:3:"å¿";s:4:"卿";s:3:"å¿";s:4:"𠨬";s:4:"𠨬";s:4:"灰";s:3:"ç°";s:4:"及";s:3:"åŠ";s:4:"叟";s:3:"åŸ";s:4:"𠭣";s:4:"ð ­£";s:4:"叫";s:3:"å«";s:4:"叱";s:3:"å±";s:4:"吆";s:3:"å†";s:4:"咞";s:3:"å’ž";s:4:"吸";s:3:"å¸";s:4:"呈";s:3:"呈";s:4:"周";s:3:"周";s:4:"咢";s:3:"å’¢";s:4:"ð¯¡";s:3:"å“¶";s:4:"唐";s:3:"å”";s:4:"啓";s:3:"å•“";s:4:"啣";s:3:"å•£";s:4:"善";s:3:"å–„";s:4:"善";s:3:"å–„";s:4:"喙";s:3:"å–™";s:4:"喫";s:3:"å–«";s:4:"喳";s:3:"å–³";s:4:"嗂";s:3:"å—‚";s:4:"圖";s:3:"圖";s:4:"嘆";s:3:"嘆";s:4:"ð¯¡";s:3:"圗";s:4:"噑";s:3:"噑";s:4:"ð¯¡";s:3:"å™´";s:4:"ð¯¡";s:3:"切";s:4:"壮";s:3:"壮";s:4:"城";s:3:"城";s:4:"埴";s:3:"埴";s:4:"堍";s:3:"å ";s:4:"型";s:3:"åž‹";s:4:"堲";s:3:"å ²";s:4:"報";s:3:"å ±";s:4:"墬";s:3:"墬";s:4:"𡓤";s:4:"𡓤";s:4:"売";s:3:"売";s:4:"壷";s:3:"壷";s:4:"夆";s:3:"夆";s:4:"ð¯¡";s:3:"多";s:4:"夢";s:3:"夢";s:4:"奢";s:3:"奢";s:4:"𡚨";s:4:"𡚨";s:4:"𡛪";s:4:"𡛪";s:4:"姬";s:3:"姬";s:4:"娛";s:3:"娛";s:4:"娧";s:3:"娧";s:4:"姘";s:3:"姘";s:4:"婦";s:3:"婦";s:4:"㛮";s:3:"ã›®";s:4:"㛼";s:3:"㛼";s:4:"嬈";s:3:"嬈";s:4:"嬾";s:3:"嬾";s:4:"嬾";s:3:"嬾";s:4:"𡧈";s:4:"𡧈";s:4:"寃";s:3:"寃";s:4:"寘";s:3:"寘";s:4:"寧";s:3:"寧";s:4:"寳";s:3:"寳";s:4:"𡬘";s:4:"𡬘";s:4:"寿";s:3:"寿";s:4:"将";s:3:"å°†";s:4:"当";s:3:"当";s:4:"尢";s:3:"å°¢";s:4:"㞁";s:3:"ãž";s:4:"屠";s:3:"å± ";s:4:"屮";s:3:"å±®";s:4:"峀";s:3:"å³€";s:4:"岍";s:3:"å²";s:4:"𡷤";s:4:"ð¡·¤";s:4:"嵃";s:3:"嵃";s:4:"𡷦";s:4:"ð¡·¦";s:4:"嵮";s:3:"åµ®";s:4:"嵫";s:3:"嵫";s:4:"嵼";s:3:"åµ¼";s:4:"ð¯¢";s:3:"å·¡";s:4:"巢";s:3:"å·¢";s:4:"㠯";s:3:"ã ¯";s:4:"巽";s:3:"å·½";s:4:"帨";s:3:"帨";s:4:"帽";s:3:"帽";s:4:"幩";s:3:"幩";s:4:"㡢";s:3:"ã¡¢";s:4:"𢆃";s:4:"𢆃";s:4:"㡼";s:3:"㡼";s:4:"庰";s:3:"庰";s:4:"庳";s:3:"庳";s:4:"ð¯¢";s:3:"庶";s:4:"廊";s:3:"廊";s:4:"ð¯¢";s:4:"𪎒";s:4:"ð¯¢";s:3:"廾";s:4:"𢌱";s:4:"𢌱";s:4:"𢌱";s:4:"𢌱";s:4:"舁";s:3:"èˆ";s:4:"弢";s:3:"å¼¢";s:4:"弢";s:3:"å¼¢";s:4:"㣇";s:3:"㣇";s:4:"𣊸";s:4:"𣊸";s:4:"𦇚";s:4:"𦇚";s:4:"形";s:3:"å½¢";s:4:"彫";s:3:"彫";s:4:"㣣";s:3:"㣣";s:4:"徚";s:3:"徚";s:4:"ð¯¢";s:3:"å¿";s:4:"志";s:3:"å¿—";s:4:"忹";s:3:"忹";s:4:"悁";s:3:"æ‚";s:4:"㤺";s:3:"㤺";s:4:"㤜";s:3:"㤜";s:4:"悔";s:3:"æ‚”";s:4:"𢛔";s:4:"𢛔";s:4:"惇";s:3:"惇";s:4:"慈";s:3:"æ…ˆ";s:4:"慌";s:3:"æ…Œ";s:4:"慎";s:3:"æ…Ž";s:4:"慌";s:3:"æ…Œ";s:4:"慺";s:3:"æ…º";s:4:"憎";s:3:"憎";s:4:"憲";s:3:"憲";s:4:"憤";s:3:"憤";s:4:"憯";s:3:"憯";s:4:"懞";s:3:"懞";s:4:"懲";s:3:"懲";s:4:"懶";s:3:"懶";s:4:"成";s:3:"æˆ";s:4:"戛";s:3:"戛";s:4:"扝";s:3:"æ‰";s:4:"抱";s:3:"抱";s:4:"拔";s:3:"æ‹”";s:4:"捐";s:3:"æ";s:4:"𢬌";s:4:"𢬌";s:4:"挽";s:3:"挽";s:4:"拼";s:3:"拼";s:4:"捨";s:3:"æ¨";s:4:"掃";s:3:"掃";s:4:"揤";s:3:"æ¤";s:4:"𢯱";s:4:"𢯱";s:4:"搢";s:3:"æ¢";s:4:"揅";s:3:"æ…";s:4:"ð¯£";s:3:"掩";s:4:"㨮";s:3:"㨮";s:4:"摩";s:3:"æ‘©";s:4:"摾";s:3:"摾";s:4:"撝";s:3:"æ’";s:4:"摷";s:3:"æ‘·";s:4:"㩬";s:3:"㩬";s:4:"敏";s:3:"æ•";s:4:"敬";s:3:"敬";s:4:"𣀊";s:4:"𣀊";s:4:"旣";s:3:"æ—£";s:4:"書";s:3:"書";s:4:"ð¯£";s:3:"晉";s:4:"㬙";s:3:"㬙";s:4:"ð¯£";s:3:"æš‘";s:4:"ð¯£";s:3:"㬈";s:4:"㫤";s:3:"㫤";s:4:"冒";s:3:"冒";s:4:"冕";s:3:"冕";s:4:"最";s:3:"最";s:4:"暜";s:3:"æšœ";s:4:"肭";s:3:"è‚­";s:4:"䏙";s:3:"ä™";s:4:"朗";s:3:"朗";s:4:"望";s:3:"望";s:4:"朡";s:3:"朡";s:4:"杞";s:3:"æž";s:4:"杓";s:3:"æ“";s:4:"ð¯£";s:4:"ð£ƒ";s:4:"㭉";s:3:"ã­‰";s:4:"柺";s:3:"柺";s:4:"枅";s:3:"æž…";s:4:"桒";s:3:"æ¡’";s:4:"梅";s:3:"梅";s:4:"𣑭";s:4:"𣑭";s:4:"梎";s:3:"梎";s:4:"栟";s:3:"æ Ÿ";s:4:"椔";s:3:"椔";s:4:"㮝";s:3:"ã®";s:4:"楂";s:3:"楂";s:4:"榣";s:3:"榣";s:4:"槪";s:3:"槪";s:4:"檨";s:3:"檨";s:4:"𣚣";s:4:"𣚣";s:4:"櫛";s:3:"æ«›";s:4:"㰘";s:3:"ã°˜";s:4:"次";s:3:"次";s:4:"𣢧";s:4:"𣢧";s:4:"歔";s:3:"æ­”";s:4:"㱎";s:3:"㱎";s:4:"歲";s:3:"æ­²";s:4:"殟";s:3:"殟";s:4:"殺";s:3:"殺";s:4:"殻";s:3:"æ®»";s:4:"𣪍";s:4:"ð£ª";s:4:"𡴋";s:4:"ð¡´‹";s:4:"𣫺";s:4:"𣫺";s:4:"汎";s:3:"汎";s:4:"𣲼";s:4:"𣲼";s:4:"沿";s:3:"沿";s:4:"泍";s:3:"æ³";s:4:"汧";s:3:"æ±§";s:4:"洖";s:3:"æ´–";s:4:"派";s:3:"æ´¾";s:4:"ð¯¤";s:3:"æµ·";s:4:"流";s:3:"æµ";s:4:"浩";s:3:"浩";s:4:"浸";s:3:"浸";s:4:"涅";s:3:"æ¶…";s:4:"𣴞";s:4:"𣴞";s:4:"洴";s:3:"æ´´";s:4:"港";s:3:"港";s:4:"湮";s:3:"æ¹®";s:4:"㴳";s:3:"ã´³";s:4:"滋";s:3:"滋";s:4:"滇";s:3:"滇";s:4:"ð¯¤";s:4:"𣻑";s:4:"淹";s:3:"æ·¹";s:4:"ð¯¤";s:3:"æ½®";s:4:"ð¯¤";s:4:"𣽞";s:4:"𣾎";s:4:"𣾎";s:4:"濆";s:3:"濆";s:4:"瀹";s:3:"瀹";s:4:"瀞";s:3:"瀞";s:4:"瀛";s:3:"瀛";s:4:"㶖";s:3:"ã¶–";s:4:"灊";s:3:"çŠ";s:4:"災";s:3:"ç½";s:4:"灷";s:3:"ç·";s:4:"炭";s:3:"ç‚­";s:4:"𠔥";s:4:"𠔥";s:4:"煅";s:3:"ç……";s:4:"ð¯¤";s:4:"𤉣";s:4:"熜";s:3:"熜";s:4:"𤎫";s:4:"𤎫";s:4:"爨";s:3:"爨";s:4:"爵";s:3:"爵";s:4:"牐";s:3:"ç‰";s:4:"𤘈";s:4:"𤘈";s:4:"犀";s:3:"犀";s:4:"犕";s:3:"犕";s:4:"𤜵";s:4:"𤜵";s:4:"𤠔";s:4:"𤠔";s:4:"獺";s:3:"çº";s:4:"王";s:3:"王";s:4:"㺬";s:3:"㺬";s:4:"玥";s:3:"玥";s:4:"㺸";s:3:"㺸";s:4:"㺸";s:3:"㺸";s:4:"瑇";s:3:"瑇";s:4:"瑜";s:3:"瑜";s:4:"瑱";s:3:"瑱";s:4:"璅";s:3:"ç’…";s:4:"瓊";s:3:"瓊";s:4:"㼛";s:3:"ã¼›";s:4:"甤";s:3:"甤";s:4:"𤰶";s:4:"𤰶";s:4:"甾";s:3:"甾";s:4:"𤲒";s:4:"𤲒";s:4:"異";s:3:"ç•°";s:4:"𢆟";s:4:"𢆟";s:4:"瘐";s:3:"ç˜";s:4:"𤾡";s:4:"𤾡";s:4:"𤾸";s:4:"𤾸";s:4:"𥁄";s:4:"ð¥„";s:4:"㿼";s:3:"㿼";s:4:"䀈";s:3:"䀈";s:4:"直";s:3:"ç›´";s:4:"ð¯¥";s:4:"𥃳";s:4:"𥃲";s:4:"𥃲";s:4:"𥄙";s:4:"𥄙";s:4:"𥄳";s:4:"𥄳";s:4:"眞";s:3:"眞";s:4:"真";s:3:"真";s:4:"真";s:3:"真";s:4:"睊";s:3:"çŠ";s:4:"䀹";s:3:"䀹";s:4:"瞋";s:3:"çž‹";s:4:"䁆";s:3:"ä†";s:4:"䂖";s:3:"ä‚–";s:4:"ð¯¥";s:4:"ð¥";s:4:"硎";s:3:"硎";s:4:"ð¯¥";s:3:"碌";s:4:"ð¯¥";s:3:"磌";s:4:"䃣";s:3:"䃣";s:4:"𥘦";s:4:"𥘦";s:4:"祖";s:3:"祖";s:4:"𥚚";s:4:"𥚚";s:4:"𥛅";s:4:"𥛅";s:4:"福";s:3:"ç¦";s:4:"秫";s:3:"ç§«";s:4:"䄯";s:3:"䄯";s:4:"穀";s:3:"ç©€";s:4:"穊";s:3:"穊";s:4:"穏";s:3:"ç©";s:4:"𥥼";s:4:"𥥼";s:4:"ð¯¥";s:4:"𥪧";s:4:"𥪧";s:4:"𥪧";s:4:"竮";s:3:"ç«®";s:4:"䈂";s:3:"䈂";s:4:"𥮫";s:4:"𥮫";s:4:"篆";s:3:"篆";s:4:"築";s:3:"築";s:4:"䈧";s:3:"䈧";s:4:"𥲀";s:4:"𥲀";s:4:"糒";s:3:"ç³’";s:4:"䊠";s:3:"䊠";s:4:"糨";s:3:"糨";s:4:"糣";s:3:"ç³£";s:4:"紀";s:3:"ç´€";s:4:"𥾆";s:4:"𥾆";s:4:"絣";s:3:"çµ£";s:4:"䌁";s:3:"äŒ";s:4:"緇";s:3:"ç·‡";s:4:"縂";s:3:"縂";s:4:"繅";s:3:"ç¹…";s:4:"䌴";s:3:"䌴";s:4:"𦈨";s:4:"𦈨";s:4:"𦉇";s:4:"𦉇";s:4:"䍙";s:3:"ä™";s:4:"𦋙";s:4:"𦋙";s:4:"罺";s:3:"罺";s:4:"𦌾";s:4:"𦌾";s:4:"羕";s:3:"羕";s:4:"翺";s:3:"翺";s:4:"者";s:3:"者";s:4:"𦓚";s:4:"𦓚";s:4:"𦔣";s:4:"𦔣";s:4:"聠";s:3:"è ";s:4:"𦖨";s:4:"𦖨";s:4:"聰";s:3:"è°";s:4:"𣍟";s:4:"ð£Ÿ";s:4:"ð¯¦";s:3:"ä•";s:4:"育";s:3:"育";s:4:"脃";s:3:"脃";s:4:"䐋";s:3:"ä‹";s:4:"脾";s:3:"脾";s:4:"媵";s:3:"媵";s:4:"𦞧";s:4:"𦞧";s:4:"𦞵";s:4:"𦞵";s:4:"𣎓";s:4:"𣎓";s:4:"𣎜";s:4:"𣎜";s:4:"舁";s:3:"èˆ";s:4:"舄";s:3:"舄";s:4:"ð¯¦";s:3:"辞";s:4:"䑫";s:3:"ä‘«";s:4:"ð¯¦";s:3:"芑";s:4:"ð¯¦";s:3:"芋";s:4:"芝";s:3:"èŠ";s:4:"劳";s:3:"劳";s:4:"花";s:3:"花";s:4:"芳";s:3:"芳";s:4:"芽";s:3:"芽";s:4:"苦";s:3:"苦";s:4:"𦬼";s:4:"𦬼";s:4:"若";s:3:"è‹¥";s:4:"茝";s:3:"èŒ";s:4:"荣";s:3:"è£";s:4:"莭";s:3:"莭";s:4:"茣";s:3:"茣";s:4:"ð¯¦";s:3:"莽";s:4:"菧";s:3:"è§";s:4:"著";s:3:"è‘—";s:4:"荓";s:3:"è“";s:4:"菊";s:3:"èŠ";s:4:"菌";s:3:"èŒ";s:4:"菜";s:3:"èœ";s:4:"𦰶";s:4:"𦰶";s:4:"𦵫";s:4:"𦵫";s:4:"𦳕";s:4:"𦳕";s:4:"䔫";s:3:"䔫";s:4:"蓱";s:3:"蓱";s:4:"蓳";s:3:"蓳";s:4:"蔖";s:3:"è”–";s:4:"𧏊";s:4:"ð§Š";s:4:"蕤";s:3:"蕤";s:4:"𦼬";s:4:"𦼬";s:4:"䕝";s:3:"ä•";s:4:"䕡";s:3:"ä•¡";s:4:"𦾱";s:4:"𦾱";s:4:"𧃒";s:4:"𧃒";s:4:"䕫";s:3:"ä•«";s:4:"虐";s:3:"è™";s:4:"虜";s:3:"虜";s:4:"虧";s:3:"è™§";s:4:"虩";s:3:"虩";s:4:"蚩";s:3:"èš©";s:4:"蚈";s:3:"蚈";s:4:"蜎";s:3:"蜎";s:4:"蛢";s:3:"蛢";s:4:"蝹";s:3:"è¹";s:4:"蜨";s:3:"蜨";s:4:"蝫";s:3:"è«";s:4:"螆";s:3:"螆";s:4:"䗗";s:3:"ä——";s:4:"蟡";s:3:"蟡";s:4:"ð¯§";s:3:"è ";s:4:"䗹";s:3:"ä—¹";s:4:"衠";s:3:"è¡ ";s:4:"衣";s:3:"è¡£";s:4:"𧙧";s:4:"ð§™§";s:4:"裗";s:3:"裗";s:4:"裞";s:3:"裞";s:4:"䘵";s:3:"䘵";s:4:"裺";s:3:"裺";s:4:"㒻";s:3:"ã’»";s:4:"𧢮";s:4:"ð§¢®";s:4:"𧥦";s:4:"𧥦";s:4:"ð¯§";s:3:"äš¾";s:4:"䛇";s:3:"䛇";s:4:"ð¯§";s:3:"誠";s:4:"ð¯§";s:3:"è«­";s:4:"變";s:3:"變";s:4:"豕";s:3:"豕";s:4:"𧲨";s:4:"𧲨";s:4:"貫";s:3:"貫";s:4:"賁";s:3:"è³";s:4:"贛";s:3:"è´›";s:4:"起";s:3:"èµ·";s:4:"𧼯";s:4:"𧼯";s:4:"𠠄";s:4:"ð  „";s:4:"跋";s:3:"è·‹";s:4:"趼";s:3:"è¶¼";s:4:"跰";s:3:"è·°";s:4:"ð¯§";s:4:"𠣞";s:4:"軔";s:3:"è»”";s:4:"輸";s:3:"輸";s:4:"𨗒";s:4:"𨗒";s:4:"𨗭";s:4:"𨗭";s:4:"邔";s:3:"é‚”";s:4:"郱";s:3:"郱";s:4:"鄑";s:3:"é„‘";s:4:"𨜮";s:4:"𨜮";s:4:"鄛";s:3:"é„›";s:4:"鈸";s:3:"鈸";s:4:"鋗";s:3:"é‹—";s:4:"鋘";s:3:"鋘";s:4:"鉼";s:3:"鉼";s:4:"鏹";s:3:"é¹";s:4:"鐕";s:3:"é•";s:4:"𨯺";s:4:"𨯺";s:4:"開";s:3:"é–‹";s:4:"䦕";s:3:"䦕";s:4:"閷";s:3:"é–·";s:4:"𨵷";s:4:"𨵷";s:4:"䧦";s:3:"䧦";s:4:"雃";s:3:"雃";s:4:"嶲";s:3:"å¶²";s:4:"霣";s:3:"霣";s:4:"𩅅";s:4:"ð©……";s:4:"𩈚";s:4:"𩈚";s:4:"䩮";s:3:"ä©®";s:4:"䩶";s:3:"ä©¶";s:4:"韠";s:3:"韠";s:4:"𩐊";s:4:"ð©Š";s:4:"䪲";s:3:"䪲";s:4:"𩒖";s:4:"ð©’–";s:4:"頋";s:3:"é ‹";s:4:"頋";s:3:"é ‹";s:4:"頩";s:3:"é ©";s:4:"ð¯¨";s:4:"ð©–¶";s:4:"飢";s:3:"飢";s:4:"䬳";s:3:"䬳";s:4:"餩";s:3:"餩";s:4:"馧";s:3:"馧";s:4:"駂";s:3:"é§‚";s:4:"駾";s:3:"é§¾";s:4:"䯎";s:3:"䯎";s:4:"𩬰";s:4:"𩬰";s:4:"鬒";s:3:"鬒";s:4:"鱀";s:3:"é±€";s:4:"鳽";s:3:"é³½";s:4:"ð¯¨";s:3:"䳎";s:4:"䳭";s:3:"ä³­";s:4:"ð¯¨";s:3:"éµ§";s:4:"ð¯¨";s:4:"𪃎";s:4:"䳸";s:3:"䳸";s:4:"𪄅";s:4:"𪄅";s:4:"𪈎";s:4:"𪈎";s:4:"𪊑";s:4:"𪊑";s:4:"麻";s:3:"麻";s:4:"䵖";s:3:"äµ–";s:4:"黹";s:3:"黹";s:4:"黾";s:3:"黾";s:4:"鼅";s:3:"é¼…";s:4:"鼏";s:3:"é¼";s:4:"鼖";s:3:"é¼–";s:4:"鼻";s:3:"é¼»";s:4:"ð¯¨";s:4:"𪘀";s:2:"Æ";s:2:"AE";s:2:"Ã";s:1:"D";s:2:"Ø";s:1:"O";s:2:"Þ";s:2:"TH";s:2:"ß";s:2:"ss";s:2:"æ";s:2:"ae";s:2:"ð";s:1:"d";s:2:"ø";s:1:"o";s:2:"þ";s:2:"th";s:2:"Ä";s:1:"D";s:2:"Ä‘";s:1:"d";s:2:"Ħ";s:1:"H";s:2:"ħ";s:1:"h";s:2:"ı";s:1:"i";s:2:"ĸ";s:1:"q";s:2:"Å";s:1:"L";s:2:"Å‚";s:1:"l";s:2:"ÅŠ";s:1:"N";s:2:"Å‹";s:1:"n";s:2:"Å’";s:2:"OE";s:2:"Å“";s:2:"oe";s:2:"Ŧ";s:1:"T";s:2:"ŧ";s:1:"t";s:2:"Æ€";s:1:"b";s:2:"Æ";s:1:"B";s:2:"Æ‚";s:1:"B";s:2:"ƃ";s:1:"b";s:2:"Ƈ";s:1:"C";s:2:"ƈ";s:1:"c";s:2:"Ɖ";s:1:"D";s:2:"ÆŠ";s:1:"D";s:2:"Æ‹";s:1:"D";s:2:"ÆŒ";s:1:"d";s:2:"Æ";s:1:"E";s:2:"Æ‘";s:1:"F";s:2:"Æ’";s:1:"f";s:2:"Æ“";s:1:"G";s:2:"Æ•";s:2:"hv";s:2:"Æ–";s:1:"I";s:2:"Æ—";s:1:"I";s:2:"Ƙ";s:1:"K";s:2:"Æ™";s:1:"k";s:2:"Æš";s:1:"l";s:2:"Æ";s:1:"N";s:2:"Æž";s:1:"n";s:2:"Æ¢";s:2:"OI";s:2:"Æ£";s:2:"oi";s:2:"Ƥ";s:1:"P";s:2:"Æ¥";s:1:"p";s:2:"Æ«";s:1:"t";s:2:"Ƭ";s:1:"T";s:2:"Æ­";s:1:"t";s:2:"Æ®";s:1:"T";s:2:"Ʋ";s:1:"V";s:2:"Ƴ";s:1:"Y";s:2:"Æ´";s:1:"y";s:2:"Ƶ";s:1:"Z";s:2:"ƶ";s:1:"z";s:2:"Ǥ";s:1:"G";s:2:"Ç¥";s:1:"g";s:2:"È¡";s:1:"d";s:2:"Ȥ";s:1:"Z";s:2:"È¥";s:1:"z";s:2:"È´";s:1:"l";s:2:"ȵ";s:1:"n";s:2:"ȶ";s:1:"t";s:2:"È·";s:1:"j";s:2:"ȸ";s:2:"db";s:2:"ȹ";s:2:"qp";s:2:"Ⱥ";s:1:"A";s:2:"È»";s:1:"C";s:2:"ȼ";s:1:"c";s:2:"Ƚ";s:1:"L";s:2:"Ⱦ";s:1:"T";s:2:"È¿";s:1:"s";s:2:"É€";s:1:"z";s:2:"Ƀ";s:1:"B";s:2:"É„";s:1:"U";s:2:"Ɇ";s:1:"E";s:2:"ɇ";s:1:"e";s:2:"Ɉ";s:1:"J";s:2:"ɉ";s:1:"j";s:2:"ÉŒ";s:1:"R";s:2:"É";s:1:"r";s:2:"ÉŽ";s:1:"Y";s:2:"É";s:1:"y";s:2:"É“";s:1:"b";s:2:"É•";s:1:"c";s:2:"É–";s:1:"d";s:2:"É—";s:1:"d";s:2:"É›";s:1:"e";s:2:"ÉŸ";s:1:"j";s:2:"É ";s:1:"g";s:2:"É¡";s:1:"g";s:2:"É¢";s:1:"G";s:2:"ɦ";s:1:"h";s:2:"ɧ";s:1:"h";s:2:"ɨ";s:1:"i";s:2:"ɪ";s:1:"I";s:2:"É«";s:1:"l";s:2:"ɬ";s:1:"l";s:2:"É­";s:1:"l";s:2:"ɱ";s:1:"m";s:2:"ɲ";s:1:"n";s:2:"ɳ";s:1:"n";s:2:"É´";s:1:"N";s:2:"ɶ";s:2:"OE";s:2:"ɼ";s:1:"r";s:2:"ɽ";s:1:"r";s:2:"ɾ";s:1:"r";s:2:"Ê€";s:1:"R";s:2:"Ê‚";s:1:"s";s:2:"ʈ";s:1:"t";s:2:"ʉ";s:1:"u";s:2:"Ê‹";s:1:"v";s:2:"Ê";s:1:"Y";s:2:"Ê";s:1:"z";s:2:"Ê‘";s:1:"z";s:2:"Ê™";s:1:"B";s:2:"Ê›";s:1:"G";s:2:"Êœ";s:1:"H";s:2:"Ê";s:1:"j";s:2:"ÊŸ";s:1:"L";s:2:"Ê ";s:1:"q";s:2:"Ê£";s:2:"dz";s:2:"Ê¥";s:2:"dz";s:2:"ʦ";s:2:"ts";s:2:"ʪ";s:2:"ls";s:2:"Ê«";s:2:"lz";s:3:"á´€";s:1:"A";s:3:"á´";s:2:"AE";s:3:"á´ƒ";s:1:"B";s:3:"á´„";s:1:"C";s:3:"á´…";s:1:"D";s:3:"á´†";s:1:"D";s:3:"á´‡";s:1:"E";s:3:"á´Š";s:1:"J";s:3:"á´‹";s:1:"K";s:3:"á´Œ";s:1:"L";s:3:"á´";s:1:"M";s:3:"á´";s:1:"O";s:3:"á´˜";s:1:"P";s:3:"á´›";s:1:"T";s:3:"á´œ";s:1:"U";s:3:"á´ ";s:1:"V";s:3:"á´¡";s:1:"W";s:3:"á´¢";s:1:"Z";s:3:"ᵫ";s:2:"ue";s:3:"ᵬ";s:1:"b";s:3:"áµ­";s:1:"d";s:3:"áµ®";s:1:"f";s:3:"ᵯ";s:1:"m";s:3:"áµ°";s:1:"n";s:3:"áµ±";s:1:"p";s:3:"áµ²";s:1:"r";s:3:"áµ³";s:1:"r";s:3:"áµ´";s:1:"s";s:3:"áµµ";s:1:"t";s:3:"áµ¶";s:1:"z";s:3:"ᵺ";s:2:"th";s:3:"áµ»";s:1:"I";s:3:"áµ½";s:1:"p";s:3:"áµ¾";s:1:"U";s:3:"á¶€";s:1:"b";s:3:"á¶";s:1:"d";s:3:"á¶‚";s:1:"f";s:3:"ᶃ";s:1:"g";s:3:"á¶„";s:1:"k";s:3:"á¶…";s:1:"l";s:3:"ᶆ";s:1:"m";s:3:"ᶇ";s:1:"n";s:3:"ᶈ";s:1:"p";s:3:"ᶉ";s:1:"r";s:3:"á¶Š";s:1:"s";s:3:"á¶Œ";s:1:"v";s:3:"á¶";s:1:"x";s:3:"á¶Ž";s:1:"z";s:3:"á¶";s:1:"a";s:3:"á¶‘";s:1:"d";s:3:"á¶’";s:1:"e";s:3:"á¶“";s:1:"e";s:3:"á¶–";s:1:"i";s:3:"á¶™";s:1:"u";s:3:"ẜ";s:1:"s";s:3:"áº";s:1:"s";s:3:"ẞ";s:2:"SS";s:3:"Ỻ";s:2:"LL";s:3:"á»»";s:2:"ll";s:3:"Ỽ";s:1:"V";s:3:"ỽ";s:1:"v";s:3:"Ỿ";s:1:"Y";s:3:"ỿ";s:1:"y";s:2:"©";s:3:"(C)";s:2:"®";s:3:"(R)";s:3:"â‚ ";s:2:"CE";s:3:"â‚¢";s:2:"Cr";s:3:"â‚£";s:3:"Fr.";s:3:"₤";s:2:"L.";s:3:"â‚§";s:3:"Pts";s:3:"₺";s:2:"TL";s:3:"₹";s:2:"Rs";s:3:"℞";s:2:"Rx";s:3:"〇";s:1:"0";s:3:"‘";s:1:"'";s:3:"’";s:1:"'";s:3:"‚";s:1:",";s:3:"‛";s:1:"'";s:3:"“";s:1:""";s:3:"â€";s:1:""";s:3:"„";s:2:",,";s:3:"‟";s:1:""";s:3:"′";s:1:"'";s:3:"ã€";s:1:""";s:3:"〞";s:1:""";s:2:"«";s:2:"<<";s:2:"»";s:2:">>";s:3:"‹";s:1:"<";s:3:"›";s:1:">";s:3:"â€";s:1:"-";s:3:"‑";s:1:"-";s:3:"‒";s:1:"-";s:3:"–";s:1:"-";s:3:"—";s:1:"-";s:3:"―";s:1:"-";s:3:"︱";s:1:"-";s:3:"︲";s:1:"-";s:3:"‖";s:2:"||";s:3:"â„";s:1:"/";s:3:"â…";s:1:"[";s:3:"â†";s:1:"]";s:3:"âŽ";s:1:"*";s:3:"ã€";s:1:",";s:3:"。";s:1:".";s:3:"〈";s:1:"<";s:3:"〉";s:1:">";s:3:"《";s:2:"<<";s:3:"》";s:2:">>";s:3:"〔";s:1:"[";s:3:"〕";s:1:"]";s:3:"〘";s:1:"[";s:3:"〙";s:1:"]";s:3:"〚";s:1:"[";s:3:"〛";s:1:"]";s:3:"ï¸";s:1:",";s:3:"︑";s:1:",";s:3:"︒";s:1:".";s:3:"︓";s:1:":";s:3:"︔";s:1:";";s:3:"︕";s:1:"!";s:3:"︖";s:1:"?";s:3:"︙";s:3:"...";s:3:"︰";s:2:"..";s:3:"︵";s:1:"(";s:3:"︶";s:1:")";s:3:"︷";s:1:"{";s:3:"︸";s:1:"}";s:3:"︹";s:1:"[";s:3:"︺";s:1:"]";s:3:"︽";s:2:"<<";s:3:"︾";s:2:">>";s:3:"︿";s:1:"<";s:3:"ï¹€";s:1:">";s:3:"﹇";s:1:"[";s:3:"﹈";s:1:"]";s:2:"×";s:1:"*";s:2:"÷";s:1:"/";s:3:"−";s:1:"-";s:3:"∕";s:1:"/";s:3:"∖";s:1:"\";s:3:"∣";s:1:"|";s:3:"∥";s:2:"||";s:3:"≪";s:2:"<<";s:3:"≫";s:2:">>";s:3:"⦅";s:2:"((";s:3:"⦆";s:2:"))";} \ No newline at end of file diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.ser b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.ser deleted file mode 100644 index 13dabdde..00000000 --- a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.ser +++ /dev/null @@ -1 +0,0 @@ -a:1092:{s:1:"A";s:1:"a";s:1:"B";s:1:"b";s:1:"C";s:1:"c";s:1:"D";s:1:"d";s:1:"E";s:1:"e";s:1:"F";s:1:"f";s:1:"G";s:1:"g";s:1:"H";s:1:"h";s:1:"I";s:1:"i";s:1:"J";s:1:"j";s:1:"K";s:1:"k";s:1:"L";s:1:"l";s:1:"M";s:1:"m";s:1:"N";s:1:"n";s:1:"O";s:1:"o";s:1:"P";s:1:"p";s:1:"Q";s:1:"q";s:1:"R";s:1:"r";s:1:"S";s:1:"s";s:1:"T";s:1:"t";s:1:"U";s:1:"u";s:1:"V";s:1:"v";s:1:"W";s:1:"w";s:1:"X";s:1:"x";s:1:"Y";s:1:"y";s:1:"Z";s:1:"z";s:2:"À";s:2:"à";s:2:"Ã";s:2:"á";s:2:"Â";s:2:"â";s:2:"Ã";s:2:"ã";s:2:"Ä";s:2:"ä";s:2:"Ã…";s:2:"Ã¥";s:2:"Æ";s:2:"æ";s:2:"Ç";s:2:"ç";s:2:"È";s:2:"è";s:2:"É";s:2:"é";s:2:"Ê";s:2:"ê";s:2:"Ë";s:2:"ë";s:2:"ÃŒ";s:2:"ì";s:2:"Ã";s:2:"í";s:2:"ÃŽ";s:2:"î";s:2:"Ã";s:2:"ï";s:2:"Ã";s:2:"ð";s:2:"Ñ";s:2:"ñ";s:2:"Ã’";s:2:"ò";s:2:"Ó";s:2:"ó";s:2:"Ô";s:2:"ô";s:2:"Õ";s:2:"õ";s:2:"Ö";s:2:"ö";s:2:"Ø";s:2:"ø";s:2:"Ù";s:2:"ù";s:2:"Ú";s:2:"ú";s:2:"Û";s:2:"û";s:2:"Ü";s:2:"ü";s:2:"Ã";s:2:"ý";s:2:"Þ";s:2:"þ";s:2:"Ä€";s:2:"Ä";s:2:"Ä‚";s:2:"ă";s:2:"Ä„";s:2:"Ä…";s:2:"Ć";s:2:"ć";s:2:"Ĉ";s:2:"ĉ";s:2:"ÄŠ";s:2:"Ä‹";s:2:"ÄŒ";s:2:"Ä";s:2:"ÄŽ";s:2:"Ä";s:2:"Ä";s:2:"Ä‘";s:2:"Ä’";s:2:"Ä“";s:2:"Ä”";s:2:"Ä•";s:2:"Ä–";s:2:"Ä—";s:2:"Ę";s:2:"Ä™";s:2:"Äš";s:2:"Ä›";s:2:"Äœ";s:2:"Ä";s:2:"Äž";s:2:"ÄŸ";s:2:"Ä ";s:2:"Ä¡";s:2:"Ä¢";s:2:"Ä£";s:2:"Ĥ";s:2:"Ä¥";s:2:"Ħ";s:2:"ħ";s:2:"Ĩ";s:2:"Ä©";s:2:"Ī";s:2:"Ä«";s:2:"Ĭ";s:2:"Ä­";s:2:"Ä®";s:2:"į";s:2:"İ";s:1:"i";s:2:"IJ";s:2:"ij";s:2:"Ä´";s:2:"ĵ";s:2:"Ķ";s:2:"Ä·";s:2:"Ĺ";s:2:"ĺ";s:2:"Ä»";s:2:"ļ";s:2:"Ľ";s:2:"ľ";s:2:"Ä¿";s:2:"Å€";s:2:"Å";s:2:"Å‚";s:2:"Ń";s:2:"Å„";s:2:"Å…";s:2:"ņ";s:2:"Ň";s:2:"ň";s:2:"ÅŠ";s:2:"Å‹";s:2:"ÅŒ";s:2:"Å";s:2:"ÅŽ";s:2:"Å";s:2:"Å";s:2:"Å‘";s:2:"Å’";s:2:"Å“";s:2:"Å”";s:2:"Å•";s:2:"Å–";s:2:"Å—";s:2:"Ř";s:2:"Å™";s:2:"Åš";s:2:"Å›";s:2:"Åœ";s:2:"Å";s:2:"Åž";s:2:"ÅŸ";s:2:"Å ";s:2:"Å¡";s:2:"Å¢";s:2:"Å£";s:2:"Ť";s:2:"Å¥";s:2:"Ŧ";s:2:"ŧ";s:2:"Ũ";s:2:"Å©";s:2:"Ū";s:2:"Å«";s:2:"Ŭ";s:2:"Å­";s:2:"Å®";s:2:"ů";s:2:"Ű";s:2:"ű";s:2:"Ų";s:2:"ų";s:2:"Å´";s:2:"ŵ";s:2:"Ŷ";s:2:"Å·";s:2:"Ÿ";s:2:"ÿ";s:2:"Ź";s:2:"ź";s:2:"Å»";s:2:"ż";s:2:"Ž";s:2:"ž";s:2:"Æ";s:2:"É“";s:2:"Æ‚";s:2:"ƃ";s:2:"Æ„";s:2:"Æ…";s:2:"Ɔ";s:2:"É”";s:2:"Ƈ";s:2:"ƈ";s:2:"Ɖ";s:2:"É–";s:2:"ÆŠ";s:2:"É—";s:2:"Æ‹";s:2:"ÆŒ";s:2:"ÆŽ";s:2:"Ç";s:2:"Æ";s:2:"É™";s:2:"Æ";s:2:"É›";s:2:"Æ‘";s:2:"Æ’";s:2:"Æ“";s:2:"É ";s:2:"Æ”";s:2:"É£";s:2:"Æ–";s:2:"É©";s:2:"Æ—";s:2:"ɨ";s:2:"Ƙ";s:2:"Æ™";s:2:"Æœ";s:2:"ɯ";s:2:"Æ";s:2:"ɲ";s:2:"ÆŸ";s:2:"ɵ";s:2:"Æ ";s:2:"Æ¡";s:2:"Æ¢";s:2:"Æ£";s:2:"Ƥ";s:2:"Æ¥";s:2:"Ʀ";s:2:"Ê€";s:2:"Ƨ";s:2:"ƨ";s:2:"Æ©";s:2:"ʃ";s:2:"Ƭ";s:2:"Æ­";s:2:"Æ®";s:2:"ʈ";s:2:"Ư";s:2:"ư";s:2:"Ʊ";s:2:"ÊŠ";s:2:"Ʋ";s:2:"Ê‹";s:2:"Ƴ";s:2:"Æ´";s:2:"Ƶ";s:2:"ƶ";s:2:"Æ·";s:2:"Ê’";s:2:"Ƹ";s:2:"ƹ";s:2:"Ƽ";s:2:"ƽ";s:2:"Ç„";s:2:"dž";s:2:"Ç…";s:2:"dž";s:2:"LJ";s:2:"lj";s:2:"Lj";s:2:"lj";s:2:"ÇŠ";s:2:"ÇŒ";s:2:"Ç‹";s:2:"ÇŒ";s:2:"Ç";s:2:"ÇŽ";s:2:"Ç";s:2:"Ç";s:2:"Ç‘";s:2:"Ç’";s:2:"Ç“";s:2:"Ç”";s:2:"Ç•";s:2:"Ç–";s:2:"Ç—";s:2:"ǘ";s:2:"Ç™";s:2:"Çš";s:2:"Ç›";s:2:"Çœ";s:2:"Çž";s:2:"ÇŸ";s:2:"Ç ";s:2:"Ç¡";s:2:"Ç¢";s:2:"Ç£";s:2:"Ǥ";s:2:"Ç¥";s:2:"Ǧ";s:2:"ǧ";s:2:"Ǩ";s:2:"Ç©";s:2:"Ǫ";s:2:"Ç«";s:2:"Ǭ";s:2:"Ç­";s:2:"Ç®";s:2:"ǯ";s:2:"DZ";s:2:"dz";s:2:"Dz";s:2:"dz";s:2:"Ç´";s:2:"ǵ";s:2:"Ƕ";s:2:"Æ•";s:2:"Ç·";s:2:"Æ¿";s:2:"Ǹ";s:2:"ǹ";s:2:"Ǻ";s:2:"Ç»";s:2:"Ǽ";s:2:"ǽ";s:2:"Ǿ";s:2:"Ç¿";s:2:"È€";s:2:"È";s:2:"È‚";s:2:"ȃ";s:2:"È„";s:2:"È…";s:2:"Ȇ";s:2:"ȇ";s:2:"Ȉ";s:2:"ȉ";s:2:"ÈŠ";s:2:"È‹";s:2:"ÈŒ";s:2:"È";s:2:"ÈŽ";s:2:"È";s:2:"È";s:2:"È‘";s:2:"È’";s:2:"È“";s:2:"È”";s:2:"È•";s:2:"È–";s:2:"È—";s:2:"Ș";s:2:"È™";s:2:"Èš";s:2:"È›";s:2:"Èœ";s:2:"È";s:2:"Èž";s:2:"ÈŸ";s:2:"È ";s:2:"Æž";s:2:"È¢";s:2:"È£";s:2:"Ȥ";s:2:"È¥";s:2:"Ȧ";s:2:"ȧ";s:2:"Ȩ";s:2:"È©";s:2:"Ȫ";s:2:"È«";s:2:"Ȭ";s:2:"È­";s:2:"È®";s:2:"ȯ";s:2:"Ȱ";s:2:"ȱ";s:2:"Ȳ";s:2:"ȳ";s:2:"Ⱥ";s:3:"â±¥";s:2:"È»";s:2:"ȼ";s:2:"Ƚ";s:2:"Æš";s:2:"Ⱦ";s:3:"ⱦ";s:2:"É";s:2:"É‚";s:2:"Ƀ";s:2:"Æ€";s:2:"É„";s:2:"ʉ";s:2:"É…";s:2:"ÊŒ";s:2:"Ɇ";s:2:"ɇ";s:2:"Ɉ";s:2:"ɉ";s:2:"ÉŠ";s:2:"É‹";s:2:"ÉŒ";s:2:"É";s:2:"ÉŽ";s:2:"É";s:2:"Ͱ";s:2:"ͱ";s:2:"Ͳ";s:2:"ͳ";s:2:"Ͷ";s:2:"Í·";s:2:"Í¿";s:2:"ϳ";s:2:"Ά";s:2:"ά";s:2:"Έ";s:2:"έ";s:2:"Ή";s:2:"ή";s:2:"Ί";s:2:"ί";s:2:"ÎŒ";s:2:"ÏŒ";s:2:"ÎŽ";s:2:"Ï";s:2:"Î";s:2:"ÏŽ";s:2:"Α";s:2:"α";s:2:"Î’";s:2:"β";s:2:"Γ";s:2:"γ";s:2:"Δ";s:2:"δ";s:2:"Ε";s:2:"ε";s:2:"Ζ";s:2:"ζ";s:2:"Η";s:2:"η";s:2:"Θ";s:2:"θ";s:2:"Ι";s:2:"ι";s:2:"Κ";s:2:"κ";s:2:"Λ";s:2:"λ";s:2:"Μ";s:2:"μ";s:2:"Î";s:2:"ν";s:2:"Ξ";s:2:"ξ";s:2:"Ο";s:2:"ο";s:2:"Π";s:2:"Ï€";s:2:"Ρ";s:2:"Ï";s:2:"Σ";s:2:"σ";s:2:"Τ";s:2:"Ï„";s:2:"Î¥";s:2:"Ï…";s:2:"Φ";s:2:"φ";s:2:"Χ";s:2:"χ";s:2:"Ψ";s:2:"ψ";s:2:"Ω";s:2:"ω";s:2:"Ϊ";s:2:"ÏŠ";s:2:"Ϋ";s:2:"Ï‹";s:2:"Ï";s:2:"Ï—";s:2:"Ϙ";s:2:"Ï™";s:2:"Ïš";s:2:"Ï›";s:2:"Ïœ";s:2:"Ï";s:2:"Ïž";s:2:"ÏŸ";s:2:"Ï ";s:2:"Ï¡";s:2:"Ï¢";s:2:"Ï£";s:2:"Ϥ";s:2:"Ï¥";s:2:"Ϧ";s:2:"ϧ";s:2:"Ϩ";s:2:"Ï©";s:2:"Ϫ";s:2:"Ï«";s:2:"Ϭ";s:2:"Ï­";s:2:"Ï®";s:2:"ϯ";s:2:"Ï´";s:2:"θ";s:2:"Ï·";s:2:"ϸ";s:2:"Ϲ";s:2:"ϲ";s:2:"Ϻ";s:2:"Ï»";s:2:"Ͻ";s:2:"Í»";s:2:"Ͼ";s:2:"ͼ";s:2:"Ï¿";s:2:"ͽ";s:2:"Ѐ";s:2:"Ñ";s:2:"Ð";s:2:"Ñ‘";s:2:"Ђ";s:2:"Ñ’";s:2:"Ѓ";s:2:"Ñ“";s:2:"Є";s:2:"Ñ”";s:2:"Ð…";s:2:"Ñ•";s:2:"І";s:2:"Ñ–";s:2:"Ї";s:2:"Ñ—";s:2:"Ј";s:2:"ј";s:2:"Љ";s:2:"Ñ™";s:2:"Њ";s:2:"Ñš";s:2:"Ћ";s:2:"Ñ›";s:2:"ÐŒ";s:2:"Ñœ";s:2:"Ð";s:2:"Ñ";s:2:"ÐŽ";s:2:"Ñž";s:2:"Ð";s:2:"ÑŸ";s:2:"Ð";s:2:"а";s:2:"Б";s:2:"б";s:2:"Ð’";s:2:"в";s:2:"Г";s:2:"г";s:2:"Д";s:2:"д";s:2:"Е";s:2:"е";s:2:"Ж";s:2:"ж";s:2:"З";s:2:"з";s:2:"И";s:2:"и";s:2:"Й";s:2:"й";s:2:"К";s:2:"к";s:2:"Л";s:2:"л";s:2:"М";s:2:"м";s:2:"Ð";s:2:"н";s:2:"О";s:2:"о";s:2:"П";s:2:"п";s:2:"Р";s:2:"Ñ€";s:2:"С";s:2:"Ñ";s:2:"Т";s:2:"Ñ‚";s:2:"У";s:2:"у";s:2:"Ф";s:2:"Ñ„";s:2:"Ð¥";s:2:"Ñ…";s:2:"Ц";s:2:"ц";s:2:"Ч";s:2:"ч";s:2:"Ш";s:2:"ш";s:2:"Щ";s:2:"щ";s:2:"Ъ";s:2:"ÑŠ";s:2:"Ы";s:2:"Ñ‹";s:2:"Ь";s:2:"ÑŒ";s:2:"Э";s:2:"Ñ";s:2:"Ю";s:2:"ÑŽ";s:2:"Я";s:2:"Ñ";s:2:"Ñ ";s:2:"Ñ¡";s:2:"Ñ¢";s:2:"Ñ£";s:2:"Ѥ";s:2:"Ñ¥";s:2:"Ѧ";s:2:"ѧ";s:2:"Ѩ";s:2:"Ñ©";s:2:"Ѫ";s:2:"Ñ«";s:2:"Ѭ";s:2:"Ñ­";s:2:"Ñ®";s:2:"ѯ";s:2:"Ѱ";s:2:"ѱ";s:2:"Ѳ";s:2:"ѳ";s:2:"Ñ´";s:2:"ѵ";s:2:"Ѷ";s:2:"Ñ·";s:2:"Ѹ";s:2:"ѹ";s:2:"Ѻ";s:2:"Ñ»";s:2:"Ѽ";s:2:"ѽ";s:2:"Ѿ";s:2:"Ñ¿";s:2:"Ò€";s:2:"Ò";s:2:"ÒŠ";s:2:"Ò‹";s:2:"ÒŒ";s:2:"Ò";s:2:"ÒŽ";s:2:"Ò";s:2:"Ò";s:2:"Ò‘";s:2:"Ò’";s:2:"Ò“";s:2:"Ò”";s:2:"Ò•";s:2:"Ò–";s:2:"Ò—";s:2:"Ò˜";s:2:"Ò™";s:2:"Òš";s:2:"Ò›";s:2:"Òœ";s:2:"Ò";s:2:"Òž";s:2:"ÒŸ";s:2:"Ò ";s:2:"Ò¡";s:2:"Ò¢";s:2:"Ò£";s:2:"Ò¤";s:2:"Ò¥";s:2:"Ò¦";s:2:"Ò§";s:2:"Ò¨";s:2:"Ò©";s:2:"Òª";s:2:"Ò«";s:2:"Ò¬";s:2:"Ò­";s:2:"Ò®";s:2:"Ò¯";s:2:"Ò°";s:2:"Ò±";s:2:"Ò²";s:2:"Ò³";s:2:"Ò´";s:2:"Òµ";s:2:"Ò¶";s:2:"Ò·";s:2:"Ò¸";s:2:"Ò¹";s:2:"Òº";s:2:"Ò»";s:2:"Ò¼";s:2:"Ò½";s:2:"Ò¾";s:2:"Ò¿";s:2:"Ó€";s:2:"Ó";s:2:"Ó";s:2:"Ó‚";s:2:"Óƒ";s:2:"Ó„";s:2:"Ó…";s:2:"Ó†";s:2:"Ó‡";s:2:"Óˆ";s:2:"Ó‰";s:2:"ÓŠ";s:2:"Ó‹";s:2:"ÓŒ";s:2:"Ó";s:2:"ÓŽ";s:2:"Ó";s:2:"Ó‘";s:2:"Ó’";s:2:"Ó“";s:2:"Ó”";s:2:"Ó•";s:2:"Ó–";s:2:"Ó—";s:2:"Ó˜";s:2:"Ó™";s:2:"Óš";s:2:"Ó›";s:2:"Óœ";s:2:"Ó";s:2:"Óž";s:2:"ÓŸ";s:2:"Ó ";s:2:"Ó¡";s:2:"Ó¢";s:2:"Ó£";s:2:"Ó¤";s:2:"Ó¥";s:2:"Ó¦";s:2:"Ó§";s:2:"Ó¨";s:2:"Ó©";s:2:"Óª";s:2:"Ó«";s:2:"Ó¬";s:2:"Ó­";s:2:"Ó®";s:2:"Ó¯";s:2:"Ó°";s:2:"Ó±";s:2:"Ó²";s:2:"Ó³";s:2:"Ó´";s:2:"Óµ";s:2:"Ó¶";s:2:"Ó·";s:2:"Ó¸";s:2:"Ó¹";s:2:"Óº";s:2:"Ó»";s:2:"Ó¼";s:2:"Ó½";s:2:"Ó¾";s:2:"Ó¿";s:2:"Ô€";s:2:"Ô";s:2:"Ô‚";s:2:"Ôƒ";s:2:"Ô„";s:2:"Ô…";s:2:"Ô†";s:2:"Ô‡";s:2:"Ôˆ";s:2:"Ô‰";s:2:"ÔŠ";s:2:"Ô‹";s:2:"ÔŒ";s:2:"Ô";s:2:"ÔŽ";s:2:"Ô";s:2:"Ô";s:2:"Ô‘";s:2:"Ô’";s:2:"Ô“";s:2:"Ô”";s:2:"Ô•";s:2:"Ô–";s:2:"Ô—";s:2:"Ô˜";s:2:"Ô™";s:2:"Ôš";s:2:"Ô›";s:2:"Ôœ";s:2:"Ô";s:2:"Ôž";s:2:"ÔŸ";s:2:"Ô ";s:2:"Ô¡";s:2:"Ô¢";s:2:"Ô£";s:2:"Ô¤";s:2:"Ô¥";s:2:"Ô¦";s:2:"Ô§";s:2:"Ô¨";s:2:"Ô©";s:2:"Ôª";s:2:"Ô«";s:2:"Ô¬";s:2:"Ô­";s:2:"Ô®";s:2:"Ô¯";s:2:"Ô±";s:2:"Õ¡";s:2:"Ô²";s:2:"Õ¢";s:2:"Ô³";s:2:"Õ£";s:2:"Ô´";s:2:"Õ¤";s:2:"Ôµ";s:2:"Õ¥";s:2:"Ô¶";s:2:"Õ¦";s:2:"Ô·";s:2:"Õ§";s:2:"Ô¸";s:2:"Õ¨";s:2:"Ô¹";s:2:"Õ©";s:2:"Ôº";s:2:"Õª";s:2:"Ô»";s:2:"Õ«";s:2:"Ô¼";s:2:"Õ¬";s:2:"Ô½";s:2:"Õ­";s:2:"Ô¾";s:2:"Õ®";s:2:"Ô¿";s:2:"Õ¯";s:2:"Õ€";s:2:"Õ°";s:2:"Õ";s:2:"Õ±";s:2:"Õ‚";s:2:"Õ²";s:2:"Õƒ";s:2:"Õ³";s:2:"Õ„";s:2:"Õ´";s:2:"Õ…";s:2:"Õµ";s:2:"Õ†";s:2:"Õ¶";s:2:"Õ‡";s:2:"Õ·";s:2:"Õˆ";s:2:"Õ¸";s:2:"Õ‰";s:2:"Õ¹";s:2:"ÕŠ";s:2:"Õº";s:2:"Õ‹";s:2:"Õ»";s:2:"ÕŒ";s:2:"Õ¼";s:2:"Õ";s:2:"Õ½";s:2:"ÕŽ";s:2:"Õ¾";s:2:"Õ";s:2:"Õ¿";s:2:"Õ";s:2:"Ö€";s:2:"Õ‘";s:2:"Ö";s:2:"Õ’";s:2:"Ö‚";s:2:"Õ“";s:2:"Öƒ";s:2:"Õ”";s:2:"Ö„";s:2:"Õ•";s:2:"Ö…";s:2:"Õ–";s:2:"Ö†";s:3:"á‚ ";s:3:"â´€";s:3:"á‚¡";s:3:"â´";s:3:"á‚¢";s:3:"â´‚";s:3:"á‚£";s:3:"â´ƒ";s:3:"Ⴄ";s:3:"â´„";s:3:"á‚¥";s:3:"â´…";s:3:"Ⴆ";s:3:"â´†";s:3:"á‚§";s:3:"â´‡";s:3:"Ⴈ";s:3:"â´ˆ";s:3:"á‚©";s:3:"â´‰";s:3:"Ⴊ";s:3:"â´Š";s:3:"á‚«";s:3:"â´‹";s:3:"Ⴌ";s:3:"â´Œ";s:3:"á‚­";s:3:"â´";s:3:"á‚®";s:3:"â´Ž";s:3:"Ⴏ";s:3:"â´";s:3:"á‚°";s:3:"â´";s:3:"Ⴑ";s:3:"â´‘";s:3:"Ⴒ";s:3:"â´’";s:3:"Ⴓ";s:3:"â´“";s:3:"á‚´";s:3:"â´”";s:3:"Ⴕ";s:3:"â´•";s:3:"á‚¶";s:3:"â´–";s:3:"á‚·";s:3:"â´—";s:3:"Ⴘ";s:3:"â´˜";s:3:"Ⴙ";s:3:"â´™";s:3:"Ⴚ";s:3:"â´š";s:3:"á‚»";s:3:"â´›";s:3:"Ⴜ";s:3:"â´œ";s:3:"Ⴝ";s:3:"â´";s:3:"Ⴞ";s:3:"â´ž";s:3:"á‚¿";s:3:"â´Ÿ";s:3:"Ⴠ";s:3:"â´ ";s:3:"áƒ";s:3:"â´¡";s:3:"Ⴢ";s:3:"â´¢";s:3:"Ⴣ";s:3:"â´£";s:3:"Ⴤ";s:3:"â´¤";s:3:"Ⴥ";s:3:"â´¥";s:3:"Ⴧ";s:3:"â´§";s:3:"áƒ";s:3:"â´­";s:3:"Ḁ";s:3:"á¸";s:3:"Ḃ";s:3:"ḃ";s:3:"Ḅ";s:3:"ḅ";s:3:"Ḇ";s:3:"ḇ";s:3:"Ḉ";s:3:"ḉ";s:3:"Ḋ";s:3:"ḋ";s:3:"Ḍ";s:3:"á¸";s:3:"Ḏ";s:3:"á¸";s:3:"á¸";s:3:"ḑ";s:3:"Ḓ";s:3:"ḓ";s:3:"Ḕ";s:3:"ḕ";s:3:"Ḗ";s:3:"ḗ";s:3:"Ḙ";s:3:"ḙ";s:3:"Ḛ";s:3:"ḛ";s:3:"Ḝ";s:3:"á¸";s:3:"Ḟ";s:3:"ḟ";s:3:"Ḡ";s:3:"ḡ";s:3:"Ḣ";s:3:"ḣ";s:3:"Ḥ";s:3:"ḥ";s:3:"Ḧ";s:3:"ḧ";s:3:"Ḩ";s:3:"ḩ";s:3:"Ḫ";s:3:"ḫ";s:3:"Ḭ";s:3:"ḭ";s:3:"Ḯ";s:3:"ḯ";s:3:"Ḱ";s:3:"ḱ";s:3:"Ḳ";s:3:"ḳ";s:3:"Ḵ";s:3:"ḵ";s:3:"Ḷ";s:3:"ḷ";s:3:"Ḹ";s:3:"ḹ";s:3:"Ḻ";s:3:"ḻ";s:3:"Ḽ";s:3:"ḽ";s:3:"Ḿ";s:3:"ḿ";s:3:"á¹€";s:3:"á¹";s:3:"Ṃ";s:3:"ṃ";s:3:"Ṅ";s:3:"á¹…";s:3:"Ṇ";s:3:"ṇ";s:3:"Ṉ";s:3:"ṉ";s:3:"Ṋ";s:3:"ṋ";s:3:"Ṍ";s:3:"á¹";s:3:"Ṏ";s:3:"á¹";s:3:"á¹";s:3:"ṑ";s:3:"á¹’";s:3:"ṓ";s:3:"á¹”";s:3:"ṕ";s:3:"á¹–";s:3:"á¹—";s:3:"Ṙ";s:3:"á¹™";s:3:"Ṛ";s:3:"á¹›";s:3:"Ṝ";s:3:"á¹";s:3:"Ṟ";s:3:"ṟ";s:3:"á¹ ";s:3:"ṡ";s:3:"á¹¢";s:3:"á¹£";s:3:"Ṥ";s:3:"á¹¥";s:3:"Ṧ";s:3:"á¹§";s:3:"Ṩ";s:3:"ṩ";s:3:"Ṫ";s:3:"ṫ";s:3:"Ṭ";s:3:"á¹­";s:3:"á¹®";s:3:"ṯ";s:3:"á¹°";s:3:"á¹±";s:3:"á¹²";s:3:"á¹³";s:3:"á¹´";s:3:"á¹µ";s:3:"á¹¶";s:3:"á¹·";s:3:"Ṹ";s:3:"á¹¹";s:3:"Ṻ";s:3:"á¹»";s:3:"á¹¼";s:3:"á¹½";s:3:"á¹¾";s:3:"ṿ";s:3:"Ẁ";s:3:"áº";s:3:"Ẃ";s:3:"ẃ";s:3:"Ẅ";s:3:"ẅ";s:3:"Ẇ";s:3:"ẇ";s:3:"Ẉ";s:3:"ẉ";s:3:"Ẋ";s:3:"ẋ";s:3:"Ẍ";s:3:"áº";s:3:"Ẏ";s:3:"áº";s:3:"áº";s:3:"ẑ";s:3:"Ẓ";s:3:"ẓ";s:3:"Ẕ";s:3:"ẕ";s:3:"ẞ";s:2:"ß";s:3:"Ạ";s:3:"ạ";s:3:"Ả";s:3:"ả";s:3:"Ấ";s:3:"ấ";s:3:"Ầ";s:3:"ầ";s:3:"Ẩ";s:3:"ẩ";s:3:"Ẫ";s:3:"ẫ";s:3:"Ậ";s:3:"ậ";s:3:"Ắ";s:3:"ắ";s:3:"Ằ";s:3:"ằ";s:3:"Ẳ";s:3:"ẳ";s:3:"Ẵ";s:3:"ẵ";s:3:"Ặ";s:3:"ặ";s:3:"Ẹ";s:3:"ẹ";s:3:"Ẻ";s:3:"ẻ";s:3:"Ẽ";s:3:"ẽ";s:3:"Ế";s:3:"ế";s:3:"Ề";s:3:"á»";s:3:"Ể";s:3:"ể";s:3:"Ễ";s:3:"á»…";s:3:"Ệ";s:3:"ệ";s:3:"Ỉ";s:3:"ỉ";s:3:"Ị";s:3:"ị";s:3:"Ọ";s:3:"á»";s:3:"Ỏ";s:3:"á»";s:3:"á»";s:3:"ố";s:3:"á»’";s:3:"ồ";s:3:"á»”";s:3:"ổ";s:3:"á»–";s:3:"á»—";s:3:"Ộ";s:3:"á»™";s:3:"Ớ";s:3:"á»›";s:3:"Ờ";s:3:"á»";s:3:"Ở";s:3:"ở";s:3:"á» ";s:3:"ỡ";s:3:"Ợ";s:3:"ợ";s:3:"Ụ";s:3:"ụ";s:3:"Ủ";s:3:"á»§";s:3:"Ứ";s:3:"ứ";s:3:"Ừ";s:3:"ừ";s:3:"Ử";s:3:"á»­";s:3:"á»®";s:3:"ữ";s:3:"á»°";s:3:"á»±";s:3:"Ỳ";s:3:"ỳ";s:3:"á»´";s:3:"ỵ";s:3:"á»¶";s:3:"á»·";s:3:"Ỹ";s:3:"ỹ";s:3:"Ỻ";s:3:"á»»";s:3:"Ỽ";s:3:"ỽ";s:3:"Ỿ";s:3:"ỿ";s:3:"Ἀ";s:3:"á¼€";s:3:"Ἁ";s:3:"á¼";s:3:"Ἂ";s:3:"ἂ";s:3:"Ἃ";s:3:"ἃ";s:3:"Ἄ";s:3:"ἄ";s:3:"á¼";s:3:"á¼…";s:3:"Ἆ";s:3:"ἆ";s:3:"á¼";s:3:"ἇ";s:3:"Ἐ";s:3:"á¼";s:3:"á¼™";s:3:"ἑ";s:3:"Ἒ";s:3:"á¼’";s:3:"á¼›";s:3:"ἓ";s:3:"Ἔ";s:3:"á¼”";s:3:"á¼";s:3:"ἕ";s:3:"Ἠ";s:3:"á¼ ";s:3:"Ἡ";s:3:"ἡ";s:3:"Ἢ";s:3:"á¼¢";s:3:"Ἣ";s:3:"á¼£";s:3:"Ἤ";s:3:"ἤ";s:3:"á¼­";s:3:"á¼¥";s:3:"á¼®";s:3:"ἦ";s:3:"Ἧ";s:3:"á¼§";s:3:"Ἰ";s:3:"á¼°";s:3:"á¼¹";s:3:"á¼±";s:3:"Ἲ";s:3:"á¼²";s:3:"á¼»";s:3:"á¼³";s:3:"á¼¼";s:3:"á¼´";s:3:"á¼½";s:3:"á¼µ";s:3:"á¼¾";s:3:"á¼¶";s:3:"Ἷ";s:3:"á¼·";s:3:"Ὀ";s:3:"á½€";s:3:"Ὁ";s:3:"á½";s:3:"Ὂ";s:3:"ὂ";s:3:"Ὃ";s:3:"ὃ";s:3:"Ὄ";s:3:"ὄ";s:3:"á½";s:3:"á½…";s:3:"á½™";s:3:"ὑ";s:3:"á½›";s:3:"ὓ";s:3:"á½";s:3:"ὕ";s:3:"Ὗ";s:3:"á½—";s:3:"Ὠ";s:3:"á½ ";s:3:"Ὡ";s:3:"ὡ";s:3:"Ὢ";s:3:"á½¢";s:3:"Ὣ";s:3:"á½£";s:3:"Ὤ";s:3:"ὤ";s:3:"á½­";s:3:"á½¥";s:3:"á½®";s:3:"ὦ";s:3:"Ὧ";s:3:"á½§";s:3:"ᾈ";s:3:"á¾€";s:3:"ᾉ";s:3:"á¾";s:3:"ᾊ";s:3:"ᾂ";s:3:"ᾋ";s:3:"ᾃ";s:3:"ᾌ";s:3:"ᾄ";s:3:"á¾";s:3:"á¾…";s:3:"ᾎ";s:3:"ᾆ";s:3:"á¾";s:3:"ᾇ";s:3:"ᾘ";s:3:"á¾";s:3:"á¾™";s:3:"ᾑ";s:3:"ᾚ";s:3:"á¾’";s:3:"á¾›";s:3:"ᾓ";s:3:"ᾜ";s:3:"á¾”";s:3:"á¾";s:3:"ᾕ";s:3:"ᾞ";s:3:"á¾–";s:3:"ᾟ";s:3:"á¾—";s:3:"ᾨ";s:3:"á¾ ";s:3:"ᾩ";s:3:"ᾡ";s:3:"ᾪ";s:3:"á¾¢";s:3:"ᾫ";s:3:"á¾£";s:3:"ᾬ";s:3:"ᾤ";s:3:"á¾­";s:3:"á¾¥";s:3:"á¾®";s:3:"ᾦ";s:3:"ᾯ";s:3:"á¾§";s:3:"Ᾰ";s:3:"á¾°";s:3:"á¾¹";s:3:"á¾±";s:3:"Ὰ";s:3:"á½°";s:3:"á¾»";s:3:"á½±";s:3:"á¾¼";s:3:"á¾³";s:3:"Ὲ";s:3:"á½²";s:3:"Έ";s:3:"á½³";s:3:"Ὴ";s:3:"á½´";s:3:"á¿‹";s:3:"á½µ";s:3:"ῌ";s:3:"ῃ";s:3:"Ῐ";s:3:"á¿";s:3:"á¿™";s:3:"á¿‘";s:3:"Ὶ";s:3:"á½¶";s:3:"á¿›";s:3:"á½·";s:3:"Ῠ";s:3:"á¿ ";s:3:"á¿©";s:3:"á¿¡";s:3:"Ὺ";s:3:"ὺ";s:3:"á¿«";s:3:"á½»";s:3:"Ῥ";s:3:"á¿¥";s:3:"Ὸ";s:3:"ὸ";s:3:"Ό";s:3:"á½¹";s:3:"Ὼ";s:3:"á½¼";s:3:"á¿»";s:3:"á½½";s:3:"ῼ";s:3:"ῳ";s:3:"Ω";s:2:"ω";s:3:"K";s:1:"k";s:3:"â„«";s:2:"Ã¥";s:3:"Ⅎ";s:3:"â…Ž";s:3:"â… ";s:3:"â…°";s:3:"â…¡";s:3:"â…±";s:3:"â…¢";s:3:"â…²";s:3:"â…£";s:3:"â…³";s:3:"â…¤";s:3:"â…´";s:3:"â…¥";s:3:"â…µ";s:3:"â…¦";s:3:"â…¶";s:3:"â…§";s:3:"â…·";s:3:"â…¨";s:3:"â…¸";s:3:"â…©";s:3:"â…¹";s:3:"â…ª";s:3:"â…º";s:3:"â…«";s:3:"â…»";s:3:"â…¬";s:3:"â…¼";s:3:"â…­";s:3:"â…½";s:3:"â…®";s:3:"â…¾";s:3:"â…¯";s:3:"â…¿";s:3:"Ↄ";s:3:"ↄ";s:3:"â’¶";s:3:"â“";s:3:"â’·";s:3:"â“‘";s:3:"â’¸";s:3:"â“’";s:3:"â’¹";s:3:"â““";s:3:"â’º";s:3:"â“”";s:3:"â’»";s:3:"â“•";s:3:"â’¼";s:3:"â“–";s:3:"â’½";s:3:"â“—";s:3:"â’¾";s:3:"ⓘ";s:3:"â’¿";s:3:"â“™";s:3:"â“€";s:3:"ⓚ";s:3:"â“";s:3:"â“›";s:3:"â“‚";s:3:"ⓜ";s:3:"Ⓝ";s:3:"â“";s:3:"â“„";s:3:"ⓞ";s:3:"â“…";s:3:"ⓟ";s:3:"Ⓠ";s:3:"â“ ";s:3:"Ⓡ";s:3:"â“¡";s:3:"Ⓢ";s:3:"â“¢";s:3:"Ⓣ";s:3:"â“£";s:3:"Ⓤ";s:3:"ⓤ";s:3:"â“‹";s:3:"â“¥";s:3:"Ⓦ";s:3:"ⓦ";s:3:"â“";s:3:"â“§";s:3:"Ⓨ";s:3:"ⓨ";s:3:"â“";s:3:"â“©";s:3:"â°€";s:3:"â°°";s:3:"â°";s:3:"â°±";s:3:"â°‚";s:3:"â°²";s:3:"â°ƒ";s:3:"â°³";s:3:"â°„";s:3:"â°´";s:3:"â°…";s:3:"â°µ";s:3:"â°†";s:3:"â°¶";s:3:"â°‡";s:3:"â°·";s:3:"â°ˆ";s:3:"â°¸";s:3:"â°‰";s:3:"â°¹";s:3:"â°Š";s:3:"â°º";s:3:"â°‹";s:3:"â°»";s:3:"â°Œ";s:3:"â°¼";s:3:"â°";s:3:"â°½";s:3:"â°Ž";s:3:"â°¾";s:3:"â°";s:3:"â°¿";s:3:"â°";s:3:"â±€";s:3:"â°‘";s:3:"â±";s:3:"â°’";s:3:"ⱂ";s:3:"â°“";s:3:"ⱃ";s:3:"â°”";s:3:"ⱄ";s:3:"â°•";s:3:"â±…";s:3:"â°–";s:3:"ⱆ";s:3:"â°—";s:3:"ⱇ";s:3:"â°˜";s:3:"ⱈ";s:3:"â°™";s:3:"ⱉ";s:3:"â°š";s:3:"ⱊ";s:3:"â°›";s:3:"ⱋ";s:3:"â°œ";s:3:"ⱌ";s:3:"â°";s:3:"â±";s:3:"â°ž";s:3:"ⱎ";s:3:"â°Ÿ";s:3:"â±";s:3:"â° ";s:3:"â±";s:3:"â°¡";s:3:"ⱑ";s:3:"â°¢";s:3:"â±’";s:3:"â°£";s:3:"ⱓ";s:3:"â°¤";s:3:"â±”";s:3:"â°¥";s:3:"ⱕ";s:3:"â°¦";s:3:"â±–";s:3:"â°§";s:3:"â±—";s:3:"â°¨";s:3:"ⱘ";s:3:"â°©";s:3:"â±™";s:3:"â°ª";s:3:"ⱚ";s:3:"â°«";s:3:"â±›";s:3:"â°¬";s:3:"ⱜ";s:3:"â°­";s:3:"â±";s:3:"â°®";s:3:"ⱞ";s:3:"â± ";s:3:"ⱡ";s:3:"â±¢";s:2:"É«";s:3:"â±£";s:3:"áµ½";s:3:"Ɽ";s:2:"ɽ";s:3:"â±§";s:3:"ⱨ";s:3:"Ⱪ";s:3:"ⱪ";s:3:"Ⱬ";s:3:"ⱬ";s:3:"â±­";s:2:"É‘";s:3:"â±®";s:2:"ɱ";s:3:"Ɐ";s:2:"É";s:3:"â±°";s:2:"É’";s:3:"â±²";s:3:"â±³";s:3:"â±µ";s:3:"â±¶";s:3:"â±¾";s:2:"È¿";s:3:"Ɀ";s:2:"É€";s:3:"â²€";s:3:"â²";s:3:"Ⲃ";s:3:"ⲃ";s:3:"Ⲅ";s:3:"â²…";s:3:"Ⲇ";s:3:"ⲇ";s:3:"Ⲉ";s:3:"ⲉ";s:3:"Ⲋ";s:3:"ⲋ";s:3:"Ⲍ";s:3:"â²";s:3:"Ⲏ";s:3:"â²";s:3:"â²";s:3:"ⲑ";s:3:"â²’";s:3:"ⲓ";s:3:"â²”";s:3:"ⲕ";s:3:"â²–";s:3:"â²—";s:3:"Ⲙ";s:3:"â²™";s:3:"Ⲛ";s:3:"â²›";s:3:"Ⲝ";s:3:"â²";s:3:"Ⲟ";s:3:"ⲟ";s:3:"â² ";s:3:"ⲡ";s:3:"â²¢";s:3:"â²£";s:3:"Ⲥ";s:3:"â²¥";s:3:"Ⲧ";s:3:"â²§";s:3:"Ⲩ";s:3:"ⲩ";s:3:"Ⲫ";s:3:"ⲫ";s:3:"Ⲭ";s:3:"â²­";s:3:"â²®";s:3:"ⲯ";s:3:"â²°";s:3:"â²±";s:3:"â²²";s:3:"â²³";s:3:"â²´";s:3:"â²µ";s:3:"â²¶";s:3:"â²·";s:3:"Ⲹ";s:3:"â²¹";s:3:"Ⲻ";s:3:"â²»";s:3:"â²¼";s:3:"â²½";s:3:"â²¾";s:3:"ⲿ";s:3:"â³€";s:3:"â³";s:3:"Ⳃ";s:3:"ⳃ";s:3:"Ⳅ";s:3:"â³…";s:3:"Ⳇ";s:3:"ⳇ";s:3:"Ⳉ";s:3:"ⳉ";s:3:"Ⳋ";s:3:"ⳋ";s:3:"Ⳍ";s:3:"â³";s:3:"Ⳏ";s:3:"â³";s:3:"â³";s:3:"ⳑ";s:3:"â³’";s:3:"ⳓ";s:3:"â³”";s:3:"ⳕ";s:3:"â³–";s:3:"â³—";s:3:"Ⳙ";s:3:"â³™";s:3:"Ⳛ";s:3:"â³›";s:3:"Ⳝ";s:3:"â³";s:3:"Ⳟ";s:3:"ⳟ";s:3:"â³ ";s:3:"ⳡ";s:3:"â³¢";s:3:"â³£";s:3:"Ⳬ";s:3:"ⳬ";s:3:"â³­";s:3:"â³®";s:3:"â³²";s:3:"â³³";s:3:"Ꙁ";s:3:"ê™";s:3:"Ꙃ";s:3:"ꙃ";s:3:"Ꙅ";s:3:"ê™…";s:3:"Ꙇ";s:3:"ꙇ";s:3:"Ꙉ";s:3:"ꙉ";s:3:"Ꙋ";s:3:"ꙋ";s:3:"Ꙍ";s:3:"ê™";s:3:"Ꙏ";s:3:"ê™";s:3:"ê™";s:3:"ꙑ";s:3:"ê™’";s:3:"ꙓ";s:3:"ê™”";s:3:"ꙕ";s:3:"ê™–";s:3:"ê™—";s:3:"Ꙙ";s:3:"ê™™";s:3:"Ꙛ";s:3:"ê™›";s:3:"Ꙝ";s:3:"ê™";s:3:"Ꙟ";s:3:"ꙟ";s:3:"ê™ ";s:3:"ꙡ";s:3:"Ꙣ";s:3:"ꙣ";s:3:"Ꙥ";s:3:"ꙥ";s:3:"Ꙧ";s:3:"ê™§";s:3:"Ꙩ";s:3:"ꙩ";s:3:"Ꙫ";s:3:"ꙫ";s:3:"Ꙭ";s:3:"ê™­";s:3:"Ꚁ";s:3:"êš";s:3:"êš‚";s:3:"ꚃ";s:3:"êš„";s:3:"êš…";s:3:"Ꚇ";s:3:"ꚇ";s:3:"Ꚉ";s:3:"ꚉ";s:3:"Ꚋ";s:3:"êš‹";s:3:"Ꚍ";s:3:"êš";s:3:"Ꚏ";s:3:"êš";s:3:"êš";s:3:"êš‘";s:3:"êš’";s:3:"êš“";s:3:"êš”";s:3:"êš•";s:3:"êš–";s:3:"êš—";s:3:"Ꚙ";s:3:"êš™";s:3:"êšš";s:3:"êš›";s:3:"Ꜣ";s:3:"ꜣ";s:3:"Ꜥ";s:3:"ꜥ";s:3:"Ꜧ";s:3:"ꜧ";s:3:"Ꜩ";s:3:"ꜩ";s:3:"Ꜫ";s:3:"ꜫ";s:3:"Ꜭ";s:3:"ꜭ";s:3:"Ꜯ";s:3:"ꜯ";s:3:"Ꜳ";s:3:"ꜳ";s:3:"Ꜵ";s:3:"ꜵ";s:3:"Ꜷ";s:3:"ꜷ";s:3:"Ꜹ";s:3:"ꜹ";s:3:"Ꜻ";s:3:"ꜻ";s:3:"Ꜽ";s:3:"ꜽ";s:3:"Ꜿ";s:3:"ꜿ";s:3:"ê€";s:3:"ê";s:3:"ê‚";s:3:"êƒ";s:3:"ê„";s:3:"ê…";s:3:"ê†";s:3:"ê‡";s:3:"êˆ";s:3:"ê‰";s:3:"êŠ";s:3:"ê‹";s:3:"êŒ";s:3:"ê";s:3:"êŽ";s:3:"ê";s:3:"ê";s:3:"ê‘";s:3:"ê’";s:3:"ê“";s:3:"ê”";s:3:"ê•";s:3:"ê–";s:3:"ê—";s:3:"ê˜";s:3:"ê™";s:3:"êš";s:3:"ê›";s:3:"êœ";s:3:"ê";s:3:"êž";s:3:"êŸ";s:3:"ê ";s:3:"ê¡";s:3:"ê¢";s:3:"ê£";s:3:"ê¤";s:3:"ê¥";s:3:"ê¦";s:3:"ê§";s:3:"ê¨";s:3:"ê©";s:3:"êª";s:3:"ê«";s:3:"ê¬";s:3:"ê­";s:3:"ê®";s:3:"ê¯";s:3:"ê¹";s:3:"êº";s:3:"ê»";s:3:"ê¼";s:3:"ê½";s:3:"áµ¹";s:3:"ê¾";s:3:"ê¿";s:3:"Ꞁ";s:3:"êž";s:3:"êž‚";s:3:"ꞃ";s:3:"êž„";s:3:"êž…";s:3:"Ꞇ";s:3:"ꞇ";s:3:"êž‹";s:3:"ꞌ";s:3:"êž";s:2:"É¥";s:3:"êž";s:3:"êž‘";s:3:"êž’";s:3:"êž“";s:3:"êž–";s:3:"êž—";s:3:"Ꞙ";s:3:"êž™";s:3:"êžš";s:3:"êž›";s:3:"êžœ";s:3:"êž";s:3:"êžž";s:3:"ꞟ";s:3:"êž ";s:3:"êž¡";s:3:"Ꞣ";s:3:"ꞣ";s:3:"Ꞥ";s:3:"ꞥ";s:3:"Ꞧ";s:3:"êž§";s:3:"Ꞩ";s:3:"êž©";s:3:"Ɦ";s:2:"ɦ";s:3:"êž«";s:2:"Éœ";s:3:"Ɡ";s:2:"É¡";s:3:"êž­";s:2:"ɬ";s:3:"êž°";s:2:"Êž";s:3:"êž±";s:2:"ʇ";s:3:"A";s:3:"ï½";s:3:"ï¼¢";s:3:"b";s:3:"ï¼£";s:3:"c";s:3:"D";s:3:"d";s:3:"ï¼¥";s:3:"ï½…";s:3:"F";s:3:"f";s:3:"ï¼§";s:3:"g";s:3:"H";s:3:"h";s:3:"I";s:3:"i";s:3:"J";s:3:"j";s:3:"K";s:3:"k";s:3:"L";s:3:"l";s:3:"ï¼­";s:3:"ï½";s:3:"ï¼®";s:3:"n";s:3:"O";s:3:"ï½";s:3:"ï¼°";s:3:"ï½";s:3:"ï¼±";s:3:"q";s:3:"ï¼²";s:3:"ï½’";s:3:"ï¼³";s:3:"s";s:3:"ï¼´";s:3:"ï½”";s:3:"ï¼µ";s:3:"u";s:3:"ï¼¶";s:3:"ï½–";s:3:"ï¼·";s:3:"ï½—";s:3:"X";s:3:"x";s:3:"ï¼¹";s:3:"ï½™";s:3:"Z";s:3:"z";s:4:"ð€";s:4:"ð¨";s:4:"ð";s:4:"ð©";s:4:"ð‚";s:4:"ðª";s:4:"ðƒ";s:4:"ð«";s:4:"ð„";s:4:"ð¬";s:4:"ð…";s:4:"ð­";s:4:"ð†";s:4:"ð®";s:4:"ð‡";s:4:"ð¯";s:4:"ðˆ";s:4:"ð°";s:4:"ð‰";s:4:"ð±";s:4:"ðŠ";s:4:"ð²";s:4:"ð‹";s:4:"ð³";s:4:"ðŒ";s:4:"ð´";s:4:"ð";s:4:"ðµ";s:4:"ðŽ";s:4:"ð¶";s:4:"ð";s:4:"ð·";s:4:"ð";s:4:"ð¸";s:4:"ð‘";s:4:"ð¹";s:4:"ð’";s:4:"ðº";s:4:"ð“";s:4:"ð»";s:4:"ð”";s:4:"ð¼";s:4:"ð•";s:4:"ð½";s:4:"ð–";s:4:"ð¾";s:4:"ð—";s:4:"ð¿";s:4:"ð˜";s:4:"ð‘€";s:4:"ð™";s:4:"ð‘";s:4:"ðš";s:4:"ð‘‚";s:4:"ð›";s:4:"ð‘ƒ";s:4:"ðœ";s:4:"ð‘„";s:4:"ð";s:4:"ð‘…";s:4:"ðž";s:4:"ð‘†";s:4:"ðŸ";s:4:"ð‘‡";s:4:"ð ";s:4:"ð‘ˆ";s:4:"ð¡";s:4:"ð‘‰";s:4:"ð¢";s:4:"ð‘Š";s:4:"ð£";s:4:"ð‘‹";s:4:"ð¤";s:4:"ð‘Œ";s:4:"ð¥";s:4:"ð‘";s:4:"ð¦";s:4:"ð‘Ž";s:4:"ð§";s:4:"ð‘";s:4:"ð‘¢ ";s:4:"ð‘£€";s:4:"𑢡";s:4:"ð‘£";s:4:"ð‘¢¢";s:4:"𑣂";s:4:"ð‘¢£";s:4:"𑣃";s:4:"𑢤";s:4:"𑣄";s:4:"ð‘¢¥";s:4:"ð‘£…";s:4:"𑢦";s:4:"𑣆";s:4:"ð‘¢§";s:4:"𑣇";s:4:"𑢨";s:4:"𑣈";s:4:"𑢩";s:4:"𑣉";s:4:"𑢪";s:4:"𑣊";s:4:"𑢫";s:4:"𑣋";s:4:"𑢬";s:4:"𑣌";s:4:"ð‘¢­";s:4:"ð‘£";s:4:"ð‘¢®";s:4:"𑣎";s:4:"𑢯";s:4:"ð‘£";s:4:"ð‘¢°";s:4:"ð‘£";s:4:"ð‘¢±";s:4:"𑣑";s:4:"ð‘¢²";s:4:"ð‘£’";s:4:"ð‘¢³";s:4:"𑣓";s:4:"ð‘¢´";s:4:"ð‘£”";s:4:"ð‘¢µ";s:4:"𑣕";s:4:"ð‘¢¶";s:4:"ð‘£–";s:4:"ð‘¢·";s:4:"ð‘£—";s:4:"𑢸";s:4:"𑣘";s:4:"ð‘¢¹";s:4:"ð‘£™";s:4:"𑢺";s:4:"𑣚";s:4:"ð‘¢»";s:4:"ð‘£›";s:4:"ð‘¢¼";s:4:"𑣜";s:4:"ð‘¢½";s:4:"ð‘£";s:4:"ð‘¢¾";s:4:"𑣞";s:4:"𑢿";s:4:"𑣟";} \ No newline at end of file diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.ser b/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.ser deleted file mode 100644 index e9e0ec2d..00000000 --- a/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.ser +++ /dev/null @@ -1 +0,0 @@ -a:1100:{s:1:"a";s:1:"A";s:1:"b";s:1:"B";s:1:"c";s:1:"C";s:1:"d";s:1:"D";s:1:"e";s:1:"E";s:1:"f";s:1:"F";s:1:"g";s:1:"G";s:1:"h";s:1:"H";s:1:"i";s:1:"I";s:1:"j";s:1:"J";s:1:"k";s:1:"K";s:1:"l";s:1:"L";s:1:"m";s:1:"M";s:1:"n";s:1:"N";s:1:"o";s:1:"O";s:1:"p";s:1:"P";s:1:"q";s:1:"Q";s:1:"r";s:1:"R";s:1:"s";s:1:"S";s:1:"t";s:1:"T";s:1:"u";s:1:"U";s:1:"v";s:1:"V";s:1:"w";s:1:"W";s:1:"x";s:1:"X";s:1:"y";s:1:"Y";s:1:"z";s:1:"Z";s:2:"µ";s:2:"Μ";s:2:"à";s:2:"À";s:2:"á";s:2:"Ã";s:2:"â";s:2:"Â";s:2:"ã";s:2:"Ã";s:2:"ä";s:2:"Ä";s:2:"Ã¥";s:2:"Ã…";s:2:"æ";s:2:"Æ";s:2:"ç";s:2:"Ç";s:2:"è";s:2:"È";s:2:"é";s:2:"É";s:2:"ê";s:2:"Ê";s:2:"ë";s:2:"Ë";s:2:"ì";s:2:"ÃŒ";s:2:"í";s:2:"Ã";s:2:"î";s:2:"ÃŽ";s:2:"ï";s:2:"Ã";s:2:"ð";s:2:"Ã";s:2:"ñ";s:2:"Ñ";s:2:"ò";s:2:"Ã’";s:2:"ó";s:2:"Ó";s:2:"ô";s:2:"Ô";s:2:"õ";s:2:"Õ";s:2:"ö";s:2:"Ö";s:2:"ø";s:2:"Ø";s:2:"ù";s:2:"Ù";s:2:"ú";s:2:"Ú";s:2:"û";s:2:"Û";s:2:"ü";s:2:"Ü";s:2:"ý";s:2:"Ã";s:2:"þ";s:2:"Þ";s:2:"ÿ";s:2:"Ÿ";s:2:"Ä";s:2:"Ä€";s:2:"ă";s:2:"Ä‚";s:2:"Ä…";s:2:"Ä„";s:2:"ć";s:2:"Ć";s:2:"ĉ";s:2:"Ĉ";s:2:"Ä‹";s:2:"ÄŠ";s:2:"Ä";s:2:"ÄŒ";s:2:"Ä";s:2:"ÄŽ";s:2:"Ä‘";s:2:"Ä";s:2:"Ä“";s:2:"Ä’";s:2:"Ä•";s:2:"Ä”";s:2:"Ä—";s:2:"Ä–";s:2:"Ä™";s:2:"Ę";s:2:"Ä›";s:2:"Äš";s:2:"Ä";s:2:"Äœ";s:2:"ÄŸ";s:2:"Äž";s:2:"Ä¡";s:2:"Ä ";s:2:"Ä£";s:2:"Ä¢";s:2:"Ä¥";s:2:"Ĥ";s:2:"ħ";s:2:"Ħ";s:2:"Ä©";s:2:"Ĩ";s:2:"Ä«";s:2:"Ī";s:2:"Ä­";s:2:"Ĭ";s:2:"į";s:2:"Ä®";s:2:"ı";s:1:"I";s:2:"ij";s:2:"IJ";s:2:"ĵ";s:2:"Ä´";s:2:"Ä·";s:2:"Ķ";s:2:"ĺ";s:2:"Ĺ";s:2:"ļ";s:2:"Ä»";s:2:"ľ";s:2:"Ľ";s:2:"Å€";s:2:"Ä¿";s:2:"Å‚";s:2:"Å";s:2:"Å„";s:2:"Ń";s:2:"ņ";s:2:"Å…";s:2:"ň";s:2:"Ň";s:2:"Å‹";s:2:"ÅŠ";s:2:"Å";s:2:"ÅŒ";s:2:"Å";s:2:"ÅŽ";s:2:"Å‘";s:2:"Å";s:2:"Å“";s:2:"Å’";s:2:"Å•";s:2:"Å”";s:2:"Å—";s:2:"Å–";s:2:"Å™";s:2:"Ř";s:2:"Å›";s:2:"Åš";s:2:"Å";s:2:"Åœ";s:2:"ÅŸ";s:2:"Åž";s:2:"Å¡";s:2:"Å ";s:2:"Å£";s:2:"Å¢";s:2:"Å¥";s:2:"Ť";s:2:"ŧ";s:2:"Ŧ";s:2:"Å©";s:2:"Ũ";s:2:"Å«";s:2:"Ū";s:2:"Å­";s:2:"Ŭ";s:2:"ů";s:2:"Å®";s:2:"ű";s:2:"Ű";s:2:"ų";s:2:"Ų";s:2:"ŵ";s:2:"Å´";s:2:"Å·";s:2:"Ŷ";s:2:"ź";s:2:"Ź";s:2:"ż";s:2:"Å»";s:2:"ž";s:2:"Ž";s:2:"Å¿";s:1:"S";s:2:"Æ€";s:2:"Ƀ";s:2:"ƃ";s:2:"Æ‚";s:2:"Æ…";s:2:"Æ„";s:2:"ƈ";s:2:"Ƈ";s:2:"ÆŒ";s:2:"Æ‹";s:2:"Æ’";s:2:"Æ‘";s:2:"Æ•";s:2:"Ƕ";s:2:"Æ™";s:2:"Ƙ";s:2:"Æš";s:2:"Ƚ";s:2:"Æž";s:2:"È ";s:2:"Æ¡";s:2:"Æ ";s:2:"Æ£";s:2:"Æ¢";s:2:"Æ¥";s:2:"Ƥ";s:2:"ƨ";s:2:"Ƨ";s:2:"Æ­";s:2:"Ƭ";s:2:"ư";s:2:"Ư";s:2:"Æ´";s:2:"Ƴ";s:2:"ƶ";s:2:"Ƶ";s:2:"ƹ";s:2:"Ƹ";s:2:"ƽ";s:2:"Ƽ";s:2:"Æ¿";s:2:"Ç·";s:2:"Ç…";s:2:"Ç„";s:2:"dž";s:2:"Ç„";s:2:"Lj";s:2:"LJ";s:2:"lj";s:2:"LJ";s:2:"Ç‹";s:2:"ÇŠ";s:2:"ÇŒ";s:2:"ÇŠ";s:2:"ÇŽ";s:2:"Ç";s:2:"Ç";s:2:"Ç";s:2:"Ç’";s:2:"Ç‘";s:2:"Ç”";s:2:"Ç“";s:2:"Ç–";s:2:"Ç•";s:2:"ǘ";s:2:"Ç—";s:2:"Çš";s:2:"Ç™";s:2:"Çœ";s:2:"Ç›";s:2:"Ç";s:2:"ÆŽ";s:2:"ÇŸ";s:2:"Çž";s:2:"Ç¡";s:2:"Ç ";s:2:"Ç£";s:2:"Ç¢";s:2:"Ç¥";s:2:"Ǥ";s:2:"ǧ";s:2:"Ǧ";s:2:"Ç©";s:2:"Ǩ";s:2:"Ç«";s:2:"Ǫ";s:2:"Ç­";s:2:"Ǭ";s:2:"ǯ";s:2:"Ç®";s:2:"Dz";s:2:"DZ";s:2:"dz";s:2:"DZ";s:2:"ǵ";s:2:"Ç´";s:2:"ǹ";s:2:"Ǹ";s:2:"Ç»";s:2:"Ǻ";s:2:"ǽ";s:2:"Ǽ";s:2:"Ç¿";s:2:"Ǿ";s:2:"È";s:2:"È€";s:2:"ȃ";s:2:"È‚";s:2:"È…";s:2:"È„";s:2:"ȇ";s:2:"Ȇ";s:2:"ȉ";s:2:"Ȉ";s:2:"È‹";s:2:"ÈŠ";s:2:"È";s:2:"ÈŒ";s:2:"È";s:2:"ÈŽ";s:2:"È‘";s:2:"È";s:2:"È“";s:2:"È’";s:2:"È•";s:2:"È”";s:2:"È—";s:2:"È–";s:2:"È™";s:2:"Ș";s:2:"È›";s:2:"Èš";s:2:"È";s:2:"Èœ";s:2:"ÈŸ";s:2:"Èž";s:2:"È£";s:2:"È¢";s:2:"È¥";s:2:"Ȥ";s:2:"ȧ";s:2:"Ȧ";s:2:"È©";s:2:"Ȩ";s:2:"È«";s:2:"Ȫ";s:2:"È­";s:2:"Ȭ";s:2:"ȯ";s:2:"È®";s:2:"ȱ";s:2:"Ȱ";s:2:"ȳ";s:2:"Ȳ";s:2:"ȼ";s:2:"È»";s:2:"È¿";s:3:"â±¾";s:2:"É€";s:3:"Ɀ";s:2:"É‚";s:2:"É";s:2:"ɇ";s:2:"Ɇ";s:2:"ɉ";s:2:"Ɉ";s:2:"É‹";s:2:"ÉŠ";s:2:"É";s:2:"ÉŒ";s:2:"É";s:2:"ÉŽ";s:2:"É";s:3:"Ɐ";s:2:"É‘";s:3:"â±­";s:2:"É’";s:3:"â±°";s:2:"É“";s:2:"Æ";s:2:"É”";s:2:"Ɔ";s:2:"É–";s:2:"Ɖ";s:2:"É—";s:2:"ÆŠ";s:2:"É™";s:2:"Æ";s:2:"É›";s:2:"Æ";s:2:"Éœ";s:3:"êž«";s:2:"É ";s:2:"Æ“";s:2:"É¡";s:3:"Ɡ";s:2:"É£";s:2:"Æ”";s:2:"É¥";s:3:"êž";s:2:"ɦ";s:3:"Ɦ";s:2:"ɨ";s:2:"Æ—";s:2:"É©";s:2:"Æ–";s:2:"É«";s:3:"â±¢";s:2:"ɬ";s:3:"êž­";s:2:"ɯ";s:2:"Æœ";s:2:"ɱ";s:3:"â±®";s:2:"ɲ";s:2:"Æ";s:2:"ɵ";s:2:"ÆŸ";s:2:"ɽ";s:3:"Ɽ";s:2:"Ê€";s:2:"Ʀ";s:2:"ʃ";s:2:"Æ©";s:2:"ʇ";s:3:"êž±";s:2:"ʈ";s:2:"Æ®";s:2:"ʉ";s:2:"É„";s:2:"ÊŠ";s:2:"Ʊ";s:2:"Ê‹";s:2:"Ʋ";s:2:"ÊŒ";s:2:"É…";s:2:"Ê’";s:2:"Æ·";s:2:"Êž";s:3:"êž°";s:2:"Í…";s:2:"Ι";s:2:"ͱ";s:2:"Ͱ";s:2:"ͳ";s:2:"Ͳ";s:2:"Í·";s:2:"Ͷ";s:2:"Í»";s:2:"Ͻ";s:2:"ͼ";s:2:"Ͼ";s:2:"ͽ";s:2:"Ï¿";s:2:"ά";s:2:"Ά";s:2:"έ";s:2:"Έ";s:2:"ή";s:2:"Ή";s:2:"ί";s:2:"Ί";s:2:"α";s:2:"Α";s:2:"β";s:2:"Î’";s:2:"γ";s:2:"Γ";s:2:"δ";s:2:"Δ";s:2:"ε";s:2:"Ε";s:2:"ζ";s:2:"Ζ";s:2:"η";s:2:"Η";s:2:"θ";s:2:"Θ";s:2:"ι";s:2:"Ι";s:2:"κ";s:2:"Κ";s:2:"λ";s:2:"Λ";s:2:"μ";s:2:"Μ";s:2:"ν";s:2:"Î";s:2:"ξ";s:2:"Ξ";s:2:"ο";s:2:"Ο";s:2:"Ï€";s:2:"Π";s:2:"Ï";s:2:"Ρ";s:2:"Ï‚";s:2:"Σ";s:2:"σ";s:2:"Σ";s:2:"Ï„";s:2:"Τ";s:2:"Ï…";s:2:"Î¥";s:2:"φ";s:2:"Φ";s:2:"χ";s:2:"Χ";s:2:"ψ";s:2:"Ψ";s:2:"ω";s:2:"Ω";s:2:"ÏŠ";s:2:"Ϊ";s:2:"Ï‹";s:2:"Ϋ";s:2:"ÏŒ";s:2:"ÎŒ";s:2:"Ï";s:2:"ÎŽ";s:2:"ÏŽ";s:2:"Î";s:2:"Ï";s:2:"Î’";s:2:"Ï‘";s:2:"Θ";s:2:"Ï•";s:2:"Φ";s:2:"Ï–";s:2:"Π";s:2:"Ï—";s:2:"Ï";s:2:"Ï™";s:2:"Ϙ";s:2:"Ï›";s:2:"Ïš";s:2:"Ï";s:2:"Ïœ";s:2:"ÏŸ";s:2:"Ïž";s:2:"Ï¡";s:2:"Ï ";s:2:"Ï£";s:2:"Ï¢";s:2:"Ï¥";s:2:"Ϥ";s:2:"ϧ";s:2:"Ϧ";s:2:"Ï©";s:2:"Ϩ";s:2:"Ï«";s:2:"Ϫ";s:2:"Ï­";s:2:"Ϭ";s:2:"ϯ";s:2:"Ï®";s:2:"ϰ";s:2:"Κ";s:2:"ϱ";s:2:"Ρ";s:2:"ϲ";s:2:"Ϲ";s:2:"ϳ";s:2:"Í¿";s:2:"ϵ";s:2:"Ε";s:2:"ϸ";s:2:"Ï·";s:2:"Ï»";s:2:"Ϻ";s:2:"а";s:2:"Ð";s:2:"б";s:2:"Б";s:2:"в";s:2:"Ð’";s:2:"г";s:2:"Г";s:2:"д";s:2:"Д";s:2:"е";s:2:"Е";s:2:"ж";s:2:"Ж";s:2:"з";s:2:"З";s:2:"и";s:2:"И";s:2:"й";s:2:"Й";s:2:"к";s:2:"К";s:2:"л";s:2:"Л";s:2:"м";s:2:"М";s:2:"н";s:2:"Ð";s:2:"о";s:2:"О";s:2:"п";s:2:"П";s:2:"Ñ€";s:2:"Р";s:2:"Ñ";s:2:"С";s:2:"Ñ‚";s:2:"Т";s:2:"у";s:2:"У";s:2:"Ñ„";s:2:"Ф";s:2:"Ñ…";s:2:"Ð¥";s:2:"ц";s:2:"Ц";s:2:"ч";s:2:"Ч";s:2:"ш";s:2:"Ш";s:2:"щ";s:2:"Щ";s:2:"ÑŠ";s:2:"Ъ";s:2:"Ñ‹";s:2:"Ы";s:2:"ÑŒ";s:2:"Ь";s:2:"Ñ";s:2:"Э";s:2:"ÑŽ";s:2:"Ю";s:2:"Ñ";s:2:"Я";s:2:"Ñ";s:2:"Ѐ";s:2:"Ñ‘";s:2:"Ð";s:2:"Ñ’";s:2:"Ђ";s:2:"Ñ“";s:2:"Ѓ";s:2:"Ñ”";s:2:"Є";s:2:"Ñ•";s:2:"Ð…";s:2:"Ñ–";s:2:"І";s:2:"Ñ—";s:2:"Ї";s:2:"ј";s:2:"Ј";s:2:"Ñ™";s:2:"Љ";s:2:"Ñš";s:2:"Њ";s:2:"Ñ›";s:2:"Ћ";s:2:"Ñœ";s:2:"ÐŒ";s:2:"Ñ";s:2:"Ð";s:2:"Ñž";s:2:"ÐŽ";s:2:"ÑŸ";s:2:"Ð";s:2:"Ñ¡";s:2:"Ñ ";s:2:"Ñ£";s:2:"Ñ¢";s:2:"Ñ¥";s:2:"Ѥ";s:2:"ѧ";s:2:"Ѧ";s:2:"Ñ©";s:2:"Ѩ";s:2:"Ñ«";s:2:"Ѫ";s:2:"Ñ­";s:2:"Ѭ";s:2:"ѯ";s:2:"Ñ®";s:2:"ѱ";s:2:"Ѱ";s:2:"ѳ";s:2:"Ѳ";s:2:"ѵ";s:2:"Ñ´";s:2:"Ñ·";s:2:"Ѷ";s:2:"ѹ";s:2:"Ѹ";s:2:"Ñ»";s:2:"Ѻ";s:2:"ѽ";s:2:"Ѽ";s:2:"Ñ¿";s:2:"Ѿ";s:2:"Ò";s:2:"Ò€";s:2:"Ò‹";s:2:"ÒŠ";s:2:"Ò";s:2:"ÒŒ";s:2:"Ò";s:2:"ÒŽ";s:2:"Ò‘";s:2:"Ò";s:2:"Ò“";s:2:"Ò’";s:2:"Ò•";s:2:"Ò”";s:2:"Ò—";s:2:"Ò–";s:2:"Ò™";s:2:"Ò˜";s:2:"Ò›";s:2:"Òš";s:2:"Ò";s:2:"Òœ";s:2:"ÒŸ";s:2:"Òž";s:2:"Ò¡";s:2:"Ò ";s:2:"Ò£";s:2:"Ò¢";s:2:"Ò¥";s:2:"Ò¤";s:2:"Ò§";s:2:"Ò¦";s:2:"Ò©";s:2:"Ò¨";s:2:"Ò«";s:2:"Òª";s:2:"Ò­";s:2:"Ò¬";s:2:"Ò¯";s:2:"Ò®";s:2:"Ò±";s:2:"Ò°";s:2:"Ò³";s:2:"Ò²";s:2:"Òµ";s:2:"Ò´";s:2:"Ò·";s:2:"Ò¶";s:2:"Ò¹";s:2:"Ò¸";s:2:"Ò»";s:2:"Òº";s:2:"Ò½";s:2:"Ò¼";s:2:"Ò¿";s:2:"Ò¾";s:2:"Ó‚";s:2:"Ó";s:2:"Ó„";s:2:"Óƒ";s:2:"Ó†";s:2:"Ó…";s:2:"Óˆ";s:2:"Ó‡";s:2:"ÓŠ";s:2:"Ó‰";s:2:"ÓŒ";s:2:"Ó‹";s:2:"ÓŽ";s:2:"Ó";s:2:"Ó";s:2:"Ó€";s:2:"Ó‘";s:2:"Ó";s:2:"Ó“";s:2:"Ó’";s:2:"Ó•";s:2:"Ó”";s:2:"Ó—";s:2:"Ó–";s:2:"Ó™";s:2:"Ó˜";s:2:"Ó›";s:2:"Óš";s:2:"Ó";s:2:"Óœ";s:2:"ÓŸ";s:2:"Óž";s:2:"Ó¡";s:2:"Ó ";s:2:"Ó£";s:2:"Ó¢";s:2:"Ó¥";s:2:"Ó¤";s:2:"Ó§";s:2:"Ó¦";s:2:"Ó©";s:2:"Ó¨";s:2:"Ó«";s:2:"Óª";s:2:"Ó­";s:2:"Ó¬";s:2:"Ó¯";s:2:"Ó®";s:2:"Ó±";s:2:"Ó°";s:2:"Ó³";s:2:"Ó²";s:2:"Óµ";s:2:"Ó´";s:2:"Ó·";s:2:"Ó¶";s:2:"Ó¹";s:2:"Ó¸";s:2:"Ó»";s:2:"Óº";s:2:"Ó½";s:2:"Ó¼";s:2:"Ó¿";s:2:"Ó¾";s:2:"Ô";s:2:"Ô€";s:2:"Ôƒ";s:2:"Ô‚";s:2:"Ô…";s:2:"Ô„";s:2:"Ô‡";s:2:"Ô†";s:2:"Ô‰";s:2:"Ôˆ";s:2:"Ô‹";s:2:"ÔŠ";s:2:"Ô";s:2:"ÔŒ";s:2:"Ô";s:2:"ÔŽ";s:2:"Ô‘";s:2:"Ô";s:2:"Ô“";s:2:"Ô’";s:2:"Ô•";s:2:"Ô”";s:2:"Ô—";s:2:"Ô–";s:2:"Ô™";s:2:"Ô˜";s:2:"Ô›";s:2:"Ôš";s:2:"Ô";s:2:"Ôœ";s:2:"ÔŸ";s:2:"Ôž";s:2:"Ô¡";s:2:"Ô ";s:2:"Ô£";s:2:"Ô¢";s:2:"Ô¥";s:2:"Ô¤";s:2:"Ô§";s:2:"Ô¦";s:2:"Ô©";s:2:"Ô¨";s:2:"Ô«";s:2:"Ôª";s:2:"Ô­";s:2:"Ô¬";s:2:"Ô¯";s:2:"Ô®";s:2:"Õ¡";s:2:"Ô±";s:2:"Õ¢";s:2:"Ô²";s:2:"Õ£";s:2:"Ô³";s:2:"Õ¤";s:2:"Ô´";s:2:"Õ¥";s:2:"Ôµ";s:2:"Õ¦";s:2:"Ô¶";s:2:"Õ§";s:2:"Ô·";s:2:"Õ¨";s:2:"Ô¸";s:2:"Õ©";s:2:"Ô¹";s:2:"Õª";s:2:"Ôº";s:2:"Õ«";s:2:"Ô»";s:2:"Õ¬";s:2:"Ô¼";s:2:"Õ­";s:2:"Ô½";s:2:"Õ®";s:2:"Ô¾";s:2:"Õ¯";s:2:"Ô¿";s:2:"Õ°";s:2:"Õ€";s:2:"Õ±";s:2:"Õ";s:2:"Õ²";s:2:"Õ‚";s:2:"Õ³";s:2:"Õƒ";s:2:"Õ´";s:2:"Õ„";s:2:"Õµ";s:2:"Õ…";s:2:"Õ¶";s:2:"Õ†";s:2:"Õ·";s:2:"Õ‡";s:2:"Õ¸";s:2:"Õˆ";s:2:"Õ¹";s:2:"Õ‰";s:2:"Õº";s:2:"ÕŠ";s:2:"Õ»";s:2:"Õ‹";s:2:"Õ¼";s:2:"ÕŒ";s:2:"Õ½";s:2:"Õ";s:2:"Õ¾";s:2:"ÕŽ";s:2:"Õ¿";s:2:"Õ";s:2:"Ö€";s:2:"Õ";s:2:"Ö";s:2:"Õ‘";s:2:"Ö‚";s:2:"Õ’";s:2:"Öƒ";s:2:"Õ“";s:2:"Ö„";s:2:"Õ”";s:2:"Ö…";s:2:"Õ•";s:2:"Ö†";s:2:"Õ–";s:3:"áµ¹";s:3:"ê½";s:3:"áµ½";s:3:"â±£";s:3:"á¸";s:3:"Ḁ";s:3:"ḃ";s:3:"Ḃ";s:3:"ḅ";s:3:"Ḅ";s:3:"ḇ";s:3:"Ḇ";s:3:"ḉ";s:3:"Ḉ";s:3:"ḋ";s:3:"Ḋ";s:3:"á¸";s:3:"Ḍ";s:3:"á¸";s:3:"Ḏ";s:3:"ḑ";s:3:"á¸";s:3:"ḓ";s:3:"Ḓ";s:3:"ḕ";s:3:"Ḕ";s:3:"ḗ";s:3:"Ḗ";s:3:"ḙ";s:3:"Ḙ";s:3:"ḛ";s:3:"Ḛ";s:3:"á¸";s:3:"Ḝ";s:3:"ḟ";s:3:"Ḟ";s:3:"ḡ";s:3:"Ḡ";s:3:"ḣ";s:3:"Ḣ";s:3:"ḥ";s:3:"Ḥ";s:3:"ḧ";s:3:"Ḧ";s:3:"ḩ";s:3:"Ḩ";s:3:"ḫ";s:3:"Ḫ";s:3:"ḭ";s:3:"Ḭ";s:3:"ḯ";s:3:"Ḯ";s:3:"ḱ";s:3:"Ḱ";s:3:"ḳ";s:3:"Ḳ";s:3:"ḵ";s:3:"Ḵ";s:3:"ḷ";s:3:"Ḷ";s:3:"ḹ";s:3:"Ḹ";s:3:"ḻ";s:3:"Ḻ";s:3:"ḽ";s:3:"Ḽ";s:3:"ḿ";s:3:"Ḿ";s:3:"á¹";s:3:"á¹€";s:3:"ṃ";s:3:"Ṃ";s:3:"á¹…";s:3:"Ṅ";s:3:"ṇ";s:3:"Ṇ";s:3:"ṉ";s:3:"Ṉ";s:3:"ṋ";s:3:"Ṋ";s:3:"á¹";s:3:"Ṍ";s:3:"á¹";s:3:"Ṏ";s:3:"ṑ";s:3:"á¹";s:3:"ṓ";s:3:"á¹’";s:3:"ṕ";s:3:"á¹”";s:3:"á¹—";s:3:"á¹–";s:3:"á¹™";s:3:"Ṙ";s:3:"á¹›";s:3:"Ṛ";s:3:"á¹";s:3:"Ṝ";s:3:"ṟ";s:3:"Ṟ";s:3:"ṡ";s:3:"á¹ ";s:3:"á¹£";s:3:"á¹¢";s:3:"á¹¥";s:3:"Ṥ";s:3:"á¹§";s:3:"Ṧ";s:3:"ṩ";s:3:"Ṩ";s:3:"ṫ";s:3:"Ṫ";s:3:"á¹­";s:3:"Ṭ";s:3:"ṯ";s:3:"á¹®";s:3:"á¹±";s:3:"á¹°";s:3:"á¹³";s:3:"á¹²";s:3:"á¹µ";s:3:"á¹´";s:3:"á¹·";s:3:"á¹¶";s:3:"á¹¹";s:3:"Ṹ";s:3:"á¹»";s:3:"Ṻ";s:3:"á¹½";s:3:"á¹¼";s:3:"ṿ";s:3:"á¹¾";s:3:"áº";s:3:"Ẁ";s:3:"ẃ";s:3:"Ẃ";s:3:"ẅ";s:3:"Ẅ";s:3:"ẇ";s:3:"Ẇ";s:3:"ẉ";s:3:"Ẉ";s:3:"ẋ";s:3:"Ẋ";s:3:"áº";s:3:"Ẍ";s:3:"áº";s:3:"Ẏ";s:3:"ẑ";s:3:"áº";s:3:"ẓ";s:3:"Ẓ";s:3:"ẕ";s:3:"Ẕ";s:3:"ẛ";s:3:"á¹ ";s:3:"ạ";s:3:"Ạ";s:3:"ả";s:3:"Ả";s:3:"ấ";s:3:"Ấ";s:3:"ầ";s:3:"Ầ";s:3:"ẩ";s:3:"Ẩ";s:3:"ẫ";s:3:"Ẫ";s:3:"ậ";s:3:"Ậ";s:3:"ắ";s:3:"Ắ";s:3:"ằ";s:3:"Ằ";s:3:"ẳ";s:3:"Ẳ";s:3:"ẵ";s:3:"Ẵ";s:3:"ặ";s:3:"Ặ";s:3:"ẹ";s:3:"Ẹ";s:3:"ẻ";s:3:"Ẻ";s:3:"ẽ";s:3:"Ẽ";s:3:"ế";s:3:"Ế";s:3:"á»";s:3:"Ề";s:3:"ể";s:3:"Ể";s:3:"á»…";s:3:"Ễ";s:3:"ệ";s:3:"Ệ";s:3:"ỉ";s:3:"Ỉ";s:3:"ị";s:3:"Ị";s:3:"á»";s:3:"Ọ";s:3:"á»";s:3:"Ỏ";s:3:"ố";s:3:"á»";s:3:"ồ";s:3:"á»’";s:3:"ổ";s:3:"á»”";s:3:"á»—";s:3:"á»–";s:3:"á»™";s:3:"Ộ";s:3:"á»›";s:3:"Ớ";s:3:"á»";s:3:"Ờ";s:3:"ở";s:3:"Ở";s:3:"ỡ";s:3:"á» ";s:3:"ợ";s:3:"Ợ";s:3:"ụ";s:3:"Ụ";s:3:"á»§";s:3:"Ủ";s:3:"ứ";s:3:"Ứ";s:3:"ừ";s:3:"Ừ";s:3:"á»­";s:3:"Ử";s:3:"ữ";s:3:"á»®";s:3:"á»±";s:3:"á»°";s:3:"ỳ";s:3:"Ỳ";s:3:"ỵ";s:3:"á»´";s:3:"á»·";s:3:"á»¶";s:3:"ỹ";s:3:"Ỹ";s:3:"á»»";s:3:"Ỻ";s:3:"ỽ";s:3:"Ỽ";s:3:"ỿ";s:3:"Ỿ";s:3:"á¼€";s:3:"Ἀ";s:3:"á¼";s:3:"Ἁ";s:3:"ἂ";s:3:"Ἂ";s:3:"ἃ";s:3:"Ἃ";s:3:"ἄ";s:3:"Ἄ";s:3:"á¼…";s:3:"á¼";s:3:"ἆ";s:3:"Ἆ";s:3:"ἇ";s:3:"á¼";s:3:"á¼";s:3:"Ἐ";s:3:"ἑ";s:3:"á¼™";s:3:"á¼’";s:3:"Ἒ";s:3:"ἓ";s:3:"á¼›";s:3:"á¼”";s:3:"Ἔ";s:3:"ἕ";s:3:"á¼";s:3:"á¼ ";s:3:"Ἠ";s:3:"ἡ";s:3:"Ἡ";s:3:"á¼¢";s:3:"Ἢ";s:3:"á¼£";s:3:"Ἣ";s:3:"ἤ";s:3:"Ἤ";s:3:"á¼¥";s:3:"á¼­";s:3:"ἦ";s:3:"á¼®";s:3:"á¼§";s:3:"Ἧ";s:3:"á¼°";s:3:"Ἰ";s:3:"á¼±";s:3:"á¼¹";s:3:"á¼²";s:3:"Ἲ";s:3:"á¼³";s:3:"á¼»";s:3:"á¼´";s:3:"á¼¼";s:3:"á¼µ";s:3:"á¼½";s:3:"á¼¶";s:3:"á¼¾";s:3:"á¼·";s:3:"Ἷ";s:3:"á½€";s:3:"Ὀ";s:3:"á½";s:3:"Ὁ";s:3:"ὂ";s:3:"Ὂ";s:3:"ὃ";s:3:"Ὃ";s:3:"ὄ";s:3:"Ὄ";s:3:"á½…";s:3:"á½";s:3:"ὑ";s:3:"á½™";s:3:"ὓ";s:3:"á½›";s:3:"ὕ";s:3:"á½";s:3:"á½—";s:3:"Ὗ";s:3:"á½ ";s:3:"Ὠ";s:3:"ὡ";s:3:"Ὡ";s:3:"á½¢";s:3:"Ὢ";s:3:"á½£";s:3:"Ὣ";s:3:"ὤ";s:3:"Ὤ";s:3:"á½¥";s:3:"á½­";s:3:"ὦ";s:3:"á½®";s:3:"á½§";s:3:"Ὧ";s:3:"á½°";s:3:"Ὰ";s:3:"á½±";s:3:"á¾»";s:3:"á½²";s:3:"Ὲ";s:3:"á½³";s:3:"Έ";s:3:"á½´";s:3:"Ὴ";s:3:"á½µ";s:3:"á¿‹";s:3:"á½¶";s:3:"Ὶ";s:3:"á½·";s:3:"á¿›";s:3:"ὸ";s:3:"Ὸ";s:3:"á½¹";s:3:"Ό";s:3:"ὺ";s:3:"Ὺ";s:3:"á½»";s:3:"á¿«";s:3:"á½¼";s:3:"Ὼ";s:3:"á½½";s:3:"á¿»";s:3:"á¾€";s:3:"ᾈ";s:3:"á¾";s:3:"ᾉ";s:3:"ᾂ";s:3:"ᾊ";s:3:"ᾃ";s:3:"ᾋ";s:3:"ᾄ";s:3:"ᾌ";s:3:"á¾…";s:3:"á¾";s:3:"ᾆ";s:3:"ᾎ";s:3:"ᾇ";s:3:"á¾";s:3:"á¾";s:3:"ᾘ";s:3:"ᾑ";s:3:"á¾™";s:3:"á¾’";s:3:"ᾚ";s:3:"ᾓ";s:3:"á¾›";s:3:"á¾”";s:3:"ᾜ";s:3:"ᾕ";s:3:"á¾";s:3:"á¾–";s:3:"ᾞ";s:3:"á¾—";s:3:"ᾟ";s:3:"á¾ ";s:3:"ᾨ";s:3:"ᾡ";s:3:"ᾩ";s:3:"á¾¢";s:3:"ᾪ";s:3:"á¾£";s:3:"ᾫ";s:3:"ᾤ";s:3:"ᾬ";s:3:"á¾¥";s:3:"á¾­";s:3:"ᾦ";s:3:"á¾®";s:3:"á¾§";s:3:"ᾯ";s:3:"á¾°";s:3:"Ᾰ";s:3:"á¾±";s:3:"á¾¹";s:3:"á¾³";s:3:"á¾¼";s:3:"á¾¾";s:2:"Ι";s:3:"ῃ";s:3:"ῌ";s:3:"á¿";s:3:"Ῐ";s:3:"á¿‘";s:3:"á¿™";s:3:"á¿ ";s:3:"Ῠ";s:3:"á¿¡";s:3:"á¿©";s:3:"á¿¥";s:3:"Ῥ";s:3:"ῳ";s:3:"ῼ";s:3:"â…Ž";s:3:"Ⅎ";s:3:"â…°";s:3:"â… ";s:3:"â…±";s:3:"â…¡";s:3:"â…²";s:3:"â…¢";s:3:"â…³";s:3:"â…£";s:3:"â…´";s:3:"â…¤";s:3:"â…µ";s:3:"â…¥";s:3:"â…¶";s:3:"â…¦";s:3:"â…·";s:3:"â…§";s:3:"â…¸";s:3:"â…¨";s:3:"â…¹";s:3:"â…©";s:3:"â…º";s:3:"â…ª";s:3:"â…»";s:3:"â…«";s:3:"â…¼";s:3:"â…¬";s:3:"â…½";s:3:"â…­";s:3:"â…¾";s:3:"â…®";s:3:"â…¿";s:3:"â…¯";s:3:"ↄ";s:3:"Ↄ";s:3:"â“";s:3:"â’¶";s:3:"â“‘";s:3:"â’·";s:3:"â“’";s:3:"â’¸";s:3:"â““";s:3:"â’¹";s:3:"â“”";s:3:"â’º";s:3:"â“•";s:3:"â’»";s:3:"â“–";s:3:"â’¼";s:3:"â“—";s:3:"â’½";s:3:"ⓘ";s:3:"â’¾";s:3:"â“™";s:3:"â’¿";s:3:"ⓚ";s:3:"â“€";s:3:"â“›";s:3:"â“";s:3:"ⓜ";s:3:"â“‚";s:3:"â“";s:3:"Ⓝ";s:3:"ⓞ";s:3:"â“„";s:3:"ⓟ";s:3:"â“…";s:3:"â“ ";s:3:"Ⓠ";s:3:"â“¡";s:3:"Ⓡ";s:3:"â“¢";s:3:"Ⓢ";s:3:"â“£";s:3:"Ⓣ";s:3:"ⓤ";s:3:"Ⓤ";s:3:"â“¥";s:3:"â“‹";s:3:"ⓦ";s:3:"Ⓦ";s:3:"â“§";s:3:"â“";s:3:"ⓨ";s:3:"Ⓨ";s:3:"â“©";s:3:"â“";s:3:"â°°";s:3:"â°€";s:3:"â°±";s:3:"â°";s:3:"â°²";s:3:"â°‚";s:3:"â°³";s:3:"â°ƒ";s:3:"â°´";s:3:"â°„";s:3:"â°µ";s:3:"â°…";s:3:"â°¶";s:3:"â°†";s:3:"â°·";s:3:"â°‡";s:3:"â°¸";s:3:"â°ˆ";s:3:"â°¹";s:3:"â°‰";s:3:"â°º";s:3:"â°Š";s:3:"â°»";s:3:"â°‹";s:3:"â°¼";s:3:"â°Œ";s:3:"â°½";s:3:"â°";s:3:"â°¾";s:3:"â°Ž";s:3:"â°¿";s:3:"â°";s:3:"â±€";s:3:"â°";s:3:"â±";s:3:"â°‘";s:3:"ⱂ";s:3:"â°’";s:3:"ⱃ";s:3:"â°“";s:3:"ⱄ";s:3:"â°”";s:3:"â±…";s:3:"â°•";s:3:"ⱆ";s:3:"â°–";s:3:"ⱇ";s:3:"â°—";s:3:"ⱈ";s:3:"â°˜";s:3:"ⱉ";s:3:"â°™";s:3:"ⱊ";s:3:"â°š";s:3:"ⱋ";s:3:"â°›";s:3:"ⱌ";s:3:"â°œ";s:3:"â±";s:3:"â°";s:3:"ⱎ";s:3:"â°ž";s:3:"â±";s:3:"â°Ÿ";s:3:"â±";s:3:"â° ";s:3:"ⱑ";s:3:"â°¡";s:3:"â±’";s:3:"â°¢";s:3:"ⱓ";s:3:"â°£";s:3:"â±”";s:3:"â°¤";s:3:"ⱕ";s:3:"â°¥";s:3:"â±–";s:3:"â°¦";s:3:"â±—";s:3:"â°§";s:3:"ⱘ";s:3:"â°¨";s:3:"â±™";s:3:"â°©";s:3:"ⱚ";s:3:"â°ª";s:3:"â±›";s:3:"â°«";s:3:"ⱜ";s:3:"â°¬";s:3:"â±";s:3:"â°­";s:3:"ⱞ";s:3:"â°®";s:3:"ⱡ";s:3:"â± ";s:3:"â±¥";s:2:"Ⱥ";s:3:"ⱦ";s:2:"Ⱦ";s:3:"ⱨ";s:3:"â±§";s:3:"ⱪ";s:3:"Ⱪ";s:3:"ⱬ";s:3:"Ⱬ";s:3:"â±³";s:3:"â±²";s:3:"â±¶";s:3:"â±µ";s:3:"â²";s:3:"â²€";s:3:"ⲃ";s:3:"Ⲃ";s:3:"â²…";s:3:"Ⲅ";s:3:"ⲇ";s:3:"Ⲇ";s:3:"ⲉ";s:3:"Ⲉ";s:3:"ⲋ";s:3:"Ⲋ";s:3:"â²";s:3:"Ⲍ";s:3:"â²";s:3:"Ⲏ";s:3:"ⲑ";s:3:"â²";s:3:"ⲓ";s:3:"â²’";s:3:"ⲕ";s:3:"â²”";s:3:"â²—";s:3:"â²–";s:3:"â²™";s:3:"Ⲙ";s:3:"â²›";s:3:"Ⲛ";s:3:"â²";s:3:"Ⲝ";s:3:"ⲟ";s:3:"Ⲟ";s:3:"ⲡ";s:3:"â² ";s:3:"â²£";s:3:"â²¢";s:3:"â²¥";s:3:"Ⲥ";s:3:"â²§";s:3:"Ⲧ";s:3:"ⲩ";s:3:"Ⲩ";s:3:"ⲫ";s:3:"Ⲫ";s:3:"â²­";s:3:"Ⲭ";s:3:"ⲯ";s:3:"â²®";s:3:"â²±";s:3:"â²°";s:3:"â²³";s:3:"â²²";s:3:"â²µ";s:3:"â²´";s:3:"â²·";s:3:"â²¶";s:3:"â²¹";s:3:"Ⲹ";s:3:"â²»";s:3:"Ⲻ";s:3:"â²½";s:3:"â²¼";s:3:"ⲿ";s:3:"â²¾";s:3:"â³";s:3:"â³€";s:3:"ⳃ";s:3:"Ⳃ";s:3:"â³…";s:3:"Ⳅ";s:3:"ⳇ";s:3:"Ⳇ";s:3:"ⳉ";s:3:"Ⳉ";s:3:"ⳋ";s:3:"Ⳋ";s:3:"â³";s:3:"Ⳍ";s:3:"â³";s:3:"Ⳏ";s:3:"ⳑ";s:3:"â³";s:3:"ⳓ";s:3:"â³’";s:3:"ⳕ";s:3:"â³”";s:3:"â³—";s:3:"â³–";s:3:"â³™";s:3:"Ⳙ";s:3:"â³›";s:3:"Ⳛ";s:3:"â³";s:3:"Ⳝ";s:3:"ⳟ";s:3:"Ⳟ";s:3:"ⳡ";s:3:"â³ ";s:3:"â³£";s:3:"â³¢";s:3:"ⳬ";s:3:"Ⳬ";s:3:"â³®";s:3:"â³­";s:3:"â³³";s:3:"â³²";s:3:"â´€";s:3:"á‚ ";s:3:"â´";s:3:"á‚¡";s:3:"â´‚";s:3:"á‚¢";s:3:"â´ƒ";s:3:"á‚£";s:3:"â´„";s:3:"Ⴄ";s:3:"â´…";s:3:"á‚¥";s:3:"â´†";s:3:"Ⴆ";s:3:"â´‡";s:3:"á‚§";s:3:"â´ˆ";s:3:"Ⴈ";s:3:"â´‰";s:3:"á‚©";s:3:"â´Š";s:3:"Ⴊ";s:3:"â´‹";s:3:"á‚«";s:3:"â´Œ";s:3:"Ⴌ";s:3:"â´";s:3:"á‚­";s:3:"â´Ž";s:3:"á‚®";s:3:"â´";s:3:"Ⴏ";s:3:"â´";s:3:"á‚°";s:3:"â´‘";s:3:"Ⴑ";s:3:"â´’";s:3:"Ⴒ";s:3:"â´“";s:3:"Ⴓ";s:3:"â´”";s:3:"á‚´";s:3:"â´•";s:3:"Ⴕ";s:3:"â´–";s:3:"á‚¶";s:3:"â´—";s:3:"á‚·";s:3:"â´˜";s:3:"Ⴘ";s:3:"â´™";s:3:"Ⴙ";s:3:"â´š";s:3:"Ⴚ";s:3:"â´›";s:3:"á‚»";s:3:"â´œ";s:3:"Ⴜ";s:3:"â´";s:3:"Ⴝ";s:3:"â´ž";s:3:"Ⴞ";s:3:"â´Ÿ";s:3:"á‚¿";s:3:"â´ ";s:3:"Ⴠ";s:3:"â´¡";s:3:"áƒ";s:3:"â´¢";s:3:"Ⴢ";s:3:"â´£";s:3:"Ⴣ";s:3:"â´¤";s:3:"Ⴤ";s:3:"â´¥";s:3:"Ⴥ";s:3:"â´§";s:3:"Ⴧ";s:3:"â´­";s:3:"áƒ";s:3:"ê™";s:3:"Ꙁ";s:3:"ꙃ";s:3:"Ꙃ";s:3:"ê™…";s:3:"Ꙅ";s:3:"ꙇ";s:3:"Ꙇ";s:3:"ꙉ";s:3:"Ꙉ";s:3:"ꙋ";s:3:"Ꙋ";s:3:"ê™";s:3:"Ꙍ";s:3:"ê™";s:3:"Ꙏ";s:3:"ꙑ";s:3:"ê™";s:3:"ꙓ";s:3:"ê™’";s:3:"ꙕ";s:3:"ê™”";s:3:"ê™—";s:3:"ê™–";s:3:"ê™™";s:3:"Ꙙ";s:3:"ê™›";s:3:"Ꙛ";s:3:"ê™";s:3:"Ꙝ";s:3:"ꙟ";s:3:"Ꙟ";s:3:"ꙡ";s:3:"ê™ ";s:3:"ꙣ";s:3:"Ꙣ";s:3:"ꙥ";s:3:"Ꙥ";s:3:"ê™§";s:3:"Ꙧ";s:3:"ꙩ";s:3:"Ꙩ";s:3:"ꙫ";s:3:"Ꙫ";s:3:"ê™­";s:3:"Ꙭ";s:3:"êš";s:3:"Ꚁ";s:3:"ꚃ";s:3:"êš‚";s:3:"êš…";s:3:"êš„";s:3:"ꚇ";s:3:"Ꚇ";s:3:"ꚉ";s:3:"Ꚉ";s:3:"êš‹";s:3:"Ꚋ";s:3:"êš";s:3:"Ꚍ";s:3:"êš";s:3:"Ꚏ";s:3:"êš‘";s:3:"êš";s:3:"êš“";s:3:"êš’";s:3:"êš•";s:3:"êš”";s:3:"êš—";s:3:"êš–";s:3:"êš™";s:3:"Ꚙ";s:3:"êš›";s:3:"êšš";s:3:"ꜣ";s:3:"Ꜣ";s:3:"ꜥ";s:3:"Ꜥ";s:3:"ꜧ";s:3:"Ꜧ";s:3:"ꜩ";s:3:"Ꜩ";s:3:"ꜫ";s:3:"Ꜫ";s:3:"ꜭ";s:3:"Ꜭ";s:3:"ꜯ";s:3:"Ꜯ";s:3:"ꜳ";s:3:"Ꜳ";s:3:"ꜵ";s:3:"Ꜵ";s:3:"ꜷ";s:3:"Ꜷ";s:3:"ꜹ";s:3:"Ꜹ";s:3:"ꜻ";s:3:"Ꜻ";s:3:"ꜽ";s:3:"Ꜽ";s:3:"ꜿ";s:3:"Ꜿ";s:3:"ê";s:3:"ê€";s:3:"êƒ";s:3:"ê‚";s:3:"ê…";s:3:"ê„";s:3:"ê‡";s:3:"ê†";s:3:"ê‰";s:3:"êˆ";s:3:"ê‹";s:3:"êŠ";s:3:"ê";s:3:"êŒ";s:3:"ê";s:3:"êŽ";s:3:"ê‘";s:3:"ê";s:3:"ê“";s:3:"ê’";s:3:"ê•";s:3:"ê”";s:3:"ê—";s:3:"ê–";s:3:"ê™";s:3:"ê˜";s:3:"ê›";s:3:"êš";s:3:"ê";s:3:"êœ";s:3:"êŸ";s:3:"êž";s:3:"ê¡";s:3:"ê ";s:3:"ê£";s:3:"ê¢";s:3:"ê¥";s:3:"ê¤";s:3:"ê§";s:3:"ê¦";s:3:"ê©";s:3:"ê¨";s:3:"ê«";s:3:"êª";s:3:"ê­";s:3:"ê¬";s:3:"ê¯";s:3:"ê®";s:3:"êº";s:3:"ê¹";s:3:"ê¼";s:3:"ê»";s:3:"ê¿";s:3:"ê¾";s:3:"êž";s:3:"Ꞁ";s:3:"ꞃ";s:3:"êž‚";s:3:"êž…";s:3:"êž„";s:3:"ꞇ";s:3:"Ꞇ";s:3:"ꞌ";s:3:"êž‹";s:3:"êž‘";s:3:"êž";s:3:"êž“";s:3:"êž’";s:3:"êž—";s:3:"êž–";s:3:"êž™";s:3:"Ꞙ";s:3:"êž›";s:3:"êžš";s:3:"êž";s:3:"êžœ";s:3:"ꞟ";s:3:"êžž";s:3:"êž¡";s:3:"êž ";s:3:"ꞣ";s:3:"Ꞣ";s:3:"ꞥ";s:3:"Ꞥ";s:3:"êž§";s:3:"Ꞧ";s:3:"êž©";s:3:"Ꞩ";s:3:"ï½";s:3:"A";s:3:"b";s:3:"ï¼¢";s:3:"c";s:3:"ï¼£";s:3:"d";s:3:"D";s:3:"ï½…";s:3:"ï¼¥";s:3:"f";s:3:"F";s:3:"g";s:3:"ï¼§";s:3:"h";s:3:"H";s:3:"i";s:3:"I";s:3:"j";s:3:"J";s:3:"k";s:3:"K";s:3:"l";s:3:"L";s:3:"ï½";s:3:"ï¼­";s:3:"n";s:3:"ï¼®";s:3:"ï½";s:3:"O";s:3:"ï½";s:3:"ï¼°";s:3:"q";s:3:"ï¼±";s:3:"ï½’";s:3:"ï¼²";s:3:"s";s:3:"ï¼³";s:3:"ï½”";s:3:"ï¼´";s:3:"u";s:3:"ï¼µ";s:3:"ï½–";s:3:"ï¼¶";s:3:"ï½—";s:3:"ï¼·";s:3:"x";s:3:"X";s:3:"ï½™";s:3:"ï¼¹";s:3:"z";s:3:"Z";s:4:"ð¨";s:4:"ð€";s:4:"ð©";s:4:"ð";s:4:"ðª";s:4:"ð‚";s:4:"ð«";s:4:"ðƒ";s:4:"ð¬";s:4:"ð„";s:4:"ð­";s:4:"ð…";s:4:"ð®";s:4:"ð†";s:4:"ð¯";s:4:"ð‡";s:4:"ð°";s:4:"ðˆ";s:4:"ð±";s:4:"ð‰";s:4:"ð²";s:4:"ðŠ";s:4:"ð³";s:4:"ð‹";s:4:"ð´";s:4:"ðŒ";s:4:"ðµ";s:4:"ð";s:4:"ð¶";s:4:"ðŽ";s:4:"ð·";s:4:"ð";s:4:"ð¸";s:4:"ð";s:4:"ð¹";s:4:"ð‘";s:4:"ðº";s:4:"ð’";s:4:"ð»";s:4:"ð“";s:4:"ð¼";s:4:"ð”";s:4:"ð½";s:4:"ð•";s:4:"ð¾";s:4:"ð–";s:4:"ð¿";s:4:"ð—";s:4:"ð‘€";s:4:"ð˜";s:4:"ð‘";s:4:"ð™";s:4:"ð‘‚";s:4:"ðš";s:4:"ð‘ƒ";s:4:"ð›";s:4:"ð‘„";s:4:"ðœ";s:4:"ð‘…";s:4:"ð";s:4:"ð‘†";s:4:"ðž";s:4:"ð‘‡";s:4:"ðŸ";s:4:"ð‘ˆ";s:4:"ð ";s:4:"ð‘‰";s:4:"ð¡";s:4:"ð‘Š";s:4:"ð¢";s:4:"ð‘‹";s:4:"ð£";s:4:"ð‘Œ";s:4:"ð¤";s:4:"ð‘";s:4:"ð¥";s:4:"ð‘Ž";s:4:"ð¦";s:4:"ð‘";s:4:"ð§";s:4:"ð‘£€";s:4:"ð‘¢ ";s:4:"ð‘£";s:4:"𑢡";s:4:"𑣂";s:4:"ð‘¢¢";s:4:"𑣃";s:4:"ð‘¢£";s:4:"𑣄";s:4:"𑢤";s:4:"ð‘£…";s:4:"ð‘¢¥";s:4:"𑣆";s:4:"𑢦";s:4:"𑣇";s:4:"ð‘¢§";s:4:"𑣈";s:4:"𑢨";s:4:"𑣉";s:4:"𑢩";s:4:"𑣊";s:4:"𑢪";s:4:"𑣋";s:4:"𑢫";s:4:"𑣌";s:4:"𑢬";s:4:"ð‘£";s:4:"ð‘¢­";s:4:"𑣎";s:4:"ð‘¢®";s:4:"ð‘£";s:4:"𑢯";s:4:"ð‘£";s:4:"ð‘¢°";s:4:"𑣑";s:4:"ð‘¢±";s:4:"ð‘£’";s:4:"ð‘¢²";s:4:"𑣓";s:4:"ð‘¢³";s:4:"ð‘£”";s:4:"ð‘¢´";s:4:"𑣕";s:4:"ð‘¢µ";s:4:"ð‘£–";s:4:"ð‘¢¶";s:4:"ð‘£—";s:4:"ð‘¢·";s:4:"𑣘";s:4:"𑢸";s:4:"ð‘£™";s:4:"ð‘¢¹";s:4:"𑣚";s:4:"𑢺";s:4:"ð‘£›";s:4:"ð‘¢»";s:4:"𑣜";s:4:"ð‘¢¼";s:4:"ð‘£";s:4:"ð‘¢½";s:4:"𑣞";s:4:"ð‘¢¾";s:4:"𑣟";s:4:"𑢿";} \ No newline at end of file diff --git a/vendor/symfony/polyfill-php54/LICENSE b/vendor/symfony/polyfill-php54/LICENSE deleted file mode 100644 index 39fa189d..00000000 --- a/vendor/symfony/polyfill-php54/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2014-2016 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php54/Php54.php b/vendor/symfony/polyfill-php54/Php54.php deleted file mode 100644 index f64b58bc..00000000 --- a/vendor/symfony/polyfill-php54/Php54.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php54; - -/** - * @author Nicolas Grekas - * - * @internal - */ -final class Php54 -{ - public static function hex2bin($data) - { - $len = strlen($data); - - if (null === $len) { - return; - } - if ($len % 2) { - trigger_error('hex2bin(): Hexadecimal input string must have an even length', E_USER_WARNING); - - return false; - } - - return pack('H*', $data); - } -} diff --git a/vendor/symfony/polyfill-php54/README.md b/vendor/symfony/polyfill-php54/README.md deleted file mode 100644 index d5dd463c..00000000 --- a/vendor/symfony/polyfill-php54/README.md +++ /dev/null @@ -1,17 +0,0 @@ -Symfony Polyfill / Php54 -======================== - -This component provides functions unavailable in releases prior to PHP 5.4: - -- [`trait_exists`](http://php.net/trait_exists) -- [`class_uses`](http://php.net/class_uses) -- [`hex2bin`](http://php.net/hex2bin) -- [`session_register_shutdown`](http://php.net/session_register_shutdown) - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php54/Resources/stubs/CallbackFilterIterator.php b/vendor/symfony/polyfill-php54/Resources/stubs/CallbackFilterIterator.php deleted file mode 100644 index b69db3d1..00000000 --- a/vendor/symfony/polyfill-php54/Resources/stubs/CallbackFilterIterator.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -class CallbackFilterIterator extends FilterIterator -{ - private $iterator; - private $callback; - - public function __construct(Iterator $iterator, $callback) - { - $this->iterator = $iterator; - $this->callback = $callback; - parent::__construct($iterator); - } - - public function accept() - { - return call_user_func($this->callback, $this->current(), $this->key(), $this->iterator); - } -} diff --git a/vendor/symfony/polyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.php b/vendor/symfony/polyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.php deleted file mode 100644 index 63afd387..00000000 --- a/vendor/symfony/polyfill-php54/Resources/stubs/RecursiveCallbackFilterIterator.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -class RecursiveCallbackFilterIterator extends CallbackFilterIterator implements RecursiveIterator -{ - private $iterator; - private $callback; - - public function __construct(RecursiveIterator $iterator, $callback) - { - $this->iterator = $iterator; - $this->callback = $callback; - parent::__construct($iterator, $callback); - } - - public function hasChildren() - { - return $this->iterator->hasChildren(); - } - - public function getChildren() - { - return new static($this->iterator->getChildren(), $this->callback); - } -} diff --git a/vendor/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php b/vendor/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php deleted file mode 100644 index 9baa7bc0..00000000 --- a/vendor/symfony/polyfill-php54/Resources/stubs/SessionHandlerInterface.php +++ /dev/null @@ -1,102 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * SessionHandlerInterface for PHP < 5.4. - * - * The order in which these methods are invoked by PHP are: - * 1. open [session_start] - * 2. read - * 3. gc [optional depending on probability settings: gc_probability / gc_divisor] - * 4. destroy [optional when session_regenerate_id(true) is used] - * 5. write [session_write_close] or destroy [session_destroy] - * 6. close - * - * Extensive documentation can be found at php.net, see links: - * - * @see http://php.net/sessionhandlerinterface - * @see http://php.net/session.customhandler - * @see http://php.net/session-set-save-handler - * - * @author Drak - * @author Tobias Schultze - */ -interface SessionHandlerInterface -{ - /** - * Re-initializes existing session, or creates a new one. - * - * @see http://php.net/sessionhandlerinterface.open - * - * @param string $savePath Save path - * @param string $sessionName Session name, see http://php.net/function.session-name.php - * - * @return bool true on success, false on failure - */ - public function open($savePath, $sessionName); - - /** - * Closes the current session. - * - * @see http://php.net/sessionhandlerinterface.close - * - * @return bool true on success, false on failure - */ - public function close(); - - /** - * Reads the session data. - * - * @see http://php.net/sessionhandlerinterface.read - * - * @param string $sessionId Session ID, see http://php.net/function.session-id - * - * @return string Same session data as passed in write() or empty string when non-existent or on failure - */ - public function read($sessionId); - - /** - * Writes the session data to the storage. - * - * Care, the session ID passed to write() can be different from the one previously - * received in read() when the session ID changed due to session_regenerate_id(). - * - * @see http://php.net/sessionhandlerinterface.write - * - * @param string $sessionId Session ID , see http://php.net/function.session-id - * @param string $data Serialized session data to save - * - * @return bool true on success, false on failure - */ - public function write($sessionId, $data); - - /** - * Destroys a session. - * - * @see http://php.net/sessionhandlerinterface.destroy - * - * @param string $sessionId Session ID, see http://php.net/function.session-id - * - * @return bool true on success, false on failure - */ - public function destroy($sessionId); - - /** - * Cleans up expired sessions (garbage collection). - * - * @see http://php.net/sessionhandlerinterface.gc - * - * @param string|int $maxlifetime Sessions that have not updated for the last maxlifetime seconds will be removed - * - * @return bool true on success, false on failure - */ - public function gc($maxlifetime); -} diff --git a/vendor/symfony/polyfill-php54/bootstrap.php b/vendor/symfony/polyfill-php54/bootstrap.php deleted file mode 100644 index e923a29d..00000000 --- a/vendor/symfony/polyfill-php54/bootstrap.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php54 as p; - -if (PHP_VERSION_ID < 50400) { - if (!function_exists('trait_exists')) { - function trait_exists($class, $autoload = true) { return $autoload && class_exists($class, $autoload) && false; } - } - if (!function_exists('class_uses')) { - function class_uses($class, $autoload = true) - { - if (is_object($class) || class_exists($class, $autoload) || interface_exists($class, false)) { - return array(); - } - - return false; - } - } - if (!function_exists('hex2bin')) { - function hex2bin($data) { return p\Php54::hex2bin($data); } - } - if (!function_exists('session_register_shutdown')) { - function session_register_shutdown() { register_shutdown_function('session_write_close'); } - } -} diff --git a/vendor/symfony/polyfill-php54/composer.json b/vendor/symfony/polyfill-php54/composer.json deleted file mode 100644 index 327f46c3..00000000 --- a/vendor/symfony/polyfill-php54/composer.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "symfony/polyfill-php54", - "type": "library", - "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=5.3.3" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Php54\\": "" }, - "files": [ "bootstrap.php" ], - "classmap": [ "Resources/stubs" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - } -} diff --git a/vendor/symfony/polyfill-php55/LICENSE b/vendor/symfony/polyfill-php55/LICENSE deleted file mode 100644 index 39fa189d..00000000 --- a/vendor/symfony/polyfill-php55/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2014-2016 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php55/Php55.php b/vendor/symfony/polyfill-php55/Php55.php deleted file mode 100644 index 396baf26..00000000 --- a/vendor/symfony/polyfill-php55/Php55.php +++ /dev/null @@ -1,63 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php55; - -/** - * @internal - */ -final class Php55 -{ - public static function boolval($val) - { - return (bool) $val; - } - - public static function json_last_error_msg() - { - switch (json_last_error()) { - case JSON_ERROR_NONE: return 'No error'; - case JSON_ERROR_DEPTH: return 'Maximum stack depth exceeded'; - case JSON_ERROR_STATE_MISMATCH: return 'State mismatch (invalid or malformed JSON)'; - case JSON_ERROR_CTRL_CHAR: return 'Control character error, possibly incorrectly encoded'; - case JSON_ERROR_SYNTAX: return 'Syntax error'; - case JSON_ERROR_UTF8: return 'Malformed UTF-8 characters, possibly incorrectly encoded'; - default: return 'Unknown error'; - } - } - - /** - * @author Sebastiaan Stok - */ - public static function hash_pbkdf2($algorithm, $password, $salt, $iterations, $length = 0, $rawOutput = false) - { - // Number of blocks needed to create the derived key - $blocks = ceil($length / strlen(hash($algorithm, null, true))); - $digest = ''; - - for ($i = 1; $i <= $blocks; ++$i) { - $ib = $block = hash_hmac($algorithm, $salt.pack('N', $i), $password, true); - - // Iterations - for ($j = 1; $j < $iterations; ++$j) { - $ib ^= ($block = hash_hmac($algorithm, $block, $password, true)); - } - - $digest .= $ib; - } - - if (!$rawOutput) { - $digest = bin2hex($digest); - } - - return substr($digest, 0, $length); - } -} diff --git a/vendor/symfony/polyfill-php55/Php55ArrayColumn.php b/vendor/symfony/polyfill-php55/Php55ArrayColumn.php deleted file mode 100644 index a3033d83..00000000 --- a/vendor/symfony/polyfill-php55/Php55ArrayColumn.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -namespace Symfony\Polyfill\Php55; - -/** - * @internal - */ -final class Php55ArrayColumn -{ - public static function array_column(array $input, $columnKey, $indexKey = null) - { - $output = array(); - - foreach ($input as $row) { - $key = $value = null; - $keySet = $valueSet = false; - - if ($indexKey !== null && array_key_exists($indexKey, $row)) { - $keySet = true; - $key = (string) $row[$indexKey]; - } - - if ($columnKey === null) { - $valueSet = true; - $value = $row; - } elseif (is_array($row) && array_key_exists($columnKey, $row)) { - $valueSet = true; - $value = $row[$columnKey]; - } - - if ($valueSet) { - if ($keySet) { - $output[$key] = $value; - } else { - $output[] = $value; - } - } - } - - return $output; - } -} diff --git a/vendor/symfony/polyfill-php55/README.md b/vendor/symfony/polyfill-php55/README.md deleted file mode 100644 index 3e432e49..00000000 --- a/vendor/symfony/polyfill-php55/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Symfony Polyfill / Php55 -======================== - -This component provides functions unavailable in releases prior to PHP 5.5: - -- [`boolval`](http://php.net/boolval) -- [`json_last_error_msg`](http://php.net/json_last_error_msg) -- [`array_column`](http://php.net/array_column) -- [`hash_pbkdf2`](http://php.net/hash_pbkdf2) -- `password_*` functions (from [ircmaxell/password_compat](https://github.com/ircmaxell/password_compat)) - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php55/bootstrap.php b/vendor/symfony/polyfill-php55/bootstrap.php deleted file mode 100644 index 5e634feb..00000000 --- a/vendor/symfony/polyfill-php55/bootstrap.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php55 as p; - -if (PHP_VERSION_ID < 50500) { - if (!function_exists('boolval')) { - function boolval($val) { return p\Php55::boolval($val); } - } - if (!function_exists('json_last_error_msg')) { - function json_last_error_msg() { return p\Php55::json_last_error_msg(); } - } - if (!function_exists('array_column')) { - function array_column($array, $columnKey, $indexKey = null) { return p\Php55ArrayColumn::array_column($array, $columnKey, $indexKey); } - } - if (!function_exists('hash_pbkdf2')) { - function hash_pbkdf2($algorithm, $password, $salt, $iterations, $length = 0, $rawOutput = false) { return p\Php55::hash_pbkdf2($algorithm, $password, $salt, $iterations, $length, $rawOutput); } - } -} diff --git a/vendor/symfony/polyfill-php55/composer.json b/vendor/symfony/polyfill-php55/composer.json deleted file mode 100644 index 49deca9e..00000000 --- a/vendor/symfony/polyfill-php55/composer.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "symfony/polyfill-php55", - "type": "library", - "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=5.3.3", - "ircmaxell/password-compat": "~1.0" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Php55\\": "" }, - "files": [ "bootstrap.php" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - } -} diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php index 824457ce..d8e68962 100644 --- a/vendor/symfony/process/ExecutableFinder.php +++ b/vendor/symfony/process/ExecutableFinder.php @@ -75,7 +75,7 @@ public function find($name, $default = null, array $extraDirs = array()) $suffixes = array(''); if ('\\' === DIRECTORY_SEPARATOR) { $pathExt = getenv('PATHEXT'); - $suffixes = $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes; + $suffixes = array_merge($suffixes, $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes); } foreach ($suffixes as $suffix) { foreach ($dirs as $dir) { diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php new file mode 100644 index 00000000..831b1093 --- /dev/null +++ b/vendor/symfony/process/InputStream.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +use Symfony\Component\Process\Exception\RuntimeException; + +/** + * Provides a way to continuously write to the input of a Process until the InputStream is closed. + * + * @author Nicolas Grekas + */ +class InputStream implements \IteratorAggregate +{ + private $onEmpty = null; + private $input = array(); + private $open = true; + + /** + * Sets a callback that is called when the write buffer becomes empty. + */ + public function onEmpty(callable $onEmpty = null) + { + $this->onEmpty = $onEmpty; + } + + /** + * Appends an input to the write buffer. + * + * @param resource|scalar|\Traversable|null The input to append as stream resource, scalar or \Traversable + */ + public function write($input) + { + if (null === $input) { + return; + } + if ($this->isClosed()) { + throw new RuntimeException(sprintf('%s is closed', static::class)); + } + $this->input[] = ProcessUtils::validateInput(__METHOD__, $input); + } + + /** + * Closes the write buffer. + */ + public function close() + { + $this->open = false; + } + + /** + * Tells whether the write buffer is closed or not. + */ + public function isClosed() + { + return !$this->open; + } + + public function getIterator() + { + $this->open = true; + + while ($this->open || $this->input) { + if (!$this->input) { + yield ''; + continue; + } + $current = array_shift($this->input); + + if ($current instanceof \Iterator) { + foreach ($current as $cur) { + yield $cur; + } + } else { + yield $current; + } + if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) { + $this->write($onEmpty($this)); + } + } + } +} diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php index fb297825..db31cc1b 100644 --- a/vendor/symfony/process/PhpExecutableFinder.php +++ b/vendor/symfony/process/PhpExecutableFinder.php @@ -44,7 +44,7 @@ public function find($includeArgs = true) } // PHP_BINARY return the current sapi executable - if (defined('PHP_BINARY') && PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg')) && is_file(PHP_BINARY)) { + if (PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg')) && is_file(PHP_BINARY)) { return PHP_BINARY.$args; } diff --git a/vendor/symfony/process/PhpProcess.php b/vendor/symfony/process/PhpProcess.php index 42ecb66f..76425ceb 100644 --- a/vendor/symfony/process/PhpProcess.php +++ b/vendor/symfony/process/PhpProcess.php @@ -67,7 +67,7 @@ public function setPhpBinary($php) /** * {@inheritdoc} */ - public function start($callback = null) + public function start(callable $callback = null) { if (null === $this->getCommandLine()) { throw new RuntimeException('Unable to find the PHP executable.'); diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php index 1a94755b..4c67d5b8 100644 --- a/vendor/symfony/process/Pipes/AbstractPipes.php +++ b/vendor/symfony/process/Pipes/AbstractPipes.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Process\Pipes; +use Symfony\Component\Process\Exception\InvalidArgumentException; + /** * @author Romain Neutron * @@ -23,14 +25,14 @@ abstract class AbstractPipes implements PipesInterface /** @var string */ private $inputBuffer = ''; - /** @var resource|null */ + /** @var resource|scalar|\Iterator|null */ private $input; /** @var bool */ private $blocked = true; public function __construct($input) { - if (is_resource($input)) { + if (is_resource($input) || $input instanceof \Iterator) { $this->input = $input; } elseif (is_string($input)) { $this->inputBuffer = $input; @@ -75,7 +77,7 @@ protected function unblock() foreach ($this->pipes as $pipe) { stream_set_blocking($pipe, 0); } - if (null !== $this->input) { + if (is_resource($this->input)) { stream_set_blocking($this->input, 0); } @@ -84,6 +86,8 @@ protected function unblock() /** * Writes input to stdin. + * + * @throws InvalidArgumentException When an input iterator yields a non supported value */ protected function write() { @@ -91,6 +95,27 @@ protected function write() return; } $input = $this->input; + + if ($input instanceof \Iterator) { + if (!$input->valid()) { + $input = null; + } elseif (is_resource($input = $input->current())) { + stream_set_blocking($input, 0); + } elseif (!isset($this->inputBuffer[0])) { + if (!is_string($input)) { + if (!is_scalar($input)) { + throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported', get_class($this->input), gettype($input))); + } + $input = (string) $input; + } + $this->inputBuffer = $input; + $this->input->next(); + $input = null; + } else { + $input = null; + } + } + $r = $e = array(); $w = array($this->pipes[0]); @@ -123,15 +148,18 @@ protected function write() } } if (feof($input)) { - // no more data to read on input resource - // use an empty buffer in the next reads - $this->input = null; + if ($this->input instanceof \Iterator) { + $this->input->next(); + } else { + $this->input = null; + } } } } // no input to read on resource, buffer is empty - if (null === $this->input && !isset($this->inputBuffer[0])) { + if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) { + $this->input = null; fclose($this->pipes[0]); unset($this->pipes[0]); } elseif (!$w) { diff --git a/vendor/symfony/process/Pipes/PipesInterface.php b/vendor/symfony/process/Pipes/PipesInterface.php index b91c393d..52bbe76b 100644 --- a/vendor/symfony/process/Pipes/PipesInterface.php +++ b/vendor/symfony/process/Pipes/PipesInterface.php @@ -53,6 +53,13 @@ public function readAndWrite($blocking, $close = false); */ public function areOpen(); + /** + * Returns if pipes are able to read output. + * + * @return bool + */ + public function haveReadSupport(); + /** * Closes file handles and pipes. */ diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php index c4babcdf..3185fe76 100644 --- a/vendor/symfony/process/Pipes/UnixPipes.php +++ b/vendor/symfony/process/Pipes/UnixPipes.php @@ -27,13 +27,13 @@ class UnixPipes extends AbstractPipes /** @var bool */ private $ptyMode; /** @var bool */ - private $disableOutput; + private $haveReadSupport; - public function __construct($ttyMode, $ptyMode, $input, $disableOutput) + public function __construct($ttyMode, $ptyMode, $input, $haveReadSupport) { $this->ttyMode = (bool) $ttyMode; $this->ptyMode = (bool) $ptyMode; - $this->disableOutput = (bool) $disableOutput; + $this->haveReadSupport = (bool) $haveReadSupport; parent::__construct($input); } @@ -48,7 +48,7 @@ public function __destruct() */ public function getDescriptors() { - if ($this->disableOutput) { + if (!$this->haveReadSupport) { $nullstream = fopen('/dev/null', 'c'); return array( @@ -138,21 +138,16 @@ public function readAndWrite($blocking, $close = false) /** * {@inheritdoc} */ - public function areOpen() + public function haveReadSupport() { - return (bool) $this->pipes; + return $this->haveReadSupport; } /** - * Creates a new UnixPipes instance. - * - * @param Process $process - * @param string|resource $input - * - * @return static + * {@inheritdoc} */ - public static function create(Process $process, $input) + public function areOpen() { - return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled()); + return (bool) $this->pipes; } } diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php index 87a781ea..a1e31155 100644 --- a/vendor/symfony/process/Pipes/WindowsPipes.php +++ b/vendor/symfony/process/Pipes/WindowsPipes.php @@ -36,13 +36,13 @@ class WindowsPipes extends AbstractPipes Process::STDERR => 0, ); /** @var bool */ - private $disableOutput; + private $haveReadSupport; - public function __construct($disableOutput, $input) + public function __construct($input, $haveReadSupport) { - $this->disableOutput = (bool) $disableOutput; + $this->haveReadSupport = (bool) $haveReadSupport; - if (!$this->disableOutput) { + if ($this->haveReadSupport) { // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. // Workaround for this problem is to use temporary files instead of pipes on Windows platform. // @@ -97,7 +97,7 @@ public function __destruct() */ public function getDescriptors() { - if ($this->disableOutput) { + if (!$this->haveReadSupport) { $nullstream = fopen('NUL', 'c'); return array( @@ -157,6 +157,14 @@ public function readAndWrite($blocking, $close = false) return $read; } + /** + * {@inheritdoc} + */ + public function haveReadSupport() + { + return $this->haveReadSupport; + } + /** * {@inheritdoc} */ @@ -177,19 +185,6 @@ public function close() $this->fileHandles = array(); } - /** - * Creates a new WindowsPipes instance. - * - * @param Process $process The process - * @param $input - * - * @return static - */ - public static function create(Process $process, $input) - { - return new static($process->isOutputDisabled(), $input); - } - /** * Removes temporary files. */ diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php index 23d56166..bd00e176 100644 --- a/vendor/symfony/process/Process.php +++ b/vendor/symfony/process/Process.php @@ -27,7 +27,7 @@ * @author Fabien Potencier * @author Romain Neutron */ -class Process +class Process implements \IteratorAggregate { const ERR = 'err'; const OUT = 'out'; @@ -43,7 +43,13 @@ class Process // Timeout Precision in seconds. const TIMEOUT_PRECISION = 0.2; + const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking + const ITER_KEEP_OUTPUT = 2; // By default, outputs are cleared while iterating, use this flag to keep them in memory + const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating + const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating + private $callback; + private $hasCallback = false; private $commandline; private $cwd; private $env; @@ -67,6 +73,7 @@ class Process private $incrementalErrorOutputOffset = 0; private $tty; private $pty; + private $inheritEnv = false; private $useFileHandles = false; /** @var PipesInterface */ @@ -132,7 +139,7 @@ class Process * @param string $commandline The command line to run * @param string|null $cwd The working directory or null to use the working dir of the current PHP process * @param array|null $env The environment variables or null to use the same environment as the current PHP process - * @param string|null $input The input + * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input * @param int|float|null $timeout The timeout in seconds or null to disable * @param array $options An array of options for proc_open * @@ -162,7 +169,6 @@ public function __construct($commandline, $cwd = null, array $env = null, $input $this->setTimeout($timeout); $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR; $this->pty = false; - $this->enhanceWindowsCompatibility = true; $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled(); $this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options); } @@ -216,7 +222,7 @@ public function run($callback = null) * @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled * @throws ProcessFailedException if the process didn't terminate successfully */ - public function mustRun($callback = null) + public function mustRun(callable $callback = null) { if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); @@ -248,22 +254,34 @@ public function mustRun($callback = null) * @throws RuntimeException When process is already running * @throws LogicException In case a callback is provided and output has been disabled */ - public function start($callback = null) + public function start(callable $callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } - if ($this->outputDisabled && null !== $callback) { - throw new LogicException('Output has been disabled, enable it to allow the use of a callback.'); - } $this->resetProcessData(); $this->starttime = $this->lastOutputTime = microtime(true); $this->callback = $this->buildCallback($callback); + $this->hasCallback = null !== $callback; $descriptors = $this->getDescriptors(); + $inheritEnv = $this->inheritEnv; $commandline = $this->commandline; + $env = $this->env; + $envBackup = array(); + if (null !== $env && $inheritEnv) { + if ('\\' === DIRECTORY_SEPARATOR && !empty($this->options['bypass_shell']) && !$this->enhanceWindowsCompatibility) { + throw new LogicException('The "bypass_shell" option must be false to inherit environment variables while enhanced Windows compatibility is off'); + } + + foreach ($env as $k => $v) { + $envBackup[$k] = getenv($k); + putenv(false === $v || null === $v ? $k : "$k=$v"); + } + $env = null; + } if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')'; foreach ($this->processPipes->getFiles() as $offset => $filename) { @@ -287,7 +305,11 @@ public function start($callback = null) $ptsWorkaround = fopen(__FILE__, 'r'); } - $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); + $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $env, $this->options); + + foreach ($envBackup as $k => $v) { + putenv(false === $v ? $k : "$k=$v"); + } if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); @@ -321,7 +343,7 @@ public function start($callback = null) * * @see start() */ - public function restart($callback = null) + public function restart(callable $callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); @@ -348,12 +370,17 @@ public function restart($callback = null) * @throws RuntimeException When process stopped after receiving signal * @throws LogicException When process is not yet started */ - public function wait($callback = null) + public function wait(callable $callback = null) { $this->requireProcessIsStarted(__FUNCTION__); $this->updateStatus(false); + if (null !== $callback) { + if (!$this->processPipes->haveReadSupport()) { + $this->stop(0); + throw new \LogicException('Pass the callback to the Process::start method or enableOutput to use a callback with Process::wait'); + } $this->callback = $this->buildCallback($callback); } @@ -496,6 +523,63 @@ public function getIncrementalOutput() return $latest; } + /** + * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR). + * + * @param int $flags A bit field of Process::ITER_* flags + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + * + * @return \Generator + */ + public function getIterator($flags = 0) + { + $this->readPipesForOutput(__FUNCTION__, false); + + $clearOutput = !(self::ITER_KEEP_OUTPUT & $flags); + $blocking = !(self::ITER_NON_BLOCKING & $flags); + $yieldOut = !(self::ITER_SKIP_OUT & $flags); + $yieldErr = !(self::ITER_SKIP_ERR & $flags); + + while (null !== $this->callback || ($yieldOut && !feof($this->stdout)) || ($yieldErr && !feof($this->stderr))) { + if ($yieldOut) { + $out = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); + + if (isset($out[0])) { + if ($clearOutput) { + $this->clearOutput(); + } else { + $this->incrementalOutputOffset = ftell($this->stdout); + } + + yield self::OUT => $out; + } + } + + if ($yieldErr) { + $err = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); + + if (isset($err[0])) { + if ($clearOutput) { + $this->clearErrorOutput(); + } else { + $this->incrementalErrorOutputOffset = ftell($this->stderr); + } + + yield self::ERR => $err; + } + } + + if (!$blocking && !isset($out[0]) && !isset($err[0])) { + yield self::OUT => ''; + } + + $this->checkTimeout(); + $this->readPipesForOutput(__FUNCTION__, $blocking); + } + } + /** * Clears the process output. * @@ -1022,72 +1106,31 @@ public function setEnv(array $env) return !is_array($value); }); - $this->env = array(); - foreach ($env as $key => $value) { - $this->env[$key] = (string) $value; - } + $this->env = $env; return $this; } - /** - * Gets the contents of STDIN. - * - * @return string|null The current contents - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use setInput() instead. - * This method is deprecated in favor of getInput. - */ - public function getStdin() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getInput() method instead.', E_USER_DEPRECATED); - - return $this->getInput(); - } - /** * Gets the Process input. * - * @return null|string The Process input + * @return resource|string|\Iterator|null The Process input */ public function getInput() { return $this->input; } - /** - * Sets the contents of STDIN. - * - * @param string|null $stdin The new contents - * - * @return self The current Process instance - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use setInput() instead. - * - * @throws LogicException In case the process is running - * @throws InvalidArgumentException In case the argument is invalid - */ - public function setStdin($stdin) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the setInput() method instead.', E_USER_DEPRECATED); - - return $this->setInput($stdin); - } - /** * Sets the input. * * This content will be passed to the underlying process standard input. * - * @param mixed $input The content + * @param resource|scalar|\Traversable|null $input The content * * @return self The current Process instance * * @throws LogicException In case the process is running - * - * Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0. */ public function setInput($input) { @@ -1178,6 +1221,30 @@ public function setEnhanceSigchildCompatibility($enhance) return $this; } + /** + * Sets whether environment variables will be inherited or not. + * + * @param bool $inheritEnv + * + * @return self The current Process instance + */ + public function inheritEnvironmentVariables($inheritEnv = true) + { + $this->inheritEnv = (bool) $inheritEnv; + + return $this; + } + + /** + * Returns whether environment variables will be inherited or not. + * + * @return bool + */ + public function areEnvironmentVariablesInherited() + { + return $this->inheritEnv; + } + /** * Performs a check between the timeout definition and the time the process started. * @@ -1232,10 +1299,13 @@ public static function isPtySupported() */ private function getDescriptors() { + if ($this->input instanceof \Iterator) { + $this->input->rewind(); + } if ('\\' === DIRECTORY_SEPARATOR) { - $this->processPipes = WindowsPipes::create($this, $this->input); + $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback); } else { - $this->processPipes = UnixPipes::create($this, $this->input); + $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback); } return $this->processPipes->getDescriptors(); @@ -1251,23 +1321,29 @@ private function getDescriptors() * * @return \Closure A PHP closure */ - protected function buildCallback($callback) + protected function buildCallback(callable $callback = null) { - $that = $this; + if ($this->outputDisabled) { + return function ($type, $data) use ($callback) { + if (null !== $callback) { + call_user_func($callback, $type, $data); + } + }; + } + $out = self::OUT; - $callback = function ($type, $data) use ($that, $callback, $out) { + + return function ($type, $data) use ($callback, $out) { if ($out == $type) { - $that->addOutput($data); + $this->addOutput($data); } else { - $that->addErrorOutput($data); + $this->addErrorOutput($data); } if (null !== $callback) { call_user_func($callback, $type, $data); } }; - - return $callback; } /** @@ -1319,11 +1395,12 @@ protected function isSigchildEnabled() /** * Reads pipes for the freshest output. * - * @param $caller The name of the method that needs fresh outputs + * @param string $caller The name of the method that needs fresh outputs + * @param bool $blocking Whether to use blocking calls or not * * @throws LogicException in case output has been disabled or process is not started */ - private function readPipesForOutput($caller) + private function readPipesForOutput($caller, $blocking = false) { if ($this->outputDisabled) { throw new LogicException('Output has been disabled.'); @@ -1331,7 +1408,7 @@ private function readPipesForOutput($caller) $this->requireProcessIsStarted($caller); - $this->updateStatus(false); + $this->updateStatus($blocking); } /** diff --git a/vendor/symfony/process/ProcessBuilder.php b/vendor/symfony/process/ProcessBuilder.php index 54877a82..cc91371f 100644 --- a/vendor/symfony/process/ProcessBuilder.php +++ b/vendor/symfony/process/ProcessBuilder.php @@ -167,13 +167,11 @@ public function addEnvironmentVariables(array $variables) /** * Sets the input of the process. * - * @param mixed $input The input as a string + * @param resource|scalar|\Traversable|null $input The input content * * @return $this * * @throws InvalidArgumentException In case the argument is invalid - * - * Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0. */ public function setInput($input) { @@ -269,15 +267,11 @@ public function getProcess() $arguments = array_merge($this->prefix, $this->arguments); $script = implode(' ', array_map(array(__NAMESPACE__.'\\ProcessUtils', 'escapeArgument'), $arguments)); + $process = new Process($script, $this->cwd, $this->env, $this->input, $this->timeout, $options); + if ($this->inheritEnv) { - // include $_ENV for BC purposes - $env = array_replace($_ENV, $_SERVER, $this->env); - } else { - $env = $this->env; + $process->inheritEnvironmentVariables(); } - - $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options); - if ($this->outputDisabled) { $process->disableOutput(); } diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php index 0bd2f6b7..cbc95708 100644 --- a/vendor/symfony/process/ProcessUtils.php +++ b/vendor/symfony/process/ProcessUtils.php @@ -71,7 +71,7 @@ public static function escapeArgument($argument) return $escapedArgument; } - return escapeshellarg($argument); + return "'".str_replace("'", "'\\''", $argument)."'"; } /** @@ -83,8 +83,6 @@ public static function escapeArgument($argument) * @return mixed The validated input * * @throws InvalidArgumentException In case the input is not valid - * - * Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0. */ public static function validateInput($caller, $input) { @@ -98,14 +96,17 @@ public static function validateInput($caller, $input) if (is_scalar($input)) { return (string) $input; } - // deprecated as of Symfony 2.5, to be removed in 3.0 - if (is_object($input) && method_exists($input, '__toString')) { - @trigger_error('Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - return (string) $input; + if ($input instanceof Process) { + return $input->getIterator($input::ITER_SKIP_ERR); + } + if ($input instanceof \Iterator) { + return $input; + } + if ($input instanceof \Traversable) { + return new \IteratorIterator($input); } - throw new InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller)); + throw new InvalidArgumentException(sprintf('%s only accepts strings, Traversable objects or stream resources.', $caller)); } return $input; diff --git a/vendor/symfony/process/composer.json b/vendor/symfony/process/composer.json index b3cb5186..a9c4a518 100644 --- a/vendor/symfony/process/composer.json +++ b/vendor/symfony/process/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, @@ -27,7 +27,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/process/phpunit.xml.dist b/vendor/symfony/process/phpunit.xml.dist index 78850008..d3884673 100644 --- a/vendor/symfony/process/phpunit.xml.dist +++ b/vendor/symfony/process/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/psr-http-message-bridge/.travis.yml b/vendor/symfony/psr-http-message-bridge/.travis.yml index 39e7eb61..30084712 100644 --- a/vendor/symfony/psr-http-message-bridge/.travis.yml +++ b/vendor/symfony/psr-http-message-bridge/.travis.yml @@ -2,6 +2,10 @@ language: php sudo: false +cache: + directories: + - $HOME/.composer/cache/files + matrix: include: - php: 5.3 @@ -12,10 +16,9 @@ matrix: env: deps=low - php: 5.6 env: deps=high - - php: nightly + - php: 7.0 - php: hhvm allow_failures: - - php: nightly - php: hhvm fast_finish: true @@ -25,15 +28,15 @@ env: - SYMFONY_DEPRECATIONS_HELPER=weak before_install: - - composer self-update - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi; + - composer self-update - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]] && [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then echo "extension = apc.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi; - if [[ "$TRAVIS_PHP_VERSION" != "nightly" ]] && [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then php -i; fi; # Set the COMPOSER_ROOT_VERSION to the right version according to the branch being built - if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi; install: - - if [[ "$TRAVIS_PHP_VERSION" != "5.3" ]] && [[ "$TRAVIS_PHP_VERSION" != "5.4" ]]; then composer require --no-update zendframework/zend-diactoros; fi; + - if [ "$TRAVIS_PHP_VERSION" != "5.3" ]; then composer require --no-update zendframework/zend-diactoros; fi; - if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi; - if [ "$deps" = "no" ]; then composer --prefer-source install; fi; - if [ "$deps" = "high" ]; then composer --prefer-source update; fi; diff --git a/vendor/symfony/psr-http-message-bridge/CHANGELOG b/vendor/symfony/psr-http-message-bridge/CHANGELOG new file mode 100644 index 00000000..cc3e9834 --- /dev/null +++ b/vendor/symfony/psr-http-message-bridge/CHANGELOG @@ -0,0 +1,3 @@ +* 1.0.0 (2016-09-14) + + * Initial release diff --git a/vendor/symfony/psr-http-message-bridge/CHANGELOG.md b/vendor/symfony/psr-http-message-bridge/CHANGELOG.md deleted file mode 100644 index 569522f7..00000000 --- a/vendor/symfony/psr-http-message-bridge/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -CHANGELOG -========= - -2.8.0 ------ - - * added the component diff --git a/vendor/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php b/vendor/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php index 31726f15..9174f051 100644 --- a/vendor/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php +++ b/vendor/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php @@ -45,11 +45,11 @@ public function createRequest(Request $symfonyRequest) $server = DiactorosRequestFactory::normalizeServer($symfonyRequest->server->all()); $headers = $symfonyRequest->headers->all(); - try { - $body = new DiactorosStream($symfonyRequest->getContent(true)); - } catch (\LogicException $e) { + if (PHP_VERSION_ID < 50600) { $body = new DiactorosStream('php://temp', 'wb+'); $body->write($symfonyRequest->getContent()); + } else { + $body = new DiactorosStream($symfonyRequest->getContent(true)); } $request = new ServerRequest( @@ -86,6 +86,10 @@ private function getFiles(array $uploadedFiles) $files = array(); foreach ($uploadedFiles as $key => $value) { + if (null === $value) { + $files[$key] = new DiactorosUploadedFile(null, 0, UPLOAD_ERR_NO_FILE, null, null); + continue; + } if ($value instanceof UploadedFile) { $files[$key] = $this->createUploadedFile($value); } else { @@ -107,7 +111,7 @@ private function createUploadedFile(UploadedFile $symfonyUploadedFile) { return new DiactorosUploadedFile( $symfonyUploadedFile->getRealPath(), - $symfonyUploadedFile->getSize(), + $symfonyUploadedFile->getClientSize(), $symfonyUploadedFile->getError(), $symfonyUploadedFile->getClientOriginalName(), $symfonyUploadedFile->getClientMimeType() diff --git a/vendor/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php b/vendor/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php index 2c356fd1..76d196bb 100644 --- a/vendor/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php +++ b/vendor/symfony/psr-http-message-bridge/Factory/HttpFoundationFactory.php @@ -14,6 +14,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UploadedFileInterface; +use Psr\Http\Message\UriInterface; use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\File\UploadedFile; @@ -32,6 +33,20 @@ class HttpFoundationFactory implements HttpFoundationFactoryInterface */ public function createRequest(ServerRequestInterface $psrRequest) { + $server = array(); + $uri = $psrRequest->getUri(); + + if ($uri instanceof UriInterface) { + $server['SERVER_NAME'] = $uri->getHost(); + $server['SERVER_PORT'] = $uri->getPort(); + $server['REQUEST_URI'] = $uri->getPath(); + $server['QUERY_STRING'] = $uri->getQuery(); + } + + $server['REQUEST_METHOD'] = $psrRequest->getMethod(); + + $server = array_replace($server, $psrRequest->getServerParams()); + $parsedBody = $psrRequest->getParsedBody(); $parsedBody = is_array($parsedBody) ? $parsedBody : array(); @@ -41,7 +56,7 @@ public function createRequest(ServerRequestInterface $psrRequest) $psrRequest->getAttributes(), $psrRequest->getCookieParams(), $this->getFiles($psrRequest->getUploadedFiles()), - $psrRequest->getServerParams(), + $server, $psrRequest->getBody()->__toString() ); $request->headers->replace($psrRequest->getHeaders()); @@ -80,10 +95,14 @@ private function getFiles(array $uploadedFiles) */ private function createUploadedFile(UploadedFileInterface $psrUploadedFile) { - $temporaryPath = $this->getTemporaryPath(); - $psrUploadedFile->moveTo($temporaryPath); + $temporaryPath = ''; + $clientFileName = ''; + if (UPLOAD_ERR_NO_FILE !== $psrUploadedFile->getError()) { + $temporaryPath = $this->getTemporaryPath(); + $psrUploadedFile->moveTo($temporaryPath); - $clientFileName = $psrUploadedFile->getClientFilename(); + $clientFileName = $psrUploadedFile->getClientFilename(); + } return new UploadedFile( $temporaryPath, diff --git a/vendor/symfony/psr-http-message-bridge/LICENSE b/vendor/symfony/psr-http-message-bridge/LICENSE index 43028bc6..12a74531 100644 --- a/vendor/symfony/psr-http-message-bridge/LICENSE +++ b/vendor/symfony/psr-http-message-bridge/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2015 Fabien Potencier +Copyright (c) 2004-2016 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/symfony/psr-http-message-bridge/composer.json b/vendor/symfony/psr-http-message-bridge/composer.json index 9dc9ce70..ad250809 100644 --- a/vendor/symfony/psr-http-message-bridge/composer.json +++ b/vendor/symfony/psr-http-message-bridge/composer.json @@ -24,10 +24,16 @@ "symfony/phpunit-bridge": "~2.7|~3.0" }, "suggest": { + "psr/http-message-implementation": "To use the HttpFoundation factory", "zendframework/zend-diactoros": "To use the Zend Diactoros factory" }, "autoload": { "psr-4": { "Symfony\\Bridge\\PsrHttpMessage\\": "" } }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } } diff --git a/vendor/symfony/routing/Annotation/Route.php b/vendor/symfony/routing/Annotation/Route.php index 191aa68a..e3d51570 100644 --- a/vendor/symfony/routing/Annotation/Route.php +++ b/vendor/symfony/routing/Annotation/Route.php @@ -54,26 +54,6 @@ public function __construct(array $data) } } - /** - * @deprecated since version 2.2, to be removed in 3.0. Use setPath instead. - */ - public function setPattern($pattern) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the setPath() method instead and use the "path" option instead of the "pattern" option in the route definition.', E_USER_DEPRECATED); - - $this->path = $pattern; - } - - /** - * @deprecated since version 2.2, to be removed in 3.0. Use getPath instead. - */ - public function getPattern() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the getPath() method instead and use the "path" option instead of the "pattern" option in the route definition.', E_USER_DEPRECATED); - - return $this->path; - } - public function setPath($path) { $this->path = $path; @@ -106,22 +86,6 @@ public function getName() public function setRequirements($requirements) { - if (isset($requirements['_method'])) { - if (0 === count($this->methods)) { - $this->methods = explode('|', $requirements['_method']); - } - - @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the "methods" option instead.', E_USER_DEPRECATED); - } - - if (isset($requirements['_scheme'])) { - if (0 === count($this->schemes)) { - $this->schemes = explode('|', $requirements['_scheme']); - } - - @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the "schemes" option instead.', E_USER_DEPRECATED); - } - $this->requirements = $requirements; } diff --git a/vendor/symfony/routing/CHANGELOG.md b/vendor/symfony/routing/CHANGELOG.md index 04ac1d31..5c21324c 100644 --- a/vendor/symfony/routing/CHANGELOG.md +++ b/vendor/symfony/routing/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +3.2.0 +----- + + * Added support for `bool`, `int`, `float`, `string`, `list` and `map` defaults in XML configurations. + * Added support for UTF-8 requirements + 2.8.0 ----- diff --git a/vendor/symfony/routing/Generator/UrlGenerator.php b/vendor/symfony/routing/Generator/UrlGenerator.php index 4a6b742e..342161e1 100644 --- a/vendor/symfony/routing/Generator/UrlGenerator.php +++ b/vendor/symfony/routing/Generator/UrlGenerator.php @@ -143,20 +143,6 @@ public function generate($name, $parameters = array(), $referenceType = self::AB */ protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array()) { - if (is_bool($referenceType) || is_string($referenceType)) { - @trigger_error('The hardcoded value you are using for the $referenceType argument of the '.__CLASS__.'::generate method is deprecated since version 2.8 and will not be supported anymore in 3.0. Use the constants defined in the UrlGeneratorInterface instead.', E_USER_DEPRECATED); - - if (true === $referenceType) { - $referenceType = self::ABSOLUTE_URL; - } elseif (false === $referenceType) { - $referenceType = self::ABSOLUTE_PATH; - } elseif ('relative' === $referenceType) { - $referenceType = self::RELATIVE_PATH; - } elseif ('network' === $referenceType) { - $referenceType = self::NETWORK_PATH; - } - } - $variables = array_flip($variables); $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters); @@ -167,18 +153,18 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa $url = ''; $optional = true; + $message = 'Parameter "{parameter}" for route "{route}" must match "{expected}" ("{given}" given) to generate a corresponding URL.'; foreach ($tokens as $token) { if ('variable' === $token[0]) { if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { // check requirement - if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#', $mergedParams[$token[3]])) { - $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); + if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) { if ($this->strictRequirements) { - throw new InvalidParameterException($message); + throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]))); } if ($this->logger) { - $this->logger->error($message); + $this->logger->error($message, array('parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]])); } return; @@ -220,25 +206,19 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa $referenceType = self::ABSOLUTE_URL; $scheme = current($requiredSchemes); } - } elseif (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) { - // We do this for BC; to be removed if _scheme is not supported anymore - $referenceType = self::ABSOLUTE_URL; - $scheme = $req; } if ($hostTokens) { $routeHost = ''; foreach ($hostTokens as $token) { if ('variable' === $token[0]) { - if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i', $mergedParams[$token[3]])) { - $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); - + if (null !== $this->strictRequirements && !preg_match('#^'.$token[2].'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) { if ($this->strictRequirements) { - throw new InvalidParameterException($message); + throw new InvalidParameterException(strtr($message, array('{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]))); } if ($this->logger) { - $this->logger->error($message); + $this->logger->error($message, array('parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]])); } return; @@ -282,12 +262,27 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa return $a == $b ? 0 : 1; }); - if ($extra && $query = http_build_query($extra, '', '&')) { + // extract fragment + $fragment = ''; + if (isset($defaults['_fragment'])) { + $fragment = $defaults['_fragment']; + } + + if (isset($extra['_fragment'])) { + $fragment = $extra['_fragment']; + unset($extra['_fragment']); + } + + if ($extra && $query = http_build_query($extra, '', '&', PHP_QUERY_RFC3986)) { // "/" and "?" can be left decoded for better user experience, see // http://tools.ietf.org/html/rfc3986#section-3.4 $url .= '?'.strtr($query, array('%2F' => '/')); } + if ('' !== $fragment) { + $url .= '#'.strtr(rawurlencode($fragment), array('%2F' => '/', '%3F' => '?')); + } + return $url; } diff --git a/vendor/symfony/routing/Generator/UrlGeneratorInterface.php b/vendor/symfony/routing/Generator/UrlGeneratorInterface.php index f501ebd9..d6e7938e 100644 --- a/vendor/symfony/routing/Generator/UrlGeneratorInterface.php +++ b/vendor/symfony/routing/Generator/UrlGeneratorInterface.php @@ -69,6 +69,8 @@ interface UrlGeneratorInterface extends RequestContextAwareInterface * * If there is no route with the given name, the generator must throw the RouteNotFoundException. * + * The special parameter _fragment will be used as the document fragment suffixed to the final URL. + * * @param string $name The name of the route * @param mixed $parameters An array of parameters * @param int $referenceType The type of reference to be generated (one of the constants) diff --git a/vendor/symfony/routing/Loader/AnnotationClassLoader.php b/vendor/symfony/routing/Loader/AnnotationClassLoader.php index f175d341..8463673e 100644 --- a/vendor/symfony/routing/Loader/AnnotationClassLoader.php +++ b/vendor/symfony/routing/Loader/AnnotationClassLoader.php @@ -139,7 +139,7 @@ protected function addRoute(RouteCollection $collection, $annot, $globals, \Refl $defaults = array_replace($globals['defaults'], $annot->getDefaults()); foreach ($method->getParameters() as $param) { - if (!isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) { + if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) { $defaults[$param->getName()] = $param->getDefaultValue(); } } @@ -220,11 +220,8 @@ protected function getGlobals(\ReflectionClass $class) ); if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { - // for BC reasons if (null !== $annot->getPath()) { $globals['path'] = $annot->getPath(); - } elseif (null !== $annot->getPattern()) { - $globals['path'] = $annot->getPattern(); } if (null !== $annot->getRequirements()) { diff --git a/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php b/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php index f66b9289..2e9e10d3 100644 --- a/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php +++ b/vendor/symfony/routing/Loader/AnnotationDirectoryLoader.php @@ -38,7 +38,15 @@ public function load($path, $type = null) $collection = new RouteCollection(); $collection->addResource(new DirectoryResource($dir, '/\.php$/')); - $files = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY)); + $files = iterator_to_array(new \RecursiveIteratorIterator( + new \RecursiveCallbackFilterIterator( + new \RecursiveDirectoryIterator($dir), + function (\SplFileInfo $current) { + return '.' !== substr($current->getBasename(), 0, 1); + } + ), + \RecursiveIteratorIterator::LEAVES_ONLY + )); usort($files, function (\SplFileInfo $a, \SplFileInfo $b) { return (string) $a > (string) $b ? 1 : -1; }); diff --git a/vendor/symfony/routing/Loader/AnnotationFileLoader.php b/vendor/symfony/routing/Loader/AnnotationFileLoader.php index b8fc0361..4dc41e16 100644 --- a/vendor/symfony/routing/Loader/AnnotationFileLoader.php +++ b/vendor/symfony/routing/Loader/AnnotationFileLoader.php @@ -92,6 +92,11 @@ protected function findClass($file) $class = false; $namespace = false; $tokens = token_get_all(file_get_contents($file)); + + if (1 === count($tokens) && T_INLINE_HTML === $tokens[0][0]) { + throw new \InvalidArgumentException(sprintf('The file "%s" does not contain PHP code. Did you forgot to add the "getAttribute('id')) || (!$node->hasAttribute('pattern') && !$node->hasAttribute('path'))) { + if ('' === ($id = $node->getAttribute('id')) || !$node->hasAttribute('path')) { throw new \InvalidArgumentException(sprintf('The element in file "%s" must have an "id" and a "path" attribute.', $path)); } - if ($node->hasAttribute('pattern')) { - if ($node->hasAttribute('path')) { - throw new \InvalidArgumentException(sprintf('The element in file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path)); - } - - @trigger_error(sprintf('The "pattern" option in file "%s" is deprecated since version 2.2 and will be removed in 3.0. Use the "path" option in the route definition instead.', $path), E_USER_DEPRECATED); - - $node->setAttribute('path', $node->getAttribute('pattern')); - $node->removeAttribute('pattern'); - } - $schemes = preg_split('/[\s,\|]++/', $node->getAttribute('schemes'), -1, PREG_SPLIT_NO_EMPTY); $methods = preg_split('/[\s,\|]++/', $node->getAttribute('methods'), -1, PREG_SPLIT_NO_EMPTY); list($defaults, $requirements, $options, $condition) = $this->parseConfigs($node, $path); - if (isset($requirements['_method'])) { - if (0 === count($methods)) { - $methods = explode('|', $requirements['_method']); - } - - unset($requirements['_method']); - @trigger_error(sprintf('The "_method" requirement of route "%s" in file "%s" is deprecated since version 2.2 and will be removed in 3.0. Use the "methods" attribute instead.', $id, $path), E_USER_DEPRECATED); - } - - if (isset($requirements['_scheme'])) { - if (0 === count($schemes)) { - $schemes = explode('|', $requirements['_scheme']); - } - - unset($requirements['_scheme']); - @trigger_error(sprintf('The "_scheme" requirement of route "%s" in file "%s" is deprecated since version 2.2 and will be removed in 3.0. Use the "schemes" attribute instead.', $id, $path), E_USER_DEPRECATED); - } - $route = new Route($node->getAttribute('path'), $defaults, $requirements, $options, $node->getAttribute('host'), $schemes, $methods, $condition); $collection->add($id, $route); } @@ -231,12 +202,16 @@ private function parseConfigs(\DOMElement $node, $path) $condition = null; foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) { + if ($node !== $n->parentNode) { + continue; + } + switch ($n->localName) { case 'default': if ($this->isElementValueNull($n)) { $defaults[$n->getAttribute('key')] = null; } else { - $defaults[$n->getAttribute('key')] = trim($n->textContent); + $defaults[$n->getAttribute('key')] = $this->parseDefaultsConfig($n, $path); } break; @@ -257,6 +232,103 @@ private function parseConfigs(\DOMElement $node, $path) return array($defaults, $requirements, $options, $condition); } + /** + * Parses the "default" elements. + * + * @param \DOMElement $element The "default" element to parse + * @param string $path Full path of the XML file being processed + * + * @return array|bool|float|int|string|null The parsed value of the "default" element + */ + private function parseDefaultsConfig(\DOMElement $element, $path) + { + if ($this->isElementValueNull($element)) { + return; + } + + // Check for existing element nodes in the default element. There can + // only be a single element inside a default element. So this element + // (if one was found) can safely be returned. + foreach ($element->childNodes as $child) { + if (!$child instanceof \DOMElement) { + continue; + } + + if (self::NAMESPACE_URI !== $child->namespaceURI) { + continue; + } + + return $this->parseDefaultNode($child, $path); + } + + // If the default element doesn't contain a nested "bool", "int", "float", + // "string", "list", or "map" element, the element contents will be treated + // as the string value of the associated default option. + return trim($element->textContent); + } + + /** + * Recursively parses the value of a "default" element. + * + * @param \DOMElement $node The node value + * @param string $path Full path of the XML file being processed + * + * @return array|bool|float|int|string The parsed value + * + * @throws \InvalidArgumentException when the XML is invalid + */ + private function parseDefaultNode(\DOMElement $node, $path) + { + if ($this->isElementValueNull($node)) { + return; + } + + switch ($node->localName) { + case 'bool': + return 'true' === trim($node->nodeValue) || '1' === trim($node->nodeValue); + case 'int': + return (int) trim($node->nodeValue); + case 'float': + return (float) trim($node->nodeValue); + case 'string': + return trim($node->nodeValue); + case 'list': + $list = array(); + + foreach ($node->childNodes as $element) { + if (!$element instanceof \DOMElement) { + continue; + } + + if (self::NAMESPACE_URI !== $element->namespaceURI) { + continue; + } + + $list[] = $this->parseDefaultNode($element, $path); + } + + return $list; + case 'map': + $map = array(); + + foreach ($node->childNodes as $element) { + if (!$element instanceof \DOMElement) { + continue; + } + + if (self::NAMESPACE_URI !== $element->namespaceURI) { + continue; + } + + $map[$element->getAttribute('key')] = $this->parseDefaultNode($element, $path); + } + + return $map; + default: + throw new \InvalidArgumentException(sprintf('Unknown tag "%s" used in file "%s". Expected "bool", "int", "float", "string", "list", or "map".', $node->localName, $path)); + } + } + private function isElementValueNull(\DOMElement $element) { $namespaceUri = 'http://www.w3.org/2001/XMLSchema-instance'; diff --git a/vendor/symfony/routing/Loader/YamlFileLoader.php b/vendor/symfony/routing/Loader/YamlFileLoader.php index 817714ac..31314011 100644 --- a/vendor/symfony/routing/Loader/YamlFileLoader.php +++ b/vendor/symfony/routing/Loader/YamlFileLoader.php @@ -27,7 +27,7 @@ class YamlFileLoader extends FileLoader { private static $availableKeys = array( - 'resource', 'type', 'prefix', 'pattern', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', + 'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', ); private $yamlParser; @@ -77,17 +77,6 @@ public function load($file, $type = null) } foreach ($parsedConfig as $name => $config) { - if (isset($config['pattern'])) { - if (isset($config['path'])) { - throw new \InvalidArgumentException(sprintf('The file "%s" cannot define both a "path" and a "pattern" attribute. Use only "path".', $path)); - } - - @trigger_error(sprintf('The "pattern" option in file "%s" is deprecated since version 2.2 and will be removed in 3.0. Use the "path" option in the route definition instead.', $path), E_USER_DEPRECATED); - - $config['path'] = $config['pattern']; - unset($config['pattern']); - } - $this->validate($config, $name, $path); if (isset($config['resource'])) { @@ -126,24 +115,6 @@ protected function parseRoute(RouteCollection $collection, $name, array $config, $methods = isset($config['methods']) ? $config['methods'] : array(); $condition = isset($config['condition']) ? $config['condition'] : null; - if (isset($requirements['_method'])) { - if (0 === count($methods)) { - $methods = explode('|', $requirements['_method']); - } - - unset($requirements['_method']); - @trigger_error(sprintf('The "_method" requirement of route "%s" in file "%s" is deprecated since version 2.2 and will be removed in 3.0. Use the "methods" option instead.', $name, $path), E_USER_DEPRECATED); - } - - if (isset($requirements['_scheme'])) { - if (0 === count($schemes)) { - $schemes = explode('|', $requirements['_scheme']); - } - - unset($requirements['_scheme']); - @trigger_error(sprintf('The "_scheme" requirement of route "%s" in file "%s" is deprecated since version 2.2 and will be removed in 3.0. Use the "schemes" option instead.', $name, $path), E_USER_DEPRECATED); - } - $route = new Route($config['path'], $defaults, $requirements, $options, $host, $schemes, $methods, $condition); $collection->add($name, $route); diff --git a/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd b/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd index d40aa422..92d4ae20 100644 --- a/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd +++ b/vendor/symfony/routing/Loader/schema/routing/routing-1.0.xsd @@ -26,7 +26,7 @@ - + @@ -37,8 +37,7 @@ - - + @@ -55,6 +54,18 @@ + + + + + + + + + + + + @@ -62,4 +73,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/routing/Matcher/ApacheUrlMatcher.php b/vendor/symfony/routing/Matcher/ApacheUrlMatcher.php deleted file mode 100644 index c0474f22..00000000 --- a/vendor/symfony/routing/Matcher/ApacheUrlMatcher.php +++ /dev/null @@ -1,124 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Matcher; - -@trigger_error('The '.__NAMESPACE__.'\ApacheUrlMatcher class is deprecated since version 2.5 and will be removed in 3.0. It\'s hard to replicate the behaviour of the PHP implementation and the performance gains are minimal.', E_USER_DEPRECATED); - -use Symfony\Component\Routing\Exception\MethodNotAllowedException; - -/** - * ApacheUrlMatcher matches URL based on Apache mod_rewrite matching (see ApacheMatcherDumper). - * - * @deprecated since version 2.5, to be removed in 3.0. - * The performance gains are minimal and it's very hard to replicate - * the behavior of PHP implementation. - * - * @author Fabien Potencier - * @author Arnaud Le Blanc - */ -class ApacheUrlMatcher extends UrlMatcher -{ - /** - * Tries to match a URL based on Apache mod_rewrite matching. - * - * Returns false if no route matches the URL. - * - * @param string $pathinfo The pathinfo to be parsed - * - * @return array An array of parameters - * - * @throws MethodNotAllowedException If the current method is not allowed - */ - public function match($pathinfo) - { - $parameters = array(); - $defaults = array(); - $allow = array(); - $route = null; - - foreach ($this->denormalizeValues($_SERVER) as $key => $value) { - $name = $key; - - // skip non-routing variables - // this improves performance when $_SERVER contains many usual - // variables like HTTP_*, DOCUMENT_ROOT, REQUEST_URI, ... - if (false === strpos($name, '_ROUTING_')) { - continue; - } - - while (0 === strpos($name, 'REDIRECT_')) { - $name = substr($name, 9); - } - - // expect _ROUTING__ - // or _ROUTING_ - - if (0 !== strpos($name, '_ROUTING_')) { - continue; - } - if (false !== $pos = strpos($name, '_', 9)) { - $type = substr($name, 9, $pos - 9); - $name = substr($name, $pos + 1); - } else { - $type = substr($name, 9); - } - - if ('param' === $type) { - if ('' !== $value) { - $parameters[$name] = $value; - } - } elseif ('default' === $type) { - $defaults[$name] = $value; - } elseif ('route' === $type) { - $route = $value; - } elseif ('allow' === $type) { - $allow[] = $name; - } - - unset($_SERVER[$key]); - } - - if (null !== $route) { - $parameters['_route'] = $route; - - return $this->mergeDefaults($parameters, $defaults); - } elseif (0 < count($allow)) { - throw new MethodNotAllowedException($allow); - } else { - return parent::match($pathinfo); - } - } - - /** - * Denormalizes an array of values. - * - * @param string[] $values - * - * @return array - */ - private function denormalizeValues(array $values) - { - $normalizedValues = array(); - foreach ($values as $key => $value) { - if (preg_match('~^(.*)\[(\d+)\]$~', $key, $matches)) { - if (!isset($normalizedValues[$matches[1]])) { - $normalizedValues[$matches[1]] = array(); - } - $normalizedValues[$matches[1]][(int) $matches[2]] = $value; - } else { - $normalizedValues[$key] = $value; - } - } - - return $normalizedValues; - } -} diff --git a/vendor/symfony/routing/Matcher/Dumper/ApacheMatcherDumper.php b/vendor/symfony/routing/Matcher/Dumper/ApacheMatcherDumper.php deleted file mode 100644 index 1eb51852..00000000 --- a/vendor/symfony/routing/Matcher/Dumper/ApacheMatcherDumper.php +++ /dev/null @@ -1,278 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Routing\Matcher\Dumper; - -@trigger_error('The '.__NAMESPACE__.'\ApacheMatcherDumper class is deprecated since version 2.5 and will be removed in 3.0. It\'s hard to replicate the behaviour of the PHP implementation and the performance gains are minimal.', E_USER_DEPRECATED); - -use Symfony\Component\Routing\Route; - -/** - * Dumps a set of Apache mod_rewrite rules. - * - * @deprecated since version 2.5, to be removed in 3.0. - * The performance gains are minimal and it's very hard to replicate - * the behavior of PHP implementation. - * - * @author Fabien Potencier - * @author Kris Wallsmith - */ -class ApacheMatcherDumper extends MatcherDumper -{ - /** - * Dumps a set of Apache mod_rewrite rules. - * - * Available options: - * - * * script_name: The script name (app.php by default) - * * base_uri: The base URI ("" by default) - * - * @param array $options An array of options - * - * @return string A string to be used as Apache rewrite rules - * - * @throws \LogicException When the route regex is invalid - */ - public function dump(array $options = array()) - { - $options = array_merge(array( - 'script_name' => 'app.php', - 'base_uri' => '', - ), $options); - - $options['script_name'] = self::escape($options['script_name'], ' ', '\\'); - - $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); - $methodVars = array(); - $hostRegexUnique = 0; - $prevHostRegex = ''; - - foreach ($this->getRoutes()->all() as $name => $route) { - if ($route->getCondition()) { - throw new \LogicException(sprintf('Unable to dump the routes for Apache as route "%s" has a condition.', $name)); - } - - $compiledRoute = $route->compile(); - $hostRegex = $compiledRoute->getHostRegex(); - - if (null !== $hostRegex && $prevHostRegex !== $hostRegex) { - $prevHostRegex = $hostRegex; - ++$hostRegexUnique; - - $rule = array(); - - $regex = $this->regexToApacheRegex($hostRegex); - $regex = self::escape($regex, ' ', '\\'); - - $rule[] = sprintf('RewriteCond %%{HTTP:Host} %s', $regex); - - $variables = array(); - $variables[] = sprintf('E=__ROUTING_host_%s:1', $hostRegexUnique); - - foreach ($compiledRoute->getHostVariables() as $i => $variable) { - $variables[] = sprintf('E=__ROUTING_host_%s_%s:%%%d', $hostRegexUnique, $variable, $i + 1); - } - - $variables = implode(',', $variables); - - $rule[] = sprintf('RewriteRule .? - [%s]', $variables); - - $rules[] = implode("\n", $rule); - } - - $rules[] = $this->dumpRoute($name, $route, $options, $hostRegexUnique); - - $methodVars = array_merge($methodVars, $route->getMethods()); - } - if (0 < count($methodVars)) { - $rule = array('# 405 Method Not Allowed'); - $methodVars = array_values(array_unique($methodVars)); - if (in_array('GET', $methodVars) && !in_array('HEAD', $methodVars)) { - $methodVars[] = 'HEAD'; - } - foreach ($methodVars as $i => $methodVar) { - $rule[] = sprintf('RewriteCond %%{ENV:_ROUTING__allow_%s} =1%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : ''); - } - $rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']); - - $rules[] = implode("\n", $rule); - } - - return implode("\n\n", $rules)."\n"; - } - - /** - * Dumps a single route. - * - * @param string $name Route name - * @param Route $route The route - * @param array $options Options - * @param bool $hostRegexUnique Unique identifier for the host regex - * - * @return string The compiled route - */ - private function dumpRoute($name, $route, array $options, $hostRegexUnique) - { - $compiledRoute = $route->compile(); - - // prepare the apache regex - $regex = $this->regexToApacheRegex($compiledRoute->getRegex()); - $regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\'); - - $methods = $this->getRouteMethods($route); - - $hasTrailingSlash = (!$methods || in_array('HEAD', $methods)) && '/$' === substr($regex, -2) && '^/$' !== $regex; - - $variables = array('E=_ROUTING_route:'.$name); - foreach ($compiledRoute->getHostVariables() as $variable) { - $variables[] = sprintf('E=_ROUTING_param_%s:%%{ENV:__ROUTING_host_%s_%s}', $variable, $hostRegexUnique, $variable); - } - foreach ($compiledRoute->getPathVariables() as $i => $variable) { - $variables[] = 'E=_ROUTING_param_'.$variable.':%'.($i + 1); - } - foreach ($this->normalizeValues($route->getDefaults()) as $key => $value) { - $variables[] = 'E=_ROUTING_default_'.$key.':'.strtr($value, array( - ':' => '\\:', - '=' => '\\=', - '\\' => '\\\\', - ' ' => '\\ ', - )); - } - $variables = implode(',', $variables); - - $rule = array("# $name"); - - // method mismatch - if (0 < count($methods)) { - $allow = array(); - foreach ($methods as $method) { - $allow[] = 'E=_ROUTING_allow_'.$method.':1'; - } - - if ($compiledRoute->getHostRegex()) { - $rule[] = sprintf('RewriteCond %%{ENV:__ROUTING_host_%s} =1', $hostRegexUnique); - } - - $rule[] = "RewriteCond %{REQUEST_URI} $regex"; - $rule[] = sprintf('RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]', implode('|', $methods)); - $rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow)); - } - - // redirect with trailing slash appended - if ($hasTrailingSlash) { - if ($compiledRoute->getHostRegex()) { - $rule[] = sprintf('RewriteCond %%{ENV:__ROUTING_host_%s} =1', $hostRegexUnique); - } - - $rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$'; - $rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]'; - } - - // the main rule - - if ($compiledRoute->getHostRegex()) { - $rule[] = sprintf('RewriteCond %%{ENV:__ROUTING_host_%s} =1', $hostRegexUnique); - } - - $rule[] = "RewriteCond %{REQUEST_URI} $regex"; - $rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]"; - - return implode("\n", $rule); - } - - /** - * Returns methods allowed for a route. - * - * @param Route $route The route - * - * @return array The methods - */ - private function getRouteMethods(Route $route) - { - $methods = $route->getMethods(); - - // GET and HEAD are equivalent - if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { - $methods[] = 'HEAD'; - } - - return $methods; - } - - /** - * Converts a regex to make it suitable for mod_rewrite. - * - * @param string $regex The regex - * - * @return string The converted regex - */ - private function regexToApacheRegex($regex) - { - $regexPatternEnd = strrpos($regex, $regex[0]); - - return preg_replace('/\?P<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1)); - } - - /** - * Escapes a string. - * - * @param string $string The string to be escaped - * @param string $char The character to be escaped - * @param string $with The character to be used for escaping - * - * @return string The escaped string - */ - private static function escape($string, $char, $with) - { - $escaped = false; - $output = ''; - foreach (str_split($string) as $symbol) { - if ($escaped) { - $output .= $symbol; - $escaped = false; - continue; - } - if ($symbol === $char) { - $output .= $with.$char; - continue; - } - if ($symbol === $with) { - $escaped = true; - } - $output .= $symbol; - } - - return $output; - } - - /** - * Normalizes an array of values. - * - * @param array $values - * - * @return string[] - */ - private function normalizeValues(array $values) - { - $normalizedValues = array(); - foreach ($values as $key => $value) { - if (is_array($value)) { - foreach ($value as $index => $bit) { - $normalizedValues[sprintf('%s[%s]', $key, $index)] = $bit; - } - } else { - $normalizedValues[$key] = (string) $value; - } - } - - return $normalizedValues; - } -} diff --git a/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php b/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php index aa7df8a7..c04605c3 100644 --- a/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/vendor/symfony/routing/Matcher/Dumper/PhpMatcherDumper.php @@ -223,8 +223,9 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren } $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods)); + $regex = $compiledRoute->getRegex(); - if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P.*?)\$\1#', $compiledRoute->getRegex(), $m)) { + if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P.*?)\$\1#'.(substr($regex, -1) === 'u' ? 'u' : ''), $regex, $m)) { if ($supportsTrailingSlash && substr($m['url'], -1) === '/') { $conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true)); $hasTrailingSlash = true; @@ -236,7 +237,6 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren $conditions[] = sprintf('0 === strpos($pathinfo, %s)', var_export($compiledRoute->getStaticPrefix(), true)); } - $regex = $compiledRoute->getRegex(); if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) { $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2); $hasTrailingSlash = true; diff --git a/vendor/symfony/routing/Route.php b/vendor/symfony/routing/Route.php index fee2002c..69a7cade 100644 --- a/vendor/symfony/routing/Route.php +++ b/vendor/symfony/routing/Route.php @@ -70,6 +70,7 @@ class Route implements \Serializable * Available options: * * * compiler_class: A class name able to compile this route instance (RouteCompiler by default) + * * utf8: Whether UTF-8 matching is enforced ot not * * @param string $path The path pattern to match * @param array $defaults An array of default parameter values @@ -87,14 +88,8 @@ public function __construct($path, array $defaults = array(), array $requirement $this->setRequirements($requirements); $this->setOptions($options); $this->setHost($host); - // The conditions make sure that an initial empty $schemes/$methods does not override the corresponding requirement. - // They can be removed when the BC layer is removed. - if ($schemes) { - $this->setSchemes($schemes); - } - if ($methods) { - $this->setMethods($methods); - } + $this->setSchemes($schemes); + $this->setMethods($methods); $this->setCondition($condition); } @@ -138,38 +133,6 @@ public function unserialize($serialized) } } - /** - * Returns the pattern for the path. - * - * @return string The pattern - * - * @deprecated since version 2.2, to be removed in 3.0. Use getPath instead. - */ - public function getPattern() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED); - - return $this->path; - } - - /** - * Sets the pattern for the path. - * - * This method implements a fluent interface. - * - * @param string $pattern The path pattern - * - * @return $this - * - * @deprecated since version 2.2, to be removed in 3.0. Use setPath instead. - */ - public function setPattern($pattern) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the setPath() method instead.', E_USER_DEPRECATED); - - return $this->setPath($pattern); - } - /** * Returns the pattern for the path. * @@ -250,14 +213,6 @@ public function getSchemes() public function setSchemes($schemes) { $this->schemes = array_map('strtolower', (array) $schemes); - - // this is to keep BC and will be removed in a future version - if ($this->schemes) { - $this->requirements['_scheme'] = implode('|', $this->schemes); - } else { - unset($this->requirements['_scheme']); - } - $this->compiled = null; return $this; @@ -299,14 +254,6 @@ public function getMethods() public function setMethods($methods) { $this->methods = array_map('strtoupper', (array) $methods); - - // this is to keep BC and will be removed in a future version - if ($this->methods) { - $this->requirements['_method'] = implode('|', $this->methods); - } else { - unset($this->requirements['_method']); - } - $this->compiled = null; return $this; @@ -540,12 +487,6 @@ public function addRequirements(array $requirements) */ public function getRequirement($key) { - if ('_scheme' === $key) { - @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getSchemes() instead.', E_USER_DEPRECATED); - } elseif ('_method' === $key) { - @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getMethods() instead.', E_USER_DEPRECATED); - } - return isset($this->requirements[$key]) ? $this->requirements[$key] : null; } @@ -643,17 +584,6 @@ private function sanitizeRequirement($key, $regex) throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key)); } - // this is to keep BC and will be removed in a future version - if ('_scheme' === $key) { - @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setSchemes() method instead.', E_USER_DEPRECATED); - - $this->setSchemes(explode('|', $regex)); - } elseif ('_method' === $key) { - @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setMethods() method instead.', E_USER_DEPRECATED); - - $this->setMethods(explode('|', $regex)); - } - return $regex; } } diff --git a/vendor/symfony/routing/RouteCollectionBuilder.php b/vendor/symfony/routing/RouteCollectionBuilder.php index 2c9e0317..726dfa90 100644 --- a/vendor/symfony/routing/RouteCollectionBuilder.php +++ b/vendor/symfony/routing/RouteCollectionBuilder.php @@ -272,7 +272,6 @@ public function build() $route->setDefaults(array_merge($this->defaults, $route->getDefaults())); $route->setOptions(array_merge($this->options, $route->getOptions())); - // we're extra careful here to avoid re-setting deprecated _method and _scheme foreach ($this->requirements as $key => $val) { if (!$route->hasRequirement($key)) { $route->setRequirement($key, $val); diff --git a/vendor/symfony/routing/RouteCompiler.php b/vendor/symfony/routing/RouteCompiler.php index ba608e7d..aa7a75e0 100644 --- a/vendor/symfony/routing/RouteCompiler.php +++ b/vendor/symfony/routing/RouteCompiler.php @@ -39,9 +39,10 @@ class RouteCompiler implements RouteCompilerInterface /** * {@inheritdoc} * - * @throws \LogicException If a variable is referenced more than once - * @throws \DomainException If a variable name starts with a digit or if it is too long to be successfully used as - * a PCRE subpattern. + * @throws \InvalidArgumentException If a path variable is named _fragment + * @throws \LogicException If a variable is referenced more than once + * @throws \DomainException If a variable name starts with a digit or if it is too long to be successfully used as + * a PCRE subpattern. */ public static function compile(Route $route) { @@ -67,6 +68,13 @@ public static function compile(Route $route) $staticPrefix = $result['staticPrefix']; $pathVariables = $result['variables']; + + foreach ($pathVariables as $pathParam) { + if ('_fragment' === $pathParam) { + throw new \InvalidArgumentException(sprintf('Route pattern "%s" cannot contain "_fragment" as a path parameter.', $route->getPath())); + } + } + $variables = array_merge($variables, $pathVariables); $tokens = $result['tokens']; @@ -91,6 +99,16 @@ private static function compilePattern(Route $route, $pattern, $isHost) $matches = array(); $pos = 0; $defaultSeparator = $isHost ? '.' : '/'; + $useUtf8 = preg_match('//u', $pattern); + $needsUtf8 = $route->getOption('utf8'); + + if (!$needsUtf8 && $useUtf8 && preg_match('/[\x80-\xFF]/', $pattern)) { + $needsUtf8 = true; + @trigger_error(sprintf('Using UTF-8 route patterns without setting the "utf8" option is deprecated since Symfony 3.2 and will throw a LogicException in 4.0. Turn on the "utf8" route option for pattern "%s".', $pattern), E_USER_DEPRECATED); + } + if (!$useUtf8 && $needsUtf8) { + throw new \LogicException(sprintf('Cannot mix UTF-8 requirements with non-UTF-8 pattern "%s".', $pattern)); + } // Match all variables enclosed in "{}" and iterate over them. But we only want to match the innermost variable // in case of nested "{}", e.g. {foo{bar}}. This in ensured because \w does not match "{" or "}" itself. @@ -100,7 +118,15 @@ private static function compilePattern(Route $route, $pattern, $isHost) // get all static text preceding the current variable $precedingText = substr($pattern, $pos, $match[0][1] - $pos); $pos = $match[0][1] + strlen($match[0][0]); - $precedingChar = strlen($precedingText) > 0 ? substr($precedingText, -1) : ''; + + if (!strlen($precedingText)) { + $precedingChar = ''; + } elseif ($useUtf8) { + preg_match('/.$/u', $precedingText, $precedingChar); + $precedingChar = $precedingChar[0]; + } else { + $precedingChar = substr($precedingText, -1); + } $isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar); // A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the @@ -116,8 +142,8 @@ private static function compilePattern(Route $route, $pattern, $isHost) throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern)); } - if ($isSeparator && strlen($precedingText) > 1) { - $tokens[] = array('text', substr($precedingText, 0, -1)); + if ($isSeparator && $precedingText !== $precedingChar) { + $tokens[] = array('text', substr($precedingText, 0, -strlen($precedingChar))); } elseif (!$isSeparator && strlen($precedingText) > 0) { $tokens[] = array('text', $precedingText); } @@ -132,7 +158,7 @@ private static function compilePattern(Route $route, $pattern, $isHost) // If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything. // Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally // part of {_format} when generating the URL, e.g. _format = 'mobile.html'. - $nextSeparator = self::findNextSeparator($followingPattern); + $nextSeparator = self::findNextSeparator($followingPattern, $useUtf8); $regexp = sprintf( '[^%s%s]+', preg_quote($defaultSeparator, self::REGEX_DELIMITER), @@ -146,6 +172,16 @@ private static function compilePattern(Route $route, $pattern, $isHost) // directly adjacent, e.g. '/{x}{y}'. $regexp .= '+'; } + } else { + if (!preg_match('//u', $regexp)) { + $useUtf8 = false; + } elseif (!$needsUtf8 && preg_match('/[\x80-\xFF]|(? 'text' === $tokens[0][0] ? $tokens[0][1] : '', - 'regex' => self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'s'.($isHost ? 'i' : ''), + 'regex' => $regexp, 'tokens' => array_reverse($tokens), 'variables' => $variables, ); @@ -187,19 +234,25 @@ private static function compilePattern(Route $route, $pattern, $isHost) * Returns the next static character in the Route pattern that will serve as a separator. * * @param string $pattern The route pattern + * @param bool $useUtf8 Whether the character is encoded in UTF-8 or not * * @return string The next static character that functions as separator (or empty string when none available) */ - private static function findNextSeparator($pattern) + private static function findNextSeparator($pattern, $useUtf8) { if ('' == $pattern) { // return empty string if pattern is empty or false (false which can be returned by substr) return ''; } // first remove all placeholders from the pattern so we can find the next real static character - $pattern = preg_replace('#\{\w+\}#', '', $pattern); + if ('' === $pattern = preg_replace('#\{\w+\}#', '', $pattern)) { + return ''; + } + if ($useUtf8) { + preg_match('/^./u', $pattern, $pattern); + } - return isset($pattern[0]) && false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : ''; + return false !== strpos(static::SEPARATORS, $pattern[0]) ? $pattern[0] : ''; } /** diff --git a/vendor/symfony/routing/Router.php b/vendor/symfony/routing/Router.php index a04385ea..6ac4205a 100644 --- a/vendor/symfony/routing/Router.php +++ b/vendor/symfony/routing/Router.php @@ -288,32 +288,27 @@ public function getMatcher() return $this->matcher; } - $class = $this->options['matcher_cache_class']; - $baseClass = $this->options['matcher_base_class']; - $expressionLanguageProviders = $this->expressionLanguageProviders; - $that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0. - - $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php', - function (ConfigCacheInterface $cache) use ($that, $class, $baseClass, $expressionLanguageProviders) { - $dumper = $that->getMatcherDumperInstance(); + $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['matcher_cache_class'].'.php', + function (ConfigCacheInterface $cache) { + $dumper = $this->getMatcherDumperInstance(); if (method_exists($dumper, 'addExpressionLanguageProvider')) { - foreach ($expressionLanguageProviders as $provider) { + foreach ($this->expressionLanguageProviders as $provider) { $dumper->addExpressionLanguageProvider($provider); } } $options = array( - 'class' => $class, - 'base_class' => $baseClass, + 'class' => $this->options['matcher_cache_class'], + 'base_class' => $this->options['matcher_base_class'], ); - $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources()); + $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); } ); require_once $cache->getPath(); - return $this->matcher = new $class($this->context); + return $this->matcher = new $this->options['matcher_cache_class']($this->context); } /** @@ -330,25 +325,22 @@ public function getGenerator() if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) { $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger); } else { - $class = $this->options['generator_cache_class']; - $baseClass = $this->options['generator_base_class']; - $that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0. - $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php', - function (ConfigCacheInterface $cache) use ($that, $class, $baseClass) { - $dumper = $that->getGeneratorDumperInstance(); + $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php', + function (ConfigCacheInterface $cache) { + $dumper = $this->getGeneratorDumperInstance(); $options = array( - 'class' => $class, - 'base_class' => $baseClass, + 'class' => $this->options['generator_cache_class'], + 'base_class' => $this->options['generator_base_class'], ); - $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources()); + $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); } ); require_once $cache->getPath(); - $this->generator = new $class($this->context, $this->logger); + $this->generator = new $this->options['generator_cache_class']($this->context, $this->logger); } if ($this->generator instanceof ConfigurableRequirementsInterface) { @@ -364,25 +356,17 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac } /** - * This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0. - * - * @internal - * * @return GeneratorDumperInterface */ - public function getGeneratorDumperInstance() + protected function getGeneratorDumperInstance() { return new $this->options['generator_dumper_class']($this->getRouteCollection()); } /** - * This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0. - * - * @internal - * * @return MatcherDumperInterface */ - public function getMatcherDumperInstance() + protected function getMatcherDumperInstance() { return new $this->options['matcher_dumper_class']($this->getRouteCollection()); } diff --git a/vendor/symfony/routing/composer.json b/vendor/symfony/routing/composer.json index d00ae6d5..156bbecb 100644 --- a/vendor/symfony/routing/composer.json +++ b/vendor/symfony/routing/composer.json @@ -16,19 +16,19 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "require-dev": { - "symfony/config": "~2.7|~3.0.0", - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", + "symfony/config": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", "doctrine/annotations": "~1.0", "doctrine/common": "~2.2", "psr/log": "~1.0" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "suggest": { "symfony/http-foundation": "For using a Symfony Request object", @@ -47,7 +47,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/routing/phpunit.xml.dist b/vendor/symfony/routing/phpunit.xml.dist index b69f066a..bcc09595 100644 --- a/vendor/symfony/routing/phpunit.xml.dist +++ b/vendor/symfony/routing/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/serializer/Annotation/MaxDepth.php b/vendor/symfony/serializer/Annotation/MaxDepth.php new file mode 100644 index 00000000..1f41948d --- /dev/null +++ b/vendor/symfony/serializer/Annotation/MaxDepth.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Annotation; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; + +/** + * Annotation class for @MaxDepth(). + * + * @Annotation + * @Target({"PROPERTY", "METHOD"}) + * + * @author Kévin Dunglas + */ +class MaxDepth +{ + /** + * @var int + */ + private $maxDepth; + + public function __construct(array $data) + { + if (!isset($data['value'])) { + throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" should be set.', get_class($this))); + } + + if (!is_int($data['value']) || $data['value'] <= 0) { + throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be a positive integer.', get_class($this))); + } + + $this->maxDepth = $data['value']; + } + + public function getMaxDepth() + { + return $this->maxDepth; + } +} diff --git a/vendor/symfony/serializer/CHANGELOG.md b/vendor/symfony/serializer/CHANGELOG.md index ceeeeb1e..de24d9ed 100644 --- a/vendor/symfony/serializer/CHANGELOG.md +++ b/vendor/symfony/serializer/CHANGELOG.md @@ -1,6 +1,23 @@ CHANGELOG ========= +3.1.0 +----- + + * added support for serializing objects that implement `JsonSerializable` + * added the `DenormalizerAwareTrait` and `NormalizerAwareTrait` traits to + support normalizer/denormalizer awareness + * added the `DenormalizerAwareInterface` and `NormalizerAwareInterface` + interfaces to support normalizer/denormalizer awareness + * added a PSR-6 compatible adapter for caching metadata + * added a `MaxDepth` option to limit the depth of the object graph when + serializing objects + * added support for serializing `SplFileInfo` objects + * added support for serializing objects that implement `DateTimeInterface` + * added `AbstractObjectNormalizer` as a base class for normalizers that deal + with objects + * added support to relation deserialization + 2.7.0 ----- diff --git a/vendor/symfony/serializer/Encoder/CsvEncoder.php b/vendor/symfony/serializer/Encoder/CsvEncoder.php new file mode 100644 index 00000000..f30d08f9 --- /dev/null +++ b/vendor/symfony/serializer/Encoder/CsvEncoder.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Encoder; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; + +/** + * Encodes CSV data. + * + * @author Kévin Dunglas + */ +class CsvEncoder implements EncoderInterface, DecoderInterface +{ + const FORMAT = 'csv'; + + private $delimiter; + private $enclosure; + private $escapeChar; + private $keySeparator; + + /** + * @param string $delimiter + * @param string $enclosure + * @param string $escapeChar + * @param string $keySeparator + */ + public function __construct($delimiter = ',', $enclosure = '"', $escapeChar = '\\', $keySeparator = '.') + { + $this->delimiter = $delimiter; + $this->enclosure = $enclosure; + $this->escapeChar = $escapeChar; + $this->keySeparator = $keySeparator; + } + + /** + * {@inheritdoc} + */ + public function encode($data, $format, array $context = array()) + { + $handle = fopen('php://temp,', 'w+'); + + if (!is_array($data)) { + $data = array(array($data)); + } elseif (empty($data)) { + $data = array(array()); + } else { + // Sequential arrays of arrays are considered as collections + $i = 0; + foreach ($data as $key => $value) { + if ($i !== $key || !is_array($value)) { + $data = array($data); + break; + } + + ++$i; + } + } + + $headers = null; + foreach ($data as $value) { + $result = array(); + $this->flatten($value, $result); + + if (null === $headers) { + $headers = array_keys($result); + fputcsv($handle, $headers, $this->delimiter, $this->enclosure, $this->escapeChar); + } elseif (array_keys($result) !== $headers) { + throw new InvalidArgumentException('To use the CSV encoder, each line in the data array must have the same structure. You may want to use a custom normalizer class to normalize the data format before passing it to the CSV encoder.'); + } + + fputcsv($handle, $result, $this->delimiter, $this->enclosure, $this->escapeChar); + } + + rewind($handle); + $value = stream_get_contents($handle); + fclose($handle); + + return $value; + } + + /** + * {@inheritdoc} + */ + public function supportsEncoding($format) + { + return self::FORMAT === $format; + } + + /** + * {@inheritdoc} + */ + public function decode($data, $format, array $context = array()) + { + $handle = fopen('php://temp', 'r+'); + fwrite($handle, $data); + rewind($handle); + + $headers = null; + $nbHeaders = 0; + $result = array(); + + while (false !== ($cols = fgetcsv($handle, 0, $this->delimiter, $this->enclosure, $this->escapeChar))) { + $nbCols = count($cols); + + if (null === $headers) { + $nbHeaders = $nbCols; + + foreach ($cols as $col) { + $headers[] = explode($this->keySeparator, $col); + } + + continue; + } + + $item = array(); + for ($i = 0; ($i < $nbCols) && ($i < $nbHeaders); ++$i) { + $depth = count($headers[$i]); + $arr = &$item; + for ($j = 0; $j < $depth; ++$j) { + // Handle nested arrays + if ($j === ($depth - 1)) { + $arr[$headers[$i][$j]] = $cols[$i]; + + continue; + } + + if (!isset($arr[$headers[$i][$j]])) { + $arr[$headers[$i][$j]] = array(); + } + + $arr = &$arr[$headers[$i][$j]]; + } + } + + $result[] = $item; + } + fclose($handle); + + if (empty($result) || isset($result[1])) { + return $result; + } + + // If there is only one data line in the document, return it (the line), the result is not considered as a collection + return $result[0]; + } + + /** + * {@inheritdoc} + */ + public function supportsDecoding($format) + { + return self::FORMAT === $format; + } + + /** + * Flattens an array and generates keys including the path. + * + * @param array $array + * @param array $result + * @param string $parentKey + */ + private function flatten(array $array, array &$result, $parentKey = '') + { + foreach ($array as $key => $value) { + if (is_array($value)) { + $this->flatten($value, $result, $parentKey.$key.$this->keySeparator); + } else { + $result[$parentKey.$key] = $value; + } + } + } +} diff --git a/vendor/symfony/serializer/Encoder/JsonDecode.php b/vendor/symfony/serializer/Encoder/JsonDecode.php index 8925ec36..e9ca7ce5 100644 --- a/vendor/symfony/serializer/Encoder/JsonDecode.php +++ b/vendor/symfony/serializer/Encoder/JsonDecode.php @@ -50,22 +50,6 @@ public function __construct($associative = false, $depth = 512) $this->recursionDepth = (int) $depth; } - /** - * Returns the last decoding error (if any). - * - * @return int - * - * @deprecated since version 2.5, to be removed in 3.0. - * The {@self decode()} method throws an exception if error found. - * @see http://php.net/manual/en/function.json-last-error.php json_last_error - */ - public function getLastError() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Catch the exception raised by the decode() method instead to get the last JSON decoding error.', E_USER_DEPRECATED); - - return $this->lastError; - } - /** * Decodes data. * @@ -101,11 +85,7 @@ public function decode($data, $format, array $context = array()) $recursionDepth = $context['json_decode_recursion_depth']; $options = $context['json_decode_options']; - if (PHP_VERSION_ID >= 50400) { - $decodedData = json_decode($data, $associative, $recursionDepth, $options); - } else { - $decodedData = json_decode($data, $associative, $recursionDepth); - } + $decodedData = json_decode($data, $associative, $recursionDepth, $options); if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) { throw new UnexpectedValueException(json_last_error_msg()); diff --git a/vendor/symfony/serializer/Encoder/JsonEncode.php b/vendor/symfony/serializer/Encoder/JsonEncode.php index 454c0d6a..14cd2c94 100644 --- a/vendor/symfony/serializer/Encoder/JsonEncode.php +++ b/vendor/symfony/serializer/Encoder/JsonEncode.php @@ -28,22 +28,6 @@ public function __construct($bitmask = 0) $this->options = $bitmask; } - /** - * Returns the last encoding error (if any). - * - * @return int - * - * @deprecated since version 2.5, to be removed in 3.0. - * The {@self encode()} throws an exception if error found. - * @see http://php.net/manual/en/function.json-last-error.php json_last_error - */ - public function getLastError() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Catch the exception raised by the encode() method instead to get the last JSON encoding error.', E_USER_DEPRECATED); - - return $this->lastError; - } - /** * Encodes PHP data to a JSON string. * diff --git a/vendor/symfony/serializer/Encoder/JsonEncoder.php b/vendor/symfony/serializer/Encoder/JsonEncoder.php index 159d4358..44a086d6 100644 --- a/vendor/symfony/serializer/Encoder/JsonEncoder.php +++ b/vendor/symfony/serializer/Encoder/JsonEncoder.php @@ -36,34 +36,6 @@ public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodin $this->decodingImpl = $decodingImpl ?: new JsonDecode(true); } - /** - * Returns the last encoding error (if any). - * - * @return int - * - * @deprecated since version 2.5, to be removed in 3.0. JsonEncode throws exception if an error is found. - */ - public function getLastEncodingError() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Catch the exception raised by the Symfony\Component\Serializer\Encoder\JsonEncode::encode() method instead to get the last JSON encoding error.', E_USER_DEPRECATED); - - return $this->encodingImpl->getLastError(); - } - - /** - * Returns the last decoding error (if any). - * - * @return int - * - * @deprecated since version 2.5, to be removed in 3.0. JsonDecode throws exception if an error is found. - */ - public function getLastDecodingError() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Catch the exception raised by the Symfony\Component\Serializer\Encoder\JsonDecode::decode() method instead to get the last JSON decoding error.', E_USER_DEPRECATED); - - return $this->decodingImpl->getLastError(); - } - /** * {@inheritdoc} */ @@ -95,18 +67,4 @@ public function supportsDecoding($format) { return self::FORMAT === $format; } - - /** - * Resolves json_last_error message. - * - * @return string - * - * @deprecated since 2.8, to be removed in 3.0. Use json_last_error_msg() instead. - */ - public static function getLastErrorMessage() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use json_last_error_msg() instead.', E_USER_DEPRECATED); - - return json_last_error_msg(); - } } diff --git a/vendor/symfony/serializer/Encoder/SerializerAwareEncoder.php b/vendor/symfony/serializer/Encoder/SerializerAwareEncoder.php index a3d8ff38..873af922 100644 --- a/vendor/symfony/serializer/Encoder/SerializerAwareEncoder.php +++ b/vendor/symfony/serializer/Encoder/SerializerAwareEncoder.php @@ -11,23 +11,17 @@ namespace Symfony\Component\Serializer\Encoder; -use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Serializer\SerializerAwareInterface; +use Symfony\Component\Serializer\SerializerAwareTrait; /** * SerializerAware Encoder implementation. * * @author Jordi Boggiano + * + * @deprecated since version 3.2, to be removed in 4.0. Use the SerializerAwareTrait instead. */ abstract class SerializerAwareEncoder implements SerializerAwareInterface { - protected $serializer; - - /** - * {@inheritdoc} - */ - public function setSerializer(SerializerInterface $serializer) - { - $this->serializer = $serializer; - } + use SerializerAwareTrait; } diff --git a/vendor/symfony/serializer/Encoder/XmlEncoder.php b/vendor/symfony/serializer/Encoder/XmlEncoder.php index 671ab978..ad058118 100644 --- a/vendor/symfony/serializer/Encoder/XmlEncoder.php +++ b/vendor/symfony/serializer/Encoder/XmlEncoder.php @@ -30,15 +30,18 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec private $format; private $context; private $rootNodeName = 'response'; + private $loadOptions; /** * Construct new XmlEncoder and allow to change the root node element name. * - * @param string $rootNodeName + * @param string $rootNodeName + * @param int|null $loadOptions A bit field of LIBXML_* constants */ - public function __construct($rootNodeName = 'response') + public function __construct($rootNodeName = 'response', $loadOptions = null) { $this->rootNodeName = $rootNodeName; + $this->loadOptions = null !== $loadOptions ? $loadOptions : LIBXML_NONET | LIBXML_NOBLANKS; } /** @@ -81,7 +84,7 @@ public function decode($data, $format, array $context = array()) libxml_clear_errors(); $dom = new \DOMDocument(); - $dom->loadXML($data, LIBXML_NONET | LIBXML_NOBLANKS); + $dom->loadXML($data, $this->loadOptions); libxml_use_internal_errors($internalErrors); libxml_disable_entity_loader($disableEntities); @@ -92,14 +95,16 @@ public function decode($data, $format, array $context = array()) throw new UnexpectedValueException($error->message); } + $rootNode = null; foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { throw new UnexpectedValueException('Document types are not allowed.'); } + if (!$rootNode && $child->nodeType !== XML_PI_NODE) { + $rootNode = $child; + } } - $rootNode = $dom->firstChild; - // todo: throw an exception if the root node name is not correctly configured (bc) if ($rootNode->hasChildNodes()) { @@ -299,11 +304,19 @@ private function parseXmlAttributes(\DOMNode $node) $data = array(); foreach ($node->attributes as $attr) { - if (ctype_digit($attr->nodeValue)) { - $data['@'.$attr->nodeName] = (int) $attr->nodeValue; - } else { + if (!is_numeric($attr->nodeValue)) { $data['@'.$attr->nodeName] = $attr->nodeValue; + + continue; } + + if (false !== $val = filter_var($attr->nodeValue, FILTER_VALIDATE_INT)) { + $data['@'.$attr->nodeName] = $val; + + continue; + } + + $data['@'.$attr->nodeName] = (float) $attr->nodeValue; } return $data; @@ -329,6 +342,10 @@ private function parseXmlValue(\DOMNode $node) $value = array(); foreach ($node->childNodes as $subnode) { + if ($subnode->nodeType === XML_PI_NODE) { + continue; + } + $val = $this->parseXml($subnode); if ('item' === $subnode->nodeName && isset($val['@key'])) { @@ -369,7 +386,10 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) if (is_array($data) || ($data instanceof \Traversable && !$this->serializer->supportsNormalization($data, $this->format))) { foreach ($data as $key => $data) { //Ah this is the magic @ attribute types. - if (0 === strpos($key, '@') && is_scalar($data) && $this->isElementNameValid($attributeName = substr($key, 1))) { + if (0 === strpos($key, '@') && $this->isElementNameValid($attributeName = substr($key, 1))) { + if (!is_scalar($data)) { + $data = $this->serializer->normalize($data, $this->format, $this->context); + } $parentNode->setAttribute($attributeName, $data); } elseif ($key === '#') { $append = $this->selectNodeType($parentNode, $data); @@ -451,7 +471,7 @@ private function appendNode(\DOMNode $parentNode, $data, $nodeName, $key = null) */ private function needsCdataWrapping($val) { - return preg_match('/[<>&]/', $val); + return 0 < preg_match('/[<>&]/', $val); } /** @@ -474,7 +494,7 @@ private function selectNodeType(\DOMNode $node, $val) } elseif ($val instanceof \Traversable) { $this->buildXml($node, $val); } elseif (is_object($val)) { - return $this->buildXml($node, $this->serializer->normalize($val, $this->format, $this->context)); + return $this->selectNodeType($node, $this->serializer->normalize($val, $this->format, $this->context)); } elseif (is_numeric($val)) { return $this->appendText($node, (string) $val); } elseif (is_string($val) && $this->needsCdataWrapping($val)) { diff --git a/vendor/symfony/serializer/Encoder/YamlEncoder.php b/vendor/symfony/serializer/Encoder/YamlEncoder.php new file mode 100644 index 00000000..41ac04f2 --- /dev/null +++ b/vendor/symfony/serializer/Encoder/YamlEncoder.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Encoder; + +use Symfony\Component\Yaml\Dumper; +use Symfony\Component\Yaml\Parser; + +/** + * Encodes YAML data. + * + * @author Kévin Dunglas + */ +class YamlEncoder implements EncoderInterface, DecoderInterface +{ + const FORMAT = 'yaml'; + + private $dumper; + private $parser; + private $defaultContext = array('yaml_inline' => 0, 'yaml_indent' => 0, 'yaml_flags' => 0); + + public function __construct(Dumper $dumper = null, Parser $parser = null, array $defaultContext = array()) + { + $this->dumper = $dumper ?: new Dumper(); + $this->parser = $parser ?: new Parser(); + $this->defaultContext = array_merge($this->defaultContext, $defaultContext); + } + + /** + * {@inheritdoc} + */ + public function encode($data, $format, array $context = array()) + { + $context = array_merge($this->defaultContext, $context); + + return $this->dumper->dump($data, $context['yaml_inline'], $context['yaml_indent'], $context['yaml_flags']); + } + + /** + * {@inheritdoc} + */ + public function supportsEncoding($format) + { + return self::FORMAT === $format; + } + + /** + * {@inheritdoc} + */ + public function decode($data, $format, array $context = array()) + { + $context = array_merge($this->defaultContext, $context); + + return $this->parser->parse($data, $context['yaml_flags']); + } + + /** + * {@inheritdoc} + */ + public function supportsDecoding($format) + { + return self::FORMAT === $format; + } +} diff --git a/vendor/symfony/serializer/Exception/Exception.php b/vendor/symfony/serializer/Exception/Exception.php deleted file mode 100644 index fc0606e2..00000000 --- a/vendor/symfony/serializer/Exception/Exception.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Serializer\Exception; - -/** - * Base exception. - * - * @deprecated since version 2.7, to be removed in 3.0. Use ExceptionInterface instead. - */ -interface Exception -{ -} diff --git a/vendor/symfony/serializer/Exception/ExceptionInterface.php b/vendor/symfony/serializer/Exception/ExceptionInterface.php index ff67edbb..99ed6324 100644 --- a/vendor/symfony/serializer/Exception/ExceptionInterface.php +++ b/vendor/symfony/serializer/Exception/ExceptionInterface.php @@ -16,6 +16,6 @@ * * @author Johannes M. Schmitt */ -interface ExceptionInterface extends Exception +interface ExceptionInterface { } diff --git a/vendor/symfony/serializer/Mapping/AttributeMetadata.php b/vendor/symfony/serializer/Mapping/AttributeMetadata.php index 7a1d3db9..b9daf5d2 100644 --- a/vendor/symfony/serializer/Mapping/AttributeMetadata.php +++ b/vendor/symfony/serializer/Mapping/AttributeMetadata.php @@ -36,6 +36,15 @@ class AttributeMetadata implements AttributeMetadataInterface */ public $groups = array(); + /** + * @var int|null + * + * @internal This property is public in order to reduce the size of the + * class' serialized representation. Do not access it. Use + * {@link getMaxDepth()} instead. + */ + public $maxDepth; + /** * Constructs a metadata for the given attribute. * @@ -72,6 +81,22 @@ public function getGroups() return $this->groups; } + /** + * {@inheritdoc} + */ + public function setMaxDepth($maxDepth) + { + $this->maxDepth = $maxDepth; + } + + /** + * {@inheritdoc} + */ + public function getMaxDepth() + { + return $this->maxDepth; + } + /** * {@inheritdoc} */ @@ -80,6 +105,11 @@ public function merge(AttributeMetadataInterface $attributeMetadata) foreach ($attributeMetadata->getGroups() as $group) { $this->addGroup($group); } + + // Overwrite only if not defined + if (null === $this->maxDepth) { + $this->maxDepth = $attributeMetadata->getMaxDepth(); + } } /** @@ -89,6 +119,6 @@ public function merge(AttributeMetadataInterface $attributeMetadata) */ public function __sleep() { - return array('name', 'groups'); + return array('name', 'groups', 'maxDepth'); } } diff --git a/vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php b/vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php index 6bb30274..abba8c19 100644 --- a/vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php +++ b/vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php @@ -43,6 +43,20 @@ public function addGroup($group); */ public function getGroups(); + /** + * Sets the serialization max depth for this attribute. + * + * @param int|null $maxDepth + */ + public function setMaxDepth($maxDepth); + + /** + * Gets the serialization max depth for this attribute. + * + * @return int|null + */ + public function getMaxDepth(); + /** * Merges an {@see AttributeMetadataInterface} with in the current one. * diff --git a/vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php b/vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php new file mode 100644 index 00000000..0b904c14 --- /dev/null +++ b/vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Mapping\Factory; + +use Psr\Cache\CacheItemPoolInterface; + +/** + * Caches metadata using a PSR-6 implementation. + * + * @author Kévin Dunglas + */ +class CacheClassMetadataFactory implements ClassMetadataFactoryInterface +{ + use ClassResolverTrait; + + /** + * @var ClassMetadataFactoryInterface + */ + private $decorated; + + /** + * @var CacheItemPoolInterface + */ + private $cacheItemPool; + + public function __construct(ClassMetadataFactoryInterface $decorated, CacheItemPoolInterface $cacheItemPool) + { + $this->decorated = $decorated; + $this->cacheItemPool = $cacheItemPool; + } + + /** + * {@inheritdoc} + */ + public function getMetadataFor($value) + { + $class = $this->getClass($value); + // Key cannot contain backslashes according to PSR-6 + $key = strtr($class, '\\', '_'); + + $item = $this->cacheItemPool->getItem($key); + if ($item->isHit()) { + return $item->get(); + } + + $metadata = $this->decorated->getMetadataFor($value); + $this->cacheItemPool->save($item->set($metadata)); + + return $metadata; + } + + /** + * {@inheritdoc} + */ + public function hasMetadataFor($value) + { + return $this->decorated->hasMetadataFor($value); + } +} diff --git a/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php b/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php index 601342ee..6604430d 100644 --- a/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php +++ b/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php @@ -23,6 +23,8 @@ */ class ClassMetadataFactory implements ClassMetadataFactoryInterface { + use ClassResolverTrait; + /** * @var LoaderInterface */ @@ -46,6 +48,10 @@ public function __construct(LoaderInterface $loader, Cache $cache = null) { $this->loader = $loader; $this->cache = $cache; + + if (null !== $cache) { + @trigger_error(sprintf('Passing a Doctrine Cache instance as 2nd parameter of the "%s" constructor is deprecated since version 3.1. This parameter will be removed in Symfony 4.0. Use the "%s" class instead.', __CLASS__, CacheClassMetadataFactory::class), E_USER_DEPRECATED); + } } /** @@ -54,9 +60,6 @@ public function __construct(LoaderInterface $loader, Cache $cache = null) public function getMetadataFor($value) { $class = $this->getClass($value); - if (!$class) { - throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', gettype($value))); - } if (isset($this->loadedClasses[$class])) { return $this->loadedClasses[$class]; @@ -66,10 +69,6 @@ public function getMetadataFor($value) return $this->loadedClasses[$class]; } - if (!class_exists($class) && !interface_exists($class)) { - throw new InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $class)); - } - $classMetadata = new ClassMetadata($class); $this->loader->loadClassMetadata($classMetadata); @@ -97,24 +96,14 @@ public function getMetadataFor($value) */ public function hasMetadataFor($value) { - $class = $this->getClass($value); - - return class_exists($class) || interface_exists($class); - } + try { + $this->getClass($value); - /** - * Gets a class name for a given class or instance. - * - * @param mixed $value - * - * @return string|bool - */ - private function getClass($value) - { - if (!is_object($value) && !is_string($value)) { - return false; + return true; + } catch (InvalidArgumentException $invalidArgumentException) { + // Return false in case of exception } - return ltrim(is_object($value) ? get_class($value) : $value, '\\'); + return false; } } diff --git a/vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.php b/vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.php new file mode 100644 index 00000000..e93277a6 --- /dev/null +++ b/vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Mapping\Factory; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; + +/** + * Resolves a class name. + * + * @internal + * + * @author Kévin Dunglas + */ +trait ClassResolverTrait +{ + /** + * Gets a class name for a given class or instance. + * + * @param mixed $value + * + * @return string + * + * @throws InvalidArgumentException If the class does not exists + */ + private function getClass($value) + { + if (is_string($value)) { + if (!class_exists($value) && !interface_exists($value)) { + throw new InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $value)); + } + + return ltrim($value, '\\'); + } + + if (!is_object($value)) { + throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', gettype($value))); + } + + return get_class($value); + } +} diff --git a/vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php b/vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php index 6c563b44..4495f0d5 100644 --- a/vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php +++ b/vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php @@ -13,6 +13,7 @@ use Doctrine\Common\Annotations\Reader; use Symfony\Component\Serializer\Annotation\Groups; +use Symfony\Component\Serializer\Annotation\MaxDepth; use Symfony\Component\Serializer\Exception\MappingException; use Symfony\Component\Serializer\Mapping\AttributeMetadata; use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; @@ -55,11 +56,13 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) } if ($property->getDeclaringClass()->name === $className) { - foreach ($this->reader->getPropertyAnnotations($property) as $groups) { - if ($groups instanceof Groups) { - foreach ($groups->getGroups() as $group) { + foreach ($this->reader->getPropertyAnnotations($property) as $annotation) { + if ($annotation instanceof Groups) { + foreach ($annotation->getGroups() as $group) { $attributesMetadata[$property->name]->addGroup($group); } + } elseif ($annotation instanceof MaxDepth) { + $attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth()); } $loaded = true; @@ -68,29 +71,40 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) } foreach ($reflectionClass->getMethods() as $method) { - if ($method->getDeclaringClass()->name === $className) { - foreach ($this->reader->getMethodAnnotations($method) as $groups) { - if ($groups instanceof Groups) { - if (preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches)) { - $attributeName = lcfirst($matches[2]); - - if (isset($attributesMetadata[$attributeName])) { - $attributeMetadata = $attributesMetadata[$attributeName]; - } else { - $attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName); - $classMetadata->addAttributeMetadata($attributeMetadata); - } - - foreach ($groups->getGroups() as $group) { - $attributeMetadata->addGroup($group); - } - } else { - throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); - } + if ($method->getDeclaringClass()->name !== $className) { + continue; + } + + $accessorOrMutator = preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches); + if ($accessorOrMutator) { + $attributeName = lcfirst($matches[2]); + + if (isset($attributesMetadata[$attributeName])) { + $attributeMetadata = $attributesMetadata[$attributeName]; + } else { + $attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName); + $classMetadata->addAttributeMetadata($attributeMetadata); + } + } + + foreach ($this->reader->getMethodAnnotations($method) as $annotation) { + if ($annotation instanceof Groups) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); } - $loaded = true; + foreach ($annotation->getGroups() as $group) { + $attributeMetadata->addGroup($group); + } + } elseif ($annotation instanceof MaxDepth) { + if (!$accessorOrMutator) { + throw new MappingException(sprintf('MaxDepth on "%s::%s" cannot be added. MaxDepth can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name)); + } + + $attributeMetadata->setMaxDepth($annotation->getMaxDepth()); } + + $loaded = true; } } diff --git a/vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php b/vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php index 0da2f7d6..76d06432 100644 --- a/vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php +++ b/vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php @@ -36,12 +36,11 @@ class XmlFileLoader extends FileLoader public function loadClassMetadata(ClassMetadataInterface $classMetadata) { if (null === $this->classes) { - $this->classes = array(); - $xml = $this->parseFile($this->file); + $this->classes = $this->getClassesFromXml(); + } - foreach ($xml->class as $class) { - $this->classes[(string) $class['name']] = $class; - } + if (!$this->classes) { + return false; } $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -62,6 +61,10 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) foreach ($attribute->group as $group) { $attributeMetadata->addGroup((string) $group); } + + if (isset($attribute['max-depth'])) { + $attributeMetadata->setMaxDepth((int) $attribute['max-depth']); + } } return true; @@ -70,6 +73,20 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) return false; } + /** + * Return the names of the classes mapped in this file. + * + * @return string[] The classes names + */ + public function getMappedClasses() + { + if (null === $this->classes) { + $this->classes = $this->getClassesFromXml(); + } + + return array_keys($this->classes); + } + /** * Parses a XML File. * @@ -89,4 +106,16 @@ private function parseFile($file) return simplexml_import_dom($dom); } + + private function getClassesFromXml() + { + $xml = $this->parseFile($this->file); + $classes = array(); + + foreach ($xml->class as $class) { + $classes[(string) $class['name']] = $class; + } + + return $classes; + } } diff --git a/vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php b/vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php index ebe2a6e4..e3afa476 100644 --- a/vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php +++ b/vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php @@ -38,61 +38,91 @@ class YamlFileLoader extends FileLoader public function loadClassMetadata(ClassMetadataInterface $classMetadata) { if (null === $this->classes) { - if (!stream_is_local($this->file)) { - throw new MappingException(sprintf('This is not a local file "%s".', $this->file)); - } - - if (null === $this->yamlParser) { - $this->yamlParser = new Parser(); - } - - $classes = $this->yamlParser->parse(file_get_contents($this->file)); - - if (empty($classes)) { - return false; - } + $this->classes = $this->getClassesFromYaml(); + } - // not an array - if (!is_array($classes)) { - throw new MappingException(sprintf('The file "%s" must contain a YAML array.', $this->file)); - } + if (!$this->classes) { + return false; + } - $this->classes = $classes; + if (!isset($this->classes[$classMetadata->getName()])) { + return false; } - if (isset($this->classes[$classMetadata->getName()])) { - $yaml = $this->classes[$classMetadata->getName()]; + $yaml = $this->classes[$classMetadata->getName()]; - if (isset($yaml['attributes']) && is_array($yaml['attributes'])) { - $attributesMetadata = $classMetadata->getAttributesMetadata(); + if (isset($yaml['attributes']) && is_array($yaml['attributes'])) { + $attributesMetadata = $classMetadata->getAttributesMetadata(); - foreach ($yaml['attributes'] as $attribute => $data) { - if (isset($attributesMetadata[$attribute])) { - $attributeMetadata = $attributesMetadata[$attribute]; - } else { - $attributeMetadata = new AttributeMetadata($attribute); - $classMetadata->addAttributeMetadata($attributeMetadata); + foreach ($yaml['attributes'] as $attribute => $data) { + if (isset($attributesMetadata[$attribute])) { + $attributeMetadata = $attributesMetadata[$attribute]; + } else { + $attributeMetadata = new AttributeMetadata($attribute); + $classMetadata->addAttributeMetadata($attributeMetadata); + } + + if (isset($data['groups'])) { + if (!is_array($data['groups'])) { + throw new MappingException(sprintf('The "groups" key must be an array of strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); } - if (isset($data['groups'])) { - if (!is_array($data['groups'])) { - throw new MappingException('The "groups" key must be an array of strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()); + foreach ($data['groups'] as $group) { + if (!is_string($group)) { + throw new MappingException(sprintf('Group names must be strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); } - foreach ($data['groups'] as $group) { - if (!is_string($group)) { - throw new MappingException('Group names must be strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()); - } + $attributeMetadata->addGroup($group); + } + } - $attributeMetadata->addGroup($group); - } + if (isset($data['max_depth'])) { + if (!is_int($data['max_depth'])) { + throw new MappingException(sprintf('The "max_depth" value must be an integer in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); } + + $attributeMetadata->setMaxDepth($data['max_depth']); } } + } + + return true; + } + + /** + * Return the names of the classes mapped in this file. + * + * @return string[] The classes names + */ + public function getMappedClasses() + { + if (null === $this->classes) { + $this->classes = $this->getClassesFromYaml(); + } + + return array_keys($this->classes); + } + + private function getClassesFromYaml() + { + if (!stream_is_local($this->file)) { + throw new MappingException(sprintf('This is not a local file "%s".', $this->file)); + } + + if (null === $this->yamlParser) { + $this->yamlParser = new Parser(); + } + + $classes = $this->yamlParser->parse(file_get_contents($this->file)); + + if (empty($classes)) { + return array(); + } - return true; + if (!is_array($classes)) { + throw new MappingException(sprintf('The file "%s" must contain a YAML array.', $this->file)); } - return false; + return $classes; } } diff --git a/vendor/symfony/serializer/Mapping/Loader/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd b/vendor/symfony/serializer/Mapping/Loader/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd index cd5a9a9f..afa8b921 100644 --- a/vendor/symfony/serializer/Mapping/Loader/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd +++ b/vendor/symfony/serializer/Mapping/Loader/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd @@ -44,13 +44,20 @@ - + + + + + + + + diff --git a/vendor/symfony/serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php b/vendor/symfony/serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php index d3daf12e..508881e8 100644 --- a/vendor/symfony/serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php +++ b/vendor/symfony/serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php @@ -44,14 +44,15 @@ public function __construct(array $attributes = null, $lowerCamelCase = true) public function normalize($propertyName) { if (null === $this->attributes || in_array($propertyName, $this->attributes)) { + $lcPropertyName = lcfirst($propertyName); $snakeCasedName = ''; - $len = strlen($propertyName); + $len = strlen($lcPropertyName); for ($i = 0; $i < $len; ++$i) { - if (ctype_upper($propertyName[$i])) { - $snakeCasedName .= '_'.strtolower($propertyName[$i]); + if (ctype_upper($lcPropertyName[$i])) { + $snakeCasedName .= '_'.strtolower($lcPropertyName[$i]); } else { - $snakeCasedName .= strtolower($propertyName[$i]); + $snakeCasedName .= strtolower($lcPropertyName[$i]); } } @@ -75,7 +76,7 @@ public function denormalize($propertyName) } if (null === $this->attributes || in_array($camelCasedName, $this->attributes)) { - return $this->lowerCamelCase ? lcfirst($camelCasedName) : $camelCasedName; + return $camelCasedName; } return $propertyName; diff --git a/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php b/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php index 63bfb871..8f5d2099 100644 --- a/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php @@ -17,15 +17,15 @@ use Symfony\Component\Serializer\Exception\RuntimeException; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; -use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; +use Symfony\Component\Serializer\SerializerAwareInterface; /** * Normalizer implementation. * * @author Kévin Dunglas */ -abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface +abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface { const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit'; const OBJECT_TO_POPULATE = 'object_to_populate'; @@ -98,15 +98,9 @@ public function setCircularReferenceLimit($circularReferenceLimit) * @param callable $circularReferenceHandler * * @return self - * - * @throws InvalidArgumentException */ - public function setCircularReferenceHandler($circularReferenceHandler) + public function setCircularReferenceHandler(callable $circularReferenceHandler) { - if (!is_callable($circularReferenceHandler)) { - throw new InvalidArgumentException('The given circular reference handler is not callable.'); - } - $this->circularReferenceHandler = $circularReferenceHandler; return $this; @@ -150,37 +144,6 @@ public function setIgnoredAttributes(array $ignoredAttributes) return $this; } - /** - * Set attributes to be camelized on denormalize. - * - * @deprecated Deprecated since version 2.7, to be removed in 3.0. Use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter instead. - * - * @param array $camelizedAttributes - * - * @return self - * - * @throws LogicException - */ - public function setCamelizedAttributes(array $camelizedAttributes) - { - @trigger_error(sprintf('%s is deprecated since version 2.7 and will be removed in 3.0. Use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter instead.', __METHOD__), E_USER_DEPRECATED); - - if ($this->nameConverter && !$this->nameConverter instanceof CamelCaseToSnakeCaseNameConverter) { - throw new LogicException(sprintf('%s cannot be called if a custom Name Converter is defined.', __METHOD__)); - } - - $attributes = array(); - foreach ($camelizedAttributes as $camelizedAttribute) { - $attributes[] = lcfirst(preg_replace_callback('/(^|_|\.)+(.)/', function ($match) { - return ('.' === $match[1] ? '_' : '').strtoupper($match[2]); - }, $camelizedAttribute)); - } - - $this->nameConverter = new CamelCaseToSnakeCaseNameConverter($attributes); - - return $this; - } - /** * Detects if the configured circular reference limit is reached. * @@ -231,22 +194,6 @@ protected function handleCircularReference($object) throw new CircularReferenceException(sprintf('A circular reference has been detected (configured limit: %d).', $this->circularReferenceLimit)); } - /** - * Format an attribute name, for example to convert a snake_case name to camelCase. - * - * @deprecated Deprecated since version 2.7, to be removed in 3.0. Use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter instead. - * - * @param string $attributeName - * - * @return string - */ - protected function formatAttribute($attributeName) - { - @trigger_error(sprintf('%s is deprecated since version 2.7 and will be removed in 3.0. Use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter instead.', __METHOD__), E_USER_DEPRECATED); - - return $this->nameConverter ? $this->nameConverter->normalize($attributeName) : $attributeName; - } - /** * Gets attributes to normalize using groups. * @@ -264,14 +211,34 @@ protected function getAllowedAttributes($classOrObject, array $context, $attribu $allowedAttributes = array(); foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) { - if (count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS]))) { - $allowedAttributes[] = $attributesAsString ? $attributeMetadata->getName() : $attributeMetadata; + $name = $attributeMetadata->getName(); + + if ( + count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS])) && + $this->isAllowedAttribute($classOrObject, $name, null, $context) + ) { + $allowedAttributes[] = $attributesAsString ? $name : $attributeMetadata; } } return $allowedAttributes; } + /** + * Is this attribute allowed? + * + * @param object|string $classOrObject + * @param string $attribute + * @param string|null $format + * @param array $context + * + * @return bool + */ + protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array()) + { + return !in_array($attribute, $this->ignoredAttributes); + } + /** * Normalizes the given data to an array. It's particularly useful during * the denormalization process. @@ -285,6 +252,23 @@ protected function prepareForDenormalization($data) return (array) $data; } + /** + * Returns the method to use to construct an object. This method must be either + * the object constructor or static. + * + * @param array $data + * @param string $class + * @param array $context + * @param \ReflectionClass $reflectionClass + * @param array|bool $allowedAttributes + * + * @return \ReflectionMethod|null + */ + protected function getConstructor(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes) + { + return $reflectionClass->getConstructor(); + } + /** * Instantiates an object using constructor parameters when needed. * @@ -298,13 +282,27 @@ protected function prepareForDenormalization($data) * @param array $context * @param \ReflectionClass $reflectionClass * @param array|bool $allowedAttributes + * @param string|null $format * * @return object * * @throws RuntimeException */ - protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes) + protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes/*, $format = null*/) { + if (func_num_args() >= 6) { + $format = func_get_arg(5); + } else { + if (__CLASS__ !== get_class($this)) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s::%s() will have a 6th `$format = null` argument in version 4.0. Not defining it is deprecated since 3.2.', get_class($this), __FUNCTION__), E_USER_DEPRECATED); + } + } + + $format = null; + } + if ( isset($context[static::OBJECT_TO_POPULATE]) && is_object($context[static::OBJECT_TO_POPULATE]) && @@ -316,7 +314,7 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref return $object; } - $constructor = $reflectionClass->getConstructor(); + $constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes); if ($constructor) { $constructorParameters = $constructor->getParameters(); @@ -336,8 +334,21 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref $params = array_merge($params, $data[$paramName]); } } elseif ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { - $params[] = $data[$key]; - // don't run set for a parameter passed to the constructor + $parameterData = $data[$key]; + try { + if (null !== $constructorParameter->getClass()) { + if (!$this->serializer instanceof DenormalizerInterface) { + throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class)); + } + $parameterClass = $constructorParameter->getClass()->getName(); + $parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $context); + } + } catch (\ReflectionException $e) { + throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e); + } + + // Don't run set for a parameter passed to the constructor + $params[] = $parameterData; unset($data[$key]); } elseif ($constructorParameter->isDefaultValueAvailable()) { $params[] = $constructorParameter->getDefaultValue(); @@ -352,7 +363,11 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref } } - return $reflectionClass->newInstanceArgs($params); + if ($constructor->isConstructor()) { + return $reflectionClass->newInstanceArgs($params); + } else { + return $constructor->invokeArgs(null, $params); + } } return new $class(); diff --git a/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php b/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php new file mode 100644 index 00000000..2b3433c5 --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php @@ -0,0 +1,355 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Serializer\Exception\CircularReferenceException; +use Symfony\Component\Serializer\Exception\LogicException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; +use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; +use Symfony\Component\PropertyInfo\Type; +use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; +use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; +use Symfony\Component\Serializer\NameConverter\NameConverterInterface; + +/** + * Base class for a normalizer dealing with objects. + * + * @author Kévin Dunglas + */ +abstract class AbstractObjectNormalizer extends AbstractNormalizer +{ + const ENABLE_MAX_DEPTH = 'enable_max_depth'; + const DEPTH_KEY_PATTERN = 'depth_%s::%s'; + + private $propertyTypeExtractor; + private $attributesCache = array(); + + public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null) + { + parent::__construct($classMetadataFactory, $nameConverter); + + $this->propertyTypeExtractor = $propertyTypeExtractor; + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null) + { + return is_object($data) && !$data instanceof \Traversable; + } + + /** + * {@inheritdoc} + * + * @throws CircularReferenceException + */ + public function normalize($object, $format = null, array $context = array()) + { + if (!isset($context['cache_key'])) { + $context['cache_key'] = $this->getCacheKey($format, $context); + } + + if ($this->isCircularReference($object, $context)) { + return $this->handleCircularReference($object); + } + + $data = array(); + $stack = array(); + $attributes = $this->getAttributes($object, $format, $context); + $class = get_class($object); + $attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null; + + foreach ($attributes as $attribute) { + if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) { + continue; + } + + $attributeValue = $this->getAttributeValue($object, $attribute, $format, $context); + + if (isset($this->callbacks[$attribute])) { + $attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue); + } + + if (null !== $attributeValue && !is_scalar($attributeValue)) { + $stack[$attribute] = $attributeValue; + } + + $data = $this->updateData($data, $attribute, $attributeValue); + } + + foreach ($stack as $attribute => $attributeValue) { + if (!$this->serializer instanceof NormalizerInterface) { + throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute)); + } + + $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $context)); + } + + return $data; + } + + /** + * Gets and caches attributes for the given object, format and context. + * + * @param object $object + * @param string|null $format + * @param array $context + * + * @return string[] + */ + protected function getAttributes($object, $format = null, array $context) + { + $class = get_class($object); + $key = $class.'-'.$context['cache_key']; + + if (isset($this->attributesCache[$key])) { + return $this->attributesCache[$key]; + } + + $allowedAttributes = $this->getAllowedAttributes($object, $context, true); + + if (false !== $allowedAttributes) { + if ($context['cache_key']) { + $this->attributesCache[$key] = $allowedAttributes; + } + + return $allowedAttributes; + } + + if (isset($this->attributesCache[$class])) { + return $this->attributesCache[$class]; + } + + return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context); + } + + /** + * Extracts attributes to normalize from the class of the given object, format and context. + * + * @param object $object + * @param string|null $format + * @param array $context + * + * @return string[] + */ + abstract protected function extractAttributes($object, $format = null, array $context = array()); + + /** + * Gets the attribute value. + * + * @param object $object + * @param string $attribute + * @param string|null $format + * @param array $context + * + * @return mixed + */ + abstract protected function getAttributeValue($object, $attribute, $format = null, array $context = array()); + + /** + * {@inheritdoc} + */ + public function supportsDenormalization($data, $type, $format = null) + { + return class_exists($type); + } + + /** + * {@inheritdoc} + */ + public function denormalize($data, $class, $format = null, array $context = array()) + { + if (!isset($context['cache_key'])) { + $context['cache_key'] = $this->getCacheKey($format, $context); + } + $allowedAttributes = $this->getAllowedAttributes($class, $context, true); + $normalizedData = $this->prepareForDenormalization($data); + + $reflectionClass = new \ReflectionClass($class); + $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes, $format); + + foreach ($normalizedData as $attribute => $value) { + if ($this->nameConverter) { + $attribute = $this->nameConverter->denormalize($attribute); + } + + if (($allowedAttributes !== false && !in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) { + continue; + } + + $value = $this->validateAndDenormalize($class, $attribute, $value, $format, $context); + try { + $this->setAttributeValue($object, $attribute, $value, $format, $context); + } catch (InvalidArgumentException $e) { + throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); + } + } + + return $object; + } + + /** + * Sets attribute value. + * + * @param object $object + * @param string $attribute + * @param mixed $value + * @param string|null $format + * @param array $context + */ + abstract protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array()); + + /** + * Validates the submitted data and denormalizes it. + * + * @param string $currentClass + * @param string $attribute + * @param mixed $data + * @param string|null $format + * @param array $context + * + * @return mixed + * + * @throws UnexpectedValueException + * @throws LogicException + */ + private function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context) + { + if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($currentClass, $attribute)) { + return $data; + } + + $expectedTypes = array(); + foreach ($types as $type) { + if (null === $data && $type->isNullable()) { + return; + } + + if ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) { + $builtinType = Type::BUILTIN_TYPE_OBJECT; + $class = $collectionValueType->getClassName().'[]'; + + if (null !== $collectionKeyType = $type->getCollectionKeyType()) { + $context['key_type'] = $collectionKeyType; + } + } else { + $builtinType = $type->getBuiltinType(); + $class = $type->getClassName(); + } + + $expectedTypes[Type::BUILTIN_TYPE_OBJECT === $builtinType && $class ? $class : $builtinType] = true; + + if (Type::BUILTIN_TYPE_OBJECT === $builtinType) { + if (!$this->serializer instanceof DenormalizerInterface) { + throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class)); + } + + if ($this->serializer->supportsDenormalization($data, $class, $format)) { + return $this->serializer->denormalize($data, $class, $format, $context); + } + } + + // JSON only has a Number type corresponding to both int and float PHP types. + // PHP's json_encode, JavaScript's JSON.stringify, Go's json.Marshal as well as most other JSON encoders convert + // floating-point numbers like 12.0 to 12 (the decimal part is dropped when possible). + // PHP's json_decode automatically converts Numbers without a decimal part to integers. + // To circumvent this behavior, integers are converted to floats when denormalizing JSON based formats and when + // a float is expected. + if (Type::BUILTIN_TYPE_FLOAT === $builtinType && is_int($data) && false !== strpos($format, JsonEncoder::FORMAT)) { + return (float) $data; + } + + if (call_user_func('is_'.$builtinType, $data)) { + return $data; + } + } + + throw new UnexpectedValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data))); + } + + /** + * Sets an attribute and apply the name converter if necessary. + * + * @param array $data + * @param string $attribute + * @param mixed $attributeValue + * + * @return array + */ + private function updateData(array $data, $attribute, $attributeValue) + { + if ($this->nameConverter) { + $attribute = $this->nameConverter->normalize($attribute); + } + + $data[$attribute] = $attributeValue; + + return $data; + } + + /** + * Is the max depth reached for the given attribute? + * + * @param AttributeMetadataInterface[] $attributesMetadata + * @param string $class + * @param string $attribute + * @param array $context + * + * @return bool + */ + private function isMaxDepthReached(array $attributesMetadata, $class, $attribute, array &$context) + { + if ( + !isset($context[static::ENABLE_MAX_DEPTH]) || + !isset($attributesMetadata[$attribute]) || + null === $maxDepth = $attributesMetadata[$attribute]->getMaxDepth() + ) { + return false; + } + + $key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute); + if (!isset($context[$key])) { + $context[$key] = 1; + + return false; + } + + if ($context[$key] === $maxDepth) { + return true; + } + + ++$context[$key]; + + return false; + } + + /** + * Gets the cache key to use. + * + * @param string|null $format + * @param array $context + * + * @return bool|string + */ + private function getCacheKey($format, array $context) + { + try { + return md5($format.serialize($context)); + } catch (\Exception $exception) { + // The context cannot be serialized, skip the cache + return false; + } + } +} diff --git a/vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php b/vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php index 921e312b..7d3d87c5 100644 --- a/vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php +++ b/vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php @@ -13,6 +13,7 @@ use Symfony\Component\Serializer\Exception\BadMethodCallException; use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\SerializerAwareInterface; use Symfony\Component\Serializer\SerializerInterface; @@ -30,6 +31,8 @@ class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterfa /** * {@inheritdoc} + * + * @throws UnexpectedValueException */ public function denormalize($data, $class, $format = null, array $context = array()) { @@ -46,12 +49,16 @@ public function denormalize($data, $class, $format = null, array $context = arra $serializer = $this->serializer; $class = substr($class, 0, -2); - return array_map( - function ($data) use ($serializer, $class, $format, $context) { - return $serializer->denormalize($data, $class, $format, $context); - }, - $data - ); + $builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null; + foreach ($data as $key => $value) { + if (null !== $builtinType && !call_user_func('is_'.$builtinType, $key)) { + throw new UnexpectedValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, gettype($key))); + } + + $data[$key] = $serializer->denormalize($value, $class, $format, $context); + } + + return $data; } /** diff --git a/vendor/symfony/serializer/Normalizer/CustomNormalizer.php b/vendor/symfony/serializer/Normalizer/CustomNormalizer.php index b676b833..688590ef 100644 --- a/vendor/symfony/serializer/Normalizer/CustomNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/CustomNormalizer.php @@ -11,11 +11,16 @@ namespace Symfony\Component\Serializer\Normalizer; +use Symfony\Component\Serializer\SerializerAwareInterface; +use Symfony\Component\Serializer\SerializerAwareTrait; + /** * @author Jordi Boggiano */ -class CustomNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface +class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface { + use SerializerAwareTrait; + /** * {@inheritdoc} */ diff --git a/vendor/symfony/serializer/Normalizer/DataUriNormalizer.php b/vendor/symfony/serializer/Normalizer/DataUriNormalizer.php new file mode 100644 index 00000000..988a491b --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/DataUriNormalizer.php @@ -0,0 +1,157 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +use Symfony\Component\HttpFoundation\File\File; +use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser; +use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; + +/** + * Normalizes an {@see \SplFileInfo} object to a data URI. + * Denormalizes a data URI to a {@see \SplFileObject} object. + * + * @author Kévin Dunglas + */ +class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface +{ + /** + * @var MimeTypeGuesserInterface + */ + private $mimeTypeGuesser; + + public function __construct(MimeTypeGuesserInterface $mimeTypeGuesser = null) + { + if (null === $mimeTypeGuesser && class_exists('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser')) { + $mimeTypeGuesser = MimeTypeGuesser::getInstance(); + } + + $this->mimeTypeGuesser = $mimeTypeGuesser; + } + + /** + * {@inheritdoc} + */ + public function normalize($object, $format = null, array $context = array()) + { + if (!$object instanceof \SplFileInfo) { + throw new InvalidArgumentException('The object must be an instance of "\SplFileInfo".'); + } + + $mimeType = $this->getMimeType($object); + $splFileObject = $this->extractSplFileObject($object); + + $data = ''; + + $splFileObject->rewind(); + while (!$splFileObject->eof()) { + $data .= $splFileObject->fgets(); + } + + if ('text' === explode('/', $mimeType, 2)[0]) { + return sprintf('data:%s,%s', $mimeType, rawurlencode($data)); + } + + return sprintf('data:%s;base64,%s', $mimeType, base64_encode($data)); + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null) + { + return $data instanceof \SplFileInfo; + } + + /** + * {@inheritdoc} + * + * Regex adapted from Brian Grinstead code. + * + * @see https://gist.github.com/bgrins/6194623 + * + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function denormalize($data, $class, $format = null, array $context = array()) + { + if (!preg_match('/^data:([a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}\/[a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}(;[a-z0-9\-]+\=[a-z0-9\-]+)?)?(;base64)?,[a-z0-9\!\$\&\\\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i', $data)) { + throw new UnexpectedValueException('The provided "data:" URI is not valid.'); + } + + try { + switch ($class) { + case 'Symfony\Component\HttpFoundation\File\File': + return new File($data, false); + + case 'SplFileObject': + case 'SplFileInfo': + return new \SplFileObject($data); + } + } catch (\RuntimeException $exception) { + throw new UnexpectedValueException($exception->getMessage(), $exception->getCode(), $exception); + } + + throw new InvalidArgumentException(sprintf('The class parameter "%s" is not supported. It must be one of "SplFileInfo", "SplFileObject" or "Symfony\Component\HttpFoundation\File\File".', $class)); + } + + /** + * {@inheritdoc} + */ + public function supportsDenormalization($data, $type, $format = null) + { + $supportedTypes = array( + \SplFileInfo::class => true, + \SplFileObject::class => true, + 'Symfony\Component\HttpFoundation\File\File' => true, + ); + + return isset($supportedTypes[$type]); + } + + /** + * Gets the mime type of the object. Defaults to application/octet-stream. + * + * @param \SplFileInfo $object + * + * @return string + */ + private function getMimeType(\SplFileInfo $object) + { + if ($object instanceof File) { + return $object->getMimeType(); + } + + if ($this->mimeTypeGuesser && $mimeType = $this->mimeTypeGuesser->guess($object->getPathname())) { + return $mimeType; + } + + return 'application/octet-stream'; + } + + /** + * Returns the \SplFileObject instance associated with the given \SplFileInfo instance. + * + * @param \SplFileInfo $object + * + * @return \SplFileObject + */ + private function extractSplFileObject(\SplFileInfo $object) + { + if ($object instanceof \SplFileObject) { + return $object; + } + + return $object->openFile(); + } +} diff --git a/vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php b/vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php new file mode 100644 index 00000000..5958aab0 --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; + +/** + * Normalizes an object implementing the {@see \DateTimeInterface} to a date string. + * Denormalizes a date string to an instance of {@see \DateTime} or {@see \DateTimeImmutable}. + * + * @author Kévin Dunglas + */ +class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface +{ + const FORMAT_KEY = 'datetime_format'; + + /** + * @var string + */ + private $format; + + /** + * @param string $format + */ + public function __construct($format = \DateTime::RFC3339) + { + $this->format = $format; + } + + /** + * {@inheritdoc} + * + * @throws InvalidArgumentException + */ + public function normalize($object, $format = null, array $context = array()) + { + if (!$object instanceof \DateTimeInterface) { + throw new InvalidArgumentException('The object must implement the "\DateTimeInterface".'); + } + + $format = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format; + + return $object->format($format); + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null) + { + return $data instanceof \DateTimeInterface; + } + + /** + * {@inheritdoc} + * + * @throws UnexpectedValueException + */ + public function denormalize($data, $class, $format = null, array $context = array()) + { + $dateTimeFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : null; + + if (null !== $dateTimeFormat) { + $object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data); + + if (false !== $object) { + return $object; + } + + $dateTimeErrors = \DateTime::class === $class ? \DateTime::getLastErrors() : \DateTimeImmutable::getLastErrors(); + + throw new UnexpectedValueException(sprintf( + 'Parsing datetime string "%s" using format "%s" resulted in %d errors:'."\n".'%s', + $data, + $dateTimeFormat, + $dateTimeErrors['error_count'], + implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors'])) + )); + } + + try { + return \DateTime::class === $class ? new \DateTime($data) : new \DateTimeImmutable($data); + } catch (\Exception $e) { + throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function supportsDenormalization($data, $type, $format = null) + { + $supportedTypes = array( + \DateTimeInterface::class => true, + \DateTimeImmutable::class => true, + \DateTime::class => true, + ); + + return isset($supportedTypes[$type]); + } + + /** + * Formats datetime errors. + * + * @param array $errors + * + * @return string[] + */ + private function formatDateTimeErrors(array $errors) + { + $formattedErrors = array(); + + foreach ($errors as $pos => $message) { + $formattedErrors[] = sprintf('at position %d: %s', $pos, $message); + } + + return $formattedErrors; + } +} diff --git a/vendor/symfony/serializer/Normalizer/DenormalizerAwareInterface.php b/vendor/symfony/serializer/Normalizer/DenormalizerAwareInterface.php new file mode 100644 index 00000000..4a6a4e26 --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/DenormalizerAwareInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +/** + * Class accepting a denormalizer. + * + * @author Joel Wurtz + */ +interface DenormalizerAwareInterface +{ + /** + * Sets the owning Denormalizer object. + * + * @param DenormalizerInterface $denormalizer + */ + public function setDenormalizer(DenormalizerInterface $denormalizer); +} diff --git a/vendor/symfony/serializer/Normalizer/DenormalizerAwareTrait.php b/vendor/symfony/serializer/Normalizer/DenormalizerAwareTrait.php new file mode 100644 index 00000000..ff8528bf --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/DenormalizerAwareTrait.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +/** + * DenormalizerAware trait. + * + * @author Joel Wurtz + */ +trait DenormalizerAwareTrait +{ + /** + * @var DenormalizerInterface + */ + protected $denormalizer; + + /** + * Sets the Denormalizer. + * + * @param DenormalizerInterface $denormalizer A DenormalizerInterface instance + */ + public function setDenormalizer(DenormalizerInterface $denormalizer) + { + $this->denormalizer = $denormalizer; + } +} diff --git a/vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php b/vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php index 003c3a68..2a15d46d 100644 --- a/vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php @@ -11,10 +11,6 @@ namespace Symfony\Component\Serializer\Normalizer; -use Symfony\Component\Serializer\Exception\CircularReferenceException; -use Symfony\Component\Serializer\Exception\LogicException; -use Symfony\Component\Serializer\Exception\RuntimeException; - /** * Converts between objects with getter and setter methods and arrays. * @@ -36,99 +32,16 @@ * @author Nils Adermann * @author Kévin Dunglas */ -class GetSetMethodNormalizer extends AbstractNormalizer +class GetSetMethodNormalizer extends AbstractObjectNormalizer { - /** - * {@inheritdoc} - * - * @throws LogicException - * @throws CircularReferenceException - */ - public function normalize($object, $format = null, array $context = array()) - { - if ($this->isCircularReference($object, $context)) { - return $this->handleCircularReference($object); - } - - $reflectionObject = new \ReflectionObject($object); - $reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC); - $allowedAttributes = $this->getAllowedAttributes($object, $context, true); - - $attributes = array(); - foreach ($reflectionMethods as $method) { - if ($this->isGetMethod($method)) { - $attributeName = lcfirst(substr($method->name, 0 === strpos($method->name, 'is') ? 2 : 3)); - if (in_array($attributeName, $this->ignoredAttributes)) { - continue; - } - - if (false !== $allowedAttributes && !in_array($attributeName, $allowedAttributes)) { - continue; - } - - $attributeValue = $method->invoke($object); - if (isset($this->callbacks[$attributeName])) { - $attributeValue = call_user_func($this->callbacks[$attributeName], $attributeValue); - } - if (null !== $attributeValue && !is_scalar($attributeValue)) { - if (!$this->serializer instanceof NormalizerInterface) { - throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $attributeName)); - } - - $attributeValue = $this->serializer->normalize($attributeValue, $format, $context); - } - - if ($this->nameConverter) { - $attributeName = $this->nameConverter->normalize($attributeName); - } - - $attributes[$attributeName] = $attributeValue; - } - } - - return $attributes; - } - - /** - * {@inheritdoc} - * - * @throws RuntimeException - */ - public function denormalize($data, $class, $format = null, array $context = array()) - { - $allowedAttributes = $this->getAllowedAttributes($class, $context, true); - $normalizedData = $this->prepareForDenormalization($data); - - $reflectionClass = new \ReflectionClass($class); - $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes); - - $classMethods = get_class_methods($object); - foreach ($normalizedData as $attribute => $value) { - if ($this->nameConverter) { - $attribute = $this->nameConverter->denormalize($attribute); - } - - $allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes); - $ignored = in_array($attribute, $this->ignoredAttributes); - - if ($allowed && !$ignored) { - $setter = 'set'.ucfirst($attribute); - - if (in_array($setter, $classMethods) && !$reflectionClass->getMethod($setter)->isStatic()) { - $object->$setter($value); - } - } - } - - return $object; - } + private static $setterAccessibleCache = array(); /** * {@inheritdoc} */ public function supportsNormalization($data, $format = null) { - return is_object($data) && !$data instanceof \Traversable && $this->supports(get_class($data)); + return parent::supportsNormalization($data, $format) && $this->supports(get_class($data)); } /** @@ -136,7 +49,7 @@ public function supportsNormalization($data, $format = null) */ public function supportsDenormalization($data, $type, $format = null) { - return class_exists($type) && $this->supports($type); + return parent::supportsDenormalization($data, $type, $format) && $this->supports($type); } /** @@ -179,4 +92,63 @@ private function isGetMethod(\ReflectionMethod $method) ) ; } + + /** + * {@inheritdoc} + */ + protected function extractAttributes($object, $format = null, array $context = array()) + { + $reflectionObject = new \ReflectionObject($object); + $reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC); + + $attributes = array(); + foreach ($reflectionMethods as $method) { + if (!$this->isGetMethod($method)) { + continue; + } + + $attributeName = lcfirst(substr($method->name, 0 === strpos($method->name, 'is') ? 2 : 3)); + + if ($this->isAllowedAttribute($object, $attributeName)) { + $attributes[] = $attributeName; + } + } + + return $attributes; + } + + /** + * {@inheritdoc} + */ + protected function getAttributeValue($object, $attribute, $format = null, array $context = array()) + { + $ucfirsted = ucfirst($attribute); + + $getter = 'get'.$ucfirsted; + if (is_callable(array($object, $getter))) { + return $object->$getter(); + } + + $isser = 'is'.$ucfirsted; + if (is_callable(array($object, $isser))) { + return $object->$isser(); + } + } + + /** + * {@inheritdoc} + */ + protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array()) + { + $setter = 'set'.ucfirst($attribute); + $key = get_class($object).':'.$setter; + + if (!isset(self::$setterAccessibleCache[$key])) { + self::$setterAccessibleCache[$key] = is_callable(array($object, $setter)) && !(new \ReflectionMethod($object, $setter))->isStatic(); + } + + if (self::$setterAccessibleCache[$key]) { + $object->$setter($value); + } + } } diff --git a/vendor/symfony/serializer/Normalizer/JsonSerializableNormalizer.php b/vendor/symfony/serializer/Normalizer/JsonSerializableNormalizer.php new file mode 100644 index 00000000..27ccf802 --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/JsonSerializableNormalizer.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\LogicException; + +/** + * A normalizer that uses an objects own JsonSerializable implementation. + * + * @author Fred Cox + */ +class JsonSerializableNormalizer extends AbstractNormalizer +{ + /** + * {@inheritdoc} + */ + public function normalize($object, $format = null, array $context = array()) + { + if ($this->isCircularReference($object, $context)) { + return $this->handleCircularReference($object); + } + + if (!$object instanceof \JsonSerializable) { + throw new InvalidArgumentException(sprintf('The object must implement "%s".', \JsonSerializable::class)); + } + + if (!$this->serializer instanceof NormalizerInterface) { + throw new LogicException('Cannot normalize object because injected serializer is not a normalizer'); + } + + return $this->serializer->normalize($object->jsonSerialize(), $format, $context); + } + + /** + * {@inheritdoc} + */ + public function supportsNormalization($data, $format = null) + { + return $data instanceof \JsonSerializable; + } + + /** + * {@inheritdoc} + */ + public function supportsDenormalization($data, $type, $format = null) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function denormalize($data, $class, $format = null, array $context = array()) + { + throw new LogicException(sprintf('Cannot denormalize with "%s".', \JsonSerializable::class)); + } +} diff --git a/vendor/symfony/serializer/Normalizer/NormalizerAwareInterface.php b/vendor/symfony/serializer/Normalizer/NormalizerAwareInterface.php new file mode 100644 index 00000000..55015fe6 --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/NormalizerAwareInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +/** + * Class accepting a normalizer. + * + * @author Joel Wurtz + */ +interface NormalizerAwareInterface +{ + /** + * Sets the owning Normalizer object. + * + * @param NormalizerInterface $normalizer + */ + public function setNormalizer(NormalizerInterface $normalizer); +} diff --git a/vendor/symfony/serializer/Normalizer/NormalizerAwareTrait.php b/vendor/symfony/serializer/Normalizer/NormalizerAwareTrait.php new file mode 100644 index 00000000..7d605875 --- /dev/null +++ b/vendor/symfony/serializer/Normalizer/NormalizerAwareTrait.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +/** + * NormalizerAware trait. + * + * @author Joel Wurtz + */ +trait NormalizerAwareTrait +{ + /** + * @var NormalizerInterface + */ + protected $normalizer; + + /** + * Sets the normalizer. + * + * @param NormalizerInterface $normalizer A NormalizerInterface instance + */ + public function setNormalizer(NormalizerInterface $normalizer) + { + $this->normalizer = $normalizer; + } +} diff --git a/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php b/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php index 0fde2697..00a0a693 100644 --- a/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/ObjectNormalizer.php @@ -14,8 +14,7 @@ use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; -use Symfony\Component\Serializer\Exception\CircularReferenceException; -use Symfony\Component\Serializer\Exception\LogicException; +use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; @@ -24,18 +23,16 @@ * * @author Kévin Dunglas */ -class ObjectNormalizer extends AbstractNormalizer +class ObjectNormalizer extends AbstractObjectNormalizer { - private $attributesCache = array(); - /** * @var PropertyAccessorInterface */ protected $propertyAccessor; - public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null) + public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null) { - parent::__construct($classMetadataFactory, $nameConverter); + parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor); $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); } @@ -43,151 +40,7 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory /** * {@inheritdoc} */ - public function supportsNormalization($data, $format = null) - { - return is_object($data) && !$data instanceof \Traversable; - } - - /** - * {@inheritdoc} - * - * @throws CircularReferenceException - */ - public function normalize($object, $format = null, array $context = array()) - { - if (!isset($context['cache_key'])) { - $context['cache_key'] = $this->getCacheKey($context); - } - if ($this->isCircularReference($object, $context)) { - return $this->handleCircularReference($object); - } - - $data = array(); - $attributes = $this->getAttributes($object, $context); - - foreach ($attributes as $attribute) { - if (in_array($attribute, $this->ignoredAttributes)) { - continue; - } - - $attributeValue = $this->propertyAccessor->getValue($object, $attribute); - - if (isset($this->callbacks[$attribute])) { - $attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue); - } - - if (null !== $attributeValue && !is_scalar($attributeValue)) { - if (!$this->serializer instanceof NormalizerInterface) { - throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $attribute)); - } - - $attributeValue = $this->serializer->normalize($attributeValue, $format, $context); - } - - if ($this->nameConverter) { - $attribute = $this->nameConverter->normalize($attribute); - } - - $data[$attribute] = $attributeValue; - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function supportsDenormalization($data, $type, $format = null) - { - return class_exists($type); - } - - /** - * {@inheritdoc} - */ - public function denormalize($data, $class, $format = null, array $context = array()) - { - if (!isset($context['cache_key'])) { - $context['cache_key'] = $this->getCacheKey($context); - } - $allowedAttributes = $this->getAllowedAttributes($class, $context, true); - $normalizedData = $this->prepareForDenormalization($data); - - $reflectionClass = new \ReflectionClass($class); - $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes); - - foreach ($normalizedData as $attribute => $value) { - if ($this->nameConverter) { - $attribute = $this->nameConverter->denormalize($attribute); - } - - $allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes); - $ignored = in_array($attribute, $this->ignoredAttributes); - - if ($allowed && !$ignored) { - try { - $this->propertyAccessor->setValue($object, $attribute, $value); - } catch (NoSuchPropertyException $exception) { - // Properties not found are ignored - } - } - } - - return $object; - } - - private function getCacheKey(array $context) - { - try { - return md5(serialize($context)); - } catch (\Exception $exception) { - // The context cannot be serialized, skip the cache - return false; - } - } - - /** - * Gets and caches attributes for this class and context. - * - * @param object $object - * @param array $context - * - * @return string[] - */ - private function getAttributes($object, array $context) - { - $class = get_class($object); - $key = $class.'-'.$context['cache_key']; - - if (isset($this->attributesCache[$key])) { - return $this->attributesCache[$key]; - } - - $allowedAttributes = $this->getAllowedAttributes($object, $context, true); - - if (false !== $allowedAttributes) { - if ($context['cache_key']) { - $this->attributesCache[$key] = $allowedAttributes; - } - - return $allowedAttributes; - } - - if (isset($this->attributesCache[$class])) { - return $this->attributesCache[$class]; - } - - return $this->attributesCache[$class] = $this->extractAttributes($object); - } - - /** - * Extracts attributes for this class and context. - * - * @param object $object - * - * @return string[] - */ - private function extractAttributes($object) + protected function extractAttributes($object, $format = null, array $context = array()) { // If not using groups, detect manually $attributes = array(); @@ -205,19 +58,32 @@ private function extractAttributes($object) } $name = $reflMethod->name; + $attributeName = null; if (0 === strpos($name, 'get') || 0 === strpos($name, 'has')) { // getters and hassers - $attributes[lcfirst(substr($name, 3))] = true; + $attributeName = substr($name, 3); + + if (!$reflClass->hasProperty($attributeName)) { + $attributeName = lcfirst($attributeName); + } } elseif (strpos($name, 'is') === 0) { // issers - $attributes[lcfirst(substr($name, 2))] = true; + $attributeName = substr($name, 2); + + if (!$reflClass->hasProperty($attributeName)) { + $attributeName = lcfirst($attributeName); + } + } + + if (null !== $attributeName && $this->isAllowedAttribute($object, $attributeName, $format, $context)) { + $attributes[$attributeName] = true; } } // properties foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) { - if ($reflProperty->isStatic()) { + if ($reflProperty->isStatic() || !$this->isAllowedAttribute($object, $reflProperty->name, $format, $context)) { continue; } @@ -226,4 +92,24 @@ private function extractAttributes($object) return array_keys($attributes); } + + /** + * {@inheritdoc} + */ + protected function getAttributeValue($object, $attribute, $format = null, array $context = array()) + { + return $this->propertyAccessor->getValue($object, $attribute); + } + + /** + * {@inheritdoc} + */ + protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array()) + { + try { + $this->propertyAccessor->setValue($object, $attribute, $value); + } catch (NoSuchPropertyException $exception) { + // Properties not found are ignored + } + } } diff --git a/vendor/symfony/serializer/Normalizer/PropertyNormalizer.php b/vendor/symfony/serializer/Normalizer/PropertyNormalizer.php index 993046f3..9795ec4b 100644 --- a/vendor/symfony/serializer/Normalizer/PropertyNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/PropertyNormalizer.php @@ -11,10 +11,6 @@ namespace Symfony\Component\Serializer\Normalizer; -use Symfony\Component\Serializer\Exception\CircularReferenceException; -use Symfony\Component\Serializer\Exception\LogicException; -use Symfony\Component\Serializer\Exception\RuntimeException; - /** * Converts between objects and arrays by mapping properties. * @@ -32,134 +28,124 @@ * @author Matthieu Napoli * @author Kévin Dunglas */ -class PropertyNormalizer extends AbstractNormalizer +class PropertyNormalizer extends AbstractObjectNormalizer { /** * {@inheritdoc} - * - * @throws CircularReferenceException */ - public function normalize($object, $format = null, array $context = array()) + public function supportsNormalization($data, $format = null) { - if ($this->isCircularReference($object, $context)) { - return $this->handleCircularReference($object); - } - - $reflectionObject = new \ReflectionObject($object); - $attributes = array(); - $allowedAttributes = $this->getAllowedAttributes($object, $context, true); + return parent::supportsNormalization($data, $format) && $this->supports(get_class($data)); + } - foreach ($reflectionObject->getProperties() as $property) { - if (in_array($property->name, $this->ignoredAttributes) || $property->isStatic()) { - continue; - } + /** + * {@inheritdoc} + */ + public function supportsDenormalization($data, $type, $format = null) + { + return parent::supportsDenormalization($data, $type, $format) && $this->supports($type); + } - if (false !== $allowedAttributes && !in_array($property->name, $allowedAttributes)) { - continue; - } + /** + * Checks if the given class has any non-static property. + * + * @param string $class + * + * @return bool + */ + private function supports($class) + { + $class = new \ReflectionClass($class); - // Override visibility - if (!$property->isPublic()) { - $property->setAccessible(true); + // We look for at least one non-static property + foreach ($class->getProperties() as $property) { + if (!$property->isStatic()) { + return true; } + } - $attributeValue = $property->getValue($object); - - if (isset($this->callbacks[$property->name])) { - $attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue); - } - if (null !== $attributeValue && !is_scalar($attributeValue)) { - if (!$this->serializer instanceof NormalizerInterface) { - throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $property->name)); - } + return false; + } - $attributeValue = $this->serializer->normalize($attributeValue, $format, $context); - } + /** + * {@inheritdoc} + */ + protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array()) + { + if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) { + return false; + } - $propertyName = $property->name; - if ($this->nameConverter) { - $propertyName = $this->nameConverter->normalize($propertyName); + try { + $reflectionProperty = new \ReflectionProperty(is_string($classOrObject) ? $classOrObject : get_class($classOrObject), $attribute); + if ($reflectionProperty->isStatic()) { + return false; } - - $attributes[$propertyName] = $attributeValue; + } catch (\ReflectionException $reflectionException) { + return false; } - return $attributes; + return true; } /** * {@inheritdoc} - * - * @throws RuntimeException */ - public function denormalize($data, $class, $format = null, array $context = array()) + protected function extractAttributes($object, $format = null, array $context = array()) { - $allowedAttributes = $this->getAllowedAttributes($class, $context, true); - $data = $this->prepareForDenormalization($data); - - $reflectionClass = new \ReflectionClass($class); - $object = $this->instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes); + $reflectionObject = new \ReflectionObject($object); + $attributes = array(); - foreach ($data as $propertyName => $value) { - if ($this->nameConverter) { - $propertyName = $this->nameConverter->denormalize($propertyName); + foreach ($reflectionObject->getProperties() as $property) { + if (!$this->isAllowedAttribute($object, $property->name)) { + continue; } - $allowed = $allowedAttributes === false || in_array($propertyName, $allowedAttributes); - $ignored = in_array($propertyName, $this->ignoredAttributes); - if ($allowed && !$ignored && $reflectionClass->hasProperty($propertyName)) { - $property = $reflectionClass->getProperty($propertyName); - - if ($property->isStatic()) { - continue; - } - - // Override visibility - if (!$property->isPublic()) { - $property->setAccessible(true); - } - - $property->setValue($object, $value); - } + $attributes[] = $property->name; } - return $object; + return $attributes; } /** * {@inheritdoc} */ - public function supportsNormalization($data, $format = null) + protected function getAttributeValue($object, $attribute, $format = null, array $context = array()) { - return is_object($data) && !$data instanceof \Traversable && $this->supports(get_class($data)); + try { + $reflectionProperty = new \ReflectionProperty(get_class($object), $attribute); + } catch (\ReflectionException $reflectionException) { + return; + } + + // Override visibility + if (!$reflectionProperty->isPublic()) { + $reflectionProperty->setAccessible(true); + } + + return $reflectionProperty->getValue($object); } /** * {@inheritdoc} */ - public function supportsDenormalization($data, $type, $format = null) + protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array()) { - return class_exists($type) && $this->supports($type); - } + try { + $reflectionProperty = new \ReflectionProperty(get_class($object), $attribute); + } catch (\ReflectionException $reflectionException) { + return; + } - /** - * Checks if the given class has any non-static property. - * - * @param string $class - * - * @return bool - */ - private function supports($class) - { - $class = new \ReflectionClass($class); + if ($reflectionProperty->isStatic()) { + return; + } - // We look for at least one non-static property - foreach ($class->getProperties() as $property) { - if (!$property->isStatic()) { - return true; - } + // Override visibility + if (!$reflectionProperty->isPublic()) { + $reflectionProperty->setAccessible(true); } - return false; + $reflectionProperty->setValue($object, $value); } } diff --git a/vendor/symfony/serializer/Normalizer/SerializerAwareNormalizer.php b/vendor/symfony/serializer/Normalizer/SerializerAwareNormalizer.php index 39568570..0480d9ff 100644 --- a/vendor/symfony/serializer/Normalizer/SerializerAwareNormalizer.php +++ b/vendor/symfony/serializer/Normalizer/SerializerAwareNormalizer.php @@ -11,26 +11,17 @@ namespace Symfony\Component\Serializer\Normalizer; -use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\Serializer\SerializerAwareTrait; use Symfony\Component\Serializer\SerializerAwareInterface; /** * SerializerAware Normalizer implementation. * * @author Jordi Boggiano + * + * @deprecated since version 3.1, to be removed in 4.0. Use the SerializerAwareTrait instead. */ abstract class SerializerAwareNormalizer implements SerializerAwareInterface { - /** - * @var SerializerInterface - */ - protected $serializer; - - /** - * {@inheritdoc} - */ - public function setSerializer(SerializerInterface $serializer) - { - $this->serializer = $serializer; - } + use SerializerAwareTrait; } diff --git a/vendor/symfony/serializer/Serializer.php b/vendor/symfony/serializer/Serializer.php index 0259bfed..c3e35bb0 100644 --- a/vendor/symfony/serializer/Serializer.php +++ b/vendor/symfony/serializer/Serializer.php @@ -15,6 +15,8 @@ use Symfony\Component\Serializer\Encoder\ChainEncoder; use Symfony\Component\Serializer\Encoder\EncoderInterface; use Symfony\Component\Serializer\Encoder\DecoderInterface; +use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Exception\LogicException; @@ -54,11 +56,15 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz /** * @var array + * + * @deprecated since 3.1 will be removed in 4.0 */ protected $normalizerCache = array(); /** * @var array + * + * @deprecated since 3.1 will be removed in 4.0 */ protected $denormalizerCache = array(); @@ -68,6 +74,14 @@ public function __construct(array $normalizers = array(), array $encoders = arra if ($normalizer instanceof SerializerAwareInterface) { $normalizer->setSerializer($this); } + + if ($normalizer instanceof DenormalizerAwareInterface) { + $normalizer->setDenormalizer($this); + } + + if ($normalizer instanceof NormalizerAwareInterface) { + $normalizer->setNormalizer($this); + } } $this->normalizers = $normalizers; diff --git a/vendor/symfony/serializer/SerializerAwareTrait.php b/vendor/symfony/serializer/SerializerAwareTrait.php new file mode 100644 index 00000000..7f5839ee --- /dev/null +++ b/vendor/symfony/serializer/SerializerAwareTrait.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer; + +/** + * SerializerAware trait. + * + * @author Joel Wurtz + */ +trait SerializerAwareTrait +{ + /** + * @var SerializerInterface + */ + protected $serializer; + + /** + * Sets the serializer. + * + * @param SerializerInterface $serializer A SerializerInterface instance + */ + public function setSerializer(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } +} diff --git a/vendor/symfony/serializer/composer.json b/vendor/symfony/serializer/composer.json index 88b7832b..d7dbfc65 100644 --- a/vendor/symfony/serializer/composer.json +++ b/vendor/symfony/serializer/composer.json @@ -16,22 +16,33 @@ } ], "require": { - "php": ">=5.3.9", - "symfony/polyfill-php55": "~1.0" + "php": ">=5.5.9" }, "require-dev": { - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0", - "symfony/config": "~2.2|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", + "symfony/yaml": "~3.1", + "symfony/config": "~2.8|~3.0", + "symfony/property-access": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/cache": "~3.1", + "symfony/property-info": "~3.1", "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0" + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "~3.0" + }, + "conflict": { + "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", + "symfony/property-info": "<3.1", + "symfony/yaml": "<3.1" }, "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/property-info": "To deserialize relations.", "symfony/yaml": "For using the default YAML mapping loader.", "symfony/config": "For using the XML mapping loader.", - "symfony/property-access": "For using the ObjectNormalizer." + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/http-foundation": "To use the DataUriNormalizer.", + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache." }, "autoload": { "psr-4": { "Symfony\\Component\\Serializer\\": "" }, @@ -42,7 +53,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/serializer/phpunit.xml.dist b/vendor/symfony/serializer/phpunit.xml.dist index 4799e3cf..ce9af71d 100644 --- a/vendor/symfony/serializer/phpunit.xml.dist +++ b/vendor/symfony/serializer/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/translation/CHANGELOG.md b/vendor/symfony/translation/CHANGELOG.md index 45f15a00..349faceb 100644 --- a/vendor/symfony/translation/CHANGELOG.md +++ b/vendor/symfony/translation/CHANGELOG.md @@ -1,6 +1,22 @@ CHANGELOG ========= +3.2.0 +----- + + * Added support for escaping `|` in plural translations with double pipe. + +3.1.0 +----- + + * Deprecated the backup feature of the file dumper classes. + +3.0.0 +----- + + * removed `FileDumper::format()` method. + * Changed the visibility of the locale property in `Translator` from protected to private. + 2.8.0 ----- diff --git a/vendor/symfony/translation/Catalogue/AbstractOperation.php b/vendor/symfony/translation/Catalogue/AbstractOperation.php index 9598e176..bb501c14 100644 --- a/vendor/symfony/translation/Catalogue/AbstractOperation.php +++ b/vendor/symfony/translation/Catalogue/AbstractOperation.php @@ -13,6 +13,8 @@ use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\MessageCatalogueInterface; +use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Exception\LogicException; /** * Base catalogues binary operation class. @@ -72,18 +74,17 @@ abstract class AbstractOperation implements OperationInterface * @param MessageCatalogueInterface $source The source catalogue * @param MessageCatalogueInterface $target The target catalogue * - * @throws \LogicException + * @throws LogicException */ public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target) { if ($source->getLocale() !== $target->getLocale()) { - throw new \LogicException('Operated catalogues must belong to the same locale.'); + throw new LogicException('Operated catalogues must belong to the same locale.'); } $this->source = $source; $this->target = $target; $this->result = new MessageCatalogue($source->getLocale()); - $this->domains = null; $this->messages = array(); } @@ -105,7 +106,7 @@ public function getDomains() public function getMessages($domain) { if (!in_array($domain, $this->getDomains())) { - throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); + throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); } if (!isset($this->messages[$domain]['all'])) { @@ -121,7 +122,7 @@ public function getMessages($domain) public function getNewMessages($domain) { if (!in_array($domain, $this->getDomains())) { - throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); + throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); } if (!isset($this->messages[$domain]['new'])) { @@ -137,7 +138,7 @@ public function getNewMessages($domain) public function getObsoleteMessages($domain) { if (!in_array($domain, $this->getDomains())) { - throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); + throw new InvalidArgumentException(sprintf('Invalid domain: %s.', $domain)); } if (!isset($this->messages[$domain]['obsolete'])) { diff --git a/vendor/symfony/translation/Catalogue/DiffOperation.php b/vendor/symfony/translation/Catalogue/DiffOperation.php deleted file mode 100644 index cb9a6f5b..00000000 --- a/vendor/symfony/translation/Catalogue/DiffOperation.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Translation\Catalogue; - -@trigger_error('The '.__NAMESPACE__.'\DiffOperation class is deprecated since version 2.8 and will be removed in 3.0. Use the TargetOperation class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * Diff operation between two catalogues. - * - * The name of 'Diff' is misleading because the operation - * has nothing to do with diff: - * - * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target} - * all = intersection ∪ (target ∖ intersection) = target - * new = all ∖ source = {x: x ∈ target ∧ x ∉ source} - * obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target} - * - * @author Jean-François Simon - * - * @deprecated since version 2.8, to be removed in 3.0. Use TargetOperation instead. - */ -class DiffOperation extends TargetOperation -{ -} diff --git a/vendor/symfony/translation/DataCollector/TranslationDataCollector.php b/vendor/symfony/translation/DataCollector/TranslationDataCollector.php index cb59d0a7..6b5e165a 100644 --- a/vendor/symfony/translation/DataCollector/TranslationDataCollector.php +++ b/vendor/symfony/translation/DataCollector/TranslationDataCollector.php @@ -101,12 +101,12 @@ private function sanitizeCollectedMessages($messages) if (!isset($result[$messageId])) { $message['count'] = 1; - $message['parameters'] = !empty($message['parameters']) ? array($message['parameters']) : array(); + $message['parameters'] = !empty($message['parameters']) ? array($this->cloneVar($message['parameters'])) : array(); $messages[$key]['translation'] = $this->sanitizeString($message['translation']); $result[$messageId] = $message; } else { if (!empty($message['parameters'])) { - $result[$messageId]['parameters'][] = $message['parameters']; + $result[$messageId]['parameters'][] = $this->cloneVar($message['parameters']); } ++$result[$messageId]['count']; diff --git a/vendor/symfony/translation/DataCollectorTranslator.php b/vendor/symfony/translation/DataCollectorTranslator.php index 50e4a2ff..cdfde100 100644 --- a/vendor/symfony/translation/DataCollectorTranslator.php +++ b/vendor/symfony/translation/DataCollectorTranslator.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +use Symfony\Component\Translation\Exception\InvalidArgumentException; + /** * @author Abdellatif Ait boudad */ @@ -36,7 +38,7 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter public function __construct(TranslatorInterface $translator) { if (!$translator instanceof TranslatorBagInterface) { - throw new \InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator))); + throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator))); } $this->translator = $translator; diff --git a/vendor/symfony/translation/Dumper/CsvFileDumper.php b/vendor/symfony/translation/Dumper/CsvFileDumper.php index afadcd88..fe5dccb4 100644 --- a/vendor/symfony/translation/Dumper/CsvFileDumper.php +++ b/vendor/symfony/translation/Dumper/CsvFileDumper.php @@ -23,16 +23,6 @@ class CsvFileDumper extends FileDumper private $delimiter = ';'; private $enclosure = '"'; - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain = 'messages') - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/FileDumper.php b/vendor/symfony/translation/Dumper/FileDumper.php index b217d108..b2b50cfc 100644 --- a/vendor/symfony/translation/Dumper/FileDumper.php +++ b/vendor/symfony/translation/Dumper/FileDumper.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Translation\Dumper; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Exception\RuntimeException; /** * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s). @@ -64,7 +66,7 @@ public function setBackup($backup) public function dump(MessageCatalogue $messages, $options = array()) { if (!array_key_exists('path', $options)) { - throw new \InvalidArgumentException('The file dumper needs a path option.'); + throw new InvalidArgumentException('The file dumper needs a path option.'); } // save a file for each domain @@ -73,12 +75,13 @@ public function dump(MessageCatalogue $messages, $options = array()) $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale()); if (file_exists($fullpath)) { if ($this->backup) { + @trigger_error('Creating a backup while dumping a message catalogue is deprecated since version 3.1 and will be removed in 4.0. Use TranslationWriter::disableBackup() to disable the backup.', E_USER_DEPRECATED); copy($fullpath, $fullpath.'~'); } } else { $directory = dirname($fullpath); if (!file_exists($directory) && !@mkdir($directory, 0777, true)) { - throw new \RuntimeException(sprintf('Unable to create directory "%s".', $directory)); + throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory)); } } // save file @@ -89,35 +92,13 @@ public function dump(MessageCatalogue $messages, $options = array()) /** * Transforms a domain of a message catalogue to its string representation. * - * Override this function in child class if $options is used for message formatting. - * * @param MessageCatalogue $messages * @param string $domain * @param array $options * * @return string representation */ - public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) - { - @trigger_error('The '.__METHOD__.' method will replace the format method in 3.0. You should overwrite it instead of overwriting format instead.', E_USER_DEPRECATED); - - return $this->format($messages, $domain); - } - - /** - * Transforms a domain of a message catalogue to its string representation. - * - * @param MessageCatalogue $messages - * @param string $domain - * - * @return string representation - * - * @deprecated since version 2.8, to be removed in 3.0. Overwrite formatCatalogue() instead. - */ - protected function format(MessageCatalogue $messages, $domain) - { - throw new \LogicException('The "FileDumper::format" method needs to be overwritten, you should implement either "format" or "formatCatalogue".'); - } + abstract public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()); /** * Gets the file extension of the dumper. diff --git a/vendor/symfony/translation/Dumper/IcuResFileDumper.php b/vendor/symfony/translation/Dumper/IcuResFileDumper.php index 049b98c7..77ce27b2 100644 --- a/vendor/symfony/translation/Dumper/IcuResFileDumper.php +++ b/vendor/symfony/translation/Dumper/IcuResFileDumper.php @@ -25,16 +25,6 @@ class IcuResFileDumper extends FileDumper */ protected $relativePathTemplate = '%domain%/%locale%.%extension%'; - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain = 'messages') - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/IniFileDumper.php b/vendor/symfony/translation/Dumper/IniFileDumper.php index 36be230b..9ed37540 100644 --- a/vendor/symfony/translation/Dumper/IniFileDumper.php +++ b/vendor/symfony/translation/Dumper/IniFileDumper.php @@ -20,16 +20,6 @@ */ class IniFileDumper extends FileDumper { - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain = 'messages') - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/JsonFileDumper.php b/vendor/symfony/translation/Dumper/JsonFileDumper.php index 022e165d..08b538e1 100644 --- a/vendor/symfony/translation/Dumper/JsonFileDumper.php +++ b/vendor/symfony/translation/Dumper/JsonFileDumper.php @@ -20,16 +20,6 @@ */ class JsonFileDumper extends FileDumper { - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain = 'messages') - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/MoFileDumper.php b/vendor/symfony/translation/Dumper/MoFileDumper.php index c2527958..00a33d25 100644 --- a/vendor/symfony/translation/Dumper/MoFileDumper.php +++ b/vendor/symfony/translation/Dumper/MoFileDumper.php @@ -21,16 +21,6 @@ */ class MoFileDumper extends FileDumper { - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain = 'messages') - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/PhpFileDumper.php b/vendor/symfony/translation/Dumper/PhpFileDumper.php index 891f2f97..c7c37aac 100644 --- a/vendor/symfony/translation/Dumper/PhpFileDumper.php +++ b/vendor/symfony/translation/Dumper/PhpFileDumper.php @@ -20,16 +20,6 @@ */ class PhpFileDumper extends FileDumper { - /** - * {@inheritdoc} - */ - protected function format(MessageCatalogue $messages, $domain) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/PoFileDumper.php b/vendor/symfony/translation/Dumper/PoFileDumper.php index 9e27bc7d..ed4418b1 100644 --- a/vendor/symfony/translation/Dumper/PoFileDumper.php +++ b/vendor/symfony/translation/Dumper/PoFileDumper.php @@ -20,16 +20,6 @@ */ class PoFileDumper extends FileDumper { - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain = 'messages') - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/QtFileDumper.php b/vendor/symfony/translation/Dumper/QtFileDumper.php index 5c2a4344..a9073f26 100644 --- a/vendor/symfony/translation/Dumper/QtFileDumper.php +++ b/vendor/symfony/translation/Dumper/QtFileDumper.php @@ -20,16 +20,6 @@ */ class QtFileDumper extends FileDumper { - /** - * {@inheritdoc} - */ - public function format(MessageCatalogue $messages, $domain) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Dumper/XliffFileDumper.php b/vendor/symfony/translation/Dumper/XliffFileDumper.php index 6a7f6556..47b05c81 100644 --- a/vendor/symfony/translation/Dumper/XliffFileDumper.php +++ b/vendor/symfony/translation/Dumper/XliffFileDumper.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation\Dumper; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Exception\InvalidArgumentException; /** * XliffFileDumper generates xliff files from a message catalogue. @@ -43,17 +44,7 @@ public function formatCatalogue(MessageCatalogue $messages, $domain, array $opti return $this->dumpXliff2($defaultLocale, $messages, $domain, $options); } - throw new \InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion)); - } - - /** - * {@inheritdoc} - */ - protected function format(MessageCatalogue $messages, $domain) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); + throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion)); } /** diff --git a/vendor/symfony/translation/Dumper/YamlFileDumper.php b/vendor/symfony/translation/Dumper/YamlFileDumper.php index 8e496488..fdd113b1 100644 --- a/vendor/symfony/translation/Dumper/YamlFileDumper.php +++ b/vendor/symfony/translation/Dumper/YamlFileDumper.php @@ -14,6 +14,7 @@ use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Util\ArrayConverter; use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Translation\Exception\LogicException; /** * YamlFileDumper generates yaml files from a message catalogue. @@ -28,7 +29,7 @@ class YamlFileDumper extends FileDumper public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array()) { if (!class_exists('Symfony\Component\Yaml\Yaml')) { - throw new \LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.'); + throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.'); } $data = $messages->all($domain); @@ -44,16 +45,6 @@ public function formatCatalogue(MessageCatalogue $messages, $domain, array $opti return Yaml::dump($data); } - /** - * {@inheritdoc} - */ - protected function format(MessageCatalogue $messages, $domain) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the formatCatalogue() method instead.', E_USER_DEPRECATED); - - return $this->formatCatalogue($messages, $domain); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/translation/Exception/InvalidArgumentException.php b/vendor/symfony/translation/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..90d06690 --- /dev/null +++ b/vendor/symfony/translation/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Exception; + +/** + * Base InvalidArgumentException for the Translation component. + * + * @author Abdellatif Ait boudad + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/translation/Exception/LogicException.php b/vendor/symfony/translation/Exception/LogicException.php new file mode 100644 index 00000000..9019c7e7 --- /dev/null +++ b/vendor/symfony/translation/Exception/LogicException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Exception; + +/** + * Base LogicException for Translation component. + * + * @author Abdellatif Ait boudad + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/translation/Exception/RuntimeException.php b/vendor/symfony/translation/Exception/RuntimeException.php new file mode 100644 index 00000000..dcd79408 --- /dev/null +++ b/vendor/symfony/translation/Exception/RuntimeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Exception; + +/** + * Base RuntimeException for the Translation component. + * + * @author Abdellatif Ait boudad + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/translation/Extractor/AbstractFileExtractor.php b/vendor/symfony/translation/Extractor/AbstractFileExtractor.php index 57fd4938..4b6b155d 100644 --- a/vendor/symfony/translation/Extractor/AbstractFileExtractor.php +++ b/vendor/symfony/translation/Extractor/AbstractFileExtractor.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation\Extractor; +use Symfony\Component\Translation\Exception\InvalidArgumentException; + /** * Base class used by classes that extract translation messages from files. * @@ -56,12 +58,12 @@ private function toSplFileInfo($file) * * @return bool * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ protected function isFile($file) { if (!is_file($file)) { - throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $file)); + throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file)); } return true; diff --git a/vendor/symfony/translation/Interval.php b/vendor/symfony/translation/Interval.php index 2a51156e..9e2cae64 100644 --- a/vendor/symfony/translation/Interval.php +++ b/vendor/symfony/translation/Interval.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +use Symfony\Component\Translation\Exception\InvalidArgumentException; + /** * Tests if a given number belongs to a given math interval. * @@ -41,14 +43,14 @@ class Interval * * @return bool * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public static function test($number, $interval) { $interval = trim($interval); if (!preg_match('/^'.self::getIntervalRegexp().'$/x', $interval, $matches)) { - throw new \InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval)); + throw new InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval)); } if ($matches[1]) { diff --git a/vendor/symfony/translation/Loader/MoFileLoader.php b/vendor/symfony/translation/Loader/MoFileLoader.php index 025fcd89..928cc9df 100644 --- a/vendor/symfony/translation/Loader/MoFileLoader.php +++ b/vendor/symfony/translation/Loader/MoFileLoader.php @@ -137,7 +137,7 @@ protected function loadResource($resource) } /** - * Reads an unsigned long from stream respecting endianess. + * Reads an unsigned long from stream respecting endianness. * * @param resource $stream * @param bool $isBigEndian diff --git a/vendor/symfony/translation/Loader/XliffFileLoader.php b/vendor/symfony/translation/Loader/XliffFileLoader.php index 4e2b7c18..e3cab654 100644 --- a/vendor/symfony/translation/Loader/XliffFileLoader.php +++ b/vendor/symfony/translation/Loader/XliffFileLoader.php @@ -15,6 +15,7 @@ use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Exception\InvalidResourceException; use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Translation\Exception\InvalidArgumentException; use Symfony\Component\Config\Resource\FileResource; /** @@ -98,6 +99,7 @@ private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, $ if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) { $metadata['notes'] = $notes; } + if (isset($translation->target) && $translation->target->attributes()) { $metadata['target-attributes'] = array(); foreach ($translation->target->attributes() as $key => $value) { @@ -105,6 +107,10 @@ private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, $ } } + if (isset($attributes['id'])) { + $metadata['id'] = (string) $attributes['id']; + } + $catalogue->setMetadata((string) $source, $metadata, $domain); } } @@ -166,7 +172,6 @@ private function utf8ToCharset($content, $encoding = null) * @param \DOMDocument $dom * @param string $schema source of the schema * - * @throws \RuntimeException * @throws InvalidResourceException */ private function validateSchema($file, \DOMDocument $dom, $schema) @@ -198,7 +203,7 @@ private function getSchema($xliffVersion) $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-2.0.xsd'); $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd'; } else { - throw new \InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion)); + throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion)); } return $this->fixXmlLocation($schemaSource, $xmlUri); @@ -223,6 +228,7 @@ private function fixXmlLocation($schemaSource, $xmlUri) $parts = explode('/', str_replace('\\', '/', $tmpfile)); } } + $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; $newPath = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts)); @@ -262,7 +268,7 @@ private function getXmlErrors($internalErrors) * * @param \DOMDocument $dom * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException * * @return string */ @@ -278,7 +284,7 @@ private function getVersionNumber(\DOMDocument $dom) $namespace = $xliff->attributes->getNamedItem('xmlns'); if ($namespace) { if (substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34) !== 0) { - throw new \InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace)); + throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace)); } return substr($namespace, 34); @@ -289,7 +295,7 @@ private function getVersionNumber(\DOMDocument $dom) return '1.2'; } - /* + /** * @param \SimpleXMLElement|null $noteElement * @param string|null $encoding * @@ -303,6 +309,7 @@ private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, $enco return $notes; } + /** @var \SimpleXMLElement $xmlNote */ foreach ($noteElement as $xmlNote) { $noteAttributes = $xmlNote->attributes(); $note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding)); diff --git a/vendor/symfony/translation/Loader/YamlFileLoader.php b/vendor/symfony/translation/Loader/YamlFileLoader.php index 5d9a3ade..41e390d0 100644 --- a/vendor/symfony/translation/Loader/YamlFileLoader.php +++ b/vendor/symfony/translation/Loader/YamlFileLoader.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation\Loader; use Symfony\Component\Translation\Exception\InvalidResourceException; +use Symfony\Component\Translation\Exception\LogicException; use Symfony\Component\Yaml\Parser as YamlParser; use Symfony\Component\Yaml\Exception\ParseException; @@ -31,7 +32,7 @@ protected function loadResource($resource) { if (null === $this->yamlParser) { if (!class_exists('Symfony\Component\Yaml\Parser')) { - throw new \LogicException('Loading translations from the YAML format requires the Symfony Yaml component.'); + throw new LogicException('Loading translations from the YAML format requires the Symfony Yaml component.'); } $this->yamlParser = new YamlParser(); diff --git a/vendor/symfony/translation/LoggingTranslator.php b/vendor/symfony/translation/LoggingTranslator.php index b259df5e..469b3d13 100644 --- a/vendor/symfony/translation/LoggingTranslator.php +++ b/vendor/symfony/translation/LoggingTranslator.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation; use Psr\Log\LoggerInterface; +use Symfony\Component\Translation\Exception\InvalidArgumentException; /** * @author Abdellatif Ait boudad @@ -35,7 +36,7 @@ class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface public function __construct(TranslatorInterface $translator, LoggerInterface $logger) { if (!$translator instanceof TranslatorBagInterface) { - throw new \InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator))); + throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator))); } $this->translator = $translator; diff --git a/vendor/symfony/translation/MessageCatalogue.php b/vendor/symfony/translation/MessageCatalogue.php index 73649fb6..c82b73e1 100644 --- a/vendor/symfony/translation/MessageCatalogue.php +++ b/vendor/symfony/translation/MessageCatalogue.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation; use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Translation\Exception\LogicException; /** * MessageCatalogue. @@ -143,7 +144,7 @@ public function add($messages, $domain = 'messages') public function addCatalogue(MessageCatalogueInterface $catalogue) { if ($catalogue->getLocale() !== $this->locale) { - throw new \LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale)); + throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale)); } foreach ($catalogue->all() as $domain => $messages) { @@ -169,14 +170,14 @@ public function addFallbackCatalogue(MessageCatalogueInterface $catalogue) $c = $catalogue; while ($c = $c->getFallbackCatalogue()) { if ($c->getLocale() === $this->getLocale()) { - throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); + throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); } } $c = $this; do { if ($c->getLocale() === $catalogue->getLocale()) { - throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); + throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale())); } foreach ($catalogue->getResources() as $resource) { diff --git a/vendor/symfony/translation/MessageSelector.php b/vendor/symfony/translation/MessageSelector.php index bdbb0f96..c6134191 100644 --- a/vendor/symfony/translation/MessageSelector.php +++ b/vendor/symfony/translation/MessageSelector.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +use Symfony\Component\Translation\Exception\InvalidArgumentException; + /** * MessageSelector. * @@ -43,15 +45,15 @@ class MessageSelector * * @return string * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function choose($message, $number, $locale) { - $parts = explode('|', $message); + preg_match_all('/(?:\|\||[^\|])++/', $message, $parts); $explicitRules = array(); $standardRules = array(); - foreach ($parts as $part) { - $part = trim($part); + foreach ($parts[0] as $part) { + $part = trim(str_replace('||', '|', $part)); if (preg_match('/^(?P'.Interval::getIntervalRegexp().')\s*(?P.*?)$/xs', $part, $matches)) { $explicitRules[$matches['interval']] = $matches['message']; @@ -74,11 +76,11 @@ public function choose($message, $number, $locale) if (!isset($standardRules[$position])) { // when there's exactly one rule given, and that rule is a standard // rule, use this rule - if (1 === count($parts) && isset($standardRules[0])) { + if (1 === count($parts[0]) && isset($standardRules[0])) { return $standardRules[0]; } - throw new \InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number)); + throw new InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number)); } return $standardRules[$position]; diff --git a/vendor/symfony/translation/PluralizationRules.php b/vendor/symfony/translation/PluralizationRules.php index 09748211..ef2be709 100644 --- a/vendor/symfony/translation/PluralizationRules.php +++ b/vendor/symfony/translation/PluralizationRules.php @@ -192,10 +192,8 @@ public static function get($number, $locale) * * @param callable $rule A PHP callable * @param string $locale The locale - * - * @throws \LogicException */ - public static function set($rule, $locale) + public static function set(callable $rule, $locale) { if ('pt_BR' === $locale) { // temporary set a locale for brazilian @@ -206,10 +204,6 @@ public static function set($rule, $locale) $locale = substr($locale, 0, -strlen(strrchr($locale, '_'))); } - if (!is_callable($rule)) { - throw new \LogicException('The given rule can not be called'); - } - self::$rules[$locale] = $rule; } } diff --git a/vendor/symfony/translation/Translator.php b/vendor/symfony/translation/Translator.php index ac0d757a..5f8eb033 100644 --- a/vendor/symfony/translation/Translator.php +++ b/vendor/symfony/translation/Translator.php @@ -13,6 +13,8 @@ use Symfony\Component\Translation\Loader\LoaderInterface; use Symfony\Component\Translation\Exception\NotFoundResourceException; +use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Exception\RuntimeException; use Symfony\Component\Config\ConfigCacheInterface; use Symfony\Component\Config\ConfigCacheFactoryInterface; use Symfony\Component\Config\ConfigCacheFactory; @@ -32,7 +34,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface /** * @var string */ - protected $locale; + private $locale; /** * @var array @@ -77,7 +79,7 @@ class Translator implements TranslatorInterface, TranslatorBagInterface * @param string|null $cacheDir The directory to use for the cache * @param bool $debug Use cache in debug mode ? * - * @throws \InvalidArgumentException If a locale contains invalid characters + * @throws InvalidArgumentException If a locale contains invalid characters */ public function __construct($locale, MessageSelector $selector = null, $cacheDir = null, $debug = false) { @@ -116,7 +118,7 @@ public function addLoader($format, LoaderInterface $loader) * @param string $locale The locale * @param string $domain The domain * - * @throws \InvalidArgumentException If the locale contains invalid characters + * @throws InvalidArgumentException If the locale contains invalid characters */ public function addResource($format, $resource, $locale, $domain = null) { @@ -152,28 +154,12 @@ public function getLocale() return $this->locale; } - /** - * Sets the fallback locale(s). - * - * @param string|array $locales The fallback locale(s) - * - * @throws \InvalidArgumentException If a locale contains invalid characters - * - * @deprecated since version 2.3, to be removed in 3.0. Use setFallbackLocales() instead - */ - public function setFallbackLocale($locales) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0. Use the setFallbackLocales() method instead.', E_USER_DEPRECATED); - - $this->setFallbackLocales(is_array($locales) ? $locales : array($locales)); - } - /** * Sets the fallback locales. * * @param array $locales The fallback locales * - * @throws \InvalidArgumentException If a locale contains invalid characters + * @throws InvalidArgumentException If a locale contains invalid characters */ public function setFallbackLocales(array $locales) { @@ -214,6 +200,10 @@ public function trans($id, array $parameters = array(), $domain = null, $locale */ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) { + $parameters = array_merge(array( + '%count%' => $number, + ), $parameters); + if (null === $domain) { $domain = 'messages'; } @@ -261,28 +251,6 @@ protected function getLoaders() return $this->loaders; } - /** - * Collects all messages for the given locale. - * - * @param string|null $locale Locale of translations, by default is current locale - * - * @return array[array] indexed by catalog - * - * @deprecated since version 2.8, to be removed in 3.0. Use TranslatorBagInterface::getCatalogue() method instead. - */ - public function getMessages($locale = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use TranslatorBagInterface::getCatalogue() method instead.', E_USER_DEPRECATED); - - $catalogue = $this->getCatalogue($locale); - $messages = $catalogue->all(); - while ($catalogue = $catalogue->getFallbackCatalogue()) { - $messages = array_replace_recursive($catalogue->all(), $messages); - } - - return $messages; - } - /** * @param string $locale */ @@ -323,10 +291,9 @@ private function initializeCacheCatalogue($locale) } $this->assertValidLocale($locale); - $self = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0. $cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale), - function (ConfigCacheInterface $cache) use ($self, $locale) { - $self->dumpCatalogue($locale, $cache); + function (ConfigCacheInterface $cache) use ($locale) { + $this->dumpCatalogue($locale, $cache); } ); @@ -339,12 +306,7 @@ function (ConfigCacheInterface $cache) use ($self, $locale) { $this->catalogues[$locale] = include $cache->getPath(); } - /** - * This method is public because it needs to be callable from a closure in PHP 5.3. It should be made protected (or even private, if possible) in 3.0. - * - * @internal - */ - public function dumpCatalogue($locale, ConfigCacheInterface $cache) + private function dumpCatalogue($locale, ConfigCacheInterface $cache) { $this->initializeCatalogue($locale); $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]); @@ -411,7 +373,7 @@ private function doLoadCatalogue($locale) if (isset($this->resources[$locale])) { foreach ($this->resources[$locale] as $resource) { if (!isset($this->loaders[$resource[0]])) { - throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0])); + throw new RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0])); } $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2])); } @@ -424,7 +386,7 @@ private function loadFallbackCatalogues($locale) foreach ($this->computeFallbackLocales($locale) as $fallback) { if (!isset($this->catalogues[$fallback])) { - $this->loadCatalogue($fallback); + $this->initializeCatalogue($fallback); } $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all()); @@ -459,12 +421,12 @@ protected function computeFallbackLocales($locale) * * @param string $locale Locale to tests * - * @throws \InvalidArgumentException If the locale contains invalid characters + * @throws InvalidArgumentException If the locale contains invalid characters */ protected function assertValidLocale($locale) { if (1 !== preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) { - throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale)); + throw new InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale)); } } diff --git a/vendor/symfony/translation/TranslatorBagInterface.php b/vendor/symfony/translation/TranslatorBagInterface.php index 14fbb17f..5e49e2dd 100644 --- a/vendor/symfony/translation/TranslatorBagInterface.php +++ b/vendor/symfony/translation/TranslatorBagInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +use Symfony\Component\Translation\Exception\InvalidArgumentException; + /** * TranslatorBagInterface. * @@ -25,7 +27,7 @@ interface TranslatorBagInterface * * @return MessageCatalogueInterface * - * @throws \InvalidArgumentException If the locale contains invalid characters + * @throws InvalidArgumentException If the locale contains invalid characters */ public function getCatalogue($locale = null); } diff --git a/vendor/symfony/translation/TranslatorInterface.php b/vendor/symfony/translation/TranslatorInterface.php index 6916c335..9fcfd5bc 100644 --- a/vendor/symfony/translation/TranslatorInterface.php +++ b/vendor/symfony/translation/TranslatorInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Translation; +use Symfony\Component\Translation\Exception\InvalidArgumentException; + /** * TranslatorInterface. * @@ -28,7 +30,7 @@ interface TranslatorInterface * * @return string The translated string * - * @throws \InvalidArgumentException If the locale contains invalid characters + * @throws InvalidArgumentException If the locale contains invalid characters */ public function trans($id, array $parameters = array(), $domain = null, $locale = null); @@ -43,7 +45,7 @@ public function trans($id, array $parameters = array(), $domain = null, $locale * * @return string The translated string * - * @throws \InvalidArgumentException If the locale contains invalid characters + * @throws InvalidArgumentException If the locale contains invalid characters */ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null); @@ -52,7 +54,7 @@ public function transChoice($id, $number, array $parameters = array(), $domain = * * @param string $locale The locale * - * @throws \InvalidArgumentException If the locale contains invalid characters + * @throws InvalidArgumentException If the locale contains invalid characters */ public function setLocale($locale); diff --git a/vendor/symfony/translation/Util/ArrayConverter.php b/vendor/symfony/translation/Util/ArrayConverter.php index 60a55e9d..9c0a420a 100644 --- a/vendor/symfony/translation/Util/ArrayConverter.php +++ b/vendor/symfony/translation/Util/ArrayConverter.php @@ -62,7 +62,7 @@ private static function &getElementByPath(array &$tree, array $parts) * $tree['foo'] was string before we found array {bar: test2}. * Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2'; */ - $elem = &$elem[ implode('.', array_slice($parts, $i)) ]; + $elem = &$elem[implode('.', array_slice($parts, $i))]; break; } $parentOfElem = &$elem; diff --git a/vendor/symfony/translation/Writer/TranslationWriter.php b/vendor/symfony/translation/Writer/TranslationWriter.php index 2f5eaa1e..901a8894 100644 --- a/vendor/symfony/translation/Writer/TranslationWriter.php +++ b/vendor/symfony/translation/Writer/TranslationWriter.php @@ -13,6 +13,8 @@ use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Translation\Dumper\DumperInterface; +use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Exception\RuntimeException; /** * TranslationWriter writes translation messages. @@ -68,19 +70,19 @@ public function getFormats() * @param string $format The format to use to dump the messages * @param array $options Options that are passed to the dumper * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function writeTranslations(MessageCatalogue $catalogue, $format, $options = array()) { if (!isset($this->dumpers[$format])) { - throw new \InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format)); + throw new InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format)); } // get the right dumper $dumper = $this->dumpers[$format]; if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) { - throw new \RuntimeException(sprintf('Translation Writer was not able to create directory "%s"', $options['path'])); + throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s"', $options['path'])); } // save diff --git a/vendor/symfony/translation/composer.json b/vendor/symfony/translation/composer.json index 79ff646c..d1aed828 100644 --- a/vendor/symfony/translation/composer.json +++ b/vendor/symfony/translation/composer.json @@ -16,17 +16,17 @@ } ], "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/config": "~2.8", - "symfony/intl": "~2.4|~3.0.0", - "symfony/yaml": "~2.2|~3.0.0", + "symfony/config": "~2.8|~3.0", + "symfony/intl": "^2.8.18|^3.2.5", + "symfony/yaml": "~2.8|~3.0", "psr/log": "~1.0" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "suggest": { "symfony/config": "", @@ -42,7 +42,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/translation/phpunit.xml.dist b/vendor/symfony/translation/phpunit.xml.dist index c25ec5ed..1fafa469 100644 --- a/vendor/symfony/translation/phpunit.xml.dist +++ b/vendor/symfony/translation/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/validator/CHANGELOG.md b/vendor/symfony/validator/CHANGELOG.md index 0ff667b7..78a5ad15 100644 --- a/vendor/symfony/validator/CHANGELOG.md +++ b/vendor/symfony/validator/CHANGELOG.md @@ -1,6 +1,17 @@ CHANGELOG ========= +3.2.0 +----- + + * deprecated `Tests\Constraints\AbstractContraintValidatorTest` in favor of `Test\ConstraintValidatorTestCase` + +3.1.0 +----- + + * deprecated `DateTimeValidator::PATTERN` constant + * added a `format` option to the `DateTime` constraint + 2.8.0 ----- diff --git a/vendor/symfony/validator/ClassBasedInterface.php b/vendor/symfony/validator/ClassBasedInterface.php deleted file mode 100644 index c57da274..00000000 --- a/vendor/symfony/validator/ClassBasedInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * An object backed by a PHP class. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Mapping\ClassMetadataInterface} instead. - */ -interface ClassBasedInterface -{ - /** - * Returns the name of the backing PHP class. - * - * @return string The name of the backing class - */ - public function getClassName(); -} diff --git a/vendor/symfony/validator/ConstraintValidator.php b/vendor/symfony/validator/ConstraintValidator.php index 804a9b2a..ece44000 100644 --- a/vendor/symfony/validator/ConstraintValidator.php +++ b/vendor/symfony/validator/ConstraintValidator.php @@ -11,9 +11,7 @@ namespace Symfony\Component\Validator; -use Symfony\Component\Validator\Context\ExecutionContextInterface as ExecutionContextInterface2Dot5; -use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface; -use Symfony\Component\Validator\Violation\LegacyConstraintViolationBuilder; +use Symfony\Component\Validator\Context\ExecutionContextInterface; /** * Base class for constraint validators. @@ -38,7 +36,7 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface const OBJECT_TO_STRING = 2; /** - * @var ExecutionContextInterface2Dot5 + * @var ExecutionContextInterface */ protected $context; @@ -50,51 +48,6 @@ public function initialize(ExecutionContextInterface $context) $this->context = $context; } - /** - * Wrapper for {@link ExecutionContextInterface::buildViolation} that - * supports the 2.4 context API. - * - * @param string $message The violation message - * @param array $parameters The message parameters - * - * @return ConstraintViolationBuilderInterface The violation builder - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - protected function buildViolation($message, array $parameters = array()) - { - @trigger_error('The '.__METHOD__.' is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - if ($this->context instanceof ExecutionContextInterface2Dot5) { - return $this->context->buildViolation($message, $parameters); - } - - return new LegacyConstraintViolationBuilder($this->context, $message, $parameters); - } - - /** - * Wrapper for {@link ExecutionContextInterface::buildViolation} that - * supports the 2.4 context API. - * - * @param ExecutionContextInterface $context The context to use - * @param string $message The violation message - * @param array $parameters The message parameters - * - * @return ConstraintViolationBuilderInterface The violation builder - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - protected function buildViolationInContext(ExecutionContextInterface $context, $message, array $parameters = array()) - { - @trigger_error('The '.__METHOD__.' is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - if ($context instanceof ExecutionContextInterface2Dot5) { - return $context->buildViolation($message, $parameters); - } - - return new LegacyConstraintViolationBuilder($context, $message, $parameters); - } - /** * Returns a string representation of the type of the value. * @@ -136,7 +89,7 @@ protected function formatTypeOf($value) */ protected function formatValue($value, $format = 0) { - $isDateTime = $value instanceof \DateTime || $value instanceof \DateTimeInterface; + $isDateTime = $value instanceof \DateTimeInterface; if (($format & self::PRETTY_DATE) && $isDateTime) { if (class_exists('IntlDateFormatter')) { diff --git a/vendor/symfony/validator/ConstraintValidatorFactory.php b/vendor/symfony/validator/ConstraintValidatorFactory.php index cc6981b9..86e44e2a 100644 --- a/vendor/symfony/validator/ConstraintValidatorFactory.php +++ b/vendor/symfony/validator/ConstraintValidatorFactory.php @@ -26,11 +26,8 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface { protected $validators = array(); - private $propertyAccessor; - - public function __construct($propertyAccessor = null) + public function __construct() { - $this->propertyAccessor = $propertyAccessor; } /** @@ -42,7 +39,7 @@ public function getInstance(Constraint $constraint) if (!isset($this->validators[$className])) { $this->validators[$className] = 'validator.expression' === $className - ? new ExpressionValidator($this->propertyAccessor) + ? new ExpressionValidator() : new $className(); } diff --git a/vendor/symfony/validator/ConstraintValidatorInterface.php b/vendor/symfony/validator/ConstraintValidatorInterface.php index 85fd451a..b215346a 100644 --- a/vendor/symfony/validator/ConstraintValidatorInterface.php +++ b/vendor/symfony/validator/ConstraintValidatorInterface.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Validator; +use Symfony\Component\Validator\Context\ExecutionContextInterface; + /** * @author Bernhard Schussek */ diff --git a/vendor/symfony/validator/ConstraintViolation.php b/vendor/symfony/validator/ConstraintViolation.php index 516004a7..015aa741 100644 --- a/vendor/symfony/validator/ConstraintViolation.php +++ b/vendor/symfony/validator/ConstraintViolation.php @@ -141,19 +141,6 @@ public function getMessageTemplate() /** * {@inheritdoc} - * - * @deprecated since version 2.7, to be removed in 3.0. - * Use getParameters() instead - */ - public function getMessageParameters() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7, to be removed in 3.0. Use the ConstraintViolation::getParameters() method instead.', E_USER_DEPRECATED); - - return $this->parameters; - } - - /** - * Alias of {@link getMessageParameters()}. */ public function getParameters() { @@ -162,19 +149,6 @@ public function getParameters() /** * {@inheritdoc} - * - * @deprecated since version 2.7, to be removed in 3.0. - * Use getPlural() instead - */ - public function getMessagePluralization() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7, to be removed in 3.0. Use the ConstraintViolation::getPlural() method instead.', E_USER_DEPRECATED); - - return $this->plural; - } - - /** - * Alias of {@link getMessagePluralization()}. */ public function getPlural() { diff --git a/vendor/symfony/validator/ConstraintViolationInterface.php b/vendor/symfony/validator/ConstraintViolationInterface.php index 11028fe0..7499d890 100644 --- a/vendor/symfony/validator/ConstraintViolationInterface.php +++ b/vendor/symfony/validator/ConstraintViolationInterface.php @@ -46,7 +46,7 @@ public function getMessage(); * Returns the raw violation message. * * The raw violation message contains placeholders for the parameters - * returned by {@link getMessageParameters}. Typically you'll pass the + * returned by {@link getParameters}. Typically you'll pass the * message template and parameters to a translation engine. * * @return string The raw violation message @@ -60,9 +60,8 @@ public function getMessageTemplate(); * that appear in the message template. * * @see getMessageTemplate() - * @deprecated since version 2.7, to be replaced by getParameters() in 3.0. */ - public function getMessageParameters(); + public function getParameters(); /** * Returns a number for pluralizing the violation message. @@ -79,10 +78,8 @@ public function getMessageParameters(); * pluralization form (in this case "choices"). * * @return int|null The number to use to pluralize of the message - * - * @deprecated since version 2.7, to be replaced by getPlural() in 3.0. */ - public function getMessagePluralization(); + public function getPlural(); /** * Returns the root element of the validation. diff --git a/vendor/symfony/validator/Constraints/AbstractComparisonValidator.php b/vendor/symfony/validator/Constraints/AbstractComparisonValidator.php index ca0c3aa7..dbaa5cd0 100644 --- a/vendor/symfony/validator/Constraints/AbstractComparisonValidator.php +++ b/vendor/symfony/validator/Constraints/AbstractComparisonValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -48,28 +47,19 @@ public function validate($value, Constraint $constraint) // If $value is immutable, convert the compared value to a // DateTimeImmutable too $comparedValue = new \DatetimeImmutable($comparedValue); - } elseif ($value instanceof \DateTime || $value instanceof \DateTimeInterface) { + } elseif ($value instanceof \DateTimeInterface) { // Otherwise use DateTime $comparedValue = new \DateTime($comparedValue); } } if (!$this->compareValues($value, $comparedValue)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE)) - ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE)) - ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue)) - ->setCode($this->getErrorCode()) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE)) - ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE)) - ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue)) - ->setCode($this->getErrorCode()) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE)) + ->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE)) + ->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue)) + ->setCode($this->getErrorCode()) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/AllValidator.php b/vendor/symfony/validator/Constraints/AllValidator.php index 94ff8190..a5eb32bb 100644 --- a/vendor/symfony/validator/Constraints/AllValidator.php +++ b/vendor/symfony/validator/Constraints/AllValidator.php @@ -13,7 +13,6 @@ use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** @@ -40,17 +39,10 @@ public function validate($value, Constraint $constraint) $context = $this->context; - if ($context instanceof ExecutionContextInterface) { - $validator = $context->getValidator()->inContext($context); - - foreach ($value as $key => $element) { - $validator->atPath('['.$key.']')->validate($element, $constraint->constraints); - } - } else { - // 2.4 API - foreach ($value as $key => $element) { - $context->validateValue($element, $constraint->constraints, '['.$key.']'); - } + $validator = $context->getValidator()->inContext($context); + + foreach ($value as $key => $element) { + $validator->atPath('['.$key.']')->validate($element, $constraint->constraints); } } } diff --git a/vendor/symfony/validator/Constraints/BicValidator.php b/vendor/symfony/validator/Constraints/BicValidator.php index f476713c..d2188071 100644 --- a/vendor/symfony/validator/Constraints/BicValidator.php +++ b/vendor/symfony/validator/Constraints/BicValidator.php @@ -17,7 +17,7 @@ /** * @author Michael Hirschler * - * @link https://en.wikipedia.org/wiki/ISO_9362#Structure + * @see https://en.wikipedia.org/wiki/ISO_9362#Structure */ class BicValidator extends ConstraintValidator { diff --git a/vendor/symfony/validator/Constraints/BlankValidator.php b/vendor/symfony/validator/Constraints/BlankValidator.php index 4b9fd3d6..ca999b5a 100644 --- a/vendor/symfony/validator/Constraints/BlankValidator.php +++ b/vendor/symfony/validator/Constraints/BlankValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -31,17 +30,10 @@ public function validate($value, Constraint $constraint) } if ('' !== $value && null !== $value) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Blank::NOT_BLANK_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Blank::NOT_BLANK_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Blank::NOT_BLANK_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/Callback.php b/vendor/symfony/validator/Constraints/Callback.php index 36e6087e..4a43665b 100644 --- a/vendor/symfony/validator/Constraints/Callback.php +++ b/vendor/symfony/validator/Constraints/Callback.php @@ -26,13 +26,6 @@ class Callback extends Constraint */ public $callback; - /** - * @var array - * - * @deprecated since version 2.4, to be removed in 3.0. - */ - public $methods; - /** * {@inheritdoc} */ @@ -43,17 +36,8 @@ public function __construct($options = null) $options = $options['value']; } - if (is_array($options) && isset($options['methods'])) { - @trigger_error('The "methods" option of the '.__CLASS__.' class is deprecated since version 2.4 and will be removed in 3.0. Use the "callback" option instead.', E_USER_DEPRECATED); - } - - if (is_array($options) && !isset($options['callback']) && !isset($options['methods']) && !isset($options['groups']) && !isset($options['payload'])) { - if (is_callable($options) || !$options) { - $options = array('callback' => $options); - } else { - // @deprecated, to be removed in 3.0 - $options = array('methods' => $options); - } + if (is_array($options) && !isset($options['callback']) && !isset($options['groups']) && !isset($options['payload'])) { + $options = array('callback' => $options); } parent::__construct($options); diff --git a/vendor/symfony/validator/Constraints/CallbackValidator.php b/vendor/symfony/validator/Constraints/CallbackValidator.php index df492040..733ee43b 100644 --- a/vendor/symfony/validator/Constraints/CallbackValidator.php +++ b/vendor/symfony/validator/Constraints/CallbackValidator.php @@ -32,45 +32,29 @@ public function validate($object, Constraint $constraint) throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Callback'); } - if (null !== $constraint->callback && null !== $constraint->methods) { - throw new ConstraintDefinitionException( - 'The Callback constraint supports either the option "callback" '. - 'or "methods", but not both at the same time.' - ); - } - - // has to be an array so that we can differentiate between callables - // and method names - if (null !== $constraint->methods && !is_array($constraint->methods)) { - throw new UnexpectedTypeException($constraint->methods, 'array'); - } - - $methods = $constraint->methods ?: array($constraint->callback); - - foreach ($methods as $method) { - if ($method instanceof \Closure) { - $method($object, $this->context); - } elseif (is_array($method)) { - if (!is_callable($method)) { - if (isset($method[0]) && is_object($method[0])) { - $method[0] = get_class($method[0]); - } - throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable', json_encode($method))); + $method = $constraint->callback; + if ($method instanceof \Closure) { + $method($object, $this->context, $constraint->payload); + } elseif (is_array($method)) { + if (!is_callable($method)) { + if (isset($method[0]) && is_object($method[0])) { + $method[0] = get_class($method[0]); } + throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable', json_encode($method))); + } - call_user_func($method, $object, $this->context); - } elseif (null !== $object) { - if (!method_exists($object, $method)) { - throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, get_class($object))); - } + call_user_func($method, $object, $this->context, $constraint->payload); + } elseif (null !== $object) { + if (!method_exists($object, $method)) { + throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, get_class($object))); + } - $reflMethod = new \ReflectionMethod($object, $method); + $reflMethod = new \ReflectionMethod($object, $method); - if ($reflMethod->isStatic()) { - $reflMethod->invoke(null, $object, $this->context); - } else { - $reflMethod->invoke($object, $this->context); - } + if ($reflMethod->isStatic()) { + $reflMethod->invoke(null, $object, $this->context, $constraint->payload); + } else { + $reflMethod->invoke($object, $this->context, $constraint->payload); } } } diff --git a/vendor/symfony/validator/Constraints/CardSchemeValidator.php b/vendor/symfony/validator/Constraints/CardSchemeValidator.php index be54a0cf..36a9d8ad 100644 --- a/vendor/symfony/validator/Constraints/CardSchemeValidator.php +++ b/vendor/symfony/validator/Constraints/CardSchemeValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -102,17 +101,10 @@ public function validate($value, Constraint $constraint) } if (!is_numeric($value)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(CardScheme::NOT_NUMERIC_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(CardScheme::NOT_NUMERIC_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(CardScheme::NOT_NUMERIC_ERROR) + ->addViolation(); return; } @@ -128,16 +120,9 @@ public function validate($value, Constraint $constraint) } } - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(CardScheme::INVALID_FORMAT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(CardScheme::INVALID_FORMAT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(CardScheme::INVALID_FORMAT_ERROR) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/ChoiceValidator.php b/vendor/symfony/validator/Constraints/ChoiceValidator.php index 83cfc6e7..6c81b3b4 100644 --- a/vendor/symfony/validator/Constraints/ChoiceValidator.php +++ b/vendor/symfony/validator/Constraints/ChoiceValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; @@ -48,7 +47,8 @@ public function validate($value, Constraint $constraint) } if ($constraint->callback) { - if (!is_callable($choices = array($this->context->getClassName(), $constraint->callback)) + if (!is_callable($choices = array($this->context->getObject(), $constraint->callback)) + && !is_callable($choices = array($this->context->getClassName(), $constraint->callback)) && !is_callable($choices = $constraint->callback) ) { throw new ConstraintDefinitionException('The Choice constraint expects a valid callback'); @@ -58,22 +58,18 @@ public function validate($value, Constraint $constraint) $choices = $constraint->choices; } + if (false === $constraint->strict) { + @trigger_error('Setting the strict option of the Choice constraint to false is deprecated since version 3.2 and will be removed in 4.0.', E_USER_DEPRECATED); + } + if ($constraint->multiple) { foreach ($value as $_value) { if (!in_array($_value, $choices, $constraint->strict)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->multipleMessage) - ->setParameter('{{ value }}', $this->formatValue($_value)) - ->setCode(Choice::NO_SUCH_CHOICE_ERROR) - ->setInvalidValue($_value) - ->addViolation(); - } else { - $this->buildViolation($constraint->multipleMessage) - ->setParameter('{{ value }}', $this->formatValue($_value)) - ->setCode(Choice::NO_SUCH_CHOICE_ERROR) - ->setInvalidValue($_value) - ->addViolation(); - } + $this->context->buildViolation($constraint->multipleMessage) + ->setParameter('{{ value }}', $this->formatValue($_value)) + ->setCode(Choice::NO_SUCH_CHOICE_ERROR) + ->setInvalidValue($_value) + ->addViolation(); return; } @@ -82,52 +78,29 @@ public function validate($value, Constraint $constraint) $count = count($value); if ($constraint->min !== null && $count < $constraint->min) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->minMessage) - ->setParameter('{{ limit }}', $constraint->min) - ->setPlural((int) $constraint->min) - ->setCode(Choice::TOO_FEW_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->minMessage) - ->setParameter('{{ limit }}', $constraint->min) - ->setPlural((int) $constraint->min) - ->setCode(Choice::TOO_FEW_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->minMessage) + ->setParameter('{{ limit }}', $constraint->min) + ->setPlural((int) $constraint->min) + ->setCode(Choice::TOO_FEW_ERROR) + ->addViolation(); return; } if ($constraint->max !== null && $count > $constraint->max) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->maxMessage) - ->setParameter('{{ limit }}', $constraint->max) - ->setPlural((int) $constraint->max) - ->setCode(Choice::TOO_MANY_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->maxMessage) - ->setParameter('{{ limit }}', $constraint->max) - ->setPlural((int) $constraint->max) - ->setCode(Choice::TOO_MANY_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->maxMessage) + ->setParameter('{{ limit }}', $constraint->max) + ->setPlural((int) $constraint->max) + ->setCode(Choice::TOO_MANY_ERROR) + ->addViolation(); return; } } elseif (!in_array($value, $choices, $constraint->strict)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Choice::NO_SUCH_CHOICE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Choice::NO_SUCH_CHOICE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Choice::NO_SUCH_CHOICE_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/Collection/Optional.php b/vendor/symfony/validator/Constraints/Collection/Optional.php deleted file mode 100644 index 68471f92..00000000 --- a/vendor/symfony/validator/Constraints/Collection/Optional.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints\Collection; - -@trigger_error('The '.__NAMESPACE__.'\Optional class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Validator\Constraints\Optional class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Validator\Constraints\Optional as BaseOptional; - -/** - * @Annotation - * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) - * - * @author Bernhard Schussek - * - * @deprecated since version 2.3, to be removed in 3.0. - * Use {@link \Symfony\Component\Validator\Constraints\Optional} instead. - */ -class Optional extends BaseOptional -{ -} diff --git a/vendor/symfony/validator/Constraints/Collection/Required.php b/vendor/symfony/validator/Constraints/Collection/Required.php deleted file mode 100644 index 4b062bb5..00000000 --- a/vendor/symfony/validator/Constraints/Collection/Required.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints\Collection; - -@trigger_error('The '.__NAMESPACE__.'\Required class is deprecated since version 2.3 and will be removed in 3.0. Use the Symfony\Component\Validator\Constraints\Required class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Validator\Constraints\Required as BaseRequired; - -/** - * @Annotation - * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) - * - * @author Bernhard Schussek - * - * @deprecated since version 2.3, to be removed in 3.0. - * Use {@link \Symfony\Component\Validator\Constraints\Required} instead. - */ -class Required extends BaseRequired -{ -} diff --git a/vendor/symfony/validator/Constraints/CollectionValidator.php b/vendor/symfony/validator/Constraints/CollectionValidator.php index 737e8809..f4a6d19e 100644 --- a/vendor/symfony/validator/Constraints/CollectionValidator.php +++ b/vendor/symfony/validator/Constraints/CollectionValidator.php @@ -13,7 +13,6 @@ use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** @@ -56,53 +55,30 @@ public function validate($value, Constraint $constraint) if ($existsInArray || $existsInArrayAccess) { if (count($fieldConstraint->constraints) > 0) { - if ($context instanceof ExecutionContextInterface) { - $context->getValidator() - ->inContext($context) - ->atPath('['.$field.']') - ->validate($value[$field], $fieldConstraint->constraints); - } else { - // 2.4 API - $context->validateValue($value[$field], $fieldConstraint->constraints, '['.$field.']'); - } - } - } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { - if ($context instanceof ExecutionContextInterface) { - $context->buildViolation($constraint->missingFieldsMessage) - ->atPath('['.$field.']') - ->setParameter('{{ field }}', $this->formatValue($field)) - ->setInvalidValue(null) - ->setCode(Collection::MISSING_FIELD_ERROR) - ->addViolation(); - } else { - $this->buildViolationInContext($context, $constraint->missingFieldsMessage) + $context->getValidator() + ->inContext($context) ->atPath('['.$field.']') - ->setParameter('{{ field }}', $this->formatValue($field)) - ->setInvalidValue(null) - ->setCode(Collection::MISSING_FIELD_ERROR) - ->addViolation(); + ->validate($value[$field], $fieldConstraint->constraints); } + } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { + $context->buildViolation($constraint->missingFieldsMessage) + ->atPath('['.$field.']') + ->setParameter('{{ field }}', $this->formatValue($field)) + ->setInvalidValue(null) + ->setCode(Collection::MISSING_FIELD_ERROR) + ->addViolation(); } } if (!$constraint->allowExtraFields) { foreach ($value as $field => $fieldValue) { if (!isset($constraint->fields[$field])) { - if ($context instanceof ExecutionContextInterface) { - $context->buildViolation($constraint->extraFieldsMessage) - ->atPath('['.$field.']') - ->setParameter('{{ field }}', $this->formatValue($field)) - ->setInvalidValue($fieldValue) - ->setCode(Collection::NO_SUCH_FIELD_ERROR) - ->addViolation(); - } else { - $this->buildViolationInContext($context, $constraint->extraFieldsMessage) - ->atPath('['.$field.']') - ->setParameter('{{ field }}', $this->formatValue($field)) - ->setInvalidValue($fieldValue) - ->setCode(Collection::NO_SUCH_FIELD_ERROR) - ->addViolation(); - } + $context->buildViolation($constraint->extraFieldsMessage) + ->atPath('['.$field.']') + ->setParameter('{{ field }}', $this->formatValue($field)) + ->setInvalidValue($fieldValue) + ->setCode(Collection::NO_SUCH_FIELD_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/Composite.php b/vendor/symfony/validator/Constraints/Composite.php index ab8466bc..d1391bb0 100644 --- a/vendor/symfony/validator/Constraints/Composite.php +++ b/vendor/symfony/validator/Constraints/Composite.php @@ -67,6 +67,10 @@ public function __construct($options = null) foreach ($nestedConstraints as $constraint) { if (!$constraint instanceof Constraint) { + if (is_object($constraint)) { + $constraint = get_class($constraint); + } + throw new ConstraintDefinitionException(sprintf('The value %s is not an instance of Constraint in constraint %s', $constraint, get_class($this))); } diff --git a/vendor/symfony/validator/Constraints/CountValidator.php b/vendor/symfony/validator/Constraints/CountValidator.php index cbe90e09..69c82572 100644 --- a/vendor/symfony/validator/Constraints/CountValidator.php +++ b/vendor/symfony/validator/Constraints/CountValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -37,45 +36,25 @@ public function validate($value, Constraint $constraint) $count = count($value); if (null !== $constraint->max && $count > $constraint->max) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage) - ->setParameter('{{ count }}', $count) - ->setParameter('{{ limit }}', $constraint->max) - ->setInvalidValue($value) - ->setPlural((int) $constraint->max) - ->setCode(Count::TOO_MANY_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage) - ->setParameter('{{ count }}', $count) - ->setParameter('{{ limit }}', $constraint->max) - ->setInvalidValue($value) - ->setPlural((int) $constraint->max) - ->setCode(Count::TOO_MANY_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage) + ->setParameter('{{ count }}', $count) + ->setParameter('{{ limit }}', $constraint->max) + ->setInvalidValue($value) + ->setPlural((int) $constraint->max) + ->setCode(Count::TOO_MANY_ERROR) + ->addViolation(); return; } if (null !== $constraint->min && $count < $constraint->min) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage) - ->setParameter('{{ count }}', $count) - ->setParameter('{{ limit }}', $constraint->min) - ->setInvalidValue($value) - ->setPlural((int) $constraint->min) - ->setCode(Count::TOO_FEW_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage) - ->setParameter('{{ count }}', $count) - ->setParameter('{{ limit }}', $constraint->min) - ->setInvalidValue($value) - ->setPlural((int) $constraint->min) - ->setCode(Count::TOO_FEW_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage) + ->setParameter('{{ count }}', $count) + ->setParameter('{{ limit }}', $constraint->min) + ->setInvalidValue($value) + ->setPlural((int) $constraint->min) + ->setCode(Count::TOO_FEW_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/CountryValidator.php b/vendor/symfony/validator/Constraints/CountryValidator.php index 138d775d..3cea3b73 100644 --- a/vendor/symfony/validator/Constraints/CountryValidator.php +++ b/vendor/symfony/validator/Constraints/CountryValidator.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\Intl\Intl; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -45,17 +44,10 @@ public function validate($value, Constraint $constraint) $countries = Intl::getRegionBundle()->getCountryNames(); if (!isset($countries[$value])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Country::NO_SUCH_COUNTRY_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Country::NO_SUCH_COUNTRY_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Country::NO_SUCH_COUNTRY_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/CurrencyValidator.php b/vendor/symfony/validator/Constraints/CurrencyValidator.php index 043bafad..a110bec6 100644 --- a/vendor/symfony/validator/Constraints/CurrencyValidator.php +++ b/vendor/symfony/validator/Constraints/CurrencyValidator.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\Intl\Intl; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -46,17 +45,10 @@ public function validate($value, Constraint $constraint) $currencies = Intl::getCurrencyBundle()->getCurrencyNames(); if (!isset($currencies[$value])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Currency::NO_SUCH_CURRENCY_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Currency::NO_SUCH_CURRENCY_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Currency::NO_SUCH_CURRENCY_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/DateTime.php b/vendor/symfony/validator/Constraints/DateTime.php index 35e29345..c65f185a 100644 --- a/vendor/symfony/validator/Constraints/DateTime.php +++ b/vendor/symfony/validator/Constraints/DateTime.php @@ -31,5 +31,6 @@ class DateTime extends Constraint self::INVALID_TIME_ERROR => 'INVALID_TIME_ERROR', ); + public $format = 'Y-m-d H:i:s'; public $message = 'This value is not a valid datetime.'; } diff --git a/vendor/symfony/validator/Constraints/DateTimeValidator.php b/vendor/symfony/validator/Constraints/DateTimeValidator.php index 29864b49..af956ee0 100644 --- a/vendor/symfony/validator/Constraints/DateTimeValidator.php +++ b/vendor/symfony/validator/Constraints/DateTimeValidator.php @@ -11,15 +11,18 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** * @author Bernhard Schussek + * @author Diego Saint Esteben */ class DateTimeValidator extends DateValidator { + /** + * @deprecated since version 3.1, to be removed in 4.0. + */ const PATTERN = '/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/'; /** @@ -31,7 +34,7 @@ public function validate($value, Constraint $constraint) throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\DateTime'); } - if (null === $value || '' === $value || $value instanceof \DateTime) { + if (null === $value || '' === $value || $value instanceof \DateTimeInterface) { return; } @@ -41,46 +44,34 @@ public function validate($value, Constraint $constraint) $value = (string) $value; - if (!preg_match(static::PATTERN, $value, $matches)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(DateTime::INVALID_FORMAT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(DateTime::INVALID_FORMAT_ERROR) - ->addViolation(); - } + \DateTime::createFromFormat($constraint->format, $value); + + $errors = \DateTime::getLastErrors(); + + if (0 < $errors['error_count']) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(DateTime::INVALID_FORMAT_ERROR) + ->addViolation(); return; } - if (!DateValidator::checkDate($matches[1], $matches[2], $matches[3])) { - if ($this->context instanceof ExecutionContextInterface) { + foreach ($errors['warnings'] as $warning) { + if ('The parsed date was invalid' === $warning) { $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) ->setCode(DateTime::INVALID_DATE_ERROR) ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(DateTime::INVALID_DATE_ERROR) - ->addViolation(); - } - } - - if (!TimeValidator::checkTime($matches[4], $matches[5], $matches[6])) { - if ($this->context instanceof ExecutionContextInterface) { + } elseif ('The parsed time was invalid' === $warning) { $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) ->setCode(DateTime::INVALID_TIME_ERROR) ->addViolation(); } else { - $this->buildViolation($constraint->message) + $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(DateTime::INVALID_TIME_ERROR) + ->setCode(DateTime::INVALID_FORMAT_ERROR) ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/DateValidator.php b/vendor/symfony/validator/Constraints/DateValidator.php index e14791c1..ed836de9 100644 --- a/vendor/symfony/validator/Constraints/DateValidator.php +++ b/vendor/symfony/validator/Constraints/DateValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -48,7 +47,7 @@ public function validate($value, Constraint $constraint) throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Date'); } - if (null === $value || '' === $value || $value instanceof \DateTime) { + if (null === $value || '' === $value || $value instanceof \DateTimeInterface) { return; } @@ -59,33 +58,19 @@ public function validate($value, Constraint $constraint) $value = (string) $value; if (!preg_match(static::PATTERN, $value, $matches)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Date::INVALID_FORMAT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Date::INVALID_FORMAT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Date::INVALID_FORMAT_ERROR) + ->addViolation(); return; } if (!self::checkDate($matches[1], $matches[2], $matches[3])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Date::INVALID_DATE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Date::INVALID_DATE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Date::INVALID_DATE_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/EmailValidator.php b/vendor/symfony/validator/Constraints/EmailValidator.php index 6ae25e01..25df180d 100644 --- a/vendor/symfony/validator/Constraints/EmailValidator.php +++ b/vendor/symfony/validator/Constraints/EmailValidator.php @@ -11,7 +11,8 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Egulias\EmailValidator\Validation\EmailValidation; +use Egulias\EmailValidator\Validation\NoRFCWarningsValidation; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\RuntimeException; @@ -56,76 +57,55 @@ public function validate($value, Constraint $constraint) } if ($constraint->strict) { - if (!class_exists('\Egulias\EmailValidator\EmailValidator') || interface_exists('\Egulias\EmailValidator\Validation\EmailValidation')) { - throw new RuntimeException('Strict email validation requires egulias/email-validator:~1.2'); + if (!class_exists('\Egulias\EmailValidator\EmailValidator')) { + throw new RuntimeException('Strict email validation requires egulias/email-validator ~1.2|~2.0'); } $strictValidator = new \Egulias\EmailValidator\EmailValidator(); - if (!$strictValidator->isValid($value, false, true)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Email::INVALID_FORMAT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Email::INVALID_FORMAT_ERROR) - ->addViolation(); - } - - return; - } - } elseif (!preg_match('/^.+\@\S+\.\S+$/', $value)) { - if ($this->context instanceof ExecutionContextInterface) { + if (interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, new NoRFCWarningsValidation())) { $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) ->setCode(Email::INVALID_FORMAT_ERROR) ->addViolation(); - } else { - $this->buildViolation($constraint->message) + + return; + } elseif (!interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, false, true)) { + $this->context->buildViolation($constraint->message) ->setParameter('{{ value }}', $this->formatValue($value)) ->setCode(Email::INVALID_FORMAT_ERROR) ->addViolation(); + + return; } + } elseif (!preg_match('/^.+\@\S+\.\S+$/', $value)) { + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Email::INVALID_FORMAT_ERROR) + ->addViolation(); return; } - $host = substr($value, strrpos($value, '@') + 1); + $host = (string) substr($value, strrpos($value, '@') + 1); // Check for host DNS resource records if ($constraint->checkMX) { if (!$this->checkMX($host)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Email::MX_CHECK_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Email::MX_CHECK_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Email::MX_CHECK_FAILED_ERROR) + ->addViolation(); } return; } if ($constraint->checkHost && !$this->checkHost($host)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Email::HOST_CHECK_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Email::HOST_CHECK_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Email::HOST_CHECK_FAILED_ERROR) + ->addViolation(); } } @@ -138,7 +118,7 @@ public function validate($value, Constraint $constraint) */ private function checkMX($host) { - return checkdnsrr($host, 'MX'); + return '' !== $host && checkdnsrr($host, 'MX'); } /** @@ -150,6 +130,6 @@ private function checkMX($host) */ private function checkHost($host) { - return $this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA')); + return '' !== $host && ($this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA'))); } } diff --git a/vendor/symfony/validator/Constraints/ExpressionValidator.php b/vendor/symfony/validator/Constraints/ExpressionValidator.php index 8cc289bb..e2f3139a 100644 --- a/vendor/symfony/validator/Constraints/ExpressionValidator.php +++ b/vendor/symfony/validator/Constraints/ExpressionValidator.php @@ -12,12 +12,8 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; -use Symfony\Component\PropertyAccess\PropertyAccess; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; -use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\RuntimeException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -27,19 +23,13 @@ */ class ExpressionValidator extends ConstraintValidator { - /** - * @var PropertyAccessorInterface - */ - private $propertyAccessor; - /** * @var ExpressionLanguage */ private $expressionLanguage; - public function __construct(PropertyAccessorInterface $propertyAccessor = null, ExpressionLanguage $expressionLanguage = null) + public function __construct($propertyAccessor = null, ExpressionLanguage $expressionLanguage = null) { - $this->propertyAccessor = $propertyAccessor; $this->expressionLanguage = $expressionLanguage; } @@ -53,41 +43,14 @@ public function validate($value, Constraint $constraint) } $variables = array(); - - // Symfony 2.5+ - if ($this->context instanceof ExecutionContextInterface) { - $variables['value'] = $value; - $variables['this'] = $this->context->getObject(); - } elseif (null === $this->context->getPropertyName()) { - $variables['value'] = $value; - $variables['this'] = $value; - } else { - $root = $this->context->getRoot(); - $variables['value'] = $value; - - if (is_object($root)) { - // Extract the object that the property belongs to from the object - // graph - $path = new PropertyPath($this->context->getPropertyPath()); - $parentPath = $path->getParent(); - $variables['this'] = $parentPath ? $this->getPropertyAccessor()->getValue($root, $parentPath) : $root; - } else { - $variables['this'] = null; - } - } + $variables['value'] = $value; + $variables['this'] = $this->context->getObject(); if (!$this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Expression::EXPRESSION_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Expression::EXPRESSION_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Expression::EXPRESSION_FAILED_ERROR) + ->addViolation(); } } @@ -102,16 +65,4 @@ private function getExpressionLanguage() return $this->expressionLanguage; } - - private function getPropertyAccessor() - { - if (null === $this->propertyAccessor) { - if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) { - throw new RuntimeException('Unable to use expressions as the Symfony PropertyAccess component is not installed.'); - } - $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); - } - - return $this->propertyAccessor; - } } diff --git a/vendor/symfony/validator/Constraints/False.php b/vendor/symfony/validator/Constraints/False.php deleted file mode 100644 index 1e103ade..00000000 --- a/vendor/symfony/validator/Constraints/False.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints; - -@trigger_error('The '.__NAMESPACE__.'\False class is deprecated since version 2.7 and will be removed in 3.0. Use the IsFalse class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * @Annotation - * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) - * - * @author Bernhard Schussek - * - * @deprecated since version 2.7, to be removed in 3.0. Use IsFalse instead. - */ -class False extends IsFalse -{ -} diff --git a/vendor/symfony/validator/Constraints/FalseValidator.php b/vendor/symfony/validator/Constraints/FalseValidator.php deleted file mode 100644 index 9614c303..00000000 --- a/vendor/symfony/validator/Constraints/FalseValidator.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints; - -@trigger_error('The '.__NAMESPACE__.'\FalseValidator class is deprecated since version 2.7 and will be removed in 3.0. Use the IsFalseValidator class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * @author Bernhard Schussek - * - * @deprecated since version 2.7, to be removed in 3.0. Use IsFalseValidator instead. - */ -class FalseValidator extends IsFalseValidator -{ -} diff --git a/vendor/symfony/validator/Constraints/FileValidator.php b/vendor/symfony/validator/Constraints/FileValidator.php index 34eb0d25..e752f2a1 100644 --- a/vendor/symfony/validator/Constraints/FileValidator.php +++ b/vendor/symfony/validator/Constraints/FileValidator.php @@ -13,7 +13,6 @@ use Symfony\Component\HttpFoundation\File\File as FileObject; use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -62,103 +61,53 @@ public function validate($value, Constraint $constraint) } list($sizeAsString, $limitAsString, $suffix) = $this->factorizeSizes(0, $limitInBytes, $binaryFormat); - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadIniSizeErrorMessage) - ->setParameter('{{ limit }}', $limitAsString) - ->setParameter('{{ suffix }}', $suffix) - ->setCode(UPLOAD_ERR_INI_SIZE) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadIniSizeErrorMessage) - ->setParameter('{{ limit }}', $limitAsString) - ->setParameter('{{ suffix }}', $suffix) - ->setCode(UPLOAD_ERR_INI_SIZE) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadIniSizeErrorMessage) + ->setParameter('{{ limit }}', $limitAsString) + ->setParameter('{{ suffix }}', $suffix) + ->setCode(UPLOAD_ERR_INI_SIZE) + ->addViolation(); return; case UPLOAD_ERR_FORM_SIZE: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadFormSizeErrorMessage) - ->setCode(UPLOAD_ERR_FORM_SIZE) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadFormSizeErrorMessage) - ->setCode(UPLOAD_ERR_FORM_SIZE) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadFormSizeErrorMessage) + ->setCode(UPLOAD_ERR_FORM_SIZE) + ->addViolation(); return; case UPLOAD_ERR_PARTIAL: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadPartialErrorMessage) - ->setCode(UPLOAD_ERR_PARTIAL) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadPartialErrorMessage) - ->setCode(UPLOAD_ERR_PARTIAL) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadPartialErrorMessage) + ->setCode(UPLOAD_ERR_PARTIAL) + ->addViolation(); return; case UPLOAD_ERR_NO_FILE: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadNoFileErrorMessage) - ->setCode(UPLOAD_ERR_NO_FILE) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadNoFileErrorMessage) - ->setCode(UPLOAD_ERR_NO_FILE) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadNoFileErrorMessage) + ->setCode(UPLOAD_ERR_NO_FILE) + ->addViolation(); return; case UPLOAD_ERR_NO_TMP_DIR: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadNoTmpDirErrorMessage) - ->setCode(UPLOAD_ERR_NO_TMP_DIR) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadNoTmpDirErrorMessage) - ->setCode(UPLOAD_ERR_NO_TMP_DIR) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadNoTmpDirErrorMessage) + ->setCode(UPLOAD_ERR_NO_TMP_DIR) + ->addViolation(); return; case UPLOAD_ERR_CANT_WRITE: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadCantWriteErrorMessage) - ->setCode(UPLOAD_ERR_CANT_WRITE) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadCantWriteErrorMessage) - ->setCode(UPLOAD_ERR_CANT_WRITE) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadCantWriteErrorMessage) + ->setCode(UPLOAD_ERR_CANT_WRITE) + ->addViolation(); return; case UPLOAD_ERR_EXTENSION: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadExtensionErrorMessage) - ->setCode(UPLOAD_ERR_EXTENSION) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadExtensionErrorMessage) - ->setCode(UPLOAD_ERR_EXTENSION) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadExtensionErrorMessage) + ->setCode(UPLOAD_ERR_EXTENSION) + ->addViolation(); return; default: - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->uploadErrorMessage) - ->setCode($value->getError()) - ->addViolation(); - } else { - $this->buildViolation($constraint->uploadErrorMessage) - ->setCode($value->getError()) - ->addViolation(); - } + $this->context->buildViolation($constraint->uploadErrorMessage) + ->setCode($value->getError()) + ->addViolation(); return; } @@ -171,33 +120,19 @@ public function validate($value, Constraint $constraint) $path = $value instanceof FileObject ? $value->getPathname() : (string) $value; if (!is_file($path)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->notFoundMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setCode(File::NOT_FOUND_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->notFoundMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setCode(File::NOT_FOUND_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->notFoundMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setCode(File::NOT_FOUND_ERROR) + ->addViolation(); return; } if (!is_readable($path)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->notReadableMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setCode(File::NOT_READABLE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->notReadableMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setCode(File::NOT_READABLE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->notReadableMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setCode(File::NOT_READABLE_ERROR) + ->addViolation(); return; } @@ -205,17 +140,10 @@ public function validate($value, Constraint $constraint) $sizeInBytes = filesize($path); if (0 === $sizeInBytes) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->disallowEmptyMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setCode(File::EMPTY_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->disallowEmptyMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setCode(File::EMPTY_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->disallowEmptyMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setCode(File::EMPTY_ERROR) + ->addViolation(); return; } @@ -225,23 +153,13 @@ public function validate($value, Constraint $constraint) if ($sizeInBytes > $limitInBytes) { list($sizeAsString, $limitAsString, $suffix) = $this->factorizeSizes($sizeInBytes, $limitInBytes, $constraint->binaryFormat); - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->maxSizeMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setParameter('{{ size }}', $sizeAsString) - ->setParameter('{{ limit }}', $limitAsString) - ->setParameter('{{ suffix }}', $suffix) - ->setCode(File::TOO_LARGE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->maxSizeMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setParameter('{{ size }}', $sizeAsString) - ->setParameter('{{ limit }}', $limitAsString) - ->setParameter('{{ suffix }}', $suffix) - ->setCode(File::TOO_LARGE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->maxSizeMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setParameter('{{ size }}', $sizeAsString) + ->setParameter('{{ limit }}', $limitAsString) + ->setParameter('{{ suffix }}', $suffix) + ->setCode(File::TOO_LARGE_ERROR) + ->addViolation(); return; } @@ -267,21 +185,12 @@ public function validate($value, Constraint $constraint) } } - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->mimeTypesMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setParameter('{{ type }}', $this->formatValue($mime)) - ->setParameter('{{ types }}', $this->formatValues($mimeTypes)) - ->setCode(File::INVALID_MIME_TYPE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->mimeTypesMessage) - ->setParameter('{{ file }}', $this->formatValue($path)) - ->setParameter('{{ type }}', $this->formatValue($mime)) - ->setParameter('{{ types }}', $this->formatValues($mimeTypes)) - ->setCode(File::INVALID_MIME_TYPE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->mimeTypesMessage) + ->setParameter('{{ file }}', $this->formatValue($path)) + ->setParameter('{{ type }}', $this->formatValue($mime)) + ->setParameter('{{ types }}', $this->formatValues($mimeTypes)) + ->setCode(File::INVALID_MIME_TYPE_ERROR) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/GroupSequence.php b/vendor/symfony/validator/Constraints/GroupSequence.php index 319eff0e..1f6f5128 100644 --- a/vendor/symfony/validator/Constraints/GroupSequence.php +++ b/vendor/symfony/validator/Constraints/GroupSequence.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Exception\OutOfBoundsException; - /** * A sequence of validation groups. * @@ -53,15 +51,13 @@ * @Target({"CLASS", "ANNOTATION"}) * * @author Bernhard Schussek - * - * Implementing \ArrayAccess, \IteratorAggregate and \Countable is @deprecated since 2.5 and will be removed in 3.0. */ -class GroupSequence implements \ArrayAccess, \IteratorAggregate, \Countable +class GroupSequence { /** * The groups in the sequence. * - * @var string[]|GroupSequence[] + * @var string[]|array[]|GroupSequence[] */ public $groups; @@ -91,121 +87,4 @@ public function __construct(array $groups) // Support for Doctrine annotations $this->groups = isset($groups['value']) ? $groups['value'] : $groups; } - - /** - * Returns an iterator for this group. - * - * Implemented for backwards compatibility with Symfony < 2.5. - * - * @return \Traversable The iterator - * - * @see \IteratorAggregate::getIterator() - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function getIterator() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - return new \ArrayIterator($this->groups); - } - - /** - * Returns whether the given offset exists in the sequence. - * - * Implemented for backwards compatibility with Symfony < 2.5. - * - * @param int $offset The offset - * - * @return bool Whether the offset exists - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function offsetExists($offset) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - return isset($this->groups[$offset]); - } - - /** - * Returns the group at the given offset. - * - * Implemented for backwards compatibility with Symfony < 2.5. - * - * @param int $offset The offset - * - * @return string The group a the given offset - * - * @throws OutOfBoundsException If the object does not exist - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function offsetGet($offset) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - if (!isset($this->groups[$offset])) { - throw new OutOfBoundsException(sprintf( - 'The offset "%s" does not exist.', - $offset - )); - } - - return $this->groups[$offset]; - } - - /** - * Sets the group at the given offset. - * - * Implemented for backwards compatibility with Symfony < 2.5. - * - * @param int $offset The offset - * @param string $value The group name - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function offsetSet($offset, $value) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - if (null !== $offset) { - $this->groups[$offset] = $value; - - return; - } - - $this->groups[] = $value; - } - - /** - * Removes the group at the given offset. - * - * Implemented for backwards compatibility with Symfony < 2.5. - * - * @param int $offset The offset - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function offsetUnset($offset) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - unset($this->groups[$offset]); - } - - /** - * Returns the number of groups in the sequence. - * - * Implemented for backwards compatibility with Symfony < 2.5. - * - * @return int The number of groups - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function count() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - return count($this->groups); - } } diff --git a/vendor/symfony/validator/Constraints/Iban.php b/vendor/symfony/validator/Constraints/Iban.php index 9c4d3838..bcb30655 100644 --- a/vendor/symfony/validator/Constraints/Iban.php +++ b/vendor/symfony/validator/Constraints/Iban.php @@ -23,21 +23,15 @@ */ class Iban extends Constraint { - /** @deprecated, to be removed in 3.0. */ - const TOO_SHORT_ERROR = '88e5e319-0aeb-4979-a27e-3d9ce0c16166'; const INVALID_COUNTRY_CODE_ERROR = 'de78ee2c-bd50-44e2-aec8-3d8228aeadb9'; const INVALID_CHARACTERS_ERROR = '8d3d85e4-784f-4719-a5bc-d9e40d45a3a5'; - /** @deprecated, to be removed in 3.0. */ - const INVALID_CASE_ERROR = 'f4bf62fe-03ec-42af-a53b-68e21b1e7274'; const CHECKSUM_FAILED_ERROR = 'b9401321-f9bf-4dcb-83c1-f31094440795'; const INVALID_FORMAT_ERROR = 'c8d318f1-2ecc-41ba-b983-df70d225cf5a'; const NOT_SUPPORTED_COUNTRY_CODE_ERROR = 'e2c259f3-4b46-48e6-b72e-891658158ec8'; protected static $errorNames = array( - self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR', self::INVALID_COUNTRY_CODE_ERROR => 'INVALID_COUNTRY_CODE_ERROR', self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', - self::INVALID_CASE_ERROR => 'INVALID_CASE_ERROR', self::CHECKSUM_FAILED_ERROR => 'CHECKSUM_FAILED_ERROR', self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR', self::NOT_SUPPORTED_COUNTRY_CODE_ERROR => 'NOT_SUPPORTED_COUNTRY_CODE_ERROR', diff --git a/vendor/symfony/validator/Constraints/IbanValidator.php b/vendor/symfony/validator/Constraints/IbanValidator.php index ae4eb112..541c7161 100644 --- a/vendor/symfony/validator/Constraints/IbanValidator.php +++ b/vendor/symfony/validator/Constraints/IbanValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -161,17 +160,10 @@ public function validate($value, Constraint $constraint) // The IBAN must contain only digits and characters... if (!ctype_alnum($canonicalized)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } @@ -180,34 +172,20 @@ public function validate($value, Constraint $constraint) $countryCode = substr($canonicalized, 0, 2); if (!ctype_alpha($countryCode)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::INVALID_COUNTRY_CODE_ERROR) + ->addViolation(); return; } // ...have a format available if (!array_key_exists($countryCode, self::$formats)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::NOT_SUPPORTED_COUNTRY_CODE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::NOT_SUPPORTED_COUNTRY_CODE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::NOT_SUPPORTED_COUNTRY_CODE_ERROR) + ->addViolation(); return; } @@ -215,17 +193,10 @@ public function validate($value, Constraint $constraint) // ...and have a valid format if (!preg_match('/^'.self::$formats[$countryCode].'$/', $canonicalized) ) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::INVALID_FORMAT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::INVALID_FORMAT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::INVALID_FORMAT_ERROR) + ->addViolation(); return; } @@ -246,17 +217,10 @@ public function validate($value, Constraint $constraint) // We cannot use PHP's modulo operator, so we calculate the // modulo step-wisely instead if (1 !== self::bigModulo97($checkSum)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::CHECKSUM_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Iban::CHECKSUM_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Iban::CHECKSUM_FAILED_ERROR) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/Image.php b/vendor/symfony/validator/Constraints/Image.php index 28803c43..a3957f23 100644 --- a/vendor/symfony/validator/Constraints/Image.php +++ b/vendor/symfony/validator/Constraints/Image.php @@ -30,6 +30,7 @@ class Image extends File const SQUARE_NOT_ALLOWED_ERROR = '5d41425b-facb-47f7-a55a-de9fbe45cb46'; const LANDSCAPE_NOT_ALLOWED_ERROR = '6f895685-7cf2-4d65-b3da-9029c5581d88'; const PORTRAIT_NOT_ALLOWED_ERROR = '65608156-77da-4c79-a88c-02ef6d18c782'; + const CORRUPTED_IMAGE_ERROR = '5d4163f3-648f-4e39-87fd-cc5ea7aad2d1'; // Include the mapping from the base class @@ -49,6 +50,7 @@ class Image extends File self::SQUARE_NOT_ALLOWED_ERROR => 'SQUARE_NOT_ALLOWED_ERROR', self::LANDSCAPE_NOT_ALLOWED_ERROR => 'LANDSCAPE_NOT_ALLOWED_ERROR', self::PORTRAIT_NOT_ALLOWED_ERROR => 'PORTRAIT_NOT_ALLOWED_ERROR', + self::CORRUPTED_IMAGE_ERROR => 'CORRUPTED_IMAGE_ERROR', ); public $mimeTypes = 'image/*'; @@ -61,6 +63,7 @@ class Image extends File public $allowSquare = true; public $allowLandscape = true; public $allowPortrait = true; + public $detectCorrupted = false; // The constant for a wrong MIME type is taken from the parent class. public $mimeTypesMessage = 'This file is not a valid image.'; @@ -74,4 +77,5 @@ class Image extends File public $allowSquareMessage = 'The image is square ({{ width }}x{{ height }}px). Square images are not allowed.'; public $allowLandscapeMessage = 'The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.'; public $allowPortraitMessage = 'The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.'; + public $corruptedMessage = 'The image file is corrupted.'; } diff --git a/vendor/symfony/validator/Constraints/ImageValidator.php b/vendor/symfony/validator/Constraints/ImageValidator.php index a5165e25..0ed0d417 100644 --- a/vendor/symfony/validator/Constraints/ImageValidator.php +++ b/vendor/symfony/validator/Constraints/ImageValidator.php @@ -11,9 +11,9 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Validator\Exception\RuntimeException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** @@ -47,22 +47,17 @@ public function validate($value, Constraint $constraint) if (null === $constraint->minWidth && null === $constraint->maxWidth && null === $constraint->minHeight && null === $constraint->maxHeight && null === $constraint->minRatio && null === $constraint->maxRatio - && $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait) { + && $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait + && !$constraint->detectCorrupted) { return; } $size = @getimagesize($value); if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->sizeNotDetectedMessage) - ->setCode(Image::SIZE_NOT_DETECTED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->sizeNotDetectedMessage) - ->setCode(Image::SIZE_NOT_DETECTED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->sizeNotDetectedMessage) + ->setCode(Image::SIZE_NOT_DETECTED_ERROR) + ->addViolation(); return; } @@ -76,19 +71,11 @@ public function validate($value, Constraint $constraint) } if ($width < $constraint->minWidth) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->minWidthMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ min_width }}', $constraint->minWidth) - ->setCode(Image::TOO_NARROW_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->minWidthMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ min_width }}', $constraint->minWidth) - ->setCode(Image::TOO_NARROW_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->minWidthMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ min_width }}', $constraint->minWidth) + ->setCode(Image::TOO_NARROW_ERROR) + ->addViolation(); return; } @@ -100,19 +87,11 @@ public function validate($value, Constraint $constraint) } if ($width > $constraint->maxWidth) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->maxWidthMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ max_width }}', $constraint->maxWidth) - ->setCode(Image::TOO_WIDE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->maxWidthMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ max_width }}', $constraint->maxWidth) - ->setCode(Image::TOO_WIDE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->maxWidthMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ max_width }}', $constraint->maxWidth) + ->setCode(Image::TOO_WIDE_ERROR) + ->addViolation(); return; } @@ -124,19 +103,11 @@ public function validate($value, Constraint $constraint) } if ($height < $constraint->minHeight) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->minHeightMessage) - ->setParameter('{{ height }}', $height) - ->setParameter('{{ min_height }}', $constraint->minHeight) - ->setCode(Image::TOO_LOW_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->minHeightMessage) - ->setParameter('{{ height }}', $height) - ->setParameter('{{ min_height }}', $constraint->minHeight) - ->setCode(Image::TOO_LOW_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->minHeightMessage) + ->setParameter('{{ height }}', $height) + ->setParameter('{{ min_height }}', $constraint->minHeight) + ->setCode(Image::TOO_LOW_ERROR) + ->addViolation(); return; } @@ -148,19 +119,11 @@ public function validate($value, Constraint $constraint) } if ($height > $constraint->maxHeight) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->maxHeightMessage) - ->setParameter('{{ height }}', $height) - ->setParameter('{{ max_height }}', $constraint->maxHeight) - ->setCode(Image::TOO_HIGH_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->maxHeightMessage) - ->setParameter('{{ height }}', $height) - ->setParameter('{{ max_height }}', $constraint->maxHeight) - ->setCode(Image::TOO_HIGH_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->maxHeightMessage) + ->setParameter('{{ height }}', $height) + ->setParameter('{{ max_height }}', $constraint->maxHeight) + ->setCode(Image::TOO_HIGH_ERROR) + ->addViolation(); } } @@ -172,19 +135,11 @@ public function validate($value, Constraint $constraint) } if ($ratio < $constraint->minRatio) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->minRatioMessage) - ->setParameter('{{ ratio }}', $ratio) - ->setParameter('{{ min_ratio }}', $constraint->minRatio) - ->setCode(Image::RATIO_TOO_SMALL_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->minRatioMessage) - ->setParameter('{{ ratio }}', $ratio) - ->setParameter('{{ min_ratio }}', $constraint->minRatio) - ->setCode(Image::RATIO_TOO_SMALL_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->minRatioMessage) + ->setParameter('{{ ratio }}', $ratio) + ->setParameter('{{ min_ratio }}', $constraint->minRatio) + ->setCode(Image::RATIO_TOO_SMALL_ERROR) + ->addViolation(); } } @@ -194,68 +149,54 @@ public function validate($value, Constraint $constraint) } if ($ratio > $constraint->maxRatio) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->maxRatioMessage) - ->setParameter('{{ ratio }}', $ratio) - ->setParameter('{{ max_ratio }}', $constraint->maxRatio) - ->setCode(Image::RATIO_TOO_BIG_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->maxRatioMessage) - ->setParameter('{{ ratio }}', $ratio) - ->setParameter('{{ max_ratio }}', $constraint->maxRatio) - ->setCode(Image::RATIO_TOO_BIG_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->maxRatioMessage) + ->setParameter('{{ ratio }}', $ratio) + ->setParameter('{{ max_ratio }}', $constraint->maxRatio) + ->setCode(Image::RATIO_TOO_BIG_ERROR) + ->addViolation(); } } if (!$constraint->allowSquare && $width == $height) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->allowSquareMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ height }}', $height) - ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->allowSquareMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ height }}', $height) - ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->allowSquareMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ height }}', $height) + ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR) + ->addViolation(); } if (!$constraint->allowLandscape && $width > $height) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->allowLandscapeMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ height }}', $height) - ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->allowLandscapeMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ height }}', $height) - ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->allowLandscapeMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ height }}', $height) + ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR) + ->addViolation(); } if (!$constraint->allowPortrait && $width < $height) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->allowPortraitMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ height }}', $height) - ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->allowPortraitMessage) - ->setParameter('{{ width }}', $width) - ->setParameter('{{ height }}', $height) - ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR) + $this->context->buildViolation($constraint->allowPortraitMessage) + ->setParameter('{{ width }}', $width) + ->setParameter('{{ height }}', $height) + ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR) + ->addViolation(); + } + + if ($constraint->detectCorrupted) { + if (!function_exists('imagecreatefromstring')) { + throw new RuntimeException('Corrupted images detection requires installed and enabled GD extension'); + } + + $resource = @imagecreatefromstring(file_get_contents($value)); + + if (false === $resource) { + $this->context->buildViolation($constraint->corruptedMessage) + ->setCode(Image::CORRUPTED_IMAGE_ERROR) ->addViolation(); + + return; } + + imagedestroy($resource); } } } diff --git a/vendor/symfony/validator/Constraints/IpValidator.php b/vendor/symfony/validator/Constraints/IpValidator.php index eb8642b5..7f806bf7 100644 --- a/vendor/symfony/validator/Constraints/IpValidator.php +++ b/vendor/symfony/validator/Constraints/IpValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -94,17 +93,10 @@ public function validate($value, Constraint $constraint) } if (!filter_var($value, FILTER_VALIDATE_IP, $flag)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Ip::INVALID_IP_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Ip::INVALID_IP_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Ip::INVALID_IP_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/IsFalseValidator.php b/vendor/symfony/validator/Constraints/IsFalseValidator.php index 522a1a25..95245fb9 100644 --- a/vendor/symfony/validator/Constraints/IsFalseValidator.php +++ b/vendor/symfony/validator/Constraints/IsFalseValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -34,16 +33,9 @@ public function validate($value, Constraint $constraint) return; } - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(IsFalse::NOT_FALSE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(IsFalse::NOT_FALSE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(IsFalse::NOT_FALSE_ERROR) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/IsNullValidator.php b/vendor/symfony/validator/Constraints/IsNullValidator.php index 1b7567fe..01b9d1e4 100644 --- a/vendor/symfony/validator/Constraints/IsNullValidator.php +++ b/vendor/symfony/validator/Constraints/IsNullValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -31,17 +30,10 @@ public function validate($value, Constraint $constraint) } if (null !== $value) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(IsNull::NOT_NULL_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(IsNull::NOT_NULL_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(IsNull::NOT_NULL_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/IsTrueValidator.php b/vendor/symfony/validator/Constraints/IsTrueValidator.php index e1ca56ec..89aa337d 100644 --- a/vendor/symfony/validator/Constraints/IsTrueValidator.php +++ b/vendor/symfony/validator/Constraints/IsTrueValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -35,17 +34,10 @@ public function validate($value, Constraint $constraint) } if (true !== $value && 1 !== $value && '1' !== $value) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(IsTrue::NOT_TRUE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(IsTrue::NOT_TRUE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(IsTrue::NOT_TRUE_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/Isbn.php b/vendor/symfony/validator/Constraints/Isbn.php index f1e83b99..615feb66 100644 --- a/vendor/symfony/validator/Constraints/Isbn.php +++ b/vendor/symfony/validator/Constraints/Isbn.php @@ -43,20 +43,6 @@ class Isbn extends Constraint public $type; public $message; - /** - * @deprecated since version 2.5, to be removed in 3.0. Use option "type" instead. - * - * @var bool - */ - public $isbn10 = false; - - /** - * @deprecated since version 2.5, to be removed in 3.0. Use option "type" instead. - * - * @var bool - */ - public $isbn13 = false; - /** * {@inheritdoc} */ diff --git a/vendor/symfony/validator/Constraints/IsbnValidator.php b/vendor/symfony/validator/Constraints/IsbnValidator.php index 6ca8488a..2e342673 100644 --- a/vendor/symfony/validator/Constraints/IsbnValidator.php +++ b/vendor/symfony/validator/Constraints/IsbnValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -47,30 +46,13 @@ public function validate($value, Constraint $constraint) $value = (string) $value; $canonical = str_replace('-', '', $value); - if (null === $constraint->type) { - if ($constraint->isbn10 && !$constraint->isbn13) { - @trigger_error('The "isbn10" option of the Isbn constraint is deprecated since version 2.5 and will be removed in 3.0. Use the "type" option instead.', E_USER_DEPRECATED); - $constraint->type = 'isbn10'; - } elseif ($constraint->isbn13 && !$constraint->isbn10) { - @trigger_error('The "isbn13" option of the Isbn constraint is deprecated since version 2.5 and will be removed in 3.0. Use the "type" option instead.', E_USER_DEPRECATED); - $constraint->type = 'isbn13'; - } - } - // Explicitly validate against ISBN-10 if ('isbn10' === $constraint->type) { if (true !== ($code = $this->validateIsbn10($canonical))) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($this->getMessage($constraint, $constraint->type)) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode($code) - ->addViolation(); - } else { - $this->buildViolation($this->getMessage($constraint, $constraint->type)) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode($code) - ->addViolation(); - } + $this->context->buildViolation($this->getMessage($constraint, $constraint->type)) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); } return; @@ -79,17 +61,10 @@ public function validate($value, Constraint $constraint) // Explicitly validate against ISBN-13 if ('isbn13' === $constraint->type) { if (true !== ($code = $this->validateIsbn13($canonical))) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($this->getMessage($constraint, $constraint->type)) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode($code) - ->addViolation(); - } else { - $this->buildViolation($this->getMessage($constraint, $constraint->type)) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode($code) - ->addViolation(); - } + $this->context->buildViolation($this->getMessage($constraint, $constraint->type)) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); } return; @@ -112,17 +87,10 @@ public function validate($value, Constraint $constraint) } if (true !== $code) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($this->getMessage($constraint)) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode($code) - ->addViolation(); - } else { - $this->buildViolation($this->getMessage($constraint)) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode($code) - ->addViolation(); - } + $this->context->buildViolation($this->getMessage($constraint)) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode($code) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/IssnValidator.php b/vendor/symfony/validator/Constraints/IssnValidator.php index 1405acfc..ae1bb6fa 100644 --- a/vendor/symfony/validator/Constraints/IssnValidator.php +++ b/vendor/symfony/validator/Constraints/IssnValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -52,17 +51,10 @@ public function validate($value, Constraint $constraint) // remove hyphen $canonical = substr($canonical, 0, 4).substr($canonical, 5); } elseif ($constraint->requireHyphen) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::MISSING_HYPHEN_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::MISSING_HYPHEN_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::MISSING_HYPHEN_ERROR) + ->addViolation(); return; } @@ -70,33 +62,19 @@ public function validate($value, Constraint $constraint) $length = strlen($canonical); if ($length < 8) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::TOO_SHORT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::TOO_SHORT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::TOO_SHORT_ERROR) + ->addViolation(); return; } if ($length > 8) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::TOO_LONG_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::TOO_LONG_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::TOO_LONG_ERROR) + ->addViolation(); return; } @@ -104,17 +82,10 @@ public function validate($value, Constraint $constraint) // 1234567X // ^^^^^^^ digits only if (!ctype_digit(substr($canonical, 0, 7))) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } @@ -122,17 +93,10 @@ public function validate($value, Constraint $constraint) // 1234567X // ^ digit, x or X if (!ctype_digit($canonical[7]) && 'x' !== $canonical[7] && 'X' !== $canonical[7]) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } @@ -140,17 +104,10 @@ public function validate($value, Constraint $constraint) // 1234567X // ^ case-sensitive? if ($constraint->caseSensitive && 'x' === $canonical[7]) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::INVALID_CASE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::INVALID_CASE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::INVALID_CASE_ERROR) + ->addViolation(); return; } @@ -167,17 +124,10 @@ public function validate($value, Constraint $constraint) } if (0 !== $checkSum % 11) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::CHECKSUM_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Issn::CHECKSUM_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Issn::CHECKSUM_FAILED_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/LanguageValidator.php b/vendor/symfony/validator/Constraints/LanguageValidator.php index 19c1ba88..c0bc08fd 100644 --- a/vendor/symfony/validator/Constraints/LanguageValidator.php +++ b/vendor/symfony/validator/Constraints/LanguageValidator.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\Intl\Intl; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -45,17 +44,10 @@ public function validate($value, Constraint $constraint) $languages = Intl::getLanguageBundle()->getLanguageNames(); if (!isset($languages[$value])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Language::NO_SUCH_LANGUAGE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Language::NO_SUCH_LANGUAGE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Language::NO_SUCH_LANGUAGE_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/LengthValidator.php b/vendor/symfony/validator/Constraints/LengthValidator.php index 1518ecf0..490f5a36 100644 --- a/vendor/symfony/validator/Constraints/LengthValidator.php +++ b/vendor/symfony/validator/Constraints/LengthValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -45,65 +44,36 @@ public function validate($value, Constraint $constraint) } if ($invalidCharset) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->charsetMessage) - ->setParameter('{{ value }}', $this->formatValue($stringValue)) - ->setParameter('{{ charset }}', $constraint->charset) - ->setInvalidValue($value) - ->setCode(Length::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->charsetMessage) - ->setParameter('{{ value }}', $this->formatValue($stringValue)) - ->setParameter('{{ charset }}', $constraint->charset) - ->setInvalidValue($value) - ->setCode(Length::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->charsetMessage) + ->setParameter('{{ value }}', $this->formatValue($stringValue)) + ->setParameter('{{ charset }}', $constraint->charset) + ->setInvalidValue($value) + ->setCode(Length::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } if (null !== $constraint->max && $length > $constraint->max) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage) - ->setParameter('{{ value }}', $this->formatValue($stringValue)) - ->setParameter('{{ limit }}', $constraint->max) - ->setInvalidValue($value) - ->setPlural((int) $constraint->max) - ->setCode(Length::TOO_LONG_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage) - ->setParameter('{{ value }}', $this->formatValue($stringValue)) - ->setParameter('{{ limit }}', $constraint->max) - ->setInvalidValue($value) - ->setPlural((int) $constraint->max) - ->setCode(Length::TOO_LONG_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->maxMessage) + ->setParameter('{{ value }}', $this->formatValue($stringValue)) + ->setParameter('{{ limit }}', $constraint->max) + ->setInvalidValue($value) + ->setPlural((int) $constraint->max) + ->setCode(Length::TOO_LONG_ERROR) + ->addViolation(); return; } if (null !== $constraint->min && $length < $constraint->min) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage) - ->setParameter('{{ value }}', $this->formatValue($stringValue)) - ->setParameter('{{ limit }}', $constraint->min) - ->setInvalidValue($value) - ->setPlural((int) $constraint->min) - ->setCode(Length::TOO_SHORT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage) - ->setParameter('{{ value }}', $this->formatValue($stringValue)) - ->setParameter('{{ limit }}', $constraint->min) - ->setInvalidValue($value) - ->setPlural((int) $constraint->min) - ->setCode(Length::TOO_SHORT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->min == $constraint->max ? $constraint->exactMessage : $constraint->minMessage) + ->setParameter('{{ value }}', $this->formatValue($stringValue)) + ->setParameter('{{ limit }}', $constraint->min) + ->setInvalidValue($value) + ->setPlural((int) $constraint->min) + ->setCode(Length::TOO_SHORT_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/LocaleValidator.php b/vendor/symfony/validator/Constraints/LocaleValidator.php index 6e779df2..93eab8cb 100644 --- a/vendor/symfony/validator/Constraints/LocaleValidator.php +++ b/vendor/symfony/validator/Constraints/LocaleValidator.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\Intl\Intl; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -46,17 +45,10 @@ public function validate($value, Constraint $constraint) $aliases = Intl::getLocaleBundle()->getAliases(); if (!isset($locales[$value]) && !in_array($value, $aliases)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Locale::NO_SUCH_LOCALE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Locale::NO_SUCH_LOCALE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Locale::NO_SUCH_LOCALE_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/LuhnValidator.php b/vendor/symfony/validator/Constraints/LuhnValidator.php index e971ab15..85e4d762 100644 --- a/vendor/symfony/validator/Constraints/LuhnValidator.php +++ b/vendor/symfony/validator/Constraints/LuhnValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -57,17 +56,10 @@ public function validate($value, Constraint $constraint) $value = (string) $value; if (!ctype_digit($value)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Luhn::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Luhn::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Luhn::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } @@ -95,17 +87,10 @@ public function validate($value, Constraint $constraint) } if (0 === $checkSum || 0 !== $checkSum % 10) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Luhn::CHECKSUM_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Luhn::CHECKSUM_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Luhn::CHECKSUM_FAILED_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/NotBlankValidator.php b/vendor/symfony/validator/Constraints/NotBlankValidator.php index 7ea5f1f4..1d6c5bc9 100644 --- a/vendor/symfony/validator/Constraints/NotBlankValidator.php +++ b/vendor/symfony/validator/Constraints/NotBlankValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -31,17 +30,10 @@ public function validate($value, Constraint $constraint) } if (false === $value || (empty($value) && '0' != $value)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(NotBlank::IS_BLANK_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(NotBlank::IS_BLANK_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(NotBlank::IS_BLANK_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/NotNullValidator.php b/vendor/symfony/validator/Constraints/NotNullValidator.php index 0402b3d6..d6f62071 100644 --- a/vendor/symfony/validator/Constraints/NotNullValidator.php +++ b/vendor/symfony/validator/Constraints/NotNullValidator.php @@ -13,7 +13,6 @@ use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** @@ -31,17 +30,10 @@ public function validate($value, Constraint $constraint) } if (null === $value) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(NotNull::IS_NULL_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(NotNull::IS_NULL_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(NotNull::IS_NULL_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/Null.php b/vendor/symfony/validator/Constraints/Null.php deleted file mode 100644 index 705d93fc..00000000 --- a/vendor/symfony/validator/Constraints/Null.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints; - -@trigger_error('The '.__NAMESPACE__.'\Null class is deprecated since version 2.7 and will be removed in 3.0. Use the IsNull class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * @Annotation - * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) - * - * @author Bernhard Schussek - * - * @deprecated since version 2.7, to be removed in 3.0. Use IsNull instead. - */ -class Null extends IsNull -{ -} diff --git a/vendor/symfony/validator/Constraints/NullValidator.php b/vendor/symfony/validator/Constraints/NullValidator.php deleted file mode 100644 index bd17eab5..00000000 --- a/vendor/symfony/validator/Constraints/NullValidator.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints; - -@trigger_error('The '.__NAMESPACE__.'\NullValidator class is deprecated since version 2.7 and will be removed in 3.0. Use the IsNullValidator class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * @author Bernhard Schussek - * - * @deprecated since version 2.7, to be removed in 3.0. Use IsNullValidator instead. - */ -class NullValidator extends IsNullValidator -{ -} diff --git a/vendor/symfony/validator/Constraints/Range.php b/vendor/symfony/validator/Constraints/Range.php index bf050ac5..dcaf9db9 100644 --- a/vendor/symfony/validator/Constraints/Range.php +++ b/vendor/symfony/validator/Constraints/Range.php @@ -26,24 +26,6 @@ class Range extends Constraint const TOO_HIGH_ERROR = '2d28afcb-e32e-45fb-a815-01c431a86a69'; const TOO_LOW_ERROR = '76454e69-502c-46c5-9643-f447d837c4d5'; - /** - * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use - * {@link INVALID_CHARACTERS_ERROR} instead. - */ - const INVALID_VALUE_ERROR = self::INVALID_CHARACTERS_ERROR; - - /** - * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use - * {@link TOO_HIGH_ERROR} instead. - */ - const BEYOND_RANGE_ERROR = self::TOO_HIGH_ERROR; - - /** - * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use - * {@link TOO_LOW_ERROR} instead. - */ - const BELOW_RANGE_ERROR = self::TOO_LOW_ERROR; - protected static $errorNames = array( self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR', self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR', diff --git a/vendor/symfony/validator/Constraints/RangeValidator.php b/vendor/symfony/validator/Constraints/RangeValidator.php index 05ef3b47..ac140dbb 100644 --- a/vendor/symfony/validator/Constraints/RangeValidator.php +++ b/vendor/symfony/validator/Constraints/RangeValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -34,18 +33,11 @@ public function validate($value, Constraint $constraint) return; } - if (!is_numeric($value) && !$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->invalidMessage) - ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) - ->setCode(Range::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->invalidMessage) - ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) - ->setCode(Range::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + if (!is_numeric($value) && !$value instanceof \DateTimeInterface) { + $this->context->buildViolation($constraint->invalidMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setCode(Range::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } @@ -57,7 +49,7 @@ public function validate($value, Constraint $constraint) // This allows to compare with any date/time value supported by // the DateTime constructor: // http://php.net/manual/en/datetime.formats.php - if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) { + if ($value instanceof \DateTimeInterface) { if (is_string($min)) { $min = new \DateTime($min); } @@ -68,37 +60,21 @@ public function validate($value, Constraint $constraint) } if (null !== $constraint->max && $value > $max) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->maxMessage) - ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) - ->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE)) - ->setCode(Range::TOO_HIGH_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->maxMessage) - ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) - ->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE)) - ->setCode(Range::TOO_HIGH_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->maxMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE)) + ->setCode(Range::TOO_HIGH_ERROR) + ->addViolation(); return; } if (null !== $constraint->min && $value < $min) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->minMessage) - ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) - ->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE)) - ->setCode(Range::TOO_LOW_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->minMessage) - ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) - ->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE)) - ->setCode(Range::TOO_LOW_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->minMessage) + ->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE)) + ->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE)) + ->setCode(Range::TOO_LOW_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/RegexValidator.php b/vendor/symfony/validator/Constraints/RegexValidator.php index 0aa0ed5e..48ee61a7 100644 --- a/vendor/symfony/validator/Constraints/RegexValidator.php +++ b/vendor/symfony/validator/Constraints/RegexValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -44,17 +43,10 @@ public function validate($value, Constraint $constraint) $value = (string) $value; if ($constraint->match xor preg_match($constraint->pattern, $value)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Regex::REGEX_FAILED_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Regex::REGEX_FAILED_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Regex::REGEX_FAILED_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/TimeValidator.php b/vendor/symfony/validator/Constraints/TimeValidator.php index b5b7b9cc..e398c10a 100644 --- a/vendor/symfony/validator/Constraints/TimeValidator.php +++ b/vendor/symfony/validator/Constraints/TimeValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -59,33 +58,19 @@ public function validate($value, Constraint $constraint) $value = (string) $value; if (!preg_match(static::PATTERN, $value, $matches)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Time::INVALID_FORMAT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Time::INVALID_FORMAT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Time::INVALID_FORMAT_ERROR) + ->addViolation(); return; } if (!self::checkTime($matches[1], $matches[2], $matches[3])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Time::INVALID_TIME_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Time::INVALID_TIME_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Time::INVALID_TIME_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/True.php b/vendor/symfony/validator/Constraints/True.php deleted file mode 100644 index b9efff37..00000000 --- a/vendor/symfony/validator/Constraints/True.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints; - -@trigger_error('The '.__NAMESPACE__.'\True class is deprecated since version 2.7 and will be removed in 3.0. Use the IsTrue class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * @Annotation - * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) - * - * @author Bernhard Schussek - * - * @deprecated since version 2.7, to be removed in 3.0. Use IsTrue instead. - */ -class True extends IsTrue -{ -} diff --git a/vendor/symfony/validator/Constraints/TrueValidator.php b/vendor/symfony/validator/Constraints/TrueValidator.php deleted file mode 100644 index 14d87980..00000000 --- a/vendor/symfony/validator/Constraints/TrueValidator.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Constraints; - -@trigger_error('The '.__NAMESPACE__.'\TrueValidator class is deprecated since version 2.7 and will be removed in 3.0. Use the IsTrueValidator class in the same namespace instead.', E_USER_DEPRECATED); - -/** - * @author Bernhard Schussek - * - * @deprecated since version 2.7, to be removed in 3.0. Use IsTrueValidator instead. - */ -class TrueValidator extends IsTrueValidator -{ -} diff --git a/vendor/symfony/validator/Constraints/TypeValidator.php b/vendor/symfony/validator/Constraints/TypeValidator.php index 48f7e28a..5c31e3b3 100644 --- a/vendor/symfony/validator/Constraints/TypeValidator.php +++ b/vendor/symfony/validator/Constraints/TypeValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -47,18 +46,10 @@ public function validate($value, Constraint $constraint) return; } - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setParameter('{{ type }}', $constraint->type) - ->setCode(Type::INVALID_TYPE_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setParameter('{{ type }}', $constraint->type) - ->setCode(Type::INVALID_TYPE_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setParameter('{{ type }}', $constraint->type) + ->setCode(Type::INVALID_TYPE_ERROR) + ->addViolation(); } } diff --git a/vendor/symfony/validator/Constraints/UrlValidator.php b/vendor/symfony/validator/Constraints/UrlValidator.php index ed0a2579..118a8def 100644 --- a/vendor/symfony/validator/Constraints/UrlValidator.php +++ b/vendor/symfony/validator/Constraints/UrlValidator.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -34,7 +33,9 @@ class UrlValidator extends ConstraintValidator \] # an IPv6 address ) (:[0-9]+)? # a port (optional) - (/?|/\S+|\?\S*|\#\S*) # a /, nothing, a / with something, a query or a fragment + (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path + (?:\? (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional) + (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional) $~ixu'; /** @@ -62,17 +63,10 @@ public function validate($value, Constraint $constraint) $pattern = sprintf(static::PATTERN, implode('|', $constraint->protocols)); if (!preg_match($pattern, $value)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Url::INVALID_URL_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Url::INVALID_URL_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Url::INVALID_URL_ERROR) + ->addViolation(); return; } @@ -80,18 +74,11 @@ public function validate($value, Constraint $constraint) if ($constraint->checkDNS) { $host = parse_url($value, PHP_URL_HOST); - if (!checkdnsrr($host, 'ANY')) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->dnsMessage) - ->setParameter('{{ value }}', $this->formatValue($host)) - ->setCode(Url::INVALID_URL_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->dnsMessage) - ->setParameter('{{ value }}', $this->formatValue($host)) - ->setCode(Url::INVALID_URL_ERROR) - ->addViolation(); - } + if (!is_string($host) || !checkdnsrr($host, 'ANY')) { + $this->context->buildViolation($constraint->dnsMessage) + ->setParameter('{{ value }}', $this->formatValue($host)) + ->setCode(Url::INVALID_URL_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/UuidValidator.php b/vendor/symfony/validator/Constraints/UuidValidator.php index d025a560..b0b4e8a7 100644 --- a/vendor/symfony/validator/Constraints/UuidValidator.php +++ b/vendor/symfony/validator/Constraints/UuidValidator.php @@ -11,10 +11,8 @@ namespace Symfony\Component\Validator\Constraints; -use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Constraints\Deprecated\UuidValidator as Deprecated; use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** @@ -57,21 +55,6 @@ class UuidValidator extends ConstraintValidator const LOOSE_MAX_LENGTH = 39; const LOOSE_FIRST_HYPHEN_POSITION = 4; - /** - * @deprecated since version 2.6, to be removed in 3.0 - */ - const STRICT_PATTERN = '/^[a-f0-9]{8}-[a-f0-9]{4}-[%s][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i'; - - /** - * @deprecated since version 2.6, to be removed in 3.0 - */ - const LOOSE_PATTERN = '/^[a-f0-9]{4}(?:-?[a-f0-9]{4}){7}$/i'; - - /** - * @deprecated since version 2.6, to be removed in 3.0 - */ - const STRICT_UUID_LENGTH = 36; - /** * {@inheritdoc} */ @@ -119,17 +102,10 @@ private function validateLoose($value, Uuid $constraint) for ($i = 0; $i < $l; ++$i) { // Check length if (!isset($trimmed[$i])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_SHORT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_SHORT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_SHORT_ERROR) + ->addViolation(); return; } @@ -139,17 +115,10 @@ private function validateLoose($value, Uuid $constraint) // ^ ^ ^ ^ ^ ^ ^ if ('-' === $trimmed[$i]) { if ($i !== $h) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) + ->addViolation(); return; } @@ -167,17 +136,10 @@ private function validateLoose($value, Uuid $constraint) // Check characters if (!ctype_xdigit($trimmed[$i])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } @@ -185,17 +147,10 @@ private function validateLoose($value, Uuid $constraint) // Check length again if (isset($trimmed[$i])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_LONG_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_LONG_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_LONG_ERROR) + ->addViolation(); } } @@ -214,17 +169,10 @@ private function validateStrict($value, Uuid $constraint) for ($i = 0; $i < self::STRICT_LENGTH; ++$i) { // Check length if (!isset($value[$i])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_SHORT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_SHORT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_SHORT_ERROR) + ->addViolation(); return; } @@ -234,17 +182,10 @@ private function validateStrict($value, Uuid $constraint) // ^ ^ ^ ^ if ('-' === $value[$i]) { if ($i !== $h) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) + ->addViolation(); return; } @@ -260,34 +201,20 @@ private function validateStrict($value, Uuid $constraint) // Check characters if (!ctype_xdigit($value[$i])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_CHARACTERS_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_CHARACTERS_ERROR) + ->addViolation(); return; } // Missing hyphen if ($i === $h) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_HYPHEN_PLACEMENT_ERROR) + ->addViolation(); return; } @@ -295,32 +222,18 @@ private function validateStrict($value, Uuid $constraint) // Check length again if (isset($value[$i])) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_LONG_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::TOO_LONG_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::TOO_LONG_ERROR) + ->addViolation(); } // Check version if (!in_array($value[self::STRICT_VERSION_POSITION], $constraint->versions)) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_VERSION_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_VERSION_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_VERSION_ERROR) + ->addViolation(); } // Check variant - first two bits must equal "10" @@ -328,17 +241,10 @@ private function validateStrict($value, Uuid $constraint) // & 0b1100 (12) // = 0b1000 (8) if ((hexdec($value[self::STRICT_VARIANT_POSITION]) & 12) !== 8) { - if ($this->context instanceof ExecutionContextInterface) { - $this->context->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_VARIANT_ERROR) - ->addViolation(); - } else { - $this->buildViolation($constraint->message) - ->setParameter('{{ value }}', $this->formatValue($value)) - ->setCode(Uuid::INVALID_VARIANT_ERROR) - ->addViolation(); - } + $this->context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $this->formatValue($value)) + ->setCode(Uuid::INVALID_VARIANT_ERROR) + ->addViolation(); } } } diff --git a/vendor/symfony/validator/Constraints/Valid.php b/vendor/symfony/validator/Constraints/Valid.php index 0fb78290..439da3ae 100644 --- a/vendor/symfony/validator/Constraints/Valid.php +++ b/vendor/symfony/validator/Constraints/Valid.php @@ -24,11 +24,6 @@ class Valid extends Constraint { public $traverse = true; - /** - * @deprecated since version 2.5, to be removed in Symfony 3.0. - */ - public $deep = true; - public function __construct($options = null) { if (is_array($options) && array_key_exists('groups', $options)) { @@ -38,10 +33,6 @@ public function __construct($options = null) )); } - if (is_array($options) && array_key_exists('deep', $options)) { - @trigger_error('The "deep" option for the Valid constraint is deprecated since version 2.5 and will be removed in 3.0. When traversing arrays, nested arrays are always traversed. When traversing nested objects, their traversal strategy is used.', E_USER_DEPRECATED); - } - parent::__construct($options); } } diff --git a/vendor/symfony/validator/Context/ExecutionContext.php b/vendor/symfony/validator/Context/ExecutionContext.php index 721766a2..1dc982c2 100644 --- a/vendor/symfony/validator/Context/ExecutionContext.php +++ b/vendor/symfony/validator/Context/ExecutionContext.php @@ -12,16 +12,15 @@ namespace Symfony\Component\Validator\Context; use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\ClassBasedInterface; use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\Mapping\ClassMetadataInterface; use Symfony\Component\Validator\Mapping\MetadataInterface; +use Symfony\Component\Validator\Mapping\MemberMetadata; use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; use Symfony\Component\Validator\Util\PropertyPath; use Symfony\Component\Validator\Validator\ValidatorInterface; -use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface; use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; /** @@ -181,25 +180,8 @@ public function setConstraint(Constraint $constraint) /** * {@inheritdoc} */ - public function addViolation($message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null) + public function addViolation($message, array $parameters = array()) { - // The parameters $invalidValue and following are ignored by the new - // API, as they are not present in the new interface anymore. - // You should use buildViolation() instead. - if (func_num_args() > 2) { - @trigger_error('The parameters $invalidValue, $plural and $code in method '.__METHOD__.' are deprecated since version 2.5 and will be removed in 3.0. Use the '.__CLASS__.'::buildViolation method instead.', E_USER_DEPRECATED); - - $this - ->buildViolation($message, $parameters) - ->setInvalidValue($invalidValue) - ->setPlural($plural) - ->setCode($code) - ->addViolation() - ; - - return; - } - $this->violations->add(new ConstraintViolation( $this->translator->trans($message, $parameters, $this->translationDomain), $message, @@ -297,7 +279,7 @@ public function getConstraint() */ public function getClassName() { - return $this->metadata instanceof ClassBasedInterface ? $this->metadata->getClassName() : null; + return $this->metadata instanceof MemberMetadata || $this->metadata instanceof ClassMetadataInterface ? $this->metadata->getClassName() : null; } /** @@ -316,103 +298,6 @@ public function getPropertyPath($subPath = '') return PropertyPath::append($this->propertyPath, $subPath); } - /** - * {@inheritdoc} - */ - public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the '.__CLASS__.'::buildViolation method instead.', E_USER_DEPRECATED); - - if (func_num_args() > 2) { - $this - ->buildViolation($message, $parameters) - ->atPath($subPath) - ->setInvalidValue($invalidValue) - ->setPlural($plural) - ->setCode($code) - ->addViolation() - ; - - return; - } - - $this - ->buildViolation($message, $parameters) - ->atPath($subPath) - ->addViolation() - ; - } - - /** - * {@inheritdoc} - */ - public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the '.__CLASS__.'::getValidator() method instead.', E_USER_DEPRECATED); - - if (is_array($value)) { - // The $traverse flag is ignored for arrays - $constraint = new Valid(array('traverse' => true, 'deep' => $deep)); - - return $this - ->getValidator() - ->inContext($this) - ->atPath($subPath) - ->validate($value, $constraint, $groups) - ; - } - - if ($traverse && $value instanceof \Traversable) { - $constraint = new Valid(array('traverse' => true, 'deep' => $deep)); - - return $this - ->getValidator() - ->inContext($this) - ->atPath($subPath) - ->validate($value, $constraint, $groups) - ; - } - - return $this - ->getValidator() - ->inContext($this) - ->atPath($subPath) - ->validate($value, null, $groups) - ; - } - - /** - * {@inheritdoc} - */ - public function validateValue($value, $constraints, $subPath = '', $groups = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the '.__CLASS__.'::getValidator() method instead.', E_USER_DEPRECATED); - - return $this - ->getValidator() - ->inContext($this) - ->atPath($subPath) - ->validate($value, $constraints, $groups) - ; - } - - /** - * {@inheritdoc} - */ - public function getMetadataFactory() - { - @trigger_error('The '.__METHOD__.' is deprecated since version 2.5 and will be removed in 3.0. Use the new Symfony\Component\Validator\Context\ExecutionContext::getValidator method in combination with Symfony\Component\Validator\Validator\ValidatorInterface::getMetadataFor or Symfony\Component\Validator\Validator\ValidatorInterface::hasMetadataFor method instead.', E_USER_DEPRECATED); - - $validator = $this->getValidator(); - - if ($validator instanceof LegacyValidatorInterface) { - return $validator->getMetadataFactory(); - } - - // The ValidatorInterface extends from the deprecated MetadataFactoryInterface, so return it when we don't have the factory instance itself - return $validator; - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/validator/Context/ExecutionContextInterface.php b/vendor/symfony/validator/Context/ExecutionContextInterface.php index d38d3374..1b145258 100644 --- a/vendor/symfony/validator/Context/ExecutionContextInterface.php +++ b/vendor/symfony/validator/Context/ExecutionContextInterface.php @@ -12,10 +12,11 @@ namespace Symfony\Component\Validator\Context; use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface; +use Symfony\Component\Validator\Mapping; use Symfony\Component\Validator\Mapping\MetadataInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface; +use Symfony\Component\Validator\ConstraintViolationListInterface; /** * The context of a validation run. @@ -58,8 +59,16 @@ * * @author Bernhard Schussek */ -interface ExecutionContextInterface extends LegacyExecutionContextInterface +interface ExecutionContextInterface { + /** + * Adds a violation at the current node of the validation graph. + * + * @param string $message The error message + * @param array $params The parameters substituted in the error message + */ + public function addViolation($message, array $params = array()); + /** * Returns a builder for adding a violation with extended information. * @@ -222,4 +231,114 @@ public function markObjectAsInitialized($cacheKey); * @see ObjectInitializerInterface */ public function isObjectInitialized($cacheKey); + + /** + * Returns the violations generated by the validator so far. + * + * @return ConstraintViolationListInterface The constraint violation list + */ + public function getViolations(); + + /** + * Returns the value at which validation was started in the object graph. + * + * The validator, when given an object, traverses the properties and + * related objects and their properties. The root of the validation is the + * object from which the traversal started. + * + * The current value is returned by {@link getValue}. + * + * @return mixed The root value of the validation + */ + public function getRoot(); + + /** + * Returns the value that the validator is currently validating. + * + * If you want to retrieve the object that was originally passed to the + * validator, use {@link getRoot}. + * + * @return mixed The currently validated value + */ + public function getValue(); + + /** + * Returns the metadata for the currently validated value. + * + * With the core implementation, this method returns a + * {@link Mapping\ClassMetadataInterface} instance if the current value is an object, + * a {@link Mapping\PropertyMetadata} instance if the current value is + * the value of a property and a {@link Mapping\GetterMetadata} instance if + * the validated value is the result of a getter method. + * + * If the validated value is neither of these, for example if the validator + * has been called with a plain value and constraint, this method returns + * null. + * + * @return MetadataInterface|null The metadata of the currently validated + * value. + */ + public function getMetadata(); + + /** + * Returns the validation group that is currently being validated. + * + * @return string The current validation group + */ + public function getGroup(); + + /** + * Returns the class name of the current node. + * + * If the metadata of the current node does not implement + * {@link Mapping\ClassMetadataInterface} or if no metadata is available for the + * current node, this method returns null. + * + * @return string|null The class name or null, if no class name could be found + */ + public function getClassName(); + + /** + * Returns the property name of the current node. + * + * If the metadata of the current node does not implement + * {@link PropertyMetadataInterface} or if no metadata is available for the + * current node, this method returns null. + * + * @return string|null The property name or null, if no property name could be found + */ + public function getPropertyName(); + + /** + * Returns the property path to the value that the validator is currently + * validating. + * + * For example, take the following object graph: + * + *
    +     * (Person)---($address: Address)---($street: string)
    +     * 
    + * + * When the Person instance is passed to the validator, the + * property path is initially empty. When the $address property + * of that person is validated, the property path is "address". When + * the $street property of the related Address instance + * is validated, the property path is "address.street". + * + * Properties of objects are prefixed with a dot in the property path. + * Indices of arrays or objects implementing the {@link \ArrayAccess} + * interface are enclosed in brackets. For example, if the property in + * the previous example is $addresses and contains an array + * of Address instance, the property path generated for the + * $street property of one of these addresses is for example + * "addresses[0].street". + * + * @param string $subPath Optional. The suffix appended to the current + * property path. + * + * @return string The current property path. The result may be an empty + * string if the validator is currently validating the + * root value of the validation graph. + */ + public function getPropertyPath($subPath = ''); } diff --git a/vendor/symfony/validator/Context/LegacyExecutionContext.php b/vendor/symfony/validator/Context/LegacyExecutionContext.php deleted file mode 100644 index 37ca2a1d..00000000 --- a/vendor/symfony/validator/Context/LegacyExecutionContext.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Context; - -@trigger_error('The '.__NAMESPACE__.'\LegacyExecutionContext class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\MetadataFactoryInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * An execution context that is compatible with the legacy API (< 2.5). - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - */ -class LegacyExecutionContext extends ExecutionContext -{ - /** - * @var MetadataFactoryInterface - */ - private $metadataFactory; - - /** - * Creates a new context. - * - * @see ExecutionContext::__construct() - * - * @internal Called by {@link LegacyExecutionContextFactory}. Should not be used - * in user code. - */ - public function __construct(ValidatorInterface $validator, $root, MetadataFactoryInterface $metadataFactory, TranslatorInterface $translator, $translationDomain = null) - { - parent::__construct( - $validator, - $root, - $translator, - $translationDomain - ); - - $this->metadataFactory = $metadataFactory; - } -} diff --git a/vendor/symfony/validator/Context/LegacyExecutionContextFactory.php b/vendor/symfony/validator/Context/LegacyExecutionContextFactory.php deleted file mode 100644 index 757eb72a..00000000 --- a/vendor/symfony/validator/Context/LegacyExecutionContextFactory.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Context; - -@trigger_error('The '.__NAMESPACE__.'\LegacyExecutionContextFactory class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\MetadataFactoryInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Creates new {@link LegacyExecutionContext} instances. - * - * Implemented for backward compatibility with Symfony < 2.5. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - */ -class LegacyExecutionContextFactory implements ExecutionContextFactoryInterface -{ - /** - * @var MetadataFactoryInterface - */ - private $metadataFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var string|null - */ - private $translationDomain; - - /** - * Creates a new context factory. - * - * @param MetadataFactoryInterface $metadataFactory The metadata factory - * @param TranslatorInterface $translator The translator - * @param string|null $translationDomain The translation domain - * to use for translating - * violation messages - */ - public function __construct(MetadataFactoryInterface $metadataFactory, TranslatorInterface $translator, $translationDomain = null) - { - $this->metadataFactory = $metadataFactory; - $this->translator = $translator; - $this->translationDomain = $translationDomain; - } - - /** - * {@inheritdoc} - */ - public function createContext(ValidatorInterface $validator, $root) - { - return new LegacyExecutionContext( - $validator, - $root, - $this->metadataFactory, - $this->translator, - $this->translationDomain - ); - } -} diff --git a/vendor/symfony/validator/DefaultTranslator.php b/vendor/symfony/validator/DefaultTranslator.php deleted file mode 100644 index 85853d8d..00000000 --- a/vendor/symfony/validator/DefaultTranslator.php +++ /dev/null @@ -1,171 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -@trigger_error('The class '.__NAMESPACE__.'\DefaultTranslator is deprecated since version 2.7 and will be removed in 3.0. Use Symfony\Component\Translation\IdentityTranslator instead.', E_USER_DEPRECATED); - -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Exception\BadMethodCallException; -use Symfony\Component\Validator\Exception\InvalidArgumentException; - -/** - * Simple translator implementation that simply replaces the parameters in - * the message IDs. - * - * Example usage: - * - * $translator = new DefaultTranslator(); - * - * echo $translator->trans( - * 'This is a {{ var }}.', - * array('{{ var }}' => 'donkey') - * ); - * - * // -> This is a donkey. - * - * echo $translator->transChoice( - * 'This is {{ count }} donkey.|These are {{ count }} donkeys.', - * 3, - * array('{{ count }}' => 'three') - * ); - * - * // -> These are three donkeys. - * - * This translator does not support message catalogs, translation domains or - * locales. Instead, it implements a subset of the capabilities of - * {@link \Symfony\Component\Translation\Translator} and can be used in places - * where translation is not required by default but should be optional. - * - * @deprecated since version 2.7, to be removed in 3.0. Use Symfony\Component\Translation\IdentityTranslator instead. - * - * @author Bernhard Schussek - */ -class DefaultTranslator implements TranslatorInterface -{ - /** - * Interpolates the given message. - * - * Parameters are replaced in the message in the same manner that - * {@link strtr()} uses. - * - * Example usage: - * - * $translator = new DefaultTranslator(); - * - * echo $translator->trans( - * 'This is a {{ var }}.', - * array('{{ var }}' => 'donkey') - * ); - * - * // -> This is a donkey. - * - * @param string $id The message id - * @param array $parameters An array of parameters for the message - * @param string $domain Ignored - * @param string $locale Ignored - * - * @return string The interpolated string - */ - public function trans($id, array $parameters = array(), $domain = null, $locale = null) - { - return strtr($id, $parameters); - } - - /** - * Interpolates the given choice message by choosing a variant according to a number. - * - * The variants are passed in the message ID using the format - * "|". "" is chosen if the passed $number is - * exactly 1. "" is chosen otherwise. - * - * This format is consistent with the format supported by - * {@link \Symfony\Component\Translation\Translator}, but it does not - * have the same expressiveness. While Translator supports intervals in - * message translations, which are needed for languages other than English, - * this translator does not. You should use Translator or a custom - * implementation of {@link \Symfony\Component\Translation\TranslatorInterface} if you need this or similar - * functionality. - * - * Example usage: - * - * echo $translator->transChoice( - * 'This is {{ count }} donkey.|These are {{ count }} donkeys.', - * 0, - * array('{{ count }}' => 0) - * ); - * - * // -> These are 0 donkeys. - * - * echo $translator->transChoice( - * 'This is {{ count }} donkey.|These are {{ count }} donkeys.', - * 1, - * array('{{ count }}' => 1) - * ); - * - * // -> This is 1 donkey. - * - * echo $translator->transChoice( - * 'This is {{ count }} donkey.|These are {{ count }} donkeys.', - * 3, - * array('{{ count }}' => 3) - * ); - * - * // -> These are 3 donkeys. - * - * @param string $id The message id - * @param int $number The number to use to find the index of the message - * @param array $parameters An array of parameters for the message - * @param string $domain Ignored - * @param string $locale Ignored - * - * @return string The translated string - * - * @throws InvalidArgumentException If the message id does not have the format - * "singular|plural". - */ - public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) - { - $ids = explode('|', $id); - - if (1 == $number) { - return strtr($ids[0], $parameters); - } - - if (!isset($ids[1])) { - throw new InvalidArgumentException(sprintf('The message "%s" cannot be pluralized, because it is missing a plural (e.g. "There is one apple|There are %%count%% apples").', $id)); - } - - return strtr($ids[1], $parameters); - } - - /** - * Not supported. - * - * @param string $locale The locale - * - * @throws BadMethodCallException - */ - public function setLocale($locale) - { - throw new BadMethodCallException('Unsupported method.'); - } - - /** - * Returns the locale of the translator. - * - * @return string Always returns 'en' - */ - public function getLocale() - { - return 'en'; - } -} diff --git a/vendor/symfony/validator/ExecutionContext.php b/vendor/symfony/validator/ExecutionContext.php deleted file mode 100644 index 52cccb2f..00000000 --- a/vendor/symfony/validator/ExecutionContext.php +++ /dev/null @@ -1,295 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -@trigger_error('The '.__NAMESPACE__.'\ExecutionContext class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Context\ExecutionContext class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Default implementation of {@link ExecutionContextInterface}. - * - * This class is immutable by design. - * - * @author Fabien Potencier - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContext} instead. - */ -class ExecutionContext implements ExecutionContextInterface -{ - /** - * @var GlobalExecutionContextInterface - */ - private $globalContext; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var null|string - */ - private $translationDomain; - - /** - * @var MetadataInterface - */ - private $metadata; - - /** - * @var mixed - */ - private $value; - - /** - * @var string - */ - private $group; - - /** - * @var string - */ - private $propertyPath; - - /** - * Creates a new execution context. - * - * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state - * @param TranslatorInterface $translator The translator for translating violation messages - * @param null|string $translationDomain The domain of the validation messages - * @param MetadataInterface $metadata The metadata of the validated node - * @param mixed $value The value of the validated node - * @param string $group The current validation group - * @param string $propertyPath The property path to the current node - */ - public function __construct(GlobalExecutionContextInterface $globalContext, TranslatorInterface $translator, $translationDomain = null, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '') - { - if (null === $group) { - $group = Constraint::DEFAULT_GROUP; - } - - $this->globalContext = $globalContext; - $this->translator = $translator; - $this->translationDomain = $translationDomain; - $this->metadata = $metadata; - $this->value = $value; - $this->propertyPath = $propertyPath; - $this->group = $group; - } - - /** - * {@inheritdoc} - */ - public function addViolation($message, array $params = array(), $invalidValue = null, $plural = null, $code = null) - { - if (null === $plural) { - $translatedMessage = $this->translator->trans($message, $params, $this->translationDomain); - } else { - try { - $translatedMessage = $this->translator->transChoice($message, $plural, $params, $this->translationDomain); - } catch (\InvalidArgumentException $e) { - $translatedMessage = $this->translator->trans($message, $params, $this->translationDomain); - } - } - - $this->globalContext->getViolations()->add(new ConstraintViolation( - $translatedMessage, - $message, - $params, - $this->globalContext->getRoot(), - $this->propertyPath, - // check using func_num_args() to allow passing null values - func_num_args() >= 3 ? $invalidValue : $this->value, - $plural, - $code - )); - } - - /** - * {@inheritdoc} - */ - public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null) - { - $this->globalContext->getViolations()->add(new ConstraintViolation( - null === $plural - ? $this->translator->trans($message, $parameters, $this->translationDomain) - : $this->translator->transChoice($message, $plural, $parameters, $this->translationDomain), - $message, - $parameters, - $this->globalContext->getRoot(), - $this->getPropertyPath($subPath), - // check using func_num_args() to allow passing null values - func_num_args() >= 4 ? $invalidValue : $this->value, - $plural, - $code - )); - } - - /** - * {@inheritdoc} - */ - public function getViolations() - { - return $this->globalContext->getViolations(); - } - - /** - * {@inheritdoc} - */ - public function getRoot() - { - return $this->globalContext->getRoot(); - } - - /** - * {@inheritdoc} - */ - public function getPropertyPath($subPath = '') - { - if ('' != $subPath && '' !== $this->propertyPath && '[' !== $subPath[0]) { - return $this->propertyPath.'.'.$subPath; - } - - return $this->propertyPath.$subPath; - } - - /** - * {@inheritdoc} - */ - public function getClassName() - { - if ($this->metadata instanceof ClassBasedInterface) { - return $this->metadata->getClassName(); - } - } - - /** - * {@inheritdoc} - */ - public function getPropertyName() - { - if ($this->metadata instanceof PropertyMetadataInterface) { - return $this->metadata->getPropertyName(); - } - } - - /** - * {@inheritdoc} - */ - public function getValue() - { - return $this->value; - } - - /** - * {@inheritdoc} - */ - public function getGroup() - { - return $this->group; - } - - /** - * {@inheritdoc} - */ - public function getMetadata() - { - return $this->metadata; - } - - /** - * {@inheritdoc} - */ - public function getMetadataFor($value) - { - return $this->globalContext->getMetadataFactory()->getMetadataFor($value); - } - - /** - * {@inheritdoc} - */ - public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false) - { - $propertyPath = $this->getPropertyPath($subPath); - - foreach ($this->resolveGroups($groups) as $group) { - $this->globalContext->getVisitor()->validate($value, $group, $propertyPath, $traverse, $deep); - } - } - - /** - * {@inheritdoc} - */ - public function validateValue($value, $constraints, $subPath = '', $groups = null) - { - $constraints = is_array($constraints) ? $constraints : array($constraints); - - if (null === $groups && '' === $subPath) { - $context = clone $this; - $context->value = $value; - $context->executeConstraintValidators($value, $constraints); - - return; - } - - $propertyPath = $this->getPropertyPath($subPath); - - foreach ($this->resolveGroups($groups) as $group) { - $context = clone $this; - $context->value = $value; - $context->group = $group; - $context->propertyPath = $propertyPath; - $context->executeConstraintValidators($value, $constraints); - } - } - - /** - * {@inheritdoc} - */ - public function getMetadataFactory() - { - return $this->globalContext->getMetadataFactory(); - } - - /** - * Executes the validators of the given constraints for the given value. - * - * @param mixed $value The value to validate - * @param Constraint[] $constraints The constraints to match against - */ - private function executeConstraintValidators($value, array $constraints) - { - foreach ($constraints as $constraint) { - $validator = $this->globalContext->getValidatorFactory()->getInstance($constraint); - $validator->initialize($this); - $validator->validate($value, $constraint); - } - } - - /** - * Returns an array of group names. - * - * @param null|string|string[] $groups The groups to resolve. If a single string is - * passed, it is converted to an array. If null - * is passed, an array containing the current - * group of the context is returned. - * - * @return array An array of validation groups - */ - private function resolveGroups($groups) - { - return $groups ? (array) $groups : (array) $this->group; - } -} diff --git a/vendor/symfony/validator/ExecutionContextInterface.php b/vendor/symfony/validator/ExecutionContextInterface.php deleted file mode 100644 index 075fecb0..00000000 --- a/vendor/symfony/validator/ExecutionContextInterface.php +++ /dev/null @@ -1,319 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * Stores the validator's state during validation. - * - * For example, let's validate the following object graph: - * - *
    - * (Person)---($firstName: string)
    - *      \
    - *   ($address: Address)---($street: string)
    - * 
    - * - * We validate the Person instance, which becomes the "root" of the - * validation run (see {@link getRoot}). The state of the context after the - * first step will be like this: - * - *
    - * (Person)---($firstName: string)
    - *    ^ \
    - *   ($address: Address)---($street: string)
    - * 
    - * - * The validator is stopped at the Person node, both the root and the - * value (see {@link getValue}) of the context point to the Person - * instance. The property path is empty at this point (see {@link getPropertyPath}). - * The metadata of the context is the metadata of the Person node - * (see {@link getMetadata}). - * - * After advancing to the property $firstName of the Person - * instance, the state of the context looks like this: - * - *
    - * (Person)---($firstName: string)
    - *      \              ^
    - *   ($address: Address)---($street: string)
    - * 
    - * - * The validator is stopped at the property $firstName. The root still - * points to the Person instance, because this is where the validation - * started. The property path is now "firstName" and the current value is the - * value of that property. - * - * After advancing to the $address property and then to the - * $street property of the Address instance, the context state - * looks like this: - * - *
    - * (Person)---($firstName: string)
    - *      \
    - *   ($address: Address)---($street: string)
    - *                               ^
    - * 
    - * - * The validator is stopped at the property $street. The root still - * points to the Person instance, but the property path is now - * "address.street" and the validated value is the value of that property. - * - * Apart from the root, the property path and the currently validated value, - * the execution context also knows the metadata of the current node (see - * {@link getMetadata}) which for example returns a {@link Mapping\PropertyMetadata} - * or a {@link Mapping\ClassMetadata} object. he context also contains the - * validation group that is currently being validated (see {@link getGroup}) and - * the violations that happened up until now (see {@link getViolations}). - * - * Apart from reading the execution context, you can also use - * {@link addViolation} or {@link addViolationAt} to add new violations and - * {@link validate} or {@link validateValue} to validate values that the - * validator otherwise would not reach. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContextInterface} instead. - */ -interface ExecutionContextInterface -{ - /** - * Adds a violation at the current node of the validation graph. - * - * Note: the parameters $invalidValue, $plural and $code are deprecated since version 2.5 and will be removed in 3.0. - * - * @param string $message The error message - * @param array $params The parameters substituted in the error message - * @param mixed $invalidValue The invalid, validated value - * @param int|null $plural The number to use to pluralize of the message - * @param int|null $code The violation code - */ - public function addViolation($message, array $params = array(), $invalidValue = null, $plural = null, $code = null); - - /** - * Adds a violation at the validation graph node with the given property - * path relative to the current property path. - * - * @param string $subPath The relative property path for the violation - * @param string $message The error message - * @param array $parameters The parameters substituted in the error message - * @param mixed $invalidValue The invalid, validated value - * @param int|null $plural The number to use to pluralize of the message - * @param int|null $code The violation code - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContextInterface::buildViolation()} - * instead. - */ - public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null); - - /** - * Validates the given value within the scope of the current validation. - * - * The value may be any value recognized by the used metadata factory - * (see {@link MetadataFactoryInterface::getMetadata}), or an array or a - * traversable object of such values. - * - * Usually you validate a value that is not the current node of the - * execution context. For this case, you can pass the {@link $subPath} - * argument which is appended to the current property path when a violation - * is created. For example, take the following object graph: - * - *
    -     * (Person)---($address: Address)---($phoneNumber: PhoneNumber)
    -     *                     ^
    -     * 
    - * - * When the execution context stops at the Person instance, the - * property path is "address". When you validate the PhoneNumber - * instance now, pass "phoneNumber" as sub path to correct the property path - * to "address.phoneNumber": - * - *
    -     * $context->validate($address->phoneNumber, 'phoneNumber');
    -     * 
    - * - * Any violations generated during the validation will be added to the - * violation list that you can access with {@link getViolations}. - * - * @param mixed $value The value to validate - * @param string $subPath The path to append to the context's property path - * @param null|string|string[] $groups The groups to validate in. If you don't pass any - * groups here, the current group of the context - * will be used. - * @param bool $traverse Whether to traverse the value if it is an array - * or an instance of \Traversable. - * @param bool $deep Whether to traverse the value recursively if - * it is a collection of collections. - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContextInterface::getValidator()} - * instead. - */ - public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false); - - /** - * Validates a value against a constraint. - * - * Use the parameter $subPath to adapt the property path for the - * validated value. For example, take the following object graph: - * - *
    -     * (Person)---($address: Address)---($street: string)
    -     *                     ^
    -     * 
    - * - * When the validator validates the Address instance, the - * property path stored in the execution context is "address". When you - * manually validate the property $street now, pass the sub path - * "street" to adapt the full property path to "address.street": - * - *
    -     * $context->validate($address->street, new NotNull(), 'street');
    -     * 
    - * - * @param mixed $value The value to validate - * @param Constraint|Constraint[] $constraints The constraint(s) to validate against - * @param string $subPath The path to append to the context's property path - * @param null|string|string[] $groups The groups to validate in. If you don't pass any - * groups here, the current group of the context - * will be used. - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContextInterface::getValidator()} - * instead. - */ - public function validateValue($value, $constraints, $subPath = '', $groups = null); - - /** - * Returns the violations generated by the validator so far. - * - * @return ConstraintViolationListInterface The constraint violation list - */ - public function getViolations(); - - /** - * Returns the value at which validation was started in the object graph. - * - * The validator, when given an object, traverses the properties and - * related objects and their properties. The root of the validation is the - * object from which the traversal started. - * - * The current value is returned by {@link getValue}. - * - * @return mixed The root value of the validation - */ - public function getRoot(); - - /** - * Returns the value that the validator is currently validating. - * - * If you want to retrieve the object that was originally passed to the - * validator, use {@link getRoot}. - * - * @return mixed The currently validated value - */ - public function getValue(); - - /** - * Returns the metadata for the currently validated value. - * - * With the core implementation, this method returns a - * {@link Mapping\ClassMetadata} instance if the current value is an object, - * a {@link Mapping\PropertyMetadata} instance if the current value is - * the value of a property and a {@link Mapping\GetterMetadata} instance if - * the validated value is the result of a getter method. - * - * If the validated value is neither of these, for example if the validator - * has been called with a plain value and constraint, this method returns - * null. - * - * @return MetadataInterface|null The metadata of the currently validated - * value. - */ - public function getMetadata(); - - /** - * Returns the used metadata factory. - * - * @return MetadataFactoryInterface The metadata factory - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContextInterface::getValidator()} - * instead and call - * {@link Validator\ValidatorInterface::getMetadataFor()} or - * {@link Validator\ValidatorInterface::hasMetadataFor()} there. - */ - public function getMetadataFactory(); - - /** - * Returns the validation group that is currently being validated. - * - * @return string The current validation group - */ - public function getGroup(); - - /** - * Returns the class name of the current node. - * - * If the metadata of the current node does not implement - * {@link ClassBasedInterface} or if no metadata is available for the - * current node, this method returns null. - * - * @return string|null The class name or null, if no class name could be found - */ - public function getClassName(); - - /** - * Returns the property name of the current node. - * - * If the metadata of the current node does not implement - * {@link PropertyMetadataInterface} or if no metadata is available for the - * current node, this method returns null. - * - * @return string|null The property name or null, if no property name could be found - */ - public function getPropertyName(); - - /** - * Returns the property path to the value that the validator is currently - * validating. - * - * For example, take the following object graph: - * - *
    -     * (Person)---($address: Address)---($street: string)
    -     * 
    - * - * When the Person instance is passed to the validator, the - * property path is initially empty. When the $address property - * of that person is validated, the property path is "address". When - * the $street property of the related Address instance - * is validated, the property path is "address.street". - * - * Properties of objects are prefixed with a dot in the property path. - * Indices of arrays or objects implementing the {@link \ArrayAccess} - * interface are enclosed in brackets. For example, if the property in - * the previous example is $addresses and contains an array - * of Address instance, the property path generated for the - * $street property of one of these addresses is for example - * "addresses[0].street". - * - * @param string $subPath Optional. The suffix appended to the current - * property path. - * - * @return string The current property path. The result may be an empty - * string if the validator is currently validating the - * root value of the validation graph. - */ - public function getPropertyPath($subPath = ''); -} diff --git a/vendor/symfony/validator/GlobalExecutionContextInterface.php b/vendor/symfony/validator/GlobalExecutionContextInterface.php deleted file mode 100644 index d9bd315a..00000000 --- a/vendor/symfony/validator/GlobalExecutionContextInterface.php +++ /dev/null @@ -1,71 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * Stores the node-independent state of a validation run. - * - * When the validator validates a graph of objects, it uses two classes to - * store the state during the validation: - * - *
      - *
    • For each node in the validation graph (objects, properties, getters) the - * validator creates an instance of {@link ExecutionContextInterface} that - * stores the information about that node.
    • - *
    • One single GlobalExecutionContextInterface stores the state - * that is independent of the current node.
    • - *
    - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Context\ExecutionContextInterface} instead. - */ -interface GlobalExecutionContextInterface -{ - /** - * Returns the violations generated by the validator so far. - * - * @return ConstraintViolationListInterface A list of constraint violations - */ - public function getViolations(); - - /** - * Returns the value at which validation was started in the object graph. - * - * @return mixed The root value - * - * @see ExecutionContextInterface::getRoot() - */ - public function getRoot(); - - /** - * Returns the visitor instance used to validate the object graph nodes. - * - * @return ValidationVisitorInterface The validation visitor - */ - public function getVisitor(); - - /** - * Returns the factory for constraint validators. - * - * @return ConstraintValidatorFactoryInterface The constraint validator factory - */ - public function getValidatorFactory(); - - /** - * Returns the factory for validation metadata objects. - * - * @return MetadataFactoryInterface The metadata factory - */ - public function getMetadataFactory(); -} diff --git a/vendor/symfony/validator/Mapping/BlackholeMetadataFactory.php b/vendor/symfony/validator/Mapping/BlackholeMetadataFactory.php deleted file mode 100644 index 01b80138..00000000 --- a/vendor/symfony/validator/Mapping/BlackholeMetadataFactory.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Mapping; - -@trigger_error('The '.__NAMESPACE__.'\BlackholeMetadataFactory class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Mapping\Factory\BlackHoleMetadataFactory class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Validator\Mapping\Factory\BlackHoleMetadataFactory as MappingBlackHoleMetadataFactory; - -/** - * Alias of {@link Factory\BlackHoleMetadataFactory}. - * - * @author Fabien Potencier - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Factory\BlackHoleMetadataFactory} instead. - */ -class BlackholeMetadataFactory extends MappingBlackHoleMetadataFactory -{ -} diff --git a/vendor/symfony/validator/Mapping/Cache/ApcCache.php b/vendor/symfony/validator/Mapping/Cache/ApcCache.php deleted file mode 100644 index 63fc8ac0..00000000 --- a/vendor/symfony/validator/Mapping/Cache/ApcCache.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Mapping\Cache; - -@trigger_error('The '.__NAMESPACE__.'\ApcCache class is deprecated since version 2.5 and will be removed in 3.0. Use DoctrineCache with the Doctrine\Common\Cache\ApcCache class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Validator\Mapping\ClassMetadata; - -/** - * @deprecated since version 2.5, to be removed in 3.0. - * Use DoctrineCache with \Doctrine\Common\Cache\ApcCache instead. - */ -class ApcCache implements CacheInterface -{ - private $prefix; - - public function __construct($prefix) - { - if (!extension_loaded('apc')) { - throw new \RuntimeException('Unable to use ApcCache to cache validator mappings as APC is not enabled.'); - } - - $this->prefix = $prefix; - } - - public function has($class) - { - if (!function_exists('apc_exists')) { - $exists = false; - - apc_fetch($this->prefix.$class, $exists); - - return $exists; - } - - return apc_exists($this->prefix.$class); - } - - public function read($class) - { - return apc_fetch($this->prefix.$class); - } - - public function write(ClassMetadata $metadata) - { - apc_store($this->prefix.$metadata->getClassName(), $metadata); - } -} diff --git a/vendor/symfony/validator/Mapping/Cache/Psr6Cache.php b/vendor/symfony/validator/Mapping/Cache/Psr6Cache.php new file mode 100644 index 00000000..15badb05 --- /dev/null +++ b/vendor/symfony/validator/Mapping/Cache/Psr6Cache.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Mapping\Cache; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * PSR-6 adapter. + * + * @author Kévin Dunglas + */ +class Psr6Cache implements CacheInterface +{ + /** + * @var CacheItemPoolInterface + */ + private $cacheItemPool; + + public function __construct(CacheItemPoolInterface $cacheItemPool) + { + $this->cacheItemPool = $cacheItemPool; + } + + /** + * {@inheritdoc} + */ + public function has($class) + { + return $this->cacheItemPool->hasItem($this->escapeClassName($class)); + } + + /** + * {@inheritdoc} + */ + public function read($class) + { + $item = $this->cacheItemPool->getItem($this->escapeClassName($class)); + + if (!$item->isHit()) { + return false; + } + + return $item->get(); + } + + /** + * {@inheritdoc} + */ + public function write(ClassMetadata $metadata) + { + $item = $this->cacheItemPool->getItem($this->escapeClassName($metadata->getClassName())); + $item->set($metadata); + + $this->cacheItemPool->save($item); + } + + /** + * Replaces backslashes by dots in a class name. + * + * @param string $class + * + * @return string + */ + private function escapeClassName($class) + { + return str_replace('\\', '.', $class); + } +} diff --git a/vendor/symfony/validator/Mapping/ClassMetadata.php b/vendor/symfony/validator/Mapping/ClassMetadata.php index dc825e1f..af32dae4 100644 --- a/vendor/symfony/validator/Mapping/ClassMetadata.php +++ b/vendor/symfony/validator/Mapping/ClassMetadata.php @@ -17,7 +17,6 @@ use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\Exception\GroupDefinitionException; -use Symfony\Component\Validator\ValidationVisitorInterface; /** * Default implementation of {@link ClassMetadataInterface}. @@ -27,7 +26,7 @@ * @author Bernhard Schussek * @author Fabien Potencier */ -class ClassMetadata extends ElementMetadata implements ClassMetadataInterface +class ClassMetadata extends GenericMetadata implements ClassMetadataInterface { /** * @var string @@ -126,47 +125,6 @@ public function __construct($class) } } - /** - * {@inheritdoc} - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - if (null === $propagatedGroup && Constraint::DEFAULT_GROUP === $group - && ($this->hasGroupSequence() || $this->isGroupSequenceProvider())) { - if ($this->hasGroupSequence()) { - $groups = $this->getGroupSequence()->groups; - } else { - $groups = $value->getGroupSequence(); - } - - foreach ($groups as $group) { - $this->accept($visitor, $value, $group, $propertyPath, Constraint::DEFAULT_GROUP); - - if (count($visitor->getViolations()) > 0) { - break; - } - } - - return; - } - - $visitor->visit($this, $value, $group, $propertyPath); - - if (null !== $value) { - $pathPrefix = empty($propertyPath) ? '' : $propertyPath.'.'; - - foreach ($this->getConstrainedProperties() as $property) { - foreach ($this->getPropertyMetadata($property) as $member) { - $member->accept($visitor, $member->getPropertyValue($value), $group, $pathPrefix.$property, $propagatedGroup); - } - } - } - } - /** * {@inheritdoc} */ @@ -319,6 +277,30 @@ public function addGetterConstraint($property, Constraint $constraint) return $this; } + /** + * Adds a constraint to the getter of the given property. + * + * @param string $property The name of the property + * @param string $method The name of the getter method + * @param Constraint $constraint The constraint + * + * @return $this + */ + public function addGetterMethodConstraint($property, $method, Constraint $constraint) + { + if (!isset($this->getters[$property])) { + $this->getters[$property] = new GetterMetadata($this->getClassName(), $property, $method); + + $this->addPropertyMetadata($this->getters[$property]); + } + + $constraint->addImplicitGroupName($this->getDefaultGroup()); + + $this->getters[$property]->addConstraint($constraint); + + return $this; + } + /** * @param string $property * @param Constraint[] $constraints @@ -334,6 +316,22 @@ public function addGetterConstraints($property, array $constraints) return $this; } + /** + * @param string $property + * @param string $method + * @param Constraint[] $constraints + * + * @return $this + */ + public function addGetterMethodConstraints($property, $method, array $constraints) + { + foreach ($constraints as $constraint) { + $this->addGetterMethodConstraint($property, $method, $constraint); + } + + return $this; + } + /** * Merges the constraints of the given metadata into this object. * @@ -346,10 +344,6 @@ public function mergeConstraints(ClassMetadata $source) } foreach ($source->getConstrainedProperties() as $property) { - if ($this->hasPropertyMetadata($property)) { - continue; - } - foreach ($source->getPropertyMetadata($property) as $member) { $member = clone $member; @@ -376,52 +370,6 @@ public function mergeConstraints(ClassMetadata $source) } } - /** - * Adds a member metadata. - * - * @param MemberMetadata $metadata - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - protected function addMemberMetadata(MemberMetadata $metadata) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the addPropertyMetadata() method instead.', E_USER_DEPRECATED); - - $this->addPropertyMetadata($metadata); - } - - /** - * Returns true if metadatas of members is present for the given property. - * - * @param string $property The name of the property - * - * @return bool - * - * @deprecated since version 2.6, to be removed in 3.0. Use {@link hasPropertyMetadata} instead. - */ - public function hasMemberMetadatas($property) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the hasPropertyMetadata() method instead.', E_USER_DEPRECATED); - - return $this->hasPropertyMetadata($property); - } - - /** - * Returns all metadatas of members describing the given property. - * - * @param string $property The name of the property - * - * @return MemberMetadata[] An array of MemberMetadata - * - * @deprecated since version 2.6, to be removed in 3.0. Use {@link getPropertyMetadata} instead. - */ - public function getMemberMetadatas($property) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getPropertyMetadata() method instead.', E_USER_DEPRECATED); - - return $this->getPropertyMetadata($property); - } - /** * {@inheritdoc} */ diff --git a/vendor/symfony/validator/Mapping/ClassMetadataFactory.php b/vendor/symfony/validator/Mapping/ClassMetadataFactory.php deleted file mode 100644 index 4069b3fb..00000000 --- a/vendor/symfony/validator/Mapping/ClassMetadataFactory.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Mapping; - -@trigger_error('The '.__NAMESPACE__.'\ClassMetadataFactory class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory; - -/** - * Alias of {@link LazyLoadingMetadataFactory}. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link LazyLoadingMetadataFactory} instead. - */ -class ClassMetadataFactory extends LazyLoadingMetadataFactory -{ -} diff --git a/vendor/symfony/validator/Mapping/ClassMetadataInterface.php b/vendor/symfony/validator/Mapping/ClassMetadataInterface.php index d8c3d843..e48e241a 100644 --- a/vendor/symfony/validator/Mapping/ClassMetadataInterface.php +++ b/vendor/symfony/validator/Mapping/ClassMetadataInterface.php @@ -11,9 +11,6 @@ namespace Symfony\Component\Validator\Mapping; -use Symfony\Component\Validator\ClassBasedInterface; -use Symfony\Component\Validator\PropertyMetadataContainerInterface as LegacyPropertyMetadataContainerInterface; - /** * Stores all metadata needed for validating objects of specific class. * @@ -31,7 +28,7 @@ * @see \Symfony\Component\Validator\GroupSequenceProviderInterface * @see TraversalStrategy */ -interface ClassMetadataInterface extends MetadataInterface, LegacyPropertyMetadataContainerInterface, ClassBasedInterface +interface ClassMetadataInterface extends MetadataInterface { /** * Returns the names of all constrained properties. @@ -76,4 +73,33 @@ public function getGroupSequence(); * @see \Symfony\Component\Validator\GroupSequenceProviderInterface */ public function isGroupSequenceProvider(); + + /** + * Check if there's any metadata attached to the given named property. + * + * @param string $property The property name + * + * @return bool + */ + public function hasPropertyMetadata($property); + + /** + * Returns all metadata instances for the given named property. + * + * If your implementation does not support properties, simply throw an + * exception in this method (for example a BadMethodCallException). + * + * @param string $property The property name + * + * @return PropertyMetadataInterface[] A list of metadata instances. Empty if + * no metadata exists for the property. + */ + public function getPropertyMetadata($property); + + /** + * Returns the name of the backing PHP class. + * + * @return string The name of the backing class + */ + public function getClassName(); } diff --git a/vendor/symfony/validator/Mapping/ElementMetadata.php b/vendor/symfony/validator/Mapping/ElementMetadata.php deleted file mode 100644 index 69fe8bfa..00000000 --- a/vendor/symfony/validator/Mapping/ElementMetadata.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Mapping; - -/** - * Contains the metadata of a structural element. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Extend {@link GenericMetadata} instead. - */ -abstract class ElementMetadata extends GenericMetadata -{ - public function __construct() - { - if (!$this instanceof MemberMetadata && !$this instanceof ClassMetadata) { - @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Mapping\GenericMetadata class instead.', E_USER_DEPRECATED); - } - } -} diff --git a/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php b/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php index 82e1cf6b..79ad1f22 100644 --- a/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php +++ b/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php @@ -14,8 +14,6 @@ use Symfony\Component\Validator\Exception\NoSuchMetadataException; use Symfony\Component\Validator\Mapping\Cache\CacheInterface; use Symfony\Component\Validator\Mapping\ClassMetadata; -use Symfony\Component\Validator\Mapping\ClassMetadataInterface; -use Symfony\Component\Validator\Mapping\Loader\LoaderChain; use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; /** diff --git a/vendor/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php b/vendor/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php index 438ef987..a70b94b9 100644 --- a/vendor/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php +++ b/vendor/symfony/validator/Mapping/Factory/MetadataFactoryInterface.php @@ -11,13 +11,33 @@ namespace Symfony\Component\Validator\Mapping\Factory; -use Symfony\Component\Validator\MetadataFactoryInterface as LegacyMetadataFactoryInterface; +use Symfony\Component\Validator\Exception\NoSuchMetadataException; +use Symfony\Component\Validator\Mapping\MetadataInterface; /** * Returns {@link \Symfony\Component\Validator\Mapping\MetadataInterface} instances for values. * * @author Bernhard Schussek */ -interface MetadataFactoryInterface extends LegacyMetadataFactoryInterface +interface MetadataFactoryInterface { + /** + * Returns the metadata for the given value. + * + * @param mixed $value Some value + * + * @return MetadataInterface The metadata for the value + * + * @throws NoSuchMetadataException If no metadata exists for the given value + */ + public function getMetadataFor($value); + + /** + * Returns whether the class is able to return metadata for the given value. + * + * @param mixed $value Some value + * + * @return bool Whether metadata can be returned for that value + */ + public function hasMetadataFor($value); } diff --git a/vendor/symfony/validator/Mapping/GenericMetadata.php b/vendor/symfony/validator/Mapping/GenericMetadata.php index 97915ac7..ff1cb6d3 100644 --- a/vendor/symfony/validator/Mapping/GenericMetadata.php +++ b/vendor/symfony/validator/Mapping/GenericMetadata.php @@ -14,9 +14,7 @@ use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Traverse; use Symfony\Component\Validator\Constraints\Valid; -use Symfony\Component\Validator\Exception\BadMethodCallException; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; -use Symfony\Component\Validator\ValidationVisitorInterface; /** * A generic container of {@link Constraint} objects. @@ -110,13 +108,10 @@ public function __clone() * * If the constraint {@link Valid} is added, the cascading strategy will be * changed to {@link CascadingStrategy::CASCADE}. Depending on the - * properties $traverse and $deep of that constraint, the traversal strategy + * $traverse property of that constraint, the traversal strategy * will be set to one of the following: * - * - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled and $deep - * is enabled - * - {@link TraversalStrategy::IMPLICIT} | {@link TraversalStrategy::STOP_RECURSION} - * if $traverse is enabled, but $deep is disabled + * - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled * - {@link TraversalStrategy::NONE} if $traverse is disabled * * @param Constraint $constraint The constraint to add @@ -140,12 +135,7 @@ public function addConstraint(Constraint $constraint) $this->cascadingStrategy = CascadingStrategy::CASCADE; if ($constraint->traverse) { - // Traverse unless the value is not traversable $this->traversalStrategy = TraversalStrategy::IMPLICIT; - - if (!$constraint->deep) { - $this->traversalStrategy |= TraversalStrategy::STOP_RECURSION; - } } else { $this->traversalStrategy = TraversalStrategy::NONE; } @@ -223,21 +213,4 @@ public function getTraversalStrategy() { return $this->traversalStrategy; } - - /** - * Exists for compatibility with the deprecated - * {@link Symfony\Component\Validator\MetadataInterface}. - * - * Should not be used. - * - * Implemented for backward compatibility with Symfony < 2.5. - * - * @throws BadMethodCallException - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath) - { - throw new BadMethodCallException('Not supported.'); - } } diff --git a/vendor/symfony/validator/Mapping/GetterMetadata.php b/vendor/symfony/validator/Mapping/GetterMetadata.php index 0cf99927..cd42c433 100644 --- a/vendor/symfony/validator/Mapping/GetterMetadata.php +++ b/vendor/symfony/validator/Mapping/GetterMetadata.php @@ -35,25 +35,30 @@ class GetterMetadata extends MemberMetadata /** * Constructor. * - * @param string $class The class the getter is defined on - * @param string $property The property which the getter returns + * @param string $class The class the getter is defined on + * @param string $property The property which the getter returns + * @param string|null $method The method that is called to retrieve the value being validated (null for auto-detection) * * @throws ValidatorException */ - public function __construct($class, $property) + public function __construct($class, $property, $method = null) { - $getMethod = 'get'.ucfirst($property); - $isMethod = 'is'.ucfirst($property); - $hasMethod = 'has'.ucfirst($property); + if (null === $method) { + $getMethod = 'get'.ucfirst($property); + $isMethod = 'is'.ucfirst($property); + $hasMethod = 'has'.ucfirst($property); - if (method_exists($class, $getMethod)) { - $method = $getMethod; - } elseif (method_exists($class, $isMethod)) { - $method = $isMethod; - } elseif (method_exists($class, $hasMethod)) { - $method = $hasMethod; - } else { - throw new ValidatorException(sprintf('Neither of these methods exist in class %s: %s, %s, %s', $class, $getMethod, $isMethod, $hasMethod)); + if (method_exists($class, $getMethod)) { + $method = $getMethod; + } elseif (method_exists($class, $isMethod)) { + $method = $isMethod; + } elseif (method_exists($class, $hasMethod)) { + $method = $hasMethod; + } else { + throw new ValidatorException(sprintf('Neither of these methods exist in class %s: %s, %s, %s', $class, $getMethod, $isMethod, $hasMethod)); + } + } elseif (!method_exists($class, $method)) { + throw new ValidatorException(sprintf('The %s() method does not exist in class %s.', $method, $class)); } parent::__construct($class, $method, $property); diff --git a/vendor/symfony/validator/Mapping/Loader/AnnotationLoader.php b/vendor/symfony/validator/Mapping/Loader/AnnotationLoader.php index d1b8c35b..b09f5a66 100644 --- a/vendor/symfony/validator/Mapping/Loader/AnnotationLoader.php +++ b/vendor/symfony/validator/Mapping/Loader/AnnotationLoader.php @@ -74,12 +74,11 @@ public function loadClassMetadata(ClassMetadata $metadata) foreach ($this->reader->getMethodAnnotations($method) as $constraint) { if ($constraint instanceof Callback) { $constraint->callback = $method->getName(); - $constraint->methods = null; $metadata->addConstraint($constraint); } elseif ($constraint instanceof Constraint) { if (preg_match('/^(get|is|has)(.+)$/i', $method->name, $matches)) { - $metadata->addGetterConstraint(lcfirst($matches[2]), $constraint); + $metadata->addGetterMethodConstraint(lcfirst($matches[2]), $matches[0], $constraint); } else { throw new MappingException(sprintf('The constraint on "%s::%s" cannot be added. Constraints can only be added on methods beginning with "get", "is" or "has".', $className, $method->name)); } diff --git a/vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php b/vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php index 8bcdf9f9..6548c5ae 100644 --- a/vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php +++ b/vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php @@ -35,19 +35,7 @@ class XmlFileLoader extends FileLoader public function loadClassMetadata(ClassMetadata $metadata) { if (null === $this->classes) { - // This method may throw an exception. Do not modify the class' - // state before it completes - $xml = $this->parseFile($this->file); - - $this->classes = array(); - - foreach ($xml->namespace as $namespace) { - $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace)); - } - - foreach ($xml->class as $class) { - $this->classes[(string) $class['name']] = $class; - } + $this->loadClassesFromXml(); } if (isset($this->classes[$metadata->getClassName()])) { @@ -61,6 +49,20 @@ public function loadClassMetadata(ClassMetadata $metadata) return false; } + /** + * Return the names of the classes mapped in this file. + * + * @return string[] The classes names + */ + public function getMappedClasses() + { + if (null === $this->classes) { + $this->loadClassesFromXml(); + } + + return array_keys($this->classes); + } + /** * Parses a collection of "constraint" XML nodes. * @@ -182,6 +184,23 @@ protected function parseFile($path) return simplexml_import_dom($dom); } + private function loadClassesFromXml() + { + // This method may throw an exception. Do not modify the class' + // state before it completes + $xml = $this->parseFile($this->file); + + $this->classes = array(); + + foreach ($xml->namespace as $namespace) { + $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace)); + } + + foreach ($xml->class as $class) { + $this->classes[(string) $class['name']] = $class; + } + } + private function loadClassMetadataFromXml(ClassMetadata $metadata, \SimpleXMLElement $classDescription) { if (count($classDescription->{'group-sequence-provider'}) > 0) { diff --git a/vendor/symfony/validator/Mapping/Loader/YamlFileLoader.php b/vendor/symfony/validator/Mapping/Loader/YamlFileLoader.php index 16212833..1eabd188 100644 --- a/vendor/symfony/validator/Mapping/Loader/YamlFileLoader.php +++ b/vendor/symfony/validator/Mapping/Loader/YamlFileLoader.php @@ -42,19 +42,7 @@ class YamlFileLoader extends FileLoader public function loadClassMetadata(ClassMetadata $metadata) { if (null === $this->classes) { - if (null === $this->yamlParser) { - $this->yamlParser = new YamlParser(); - } - - $this->classes = $this->parseFile($this->file); - - if (isset($this->classes['namespaces'])) { - foreach ($this->classes['namespaces'] as $alias => $namespace) { - $this->addNamespaceAlias($alias, $namespace); - } - - unset($this->classes['namespaces']); - } + $this->loadClassesFromYaml(); } if (isset($this->classes[$metadata->getClassName()])) { @@ -68,6 +56,20 @@ public function loadClassMetadata(ClassMetadata $metadata) return false; } + /** + * Return the names of the classes mapped in this file. + * + * @return string[] The classes names + */ + public function getMappedClasses() + { + if (null === $this->classes) { + $this->loadClassesFromYaml(); + } + + return array_keys($this->classes); + } + /** * Parses a collection of YAML nodes. * @@ -131,12 +133,23 @@ private function parseFile($path) return $classes; } - /** - * Loads the validation metadata from the given YAML class description. - * - * @param ClassMetadata $metadata The metadata to load - * @param array $classDescription The YAML class description - */ + private function loadClassesFromYaml() + { + if (null === $this->yamlParser) { + $this->yamlParser = new YamlParser(); + } + + $this->classes = $this->parseFile($this->file); + + if (isset($this->classes['namespaces'])) { + foreach ($this->classes['namespaces'] as $alias => $namespace) { + $this->addNamespaceAlias($alias, $namespace); + } + + unset($this->classes['namespaces']); + } + } + private function loadClassMetadataFromYaml(ClassMetadata $metadata, array $classDescription) { if (isset($classDescription['group_sequence_provider'])) { diff --git a/vendor/symfony/validator/Mapping/MemberMetadata.php b/vendor/symfony/validator/Mapping/MemberMetadata.php index 0def2484..edeed374 100644 --- a/vendor/symfony/validator/Mapping/MemberMetadata.php +++ b/vendor/symfony/validator/Mapping/MemberMetadata.php @@ -13,7 +13,6 @@ use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; -use Symfony\Component\Validator\ValidationVisitorInterface; /** * Stores all metadata needed for validating a class property. @@ -27,7 +26,7 @@ * * @see PropertyMetadataInterface */ -abstract class MemberMetadata extends ElementMetadata implements PropertyMetadataInterface +abstract class MemberMetadata extends GenericMetadata implements PropertyMetadataInterface { /** * @var string @@ -75,22 +74,6 @@ public function __construct($class, $name, $property) $this->property = $property; } - /** - * {@inheritdoc} - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - $visitor->visit($this, $value, $group, $propertyPath); - - if ($this->isCascaded()) { - $visitor->validate($value, $propagatedGroup ?: $group, $propertyPath, $this->isCollectionCascaded(), $this->isCollectionCascadedDeeply()); - } - } - /** * {@inheritdoc} */ @@ -182,53 +165,6 @@ public function isPrivate($objectOrClassName) return $this->getReflectionMember($objectOrClassName)->isPrivate(); } - /** - * Returns whether objects stored in this member should be validated. - * - * @return bool - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link getCascadingStrategy()} instead. - */ - public function isCascaded() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getCascadingStrategy() method instead.', E_USER_DEPRECATED); - - return (bool) ($this->cascadingStrategy & CascadingStrategy::CASCADE); - } - - /** - * Returns whether arrays or traversable objects stored in this member - * should be traversed and validated in each entry. - * - * @return bool - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link getTraversalStrategy()} instead. - */ - public function isCollectionCascaded() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getTraversalStrategy() method instead.', E_USER_DEPRECATED); - - return (bool) ($this->traversalStrategy & (TraversalStrategy::IMPLICIT | TraversalStrategy::TRAVERSE)); - } - - /** - * Returns whether arrays or traversable objects stored in this member - * should be traversed recursively for inner arrays/traversable objects. - * - * @return bool - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link getTraversalStrategy()} instead. - */ - public function isCollectionCascadedDeeply() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getTraversalStrategy() method instead.', E_USER_DEPRECATED); - - return !($this->traversalStrategy & TraversalStrategy::STOP_RECURSION); - } - /** * Returns the reflection instance for accessing the member's value. * diff --git a/vendor/symfony/validator/Mapping/MetadataInterface.php b/vendor/symfony/validator/Mapping/MetadataInterface.php index 1e9d3c89..514beb94 100644 --- a/vendor/symfony/validator/Mapping/MetadataInterface.php +++ b/vendor/symfony/validator/Mapping/MetadataInterface.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Validator\Mapping; use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\MetadataInterface as LegacyMetadataInterface; /** * A container for validation metadata. @@ -29,7 +28,7 @@ * @see CascadingStrategy * @see TraversalStrategy */ -interface MetadataInterface extends LegacyMetadataInterface +interface MetadataInterface { /** * Returns the strategy for cascading objects. @@ -55,4 +54,13 @@ public function getTraversalStrategy(); * @return Constraint[] A list of Constraint instances */ public function getConstraints(); + + /** + * Returns all constraints for a given validation group. + * + * @param string $group The validation group + * + * @return Constraint[] A list of constraint instances + */ + public function findConstraints($group); } diff --git a/vendor/symfony/validator/Mapping/PropertyMetadataInterface.php b/vendor/symfony/validator/Mapping/PropertyMetadataInterface.php index d7a4114d..059b142e 100644 --- a/vendor/symfony/validator/Mapping/PropertyMetadataInterface.php +++ b/vendor/symfony/validator/Mapping/PropertyMetadataInterface.php @@ -11,9 +11,6 @@ namespace Symfony\Component\Validator\Mapping; -use Symfony\Component\Validator\ClassBasedInterface; -use Symfony\Component\Validator\PropertyMetadataInterface as LegacyPropertyMetadataInterface; - /** * Stores all metadata needed for validating the value of a class property. * @@ -30,6 +27,21 @@ * @see CascadingStrategy * @see TraversalStrategy */ -interface PropertyMetadataInterface extends MetadataInterface, LegacyPropertyMetadataInterface, ClassBasedInterface +interface PropertyMetadataInterface extends MetadataInterface { + /** + * Returns the name of the property. + * + * @return string The property name + */ + public function getPropertyName(); + + /** + * Extracts the value of the property from the given container. + * + * @param mixed $containingValue The container to extract the property value from + * + * @return mixed The value of the property + */ + public function getPropertyValue($containingValue); } diff --git a/vendor/symfony/validator/Mapping/TraversalStrategy.php b/vendor/symfony/validator/Mapping/TraversalStrategy.php index 164992b2..c22469b1 100644 --- a/vendor/symfony/validator/Mapping/TraversalStrategy.php +++ b/vendor/symfony/validator/Mapping/TraversalStrategy.php @@ -46,16 +46,6 @@ class TraversalStrategy */ const TRAVERSE = 4; - /** - * Specifies that nested instances of {@link \Traversable} should never be - * iterated. Can be combined with {@link IMPLICIT} or {@link TRAVERSE}. - * - * @deprecated since version 2.5, to be removed in 3.0. This constant was added for backwards compatibility only. - * - * @internal - */ - const STOP_RECURSION = 8; - /** * Not instantiable. */ diff --git a/vendor/symfony/validator/MetadataFactoryInterface.php b/vendor/symfony/validator/MetadataFactoryInterface.php deleted file mode 100644 index 555bea9a..00000000 --- a/vendor/symfony/validator/MetadataFactoryInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * Returns {@link MetadataInterface} instances for values. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Mapping\Factory\MetadataFactoryInterface} instead. - */ -interface MetadataFactoryInterface -{ - /** - * Returns the metadata for the given value. - * - * @param mixed $value Some value - * - * @return MetadataInterface The metadata for the value - * - * @throws Exception\NoSuchMetadataException If no metadata exists for the given value - */ - public function getMetadataFor($value); - - /** - * Returns whether the class is able to return metadata for the given value. - * - * @param mixed $value Some value - * - * @return bool Whether metadata can be returned for that value - */ - public function hasMetadataFor($value); -} diff --git a/vendor/symfony/validator/MetadataInterface.php b/vendor/symfony/validator/MetadataInterface.php deleted file mode 100644 index 2c894490..00000000 --- a/vendor/symfony/validator/MetadataInterface.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * A container for validation metadata. - * - * The container contains constraints that may belong to different validation - * groups. Constraints for a specific group can be fetched by calling - * {@link findConstraints}. - * - * Implement this interface to add validation metadata to your own metadata - * layer. Each metadata may have named properties. Each property can be - * represented by one or more {@link PropertyMetadataInterface} instances that - * are returned by {@link getPropertyMetadata}. Since - * PropertyMetadataInterface inherits from MetadataInterface, - * each property may be divided into further properties. - * - * The {@link accept} method of each metadata implements the Visitor pattern. - * The method should forward the call to the visitor's - * {@link ValidationVisitorInterface::visit} method and additionally call - * accept() on all structurally related metadata instances. - * - * For example, to store constraints for PHP classes and their properties, - * create a class ClassMetadata (implementing MetadataInterface) - * and a class PropertyMetadata (implementing PropertyMetadataInterface). - * ClassMetadata::getPropertyMetadata($property) returns all - * PropertyMetadata instances for a property of that class. Its - * accept()-method simply forwards to ValidationVisitorInterface::visit() - * and calls accept() on all contained PropertyMetadata - * instances, which themselves call ValidationVisitorInterface::visit() - * again. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Mapping\MetadataInterface} instead. - */ -interface MetadataInterface -{ - /** - * Implementation of the Visitor design pattern. - * - * Calls {@link ValidationVisitorInterface::visit} and then forwards the - * accept()-call to all property metadata instances. - * - * @param ValidationVisitorInterface $visitor The visitor implementing the validation logic - * @param mixed $value The value to validate - * @param string|string[] $group The validation group to validate in - * @param string $propertyPath The current property path in the validation graph - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath); - - /** - * Returns all constraints for a given validation group. - * - * @param string $group The validation group - * - * @return Constraint[] A list of constraint instances - */ - public function findConstraints($group); -} diff --git a/vendor/symfony/validator/PropertyMetadataContainerInterface.php b/vendor/symfony/validator/PropertyMetadataContainerInterface.php deleted file mode 100644 index b5c9cf4d..00000000 --- a/vendor/symfony/validator/PropertyMetadataContainerInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * A container for {@link PropertyMetadataInterface} instances. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Mapping\ClassMetadataInterface} instead. - */ -interface PropertyMetadataContainerInterface -{ - /** - * Check if there's any metadata attached to the given named property. - * - * @param string $property The property name - * - * @return bool - */ - public function hasPropertyMetadata($property); - - /** - * Returns all metadata instances for the given named property. - * - * If your implementation does not support properties, simply throw an - * exception in this method (for example a BadMethodCallException). - * - * @param string $property The property name - * - * @return PropertyMetadataInterface[] A list of metadata instances. Empty if - * no metadata exists for the property. - */ - public function getPropertyMetadata($property); -} diff --git a/vendor/symfony/validator/PropertyMetadataInterface.php b/vendor/symfony/validator/PropertyMetadataInterface.php deleted file mode 100644 index 64ae881e..00000000 --- a/vendor/symfony/validator/PropertyMetadataInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * A container for validation metadata of a property. - * - * What exactly you define as "property" is up to you. The validator expects - * implementations of {@link MetadataInterface} that contain constraints and - * optionally a list of named properties that also have constraints (and may - * have further sub properties). Such properties are mapped by implementations - * of this interface. - * - * @author Bernhard Schussek - * - * @see MetadataInterface - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Mapping\PropertyMetadataInterface} instead. - */ -interface PropertyMetadataInterface extends MetadataInterface -{ - /** - * Returns the name of the property. - * - * @return string The property name - */ - public function getPropertyName(); - - /** - * Extracts the value of the property from the given container. - * - * @param mixed $containingValue The container to extract the property value from - * - * @return mixed The value of the property - */ - public function getPropertyValue($containingValue); -} diff --git a/vendor/symfony/validator/Test/ConstraintValidatorTestCase.php b/vendor/symfony/validator/Test/ConstraintValidatorTestCase.php new file mode 100644 index 00000000..c2932f81 --- /dev/null +++ b/vendor/symfony/validator/Test/ConstraintValidatorTestCase.php @@ -0,0 +1,343 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Test; + +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\NotNull; +use Symfony\Component\Validator\ConstraintValidatorInterface; +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\Context\ExecutionContext; +use Symfony\Component\Validator\Context\ExecutionContextInterface; +use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Validator\Mapping\PropertyMetadata; + +/** + * A test case to ease testing Constraint Validators. + * + * @author Bernhard Schussek + */ +abstract class ConstraintValidatorTestCase extends TestCase +{ + /** + * @var ExecutionContextInterface + */ + protected $context; + + /** + * @var ConstraintValidatorInterface + */ + protected $validator; + + protected $group; + protected $metadata; + protected $object; + protected $value; + protected $root; + protected $propertyPath; + protected $constraint; + protected $defaultTimezone; + + protected function setUp() + { + $this->group = 'MyGroup'; + $this->metadata = null; + $this->object = null; + $this->value = 'InvalidValue'; + $this->root = 'root'; + $this->propertyPath = 'property.path'; + + // Initialize the context with some constraint so that we can + // successfully build a violation. + $this->constraint = new NotNull(); + + $this->context = $this->createContext(); + $this->validator = $this->createValidator(); + $this->validator->initialize($this->context); + + \Locale::setDefault('en'); + + $this->setDefaultTimezone('UTC'); + } + + protected function tearDown() + { + $this->restoreDefaultTimezone(); + } + + protected function setDefaultTimezone($defaultTimezone) + { + // Make sure this method can not be called twice before calling + // also restoreDefaultTimezone() + if (null === $this->defaultTimezone) { + $this->defaultTimezone = date_default_timezone_get(); + date_default_timezone_set($defaultTimezone); + } + } + + protected function restoreDefaultTimezone() + { + if (null !== $this->defaultTimezone) { + date_default_timezone_set($this->defaultTimezone); + $this->defaultTimezone = null; + } + } + + protected function createContext() + { + $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock(); + $validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock(); + $contextualValidator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ContextualValidatorInterface')->getMock(); + + $context = new ExecutionContext($validator, $this->root, $translator); + $context->setGroup($this->group); + $context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); + $context->setConstraint($this->constraint); + + $validator->expects($this->any()) + ->method('inContext') + ->with($context) + ->will($this->returnValue($contextualValidator)); + + return $context; + } + + protected function setGroup($group) + { + $this->group = $group; + $this->context->setGroup($group); + } + + protected function setObject($object) + { + $this->object = $object; + $this->metadata = is_object($object) + ? new ClassMetadata(get_class($object)) + : null; + + $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); + } + + protected function setProperty($object, $property) + { + $this->object = $object; + $this->metadata = is_object($object) + ? new PropertyMetadata(get_class($object), $property) + : null; + + $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); + } + + protected function setValue($value) + { + $this->value = $value; + $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); + } + + protected function setRoot($root) + { + $this->root = $root; + $this->context = $this->createContext(); + $this->validator->initialize($this->context); + } + + protected function setPropertyPath($propertyPath) + { + $this->propertyPath = $propertyPath; + $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath); + } + + protected function expectNoValidate() + { + $validator = $this->context->getValidator()->inContext($this->context); + $validator->expects($this->never()) + ->method('atPath'); + $validator->expects($this->never()) + ->method('validate'); + } + + protected function expectValidateAt($i, $propertyPath, $value, $group) + { + $validator = $this->context->getValidator()->inContext($this->context); + $validator->expects($this->at(2 * $i)) + ->method('atPath') + ->with($propertyPath) + ->will($this->returnValue($validator)); + $validator->expects($this->at(2 * $i + 1)) + ->method('validate') + ->with($value, $this->logicalOr(null, array(), $this->isInstanceOf('\Symfony\Component\Validator\Constraints\Valid')), $group); + } + + protected function expectValidateValueAt($i, $propertyPath, $value, $constraints, $group = null) + { + $contextualValidator = $this->context->getValidator()->inContext($this->context); + $contextualValidator->expects($this->at(2 * $i)) + ->method('atPath') + ->with($propertyPath) + ->will($this->returnValue($contextualValidator)); + $contextualValidator->expects($this->at(2 * $i + 1)) + ->method('validate') + ->with($value, $constraints, $group); + } + + protected function assertNoViolation() + { + $this->assertSame(0, $violationsCount = count($this->context->getViolations()), sprintf('0 violation expected. Got %u.', $violationsCount)); + } + + /** + * @param $message + * + * @return ConstraintViolationAssertion + */ + protected function buildViolation($message) + { + return new ConstraintViolationAssertion($this->context, $message, $this->constraint); + } + + abstract protected function createValidator(); +} + +/** + * @internal + */ +class ConstraintViolationAssertion +{ + /** + * @var ExecutionContextInterface + */ + private $context; + + /** + * @var ConstraintViolationAssertion[] + */ + private $assertions; + + private $message; + private $parameters = array(); + private $invalidValue = 'InvalidValue'; + private $propertyPath = 'property.path'; + private $translationDomain; + private $plural; + private $code; + private $constraint; + private $cause; + + public function __construct(ExecutionContextInterface $context, $message, Constraint $constraint = null, array $assertions = array()) + { + $this->context = $context; + $this->message = $message; + $this->constraint = $constraint; + $this->assertions = $assertions; + } + + public function atPath($path) + { + $this->propertyPath = $path; + + return $this; + } + + public function setParameter($key, $value) + { + $this->parameters[$key] = $value; + + return $this; + } + + public function setParameters(array $parameters) + { + $this->parameters = $parameters; + + return $this; + } + + public function setTranslationDomain($translationDomain) + { + $this->translationDomain = $translationDomain; + + return $this; + } + + public function setInvalidValue($invalidValue) + { + $this->invalidValue = $invalidValue; + + return $this; + } + + public function setPlural($number) + { + $this->plural = $number; + + return $this; + } + + public function setCode($code) + { + $this->code = $code; + + return $this; + } + + public function setCause($cause) + { + $this->cause = $cause; + + return $this; + } + + public function buildNextViolation($message) + { + $assertions = $this->assertions; + $assertions[] = $this; + + return new self($this->context, $message, $this->constraint, $assertions); + } + + public function assertRaised() + { + $expected = array(); + foreach ($this->assertions as $assertion) { + $expected[] = $assertion->getViolation(); + } + $expected[] = $this->getViolation(); + + $violations = iterator_to_array($this->context->getViolations()); + + Assert::assertSame($expectedCount = count($expected), $violationsCount = count($violations), sprintf('%u violation(s) expected. Got %u.', $expectedCount, $violationsCount)); + + reset($violations); + + foreach ($expected as $violation) { + Assert::assertEquals($violation, current($violations)); + next($violations); + } + } + + private function getViolation() + { + return new ConstraintViolation( + null, + $this->message, + $this->parameters, + $this->context->getRoot(), + $this->propertyPath, + $this->invalidValue, + $this->plural, + $this->code, + $this->constraint, + $this->cause + ); + } +} diff --git a/vendor/symfony/validator/Validation.php b/vendor/symfony/validator/Validation.php index 94ed62c5..950efb6c 100644 --- a/vendor/symfony/validator/Validation.php +++ b/vendor/symfony/validator/Validation.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Validator; +use Symfony\Component\Validator\Validator\ValidatorInterface; + /** * Entry point for the Validator component. * @@ -18,24 +20,6 @@ */ final class Validation { - /** - * The Validator API provided by Symfony 2.4 and older. - * - * @deprecated use API_VERSION_2_5_BC instead. - */ - const API_VERSION_2_4 = 1; - - /** - * The Validator API provided by Symfony 2.5 and newer. - */ - const API_VERSION_2_5 = 2; - - /** - * The Validator API provided by Symfony 2.5 and newer with a backwards - * compatibility layer for 2.4 and older. - */ - const API_VERSION_2_5_BC = 3; - /** * Creates a new validator. * diff --git a/vendor/symfony/validator/ValidationVisitor.php b/vendor/symfony/validator/ValidationVisitor.php deleted file mode 100644 index 82af6a9e..00000000 --- a/vendor/symfony/validator/ValidationVisitor.php +++ /dev/null @@ -1,212 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -@trigger_error('The '.__NAMESPACE__.'\ValidationVisitor class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Exception\NoSuchMetadataException; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Default implementation of {@link ValidationVisitorInterface} and - * {@link GlobalExecutionContextInterface}. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - */ -class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionContextInterface -{ - /** - * @var mixed - */ - private $root; - - /** - * @var MetadataFactoryInterface - */ - private $metadataFactory; - - /** - * @var ConstraintValidatorFactoryInterface - */ - private $validatorFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var null|string - */ - private $translationDomain; - - /** - * @var array - */ - private $objectInitializers; - - /** - * @var ConstraintViolationList - */ - private $violations; - - /** - * @var array - */ - private $validatedObjects = array(); - - /** - * Creates a new validation visitor. - * - * @param mixed $root The value passed to the validator - * @param MetadataFactoryInterface $metadataFactory The factory for obtaining metadata instances - * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating constraint validators - * @param TranslatorInterface $translator The translator for translating violation messages - * @param string|null $translationDomain The domain of the translation messages - * @param ObjectInitializerInterface[] $objectInitializers The initializers for preparing objects before validation - * - * @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface - */ - public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, TranslatorInterface $translator, $translationDomain = null, array $objectInitializers = array()) - { - foreach ($objectInitializers as $initializer) { - if (!$initializer instanceof ObjectInitializerInterface) { - throw new UnexpectedTypeException($initializer, 'Symfony\Component\Validator\ObjectInitializerInterface'); - } - } - - $this->root = $root; - $this->metadataFactory = $metadataFactory; - $this->validatorFactory = $validatorFactory; - $this->translator = $translator; - $this->translationDomain = $translationDomain; - $this->objectInitializers = $objectInitializers; - $this->violations = new ConstraintViolationList(); - } - - /** - * {@inheritdoc} - */ - public function visit(MetadataInterface $metadata, $value, $group, $propertyPath) - { - $context = new ExecutionContext( - $this, - $this->translator, - $this->translationDomain, - $metadata, - $value, - $group, - $propertyPath - ); - - $context->validateValue($value, $metadata->findConstraints($group)); - } - - /** - * {@inheritdoc} - */ - public function validate($value, $group, $propertyPath, $traverse = false, $deep = false) - { - if (null === $value) { - return; - } - - if (is_object($value)) { - $hash = spl_object_hash($value); - - // Exit, if the object is already validated for the current group - if (isset($this->validatedObjects[$hash][$group])) { - return; - } - - // Initialize if the object wasn't initialized before - if (!isset($this->validatedObjects[$hash])) { - foreach ($this->objectInitializers as $initializer) { - if (!$initializer instanceof ObjectInitializerInterface) { - throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.'); - } - $initializer->initialize($value); - } - } - - // Remember validating this object before starting and possibly - // traversing the object graph - $this->validatedObjects[$hash][$group] = true; - } - - // Validate arrays recursively by default, otherwise every driver needs - // to implement special handling for arrays. - // https://github.com/symfony/symfony/issues/6246 - if (is_array($value) || ($traverse && $value instanceof \Traversable)) { - foreach ($value as $key => $element) { - // Ignore any scalar values in the collection - if (is_object($element) || is_array($element)) { - // Only repeat the traversal if $deep is set - $this->validate($element, $group, $propertyPath.'['.$key.']', $deep, $deep); - } - } - - try { - $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath); - } catch (NoSuchMetadataException $e) { - // Metadata doesn't necessarily have to exist for - // traversable objects, because we know how to validate - // them anyway. Optionally, additional metadata is supported. - } - } else { - $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath); - } - } - - /** - * {@inheritdoc} - */ - public function getViolations() - { - return $this->violations; - } - - /** - * {@inheritdoc} - */ - public function getRoot() - { - return $this->root; - } - - /** - * {@inheritdoc} - */ - public function getVisitor() - { - return $this; - } - - /** - * {@inheritdoc} - */ - public function getValidatorFactory() - { - return $this->validatorFactory; - } - - /** - * {@inheritdoc} - */ - public function getMetadataFactory() - { - return $this->metadataFactory; - } -} diff --git a/vendor/symfony/validator/ValidationVisitorInterface.php b/vendor/symfony/validator/ValidationVisitorInterface.php deleted file mode 100644 index b6c6e9f1..00000000 --- a/vendor/symfony/validator/ValidationVisitorInterface.php +++ /dev/null @@ -1,82 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * Validates values against constraints defined in {@link MetadataInterface} - * instances. - * - * This interface is an implementation of the Visitor design pattern. A value - * is validated by first passing it to the {@link validate} method. That method - * will determine the matching {@link MetadataInterface} for validating the - * value. It then calls the {@link MetadataInterface::accept} method of that - * metadata. accept() does two things: - * - *
      - *
    1. It calls {@link visit} to validate the value against the constraints of - * the metadata.
    2. - *
    3. It calls accept() on all nested metadata instances with the - * corresponding values extracted from the current value. For example, if the - * current metadata represents a class and the current value is an object of - * that class, the metadata contains nested instances for each property of that - * class. It forwards the call to these nested metadata with the values of the - * corresponding properties in the original object.
    4. - *
    - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - */ -interface ValidationVisitorInterface -{ - /** - * Validates a value. - * - * If the value is an array or a traversable object, you can set the - * parameter $traverse to true in order to run through - * the collection and validate each element. If these elements can be - * collections again and you want to traverse them recursively, set the - * parameter $deep to true as well. - * - * If you set $traversable to true, the visitor will - * nevertheless try to find metadata for the collection and validate its - * constraints. If no such metadata is found, the visitor ignores that and - * only iterates the collection. - * - * If you don't set $traversable to true and the visitor - * does not find metadata for the given value, it will fail with an - * exception. - * - * @param mixed $value The value to validate - * @param string $group The validation group to validate - * @param string $propertyPath The current property path in the validation graph - * @param bool $traverse Whether to traverse the value if it is traversable - * @param bool $deep Whether to traverse nested traversable values recursively - * - * @throws Exception\NoSuchMetadataException If no metadata can be found for - * the given value. - */ - public function validate($value, $group, $propertyPath, $traverse = false, $deep = false); - - /** - * Validates a value against the constraints defined in some metadata. - * - * This method implements the Visitor design pattern. See also - * {@link ValidationVisitorInterface}. - * - * @param MetadataInterface $metadata The metadata holding the constraints - * @param mixed $value The value to validate - * @param string $group The validation group to validate - * @param string $propertyPath The current property path in the validation graph - */ - public function visit(MetadataInterface $metadata, $value, $group, $propertyPath); -} diff --git a/vendor/symfony/validator/Validator.php b/vendor/symfony/validator/Validator.php deleted file mode 100644 index 4da27e7b..00000000 --- a/vendor/symfony/validator/Validator.php +++ /dev/null @@ -1,237 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -@trigger_error('The '.__NAMESPACE__.'\Validator class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Validator\RecursiveValidator class instead.', E_USER_DEPRECATED); - -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\Valid; -use Symfony\Component\Validator\Exception\ValidatorException; - -/** - * Default implementation of {@link ValidatorInterface}. - * - * @author Fabien Potencier - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Validator\RecursiveValidator} instead. - */ -class Validator implements ValidatorInterface, Mapping\Factory\MetadataFactoryInterface -{ - /** - * @var MetadataFactoryInterface - */ - private $metadataFactory; - - /** - * @var ConstraintValidatorFactoryInterface - */ - private $validatorFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var null|string - */ - private $translationDomain; - - /** - * @var array - */ - private $objectInitializers; - - public function __construct( - MetadataFactoryInterface $metadataFactory, - ConstraintValidatorFactoryInterface $validatorFactory, - TranslatorInterface $translator, - $translationDomain = 'validators', - array $objectInitializers = array() - ) { - $this->metadataFactory = $metadataFactory; - $this->validatorFactory = $validatorFactory; - $this->translator = $translator; - $this->translationDomain = $translationDomain; - $this->objectInitializers = $objectInitializers; - } - - /** - * {@inheritdoc} - */ - public function getMetadataFactory() - { - return $this->metadataFactory; - } - - /** - * {@inheritdoc} - */ - public function getMetadataFor($value) - { - return $this->metadataFactory->getMetadataFor($value); - } - - /** - * {@inheritdoc} - */ - public function hasMetadataFor($value) - { - return $this->metadataFactory->hasMetadataFor($value); - } - - /** - * {@inheritdoc} - */ - public function validate($value, $groups = null, $traverse = false, $deep = false) - { - $visitor = $this->createVisitor($value); - - foreach ($this->resolveGroups($groups) as $group) { - $visitor->validate($value, $group, '', $traverse, $deep); - } - - return $visitor->getViolations(); - } - - /** - * {@inheritdoc} - * - * @throws ValidatorException If the metadata for the value does not support properties. - */ - public function validateProperty($containingValue, $property, $groups = null) - { - $visitor = $this->createVisitor($containingValue); - $metadata = $this->metadataFactory->getMetadataFor($containingValue); - - if (!$metadata instanceof PropertyMetadataContainerInterface) { - $valueAsString = is_scalar($containingValue) - ? '"'.$containingValue.'"' - : 'the value of type '.gettype($containingValue); - - throw new ValidatorException(sprintf('The metadata for %s does not support properties.', $valueAsString)); - } - - foreach ($this->resolveGroups($groups) as $group) { - if (!$metadata->hasPropertyMetadata($property)) { - continue; - } - - foreach ($metadata->getPropertyMetadata($property) as $propMeta) { - $propMeta->accept($visitor, $propMeta->getPropertyValue($containingValue), $group, $property); - } - } - - return $visitor->getViolations(); - } - - /** - * {@inheritdoc} - * - * @throws ValidatorException If the metadata for the value does not support properties. - */ - public function validatePropertyValue($containingValue, $property, $value, $groups = null) - { - $visitor = $this->createVisitor(is_object($containingValue) ? $containingValue : $value); - $metadata = $this->metadataFactory->getMetadataFor($containingValue); - - if (!$metadata instanceof PropertyMetadataContainerInterface) { - $valueAsString = is_scalar($containingValue) - ? '"'.$containingValue.'"' - : 'the value of type '.gettype($containingValue); - - throw new ValidatorException(sprintf('The metadata for '.$valueAsString.' does not support properties.')); - } - - // If $containingValue is passed as class name, take $value as root - // and start the traversal with an empty property path - $propertyPath = is_object($containingValue) ? $property : ''; - - foreach ($this->resolveGroups($groups) as $group) { - if (!$metadata->hasPropertyMetadata($property)) { - continue; - } - - foreach ($metadata->getPropertyMetadata($property) as $propMeta) { - $propMeta->accept($visitor, $value, $group, $propertyPath); - } - } - - return $visitor->getViolations(); - } - - /** - * {@inheritdoc} - */ - public function validateValue($value, $constraints, $groups = null) - { - $context = new ExecutionContext($this->createVisitor($value), $this->translator, $this->translationDomain); - - $constraints = is_array($constraints) ? $constraints : array($constraints); - - foreach ($constraints as $constraint) { - if ($constraint instanceof Valid) { - // Why can't the Valid constraint be executed directly? - // - // It cannot be executed like regular other constraints, because regular - // constraints are only executed *if they belong to the validated group*. - // The Valid constraint, on the other hand, is always executed and propagates - // the group to the cascaded object. The propagated group depends on - // - // * Whether a group sequence is currently being executed. Then the default - // group is propagated. - // - // * Otherwise the validated group is propagated. - - throw new ValidatorException( - sprintf( - 'The constraint %s cannot be validated. Use the method validate() instead.', - get_class($constraint) - ) - ); - } - - $context->validateValue($value, $constraint, '', $groups); - } - - return $context->getViolations(); - } - - /** - * @param mixed $root - * - * @return ValidationVisitor - */ - private function createVisitor($root) - { - return new ValidationVisitor( - $root, - $this->metadataFactory, - $this->validatorFactory, - $this->translator, - $this->translationDomain, - $this->objectInitializers - ); - } - - /** - * @param null|string|string[] $groups - * - * @return string[] - */ - private function resolveGroups($groups) - { - return $groups ? (array) $groups : array(Constraint::DEFAULT_GROUP); - } -} diff --git a/vendor/symfony/validator/Validator/LegacyValidator.php b/vendor/symfony/validator/Validator/LegacyValidator.php deleted file mode 100644 index 588baa90..00000000 --- a/vendor/symfony/validator/Validator/LegacyValidator.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Validator; - -@trigger_error('The '.__NAMESPACE__.'\LegacyValidator class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -/** - * A validator that supports both the API of Symfony < 2.5 and Symfony 2.5+. - * - * @author Bernhard Schussek - * - * @see \Symfony\Component\Validator\ValidatorInterface - * @see \Symfony\Component\Validator\Validator\ValidatorInterface - * @deprecated since version 2.5, to be removed in 3.0. - */ -class LegacyValidator extends RecursiveValidator -{ -} diff --git a/vendor/symfony/validator/Validator/RecursiveContextualValidator.php b/vendor/symfony/validator/Validator/RecursiveContextualValidator.php index a9e9f7f0..838d12b4 100644 --- a/vendor/symfony/validator/Validator/RecursiveContextualValidator.php +++ b/vendor/symfony/validator/Validator/RecursiveContextualValidator.php @@ -27,7 +27,7 @@ use Symfony\Component\Validator\Mapping\MetadataInterface; use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; use Symfony\Component\Validator\Mapping\TraversalStrategy; -use Symfony\Component\Validator\MetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\ObjectInitializerInterface; use Symfony\Component\Validator\Util\PropertyPath; @@ -175,7 +175,6 @@ public function validate($value, $constraints = null, $groups = null) $value, $this->defaultPropertyPath, $groups, - true, $this->context ); @@ -200,8 +199,6 @@ public function validateProperty($object, $propertyName, $groups = null) $classMetadata = $this->metadataFactory->getMetadataFor($object); if (!$classMetadata instanceof ClassMetadataInterface) { - // Cannot be UnsupportedMetadataException because of BC with - // Symfony < 2.5 throw new ValidatorException(sprintf( 'The metadata factory should return instances of '. '"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '. @@ -227,7 +224,7 @@ public function validateProperty($object, $propertyName, $groups = null) $this->validateGenericNode( $propertyValue, $object, - $cacheKey.':'.$propertyName, + $cacheKey.':'.get_class($object).':'.$propertyName, $propertyMetadata, $propertyPath, $groups, @@ -251,8 +248,6 @@ public function validatePropertyValue($objectOrClass, $propertyName, $value, $gr $classMetadata = $this->metadataFactory->getMetadataFor($objectOrClass); if (!$classMetadata instanceof ClassMetadataInterface) { - // Cannot be UnsupportedMetadataException because of BC with - // Symfony < 2.5 throw new ValidatorException(sprintf( 'The metadata factory should return instances of '. '"\Symfony\Component\Validator\Mapping\ClassMetadataInterface", '. @@ -285,7 +280,7 @@ public function validatePropertyValue($objectOrClass, $propertyName, $value, $gr $this->validateGenericNode( $value, $object, - $cacheKey.':'.$propertyName, + $cacheKey.':'.get_class($object).':'.$propertyName, $propertyMetadata, $propertyPath, $groups, @@ -387,7 +382,6 @@ private function validateObject($object, $propertyPath, array $groups, $traversa $object, $propertyPath, $groups, - $traversalStrategy & TraversalStrategy::STOP_RECURSION, $context ); } @@ -401,36 +395,24 @@ private function validateObject($object, $propertyPath, array $groups, $traversa * objects are iterated as well. Nested arrays are always iterated, * regardless of the value of $recursive. * - * @param array|\Traversable $collection The collection - * @param string $propertyPath The current property path - * @param string[] $groups The validated groups - * @param bool $stopRecursion Whether to disable - * recursive iteration. For - * backwards compatibility - * with Symfony < 2.5. - * @param ExecutionContextInterface $context The current execution context + * @param array|\Traversable $collection The collection + * @param string $propertyPath The current property path + * @param string[] $groups The validated groups + * @param ExecutionContextInterface $context The current execution context * * @see ClassNode * @see CollectionNode */ - private function validateEachObjectIn($collection, $propertyPath, array $groups, $stopRecursion, ExecutionContextInterface $context) + private function validateEachObjectIn($collection, $propertyPath, array $groups, ExecutionContextInterface $context) { - if ($stopRecursion) { - $traversalStrategy = TraversalStrategy::NONE; - } else { - $traversalStrategy = TraversalStrategy::IMPLICIT; - } - foreach ($collection as $key => $value) { if (is_array($value)) { // Arrays are always cascaded, independent of the specified // traversal strategy - // (BC with Symfony < 2.5) $this->validateEachObjectIn( $value, $propertyPath.'['.$key.']', $groups, - $stopRecursion, $context ); @@ -438,13 +420,12 @@ private function validateEachObjectIn($collection, $propertyPath, array $groups, } // Scalar and null values in the collection are ignored - // (BC with Symfony < 2.5) if (is_object($value)) { $this->validateObject( $value, $propertyPath.'['.$key.']', $groups, - $traversalStrategy, + TraversalStrategy::IMPLICIT, $context ); } @@ -608,7 +589,7 @@ private function validateClassNode($object, $cacheKey, ClassMetadataInterface $m $this->validateGenericNode( $propertyValue, $object, - $cacheKey.':'.$propertyName, + $cacheKey.':'.get_class($object).':'.$propertyName, $propertyMetadata, PropertyPath::append($propertyPath, $propertyName), $groups, @@ -622,9 +603,7 @@ private function validateClassNode($object, $cacheKey, ClassMetadataInterface $m // If no specific traversal strategy was requested when this method // was called, use the traversal strategy of the class' metadata if ($traversalStrategy & TraversalStrategy::IMPLICIT) { - // Keep the STOP_RECURSION flag, if it was set - $traversalStrategy = $metadata->getTraversalStrategy() - | ($traversalStrategy & TraversalStrategy::STOP_RECURSION); + $traversalStrategy = $metadata->getTraversalStrategy(); } // Traverse only if IMPLICIT or TRAVERSE @@ -639,8 +618,6 @@ private function validateClassNode($object, $cacheKey, ClassMetadataInterface $m // If TRAVERSE, fail if we have no Traversable if (!$object instanceof \Traversable) { - // Must throw a ConstraintDefinitionException for backwards - // compatibility reasons with Symfony < 2.5 throw new ConstraintDefinitionException(sprintf( 'Traversal was enabled for "%s", but this class '. 'does not implement "\Traversable".', @@ -652,7 +629,6 @@ private function validateClassNode($object, $cacheKey, ClassMetadataInterface $m $object, $propertyPath, $groups, - $traversalStrategy & TraversalStrategy::STOP_RECURSION, $context ); } @@ -738,9 +714,7 @@ private function validateGenericNode($value, $object, $cacheKey, MetadataInterfa // If no specific traversal strategy was requested when this method // was called, use the traversal strategy of the node's metadata if ($traversalStrategy & TraversalStrategy::IMPLICIT) { - // Keep the STOP_RECURSION flag, if it was set - $traversalStrategy = $metadata->getTraversalStrategy() - | ($traversalStrategy & TraversalStrategy::STOP_RECURSION); + $traversalStrategy = $metadata->getTraversalStrategy(); } // The $cascadedGroups property is set, if the "Default" group is @@ -751,12 +725,10 @@ private function validateGenericNode($value, $object, $cacheKey, MetadataInterfa if (is_array($value)) { // Arrays are always traversed, independent of the specified // traversal strategy - // (BC with Symfony < 2.5) $this->validateEachObjectIn( $value, $propertyPath, $cascadedGroups, - $traversalStrategy & TraversalStrategy::STOP_RECURSION, $context ); @@ -765,7 +737,6 @@ private function validateGenericNode($value, $object, $cacheKey, MetadataInterfa // If the value is a scalar, pass it anyway, because we want // a NoSuchMetadataException to be thrown in that case - // (BC with Symfony < 2.5) $this->validateObject( $value, $propertyPath, @@ -811,7 +782,7 @@ private function stepThroughGroupSequence($value, $object, $cacheKey, MetadataIn $cascadedGroups = $cascadedGroup ? array($cascadedGroup) : null; foreach ($groupSequence->groups as $groupInSequence) { - $groups = array($groupInSequence); + $groups = (array) $groupInSequence; if ($metadata instanceof ClassMetadataInterface) { $this->validateClassNode( diff --git a/vendor/symfony/validator/Validator/RecursiveValidator.php b/vendor/symfony/validator/Validator/RecursiveValidator.php index abd29087..c79d0a77 100644 --- a/vendor/symfony/validator/Validator/RecursiveValidator.php +++ b/vendor/symfony/validator/Validator/RecursiveValidator.php @@ -11,22 +11,18 @@ namespace Symfony\Component\Validator\Validator; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Constraints\GroupSequence; -use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Component\Validator\MetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\ObjectInitializerInterface; -use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface; /** * Recursive implementation of {@link ValidatorInterface}. * * @author Bernhard Schussek */ -class RecursiveValidator implements ValidatorInterface, LegacyValidatorInterface +class RecursiveValidator implements ValidatorInterface { /** * @var ExecutionContextFactoryInterface @@ -113,21 +109,8 @@ public function hasMetadataFor($object) /** * {@inheritdoc} */ - public function validate($value, $groups = null, $traverse = false, $deep = false) + public function validate($value, $constraints = null, $groups = null) { - $numArgs = func_num_args(); - - // Use new signature if constraints are given in the second argument - if (self::testConstraints($groups) && ($numArgs < 3 || 3 === $numArgs && self::testGroups($traverse))) { - // Rename to avoid total confusion ;) - $constraints = $groups; - $groups = $traverse; - } else { - @trigger_error('The Symfony\Component\Validator\ValidatorInterface::validate method is deprecated in version 2.5 and will be removed in version 3.0. Use the Symfony\Component\Validator\Validator\ValidatorInterface::validate method instead.', E_USER_DEPRECATED); - - $constraints = new Valid(array('traverse' => $traverse, 'deep' => $deep)); - } - return $this->startContext($value) ->validate($value, $constraints, $groups) ->getViolations(); @@ -153,34 +136,4 @@ public function validatePropertyValue($objectOrClass, $propertyName, $value, $gr ->validatePropertyValue($objectOrClass, $propertyName, $value, $groups) ->getViolations(); } - - /** - * {@inheritdoc} - */ - public function validateValue($value, $constraints, $groups = null) - { - @trigger_error('The '.__METHOD__.' method is deprecated in version 2.5 and will be removed in version 3.0. Use the Symfony\Component\Validator\Validator\ValidatorInterface::validate method instead.', E_USER_DEPRECATED); - - return $this->validate($value, $constraints, $groups); - } - - /** - * {@inheritdoc} - */ - public function getMetadataFactory() - { - @trigger_error('The '.__METHOD__.' method is deprecated in version 2.5 and will be removed in version 3.0. Use the Symfony\Component\Validator\Validator\ValidatorInterface::getMetadataFor or Symfony\Component\Validator\Validator\ValidatorInterface::hasMetadataFor method instead.', E_USER_DEPRECATED); - - return $this->metadataFactory; - } - - private static function testConstraints($constraints) - { - return null === $constraints || $constraints instanceof Constraint || (is_array($constraints) && (0 === count($constraints) || current($constraints) instanceof Constraint)); - } - - private static function testGroups($groups) - { - return null === $groups || is_string($groups) || $groups instanceof GroupSequence || (is_array($groups) && (0 === count($groups) || is_string(current($groups)) || current($groups) instanceof GroupSequence)); - } } diff --git a/vendor/symfony/validator/ValidatorBuilder.php b/vendor/symfony/validator/ValidatorBuilder.php index 4a69976e..704d76ba 100644 --- a/vendor/symfony/validator/ValidatorBuilder.php +++ b/vendor/symfony/validator/ValidatorBuilder.php @@ -15,21 +15,19 @@ use Doctrine\Common\Annotations\CachedReader; use Doctrine\Common\Annotations\Reader; use Doctrine\Common\Cache\ArrayCache; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Translation\IdentityTranslator; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Validator\Context\ExecutionContextFactory; -use Symfony\Component\Validator\Exception\InvalidArgumentException; use Symfony\Component\Validator\Exception\ValidatorException; use Symfony\Component\Validator\Mapping\Cache\CacheInterface; use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; use Symfony\Component\Validator\Mapping\Loader\LoaderChain; +use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader; use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader; -use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader; use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader; -use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader; use Symfony\Component\Validator\Validator\RecursiveValidator; /** @@ -89,11 +87,6 @@ class ValidatorBuilder implements ValidatorBuilderInterface */ private $translationDomain; - /** - * @var PropertyAccessorInterface|null - */ - private $propertyAccessor; - /** * {@inheritdoc} */ @@ -263,10 +256,6 @@ public function setMetadataCache(CacheInterface $cache) */ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory) { - if (null !== $this->propertyAccessor) { - throw new ValidatorException('You cannot set a validator factory after setting a custom property accessor. Remove the call to setPropertyAccessor() if you want to call setConstraintValidatorFactory().'); - } - $this->validatorFactory = $validatorFactory; return $this; @@ -293,38 +282,29 @@ public function setTranslationDomain($translationDomain) } /** - * {@inheritdoc} - * - * @deprecated since version 2.5, to be removed in 3.0. - * The validator will function without a property accessor. + * @return LoaderInterface[] */ - public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor) + public function getLoaders() { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. The validator will function without a property accessor.', E_USER_DEPRECATED); + $loaders = array(); - if (null !== $this->validatorFactory) { - throw new ValidatorException('You cannot set a property accessor after setting a custom validator factory. Configure your validator factory instead.'); + foreach ($this->xmlMappings as $xmlMapping) { + $loaders[] = new XmlFileLoader($xmlMapping); } - $this->propertyAccessor = $propertyAccessor; - - return $this; - } + foreach ($this->yamlMappings as $yamlMappings) { + $loaders[] = new YamlFileLoader($yamlMappings); + } - /** - * {@inheritdoc} - * - * @deprecated since version 2.7, to be removed in 3.0. - */ - public function setApiVersion($apiVersion) - { - @trigger_error('The '.__METHOD__.' method is deprecated in version 2.7 and will be removed in version 3.0.', E_USER_DEPRECATED); + foreach ($this->methodMappings as $methodName) { + $loaders[] = new StaticMethodLoader($methodName); + } - if (!in_array($apiVersion, array(Validation::API_VERSION_2_4, Validation::API_VERSION_2_5, Validation::API_VERSION_2_5_BC))) { - throw new InvalidArgumentException(sprintf('The requested API version is invalid: "%s"', $apiVersion)); + if ($this->annotationReader) { + $loaders[] = new AnnotationLoader($this->annotationReader); } - return $this; + return $loaders; } /** @@ -335,28 +315,7 @@ public function getValidator() $metadataFactory = $this->metadataFactory; if (!$metadataFactory) { - $loaders = array(); - - if (count($this->xmlMappings) > 1) { - $loaders[] = new XmlFilesLoader($this->xmlMappings); - } elseif (1 === count($this->xmlMappings)) { - $loaders[] = new XmlFileLoader($this->xmlMappings[0]); - } - - if (count($this->yamlMappings) > 1) { - $loaders[] = new YamlFilesLoader($this->yamlMappings); - } elseif (1 === count($this->yamlMappings)) { - $loaders[] = new YamlFileLoader($this->yamlMappings[0]); - } - - foreach ($this->methodMappings as $methodName) { - $loaders[] = new StaticMethodLoader($methodName); - } - - if ($this->annotationReader) { - $loaders[] = new AnnotationLoader($this->annotationReader); - } - + $loaders = $this->getLoaders(); $loader = null; if (count($loaders) > 1) { @@ -368,7 +327,7 @@ public function getValidator() $metadataFactory = new LazyLoadingMetadataFactory($loader, $this->metadataCache); } - $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory($this->propertyAccessor); + $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory(); $translator = $this->translator; if (null === $translator) { diff --git a/vendor/symfony/validator/ValidatorBuilderInterface.php b/vendor/symfony/validator/ValidatorBuilderInterface.php index b9b33e4f..e4bd1040 100644 --- a/vendor/symfony/validator/ValidatorBuilderInterface.php +++ b/vendor/symfony/validator/ValidatorBuilderInterface.php @@ -12,9 +12,10 @@ namespace Symfony\Component\Validator; use Doctrine\Common\Annotations\Reader; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Validator\Mapping\Cache\CacheInterface; +use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; +use Symfony\Component\Validator\Validator\ValidatorInterface; /** * A configurable builder for ValidatorInterface objects. @@ -160,30 +161,6 @@ public function setTranslator(TranslatorInterface $translator); */ public function setTranslationDomain($translationDomain); - /** - * Sets the property accessor for resolving property paths. - * - * @param PropertyAccessorInterface $propertyAccessor The property accessor - * - * @return $this - * - * @deprecated since version 2.5, to be removed in 3.0. - */ - public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor); - - /** - * Sets the API version that the returned validator should support. - * - * @param int $apiVersion The required API version - * - * @return $this - * - * @see Validation::API_VERSION_2_5 - * @see Validation::API_VERSION_2_5_BC - * @deprecated since version 2.7, to be removed in 3.0. - */ - public function setApiVersion($apiVersion); - /** * Builds and returns a new validator object. * diff --git a/vendor/symfony/validator/ValidatorInterface.php b/vendor/symfony/validator/ValidatorInterface.php deleted file mode 100644 index 58b8cd6e..00000000 --- a/vendor/symfony/validator/ValidatorInterface.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator; - -/** - * Validates values and graphs of objects and arrays. - * - * @author Bernhard Schussek - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link \Symfony\Component\Validator\Validator\ValidatorInterface} instead. - */ -interface ValidatorInterface -{ - /** - * Validates a value. - * - * The accepted values depend on the {@link MetadataFactoryInterface} - * implementation. - * - * The signature changed with Symfony 2.5 (see - * {@link Validator\ValidatorInterface::validate()}. This signature will be - * disabled in Symfony 3.0. - * - * @param mixed $value The value to validate - * @param array|null $groups The validation groups to validate - * @param bool $traverse Whether to traverse the value if it is traversable - * @param bool $deep Whether to traverse nested traversable values recursively - * - * @return ConstraintViolationListInterface A list of constraint violations. If the - * list is empty, validation succeeded. - */ - public function validate($value, $groups = null, $traverse = false, $deep = false); - - /** - * Validates a property of a value against its current value. - * - * The accepted values depend on the {@link MetadataFactoryInterface} - * implementation. - * - * @param mixed $containingValue The value containing the property - * @param string $property The name of the property to validate - * @param array|null $groups The validation groups to validate - * - * @return ConstraintViolationListInterface A list of constraint violations. If the - * list is empty, validation succeeded. - */ - public function validateProperty($containingValue, $property, $groups = null); - - /** - * Validate a property of a value against a potential value. - * - * The accepted values depend on the {@link MetadataFactoryInterface} - * implementation. - * - * @param mixed $containingValue The value containing the property - * @param string $property The name of the property to validate - * @param string $value The value to validate against the - * constraints of the property. - * @param array|null $groups The validation groups to validate - * - * @return ConstraintViolationListInterface A list of constraint violations. If the - * list is empty, validation succeeded. - */ - public function validatePropertyValue($containingValue, $property, $value, $groups = null); - - /** - * Validates a value against a constraint or a list of constraints. - * - * @param mixed $value The value to validate - * @param Constraint|Constraint[] $constraints The constraint(s) to validate against - * @param array|null $groups The validation groups to validate - * - * @return ConstraintViolationListInterface A list of constraint violations. If the - * list is empty, validation succeeded. - * - * @deprecated since version 2.5, to be removed in 3.0. - * Renamed to {@link Validator\ValidatorInterface::validate()} - * in Symfony 2.5. - */ - public function validateValue($value, $constraints, $groups = null); - - /** - * Returns the factory for metadata instances. - * - * @return MetadataFactoryInterface The metadata factory - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use {@link Validator\ValidatorInterface::getMetadataFor()} or - * {@link Validator\ValidatorInterface::hasMetadataFor()} - * instead. - */ - public function getMetadataFactory(); -} diff --git a/vendor/symfony/validator/Violation/LegacyConstraintViolationBuilder.php b/vendor/symfony/validator/Violation/LegacyConstraintViolationBuilder.php deleted file mode 100644 index 7410b0a6..00000000 --- a/vendor/symfony/validator/Violation/LegacyConstraintViolationBuilder.php +++ /dev/null @@ -1,166 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\Violation; - -@trigger_error('The '.__NAMESPACE__.'\LegacyConstraintViolationBuilder class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - -use Symfony\Component\Validator\ExecutionContextInterface; - -/** - * Backwards-compatible implementation of {@link ConstraintViolationBuilderInterface}. - * - * @author Bernhard Schussek - * - * @internal You should not instantiate or use this class. Code against - * {@link ConstraintViolationBuilderInterface} instead. - * - * @deprecated since version 2.5.5, to be removed in 3.0. - */ -class LegacyConstraintViolationBuilder implements ConstraintViolationBuilderInterface -{ - /** - * @var ExecutionContextInterface - */ - private $context; - - /** - * @var string - */ - private $message; - - /** - * @var array - */ - private $parameters; - - /** - * @var mixed - */ - private $invalidValue; - - /** - * @var string - */ - private $propertyPath; - - /** - * @var int|null - */ - private $plural; - - /** - * @var mixed - */ - private $code; - - public function __construct(ExecutionContextInterface $context, $message, array $parameters) - { - $this->context = $context; - $this->message = $message; - $this->parameters = $parameters; - $this->invalidValue = $context->getValue(); - } - - /** - * {@inheritdoc} - */ - public function atPath($path) - { - $this->propertyPath = $path; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setParameter($key, $value) - { - $this->parameters[$key] = $value; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setParameters(array $parameters) - { - $this->parameters = $parameters; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setTranslationDomain($translationDomain) - { - // can't be set in the old API - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setInvalidValue($invalidValue) - { - $this->invalidValue = $invalidValue; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setPlural($number) - { - $this->plural = $number; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setCode($code) - { - $this->code = $code; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setCause($cause) - { - // do nothing - we can't save the cause through the old API - - return $this; - } - - /** - * {@inheritdoc} - */ - public function addViolation() - { - if ($this->propertyPath) { - $this->context->addViolationAt($this->propertyPath, $this->message, $this->parameters, $this->invalidValue, $this->plural, $this->code); - - return; - } - - $this->context->addViolation($this->message, $this->parameters, $this->invalidValue, $this->plural, $this->code); - } -} diff --git a/vendor/symfony/validator/composer.json b/vendor/symfony/validator/composer.json index f68d6e95..f17085aa 100644 --- a/vendor/symfony/validator/composer.json +++ b/vendor/symfony/validator/composer.json @@ -16,22 +16,26 @@ } ], "require": { - "php": ">=5.3.9", + "php": ">=5.5.9", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation": "~2.4|~3.0.0" + "symfony/translation": "~2.8|~3.0" }, "require-dev": { - "symfony/http-foundation": "~2.3|~3.0.0", - "symfony/intl": "~2.7.4|~2.8|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0", - "symfony/config": "~2.2|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/intl": "^2.8.18|^3.2.5", + "symfony/yaml": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/cache": "~3.1", "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "egulias/email-validator": "~1.2,>=1.2.1" + "egulias/email-validator": "^1.2.8|~2.0" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "suggest": { + "psr/cache-implementation": "For using the metadata cache.", "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", "doctrine/cache": "For using the default cached annotation reader and metadata cache.", "symfony/http-foundation": "", @@ -39,8 +43,8 @@ "symfony/yaml": "", "symfony/config": "", "egulias/email-validator": "Strict (RFC compliant) email validation", - "symfony/property-access": "For using the 2.4 Validator API", - "symfony/expression-language": "For using the 2.4 Expression validator" + "symfony/property-access": "For using the Expression validator", + "symfony/expression-language": "For using the Expression validator" }, "autoload": { "psr-4": { "Symfony\\Component\\Validator\\": "" }, @@ -51,7 +55,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/validator/phpunit.xml.dist b/vendor/symfony/validator/phpunit.xml.dist index cf8c3438..0e82129d 100644 --- a/vendor/symfony/validator/phpunit.xml.dist +++ b/vendor/symfony/validator/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/symfony/yaml/CHANGELOG.md b/vendor/symfony/yaml/CHANGELOG.md index f55b5704..1a112f12 100644 --- a/vendor/symfony/yaml/CHANGELOG.md +++ b/vendor/symfony/yaml/CHANGELOG.md @@ -1,6 +1,64 @@ CHANGELOG ========= +3.2.0 +----- + + * Mappings with a colon (`:`) that is not followed by a whitespace are deprecated + and will lead to a `ParseException` in Symfony 4.0 (e.g. `foo:bar` must be + `foo: bar`). + + * Added support for parsing PHP constants: + + ```php + Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT); + ``` + + * Support for silently ignoring duplicate mapping keys in YAML has been + deprecated and will lead to a `ParseException` in Symfony 4.0. + +3.1.0 +----- + + * Added support to dump `stdClass` and `ArrayAccess` objects as YAML mappings + through the `Yaml::DUMP_OBJECT_AS_MAP` flag. + + * Strings that are not UTF-8 encoded will be dumped as base64 encoded binary + data. + + * Added support for dumping multi line strings as literal blocks. + + * Added support for parsing base64 encoded binary data when they are tagged + with the `!!binary` tag. + + * Added support for parsing timestamps as `\DateTime` objects: + + ```php + Yaml::parse('2001-12-15 21:59:43.10 -5', Yaml::PARSE_DATETIME); + ``` + + * `\DateTime` and `\DateTimeImmutable` objects are dumped as YAML timestamps. + + * Deprecated usage of `%` at the beginning of an unquoted string. + + * Added support for customizing the YAML parser behavior through an optional bit field: + + ```php + Yaml::parse('{ "foo": "bar", "fiz": "cat" }', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE | Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP); + ``` + + * Added support for customizing the dumped YAML string through an optional bit field: + + ```php + Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE | Yaml::DUMP_OBJECT); + ``` + +3.0.0 +----- + + * Yaml::parse() now throws an exception when a blackslash is not escaped + in double-quoted strings + 2.8.0 ----- diff --git a/vendor/symfony/yaml/Command/LintCommand.php b/vendor/symfony/yaml/Command/LintCommand.php new file mode 100644 index 00000000..ea86a1f8 --- /dev/null +++ b/vendor/symfony/yaml/Command/LintCommand.php @@ -0,0 +1,234 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Parser; + +/** + * Validates YAML files syntax and outputs encountered errors. + * + * @author Grégoire Pineau + * @author Robin Chalas + */ +class LintCommand extends Command +{ + private $parser; + private $format; + private $displayCorrectFiles; + private $directoryIteratorProvider; + private $isReadableProvider; + + public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null) + { + parent::__construct($name); + + $this->directoryIteratorProvider = $directoryIteratorProvider; + $this->isReadableProvider = $isReadableProvider; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('lint:yaml') + ->setDescription('Lints a file and outputs encountered errors') + ->addArgument('filename', null, 'A file or a directory or STDIN') + ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') + ->setHelp(<<%command.name% command lints a YAML file and outputs to STDOUT +the first encountered syntax error. + +You can validates YAML contents passed from STDIN: + + cat filename | php %command.full_name% + +You can also validate the syntax of a file: + + php %command.full_name% filename + +Or of a whole directory: + + php %command.full_name% dirname + php %command.full_name% dirname --format=json + +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + $filename = $input->getArgument('filename'); + $this->format = $input->getOption('format'); + $this->displayCorrectFiles = $output->isVerbose(); + + if (!$filename) { + if (!$stdin = $this->getStdin()) { + throw new \RuntimeException('Please provide a filename or pipe file content to STDIN.'); + } + + return $this->display($io, array($this->validate($stdin))); + } + + if (!$this->isReadable($filename)) { + throw new \RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); + } + + $filesInfo = array(); + foreach ($this->getFiles($filename) as $file) { + $filesInfo[] = $this->validate(file_get_contents($file), $file); + } + + return $this->display($io, $filesInfo); + } + + private function validate($content, $file = null) + { + try { + $this->getParser()->parse($content); + } catch (ParseException $e) { + return array('file' => $file, 'valid' => false, 'message' => $e->getMessage()); + } + + return array('file' => $file, 'valid' => true); + } + + private function display(SymfonyStyle $io, array $files) + { + switch ($this->format) { + case 'txt': + return $this->displayTxt($io, $files); + case 'json': + return $this->displayJson($io, $files); + default: + throw new \InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); + } + } + + private function displayTxt(SymfonyStyle $io, array $filesInfo) + { + $countFiles = count($filesInfo); + $erroredFiles = 0; + + foreach ($filesInfo as $info) { + if ($info['valid'] && $this->displayCorrectFiles) { + $io->comment('OK'.($info['file'] ? sprintf(' in %s', $info['file']) : '')); + } elseif (!$info['valid']) { + ++$erroredFiles; + $io->text(' ERROR '.($info['file'] ? sprintf(' in %s', $info['file']) : '')); + $io->text(sprintf(' >> %s', $info['message'])); + } + } + + if ($erroredFiles === 0) { + $io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles)); + } else { + $io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles)); + } + + return min($erroredFiles, 1); + } + + private function displayJson(SymfonyStyle $io, array $filesInfo) + { + $errors = 0; + + array_walk($filesInfo, function (&$v) use (&$errors) { + $v['file'] = (string) $v['file']; + if (!$v['valid']) { + ++$errors; + } + }); + + $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + + return min($errors, 1); + } + + private function getFiles($fileOrDirectory) + { + if (is_file($fileOrDirectory)) { + yield new \SplFileInfo($fileOrDirectory); + + return; + } + + foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) { + if (!in_array($file->getExtension(), array('yml', 'yaml'))) { + continue; + } + + yield $file; + } + } + + private function getStdin() + { + if (0 !== ftell(STDIN)) { + return; + } + + $inputs = ''; + while (!feof(STDIN)) { + $inputs .= fread(STDIN, 1024); + } + + return $inputs; + } + + private function getParser() + { + if (!$this->parser) { + $this->parser = new Parser(); + } + + return $this->parser; + } + + private function getDirectoryIterator($directory) + { + $default = function ($directory) { + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + }; + + if (null !== $this->directoryIteratorProvider) { + return call_user_func($this->directoryIteratorProvider, $directory, $default); + } + + return $default($directory); + } + + private function isReadable($fileOrDirectory) + { + $default = function ($fileOrDirectory) { + return is_readable($fileOrDirectory); + }; + + if (null !== $this->isReadableProvider) { + return call_user_func($this->isReadableProvider, $fileOrDirectory, $default); + } + + return $default($fileOrDirectory); + } +} diff --git a/vendor/symfony/yaml/Dumper.php b/vendor/symfony/yaml/Dumper.php index 05817f5d..98d82434 100644 --- a/vendor/symfony/yaml/Dumper.php +++ b/vendor/symfony/yaml/Dumper.php @@ -23,7 +23,19 @@ class Dumper * * @var int */ - protected $indentation = 4; + protected $indentation; + + /** + * @param int $indentation + */ + public function __construct($indentation = 4) + { + if ($indentation < 1) { + throw new \InvalidArgumentException('The indentation must be greater than zero.'); + } + + $this->indentation = $indentation; + } /** * Sets the indentation. @@ -32,9 +44,7 @@ class Dumper */ public function setIndentation($num) { - if ($num < 1) { - throw new \InvalidArgumentException('The indentation must be greater than zero.'); - } + @trigger_error('The '.__METHOD__.' method is deprecated since version 3.1 and will be removed in 4.0. Pass the indentation to the constructor instead.', E_USER_DEPRECATED); $this->indentation = (int) $num; } @@ -42,32 +52,59 @@ public function setIndentation($num) /** * Dumps a PHP value to YAML. * - * @param mixed $input The PHP value - * @param int $inline The level where you switch to inline YAML - * @param int $indent The level of indentation (used internally) - * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param bool $objectSupport true if object support is enabled, false otherwise + * @param mixed $input The PHP value + * @param int $inline The level where you switch to inline YAML + * @param int $indent The level of indentation (used internally) + * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string * * @return string The YAML representation of the PHP value */ - public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false) + public function dump($input, $inline = 0, $indent = 0, $flags = 0) { + if (is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (func_num_args() >= 5) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); + + if (func_get_arg(4)) { + $flags |= Yaml::DUMP_OBJECT; + } + } + $output = ''; $prefix = $indent ? str_repeat(' ', $indent) : ''; if ($inline <= 0 || !is_array($input) || empty($input)) { - $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport); + $output .= $prefix.Inline::dump($input, $flags); } else { $isAHash = Inline::isHash($input); foreach ($input as $key => $value) { + if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n")) { + $output .= sprintf("%s%s%s |\n", $prefix, $isAHash ? Inline::dump($key, $flags).':' : '-', ''); + + foreach (preg_split('/\n|\r\n/', $value) as $row) { + $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row); + } + + continue; + } + $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value); $output .= sprintf('%s%s%s%s', $prefix, - $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-', + $isAHash ? Inline::dump($key, $flags).':' : '-', $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport) + $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) ).($willBeInlined ? "\n" : ''); } } diff --git a/vendor/symfony/yaml/Escaper.php b/vendor/symfony/yaml/Escaper.php index a74f14dd..94bb3924 100644 --- a/vendor/symfony/yaml/Escaper.php +++ b/vendor/symfony/yaml/Escaper.php @@ -33,13 +33,15 @@ class Escaper "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", - "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9"); + "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", + ); private static $escaped = array('\\\\', '\\"', '\\\\', '\\"', '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', - '\\N', '\\_', '\\L', '\\P'); + '\\N', '\\_', '\\L', '\\P', + ); /** * Determines if a PHP value would require double quoting in YAML. @@ -50,7 +52,7 @@ class Escaper */ public static function requiresDoubleQuoting($value) { - return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); + return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); } /** @@ -82,7 +84,7 @@ public static function requiresSingleQuoting($value) // Determines if the PHP value contains any single characters that would // cause it to require single quoting in YAML. - return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); + return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); } /** diff --git a/vendor/symfony/yaml/Exception/ParseException.php b/vendor/symfony/yaml/Exception/ParseException.php index b74eb913..3b38b643 100644 --- a/vendor/symfony/yaml/Exception/ParseException.php +++ b/vendor/symfony/yaml/Exception/ParseException.php @@ -26,11 +26,11 @@ class ParseException extends RuntimeException /** * Constructor. * - * @param string $message The error message - * @param int $parsedLine The line where the error occurred - * @param int $snippet The snippet of code near the problem - * @param string $parsedFile The file name where the error occurred - * @param \Exception $previous The previous exception + * @param string $message The error message + * @param int $parsedLine The line where the error occurred + * @param string|null $snippet The snippet of code near the problem + * @param string|null $parsedFile The file name where the error occurred + * @param \Exception|null $previous The previous exception */ public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null) { @@ -123,12 +123,7 @@ private function updateRepr() } if (null !== $this->parsedFile) { - if (PHP_VERSION_ID >= 50400) { - $jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - } else { - $jsonOptions = 0; - } - $this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions)); + $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); } if ($this->parsedLine >= 0) { diff --git a/vendor/symfony/yaml/Inline.php b/vendor/symfony/yaml/Inline.php index 74d23be0..ccbf9046 100644 --- a/vendor/symfony/yaml/Inline.php +++ b/vendor/symfony/yaml/Inline.php @@ -18,33 +18,69 @@ * Inline implements a YAML parser/dumper for the YAML inline syntax. * * @author Fabien Potencier + * + * @internal */ class Inline { - const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; + const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')'; + + public static $parsedLineNumber; private static $exceptionOnInvalidType = false; private static $objectSupport = false; private static $objectForMap = false; + private static $constantSupport = false; /** * Converts a YAML string to a PHP value. * - * @param string $value A YAML string - * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param bool $objectSupport true if object support is enabled, false otherwise - * @param bool $objectForMap true if maps should return a stdClass instead of array() - * @param array $references Mapping of variable names to values + * @param string $value A YAML string + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param array $references Mapping of variable names to values * * @return mixed A PHP value * * @throws ParseException */ - public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array()) + public static function parse($value, $flags = 0, $references = array()) { - self::$exceptionOnInvalidType = $exceptionOnInvalidType; - self::$objectSupport = $objectSupport; - self::$objectForMap = $objectForMap; + if (is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (func_num_args() >= 3 && !is_array($references)) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); + + if ($references) { + $flags |= Yaml::PARSE_OBJECT; + } + + if (func_num_args() >= 4) { + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); + + if (func_get_arg(3)) { + $flags |= Yaml::PARSE_OBJECT_FOR_MAP; + } + } + + if (func_num_args() >= 5) { + $references = func_get_arg(4); + } else { + $references = array(); + } + } + + self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags); + self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags); + self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags); + self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags); $value = trim($value); @@ -60,15 +96,15 @@ public static function parse($value, $exceptionOnInvalidType = false, $objectSup $i = 0; switch ($value[0]) { case '[': - $result = self::parseSequence($value, $i, $references); + $result = self::parseSequence($value, $flags, $i, $references); ++$i; break; case '{': - $result = self::parseMapping($value, $i, $references); + $result = self::parseMapping($value, $flags, $i, $references); ++$i; break; default: - $result = self::parseScalar($value, null, array('"', "'"), $i, true, $references); + $result = self::parseScalar($value, $flags, null, array('"', "'"), $i, true, $references); } // some comments are allowed at the end @@ -86,35 +122,58 @@ public static function parse($value, $exceptionOnInvalidType = false, $objectSup /** * Dumps a given PHP variable to a YAML string. * - * @param mixed $value The PHP variable to convert - * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param bool $objectSupport true if object support is enabled, false otherwise + * @param mixed $value The PHP variable to convert + * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string * * @return string The YAML string representing the PHP value * * @throws DumpException When trying to dump PHP resource */ - public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false) + public static function dump($value, $flags = 0) { + if (is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (func_num_args() >= 3) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); + + if (func_get_arg(2)) { + $flags |= Yaml::DUMP_OBJECT; + } + } + switch (true) { case is_resource($value): - if ($exceptionOnInvalidType) { + if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); } return 'null'; + case $value instanceof \DateTimeInterface: + return $value->format('c'); case is_object($value): - if ($objectSupport) { + if (Yaml::DUMP_OBJECT & $flags) { return '!php/object:'.serialize($value); } - if ($exceptionOnInvalidType) { + if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { + return self::dumpArray((array) $value, $flags); + } + + if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { throw new DumpException('Object support when dumping a YAML file has been disabled.'); } return 'null'; case is_array($value): - return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport); + return self::dumpArray($value, $flags); case null === $value: return 'null'; case true === $value: @@ -146,11 +205,14 @@ public static function dump($value, $exceptionOnInvalidType = false, $objectSupp return $repr; case '' == $value: return "''"; + case self::isBinaryString($value): + return '!!binary '.base64_encode($value); case Escaper::requiresDoubleQuoting($value): return Escaper::escapeWithDoubleQuotes($value); case Escaper::requiresSingleQuoting($value): - case preg_match(self::getHexRegex(), $value): - case preg_match(self::getTimestampRegex(), $value): + case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value): + case Parser::preg_match(self::getHexRegex(), $value): + case Parser::preg_match(self::getTimestampRegex(), $value): return Escaper::escapeWithSingleQuotes($value); default: return $value; @@ -182,19 +244,18 @@ public static function isHash(array $value) /** * Dumps a PHP array to a YAML string. * - * @param array $value The PHP array to dump - * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param bool $objectSupport true if object support is enabled, false otherwise + * @param array $value The PHP array to dump + * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string * * @return string The YAML string representing the PHP array */ - private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport) + private static function dumpArray($value, $flags) { // array if ($value && !self::isHash($value)) { $output = array(); foreach ($value as $val) { - $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport); + $output[] = self::dump($val, $flags); } return sprintf('[%s]', implode(', ', $output)); @@ -203,7 +264,7 @@ private static function dumpArray($value, $exceptionOnInvalidType, $objectSuppor // hash $output = array(); foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport)); + $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags)); } return sprintf('{ %s }', implode(', ', $output)); @@ -212,12 +273,13 @@ private static function dumpArray($value, $exceptionOnInvalidType, $objectSuppor /** * Parses a YAML scalar. * - * @param string $scalar - * @param string $delimiters - * @param array $stringDelimiters - * @param int &$i - * @param bool $evaluate - * @param array $references + * @param string $scalar + * @param int $flags + * @param string[] $delimiters + * @param string[] $stringDelimiters + * @param int &$i + * @param bool $evaluate + * @param array $references * * @return string * @@ -225,7 +287,7 @@ private static function dumpArray($value, $exceptionOnInvalidType, $objectSuppor * * @internal */ - public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array()) + public static function parseScalar($scalar, $flags = 0, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array()) { if (in_array($scalar[$i], $stringDelimiters)) { // quoted scalar @@ -244,10 +306,10 @@ public static function parseScalar($scalar, $delimiters = null, $stringDelimiter $i += strlen($output); // remove comments - if (preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) { + if (Parser::preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) { $output = substr($output, 0, $match[0][1]); } - } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { + } elseif (Parser::preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { $output = $match[1]; $i += strlen($output); } else { @@ -256,14 +318,15 @@ public static function parseScalar($scalar, $delimiters = null, $stringDelimiter // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >) if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) { - @trigger_error(sprintf('Not quoting the scalar "%s" starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output, $output[0]), E_USER_DEPRECATED); + throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0])); + } - // to be thrown in 3.0 - // throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0])); + if ($output && '%' === $output[0]) { + @trigger_error(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', $output), E_USER_DEPRECATED); } if ($evaluate) { - $output = self::evaluateScalar($output, $references); + $output = self::evaluateScalar($output, $flags, $references); } } @@ -282,7 +345,7 @@ public static function parseScalar($scalar, $delimiters = null, $stringDelimiter */ private static function parseQuotedScalar($scalar, &$i) { - if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { + if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i))); } @@ -304,6 +367,7 @@ private static function parseQuotedScalar($scalar, &$i) * Parses a YAML sequence. * * @param string $sequence + * @param int $flags * @param int &$i * @param array $references * @@ -311,7 +375,7 @@ private static function parseQuotedScalar($scalar, &$i) * * @throws ParseException When malformed inline YAML string is parsed */ - private static function parseSequence($sequence, &$i = 0, $references = array()) + private static function parseSequence($sequence, $flags, &$i = 0, $references = array()) { $output = array(); $len = strlen($sequence); @@ -322,11 +386,11 @@ private static function parseSequence($sequence, &$i = 0, $references = array()) switch ($sequence[$i]) { case '[': // nested sequence - $output[] = self::parseSequence($sequence, $i, $references); + $output[] = self::parseSequence($sequence, $flags, $i, $references); break; case '{': // nested mapping - $output[] = self::parseMapping($sequence, $i, $references); + $output[] = self::parseMapping($sequence, $flags, $i, $references); break; case ']': return $output; @@ -335,14 +399,14 @@ private static function parseSequence($sequence, &$i = 0, $references = array()) break; default: $isQuoted = in_array($sequence[$i], array('"', "'")); - $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references); + $value = self::parseScalar($sequence, $flags, array(',', ']'), array('"', "'"), $i, true, $references); // the value can be an array if a reference has been resolved to an array var - if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) { + if (is_string($value) && !$isQuoted && false !== strpos($value, ': ')) { // embedded mapping? try { $pos = 0; - $value = self::parseMapping('{'.$value.'}', $pos, $references); + $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references); } catch (\InvalidArgumentException $e) { // no, it's not } @@ -363,6 +427,7 @@ private static function parseSequence($sequence, &$i = 0, $references = array()) * Parses a YAML mapping. * * @param string $mapping + * @param int $flags * @param int &$i * @param array $references * @@ -370,7 +435,7 @@ private static function parseSequence($sequence, &$i = 0, $references = array()) * * @throws ParseException When malformed inline YAML string is parsed */ - private static function parseMapping($mapping, &$i = 0, $references = array()) + private static function parseMapping($mapping, $flags, &$i = 0, $references = array()) { $output = array(); $len = strlen($mapping); @@ -392,7 +457,15 @@ private static function parseMapping($mapping, &$i = 0, $references = array()) } // key - $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false); + $key = self::parseScalar($mapping, $flags, array(':', ' '), array('"', "'"), $i, false); + + if (':' !== $key && false === $i = strpos($mapping, ':', $i)) { + break; + } + + if (':' !== $key && (!isset($mapping[$i + 1]) || !in_array($mapping[$i + 1], array(' ', ',', '[', ']', '{', '}'), true))) { + @trigger_error('Using a colon that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}" is deprecated since version 3.2 and will throw a ParseException in 4.0.', E_USER_DEPRECATED); + } // value $done = false; @@ -401,23 +474,27 @@ private static function parseMapping($mapping, &$i = 0, $references = array()) switch ($mapping[$i]) { case '[': // nested sequence - $value = self::parseSequence($mapping, $i, $references); + $value = self::parseSequence($mapping, $flags, $i, $references); // Spec: Keys MUST be unique; first one wins. // Parser cannot abort this mapping earlier, since lines // are processed sequentially. if (!isset($output[$key])) { $output[$key] = $value; + } else { + @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); } $done = true; break; case '{': // nested mapping - $value = self::parseMapping($mapping, $i, $references); + $value = self::parseMapping($mapping, $flags, $i, $references); // Spec: Keys MUST be unique; first one wins. // Parser cannot abort this mapping earlier, since lines // are processed sequentially. if (!isset($output[$key])) { $output[$key] = $value; + } else { + @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); } $done = true; break; @@ -425,12 +502,14 @@ private static function parseMapping($mapping, &$i = 0, $references = array()) case ' ': break; default: - $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references); + $value = self::parseScalar($mapping, $flags, array(',', '}'), array('"', "'"), $i, true, $references); // Spec: Keys MUST be unique; first one wins. // Parser cannot abort this mapping earlier, since lines // are processed sequentially. if (!isset($output[$key])) { $output[$key] = $value; + } else { + @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); } $done = true; --$i; @@ -451,13 +530,14 @@ private static function parseMapping($mapping, &$i = 0, $references = array()) * Evaluates scalars and replaces magic values. * * @param string $scalar + * @param int $flags * @param array $references * - * @return string A YAML string + * @return mixed The evaluated YAML string * * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved */ - private static function evaluateScalar($scalar, $references = array()) + private static function evaluateScalar($scalar, $flags, $references = array()) { $scalar = trim($scalar); $scalarLower = strtolower($scalar); @@ -496,7 +576,7 @@ private static function evaluateScalar($scalar, $references = array()) case 0 === strpos($scalar, '!str'): return (string) substr($scalar, 5); case 0 === strpos($scalar, '! '): - return (int) self::parseScalar(substr($scalar, 2)); + return (int) self::parseScalar(substr($scalar, 2), $flags); case 0 === strpos($scalar, '!php/object:'): if (self::$objectSupport) { return unserialize(substr($scalar, 12)); @@ -509,6 +589,8 @@ private static function evaluateScalar($scalar, $references = array()) return; case 0 === strpos($scalar, '!!php/object:'): if (self::$objectSupport) { + @trigger_error('The !!php/object tag to indicate dumped PHP objects is deprecated since version 3.1 and will be removed in 4.0. Use the !php/object tag instead.', E_USER_DEPRECATED); + return unserialize(substr($scalar, 13)); } @@ -516,9 +598,25 @@ private static function evaluateScalar($scalar, $references = array()) throw new ParseException('Object support when parsing a YAML file has been disabled.'); } + return; + case 0 === strpos($scalar, '!php/const:'): + if (self::$constantSupport) { + if (defined($const = substr($scalar, 11))) { + return constant($const); + } + + throw new ParseException(sprintf('The constant "%s" is not defined.', $const)); + } + if (self::$exceptionOnInvalidType) { + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar)); + } + return; case 0 === strpos($scalar, '!!float '): return (float) substr($scalar, 8); + case Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar): + $scalar = str_replace('_', '', (string) $scalar); + // omitting the break / return as integers are handled in the next case case ctype_digit($scalar): $raw = $scalar; $cast = (int) $scalar; @@ -530,16 +628,30 @@ private static function evaluateScalar($scalar, $references = array()) return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw); case is_numeric($scalar): - case preg_match(self::getHexRegex(), $scalar): + case Parser::preg_match(self::getHexRegex(), $scalar): + $scalar = str_replace('_', '', $scalar); + return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar; case '.inf' === $scalarLower: case '.nan' === $scalarLower: return -log(0); case '-.inf' === $scalarLower: return log(0); - case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): - return (float) str_replace(',', '', $scalar); - case preg_match(self::getTimestampRegex(), $scalar): + case 0 === strpos($scalar, '!!binary '): + return self::evaluateBinaryScalar(substr($scalar, 9)); + case Parser::preg_match('/^(-|\+)?[0-9][0-9,]*(\.[0-9_]+)?$/', $scalar): + case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar): + if (false !== strpos($scalar, ',')) { + @trigger_error('Using the comma as a group separator for floats is deprecated since version 3.2 and will be removed in 4.0.', E_USER_DEPRECATED); + } + + return (float) str_replace(array(',', '_'), '', $scalar); + case Parser::preg_match(self::getTimestampRegex(), $scalar): + if (Yaml::PARSE_DATETIME & $flags) { + // When no timezone is provided in the parsed date, YAML spec says we must assume UTC. + return new \DateTime($scalar, new \DateTimeZone('UTC')); + } + $timeZone = date_default_timezone_get(); date_default_timezone_set('UTC'); $time = strtotime($scalar); @@ -552,6 +664,33 @@ private static function evaluateScalar($scalar, $references = array()) } } + /** + * @param string $scalar + * + * @return string + * + * @internal + */ + public static function evaluateBinaryScalar($scalar) + { + $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar)); + + if (0 !== (strlen($parsedBinaryData) % 4)) { + throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', strlen($parsedBinaryData))); + } + + if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) { + throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData)); + } + + return base64_decode($parsedBinaryData, true); + } + + private static function isBinaryString($value) + { + return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value); + } + /** * Gets a regex that matches a YAML date. * @@ -584,6 +723,6 @@ private static function getTimestampRegex() */ private static function getHexRegex() { - return '~^0x[0-9a-f]++$~i'; + return '~^0x[0-9a-f_]++$~i'; } } diff --git a/vendor/symfony/yaml/Parser.php b/vendor/symfony/yaml/Parser.php index 97db3af8..184c30a3 100644 --- a/vendor/symfony/yaml/Parser.php +++ b/vendor/symfony/yaml/Parser.php @@ -20,9 +20,8 @@ */ class Parser { + const TAG_PATTERN = '((?P![\w!.\/:-]+) +)?'; const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; - // BC - wrongly named - const FOLDED_SCALAR_PATTERN = self::BLOCK_SCALAR_HEADER_PATTERN; private $offset = 0; private $totalNumberOfLines; @@ -50,37 +49,95 @@ public function __construct($offset = 0, $totalNumberOfLines = null, array $skip /** * Parses a YAML string to a PHP value. * - * @param string $value A YAML string - * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param bool $objectSupport true if object support is enabled, false otherwise - * @param bool $objectForMap true if maps should return a stdClass instead of array() + * @param string $value A YAML string + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior * * @return mixed A PHP value * * @throws ParseException If the YAML is not valid */ - public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false) + public function parse($value, $flags = 0) { - if (!preg_match('//u', $value)) { + if (is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (func_num_args() >= 3) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); + + if (func_get_arg(2)) { + $flags |= Yaml::PARSE_OBJECT; + } + } + + if (func_num_args() >= 4) { + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); + + if (func_get_arg(3)) { + $flags |= Yaml::PARSE_OBJECT_FOR_MAP; + } + } + + if (false === preg_match('//u', $value)) { throw new ParseException('The YAML value does not appear to be valid UTF-8.'); } + + $this->refs = array(); + + $mbEncoding = null; + $e = null; + $data = null; + + if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('UTF-8'); + } + + try { + $data = $this->doParse($value, $flags); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if (null !== $mbEncoding) { + mb_internal_encoding($mbEncoding); + } + + $this->lines = array(); + $this->currentLine = ''; + $this->refs = array(); + $this->skippedLineNumbers = array(); + $this->locallySkippedLineNumbers = array(); + + if (null !== $e) { + throw $e; + } + + return $data; + } + + private function doParse($value, $flags) + { $this->currentLineNb = -1; $this->currentLine = ''; $value = $this->cleanup($value); $this->lines = explode("\n", $value); + $this->locallySkippedLineNumbers = array(); if (null === $this->totalNumberOfLines) { $this->totalNumberOfLines = count($this->lines); } - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('UTF-8'); - } - $data = array(); $context = null; $allowOverwrite = false; + while ($this->moveToNextLine()) { if ($this->isCurrentLineEmpty()) { continue; @@ -92,23 +149,23 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = } $isRef = $mergeNode = false; - if (preg_match('#^\-((?P\s+)(?P.+?))?\s*$#u', $this->currentLine, $values)) { + if (self::preg_match('#^\-((?P\s+)(?P.+))?$#u', rtrim($this->currentLine), $values)) { if ($context && 'mapping' == $context) { throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine); } $context = 'sequence'; - if (isset($values['value']) && preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { + if (isset($values['value']) && self::preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } // array if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap); + $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags); } else { if (isset($values['leadspaces']) - && preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\s*$#u', $values['value'], $matches) + && self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+))?$#u', rtrim($values['value']), $matches) ) { // this is a compact notation element, add to next block and parse $block = $values['value']; @@ -116,23 +173,27 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1); } - $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $exceptionOnInvalidType, $objectSupport, $objectForMap); + $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags); } else { - $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context); + $data[] = $this->parseValue($values['value'], $flags, $context); } } if ($isRef) { $this->refs[$isRef] = end($data); } - } elseif (preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) { + } elseif ( + self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P.+))?$#u', rtrim($this->currentLine), $values) + && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'"))) + ) { if ($context && 'sequence' == $context) { throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine); } $context = 'mapping'; // force correct settings - Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs); + Inline::parse(null, $flags, $this->refs); try { + Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); $key = Inline::parseScalar($values['key']); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); @@ -161,18 +222,14 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); } - foreach ($refValue as $key => $value) { - if (!isset($data[$key])) { - $data[$key] = $value; - } - } + $data += $refValue; // array union } else { if (isset($values['value']) && $values['value'] !== '') { $value = $values['value']; } else { $value = $this->getNextEmbedBlock(); } - $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $exceptionOnInvalidType, $objectSupport, $objectForMap); + $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags); if (!is_array($parsed)) { throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); @@ -187,23 +244,15 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem); } - foreach ($parsedItem as $key => $value) { - if (!isset($data[$key])) { - $data[$key] = $value; - } - } + $data += $parsedItem; // array union } } else { // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the // current mapping, unless the key already exists in it. - foreach ($parsed as $key => $value) { - if (!isset($data[$key])) { - $data[$key] = $value; - } - } + $data += $parsed; // array union } } - } elseif (isset($values['value']) && preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { + } elseif (isset($values['value']) && self::preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { $isRef = $matches['ref']; $values['value'] = $matches['value']; } @@ -218,21 +267,29 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = // But overwriting is allowed when a merge node is used in current block. if ($allowOverwrite || !isset($data[$key])) { $data[$key] = null; + } else { + @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); } } else { - $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap); + // remember the parsed line number here in case we need it to provide some contexts in error messages below + $realCurrentLineNbKey = $this->getRealCurrentLineNb(); + $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags); // Spec: Keys MUST be unique; first one wins. // But overwriting is allowed when a merge node is used in current block. if ($allowOverwrite || !isset($data[$key])) { $data[$key] = $value; + } else { + @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, $realCurrentLineNbKey + 1), E_USER_DEPRECATED); } } } else { - $value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context); + $value = $this->parseValue($values['value'], $flags, $context); // Spec: Keys MUST be unique; first one wins. // But overwriting is allowed when a merge node is used in current block. if ($allowOverwrite || !isset($data[$key])) { $data[$key] = $value; + } else { + @trigger_error(sprintf('Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); } } if ($isRef) { @@ -247,7 +304,8 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = // 1-liner optionally followed by newline(s) if (is_string($value) && $this->lines[0] === trim($value)) { try { - $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs); + Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); + $value = Inline::parse($this->lines[0], $flags, $this->refs); } catch (ParseException $e) { $e->setParsedLine($this->getRealCurrentLineNb() + 1); $e->setSnippet($this->currentLine); @@ -255,42 +313,14 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = throw $e; } - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - return $value; } - switch (preg_last_error()) { - case PREG_INTERNAL_ERROR: - $error = 'Internal PCRE error.'; - break; - case PREG_BACKTRACK_LIMIT_ERROR: - $error = 'pcre.backtrack_limit reached.'; - break; - case PREG_RECURSION_LIMIT_ERROR: - $error = 'pcre.recursion_limit reached.'; - break; - case PREG_BAD_UTF8_ERROR: - $error = 'Malformed UTF-8 data.'; - break; - case PREG_BAD_UTF8_OFFSET_ERROR: - $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; - break; - default: - $error = 'Unable to parse.'; - } - - throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine); + throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine); } } - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - if ($objectForMap && !is_object($data) && 'mapping' === $context) { + if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !is_object($data) && 'mapping' === $context) { $object = new \stdClass(); foreach ($data as $key => $value) { @@ -303,7 +333,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport = return empty($data) ? null : $data; } - private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap) + private function parseBlock($offset, $yaml, $flags) { $skippedLineNumbers = $this->skippedLineNumbers; @@ -318,7 +348,7 @@ private function parseBlock($offset, $yaml, $exceptionOnInvalidType, $objectSupp $parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers); $parser->refs = &$this->refs; - return $parser->parse($yaml, $exceptionOnInvalidType, $objectSupport, $objectForMap); + return $parser->doParse($yaml, $flags); } /** @@ -501,17 +531,15 @@ private function moveToPreviousLine() /** * Parses a YAML value. * - * @param string $value A YAML value - * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise - * @param bool $objectSupport True if object support is enabled, false otherwise - * @param bool $objectForMap true if maps should return a stdClass instead of array() - * @param string $context The parser context (either sequence or mapping) + * @param string $value A YAML value + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param string $context The parser context (either sequence or mapping) * * @return mixed A PHP value * * @throws ParseException When reference does not exist */ - private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context) + private function parseValue($value, $flags, $context) { if (0 === strpos($value, '*')) { if (false !== $pos = strpos($value, '#')) { @@ -527,20 +555,47 @@ private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $ob return $this->refs[$value]; } - if (preg_match('/^'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { + if (self::preg_match('/^'.self::TAG_PATTERN.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; - return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); + $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); + + if (isset($matches['tag']) && '!!binary' === $matches['tag']) { + return Inline::evaluateBinaryScalar($data); + } + + return $data; } try { - $parsedValue = Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs); + $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null; + + // do not take following lines into account when the current line is a quoted single line value + if (null !== $quotation && preg_match('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) { + return Inline::parse($value, $flags, $this->refs); + } + + while ($this->moveToNextLine()) { + // unquoted strings end before the first unindented line + if (null === $quotation && $this->getCurrentLineIndentation() === 0) { + $this->moveToPreviousLine(); + + break; + } + + $value .= ' '.trim($this->currentLine); + + // quoted string values end with a line that is terminated with the quotation character + if ('' !== $this->currentLine && substr($this->currentLine, -1) === $quotation) { + break; + } + } - if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { - @trigger_error(sprintf('Using a colon in the unquoted mapping value "%s" in line %d is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $value, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); + Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); + $parsedValue = Inline::parse($value, $flags, $this->refs); - // to be thrown in 3.0 - // throw new ParseException('A colon cannot be used in an unquoted mapping value.'); + if ('mapping' === $context && is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { + throw new ParseException('A colon cannot be used in an unquoted mapping value.'); } return $parsedValue; @@ -582,7 +637,7 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0) // determine indentation if not specified if (0 === $indentation) { - if (preg_match('/^ +/', $this->currentLine, $matches)) { + if (self::preg_match('/^ +/', $this->currentLine, $matches)) { $indentation = strlen($matches[0]); } } @@ -593,7 +648,7 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0) while ( $notEOF && ( $isCurrentLineBlank || - preg_match($pattern, $this->currentLine, $matches) + self::preg_match($pattern, $this->currentLine, $matches) ) ) { if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) { @@ -626,7 +681,7 @@ private function parseBlockScalar($style, $chomping = '', $indentation = 0) $previousLineIndented = false; $previousLineBlank = false; - for ($i = 0; $i < count($blockLines); ++$i) { + for ($i = 0, $blockLinesCount = count($blockLines); $i < $blockLinesCount; ++$i) { if ('' === $blockLines[$i]) { $text .= "\n"; $previousLineIndented = false; @@ -681,10 +736,7 @@ private function isNextLineIndented() return false; } - $ret = false; - if ($this->getCurrentLineIndentation() > $currentIndentation) { - $ret = true; - } + $ret = $this->getCurrentLineIndentation() > $currentIndentation; $this->moveToPreviousLine(); @@ -785,14 +837,7 @@ private function isNextLineUnIndentedCollection() return false; } - $ret = false; - if ( - $this->getCurrentLineIndentation() == $currentIndentation - && - $this->isStringUnIndentedCollectionItem() - ) { - $ret = true; - } + $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem(); $this->moveToPreviousLine(); @@ -816,6 +861,48 @@ private function isStringUnIndentedCollectionItem() */ private function isBlockScalarHeader() { - return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine); + return (bool) self::preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine); + } + + /** + * A local wrapper for `preg_match` which will throw a ParseException if there + * is an internal error in the PCRE engine. + * + * This avoids us needing to check for "false" every time PCRE is used + * in the YAML engine + * + * @throws ParseException on a PCRE internal error + * + * @see preg_last_error() + * + * @internal + */ + public static function preg_match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0) + { + if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) { + switch (preg_last_error()) { + case PREG_INTERNAL_ERROR: + $error = 'Internal PCRE error.'; + break; + case PREG_BACKTRACK_LIMIT_ERROR: + $error = 'pcre.backtrack_limit reached.'; + break; + case PREG_RECURSION_LIMIT_ERROR: + $error = 'pcre.recursion_limit reached.'; + break; + case PREG_BAD_UTF8_ERROR: + $error = 'Malformed UTF-8 data.'; + break; + case PREG_BAD_UTF8_OFFSET_ERROR: + $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; + break; + default: + $error = 'Error.'; + } + + throw new ParseException($error); + } + + return $ret; } } diff --git a/vendor/symfony/yaml/Unescaper.php b/vendor/symfony/yaml/Unescaper.php index 1e02cc9f..6e863e12 100644 --- a/vendor/symfony/yaml/Unescaper.php +++ b/vendor/symfony/yaml/Unescaper.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Yaml; +use Symfony\Component\Yaml\Exception\ParseException; + /** * Unescaper encapsulates unescaping rules for single and double-quoted * YAML strings. @@ -21,16 +23,6 @@ */ class Unescaper { - /** - * Parser and Inline assume UTF-8 encoding, so escaped Unicode characters - * must be converted to that encoding. - * - * @deprecated since version 2.5, to be removed in 3.0 - * - * @internal - */ - const ENCODING = 'UTF-8'; - /** * Regex fragment that matches an escaped character in a double quoted string. */ @@ -57,9 +49,8 @@ public function unescapeSingleQuotedString($value) */ public function unescapeDoubleQuotedString($value) { - $self = $this; - $callback = function ($match) use ($self) { - return $self->unescapeCharacter($match[0]); + $callback = function ($match) { + return $this->unescapeCharacter($match[0]); }; // evaluate the string @@ -72,11 +63,8 @@ public function unescapeDoubleQuotedString($value) * @param string $value An escaped character * * @return string The unescaped character - * - * @internal This method is public to be usable as callback. It should not - * be used in user code. Should be changed in 3.0. */ - public function unescapeCharacter($value) + private function unescapeCharacter($value) { switch ($value[1]) { case '0': @@ -126,9 +114,7 @@ public function unescapeCharacter($value) case 'U': return self::utf8chr(hexdec(substr($value, 2, 8))); default: - @trigger_error('Not escaping a backslash in a double-quoted string is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', E_USER_DEPRECATED); - - return $value; + throw new ParseException(sprintf('Found unknown escape character "%s".', $value)); } } diff --git a/vendor/symfony/yaml/Yaml.php b/vendor/symfony/yaml/Yaml.php index 6fc4e927..46e6ef5c 100644 --- a/vendor/symfony/yaml/Yaml.php +++ b/vendor/symfony/yaml/Yaml.php @@ -20,6 +20,16 @@ */ class Yaml { + const DUMP_OBJECT = 1; + const PARSE_EXCEPTION_ON_INVALID_TYPE = 2; + const PARSE_OBJECT = 4; + const PARSE_OBJECT_FOR_MAP = 8; + const DUMP_EXCEPTION_ON_INVALID_TYPE = 16; + const PARSE_DATETIME = 32; + const DUMP_OBJECT_AS_MAP = 64; + const DUMP_MULTI_LINE_LITERAL_BLOCK = 128; + const PARSE_CONSTANT = 256; + /** * Parses YAML into a PHP value. * @@ -29,47 +39,44 @@ class Yaml * print_r($array); * * - * As this method accepts both plain strings and file names as an input, - * you must validate the input before calling this method. Passing a file - * as an input is a deprecated feature and will be removed in 3.0. - * - * Note: the ability to pass file names to the Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead. - * - * @param string $input Path to a YAML file or a string containing YAML - * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise - * @param bool $objectSupport True if object support is enabled, false otherwise - * @param bool $objectForMap True if maps should return a stdClass instead of array() + * @param string $input A string containing YAML + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior * * @return mixed The YAML converted to a PHP value * * @throws ParseException If the YAML is not valid */ - public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false) + public static function parse($input, $flags = 0) { - // if input is a file, process it - $file = ''; - if (strpos($input, "\n") === false && is_file($input)) { - @trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED); + if (is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - if (false === is_readable($input)) { - throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input)); + if ($flags) { + $flags = self::PARSE_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; } - - $file = $input; - $input = file_get_contents($file); } - $yaml = new Parser(); + if (func_num_args() >= 3) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - try { - return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap); - } catch (ParseException $e) { - if ($file) { - $e->setParsedFile($file); + if (func_get_arg(2)) { + $flags |= self::PARSE_OBJECT; } + } + + if (func_num_args() >= 4) { + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - throw $e; + if (func_get_arg(3)) { + $flags |= self::PARSE_OBJECT_FOR_MAP; + } } + + $yaml = new Parser(); + + return $yaml->parse($input, $flags); } /** @@ -78,23 +85,35 @@ public static function parse($input, $exceptionOnInvalidType = false, $objectSup * The dump method, when supplied with an array, will do its best * to convert the array into friendly YAML. * - * @param mixed $input The PHP value - * @param int $inline The level where you switch to inline YAML - * @param int $indent The amount of spaces to use for indentation of nested nodes - * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise - * @param bool $objectSupport true if object support is enabled, false otherwise + * @param mixed $input The PHP value + * @param int $inline The level where you switch to inline YAML + * @param int $indent The amount of spaces to use for indentation of nested nodes + * @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string * * @return string A YAML string representing the original PHP value */ - public static function dump($input, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false) + public static function dump($input, $inline = 2, $indent = 4, $flags = 0) { - if ($indent < 1) { - throw new \InvalidArgumentException('The indentation must be greater than zero.'); + if (is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); + + if ($flags) { + $flags = self::DUMP_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (func_num_args() >= 5) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the DUMP_OBJECT flag instead.', E_USER_DEPRECATED); + + if (func_get_arg(4)) { + $flags |= self::DUMP_OBJECT; + } } - $yaml = new Dumper(); - $yaml->setIndentation($indent); + $yaml = new Dumper($indent); - return $yaml->dump($input, $inline, 0, $exceptionOnInvalidType, $objectSupport); + return $yaml->dump($input, $inline, 0, $flags); } } diff --git a/vendor/symfony/yaml/composer.json b/vendor/symfony/yaml/composer.json index af97f80f..9c92bebc 100644 --- a/vendor/symfony/yaml/composer.json +++ b/vendor/symfony/yaml/composer.json @@ -16,7 +16,13 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" }, @@ -27,7 +33,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "3.2-dev" } } } diff --git a/vendor/symfony/yaml/phpunit.xml.dist b/vendor/symfony/yaml/phpunit.xml.dist index 6bdbea16..7c732f8a 100644 --- a/vendor/symfony/yaml/phpunit.xml.dist +++ b/vendor/symfony/yaml/phpunit.xml.dist @@ -5,6 +5,8 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > diff --git a/vendor/twig/twig/.php_cs.dist b/vendor/twig/twig/.php_cs.dist new file mode 100644 index 00000000..cd75923a --- /dev/null +++ b/vendor/twig/twig/.php_cs.dist @@ -0,0 +1,15 @@ +setRules(array( + '@Symfony' => true, + '@Symfony:risky' => true, + 'array_syntax' => array('syntax' => 'long'), + 'php_unit_fqcn_annotation' => false, + 'no_unreachable_default_argument_value' => false, + 'braces' => array('allow_single_line_closure' => true), + 'heredoc_to_nowdoc' => false, + )) + ->setRiskyAllowed(true) + ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__)) +; diff --git a/vendor/twig/twig/.travis.yml b/vendor/twig/twig/.travis.yml index 37262da2..41b7510b 100644 --- a/vendor/twig/twig/.travis.yml +++ b/vendor/twig/twig/.travis.yml @@ -5,7 +5,7 @@ sudo: false cache: directories: - vendor - - $HOME/.composer/cache + - $HOME/.composer/cache/files php: - 5.2 @@ -14,12 +14,16 @@ php: - 5.5 - 5.6 - 7.0 + - 7.1 - hhvm env: - TWIG_EXT=no - TWIG_EXT=yes +before_install: + - if [[ ! $TRAVIS_PHP_VERSION = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi + install: # Composer is not available on PHP 5.2 - if [ ${TRAVIS_PHP_VERSION:0:3} != "5.2" ]; then travis_retry composer install; fi @@ -34,6 +38,7 @@ matrix: exclude: - php: hhvm env: TWIG_EXT=yes - allow_failures: - php: 7.0 env: TWIG_EXT=yes + - php: 7.1 + env: TWIG_EXT=yes diff --git a/vendor/twig/twig/CHANGELOG b/vendor/twig/twig/CHANGELOG index 85de10dd..0b630a16 100644 --- a/vendor/twig/twig/CHANGELOG +++ b/vendor/twig/twig/CHANGELOG @@ -1,3 +1,108 @@ +* 1.32.0 (2017-02-26) + + * fixed deprecation notice in Twig_Util_DeprecationCollector + * added a PSR-11 compatible runtime loader + * added `side` argument to `trim` to allow left or right trimming only. + +* 1.31.0 (2017-01-11) + + * added Twig_NodeCaptureInterface for nodes that capture all output + * fixed marking the environment as initialized too early + * fixed C89 compat for the C extension + * turned fatal error into exception when a previously generated cache is corrupted + * fixed offline cache warm-ups for embedded templates + +* 1.30.0 (2016-12-23) + + * added Twig_FactoryRuntimeLoader + * deprecated function/test/filter/tag overriding + * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr + +* 1.29.0 (2016-12-13) + + * fixed sandbox being left enabled if an exception is thrown while rendering + * marked some classes as being final (via @final) + * made Twig_Error report real source path when possible + * added support for {{ _self }} to provide an upgrade path from 1.x to 2.0 (replaces {{ _self.templateName }}) + * deprecated silent display of undefined blocks + * deprecated support for mbstring.func_overload != 0 + +* 1.28.2 (2016-11-23) + + * fixed precedence between getFoo() and isFoo() in Twig_Template::getAttribute() + * improved a deprecation message + +* 1.28.1 (2016-11-18) + + * fixed block() function when used with a template argument + +* 1.28.0 (2016-11-17) + + * added support for the PHP 7 null coalescing operator for the ?? Twig implementation + * exposed a way to access template data and methods in a portable way + * changed context access to use the PHP 7 null coalescing operator when available + * added the "with" tag + * added support for a custom template on the block() function + * added "is defined" support for block() and constant() + * optimized the way attributes are fetched + +* 1.27.0 (2016-10-25) + + * deprecated Twig_Parser::getEnvironment() + * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor() + * deprecated Twig_Compiler::addIndentation() + * fixed regression when registering two extensions having the same class name + * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead) + * fixed the filesystem loader with relative paths + * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine() + * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext() + * deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName() + * deprecated the "filename" escaping strategy (use "name" instead) + * added Twig_Source to hold information about the original template + * deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName() + * deprecated Parser::getFilename() + * fixed template paths when a template name contains a protocol like vfs:// + * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties + +* 1.26.1 (2016-10-05) + + * removed template source code from generated template classes when debug is disabled + * fixed default implementation of Twig_Template::getDebugInfo() for better BC + * fixed regression on static calls for functions/filters/tests + +* 1.26.0 (2016-10-02) + + * added template cache invalidation based on more environment options + * added a missing deprecation notice + * fixed template paths when a template is stored in a PHAR file + * allowed filters/functions/tests implementation to use a different class than the extension they belong to + * deprecated Twig_ExtensionInterface::getName() + +* 1.25.0 (2016-09-21) + + * changed the way we store template source in template classes + * removed usage of realpath in cache keys + * fixed Twig cache sharing when used with different versions of PHP + * removed embed parent workaround for simple use cases + * deprecated the ability to store non Node instances in Node::$nodes + * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler() + * deprecated Twig_Compiler::getFilename() + +* 1.24.2 (2016-09-01) + + * fixed static callables + * fixed a potential PHP warning when loading the cache + * fixed a case where the autoescaping does not work as expected + +* 1.24.1 (2016-05-30) + + * fixed reserved keywords (forbids true, false, null and none keywords for variables names) + * fixed support for PHP7 (Throwable support) + * marked the following methods as being internals on Twig_Environment: + getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(), + getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(), + getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension() + * 1.24.0 (2016-01-25) * adding support for the ?? operator diff --git a/vendor/twig/twig/LICENSE b/vendor/twig/twig/LICENSE index cc74f810..b6e17a1a 100644 --- a/vendor/twig/twig/LICENSE +++ b/vendor/twig/twig/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009-2016 by the Twig Team. +Copyright (c) 2009-2017 by the Twig Team. Some rights reserved. diff --git a/vendor/twig/twig/composer.json b/vendor/twig/twig/composer.json index 507d8aec..f53b91b3 100644 --- a/vendor/twig/twig/composer.json +++ b/vendor/twig/twig/composer.json @@ -30,8 +30,9 @@ "php": ">=5.2.7" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7", - "symfony/debug": "~2.7" + "symfony/phpunit-bridge": "~3.2", + "symfony/debug": "~2.7", + "psr/container": "^1.0" }, "autoload": { "psr-0" : { @@ -40,7 +41,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.24-dev" + "dev-master": "1.32-dev" } } } diff --git a/vendor/twig/twig/lib/Twig/Autoloader.php b/vendor/twig/twig/lib/Twig/Autoloader.php index 14016b29..212af544 100644 --- a/vendor/twig/twig/lib/Twig/Autoloader.php +++ b/vendor/twig/twig/lib/Twig/Autoloader.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,7 +23,7 @@ class Twig_Autoloader /** * Registers Twig_Autoloader as an SPL autoloader. * - * @param bool $prepend Whether to prepend the autoloader or not. + * @param bool $prepend whether to prepend the autoloader or not */ public static function register($prepend = false) { @@ -39,7 +39,7 @@ public static function register($prepend = false) /** * Handles autoloading of classes. * - * @param string $class A class name. + * @param string $class a class name */ public static function autoload($class) { diff --git a/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php b/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php index 3c6ef662..1c917d2f 100644 --- a/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php +++ b/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php @@ -16,9 +16,6 @@ */ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface { - /** - * {@inheritdoc} - */ final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) { if (!$node instanceof Twig_Node) { @@ -28,9 +25,6 @@ final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env) return $this->doEnterNode($node, $env); } - /** - * {@inheritdoc} - */ final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) { if (!$node instanceof Twig_Node) { @@ -43,9 +37,6 @@ final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env) /** * Called before child nodes are visited. * - * @param Twig_Node $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * * @return Twig_Node The modified node */ abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env); @@ -53,9 +44,6 @@ abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env); /** * Called after child nodes are visited. * - * @param Twig_Node $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * * @return Twig_Node|false The modified node or false if the node must be removed */ abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env); diff --git a/vendor/twig/twig/lib/Twig/Cache/Filesystem.php b/vendor/twig/twig/lib/Twig/Cache/Filesystem.php index bebc2bfa..de4e5072 100644 --- a/vendor/twig/twig/lib/Twig/Cache/Filesystem.php +++ b/vendor/twig/twig/lib/Twig/Cache/Filesystem.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -31,9 +31,6 @@ public function __construct($directory, $options = 0) $this->options = $options; } - /** - * {@inheritdoc} - */ public function generateKey($name, $className) { $hash = hash('sha256', $className); @@ -41,17 +38,13 @@ public function generateKey($name, $className) return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php'; } - /** - * {@inheritdoc} - */ public function load($key) { - @include_once $key; + if (file_exists($key)) { + @include_once $key; + } } - /** - * {@inheritdoc} - */ public function write($key, $content) { $dir = dirname($key); @@ -82,9 +75,6 @@ public function write($key, $content) throw new RuntimeException(sprintf('Failed to write cache file "%s".', $key)); } - /** - * {@inheritdoc} - */ public function getTimestamp($key) { if (!file_exists($key)) { diff --git a/vendor/twig/twig/lib/Twig/Cache/Null.php b/vendor/twig/twig/lib/Twig/Cache/Null.php index fde8c808..7a194950 100644 --- a/vendor/twig/twig/lib/Twig/Cache/Null.php +++ b/vendor/twig/twig/lib/Twig/Cache/Null.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,35 +12,25 @@ /** * Implements a no-cache strategy. * + * @final + * * @author Fabien Potencier */ class Twig_Cache_Null implements Twig_CacheInterface { - /** - * {@inheritdoc} - */ public function generateKey($name, $className) { return ''; } - /** - * {@inheritdoc} - */ public function write($key, $content) { } - /** - * {@inheritdoc} - */ public function load($key) { } - /** - * {@inheritdoc} - */ public function getTimestamp($key) { return 0; diff --git a/vendor/twig/twig/lib/Twig/CacheInterface.php b/vendor/twig/twig/lib/Twig/CacheInterface.php index 9b17e0f4..2a3f04dd 100644 --- a/vendor/twig/twig/lib/Twig/CacheInterface.php +++ b/vendor/twig/twig/lib/Twig/CacheInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Compiler.php b/vendor/twig/twig/lib/Twig/Compiler.php index abea3aaf..cdca49c5 100644 --- a/vendor/twig/twig/lib/Twig/Compiler.php +++ b/vendor/twig/twig/lib/Twig/Compiler.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,25 +26,25 @@ class Twig_Compiler implements Twig_CompilerInterface protected $sourceLine; protected $filename; - /** - * Constructor. - * - * @param Twig_Environment $env The twig environment instance - */ public function __construct(Twig_Environment $env) { $this->env = $env; } + /** + * @deprecated since 1.25 (to be removed in 2.0) + */ public function getFilename() { + @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); + return $this->filename; } /** * Returns the environment instance related to this compiler. * - * @return Twig_Environment The environment instance + * @return Twig_Environment */ public function getEnvironment() { @@ -67,7 +67,7 @@ public function getSource() * @param Twig_NodeInterface $node The node to compile * @param int $indentation The current indentation * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function compile(Twig_NodeInterface $node, $indentation = 0) { @@ -80,7 +80,8 @@ public function compile(Twig_NodeInterface $node, $indentation = 0) $this->indentation = $indentation; if ($node instanceof Twig_Node_Module) { - $this->filename = $node->getAttribute('filename'); + // to be removed in 2.0 + $this->filename = $node->getTemplateName(); } $node->compile($this); @@ -91,7 +92,7 @@ public function compile(Twig_NodeInterface $node, $indentation = 0) public function subcompile(Twig_NodeInterface $node, $raw = true) { if (false === $raw) { - $this->addIndentation(); + $this->source .= str_repeat(' ', $this->indentation * 4); } $node->compile($this); @@ -104,7 +105,7 @@ public function subcompile(Twig_NodeInterface $node, $raw = true) * * @param string $string The string * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function raw($string) { @@ -116,14 +117,13 @@ public function raw($string) /** * Writes a string to the compiled code by adding indentation. * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function write() { $strings = func_get_args(); foreach ($strings as $string) { - $this->addIndentation(); - $this->source .= $string; + $this->source .= str_repeat(' ', $this->indentation * 4).$string; } return $this; @@ -132,10 +132,14 @@ public function write() /** * Appends an indentation to the current PHP code after compilation. * - * @return Twig_Compiler The current compiler instance + * @return $this + * + * @deprecated since 1.27 (to be removed in 2.0). */ public function addIndentation() { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', E_USER_DEPRECATED); + $this->source .= str_repeat(' ', $this->indentation * 4); return $this; @@ -146,7 +150,7 @@ public function addIndentation() * * @param string $value The string * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function string($value) { @@ -160,7 +164,7 @@ public function string($value) * * @param mixed $value The value to convert * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function repr($value) { @@ -201,28 +205,28 @@ public function repr($value) /** * Adds debugging information. * - * @param Twig_NodeInterface $node The related twig node - * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function addDebugInfo(Twig_NodeInterface $node) { - if ($node->getLine() != $this->lastLine) { - $this->write(sprintf("// line %d\n", $node->getLine())); + if ($node->getTemplateLine() != $this->lastLine) { + $this->write(sprintf("// line %d\n", $node->getTemplateLine())); // when mbstring.func_overload is set to 2 // mb_substr_count() replaces substr_count() // but they have different signatures! if (((int) ini_get('mbstring.func_overload')) & 2) { + @trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED); + // this is much slower than the "right" version $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n"); } else { $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); } $this->sourceOffset = strlen($this->source); - $this->debugInfo[$this->sourceLine] = $node->getLine(); + $this->debugInfo[$this->sourceLine] = $node->getTemplateLine(); - $this->lastLine = $node->getLine(); + $this->lastLine = $node->getTemplateLine(); } return $this; @@ -240,7 +244,7 @@ public function getDebugInfo() * * @param int $step The number of indentation to add * - * @return Twig_Compiler The current compiler instance + * @return $this */ public function indent($step = 1) { @@ -254,7 +258,7 @@ public function indent($step = 1) * * @param int $step The number of indentation to remove * - * @return Twig_Compiler The current compiler instance + * @return $this * * @throws LogicException When trying to outdent too much so the indentation would become negative */ @@ -262,7 +266,7 @@ public function outdent($step = 1) { // can't outdent by more steps than the current indentation level if ($this->indentation < $step) { - throw new LogicException('Unable to call outdent() as the indentation would become negative'); + throw new LogicException('Unable to call outdent() as the indentation would become negative.'); } $this->indentation -= $step; diff --git a/vendor/twig/twig/lib/Twig/CompilerInterface.php b/vendor/twig/twig/lib/Twig/CompilerInterface.php index 272c7672..42872c9c 100644 --- a/vendor/twig/twig/lib/Twig/CompilerInterface.php +++ b/vendor/twig/twig/lib/Twig/CompilerInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,9 +21,7 @@ interface Twig_CompilerInterface /** * Compiles a node. * - * @param Twig_NodeInterface $node The node to compile - * - * @return Twig_CompilerInterface The current compiler instance + * @return $this */ public function compile(Twig_NodeInterface $node); diff --git a/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php b/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php new file mode 100644 index 00000000..3284569d --- /dev/null +++ b/vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php @@ -0,0 +1,37 @@ + + * @author Robin Chalas + */ +class Twig_ContainerRuntimeLoader implements Twig_RuntimeLoaderInterface +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function load($class) + { + if ($this->container->has($class)) { + return $this->container->get($class); + } + } +} diff --git a/vendor/twig/twig/lib/Twig/Environment.php b/vendor/twig/twig/lib/Twig/Environment.php index 4100ef58..c146858d 100644 --- a/vendor/twig/twig/lib/Twig/Environment.php +++ b/vendor/twig/twig/lib/Twig/Environment.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -16,7 +16,12 @@ */ class Twig_Environment { - const VERSION = '1.24.0'; + const VERSION = '1.32.0'; + const VERSION_ID = 13200; + const MAJOR_VERSION = 1; + const MINOR_VERSION = 32; + const RELEASE_VERSION = 0; + const EXTRA_VERSION = ''; protected $charset; protected $loader; @@ -49,6 +54,10 @@ class Twig_Environment private $bcWriteCacheFile = false; private $bcGetCacheFilename = false; private $lastModifiedExtension = 0; + private $extensionsByClass = array(); + private $runtimeLoaders = array(); + private $runtimes = array(); + private $optionsHash; /** * Constructor. @@ -78,14 +87,14 @@ class Twig_Environment * * false: disable auto-escaping * * true: equivalent to html * * html, js: set the autoescaping to one of the supported strategies - * * filename: set the autoescaping strategy based on the template filename extension - * * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename" + * * name: set the autoescaping strategy based on the template name extension + * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name" * * * optimizations: A flag that indicates which optimizations to apply * (default to -1 which means that all optimizations are enabled; * set it to 0 to disable). * - * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance + * @param Twig_LoaderInterface $loader * @param array $options An array of options */ public function __construct(Twig_LoaderInterface $loader = null, $options = array()) @@ -155,6 +164,7 @@ public function getBaseTemplateClass() public function setBaseTemplateClass($class) { $this->baseTemplateClass = $class; + $this->updateOptionsHash(); } /** @@ -163,6 +173,7 @@ public function setBaseTemplateClass($class) public function enableDebug() { $this->debug = true; + $this->updateOptionsHash(); } /** @@ -171,6 +182,7 @@ public function enableDebug() public function disableDebug() { $this->debug = false; + $this->updateOptionsHash(); } /** @@ -215,6 +227,7 @@ public function isAutoReload() public function enableStrictVariables() { $this->strictVariables = true; + $this->updateOptionsHash(); } /** @@ -223,6 +236,7 @@ public function enableStrictVariables() public function disableStrictVariables() { $this->strictVariables = false; + $this->updateOptionsHash(); } /** @@ -300,7 +314,10 @@ public function getCacheFilename($name) * * * The cache key for the given template; * * The currently enabled extensions; - * * Whether the Twig C extension is available or not. + * * Whether the Twig C extension is available or not; + * * PHP version; + * * Twig version; + * * Options with what environment was created. * * @param string $name The name for which to calculate the template class name * @param int|null $index The index if it is an embedded template @@ -309,9 +326,7 @@ public function getCacheFilename($name) */ public function getTemplateClass($name, $index = null) { - $key = $this->getLoader()->getCacheKey($name); - $key .= json_encode(array_keys($this->extensions)); - $key .= function_exists('twig_template_get_attributes'); + $key = $this->getLoader()->getCacheKey($name).$this->optionsHash; return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '_'.$index); } @@ -363,19 +378,48 @@ public function display($name, array $context = array()) } /** - * Loads a template by name. + * Loads a template. + * + * @param string|Twig_TemplateWrapper|Twig_Template $name The template name + * + * @return Twig_TemplateWrapper + */ + public function load($name) + { + if ($name instanceof Twig_TemplateWrapper) { + return $name; + } + + if ($name instanceof Twig_Template) { + return new Twig_TemplateWrapper($this, $name); + } + + return new Twig_TemplateWrapper($this, $this->loadTemplate($name)); + } + + /** + * Loads a template internal representation. + * + * This method is for internal use only and should never be called + * directly. * * @param string $name The template name * @param int $index The index if it is an embedded template * * @return Twig_TemplateInterface A template instance representing the given template name * - * @throws Twig_Error_Loader When the template cannot be found - * @throws Twig_Error_Syntax When an error occurred during compilation + * @throws Twig_Error_Loader When the template cannot be found + * @throws Twig_Error_Runtime When a previously generated cache is corrupted + * @throws Twig_Error_Syntax When an error occurred during compilation + * + * @internal */ public function loadTemplate($name, $index = null) { - $cls = $this->getTemplateClass($name, $index); + $cls = $mainCls = $this->getTemplateClass($name); + if (null !== $index) { + $cls .= '_'.$index; + } if (isset($this->loadedTemplates[$cls])) { return $this->loadedTemplates[$cls]; @@ -385,7 +429,7 @@ public function loadTemplate($name, $index = null) if ($this->bcGetCacheFilename) { $key = $this->getCacheFilename($name); } else { - $key = $this->cache->generateKey($name, $cls); + $key = $this->cache->generateKey($name, $mainCls); } if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) { @@ -393,14 +437,34 @@ public function loadTemplate($name, $index = null) } if (!class_exists($cls, false)) { - $content = $this->compileSource($this->getLoader()->getSource($name), $name); + $loader = $this->getLoader(); + if (!$loader instanceof Twig_SourceContextLoaderInterface) { + $source = new Twig_Source($loader->getSource($name), $name); + } else { + $source = $loader->getSourceContext($name); + } + + $content = $this->compileSource($source); + if ($this->bcWriteCacheFile) { $this->writeCacheFile($key, $content); } else { $this->cache->write($key, $content); + $this->cache->load($key); } - eval('?>'.$content); + if (!class_exists($mainCls, false)) { + /* Last line of defense if either $this->bcWriteCacheFile was used, + * $this->cache is implemented as a no-op or we have a race condition + * where the cache was cleared between the above calls to write to and load from + * the cache. + */ + eval('?>'.$content); + } + } + + if (!class_exists($cls, false)) { + throw new Twig_Error_Runtime(sprintf('Failed to load Twig template "%s", index "%s": cache is corrupted.', $name, $index), -1, $source); } } @@ -438,6 +502,10 @@ public function createTemplate($template) } catch (Exception $e) { $this->setLoader($current); + throw $e; + } catch (Throwable $e) { + $this->setLoader($current); + throw $e; } $this->setLoader($current); @@ -541,10 +609,14 @@ public function clearCacheFiles() /** * Gets the Lexer instance. * - * @return Twig_LexerInterface A Twig_LexerInterface instance + * @return Twig_LexerInterface + * + * @deprecated since 1.25 (to be removed in 2.0) */ public function getLexer() { + @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); + if (null === $this->lexer) { $this->lexer = new Twig_Lexer($this); } @@ -552,11 +624,6 @@ public function getLexer() return $this->lexer; } - /** - * Sets the Lexer instance. - * - * @param Twig_LexerInterface $lexer A Twig_LexerInterface instance - */ public function setLexer(Twig_LexerInterface $lexer) { $this->lexer = $lexer; @@ -565,25 +632,38 @@ public function setLexer(Twig_LexerInterface $lexer) /** * Tokenizes a source code. * - * @param string $source The template source code - * @param string $name The template name + * @param string|Twig_Source $source The template source code + * @param string $name The template name (deprecated) * - * @return Twig_TokenStream A Twig_TokenStream instance + * @return Twig_TokenStream * * @throws Twig_Error_Syntax When the code is syntactically wrong */ public function tokenize($source, $name = null) { - return $this->getLexer()->tokenize($source, $name); + if (!$source instanceof Twig_Source) { + @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); + $source = new Twig_Source($source, $name); + } + + if (null === $this->lexer) { + $this->lexer = new Twig_Lexer($this); + } + + return $this->lexer->tokenize($source); } /** * Gets the Parser instance. * - * @return Twig_ParserInterface A Twig_ParserInterface instance + * @return Twig_ParserInterface + * + * @deprecated since 1.25 (to be removed in 2.0) */ public function getParser() { + @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); + if (null === $this->parser) { $this->parser = new Twig_Parser($this); } @@ -591,11 +671,6 @@ public function getParser() return $this->parser; } - /** - * Sets the Parser instance. - * - * @param Twig_ParserInterface $parser A Twig_ParserInterface instance - */ public function setParser(Twig_ParserInterface $parser) { $this->parser = $parser; @@ -604,24 +679,30 @@ public function setParser(Twig_ParserInterface $parser) /** * Converts a token stream to a node tree. * - * @param Twig_TokenStream $stream A token stream instance - * - * @return Twig_Node_Module A node tree + * @return Twig_Node_Module * * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong */ public function parse(Twig_TokenStream $stream) { - return $this->getParser()->parse($stream); + if (null === $this->parser) { + $this->parser = new Twig_Parser($this); + } + + return $this->parser->parse($stream); } /** * Gets the Compiler instance. * - * @return Twig_CompilerInterface A Twig_CompilerInterface instance + * @return Twig_CompilerInterface + * + * @deprecated since 1.25 (to be removed in 2.0) */ public function getCompiler() { + @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED); + if (null === $this->compiler) { $this->compiler = new Twig_Compiler($this); } @@ -629,11 +710,6 @@ public function getCompiler() return $this->compiler; } - /** - * Sets the Compiler instance. - * - * @param Twig_CompilerInterface $compiler A Twig_CompilerInterface instance - */ public function setCompiler(Twig_CompilerInterface $compiler) { $this->compiler = $compiler; @@ -642,20 +718,22 @@ public function setCompiler(Twig_CompilerInterface $compiler) /** * Compiles a node and returns the PHP code. * - * @param Twig_NodeInterface $node A Twig_NodeInterface instance - * * @return string The compiled PHP source code */ public function compile(Twig_NodeInterface $node) { - return $this->getCompiler()->compile($node)->getSource(); + if (null === $this->compiler) { + $this->compiler = new Twig_Compiler($this); + } + + return $this->compiler->compile($node)->getSource(); } /** * Compiles a template source code. * - * @param string $source The template source code - * @param string $name The template name + * @param string|Twig_Source $source The template source code + * @param string $name The template name (deprecated) * * @return string The compiled PHP source code * @@ -663,36 +741,34 @@ public function compile(Twig_NodeInterface $node) */ public function compileSource($source, $name = null) { - try { - $compiled = $this->compile($this->parse($this->tokenize($source, $name)), $source); - - if (isset($source[0])) { - $compiled .= '/* '.str_replace(array('*/', "\r\n", "\r", "\n"), array('*//* ', "\n", "\n", "*/\n/* "), $source)."*/\n"; - } + if (!$source instanceof Twig_Source) { + @trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); + $source = new Twig_Source($source, $name); + } - return $compiled; + try { + return $this->compile($this->parse($this->tokenize($source))); } catch (Twig_Error $e) { - $e->setTemplateFile($name); + $e->setSourceContext($source); throw $e; } catch (Exception $e) { - throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e); + throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e); } } - /** - * Sets the Loader instance. - * - * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance - */ public function setLoader(Twig_LoaderInterface $loader) { + if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) { + @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED); + } + $this->loader = $loader; } /** * Gets the Loader instance. * - * @return Twig_LoaderInterface A Twig_LoaderInterface instance + * @return Twig_LoaderInterface */ public function getLoader() { @@ -748,51 +824,100 @@ public function initRuntime() /** * Returns true if the given extension is registered. * - * @param string $name The extension name + * @param string $class The extension class name * * @return bool Whether the extension is registered or not */ - public function hasExtension($name) + public function hasExtension($class) { - return isset($this->extensions[$name]); + $class = ltrim($class, '\\'); + if (isset($this->extensions[$class])) { + if ($class !== get_class($this->extensions[$class])) { + @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); + } + + return true; + } + + return isset($this->extensionsByClass[$class]); } /** - * Gets an extension by name. + * Adds a runtime loader. + */ + public function addRuntimeLoader(Twig_RuntimeLoaderInterface $loader) + { + $this->runtimeLoaders[] = $loader; + } + + /** + * Gets an extension by class name. * - * @param string $name The extension name + * @param string $class The extension class name * - * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance + * @return Twig_ExtensionInterface */ - public function getExtension($name) + public function getExtension($class) { - if (!isset($this->extensions[$name])) { - throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name)); + $class = ltrim($class, '\\'); + + if (isset($this->extensions[$class])) { + if ($class !== get_class($this->extensions[$class])) { + @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); + } + + return $this->extensions[$class]; } - return $this->extensions[$name]; + if (!isset($this->extensionsByClass[$class])) { + throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $class)); + } + + return $this->extensionsByClass[$class]; } /** - * Registers an extension. + * Returns the runtime implementation of a Twig element (filter/function/test). + * + * @param string $class A runtime class name + * + * @return object The runtime implementation * - * @param Twig_ExtensionInterface $extension A Twig_ExtensionInterface instance + * @throws Twig_Error_Runtime When the template cannot be found */ - public function addExtension(Twig_ExtensionInterface $extension) + public function getRuntime($class) { - $name = $extension->getName(); + if (isset($this->runtimes[$class])) { + return $this->runtimes[$class]; + } + + foreach ($this->runtimeLoaders as $loader) { + if (null !== $runtime = $loader->load($class)) { + return $this->runtimes[$class] = $runtime; + } + } + + throw new Twig_Error_Runtime(sprintf('Unable to load the "%s" runtime.', $class)); + } + public function addExtension(Twig_ExtensionInterface $extension) + { if ($this->extensionInitialized) { - throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $name)); + throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName())); } - if (isset($this->extensions[$name])) { - @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $name), E_USER_DEPRECATED); + $class = get_class($extension); + if ($class !== $extension->getName()) { + if (isset($this->extensions[$extension->getName()])) { + unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]); + @trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), E_USER_DEPRECATED); + } } $this->lastModifiedExtension = 0; - - $this->extensions[$name] = $extension; + $this->extensionsByClass[$class] = $extension; + $this->extensions[$extension->getName()] = $extension; + $this->updateOptionsHash(); } /** @@ -812,7 +937,17 @@ public function removeExtension($name) throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name)); } - unset($this->extensions[$name]); + $class = ltrim($name, '\\'); + if (isset($this->extensions[$class])) { + if ($class !== get_class($this->extensions[$class])) { + @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED); + } + + unset($this->extensions[$class]); + } + + unset($this->extensions[$class]); + $this->updateOptionsHash(); } /** @@ -830,18 +965,13 @@ public function setExtensions(array $extensions) /** * Returns all registered extensions. * - * @return array An array of extensions + * @return Twig_ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on) */ public function getExtensions() { return $this->extensions; } - /** - * Registers a Token Parser. - * - * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance - */ public function addTokenParser(Twig_TokenParserInterface $parser) { if ($this->extensionInitialized) { @@ -854,7 +984,9 @@ public function addTokenParser(Twig_TokenParserInterface $parser) /** * Gets the registered Token Parsers. * - * @return Twig_TokenParserBrokerInterface A broker containing token parsers + * @return Twig_TokenParserBrokerInterface + * + * @internal */ public function getTokenParsers() { @@ -870,7 +1002,9 @@ public function getTokenParsers() * * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes. * - * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances + * @return Twig_TokenParserInterface[] + * + * @internal */ public function getTags() { @@ -884,11 +1018,6 @@ public function getTags() return $tags; } - /** - * Registers a Node Visitor. - * - * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance - */ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { if ($this->extensionInitialized) { @@ -901,7 +1030,9 @@ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) /** * Gets the registered Node Visitors. * - * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances + * @return Twig_NodeVisitorInterface[] + * + * @internal */ public function getNodeVisitors() { @@ -916,12 +1047,12 @@ public function getNodeVisitors() * Registers a Filter. * * @param string|Twig_SimpleFilter $name The filter name or a Twig_SimpleFilter instance - * @param Twig_FilterInterface|Twig_SimpleFilter $filter A Twig_FilterInterface instance or a Twig_SimpleFilter instance + * @param Twig_FilterInterface|Twig_SimpleFilter $filter */ public function addFilter($name, $filter = null) { if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) { - throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter'); + throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter.'); } if ($name instanceof Twig_SimpleFilter) { @@ -947,6 +1078,8 @@ public function addFilter($name, $filter = null) * @param string $name The filter name * * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist + * + * @internal */ public function getFilter($name) { @@ -990,9 +1123,11 @@ public function registerUndefinedFilterCallback($callable) * * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback. * - * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances + * @return Twig_FilterInterface[] * * @see registerUndefinedFilterCallback + * + * @internal */ public function getFilters() { @@ -1012,7 +1147,7 @@ public function getFilters() public function addTest($name, $test = null) { if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) { - throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest'); + throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest.'); } if ($name instanceof Twig_SimpleTest) { @@ -1032,7 +1167,9 @@ public function addTest($name, $test = null) /** * Gets the registered Tests. * - * @return Twig_TestInterface[] An array of Twig_TestInterface instances + * @return Twig_TestInterface[] + * + * @internal */ public function getTests() { @@ -1049,6 +1186,8 @@ public function getTests() * @param string $name The test name * * @return Twig_Test|false A Twig_Test instance or false if the test does not exist + * + * @internal */ public function getTest($name) { @@ -1067,12 +1206,12 @@ public function getTest($name) * Registers a Function. * * @param string|Twig_SimpleFunction $name The function name or a Twig_SimpleFunction instance - * @param Twig_FunctionInterface|Twig_SimpleFunction $function A Twig_FunctionInterface instance or a Twig_SimpleFunction instance + * @param Twig_FunctionInterface|Twig_SimpleFunction $function */ public function addFunction($name, $function = null) { if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) { - throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction'); + throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction.'); } if ($name instanceof Twig_SimpleFunction) { @@ -1098,6 +1237,8 @@ public function addFunction($name, $function = null) * @param string $name function name * * @return Twig_Function|false A Twig_Function instance or false if the function does not exist + * + * @internal */ public function getFunction($name) { @@ -1141,9 +1282,11 @@ public function registerUndefinedFunctionCallback($callable) * * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback. * - * @return Twig_FunctionInterface[] An array of Twig_FunctionInterface instances + * @return Twig_FunctionInterface[] * * @see registerUndefinedFunctionCallback + * + * @internal */ public function getFunctions() { @@ -1189,6 +1332,8 @@ public function addGlobal($name, $value) * Gets the registered Globals. * * @return array An array of globals + * + * @internal */ public function getGlobals() { @@ -1227,6 +1372,8 @@ public function mergeGlobals(array $context) * Gets the registered unary Operators. * * @return array An array of unary operators + * + * @internal */ public function getUnaryOperators() { @@ -1241,6 +1388,8 @@ public function getUnaryOperators() * Gets the registered binary Operators. * * @return array An array of binary operators + * + * @internal */ public function getBinaryOperators() { @@ -1261,6 +1410,9 @@ public function computeAlternatives($name, $items) return Twig_Error_Syntax::computeAlternatives($name, $items); } + /** + * @internal + */ protected function initGlobals() { $globals = array(); @@ -1286,13 +1438,15 @@ protected function initGlobals() return call_user_func_array('array_merge', $globals); } + /** + * @internal + */ protected function initExtensions() { if ($this->extensionInitialized) { return; } - $this->extensionInitialized = true; $this->parsers = new Twig_TokenParserBroker(array(), array(), false); $this->filters = array(); $this->functions = array(); @@ -1305,8 +1459,13 @@ protected function initExtensions() $this->initExtension($extension); } $this->initExtension($this->staging); + // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception + $this->extensionInitialized = true; } + /** + * @internal + */ protected function initExtension(Twig_ExtensionInterface $extension) { // filters @@ -1351,7 +1510,7 @@ protected function initExtension(Twig_ExtensionInterface $extension) $this->parsers->addTokenParserBroker($parser); } else { - throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); + throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances.'); } } @@ -1362,8 +1521,12 @@ protected function initExtension(Twig_ExtensionInterface $extension) // operators if ($operators = $extension->getOperators()) { + if (!is_array($operators)) { + throw new InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', get_class($extension), is_object($operators) ? get_class($operators) : gettype($operators).(is_resource($operators) ? '' : '#'.$operators))); + } + if (2 !== count($operators)) { - throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); + throw new InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', get_class($extension), count($operators))); } $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]); @@ -1378,4 +1541,21 @@ protected function writeCacheFile($file, $content) { $this->cache->write($file, $content); } + + private function updateOptionsHash() + { + $hashParts = array_merge( + array_keys($this->extensions), + array( + (int) function_exists('twig_template_get_attributes'), + PHP_MAJOR_VERSION, + PHP_MINOR_VERSION, + self::VERSION, + (int) $this->debug, + $this->baseTemplateClass, + (int) $this->strictVariables, + ) + ); + $this->optionsHash = implode(':', $hashParts); + } } diff --git a/vendor/twig/twig/lib/Twig/Error.php b/vendor/twig/twig/lib/Twig/Error.php index 37c74352..358a03b9 100644 --- a/vendor/twig/twig/lib/Twig/Error.php +++ b/vendor/twig/twig/lib/Twig/Error.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -25,8 +25,8 @@ * and line number) yourself by passing them to the constructor. If some or all * these information are not available from where you throw the exception, then * this class will guess them automatically (when the line number is set to -1 - * and/or the filename is set to null). As this is a costly operation, this - * can be disabled by passing false for both the filename and the line number + * and/or the name is set to null). As this is a costly operation, this + * can be disabled by passing false for both the name and the line number * when creating a new instance of this class. * * @author Fabien Potencier @@ -34,29 +34,43 @@ class Twig_Error extends Exception { protected $lineno; + // to be renamed to name in 2.0 protected $filename; protected $rawMessage; protected $previous; + private $sourcePath; + private $sourceCode; + /** * Constructor. * - * Set both the line number and the filename to false to + * Set both the line number and the name to false to * disable automatic guessing of the original template name * and line number. * * Set the line number to -1 to enable its automatic guessing. - * Set the filename to null to enable its automatic guessing. + * Set the name to null to enable its automatic guessing. * * By default, automatic guessing is enabled. * - * @param string $message The error message - * @param int $lineno The template line where the error occurred - * @param string $filename The template file name where the error occurred - * @param Exception $previous The previous exception + * @param string $message The error message + * @param int $lineno The template line where the error occurred + * @param Twig_Source|string|null $source The source context where the error occurred + * @param Exception $previous The previous exception */ - public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) + public function __construct($message, $lineno = -1, $source = null, Exception $previous = null) { + if (null === $source) { + $name = null; + } elseif (!$source instanceof Twig_Source) { + // for compat with the Twig C ext., passing the template name as string is accepted + $name = $source; + } else { + $name = $source->getName(); + $this->sourceCode = $source->getCode(); + $this->sourcePath = $source->getPath(); + } if (PHP_VERSION_ID < 50300) { $this->previous = $previous; parent::__construct(''); @@ -65,9 +79,9 @@ public function __construct($message, $lineno = -1, $filename = null, Exception } $this->lineno = $lineno; - $this->filename = $filename; + $this->filename = $name; - if (-1 === $this->lineno || null === $this->filename) { + if (-1 === $lineno || null === $name || null === $this->sourcePath) { $this->guessTemplateInfo(); } @@ -87,23 +101,62 @@ public function getRawMessage() } /** - * Gets the filename where the error occurred. + * Gets the logical name where the error occurred. * - * @return string The filename + * @return string The name + * + * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead. */ public function getTemplateFile() { + @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED); + return $this->filename; } /** - * Sets the filename where the error occurred. + * Sets the logical name where the error occurred. + * + * @param string $name The name * - * @param string $filename The filename + * @deprecated since 1.27 (to be removed in 2.0). Use setSourceContext() instead. */ - public function setTemplateFile($filename) + public function setTemplateFile($name) { - $this->filename = $filename; + @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), E_USER_DEPRECATED); + + $this->filename = $name; + + $this->updateRepr(); + } + + /** + * Gets the logical name where the error occurred. + * + * @return string The name + * + * @deprecated since 1.29 (to be removed in 2.0). Use getSourceContext() instead. + */ + public function getTemplateName() + { + @trigger_error(sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->filename; + } + + /** + * Sets the logical name where the error occurred. + * + * @param string $name The name + * + * @deprecated since 1.29 (to be removed in 2.0). Use setSourceContext() instead. + */ + public function setTemplateName($name) + { + @trigger_error(sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), E_USER_DEPRECATED); + + $this->filename = $name; + $this->sourceCode = $this->sourcePath = null; $this->updateRepr(); } @@ -130,6 +183,32 @@ public function setTemplateLine($lineno) $this->updateRepr(); } + /** + * Gets the source context of the Twig template where the error occurred. + * + * @return Twig_Source|null + */ + public function getSourceContext() + { + return $this->filename ? new Twig_Source($this->sourceCode, $this->filename, $this->sourcePath) : null; + } + + /** + * Sets the source context of the Twig template where the error occurred. + */ + public function setSourceContext(Twig_Source $source = null) + { + if (null === $source) { + $this->sourceCode = $this->filename = $this->sourcePath = null; + } else { + $this->sourceCode = $source->getCode(); + $this->filename = $source->getName(); + $this->sourcePath = $source->getPath(); + } + + $this->updateRepr(); + } + public function guess() { $this->guessTemplateInfo(); @@ -168,6 +247,13 @@ protected function updateRepr() { $this->message = $this->rawMessage; + if ($this->sourcePath && $this->lineno > 0) { + $this->file = $this->sourcePath; + $this->line = $this->lineno; + + return; + } + $dot = false; if ('.' === substr($this->message, -1)) { $this->message = substr($this->message, 0, -1); @@ -182,11 +268,11 @@ protected function updateRepr() if ($this->filename) { if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) { - $filename = sprintf('"%s"', $this->filename); + $name = sprintf('"%s"', $this->filename); } else { - $filename = json_encode($this->filename); + $name = json_encode($this->filename); } - $this->message .= sprintf(' in %s', $filename); + $this->message .= sprintf(' in %s', $name); } if ($this->lineno && $this->lineno >= 0) { @@ -227,11 +313,18 @@ protected function guessTemplateInfo() } } - // update template filename + // update template name if (null !== $template && null === $this->filename) { $this->filename = $template->getTemplateName(); } + // update template path if any + if (null !== $template && null === $this->sourcePath) { + $src = $template->getSourceContext(); + $this->sourceCode = $src->getCode(); + $this->sourcePath = $src->getPath(); + } + if (null === $template || $this->lineno > -1) { return; } diff --git a/vendor/twig/twig/lib/Twig/Error/Loader.php b/vendor/twig/twig/lib/Twig/Error/Loader.php index 68efb574..68297201 100644 --- a/vendor/twig/twig/lib/Twig/Error/Loader.php +++ b/vendor/twig/twig/lib/Twig/Error/Loader.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,8 +24,15 @@ */ class Twig_Error_Loader extends Twig_Error { - public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) + public function __construct($message, $lineno = -1, $source = null, Exception $previous = null) { - parent::__construct($message, false, false, $previous); + if (PHP_VERSION_ID < 50300) { + $this->previous = $previous; + Exception::__construct(''); + } else { + Exception::__construct('', 0, $previous); + } + $this->appendMessage($message); + $this->setTemplateLine(false); } } diff --git a/vendor/twig/twig/lib/Twig/Error/Runtime.php b/vendor/twig/twig/lib/Twig/Error/Runtime.php index 8b6ceddb..c4e41b1d 100644 --- a/vendor/twig/twig/lib/Twig/Error/Runtime.php +++ b/vendor/twig/twig/lib/Twig/Error/Runtime.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Error/Syntax.php b/vendor/twig/twig/lib/Twig/Error/Syntax.php index f73730a1..bded07e5 100644 --- a/vendor/twig/twig/lib/Twig/Error/Syntax.php +++ b/vendor/twig/twig/lib/Twig/Error/Syntax.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php index b168c3c3..553fb4e5 100644 --- a/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php +++ b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/ExpressionParser.php b/vendor/twig/twig/lib/Twig/ExpressionParser.php index 7b2d58f2..517ad14c 100644 --- a/vendor/twig/twig/lib/Twig/ExpressionParser.php +++ b/vendor/twig/twig/lib/Twig/ExpressionParser.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,6 +19,8 @@ * @see http://en.wikipedia.org/wiki/Operator-precedence_parser * * @author Fabien Potencier + * + * @internal */ class Twig_ExpressionParser { @@ -29,11 +31,23 @@ class Twig_ExpressionParser protected $unaryOperators; protected $binaryOperators; - public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators) + private $env; + + public function __construct(Twig_Parser $parser, $env = null) { $this->parser = $parser; - $this->unaryOperators = $unaryOperators; - $this->binaryOperators = $binaryOperators; + + if ($env instanceof Twig_Environment) { + $this->env = $env; + $this->unaryOperators = $env->getUnaryOperators(); + $this->binaryOperators = $env->getBinaryOperators(); + } else { + @trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED); + + $this->env = $parser->getEnvironment(); + $this->unaryOperators = func_get_arg(1); + $this->binaryOperators = func_get_arg(2); + } } public function parseExpression($precedence = 0) @@ -44,7 +58,11 @@ public function parseExpression($precedence = 0) $op = $this->binaryOperators[$token->getValue()]; $this->parser->getStream()->next(); - if (isset($op['callable'])) { + if ('is not' === $token->getValue()) { + $expr = $this->parseNotTestExpression($expr); + } elseif ('is' === $token->getValue()) { + $expr = $this->parseTestExpression($expr); + } elseif (isset($op['callable'])) { $expr = call_user_func($op['callable'], $this->parser, $expr); } else { $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']); @@ -171,7 +189,7 @@ public function parsePrimaryExpression() $negClass = 'Twig_Node_Expression_Unary_Neg'; $posClass = 'Twig_Node_Expression_Unary_Pos'; if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) { - throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()); } $this->parser->getStream()->next(); @@ -187,7 +205,7 @@ public function parsePrimaryExpression() } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) { $node = $this->parseHashExpression(); } else { - throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()); } } @@ -216,7 +234,7 @@ public function parseStringExpression() $expr = array_shift($nodes); foreach ($nodes as $node) { - $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine()); + $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getTemplateLine()); } return $expr; @@ -278,7 +296,7 @@ public function parseHashExpression() } else { $current = $stream->getCurrent(); - throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext()); } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); @@ -317,20 +335,25 @@ public function getFunctionNode($name, $line) case 'parent': $this->parseArguments(); if (!count($this->parser->getBlockStack())) { - throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getFilename()); + throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext()); } if (!$this->parser->getParent() && !$this->parser->hasTraits()) { - throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getFilename()); + throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext()); } return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line); case 'block': - return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line); + $args = $this->parseArguments(); + if (count($args) < 1) { + throw new Twig_Error_Syntax('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext()); + } + + return new Twig_Node_Expression_BlockReference($args->getNode(0), count($args) > 1 ? $args->getNode(1) : null, $line); case 'attribute': $args = $this->parseArguments(); if (count($args) < 2) { - throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getFilename()); + throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext()); } return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line); @@ -379,18 +402,18 @@ public function parseSubscriptExpression($node) } } } else { - throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); + throw new Twig_Error_Syntax('Expected name or number.', $lineno, $stream->getSourceContext()); } if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { if (!$arg instanceof Twig_Node_Expression_Constant) { - throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext()); } $name = $arg->getAttribute('value'); if ($this->parser->isReservedMacroName($name)) { - throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()); } $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno); @@ -500,7 +523,7 @@ public function parseArguments($namedArguments = false, $definition = false) $name = null; if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) { if (!$value instanceof Twig_Node_Expression_Name) { - throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $stream->getSourceContext()); } $name = $value->getAttribute('name'); @@ -508,7 +531,7 @@ public function parseArguments($namedArguments = false, $definition = false) $value = $this->parsePrimaryExpression(); if (!$this->checkConstantExpression($value)) { - throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext()); } } else { $value = $this->parseExpression(); @@ -536,15 +559,17 @@ public function parseArguments($namedArguments = false, $definition = false) public function parseAssignmentExpression() { + $stream = $this->parser->getStream(); $targets = array(); while (true) { - $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to'); - if (in_array($token->getValue(), array('true', 'false', 'none'))) { - throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $token->getValue()), $token->getLine(), $this->parser->getFilename()); + $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to'); + $value = $token->getValue(); + if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) { + throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext()); } - $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine()); + $targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine()); - if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { + if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) { break; } } @@ -565,13 +590,80 @@ public function parseMultitargetExpression() return new Twig_Node($targets); } - protected function getFunctionNodeClass($name, $line) + private function parseNotTestExpression(Twig_NodeInterface $node) { - $env = $this->parser->getEnvironment(); + return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine()); + } + + private function parseTestExpression(Twig_NodeInterface $node) + { + $stream = $this->parser->getStream(); + list($name, $test) = $this->getTest($node->getTemplateLine()); + + $class = $this->getTestNodeClass($test); + $arguments = null; + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { + $arguments = $this->parser->getExpressionParser()->parseArguments(true); + } - if (false === $function = $env->getFunction($name)) { - $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getFilename()); - $e->addSuggestions($name, array_keys($env->getFunctions())); + return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine()); + } + + private function getTest($line) + { + $stream = $this->parser->getStream(); + $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); + + if ($test = $this->env->getTest($name)) { + return array($name, $test); + } + + if ($stream->test(Twig_Token::NAME_TYPE)) { + // try 2-words tests + $name = $name.' '.$this->parser->getCurrentToken()->getValue(); + + if ($test = $this->env->getTest($name)) { + $stream->next(); + + return array($name, $test); + } + } + + $e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext()); + $e->addSuggestions($name, array_keys($this->env->getTests())); + + throw $e; + } + + private function getTestNodeClass($test) + { + if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) { + $stream = $this->parser->getStream(); + $message = sprintf('Twig Test "%s" is deprecated', $test->getName()); + if (!is_bool($test->getDeprecatedVersion())) { + $message .= sprintf(' since version %s', $test->getDeprecatedVersion()); + } + if ($test->getAlternative()) { + $message .= sprintf('. Use "%s" instead', $test->getAlternative()); + } + $src = $stream->getSourceContext(); + $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine()); + + @trigger_error($message, E_USER_DEPRECATED); + } + + if ($test instanceof Twig_SimpleTest) { + return $test->getNodeClass(); + } + + return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test'; + } + + protected function getFunctionNodeClass($name, $line) + { + if (false === $function = $this->env->getFunction($name)) { + $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext()); + $e->addSuggestions($name, array_keys($this->env->getFunctions())); throw $e; } @@ -584,7 +676,8 @@ protected function getFunctionNodeClass($name, $line) if ($function->getAlternative()) { $message .= sprintf('. Use "%s" instead', $function->getAlternative()); } - $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line); + $src = $this->parser->getStream()->getSourceContext(); + $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line); @trigger_error($message, E_USER_DEPRECATED); } @@ -598,11 +691,9 @@ protected function getFunctionNodeClass($name, $line) protected function getFilterNodeClass($name, $line) { - $env = $this->parser->getEnvironment(); - - if (false === $filter = $env->getFilter($name)) { - $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getFilename()); - $e->addSuggestions($name, array_keys($env->getFilters())); + if (false === $filter = $this->env->getFilter($name)) { + $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext()); + $e->addSuggestions($name, array_keys($this->env->getFilters())); throw $e; } @@ -615,7 +706,8 @@ protected function getFilterNodeClass($name, $line) if ($filter->getAlternative()) { $message .= sprintf('. Use "%s" instead', $filter->getAlternative()); } - $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line); + $src = $this->parser->getStream()->getSourceContext(); + $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line); @trigger_error($message, E_USER_DEPRECATED); } diff --git a/vendor/twig/twig/lib/Twig/Extension.php b/vendor/twig/twig/lib/Twig/Extension.php index cb03b3de..5d72634a 100644 --- a/vendor/twig/twig/lib/Twig/Extension.php +++ b/vendor/twig/twig/lib/Twig/Extension.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,69 +11,55 @@ abstract class Twig_Extension implements Twig_ExtensionInterface { /** - * {@inheritdoc} - * * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead */ public function initRuntime(Twig_Environment $environment) { } - /** - * {@inheritdoc} - */ public function getTokenParsers() { return array(); } - /** - * {@inheritdoc} - */ public function getNodeVisitors() { return array(); } - /** - * {@inheritdoc} - */ public function getFilters() { return array(); } - /** - * {@inheritdoc} - */ public function getTests() { return array(); } - /** - * {@inheritdoc} - */ public function getFunctions() { return array(); } - /** - * {@inheritdoc} - */ public function getOperators() { return array(); } /** - * {@inheritdoc} - * * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead */ public function getGlobals() { return array(); } + + /** + * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally + */ + public function getName() + { + return get_class($this); + } } diff --git a/vendor/twig/twig/lib/Twig/Extension/Core.php b/vendor/twig/twig/lib/Twig/Extension/Core.php index 79ef5210..22824a88 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Core.php +++ b/vendor/twig/twig/lib/Twig/Extension/Core.php @@ -8,11 +8,15 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +/** + * @final + */ class Twig_Extension_Core extends Twig_Extension { protected $dateFormats = array('F j, Y H:i', '%d days'); @@ -95,9 +99,9 @@ public function getTimezone() /** * Sets the default format to be used by the number_format filter. * - * @param int $decimal The number of decimal places to use. - * @param string $decimalPoint The character(s) to use for the decimal point. - * @param string $thousandSep The character(s) to use for the thousands separator. + * @param int $decimal the number of decimal places to use + * @param string $decimalPoint the character(s) to use for the decimal point + * @param string $thousandSep the character(s) to use for the thousands separator */ public function setNumberFormat($decimal, $decimalPoint, $thousandSep) { @@ -132,6 +136,7 @@ public function getTokenParsers() new Twig_TokenParser_Flush(), new Twig_TokenParser_Do(), new Twig_TokenParser_Embed(), + new Twig_TokenParser_With(), ); } @@ -158,7 +163,7 @@ public function getFilters() new Twig_SimpleFilter('upper', 'strtoupper'), new Twig_SimpleFilter('lower', 'strtolower'), new Twig_SimpleFilter('striptags', 'strip_tags'), - new Twig_SimpleFilter('trim', 'trim'), + new Twig_SimpleFilter('trim', 'twig_trim_filter'), new Twig_SimpleFilter('nl2br', 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), // array helpers @@ -258,82 +263,14 @@ public function getOperators() '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'is' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'is not' => array('precedence' => 100, 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT), '??' => array('precedence' => 300, 'class' => 'Twig_Node_Expression_NullCoalesce', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT), ), ); } - public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node) - { - return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine()); - } - - public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node) - { - $stream = $parser->getStream(); - list($name, $test) = $this->getTest($parser, $node->getLine()); - - if ($test instanceof Twig_SimpleTest && $test->isDeprecated()) { - $message = sprintf('Twig Test "%s" is deprecated', $name); - if (!is_bool($test->getDeprecatedVersion())) { - $message .= sprintf(' since version %s', $test->getDeprecatedVersion()); - } - if ($test->getAlternative()) { - $message .= sprintf('. Use "%s" instead', $test->getAlternative()); - } - $message .= sprintf(' in %s at line %d.', $stream->getFilename(), $stream->getCurrent()->getLine()); - - @trigger_error($message, E_USER_DEPRECATED); - } - - $class = $this->getTestNodeClass($parser, $test); - $arguments = null; - if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { - $arguments = $parser->getExpressionParser()->parseArguments(true); - } - - return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); - } - - protected function getTest(Twig_Parser $parser, $line) - { - $stream = $parser->getStream(); - $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); - $env = $parser->getEnvironment(); - - if ($test = $env->getTest($name)) { - return array($name, $test); - } - - if ($stream->test(Twig_Token::NAME_TYPE)) { - // try 2-words tests - $name = $name.' '.$parser->getCurrentToken()->getValue(); - - if ($test = $env->getTest($name)) { - $parser->getStream()->next(); - - return array($name, $test); - } - } - - $e = new Twig_Error_Syntax(sprintf('Unknown "%s" test.', $name), $line, $parser->getFilename()); - $e->addSuggestions($name, array_keys($env->getTests())); - - throw $e; - } - - protected function getTestNodeClass(Twig_Parser $parser, $test) - { - if ($test instanceof Twig_SimpleTest) { - return $test->getNodeClass(); - } - - return $test instanceof Twig_Test_Node ? $test->getClass() : 'Twig_Node_Expression_Test'; - } - public function getName() { return 'core'; @@ -343,7 +280,7 @@ public function getName() /** * Cycles over a value. * - * @param ArrayAccess|array $values An array or an ArrayAccess instance + * @param ArrayAccess|array $values * @param int $position The cycle position * * @return string The next value in the cycle @@ -363,10 +300,10 @@ function twig_cycle($values, $position) * - a random character from a string * - a random integer between 0 and the integer parameter. * - * @param Twig_Environment $env A Twig_Environment instance - * @param Traversable|array|int|string $values The values to pick a random item from + * @param Twig_Environment $env + * @param Traversable|array|int|float|string $values The values to pick a random item from * - * @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is). + * @throws Twig_Error_Runtime when $values is an empty array (does not apply to an empty string which is returned as is) * * @return mixed A random value from the given sequence */ @@ -423,7 +360,7 @@ function twig_random(Twig_Environment $env, $values = null) * {{ post.published_at|date("m/d/Y") }} * * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param DateTime|DateTimeInterface|DateInterval|string $date A date * @param string|null $format The target format, null to use the default * @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged @@ -433,7 +370,7 @@ function twig_random(Twig_Environment $env, $values = null) function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null) { if (null === $format) { - $formats = $env->getExtension('core')->getDateFormat(); + $formats = $env->getExtension('Twig_Extension_Core')->getDateFormat(); $format = $date instanceof DateInterval ? $formats[1] : $formats[0]; } @@ -451,7 +388,7 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $ * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }} * * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param DateTime|string $date A date * @param string $modifier A modifier string * @@ -477,7 +414,7 @@ function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) * {% endif %} * * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param DateTime|DateTimeInterface|string|null $date A date * @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged * @@ -488,7 +425,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu // determine the timezone if (false !== $timezone) { if (null === $timezone) { - $timezone = $env->getExtension('core')->getTimezone(); + $timezone = $env->getExtension('Twig_Extension_Core')->getTimezone(); } elseif (!$timezone instanceof DateTimeZone) { $timezone = new DateTimeZone($timezone); } @@ -509,14 +446,14 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu } if (null === $date || 'now' === $date) { - return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('core')->getTimezone()); + return new DateTime($date, false !== $timezone ? $timezone : $env->getExtension('Twig_Extension_Core')->getTimezone()); } $asString = (string) $date; if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) { $date = new DateTime('@'.$date); } else { - $date = new DateTime($date, $env->getExtension('core')->getTimezone()); + $date = new DateTime($date, $env->getExtension('Twig_Extension_Core')->getTimezone()); } if (false !== $timezone) { @@ -544,7 +481,7 @@ function twig_replace_filter($str, $from, $to = null) return strtr($str, $from, $to); } elseif (!is_array($from)) { - throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".',is_object($from) ? get_class($from) : gettype($from))); + throw new Twig_Error_Runtime(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', is_object($from) ? get_class($from) : gettype($from))); } return strtr($str, $from); @@ -579,17 +516,17 @@ function twig_round($value, $precision = 0, $method = 'common') * be used. Supplying any of the parameters will override the defaults set in the * environment object. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param mixed $number A float/int/string of the number to format - * @param int $decimal The number of decimal points to display. - * @param string $decimalPoint The character(s) to use for the decimal point. - * @param string $thousandSep The character(s) to use for the thousands separator. + * @param int $decimal the number of decimal points to display + * @param string $decimalPoint the character(s) to use for the decimal point + * @param string $thousandSep the character(s) to use for the thousands separator * * @return string The formatted number */ function twig_number_format_filter(Twig_Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null) { - $defaults = $env->getExtension('core')->getNumberFormat(); + $defaults = $env->getExtension('Twig_Extension_Core')->getNumberFormat(); if (null === $decimal) { $decimal = $defaults[0]; } @@ -629,7 +566,7 @@ function twig_urlencode_filter($url) /** * JSON encodes a variable. * - * @param mixed $value The value to encode. + * @param mixed $value the value to encode * @param int $options Not used on PHP 5.2.x * * @return mixed The JSON encoded value @@ -648,7 +585,7 @@ function twig_jsonencode_filter($value, $options = 0) /** * JSON encodes a variable. * - * @param mixed $value The value to encode. + * @param mixed $value the value to encode * @param int $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT * * @return mixed The JSON encoded value @@ -708,7 +645,7 @@ function twig_array_merge($arr1, $arr2) /** * Slices a variable. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param mixed $item A variable * @param int $start Start of the slice * @param int $length Size of the slice @@ -719,7 +656,7 @@ function twig_array_merge($arr1, $arr2) function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false) { if ($item instanceof Traversable) { - if ($item instanceof IteratorAggregate) { + while ($item instanceof IteratorAggregate) { $item = $item->getIterator(); } @@ -750,7 +687,7 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese /** * Returns the first element of the item. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param mixed $item A variable * * @return mixed The first element of the item @@ -765,7 +702,7 @@ function twig_first(Twig_Environment $env, $item) /** * Returns the last element of the item. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param mixed $item A variable * * @return mixed The last element of the item @@ -821,7 +758,7 @@ function twig_join_filter($value, $glue = '') * {# returns [aa, bb, cc] #} * * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $value A string * @param string $delimiter The delimiter * @param int $limit The limit @@ -888,7 +825,27 @@ function _twig_default_filter($value, $default = '') function twig_get_array_keys_filter($array) { if ($array instanceof Traversable) { - return array_keys(iterator_to_array($array)); + while ($array instanceof IteratorAggregate) { + $array = $array->getIterator(); + } + + if ($array instanceof Iterator) { + $keys = array(); + $array->rewind(); + while ($array->valid()) { + $keys[] = $array->key(); + $array->next(); + } + + return $keys; + } + + $keys = array(); + foreach ($array as $key => $item) { + $keys[] = $key; + } + + return $keys; } if (!is_array($array)) { @@ -901,7 +858,7 @@ function twig_get_array_keys_filter($array) /** * Reverses a variable. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param array|Traversable|string $item An array, a Traversable instance, or a string * @param bool $preserveKeys Whether to preserve key or not * @@ -968,17 +925,56 @@ function twig_in_filter($value, $compare) } elseif (is_string($compare) && (is_string($value) || is_int($value) || is_float($value))) { return '' === $value || false !== strpos($compare, (string) $value); } elseif ($compare instanceof Traversable) { - return in_array($value, iterator_to_array($compare, false), is_object($value) || is_resource($value)); + if (is_object($value) || is_resource($value)) { + foreach ($compare as $item) { + if ($item === $value) { + return true; + } + } + } else { + foreach ($compare as $item) { + if ($item == $value) { + return true; + } + } + } + + return false; } return false; } +/** + * Returns a trimmed string. + * + * @return string + * + * @throws Twig_Error_Runtime When an invalid trimming side is used (not a string or not 'left', 'right', or 'both') + */ +function twig_trim_filter($string, $characterMask = null, $side = 'both') +{ + if (null === $characterMask) { + $characterMask = " \t\n\r\0\x0B"; + } + + switch ($side) { + case 'both': + return trim($string, $characterMask); + case 'left': + return ltrim($string, $characterMask); + case 'right': + return rtrim($string, $characterMask); + default: + throw new Twig_Error_Runtime('Trimming side must be "left", "right" or "both".'); + } +} + /** * Escapes a string. * - * @param Twig_Environment $env A Twig_Environment instance - * @param string $string The value to be escaped + * @param Twig_Environment $env + * @param mixed $string The value to be escaped * @param string $strategy The escaping strategy * @param string $charset The charset * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) @@ -1058,7 +1054,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $string = twig_convert_encoding($string, 'UTF-8', $charset); } - if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { + if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } @@ -1075,7 +1071,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $string = twig_convert_encoding($string, 'UTF-8', $charset); } - if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { + if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } @@ -1092,7 +1088,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $string = twig_convert_encoding($string, 'UTF-8', $charset); } - if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { + if (0 == strlen($string) ? false : 1 !== preg_match('/^./su', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } @@ -1115,7 +1111,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', static $escapers; if (null === $escapers) { - $escapers = $env->getExtension('core')->getEscapers(); + $escapers = $env->getExtension('Twig_Extension_Core')->getEscapers(); } if (isset($escapers[$strategy])) { @@ -1256,7 +1252,7 @@ function _twig_escape_html_attr_callback($matches) /** * Returns the length of a variable. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param mixed $thing A variable * * @return int The length of the value @@ -1269,7 +1265,7 @@ function twig_length_filter(Twig_Environment $env, $thing) /** * Converts a string to uppercase. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $string A string * * @return string The uppercased string @@ -1286,7 +1282,7 @@ function twig_upper_filter(Twig_Environment $env, $string) /** * Converts a string to lowercase. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $string A string * * @return string The lowercased string @@ -1303,7 +1299,7 @@ function twig_lower_filter(Twig_Environment $env, $string) /** * Returns a titlecased string. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $string A string * * @return string The titlecased string @@ -1320,7 +1316,7 @@ function twig_title_string_filter(Twig_Environment $env, $string) /** * Returns a capitalized string. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $string A string * * @return string The capitalized string @@ -1339,7 +1335,7 @@ function twig_capitalize_string_filter(Twig_Environment $env, $string) /** * Returns the length of a variable. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param mixed $thing A variable * * @return int The length of the value @@ -1352,7 +1348,7 @@ function twig_length_filter(Twig_Environment $env, $thing) /** * Returns a titlecased string. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $string A string * * @return string The titlecased string @@ -1365,7 +1361,7 @@ function twig_title_string_filter(Twig_Environment $env, $string) /** * Returns a capitalized string. * - * @param Twig_Environment $env A Twig_Environment instance + * @param Twig_Environment $env * @param string $string A string * * @return string The capitalized string @@ -1451,8 +1447,8 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a $variables = array_merge($context, $variables); } - if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) { - $sandbox = $env->getExtension('sandbox'); + if ($isSandboxed = $sandboxed && $env->hasExtension('Twig_Extension_Sandbox')) { + $sandbox = $env->getExtension('Twig_Extension_Sandbox'); if (!$alreadySandboxed = $sandbox->isSandboxed()) { $sandbox->enableSandbox(); } @@ -1469,6 +1465,18 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a throw $e; } + } catch (Throwable $e) { + if ($isSandboxed && !$alreadySandboxed) { + $sandbox->disableSandbox(); + } + + throw $e; + } catch (Exception $e) { + if ($isSandboxed && !$alreadySandboxed) { + $sandbox->disableSandbox(); + } + + throw $e; } if ($isSandboxed && !$alreadySandboxed) { @@ -1489,8 +1497,13 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a */ function twig_source(Twig_Environment $env, $name, $ignoreMissing = false) { + $loader = $env->getLoader(); try { - return $env->getLoader()->getSource($name); + if (!$loader instanceof Twig_SourceContextLoaderInterface) { + return $loader->getSource($name); + } else { + return $loader->getSourceContext($name)->getCode(); + } } catch (Twig_Error_Loader $e) { if (!$ignoreMissing) { throw $e; @@ -1515,6 +1528,23 @@ function twig_constant($constant, $object = null) return constant($constant); } +/** + * Checks if a constant exists. + * + * @param string $constant The name of the constant + * @param null|object $object The object to get the constant from + * + * @return bool + */ +function twig_constant_is_defined($constant, $object = null) +{ + if (null !== $object) { + $constant = get_class($object).'::'.$constant; + } + + return defined($constant); +} + /** * Batches item. * diff --git a/vendor/twig/twig/lib/Twig/Extension/Debug.php b/vendor/twig/twig/lib/Twig/Extension/Debug.php index 42fdb1e3..d22a3855 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Debug.php +++ b/vendor/twig/twig/lib/Twig/Extension/Debug.php @@ -3,11 +3,15 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +/** + * @final + */ class Twig_Extension_Debug extends Twig_Extension { public function getFunctions() diff --git a/vendor/twig/twig/lib/Twig/Extension/Escaper.php b/vendor/twig/twig/lib/Twig/Extension/Escaper.php index 0be721d5..118b6b36 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Escaper.php +++ b/vendor/twig/twig/lib/Twig/Extension/Escaper.php @@ -3,18 +3,20 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +/** + * @final + */ class Twig_Extension_Escaper extends Twig_Extension { protected $defaultStrategy; /** - * Constructor. - * * @param string|false|callable $defaultStrategy An escaping strategy * * @see setDefaultStrategy() @@ -45,7 +47,7 @@ public function getFilters() * Sets the default strategy to use when not defined by the user. * * The strategy can be a valid PHP callback that takes the template - * "filename" as an argument and returns the strategy to use. + * name as an argument and returns the strategy to use. * * @param string|false|callable $defaultStrategy An escaping strategy */ @@ -59,6 +61,12 @@ public function setDefaultStrategy($defaultStrategy) } if ('filename' === $defaultStrategy) { + @trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', E_USER_DEPRECATED); + + $defaultStrategy = 'name'; + } + + if ('name' === $defaultStrategy) { $defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess'); } @@ -68,16 +76,16 @@ public function setDefaultStrategy($defaultStrategy) /** * Gets the default strategy to use when not defined by the user. * - * @param string $filename The template "filename" + * @param string $name The template name * * @return string|false The default strategy to use for the template */ - public function getDefaultStrategy($filename) + public function getDefaultStrategy($name) { // disable string callables to avoid calling a function named html or js, // or any other upcoming escaping strategy if (!is_string($this->defaultStrategy) && false !== $this->defaultStrategy) { - return call_user_func($this->defaultStrategy, $filename); + return call_user_func($this->defaultStrategy, $name); } return $this->defaultStrategy; diff --git a/vendor/twig/twig/lib/Twig/Extension/Optimizer.php b/vendor/twig/twig/lib/Twig/Extension/Optimizer.php index 5a64a1a4..e100f0b5 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Optimizer.php +++ b/vendor/twig/twig/lib/Twig/Extension/Optimizer.php @@ -3,11 +3,15 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +/** + * @final + */ class Twig_Extension_Optimizer extends Twig_Extension { protected $optimizers; diff --git a/vendor/twig/twig/lib/Twig/Extension/Profiler.php b/vendor/twig/twig/lib/Twig/Extension/Profiler.php index 4d9f97f8..1d874ef8 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Profiler.php +++ b/vendor/twig/twig/lib/Twig/Extension/Profiler.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -36,7 +36,7 @@ public function leave(Twig_Profiler_Profile $profile) public function getNodeVisitors() { - return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName())); + return array(new Twig_Profiler_NodeVisitor_Profiler(get_class($this))); } public function getName() diff --git a/vendor/twig/twig/lib/Twig/Extension/Sandbox.php b/vendor/twig/twig/lib/Twig/Extension/Sandbox.php index 760d1238..1469a1e0 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/Extension/Sandbox.php @@ -3,11 +3,15 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +/** + * @final + */ class Twig_Extension_Sandbox extends Twig_Extension { protected $sandboxedGlobally; diff --git a/vendor/twig/twig/lib/Twig/Extension/Staging.php b/vendor/twig/twig/lib/Twig/Extension/Staging.php index d21004d0..34b71d27 100644 --- a/vendor/twig/twig/lib/Twig/Extension/Staging.php +++ b/vendor/twig/twig/lib/Twig/Extension/Staging.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -29,6 +29,10 @@ class Twig_Extension_Staging extends Twig_Extension public function addFunction($name, $function) { + if (isset($this->functions[$name])) { + @trigger_error(sprintf('Overriding function "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), E_USER_DEPRECATED); + } + $this->functions[$name] = $function; } @@ -39,6 +43,10 @@ public function getFunctions() public function addFilter($name, $filter) { + if (isset($this->filters[$name])) { + @trigger_error(sprintf('Overriding filter "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), E_USER_DEPRECATED); + } + $this->filters[$name] = $filter; } @@ -59,7 +67,11 @@ public function getNodeVisitors() public function addTokenParser(Twig_TokenParserInterface $parser) { - $this->tokenParsers[] = $parser; + if (isset($this->tokenParsers[$parser->getTag()])) { + @trigger_error(sprintf('Overriding tag "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $parser->getTag()), E_USER_DEPRECATED); + } + + $this->tokenParsers[$parser->getTag()] = $parser; } public function getTokenParsers() @@ -79,6 +91,10 @@ public function getGlobals() public function addTest($name, $test) { + if (isset($this->tests[$name])) { + @trigger_error(sprintf('Overriding test "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), E_USER_DEPRECATED); + } + $this->tests[$name] = $test; } diff --git a/vendor/twig/twig/lib/Twig/Extension/StringLoader.php b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php index 2a3ddb6a..c4151739 100644 --- a/vendor/twig/twig/lib/Twig/Extension/StringLoader.php +++ b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php @@ -3,11 +3,15 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +/** + * @final + */ class Twig_Extension_StringLoader extends Twig_Extension { public function getFunctions() @@ -33,7 +37,7 @@ public function getName() * @param Twig_Environment $env A Twig_Environment instance * @param string $template A template as a string or object implementing __toString() * - * @return Twig_Template A Twig_Template instance + * @return Twig_Template */ function twig_template_from_string(Twig_Environment $env, $template) { diff --git a/vendor/twig/twig/lib/Twig/ExtensionInterface.php b/vendor/twig/twig/lib/Twig/ExtensionInterface.php index 776ffeba..c5214bd5 100644 --- a/vendor/twig/twig/lib/Twig/ExtensionInterface.php +++ b/vendor/twig/twig/lib/Twig/ExtensionInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,8 +21,6 @@ interface Twig_ExtensionInterface * * This is where you can load some file that contains filter functions for instance. * - * @param Twig_Environment $environment The current Twig_Environment instance - * * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead */ public function initRuntime(Twig_Environment $environment); @@ -37,7 +35,7 @@ public function getTokenParsers(); /** * Returns the node visitor instances to add to the existing list. * - * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances + * @return Twig_NodeVisitorInterface[] */ public function getNodeVisitors(); @@ -65,7 +63,7 @@ public function getFunctions(); /** * Returns a list of operators to add to the existing list. * - * @return array An array of operators + * @return array First array of unary operators, second array of binary operators */ public function getOperators(); @@ -82,6 +80,8 @@ public function getGlobals(); * Returns the name of the extension. * * @return string The extension name + * + * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally */ public function getName(); } diff --git a/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php b/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php new file mode 100644 index 00000000..f428047c --- /dev/null +++ b/vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php @@ -0,0 +1,37 @@ + + */ +class Twig_FactoryRuntimeLoader implements Twig_RuntimeLoaderInterface +{ + private $map; + + /** + * @param array $map An array where keys are class names and values factory callables + */ + public function __construct($map = array()) + { + $this->map = $map; + } + + public function load($class) + { + if (isset($this->map[$class])) { + $runtimeFactory = $this->map[$class]; + + return $runtimeFactory(); + } + } +} diff --git a/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php b/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php index 9bda0b4f..47183726 100644 --- a/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +++ b/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,7 +13,7 @@ * Default autoescaping strategy based on file names. * * This strategy sets the HTML as the default autoescaping strategy, - * but changes it based on the filename. + * but changes it based on the template name. * * Note that there is no runtime performance impact as the * default autoescaping strategy is set at compilation time. @@ -25,21 +25,21 @@ class Twig_FileExtensionEscapingStrategy /** * Guesses the best autoescaping strategy based on the file name. * - * @param string $filename The template file name + * @param string $name The template name * * @return string|false The escaping strategy name to use or false to disable */ - public static function guess($filename) + public static function guess($name) { - if (in_array(substr($filename, -1), array('/', '\\'))) { + if (in_array(substr($name, -1), array('/', '\\'))) { return 'html'; // return html for directories } - if ('.twig' === substr($filename, -5)) { - $filename = substr($filename, 0, -5); + if ('.twig' === substr($name, -5)) { + $name = substr($name, 0, -5); } - $extension = pathinfo($filename, PATHINFO_EXTENSION); + $extension = pathinfo($name, PATHINFO_EXTENSION); switch ($extension) { case 'js': diff --git a/vendor/twig/twig/lib/Twig/Filter.php b/vendor/twig/twig/lib/Twig/Filter.php index 101d2e79..893d75d1 100644 --- a/vendor/twig/twig/lib/Twig/Filter.php +++ b/vendor/twig/twig/lib/Twig/Filter.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Filter/Function.php b/vendor/twig/twig/lib/Twig/Filter/Function.php index d679cab2..71b16554 100644 --- a/vendor/twig/twig/lib/Twig/Filter/Function.php +++ b/vendor/twig/twig/lib/Twig/Filter/Function.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Filter/Method.php b/vendor/twig/twig/lib/Twig/Filter/Method.php index 655aab40..1b75676c 100644 --- a/vendor/twig/twig/lib/Twig/Filter/Method.php +++ b/vendor/twig/twig/lib/Twig/Filter/Method.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -37,6 +37,6 @@ public function __construct(Twig_ExtensionInterface $extension, $method, array $ public function compile() { - return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method); + return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method); } } diff --git a/vendor/twig/twig/lib/Twig/Filter/Node.php b/vendor/twig/twig/lib/Twig/Filter/Node.php index a922f503..3e6b12ef 100644 --- a/vendor/twig/twig/lib/Twig/Filter/Node.php +++ b/vendor/twig/twig/lib/Twig/Filter/Node.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/FilterCallableInterface.php b/vendor/twig/twig/lib/Twig/FilterCallableInterface.php index 56798613..21b028c4 100644 --- a/vendor/twig/twig/lib/Twig/FilterCallableInterface.php +++ b/vendor/twig/twig/lib/Twig/FilterCallableInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/FilterInterface.php b/vendor/twig/twig/lib/Twig/FilterInterface.php index 6b0be0e3..9d7e9ab6 100644 --- a/vendor/twig/twig/lib/Twig/FilterInterface.php +++ b/vendor/twig/twig/lib/Twig/FilterInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Function.php b/vendor/twig/twig/lib/Twig/Function.php index 9fc76a8b..9dc16e90 100644 --- a/vendor/twig/twig/lib/Twig/Function.php +++ b/vendor/twig/twig/lib/Twig/Function.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Function/Function.php b/vendor/twig/twig/lib/Twig/Function/Function.php index ae83e153..97c0eb77 100644 --- a/vendor/twig/twig/lib/Twig/Function/Function.php +++ b/vendor/twig/twig/lib/Twig/Function/Function.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2010 Arnaud Le Blanc + * (c) Fabien Potencier + * (c) Arnaud Le Blanc * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Function/Method.php b/vendor/twig/twig/lib/Twig/Function/Method.php index ba9945ed..4299e118 100644 --- a/vendor/twig/twig/lib/Twig/Function/Method.php +++ b/vendor/twig/twig/lib/Twig/Function/Method.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2010 Arnaud Le Blanc + * (c) Fabien Potencier + * (c) Arnaud Le Blanc * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -38,6 +38,6 @@ public function __construct(Twig_ExtensionInterface $extension, $method, array $ public function compile() { - return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method); + return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method); } } diff --git a/vendor/twig/twig/lib/Twig/Function/Node.php b/vendor/twig/twig/lib/Twig/Function/Node.php index 118b0bab..0adc5d93 100644 --- a/vendor/twig/twig/lib/Twig/Function/Node.php +++ b/vendor/twig/twig/lib/Twig/Function/Node.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php b/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php index 87d795eb..d23d6917 100644 --- a/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php +++ b/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/FunctionInterface.php b/vendor/twig/twig/lib/Twig/FunctionInterface.php index f4492344..00d4f95c 100644 --- a/vendor/twig/twig/lib/Twig/FunctionInterface.php +++ b/vendor/twig/twig/lib/Twig/FunctionInterface.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier - * (c) 2010 Arnaud Le Blanc + * (c) Fabien Potencier + * (c) Arnaud Le Blanc * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Lexer.php b/vendor/twig/twig/lib/Twig/Lexer.php index dd798738..834b54fb 100644 --- a/vendor/twig/twig/lib/Twig/Lexer.php +++ b/vendor/twig/twig/lib/Twig/Lexer.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,6 +26,7 @@ class Twig_Lexer implements Twig_LexerInterface protected $states; protected $brackets; protected $env; + // to be renamed to $name in 2.0 (where it is private) protected $filename; protected $options; protected $regexes; @@ -33,6 +34,8 @@ class Twig_Lexer implements Twig_LexerInterface protected $positions; protected $currentVarBlockLine; + private $source; + const STATE_DATA = 0; const STATE_BLOCK = 1; const STATE_VAR = 2; @@ -72,11 +75,19 @@ public function __construct(Twig_Environment $env, array $options = array()) ); } - /** - * {@inheritdoc} - */ - public function tokenize($code, $filename = null) + public function tokenize($code, $name = null) { + if (!$code instanceof Twig_Source) { + @trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); + $this->source = new Twig_Source($code, $name); + } else { + $this->source = $code; + } + + if (((int) ini_get('mbstring.func_overload')) & 2) { + @trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED); + } + if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) { $mbEncoding = mb_internal_encoding(); mb_internal_encoding('ASCII'); @@ -84,8 +95,8 @@ public function tokenize($code, $filename = null) $mbEncoding = null; } - $this->code = str_replace(array("\r\n", "\r"), "\n", $code); - $this->filename = $filename; + $this->code = str_replace(array("\r\n", "\r"), "\n", $this->source->getCode()); + $this->filename = $this->source->getName(); $this->cursor = 0; $this->lineno = 1; $this->end = strlen($this->code); @@ -129,14 +140,14 @@ public function tokenize($code, $filename = null) if (!empty($this->brackets)) { list($expect, $lineno) = array_pop($this->brackets); - throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source); } if ($mbEncoding) { mb_internal_encoding($mbEncoding); } - return new Twig_TokenStream($this->tokens, $this->filename); + return new Twig_TokenStream($this->tokens, $this->source); } protected function lexData() @@ -224,7 +235,7 @@ protected function lexExpression() $this->moveCursor($match[0]); if ($this->cursor >= $this->end) { - throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source); } } @@ -256,12 +267,12 @@ protected function lexExpression() // closing bracket elseif (false !== strpos(')]}', $this->code[$this->cursor])) { if (empty($this->brackets)) { - throw new Twig_Error_Syntax(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source); } list($expect, $lineno) = array_pop($this->brackets); if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) { - throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source); } } @@ -281,7 +292,7 @@ protected function lexExpression() } // unlexable else { - throw new Twig_Error_Syntax(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source); } } @@ -292,7 +303,7 @@ protected function lexRawData($tag) } if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { - throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source); } $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor); @@ -308,7 +319,7 @@ protected function lexRawData($tag) protected function lexComment() { if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) { - throw new Twig_Error_Syntax('Unclosed comment.', $this->lineno, $this->filename); + throw new Twig_Error_Syntax('Unclosed comment.', $this->lineno, $this->source); } $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]); @@ -327,7 +338,7 @@ protected function lexString() } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) { list($expect, $lineno) = array_pop($this->brackets); if ($this->code[$this->cursor] != '"') { - throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->filename); + throw new Twig_Error_Syntax(sprintf('Unclosed "%s".', $expect), $lineno, $this->source); } $this->popState(); @@ -403,7 +414,7 @@ protected function pushState($state) protected function popState() { if (0 === count($this->states)) { - throw new Exception('Cannot pop state without a previous state'); + throw new Exception('Cannot pop state without a previous state.'); } $this->state = array_pop($this->states); diff --git a/vendor/twig/twig/lib/Twig/LexerInterface.php b/vendor/twig/twig/lib/Twig/LexerInterface.php index 24a94787..c10bbfec 100644 --- a/vendor/twig/twig/lib/Twig/LexerInterface.php +++ b/vendor/twig/twig/lib/Twig/LexerInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,12 +21,12 @@ interface Twig_LexerInterface /** * Tokenizes a source code. * - * @param string $code The source code - * @param string $filename A unique identifier for the source code + * @param string|Twig_Source $code The source code + * @param string $name A unique identifier for the source code * - * @return Twig_TokenStream A token stream instance + * @return Twig_TokenStream * * @throws Twig_Error_Syntax When the code is syntactically wrong */ - public function tokenize($code, $filename = null); + public function tokenize($code, $name = null); } diff --git a/vendor/twig/twig/lib/Twig/Loader/Array.php b/vendor/twig/twig/lib/Twig/Loader/Array.php index 90221d5d..430efd06 100644 --- a/vendor/twig/twig/lib/Twig/Loader/Array.php +++ b/vendor/twig/twig/lib/Twig/Loader/Array.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,18 +19,18 @@ * * This loader should only be used for unit testing. * + * @final + * * @author Fabien Potencier */ -class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface +class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface { protected $templates = array(); /** - * Constructor. - * * @param array $templates An array of templates (keys are the names, and values are the source code) */ - public function __construct(array $templates) + public function __construct(array $templates = array()) { $this->templates = $templates; } @@ -46,11 +46,10 @@ public function setTemplate($name, $template) $this->templates[(string) $name] = $template; } - /** - * {@inheritdoc} - */ public function getSource($name) { + @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED); + $name = (string) $name; if (!isset($this->templates[$name])) { throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); @@ -59,17 +58,21 @@ public function getSource($name) return $this->templates[$name]; } - /** - * {@inheritdoc} - */ + public function getSourceContext($name) + { + $name = (string) $name; + if (!isset($this->templates[$name])) { + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + } + + return new Twig_Source($this->templates[$name], $name); + } + public function exists($name) { return isset($this->templates[(string) $name]); } - /** - * {@inheritdoc} - */ public function getCacheKey($name) { $name = (string) $name; @@ -80,9 +83,6 @@ public function getCacheKey($name) return $this->templates[$name]; } - /** - * {@inheritdoc} - */ public function isFresh($name, $time) { $name = (string) $name; diff --git a/vendor/twig/twig/lib/Twig/Loader/Chain.php b/vendor/twig/twig/lib/Twig/Loader/Chain.php index 81d57ada..ffa892b1 100644 --- a/vendor/twig/twig/lib/Twig/Loader/Chain.php +++ b/vendor/twig/twig/lib/Twig/Loader/Chain.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,17 +12,17 @@ /** * Loads templates from other loaders. * + * @final + * * @author Fabien Potencier */ -class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface +class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface { private $hasSourceCache = array(); protected $loaders = array(); /** - * Constructor. - * - * @param Twig_LoaderInterface[] $loaders An array of loader instances + * @param Twig_LoaderInterface[] $loaders */ public function __construct(array $loaders = array()) { @@ -31,22 +31,16 @@ public function __construct(array $loaders = array()) } } - /** - * Adds a loader instance. - * - * @param Twig_LoaderInterface $loader A Loader instance - */ public function addLoader(Twig_LoaderInterface $loader) { $this->loaders[] = $loader; $this->hasSourceCache = array(); } - /** - * {@inheritdoc} - */ public function getSource($name) { + @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED); + $exceptions = array(); foreach ($this->loaders as $loader) { if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { @@ -63,9 +57,28 @@ public function getSource($name) throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); } - /** - * {@inheritdoc} - */ + public function getSourceContext($name) + { + $exceptions = array(); + foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + + try { + if ($loader instanceof Twig_SourceContextLoaderInterface) { + return $loader->getSourceContext($name); + } + + return new Twig_Source($loader->getSource($name), $name); + } catch (Twig_Error_Loader $e) { + $exceptions[] = $e->getMessage(); + } + } + + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); + } + public function exists($name) { $name = (string) $name; @@ -84,7 +97,11 @@ public function exists($name) } try { - $loader->getSource($name); + if ($loader instanceof Twig_SourceContextLoaderInterface) { + $loader->getSourceContext($name); + } else { + $loader->getSource($name); + } return $this->hasSourceCache[$name] = true; } catch (Twig_Error_Loader $e) { @@ -94,9 +111,6 @@ public function exists($name) return $this->hasSourceCache[$name] = false; } - /** - * {@inheritdoc} - */ public function getCacheKey($name) { $exceptions = array(); @@ -115,9 +129,6 @@ public function getCacheKey($name) throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); } - /** - * {@inheritdoc} - */ public function isFresh($name, $time) { $exceptions = array(); diff --git a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php index 1bc75a10..25be4e2d 100644 --- a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php +++ b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -14,7 +14,7 @@ * * @author Fabien Potencier */ -class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface +class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface { /** Identifier of the main namespace. */ const MAIN_NAMESPACE = '__main__'; @@ -23,13 +23,19 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI protected $cache = array(); protected $errorCache = array(); + private $rootPath; + /** - * Constructor. - * - * @param string|array $paths A path or an array of paths where to look for templates + * @param string|array $paths A path or an array of paths where to look for templates + * @param string|null $rootPath The root path common to all relative paths (null for getcwd()) */ - public function __construct($paths = array()) + public function __construct($paths = array(), $rootPath = null) { + $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).DIRECTORY_SEPARATOR; + if (false !== $realPath = realpath($rootPath)) { + $this->rootPath = $realPath.DIRECTORY_SEPARATOR; + } + if ($paths) { $this->setPaths($paths); } @@ -81,7 +87,7 @@ public function setPaths($paths, $namespace = self::MAIN_NAMESPACE) * Adds a path where templates are stored. * * @param string $path A path where to look for templates - * @param string $namespace A path name + * @param string $namespace A path namespace * * @throws Twig_Error_Loader */ @@ -90,8 +96,9 @@ public function addPath($path, $namespace = self::MAIN_NAMESPACE) // invalidate the cache $this->cache = $this->errorCache = array(); - if (!is_dir($path)) { - throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); + $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path; + if (!is_dir($checkPath)) { + throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath)); } $this->paths[$namespace][] = rtrim($path, '/\\'); @@ -101,7 +108,7 @@ public function addPath($path, $namespace = self::MAIN_NAMESPACE) * Prepends a path where templates are stored. * * @param string $path A path where to look for templates - * @param string $namespace A path name + * @param string $namespace A path namespace * * @throws Twig_Error_Loader */ @@ -110,8 +117,9 @@ public function prependPath($path, $namespace = self::MAIN_NAMESPACE) // invalidate the cache $this->cache = $this->errorCache = array(); - if (!is_dir($path)) { - throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); + $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path; + if (!is_dir($checkPath)) { + throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath)); } $path = rtrim($path, '/\\'); @@ -123,25 +131,31 @@ public function prependPath($path, $namespace = self::MAIN_NAMESPACE) } } - /** - * {@inheritdoc} - */ public function getSource($name) { + @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED); + return file_get_contents($this->findTemplate($name)); } - /** - * {@inheritdoc} - */ + public function getSourceContext($name) + { + $path = $this->findTemplate($name); + + return new Twig_Source(file_get_contents($path), $name, $path); + } + public function getCacheKey($name) { - return $this->findTemplate($name); + $path = $this->findTemplate($name); + $len = strlen($this->rootPath); + if (0 === strncmp($this->rootPath, $path, $len)) { + return substr($path, $len); + } + + return $path; } - /** - * {@inheritdoc} - */ public function exists($name) { $name = $this->normalizeName($name); @@ -153,13 +167,12 @@ public function exists($name) try { return false !== $this->findTemplate($name, false); } catch (Twig_Error_Loader $exception) { + @trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', get_class($this)), E_USER_DEPRECATED); + return false; } } - /** - * {@inheritdoc} - */ public function isFresh($name, $time) { return filemtime($this->findTemplate($name)) <= $time; @@ -197,6 +210,10 @@ protected function findTemplate($name) } foreach ($this->paths[$namespace] as $path) { + if (!$this->isAbsolutePath($path)) { + $path = $this->rootPath.'/'.$path; + } + if (is_file($path.'/'.$shortname)) { if (false !== $realpath = realpath($path.'/'.$shortname)) { return $this->cache[$name] = $realpath; @@ -257,4 +274,15 @@ protected function validateName($name) } } } + + private function isAbsolutePath($file) + { + return strspn($file, '/\\', 0, 1) + || (strlen($file) > 3 && ctype_alpha($file[0]) + && substr($file, 1, 1) === ':' + && strspn($file, '/\\', 2, 1) + ) + || null !== parse_url($file, PHP_URL_SCHEME) + ; + } } diff --git a/vendor/twig/twig/lib/Twig/Loader/String.php b/vendor/twig/twig/lib/Twig/Loader/String.php index 00f507a4..950bd35b 100644 --- a/vendor/twig/twig/lib/Twig/Loader/String.php +++ b/vendor/twig/twig/lib/Twig/Loader/String.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -27,35 +27,30 @@ * * @author Fabien Potencier */ -class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface +class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface, Twig_SourceContextLoaderInterface { - /** - * {@inheritdoc} - */ public function getSource($name) { + @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', get_class($this)), E_USER_DEPRECATED); + return $name; } - /** - * {@inheritdoc} - */ + public function getSourceContext($name) + { + return new Twig_Source($name, $name); + } + public function exists($name) { return true; } - /** - * {@inheritdoc} - */ public function getCacheKey($name) { return $name; } - /** - * {@inheritdoc} - */ public function isFresh($name, $time) { return true; diff --git a/vendor/twig/twig/lib/Twig/LoaderInterface.php b/vendor/twig/twig/lib/Twig/LoaderInterface.php index 544ea4e3..b0299972 100644 --- a/vendor/twig/twig/lib/Twig/LoaderInterface.php +++ b/vendor/twig/twig/lib/Twig/LoaderInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,6 +24,8 @@ interface Twig_LoaderInterface * @return string The template source code * * @throws Twig_Error_Loader When $name is not found + * + * @deprecated since 1.27 (to be removed in 2.0), implement Twig_SourceContextLoaderInterface */ public function getSource($name); diff --git a/vendor/twig/twig/lib/Twig/Markup.php b/vendor/twig/twig/lib/Twig/Markup.php index 69871fcb..535ebe9e 100644 --- a/vendor/twig/twig/lib/Twig/Markup.php +++ b/vendor/twig/twig/lib/Twig/Markup.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node.php b/vendor/twig/twig/lib/Twig/Node.php index 3065f675..807f198f 100644 --- a/vendor/twig/twig/lib/Twig/Node.php +++ b/vendor/twig/twig/lib/Twig/Node.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -22,6 +22,8 @@ class Twig_Node implements Twig_NodeInterface protected $lineno; protected $tag; + private $name; + /** * Constructor. * @@ -35,6 +37,11 @@ class Twig_Node implements Twig_NodeInterface */ public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null) { + foreach ($nodes as $name => $node) { + if (!$node instanceof Twig_NodeInterface) { + @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED); + } + } $this->nodes = $nodes; $this->attributes = $attributes; $this->lineno = $lineno; @@ -111,8 +118,18 @@ public function compile(Twig_Compiler $compiler) } } + public function getTemplateLine() + { + return $this->lineno; + } + + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function getLine() { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateLine() instead.', E_USER_DEPRECATED); + return $this->lineno; } @@ -122,11 +139,7 @@ public function getNodeTag() } /** - * Returns true if the attribute is defined. - * - * @param string $name The attribute name - * - * @return bool true if the attribute is defined, false otherwise + * @return bool */ public function hasAttribute($name) { @@ -134,10 +147,6 @@ public function hasAttribute($name) } /** - * Gets an attribute value by name. - * - * @param string $name - * * @return mixed */ public function getAttribute($name) @@ -150,8 +159,6 @@ public function getAttribute($name) } /** - * Sets an attribute by name to a value. - * * @param string $name * @param mixed $value */ @@ -160,21 +167,12 @@ public function setAttribute($name, $value) $this->attributes[$name] = $value; } - /** - * Removes an attribute by name. - * - * @param string $name - */ public function removeAttribute($name) { unset($this->attributes[$name]); } /** - * Returns true if the node with the given name exists. - * - * @param string $name - * * @return bool */ public function hasNode($name) @@ -183,10 +181,6 @@ public function hasNode($name) } /** - * Gets a node by name. - * - * @param string $name - * * @return Twig_Node */ public function getNode($name) @@ -198,22 +192,15 @@ public function getNode($name) return $this->nodes[$name]; } - /** - * Sets a node. - * - * @param string $name - * @param Twig_Node $node - */ public function setNode($name, $node = null) { + if (!$node instanceof Twig_NodeInterface) { + @trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', is_object($node) ? get_class($node) : null === $node ? 'null' : gettype($node), $name, get_class($this)), E_USER_DEPRECATED); + } + $this->nodes[$name] = $node; } - /** - * Removes a node by name. - * - * @param string $name - */ public function removeNode($name) { unset($this->nodes[$name]); @@ -228,4 +215,39 @@ public function getIterator() { return new ArrayIterator($this->nodes); } + + public function setTemplateName($name) + { + $this->name = $name; + foreach ($this->nodes as $node) { + if (null !== $node) { + $node->setTemplateName($name); + } + } + } + + public function getTemplateName() + { + return $this->name; + } + + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ + public function setFilename($name) + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', E_USER_DEPRECATED); + + $this->setTemplateName($name); + } + + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ + public function getFilename() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED); + + return $this->name; + } } diff --git a/vendor/twig/twig/lib/Twig/Node/AutoEscape.php b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php index 47cc998d..570f23e4 100644 --- a/vendor/twig/twig/lib/Twig/Node/AutoEscape.php +++ b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Block.php b/vendor/twig/twig/lib/Twig/Node/Block.php index a05af6fb..dfd8ceb8 100644 --- a/vendor/twig/twig/lib/Twig/Node/Block.php +++ b/vendor/twig/twig/lib/Twig/Node/Block.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/BlockReference.php b/vendor/twig/twig/lib/Twig/Node/BlockReference.php index 9cd1551f..d9b59378 100644 --- a/vendor/twig/twig/lib/Twig/Node/BlockReference.php +++ b/vendor/twig/twig/lib/Twig/Node/BlockReference.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Body.php b/vendor/twig/twig/lib/Twig/Node/Body.php index 3ffb1342..2314c9ab 100644 --- a/vendor/twig/twig/lib/Twig/Node/Body.php +++ b/vendor/twig/twig/lib/Twig/Node/Body.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php b/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php index b4a436ab..b9cf054a 100644 --- a/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +++ b/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -33,7 +33,7 @@ public function compile(Twig_Compiler $compiler) foreach (array('tags', 'filters', 'functions') as $type) { foreach ($this->{'used'.ucfirst($type)} as $name => $node) { if ($node instanceof Twig_Node) { - ${$type}[$name] = $node->getLine(); + ${$type}[$name] = $node->getTemplateLine(); } else { ${$type}[$node] = null; } @@ -46,7 +46,7 @@ public function compile(Twig_Compiler $compiler) ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n") ->write("try {\n") ->indent() - ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n") + ->write("\$this->env->getExtension('Twig_Extension_Sandbox')->checkSecurity(\n") ->indent() ->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n") ->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n") @@ -56,7 +56,7 @@ public function compile(Twig_Compiler $compiler) ->outdent() ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n") ->indent() - ->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n") + ->write("\$e->setSourceContext(\$this->getSourceContext());\n\n") ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n") ->indent() ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n") diff --git a/vendor/twig/twig/lib/Twig/Node/Do.php b/vendor/twig/twig/lib/Twig/Node/Do.php index 14fb84e9..94305c7a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Do.php +++ b/vendor/twig/twig/lib/Twig/Node/Do.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Embed.php b/vendor/twig/twig/lib/Twig/Node/Embed.php index a2130403..1786f36c 100644 --- a/vendor/twig/twig/lib/Twig/Node/Embed.php +++ b/vendor/twig/twig/lib/Twig/Node/Embed.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,11 +17,13 @@ class Twig_Node_Embed extends Twig_Node_Include { // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) - public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) + public function __construct($name, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) { parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); - $this->setAttribute('filename', $filename); + $this->setAttribute('name', $name); + // to be removed in 2.0, used name instead + $this->setAttribute('filename', $name); $this->setAttribute('index', $index); } @@ -29,11 +31,11 @@ protected function addGetTemplate(Twig_Compiler $compiler) { $compiler ->write('$this->loadTemplate(') - ->string($this->getAttribute('filename')) + ->string($this->getAttribute('name')) ->raw(', ') - ->repr($compiler->getFilename()) + ->repr($this->getTemplateName()) ->raw(', ') - ->repr($this->getLine()) + ->repr($this->getTemplateLine()) ->raw(', ') ->string($this->getAttribute('index')) ->raw(')') diff --git a/vendor/twig/twig/lib/Twig/Node/Expression.php b/vendor/twig/twig/lib/Twig/Node/Expression.php index a7382e7d..e609d812 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Array.php b/vendor/twig/twig/lib/Twig/Node/Expression/Array.php index 83e583b0..0c726c04 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Array.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Array.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -43,7 +43,7 @@ public function hasElement(Twig_Node_Expression $key) foreach ($this->getKeyValuePairs() as $pair) { // we compare the string representation of the keys // to avoid comparing the line numbers which are not relevant here. - if ((string) $key == (string) $pair['key']) { + if ((string) $key === (string) $pair['key']) { return true; } } @@ -54,7 +54,7 @@ public function hasElement(Twig_Node_Expression $key) public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null) { if (null === $key) { - $key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine()); + $key = new Twig_Node_Expression_Constant(++$this->index, $value->getTemplateLine()); } array_push($this->nodes, $key, $value); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php b/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php index ce0c5fbc..ceb72823 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php index c821db52..d4787698 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php index 0ef8e117..51bba480 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php index d5752ebb..9b3997da 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php index 9a46d845..fa9729db 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php index 058a20bf..e3be5485 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php index f4da73d44..9255d8f7 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php index f9a64627..7de9070e 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php index e0797a61..386b4eab 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php index 93b3b96f..c24b720a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2013 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php index 7b1236d0..4535cd08 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php index b606f6d1..b386ae35 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,9 +12,9 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary { public function compile(Twig_Compiler $compiler) { - $compiler->raw('intval(floor('); + $compiler->raw('(int) floor('); parent::compile($compiler); - $compiler->raw('))'); + $compiler->raw(')'); } public function operator(Twig_Compiler $compiler) diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php index a110bd92..52dcb332 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php index 3754fed2..1d66d6c4 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php index 9565a608..ba44961a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php index 45fd3004..c9d20c42 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php index e38e257c..219b3bdb 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php index 93bb2920..b22debf2 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2013 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php index 9924114f..c99874ca 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php index c91529ca..0d24cee4 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php index 26867ba2..69eae7e8 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php index 49ab39e9..f276da7d 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php index adba49c6..7621763d 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php index cd6d0462..d3225ded 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,10 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary { public function compile(Twig_Compiler $compiler) { + if (PHP_VERSION_ID >= 50600) { + return parent::compile($compiler); + } + $compiler ->raw('pow(') ->subcompile($this->getNode('left')) diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php index 692ec9c6..4261cdea 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php index d2e30d66..d1e9a5a7 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2013 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php index d4463991..b423d3ee 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php index f6ed6ff4..056d9918 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,30 +17,75 @@ */ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression { - public function __construct(Twig_NodeInterface $name, $asString = false, $lineno, $tag = null) + /** + * @param Twig_Node|null $template + */ + public function __construct(Twig_NodeInterface $name, $template = null, $lineno, $tag = null) { - parent::__construct(array('name' => $name), array('as_string' => $asString, 'output' => false), $lineno, $tag); + if (is_bool($template)) { + @trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED); + + $template = null; + } + + $nodes = array('name' => $name); + if (null !== $template) { + $nodes['template'] = $template; + } + + parent::__construct($nodes, array('is_defined_test' => false, 'output' => false), $lineno, $tag); } public function compile(Twig_Compiler $compiler) { - if ($this->getAttribute('as_string')) { - $compiler->raw('(string) '); + if ($this->getAttribute('is_defined_test')) { + $this->compileTemplateCall($compiler, 'hasBlock'); + } else { + if ($this->getAttribute('output')) { + $compiler->addDebugInfo($this); + + $this + ->compileTemplateCall($compiler, 'displayBlock') + ->raw(";\n"); + } else { + $this->compileTemplateCall($compiler, 'renderBlock'); + } } + } - if ($this->getAttribute('output')) { - $compiler - ->addDebugInfo($this) - ->write('$this->displayBlock(') - ->subcompile($this->getNode('name')) - ->raw(", \$context, \$blocks);\n") - ; + private function compileTemplateCall(Twig_Compiler $compiler, $method) + { + if (!$this->hasNode('template')) { + $compiler->write('$this'); } else { $compiler - ->raw('$this->renderBlock(') - ->subcompile($this->getNode('name')) - ->raw(', $context, $blocks)') + ->write('$this->loadTemplate(') + ->subcompile($this->getNode('template')) + ->raw(', ') + ->repr($this->getTemplateName()) + ->raw(', ') + ->repr($this->getTemplateLine()) + ->raw(')') ; } + + $compiler->raw(sprintf('->%s', $method)); + $this->compileBlockArguments($compiler); + + return $compiler; + } + + private function compileBlockArguments(Twig_Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('name')) + ->raw(', $context'); + + if (!$this->hasNode('template')) { + $compiler->raw(', $blocks'); + } + + return $compiler->raw(')'); } } diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Call.php b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php index 240553f9..27767972 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Call.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php @@ -3,25 +3,36 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression { + private $reflector; + protected function compileCallable(Twig_Compiler $compiler) { $closingParenthesis = false; if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) { - if (is_string($callable)) { + if (is_string($callable) && false === strpos($callable, '::')) { $compiler->raw($callable); - } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) { - $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1])); } else { - $type = ucfirst($this->getAttribute('type')); - $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name'))); - $closingParenthesis = true; + list($r, $callable) = $this->reflectCallable($callable); + if ($r instanceof ReflectionMethod && is_string($callable[0])) { + if ($r->isStatic()) { + $compiler->raw(sprintf('%s::%s', $callable[0], $callable[1])); + } else { + $compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1])); + } + } elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) { + $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1])); + } else { + $type = ucfirst($this->getAttribute('type')); + $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name'))); + $closingParenthesis = true; + } } } else { $compiler->raw($this->getAttribute('thing')->compile()); @@ -71,7 +82,7 @@ protected function compileArguments(Twig_Compiler $compiler) $first = false; } - if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) { + if ($this->hasNode('arguments')) { $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null; $arguments = $this->getArguments($callable, $this->getNode('arguments')); @@ -121,7 +132,6 @@ protected function getArguments($callable, $arguments) throw new LogicException($message); } - // manage named arguments $callableParameters = $this->getCallableParameters($callable, $isVariadic); $arguments = array(); $names = array(); @@ -136,7 +146,7 @@ protected function getArguments($callable, $arguments) throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName)); } - if (!empty($missingArguments)) { + if (count($missingArguments)) { throw new Twig_Error_Syntax(sprintf( 'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".', $name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)) @@ -195,7 +205,7 @@ protected function getArguments($callable, $arguments) throw new Twig_Error_Syntax(sprintf( 'Unknown argument%s "%s" for %s "%s(%s)".', count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names) - ), $unknownParameter ? $unknownParameter->getLine() : -1); + ), $unknownParameter ? $unknownParameter->getTemplateLine() : -1); } return $arguments; @@ -208,15 +218,9 @@ protected function normalizeName($name) private function getCallableParameters($callable, $isVariadic) { - if (is_array($callable)) { - $r = new ReflectionMethod($callable[0], $callable[1]); - } elseif (is_object($callable) && !$callable instanceof Closure) { - $r = new ReflectionObject($callable); - $r = $r->getMethod('__invoke'); - } elseif (is_string($callable) && false !== strpos($callable, '::')) { - $r = new ReflectionMethod($callable); - } else { - $r = new ReflectionFunction($callable); + list($r) = $this->reflectCallable($callable); + if (null === $r) { + return array(); } $parameters = $r->getParameters(); @@ -240,7 +244,7 @@ private function getCallableParameters($callable, $isVariadic) array_pop($parameters); } else { $callableName = $r->name; - if ($r->getDeclaringClass()) { + if ($r instanceof ReflectionMethod) { $callableName = $r->getDeclaringClass()->name.'::'.$callableName; } @@ -250,4 +254,36 @@ private function getCallableParameters($callable, $isVariadic) return $parameters; } + + private function reflectCallable($callable) + { + if (null !== $this->reflector) { + return $this->reflector; + } + + if (is_array($callable)) { + if (!method_exists($callable[0], $callable[1])) { + // __call() + return array(null, array()); + } + $r = new ReflectionMethod($callable[0], $callable[1]); + } elseif (is_object($callable) && !$callable instanceof Closure) { + $r = new ReflectionObject($callable); + $r = $r->getMethod('__invoke'); + $callable = array($callable, '__invoke'); + } elseif (is_string($callable) && false !== $pos = strpos($callable, '::')) { + $class = substr($callable, 0, $pos); + $method = substr($callable, $pos + 2); + if (!method_exists($class, $method)) { + // __staticCall() + return array(null, array()); + } + $r = new ReflectionMethod($callable); + $callable = array($class, $method); + } else { + $r = new ReflectionFunction($callable); + } + + return $this->reflector = array($r, $callable); + } } diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php b/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php index edcb1e2d..67cca1fd 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php b/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php index a91dc698..1a2c5964 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php b/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php index b4882e36..114b5cd9 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php index a906232e..a8fa847a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php b/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php index 1827c888..d32d86d3 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -22,13 +22,13 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter { public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null) { - $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine()); + $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine()); if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) { - $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine()); - $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getLine()); + $test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getTemplateLine()); + $false = count($arguments) ? $arguments->getNode(0) : new Twig_Node_Expression_Constant('', $node->getTemplateLine()); - $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getLine()); + $node = new Twig_Node_Expression_Conditional($test, $default, $false, $node->getTemplateLine()); } else { $node = $default; } diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Function.php b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php index 7326ede2..eaad56ec 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Function.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,7 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call { public function __construct($name, Twig_NodeInterface $arguments, $lineno) { - parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno); + parent::__construct(array('arguments' => $arguments), array('name' => $name, 'is_defined_test' => false), $lineno); } public function compile(Twig_Compiler $compiler) @@ -27,7 +27,12 @@ public function compile(Twig_Compiler $compiler) $this->setAttribute('needs_context', $function->needsContext()); $this->setAttribute('arguments', $function->getArguments()); if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) { - $this->setAttribute('callable', $function->getCallable()); + $callable = $function->getCallable(); + if ('constant' === $name && $this->getAttribute('is_defined_test')) { + $callable = 'twig_constant_is_defined'; + } + + $this->setAttribute('callable', $callable); } if ($function instanceof Twig_SimpleFunction) { $this->setAttribute('is_variadic', $function->isVariadic()); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php index 6ce61111..75814265 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,11 +13,20 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression { public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno) { - parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno); + $nodes = array('node' => $node, 'attribute' => $attribute); + if (null !== $arguments) { + $nodes['arguments'] = $arguments; + } + + parent::__construct($nodes, array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno); } public function compile(Twig_Compiler $compiler) { + if ($this->getAttribute('disable_c_ext')) { + @trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED); + } + if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) { $compiler->raw('twig_template_get_attributes($this, '); } else { @@ -36,10 +45,10 @@ public function compile(Twig_Compiler $compiler) $needFourth = $this->getAttribute('ignore_strict_check'); $needThird = $needFourth || $this->getAttribute('is_defined_test'); $needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type'); - $needFirst = $needSecond || null !== $this->getNode('arguments'); + $needFirst = $needSecond || $this->hasNode('arguments'); if ($needFirst) { - if (null !== $this->getNode('arguments')) { + if ($this->hasNode('arguments')) { $compiler->raw(', ')->subcompile($this->getNode('arguments')); } else { $compiler->raw(', array()'); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php b/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php index 620b02bf..39481337 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Name.php b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php index a6e0ff42..e03ca357 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Name.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -43,10 +43,20 @@ public function compile(Twig_Compiler $compiler) ->raw(']') ; } else { - // remove the non-PHP 5.4 version when PHP 5.3 support is dropped - // as the non-optimized version is just a workaround for slow ternary operator - // when the context has a lot of variables - if (PHP_VERSION_ID >= 50400) { + if (PHP_VERSION_ID >= 70000) { + // use PHP 7 null coalescing operator + $compiler + ->raw('($context[') + ->string($name) + ->raw('] ?? ') + ; + + if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) { + $compiler->raw('null)'); + } else { + $compiler->raw('$this->getContext($context, ')->string($name)->raw('))'); + } + } elseif (PHP_VERSION_ID >= 50400) { // PHP 5.4 ternary operator performance was optimized $compiler ->raw('(isset($context[') diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php b/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php index 10039130..14f6358f 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php @@ -13,11 +13,34 @@ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno) { $test = new Twig_Node_Expression_Binary_And( - new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getLine()), - new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getLine()), $left->getLine()), - $left->getLine() + new Twig_Node_Expression_Test_Defined(clone $left, 'defined', new Twig_Node(), $left->getTemplateLine()), + new Twig_Node_Expression_Unary_Not(new Twig_Node_Expression_Test_Null($left, 'null', new Twig_Node(), $left->getTemplateLine()), $left->getTemplateLine()), + $left->getTemplateLine() ); parent::__construct($test, $left, $right, $lineno); } + + public function compile(Twig_Compiler $compiler) + { + /* + * This optimizes only one case. PHP 7 also supports more complex expressions + * that can return null. So, for instance, if log is defined, log("foo") ?? "..." works, + * but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced + * cases might be implemented as an optimizer node visitor, but has not been done + * as benefits are probably not worth the added complexity. + */ + if (PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof Twig_Node_Expression_Name) { + $this->getNode('expr2')->setAttribute('always_defined', true); + $compiler + ->raw('((') + ->subcompile($this->getNode('expr2')) + ->raw(') ?? (') + ->subcompile($this->getNode('expr3')) + ->raw('))') + ; + } else { + parent::compile($compiler); + } + } } diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php index 694c0804..e7d82d81 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php b/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php index e6b058e8..09a04a31 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php index c0358c8b..3dfe4f19 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,12 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call { public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $arguments = null, $lineno) { - parent::__construct(array('node' => $node, 'arguments' => $arguments), array('name' => $name), $lineno); + $nodes = array('node' => $node); + if (null !== $arguments) { + $nodes['arguments'] = $arguments; + } + + parent::__construct($nodes, array('name' => $name), $lineno); } public function compile(Twig_Compiler $compiler) diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php index de55f5f5..ffde3488 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php index 3dc6ff59..31cd987c 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -29,12 +29,15 @@ public function __construct(Twig_NodeInterface $node, $name, Twig_NodeInterface $node->setAttribute('is_defined_test', true); } elseif ($node instanceof Twig_Node_Expression_GetAttr) { $node->setAttribute('is_defined_test', true); - $this->changeIgnoreStrictCheck($node); + } elseif ($node instanceof Twig_Node_Expression_BlockReference) { + $node->setAttribute('is_defined_test', true); + } elseif ($node instanceof Twig_Node_Expression_Function && 'constant' === $node->getAttribute('name')) { + $node->setAttribute('is_defined_test', true); } elseif ($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array) { - $node = new Twig_Node_Expression_Constant(true, $node->getLine()); + $node = new Twig_Node_Expression_Constant(true, $node->getTemplateLine()); } else { - throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getLine()); + throw new Twig_Error_Syntax('The "defined" test only works with simple variables.', $this->getTemplateLine()); } parent::__construct($node, $name, $arguments, $lineno); diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php index d5bed234..0d6bdb49 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php index d7853e89..fe42e627 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php index 1c83825a..934d8356 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php index 421c19e8..4f16029a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php index b48905ee..abc2f5be 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php index 1cf54c32..0ea2c2c3 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php index 2a3937ec..ca3ef8f3 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php index f94073cf..a5e4f198 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php index 04edb52a..5497532b 100644 --- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php +++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Flush.php b/vendor/twig/twig/lib/Twig/Node/Flush.php index 2af17a42..cd4be411 100644 --- a/vendor/twig/twig/lib/Twig/Node/Flush.php +++ b/vendor/twig/twig/lib/Twig/Node/Flush.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/For.php b/vendor/twig/twig/lib/Twig/Node/For.php index 2d450932..f93d9c81 100644 --- a/vendor/twig/twig/lib/Twig/Node/For.php +++ b/vendor/twig/twig/lib/Twig/Node/For.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -27,7 +27,12 @@ public function __construct(Twig_Node_Expression_AssignName $keyTarget, Twig_Nod $body = new Twig_Node_If(new Twig_Node(array($ifexpr, $body)), null, $lineno, $tag); } - parent::__construct(array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body, 'else' => $else), array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag); + $nodes = array('key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body); + if (null !== $else) { + $nodes['else'] = $else; + } + + parent::__construct($nodes, array('with_loop' => true, 'ifexpr' => null !== $ifexpr), $lineno, $tag); } public function compile(Twig_Compiler $compiler) @@ -40,7 +45,7 @@ public function compile(Twig_Compiler $compiler) ->raw(");\n") ; - if (null !== $this->getNode('else')) { + if ($this->hasNode('else')) { $compiler->write("\$context['_iterated'] = false;\n"); } @@ -69,7 +74,7 @@ public function compile(Twig_Compiler $compiler) } } - $this->loop->setAttribute('else', null !== $this->getNode('else')); + $this->loop->setAttribute('else', $this->hasNode('else')); $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop')); $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr')); @@ -85,7 +90,7 @@ public function compile(Twig_Compiler $compiler) ->write("}\n") ; - if (null !== $this->getNode('else')) { + if ($this->hasNode('else')) { $compiler ->write("if (!\$context['_iterated']) {\n") ->indent() diff --git a/vendor/twig/twig/lib/Twig/Node/ForLoop.php b/vendor/twig/twig/lib/Twig/Node/ForLoop.php index 2554d480..ab0215e6 100644 --- a/vendor/twig/twig/lib/Twig/Node/ForLoop.php +++ b/vendor/twig/twig/lib/Twig/Node/ForLoop.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/If.php b/vendor/twig/twig/lib/Twig/Node/If.php index caff9368..9cd78f47 100644 --- a/vendor/twig/twig/lib/Twig/Node/If.php +++ b/vendor/twig/twig/lib/Twig/Node/If.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,7 +19,12 @@ class Twig_Node_If extends Twig_Node { public function __construct(Twig_NodeInterface $tests, Twig_NodeInterface $else = null, $lineno, $tag = null) { - parent::__construct(array('tests' => $tests, 'else' => $else), array(), $lineno, $tag); + $nodes = array('tests' => $tests); + if (null !== $else) { + $nodes['else'] = $else; + } + + parent::__construct($nodes, array(), $lineno, $tag); } public function compile(Twig_Compiler $compiler) @@ -45,7 +50,7 @@ public function compile(Twig_Compiler $compiler) ; } - if ($this->hasNode('else') && null !== $this->getNode('else')) { + if ($this->hasNode('else')) { $compiler ->outdent() ->write("} else {\n") diff --git a/vendor/twig/twig/lib/Twig/Node/Import.php b/vendor/twig/twig/lib/Twig/Node/Import.php index df37af37..759bb5c3 100644 --- a/vendor/twig/twig/lib/Twig/Node/Import.php +++ b/vendor/twig/twig/lib/Twig/Node/Import.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -37,9 +37,9 @@ public function compile(Twig_Compiler $compiler) ->raw('$this->loadTemplate(') ->subcompile($this->getNode('expr')) ->raw(', ') - ->repr($compiler->getFilename()) + ->repr($this->getTemplateName()) ->raw(', ') - ->repr($this->getLine()) + ->repr($this->getTemplateLine()) ->raw(')') ; } diff --git a/vendor/twig/twig/lib/Twig/Node/Include.php b/vendor/twig/twig/lib/Twig/Node/Include.php index 9952f731..15a27ca6 100644 --- a/vendor/twig/twig/lib/Twig/Node/Include.php +++ b/vendor/twig/twig/lib/Twig/Node/Include.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,7 +19,12 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface { public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null) { - parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag); + $nodes = array('expr' => $expr); + if (null !== $variables) { + $nodes['variables'] = $variables; + } + + parent::__construct($nodes, array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag); } public function compile(Twig_Compiler $compiler) @@ -59,16 +64,16 @@ protected function addGetTemplate(Twig_Compiler $compiler) ->write('$this->loadTemplate(') ->subcompile($this->getNode('expr')) ->raw(', ') - ->repr($compiler->getFilename()) + ->repr($this->getTemplateName()) ->raw(', ') - ->repr($this->getLine()) + ->repr($this->getTemplateLine()) ->raw(')') ; } protected function addTemplateArguments(Twig_Compiler $compiler) { - if (null === $this->getNode('variables')) { + if (!$this->hasNode('variables')) { $compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()'); } elseif (false === $this->getAttribute('only')) { $compiler diff --git a/vendor/twig/twig/lib/Twig/Node/Macro.php b/vendor/twig/twig/lib/Twig/Node/Macro.php index 932e795f..e9e1421a 100644 --- a/vendor/twig/twig/lib/Twig/Node/Macro.php +++ b/vendor/twig/twig/lib/Twig/Node/Macro.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -22,7 +22,7 @@ public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface { foreach ($arguments as $argumentName => $argument) { if (self::VARARGS_NAME === $argumentName) { - throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getLine()); + throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine()); } } @@ -70,7 +70,7 @@ public function compile(Twig_Compiler $compiler) foreach ($this->getNode('arguments') as $name => $default) { $compiler - ->addIndentation() + ->write('') ->string($name) ->raw(' => $__'.$name.'__') ->raw(",\n") @@ -78,7 +78,7 @@ public function compile(Twig_Compiler $compiler) } $compiler - ->addIndentation() + ->write('') ->string(self::VARARGS_NAME) ->raw(' => ') ; @@ -109,6 +109,11 @@ public function compile(Twig_Compiler $compiler) ->write("ob_end_clean();\n\n") ->write("throw \$e;\n") ->outdent() + ->write("} catch (Throwable \$e) {\n") + ->indent() + ->write("ob_end_clean();\n\n") + ->write("throw \$e;\n") + ->outdent() ->write("}\n\n") ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n") ->outdent() diff --git a/vendor/twig/twig/lib/Twig/Node/Module.php b/vendor/twig/twig/lib/Twig/Node/Module.php index 01161d3e..5bfcc923 100644 --- a/vendor/twig/twig/lib/Twig/Node/Module.php +++ b/vendor/twig/twig/lib/Twig/Node/Module.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,11 +21,18 @@ */ class Twig_Node_Module extends Twig_Node { - public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename) + private $source; + + public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '') { - // embedded templates are set as attributes so that they are only visited once by the visitors - parent::__construct(array( - 'parent' => $parent, + if (!$name instanceof Twig_Source) { + @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); + $this->source = new Twig_Source($source, $name); + } else { + $this->source = $name; + } + + $nodes = array( 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, @@ -35,11 +42,23 @@ public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $pare 'constructor_start' => new Twig_Node(), 'constructor_end' => new Twig_Node(), 'class_end' => new Twig_Node(), - ), array( - 'filename' => $filename, + ); + if (null !== $parent) { + $nodes['parent'] = $parent; + } + + // embedded templates are set as attributes so that they are only visited once by the visitors + parent::__construct($nodes, array( + // source to be remove in 2.0 + 'source' => $this->source->getCode(), + // filename to be remove in 2.0 (use getTemplateName() instead) + 'filename' => $this->source->getName(), 'index' => null, 'embedded_templates' => $embeddedTemplates, ), 1); + + // populate the template name of all node children + $this->setTemplateName($this->source->getName()); } public function setIndex($index) @@ -67,7 +86,7 @@ protected function compileTemplate(Twig_Compiler $compiler) if ( count($this->getNode('blocks')) || count($this->getNode('traits')) - || null === $this->getNode('parent') + || !$this->hasNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant || count($this->getNode('constructor_start')) || count($this->getNode('constructor_end')) @@ -89,14 +108,19 @@ protected function compileTemplate(Twig_Compiler $compiler) $this->compileDebugInfo($compiler); + $this->compileGetSource($compiler); + + $this->compileGetSourceContext($compiler); + $this->compileClassFooter($compiler); } protected function compileGetParent(Twig_Compiler $compiler) { - if (null === $parent = $this->getNode('parent')) { + if (!$this->hasNode('parent')) { return; } + $parent = $this->getNode('parent'); $compiler ->write("protected function doGetParent(array \$context)\n", "{\n") @@ -112,9 +136,9 @@ protected function compileGetParent(Twig_Compiler $compiler) ->raw('$this->loadTemplate(') ->subcompile($parent) ->raw(', ') - ->repr($compiler->getFilename()) + ->repr($this->source->getName()) ->raw(', ') - ->repr($this->getNode('parent')->getLine()) + ->repr($parent->getTemplateLine()) ->raw(')') ; } @@ -130,9 +154,9 @@ protected function compileClassHeader(Twig_Compiler $compiler) { $compiler ->write("\n\n") - // if the filename contains */, add a blank to avoid a PHP parse error - ->write('/* '.str_replace('*/', '* /', $this->getAttribute('filename'))." */\n") - ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index'))) + // if the template name contains */, add a blank to avoid a PHP parse error + ->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n") + ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index'))) ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass())) ->write("{\n") ->indent() @@ -149,17 +173,17 @@ protected function compileConstructor(Twig_Compiler $compiler) ; // parent - if (null === $parent = $this->getNode('parent')) { + if (!$this->hasNode('parent')) { $compiler->write("\$this->parent = false;\n\n"); - } elseif ($parent instanceof Twig_Node_Expression_Constant) { + } elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) { $compiler ->addDebugInfo($parent) ->write('$this->parent = $this->loadTemplate(') ->subcompile($parent) ->raw(', ') - ->repr($compiler->getFilename()) + ->repr($this->source->getName()) ->raw(', ') - ->repr($this->getNode('parent')->getLine()) + ->repr($parent->getTemplateLine()) ->raw(");\n") ; } @@ -277,7 +301,8 @@ protected function compileDisplay(Twig_Compiler $compiler) ->subcompile($this->getNode('body')) ; - if (null !== $parent = $this->getNode('parent')) { + if ($this->hasNode('parent')) { + $parent = $this->getNode('parent'); $compiler->addDebugInfo($parent); if ($parent instanceof Twig_Node_Expression_Constant) { $compiler->write('$this->parent'); @@ -314,7 +339,7 @@ protected function compileGetTemplateName(Twig_Compiler $compiler) ->write("public function getTemplateName()\n", "{\n") ->indent() ->write('return ') - ->repr($this->getAttribute('filename')) + ->repr($this->source->getName()) ->raw(";\n") ->outdent() ->write("}\n\n") @@ -330,7 +355,7 @@ protected function compileIsTraitable(Twig_Compiler $compiler) // // Put another way, a template can be used as a trait if it // only contains blocks and use statements. - $traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros')); + $traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros')); if ($traitable) { if ($this->getNode('body') instanceof Twig_Node_Body) { $nodes = $this->getNode('body')->getNode(0); @@ -380,6 +405,37 @@ protected function compileDebugInfo(Twig_Compiler $compiler) ->indent() ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true)))) ->outdent() + ->write("}\n\n") + ; + } + + protected function compileGetSource(Twig_Compiler $compiler) + { + $compiler + ->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n") + ->write("public function getSource()\n", "{\n") + ->indent() + ->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n") + ->write('return $this->getSourceContext()->getCode();') + ->raw("\n") + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileGetSourceContext(Twig_Compiler $compiler) + { + $compiler + ->write("public function getSourceContext()\n", "{\n") + ->indent() + ->write('return new Twig_Source(') + ->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '') + ->raw(', ') + ->string($this->source->getName()) + ->raw(', ') + ->string($this->source->getPath()) + ->raw(");\n") + ->outdent() ->write("}\n") ; } @@ -391,13 +447,13 @@ protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var) ->write(sprintf('%s = $this->loadTemplate(', $var)) ->subcompile($node) ->raw(', ') - ->repr($compiler->getFilename()) + ->repr($node->getTemplateName()) ->raw(', ') - ->repr($node->getLine()) + ->repr($node->getTemplateLine()) ->raw(");\n") ; } else { - throw new LogicException('Trait templates can only be constant nodes'); + throw new LogicException('Trait templates can only be constant nodes.'); } } } diff --git a/vendor/twig/twig/lib/Twig/Node/Print.php b/vendor/twig/twig/lib/Twig/Node/Print.php index 7b69ee81..9e317c84 100644 --- a/vendor/twig/twig/lib/Twig/Node/Print.php +++ b/vendor/twig/twig/lib/Twig/Node/Print.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Sandbox.php b/vendor/twig/twig/lib/Twig/Node/Sandbox.php index cd705e25..658e068e 100644 --- a/vendor/twig/twig/lib/Twig/Node/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/Node/Sandbox.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -25,7 +25,7 @@ public function compile(Twig_Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write("\$sandbox = \$this->env->getExtension('sandbox');\n") + ->write("\$sandbox = \$this->env->getExtension('Twig_Extension_Sandbox');\n") ->write("if (!\$alreadySandboxed = \$sandbox->isSandboxed()) {\n") ->indent() ->write("\$sandbox->enableSandbox();\n") diff --git a/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php index 148dd2bb..fba0051b 100644 --- a/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +++ b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -25,7 +25,7 @@ public function compile(Twig_Compiler $compiler) { $compiler ->addDebugInfo($this) - ->write('echo $this->env->getExtension(\'sandbox\')->ensureToStringAllowed(') + ->write('echo $this->env->getExtension(\'Twig_Extension_Sandbox\')->ensureToStringAllowed(') ->subcompile($this->getNode('expr')) ->raw(");\n") ; @@ -36,11 +36,9 @@ public function compile(Twig_Compiler $compiler) * * This is mostly needed when another visitor adds filters (like the escaper one). * - * @param Twig_Node $node A Node - * * @return Twig_Node */ - protected function removeNodeFilter($node) + protected function removeNodeFilter(Twig_Node $node) { if ($node instanceof Twig_Node_Expression_Filter) { return $this->removeNodeFilter($node->getNode('node')); diff --git a/vendor/twig/twig/lib/Twig/Node/Set.php b/vendor/twig/twig/lib/Twig/Node/Set.php index e5a66037..36e05cca 100644 --- a/vendor/twig/twig/lib/Twig/Node/Set.php +++ b/vendor/twig/twig/lib/Twig/Node/Set.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -14,7 +14,7 @@ * * @author Fabien Potencier */ -class Twig_Node_Set extends Twig_Node +class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface { public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterface $values, $lineno, $tag = null) { @@ -30,7 +30,7 @@ public function __construct($capture, Twig_NodeInterface $names, Twig_NodeInterf $values = $this->getNode('values'); if ($values instanceof Twig_Node_Text) { - $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getLine())); + $this->setNode('values', new Twig_Node_Expression_Constant($values->getAttribute('data'), $values->getTemplateLine())); $this->setAttribute('capture', false); } } diff --git a/vendor/twig/twig/lib/Twig/Node/SetTemp.php b/vendor/twig/twig/lib/Twig/Node/SetTemp.php index 3bdd1cb7..0f43c7d3 100644 --- a/vendor/twig/twig/lib/Twig/Node/SetTemp.php +++ b/vendor/twig/twig/lib/Twig/Node/SetTemp.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Spaceless.php b/vendor/twig/twig/lib/Twig/Node/Spaceless.php index 486e461a..00419e26 100644 --- a/vendor/twig/twig/lib/Twig/Node/Spaceless.php +++ b/vendor/twig/twig/lib/Twig/Node/Spaceless.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/Text.php b/vendor/twig/twig/lib/Twig/Node/Text.php index 39879bb2..2c013cd7 100644 --- a/vendor/twig/twig/lib/Twig/Node/Text.php +++ b/vendor/twig/twig/lib/Twig/Node/Text.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Node/With.php b/vendor/twig/twig/lib/Twig/Node/With.php new file mode 100644 index 00000000..4978f375 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Node/With.php @@ -0,0 +1,62 @@ + + */ +class Twig_Node_With extends Twig_Node +{ + public function __construct(Twig_Node $body, Twig_Node $variables = null, $only = false, $lineno, $tag = null) + { + $nodes = array('body' => $body); + if (null !== $variables) { + $nodes['variables'] = $variables; + } + + parent::__construct($nodes, array('only' => (bool) $only), $lineno, $tag); + } + + public function compile(Twig_Compiler $compiler) + { + $compiler->addDebugInfo($this); + + if ($this->hasNode('variables')) { + $varsName = $compiler->getVarName(); + $compiler + ->write(sprintf('$%s = ', $varsName)) + ->subcompile($this->getNode('variables')) + ->raw(";\n") + ->write(sprintf("if (!is_array(\$%s)) {\n", $varsName)) + ->indent() + ->write("throw new Twig_Error_Runtime('Variables passed to the \"with\" tag must be a hash.');\n") + ->outdent() + ->write("}\n") + ; + + if ($this->getAttribute('only')) { + $compiler->write("\$context = array('_parent' => \$context);\n"); + } else { + $compiler->write("\$context['_parent'] = \$context;\n"); + } + + $compiler->write(sprintf("\$context = array_merge(\$context, \$%s);\n", $varsName)); + } else { + $compiler->write("\$context['_parent'] = \$context;\n"); + } + + $compiler + ->subcompile($this->getNode('body')) + ->write("\$context = \$context['_parent'];\n") + ; + } +} diff --git a/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php b/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php new file mode 100644 index 00000000..97ffb6af --- /dev/null +++ b/vendor/twig/twig/lib/Twig/NodeCaptureInterface.php @@ -0,0 +1,19 @@ + + */ +interface Twig_NodeCaptureInterface +{ +} diff --git a/vendor/twig/twig/lib/Twig/NodeInterface.php b/vendor/twig/twig/lib/Twig/NodeInterface.php index 8077349b..78e758bd 100644 --- a/vendor/twig/twig/lib/Twig/NodeInterface.php +++ b/vendor/twig/twig/lib/Twig/NodeInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,11 +20,12 @@ interface Twig_NodeInterface extends Countable, IteratorAggregate { /** * Compiles the node to PHP. - * - * @param Twig_Compiler $compiler A Twig_Compiler instance */ public function compile(Twig_Compiler $compiler); + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function getLine(); public function getNodeTag(); diff --git a/vendor/twig/twig/lib/Twig/NodeOutputInterface.php b/vendor/twig/twig/lib/Twig/NodeOutputInterface.php index 22172c09..e6bbd964 100644 --- a/vendor/twig/twig/lib/Twig/NodeOutputInterface.php +++ b/vendor/twig/twig/lib/Twig/NodeOutputInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/NodeTraverser.php b/vendor/twig/twig/lib/Twig/NodeTraverser.php index 00f7b54b..35322174 100644 --- a/vendor/twig/twig/lib/Twig/NodeTraverser.php +++ b/vendor/twig/twig/lib/Twig/NodeTraverser.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -14,6 +14,8 @@ * * It visits all nodes and their children and calls the given visitor for each. * + * @final + * * @author Fabien Potencier */ class Twig_NodeTraverser @@ -22,10 +24,8 @@ class Twig_NodeTraverser protected $visitors = array(); /** - * Constructor. - * - * @param Twig_Environment $env A Twig_Environment instance - * @param Twig_NodeVisitorInterface[] $visitors An array of Twig_NodeVisitorInterface instances + * @param Twig_Environment $env + * @param Twig_NodeVisitorInterface[] $visitors */ public function __construct(Twig_Environment $env, array $visitors = array()) { @@ -35,11 +35,6 @@ public function __construct(Twig_Environment $env, array $visitors = array()) } } - /** - * Adds a visitor. - * - * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance - */ public function addVisitor(Twig_NodeVisitorInterface $visitor) { if (!isset($this->visitors[$visitor->getPriority()])) { @@ -52,8 +47,6 @@ public function addVisitor(Twig_NodeVisitorInterface $visitor) /** * Traverses a node and calls the registered visitors. * - * @param Twig_NodeInterface $node A Twig_NodeInterface instance - * * @return Twig_NodeInterface */ public function traverse(Twig_NodeInterface $node) diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php index 5c949777..7169f6f6 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,8 @@ /** * Twig_NodeVisitor_Escaper implements output escaping. * + * @final + * * @author Fabien Potencier */ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor @@ -28,16 +30,14 @@ public function __construct() $this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis(); } - /** - * {@inheritdoc} - */ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { - if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) { + if ($env->hasExtension('Twig_Extension_Escaper') && $defaultStrategy = $env->getExtension('Twig_Extension_Escaper')->getDefaultStrategy($node->getTemplateName())) { $this->defaultStrategy = $defaultStrategy; } $this->safeVars = array(); + $this->blocks = array(); } elseif ($node instanceof Twig_Node_AutoEscape) { $this->statusStack[] = $node->getAttribute('value'); } elseif ($node instanceof Twig_Node_Block) { @@ -49,14 +49,12 @@ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) return $node; } - /** - * {@inheritdoc} - */ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { $this->defaultStrategy = false; $this->safeVars = array(); + $this->blocks = array(); } elseif ($node instanceof Twig_Node_Expression_Filter) { return $this->preEscapeFilterNode($node, $env); } elseif ($node instanceof Twig_Node_Print) { @@ -88,7 +86,7 @@ protected function escapePrintNode(Twig_Node_Print $node, Twig_Environment $env, return new $class( $this->getEscaperFilter($type, $expression), - $node->getLine() + $node->getTemplateLine() ); } @@ -140,16 +138,13 @@ protected function needEscaping(Twig_Environment $env) protected function getEscaperFilter($type, Twig_NodeInterface $node) { - $line = $node->getLine(); + $line = $node->getTemplateLine(); $name = new Twig_Node_Expression_Constant('escape', $line); $args = new Twig_Node(array(new Twig_Node_Expression_Constant((string) $type, $line), new Twig_Node_Expression_Constant(null, $line), new Twig_Node_Expression_Constant(true, $line))); return new Twig_Node_Expression_Filter($node, $name, $args, $line); } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php index 872b7fea..43453c4d 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,6 +17,8 @@ * You can configure which optimizations you want to activate via the * optimizer mode. * + * @final + * * @author Fabien Potencier */ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor @@ -34,8 +36,6 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor protected $inABody = false; /** - * Constructor. - * * @param int $optimizers The optimizer mode */ public function __construct($optimizers = -1) @@ -47,16 +47,13 @@ public function __construct($optimizers = -1) $this->optimizers = $optimizers; } - /** - * {@inheritdoc} - */ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { $this->enterOptimizeFor($node, $env); } - if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) { if ($this->inABody) { if (!$node instanceof Twig_Node_Expression) { if (get_class($node) !== 'Twig_Node') { @@ -73,9 +70,6 @@ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) return $node; } - /** - * {@inheritdoc} - */ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { $expression = $node instanceof Twig_Node_Expression; @@ -90,14 +84,14 @@ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) $node = $this->optimizePrintNode($node, $env); - if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) { + if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('Twig_Extension_Sandbox')) { if ($node instanceof Twig_Node_Body) { $this->inABody = false; } elseif ($this->inABody) { if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) { $nodes = array(); foreach (array_unique($prependedNodes) as $name) { - $nodes[] = new Twig_Node_SetTemp($name, $node->getLine()); + $nodes[] = new Twig_Node_SetTemp($name, $node->getTemplateLine()); } $nodes[] = $node; @@ -114,7 +108,7 @@ protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) { $this->prependedNodes[0][] = $node->getAttribute('name'); - return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine()); + return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getTemplateLine()); } return $node; @@ -127,9 +121,6 @@ protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment * * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()" * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment - * * @return Twig_NodeInterface */ protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env) @@ -138,13 +129,14 @@ protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment return $node; } + $exprNode = $node->getNode('expr'); if ( - $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference || - $node->getNode('expr') instanceof Twig_Node_Expression_Parent + $exprNode instanceof Twig_Node_Expression_BlockReference || + $exprNode instanceof Twig_Node_Expression_Parent ) { - $node->getNode('expr')->setAttribute('output', true); + $exprNode->setAttribute('output', true); - return $node->getNode('expr'); + return $exprNode; } return $node; @@ -153,9 +145,6 @@ protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment /** * Removes "raw" filters. * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment - * * @return Twig_NodeInterface */ protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env) @@ -169,9 +158,6 @@ protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment /** * Optimizes "for" tag by removing the "loop" variable creation whenever possible. - * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment */ protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env) { @@ -236,9 +222,6 @@ protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $ /** * Optimizes "for" tag by removing the "loop" variable creation whenever possible. - * - * @param Twig_NodeInterface $node A Node - * @param Twig_Environment $env The current Twig environment */ protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env) { @@ -261,9 +244,6 @@ protected function addLoopToAll() } } - /** - * {@inheritdoc} - */ public function getPriority() { return 255; diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php index 439f5bf4..6997f357 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php @@ -9,6 +9,9 @@ * file that was distributed with this source code. */ +/** + * @final + */ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor { protected $data = array(); @@ -57,17 +60,11 @@ protected function setSafe(Twig_NodeInterface $node, array $safe) ); } - /** - * {@inheritdoc} - */ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { return $node; } - /** - * {@inheritdoc} - */ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Expression_Constant) { @@ -144,9 +141,6 @@ protected function intersectSafe(array $a = null, array $b = null) return array_intersect($a, $b); } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; diff --git a/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php index 7f1b913b..baf00a03 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,8 @@ /** * Twig_NodeVisitor_Sandbox implements sandboxing. * + * @final + * * @author Fabien Potencier */ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor @@ -21,9 +23,6 @@ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor protected $filters; protected $functions; - /** - * {@inheritdoc} - */ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { @@ -51,16 +50,13 @@ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) // wrap print to check __toString() calls if ($node instanceof Twig_Node_Print) { - return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag()); + return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getTemplateLine(), $node->getNodeTag()); } } return $node; } - /** - * {@inheritdoc} - */ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { @@ -72,9 +68,6 @@ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) return $node; } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; diff --git a/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php index f2761630..092d36ae 100644 --- a/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php +++ b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,9 +19,6 @@ interface Twig_NodeVisitorInterface /** * Called before child nodes are visited. * - * @param Twig_NodeInterface $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * * @return Twig_NodeInterface The modified node */ public function enterNode(Twig_NodeInterface $node, Twig_Environment $env); @@ -29,9 +26,6 @@ public function enterNode(Twig_NodeInterface $node, Twig_Environment $env); /** * Called after child nodes are visited. * - * @param Twig_NodeInterface $node The node to visit - * @param Twig_Environment $env The Twig environment instance - * * @return Twig_NodeInterface|false The modified node or false if the node must be removed */ public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env); diff --git a/vendor/twig/twig/lib/Twig/Parser.php b/vendor/twig/twig/lib/Twig/Parser.php index 4628d67d..070f301b 100644 --- a/vendor/twig/twig/lib/Twig/Parser.php +++ b/vendor/twig/twig/lib/Twig/Parser.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,18 +32,18 @@ class Twig_Parser implements Twig_ParserInterface protected $traits; protected $embeddedTemplates = array(); - /** - * Constructor. - * - * @param Twig_Environment $env A Twig_Environment instance - */ public function __construct(Twig_Environment $env) { $this->env = $env; } + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function getEnvironment() { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED); + return $this->env; } @@ -52,18 +52,21 @@ public function getVarName() return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); } + /** + * @deprecated since 1.27 (to be removed in 2.0). Use $parser->getStream()->getSourceContext()->getPath() instead. + */ public function getFilename() { - return $this->stream->getFilename(); + @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->stream->getSourceContext()->getName(); } - /** - * {@inheritdoc} - */ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false) { // push all variables into the stack to keep the current state of the parser // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336 + // This hack can be removed when min version if PHP 7.0 $vars = array(); foreach ($this as $k => $v) { $vars[$k] = $v; @@ -84,7 +87,7 @@ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = fals } if (null === $this->expressionParser) { - $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators()); + $this->expressionParser = new Twig_ExpressionParser($this, $this->env); } $this->stream = $stream; @@ -103,8 +106,8 @@ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = fals $body = new Twig_Node(); } } catch (Twig_Error_Syntax $e) { - if (!$e->getTemplateFile()) { - $e->setTemplateFile($this->getFilename()); + if (!$e->getSourceContext()) { + $e->setSourceContext($this->stream->getSourceContext()); } if (!$e->getTemplateLine()) { @@ -114,7 +117,7 @@ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = fals throw $e; } - $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename()); + $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext()); $traverser = new Twig_NodeTraverser($this->env, $this->visitors); @@ -151,7 +154,7 @@ public function subparse($test, $dropNeedle = false) $token = $this->getCurrentToken(); if ($token->getType() !== Twig_Token::NAME_TYPE) { - throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->getFilename()); + throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext()); } if (null !== $test && call_user_func($test, $token)) { @@ -169,13 +172,13 @@ public function subparse($test, $dropNeedle = false) $subparser = $this->handlers->getTokenParser($token->getValue()); if (null === $subparser) { if (null !== $test) { - $e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->getFilename()); + $e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()); if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) { $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno)); } } else { - $e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->getFilename()); + $e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()); $e->addSuggestions($token->getValue(), array_keys($this->env->getTags())); } @@ -191,7 +194,7 @@ public function subparse($test, $dropNeedle = false) break; default: - throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename()); + throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext()); } } @@ -202,13 +205,23 @@ public function subparse($test, $dropNeedle = false) return new Twig_Node($rv, array(), $lineno); } + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function addHandler($name, $class) { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED); + $this->handlers[$name] = $class; } + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED); + $this->visitors[] = $visitor; } @@ -244,7 +257,7 @@ public function getBlock($name) public function setBlock($name, Twig_Node_Block $value) { - $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine()); + $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getTemplateLine()); } public function hasMacro($name) @@ -255,7 +268,7 @@ public function hasMacro($name) public function setMacro($name, Twig_Node_Macro $node) { if ($this->isReservedMacroName($name)) { - throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getLine(), $this->getFilename()); + throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext()); } $this->macros[$name] = $node; @@ -325,9 +338,7 @@ public function popLocalScope() } /** - * Gets the expression parser. - * - * @return Twig_ExpressionParser The expression parser + * @return Twig_ExpressionParser */ public function getExpressionParser() { @@ -345,9 +356,7 @@ public function setParent($parent) } /** - * Gets the token stream. - * - * @return Twig_TokenStream The token stream + * @return Twig_TokenStream */ public function getStream() { @@ -355,9 +364,7 @@ public function getStream() } /** - * Gets the current token. - * - * @return Twig_Token The current token + * @return Twig_Token */ public function getCurrentToken() { @@ -373,14 +380,14 @@ protected function filterBodyNodes(Twig_NodeInterface $node) (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface) ) { if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) { - throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename()); + throw new Twig_Error_Syntax('A template that extends another one cannot start with a byte order mark (BOM); it must be removed.', $node->getTemplateLine(), $this->stream->getSourceContext()); } - throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename()); + throw new Twig_Error_Syntax('A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext()); } - // bypass "set" nodes as they "capture" the output - if ($node instanceof Twig_Node_Set) { + // bypass nodes that will "capture" the output + if ($node instanceof Twig_NodeCaptureInterface) { return $node; } diff --git a/vendor/twig/twig/lib/Twig/ParserInterface.php b/vendor/twig/twig/lib/Twig/ParserInterface.php index 8e7cc0a8..85c6e67b 100644 --- a/vendor/twig/twig/lib/Twig/ParserInterface.php +++ b/vendor/twig/twig/lib/Twig/ParserInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,9 +21,7 @@ interface Twig_ParserInterface /** * Converts a token stream to a node tree. * - * @param Twig_TokenStream $stream A token stream instance - * - * @return Twig_Node_Module A node tree + * @return Twig_Node_Module * * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong */ diff --git a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php index b82747a9..6be67edf 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * @author Fabien Potencier + * + * @final */ class Twig_Profiler_Dumper_Blackfire { diff --git a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php index f066da75..f0fa406a 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * @author Fabien Potencier + * + * @final */ class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text { diff --git a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php index 998e210d..c77e6918 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * @author Fabien Potencier + * + * @final */ class Twig_Profiler_Dumper_Text { diff --git a/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php b/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php index 2f972148..e10d857e 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,9 +21,6 @@ public function __construct($extensionName, $type, $name, $varName) parent::__construct(array(), array('extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName)); } - /** - * {@inheritdoc} - */ public function compile(Twig_Compiler $compiler) { $compiler diff --git a/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php b/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php index 88074c2f..e4d0beb4 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,9 +21,6 @@ public function __construct($varName) parent::__construct(array(), array('var_name' => $varName)); } - /** - * {@inheritdoc} - */ public function compile(Twig_Compiler $compiler) { $compiler diff --git a/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php b/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php index 4b0baa82..a9904748 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +++ b/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * @author Fabien Potencier + * + * @final */ class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor { @@ -21,22 +23,16 @@ public function __construct($extensionName) $this->extensionName = $extensionName; } - /** - * {@inheritdoc} - */ protected function doEnterNode(Twig_Node $node, Twig_Environment $env) { return $node; } - /** - * {@inheritdoc} - */ protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { $varName = $this->getVarName(); - $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getAttribute('filename'), $varName), $node->getNode('display_start')))); + $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')))); $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end')))); } elseif ($node instanceof Twig_Node_Block) { $varName = $this->getVarName(); @@ -62,9 +58,6 @@ private function getVarName() return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); } - /** - * {@inheritdoc} - */ public function getPriority() { return 0; diff --git a/vendor/twig/twig/lib/Twig/Profiler/Profile.php b/vendor/twig/twig/lib/Twig/Profiler/Profile.php index 104bc058..9274da28 100644 --- a/vendor/twig/twig/lib/Twig/Profiler/Profile.php +++ b/vendor/twig/twig/lib/Twig/Profiler/Profile.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2015 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * @author Fabien Potencier + * + * @final */ class Twig_Profiler_Profile implements IteratorAggregate, Serializable { diff --git a/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php b/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php new file mode 100644 index 00000000..c41f44af --- /dev/null +++ b/vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php @@ -0,0 +1,27 @@ + + */ +interface Twig_RuntimeLoaderInterface +{ + /** + * Creates the runtime implementation of a Twig element (filter/function/test). + * + * @param string $class A runtime class + * + * @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class + */ + public function load($class); +} diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php index 015bfaea..5a4e021d 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php index 99faba9d..1967cf76 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php index 05cf488a..79a400f1 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php new file mode 100644 index 00000000..9e5d4df0 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php @@ -0,0 +1,38 @@ + + */ +class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityError +{ + private $className; + private $methodName; + + public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, $lineno, $filename, $previous); + $this->className = $className; + $this->methodName = $methodName; + } + + public function getClassName() + { + return $this->className; + } + + public function getMethodName() + { + return $this->methodName; + } +} diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php new file mode 100644 index 00000000..9f7eab29 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php @@ -0,0 +1,38 @@ + + */ +class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_SecurityError +{ + private $className; + private $propertyName; + + public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, $lineno, $filename, $previous); + $this->className = $className; + $this->propertyName = $propertyName; + } + + public function getClassName() + { + return $this->className; + } + + public function getPropertyName() + { + return $this->propertyName; + } +} diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php index b3bb5e8e..a177206c 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php index c4dd03df..4470c39f 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,8 @@ /** * Represents a security policy which need to be enforced when sandbox mode is enabled. * + * @final + * * @author Fabien Potencier */ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface @@ -97,7 +99,8 @@ public function checkMethodAllowed($obj, $method) } if (!$allowed) { - throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); + $class = get_class($obj); + throw new Twig_Sandbox_SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method); } } @@ -113,7 +116,8 @@ public function checkPropertyAllowed($obj, $property) } if (!$allowed) { - throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, get_class($obj))); + $class = get_class($obj); + throw new Twig_Sandbox_SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property); } } } diff --git a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php index 6ab48e3c..2111a03c 100644 --- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php +++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/SimpleFilter.php b/vendor/twig/twig/lib/Twig/SimpleFilter.php index 0c1e092a..a0b98af3 100644 --- a/vendor/twig/twig/lib/Twig/SimpleFilter.php +++ b/vendor/twig/twig/lib/Twig/SimpleFilter.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009-2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,8 @@ /** * Represents a template filter. * + * @final + * * @author Fabien Potencier */ class Twig_SimpleFilter diff --git a/vendor/twig/twig/lib/Twig/SimpleFunction.php b/vendor/twig/twig/lib/Twig/SimpleFunction.php index 63003d6a..b7ef92a5 100644 --- a/vendor/twig/twig/lib/Twig/SimpleFunction.php +++ b/vendor/twig/twig/lib/Twig/SimpleFunction.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010-2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,8 @@ /** * Represents a template function. * + * @final + * * @author Fabien Potencier */ class Twig_SimpleFunction diff --git a/vendor/twig/twig/lib/Twig/SimpleTest.php b/vendor/twig/twig/lib/Twig/SimpleTest.php index cff3ae7c..b9ae8f14 100644 --- a/vendor/twig/twig/lib/Twig/SimpleTest.php +++ b/vendor/twig/twig/lib/Twig/SimpleTest.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010-2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,6 +12,8 @@ /** * Represents a template test. * + * @final + * * @author Fabien Potencier */ class Twig_SimpleTest diff --git a/vendor/twig/twig/lib/Twig/Source.php b/vendor/twig/twig/lib/Twig/Source.php new file mode 100644 index 00000000..389317ec --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Source.php @@ -0,0 +1,51 @@ + + */ +class Twig_Source +{ + private $code; + private $name; + private $path; + + /** + * @param string $code The template source code + * @param string $name The template logical name + * @param string $path The filesystem path of the template if any + */ + public function __construct($code, $name, $path = '') + { + $this->code = $code; + $this->name = $name; + $this->path = $path; + } + + public function getCode() + { + return $this->code; + } + + public function getName() + { + return $this->name; + } + + public function getPath() + { + return $this->path; + } +} diff --git a/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php b/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php new file mode 100644 index 00000000..acf21e37 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php @@ -0,0 +1,31 @@ + + * + * @deprecated since 1.27 (to be removed in 3.0) + */ +interface Twig_SourceContextLoaderInterface +{ + /** + * Returns the source context for a given template logical name. + * + * @param string $name The template logical name + * + * @return Twig_Source + * + * @throws Twig_Error_Loader When $name is not found + */ + public function getSourceContext($name); +} diff --git a/vendor/twig/twig/lib/Twig/Template.php b/vendor/twig/twig/lib/Twig/Template.php index a8160227..f1855f11 100644 --- a/vendor/twig/twig/lib/Twig/Template.php +++ b/vendor/twig/twig/lib/Twig/Template.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,10 +13,19 @@ /** * Default base class for compiled templates. * + * This class is an implementation detail of how template compilation currently + * works, which might change. It should never be used directly. Use $twig->load() + * instead, which returns an instance of Twig_TemplateWrapper. + * * @author Fabien Potencier + * + * @internal */ abstract class Twig_Template implements Twig_TemplateInterface { + /** + * @internal + */ protected static $cache = array(); protected $parent; @@ -25,16 +34,19 @@ abstract class Twig_Template implements Twig_TemplateInterface protected $blocks = array(); protected $traits = array(); - /** - * Constructor. - * - * @param Twig_Environment $env A Twig_Environment instance - */ public function __construct(Twig_Environment $env) { $this->env = $env; } + /** + * @internal this method will be removed in 2.0 and is only used internally to provide an upgrade path from 1.x to 2.0 + */ + public function __toString() + { + return $this->getTemplateName(); + } + /** * Returns the template name. * @@ -42,6 +54,42 @@ public function __construct(Twig_Environment $env) */ abstract public function getTemplateName(); + /** + * Returns debug information about the template. + * + * @return array Debug information + * + * @internal + */ + public function getDebugInfo() + { + return array(); + } + + /** + * Returns the template source code. + * + * @return string The template source code + * + * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead + */ + public function getSource() + { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED); + + return ''; + } + + /** + * Returns information about the original template source code. + * + * @return Twig_Source + */ + public function getSourceContext() + { + return new Twig_Source('', $this->getTemplateName()); + } + /** * @deprecated since 1.20 (to be removed in 2.0) */ @@ -85,7 +133,7 @@ public function getParent(array $context) $this->parents[$parent] = $this->loadTemplate($parent); } } catch (Twig_Error_Loader $e) { - $e->setTemplateFile(null); + $e->setSourceContext(null); $e->guess(); throw $e; @@ -125,7 +173,7 @@ public function displayParentBlock($name, array $context, array $blocks = array( } elseif (false !== $parent = $this->getParent($context)) { $parent->displayBlock($name, $context, $blocks, false); } else { - throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName()); + throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext()); } } @@ -157,17 +205,17 @@ public function displayBlock($name, array $context, array $blocks = array(), $us $block = null; } - if (null !== $template) { - // avoid RCEs when sandbox is enabled - if (!$template instanceof self) { - throw new LogicException('A block must be a method on a Twig_Template instance.'); - } + // avoid RCEs when sandbox is enabled + if (null !== $template && !$template instanceof self) { + throw new LogicException('A block must be a method on a Twig_Template instance.'); + } + if (null !== $template) { try { $template->$block($context, $blocks); } catch (Twig_Error $e) { - if (!$e->getTemplateFile()) { - $e->setTemplateFile($template->getTemplateName()); + if (!$e->getSourceContext()) { + $e->setSourceContext($template->getSourceContext()); } // this is mostly useful for Twig_Error_Loader exceptions @@ -179,10 +227,12 @@ public function displayBlock($name, array $context, array $blocks = array(), $us throw $e; } catch (Exception $e) { - throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e); + throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e); } } elseif (false !== $parent = $this->getParent($context)) { $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false); + } else { + @trigger_error(sprintf('Silent display of undefined block "%s" in template "%s" is deprecated since version 1.29 and will throw an exception in 2.0. Use the "block(\'%s\') is defined" expression to test for block existence.', $name, $this->getTemplateName(), $name), E_USER_DEPRECATED); } } @@ -232,44 +282,70 @@ public function renderBlock($name, array $context, array $blocks = array(), $use } /** - * Returns whether a block exists or not. - * - * This method is for internal use only and should never be called - * directly. + * Returns whether a block exists or not in the current context of the template. * - * This method does only return blocks defined in the current template - * or defined in "used" traits. + * This method checks blocks defined in the current template + * or defined in "used" traits or defined in parent templates. * - * It does not return blocks from parent templates as the parent - * template name can be dynamic, which is only known based on the - * current context. - * - * @param string $name The block name + * @param string $name The block name + * @param array $context The context + * @param array $blocks The current set of blocks * * @return bool true if the block exists, false otherwise * * @internal */ - public function hasBlock($name) + public function hasBlock($name, array $context = null, array $blocks = array()) { - return isset($this->blocks[(string) $name]); + if (null === $context) { + @trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED); + + return isset($this->blocks[(string) $name]); + } + + if (isset($blocks[$name])) { + return $blocks[$name][0] instanceof self; + } + + if (isset($this->blocks[$name])) { + return true; + } + + if (false !== $parent = $this->getParent($context)) { + return $parent->hasBlock($name, $context); + } + + return false; } /** - * Returns all block names. + * Returns all block names in the current context of the template. * - * This method is for internal use only and should never be called - * directly. + * This method checks blocks defined in the current template + * or defined in "used" traits or defined in parent templates. * - * @return array An array of block names + * @param array $context The context + * @param array $blocks The current set of blocks * - * @see hasBlock + * @return array An array of block names * * @internal */ - public function getBlockNames() + public function getBlockNames(array $context = null, array $blocks = array()) { - return array_keys($this->blocks); + if (null === $context) { + @trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', E_USER_DEPRECATED); + + return array_keys($this->blocks); + } + + $names = array_merge(array_keys($blocks), array_keys($this->blocks)); + + if (false !== $parent = $this->getParent($context)) { + $names = array_merge($names, $parent->getBlockNames($context)); + } + + return array_unique($names); } protected function loadTemplate($template, $templateName = null, $line = null, $index = null) @@ -283,10 +359,14 @@ protected function loadTemplate($template, $templateName = null, $line = null, $ return $template; } + if ($template instanceof Twig_TemplateWrapper) { + return $template; + } + return $this->env->loadTemplate($template, $index); } catch (Twig_Error $e) { - if (!$e->getTemplateFile()) { - $e->setTemplateFile($templateName ? $templateName : $this->getTemplateName()); + if (!$e->getSourceContext()) { + $e->setSourceContext($templateName ? new Twig_Source('', $templateName) : $this->getSourceContext()); } if ($e->getTemplateLine()) { @@ -311,8 +391,6 @@ protected function loadTemplate($template, $templateName = null, $line = null, $ * * @return array An array of blocks * - * @see hasBlock - * * @internal */ public function getBlocks() @@ -320,44 +398,11 @@ public function getBlocks() return $this->blocks; } - /** - * Returns the template source code. - * - * @return string|null The template source code or null if it is not available - */ - public function getSource() - { - $reflector = new ReflectionClass($this); - $file = $reflector->getFileName(); - - if (!file_exists($file)) { - return; - } - - $source = file($file, FILE_IGNORE_NEW_LINES); - array_splice($source, 0, $reflector->getEndLine()); - - $i = 0; - while (isset($source[$i]) && '/* */' === substr_replace($source[$i], '', 3, -2)) { - $source[$i] = str_replace('*//* ', '*/', substr($source[$i], 3, -2)); - ++$i; - } - array_splice($source, $i); - - return implode("\n", $source); - } - - /** - * {@inheritdoc} - */ public function display(array $context, array $blocks = array()) { $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks)); } - /** - * {@inheritdoc} - */ public function render(array $context) { $level = ob_get_level(); @@ -369,6 +414,12 @@ public function render(array $context) ob_end_clean(); } + throw $e; + } catch (Throwable $e) { + while (ob_get_level() > $level) { + ob_end_clean(); + } + throw $e; } @@ -380,8 +431,8 @@ protected function displayWithErrorHandling(array $context, array $blocks = arra try { $this->doDisplay($context, $blocks); } catch (Twig_Error $e) { - if (!$e->getTemplateFile()) { - $e->setTemplateFile($this->getTemplateName()); + if (!$e->getSourceContext()) { + $e->setSourceContext($this->getSourceContext()); } // this is mostly useful for Twig_Error_Loader exceptions @@ -393,7 +444,7 @@ protected function displayWithErrorHandling(array $context, array $blocks = arra throw $e; } catch (Exception $e) { - throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e); + throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e); } } @@ -433,7 +484,7 @@ final protected function getContext($context, $item, $ignoreStrictCheck = false) return; } - throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName()); + throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist.', $item), -1, $this->getSourceContext()); } return $context[$item]; @@ -452,6 +503,8 @@ final protected function getContext($context, $item, $ignoreStrictCheck = false) * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true * * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false + * + * @internal */ protected function getAttribute($object, $item, array $arguments = array(), $type = self::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) { @@ -459,7 +512,7 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ if (self::METHOD_CALL !== $type) { $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item; - if ((is_array($object) && array_key_exists($arrayItem, $object)) + if ((is_array($object) && (isset($object[$arrayItem]) || array_key_exists($arrayItem, $object))) || ($object instanceof ArrayAccess && isset($object[$arrayItem])) ) { if ($isDefinedTest) { @@ -479,28 +532,28 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ } if ($object instanceof ArrayAccess) { - $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object)); + $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, get_class($object)); } elseif (is_object($object)) { - $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object)); + $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, get_class($object)); } elseif (is_array($object)) { if (empty($object)) { - $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem); + $message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem); } else { - $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))); + $message = sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object))); } } elseif (self::ARRAY_CALL === $type) { if (null === $object) { - $message = sprintf('Impossible to access a key ("%s") on a null variable', $item); + $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item); } else { - $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object); + $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, gettype($object), $object); } } elseif (null === $object) { - $message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item); + $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item); } else { - $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object); + $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, gettype($object), $object); } - throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); + throw new Twig_Error_Runtime($message, -1, $this->getSourceContext()); } } @@ -514,12 +567,12 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ } if (null === $object) { - $message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item); + $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item); } else { - $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object); + $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, gettype($object), $object); } - throw new Twig_Error_Runtime($message, -1, $this->getTemplateName()); + throw new Twig_Error_Runtime($message, -1, $this->getSourceContext()); } // object property @@ -529,8 +582,8 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ return true; } - if ($this->env->hasExtension('sandbox')) { - $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item); + if ($this->env->hasExtension('Twig_Extension_Sandbox')) { + $this->env->getExtension('Twig_Extension_Sandbox')->checkPropertyAllowed($object, $item); } return $object->$item; @@ -540,37 +593,57 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ $class = get_class($object); // object method - if (!isset(self::$cache[$class]['methods'])) { + if (!isset(self::$cache[$class])) { // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates if ($object instanceof self) { $ref = new ReflectionClass($class); $methods = array(); foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) { - $methodName = strtolower($refMethod->name); - // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment - if ('getenvironment' !== $methodName) { - $methods[$methodName] = true; + if ('getenvironment' !== strtolower($refMethod->name)) { + $methods[] = $refMethod->name; } } - - self::$cache[$class]['methods'] = $methods; } else { - self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object))); + $methods = get_class_methods($object); + } + // sort values to have consistent behavior, so that "get" methods win precedence over "is" methods + sort($methods); + + $cache = array(); + + foreach ($methods as $method) { + $cache[$method] = $method; + $cache[$lcName = strtolower($method)] = $method; + + if ('g' === $lcName[0] && 0 === strpos($lcName, 'get')) { + $name = substr($method, 3); + $lcName = substr($lcName, 3); + } elseif ('i' === $lcName[0] && 0 === strpos($lcName, 'is')) { + $name = substr($method, 2); + $lcName = substr($lcName, 2); + } else { + continue; + } + + if (!isset($cache[$name])) { + $cache[$name] = $method; + } + if (!isset($cache[$lcName])) { + $cache[$lcName] = $method; + } } + self::$cache[$class] = $cache; } $call = false; - $lcItem = strtolower($item); - if (isset(self::$cache[$class]['methods'][$lcItem])) { - $method = (string) $item; - } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) { - $method = 'get'.$item; - } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) { - $method = 'is'.$item; - } elseif (isset(self::$cache[$class]['methods']['__call'])) { - $method = (string) $item; + if (isset(self::$cache[$class][$item])) { + $method = self::$cache[$class][$item]; + } elseif (isset(self::$cache[$class][$lcItem = strtolower($item)])) { + $method = self::$cache[$class][$lcItem]; + } elseif (isset(self::$cache[$class]['__call'])) { + $method = $item; $call = true; } else { if ($isDefinedTest) { @@ -581,21 +654,25 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ return; } - throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName()); + throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getSourceContext()); } if ($isDefinedTest) { return true; } - if ($this->env->hasExtension('sandbox')) { - $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method); + if ($this->env->hasExtension('Twig_Extension_Sandbox')) { + $this->env->getExtension('Twig_Extension_Sandbox')->checkMethodAllowed($object, $method); } // Some objects throw exceptions when they have __call, and the method we try // to call is not supported. If ignoreStrictCheck is true, we should return null. try { - $ret = call_user_func_array(array($object, $method), $arguments); + if (!$arguments) { + $ret = $object->$method(); + } else { + $ret = call_user_func_array(array($object, $method), $arguments); + } } catch (BadMethodCallException $e) { if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) { return; @@ -603,9 +680,19 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ throw $e; } - // useful when calling a template method from a template - // this is not supported but unfortunately heavily used in the Symfony profiler + // @deprecated in 1.28 if ($object instanceof Twig_TemplateInterface) { + $self = $object->getTemplateName() === $this->getTemplateName(); + $message = sprintf('Calling "%s" on template "%s" from template "%s" is deprecated since version 1.28 and won\'t be supported anymore in 2.0.', $item, $object->getTemplateName(), $this->getTemplateName()); + if ('renderBlock' === $method || 'displayBlock' === $method) { + $message .= sprintf(' Use block("%s"%s) instead).', $arguments[0], $self ? '' : ', template'); + } elseif ('hasBlock' === $method) { + $message .= sprintf(' Use "block("%s"%s) is defined" instead).', $arguments[0], $self ? '' : ', template'); + } elseif ('render' === $method || 'display' === $method) { + $message .= sprintf(' Use include("%s") instead).', $object->getTemplateName()); + } + @trigger_error($message, E_USER_DEPRECATED); + return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset()); } diff --git a/vendor/twig/twig/lib/Twig/TemplateInterface.php b/vendor/twig/twig/lib/Twig/TemplateInterface.php index 32746407..457ef7d7 100644 --- a/vendor/twig/twig/lib/Twig/TemplateInterface.php +++ b/vendor/twig/twig/lib/Twig/TemplateInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -42,7 +42,7 @@ public function display(array $context, array $blocks = array()); /** * Returns the bound environment for this template. * - * @return Twig_Environment The current environment + * @return Twig_Environment */ public function getEnvironment(); } diff --git a/vendor/twig/twig/lib/Twig/TemplateWrapper.php b/vendor/twig/twig/lib/Twig/TemplateWrapper.php new file mode 100644 index 00000000..b72b92c2 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/TemplateWrapper.php @@ -0,0 +1,131 @@ + + */ +final class Twig_TemplateWrapper +{ + private $env; + private $template; + + /** + * This method is for internal use only and should never be called + * directly (use Twig_Environment::load() instead). + * + * @internal + */ + public function __construct(Twig_Environment $env, Twig_Template $template) + { + $this->env = $env; + $this->template = $template; + } + + /** + * Renders the template. + * + * @param array $context An array of parameters to pass to the template + * + * @return string The rendered template + */ + public function render($context = array()) + { + return $this->template->render($context); + } + + /** + * Displays the template. + * + * @param array $context An array of parameters to pass to the template + */ + public function display($context = array()) + { + $this->template->display($context); + } + + /** + * Checks if a block is defined. + * + * @param string $name The block name + * @param array $context An array of parameters to pass to the template + * + * @return bool + */ + public function hasBlock($name, $context = array()) + { + return $this->template->hasBlock($name, $context); + } + + /** + * Returns defined block names in the template. + * + * @param array $context An array of parameters to pass to the template + * + * @return string[] An array of defined template block names + */ + public function getBlockNames($context = array()) + { + return $this->template->getBlockNames($context); + } + + /** + * Renders a template block. + * + * @param string $name The block name to render + * @param array $context An array of parameters to pass to the template + * + * @return string The rendered block + */ + public function renderBlock($name, $context = array()) + { + $context = $this->env->mergeGlobals($context); + $level = ob_get_level(); + ob_start(); + try { + $this->template->displayBlock($name, $context); + } catch (Exception $e) { + while (ob_get_level() > $level) { + ob_end_clean(); + } + + throw $e; + } catch (Throwable $e) { + while (ob_get_level() > $level) { + ob_end_clean(); + } + + throw $e; + } + + return ob_get_clean(); + } + + /** + * Displays a template block. + * + * @param string $name The block name to render + * @param array $context An array of parameters to pass to the template + */ + public function displayBlock($name, $context = array()) + { + $this->template->displayBlock($name, $this->env->mergeGlobals($context)); + } + + /** + * @return Twig_Source + */ + public function getSourceContext() + { + return $this->template->getSourceContext(); + } +} diff --git a/vendor/twig/twig/lib/Twig/Test.php b/vendor/twig/twig/lib/Twig/Test.php index 3c2d8590..b450ec62 100644 --- a/vendor/twig/twig/lib/Twig/Test.php +++ b/vendor/twig/twig/lib/Twig/Test.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Test/Function.php b/vendor/twig/twig/lib/Twig/Test/Function.php index 5e76c711..9e83c3f8 100644 --- a/vendor/twig/twig/lib/Twig/Test/Function.php +++ b/vendor/twig/twig/lib/Twig/Test/Function.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php index 45ca7dc4..ca0f3594 100644 --- a/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +++ b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -167,17 +167,12 @@ protected function doIntegrationTest($file, $message, $condition, $templates, $e if (false !== $exception) { $message = $e->getMessage(); $this->assertSame(trim($exception), trim(sprintf('%s: %s', get_class($e), $message))); - $this->assertSame('.', substr($message, strlen($message) - 1), $message, 'Exception message must end with a dot.'); + $last = substr($message, strlen($message) - 1); + $this->assertTrue('.' === $last || '?' === $last, $message, 'Exception message must end with a dot or a question mark.'); return; } - if ($e instanceof Twig_Error_Syntax) { - $e->setTemplateFile($file); - - throw $e; - } - throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); } @@ -190,11 +185,7 @@ protected function doIntegrationTest($file, $message, $condition, $templates, $e return; } - if ($e instanceof Twig_Error_Syntax) { - $e->setTemplateFile($file); - } else { - $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); - } + $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e); $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage())); } @@ -211,8 +202,13 @@ protected function doIntegrationTest($file, $message, $condition, $templates, $e foreach (array_keys($templates) as $name) { echo "Template: $name\n"; - $source = $loader->getSource($name); - echo $twig->compile($twig->parse($twig->tokenize($source, $name))); + $loader = $twig->getLoader(); + if (!$loader instanceof Twig_SourceContextLoaderInterface) { + $source = new Twig_Source($loader->getSource($name), $name); + } else { + $source = $loader->getSourceContext($name); + } + echo $twig->compile($twig->parse($twig->tokenize($source))); } } $this->assertEquals($expected, $output, $message.' (in '.$file.')'); diff --git a/vendor/twig/twig/lib/Twig/Test/Method.php b/vendor/twig/twig/lib/Twig/Test/Method.php index 27799864..feccd5db 100644 --- a/vendor/twig/twig/lib/Twig/Test/Method.php +++ b/vendor/twig/twig/lib/Twig/Test/Method.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -35,6 +35,6 @@ public function __construct(Twig_ExtensionInterface $extension, $method, array $ public function compile() { - return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method); + return sprintf('$this->env->getExtension(\'%s\')->%s', get_class($this->extension), $this->method); } } diff --git a/vendor/twig/twig/lib/Twig/Test/Node.php b/vendor/twig/twig/lib/Twig/Test/Node.php index baef49cc..6098a527 100644 --- a/vendor/twig/twig/lib/Twig/Test/Node.php +++ b/vendor/twig/twig/lib/Twig/Test/Node.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php index e591c1d5..a6b550cf 100644 --- a/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php +++ b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php @@ -46,6 +46,10 @@ protected function getVariableGetter($name, $line = false) { $line = $line > 0 ? "// line {$line}\n" : ''; + if (PHP_VERSION_ID >= 70000) { + return sprintf('%s($context["%s"] ?? null)', $line, $name, $name); + } + if (PHP_VERSION_ID >= 50400) { return sprintf('%s(isset($context["%s"]) ? $context["%s"] : null)', $line, $name, $name); } diff --git a/vendor/twig/twig/lib/Twig/TestCallableInterface.php b/vendor/twig/twig/lib/Twig/TestCallableInterface.php index 98d34578..51ecb9a2 100644 --- a/vendor/twig/twig/lib/Twig/TestCallableInterface.php +++ b/vendor/twig/twig/lib/Twig/TestCallableInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/TestInterface.php b/vendor/twig/twig/lib/Twig/TestInterface.php index 2fa821ca..91664075 100644 --- a/vendor/twig/twig/lib/Twig/TestInterface.php +++ b/vendor/twig/twig/lib/Twig/TestInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/vendor/twig/twig/lib/Twig/Token.php b/vendor/twig/twig/lib/Twig/Token.php index a0a029bc..717ab087 100644 --- a/vendor/twig/twig/lib/Twig/Token.php +++ b/vendor/twig/twig/lib/Twig/Token.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -14,6 +14,8 @@ * Represents a Token. * * @author Fabien Potencier + * + * @final */ class Twig_Token { @@ -36,8 +38,6 @@ class Twig_Token const INTERPOLATION_END_TYPE = 11; /** - * Constructor. - * * @param int $type The type of the token * @param string $value The token value * @param int $lineno The line position in the source @@ -49,11 +49,6 @@ public function __construct($type, $value, $lineno) $this->lineno = $lineno; } - /** - * Returns a string representation of the token. - * - * @return string A string representation of the token - */ public function __toString() { return sprintf('%s(%s)', self::typeToString($this->type, true), $this->value); @@ -63,9 +58,9 @@ public function __toString() * Tests the current token for a type and/or a value. * * Parameters may be: - * * just type - * * type and value (or array of possible values) - * * just value (or array of possible values) (NAME_TYPE is used as type) + * * just type + * * type and value (or array of possible values) + * * just value (or array of possible values) (NAME_TYPE is used as type) * * @param array|int $type The type to test * @param array|string|null $values The token value @@ -87,9 +82,7 @@ public function test($type, $values = null) } /** - * Gets the line. - * - * @return int The source line + * @return int */ public function getLine() { @@ -97,9 +90,7 @@ public function getLine() } /** - * Gets the token type. - * - * @return int The token type + * @return int */ public function getType() { @@ -107,9 +98,7 @@ public function getType() } /** - * Gets the token value. - * - * @return string The token value + * @return string */ public function getValue() { @@ -174,7 +163,7 @@ public static function typeToString($type, $short = false) } /** - * Returns the english representation of a given type. + * Returns the English representation of a given type. * * @param int $type The type as an integer * diff --git a/vendor/twig/twig/lib/Twig/TokenParser.php b/vendor/twig/twig/lib/Twig/TokenParser.php index fa9b6d86..700a227f 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser.php +++ b/vendor/twig/twig/lib/Twig/TokenParser.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,8 +23,6 @@ abstract class Twig_TokenParser implements Twig_TokenParserInterface /** * Sets the parser associated with this token parser. - * - * @param Twig_Parser $parser A Twig_Parser instance */ public function setParser(Twig_Parser $parser) { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php b/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php index fd34cafe..176820ea 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,6 +26,8 @@ * using the js escaping strategy * {% endautoescape %} * + * + * @final */ class Twig_TokenParser_AutoEscape extends Twig_TokenParser { @@ -39,7 +41,7 @@ public function parse(Twig_Token $token) } else { $expr = $this->parser->getExpressionParser()->parseExpression(); if (!$expr instanceof Twig_Node_Expression_Constant) { - throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); } $value = $expr->getAttribute('value'); @@ -53,7 +55,7 @@ public function parse(Twig_Token $token) @trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED); if (false === $value) { - throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); } $value = $stream->next()->getValue(); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Block.php b/vendor/twig/twig/lib/Twig/TokenParser/Block.php index 4ffafbe7..9dae2b90 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Block.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Block.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,6 +19,8 @@ * {% block title %}{% endblock %} - My Webpage * {% endblock %} * + * + * @final */ class Twig_TokenParser_Block extends Twig_TokenParser { @@ -28,7 +30,7 @@ public function parse(Twig_Token $token) $stream = $this->parser->getStream(); $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); if ($this->parser->hasBlock($name)) { - throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno)); $this->parser->pushLocalScope(); @@ -40,7 +42,7 @@ public function parse(Twig_Token $token) $value = $token->getValue(); if ($value != $name) { - throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } } } else { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Do.php b/vendor/twig/twig/lib/Twig/TokenParser/Do.php index 7adb5a08..fd03a296 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Do.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Do.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * Evaluates an expression, discarding the returned value. + * + * @final */ class Twig_TokenParser_Do extends Twig_TokenParser { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Embed.php b/vendor/twig/twig/lib/Twig/TokenParser/Embed.php index e685b955..019d9781 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Embed.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Embed.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2012 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,8 @@ /** * Embeds a template. + * + * @final */ class Twig_TokenParser_Embed extends Twig_TokenParser_Include { @@ -22,24 +24,33 @@ public function parse(Twig_Token $token) list($variables, $only, $ignoreMissing) = $this->parseArguments(); + $parentToken = $fakeParentToken = new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()); + if ($parent instanceof Twig_Node_Expression_Constant) { + $parentToken = new Twig_Token(Twig_Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine()); + } elseif ($parent instanceof Twig_Node_Expression_Name) { + $parentToken = new Twig_Token(Twig_Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine()); + } + // inject a fake parent to make the parent() function work $stream->injectTokens(array( new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()), new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()), - new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()), + $parentToken, new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()), )); $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true); // override the parent with the correct one - $module->setNode('parent', $parent); + if ($fakeParentToken === $parentToken) { + $module->setNode('parent', $parent); + } $this->parser->embedTemplate($module); $stream->expect(Twig_Token::BLOCK_END_TYPE); - return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + return new Twig_Node_Embed($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); } public function decideBlockEnd(Twig_Token $token) diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Extends.php b/vendor/twig/twig/lib/Twig/TokenParser/Extends.php index 510417ad..b8454d2d 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Extends.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Extends.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -16,21 +16,25 @@ *
      *  {% extends "base.html" %}
      * 
    + * + * @final */ class Twig_TokenParser_Extends extends Twig_TokenParser { public function parse(Twig_Token $token) { + $stream = $this->parser->getStream(); + if (!$this->parser->isMainScope()) { - throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax('Cannot extend from a block.', $token->getLine(), $stream->getSourceContext()); } if (null !== $this->parser->getParent()) { - throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext()); } $this->parser->setParent($this->parser->getExpressionParser()->parseExpression()); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); } public function getTag() diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Filter.php b/vendor/twig/twig/lib/Twig/TokenParser/Filter.php index b20dd5b3..1cdc0dd0 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Filter.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Filter.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,13 +17,15 @@ * This text becomes uppercase * {% endfilter %} * + * + * @final */ class Twig_TokenParser_Filter extends Twig_TokenParser { public function parse(Twig_Token $token) { $name = $this->parser->getVarName(); - $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), true, $token->getLine(), $this->getTag()); + $ref = new Twig_Node_Expression_BlockReference(new Twig_Node_Expression_Constant($name, $token->getLine()), null, $token->getLine(), $this->getTag()); $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag()); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Flush.php b/vendor/twig/twig/lib/Twig/TokenParser/Flush.php index f9ce7c3b..b09ff957 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Flush.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Flush.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,6 +13,8 @@ * Flushes the output to the client. * * @see flush() + * + * @final */ class Twig_TokenParser_Flush extends Twig_TokenParser { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/For.php b/vendor/twig/twig/lib/Twig/TokenParser/For.php index 3fac5111..6407afa8 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/For.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/For.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,6 +20,8 @@ * {% endfor %} * * + * + * @final */ class Twig_TokenParser_For extends Twig_TokenParser { @@ -48,13 +50,13 @@ public function parse(Twig_Token $token) if (count($targets) > 1) { $keyTarget = $targets->getNode(0); - $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine()); + $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine()); $valueTarget = $targets->getNode(1); - $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); + $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine()); } else { $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno); $valueTarget = $targets->getNode(0); - $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine()); + $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine()); } if ($ifexpr) { @@ -79,7 +81,7 @@ public function decideForEnd(Twig_Token $token) protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node) { if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { - throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext()); } foreach ($node as $n) { @@ -98,7 +100,7 @@ protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterfa if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) { $attribute = $node->getNode('attribute'); if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) { - throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext()); } } diff --git a/vendor/twig/twig/lib/Twig/TokenParser/From.php b/vendor/twig/twig/lib/Twig/TokenParser/From.php index f7547ebe..69c09c2f 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/From.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/From.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -15,6 +15,8 @@ *
      *   {% from 'forms.html' import forms %}
      * 
    + * + * @final */ class Twig_TokenParser_From extends Twig_TokenParser { @@ -46,7 +48,7 @@ public function parse(Twig_Token $token) foreach ($targets as $name => $alias) { if ($this->parser->isReservedMacroName($name)) { - throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext()); } $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var')); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/If.php b/vendor/twig/twig/lib/Twig/TokenParser/If.php index 91c06049..05459408 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/If.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/If.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -22,6 +22,8 @@ * * {% endif %} * + * + * @final */ class Twig_TokenParser_If extends Twig_TokenParser { @@ -56,7 +58,7 @@ public function parse(Twig_Token $token) break; default: - throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } } diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Import.php b/vendor/twig/twig/lib/Twig/TokenParser/Import.php index 85c5c036..fa5ebae2 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Import.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Import.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -15,6 +15,8 @@ *
      *   {% import 'forms.html' as forms %}
      * 
    + * + * @final */ class Twig_TokenParser_Import extends Twig_TokenParser { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Include.php b/vendor/twig/twig/lib/Twig/TokenParser/Include.php index 0e76dae3..b3ac1bc7 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Include.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Include.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -18,6 +18,8 @@ * Body * {% include 'footer.html' %} * + * + * @final */ class Twig_TokenParser_Include extends Twig_TokenParser { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Macro.php b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php index 8a7ebd6e..b845c909 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Macro.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,6 +17,8 @@ * * {% endmacro %} * + * + * @final */ class Twig_TokenParser_Macro extends Twig_TokenParser { @@ -35,7 +37,7 @@ public function parse(Twig_Token $token) $value = $token->getValue(); if ($value != $name) { - throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } } $this->parser->popLocalScope(); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php b/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php index 1feadd08..0b08fe61 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,14 +19,17 @@ * * * @see http://www.twig-project.org/doc/api.html#sandbox-extension for details + * + * @final */ class Twig_TokenParser_Sandbox extends Twig_TokenParser { public function parse(Twig_Token $token) { - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream = $this->parser->getStream(); + $stream->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(Twig_Token::BLOCK_END_TYPE); // in a sandbox tag, only include tags are allowed if (!$body instanceof Twig_Node_Include) { @@ -36,7 +39,7 @@ public function parse(Twig_Token $token) } if (!$node instanceof Twig_Node_Include) { - throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getLine(), $this->parser->getFilename()); + throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext()); } } } diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Set.php b/vendor/twig/twig/lib/Twig/TokenParser/Set.php index 5ca614bd..d03a36b0 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Set.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Set.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -25,6 +25,8 @@ * * {% set foo %}Some content{% endset %} * + * + * @final */ class Twig_TokenParser_Set extends Twig_TokenParser { @@ -41,13 +43,13 @@ public function parse(Twig_Token $token) $stream->expect(Twig_Token::BLOCK_END_TYPE); if (count($names) !== count($values)) { - throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); } } else { $capture = true; if (count($names) > 1) { - throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); } $stream->expect(Twig_Token::BLOCK_END_TYPE); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php b/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php index 53d906d8..e8b2638e 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,6 +21,8 @@ * * {# output will be
    foo
    #} * + * + * @final */ class Twig_TokenParser_Spaceless extends Twig_TokenParser { diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Use.php b/vendor/twig/twig/lib/Twig/TokenParser/Use.php index 4945d03c..c3fb0697 100644 --- a/vendor/twig/twig/lib/Twig/TokenParser/Use.php +++ b/vendor/twig/twig/lib/Twig/TokenParser/Use.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2011 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -22,6 +22,8 @@ * * * @see http://www.twig-project.org/doc/templates.html#horizontal-reuse for details. + * + * @final */ class Twig_TokenParser_Use extends Twig_TokenParser { @@ -31,7 +33,7 @@ public function parse(Twig_Token $token) $stream = $this->parser->getStream(); if (!$template instanceof Twig_Node_Expression_Constant) { - throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getFilename()); + throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); } $targets = array(); diff --git a/vendor/twig/twig/lib/Twig/TokenParser/With.php b/vendor/twig/twig/lib/Twig/TokenParser/With.php new file mode 100644 index 00000000..8d078d97 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/TokenParser/With.php @@ -0,0 +1,50 @@ + + * + * @final + */ +class Twig_TokenParser_With extends Twig_TokenParser +{ + public function parse(Twig_Token $token) + { + $stream = $this->parser->getStream(); + + $variables = null; + $only = false; + if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) { + $variables = $this->parser->getExpressionParser()->parseExpression(); + $only = $stream->nextIf(Twig_Token::NAME_TYPE, 'only'); + } + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + $body = $this->parser->subparse(array($this, 'decideWithEnd'), true); + + $stream->expect(Twig_Token::BLOCK_END_TYPE); + + return new Twig_Node_With($body, $variables, $only, $token->getLine(), $this->getTag()); + } + + public function decideWithEnd(Twig_Token $token) + { + return $token->test('endwith'); + } + + public function getTag() + { + return 'with'; + } +} diff --git a/vendor/twig/twig/lib/Twig/TokenParserBroker.php b/vendor/twig/twig/lib/Twig/TokenParserBroker.php index d88bb43e..a6401350 100644 --- a/vendor/twig/twig/lib/Twig/TokenParserBroker.php +++ b/vendor/twig/twig/lib/Twig/TokenParserBroker.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier - * (c) 2010 Arnaud Le Blanc + * (c) Fabien Potencier + * (c) Arnaud Le Blanc * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,8 +24,6 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface protected $brokers = array(); /** - * Constructor. - * * @param array|Traversable $parsers A Traversable of Twig_TokenParserInterface instances * @param array|Traversable $brokers A Traversable of Twig_TokenParserBrokerInterface instances * @param bool $triggerDeprecationError @@ -50,21 +48,11 @@ public function __construct($parsers = array(), $brokers = array(), $triggerDepr } } - /** - * Adds a TokenParser. - * - * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance - */ public function addTokenParser(Twig_TokenParserInterface $parser) { $this->parsers[$parser->getTag()] = $parser; } - /** - * Removes a TokenParser. - * - * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance - */ public function removeTokenParser(Twig_TokenParserInterface $parser) { $name = $parser->getTag(); @@ -73,21 +61,11 @@ public function removeTokenParser(Twig_TokenParserInterface $parser) } } - /** - * Adds a TokenParserBroker. - * - * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance - */ public function addTokenParserBroker(Twig_TokenParserBroker $broker) { $this->brokers[] = $broker; } - /** - * Removes a TokenParserBroker. - * - * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance - */ public function removeTokenParserBroker(Twig_TokenParserBroker $broker) { if (false !== $pos = array_search($broker, $this->brokers)) { diff --git a/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php b/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php index 3ec2a880..6c93f5ea 100644 --- a/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php +++ b/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier - * (c) 2010 Arnaud Le Blanc + * (c) Fabien Potencier + * (c) Arnaud Le Blanc * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,14 +26,12 @@ interface Twig_TokenParserBrokerInterface * * @param string $tag A tag name * - * @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found + * @return Twig_TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found */ public function getTokenParser($tag); /** * Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of. - * - * @param Twig_ParserInterface $parser A Twig_ParserInterface interface */ public function setParser(Twig_ParserInterface $parser); diff --git a/vendor/twig/twig/lib/Twig/TokenParserInterface.php b/vendor/twig/twig/lib/Twig/TokenParserInterface.php index 12ec3961..aea96996 100644 --- a/vendor/twig/twig/lib/Twig/TokenParserInterface.php +++ b/vendor/twig/twig/lib/Twig/TokenParserInterface.php @@ -3,7 +3,7 @@ /* * This file is part of Twig. * - * (c) 2010 Fabien Potencier + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -18,17 +18,13 @@ interface Twig_TokenParserInterface { /** * Sets the parser associated with this token parser. - * - * @param Twig_Parser $parser A Twig_Parser instance */ public function setParser(Twig_Parser $parser); /** * Parses a token and returns a node. * - * @param Twig_Token $token A Twig_Token instance - * - * @return Twig_NodeInterface A Twig_NodeInterface instance + * @return Twig_NodeInterface * * @throws Twig_Error_Syntax */ diff --git a/vendor/twig/twig/lib/Twig/TokenStream.php b/vendor/twig/twig/lib/Twig/TokenStream.php index 016f8122..27ca1a74 100644 --- a/vendor/twig/twig/lib/Twig/TokenStream.php +++ b/vendor/twig/twig/lib/Twig/TokenStream.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,6 +13,8 @@ /** * Represents a token stream. * + * @final + * * @author Fabien Potencier */ class Twig_TokenStream @@ -21,23 +23,30 @@ class Twig_TokenStream protected $current = 0; protected $filename; + private $source; + /** - * Constructor. - * - * @param array $tokens An array of tokens - * @param string $filename The name of the filename which tokens are associated with + * @param array $tokens An array of tokens + * @param string|null $name The name of the template which tokens are associated with + * @param string|null $source The source code associated with the tokens */ - public function __construct(array $tokens, $filename = null) + public function __construct(array $tokens, $name = null, $source = null) { + if (!$name instanceof Twig_Source) { + if (null !== $name || null !== $source) { + @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED); + } + $this->source = new Twig_Source($source, $name); + } else { + $this->source = $name; + } + $this->tokens = $tokens; - $this->filename = $filename; + + // deprecated, not used anymore, to be removed in 2.0 + $this->filename = $this->source->getName(); } - /** - * Returns a string representation of the token stream. - * - * @return string - */ public function __toString() { return implode("\n", $this->tokens); @@ -56,7 +65,7 @@ public function injectTokens(array $tokens) public function next() { if (!isset($this->tokens[++$this->current])) { - throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->filename); + throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source); } return $this->tokens[$this->current - 1]; @@ -89,7 +98,7 @@ public function expect($type, $value = null, $message = null) Twig_Token::typeToEnglish($token->getType()), $token->getValue(), Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''), $line, - $this->filename + $this->source ); } $this->next(); @@ -107,7 +116,7 @@ public function expect($type, $value = null, $message = null) public function look($number = 1) { if (!isset($this->tokens[$this->current + $number])) { - throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename); + throw new Twig_Error_Syntax('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source); } return $this->tokens[$this->current + $number]; @@ -134,8 +143,6 @@ public function isEOF() } /** - * Gets the current token. - * * @return Twig_Token */ public function getCurrent() @@ -144,12 +151,44 @@ public function getCurrent() } /** - * Gets the filename associated with this stream. + * Gets the name associated with this stream (null if not defined). * - * @return string + * @return string|null + * + * @deprecated since 1.27 (to be removed in 2.0) */ public function getFilename() { - return $this->filename; + @trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->source->getName(); + } + + /** + * Gets the source code associated with this stream. + * + * @return string + * + * @internal Don't use this as it might be empty depending on the environment configuration + * + * @deprecated since 1.27 (to be removed in 2.0) + */ + public function getSource() + { + @trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->source->getCode(); + } + + /** + * Gets the source associated with this stream. + * + * @return Twig_Source + * + * @internal + */ + public function getSourceContext() + { + return $this->source; } } diff --git a/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php b/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php index e406f0aa..884cf055 100644 --- a/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php +++ b/vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php @@ -11,6 +11,8 @@ /** * @author Fabien Potencier + * + * @final */ class Twig_Util_DeprecationCollector { @@ -28,7 +30,7 @@ public function __construct(Twig_Environment $twig) * @param string $dir A directory where templates are stored * @param string $ext Limit the loaded templates by extension * - * @return array() An array of deprecations + * @return array An array of deprecations */ public function collectDir($dir, $ext = '.twig') { @@ -44,11 +46,11 @@ public function collectDir($dir, $ext = '.twig') /** * Returns deprecations for passed templates. * - * @param Iterator $iterator An iterator of templates (where keys are template names and values the contents of the template) + * @param Traversable $iterator An iterator of templates (where keys are template names and values the contents of the template) * - * @return array() An array of deprecations + * @return array An array of deprecations */ - public function collect(Iterator $iterator) + public function collect(Traversable $iterator) { $this->deprecations = array(); @@ -56,7 +58,7 @@ public function collect(Iterator $iterator) foreach ($iterator as $name => $contents) { try { - $this->twig->parse($this->twig->tokenize($contents, $name)); + $this->twig->parse($this->twig->tokenize(new Twig_Source($contents, $name))); } catch (Twig_Error_Syntax $e) { // ignore templates containing syntax errors } diff --git a/vendor/twig/twig/phpunit.xml.dist b/vendor/twig/twig/phpunit.xml.dist index 6f6d1d25..ce773278 100644 --- a/vendor/twig/twig/phpunit.xml.dist +++ b/vendor/twig/twig/phpunit.xml.dist @@ -17,6 +17,14 @@
    + + + + + + + + ./lib/Twig/ diff --git a/vendor/wikimedia/composer-merge-plugin/README.md b/vendor/wikimedia/composer-merge-plugin/README.md index f020d40a..e63b847b 100644 --- a/vendor/wikimedia/composer-merge-plugin/README.md +++ b/vendor/wikimedia/composer-merge-plugin/README.md @@ -24,6 +24,9 @@ extensions which may be managed via Composer. Installation ------------ +Composer Merge Plugin requires [Composer 1.0.0](https://getcomposer.org/) or +newer. + ``` $ composer require wikimedia/composer-merge-plugin ``` @@ -32,7 +35,7 @@ $ composer require wikimedia/composer-merge-plugin Usage ----- -``` +```json { "require": { "wikimedia/composer-merge-plugin": "dev-master" @@ -48,8 +51,11 @@ Usage ], "recurse": true, "replace": false, + "ignore-duplicates": false, "merge-dev": true, - "merge-extra": false + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false } } } @@ -88,11 +94,13 @@ in the top-level composer.json file: * [suggest](https://getcomposer.org/doc/04-schema.md#suggest) * [extra](https://getcomposer.org/doc/04-schema.md#extra) (optional, see [merge-extra](#merge-extra) below) +* [scripts](https://getcomposer.org/doc/04-schema.md#scripts) + (optional, see [merge-scripts](#merge-scripts) below) ### require -The `require` setting is identical to `[include](#include)` except when +The `require` setting is identical to [`include`](#include) except when a pattern fails to match at least one file then it will cause an error. ### recurse @@ -112,6 +120,19 @@ package declarations found in merged files will overwrite the declarations made by earlier files. Files are loaded in the order specified by the `include` setting with globbed files being processed in alphabetical order. +### ignore-duplicates + +By default, Composer's conflict resolution engine is used to determine which +version of a package should be installed when multiple files specify the same +package. An `"ignore-duplicates": true` setting can be provided to change to +a "first version specified wins" conflict resolution strategy. In this mode, +duplicate package declarations found in merged files will be ignored in favor +of the declarations made by earlier files. Files are loaded in the order +specified by the `include` setting with globbed files being processed in +alphabetical order. + +Note: `"replace": true` and `"ignore-duplicates": true` modes are mutually +exclusive. If both are set, `"ignore-duplicates": true` will be used. ### merge-dev @@ -127,13 +148,30 @@ section is to accept the first version of any key found (e.g. a key in the master config wins over the version found in any imported config). If `replace` mode is active ([see above](#replace)) then this behavior changes and the last key found will win (e.g. the key in the master config is replaced -by the key in the imported config). The usefulness of merging the extra -section will vary depending on the Composer plugins being used and the order -in which they are processed by Composer. +by the key in the imported config). If `"merge-extra-deep": true` is specified +then, the sections are merged similar to array_merge_recursive() - however +duplicate string array keys are replaced instead of merged, while numeric +array keys are merged as usual. The usefulness of merging the extra section +will vary depending on the Composer plugins being used and the order in which +they are processed by Composer. Note that `merge-plugin` sections are excluded from the merge process, but are always processed by the plugin unless [recursion](#recurse) is disabled. +### merge-scripts + +A `"merge-scripts": true` setting enables merging the contents of the +`scripts` section of included files as well. The normal merge mode for the +scripts section is to accept the first version of any key found (e.g. a key in +the master config wins over the version found in any imported config). If +`replace` mode is active ([see above](#replace)) then this behavior changes +and the last key found will win (e.g. the key in the master config is replaced +by the key in the imported config). + +Note: [custom commands][] added by merged configuration will work when invoked +as `composer run-script my-cool-command` but will not be available using the +normal `composer my-cool-command` shortcut. + Running tests ------------- @@ -167,8 +205,8 @@ GitHub as well. License ------- -Composer Merge plugin is licensed under the MIT license. See the `LICENSE` -file for more details. +Composer Merge plugin is licensed under the MIT license. See the +[`LICENSE`](LICENSE) file for more details. --- @@ -181,3 +219,4 @@ file for more details. [License]: https://img.shields.io/packagist/l/wikimedia/composer-merge-plugin.svg?style=flat [Build Status]: https://img.shields.io/travis/wikimedia/composer-merge-plugin.svg?style=flat [Code Coverage]: https://img.shields.io/scrutinizer/coverage/g/wikimedia/composer-merge-plugin/master.svg?style=flat +[custom commands]: https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands diff --git a/vendor/wikimedia/composer-merge-plugin/composer.json b/vendor/wikimedia/composer-merge-plugin/composer.json index dce70e7d..e504c91e 100644 --- a/vendor/wikimedia/composer-merge-plugin/composer.json +++ b/vendor/wikimedia/composer-merge-plugin/composer.json @@ -16,7 +16,7 @@ "php": ">=5.3.2" }, "require-dev": { - "composer/composer": "1.0.*@dev", + "composer/composer": "~1.0.0", "jakub-onderka/php-parallel-lint": "~0.8", "phpunit/phpunit": "~4.8|~5.0", "squizlabs/php_codesniffer": "~2.1.0" diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php index b32131ff..85997ae5 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/ExtraPackage.php @@ -58,6 +58,11 @@ class ExtraPackage */ protected $package; + /** + * @var VersionParser $versionParser + */ + protected $versionParser; + /** * @param string $path Path to composer.json file * @param Composer $composer @@ -70,6 +75,7 @@ public function __construct($path, Composer $composer, Logger $logger) $this->logger = $logger; $this->json = $this->readPackageJson($path); $this->package = $this->loadPackage($this->json); + $this->versionParser = new VersionParser(); } /** @@ -120,10 +126,10 @@ protected function readPackageJson($path) } /** - * @param string $json + * @param array $json * @return CompletePackage */ - protected function loadPackage($json) + protected function loadPackage(array $json) { $loader = new ArrayLoader(); $package = $loader->load($json); @@ -146,12 +152,9 @@ protected function loadPackage($json) */ public function mergeInto(RootPackageInterface $root, PluginState $state) { - $this->addRepositories($root); + $this->prependRepositories($root); $this->mergeRequires('require', $root, $state); - if ($state->isDevMode()) { - $this->mergeRequires('require-dev', $root, $state); - } $this->mergePackageLinks('conflict', $root); $this->mergePackageLinks('replace', $root); @@ -160,11 +163,29 @@ public function mergeInto(RootPackageInterface $root, PluginState $state) $this->mergeSuggests($root); $this->mergeAutoload('autoload', $root); + + $this->mergeExtra($root, $state); + + $this->mergeScripts($root, $state); + if ($state->isDevMode()) { - $this->mergeAutoload('devAutoload', $root); + $this->mergeDevInto($root, $state); + } else { + $this->mergeReferences($root); } + } - $this->mergeExtra($root, $state); + /** + * Merge just the dev portion into a RootPackageInterface + * + * @param RootPackageInterface $root + * @param PluginState $state + */ + public function mergeDevInto(RootPackageInterface $root, PluginState $state) + { + $this->mergeRequires('require-dev', $root, $state); + $this->mergeAutoload('devAutoload', $root); + $this->mergeReferences($root); } /** @@ -173,7 +194,7 @@ public function mergeInto(RootPackageInterface $root, PluginState $state) * * @param RootPackageInterface $root */ - protected function addRepositories(RootPackageInterface $root) + protected function prependRepositories(RootPackageInterface $root) { if (!isset($this->json['repositories'])) { return; @@ -185,12 +206,12 @@ protected function addRepositories(RootPackageInterface $root) if (!isset($repoJson['type'])) { continue; } - $this->logger->info("Adding {$repoJson['type']} repository"); + $this->logger->info("Prepending {$repoJson['type']} repository"); $repo = $repoManager->createRepository( $repoJson['type'], $repoJson ); - $repoManager->addRepository($repo); + $repoManager->prependRepository($repo); $newRepos[] = $repo; } @@ -254,9 +275,17 @@ protected function mergeOrDefer( array $merge, $state ) { + if ($state->ignoreDuplicateLinks() && $state->replaceDuplicateLinks()) { + $this->logger->warning("Both replace and ignore-duplicates are true. These are mutually exclusive."); + $this->logger->warning("Duplicate packages will be ignored."); + } + $dups = array(); foreach ($merge as $name => $link) { - if (!isset($origin[$name]) || $state->replaceDuplicateLinks()) { + if (isset($origin[$name]) && $state->ignoreDuplicateLinks()) { + $this->logger->info("Ignoring duplicate {$name}"); + continue; + } elseif (!isset($origin[$name]) || $state->replaceDuplicateLinks()) { $this->logger->info("Merging {$name}"); $origin[$name] = $link; } else { @@ -402,23 +431,68 @@ public function mergeExtra(RootPackageInterface $root, PluginState $state) if ($state->replaceDuplicateLinks()) { $unwrapped->setExtra( - array_merge($rootExtra, $extra) + self::mergeExtraArray($state->shouldMergeExtraDeep(), $rootExtra, $extra) ); - } else { - foreach (array_intersect( - array_keys($extra), - array_keys($rootExtra) - ) as $key) { - $this->logger->info( - "Ignoring duplicate {$key} in ". - "{$this->path} extra config." - ); + if (!$state->shouldMergeExtraDeep()) { + foreach (array_intersect( + array_keys($extra), + array_keys($rootExtra) + ) as $key) { + $this->logger->info( + "Ignoring duplicate {$key} in ". + "{$this->path} extra config." + ); + } } $unwrapped->setExtra( - array_merge($extra, $rootExtra) + self::mergeExtraArray($state->shouldMergeExtraDeep(), $extra, $rootExtra) + ); + } + } + + /** + * Merge scripts config into a RootPackageInterface + * + * @param RootPackageInterface $root + * @param PluginState $state + */ + public function mergeScripts(RootPackageInterface $root, PluginState $state) + { + $scripts = $this->package->getScripts(); + if (!$state->shouldMergeScripts() || empty($scripts)) { + return; + } + + $rootScripts = $root->getScripts(); + $unwrapped = self::unwrapIfNeeded($root, 'setScripts'); + + if ($state->replaceDuplicateLinks()) { + $unwrapped->setScripts( + array_merge($rootScripts, $scripts) ); + } else { + $unwrapped->setScripts( + array_merge($scripts, $rootScripts) + ); + } + } + + /** + * Merges two arrays either via arrayMergeDeep or via array_merge. + * + * @param bool $mergeDeep + * @param array $array1 + * @param array $array2 + * @return array + */ + public static function mergeExtraArray($mergeDeep, $array1, $array2) + { + if ($mergeDeep) { + return NestedArray::mergeDeep($array1, $array2); } + + return array_merge($array1, $array2); } /** @@ -438,7 +512,7 @@ protected function replaceSelfVersionDependencies( $linkType = BasePackage::$supportedLinkTypes[$type]; $version = $root->getVersion(); $prettyVersion = $root->getPrettyVersion(); - $vp = new VersionParser(); + $vp = $this->versionParser; $method = 'get' . ucfirst($linkType['method']); $packages = $root->$method(); @@ -503,5 +577,53 @@ public static function unwrapIfNeeded( // @codeCoverageIgnoreEnd return $root; } + + /** + * Update the root packages reference information. + * + * @param RootPackageInterface $root + */ + protected function mergeReferences(RootPackageInterface $root) + { + // Merge source reference information for merged packages. + // @see RootPackageLoader::load + $references = array(); + $unwrapped = $this->unwrapIfNeeded($root, 'setReferences'); + foreach (array('require', 'require-dev') as $linkType) { + $linkInfo = BasePackage::$supportedLinkTypes[$linkType]; + $method = 'get'.ucfirst($linkInfo['method']); + $links = array(); + foreach ($unwrapped->$method() as $link) { + $links[$link->getTarget()] = $link->getConstraint()->getPrettyString(); + } + $references = $this->extractReferences($links, $references); + } + $unwrapped->setReferences($references); + } + + /** + * Extract vcs revision from version constraint (dev-master#abc123. + * + * @param array $requires + * @param array $references + * @return array + * @see RootPackageLoader::extractReferences() + */ + protected function extractReferences(array $requires, array $references) + { + foreach ($requires as $reqName => $reqVersion) { + $reqVersion = preg_replace('{^([^,\s@]+) as .+$}', '$1', $reqVersion); + $stabilityName = VersionParser::parseStability($reqVersion); + if ( + preg_match('{^[^,\s@]+?#([a-f0-9]+)$}', $reqVersion, $match) && + $stabilityName === 'dev' + ) { + $name = strtolower($reqName); + $references[$name] = $match[1]; + } + } + + return $references; + } } // vim:sw=4:ts=4:sts=4:et: diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/NestedArray.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/NestedArray.php new file mode 100644 index 00000000..91bd295f --- /dev/null +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/NestedArray.php @@ -0,0 +1,116 @@ + 'x', 'attributes' => array('title' => t('X'), 'class' => array('a', 'b'))); + * $link_options_2 = array('fragment' => 'y', 'attributes' => array('title' => t('Y'), 'class' => array('c', 'd'))); + * + * // This results in array('fragment' => array('x', 'y'), 'attributes' => + * // array('title' => array(t('X'), t('Y')), 'class' => array('a', 'b', + * // 'c', 'd'))). + * $incorrect = array_merge_recursive($link_options_1, $link_options_2); + * + * // This results in array('fragment' => 'y', 'attributes' => + * // array('title' => t('Y'), 'class' => array('a', 'b', 'c', 'd'))). + * $correct = NestedArray::mergeDeep($link_options_1, $link_options_2); + * @endcode + * + * @param array ... + * Arrays to merge. + * + * @return array + * The merged array. + * + * @see NestedArray::mergeDeepArray() + */ + public static function mergeDeep() + { + return self::mergeDeepArray(func_get_args()); + } + + /** + * Merges multiple arrays, recursively, and returns the merged array. + * + * This function is equivalent to NestedArray::mergeDeep(), except the + * input arrays are passed as a single array parameter rather than + * a variable parameter list. + * + * The following are equivalent: + * - NestedArray::mergeDeep($a, $b); + * - NestedArray::mergeDeepArray(array($a, $b)); + * + * The following are also equivalent: + * - call_user_func_array('NestedArray::mergeDeep', $arrays_to_merge); + * - NestedArray::mergeDeepArray($arrays_to_merge); + * + * @param array $arrays + * An arrays of arrays to merge. + * @param bool $preserveIntegerKeys + * (optional) If given, integer keys will be preserved and merged + * instead of appended. Defaults to false. + * + * @return array + * The merged array. + * + * @see NestedArray::mergeDeep() + */ + public static function mergeDeepArray( + array $arrays, + $preserveIntegerKeys = false + ) { + $result = array(); + foreach ($arrays as $array) { + foreach ($array as $key => $value) { + // Renumber integer keys as array_merge_recursive() does + // unless $preserveIntegerKeys is set to TRUE. Note that PHP + // automatically converts array keys that are integer strings + // (e.g., '1') to integers. + if (is_integer($key) && !$preserveIntegerKeys) { + $result[] = $value; + } elseif (isset($result[$key]) && + is_array($result[$key]) && + is_array($value) + ) { + // Recurse when both values are arrays. + $result[$key] = self::mergeDeepArray( + array($result[$key], $value), + $preserveIntegerKeys + ); + } else { + // Otherwise, use the latter value, overriding any + // previous value. + $result[$key] = $value; + } + } + } + return $result; + } +} +// vim:sw=4:ts=4:sts=4:et: diff --git a/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php b/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php index a191c1e8..7aa90ac4 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php +++ b/vendor/wikimedia/composer-merge-plugin/src/Merge/PluginState.php @@ -54,6 +54,11 @@ class PluginState */ protected $replace = false; + /** + * @var bool $ignore + */ + protected $ignore = false; + /** * Whether to merge the -dev sections. * @var bool $mergeDev @@ -74,6 +79,31 @@ class PluginState */ protected $mergeExtra = false; + /** + * Whether to merge the extra section in a deep / recursive way. + * + * By default the extra section is merged with array_merge() and duplicate + * keys are ignored. When enabled this allows to merge the arrays recursively + * using the following rule: Integer keys are merged, while array values are + * replaced where the later values overwrite the former. + * + * This is useful especially for the extra section when plugins use larger + * structures like a 'patches' key with the packages as sub-keys and the + * patches as values. + * + * When 'replace' mode is activated the order of array merges is exchanged. + * + * @var bool $mergeExtraDeep + */ + protected $mergeExtraDeep = false; + + /** + * Whether to merge the scripts section. + * + * @var bool $mergeScripts + */ + protected $mergeScripts = false; + /** * @var bool $firstInstall */ @@ -114,8 +144,11 @@ public function loadSettings() 'require' => array(), 'recurse' => true, 'replace' => false, + 'ignore-duplicates' => false, 'merge-dev' => true, 'merge-extra' => false, + 'merge-extra-deep' => false, + 'merge-scripts' => false, ), isset($extra['merge-plugin']) ? $extra['merge-plugin'] : array() ); @@ -126,8 +159,11 @@ public function loadSettings() $config['require'] : array($config['require']); $this->recurse = (bool)$config['recurse']; $this->replace = (bool)$config['replace']; + $this->ignore = (bool)$config['ignore-duplicates']; $this->mergeDev = (bool)$config['merge-dev']; $this->mergeExtra = (bool)$config['merge-extra']; + $this->mergeExtraDeep = (bool)$config['merge-extra-deep']; + $this->mergeScripts = (bool)$config['merge-scripts']; } /** @@ -217,7 +253,17 @@ public function setDevMode($flag) */ public function isDevMode() { - return $this->mergeDev && $this->devMode; + return $this->shouldMergeDev() && $this->devMode; + } + + /** + * Should devMode settings be merged? + * + * @return bool + */ + public function shouldMergeDev() + { + return $this->mergeDev; } /** @@ -307,6 +353,16 @@ public function replaceDuplicateLinks() return $this->replace; } + /** + * Should duplicate links be ignored? + * + * @return bool + */ + public function ignoreDuplicateLinks() + { + return $this->ignore; + } + /** * Should the extra section be merged? * @@ -323,5 +379,39 @@ public function shouldMergeExtra() { return $this->mergeExtra; } + + /** + * Should the extra section be merged deep / recursively? + * + * By default the extra section is merged with array_merge() and duplicate + * keys are ignored. When enabled this allows to merge the arrays recursively + * using the following rule: Integer keys are merged, while array values are + * replaced where the later values overwrite the former. + * + * This is useful especially for the extra section when plugins use larger + * structures like a 'patches' key with the packages as sub-keys and the + * patches as values. + * + * When 'replace' mode is activated the order of array merges is exchanged. + * + * @return bool + */ + public function shouldMergeExtraDeep() + { + return $this->mergeExtraDeep; + } + + + /** + * Should the scripts section be merged? + * + * By default, the scripts section is not merged. + * + * @return bool + */ + public function shouldMergeScripts() + { + return $this->mergeScripts; + } } // vim:sw=4:ts=4:sts=4:et: diff --git a/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php b/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php index ea41d41a..7eab0460 100644 --- a/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php +++ b/vendor/wikimedia/composer-merge-plugin/src/MergePlugin.php @@ -16,6 +16,7 @@ use Composer\Composer; use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\EventDispatcher\Event as BaseEvent; use Composer\EventDispatcher\EventSubscriberInterface; use Composer\Factory; use Composer\Installer; @@ -26,7 +27,7 @@ use Composer\IO\IOInterface; use Composer\Package\RootPackageInterface; use Composer\Plugin\PluginInterface; -use Composer\Script\Event; +use Composer\Script\Event as ScriptEvent; use Composer\Script\ScriptEvents; /** @@ -86,6 +87,16 @@ class MergePlugin implements PluginInterface, EventSubscriberInterface */ const PACKAGE_NAME = 'wikimedia/composer-merge-plugin'; + /** + * Name of the composer 1.1 init event. + */ + const COMPAT_PLUGINEVENTS_INIT = 'init'; + + /** + * Priority that plugin uses to register callbacks. + */ + const CALLBACK_PRIORITY = 50000; + /** * @var Composer $composer */ @@ -102,11 +113,18 @@ class MergePlugin implements PluginInterface, EventSubscriberInterface protected $logger; /** - * Files that have already been processed + * Files that have already been fully processed + * + * @var string[] $loaded + */ + protected $loaded = array(); + + /** + * Files that have already been partially processed * - * @var string[] $loadedFiles + * @var string[] $loadedNoDev */ - protected $loadedFiles = array(); + protected $loadedNoDev = array(); /** * {@inheritdoc} @@ -124,24 +142,52 @@ public function activate(Composer $composer, IOInterface $io) public static function getSubscribedEvents() { return array( - InstallerEvents::PRE_DEPENDENCIES_SOLVING => 'onDependencySolve', - PackageEvents::POST_PACKAGE_INSTALL => 'onPostPackageInstall', - ScriptEvents::POST_INSTALL_CMD => 'onPostInstallOrUpdate', - ScriptEvents::POST_UPDATE_CMD => 'onPostInstallOrUpdate', - ScriptEvents::PRE_AUTOLOAD_DUMP => 'onInstallUpdateOrDump', - ScriptEvents::PRE_INSTALL_CMD => 'onInstallUpdateOrDump', - ScriptEvents::PRE_UPDATE_CMD => 'onInstallUpdateOrDump', + // Use our own constant to make this event optional. Once + // composer-1.1 is required, this can use PluginEvents::INIT + // instead. + self::COMPAT_PLUGINEVENTS_INIT => + array('onInit', self::CALLBACK_PRIORITY), + InstallerEvents::PRE_DEPENDENCIES_SOLVING => + array('onDependencySolve', self::CALLBACK_PRIORITY), + PackageEvents::POST_PACKAGE_INSTALL => + array('onPostPackageInstall', self::CALLBACK_PRIORITY), + ScriptEvents::POST_INSTALL_CMD => + array('onPostInstallOrUpdate', self::CALLBACK_PRIORITY), + ScriptEvents::POST_UPDATE_CMD => + array('onPostInstallOrUpdate', self::CALLBACK_PRIORITY), + ScriptEvents::PRE_AUTOLOAD_DUMP => + array('onInstallUpdateOrDump', self::CALLBACK_PRIORITY), + ScriptEvents::PRE_INSTALL_CMD => + array('onInstallUpdateOrDump', self::CALLBACK_PRIORITY), + ScriptEvents::PRE_UPDATE_CMD => + array('onInstallUpdateOrDump', self::CALLBACK_PRIORITY), ); } + /** + * Handle an event callback for initialization. + * + * @param \Composer\EventDispatcher\Event $event + */ + public function onInit(BaseEvent $event) + { + $this->state->loadSettings(); + // It is not possible to know if the user specified --dev or --no-dev + // so assume it is false. The dev section will be merged later when + // the other events fire. + $this->state->setDevMode(false); + $this->mergeFiles($this->state->getIncludes(), false); + $this->mergeFiles($this->state->getRequires(), true); + } + /** * Handle an event callback for an install, update or dump command by * checking for "merge-plugin" in the "extra" data and merging package * contents if found. * - * @param Event $event + * @param ScriptEvent $event */ - public function onInstallUpdateOrDump(Event $event) + public function onInstallUpdateOrDump(ScriptEvent $event) { $this->state->loadSettings(); $this->state->setDevMode($event->isDevMode()); @@ -196,16 +242,32 @@ function ($files, $pattern) use ($required) { */ protected function mergeFile(RootPackageInterface $root, $path) { - if (isset($this->loadedFiles[$path])) { - $this->logger->debug("Already merged $path"); + if (isset($this->loaded[$path]) || + (isset($this->loadedNoDev[$path]) && !$this->state->isDevMode()) + ) { + $this->logger->debug( + "Already merged $path completely" + ); return; - } else { - $this->loadedFiles[$path] = true; } - $this->logger->info("Loading {$path}..."); $package = new ExtraPackage($path, $this->composer, $this->logger); - $package->mergeInto($root, $this->state); + + if (isset($this->loadedNoDev[$path])) { + $this->logger->info( + "Loading -dev sections of {$path}..." + ); + $package->mergeDevInto($root, $this->state); + } else { + $this->logger->info("Loading {$path}..."); + $package->mergeInto($root, $this->state); + } + + if ($this->state->isDevMode()) { + $this->loaded[$path] = true; + } else { + $this->loadedNoDev[$path] = true; + } if ($this->state->recurseIncludes()) { $this->mergeFiles($package->getIncludes(), false); @@ -230,7 +292,12 @@ public function onDependencySolve(InstallerEvent $event) ); $request->install($link->getTarget(), $link->getConstraint()); } - if ($this->state->isDevMode()) { + + // Issue #113: Check devMode of event rather than our global state. + // Composer fires the PRE_DEPENDENCIES_SOLVING event twice for + // `--no-dev` operations to decide which packages are dev only + // requirements. + if ($this->state->shouldMergeDev() && $event->isDevMode()) { foreach ($this->state->getDuplicateLinks('require-dev') as $link) { $this->logger->info( "Adding dev dependency {$link}" @@ -266,9 +333,9 @@ public function onPostPackageInstall(PackageEvent $event) * plugin was installed during the run then trigger an update command to * process any merge-patterns in the current config. * - * @param Event $event + * @param ScriptEvent $event */ - public function onPostInstallOrUpdate(Event $event) + public function onPostInstallOrUpdate(ScriptEvent $event) { // @codeCoverageIgnoreStart if ($this->state->isFirstInstall()) { diff --git a/vendor/zendframework/zend-diactoros/.coveralls.yml b/vendor/zendframework/zend-diactoros/.coveralls.yml index 53bda829..bc71b62f 100644 --- a/vendor/zendframework/zend-diactoros/.coveralls.yml +++ b/vendor/zendframework/zend-diactoros/.coveralls.yml @@ -1,3 +1,2 @@ coverage_clover: clover.xml json_path: coveralls-upload.json -src_dir: src diff --git a/vendor/zendframework/zend-diactoros/CHANGELOG.md b/vendor/zendframework/zend-diactoros/CHANGELOG.md index 57b0a871..fc65b32a 100644 --- a/vendor/zendframework/zend-diactoros/CHANGELOG.md +++ b/vendor/zendframework/zend-diactoros/CHANGELOG.md @@ -2,7 +2,139 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 1.1.3 - 2015-08-10 +## 1.4.1 - 2017-08-17 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- [#260](https://github.com/zendframework/zend-diactoros/pull/260) removes + support for HHVM, as tests have failed against it for some time. + +### Fixed + +- [#247](https://github.com/zendframework/zend-diactoros/pull/247) fixes the + `Stream` and `RelativeStream` `__toString()` method implementations to check + if the stream `isSeekable()` before attempting to `rewind()` it, ensuring that + the method does not raise exceptions (PHP does not allow exceptions in that + method). In particular, this fixes an issue when using AWS S3 streams. + +- [#252](https://github.com/zendframework/zend-diactoros/pull/252) provides a + fix to the `SapiEmitterTrait` to ensure that any `Set-Cookie` headers in the + response instance do not override those set by PHP when a session is created + and/or regenerated. + +- [#257](https://github.com/zendframework/zend-diactoros/pull/257) provides a + fix for the `PhpInputStream::read()` method to ensure string content that + evaluates as empty (including `0`) is still cached. + +- [#258](https://github.com/zendframework/zend-diactoros/pull/258) updates the + `Uri::filterPath()` method to allow parens within a URI path, per [RFC 3986 + section 3.3](https://tools.ietf.org/html/rfc3986#section-3.3) (parens are + within the character set "sub-delims"). + +## 1.4.0 - 2017-04-06 + +### Added + +- [#219](https://github.com/zendframework/zend-diactoros/pull/219) adds two new + classes, `Zend\Diactoros\Request\ArraySerializer` and + `Zend\Diactoros\Response\ArraySerializer`. Each exposes the static methods + `toArray()` and `fromArray()`, allowing de/serialization of messages from and + to arrays. + +- [#236](https://github.com/zendframework/zend-diactoros/pull/236) adds two new + constants to the `Response` class: `MIN_STATUS_CODE_VALUE` and + `MAX_STATUS_CODE_VALUE`. + +### Changes + +- [#240](https://github.com/zendframework/zend-diactoros/pull/240) changes the + behavior of `ServerRequestFactory::fromGlobals()` when no `$cookies` argument + is present. Previously, it would use `$_COOKIES`; now, if a `Cookie` header is + present, it will parse and use that to populate the instance instead. + + This change allows utilizing cookies that contain period characters (`.`) in + their names (PHP's built-in cookie handling renames these to replace `.` with + `_`, which can lead to synchronization issues with clients). + +- [#235](https://github.com/zendframework/zend-diactoros/pull/235) changes the + behavior of `Uri::__toString()` to better follow proscribed behavior in PSR-7. + In particular, prior to this release, if a scheme was missing but an authority + was present, the class was incorrectly returning a value that did not include + a `//` prefix. As of this release, it now does this correctly. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 1.3.11 - 2017-04-06 + +### Added + +- Nothing. + +### Changes + +- [#241](https://github.com/zendframework/zend-diactoros/pull/241) changes the + constraint by which the package provides `psr/http-message-implementation` to + simply `1.0` instead of `~1.0.0`, to follow how other implementations provide + PSR-7. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#161](https://github.com/zendframework/zend-diactoros/pull/161) adds + additional validations to header names and values to ensure no malformed values + are provided. + +- [#234](https://github.com/zendframework/zend-diactoros/pull/234) fixes a + number of reason phrases in the `Response` instance, and adds automation from + the canonical IANA sources to ensure any new phrases added are correct. + +## 1.3.10 - 2017-01-23 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#226](https://github.com/zendframework/zend-diactoros/pull/226) fixed an + issue with the `SapiStreamEmitter` causing the response body to be cast + to `(string)` and also be read as a readable stream, potentially producing + double output. + +## 1.3.9 - 2017-01-17 ### Added @@ -18,6 +150,364 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed +- [#223](https://github.com/zendframework/zend-diactoros/issues/223) + [#224](https://github.com/zendframework/zend-diactoros/pull/224) fixed an issue + with the `SapiStreamEmitter` consuming too much memory when producing output + for readable bodies. + +## 1.3.8 - 2017-01-05 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#222](https://github.com/zendframework/zend-diactoros/pull/222) fixes the + `SapiStreamEmitter`'s handling of the `Content-Range` header to properly only + emit a range of bytes if the header value is in the form `bytes {first-last}/length`. + This allows using other range units, such as `items`, without incorrectly + emitting truncated content. + +## 1.3.7 - 2016-10-11 + +### Added + +- [#208](https://github.com/zendframework/zend-diactoros/pull/208) adds several + missing response codes to `Zend\Diactoros\Response`, including: + - 226 ('IM used') + - 308 ('Permanent Redirect') + - 444 ('Connection Closed Without Response') + - 499 ('Client Closed Request') + - 510 ('Not Extended') + - 599 ('Network Connect Timeout Error') +- [#211](https://github.com/zendframework/zend-diactoros/pull/211) adds support + for UTF-8 characters in query strings handled by `Zend\Diactoros\Uri`. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 1.3.6 - 2016-09-07 + +### Added + +- [#170](https://github.com/zendframework/zend-diactoros/pull/170) prepared + documentation for publication at https://zendframework.github.io/zend-diactoros/ +- [#165](https://github.com/zendframework/zend-diactoros/pull/165) adds support + for Apache `REDIRECT_HTTP_*` header detection in the `ServerRequestFactory`. +- [#166](https://github.com/zendframework/zend-diactoros/pull/166) adds support + for UTF-8 characters in URI paths. +- [#204](https://github.com/zendframework/zend-diactoros/pull/204) adds testing + against PHP 7.1 release-candidate builds. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#186](https://github.com/zendframework/zend-diactoros/pull/186) fixes a typo + in a variable name within the `SapiStreamEmitter`. +- [#200](https://github.com/zendframework/zend-diactoros/pull/200) updates the + `SapiStreamEmitter` to implement a check for `isSeekable()` prior to attempts + to rewind; this allows it to work with non-seekable streams such as the + `CallbackStream`. +- [#169](https://github.com/zendframework/zend-diactoros/pull/169) ensures that + response serialization always provides a `\r\n\r\n` sequence following the + headers, even when no message body is present, to ensure it conforms with RFC + 7230. +- [#175](https://github.com/zendframework/zend-diactoros/pull/175) updates the + `Request` class to set the `Host` header from the URI host if no header is + already present. (Ensures conformity with PSR-7 specification.) +- [#197](https://github.com/zendframework/zend-diactoros/pull/197) updates the + `Uri` class to ensure that string serialization does not include a colon after + the host name if no port is present in the instance. + +## 1.3.5 - 2016-03-17 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#160](https://github.com/zendframework/zend-diactoros/pull/160) fixes HTTP + protocol detection in the `ServerRequestFactory` to work correctly with HTTP/2. + +## 1.3.4 - 2016-03-17 + +### Added + +- [#119](https://github.com/zendframework/zend-diactoros/pull/119) adds the 451 + (Unavailable for Legal Reasons) status code to the `Response` class. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#117](https://github.com/zendframework/zend-diactoros/pull/117) provides + validation of the HTTP protocol version. +- [#127](https://github.com/zendframework/zend-diactoros/pull/127) now properly + removes attributes with `null` values when calling `withoutAttribute()`. +- [#132](https://github.com/zendframework/zend-diactoros/pull/132) updates the + `ServerRequestFactory` to marshal the request path fragment, if present. +- [#142](https://github.com/zendframework/zend-diactoros/pull/142) updates the + exceptions thrown by `HeaderSecurity` to include the header name and/or + value. +- [#148](https://github.com/zendframework/zend-diactoros/pull/148) fixes several + stream operations to ensure they raise exceptions when the internal pointer + is at an invalid position. +- [#151](https://github.com/zendframework/zend-diactoros/pull/151) ensures + URI fragments are properly encoded. + +## 1.3.3 - 2016-01-04 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#135](https://github.com/zendframework/zend-diactoros/pull/135) fixes the + behavior of `ServerRequestFactory::marshalHeaders()` to no longer omit + `Cookie` headers from the aggregated headers. While the values are parsed and + injected into the cookie params, it's useful to have access to the raw headers + as well. + +## 1.3.2 - 2015-12-22 + +### Added + +- [#124](https://github.com/zendframework/zend-diactoros/pull/124) adds four + more optional arguments to the `ServerRequest` constructor: + - `array $cookies` + - `array $queryParams` + - `null|array|object $parsedBody` + - `string $protocolVersion` + `ServerRequestFactory` was updated to pass values for each of these parameters + when creating an instance, instead of using the related `with*()` methods on + an instance. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#122](https://github.com/zendframework/zend-diactoros/pull/122) updates the + `ServerRequestFactory` to retrieve the HTTP protocol version and inject it in + the generated `ServerRequest`, which previously was not performed. + +## 1.3.1 - 2015-12-16 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#113](https://github.com/zendframework/zend-diactoros/pull/113) fixes an + issue in the response serializer, ensuring that the status code in the + deserialized response is an integer. +- [#115](https://github.com/zendframework/zend-diactoros/pull/115) fixes an + issue in the various text-basd response types (`TextResponse`, `HtmlResponse`, + and `JsonResponse`); due to the fact that the constructor was not + rewinding the message body stream, `getContents()` was thus returning `null`, + as the pointer was at the end of the stream. The constructor now rewinds the + stream after populating it in the constructor. + +## 1.3.0 - 2015-12-15 + +### Added + +- [#110](https://github.com/zendframework/zend-diactoros/pull/110) adds + `Zend\Diactoros\Response\SapiEmitterTrait`, which provides the following + private method definitions: + - `injectContentLength()` + - `emitStatusLine()` + - `emitHeaders()` + - `flush()` + - `filterHeader()` + The `SapiEmitter` implementation has been updated to remove those methods and + instead compose the trait. +- [#111](https://github.com/zendframework/zend-diactoros/pull/111) adds + a new emitter implementation, `SapiStreamEmitter`; this emitter type will + loop through the stream instead of emitting it in one go, and supports content + ranges. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 1.2.1 - 2015-12-15 + +### Added + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#101](https://github.com/zendframework/zend-diactoros/pull/101) fixes the + `withHeader()` implementation to ensure that if the header existed previously + but using a different casing strategy, the previous version will be removed + in the cloned instance. +- [#103](https://github.com/zendframework/zend-diactoros/pull/103) fixes the + constructor of `Response` to ensure that null status codes are not possible. +- [#99](https://github.com/zendframework/zend-diactoros/pull/99) fixes + validation of header values submitted via request and response constructors as + follows: + - numeric (integer and float) values are now properly allowed (this solves + some reported issues with setting Content-Length headers) + - invalid header names (non-string values or empty strings) now raise an + exception. + - invalid individual header values (non-string, non-numeric) now raise an + exception. + +## 1.2.0 - 2015-11-24 + +### Added + +- [#88](https://github.com/zendframework/zend-diactoros/pull/88) updates the + `SapiEmitter` to emit a `Content-Length` header with the content length as + reported by the response body stream, assuming that + `StreamInterface::getSize()` returns an integer. +- [#77](https://github.com/zendframework/zend-diactoros/pull/77) adds a new + response type, `Zend\Diactoros\Response\TextResponse`, for returning plain + text responses. By default, it sets the content type to `text/plain; + charset=utf-8`; per the other response types, the signature is `new + TextResponse($text, $status = 200, array $headers = [])`. +- [#90](https://github.com/zendframework/zend-diactoros/pull/90) adds a new + `Zend\Diactoros\CallbackStream`, allowing you to back a stream with a PHP + callable (such as a generator) to generate the message content. Its + constructor accepts the callable: `$stream = new CallbackStream($callable);` + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#77](https://github.com/zendframework/zend-diactoros/pull/77) updates the + `HtmlResponse` to set the charset to utf-8 by default (if no content type + header is provided at instantiation). + +## 1.1.4 - 2015-10-16 + +### Added + +- [#98](https://github.com/zendframework/zend-diactoros/pull/98) adds + `JSON_UNESCAPED_SLASHES` to the default `json_encode` flags used by + `Zend\Diactoros\Response\JsonResponse`. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#96](https://github.com/zendframework/zend-diactoros/pull/96) updates + `withPort()` to allow `null` port values (indicating usage of default for + the given scheme). +- [#91](https://github.com/zendframework/zend-diactoros/pull/91) fixes the + logic of `withUri()` to do a case-insensitive check for an existing `Host` + header, replacing it with the new one. + +## 1.1.3 - 2015-08-10 + +### Added + +- [#73](https://github.com/zendframework/zend-diactoros/pull/73) adds caching of + the vendor directory to the Travis-CI configuration, to speed up builds. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + - [#71](https://github.com/zendframework/zend-diactoros/pull/71) fixes the docblock of the `JsonResponse` constructor to typehint the `$data` argument as `mixed`. @@ -181,7 +671,7 @@ immediately. - [#57](https://github.com/zendframework/zend-diactoros/pull/57) fixes the behavior of how the `ServerRequestFactory` marshals upload files when they are represented as a nested associative array. -- [#49](https://github.com/zendframework/zend-diactoros/pull/49) provides several +- [#49](https://github.com/zendframework/zend-diactoros/pull/49) provides several fixes that ensure that Diactoros complies with the PSR-7 specification: - `MessageInterface::getHeaderLine()` MUST return a string (that string CAN be empty). Previously, Diactoros would return `null`. diff --git a/vendor/zendframework/zend-diactoros/CONDUCT.md b/vendor/zendframework/zend-diactoros/CONDUCT.md new file mode 100644 index 00000000..c663d2be --- /dev/null +++ b/vendor/zendframework/zend-diactoros/CONDUCT.md @@ -0,0 +1,43 @@ +# Contributor Code of Conduct + +The Zend Framework project adheres to [The Code Manifesto](http://codemanifesto.com) +as its guidelines for contributor interactions. + +## The Code Manifesto + +We want to work in an ecosystem that empowers developers to reach their +potential — one that encourages growth and effective collaboration. A space that +is safe for all. + +A space such as this benefits everyone that participates in it. It encourages +new developers to enter our field. It is through discussion and collaboration +that we grow, and through growth that we improve. + +In the effort to create such a place, we hold to these values: + +1. **Discrimination limits us.** This includes discrimination on the basis of + race, gender, sexual orientation, gender identity, age, nationality, technology + and any other arbitrary exclusion of a group of people. +2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort + levels. Remember that, and if brought to your attention, heed it. +3. **We are our biggest assets.** None of us were born masters of our trade. + Each of us has been helped along the way. Return that favor, when and where + you can. +4. **We are resources for the future.** As an extension of #3, share what you + know. Make yourself a resource to help those that come after you. +5. **Respect defines us.** Treat others as you wish to be treated. Make your + discussions, criticisms and debates from a position of respectfulness. Ask + yourself, is it true? Is it necessary? Is it constructive? Anything less is + unacceptable. +6. **Reactions require grace.** Angry responses are valid, but abusive language + and vindictive actions are toxic. When something happens that offends you, + handle it assertively, but be respectful. Escalate reasonably, and try to + allow the offender an opportunity to explain themselves, and possibly correct + the issue. +7. **Opinions are just that: opinions.** Each and every one of us, due to our + background and upbringing, have varying opinions. The fact of the matter, is + that is perfectly acceptable. Remember this: if you respect your own + opinions, you should respect the opinions of others. +8. **To err is human.** You might not intend it, but mistakes do happen and + contribute to build experience. Tolerate honest mistakes, and don't hesitate + to apologize if you make one yourself. diff --git a/vendor/zendframework/zend-diactoros/CONTRIBUTING.md b/vendor/zendframework/zend-diactoros/CONTRIBUTING.md index d99a16cb..817ba7bf 100644 --- a/vendor/zendframework/zend-diactoros/CONTRIBUTING.md +++ b/vendor/zendframework/zend-diactoros/CONTRIBUTING.md @@ -78,14 +78,14 @@ standards checks, and provides configuration for our selected checks. To run checks only: ```console -$ ./vendor/bin/phpcs --standard=PSR2 src test +$ composer cs-check ``` `phpcs` also installs a tool named `phpcbf` which can attempt to fix problems for you: ```console -$ ./vendor/bin/phpcbf --standard=PSR2 src test +$ composer cs-fix ``` If you allow phpcbf to fix CS issues, please re-run the tests to ensure @@ -102,7 +102,7 @@ pull your work into the master repository. We recommend using 3. Clone the canonical repository locally and enter it. ```console - $ git clone git://github.com:zendframework/zend-diactoros.git + $ git clone git://github.com/zendframework/zend-diactoros.git $ cd zend-diactoros ``` @@ -221,3 +221,8 @@ repository, we suggest doing some cleanup of these branches. ```console $ git push {username} : ``` + + +## Conduct + +Please see our [CONDUCT.md](CONDUCT.md) to understand expected behavior when interacting with others in the project. diff --git a/vendor/zendframework/zend-diactoros/LICENSE.md b/vendor/zendframework/zend-diactoros/LICENSE.md index b401e72d..c7e9a85d 100644 --- a/vendor/zendframework/zend-diactoros/LICENSE.md +++ b/vendor/zendframework/zend-diactoros/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2015, Zend Technologies USA, Inc. +Copyright (c) 2015-2016, Zend Technologies USA, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/vendor/zendframework/zend-diactoros/README.md b/vendor/zendframework/zend-diactoros/README.md index b25dc9b3..fadb18c2 100644 --- a/vendor/zendframework/zend-diactoros/README.md +++ b/vendor/zendframework/zend-diactoros/README.md @@ -18,17 +18,11 @@ This package supercedes and replaces [phly/http](https://github.com/phly/http). ## Documentation -Documentation is [in the doc tree](doc/), and can be compiled using [bookdown](http://bookdown.io): +Documentation is available at: -```console -$ bookdown doc/bookdown.json -$ php -S 0.0.0.0:8080 -t doc/html/ # then browse to http://localhost:8080/ -``` +- https://zendframework.github.io/zend-diactoros/ -> ### Bookdown -> -> You can install bookdown globally using `composer global require bookdown/bookdown`. If you do -> this, make sure that `$HOME/.composer/vendor/bin` is on your `$PATH`. +Source files for documentation are [in the doc/ tree](doc/). [Master]: https://travis-ci.org/zendframework/zend-diactoros [Master image]: https://secure.travis-ci.org/zendframework/zend-diactoros.svg?branch=master diff --git a/vendor/zendframework/zend-diactoros/composer.json b/vendor/zendframework/zend-diactoros/composer.json index fee75d9a..12e4a9f3 100644 --- a/vendor/zendframework/zend-diactoros/composer.json +++ b/vendor/zendframework/zend-diactoros/composer.json @@ -15,20 +15,22 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" + "dev-master": "1.4-dev", + "dev-develop": "1.5-dev" } }, "require": { - "php": ">=5.4", + "php": "^5.4 || ^7.0", "psr/http-message": "~1.0" }, "require-dev": { - "phpunit/PHPUnit": "~4.6", - "squizlabs/php_codesniffer": "^2.3.1" + "phpunit/phpunit": "^4.6 || ^5.5", + "zendframework/zend-coding-standard": "~1.0.0", + "ext-dom": "*", + "ext-libxml": "*" }, "provide": { - "psr/http-message-implementation": "~1.0.0" + "psr/http-message-implementation": "1.0" }, "autoload": { "psr-4": { @@ -43,5 +45,16 @@ "test/TestAsset/Functions.php", "test/TestAsset/SapiResponse.php" ] + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "upload-coverage": "coveralls -v", + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "test": "phpunit --colors=always", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" } } diff --git a/vendor/zendframework/zend-diactoros/composer.lock b/vendor/zendframework/zend-diactoros/composer.lock new file mode 100644 index 00000000..c73430e4 --- /dev/null +++ b/vendor/zendframework/zend-diactoros/composer.lock @@ -0,0 +1,1145 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "287996fa611f46eb393c625c762f709f", + "content-hash": "3efa62db7f378a4802a4cf729875f3aa", + "packages": [ + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06 14:39:51" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/prophecy", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2017-03-02 20:05:34" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-10-06 15:47:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2016-10-03 07:40:28" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26 11:10:40" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-02-27 10:12:30" + }, + { + "name": "phpunit/phpunit", + "version": "4.8.35", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/791b1a67c25af50e230f841ee7a9c6eba507dc87", + "reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2017-02-06 05:18:07" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2015-10-02 06:51:40" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29 09:50:25" + }, + { + "name": "sebastian/diff", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-12-08 07:14:41" + }, + { + "name": "sebastian/environment", + "version": "1.3.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-08-18 05:49:44" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-06-17 09:04:28" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12 03:26:01" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-10-03 07:41:43" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2015-06-21 13:59:46" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "scripts/phpcs", + "scripts/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "CodeSniffer.php", + "CodeSniffer/CLI.php", + "CodeSniffer/Exception.php", + "CodeSniffer/File.php", + "CodeSniffer/Fixer.php", + "CodeSniffer/Report.php", + "CodeSniffer/Reporting.php", + "CodeSniffer/Sniff.php", + "CodeSniffer/Tokens.php", + "CodeSniffer/Reports/", + "CodeSniffer/Tokenizers/", + "CodeSniffer/DocGenerators/", + "CodeSniffer/Standards/AbstractPatternSniff.php", + "CodeSniffer/Standards/AbstractScopeSniff.php", + "CodeSniffer/Standards/AbstractVariableSniff.php", + "CodeSniffer/Standards/IncorrectPatternException.php", + "CodeSniffer/Standards/Generic/Sniffs/", + "CodeSniffer/Standards/MySource/Sniffs/", + "CodeSniffer/Standards/PEAR/Sniffs/", + "CodeSniffer/Standards/PSR1/Sniffs/", + "CodeSniffer/Standards/PSR2/Sniffs/", + "CodeSniffer/Standards/Squiz/Sniffs/", + "CodeSniffer/Standards/Zend/Sniffs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2017-03-01 22:17:45" + }, + { + "name": "symfony/yaml", + "version": "v2.8.19", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "286d84891690b0e2515874717e49360d1c98a703" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/286d84891690b0e2515874717e49360d1c98a703", + "reference": "286d84891690b0e2515874717e49360d1c98a703", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2017-03-20 09:41:44" + }, + { + "name": "zendframework/zend-coding-standard", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-coding-standard.git", + "reference": "893316d2904e93f1c74c1384b6d7d57778299cb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-coding-standard/zipball/893316d2904e93f1c74c1384b6d7d57778299cb6", + "reference": "893316d2904e93f1c74c1384b6d7d57778299cb6", + "shasum": "" + }, + "require": { + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Zend Framework coding standard", + "keywords": [ + "Coding Standard", + "zf" + ], + "time": "2016-11-09 21:30:43" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^5.4 || ^7.0" + }, + "platform-dev": { + "ext-dom": "*", + "ext-libxml": "*" + } +} diff --git a/vendor/zendframework/zend-diactoros/mkdocs.yml b/vendor/zendframework/zend-diactoros/mkdocs.yml new file mode 100644 index 00000000..a0866064 --- /dev/null +++ b/vendor/zendframework/zend-diactoros/mkdocs.yml @@ -0,0 +1,16 @@ +docs_dir: doc/book +site_dir: doc/html +pages: + - index.md + - Overview: overview.md + - Installation: install.md + - Usage: usage.md + - Reference: + - "Custom Responses": custom-responses.md + - "Emitting Responses": emitting-responses.md + - Serialization: serialization.md + - API: api.md +site_name: zend-diactoros +site_description: 'zend-diactoros: PSR-7 HTTP message implementation' +repo_url: 'https://github.com/zendframework/zend-diactoros' +copyright: 'Copyright (c) 2016 Zend Technologies USA Inc.' diff --git a/vendor/zendframework/zend-diactoros/phpcs.xml b/vendor/zendframework/zend-diactoros/phpcs.xml deleted file mode 100644 index e994eae1..00000000 --- a/vendor/zendframework/zend-diactoros/phpcs.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - Zend Framework coding standard - - - - - - - - - - - - - - - - src - test - diff --git a/vendor/zendframework/zend-diactoros/src/AbstractSerializer.php b/vendor/zendframework/zend-diactoros/src/AbstractSerializer.php index a55ca5a3..9ee9afd0 100644 --- a/vendor/zendframework/zend-diactoros/src/AbstractSerializer.php +++ b/vendor/zendframework/zend-diactoros/src/AbstractSerializer.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/CallbackStream.php b/vendor/zendframework/zend-diactoros/src/CallbackStream.php new file mode 100644 index 00000000..c8e6bc6f --- /dev/null +++ b/vendor/zendframework/zend-diactoros/src/CallbackStream.php @@ -0,0 +1,181 @@ +attach($callback); + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->getContents(); + } + + /** + * {@inheritdoc} + */ + public function close() + { + $this->callback = null; + } + + /** + * {@inheritdoc} + */ + public function detach() + { + $callback = $this->callback; + $this->callback = null; + return $callback; + } + + /** + * Attach a new callback to the instance. + * + * @param callable $callback + * @throws InvalidArgumentException for callable callback + */ + public function attach(callable $callback) + { + $this->callback = $callback; + } + + /** + * {@inheritdoc} + */ + public function getSize() + { + } + + /** + * {@inheritdoc} + */ + public function tell() + { + throw new RuntimeException('Callback streams cannot tell position'); + } + + /** + * {@inheritdoc} + */ + public function eof() + { + return empty($this->callback); + } + + /** + * {@inheritdoc} + */ + public function isSeekable() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function seek($offset, $whence = SEEK_SET) + { + throw new RuntimeException('Callback streams cannot seek position'); + } + + /** + * {@inheritdoc} + */ + public function rewind() + { + throw new RuntimeException('Callback streams cannot rewind position'); + } + + /** + * {@inheritdoc} + */ + public function isWritable() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function write($string) + { + throw new RuntimeException('Callback streams cannot write'); + } + + /** + * {@inheritdoc} + */ + public function isReadable() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function read($length) + { + throw new RuntimeException('Callback streams cannot read'); + } + + /** + * {@inheritdoc} + */ + public function getContents() + { + $callback = $this->detach(); + return $callback ? $callback() : ''; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($key = null) + { + $metadata = [ + 'eof' => $this->eof(), + 'stream_type' => 'callback', + 'seekable' => false + ]; + + if (null === $key) { + return $metadata; + } + + if (! array_key_exists($key, $metadata)) { + return null; + } + + return $metadata[$key]; + } +} diff --git a/vendor/zendframework/zend-diactoros/src/Exception/DeprecatedMethodException.php b/vendor/zendframework/zend-diactoros/src/Exception/DeprecatedMethodException.php index bdef44a1..59a2e419 100644 --- a/vendor/zendframework/zend-diactoros/src/Exception/DeprecatedMethodException.php +++ b/vendor/zendframework/zend-diactoros/src/Exception/DeprecatedMethodException.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/Exception/ExceptionInterface.php b/vendor/zendframework/zend-diactoros/src/Exception/ExceptionInterface.php index a2b22fbf..4bb54df8 100644 --- a/vendor/zendframework/zend-diactoros/src/Exception/ExceptionInterface.php +++ b/vendor/zendframework/zend-diactoros/src/Exception/ExceptionInterface.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/HeaderSecurity.php b/vendor/zendframework/zend-diactoros/src/HeaderSecurity.php index 231beac0..ecca716b 100644 --- a/vendor/zendframework/zend-diactoros/src/HeaderSecurity.php +++ b/vendor/zendframework/zend-diactoros/src/HeaderSecurity.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -24,6 +24,7 @@ final class HeaderSecurity { /** * Private constructor; non-instantiable. + * @codeCoverageIgnore */ private function __construct() { @@ -128,8 +129,17 @@ public static function isValid($value) */ public static function assertValid($value) { + if (! is_string($value) && ! is_numeric($value)) { + throw new InvalidArgumentException(sprintf( + 'Invalid header value type; must be a string or numeric; received %s', + (is_object($value) ? get_class($value) : gettype($value)) + )); + } if (! self::isValid($value)) { - throw new InvalidArgumentException('Invalid header value'); + throw new InvalidArgumentException(sprintf( + '"%s" is not valid header value', + $value + )); } } @@ -142,8 +152,17 @@ public static function assertValid($value) */ public static function assertValidName($name) { + if (! is_string($name)) { + throw new InvalidArgumentException(sprintf( + 'Invalid header name type; expected string; received %s', + (is_object($name) ? get_class($name) : gettype($name)) + )); + } if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/', $name)) { - throw new InvalidArgumentException('Invalid header name'); + throw new InvalidArgumentException(sprintf( + '"%s" is not valid header name', + $name + )); } } } diff --git a/vendor/zendframework/zend-diactoros/src/MessageTrait.php b/vendor/zendframework/zend-diactoros/src/MessageTrait.php index 1b3fc6f5..1c9768b5 100644 --- a/vendor/zendframework/zend-diactoros/src/MessageTrait.php +++ b/vendor/zendframework/zend-diactoros/src/MessageTrait.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -70,6 +70,7 @@ public function getProtocolVersion() */ public function withProtocolVersion($version) { + $this->validateProtocolVersion($version); $new = clone $this; $new->protocol = $version; return $new; @@ -111,7 +112,7 @@ public function getHeaders() */ public function hasHeader($header) { - return array_key_exists(strtolower($header), $this->headerNames); + return isset($this->headerNames[strtolower($header)]); } /** @@ -135,10 +136,8 @@ public function getHeader($header) } $header = $this->headerNames[strtolower($header)]; - $value = $this->headers[$header]; - $value = is_array($value) ? $value : [$value]; - return $value; + return $this->headers[$header]; } /** @@ -188,22 +187,17 @@ public function getHeaderLine($name) */ public function withHeader($header, $value) { - if (is_string($value)) { - $value = [$value]; - } - - if (! is_array($value) || ! $this->arrayContainsOnlyStrings($value)) { - throw new InvalidArgumentException( - 'Invalid header value; must be a string or array of strings' - ); - } - - HeaderSecurity::assertValidName($header); - self::assertValidHeaderValue($value); + $this->assertHeader($header); $normalized = strtolower($header); $new = clone $this; + if ($new->hasHeader($header)) { + unset($new->headers[$new->headerNames[$normalized]]); + } + + $value = $this->filterHeaderValue($value); + $new->headerNames[$normalized] = $header; $new->headers[$header] = $value; @@ -229,27 +223,16 @@ public function withHeader($header, $value) */ public function withAddedHeader($header, $value) { - if (is_string($value)) { - $value = [ $value ]; - } - - if (! is_array($value) || ! $this->arrayContainsOnlyStrings($value)) { - throw new InvalidArgumentException( - 'Invalid header value; must be a string or array of strings' - ); - } - - HeaderSecurity::assertValidName($header); - self::assertValidHeaderValue($value); + $this->assertHeader($header); if (! $this->hasHeader($header)) { return $this->withHeader($header, $value); } - $normalized = strtolower($header); - $header = $this->headerNames[$normalized]; + $header = $this->headerNames[strtolower($header)]; $new = clone $this; + $value = $this->filterHeaderValue($value); $new->headers[$header] = array_merge($this->headers[$header], $value); return $new; } @@ -310,15 +293,21 @@ public function withBody(StreamInterface $body) return $new; } - /** - * Test that an array contains only strings - * - * @param array $array - * @return bool - */ - private function arrayContainsOnlyStrings(array $array) + private function getStream($stream, $modeIfNotInstance) { - return array_reduce($array, [__CLASS__, 'filterStringValue'], true); + if ($stream instanceof StreamInterface) { + return $stream; + } + + if (! is_string($stream) && ! is_resource($stream)) { + throw new InvalidArgumentException( + 'Stream must be a string stream resource identifier, ' + . 'an actual stream resource, ' + . 'or a Psr\Http\Message\StreamInterface implementation' + ); + } + + return new Stream($stream, $modeIfNotInstance); } /** @@ -327,57 +316,80 @@ private function arrayContainsOnlyStrings(array $array) * Used by message constructors to allow setting all initial headers at once. * * @param array $originalHeaders Headers to filter. - * @return array Filtered headers and names. */ - private function filterHeaders(array $originalHeaders) + private function setHeaders(array $originalHeaders) { $headerNames = $headers = []; - foreach ($originalHeaders as $header => $value) { - if (! is_string($header)) { - continue; - } - if (! is_array($value) && ! is_string($value)) { - continue; - } + foreach ($originalHeaders as $header => $value) { + $value = $this->filterHeaderValue($value); - if (! is_array($value)) { - $value = [ $value ]; - } + $this->assertHeader($header); $headerNames[strtolower($header)] = $header; $headers[$header] = $value; } - return [$headerNames, $headers]; + $this->headerNames = $headerNames; + $this->headers = $headers; } /** - * Test if a value is a string - * - * Used with array_reduce. + * Validate the HTTP protocol version * - * @param bool $carry - * @param mixed $item - * @return bool + * @param string $version + * @throws InvalidArgumentException on invalid HTTP protocol version + */ + private function validateProtocolVersion($version) + { + if (empty($version)) { + throw new InvalidArgumentException(sprintf( + 'HTTP protocol version can not be empty' + )); + } + if (! is_string($version)) { + throw new InvalidArgumentException(sprintf( + 'Unsupported HTTP protocol version; must be a string, received %s', + (is_object($version) ? get_class($version) : gettype($version)) + )); + } + + // HTTP/1 uses a "." numbering scheme to indicate + // versions of the protocol, while HTTP/2 does not. + if (! preg_match('#^(1\.[01]|2)$#', $version)) { + throw new InvalidArgumentException(sprintf( + 'Unsupported HTTP protocol version "%s" provided', + $version + )); + } + } + + /** + * @param mixed $values + * @return string[] */ - private static function filterStringValue($carry, $item) + private function filterHeaderValue($values) { - if (! is_string($item)) { - return false; + if (! is_array($values)) { + $values = [$values]; } - return $carry; + + return array_map(function ($value) { + HeaderSecurity::assertValid($value); + + return (string) $value; + }, $values); } /** - * Assert that the provided header values are valid. + * Ensure header name and values are valid. + * + * @param string $name * - * @see http://tools.ietf.org/html/rfc7230#section-3.2 - * @param string[] $values * @throws InvalidArgumentException */ - private static function assertValidHeaderValue(array $values) + private function assertHeader($name) { - array_walk($values, __NAMESPACE__ . '\HeaderSecurity::assertValid'); + HeaderSecurity::assertValidName($name); } } diff --git a/vendor/zendframework/zend-diactoros/src/PhpInputStream.php b/vendor/zendframework/zend-diactoros/src/PhpInputStream.php index a035234e..eee973b6 100644 --- a/vendor/zendframework/zend-diactoros/src/PhpInputStream.php +++ b/vendor/zendframework/zend-diactoros/src/PhpInputStream.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -26,12 +26,10 @@ class PhpInputStream extends Stream /** * @param string|resource $stream - * @param string $mode */ - public function __construct($stream = 'php://input', $mode = 'r') + public function __construct($stream = 'php://input') { - $mode = 'r'; - parent::__construct($stream, $mode); + parent::__construct($stream, 'r'); } /** @@ -61,7 +59,7 @@ public function isWritable() public function read($length) { $content = parent::read($length); - if ($content && ! $this->reachedEof) { + if (! $this->reachedEof) { $this->cache .= $content; } diff --git a/vendor/zendframework/zend-diactoros/src/RelativeStream.php b/vendor/zendframework/zend-diactoros/src/RelativeStream.php index f293d519..819f4fd9 100644 --- a/vendor/zendframework/zend-diactoros/src/RelativeStream.php +++ b/vendor/zendframework/zend-diactoros/src/RelativeStream.php @@ -3,13 +3,14 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ namespace Zend\Diactoros; use Psr\Http\Message\StreamInterface; +use RuntimeException; /** * Class RelativeStream @@ -47,7 +48,9 @@ public function __construct(StreamInterface $decoratedStream, $offset) */ public function __toString() { - $this->seek(0); + if ($this->isSeekable()) { + $this->seek(0); + } return $this->getContents(); } @@ -131,6 +134,9 @@ public function isWritable() */ public function write($string) { + if ($this->tell() < 0) { + throw new RuntimeException('Invalid pointer position'); + } return $this->decoratedStream->write($string); } @@ -147,6 +153,9 @@ public function isReadable() */ public function read($length) { + if ($this->tell() < 0) { + throw new RuntimeException('Invalid pointer position'); + } return $this->decoratedStream->read($length); } @@ -155,6 +164,9 @@ public function read($length) */ public function getContents() { + if ($this->tell() < 0) { + throw new RuntimeException('Invalid pointer position'); + } return $this->decoratedStream->getContents(); } diff --git a/vendor/zendframework/zend-diactoros/src/Request.php b/vendor/zendframework/zend-diactoros/src/Request.php index 6e00c252..76805136 100644 --- a/vendor/zendframework/zend-diactoros/src/Request.php +++ b/vendor/zendframework/zend-diactoros/src/Request.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -11,6 +11,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriInterface; /** * HTTP Request encapsulation @@ -21,10 +22,10 @@ */ class Request implements RequestInterface { - use MessageTrait, RequestTrait; + use RequestTrait; /** - * @param null|string $uri URI for the request, if any. + * @param null|string|UriInterface $uri URI for the request, if any. * @param null|string $method HTTP method for the request, if any. * @param string|resource|StreamInterface $body Message body, if any. * @param array $headers Headers for the message, if any. @@ -42,7 +43,7 @@ public function getHeaders() { $headers = $this->headers; if (! $this->hasHeader('host') - && ($this->uri && $this->uri->getHost()) + && $this->uri->getHost() ) { $headers['Host'] = [$this->getHostFromUri()]; } @@ -57,7 +58,7 @@ public function getHeader($header) { if (! $this->hasHeader($header)) { if (strtolower($header) === 'host' - && ($this->uri && $this->uri->getHost()) + && $this->uri->getHost() ) { return [$this->getHostFromUri()]; } @@ -66,9 +67,7 @@ public function getHeader($header) } $header = $this->headerNames[strtolower($header)]; - $value = $this->headers[$header]; - $value = is_array($value) ? $value : [$value]; - return $value; + return $this->headers[$header]; } } diff --git a/vendor/zendframework/zend-diactoros/src/Request/ArraySerializer.php b/vendor/zendframework/zend-diactoros/src/Request/ArraySerializer.php new file mode 100644 index 00000000..f48db37e --- /dev/null +++ b/vendor/zendframework/zend-diactoros/src/Request/ArraySerializer.php @@ -0,0 +1,85 @@ + $request->getMethod(), + 'request_target' => $request->getRequestTarget(), + 'uri' => (string) $request->getUri(), + 'protocol_version' => $request->getProtocolVersion(), + 'headers' => $request->getHeaders(), + 'body' => (string) $request->getBody(), + ]; + } + + /** + * Deserialize a request array to a request instance. + * + * @param array $serializedRequest + * @return Request + * @throws UnexpectedValueException when cannot deserialize response + */ + public static function fromArray(array $serializedRequest) + { + try { + $uri = self::getValueFromKey($serializedRequest, 'uri'); + $method = self::getValueFromKey($serializedRequest, 'method'); + $body = new Stream('php://memory', 'wb+'); + $body->write(self::getValueFromKey($serializedRequest, 'body')); + $headers = self::getValueFromKey($serializedRequest, 'headers'); + $requestTarget = self::getValueFromKey($serializedRequest, 'request_target'); + $protocolVersion = self::getValueFromKey($serializedRequest, 'protocol_version'); + + return (new Request($uri, $method, $body, $headers)) + ->withRequestTarget($requestTarget) + ->withProtocolVersion($protocolVersion); + } catch (\Exception $exception) { + throw new UnexpectedValueException('Cannot deserialize request', null, $exception); + } + } + + /** + * @param array $data + * @param string $key + * @param string $message + * @return mixed + * @throws UnexpectedValueException + */ + private static function getValueFromKey(array $data, $key, $message = null) + { + if (isset($data[$key])) { + return $data[$key]; + } + if ($message === null) { + $message = sprintf('Missing "%s" key in serialized request', $key); + } + throw new UnexpectedValueException($message); + } +} diff --git a/vendor/zendframework/zend-diactoros/src/Request/Serializer.php b/vendor/zendframework/zend-diactoros/src/Request/Serializer.php index d7c8d131..8f45e5ed 100644 --- a/vendor/zendframework/zend-diactoros/src/Request/Serializer.php +++ b/vendor/zendframework/zend-diactoros/src/Request/Serializer.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -76,6 +76,10 @@ public static function fromStream(StreamInterface $stream) */ public static function toString(RequestInterface $request) { + $httpMethod = $request->getMethod(); + if (empty($httpMethod)) { + throw new UnexpectedValueException('Object can not be serialized because HTTP method is empty'); + } $headers = self::serializeHeaders($request->getHeaders()); $body = (string) $request->getBody(); $format = '%s %s HTTP/%s%s%s'; @@ -89,7 +93,7 @@ public static function toString(RequestInterface $request) return sprintf( $format, - $request->getMethod(), + $httpMethod, $request->getRequestTarget(), $request->getProtocolVersion(), $headers, diff --git a/vendor/zendframework/zend-diactoros/src/RequestTrait.php b/vendor/zendframework/zend-diactoros/src/RequestTrait.php index 2ef15a94..6117b98a 100644 --- a/vendor/zendframework/zend-diactoros/src/RequestTrait.php +++ b/vendor/zendframework/zend-diactoros/src/RequestTrait.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -22,14 +22,11 @@ * the environment. As such, this trait exists to provide the common code * between both client-side and server-side requests, and each can then * use the headers functionality required by their implementations. - * - * @property array $headers - * @property array $headerNames - * @property StreamInterface $stream - * @method bool hasHeader(string $header) */ trait RequestTrait { + use MessageTrait; + /** * @var string */ @@ -43,7 +40,7 @@ trait RequestTrait private $requestTarget; /** - * @var null|UriInterface + * @var UriInterface */ private $uri; @@ -52,7 +49,7 @@ trait RequestTrait * * Used by constructors. * - * @param null|string $uri URI for the request, if any. + * @param null|string|UriInterface $uri URI for the request, if any. * @param null|string $method HTTP method for the request, if any. * @param string|resource|StreamInterface $body Message body, if any. * @param array $headers Headers for the message, if any. @@ -60,33 +57,52 @@ trait RequestTrait */ private function initialize($uri = null, $method = null, $body = 'php://memory', array $headers = []) { - if (! $uri instanceof UriInterface && ! is_string($uri) && null !== $uri) { - throw new InvalidArgumentException( - 'Invalid URI provided; must be null, a string, or a Psr\Http\Message\UriInterface instance' - ); - } - $this->validateMethod($method); - if (! is_string($body) && ! is_resource($body) && ! $body instanceof StreamInterface) { - throw new InvalidArgumentException( - 'Body must be a string stream resource identifier, ' - . 'an actual stream resource, ' - . 'or a Psr\Http\Message\StreamInterface implementation' - ); + $this->method = $method ?: ''; + $this->uri = $this->createUri($uri); + $this->stream = $this->getStream($body, 'wb+'); + + $this->setHeaders($headers); + + // per PSR-7: attempt to set the Host header from a provided URI if no + // Host header is provided + if (! $this->hasHeader('Host') && $this->uri->getHost()) { + $this->headerNames['host'] = 'Host'; + $this->headers['Host'] = [$this->getHostFromUri()]; } + } + /** + * Create and return a URI instance. + * + * If `$uri` is a already a `UriInterface` instance, returns it. + * + * If `$uri` is a string, passes it to the `Uri` constructor to return an + * instance. + * + * If `$uri is null, creates and returns an empty `Uri` instance. + * + * Otherwise, it raises an exception. + * + * @param null|string|UriInterface $uri + * @return UriInterface + * @throws InvalidArgumentException + */ + private function createUri($uri) + { + if ($uri instanceof UriInterface) { + return $uri; + } if (is_string($uri)) { - $uri = new Uri($uri); + return new Uri($uri); } - - $this->method = $method ?: ''; - $this->uri = $uri ?: new Uri(); - $this->stream = ($body instanceof StreamInterface) ? $body : new Stream($body, 'wb+'); - - list($this->headerNames, $headers) = $this->filterHeaders($headers); - $this->assertHeaders($headers); - $this->headers = $headers; + if ($uri === null) { + return new Uri(); + } + throw new InvalidArgumentException( + 'Invalid URI provided; must be null, a string, or a Psr\Http\Message\UriInterface instance' + ); } /** @@ -111,10 +127,6 @@ public function getRequestTarget() return $this->requestTarget; } - if (! $this->uri) { - return '/'; - } - $target = $this->uri->getPath(); if ($this->uri->getQuery()) { $target .= '?' . $this->uri->getQuery(); @@ -249,6 +261,16 @@ public function withUri(UriInterface $uri, $preserveHost = false) } $new->headerNames['host'] = 'Host'; + + // Remove an existing host header if present, regardless of current + // de-normalization of the header name. + // @see https://github.com/zendframework/zend-diactoros/issues/91 + foreach (array_keys($new->headers) as $header) { + if (strtolower($header) === 'host') { + unset($new->headers[$header]); + } + } + $new->headers['Host'] = [$host]; return $new; @@ -292,18 +314,4 @@ private function getHostFromUri() $host .= $this->uri->getPort() ? ':' . $this->uri->getPort() : ''; return $host; } - - /** - * Ensure header names and values are valid. - * - * @param array $headers - * @throws InvalidArgumentException - */ - private function assertHeaders(array $headers) - { - foreach ($headers as $name => $headerValues) { - HeaderSecurity::assertValidName($name); - array_walk($headerValues, __NAMESPACE__ . '\HeaderSecurity::assertValid'); - } - } } diff --git a/vendor/zendframework/zend-diactoros/src/Response.php b/vendor/zendframework/zend-diactoros/src/Response.php index ef250e6a..cd22b5db 100644 --- a/vendor/zendframework/zend-diactoros/src/Response.php +++ b/vendor/zendframework/zend-diactoros/src/Response.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -24,6 +24,9 @@ class Response implements ResponseInterface { use MessageTrait; + const MIN_STATUS_CODE_VALUE = 100; + const MAX_STATUS_CODE_VALUE = 599; + /** * Map of standard HTTP status code/reason phrases * @@ -42,8 +45,9 @@ class Response implements ResponseInterface 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', - 207 => 'Multi-status', + 207 => 'Multi-Status', 208 => 'Already Reported', + 226 => 'IM Used', // REDIRECTION CODES 300 => 'Multiple Choices', 301 => 'Moved Permanently', @@ -51,8 +55,9 @@ class Response implements ResponseInterface 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', - 306 => 'Switch Proxy', // Deprecated + 306 => 'Switch Proxy', // Deprecated to 306 => '(Unused)' 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', // CLIENT ERROR 400 => 'Bad Request', 401 => 'Unauthorized', @@ -62,17 +67,18 @@ class Response implements ResponseInterface 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', - 408 => 'Request Time-out', + 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Large', + 413 => 'Payload Too Large', + 414 => 'URI Too Long', 415 => 'Unsupported Media Type', - 416 => 'Requested range not satisfiable', + 416 => 'Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', + 421 => 'Misdirected Request', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', @@ -81,17 +87,22 @@ class Response implements ResponseInterface 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', + 444 => 'Connection Closed Without Response', + 451 => 'Unavailable For Legal Reasons', // SERVER ERROR + 499 => 'Client Closed Request', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', - 504 => 'Gateway Time-out', - 505 => 'HTTP Version not supported', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', + 510 => 'Not Extended', 511 => 'Network Authentication Required', + 599 => 'Network Connect Timeout Error', ]; /** @@ -102,34 +113,19 @@ class Response implements ResponseInterface /** * @var int */ - private $statusCode = 200; + private $statusCode; /** - * @param string|resource|StreamInterface $stream Stream identifier and/or actual stream resource + * @param string|resource|StreamInterface $body Stream identifier and/or actual stream resource * @param int $status Status code for the response, if any. * @param array $headers Headers for the response, if any. * @throws InvalidArgumentException on any invalid element. */ public function __construct($body = 'php://memory', $status = 200, array $headers = []) { - if (! is_string($body) && ! is_resource($body) && ! $body instanceof StreamInterface) { - throw new InvalidArgumentException( - 'Stream must be a string stream resource identifier, ' - . 'an actual stream resource, ' - . 'or a Psr\Http\Message\StreamInterface implementation' - ); - } - - if (null !== $status) { - $this->validateStatus($status); - } - - $this->stream = ($body instanceof StreamInterface) ? $body : new Stream($body, 'wb+'); - $this->statusCode = $status ? (int) $status : 200; - - list($this->headerNames, $headers) = $this->filterHeaders($headers); - $this->assertHeaders($headers); - $this->headers = $headers; + $this->setStatusCode($status); + $this->stream = $this->getStream($body, 'wb+'); + $this->setHeaders($headers); } /** @@ -159,44 +155,32 @@ public function getReasonPhrase() */ public function withStatus($code, $reasonPhrase = '') { - $this->validateStatus($code); $new = clone $this; - $new->statusCode = (int) $code; + $new->setStatusCode($code); $new->reasonPhrase = $reasonPhrase; return $new; } /** - * Validate a status code. + * Set a valid status code. * - * @param int|string $code + * @param int $code * @throws InvalidArgumentException on an invalid status code. */ - private function validateStatus($code) + private function setStatusCode($code) { if (! is_numeric($code) || is_float($code) - || $code < 100 - || $code >= 600 + || $code < static::MIN_STATUS_CODE_VALUE + || $code > static::MAX_STATUS_CODE_VALUE ) { throw new InvalidArgumentException(sprintf( - 'Invalid status code "%s"; must be an integer between 100 and 599, inclusive', - (is_scalar($code) ? $code : gettype($code)) + 'Invalid status code "%s"; must be an integer between %d and %d, inclusive', + (is_scalar($code) ? $code : gettype($code)), + static::MIN_STATUS_CODE_VALUE, + static::MAX_STATUS_CODE_VALUE )); } - } - - /** - * Ensure header names and values are valid. - * - * @param array $headers - * @throws InvalidArgumentException - */ - private function assertHeaders(array $headers) - { - foreach ($headers as $name => $headerValues) { - HeaderSecurity::assertValidName($name); - array_walk($headerValues, __NAMESPACE__ . '\HeaderSecurity::assertValid'); - } + $this->statusCode = $code; } } diff --git a/vendor/zendframework/zend-diactoros/src/Response/ArraySerializer.php b/vendor/zendframework/zend-diactoros/src/Response/ArraySerializer.php new file mode 100644 index 00000000..be4ab3e7 --- /dev/null +++ b/vendor/zendframework/zend-diactoros/src/Response/ArraySerializer.php @@ -0,0 +1,84 @@ + $response->getStatusCode(), + 'reason_phrase' => $response->getReasonPhrase(), + 'protocol_version' => $response->getProtocolVersion(), + 'headers' => $response->getHeaders(), + 'body' => (string) $response->getBody(), + ]; + } + + /** + * Deserialize a response array to a response instance. + * + * @param array $serializedResponse + * @return Response + * @throws UnexpectedValueException when cannot deserialize response + */ + public static function fromArray(array $serializedResponse) + { + try { + $body = new Stream('php://memory', 'wb+'); + $body->write(self::getValueFromKey($serializedResponse, 'body')); + + $statusCode = self::getValueFromKey($serializedResponse, 'status_code'); + $headers = self::getValueFromKey($serializedResponse, 'headers'); + $protocolVersion = self::getValueFromKey($serializedResponse, 'protocol_version'); + $reasonPhrase = self::getValueFromKey($serializedResponse, 'reason_phrase'); + + return (new Response($body, $statusCode, $headers)) + ->withProtocolVersion($protocolVersion) + ->withStatus($statusCode, $reasonPhrase); + } catch (\Exception $exception) { + throw new UnexpectedValueException('Cannot deserialize response', null, $exception); + } + } + + /** + * @param array $data + * @param string $key + * @param string $message + * @return mixed + * @throws UnexpectedValueException + */ + private static function getValueFromKey(array $data, $key, $message = null) + { + if (isset($data[$key])) { + return $data[$key]; + } + if ($message === null) { + $message = sprintf('Missing "%s" key in serialized request', $key); + } + throw new UnexpectedValueException($message); + } +} diff --git a/vendor/zendframework/zend-diactoros/src/Response/EmitterInterface.php b/vendor/zendframework/zend-diactoros/src/Response/EmitterInterface.php index 25ea7f39..f27b4a9c 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/EmitterInterface.php +++ b/vendor/zendframework/zend-diactoros/src/Response/EmitterInterface.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/Response/EmptyResponse.php b/vendor/zendframework/zend-diactoros/src/Response/EmptyResponse.php index 91103069..010cb9d3 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/EmptyResponse.php +++ b/vendor/zendframework/zend-diactoros/src/Response/EmptyResponse.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/Response/HtmlResponse.php b/vendor/zendframework/zend-diactoros/src/Response/HtmlResponse.php index d298ee01..1e1f032a 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/HtmlResponse.php +++ b/vendor/zendframework/zend-diactoros/src/Response/HtmlResponse.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -41,7 +41,7 @@ public function __construct($html, $status = 200, array $headers = []) parent::__construct( $this->createBody($html), $status, - $this->injectContentType('text/html', $headers) + $this->injectContentType('text/html; charset=utf-8', $headers) ); } @@ -68,6 +68,7 @@ private function createBody($html) $body = new Stream('php://temp', 'wb+'); $body->write($html); + $body->rewind(); return $body; } } diff --git a/vendor/zendframework/zend-diactoros/src/Response/InjectContentTypeTrait.php b/vendor/zendframework/zend-diactoros/src/Response/InjectContentTypeTrait.php index 00fd2171..4f2caf84 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/InjectContentTypeTrait.php +++ b/vendor/zendframework/zend-diactoros/src/Response/InjectContentTypeTrait.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php b/vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php index 766c8665..c8af7c4c 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php +++ b/vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -24,6 +24,17 @@ class JsonResponse extends Response { use InjectContentTypeTrait; + /** + * Default flags for json_encode; value of: + * + * + * JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES + * + * + * @const int + */ + const DEFAULT_JSON_FLAGS = 79; + /** * Create a JSON response with the given data. * @@ -34,6 +45,7 @@ class JsonResponse extends Response * - JSON_HEX_APOS * - JSON_HEX_AMP * - JSON_HEX_QUOT + * - JSON_UNESCAPED_SLASHES * * @param mixed $data Data to convert to JSON. * @param int $status Integer status code for the response; 200 by default. @@ -41,10 +53,15 @@ class JsonResponse extends Response * @param int $encodingOptions JSON encoding options to use. * @throws InvalidArgumentException if unable to encode the $data to JSON. */ - public function __construct($data, $status = 200, array $headers = [], $encodingOptions = 15) - { + public function __construct( + $data, + $status = 200, + array $headers = [], + $encodingOptions = self::DEFAULT_JSON_FLAGS + ) { $body = new Stream('php://temp', 'wb+'); $body->write($this->jsonEncode($data, $encodingOptions)); + $body->rewind(); $headers = $this->injectContentType('application/json', $headers); diff --git a/vendor/zendframework/zend-diactoros/src/Response/RedirectResponse.php b/vendor/zendframework/zend-diactoros/src/Response/RedirectResponse.php index 26911f0a..bce82499 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/RedirectResponse.php +++ b/vendor/zendframework/zend-diactoros/src/Response/RedirectResponse.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -12,7 +12,6 @@ use InvalidArgumentException; use Psr\Http\Message\UriInterface; use Zend\Diactoros\Response; -use Zend\Diactoros\Stream; /** * Produce a redirect response. diff --git a/vendor/zendframework/zend-diactoros/src/Response/SapiEmitter.php b/vendor/zendframework/zend-diactoros/src/Response/SapiEmitter.php index bba291e3..a9613429 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/SapiEmitter.php +++ b/vendor/zendframework/zend-diactoros/src/Response/SapiEmitter.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -14,6 +14,8 @@ class SapiEmitter implements EmitterInterface { + use SapiEmitterTrait; + /** * Emits a response for a PHP SAPI environment. * @@ -29,88 +31,21 @@ public function emit(ResponseInterface $response, $maxBufferLevel = null) throw new RuntimeException('Unable to emit response; headers already sent'); } + $response = $this->injectContentLength($response); + $this->emitStatusLine($response); $this->emitHeaders($response); - $this->emitBody($response, $maxBufferLevel); - } - - /** - * Emit the status line. - * - * Emits the status line using the protocol version and status code from - * the response; if a reason phrase is availble, it, too, is emitted. - * - * @param ResponseInterface $response - */ - private function emitStatusLine(ResponseInterface $response) - { - $reasonPhrase = $response->getReasonPhrase(); - header(sprintf( - 'HTTP/%s %d%s', - $response->getProtocolVersion(), - $response->getStatusCode(), - ($reasonPhrase ? ' ' . $reasonPhrase : '') - )); - } - - /** - * Emit response headers. - * - * Loops through each header, emitting each; if the header value - * is an array with multiple values, ensures that each is sent - * in such a way as to create aggregate headers (instead of replace - * the previous). - * - * @param ResponseInterface $response - */ - private function emitHeaders(ResponseInterface $response) - { - foreach ($response->getHeaders() as $header => $values) { - $name = $this->filterHeader($header); - $first = true; - foreach ($values as $value) { - header(sprintf( - '%s: %s', - $name, - $value - ), $first); - $first = false; - } - } + $this->flush($maxBufferLevel); + $this->emitBody($response); } /** * Emit the message body. * - * Loops through the output buffer, flushing each, before emitting - * the response body using `echo()`. - * * @param ResponseInterface $response - * @param int $maxBufferLevel Flush up to this buffer level. */ - private function emitBody(ResponseInterface $response, $maxBufferLevel) + private function emitBody(ResponseInterface $response) { - if (null === $maxBufferLevel) { - $maxBufferLevel = ob_get_level(); - } - - while (ob_get_level() > $maxBufferLevel) { - ob_end_flush(); - } - echo $response->getBody(); } - - /** - * Filter a header name to wordcase - * - * @param string $header - * @return string - */ - private function filterHeader($header) - { - $filtered = str_replace('-', ' ', $header); - $filtered = ucwords($filtered); - return str_replace(' ', '-', $filtered); - } } diff --git a/vendor/zendframework/zend-diactoros/src/Response/SapiEmitterTrait.php b/vendor/zendframework/zend-diactoros/src/Response/SapiEmitterTrait.php new file mode 100644 index 00000000..1e1667ae --- /dev/null +++ b/vendor/zendframework/zend-diactoros/src/Response/SapiEmitterTrait.php @@ -0,0 +1,109 @@ +hasHeader('Content-Length')) { + // PSR-7 indicates int OR null for the stream size; for null values, + // we will not auto-inject the Content-Length. + if (null !== $response->getBody()->getSize()) { + return $response->withHeader('Content-Length', (string) $response->getBody()->getSize()); + } + } + + return $response; + } + + /** + * Emit the status line. + * + * Emits the status line using the protocol version and status code from + * the response; if a reason phrase is available, it, too, is emitted. + * + * @param ResponseInterface $response + */ + private function emitStatusLine(ResponseInterface $response) + { + $reasonPhrase = $response->getReasonPhrase(); + header(sprintf( + 'HTTP/%s %d%s', + $response->getProtocolVersion(), + $response->getStatusCode(), + ($reasonPhrase ? ' ' . $reasonPhrase : '') + )); + } + + /** + * Emit response headers. + * + * Loops through each header, emitting each; if the header value + * is an array with multiple values, ensures that each is sent + * in such a way as to create aggregate headers (instead of replace + * the previous). + * + * @param ResponseInterface $response + */ + private function emitHeaders(ResponseInterface $response) + { + foreach ($response->getHeaders() as $header => $values) { + $name = $this->filterHeader($header); + $first = $name === 'Set-Cookie' ? false : true; + foreach ($values as $value) { + header(sprintf( + '%s: %s', + $name, + $value + ), $first); + $first = false; + } + } + } + + /** + * Loops through the output buffer, flushing each, before emitting + * the response. + * + * @param int|null $maxBufferLevel Flush up to this buffer level. + */ + private function flush($maxBufferLevel = null) + { + if (null === $maxBufferLevel) { + $maxBufferLevel = ob_get_level(); + } + + while (ob_get_level() > $maxBufferLevel) { + ob_end_flush(); + } + } + + /** + * Filter a header name to wordcase + * + * @param string $header + * @return string + */ + private function filterHeader($header) + { + $filtered = str_replace('-', ' ', $header); + $filtered = ucwords($filtered); + return str_replace(' ', '-', $filtered); + } +} diff --git a/vendor/zendframework/zend-diactoros/src/Response/SapiStreamEmitter.php b/vendor/zendframework/zend-diactoros/src/Response/SapiStreamEmitter.php new file mode 100644 index 00000000..02095e50 --- /dev/null +++ b/vendor/zendframework/zend-diactoros/src/Response/SapiStreamEmitter.php @@ -0,0 +1,135 @@ +injectContentLength($response); + + $this->emitStatusLine($response); + $this->emitHeaders($response); + $this->flush(); + + $range = $this->parseContentRange($response->getHeaderLine('Content-Range')); + + if (is_array($range) && $range[0] === 'bytes') { + $this->emitBodyRange($range, $response, $maxBufferLength); + return; + } + + $this->emitBody($response, $maxBufferLength); + } + + /** + * Emit the message body. + * + * @param ResponseInterface $response + * @param int $maxBufferLength + */ + private function emitBody(ResponseInterface $response, $maxBufferLength) + { + $body = $response->getBody(); + + if ($body->isSeekable()) { + $body->rewind(); + } + + if (! $body->isReadable()) { + echo $body; + return; + } + + while (! $body->eof()) { + echo $body->read($maxBufferLength); + } + } + + /** + * Emit a range of the message body. + * + * @param array $range + * @param ResponseInterface $response + * @param int $maxBufferLength + */ + private function emitBodyRange(array $range, ResponseInterface $response, $maxBufferLength) + { + list($unit, $first, $last, $length) = $range; + + $body = $response->getBody(); + + $length = $last - $first + 1; + + if ($body->isSeekable()) { + $body->seek($first); + + $first = 0; + } + + if (! $body->isReadable()) { + echo substr($body->getContents(), $first, $length); + return; + } + + $remaining = $length; + + while ($remaining >= $maxBufferLength && ! $body->eof()) { + $contents = $body->read($maxBufferLength); + $remaining -= strlen($contents); + + echo $contents; + } + + if ($remaining > 0 && ! $body->eof()) { + echo $body->read($remaining); + } + } + + /** + * Parse content-range header + * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16 + * + * @param string $header + * @return false|array [unit, first, last, length]; returns false if no + * content range or an invalid content range is provided + */ + private function parseContentRange($header) + { + if (preg_match('/(?P[\w]+)\s+(?P\d+)-(?P\d+)\/(?P\d+|\*)/', $header, $matches)) { + return [ + $matches['unit'], + (int) $matches['first'], + (int) $matches['last'], + $matches['length'] === '*' ? '*' : (int) $matches['length'], + ]; + } + return false; + } +} diff --git a/vendor/zendframework/zend-diactoros/src/Response/Serializer.php b/vendor/zendframework/zend-diactoros/src/Response/Serializer.php index 8da835da..1d48dc10 100644 --- a/vendor/zendframework/zend-diactoros/src/Response/Serializer.php +++ b/vendor/zendframework/zend-diactoros/src/Response/Serializer.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -37,7 +37,7 @@ public static function fromString($message) * Parse a response from a stream. * * @param StreamInterface $stream - * @return ResponseInterface + * @return Response * @throws InvalidArgumentException when the stream is not readable. * @throws UnexpectedValueException when errors occur parsing the message. */ @@ -54,7 +54,7 @@ public static function fromStream(StreamInterface $stream) return (new Response($body, $status, $headers)) ->withProtocolVersion($version) - ->withStatus($status, $reasonPhrase); + ->withStatus((int) $status, $reasonPhrase); } /** @@ -73,9 +73,8 @@ public static function toString(ResponseInterface $response) if (! empty($headers)) { $headers = "\r\n" . $headers; } - if (! empty($body)) { - $headers .= "\r\n\r\n"; - } + + $headers .= "\r\n\r\n"; return sprintf( $format, diff --git a/vendor/zendframework/zend-diactoros/src/Response/TextResponse.php b/vendor/zendframework/zend-diactoros/src/Response/TextResponse.php new file mode 100644 index 00000000..13df29d8 --- /dev/null +++ b/vendor/zendframework/zend-diactoros/src/Response/TextResponse.php @@ -0,0 +1,74 @@ +createBody($text), + $status, + $this->injectContentType('text/plain; charset=utf-8', $headers) + ); + } + + /** + * Create the message body. + * + * @param string|StreamInterface $text + * @return StreamInterface + * @throws InvalidArgumentException if $html is neither a string or stream. + */ + private function createBody($text) + { + if ($text instanceof StreamInterface) { + return $text; + } + + if (! is_string($text)) { + throw new InvalidArgumentException(sprintf( + 'Invalid content (%s) provided to %s', + (is_object($text) ? get_class($text) : gettype($text)), + __CLASS__ + )); + } + + $body = new Stream('php://temp', 'wb+'); + $body->write($text); + $body->rewind(); + return $body; + } +} diff --git a/vendor/zendframework/zend-diactoros/src/Server.php b/vendor/zendframework/zend-diactoros/src/Server.php index e3c9b308..768d7f38 100644 --- a/vendor/zendframework/zend-diactoros/src/Server.php +++ b/vendor/zendframework/zend-diactoros/src/Server.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ diff --git a/vendor/zendframework/zend-diactoros/src/ServerRequest.php b/vendor/zendframework/zend-diactoros/src/ServerRequest.php index 67a04b40..ecd52b0d 100644 --- a/vendor/zendframework/zend-diactoros/src/ServerRequest.php +++ b/vendor/zendframework/zend-diactoros/src/ServerRequest.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -13,6 +13,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileInterface; +use Psr\Http\Message\UriInterface; /** * Server-side HTTP request @@ -30,7 +31,7 @@ */ class ServerRequest implements ServerRequestInterface { - use MessageTrait, RequestTrait; + use RequestTrait; /** * @var array @@ -65,10 +66,14 @@ class ServerRequest implements ServerRequestInterface /** * @param array $serverParams Server parameters, typically from $_SERVER * @param array $uploadedFiles Upload file information, a tree of UploadedFiles - * @param null|string $uri URI for the request, if any. + * @param null|string|UriInterface $uri URI for the request, if any. * @param null|string $method HTTP method for the request, if any. * @param string|resource|StreamInterface $body Message body, if any. * @param array $headers Headers for the message, if any. + * @param array $cookies Cookies for the message, if any. + * @param array $queryParams Query params for the message, if any. + * @param null|array|object $parsedBody The deserialized body parameters, if any. + * @param string $protocol HTTP protocol version. * @throws InvalidArgumentException for any invalid value. */ public function __construct( @@ -77,14 +82,25 @@ public function __construct( $uri = null, $method = null, $body = 'php://input', - array $headers = [] + array $headers = [], + array $cookies = [], + array $queryParams = [], + $parsedBody = null, + $protocol = '1.1' ) { $this->validateUploadedFiles($uploadedFiles); - $body = $this->getStream($body); + if ($body === 'php://input') { + $body = new PhpInputStream(); + } + $this->initialize($uri, $method, $body, $headers); $this->serverParams = $serverParams; $this->uploadedFiles = $uploadedFiles; + $this->cookieParams = $cookies; + $this->queryParams = $queryParams; + $this->parsedBody = $parsedBody; + $this->protocol = $protocol; } /** @@ -203,10 +219,6 @@ public function withAttribute($attribute, $value) */ public function withoutAttribute($attribute) { - if (! isset($this->attributes[$attribute])) { - return clone $this; - } - $new = clone $this; unset($new->attributes[$attribute]); return $new; @@ -248,33 +260,6 @@ public function withMethod($method) return $new; } - /** - * Set the body stream - * - * @param string|resource|StreamInterface $stream - * @return StreamInterface - */ - private function getStream($stream) - { - if ($stream === 'php://input') { - return new PhpInputStream(); - } - - if (! is_string($stream) && ! is_resource($stream) && ! $stream instanceof StreamInterface) { - throw new InvalidArgumentException( - 'Stream must be a string stream resource identifier, ' - . 'an actual stream resource, ' - . 'or a Psr\Http\Message\StreamInterface implementation' - ); - } - - if (! $stream instanceof StreamInterface) { - return new Stream($stream, 'r'); - } - - return $stream; - } - /** * Recursively validate the structure in an uploaded files array. * diff --git a/vendor/zendframework/zend-diactoros/src/ServerRequestFactory.php b/vendor/zendframework/zend-diactoros/src/ServerRequestFactory.php index e23dfe58..e2ac59b6 100644 --- a/vendor/zendframework/zend-diactoros/src/ServerRequestFactory.php +++ b/vendor/zendframework/zend-diactoros/src/ServerRequestFactory.php @@ -3,17 +3,16 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ namespace Zend\Diactoros; use InvalidArgumentException; -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\MessageInterface; use Psr\Http\Message\UploadedFileInterface; use stdClass; +use UnexpectedValueException; /** * Class for marshaling a request object from the current PHP environment. @@ -60,19 +59,23 @@ public static function fromGlobals( $server = static::normalizeServer($server ?: $_SERVER); $files = static::normalizeFiles($files ?: $_FILES); $headers = static::marshalHeaders($server); - $request = new ServerRequest( + + if (null === $cookies && array_key_exists('cookie', $headers)) { + $cookies = self::parseCookieHeader($headers['cookie']); + } + + return new ServerRequest( $server, $files, static::marshalUriFromServer($server, $headers), static::get('REQUEST_METHOD', $server, 'GET'), 'php://input', - $headers + $headers, + $cookies ?: $_COOKIE, + $query ?: $_GET, + $body ?: $_POST, + static::marshalProtocolVersion($server) ); - - return $request - ->withCookieParams($cookies ?: $_COOKIE) - ->withQueryParams($query ?: $_GET) - ->withParsedBody($body ?: $_POST); } /** @@ -196,24 +199,26 @@ public static function marshalHeaders(array $server) { $headers = []; foreach ($server as $key => $value) { - if (strpos($key, 'HTTP_COOKIE') === 0) { - // Cookies are handled using the $_COOKIE superglobal - continue; + // Apache prefixes environment variables with REDIRECT_ + // if they are added by rewrite rules + if (strpos($key, 'REDIRECT_') === 0) { + $key = substr($key, 9); + + // We will not overwrite existing variables with the + // prefixed versions, though + if (array_key_exists($key, $server)) { + continue; + } } if ($value && strpos($key, 'HTTP_') === 0) { - $name = strtr(substr($key, 5), '_', ' '); - $name = strtr(ucwords(strtolower($name)), ' ', '-'); - $name = strtolower($name); - + $name = strtr(strtolower(substr($key, 5)), '_', '-'); $headers[$name] = $value; continue; } if ($value && strpos($key, 'CONTENT_') === 0) { - $name = substr($key, 8); // Content- - $name = 'Content-' . (($name == 'MD5') ? $name : ucfirst(strtolower($name))); - $name = strtolower($name); + $name = 'content-' . strtolower(substr($key, 8)); $headers[$name] = $value; continue; } @@ -267,8 +272,15 @@ public static function marshalUriFromServer(array $server, array $headers) $query = ltrim($server['QUERY_STRING'], '?'); } + // URI fragment + $fragment = ''; + if (strpos($path, '#') !== false) { + list($path, $fragment) = explode('#', $path, 2); + } + return $uri ->withPath($path) + ->withFragment($fragment) ->withQuery($query); } @@ -455,4 +467,56 @@ private static function normalizeNestedFileSpec(array $files = []) } return $normalizedFiles; } + + /** + * Return HTTP protocol version (X.Y) + * + * @param array $server + * @return string + */ + private static function marshalProtocolVersion(array $server) + { + if (! isset($server['SERVER_PROTOCOL'])) { + return '1.1'; + } + + if (! preg_match('#^(HTTP/)?(?P[1-9]\d*(?:\.\d)?)$#', $server['SERVER_PROTOCOL'], $matches)) { + throw new UnexpectedValueException(sprintf( + 'Unrecognized protocol version (%s)', + $server['SERVER_PROTOCOL'] + )); + } + + return $matches['version']; + } + + /** + * Parse a cookie header according to RFC 6265. + * + * PHP will replace special characters in cookie names, which results in other cookies not being available due to + * overwriting. Thus, the server request should take the cookies from the request header instead. + * + * @param $cookieHeader + * @return array + */ + private static function parseCookieHeader($cookieHeader) + { + preg_match_all('( + (?:^\\n?[ \t]*|;[ ]) + (?P[!#$%&\'*+-.0-9A-Z^_`a-z|~]+) + = + (?P"?) + (?P[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*) + (?P=DQUOTE) + (?=\\n?[ \t]*$|;[ ]) + )x', $cookieHeader, $matches, PREG_SET_ORDER); + + $cookies = []; + + foreach ($matches as $match) { + $cookies[$match['name']] = urldecode($match['value']); + } + + return $cookies; + } } diff --git a/vendor/zendframework/zend-diactoros/src/Stream.php b/vendor/zendframework/zend-diactoros/src/Stream.php index aca58d28..f9aaa416 100644 --- a/vendor/zendframework/zend-diactoros/src/Stream.php +++ b/vendor/zendframework/zend-diactoros/src/Stream.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -19,7 +19,7 @@ class Stream implements StreamInterface { /** - * @var resource + * @var resource|null */ protected $resource; @@ -48,7 +48,10 @@ public function __toString() } try { - $this->rewind(); + if ($this->isSeekable()) { + $this->rewind(); + } + return $this->getContents(); } catch (RuntimeException $e) { return ''; diff --git a/vendor/zendframework/zend-diactoros/src/UploadedFile.php b/vendor/zendframework/zend-diactoros/src/UploadedFile.php index 1aa083f0..767724b8 100644 --- a/vendor/zendframework/zend-diactoros/src/UploadedFile.php +++ b/vendor/zendframework/zend-diactoros/src/UploadedFile.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -51,6 +51,14 @@ class UploadedFile implements UploadedFileInterface */ private $stream; + /** + * @param string|resource $streamOrFile + * @param int $size + * @param int $errorStatus + * @param string|null $clientFilename + * @param string|null $clientMediaType + * @throws InvalidArgumentException + */ public function __construct($streamOrFile, $size, $errorStatus, $clientFilename = null, $clientMediaType = null) { if ($errorStatus === UPLOAD_ERR_OK) { @@ -134,24 +142,26 @@ public function getStream() */ public function moveTo($targetPath) { - if ($this->error !== UPLOAD_ERR_OK) { - throw new RuntimeException('Cannot retrieve stream due to upload error'); + if ($this->moved) { + throw new RuntimeException('Cannot move file; already moved!'); } - if (! is_string($targetPath)) { - throw new InvalidArgumentException( - 'Invalid path provided for move operation; must be a string' - ); + if ($this->error !== UPLOAD_ERR_OK) { + throw new RuntimeException('Cannot retrieve stream due to upload error'); } - if (empty($targetPath)) { + if (! is_string($targetPath) || empty($targetPath)) { throw new InvalidArgumentException( 'Invalid path provided for move operation; must be a non-empty string' ); } - if ($this->moved) { - throw new RuntimeException('Cannot move file; already moved!'); + $targetDirectory = dirname($targetPath); + if (! is_dir($targetDirectory) || ! is_writable($targetDirectory)) { + throw new RuntimeException(sprintf( + 'The target directory `%s` does not exists or is not writable', + $targetDirectory + )); } $sapi = PHP_SAPI; diff --git a/vendor/zendframework/zend-diactoros/src/Uri.php b/vendor/zendframework/zend-diactoros/src/Uri.php index be3077a1..0db8ca18 100644 --- a/vendor/zendframework/zend-diactoros/src/Uri.php +++ b/vendor/zendframework/zend-diactoros/src/Uri.php @@ -3,7 +3,7 @@ * Zend Framework (http://framework.zend.com/) * * @see http://github.com/zendframework/zend-diactoros for the canonical source repository - * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License */ @@ -36,7 +36,7 @@ class Uri implements UriInterface * * @const string */ - const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~'; + const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~\pL'; /** * @var int[] Array indexed by valid scheme names to their corresponding ports. @@ -306,21 +306,23 @@ public function withHost($host) */ public function withPort($port) { - if (! is_numeric($port)) { + if (! is_numeric($port) && $port !== null) { throw new InvalidArgumentException(sprintf( - 'Invalid port "%s" specified; must be an integer or integer string', + 'Invalid port "%s" specified; must be an integer, an integer string, or null', (is_object($port) ? get_class($port) : gettype($port)) )); } - $port = (int) $port; + if ($port !== null) { + $port = (int) $port; + } if ($port === $this->port) { // Do nothing if no change was made. return clone $this; } - if ($port < 1 || $port > 65535) { + if ($port !== null && $port < 1 || $port > 65535) { throw new InvalidArgumentException(sprintf( 'Invalid port "%d" specified; must be a valid TCP/UDP port', $port @@ -440,12 +442,12 @@ private function parseUri($uri) ); } - $this->scheme = isset($parts['scheme']) ? $this->filterScheme($parts['scheme']) : ''; - $this->userInfo = isset($parts['user']) ? $parts['user'] : ''; - $this->host = isset($parts['host']) ? $parts['host'] : ''; - $this->port = isset($parts['port']) ? $parts['port'] : null; - $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : ''; - $this->query = isset($parts['query']) ? $this->filterQuery($parts['query']) : ''; + $this->scheme = isset($parts['scheme']) ? $this->filterScheme($parts['scheme']) : ''; + $this->userInfo = isset($parts['user']) ? $parts['user'] : ''; + $this->host = isset($parts['host']) ? $parts['host'] : ''; + $this->port = isset($parts['port']) ? $parts['port'] : null; + $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : ''; + $this->query = isset($parts['query']) ? $this->filterQuery($parts['query']) : ''; $this->fragment = isset($parts['fragment']) ? $this->filterFragment($parts['fragment']) : ''; if (isset($parts['pass'])) { @@ -468,11 +470,11 @@ private static function createUriString($scheme, $authority, $path, $query, $fra $uri = ''; if (! empty($scheme)) { - $uri .= sprintf('%s://', $scheme); + $uri .= sprintf('%s:', $scheme); } if (! empty($authority)) { - $uri .= $authority; + $uri .= '//' . $authority; } if ($path) { @@ -505,6 +507,9 @@ private static function createUriString($scheme, $authority, $path, $query, $fra private function isNonStandardPort($scheme, $host, $port) { if (! $scheme) { + if ($host && ! $port) { + return false; + } return true; } @@ -551,7 +556,7 @@ private function filterScheme($scheme) private function filterPath($path) { $path = preg_replace_callback( - '/(?:[^' . self::CHAR_UNRESERVED . ':@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^' . self::CHAR_UNRESERVED . ')(:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/u', [$this, 'urlEncodeChar'], $path ); @@ -625,7 +630,7 @@ private function splitQueryValue($value) private function filterFragment($fragment) { if (! empty($fragment) && strpos($fragment, '#') === 0) { - $fragment = substr($fragment, 1); + $fragment = '%23' . substr($fragment, 1); } return $this->filterQueryOrFragment($fragment); @@ -640,7 +645,7 @@ private function filterFragment($fragment) private function filterQueryOrFragment($value) { return preg_replace_callback( - '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/u', [$this, 'urlEncodeChar'], $value ); diff --git a/vendor/zendframework/zend-escaper/CHANGELOG.md b/vendor/zendframework/zend-escaper/CHANGELOG.md new file mode 100644 index 00000000..de6a08b3 --- /dev/null +++ b/vendor/zendframework/zend-escaper/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 2.5.2 - 2016-06-30 + +### Added + +- [#11](https://github.com/zendframework/zend-escaper/pull/11), + [#12](https://github.com/zendframework/zend-escaper/pull/12), and + [#13](https://github.com/zendframework/zend-escaper/pull/13) prepare and + publish documentation to https://zendframework.github.io/zend-escaper/ + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#3](https://github.com/zendframework/zend-escaper/pull/3) updates the + the escaping mechanism to add support for escaping characters outside the Basic + Multilingual Plane when escaping for JS, CSS, or HTML attributes. diff --git a/vendor/zendframework/zend-escaper/CONDUCT.md b/vendor/zendframework/zend-escaper/CONDUCT.md new file mode 100644 index 00000000..c663d2be --- /dev/null +++ b/vendor/zendframework/zend-escaper/CONDUCT.md @@ -0,0 +1,43 @@ +# Contributor Code of Conduct + +The Zend Framework project adheres to [The Code Manifesto](http://codemanifesto.com) +as its guidelines for contributor interactions. + +## The Code Manifesto + +We want to work in an ecosystem that empowers developers to reach their +potential — one that encourages growth and effective collaboration. A space that +is safe for all. + +A space such as this benefits everyone that participates in it. It encourages +new developers to enter our field. It is through discussion and collaboration +that we grow, and through growth that we improve. + +In the effort to create such a place, we hold to these values: + +1. **Discrimination limits us.** This includes discrimination on the basis of + race, gender, sexual orientation, gender identity, age, nationality, technology + and any other arbitrary exclusion of a group of people. +2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort + levels. Remember that, and if brought to your attention, heed it. +3. **We are our biggest assets.** None of us were born masters of our trade. + Each of us has been helped along the way. Return that favor, when and where + you can. +4. **We are resources for the future.** As an extension of #3, share what you + know. Make yourself a resource to help those that come after you. +5. **Respect defines us.** Treat others as you wish to be treated. Make your + discussions, criticisms and debates from a position of respectfulness. Ask + yourself, is it true? Is it necessary? Is it constructive? Anything less is + unacceptable. +6. **Reactions require grace.** Angry responses are valid, but abusive language + and vindictive actions are toxic. When something happens that offends you, + handle it assertively, but be respectful. Escalate reasonably, and try to + allow the offender an opportunity to explain themselves, and possibly correct + the issue. +7. **Opinions are just that: opinions.** Each and every one of us, due to our + background and upbringing, have varying opinions. The fact of the matter, is + that is perfectly acceptable. Remember this: if you respect your own + opinions, you should respect the opinions of others. +8. **To err is human.** You might not intend it, but mistakes do happen and + contribute to build experience. Tolerate honest mistakes, and don't hesitate + to apologize if you make one yourself. diff --git a/vendor/zendframework/zend-escaper/CONTRIBUTING.md b/vendor/zendframework/zend-escaper/CONTRIBUTING.md index 2b58aca3..8eb4657f 100644 --- a/vendor/zendframework/zend-escaper/CONTRIBUTING.md +++ b/vendor/zendframework/zend-escaper/CONTRIBUTING.md @@ -227,3 +227,8 @@ repository, we suggest doing some cleanup of these branches. ```console $ git push {username} : ``` + + +## Conduct + +Please see our [CONDUCT.md](CONDUCT.md) to understand expected behavior when interacting with others in the project. diff --git a/vendor/zendframework/zend-escaper/README.md b/vendor/zendframework/zend-escaper/README.md index 9ed284f0..4124bdd0 100644 --- a/vendor/zendframework/zend-escaper/README.md +++ b/vendor/zendframework/zend-escaper/README.md @@ -5,10 +5,9 @@ The OWASP Top 10 web security risks study lists Cross-Site Scripting (XSS) in second place. PHP’s sole functionality against XSS is limited to two functions -of which one is commonly misapplied. Thus, the `Zend\Escaper` component was written. +of which one is commonly misapplied. Thus, the zend-escaper component was written. It offers developers a way to escape output and defend from XSS and related vulnerabilities by introducing contextual escaping based on peer-reviewed rules. - - File issues at https://github.com/zendframework/zend-escaper/issues -- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-escaper +- Documentation is at https://zendframework.github.io/zend-escaper/ diff --git a/vendor/zendframework/zend-escaper/composer.json b/vendor/zendframework/zend-escaper/composer.json index faa4375d..2abc6288 100644 --- a/vendor/zendframework/zend-escaper/composer.json +++ b/vendor/zendframework/zend-escaper/composer.json @@ -13,7 +13,7 @@ } }, "require": { - "php": ">=5.3.23" + "php": ">=5.5" }, "minimum-stability": "dev", "prefer-stable": true, @@ -32,4 +32,4 @@ "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0" } -} \ No newline at end of file +} diff --git a/vendor/zendframework/zend-escaper/doc/book/configuration.md b/vendor/zendframework/zend-escaper/doc/book/configuration.md new file mode 100644 index 00000000..b1932667 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/configuration.md @@ -0,0 +1,21 @@ +# Configuration + +`Zend\Escaper\Escaper` has only one configuration option available, and that is +the encoding to be used by the `Escaper` instance. + +The default encoding is **utf-8**. Other supported encodings are: + +- iso-8859-1 +- iso-8859-5 +- iso-8859-15 +- cp866, ibm866, 866 +- cp1251, windows-1251 +- cp1252, windows-1252 +- koi8-r, koi8-ru +- big5, big5-hkscs, 950, gb2312, 936 +- shift\_jis, sjis, sjis-win, cp932 +- eucjp, eucjp-win +- macroman + +If an unsupported encoding is passed to `Zend\Escaper\Escaper`, a +`Zend\Escaper\Exception\InvalidArgumentException` will be thrown. diff --git a/vendor/zendframework/zend-escaper/doc/book/escaping-css.md b/vendor/zendframework/zend-escaper/doc/book/escaping-css.md new file mode 100644 index 00000000..63b554bd --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/escaping-css.md @@ -0,0 +1,74 @@ +# Escaping Cascading Style Sheets + +CSS is similar to [escaping Javascript](escaping-javascript.md). CSS escaping +excludes only basic alphanumeric characters and escapes all other characters +into valid CSS hexadecimal escapes. + +## Example of Bad CSS Escaping + +In most cases developers forget to escape CSS completely: + +```php + + +'); +} +INPUT; +?> + + + Unescaped CSS + + + + +

    User controlled CSS needs to be properly escaped!

    + + +``` + +In the above example, by failing to escape the user provided CSS, an attacker +can execute an XSS attack fairly easily. + +## Example of Good CSS Escaping + +By using `escapeCss()` method in the CSS context, such attacks can be prevented: + +```php + + +'); +} +INPUT; + +$escaper = new Zend\Escaper\Escaper('utf-8'); +$output = $escaper->escapeCss($input); +?> + + + Escaped CSS + + + + +

    User controlled CSS needs to be properly escaped!

    + + +``` + +By properly escaping user controlled CSS, we can prevent XSS attacks in our web +applications. diff --git a/vendor/zendframework/zend-escaper/doc/book/escaping-html-attributes.md b/vendor/zendframework/zend-escaper/doc/book/escaping-html-attributes.md new file mode 100644 index 00000000..d4987794 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/escaping-html-attributes.md @@ -0,0 +1,128 @@ +# Escaping HTML Attributes + +Escaping data in **HTML Attribute** contexts is most often done incorrectly, if +not overlooked completely by developers. Regular [HTML +escaping](escaping-html.md) can be used for escaping HTML attributes *only* if +the attribute value can be **guaranteed as being properly quoted**! To avoid +confusion, we recommend always using the HTML Attribute escaper method when +dealing with HTTP attributes specifically. + +To escape data for an HTML Attribute, use `Zend\Escaper\Escaper`'s +`escapeHtmlAttr()` method. Internally it will convert the data to UTF-8, check +for its validity, and use an extended set of characters to escape that are not +covered by `htmlspecialchars()` to cover the cases where an attribute might be +unquoted or quoted illegally. + +## Examples of Bad HTML Attribute Escaping + +An example of incorrect HTML attribute escaping: + +```php + + + + + + Single Quoted Attribute + + + +
    + + ?> + + What framework are you using? + +
    + + +``` + +In the above example, the default `ENT_COMPAT` flag is being used, which does +not escape single quotes, thus resulting in an alert box popping up when the +`onmouseover` event happens on the `span` element. + +Another example of incorrect HTML attribute escaping can happen when unquoted +attributes are used (which is, by the way, perfectly valid HTML5): + +```php + + + + + + Quoteless Attribute + + + +
    + + ?> + > + What framework are you using? + +
    + + +``` + +The above example shows how it is easy to break out from unquoted attributes in +HTML5. + +## Example of Good HTML Attribute Escaping + +Both of the previous examples can be avoided by simply using the +`escapeHtmlAttr()` method: + +```php + + +escapeHtmlAttr($input); +?> + + + Quoteless Attribute + + + +
    + + ?> + > + What framework are you using? + +
    + + +``` + +In the above example, the malicious input from the attacker becomes completely +harmless as we used proper HTML attribute escaping! diff --git a/vendor/zendframework/zend-escaper/doc/book/escaping-html.md b/vendor/zendframework/zend-escaper/doc/book/escaping-html.md new file mode 100644 index 00000000..7a88023f --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/escaping-html.md @@ -0,0 +1,74 @@ +# Escaping HTML + +Probably the most common escaping happens for **HTML body** contexts. There are +very few characters with special meaning in this context, yet it is quite common +to escape data incorrectly, namely by setting the wrong flags and character +encoding. + +For escaping data to use within an HTML body context, use +`Zend\Escaper\Escaper`'s `escapeHtml()` method. Internally it uses PHP's +`htmlspecialchars()`, correctly setting the flags and encoding for you. + +```php +// Outputting this without escaping would be a bad idea! +$input = ''; + +$escaper = new Zend\Escaper\Escaper('utf-8'); + +// somewhere in an HTML template +
    + escapeHtml($input) // all safe! ?> +
    +``` + +One thing a developer needs to pay special attention to is the encoding in which +the document is served to the client, as it **must be the same** as the encoding +used for escaping! + +## Example of Bad HTML Escaping + +An example of incorrect usage: + +```php +alert("zf2")'; +$escaper = new Zend\Escaper\Escaper('utf-8'); +?> + + + + + Encodings set incorrectly! + + + +escapeHtml($input); +?> + +``` + +## Example of Good HTML Escaping + +An example of correct usage: + +```php +alert("zf2")'; +$escaper = new Zend\Escaper\Escaper('utf-8'); +?> + + + + + Encodings set correctly! + + + +escapeHtml($input); +?> + +``` diff --git a/vendor/zendframework/zend-escaper/doc/book/escaping-javascript.md b/vendor/zendframework/zend-escaper/doc/book/escaping-javascript.md new file mode 100644 index 00000000..f40efa64 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/escaping-javascript.md @@ -0,0 +1,93 @@ +# Escaping Javascript + +Javascript string literals in HTML are subject to significant restrictions due +to the potential for unquoted attributes and uncertainty as to whether +Javascript will be viewed as being `CDATA` or `PCDATA` by the browser. To +eliminate any possible XSS vulnerabilities, Javascript escaping for HTML extends +the escaping rules of both ECMAScript and JSON to include any potentially +dangerous character. Very similar to HTML attribute value escaping, this means +escaping everything except basic alphanumeric characters and the comma, period, +and underscore characters as hexadecimal or unicode escapes. + +Javascript escaping applies to all literal strings and digits. It is not +possible to safely escape other Javascript markup. + +To escape data in the **Javascript context**, use `Zend\Escaper\Escaper`'s +`escapeJs()` method. An extended set of characters are escaped beyond +ECMAScript's rules for Javascript literal string escaping in order to prevent +misinterpretation of Javascript as HTML leading to the injection of special +characters and entities. + +## Example of Bad Javascript Escaping + +An example of incorrect Javascript escaping: + +```php + + + + + + Unescaped Entities + + + + +

    json_encode() is not good for escaping javascript!

    + + +``` + +The above example will show an alert popup box as soon as the page is loaded, +because the data is not properly escaped for the Javascript context. + +## Example of Good Javascript Escaping + +By using the `escapeJs()` method in the Javascript context, such attacks can be +prevented: + +```php + + +escapeJs($input); +?> + + + Escaped Entities + + + + +

    Zend\Escaper\Escaper::escapeJs() is good for escaping javascript!

    + + +``` + +In the above example, the Javascript parser will most likely report a +`SyntaxError`, but at least the targeted application remains safe from such +attacks. diff --git a/vendor/zendframework/zend-escaper/doc/book/escaping-url.md b/vendor/zendframework/zend-escaper/doc/book/escaping-url.md new file mode 100644 index 00000000..4dc13e14 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/escaping-url.md @@ -0,0 +1,57 @@ +# Escaping URLs + +This method is basically an alias for PHP's `rawurlencode()` which has applied +RFC 3986 since PHP 5.3. It is included primarily for consistency. + +URL escaping applies to data being inserted into a URL and not to the whole URL +itself. + +## Example of Bad URL Escaping + +XSS attacks are easy if data inserted into URLs is not escaped properly: + +```php + + + + + + Unescaped URL data + + + + Click here! + + +``` + +## Example of Good URL Escaping + +By properly escaping data in URLs by using `escapeUrl()`, we can prevent XSS +attacks: + +```php + + +escapeUrl($input); +?> + + + Unescaped URL data + + + + Click here! + + +``` diff --git a/vendor/zendframework/zend-escaper/doc/book/index.html b/vendor/zendframework/zend-escaper/doc/book/index.html new file mode 100644 index 00000000..7263c45b --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/index.html @@ -0,0 +1,10 @@ +
    +
    +

    zend-escaper

    + +

    Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs.

    + +
    $ composer require zendframework/zend-escaper
    +
    +
    + diff --git a/vendor/zendframework/zend-escaper/doc/book/index.md b/vendor/zendframework/zend-escaper/doc/book/index.md new file mode 100644 index 00000000..4124bdd0 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/index.md @@ -0,0 +1,13 @@ +# zend-escaper + +[![Build Status](https://secure.travis-ci.org/zendframework/zend-escaper.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-escaper) +[![Coverage Status](https://coveralls.io/repos/zendframework/zend-escaper/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-escaper?branch=master) + +The OWASP Top 10 web security risks study lists Cross-Site Scripting (XSS) in +second place. PHP’s sole functionality against XSS is limited to two functions +of which one is commonly misapplied. Thus, the zend-escaper component was written. +It offers developers a way to escape output and defend from XSS and related +vulnerabilities by introducing contextual escaping based on peer-reviewed rules. + +- File issues at https://github.com/zendframework/zend-escaper/issues +- Documentation is at https://zendframework.github.io/zend-escaper/ diff --git a/vendor/zendframework/zend-escaper/doc/book/intro.md b/vendor/zendframework/zend-escaper/doc/book/intro.md new file mode 100644 index 00000000..08204562 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/intro.md @@ -0,0 +1,51 @@ +# Introduction + +The [OWASP Top 10 web security risks](https://www.owasp.org/index.php/Top_10_2010-Main) +study lists Cross-Site Scripting (XSS) in second place. PHP's sole functionality +against XSS is limited to two functions of which one is commonly misapplied. +Thus, the zend-escaper component was written. It offers developers a way to +escape output and defend from XSS and related vulnerabilities by introducing +**contextual escaping based on peer-reviewed rules**. + +zend-escaper was written with ease of use in mind, so it can be used completely stand-alone from +the rest of the framework, and as such can be installed with Composer: + +```bash +$ composer install zendframework/zend-escaper +``` + +Several Zend Framework components provide integrations for consuming +zend-escaper, including [zend-view](https://github.com/zendframework/zend-view), +which provides a set of helpers that consume it. + +> ### Security +> +> zend-escaper is a security related component. As such, if you believe you have +> found an issue, we ask that you follow our [Security Policy](http://framework.zend.com/security/) +> and report security issues accordingly. The Zend Framework team and the +> contributors thank you in advance. + +## Overview + +zend-escaper provides one class, `Zend\Escaper\Escaper`, which in turn provides +five methods for escaping output. Which method to use depends on the context in +which the output is used. It is up to the developer to use the right methods in +the right context. + +`Zend\Escaper\Escaper` has the following escaping methods available for each context: + +- `escapeHtml`: escape a string for an HTML body context. +- `escapeHtmlAttr`: escape a string for an HTML attribute context. +- `escapeJs`: escape a string for a Javascript context. +- `escapeCss`: escape a string for a CSS context. +- `escapeUrl`: escape a string for a URI or URI parameter context. + +Usage of each method will be discussed in detail in later chapters. + +## What zend-Escaper is not + +zend-escaper is meant to be used only for *escaping data for output*, and as +such should not be misused for *filtering input data*. For such tasks, use +[zend-filter](https://zendframework.github.io/zend-filter/), +[HTMLPurifier](http://htmlpurifier.org/) or PHP's +[Filter](http://php.net/filter) functionality should be used. diff --git a/vendor/zendframework/zend-escaper/doc/book/theory-of-operation.md b/vendor/zendframework/zend-escaper/doc/book/theory-of-operation.md new file mode 100644 index 00000000..9a769b07 --- /dev/null +++ b/vendor/zendframework/zend-escaper/doc/book/theory-of-operation.md @@ -0,0 +1,147 @@ +# Theory of Operation + +zend-escaper provides methods for escaping output data, dependent on the context +in which the data will be used. Each method is based on peer-reviewed rules and +is in compliance with the current OWASP recommendations. + +The escaping follows a well-known and fixed set of encoding rules defined by +OWASP for each key HTML context. These rules cannot be impacted or negated by +browser quirks or edge-case HTML parsing unless the browser suffers a +catastrophic bug in its HTML parser or Javascript interpreter — both of +these are unlikely. + +The contexts in which zend-escaper should be used are **HTML Body**, **HTML +Attribute**, **Javascript**, **CSS**, and **URL/URI** contexts. + +Every escaper method will take the data to be escaped, make sure it is utf-8 +encoded data (or try to convert it to utf-8), perform context-based escaping, +encode the escaped data back to its original encoding, and return the data to +the caller. + +The actual escaping of the data differs between each method; they all have their +own set of rules according to which escaping is performed. An example will allow +us to clearly demonstrate the difference, and how the same characters are being +escaped differently between contexts: + +```php +$escaper = new Zend\Escaper\Escaper('utf-8'); + +// <script>alert("zf2")</script> +echo $escaper->escapeHtml(''); + +// <script>alert("zf2")</script> +echo $escaper->escapeHtmlAttr(''); + +// \x3Cscript\x3Ealert\x28\x22zf2\x22\x29\x3C\x2Fscript\x3E +echo $escaper->escapeJs(''); + +// \3C script\3E alert\28 \22 zf2\22 \29 \3C \2F script\3E +echo $escaper->escapeCss(''); + +// %3Cscript%3Ealert%28%22zf2%22%29%3C%2Fscript%3E +echo $escaper->escapeUrl(''); +``` + +More detailed examples will be given in later chapters. + +## The Problem with Inconsistent Functionality + +At present, programmers orient towards the following PHP functions for each +common HTML context: + +- **HTML Body**: `htmlspecialchars()` or `htmlentities()` +- **HTML Attribute**: `htmlspecialchars()` or `htmlentities()` +- **Javascript**: `addslashes()` or `json_encode()` +- **CSS**: n/a +- **URL/URI**: `rawurlencode()` or `urlencode()` + +In practice, these decisions appear to depend more on what PHP offers, and if it +can be interpreted as offering sufficient escaping safety, than it does on what +is recommended in reality to defend against XSS. While these functions can +prevent some forms of XSS, they do not cover all use cases or risks and are +therefore insufficient defenses. + +Using `htmlspecialchars()` in a perfectly valid HTML5 unquoted attribute value, +for example, is completely useless since the value can be terminated by a space +(among other things), which is never escaped. Thus, in this instance, we have a +conflict between a widely used HTML escaper and a modern HTML specification, +with no specific function available to cover this use case. While it's tempting +to blame users, or the HTML specification authors, escaping just needs to deal +with whatever HTML and browsers allow. + +Using `addslashes()`, custom backslash escaping, or `json_encode()` will +typically ignore HTML special characters such as ampersands, which may be used +to inject entities into Javascript. Under the right circumstances, the browser +will convert these entities into their literal equivalents before interpreting +Javascript, thus allowing attackers to inject arbitrary code. + +Inconsistencies with valid HTML, insecure default parameters, lack of character +encoding awareness, and misrepresentations of what functions are capable of by +some programmers — these all make escaping in PHP an unnecessarily +convoluted quest. + +To circumvent the lack of escaping methods in PHP, zend-escaper addresses the +need to apply context-specific escaping in web applications. It implements +methods that specifically target XSS and offers programmers a tool to secure +their applications without misusing other inadequate methods, or using, most +likely incomplete, home-grown solutions. + +## Why Contextual Escaping? + +To understand why multiple standardised escaping methods are needed, what +follows are several quick points; they are by no means a complete set of +reasons, however! + +### HTML escaping of unquoted HTML attribute values still allows XSS + +This is probably the best known way to defeat `htmlspecialchars()` when used on +attribute values, since any space (or character interpreted as a space — +there are a lot) lets you inject new attributes whose content can't be +neutralised by HTML escaping. The solution (where this is possible) is +additional escaping as defined by the OWASP ESAPI codecs. The point here can be +extended further — escaping only works if a programmer or designer knows +what they're doing. In many contexts, there are additional practices and gotchas +that need to be carefully monitored since escaping sometimes needs a little +extra help to protect against XSS — even if that means ensuring all +attribute values are properly double quoted despite this not being required for +valid HTML. + +### HTML escaping of CSS, Javascript or URIs is often reversed when passed to non-HTML interpreters by the browser + +HTML escaping is just that &mdsash; it's designed to escape a string for HTML +(i.e. prevent tag or attribute insertion), but not alter the underlying meaning +of the content, whether it be text, Javascript, CSS, or URIs. For that purpose, +a fully HTML-escaped version of any other context may still have its unescaped +form extracted before it's interpreted or executed. For this reason we need +separate escapers for Javascript, CSS, and URIs, and developers or designers +writing templates **must** know which escaper to apply to which context. Of +course, this means you need to be able to identify the correct context before +selecting the right escaper! + +### DOM-based XSS requires a defence using at least two levels of different escaping in many cases + +DOM-based XSS has become increasingly common as Javascript has taken off in +popularity for large scale client-side coding. A simple example is Javascript +defined in a template which inserts a new piece of HTML text into the DOM. If +the string is only HTML escaped, it may still contain Javascript that will +execute in that context. If the string is only Javascript-escaped, it may +contain HTML markup (new tags and attributes) which will be injected into the +DOM and parsed once the inserting Javascript executes. Damned either way? The +solution is to escape twice — first escape the string for HTML (make it +safe for DOM insertion), and then for Javascript (make it safe for the current +Javascript context). Nested contexts are a common means of bypassing naive +escaping habits (e.g. you can inject Javascript into a CSS expression within an +HTML attribute). + +### PHP has no known anti-XSS escape functions (only those kidnapped from their original purposes) + +A simple example, widely used, is when you see `json_encode()` used to escape +Javascript, or worse, some kind of mutant `addslashes()` implementation. These +were never designed to eliminate XSS, yet PHP programmers use them as such. For +example, `json_encode()` does not escape the ampersand or semi-colon characters +by default. That means you can easily inject HTML entities which could then be +decoded before the Javascript is evaluated in a HTML document. This lets you +break out of strings, add new JS statements, close tags, etc. In other words, +using `json_encode()` is insufficient and naive. The same, arguably, could be +said for `htmlspecialchars()` which has its own well known limitations that make +a singular reliance on it a questionable practice. diff --git a/vendor/zendframework/zend-escaper/mkdocs.yml b/vendor/zendframework/zend-escaper/mkdocs.yml new file mode 100644 index 00000000..48e7b311 --- /dev/null +++ b/vendor/zendframework/zend-escaper/mkdocs.yml @@ -0,0 +1,17 @@ +docs_dir: doc/book +site_dir: doc/html +pages: + - index.md + - Intro: intro.md + - Reference: + - "Theory of Operation": theory-of-operation.md + - Configuration: configuration.md + - "Escaping HTML": escaping-html.md + - "Escaping HTML Attributes": escaping-html-attributes.md + - "Escaping Javascript": escaping-javascript.md + - "Escaping CSS": escaping-css.md + - "Escaping URLs": escaping-url.md +site_name: zend-escaper +site_description: zend-escaper +repo_url: 'https://github.com/zendframework/zend-escaper' +copyright: 'Copyright (c) 2016 Zend Technologies USA Inc.' diff --git a/vendor/zendframework/zend-escaper/src/Escaper.php b/vendor/zendframework/zend-escaper/src/Escaper.php index 072d543f..e68e32b0 100644 --- a/vendor/zendframework/zend-escaper/src/Escaper.php +++ b/vendor/zendframework/zend-escaper/src/Escaper.php @@ -24,12 +24,12 @@ class Escaper * * @var array */ - protected static $htmlNamedEntityMap = array( + protected static $htmlNamedEntityMap = [ 34 => 'quot', // quotation mark 38 => 'amp', // ampersand 60 => 'lt', // less-than sign 62 => 'gt', // greater-than sign - ); + ]; /** * Current encoding for escaping. If not UTF-8, we convert strings from this encoding @@ -41,13 +41,11 @@ class Escaper /** * Holds the value of the special flags passed as second parameter to - * htmlspecialchars(). We modify these for PHP 5.4 to take advantage - * of the new ENT_SUBSTITUTE flag for correctly dealing with invalid - * UTF-8 sequences. + * htmlspecialchars(). * - * @var string + * @var int */ - protected $htmlSpecialCharsFlags = ENT_QUOTES; + protected $htmlSpecialCharsFlags; /** * Static Matcher which escapes characters for HTML Attribute contexts @@ -75,7 +73,7 @@ class Escaper * * @var array */ - protected $supportedEncodings = array( + protected $supportedEncodings = [ 'iso-8859-1', 'iso8859-1', 'iso-8859-5', 'iso8859-5', 'iso-8859-15', 'iso8859-15', 'utf-8', 'cp866', 'ibm866', '866', 'cp1251', 'windows-1251', @@ -85,12 +83,11 @@ class Escaper 'big5-hkscs', 'shift_jis', 'sjis', 'sjis-win', 'cp932', '932', 'euc-jp', 'eucjp', 'eucjp-win', 'macroman' - ); + ]; /** * Constructor: Single parameter allows setting of global encoding for use by - * the current object. If PHP 5.4 is detected, additional ENT_SUBSTITUTE flag - * is set for htmlspecialchars() calls. + * the current object. * * @param string $encoding * @throws Exception\InvalidArgumentException @@ -116,14 +113,13 @@ public function __construct($encoding = null) $this->encoding = $encoding; } - if (defined('ENT_SUBSTITUTE')) { - $this->htmlSpecialCharsFlags|= ENT_SUBSTITUTE; - } + // We take advantage of ENT_SUBSTITUTE flag to correctly deal with invalid UTF-8 sequences. + $this->htmlSpecialCharsFlags = ENT_QUOTES | ENT_SUBSTITUTE; // set matcher callbacks - $this->htmlAttrMatcher = array($this, 'htmlAttrMatcher'); - $this->jsMatcher = array($this, 'jsMatcher'); - $this->cssMatcher = array($this, 'cssMatcher'); + $this->htmlAttrMatcher = [$this, 'htmlAttrMatcher']; + $this->jsMatcher = [$this, 'jsMatcher']; + $this->cssMatcher = [$this, 'cssMatcher']; } /** @@ -248,7 +244,7 @@ protected function htmlAttrMatcher($matches) * replace it with while grabbing the integer value of the character. */ if (strlen($chr) > 1) { - $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); + $chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8'); } $hex = bin2hex($chr); @@ -281,7 +277,13 @@ protected function jsMatcher($matches) return sprintf('\\x%02X', ord($chr)); } $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); - return sprintf('\\u%04s', strtoupper(bin2hex($chr))); + $hex = strtoupper(bin2hex($chr)); + if (strlen($hex) <= 4) { + return sprintf('\\u%04s', $hex); + } + $highSurrogate = substr($hex, 0, 4); + $lowSurrogate = substr($hex, 4, 4); + return sprintf('\\u%04s\\u%04s', $highSurrogate, $lowSurrogate); } /** @@ -297,7 +299,7 @@ protected function cssMatcher($matches) if (strlen($chr) == 1) { $ord = ord($chr); } else { - $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); + $chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8'); $ord = hexdec(bin2hex($chr)); } return sprintf('\\%X ', $ord); diff --git a/vendor/zendframework/zend-feed/CHANGELOG.md b/vendor/zendframework/zend-feed/CHANGELOG.md index 426cab52..55fa7cd5 100644 --- a/vendor/zendframework/zend-feed/CHANGELOG.md +++ b/vendor/zendframework/zend-feed/CHANGELOG.md @@ -2,12 +2,65 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 2.5.2 - TBD +## 2.7.0 - 2016-02-11 ### Added +- [#21](https://github.com/zendframework/zend-feed/pull/21) edits, revises, and + prepares the documentation for publication at https://zendframework.github.io/zend-feed/ + +### Deprecated + +- Nothing. + +### Removed + - Nothing. +### Fixed + +- [#20](https://github.com/zendframework/zend-feed/pull/20) makes the two + zend-servicemanager extension manager implementations forwards compatible + with version 3, and the overall code base forwards compatible with zend-stdlib + v3. + +## 2.6.0 - 2015-11-24 + +### Added + +- [#13](https://github.com/zendframework/zend-feed/pull/13) introduces + `Zend\Feed\Writer\StandaloneExtensionManager`, an implementation of + `Zend\Feed\Writer\ExtensionManagerInterface` that has no dependencies. + `Zend\Feed\Writer\ExtensionManager` now composes this by default, instead of + `Zend\Feed\Writer\ExtensionPluginManager`, for managing the various feed and + entry extensions. If you relied on `ExtensionPluginManager` previously, you + will need to create an instance manually and inject it into the `Writer` + instance. +- [#14](https://github.com/zendframework/zend-feed/pull/14) introduces: + - `Zend\Feed\Reader\Http\HeaderAwareClientInterface`, which extends + `ClientInterface` and adds an optional argument to the `get()` method, + `array $headers = []`; this argument allows specifying request headers for + the client to send. `$headers` should have header names for keys, and the + values should be arrays of strings/numbers representing the header values + (if only a single value is necessary, it should be represented as an single + value array). + - `Zend\Feed\Reader\Http\HeaderAwareResponseInterface`, which extends + `ResponseInterface` and adds the method `getHeader($name, $default = null)`. + Clients may return either a `ResponseInterface` or + `HeaderAwareResponseInterface` instance. + - `Zend\Feed\Reader\Http\Response`, which is an implementation of + `HeaderAwareResponseInterface`. Its constructor accepts the status code, + body, and, optionally, headers. + - `Zend\Feed\Reader\Http\Psr7ResponseDecorator`, which is an implementation of + `HeaderAwareResponseInterface`. Its constructor accepts a PSR-7 response + instance, and the various methdos then proxy to those methods. This should + make creating wrappers for PSR-7 HTTP clients trivial. + - `Zend\Feed\Reader\Http\ZendHttpClientDecorator`, which decorates a + `Zend\Http\Client` instance, implements `HeaderAwareClientInterface`, and + returns a `Response` instance seeded from the zend-http response upon + calling `get()`. The class exposes a `getDecoratedClient()` method to allow + retrieval of the decorated zend-http client instance. + ### Deprecated - Nothing. @@ -23,3 +76,19 @@ All notable changes to this project will be documented in this file, in reverse - [#2](https://github.com/zendframework/zend-feed/pull/2) ensures that the routine for "absolutising" a link in `Reader\FeedSet` always generates a URI with a scheme. +- [#14](https://github.com/zendframework/zend-feed/pull/14) makes the following + changes to fix behavior around HTTP clients used within + `Zend\Feed\Reader\Reader`: + - `setHttpClient()` now ensures that the passed client is either a + `Zend\Feed\Reader\Http\ClientInterface` or `Zend\Http\Client`, raising an + `InvalidArgumentException` if neither. If a `Zend\Http\Client` is passed, it + is passed to the constructor of `Zend\Feed\Reader\Http\ZendHttpClientDecorator`, + and the decorator instance is used. + - `getHttpClient()` now *always* returns a `Zend\Feed\Reader\Http\ClientInterface` + instance. If no instance is currently registered, it lazy loads a + `ZendHttpClientDecorator` instance. + - `import()` was updated to consume a `ClientInterface` instance; when caches + are in play, it checks the client against `HeaderAwareClientInterface` to + determine if it can check for HTTP caching headers, and, if so, to retrieve + them. + - `findFeedLinks()` was updated to consume a `ClientInterface`. diff --git a/vendor/zendframework/zend-feed/README.md b/vendor/zendframework/zend-feed/README.md index ba8b8726..3e2afd55 100644 --- a/vendor/zendframework/zend-feed/README.md +++ b/vendor/zendframework/zend-feed/README.md @@ -10,4 +10,4 @@ structure with the same natural syntax, and turning the result back into XML. - File issues at https://github.com/zendframework/zend-feed/issues -- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-feed +- Documentation is at https://zendframework.github.io/zend-feed/ diff --git a/vendor/zendframework/zend-feed/composer.json b/vendor/zendframework/zend-feed/composer.json index 2c29f067..0183b5d7 100644 --- a/vendor/zendframework/zend-feed/composer.json +++ b/vendor/zendframework/zend-feed/composer.json @@ -13,32 +13,34 @@ } }, "require": { - "php": ">=5.5", - "zendframework/zend-escaper": "~2.5", - "zendframework/zend-stdlib": "~2.5" + "php": "^5.5 || ^7.0", + "zendframework/zend-escaper": "^2.5", + "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { - "zendframework/zend-db": "~2.5", - "zendframework/zend-cache": "~2.5", - "zendframework/zend-http": "~2.5", - "zendframework/zend-servicemanager": "~2.5", - "zendframework/zend-validator": "~2.5", + "zendframework/zend-db": "^2.5", + "zendframework/zend-cache": "^2.5", + "zendframework/zend-http": "^2.5", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-validator": "^2.5", "fabpot/php-cs-fixer": "1.7.*", - "phpunit/PHPUnit": "~4.0" + "phpunit/PHPUnit": "~4.0", + "psr/http-message": "^1.0" }, "suggest": { - "zendframework/zend-cache": "Zend\\Cache component", - "zendframework/zend-db": "Zend\\Db component", + "psr/http-message": "PSR-7 ^1.0, if you wish to use Zend\\Feed\\Reader\\Http\\Psr7ResponseDecorator", + "zendframework/zend-cache": "Zend\\Cache component, for optionally caching feeds between requests", + "zendframework/zend-db": "Zend\\Db component, for use with PubSubHubbub", "zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader", - "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations", - "zendframework/zend-validator": "Zend\\Validator component" + "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for easily extending ExtensionManager implementations", + "zendframework/zend-validator": "Zend\\Validator component, for validating email addresses used in Atom feeds and entries ehen using the Writer subcomponent" }, "minimum-stability": "dev", "prefer-stable": true, "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.7-dev", + "dev-develop": "2.8-dev" } }, "autoload-dev": { @@ -46,4 +48,4 @@ "ZendTest\\Feed\\": "test/" } } -} \ No newline at end of file +} diff --git a/vendor/zendframework/zend-feed/doc/book/consuming-atom-entry.md b/vendor/zendframework/zend-feed/doc/book/consuming-atom-entry.md new file mode 100644 index 00000000..280e32bd --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/consuming-atom-entry.md @@ -0,0 +1,23 @@ +# Consuming a Single Atom Entry + +Single Atom `` elements are also valid by themselves. Usually the URL for +an entry is the feed's URL followed by `/`, such as +`http://atom.example.com/feed/1`, using the example URL we used above. This +pattern may exist for some web services which use Atom as a container syntax. + +If you read a single entry, you will have a `Zend\Feed\Reader\Entry\Atom` object. + +## Reading a Single-Entry Atom Feed + +```php +$entry = Zend\Feed\Reader\Reader::import('http://atom.example.com/feed/1'); +echo 'Entry title: ' . $entry->getTitle(); +``` + +> ## Importing requires an HTTP client +> +> To import a feed, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). diff --git a/vendor/zendframework/zend-feed/doc/book/consuming-atom.md b/vendor/zendframework/zend-feed/doc/book/consuming-atom.md new file mode 100644 index 00000000..fdee05ac --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/consuming-atom.md @@ -0,0 +1,62 @@ +# Consuming Atom Feeds + +`Zend\Feed\Reader\Feed\Atom` is used in much the same way as +`Zend\Feed\Reader\Feed\Rss`. It provides the same access to feed-level +properties and iteration over entries in the feed. The main difference is in the +structure of the Atom protocol itself. Atom is a successor to RSS; it is a +more generalized protocol and it is designed to deal more easily with feeds that +provide their full content inside the feed, splitting RSS' `description` tag +into two elements, `summary` and `content`, for that purpose. + +## Basic Use of an Atom Feed + +Read an Atom feed and print the `title` and `summary` of each entry: + +```php +$feed = Zend\Feed\Reader\Reader::import('http://atom.example.com/feed/'); +echo 'The feed contains ' . $feed->count() . ' entries.' . "\n\n"; +foreach ($feed as $entry) { + echo 'Title: ' . $entry->getTitle() . "\n"; + echo 'Description: ' . $entry->getDescription() . "\n"; + echo 'URL: ' . $entry->getLink() . "\n\n"; +} +``` + +> ## Importing requires an HTTP client +> +> To import a feed, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). + +In an Atom feed, you can expect to find the following feed properties: + +- `title`: The feed's title, same as RSS' channel title. +- `id`: Every feed and entry in Atom has a unique identifier. +- `link`: Feeds can have multiple links, which are distinguished by a `type` + attribute. The equivalent to RSS's channel link would be `type="text/html"`. + If the link is to an alternate version of the same content that's in the feed, + it would have a `rel="alternate"` attribute. +- `subtitle`: The feed's description, equivalent to RSS' channel description. +- `author`: The feed's author, with `name` and `email` sub-tags. + +Atom entries commonly have the following properties: + +- `id`: The entry's unique identifier. +- `title`: The entry's title, same as RSS item titles. +- `link`: A link to another format or an alternate view of this entry. + The link property of an atom entry typically has an `href` attribute. +- `summary`: A summary of this entry's content. +- `content`: The full content of the entry; can be skipped if the feed just + contains summaries. +- `author`: with `name` and `email` sub-tags like feeds have. +- `published`: the date the entry was published, in RFC 3339 format. +- `updated`: the date the entry was last updated, in RFC 3339 format. + +Where relevant, `Zend\Feed` supports a number of common RSS extensions including +Dublin Core; Content, Slash, Syndication, and Syndication/Thread; and several +others in common use on blogs. + +For more information on Atom and plenty of resources, see +[http://www.atomenabled.org/](http://www.atomenabled.org/). diff --git a/vendor/zendframework/zend-feed/doc/book/consuming-rss.md b/vendor/zendframework/zend-feed/doc/book/consuming-rss.md new file mode 100644 index 00000000..f965a0c4 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/consuming-rss.md @@ -0,0 +1,99 @@ +# Consuming RSS Feeds + +## Reading a feed + +To read an RSS feed, pass its URL to `Zend\Feed\Reader\Reader::import()`: + +```php +$channel = Zend\Feed\Reader\Reader::import('http://rss.example.com/channelName'); +``` + +> ## Importing requires an HTTP client +> +> To import a feed, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). + +If any errors occur fetching the feed, a +`Zend\Feed\Reader\Exception\RuntimeException` will be thrown. + +## Get properties + +Once you have a feed object, you can access any of the standard RSS channel +properties via the various instance getter methods: + +```php +echo $channel->getTitle(); +echo $channel->getAuthor(); +// etc. +``` + +If channel properties have attributes, the getter method will return a key/value +pair, where the key is the attribute name, and the value is the attribute value. + +```php +$author = $channel->getAuthor(); +echo $author['name']; +``` + +Most commonly, you'll want to loop through the feed and do something with its +entries. `Zend\Feed\Reader\Feed\Rss` internally converts all entries to a +`Zend\Feed\Reader\Entry\Rss` instance. Entry properties, similarly to channel +properties, can be accessed via getter methods, such as `getTitle`, +`getDescription`, etc. + +An example of printing all titles of articles in a channel is: + +```php +foreach ($channel as $item) { + echo $item->getTitle() . "\n"; +} +``` + +If you are not familiar with RSS, here are the standard elements you can expect +to be available in an RSS channel and in individual RSS items (entries). + +Required channel elements: + +- `title`: The name of the channel. +- `link`: The URL of the web site corresponding to the channel. +- `description`: A sentence (or more) describing the channel. + +Common optional channel elements: + +- `pubDate`: The publication date of this set of content, in RFC 822 date + format. +- `language`: The language the channel is written in. +- `category`: One or more (specified by multiple tags) categories the channel + belongs to. + +RSS `` elements do not have any strictly required elements. However, +either `title` or `description` must be present. + +Common item elements: + +- `title`: The title of the item. +- `link`: The URL of the item. +- `description`: A synopsis of the item. +- `author`: The author's email address. +- `category`: One more categories that the item belongs to. +- `comments`: URL of comments relating to this item. +- `pubDate`: The date the item was published, in RFC 822 date format. + +In your code you can always test to see if an element is non-empty by calling +the getter: + +```php +if ($item->getPropname()) { + // ... proceed. +} +``` + +Where relevant, `Zend\Feed` supports a number of common RSS extensions including +Dublin Core, Atom (inside RSS); the Content, Slash, Syndication, +Syndication/Thread extensions; as well as several others. + +Please see the official [RSS 2.0 specification](http://cyber.law.harvard.edu/rss/rss.html) +for further information. diff --git a/vendor/zendframework/zend-feed/doc/book/find-feeds.md b/vendor/zendframework/zend-feed/doc/book/find-feeds.md new file mode 100644 index 00000000..0f934072 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/find-feeds.md @@ -0,0 +1,48 @@ +# Feed Discovery from Web Pages + +Web pages often contain `` tags that refer to feeds with content relevant +to the particular page. `Zend\Feed\Reader\Reader` enables you to retrieve all +feeds referenced by a web page with one method call: + +```php +$feedLinks = Zend\Feed\Reader\Reader::findFeedLinks('http://www.example.com/news.html'); +``` + +> ## Finding feed links requires an HTTP client +> +> To find feed links, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). + +Here the `findFeedLinks()` method returns a `Zend\Feed\Reader\FeedSet` object, +which is in turn a collection of other `Zend\Feed\Reader\FeedSet` objects, each +referenced by `` tags on the `news.html` web page. +`Zend\Feed\Reader\Reader` will throw a +`Zend\Feed\Reader\Exception\RuntimeException` upon failure, such as an HTTP +404 response code or a malformed feed. + +You can examine all feed links located by iterating across the collection: + +```php +$rssFeed = null; +$feedLinks = Zend\Feed\Reader\Reader::findFeedLinks('http://www.example.com/news.html'); +foreach ($feedLinks as $link) { + if (stripos($link['type'], 'application/rss+xml') !== false) { + $rssFeed = $link['href']; + break; +} +``` + +Each `Zend\Feed\Reader\FeedSet` object will expose the `rel`, `href`, `type`, +and `title` properties of detected links for all RSS, Atom, or RDF feeds. You +can always select the first encountered link of each type by using a shortcut: +the first encountered link of a given type is assigned to a property named after +the feed type. + +```php +$rssFeed = null; +$feedLinks = Zend\Feed\Reader\Reader::findFeedLinks('http://www.example.com/news.html'); +$firstAtomFeed = $feedLinks->atom; +``` diff --git a/vendor/zendframework/zend-feed/doc/book/http-clients.md b/vendor/zendframework/zend-feed/doc/book/http-clients.md new file mode 100644 index 00000000..9b936349 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/http-clients.md @@ -0,0 +1,236 @@ +# HTTP Clients and zend-feed + +Several operations in zend-feed's Reader subcomponent require an HTTP client: + +- importing a feed +- finding links in a feed + +In order to allow developers a choice in HTTP clients, the subcomponent defines +several interfaces and classes. Elsewhere in the documentation, we reference +where an HTTP client may be used; this document details what constitutes an HTTP +client and its behavior, and some of the concrete classes available within the +component for implementing this behavior. + +## ClientInterface and HeaderAwareClientInterface + +First, we define two interfaces for clients, +`Zend\Feed\Reader\Http\ClientInterface` and `HeaderAwareClientInterface`: + +```php +namespace Zend\Feed\Reader\Http; + +interface ClientInterface +{ + /** + * Make a GET request to a given URL. + * + * @param string $url + * @return ResponseInterface + */ + public function get($url); +} + +interface HeaderAwareClientInterface extends ClientInterface +{ + /** + * Make a GET request to a given URL. + * + * @param string $url + * @param array $headers + * @return ResponseInterface + */ + public function get($url, array $headers = []); +} +``` + +The first is header-agnostic, and assumes that the client will simply perform an +HTTP GET request. The second allows providing headers to the client; typically, +these are used for HTTP caching headers. `$headers` must be in the following +structure: + +```php +$headers = [ + 'X-Header-Name' => [ + 'header', + 'values', + ], +]; +``` + +i.e., each key is a header name, and each value is an array of values for that +header. If the header represents only a single value, it should be an array with +that value: + +```php +$headers = [ + 'Accept' => [ 'application/rss+xml' ], +]; +``` + +A call to `get()` should yield a *response*. + +## ResponseInterface and HeaderAwareResponseInterface + +Responses are modeled using `Zend\Feed\Reader\Http\ResponseInterface` and +`HeaderAwareResponseInterface`: + +```php +namespace Zend\Feed\Reader\Http; + +class ResponseInterface +{ + /** + * Retrieve the status code. + * + * @return int + */ + public function getStatusCode(); + + /** + * Retrieve the response body contents. + * + * @return string + */ + public function getBody(); +} + +class HeaderAwareResponseInterface extends ResponseInterface +{ + /** + * Retrieve a named header line. + * + * Retrieve a header by name; all values MUST be concatenated to a single + * line. If no matching header is found, return the $default value. + * + * @param string $name + * @param null|string $default + * @return string + public function getHeaderLine($name, $default = null); +} +``` + +Internally, `Reader` will typehint against `ClientInterface` for the bulk of +operations. In some cases, however, certain capabilities are only possible if +the response can provide headers (e.g., for caching); in such cases, it will +check the instance against `HeaderAwareResponseInterface`, and only call +`getHeaderLine()` if it matches. + +## Response + +zend-feed ships with a generic `ResponseInterface` implementation, +`Zend\Feed\Http\Response`. It implements `HeaderAwareResponseInterface`, and +defines the following constructor: + +```php +namespace Zend\Feed\Reader\Http; + +class Response implements HeaderAwareResponseInterface +{ + /** + * Constructor + * + * @param int $statusCode Response status code + * @param string $body Response body + * @param array $headers Response headers, if available + */ + public function __construct($statusCode, $body, array $headers = []); +} +``` + +## PSR-7 Response + +[PSR-7](http://www.php-fig.org/psr/psr-7/) defines a set of HTTP message +interfaces, but not a client interface. To facilitate wrapping an HTTP client +that uses PSR-7 messages, we provide `Zend\Feed\Reader\Psr7ResponseDecorator`: + +```php +namespace Zend\Feed\Reader\Http; + +use Psr\Http\Message\ResponseInterface as PsrResponseInterface; + +class Psr7ResponseDecorator implements HeaderAwareResponseInterface +{ + /** + * @param PsrResponseInterface $response + */ + public function __construct(PsrResponseInterface $response); + + /** + * @return PsrResponseInterface + */ + public function getDecoratedResponse(); +} +``` + +Clients can then take the PSR-7 response they receive, pass it to the decorator, +and return the decorator. + +To use the PSR-7 response, you will need to add the PSR-7 interfaces to your +application, if they are not already installed by the client of your choice: + +```bash +$ composer require psr/http-message +``` + +## zend-http + +We also provide a zend-http client decorator, +`Zend\Feed\Reader\Http\ZendHttpClientDecorator`: + +```php +namespace Zend\Feed\Reader\Http; + +use Zend\Http\Client as HttpClient; + +class ZendHttpClientDecorator implements HeaderAwareClientInterface +{ + /** + * @param HttpClient $client + */ + public function __construct(HttpClient $client); + + /** + * @return HttpClient + */ + public function getDecoratedClient(); +} +``` + +Its `get()` implementation returns a `Response` instance seeded from the +zend-http response returned, including status, body, and headers. + +zend-http is the default implementation assumed by `Zend\Feed\Reader\Reader`, +but *is not installed by default*. You may install it using composer: + +```bash +$ composer require zendframework/zend-http +``` + +## Providing a client to Reader + +By default, `Zend\Feed\Reader\Reader` will lazy load a zend-http client. If you +have not installed zend-http, however, PHP will raise an error indicating the +class is not found! + +As such, you have two options: + +1. Install zend-http: `composer require zendframework/zend-http`. +2. Inject the `Reader` with your own HTTP client. + +To accomplish the second, you will need an implementation of +`Zend\Feed\Reader\Http\ClientInterface` or `HeaderAwareClientInterface`, and an +instance of that implementation. Once you do, you can use the static method +`setHttpClient()` to inject it. + +As an example, let's say you've created a PSR-7-based implementation named +`My\Http\Psr7FeedClient`. You could then do the following: + +```php +use My\Http\Psr7FeedClient; +use Zend\Feed\Reader\Reader; + +Reader::setHttpClient(new Psr7FeedClient()); +``` + +Your client will then be used for all `import()` and `findFeedLinks()` +operations. diff --git a/vendor/zendframework/zend-feed/doc/book/importing.md b/vendor/zendframework/zend-feed/doc/book/importing.md new file mode 100644 index 00000000..52b58936 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/importing.md @@ -0,0 +1,49 @@ +# Importing Feeds + +`Zend\Feed` enables developers to retrieve feeds via `Zend\Feader\Reader`. If +you know the URI of a feed, use the `Zend\Feed\Reader\Reader::import()` method +to consume it: + +```php +$feed = Zend\Feed\Reader\Reader::import('http://feeds.example.com/feedName'); +``` + +> ## Importing requires an HTTP client +> +> To import a feed, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). + +You can also use `Zend\Feed\Reader\Reader` to fetch the contents of a feed from +a file or the contents of a PHP string variable: + +```php +// importing a feed from a text file +$feedFromFile = Zend\Feed\Reader\Reader::importFile('feed.xml'); + +// importing a feed from a PHP string variable +$feedFromPHP = Zend\Feed\Reader\Reader::importString($feedString); +``` + +In each of the examples above, an object of a class that extends +`Zend\Feed\Reader\Feed\AbstractFeed` is returned upon success, depending on the +type of the feed. If an RSS feed were retrieved via one of the import methods +above, then a `Zend\Feed\Reader\Feed\Rss` object would be returned. On the other +hand, if an Atom feed were imported, then a `Zend\Feed\Reader\Feed\Atom` object +is returned. The import methods will also throw a +`Zend\Feed\Exception\Reader\RuntimeException` object upon failure, such as an +unreadable or malformed feed. + +## Dumping the contents of a feed + +To dump the contents of a `Zend\Feed\Reader\Feed\AbstractFeed` instance, you may +use the `saveXml()` method. + +```php +assert($feed instanceof Zend\Feed\Reader\Feed\AbstractFeed); + +// dump the feed to standard output +print $feed->saveXml(); +``` diff --git a/vendor/zendframework/zend-feed/doc/book/index.html b/vendor/zendframework/zend-feed/doc/book/index.html new file mode 100644 index 00000000..f05b9c11 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/index.html @@ -0,0 +1,10 @@ +
    +
    +

    zend-feed

    + +

    Consume and generate Atom and RSS feeds, and interact with Pubsubhubbub.

    + +
    $ composer require zendframework/zend-feed
    +
    +
    + diff --git a/vendor/zendframework/zend-feed/doc/book/index.md b/vendor/zendframework/zend-feed/doc/book/index.md new file mode 100644 index 00000000..3e2afd55 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/index.md @@ -0,0 +1,13 @@ +# zend-feed + +[![Build Status](https://secure.travis-ci.org/zendframework/zend-feed.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-feed) +[![Coverage Status](https://coveralls.io/repos/zendframework/zend-feed/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-feed?branch=master) + +`Zend\Feed` provides functionality for consuming RSS and Atom feeds. It provides +a natural syntax for accessing elements of feeds, feed attributes, and entry +attributes. `Zend\Feed` also has extensive support for modifying feed and entry +structure with the same natural syntax, and turning the result back into XML. + + +- File issues at https://github.com/zendframework/zend-feed/issues +- Documentation is at https://zendframework.github.io/zend-feed/ diff --git a/vendor/zendframework/zend-feed/doc/book/intro.md b/vendor/zendframework/zend-feed/doc/book/intro.md new file mode 100644 index 00000000..784aac8f --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/intro.md @@ -0,0 +1,62 @@ +# Introduction + +`Zend\Feed` provides functionality for consuming RSS and Atom feeds. It provides +a natural syntax for accessing elements of feeds, feed attributes, and entry +attributes. `Zend\Feed` also has extensive support for modifying feed and entry +structure with the same natural syntax, and turning the result back into XML. +In the future, this modification support could provide support for the Atom +Publishing Protocol. + +`Zend\Feed` consists of `Zend\Feed\Reader` for reading RSS and Atom feeds, +`Zend\Feed\Writer` for writing RSS and Atom feeds, and `Zend\Feed\PubSubHubbub` +for working with Hub servers. Furthermore, both `Zend\Feed\Reader` and +`Zend\Feed\Writer` support extensions which allows for working with additional +data in feeds, not covered in the core API but used in conjunction with RSS and +Atom feeds. + +In the example below, we demonstrate a simple use case of retrieving an RSS feed +and saving relevant portions of the feed data to a simple PHP array, which could +then be used for printing the data, storing to a database, etc. + +> ## RSS optional properties +> +> Many *RSS* feeds have different channel and item properties available. The +> *RSS* specification provides for many optional properties, so be aware of this +> when writing code to work with *RSS* data. `Zend\Feed` supports all optional +> properties of the core *RSS* and *Atom* specifications. + +## Reading RSS Feed Data + +```php +// Fetch the latest Slashdot headlines +try { + $slashdotRss = + Zend\Feed\Reader\Reader::import('http://rss.slashdot.org/Slashdot/slashdot'); +} catch (Zend\Feed\Reader\Exception\RuntimeException $e) { + // feed import failed + echo "Exception caught importing feed: {$e->getMessage()}\n"; + exit; +} + +// Initialize the channel/feed data array +$channel = [ + 'title' => $slashdotRss->getTitle(), + 'link' => $slashdotRss->getLink(), + 'description' => $slashdotRss->getDescription(), + 'items' => [], +]; + +// Loop over each channel item/entry and store relevant data for each +foreach ($slashdotRss as $item) { + $channel['items'][] = [ + 'title' => $item->getTitle(), + 'link' => $item->getLink(), + 'description' => $item->getDescription(), + ]; +} +``` + +Your `$channel` array now contains the basic meta-information for the RSS +channel and all items that it contained. The process is identical for Atom +feeds since `Zend\Feed` provides a common feed API; i.e. all getters and +setters are the same regardless of feed format. diff --git a/vendor/zendframework/zend-feed/doc/book/pubsubhubbub.md b/vendor/zendframework/zend-feed/doc/book/pubsubhubbub.md new file mode 100644 index 00000000..c5719fa4 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/pubsubhubbub.md @@ -0,0 +1,452 @@ +# Zend\\Feed\\PubSubHubbub + +`Zend\Feed\PubSubHubbub` is an implementation of the [PubSubHubbub Core 0.2/0.3 +Specification (Working Draft)](http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html). +It offers implementations of a Pubsubhubbub Publisher and Subscriber suited to +PHP applications. + +## What is PubSubHubbub? + +Pubsubhubbub is an open, simple, web-scale, pubsub protocol. A common use case +to enable blogs (Publishers) to "push" updates from their RSS or Atom feeds +(Topics) to end Subscribers. These Subscribers will have subscribed to the +blog's RSS or Atom feed via a Hub, a central server which is notified of any +updates by the Publisher, and which then distributes these updates to all +Subscribers. Any feed may advertise that it supports one or more Hubs using an +Atom namespaced link element with a rel attribute of "hub" (i.e., `rel="hub"`). + +Pubsubhubbub has garnered attention because it is a pubsub protocol which is +easy to implement and which operates over HTTP. Its philosophy is to replace the +traditional model where blog feeds have been polled at regular intervals to +detect and retrieve updates. Depending on the frequency of polling, this can +take a lot of time to propagate updates to interested parties from planet +aggregators to desktop readers. With a pubsub system in place, updates are not +simply polled by Subscribers, they are pushed to Subscribers, eliminating any +delay. For this reason, Pubsubhubbub forms part of what has been dubbed the +real-time web. + +The protocol does not exist in isolation. Pubsub systems have been around for a +while, such as the familiar Jabber Publish-Subscribe protocol, +[XEP-0060](http://www.xmpp.org/extensions/xep-0060.html), or the less well-known +[rssCloud](http://www.rssboard.org/rsscloud-interface) (described in 2001). +However, these have not achieved widespread adoption due to either their +complexity, poor timing, or lack of suitability for web applications. rssCloud, +which was recently revived as a response to the appearance of Pubsubhubbub, has +also seen its usage increase significantly, though it lacks a formal +specification and currently does not support Atom 1.0 feeds. + +Perhaps surprisingly given its relative early age, Pubsubhubbub is already in +use including in Google Reader and Feedburner, and there are plugins available +for Wordpress blogs. + +## Architecture + +`Zend\Feed\PubSubHubbub` implements two sides of the Pubsubhubbub 0.2/0.3 +Specification: a Publisher and a Subscriber. It does not currently implement a +Hub Server. + +A Publisher is responsible for notifying all supported Hubs (many can be +supported to add redundancy to the system) of any updates to its feeds, whether +they be Atom or RSS based. This is achieved by pinging the supported Hub Servers +with the URL of the updated feed. In Pubsubhubbub terminology, any updatable +resource capable of being subscribed to is referred to as a Topic. Once a ping +is received, the Hub will request the updated feed, process it for updated +items, and forward all updates to all Subscribers subscribed to that feed. + +A Subscriber is any party or application which subscribes to one or more Hubs to +receive updates from a Topic hosted by a Publisher. The Subscriber never +directly communicates with the Publisher since the Hub acts as an intermediary, +accepting subscriptions and sending updates to Subscribers. The Subscriber +therefore communicates only with the Hub, either to subscribe or unsubscribe to +Topics, or when it receives updates from the Hub. This communication design +("Fat Pings") effectively removes the possibility of a "Thundering Herd" issue. +(Thundering Herds occur in a pubsub system where the Hub merely informs +Subscribers that an update is available, prompting all Subscribers to +immediately retrieve the feed from the Publisher, giving rise to a traffic +spike.) In Pubsubhubbub, the Hub distributes the actual update in a "Fat Ping" +so the Publisher is not subjected to any traffic spike. + +`Zend\Feed\PubSubHubbub` implements Pubsubhubbub Publishers and Subscribers with +the classes `Zend\Feed\PubSubHubbub\Publisher` and +`Zend\Feed\PubSubHubbub\Subscriber`. In addition, the Subscriber implementation +may handle any feed updates forwarded from a Hub by using +`Zend\Feed\PubSubHubbub\Subscriber\Callback`. These classes, their use cases, +and etheir APIs are covered in subsequent sections. + +## Zend\\Feed\\PubSubHubbub\\Publisher + +In Pubsubhubbub, the Publisher is the party publishing a live feed with content +updates. This may be a blog, an aggregator, or even a web service with a public +feed based API. In order for these updates to be pushed to Subscribers, the +Publisher must notify all of its supported Hubs that an update has occurred +using a simple HTTP POST request containing the URI of the updated Topic (i.e., +the updated RSS or Atom feed). The Hub will confirm receipt of the notification, +fetch the updated feed, and forward any updates to any Subscribers who have +subscribed to that Hub for updates from the relevant feed. + +By design, this means the Publisher has very little to do except send these Hub +pings whenever its feeds change. As a result, the Publisher implementation is +extremely simple to use and requires very little work to setup and use when +feeds are updated. + +`Zend\Feed\PubSubHubbub\Publisher` implements a full Pubsubhubbub Publisher. Its +setup for use primarily requires that it is configured with the URI endpoint for +all Hubs to be notified of updates, and the URIs of all Topics to be included in +the notifications. + +The following example shows a Publisher notifying a collection of Hubs about +updates to a pair of local RSS and Atom feeds. The class retains a collection of +errors which include the Hub URLs, so that notification can be attempted again +later and/or logged if any notifications happen to fail. Each resulting error +array also includes a "response" key containing the related HTTP response +object. In the event of any errors, it is strongly recommended to attempt the +operation for failed Hub Endpoints at least once more at a future time. This may +require the use of either a scheduled task for this purpose or a job queue, +though such extra steps are optional. + +```php +use Zend\Feed\PubSubHubbub\Publisher; + +$publisher = Publisher; +$publisher->addHubUrls([ + 'http://pubsubhubbub.appspot.com/', + 'http://hubbub.example.com', +]); +$publisher->addUpdatedTopicUrls([ + 'http://www.example.net/rss', + 'http://www.example.net/atom', +]); +$publisher->notifyAll(); + +if (! $publisher->isSuccess()) { + // check for errors + $errors = $publisher->getErrors(); + $failedHubs = []; + foreach ($errors as $error) { + $failedHubs[] = $error['hubUrl']; + } +} + +// reschedule notifications for the failed Hubs in $failedHubs +``` + +If you prefer having more concrete control over the Publisher, the methods +`addHubUrls()` and `addUpdatedTopicUrls()` pass each array value to the singular +`addHubUrl()` and `addUpdatedTopicUrl()` public methods. There are also matching +`removeUpdatedTopicUrl()` and `removeHubUrl()` methods. + +You can also skip setting Hub URIs, and notify each in turn using the +`notifyHub()` method which accepts the URI of a Hub endpoint as its only +argument. + +There are no other tasks to cover. The Publisher implementation is very simple +since most of the feed processing and distribution is handled by the selected +Hubs. It is, however, important to detect errors and reschedule notifications as +soon as possible (with a reasonable maximum number of retries) to ensure +notifications reach all Subscribers. In many cases, as a final alternative, Hubs +may frequently poll your feeds to offer some additional tolerance for failures +both in terms of their own temporary downtime or Publisher errors or downtime. + +## Zend\\Feed\\PubSubHubbub\\Subscriber + +In Pubsubhubbub, the Subscriber is the party who wishes to receive updates to +any Topic (RSS or Atom feed). They achieve this by subscribing to one or more of +the Hubs advertised by that Topic, usually as a set of one or more Atom 1.0 +links with a rel attribute of "hub" (i.e., `rel="hub"`). The Hub from that point +forward will send an Atom or RSS feed containing all updates to that +Subscriber's callback URL when it receives an update notification from the +Publisher. In this way, the Subscriber need never actually visit the original +feed (though it's still recommended at some level to ensure updates are +retrieved if ever a Hub goes offline). All subscription requests must contain +the URI of the Topic being subscribed and a callback URL which the Hub will use +to confirm the subscription and to forward updates. + +The Subscriber therefore has two roles. The first is to *create* and *manage* +subscriptions, including subscribing for new Topics with a Hub, unsubscribing +(if necessary), and periodically renewing subscriptions, since they may have an +expiry set by the Hub. This is handled by `Zend\Feed\PubSubHubbub\Subscriber`. + +The second role is to *accept updates* sent by a Hub to the Subscriber's +callback URL, i.e. the URI the Subscriber has assigned to handle updates. The +callback URL also handles events where the Hub contacts the Subscriber to +confirm all subscriptions and unsubscriptions. This is handled by using an +instance of `Zend\Feed\PubSubHubbub\Subscriber\Callback` when the callback URL +is accessed. + +> ### Query strings in callback URLs +> +> `Zend\Feed\PubSubHubbub\Subscriber` implements the Pubsubhubbub 0.2/0.3 +> specification. As this is a new specification version, not all Hubs currently +> implement it. The new specification allows the callback URL to include a query +> string which is used by this class, but not supported by all Hubs. In the +> interests of maximising compatibility, it is therefore recommended that the +> query string component of the Subscriber callback URI be presented as a path +> element, i.e. recognised as a parameter in the route associated with the +> callback URI and used by the application's router. + +### Subscribing and Unsubscribing + +`Zend\Feed\PubSubHubbub\Subscriber` implements a full Pubsubhubbub Subscriber +capable of subscribing to, or unsubscribing from, any Topic via any Hub +advertised by that Topic. It operates in conjunction with +`Zend\Feed\PubSubHubbub\Subscriber\Callback`, which accepts requests from a Hub +to confirm all subscription or unsubscription attempts (to prevent third-party +misuse). + +Any subscription (or unsubscription) requires the relevant information before +proceeding, i.e. the URI of the Topic (Atom or RSS feed) to be subscribed to for +updates, and the URI of the endpoint for the Hub which will handle the +subscription and forwarding of the updates. The lifetime of a subscription may +be determined by the Hub, but most Hubs should support automatic subscription +refreshes by checking with the Subscriber. This is supported by +`Zend\Feed\PubSubHubbub\Subscriber\Callback` and requires no other work on your +part. It is still strongly recommended that you use the Hub-sourced subscription +time-to.live (ttl) to schedule the creation of new subscriptions (the process is +identical to that for any new subscription) to refresh it with the Hub. While it +should not be necessary per se, it covers cases where a Hub may not support +automatic subscription refreshing, and rules out Hub errors for additional +redundancy. + +With the relevant information to hand, a subscription can be attempted as +demonstrated below: + +```php +use Zend\Feed\PubSubHubbub\Model\Subscription; +use Zend\Feed\PubSubHubbub\Subscriber; + +$storage = new Subscription; +$subscriber = new Subscriber; +$subscriber->setStorage($storage); +$subscriber->addHubUrl('http://hubbub.example.com'); +$subscriber->setTopicUrl('http://www.example.net/rss.xml'); +$subscriber->setCallbackUrl('http://www.mydomain.com/hubbub/callback'); +$subscriber->subscribeAll(); +``` + +In order to store subscriptions and offer access to this data for general use, +the component requires a database (a schema is provided later in this section). +By default, it is assumed the table name is "subscription", and it utilises +`Zend\Db\TableGateway\TableGateway` in the background, meaning it will use the +default adapter you have set for your application. You may also pass a specific +custom `Zend\Db\TableGateway\TableGateway` instance into the associated model +`Zend\Feed\PubSubHubbub\Model\Subscription`. This custom adapter may be as +simple in intent as changing the table name to use or as complex as you deem +necessary. + +While this model is offered as a default ready-to-roll solution, you may create +your own model using any other backend or database layer (e.g. Doctrine) so long +as the resulting class implements the interface +`Zend\Feed\PubSubHubbub\Model\SubscriptionInterface`. + +An example schema (MySQL) for a subscription table accessible by the provided +model may look similar to: + +```sql +CREATE TABLE IF NOT EXISTS `subscription` ( + `id` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', + `topic_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `hub_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `created_time` datetime DEFAULT NULL, + `lease_seconds` bigint(20) DEFAULT NULL, + `verify_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `secret` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, + `expiration_time` datetime DEFAULT NULL, + `subscription_state` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +``` + +Behind the scenes, the Subscriber above will send a request to the Hub endpoint +containing the following parameters (based on the previous example): + +Parameter | Value | Explanation +--------- | ----- | ----------- +`hub.callback` | `http://www.mydomain.com/hubbub/callback?xhub.subscription=5536df06b5dcb966edab3a4c4d56213c16a8184` | The URI used by a Hub to contact the Subscriber and either request confirmation of a (un)subscription request, or send updates from subscribed feeds. The appended query string contains a custom parameter (hence the xhub designation). It is a query string parameter preserved by the Hub and re-sent with all Subscriber requests. Its purpose is to allow the Subscriber to identify and look up the subscription associated with any Hub request in a backend storage medium. This is a non-standard parameter used by this component in preference to encoding a subscription key in the URI path, which is difficult to enforce generically. Nevertheless, since not all Hubs support query string parameters, we still strongly recommend adding the subscription key as a path component in the form `http://www.mydomain.com/hubbub/callback/5536df06b5dcb966edab3a4c4d56213c16a8184`. This requires defining a route capable of parsing out the final value of the key, retrieving the value, and passing it to the Subscriber callback object. The value should be passed into the method `Zend\PubSubHubbub\Subscriber\Callback::setSubscriptionKey()`. A detailed example is offered later. +`hub.lease_seconds` | `2592000` | The number of seconds for which the Subscriber would like a new subscription to remain valid (i.e. a TTL). Hubs may enforce their own maximum subscription period. All subscriptions should be renewed by re-subscribing before the subscription period ends to ensure continuity of updates. Hubs should additionally attempt to automatically refresh subscriptions before they expire by contacting Subscribers (handled automatically by the `Callback` class). +`hub.mode` | `subscribe` | Value indicating this is a subscription request. Unsubscription requests would use the "unsubscribe" value. +`hub.topic` | `http://www.example.net/rss.xml` | The URI of the Topic (i.e. Atom or RSS feed) which the Subscriber wishes to subscribe to for updates. +`hub.verify` | `sync` or `async` | Indicates to the Hub the preferred mode of verifying subscriptions or unsubscriptions. It is repeated twice in order of preference. Technically this component does not distinguish between the two modes and treats both equally. +`hub.verify_token` | `3065919804abcaa7212ae89.879827871253878386` | A verification token returned to the Subscriber by the Hub when it is confirming a subscription or unsubscription. Offers a measure of reliance that the confirmation request originates from the correct Hub to prevent misuse. + +You can modify several of these parameters to indicate a different preference. +For example, you can set a different lease seconds value using +`Zend\Feed\PubSubHubbub\Subscriber::setLeaseSeconds(),` or show a preference for +the `async` verify mode by using `setPreferredVerificationMode(Zend\Feed\PubSubHubbub\PubSubHubbub::VERIFICATION_MODE_ASYNC)`. +However, the Hubs retain the capability to enforce their own preferences, and +for this reason the component is deliberately designed to work across almost any +set of options with minimum end-user configuration required. Conventions are +great when they work! + +> ### Verification modes +> +> While Hubs may require the use of a specific verification mode (both are +> supported by `Zend\Feed\PubSubHubbub`), you may indicate a specific preference +> using the `setPreferredVerificationMode()` method. In `sync` (synchronous) +> mode, the Hub attempts to confirm a subscription as soon as it is received, +> and before responding to the subscription request. In `async` (asynchronous) +> mode, the Hub will return a response to the subscription request immediately, +> and its verification request may occur at a later time. Since +> `Zend\Feed\PubSubHubbub` implements the Subscriber verification role as a +> separate callback class and requires the use of a backend storage medium, it +> actually supports both transparently. In terms of end-user performance, +> asynchronous verification is very much preferred to eliminate the impact of a +> poorly performing Hub tying up end-user server resources and connections for +> too long. + +Unsubscribing from a Topic follows the exact same pattern as the previous +example, with the exception that we should call `unsubscribeAll()` instead. The +parameters included are identical to a subscription request with the exception +that `hub.mode` is set to "unsubscribe". + +By default, a new instance of `Zend\PubSubHubbub\Subscriber` will attempt to use +a database backed storage medium which defaults to using the default zend-db +adapter with a table name of "subscription". It is recommended to set a custom +storage solution where these defaults are not apt either by passing in a new +model supporting the required interface or by passing a new instance of +`Zend\Db\TableGateway\TableGateway` to the default model's constructor to change +the used table name. + +### Handling Subscriber Callbacks + +Whenever a subscription or unsubscription request is made, the Hub must verify +the request by forwarding a new verification request to the callback URL set in +the subscription or unsubscription parameters. To handle these Hub requests, +which will include all future communications containing Topic (feed) updates, +the callback URL should trigger the execution of an instance of +`Zend\Feed\PubSubHubbub\Subscriber\Callback` to handle the request. + +The `Callback` class should be configured to use the same storage medium as the +`Subscriber` class. The bulk of the work is handled internal to these classes. + +```php +use Zend\Feed\PubSubHubbub\Model\Subscription; +use Zend\Feed\PubSubHubbub\Subscriber\Callback; + +$storage = new Subscription(); +$callback = new Callback(); +$callback->setStorage($storage); +$callback->handle(); +$callback->sendResponse(); + +/* + * Check if the callback resulting in the receipt of a feed update. + * Otherwise it was either a (un)sub verification request or invalid request. + * Typically we need do nothing other than add feed update handling; the rest + * is handled internally by the class. + */ +if ($callback->hasFeedUpdate()) { + $feedString = $callback->getFeedUpdate(); + /* + * Process the feed update asynchronously to avoid a Hub timeout. + */ +} +``` + +> #### Query and body parameters +> +> It should be noted that `Zend\Feed\PubSubHubbub\Subscriber\Callback` may +> independently parse any incoming query string and other parameters. This is +> necessary since PHP alters the structure and keys of a query string when it is +> parsed into the `$_GET` or `$_POST` superglobals; for example, all duplicate +> keys are ignored and periods are converted to underscores. Pubsubhubbub +> features both of these in the query strings it generates. + +> #### Always delay feed processing +> +> It is essential that developers recognise that Hubs are only concerned with +> sending requests and receiving a response which verifies its receipt. If a +> feed update is received, it should never be processed on the spot since this +> leaves the Hub waiting for a response. Rather, any processing should be +> offloaded to another process or deferred until after a response has been +> returned to the Hub. One symptom of a failure to promptly complete Hub +> requests is that a Hub may continue to attempt delivery of the update or +> verification request leading to duplicated update attempts being processed by +> the Subscriber. This appears problematic, but in reality a Hub may apply a +> timeout of just a few seconds, and if no response is received within that time +> it may disconnect (assuming a delivery failure) and retry later. Note that +> Hubs are expected to distribute vast volumes of updates so their resources are +> stretched; please process feeds asynchronously (e.g. in a separate process or +> a job queue or even a cronjob) as much as possible. + +### Setting Up And Using A Callback URL Route + +As noted earlier, the `Zend\Feed\PubSubHubbub\Subscriber\Callback` class +receives the combined key associated with any subscription from the Hub via one +of two methods. The technically preferred method is to add this key to the +callback URL employed by the Hub in all future requests using a query string +parameter with the key `xhub.subscription`. However, for historical reasons +(primarily that this was not supported in Pubsubhubbub 0.1, and a late addition +to 0.2 ), it is strongly recommended to use the most compatible means of adding +this key to the callback URL by appending it to the URL's path. + +Thus the URL `http://www.example.com/callback?xhub.subscription=key` would become +`http://www.example.com/callback/key`. + +Since the query string method is the default in anticipation of a greater level +of future support for the full 0.2/0.3 specification, this requires some +additional work to implement. + +The first step is to make the `Zend\Feed\PubSubHubbub\Subscriber\Callback` class +aware of the path contained subscription key. It's manually injected; therefore +it also requires manually defining a route for this purpose. This is achieved by +called the method `Zend\Feed\PubSubHubbub\Subscriber\Callback::setSubscriptionKey()` +with the parameter being the key value available from the router. The example +below demonstrates this using a zend-mvc controller. + +```php +use Zend\Feed\PubSubHubbub\Model\Subscription; +use Zend\Feed\PubSubHubbub\Subscriber\Callback; +use Zend\Mvc\Controller\AbstractActionController; + +class CallbackController extends AbstractActionController +{ + + public function indexAction() + { + $storage = new Subscription(); + $callback = new Callback(); + $callback->setStorage($storage); + + /* + * Inject subscription key parsing from URL path using + * a parameter from the router. + */ + $subscriptionKey = $this->params()->fromRoute('subkey'); + $callback->setSubscriptionKey($subscriptionKey); + $callback->handle(); + $callback->sendResponse(); + + /* + * Check if the callback resulting in the receipt of a feed update. + * Otherwise it was either a (un)sub verification request or invalid + * request. Typically we need do nothing other than add feed update + * handling; the rest is handled internally by the class. + */ + if ($callback->hasFeedUpdate()) { + $feedString = $callback->getFeedUpdate(); + /* + * Process the feed update asynchronously to avoid a Hub timeout. + */ + } + } +} +``` + +The example below illustrates adding a route mapping the path segment to a route +parameter, using zend-mvc: + +```php +use Zend\Mvc\Router\Http\Segment as SegmentRoute;; + +// Route defininition for enabling appending of a PuSH Subscription's lookup key +$route = SegmentRoute::factory([ + 'route' => '/callback/:subkey', + 'constraints' => [ + 'subkey' => '[a-z0-9]+', + ], + 'defaults' => [ + 'controller' => 'application-index', + 'action' => 'index', + ] +]); +``` diff --git a/vendor/zendframework/zend-feed/doc/book/reader.md b/vendor/zendframework/zend-feed/doc/book/reader.md new file mode 100644 index 00000000..ec1038ba --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/reader.md @@ -0,0 +1,825 @@ +# Zend\\Feed\\Reader + +`Zend\Feed\Reader` is a component used to consume RSS and Atom feeds of +any version, including RDF/RSS 1.0, RSS 2.0, Atom 0.3, and Atom 1.0. The API for +retrieving feed data is deliberately simple since `Zend\Feed\Reader` is capable +of searching any feed of any type for the information requested through the API. +If the typical elements containing this information are not present, it will +adapt and fall back on a variety of alternative elements instead. This ability +to choose from alternatives removes the need for users to create their own +abstraction layer on top of the component to make it useful or have any in-depth +knowledge of the underlying standards, current alternatives, and namespaced +extensions. + +Internally, the `Zend\Feed\Reader\Reader` class works almost entirely on the +basis of making XPath queries against the feed XML's Document Object Model. This +singular approach to parsing is consistent, and the component offers a plugin +system to add to the Feed and Entry APIs by writing extensions on a similar +basis. + +Performance is assisted in three ways. First of all, `Zend\Feed\Reader\Reader` +supports caching using [zend-cache](https://github.com/zendframework/zend-cache) +to maintain a copy of the original feed XML. This allows you to skip network +requests for a feed URI if the cache is valid. Second, the Feed and Entry APIs +are backed by an internal cache (non-persistent) so repeat API calls for the +same feed will avoid additional DOM or XPath use. Thirdly, importing feeds from +a URI can take advantage of HTTP Conditional `GET` requests which allow servers +to issue an empty 304 response when the requested feed has not changed since the +last time you requested it. In the final case, an zend-cache storage instance +will hold the last received feed along with the ETag and Last-Modified header +values sent in the HTTP response. + +`Zend\Feed\Reader\Reader` is not capable of constructing feeds, and delegates +this responsibility to `Zend\Feed\Writer\Writer`. + +## Importing Feeds + +Feeds can be imported from a string, file or a URI. Importing from a URI can +additionally utilise an HTTP Conditional `GET` request. If importing fails, an +exception will be raised. The end result will be an object of type +`Zend\Feed\Reader\Feed\AbstractFeed`, the core implementations of which are +`Zend\Feed\Reader\Feed\Rss` and `Zend\Feed\Reader\Feed\Atom`. Both objects +support multiple (all existing) versions of these broad feed types. + +In the following example, we import an RDF/RSS 1.0 feed and extract some basic +information that can be saved to a database or elsewhere. + +```php +$feed = Zend\Feed\Reader\Reader::import('http://www.planet-php.net/rdf/'); +$data = [ + 'title' => $feed->getTitle(), + 'link' => $feed->getLink(), + 'dateModified' => $feed->getDateModified(), + 'description' => $feed->getDescription(), + 'language' => $feed->getLanguage(), + 'entries' => [], +]; + +foreach ($feed as $entry) { + $edata = [ + 'title' => $entry->getTitle(), + 'description' => $entry->getDescription(), + 'dateModified' => $entry->getDateModified(), + 'authors' => $entry->getAuthors(), + 'link' => $entry->getLink(), + 'content' => $entry->getContent(), + ]; + $data['entries'][] = $edata; +} +``` + +> ## Importing requires an HTTP client +> +> To import a feed, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). + +The example above demonstrates `Zend\Feed\Reader\Reader`'s API, and it also +demonstrates some of its internal operation. In reality, the RDF feed selected +does not have any native date or author elements; however it does utilise the +Dublin Core 1.1 module which offers namespaced creator and date elements. +`Zend\Feed\Reader\Reader` falls back on these and similar options if no relevant +native elements exist. If it absolutely cannot find an alternative it will +return `NULL`, indicating the information could not be found in the feed. You +should note that classes implementing `Zend\Feed\Reader\Feed\AbstractFeed` also +implement the SPL `Iterator` and `Countable` interfaces. + +Feeds can also be imported from strings or files. + +```php +// from a URI +$feed = Zend\Feed\Reader\Reader::import('http://www.planet-php.net/rdf/'); + +// from a String +$feed = Zend\Feed\Reader\Reader::importString($feedXmlString); + +// from a file +$feed = Zend\Feed\Reader\Reader::importFile('./feed.xml'); +``` + +## Retrieving Underlying Feed and Entry Sources + +`Zend\Feed\Reader\Reader` does its best not to stick you in a narrow confine. If +you need to work on a feed outside of `Zend\Feed\Reader\Reader`, you can extract +the base DOMDocument or DOMElement objects from any class, or even an XML +string containing these. Also provided are methods to extract the current +DOMXPath object (with all core and extension namespaces registered) and the +correct prefix used in all XPath queries for the current feed or entry. The +basic methods to use (on any object) are `saveXml()`, `getDomDocument()`, +`getElement()`, `getXpath()` and `getXpathPrefix()`. These will let you break +free of `Zend\Feed\Reader` and do whatever else you want. + +- `saveXml()` returns an XML string containing only the element representing the + current object. +- `getDomDocument()` returns the DOMDocument object representing the entire feed + (even if called from an entry object). +- `getElement()` returns the DOMElement of the current object (i.e. the feed or + current entry). +- `getXpath()` returns the DOMXPath object for the current feed (even if called + from an entry object) with the namespaces of the current feed type and all + loaded extensions pre-registered. +- `getXpathPrefix()` returns the query prefix for the current object (i.e. the + feed or current entry) which includes the correct XPath query path for that + specific feed or entry. + +Let's look at an example where a feed might include an RSS extension not +supported by `Zend\Feed\Reader\Reader` out of the box. Notably, you could write +and register an extension (covered later) to do this, but that's not always +warranted for a quick check. You must register any new namespaces on the +DOMXPath object before use unless they are registered by `Zend\Feed\Reader` or +an extension beforehand. + +```php +$feed = Zend\Feed\Reader\Reader::import('http://www.planet-php.net/rdf/'); +$xpathPrefix = $feed->getXpathPrefix(); +$xpath = $feed->getXpath(); +$xpath->registerNamespace('admin', 'http://webns.net/mvcb/'); +$reportErrorsTo = $xpath->evaluate( + 'string(' . $xpathPrefix . '/admin:errorReportsTo)' +); +``` + +> ### Do not register duplicate namespaces +> +> If you register an already registered namespace with a different prefix name +> to that used internally by `Zend\Feed\Reader\Reader`, it will break the +> internal operation of this component. + +## Cache Support and Intelligent Requests + +### Adding Cache Support to Zend\\Feed\\Reader\\Reader + +`Zend\Feed\Reader\Reader` supports using a +[zend-cache](https://github.com/zendframework/zend-cache) storage instance to +cache feeds (as XML) to avoid unnecessary network requests. To add a cache, +create and configure your cache instance, and then tell +`Zend\Feed\Reader\Reader` to use it. The cache key used is +"`Zend\Feed\Reader\\`" followed by the MD5 hash of the feed's URI. + +```php +$cache = Zend\Cache\StorageFactory::adapterFactory('Memory'); +Zend\Feed\Reader\Reader::setCache($cache); +``` + +### HTTP Conditional GET Support + +The big question often asked when importing a feed frequently is if it has even +changed. With a cache enabled, you can add HTTP Conditional `GET` support to +your arsenal to answer that question. + +Using this method, you can request feeds from URIs and include their last known +ETag and Last-Modified response header values with the request (using the +If-None-Match and If-Modified-Since headers). If the feed on the server remains +unchanged, you should receive a 304 response which tells +`Zend\Feed\Reader\Reader` to use the cached version. If a full feed is sent in a +response with a status code of 200, this means the feed has changed and +`Zend\Feed\Reader\Reader` will parse the new version and save it to the cache. +It will also cache the new ETag and Last-Modified header values for future use. + +> #### Conditional GET requires a HeaderAwareClientInterface +> +> Conditional GET support only works for `Zend\Feed\Reader\Http\HeaderAwareClientInterface` +> client implementations, as it requires the ability to send HTTP headers. + +These "conditional" requests are not guaranteed to be supported by the server +you request a *URI* of, but can be attempted regardless. Most common feed +sources like blogs should however have this supported. To enable conditional +requests, you will need to provide a cache to `Zend\Feed\Reader\Reader`. + +```php +$cache = Zend\Cache\StorageFactory::adapterFactory('Memory'); + +Zend\Feed\Reader\Reader::setCache($cache); +Zend\Feed\Reader\Reader::useHttpConditionalGet(); + +$feed = Zend\Feed\Reader\Reader::import('http://www.planet-php.net/rdf/'); +``` + +In the example above, with HTTP Conditional `GET` requests enabled, the response +header values for ETag and Last-Modified will be cached along with the feed. For +the the cache's lifetime, feeds will only be updated on the cache if a non-304 +response is received containing a valid RSS or Atom XML document. + +If you intend on managing request headers from outside +`Zend\Feed\Reader\Reader`, you can set the relevant If-None-Matches and +If-Modified-Since request headers via the URI import method. + +```php +$lastEtagReceived = '5e6cefe7df5a7e95c8b1ba1a2ccaff3d'; +$lastModifiedDateReceived = 'Wed, 08 Jul 2009 13:37:22 GMT'; +$feed = Zend\Feed\Reader\Reader::import( + $uri, $lastEtagReceived, $lastModifiedDateReceived +); +``` + +## Locating Feed URIs from Websites + +These days, many websites are aware that the location of their XML feeds is not +always obvious. A small RDF, RSS, or Atom graphic helps when the user is reading +the page, but what about when a machine visits trying to identify where your +feeds are located? To assist in this, websites may point to their feeds using +`` tags in the `` section of their HTML. To take advantage +of this, you can use `Zend\Feed\Reader\Reader` to locate these feeds using the +static `findFeedLinks()` method. + +This method calls any URI and searches for the location of RSS, RDF, and Atom +feeds assuming, the website's HTML contains the relevant links. It then returns +a value object where you can check for the existence of a RSS, RDF or Atom feed +URI. + +The returned object is an `ArrayObject` subclass called +`Zend\Feed\Reader\FeedSet`, so you can cast it to an array or iterate over it to +access all the detected links. However, as a simple shortcut, you can just grab +the first RSS, RDF, or Atom link using its public properties as in the example +below. Otherwise, each element of the `ArrayObject` is a simple array with the +keys `type` and `uri` where the type is one of "rdf", "rss", or "atom". + +```php +$links = Zend\Feed\Reader\Reader::findFeedLinks('http://www.planet-php.net'); + +if (isset($links->rdf)) { + echo $links->rdf, "\n"; // http://www.planet-php.org/rdf/ +} +if (isset($links->rss)) { + echo $links->rss, "\n"; // http://www.planet-php.org/rss/ +} +if (isset($links->atom)) { + echo $links->atom, "\n"; // http://www.planet-php.org/atom/ +} +``` + +Based on these links, you can then import from whichever source you wish in the usual manner. + +> ### Finding feed links requires an HTTP client +> +> To find feed links, you will need to have an [HTTP client](zend.feed.http-clients) +> available. +> +> If you are not using zend-http, you will need to inject `Reader` with the HTTP +> client. See the [section on providing a client to Reader](http-clients.md#providing-a-client-to-reader). + +This quick method only gives you one link for each feed type, but websites may +indicate many links of any type. Perhaps it's a news site with a RSS feed for +each news category. You can iterate over all links using the ArrayObject's +iterator. + +```php +$links = Zend\Feed\Reader::findFeedLinks('http://www.planet-php.net'); + +foreach ($links as $link) { + echo $link['href'], "\n"; +} +``` + +## Attribute Collections + +In an attempt to simplify return types, return types from the various feed and +entry level methods may include an object of type +`Zend\Feed\Reader\Collection\AbstractCollection`. Despite the special class name +which I'll explain below, this is just a simple subclass of SPL's `ArrayObject`. + +The main purpose here is to allow the presentation of as much data as possible +from the requested elements, while still allowing access to the most relevant +data as a simple array. This also enforces a standard approach to returning such +data which previously may have wandered between arrays and objects. + +The new class type acts identically to `ArrayObject` with the sole addition +being a new method `getValues()` which returns a simple flat array containing +the most relevant information. + +A simple example of this is `Zend\Feed\Reader\Reader\FeedInterface::getCategories()`. +When used with any RSS or Atom feed, this method will return category data as a +container object called `Zend\Feed\Reader\Collection\Category`. The container +object will contain, per category, three fields of data: term, scheme, and label. +The "term" is the basic category name, often machine readable (i.e. plays nice +with URIs). The scheme represents a categorisation scheme (usually a URI +identifier) also known as a "domain" in RSS 2.0. The "label" is a human readable +category name which supports HTML entities. In RSS 2.0, there is no label +attribute so it is always set to the same value as the term for convenience. + +To access category labels by themselves in a simple value array, you might +commit to something like: + +```php +$feed = Zend\Feed\Reader\Reader::import('http://www.example.com/atom.xml'); +$categories = $feed->getCategories(); +$labels = []; +foreach ($categories as $cat) { + $labels[] = $cat['label'] +} +``` + +It's a contrived example, but the point is that the labels are tied up with +other information. + +However, the container class allows you to access the "most relevant" data as a +simple array using the `getValues()` method. The concept of "most relevant" is +obviously a judgement call. For categories it means the category labels (not the +terms or schemes) while for authors it would be the authors' names (not their +email addresses or URIs). The simple array is flat (just values) and passed +through `array_unique()` to remove duplication. + +```php +$feed = Zend\Feed\Reader\Reader::import('http://www.example.com/atom.xml'); +$categories = $feed->getCategories(); +$labels = $categories->getValues(); +``` + +The above example shows how to extract only labels and nothing else thus giving +simple access to the category labels without any additional work to extract that +data by itself. + +## Retrieving Feed Information + +Retrieving information from a feed (we'll cover entries and items in the next +section though they follow identical principals) uses a clearly defined API +which is exactly the same regardless of whether the feed in question is RSS, +RDF, or Atom. The same goes for sub-versions of these standards and we've tested +every single RSS and Atom version. While the underlying feed XML can differ +substantially in terms of the tags and elements they present, they nonetheless +are all trying to convey similar information and to reflect this all the +differences and wrangling over alternative tags are handled internally by +`Zend\Feed\Reader\Reader` presenting you with an identical interface for each. +Ideally, you should not have to care whether a feed is RSS or Atom so long as +you can extract the information you want. + +> ### RSS feeds vary widely +> +> While determining common ground between feed types is itself complex, it +> should be noted that *RSS* in particular is a constantly disputed +> "specification". This has its roots in the original RSS 2.0 document, which +> contains ambiguities and does not detail the correct treatment of all +> elements. As a result, this component rigorously applies the RSS 2.0.11 +> Specification published by the RSS Advisory Board and its accompanying RSS +> Best Practices Profile. No other interpretation of RSS +> 2.0 will be supported, though exceptions may be allowed where it does not +> directly prevent the application of the two documents mentioned above. + +Of course, we don't live in an ideal world, so there may be times the API just +does not cover what you're looking for. To assist you, `Zend\Feed\Reader\Reader` +offers a plugin system which allows you to write extensions to expand the core +API and cover any additional data you are trying to extract from feeds. If +writing another extension is too much trouble, you can simply grab the +underlying DOM or XPath objects and do it by hand in your application. Of +course, we really do encourage writing an extension simply to make it more +portable and reusable, and useful extensions may be proposed to the component +for formal addition. + +Below is a summary of the Core API for feeds. You should note it comprises not +only the basic RSS and Atom standards, but also accounts for a number of +included extensions bundled with `Zend\Feed\Reader\Reader`. The naming of these +extension sourced methods remain fairly generic; all Extension methods operate +at the same level as the Core API though we do allow you to retrieve any +specific extension object separately if required. + +### Feed Level API Methods + +Method | Description +------ | ----------- +`getId()` | Returns a unique ID associated with this feed +`getTitle()` | Returns the title of the feed +`getDescription()` | Returns the text description of the feed. +`getLink()` | Returns a URI to the HTML website containing the same or similar information as this feed (i.e. if the feed is from a blog, it should provide the blog's URI where the HTML version of the entries can be read). +`getFeedLink()` | Returns the URI of this feed, which may be the same as the URI used to import the feed. There are important cases where the feed link may differ because the source URI is being updated and is intended to be removed in the future. +`getAuthors()` | Returns an object of type `Zend\Feed\Reader\Collection\Author` which is an `ArrayObject` whose elements are each simple arrays containing any combination of the keys "name", "email" and "uri". Where irrelevant to the source data, some of these keys may be omitted. +`getAuthor(integer $index = 0)` | Returns either the first author known, or with the optional $index parameter any specific index on the array of authors as described above (returning `NULL` if an invalid index). +`getDateCreated()` | Returns the date on which this feed was created. Generally only applicable to Atom, where it represents the date the resource described by an Atom 1.0 document was created. The returned date will be a `DateTime` object. +`getDateModified()` | Returns the date on which this feed was last modified. The returned date will be a `DateTime` object. +`getLastBuildDate()` | Returns the date on which this feed was last built. The returned date will be a `DateTime` object. This is only supported by RSS; Atom feeds will always return `NULL`. +`getLanguage()` | Returns the language of the feed (if defined) or simply the language noted in the XML document. +`getGenerator()` | Returns the generator of the feed, e.g. the software which generated it. This may differ between RSS and Atom since Atom defines a different notation. +`getCopyright()` | Returns any copyright notice associated with the feed. +`getHubs()` | Returns an array of all Hub Server URI endpoints which are advertised by the feed for use with the Pubsubhubbub Protocol, allowing subscriptions to the feed for real-time updates. +`getCategories()` | Returns a `Zend\Feed\Reader\Collection\Category` object containing the details of any categories associated with the overall feed. The supported fields include "term" (the machine readable category name), "scheme" (the categorisation scheme and domain for this category), and "label" (a HTML decoded human readable category name). Where any of the three fields are absent from the field, they are either set to the closest available alternative or, in the case of "scheme", set to `NULL`. +`getImage()` | Returns an array containing data relating to any feed image or logo, or `NULL` if no image found. The resulting array may contain the following keys: uri, link, title, description, height, and width. Atom logos only contain a URI so the remaining metadata is drawn from RSS feeds only. + +Given the variety of feeds in the wild, some of these methods will undoubtedly +return `NULL` indicating the relevant information couldn't be located. Where +possible, `Zend\Feed\Reader\Reader` will fall back on alternative elements +during its search. For example, searching an RSS feed for a modification date is +more complicated than it looks. RSS 2.0 feeds should include a `` +tag and/or a `` element. But what if it doesn't? Maybe this is an RSS +1.0 feed? Perhaps it instead has an `` element with identical +information (Atom may be used to supplement RSS syntax)? Failing that, we +could simply look at the entries, pick the most recent, and use its `` +element. Assuming it exists, that is. Many feeds also use Dublin Core 1.0 or 1.1 +`` elements for feeds and entries. Or we could find Atom lurking again. + +The point is, `Zend\Feed\Reader\Reader` was designed to know this. When you ask +for the modification date (or anything else), it will run off and search for all +these alternatives until it either gives up and returns `NULL`, or finds an +alternative that should have the right answer. + +In addition to the above methods, all feed objects implement methods for +retrieving the DOM and XPath objects for the current feeds as described +earlier. Feed objects also implement the SPL Iterator and Countable +interfaces. The extended API is summarised below. + +### Extended Feed API Methods + +Method | Description +------ | ----------- +`getDomDocument()` | Returns the parent DOMDocument object for the entire source XML document. +`getElement()` | Returns the current feed level DOMElement object. +`saveXml()` | Returns a string containing an XML document of the entire feed element (this is not the original document, but a rebuilt version). +`getXpath()` | Returns the DOMXPath object used internally to run queries on the DOMDocument object (this includes core and extension namespaces pre-registered). +`getXpathPrefix()` | Returns the valid DOM path prefix prepended to all XPath queries matching the feed being queried. +`getEncoding()` | Returns the encoding of the source XML document (note: this cannot account for errors such as the server sending documents in a different encoding). Where not defined, the default UTF-8 encoding of Unicode is applied. +`count()` | Returns a count of the entries or items this feed contains (implements SPL `Countable` interface) +`current()` | Returns either the current entry (using the current index from `key()`). +`key()` | Returns the current entry index. +`next()` | Increments the entry index value by one. +`rewind()` | Resets the entry index to 0. +`valid()` | Checks that the current entry index is valid, i.e. it does not fall below 0 and does not exceed the number of entries existing. +`getExtensions()` | Returns an array of all extension objects loaded for the current feed (note: both feed-level and entry-level extensions exist, and only feed-level extensions are returned here). The array keys are of the form `{ExtensionName}_Feed`. +`getExtension(string $name)` | Returns an extension object for the feed registered under the provided name. This allows more fine-grained access to extensions which may otherwise be hidden within the implementation of the standard API methods. +`getType()` | Returns a static class constant (e.g. `Zend\Feed\Reader\Reader::TYPE_ATOM_03`, i.e. "Atom 0.3"), indicating exactly what kind of feed is being consumed. + +## Retrieving Entry/Item Information + +Retrieving information for specific entries or items (depending on whether you +speak Atom or RSS) is identical to feed level data. Accessing entries is +simply a matter of iterating over a feed object or using the SPL `Iterator` +interface feed objects implement, and calling the appropriate method on each. + +### Entry API Methods + +Method | Description +------ | ----------- +`getId()` | Returns a unique ID for the current entry. +`getTitle()` | Returns the title of the current entry. +`getDescription()` | Returns a description of the current entry. +`getLink()` | Returns a URI to the HTML version of the current entry. +`getPermaLink()` | Returns the permanent link to the current entry. In most cases, this is the same as using `getLink()`. +`getAuthors()` | Returns an object of type `Zend\Feed\Reader\Collection\Author`, which is an `ArrayObject` whose elements are each simple arrays containing any combination of the keys "name", "email" and "uri". Where irrelevant to the source data, some of these keys may be omitted. +`getAuthor(integer $index = 0)` | Returns either the first author known, or, with the optional `$index` parameter, any specific index on the array of Authors as described above (returning `NULL` if an invalid index). +`getDateCreated()` | Returns the date on which the current entry was created. Generally only applicable to Atom where it represents the date the resource described by an Atom 1.0 document was created. +`getDateModified()` | Returns the date on which the current entry was last modified. +`getContent()` | Returns the content of the current entry (this has any entities reversed if possible, assuming the content type is HTML). The description is returned if a separate content element does not exist. +`getEnclosure()` | Returns an array containing the value of all attributes from a multi-media `` element including as array keys: url, length, type. In accordance with the RSS Best Practices Profile of the RSS Advisory Board, no support is offers for multiple enclosures since such support forms no part of the RSS specification. +`getCommentCount()` | Returns the number of comments made on this entry at the time the feed was last generated. +`getCommentLink()` | Returns a URI pointing to the HTML page where comments can be made on this entry. +`getCommentFeedLink([string $type = ‘atom'|'rss'])` | Returns a URI pointing to a feed of the provided type containing all comments for this entry (type defaults to Atom/RSS depending on current feed type). +`getCategories()` | Returns a `Zend\Feed\Reader\Collection\Category` object containing the details of any categories associated with the entry. The supported fields include "term" (the machine readable category name), "scheme" (the categorisation scheme and domain for this category), and "label" (an HTML-decoded human readable category name). Where any of the three fields are absent from the field, they are either set to the closest available alternative or, in the case of "scheme", set to `NULL`. + +The extended API for entries is identical to that for feeds with the exception +of the `Iterator` methods, which are not needed here. + +> ### Modified vs Created dates +> +> There is often confusion over the concepts of *modified* and *created* dates. +> In Atom, these are two clearly defined concepts (so knock yourself out) but in +> RSS they are vague. RSS 2.0 defines a single `` element which +> typically refers to the date this entry was published, i.e. a creation date of +> sorts. This is not always the case, and it may change with updates or not. As a +> result, if you really want to check whether an entry has changed, don't rely on +> the results of `getDateModified()`. Instead, consider tracking the MD5 hash of +> three other elements concatenated, e.g. using `getTitle()`, `getDescription()`, +> and `getContent()`. If the entry was truly updated, this hash computation will +> give a different result than previously saved hashes for the same entry. This +> is obviously content oriented, and will not assist in detecting changes to +> other relevant elements. Atom feeds should not require such steps. + +> Further muddying the waters, dates in feeds may follow different standards. +> Atom and Dublin Core dates should follow ISO 8601, and RSS dates should +> follow RFC 822 or RFC 2822 (which is also common). Date methods will throw an +> exception if `DateTime` cannot load the date string using one of the above +> standards, or the PHP recognised possibilities for RSS dates. + +> ### Validation +> +> The values returned from these methods are not validated. This means users +> must perform validation on all retrieved data including the filtering of any +> HTML such as from `getContent()` before it is output from your application. +> Remember that most feeds come from external sources, and therefore the default +> assumption should be that they cannot be trusted. + +### Extended Entry Level API Methods + +Method | Description +------ | ----------- +`getDomDocument()` | Returns the parent DOMDocument object for the entire feed (not just the current entry). +`getElement()` | Returns the current entry level DOMElement object. +`getXpath()` | Returns the DOMXPath object used internally to run queries on the DOMDocument object (this includes core and extension namespaces pre-registered). +`getXpathPrefix()` | Returns the valid DOM path prefix prepended to all XPath queries matching the entry being queried. +`getEncoding()` | Returns the encoding of the source XML document (note: this cannot account for errors such as the server sending documents in a different encoding). The default encoding applied in the absence of any other is the UTF-8 encoding of Unicode. +`getExtensions()` | Returns an array of all extension objects loaded for the current entry (note: both feed-level and entry-level extensions exist, and only entry-level extensions are returned here). The array keys are in the form `{ExtensionName}Entry`. +`getExtension(string $name)` | Returns an extension object for the entry registered under the provided name. This allows more fine-grained access to extensions which may otherwise be hidden within the implementation of the standard API methods. +`getType()` | Returns a static class constant (e.g. `Zend\Feed\Reader\Reader::TYPE_ATOM_03`, i.e. "Atom 0.3") indicating exactly what kind of feed is being consumed. + +## Extending Feed and Entry APIs + +Extending `Zend\Feed\Reader\Reader` allows you to add methods at both the feed +and entry level which cover the retrieval of information not already supported +by `Zend\Feed\Reader\Reader`. Given the number of RSS and Atom extensions that +exist, this is a good thing, since `Zend\Feed\Reader\Reader` couldn't possibly +add everything. + +There are two types of extensions possible, those which retrieve information +from elements which are immediate children of the root element (e.g. +`` for RSS or `` for Atom), and those who retrieve information +from child elements of an entry (e.g. `` for RSS or `` for Atom). +On the filesystem, these are grouped as classes within a namespace based on the +extension standard's name. For example, internally we have +`Zend\Feed\Reader\Extension\DublinCore\Feed` and +`Zend\Feed\Reader\Extension\DublinCore\Entry` classes which are two extensions +implementing Dublin Core 1.0 and 1.1 support. + +Extensions are loaded into `Zend\Feed\Reader\Reader` using an "extension +manager". Extension managers must implement `Zend\Feed\Reader\ExtensionManagerInterface`. +Three implementations exist: + +- `Zend\Feed\Reader\StandaloneExtensionManager` is a hard-coded implementation + seeded with all feed and entry implementations. You can extend it to add + extensions, though it's likely easier to copy and paste it, adding your + changes. +- `Zend\Feed\Reader\ExtensionPluginManager` is a `Zend\ServiceManager\AbstractPluginManager` + implementation, `Zend\Feed\Reader\ExtensionManager`; as such, you can extend + it to add more extensions, use a `Zend\ServiceManager\ConfigInterface` instance + to inject it with more extensions, or use its public API for adding services + (e.g., `setService()`, `setFactory()`, etc.). This implementation *does not* + implement `ExtensionManagerInterface`, and must be used with `ExtensionManager`. +- `Zend\Feed\Reader\ExtensionManager` exists for legacy purposes; prior to 2.3, + this was an `AbstractPluginManager` implementation, and the only provided + extension manager. It now implements `ExtensionManagerInterface`, and acts as + a decorator for `ExtensionPluginManager`. + +By default, `Zend\Feed\Reader\Reader` composes a `StandaloneExtensionManager`. You +can inject an alternate implementation using `Reader::setExtensionManager()`: + +```php +$extensions = new Zend\Feed\Reader\ExtensionPluginManager(); +Zend\Feed\Reader\Reader::setExtensionManager( + new ExtensionManager($extensions) +); +``` + +The shipped implementations all provide the default extensions (so-called +"Core Extensions") used internally by `Zend\Feed\Reader\Reader`. These +include: + +Extension | Description +--------- | ----------- +DublinCore (Feed and Entry) | Implements support for Dublin Core Metadata Element Set 1.0 and 1.1. +Content (Entry only) | Implements support for Content 1.0. +Atom (Feed and Entry) | Implements support for Atom 0.3 and Atom 1.0. +Slash | Implements support for the Slash RSS 1.0 module. +WellFormedWeb | Implements support for the Well Formed Web CommentAPI 1.0. +Thread | Implements support for Atom Threading Extensions as described in RFC 4685. +Podcast | Implements support for the Podcast 1.0 DTD from Apple. + +The core extensions are somewhat special since they are extremely common and +multi-faceted. For example, we have a core extension for Atom. Atom is +implemented as an extension (not just a base class) because it doubles as a +valid RSS module; you can insert Atom elements into RSS feeds. I've even seen +RDF feeds which use a lot of Atom in place of more common extensions like +Dublin Core. + +The following is a list of non-Core extensions that are offered, but not registered +by default. If you want to use them, you'll need to +tell `Zend\Feed\Reader\Reader` to load them in advance of importing a feed. +Additional non-Core extensions will be included in future iterations of the +component. + +Extension | Description +--------- | ----------- +Syndication | Implements Syndication 1.0 support for RSS feeds. +CreativeCommons | An RSS module that adds an element at the `` or `` level that specifies which Creative Commons license applies. + +`Zend\Feed\Reader\Reader` requires you to explicitly register non-Core +extensions in order to expose their API to feed and entry objects. Below, we +register the optional Syndication extension, and discover that it can be +directly called from the entry API without any effort. (Note that +extension names are case sensitive and use camelCasing for multiple terms.) + +```php +use Zend\Feed\Reader\Reader; + +Reader::registerExtension('Syndication'); +$feed = Reader::import('http://rss.slashdot.org/Slashdot/slashdot'); +$updatePeriod = $feed->getUpdatePeriod(); +``` + +In the simple example above, we checked how frequently a feed is being updated +using the `getUpdatePeriod()` method. Since it's not part of +`Zend\Feed\Reader\Reader`'s core API, it could only be a method supported by +the newly registered Syndication extension. + +As you can also notice, methods provided by extensions are accessible from the +main API using method overloading. As an alternative, you can also directly +access any extension object for a similar result as seen below. + +```php +use Zend\Feed\Reader\Reader; + +Reader::registerExtension('Syndication'); +$feed = Reader::import('http://rss.slashdot.org/Slashdot/slashdot'); +$syndication = $feed->getExtension('Syndication'); +$updatePeriod = $syndication->getUpdatePeriod(); +``` + +### Writing Zend\\Feed\\Reader Extensions + +Inevitably, there will be times when the `Zend\Feed\Reader` API is just +not capable of getting something you need from a feed or entry. You can use the +underlying source objects, like DOMDocument, to get these by hand; however, there +is a more reusable method available: you can write extensions supporting these new +queries. + +As an example, let's take the case of a purely fictitious corporation named +Jungle Books. Jungle Books have been publishing a lot of reviews on books they +sell (from external sources and customers), which are distributed as an RSS 2.0 +feed. Their marketing department realises that web applications using this feed +cannot currently figure out exactly what book is being reviewed. To make life +easier for everyone, they determine that the geek department needs to extend +RSS 2.0 to include a new element per entry supplying the ISBN-10 or ISBN-13 +number of the publication the entry concerns. They define the new `` +element quite simply with a standard name and namespace URI: + +- Name: JungleBooks 1.0 +- Namespace URI: http://example.com/junglebooks/rss/module/1.0/ + +A snippet of RSS containing this extension in practice could be something +similar to: + +```xml + + + + Jungle Books Customer Reviews + http://example.com/junglebooks + Many book reviews! + Fri, 26 Jun 2009 19:15:10 GMT + + http://example.com/junglebooks/book/938 + + + Review Of Flatland: A Romance of Many Dimensions + http://example.com/junglebooks/review/987 + Confused Physics Student + + A romantic square?! + + Thu, 25 Jun 2009 20:03:28 -0700 + 048627263X + + + +``` + +Implementing this new ISBN element as a simple entry level extension would +require the following class (using your own namespace). + +```php +namespace My\FeedReader\Extension\JungleBooks; + +use Zend\Feed\Reader\Extension\AbstractEntry; + +class Entry extends AbstractEntry +{ + public function getIsbn() + { + if (isset($this->data['isbn'])) { + return $this->data['isbn']; + } + + $isbn = $this->xpath->evaluate( + 'string(' . $this->getXpathPrefix() . '/jungle:isbn)' + ); + + if (! $isbn) { + $isbn = null; + } + + $this->data['isbn'] = $isbn; + return $this->data['isbn']; + } + + protected function registerNamespaces() + { + $this->xpath->registerNamespace( + 'jungle', + 'http://example.com/junglebooks/rss/module/1.0/' + ); + } +} +``` + +This extension creates a new method `getIsbn()`, which runs an XPath query on +the current entry to extract the ISBN number enclosed by the `` +element. It can optionally store this to the internal non-persistent cache (no +need to keep querying the DOM if it's called again on the same entry). The +value is returned to the caller. At the end we have a protected method (it's +abstract, making it required by implementations) which registers the Jungle +Books namespace for their custom RSS module. While we call this an RSS module, +there's nothing to prevent the same element being used in Atom feeds; all +extensions which use the prefix provided by `getXpathPrefix()` are actually +neutral and work on RSS or Atom feeds with no extra code. + +Since this extension is stored outside of zend-feed, you'll need to ensure your +application can autoload it. Once that's in place, you will also need to ensure +your extension manager knows about it, and then register the extension with +`Zend\Feed\Reader\Reader`. + +The following example uses `Zend\Feed\Reader\ExtensionPluginManager` to manage +extensions, as it provides the ability to register new extensions without +requiring extension of the plugin manager itself. To use it, first intall +zend-servicemanager: + +```bash +$ composer require zendframework/zend-servicemanager +``` + +From there: + +```php +use My\FeedReader\Extension\JungleBooks; +use Zend\Feed\Reader\ExtensionManager; +use Zend\Feed\Reader\ExtensionPluginManager; +use Zend\Feed\Reader\Reader; + +$extensions = new ExtensionPluginManager(); +$extensions->setInvokableClass('JungleBooksEntry', JungleBooks\Entry::class); +Reader::setExtensionManager(new ExtensionManager($extensions)); +Reader::registerExtension('JungleBooks'); + +$feed = Reader::import('http://example.com/junglebooks/rss'); + +// ISBN for whatever book the first entry in the feed was concerned with +$firstIsbn = $feed->current()->getIsbn(); +``` + +Writing a feed extension is not much different. The example feed from earlier +included an unmentioned `` element which Jungle Books have +added to their standard to include a link to the day's most popular book (in +terms of visitor traffic). Here's an extension which adds a +`getDaysPopularBookLink()` method to the feel level API. + +```php +namespace My\FeedReader\Extension\JungleBooks; + +use Zend\Feed\Reader\Extension\AbstractFeed; + +class Feed extends AbstractFeed +{ + public function getDaysPopularBookLink() + { + if (isset($this->data['dayPopular'])) { + return $this->data['dayPopular']; + } + + $dayPopular = $this->xpath->evaluate( + 'string(' . $this->getXpathPrefix() . '/jungle:dayPopular)' + ); + + if (!$dayPopular) { + $dayPopular = null; + } + + $this->data['dayPopular'] = $dayPopular; + return $this->data['dayPopular']; + } + + protected function registerNamespaces() + { + $this->xpath->registerNamespace( + 'jungle', + 'http://example.com/junglebooks/rss/module/1.0/' + ); + } +} +``` + +Let's add to the previous example; we'll register the new class with the +extension manager, and then demonstrate using the newly exposed method: + +```php +use My\FeedReader\Extension\JungleBooks; +use Zend\Feed\Reader\ExtensionManager; +use Zend\Feed\Reader\ExtensionPluginManager; +use Zend\Feed\Reader\Reader; + +$extensions = new ExtensionPluginManager(); +$extensions->setInvokableClass('JungleBooksEntry', JungleBooks\Entry::class); +$extensions->setInvokableClass('JungleBooksFeed', JungleBooks\Feed::class); +Reader::setExtensionManager(new ExtensionManager($extensions)); +Reader::registerExtension('JungleBooks'); + +$feed = Reader::import('http://example.com/junglebooks/rss'); + +// URI to the information page of the day's most popular book with visitors +$daysPopularBookLink = $feed->getDaysPopularBookLink(); +``` + +Going through these examples, you'll note that while we need to register the +feed and entry classes separately with the plugin manager, we don't register +them separately when registering the extension with the `Reader`. Extensions +within the same standard may or may not include both a feed and entry class, so +`Zend\Feed\Reader\Reader` only requires you to register the overall parent name, +e.g. JungleBooks, DublinCore, Slash. Internally, it can check at what level +extensions exist and load them up if found. In our case, we have a complete +extension now, spanning the classes `JungleBooks\Feed` and `JungleBooks\Entry`. diff --git a/vendor/zendframework/zend-feed/doc/book/security.md b/vendor/zendframework/zend-feed/doc/book/security.md new file mode 100644 index 00000000..bc6ccd2c --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/security.md @@ -0,0 +1,161 @@ +# Zend\\Feed\\Reader and Security + +As with any data coming from a source that is beyond the developer's control, +special attention needs to be given to securing, validating and filtering that +data. Similar to data input to our application by users, data coming from RSS +and Atom feeds should also be considered unsafe and potentially dangerous, as it +allows the delivery of HTML and [xHTML](http://tools.ietf.org/html/rfc4287#section-8.1). +Because data validation and filtration is out of `Zend\Feed`'s scope, this task +is left for implementation by the developer, by using libraries such as +zend-escaper for escaping and [HTMLPurifier](http://www.htmlpurifier.org/) for +validating and filtering feed data. + +Escaping and filtering of potentially insecure data is highly recommended before +outputting it anywhere in our application or before storing that data in some +storage engine (be it a simple file or a database.). + +## Filtering data using HTMLPurifier + +Currently, the best available library for filtering and validating (x)HTML data +in PHP is [HTMLPurifier](http://www.htmlpurifier.org/), and, as such, is the +recommended tool for this task. HTMLPurifier works by filtering out all (x)HTML +from the data, except for the tags and attributes specifically allowed in a +whitelist, and by checking and fixing nesting of tags, ensuring +standards-compliant output. + +The following examples will show a basic usage of HTMLPurifier, but developers +are urged to go through and read [HTMLPurifier's documentation](http://www.htmlpurifier.org/docs). + +```php +// Setting HTMLPurifier's options +$options = [ + // Allow only paragraph tags + // and anchor tags wit the href attribute + [ + 'HTML.Allowed', + 'p,a[href]' + ], + // Format end output with Tidy + [ + 'Output.TidyFormat', + true + ], + // Assume XHTML 1.0 Strict Doctype + [ + 'HTML.Doctype', + 'XHTML 1.0 Strict' + ], + // Disable cache, but see note after the example + [ + 'Cache.DefinitionImpl', + null + ] +]; + +// Configuring HTMLPurifier +$config = HTMLPurifier_Config::createDefault(); +foreach ($options as $option) { + $config->set($option[0], $option[1]); +} + +// Creating a HTMLPurifier with it's config +$purifier = new HTMLPurifier($config); + +// Fetch the RSS +try { + $rss = Zend\Feed\Reader\Reader::import('http://www.planet-php.net/rss/'); +} catch (Zend\Feed\Exception\Reader\RuntimeException $e) { + // feed import failed + echo "Exception caught importing feed: {$e->getMessage()}\n"; + exit; +} + +// Initialize the channel data array +// See that we're cleaning the description with HTMLPurifier +$channel = [ + 'title' => $rss->getTitle(), + 'link' => $rss->getLink(), + 'description' => $purifier->purify($rss->getDescription()), + 'items' => [], +]; + +// Loop over each channel item and store relevant data +// See that we're cleaning the descriptions with HTMLPurifier +foreach ($rss as $item) { + $channel['items'][] = [ + 'title' => $item->getTitle(), + 'link' => $item->getLink(), + 'description' => $purifier->purify($item->getDescription()), + ]; +} +``` + +> ### Tidy is required +> +> HTMLPurifier is using the PHP [Tidy extension](http://php.net/tidy) to clean +> and repair the final output. If this extension is not available, it will +> silently fail, but its availability has no impact on the library's security. + +> ### Caching +> +> For the sake of this example, the HTMLPurifier's cache is disabled, but it is +> recommended to configure caching and use its standalone include file as it can +> improve the performance of HTMLPurifier substantially. + +## Escaping data using zend-escaper + +To help prevent XSS attacks, Zend Framework provides the [zend-escaper component](https://github.com/zendframework/zend-escaper), +which complies to the current [OWASP recommendations](https://www.owasp.org/index.php/XSS_Prevention_Cheat_Sheet), +and as such, is the recommended tool for escaping HTML tags and attributes, +Javascript, CSS and URLs before outputing any potentially insecure data to the +users. + +```php +try { + $rss = Zend\Feed\Reader\Reader::import('http://www.planet-php.net/rss/'); +} catch (Zend\Feed\Exception\Reader\RuntimeException $e) { + // feed import failed + echo "Exception caught importing feed: {$e->getMessage()}\n"; + exit; +} + +// Validate all URIs +$linkValidator = new Zend\Validator\Uri; +$link = null; +if ($linkValidator->isValid($rss->getLink())) { + $link = $rss->getLink(); +} + +// Escaper used for escaping data +$escaper = new Zend\Escaper\Escaper('utf-8'); + +// Initialize the channel data array +$channel = [ + 'title' => $escaper->escapeHtml($rss->getTitle()), + 'link' => $escaper->escapeUrl($link), + 'description' => $escaper->escapeHtml($rss->getDescription()), + 'items' => [], +]; + +// Loop over each channel item and store relevant data +foreach ($rss as $item) { + $link = null; + if ($linkValidator->isValid($rss->getLink())) { + $link = $item->getLink(); + } + $channel['items'][] = [ + 'title' => $escaper->escapeHtml($item->getTitle()), + 'link' => $escaper->escapeUrl($link), + 'description' => $escaper->escapeHtml($item->getDescription()), + ]; +} +``` + +The feed data is now safe for output to HTML templates. You can, of course, skip +escaping when simply storing the data persistently, but remember to escape it on +output later! + +Of course, these are just basic examples, and cannot cover all possible +scenarios that you, as a developer, can, and most likely will, encounter. Your +responsibility is to learn what libraries and tools are at your disposal, and +when and how to use them to secure your web applications. diff --git a/vendor/zendframework/zend-feed/doc/book/writer.md b/vendor/zendframework/zend-feed/doc/book/writer.md new file mode 100644 index 00000000..749b0e69 --- /dev/null +++ b/vendor/zendframework/zend-feed/doc/book/writer.md @@ -0,0 +1,280 @@ +# Zend\\Feed\\Writer + +`Zend\Feed\Writer` is the sibling component to `Zend\Feed\Reader` responsible +for *generating* feeds. It supports the Atom 1.0 specification (RFC 4287) and +RSS 2.0 as specified by the RSS Advisory Board (RSS 2.0.11). It does not deviate +from these standards. It does, however, offer a simple extension system which +allows for any extension and module for either of these two specifications to be +implemented if they are not provided out of the box. + +In many ways, `Zend\Feed\Writer` is the inverse of `Zend\Feed\Reader`. Where +`Zend\Reader\Reader` focuses on providing an easy to use architecture fronted by +getter methods, `Zend\Feed\Writer` is fronted by similarly named setters or +mutators. This ensures the API won't pose a learning curve to anyone familiar +with `Zend\Feed\Reader`. + +As a result of this design, the rest may even be obvious. Behind the scenes, +data set on any `Zend\Feed\Writer\Writer` instance is translated at render time +onto a DOMDocument object using the necessary feed elements. For each supported +feed type there is both an Atom 1.0 and RSS 2.0 renderer. Using a DOMDocument +class rather than a templating solution has numerous advantages, the most +obvious being the ability to export the DOMDocument for additional processing +and relying on PHP DOM for correct and valid rendering. + +## Architecture + +The architecture of `Zend\Feed\Writer` is very simple. It has two core sets of +classes: data containers and renderers. + +The containers include the `Zend\Feed\Writer\Feed` and `Zend\Feed\Writer\Entry` +classes. The Entry classes can be attached to any Feed class. The sole purpose +of these containers is to collect data about the feed to generate using a simple +interface of setter methods. These methods perform some data validity testing. +For example, it will validate any passed URIs, dates, etc. These checks are not +tied to any of the feed standards definitions. The container objects also +contain methods to allow for fast rendering and export of the final feed, and +these can be reused at will. + +In addition to the main data container classes, there are two additional Atom +2.0-specific classes: `Zend\Feed\Writer\Source` and `Zend\Feed\Writer\Deleted`. +The former implements Atom 2.0 source elements which carry source feed metadata +for a specific entry within an aggregate feed (i.e. the current feed is not the +entry's original source). The latter implements the [Atom Tombstones RFC](https://tools.ietf.org/html/rfc6721), +allowing feeds to carry references to entries which have been deleted. + +While there are two main data container types, there are four renderers: two +matching container renderers per supported feed type. Each renderer accepts a +container, and, based on its content, attempts to generate valid feed markup. If +the renderer is unable to generate valid feed markup (perhaps due to the +container missing an obligatory data point), it will report this by throwing an +exception. While it is possible to ignore exceptions, this removes the default +safeguard of ensuring you have sufficient data set to render a wholly valid +feed. + +To explain this more clearly: you may construct a set of data containers for a +feed where there is a Feed container, into which has been added some Entry +containers and a Deleted container. This forms a data hierarchy resembling a +normal feed. When rendering is performed, this hierarchy has its pieces passed +to relevant renderers, and the partial feeds (all DOMDocuments) are then pieced +together to create a complete feed. In the case of Source or Deleted (Tombstone) +containers, these are rendered only for Atom 2.0 and ignored for RSS. + +Due to the system being divided between data containers and renderers, +extensions have more mandatory requirements than their equivalents in the +`Zend\Feed\Reader` subcomponent. A typical extension offering namespaced feed +and entry level elements must itself reflect the exact same architecture: i.e. +it must offer both feed and entry level data containers, and matching renderers. +There is, fortunately, no complex integration work required since all extension +classes are simply registered and automatically used by the core classes. We +cover extensions in more detail at the end of this chapter. + +## Getting Started + +To use `Zend\Feed\Writer\Writer`, you will provide it with data, and then +trigger the renderer. What follows is an example demonstrating generation of a +minimal Atom 1.0 feed. Each feed or entry uses a separate data container. + +```php +use Zend\Feed\Writer\Feed; + +/** + * Create the parent feed + */ +$feed = new Feed; +$feed->setTitle("Paddy's Blog"); +$feed->setLink('http://www.example.com'); +$feed->setFeedLink('http://www.example.com/atom', 'atom'); +$feed->addAuthor([ + 'name' => 'Paddy', + 'email' => 'paddy@example.com', + 'uri' => 'http://www.example.com', +]); +$feed->setDateModified(time()); +$feed->addHub('http://pubsubhubbub.appspot.com/'); + +/** + * Add one or more entries. Note that entries must + * be manually added once created. + */ +$entry = $feed->createEntry(); +$entry->setTitle('All Your Base Are Belong To Us'); +$entry->setLink('http://www.example.com/all-your-base-are-belong-to-us'); +$entry->addAuthor([ + 'name' => 'Paddy', + 'email' => 'paddy@example.com', + 'uri' => 'http://www.example.com', +]); +$entry->setDateModified(time()); +$entry->setDateCreated(time()); +$entry->setDescription('Exposing the difficulty of porting games to English.'); +$entry->setContent( + 'I am not writing the article. The example is long enough as is ;).' +); +$feed->addEntry($entry); + +/** + * Render the resulting feed to Atom 1.0 and assign to $out. + * You can substitute "atom" with "rss" to generate an RSS 2.0 feed. + */ +$out = $feed->export('atom'); +``` + +The output rendered should be as follows: + +```xml + + + Paddy's Blog + Writing about PC Games since 176 BC. + 2009-12-14T20:28:18+00:00 + + Zend\Feed\Writer + + + + http://www.example.com + + Paddy + paddy@example.com + http://www.example.com + + + + <![CDATA[All Your Base Are Belong To + Us]]> + + + + 2009-12-14T20:28:18+00:00 + 2009-12-14T20:28:18+00:00 + + http://www.example.com/all-your-base-are-belong-to-us + + Paddy + paddy@example.com + http://www.example.com + + + + + + +``` + +This is a perfectly valid Atom 1.0 example. It should be noted that omitting an +obligatory point of data, such as a title, will trigger an exception when +rendering as Atom 1.0. This will differ for RSS 2.0, since a title may be +omitted so long as a description is present. This gives rise to exceptions that +differ between the two standards depending on the renderer in use. By design, +`Zend\Feed\Writer` will not render an invalid feed for either standard +unless the end-user deliberately elects to ignore all exceptions. This built in +safeguard was added to ensure users without in-depth knowledge of the relevant +specifications have a bit less to worry about. + +## Setting Feed Data Points + +Before you can render a feed, you must first setup the data necessary for the +feed being rendered. This utilises a simple setter style API, which doubles as +a method for validating the data being set. By design, the API closely matches +that for `Zend\Feed\Reader` to avoid undue confusion and uncertainty. + +`Zend\Feed\Writer` offers this API via its data container classes +`Zend\Feed\Writer\Feed` and `Zend\Feed\Writer\Entry` (not to mention the Atom +2.0 specific and extension classes). These classes merely store all feed data in +a type-agnostic manner, meaning you may reuse any data container with any +renderer without requiring additional work. Both classes are also amenable to +extensions, meaning that an extension may define its own container classes which +are registered to the base container classes as extensions, and are checked when +any method call triggers the base container's `__call()` method, allowing method +overloading to the extension classes. + +Here's a summary of the Core API for Feeds. You should note it comprises not +only the basic RSS and Atom standards, but also accounts for a number of +included extensions bundled with `Zend\Feed\Writer`. The naming of these +extension sourced methods remain fairly generic; all extension methods operate +at the same level as the Core API, though we do allow you to retrieve any +specific extension object separately if required. + +The Feed API for data is contained in `Zend\Feed\Writer\Feed`. In addition to the API +detailed below, the class also implements the `Countable` and `Iterator` interfaces. + +### Feed API Methods + +Method | Description +------ | ----------- +`setId()` | Set a unique identifier associated with this feed. For Atom 1.0 this is an `atom:id` element, whereas for RSS 2.0 it is added as a `guid` element. These are optional so long as a link is added; i.e. if no identifier is provided, the link is used. +`setTitle()` | Set the title of the feed. +`setDescription()` | Set the text description of the feed. +`setLink()` | Set a URI to the HTML website containing the same or similar information as this feed (i.e. if the feed is from a blog, it should provide the blog's URI where the HTML version of the entries can be read). +`setFeedLinks()` | Add a link to an XML feed, whether it is to the feed being generated, or an alternate URI pointing to the same feed but in a different format. At a minimum, it is recommended to include a link to the feed being generated so it has an identifiable final URI allowing a client to track its location changes without necessitating constant redirects. The parameter is an array of arrays, where each sub-array contains the keys "type" and "uri". The type should be one of "atom", "rss", or "rdf". +`addAuthors()` | Sets the data for authors. The parameter is an array of array,s where each sub-array may contain the keys "name", "email", and "uri". The "uri" value is only applicable for Atom feeds, since RSS contains no facility to show it. For RSS 2.0, rendering will create two elements: an author element containing the email reference with the name in brackets, and a Dublin Core creator element only containing the name. +`addAuthor()` | Sets the data for a single author following the same array format as described above for a single sub-array. +`setDateCreated()` | Sets the date on which this feed was created. Generally only applicable to Atom, where it represents the date the resource described by an Atom 1.0 document was created. The expected parameter may be a UNIX timestamp or a `DateTime` object. +`setDateModified()` | Sets the date on which this feed was last modified. The expected parameter may be a UNIX timestamp or a `DateTime` object. +`setLastBuildDate()` | Sets the date on which this feed was last build. The expected parameter may be a UNIX timestamp or a `DateTime` object. This will only be rendered for RSS 2.0 feeds, and is automatically rendered as the current date by default when not explicitly set. +`setLanguage()` | Sets the language of the feed. This will be omitted unless set. +`setGenerator()` | Allows the setting of a generator. The parameter should be an array containing the keys "name", "version", and "uri". If omitted a default generator will be added referencing `Zend\Feed\Writer`, the current zend-version version, and the Framework's URI. +`setCopyright()` | Sets a copyright notice associated with the feed. +`addHubs()` | Accepts an array of Pubsubhubbub Hub Endpoints to be rendered in the feed as Atom links so that PuSH Subscribers may subscribe to your feed. Note that you must implement a Pubsubhubbub Publisher in order for real-time updates to be enabled. A Publisher may be implemented using `Zend\Feed\Pubsubhubbub\Publisher`. The method `addHub()` allows adding a single hub at a time. +`addCategories()` | Accepts an array of categories for rendering, where each element is itself an array whose possible keys include "term", "label", and "scheme". The "term" is a typically a category name suitable for inclusion in a URI. The "label" may be a human readable category name supporting special characters (it is HTML encoded during rendering) and is a required key. The "scheme" (called the domain in RSS) is optional, but must be a valid URI. The method `addCategory()` allows adding a single category at a time. +`setImage()` | Accepts an array of image metadata for an RSS image or Atom logo. Atom 1.0 only requires a URI. RSS 2.0 requires a URI, HTML link, and an image title. RSS 2.0 optionally may send a width, height, and image description. To provide these, use an array argument with the following keys: "uri", "link", "title", "description", "height", and "width". The RSS 2.0 HTML link should point to the feed source's HTML page. +`createEntry()` | Returns a new instance of `Zend\Feed\Writer\Entry`. This is the Entry data container. New entries are not automatically assigned to the current feed, so you must explicitly call `addEntry()` to add the entry for rendering. +`addEntry()` | Adds an instance of `Zend\Feed\Writer\Entry` to the current feed container for rendering. +`createTombstone()` | Returns a new instance of `Zend\Feed\Writer\Deleted`. This is the Atom 2.0 Tombstone data container. New entries are not automatically assigned to the current feed, so you must explicitly call `addTombstone()` to add the deleted entry for rendering. +`addTombstone()` | Adds an instance of `Zend\Feed\Writer\Deleted` to the current feed container for rendering. +`removeEntry()` | Accepts a parameter indicating an array index of the entry to remove from the feed. +`export()` | Exports the entire data hierarchy to an XML feed. The method has two parameters. The first is the feed type, one of "atom" or "rss". The second is an optional boolean to set indicating whether or not Exceptions are thrown. The default is `TRUE`. + +> #### Retrieval methods +> +> In addition to the setters listed above, `Feed` instances also provide +> matching getters to retrieve data from the `Feed` data container. For +> example, `setImage()` is matched with a `getImage()` method. + +## Setting Entry Data Points + +Below is a summary of the Core API for entries and items. You should note that +it covers not only the basic RSS and Atom standards, but also a number of +included extensions bundled with `Zend\Feed\Writer`. The naming of these +extension sourced methods remain fairly generic; all extension methods operate +at the same level as the Core API, though we do allow you to retrieve any +specific extension object separately if required. + +The Entry *API* for data is contained in `Zend\Feed\Writer\Entry`. + +### Entry API Methods + +Method | Description +------ | ----------- +`setId()` | Set a unique identifier associated with this entry. For Atom 1.0 this is an `atom:id` element, whereas for RSS 2.0 it is added as a `guid` element. These are optional so long as a link is added; i.e. if no identifier is provided, the link is used. +`setTitle()` | Set the title of the entry. +`setDescription()` | Set the text description of the entry. +`setContent()` | Set the content of the entry. +`setLink()` | Set a URI to the HTML website containing the same or similar information as this entry (i.e. if the feed is from a blog, it should provide the blog article's URI where the HTML version of the entry can be read). +`setFeedLinks()` | Add a link to an XML feed, whether it is to the feed being generated, or an alternate URI pointing to the same feed but in a different format. At a minimum, it is recommended to include a link to the feed being generated so it has an identifiable final URI allowing a client to track its location changes without necessitating constant redirects. The parameter is an array of arrays, where each sub-array contains the keys "type" and "uri". The type should be one of "atom", "rss", or "rdf". If a type is omitted, it defaults to the type used when rendering the feed. +`addAuthors()` | Sets the data for authors. The parameter is an array of array,s where each sub-array may contain the keys "name", "email", and "uri". The "uri" value is only applicable for Atom feeds, since RSS contains no facility to show it. For RSS 2.0, rendering will create two elements: an author element containing the email reference with the name in brackets, and a Dublin Core creator element only containing the name. +`addAuthor()` | Sets the data for a single author following the same format as described above for a single sub-array. +`setDateCreated()` | Sets the date on which this entry was created. Generally only applicable to Atom where it represents the date the resource described by an Atom 1.0 document was created. The expected parameter may be a UNIX timestamp or a `DateTime` object. If omitted, the date used will be the current date and time. +`setDateModified()` | Sets the date on which this entry was last modified. The expected parameter may be a UNIX timestamp or a `DateTime` object. If omitted, the date used will be the current date and time. +`setCopyright()` | Sets a copyright notice associated with the entry. +`addCategories()` | Accepts an array of categories for rendering, where each element is itself an array whose possible keys include "term", "label", and "scheme". The "term" is a typically a category name suitable for inclusion in a URI. The "label" may be a human readable category name supporting special characters (it is encoded during rendering) and is a required key. The "scheme" (called the domain in RSS) is optional but must be a valid URI. +`addCategory()` | Sets the data for a single category following the same format as described above for a single sub-array. +`setCommentCount()` | Sets the number of comments associated with this entry. Rendering differs between RSS and Atom 2.0 depending on the element or attribute needed. +`setCommentLink()` | Sets a link to an HTML page containing comments associated with this entry. +`setCommentFeedLink()` | Sets a link to an XML feed containing comments associated with this entry. The parameter is an array containing the keys "uri" and "type", where the type is one of "rdf", "rss", or "atom". +`setCommentFeedLinks()` | Same as `setCommentFeedLink()`, except it accepts an array of arrays, where each subarray contains the expected parameters of `setCommentFeedLink()`. +`setEncoding()` | Sets the encoding of entry text. This will default to UTF-8, which is the preferred encoding. + +> #### Retrieval methods +> +> In addition to the setters listed above, `Entry` instances also provide +> matching getters to retrieve data from the `Entry` data container. For +> example, `setContent()` is matched with a `getContent()` method. + +## Extensions + +- TODO diff --git a/vendor/zendframework/zend-feed/mkdocs.yml b/vendor/zendframework/zend-feed/mkdocs.yml new file mode 100644 index 00000000..609957c1 --- /dev/null +++ b/vendor/zendframework/zend-feed/mkdocs.yml @@ -0,0 +1,20 @@ +docs_dir: doc/book +site_dir: doc/html +pages: + - index.md + - Introduction: intro.md + - Reader: + - "Zend\\Feed\\Reader": reader.md + - 'HTTP Clients': http-clients.md + - 'Importing Feeds': importing.md + - 'Feed Discovery': find-feeds.md + - 'Consuming RSS Feeds': consuming-rss.md + - 'Consuming Atom Feeds': consuming-atom.md + - 'Consuming Atom Entries': consuming-atom-entry.md + - Security: security.md + - Writer: writer.md + - Pubsubhubbub: pubsubhubbub.md +site_name: zend-feed +site_description: Zend\Feed +repo_url: 'https://github.com/zendframework/zend-feed' +copyright: 'Copyright (c) 2016 Zend Technologies USA Inc.' diff --git a/vendor/zendframework/zend-feed/src/Reader/Entry/Atom.php b/vendor/zendframework/zend-feed/src/Reader/Entry/Atom.php index c68f360f..84efaadd 100644 --- a/vendor/zendframework/zend-feed/src/Reader/Entry/Atom.php +++ b/vendor/zendframework/zend-feed/src/Reader/Entry/Atom.php @@ -104,7 +104,7 @@ public function getContent() /** * Get the entry creation date * - * @return string + * @return \DateTime */ public function getDateCreated() { @@ -122,7 +122,7 @@ public function getDateCreated() /** * Get the entry modification date * - * @return string + * @return \DateTime */ public function getDateModified() { diff --git a/vendor/zendframework/zend-feed/src/Reader/Entry/EntryInterface.php b/vendor/zendframework/zend-feed/src/Reader/Entry/EntryInterface.php index c5e5fb22..250f4b6e 100644 --- a/vendor/zendframework/zend-feed/src/Reader/Entry/EntryInterface.php +++ b/vendor/zendframework/zend-feed/src/Reader/Entry/EntryInterface.php @@ -38,14 +38,14 @@ public function getContent(); /** * Get the entry creation date * - * @return string + * @return \DateTime */ public function getDateCreated(); /** * Get the entry modification date * - * @return string + * @return \DateTime */ public function getDateModified(); diff --git a/vendor/zendframework/zend-feed/src/Reader/Entry/Rss.php b/vendor/zendframework/zend-feed/src/Reader/Entry/Rss.php index b55fdad4..0832ba36 100644 --- a/vendor/zendframework/zend-feed/src/Reader/Entry/Rss.php +++ b/vendor/zendframework/zend-feed/src/Reader/Entry/Rss.php @@ -167,7 +167,7 @@ public function getContent() /** * Get the entry's date of creation * - * @return string + * @return \DateTime */ public function getDateCreated() { @@ -178,7 +178,7 @@ public function getDateCreated() * Get the entry's date of modification * * @throws Exception\RuntimeException - * @return string + * @return \DateTime */ public function getDateModified() { diff --git a/vendor/zendframework/zend-feed/src/Reader/Exception/InvalidHttpClientException.php b/vendor/zendframework/zend-feed/src/Reader/Exception/InvalidHttpClientException.php new file mode 100644 index 00000000..c5d66298 --- /dev/null +++ b/vendor/zendframework/zend-feed/src/Reader/Exception/InvalidHttpClientException.php @@ -0,0 +1,16 @@ + 'Zend\Feed\Reader\Extension\Atom\Entry', - 'atomfeed' => 'Zend\Feed\Reader\Extension\Atom\Feed', - 'contententry' => 'Zend\Feed\Reader\Extension\Content\Entry', - 'creativecommonsentry' => 'Zend\Feed\Reader\Extension\CreativeCommons\Entry', - 'creativecommonsfeed' => 'Zend\Feed\Reader\Extension\CreativeCommons\Feed', - 'dublincoreentry' => 'Zend\Feed\Reader\Extension\DublinCore\Entry', - 'dublincorefeed' => 'Zend\Feed\Reader\Extension\DublinCore\Feed', - 'podcastentry' => 'Zend\Feed\Reader\Extension\Podcast\Entry', - 'podcastfeed' => 'Zend\Feed\Reader\Extension\Podcast\Feed', - 'slashentry' => 'Zend\Feed\Reader\Extension\Slash\Entry', - 'syndicationfeed' => 'Zend\Feed\Reader\Extension\Syndication\Feed', - 'threadentry' => 'Zend\Feed\Reader\Extension\Thread\Entry', - 'wellformedwebentry' => 'Zend\Feed\Reader\Extension\WellFormedWeb\Entry', + protected $aliases = [ + 'atomentry' => Extension\Atom\Entry::class, + 'atomEntry' => Extension\Atom\Entry::class, + 'AtomEntry' => Extension\Atom\Entry::class, + 'atomfeed' => Extension\Atom\Feed::class, + 'atomFeed' => Extension\Atom\Feed::class, + 'AtomFeed' => Extension\Atom\Feed::class, + 'contententry' => Extension\Content\Entry::class, + 'contentEntry' => Extension\Content\Entry::class, + 'ContentEntry' => Extension\Content\Entry::class, + 'creativecommonsentry' => Extension\CreativeCommons\Entry::class, + 'creativeCommonsEntry' => Extension\CreativeCommons\Entry::class, + 'CreativeCommonsEntry' => Extension\CreativeCommons\Entry::class, + 'creativecommonsfeed' => Extension\CreativeCommons\Feed::class, + 'creativeCommonsFeed' => Extension\CreativeCommons\Feed::class, + 'CreativeCommonsFeed' => Extension\CreativeCommons\Feed::class, + 'dublincoreentry' => Extension\DublinCore\Entry::class, + 'dublinCoreEntry' => Extension\DublinCore\Entry::class, + 'DublinCoreEntry' => Extension\DublinCore\Entry::class, + 'dublincorefeed' => Extension\DublinCore\Feed::class, + 'dublinCoreFeed' => Extension\DublinCore\Feed::class, + 'DublinCoreFeed' => Extension\DublinCore\Feed::class, + 'podcastentry' => Extension\Podcast\Entry::class, + 'podcastEntry' => Extension\Podcast\Entry::class, + 'PodcastEntry' => Extension\Podcast\Entry::class, + 'podcastfeed' => Extension\Podcast\Feed::class, + 'podcastFeed' => Extension\Podcast\Feed::class, + 'PodcastFeed' => Extension\Podcast\Feed::class, + 'slashentry' => Extension\Slash\Entry::class, + 'slashEntry' => Extension\Slash\Entry::class, + 'SlashEntry' => Extension\Slash\Entry::class, + 'syndicationfeed' => Extension\Syndication\Feed::class, + 'syndicationFeed' => Extension\Syndication\Feed::class, + 'SyndicationFeed' => Extension\Syndication\Feed::class, + 'threadentry' => Extension\Thread\Entry::class, + 'threadEntry' => Extension\Thread\Entry::class, + 'ThreadEntry' => Extension\Thread\Entry::class, + 'wellformedwebentry' => Extension\WellFormedWeb\Entry::class, + 'wellFormedWebEntry' => Extension\WellFormedWeb\Entry::class, + 'WellFormedWebEntry' => Extension\WellFormedWeb\Entry::class, ]; /** - * Do not share instances + * Factories for default set of extension classes + * + * @var array + */ + protected $factories = [ + Extension\Atom\Entry::class => InvokableFactory::class, + Extension\Atom\Feed::class => InvokableFactory::class, + Extension\Content\Entry::class => InvokableFactory::class, + Extension\CreativeCommons\Entry::class => InvokableFactory::class, + Extension\CreativeCommons\Feed::class => InvokableFactory::class, + Extension\DublinCore\Entry::class => InvokableFactory::class, + Extension\DublinCore\Feed::class => InvokableFactory::class, + Extension\Podcast\Entry::class => InvokableFactory::class, + Extension\Podcast\Feed::class => InvokableFactory::class, + Extension\Slash\Entry::class => InvokableFactory::class, + Extension\Syndication\Feed::class => InvokableFactory::class, + Extension\Thread\Entry::class => InvokableFactory::class, + Extension\WellFormedWeb\Entry::class => InvokableFactory::class, + // Legacy (v2) due to alias resolution; canonical form of resolved + // alias is used to look up the factory, while the non-normalized + // resolved alias is used as the requested name passed to the factory. + 'zendfeedreaderextensionatomentry' => InvokableFactory::class, + 'zendfeedreaderextensionatomfeed' => InvokableFactory::class, + 'zendfeedreaderextensioncontententry' => InvokableFactory::class, + 'zendfeedreaderextensioncreativecommonsentry' => InvokableFactory::class, + 'zendfeedreaderextensioncreativecommonsfeed' => InvokableFactory::class, + 'zendfeedreaderextensiondublincoreentry' => InvokableFactory::class, + 'zendfeedreaderextensiondublincorefeed' => InvokableFactory::class, + 'zendfeedreaderextensionpodcastentry' => InvokableFactory::class, + 'zendfeedreaderextensionpodcastfeed' => InvokableFactory::class, + 'zendfeedreaderextensionslashentry' => InvokableFactory::class, + 'zendfeedreaderextensionsyndicationfeed' => InvokableFactory::class, + 'zendfeedreaderextensionthreadentry' => InvokableFactory::class, + 'zendfeedreaderextensionwellformedwebentry' => InvokableFactory::class, + ]; + + /** + * Do not share instances (v2) * * @var bool */ protected $shareByDefault = false; + /** + * Do not share instances (v3) + * + * @var bool + */ + protected $sharedByDefault = false; + /** * Validate the plugin * @@ -57,7 +129,7 @@ class ExtensionPluginManager extends AbstractPluginManager * @return void * @throws Exception\InvalidArgumentException if invalid */ - public function validatePlugin($plugin) + public function validate($plugin) { if ($plugin instanceof Extension\AbstractEntry || $plugin instanceof Extension\AbstractFeed @@ -66,7 +138,7 @@ public function validatePlugin($plugin) return; } - throw new Exception\InvalidArgumentException(sprintf( + throw new InvalidServiceException(sprintf( 'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed ' . 'or %s\Extension\AbstractEntry', (is_object($plugin) ? get_class($plugin) : gettype($plugin)), @@ -74,4 +146,26 @@ public function validatePlugin($plugin) __NAMESPACE__ )); } + + /** + * Validate the plugin (v2) + * + * @param mixed $plugin + * @return void + * @throws Exception\InvalidArgumentException if invalid + */ + public function validatePlugin($plugin) + { + try { + $this->validate($plugin); + } catch (InvalidServiceException $e) { + throw new Exception\InvalidArgumentException(sprintf( + 'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed ' + . 'or %s\Extension\AbstractEntry', + (is_object($plugin) ? get_class($plugin) : gettype($plugin)), + __NAMESPACE__, + __NAMESPACE__ + )); + } + } } diff --git a/vendor/zendframework/zend-feed/src/Reader/Http/HeaderAwareClientInterface.php b/vendor/zendframework/zend-feed/src/Reader/Http/HeaderAwareClientInterface.php new file mode 100644 index 00000000..5895b7cd --- /dev/null +++ b/vendor/zendframework/zend-feed/src/Reader/Http/HeaderAwareClientInterface.php @@ -0,0 +1,33 @@ + + * [ + * 'header-name' => [ + * 'header', + * 'values' + * ] + * ] + * + * + * @param string $uri + * @param array $headers + * @return HeaderAwareResponseInterface + */ + public function get($uri, array $headers = []); +} diff --git a/vendor/zendframework/zend-feed/src/Reader/Http/HeaderAwareResponseInterface.php b/vendor/zendframework/zend-feed/src/Reader/Http/HeaderAwareResponseInterface.php new file mode 100644 index 00000000..509c5fd7 --- /dev/null +++ b/vendor/zendframework/zend-feed/src/Reader/Http/HeaderAwareResponseInterface.php @@ -0,0 +1,28 @@ +decoratedResponse = $response; + } + + /** + * Return the original PSR-7 response being decorated. + * + * @return Psr7ResponseInterface + */ + public function getDecoratedResponse() + { + return $this->decoratedResponse; + } + + /** + * {@inheritDoc} + */ + public function getBody() + { + return (string) $this->decoratedResponse->getBody(); + } + + /** + * {@inheritDoc} + */ + public function getStatusCode() + { + return $this->decoratedResponse->getStatusCode(); + } + + /** + * {@inheritDoc} + */ + public function getHeaderLine($name, $default = null) + { + if (! $this->decoratedResponse->hasHeader($name)) { + return $default; + } + return $this->decoratedResponse->getHeaderLine($name); + } +} diff --git a/vendor/zendframework/zend-feed/src/Reader/Http/Response.php b/vendor/zendframework/zend-feed/src/Reader/Http/Response.php new file mode 100644 index 00000000..482c33e1 --- /dev/null +++ b/vendor/zendframework/zend-feed/src/Reader/Http/Response.php @@ -0,0 +1,175 @@ +validateStatusCode($statusCode); + $this->validateBody($body); + $this->validateHeaders($headers); + + $this->statusCode = (int) $statusCode; + $this->body = (string) $body; + $this->headers = $this->normalizeHeaders($headers); + } + + /** + * {@inheritDoc} + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * {@inheritDoc} + */ + public function getBody() + { + return $this->body; + } + + /** + * {@inheritDoc} + */ + public function getHeaderLine($name, $default = null) + { + $normalizedName = strtolower($name); + return isset($this->headers[$normalizedName]) + ? $this->headers[$normalizedName] + : $default; + } + + /** + * Validate that we have a status code argument that will work for our context. + * + * @param mixed $body + * @throws Exception\InvalidArgumentException for arguments not castable + * to integer HTTP status codes. + */ + private function validateStatusCode($statusCode) + { + if (! is_numeric($statusCode)) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects a numeric status code; received %s', + __CLASS__, + (is_object($statusCode) ? get_class($statusCode) : gettype($statusCode)) + )); + } + + if (100 > $statusCode || 599 < $statusCode) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects an integer status code between 100 and 599 inclusive; received %s', + __CLASS__, + $statusCode + )); + } + + if (intval($statusCode) != $statusCode) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects an integer status code; received %s', + __CLASS__, + $statusCode + )); + } + } + + /** + * Validate that we have a body argument that will work for our context. + * + * @param mixed $body + * @throws Exception\InvalidArgumentException for arguments not castable + * to strings. + */ + private function validateBody($body) + { + if (is_string($body)) { + return; + } + + if (is_object($body) && method_exists($body, '__toString')) { + return; + } + + throw new Exception\InvalidArgumentException(sprintf( + '%s expects a string body, or an object that can cast to string; received %s', + __CLASS__, + (is_object($body) ? get_class($body) : gettype($body)) + )); + } + + /** + * Validate header values. + * + * @param array $headers + * @throws Exception\InvalidArgumentException + */ + private function validateHeaders(array $headers) + { + foreach ($headers as $name => $value) { + if (! is_string($name) || is_numeric($name) || empty($name)) { + throw new Exception\InvalidArgumentException(sprintf( + 'Header names provided to %s must be non-empty, non-numeric strings; received %s', + __CLASS__, + $name + )); + } + + if (! is_string($value) && ! is_numeric($value)) { + throw new Exception\InvalidArgumentException(sprintf( + 'Individual header values provided to %s must be a string or numeric; received %s for header %s', + __CLASS__, + (is_object($value) ? get_class($value) : gettype($value)), + $name + )); + } + } + } + + /** + * Normalize header names to lowercase. + * + * @param array $headers + * @return array + */ + private function normalizeHeaders(array $headers) + { + $normalized = []; + foreach ($headers as $name => $value) { + $normalized[strtolower($name)] = $value; + } + return $normalized; + } +} diff --git a/vendor/zendframework/zend-feed/src/Reader/Http/ZendHttpClientDecorator.php b/vendor/zendframework/zend-feed/src/Reader/Http/ZendHttpClientDecorator.php new file mode 100644 index 00000000..dbff9932 --- /dev/null +++ b/vendor/zendframework/zend-feed/src/Reader/Http/ZendHttpClientDecorator.php @@ -0,0 +1,118 @@ +client = $client; + } + + /** + * @return ZendHttpClient + */ + public function getDecoratedClient() + { + return $this->client; + } + + /** + * {@inheritDoc} + */ + public function get($uri, array $headers = []) + { + $this->client->resetParameters(); + $this->client->setMethod('GET'); + $this->client->setHeaders(new Headers()); + $this->client->setUri($uri); + if (! empty($headers)) { + $this->injectHeaders($headers); + } + $response = $this->client->send(); + + return new Response( + $response->getStatusCode(), + $response->getBody(), + $this->prepareResponseHeaders($response->getHeaders()) + ); + } + + /** + * Inject header values into the client. + * + * @param array $headerValues + */ + private function injectHeaders(array $headerValues) + { + $headers = $this->client->getRequest()->getHeaders(); + foreach ($headerValues as $name => $values) { + if (! is_string($name) || is_numeric($name) || empty($name)) { + throw new Exception\InvalidArgumentException(sprintf( + 'Header names provided to %s::get must be non-empty, non-numeric strings; received %s', + __CLASS__, + $name + )); + } + + if (! is_array($values)) { + throw new Exception\InvalidArgumentException(sprintf( + 'Header values provided to %s::get must be arrays of values; received %s', + __CLASS__, + (is_object($values) ? get_class($values) : gettype($values)) + )); + } + + foreach ($values as $value) { + if (! is_string($value) && ! is_numeric($value)) { + throw new Exception\InvalidArgumentException(sprintf( + 'Individual header values provided to %s::get must be strings or numbers; ' + . 'received %s for header %s', + __CLASS__, + (is_object($value) ? get_class($value) : gettype($value)), + $name + )); + } + + $headers->addHeaderLine($name, $value); + } + } + } + + /** + * Normalize headers to use with HeaderAwareResponseInterface. + * + * Ensures multi-value headers are represented as a single string, via + * comma concatenation. + * + * @param Headers $headers + * @return array + */ + private function prepareResponseHeaders(Headers $headers) + { + $normalized = []; + foreach ($headers->toArray() as $name => $value) { + $normalized[$name] = is_array($value) ? implode(', ', $value) : $value; + } + return $normalized; + } +} diff --git a/vendor/zendframework/zend-feed/src/Reader/Reader.php b/vendor/zendframework/zend-feed/src/Reader/Reader.php index 09bdcf4b..693a3e2e 100644 --- a/vendor/zendframework/zend-feed/src/Reader/Reader.php +++ b/vendor/zendframework/zend-feed/src/Reader/Reader.php @@ -14,6 +14,7 @@ use Zend\Cache\Storage\StorageInterface as CacheStorage; use Zend\Http as ZendHttp; use Zend\Stdlib\ErrorHandler; +use Zend\Feed\Reader\Exception\InvalidHttpClientException; /** */ @@ -57,7 +58,7 @@ class Reader implements ReaderImportInterface /** * HTTP client object to use for retrieving feeds * - * @var ZendHttp\Client + * @var Http\ClientInterface */ protected static $httpClient = null; @@ -117,23 +118,30 @@ public static function setCache(CacheStorage $cache) * * Sets the HTTP client object to use for retrieving the feeds. * - * @param ZendHttp\Client $httpClient + * @param ZendHttp\Client | Http\ClientInterface $httpClient * @return void */ - public static function setHttpClient(ZendHttp\Client $httpClient) + public static function setHttpClient($httpClient) { + if ($httpClient instanceof ZendHttp\Client) { + $httpClient = new Http\ZendHttpClientDecorator($httpClient); + } + + if (! $httpClient instanceof Http\ClientInterface) { + throw new InvalidHttpClientException(); + } static::$httpClient = $httpClient; } /** * Gets the HTTP client object. If none is set, a new ZendHttp\Client will be used. * - * @return ZendHttp\Client + * @return Http\ClientInterface */ public static function getHttpClient() { - if (!static::$httpClient instanceof ZendHttp\Client) { - static::$httpClient = new ZendHttp\Client(); + if (! static::$httpClient) { + static::$httpClient = new Http\ZendHttpClientDecorator(new ZendHttp\Client()); } return static::$httpClient; @@ -189,17 +197,16 @@ public static function useHttpConditionalGet($bool = true) */ public static function import($uri, $etag = null, $lastModified = null) { - $cache = self::getCache(); - $client = self::getHttpClient(); - $client->resetParameters(); - $headers = new ZendHttp\Headers(); - $client->setHeaders($headers); - $client->setUri($uri); + $cache = self::getCache(); + $client = self::getHttpClient(); $cacheId = 'Zend_Feed_Reader_' . md5($uri); if (static::$httpConditionalGet && $cache) { - $data = $cache->getItem($cacheId); - if ($data) { + $headers = []; + $data = $cache->getItem($cacheId); + if ($data && $client instanceof Http\HeaderAwareClientInterface) { + // Only check for ETag and last modified values in the cache + // if we have a client capable of emitting headers in the first place. if ($etag === null) { $etag = $cache->getItem($cacheId . '_etag'); } @@ -207,13 +214,13 @@ public static function import($uri, $etag = null, $lastModified = null) $lastModified = $cache->getItem($cacheId . '_lastmodified'); } if ($etag) { - $headers->addHeaderLine('If-None-Match', $etag); + $headers['If-None-Match'] = [$etag]; } if ($lastModified) { - $headers->addHeaderLine('If-Modified-Since', $lastModified); + $headers['If-Modified-Since'] = [$lastModified]; } } - $response = $client->send(); + $response = $client->get($uri, $headers); if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 304) { throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode()); } @@ -222,11 +229,14 @@ public static function import($uri, $etag = null, $lastModified = null) } else { $responseXml = $response->getBody(); $cache->setItem($cacheId, $responseXml); - if ($response->getHeaders()->get('ETag')) { - $cache->setItem($cacheId . '_etag', $response->getHeaders()->get('ETag')->getFieldValue()); - } - if ($response->getHeaders()->get('Last-Modified')) { - $cache->setItem($cacheId . '_lastmodified', $response->getHeaders()->get('Last-Modified')->getFieldValue()); + + if ($response instanceof Http\HeaderAwareResponseInterface) { + if ($response->getHeaderLine('ETag', false)) { + $cache->setItem($cacheId . '_etag', $response->getHeaderLine('ETag')); + } + if ($response->getHeaderLine('Last-Modified', false)) { + $cache->setItem($cacheId . '_lastmodified', $response->getHeaderLine('Last-Modified')); + } } } return static::importString($responseXml); @@ -235,7 +245,7 @@ public static function import($uri, $etag = null, $lastModified = null) if ($data) { return static::importString($data); } - $response = $client->send(); + $response = $client->get($uri); if ((int) $response->getStatusCode() !== 200) { throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode()); } @@ -243,7 +253,7 @@ public static function import($uri, $etag = null, $lastModified = null) $cache->setItem($cacheId, $responseXml); return static::importString($responseXml); } else { - $response = $client->send(); + $response = $client->get($uri); if ((int) $response->getStatusCode() !== 200) { throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode()); } @@ -270,7 +280,7 @@ public static function import($uri, $etag = null, $lastModified = null) public static function importRemoteFeed($uri, Http\ClientInterface $client) { $response = $client->get($uri); - if (!$response instanceof Http\ResponseInterface) { + if (! $response instanceof Http\ResponseInterface) { throw new Exception\RuntimeException(sprintf( 'Did not receive a %s\Http\ResponseInterface from the provided HTTP client; received "%s"', __NAMESPACE__, @@ -371,9 +381,8 @@ public static function importFile($filename) */ public static function findFeedLinks($uri) { - $client = static::getHttpClient(); - $client->setUri($uri); - $response = $client->send(); + $client = static::getHttpClient(); + $response = $client->get($uri); if ($response->getStatusCode() !== 200) { throw new Exception\RuntimeException("Failed to access $uri, got response code " . $response->getStatusCode()); } diff --git a/vendor/zendframework/zend-feed/src/Writer/Extension/ITunes/Feed.php b/vendor/zendframework/zend-feed/src/Writer/Extension/ITunes/Feed.php index 0b21b3b0..054fe3e3 100644 --- a/vendor/zendframework/zend-feed/src/Writer/Extension/ITunes/Feed.php +++ b/vendor/zendframework/zend-feed/src/Writer/Extension/ITunes/Feed.php @@ -14,8 +14,6 @@ use Zend\Stdlib\StringUtils; use Zend\Stdlib\StringWrapper\StringWrapperInterface; -/** -*/ class Feed { /** diff --git a/vendor/zendframework/zend-feed/src/Writer/ExtensionManager.php b/vendor/zendframework/zend-feed/src/Writer/ExtensionManager.php index b0e0e3bf..a7efb3e1 100644 --- a/vendor/zendframework/zend-feed/src/Writer/ExtensionManager.php +++ b/vendor/zendframework/zend-feed/src/Writer/ExtensionManager.php @@ -12,7 +12,7 @@ /** * Default implementation of ExtensionManagerInterface * - * Decorator of ExtensionPluginManager. + * Decorator for an ExtensionManagerInstance. */ class ExtensionManager implements ExtensionManagerInterface { @@ -22,14 +22,14 @@ class ExtensionManager implements ExtensionManagerInterface * Constructor * * Seeds the extension manager with a plugin manager; if none provided, - * creates an instance. + * creates and decorates an instance of StandaloneExtensionManager. * - * @param null|ExtensionPluginManager $pluginManager + * @param null|ExtensionManagerInterface $pluginManager */ - public function __construct(ExtensionPluginManager $pluginManager = null) + public function __construct(ExtensionManagerInterface $pluginManager = null) { if (null === $pluginManager) { - $pluginManager = new ExtensionPluginManager(); + $pluginManager = new StandaloneExtensionManager(); } $this->pluginManager = $pluginManager; } @@ -37,7 +37,7 @@ public function __construct(ExtensionPluginManager $pluginManager = null) /** * Method overloading * - * Proxy to composed ExtensionPluginManager instance. + * Proxy to composed ExtensionManagerInterface instance. * * @param string $method * @param array $args diff --git a/vendor/zendframework/zend-feed/src/Writer/ExtensionPluginManager.php b/vendor/zendframework/zend-feed/src/Writer/ExtensionPluginManager.php index 8586b48a..34cc57f4 100644 --- a/vendor/zendframework/zend-feed/src/Writer/ExtensionPluginManager.php +++ b/vendor/zendframework/zend-feed/src/Writer/ExtensionPluginManager.php @@ -10,6 +10,8 @@ namespace Zend\Feed\Writer; use Zend\ServiceManager\AbstractPluginManager; +use Zend\ServiceManager\Exception\InvalidServiceException; +use Zend\ServiceManager\Factory\InvokableFactory; /** * Plugin manager implementation for feed writer extensions @@ -19,41 +21,107 @@ class ExtensionPluginManager extends AbstractPluginManager { /** - * Default set of extension classes + * Aliases for default set of extension classes * * @var array */ - protected $invokableClasses = [ - 'atomrendererfeed' => 'Zend\Feed\Writer\Extension\Atom\Renderer\Feed', - 'contentrendererentry' => 'Zend\Feed\Writer\Extension\Content\Renderer\Entry', - 'dublincorerendererentry' => 'Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry', - 'dublincorerendererfeed' => 'Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed', - 'itunesentry' => 'Zend\Feed\Writer\Extension\ITunes\Entry', - 'itunesfeed' => 'Zend\Feed\Writer\Extension\ITunes\Feed', - 'itunesrendererentry' => 'Zend\Feed\Writer\Extension\ITunes\Renderer\Entry', - 'itunesrendererfeed' => 'Zend\Feed\Writer\Extension\ITunes\Renderer\Feed', - 'slashrendererentry' => 'Zend\Feed\Writer\Extension\Slash\Renderer\Entry', - 'threadingrendererentry' => 'Zend\Feed\Writer\Extension\Threading\Renderer\Entry', - 'wellformedwebrendererentry' => 'Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry', + protected $aliases = [ + 'atomrendererfeed' => Extension\Atom\Renderer\Feed::class, + 'atomRendererFeed' => Extension\Atom\Renderer\Feed::class, + 'AtomRendererFeed' => Extension\Atom\Renderer\Feed::class, + 'contentrendererentry' => Extension\Content\Renderer\Entry::class, + 'contentRendererEntry' => Extension\Content\Renderer\Entry::class, + 'ContentRendererEntry' => Extension\Content\Renderer\Entry::class, + 'dublincorerendererentry' => Extension\DublinCore\Renderer\Entry::class, + 'dublinCoreRendererEntry' => Extension\DublinCore\Renderer\Entry::class, + 'DublinCoreRendererEntry' => Extension\DublinCore\Renderer\Entry::class, + 'dublincorerendererfeed' => Extension\DublinCore\Renderer\Feed::class, + 'dublinCoreRendererFeed' => Extension\DublinCore\Renderer\Feed::class, + 'DublinCoreRendererFeed' => Extension\DublinCore\Renderer\Feed::class, + 'itunesentry' => Extension\ITunes\Entry::class, + 'itunesEntry' => Extension\ITunes\Entry::class, + 'iTunesEntry' => Extension\ITunes\Entry::class, + 'ItunesEntry' => Extension\ITunes\Entry::class, + 'itunesfeed' => Extension\ITunes\Feed::class, + 'itunesFeed' => Extension\ITunes\Feed::class, + 'iTunesFeed' => Extension\ITunes\Feed::class, + 'ItunesFeed' => Extension\ITunes\Feed::class, + 'itunesrendererentry' => Extension\ITunes\Renderer\Entry::class, + 'itunesRendererEntry' => Extension\ITunes\Renderer\Entry::class, + 'iTunesRendererEntry' => Extension\ITunes\Renderer\Entry::class, + 'ItunesRendererEntry' => Extension\ITunes\Renderer\Entry::class, + 'itunesrendererfeed' => Extension\ITunes\Renderer\Feed::class, + 'itunesRendererFeed' => Extension\ITunes\Renderer\Feed::class, + 'iTunesRendererFeed' => Extension\ITunes\Renderer\Feed::class, + 'ItunesRendererFeed' => Extension\ITunes\Renderer\Feed::class, + 'slashrendererentry' => Extension\Slash\Renderer\Entry::class, + 'slashRendererEntry' => Extension\Slash\Renderer\Entry::class, + 'SlashRendererEntry' => Extension\Slash\Renderer\Entry::class, + 'threadingrendererentry' => Extension\Threading\Renderer\Entry::class, + 'threadingRendererEntry' => Extension\Threading\Renderer\Entry::class, + 'ThreadingRendererEntry' => Extension\Threading\Renderer\Entry::class, + 'wellformedwebrendererentry' => Extension\WellFormedWeb\Renderer\Entry::class, + 'wellFormedWebRendererEntry' => Extension\WellFormedWeb\Renderer\Entry::class, + 'WellFormedWebRendererEntry' => Extension\WellFormedWeb\Renderer\Entry::class, ]; /** - * Do not share instances + * Factories for default set of extension classes + * + * @var array + */ + protected $factories = [ + Extension\Atom\Renderer\Feed::class => InvokableFactory::class, + Extension\Content\Renderer\Entry::class => InvokableFactory::class, + Extension\DublinCore\Renderer\Entry::class => InvokableFactory::class, + Extension\DublinCore\Renderer\Feed::class => InvokableFactory::class, + Extension\ITunes\Entry::class => InvokableFactory::class, + Extension\ITunes\Feed::class => InvokableFactory::class, + Extension\ITunes\Renderer\Entry::class => InvokableFactory::class, + Extension\ITunes\Renderer\Feed::class => InvokableFactory::class, + Extension\Slash\Renderer\Entry::class => InvokableFactory::class, + Extension\Threading\Renderer\Entry::class => InvokableFactory::class, + Extension\WellFormedWeb\Renderer\Entry::class => InvokableFactory::class, + // Legacy (v2) due to alias resolution; canonical form of resolved + // alias is used to look up the factory, while the non-normalized + // resolved alias is used as the requested name passed to the factory. + 'zendfeedwriterextensionatomrendererfeed' => InvokableFactory::class, + 'zendfeedwriterextensioncontentrendererentry' => InvokableFactory::class, + 'zendfeedwriterextensiondublincorerendererentry' => InvokableFactory::class, + 'zendfeedwriterextensiondublincorerendererfeed' => InvokableFactory::class, + 'zendfeedwriterextensionitunesentry' => InvokableFactory::class, + 'zendfeedwriterextensionitunesfeed' => InvokableFactory::class, + 'zendfeedwriterextensionitunesrendererentry' => InvokableFactory::class, + 'zendfeedwriterextensionitunesrendererfeed' => InvokableFactory::class, + 'zendfeedwriterextensionslashrendererentry' => InvokableFactory::class, + 'zendfeedwriterextensionthreadingrendererentry' => InvokableFactory::class, + 'zendfeedwriterextensionwellformedwebrendererentry' => InvokableFactory::class, + ]; + + /** + * Do not share instances (v2) * * @var bool */ protected $shareByDefault = false; /** - * Validate the plugin + * Do not share instances (v3) + * + * @var bool + */ + protected $sharedByDefault = false; + + /** + * Validate the plugin (v3) * * Checks that the extension loaded is of a valid type. * * @param mixed $plugin * @return void - * @throws Exception\InvalidArgumentException if invalid + * @throws InvalidServiceException if invalid */ - public function validatePlugin($plugin) + public function validate($plugin) { if ($plugin instanceof Extension\AbstractRenderer) { // we're okay @@ -70,11 +138,32 @@ public function validatePlugin($plugin) return; } - throw new Exception\InvalidArgumentException(sprintf( + throw new InvalidServiceException(sprintf( 'Plugin of type %s is invalid; must implement %s\Extension\RendererInterface ' . 'or the classname must end in "Feed" or "Entry"', (is_object($plugin) ? get_class($plugin) : gettype($plugin)), __NAMESPACE__ )); } + + /** + * Validate plugin (v2) + * + * @param mixed $plugin + * @return void + * @throws Exception\InvalidArgumentException when invalid + */ + public function validatePlugin($plugin) + { + try { + $this->validate($plugin); + } catch (InvalidServiceException $e) { + throw new Exception\InvalidArgumentException(sprintf( + 'Plugin of type %s is invalid; must implement %s\Extension\RendererInterface ' + . 'or the classname must end in "Feed" or "Entry"', + (is_object($plugin) ? get_class($plugin) : gettype($plugin)), + __NAMESPACE__ + )); + } + } } diff --git a/vendor/zendframework/zend-feed/src/Writer/StandaloneExtensionManager.php b/vendor/zendframework/zend-feed/src/Writer/StandaloneExtensionManager.php new file mode 100644 index 00000000..c9a88c76 --- /dev/null +++ b/vendor/zendframework/zend-feed/src/Writer/StandaloneExtensionManager.php @@ -0,0 +1,50 @@ + Extension\Atom\Renderer\Feed::class, + 'Content\Renderer\Entry' => Extension\Content\Renderer\Entry::class, + 'DublinCore\Renderer\Entry' => Extension\DublinCore\Renderer\Entry::class, + 'DublinCore\Renderer\Feed' => Extension\DublinCore\Renderer\Feed::class, + 'ITunes\Entry' => Extension\ITunes\Entry::class, + 'ITunes\Feed' => Extension\ITunes\Feed::class, + 'ITunes\Renderer\Entry' => Extension\ITunes\Renderer\Entry::class, + 'ITunes\Renderer\Feed' => Extension\ITunes\Renderer\Feed::class, + 'Slash\Renderer\Entry' => Extension\Slash\Renderer\Entry::class, + 'Threading\Renderer\Entry' => Extension\Threading\Renderer\Entry::class, + 'WellFormedWeb\Renderer\Entry' => Extension\WellFormedWeb\Renderer\Entry::class, + ]; + + /** + * Do we have the extension? + * + * @param string $extension + * @return bool + */ + public function has($extension) + { + return array_key_exists($extension, $this->extensions); + } + + /** + * Retrieve the extension + * + * @param string $extension + * @return mixed + */ + public function get($extension) + { + $class = $this->extensions[$extension]; + return new $class(); + } +} diff --git a/vendor/zendframework/zend-feed/src/Writer/Writer.php b/vendor/zendframework/zend-feed/src/Writer/Writer.php index a4f95bfc..4c1e257f 100644 --- a/vendor/zendframework/zend-feed/src/Writer/Writer.php +++ b/vendor/zendframework/zend-feed/src/Writer/Writer.php @@ -105,13 +105,16 @@ public static function registerExtension($name) return; } } - if (!$manager->has($feedName) - && !$manager->has($entryName) - && !$manager->has($feedRendererName) - && !$manager->has($entryRendererName) + if (! $manager->has($feedName) + && ! $manager->has($entryName) + && ! $manager->has($feedRendererName) + && ! $manager->has($entryRendererName) ) { - throw new Exception\RuntimeException('Could not load extension: ' . $name - . 'using Plugin Loader. Check prefix paths are configured and extension exists.'); + throw new Exception\RuntimeException(sprintf( + 'Could not load extension "%s" using Plugin Loader. ' + . 'Check prefix paths are configured and extension exists.', + $name + )); } if ($manager->has($feedName)) { static::$extensions['feed'][] = $feedName; diff --git a/vendor/zendframework/zend-hydrator/CHANGELOG.md b/vendor/zendframework/zend-hydrator/CHANGELOG.md deleted file mode 100644 index 69116862..00000000 --- a/vendor/zendframework/zend-hydrator/CHANGELOG.md +++ /dev/null @@ -1,39 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file, in reverse chronological order by release. - -## 1.0.0 - 2015-09-17 - -Initial release. This ports all hydrator classes and functionality from -[zend-stdlib](https://github.com/zendframework/zend-stdlib) to a standalone -repository. All final keywords are removed, to allow a deprecation cycle in the -zend-stdlib component. - -Please note: the following classes will be marked as `final` for a version 2.0.0 -release to immediately follow 1.0.0: - -- `Zend\Hydrator\NamingStrategy\IdentityNamingStrategy` -- `Zend\Hydrator\NamingStrategy\ArrayMapNamingStrategy` -- `Zend\Hydrator\NamingStrategy\CompositeNamingStrategy` -- `Zend\Hydrator\Strategy\ExplodeStrategy` -- `Zend\Hydrator\Strategy\StrategyChain` -- `Zend\Hydrator\Strategy\DateTimeFormatterStrategy` -- `Zend\Hydrator\Strategy\BooleanStrategy` - -As such, you should not extend them. - -### Added - -- Nothing. - -### Deprecated - -- Nothing. - -### Removed - -- Nothing. - -### Fixed - -- Nothing. diff --git a/vendor/zendframework/zend-hydrator/CONTRIBUTING.md b/vendor/zendframework/zend-hydrator/CONTRIBUTING.md deleted file mode 100644 index ddfff50e..00000000 --- a/vendor/zendframework/zend-hydrator/CONTRIBUTING.md +++ /dev/null @@ -1,229 +0,0 @@ -# CONTRIBUTING - -## RESOURCES - -If you wish to contribute to Zend Framework, please be sure to -read/subscribe to the following resources: - - - [Coding Standards](https://github.com/zendframework/zf2/wiki/Coding-Standards) - - [Contributor's Guide](http://framework.zend.com/participate/contributor-guide) - - ZF Contributor's mailing list: - Archives: http://zend-framework-community.634137.n4.nabble.com/ZF-Contributor-f680267.html - Subscribe: zf-contributors-subscribe@lists.zend.com - - ZF Contributor's IRC channel: - #zftalk.dev on Freenode.net - -If you are working on new features or refactoring [create a proposal](https://github.com/zendframework/zend-hydrator/issues/new). - -## Reporting Potential Security Issues - -If you have encountered a potential security vulnerability, please **DO NOT** report it on the public -issue tracker: send it to us at [zf-security@zend.com](mailto:zf-security@zend.com) instead. -We will work with you to verify the vulnerability and patch it as soon as possible. - -When reporting issues, please provide the following information: - -- Component(s) affected -- A description indicating how to reproduce the issue -- A summary of the security vulnerability and impact - -We request that you contact us via the email address above and give the project -contributors a chance to resolve the vulnerability and issue a new release prior -to any public exposure; this helps protect users and provides them with a chance -to upgrade and/or update in order to protect their applications. - -For sensitive email communications, please use [our PGP key](http://framework.zend.com/zf-security-pgp-key.asc). - -## RUNNING TESTS - -> ### Note: testing versions prior to 2.4 -> -> This component originates with Zend Framework 2. During the lifetime of ZF2, -> testing infrastructure migrated from PHPUnit 3 to PHPUnit 4. In most cases, no -> changes were necessary. However, due to the migration, tests may not run on -> versions < 2.4. As such, you may need to change the PHPUnit dependency if -> attempting a fix on such a version. - -To run tests: - -- Clone the repository: - - ```console - $ git clone git@github.com:zendframework/zend-hydrator.git - $ cd - ``` - -- Install dependencies via composer: - - ```console - $ curl -sS https://getcomposer.org/installer | php -- - $ ./composer.phar install - ``` - - If you don't have `curl` installed, you can also download `composer.phar` from https://getcomposer.org/ - -- Run the tests via `phpunit` and the provided PHPUnit config, like in this example: - - ```console - $ ./vendor/bin/phpunit - ``` - -You can turn on conditional tests with the phpunit.xml file. -To do so: - - - Copy `phpunit.xml.dist` file to `phpunit.xml` - - Edit `phpunit.xml` to enable any specific functionality you - want to test, as well as to provide test values to utilize. - -## Running Coding Standards Checks - -This component uses [phpcs](https://github.com/squizlabs/PHP_CodeSniffer) for coding -standards checks, and provides configuration for our selected checks. -`phpcs` is installed by default via Composer. - -To run checks only: - -```console -$ ./vendor/bin/phpcs -``` - -`phpcs` also provides a tool that can automatically fix many CS issues, -`phpcbf`: - -```console -$ ./vendor/bin/phpcbf -``` - -If you allow `phpcbf` to fix CS issues, please re-run the tests to ensure -they pass, and make sure you add and commit the changes after verification. - -## Recommended Workflow for Contributions - -Your first step is to establish a public repository from which we can -pull your work into the master repository. We recommend using -[GitHub](https://github.com), as that is where the component is already hosted. - -1. Setup a [GitHub account](http://github.com/), if you haven't yet -2. Fork the repository (http://github.com/zendframework/zend-hydrator) -3. Clone the canonical repository locally and enter it. - - ```console - $ git clone git://github.com:zendframework/zend-hydrator.git - $ cd zend-hydrator - ``` - -4. Add a remote to your fork; substitute your GitHub username in the command - below. - - ```console - $ git remote add {username} git@github.com:{username}/zend-hydrator.git - $ git fetch {username} - ``` - -### Keeping Up-to-Date - -Periodically, you should update your fork or personal repository to -match the canonical ZF repository. Assuming you have setup your local repository -per the instructions above, you can do the following: - - -```console -$ git checkout master -$ git fetch origin -$ git rebase origin/master -# OPTIONALLY, to keep your remote up-to-date - -$ git push {username} master:master -``` - -If you're tracking other branches -- for example, the "develop" branch, where -new feature development occurs -- you'll want to do the same operations for that -branch; simply substitute "develop" for "master". - -### Working on a patch - -We recommend you do each new feature or bugfix in a new branch. This simplifies -the task of code review as well as the task of merging your changes into the -canonical repository. - -A typical workflow will then consist of the following: - -1. Create a new local branch based off either your master or develop branch. -2. Switch to your new local branch. (This step can be combined with the - previous step with the use of `git checkout -b`.) -3. Do some work, commit, repeat as necessary. -4. Push the local branch to your remote repository. -5. Send a pull request. - -The mechanics of this process are actually quite trivial. Below, we will -create a branch for fixing an issue in the tracker. - -```console -$ git checkout -b hotfix/9295 -Switched to a new branch 'hotfix/9295' -``` - -... do some work ... - - -```console -$ git commit -``` - -... write your log message ... - - -```console -$ git push {username} hotfix/9295:hotfix/9295 -Counting objects: 38, done. -Delta compression using up to 2 threads. -Compression objects: 100% (18/18), done. -Writing objects: 100% (20/20), 8.19KiB, done. -Total 20 (delta 12), reused 0 (delta 0) -To ssh://git@github.com/{username}/zend-hydrator.git - b5583aa..4f51698 HEAD -> master -``` - -To send a pull request, you have two options. - -If using GitHub, you can do the pull request from there. Navigate to -your repository, select the branch you just created, and then select the -"Pull Request" button in the upper right. Select the user/organization -"zendframework" as the recipient. - -If using your own repository - or even if using GitHub - you can use `git -format-patch` to create a patchset for us to apply; in fact, this is -**recommended** for security-related patches. If you use `format-patch`, please -send the patches as attachments to: - -- zf-devteam@zend.com for patches without security implications -- zf-security@zend.com for security patches - -#### What branch to issue the pull request against? - -Which branch should you issue a pull request against? - -- For fixes against the stable release, issue the pull request against the - "master" branch. -- For new features, or fixes that introduce new elements to the public API (such - as new public methods or properties), issue the pull request against the - "develop" branch. - -### Branch Cleanup - -As you might imagine, if you are a frequent contributor, you'll start to -get a ton of branches both locally and on your remote. - -Once you know that your changes have been accepted to the master -repository, we suggest doing some cleanup of these branches. - -- Local branch cleanup - - ```console - $ git branch -d - ``` - -- Remote branch removal - - ```console - $ git push {username} : - ``` diff --git a/vendor/zendframework/zend-hydrator/LICENSE.md b/vendor/zendframework/zend-hydrator/LICENSE.md deleted file mode 100644 index dbb1b49c..00000000 --- a/vendor/zendframework/zend-hydrator/LICENSE.md +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2005-2015, Zend Technologies USA, Inc. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -- Neither the name of Zend Technologies USA, Inc. nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/zendframework/zend-hydrator/README.md b/vendor/zendframework/zend-hydrator/README.md deleted file mode 100644 index 76083347..00000000 --- a/vendor/zendframework/zend-hydrator/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# zend-hydrator - -[![Build Status](https://secure.travis-ci.org/zendframework/zend-hydrator.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-hydrator) -[![Coverage Status](https://coveralls.io/repos/zendframework/zend-hydrator/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-hydrator?branch=master) - -`Zend\Hydrator` provides utilities for mapping arrays to objects, and vice -versa, including facilities for filtering which data is mapped as well as -providing mechanisms for mapping nested structures. - -- File issues at https://github.com/zendframework/zend-hydrator/issues -- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-stdlib diff --git a/vendor/zendframework/zend-hydrator/composer.json b/vendor/zendframework/zend-hydrator/composer.json deleted file mode 100644 index 21b4afe0..00000000 --- a/vendor/zendframework/zend-hydrator/composer.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "zendframework/zend-hydrator", - "description": " ", - "license": "BSD-3-Clause", - "keywords": [ - "zf2", - "hydrator" - ], - "homepage": "https://github.com/zendframework/zend-hydrator", - "autoload": { - "psr-4": { - "Zend\\Hydrator\\": "src/" - } - }, - "require": { - "php": ">=5.5", - "zendframework/zend-stdlib": "^2.5.1" - }, - "require-dev": { - "zendframework/zend-eventmanager": "^2.5.1", - "zendframework/zend-inputfilter": "^2.5.1", - "zendframework/zend-serializer": "^2.5.1", - "zendframework/zend-servicemanager": "^2.5.1", - "zendframework/zend-filter": "^2.5.1", - "phpunit/PHPUnit": "~4.0", - "squizlabs/php_codesniffer": "^2.0@dev" - }, - "suggest": { - "zendframework/zend-eventmanager": "^2.5.1, to support aggregate hydrator usage", - "zendframework/zend-serializer": "^2.5.1, to use the SerializableStrategy", - "zendframework/zend-servicemanager": "^2.5.1, to support hydrator plugin manager usage", - "zendframework/zend-filter": "^2.5.1, to support naming strategy hydrator usage" - }, - "minimum-stability": "dev", - "prefer-stable": true, - "extra": { - "branch-alias": { - "dev-master": "1.0-dev", - "dev-develop": "1.1-dev" - } - }, - "autoload-dev": { - "psr-4": { - "ZendTest\\Hydrator\\": "test/" - } - } -} diff --git a/vendor/zendframework/zend-hydrator/phpcs.xml b/vendor/zendframework/zend-hydrator/phpcs.xml deleted file mode 100644 index e994eae1..00000000 --- a/vendor/zendframework/zend-hydrator/phpcs.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - Zend Framework coding standard - - - - - - - - - - - - - - - - src - test - diff --git a/vendor/zendframework/zend-hydrator/src/AbstractHydrator.php b/vendor/zendframework/zend-hydrator/src/AbstractHydrator.php deleted file mode 100644 index 6f3f0a90..00000000 --- a/vendor/zendframework/zend-hydrator/src/AbstractHydrator.php +++ /dev/null @@ -1,283 +0,0 @@ -strategies = new ArrayObject(); - $this->filterComposite = new Filter\FilterComposite(); - } - - /** - * Gets the strategy with the given name. - * - * @param string $name The name of the strategy to get. - * - * @throws Exception\InvalidArgumentException - * @return Strategy\StrategyInterface - */ - public function getStrategy($name) - { - if (isset($this->strategies[$name])) { - return $this->strategies[$name]; - } - - if (!isset($this->strategies['*'])) { - throw new Exception\InvalidArgumentException(sprintf( - '%s: no strategy by name of "%s", and no wildcard strategy present', - __METHOD__, - $name - )); - } - - return $this->strategies['*']; - } - - /** - * Checks if the strategy with the given name exists. - * - * @param string $name The name of the strategy to check for. - * @return bool - */ - public function hasStrategy($name) - { - return array_key_exists($name, $this->strategies) - || array_key_exists('*', $this->strategies); - } - - /** - * Adds the given strategy under the given name. - * - * @param string $name The name of the strategy to register. - * @param Strategy\StrategyInterface $strategy The strategy to register. - * @return HydratorInterface - */ - public function addStrategy($name, Strategy\StrategyInterface $strategy) - { - $this->strategies[$name] = $strategy; - return $this; - } - - /** - * Removes the strategy with the given name. - * - * @param string $name The name of the strategy to remove. - * @return HydratorInterface - */ - public function removeStrategy($name) - { - unset($this->strategies[$name]); - return $this; - } - - /** - * Converts a value for extraction. If no strategy exists the plain value is returned. - * - * @param string $name The name of the strategy to use. - * @param mixed $value The value that should be converted. - * @param mixed $object The object is optionally provided as context. - * @return mixed - */ - public function extractValue($name, $value, $object = null) - { - if ($this->hasStrategy($name)) { - $strategy = $this->getStrategy($name); - $value = $strategy->extract($value, $object); - } - return $value; - } - - /** - * Converts a value for hydration. If no strategy exists the plain value is returned. - * - * @param string $name The name of the strategy to use. - * @param mixed $value The value that should be converted. - * @param array $data The whole data is optionally provided as context. - * @return mixed - */ - public function hydrateValue($name, $value, $data = null) - { - if ($this->hasStrategy($name)) { - $strategy = $this->getStrategy($name); - $value = $strategy->hydrate($value, $data); - } - return $value; - } - - /** - * Convert a name for extraction. If no naming strategy exists, the plain value is returned. - * - * @param string $name The name to convert. - * @param null $object The object is optionally provided as context. - * @return mixed - */ - public function extractName($name, $object = null) - { - if ($this->hasNamingStrategy()) { - $name = $this->getNamingStrategy()->extract($name, $object); - } - return $name; - } - - /** - * Converts a value for hydration. If no naming strategy exists, the plain value is returned. - * - * @param string $name The name to convert. - * @param array $data The whole data is optionally provided as context. - * @return mixed - */ - public function hydrateName($name, $data = null) - { - if ($this->hasNamingStrategy()) { - $name = $this->getNamingStrategy()->hydrate($name, $data); - } - return $name; - } - - /** - * Get the filter instance - * - * @return Filter\FilterComposite - */ - public function getFilter() - { - return $this->filterComposite; - } - - /** - * Add a new filter to take care of what needs to be hydrated. - * To exclude e.g. the method getServiceLocator: - * - * - * $composite->addFilter("servicelocator", - * function ($property) { - * list($class, $method) = explode('::', $property); - * if ($method === 'getServiceLocator') { - * return false; - * } - * return true; - * }, FilterComposite::CONDITION_AND - * ); - * - * - * @param string $name Index in the composite - * @param callable|Filter\FilterInterface $filter - * @param int $condition - * @return Filter\FilterComposite - */ - public function addFilter($name, $filter, $condition = Filter\FilterComposite::CONDITION_OR) - { - return $this->filterComposite->addFilter($name, $filter, $condition); - } - - /** - * Check whether a specific filter exists at key $name or not - * - * @param string $name Index in the composite - * @return bool - */ - public function hasFilter($name) - { - return $this->filterComposite->hasFilter($name); - } - - /** - * Remove a filter from the composition. - * To not extract "has" methods, you simply need to unregister it - * - * - * $filterComposite->removeFilter('has'); - * - * - * @param $name - * @return Filter\FilterComposite - */ - public function removeFilter($name) - { - return $this->filterComposite->removeFilter($name); - } - - /** - * Adds the given naming strategy - * - * @param NamingStrategy\NamingStrategyInterface $strategy The naming to register. - * @return self - */ - public function setNamingStrategy(NamingStrategy\NamingStrategyInterface $strategy) - { - $this->namingStrategy = $strategy; - - return $this; - } - - /** - * Gets the naming strategy. - * - * @return NamingStrategy\NamingStrategyInterface - */ - public function getNamingStrategy() - { - return $this->namingStrategy; - } - - /** - * Checks if a naming strategy exists. - * - * @return bool - */ - public function hasNamingStrategy() - { - return isset($this->namingStrategy); - } - - /** - * Removes the naming strategy - * - * @return self - */ - public function removeNamingStrategy() - { - $this->namingStrategy = null; - - return $this; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Aggregate/AggregateHydrator.php b/vendor/zendframework/zend-hydrator/src/Aggregate/AggregateHydrator.php deleted file mode 100644 index fa384adb..00000000 --- a/vendor/zendframework/zend-hydrator/src/Aggregate/AggregateHydrator.php +++ /dev/null @@ -1,85 +0,0 @@ -getEventManager()->attachAggregate(new HydratorListener($hydrator), $priority); - } - - /** - * {@inheritDoc} - */ - public function extract($object) - { - $event = new ExtractEvent($this, $object); - - $this->getEventManager()->trigger($event); - - return $event->getExtractedData(); - } - - /** - * {@inheritDoc} - */ - public function hydrate(array $data, $object) - { - $event = new HydrateEvent($this, $object, $data); - - $this->getEventManager()->trigger($event); - - return $event->getHydratedObject(); - } - - /** - * {@inheritDoc} - */ - public function setEventManager(EventManagerInterface $eventManager) - { - $eventManager->setIdentifiers([__CLASS__, get_class($this)]); - - $this->eventManager = $eventManager; - } - - /** - * {@inheritDoc} - */ - public function getEventManager() - { - if (null === $this->eventManager) { - $this->setEventManager(new EventManager()); - } - - return $this->eventManager; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Aggregate/ExtractEvent.php b/vendor/zendframework/zend-hydrator/src/Aggregate/ExtractEvent.php deleted file mode 100644 index 13959175..00000000 --- a/vendor/zendframework/zend-hydrator/src/Aggregate/ExtractEvent.php +++ /dev/null @@ -1,98 +0,0 @@ -target = $target; - $this->extractionObject = $extractionObject; - } - - /** - * Retrieves the object from which data is extracted - * - * @return object - */ - public function getExtractionObject() - { - return $this->extractionObject; - } - - /** - * @param object $extractionObject - * - * @return void - */ - public function setExtractionObject($extractionObject) - { - $this->extractionObject = $extractionObject; - } - - /** - * Retrieves the data that has been extracted - * - * @return array - */ - public function getExtractedData() - { - return $this->extractedData; - } - - /** - * @param array $extractedData - * - * @return void - */ - public function setExtractedData(array $extractedData) - { - $this->extractedData = $extractedData; - } - - /** - * Merge provided data with the extracted data - * - * @param array $additionalData - * - * @return void - */ - public function mergeExtractedData(array $additionalData) - { - $this->extractedData = array_merge($this->extractedData, $additionalData); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Aggregate/HydrateEvent.php b/vendor/zendframework/zend-hydrator/src/Aggregate/HydrateEvent.php deleted file mode 100644 index 7865964d..00000000 --- a/vendor/zendframework/zend-hydrator/src/Aggregate/HydrateEvent.php +++ /dev/null @@ -1,84 +0,0 @@ -target = $target; - $this->hydratedObject = $hydratedObject; - $this->hydrationData = $hydrationData; - } - - /** - * Retrieves the object that is being hydrated - * - * @return object - */ - public function getHydratedObject() - { - return $this->hydratedObject; - } - - /** - * @param object $hydratedObject - */ - public function setHydratedObject($hydratedObject) - { - $this->hydratedObject = $hydratedObject; - } - - /** - * Retrieves the data that is being used for hydration - * - * @return array - */ - public function getHydrationData() - { - return $this->hydrationData; - } - - /** - * @param array $hydrationData - */ - public function setHydrationData(array $hydrationData) - { - $this->hydrationData = $hydrationData; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Aggregate/HydratorListener.php b/vendor/zendframework/zend-hydrator/src/Aggregate/HydratorListener.php deleted file mode 100644 index c8260a43..00000000 --- a/vendor/zendframework/zend-hydrator/src/Aggregate/HydratorListener.php +++ /dev/null @@ -1,72 +0,0 @@ -hydrator = $hydrator; - } - - /** - * {@inheritDoc} - */ - public function attach(EventManagerInterface $events, $priority = 1) - { - $this->listeners[] = $events->attach(HydrateEvent::EVENT_HYDRATE, [$this, 'onHydrate'], $priority); - $this->listeners[] = $events->attach(ExtractEvent::EVENT_EXTRACT, [$this, 'onExtract'], $priority); - } - - /** - * Callback to be used when {@see HydrateEvent::EVENT_HYDRATE} is triggered - * - * @param HydrateEvent $event - * @return object - * @internal - */ - public function onHydrate(HydrateEvent $event) - { - $object = $this->hydrator->hydrate($event->getHydrationData(), $event->getHydratedObject()); - $event->setHydratedObject($object); - return $object; - } - - /** - * Callback to be used when {@see ExtractEvent::EVENT_EXTRACT} is triggered - * - * @param ExtractEvent $event - * @return array - * @internal - */ - public function onExtract(ExtractEvent $event) - { - $data = $this->hydrator->extract($event->getExtractionObject()); - $event->mergeExtractedData($data); - return $data; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/ArraySerializable.php b/vendor/zendframework/zend-hydrator/src/ArraySerializable.php deleted file mode 100644 index 24edee5c..00000000 --- a/vendor/zendframework/zend-hydrator/src/ArraySerializable.php +++ /dev/null @@ -1,81 +0,0 @@ -getArrayCopy(); - $filter = $this->getFilter(); - - foreach ($data as $name => $value) { - if (!$filter->filter($name)) { - unset($data[$name]); - continue; - } - $extractedName = $this->extractName($name, $object); - // replace the original key with extracted, if differ - if ($extractedName !== $name) { - unset($data[$name]); - $name = $extractedName; - } - $data[$name] = $this->extractValue($name, $value, $object); - } - - return $data; - } - - /** - * Hydrate an object - * - * Hydrates an object by passing $data to either its exchangeArray() or - * populate() method. - * - * @param array $data - * @param object $object - * @return object - * @throws Exception\BadMethodCallException for an $object not implementing exchangeArray() or populate() - */ - public function hydrate(array $data, $object) - { - $replacement = []; - foreach ($data as $key => $value) { - $name = $this->hydrateName($key, $data); - $replacement[$name] = $this->hydrateValue($name, $value, $data); - } - - if (is_callable([$object, 'exchangeArray'])) { - $object->exchangeArray($replacement); - } elseif (is_callable([$object, 'populate'])) { - $object->populate($replacement); - } else { - throw new Exception\BadMethodCallException( - sprintf('%s expects the provided object to implement exchangeArray() or populate()', __METHOD__) - ); - } - return $object; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/ClassMethods.php b/vendor/zendframework/zend-hydrator/src/ClassMethods.php deleted file mode 100644 index 80cce848..00000000 --- a/vendor/zendframework/zend-hydrator/src/ClassMethods.php +++ /dev/null @@ -1,268 +0,0 @@ -setUnderscoreSeparatedKeys($underscoreSeparatedKeys); - - $this->callableMethodFilter = new Filter\OptionalParametersFilter(); - - $this->filterComposite->addFilter('is', new Filter\IsFilter()); - $this->filterComposite->addFilter('has', new Filter\HasFilter()); - $this->filterComposite->addFilter('get', new Filter\GetFilter()); - $this->filterComposite->addFilter( - 'parameter', - new Filter\OptionalParametersFilter(), - Filter\FilterComposite::CONDITION_AND - ); - } - - /** - * @param array|Traversable $options - * @return ClassMethods - * @throws Exception\InvalidArgumentException - */ - public function setOptions($options) - { - if ($options instanceof Traversable) { - $options = ArrayUtils::iteratorToArray($options); - } elseif (!is_array($options)) { - throw new Exception\InvalidArgumentException( - 'The options parameter must be an array or a Traversable' - ); - } - if (isset($options['underscoreSeparatedKeys'])) { - $this->setUnderscoreSeparatedKeys($options['underscoreSeparatedKeys']); - } - - return $this; - } - - /** - * @param bool $underscoreSeparatedKeys - * @return ClassMethods - */ - public function setUnderscoreSeparatedKeys($underscoreSeparatedKeys) - { - $this->underscoreSeparatedKeys = (bool) $underscoreSeparatedKeys; - - if ($this->underscoreSeparatedKeys) { - $this->setNamingStrategy(new NamingStrategy\UnderscoreNamingStrategy); - } elseif ($this->getNamingStrategy() instanceof NamingStrategy\UnderscoreNamingStrategy) { - $this->removeNamingStrategy(); - } - - return $this; - } - - /** - * @return bool - */ - public function getUnderscoreSeparatedKeys() - { - return $this->underscoreSeparatedKeys; - } - - /** - * Extract values from an object with class methods - * - * Extracts the getter/setter of the given $object. - * - * @param object $object - * @return array - * @throws Exception\BadMethodCallException for a non-object $object - */ - public function extract($object) - { - if (!is_object($object)) { - throw new Exception\BadMethodCallException(sprintf( - '%s expects the provided $object to be a PHP object)', - __METHOD__ - )); - } - - $objectClass = get_class($object); - - // reset the hydrator's hydrator's cache for this object, as the filter may be per-instance - if ($object instanceof Filter\FilterProviderInterface) { - $this->extractionMethodsCache[$objectClass] = null; - } - - // pass 1 - finding out which properties can be extracted, with which methods (populate hydration cache) - if (! isset($this->extractionMethodsCache[$objectClass])) { - $this->extractionMethodsCache[$objectClass] = []; - $filter = $this->filterComposite; - $methods = get_class_methods($object); - - if ($object instanceof Filter\FilterProviderInterface) { - $filter = new Filter\FilterComposite( - [$object->getFilter()], - [new Filter\MethodMatchFilter('getFilter')] - ); - } - - foreach ($methods as $method) { - $methodFqn = $objectClass . '::' . $method; - - if (! ($filter->filter($methodFqn) && $this->callableMethodFilter->filter($methodFqn))) { - continue; - } - - $attribute = $method; - - if (strpos($method, 'get') === 0) { - $attribute = substr($method, 3); - if (!property_exists($object, $attribute)) { - $attribute = lcfirst($attribute); - } - } - - $this->extractionMethodsCache[$objectClass][$method] = $attribute; - } - } - - $values = []; - - // pass 2 - actually extract data - foreach ($this->extractionMethodsCache[$objectClass] as $methodName => $attributeName) { - $realAttributeName = $this->extractName($attributeName, $object); - $values[$realAttributeName] = $this->extractValue($realAttributeName, $object->$methodName(), $object); - } - - return $values; - } - - /** - * Hydrate an object by populating getter/setter methods - * - * Hydrates an object by getter/setter methods of the object. - * - * @param array $data - * @param object $object - * @return object - * @throws Exception\BadMethodCallException for a non-object $object - */ - public function hydrate(array $data, $object) - { - if (!is_object($object)) { - throw new Exception\BadMethodCallException(sprintf( - '%s expects the provided $object to be a PHP object)', - __METHOD__ - )); - } - - $objectClass = get_class($object); - - foreach ($data as $property => $value) { - $propertyFqn = $objectClass . '::$' . $property; - - if (! isset($this->hydrationMethodsCache[$propertyFqn])) { - $setterName = 'set' . ucfirst($this->hydrateName($property, $data)); - - $this->hydrationMethodsCache[$propertyFqn] = is_callable([$object, $setterName]) - ? $setterName - : false; - } - - if ($this->hydrationMethodsCache[$propertyFqn]) { - $object->{$this->hydrationMethodsCache[$propertyFqn]}($this->hydrateValue($property, $value, $data)); - } - } - - return $object; - } - - /** - * {@inheritDoc} - */ - public function addFilter($name, $filter, $condition = Filter\FilterComposite::CONDITION_OR) - { - $this->resetCaches(); - - return parent::addFilter($name, $filter, $condition); - } - - /** - * {@inheritDoc} - */ - public function removeFilter($name) - { - $this->resetCaches(); - - return parent::removeFilter($name); - } - - /** - * {@inheritDoc} - */ - public function setNamingStrategy(NamingStrategy\NamingStrategyInterface $strategy) - { - $this->resetCaches(); - - return parent::setNamingStrategy($strategy); - } - - /** - * {@inheritDoc} - */ - public function removeNamingStrategy() - { - $this->resetCaches(); - - return parent::removeNamingStrategy(); - } - - /** - * Reset all local hydration/extraction caches - */ - private function resetCaches() - { - $this->hydrationMethodsCache = $this->extractionMethodsCache = []; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/DelegatingHydrator.php b/vendor/zendframework/zend-hydrator/src/DelegatingHydrator.php deleted file mode 100644 index a6f3f947..00000000 --- a/vendor/zendframework/zend-hydrator/src/DelegatingHydrator.php +++ /dev/null @@ -1,57 +0,0 @@ -hydrators = $hydrators; - } - - /** - * {@inheritdoc} - */ - public function hydrate(array $data, $object) - { - return $this->getHydrator($object)->hydrate($data, $object); - } - - /** - * {@inheritdoc} - */ - public function extract($object) - { - return $this->getHydrator($object)->extract($object); - } - - /** - * Gets hydrator of an object - * - * @param object $object - * @return HydratorInterface - */ - protected function getHydrator($object) - { - return $this->hydrators->get(get_class($object)); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/DelegatingHydratorFactory.php b/vendor/zendframework/zend-hydrator/src/DelegatingHydratorFactory.php deleted file mode 100644 index 89f28417..00000000 --- a/vendor/zendframework/zend-hydrator/src/DelegatingHydratorFactory.php +++ /dev/null @@ -1,29 +0,0 @@ -orFilter = new ArrayObject($orFilter); - $this->andFilter = new ArrayObject($andFilter); - } - - /** - * Add a filter to the composite. Has to be indexed with $name in - * order to identify a specific filter. - * - * This example will exclude all methods from the hydration, that starts with 'getService' - * - * $composite->addFilter('exclude', - * function ($method) { - * if (preg_match('/^getService/', $method) { - * return false; - * } - * return true; - * }, FilterComposite::CONDITION_AND - * ); - * - * - * @param string $name - * @param callable|FilterInterface $filter - * @param int $condition Can be either - * FilterComposite::CONDITION_OR or FilterComposite::CONDITION_AND - * @throws InvalidArgumentException - * @return FilterComposite - */ - public function addFilter($name, $filter, $condition = self::CONDITION_OR) - { - if (!is_callable($filter) && !($filter instanceof FilterInterface)) { - throw new InvalidArgumentException( - 'The value of ' . $name . ' should be either a callable or ' . - 'an instance of Zend\Stdlib\Hydrator\Filter\FilterInterface' - ); - } - - if ($condition === self::CONDITION_OR) { - $this->orFilter[$name] = $filter; - } elseif ($condition === self::CONDITION_AND) { - $this->andFilter[$name] = $filter; - } - - return $this; - } - - /** - * Remove a filter from the composition - * - * @param $name string Identifier for the filter - * @return FilterComposite - */ - public function removeFilter($name) - { - if (isset($this->orFilter[$name])) { - unset($this->orFilter[$name]); - } - - if (isset($this->andFilter[$name])) { - unset($this->andFilter[$name]); - } - - return $this; - } - - /** - * Check if $name has a filter registered - * - * @param $name string Identifier for the filter - * @return bool - */ - public function hasFilter($name) - { - return isset($this->orFilter[$name]) || isset($this->andFilter[$name]); - } - - /** - * Filter the composite based on the AND and OR condition - * Will return true if one from the "or conditions" and all from - * the "and condition" returns true. Otherwise false - * - * @param $property string Parameter will be e.g. Parent\Namespace\Class::method - * @return bool - */ - public function filter($property) - { - $andCount = count($this->andFilter); - $orCount = count($this->orFilter); - // return true if no filters are registered - if ($orCount === 0 && $andCount === 0) { - return true; - } elseif ($orCount === 0 && $andCount !== 0) { - $returnValue = true; - } else { - $returnValue = false; - } - - // Check if 1 from the or filters return true - foreach ($this->orFilter as $filter) { - if (is_callable($filter)) { - if ($filter($property) === true) { - $returnValue = true; - break; - } - continue; - } else { - if ($filter->filter($property) === true) { - $returnValue = true; - break; - } - } - } - - // Check if all of the and condition return true - foreach ($this->andFilter as $filter) { - if (is_callable($filter)) { - if ($filter($property) === false) { - return false; - } - continue; - } else { - if ($filter->filter($property) === false) { - return false; - } - } - } - - return $returnValue; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Filter/FilterInterface.php b/vendor/zendframework/zend-hydrator/src/Filter/FilterInterface.php deleted file mode 100644 index fb49918f..00000000 --- a/vendor/zendframework/zend-hydrator/src/Filter/FilterInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -method = $method; - $this->exclude = $exclude; - } - - public function filter($property) - { - $pos = strpos($property, '::'); - if ($pos !== false) { - $pos += 2; - } else { - $pos = 0; - } - if (substr($property, $pos) === $this->method) { - return !$this->exclude; - } - return $this->exclude; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Filter/NumberOfParameterFilter.php b/vendor/zendframework/zend-hydrator/src/Filter/NumberOfParameterFilter.php deleted file mode 100644 index abd8ee67..00000000 --- a/vendor/zendframework/zend-hydrator/src/Filter/NumberOfParameterFilter.php +++ /dev/null @@ -1,49 +0,0 @@ -numberOfParameters = (int) $numberOfParameters; - } - - /** - * @param string $property the name of the property - * @return bool - * @throws InvalidArgumentException - */ - public function filter($property) - { - try { - $reflectionMethod = new ReflectionMethod($property); - } catch (ReflectionException $exception) { - throw new InvalidArgumentException( - "Method $property doesn't exist" - ); - } - - return $reflectionMethod->getNumberOfParameters() === $this->numberOfParameters; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Filter/OptionalParametersFilter.php b/vendor/zendframework/zend-hydrator/src/Filter/OptionalParametersFilter.php deleted file mode 100644 index 25775d7e..00000000 --- a/vendor/zendframework/zend-hydrator/src/Filter/OptionalParametersFilter.php +++ /dev/null @@ -1,55 +0,0 @@ -getParameters(), - function (ReflectionParameter $parameter) { - return ! $parameter->isOptional(); - } - ); - - return static::$propertiesCache[$property] = empty($mandatoryParameters); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/FilterEnabledInterface.php b/vendor/zendframework/zend-hydrator/src/FilterEnabledInterface.php deleted file mode 100644 index f95f8b4b..00000000 --- a/vendor/zendframework/zend-hydrator/src/FilterEnabledInterface.php +++ /dev/null @@ -1,59 +0,0 @@ - - * $composite->addFilter( - * "servicelocator", - * function ($property) { - * list($class, $method) = explode('::', $property); - * if ($method === 'getServiceLocator') { - * return false; - * } - * return true; - * }, - * FilterComposite::CONDITION_AND - * ); - * - * - * @param string $name Index in the composite - * @param callable|Filter\FilterInterface $filter - * @param int $condition - * @return Filter\FilterComposite - */ - public function addFilter($name, $filter, $condition = Filter\FilterComposite::CONDITION_OR); - - /** - * Check whether a specific filter exists at key $name or not - * - * @param string $name Index in the composite - * @return bool - */ - public function hasFilter($name); - - /** - * Remove a filter from the composition. - * To not extract "has" methods, you simply need to unregister it - * - * - * $filterComposite->removeFilter('has'); - * - * - * @param $name - * @return Filter\FilterComposite - */ - public function removeFilter($name); -} diff --git a/vendor/zendframework/zend-hydrator/src/HydrationInterface.php b/vendor/zendframework/zend-hydrator/src/HydrationInterface.php deleted file mode 100644 index ca289834..00000000 --- a/vendor/zendframework/zend-hydrator/src/HydrationInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -hydrator = $hydrator; - - return $this; - } - - /** - * Retrieve hydrator - * - * @param void - * @return null|HydratorInterface - * @access public - */ - public function getHydrator() - { - return $this->hydrator; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/HydratorInterface.php b/vendor/zendframework/zend-hydrator/src/HydratorInterface.php deleted file mode 100644 index a48effa8..00000000 --- a/vendor/zendframework/zend-hydrator/src/HydratorInterface.php +++ /dev/null @@ -1,14 +0,0 @@ - 'Zend\Hydrator\DelegatingHydrator', - ]; - - /** - * Default set of adapters - * - * @var array - */ - protected $invokableClasses = [ - 'arrayserializable' => 'Zend\Hydrator\ArraySerializable', - 'classmethods' => 'Zend\Hydrator\ClassMethods', - 'objectproperty' => 'Zend\Hydrator\ObjectProperty', - 'reflection' => 'Zend\Hydrator\Reflection' - ]; - - /** - * Default factory-based adapters - * - * @var array - */ - protected $factories = [ - 'Zend\Hydrator\DelegatingHydrator' => 'Zend\Hydrator\DelegatingHydratorFactory', - ]; - - /** - * {@inheritDoc} - */ - public function validatePlugin($plugin) - { - if ($plugin instanceof HydratorInterface) { - // we're okay - return; - } - - throw new Exception\RuntimeException(sprintf( - 'Plugin of type %s is invalid; must implement Zend\Hydrator\HydratorInterface', - (is_object($plugin) ? get_class($plugin) : gettype($plugin)) - )); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Iterator/HydratingArrayIterator.php b/vendor/zendframework/zend-hydrator/src/Iterator/HydratingArrayIterator.php deleted file mode 100644 index 8e14f035..00000000 --- a/vendor/zendframework/zend-hydrator/src/Iterator/HydratingArrayIterator.php +++ /dev/null @@ -1,36 +0,0 @@ -setHydrator($hydrator); - $this->setPrototype($prototype); - parent::__construct($data); - } - - /** - * @inheritdoc - */ - public function setPrototype($prototype) - { - if (is_object($prototype)) { - $this->prototype = $prototype; - return; - } - - if (!class_exists($prototype)) { - throw new InvalidArgumentException( - sprintf('Method %s was passed an invalid class name: %s', __METHOD__, $prototype) - ); - } - - $this->prototype = new $prototype; - } - - /** - * @inheritdoc - */ - public function setHydrator(HydratorInterface $hydrator) - { - $this->hydrator = $hydrator; - } - - /** - * @return object Returns hydrated clone of $prototype - */ - public function current() - { - $currentValue = parent::current(); - $object = clone $this->prototype; - $this->hydrator->hydrate($currentValue, $object); - return $object; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/NamingStrategy/ArrayMapNamingStrategy.php b/vendor/zendframework/zend-hydrator/src/NamingStrategy/ArrayMapNamingStrategy.php deleted file mode 100644 index c6333e2d..00000000 --- a/vendor/zendframework/zend-hydrator/src/NamingStrategy/ArrayMapNamingStrategy.php +++ /dev/null @@ -1,51 +0,0 @@ -extractionMap = $extractionMap; - $this->hydrationMap = array_flip($extractionMap); - } - - /** - * {@inheritDoc} - */ - public function hydrate($name) - { - return isset($this->hydrationMap[$name]) ? $this->hydrationMap[$name] : $name; - } - - /** - * {@inheritDoc} - */ - public function extract($name) - { - return isset($this->extractionMap[$name]) ? $this->extractionMap[$name] : $name; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/NamingStrategy/CompositeNamingStrategy.php b/vendor/zendframework/zend-hydrator/src/NamingStrategy/CompositeNamingStrategy.php deleted file mode 100644 index c2bae8c2..00000000 --- a/vendor/zendframework/zend-hydrator/src/NamingStrategy/CompositeNamingStrategy.php +++ /dev/null @@ -1,64 +0,0 @@ -namingStrategies = array_map( - function (NamingStrategyInterface $strategy) { - // this callback is here only to ensure type-safety - return $strategy; - }, - $strategies - ); - - $this->defaultNamingStrategy = $defaultNamingStrategy ?: new IdentityNamingStrategy(); - } - - /** - * {@inheritDoc} - */ - public function extract($name) - { - $strategy = isset($this->namingStrategies[$name]) - ? $this->namingStrategies[$name] - : $this->defaultNamingStrategy; - - return $strategy->extract($name); - } - - /** - * {@inheritDoc} - */ - public function hydrate($name) - { - $strategy = isset($this->namingStrategies[$name]) - ? $this->namingStrategies[$name] - : $this->defaultNamingStrategy; - - return $strategy->hydrate($name); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/NamingStrategy/IdentityNamingStrategy.php b/vendor/zendframework/zend-hydrator/src/NamingStrategy/IdentityNamingStrategy.php deleted file mode 100644 index 59e3feda..00000000 --- a/vendor/zendframework/zend-hydrator/src/NamingStrategy/IdentityNamingStrategy.php +++ /dev/null @@ -1,29 +0,0 @@ -mapping = $mapping; - $this->reverse = $reverse ?: $this->flipMapping($mapping); - } - - /** - * Safelly flip mapping array. - * - * @param array $array Array to flip - * @return array Flipped array - * @throws InvalidArgumentException - */ - protected function flipMapping(array $array) - { - array_walk($array, function ($value) { - if (!is_string($value) && !is_int($value)) { - throw new InvalidArgumentException('Mapping array can\'t be flipped because of invalid value'); - } - }); - - return array_flip($array); - } - - /** - * Converts the given name so that it can be extracted by the hydrator. - * - * @param string $name The original name - * @return mixed The hydrated name - */ - public function hydrate($name) - { - if (array_key_exists($name, $this->mapping)) { - return $this->mapping[$name]; - } - - return $name; - } - - /** - * Converts the given name so that it can be hydrated by the hydrator. - * - * @param string $name The original name - * @return mixed The extracted name - */ - public function extract($name) - { - if (array_key_exists($name, $this->reverse)) { - return $this->reverse[$name]; - } - - return $name; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/NamingStrategy/NamingStrategyInterface.php b/vendor/zendframework/zend-hydrator/src/NamingStrategy/NamingStrategyInterface.php deleted file mode 100644 index cb7ca94e..00000000 --- a/vendor/zendframework/zend-hydrator/src/NamingStrategy/NamingStrategyInterface.php +++ /dev/null @@ -1,34 +0,0 @@ -getUnderscoreToStudlyCaseFilter()->filter($name); - } - - /** - * Remove capitalized letters and prepend underscores. - * - * @param string $name - * @return string - */ - public function extract($name) - { - return $this->getCamelCaseToUnderscoreFilter()->filter($name); - } - - /** - * @return FilterChain - */ - protected function getUnderscoreToStudlyCaseFilter() - { - if (static::$underscoreToStudlyCaseFilter instanceof FilterChain) { - return static::$underscoreToStudlyCaseFilter; - } - - $filter = new FilterChain(); - - $filter->attachByName('WordUnderscoreToStudlyCase'); - - return static::$underscoreToStudlyCaseFilter = $filter; - } - - /** - * @return FilterChain - */ - protected function getCamelCaseToUnderscoreFilter() - { - if (static::$camelCaseToUnderscoreFilter instanceof FilterChain) { - return static::$camelCaseToUnderscoreFilter; - } - - $filter = new FilterChain(); - - $filter->attachByName('WordCamelCaseToUnderscore'); - $filter->attachByName('StringToLower'); - - return static::$camelCaseToUnderscoreFilter = $filter; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/NamingStrategyEnabledInterface.php b/vendor/zendframework/zend-hydrator/src/NamingStrategyEnabledInterface.php deleted file mode 100644 index c01a5272..00000000 --- a/vendor/zendframework/zend-hydrator/src/NamingStrategyEnabledInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -getFilter(); - - foreach ($data as $name => $value) { - // Filter keys, removing any we don't want - if (! $filter->filter($name)) { - unset($data[$name]); - continue; - } - - // Replace name if extracted differ - $extracted = $this->extractName($name, $object); - - if ($extracted !== $name) { - unset($data[$name]); - $name = $extracted; - } - - $data[$name] = $this->extractValue($name, $value, $object); - } - - return $data; - } - - /** - * {@inheritDoc} - * - * Hydrate an object by populating public properties - * - * Hydrates an object by setting public properties of the object. - * - * @throws Exception\BadMethodCallException for a non-object $object - */ - public function hydrate(array $data, $object) - { - if (!is_object($object)) { - throw new Exception\BadMethodCallException( - sprintf('%s expects the provided $object to be a PHP object)', __METHOD__) - ); - } - - $properties = & self::$skippedPropertiesCache[get_class($object)]; - - if (! isset($properties)) { - $reflection = new ReflectionClass($object); - $properties = array_fill_keys( - array_map( - function (ReflectionProperty $property) { - return $property->getName(); - }, - $reflection->getProperties( - ReflectionProperty::IS_PRIVATE - + ReflectionProperty::IS_PROTECTED - + ReflectionProperty::IS_STATIC - ) - ), - true - ); - } - - foreach ($data as $name => $value) { - $property = $this->hydrateName($name, $data); - - if (isset($properties[$property])) { - continue; - } - - $object->$property = $this->hydrateValue($property, $value, $data); - } - - return $object; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Reflection.php b/vendor/zendframework/zend-hydrator/src/Reflection.php deleted file mode 100644 index 019748b1..00000000 --- a/vendor/zendframework/zend-hydrator/src/Reflection.php +++ /dev/null @@ -1,95 +0,0 @@ -extractName($property->getName(), $object); - if (!$this->filterComposite->filter($propertyName)) { - continue; - } - - $value = $property->getValue($object); - $result[$propertyName] = $this->extractValue($propertyName, $value, $object); - } - - return $result; - } - - /** - * Hydrate $object with the provided $data. - * - * @param array $data - * @param object $object - * @return object - */ - public function hydrate(array $data, $object) - { - $reflProperties = self::getReflProperties($object); - foreach ($data as $key => $value) { - $name = $this->hydrateName($key, $data); - if (isset($reflProperties[$name])) { - $reflProperties[$name]->setValue($object, $this->hydrateValue($name, $value, $data)); - } - } - return $object; - } - - /** - * Get a reflection properties from in-memory cache and lazy-load if - * class has not been loaded. - * - * @param string|object $input - * @throws Exception\InvalidArgumentException - * @return ReflectionProperty[] - */ - protected static function getReflProperties($input) - { - if (is_object($input)) { - $input = get_class($input); - } elseif (!is_string($input)) { - throw new Exception\InvalidArgumentException('Input must be a string or an object.'); - } - - if (isset(static::$reflProperties[$input])) { - return static::$reflProperties[$input]; - } - - static::$reflProperties[$input] = []; - $reflClass = new ReflectionClass($input); - $reflProperties = $reflClass->getProperties(); - - foreach ($reflProperties as $property) { - $property->setAccessible(true); - static::$reflProperties[$input][$property->getName()] = $property; - } - - return static::$reflProperties[$input]; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/BooleanStrategy.php b/vendor/zendframework/zend-hydrator/src/Strategy/BooleanStrategy.php deleted file mode 100644 index dcb3a429..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/BooleanStrategy.php +++ /dev/null @@ -1,104 +0,0 @@ -trueValue = $trueValue; - $this->falseValue = $falseValue; - } - - /** - * Converts the given value so that it can be extracted by the hydrator. - * - * @param bool $value The original value. - * @throws InvalidArgumentException - * @return int|string Returns the value that should be extracted. - */ - public function extract($value) - { - if (!is_bool($value)) { - throw new InvalidArgumentException(sprintf( - 'Unable to extract. Expected bool. %s was given.', - is_object($value) ? get_class($value) : gettype($value) - )); - } - - return $value === true ? $this->trueValue : $this->falseValue; - } - - /** - * Converts the given value so that it can be hydrated by the hydrator. - * - * @param int|string $value The original value. - * @throws InvalidArgumentException - * @return bool Returns the value that should be hydrated. - */ - public function hydrate($value) - { - if (!is_string($value) && !is_int($value)) { - throw new InvalidArgumentException(sprintf( - 'Unable to hydrate. Expected string or int. %s was given.', - is_object($value) ? get_class($value) : gettype($value) - )); - } - - if ($value === $this->trueValue) { - return true; - } - - if ($value === $this->falseValue) { - return false; - } - - throw new InvalidArgumentException(sprintf( - 'Unexpected value %s can\'t be hydrated. Expect %s or %s as Value.', - $value, - $this->trueValue, - $this->falseValue - )); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/ClosureStrategy.php b/vendor/zendframework/zend-hydrator/src/Strategy/ClosureStrategy.php deleted file mode 100644 index 1f6526de..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/ClosureStrategy.php +++ /dev/null @@ -1,113 +0,0 @@ - - * function ($value) { - * return $value; - * }; - * - * - * @var callable - */ - protected $extractFunc = null; - - /** - * Function, used in hydrate method, default: - * - * - * function ($value) { - * return $value; - * }; - * - * - * @var callable - */ - protected $hydrateFunc = null; - - /** - * You can describe how your values will extract and hydrate, like this: - * - * - * $hydrator->addStrategy('category', new ClosureStrategy( - * function (Category $value) { - * return (int) $value->id; - * }, - * function ($value) { - * return new Category((int) $value); - * } - * )); - * - * - * @param callable $extractFunc - anonymous function, that extract values - * from object - * @param callable $hydrateFunc - anonymous function, that hydrate values - * into object - */ - public function __construct($extractFunc = null, $hydrateFunc = null) - { - if (isset($extractFunc)) { - if (!is_callable($extractFunc)) { - throw new \Exception('$extractFunc must be callable'); - } - - $this->extractFunc = $extractFunc; - } else { - $this->extractFunc = function ($value) { - return $value; - }; - } - - if (isset($hydrateFunc)) { - if (!is_callable($hydrateFunc)) { - throw new \Exception('$hydrateFunc must be callable'); - } - - $this->hydrateFunc = $hydrateFunc; - } else { - $this->hydrateFunc = function ($value) { - return $value; - }; - } - } - - /** - * Converts the given value so that it can be extracted by the hydrator. - * - * @param mixed $value The original value. - * @param array $object The object is optionally provided as context. - * @return mixed Returns the value that should be extracted. - */ - public function extract($value, $object = null) - { - $func = $this->extractFunc; - - return $func($value, $object); - } - - /** - * Converts the given value so that it can be hydrated by the hydrator. - * - * @param mixed $value The original value. - * @param array $data The whole data is optionally provided as context. - * @return mixed Returns the value that should be hydrated. - */ - public function hydrate($value, $data = null) - { - $func = $this->hydrateFunc; - - return $func($value, $data); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/DateTimeFormatterStrategy.php b/vendor/zendframework/zend-hydrator/src/Strategy/DateTimeFormatterStrategy.php deleted file mode 100644 index 62dda714..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/DateTimeFormatterStrategy.php +++ /dev/null @@ -1,80 +0,0 @@ -format = (string) $format; - $this->timezone = $timezone; - } - - /** - * {@inheritDoc} - * - * Converts to date time string - * - * @param mixed|DateTime $value - * - * @return mixed|string - */ - public function extract($value) - { - if ($value instanceof DateTime) { - return $value->format($this->format); - } - - return $value; - } - - /** - * Converts date time string to DateTime instance for injecting to object - * - * {@inheritDoc} - * - * @param mixed|string $value - * - * @return mixed|DateTime - */ - public function hydrate($value) - { - if ($value === '' || $value === null) { - return; - } - - if ($this->timezone) { - $hydrated = DateTime::createFromFormat($this->format, $value, $this->timezone); - } else { - $hydrated = DateTime::createFromFormat($this->format, $value); - } - - return $hydrated ?: $value; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/DefaultStrategy.php b/vendor/zendframework/zend-hydrator/src/Strategy/DefaultStrategy.php deleted file mode 100644 index 6fb8f458..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/DefaultStrategy.php +++ /dev/null @@ -1,35 +0,0 @@ -setValueDelimiter($delimiter); - - $this->explodeLimit = ($explodeLimit === null) ? null : (int) $explodeLimit; - } - - /** - * Sets the delimiter string that the values will be split upon - * - * @param string $delimiter - * @return self - */ - private function setValueDelimiter($delimiter) - { - if (!is_string($delimiter)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects Delimiter to be string, %s provided instead', - __METHOD__, - is_object($delimiter) ? get_class($delimiter) : gettype($delimiter) - )); - } - - if (empty($delimiter)) { - throw new Exception\InvalidArgumentException('Delimiter cannot be empty.'); - } - - $this->valueDelimiter = $delimiter; - } - - /** - * {@inheritDoc} - * - * Split a string by delimiter - * - * @param string|null $value - * - * @return string[] - * - * @throws Exception\InvalidArgumentException - */ - public function hydrate($value) - { - if (null === $value) { - return []; - } - - if (!(is_string($value) || is_numeric($value))) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects argument 1 to be string, %s provided instead', - __METHOD__, - is_object($value) ? get_class($value) : gettype($value) - )); - } - - if ($this->explodeLimit !== null) { - return explode($this->valueDelimiter, $value, $this->explodeLimit); - } - - return explode($this->valueDelimiter, $value); - } - - /** - * {@inheritDoc} - * - * Join array elements with delimiter - * - * @param string[] $value The original value. - * - * @return string|null - */ - public function extract($value) - { - if (!is_array($value)) { - throw new Exception\InvalidArgumentException(sprintf( - '%s expects argument 1 to be array, %s provided instead', - __METHOD__, - is_object($value) ? get_class($value) : gettype($value) - )); - } - - return empty($value) ? null : implode($this->valueDelimiter, $value); - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/SerializableStrategy.php b/vendor/zendframework/zend-hydrator/src/Strategy/SerializableStrategy.php deleted file mode 100644 index bc49e7b2..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/SerializableStrategy.php +++ /dev/null @@ -1,123 +0,0 @@ -setSerializer($serializer); - if ($serializerOptions) { - $this->setSerializerOptions($serializerOptions); - } - } - - /** - * Serialize the given value so that it can be extracted by the hydrator. - * - * @param mixed $value The original value. - * @return mixed Returns the value that should be extracted. - */ - public function extract($value) - { - $serializer = $this->getSerializer(); - return $serializer->serialize($value); - } - - /** - * Unserialize the given value so that it can be hydrated by the hydrator. - * - * @param mixed $value The original value. - * @return mixed Returns the value that should be hydrated. - */ - public function hydrate($value) - { - $serializer = $this->getSerializer(); - return $serializer->unserialize($value); - } - - /** - * Set serializer - * - * @param string|SerializerAdapter $serializer - * @return SerializableStrategy - */ - public function setSerializer($serializer) - { - if (!is_string($serializer) && !$serializer instanceof SerializerAdapter) { - throw new InvalidArgumentException(sprintf( - '%s expects either a string serializer name or Zend\Serializer\Adapter\AdapterInterface instance; ' - . 'received "%s"', - __METHOD__, - (is_object($serializer) ? get_class($serializer) : gettype($serializer)) - )); - } - $this->serializer = $serializer; - return $this; - } - - /** - * Get serializer - * - * @return SerializerAdapter - */ - public function getSerializer() - { - if (is_string($this->serializer)) { - $options = $this->getSerializerOptions(); - $this->setSerializer(SerializerFactory::factory($this->serializer, $options)); - } elseif (null === $this->serializer) { - $this->setSerializer(SerializerFactory::getDefaultAdapter()); - } - - return $this->serializer; - } - - /** - * Set configuration options for instantiating a serializer adapter - * - * @param mixed $serializerOptions - * @return SerializableStrategy - */ - public function setSerializerOptions($serializerOptions) - { - $this->serializerOptions = $serializerOptions; - return $this; - } - - /** - * Get configuration options for instantiating a serializer adapter - * - * @return mixed - */ - public function getSerializerOptions() - { - return $this->serializerOptions; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/StrategyChain.php b/vendor/zendframework/zend-hydrator/src/Strategy/StrategyChain.php deleted file mode 100644 index 49d514d3..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/StrategyChain.php +++ /dev/null @@ -1,73 +0,0 @@ -extractionStrategies = array_map( - function (StrategyInterface $strategy) { - // this callback is here only to ensure type-safety - return $strategy; - }, - $extractionStrategies - ); - - $this->hydrationStrategies = array_reverse($extractionStrategies); - } - - /** - * {@inheritDoc} - */ - public function extract($value) - { - foreach ($this->extractionStrategies as $strategy) { - $value = $strategy->extract($value); - } - - return $value; - } - - /** - * {@inheritDoc} - */ - public function hydrate($value) - { - foreach ($this->hydrationStrategies as $strategy) { - $value = $strategy->hydrate($value); - } - - return $value; - } -} diff --git a/vendor/zendframework/zend-hydrator/src/Strategy/StrategyInterface.php b/vendor/zendframework/zend-hydrator/src/Strategy/StrategyInterface.php deleted file mode 100644 index a7055933..00000000 --- a/vendor/zendframework/zend-hydrator/src/Strategy/StrategyInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - ``` + + +## Conduct + +Please see our [CONDUCT.md](CONDUCT.md) to understand expected behavior when interacting with others in the project. diff --git a/vendor/zendframework/zend-stdlib/README.md b/vendor/zendframework/zend-stdlib/README.md index d87d00c9..f4ca9532 100644 --- a/vendor/zendframework/zend-stdlib/README.md +++ b/vendor/zendframework/zend-stdlib/README.md @@ -7,7 +7,6 @@ class for different scopes like: - array utilities functions; -- hydrators; - json serializable interfaces; - general messaging systems; - string wrappers; diff --git a/vendor/zendframework/zend-stdlib/composer.json b/vendor/zendframework/zend-stdlib/composer.json index 4a5ecd55..46f6af00 100644 --- a/vendor/zendframework/zend-stdlib/composer.json +++ b/vendor/zendframework/zend-stdlib/composer.json @@ -13,32 +13,17 @@ } }, "require": { - "php": ">=5.5", - "zendframework/zend-hydrator": "~1.0" + "php": "^5.5 || ^7.0" }, "require-dev": { - "zendframework/zend-config": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-servicemanager": "~2.5", - "zendframework/zend-filter": "~2.5", "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0", "athletic/athletic": "~0.1" }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage", - "zendframework/zend-filter": "To support naming strategy hydrator usage" - }, - "minimum-stability": "dev", - "prefer-stable": true, "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "3.0-dev", + "dev-develop": "3.1-dev" } }, "autoload-dev": { diff --git a/vendor/zendframework/zend-stdlib/doc/book/index.html b/vendor/zendframework/zend-stdlib/doc/book/index.html new file mode 100644 index 00000000..f4b09ab4 --- /dev/null +++ b/vendor/zendframework/zend-stdlib/doc/book/index.html @@ -0,0 +1,10 @@ +
    +
    +

    zend-stdlib

    + +

    SPL extensions, array utilities, error handlers, and more.

    + +
    $ composer require zendframework/zend-stdlib
    +
    +
    + diff --git a/vendor/zendframework/zend-stdlib/doc/book/index.md b/vendor/zendframework/zend-stdlib/doc/book/index.md new file mode 100644 index 00000000..f4ca9532 --- /dev/null +++ b/vendor/zendframework/zend-stdlib/doc/book/index.md @@ -0,0 +1,18 @@ +# zend-stdlib + +[![Build Status](https://secure.travis-ci.org/zendframework/zend-stdlib.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-stdlib) +[![Coverage Status](https://coveralls.io/repos/zendframework/zend-stdlib/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-stdlib?branch=master) + +`Zend\Stdlib` is a set of components that implements general purpose utility +class for different scopes like: + +- array utilities functions; +- json serializable interfaces; +- general messaging systems; +- string wrappers; +- etc. + +--- + +- File issues at https://github.com/zendframework/zend-stdlib/issues +- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-stdlib diff --git a/vendor/zendframework/zend-stdlib/doc/book/migration.md b/vendor/zendframework/zend-stdlib/doc/book/migration.md new file mode 100644 index 00000000..a0c7ff39 --- /dev/null +++ b/vendor/zendframework/zend-stdlib/doc/book/migration.md @@ -0,0 +1,60 @@ +# Migration Guide + +## From v2 to v3 + +The changes made going from v2 to v3 were: + +- Removal of the Hydrator subcomponent. +- Removal of the `CallbackHandler` class. +- Removal of `Zend\Stdlib\Guard\GuardUtils`. + +### Hydrators + +The biggest single change from version 2 to version 3 is that the hydrator +subcomponent, which was deprecated in v2.7.0, is now removed. This means that if +you were using zend-stdlib principally for the hydrators, you need to convert +your code to use [zend-hydrator](https://github.com/zendframework/zend-hydrator). + +This will also mean a multi-step migration. zend-stdlib v3 pre-dates +zend-hydrator v2.1, which will be the first version that supports zend-stdlib v3 +and zend-servicemanager v3. If you are using Composer, the migration should be +seamless: + +- Remove your zend-stdlib dependency: + + ```bash + $ composer remove zendframework/zend-stdlib + ``` + +- Update to use zend-hydrator: + + ```bash + $ composer require zendframework/zend-hydrator + ``` + +When zend-hydrator updates to newer versions of zend-stdlib and +zend-servicemanager, you will either automatically get those versions, or you +can tell composer to use those specific versions: + +```bash +$ composer require "zendframework/zend-stdlib:^3.0" +``` + +### CallbackHandler + +`Zend\Stdlib\CallbackHandler` primarily existed for legacy purposes; it was +created before the `callable` typehint existed, so that we could typehint PHP +callables. It also provided some minimal features around lazy-loading callables +from instantiable classes, but these features were rarely used, and better +approaches already exist for handling such functinality in zend-servicemanager +and zend-expressive. + +As such, the class was marked deprecated in v2.7.0, and removed for v3.0.0. + +### GuardUtils + +Version 3 removes `Zend\Stdlib\Guard\GuardUtils`. This abstract class existed to +provide the functionality of the various traits also present in that +subcomponent, for consumers on versions of PHP earlier than 5.4. Since the +minimum required version is now PHP 5.5, the class is unnecessary. If you were +using it previously, compose the related traits instead. diff --git a/vendor/zendframework/zend-stdlib/doc/bookdown.json b/vendor/zendframework/zend-stdlib/doc/bookdown.json new file mode 100644 index 00000000..ad93f485 --- /dev/null +++ b/vendor/zendframework/zend-stdlib/doc/bookdown.json @@ -0,0 +1,14 @@ +{ + "title": "Zend\\Stdlib", + "target": "html/", + "content": [ + "book/zend.stdlib.hydrator.md", + "book/zend.stdlib.hydrator.filter.md", + "book/zend.stdlib.hydrator.strategy.md", + "book/zend.stdlib.hydrator.aggregate.md", + "book/zend.stdlib.hydrator.namingstrategy.compositenamingstrategy.md", + "book/zend.stdlib.hydrator.namingstrategy.identitynamingstrategy.md", + "book/zend.stdlib.hydrator.namingstrategy.mapnamingstrategy.md", + "book/zend.stdlib.hydrator.namingstrategy.underscorenamingstrategy.md" + ] +} \ No newline at end of file diff --git a/vendor/zendframework/zend-stdlib/mkdocs.yml b/vendor/zendframework/zend-stdlib/mkdocs.yml new file mode 100644 index 00000000..bf87a22a --- /dev/null +++ b/vendor/zendframework/zend-stdlib/mkdocs.yml @@ -0,0 +1,9 @@ +docs_dir: doc/book +site_dir: doc/html +pages: + - index.md + - Migration: migration.md +site_name: zend-stdlib +site_description: Zend\Stdlib +repo_url: 'https://github.com/zendframework/zend-stdlib' +copyright: 'Copyright (c) 2016 Zend Technologies USA Inc.' diff --git a/vendor/zendframework/zend-stdlib/src/CallbackHandler.php b/vendor/zendframework/zend-stdlib/src/CallbackHandler.php deleted file mode 100644 index dc6bc746..00000000 --- a/vendor/zendframework/zend-stdlib/src/CallbackHandler.php +++ /dev/null @@ -1,192 +0,0 @@ -metadata = $metadata; - $this->registerCallback($callback); - } - - /** - * Registers the callback provided in the constructor - * - * @param callable $callback - * @throws Exception\InvalidCallbackException - * @return void - */ - protected function registerCallback($callback) - { - if (!is_callable($callback)) { - throw new Exception\InvalidCallbackException('Invalid callback provided; not callable'); - } - - $this->callback = $callback; - } - - /** - * Retrieve registered callback - * - * @return callable - */ - public function getCallback() - { - return $this->callback; - } - - /** - * Invoke handler - * - * @param array $args Arguments to pass to callback - * @return mixed - */ - public function call(array $args = []) - { - $callback = $this->getCallback(); - $argCount = count($args); - - if (is_string($callback)) { - $result = $this->validateStringCallbackFor54($callback); - - if ($result !== true && $argCount <= 3) { - $callback = $result; - // Minor performance tweak, if the callback gets called more - // than once - $this->callback = $result; - } - } - - // Minor performance tweak; use call_user_func() until > 3 arguments - // reached - switch ($argCount) { - case 0: - return $callback(); - case 1: - return $callback(array_shift($args)); - case 2: - $arg1 = array_shift($args); - $arg2 = array_shift($args); - return $callback($arg1, $arg2); - case 3: - $arg1 = array_shift($args); - $arg2 = array_shift($args); - $arg3 = array_shift($args); - return $callback($arg1, $arg2, $arg3); - default: - return call_user_func_array($callback, $args); - } - } - - /** - * Invoke as functor - * - * @return mixed - */ - public function __invoke() - { - return $this->call(func_get_args()); - } - - /** - * Get all callback metadata - * - * @return array - */ - public function getMetadata() - { - return $this->metadata; - } - - /** - * Retrieve a single metadatum - * - * @param string $name - * @return mixed - */ - public function getMetadatum($name) - { - if (array_key_exists($name, $this->metadata)) { - return $this->metadata[$name]; - } - return; - } - - /** - * Validate a static method call - * - * - * @param string $callback - * @return true|array - * @throws Exception\InvalidCallbackException if invalid - */ - protected function validateStringCallbackFor54($callback) - { - if (!strstr($callback, '::')) { - return true; - } - - list($class, $method) = explode('::', $callback, 2); - - if (!class_exists($class)) { - throw new Exception\InvalidCallbackException(sprintf( - 'Static method call "%s" refers to a class that does not exist', - $callback - )); - } - - $r = new ReflectionClass($class); - if (!$r->hasMethod($method)) { - throw new Exception\InvalidCallbackException(sprintf( - 'Static method call "%s" refers to a method that does not exist', - $callback - )); - } - $m = $r->getMethod($method); - if (!$m->isStatic()) { - throw new Exception\InvalidCallbackException(sprintf( - 'Static method call "%s" refers to a method that is not static', - $callback - )); - } - - // returning a non boolean value may not be nice for a validate method, - // but that allows the usage of a static string callback without using - // the call_user_func function. - return [$class, $method]; - } -} diff --git a/vendor/zendframework/zend-stdlib/src/DateTime.php b/vendor/zendframework/zend-stdlib/src/DateTime.php deleted file mode 100644 index cdab67d6..00000000 --- a/vendor/zendframework/zend-stdlib/src/DateTime.php +++ /dev/null @@ -1,47 +0,0 @@ - GLOB_NOSORT, self::GLOB_NOCHECK => GLOB_NOCHECK, self::GLOB_NOESCAPE => GLOB_NOESCAPE, - self::GLOB_BRACE => GLOB_BRACE, + self::GLOB_BRACE => defined('GLOB_BRACE') ? GLOB_BRACE : 0, self::GLOB_ONLYDIR => GLOB_ONLYDIR, self::GLOB_ERR => GLOB_ERR, ]; diff --git a/vendor/zendframework/zend-stdlib/src/Guard/GuardUtils.php b/vendor/zendframework/zend-stdlib/src/Guard/GuardUtils.php deleted file mode 100644 index 4fe4ccac..00000000 --- a/vendor/zendframework/zend-stdlib/src/Guard/GuardUtils.php +++ /dev/null @@ -1,85 +0,0 @@ -